k近邻算法(KNN)

简介

KNN算法是数据挖掘分类技术中最简单的方法之一。它通过测量不同特征值之间的距离进行分类的。其基本思路为:如果一个样本在特征空间中的k个最近邻样本中的大多数属于某一个类别,则该样本也属于这个类别。该方法在决定类别上只依据最近的一个或者几个样本的类别来决定待分类样本所属的类别。

原理

给定一个样本数据集(称为训练集),样本集内每一个数据都已经存在标签。(例如:'兔子'这个数据的标签是'动物')。现在,输入一个新的数据,含有诸多属性,将每一个属性与样本集中的数据对应的属性进行比较,通过算法找到样本集中与它最相似的k个数据, 再获得这k个样本数据出现最多的标签作为这个新数据的标签。

例如

数据编号 腿的个数 翅膀个数 尾巴个数 类别
data1 4 0 0 A
data2 2 1 1 B
data3 0 0 0 C

这时,一个新的数据需要分类。

数据编号 腿的个数 翅膀个数 尾巴个数
datainput 4 0 0

我们将待标记的数据和样本集里面的数据比对,发现它的每一个属性均和data1一致,也只有data1和它完全一致,不难给与标签为A。

在上面这个看似简单的过程中其实有很多值得思考的东西。

首先我是如何判断data1和它一致呢?

我是相同属性去比较的,然后发现每一个属性值完全相同。可是这是因为属性少,数据量少,而且一个“等与不等”就能给出结论。但是事实上很多时候(几乎所有时候)完全一致的两个数据是几乎不存在的,那种情况下那么多的属性,我如何度量两个数据的接近程度,如何得到最接近的k个数据呢?

那么如何得到最接近的k个数据呢?

这个问题其实不难回答,只要求出待标记数据与已知数据的属性距离就ok了,至于距离怎么求?这个也不难,如果只有两个属性,可以建立二维坐标系,求出新数据的点与其他所有点的距离即可。如果属性更多,可以从二维上推广,得到高维两点之间的距离公式。

这个公式其实就是欧几里得度量公式。(也可以使用曼哈顿距离公式,当然这两个都是闵可夫斯基距离公式的特例,但是只有欧式距离保证收敛)

就这样,我们计算出了待标记数据和所有样本数据的距离,这是个数值,比较得到最接近的k个数据,统计这k个数据的标签频率,选取出现频率最高的或者最高的中的一个,为新数据打上标签。

k值的选择

统计学方法中参数选择一般是要在偏差(Bias)与方差(Variance)之间取得一个平衡(Tradeoff)。对KNN而言,k值的选择也要在偏差和方差之间取得平衡。若k取值太小,则分类结果可能因为噪声点的干扰而出现错误,此时方差较大;若k取值太大,假设达到样本数据总量,那么对所有的测试样本而言,结果都一样,分类的结果都是样本最多的类别,这样稳定是稳定了,但是预测结果与真实值相差太远,偏差过大。因此,k值既不能太大也不能太小,通常的做法是,利用交叉验证(Cross Validation)评估一系列不同的k值,选取结果最好的k值作为训练参数。

实战

使用KNN实现约会网站的配对效果

项目描述

假设存在这样一种情况,海伦使用在线约会网站寻找合适自己的约会对象,尽管网站时常推荐,但是她没有找到合适的人。经过总结,她发现交往过三类人。

  • 不喜欢的(类别1)
  • 魅力一般的(类别2)
  • 极具魅力的)类别3)

尽管发现了这个规律,但是海伦依然无法将约会网站匹配的对象划分到恰当类别中,海伦希望分类软件可以更好地帮助她将匹配对象划分到正确的分类中。此外,海伦还收集到一些约会网站未曾记录的信息,她认为这些数据有助于匹配对象的分类。

根据已有数据集,不难发现每个样本数据有三个特征一个类别,但是发现飞行里程数都是上万的,而其他两项的值都不超过10,在计算距离时就会造成这个特征值权重极大,这是不合理的,因为三个特征影响程度应该相当,这里通过归一化处理数据集的特征值。

