本文風格:以??簡單易懂??的語言帶你徹底搞懂KNN,了解什么是有監督學習算法。
認真看完這篇文章,徹底了解KNN、了解監督學習算法絕對是一樣很簡單的事情。
注:本篇文章非常詳細,同時我也附加了Python代碼,歡迎收藏后慢慢閱讀。
本文主要介紹的有監督學習算法是KNN,后續會接著介紹決策樹、線性回歸等算法。
首先,第一個也是最主要的問題——KNN是如何對樣本進行分類的呢?
它的本質是通過距離判斷兩個樣本是否相似,如果距離夠近就認為他們足夠相似屬于同一類別。
當然只對比一個樣本是不夠的,誤差會很大,我們需要找到離其最近的 k 個樣本,并將這些樣本稱之為「近鄰」(nearest neighbor)。對這 k 個近鄰,查看它們的都屬于何種類別(這些類別我們稱作「標簽」 (labels))。
然后根據“少數服從多數,一點算一票”原則進行判斷,數量最多的的標簽類別就是新樣本的標簽類別。其中涉及到的原理是“越相近越相似”,這也是KNN的基本假設。
假設 X_test 待標記的數據樣本,X_train 為已標記的數據集。
該算法的「距離」在二維坐標軸就表示兩點之間的距離,計算距離的公式有很多。
我們常用歐拉公式,即“歐氏距離”。回憶一下,一個平面直角坐標系上,如何計算兩點之間的距離?
應該不難會想起來吧,公式應該大致如下: d i s t a n c e ( A , B ) = ( x A ? x B ) 2 + ( y A ? y B ) 2 distance(A, B)=/sqrt[]{(x_A-x_B)^2+(y_A-y_B)^2} distance(A,B)=(xA??xB?)2+(yA??yB?)2?那如果不是在一個平面直角坐標系,而是在立體直角坐標系上,怎么計算呢? d i s t a n c e ( A , B ) = ( x A ? x B ) 2 + ( y A ? y B ) 2 + ( z A ? z B ) 2 distance(A, B)=/sqrt[]{(x_A-x_B)^2+(y_A-y_B)^2+(z_A-z_B)^2} distance(A,B)=(xA??xB?)2+(yA??yB?)2+(zA??zB?)2?那如果是n維空間呢? d i s t a n c e ( A , B ) = ( x 1 A ? x 1 B ) 2 + ( x 2 A ? x 2 B ) 2 + ( x 3 A ? x 3 B ) 2 + . . . . . . + ( x n A ? x n B ) 2 = ∑ i = 1 n ( x i A ? x i B ) 2 distance(A, B)=/sqrt[]{(x_{1A}-x_{1B})^2+(x_{2A}-x_{2B})^2+(x_{3A}-x_{3B})^2+......+(x_{nA}-x_{nB})^2}=/sqrt[]{/sum_{i=1}^{n} {(x_{iA}-x_{iB})^2}} distance(A,B)=(x1A??x1B?)2+(x2A??x2B?)2+(x3A??x3B?)2+......+(xnA??xnB?)2?=i=1∑n?(xiA??xiB?)2?而在我們的機器學習中,坐標軸上的值 x 1 x_1 x1?, x 2 x_2 x2? , x 3 x_3 x3? ,…… x n x_n xn?正是我們樣本數據上的 n 個特征。
算法參數是 k,k 可以理解為標記數據周圍幾個數作為參考對象,參數選擇需要根據數據來決定。
默認情況下,在計算距離時,權重都是相同的,但實際上我們可以針對不同的鄰居指定不同的距。離權重,比如距離越近權重越高。
使用一定半徑內的點取代距離最近的 k 個點。
這里我還是先以上篇文章講到的紅酒分類為例子,待會還會有其他實例。
import numpy as npimport pandas as pdimport matplotlib.pyplot as plt# 解決坐標軸刻度負號亂碼plt.rcParams["axes.unicode_minus"] = False# 解決中文亂碼問題plt.rcParams["font.sans-serif"] = ["Simhei"]plt.style.use("ggplot")# plt.figure(figsize=(2,3),dpi=720)
首先隨機設置十個樣本點表示十杯酒,這里取了部分樣本點。
為了方便驗證,這里使用 Python 的字典 dict 構建數據集,然后再將其轉化成 DataFrame 格式。
rowdata = {"顏色深度": [14.23,13.2,13.16,14.37,13.24,12.07,12.43,11.79,12.37,12.04], "酒精濃度": [5.64,4.38,5.68,4.80,4.32,2.76,3.94,3.1,2.12,2.6], "品種": [0,0,0,0,0,1,1,1,1,1]} # 0 代表 “黑皮諾”,1 代表 “赤霞珠” wine_data = pd.DataFrame(rowdata)wine_data
X = np.array(wine_data.iloc[:,0:2]) #我們把特征(酒的屬性)放在X y = np.array(wine_data.iloc[:,-1]) #把標簽(酒的類別)放在Y
我們先來畫一下圖。
#探索數據,假如我們給出新數據[12.03,4.1] ,你能猜出這杯紅酒是什么類別么? new_data = np.array([12.03,4.1]) plt.scatter(X[y==1,0], X[y==1,1], color="red", label="赤霞珠") #畫出標簽y為1 的、關于“赤霞珠”的散點 plt.scatter(X[y==0,0], X[y==0,1], color="purple", label="黑皮諾") #畫出標簽y為0 的、關于“黑皮諾”的散點 plt.scatter(new_data[0],new_data[1], color="yellow") # 新數據點 new_data plt.xlabel("酒精濃度") plt.ylabel("顏色深度") plt.legend(loc="lower right") plt.savefig("葡萄酒樣本.png")
講道理,你應該一下就能看出來了。不過,如果是計算機,會這么分辨呢?
我們使用歐式距離公式,計算新數據點 new_data 與現存的 X 數據集每一個點的距離:
from math import sqrt distance = [sqrt(np.sum((x-new_data)**2)) for x in X ] distance
那現在,我們就已經得到黃點距離其它每個點的距離啦。
sort_dist = np.argsort(distance) # 這里是用到了argsort方法,可以返回數據對應的下標,如果直接用sort方法的話是返回打亂的數據,我們也不好區分對應是什么類別。sort_dist
array([6, 7, 1, 4, 5, 9, 2, 8, 3, 0], dtype=int64)
6、7、4為最近的3個“數據點”的索引值,那么這些索引值對應的原數據的標簽是什么?
k = 3 topK = [y[i] for i in sort_dist[:k]] topK
[1,1,0]
這個時候我們就得到了離黃點最近的三個點對應的類別啦。
# 在numpy中有mean、median方法可以求平均數和中位數,不過沒有方法直接求眾數。pd.Series(topK).value_counts().index[0]
1
所以當我們的k取3時,分類結果為1,也就是赤霞珠。大家看一下是不是跟我們人腦分辨的結果是一樣的呢?
那為了后續更好的操作,我們可以將上述過程封裝成一個函數。
def KNN(new_data,dataSet,k): """ 函數功能:KNN分類器 參數說明: new_data: 需要預測分類的數據集 dataSet: 已知分類標簽的數據集 k: k-近鄰算法參數,選擇距離最小的k個點 return: result: 分類結果 """ from math import sqrt from collections import Counter import numpy as np import pandas as pd result = [] distance = [sqrt(np.sum((x-new_data)**2)) for x in np.array(dataSet.iloc[:,0:2])] sort_dist = np.argsort(distance) topK = [dataSet.iloc[:,-1
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/119682.html
摘要:進入當前程序的學習系統的所有樣本稱作輸入,并組成輸入空間。結束語注意這篇文章僅僅是我接下來的機器學習系列的第一篇,后續還會有更多的內容。 往期回顧:統計學習方法第...
摘要:小栗子對于可樂來講,只要是同一個品牌的可樂,他們就有著同樣的成分,這被稱之為配方。小栗子對于可樂來說,按照配方把可樂生產出來的過程就是實例化的過程。小栗子類的屬性與正常的變量并無區別。 前言 我是栗子,帶大家從零開始學習Python,希望每篇文章都能讓你收獲滿滿! 今天我們要說的是面向對象的...
閱讀 3560·2021-09-22 10:52
閱讀 1588·2021-09-09 09:34
閱讀 1990·2021-09-09 09:33
閱讀 757·2019-08-30 15:54
閱讀 2595·2019-08-29 11:15
閱讀 713·2019-08-26 13:37
閱讀 1666·2019-08-26 12:11
閱讀 2974·2019-08-26 12:00