99999久久久久久亚洲,欧美人与禽猛交狂配,高清日韩av在线影院,一个人在线高清免费观看,啦啦啦在线视频免费观看www

熱線電話:13121318867

登錄
首頁(yè)精彩閱讀機(jī)器學(xué)習(xí)的敲門(mén)磚:kNN算法(中)
機(jī)器學(xué)習(xí)的敲門(mén)磚:kNN算法(中)
2019-10-17
收藏
<a href='/map/jiqixuexi/' style='color:#000;font-size:inherit;'>機(jī)器學(xué)習(xí)</a>的敲門(mén)磚:kNN算法(中)

作者 | Japson

來(lái)源 | 木東居士

0x01 前言

在《機(jī)器學(xué)習(xí)的敲門(mén)磚:kNN算法(上)》中,我們了解了非常適合入門(mén)機(jī)器學(xué)習(xí)的算法:k近鄰算法。

我們學(xué)習(xí)了kNN算法的流程,并且在jupyter notebook上手動(dòng)實(shí)現(xiàn)了代碼,并且在外部也進(jìn)行了封裝。最后我們學(xué)習(xí)了sklearn中的kNN算法。

在品嘗到“實(shí)踐”的勝利果實(shí)后,我們不僅有一個(gè)疑問(wèn):

思想如此樸素的kNN算法,它的效果怎樣樣?預(yù)測(cè)準(zhǔn)確率高不高?在機(jī)器學(xué)習(xí)中如何評(píng)價(jià)一個(gè)算法的好壞?我們?cè)?a href='/map/jiqixuexi/' style='color:#000;font-size:inherit;'>機(jī)器學(xué)習(xí)過(guò)程中還有需要注意那些其他的問(wèn)題呢?

在這篇文章中,我們使用訓(xùn)練數(shù)據(jù)集和測(cè)試數(shù)據(jù)集來(lái)判斷模型的好壞,給出并實(shí)現(xiàn)accurcay這一分類(lèi)問(wèn)題常用指標(biāo)。最后我們?cè)偬綄こ瑓?shù)的選擇對(duì)模型的影響。


0x01 判斷模型好壞


1.1 訓(xùn)練數(shù)據(jù)集&測(cè)試數(shù)據(jù)集

我們已經(jīng)興致勃勃的訓(xùn)練好了一個(gè)模型了,問(wèn)題是:它能直接拿到生產(chǎn)環(huán)境正確使用么?

  • 我們現(xiàn)在只是能拿到一個(gè)預(yù)測(cè)結(jié)果,還不知道這個(gè)模型效果怎么樣?
  • 預(yù)測(cè)的結(jié)果準(zhǔn)不準(zhǔn)
  • 如果拿到真實(shí)環(huán)境,其實(shí)是沒(méi)有l(wèi)abel的,我們?cè)趺磳?duì)結(jié)果進(jìn)行驗(yàn)證呢?

實(shí)際上,從訓(xùn)練好模型到真實(shí)使用,還差著遠(yuǎn)呢。我們要做的第一步就是:

將原始數(shù)據(jù)中的一部分作為訓(xùn)練數(shù)據(jù)、另一部分作為測(cè)試數(shù)據(jù)。使用訓(xùn)練數(shù)據(jù)訓(xùn)練模型,再用測(cè)試數(shù)據(jù)看好壞。即通過(guò)測(cè)試數(shù)據(jù)判斷模型好壞,然后再不斷對(duì)模型進(jìn)行修改。


1.2 鳶尾花train_test

鳶尾花數(shù)據(jù)集是UCI數(shù)據(jù)庫(kù)中常用數(shù)據(jù)集。我們可以直接加載數(shù)據(jù)集,并嘗試對(duì)數(shù)據(jù)進(jìn)行一定探索:

import numpy as npfrom sklearn import datasetsimport matplotlib.pyplot as plt
iris = datasets.load_iris()
X = iris.data
y = iris.target
X.shape
輸出:(150, 4)
X.shape
輸出:(150,)

我們下面進(jìn)行訓(xùn)練數(shù)據(jù)集、測(cè)試數(shù)據(jù)集的拆分工作(train_test_split)。

