量化百科

机器学习复习笔记之模型构建和优化过程

由ypyu创建,最终由ypyu 被浏览 68 用户

机器学习流水线

预处理过程

探索数据集、数据预处理、特征工程。

——见相关笔记

构建模型过程

包括构建模型的预处理,选择算法与模型优化,而模型优化涉及评估验证和调参。

预测过程

系统设计指导原则

快速搭建你的第一个系统,然后开始迭代。而不是妄图一口吃成个胖子,一下就能搭建出复杂而完美的系统。

不断地验证,不断地调试,不要妄图一下就写出一个完美的模型,而宁愿一开始比较粗糙,比较简单,但迅速实现,然后一步一步的误差分析和优化而使它变好。


构建模型的预处理过程

1、提取特征集和标签

labels = data['income']
features = data.drop('income', axis = 1)

2、切分训练集、验证集(开发集)、测试集

如果像一些kaggle竞赛之类的,别人已经为你切分了训练集和测试集,只给你训练集训练,那这时只需切分一次即可,将训练集再切分为训练集和验证集。但如果没有,那就可能需要切分两次。第一次切分一般就是留出法切出测试集;第二次切分则有两种方法:留出法和交叉验证法。

2.1 train、valid(dev)、test的区别

训练集用于训练模型(模型的学习),验证集用于调参(模型的优化)、测试集用于实践(模型的应用)

训练集 → 题解大全

验证集 → 模拟考试

测试集 → 高考

2.2 测试集大小的设置

一是取决于你拥有的数据量的大小,数据量越大,比例可以越小。

二是取决于对系统性能是否有要有置信度很高的评估,越靠谱的评估需要测试集越大。

小数据时代:6:2:2

百万数据,98:1:1

更多:99.5:0.25:0.25

2.3 具体切分方法

(1)留出法

from sklearn.model_selection import train_test_split 
X_train, X_test, y_train, y_test = train_test_split(features, labels, test_size = 0.2, random_state = 42)

(2)交叉验证

——充分利用数据集

kf = KFold(n_splits=2)

将 shuffle(洗牌) 参数设置为 true。以防止可能产生的问题:一类数据大都被归入了训练集,另一类数据大都被归入了测试集,因此导致算法的准确度很低。(比如说一堆邮件分别是甲和乙写的,而我们把甲写的都划入了训练集,把乙写的都划入了测试集)


设置评估指标

无论是选择不同的算法,还是不同的参数(调参),都需要基于一个评估指标。

选择不同评估指标,具体取决于我们要尝试解决的问题,比如分类问题和回归问题就有不同的评估指标。又比如有些数据存在样本不平衡问题, 有些问题旨在识别某一类数据,这时用简单的准确度(accuracy)指标就没有意义(天真预测器的对比)。

分类问题

true和false:真和假;代表你的判断是否正确。

positive和negative:阳、正和阴、负;代表你判断的类别。

**(1)查准率(命中率):**precision

precision=真正例/(真正例+假正例)——多做多错、少做少错

——我们只统计你选P并正确的题除以你选P的题,以此来判断你的分数。看你是否对某一类一击即命中。

适合:倾斜数据集。我们一般把数量较少的样本叫阳性样本(正例,positive),一般情况下我们也只关心阳性样本的预测结果。最常见的倾斜数据例子是癌症检查,得了癌症的不幸的人就是阳性样本,相对于健康的大众,他们是稀少的存在。

**(2)查全率(召回率、识别率):**recall

recall=真正例/(真正例+假负例)——宁可错杀、不可放过

——我们只统计你选P并正确的题除以正确答案应该是P的题,以此来判断你的分数。看你是否对把某一类全部识别出来。

适合:假阳性和假阴性这两种错误的重要性不同的场景。比如边境的安检会犯两种错误,不是恐怖分子却当作恐怖分子审讯(假阴),是恐怖分子却当作正常人放行(假阳),无疑假阳的错误更严重。再比如统计学中,第一类错误就是假阳性错误,即原假设本为真,却错误地拒绝,如前所述,这里的阳性(或正例)不是正确或错误、肯定或否定,而是我们所更关心的那个结果,拒绝原假设就是我们更关心的,因为这样才能证明备择假设正确。

(3)F分数

F分数将两个指标结合在一起变成一个指标,同时考虑精确率和召回率,叫做单一数字评估指标或单实数评估指标。

$F_{\beta}=\frac{(1+\beta^{2})\times p\times r}{(\beta^{2}\times p)+r}=\frac{1+\beta^{2}}{\frac{\beta^{2}}{r}+\frac{1}{p}}$

