一、RandomTree算法
在网上搜了一下,并没有找到RandomTree的严格意义上的算法描述,因此我觉得RandomTree充其量只是一种构建树的思路,和普通决策树相比,RandomTree会随机的选择若干属性来进行构建而不是选取所有的属性。
Weka在实现上,对于随机属性的选取、生成分裂点的过程是这样的:
1、设置一个要选取的属性的数量K
2、在全域属性中无放回的对属性进行抽样
3、算出该属性的信息增益(注意不是信息增益率)
4、重复K次,选出信息增益最大的当分裂节点。
5、构建该节点的孩子子树。
二、具体代码实现
(1)buildClassifier
public void buildClassifier(Instances data) throws Exception {
// 如果传入的K不合理,把K放到一个合理的范围里
if (m_KValue > data.numAttributes() - 1)
m_KValue = data.numAttributes() - 1;
if (m_KValue < 1)
m_KValue = (int) Utils.log2(data.numAttributes()) + 1;//这个是K的默认值
// 判断一下该分类器是否有能力处理这个数据集,如果没能力直接就在testWithFail里抛异常退出了
getCapabilities().testWithFail(data);
// 删除掉missClass
data = new Instances(data);
data.deleteWithMissingClass();
// 如果只有一列,就build一个ZeroR模型,之后就结束了。ZeroR模型分类是这样的:如果是连续型,总是返回期望,如果离散型,总是返回训练集中出现最多的那个
if (data.numAttributes() == 1) {
System.err
.println("Cannot build model (only class attribute present in data!), "
+ "using ZeroR model instead!");
m_zeroR = new weka.classifiers.rules.ZeroR();
m_zeroR.buildClassifier(data);
return;
} else {
m_zeroR = null;
}
// 如果m_NumFlods大于0,则会把数据集分为两部分,一部分用于train,一部分用于test,也就是backfit
//分的方式和多折交叉验证是一样的,例如m_NumFlods是10的话,则train占90%,backfit占10%
Instances train = null;
Instances backfit = null;
Random rand = data.getRandomNumberGenerator(m_randomSeed);
if (m_NumFolds <= 0) {
train = data;