关于KNN算法的基础及其底层代码实现

本文介绍了K近邻算法的基本概念,包括其工作原理、步骤,以及常用的几种距离计算方法。通过实例演示如何使用欧几里得距离法处理电影数据,预测未知样本的类别。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

算法核心

对于一个样本来说,选择K个离其最近的样本。这k个样本都有自己的类别,在这k个之中,哪个种类最多,则该样本属于哪一类别。

(一般k自己取一个较小的值)

算法实现流程(以下我们将样本简称为点):

首先:计算数据集中已知类的点与我们选择要识别的点的距离。

然后:按距离以递增的次序排列。

紧接:自己定一个k值,然后选取与要识别的点的距离最小的k个点。

其次:统计k个点中,各个类别出现的概率。

最后:取概率最高的类别作为要识别的点的类别。

(样本的维度:一般而言样本的维度其实就是其特征的多少)

准备工作:

如何计算距离:

补充知识点(以下为我们常用的知识点):

(x,y皆为样本,或者说是样本的特征向量,特征的值相减的时候是对应的)

欧几里得距离:d(x,y)=\sqrt{\sum_{i}^{}(x_{i}-y_{i})_{}^{2}}
曼哈顿距离:d(x,y)=\sum_{i}^{}|x_{i}-y_{i}|
切比雪夫距离(棋盘距离,因为与国际象棋的棋盘的距离计算有异曲同工之妙):d(x,y)=max_{i}|x_{i}-y_{i}|

这个距离计算公式的意思是:两点之间的距离为其各个特征向量值的差的绝对值中的最大值。

闵可夫斯基距离:d(x,y)=(\sum_{i}|x_{i}-y_{i}|^{p} )^{1/p}

这个距离公式和上面的欧几里得距离还有曼哈顿距离公式有联系,可以尝试带入数值p

汉明距离:d(x,y)=1/N_{i}\sum _{x_{i}!=y_{i}} 1

该距离常用于表示两个长度相同的字中不同的字的数量。可对两个字符串进行异或运算,统计结果为1的个数即可。

余弦相似度:

通过测量两个(样本)点的特征向量夹角的余弦值,来度量它们之间的相似性。

用于代码实现的示例数据集

代码实现

提取数据:
有分类的数据:
movie_data = {"宝贝当家": [45, 2, 9, "喜剧片"],
              "美人鱼": [21, 17, 5, "喜剧片"],
              "澳门风云3": [54, 9, 11, "喜剧片"],
              "功夫熊猫3": [39, 0, 31, "喜剧片"],
                 "谍影重重": [5, 2, 57, "动作片"],
                  "叶问3": [3, 2, 65, "动作片"],
                 "伦敦陷落": [2, 3, 55, "动作片"],
              "我的特工爷爷": [6, 4, 21, "动作片"],
              "奔爱": [7, 46, 4, "爱情片"],
              "夜孔雀": [9, 39, 8, "爱情片"],
              "代理情人": [9, 38, 2, "爱情片"],
              "新步步惊心": [8, 34, 17, "爱情片"]}
我们要判断的数据:
data=['唐人街探案',23,3,17,'?']
数据清洗:
index_row=[]
index_clo=[]
for x in movie_data.keys():
    index_row.append(x)
for x in movie_data.values():
    index_clo.append(x)
print(index_row)
print(index_clo)
#  需要判断的数据:
data=['唐人街探案',23,3,17,'?']
#清洗
data_test=[23,3,17]
选择距离的计算方法:
#选择测量距离的方法:
#欧几里得距离法
dic_data={}
def Ojld(a,b):
    c=math.sqrt((a[0]-b[0])**2+(a[1]-b[1])**2+(a[2]-b[2])**2) #计算距离
    d=b[-1] #提取影片类别
    global dic_data
    dic_data.update({c:d})#生成 距离:影片类别 字典
for x in index_clo: # 带入函数计算
    print(x)
    Ojld(data_test,x)
print(dic_data)  #得到字典
list_sort=list(dic_data.keys())#得到距离列表
list_sort.sort()#将距离从小到大排序
print(list_sort)
完整代码:
import math
movie_data = {"宝贝当家": [45, 2, 9, "喜剧片"],
              "美人鱼": [21, 17, 5, "喜剧片"],
              "澳门风云3": [54, 9, 11, "喜剧片"],
              "功夫熊猫3": [39, 0, 31, "喜剧片"],
                 "谍影重重": [5, 2, 57, "动作片"],
                  "叶问3": [3, 2, 65, "动作片"],
                 "伦敦陷落": [2, 3, 55, "动作片"],
              "我的特工爷爷": [6, 4, 21, "动作片"],
              "奔爱": [7, 46, 4, "爱情片"],
              "夜孔雀": [9, 39, 8, "爱情片"],
              "代理情人": [9, 38, 2, "爱情片"],
              "新步步惊心": [8, 34, 17, "爱情片"]}
#数据清洗
index_row=[]
index_clo=[]
for x in movie_data.keys():
    index_row.append(x)
for x in movie_data.values():
    index_clo.append(x)
print(index_row)
print(index_clo)
#  需要判断的数据:
data=['唐人街探案',23,3,17,'?']
#清洗
data_test=[23,3,17]
#选择测量距离的方法:
#欧几里得距离法
dic_data={}
def Ojld(a,b):
    c=math.sqrt((a[0]-b[0])**2+(a[1]-b[1])**2+(a[2]-b[2])**2) #计算距离
    d=b[-1] #提取影片类别
    global dic_data
    dic_data.update({c:d})#生成 距离:影片类别 字典
for x in index_clo: # 带入函数计算
    print(x)
    Ojld(data_test,x)
print(dic_data)  #得到字典
list_sort=list(dic_data.keys())#得到距离列表
list_sort.sort()#将距离从小到大排序
print(list_sort)
#定义所有影片类型的字典
film_type={'爱情片':0,'动作片':0,'喜剧片':0}
#定k的值,我们选择k为5
k=5
list_type=[]
for x in range(5):
    list_type.append(dic_data[list_sort[x]])
print(list_type)#得到前五个距离对应的影片类型
for x in list_type:
    film_type[x]=film_type[x]+1
print(film_type)
max_=max(list(film_type.values()))
print(max_)
for x,y in film_type.items():
    if y==max_:
        print(x) # 得到前五个中频率最多的类别

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值