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,所以稳定性也是逻辑斯蒂回归好.
网友评论