控制 Scikit Learn 中逻辑回归的阈值

问题描述 投票:0回答:6

我正在高度不平衡的数据集上使用

LogisticRegression()
中的
scikit-learn
方法。我什至将
class_weight
功能改为
auto

我知道在逻辑回归中应该可以知道特定类对的阈值是多少。

是否可以知道

LogisticRegression()
方法设计的每个“一对多”类别的阈值是多少?

我在文档页面中没有找到任何内容。

默认情况下,无论参数值如何,它是否都会应用

0.5
值作为所有类的阈值?

python machine-learning scikit-learn classification logistic-regression
6个回答
36
投票

我使用了一个小技巧,不使用

model.predict(test_data)
,而使用
model.predict_proba(test_data)
。然后使用一系列阈值来分析对预测的影响;

pred_proba_df = pd.DataFrame(model.predict_proba(x_test))
threshold_list = [0.05,0.1,0.15,0.2,0.25,0.3,0.35,0.4,0.45,0.5,0.55,0.6,0.65,.7,.75,.8,.85,.9,.95,.99]
for i in threshold_list:
    print ('\n******** For i = {} ******'.format(i))
    Y_test_pred = pred_proba_df.applymap(lambda x: 1 if x>i else 0)
    test_accuracy = metrics.accuracy_score(Y_test.as_matrix().reshape(Y_test.as_matrix().size,1),
                                           Y_test_pred.iloc[:,1].as_matrix().reshape(Y_test_pred.iloc[:,1].as_matrix().size,1))
    print('Our testing accuracy is {}'.format(test_accuracy))

    print(confusion_matrix(Y_test.as_matrix().reshape(Y_test.as_matrix().size,1),
                           Y_test_pred.iloc[:,1].as_matrix().reshape(Y_test_pred.iloc[:,1].as_matrix().size,1)))

最好的!


24
投票

逻辑回归选择概率最大的类。在 2 个类别的情况下,阈值为 0.5:如果 P(Y=0) > 0.5,则显然 P(Y=0) > P(Y=1)。多类别设置也是如此:它再次选择概率最大的类别(参见例如 Ng 的讲座,底线)。

引入特殊阈值仅影响误报/漏报的比例(从而影响精度/召回率权衡),但它不是 LR 模型的参数。另请参阅类似的问题


22
投票

是的,Sci-Kit learn 使用 P>=0.5 的阈值进行二元分类。我将在已经发布的一些答案的基础上使用两个选项来检查这一点:

一个简单的选择是使用下面代码的 model.predict_proba(test_x) 段的输出以及类预测(下面的代码 model.predict(test_x) 段的输出)来提取每个分类的概率。然后,将类预测及其概率附加到您的测试数据帧中作为检查。

作为另一种选择,可以使用以下代码以图形方式查看不同阈值下的精确率与召回率。

### Predict test_y values and probabilities based on fitted logistic 
regression model

pred_y=log.predict(test_x) 

probs_y=log.predict_proba(test_x) 
  # probs_y is a 2-D array of probability of being labeled as 0 (first 
  column of 
  array) vs 1 (2nd column in array)

from sklearn.metrics import precision_recall_curve
precision, recall, thresholds = precision_recall_curve(test_y, probs_y[:, 
1]) 
   #retrieve probability of being 1(in second column of probs_y)
pr_auc = metrics.auc(recall, precision)

plt.title("Precision-Recall vs Threshold Chart")
plt.plot(thresholds, precision[: -1], "b--", label="Precision")
plt.plot(thresholds, recall[: -1], "r--", label="Recall")
plt.ylabel("Precision, Recall")
plt.xlabel("Threshold")
plt.legend(loc="lower left")
plt.ylim([0,1])

3
投票

我们可以使用包装器,如下所示:

model = LogisticRegression()
model.fit(X, y)

def custom_predict(X, threshold):
    probs = model.predict_proba(X) 
    return (probs[:, 1] > threshold).astype(int)
    
    
new_preds = custom_predict(X=X, threshold=0.4) 

0
投票

如果在 Pandas 版本 0.23.0+ 中使用 @jazib jamil 和 @Halee 的解决方案,请将

.as_matrix()
替换为
.values
(文档)

pred_proba_df = pd.DataFrame(model.predict_proba(x_test))
threshold_list = [0.05,0.1,0.15,0.2,0.25,0.3,0.35,0.4,0.45,0.5,0.55,0.6,0.65,.7,.75,.8,.85,.9,.95,.99]
for i in threshold_list:
    print ('\n******** For i = {} ******'.format(i))
    Y_test_pred = pred_proba_df.applymap(lambda x: 1 if x>i else 0)
    test_accuracy = metrics.accuracy_score(Y_test.values.reshape(Y_test.values.size,1),
                                           Y_test_pred.iloc[:,1].values.reshape(Y_test_pred.iloc[:,1].values.size,1))
    print('Our testing accuracy is {}'.format(test_accuracy))

    print(confusion_matrix(Y_test.values.reshape(Y_test.values.size,1),
                           Y_test_pred.iloc[:,1].values.reshape(Y_test_pred.iloc[:,1].values.size,1)))

0
投票

对于概率分类器(例如逻辑回归),最佳的贝叶斯估计器

ŷ = argmax_y P(Y = y | X)

即概率最高的预测类别。对于二元分类,这相当于使用概率 0.5 作为阈值。

© www.soinside.com 2019 - 2024. All rights reserved.