ランダムフォレスト:テストセットで新しい因子レベルを処理する方法


13

Rのランダムフォレストモデルを使用して予測しようとしています。

ただし、テストセットとトレーニングセットでは値が異なる要因があるため、エラーが発生します。たとえば、因子にCat_234, 68, 76、トレーニングセットに表示されないテストセットの値などがあります。残念ながら、テストセットを制御することはできません...そのまま使用する必要があります。

私の唯一の回避策は、問題のある要素を数値に変換して戻すことas.numeric()でした。それは機能しますが、これらの値は数値的な意味を持たないコードであるため、私はあまり満足していません...

テストセットから新しい値を削除する別の解決策があると思いますか?ただし1, 2, 14, 32、トレーニングとテストの両方にあり、予測に役立つ可能性のある情報を含む他のすべての因子値(たとえば、値など)を削除することはありません。


1
テストの値をトレーニングセットに含める必要がある理由はわかっています。分類の考え方は、トレーニングデータを使用して、クラス条件付き密度がどのように見えるかを把握することです。密度から考えられるすべての値が表示されるわけではありません。ツリー上の分割で変数が使用され、分割により、未表示の値と表示されている値のどちらに続くブランチが決定されるか。
マイケルR.チェルニック

有効なポイントを作成しますが、実際のレベルでは(RのRFパッケージ)について問い合わせた特定のツールを使用することは許可されていません。代入を含む私の答えはそれを回避する1つの方法ですが、確かに最良の解決策ではありません。Isは少なくともコードをクラッシュさせないので、小さな値の作業に対しては少なくとも機能します。
Bogdanovist

ここに私の質問に似ています:stats.stackexchange.com/questions/18004/…。RFの代わりにGBMを使用する可能性があります。新しい因子レベルをよりうまく処理できるように思えるからです。また、パーティでのRFの実装を検討しましたか?これらの問題(および欠損値をシームレスに処理できないこと)のため、私はrandomForestが好きではありませんでした。
B_Miner

回答:


2

テストセットに新しい係数値を含むこれらのポイントが多数ある場合、最適なアプローチが何であるかはわかりません。それがほんの一握りのポイントである場合、誤った因子レベルを欠損データとして扱い、適切と思われるあらゆるアプローチでそれらを補完するような、なんとなく抜け出すことができるかもしれません。Rの実装には、欠損データを補完するいくつかの方法があります。これらの因子レベルをNAに設定して、欠損データを示す必要があります。


8

KingBonoit、このスニペットはレベルを調和させるのに役立ちます:

for(attr in colnames(training))
{
  if (is.factor(training[[attr]]))
  {
    new.levels <- setdiff(levels(training[[attr]]), levels(testing[[attr]]))
    if ( length(new.levels) == 0 )
    { print(paste(attr, '- no new levels')) }
    else
    {
      print(c(paste(attr, length(new.levels), 'of new levels, e.g.'), head(new.levels, 2)))
      levels(testing[[attr]]) <- union(levels(testing[[attr]]), levels(training[[attr]]))
    }
  }
}

また、どの属性が変更されたかを出力します。もっとエレガントに(ldplyなどを使って)書く良い方法を見つけられませんでした。どんなヒントでも大歓迎です。


4

上記の@Kingの応答に対処するために作成したコードを次に示します。エラーを修正しました:

# loops through factors and standardizes the levels
for (f in 1:length(names(trainingDataSet))) {
    if (levels(testDataSet[,f]) > levels(trainingDataSet[,f])) {    
            levels(testDataSet[,f]) = levels(trainingDataSet[,f])       
    } else {
            levels(trainingDataSetSMOTEpred[,f]) = levels(testDataSet[,f])      
    }
}

こんにちは@ifarb、私はあなたの解決策を理解しようとしています:何がtrainingDataSetSMOTEpredであり、コードのどこで定義されていますか?
カシアクルマ

3

テストとトレーニングセットを1つのセットとして組み合わせてから、トレーニングセットのレベルを変更する必要があります。私のコードは次のとおりです。

totalData <- rbind(trainData, testData)
for (f in 1:length(names(totalData))) {
  levels(trainData[, f]) <- levels(totalData[, f])
}

これは、テストのレベル数がトレーニングよりも多いか少ない場合に機能します。


2

RでrandomForestを使用する場合、お粗末な回避策があります。おそらく理論的には健全ではありませんが、実行されます。

levels(testSet$Cat_2) = levels(trainingSet$Cat_2)

またはその逆。基本的に、Rに0の場合があるだけで有効な値であることを伝えます。だから、エラーについて私を盗聴するのを止めてください。

私は、すべてのカテゴリ機能に対してアクションを自動的に実行するようにコーディングするほど賢くはありません。方法がわかればコードを送ってください...


ただし、テストのレベル数がトレーニング以上の場合、これは機能しません。テストデータファクタレベルがトレーニングデータファクタレベル以下の場合にのみ機能します。
KarthikS

1

これが当てはまる場合は、すでに考えたことがあると思いますが、テストセットに実際の値があり、クロス検証目的でテストセットを使用している場合は、データフレームをトレーニングおよびテストデータフレームに再分割しますこれら2つの要素のバランスが取れていれば、問題を回避できます。この方法は、一般に成層交差検定として知られています。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.