**个人的学习笔记,欢迎大佬指点**
保姆级注释,小白友好
所需数据集链接:链接:https://pan.baidu.com/s/1BgWuKq5qCLJMaX8G4khYKQ
提取码:je80
复制这段内容后打开百度网盘手机App,操作更方便哦
k-近邻算法(k-Nearest Neighbour algorithm),又称为KNN算法,是数据挖掘技术中原理最简单的算法。KNN的工作原理:给定一个已知标签类别的训练数据集,输入没有标签的新数据后,在训练数据集中找到与新数据最邻近的k个实例,如果这k个实例的多数属于某个类别,那么新数据就属于这个类别。可以简单理解为:由那些离X最近的k个点来投票决定X归为哪一类。
k-近邻算法是用什么方法进行判断呢?没错,就是距离度量。
也就是在二维平面中计算两点之间的距离,就可以用我们高中学过的距离计算公式:
如果是多个特征扩展到N维空间,怎么计算?没错,我们可以使用欧氏距离(也称欧几里得度量),如下所示
Demo描述:海伦一直使用在线约会网站寻找适合自己的约会对象,尽管约会网站会推荐不同的人选,但她并不是每一个都喜欢,经过一番总结,她发现曾经交往的对象可以分为三类:不喜欢的人、魅力一般的人、极具魅力得人
海伦收集约会数据已经有了一段时间,她把这些数据存放在文本文件datingTestSet.txt中,其中各字段分别为:每年飞行常客里程、玩游戏视频所占时间比、每周消费冰淇淋公升数
#Demo:k-近邻算法之约会网站配对效果判定
import pandas as pd
#创建数据集
datingTestSet = pd.read_csv('D://BaiduNetdiskDownload//1//数据集//datingTestSet.txt', header = None, sep='\t')#数据集用空格分隔,用read_table读取
datingTestSet.columns = ['每年飞行常客里程', '玩游戏视频所占时间比', '每周消费冰淇淋公升数', '喜欢与否']#添加列索引
print(datingTestSet.shape)#显示数据的形状
print(datingTestSet.info())#显示数据的参数信息
print(datingTestSet)
#分析数据,使用 Matplotlib 创建散点图,查看各数据的分布情况
import matplotlib as mpl
import matplotlib.pyplot as plt
##把不同标签用颜色区分
Colors = []#用于存放颜色列表
for i in range(datingTestSet.shape[0]):
m = datingTestSet.iloc[i,-1]
if m=='didntLike':
Colors.append('black')
if m=='smallDoses':
Colors.append('orange')
if m=='largeDoses':
Colors.append('red')
##绘制两两特征之间的散点图
plt.rcParams['font.sans-serif']=['Simhei'] #图中字体设置为黑体
pl = plt.figure(figsize=(12,8))
fig1 = pl.add_subplot(131)#划分子画布
plt.scatter(datingTestSet.iloc[:, 1], datingTestSet.iloc[:, 2], marker='.', c=Colors)
plt.xlabel('玩游戏视频所占时间比')
plt.ylabel('每周消费冰淇淋公升数')
fig2 = pl.add_subplot(132)
plt.scatter(datingTestSet.iloc[:, 0], datingTestSet.iloc[:, 1], marker='.', c=Colors)
plt.xlabel('每年飞行常客里程')
plt.ylabel('玩游戏视频所占时间比')
fig3 = pl.add_subplot(133)
plt.scatter(datingTestSet.iloc[:, 0], datingTestSet.iloc[:, 2], marker='.', c=Colors)
plt.xlabel('每年飞行常客里程')
plt.ylabel('每周消费冰淇淋公升数')
plt.show()
#数据标准化
"""
函数功能:归一化
参数说明:
dataSet:原始数据集
返回:0-1标准化之后的数据集
"""
def minmax(dataSet):
minDf = dataSet.min()
maxDf = dataSet.max()
normSet = (dataSet - minDf )/(maxDf - minDf)
return normSet
datingT = pd.concat([minmax(datingTestSet.iloc[:, :3]), datingTestSet.iloc[:,3]], axis=1)#将数据的前三列进行归一化,并与第四列拼接
print(datingT)
#划分训练集和测试集
"""
函数功能:切分训练集和测试集
参数说明:
dataSet:原始数据集
rate:训练集所占比例
返回:切分好的训练集和测试集
"""
def randSplit(dataSet,rate=0.9):
n = dataSet.shape[0]
m = int(n*rate)
train = dataSet.iloc[:m,:]
test = dataSet.iloc[m:,:]
test.index = range(test.shape[0])
return train,test
train,test = randSplit(datingT, rate=0.9)
#创建k-近邻分类函数
"""
函数功能:k-近邻算法分类器
参数说明:
train:训练集
test:测试集
k:k-近邻参数,即选择距离最小的k个点
返回:预测好分类的测试集
"""
def datingClass(train,test,k):
n = train.shape[1] - 1#一共3个特征
m = test.shape[0]
result = []
for i in range(m):
dist = list((((train.iloc[:, :n] - test.iloc[i, :n]) ** 2).sum(1))**0.5)
dist_l = pd.DataFrame({'dist': dist, 'labels': (train.iloc[:, n])})
dr = dist_l.sort_values(by = 'dist')[: k]#对dist_l按照dist进行排序,并取最近的k个
re = dr.loc[:, 'labels'].value_counts()
result.append(re.index[0])
result = pd.Series(result)#将result转变为Series格式
test['predict'] = result#对test数据结构添加'predict'列
acc = (test.iloc[:,-1]==test.iloc[:,-2]).mean()
print(f'模型预测准确率为{acc}')
return test
test = datingClass(train,test,5)
print(test)
运行结果