成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

以??簡(jiǎn)單易懂??的語(yǔ)言帶你搞懂有監(jiān)督學(xué)習(xí)算法【附Python代碼詳解】機(jī)器學(xué)習(xí)系列之KNN篇

MoAir / 1599人閱讀

必須要看的前言

本文風(fēng)格:以??簡(jiǎn)單易懂??的語(yǔ)言帶你徹底搞懂KNN,了解什么是有監(jiān)督學(xué)習(xí)算法。

認(rèn)真看完這篇文章,徹底了解KNN、了解監(jiān)督學(xué)習(xí)算法絕對(duì)是一樣很簡(jiǎn)單的事情。

注:本篇文章非常詳細(xì),同時(shí)我也附加了Python代碼,歡迎收藏后慢慢閱讀。

監(jiān)督學(xué)習(xí)算法

本文主要介紹的有監(jiān)督學(xué)習(xí)算法是KNN,后續(xù)會(huì)接著介紹決策樹、線性回歸等算法。

KNN/K近鄰算法

1 算法原理

首先,第一個(gè)也是最主要的問(wèn)題——KNN是如何對(duì)樣本進(jìn)行分類的呢?

它的本質(zhì)是通過(guò)距離判斷兩個(gè)樣本是否相似,如果距離夠近就認(rèn)為他們足夠相似屬于同一類別。

當(dāng)然只對(duì)比一個(gè)樣本是不夠的,誤差會(huì)很大,我們需要找到離其最近的 k 個(gè)樣本,并將這些樣本稱之為「近鄰」(nearest neighbor)。對(duì)這 k 個(gè)近鄰,查看它們的都屬于何種類別(這些類別我們稱作「標(biāo)簽」 (labels))。

然后根據(jù)“少數(shù)服從多數(shù),一點(diǎn)算一票”原則進(jìn)行判斷,數(shù)量最多的的標(biāo)簽類別就是新樣本的標(biāo)簽類別。其中涉及到的原理是“越相近越相似”,這也是KNN的基本假設(shè)。

1.1 實(shí)現(xiàn)過(guò)程

假設(shè) X_test 待標(biāo)記的數(shù)據(jù)樣本,X_train 為已標(biāo)記的數(shù)據(jù)集。

  • 遍歷已標(biāo)記數(shù)據(jù)集中所有的樣本,計(jì)算每個(gè)樣本與待標(biāo)記點(diǎn)的距離,并把距離保存在 Distance 數(shù)組中。
  • 對(duì) Distance 數(shù)組進(jìn)行排序,取距離最近的 k 個(gè)點(diǎn),記為 X_knn。
  • 在 X_knn 中統(tǒng)計(jì)每個(gè)類別的個(gè)數(shù),即 class0 在 X_knn 中有幾個(gè)樣本,class1 在 X_knn 中有幾個(gè)樣本等。
  • 待標(biāo)記樣本的類別,就是在 X_knn 中樣本個(gè)數(shù)最多的那個(gè)類別。

1.2 距離的確定

該算法的「距離」在二維坐標(biāo)軸就表示兩點(diǎn)之間的距離,計(jì)算距離的公式有很多。

我們常用歐拉公式,即“歐氏距離”?;貞浺幌拢粋€(gè)平面直角坐標(biāo)系上,如何計(jì)算兩點(diǎn)之間的距離?

應(yīng)該不難會(huì)想起來(lái)吧,公式應(yīng)該大致如下: 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 ?那如果不是在一個(gè)平面直角坐標(biāo)系,而是在立體直角坐標(biāo)系上,怎么計(jì)算呢? 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=1n?(xiA??xiB?)2 ?而在我們的機(jī)器學(xué)習(xí)中,坐標(biāo)軸上的值 x 1 x_1 x1?, x 2 x_2 x2? , x 3 x_3 x3? ,…… x n x_n xn?正是我們樣本數(shù)據(jù)上的 n 個(gè)特征。

2 算法的優(yōu)缺點(diǎn)

算法參數(shù)是 k,k 可以理解為標(biāo)記數(shù)據(jù)周圍幾個(gè)數(shù)作為參考對(duì)象,參數(shù)選擇需要根據(jù)數(shù)據(jù)來(lái)決定。

  • k 值越大,模型的偏差越大,對(duì)噪聲數(shù)據(jù)越不敏感。
  • k 值很大時(shí),可能造成模型欠擬合。
  • k 值越小,模型的方差就會(huì)越大。
  • 但是 k 值太小,容易過(guò)擬合。

3 算法的變種

3.1 變種一

默認(rèn)情況下,在計(jì)算距離時(shí),權(quán)重都是相同的,但實(shí)際上我們可以針對(duì)不同的鄰居指定不同的距。離權(quán)重,比如距離越近權(quán)重越高。

  • 這個(gè)可以通過(guò)指定算法的 weights 參數(shù)來(lái)實(shí)現(xiàn)。

3.2 變種二

使用一定半徑內(nèi)的點(diǎn)取代距離最近的 k 個(gè)點(diǎn)。

  • 在 scikit-learn 中,RadiusNeighborsClassifier 實(shí)現(xiàn)了這種算法的變種。
  • 當(dāng)數(shù)據(jù)采樣不均勻時(shí),該算法變種可以取得更好的性能。

4 Python代碼實(shí)現(xiàn)

這里我還是先以上篇文章講到的紅酒分類為例子,待會(huì)還會(huì)有其他實(shí)例。

4.1 導(dǎo)入模塊

