特徵選擇和交叉驗證
我最近在這個網站(@Aniko、@Dikran Marsupial、@Erik)和其他地方閱讀了很多關於交叉驗證發生過度擬合的問題 - (Smialowski 等人 2010 Bioinformatics, Hastie, Elements of Statistics learning)。建議是,使用交叉驗證(或其他模型估計方法,如自舉)在模型性能估計之外執行的任何監督特徵選擇(使用與類標籤的相關性)都可能導致過度擬合。
這對我來說似乎不直觀 - 當然,如果您選擇一個特徵集,然後使用交叉驗證僅使用所選特徵評估您的模型,那麼您將獲得對這些特徵的廣義模型性能的無偏估計(這假設正在研究的樣本具有代表性人口)?
通過這個過程,當然不能聲稱一個最佳特徵集,但是可以報告所選特徵集在看不見的數據上的性能是有效的嗎?
我接受基於整個數據集選擇特徵可能會導致測試集和訓練集之間的一些數據洩漏。但是,如果在初始選擇後特性集是靜態的,並且沒有進行其他調整,那麼報告交叉驗證的性能指標肯定是有效的嗎?
就我而言,我有 56 個功能和 259 個案例,所以 #cases > #features。這些特徵來自傳感器數據。
抱歉,如果我的問題似乎是派生的,但這似乎是需要澄清的重要一點。
編輯: 關於在上面詳述的數據集的交叉驗證中實現特徵選擇(感謝下面的答案),我可以確認在該數據集中的交叉驗證之前選擇特徵引入了顯著偏見。與 2 類公式相比,3 類公式的這種偏差/過度擬合最大。我認為我使用逐步回歸進行特徵選擇的事實增加了這種過度擬合;為了比較的目的,在一個不同但相關的數據集上,我將在交叉驗證之前執行的順序前向特徵選擇例程與我之前在 CV 中使用特徵選擇獲得的結果進行了比較。兩種方法之間的結果沒有顯著差異。這可能意味著逐步回歸比順序 FS 更容易過度擬合,或者可能是該數據集的一個怪癖。
如果您對所有數據執行特徵選擇然後進行交叉驗證,那麼交叉驗證過程的每一折中的測試數據也被用於選擇特徵,這就是性能分析的偏差。
考慮這個例子。我們通過擲硬幣 10 次並記錄它是正面還是反面來生成一些目標數據。接下來,我們通過為每個特徵擲硬幣 10 次來生成 20 個特徵,並寫下我們得到的結果。然後,我們通過選擇與目標數據盡可能匹配的特徵來執行特徵選擇,並將其用作我們的預測。如果我們隨後進行交叉驗證,我們將獲得略低於 0.5 的預期錯誤率。這是因為我們在交叉驗證過程的每一折中都基於訓練集和測試集的相關性來選擇特徵。然而,真正的錯誤率將是 0.5,因為目標數據只是隨機的。如果您在交叉驗證的每一折中獨立執行特徵選擇,則錯誤率的預期值為 0。
關鍵思想是交叉驗證是一種估計構建模型的過程的泛化性能的方法,因此您需要在每個折疊中重複整個過程。否則,您最終會得到一個有偏差的估計,或低估估計的方差(或兩者兼而有之)。
高溫高壓
這是一些 MATLAB 代碼,用於執行此設置的 Monte-Carlo 仿真,具有 56 個功能和 259 個案例,以匹配您的示例,它給出的輸出是:
有偏估計:erate = 0.429210 (0.397683 - 0.451737)
無偏估計量:erate = 0.499689 (0.397683 - 0.590734)
有偏估計器是在交叉驗證之前執行特徵選擇的估計器,無偏估計器是在交叉驗證的每個折疊中獨立執行特徵選擇的估計器。這表明在這種情況下偏差可能非常嚴重,具體取決於學習任務的性質。
NF = 56; NC = 259; NFOLD = 10; NMC = 1e+4; % perform Monte-Carlo simulation of biased estimator erate = zeros(NMC,1); for i=1:NMC y = randn(NC,1) >= 0; x = randn(NC,NF) >= 0; % perform feature selection err = mean(repmat(y,1,NF) ~= x); [err,idx] = min(err); % perform cross-validation partition = mod(1:NC, NFOLD)+1; y_xval = zeros(size(y)); for j=1:NFOLD y_xval(partition==j) = x(partition==j,idx(1)); end erate(i) = mean(y_xval ~= y); plot(erate); drawnow; end erate = sort(erate); fprintf(1, ' Biased estimator: erate = %f (%f - %f)\n', mean(erate), erate(ceil(0.025*end)), erate(floor(0.975*end))); % perform Monte-Carlo simulation of unbiased estimator erate = zeros(NMC,1); for i=1:NMC y = randn(NC,1) >= 0; x = randn(NC,NF) >= 0; % perform cross-validation partition = mod(1:NC, NFOLD)+1; y_xval = zeros(size(y)); for j=1:NFOLD % perform feature selection err = mean(repmat(y(partition~=j),1,NF) ~= x(partition~=j,:)); [err,idx] = min(err); y_xval(partition==j) = x(partition==j,idx(1)); end erate(i) = mean(y_xval ~= y); plot(erate); drawnow; end erate = sort(erate); fprintf(1, 'Unbiased estimator: erate = %f (%f - %f)\n', mean(erate), erate(ceil(0.025*end)), erate(floor(0.975*end)));