说您需要收集更多数据的评论可能是正确的。但是,如果您认为您的模型有足够的数据来学习有用的东西,您可以对少数类进行过度采样(或者可能对多数类进行采样,但这听起来像是过度采样的问题)。数据集中只有一个类使您的模型几乎不可能了解该类的任何内容。
这里有一些指向 python 中过采样和欠采样库的链接。著名的不平衡学习库很棒。
https://imbalanced-learn.org/en/stable/generated/imblearn.under_sampling.RandomUnderSampler.html
https://imbalanced-learn.org/en/stable/generated/imblearn.over_sampling.RandomOverSampler.html
https://imbalanced-learn.readthedocs.io/en/stable/generated/imblearn.over_sampling.SMOTE.html
https://imbalanced-learn.readthedocs.io/en/stable/auto_examples/over-sampling/plot_comparison_over_sampling.html#sphx-glr-auto-examples-over-sampling-plot-comparison-over-sampling-py
https://imbalanced-learn.org/en/stable/combine.html
您的案例听起来很适合 SMOTE。你还提到你想改变比率。 imblearn.over_sampling.SMOTE 中有一个名为 ratio 的参数,您可以在其中传递字典。您也可以使用百分比来执行此操作(请参阅文档)。
SMOTE 使用 K-Nearest-Neighbors 算法生成与采样数据不足的数据点“相似”的数据点。这是一种比传统过采样更强大的算法,因为当您的模型获得训练数据时,它有助于避免您的模型记忆特定示例的关键点的问题。相反,smote 创建了一个“相似”的数据点(可能在多维空间中),因此您的模型可以更好地学习泛化。
注意:不要对完整数据集使用 SMOTE,这一点至关重要。您必须仅在训练集上使用 SMOTE(即拆分后),然后在验证集和测试集上进行验证,以查看您的 SMOTE 模型是否优于其他模型。如果您不这样做,将会出现数据泄漏,并且您将获得一个与您想要的模型甚至不太相似的模型。
from collections import Counter
from imblearn.pipeline import Pipeline
from imblearn.over_sampling import SMOTE
import numpy as np
from xgboost import XGBClassifier
import warnings
warnings.filterwarnings(action='ignore', category=DeprecationWarning)
sm = SMOTE(random_state=0, n_jobs=8, ratio={'class1':100, 'class2':100, 'class3':80, 'class4':60, 'class5':90})
X_resampled, y_resampled = sm.fit_sample(X_normalized, y)
print('Original dataset shape:', Counter(y))
print('Resampled dataset shape:', Counter(y_resampled))
X_train_smote, X_test_smote, y_train_smote, y_test_smote = train_test_split(X_resampled, y_resampled)
X_train_smote.shape, X_test_smote.shape, y_train_smote.shape, y_test_smote.shape, X_resampled.shape, y_resampled.shape
smote_xgbc = XGBClassifier(n_jobs=8).fit(X_train_smote, y_train_smote)
print('TRAIN')
print(accuracy_score(smote_xgbc.predict(np.array(X_train_normalized)), y_train))
print(f1_score(smote_xgbc.predict(np.array(X_train_normalized)), y_train))
print('TEST')
print(accuracy_score(smote_xgbc.predict(np.array(X_test_normalized)), y_test))
print(f1_score(smote_xgbc.predict(np.array(X_test_normalized)), y_test))