「半教師付き学習」-これは過剰適合ですか?


21

私は、Kaggleコンペティション(マルウェア分類)の勝利ソリューションのレポートを読んでいました。レポートはこのフォーラムの投稿にあります。問題は、トレインセットに10000個の要素、テストセットに10000個の要素がある分類問題(9つのクラス、メトリックは対数損失)でした。

競争中、モデルはテストセットの30%に対して評価されました。もう1つの重要な要素は、モデルのパフォーマンスが非常に優れていたことです(100%に近い精度)

著者は次の手法を使用しました。

もう1つの重要なテクニックは、半教師あり学習です。最初に、最適なモデルの最大確率を選択して、テストセットの擬似ラベルを生成します。次に、トレインデータとテストデータの両方を使用して、クロス検証方式でテストセットを再度予測します。たとえば、テストデータセットは4つのパートA、B、C、Dに分割されます。トレーニングデータ全体と、疑似ラベル付きのテストデータA、B、Cを新しいトレーニングセットとして使用し、テストを予測します。 Dを設定します

同じ方法を使用してA、B、Cを予測します。Xiaozhouによって発明されたこのアプローチは驚くほどうまく機能し、ローカルクロス検証損失、パブリックLB損失、プライベートLB損失を削減します。最高の半教師あり学習モデルは、プライベートLBログ損失で0.0023を達成できます。これは、すべてのソリューションで最高のスコアです。

結果をどのように改善できるのか、本当にわかりません。それは、テストセットの30%が「漏出」し、この情報を使用する方法だったからでしょうか。

それとも、なぜ機能するのかを説明する理論的な理由はありますか?

回答:


8

過剰適合しているようには見えません。直感的に、過剰適合とは、トレーニングセットの癖(ノイズ)へのトレーニングを意味し、したがって、これらの癖を共有していないテストセットでは悪化します。私が何が起こったのかを理解すれば、彼らは保留されたテストデータに対して予想外に悪いことをしなかったので、経験的に過剰適合を排除します。(それらには別の問題があり、最後に言及しますが、それは過剰適合ではありません。)

したがって、利用可能な(30%?)テストデータを利用するのは正しいことです。質問は次のとおりです。

使用可能なテストデータにラベルが関連付けられている場合は、それをトレーニングデータにまとめてトレーニングデータを拡大するだけで、一般的には明らかな方法でより良い結果が得られます。そこには本当の成果はありません。

精度スコアにアクセスできる場合、ラベルを明示的にリストする必要はありません。スコアを繰り返し送信することで、単純に精度の勾配を登ることができます。これは、デザインが不十分な競技で過去に行ったことです。

使用可能なテストデータにラベルが関連付けられていない場合(直接的または間接的に)、少なくとも2つの可能性があります。

第1に、これは、トレーニングデータのみの予測が含まれる擬似ラベル付きテストデータの予測と一致しない場合に焦点を当てている間接的なブースティング方法である可能性があります。

