scikit-learn 中常用的评估模型

一,scikit-learn中常用的评估模型

1.评估分类模型


2.评估回归模型


二、常见模型评估解析:

对于二分类问题,可将样例根据其真实类别和分类器预测类别划分 为:( T,F 表示预测的正确与错误性, P,N 表示预测的正类和负类)
真正例( TruePositive TP ):真实类别为正例,预测类别为正例。
假正例( FalsePositive FP ):真实类别为负例,预测类别为正例。
假负例( FalseNegative FN ):真实类别为正例,预测类别为负例。
真负例( TrueNegative TN ):真实类别为负例,预测类别为负例
构建混淆矩阵( ConfusionMatrix :

识别精确度( accuracy
Accuracy=(TP+FN)/(TP+TN+FP+FN)×100%

准确率( precision ):
                                               
•召回率(recall):
                                       
F1 值: 精确度和召回率的调和平均
                                                                  

精确度和召回率都高时, F1 也会高. F1 1 时达到最佳值(完美的精确度和召回率),最差为 0 .在二元分类中, F1 测试准确度的量度。

classification_report 的主要参数:

主要参数: 
y_true:1维数组,或标签指示器数组/稀疏矩阵,目标值。 
y_pred:1维数组,或标签指示器数组/稀疏矩阵,分类器返回的估计值。 
labels:array,shape = [n_labels],报表中包含的标签索引的可选列表。 
target_names:字符串列表,与标签匹配的可选显示名称(相同顺序)。 
sample_weight:类似于shape = [n_samples]的数组,可选项,样本权重。 
digits:int,输出浮点值的位数.


from sklearn.metrics import classification_report
y_true = [0,1,2,2,1,0]
y_pred = [0,2,0,2,1,0]

target_names= ['class0','class1','class2']
reports = classification_report(y_true, y_pred, target_names=target_names)  #生成分类的指标的文本报告
print(reports)
#输出结果
#              precision    recall  f1-score   support
# 
#      class0       0.67      1.00      0.80         2    #support为真实label出现的次数
#      class1       1.00      0.50      0.67         2
#      class2       0.50      0.50      0.50         2
# 
# avg / total       0.72      0.67      0.66         6
真实值 预测值
0 0
1 2
2 0
2 2
1 1
0 0
先计算label 0:即reports的class0
计算precision准确率时,只看分类标签是 0 的预测值,如图有 3 个,再看其预测成功的个数 ,有2个,所以准确率为 0.67
计算recall召回率时:只看分类标签是0 的真实值,如图有2 个,再看其预测成功的个数, 有2 个,所以召回率为 1
结合p 和 r 计算 F1值

同理:计算label 1 和label 2  
1).回归模型评估:

1. 均方根误差( RootMean Squared Error RMSE
RMSE 是一个衡量回归模型误差率的常用公式。然而,它仅能比较误差是相同单位的模型

由于对误差 E 进行平方,加强了数值大的误差在指标中的作用,从而提高了指标的灵敏性。

2. 平均 绝对误差( Mean Absolute Error MAE)

3. 平均绝对百分误差( MeanAbsolute Percentage Error

一般认为 MAPE 小于 10 时,预测精度高。

•2)分类模型评估:
ROC-AUC 曲线

AUC 值为 ROC 曲线所覆盖的区域面积 , 显然 ,AUC 越大 , 分类器分类效果越好

AUC 的物理意义
假设分类器的输出是样本属于正类的 score (置信度),则 AUC 的物理意义为,任取一对(正、负)样本,正样本的 score 大于负样本的 score 的概率。

1.ROC 曲线:接受者操作特征( receiveroperating characteristic )曲线代表每个点反映着对同一个信号刺激的感受性。 ROC 曲线 AUC 常被用来评价一个二值分类器( binaryclassifier )的优劣


横轴 FPR 越大,代表预测正类中实际负类越多
纵轴 TPR 越大,代表预测正类中实际正类也越多
因此,曲线越靠近( 0,1 )点,越往对角线 45 度左上角偏,分类效果越好。

如何绘制 ROC 曲线



    当我们将threshold设置为10时,分别可以得到ROC曲线上的(0,0)(1,1)两个点。将这些(FPR,TPR)对连接起来,就得到了ROC曲线。当threshold取值越多,ROC曲线越平滑。

  其实,我们并不一定要得到每个测试样本是正样本的概率值,只要得到这个分类器对该测试样本的“评分值”即可(评分值并不一定在(0,1)区间)。评分越高,表示分类器越肯定地认为这个测试样本是正样本,而且同时使用各个评分值作为threshold。将评分值转化为概率更易于理解一些。

2.AUC Areaunder roc curve )在 ROC 曲线下的面积,度量分类模型的好坏。

由于 ROC 曲线一般都处于 y=x 这条直线的上方,所以 AUC 的取值范围在 0.5 1 之间。使用 AUC 值作为评价标准是因为很多时候 ROC 曲线并不能清晰的说明哪个分类器的效果更好,而作为一个数值,对应 AUC 更大的分类器效果更好
首先 AUC 值是一个概率值,当你随机挑选一个正样本以及一个负样本,当前的分类算法根据计算得到的 Score 值将这个正样本排在负样本前面的概率就是 AUC 值。当然, AUC 值越大,当前的分类算法越有可能将正样本排在负样本前面,即能够更好的分类。

判定 AUC 曲线的优劣:
. 90-1= very good (A)
.80-.90= good (B)
.70-.80= not so good (C)
.60-.70= poor (D)
.50-.60= fail (F)

3. 精度 - 召回率曲线 PRC precisionrecall   curve ):与 ROC 曲线不同的是: PRC 曲线是往右上角靠拢效果较好。

