Jak dopasować splajn do danych zawierających wartości i 1. / 2. pochodną?


14

Mam zestaw danych, który zawiera, powiedzmy, kilka pomiarów pozycji, prędkości i przyspieszenia. Wszystkie pochodzą z tego samego „biegu”. Mógłbym zbudować układ liniowy i dopasować wielomian do wszystkich tych pomiarów.

Ale czy mogę zrobić to samo z splajnami? W jaki sposób można to zrobić?

Oto kilka symulowanych danych, które chciałbym dopasować:

f <- function(x) 2+x-0.5*x^2+rnorm(length(x), mean=0, sd=0.1)
df <- function(x) 1-x+rnorm(length(x), mean=0, sd=0.3)
ddf <- function(x) -1+rnorm(length(x), mean=0, sd=0.6)

x_f <- runif(5, 0, 5)
x_df <- runif(8, 3, 8)
x_ddf <- runif(10, 4, 9)

data <- data.frame(type=rep('f'), x=x_f, y=f(x_f))
data <- rbind(data, data.frame(type=rep('df'), x=x_df, y=df(x_df)))
data <- rbind(data, data.frame(type=rep('ddf'), x=x_ddf, y=ddf(x_ddf)))

library(ggplot2)
ggplot(data, aes(x, y, color=type)) + geom_point()


library(splines)
m <- lm(data$y ~ bs(data$x, degree=6)) # but I want to fit on f, df, ddf. possible?

wprowadź opis zdjęcia tutaj


Nie znam odpowiedzi na twoje pytanie, ale splinefunpotrafię obliczyć pochodne i prawdopodobnie możesz to wykorzystać jako punkt wyjścia do dopasowania danych za pomocą niektórych odwrotnych metod? Chcę poznać rozwiązanie tego problemu.
David LeBauer,

1
Problem ten rozwiązał Maurice Cox w swoim artykule z 1972 roku. Nie wiem, czy R to obsługuje, ale szukanym terminem jest „splajn pustelnika”.
user14717,

@DavidLeBauer właśnie to robię. Sformalizowałem problem optymalizacji, który pasuje do wielu punktów, tak że splajn i jego pochodne przybliżają dane. Ale bardziej bezpośrednia metoda byłaby świetna.
dani

3
Całkiem standardowe podejście polega na filtrowaniu Kalmana. Stan (nieobserwowalny) zawiera dokładne pochodne, a obserwacje są ich hałaśliwymi wersjami. Na przykład model splajnu sześciennego z grubsza mówi, że pochodna drugiego rzędu jest białym szumem (w czasie ciągłym), ale można również zastosować model wyższego rzędu. Będziesz musiał opisać szum pomiaru w zależności od kolejności wyprowadzania dla bieżącej obserwacji. Trzy wariancje hałasu (do oszacowania) mogą wystarczyć w pierwszym podejściu.
Yves

2
co to jest błąd pomiaru instrumentów pochodnych? czy jest znacznie wyższa niż pozycja? także na wykresie, dlaczego punkty nie są wyrównane? co to jest oś x?
Aksakal

Odpowiedzi:


9

Opiszemy, jak można używać splajnu za pomocą technik filtrowania Kalmana (KF) w odniesieniu do modelu State-Space (SSM). Fakt, że niektóre modele splajnu mogą być reprezentowane przez SSM i obliczane za pomocą KF, został ujawniony przez CF Ansley i R. Kohna w latach 1980-1990. Oszacowana funkcja i jej pochodne są oczekiwaniami państwa zależnymi od obserwacji. Oszacowania te są obliczane przy użyciu wygładzania o ustalonych odstępach czasu , rutynowego zadania podczas korzystania z SSM.

Dla uproszczenia załóżmy, że obserwacje są dokonywane w momentach oraz że liczba obserwacji w obejmuje tylko jedną pochodną z rzędem w . Część obserwacyjna modelu zapisuje jako gdzie oznacza nieobserwowaną prawdziwą funkcję, a jest błędem Gaussa z wariancją zależności od rzędu pochodnej . Równanie przejścia (czas ciągły) przyjmuje postać ogólną t1<t2<<tnktkd kdk{0,1,2}

