首页 文章

sklearn LogisticRegression并更改分类的默认阈值

提问于
浏览
9

我正在使用sklearn包中的LogisticRegression,并且有一个关于分类的快速问题 . 我为我的分类器 Build 了一条ROC曲线,结果证明我的训练数据的最佳阈值大约为0.25 . 我假设创建预测时的默认阈值是0.5 . 如何进行10倍交叉验证时,如何更改此默认设置以了解模型的准确度?基本上,我希望我的模型能够为大于0.25但不是0.5的任何人预测“1” . 我一直在查看所有文档,我似乎无法到达任何地方 .

在此先感谢您的帮助 .

2 回答

  • 4

    这不是内置功能 . 您可以通过将LogisticRegression类包装在您自己的类中,并添加在自定义 predict() 方法中使用的 threshold 属性来实现它 .

    但是,一些警告:

    • 默认阈值实际为0. LogisticRegression.decision_function() 返回到所选分离超平面的有符号距离 . 如果您正在查看 predict_proba() ,那么您正在查看超平面距离的 logit() ,其阈值为0.5 . 但是计算成本更高 .

    • 通过选择像这样的"optimal"阈值,您正在利用信息后学习,这会破坏您的测试集(即,您的测试或验证集不再提供对样本外错误的无偏估计) . 因此,除非您仅在训练集上的交叉验证循环内选择阈值,否则可能会引起额外的过度拟合,然后将其与训练分类器一起使用您的测试集 .

    • 如果您遇到不 balancer 问题而不是手动设置阈值,请考虑使用 class_weight . 这应该迫使分类器选择远离严重感兴趣类的超平面 .

  • 2

    我想给出一个实际的答案

    from sklearn.datasets import make_classification
    from sklearn.model_selection import train_test_split
    from sklearn.linear_model import LogisticRegression
    from sklearn.metrics import accuracy_score, confusion_matrix, recall_score, roc_auc_score, precision_score
    
    X, y = make_classification(
        n_classes=2, class_sep=1.5, weights=[0.9, 0.1],
        n_features=20, n_samples=1000, random_state=10
    )
    
    X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.33, random_state=42)
    
    clf = LogisticRegression(class_weight="balanced")
    clf.fit(X_train, y_train)
    THRESHOLD = 0.25
    preds = np.where(clf.predict_proba(X_test)[:,1] > THRESHOLD, 1, 0)
    
    pd.DataFrame(data=[accuracy_score(y_test, preds), recall_score(y_test, preds),
                       precision_score(y_test, preds), roc_auc_score(y_test, preds)], 
                 index=["accuracy", "recall", "precision", "roc_auc_score"])
    

    通过将 THRESHOLD 更改为 0.25 ,可以发现 recallprecision 分数正在下降 . 但是,通过删除 class_weight 参数, accuracy 会增加,但 recall 分数会下降 . 请参阅@accepted答案

相关问题