Меня не волнует fda
использование Inception- подобных списочно-структурных объектов-списков-в-списках, но мой ответ будет зависеть от системы, созданной создателями пакетов.
Я думаю, поучительно сначала подумать о том, что именно мы делаем. Исходя из вашего описания того, что вы сделали до сих пор, я верю, что вы делаете это (дайте мне знать, если я что-то неправильно понял). Я буду продолжать использовать нотацию и, из-за отсутствия реальных данных, пример из анализа функциональных данных Рамсея и Сильвермана и анализа функциональных данных Рамзея, Хукера и Грейвса с помощью R и MATLAB (некоторые из следующих уравнений и кода были сняты напрямую из этих книг).
Мы моделируем скалярный отклик через функциональную линейную модель, т.е.
Yя= β0+ ∫T0Икся( s ) β( s ) dс + ϵя
Разложим в некотором базисе. Мы используем, скажем, K базисных функций. Так,βК
β( s ) = ∑к = 1КбКθК( s )
В матричной записи это .β( s ) = θ'( s ) b
Мы также расширяем ковариатные функции в некотором базисе (скажем, базисных функций). Так,L
Икся( s ) = ∑к = 1Lся кψК( s )
Опять же, в матричной записи это .Икс( s ) = C ψ ( s )
И, таким образом, если мы позволим , наша модель может быть выражена какJ =∫ψ ( s ) θ'( s ) ds
Y= β0+ C J b .
И если мы допустим и , наша модель будетξ = [ β 0Z = [ 1C J ]ξ = [ β0б']'
y = Z ξ
И это выглядит гораздо более знакомым для нас.
Теперь я вижу, что вы добавляете некоторую регуляризацию. fda
Пакет работает с шероховатостью штрафами формы
п= λ ∫[ L β( s ) ]2ds
для некоторого линейного дифференциального оператора . Теперь можно показать (подробности здесь опущены - это действительно не сложно показать), что если мы определим штрафную матрицу какRLр
R =λ ⎛⎝⎜⎜⎜⎜⎜00⋮00р1⋮0⋯⋯⋱⋯00⋮рК⎞⎠⎟⎟⎟⎟⎟
где в терминах базисного расширения , тогда мы минимизируем штрафную сумму квадратов:β iряβя
( у - Z ξ )'( y - Z ξ ) + λ ξ'R ξ ,
и поэтому наша проблема - всего лишь регрессия гребня с решением:
ξ^= ( Z'Z +λ R )- 1Z'Y .
Я прошел через вышесказанное, потому что, (1) я думаю, что важно, чтобы мы понимали, что мы делаем, и (2) некоторые из вышеперечисленных необходимы для понимания части кода, который я буду использовать позже. На коду ...
Вот пример данных с кодом R Я использую канадский набор данных о погоде, представленный в fda
пакете. Мы будем моделировать логарифм годовых осадков для ряда метеостанций с помощью функциональной линейной модели и будем использовать температурные профили (температуры регистрировались один раз в день в течение 365 дней) для каждой станции в качестве функциональных ковариат. Мы будем действовать так же, как вы описываете в вашей ситуации. Данные были зарегистрированы на 35 станциях. Я разделю набор данных на 34 станции, которые будут использоваться в качестве моих данных, и последнюю станцию, которая будет моим "новым" набором данных.
Я продолжаю через код R и комментарии (я предполагаю, что вы достаточно знакомы с fda
пакетом, так что ничто из следующего не является слишком удивительным - если это не так, пожалуйста, дайте мне знать):
# 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)
Теперь, когда год назад мне впервые рассказали о функциональных данных, я поиграл с этим пакетом. Я также был не в состоянии predict.fRegress
дать мне то, что я хотел. Оглядываясь назад, я все еще не знаю, как заставить его вести себя. Итак, нам просто нужно получить прогнозы полу-вручную. Я буду использовать части, которые я вытащил прямо из кода fRegress()
. Я снова продолжаю через код и комментарии.
Во-первых, установка:
# 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)
Теперь, чтобы получить прогнозы
Y^n e w= Zn e wξ^
Я просто беру код, который fRegress
использует для вычисления yhatfdobj
и немного его редактировать. fRegress
вычисляет yhatfdobj
путем оценки интеграла помощью правила трапеции (с и развернутыми в соответствующих базах). X i β∫T0Икся( s ) β( s )Иксяβ
Как правило, fRegress
вычисляет подогнанные значения, просматривая ковариаты, хранящиеся в annPrecTemp$xfdlist
. Так что для нашей проблемы, мы заменим этот ковариативный список с соответствующим одным в нашем новом списке ковариата, то есть templistNew
. Вот код (идентичный коду fRegress
с двумя правками, удалению ненужного кода и добавлению пары комментариев):
# 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
}
(примечание: если вы посмотрите на этот фрагмент и окружающий код fRegress
, вы увидите шаги, которые я описал выше).
Я протестировал код, повторно запустив пример погоды, используя все 35 станций в качестве наших данных, и сравнил вывод из вышеуказанного цикла с annPrecTemp$yhatfdobj
и все совпадает. Я также запускал его пару раз, используя разные станции в качестве «новых» данных, и все кажется разумным.
Дайте мне знать, если что-то из перечисленного неясно или что-то работает неправильно. Извините за слишком подробный ответ. Я не мог с собой поделать :) И если вы еще не владеете ими, посмотрите две книги, которые я использовал, чтобы написать этот ответ. Это действительно хорошие книги.