我在构建处理不平衡数据(80:20)的机器学习分类器时有点迷茫。数据集有30列;目标是Label。我想预测主要类别。我试图重现以下步骤:
- 将数据划分为训练集和测试集
- 对训练集进行交叉验证
- 仅对测试折叠进行欠采样
- 在通过交叉验证选择模型后,对训练集进行欠采样并训练分类器
- 在未触及的测试集上估计性能(召回率)
我所做的如下所示:
y = df['Label'] X = df.drop('Label',axis=1) X.shape, y.shape X_train, X_test, y_train, y_test = train_test_split(X, y, test_size = 0.2, random_state = 12) X_train.shape, X_test.shape tree = DecisionTreeClassifier(max_depth = 5) tree.fit(X_train, y_train) y_test_tree = tree.predict(X_test) y_train_tree = tree.predict(X_train) acc_train_tree = accuracy_score(y_train,y_train_tree) acc_test_tree = accuracy_score(y_test,y_test_tree)
我对如何在训练集上进行交叉验证、在测试折叠上应用欠采样以及对训练集进行欠采样并训练分类器有一些疑问。你熟悉这些步骤吗?如果熟悉,我会很感激你的帮助。
如果我按以下方式做:
y = df['Label']X = df.drop('Label',axis=1)X.shape, y.shapeX_train, X_test, y_train, y_test = train_test_split(X, y, test_size = 0.2, random_state = 12)X_train.shape, X_test.shapetree = DecisionTreeClassifier(max_depth = 5)tree.fit(X_train, y_train)y_test_tree = tree.predict(X_test)y_train_tree = tree.predict(X_train)acc_train_tree = accuracy_score(y_train,y_train_tree)acc_test_tree = accuracy_score(y_test,y_test_tree)# CVscores = cross_val_score(tree,X_train, y_train,cv = 3, scoring = "accuracy")ypred = cross_val_predict(tree,X_train,y_train,cv = 3)print(classification_report(y_train,ypred))accuracy_score(y_train,ypred)confusion_matrix(y_train,ypred)
我得到以下输出
precision recall f1-score support -1 0.73 0.99 0.84 291 1 0.00 0.00 0.00 105accuracy 0.73 396macro avg 0.37 0.50 0.42 396weighted avg 0.54 0.73 0.62 396
我猜我在上面的代码中遗漏了一些东西或做错了什么。
数据样本:
Have_0 Have_1 Have_2 Have_letters Label1 0 1 1 10 0 0 1 -1 1 1 1 1 -10 1 0 0 11 1 0 0 11 0 0 1 -11 0 0 0 1
回答:
通常,创建交叉验证集的最佳方法是模拟你的测试数据。在你的情况下,如果我们要将数据分为3个集合(训练集、交叉验证集、测试集),最好的方法是创建具有相同真标签/假标签比例的集合。这是我在以下函数中所做的。
通过这种方式,我们得到了具有以下形状的集合(所有集合都具有相同的真标签/假标签比例):