【发布时间】:2021-09-18 08:29:11
【问题描述】:
我有一个包含 1400 个 obs 和 19 列的数据集。 Target 变量具有值 1(我最感兴趣的值)和 0。类的分布显示不平衡 (70:30)。
使用下面的代码,我得到了奇怪的值(全为 1)。我不知道这是由于数据过度拟合/不平衡问题还是由于特征选择问题(我使用了 Pearson 相关性,因为所有值都是数字/布尔值)。 我认为遵循的步骤是错误的。
import numpy as np
import math
import sklearn.metrics as metrics
from sklearn.metrics import f1_score
y = df['Label']
X = df.drop('Label',axis=1)
def create_cv(X,y):
if type(X)!=np.ndarray:
X=X.values
y=y.values
test_size=1/5
proportion_of_true=y[y==1].shape[0]/y.shape[0]
num_test_samples=math.ceil(y.shape[0]*test_size)
num_test_true_labels=math.floor(num_test_samples*proportion_of_true)
num_test_false_labels=math.floor(num_test_samples-num_test_true_labels)
y_test=np.concatenate([y[y==0][:num_test_false_labels],y[y==1][:num_test_true_labels]])
y_train=np.concatenate([y[y==0][num_test_false_labels:],y[y==1][num_test_true_labels:]])
X_test=np.concatenate([X[y==0][:num_test_false_labels] ,X[y==1][:num_test_true_labels]],axis=0)
X_train=np.concatenate([X[y==0][num_test_false_labels:],X[y==1][num_test_true_labels:]],axis=0)
return X_train,X_test,y_train,y_test
X_train,X_test,y_train,y_test=create_cv(X,y)
X_train,X_crossv,y_train,y_crossv=create_cv(X_train,y_train)
tree = DecisionTreeClassifier(max_depth = 5)
tree.fit(X_train, y_train)
y_predict_test = tree.predict(X_test)
print(classification_report(y_test, y_predict_test))
f1_score(y_test, y_predict_test)
输出:
precision recall f1-score support
0 1.00 1.00 1.00 24
1 1.00 1.00 1.00 70
accuracy 1.00 94
macro avg 1.00 1.00 1.00 94
weighted avg 1.00 1.00 1.00 94
在数据不平衡、使用 CV 和/或抽样不足时,是否有人在构建分类器时遇到过类似问题?很高兴分享整个数据集,以防您可能想要复制输出。 我想问你一些明确的答案,可以告诉我步骤和我做错了什么。
我知道,为了减少过度拟合和处理平衡数据,有一些方法,例如随机抽样(过度/不足)、SMOTE、CV。我的想法是
- 在考虑不平衡的情况下拆分训练/测试数据
- 在火车组上执行 CV
- 仅在测试折叠上应用欠采样
- 借助 CV 选择模型后,对训练集进行欠采样并训练分类器
- 估计未触及测试集的性能 (f1-score)
正如这个问题中所概述的那样:CV and under sampling on a test fold。
我认为上述步骤应该是有意义的,但很高兴收到您对此的任何反馈。
【问题讨论】:
-
只是一个指针。我使用 SMOTE+ENN 作为过采样和欠采样的组合。这对我的数据产生了很好的效果。
-
非常感谢 Kabilan Mohanraj。我也会看看这种方法。我认为比较不同的方法会很好:)
-
我不会担心 70:30 比例的决策树不平衡,我会完全消除它。只需进行适当的交叉验证。您的报告说树对测试集进行了完美分类,这很奇怪,我会检查您那里所有 X_/y_ 变量的形状,以确保您得到预期的拆分。如果一切看起来都不错,您的观察中是否有可能有重复的数据?或者也许标签确实可以从观察中完全预测。
-
谢谢你,sturgemeister,你的建议。我将使用几个分类器,包括上面示例中的决策树,进行比较。我担心的是交叉验证。我认为我的预测出了点问题。我会排除重复数据(如果上述步骤 - 包括我拥有的所有内容 - 不要创建重复数据),但我会说预测采用了错误的字段
标签: python machine-learning scikit-learn cross-validation resampling