使用Weka進行資料探勘(Weka教程六)Weka取樣Filter/Resample/SMOTE
阿新 • • 發佈:2019-01-10
資料預處理中,有一個原理很簡單但是非常重要的部分:取樣。良好的取樣可以讓資料集變得平衡,會大大的提高預測和分類的效果。
取樣是很複雜的一個領域,背後涉及到資料的分佈/資料的性質等很多內容。常見的取樣有:
Simple Random Sampling(簡單隨機取樣),
OfflineSampling(離線等可能K取樣),
Online Sampling(線上等可能K取樣),
Ratio-based Sampling(等比例隨機取樣),
Acceptance-RejectionSampling(接受-拒絕取樣),
Importance Sampling(重要性取樣),
MCMC(MarkovChain Monte Carlo 馬爾科夫蒙特卡羅取樣演算法)。
- 簡單有放回隨機取樣
Filter支援多種取樣方式,其中有監督的取樣比較複雜,因此主要講解有監督學習取樣方法。Filter中的Resample取樣就是簡單的有放回抽樣。
其引數有下面幾個:
-S <num>
Specify the random number seed (default 1)
指定隨機數種子,隨機數種子相同,則取樣結果相同。
-Z <num>
The size of the output dataset, as a percentage of
the input dataset (default 100)
指定取樣資料佔整個資料的比例。
-B <num >
Bias factor towards uniform class distribution.
0 = distribution in input data -- 1 = uniform distribution.
(default 0)
是否按照原來資料類別的分佈分層抽樣。
-no-replacement
Disables replacement of instances
(default: with replacement)
-V
Inverts the selection - only available with '-no-replacement' .
由以上引數可以看出,Weka支援的比例好像最小為1%,其實並不是,你可以使用小數實現更低的取樣比。此外,你可以將取樣比例設定成大於100%,如果你這樣做了,那麼你的結果資料集將會出現重複的資料。這樣是沒有意義的。
使用Resample進行取樣是比較簡單的,下面是一個例子:
public static Instances BoostrapSample(Instances data) {
String[] options = {"-S",1};
Resample convert = new Resample();
try {
convert.setOptions(options);
convert.setInputFormat(data);
data = Filter.useFilter(data, convert);
} catch (Exception e) {
e.printStackTrace();
}
return data;
}
- SMOTE取樣
隨機取樣比較簡單,其實Weka還支援一種附加的取樣方法,在Weka3.6版本以下,這個功能嵌入在Weka包裡,Weka3.7版本開始,這個功能需要額外的第三方包的支援,這種取樣就是SMOTE取樣。
SMOTE演算法的思想是合成新的少數類樣本,合成的策略是對每個少數類樣本a,從它的最近鄰中隨機選一個樣本b,然後在a、b之間的連線上隨機選一點作為新合成的少數類樣本。 這是一種過取樣方法,通過製造更多模擬的少數類樣本來實現各個樣本之間的平衡。
下圖是其主要思想的形式化表示:
在Weka3.7版本,你必須先新增第三方包,最簡單的方法就是新增一個新的maven依賴:
<dependency>
<groupId>nz.ac.waikato.cms.weka</groupId>
<artifactId>SMOTE</artifactId>
<version>1.0.3</version>
</dependency>
SMOTE取樣實現程式碼如下:
public static Instances SMOTESample(Instances data,int normalElemFlag) {
SMOTE convert = new SMOTE();
int seed = (int) (Math.random() * 10);
String[] options = {"-S", String.valueOf(seed), "-P", "100.0", "-K", "5"};
Instances SmoteInstances = null;
try {
convert.setOptions(options);
convert.setInputFormat(data);
SmoteInstances = Filter.useFilter(data, convert);
} catch (Exception e) {
e.printStackTrace();
}
return SmoteInstances;
}
需要注意的是,在執行完畢SMOTE取樣之後,多數類樣本並不會隨之減少,因此,如果你想讓多數類和少數類樣本平衡,就必須再使用簡單取樣丟棄多餘的多數類樣本。