一、什麼是knn算法
knn算法實際上是利用訓練數據集對特徵向量空間進行劃分,並作爲其分類的模型。其輸入是實例的特徵向量,輸出爲實例的類別。尋找最近的k個數據,推測新數據的分類。
二、算法原理
對於上面的這個散點圖,已知的點是分佈在一個二維空間的,當然,在實際生活中,情況會變得複雜,可能是多維的。這個例子表示的是腫瘤病人的相關信息,橫軸表示腫瘤的大小,縱軸表示腫瘤發現的時間,這兩個軸均是病人腫瘤的特徵信息。紅色的點表示良性腫瘤,藍色的表示惡性,表示的是腫瘤的分類。
有了這些初始信息,假如這個時候來了一條新的腫瘤特徵信息,我們就可以通過knn算法來對其分類進行預測:
首先我們會取一個k值,假如這裏k=3(k如何取值後面會提到)。接下來要做的就是在所有的點中選擇離這個新的點最近的三個點,然後這三個點根據自己的分類進行投票,這裏的話三個點都是惡性腫瘤,所以根據惡性對良性3:0推測這個新的點也是惡性腫瘤。
knn算法的本質其實是認爲兩個樣本如果他們足夠相似的話,那麼他們就具有更高的概率屬於同一類別。這裏我們通過計算兩個樣本在樣本空間中的距離來衡量他們的相似度。
三、通用步驟
- 計算距離
計算待求點與其他點之間的距離(常用歐幾里得距離或馬氏距離) - 升序排列
將計算的距離按照升序排列,即距離越近越靠前 - 取前k個
- 加權平均
四、簡單應用
對於上圖這樣的100條數據(數據來源:https://www.kaggle.com/sajidsaifi/prostate-cancer),表示癌症病人診療結果與各項指標之間的關係,使用knn算法來預測新數據基於各項指標的診療結果
import pandas as pd
import random
from collections import Counter
# 讀取數據
file_data = pd.read_csv("./_Cancer.csv").to_dict(orient="records")
# 分組:測試集(少量)、訓練集--(確保算法是有效的、可行的)
# 避免偶然情況,先將數據集打亂
random.shuffle(file_data)
test_set = file_data[:len(file_data) // 3]
train_set = file_data[len(file_data) // 3:]
# 計算距離(這裏使用歐氏距離)
def distance(p1, p2):
res = 0
for key in (
"radius", "texture", "perimeter", "area", "smoothness", "compactness", "symmetry", "fractal_dimension"):
res += (p1[key] - p2[key]) ** 2
return res ** 0.5
K = 5 #這裏取K=5
# KNN
def knn(new_data):
# 1.計算距離
res = [{"diagnosis_result": train_data["diagnosis_result"], "distance": distance(new_data, train_data)} for
train_data in train_set]
# 2.升序排列
res = sorted(res, key=lambda item: item["distance"])
# 3.取前K個
res = res[:K]
# 4.投票選舉(也可以加權平均)
res_list = [item["diagnosis_result"] for item in res]
votes = Counter(res_list)
return votes.most_common(1)[0][0]
# 測試
correct = 0
for test in test_set:
if test["diagnosis_result"] == knn(test):
correct += 1
print("正確率 = {:.2f}%".format((correct / len(test_set)) * 100))
100條數據測得準確率在80%左右