《机器学习实战》学习笔记——kNN算法
2015-06-05 17:04
253 查看
《机器学习实战》(MLiA)是一本介绍机器学习的书(的确是废话),和其他书不同的地方在于它给出了python的实现代码,而其他的书籍重在解释理论。我作为一名渣渣,理论就先放一放了。
MLiA的第一章主要介绍了一些概念、常识性的东西,所以不做介绍,这篇文章主要介绍k-近邻算法(kNN)。
kNN算法的优点是精度高,对异常值(离群点)不敏感且不需要训练;缺点是计算复杂度、空间复杂度高。
kNN算法的适用范围是数值型和标称型数据。
kNN工作原理是:
存在一个样本数据集合,也称作训练样本集,并且样本集中每个数据都存在标签,即我们知道样本集中每一数据与所属分类的对应关系。输人没有标签的新数据后,将新数据的每个特征与样本集中数据对应的特征进行比较,然后算法提取样本集中特征最相似数据(最近邻)的分类标签。一般来说,我们只选择样本数据集中前k个最相似的数据,这就是k-近邻算法中k的出处,通常k是不大于20的整数。最后,选择k个最相似数据中出现次数最多的分类,作为新数据的分类。
kNN算法的算法流程为:
(1).计算已知类别数据集中的点与当前点之间的距离;
(2).按照距离递增次序排序;
(3).选取与当前点距离最小的k个点;
(4).确定前k个点所在类别的出现频率;
(5).返回前k个点出现频率最高的类别作为当前点的预测分类。
既然算法流程已经明确,现在开始构造自己的算法。《MLiA》中采用的是python来构造的算法,原因是机器学习的算法大都需要处理复杂的矩阵运算。鉴于自己的算法处理的数据特征维数并不多,矩阵运算较少,故写了一个简单的c++版本
这样就完成了一个简单版的kNN。
测试:
输入0.1 ,0.2, k = 5,结果如下:
输入0.8, 1.2, k = 5, 结果如下:
MLiA的第一章主要介绍了一些概念、常识性的东西,所以不做介绍,这篇文章主要介绍k-近邻算法(kNN)。
kNN算法的优点是精度高,对异常值(离群点)不敏感且不需要训练;缺点是计算复杂度、空间复杂度高。
kNN算法的适用范围是数值型和标称型数据。
kNN工作原理是:
存在一个样本数据集合,也称作训练样本集,并且样本集中每个数据都存在标签,即我们知道样本集中每一数据与所属分类的对应关系。输人没有标签的新数据后,将新数据的每个特征与样本集中数据对应的特征进行比较,然后算法提取样本集中特征最相似数据(最近邻)的分类标签。一般来说,我们只选择样本数据集中前k个最相似的数据,这就是k-近邻算法中k的出处,通常k是不大于20的整数。最后,选择k个最相似数据中出现次数最多的分类,作为新数据的分类。
kNN算法的算法流程为:
(1).计算已知类别数据集中的点与当前点之间的距离;
(2).按照距离递增次序排序;
(3).选取与当前点距离最小的k个点;
(4).确定前k个点所在类别的出现频率;
(5).返回前k个点出现频率最高的类别作为当前点的预测分类。
既然算法流程已经明确,现在开始构造自己的算法。《MLiA》中采用的是python来构造的算法,原因是机器学习的算法大都需要处理复杂的矩阵运算。鉴于自己的算法处理的数据特征维数并不多,矩阵运算较少,故写了一个简单的c++版本
/* kNN.cpp * @author: Toroto */ #include <iostream> #include <math.h> using namespace std; #define DSSIZE 8 //训练集大小 /* * 数据结构: * 包含两个特征:x, y * 及标记:label */ struct data{ float x, y; char label; }; data D[DSSIZE]; //训练集 float dis[DSSIZE]; //距离数组 //设置训练集: //{(0,0),(0,0.1),(0,0.2)(0,0.3),(1,1.4),(1,1.5),(1,1.6),(1,1.7)} void init(int x){ for (int i = 0; i < x; i++){ if (i < 4){ D[i].x = 0; D[i].label = 'A'; } else { D[i].x = 1; D[i].label = 'B'; } D[i].y = D[i].x + 0.1 * i; } }; /* * kNN算法实现: * 参数: * x, y: 目标向量 k:最近邻居的数目 * 返回值:待分类向量的标签 */ char kNN(float x, float y, int k){ float temp; data tem; for (int i = 0; i < DSSIZE; i++){ //计算目标向量到各训练数据的距离 dis[i] = pow(pow(x - D[i].x, 2) + pow(y - D[i].y, 2), 0.5); // cout << "i = " << i << "; distance = " << dis[i] << endl; } //排序 for (int i = 0; i < DSSIZE; i++){ for (int j = i; j < DSSIZE; j++){ if (dis[i] > dis[j]){ temp = dis[i]; dis[i] = dis[j]; dis[j] = temp; tem = D[i]; D[i] = D[j]; D[j] = tem; } } } /* for (int i = 0; i < DSSIZE; i++){ cout << D[i].x << " " << D[i].y << " " << D[i].label << " " << dis[i] << endl; } //*/ int label_A = 0, label_B = 0; //在给定数目的最近邻居中选择出现次数最多的邻居 for (int i = 0; i < k; i++){ if (D[i].label == 'A') label_A++; else label_B++; } return label_A > label_B ? 'A' : 'B'; } int main(){ init(DSSIZE); int k; float x, y; char label; cout << "输入x, y: "; cin >> x >> y; cout << "输入k :"; cin >> k; label = kNN(x * 1.0, y * 1.0, k); cout << label << endl; return 0; };
这样就完成了一个简单版的kNN。
测试:
输入0.1 ,0.2, k = 5,结果如下:
输入0.8, 1.2, k = 5, 结果如下:
相关文章推荐
- android 代码实现控件之间的间距
- [Android]在代码里运行另一个程序的方法
- 肯特·贝克:改变人生的代码整理魔法
- 网页恶意代码的预防
- 高手写的Tracer-Flash代码调试类代码下载
- CSS代码缩写技巧
- 非主流Q-zOne代码代码搜集第1/2页
- CreateWeb.vbs 代码
- Lua中编译执行代码相关的函数详解
- 更有效率的css代码编写第1/3页
- 代码中到底应不应当写注释?
- SQL语言查询基础:连接查询 联合查询 代码
- 论坛头像随机变换代码
- .NET 常用功能和代码小结
- C#实现压缩HTML代码的方法
- asp编程中常用的javascript辅助代码第1/2页
- C#超实用代码段合集
- Javascript代码在页面加载时的执行顺序介绍
- JS实现图片无间断滚动代码汇总
- 我的论坛源代码(二)