代码实现(注意区别

自行编写KNN算法

# -*-coding:utf-8-*-
from numpy import *
import operatordef classify0(inX, dataSet, labels, k):'''利用距离公式计算出最接近的k个样本中出现最多的标签:param inX: 待分类的样本:param dataSet: 特征矩阵:param labels: 类别矩阵:param k: k值:return: 最接近的标签'''print(inX)dataSetSize = dataSet.shape[0]diffMat = tile(inX, (dataSetSize, 1)) - dataSetsqDiffMat = diffMat ** 2sqDisttances = sqDiffMat.sum(axis=1)distances = sqDisttances ** 0.5sortedDistIndicies = distances.argsort()classCount = {}for i in range(k):voteIlabel = labels[sortedDistIndicies[i]]classCount[voteIlabel] = classCount.get(voteIlabel, 0) + 1# 依照标签出现的频率排序sortedClassCount = sorted(classCount.items(), key=operator.itemgetter(1), reverse=True)# 选取频率最大的标签return sortedClassCount[0][0]def file2matrix(filename):'''数据读取为矩阵:param filename: 文件名:return: 特征矩阵, 标签矩阵'''fr = open(filename)arrayOLines = fr.readlines()numberOfLines = len(arrayOLines)returnMat = zeros((numberOfLines, 3))classLabelVector = []index = 0for line in arrayOLines:line = line.strip()listFromLine = line.split('\t')returnMat[index, :] = listFromLine[0:3]classLabelVector.append(int(listFromLine[-1]))index += 1return returnMat, classLabelVectordef autoNorm(dataSet):'''归一化数据:param dataSet: 数据集:return: 归一化后的数据集'''minVals = dataSet.min(0)maxVals = dataSet.max(0)ranges = maxVals - minValsm = dataSet.shape[0]normDataSet = dataSet - tile(minVals, (m, 1))normDataSet = normDataSet / tile(ranges, (m, 1))print(normDataSet)return normDataSet, ranges, minValsdef classifyPerson():'''网站实测:return: 可能标签'''resultList = ['不喜欢', '一般喜欢', '特别喜欢']percentTats = float(input("玩游戏占的百分比"))ffMiles = float(input("每年坐飞机多少公里"))iceCream = float(input("每年吃多少公升的冰淇淋"))datingDataMat, datingLabels = file2matrix('data/datingTestSet2.txt')normMat, ranges, minVals = autoNorm(datingDataMat)inArr = array([ffMiles, percentTats, iceCream])print((inArr - minVals) / ranges)classifierResult = classify0((inArr - minVals) / ranges, normMat, datingLabels, 3)print("你将有可能对这个人是:", resultList[int(classifierResult) - 1])if __name__ == '__main__':classifyPerson()

使用sklearn的KNN模块

# -*-coding:UTF-8 -*-
from sklearn.neighbors import KNeighborsClassifier
from sklearn.preprocessing import MinMaxScaler
from numpy import *def file2matrix(filename):'''数据读取为矩阵:param filename: 文件名:return: 特征矩阵, 标签矩阵'''fr = open(filename)arrayOLines = fr.readlines()numberOfLines = len(arrayOLines)returnMat = zeros((numberOfLines, 3))classLabelVector = []index = 0for line in arrayOLines:line = line.strip()listFromLine = line.split('\t')returnMat[index, :] = listFromLine[0:3]classLabelVector.append(int(listFromLine[-1]))index += 1return returnMat, classLabelVectordef autoNorm(dataSet):'''归一化数据:param dataSet: 数据集:return: 归一化后的数据集'''minVals = dataSet.min(0)maxVals = dataSet.max(0)ranges = maxVals - minValsmin_max_scaler = MinMaxScaler()normDataSet = min_max_scaler.fit_transform(dataSet)return normDataSet, ranges, minValsdef classifyPerson(model):'''网站实测:return: 可能标签'''resultList = ['不喜欢', '一般喜欢', '特别喜欢']percentTats = float(input("玩游戏占的百分比"))ffMiles = float(input("每年坐飞机多少公里"))iceCream = float(input("每年吃多少公升的冰淇淋"))datingDataMat, datingLabels = file2matrix('data/datingTestSet2.txt')normMat, ranges, minVals = autoNorm(datingDataMat)inArr = array([[ffMiles, percentTats, iceCream]])model.fit(normMat, datingLabels)print((inArr - minVals) / ranges)rst = model.predict((inArr - minVals) / ranges)print("你将有可能对这个人是:", resultList[int(rst) - 1])if __name__ == '__main__':model = KNeighborsClassifier(n_neighbors=3, weights='uniform', algorithm='auto', leaf_size=30,p=2, metric='minkowski', metric_params=None, n_jobs=1)classifyPerson(model)

补充说明

参考《Python3数据分析与机器学习实战》,具体的代码和数据集可以在我的GitHub找到,欢迎star或者fork。

机器学习-分类之K近邻算法(KNN)原理及实战相关推荐

  1. K近邻算法(KNN)原理小结

    点击上方"小白学视觉",选择加"星标"或"置顶" 重磅干货,第一时间送达 目录 1. KNN算法原理 2. KNN算法三要素 3. KNN算 ...

  2. 【机器学习入门】(1) K近邻算法:原理、实例应用(红酒分类预测)附python完整代码及数据集

    各位同学好,今天我向大家介绍一下python机器学习中的K近邻算法.内容有:K近邻算法的原理解析:实战案例--红酒分类预测.红酒数据集.完整代码在文章最下面. 案例简介:有178个红酒样本,每一款红酒 ...

  3. k近邻算法(KNN)-分类算法

    k近邻算法(KNN)-分类算法 1 概念 定义:如果一个样本在特征空间中的k个最相似(即特征空间中最邻近)的样本中的大多数属于某一个类别,则该样本也属于这个类别. k-近邻算法采用测量不同特征值之间的 ...

  4. 基于KD树的K近邻算法(KNN)算法

    文章目录 KNN 简介 KNN 三要素 距离度量 k值的选择 分类决策规则 KNN 实现 1,构造kd树 2,搜索最近邻 3,预测 用kd树完成最近邻搜索 K近邻算法(KNN)算法,是一种基本的分类与 ...

  5. 01 K近邻算法 KNN

    01 K近邻算法 KNN k近邻算法基础 等价于 scikit-learn中的机器学习算法封装 训练数据集,测试数据集 分类准确度 超参数 考虑距离权重 更多关于距离的定义 搜索明可夫斯基距离相应的p ...

  6. 基于kd树的k近邻算法——KNN

    1.简介 k近邻算法是机器学习中一种基本的分类与回归算法,对你没听错k近邻算法不仅可以用来做分类,还可以用于回归,英文全称为k-Nearest Neighbor简称k-NN.k近邻算法属于一种有监督学 ...

  7. k近邻算法 (KNN)

    k近邻算法 k近邻算法(KNN,K-NearestNeighbor)是一种基本分类和回归方法,监督学习算法,本质上是基于一种数据统计的方法: 核心思想:给定一个训练数据集,对新的输入实例,在训练数据集 ...

  8. chapter2 机器学习之KNN(k-nearest neighbor algorithm)--K近邻算法从原理到实现

    一.引入 K近邻算法作为数据挖掘十大经典算法之一,其算法思想可谓是intuitive,就是从训练集里找离预测点最近的K个样本来预测分类 因为算法思想简单,你可以用很多方法实现它,这时效率就是我们需要慎 ...

  9. 2 机器学习 K近邻算法(KNN) 学习曲线 交叉验证 手写数字识别

    机器学习 1 K-近邻算法介绍 1.1 分类问题 分类问题:根据已知样本的某些特征,判断一个未知样本属于哪种样本类别. 与回归问题相比,分类问题的输出结果是离散值,用于指定输入的样本数据属于哪个类别. ...

最新文章

  1. 15.文件系统——软RAID的实现(二)(mdadm,watch, RAID1)
  2. 学习笔记 --- 编码过程中常见的三种异步方式
  3. 007_Buzz事件
  4. Tensorflow中张量数据类型的转换
  5. python selenium api_Selenium2+python自动化-查看selenium API
  6. 线程的五大状态及转换
  7. 回购价低于股价怎么办?
  8. python装饰器详解-python装饰器的详细解析
  9. 深度学习2.0-23.Keras高层接口之模型的加载与保存
  10. 拓端tecdat:matlab数据可视化交通流量分析天气条件、共享单车时间序列数据
  11. elasticsearch 批量插入
  12. 暗黑3服务器维护时间多久,暗黑3亚服维护近24小时 将封10万账号
  13. jquery html app,jquery .html()vs .append()
  14. Golang方差算法
  15. Github系列教程一 ————开门
  16. 跟小甲鱼学Web开发笔记06(最新进展不按进度顺序)
  17. java中像scanf一样多个输入_VB模拟键盘输入的N种方法
  18. Tyrion 中文文档(含示例源码)
  19. 分布式事务解决方案——TCC
  20. 【Java面试】什么是字节码?采用字节码的好处是什么?

热门文章

  1. NIO和BIO如何影响应用程序的设计-设置处理线程数
  2. MyBatis 源码解读-loadCustomVfs(settings)
  3. 延时加载refresh()方法
  4. idea 自动导入包和自动将没用的包去除
  5. Filter_细节_过滤器拦截方式配置
  6. MySQL常用存储引擎之Innodb
  7. 组合模式源码解析(jdk+mybatis)
  8. 外观模式coding
  9. 使用Github(仓库管理)
  10. linux系统牵引程序设置,Linux上安装Wine运行AutoCAD实例[多图]