2020年1月26日 星期日

[機器學習] SMOTE and undersamplimg

在醫學資訊學的領域裡面, 常常遇到一種很痛苦的情況, 就是想預測的事件佔訓練資料的比例太少, 舉例來說, 我們想用機器學習來預測某種罕見疾病的發生率, 可是大部分的臨床情形我們可能蒐集到幾百甚至幾千個符合條件的病人, 但是裡面只有十個病人有這個疾病, 這樣在使用機器學習來做預測的時候, 會遇到許多困難, 比如說要做cross validation的時候, 很容易某一個training set 完全沒有我們想預測的事件, 造成訓練結果不理想甚至有問題, 因此, 聰明的電腦科學家就想到一個辦法, 就是所謂的oversampling(過度取樣), 簡單來說就是把我們想預測的事件樣本把它增加, 來讓資料更容易訓練

其中有一個很有名的做法, 就是SMOTE(Synthetic Minority Over-sampling Technique), 其實這個方法早在2002年就有人提出來了(reference 1), 簡單來說, 就是選取相鄰的點, 然後再點跟點中間做內插, 內插得到的點, 就當作新的樣本, 用這樣來增加樣本數

paper 內其實pseudocode整理的非常好, 不過寫部落格就是要用自己的話說一次這樣記憶才會深刻XD, 因此還是來講解一下XD

pseudocode 我用中文稍微講解一下:

函數SMOTE(T,N,K)

輸入:  T:  minority class的個數
           N: 想拿多少比例出來做SMOTE
           K: 要找幾個相鄰的minority class的點來做SMOTE

輸出: T*(N/100)個點

演算法:

用白話來說就是先隨機分布樣本, 再把樣本裡面 T*(N/100)的樣本拿出來, 之後再針對每一個樣本, 針對其最接近的K個點, 取出其中一個點, 做內插, 內差的比例也是隨機決定的

其實這個算法還蠻簡單的, 不過作者再這篇文章裏面還有提到只做SMOTE可能還不夠好, 要改善majority class 跟 minority class的話, 還可以針對majority class 做undersampling, 也就是只取一部份的majority class來做預測

R語言裡面也有相關SMOTE套件, 有比較舊的DMwR, 還有比較新的SMOTEfamily

這裡簡單講一下 DMwR套件裡面的SMOTE 函數, 其實這個函數連undersampling都做了, 有幾個參數:

form: 拿來預測的formula, 其實簡單想就是拿來預測的分類
data: 拿來預測的資料
perc.over: minority class要增加幾倍, 舉例來說perc.over設為100,表示原本的minority class變成兩倍
k: 要看最近的幾個鄰居
prec.under: majority class要拿多少數量, 舉例來說perc.over設為100, 如果perc.under設為400,就會拿perc.over的四倍
learner: 可以不用設定, 也可以設成之後要拿來分類的演算法

reference:
1. Chawla, Nitesh V., et al. "SMOTE: synthetic minority over-sampling technique." Journal of artificial intelligence research 16 (2002): 321-357.
2. https://CRAN.R-project.org/package=DMwR 
3. https://cran.r-project.org/web/packages/smotefamily/smotefamily.pdf

沒有留言:

張貼留言