【问题标题】:LogisticRegressionCV incorrectly predicting the labelsLogisticRegressionCV 错误地预测标签
【发布时间】:2020-04-17 15:11:22
【问题描述】:

我有 4 个连续变量 x_1 到 x_4,每个变量通过原始数据的最小-最大缩放分布在 [0, 1] 范围内。我正在使用 LogisticRegression() 将类的标签预测为“1”或“0”。

什么不工作?好吧,我的 LogisticRegression() 预测所有分类为“1”类型。

split = StratifiedShuffleSplit(n_splits=1, test_size=0.2, random_state=0)
for train_indices, test_indices in split.split(numerical_data, y):
    x_train = numerical_data[train_indices]
    y_train = y[train_indices]
    x_test  = numerical_data[test_indices]
    y_test  = y[test_indices]
reg = LogisticRegression()
reg.fit(x_train, y_train)
y_pred = reg.predict(x_test)
print(classification_report_without_support(y_test, y_pred))

我有以下问题

  1. Lo​​gisticRegression 是否适合这项工作?因为它可以很好地处理一次性编码数据。
  2. 它是否处理连续数据?我想是的。
  3. 我为 LogisticRegression 设置的任何参数是否不正确?你能推荐一些更好或更整洁的东西吗?
  4. 最后,我是不是做错了什么?

输出


              precision    recall  f1-score

           0       0.00      0.00      0.00
           1       0.90      1.00      0.95

    accuracy                           0.90
   macro avg       0.45      0.50      0.47
weighted avg       0.80      0.90      0.85

UndefinedMetricWarning: Precision and F-score are ill-defined and being set to 0.0 in labels with no predicted samples. Use `zero_division` parameter to control this behavior.
  _warn_prf(average, modifier, msg_start, len(result))

SMOTE + same settings for LogisticRegressionCV

              precision    recall  f1-score

           0       0.63      0.73      0.67
           1       0.68      0.57      0.62

    accuracy                           0.65
   macro avg       0.65      0.65      0.65
weighted avg       0.65      0.65      0.65

带有 LogisticRegression 的 SMOTE 代码。

os = SMOTE(random_state=0)
x_train, x_test, y_train, y_test = train_test_split(numerical_data, y, test_size=0.2, random_state=0)

os_data_x, os_data_y = os.fit_sample(x_train, y_train)
os_data_X = pd.DataFrame(data=os_data_x,columns=['x1', 'x2', 'x3', 'x4'] )
os_data_Y = pd.DataFrame(data=os_data_y,columns=['y'])

x_train, x_test, y_train, y_test = train_test_split(os_data_X, os_data_Y.values.ravel(), test_size=0.2, random_state=0)

reg.fit(x_train, y_train)

y_pred = reg.predict(x_test)
print(classification_report_without_support(y_test, y_pred))
Accuracy of classifier on test set: 0.71

              precision    recall  f1-score

           0       0.14      0.70      0.24
           1       0.95      0.57      0.71

    accuracy                           0.58
   macro avg       0.55      0.63      0.47
weighted avg       0.87      0.58      0.67

【问题讨论】:

    标签: machine-learning scikit-learn classification logistic-regression


    【解决方案1】:

    您的数据似乎不平衡,从精确召回表中我们可以看到1 类在您的总数据中贡献了接近90%。解决类不平衡问题有多种方法,详细解决方法可以参考这个blog

    解决此问题的一个快速解决方案是为您的模型添加类权重(到目前为止,它是您代码中的默认值 None),这基本上意味着当您的模型制作一个预测类0 比类1 的错误。首先,您可以将类权重值从 None 更改为 balanced 并查看其执行情况。

    但同时您应该注意,添加类权重也会对 1 类的性能造成影响,这基本上是您需要权衡的一个因素。

    希望这会有所帮助!

    【讨论】:

    • 您的建议确实很有帮助。在看到您的 cmets 之前,我发现 LogisticRegressionCV 性能不佳的原因不仅仅是数据不平衡,还有更多。我什至尝试添加班级权重,但没有太大帮助。我尝试了其他分类器,如 SVM 和 Perceptron,但性能同样糟糕。最后,我做了一个 hack (1) 采样与坏标签相同数量的“好”标签 (2) 通过随机调整现有数据对“坏”标签进行过采样。我很高兴看到一个名叫 Nitish Shukla 的人也有同样的想法,并且有一篇关于它的研究论文。
    • 还有一种叫做 SMOTE 的技术,您可能有兴趣探索一下。
    • 我已经编辑了原始帖子并添加了 SMOTE 的分类报告,其设置与 LogisticRegressionCV 相同。非常感谢您在理解本报告和进一步改进建议方面提供的帮助。
    • 我还有一个问题,如果我有一个不平衡的数据集,那么我应该不做 StratifiedShuffleSplit 吗?相反,我应该只是洗牌并进行 K 次弃牌,但要确保不要分层,对吗?我将单独尝试 KFold() 并专注于标签“0”或坏人的召回分数。
    • 据我所知,`StratifiedShuffleSplit` 在这种情况下比KFold 更适用,原因是,当你只使用KFold 时,可能会有一些您的数据折叠可能只包含来自多数类的样本,如果您要将模型拟合到这个数据折叠,那么它没有任何意义。而StratifiedShuffleSplit 将确保所有折叠的数据都包含其中的类,并且训练的模型将更有意义。
    猜你喜欢
    • 2020-09-22
    • 1970-01-01
    • 2012-11-25
    • 2017-03-07
    • 2020-12-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-02-16
    相关资源
    最近更新 更多