机器学习基础(三)

1调参

​ 我们很自然的问题就是岭回归中的参数𝜆和参数w之间有什么不一样?事实上,参数w是我们通过设定某一个具体的𝜆后使用类似于最小二乘法、梯度下降法等方式优化出来的,我们总是设定了𝜆是多少后才优化出来的参数w。因此,类似于参数w一样,使用最小二乘法或者梯度下降法等最优化算法优化出来的数我们称为参数,类似于𝜆一样,我们无法使用最小二乘法或者梯度下降法等最优化算法优化出来的数我们称为超参数。模型超参数是模型外部的配置,其值无法从数据中估计。模型参数是模型内部的配置变量,其值可以根据数据进行估计。

参数:

  • 进行预测时需要参数。
  • 参数定义了可使用的模型。
  • 参数是从数据估计获悉的。
  • 参数通常不由编程者手动设置。
  • 参数通常被保存为学习模型的一部分。
  • 参数是机器学习算法的关键,它们通常由过去的训练数据中总结得出 。

超参数:

  • 超参数通常用于帮助估计模型参数。
  • 超参数通常由人工指定。
  • 超参数通常可以使用启发式设置。
  • 超参数经常被调整为给定的预测建模问题。

下面介绍两个scikit-learn中的两个调参函数:GridSearchCV()、 RandomizedSearchCV

1.1 网格搜索GridSearchCV()

网格搜索的思想非常简单,就是把所有的超参数选择列出来分别做排列组合,然后针对每组超参数分别建立一个模型,然后选择测试误差最小的那组超参数。换句话说,我们需要从超参数空间中寻找最优的超参数,很像一个网格中找到一个最优的节点,因此叫网格搜索。

class sklearn.model_selection.``GridSearchCV(estimator, param_grid, ***, scoring=None, n_jobs=None, refit=True, cv=None, verbose=0, pre_dispatch=‘2*n_jobs’, error_score=nan, return_train_score=False)

1.estimator

选择使用的分类器,并且传入除需要确定最佳的参数之外的其他参数。每一个分类器都需要一个scoring参数,或者score方法:如estimator=RandomForestClassifier(min_samples_split=100,min_samples_leaf=20,max_depth=8,max_features=‘sqrt’,random_state=10),

2.param_grid

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

param_grid =param_test1,

param_test1 = {‘n_estimators’:range(10,71,10)}。

3.scoring=None

模型评价标准,默认None,这时需要使用score函数;或者如scoring=‘roc_auc’,

根据所选模型不同,评价准则不同。字符串(函数名),或是可调用对象,

需要其函数签名形如:scorer(estimator, X, y);如果是None,则使用estimator的误差估计函数。

4.n_jobs=1

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

5.cv=None

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

6.verbose=0, scoring=None

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

7.pre_dispatch=‘2*n_jobs’

指定总共分发的并行任务数。当n_jobs大于1时,数据将在每个运行点进行复制,这可能导致OOM,

而设置pre_dispatch参数,则可以预先划分总共的job数量,使数据最多被复制pre_dispatch次

8.return_train_score=’warn’

如果“False”,cv_results_属性将不包括训练分数。

9.refit :默认为True,程序将会以交叉验证训练集得到的最佳参数,重新对所有可用的训练集与开发集进行,

作为最终用于性能评估的最佳模型参数。即在搜索参数结束后,用最佳参数结果再次fit一遍全部数据集。

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

进行预测的常用方法和属性

grid.fit:运行网格搜索

grid_scores_:给出不同参数情况下的评价结果

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

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

下面通过一个例子,介绍一下GridSearchCV的用法

params={'C':[0.05,0.1,1,3,10,13,15],'max_iter':[100,500,1000,1500],'class_weight':['balanced',None],'solver':['liblinear','sag','lbfgs','newto-cg'],'penalty':['l1','l2']}
lr=LogisticRegression(C=10,max_iter=1000,solver='newton-cg')
clf=GridSearchCV(lr,param_grid=params,cv=10,n_jobs=4)
clf.fit(train_x,train_y)
print(clf.best_params_)

上述代码是逻辑回归利用GridSearchCV()调参,params是需要调整的参数及其取值,GridSeachCV会一一尝试每一种可能的组合,获取误差最小的一组参数组合。调参之前需要对模型的参数进行详细的了解,搞懂每个参数的作用,否则胡乱的尝试参数不一定能获取较好的结果。下面是逻辑回归的参数解析,可以对照下面参数的解析,尝试参数的可能取值。

linear_model.``LogisticRegression(penalty=‘l2’, dual=False, tol=0.0001, C=1.0, fit_intercept=True, intercept_scaling=1, class_weight=None, random_state=None, solver=‘lbfgs’, max_iter=100, multi_class=‘auto’, verbose=0, warm_start=False, n_jobs=None, l1_ratio=None

  1. penalty:‘l1’,‘l2’,‘elasticnet’,‘none’},默认='l2’

