交叉验证:评估估计器性能
为了防止出现过拟合的情况,一般需要将数据分为训练集和测试集。在Sklearn中可以利用
train_test_split()函数来划分数据集。
import numpy as np
from sklearn.model_selection import train_test_split
from sklearn import datasets
from sklearn import svm
iris = datasets.load_iris()
iris.data.shape,iris.target.shape
输出:((150, 4), (150,))
现在我们可以用60%的数据用作训练集,40%的数据用作测试集
X_train,X_test,y_train,y_test = train_test_split(iris.data,iris.target,test_size = 0.4,random_state = 0)
X_train.shape,y_train.shape
((90, 4), (90,))
X_test.shape,y_test.shape
((60, 4), (60,))
用训练集训练模型,在测试集上进行评估模型的性能。
clf = svm.SVC(kernel='linear',C=1).fit(X_train,y_train)
clf.score(X_test,y_test)
0.9666666666666667
在机器学习中需要我们手动输入的参数叫做超参数,其余的参数需要依靠数据来进行训练,不需要我们手动设定。
进行超参数选择的过程叫做调参。
如果只是把数据集分为训练集合测试集的话,那么还是可能发生过拟合的情况的。实际应用的时候,我们一般是把数据分为训练集、验证集和测试集三部分。
但是这样一来,我们可以用来训练的数据也就相应的变少了,尤其是当数据集不是太充分的情况下,更是如此。
解决这个问题的方法就是交叉验证。
交叉验证在计算上可能比较昂贵,但是这样不会浪费数据。
模型训练时,一个典型的交叉验证流程图如下:
最好的参数可以通过grid search(网格搜索)技术找到
计算交叉验证的度量:
最简单的使用交叉验证的方法是在数据集和模型上调用cross_val_score函数
>>> from sklearn.model_selection import cross_val_score
>>> clf = svm.SVC(kernel='linear', C=1)
>>> scores = cross_val_score(clf, iris.data, iris.target, cv=5)
>>> scores
array([0.96..., 1. ..., 0.96..., 0.96..., 1. ])
在超参数kernel = ‘linear’ 和C = 1 给定的情况下,将训练数据分成5份,5次迭代下来的测试得分为array([0.96…, 1. …, 0.96…, 0.96…, 1. ])
(如果要调整超参数的话,需要给kernel和C赋不同的值,进行交叉验证,选择平均分最高的超参数,这就是参数调整)
下面的例子用来查找KNN算法中,最优的k值,在(1-31之间选择)
用于调节参数
from sklearn.cross_validation import cross_val_score
# search for an optimal value of K for KNN model
k_range = range(1,31)
k_scores = []
for k in k_range:
knn = KNeighborsClassifier(n_neighbors=k)
scores = cross_val_score(knn, X, y, cv=10, scoring='accuracy')
k_scores.append(scores.mean())
print k_scores
调整估计器的超参数
超参数是在模型中不直接学习的参数,在scikit学习中,他们被作为参数传递给模型的构造函数。
典型的例子包括 支持向量机的C、kernel 与gamma .
通过搜索超参数空间来获取最高的交叉验证分数是可能的并推荐的。
可以通过这种方法来优化模型的任何超参数。
进行调参应该有以下准备条件:
1)一个学习器(回归或者分类,如sklearn.svm.SVC)
2)一个参数空间
3)一个从参数空间寻找参数的方法
4)一个交叉验证的规则
5)一个性能评估的策略
穷举式的网格搜索:
GridSearchCV 在数据集上拟合时,将评估参数值的所有可能组合,并保留最佳组合。
通过GridSearchCV穷举网格搜索生成所有的参数候选者param_grid.
param_grid = [
{'C': [1, 10, 100, 1000], 'kernel': ['linear']},
{'C': [1, 10, 100, 1000], 'gamma': [0.001, 0.0001], 'kernel': ['rbf']},
]
应该探讨两个网格:一个线性内核和C值在[1,10,100,1000]中,
第二个是RBF内核,C值的交叉乘积在[1,10 ,100,1000]和[0.001,0.0001]中的伽马值。
随机搜索
随机搜索就是制定参数的随机分布的策略,从这些策略当中随机产生我们需要的参数进行评估。sklearn当中使用RandomizedSearchCV来完成。