1

これがCrossValidatedでより適している場合はお詫びします。

Rのmgcvパッケージを使用してGAMモデルを二項データに適合させています。共変量の1つは周期的であるため、bs = "cc"循環3次スプラインを指定しています。相互検証フレームワークでこれを行っていますが、predict関数を使用してホールドアウトデータを適合させると、次のエラーが発生します。

Error in pred.mat(x, object$xp, object$BD) : 
  can't predict outside range of knots with periodic smoother

エラーを再現する必要があるコードは次のとおりです。

# generate data:
x <- runif(100,min=-pi,max=pi)
linPred <- 2*cos(x) # value of the linear predictor
theta <- 1 / (1 + exp(-linPred)) # 
y <- rbinom(100,1,theta)
plot(x,theta)
df <- data.frame(x=x,y=y)

# fit gam with periodic smoother:
gamFit <- gam(y ~ s(x,bs="cc",k=5),data=df,family=binomial())
summary(gamFit)

plot(gamFit)

# predict y values for new data:
x.2 <- runif(100,min=-pi,max=pi)
df.2 <- data.frame(x=x.2)
predict(gamFit,newdata=df.2)

私がどこで間違っているのかについての提案は大歓迎です。たぶん、-piとpiに該当するノットを手動で指定しますか?

4

2 に答える 2

2

最初の実行ではエラーは発生しませんでしたが、2回目の試行ではエラーを再現しました。おそらく、とを使用する必要がありset.seed(123) #{no error}ますset.seed(223) #{produces error}。それが部分的な成功を生み出すかどうかを確認します。派生データセットと検証データセットのポイント数が比較的少ないバリエーションが見られていると思います。GAMフィットの100ポイントは、特に「寛大」ではありません。

gamFitオブジェクトを見ると、ノットの範囲がでエンコードされているgamFit$smooth[[1]]['xp']ように見えるので、これにより入力が適切な範囲に制限されます。

 x.2 <- runif(100,min=-pi,max=pi); 
 x.2 <- x.2[findInterval(x.2, range(gamFit$smooth[[1]]['xp']) )== 1]

 # Removes the errors in all the situations I tested
 # There were three points outside the range in the set.seed(223) case
于 2012-07-31T22:17:04.973 に答える
1

問題は、テスト セットにトレーニング セットの範囲外の値が含まれていることです。スプラインを使用したため、ノットは の最小値と最大値で作成され、x近似関数はその範囲外では定義されていません。したがって、モデルをテストするときは、範囲外のポイントを除外する必要があります。テスト セット内のポイントを除外する方法は次のとおりです。

set.seed(2)
... <Your code>
predict(gamFit,newdata=df.2[df.2$x>=min(df$x) & df.2$x<=max(df$x),,drop=F])

または、モデル内の「外側」ノット ポイントをデータ全体の最小値と最大値に指定することもできます。私はそれをオフハンドで行う方法がわかりません。

于 2012-07-31T22:37:34.083 に答える