k近鄰演算法本身是個很簡單的演算法,某些時候甚至不能稱之為機器學習演算法,因為它沒有「學習」的過程,僅僅通過判定和要**的x
xx相近的點都呈現的表徵來確定x
xx的對應類標y
yy就可以了,但是《統計學習方法》這本書使用了kd-tree的方法來尋找最近鄰,其主要目的是在資料量比較大的時候能夠優化查詢效率,從原理來講,樹結構的查詢的時間複雜度o(l
ogn)
o\left( logn \right)
o(logn
)比線性查詢的複雜度o(n
)o\left( n \right)
o(n)
低,因此效率比較高。
輸入:訓練資料集t
=t = \
t=其中, xi∈
x⊆rn
x_i \in \mathcal \subseteq r^n
xi∈x⊆
rn為例項的特徵向量,yi∈
y=
y_i \in \mathcal =\
yi∈y=
為例項的類別, i=1
,2,.
..
ni = 1,2,...n
i=1,2,
...n
; 例項特徵向量xxx.
輸出:例項x
xx所屬類別y
yy
def caldis(x_1,x_2,dis_type = none):
"""距離度量公式,包含2種,分別記為'e','m',e為歐式距離,m是曼哈頓距離
x_1,x_2為兩個向量s
"""distance = 0
if (dis_type == none)|(dis_type == 'e'):
distance = math.sqrt(sum((x_1-x_2)**2))
elif (dis_type == 'm'):
distance = sum(abs(x_1-x_2))
else:
print('warning: 函式caldis(self,x_1,x_2,dis_type)沒有dis_type='+ str(dis_type) +' 這種距離度量方法,請重新定義dis_type=e或者m')
return distance
測試距離計算
import numpy as np
import math
a = np.array([1,2])
b = np.array([2,1])
print('歐式距離為:' ,caldis(a,b,'e'))
print('曼哈頓距離為:' , caldis(a,b,'m'))
歐式距離為: 1.4142135623730951
曼哈頓距離為: 2
這裡使用遍歷計算的方法直接及計算距離並找到最近的k個元素
data = np.array([[2,3],[5,4],[9,6],[4,7],[8,1],[7,2]])
data_label = np.array([1,1,0,1,0,0])
這裡首先定義訓練部分「train」,但是實質不是訓練過程,這裡用來儲存模型的引數,即x,y,k,distance_type
class myknn():
def train(self, x, y, k = none, dis_type = none):
model =
self.x = x
self.y = y
if k == none:
self.k = 1
else:
self.k = k
if dis_type == none:
self.dis_type = 'e'
else:
self.dis_type = dis_type
return model
def predict(self,x,model,dis_type = none):
if x.ndim == 1: # 如果是乙個樣本
x = x.reshape(1,len(x)) # 轉化為1×n的張量樣本
predicted_y = # 用於儲存**類別
for i in range(len(x)): # **x的每個元素
distance = # 儲存x[j]與原有資料所有樣本之間的距離
for j in range(len(model[0])): # 計算x[j]與原有資料所有樣本之間的距離
predicted_y_distance = np.column_stack((model[1],distance)) # 合併得到(y,distance)兩列資料
# 排序,以下步驟實現argmax的那個步驟
sorted_y_distance = predicted_y_distance[
predicted_y_distance.argsort(0)[:,1]] # 對得到的(y,distance)按照第二列排序
knn_data = sorted_y_distance[:model[2]]
nearestky_list = knn_data[:,0].tolist()
count =
y = sorted(count.keys())[0]
return predicted_y
def accuracy(self,precited_y,real_y):
self.y = precited_y
self.realy = real_y
return 1-sum(np.sign(np.abs(self.y-self.realy)))/len(self.y)
測試:
mk = myknn()
model1 = mk.train(data,data_label,k=3,dis_type='m') # 曼哈頓距離,k=3
predicted_y = mk.predict(data,model1)
print('使用曼哈頓距離得到的正確率:',mk.accuracy(predicted_y,data_label))
model2 = mk.train(data,data_label) # 歐式距離,k為預設值k=1
predicted_y = mk.predict(data,model2)
print('使用歐式距離得到的正確率:',mk.accuracy(predicted_y,data_label))
使用曼哈頓距離得到的正確率: 1.0
使用歐式距離得到的正確率: 1.0
機器學習 k 近鄰演算法(手寫字識別)
knn演算法在簡單二維資料上計算時 d 根號 x0 x 2 y0 y 2 這裡被推廣到1024維,將32 32二進位制當成1 1024的向量。計算上和二維是一樣的。缺點是計算量太大了。usr bin python coding utf 8 用knn識別手寫數字 from numpy import i...
機器學習實戰 使用K 近鄰演算法識別手寫數字
每張都是32畫素x32畫素 def img2vector filename 將32x32的影象轉化為1x1024的向量 param filename return return vect zeros 1,1024 fr open filename for i in range 32 用for lin...
機器學習 2 k 鄰近演算法識別手寫數字
思路 訓練集 trainingdigits資料夾內的32位二進位制影象矩陣 target向量 從trainingdigits資料夾內的檔名讀取影象矩陣所表示的數字 測試集 testdigits資料夾內的32位二進位制影象矩陣 predicted 值 從testdigits資料夾內檔名讀取影象矩陣所表...