关于人工智能:应对机器学习中类不平衡的10种技巧

47次阅读

共计 6728 个字符,预计需要花费 17 分钟才能阅读完成。

作者 |GUEST BLOG
编译 |Flin
起源 |analyticsvidhya

总览

  • 相熟类失衡
  • 理解解决不均衡类的各种技术,例如 -

    • 随机欠采样
    • 随机过采样
    • NearMiss
  • 你能够查看代码的执行在我的 GitHub 库在这里

介绍

当一个类的察看值高于其余类的察看值时,则存在类失衡。

示例:检测信用卡欺诈交易。如下图所示,欺诈交易大概为 400,而非欺诈交易大概为 90000。

类不均衡是机器学习中的常见问题,尤其是在分类问题中。不均衡数据可能会长工夫障碍咱们的模型准确性。

类不均衡呈现在许多畛域,包含:

  • 欺诈辨认
  • 垃圾邮件过滤
  • 疾病筛查
  • SaaS 订阅散失
  • 广告点击

类失衡问题

当每个类别中的样本数量大抵相等时,大多数机器学习算法成果最佳。这是因为大多数算法都是为了最大化精确度和缩小误差而设计的。

然而,如果数据集不均衡,那么在这种状况下,仅仅通过预测少数类就能够取得相当高的准确率,然而无奈捕获少数类,这通常是创立模型的首要目标。

信用卡欺诈检测示例

假如咱们有一个信用卡公司的数据集,咱们必须找出信用卡交易是否是欺诈性的。

然而这里有个陷阱……欺诈交易绝对常见,只有 6%的交易是欺诈行为。

当初,在你还没有开始之前,你是否能想到问题应该如何解决?设想一下,如果你基本不花工夫训练模型。相同,如果你只编写了一行总是预测“没有欺诈性交易”的代码,该怎么办?

def transaction(transaction_data):
    return 'No fradulent transaction'

好吧,你猜怎么着?你的“解决方案”将具备 94%的准确性!

可怜的是,这种准确性令人误会。

  • 所有这些非欺诈性的交易,你都将领有 100%的准确性。
  • 那些欺诈性的交易,你的准确性为 0%。
  • 仅仅因为大多数交易不是欺诈性的(不是因为你的模型很好),你的总体准确性就很高。

这显然是一个问题,因为许多机器学习算法都旨在最大水平地进步整体准确性。在本文中,咱们将看到解决不均衡数据的不同技术。

数据

咱们将在本文中应用信用卡欺诈检测数据集,你能够从此处找到该数据集。

  • https://www.kaggle.com/mlg-ul…

加载数据后,显示数据集的前五行。

# check the target variable that is fraudulet and not fradulent transactiondata['Class'].value_counts()# 0 -> non fraudulent
# 1 -> fraudulent

# visualize the target variable
g = sns.countplot(data['Class'])
g.set_xticklabels(['Not Fraud','Fraud'])
plt.show()  

你能够分明地看到数据集之间存在微小差别。9000 次非欺诈性交易和 492 次欺诈性交易。

指标陷阱

新开发人员用户在解决不均衡数据集时遇到的一个次要问题与用于评估其模型的指标无关。应用更简略的指标,比方准确度得分,可能会产生误导。在具备高度不均衡类的数据集中,分类器总是在不进行特征分析的状况下“预测”最常见的类,并且它的准确率很高,显然不是正确的。

让咱们做这个试验,应用简略的 XGBClassifier 和无特色工程:

# import linrary
from xgboost import XGBClassifier

xgb_model = XGBClassifier().fit(x_train, y_train)

# predict
xgb_y_predict = xgb_model.predict(x_test)

# accuracy score
xgb_score = accuracy_score(xgb_y_predict, y_test)

print('Accuracy score is:', xbg_score)OUTPUT
Accuracy score is: 0.992

咱们能够看到 99%的准确度,咱们失去的是十分高的准确度,因为它预测大多数类别为 0(非欺诈性)。

重采样技术

一种解决高度不均衡数据集的宽泛采纳的技术称为重采样。它包含从少数类中删除样本(欠采样)和 / 或从少数类中增加更多示例(过采样)。

只管均衡类有很多益处,然而这些技巧也有毛病。

过采样最简略的实现是复制多数群体类别的随机记录,这可能会导致适度捕捞。

欠采样最简略的实现波及从少数类中删除随机记录,这可能会导致信息失落。

让咱们用信用卡欺诈检测示例来实现它。

咱们将首先将类 0 和类 1 离开。

