代碼編輯工具:jupyter notebook
01 理論講解
1. KNN算法特點:
2. 算法原理
為了簡化問題卦停,這里只關(guān)心樣本的兩個特征,腫瘤大小和發(fā)現(xiàn)腫瘤的時間奔滑。對應(yīng)紅色(樣本數(shù)據(jù))點表示良性腫瘤,藍色(樣本數(shù)據(jù))表示惡性腫瘤,綠色(預(yù)測數(shù)據(jù))的點表示我們要預(yù)測的數(shù)據(jù)磁携,k=3表示在所有的點里,找到離這個綠色最近的三個點良风,然后判斷是紅色點多還是藍色點多谊迄,綠色點和多的一邊同類闷供。
例如:這里的綠色點,它周圍的3個點都是藍色點统诺,所以這個綠色點應(yīng)該屬于惡性腫瘤歪脏。
3. 歐拉距離
計算距離我們這里采用歐拉距離,就是兩個點對應(yīng)維度上的坐標(biāo)值相減粮呢、平方婿失、求和、開根號的過程
歐拉距離-2維,平面兩個點的距離:
歐拉距離-3維,三維立體空間兩個點的距離:
歐拉距離-n維,推導(dǎo)到n空間依然有效
歐拉距離-n維符-簡潔版:
02 代碼實戰(zhàn)
import numpy as np #導(dǎo)入numpy啄寡,用于科學(xué)計算豪硅,如,矩陣運算
import matplotlib.pyplot as plt #導(dǎo)入圖像顯示庫pyplot这难,如折線圖
import random #導(dǎo)入隨機函數(shù)庫舟误,生成隨機數(shù)
##### 10個樣本數(shù)據(jù)
data_X = [
[-0.32236679, -1.38462662],#標(biāo)簽值:0
[-0.60582652, -1.93436036],#標(biāo)簽值:0
[-2.37209117, -0.34753905],#標(biāo)簽值:0
[-0.13360596, 0.96327911],#標(biāo)簽值:0
[-1.43553756, -0.84890974],#標(biāo)簽值:0
[ 3.70753694, 0.98062288],#標(biāo)簽值:1
[ 2.029152 , -0.1819102 ],#標(biāo)簽值:1
[ 5.45626862, -1.20479895],#標(biāo)簽值:1
[ 4.07688348, -0.29181106],#標(biāo)簽值:1
[ 4.22392082, -2.92426277] #標(biāo)簽值:1
]
data_y = [0, 0, 0, 0, 0, 1, 1, 1, 1, 1] #標(biāo)簽數(shù)據(jù),0代表良性腫瘤姻乓,1代表惡性腫瘤嵌溢,是個二分類問題
data_y_name = ['良性腫瘤','惡性腫瘤']#分類名稱,0:良性腫瘤蹋岩,1:惡性腫瘤
X_train = np.array(data_X) #轉(zhuǎn)為numpy ndarray格式
y_train = np.array(data_y) #轉(zhuǎn)為numpy ndarray格式
x1 = X_train[y_train == 0,0] #在下標(biāo)為0的列上赖草,標(biāo)簽值為0的所有值,作為x1
y1 = X_train[y_train == 0,1] #在下標(biāo)為0的列上剪个,標(biāo)簽值為0的所有值秧骑,作為y1
plt.scatter(x1,y1,label="良性腫瘤") #把樣本數(shù)據(jù)x1,y1顯示在圖像上
x2 = X_train[y_train == 1,0] #在下標(biāo)為0的列上扣囊,標(biāo)簽值為1的所有值乎折,作為x2
y2 = X_train[y_train == 1,1] #在下標(biāo)為1的列上,標(biāo)簽值為1的所有值侵歇,作為y2
plt.scatter(x2,y2,label="惡性腫瘤") #把樣本數(shù)據(jù)x2骂澄,y2顯示在圖像上
x = np.array([2.093607318, -0.565731514]) #把需要預(yù)測的x顯示在圖像上
plt.scatter(x[0],x[1],label="預(yù)測點")
plt.show() #顯示圖像,效果如下
#通過歐拉距離計算預(yù)測點到每一個樣本點之前的距離
distances = []
for x_train in data_X:
d = np.sqrt(np.sum((x_train - x) ** 2))
distances.append(d)
distances
[2.5509841405146267,
3.02656372208528,
4.471025714203831,
2.7015463116527125,
3.540487745720093,
2.235169062199137,
0.38919569511900787,
3.422849429893747,
2.0021030817310623,
3.178192143708816]
#對計算出來的結(jié)果進行排序惕虑,返回排序后的下標(biāo)順序
sort_distances = np.argsort(distances)
sort_distances
array([6, 8, 5, 0, 3, 1, 9, 7, 4, 2], dtype=int64)
k = 4 #設(shè)置KNN的k值為3
X_top = X_train[sort_distances[0:k]] #計算舉例最近的三個點
X_top
array([[ 2.029152 , -0.1819102 ],
[ 4.07688348, -0.29181106],
[ 3.70753694, 0.98062288],
[-0.32236679, -1.38462662]])
#離的最近的k個點和預(yù)測點之前畫虛線
for top in X_top:
line_x = [top[0],x[0]]
linx_y = [top[1],x[1]]
plt.plot(line_x,linx_y,':')
#畫樣本點
plt.scatter(x1,y1) #良性腫瘤
plt.scatter(x2,y2) #惡性腫瘤
#畫預(yù)測點
plt.scatter(x[0],x[1])
#圖像顯示
plt.show()
#通過距離最近的k個值坟冲,獲取指定樣本的標(biāo)簽
y_top_k = y_train[sort_distances[0:k]]
y_top_k
array([1, 1, 1, 0])
from collections import Counter
#統(tǒng)計不同分類標(biāo)簽的個數(shù)
votes = Counter(y_top6)
votes
Counter({1: 3, 0: 1})
#獲取最多分類的那個標(biāo)簽值
lvalue = votes.most_common(1)[0][0]
lvalue
1
#通過標(biāo)簽值顯示對于的分類名稱
data_y_name[lvalue]
'惡性腫瘤'