微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Scikit-learn和Yellowbrick给出不同的分数

如何解决Scikit-learn和Yellowbrick给出不同的分数

我正在使用sklearn计算分类器的平均精度和roc_auc,并使用yellowbrick绘制roc_auc和精度调用曲线。问题在于,这些软件包在两个指标中给出的分数都不相同,我不知道哪个是正确的。

使用的代码

import numpy as np
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import train_test_split
from yellowbrick.classifier import ROCAUC
from yellowbrick.classifier import PrecisionRecallCurve
from sklearn.datasets import make_classification
from sklearn.metrics import roc_auc_score
from sklearn.metrics import average_precision_score

seed = 42

# provides de data
X,y = make_classification(n_samples=1000,n_features=2,n_redundant=0,n_informative=2,random_state=seed)

X_train,X_test,y_train,y_test = train_test_split(X,y,test_size=0.2,random_state=42)

clf_lr = LogisticRegression(random_state=seed)
clf_lr.fit(X_train,y_train)

y_pred = clf_lr.predict(X_test)
roc_auc = roc_auc_score(y_test,y_pred)
avg_precision = average_precision_score(y_test,y_pred)
print(f"ROC_AUC: {roc_auc}")
print(f"Average_precision: {avg_precision}")
print('='*20)

# visualizations
viz3 = ROCAUC(LogisticRegression(random_state=seed))
viz3.fit(X_train,y_train) 
viz3.score(X_test,y_test)
viz3.show()
viz4 = PrecisionRecallCurve(LogisticRegression(random_state=seed))
viz4.fit(X_train,y_train)
viz4.score(X_test,y_test)
viz4.show()

代码产生以下输出

从上面可以看出,度量标准根据程序包提供不同的值。在打印语句中是scikit-learn计算的值,而在图中显示的是带注释的由yellowbrick计算的值。

解决方法

由于您使用scikit-learn的predict方法,因此您的预测y_pred是硬类成员身份,而不是概率:

np.unique(y_pred)
# array([0,1])

但是对于ROC和Precision-Recall计算,应该不是;您传递给这些方法的预测应该是概率,而不是硬类。来自average_precision_score docs

y_score:数组,形状= [n_samples]或[n_samples,n_classes]

目标分数可以是肯定类别的概率估计值,置信度值或决策的非阈值度量(如 在某些分类器上由“ decision_function”返回)。

其中非阈值表示不是硬类roc_auc_scoredocs)也是如此。

使用以下代码对此进行更正,使scikit-learn结果与Yellowbrick返回的结果相同:

y_pred = clf_lr.predict_proba(X_test)     # get probabilities
y_prob = np.array([x[1] for x in y_pred]) # keep the prob for the positive class 1
roc_auc = roc_auc_score(y_test,y_prob)
avg_precision = average_precision_score(y_test,y_prob)
print(f"ROC_AUC: {roc_auc}")
print(f"Average_precision: {avg_precision}")

结果:

ROC_AUC: 0.9545954595459546
Average_precision: 0.9541994473779806

Yellowbrick在内部(透明地)处理所有这些计算细节,因此在此处进行的scikit-learn手动过程中不会出错。


请注意,在二进制情况下(如此处所示),您可以(并且应该)使用binary=True参数使图的混乱程度降低:

viz3 = ROCAUC(LogisticRegression(random_state=seed),binary=True) # similarly for the PrecisionRecall curve

且与直觉所期望的相反,至少对于二进制情况,score的{​​{1}}方法将返回AUC,而是准确性,如docs中所指定:

ROCAUC

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。