2014-02-19 86 views
7

我一直試圖在scikit-learn中使用加權樣本,同時訓練隨機森林分類器。當我直接將樣本權重傳遞給分類器時,效果很好。 RandomForestClassifier().fit(X,y,sample_weight=weights),但是當我嘗試了網格搜索,以找到更好的超參數進行分類,我碰了壁:scikit-learn中的樣本權重在交叉驗證中破裂

要使用電網參數時傳遞的權重,用法:

grid_search = GridSearchCV(RandomForestClassifier(), params, n_jobs=-1, 
          fit_params={"sample_weight"=weights}) 

的問題是交叉驗證器不知道樣本權重,因此不會將它們與實際數據一起重新採樣,因此調用grid_search.fit(X,y)失敗:交叉驗證器創建X和y的子集,sub_X和sub_y,最終分類器是用classifier.fit(sub_X, sub_y, sample_weight=weights)調用,但現在重量未被重新採樣,因此引發異常。

現在我已經在訓練分類器之前通過對高重量樣本進行過採樣來解決這個問題,但這只是一個臨時解決方法。有關如何進行的任何建議?

回答

2

我會建議編寫自己的交叉驗證參數選擇,因爲它只是python中的10-15行代碼(特別是使用scikit-learn中的kfold對象),而過採樣可能是一個很大的瓶頸。

+1

問題是GridSearchCV在其代碼中嵌入了交叉驗證。我沒有修改的問題,但這樣做似乎很髒。作爲一個元問題,兩種方法(重採樣和加權)實際上是否等價?嗯,看起來有點看起來,它似乎不是,但也都工作:http://statistics.berkeley.edu/sites/default/files/tech-reports/666.pdf –

+1

我開始修改超參數搜索(grid_search.py​​中的'fit_grid_point')將類權重考慮在內,然後我意識到scikit-learn中還存在另一個明顯的缺失:交叉驗證中的得分不會考慮類權重(我更關心評估錯誤時將少數羣體分類錯誤)。這一切都促使我重新取樣,只有在我遇到性能問題時才正確解決這個問題。 –

5

編輯:我從下面看到的分數看起來不太正確。這可能是因爲,正如上面提到的那樣,即使使用重量進行擬合時,他們可能也不會用於計分。

看來現在已經修復了。我運行sklearn版本0.15.2。我的代碼看起來像這樣:

model = SGDRegressor() 
parameters = {'alpha':[0.01, 0.001, 0.0001]} 
cv = GridSearchCV(model, parameters, fit_params={'sample_weight': weights}) 
cv.fit(X, y) 

希望可以幫助(您和其他人看到這篇文章)。

2

我的信譽太少,所以我無法對@xenocyon發表評論。我使用sklearn 0.18.1,我也在代碼中使用pipeline。爲我工作的解決方案是:

fit_params={'classifier__sample_weight': w}其中w是權重向量和classifier是管道中的步驟名稱。

+0

這是爲我做的!真是太棒了。 – bwest87