KNN (K Nearest Neighbor,K近邻)算法的python实现

       机器学习中KNN是个最基本的分类方法之一。KNN的全称是K Nearest Neighbor,意思很明显:求K个最近的样本。这里需要说明的有两点:1、这个近是通过距离来体现的,我们算距离的方法有很多,最常用的有:cos(余弦距离),曼哈顿(出租车)距离,以及欧几里得距离。一般来说我们可以使用任何一个求距离的公式去求距离;2、这个距离是求解待分类样本与已经标记好的已知样本集中的每个样本之间的距离。

       从上面的分析中,我们可以知道,KNN分类是基于样本和标签的分类方法,即每一个样本必须要有一个明确的标签。所以我们待分类的样本通过该方法进行分类之后也必须也会得到唯一的一个标签与之对应。但是KNN求解的是与待分类样本距离最近的K个已经标记了的已知样本。所以我们得到这K个最近邻的样本后还必须要对这些样本进行按照它们所属的类别进行排序。比如我们的样本集只有6个样本,分别是 [A, B, C, D, E, F],对应的标签分别是[1, 2, 1, 2, 0, 1],待分类样本是G(其中G和样本集中的每个样本的维度应该要一致),通过计算我们发现G与这6个样本之间的欧式距离分别是[0.147, 0.239, 0.159, 0.289, 1.33, 0.247],K=3,那么我们会得到如下结果:[0.147, 0.159, 0.239],对应的标签分别为:[1, 1, 2]那么我们发现样本G可能属于类别1,也有可能属于类别2,但是我们发现G属于类别1的可能性要大些。至于这个可能性一方面是凭直觉,另方面是还是凭直觉([1, 1, 2]),所以我们凭直觉就可以将样本G归为类别1.

       下面给出使用python编写的KNN代码,这个代码里我使用了lambda匿名函数以及python的其它几个内置函数,不熟悉这些东东的用法的盆友们可以翻看我之前写的博客。代码如下:

from math import sqrt


def get_data():
    data = {'data': [], 'label': []}
    group = [[1.0, 1.1], [1.0, 1.0], [0, 0], [0, 0.1]]
    labels = ['A', 'A', 'B', 'B']
    data['data'].append(group)
    data['label'].append(labels)
    return data


def compute_distance(sample, data, k):
    assert isinstance(sample, list) and len(sample) > 0
    assert isinstance(data, dict) and len(data) > 0
    assert len(sample) == len(data['data'][0][0])
    distance = [0] * len(data['data'][0])
    for sample_index in range(0, len(distance), 1):
        distance[sample_index] = sqrt(sum(list(map(lambda x: pow(x[0] - x[1], 2), zip(data['data'][0][sample_index], sample)))))
    distance = sorted(zip(distance, data['label'][0]), reverse=False)
    predicted_label = list(map(lambda x: x[-1], distance[:k]))
    print(predicted_label)
    count_labels = sorted(list(map(lambda x: (x, predicted_label.count(x)), set(data['label'][0]))), reverse=True)
    return count_labels[0][0]

label = compute_distance([0, 0], get_data(), 3)
print('label:', label)
['A', 'B', 'B']
label: B

        

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值