我的想法是先去看一下西瓜书对K近邻的讲解,再去看看代码实现。
ok那现在开始!
K近邻简称KNN——属于监督学习。因此在训练集中肯定是有标签的,
“近朱者赤,近墨者黑”
① 过程:
1.确定K值
2.给定的测试样本进去预测(分类任务中常用“投票法”)(回归任务常用“平均法‘)
3.预测结果:将这K个样本中出现最多的类别标记作为预测结果
K近邻是懒惰学习:
因为它没有显式的训练过程。仅仅只是把样本保存起来,训练时间开销为0,等到收到样本后才开始处理。
而其他在训练阶段就对样本处理的学习方法称为:急切学习
② 代码实现
#代码案例
import pandas as pd
import numpy as np
import operator
#导入数据
data=pd.read_csv("D:/科研/机器学习/._iris.csv", encoding='gbk')
#欧几里得距离
#计算两个数据点的欧几里得距离
def euclideanDistance(data1,data2,length):
distance =0
for x in range(length):
distance+=np.square(data1[x]-data2[x]) #np.square():用于计算平方
return np.sqrt(distance) #np.sqrt():用于开根号
# KNN 模型
def knn(trainingSet, testInstance, k): #定义一个函数,有三个参数:训练数据的set,测试数据的距离,K的值
distances = {}#初始化
sort = {}
length = testInstance.shape[1]#计算测试数据距离的列数,存储在length中
# 计算每行训练数据和测试数据之间的欧氏距离、、
#使用for 循环遍历训练数据里面的每一行数据
for x in range(len(trainingSet)):
#调用euclideanDistance函数,计算训练和测试的第x 行数据之间的欧式距离
dist = euclideanDistance(testInstance, trainingSet.iloc[x], length)
#将计算得到的距离存储在distances字典中,key为x,value为dist[0]
distances[x] = dist[0]
# 根据距离对它们进行排序
#将distances按照距离的大小排序,存储在sorted_d中。
sorted_d = sorted(distances.items(), key=operator.itemgetter(1))
neighbors = []
# 提取前 k 个邻居
#使用for循环提取前k个邻居的索引,存储在neighbors列表中。
for x in range(k):
neighbors.append(sorted_d[x][0])
classVotes = {}
#初始化一个空字典classVotes用于存储每个类别的投票数
# 计算邻居中频率最高的类别
for x in range(len(neighbors)):
response = trainingSet.iloc[neighbors[x]][-1]
if response in classVotes:
classVotes[response] += 1
else:
classVotes[response] = 1
sortedVotes = sorted(classVotes.items(), key=operator.itemgetter(1), reverse=True)
return (sortedVotes[0][0], neighbors)
#定义一个测试数据
test_data=[[6.8,5.1,4.9,1.5]]
test=pd.DataFrame(test_data)
#设置邻居数3
k=3
#运行KNN模型
result,neigh=knn(data,test,k)
#预测类别 相邻的K个邻居
print('类别:',result,'相邻的K个邻居',neigh)
结果:
代码参考:https://blog.youkuaiyun.com/lyc2016012170/article/details/121847859