一、算法
关于REPTree我实在是没找到什么相关其算法的资料,或许是Weka自创的一个关于决策树的改进,也许是其它某种决策树方法的别名,根据类的注释:Fast decision tree learner. Builds a decision/regression tree using information gain/variance and prunes it using reduced-error pruning (with backfitting). Only sorts values for numeric attributes once. Missing values are dealt with by splitting the corresponding instances into pieces (i.e. as in C4.5).
我们大概知道和C4.5相比,大概多了backfitting过程,并且数值型排序只进行一次(回想一下J48也就是C4.5算法是每个数据子集都要进行排序),并且缺失值的处理方式和C4.5一样,走不同的path再把结果进行加权。
具体和C4.5的比较将在代码分析之后给出一个总结。
二、buildClassifier
“大名鼎鼎”的分类器训练主入口,几乎每篇分析分类器源码都从这个方法入手。
public void buildClassifier(Instances data) throws Exception {
// 首先例行公事看一下给定数据集是否能使用REPTree进行分类,REPTREE基本能支持所有类型
getCapabilities().testWithFail(data);
// 把classIndex上没有数据的instance干掉,这些数据既不能用于训练也不能用于backfit
data = new Instances(data);
data.deleteWithMissingClass();
Random random = new Random(m_Seed);
m_zeroR = null;
if (data.numAttributes() == 1) {
m_zeroR = new ZeroR();//如果只有一列的话,就是用m_ZerO作为分类器,很直观只有一列的话肯定就是结果列了,只有结果列无法训练分类器,只能使用最基本的米ZerO作为分类器,mZerO的分类方法再上篇日志有说到。
m_zeroR.buildClassifier(data);
return;
}
// Randomize and stratify
data.randomize(random);//进行随机排列
if (data.classAttribute().isNominal()) {
data.stratify(m_NumFolds);//如果枚举型还要进行一下分层,目的是
}
// 如果需要剪枝,则分为train集合和prune集合,否则只要train集合就行了
Instances train = null;
Instances prune = null;
if (!m_NoPruning) {
train = data.trainCV(m_NumFolds, 0, random);//这里是用了多折交叉验证的方法取得train和test
prune = data.testCV(m_NumFolds, 0);
} else {
train = data;
}
// 建立了两个数组,第一维数据无意义,只是把三维数组当二维数组用而已,第二维代表各属性,第三维代表排序的index(顺序统计量)
int[][][] sortedIndices = new int[1][train.numAttributes()][0];//这个里面存放的是各instance的下标
double[][][] weights = new double[1][train.numAttributes()][0];//这个里面存放的是下标对应的instance的weight
double[] vals = new double[train.numInstances()];//这个是临时数组,用于排序用的
for (int j = 0; j < train.numAttributes(); j++) {
if (j !&#