——其实就是两个指标的加权调和平均数,权重β越大表示召回率越重要,等于1时就是F1分数。

from sklearn.metrics import fbeta_score, accuracy_score
results = {}
results['acc'] = accuracy_score(y_true,predictions)
results['f'] = fbeta_score(y_true,predictions,beta=0.5)

(4)ROC 与 AUC

ROC(Receiver Operating Characteristic):接收者操作特征曲线。

AUC(Area Under Curve):ROC曲线下的面积。

为什么要使用 ROC和AUC:在实际的数据集中经常会出现类不平衡(class imbalance)现象,即负样本比正样本多很多(或者相反),而且测试数据中的正负样本的分布也可能随着时间变化。当测试集中的正负样本的分布变化的时候,其性能得分就会有很大的变动(想想如果是瞎蒙,全猜A或全猜B的情况),但ROC曲线能够保持不变。

ROC曲线的横坐标为FPR(false positive rate),纵坐标为TPR(true positive rate)。

考虑ROC曲线图中的四个点和一条线:

第一个点(0,1),即FPR=0, TPR=1,也意味着TNR=1,FNR=0,没有分类false的,所有的分类均正确。

第二个点(1,0),即FPR=1,TPR=0,同理这意味着所有分类均错误。

第三个点(0,0),即FPR=TPR=0,意味着TNR=FNR=1,该分类器预测所有的样本都为负样本(N)。

第四个点(1,1),该分类器预测所有的样本都为正样本(P)。

基于以上分析,可以说:ROC曲线越接近左上角,该分类器的性能越好

AUC是ROC曲线下的面积,显然数值不大于1。又由于ROC曲线一般都处于y=x这条直线的上方,所以AUC的取值范围一般在0.5和1之间。

使用AUC值作为评价标准是因为很多时候ROC曲线只是一个曲线,当两条曲线比较接近时不容易比较,而AUC作为一个数值,可以更直接的比较大小。

回归问题

(1)平均绝对误差(Mean Absolute Error):MAE=

$\frac{1}{m}\sum_{i=1}^{m}{|y_{predict}^{(i)}-y_{true}^{(i)}|}$

——有关平均绝对误差和如何在 sklearn 中使用它的更多信息,查看此处

(2)均方误差(Mean Square Error):MSE=

$\frac{1}{m}\sum_{i=1}^{m}{(y_{predict}^{(i)}-y_{true}^{(i)})^{2}}$

——误差平方和(Sum of Squares for Error,SSE)=MSE×m

(3)均方根误差(Root Mean Square Error):RMSE=√MSE

(4)均方根百分比误差(Root Mean Square Percentage Error ):RMSPE

——Kaggle比赛Rossmann Store Sales项目即用RMSPE作为评估销售预测的误差。就是在RMSE的基础上,令真实值与预测值之差再除以真实值,形成一个比例。

def metric_RMSPE(y_true, y_predict):
    y1 = np.array(y_predict)
    y2 = np.array(y_true)
    n = len(y_true)
    temp = np.square((y1 - y2)/y2).sum()
    score = np.sqrt(temp/n)
    return score

(5)R2分数=SSR/SST=1-SSE/SST

——指模型里可解释内容的占比。

  • 残差或误差平方和(预测值/估计值与真实值)

SSE(Sum of Squares for Error) = RSS (residual sum of squares)

  • 总的平方和(真实值与均值)

SST(Sum of Squares for Total) = TSS(total sum of squares)

  • 回归平方和(预测值与均值)

SSR(Sum of Squares for Regression) = ESS (explained sum of squares)

鉴于R^2局限性:当给模型增加自变量时,决定系数也随之逐步增大,但这种增大是因为自变量个数的增多引起的,而不一定真的是模型的拟合度变好。

所以有调整后的R2=1-(SSE/dfE)/(SST/dfT)

**区别:**R^2相当于是对所有的数据都会有一个相同的比较标准。也就是说你得到一个值0.9999,那就非常好(当然对不同的应用你对好的定义可能会不一样,比如某些你觉得0.6就够了,某些你要0.8)。而MAE和MSE就是数据相关了,范围可以非常大,你单纯根据一个值完全不知道效果怎么样。

相比于 R^2 作为拟合度的评价, RMSPE 更贴近误差的概念。而相比于 MSE 和 RMSE, RMSPE 计算的是一个误差率,这样就避免了真实值之间大小的不同而对误差产生的影响。 RMSPE 的缺点是,如果预测值是真实值的两倍以上,则 RMSPE 取值可能就会非常大,失去了评估的意义。所以理论上, RMSPE的取值范围是 0 到正无穷


