原理
ROC 全称是"受试者工作特征" (Receiver Operating Characteristic) 曲线。
我们根据学习器的预测结果对样例进行排序,按此顺序逐个把样本作为正例进行预测,每次计算出两个重要量的值,分别以它们为横、纵坐标作图'就得到了 "ROC 曲线"。
ROC 曲线的纵轴是"真正例率" (True Positive Rate,简称 TPR),横轴是"假正例率" (False Positive Rate,简称 FPR) ,两者分别定义为:
若一个学习器的 ROC 曲线被另 一个学习器的曲线完全"包住", 则可断言后者的性能优于前者;若两个学习器的 ROC 曲线发生交叉,则难以-般性地断言两者孰优孰劣 . 此时如果一定要进行比较, 则较为合理的判据是 比较 ROC 曲线下 的面积,即 AUC (Area Under ROC Curve).
代码演示
1. 先导入库
import numpy as np
import matplotlib.pyplot as plt
from sklearn.model_selection import train_test_split
2. 加载数据集,并在x-y坐标轴上画出来,样本数量200个,且是随机的,红点是目标类,正例,蓝点是负例。
# 显示点数
def load_pts():
dots = 200 # 点数
X = np.random.randn(dots,2) * 15 #建立数据集,shape(200,2),坐标放大15倍
# 建立X的类别
y = np.zeros(dots, dtype='int')
for i in range(X.shape[0]):
if X[i,0] > -15 and X[i,0] < 15 and X[i,1] > -15 and X[i,1] < 15: # 矩形框内的样本都是目标类(正例)
y[i] = 1
if 0 == np.random.randint(i+1) % 10: # 对数据随机地插入错误,20个左右
y[i] = 1 - y[i]
plt.scatter(X[np.argwhere(y==0).flatten(),0], X[np.argwhere(y==0).flatten(),1],s = 20, color = 'blue', edgecolor = 'k')
plt.scatter(X[np.argwhere(y==1).flatten(),0], X[np.argwhere(y==1).flatten(),1],s = 20, color = 'red', edgecolor = 'k')
plt.xlim(-40,40)
plt.ylim(-40,40)
plt.grid(False)
plt.tick_params(
axis='x',
which='both',
bottom=False,
top=False)
return X, y
X, y = load_pts()
plt.show()
3. 定义绘制模型拟合数据的效果图函数
def plot_model(X, y, clf):
plt.scatter(X[np.argwhere(y==0).flatten(),0],X[np.argwhere(y==0).flatten(),1],s = 20, color = 'blue', edgecolor = 'k')
plt.scatter(X[np.argwhere(y==1).flatten(),0],X[np.argwhere(y==1).flatten(),1],s = 20, color = 'red', edgecolor = 'k')
plt.xlim(-40,40)
plt.ylim(-40,40)
plt.grid(False)
plt.tick_params(
axis='x',
which='both',
bottom=False,
top=False)
r = np.linspace(-40,40,300)
s,t = np.meshgrid(r,r)
s = np.reshape(s,(np.size(s),1))
t = np.reshape(t,(np.size(t),1))
h = np.concatenate((s,t),1)
z = clf.predict(h)
s.shape = (np.size(r),np.size(r))
t.shape = (np.size(r),np.size(r))
z.shape = (np.size(r),np.size(r))
plt.contourf(s,t,z,colors = ['blue','red'],alpha = 0.2,levels = range(-1,2))
if len(np.unique(z)) > 1:
plt.contour(s,t,z,colors = 'k', linewidths = 2)
plt.show()
4. 训练模型
这里选用了三种模型,效果各异。
from sklearn.model_selection import train_test_split
from sklearn.ensemble import GradientBoostingClassifier
from sklearn.tree import DecisionTreeClassifier
from sklearn.svm import SVC
X_train, X_test, y_train, y_test = train_test_split(X,y,test_size=0.5) #将数据集拆分成训练集和测试集
#clf = DecisionTreeClassifier(max_depth=5, min_samples_leaf=4,
# min_samples_split=4)
#clf = GradientBoostingClassifier(max_depth=8, min_samples_leaf=10,
# min_samples_split=10)
clf = SVC(kernel='rbf', gamma=0.001, probability=True)
clf.fit(X_train, y_train)
plot_model(X, y, clf)
5. 评估模型
这里重点关注参数y_score,有两种方法得到:
- predict_proba给出测试集每个样本的[反例, 正例]的概率,计算roc_curve只需使用正例的概率。
- decision_function,这里不过多解释。
from sklearn.metrics import roc_curve
y_score = clf.predict_proba(X_test)
#_score = clf.decision_function(X_test)
#print(y_score)
fpr, tpr, _ = roc_curve(y_test, y_score[:,1])
#r, tpr, _ = roc_curve(y_test, y_score)
#print("fpr:",fpr)
#print("tpr:", tpr)
7.绘制ROC
由于样本是随机产生的,每次获取的样本都不一样,ROC也会略有差别。这个模型显然不是最优的,决策树模型会更好。
from sklearn.metrics import auc
def plot_roc_curve(fpr, tpr):
plt.figure()
lw = 2
roc_auc = auc(fpr,tpr)
plt.plot(fpr, tpr, color='darkorange',lw=lw,
label='ROC curve (area = %0.2f)' % roc_auc)
plt.plot([0,1], [0,1], color='navy', lw=lw, linestyle='--')
plt.xlim([0, 1.0])
plt.ylim([0, 1.05])
plt.xlabel('False Positive Rate')
plt.ylabel('True Positive Rate')
#plt.title('')
plt.legend(loc="lower right")
plt.show()
plot_roc_curve(fpr, tpr)
参考:《机器学习》周志华