Tôi không quan tâm cho fda
's sử dụng Inception -like cấu trúc đối tượng list-trong-list-trong-list, nhưng phản ứng của tôi sẽ tuân theo hệ thống các tác giả gói đã tạo.
Tôi nghĩ rằng đó là hướng dẫn để đầu tiên nghĩ về những gì chúng ta đang làm chính xác. Dựa trên mô tả của bạn về những gì bạn đã làm cho đến nay, đây là những gì tôi tin rằng bạn đang làm (hãy cho tôi biết nếu tôi đã giải thích sai điều gì đó). Tôi sẽ tiếp tục sử dụng ký hiệu và do thiếu dữ liệu thực, một ví dụ từ Phân tích dữ liệu chức năng của Ramsay và Silverman và Phân tích dữ liệu chức năng của Ramsay, Hooker và Graves với R và MATLAB (Một số phương trình và mã sau đây được gỡ bỏ trực tiếp từ những cuốn sách này).
Chúng tôi đang mô hình hóa một phản ứng vô hướng thông qua một mô hình tuyến tính chức năng, tức là
yi=β0+∫T0Xi(s)β(s)ds+ϵi
βK
β(s)=∑k=1Kbkθk(s)
Trong ký hiệu ma trận, đây là .β(s)=θ′(s)b
Chúng tôi cũng mở rộng các hàm đồng biến trong một số cơ sở (giả sử các hàm cơ sở ). Vì thế,L
Xi(s)=∑k=1Lcikψk(s)
Một lần nữa, trong ký hiệu ma trận, đây là .X(s)=Cψ(s)
Và do đó, nếu chúng ta để , mô hình của chúng ta có thể được biểu thị dưới dạngJ=∫ψ(s)θ′(s)ds
y=β0+CJb .
Và nếu chúng ta để và , mô hình của chúng tôi làZ=[1CJ]ξ=[β0b′]′
y=Zξ
Và điều này có vẻ quen thuộc hơn nhiều đối với chúng tôi.
Bây giờ tôi thấy bạn đang thêm một số loại chính quy. Các fda
gói làm việc với hình phạt nhám có dạng
P=λ∫[Lβ(s)]2ds
đối với một số tuyến tính điều hành khác biệt . Bây giờ nó có thể được hiển thị (chi tiết còn sót lại ở đây - thực sự không khó để thể hiện điều này) rằng nếu chúng ta xác định ma trận phạt làLR
R=λ⎛⎝⎜⎜⎜⎜⎜00⋮00R1⋮0⋯⋯⋱⋯00⋮RK⎞⎠⎟⎟⎟⎟⎟
Trong đó là về việc mở rộng cơ sở của , thì chúng tôi giảm thiểu tổng bình phương bị phạt:Riβi
(y−Zξ)′(y−Zξ)+λξ′Rξ ,
và vì vậy, vấn đề của chúng tôi chỉ đơn thuần là hồi quy sườn núi với giải pháp:
ξ^=(Z′Z+λR)−1Z′y .
Tôi đã đi qua phần trên bởi vì, (1) Tôi nghĩ điều quan trọng là chúng ta hiểu những gì chúng ta đang làm và (2) một số điều trên là cần thiết để hiểu một số mã tôi sẽ sử dụng sau này. Bật mã ...
Đây là một ví dụ dữ liệu với mã R. Tôi đang sử dụng bộ dữ liệu thời tiết Canada được cung cấp trong fda
gói. Chúng tôi sẽ lập mô hình lượng mưa hàng năm cho một số trạm thời tiết thông qua mô hình tuyến tính chức năng và chúng tôi sẽ sử dụng các cấu hình nhiệt độ (nhiệt độ được ghi lại một lần một ngày trong 365 ngày) từ mỗi trạm như là các biến số chức năng. Chúng tôi sẽ tiến hành tương tự như cách bạn mô tả trong tình huống của bạn. Dữ liệu được ghi nhận tại 35 trạm. Tôi sẽ chia tập dữ liệu thành 34 trạm, dữ liệu này sẽ được sử dụng làm dữ liệu của tôi và trạm cuối cùng, đây sẽ là tập dữ liệu "mới" của tôi.
Tôi tiếp tục thông qua mã R và nhận xét (Tôi cho rằng bạn đã đủ quen thuộc với fda
gói sao cho không có gì sau đây là quá ngạc nhiên - nếu đây không phải là trường hợp, vui lòng cho tôi biết):
# 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)
Bây giờ khi tôi lần đầu tiên được dạy về dữ liệu chức năng cách đây một năm, tôi đã chơi xung quanh với gói này. Tôi cũng không thể có được predict.fRegress
để cho tôi những gì tôi muốn. Bây giờ nhìn lại, tôi vẫn không biết làm thế nào để nó hoạt động. Vì vậy, chúng ta sẽ phải có được các dự đoán bán thủ công. Tôi sẽ sử dụng các phần mà tôi đã rút thẳng ra khỏi mã cho fRegress()
. Một lần nữa, tôi tiếp tục thông qua mã và ý kiến.
Đầu tiên, thiết lập:
# 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)
Bây giờ để có được dự đoán
y^new=Znewξ^
Tôi chỉ lấy mã fRegress
sử dụng để tính toán yhatfdobj
và chỉnh sửa nó một chút. fRegress
tính toán yhatfdobj
bằng cách ước tính tích phân thông qua quy tắc hình thang (với và mở rộng trong các cơ sở tương ứng của chúng). ∫T0Xi(s)β(s)Xiβ
Thông thường, fRegress
tính toán các giá trị được trang bị bằng cách lặp qua các hiệp phương được lưu trữ trong annPrecTemp$xfdlist
. Vì vậy, đối với vấn đề của chúng tôi, chúng tôi thay thế danh sách đồng biến này bằng danh sách đồng biến tương ứng trong danh sách đồng biến mới của chúng tôi, nghĩa là , templistNew
. Đây là mã (giống hệt mã được tìm thấy trong fRegress
hai lần chỉnh sửa, một số xóa mã không cần thiết và thêm một vài nhận xét):
# 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
}
(lưu ý: nếu bạn nhìn vào đoạn mã này và mã xung quanh fRegress
, bạn sẽ thấy các bước tôi đã nêu ở trên).
Tôi đã kiểm tra mã bằng cách chạy lại ví dụ thời tiết bằng cách sử dụng tất cả 35 trạm làm dữ liệu của chúng tôi và so sánh đầu ra từ vòng lặp trên annPrecTemp$yhatfdobj
và mọi thứ khớp với nhau. Tôi cũng đã chạy nó một vài lần bằng cách sử dụng các trạm khác nhau làm dữ liệu "mới" của mình và mọi thứ có vẻ hợp lý.
Hãy cho tôi biết nếu bất kỳ điều nào ở trên không rõ ràng hoặc nếu bất cứ điều gì không hoạt động chính xác. Xin lỗi vì phản ứng quá chi tiết. Tôi không thể tự giúp mình :) Và nếu bạn chưa sở hữu chúng, hãy xem hai cuốn sách tôi đã sử dụng để viết phản hồi này. Chúng thực sự là những cuốn sách hay.