我有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))
我有以下问题
- LogisticRegression 是否适合这项工作?因为它在处理独热编码数据时表现良好。
- 它能处理连续数据吗?我认为可以。
- 我是否设置了 LogisticRegression 的任何参数不正确?您能建议一些更好的或更简洁的设置吗?
- 最后,我是否做错了什么?
输出
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.47weighted avg 0.80 0.90 0.85UndefinedMetricWarning: 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.65weighted avg 0.65 0.65 0.65
使用 SMOTE 和 LogisticRegression 的代码。
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.47weighted avg 0.87 0.58 0.67
回答:
你的数据似乎不平衡,从精确度和召回率表中可以看出,类别 1
占你总数据的近 90%
。解决类别不平衡问题的方法有很多,你可以参考这篇博客获取详细的解决方案。
解决这个问题的一个快速方法是为你的模型添加类别权重(目前你的代码中是默认值 None
),这意味着当模型在预测类别 0
时犯错时,你会对模型进行更多的惩罚,而不是类别 1
。你可以先将类别权重值从 None
更改为 balanced
,看看它的表现如何。
但与此同时,你也应该注意,添加类别权重也会影响类别 1
的性能,这基本上是一个你需要权衡的取舍问题。