选择算法

1、kaggle调查:最常使用的算法排名

logistic回归基于经典的回归理论,最大的优点是结果可解释,速度快,操作还简单(不用调参),所以在工业界应用最为广泛(第1)。

DT的输出结果可以进行可视化,也易于理解,在特征不多时效果也很好,应用也很多。(第2)

DT有稳定性差、易过拟合等问题,而各种基于树的算法不同程度解决了这些问题,成为在传统机器学习中比较强大的算法。(RF第3,集成方法第6,GBM第8)

神经网络、深度学习随着大数据的兴起,在CV/NLP等领域应用越来越广泛(NN第4,CNN第9,RNN第10)。

贝叶斯模型是与别的不同的生成式模型,有其自己的应用领域(第5)。

SVM的应用与神经网络、深度学习有所重合,在后者的冲击下有些失势(第7)。

HMM(隐马尔可夫模型)的应用与RNN有些重合(第13)

2、监督学习的算法选择思路

(1)看问题类型:是分类还是回归?

(2)看准确度要求

(3)看处理速度要求

(4)看调参难度

调参容易:logistic回归(不需调参,除非要正则化)

调参困难:XGBoost、神经网络及深度学习

(5)是否有局部最优问题

局部最优问题:神经网络、DT

无局部最优问题:logistic回归、SVM、NB

(6)是否易于理解、解释

简单:logistic回归、NB、DT

复杂:神经网络及深度学习(黑箱)

(7)特征数量

适合多特征:NB、神经网络及深度学习

适合少特征:DT(多特征容易过拟合)、RF(也只有几十维)

(8)数据规模

要大数据:神经网络、DT、集成学习

要小数据:logistic回归、SVM、NB

(9)是否容易过拟合

容易过拟合:DT、神经网络

不易过拟合:logistic回归、NB、RF

(10)是否需要特征缩放

需要缩放的:logistic回归、SVM、K均值聚类

不需要缩放的:决策树、NB

(11)缺失值较多

抗缺失能力强:DT、NB(?)

抗缺失能力弱:SVM

(12)噪声、异常值较多

抗干扰能力强:NB、神经网络

抗干扰能力弱:SVM、DT

3、其他参考:


模型优化(调参)

模型优化实际就是一个调参的过程,在使用各种模型优化策略时,不可避免的需要设定各种超参数,通过设置一个最佳超参数达到模型的最佳性能。

1、模型优化的目标:降低偏差与方差,避免欠拟合和过拟合

我们希望最优的模型不仅可以很好地拟合训练数据,而且有较好的泛化能力,也就是说训练误差和泛化误差都小,即同时具有较小的偏差(bias)和方差(variance)。偏差过大就是欠拟合,说明模型并没有很好地学到数据的信息;方差过大就是过拟合,说明模型并没有把在训练集数据上学到的东西很好地用到测试集上。

2、如何衡量偏差和方差/如何衡量

法(1):设定一个最优误差(贝叶斯误差),将最优误差、训练集误差、验证集误差三者进行对比。

比如三者分别为1/2/7,妥妥的方差过大;比如三者为1/10/11,妥妥的偏差过大。

——一般将人类水平作为贝叶斯误差,否则就需要自己手动设置一个基准(benchmark)。

法(2):通过学习曲线(准确率和数据规模的关系)和模型复杂度曲线(准确率和模型复杂度的关系)来看。

from sklearn.learning_curve import learning_curve # sklearn 0.17 
from sklearn.model_selection import learning_curve # sklearn 0.18 
learning_curve(estimator, X, y, cv=cv, n_jobs=n_jobs, train_sizes=train_sizes)

参数说明:

estimator是我们正在用来预测的模型,cv是交叉验证生成器,例如KFold();

train_sizes是依次用多少数量的训练数据来生成曲线。比如 train_sizes = np.linspace(.1,1.0,10),就是生成[ 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1.]的数组。这里是一个比例。比如你的总训练集是1000,kf = KFold(n_splits=3),那么就是把总训练数据分三份,三分之一为验证集,三分之二(666)为训练集,那么就是从0.1*666到1*666为横轴的刻度。

这个参数的意义:画学习曲线时,一口一口喂数据,喂一口,得到score,画点,最后连点成线。既然这样,怎么决定这个数组的数量呢,你中意,你喜欢光滑点,大口喂,喜欢波澜点,小口喂。

