《分类算法Java代码分析》由会员分享,可在线阅读,更多相关《分类算法Java代码分析(46页珍藏版)》请在金锄头文库上搜索。
1、Weak.classifiers包中含有用于分类和数值预测的大部分算法的实现。这个包中最重要的是类是Classifier,它定义了任何用于分类或数值预测的学习方案的通用结构。Classifier含有三个方法,buildClassfier(),classifyInstance(),distributionForInstance().学习算法用Classifier的子类代表,因此,自动继承这三个方法。每种方案都会根据构建分类器以及它对实例进行分类的具体方式对这三个方法进行重新定义。首先先解释一下算法名字,很多人很奇怪为什么叫IB1,IBK,IB Instance-Based的缩写,但按Jiawei
2、 Han书上所写,KNN其实是Instance-based learning(也被称为Lazing learning)中一种,他还讲解了基于案例的推理(Case-based reasoning)。算法其实是KNN,但是作者论文的名字是Instance-based Learning Algorithms。 我先介绍一下IB1,IB1就是只找一个邻居。我们还是先看buildClassifier。 public void buildClassifier(Instances instances) throws Exception if (instances.classAttribute().isNum
3、eric() throw new Exception(IB1: Class is numeric!); /类别属性是数值型的话,报错。 if (instances.checkForStringAttributes() throw new UnsupportedAttributeTypeException( IB1: Cannot handle string attributes!); /检查其他属性,如果是字符串String类型,报错:不能处理 / Throw away training instances with missing class 缺失类别属性的实例扔掉 m_Train = ne
4、w Instances(instances, 0, instances.numInstances(); m_Train.deleteWithMissingClass(); /Instance是一个类,Create empty instance with three attribute values m_MinArray = new doublem_Train.numAttributes();/定义一个数组,m_MinArray ,数据类型是double型,共有m_Train.numAttributes()个数据。 m_MaxArray = new doublem_Train.numAttrib
5、utes(); for (int i = 0; i m_Train.numAttributes(); i+) m_MinArrayi = m_MaxArrayi = Double.NaN; /还没有将真正的实例的属性存放在这两个数组里 Enumeration enu = m_Train.enumerateInstances(); /列举出每个实例的属性值 while (enu.hasMoreElements() /以枚举的实例属性数量进行循环判断 updateMinMax(Instance) enu.nextElement(); /更新属性的最大最小值 是的,KNN也有buildClassif
6、ier,听起来蛮奇怪的。第二个if,IB1不能对字符串属性进行学习,因为这种属性不好定义距离,比如a和ab是0.5还是1呢?然类别缺失的样本抛弃。m_MinArray和m_MaxArray分别保存每一个属性的最小值和最大值。最下面是对样本进行循环,找出最大值,最小值,updataMinMax代码如下: private void updateMinMax(Instance instance) for (int j = 0; j m_Train.numAttributes(); j+) /有多少个属性就循环多少次 if (m_Train.attribute(j).isNumeric() & (!i
7、nstance.isMissing(j) /这个属性的第j个值是数值型,并且,实例不缺失这个属性值 if (Double.isNaN(m_MinArrayj) m_MinArrayj = instance.value(j); /value()是要返回实例的属性值。 m_MaxArrayj = instance.value(j); else if (instance.value(j) m_MaxArrayj) m_MaxArrayj = instance.value(j); /如果这个属性值大于之前定义的最大属性值,将其值赋给最大属性值。 Double.isNaN(m_MinArrayj)判断是
8、不是m_MinArray和m_MaxArray已经赋值过了,else,如果可以更新min和更新max。 再看一下classifyInstance函数: public double classifyInstance(Instance instance) throws Exception /对待分类实例进行分类的过程。 if (m_Train.numInstances() = 0) throw new Exception(No training instances!); /实例数量为0,报错 double distance, minDistance = Double.MAX_VALUE,/声明并且
9、初始化 classValue = 0;/ classValue():实例的类别属性Returns an instances class value in internal format updateMinMax(instance); Enumeration enu = m_Train.enumerateInstances(); / enumerateInstances():Returns an enumeration (列举,枚举)of all the attributes. while (enu.hasMoreElements() Instance trainInstance = (Inst
10、ance) enu.nextElement(); if (!trainInstance.classIsMissing() distance = distance(instance, trainInstance); /distance方法在后面有说明 if (distance minDistance) minDistance = distance; classValue = trainInstance.classValue();/classValue():Returns an instances class value in internal format,返回这个实例的类别属性 return
11、classValue; 因为要进化归范化,所以对这个待分类的样本再次调用updateMinMax。?然后对训练样本进行循环,用distance计算与每一个训练样本和待分类样本的距离,如果比前面的距离小,则记录,最后返回与测试样本距离最小的样本的类别值。 private double distance(Instance first, Instance second) double diff, distance = 0; /声明并且初始化为0 for (int i = 0; i m_Train.numAttributes(); i+) if (i = m_Train.classIndex() /
12、classIndex():Returns the class attributes index continue; if (m_Train.attribute(i).isNominal() / If attribute is nominal if (first.isMissing(i) | second.isMissing(i) | (int) first.value(i) != (int) second.value(i) distance += 1; else / If attribute is numeric if (first.isMissing(i) | second.isMissing(i) if (first.isMissing(i) & second.isMissing(i) diff = 1; else if (second.isMissing(i) diff = norm(first.value(i), i); else diff = norm(second.value(i),