You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

knn_classification.py 8.1 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206
  1. # -*- coding: utf-8 -*-
  2. # ---
  3. # jupyter:
  4. # jupytext_format_version: '1.2'
  5. # kernelspec:
  6. # display_name: Python 3
  7. # language: python
  8. # name: python3
  9. # language_info:
  10. # codemirror_mode:
  11. # name: ipython
  12. # version: 3
  13. # file_extension: .py
  14. # mimetype: text/x-python
  15. # name: python
  16. # nbconvert_exporter: python
  17. # pygments_lexer: ipython3
  18. # version: 3.5.2
  19. # ---
  20. # # KNN Classification
  21. #
  22. #
  23. # KNN最邻近规则,主要应用领域是对未知事物的识别,即判断未知事物属于哪一类,判断思想是,基于欧几里得定理,判断未知事物的特征和哪一类已知事物的的特征最接近;
  24. #
  25. # K最近邻(k-Nearest Neighbor,KNN)分类算法,是一个理论上比较成熟的方法,也是最简单的机器学习算法之一。该方法的思路是:如果一个样本在特征空间中的k个最相似(即特征空间中最邻近)的样本中的大多数属于某一个类别,则该样本也属于这个类别。KNN算法中,所选择的邻居都是已经正确分类的对象。该方法在定类决策上只依据最邻近的一个或者几个样本的类别来决定待分样本所属的类别。 KNN方法虽然从原理上也依赖于极限定理,但在类别决策时,只与极少量的相邻样本有关。由于KNN方法主要靠周围有限的邻近的样本,而不是靠判别类域的方法来确定所属类别的,因此对于类域的交叉或重叠较多的待分样本集来说,KNN方法较其他方法更为适合。
  26. #
  27. # KNN算法不仅可以用于分类,还可以用于回归。通过找出一个样本的k个最近邻居,将这些邻居的属性的平均值赋给该样本,就可以得到该样本的属性。更有用的方法是将不同距离的邻居对该样本产生的影响给予不同的权值(weight),如权值与距离成正比(组合函数)。
  28. #
  29. # 该算法在分类时有个主要的不足是,当样本不平衡时,如一个类的样本容量很大,而其他类样本容量很小时,有可能导致当输入一个新样本时,该样本的K个邻居中大容量类的样本占多数。 该算法只计算“最近的”邻居样本,某一类的样本数量很大,那么或者这类样本并不接近目标样本,或者这类样本很靠近目标样本。无论怎样,数量并不能影响运行结果。可以采用权值的方法(和该样本距离小的邻居权值大)来改进。该方法的另一个不足之处是计算量较大,因为对每一个待分类的文本都要计算它到全体已知样本的距离,才能求得它的K个最近邻点。目前常用的解决方法是事先对已知样本点进行剪辑,事先去除对分类作用不大的样本。该算法比较适用于样本容量比较大的类域的自动分类,而那些样本容量较小的类域采用这种算法比较容易产生误分。
  30. #
  31. # K-NN可以说是一种最直接的用来分类未知数据的方法。基本通过下面这张图跟文字说明就可以明白K-NN是干什么的
  32. # ![knn](images/knn.png)
  33. #
  34. # 简单来说,K-NN可以看成:有那么一堆你已经知道分类的数据,然后当一个新数据进入的时候,就开始跟训练数据里的每个点求距离,然后挑离这个训练数据最近的K个点看看这几个点属于什么类型,然后用少数服从多数的原则,给新数据归类。
  35. #
  36. #
  37. # 算法步骤:
  38. #
  39. # * step.1---初始化距离为最大值
  40. # * step.2---计算未知样本和每个训练样本的距离dist
  41. # * step.3---得到目前K个最临近样本中的最大距离maxdist
  42. # * step.4---如果dist小于maxdist,则将该训练样本作为K-最近邻样本
  43. # * step.5---重复步骤2、3、4,直到未知样本和所有训练样本的距离都算完
  44. # * step.6---统计K-最近邻样本中每个类标号出现的次数
  45. # * step.7---选择出现频率最大的类标号作为未知样本的类标号
  46. # ## Program
  47. # +
  48. import numpy as np
  49. import operator
  50. class KNN(object):
  51. def __init__(self, k=3):
  52. self.k = k
  53. def fit(self, x, y):
  54. self.x = x
  55. self.y = y
  56. def _square_distance(self, v1, v2):
  57. return np.sum(np.square(v1-v2))
  58. def _vote(self, ys):
  59. ys_unique = np.unique(ys)
  60. vote_dict = {}
  61. for y in ys:
  62. if y not in vote_dict.keys():
  63. vote_dict[y] = 1
  64. else:
  65. vote_dict[y] += 1
  66. sorted_vote_dict = sorted(vote_dict.items(), key=operator.itemgetter(1), reverse=True)
  67. return sorted_vote_dict[0][0]
  68. def predict(self, x):
  69. y_pred = []
  70. for i in range(len(x)):
  71. dist_arr = [self._square_distance(x[i], self.x[j]) for j in range(len(self.x))]
  72. sorted_index = np.argsort(dist_arr)
  73. top_k_index = sorted_index[:self.k]
  74. y_pred.append(self._vote(ys=self.y[top_k_index]))
  75. return np.array(y_pred)
  76. def score(self, y_true=None, y_pred=None):
  77. if y_true is None and y_pred is None:
  78. y_pred = self.predict(self.x)
  79. y_true = self.y
  80. score = 0.0
  81. for i in range(len(y_true)):
  82. if y_true[i] == y_pred[i]:
  83. score += 1
  84. score /= len(y_true)
  85. return score
  86. # +
  87. # %matplotlib inline
  88. import numpy as np
  89. import matplotlib.pyplot as plt
  90. # data generation
  91. np.random.seed(314)
  92. data_size_1 = 300
  93. x1_1 = np.random.normal(loc=5.0, scale=1.0, size=data_size_1)
  94. x2_1 = np.random.normal(loc=4.0, scale=1.0, size=data_size_1)
  95. y_1 = [0 for _ in range(data_size_1)]
  96. data_size_2 = 400
  97. x1_2 = np.random.normal(loc=10.0, scale=2.0, size=data_size_2)
  98. x2_2 = np.random.normal(loc=8.0, scale=2.0, size=data_size_2)
  99. y_2 = [1 for _ in range(data_size_2)]
  100. x1 = np.concatenate((x1_1, x1_2), axis=0)
  101. x2 = np.concatenate((x2_1, x2_2), axis=0)
  102. x = np.hstack((x1.reshape(-1,1), x2.reshape(-1,1)))
  103. y = np.concatenate((y_1, y_2), axis=0)
  104. data_size_all = data_size_1+data_size_2
  105. shuffled_index = np.random.permutation(data_size_all)
  106. x = x[shuffled_index]
  107. y = y[shuffled_index]
  108. split_index = int(data_size_all*0.7)
  109. x_train = x[:split_index]
  110. y_train = y[:split_index]
  111. x_test = x[split_index:]
  112. y_test = y[split_index:]
  113. # visualize data
  114. plt.scatter(x_train[:,0], x_train[:,1], c=y_train, marker='.')
  115. plt.title("train data")
  116. plt.show()
  117. plt.scatter(x_test[:,0], x_test[:,1], c=y_test, marker='.')
  118. plt.title("test data")
  119. plt.show()
  120. # +
  121. # data preprocessing
  122. x_train = (x_train - np.min(x_train, axis=0)) / (np.max(x_train, axis=0) - np.min(x_train, axis=0))
  123. x_test = (x_test - np.min(x_test, axis=0)) / (np.max(x_test, axis=0) - np.min(x_test, axis=0))
  124. # knn classifier
  125. clf = KNN(k=3)
  126. clf.fit(x_train, y_train)
  127. print('train accuracy: {:.3}'.format(clf.score()))
  128. y_test_pred = clf.predict(x_test)
  129. print('test accuracy: {:.3}'.format(clf.score(y_test, y_test_pred)))
  130. # -
  131. # ## sklearn program
  132. # +
  133. % matplotlib inline
  134. import matplotlib.pyplot as plt
  135. from sklearn import datasets, neighbors, linear_model
  136. # load data
  137. digits = datasets.load_digits()
  138. X_digits = digits.data
  139. y_digits = digits.target
  140. print("Feature dimensions: ", X_digits.shape)
  141. print("Label dimensions: ", y_digits.shape)
  142. # +
  143. # plot sample images
  144. nplot = 10
  145. fig, axes = plt.subplots(nrows=1, ncols=nplot)
  146. for i in range(nplot):
  147. img = X_digits[i].reshape(8, 8)
  148. axes[i].imshow(img)
  149. axes[i].set_title(y_digits[i])
  150. # +
  151. # split train / test data
  152. n_samples = len(X_digits)
  153. n_train = int(0.4 * n_samples)
  154. X_train = X_digits[:n_train]
  155. y_train = y_digits[:n_train]
  156. X_test = X_digits[n_train:]
  157. y_test = y_digits[n_train:]
  158. # +
  159. # do KNN classification
  160. knn = neighbors.KNeighborsClassifier()
  161. logistic = linear_model.LogisticRegression()
  162. print('KNN score: %f' % knn.fit(X_train, y_train).score(X_test, y_test))
  163. print('LogisticRegression score: %f' % logistic.fit(X_train, y_train).score(X_test, y_test))
  164. # -
  165. # ## References
  166. # * [Digits Classification Exercise](http://scikit-learn.org/stable/auto_examples/exercises/plot_digits_classification_exercise.html)
  167. # * [knn算法的原理与实现](https://zhuanlan.zhihu.com/p/36549000)

机器学习越来越多应用到飞行器、机器人等领域,其目的是利用计算机实现类似人类的智能,从而实现装备的智能化与无人化。本课程旨在引导学生掌握机器学习的基本知识、典型方法与技术,通过具体的应用案例激发学生对该学科的兴趣,鼓励学生能够从人工智能的角度来分析、解决飞行器、机器人所面临的问题和挑战。本课程主要内容包括Python编程基础,机器学习模型,无监督学习、监督学习、深度学习基础知识与实现,并学习如何利用机器学习解决实际问题,从而全面提升自我的《综合能力》。