KNN簡介
爲了判斷未知實例的類別,以所有已知類別的實例作爲
參照選擇參數K
計算未知實例與所有已知實例的距離(歐式距離)
選擇最近K個已知實例
根據少數服從多數的投票法則(majority-voting) ,讓
未知實例歸類爲K個最鄰近樣本中最多數的類別
算法缺點:
算法複雜度較高(需要比較所有已知實例與要分類的實例)
當其樣本分佈不平衡時,比如其中一類樣本過大(實例數量
過多)佔主導的時候,新的未知實例容易被歸類爲這個主導
樣本,因爲這類樣本實例的數量過大,但這個新的未知實例
實際並沒有接近目標樣本
算法實踐
首先進行數據可視化,數據集分爲A,B兩類,然後通過計算歐氏距離預測未知X的類別
數據可視化:
import matplotlib.pyplot as plt
import numpy as np
import operator
#已知類A,B的數據
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
x = np.array([18])
y = np.array([90])
scatter3 = plt.scatter(x,y,c='k')
#畫圖例
plt.legend(handles=[scatter1,scatter2,scatter3],labels=['A類','B類','未知X'],loc='best')
plt.show()
KNN預測:
import matplotlib.pyplot as plt
import numpy as np
import operator
# 已知分類的數據
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]
# 複製x_test
np.tile(x_test, (x_data_size,1))
# 計算x_test與每一個樣本的差值
diffMat = np.tile(x_test, (x_data_size,1)) - x_data
# 計算差值的平方
sqDiffMat = diffMat**2
# 求和
sqDistances = sqDiffMat.sum(axis=1)
# 開方
distances = sqDistances**0.5
# 從小到大排序
sortedDistances = distances.argsort()
classCount = {}
# 設置k
k = 5
for i in range(k):
# 獲取標籤
votelabel = y_data[sortedDistances[i]]
# 統計標籤數量
classCount[votelabel] = classCount.get(votelabel,0) + 1
# 得到的classCount爲{'A':3,'B':2},也有可能多的不在前面,所以需要排序
# 根據operator.itemgetter(1)-第1個值對classCount排序,然後再取倒序
sortedClassCount = sorted(classCount.items(),key=operator.itemgetter(1), reverse=True)
# 獲取數量最多的標籤
knnclass = sortedClassCount[0][0]
轉自:https://www.bilibili.com/video/BV1Rt411q7WJ?p=42