KNN分類算法及python代碼實現

KNN分類算法(先驗數據中就有類別之分,未知的數據會被歸類爲以前類別中的某一類!python

一、KNN介紹算法

K最近鄰(k-Nearest NeighborKNN分類算法是最簡單的機器學習算法。app

機器學習,算法自己不是最難的,最難的是:python2.7

一、數學建模:把業務中的特性抽象成向量的過程;機器學習

二、選取適合模型的數據樣本。ide

這兩個事都不是簡單的事。算法反而是比較簡單的事。函數

本質上,KNN算法就是用距離來衡量樣本之間的類似度。學習

 

二、算法圖示測試

◊ 從訓練集中找到和新數據最接近的k條記錄,而後根據多數類來決定新數據類別。idea

◊算法涉及3個主要因素:

1) 訓練數據集

2) 距離或類似度的計算衡量

3) k的大小

 

◊算法描述

1) 已知兩類「先驗」數據,分別是藍方塊和紅三角,他們分佈在一個二維空間中

2) 有一個未知類別的數據(綠點),須要判斷它是屬於「藍方塊」仍是「紅三角」類

3) 考察離綠點最近的3個(或k)數據點的類別,佔多數的類別即爲綠點斷定類別

 

三、算法要點

3.一、計算步驟

 1算距離:給定測試對象,計算它與訓練集中的每一個對象的距離

 2找鄰居:圈定距離最近的k個訓練對象,做爲測試對象的近鄰

 3作分類:根據這k個近鄰歸屬的主要類別,來對測試對象分類

 

3.二、類似度的度量

◊距離越近應該意味着這兩個點屬於一個分類的可能性越大。

但,距離不能表明一切,有些數據的類似度衡量並不適合用距離

◊類似度衡量方法:包括歐式距離夾角餘弦等。

(簡單應用中,通常使用歐氏距離,但對於文本分類來講,使用餘弦(cosine)來計算類似度就比歐式(Euclidean)距離更合適

 

3.三、類別的斷定

簡單投票法:少數服從多數,近鄰中哪一個類別的點最多就分爲該類。

加權投票法:根據距離的遠近,對近鄰的投票進行加權,距離越近則權重越大(權重爲距離平方的倒數)

 

3.四、算法不足

  • 樣本不平衡容易致使結果錯誤

◊如一個類的樣本容量很大,而其餘類樣本容量很小時,有可能致使當輸入一個新樣本時,該樣本的K個鄰居中大容量類的樣本佔多數。

◊改善方法:對此能夠採用權值的方法(和該樣本距離小的鄰居權值大)來改進。

  • 計算量較大

◊由於對每個待分類的文本都要計算它到全體已知樣本的距離,才能求得它的K個最近鄰點。

◊改善方法:事先對已知樣本點進行剪輯,事先去除對分類做用不大的樣本。

該方法比較適用於樣本容量比較大的類域的分類,而那些樣本容量較小的類域採用這種算法比較容易產生誤分。

 

四、KNN分類算法python實現(python2.7)

需求:

有如下先驗數據,使用knn算法對未知類別數據分類

屬性1

屬性2

類別

1.0

0.9

A

1.0

1.0

A

0.1

0.2

B

0.0

0.1

B

 

未知類別數據

屬性1

屬性2

類別

1.2

1.0

?

0.1

0.3

?

 

python實現:

KNN.py腳本文件

 1 #!/usr/bin/python
 2 # coding=utf-8
 3 #########################################
 4 # kNN: k Nearest Neighbors
 5 
 6 #  輸入:      newInput:  (1xN)的待分類向量
 7 #             dataSet:   (NxM)的訓練數據集
 8 #             labels:     訓練數據集的類別標籤向量
 9 #             k:         近鄰數
10 
11 # 輸出:     可能性最大的分類標籤
12 #########################################
13 
14 from numpy import *
15 import operator
16 
17 # 建立一個數據集,包含2個類別共4個樣本
18 def createDataSet():
19     # 生成一個矩陣,每行表示一個樣本
20     group = array([[1.0, 0.9], [1.0, 1.0], [0.1, 0.2], [0.0, 0.1]])
21     # 4個樣本分別所屬的類別
22     labels = ['A', 'A', 'B', 'B']
23     return group, labels
24 
25 # KNN分類算法函數定義
26 def kNNClassify(newInput, dataSet, labels, k):
27     numSamples = dataSet.shape[0]   # shape[0]表示行數
28 
29     # # step 1: 計算距離[
30     # 假如:
31     # Newinput:[1,0,2]
32     # Dataset:
33     # [1,0,1]
34     # [2,1,3]
35     # [1,0,2]
36     # 計算過程即爲:
37     # 一、求差
38     # [1,0,1]       [1,0,2]
39     # [2,1,3]   --   [1,0,2]
40     # [1,0,2]       [1,0,2]
41     # =
42     # [0,0,-1]
43     # [1,1,1]
44     # [0,0,-1]
45     # 二、對差值平方
46     # [0,0,1]
47     # [1,1,1]
48     # [0,0,1]
49     # 三、將平方後的差值累加
50     # [1]
51     # [3]
52     # [1]
53     # 四、將上一步驟的值求開方,即得距離
54     # [1]
55     # [1.73]
56     # [1]
57     #
58     # ]
59     # tile(A, reps): 構造一個矩陣,經過A重複reps次獲得
60     # the following copy numSamples rows for dataSet
61     diff = tile(newInput, (numSamples, 1)) - dataSet  # 按元素求差值
62     squaredDiff = diff ** 2  # 將差值平方
63     squaredDist = sum(squaredDiff, axis = 1)   # 按行累加
64     distance = squaredDist ** 0.5  # 將差值平方和求開方,即得距離
65 
66     # # step 2: 對距離排序
67     # argsort() 返回排序後的索引值
68     sortedDistIndices = argsort(distance)
69     classCount = {} # define a dictionary (can be append element)
70     for i in xrange(k):
71         # # step 3: 選擇k個最近鄰
72         voteLabel = labels[sortedDistIndices[i]]
73 
74         # # step 4: 計算k個最近鄰中各種別出現的次數
75         # when the key voteLabel is not in dictionary classCount, get()
76         # will return 0
77         classCount[voteLabel] = classCount.get(voteLabel, 0) + 1
78 
79     # # step 5: 返回出現次數最多的類別標籤
80     maxCount = 0
81     for key, value in classCount.items():
82         if value > maxCount:
83             maxCount = value
84             maxIndex = key
85 
86     return maxIndex

 

KNNTest.py測試文件

 1 #!/usr/bin/python
 2 # coding=utf-8
 3 import KNN
 4 from numpy import *
 5 # 生成數據集和類別標籤
 6 dataSet, labels = KNN.createDataSet()
 7 # 定義一個未知類別的數據
 8 testX = array([1.2, 1.0])
 9 k = 3
10 # 調用分類函數對未知數據分類
11 outputLabel = KNN.kNNClassify(testX, dataSet, labels, 3)
12 print "Your input is:", testX, "and classified to class: ", outputLabel
13 
14 testX = array([0.1, 0.3])
15 outputLabel = KNN.kNNClassify(testX, dataSet, labels, 3)
16 print "Your input is:", testX, "and classified to class: ", outputLabel

 

運行結果:

相關文章
相關標籤/搜索