适用 场景:
1. 地震的预测
对于地震的预测,我们希望的是
RECALL 非常高,也就是说每次地震我们都希望预测出来。这个时候我们可以牺牲 PRECISION 。情愿发出 1000 次警报,把 10 次地震都预测正确了;也不要预测 100 次对了 8 次漏了两次。
2. 嫌疑人定罪
基于不错怪一个好人的原则,对于嫌疑人的定罪我们希望是非常准确的。及时有时候放过了一些罪犯(
recall 低),但也是值得的。

4. 如何避免过拟合:
拟合表现为在训练数据上的误差非常小,而在测试数据集上的误差反而增大。其中原因一般是模型过于复杂,过分去拟合数据的噪声和离群点,导致模型的泛化能力差,鲁棒性差。
常见的解决办法:增大数据集,对模型进行正则化。

5. 交叉验证:
K-Folds 交叉验证: K 层交叉验证是将原始数据随机分为 K 个部分,在 K 个部分中,选择 1 个作为测试集, K-1 个作为训练集。将实验重复 K 次,每次实验都从 K 个部分选择 1 个不同的作为测试集,最后对得到的 K 个实验结果取平均。
#coding=gbk
'''
Created on 2018年7月10日

@author: Administrator
'''

#交叉验证

#1.留出法:直接将原始的数据集变换成2类互斥的两类,一部分为训练集,另一部分为验证集、
#在sklearn中使用  train_test_split函数
from sklearn.model_selection import train_test_split
import numpy as np
from sklearn import svm     #支持向量机
from sklearn import datasets

iris = datasets.load_iris()     #加载鸢尾花数据集
print(iris.data.shape, iris.target.shape)   #(150, 4) (150,)

x_train, x_test, y_train, y_test = train_test_split(iris.data, iris.target, 
                                                    test_size = 0.2, random_state=666)  
#test_size 表示测试集所占的比例

print(x_train.shape, x_test.shape)       #(120, 4) (30, 4)
print(y_train.shape, y_test.shape)      #(120,) (30,)