(O1)y(tk)=f[dk](tk)+ε(tk)
f(t)ε ( t k ) H ( t k ) d k dε(tk)H.(tk)rek
(T1)reretα(t)=ZAα(t)+η(t)
gdzie jest nieobserwowanym wektorem stanu, a to biały szum Gaussa z kowariancją , zakładając, że jest niezależny od hałas obserwacyjny r.vs . Aby opisać splajn, rozważamy stan uzyskany przez ułożenie pierwszych pochodnych, tj. . Przejście jest [f[1](t)f[2](t)f[m-1](t)f[m](t)]=[010α(t)η(t)Qε(tk)mα(t): =[fa(t),fa[1](t),,fa[m-1](t)]
[fa[1](t)fa[2)](t)fa[m-1](t)fa[m](t)]=[010001100][fa(t)fa[1](t)fa[m-2)](t)fa[m-1](t)]+[000η(t)]
2m2m-1m=2>1 rok ( t k ) a następnie otrzymujemy wielomianowy splajn z rzędem (i stopniem ). Podczas gdy odpowiada zwykłem splajnowi sześciennemu,2)m2)m-1m=2)>1. Aby trzymać się klasycznego formalizmu SSM, możemy przepisać (O1) jako gdzie macierz obserwacji wybiera odpowiednią pochodną w a wariancja z jest wybierana w zależności od . Więc gdzie , i . Podobnie
(O2)y(tk)=Z(tk)α(tk)+ε(tk),
Z(tk)α(tk)H.(tk)ε(tk)rekZ(tk)=Zrek+1Z1: =[1,0,,0]Z2): =[0,1,0]Z3): =[0,0,1,0,]H.(tk)=H.rek+1 H 1 H 2 H 3dla trzech , i . H.1H.2)H.3)

Chociaż przejście odbywa się w czasie ciągłym, KF jest w rzeczywistości standardowym czasem dyskretnym . Rzeczywiście, w praktyce skupimy się na czasach których mamy obserwację lub w których chcemy oszacować pochodne. Możemy przyjąć zbiór tych dwóch zbiorów czasów i założyć, że może brakować obserwacji w : pozwala to oszacować pochodne dowolnym momencie niezależnie od istnienia obserwacji. Pozostaje jeszcze ustalić dyskretny SSM.t{tk}tkmtk

Użyjemy indeksów dla dyskretnych czasów, pisząc dla i tak dalej. SSM z czasem dyskretnym ma postać gdzie macierze i pochodzą od (T1) i (O2), podczas gdy wariancja jest podana przez pod warunkiem, żeαkα(tk)

(DT)αk+1=T.kαk+ηkyk=Zkαk+εk
T.kQk: =Var(ηk)εkH.k=H.rek+1ykTk=exp{δkA}=[ 1 δ 1 knie brakuje. Za pomocą algebry możemy znaleźć macierz przejścia dla dyskretnego czasu SSM gdzie dla . Podobnie macierz kowariancji dla SSM z czasem dyskretnym można podać jako
T.k=exp{δkZA}=[1δk11!δk2)2)!δkm-1(m-1)!01δk11!δk11!01],

δk: =tk+1-tkk<nQk=Var(ηk)
Qk=ση2)[δk2)m-ja-jot+1(m-ja)!(m-jot)!(2)m-ja-jot+1)]ja,jot
ij1m gdzie wskaźniki oraz wynoszą od do .jajot1m

Teraz, aby przenieść obliczenia w R, potrzebujemy pakietu poświęconego KF i akceptującego modele zmieniające się w czasie; pakiet CRAN KFAS wydaje się dobrą opcją. Możemy napisać funkcje R do obliczenia macierzy i z wektora czasów w celu zakodowania SSM (DT). W używanych przez pakiet macierz przychodzi do pomnożenia szumu w równaniu przejścia (DT): bierzemy to tutaj za tożsamość . Należy również pamiętać, że należy tutaj zastosować rozproszoną kowariancję początkową.T.kQktkRkηkjam

