C++ with Machine Learning -K–nearest neighbors

我本想写C++与人工智能,但是转念一想,人工智能范围太大了,我根本介绍不完也没能力介绍完,所以还是取了他的子集。我想这应该是一个有关机器学习的系列文章,我会不定期更新文章,希望喜欢机器学习的朋友不宁赐教。

本系列特别之处是与一些实例相结合来系统的讲解有关机器学习的各种算法,由于能力和时间有限,不会向诸如Simon Haykin<<NEURAL NETWORKS>>等大块头详细的讲解某一个领域的所有算法与概念,我会有选择的讲解一些算法作为引导,如果要继续深入则推荐读者系统阅读相关书籍。

首先你需要做的事情就是放松,不要被一大堆字吓到,因为他们都非常浅显易懂,我相信认真看的每个人都能明白K近邻算法。

K–nearest neighbors,简称 KNN/kNN,用来处理分类和回归,它是最简单的Machine Learning Algorithm,所以以它为开端。

这里考虑一个实例,有两个小组AB,A组为实践组,B组为理论组,A组的实践分平均为90,理论为30,B组实践分为20分,理论分为70分,现在有一个同学实践60分,理论60分,她到底属于哪个组?

就像上面的图片一样,不过我们可以使用欧氏距离[附录]计算出未知点与其他四个点的距离(相似度/相似值),然后把计算出来的值从小到大排序,选择K个值(这就是k的由来),这K个值都是选择最小的。

比如最后用欧氏距离计算出来的距离是

与1点的距离:5,

与2点的距离:5.3

与3点的距离:2.2

与4点的距离:7.12

我们就需要对上面排序,排成这样:

与3点的距离:2.2

与1点的距离:5,

与2点的距离:5.3

与4点的距离:7.12

整理一下上面的思路:

1)读取训练样本集(这里我用x0y0和type三个数组分别保存每个数据的第一个特征值第二个特征值和类型)

2)读取需要分类的数据,然后计算需要分类的数据和训练样本集中每个数据的距离(计算出来的数据需要用map之类的容器与类型关联)

3)把上面计算的每个距离排序(map排序)

4)假设是从上到下升序,那就从上选择k个值

5)统计这k个之中哪个类型出现频率最高,最高的就是分类结果

这里假设K=3,就意味这我们需要选择前面三个数据,然后判断前面三个数据中A和B,3点是B类,1点是A类,2点是B类,这里显然B类多一些,所以未知数就是B类,到这里算法是想就解释了,很简单把,因为它是最简单的ML算法,下面就是C++的实现了

//A bad version about k-nearest neighbour algorithm,just a teaching sample.
#include <iostream>
#include <algorithm>
#include <map>
#include <math.h> const int k=3; std::ostream & operator<<(std::ostream& out, const std::pair<double,char>& p) {
return out << p.first << "\t" << p.second;
}
//训练样本数据集
class simple_data{
public:
simple_data(double x,double y,char classtype):
type(classtype),datx(x),daty(y)
{}
inline double get_distance(double x0,double y0){
return sqrt((pow(datx-x0,2)+pow(daty-y0,2)));//欧氏距离
}
char type;
private:
double datx;
double daty;
}; int main(){
//构造<span style="font-family: Arial, Helvetica, sans-serif;">训练样本数据集,这样正常情况下应该从文本读入。为了方便就直接构造了</span>
simple_data sd1(1.0,2.0,'A');
simple_data sd2(2.0,3.0,'A');
simple_data sd3(12.0,13.0,'B');
simple_data sd4(8.0,9.0,'B'); //读入需要分类的新数据,并计算它和所有点的距离
double newdata[2]={1.0,1.0};
std::map<double,char> mp;
mp.insert(std::pair<double,char>(sd1.get_distance(newdata[0],newdata[1]),sd1.type));
mp.insert(std::pair<double,char>(sd2.get_distance(newdata[0],newdata[1]),sd2.type));
mp.insert(std::pair<double,char>(sd3.get_distance(newdata[0],newdata[1]),sd3.type));
mp.insert(std::pair<double,char>(sd4.get_distance(newdata[0],newdata[1]),sd4.type));
//得到相似度,并进行排序,最后输出
unsigned int acout=0,bcout=0,i=0;
std::cout<<"相似度:"<<'\t'<<"类型:\n";
for(std::map<double,char>::iterator iter = mp.begin();
iter != mp.end();++iter)
{
i++;
std::cout << *iter <<std::endl;
if(i<k){
if(mp[i]='A'){
acout++;
}else{
bcout++;
}
}
}
if(acout>bcout)
std::cout<<"未知类型数属于:A";
else
std::cout<<"未知类型数属于:B" }