svm_clf = svm.SVC(kernel='linear', C= 1).fit(x_train, y_train)
print(svm_clf.score(x_test, y_test))    #    1.0 百分之百的预测成功率

#2.交叉验证方法
from sklearn.model_selection import KFold
import numpy as np
x = np.array([[1,2],[3,4],[5,6],[7,8]])
y = np.array([1,2,3,4])

kf = KFold(n_splits=2,random_state=666)     #n_splits 是指将数据输出多少份
for train_index, test_index in kf.split(x):
    print('train_index:', train_index, 'test_index:',test_index)
# train_index: [2 3] test_index: [0 1]
# train_index: [0 1] test_index: [2 3]

#当n_splits = 3 时,输出如下:
# train_index: [2 3] test_index: [0 1]
# train_index: [0 1 3] test_index: [2]
# train_index: [0 1 2] test_index: [3]

    x_train, y_train = x[train_index],y[train_index]
    x_test , y_test = x[test_index], y[test_index]
print(x_train,' ',y_train)
print(x_test,' ',y_test)

#2.2 RepeatedKFold p次k折交叉验证,RepeatedKFold方法可以控制交叉验证的次数。n_repeats
from sklearn.model_selection import RepeatedKFold
x1 = np.array([[1,2],[3,4],[5,6],[7,8]])
y1 = np.array([1,2,3,4])

rk = RepeatedKFold(n_splits=2, n_repeats=2, random_state=666)
for train_index, test_index in rk.split(x1):
    print('train_index:',train_index,'test_index:', test_index)
# train_index: [0 2] test_index: [1 3]
# train_index: [1 3] test_index: [0 2]
# train_index: [2 3] test_index: [0 1]
# train_index: [0 1] test_index: [2 3]

#3 留一法  LeaveOneOut 
print('-----LeaveOneOut------')
from sklearn.model_selection import LeaveOneOut

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

loo = LeaveOneOut()
for train_index, test_index in loo.split(x2):
    print('train_index:',train_index, 'test_index:', test_index)
# train_index: [1 2 3 4] test_index: [0]
# train_index: [0 2 3 4] test_index: [1]
# train_index: [0 1 3 4] test_index: [2]
# train_index: [0 1 2 4] test_index: [3]
# train_index: [0 1 2 3] test_index: [4]    

#3.2 LeavePOut 留p法
#基本原理和留一法是一样的
from sklearn.model_selection import LeavePOut

lpo = LeavePOut(p=2)
for train_index, test_index in lpo.split(x2):
    print('train_index:',train_index, 'test_index:',test_index)
# train_index: [2 3 4] test_index: [0 1]
# train_index: [1 3 4] test_index: [0 2]
# train_index: [1 2 4] test_index: [0 3]        有10中取法
# train_index: [1 2 3] test_index: [0 4]
# train_index: [0 3 4] test_index: [1 2]
# train_index: [0 2 4] test_index: [1 3]
# train_index: [0 2 3] test_index: [1 4]
# train_index: [0 1 4] test_index: [2 3]
# train_index: [0 1 3] test_index: [2 4]
# train_index: [0 1 2] test_index: [3 4]    

#4.shuffleSplit 随机分配, 可以随机把数据打乱,然后分为训练集和测试集
print('------shufflesplit------')

from sklearn.model_selection import ShuffleSplit
ss = ShuffleSplit(n_splits=4, random_state = 666, test_size=0.4)
for train_index, test_index in ss.split(x2):
    print('train_index:',train_index,'test_index:',test_index)
# train_index: [1 2 4] test_index: [3 0]
# train_index: [0 2 1] test_index: [3 4]
# train_index: [0 2 3] test_index: [4 1]
# train_index: [1 2 4] test_index: [0 3]



参考:柚子皮blog

猜你喜欢

转载自blog.csdn.net/qq_40587575/article/details/80988088
今日推荐