机器学习:模型性能评估与参数调优
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.LeaveOneOut,LOO)
留一交叉验证是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),但却也不易做到。一般的作法是随机取样,当样本数量足够时,便可达到均匀取样的效果。然而随机也正是此作法的盲点,也是经常是可以在数据上做手脚的地方。举例来说,当辨识率不理想时,便重新取样一组训练集 与测试集,直到测试集的辨识率满意为止,但严格来说便算是作弊。
以上是关于机器学习:模型性能评估与参数调优的主要内容,如果未能解决你的问题,请参考以下文章