机器学习:IB1算法的weka源码详细解析(1NN)
机器学习的1NN最近邻算法,在weka里叫IB1,是因为Instance Base 1 ,也就是只基于一个最近邻的实例的惰性学习算法。
下面总结一下,weka中对IB1源码的学习总结。
首先需要把 weka-src.jar 引入编译路径,否则无法跟踪源码。
1)读取data数据,完成 IB1 分类器的调用,结果预测评估。为了后面的跟踪。
try {
File file = new File("F:\\tools/lib/data/contact-lenses.arff");
ArffLoader loader = new ArffLoader();
loader.setFile(file);
ins = loader.getDataSet();
// 在使用样本之前一定要首先设置instances的classIndex,否则在使用instances对象是会抛出异常
ins.setClassIndex(ins.numAttributes() - );
cfs = new IB1();
cfs.buildClassifier(ins);
Instance testInst;
Evaluation testingEvaluation = new Evaluation(ins);
int length = ins.numInstances();
for (int i = ; i < length; i++) {
testInst = ins.instance(i);
// 通过这个方法来用每个测试样本测试分类器的效果
double predictValue = cfs.classifyInstance(testInst);
System.out.println(testInst.classValue()+"--"+predictValue);
}
// System.out.println("分类器的正确率:" + ( - testingEvaluation.errorRate()));
} catch (Exception e) {
e.printStackTrace();
}
2)ctrl 点击buildClassifier,进一步跟踪buildClassifier方法的源码,在IB1的类中重写了这个抽象方法,源码为:
public void buildClassifier(Instances instances) throws Exception {
// can classifier handle the data?
getCapabilities().testWithFail(instances);
// remove instances with missing class
instances = new Instances(instances);
instances.deleteWithMissingClass();
m_Train = new Instances(instances, , instances.numInstances());
m_MinArray = new double [m_Train.numAttributes()];
m_MaxArray = new double [m_Train.numAttributes()];
for (int i = ; i < m_Train.numAttributes(); i++) {
m_MinArray[i] = m_MaxArray[i] = Double.NaN;
}
Enumeration enu = m_Train.enumerateInstances();
while (enu.hasMoreElements()) {
updateMinMax((Instance) enu.nextElement());
}
}
(1)if是判断,IB1分类器不能处理属性是字符串和类别是数值型的样本;
(2)if是判断,删除没有类标签的样本;
(3)m_MinArray 和 m_MaxArray 分别保存最小和最大值,并且初始化double数组【样本个数】;
(4)遍历所有的训练样本实例,求最小和最大值;继续跟踪updateMinMax方法;
3)IB1类的updateMinMax方法的源码如下:
private void updateMinMax(Instance instance) {
for (int j = ;j < m_Train.numAttributes(); j++) {
if ((m_Train.attribute(j).isNumeric()) && (!instance.isMissing(j))) {
if (Double.isNaN(m_MinArray[j])) {
m_MinArray[j] = instance.value(j);
m_MaxArray[j] = instance.value(j);
} else {
if (instance.value(j) < m_MinArray[j]) {
m_MinArray[j] = instance.value(j);
} else {
if (instance.value(j) > m_MaxArray[j]) {
m_MaxArray[j] = instance.value(j);
}
}
}
}
}
}
(1)过滤掉属性不是数值型和缺失标签的实例;
(2)若是isNaN,is not a number,是数值型的话,循环遍历样本的每一个属性,求出最大最小值;
到此为止,训练了IB1模型(有人可能会问lazy的算法难道不是不需要训练模型吗?我认为build分类器是为了初始化 m_Train和求所有实例的每个属性的最大最小值,为了下一步求distance做准备)
下面介绍下预测源码:
4)跟踪classifyInstance方法,源码如下:
public double classifyInstance(Instance instance) throws Exception {
if (m_Train.numInstances() == ) {
throw new Exception("No training instances!");
}
double distance, minDistance = Double.MAX_VALUE, classValue = ;
updateMinMax(instance);
Enumeration enu = m_Train.enumerateInstances();
while (enu.hasMoreElements()) {
Instance trainInstance = (Instance) enu.nextElement();
if (!trainInstance.classIsMissing()) {
distance = distance(instance, trainInstance);
if (distance < minDistance) {
minDistance = distance;
classValue = trainInstance.classValue();
}
}
}
return classValue;
}
(1)调用方法updateMinMax更新了加入测试实例后的最大最小值;
(2)计算测试实例到每一个训练实例的距离,distance方法,并且保存距离最小的实例minDistance;
5)跟踪classifyInstance方法,源码如下:
private double distance(Instance first, Instance second) {
double diff, distance = ;
for(int i = ; i < m_Train.numAttributes(); i++) {
if (i == m_Train.classIndex()) {
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 += ;
}
} else {
// If attribute is numeric
if (first.isMissing(i) || second.isMissing(i)){
if (first.isMissing(i) && second.isMissing(i)) {
diff = ;
} else {
if (second.isMissing(i)) {
diff = norm(first.value(i), i);
} else {
diff = norm(second.value(i), i);
}
if (diff < 0.5) {
diff = 1.0 - diff;
}
}
} else {
diff = norm(first.value(i), i) - norm(second.value(i), i);
}
distance += diff * diff;
}
}
return distance;
}
对每一个属性遍历,计算数值属性距离的平方和,norm方法为规范化距离公式,为【0,1】的实数
6)跟踪norm规范化方法,源码如下:
private double norm(double x,int i) {
if (Double.isNaN(m_MinArray[i])
|| Utils.eq(m_MaxArray[i], m_MinArray[i])) {
return ;
} else {
return (x - m_MinArray[i]) / (m_MaxArray[i] - m_MinArray[i]);
}
}
规范化距离:(x - m_MinArray[i]) / (m_MaxArray[i] - m_MinArray[i]);
具体的算法伪代码,请查找最近邻分类器的论文,我就不贴出来了。
机器学习:IB1算法的weka源码详细解析(1NN)的更多相关文章
- Thrift之代码生成器Compiler原理及源码详细解析1
我的新浪微博:http://weibo.com/freshairbrucewoo. 欢迎大家相互交流,共同提高技术. 又很久没有写博客了,最近忙着研究GlusterFS,本来周末打算写几篇博客的,但是 ...
- Vue源码详细解析:transclude,compile,link,依赖,批处理...一网打尽,全解析!
用了Vue很久了,最近决定系统性的看看Vue的源码,相信看源码的同学不在少数,但是看的时候却发现挺有难度,Vue虽然足够精简,但是怎么说现在也有10k行的代码量了,深入进去逐行查看的时候感觉内容庞杂并 ...
- Thrift之代码生成器Compiler原理及源码详细解析2
我的新浪微博:http://weibo.com/freshairbrucewoo. 欢迎大家相互交流,共同提高技术. 2 t_generator类和t_generator_registry类 这个两 ...
- Thrift之TProcess类体系原理及源码详细解析
我的新浪微博:http://weibo.com/freshairbrucewoo. 欢迎大家相互交流,共同提高技术. 之前对Thrift自动生成代码的实现细节做了详细的分析,下面进行处理层的实现做详细 ...
- Java平台调用Python平台已有算法(附源码及解析)
1. 问题描述 Java平台要调用Pyhon平台已有的算法,为了减少耦合度,采用Pyhon平台提供Restful 接口,Java平台负责来调用,采用Http+Json格式交互. 2. 解决方案 2.1 ...
- thrift之TTransport类体系原理及源码详细解析1-类结构和抽象基类
本章主要介绍Thrift的传输层功能的实现,传输的方式多种多样,可以采用压缩.分帧等,而这些功能的实现都是相互独立,和上一章介绍的协议类实现方式比较雷同,还是先看看这部分的类关系图,如下: 由上面的类 ...
- 机器学习:weka源码在eclipse的配置和异常VerifyError的解决
今天把weka源码导入eclipse,打算学习下weka源码,遇到一些问题,网上资料不足,自己总结下,希望为后来人铺路. 1)新建java项目,命名weka3-6 2)把weka-src.jar解压, ...
- OpenCV学习笔记(27)KAZE 算法原理与源码分析(一)非线性扩散滤波
http://blog.csdn.net/chenyusiyuan/article/details/8710462 OpenCV学习笔记(27)KAZE 算法原理与源码分析(一)非线性扩散滤波 201 ...
- AQS源码详细解读
AQS源码详细解读 目录 AQS源码详细解读 基础 CAS相关知识 通过标识位进行线程挂起的并发编程范式 MPSC队列的实现技巧 代码讲解 独占模式 独占模式下请求资源 独占模式下的释放资源 共享模式 ...
随机推荐
- Hive中的数据库(Database)和表(Table)
在前面的文章中,介绍了可以把Hive当成一个"数据库",它也具备传统数据库的数据单元,数据库(Database/Schema)和表(Table). 本文介绍一下Hive中的数据库( ...
- 网关高可用之keepavlived全流程(安装/配置/验证/解析)
1.场景描述 因为要做网关的高可用,用到了keepalived+nginx,来保证nginx的高可用.(微服务时代之网关及注册中心高可用架构设计),如下图: 安装了keepavlived,走了一些弯路 ...
- STL中排序函数的用法(Qsort,Sort,Stable_sort,Partial_sort,List::sort)
都知道排序很重要,也学了各式各样的排序算法,冒泡.插入.归并等等,但其实在ACM比赛中,只要不是太慢的算法,都可以适用(除非某些题目卡时间卡的很死),这个时候,速度与技巧便成了关键,而在C++的标准库 ...
- 松软科技课堂:SQLUNION和UNIONALL操作符
SQL UNION 操作符 UNION 操作符用于合并两个或多个 SELECT 语句的结果集. 请注意,UNION 内部的 SELECT 语句必须拥有相同数量的列.列也必须拥有相似的数据类型.同时,每 ...
- Linux 笔记 - 第十四章 LAMP 之(一) 环境搭建
博客地址:http://www.moonxy.com 一.前言 LAMP 是 Linux Apache MySQL PHP 的简写,即把 Apache.MySQL 以及 PHP 安装在 Linux 系 ...
- .NET分布式大规模计算利器-Orleans(一)
写在前面 Orleans是基于Actor模型思想的.NET领域的框架,它提供了一种直接而简单的方法来构建分布式大规模计算应用程序,而无需学习和应用复杂的并发或其他扩展模式.我在2015年下半年开始 ...
- 腾讯、阿里、百度、360、114 公共DNS分享
DNS,在互联网有着重要的地位,域名转换成IP,都是DNS在工作. 腾讯 DNS+ IP:119.29.29.29 备用:182.254.116.116 阿里DNS ip:223.5.5.5 223. ...
- [Code] 烧脑之算法模型
把博客的算法过一遍,我的天呐多得很,爱咋咋地! 未来可考虑下博弈算法. 基本的编程陷阱:[c++] 面试题之犄角旮旯 第壹章[有必要添加Python] 基本的算法思想:[Algorithm] 面试题之 ...
- [LeetCode]singleNumber
题目:singleNumber Given an array of integers, every element appears twice except for one. Find that si ...
- elasticsearch的分布式基础概念(1)
Elasticsearch对复杂分布式机制的透明隐藏特性 Elasticsearch是一套分布式的系统,分布式是为了应对大数据量 隐藏了复杂的分布式机制 分片机制(随随便便就将一些document插入 ...