美文网首页
机器学习评价指标

机器学习评价指标

作者: 不会忘的名字 | 来源:发表于2019-01-02 11:43 被阅读0次

1.机器学习常见评价指标

为什么要用AUC作为二分类模型的评价指标呢?为什么不直接通过计算准确率来对模型进行评价呢?答案是这样的:机器学习中的很多模型对于分类问题的预测结果大多是概率,即属于某个类别的概率,如果计算准确率的话,就要把概率转化为类别,这就需要设定一个阈值,概率大于某个阈值的属于一类,概率小于某个阈值的属于另一类,而阈值的设定直接影响了准确率的计算。使用AUC可以解决这个问题,接下来详细介绍AUC的计算。

  • AUC
    AUC是一个模型评价指标,用于二分类模型的评价。AUC是“Area under Curve(曲线下的面积)”的英文缩写,而这条“Curve(曲线)”就是ROC曲线。

ROC(Receiver Operating Characteristic)曲线,也就是受试者工作曲线,用于二分类判别效果的分析与评价.一般自变量为连续变量,因变量为二分类变量.


metric度量.png

然后,我们计算两个指标的值:
  True Positive Rate=TP/(TP+FN),代表将真实正样本划分为正样本的概率 真阳率
  False Positive Rate=FP/(FP+TN),代表将真实负样本划分为正样本的概率 伪阳率
  接着,我们以“True Positive Rate”作为纵轴,以“False Positive Rate”作为横轴,画出ROC曲线。类似下图:


类似图---ROC.png
  • Precision、Recall、F-measure、Accuracy


    metric度量.png
    其他评测标准图.png

2.ROC-AUC图形绘制

  • 导包
from sklearn.datasets import load_iris
from sklearn.model_selection import StratifiedKFold
from scipy import interp
import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline
  • 线性插值和分层抽样
    1.线性插值举例
# 线性插值
# 根据已有的数据的规律,推算出新的数据
x1 = np.linspace(0, 2*np.pi, 20)
y1 = np.sin(x1)
plt.scatter(x1, y1, s=100, marker='o')
随机生成20点图.png
x2 = np.linspace(0, 2*np.pi, 50)
# 通过线性插值来生成y2的值
y2 = interp(x2, x1, y1)
plt.scatter(x1, y1, s=100, marker='o')
plt.scatter(x2, y2, s=100, marker='d')
通过线性插值生成的50个点图.png
  • 代码部分
iris = load_iris()
data = iris.data
target = iris.target
# 分层取样
ss = StratifiedKFold(6)
for train,test in ss.split(data, target):
    # 返回的是训练数据和测试数据的索引值.
    print(train,  test)
    print('-----------------------------------------------')
# auc是一个二分类的评价指标.
# iris是三分类问题.所以我们要转化为2分类问题.
# 提取期中的两类数据即可.
cond = target != 2

X = data[cond]
y = target[cond]
display(X.shape, y.shape)

out:(100, 4)
    (100,)
# 加噪声, 为了auc能够体现出区别来.
data_ = np.hstack((X,np.random.randn(100,800)))
data_.shape
out:(100, 804)
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import auc, roc_curve
  • 逻辑斯蒂回归画出roc
# 画出每一层数据的roc曲线
ss = StratifiedKFold(6)
i = 1

# fpr_mean 一定是在0到1之间.
# 人为的创建fpr_mean
fpr_mean = np.linspace(0,1, 100)
# 定一个空列表去接收每一次分层训练的tpr_mean
tprs = []
# 定义一个空的列表用来接收每次分层训练的auc,用来计算方差
aucs = []

for train,test in ss.split(data_, y):
    logistic = LogisticRegression()
    logistic.fit(data_[train], y[train])
#     logistic.predict(data_[test]) # 这样写,预测的结果就是0和1,即类别.
#     print(logistic.predict_proba(data_[test]))
    y_ = logistic.predict_proba(data_[test])
    # 获取roc曲线的x,y轴数据
    fpr, tpr, thresholds = roc_curve(y[test], y_[:,1])