一般情況下我們按照0.8:0.2的比例進(jìn)行拆分,但是有時(shí)候我們不能簡(jiǎn)單地把前n個(gè)數(shù)據(jù)作為訓(xùn)練數(shù)據(jù)集,后n個(gè)作為測(cè)試數(shù)據(jù)集。

比如下面這個(gè),是有順序的。

<a href='/map/jiqixuexi/' style='color:#000;font-size:inherit;'>機(jī)器學(xué)習(xí)</a>的敲門(mén)磚:kNN算法(中)

為了解決這個(gè)問(wèn)題,我們可以將數(shù)據(jù)集打亂,做一個(gè)shuffle操作。但是本數(shù)據(jù)集的特征和標(biāo)簽是分開(kāi)的,也就是說(shuō)我們分別亂序后,原來(lái)的對(duì)應(yīng)關(guān)系就不存在了。有兩種方法解決這一問(wèn)題:

  • 將X和y合并為同一個(gè)矩陣,然后對(duì)矩陣進(jìn)行shuffle,之后再分解
  • 對(duì)y的索引進(jìn)行亂序,根據(jù)索引確定與X的對(duì)應(yīng)關(guān)系,最后再通過(guò)亂序的索引進(jìn)行賦值


第一種方法

首先看第一種方法:

# 方法1# 使用concatenate函數(shù)進(jìn)行拼接,因?yàn)閭魅氲木仃嚤仨毦哂邢嗤男螤?。因此需要?duì)label進(jìn)行reshape操作,reshape(-1,1)表示行數(shù)自動(dòng)計(jì)算,1列。axis=1表示縱向拼接。tempConcat = np.concatenate((X, y.reshape(-1,1)), axis=1)# 拼接好后,直接進(jìn)行亂序操作np.random.shuffle(tempConcat)# 再將shuffle后的數(shù)組使用split方法拆分shuffle_X,shuffle_y = np.split(tempConcat, [4], axis=1)# 設(shè)置劃分的比例test_ratio = 0.2test_size = int(len(X) * test_ratio)
X_train = shuffle_X[test_size:]
y_train = shuffle_y[test_size:]
X_test = shuffle_X[:test_size]
y_test = shuffle_y[:test_size]
print(X_train.shape)
print(X_test.shape)
print(y_train.shape)
print(y_test.shape)
輸出:(120, 4)
(30, 4)
(120, 1)
(30, 1)


第二種方法

# 方法2# 將x長(zhǎng)度這么多的數(shù),返回一個(gè)新的打亂順序的數(shù)組,注意,數(shù)組中的元素不是原來(lái)的數(shù)據(jù),而是混亂的索引shuffle_index = np.random.permutation(len(X))# 指定測(cè)試數(shù)據(jù)的比例test_ratio = 0.2test_size = int(len(X) * test_ratio)
test_index = shuffle_index[:test_size]
train_index = shuffle_index[test_size:]
X_train = X[train_index]
X_test = X[test_index]
y_train = y[train_index]
y_test = y[test_index]
print(X_train.shape)
print(X_test.shape)
print(y_train.shape)
print(y_test.shape)
輸出:(120, 4)
(30, 4)
(120,)
(30,)
<a href='/map/jiqixuexi/' style='color:#000;font-size:inherit;'>機(jī)器學(xué)習(xí)</a>的敲門(mén)磚:kNN算法(中)


1.3 編寫(xiě)自己的train_test_split

下面我們將編寫(xiě)自己的train_test_split,并封裝成方法。


編寫(xiě)

還記得我們的github上的工程嗎?https://github.com/japsonzbz/ML_Algorithms

編寫(xiě)一個(gè)自己的train_test_split方法。這個(gè)方法可以放到model——selection.py下。因?yàn)榉指钣?xùn)練集和測(cè)試集合,可以幫助我們測(cè)試機(jī)器學(xué)習(xí)性能,能夠幫助我們更好地選擇模型。

