Rのfdaパッケージを使用して新しい曲線からの応答を予測する


10

基本的には、いくつかの曲線を使用してスカラー応答を予測するだけです。私は(fdaパッケージのfRegressを使用して)回帰を行っていますが、結果を新しい曲線セット(予測用)に適用する方法がわかりません。

N = 536の曲線と536のスカラー応答があります。これまでに行ったことは次のとおりです。

  • カーブのベースを作成しました。
  • ペナルティを導入するためにfdParオブジェクトを作成しました
  • 指定したペナルティで選択したペナルティでカーブを滑らかにするために、smooth.basisを使用してfdオブジェクトを作成しました。
  • 私はfRegress()を使用して回帰を実行し、スカラー応答の曲線を回帰しました。

さて、私がやりたいのは、その回帰を使用して、私が持っている新しいデータセットの予測を生成することです。これを行う簡単な方法を見つけることができないようです。

乾杯


基礎、平滑化された(fd)オブジェクト、およびfRegress()からの回帰推定から手動で予測を計算する方法の説明も非常に役立ちます。
dcl、2011年

ただ確認する:(ここのfdaマニュアルから)オプションをpredict.fRegress使用してみましたか?newdata

私が持っているのは、「newdata」がどのクラスまたはフォーマットでなければならないかが正確にわからないだけです。予測したい平滑化曲線であるfdまたはfdSmoothオブジェクトを受け入れません。また、生の引数や共変量の値を入力することもできません。
dcl、2011年

1
1年ほど前にfdaパッケージをいじったときに同様の問題があったことを覚えています。予測を手動で取得することを含む応答を作成していましたが、それを保存しなかったため、その大部分が失われました。他の誰かが私に打ち負かさない場合、私は数日であなたのための解決策を持っているはずです。

回答:


14

Inceptionのようなlist-within-list-within-listオブジェクト構造fdaの使用については気にしませんが、私の応答は、パッケージ作成者が作成したシステムに従います。

私たちが正確に何をしているかを最初に考えることは有益だと思います。あなたがこれまでに行ったことの説明に基づいて、これはあなたがやっていると私が信じていることです(私が何かを誤って解釈した場合はお知らせください)。私は表記法を使い続けますが、実際のデータが不足しているため、RamsayとSilvermanの関数型データ分析、Ramsay、Hooker、およびGravesのRとMATLABを使用した関数型データ分析の例 (次の方程式とコードの一部は直接持ち上げられます)これらの本から)。

機能的な線形モデルを介してスカラー応答をモデル化しています。

yi=β0+0TXi(s)β(s)ds+ϵi

βK

β(s)=k=1Kbkθk(s)

行列表記では、これはです。β(s)=θ(s)b

また、共変量関数もいくつかの基底で拡張します(基底関数など)。そう、L

Xi(s)=k=1Lcikψk(s)

繰り返しますが、行列表記では、これはです。X(s)=Cψ(s)

したがって、とすると、モデルは次のように表すことができます。J=ψ(s)θ(s)ds

y=β0+CJb

そして、およびとすると、モデルはZ=[1CJ]ξ=[β0b]

y=Zξ

そして、これは私たちにとってより身近に見えます。

今、あなたはある種の正則化を追加しているのがわかります。fdaパッケージには、フォームの粗さのペナルティで動作します

P=λ[Lβ(s)]2ds

線形微分演算子。これで、ペナルティマトリックスを次のように定義するとLR

R=λ(0000R1000RK)

ここで、は基底展開に関するものであり、ペナルティ付き二乗和を最小化します。Riβi

(yZξ)(yZξ)+λξRξ

したがって、私たちの問題は、ソリューションの尾根回帰にすぎません。

ξ^=(ZZ+λR)1Zy

(1)私たちが何をしているかを理解することが重要であると思います、そして(2)上記のいくつかは、後で使用するコードのいくつかを理解するために必要です。コードに...

Rコードを使用したデータの例を次に示します。fdaパッケージで提供されているカナダの気象データセットを使用しています。関数型線形モデルを使用して、多数の気象観測所の年間降水量のログをモデル化し、関数型共変量として各観測所からの温度プロファイル(温度は1日1回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)

1年ほど前に機能データについて初めて教えられたとき、私はこのパッケージをいじりました。また、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^new=Znewξ^

fRegress計算yhatfdobjして少し編集するために使用するコードを取り上げます。 台形規則(とがそれぞれの基底で展開されているを介して積分を推定するfRegressことyhatfdobjによって計算します。 0TXi(s)β(s)Xiβ

通常、にfRegress格納されている共変量をループすることにより、近似値を計算しannPrecTemp$xfdlistます。したがって、問題については、この共変量リストを新しい共変量リストの対応するもの、つまりに置き換えtemplistNewます。これがコードです(fRegress2つの編集、不要なコードのいくつかの削除、およびいくつかのコメントが追加されているで見つかったコードと同じ):

# 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、すべてが一致するようにしました。私はまた、「新しい」データとしてさまざまなステーションを使用して数回実行しましたが、すべてが妥当であるようです。

上記のいずれかが不明確な場合や、正しく機能していない場合はお知らせください。過度に詳細な応答でごめんなさい。私は自分自身を助けることができませんでした:)そして、あなたがまだそれらを所有していない場合は、この応答を書くために使用した2冊の本をチェックしてください。彼らは本当に良い本です。


これはまさに私が必要としているもののようです。ありがとうございました。私はnfine / tine / deltatのものをいじる必要がないと思いますか?統合は十分正確に行われていると思いますか?
dcl、2011年

また、「新しい」共変量または「古い」共変量に直接ペナルティを課していないことにも気づきました。それはすべて、ペナルティベータ(および私が推測する基底関数の数)で行われます。ペナルティラムダがベータに適用されます。回帰の前にスムースにペナルティを課すことで同じ効果を達成しますか?(ラムダの値は同じ)
dcl

1
積分の近似に使用されるグリッドはかなり細かいので、近似はかなり良いはずです。あなたは常に増加nfineし、積分がどれだけ変化するかを見ることができますが、私はそれがあまり効果がないと思います。ペナルティに関しては、はい、この場合、ではなく直接ペナルティを課しています。RamsayとSilverman は、ペナルティを直接適用する基底関数なしでを推定する別のペナルティメソッドについて説明します。両方の方法で関数に滑らかさの制約が生じますが、「同じ効果」が得られるかどうかはわかりません。ξββ^ββ

コードを操作して複数の曲線の予測を生成しようとしましたが、正しく実行したかどうかはわかりません。手始めに、ループの最初の反復後のyhatmatはすべての曲線に対して一定ではありません...これはと同等であることを意味しますか?β0
dcl、2011年

1
@dclループでは、場合、が追加されます(Xlistの最初のリストが切片の項に対応していると想定)。使用しているコードのスニペットを質問に追加して、それを確認できますか?j=1β0^y^
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.