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

机器学习评价指标

作者: 不会忘的名字 | 来源:发表于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