简介当一个类的观察值高于其他类的观察值时,就会存在类不平衡。示例:检测欺诈性信用卡交易。如下图所示,欺诈交易约400笔,非欺诈交易约9万笔。类别不平衡是机器学习中的一个常见问题,尤其是在分类问题中。不平衡的数据会长期阻碍我们的模型准确性。类不平衡出现在许多领域,包括:欺诈检测垃圾邮件过滤疾病筛查SaaS订阅流失广告点击类不平衡问题大多数机器学习算法在每个类中的样本数量大致相等时效果最好。这是因为大多数算法旨在最大限度地提高准确性并最大限度地减少错误。然而,如果数据集是不平衡的,那么在这种情况下,可以通过简单地预测多数类来获得相当高的准确度,但无法捕获少数类,这通常是创建模型的主要目的。信用卡欺诈检测示例假设我们有一个信用卡公司的数据集,我们必须找出信用卡交易是否存在欺诈。但问题是……欺诈性交易相对较少,只有6%的交易是欺诈性的。现在,在你开始之前,你能想到应该如何解决这个问题吗?想象一下,如果您根本不花时间训练模型。相反,如果您只是编写了一行始终预测“无欺诈交易”的代码怎么办?deftransaction(transaction_data):return'Nofraudulenttransaction'那么,你猜怎么着?您的“解决方案”的准确率为94%!不幸的是,这种准确性具有误导性。您对所有这些非欺诈性交易的准确性将达到100%。那些欺诈交易,你的准确率是0%。仅仅因为大多数交易不是欺诈性的(不是因为你的模型很好),你的整体准确性很高。这显然是一个问题,因为许多机器学习算法旨在最大限度地提高整体准确性。在本文中,我们将看到处理不平衡数据的不同技术。数据我们将在本文中使用信用卡欺诈检测数据集,您可以在此处找到该数据集。https://www.kaggle.com/mlg-ulb/creditcardfraud加载数据后,显示数据集的前五行。#checkthetargetvariablethatisfrauduletandnotfraudulenttransactiondata['Class'].value_counts()#0->nonfraudulent#1->fraudulent#visualizethetargetvariableg=sns.countplot(data['Class'])g.set_xticklabels(['NotFraud','Fraud'])plt.show()可以清楚地看到数据集之间存在巨大差异。9000笔非欺诈交易和492笔欺诈交易。度量陷阱新开发人员用户在处理不平衡数据集时遇到的主要问题之一与用于评估其模型的度量有关。使用更简单的指标(例如准确度分数)可能会产生误导。在类别高度不平衡的数据集中,分类器总是在不进行特征分析的情况下“预测”最常见的类别,而且准确率很高,这显然是不正确的。让我们做这个实验,使用一个简单的XGBClassifier和无特征的工程:,xbg_score)OUTPUTAccuracyscoreis:0.992我们可以看到,在99%的准确率下,我们得到的准确率非常高,因为它对大多数类别的预测为0(非欺诈)。重采样技术一种广泛采用的处理高度不平衡数据集的技术称为重采样。它包括从多数类中删除样本(欠采样)和/或从少数类中添加更多示例(过采样)。尽管平衡类有很多好处,但这些技术也有缺点。过度采样的最简单实现是为少数类复制随机记录,这可能导致过度捕捞。欠采样的最简单实现涉及从多数类中删除随机记录,这可能会导致信息丢失。让我们用信用卡欺诈检测示例来实现它。我们首先将类0与类1分开。#classcountclass_count_0,class_count_1=data['Class'].value_counts()#Separateclassclass_0=data[data['Class']==0]class_1=data[data['Class']==1]#printtheshapeoftheclassprint('class0:',class_0.shape)print('class1:',class_1.shape1.随机欠采样欠采样可以定义为从多数类中移除观察值。这是在多数类和少数类平衡之前完成的。当你有大量的在处理数百万行数据时,欠采样可能是一个不错的选择。但欠采样的一个缺点是我们可能会删除有价值的信息。class_0_under=class_0.sample(class_count_1)test_under=pd.concat([class_0_under,class_1],axis=0)print("totalclassof1and0:",test_under['Class'].value_counts())#plotthecountafterunder-sampelingtest_under['Class'].value_counts().plot(kind='bar',title='count(target)')2.RandomOversampling过采样可以定义为向少数类添加更多副本。当你d没有很多数据要处理。欠采样时要考虑的一个缺点是它可能导致过度拟合并导致测试集泛化能力差。class_1_over=class_1.sample(class_count_0,replace=True)test_over=pd.concat([class_1_over,class_0],axis=0)print("totalclassof1and0:",test_under['Class'].value_counts())#plotthecountafterunder-sampelingtest_over['Class'].value_counts().plot(kind='bar',title='count(target)')使用不平衡学习python模块来平衡数据科学文献中已经提出了许多更复杂的重采样技术。例如,我们可以通过从每个聚类中删除记录来对多数类的记录进行聚类和欠采样,以寻求保留信息。在过采样中,我们可以对这些副本进行小的改动,创建更多样的合成样本,而不是创建少数记录的精确副本。让我们使用Python库imbalanced-learn应用其中一些重采样技术。它与scikit-learn兼容,是scikit-learn-contrib项目的一部分。importimblearn3.使用imblearnRandomUnderSampler进行随机欠采样通过随机选择目标类的数据子集来快速简便地平衡数据。通过随机选择有或没有备选方案的样本,对多数类别进行欠采样。#importlibraryfromimblearn.under_samplingimportUnderSamplerrus=RandomUnderSampler(random_state=42,replacement=True)#fitpredictorandtargetvariablex_rus,y_rus=rus.fit_resample(x,y)print('originaldatasetshape:',Counter(y))print('Resampledataset_shape:',Counter(y)))print('Resampledataset_shape('Resample',Counter(y)))4.使用imblearn进行随机过采样处理不平衡数据的一种方法是在少数群体中生成新样本。最天真的策略是通过用随机样本替换当前可用样本来生成新样本。随机过采样提供了这样的解决方案。#importlibraryfromimblearn.over_samplingimportRandomOverSamplerros=RandomOverSampler(random_state=42)#fitpredictorandtargetvariablex_ros,y_ros=ros.fit_resample(x,y)print('Originaldatasetshape',Counter(y))print('Resampledatasetshape',Counter(y_ros))5。:Tomek链接Tomek链接是一对非常接近但类别相反的实例。删除每对多数类的实例会增加两个类之间的空间,从而有助于分类过程。如果两个样本彼此最接近,则存在Tomek链接。在下面的代码中,我们将使用ratio='majority'对多数类重新采样。#importlibraryfromimblearn.under_samplingimportTomekLinkstl=RandomOverSampler(sampling_strategy='majority')#fitpredictorandtargetvariablex_tl,y_tl=ros.fit_resample(x,y)print('Originaldatasetshape',Counter(y))print('Resampledatasetshape',Counter(y))6。ros(ySyntheticMinorityOversamplingTechnique(SMOTE)该技术是一种合成少数过采样技术。SMOTE(SyntheticMinorityOversamplingTechnique)的工作原理是从少数类中随机选取一个点并计算该点的k-最近邻点。复合点是添加在所选点及其相邻点之间。SMOTE算法通过以下四个简单步骤工作:选择少数类作为输入向量找到它的k个最近邻居(在SMOTE()函数中指定k_neighbors作为参数)选择这些邻居之一并将合成点放在连接中考虑在点in及其选定邻居的线上的任何位置重复这些步骤,直到数据平衡#importlibraryfromimblearn.over_samplingimportSMOTEsmote=SMOTE()#fitpredictorandtargetvariablex_smote,y_smote=smote.fit_resample(x,y)print('Originaldatasetshape',Counter(y))print('Resampledatasetshape',Counter(y_ros))7.NearMissNearMiss是一种欠采样技术。不是使用距离对少数类进行重采样,而是将多数类等同于少数类。fromimblearn.under_samplingimportNearMissnm=NearMiss()x_nm,y_nm=nm.fit_resample(x,y)print('Originaldatasetshape:',Counter(y))print('Resampledatasetshape:',Counter(y_nm))8.更改性能指标评估no准确性不是平衡数据集时使用的最佳指标,因为它可能会产生误导。可以提供更好洞察力的指标有:混淆矩阵:显示正确和错误预测类型的表格。精度:真阳性数除以所有阳性预测。精密度也称为阳性预测值。它是衡量分类器准确性的指标。低精度表示大量误报。Recall:真阳性的数量除以测试数据中正值的数量。召回率也称为灵敏度或真阳性率。它是衡量分类器完整性的指标。低召回率表示大量假阴性。F1:分数:精确率和召回率的加权平均值。ROC曲线下面积(AUROC):AUROC表示模型将观察值与两个类别区分开来的可能性。换句话说,如果您从每个类别中随机选择一个观察值,您的模型能够正确“排序”它们的概率是多少?9.惩罚算法(成本敏感训练)下一个策略是使用惩罚学习算法,该算法增加了少数类错误分类的成本。这种技术的一种流行算法是Penalized-SVM。在训练过程中,我们可以使用参数class_weight='balanced'来惩罚少数类的错误,其数量与代表性不足的程度成正比。如果我们想为SVM算法启用概率估计,我们还想包括参数probability=True。让我们在原始不平衡数据集上使用惩罚SVM训练模型:#loadlibraryfromsklearn.svmimportSVC#wecanaddclass_weight='balanced'toaddpanalizemistakesvc_model=SVC(class_weight='balanced',probability=True)svc_model.fit(x_train,y_train)svc_predict=svc_model。预测(x_test)#checkperformanceprint('ROCAUCscore:',roc_auc_score(y_test,svc_predict))打印('Accuracyscore:',accuracy_score(y_test,svc_predict))打印('F1score:',f1_score(y_test,svc_predict))10.Change算法虽然在每个机器学习问题中尝试各种算法是一个很好的经验法则,但它对不平衡数据集尤其有益。决策树通常在不平衡数据上表现良好。在现代机器学习中,树集成(随机森林、梯度提升树等)几乎总是优于单个决策树,因此我们将直接进入:基于树的算法通过学习if/else问题的层次结构来工作。这可以强制解析两个类。#loadlibraryfromsklearn.ensembleimportRandomForestClassifierrfc=RandomForestClassifier()#fitthepredictorandtargetrfc.fit(x_train,y_train)#predictrfc_predict=rfc.predict(x_test)#checkperformanceprint('ROCAUCscore:',roc_auc_score(y_test,rfc_predict))print('Accuracyscore:core',准确y_test,rfc_predict))print('F1score:',f1_score(y_test,rfc_predict))欠采样的优缺点Pros当训练数据集是大问题时,它可以通过减少训练数据样本的数量来帮助改善运行时间和存储。缺点它可以丢弃潜在有用的信息,这对于构建规则分类器很重要。通过随机欠采样选择的样本可能是有偏差的样本。可能导致实际测试数据集的结果不准确。过采样的优点和缺点优点与欠采样不同,此方法不会导致信息丢失。在采样条件下表现更好缺点增加过度拟合的可能性,因为它复制了少数事件。您可以在我的GitHub存储库中查看代码的实现。https://github.com/benai9916/Handle-imbalanced-data/tree/master结论总而言之,在本文中我们看到了处理数据集中类不平衡的各种技术。在处理不平衡数据时,其实有很多方法可以尝试。希望本文对您有所帮助。
