1.模型验证回顾


进行模型验证的一个重要目的是要选出一个最合适的模型,对于监督学习而言,我们希望模型对于未知数据的泛化能力强,所以就需要模型验证这一过程来体现不同的模型对于未知数据的表现效果。


最先我们用训练准确度(用全部数据进行训练和测试)来衡量模型的表现,这种方法会导致模型过拟合;为了解决这一问题,我们将所有数据分成训练集和测试集两部分,我们用训练集进行模型训练,得到的模型再用测试集来衡量模型的预测表现能力,这种度量方式叫测试准确度,这种方式可以有效避免过拟合。

测试准确度的一个缺点是其样本准确度是一个高方差估计(high variance estimate),所以该样本准确度会依赖不同的测试集,其表现效果不尽相同。

交叉验证的过程

* 选择K的值(一般是10),将数据集分成K等份
* 使用其中的K-1份数据作为训练数据,另外一份数据作为测试数据,进行模型的训练
* 使用一种度量测度来衡量模型的预测性能
交叉验证的优点

* 交叉验证通过降低模型在一次数据分割中性能表现上的方差来保证模型性能的稳定性
* 交叉验证可以用于选择调节参数、比较模型性能差别、选择特征
交叉验证的缺点

* 交叉验证带来一定的计算代价,尤其是当数据集很大的时候,导致计算过程会变得很慢
高方差估计的例子

下面我们使用iris数据来说明利用测试准确度来衡量模型表现的方差很高。
from sklearn.model_selection import train_test_split from sklearn.datasets
import load_iris from sklearn.neighbors import KNeighborsClassifier from
sklearn import metrics data = load_iris() train = data.data test = data.target
for i in range(1,5): print("random_state is ", i,", and accuracy score is:")
train_x, test_x, train_y, test_y = train_test_split(train, test,random_state=i)
knn = KNeighborsClassifier(5) knn.fit(train_x,train_y)
y_pred=knn.predict(test_x) print(metrics.accuracy_score(test_y,y_pred))
结果:
random_state is 1 , and accuracy score is: 1.0 random_state is 2 , and
accuracy score is: 1.0 random_state is 3 , and accuracy score is:
0.9473684210526315 random_state is 4 , and accuracy score is: 0.9736842105263158

上面的测试准确率可以看出,不同的训练集、测试集分割的方法导致其准确率不同,而交叉验证的基本思想是:将数据集进行一系列分割,生成一组不同的训练测试集,然后分别训练模型并计算测试准确率,最后对结果进行平均处理。这样来有效降低测试准确率的差异。

2. K折交叉验证

* 将数据集平均分割成K个等份
* 使用1份数据作为测试数据,其余作为训练数据
* 计算测试准确率
* 使用不同的测试集,重复2、3步骤
* 对准确率做平均,作为对未知数据预测准确率的估计


 3.使用交叉验证的建议

* K=10是一个一般的建议
* 如果对于分类问题,应该使用分层抽样(stratified sampling)来生成数据,保证正负例的比例在训练集和测试集中的比例相同
 

4.交叉验证的例子

4.1用于参数调优


交叉验证的方法可以帮助我们进行调参,最终得到一组最佳的模型参数。下面的例子我们依然使用iris数据和KNN模型,通过调节参数,得到一组最佳的参数使得测试数据的准确率和泛化能力最佳。
from sklearn.datasets import load_iris from sklearn.neighbors import
KNeighborsClassifier # import warnings # warnings.filterwarnings("ignore") from
sklearn.model_selection import cross_val_score data = load_iris() train =
data.data test = data.target knn = KNeighborsClassifier(5) scores =
cross_val_score(knn,train,test,cv=10,scoring='accuracy') print(scores) [1.
0.93333333 1. 1. 0.86666667 0.93333333 0.93333333 1. 1. 1. ]
这个是每一次的的准确率,下面我们进行把这些准确率进行平均
print(scores.mean()) [1. 0.93333333 1. 1. 0.86666667 0.93333333 0.93333333 1.
1. 1. ] 0.9666666666666668
在上面的代码中,我们使用的是k=5这个值,但不一定是左右的,所以我们可以来进行选择,找到一个最优的k
from sklearn.datasets import load_iris from sklearn.neighbors import
KNeighborsClassifier # import warnings # warnings.filterwarnings("ignore") from
sklearn.model_selection import cross_val_score data = load_iris() train =
data.data test = data.target for i in range (1,30): knn =
KNeighborsClassifier(i) scores =
cross_val_score(knn,train,test,cv=10,scoring='accuracy') print(scores.mean())
结果:
0.96 0.9533333333333334 0.9666666666666666 0.9666666666666666
0.9666666666666668 0.9666666666666668 0.9666666666666668 0.9666666666666668
0.9733333333333334 0.9666666666666668 0.9666666666666668 0.9733333333333334
0.9800000000000001 0.9733333333333334 0.9733333333333334 0.9733333333333334
0.9733333333333334 0.9800000000000001 0.9733333333333334 0.9800000000000001
0.9666666666666666 0.9666666666666666 0.9733333333333334 0.96
0.9666666666666666 0.96 0.9666666666666666 0.9533333333333334 0.9533333333333334
4.2用于模型的选择

交叉验证也可以帮助我们进行模型选择,以下是一组例子,分别使用iris数据,KNN和logistic回归模型进行模型的比较和选择。

当阿然这里只是选择两个举个例子
knn = KNeighborsClassifier(n_neighbors=5) print (cross_val_score(knn, train,
test, cv=10, scoring='accuracy').mean()) lr = LogisticRegression()
print(cross_val_score(lr,train,test,cv=10,scoring='accuracy').mean())
0.9666666666666668 0.9533333333333334