资讯专栏INFORMATION COLUMN

机器学习——K近邻算法

SexySix / 1646人阅读

摘要:而代码是给出现情况增加次数,出现一次排序导入运算符模块的方法,按照第二个元素的次序对元组进行排序,此处的排序为逆序。

机器学习——K近邻算法 概述

k近邻是一种基本分类与回归方法.

输入:特征向量

输出:实例的类别(可取多类)

核心思想:如果一个样本在特征空间中的k个最相邻的样本中的大多数属于某一个类别,则该样本也属于这个类别,并具有这个类别上样本的特性.

优点:计算精度高、对异常值不敏感、无数据输入假定

缺点:计算复杂度高、空间复杂度高

适用范围:数值型和标称型

算法流程

</>复制代码

  1. 收集数据

  2. 准备数据:距离计算所需要的数值,最好是结构化的数据格式

  3. 分析数据:可以适用任何方法

  4. 训练算法:此步骤不适用于KNN

  5. 测试算法:计算错误率

  6. 使用算法:首先需要输入样本数据和结构化的输出结果,然后运行k-近邻算法判定输入数据分别属于哪个分类,最后应用对计算出的分类执行后续的处理

kNN算法
构造数据集

</>复制代码

  1. import numpy as np
  2. def create_data_set():
  3. """构造数据集"""
  4. group = np.array([[1.0, 1.1], [1.0, 1.0], [0, 0], [0, 0.1]])
  5. label = ["A", "A", "B", "B"]
  6. return group, label
生成数据集

</>复制代码

  1. group, label = create_data_set()
实现kNN算法伪代码

对未知类别属性的数据集种的每个点依次执行以下步骤:

1. 计算已知类别属性的数据集中的每个点与当前点之间的距离

2. 按照距离递增次序排序

3. 选取与当前点距离最小的k个点

4. 确定前k个点所在类别的出现频率

5. 返回前k个点出现频率最高的类别作为当前点的预测分类

</>复制代码

  1. import operator
  2. def classify0(inX, data_set, label, k):
  3. """
  4. KNN算法
  5. :param inX: 用于分类的输入向量
  6. :param data_set: 训练样本集
  7. :param label: 训练标签向量
  8. :param k: 选取最近邻居的数量
  9. :return: k个邻居里频率最高的分类
  10. """
  11. """距离计算"""
  12. # 获得样本量
  13. data_set_size = data_set.shape[0]
  14. # tile:在行方向重复inX,dataSetSize次,在列方向上重复inX,1次
  15. diff_mat = np.tile(inX, (data_set_size, 1)) - data_set
  16. # 离原点的距离,相见后平方
  17. sq_diff_mat = diff_mat ** 2
  18. # x轴和y轴差的平方和
  19. sq_distances = sq_diff_mat.sum(axis=1)
  20. # 然后开方
  21. distances = sq_distances ** 0.5
  22. # argsort函数返回的是数组值从小到大的索引值
  23. sorted_distance_index = distances.argsort()
  24. class_count = {}
  25. """选择距离最小的点"""
  26. for i in range(k):
  27. # 返回距离最近的第i个样本所对应的标签
  28. vote_label = label[sorted_distance_index[i]]
  29. # print(voteIlabel)
  30. # print(classCount.get(voteIlabel, 0))
  31. # 这里的0是设置默认值为0,而代替None。而代码是给出现情况增加次数,出现一次+1
  32. class_count[vote_label] = class_count.get(vote_label, 0) + 1
  33. # print(classCount)
  34. """排序"""
  35. # 导入运算符模块的itemgetter方法,按照第二个元素的次序对元组进行排序,此处的排序为逆序。
  36. sorted_class_count = sorted(class_count.items(), key=operator.itemgetter(1), reverse=True)
  37. # 返回频率最大的Label
  38. return sorted_class_count[0][0]
添加算法测试代码

</>复制代码

  1. classify0([0, 0], group, label, k=3)
约会网站示例
加载并解析数据