EDIT jak pierwotnie napisany był w błędzie. Naprawiono (również w kodzie R i obrazie).Q

CF Ansley i R. Kohn (1986) „O równoważności dwóch podejść stochastycznych do wygładzania splajnu” J. Appl. Probab , 23, s. 391–405

R. Kohn i CF Ansley (1987) „Nowy algorytm wygładzania splajnu oparty na wygładzaniu procesu stochastycznego” SIAM J. Sci. i Stat. Comput. , 8 (1), s. 33–48

J. Helske (2017). „KFAS: wykładnicze modele przestrzeni stanów rodzinnych w R” J. Stat. Miękki. , 78 (10), s. 1–39

wygładzanie za pomocą instrumentów pochodnych

smoothWithDer <- function(t, y, d, m = 3,
                          Hstar = c(3, 0.2, 0.1)^2, sigma2eta = 1.0^2) {

    ## define the SSM matrices, depending on 'delta_k' or on 'd_k'
    Tfun <- function(delta) {
        mat <-  matrix(0, nrow = m, ncol = m)
        for (i in 0:(m-1)) {
            mat[col(mat) == row(mat) + i] <- delta^i / gamma(i + 1)
        }
        mat
    }
    Qfun <- function(delta) {
        im <- (m - 1):0
        x <- delta^im / gamma(im + 1)
        mat <- outer(X = x, Y = x, FUN = "*")
        im2 <- outer(im, im, FUN = "+")
        sigma2eta * mat * delta / (im2 + 1) 
    }
    Zfun <-  function(d) {
        Z <- matrix(0.0, nrow = 1, ncol = m)
        Z[1, d + 1] <- 1.0
        Z
    }
    Hfun <- function(d) ifelse(d >= 0, Hstar[d + 1], 0.0)
    Rfun <- function() diag(x = 1.0, nrow = m)

    ## define arrays by stacking the SSM matrices. We need one more
    ## 'delta' at the end of the series
    n <- length(t)
    delta <-  diff(t)
    delta <- c(delta, mean(delta))

    Ta <- Qa <- array(0.0, dim = c(m, m, n))
    Za <- array(0.0, dim = c(1, m, n))
    Ha <- array(0.0, dim = c(1, 1, n))
    Ra <-  array(0.0, dim = c(m, m, n))

    for (k in 1:n) {
        Ta[ , , k] <- Tfun(delta[k])
        Qa[ , , k] <- Qfun(delta[k])
        Za[ , , k] <- Zfun(d[k])
        Ha[ , , k] <- Hfun(d[k])
        Ra[ , , k] <- Rfun()
    }

    require(KFAS)
    ## define the SSM and perform Kalman Filtering and smoothing
    mod <- SSModel(y ~ SSMcustom(Z = Za, T = Ta, R = Ra, Q = Qa, n = n,
                                 P1 = matrix(0, nrow = m, ncol = m),
                                 P1inf = diag(1.0, nrow = m), 
                                 state_names = paste0("d", 0:(m-1))) - 1)
    out <- KFS(mod, smoothing = "state")
    list(t = t, filtered = out$att, smoothed = out$alphahat)

}

## An example function as in OP
f <- function(t, d = rep(0, length = length(t))) {
    f <- rep(NA, length(t))
    if (any(ind <- (d == 0))) f[ind] <- 2.0 + t[ind] - 0.5 * t[ind]^2
    if (any(ind <- (d == 1))) f[ind] <- 1.0 - t[ind]
    if (any(ind <- (d == 2))) f[ind] <- -1.0
    f
}

set.seed(123)
n <-  100
t <- seq(from = 0, to = 10, length = n)
Hstar <- c(3, 0.4, 0.2)^2
sigma2eta <- 1.0

