KNN要用到歐氏距離
KNN下面的缺點很容易使分類出錯(比如下面黑色的點)
下面是KNN算法的三個例子demo,
第一個例子是根據算法原理實作
import matplotlib.pyplot as plt
import numpy as np
import operator
# 已知分類的資料
x1 = np.array([3,2,1])
y1 = np.array([104,100,81])
x2 = np.array([101,99,98])
y2 = np.array([10,5,2])
scatter1 = plt.scatter(x1,y1,c='r')
scatter2 = plt.scatter(x2,y2,c='b')
# 未知資料
x = np.array([18])
y = np.array([90])
scatter3 = plt.scatter(x,y,c='k')
#畫圖例
plt.legend(handles=[scatter1,scatter2,scatter3],labels=['labelA','labelB','X'],loc='best')
plt.show()
# 已知分類的資料
x_data = np.array([[3,104],
[2,100],
[1,81],
[101,10],
[99,5],
[81,2]])
y_data = np.array(['A','A','A','B','B','B'])
x_test = np.array([18,90])
# 計算樣本數量
x_data_size = x_data.shape[0]
print(x_data_size)
# 複制x_test
print(np.tile(x_test, (x_data_size,1)))
# 計算x_test與每一個樣本的內插補點
diffMat = np.tile(x_test, (x_data_size,1)) - x_data
diffMat
# 計算內插補點的平方
sqDiffMat = diffMat**2
sqDiffMat
# 求和
sqDistances = sqDiffMat.sum(axis=1)
sqDistances
# 開方
distances = sqDistances**0.5
print(distances)
# 從小到大排序
sortedDistances = distances.argsort()#傳回distances裡的資料從小到大的下标數組
print(sortedDistances)
classCount = {}
# 設定k
k = 5
for i in range(k):
# 擷取标簽
votelabel = y_data[sortedDistances[i]]
# 統計标簽數量
classCount[votelabel] = classCount.get(votelabel,0) + 1#)0表示沒有該字典裡沒有該值時預設為0
classCount
# 根據operator.itemgetter(1)-第1個值對classCount排序,然後再取倒序
sortedClassCount = sorted(classCount.items(),key=operator.itemgetter(1), reverse=True)
print(sortedClassCount)
# 擷取數量最多的标簽
knnclass = sortedClassCount[0][0]#第一個0表示取第一個鍵值對('A', 3),第二個0表示取('A', 3)的‘A’
print(knnclass)
1 import numpy as np#對iris資料集進行訓練分類
2 from sklearn import datasets
3 from sklearn.model_selection import train_test_split
4 from sklearn.metrics import classification_report,confusion_matrix#對模型分類結果進行評估的兩個模型
5 import operator#,關于operator的使用
6 import random
7 def knn(x_test, x_data, y_data, k):
8 x_data_size = x_data.shape[0] # 計算樣本數量
9 diffMat = np.tile(x_test,(x_data_size,1)) - x_data# 複制x_test,計算x_test與每一個樣本的內插補點
10 sqDiffMat = diffMat**2# # 計算內插補點的平方
11 sqDistance = sqDiffMat.sum(axis= 1) # 求和
12 distances = sqDistance**0.5 # 開方
13 sortedDistance = distances.argsort()# 從小到大排序
14 classCount = {}
15 for i in range(k):
16 vlabel = y_data[sortedDistance[i]] # 擷取标簽
17 classCount[vlabel] = classCount.get(vlabel,0)+1# 統計标簽數量
18 sortedClassCount = sorted(classCount.items(),key = operator.itemgetter(1), reverse = True) # 根據operator.itemgetter(1)-第1個值對classCount排序,然後再取倒序
19 return sortedClassCount[0][0]
20 iris = datasets.load_iris()# 載入資料
21 x_train,x_test,y_train,y_test = train_test_split(iris.data, iris.target, test_size=0.3)
22 #打亂資料
23 # data_size = iris.data.shape[0]
24 # index = [i for i in range(data_size)]
25 # random.shuffle(index)
26 # iris.data = iris.data[index]
27 # iris.target = iris.target[index]
28 # test_size = 40#切分資料集
29 # x_train = iris.data[test_size:]
30 # x_test = iris.data[:test_size]
31 # y_train = iris.target[test_size:]
32 # y_test = iris.target[:test_size]
33 prodictions = []
34 for i in range(x_test.shape[0]):
35 prodictions.append(knn(x_test[i],x_train,y_train,5))
36 print(prodictions)
37 print(classification_report(y_test, prodictions))
38 print(confusion_matrix(y_test,prodictions))
39 #關于混淆矩陣可以看這篇部落格,
1 # 導入算法包以及資料集
2 from sklearn import neighbors
3 from sklearn import datasets
4 from sklearn.model_selection import train_test_split
5 from sklearn.metrics import classification_report
6 import random
7 # 載入資料
8 iris = datasets.load_iris()
9 #print(iris)
10 # 打亂資料切分資料集
11 # x_train,x_test,y_train,y_test = train_test_split(iris.data, iris.target, test_size=0.2) #分割資料0.2為測試資料,0.8為訓練資料
12
13 #打亂資料
14 data_size = iris.data.shape[0]
15 index = [i for i in range(data_size)]
16 random.shuffle(index)
17 iris.data = iris.data[index]
18 iris.target = iris.target[index]
19
20 #切分資料集
21 test_size = 40
22 x_train = iris.data[test_size:]
23 x_test = iris.data[:test_size]
24 y_train = iris.target[test_size:]
25 y_test = iris.target[:test_size]
26
27 # 構模組化型
28 model = neighbors.KNeighborsClassifier(n_neighbors=3)
29 model.fit(x_train, y_train)
30 prediction = model.predict(x_test)
31 print(prediction)
32 print(classification_report(y_test, prediction))
這三個代碼第一個,第二個是根據底層原理實作knn算法,第三個則是調用庫函數處理資料。
下面一個代碼是利用第三個代碼中用到的庫實作第一個代碼功能,可以發現使用系統提供的庫,簡單許多
1 from sklearn import neighbors
2 from sklearn.model_selection import train_test_split
3 from sklearn.metrics import classification_report
4 import numpy as np
5 x_data = np.array([[3,104],
6 [2,100],
7 [1,81],
8 [101,10],
9 [99,5],
10 [81,2]])
11 y_data = np.array(['A','A','A','B','B','B'])
12 x_test1 = np.array([[18,90]])
13 x_train, x_test, y_train,y_test = train_test_split(x_data, y_data,test_size= 0.3)
14 model = neighbors.KNeighborsClassifier(n_neighbors=3)
15 model.fit(x_train, y_train)
16 print(x_test1)
17 prediction = model.predict(x_test1)
18 print(prediction)
對字典進行排序:dic = sorted(dic.items(),key = operator.itemgetter(1),reverse=True)