</>复制代码

  1. # 将文本记录转换为numpy的解析程序
  2. def file2matrix(filename):
  3. fr = open(filename)
  4. # readlines把文件所有内容读取出来,组成一个列表,其中一行为一个元素
  5. array_of_lines = fr.readlines()
  6. number_of_lines = len(array_of_lines)
  7. # 返回一个用1000行每行3个0填充的数组,形成特征矩阵
  8. return_mat = np.zeros((number_of_lines, 3))
  9. class_label_vector = []
  10. for index, line in enumerate(array_of_lines):
  11. # 去除每行前后的空格
  12. line = line.strip()
  13. # 根据
  14. 把每行分隔成由四个元素组成的列表
  15. list_from_line = line.split("
  16. ")
  17. # 选取前3个元素,将它们按顺序存储到特征矩阵中
  18. return_mat[index, :] = list_from_line[0: 3]
  19. # 将列表的最后一个元素储存到class_label_vector中去,储存的元素值为整型
  20. class_label_vector.append(int(list_from_line[-1]))
  21. return return_mat, class_label_vector
获得解析数据

</>复制代码

  1. dating_data_mat, dating_labels = file2matrix("datingTestSet2.txt")
使用Matplotlib创建散点图

</>复制代码

  1. import matplotlib.pyplot as plt
  2. # 创建Figure实例
  3. fig = plt.figure()
  4. # 添加一个子图,返回Axes实例
  5. ax = fig.add_subplot(111) # 选取最近邻居的数量
  6. # 生成散点图,x轴使用dating_data_mat第二列数据,y轴使用dating_data_mat的第三列数据
  7. # ax.scatter(x=dating_data_mat[:, 1], y=dating_data_mat[:, 2])
  8. # 个性化标记散点图,形状(s)和颜色(c)
  9. ax.scatter(x=dating_data_mat[:, 1], y=dating_data_mat[:, 2], s=15.0 * np.array(dating_labels), c=np.array(dating_labels))
  10. plt.show()
归一化特征值

newValue=(oldValue−min)/(max−min)

</>复制代码

  1. def auto_num(data_set):
  2. """
  3. 归一化特征值
  4. :param data_set: 数据集
  5. :return 归一化后的数据集, 列的差值范围, 列的最小值
  6. """
  7. # 列的最小值
  8. min_val = data_set.min()
  9. # 列的最大值
  10. max_val = data_set.max()
  11. # 列的差值范围
  12. range_s = max_val - min_val
  13. # 构造返回矩阵
  14. norm_data_set = np.zeros(shape=np.shape(data_set))
  15. # m = data_set.shape[0]
  16. # oldValue - min
  17. norm_data_set = data_set - np.tile(min_val, (data_set.shape[0], 1))
  18. # (oldValue - min) / (max - min)
  19. norm_data_set = norm_data_set / np.tile(range_s, (data_set.shape[0], 1))
  20. return norm_data_set, range_s, min_val
归一化测试

</>复制代码

  1. normalize_data_set, ranges, min_val = auto_num(dating_data_mat)
  2. print(normalize_data_set)
测试算法

</>复制代码

  1. def dating_class_test():
  2. # 选择测试数据量
  3. ho_ratio = 0.10
  4. # 解析数据
  5. dating_data_mat, dating_labels = file2matrix("datingTestSet2.txt")
  6. # 归一化数据
  7. norm_mat, range_s, min_val = auto_num(dating_data_mat)
  8. # 拆分10%数据作为测试数据
  9. m = norm_mat.shape[0] # 总数据量
  10. num_test_vec = int(m * ho_ratio) # 测试数据量
  11. # 错误样本计数
  12. error_count = 0.0
  13. # 对测试数据进行分类,并对比检验结果正确率
  14. for i in range(num_test_vec):
  15. classifier_result = classify0( # classifier_result : k个邻居里频率最高的分类
  16. norm_mat[i, :], # 用于分类的输入向量(测试数据, : 表示一行内所有元素)
  17. norm_mat[num_test_vec: m, :], # 训练样本集(从测试的数据开始到总数据量结束)
  18. dating_labels[num_test_vec:m], # 训练标签向量(从测试的数据开始到总数据量结束)
  19. 3 # 选取最近邻居的数量
  20. )
  21. print("the classifier came back with: %d, the real answer is: %d" % (classifier_result, dating_labels[i]))
  22. if classifier_result != dating_labels[i]:
  23. error_count += 1.0
  24. print("the total error rate is: %f" % (error_count / float(num_test_vec)))
执行测试

</>复制代码

  1. dating_class_test()
使用算法

</>复制代码

  1. def classify_person():
  2. """
  3. 根据输入指标,通过分类器进行预测喜欢程度
  4. :return:
  5. """
  6. result_list = ["not at all", "in small doses", "in large doses"]
  7. percent_tats = float(input("percentage of time spent playing vedio games?"))
  8. ff_miles = float(input("frequent flier miles earned per year?"))
  9. ice_cream = float(input("liters of ice cream consumed per year?"))
  10. dating_data, dating_labels = file2matrix("datingTestSet2.txt")
  11. normalize_matrix, ranges, min_val = auto_num(dating_data)
  12. # 将输入指标,归一化后代入分类器进行预测
  13. in_arr = np.array([ff_miles, percent_tats, ice_cream])
  14. print(in_arr, min_val, ranges, (in_arr-min_val)/ranges)
  15. print(ranges)
  16. classifier_result = classify0((in_arr-min_val)/ranges, normalize_matrix, dating_labels, 3)
  17. print("You will probably like this person: ", result_list[classifier_result - 1])
执行函数

</>复制代码

  1. classify_person()
输出

</>复制代码

  1. percentage of time spent playing vedio games?20
  2. frequent flier miles earned per year?299
  3. liters of ice cream consumed per year?1
  4. You will probably like this person: in large doses
sklearn中实现

</>复制代码

  1. from sklearn import neighbors
  2. def knn_classify_person():
  3. """
  4. 根据输入指标,通过分类器进行预测喜欢程度
  5. :return:
  6. """
  7. result_list = np.array(["not at all", "in small doses", "in large doses"])
  8. percent_tats = float(input("percentage of time spent playing vedio games?"))
  9. ff_miles = float(input("frequent flier miles earned per year?"))
  10. ice_cream = float(input("liters of ice cream consumed per year?"))
  11. dating_data, dating_labels = file2matrix("datingTestSet2.txt")
  12. normalize_matrix, ranges, min_val = auto_num(dating_data)
  13. # 将输入指标,归一化后代入分类器进行预测
  14. in_arr = np.array([ff_miles, percent_tats, ice_cream])
  15. # 声明k为3的knn算法,n_neighbors即是邻居数量,默认值为5
  16. knn = neighbors.KNeighborsClassifier(n_neighbors=3)
  17. # 训练算法
  18. knn.fit(normalize_matrix, dating_labels)
  19. # 预测
  20. classifier_result = knn.predict([(in_arr - min_val) / ranges])
  21. print("You will probably like this person: ", result_list[classifier_result - 1][0])
  22. # 执行函数
  23. knn_classify_person()

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/41659.html

相关文章

  • 如何用机器学习算法来进行电影分类?(含Python代码)

    摘要:电影分析近邻算法周末,小迪与女朋友小西走出电影院,回味着刚刚看过的电影。近邻分类电影类型小迪回到家,打开电脑,想实现一个分类电影的案例。分类器并不会得到百分百正确的结果,我们可以使用很多种方法来验证分类器的准确率。 电影分析——K近邻算法 周末,小迪与女朋友小西走出电影院,回味着刚刚看过的电影。 小迪:刚刚的电影很精彩,打斗场景非常真实,又是一部优秀的动作片! 小西:是吗?我怎么感觉这...

    animabear 评论0 收藏0
  • 机器学习实战 Task1】 (KNN)k近邻算法的应用

    摘要:背景近邻算法的概述近邻算法的简介近邻算法是属于一个非常有效且易于掌握的机器学习算法,简单的说就是采用测量不同特征值之间距离的方法对数据进行分类的一个算法。完美的分类器的错误率为,而最差的分类器的错误率则为。 1 背景 1.1 k近邻算法的概述 (1)k近邻算法的简介 k-近邻算法是属于一个非...

    toddmark 评论0 收藏0
  • 机器学习(六)-基于KNN分类算法的自动划分电影的题材类型实现

    摘要:算法及工作原理近邻算法采用测量不同特征值之间的距离方法进行分类。最后选择个最相似数据中出现次数最多的分类作为新数据的分类。 1 分类算法引言 众所周知,电影可以按照题材分类,然而题材本身是如何定义的?由谁来判定某部电影属于哪个题材?也就是说同一题材的电影具有哪些公共特征?这些都是在进行电影分类时必须要考虑的问题。 动作片中也会存在接吻镜头,爱情片中也会存在打斗场景,我们不能单纯依靠是...

    MkkHou 评论0 收藏0
  • 机器学习1——k近邻算法

    k近邻(k-Nearest Neighbor,kNN)算法是经典的带监督的分类算法,核心思想是如果一个样本在特征空间中的k个最相邻的样本中的大多数属于某一个类别,则针对该样本的划分结果也属于这个类别。 1. 算法步骤 准备训练数据和测试数据; 确定参数 k; 计算测试数据与各个训练数据之间的距离,距离的递增关系进行排序; 选取距离最小的 k 个点; 确定前 k 个点所在类别的出现频率; 返回前 ...

    seanlook 评论0 收藏0

发表评论

0条评论

SexySix

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<