这是一个比较糟糕的版本,比如样本数据直接指定了(一般是从其他文件读入),不过目的很简单就是这样能省去一些读写文件的代码能看得清楚一些。

这里我写了一个拙劣的KNN API:https://github.com/racaljk/MachineLearning

有待改进的地方还有很多,我会陆续完善它。

补充

如果要计算2个以上特征值需要注意的除了改变距离计算方法之外还要注意K值尽量不要太大,实际上这一rule也存在于两个特征值,K值的大小和和数据的精确度是影响计算的两个方面,又尤其是数据精确度,建议尽量三位小数内进行计算,因为最后我们的目的是分类不是精确计算。

附:

1)欧氏距离

最常见的两点之间或多点之间的距离表示法,又称之为欧几里得度量,它定义于欧几里得空间中,如点 x = (x1,...,xn) 和 y = (y1,...,yn) 之间的距离为:

二维平面上两点a(x1,y1)与b(x2,y2)间的欧氏距离:

本文由于只有两个特征值(就是XY)所以使用的,到底如何选择请根据实际情况而定,假如你需要分类的特征值除了理论分数实践分数之外还包括思想品德分数英语分数,显然就必须使用第一个公式.

2)曼哈顿距离(from http://blog.csdn.net/v_july_v/article/details/8203674/)

比较常见的一个距离计算,如A星寻路算法就使用的曼哈顿距离计算。

(1)二维平面两点a(x1,y1)与b(x2,y2)间的曼哈顿距离 
(2)两个n维向量a(x11,x12,…,x1n)与 b(x21,x22,…,x2n)间的曼哈顿距离 

[机器学习系列] k-近邻算法(K–nearest neighbors)的更多相关文章

  1. 第四十六篇 入门机器学习——kNN - k近邻算法(k-Nearest Neighbors)

    No.1. k-近邻算法的特点 No.2. 准备工作,导入类库,准备测试数据 No.3. 构建训练集 No.4. 简单查看一下训练数据集大概是什么样子,借助散点图 No.5. kNN算法的目的是,假如 ...

  2. 机器学习03:K近邻算法

    本文来自同步博客. P.S. 不知道怎么显示数学公式以及排版文章.所以如果觉得文章下面格式乱的话请自行跳转到上述链接.后续我将不再对数学公式进行截图,毕竟行内公式截图的话排版会很乱.看原博客地址会有更 ...

  3. 02-16 k近邻算法

    目录 k近邻算法 一.k近邻算法学习目标 二.k近邻算法引入 三.k近邻算法详解 3.1 k近邻算法三要素 3.1.1 k值的选择 3.1.2 最近邻算法 3.1.3 距离度量的方式 3.1.4 分类 ...

  4. k近邻算法

    k 近邻算法是一种基本分类与回归方法.我现在只是想讨论分类问题中的k近邻法.k近邻算法的输入为实例的特征向量,对应于特征空间的点,输出的为实例的类别.k邻近法假设给定一个训练数据集,其中实例类别已定. ...

  5. 机器学习(四) 分类算法--K近邻算法 KNN (上)

    一.K近邻算法基础 KNN------- K近邻算法--------K-Nearest Neighbors 思想极度简单 应用数学知识少 (近乎为零) 效果好(缺点?) 可以解释机器学习算法使用过程中 ...

  6. 机器学习(1)——K近邻算法

    KNN的函数写法 import numpy as np from math import sqrt from collections import Counter def KNN_classify(k ...

  7. 02机器学习实战之K近邻算法

    第2章 k-近邻算法 KNN 概述 k-近邻(kNN, k-NearestNeighbor)算法是一种基本分类与回归方法,我们这里只讨论分类问题中的 k-近邻算法. 一句话总结:近朱者赤近墨者黑! k ...

  8. Python3入门机器学习 - k近邻算法

    邻近算法,或者说K最近邻(kNN,k-NearestNeighbor)分类算法是数据挖掘分类技术中最简单的方法之一.所谓K最近邻,就是k个最近的邻居的意思,说的是每个样本都可以用它最接近的k个邻居来代 ...

  9. 机器学习:k-NN算法(也叫k近邻算法)

    一.kNN算法基础 # kNN:k-Nearest Neighboors # 多用于解决分裂问题 1)特点: 是机器学习中唯一一个不需要训练过程的算法,可以别认为是没有模型的算法,也可以认为训练数据集 ...

随机推荐

  1. Spring4 AOP详解

    Spring4 AOP详解 第一章Spring 快速入门并没有对Spring4 的 AOP 做太多的描述,是因为AOP切面编程概念不好理解.所以这章主要从三个方面详解AOP:AOP简介(了解),基于注 ...

  2. Listview嵌套Listview

    今天做项目,打算模仿淘宝的订单管理,需要Listview嵌套Listview,都是两个控件都是沿着一个方向滑动的,嵌套在一起不幸福,以下是解决方案,打个笔记,以后估计还得用: 其中onMeasure函 ...

  3. Gluon炼丹(Kaggle 120种狗分类,迁移学习加双模型融合)

    这是在kaggle上的一个练习比赛,使用的是ImageNet数据集的子集. 注意,mxnet版本要高于0.12.1b2017112. 下载数据集. train.zip test.zip labels ...

  4. 面试相关-转载-well,yzl——持续更新

    转载yl,yzl大神的面经,顺便自己复习一下专业课的内容 操作系统相关: 什么是进程, 什么是线程.它们之间的区别和联系. 进程管理内存资源+运行过程, 线程只管理运行过程, 线程要在进程提供的资源基 ...

  5. Unity3D手机斗地主游戏开发实战(04)_出牌判断大小(已完结)

    之前我们实现了叫地主.玩家和电脑自动出牌主要功能,但是还有个问题,出牌的时候,没有有效性检查和比较牌力大小.比如说,出牌3,4,5,目前是可以出牌的,然后下家可以出任何牌如3,6,9. 问题1:出牌检 ...

  6. MySQL查看和修改表的存储引擎(转载+加点东西)

    1 查看系统支持的存储引擎 show engines; 2 查看表使用的存储引擎 两种方法: a.show table status from YOUR_DB_NAME where name='YOU ...

  7. 独家分析:安卓“Janus”漏洞的产生原理及利用过程

    近日,Google在12月发布的安卓系统安全公告中披露了一个名为"Janus"安卓漏洞(漏洞编号:CVE-2017-13156).该漏洞可以让攻击者绕过安卓系统的signature ...

  8. cookie解决跨域问题

    v一.前言 随着项目模块越来越多,很多模块现在都是独立部署.模块之间的交流有时可能会通过cookie来完成.比如说门户和应用,分别部署在不同的机器或者web容器中,假如用户登陆之后会在浏览器客户端写入 ...

  9. redis秒杀

    用Redis轻松实现秒杀系统 秒杀系统的架构设计 秒杀系统,是典型的短时大量突发访问类问题.对这类问题,有三种优化性能的思路: 写入内存而不是写入硬盘 异步处理而不是同步处理 分布式处理 用上这三招, ...

  10. select控件自动触发change事件

    这里接上面的二级联动.背景:当页面跳转到修改页面时,需要首先绑定学院和专业.这就需要在页面加载时触发select的change事件,具体用trigger函数进行实现.代码如下. $("#xs ...