fTrue <- cbind(d0 = f(t), d1 = f(t, d = 1), d2 = f(t, d = 2))

## ============================================================================
## use a derivative index of -1 to indicate non-observed values, where
## 'y' will be NA
##
## [RUN #0]  no derivative  m = 2 (cubic spline)
## ============================================================================
d0 <- sample(c(-1, 0), size = n, replace = TRUE, prob = c(0.7, 0.3))
ft0 <-  f(t, d0)
## add noise picking the right sd
y0 <- ft0 + rnorm(n = n, sd = c(0.0, sqrt(Hstar))[d0 + 2])
res0 <- smoothWithDer(t, y0, d0, m = 2, Hstar = Hstar)

## ============================================================================
## [RUN #1] Only first order derivative: we can take m = 2 (cubic spline)
## ============================================================================
d1 <- sample(c(-1, 0:1), size = n, replace = TRUE, prob = c(0.7, 0.15, 0.15))
ft1 <-  f(t, d1)
y1 <- ft1 + rnorm(n = n, sd = c(0.0, sqrt(Hstar))[d1 + 2])
res1 <- smoothWithDer(t, y1, d1, m = 2, Hstar = Hstar)

## ============================================================================
## [RUN #2] First and second order derivative: we can take m = 3
## (quintic spline)
## ============================================================================
d2 <- sample(c(-1, 0:2), size = n, replace = TRUE, prob = c(0.7, 0.1, 0.1, 0.1))
ft2 <-  f(t, d2)
y2 <- ft2 + rnorm(n = n, sd = c(0.0, sqrt(Hstar))[d2 + 2])
res2 <- smoothWithDer(t, y2, d2, m = 3, Hstar = Hstar)

## plots : a ggplot with facets would be better here.
for (run in 0:2) {
    resrun <- get(paste0("res", run))
    drun <- get(paste0("d", run))
    yrun <- get(paste0("y", run))
    matplot(t, resrun$smoothed, pch = 16, cex = 0.7, ylab = "", xlab = "")
    matlines(t, fTrue, lwd = 2, lty = 1)
    for (dv in 0:2) {
        points(t[drun == dv], yrun[drun == dv], cex = 1.2, pch = 22, lwd = 2,
               bg = "white", col = dv + 1)
    }
    title(main = sprintf("run %d. Dots = smooothed, lines = true, square = obs", run))
    legend("bottomleft", col = 1:3, legend = c("d0", "d1", "d2"), lty = 1)
}

Dziękuję za Twoją odpowiedź. Bardzo mnie to interesuje. Obecnie nie zezwala się na używanie wartości fi jej pochodnych do pewnego stopnia t. Czy możliwe jest wykorzystanie wszystkich informacji? Ponownie, miłosierdzie za twoją odpowiedź.
dani

Moje czytanie jest takie, że wszystko poniżej T1 dotyczy używania wielu pochodnych w tej samej procedurze wnioskowania. Yves może jednak potwierdzić.
eric_kernfeld

Rzeczywiście, możesz użyć powiedzmy pochodnych dla jednego : obserwacja jest wtedy wektorem, a ma wiersze wybierają pożądane pochodne. Jestem pewien, że wspólna współpracuje z KFAS , ale przy użyciu NAS może być możliwe, aby mieć zmienny czas jak dobrze. t k y k Z k o k o > 1 ook>1tkykZkoko>1o
Yves

@Yves Czy ja cię rozumiem poprawnie: Jeśli mam pierwszą i drugą pochodną w punkcie t_k, wówczas Z_k wygląda następująco: matrix(c(0,0,0, 0,1,0, 0,0,1), nrow=length(d_k), ncol=m, byrow = T). Ogólnie rzecz biorąc, byłby to sześcian wymiaru „najwyższa pochodna” * „stopień splajnu” * „liczba kroków czasowych”
dani

Tak @dani, prawie: liczba wierszy dla wszystkich macierzy wynosi tj. w przykładzie. Jest to najwyższy rząd instrumentów pochodnych plus jeden. Ponadto stopień splajnu wynosi , a nie . W twoim przykładzie, ponieważ nie obserwujesz pochodnej rzędu (samej funkcji), należy ją ustawić w obserwacjach i możesz również upuścić pierwszy wiersz. Podejrzewam jednak, że w tym konkretnym przypadku problem jest źle postawiony, SSM może nie być zauważalny . Zkmaxk{rek+1}3)2)m-1m0NA
Yves

5

Możesz zrobić spektakularnie dobrze ze standardową procedurą najmniejszych kwadratów, pod warunkiem, że masz rozsądne pojęcie o względnych rozmiarach błędów losowych popełnianych dla każdej pochodnej. Nie ma ograniczeń co do liczby pomiarów, które wykonujesz dla każdej wartości - możesz nawet jednocześnie mierzyć różne pochodne dla każdej z nich. Jedynym ograniczeniem w stosowaniu zwykłych najmniejszych kwadratów (OLS) jest zwykłe: zakłada się, że pomiary są niezależne.x

Podstawową ideę można najlepiej wyrazić poprzez streszczenie problemu. Twój model wykorzystuje zestaw funkcji (jak każda podstawa splajnu) jako podstawa do przewidywania wartości nieznanej funkcji w punktach Oznacza to, że do oszacowania współczynników dla których każda z kombinacji liniowych przybliżeniu zbliżona do Nazwijmy to (wektorową) przestrzenią kombinacji liniowychpfajot:RR, jot=1,2),,pyja=fa(xja)fa(x1,x2),,xn).βjotjotβjotfajot(xja)yja.fa.

Szczególne w tym problemie jest to, że niekoniecznie obserwujeszyja. Zamiast tego istnieje zdefiniowany zestaw funkcjonałów liniowych powiązany z danymi. Przypomnij sobie, że funkcja jest „funkcją funkcji”: każdy przypisuje liczbę do dowolnej funkcji Model zakłada, żeL.jaL.jaL.ja[fa]fafa.

(1)yja=L.ja[fa]+σjaεja

gdzie otrzymują funkcjonały, są znanymi współczynnikami skali, a są niezależnymi i identycznie rozmieszczonymi losowymi zmiennymi.L.jaσja>0εja

Dwa dodatkowe założenia sprawiają, że OLS ma zastosowanie i ma znaczenie statystyczne:

  1. Wspólna dystrybucja ma skończoną wariancję.εja

  2. Każdy jest funkcją liniową . Funkcjonalny jest liniowy, gdy dla dowolnego elementu i odpowiadających mu liczbL.jaL.fajotfaαjot,

    L[jotαjotfajot]=jotαjotL.[fajot].

(2) pozwala na wyraźniejsze wyrażenie modelu jako(1)

yja=β1L.ja[fa1]++βpL.ja[fap]+σjaεja.

Cały sens tej redukcji polega na tym, że ponieważ określono wszystkie funkcjonały wszystkie podstawowe funkcje a standardowe odchylenia wartości są liczbami - - są to zwykłe „zmienne” lub „cechy” problemu regresji - a są jedynie wagami (względnymi). Tak więc, w optymalnym sensie twierdzenia Gaussa-Markowa, OLS jest świetną procedurą do zastosowania.L.ja,fajot,σja,L.ja[fajot]σja

Funkcjonaliści biorący udział w pytaniu to:

  • Oceń w określonym punkcie Tak zwykle robimy. Jest to liniowe, ponieważ z definicji liniowe kombinacje funkcji są oceniane punktowo.fax: L.[fa]=fa(x).

  • Oceń pochodną w określonym punkcie Jest to liniowe, ponieważ różnicowanie jest liniowe.fax: L.[fa]=fa(x).

  • Oceń drugą pochodną w określonym punkciefax: L.[fa]=fa(x).


Ok, jak dobrze działa to podejście? Jak zwykle przestudiujemy resztki porównując dopasowane wartości z wartościami zaobserwowanymi. Ponieważ pozycje, prędkości i przyspieszenia są w różnych jednostkach, należy je narysować na osobnych osiach.y^ja-yjay^ja

Postać

Górny rząd używa krzywych do wykreślenia i pierwszych dwóch pochodnych. Odpowiednie punkty danych wykreślono na krzywych: obserwowane wartości po lewej stronie, obserwowane pochodne po środku i obserwowane drugie pochodne po prawej.y^

Dolny rząd przedstawia odpowiednie wartości resztkowe. Jak zwykle szukamy braku jakiegokolwiek znaczącego związku: mamy nadzieję, że wartości rezydualne (ich współrzędne Y) zmieniają się losowo od lewej do prawej, wykazując niezależność i brak trendów.

Gdy wartości danych wytworzono dokładnie tak, jak w odpowiedzi na pytanie (po ustawieniu losowych liczb do 17 za pomocą na odtwarzalność). Zbadałem pasowania za pomocą spacji B-spline generowanych przez funkcję , również jak w pytaniu, dla stopni od 1 do 6. Ta rycina pokazuje wyniki dla stopnia 2, który jest najniższym stopniem (czyli najprostszym modelem) wykazujący niski AIC i dobre zachowanie resztkowe, a także model wskazany przez ANOVA wszystkich sześciu (zagnieżdżonych) modeli.n=23set.seed(17)faRbs

Dopasowanie jest

y^=-27,48993+2,54078fa1+2,97679fa2)

gdzie i są funkcjami podstawowymi splajnu B utworzonymi przez .fa1fa2)bs

Resztki zachowują się dobrze. Pasowania są dobre. Co więcej, podejście to znalazło właściwy model: dane rzeczywiście zostały wygenerowane z funkcji kwadratowej (stopień 2). Ponadto odchylenia standardowe reszt wynoszą mniej więcej odpowiednie rozmiary: 0,11, 0,20 i 0,61 w porównaniu do 0,1, 0,3 i 0,6 użytych do wygenerowania błędów pierwotnych. To dość niesamowite, biorąc pod uwagę fakt, że krzywe te ekstrapolują obserwacje (które nie wykraczają poza ) i używają tak małego zestawu danych ( ).x=5n=23

Wreszcie, resztki pasowań dla splajnów wyższego stopnia są jakościowo takie same; wprowadzają jedynie niewielkie ulepszenia kosztem stosowania mniej wiarygodnych modeli. W przypadku wystarczająco wysokich stopni zaczynają się gwałtownie oscylować , na przykład dla małych wartości między obserwowanymi wartościami. Aby zilustrować to (złe) zachowanie, oto dopasowanie stopnia 9:x

Rysunek 2

Wreszcie, oto przykład, w którym dokonano wielu obserwacji różnych funkcjonałów liniowych podstawy. Kod generowania tych obserwacji został zmieniony z kodu w pytaniu na

mult <- 2
x_f <- rep(runif(5, 0, 5), mult)       # Two observations per point
x_df <- rep(runif(8, 3, 8), mult)      # Two derivatives per point
x_ddf <- c(x_df, rep(runif(10, 4, 9))  # Derivative and acceleration per point

Rycina 3


RKod do przeprowadzania tych obliczeń jest dość ogólne. W szczególności wykorzystuje numeryczne zróżnicowanie do znalezienia pochodnych, tak aby nie było zależne od rodzaju użytego splajnu. Obsługuje różne wartości obserwacje proporcjonalnie do Automatycznie konstruuje i dopasowuje zestaw modeli w pętli. Funkcjonalności liniowe i odchylenia standardowe są zakodowane na stałe. Istnieją trzy z nich, wybrane zgodnie z wartością zmiennej w zestawie danych.σja1/σja2).L.jaσjatype

