自己動手寫機器學習演算法 第3章 k近鄰法描述

2021-08-26 23:30:50 字數 3459 閱讀 1804

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資料夾內檔名讀取影象矩陣所表...