import numpy as npdef train_test_split(X, y, test_ratio=0.2, seed=None):
 """將矩陣X和標(biāo)簽y按照test_ration分割成X_train, X_test, y_train, y_test"""
 assert X.shape[0] == y.shape[0], \ "the size of X must be equal to the size of y"
 assert 0.0 <= test_ratio <= 1.0, \ "test_train must be valid"
 if seed: # 是否使用隨機(jī)種子,使隨機(jī)結(jié)果相同,方便debug
 np.random.seed(seed) # permutation(n) 可直接生成一個(gè)隨機(jī)排列的數(shù)組,含有n個(gè)元素
 shuffle_index = np.random.permutation(len(X))
 test_size = int(len(X) * test_ratio)
 test_index = shuffle_index[:test_size]
 train_index = shuffle_index[test_size:]
 X_train = X[train_index]
 X_test = X[test_index]
 y_train = y[train_index]
 y_test = y[test_index] return X_train, X_test, y_train, y_test


調(diào)用

from myAlgorithm.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X, y)
print(X_train.shape)
print(X_test.shape)
print(y_train.shape)
print(y_test.shape)
輸出:(120, 4)
(30, 4)
(120,)
(30,)

再得到分割好的訓(xùn)練數(shù)據(jù)集和測(cè)試數(shù)據(jù)集以后,下面將其應(yīng)用于kNN算法中。

我們可以簡(jiǎn)單驗(yàn)證一下,X_train, y_train通過(guò)fit傳入算法,然后對(duì)X_test做預(yù)測(cè),得到y(tǒng)_predict。

然后我們可以直觀地把y_predict和實(shí)際的結(jié)果y_test進(jìn)行一個(gè)比較,看有多少個(gè)元素一樣。當(dāng)然我們也可以自己計(jì)算一下正確率

from myAlgorithm.kNN import kNNClassifier
my_kNNClassifier = kNNClassifier(k=3)
my_kNNClassifier.fit(X_train, y_train)
y_predict = my_kNNClassifier.predict(X_test)
y_predict
y_test# 兩個(gè)向量的比較,返回一個(gè)布爾型向量,對(duì)這個(gè)布爾向量(faluse=1,true=0)sum,sum(y_predict == y_test)29sum(y_predict == y_test)/len(y_test)0.96666666666667


1.4 sklearn中的train_test_split

我們自己寫(xiě)的train_test_split其實(shí)也是在模仿sklearn風(fēng)格,更多的時(shí)候我們可以直接調(diào)用。

from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=666)
print(X_train.shape)
print(X_test.shape)
print(y_train.shape)
print(y_test.shape)
輸出:(112, 4)
(38, 4)
(112,)
(38,)
<a href='/map/jiqixuexi/' style='color:#000;font-size:inherit;'>機(jī)器學(xué)習(xí)</a>的敲門(mén)磚:kNN算法(中)


0x02 分類(lèi)準(zhǔn)確度accuracy

在劃分出測(cè)試數(shù)據(jù)集后,我們就可以驗(yàn)證其模型準(zhǔn)確率了。在這了引出一個(gè)非常簡(jiǎn)單且常用的概念:accuracy(分類(lèi)準(zhǔn)確度)

accuracy_score:函數(shù)計(jì)算分類(lèi)準(zhǔn)確率,返回被正確分類(lèi)的樣本比例(default)或者是數(shù)量(normalize=False)

在多標(biāo)簽分類(lèi)問(wèn)題中,該函數(shù)返回子集的準(zhǔn)確率,對(duì)于一個(gè)給定的多標(biāo)簽樣本,如果預(yù)測(cè)得到的標(biāo)簽集合與該樣本真正的標(biāo)簽集合嚴(yán)格吻合,則subset accuracy =1.0否則是0.0

因accuracy定義清洗、計(jì)算方法簡(jiǎn)單,因此經(jīng)常被使用。但是它在某些情況下并不一定是評(píng)估模型的最佳工具。精度(查準(zhǔn)率)和召回率(查全率)等指標(biāo)對(duì)衡量機(jī)器學(xué)習(xí)的模型性能在某些場(chǎng)合下要比accuracy更好。

