1. 程式人生 > >sklearn中的交叉驗證與引數選擇

sklearn中的交叉驗證與引數選擇

大家可能看到交叉驗證想到最多的就是sklearn裡面資料集的劃分方法train_test_split,實際上這只是資料交叉驗證的資料方法,對模型的進行評分。這裡我們將對仔細講解sklearn中交叉驗證如何判斷模型是否過擬合並進行引數選擇。主要涉及一下方法:
這裡寫圖片描述
其中方法中的得分引數如下,部分下面會解釋:
這裡寫圖片描述

一、cross_validate評估模型的表現:
1,對模型訓練一次,然後評估:這樣還是會存在過擬合的問題。具體如下:

#直接訓練
X_train,X_test,y_train,y_test=train_test_split(iris_X,iris_y,random_state=4
) #把資料集分為訓練集和測試集兩個部分一部分是訓練集,一部分是測試集,其中測試集佔了30% knn=KNeighborsClassifier(n_neighbors=5) knn.fit(X_train,y_train) print(knn.score(X_test,y_test))

解決辦法就是把資料分成(訓練,驗證,測試),但是這樣的問題就是會導致資料的浪費。接下來我們用交叉驗證的方法評估。

2,cross_val_score方法:
(1)這個方法是對資料進行多次分割,然後訓練多個模型並評分,每次分割不一樣。之後我們用評分的均值來代表這個模型的得分。方法重要引數是:cv代表計算多少次,分割次數;scoring代表方法。

#交叉驗證
from sklearn.model_selection import cross_val_score
knn = KNeighborsClassifier(n_neighbors=5)
score = cross_val_score(knn,iris_X,iris_y,cv=5,scoring='accuracy')
print(score)
print(score.mean())

(2)我們可以用這個方法,改變超引數n_neighbors的值,對不同模型進行準確評分,進行引數選擇。(程式碼比較簡單,看註釋應該可以理解)

from sklearn.datasets import
load_iris from sklearn.neighbors import KNeighborsClassifier iris=load_iris() iris_X=iris.data iris_y=iris.target #交叉驗證 from sklearn.model_selection import cross_val_score knn = KNeighborsClassifier(n_neighbors=5) score = cross_val_score(knn,iris_X,iris_y,cv=5,scoring='accuracy') print(score) print(score.mean()) #交叉驗證對引數進行選擇 import matplotlib.pyplot as plt k_range = range(1,31) k_loss = [] k_accuracy = [] for k in k_range:#對引數進行控制,選擇引數表現好的,視覺化展示 knn = KNeighborsClassifier(n_neighbors=k) accuracy = cross_val_score(knn,iris_X,iris_y,cv=10,scoring='accuracy')#for classification 精度 loss = -cross_val_score(knn,iris_X,iris_y,cv=10,scoring='neg_mean_squared_error')#for regression 損失函式 k_accuracy.append(accuracy.mean())#計算均值得分 k_loss.append(loss.mean()) #繪圖 plt.subplot(1,2,1) plt.plot(k_range,k_accuracy) plt.xlabel("Value of K for KNN") plt.ylabel("Cross-validates Accuracy") plt.subplot(1,2,2) plt.plot(k_range,k_loss) plt.xlabel("Value of K for KNN") plt.ylabel("Cross-validates Loss") plt.show()

(3)cv可以傳入資料的分割方法:分割方法用ShuffleSplit(還有其他的類)類來定義

from sklearn.model_selection import ShuffleSplit
n_samples = iris.data.shape[0]
cv = ShuffleSplit(n_splits=3, test_size=0.3, random_state=0)
cross_val_score(clf, iris.data, iris.target, cv=cv)

3,cross_validate方法:這個就是可以設定多個評分輸出,其他一樣

from sklearn.model_selection import cross_validate
from sklearn.metrics import recall_score
scoring = ['precision_macro', 'recall_macro']#設定評分項
clf = svm.SVC(kernel='linear', C=1, random_state=0)
scores = cross_validate(clf, iris.data, iris.target, scoring=scoring, cv=5, return_train_score=False)
sorted(scores.keys())
scores['test_recall_macro']                       

4,cross_val_predict方法:這個是對計算預測值,然後我們可以根據預測值計算得分。

from sklearn import metrics
from sklearn.datasets import load_iris
from sklearn.model_selection import cross_val_predict
from sklearn.neighbors import KNeighborsClassifier

