天下武功牡昆,唯快不破。今天就正式講解如何通過(guò)《sklearn小抄》武林秘籍摊欠,成為一代宗師調(diào)包俠丢烘。欲練此功,必先自宮些椒;就算自宮播瞳,未必成功;若不自宮免糕,也能成功赢乓。傳說(shuō)江湖(機(jī)器學(xué)習(xí)領(lǐng)域)有兩大派別:一是學(xué)術(shù)派,該派資歷高石窑,家境好牌芋,多為名門(mén)世家(學(xué)歷高,數(shù)學(xué)好)松逊,重基礎(chǔ)(數(shù)學(xué)推導(dǎo)和理論知識(shí))躺屁;一是實(shí)踐派,以找人切磋為主(實(shí)踐為主)经宏,多在切磋中提升能力犀暑⊙被鳎《機(jī)器學(xué)習(xí)實(shí)戰(zhàn)》系列為學(xué)術(shù)派,《sklearn調(diào)包俠》系列為實(shí)踐派耐亏,該系列會(huì)簡(jiǎn)單講解原理徊都,多引用于《機(jī)器學(xué)習(xí)實(shí)戰(zhàn)》系列的算法講解(必要的內(nèi)力),然后在實(shí)操中完成各機(jī)器學(xué)習(xí)算法广辰。
tips:在本篇中會(huì)按小抄詳細(xì)過(guò)一遍暇矫,之后就可能會(huì)隨意一些。
KNN算法原理
計(jì)算測(cè)試樣本與每個(gè)訓(xùn)練樣本的距離择吊,取前k個(gè)距離最小的訓(xùn)練樣本李根,最后選擇這k個(gè)樣本中出現(xiàn)最多的分類,作為測(cè)試樣本的分類干发。
如圖所示朱巨,綠色的為測(cè)試樣本史翘,當(dāng)k取3時(shí)枉长,該樣本就屬于紅色類;當(dāng)k取5時(shí)琼讽,就屬于藍(lán)色類了必峰。所以k值的選擇很大程度影響著該算法的結(jié)果,通常k的取值不大于20钻蹬。
實(shí)戰(zhàn)——糖尿病預(yù)測(cè)
數(shù)據(jù)導(dǎo)入
本數(shù)據(jù)可在kaggle中進(jìn)行下載吼蚁,讀者可以去我的百度云鏈接進(jìn)行下載。
(鏈接:https://pan.baidu.com/s/1gqaGuQ9kWZFfc-SXbYFDkA 密碼:lxfx)
該數(shù)據(jù)為csv格式文件问欠,我們通過(guò)pandas讀入:
import numpy as np
import pandas as pd
data = pd.read_csv('data/pima-indians-diabetes/diabetes.csv')
data.head()
我們簡(jiǎn)單看下各字段的意思:
- Pregnancies:懷孕的次數(shù)
- Glucose:血漿葡萄糖濃度
- BloodPressure:舒張壓
- SkinThickness:肱三頭肌皮膚皺皺厚度
- Insulin: 胰島素
- BMI:身體質(zhì)量指數(shù)
- Dia....:糖尿病血統(tǒng)指數(shù)
- Age:年齡
- Outcone:是否糖尿病肝匆,1為是
我們把數(shù)據(jù)劃分為特征和label,前8列為特征顺献,最后一列為label旗国。
X = data.iloc[:, 0:8]
Y = data.iloc[:, 8]
切分?jǐn)?shù)據(jù)集
在模型訓(xùn)練前,需要將數(shù)據(jù)集切分為訓(xùn)練集和測(cè)試集(73開(kāi)或者其它)注整,這里選擇82開(kāi)能曾,使用sklearn中model_selection模塊中的train_test_split方法。
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=22)
這里的test_size為測(cè)試集的比例肿轨,random_state為隨機(jī)種子寿冕,這里可設(shè)置任意數(shù)字,保證下次運(yùn)行同樣可以選擇出對(duì)應(yīng)的訓(xùn)練集和測(cè)試集椒袍。
數(shù)據(jù)預(yù)處理
這里沒(méi)有對(duì)數(shù)據(jù)進(jìn)行預(yù)處理驼唱。
模型訓(xùn)練與評(píng)估
KNN算法使用sklearn.neighbors模塊中的KNeighborsClassifier方法。常用的參數(shù)如下:
- n_neighbors驹暑,整數(shù)曙蒸,也就是k值捌治。
- weights,默認(rèn)為‘uniform’纽窟;這個(gè)參數(shù)可以針對(duì)不同的鄰居指定不同的權(quán)重肖油,也就是說(shuō),越近可以權(quán)重越高臂港,默認(rèn)是一樣的權(quán)重森枪。‘distance’可以設(shè)置不同權(quán)重审孽。
在sklearn.neighbors還有一個(gè)變種KNN算法县袱,為RadiusNeighborsClassifier算法,可以使用一定半徑的點(diǎn)來(lái)取代距離最近的k個(gè)點(diǎn)佑力。
接下來(lái)式散,我們通過(guò)設(shè)置weight和RadiusNeighborsClassifier,對(duì)算法進(jìn)行比較打颤。
from sklearn.neighbors import KNeighborsClassifier,RadiusNeighborsClassifier
model1 = KNeighborsClassifier(n_neighbors=2)
model1.fit(X_train, Y_train)
score1 = model1.score(X_test, Y_test)
model2 = KNeighborsClassifier(n_neighbors=2, weights='distance')
model2.fit(X_train, Y_train)
score2 = model2.score(X_test, Y_test)
model3 = RadiusNeighborsClassifier(n_neighbors=2, radius=500.0)
model3.fit(X_train, Y_train)
score3 = model3.score(X_test, Y_test)
print(score1, score2, score3)
#result
#0.714285714286 0.701298701299 0.649350649351
可以看出默認(rèn)情況的KNN算法結(jié)果最好暴拄。
交叉驗(yàn)證
通過(guò)上述結(jié)果可以看出:默認(rèn)情況的KNN算法結(jié)果最好。這個(gè)判斷準(zhǔn)確么编饺?答案是不準(zhǔn)確乖篷,因?yàn)槲覀冎皇请S機(jī)分配了一次訓(xùn)練和測(cè)試樣本,可能下次隨機(jī)選擇訓(xùn)練和測(cè)試樣本透且,結(jié)果就不一樣了撕蔼。這里的方法為:交叉驗(yàn)證瑰妄。我們把數(shù)據(jù)集劃分為10折吆视,每次用9折訓(xùn)練,1折測(cè)試澳盐,就會(huì)有10次結(jié)果锅论,求十次的平均即可讼溺。當(dāng)然,可以設(shè)置cv的值棍厌,選擇不同的折數(shù)肾胯。
from sklearn.model_selection import cross_val_score
result1 = cross_val_score(model1, X, Y, cv=10)
result2 = cross_val_score(model2, X, Y, cv=10)
result3 = cross_val_score(model3, X, Y, cv=10)
print(result1.mean(), result2.mean(), result3.mean())
# result
# 0.712235133288 0.67966507177 0.64976076555
可以看出,還是默認(rèn)情況的KNN算法結(jié)果最好耘纱。
模型調(diào)優(yōu)
無(wú)模型調(diào)優(yōu)敬肚。