Nie dbam o fda
„s wykorzystania Incepcja -Jak list-wewnątrz-listy-w całym wykazie struktur obiektów, ale moja odpowiedź będzie trwać przez system autorzy pakietów zostały utworzone.
Myślę, że warto najpierw pomyśleć o tym, co dokładnie robimy. W oparciu o opis tego, co zrobiłeś do tej pory, robię to, co według mnie robisz (daj mi znać, jeśli coś źle zinterpretowałem). Będę nadal używać notacji, a ze względu na brak rzeczywistych danych, przykład z analizy danych funkcjonalnych Ramsaya i Silvermana oraz analizy danych funkcjonalnych Ramsaya, Hookera i Gravesa za pomocą R i MATLAB (niektóre z poniższych równań i kodu są podnoszone bezpośrednio z tych książek).
Modelujemy odpowiedź skalarną za pomocą funkcjonalnego modelu liniowego, tj
yi=β0+∫T0Xi(s)β(s)ds+ϵi
W pewnym stopniu rozszerzamy . Używamy, powiedzmy, funkcji bazowych K. Więc,βK
β(s)=∑k=1Kbkθk(s)
W notacji macierzowej jest to .β(s)=θ′(s)b
Rozszerzamy również funkcje współzmienne w pewnym stopniu (powiedzmy funkcje podstawowe ). Więc,L
Xi(s)=∑k=1Lcikψk(s)
Ponownie, w notacji macierzowej jest to .X(s)=Cψ(s)
A zatem, jeśli pozwolimy , nasz model można wyrazić jakoJ=∫ψ(s)θ′(s)ds
y=β0+CJb
Z=[1CJ]ξ=[β0b′]′
y=Zξ
I wygląda nam to znacznie lepiej.
Teraz widzę, że dodajesz jakąś regularyzację. fda
Pakiet współpracuje z chropowatości kar formularza
P=λ∫[Lβ(s)]2ds
LR
R=λ⎛⎝⎜⎜⎜⎜⎜00⋮00R1⋮0⋯⋯⋱⋯00⋮RK⎞⎠⎟⎟⎟⎟⎟
Riβi
(y−Zξ)′(y−Zξ)+λξ′Rξ
dlatego naszym problemem jest jedynie regresja kalenicy z rozwiązaniem:
ξ^=(Z′Z+λR)−1Z′y
Przeszedłem powyższe, ponieważ: (1) myślę, że ważne jest, abyśmy rozumieli, co robimy, i (2) niektóre z powyższych są konieczne, aby zrozumieć część kodu, którego użyję później. Do kodu ...
Oto przykład danych z kodem R. Korzystam z kanadyjskiego zestawu danych pogodowych zawartych w fda
pakiecie. Modelujemy dzienne opady atmosferyczne dla wielu stacji pogodowych za pomocą funkcjonalnego modelu liniowego i wykorzystujemy profile temperatur (temperatury rejestrowano raz dziennie przez 365 dni) z każdej stacji jako funkcjonalne zmienne towarzyszące. Postępujemy podobnie do tego, co opisujesz w swojej sytuacji. Dane rejestrowano na 35 stacjach. Podzielę zestaw danych na 34 stacje, które zostaną wykorzystane jako moje dane, oraz na ostatnią stację, która będzie moim „nowym” zestawem danych.
Kontynuuję przez kod R i komentarze (zakładam, że znasz się na fda
pakiecie tak, że nic poniżej nie jest zbyt zaskakujące - jeśli tak nie jest, daj mi znać):
# pick out data and 'new data'
dailydat <- daily$precav[,2:35]
dailytemp <- daily$tempav[,2:35]
dailydatNew <- daily$precav[,1]
dailytempNew <- daily$tempav[,1]
# set up response variable
annualprec <- log10(apply(dailydat,2,sum))
# create basis objects for and smooth covariate functions
tempbasis <- create.fourier.basis(c(0,365),65)
tempSmooth <- smooth.basis(day.5,dailytemp,tempbasis)
tempfd <- tempSmooth$fd
# create design matrix object
templist <- vector("list",2)
templist[[1]] <- rep(1,34)
templist[[2]] <- tempfd
# create constant basis (for intercept) and
# fourier basis objects for remaining betas
conbasis <- create.constant.basis(c(0,365))
betabasis <- create.fourier.basis(c(0,365),35)
betalist <- vector("list",2)
betalist[[1]] <- conbasis
betalist[[2]] <- betabasis
# set roughness penalty for betas
Lcoef <- c(0,(2*pi/365)^2,0)
harmaccelLfd <- vec2Lfd(Lcoef, c(0,365))
lambda <- 10^12.5
betafdPar <- fdPar(betabasis, harmaccelLfd, lambda)
betalist[[2]] <- betafdPar
# regress
annPrecTemp <- fRegress(annualprec, templist, betalist)
Teraz, gdy rok temu dowiedziałem się o danych funkcjonalnych, bawiłem się tym pakietem. Nie mogłem też predict.fRegress
dać mi tego, czego chciałem. Patrząc na to teraz, wciąż nie wiem, jak to zrobić. Będziemy musieli więc uzyskać prognozy półautomatycznie. Będę używał elementów, dla których wyciągnąłem prosto z kodu fRegress()
. Ponownie kontynuuję za pomocą kodu i komentarzy.
Po pierwsze, konfiguracja:
# create basis objects for and smooth covariate functions for new data
tempSmoothNew <- smooth.basis(day.5,dailytempNew,tempbasis)
tempfdNew <- tempSmoothNew$fd
# create design matrix object for new data
templistNew <- vector("list",2)
templistNew[[1]] <- rep(1,1)
templistNew[[2]] <- tempfdNew
# convert the intercept into an fd object
onebasis <- create.constant.basis(c(0,365))
templistNew[[1]] <- fd(matrix(templistNew[[1]],1,1), onebasis)
Teraz, aby uzyskać prognozy
y^new=Znewξ^
fRegress
yhatfdobj
fRegress
yhatfdobj
∫T0Xi(s)β(s)Xiβ
Zwykle fRegress
oblicza dopasowane wartości, zapętlając zmienne towarzyszące zapisane w annPrecTemp$xfdlist
. Dlatego w przypadku naszego problemu zastępujemy tę listę zmiennych towarzyszących odpowiadającą jej na naszej nowej liście zmiennych, tj templistNew
. Oto kod (identyczny z kodem znalezionym w fRegress
dwóch edycjach, usunięciu niepotrzebnego kodu i dodaniu kilku komentarzy):
# set up yhat matrix (in our case it's 1x1)
yhatmat <- matrix(0,1,1)
# loop through covariates
p <- length(templistNew)
for(j in 1:p){
xfdj <- templistNew[[j]]
xbasis <- xfdj$basis
xnbasis <- xbasis$nbasis
xrng <- xbasis$rangeval
nfine <- max(501,10*xnbasis+1)
tfine <- seq(xrng[1], xrng[2], len=nfine)
deltat <- tfine[2]-tfine[1]
xmat <- eval.fd(tfine, xfdj)
betafdParj <- annPrecTemp$betaestlist[[j]]
betafdj <- betafdParj$fd
betamat <- eval.fd(tfine, betafdj)
# estimate int(x*beta) via trapezoid rule
fitj <- deltat*(crossprod(xmat,betamat) -
0.5*(outer(xmat[1,],betamat[1,]) +
outer(xmat[nfine,],betamat[nfine,])))
yhatmat <- yhatmat + fitj
}
(uwaga: jeśli spojrzysz na ten fragment i otaczający go kod fRegress
, zobaczysz kroki, które przedstawiłem powyżej).
Przetestowałem kod, ponownie uruchamiając przykład pogody, używając wszystkich 35 stacji jako naszych danych i porównałem wynik z powyższej pętli do annPrecTemp$yhatfdobj
i wszystko pasuje. Uruchomiłem go również kilka razy, używając różnych stacji jako moich „nowych” danych i wszystko wydaje się rozsądne.
Daj mi znać, jeśli którekolwiek z powyższych jest niejasne lub jeśli coś nie działa poprawnie. Przepraszamy za zbyt szczegółową odpowiedź. Nie mogłem się powstrzymać :) A jeśli jeszcze ich nie masz, sprawdź dwie książki, w których pisałem tę odpowiedź. To naprawdę dobre książki.