一、KNN算法的核心思想:尋找最近的k個數據,推測新數據的分類
二、KNN算法的原理:
- 計算測量數據與各個訓練數據之間的距離;
- 按照距離的遞增關係進行排序;
- 選取前k個距離最小的點;
- 對這前k個點距離取加權平均數;
三、計算距離量度方式包括:
樣本空間內的兩個點之間的距離量度表示兩個樣本點之間的相似程度:距離越短,表示相似程度越高;反之,相似程度越低。量度空間中點的距離,有好幾種量度方式,比如常見的曼哈頓距離計算,歐式距離計算等等。不過通常KNN算法中使用的是歐式距離,不用曼哈頓距離。
曼哈頓距離只計算水平或垂直距離,有維度的限制。
歐式距離可用於任何空間的距離計算問題。
樣本空間內的數據點可以存在於任何空間,歐氏距離是更可行的選擇。
四、k的選取:
- k太大:導致分類模糊
- k太小:受個例影響,波動較大
- 在實際應用中,K值一般取一個比較小的數值,例如採用交叉驗證法(將樣本數據按照一定比例,拆分出訓練用的數據和驗證用的數據,比如6:4拆分出部分訓練數據和驗證數據),從選取一個較小的K值開始,不斷增加K的值,然後計算驗證集合的方差,最終找到一個比較合適的K值。
- 一般也要選擇K的值應該儘量選擇爲奇數,並且不要是分類結果的偶數倍,否則會出現同票的情況。
五、應用——癌症數據模擬:
import random
import csv
#讀取
with open('F:\python_jqxx\knn\Prostate_Cancer.csv','r') as file:
# 以字典的形式讀取文件
reader = csv.DictReader(file)
#放入list中
datas = [row for row in reader]
#分組
#打亂順序
random.shuffle(datas)
#訓練集
n = len(datas)//3
train_set = datas[n:]
#測試集
test_set = datas[0:n]
#knn
#距離(歐氏距離)
def distance(d1,d2):
res = 0;
for key in ("radius", "texture", "perimeter",
"area", "smoothness", "compactness", "symmetry", "fractal_dimension"):
#平方
res += (float(d1[key]) - float(d2[key]))**2
#開方
return res**0.5
k = 3
def knn(data):
#距離
res=[
{"result":train['diagnosis_result'],"distance":distance(data,train)}
for train in train_set
]
#res = [{'result': 'M', 'distance': 138.97843884214558}, {'result': 'M', 'distance': 264.20447461767185}...]
#升序排序
res = sorted(res,key = lambda item:item['distance'])
#取前k個
res2 = res[0:k]
#加權平均
result = {'B':0,'M':0}
#總距離
sum = 0
for r in res2:
sum += r['distance']
for r in res2:
#加權
result[r['result']] += 1 - r['distance']/sum
if result['B'] > result['M']:
return 'B'
else:
return 'M'
#測試階段
correct = 0
for test in test_set:
result = test['diagnosis_result']
result2 = knn(test)
if result == result2:
correct = correct + 1;
print("準確率:{:.2f}%".format(correct*100/len(test_set)))
結果:
六、KNN算法的優缺點:
優點
1、KNN可以處理分類問題,同時天然可以處理多分類問題,比如鳶尾花的分類
2、簡單,易懂,同時也很強大,對於手寫數字的識別,鳶尾花這一類問題來說,準確率很高
3、KNN還可以處理迴歸問題,也就是預測
缺點
1、效率低,因爲每一次分類或者回歸,都要把訓練數據和測試數據都算一遍,如果數據量很大的話,需要的算力會很驚人
2、對訓練數據依賴度特別大,雖然所有機器學習的算法對數據的依賴度很高,但是KNN尤其嚴重,因爲如果我們的訓練數據集中,有一兩個數據是錯誤的,剛剛好又在我們需要分類的數值的旁邊,這樣就會直接導致預測的數據的不準確,對訓練數據的容錯性太差
3、維數災難,KNN算法對於多維度的數據處理也不是很好
七、KNN算法的時間複雜度:
KNN算法的時間複雜度爲O(D*N*N)。其中D爲維度數,N爲樣本總數。從時間複雜度上我們可以很清楚的就知道KNN非常不適合高維度的數據集,容易發生維度爆炸的情況。