Jako przykłady tego, w jaki sposób można użyć pasowań, coda drukuje streszczenia, listę ich AIC i ANOVA wszystkich z nich.

#
# Estimate spline derivatives at points of `x`.
#
d <- function(x, s, order=1) {
  h <- diff(range(x, na.rm=TRUE))
  dh <- h * 1e-4
  lags <- seq(-order, order, length.out=order+1) * dh/2
  b <- choose(order, 0:order) * (-1)^(order:0)
  y <- b %*% matrix(predict(s, c(outer(lags, x, `+`))), nrow=length(lags))
  y <- matrix(y / (dh^order), nrow=length(x))
}
#
# Fit and plot models by degree.
#
data$order <- c(f=0, df=1, ddf=2)[data$type]
k <- max(data$order)
x <- data$x
w <- (c(0.1, 0.3, 0.6)^(-2))[data$order+1] # As specified in the question

fits <- lapply(1:6, function(deg) {
  #
  # Construct a model matrix.
  #
  s <- bs(x, degree=deg, intercept=TRUE)
  X.l <- lapply(seq.int(k+1)-1, function(i) {
    X <- subset(data, order==i)
    Y <- as.data.frame(d(X$x, s, order=i))
    cbind(X, Y)
  })
  X <- do.call("rbind", X.l)
  #
  # Fit WLS models.
  #
  f <- as.formula(paste("y ~ -1 +", paste0("V", 0:deg+1, collapse="+")))
  fit <- lm(f, X, weights=w)
  msr <- tapply(residuals(fit), data$order, function(r) {
    k <- length(r) - 1 - deg
    ifelse(k >= 1, sum(r^2) / k, 1)
  })
  #
  # Compute predicted values along the graphs.
  #
  X.new <- data.frame(x = seq(min(X$x), max(X$x), length.out=101))
  X.new$y.hat <- predict(s, X.new$x) %*% coefficients(fit)
  X.new$Dy.hat <- d(X.new$x, s, 1) %*% coefficients(fit)
  X.new$DDy.hat <- d(X.new$x, s, 2) %*% coefficients(fit)
  X$Residual <- residuals(fit)
  #
  # Return the model.
  #
  fit$msr <- msr
  fit
})
lapply(fits, function(f) sqrt(f$msr))
lapply(fits, summary)
lapply(fits, AIC)
do.call("anova", fits)

1

Przede wszystkim chcę podziękować za postawienie tego pytania. To NAPRAWDĘ interesujące pytanie. Uwielbiam splajny i fajne rzeczy, które możesz z nimi zrobić. To dało mi wymówkę do przeprowadzenia badań. :-)

BLUF: Krótka odpowiedź brzmi „nie”. Nie znam żadnej funkcji w R, która zrobiłaby to dla ciebie automatycznie. Długa odpowiedź jest ... znacznie bardziej skomplikowana. Fakt, że próbki i wartości funkcji nie są próbkowane w tym samym miejscu, utrudnia to. A fakt, że nie masz wartości funkcji blisko prawego końca przedziału, może to uniemożliwić.

Zacznijmy od splajnu sześciennego. Biorąc pod uwagę punkty i odpowiadające im drugie pochodne , przechodzący przez nie splajn sześcienny to:(xjot,yjot)zjot