#     print(fpr, tpr, thresholds)
#     print('--------------------------')
    # 有了fpr和tpr我们可以算auc
    auc_ = auc(fpr, tpr)
    aucs.append(auc_)
#     print(auc_)
    # 画出roc曲线
    plt.plot(fpr, tpr, label='fold %d auc: %.4f' % (i, auc_), alpha=.5)
    i += 1
    
    # 根据已有的fpr和tpr的关系,用线性插值求出已有的fpr_mean对应的tpr_mean
    tpr_mean = interp(fpr_mean, fpr, tpr)
    # 接收tpr_mean
    tprs.append(tpr_mean)
  

# 计算tpr_mean 
tpr_mean = np.array(tprs).mean(axis=0)
# 强行人为的把tpr_mean的一个元素改成0,最后一个元素改成1
tpr_mean[0] = 0
tpr_mean[-1] = 1

# 希望计算平均auc
auc_mean = auc(fpr_mean, tpr_mean)
# auc的方差
auc_std = np.array(aucs).std()

# 画出auc_mean对应的roc曲线
plt.plot(fpr_mean, tpr_mean, label='mean auc: %.4f$\pm$%.2f' % (auc_mean, auc_std), c='g')

plt.legend()
逻辑斯蒂回归计算的roc曲线图.png
  • SVC画出的roc图
from sklearn.svm import SVC
# 画出svc的roc曲线
# 画出每一层数据的roc曲线
ss = StratifiedKFold(6)
i = 1

# fpr_mean 一定是在0到1之间.
# 人为的创建fpr_mean
fpr_mean = np.linspace(0,1, 100)
# 定一个空列表去接收每一次分层训练的tpr_mean
tprs = []
# 定义一个空的列表用来接收每次分层训练的auc,用来计算方差
aucs = []

for train,test in ss.split(data_, y):
    svc = SVC(probability=True)
    svc.fit(data_[train], y[train])
#     logistic.predict(data_[test]) # 这样写,预测的结果就是0和1,即类别.
#     print(logistic.predict_proba(data_[test]))
    y_ = svc.predict_proba(data_[test])
    # 获取roc曲线的x,y轴数据
    fpr, tpr, thresholds = roc_curve(y[test], y_[:,1])
#     print(fpr, tpr, thresholds)
#     print('--------------------------')
    # 有了fpr和tpr我们可以算auc
    auc_ = auc(fpr, tpr)
    aucs.append(auc_)
#     print(auc_)
    # 画出roc曲线
    plt.plot(fpr, tpr, label='fold %d auc: %.4f' % (i, auc_), alpha=.5)
    i += 1
    
    # 根据已有的fpr和tpr的关系,用线性插值求出已有的fpr_mean对应的tpr_mean
    tpr_mean = interp(fpr_mean, fpr, tpr)
    # 接收tpr_mean
    tprs.append(tpr_mean)
  

# 计算tpr_mean 
tpr_mean = np.array(tprs).mean(axis=0)
# 强行人为的把tpr_mean的一个元素改成0,最后一个元素改成1
tpr_mean[0] = 0
tpr_mean[-1] = 1

# 希望计算平均auc
auc_mean = auc(fpr_mean, tpr_mean)
# auc的方差
auc_std = np.array(aucs).std()

# 画出auc_mean对应的roc曲线
plt.plot(fpr_mean, tpr_mean, label='mean auc: %.4f$\pm$%.2f' % (auc_mean, auc_std), c='g')

plt.legend()
SVC的roc.png
  • 总结
    在这个数据集中,logistic平均auc 0.7777, svc 是0.6802,稳定性方面,logistic方差是0.15, svc是0.31,所以稳定性也是逻辑斯蒂回归好.

相关文章

网友评论

      本文标题:机器学习评价指标

      本文链接:https://www.haomeiwen.com/subject/fdzalqtx.html