34

モデルを因子データに適合させて予測しています。newdatainpredict.lm()にモデルにとって未知の因子レベルが 1 つ含まれている場合、すべてpredict.lm()失敗し、エラーが返されます。

predict.lm()エラーだけでなく、モデルが知っている因子レベルの予測と未知の因子レベルの NA を返す良い方法はありますか?

コード例:

foo <- data.frame(response=rnorm(3),predictor=as.factor(c("A","B","C")))
model <- lm(response~predictor,foo)
foo.new <- data.frame(predictor=as.factor(c("A","B","C","D")))
predict(model,newdata=foo.new)

NA最後のコマンドで、因子レベル「A」、「B」、「C」に対応する 3 つの「実際の」予測と、未知のレベル「D」に対応する予測を返したいと思います。

4

7 に答える 7

29

次のように、計算の前に余分なレベルを削除する必要があります。

> id <- which(!(foo.new$predictor %in% levels(foo$predictor)))
> foo.new$predictor[id] <- NA
> predict(model,newdata=foo.new)
         1          2          3          4 
-0.1676941 -0.6454521  0.4524391         NA 

これはより一般的な方法で、元のデータにないすべてのレベルを NA に設定します。ハドリーがコメントで述べたように、predict()関数にこれを含めることを選択できたかもしれませんが、そうしませんでした

なぜそれをしなければならないのかは、計算自体を見れば明らかです。内部的には、予測は次のように計算されます。

model.matrix(~predictor,data=foo) %*% coef(model)
        [,1]
1 -0.1676941
2 -0.6454521
3  0.4524391

下部には、両方のモデル マトリックスがあります。の 1 つに余分な列があることがわかりますfoo.new。そのため、行列計算はもう使用できません。新しいデータセットを使用してモデル化すると、別のモデルも得られます。つまり、追加のレベル用の追加のダミー変数を持つモデルになります。

> model.matrix(~predictor,data=foo)
  (Intercept) predictorB predictorC
1           1          0          0
2           1          1          0
3           1          0          1
attr(,"assign")
[1] 0 1 1
attr(,"contrasts")
attr(,"contrasts")$predictor
[1] "contr.treatment"

> model.matrix(~predictor,data=foo.new)
  (Intercept) predictorB predictorC predictorD
1           1          0          0          0
2           1          1          0          0
3           1          0          1          0
4           1          0          0          1
attr(,"assign")
[1] 0 1 1 1
attr(,"contrasts")
attr(,"contrasts")$predictor
[1] "contr.treatment"

モデル マトリックスから最後の列を削除することもできません。削除しても、他の両方のレベルが影響を受けるからです。レベルのコードはA(0,0) です。Bこれは (1,0) であり、これはC(0,1)Dであり、また (0,0) です! したがって、最後のダミー変数を素朴に削除する場合、モデルは と が同じレベルであるAと想定します。D

より理論的な部分では、すべてのレベルがなくてもモデルを構築できます。さて、前に説明しようとしたように、そのモデルは、モデルを構築するときに使用したレベルに対してのみ有効です。新しいレベルに遭遇した場合は、新しいモデルを構築して追加情報を含める必要があります。そうしないと、余分なレベルをデータセットから削除するしかありません。しかし、基本的にそこに含まれていたすべての情報が失われるため、一般的には良い方法とは見なされません。

于 2010-11-26T12:38:41.667 に答える
6

lm モデルを作成した後、predict を呼び出す前にデータの不足しているレベルに対処したい場合 (事前にどのレベルが不足している可能性があるか正確にはわからないため)、ここに、モデルから NA - 予測でも NA が得られるため、別の方法を使用してこれらの値を予測できます。

objectは lm(...,data=trainData) からの lm 出力になります

dataは、予測を作成するデータ フレームになります。

missingLevelsToNA<-function(object,data){

  #Obtain factor predictors in the model and their levels ------------------

  factors<-(gsub("[-^0-9]|as.factor|\\(|\\)", "",names(unlist(object$xlevels))))
  factorLevels<-unname(unlist(object$xlevels))
  modelFactors<-as.data.frame(cbind(factors,factorLevels))


  #Select column names in your data that are factor predictors in your model -----

  predictors<-names(data[names(data) %in% factors])


  #For each factor predictor in your data if the level is not in the model set the value to NA --------------

  for (i in 1:length(predictors)){
    found<-data[,predictors[i]] %in% modelFactors[modelFactors$factors==predictors[i],]$factorLevels
    if (any(!found)) data[!found,predictors[i]]<-NA
  }

  data

}
于 2016-09-14T16:29:51.017 に答える