本文主要是介绍SK中模型选择模块的使用,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
sklearn 中关于model_selection的总结
|||评分标准、metric模块!
API: http://scikit-learn.org/stable/model_selection.html
- model_selection,顾名思义必然是在训练数据的时候使用啊。用来干什么呢?我们进行参数调整,我们选择不同的ML算法。那么这些算法和参数怎么才是最好的搭配呢?在sklearn给出了一整套完整的解决方案,这里对其中的常用的方法进行备注,以备自己以后查看使用。
首先来看一下sklearn最新版中给出的一些model_selection的内容目录。
Cross-validation: evaluating estimator performance(交叉验证:评估估计器的表现)
Computing cross-validated metrics(计算验证指标)
Cross validation iterators(交叉验证迭代)
Tuning the hyper-parameters of an estimator(调整估计量的超参数)
Exhaustive Grid Search (网格搜索)
Randomized Parameter Optimization (随机参数优化)
Tips for parameter search(参数检索的tips)
Model evaluation: quantifying the quality of predictions(模型评估:验证模型预测的质量)
The scoring parameter: defining model evaluation rules
Classification metrics
Multilabel ranking metrics
Regression metrics
Clustering metrics
- Dummy estimators
Model persistence
- Validation curves: plotting scores to evaluate models
- Validation curve
- Learning curve
观察这个官方文档的目录就会发现,安排方式就是按着写代码的顺序来的啊。但是博主的还是个小菜鸟也用不到他里面这么这么多的功能所以在这里只是对自己已经使用的几个做一总结。剩余的以后再做补充。
新版本的sklearn中已经将原来的Cross-Validation模块迁移至model_selection中在使用相关内容是可以试用以下代码:
from sklearn import model_selection
model_selection中集成了大量的方法供人们使用,但是作为一个程序员还是要把其中的调用逻辑搞清楚的,如果使用上面的导入方法,在使用内部的方法的时候最好是是model_selection.xxx()的形式,这样代码的可读性比较强一点。当然不使用这个方法直接使用函数也是可以的。当然如果明确知道自己使用的是什么方法通过下面这个代码也是可以的:
from sklearn.model_selection import XXX
一、 评估估计器的表现
(一)、数据切分 —- 数据已经预处理完成
我们将预处理好的数据传入算法中开始进行训练。这个时候我们一般会使用几种固定的方法:
1、 将有限的数据集划分为训练集和测试集。这样可以将训练和测试的数据彻底分开提高训练的准备性。代码如下:
#将原始数据进行切分,注意一下返回的数据都有哪些#传入的参数依次:输入集x,y、切分后的测试数据占比、随机种子x_train,x_test,y_train,y_test = model_selection.train_test_split(x,y,test_size=0.3,random_state=0)
2、 为了降低过拟合将训练数据再次进行切分,将其划分成几个迭代过程。这里需要注意一下,我们进行三次迭代则训练数据就被分成三组。第一次迭代拿前两组进行训练后一组进行验证。剩下的按这个方式不断地迭代下去。相关代码如下:
#对训练数据进行3轮迭代的验证#相关参数说明:x_train,进行几轮迭代,随机种子fold = KFold(taitanic.shape[0],n_folds=3,random_state=1)#一定要注意每一个fold里面是每一组中train和test数据的下标。我们可以使用下面的for循环的样式,将两个部分迭代出来。for train,test in fold:
补充说明:这里是对数据进行切分的方法,当然针对不同的数据有不同额切分办法,当下我用到的最多的就是这个切分了。
(二)、计算验证指标
1、调用 model_selection.cross_val_score(具体参数参看文档) 最简单的方式。相关代码如下:
from sklearn.model_selection import cross_val_score#进行数据训练使用的算法,这里采用的是svm中的算法。clf = svm.SVC(kernel='linear', C=1)#iris.data,iris.target:x_train,y_train数据#cv: 交叉验证的方式如上文返回的fold就是在这个地方使用的。####当然如果指定整数5的话,表示要进行5轮迭代。这个方法自己就进行交叉验证了就不麻烦kflod了。####scores = cross_val_score(clf, iris.data, iris.target, cv=5)#返回值scores中包含着cv次迭代的返回的scores值,是一个array格式的list结构。可以通过使用scores.mean()得到这个迭代的均值。###特别的当我们进行参数选择的时候,可以通过这个均值来衡量不同参数下的模型效果的。其实只要理解了,拓展就很容易了。 ###当然我们也会想这个scores究竟指定是什么呢?默认情况下是f1,在api中有详细的说明,如果需要指定了去这里看看就好:http://scikit-learn.org/stable/modules/model_evaluation.html#scoring-parameter
补充说明:这里给自己也提一下醒,这个地方我看着api中还有好多个传参函数,怎么用还没有学会希望自己慢慢的把他们明白了。
2、调用 model_selection.cross_validate(具体参数参看文档)。
这个方法应该是要引起足够重视的。翻译API后发现,与前文cross_val_score有两点不同:a.允许一次使用多个评估标准。b.返回一个字典结构其中包括training scores, fit-times and score-times
我们首先开看一下这个multiple metric evaluation究竟是个啥!!! 在机器学习领域的算法中其实模型好坏的评估标准就那么几个,比如说什么recall值啊等等的。在sklearn中完美的集成了这些值标准,具体有哪些并且包含在什么module中,请查看API:http://scikit-learn.org/stable/modules/model_evaluation.html#scoring-parameter
现在书归正传,首先上代码:
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)###注意最后一个参数的用法,默认情况下是true返回训练的时间,使用时可以设置成False,因为返回的一般用不到。
###scoring参数,如果多个参数则必须组合成字典结构。一个参数时则是字符串结构。也可以使用默认的f1-score。scores = cross_validate(clf, iris.data, iris.target, scoring=scoring,cv=5, return_train_score=False)###建议以后自己用的时候也这样打印一下,方便自己的使用。sorted(scores.keys())['fit_time', 'score_time', 'test_precision_macro', 'test_recall_macro']
scores['test_recall_macro'] array([ 0.96..., 1. ..., 0.96..., 0.96..., 1. ])
3、通过 cross_val_predict 生成预测的评价指标。这个的使用方法与cross_val_predict完全相同。
scores = cross_validate(clf, iris.data, iris.target,scoring='precision_macro')sorted(scores.keys())
['fit_time', 'score_time', 'test_score', 'train_score']
二 、调整估计量的超参数
(一)、GridSearchCV() —- 表格搜索
这是个强悍到不行的函数,实在是让我想不明白它是如何直接去进行参数组合的。我们先上代码看一下怎么使用它:
#先导入一些依赖包
from sklearn.ensemble import GradientBoostingClassifier
from sklearn.grid_search import GridSearchCV
from sklearn import metrics
import numnpy as np
import pandas as pd
#设置要查找的参数
params=params={'learning_rate':np.linspace(0.05,0.25,5), 'max_depth':[x for x in range(1,8,1)], 'min_samples_leaf':[x for x in range(1,5,1)], 'n_estimators':[x for x in range(50,100,10)]}
#设置模型和评价指标,开始用不同的参数训练模型
clf = GradientBoostingClassifier()
grid = GridSearchCV(clf, params, cv=10, scoring="f1")
grid.fit(X, y)grid.best_score_ #查看最佳分数(此处为f1_score)
grid.best_params_ #查看最佳参数
grid.best_score_
grid.best_params_
grid.best_estimator_
#获取最佳模型,利用最佳模型来进行预测
best_model=grid.best_estimator_
predict_y=best_model.predict(Test_X)
metrics.f1_score(y, predict_y)
因为电脑出了问题又重新写的!草!
自动化调参这里,还有一些随机的方法。等等的,现在用不太着,过段时间有时间来再过来把这个地方的墙垒起来把
三、模型评估:验证模型预测的质量
我们训练的模型究竟是好还是坏呢?sklearn有一个完整的解决方案。对于模型评估sklearn给出了三种解决方案:
- Estimator score method(估计器成绩法)
不同的估计器都有一个score方法,提供了一个默认的内置评估标准。每一个评估器都有自己的方法,在这里就不赘述了。当研究到评估期的时候留心一下就好了。
- Scoring parameter(Scoring参数)
我们前文介绍估计工具的时候提到了使用依靠内部评分策略的cross-validation( model_selection.cross_val_score 和 model_selection.GridSearchCV )方法。至于如何使用前文也已详细阐述,不过要着重说明的是Scoring变量还是由那个表给出,具体的内容请看API:
http://scikitlearn.org/stable/modules/model_evaluation.html#scoring-parameter
- Metric functions(metric方法)
metric是sklearn中内置的一个专门用来提供标准的一个模块。机器学习当中需要评价的功能基本上在这个模块里面都能找到。
书归正传,我们可以使用这个模块自定义我们自己的评价策略。说白了,就是我们自己想用什么评价就用什么评价标准。这里其实又跟上面重合了,但是为什么要拿出来说一下呢?最大的一个原因是里面有个make_scorer方法,当我们选用metric的评价标准时有些是要传递参数的,这个时候就需要这个方法出马了(至于为啥传参还真是不太清楚,不过马上就清楚了),给出一段示例代码:
from sklearn.metrics import fbeta_score, make_scorer
#make_scorer就是在这里用的
ftwo_scorer = make_scorer(fbeta_score, beta=2)
from sklearn.model_selection import GridSearchCV
from sklearn.svm import LinearSVC
grid = GridSearchCV(LinearSVC(), param_grid={'C': [1, 10]}, scoring=ftwo_scorer)
注:使用这个方法的时候将 greater_is_better 参数置为False。
重要提示:这一部分其实并没有说明任何新知识,但是给出了把评分这个事情进行一步梳理。至于Metric模块剩下的评分的方法和标准的含义,后面学到这里的时候,会专门写一篇博客来深入的探究一下。
四、Model persistence(模型持久)
通俗的说模型持久化就是把我们训练完成的模型给序列化一下,或者是到流里面或者是到文件里面。之前见过最多的就是把java的对象序列化,而在Python中一个模型也相当于一个对象,所以从最根本上来说将模型持久化也就是序列化。那么怎么做么呢?
首先我们来看Python中自带的序列化方法:
from sklearn import svm
from sklearn import datasets
clf = svm.SVC()
iris = datasets.load_iris()
X, y = iris.data, iris.target
clf.fit(X, y)
SVC(C=1.0, cache_size=200, class_weight=None, coef0=0.0,decision_function_shape='ovr', degree=3, gamma='auto', kernel='rbf',max_iter=-1, probability=False, random_state=None, shrinking=True,tol=0.001, verbose=False)
#关注一下这里就好啦!
import pickle
s = pickle.dumps(clf)
clf2 = pickle.loads(s)
clf2.predict(X[0:1])
当然,sklearn中也必然整合相关的方法怎么使用呢?
#joblib 序列的化的效率高也更加稳定,并且可以将模型写入文件中。并通过另一python程序加载执行。很6啊。
from sklearn.externals import joblib
joblib.dump(clf, 'filename.pkl')
clf = joblib.load('filename.pkl')
五、Validation curves: plotting scores to evaluate models(验证图像)
我们先说一点有意思的事情。我们训练模型就是想得到一个无限接近真实情况的曲线。所以才需要选择训练算法和调整参数啊。那么 误差的存在是无法避免的。我们可以将误差分解为三个部分:偏差、方差、噪声。
偏差反映的是模型在样本上的输出与真实值之间的误差,即模型本身的精准度。方差反映的是模型每一次输出结果与模型输出期望之间的误差,即模型的稳定性。当我们拟合图像的时候,如果偏差过大则曲线过于简单对样本拟合度不够,如果方差过大则拟合曲线过于复杂出现过拟合。
偏差和方差是估计量的固有属性,并且不可兼得。造成这种现象的根本原因是,我们总是希望试图用有限训练样本去估计无限的真实数据。当我们更加相信这些数据的真实性,而忽视对模型的先验知识,就会尽量保证模型在训练样本上的准确度,这样可以减少模型的Bias。但是,这样学习到的模型,很可能会失去一定的泛化能力,从而造成过拟合,降低模型在真实数据上的表现,增加模型的不确定性。相反,如果更加相信我们对于模型的先验知识,在学习模型的过程中对模型增加更多的限制,就可以降低模型的variance,提高模型的稳定性,但也会使模型的Bias增大。
上面说完了基本的概念,那么我们该怎么在实际的操作中去发现我们训练的模型的是否是过拟合或者欠拟合呢?以及我们增加新的训练数据的时候是否对模型的优化起到作用了呢?
幸运的是model_selection提供了以下两种方法供我们使用,我们现在一一来看:
1 、Plotting Validation Curves (验证曲线)
为了验证模型,我们需要一个评分函数,例如分类器的准确性。选择估计器的多个超参数的正确方法当然是网格搜索或类似的方法,其在验证集或多个验证集上选择具有最大分数的超参数。请注意,如果我们根据验证分数对超参数进行了优化,则验证分数是有偏的,而不是泛化的好估计。为了得到对泛化的适当估计,我们必须在另一个测试集上计算得分。
然而,绘制单个超参数对训练分数和验证分数的影响有时是有帮助的,以找出估计器对于某些超参数值是过度拟合还是欠拟合。
import matplotlib.pyplot as plt
import numpy as npfrom sklearn.datasets import load_digits
from sklearn.svm import SVC
from sklearn.model_selection import validation_curvedigits = load_digits()
X, y = digits.data, digits.targetparam_range = np.logspace(-6, -1, 5)
train_scores, test_scores = validation_curve(SVC(), X, y, param_name="gamma", param_range=param_range,cv=10, scoring="accuracy", n_jobs=1)
train_scores_mean = np.mean(train_scores, axis=1)
train_scores_std = np.std(train_scores, axis=1)
test_scores_mean = np.mean(test_scores, axis=1)
test_scores_std = np.std(test_scores, axis=1)plt.title("Validation Curve with SVM")
plt.xlabel("$\gamma$")
plt.ylabel("Score")
plt.ylim(0.0, 1.1)
lw = 2
plt.semilogx(param_range, train_scores_mean, label="Training score",color="darkorange", lw=lw)
plt.fill_between(param_range, train_scores_mean - train_scores_std,train_scores_mean + train_scores_std, alpha=0.2,color="darkorange", lw=lw)
plt.semilogx(param_range, test_scores_mean, label="Cross-validation score",color="navy", lw=lw)
plt.fill_between(param_range, test_scores_mean - test_scores_std,test_scores_mean + test_scores_std, alpha=0.2,color="navy", lw=lw)
plt.legend(loc="best")
plt.show()
在这个图中,你可以看到SVM对于核参数γ的不同值的训练分数和验证分数。对于非常低的gamma值,您可以看到训练分数和验证分数都很低。这被称为underfit。gamma的中等值会导致两个分数的高值,即分类器表现相当好。如果伽马值太高,分类器会过度训练,这意味着训练分数是好的,但是验证分数是差的。
2 、Plotting Learning Curves(学习曲线)
学习曲线显示了对于不同数量的训练样本的估计器的验证和训练评分。这是一个工具,可以找出我们从添加更多的训练数据中受益多少,以及估计器是否因方差错误或偏差错误而受到更多的影响。如果验证分数和训练分数都随着训练集规模的增加而收敛到一个太低的值,那么我们就不会从更多的训练数据中受益
import numpy as np
import matplotlib.pyplot as plt
from sklearn.naive_bayes import GaussianNB
from sklearn.svm import SVC
from sklearn.datasets import load_digits
from sklearn.model_selection import learning_curve
from sklearn.model_selection import ShuffleSplitdef plot_learning_curve(estimator, title, X, y, ylim=None, cv=None,n_jobs=1, train_sizes=np.linspace(.1, 1.0, 5)):"""Generate a simple plot of the test and training learning curve.Parameters----------estimator : object type that implements the "fit" and "predict" methodsAn object of that type which is cloned for each validation.title : stringTitle for the chart.X : array-like, shape (n_samples, n_features)Training vector, where n_samples is the number of samples andn_features is the number of features.y : array-like, shape (n_samples) or (n_samples, n_features), optionalTarget relative to X for classification or regression;None for unsupervised learning.ylim : tuple, shape (ymin, ymax), optionalDefines minimum and maximum yvalues plotted.cv : int, cross-validation generator or an iterable, optionalDetermines the cross-validation splitting strategy.Possible inputs for cv are:- None, to use the default 3-fold cross-validation,- integer, to specify the number of folds.- An object to be used as a cross-validation generator.- An iterable yielding train/test splits.For integer/None inputs, if ``y`` is binary or multiclass,:class:`StratifiedKFold` used. If the estimator is not a classifieror if ``y`` is neither binary nor multiclass, :class:`KFold` is used.Refer :ref:`User Guide <cross_validation>` for the variouscross-validators that can be used here.n_jobs : integer, optionalNumber of jobs to run in parallel (default 1)."""plt.figure()plt.title(title)if ylim is not None:plt.ylim(*ylim)plt.xlabel("Training examples")plt.ylabel("Score")train_sizes, train_scores, test_scores = learning_curve(estimator, X, y, cv=cv, n_jobs=n_jobs, train_sizes=train_sizes)train_scores_mean = np.mean(train_scores, axis=1)train_scores_std = np.std(train_scores, axis=1)test_scores_mean = np.mean(test_scores, axis=1)test_scores_std = np.std(test_scores, axis=1)plt.grid()plt.fill_between(train_sizes, train_scores_mean - train_scores_std,train_scores_mean + train_scores_std, alpha=0.1,color="r")plt.fill_between(train_sizes, test_scores_mean - test_scores_std,test_scores_mean + test_scores_std, alpha=0.1, color="g")plt.plot(train_sizes, train_scores_mean, 'o-', color="r",label="Training score")plt.plot(train_sizes, test_scores_mean, 'o-', color="g",label="Cross-validation score")plt.legend(loc="best")return pltdigits = load_digits()
X, y = digits.data, digits.targettitle = "Learning Curves (Naive Bayes)"
# Cross validation with 100 iterations to get smoother mean test and train
# score curves, each time with 20% data randomly selected as a validation set.
cv = ShuffleSplit(n_splits=100, test_size=0.2, random_state=0)estimator = GaussianNB()
plot_learning_curve(estimator, title, X, y, ylim=(0.7, 1.01), cv=cv, n_jobs=4)title = "Learning Curves (SVM, RBF kernel, $\gamma=0.001$)"
# SVC is more expensive so we do a lower number of CV iterations:
cv = ShuffleSplit(n_splits=10, test_size=0.2, random_state=0)
estimator = SVC(gamma=0.001)
plot_learning_curve(estimator, title, X, y, (0.7, 1.01), cv=cv, n_jobs=4)plt.show()
在上边显示了数字数据集的朴素贝叶斯分类器的学习曲线。请注意,训练分数和交叉验证分数最后都不是很好。然而,曲线的形状常常可以在更复杂的数据集中找到:训练得分在开始和结束时都非常高,开始时交叉验证得分非常低,并且增加。在下边图片,我们看到了RBF内核的SVM的学习曲线。我们可以清楚地看到,训练分数仍然在最大值附近,验证分数可以随着更多的训练样本而增加。
the end 。。。
这篇关于SK中模型选择模块的使用的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!