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#https://blog.csdn.net/u010339879/article/details/98304292,關於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 #關於混淆矩陣可以看這篇博客,#https://www.cnblogs.com/missidiot/p/9450662.html
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)