正则化项的选择。正则化主要有两种:L1和L2,LogisticRegression默认选择L2正则化。

‘liblinear’ 支持L1和L2,但‘newton-cg’, ‘sag’ 和‘lbfgs’ 只支持L2正则化。仅“ saga”求解器支持“ elasticnet”。如果为“ none”(liblinear求解器不支持),则不应用任何正则化。

  1. dual:bool(True、False), default:False

如果为True,则求解对偶形式,只有在penalty=‘l2’ 且solver=‘liblinear’ 时有对偶形式;通常样本数大于特征数的情况下,默认为False,求解原始形式。

  1. tol : float, default:1e-4
    停止标准,误差不超过tol时,停止进一步的计算。

  2. C :float,default:1.0
    正则化强度(正则化系数λ)的倒数; 必须是大于0的浮点数。 与支持向量机一样,较小的值指定更强的正则化,通常默认为1。

  3. fit_intercept:bool(True、False),default:True
    是否存在截距,默认存在。

  4. intercept_scaling :float,default :1.0

仅在使用solver为“liblinear”且fit_intercept=True时有用。 在这种情况下,x变为[x,intercept_scaling],即具有等于intercept_scaling的常数值的“合成”特征被附加到实例矢量。 截距变成了intercept_scaling * synthetic_feature_weight. 注意: 合成特征权重与所有其他特征一样经受l1 / l2正则化。 为了减小正则化对合成特征权重(并因此对截距)的影响,必须增加intercept_scaling。相当于人造一个特征出来,该特征恒为 1,其权重为b。

  1. class_weight :dict or ‘balanced’,default:None
    class_weight参数用于标示分类模型中各种类型的权重,可以不输入,即不考虑权重,或者说所有类型的权重一样。如果选择输入的话,可以选择balanced让类库自己计算类型权重,或者我们自己输入各个类型的权重,比如对于0,1的二元模型,我们可以定义class_weight={0:0.9, 1:0.1},这样类型0的权重为90%,而类型1的权重为10%。
    如果class_weight选择balanced,那么类库会根据训练样本量来计算权重。某种类型样本量越多,则权重越低,样本量越少,则权重越高。当class_weight为balanced时,类权重计算方法如下:n_samples / (n_classes * np.bincount(y))

  2. random_state:int,RandomState instance or None,optional,default:None

在随机数据混洗时使用的伪随机数生成器的种子。 如果是int,则random_state是随机数生成器使用的种子; 如果是RandomState实例,则random_state是随机数生成器; 如果为None,则随机数生成器是np.random使用的RandomState实例。 在求solver是’sag’或’liblinear’时使用。

  1. solver :‘newton-cg’,‘lbfgs’,‘liblinear’,‘sag’,‘saga’,default:liblinear
    liblinear:使用了开源的liblinear库实现,内部使用了坐标轴下降法来迭代优化损失函数。
    lbfgs:拟牛顿法的一种,利用损失函数二阶导数矩阵即海森矩阵来迭代优化损失函数。
    newton-cg:也是牛顿法家族的一种,利用损失函数二阶导数矩阵即海森矩阵来迭代优化损失函数。
    sag:即随机平均梯度下降,是梯度下降法的变种,和普通梯度下降法的区别是每次迭代仅仅用一部分的样本来计算梯度,适合于样本数据多的时候。

    saga:线性收敛的随机优化算法。对于小型数据集,‘liblinear’是一个不错的选择,而’sag’和’saga’对于大型的更快。对于多类问题,只有’newton-cg’,‘sag’,'saga’和’lbfgs’处理多项损失;'liblinear’仅限于一项损失。 ‘newton-cg’,'lbfgs’和’sag’只处理L2惩罚,而’liblinear’和’saga’处理L1惩罚。“sag”和“saga”快速收敛仅在具有大致相同比例的要素上得到保证, 可以使用sklearn.preprocessing中的缩放器预处理数据。

  2. max_iter:int ,default:100

仅适用于newton-cg,sag和lbfgs求解器。 求解器收敛的最大迭代次数。

  1. multi_class:str,{‘ovr’, ‘multinomial’},default:‘ovr’

    ‘ovr’ :采用 one-vs-rest 策略,‘multinomial’:直接采用多分类逻辑回归策略。

    ​ 多类选项可以是’ovr’或’multinomial’。 如果选择的选项是’ovr’,那么二进制问题适合每个标签。 另外,最小化损失是整个概率分布中的多项式损失拟合。 不适用于liblinear解算器。

  2. verbose:int,default:0

对于liblinear和lbfgs求解器,将verbose设置为任何正数以表示详细程度。用于开启/关闭迭代中间输出的日志。

  1. warm_start:bool(True、False),default:False

如果为True,那么使用前一次训练结果继续训练,否则从头开始训练。对于liblinear解算器没用。

  1. n_jobs:int,default:1