第二に、それは簡単な半教師付き学習である可能性があります。直感的に:ラベル付けされていないデータの密度を使用して、教師ありメソッドの分類境界の形成に役立てることができます。明確にするための半教師あり学習のウィキペディア定義の図(https://en.wikipedia.org/wiki/Semi-supervised_learning#/media/File:Example_of_unlabeled_data_in_semisupervised_learning.png)を参照してください

しかし、これはここにトリックがないという意味ではありません。そして、その秘は、トレーニングとテストデータの定義にあります。原則として、トレーニングデータは、モデルを展開する準備ができたときに手元にあるデータを表します。また、テストデータは、システムが稼働状態になるとシステムに送られる将来のデータを表します。

その場合、テストデータのトレーニングは、まだ見たことのないデータを利用している未来からのリークです。これは、現実の世界では大きな問題であり、いくつかの変数は事実の後まで(たとえば、調査が行われた後)存在しないか、後日更新される可能性があります。

そこで彼らはここでメタゲーミングしています。彼らがしたことは、いくつかのテストデータへのアクセスを与えられたので、競争のルールの範囲内で合法です。しかし、現実の世界では合法ではありません。実際のテストは、新しいデータに対する将来のテストです。


2

いいえ、過剰適合ではありません。

ここでのあなたの心配は、モデルがデータをモデル化するのではなく、心を痛めていることです。これは、モデルの複雑さ(同じまま)とデータのサイズに依存します。これは、モデルが複雑すぎる場合、および/またはトレーニングデータが小さすぎる場合に発生しますが、どちらもここでは当てはまりません。半教師あり学習後にテストエラー(クロス検証エラー)が最小化されるという事実は、過剰適合ではないことを意味するはずです。

このようなアプローチが機能している理由について
ここで使用されているアプローチは、非世界的なものではなく、多くの人々が多くの機械学習競技会でこれをしているのを見ました(申し訳ありませんが、私はこれを見た場所を思い出せません)。
テストデータの一部を予測し、それをトレーニングに含めると、モデルは新しい機能にさらされます。この場合、テストデータはトレーニングデータと同じ大きさであり、半教師あり学習によって多くのデータが得られるのも不思議ではありません。

これで
ありがとう


「モデル」を明確に定義する必要があります。これは、一般化された自由度(pegasus.cc.ucf.edu/~lni/sta6236/Ye1998.pdf)の問題全体によく似ています。誰かが「最終モデル」を指し示します。プロセスには多くの複雑さが詰め込まれています。私の本能は、プロセスの残りの部分を無視して「最終モデル」を指し、それが半教師付きステップなしの「最終モデル」よりも複雑ではないと主張し、次に進むことはできないということです。あなたが言うように、サンプル外のテスト結果の改善良い指標です。
ウェイン

2

(定義による)過剰なフィッティングではありません。テストセットのターゲット情報は保持されます。半教師付きにより、モデルをトレーニングするための追加の合成データセットを生成できます。記述されたアプローチでは、元のトレーニングデータは比率4:3で合成された重みなしで混合されます。したがって、合成データの品質が低い場合、このアプローチは悲惨な結果になります。予測が不確実な問題については、合成データセットの精度が低いと思います。基礎となる構造が非常に複雑で、システムのノイズが低い場合、合成データの生成に役立つ可能性があります。ディープラーニング(私の専門知識ではない)では、半教師あり学習が非常に大きいと考えています。ここでは、機能表現も学習します。

rfとxgboostの両方を使用して、いくつかのデータセットで半教師付きトレーニングを行い、確度の高い結果が得られず、精度の向上を再現しようとしました。[コードを自由に編集してください。]半監視を使用した場合の精度の実際の改善は、Kaggleレポートではかなり控えめで、多分ランダムですか?

rm(list=ls())
#define a data structure
fy2 = function(nobs=2000,nclass=9) sample(1:nclass-1,nobs,replace=T)
fX2 = function(y,noise=.05,twist=8,min.width=.7) {
  x1 = runif(length(y)) * twist
  helixStart = seq(0,2*pi,le=length(unique(y))+1)[-1]
  x2 = sin(helixStart[y+1]+x1)*(abs(x1)+min.width) + rnorm(length(y))*noise
  x3 = cos(helixStart[y+1]+x1)*(abs(x1)+min.width) + rnorm(length(y))*noise
  cbind(x1,x2,x3)
}

#define a wrapper to predict n-1 folds of test set and retrain and predict last fold  
smartTrainPred = function(model,trainX,trainy,testX,nfold=4,...) {
  obj = model(trainX,trainy,...)
  folds = split(sample(1:dim(trainX)[1]),1:nfold)
  predDF = do.call(rbind,lapply(folds, function(fold) {
    bigX      = rbind(trainX ,testX[-fold,])
    bigy      = c(trainy,predict(obj,testX[-fold,]))
    if(is.factor(trainy)) bigy=factor(bigy-1)
    bigModel  = model(bigX,bigy,...)
    predFold  = predict(bigModel,testX[fold,])
    data.frame(sampleID=fold, pred=predFold)
  }))
  smartPreds = predDF[sort(predDF$sampleID,ind=T)$ix,2]
}

library(xgboost)
library(randomForest)

#complex but perfect separatable
trainy = fy2(); trainX = fX2(trainy)
testy  = fy2();  testX = fX2(testy )
pairs(trainX,col=trainy+1)

ここに画像の説明を入力してください

#try with randomForest
rf = randomForest(trainX,factor(trainy))
normPred = predict(rf,testX)
cat("\n supervised rf", mean(testy!=normPred))
smartPred = smartTrainPred(randomForest,trainX,factor(trainy),testX,nfold=4)
cat("\n semi-supervised rf",mean(testy!=smartPred))

#try with xgboost
xgb = xgboost(trainX,trainy,
              nrounds=35,verbose=F,objective="multi:softmax",num_class=9)
normPred = predict(xgb,testX)
cat("\n supervised xgboost",mean(testy!=normPred))

smartPred = smartTrainPred(xgboost,trainX,trainy,testX,nfold=4,
                           nrounds=35,verbose=F,objective="multi:softmax",num_class=9)
cat("\n semi-supervised xgboost",mean(testy!=smartPred))



printing prediction error:
 supervised rf 0.007
 semi-supervised rf 0.0085
 supervised xgboost 0.046
 semi-supervised xgboost 0.049

1

この定義では、「統計モデルが基礎となる関係の代わりにランダムなエラーまたはノイズを記述するときにオーバーフィットが発生します。」(wikipedia)、ソリューションはオーバーフィットではありません。

ただし、この状況では:
-テストデータはアイテムのストリームであり、アイテムの固定セットではありません。
または
-予測プロセスに学習段階を含めるべきではありません(たとえば、パフォーマンスの問題のため)

上記のソリューションは過剰適合です。モデリングの精度は実際の状況以上のものだからです。

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