【简单学习机器学习】 简单易学的机器学习算法——K-近邻算法

原文见:https://blog.csdn.net/google19890102/article/details/23924971




一、近邻算法(Nearest Neighbors)


1、近邻算法的概念


近邻算法(Nearest Neighbors)是一种典型的非参模型,与生成方法(generalizing method)不同的是,在近邻算法中,通过以实例的形式存储所有的训练样本,假设有m个训练样本:

此时需要存储这m个训练样本,因此,近邻算法也称为基于实例的模型。

    对于一个需要预测的样本,通过与存储好的训练样本比较,以较为相似的样本的标签作为近邻算法的预测结果。


2、近邻算法的分类


在近邻算法中,根据处理的问题的不同,可以分为:
  • 近邻分类算法
  • 近邻回归算法
在本篇博文中,主要介绍近邻分类算法。
注意:除了上述的监督式近邻算法,在近邻算法中,还有一类非监督的近邻算法。

二、近邻分类算法


1、近邻分类算法的概念


    在近邻分类算法中,对于预测的数据,将其与训练样本进行比较,找到最为相似的K个训练样本,并以这K个训练样本中出现最多的标签作为最终的预测标签。
    在近邻分类算法中,最主要的是K-近邻算法。


2、KNN算法概述


    K-NN算法是最简单的分类算法,主要的思想是计算待分类样本与训练样本之间的差异性,并将差异按照由小到大排序,选出前面K个差异最小的类别,并统计在K个中类别出现次数最多的类别为最相似的类,最终将待分类样本分到最相似的训练样本的类中。与投票(Vote)的机制类似。


3、样本差异性


    比较常用的差异性计算方法为欧式距离。 欧式距离:样本 与样本 之间的欧式距离为:

4、KNN算法的流程

  • 求预测样本与训练样本之间的相似性
  • 依据相似性排序
  • 选择前K个最为相似的样本对应的类别
  • 得到预测的分类结果

扫描二维码关注公众号,回复: 2127596 查看本文章

三、K-近邻算法实现


1、Python实现



   以手写字体MNIST的识别为例,对于测试集中的每一个样本预测其类别,对于手写字体,如下图所示:

k_nn.py


     
     
  1. # coding:UTF-8
  2. import cPickle as pickle
  3. import gzip
  4. import numpy as np
  5. def load_data(data_file):
  6. with gzip.open(data_file, ‘rb’) as f:
  7. train_set, valid_set, test_set = pickle.load(f)
  8. return train_set[ 0], train_set[ 1], test_set[ 0], test_set[ 1]
  9. def cal_distance(x, y):
  10. return ((x - y) * (x - y).T)[ 0, 0]
  11. def get_prediction(train_y, result):
  12. result_dict = {}
  13. for i in xrange(len(result)):
  14. if train_y[result[i]] not in result_dict:
  15. result_dict[train_y[result[i]]] = 1
  16. else:
  17. result_dict[train_y[result[i]]] += 1
  18. predict = sorted(result_dict.items(), key= lambda d: d[ 1])
  19. return predict[ 0][ 0]
  20. def k_nn(train_data, train_y, test_data, k):
  21. # print test_data
  22. m = np.shape(test_data)[ 0] # 需要计算的样本的个数
  23. m_train = np.shape(train_data)[ 0]
  24. predict = []
  25. for i in xrange(m):
  26. # 对每一个需要计算的样本计算其与所有的训练数据之间的距离
  27. distance_dict = {}
  28. for i_train in xrange(m_train):
  29. distance_dict[i_train] = cal_distance(train_data[i_train, :], test_data[i, :])
  30. # 对距离进行排序,得到最终的前k个作为最终的预测
  31. distance_result = sorted(distance_dict.items(), key= lambda d: d[ 1])
  32. # 取出前k个的结果作为最终的结果
  33. result = []
  34. count = 0
  35. for x in distance_result:
  36. if count >= k:
  37. break
  38. result.append(x[ 0])
  39. count += 1
  40. # 得到预测
  41. predict.append(get_prediction(train_y, result))
  42. return predict
  43. def get_correct_rate(result, test_y):
  44. m = len(result)
  45. correct = 0.0
  46. for i in xrange(m):
  47. if result[i] == test_y[i]:
  48. correct += 1
  49. return correct / m
  50. if name == main:
  51. # 1、导入
  52. print “———- 1、load data ————”
  53. train_x, train_y, test_x, test_y = load_data( “mnist.pkl.gz”)
  54. # 2、利用k_NN计算
  55. train_x = np.mat(train_x)
  56. test_x = np.mat(test_x)
  57. print “———- 2、K-NN ————-“
  58. result = k_nn(train_x, train_y, test_x[: 10,:], 10)
  59. print result
  60. # 3、预测正确性
  61. print “———- 3、correct rate ————-“
  62. print get_correct_rate(result, test_y)