如果multi_class =‘ovr’,则在对类进行并行化时使用的CPU数量。 无论是否指定’multi_class’,当solver设置为’liblinear’时,都会忽略此参数。 如果给定值-1,则使用所有CPU。

1.2 随机搜索 RandomizedSearchCV()

​ 网格搜索相当于暴力地从参数空间中每个都尝试一遍,然后选择最优的那组参数,这样的方法显然是不够高效的,因为随着参数类别个数的增加,需要尝试的次数呈指数级增长。有没有一种更加高效的调优方式呢?那就是使用随机搜索的方式,这种方式不仅仅高校,而且实验证明,随机搜索法结果比稀疏化网格法稍好(有时候也会极差,需要权衡)。参数的随机搜索中的每个参数都是从可能的参数值的分布中采样的。与网格搜索相比,这有两个主要优点:

  • 可以独立于参数数量和可能的值来选择计算成本。
  • 添加不影响性能的参数不会降低效率。

class sklearn.model_selection.``RandomizedSearchCV(estimator, param_distributions, ***, n_iter=10, scoring=None, n_jobs=None, refit=True, cv=None, verbose=0, pre_dispatch=‘2*n_jobs’, random_state=None, error_score=nan, return_train_score=False)

参数解释同GridSearchCV()函数

1.3 管道工作流

​ 当我们对训练集应用各种预处理操作时(特征标准化、主成分分析等等), 我们都需要对测试集重复利用这些参数,以免出现数据泄露(data leakage)。pipeline 实现了对全部步骤的流式化封装和管理(streaming workflows with pipelines),可以很方便地使参数集在新数据集(比如测试集)上被重复使用。

​ Pipeline可以将许多算法模型串联起来,比如将特征提取、归一化、分类组织在一起形成一个典型的机器学习问题工作流。主要带来两点好处:

  1. 直接调用fit和predict方法来对pipeline中的所有算法模型进行训练和预测。

  2. 可以结合grid search对参数进行选择。

Parameters

  • steps : 步骤:列表(list)
    被连接的(名称,变换)元组(实现拟合/变换)的列表,按照它们被连接的顺序,最后一个对象是估计器(estimator)。
  • memory:内存参数,Instance of sklearn.external.joblib.Memory or string, optional (default=None)
    属性,name_steps:bunch object,具有属性访问权限的字典
    只读属性以用户给定的名称访问任何步骤参数。键是步骤名称,值是步骤参数。或者也可以直接通过”.步骤名称”获取
    funcution

Pipline的方法都是执行各个学习器中对应的方法,如果该学习器没有该方法,会报错假设该Pipline共有n个学习器

  • transform():依次执行各个学习器的transform方法
  • fit():依次对前n-1个学习器执行fit和transform方法,第n个学习器(最后一个学习器)执行fit方法
  • predict():执行第n个学习器的predict方法
  • score():执行第n个学习器的score方法
  • set_params():设置第n个学习器的参数
  • get_param():获取第n个学习器的参数

举例:

我们要用 Pipeline 对训练集和测试集进行如下操作:

  • 先用 StandardScaler 对数据集每一列做标准化处理,(是 transformer)
  • 再用 PCA 将原始的 30 维度特征压缩的 2 维度,(是 transformer)
  • 最后再用模型 LogisticRegression。(是 Estimator)

(1) Pipeline

调用 Pipeline 时,输入由元组构成的列表,每个元组第一个值为变量名,元组第二个元素是 sklearn 中的 transformer 或 Estimator。

注意中间每一步是 transformer,即它们必须包含 fit 和 transform 方法,或者 fit_transform。
最后一步是一个 Estimator,即最后一步模型要有 fit 方法,可以没有 transform 方法。

然后用 Pipeline.fit对训练集进行训练,pipe_lr.fit(X_train, y_train)
再直接用 Pipeline.score 对测试集进行预测并评分 pipe_lr.score(X_test, y_test)

# 把所有的操作全部封在一个管道pipeline内形成一个工作流:
## 标准化+PCA+逻辑回归
from sklearn.preprocessing import StandardScaler
from sklearn.decomposition import PCA
from sklearn.linear_model import LogisticRegression
from sklearn.pipeline import Pipeline
pipe_lr = Pipeline([('sc', StandardScaler()),
                    ('pca', PCA(n_components=2)),
                    ('clf', LogisticRegression(random_state=1))
                    ])
pipe_lr.fit(X_train, y_train)
print('Test accuracy: %.3f' % pipe_lr.score(X_test, y_test))

(2) make_pipeline

from sklearn.preprocessing import StandardScaler
from sklearn.decomposition import PCA
from sklearn.linear_model import LogisticRegression
from sklearn.pipeline import make_pipeline
pipe_lr1 = make_pipeline(StandardScaler(),PCA(n_components=2),LogisticRegression(random_state=1))
pipe_lr1.fit(X_train,y_train)
y_pred1 = pipe_lr.predict(X_test)
print("Test Accuracy: %.3f"% pipe_lr1.score(X_test,y_test))
  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值