import numpy as npimport pandas as pdimport matplotlib.pyplot as plt# 解決坐標(biāo)軸刻度負(fù)號(hào)亂碼plt.rcParams["axes.unicode_minus"] = False# 解決中文亂碼問(wèn)題plt.rcParams["font.sans-serif"] = ["Simhei"]plt.style.use("ggplot")# plt.figure(figsize=(2,3),dpi=720)

4.2 構(gòu)建已經(jīng)分類好的原始數(shù)據(jù)集

首先隨機(jī)設(shè)置十個(gè)樣本點(diǎn)表示十杯酒,這里取了部分樣本點(diǎn)。

為了方便驗(yàn)證,這里使用 Python 的字典 dict 構(gòu)建數(shù)據(jù)集,然后再將其轉(zhuǎn)化成 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]) #把標(biāo)簽(酒的類別)放在Y

我們先來(lái)畫一下圖。

#探索數(shù)據(jù),假如我們給出新數(shù)據(jù)[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="赤霞珠") #畫出標(biāo)簽y為1 的、關(guān)于“赤霞珠”的散點(diǎn) plt.scatter(X[y==0,0], X[y==0,1], color="purple", label="黑皮諾") #畫出標(biāo)簽y為0 的、關(guān)于“黑皮諾”的散點(diǎn) plt.scatter(new_data[0],new_data[1], color="yellow") # 新數(shù)據(jù)點(diǎn) new_data plt.xlabel("酒精濃度") plt.ylabel("顏色深度") plt.legend(loc="lower right") plt.savefig("葡萄酒樣本.png")


講道理,你應(yīng)該一下就能看出來(lái)了。不過(guò),如果是計(jì)算機(jī),會(huì)這么分辨呢?

4.3 計(jì)算已知類別數(shù)據(jù)集中的點(diǎn)與當(dāng)前點(diǎn)之間的距離。

我們使用歐式距離公式,計(jì)算新數(shù)據(jù)點(diǎn) new_data 與現(xiàn)存的 X 數(shù)據(jù)集每一個(gè)點(diǎn)的距離:

from math import sqrt distance = [sqrt(np.sum((x-new_data)**2)) for x in X ] distance


那現(xiàn)在,我們就已經(jīng)得到黃點(diǎn)距離其它每個(gè)點(diǎn)的距離啦。

4.4 將距離升序排列,然后選取距離最小的k個(gè)點(diǎn)。

sort_dist = np.argsort(distance) # 這里是用到了argsort方法,可以返回?cái)?shù)據(jù)對(duì)應(yīng)的下標(biāo),如果直接用sort方法的話是返回打亂的數(shù)據(jù),我們也不好區(qū)分對(duì)應(yīng)是什么類別。sort_dist

array([6, 7, 1, 4, 5, 9, 2, 8, 3, 0], dtype=int64)

6、7、4為最近的3個(gè)“數(shù)據(jù)點(diǎn)”的索引值,那么這些索引值對(duì)應(yīng)的原數(shù)據(jù)的標(biāo)簽是什么?

k = 3 topK = [y[i] for i in sort_dist[:k]] topK

[1,1,0]

這個(gè)時(shí)候我們就得到了離黃點(diǎn)最近的三個(gè)點(diǎn)對(duì)應(yīng)的類別啦。

4.5 確定前k個(gè)點(diǎn)所在類別的計(jì)數(shù)。

# 在numpy中有mean、median方法可以求平均數(shù)和中位數(shù),不過(guò)沒(méi)有方法直接求眾數(shù)。pd.Series(topK).value_counts().index[0]

1

所以當(dāng)我們的k取3時(shí),分類結(jié)果為1,也就是赤霞珠。大家看一下是不是跟我們?nèi)四X分辨的結(jié)果是一樣的呢?

4.6 封裝成函數(shù)

那為了后續(xù)更好的操作,我們可以將上述過(guò)程封裝成一個(gè)函數(shù)。

def KNN(new_data,dataSet,k): 	""" 	函數(shù)功能:KNN分類器 	參數(shù)說(shuō)明: 	new_data: 需要預(yù)測(cè)分類的數(shù)據(jù)集 	dataSet: 已知分類標(biāo)簽的數(shù)據(jù)集 	k: k-近鄰算法參數(shù),選擇距離最小的k個(gè)點(diǎn) 	return: 	result: 分類結(jié)果 	""" 	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           
               
                                           
                       
                 

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/119682.html

相關(guān)文章

  • 開始學(xué)習(xí)機(jī)器學(xué)習(xí)前你必須要了解知識(shí)有哪些?機(jī)器學(xué)習(xí)系列入門

    摘要:進(jìn)入當(dāng)前程序的學(xué)習(xí)系統(tǒng)的所有樣本稱作輸入,并組成輸入空間。結(jié)束語(yǔ)注意這篇文章僅僅是我接下來(lái)的機(jī)器學(xué)習(xí)系列的第一篇,后續(xù)還會(huì)有更多的內(nèi)容。 往期回顧:統(tǒng)計(jì)學(xué)習(xí)方法第...

    leoperfect 評(píng)論0 收藏0
  • Python從入門到實(shí)戰(zhàn)】一文章帶你搞懂Python類~

    摘要:小栗子對(duì)于可樂(lè)來(lái)講,只要是同一個(gè)品牌的可樂(lè),他們就有著同樣的成分,這被稱之為配方。小栗子對(duì)于可樂(lè)來(lái)說(shuō),按照配方把可樂(lè)生產(chǎn)出來(lái)的過(guò)程就是實(shí)例化的過(guò)程。小栗子類的屬性與正常的變量并無(wú)區(qū)別。 前言 我是栗子,帶大家從零開始學(xué)習(xí)Python,希望每篇文章都能讓你收獲滿滿! 今天我們要說(shuō)的是面向?qū)ο蟮?..

    cloud 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<