當(dāng)然這些指標(biāo)在后續(xù)都會(huì)介紹。在這里我們就使用分類(lèi)精準(zhǔn)度,并將其作用于一個(gè)新的手寫(xiě)數(shù)字識(shí)別分類(lèi)算法上。


2.1 數(shù)據(jù)探索

import numpy as npimport matplotlibimport matplotlib.pyplot as pltfrom sklearn import datasetsfrom sklearn.model_selection import train_test_splitfrom sklearn.neighbors import KNeighborsClassifier# 手寫(xiě)數(shù)字?jǐn)?shù)據(jù)集,封裝好的對(duì)象,可以理解為一個(gè)字段digits = datasets.load_digits()# 可以使用keys()方法來(lái)看一下數(shù)據(jù)集的詳情digits.keys()
輸出:dict_keys(['data', 'target', 'target_names', 'images', 'DESCR'])

我們可以看一下sklearn.datasets提供的數(shù)據(jù)描述:

# 5620張圖片,每張圖片有64個(gè)像素點(diǎn)即特征(8*8整數(shù)像素圖像),每個(gè)特征的取值范圍是1~16(sklearn中的不全),對(duì)應(yīng)的分類(lèi)結(jié)果是10個(gè)數(shù)字print(digits.DESCR)

下面我們根據(jù)datasets提供的方法,進(jìn)行簡(jiǎn)單的數(shù)據(jù)探索。

# 特征的shapeX = digits.data
X.shape
(1797, 64)# 標(biāo)簽的shapey = digits.target
y.shape
(1797, )# 標(biāo)簽分類(lèi)digits.target_names
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])# 去除某一個(gè)具體的數(shù)據(jù),查看其特征以及標(biāo)簽信息some_digit = X[666]
some_digit
array([ 0., 0., 5., 15., 14., 3., 0., 0., 0., 0., 13., 15., 9.,15., 2., 0., 0., 4., 16., 12., 0., 10., 6., 0., 0., 8.,16., 9., 0., 8., 10., 0., 0., 7., 15., 5., 0., 12., 11.,0., 0., 7., 13., 0., 5., 16., 6., 0., 0., 0., 16., 12.,15., 13., 1., 0., 0., 0., 6., 16., 12., 2., 0., 0.])
y[666]0# 也可以這條數(shù)據(jù)進(jìn)行可視化some_digmit_image = some_digit.reshape(8, 8)
plt.imshow(some_digmit_image, cmap = matplotlib.cm.binary)
plt.show()
<a href='/map/jiqixuexi/' style='color:#000;font-size:inherit;'>機(jī)器學(xué)習(xí)</a>的敲門(mén)磚:kNN算法(中)


2.2 自己實(shí)現(xiàn)分類(lèi)準(zhǔn)確度

在分類(lèi)任務(wù)結(jié)束后,我們就可以計(jì)算分類(lèi)算法的準(zhǔn)確率。其邏輯如下:

X_train, X_test, y_train, y_test = train_test_split(X, y)
knn_clf = KNeighborsClassifier(n_neighbors=3)
knn_clf.fit(X_train, y_train)
y_predict = knn_clf.predict(X_test)# 比對(duì)y_predict和y_test結(jié)果是否一致sum(y_predict == y_test) / len(y_test)0.9955555555555555

下面我們?cè)谖覀冏约旱墓こ涛募刑砑右粋€(gè)metrics.py,用來(lái)度量性能的各種指標(biāo)。

import numpy as npfrom math import sqrtdef accuracy_score(y_true, y_predict):
 """計(jì)算y_true和y_predict之間的準(zhǔn)確率"""
 assert y_true.shape[0] != y_predict.shape[0], \ "the size of y_true must be equal to the size of y_predict"
 return sum(y_true == y_predict) / len(y_true)

