目录
2、对训练集进行划分并且创建分类器,并使用micro-average(微平均)来计算三个分类的总体精确率和召回率
一、P-R曲线
P-R曲线,是指以查准率(亦称准确率)为纵轴、查全率(亦称召回率)为横轴画出的曲线,反映了查准率随查全率的变化趋势,在机器学习中常用于二分类模型的评价及选择。
PR曲线(Precision-Recall Curve)是衡量二分类模型性能的一种评价指标。它是通过改变阈值,绘制出precision(精确率)和recall(召回率)两种指标对应的曲线。
精确率:预测为正类的数据中实际为正类的比例,公式为:Precision = TP / (TP + FP),其中TP表示真正例,FP表示假正例:
召回率:所有正样本中被预测为正的比例,公式为:Recall = TP / (TP + FN),其中TP表示真正例,FN表示假负例:
不同的阈值会导致精确率和召回率的变化,相应地,PR曲线会在precision-recall空间中绘制出各个阈值对应的点。曲线下面积(AUC-PR)越大,说明模型性能越好。PR曲线相对于ROC曲线,对于类别数据不平衡和少数类识别更加敏感。
绘制原理:
在训练集上训练出二分类模型后我们将测试集中的数据输入模型,这时我们可以计算得到这些数据属于某个类别的概率,将这些预测概率从小到大排列,然后将分类阈值依次设为[0,1]区间中不同的概率值并计算这时的准确率和召回率,最后将这些准确率和召回率在二维坐标系中连起来就得到了ROC曲线。
二、数据集内容
UCI Machine Learning Repository
三、代码
1、读取数据集
import numpy as np
import matplotlib.pyplot as plt
from sklearn import svm
from sklearn.preprocessing import label_binarize
from sklearn.metrics import precision_recall_curve,average_precision_score
from sklearn.multiclass import OneVsRestClassifier
#切分数据集
from sklearn.model_selection import train_test_split
filename = "iris copy.txt"
#打开文件
fr = open(filename)
#读取文件所有内容
arrayOLines = fr.readlines()
#得到文件行数
numberOfLines = len(arrayOLines)
#返回的NumPy矩阵,解析完成的数据:numberOfLines行,3列
returnMat = np.zeros((numberOfLines,4))
#返回的分类标签向量
classLabelVector = []
#行的索引值
index = 0
for line in arrayOLines:
#s.strip(rm),当rm空时,默认删除空白符(包括'/n','/r','/t',' ')
line = line.strip()
#使用s.split(str="",num=string,cout(str))将字符串根据'/t'分隔符进行切片。
listFromLine = line.split(' ')
#将数据1-4列提取出来,存放到returnMat的NumPy矩阵中,也就是特征矩阵
returnMat[index,:] = listFromLine[1:5]
#根据文本中标记的喜欢的程度进行分类,1代表setosa,2代表versicolor,3代表virginica
if listFromLine[-1] == '"setosa"':
classLabelVector.append(1)
elif listFromLine[-1] == '"versicolor"':
classLabelVector.append(2)
elif listFromLine[-1] == '"virginica"':
classLabelVector.append(3)
index += 1
#iris = load_iris()
#1-4列为特征,最后一列为标签
#划分特征和标签
y=classLabelVector
X=returnMat
#print(y)
#转化为类别标签
y=label_binarize(y,classes=[1,2,3])#标签二值化 y从第一列开始取所以初始值为1
n_classes=y.shape[1]
#print(y)
#增加噪声
random_state=np.random.RandomState(0)
n_samples,n_features=X.shape
#在原始x的列上n_feature*n倍级噪声增加n倍
X=np.c_[X,random_state.randn(n_samples,200*n_features)]
2、对训练集进行划分并且创建分类器,并使用micro-average(微平均)来计算三个分类的总体精确率和召回率
此处用的分类器为SVM分类器,SVM的主要思想是找到一个最优的超平面来分离数据,使得两个不同类别的样本点到该超平面的距离最大化。
在SVM中,样本点被表示为特征空间中的向量,每个向量有一个类别标签。SVM的目标是找到一个超平面,使得不同类别的样本点最大化到该超平面的距离。这个距离也被称为“边距”,SVM的分离器就是用来找到这个边距最大的超平面。
#训练。计算decision
X_train,X_test,y_train,y_test=train_test_split(X,y,test_size=0.8,random_state=random_state)#分割训练集
#创建二分类器
classifier=OneVsRestClassifier(svm.SVC(kernel="linear",probability=True,random_state=random_state))
#decision_function计算距离
#使用训练好的SVM分类器进行预测,返回每个样本属正类的可能性
y_score=classifier.fit(X_train,y_train).decision_function(X_test)
#print(y_score)
#对三个分类计算pre,recall,并用micro求平均
precision=dict()
recall=dict()
avg_pre=dict()#字典,表示每个类别或整体的平均准确率
for i in range(n_classes):
precision[i],recall[i],_=precision_recall_curve(y_test[:,i],y_score[:,i])
avg_pre[i]=average_precision_score(y_test[:,i],y_score[:,i])
precision["micro"],recall["micro"],_=precision_recall_curve(y_test.ravel(),y_score.ravel())
avg_pre["micro"]=average_precision_score(y_test,y_score,average="micro")
3、绘图
#绘制曲线
plt.clf()
plt.plot(recall["micro"],precision["micro"],label="micro_avg P-R(area={0:0.2f})".format(avg_pre["micro"]))
#label="micro_avg P-R(area={0:0.2f})".format(avg_pre["micro"])格式化字符串表示avg_pre的面积
#for i in range(n_classes):#n_classes类别数量
# plt.plot(recall[i],precision[i],label="P-R curve of class{0}(area={1:0.2f})".format(i,avg_pre[i]))
plt.xlim([0.0,0.1])
plt.ylim([0.0,1.01])
plt.legend(loc="lower right")#右下角添加图例
plt.show()
四、实验结果
五、小结
学习了有关PR曲线的知识。