废话流
这学期选了岳晓冬老师的机器学习基础,这个老师很吊不多说,我很菜这个也不多说。
笨鸟先飞早入林,那就努力学习!
秋季学习选修了python数据分析,算是有一点基础,秋季的时候有写过knn、pca降维以及kmenas聚类的python实现,但仍有不少不理解的地方,借着这次机会一并干掉。
知识点整理
knn是一种基本的分类与回归方法。
knn没有显式的学习过程。
给定一个训练集,其中实例的类别已定。求出待预测实例距离训练集中实例的距离,选择距离最近的k个实例,通过多数表决的方式进行分类预测。
knn有三个基本的要素:1.k值的选择(这个有点重要!!) 2.距离的度量 3.分类决策规则
k值的选择
1.选择过小:容易发生过拟合,模型过于复杂。预测结果对近邻实例点非常敏感。邻近节点变化就会引起预测结果的变化。
2.选择过大:容易发生欠拟合,模型过于简单。与输入实例距离较远的点也会有影响,使预测发生错误。
代码实现(python)
基本每行代码都有注释,简单易懂。今天先总结到这里,以后有新的领悟再来总结。
1 import numpy as np
2 import operator
3
4 #test_data是测试数据集,train_dataset训练数据集,train_label是标签
5 def knn_classify(test_data, train_dataset, train_label, k):
6 # 获得训练样本个数
7 train_dataset_amount = train_dataset.shape[0]
8 # 生成矩阵test_rep_mat,这个矩阵的行数和train_dataset一致但只有一列,元素为test_data
9 test_rep_mat = np.tile(test_data, (train_dataset_amount, 1))
10
11 # 求差,将平方后的数据相加,sum(axis=1)是将一个矩阵的每一行向量内的数据相加,得到一个list,list的元素个数和行数一样;
12 # 开平方,得到欧式距离
13 distance = (np.sum((test_rep_mat - train_dataset) ** 2, axis=1)) ** 0.5
14
15 # argsort 将元素从小到大排列,得到这个数组元素在distance中的index(索引),dist_index元素内容是distance的索引
16 dist_index = distance.argsort()
17 # 新建一个字典
18 class_count = {}
19 for i in range(k):
20 # 找距离最近的三个点的标签
21 label = train_label[dist_index[i]]
22 # 如果属于某个类,在该类的基础上加1,相当于增加其权重,
23 # 如果不是某个类则新建字典的一个key并且等于1(本来是为0的,后面加了个1)
24 class_count[label] = class_count.get(label, 0) + 1
25 # 降序排列,item是将字典中每对key和value组成一个元组
26 # operator.itemgetter获取key对象第一个域的值(从0开始计数,这个题目意思就是以字典中第二个数为关键值来比较)
27 class_count_list = sorted(class_count.items(), key=operator.itemgetter(0), reverse=True)
28 #返回结果
29 return class_count_list[0][0]
30
31
32 # 写一个主函数来测试下
33 if __name__ == '__main__':
34 train_data_set = np.array([[2.2, 1.4], \
35 [2.4, 2.3], \
36 [1.1, 3.4], \
37 [8.3, 7.3], \
38 [9.2, 8.3], \
39 [10.2, 11.1], \
40 [11.2, 9.3]])
41 train_label = ['A', 'A', 'A', 'B', 'B', 'B', 'B']
42 test_data = [4.6, 3.4]
43 print('分类结果为:', knn_classify(test_data, train_data_set, train_label, 3))