這樣以后就不用一遍遍地寫(xiě)邏輯了,直接調(diào)用我們寫(xiě)好的封裝函數(shù)。我們?cè)僬{(diào)用一下:

from myAlgorithm.metrics import accuracy_score
accuracy_score(y_test, y_predict)

但在實(shí)際情況下,我們有時(shí)可能還有這樣的需求:用classifier將我們的預(yù)測(cè)值y_predicr預(yù)測(cè)出來(lái)了,再去看和真值的比例。但是有時(shí)候我們對(duì)預(yù)測(cè)值y_predicr是多少不感興趣,我們只對(duì)模型的準(zhǔn)確率感興趣。

可以在kNN算法模型中進(jìn)一步封裝一個(gè)函數(shù)(完整代碼見(jiàn)https://github.com/japsonzbz/ML_Algorithms)

def score(self, X_test, y_test):
 """根據(jù)X_test進(jìn)行預(yù)測(cè), 給出預(yù)測(cè)的真值y_test,計(jì)算預(yù)測(cè)算法的準(zhǔn)確度"""
 y_predict = self.predict(X_test) return accuracy_score(y_test, y_predict)

然后我們就可以直接運(yùn)行著這命令,直接測(cè)出模型分類(lèi)準(zhǔn)確度:

my_knn_clf.score(X_test, y_test)

<a href='/map/jiqixuexi/' style='color:#000;font-size:inherit;'>機(jī)器學(xué)習(xí)</a>的敲門(mén)磚:kNN算法(中)


2.3 sklearn中的準(zhǔn)確度

更多的時(shí)候,我們還是使用sklearn中封裝好的方法。我們自己實(shí)現(xiàn)一遍,其實(shí)是簡(jiǎn)化版的,只是幫助我們更好地了解其底層原理。

from sklearn.model_selection import train_test_splitfrom sklearn.metrics import accuracy_score
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=666)
knn_clf = KNeighborsClassifier(n_neighbors=3)
knn_clf.fit(X_train, y_train)
y_predict = knn_clf.predict(X_test)
accuracy_score(y_test, y_predict)
輸出:0.9888888888888889# 不看y_predictknn_clf.score(X_test,y_test)
輸出:0.9888888888888889


0x03 超參數(shù)


3.1 超參數(shù)簡(jiǎn)介

之前我們都是為knn算法傳一個(gè)默認(rèn)的k值。在具體使用時(shí)應(yīng)該傳遞什么值合適呢?

這就涉及了機(jī)器學(xué)習(xí)領(lǐng)域中的一個(gè)重要問(wèn)題:超參數(shù)。所謂超參數(shù),就是在機(jī)器學(xué)習(xí)算法模型執(zhí)行之前需要指定的參數(shù)。(調(diào)參調(diào)的就是超參數(shù)) 如kNN算法中的k。

與之相對(duì)的概念是模型參數(shù),即算法過(guò)程中學(xué)習(xí)的屬于這個(gè)模型的參數(shù)(kNN中沒(méi)有模型參數(shù),回歸算法有很多模型參數(shù))

如何選擇最佳的超參數(shù),這是機(jī)器學(xué)習(xí)中的一個(gè)永恒的問(wèn)題。在實(shí)際業(yè)務(wù)場(chǎng)景中,調(diào)參的難度大很多,一般我們會(huì)業(yè)務(wù)領(lǐng)域知識(shí)、經(jīng)驗(yàn)數(shù)值、實(shí)驗(yàn)搜索等方面獲得最佳參數(shù)。


3.2 尋找好的k

針對(duì)于上一小節(jié)的手寫(xiě)數(shù)字識(shí)別分類(lèi)代碼,嘗試尋找最好的k值。邏輯非常簡(jiǎn)單,就是設(shè)定一個(gè)初始化的分?jǐn)?shù),然后循環(huán)更新k值,找到最好的score

# 指定最佳值的分?jǐn)?shù),初始化為0.0;設(shè)置最佳值k,初始值為-1best_score = 0.0best_k = -1for k in range(1, 11): # 暫且設(shè)定到1~11的范圍內(nèi)
 knn_clf = KNeighborsClassifier(n_neighbors=k)
 knn_clf.fit(X_train, y_train)
 score = knn_clf.score(X_test, y_test) if score > best_score:
 best_k = k
 best_score = score
print("best_k = ", best_k)
print("best_score = ", best_score)
輸出:best_k = 4best_score = 0.9916666666666667