S.jot(x)=ZAyjot+byjot+1+dozjot+rezjot+1
gdzie Łatwo jest sprawdzić, czy , , i . To gwarantuje, że splajn i jego druga pochodna są ciągłe. Jednak w tym momencie nie mamy ciągłej pierwszej pochodnej. Aby wymusić ciągłość pierwszej pochodnej, potrzebujemy następującego ograniczenia:
hjot=xjot+1-xjotZA=xjot+1-xhjotb=1-ZAdo=16(ZA3)-ZA)hjot2)re=16(b3)-b)hjot2)
S.jot(xjot)=yjotS.jot(xjot+1)=yjot+1S.jot(xjot)=zjotS.jot(xjot+1)=zjot+1
(1)6hjot-1yjot-1-(6hjot-1+6hjot)yjot+6hjotyjot+1=hjot-1zjot-1+2)(hjot-1+hjot)zjot+hjotzjot+1
W klasycznej konfiguracji splajnu sześciennego zakładasz, że masz punkty i używasz równania (wraz z dwoma dodatkowymi ograniczeniami brzegowymi) do rozwiązania dla . Po znajomości splajn jest w pełni określony i można go użyć do interpolacji w dowolnym dowolnym punkcie. Jako dodatkowy bonus równanie zamienia się w macierz tridiagonalną, którą można rozwiązać w czasie liniowym!(xjot,yjot)(1)zjotzjot(1)

OK, załóżmy teraz, że zamiast znać , znasz . Czy możesz użyć równania aby rozwiązać dla ? Z czystego punktu widzenia algebry wydaje się to wykonalne. Istnieje równań i nieznanych, więc ... dlaczego nie? Ale okazuje się, że nie możesz; matryca będzie pojedyncza. I nie powinno to dziwić. Jak można interpolować wartości funkcji, biorąc pod uwagę TYLKO drugie pochodne? Przynajmniej potrzebujesz wartości początkowej, takiej jak równanie różniczkowe.yjotzjot(1)yjotN.N.

Co z twoją sytuacją? Niektóre z twoich punktów mają wartości funkcji, a niektóre z twoich pochodnych. Na razie zignorujmy pierwsze pochodne (to rodzaj bałaganu, z którym trzeba sobie poradzić w przypadku splajnu sześciennego). Formalnie niech będzie zbiorem punktów z wartościami funkcji, a będzie zbiorem punktów z drugimi pochodnymi. Nadal mamy równań z niewiadomymi. tylko, że niektóre niewiadome to a niektóre to . Okazuje się, że otrzymasz rozwiązanie, jeśli 0, 1 lub 2 ORAZ lub(xja,yja),jaja(xjot,zjot),jotjotN.N.yjotzjotjaN.-3),N.-2)N.-1ja. Innymi słowy, jeden z pierwszych trzech punktów musi być wartością funkcji ORAZ jeden z ostatnich trzech punktów musi być wartością funkcji. Oprócz tego ograniczenia możesz wrzucać dowolną liczbę instrumentów pochodnych.

A co z tymi pierwszymi pochodnymi? Z pewnością możliwe jest uwzględnienie pierwszych pochodnych w splajnie. Ale, jak powiedziałem, robi się znacznie bardziej bałagan. Pierwszą pochodną splajnu podaje: Oczywiście, naprawdę interesuje nas tylko pochodna w węzłach, więc możemy to trochę uprościć, oceniając ją na : można dodawać te ograniczenia macierzy otrzymanej z równania

S.jot(x)=yjot+1-yjothjot-3)ZA2)-16hjotzjot+3)b2)-16hjotzjot+1
xjot
S.jot(xjot)=yjot+1-yjothjot-13)hjotzjot-16hjotzjot+1
(1)a powstały splajn będzie miał określone pierwsze pochodne. Ponadto pomoże to w rozwiązaniu problemu pojedynczej macierzy. Dostaniesz rozwiązanie, jeśli ZNAJDZIESZ wartość funkcji lub pierwszą pochodną w pierwszych trzech i ostatnich trzech punktach.

Więc umieściłem to wszystko w jakimś kodzie i oto zdjęcie, które otrzymałem:

Spline poszło nie tak

Jak widać, wyniki nie są świetne. Jest tak, ponieważ jest to regularny splajn, który musi honorować WSZYSTKIE dane. Ponieważ dane są stochastyczne, naprawdę musimy użyć splajnu regresji. To temat na inny post. Ale jeśli przejdziesz przez matematykę, skończysz optymalizować kwadratową funkcję celu podlegającą ograniczeniom równości liniowej - i istnieje rozwiązanie w formie zamkniętej!

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.