我正在使用sklearn包中的LogisticRegression,并且有一个关于分类的快速问题。我为我的分类器建立了一条ROC曲线,结果证明我的训练数据的最佳阈值大约为0.25。我假设创建预测时的默认阈值是0.5。如何进行10倍交叉验证时,如何更改此默认设置以了解模型的准确度?基本上,我希望我的模型能够为大于0.25但不是0.5的任何人预测“1”。我一直在查看所有文档,我似乎无法到达任何地方。
提前感谢您的帮助。
答案 0 :(得分:3)
我想给出一个实际的答案
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
,可以发现recall
和precision
的分数正在降低。
但是,通过删除class_weight
参数,accuracy
会增加,但recall
分数会下降。
请参阅@接受的答案
答案 1 :(得分:1)
您可以更改阈值,但该阈值为0.5,以使计算正确。如果您有一个不平衡的集合,则分类如下图所示。
您会看到类别1的预期非常差。 1类占人口的2%。 在将结果变量平衡为50%至50%(使用过采样)后,0.5阈值到达了图表的中心。
答案 2 :(得分:0)
特殊情况:一维逻辑回归
使用以下公式来计算将样本X
标记为1
和标记为0
的区域的值。
from scipy.special import logit
thresh = 0.1
val = (logit(thresh)-clf.intercept_)/clf.coef_[0]
因此,可以使用以下更直接的方法来计算预测
preds = np.where(X>val, 1, 0)
答案 3 :(得分:0)
出于完整性考虑,我想提一下另一种基于scikit概率计算using binarize优雅地生成预测的方法:
import numpy as np
from sklearn.preprocessing import binarize
THRESHOLD = 0.25
# This probabilities would come from logistic_regression.predict_proba()
y_logistic_prob = np.random.uniform(size=10)
predictions = binarize(y_logistic_prob.reshape(-1, 1), THRESHOLD).ravel()
此外,我同意the considerations that Andreus makes,特别是2和3。请务必注意它们。
答案 4 :(得分:0)
def find_best_threshold(threshould, fpr, tpr):
t = threshould[np.argmax(tpr*(1-fpr))]
# (tpr*(1-fpr)) will be maximum if your fpr is very low and tpr is very high
print("the maximum value of tpr*(1-fpr)", max(tpr*(1-fpr)), "for threshold", np.round(t,3))
return t
如果您想要找到最佳的真实正值率和nagatuve率,可以使用此功能
答案 5 :(得分:0)
就我的算法而言还可以:
threshold = 0.1
LR_Grid_ytest_THR = ((model.predict_proba(Xtest)[:, 1])>= threshold).astype(int)
和:
print('Valuation for test data only:')
print(classification_report(ytest, model.predict(Xtest)))
print("----------------------------------------------------------------------")
print('Valuation for test data only (new_threshold):')
print(classification_report(ytest, LR_Grid_ytest_THR))