英文官方教程链接如下:
https://scikit-learn.org/stable/tutorial/statistical_inference/model_selection.htmlhttps://scikit-learn.org/stable/tutorial/statistical_inference/model_selection.html如有侵权,务必联系删除。
这一部分看着挺难的,我们一起加油吧。
Score, and cross-validated scores
每个分类器都会提供 score 方法,它可以作为判断拟合/预测质量的依据。
from sklearn import datasets, svm
X_digits, y_digits = datasets.load_digits(return_X_y=True)
length = len(X_digits)
use = int(length*0.9)
svc = svm.SVC(C=1, kernel='linear')
fit = svc.fit(X_digits[:use], y_digits[:use])
score = fit.score(X_digits[use:], y_digits[use:])
print(score)
#kernel的选择和对应分数
# linear:0.9666666666666667
# poly:0.9666666666666667
# rbf:0.95
# sigmoid:0.8666666666666667
#precomputed不能用作kernel,因为它需要给它输入的矩阵是方正
我觉得选择合适的 kernel 也是一门技术,需要具体问题具体分析,不过抱歉,我现在还没学会,只能多试几次了。
接下来的是重点,我不知道它是不是很常用,但我刚入门深度学习的时候经常看到。
这里就直接给出官方的 k折交叉验证的一个例子了,个人觉得代码的讲解十分浅显易懂,由此可见写代码的人的技术是真的高,毕竟大道至简吗。代码如下:
import numpy as np
from sklearn import datasets, svm
X_digits, y_digits = datasets.load_digits(return_X_y=True)
svc = svm.SVC(C=1, kernel='rbf')
X_folds = np.array_split(X_digits, 3)
#进行不均等切割,分成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)
#将之前分成的3份的第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)
#kernel的选择和对应分数
# linear:[0.9348914858096828, 0.9565943238731218, 0.9398998330550918]
# poly:[0.9582637729549248, 0.9799666110183639, 0.9515859766277128]
# rbf:[0.9666110183639399, 0.9816360601001669, 0.9549248747913188]
# sigmoid:[0.8697829716193656, 0.9015025041736227, 0.8764607679465777]
与上一片代码的结果对比,由此可见,kernel 真的要学着会调啊。
Cross-validation generators
KFold (n_splits, shuffle, random_state) | 分成 K 折,再 K-1 上训练,再剩下的上面测试 |
StratifiedKFold (n_splits, shuffle, random_state) | 和上一个一样,但是在每一折保留了类别分配 |
GroupKFold (n_splits) | 确保验证和测试集不同时出现相同的组 |
ShuffleSplit (n_splits, test_size, train_size, random_state) | 基于随机排列生成训练/测试切片 |
StratifiedShuffleSplit | 和上一个一样,但是在每一折保留了类别分配 |
GroupShuffleSplit | 确保验证和测试集不同时出现相同的组 |
LeaveOneGroupOut () | Takes a group array to group observations(不好意思,没看懂) |
LeavePGroupsOut (n_groups) | 除去P组 |
LeaveOneOut () | 除去一个观测 |
LeavePOut (p) | 除去P观测 |
PredefinedSplit | 基于预定义分割生成训练/测试切片 |
这里我就讲一下第一个吧,嘿嘿,其实是其他的我也不会,懒得再去深入探究一下。
import numpy as np
from sklearn.model_selection import KFold
x = np.arange(8)
k_fold = KFold(n_splits=3,shuffle=True)
#分成3份并加上达伦效果
for train,test in k_fold.split(x):
print('Train:{},Test:{}'.format(train,test))
#Train:[1 2 4 6 7],Test:[0 3 5]
#Train:[0 2 3 5 7],Test:[1 4 6]
#Train:[0 1 3 4 5 6],Test:[2 7]
可能有人好奇为什么你分成三份,打印出来的却只有两份呢?其实我刚运行完之后也思考了一会,不过现在想明白了。那就是正如上一片代码或者表格里描述的那样,它将 K-1 折作为训练集,这里面暗含着将 K-1 块拼接的过程,剩下来的一块作为测试集。(我觉得这样理解挺合理的,如有错误,敬请指正)。现在想想,其他的方法也可以找这样使用,大家不妨自己动手试试。
Grid-search and cross-validated estimators
scikit-learn提供了一个对象,给定数据情况下,在评估器在参数网格上拟合的过程中,它会计算分数,并选择能够使得交叉验证分数最大的一组参数。
import numpy as np
from sklearn.model_selection import GridSearchCV
from sklearn import datasets, svm
X_digits, y_digits = datasets.load_digits(return_X_y=True)
Cs = np.linspace(0.1,200)
svc = svm.SVC(C=1, kernel='poly')
clf = GridSearchCV(estimator=svc, param_grid=dict(C=Cs),n_jobs=-1)
clf.fit(X_digits[:1000], y_digits[:1000])
print(clf.best_score_)
#0.959
这里我用的也是官方的代码,大家可以试着自己改一改,我的水平也就这么高了。