训练模型时,遇到不平衡的数据怎么办?

大家好,我是小寒。

原文链接

你是否曾经遇到过这样的问题:你的数据集中的正类样本非常小,以至于模型无法学习?

「在这种情况下,仅通过预测多数类就可以获得相当高的准确度,但无法捕获少数类。」

这样的数据集很常见,被称为「不平衡数据集。」

不平衡数据集是分类问题的一种特殊情况,其中类之间分布不均匀。通常,它们由两个类组成:多数(负)类和少数(正)类。

在不同的领域都会有这样的数据集,例如:

  • 「金融」:欺诈检测数据集的欺诈率通常约为 1%-2%
  • 「广告服务」
  • 「运输」/「航空公司」:飞机发生故障的概率也非常低。
  • 「医疗」:患者是否患有癌症的概率很低。

那么我们如何解决这些问题呢?

1、随机欠采样和过采样

处理高度不平衡的数据集的一种被广泛采用的方法是重采样。它包括从多数类中删除样本(欠采样)和 从少数类中添加更多样本(过采样)。

让我们首先创建一个不平衡的数据集。

from sklearn.datasets import make_classification
X, y = make_classification(
    n_classes=2, class_sep=1.5, weights=[0.9, 0.1],
    n_informative=3, n_redundant=1, flip_y=0,
    n_features=20, n_clusters_per_class=1,
    n_samples=100, random_state=10
)
X = pd.DataFrame(X)
X['target'] = y

我们现在可以使用以下方法进行随机过采样和欠采样:

num_0 = len(X[X['target']==0])
num_1 = len(X[X['target']==1]) print(num_0,num_1) #random undersample undersampled_data = pd.concat([X[X['target']==0].sample(num_1),X[X['target']==1]]) print(len(undersampled_data)) # random oversample oversampled_data = pd.concat([X[X['target']==0],X[X['target']==1].sample(num_0,replace=True)]) print(len(oversampled_data))

2、使用 imblearn 进行欠采样和过采样

imblearn 是 python 的一个包,用于解决不平衡的数据集。它提供了多种欠采样和过采样的方法。

a、使用 Tomek Links 进行欠采样

它提供的其中一种方法称为 Tomek Links,Tomek Links 是邻近的两个相反类的例子。

在这个算法中,我们最终从 Tomek Links 中删除了多数类别的元素,这为分类器提供了一个更好的决策边界。

「原理:如果有两个不同类别的样本,它们的最近邻都是对方,也就是A的最近邻是B,B的最近邻是A,那么A,B就是Tomek link。我们要做的就是将所有 Tomek link 都删除掉。那么一个删除 Tomek link 的方法就是,将组成 Tomek link 的两个样本,如果有一个属于多数类样本,就将该多数类样本删除掉。」

from imblearn.under_sampling import TomekLinks
tl = TomekLinks(return_indices=True, ratio='majority')
X_tl, y_tl, id_tl = tl.fit_sample(X, y)
b. 使用 SMOTE 进行过采样。

在 SMOTE(Synthetic Minority Oversampling Technique)中,我们在现有元素附近为少数类合成元素。

from imblearn.under_sampling import TomekLinks
tl = TomekLinks(return_indices=True, ratio='majority')
X_tl, y_tl, id_tl = tl.fit_sample(X, y)

imblearn 包中还有多种其他方法可用于欠采样(Cluster Centroids、NearMiss 等)和过采样(ADASYN 和 bSMOTE),你可以查看它们。

3、模型中的 class_weights

大多数机器学习模型都提供了一个名为 class_weights 参数。例如,在随机森林分类器中, 我们可以使用字典为少数类指定更高的权重。

from sklearn.linear_model import LogisticRegression
clf = LogisticRegression(class_weight={0:1,1:10})

我们来看一下它背后的细节。

在逻辑回归中,我们使用「交叉熵」计算每个样本的损失:

Loss = −ylog(p) − (1−y)log(1−p)

「在这种特殊形式中,我们对正类和负类赋予相同的权重。」

当我们将 class_weight 设置为class_weight = {0:1,1:20}时,后台的分类器会尝试最小化:

NewLoss = −20*ylog(p) − 1*(1−y)log(1−p)

「那么这里到底发生了什么?」

  • 如果我们的模型给出的概率为 0.3,并且我们对正样本进行了错误分类,则 NewLoss 的值为 -20 log(0.3) = 10.45

  • 如果我们的模型给出的概率为 0.7,并且我们错误分类了一个负例,则 NewLoss 的值是 -log(0.3) = 0.52

这意味着,在这种情况下,当模型错误地分类了一个少数正样本时,我们对模型的惩罚要高出大约 20 倍。

「我们如何计算 class_weights?」

没有一种方法可以做到这一点,这应该构建为「针对你的特定问题的超参数搜索问题。」

但是,如果你想使用 y 变量的分布来获取 class_weights,你可以使用 sklearn 来实现。

from sklearn.utils.class_weight import compute_class_weight
class_weights = compute_class_weight('balanced', np.unique(y), y)

4、改变你的评估指标

每当我们处理不平衡的数据集时,选择正确的评估指标非常重要。通常,在这种情况下,F1-Score 是我想要的「评估指标」

「那么它有什么帮助呢?」

让我们从一个二元预测问题开始。 「我们正在预测小行星是否会撞击地球。」

因此,我们创建了一个模型,「将整个数据集都预测为 “否”。」

「准确度是多少(通常是最常用的评估指标)?」

超过 99%,所以从准确率上看,这个模型还不错,但一文不值。

「现在,F1 score 是多少?」

正类的召回率是多少?它为零。因此 F1 分数也是 0。

简单来说, 「F1 score 在分类器的精度和召回率之间保持平衡」

你可以使用以下方法计算二元预测问题的 F1 score:

from sklearn.metrics import f1_score
y_true = [0, 1, 1, 0, 1, 1]
y_pred = [0, 0, 1, 0, 0, 1]
f1_score(y_true, y_pred)

5、其它

根据你的用例和你要解决的问题,其他各种方法可能会起作用:

a、收集更多数据

如果可以的话,这是你应该尝试的明确的事情。使用更多正面示例,获取更多数据将有助于你的模型从多数和少数类别的角度获得更多样化的视角。

b、将问题视为异常检测

你可能希望将分类问题视为异常检测问题。

「异常检测」 是通过与大多数数据显著不同而引起怀疑的稀有项目、事件或观察结果的识别。

c、基于模型

有些模型特别适合不平衡的数据集。

例如,在提升模型中,我们给在每次树迭代中被错误分类的案例赋予更多的权重。

#机器学习##深度学习##数据分析#
全部评论
学习是一种快乐
点赞 回复 分享
发布于 2022-10-11 17:47 河南

相关推荐

Yushuu:你的确很厉害,但是有一个小问题:谁问你了?我的意思是,谁在意?我告诉你,根本没人问你,在我们之中0人问了你,我把所有问你的人都请来 party 了,到场人数是0个人,誰问你了?WHO ASKED?谁问汝矣?誰があなたに聞きましたか?누가 물어봤어?我爬上了珠穆朗玛峰也没找到谁问你了,我刚刚潜入了世界上最大的射电望远镜也没开到那个问你的人的盒,在找到谁问你之前我连癌症的解药都发明了出来,我开了最大距离渲染也没找到谁问你了我活在这个被辐射蹂躏了多年的破碎世界的坟墓里目睹全球核战争把人类文明毁灭也没见到谁问你了😆
点赞 评论 收藏
分享
沉淀一会:1.同学你面试评价不错,概率很大,请耐心等待; 2.你的排名比较靠前,不要担心,耐心等待; 3.问题不大,正在审批,不要着急签其他公司,等等我们! 4.预计9月中下旬,安心过节; 5.下周会有结果,请耐心等待下; 6.可能国庆节前后,一有结果我马上通知你; 7.预计10月中旬,再坚持一下; 8.正在走流程,就这两天了; 9.同学,结果我也不知道,你如果查到了也告诉我一声; 10.同学你出线不明朗,建议签其他公司保底! 11.同学你找了哪些公司,我也在找工作。
点赞 评论 收藏
分享
评论
2
10
分享
牛客网
牛客企业服务