Dự đoán phản hồi từ các đường cong mới bằng gói fda trong R


10

Về cơ bản tất cả những gì tôi muốn làm là dự đoán một phản ứng vô hướng bằng cách sử dụng một số đường cong. Tôi đã thực hiện hồi quy (sử dụng fRegress từ gói fda) nhưng không biết làm thế nào để áp dụng kết quả vào một bộ đường cong MỚI (để dự đoán).

Tôi có N = 536 đường cong và 536 phản hồi vô hướng. Đây là những gì tôi đã làm cho đến nay:

  • Tôi đã tạo ra một cơ sở cho các đường cong.
  • Tôi đã tạo một đối tượng fdPar để giới thiệu một hình phạt
  • Tôi đã tạo đối tượng fd bằng cách sử dụng smooth.bocation để làm mịn các đường cong với hình phạt được chọn trên cơ sở đã chỉ định.
  • Tôi đã chạy hồi quy bằng fRegress (), hồi quy các đường cong trên phản hồi vô hướng.

Bây giờ, tất cả những gì tôi muốn làm là sử dụng hồi quy đó để đưa ra dự đoán cho một tập hợp dữ liệu mới mà tôi có. Tôi dường như không thể tìm thấy một cách dễ dàng để làm điều này.

Chúc mừng


Ngay cả một mô tả về cách tính toán các dự đoán theo cách thủ công từ cơ sở, các đối tượng được làm mịn (fd) và ước tính hồi quy từ fRegress () sẽ rất hữu ích.
dcl

Chỉ cần kiểm tra: bạn đã thử sử predict.fRegressdụng newdatatùy chọn (từ hướng dẫn fda ở đây ) chưa?

Tôi có, chỉ là tôi không chắc chắn chính xác về loại hoặc định dạng của 'newdata'. Nó sẽ không chấp nhận một đối tượng fd hoặc fdSmooth là các đường cong được làm mịn mà tôi muốn dự đoán từ đó. Và nó sẽ không cho phép tôi nhập các đối số thô và các giá trị đồng biến.
dcl

1
Tôi nhớ có một vấn đề tương tự khoảng một năm trước khi tôi chơi xung quanh với fdagói. Tôi đã viết một phản hồi liên quan đến việc nhận dự đoán bằng tay, nhưng một đoạn lớn của nó đã bị mất do không lưu nó. Nếu ai đó không đánh bại tôi, tôi sẽ có giải pháp cho bạn sau vài ngày.

Câu trả lời:


14

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+0TXi(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 fdagó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=λ(0000R1000RK)

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

(yZξ)(yZξ)+λξ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:

ξ^=(ZZ+λR)1Zy .

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 fdagó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 fdagó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ã fRegresssử dụng để tính toán yhatfdobjvà chỉnh sửa nó một chút. fRegresstính toán yhatfdobjbằ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). 0TXi(s)β(s)Xiβ

Thông thường, fRegresstí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 fRegresshai 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$yhatfdobjvà 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.


Điều này có vẻ như chính xác những gì tôi cần. Cảm ơn bạn. Tôi cho rằng tôi sẽ không phải chơi xung quanh với những thứ nfine / tine / deltat phải không? Tôi có nên cho rằng việc tích hợp đang được thực hiện đủ chính xác?
dcl

Ngoài ra, tôi nhận thấy rằng bạn đã không xử phạt đồng biến 'mới' hoặc 'cũ'. Tất cả đều được thực hiện với việc xử phạt beta (và số lượng các hàm cơ bản tôi đoán). Lambda hình phạt được áp dụng cho phiên bản beta. Bạn có đạt được hiệu quả tương tự bằng cách xử phạt các lần làm mịn trước khi hồi quy không? (có cùng giá trị của lambda)
dcl

1
Lưới được sử dụng để xấp xỉ tích phân là khá tốt, do đó, xấp xỉ sẽ khá tốt. Bạn luôn có thể tăng nfinevà xem có bao nhiêu thay đổi tích phân nhưng tôi đoán nó sẽ không làm được gì nhiều. Theo như hình phạt, có, chúng tôi sẽ trực tiếp xử phạt thay vì trong trường hợp này. Ramsay và Silverman thảo luận về một phương thức phạt khác ước tính mà không có các chức năng cơ bản nơi chúng tôi áp dụng hình phạt trực tiếp cho . Cả hai cách đều tạo ra một ràng buộc về độ mịn đối với các chức năng , nhưng tôi không chắc liệu bạn có nhận được 'hiệu ứng tương tự' hay không. ξββ^ββ

Tôi đã thử thao tác mã để đưa ra dự đoán cho nhiều đường cong, nhưng tôi không chắc mình đã thực hiện đúng. Đối với người mới bắt đầu, yhatmat không phải là hằng số cho tất cả các đường cong sau lần lặp đầu tiên của vòng lặp ... Điều này có nghĩa là tương đương với ? β0
dcl

1
@dcl Trong vòng lặp, khi , nó đang thêm vào (giả sử danh sách đầu tiên trong danh sách X của bạn tương ứng với thuật ngữ chặn). Bạn có thể thêm đoạn mã bạn đang sử dụng vào câu hỏi của mình để tôi có thể xem nó không? j=1β0^y^
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.