本文转载自公众号《核心阅读》(ID:AI_Discovery)。机器学习中的一个常见问题是处理不平衡数据,其中目标类别严重不成比例并且数据量非常不成比例。什么是多类不平衡数据?当分类问题的目标类(两个或多个)分布不均匀时,称为不平衡数据。如果这个问题处理不好,模型将是一场灾难,因为用类不平衡数据建模会偏向多数类。处理不平衡数据有不同的方法,最常见的是过采样和创建合成样本。什么是SMOTE算法?SMOTE是一种过采样技术,用于从数据集中生成合成示例,可提高少数类的预测能力。虽然没有信息丢失,但它有一些局限性。合成样本限制:SMOTE不适用于高维数据。可能会发生类别重叠,并给数据引入更多噪声。因此,要跳过此问题,请使用“class_weight”参数手动为类分配权重。为什么要使用类权重?类别权重通过惩罚具有不同权重的类别来直接修改损失函数,有目的地增加少数类别的权力并降低多数类别的权力。因此,它比SMOTE效果更好。本文将介绍一些最流行的从数据中获取权重的技术,这些技术适用于不平衡学习问题。(1)sklearnutils可以使用sklearn获取和计算类权重。在训练模型时将这些权重添加到少数类中可以提高类分类性能。fromsklearn.utilsimportclass_weightclass_weightclass_weight=class_weight.compute_class_weight('balanced,np.unique(target_Y),target_Y)model=LogisticRegression(class_weightclass_weight=class_weight)model.fit(X,target_Y)#['balanced','calculatedbalanced','normalized']是我们可以玩的超参数。对于几乎所有的分类算法,从逻辑回归到Catboost,都有一个class_weight参数。但是XGboost将scale_pos_weight用于二元分类,将样本权重用于二元和多类问题。(2)长短比非常简单明了。将行数除以每个类的计数,然后weights=df[target_Y].value_counts()/len(df)model=LGBMClassifier(class_weight=weights)model.fit(X,target_Y)(3)SmoothenWeights这是选择权重的最佳方法之一。labels_dict是一个字典对象,包含每个类的计数,对数函数对不平衡类的权重进行平均。defclass_weight(labels_dict,mu=0.15):total=np.sum(labels_dict.values())keys=labels_dict.keys()weight=dict()foriinkeys:score=np.log(mu*total/float(labels_dict[i]))weight[i]=scoreifscore>1else1returnweight#randomlabels_dictlabels_dict=df[target_Y].value_counts().to_dict()weights=class_weight(labels_dict)model=RandomForestClassifier(class_weight=weights)model.fit(X,target_Y)(4)sampleweightstrategy下面的函数与XGboost算法用来获取样本权重的class_weight参数不同。它为每个训练样本返回不同的权重。sample_weights是一个与数据长度相同的数组,其中包含应用于每个样本的模型损失的权重。defBalancedSampleWeights(y_train,class_weight_coef):classes=np.unique(y_train,axis=0)classes.sort()class_samples=np.bincount(y_train)total_samples=class_samples.sum()n_classes=len(class_samples)weights=total_samples/(n_classes*class_samples*1.0)class_weight_dict={key:valuefor(key,value)inzip(classes,weights)}class_weight_dict[classes[1]]=class_weight_dict[classes[1]]*class_weight_coefsample_weights=[class_weight_dict[i]foriiny_train]返回样本权重#Usageweight=BalancedSampleWeights(target_Y,class_weight_coef)model=XGBClassifier(sample_weight=weight)model.fit(X,target_Y)(5)类权重和样本权重:样本权重用于为每个训练样本提供权重,也就是说应该传递一个元素数量与训练样本完全相同的一维数组。类权重用于为每个目标类提供权重,也就是说要为每个待分类的类传递一个权重。以上是分类器寻找类别权重和样本权重的几种方法,这些技巧对我的项目都很有效,你可以试试这些技巧,一定会有很大帮助。
