非平衡数据的处理笔记

简介: 非平衡数据的处理笔记

前言


众所周知,非平衡数据会极大的影响模型的评判效果,并且会过拟合。所以我们在处理数据的时候,首先需要做的是处理非平衡数据,使得各类型数据均衡。


一、处理非平衡数据的各种方法


1-1、欠采样(下采样


下采样


  • 在自然语言处理中,下采样是指对文本数据进行降采样,即减少文本数据中词语的出现次数。这种处理方式可以有效地减少文本数据的维度,提高模型训练的效率,同时也可以避免过拟合的问题。
  • 常见的下采样算法包括TF-IDF(Term Frequency-Inverse Document Frequency)算法和词汇表剪枝(Vocabulary Pruning)算法。TF-IDF算法通过计算文档中每个词语的频率和逆文档频率来衡量词语的重要性,并选择出现频率较高但又不是停用词的词语进行保留。而词汇表剪枝算法则是通过设置词语出现频率的阈值来删除出现频率较低的词语,从而达到降采样的目的。
  • 需要注意的是,下采样虽然可以提高模型训练的效率,但也可能会导致信息的丢失。因此,在实际应用中需要根据具体的任务需求和数据情况来选择合适的下采样算法和参数,以平衡数据降维和信息保留之间的关系。
  • 下列代码为对下采样的简单解释
# define:下采样,是对非平衡数据中样本较多的那一类进行采样,使其等于样本量较少的那一类
# eg: Dataframe 列名为y的这一行,统计 0、1出现的频率
df['y'].value_counts()
0    143346
1     16225
Name: y, dtype: int64
# notice: 很明显的数据不均衡,对样本较多的0类进行采样,采样数量为样本量较少那一类的数量
# n:数量  也可以用frac参数直接取比例
df_y0_undersample = df[df['y'] == 0].sample(n=(df['y']==1).sum(), random_state=201)
# 之后将他们连结在一起。
df = pd.concat([df[df['y'] == 1], df_y0_undersample])

1-2、过采样


过采样


  • 在自然语言处理中,过采样(oversampling)是指对文本数据进行过采样处理,即增加文本数据中某些词语的出现次数,以达到平衡数据分布的目的。过采样通常应用于数据不平衡的情况下,例如在文本分类任务中某些类别的样本数量很少,而另一些类别的样本数量很多的情况下,可以通过过采样的方式来平衡样本分布。
  • 对非平衡数据中样本较少的那一类进行采样,一般做法是将其复制几遍来达到正负样本平衡,这样容易过拟合,所以使用较少


1-3、人工合成

人工合成


  • 常见的人工合成(过采样)算法包括SMOTE(Synthetic Minority Over-sampling Technique)算法和ADASYN(Adaptive Synthetic Sampling)算法。这些算法都是通过在数据集中生成新的样本来实现过采样的目的。具体来说,SMOTE算法会生成一些合成样本,这些样本是由少数类样本和它们的近邻点组合而成的,而ADASYN算法则是根据每个少数类样本周围的密度来生成不同数量的合成样本。
  • 需要注意的是,过采样可能会导致过拟合的问题,因为在数据集中引入了一些人工生成的样本。因此,在实际应用中需要权衡过采样和过拟合之间的关系,根据具体的任务需求和数据情况来选择合适的过采样算法和参数。
  • 下边以SMOTE为例:

# define:人为合成一些样本量较少的数据,来达到正负样本平衡,比较常用的方法就是SMOTE。
# SMOTE的算法原理如下:根据正负样本比例,确认采样的比例,即要合成样本的数量(k值),对于少数样本中的每个x,利用KNN算法,选取k个待采样的值x_n,然后对x_n进行如下运算得到对应的x_new:x_new=x+rand(1)*|x-x_n|
# (rand(1)表示生成0-1之间的一个随机数)
# 关于SMOTE算法的实现也由现成的库,我们直接pip安装就可以使用。
from collections import Counter
from imblearn.over_sampling import SMOTE 
print('Original dataset shape {}'.format(Counter(y)))
sm = SMOTE(random_state=42)
X_res, y_res = sm.fit_sample(x, y)
print('Resampled dataset shape {}'.format(Counter(y_res)))
# 将模型进行封装,方便调用
def get_result_data(x,y):
    x_=scale(x,with_mean=True,with_std=True)
    x_train,x_test,y_train,y_test=train_test_split(x,y,test_size=0.4,random_state=0)
    model=LogisticRegression()
    clf=model.fit(x_train,y_train)
    print("LR模型测试成绩:{:.2f}".format(clf.score(x_test,y_test)))
    y_pred=clf.predict(x_test)
    target_names = ['class 0', 'class 1']
    print(classification_report(y_test, y_pred, target_names=target_names))
    y_pred1=clf.decision_function(x_test)
    fpr,tpr,threshold=roc_curve(y_test,y_pred1)
    rocauc=auc(fpr,tpr)#计算AUC
    print("ROC分数:{:.2f}".format(rocauc))
if __name__=="__main__":
    get_result_data(X_res, y_res)

1-4、调整权重(效果较好而且快捷)


调整权重


  • 在自然语言处理中,由于某些类别的样本数量很少,而其他类别的样本数量很多,导致数据分布不平衡。这种情况下,调整权重是一种常见的处理方法之一。
  • 调整权重的思路是给样本设置不同的权重,以强调少数类样本的重要性。在文本分类任务中,可以根据每个类别的样本数量来设置权重,具体地,可以使用倒数或平方根等函数来计算样本权重,如下所示:

image.png


  • 其中 w i 表示第 i 个类别的样本权重,N表示第 i 个类别的样本数量。这种权重设置方式可以使得少数类样本的权重更大,从而在模型训练中更容易被捕捉到。
  • 在实际应用中,除了调整样本权重之外,还可以采用其他方法来处理非平衡数据,例如过采样、下采样等方法,或者使用集成学习的方法,如基于bagging和boosting的方法等。需要根据具体的任务需求和数据情况来选择合适的方法,以提高模型的性能和泛化能力。
  • 下边是一个简单的调整权重案例代码:
# define:人为合成一些样本量较少的数据,来达到正负样本平衡。即人为的定义不同样本的表决权重,比如正负样本绝对量的比值为1:10,为了抵消这种量级上的不平衡,我们在模型中可以给与模型正负样本10:1的表决权重,也就是10个正样本的表决相当于1个负样本的表决。
# realize:通过设置模型的参数class_weight="balanced"来实现
x_=scale(x,with_mean=True,with_std=True)
x_train,x_test,y_train,y_test=train_test_split(x,y,test_size=0.4,random_state=0)
model=LogisticRegression(class_weight="balanced")
clf=model.fit(x_train,y_train)
print("LR模型测试成绩:{:.2f}".format(clf.score(x_test,y_test)))
y_pred=clf.predict(x_test)
target_names = ['class 0', 'class 1']
print(classification_report(y_test, y_pred, target_names=target_names))
y_pred1=clf.decision_function(x_test)
fpr,tpr,threshold=roc_curve(y_test,y_pred1)
rocauc=auc(fpr,tpr)#计算AUC
print("ROC分数:{:.2f}".format(rocauc))


参考文章:

机器学习中非平衡数据处理.


总结


今天很轻松,有空学习新知识!

相关文章
|
1月前
|
机器学习/深度学习 算法 数据挖掘
介绍一下如何处理数据不平衡的问题
介绍一下如何处理数据不平衡的问题
47 1
|
7月前
|
数据可视化 vr&ar
R语言统计学DOE实验设计:用平衡不完全区组设计(BIBD)分析纸飞机飞行时间实验数据
R语言统计学DOE实验设计:用平衡不完全区组设计(BIBD)分析纸飞机飞行时间实验数据
|
7月前
关于近视与老花眼是否会达到平衡的研究
近视和老花眼是两种常见的眼睛屈光问题,它们有不同的原因和发展过程。近视是指远处物体看不清楚,主要是眼球轴长或角膜曲率过大导致光线聚焦在视网膜前,而不是在上面。老花眼是指难以看清近距离物体,主要是由于年龄增长导致眼中晶体变硬,难以调节对近距离的聚焦能力。
关于近视与老花眼是否会达到平衡的研究
|
机器学习/深度学习 Python
处理不平衡数据:技术详解与实例分析
处理不平衡数据:技术详解与实例分析
777 0
|
存储 算法
算法设计与分析/数据结构与算法实验5:找新数最小的删除方案
算法设计与分析/数据结构与算法实验5:找新数最小的删除方案
133 0
算法设计与分析/数据结构与算法实验5:找新数最小的删除方案
|
算法 搜索推荐 大数据
数据结构上机实践第二周项目3——体验复杂度
数据结构上机实践第二周项目3——体验复杂度
106 0
数据结构上机实践第二周项目3——体验复杂度
|
数据挖掘 开发者
不平衡分类| 学习笔记
快速学习不平衡分类。
不平衡分类| 学习笔记
数据结构与算法--算法效率的度量方法
数据结构与算法--算法效率的度量方法
|
机器学习/深度学习 算法 Java
面经手册 · 第3篇《HashMap核心知识,扰动函数、负载因子、扩容链表拆分深度学习(+实践验证)》
HashMap 最早出现在 JDK 1.2中,底层基于散列算法实现。HashMap 允许 null 键和 null 值,在计算哈键的哈希值时,null 键哈希值为 0。HashMap 并不保证键值对的顺序,这意味着在进行某些操作后,键值对的顺序可能会发生变化。另外,需要注意的是,HashMap 是非线程安全类,在多线程环境下可能会存在问题。
187 0
面经手册 · 第3篇《HashMap核心知识,扰动函数、负载因子、扩容链表拆分深度学习(+实践验证)》
|
机器学习/深度学习 算法 Java
面试这么撩准拿offer,HashMap深度学习,扰动函数、负载因子、扩容拆分,原理和实践验证,让懂了就是真的懂!
散列表实现?扰动函数?初始化容量?负载因子?扩容元素拆分?🕵HashMap理论学习+实践验证,让懂了就是真的懂!
2341 0
面试这么撩准拿offer,HashMap深度学习,扰动函数、负载因子、扩容拆分,原理和实践验证,让懂了就是真的懂!