R语言:逻辑回归ROC曲线对角线分析过程及结果

之前我们讨论了使用ROC曲线来描述分类器的优势,有人说它描述了“随机猜测类别的策略”。

由Kaizong Ye,Liao Bao撰写

让我们回到ROC曲线来说明,考虑一个非常简单的数据集,其中包含10个观测值(不可线性分离)。

在这里我们可以检查一下,确实是不可分离的。

plot(x1,x2,col=c("red","blue")[1+y],pch=19)

×

roc曲线:接收者操作特征(receiver operating characteristic),roc曲线上每个点反映着对同一信号刺激的感受性。

针对一个二分类问题,将实例分成正类(postive)或者负类(negative)。但是实际中分类时,会出现四种情况(都是针对预测的类别来命名的).

(1)真正类(True Postive TP)(预测为正类,刚好预测的是正确的)

(2)假负类(False Negative FN)(预测为负类,只不过预测错了)

(3)假正类(False Postive FP)(预测为正类,只不过预测错了)

(4)真负类(True Negative TN)(预测为负类,刚好预测的是正确的)


横轴:负正类率(false postive rate FPR)特异度,划分实例中所有负例占所有负例的比例;(1-Specificity)

纵轴:真正类率(true postive rate TPR)灵敏度,Sensitivity(正类覆盖率)(又是召回率recall

由上表可得出横,纵轴的计算公式:

(1)真正类率(True Postive Rate)TPR: TP/(TP+FN),代表分类器预测的正类中实际正实例占所有正实例的比例。Sensitivity

(2)负正类率(False Postive Rate)FPR: FP/(FP+TN),代表分类器预测的正类中实际负实例占所有负实例的比例。1-Specificity

(3)真负类率(True Negative Rate)TNR: TN/(FP+TN),代表分类器预测的负类中实际负实例占所有负实例的比例,TNR=1-FPR。Specificity

假设采用逻辑回归分类器,其给出针对每个实例为正类的概率,那么通过设定一个阈值如0.6,概率大于等于0.6的为正类,小于0.6的为负类。对应的就可以算出一组(FPR,TPR),在平面中得到对应坐标点。随着阈值的逐渐减小,越来越多的实例被划分为正类,但是这些正类中同样也掺杂着真正的负实例,即TPR和FPR会同时增大。阈值最大时,对应坐标点为(0,0),阈值最小时,对应坐标点(1,1)。



考虑逻辑回归

reg = glm(y~x1+x2,data=df,family=binomial(link = "logit"))

我们可以使用我们自己的roc函数


 roc=function(s,print=FALSE){
Ps=(S<=s)*1
 
FP=sum((Ps==1)*(Y==0)/sum(Y==0)
 
TP=sum((Ps==1)*(Y==1)/sum(Y==1)
 
if(print==TRUE){
 
print(table(Observed=Y,Predicted=Ps))
 
 
vect=c(FP,TP)
 
names(vect)=c("FPR","TPR")
 

或R包

performance(prediction(S,Y),"tpr","fpr")

我们可以在这里同时绘制两个


视频

逻辑回归Logistic模型原理和R语言分类预测冠心病风险实例

探索见解

去bilibili观看

探索更多视频

因此,我们的代码在这里可以正常工作。让我们考虑一下对角线。第一个是:每个人都有相同的概率(例如50%)


points(V[1,],V[2,])

但是,我们这里只有两点:(0,0)和(1,1)。实际上,无论我们选择何种概率,都是这种情况

 
plot(performance(prediction(S,Y),"tpr","fpr"))
points(V[1,],V[2,])

R语言用逻辑回归、决策树和随机森林对信贷数据集进行分类预测

阅读文章


我们可以尝试另一种策略,例如“通过扔无偏硬币进行预测”。我们得到

 segments(0,0,1,1,col="light blue")

我们还可以尝试“随机分类器”,在其中我们随机选择分数

  S=runif(10)

更进一步。我们考虑另一个函数来绘制ROC曲线

y=roc(x) 
lines(x,y,type="s",col="red")

但是现在考虑随机选择的策略

 
for(i in 1:500){
S=runif(10)
V=Vectorize(roc.curve)(seq(0,1,length=251)
MY[i,]=roc_curve(x)

红线是所有随机分类器的平均值。它不是一条直线,我们观察到它在对角线周围的波动。

 
 
reg = glm(PRO~.,data=my,family=binomial(link = "logit"))
 
 
plot(performance(prediction(S,Y),"tpr","fpr"))
 
 
segments(0,0,1,1,col="light blue")

这是一个“随机分类器”,我们在单位区间上随机绘制分数

  segments(0,0,1,1,col="light blue")

如果我们重复500次,我们可以获得

 
for(i in 1:500){
S=runif(length(Y))
MY[i,]=roc(x)
}
lines(c(0,x),c(0,apply(MY,2,mean)),col="red",type="s",lwd=3)
segments(0,0,1,1,col="light blue")

因此,当我在单位区间上随机绘制分数时,就会得到对角线的结果。给定Y,我们可以绘制分数的两个经验累积分布函数

 
 
plot(f0,(0:(length(f0)-1))/(length(f0)-1))
 
lines(f1,(0:(length(f1)-1))/(length(f1)-1))

我们还可以使用直方图(或密度估计值)查看分数的分布

hist(S[Y==0],col=rgb(1,0,0,.2),
 probability=TRUE,breaks=(0:10)/10,border="white")
 

我们确实有一个“完美的分类器”(曲线靠近左上角)

有错误。那应该是下面的情况

在10%的情况下,我们可能会分类错误

更多的错误分类

最终我们有对角线


可下载资源

关于作者

Kaizong Ye拓端研究室(TRL)的研究员。

本文借鉴了作者最近为《R语言数据分析挖掘必知必会 》课堂做的准备。

​非常感谢您阅读本文,如需帮助请联系我们!

 
QQ在线咨询
售前咨询热线
15121130882
售后咨询热线
0571-63341498

关注有关新文章的微信公众号


永远不要错过任何见解。当新文章发表时,我们会通过微信公众号向您推送。

技术干货

最新洞察

This will close in 0 seconds