原生python實現knn分類演算法

2021-09-28 15:56:40 字數 4629 閱讀 7675

一、 題目

原生python實現knn分類演算法

二、 演算法設計

k 近鄰(k-nearset neighbor,簡稱 knn)學習是一種常用的監督學習方法,其工作機制非常簡單:給定測試樣本,基於某種距離度量找出訓練集中與其最靠近的 k 個訓練樣本,然後基於這 k 個「鄰居」的資訊來進行觀測。通常,在 分類任務 中可使用「投票法」,即將這 k 個樣本點**現最多的類別標記作為**結果;在 回歸任務 中可使用「平均法」,將這 k 個樣本的實值輸出標記的平均值作為**結果;還可以基於距離遠近進行加權平均或加權投票,距離越近的樣本權重越大。

knn 演算法:

將每個樣本視作乙個點

載入資料集,對資料進行必要的預處理

設定引數k,k最好選擇奇數,因為後續進行歸類的策略是少數服從多數,設定k為奇數的話總會有結果。

計算待**點與已知點之間的關係,這裡的關係可以有多種方式來體現,常用如下:

①歐式距離(應用較廣,其他及其演算法也有廣泛應用),其計算方法:

②曼哈頓距離

③……之前確定了引數k,計算了待**點與已知點之間的距離衡量,將計算的結果進行從小到大排序,取前k個點

將待**點歸類為多數的那乙個類別,這便是對於未知點的類別**結果了。

三、源**

import numpy as np

import pandas as pd

# 讀取資料集,header引數來指定引數標題的行,預設為0,第一行,如果沒有標題使用none

data = pd.read_csv(

'iris.csv'

, header=0)

# 對文字進行處理,將species列的文字對映成數值型別

data[

'species'

]= data[

'species'].

map(

)data.sample(10)

# 刪除不需要的列

data.drop(

"id"

, axis=

1, inplace=

true

)# 重複值檢查,any(),一旦有重複值,就返回true

data.duplicated().

any(

)# 刪除重複的資料

data.drop_duplicates(inplace=

true

)# 檢視各類別的資料條數

data[

'species'

].value_counts(

)#顯示讀取的資料

print

(data)

# 編寫knn類

class

knn:

def__init__

(self, k)

:"""

k:int

鄰居的個數

"""self.k = k

deffit(self, x, y)

:"""

x:類似陣列型別,list,ndarray……形狀:[樣本的數量,特徵的數量]

y:類似陣列型別,形狀為[樣本數量]

每個樣本的目標值,也是就是標籤

"""# 將x轉換成ndarray型別,如果x已經是ndarray則不進行轉換

self.x = np.asarray(x)

self.y = np.asarray(y)

defpredict

(self, x)

:"""根據引數傳遞的樣本,對樣本資料進行**,返回**之後的結果

----

x:類似陣列型別,list,ndarray……形狀:[樣本的數量,特徵的數量]

return

----

result:數型別,**的結果。

"""# 將測試的x轉換為ndarray結構

x = np.asarray(x)

result =

for x in x:

# ndarray相減為對應元素相減,測試的x的每一行與self.x 相減

# 求歐氏距離:每個元素都取平方值

dis = np.sqrt(np.

sum(

(x - self.x)**2

, axis=1)

)# 求最近的k個點的距離,sort()排序不適用,因為排序後打亂了順序

# argsort(),返回每個元素在排序之前原陣列的索引

index = dis.argsort(

)# 取前k個元素,距離最近的k的元素

index = index[

:self.k]

# 返回陣列中每個元素出現的次數,元素必須是非負整數

count = np.bincount(self.y[index]

)# 返回ndarray之最大的元素的索引,該索引就是我們判定的類別))

return np.asarray(result)

defpredict2

(self, x)

:"""根據引數傳遞的樣本,對樣本資料進行**(考慮權重,使用距離的倒數作為權重),返回**之後的結果

parameters

----

x:類似陣列型別,list,ndarray……形狀:[樣本的數量,特徵的數量]

return

----

result:數型別,**的結果。

"""# 將測試的x轉換為ndarray結構

x = np.asarray(x)

result =

for x in x:

# ndarray相減為對應元素相減,測試的x的每一行與self.x 相減

# 求歐氏距離:每個元素都取平方值

dis = np.sqrt(np.

sum(

(x - self.x)**2

, axis=1)

)# 求最近的k個點的距離,sort()排序不適用,因為排序後打亂了順序

# argsort(),返回每個元素在排序之前原陣列的索引

index = dis.argsort(

)# 取前k個元素,距離最近的k的元素

index = index[

:self.k]

# 返回陣列中每個元素出現的次數,元素必須是非負整數,【使用weight考慮權重,權重為距離的倒數】

count = np.bincount(self.y[index]

, weights=

1/ dis[index]

)# 返回ndarray之最大的元素的索引,該索引就是我們判定的類別))

return np.asarray(result)

#資料集拆分成訓練集和測試集

#1、提取每個類別鳶尾花的數量

t0 = data[data[

'species']==

0]t1 = data[data[

'species']==

1]t2 = data[data[

'species']==

2]#打亂順序,random_state ,記住打亂的順序

t0 = t0.sample(

len(t0)

,random_state=0)

t1 = t1.sample(

len(t1)

,random_state=0)

t2 = t2.sample(

len(t2)

,random_state=0)

train_x = pd.concat(

[t0.iloc[:40

,:-1

],t1.iloc[:40

,:-1

],t2.iloc[:40

,:-1

]],axis=0)

train_y = pd.concat(

[t0.iloc[:40

,-1]

,t1.iloc[:40

,-1]

,t2.iloc[:40

,-1]

],axis=0)

test_x = pd.concat(

[t0.iloc[40:

,:-1

],t1.iloc[40:

,:-1

],t2.iloc[40:

,:-1

]],axis=0)

test_y = pd.concat(

[t0.iloc[40:

,-1]

,t1.iloc[40:

,-1]

,t2.iloc[40:

,-1]

],axis=0)

#進行訓練與測試

knn = knn(k=3)

#進行訓練

knn.fit(train_x,train_y)

#進行測試

result = knn.predict(test_x)

# display(result)

# display(test_y)

#檢視**結果

print

(np.mean(result == test_y)

)

原生Python實現KNN分類演算法

原生python實現knn分類演算法,用鳶尾花資料集。knn是一種聚類演算法,用於對新的資料點進行分類。對於乙個只知道特徵的資料點,首先計算它和已知訓練集所有點的距離,然後選擇最近的k個點進行 投票表決 來決定所屬型別。因為訓練集的標籤是已知的,所以根據 投票 結果,判定該點的型別為 票數 最多的類...

原生python實現knn分類演算法,用鳶尾花資料集

1.作業題目 原生python實現knn分類演算法,用鳶尾花資料集 2.演算法設計 knn演算法設計思路 演算法涉及3個主要因素 訓練資料集 距離或相似度的計算衡量 k的大小 對於確定未知類別 1.計算已知類別資料集中的點與當前點的距離 距離的計算一般使用歐氏距離或曼哈頓距離 2.按照距離依次排序 ...

原生python實現knn演算法

1 knn演算法的思想 就是在訓練集中資料和標籤已知的情況下,輸入測試資料,將測試資料的特徵與訓練集中對應的特徵進行相互比較,找到訓練集中與之最為相似的前k個資料,則該測試資料對應的類別就是k個資料 現次數最多的那個分類。2 演算法設計 根據knn演算法的思想可以得到knn演算法的步驟為 1 計算測...