scoring参数设置一个评分函数(比如accuracy和F1)

学习曲线

模型复杂度曲线

3、解决方法

(1)降低偏差减少欠拟合

更多的特征、不同的模型和参数(复杂度升高)

(2)降低方差减小过拟合

更多的数据、不同的模型和参数(复杂度降低)、正则化

法1:正则化

即将前面一直说的代价函数(损失函数、风险函数)中加入一个正则化项。以线性回归为例:

$J(w)=\frac{1}{2m}\sum_{i=1}^{m}{L(f(x^{(i)}),y^{(i)})}+\frac{1}{2m}\lambda||w||_{2}^{2}$

这时的代价函数又叫结构风险函数,前面的部分叫做经验风险或经验损失(机器学习的训练过程类比人类的经验式学习)。λ叫做正则化参数,||w||是范数,其下标为2代表是L2范数(欧几里得距离),所以叫L2正则化。(加平方为了消去根号,便于计算,并且增大惩罚力度)

而L1正则化用曼哈顿距离,即绝对值。用L1可能造成有些w为0的情况(造成稀疏)。

神经网络中,多了层数的概念,正则化项略有不同,对于每一层都有一个参数矩阵:

第l层有n[l]个节点就需要n[l]个方程,每个方程都有n[l-1]个参数(对应上一层的输出)。

上式叫做弗罗贝尼乌斯范数(Frobenius norm)。

带正则化项的目标函数进行梯度下降,相当于每次迭代都比原来减少的更多,所以L2正则化叫又权重衰减。

无λ不能起到正则化作用,λ过大则会导致w过小(即压缩权重,但压缩过大会导致很多w被设置为0,可理解为删掉神经网络中的部分node,使得神经网络过于简单),倾向于欠拟合。所以找到合适的中间值,才能实现 just right。

法2:调参

  • **手动调参:**参考经验、其他人的成果。

  • 使用sklearn中网格调参,暴力搜索最佳参数组合

    from sklearn.model_selection import GridSearchCV from sklearn.metrics import make_scorer

    建立模型

    clf =

    以字典格式创建待调参数的列表

    parameters = {}

    自定义评估标准(可选)

    scorer = make_scorer(fbeta_score,beta=0.5)

    交叉验证(可选)

    cross_validator = KFold()

    创建网格搜索器

    grid_obj = GridSearchCV(clf, parameters, scoring=scorer, cv=cross_validator)

    用训练数据拟合以找到最佳参数

    grid_obj.fit(X_train, y_train)

    获取具有最佳参数的模型

    best_reg = grid_obj.best_estimator_

    用此模型预测结果

    val_predictions = best_clf.predict(X_val)

因为 sklearn 中 GridSearchCV 遍历所有给定的参数组合。所以内存占用高,运算速度慢。在实践中还有 RandomizedSearchCV 也可以使用,并且效果还不错。可以参考这篇文章论文

4、深度学习的优化策略

——更多神经网络的优化策略见相关笔记

对于传统机器学习算法,常常面临方差和偏差两者的权衡(二者负相关),但对于深度神经网络算法和大数据,我们可能做到降低一方的同时不影响另一方(这可能是深度学习对传统监督学习的其中一个提升)。

这就是所谓**正交化(orthogonalization)**的优化策略。

——正交意味着互成90度,比如电视机,一个按钮对应一个功能,互不影响。

但是,深度学习虽然可以很多方法来优化模型,但同时也有代价,就是很多方法都会附带着超参数,所以用的优化方法越多,需要调的超参数越多。

吴恩达推荐一个系统化的步骤,先通过增加网络的层数(深度)、增加训练时长以降低偏差,再通过增加数据、正则化等方式降低方差,然后不断循环这个过程。

比如你希望有一组独立的方法可以分别提升训练集、验证集(开发集)、测试集上的表现,而能够互不影响,这样就不会出现类似需要平衡偏差和方差的情况了。

提升训练集表现:更大的神经网络、优化算法

提升验证集表现:更大的训练集、正则化

提升测试集表现:更大的验证集

但像early stopping就会同时影响训练集和验证集,这种方法就没那么正交化了。

5、其他参考

维基百科 https://en.wikipedia.org/wiki/Bias%E2%80%93variance_tradeoff

华盛顿大学机器学习课程 https://www.coursera.org/learn/ml-regression/home/week/3

Scott Fortmann-Roe 撰写的**这篇文章**。

\

标签

数据预处理特征工程机器学习
评论
  • auc怎么在这个平台实现