使用Weka进行数据挖掘(Weka教程六)Weka采样Filter/Resample/SMOTE

数据预处理中,有一个原理很简单但是非常重要的部分:采样。良好的采样可以让数据集变得平衡,会大大的提高预测和分类的效果。
采样是很复杂的一个领域,背后涉及到数据的分布/数据的性质等很多内容。常见的采样有:
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之间的连线上随机选一点作为新合成的少数类样本。 这是一种过采样方法,通过制造更多模拟的少数类样本来实现各个样本之间的平衡。
    下图是其主要思想的形式化表示:
    使用Weka进行数据挖掘(Weka教程六)Weka采样Filter/Resample/SMOTE_第1张图片
    在Weka3.7版本,你必须先添加第三方包,最简单的方法就是添加一个新的maven依赖:
<dependency>
    <groupId>nz.ac.waikato.cms.wekagroupId>
    <artifactId>SMOTEartifactId>
    <version>1.0.3version>
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采样之后,多数类样本并不会随之减少,因此,如果你想让多数类和少数类样本平衡,就必须再使用简单采样丢弃多余的多数类样本。

你可能感兴趣的:(Weka+Java数据挖掘)