# class count
class_count_0, class_count_1 = data['Class'].value_counts()

# Separate class
class_0 = data[data['Class'] == 0]
class_1 = data[data['Class'] == 1]# print the shape of the class
print('class 0:', class_0.shape)
print('class 1:', class_1.shape

1. 随机欠采样

欠采样能够定义为删除少数类的察看值。这是在少数类和少数类被均衡之前进行的。

当你领有大量数据时,欠采样可能是一个不错的抉择,比方数百万行。然而欠采样的一个毛病是咱们可能删除了有价值的信息。

class_0_under = class_0.sample(class_count_1)

test_under = pd.concat([class_0_under, class_1], axis=0)

print("total class of 1 and0:",test_under['Class'].value_counts())# plot the count after under-sampeling
test_under['Class'].value_counts().plot(kind='bar', title='count (target)')

2. 随机过采样

过采样能够定义为向少数类增加更多正本。当你没有大量数据要解决时,过采样可能是一个不错的抉择。

欠采样时要思考的一个弊病是,它可能导致过拟合并导致测试集泛化不佳。

class_1_over = class_1.sample(class_count_0, replace=True)

test_over = pd.concat([class_1_over, class_0], axis=0)

print("total class of 1 and 0:",test_under['Class'].value_counts())# plot the count after under-sampeling
test_over['Class'].value_counts().plot(kind='bar', title='count (target)')

应用不均衡学习 python 模块均衡数据

在迷信文献中曾经提出了许多更简单的重采样技术。

例如,咱们能够将少数类的记录聚类,并通过从每个聚类中删除记录来进行欠采样,从而寻求保留信息。在过采样中,咱们能够为这些正本引入较小的变动,从而创立更多样的合成样本,而不是创立多数群体记录的准确正本。

让咱们应用 Python 库 imbalanced-learn 利用其中一些重采样技术。它与 scikit-learn 兼容,并且是 scikit-learn-contrib 我的项目的一部分。

import imblearn

3. 应用 imblearn 进行随机欠采样

RandomUnderSampler 通过为指标类别随机抉择数据子集来均衡数据的疾速简便办法。通过随机抉择有或没有替代品的样本对少数类别进行欠采样。

# import library
from imblearn.under_sampling import RandomUnderSampler

rus = RandomUnderSampler(random_state=42, replacement=True)# fit predictor and target variable
x_rus, y_rus = rus.fit_resample(x, y)

print('original dataset shape:', Counter(y))
print('Resample dataset shape', Counter(y_rus))

4. 应用 imblearn 进行随机过采样

解决不均衡数据的一种办法是在多数群体中生成新样本。最童稚的策略是通过随机采样替换以后可用的采样来生成新的采样。随机过采样提供了这样一个计划。

# import library
from imblearn.over_sampling import RandomOverSampler

ros = RandomOverSampler(random_state=42)

# fit predictor and target variablex_ros, y_ros = ros.fit_resample(x, y)

print('Original dataset shape', Counter(y))
print('Resample dataset shape', Counter(y_ros))

5. 欠采样:Tomek 链接

Tomek 链接是一对十分靠近的实例,但类别相同。删除每对少数类的实例会减少两个类之间的空间,从而有助于分类过程。

如果两个样本是彼此的最近邻,则存在 Tomek 的链接

在上面的代码中,咱们将用于 ratio='majority' 对少数类进行从新采样。

# import library
from imblearn.under_sampling import TomekLinks

tl = RandomOverSampler(sampling_strategy='majority')

# fit predictor and target variable
x_tl, y_tl = ros.fit_resample(x, y)

print('Original dataset shape', Counter(y))
print('Resample dataset shape', Counter(y_ros))

6. Synthetic Minority Oversampling Technique (SMOTE)

该技术为合成多数过采样技术。

SMOTE(合成多数过采样技术)的工作原理是从少数类中随机选取一个点并计算该点的 k 近邻。合成点被增加到所选的点和它的相邻点之间。

SMOTE 算法通过以下四个简略步骤工作:

  1. 抉择少数类作为输出向量
  2. 查找其 k 个最近邻(在 SMOTE()函数中将 k_neighbors 指定为参数)
  3. 抉择这些街坊中的一个,并将合成点搁置在连贯思考中的点及其所选街坊的线上的任何地位
  4. 反复这些步骤,直到数据均衡
# import library
from imblearn.over_sampling import SMOTE

smote = SMOTE()

# fit predictor and target variable
x_smote, y_smote = smote.fit_resample(x, y)

print('Original dataset shape', Counter(y))
print('Resample dataset shape', Counter(y_ros))

7. NearMiss

NearMiss 是欠采样技术。与其应用间隔从新采样少数类,不如将少数类等同于少数类。

from imblearn.under_sampling import NearMiss

nm = NearMiss()

x_nm, y_nm = nm.fit_resample(x, y)

print('Original dataset shape:', Counter(y))
print('Resample dataset shape:', Counter(y_nm))

8. 更改性能指标

评估不均衡数据集时,准确性不是最佳的度量规范,因为它可能会产生误导。

能够提供更好洞察力的指标是:

  • 混同矩阵:显示正确预测和谬误预测类型的表。
  • 精度:实在阳性的数目除以所有阳性预测。精度也称为正预测值。它是分类器准确性的度量。低精度示意大量误报。
  • 召回率:实在阳性的数量除以测试数据中的阳性值的数量。召回也称为敏感度或实在阳性率。它是分类器完整性的度量。较低的召回率示意大量假阴性。
  • F1:得分:准确性和召回率的加权平均值。
  • ROC 曲线下面积(AUROC):AUROC 示意模型将观测值与两个类辨别开来的可能性。

换句话说,如果你从每个类中随机抉择一个察看值,你的模型可能正确“排序”它们的概率有多大?

9. 惩办算法(老本敏感训练)

下一个策略是应用惩罚性学习算法,该算法会减少少数类分类谬误的老本。

这项技术的一种风行算法是 Penalized-SVM。

在训练过程中,咱们能够应用参数 class_weight='balanced' 来惩办少数类的谬误,惩办量与代表性有余的水平成正比。

如果咱们想为反对向量机算法启用概率预计,咱们还心愿蕴含参数 probability=True。

让咱们在原始不均衡数据集上应用 Penalized-SVM 训练模型:

# load library
from sklearn.svm import SVC

# we can add class_weight='balanced' to add panalize mistake
svc_model = SVC(class_weight='balanced', probability=True)

svc_model.fit(x_train, y_train)

svc_predict = svc_model.predict(x_test)# check performance
print('ROCAUC score:',roc_auc_score(y_test, svc_predict))
print('Accuracy score:',accuracy_score(y_test, svc_predict))
print('F1 score:',f1_score(y_test, svc_predict))

10. 更改算法

只管在每个机器学习问题中,尝试各种算法都是一个很好的教训法令,然而对于不均衡的数据集而言,这尤其无利。

决策树常常在不均衡的数据上体现良好。在古代机器学习中,树集成(随机森林,梯度加强树等)简直总是胜过单个决策树,因而咱们将间接跳到:

基于树的算法通过学习 if / else 问题的层次结构来工作。这能够强制解决两个类。

# load library
from sklearn.ensemble import RandomForestClassifier

rfc = RandomForestClassifier()

# fit the predictor and target
rfc.fit(x_train, y_train)

# predict
rfc_predict = rfc.predict(x_test)# check performance
print('ROCAUC score:',roc_auc_score(y_test, rfc_predict))
print('Accuracy score:',accuracy_score(y_test, rfc_predict))
print('F1 score:',f1_score(y_test, rfc_predict))

欠采样的长处和毛病

长处

  • 当训练数据集很大时,它能够通过缩小训练数据样本的数量来帮忙改善运行工夫和存储问题。

毛病

  • 它能够抛弃可能有用的信息,这对于构建规定分类器可能很重要。
  • 通过随机欠采样抉择的样本可能是有偏差的样本。可能导致理论测试数据集的后果不精确。

过采样的优缺点

长处

  • 与欠采样不同,此办法不会导致信息失落。
  • 在抽样条件下体现更佳

毛病

  • 因为它复制了多数群体事件,因而减少了适度拟合的可能性。

你能够在我的 GitHub 存储库中查看代码的实现。

  • https://github.com/benai9916/…

参考文献

  1. https://elitedatascience.com/…
  2. https://towardsdatascience.co…

论断

总而言之,在本文中,咱们曾经看到了解决数据集中的类不均衡的各种技术。解决不均衡数据时,实际上有很多办法能够尝试。心愿本文对你有所帮忙。

谢谢浏览!

原文链接:https://www.analyticsvidhya.c…

欢送关注磐创 AI 博客站:
http://panchuang.net/

sklearn 机器学习中文官网文档:
http://sklearn123.com/

欢送关注磐创博客资源汇总站:
http://docs.panchuang.net/

正文完
 0