准備
相關的庫
相關的庫包括:
- numpy
- pandas
- sklearn
帶入代碼如下:
import pandas as pd
import numpy as np
from sklearn.neighbors import KNeighborsClassfier as KNN
數據准備
數據是sklearn的乳腺癌數據。
from skleanr.datasets import load_breast_cancer
data=load_breast_caner()
data主要分為兩部分:data
和target
,把這兩部分,設置變量導入DataFrame
中可查看基本形狀。
X = data.data
y = data.target
sklearn
的數據其形式比較固定,data
的主要屬性有:
data
。數據,即變量的值,多行多列target
。目標,即因變量的值,一般是一行DESCR
。描述,可打印出,描述變量、目標features_names
。X的列名target_names
。Y的列名filename
。數據文件所在位置(一般在\lib\site-packages\sklearn\datasets\data\
目錄下)
分數據集和測試集:
from sklearn.model_selection import train_test_split
Xtrain,Xtest,Ytrain,Ytest=train_test_split(X, y, test_size=0.3)
注意:
- 0.3是指30%數據作為測試。每次運行不同,可通過
random_state
控制 - 返回的結果固定,不可錯
建立模型
clf = KNN(n_neighbors = 5)
clf=clf.fit(Xtrain,Ytrain)
clf就是訓練好的模型,可調用接口查看進行預測和評分。常用是predict
、score
和kneighbors
。三者分別用來預測、評分、求最近鄰。
在選擇訓練集和測試集的時候,可能會存在以下問題。
- 選擇測試集和訓練集每次都是不同的,因此每次模型的效果都不同。
- 選擇測試集和訓練集有時會極大影響模型。——特別是當數據是有順序的時候。
因此需要交叉驗證,找到最好的參數,再次訓練模型。
K折交叉驗證
K折交叉驗證的方法:
cvresult=CVS(clf,X,y,cv=5)
CVS的第一個參數是訓練過的模型,參數cv是折數。
cvresult.mean() # 取得均值
cvresult.var() #取得方差
可利用方差,繪制出學習曲線:
score =[]
var_=[]
krange=range(1,21)
for i in krange:
clf=KNN(n_neighbors=i)
cvresult=CVS(clf,X,y,cv=5)
score.append(cvresult.mean())
var_.append(cvresult.var())
plt.plot(krange,score,color='k')
plt.plot(krange,np.array(score)+np.array(var_)*2,c='red',linestyle='--')
plt.plot(krange,np.array(score)-np.array(var_)*2,c='red',linestyle='--')
bestindex=score.index(max(score))
print(bestindex+1)
print(score[bestindex])
常用交叉驗證
- K折。特別在回歸模型,若數據有順序,結果會很糟糕
- stratifiedKfold。常用
- shuffleSplit。常用
- GroupKFold。
但是如果把數據分為:訓練數據、測試數據。訓練數據又分出來一部分驗證數據,那么真正用於訓練的數據就更小了。
歸一化
KNN是距離類的模型,因此需要歸一化。也就是把數據減去最差值,處以極差:
\[x^*=\frac{x-min(x)}{max(x)-min(x)} \]
歸一化要分訓練集和測試集之后。(因為歸一化時候用到的極值,很可能就是測試集的數據,這樣事先就把數據透露給模型了)
Xtrain,Xtest,Ytrain,Ytest=train_test_split(X_,y,
test_size=0.3,
random_state=420)
MMS=nms().fit(Xtrain) #MMS中,有Xtrain的min,和極差
Xtest_=MMS.transform(Xtest)
Xtrain_=MMS.transform(Xtrain) #分別對訓練集、測試集進行歸一化
這樣再運行學習曲線的代碼,得到的結果就要好一些: