单条PR曲线的绘制及相关参数(BEP,AP)的输出
# 姓 名:耿大哥讲算法
# 开发时间:2023/7/4 22:43
import matplotlib.pyplot as plt
from sklearn.metrics import precision_recall_curve,auc
import matplotlib;matplotlib.rc("font",family='Microsoft YaHei')
label=[0 ,1 ,0 ,1 ,1 ,1 ,0 ,0 ,1 ,0 ,0 ,1]
score=[0.2,0.5,0.8,0.6,0.4,0.2,0.9,0.7,0.6,0.5,0.1,0.3]
if label.count(0)==len(label):print('真实类别全为负!')
elif label.count(1)==len(label):print('真实类别全为正!')
else:
yuzhi=list(set(score))
yuzhi.sort(reverse=True)
if 1 not in yuzhi:yuzhi.insert(0,1)
else:pass
#不用工具包求Precision,Recall,yuzhi
Recall,Precision=[],[]
for k in yuzhi:
TP,FP=0,0
for i in range(len(label)):
if label[i]==1 and score[i]>=k:TP+=1
elif label[i]==0 and score[i]>=k:FP+=1
else:pass
Recall.append(TP/label.count(1))
if TP+FP==0:Precision.append(1)
else:Precision.append(TP/(TP+FP))
#用工具包求Precision,Recall,yuzhi
#Precision,Recall,yuzhi=precision_recall_curve(label,score)
X,Y,jiaodian_x=Recall,Precision,[]
for i in range(len(X)-1):
if Y[i]>X[i] and Y[i+1]==X[i+1]:jiaodian_x.append(X[i+1])
elif Y[i]>X[i] and Y[i+1]<X[i+1]:
if X[i]==X[i+1]:jiaodian_x.append(X[i])
else:jiaodian_x.append((X[i]*Y[i+1]-Y[i]*X[i+1])/(Y[i+1]-Y[i]-X[i+1]+X[i]))
elif Y[i]==X[i] and Y[i+1]>X[i+1]:jiaodian_x.append(X[i])
elif Y[i]==X[i] and Y[i+1]==X[i+1]:jiaodian_x.append(X[i+1]);jiaodian_x.append(X[i])
elif Y[i]==X[i] and Y[i+1]<X[i+1]:jiaodian_x.append(X[i])
elif Y[i]<X[i] and Y[i+1]>X[i+1]:
if X[i]==X[i+1]:jiaodian_x.append(X[i])
else:jiaodian_x.append((X[i]*Y[i+1]-Y[i]*X[i+1])/(Y[i+1]-Y[i]-X[i+1]+X[i]))
elif Y[i]<X[i] and Y[i+1]==X[i+1]:jiaodian_x.append(X[i+1])
else:pass
jiaodian_x=list(set(jiaodian_x))
plt.plot(X,Y,'b*-',label='PR曲线(AP='+str('%.3f'%auc(X,Y))+')')
for i in jiaodian_x:plt.text(i-0.05,i+0.05,'%.3f'%i)
plt.plot([0,1],[0,1],'*--',color='black',label='45°线')
plt.plot(jiaodian_x,jiaodian_x,'ro')
plt.xlabel('Recall');plt.ylabel('Precision');plt.legend();plt.show()