目录
二.K近邻算法
1.K-近邻算法简介
1>什么是K-近邻算法
K近邻算法是一种基本分类与回归方法。算法的核心思想是,即是给定一个训练数据集,对新的输入实例,在训练数据集中找到与该实例最邻近的K个实例,这K个实例的多数属于某个类,就把该输入实例分类到这个类中。K近邻算法通过测量不同特征值之间的距离进行分类。KNN对新样本进行预测的方法是:根据其k个最近邻的训练实例类别,通过多数表决等方式进行预测
2>K-近邻算法的具体流程
(1)收集数据:可以使用任何方法
(2)准备数据:距离计算所需要的数值,最好是结构化的数据格式
(3)分析数据:当拥有了适当的数据量后,通过对数据的分析,根据需要,取得适合的K值
(4)使用算法:首先需要输入样本数据和结构化的输出结果,然后运行k-近邻算法,判定输入数据分别属于哪个分类,最后应用,对计算出的分类执行后续的处理
2.利用K-近邻算法实现简单电影类别分类
1>实验目的:
利用K-近邻算法实现对于一个电影为动作片还是爱情片进行分类,其中截取了打斗镜头和亲吻镜头的数量值作为判断一个电影是动作片还是爱情片的两个特征。
2>收集数据:
既可以通过网上检索的方式收缩数据,也可以通过阅读书物的方式收缩数据,或者根据主观能动性实现对数据的收集。
3>准备数据:
对于此次数据集,主要是以“1,2,3”的形式保存在文本文件中,其中1代表的是打斗镜头的数量,2代表的接吻镜头的数量,3代表的是此电影的种类。其中保存数据的文本文件命名为data。
4>获取数据:
在已经获得数据集的情况下,将文本文件中的数据集通过python代码导入到python文件当中.
def data():
string_file = 'D:\Many_Applications------\data\data.txt'
data_all = []
data_label = []
with open(string_file, 'r', encoding="UTF-8") as f:
for line in f:
list = line.split(",")
data_all.append([int(list[0]), int(list[1])])
data_label.append((str(list[2])).split('\n')[0])
return data_all, data_label
如上图代码,line用于保存从文本文件中读出来的每一组数据,并且利用list对line进行分割之后,分别获得数据集中的数据,以及数据集中的标签.
5>数据归一化:
def normalize(in_test,data_all):
min_data = nu.min(data_all)
max_data = nu.max(data_all)
test_data = (in_test-min_data) / (max_data-min_data)
all_data = (data_all-min_data) / (max_data-min_data)
return test_data,all_data
对所要测试的数据集以及所拥有的数据集都进行归一化处理,其中归一化的公式为:
X=(X-X(min))/(X(max)-X(min))
归一化的结果如下:
6>k-近邻算法实现:
def knn(test_data,all_data,data_labels,k):
data_size = all_data.shape[0]
#print(data_size)
#计算距离
first = (nu.tile(test_data,(data_size,1)) - all_data)**2
second = (first.sum(axis=1))**0.5
# 排序
result = second.argsort()
data_dict = dict()
# 找到与待测数据最近的前k个数据
for i in range(k):
# 获取离测试数据最近的k个数据(根据下标获取其标签)
data_label = data_labels[result[i]]
# 将获得到的标签以及出现的对应次数以键值对的方式放入字典中
data_dict[data_label] = data_dict.get(data_label, 0) + 1
sort_dict = sorted(data_dict.items(), key=operator.itemgetter(1), reverse=True)
mat.scatter(all_data[:, 0], all_data[:, 1], c='blue', label='all_data') # 绘制数据集散点图
mat.scatter(test_data[0], test_data[1], c='red', label='test_result') # 绘制待测数据散点图
mat.xlabel('Fight footage')
mat.ylabel('Kissing shots')
mat.legend()
return sort_dict[0][0]
该算法实现的函数,传入的参数分别为归一化的测试集和数据集、标签以及k的值
首先通过.shape来获取行数,并计算相应的欧式距离,然后利用for循环进行遍历距离测试集最近的k个数据集,并进行相应结果的统计,将统计后的结果通过降序整理后的结果保存在sort_dict中,最后返回的出现频次最多的作为测试集的结果.其中图像化的显示,则是利用matplotlib包来实现。
计算欧式距离的公式如下:
7>运行结果:(含不同的测试数据)
3.实验结果分析以及总结
1>实验结果分析:
根据三次的测试结果可知,当数据集中的数据的特征值的差距比较明显的时候,利用k-近邻算法来预测测试集的结果是较为准确的,在这点上是比较简单且较为清晰的,特别是在对于数据集的数据都是比较集中的时候。但是对于此次实验的数据集的情况,若当两个特征值的数值较为接近的时候,这时候即使对于k的值的选取有所不同,仍有可能出现相同的结果,同时,也由于特征值的数值较为接近,因此对于结果的界定就比较模糊,就十分有可能对于各个特征值微小的数据的变化而使得测试集的结果有大幅度的变化。
2>总结:
通过本次实验我得出k-近邻算法的优缺点:
优点:
k近邻算法是一种在线技术,新数据可以直接加入数据集而不必进行重新训练,
k近邻算法理论简单,容易实现。
缺点:
k近邻算法每预测一个“点”的分类都会重新进行一次全局运算,容量大的数据集计算量大。
k近邻算法样本不平衡时,预测偏差比较大。
总结:
通过本次的k-近邻算法的实验课,我对于python代码的整体流程有了更多的清晰的认识,同时,也在编码过程中,对python代码的架构有了更多的认识。但是,也通过本次的实验,也让我清晰的认识到了,自身在python编码上的不足,许多知识点都是模糊不清,对于许多的包的使用也是模糊。也因此,对代码的编写十分的困难,难以完全通过自身的能力来完成此次实验。还需不断努力。
但也通过本次的实验,对于k-近邻算法有了更深刻的认识,对于k-近邻算法的优缺点有了更多的认识,也明白了该算法并不是想象中的那么万能。也希望在之后的实验课,能更多的提升自己的能力。