可以看到,最好的k值是4,在我們?cè)O(shè)定的k的取值范圍中間。需要注意的是,如果我們得到的值正好在邊界上,我們需要稍微擴(kuò)展一下取值范圍。因?yàn)槁?,你懂的?/span>


3.2 另一個(gè)超參數(shù):權(quán)重

在回顧kNN算法思想時(shí),我們應(yīng)該還記得,對(duì)于簡(jiǎn)單的kNN算法,只需要考慮最近的n個(gè)數(shù)據(jù)是什么即可。但是如果我們考慮距離呢?

如果我們認(rèn)為,距離樣本數(shù)據(jù)點(diǎn)最近的節(jié)點(diǎn),對(duì)其影響最大,那么我們使用距離的倒數(shù)作為權(quán)重。假設(shè)距離樣本點(diǎn)最近的三個(gè)節(jié)點(diǎn)分別是紅色、藍(lán)色、藍(lán)色,距離分別是1、4、3。那么普通的k近鄰算法:藍(lán)色獲勝??紤]權(quán)重(距離的倒數(shù)):紅色:1,藍(lán)色:1/3 + 1/4 = 7/12,紅色勝。

在 sklearn.neighbors 的構(gòu)造函數(shù) KNeighborsClassifier 中有一個(gè)參數(shù):weights,默認(rèn)是uniform即不考慮距離,也可以寫(xiě)distance來(lái)考慮距離權(quán)重(默認(rèn)是歐拉距離,如果要是曼哈頓距離,則可以寫(xiě)參數(shù)p(明可夫斯基距離的參數(shù)),這個(gè)也是超參數(shù))

因?yàn)橛袃蓚€(gè)超參數(shù),因此使用雙重循環(huán),去查找最合適的兩個(gè)參數(shù),并打印。

# 兩種方式進(jìn)行比較best_method = ""best_score = 0.0best_k = -1for method in ["uniform","distance"]: for k in range(1, 11):
 knn_clf = KNeighborsClassifier(n_neighbors=k, weights=method, p=2)
 knn_clf.fit(X_train, y_train)
 score = knn_clf.score(X_test, y_test) if score > best_score:
 best_k = k
 best_score = score
 best_method = method
print("best_method = ", method)
print("best_k = ", best_k)
print("best_score = ", best_score)
輸出:best_method = distance
best_k = 4best_score = 0.9916666666666667

<a href='/map/jiqixuexi/' style='color:#000;font-size:inherit;'>機(jī)器學(xué)習(xí)</a>的敲門(mén)磚:kNN算法(中)


3.3 超參數(shù)網(wǎng)格搜索

在具體的超參數(shù)搜索過(guò)程中會(huì)需要很多問(wèn)題,超參數(shù)過(guò)多、超參數(shù)之間相互依賴(lài)等等。如何一次性地把我們想要得到最好的超參數(shù)組合列出來(lái)。sklearn中專(zhuān)門(mén)封裝了一個(gè)超參數(shù)網(wǎng)格搜索方法Grid Serach。

在進(jìn)行網(wǎng)格搜索之前,首先需要定義一個(gè)搜索的參數(shù)param_search。是一個(gè)數(shù)組,數(shù)組中的每個(gè)元素是個(gè)字典,字典中的是對(duì)應(yīng)的一組網(wǎng)格搜索,每一組網(wǎng)格搜索是這一組網(wǎng)格搜索每個(gè)參數(shù)的取值范圍。鍵是參數(shù)的名稱(chēng),值是鍵所對(duì)應(yīng)的參數(shù)的列表。

param_search = [
 { "weights":["uniform"], "n_neighbors":[i for i in range(1,11)]
 },
 { "weights":["distance"], "n_neighbors":[i for i in range(1,11)], "p":[i for i in range(1,6)]
 }
]

可以看到,當(dāng)weights = uniform即不使用距離時(shí),我們只搜索超參數(shù)k,當(dāng)weights = distance即使用距離時(shí),需要看超參數(shù)p使用那個(gè)距離公式。下面創(chuàng)建要進(jìn)行網(wǎng)格搜索所對(duì)應(yīng)的分類(lèi)算法并調(diào)用剛哥搜索:

