モデルの選択と相互検証:正しい方法


34

CrossValidatedには、モデルの選択と相互検証のトピックに関する多数のスレッドがあります。以下にいくつかを示します。

ただし、これらのスレッドに対する回答はかなり一般的であり、主にクロス検証とモデル選択の特定のアプローチに関する問題を強調しています。

ようなものを作るために、可能な限り具体的な、我々はRBFカーネルをSVMで作業していること、たとえば言う: 、及びそのフィーチャXとラベルyのデータセットがあり、それをしたいK(x,x)=(γ|xx|)2

  1. モデルの可能な限り最良の値を見つける(およびγC
  2. データセットを使用してSVMをトレーニングします(最終展開用)
  3. 一般化誤差とこの誤差の周りの不確実性(分散)を推定する

そうするために、私は個人的にグリッド検索を行います。例えば、とあらゆる可能な組み合わせを試し ます。簡単にするために、次の範囲を想定できます。Cγ

  • C{10,100,1000}
  • γ{0.1,0.2,0.5,1.0}

具体的には、完全なデータセットを使用して、次のことを行います。

  1. すべての(のためにCγ)のペア、私は、の繰り返し(例えば100回のランダム繰り返し)繰り返しんKクロスバリデーションを倍(例えばK=10)、私のデータセットに、すなわち私は上の私のSVM訓練K1折り目をし、評価左の折り畳みにエラーがあり、すべてのK折り畳みを繰り返します。全体として、100 x 10 = 1000個のテストエラーを収集します。
  2. そのような(Cγ)ペアごとに、これらの1000個のテストエラー\ mu_M、\ sigma_Mの平均と分散を計算しμM,σMます。

次に、完全なデータセットで最終的なSVMをトレーニングするために使用する最適なモデル(最適なカーネルパラメーター)を選択します。私の理解では、最小誤差平均と分散 μMおよびσMを持つモデルを選択することが正しい選択であり、このモデルのμMσMは、完全なデータセット。

しかし、上記のスレッドの回答を読んだ後、私はこの方法が配備および/またはそのエラー(一般化パフォーマンス)を推定するための最良のSVMを選択するためのこの方法は欠陥であり、選択するより良い方法があるという印象を受けています最高のSVMとそのエラーの報告。もしそうなら、彼らは何ですか?具体的な答えを探しています。

この問題に固執して、どのようにして具体的に最良のモデルを選択し、その一般化エラー適切に推定できますか?


できるだけ具体的にするために、データセットに統計的に独立したケースがいくつあるか教えてください。最適化のために評価するターゲット関数は何ですか/どのようなエラー測定を使用しますか?パラメータグリッド上で、選択したエラー測定値の一貫した動作を実際に観察していますか?分類について話している場合、エラー測定でこれが可能になります:反復交差検証結果は、サンプルサイズが有限であるために予想される(しかし測定できない)分散と比較する方法は?
cbeleitesはモニカをサポートします

あなたが興味深い見つけることが記事:optimalprediction.com/files/pdf/V2A5.pdf
user31256

2
非常に明確で詳細な質問、およびデータサイエンスコミュニティ全体に非常に関連性の高い質問に対して+1。
-NickBraunagel

回答:


20

JMLRでの私の論文はこの正確な質問に対処し、質問で提案された手順(または少なくとも1つの非常によく似た手順)が楽観的に偏ったパフォーマンス推定をもたらす理由を示しています。

Gavin C. Cawley、Nicola LC Talbot、「パフォーマンス評価におけるモデル選択とその後の選択バイアスの過剰適合」、Journal of Machine Learning Research、11(Jul):2079-2107、2010。(www

覚えておくべき重要なことは、交差検証は、モデル自体ではなく、モデルを生成する方法の一般化パフォーマンスを推定する手法であることです。そのため、カーネルパラメーターの選択がモデルの生成プロセスの一部である場合、モデル選択プロセスも相互検証する必要があります。そうしないと、楽観的に偏ったパフォーマンス推定値になります(提案する手順で発生します)。

関数fit_modelがあり、属性Xと目的の応答Yで構成されるデータセットを受け取り、ハイパーパラメーター(この場合はカーネルと正則化パラメーター)の調整を含む、そのデータセットの近似モデルを返すと仮定します。ハイパーパラメーターのこの調整は、XおよびTでの相互検証エラーの最小化など、さまざまな方法で実行できます。

手順1-関数fit_modelを使用して、使用可能なすべてのデータにモデルを適合させます。これにより、操作で使用するモデルが得られます。

ステップ2-パフォーマンス評価。利用可能なすべてのデータを使用して、相互検証を繰り返し実行します。各フォールドで、データはトレーニングセットとテストセットに分割されます。トレーニングセットを使用してモデルを近似し(近似モデルのハイパーパラメーター値を記録)、テストセットのパフォーマンスを評価します。すべてのテストセットの平均をパフォーマンスの推定値として使用します(おそらく値の広がりも調べてください)。

ステップ3-ハイパーパラメーター設定の可変性-ステップ3で収集されたハイパーパラメーター値の分析を実行します。ただし、ハイパーパラメーターについて特別なものはなく、推定されたモデルのパラメーターにすぎません(間接的に) )データから。それらは、計算/数学上の利便性のために、パラメータではなくハイパーパラメータとして扱われますが、そうである必要はありません。

ここで相互検証を使用する場合の問題は、トレーニングデータとテストデータが(データを共有するため)独立したサンプルではないことです。つまり、パフォーマンス推定値とハイパーパラメーターの分散の推定値にバイアスがかかります(つまり、各フォールドのデータの純粋に独立したサンプルの場合よりも小さい)。交差検証を繰り返すのではなく、おそらくブートストラップを代わりに使用し、計算上実行可能な場合は、結果のモデルをバッグします。

重要な点は、公平なパフォーマンス推定を得るために、最終モデル(fit_model)を生成するために使用する手順はすべて、交差検証手順の各フォールドで個別に繰り返す必要があるということです。


これは素晴らしい答えです。あなたが言うときrather than repeated cross-validation you would go for bootstrapping-正確に違いは何ですか?どちらも、データを複数に分割しtraintestから、トレーニングをtrain行い、評価するという複数の繰り返しを伴いtestます。
ジョシュ

4
ブートストラッピング(置換によるサンプリング)は、繰り返しの交差検証よりもランダム化されるため、多数の再サンプリングを実行するより自然な方法のようです。ブートストラップの場合、バッグに入れられたアンサンブルの使用は、パフォーマンスの見積もりとしてout-of-bagエラーを伴う素晴らしい機能です。この2つを選択するのにそれほど多くはありません。
ディクラン有袋類

@Dikranに感謝-これは、例えばブートストラップを使用すると仮定すると、繰り返しにわたる平均と分散を考慮して、どのように良いモデルを選択するのだろうと思いましたか?(つまり、どのモデル選択プロトコルに従うのですか?)。この質問まさにこの質問を提起します。そのスレッドで入力を取得することは非常に貴重です!
ジョシュ

@DikranMarsupial手順1〜3のコード(PythonやRなど)を投稿できますか?具体的なコードを見ると、このような手順を理解する方がずっと簡単です。
tobip

1
重要なメッセージ:「重要な点は、公平なパフォーマンス推定を得るために、最終モデル(fit_model)を生成するために使用する手順はすべて、相互検証手順の各フォールドで独立して繰り返す必要があることです。」この正確なメッセージは、統計学習の要素(セクション7.10.2を参照)でも伝えられています:web.stanford.edu/~hastie/Papers/ESLII.pdf
NickBraunagel

0

γC

これらのハイパーパラメーターを最適化し、これらを使用してSVMをトレーニングする手順も、単なる機械学習アルゴリズムです。SVMの内部パラメーター(サポートベクター)のみを最適化する代わりに、ハイパーパラメーターも最適化します。

これで、2つの問題があります(個別に解決できます)。

相互検証の誤用(最適なハイパーパラメーター値のパフォーマンスのレポート)を読んで、それらを混同しないようにしてください。


あなたの質問の具体的な問題に対する特定の(おそらく最適ではない)解決策:

k = 5
loss_CV = zeros(k)
for i in 1:k 
    Xi_train, Xi_test = folds(X,k)[i]
    loss = zeros((3,3))
    for lambda in {0.1,0.2,0.5,1.0}
        for C in {10,100,1000}
            for j in 1:k
                Xj_train, Xj_test = folds(Xi_train,k)[j]
                model = SVM(Xj_train,lambda, C)
                loss[lambda,C] += test_error(model,Xj_test)
    lambda, C = argmax(loss)
    model = SVM(Xi_train,lambda, C)
    loss_CV += test_error(model,Xi_test)

loss = zeros((3,3))
for lambda in {0.1,0.2,0.5,1.0}
    for C in {10,100,1000}
        for j in 1:k
            Xj_train, Xj_test = folds(Xi_train,k)[j]
            model = SVM(Xj_train,lambda, C)
            loss[lambda,C] += test_error(model,Xj_test)
lambda, C = argmax(loss)
model = SVM(Xi_train,lambda, C)

ここmodelが、「最良のモデル」でありloss_CV、「その一般化誤差の適切な推定値」になります(上向きに偏りますが、ケーキを持って食べることはできません)。

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