sklearn中的model_selection模块(1)
sklearn作为Python的强大机器学习包,model_selection模块是其重要的一个模块:
1.model_selection.cross_validation:
(1)分数,和交叉验证分数
众所周知,每一个模型会得出一个score方法用于裁决模型在新的数据上拟合的质量。其值越大越好。
from sklearn import datasets, svm digits = datasets.load_digits() X_digits = digits.data y_digits = digits.target svc = svm.SVC(C=1, kernel='linear') svc.fit(X_digits[:-100], y_digits[:-100]).score(X_digits[-100:], y_digits[-100:])
为了获得一个更好的预测精确度度量,我们可以把我们使用的数据折叠交错地分成训练集和测试集:
import numpy as np X_folds = np.array_split(X_digits, 3) y_folds = np.array_split(y_digits, 3) scores = list() for k in range(3): # We use 'list' to copy, in order to 'pop' later on X_train = list(X_folds) X_test = X_train.pop(k) X_train = np.concatenate(X_train) y_train = list(y_folds) y_test = y_train.pop(k) y_train = np.concatenate(y_train) scores.append(svc.fit(X_train, y_train).score(X_test, y_test)) print(scores)
这被称为KFold交叉验证
(2)交叉验证生成器
上面将数据划分为训练集和测试集的代码写起来很是沉闷乏味。scikit-learn为此自带了交叉验证生成器以生成目录列表:
from sklearn import cross_validation k_fold = cross_validation.KFold(n=6, n_folds=3) for train_indices, test_indices in k_fold: print('Train: %s | test: %s' % (train_indices, test_indices))
接着交叉验证就可以很容易实现了:
kfold = cross_validation.KFold(len(X_digits), n_folds=3) [svc.fit(X_digits[train], y_digits[train]).score(X_digits[test], y_digits[test]) for train, test in kfold]
为了计算一个模型的score,scikit-learn自带了一个帮助函数:
cross_validation.cross_val_score(svc, X_digits, y_digits, cv=kfold, n_jobs=-1)
n_jobs=-1
意味着将计算任务分派个计算机的所有CPU.
交叉验证生成器:KFold(n,k)
交叉分割,K-1上进行训练,生于数据样例用于测试StratifiedKFold(y,K)
保存每一个fold的类比率/标签分布leaveOneOut(n)
至预留一个观测样例leaveOneLabelOut(labels)
采用一个标签数组把观测样例分组
2.model_selection.grid search 网格搜索和交叉验证模型
网格搜索:
scikit-learn提供一个对象,他得到数据可以在采用一个参数的模型拟合过程中选择使得交叉验证分数最高的参数。该对象的构造函数需要一个模型作为参数:
from sklearn.grid_search import GridSearchCV Cs = np.logspace(-6, -1, 10) clf = GridSearchCV(estimator=svc, param_grid=dict(C=Cs), n_jobs=-1) clf.fit(X_digits[:1000], y_digits[:1000]) clf.best_score_ clf.best_estimator_.C # Prediction performance on test set is not as good as on train set clf.score(X_digits[1000:], y_digits[1000:])
默认情况下,GridSearchCV
使用3-fold
交叉验证。然而,当他探测到是一个分类器而不是回归量,将会采用分层的3-fold
。
嵌套 交叉验证
cross_validation.cross_val_score(clf, X_digits, y_digits)
两个交叉验证循环是并行执行的:一个GridSearchCV
模型设置gamma
,另一个使用cross_val_score
度量模型的预测表现。结果分数是在新数据预测分数的无偏差估测。
【警告】你不能在并行计算时嵌套对象(n_jobs
不同于1)
交叉验证估测:
在算法by算法的基础上使用交叉验证去设置参数更高效。这也是为什么对于一个特定的模型/估测器引入Cross-validation
:评估估测器表现模型去自动的通过交叉验证设置参数。
from sklearn import linear_model, datasets lasso = linear_model.LassoCV() diabetes = datasets.load_diabetes() X_diabetes = diabetes.data y_diabetes = diabetes.target lasso.fit(X_diabetes, y_diabetes) # The estimator chose automatically its lambda: lasso.alpha_
这些模型的称呼和他们的对应模型很相似,只是在他们模型名字的后面加上了'CV
'.
【补充】嵌套交叉验证
通过嵌套交叉验证选择算法
- 如果需要在不同机器学习算法之间做选择,则可以使用嵌套交叉验证
- 分为内层嵌套和外层:一般使用GridSearchCV()进行内层的交叉验证,使用cross_val_score()进行外层交叉验证;
-
原理
- 在嵌套交叉验证的外围循环中,将数据划分为训练块及测试块
- 在内部循环中,则基于这些训练块,使用k折交叉验证
- 完成模型选择后,使用测试块进行模型性能的评估
- 如下图所示,是一种5*2交叉验证
gs = GridSearchCV(estimator=pipe_svc, param_grid=param_grid, scoring='accuracy', cv=2) # Note: Optionally, you could use cv=2 # in the GridSearchCV above to produce # the 5 x 2 nested CV that is shown in the figure. scores = cross_val_score(gs, X_train, y_train, scoring='accuracy', cv=5) print('CV accuracy: %.3f +/- %.3f' % (np.mean(scores), np.std(scores))) CV accuracy: 0.965 +/- 0.025
- 也可以使用该方法比较模型。如比较SVM模型和决策树模型
-
from sklearn.tree import DecisionTreeClassifier gs = GridSearchCV(estimator=DecisionTreeClassifier(random_state=0), param_grid=[{'max_depth': [1, 2, 3, 4, 5, 6, 7, None]}], scoring='accuracy', cv=2) scores = cross_val_score(gs, X_train, y_train, scoring='accuracy', cv=5) print('CV accuracy: %.3f +/- %.3f' % (np.mean(scores), np.std(scores))) CV accuracy: 0.921 +/- 0.029