knn_clf = KNeighborsClassifier()# 調(diào)用網(wǎng)格搜索方法from sklearn.model_selection import GridSearchCV# 定義網(wǎng)格搜索的對(duì)象grid_search,其構(gòu)造函數(shù)的第一個(gè)參數(shù)表示對(duì)哪一個(gè)分類(lèi)器進(jìn)行算法搜索,第二個(gè)參數(shù)表示網(wǎng)格搜索相應(yīng)的參數(shù)grid_search = GridSearchCV(knn_clf, param_search)

下面就是針對(duì)X_train, y_train,使用grid_search在param_search列表中尋找最佳超參數(shù)組:

%%time
grid_search.fit(X_train, y_train)
輸出:CPU times: user 2min 21s, sys: 628 ms, total: 2min 21s
Wall time: 2min 23s
GridSearchCV(cv=None, error_score='raise',
 estimator=KNeighborsClassifier(algorithm='auto', leaf_size=30, metric='minkowski',
 metric_params=None, n_jobs=1, n_neighbors=5, p=2,
 weights='uniform'),
 fit_params=None, iid=True, n_jobs=1,
 param_grid=[{'weights': ['uniform'], 'n_neighbors': [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]}, {'weights': ['distance'], 'n_neighbors': [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], 'p': [1, 2, 3, 4, 5]}],
 pre_dispatch='2*n_jobs', refit=True, return_train_score='warn',
 scoring=None, verbose=0)

可以使用網(wǎng)格搜索的評(píng)估函數(shù)來(lái)返回最佳分類(lèi)起所對(duì)應(yīng)的參數(shù)

# 返回的是網(wǎng)格搜索搜索到的最佳的分類(lèi)器對(duì)應(yīng)的參數(shù) grid_search.best_estimator_
輸出:KNeighborsClassifier(algorithm='auto', leaf_size=30, metric='minkowski',
 metric_params=None, n_jobs=1, n_neighbors=3, p=3,
 weights='distance')

也可以查看最佳參數(shù)的分類(lèi)器的準(zhǔn)確度。

我們會(huì)注意到,best_estimator_和best_score_參數(shù)后面有一個(gè)_。這是一種常見(jiàn)的語(yǔ)法規(guī)范,不是用戶(hù)傳入的參數(shù),而是根據(jù)用戶(hù)傳入的規(guī)則,自己計(jì)算出來(lái)的結(jié)果,參數(shù)名字后面接_

grid_search.best_score_
輸出:0.9853862212943633grid_search.beat_params_
輸出:{'n_neighbors':3, 'p':3, 'weights':'distance'}
knn_clf = grid_search.beat_estimator_
knn_clf.score(X_test, y_test)
輸出:0.9833333333328


0xFF 總結(jié)

在這篇文章中,我們借助kNN分類(lèi)算法,學(xué)習(xí)了如下知識(shí)點(diǎn):

  • 為了驗(yàn)證模型的好壞,將數(shù)據(jù)集劃分為訓(xùn)練數(shù)據(jù)集和測(cè)試數(shù)據(jù)集,這樣我們就可以對(duì)測(cè)試數(shù)據(jù)集的進(jìn)行預(yù)測(cè),然后使用label進(jìn)行驗(yàn)證。
  • 在我們得到了分類(lèi)結(jié)果之后,就可以使用分類(lèi)正確的數(shù)據(jù)點(diǎn)比上總的測(cè)試數(shù)據(jù)點(diǎn),這樣就可以計(jì)算出accuracy分類(lèi)精準(zhǔn)度。
  • 使用kNN算法對(duì)手寫(xiě)數(shù)字分類(lèi) 當(dāng)然,不同的評(píng)價(jià)指標(biāo)有不同的使用場(chǎng)景,不能亂用。
  • 最后我們以kNN算法為例,探究了不同的超參數(shù)對(duì)模型的影響,使用sklearn中封裝好的網(wǎng)格搜索算法,可以幫助我們進(jìn)行基礎(chǔ)調(diào)參。

