KNN学习笔记

1.     是什么/原理

2.     核心思想:“近朱者赤,近墨者黑”,由你的邻居来推断出你的类别

3.     python实现

4.     算法不足之处

 

1.     k近邻法(KNN)是一种基本分类与回归方法,是“懒惰学习”的代表,其算法的时间复杂度是O(n),一般适用于样本数较少的数据集。其输出可以是多类。

K近邻法的三个基本要素是:k值的选择、距离度量、分类决策规则。

k近邻法没有显式的学习过程,即没有训练阶段,数据集事先已有了分类和特征值,待收到新样本后直接进行处理。

相似度衡量方法:包括欧式距离(p=2)、曼哈顿距离(p=1)、夹角余弦

简单应用中,一般使用欧氏距离,但对于文本分类来说,使用余弦来计算相似度就比欧式距离更合适

 

2.      k近邻法中k值的选择会对k近邻法的结果产生重大影响。选取的k值若较小,就相当于用较小的领域中的训练实例进行预测,“学习”的近似误差会减小,只有与输入实例较近的训练实例才会对预测结果起作用,但缺点是“学习”的估计误差会增大,预测结果会对近邻的实例点非常敏感。反之,若选取的k值较大,其优点是可以减少学习的估计误差,但缺点是学习的近似误差会增大。K值的增大意味整体的模型变得简单(k值越小模型越复杂,k值较小可能产生过拟合的现象)。所以在应用中,k值一般取一个比较小的数值,通常采用交叉验证法来选取最优的k值。

3.       

Q:什么是近似误差和估计误差?

 

答:近似误差可以理解为模型估计值与实际值之间的差距。

       估计误差可以理解为模型的估计系数与实际系数之间的差距。

     近似误差,更关注于“训练”。最小化近似误差,即为使估计值尽量接近真实值,这里的真实值指的是训练样本,模型本身并不是最接近真实分布。换一组样本可能就不近似了,这种训练样本表现好,测试样本表现不好的现象称为过拟合。

估计误差,更关注于“测试”、“泛化”。与近似误差相反,最小化估计误差,即为使估计系数尽量接近真实系数,可能此时对于训练样本得到的估计值不一定最接近真实值,但模型肯呢个更加接近真实分布。

如图(图片来自百度百科)

K值若较小,这里取内圈,红色三角占2/3,则绿色的未知物被判断为红色三角;

K值若较大,这里取外圈,蓝色方块占3/5,则绿色未知物被判断为蓝色方块。

 

4.      实现:

from numpy import *  # 引入科学计算包

import operator  # 经典python函数库。运算符模块。

# 创建数据集

def createDataSet():

   group = array([[1.0, 1.1], [1.0, 1.0], [0, 0], [0, 0.1]])

   labels = ['A', 'A', 'B', 'B']

   return group, labels

 

# 算法核心

# inX:用于分类的输入向量。即将对其进行分类。

# dataSet:训练样本集

# labels: 标签向量

def classfy0(inX, dataSet, labels, k):

# 距离计算(这里用的欧氏距离)

   dataSetSize = dataSet.shape[0]  # 得到数组的行数。即知道有几个训练数据

   diffMat = tile(inX, (dataSetSize, 1)) - dataSet  # tile:numpy中的函数。tile将原来的一个数组,扩充成了4个一样的数组。diffMat得到了目标与训练数值之间的差值。

   sqDiffMat = diffMat ** 2  # 各个元素分别平方

   sqDistances = sqDiffMat.sum(axis=1) # sum(axis=1)函数表示按行求和,一般默认axis=0即默认列求和

distances =sqDistances ** 0.5  # 开方,得到距离。

假如:(这里用的欧氏距离)

Newinput:[1,0,2]

Dataset:

[1,0,1]

[2,1,3]

[1,0,2]

计算过程即为:

1、求差

[1,0,1]       [1,0,2]

[2,1,3]   --  [1,0,2]

[1,0,2]       [1,0,2]

=

[0,0,-1]

[1,1,1]

[0,0,-1]

2、对差值平方

[0,0,1]

[1,1,1]

[0,0,1]

3、将平方后的差值累加

[1]

[3]

[1]

4、将上一步骤的值求开方,即得距离

[1]

[1.73]

[1]

这就是以上的步骤

   sortedDistIndicies = distances.argsort() # 升序排列

    # 选择距离最小的k个点。

   classCount = {}

    fori in range(k):

       voteIlabel = labels[sortedDistIndicies[i]]

       classCount[voteIlabel] = classCount.get(voteIlabel, 0) + 1

    # 排序

   sortedClassCount = sorted(classCount.items(),key=operator.itemgetter(1), reverse=True)    #Python3.5中:iteritems变为items

   return sortedClassCount[0][0]

 

if __name__== '__main__':

   dataSet, labels = createDataSet()

   input = array([1.1, 0.3])

    K =3

   output = classfy0(input, dataSet, labels, K)

print("测试数据为:", input, "分类结果为:", output)

 

5.      算法不足之处:

1.      样本不平衡容易导致结果错误;

2.      计算量较大。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值