最近邻算法(KNN)

最近邻算法:

1.什么是最近邻是什么?

  kNN算法全程是k-最近邻算法(k-Nearest Neighbor)

  kNN算法的核心思想是如果一个样本在特征空间中的k个最相邻的样本中的大多数数以一个类型别,则该样本也属于这个类别,并具有该类别上样本的特征。该方法在确定分类决策上,只依据最近邻的一个或者几个样本的类别来决定待分样本所属的类别。

下面举例说明:

 

即使不知道未知电影属于哪个类型,我们也可以通过某种方式计算,如下图

 

现在,我们得到了样本集中与未知电影的距离,按照距离的递增顺序,可以找到k个距离最近的电影,假设k=3,则三个最靠近的电影是he is not realy into Dudes,Beautiful women, California man , kNN 算法按照距离最近的三部电影类型决定未知电影的类型,这三部都是爱情片,所以未知电影的类型也是爱情片。

2:kNN算法的一般流程

  • step.1---初始化距离为最大值
  • step.2---计算未知样本和每个训练样本的距离dist
  • step.3---得到目前K个最邻近样本中的最大距离maxdist
  • step.4---如果dist小于maxdist, 则将训练样本作为K-最近邻样本
  • step.5---重复步骤2,3,4,直到未知样本和所有训练样本的距离都算完
  • step.6---统计K-最近邻样本中每个类标号出现的次数
  • step.7---出现频率最大的类标号最为未知样本的类标号

3.距离公式

在KNN算法中,通过计算对象间距离作为各个对象之间的非相似性指标,避免了对象之间的匹配问题,在这里距离一般使用欧式距离或者曼哈顿距离:

 

 对应代码如下

#  kNN算法全称是k-最近邻算法(K-Nearest Neighbor)
from numpy import *
import operator

# 创建数据函数
def createDataSet():
    """ 创建数据集,array 创建数组
    array数组内依次是打斗次数, 接吻次数
    group小组, labels标签"""
    group = array([[3, 104], [2, 100], [1, 81], [101, 10], [99, 5], [98, 2]])
    labels = ["爱情片", "爱情片", "爱情片", "动作片", "动作片", "动作片"]
    return group, labels

# 归类函数
def classify(inX, dataSet, labels, k):
    """ 获取维度,
     inX 待测目标的数据,
     dataSet 样本数据,
     labels 标签,
     k 设置比较邻近的个数"""
    dataSetSize = dataSet.shape[0]  # 训练数据集数据 行数
    print(dataSetSize)
    print(tile(inX, (dataSetSize, 1)))

    diffMat = tile(inX, (dataSetSize, 1)) - dataSet  # 测试数据,样本之间的数据 矩阵偏差
    print(diffMat)

    sqDiffMat = diffMat**2  # 平方计算,得出每个距离的值
    print(sqDiffMat)

    sqDistance = sqDiffMat.sum(axis=1)  # 输出每行的值
    print(sqDistance)

    distances = sqDistance**0.5  # 开方计算
    print(distances)

    sortedDistances = distances.argsort()  # 排序 按距离从小到大 输出索引
    print(sortedDistances)

    classCount = {}
    for i in range(k):
        voteIlabel = labels[sortedDistances[i]] + 1.0 # 按照排序,获取k个对应的标签
        classCount[voteIlabel] = classCount.get(voteIlabel, 0)  # 在字典中添加距离最近的k个对应标签
    sortedClassCount = sorted(classCount.items(), key=operator.itemgetter(1), reverse=True)

    return sortedClassCount[0][0]

group, labels = createDataSet()
res = classify([18, 90], group, labels, 3)
print(res)

 运行结果:

 

 

 知识扩展:

python3字典中items()和python2.x中iteritems()有什么不同?
numpy中 array数组的shape属性
numpy 中 shape_base提供的tile方法

 

posted @ 2018-11-27 19:54  pupilheart  阅读(18161)  评论(1编辑  收藏  举报
点击游惊戏

公告:昔日最爱

数学中国 【python交流群】921487667