現(xiàn)在我們通過(guò)kNN算法,已經(jīng)學(xué)習(xí)到不少機(jī)器學(xué)習(xí)相關(guān)的知識(shí)和概念了,在下一篇文章中,會(huì)一起學(xué)習(xí)機(jī)器學(xué)習(xí)中的另一個(gè)重要概念:數(shù)據(jù)歸一化。并且會(huì)對(duì)kNN的優(yōu)缺點(diǎn)以及相關(guān)的優(yōu)化算法做一個(gè)總結(jié)。

數(shù)據(jù)分析咨詢(xún)請(qǐng)掃描二維碼

若不方便掃碼,搜微信號(hào):CDAshujufenxi

數(shù)據(jù)分析師資訊
更多

OK
客服在線
立即咨詢(xún)
客服在線
立即咨詢(xún)
') } function initGt() { var handler = function (captchaObj) { captchaObj.appendTo('#captcha'); captchaObj.onReady(function () { $("#wait").hide(); }).onSuccess(function(){ $('.getcheckcode').removeClass('dis'); $('.getcheckcode').trigger('click'); }); window.captchaObj = captchaObj; }; $('#captcha').show(); $.ajax({ url: "/login/gtstart?t=" + (new Date()).getTime(), // 加隨機(jī)數(shù)防止緩存 type: "get", dataType: "json", success: function (data) { $('#text').hide(); $('#wait').show(); // 調(diào)用 initGeetest 進(jìn)行初始化 // 參數(shù)1:配置參數(shù) // 參數(shù)2:回調(diào),回調(diào)的第一個(gè)參數(shù)驗(yàn)證碼對(duì)象,之后可以使用它調(diào)用相應(yīng)的接口 initGeetest({ // 以下 4 個(gè)配置參數(shù)為必須,不能缺少 gt: data.gt, challenge: data.challenge, offline: !data.success, // 表示用戶(hù)后臺(tái)檢測(cè)極驗(yàn)服務(wù)器是否宕機(jī) new_captcha: data.new_captcha, // 用于宕機(jī)時(shí)表示是新驗(yàn)證碼的宕機(jī) product: "float", // 產(chǎn)品形式,包括:float,popup width: "280px", https: true // 更多配置參數(shù)說(shuō)明請(qǐng)參見(jiàn):http://docs.geetest.com/install/client/web-front/ }, handler); } }); } function codeCutdown() { if(_wait == 0){ //倒計(jì)時(shí)完成 $(".getcheckcode").removeClass('dis').html("重新獲取"); }else{ $(".getcheckcode").addClass('dis').html("重新獲取("+_wait+"s)"); _wait--; setTimeout(function () { codeCutdown(); },1000); } } function inputValidate(ele,telInput) { var oInput = ele; var inputVal = oInput.val(); var oType = ele.attr('data-type'); var oEtag = $('#etag').val(); var oErr = oInput.closest('.form_box').next('.err_txt'); var empTxt = '請(qǐng)輸入'+oInput.attr('placeholder')+'!'; var errTxt = '請(qǐng)輸入正確的'+oInput.attr('placeholder')+'!'; var pattern; if(inputVal==""){ if(!telInput){ errFun(oErr,empTxt); } return false; }else { switch (oType){ case 'login_mobile': pattern = /^1[3456789]\d{9}$/; if(inputVal.length==11) { $.ajax({ url: '/login/checkmobile', type: "post", dataType: "json", data: { mobile: inputVal, etag: oEtag, page_ur: window.location.href, page_referer: document.referrer }, success: function (data) { } }); } break; case 'login_yzm': pattern = /^\d{6}$/; break; } if(oType=='login_mobile'){ } if(!!validateFun(pattern,inputVal)){ errFun(oErr,'') if(telInput){ $('.getcheckcode').removeClass('dis'); } }else { if(!telInput) { errFun(oErr, errTxt); }else { $('.getcheckcode').addClass('dis'); } return false; } } return true; } function errFun(obj,msg) { obj.html(msg); if(msg==''){ $('.login_submit').removeClass('dis'); }else { $('.login_submit').addClass('dis'); } } function validateFun(pat,val) { return pat.test(val); }