当取K=10时,对测试集中的10个数据样本的最终的预测准确性为:70%,预测值为:[7, 2, 1, 0, 9, 1, 9, 9, 8, 9],原始值为[7 2 1 0 4 1 4 9 5 9]

2、Scikit-leanrn


Scikit-learn库中对K-NN算法有很好的支持,核心程序为:


    
    
  1. clf = neighbors.KNeighborsClassifier(n_neighbors)
  2. clf.fit(X, y)


四、K-NN算法中存在的问题及解决方


1、计算复杂度的问题


       在K-NN算法中,每一个预测样本需要与所有的训练样本计算相似度,计算量比较大。比较常用的方法有K-D树,局部敏感哈希等等

2、K-NN的均匀投票


       在上述的 K-NN 算法中,最终对标签的选择是通过投票的方式决定的,在投票的过程中,每一个训练样本的投票的权重是相等的,可以对每个训练样本的投票加权,以期望最相似的样本有更高的决策权。


参考文献


1、1.6. Nearest Neighbors点击打开链接




一、近邻算法(Nearest Neighbors)


1、近邻算法的概念


近邻算法(Nearest Neighbors)是一种典型的非参模型,与生成方法(generalizing method)不同的是,在近邻算法中,通过以实例的形式存储所有的训练样本,假设有m个训练样本:

此时需要存储这m个训练样本,因此,近邻算法也称为基于实例的模型。

    对于一个需要预测的样本,通过与存储好的训练样本比较,以较为相似的样本的标签作为近邻算法的预测结果。


2、近邻算法的分类


在近邻算法中,根据处理的问题的不同,可以分为:
  • 近邻分类算法
  • 近邻回归算法
在本篇博文中,主要介绍近邻分类算法。
注意:除了上述的监督式近邻算法,在近邻算法中,还有一类非监督的近邻算法。

二、近邻分类算法


1、近邻分类算法的概念


    在近邻分类算法中,对于预测的数据,将其与训练样本进行比较,找到最为相似的K个训练样本,并以这K个训练样本中出现最多的标签作为最终的预测标签。
    在近邻分类算法中,最主要的是K-近邻算法。


2、KNN算法概述


    K-NN算法是最简单的分类算法,主要的思想是计算待分类样本与训练样本之间的差异性,并将差异按照由小到大排序,选出前面K个差异最小的类别,并统计在K个中类别出现次数最多的类别为最相似的类,最终将待分类样本分到最相似的训练样本的类中。与投票(Vote)的机制类似。


3、样本差异性


    比较常用的差异性计算方法为欧式距离。 欧式距离:样本 与样本 之间的欧式距离为:

4、KNN算法的流程

  • 求预测样本与训练样本之间的相似性
  • 依据相似性排序
  • 选择前K个最为相似的样本对应的类别
  • 得到预测的分类结果

三、K-近邻算法实现


1、Python实现



   以手写字体MNIST的识别为例,对于测试集中的每一个样本预测其类别,对于手写字体,如下图所示:

k_nn.py


   
   
  1. # coding:UTF-8
  2. import cPickle as pickle
  3. import gzip
  4. import numpy as np
  5. def load_data(data_file):
  6. with gzip.open(data_file, ‘rb’) as f:
  7. train_set, valid_set, test_set = pickle.load(f)
  8. return train_set[ 0], train_set[ 1], test_set[ 0], test_set[ 1]
  9. def cal_distance(x, y):
  10. return ((x - y) * (x - y).T)[ 0, 0]
  11. def get_prediction(train_y, result):
  12. result_dict = {}
  13. for i in xrange(len(result)):
  14. if train_y[result[i]] not in result_dict:
  15. result_dict[train_y[result[i]]] = 1
  16. else:
  17. result_dict[train_y[result[i]]] += 1
  18. predict = sorted(result_dict.items(), key= lambda d: d[ 1])
  19. return predict[ 0][ 0]
  20. def k_nn(train_data, train_y, test_data, k):
  21. # print test_data
  22. m = np.shape(test_data)[ 0] # 需要计算的样本的个数
  23. m_train = np.shape(train_data)[ 0]
  24. predict = []
  25. for i in xrange(m):
  26. # 对每一个需要计算的样本计算其与所有的训练数据之间的距离
  27. distance_dict = {}
  28. for i_train in xrange(m_train):
  29. distance_dict[i_train] = cal_distance(train_data[i_train, :], test_data[i, :])
  30. # 对距离进行排序,得到最终的前k个作为最终的预测
  31. distance_result = sorted(distance_dict.items(), key= lambda d: d[ 1])
  32. # 取出前k个的结果作为最终的结果
  33. result = []
  34. count = 0
  35. for x in distance_result:
  36. if count >= k:
  37. break
  38. result.append(x[ 0])
  39. count += 1
  40. # 得到预测
  41. predict.append(get_prediction(train_y, result))
  42. return predict
  43. def get_correct_rate(result, test_y):
  44. m = len(result)
  45. correct = 0.0
  46. for i in xrange(m):
  47. if result[i] == test_y[i]:
  48. correct += 1
  49. return correct / m
  50. if name == main:
  51. # 1、导入
  52. print “———- 1、load data ————”
  53. train_x, train_y, test_x, test_y = load_data( “mnist.pkl.gz”)
  54. # 2、利用k_NN计算
  55. train_x = np.mat(train_x)
  56. test_x = np.mat(test_x)
  57. print “———- 2、K-NN ————-“
  58. result = k_nn(train_x, train_y, test_x[: 10,:], 10)
  59. print result
  60. # 3、预测正确性
  61. print “———- 3、correct rate ————-“
  62. print get_correct_rate(result, test_y)


当取K=10时,对测试集中的10个数据样本的最终的预测准确性为:70%,预测值为:[7, 2, 1, 0, 9, 1, 9, 9, 8, 9],原始值为[7 2 1 0 4 1 4 9 5 9]

2、Scikit-leanrn


Scikit-learn库中对K-NN算法有很好的支持,核心程序为:


  
  
  1. clf = neighbors.KNeighborsClassifier(n_neighbors)
  2. clf.fit(X, y)


四、K-NN算法中存在的问题及解决方


1、计算复杂度的问题


       在K-NN算法中,每一个预测样本需要与所有的训练样本计算相似度,计算量比较大。比较常用的方法有K-D树,局部敏感哈希等等

2、K-NN的均匀投票


       在上述的 K-NN 算法中,最终对标签的选择是通过投票的方式决定的,在投票的过程中,每一个训练样本的投票的权重是相等的,可以对每个训练样本的投票加权,以期望最相似的样本有更高的决策权。


参考文献


1、1.6. Nearest Neighbors点击打开链接

猜你喜欢

转载自blog.csdn.net/feng_zhiyu/article/details/80923210
今日推荐