KNN-K最近鄰算法
什么是KNN算法
KNN算法是尋找最近的K個數據,推測新數據的分類
算法原理
通用步驟
- 計算距離(常用有歐幾里得距離、馬氏距離)
- 升序排序
- 取前K個
- 加權平均
K的選取
- K太大:會導致分類模糊
- K太小:容易受個例影響,波動較大
- 選取:均方根誤差(找到峰值
實例:預測癌症良性 OR 惡性
數據分析與預處理
M:惡性
B:良性
其他數據為判斷良性 、 惡性的依據
划分數據集
取數據的1/3作為測試集,2/3作為訓練集
import random
import csv
# 癌症預測數據文件讀取
with open("Prostate_Cancer.csv", "r") as file:
reader = csv.DictReader(file)
datas = [row for row in reader]
# 分組 -訓練集2/3 -測試集1/3
# 將數據打亂,每次得到不同的分組
random.shuffle(datas)
n = len(datas) // 3
test_set = datas[0:n]
train_set = datas[n:]
歐幾里得公式測距離
# 距離
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值
先嘗試K取5
將運算后的數據按距離升序排列
選取距離最小的k個樣點
加權平均
分類計算加權平均距離,多數表決預測
源碼
import random
import csv
# 癌症預測數據文件讀取
with open("Prostate_Cancer.csv", "r") as file:
reader = csv.DictReader(file)
datas = [row for row in reader]
# 分組 -訓練集2/3 -測試集1/3
# 將數據打亂,每次得到不同的分組
random.shuffle(datas)
n = len(datas) // 3
test_set = datas[0:n]
train_set = datas[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 = 5
def knn(data):
# 1.所有的距離
res = [
{"result": train["diagnosis_result"], "distance": distance(data, train)}
for train in train_set
]
# 2.升序排序
res = sorted(res, key=lambda item: item["distance"])
# 3.取前K個
res2 = res[0:K]
# 4.加權平均
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
# print(result)
# print(data["diagnosis_result"])
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 += 1
print("准確個數:", correct)
print("測試總數:", len(test_set))
print("准確率:{:.2f}%".format(100 * correct / len(test_set)))