用SMOTE演算法處理樣本不均衡問題
十一放假前搭了一個簡單的分類器,讓同事接數據幫我做測試。模型訓練完之後,同事告訴我分類器的正確率只有30%多一點。當時我就很震驚,這個分類器的性能在我的預計中應該遠高於此。
於是立即開始檢查問題,很快發現問題的所在。樣本數據大概有二十多個分類,但是整個樣本卻非常的不均衡。其中數量占第一的樣本數佔了整體的一半還多,而最少的樣本佔比1%都不到。
很明顯這就是問題所在了。說來首先需要自我檢討一下,覺得馬上就放假,於是就心存僥倖偷了個懶,在寫演算法程序的時候根本沒有考慮樣本不均衡的問題,而是想當然認為應該差不多。所以,偷工減料的地方還是第一時間返工了。
整個處理過程在這裡還是重新闡述一下,可能也會有同志們遇到類似問題,在此作為解決案例貼出來。
1.什麼是樣本不均衡的問題
簡單來說,樣本不均衡問題就是不同類型樣本數量差異過大。舉個簡單的例子,教一個小盆友怎麼識別飛機和老鷹。給他看了一千張各種飛機的圖片,但是只給他看了一張老鷹的圖片。這個時候讓他去區分老鷹和飛機是區別不出來的,可能小盆友會認為老鷹和玩具飛機也差不了太多。
對機器學習也是 如此,整個樣本集數據差異過大,同樣會造成機器學習的性能降低。比如,在我的實際案例中,由於排名第一的樣本數量過大,而其他所有類型被分散到不到一半的裡邊,導致的結果就是幾乎所有的分類都被分到第一類裡邊。結果導致事實上分類準確的結果就是測試數據中排名第一樣本的佔比。
我做的分類器在這個學習過程中根本就沒有找到不同類型樣本的特徵所在。
2.關於SMOTE演算法的白話闡述
怎麼處理不均衡的樣本呢?一個簡單粗暴的解決方案當然是把樣本變均衡啦!
當然有些簡單且比較有效的處理方案,比如我把樣本數量多的類型少抽一些,或者把樣本數量少的類型多抽幾遍。比如一個1000:10的樣本,我可以把1000個的那一類只抽百分之一,或者把10個的那一類反覆抽一百遍。這樣從結果來看,總是均衡的。不過這也是有一定問題的。只抽百分之一的話,那絕大部分樣本的數據可能就被遺漏了;而如果反覆抽一百遍,無疑會放大這部分數據的干擾,造成過擬合的問題。
所以SMOTE演算法是一個看上去更專業一些的解決方案。簡單來說,就是如果樣本數量不夠我就創造樣本。也就是,我們找樣本周圍的近鄰,合成新的樣本數據。
具體怎麼處理呢?還是上邊那個1000:10的例子。我們可以把那10個尋找他們的近鄰數據,然後在他們之間插值,來形成新的數據。這樣一來,如果合成了990個新數據,兩邊也就差不多均衡了。雖然肯定比不上樣本均衡的條件下訓練效果,但是相比於前邊的簡單處理方案,這樣的結果一般來說是要更好一些的。
簡單介紹到此為止,如果有同學們想深入了解的,建議還是找幾篇paper來讀。不過這個演算法整體也非常簡單,理解起來相信不會有難度。
3.處理過程和結果
所以後來我們就按照這個思路處理了數據不均衡問題。整個處理過程其實沒有太多好說的,無非也就是按照演算法寫了一個簡單的程序,處理了一下樣本再重新訓練模型。
雖然沒做什麼工作,但是簡單改了一下之後,就從30%出頭的正確率一下子到了89%,離90%只差一點點啦。
推薦閱讀:
※沒有價值觀的演算法下崗了,但我希望演算法能快快長大
※037 Sudoku Solver[H]
※演算法:1.two sum
※021 Merge Two Sorted Lists[E]
※按出現次數從少到多的順序輸出數組中的字元串