处理不平衡数据集的策略

在许多实际应用中,收集的数据往往是不平衡的,即目标类别的样本数量并不均等。例如,在个人贷款分类问题中,很容易获得“未批准”的数据,而“批准”的数据则相对较少。这种不平衡会导致模型倾向于多数类,从而降低模型的预测能力。此外,不平衡数据还会导致II型错误的增加,在典型的二元分类问题中尤为明显。这种挑战不仅局限于机器学习模型,计算机视觉自然语言处理领域也同样存在。通过使用不同的技术可以有效处理这些问题。本文将简要介绍各种数据增强方法,而不深入技术细节。

机器学习中的不平衡数据

处理类别不平衡的主要方法是上采样(过采样)和下采样(欠采样)。这些采样过程仅应用于训练集,而不改变验证和测试数据。Python中的imbalanced-learn库可以帮助实现数据重采样。上采样是将少数类的合成数据点注入数据集的过程,使得两个标签的数量几乎相同。这种平衡过程可以防止模型倾向于多数类,同时保持目标类别之间的边界不变。然而,上采样机制会因为额外的信息而引入偏差。

# 导入imbalanced-learn库 from imblearn.over_sampling import SMOTENC oversample = SMOTENC(categorical_features=[0,1,2,3,4,9,10], random_state = 100) X, y = oversample.fit_resample(X, y)

数据复制是一种上采样方法,它随机选择对应于少数类的现有数据点并进行复制。

from sklearn.utils import resample maxcount = 332 train_nonnull_resampled = train_nonnull[0:0] for grp in train_nonnull['Loan_Status'].unique(): GrpDF = train_nonnull[train_nonnull['Loan_Status'] == grp] resampled = resample(GrpDF, replace=True, n_samples=int(maxcount), random_state=123) train_nonnull_resampled = train_nonnull_resampled.append(resampled)

下采样是一种减少多数类训练样本数量的机制。它有助于平衡目标类别的数量。通过移除收集的数据,可能会丢失大量有价值的信息。

from imblearn.under_sampling import TomekLinks undersample = TomekLinks() X, y = undersample.fit_resample(X, y)

基于质心的算法试图在多数类中找到同质聚类,并仅保留质心。这将减少多数类的大部分标签。它利用了KMeans聚类中使用的逻辑,但会浪费大量有用信息。

计算机视觉中的不平衡数据

对于图像和文本输入等非结构化数据,上述平衡技术将无效。在计算机视觉中,模型的输入是图像中像素的张量表示。因此,随机更改像素值(以增加更多输入记录)可能会完全改变图片的含义。有一种称为数据增强的概念,即图像经过大量变换,但仍然保持含义不变。

各种图像变换包括缩放、裁剪、翻转、填充、旋转、亮度、对比度和饱和度级别的变化。通过这样做,只需一张图像,就可以创建一个庞大的图像数据集。

from keras.preprocessing.image import ImageDataGenerator, array_to_img, img_to_array, load_img datagen = ImageDataGenerator( rotation_range=40, width_shift_range=0.2, height_shift_range=0.2, shear_range=0.2, zoom_range=0.2, horizontal_flip=True, fill_mode='nearest') img = load_img('images/0.jpg') x = img_to_array(img) x = x.reshape((1,) + x.shape) print(x.shape) i = 0 for batch in datagen.flow(x, batch_size=1, save_to_dir='preview', save_prefix='vehichle', save_format='jpeg'): i += 1 if i > 19: break

整个代码以及预训练模型可以在GitHub仓库中找到。

自然语言处理中的不平衡数据

自然语言处理模型处理的是文本等序列数据,当前数据与之前的数据具有时间依赖性。由于文本输入属于非结构化数据,以不同的方式处理这些场景。例如,如果考虑一个工单分类语言模型,其中IT工单需要根据输入文本中出现的单词序列分配给不同的组。

from googletrans import Translator translator = Translator() def German_translation(x): german_translation = translator.translate(x, dest='de') return german_translation.text def English_translation(x): english_translation = translator.translate(x, dest='en') return english_translation.text x = German_translation("warning for using windows disk space") English_translation(x) import numpy as np from tensorflow import keras from sklearn.utils.class_weight import compute_class_weight y_integers = np.argmax(raw_y_train, axis=1) class_weights = compute_class_weight('balanced', np.unique(y_integers), y_integers) d_class_weights = dict(enumerate(class_weights)) history = model.fit(input_final, raw_y_train, batch_size=32, class_weight = d_class_weights, epochs=8,callbacks=[checkpoint,reduceLoss],validation_data =(val_final, raw_y_val), verbose=1)
沪ICP备2024098111号-1
上海秋旦网络科技中心:上海市奉贤区金大公路8218号1幢 联系电话:17898875485