机器学习——交叉验证,GridSearchCV,岭回归

0.交叉验证

  交叉验证的基本思想是把在某种意义下将原始数据(dataset)进行分组,一部分做为训练集(train set),另一部分做为验证集(validation set or test set),首先用训练集对分类器进行训练,再利用验证集来测试训练得到的模型(model),以此来做为评价分类器的性能指标。

  交叉验证用在数据不是很充足的时候。比如在我日常项目里面,对于普通适中问题,如果数据样本量小于一万条,我们就会采用交叉验证来训练优化选择模型。如果样本大于一万条的话,我们一般随机的把数据分成三份,一份为训练集(Training Set),一份为验证集(Validation Set),最后一份为测试集(Test Set)。用训练集来训练模型,用验证集来评估模型预测的好坏和选择模型及其对应的参数。把最终得到的模型再用于测试集,最终决定使用哪个模型以及对应参数。

  根据切分的方法不同,交叉验证分为下面三种:   

  第一种是简单交叉验证,所谓的简单,是和其他交叉验证方法相对而言的。首先,我们随机的将样本数据分为两部分(比如: 70%的训练集,30%的测试集),然后用训练集来训练模型,在测试集上验证模型及参数。接着,我们再把样本打乱,重新选择训练集和测试集,继续训练数据和检验模型。最后我们选择损失函数评估最优的模型和参数。 

   第二种是S折交叉验证(S-Folder Cross Validation)。和第一种方法不同,S折交叉验证会把样本数据随机的分成S份,每次随机的选择S-1份作为训练集,剩下的1份做测试集。当这一轮完成后,重新随机选择S-1份来训练数据。若干轮(小于S)之后,选择损失函数评估最优的模型和参数。

  第三种是留一交叉验证(Leave-one-out Cross Validation),它是第二种情况的特例,此时S等于样本数N,这样对于N个样本,每次选择N-1个样本来训练数据,留一个样本来验证模型预测的好坏。此方法主要用于样本量非常少的情况,比如对于普通适中问题,N小于50时,我一般采用留一交叉验证。

 

1.模型调参利器GridSearchCV(网格搜索)

  GridSearchCV能够通过给定的参数列表,自动的帮我们选择一个最优的参数,在数据集不大的情况下非常适合使用。函数的相关参数的含义如下:

    GridSearchCV(estimatorparam_gridscoring=Nonefit_params=Nonen_jobs=1iid=Truerefit=Truecv=Noneverbose=0pre_dispatch='2*n_jobs'error_score='raise'return_train_score=True)

Parameters:

  estimator:所使用的分类器,或者pipeline

  param_grid:值为字典或者列表,即需要最优化的参数的取值

  scoring:准确度评价标准,默认None,这时需要使用score函数;或者如scoring='roc_auc',根据所选模型不同,评价准则不同。字符串(函数名),或是可调用对象,需要其函数签名形如:scorer(estimator, X, y);如果是None,则使用estimator的误差估计函数。

  n_jobs:并行数,int:个数,-1:跟CPU核数一致, 1:默认值。

  pre_dispatch:指定总共分发的并行任务数。当n_jobs大于1时,数据将在每个运行点进行复制,这可能导致OOM,而设置pre_dispatch参数,则可以预先划分总共的job数量,使数据最多被复制pre_dispatch次

  iid:默认True,为True时,默认为各个样本fold概率分布一致,误差估计为所有样本之和,而非各个fold的平均。

  cv:交叉验证参数,默认None,使用三折交叉验证。指定fold数量,默认为3,也可以是yield训练/测试数据的生成器。

  refit:默认为True,程序将会以交叉验证训练集得到的最佳参数,重新对所有可用的训练集与开发集进行,作为最终用于性能评估的最佳模型参数。即在搜索参数结束后,用最佳参数结果再次fit一遍全部数据集。

  verbose:日志冗长度,int:冗长度,0:不输出训练过程,1:偶尔输出,>1:对每个子模型都输出。

Attributes:
  best_estimator_:效果最好的分类器

  best_score_:成员提供优化过程期间观察到的最好的评分

  best_params_:描述了已取得最佳结果的参数的组合

  best_index_:对应于最佳候选参数设置的索引(cv_results_数组的索引)。

Methods:

  decision_function:使用找到的参数最好的分类器调用decision_function。

  fit(Xy=Nonegroups=None**fit_params):训练

  get_params(deep=True):获取这个估计器的参数。

  predict(X):用找到的最佳参数调用预估器。(直接预测每个样本属于哪一个类别)

  predict_log_proda(X):用找到的最佳参数调用预估器。(得到每个测试集样本在每一个类别的得分取log情况)

  predict_proba(X):用找到的最佳参数调用预估器。(得到每个测试集样本在每一个类别的得分情况)

  score(Xy=None):返回给定数据上的得分,如果预估器已经选出最优的分类器。

  transform(X):调用最优分类器进行对X的转换。

  下面我们一岭回归为例,运用GridSearchCV进行调参工作:

 1 import numpy as np
 2 import matplotlib.pyplot as plt
 3 import pandas as pd
 4 from sklearn.model_selection import train_test_split
 5 from sklearn.linear_model import Lasso, Ridge
 6 from sklearn.model_selection import GridSearchCV
 7 
 8 
 9 if __name__ == "__main__":
10     # pandas读入
11     data = pd.read_csv('../data-set/Advertising.csv')
12     x = data[['TV', 'Radio', 'Newspaper']]
13     
14     y = data['Sales']
15 
16     x_train, x_test, y_train, y_test = train_test_split(x, y, random_state=1)
17     
18     #model = Lasso()
19     model = Ridge()
20 
21     alpha_can = np.logspace(-3, 2, 10)
22     lasso_model = GridSearchCV(model, param_grid={'alpha': alpha_can}, cv=5)
23     lasso_model.fit(x, y)
24     print('验证参数:\n', lasso_model.best_params_)
25 
26     y_hat = lasso_model.predict(np.array(x_test))
27     mse = np.average((y_hat - np.array(y_test)) ** 2)  # Mean Squared Error
28     rmse = np.sqrt(mse)  # Root Mean Squared Error
29     print(mse, rmse)
30 
31     t = np.arange(len(x_test))
32     plt.plot(t, y_test, 'r-', linewidth=2, label='Test')
33     plt.plot(t, y_hat, 'g-', linewidth=2, label='Predict')
34     plt.legend(loc='upper right')
35     plt.grid()
36     plt.show()

  在上述的代码中,np.logspace(-3, 2, 10)为返回10^-3到10^2的长度为默认10的列表,作为参数的可选值,lasso_model = GridSearchCV(model, param_grid={'alpha': alpha_can}, cv=5)中,param_grid自动参数alpha的参数列表,cv表示使用5折交叉验证。

运行结果如下:

 

 

欢迎关注我的公众号,不定期更新机器学习原理教程!

 

posted @ 2019-04-01 22:58  Baby-Lily  阅读(6238)  评论(0编辑  收藏  举报