为什么 ROC 曲线不平滑?

机器算法验证 分类 scikit-学习
2022-03-31 03:34:00

以下是我在训练和验证数据集上从当前训练的模型中获得的一些性能结果。有些3类的训练样本不平衡。我使用sklearn.metrics来计算指标average='weighted'

训练和验证数据集的结果

以下是 ROC 曲线(第一个来自训练数据集,第二个来自验证数据集)。

训练数据集上的 ROC 曲线 验证数据集上的 ROC 曲线

第 0 类(记为C0)是背景类,第 1 类(记为C1)和第 2 类(记为C2)是正类。我想同时提高 和 的C1准确性C2ROC 曲线似乎并不平滑。这是一个有效的模型吗?我能从这些结果中得到什么?如何改进它们,尤其是解决类不平衡问题?任何意见表示赞赏。谢谢!

更新:源代码如下:

代码

1个回答

我知道这个问题已经存在两年了,并且在评论中给出了技术答案,但更详细的答案可能会帮助其他仍在为这些概念苦苦挣扎的人。

OP 的 ROC 曲线错误,因为他使用模型的预测值而不是概率。

这是什么意思?

训练模型时,它会学习输入变量和输出变量之间的关系。对于显示模型的每个观察,模型会了解给定观察属于某个类别的可能性有多大。当模型与测试数据一起呈现时,它会为每个看不见的观察猜测它属于给定类别的可能性有多大。

模型如何知道观察是否属于某个类? 在测试过程中,模型收到一个观察结果,估计有 51% 的概率属于 X 类。如何决定是否标记为 X 类?研究人员将设置一个阈值,告诉模型所有概率低于 50% 的观测值必须归类为 Y,所有高于此的观测值必须归类为 X。有时,研究人员希望设置更严格的规则,因为他们对正确更感兴趣预测像 X 这样的给定类别,而不是尝试预测所有类别。

因此,您训练的模型已经为您的每个观察估计了一个概率,但阈值最终将决定您的观察将被归类到哪个类别。

为什么这很重要?

ROC 创建的曲线为模型在不同阈值水平下的真阳性率和假阳性率分别绘制一个点。这有助于研究人员了解所有阈值水平的 FPR 和 TPR 之间的权衡。

因此,当您将预测值而不是预测概率传递给您的 ROC 时,您只会得到一个点,因为这些值是使用一个特定阈值计算的。因为该点是您的模型在一个特定阈值水平下的 TPR 和 FPR。

您需要做的是改用概率并让阈值变化。

像这样运行你的模型:

from sklearn.neighbors import KNeighborsClassifier
knn = KNeighborsClassifier()
knn_model = knn.fit(X_train,y_train)
#Use the values for your confusion matrix
knn_y_model = knn_model.predict(X=X_test)
# Use the probabilities for your ROC and Precision-recall curves
knn_y_proba = knn_model.predict_proba(X=X_test)

创建混淆矩阵时,您将使用模型的值

from mlxtend.plotting import plot_confusion_matrix
fig, ax = plot_confusion_matrix(conf_mat=confusion_matrix(y_test,knn_y_model),
                                show_absolute=True,show_normed=True,colorbar=True)
plt.title("Confusion matrix - KNN")
plt.ylabel('True label')
plt.xlabel('Predicted label'

创建 ROC 曲线时,您将使用概率

import scikitplot as skplt
plot = skplt.metrics.plot_roc(y_test, knn_y_proba)
plt.title("ROC Curves - K-Nearest Neighbors")