机器学习:模型性能评估与参数调优

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了机器学习:模型性能评估与参数调优相关的知识,希望对你有一定的参考价值。

模型性能评估的常用指标

真阳性(True Positive,TP):指被分类器正确分类的正例数据

真阴性(True Negative,TN):指被分类器正确分类的负例数据

假阳性(False Positive,FP):被错误地标记为正例数据的负例数据

假阴性(False Negative,FN):被错误地标记为负例数据的正例数据

 

精确率=TP/(TP+FP),TP+FP是模型预测的正样本总数,精确率衡量的是准确性;

召回率=TP/(TP+FN),TP+FN是真实的正样本总数,召回率衡量的是覆盖率;

F1=(2*精确率*召回率)/(精确率+召回率),F1值是精确率和召回率的综合评估

 

ROC曲线是常用的二分类场景的模型评估算法曲线

曲线的横轴是FP值,纵轴是TP值

曲线越接近于左上角就说明模型的效果越好

ROC更多是通过曲线的光滑程度以及曲线的斜率来获取模型内的信息

 

AUC值表示ROC曲线与横轴围起来的面积

AUC值越大表示模型的效果越好,AUC介于0到1之间,通常大于0.5;若大于0.9则证明模型性能不错

 

使用k折交叉验证评估模型性能

1.   holdout交叉验证

方法:将原始数据随机分为训练集、验证集两部分,利用训练集训练分类器,然后利用验证集验证分类器性能

优点:处理简单,只需随机把原始数据分为两组即可

缺点:

1)验证集分类准确率对原始数据的划分方法是敏感的,模型及参数缺乏鲁棒性。

2)该方法只用了部分数据进行模型的训练,无法充分利用完整样本的数据,易出现欠拟合的情况。

 

2.   k-fold交叉验证

训练集被不重复地划分(均分)为k份,将每个子集分别做一次验证集,其余的K-1组子集作为训练集,由此得到K个模型,这K个模型的分类准确率的平均数作为此K-CV下分类器的性能指标。

优点

1)对数据划分方法的敏感性较低,同时模型性能的评估基于k个子模型性能的均值,这使得模型性能的评估具有较小的偏差,准确性较高。

2)K-fold CV的计算成本适中

缺点: K的选取是一个Bias和Variance的trade-off。

 

代码示例:

from sklearn.model_selection import KFold

X = np.array([[1, 2], [3, 4], [1, 2], [3, 4]])

y = np.array([1, 2, 3, 4])

kf = KFold(n_splits=2)

train,test=kf.split(X)

print(‘train:‘,train)

print(‘test:‘,test)

out

train: (array([2, 3]), array([0, 1]))

test: (array([0, 1]), array([2, 3]))

 

3.   留一交叉验证(sklearn.model_selection.LeaveOneOutLOO

留一交叉验证是K折交叉验证的一个特例,此时K等于数据集样本数N,即每次只有一个样本用于测试,其余的N-1个样本作为训练集,所以LOO-CV会得到N个模型,这N个模型最终的验证集的分类准确率的平均数作为此下LOO-CV分类器的性能指标.当数据集较小时,可用LOO-CV。

优点:

1)它不受数据划分方法的影响,因为每一个数据都单独的做过测试集

2)几乎用到了所有的数据,保证了模型的bias更小 

缺点:计算成本高,因为需要建立的模型数量与原始数据样本数量相同

 

Stratified k-fold(分层k折交叉验证)

在分层k折交叉验证中,训练集被分成k份,每一份的类别比例尽可能相等。举例:若预测结果只有0、1两类,那么每一份训练集中的预测结果为0和1的样本数是尽可能相等的。

 

代码实现:

from sklearn.model_selection import StratifiedKFold

import numpy as np

X = np.array([[1, 2], [3, 4], [1, 2], [3, 4], [1, 2], [3, 4]])

y = np.array([0, 1, 0, 1, 0, 1])

skf = StratifiedKFold(n_splits=2,random_state=0)

train,test=skf.split(X, y)

print(‘train:‘,train)

print(‘test:‘,test)

输出

train: (array([4, 5]), array([0, 1, 2, 3]))

test: (array([0, 1, 2, 3]), array([4, 5]))

#索引4、5对应的预测值分别为0、1(0、1各占比50%);

#索引0、1、2、3对应的预测值分别为0、1、0、1(0、1各占比50%)

 

 

from sklearn.model_selection import cross_val_score

 

cross_val_score(estimator, X, y=None, groups=None, scoring=None, cv=None, n_jobs=1, verbose=0, fit_params=None, pre_dispatch=‘2*n_jobs’)

 

cv : 整数、交叉验证生成器或迭代器;

取值为None时, 默认3折交叉验证;

取值为integer时, 若模型为分类器且y为二值或多值变量时则选择StratifiedKFold,在其他情况下为Kfold交叉验证。

 

代码示例:

>>> from sklearn import datasets, linear_model

>>> from sklearn.model_selection import cross_val_score

>>> diabetes = datasets.load_diabetes()

>>> X = diabetes.data[:150]

>>> y = diabetes.target[:150]

>>> lasso = linear_model.Lasso()

>>> print(cross_val_score(lasso, X, y)) 

[ 0.33150734  0.08022311  0.03531764]

 

数据集分割原则

交叉验证在,原始数据集分割为训练集与测试集,必须遵守两个要点:

训练集中样本数量必须够多,一般至少大于总样本数的 50%。

两组子集必须从完整集合中均匀取样。

其中第 2 点特别重要,均匀取样的目的是希望减少 训练集/测试集 与完整集合之间的偏差(bias),但却也不易做到。一般的作法是随机取样,当样本数量足够时,便可达到均匀取样的效果。然而随机也正是此作法的盲点,也是经常是可以在数据上做手脚的地方。举例来说,当辨识率不理想时,便重新取样一组训练集 与测试集,直到测试集的辨识率满意为止,但严格来说便算是作弊。

 

以上是关于机器学习:模型性能评估与参数调优的主要内容,如果未能解决你的问题,请参考以下文章

性能评价

机器学习综述:机器学习中的模型评价模型选择与算法选择

文末送书调参太费力?自动化机器学习来帮你!

周志华 《机器学习初步》模型评估与选择

机器学习中调参调优思想以随机森林乳腺癌数据集为例子

机器学习基础——模型参数评估与选择