2015-06-22 25 views
49

我很難理解scikit-learn的Logistic迴歸中的class_weight參數如何操作。scikit-learn中的class_weight參數如何工作?

我想用邏輯迴歸做一個非常不平衡的數據集的二元分類現狀。這些類別被標記爲0(負)和1(正),並且觀察到的數據與大多數樣品具有負結果的比率約爲19:1。

第一次嘗試:手動準備訓練數據

我拆我成不相交集的培訓和測試(約80/20)中的數據。然後我手工隨機抽取訓練數據得到不同比例的訓練數據,比例爲19:1;從2:1 - > 16:1。

然後,我對這些不同的訓練數據子集進行邏輯迴歸訓練,並繪製作爲不同訓練比例函數的回憶(= TP /(TP + FN))。當然,召回是根據觀察到比例爲19:1的不相交TEST樣本計算的。請注意,儘管我在不同的訓練數據上訓練了不同的模型,但我仍然使用相同的(不相交的)測試數據對所有人進行了回想。

結果如預期:在2:1的訓練比例下回憶約爲60%,到達16:1時相當快地下降。有幾個比例爲2:1 - > 6:1,召回率高於5%。

第二次嘗試:網格搜索

接下來,我想測試不同的正則化參數,所以我用GridSearchCV並提出了C參數的幾個值還有class_weight參數的網格。負米的比例:以我ñ翻譯肯定訓練樣本進入class_weight詞典語言,我以爲我剛纔指定幾個字典如下:

{ 0:0.67, 1:0.33 } #expected 2:1 
{ 0:0.75, 1:0.25 } #expected 3:1 
{ 0:0.8, 1:0.2 } #expected 4:1 

,我也包括在內Noneauto

這一次的結果完全被破壞了。對於class_weight的每個值,除auto之外,我所有的召回都很少(< 0.05)。所以我只能假設我對如何設置class_weight字典的理解是錯誤的。有趣的是,在網格搜索中,'auto'的class_weight值對於所有C的值都大約爲59%,並且我猜想它的餘額爲1:1?

我的問題

1)你如何正確使用class_weight到您實際賦予其實現訓練數據不同的平衡?具體來說,我會傳遞什麼字典到class_weight以使用n:m比例的否定:正面訓練樣本? 2)如果您將各種class_weight字典傳遞給GridSearchCV,在交叉驗證期間,它會根據字典重新平衡訓練摺疊數據,但是使用真實的給定樣本比例來計算測試摺疊的評分函數?這是至關重要的,因爲任何度量標準只有在來自觀察比例的數據時纔對我有用。

3)autoclass_weight做的比例是多少?我閱讀了文檔,我假設「平衡數據與其頻率成反比」僅僅意味着它使它成爲1:1。它是否正確?如果沒有,有人可以澄清?

非常感謝你,任何澄清將不勝感激!

回答

49

首先,單單回憶可能並不好。您可以簡單地通過將所有內容分類爲正面課程來實現100%的回憶。 我通常建議使用AUC選擇參數,然後找到了工作點,你有興趣在一個閾值(比方說一個給定精度水平)

對於如何class_weight作品:它懲罰的失誤與class_weight[i]class[i]樣本而不是1.因此,更高的課堂重量意味着您希望更重視課堂。從你所說的看來,0級比1級更頻繁19倍。所以你應該增加1級相對於0級的class_weight,比如{0:.1,1:.9}。 如果class_weight不等於1,它將基本上改變正則化參數。

有關class_weight="auto"的工作原理,您可以查看this discussion。 在開發版本中,您可以使用class_weight="balanced",這更容易理解:它基本上意味着複製較小的類,直到您擁有與較大的樣本一樣多的樣本,但以隱式的方式。

+0

謝謝!快速提問:我提到召回是爲了清晰起見,事實上我正在設法決定使用哪種AUC作爲我的措施。我的理解是,我應該使ROC曲線下的面積最大,或者召回與精度曲線下的面積最大,以找到參數。通過這種方式選取參數後,我相信我會通過沿曲線滑動來選擇分類閾值。這是你的意思嗎?如果是這樣,兩條曲線中的哪一條最有意義看待我的目標是捕捉儘可能多的TP?此外,謝謝你的工作和對scikit-learn的貢獻! – ministry

+1

我認爲使用ROC會是更爲標準的方式,但我認爲不會有太大的差異。不過,你需要一些標準來挑選曲線上的點。 –

+0

在這種情況下,是否還有更重的懲罰更小的集合的錯誤分類的想法?儘管我同意要嘗試的是class_weight參數的平衡設置。 –