iris = load_iris()
clf = KNeighborsClassifier(n_neighbors=5)
predicted = cross_val_predict(clf, iris.data, iris.target, cv=10)
score = metrics.accuracy_score(iris.target, predicted)#計算得分
print(score)

二、Validation curves驗證曲線:前面主要講的是模型的評估,主要思想就是採用多次資料分割的思想進行交叉驗證,用每次分割的得分均值評估模型。這裡主要講通過可視化了解模型的訓練過程,判斷模型是否過擬合,並進行引數選擇。

1,validation_curve驗證曲線方法:這個方法是用來測試模型不同引數(不同模型)的得分情況。重要引數為:param_name代表要控制的引數;param_range代表引數的取值列表。其他引數都一樣。返回訓練和測試集上的得分。
(根據模型在訓練集合測試集上,不同引數取值的結果,判斷模型是否過擬合,並進行引數選擇;每次針對一個引數)

from sklearn.model_selection import validation_curve   #視覺化學習的整個過程
from sklearn.datasets import load_digits
from sklearn.svm import SVC
import matplotlib.pyplot as plt
import numpy as np

digits=load_digits()
X=digits.data
y=digits.target
gamma_range=np.logspace(-6,-2.3,5)#從-6到-2.3取5個點
train_loss,test_loss=validation_curve(
    SVC(),X,y,param_name="gamma",param_range=gamma_range,cv=10,scoring="neg_mean_squared_error")
train_loss_mean= (-1)*np.mean(train_loss,axis=1)
test_loss_mean= (-1)*np.mean(test_loss,axis=1)

plt.plot(gamma_range,train_loss_mean,"o-",color="r",label="Training")
plt.plot(gamma_range,test_loss_mean,"o-",color="g",label="Cross-validation")

plt.xlabel("gamma")
plt.ylabel("Loss")
plt.legend(loc="best")
plt.show()

2,learning_curve學習曲線方法:這個方法顯示了對於不同數量的訓練樣本的模型的驗證和訓練評分。 這是一個工具,可以找出我們從新增更多的訓練資料中受益多少,以及估計器是否因方差錯誤或偏差錯誤而受到更多的影響。 如果驗證分數和訓練分數都隨著訓練集規模的增加而收斂到一個太低的值,那麼我們就不會從更多的訓練資料中受益。 在下面的情節中,你可以看到一個例子:樸素貝葉斯大致收斂到一個低分。
方法重要引數:train_sizes代表每次選擇進行訓練的資料大小。
方法返回:訓練資料大小列表,訓練集,測試集上的得分列表

from sklearn.model_selection import learning_curve   #視覺化學習的整個過程
from sklearn.datasets import load_digits
from sklearn.svm import SVC
import matplotlib.pyplot as plt
import numpy as np

digits=load_digits()
X=digits.data
y=digits.target

#交叉驗證測試
train_sizes,train_loss,test_loss = learning_curve(SVC(gamma=0.1),X,y,cv=10,scoring='neg_mean_squared_error',train_sizes=[0.1,0.25,0.5,0.75,1])   #記錄的點是學習過程中的10%,25%等等的點
train_loss_mean = -1 * np.mean(train_loss,axis=1)
test_loss_mean = -1 * np.mean(test_loss,axis=1)

#視覺化展示
plt.subplot(1,2,1)
plt.plot(train_sizes,train_loss_mean,'o-',color='r',label='train')
plt.plot(train_sizes,test_loss_mean,'o-',color='g',label='cross_validation')

plt.xlabel("Training examples")
plt.ylabel("Loss")
plt.legend(loc="best")

#交叉驗證測試
train_sizes,train_loss,test_loss = learning_curve(SVC(gamma=0.001),X,y,cv=10,scoring='neg_mean_squared_error',train_sizes=[0.1,0.25,0.5,0.75,1])   #記錄的點是學習過程中的10%,25%等等的點
train_loss_mean = 1 * np.mean(train_loss,axis=1)
test_loss_mean = 1 * np.mean(test_loss,axis=1)

#視覺化展示
plt.subplot(1,2,2)
plt.plot(train_sizes,train_loss_mean,'o-',color='r',label='train')
plt.plot(train_sizes,test_loss_mean,'o-',color='g',label='cross_validation')

plt.xlabel("Training examples")
plt.ylabel("Loss")
plt.legend(loc="best")
plt.show()