做机器学习的朋友应该都遇到过这种场景:拿到的数据集里正样本只有几百条,负样本却有上百万条,正负比例悬殊到模型看一眼就想"躺平"。我用合成数据(synthetic data)处理过好几个这样的极度不平衡数据集,说实话,合成数据确实是目前最有效的手段之一,但前提是方法选对、比例调好,否则它会把你的模型带进更深的坑。
这篇文章基于我在一个模拟风控项目里的真实经历,讲清楚极度不平衡数据集的底层逻辑、合成数据的常见生成路线、以及我在实验中踩过的坑和最终的判断标准。内容不只给结论,连推理过程、实验配置和评价方式都会展开,方便你直接照着做。
1. 极度不平衡问题的底层逻辑:为什么模型总是"装死"
1.1 准确率骗局:99.9%的"好模型"根本不能用
先讲一个反直觉的现象。在一个正负样本比例约为1:10000的风控数据集上,哪怕我用一个什么都不做的模型,永远输出"正常",它的准确率也能达到99.99%。这个准确率相当好看,但放到真实业务里就是个废物,因为它把所有的风险用户全部放走了。
准确率这个指标在不平衡数据上的失效,是所有后续问题的起点。很多人拿到一个不平衡数据集,第一反应是"哇,准确率这么高,模型是不是已经训练好了",实际上模型什么都没学到。真正要看的往往不是准确率,而是召回率、精确率、F1、PR曲线这些能反映少数类表现的东西。
所以处理极度不平衡数据集的第一件事不是选算法,而是换评估视角。如果我们连"好模型"的定义都错了,后面做再多合成数据都是白搭。
1.2 类别不平衡的三个层次:数据、损失函数、评估指标
我把不平衡问题拆成三层来看,这样比较好定位问题出在哪。
第一层是数据层。少数类样本量太少,模型根本没有足够信息去学习它的特征分布,或者说学习的方差太大,换一批数据结果就完全不同。比如正样本只有50条,哪怕用随机森林这类模型,也很容易把其中几个异常点当成代表性特征。
第二层是损失函数层。常见模型在训练时默认每个样本的权重相同,因此多数类贡献的梯度远远大于少数类,模型自然倾向于把样本判断成多数类。哪怕数据分布是均衡的,损失函数本身也会给少数类分配很少的"注意力"。
第三层是评估层。如前面所说,准确率在极度不平衡下没有意义,它无法反映模型对少数类的识别能力。正确的做法是用PR曲线下面积、F1分数、召回率等指标,尤其是PR-AUC,它比ROC-AUC在极度不平衡时更能体现实用价值。
合成数据主要作用在第一层,也就是往数据里注入人工构造的少数类样本,让模型有更多"例子"可以学。但如果不理解第二层和第三层,合成数据的效果会被严重高估,因为模型可能还是在用多数类的逻辑做判断,只是多背了几条少数类样本而已。
1.3 合成数据要解决的核心矛盾
极度不平衡数据有一个核心矛盾:我们想让模型识别少数类,但少数类的真实样本太少了,模型无法从中提炼出稳定的边界。合成数据的本质,是用"合理假设"替换"真实观察",把少数类特征空间里的空洞填补出来。
这里的关键词是"合理假设"。SMOTE假设少数类样本之间的线性插值仍然属于少数类,这个假设在特征连续且局部线性时可以成立。而生成对抗网络(GAN)假设我们能够学习少数类样本的潜在分布,并从该分布中采样新样本。扩散模型则假设通过逐步去噪可以还原真实数据分布。
但任何一种合成方法都无法凭空创造信息。它能做到的是把已有样本里隐含的结构信息挖掘出来,并重新组合出和真实样本接近但不完全相同的样本。所以合成数据真正的价值,是降低模型过拟合的风险、稳定训练过程,而不是无限增加信息量。
理解了这个核心矛盾,我们接下来看具体有哪些合成手段,以及它们各自适合什么场景。
2. 合成数据的常见路线:从SMOTE到生成模型
2.1 插值派:SMOTE族算法与变体
SMOTE(Synthetic Minority Over-sampling Technique)是处理不平衡数据最经典的方法,发布于2002年,到今天依然是很多实验的baseline。它的思路很简单:对每个少数类样本,在它的k近邻中随机选一个样本,然后在这两个样本的连线上随机取一点,作为新的合成样本。
为什么这个方法有效?因为它在少数类样本的局部邻域内做插值,相当于假设少数类在这个局部区域内是线性可分的,新样本既接近旧样本,又有一定的变化,能缓解少数类样本过少导致的过拟合。
不过SMOTE有一个明显问题:它不考虑多数类样本的位置,如果少数类样本恰好处在决策边界上或者在多数类密集区域,盲目插值生成的样本可能落在多数类区域里,反而让分类边界更混乱。
针对这个问题,后来出现了不少变体:
- Borderline-SMOTE:只对位于边界区域的少数类样本做插值,认为这些样本对分类决策更有价值。
- SMOTE-ENN:先用SMOTE生成样本,再用编辑近邻法剔除那些可能被多数类包围的"危险样本",清理决策边界。
- ADASYN:按少数类样本周围多数类比例来决定生成多少样本,周围多数类越多,就越重点生成。
这些变体的核心思想都在于:不要盲目均匀地生成样本,而是把生成的资源集中在更有价值、更难以分类的区域。
实际使用中,我的经验是SMOTE-ENN在极度不平衡场景下往往比原始SMOTE更稳定,因为它自带清理步骤,能去掉不少插值产生的噪声。ADASYN对噪声很敏感,如果少数类样本里本身有离群点,它可能会放大这些离群点的影响。
2.2 生成派:VAE/GAN/扩散模型
如果说插值派是"在已知样本之间做文章",那生成派就是"学习整个分布,再从头生成"。生成派的代表有VAE(变分自编码器)、GAN(生成对抗网络)和扩散模型。
VAE通过编码器把样本压缩到低维隐空间,再让解码器从隐空间中还原样本,训练完成后,我们可以从隐空间中随机采样,然后通过解码器生成新样本。VAE的关键优势是训练相对稳定,不容易出现模式崩溃,生成的样本多样性也还行。
GAN则是让生成器和判别器对抗训练,生成器试图骗过判别器,判别器试图区分真实样本和生成样本。在极度不平衡数据上直接训练GAN会比较困难,因为少数类样本太少,判别器很容易"记住"那几百条真实样本,生成器就会走捷径,输出和真实样本几乎相同的"复制品",而不是多样性的新样本。
扩散模型是目前比较前沿的选择。它通过逐步加噪破坏数据,再学习逐步去噪还原数据的过程,生成质量往往比GAN更好、更稳定,但计算成本也高不少。对表格数据来说,扩散模型用得好确实能生成相当逼真的少数类样本,但它需要的数据量也不是几百条就能满足的。
在实操中,如果只有几百条少数类样本,我不太推荐直接上GAN或扩散模型。训练不充分、模式崩溃的风险太高,反而浪费时间。VAE是个折中选择,但如果特征空间维度很高、各特征关联复杂,VAE生成样本的质量也有限。
2.3 增强派:半监督与伪标签的边界
还有一条路线介于"生成"和"复制"之间:用模型本身对未标注数据做预测,把置信度高的预测结果当作伪标签,加入训练集。对不平衡数据来说,可以先让模型在原始数据上训练,然后用它去预测大量未标注样本,把疑似少数类的样本挑出来。
这种做法看起来像是"免费"增加了少数类样本,但风险也很大:模型一开始就对少数类识别不好,它挑出来的"少数类样本"里真实错误率可能很高,用这些噪声伪标签训练,会形成错误信心循环。所以在实务中,我一般把伪标签方法当作补充手段,而且必须配合置信度阈值筛选和人工抽检,不能完全放手。
有一个模糊地带是数据增强技术。比如对图像数据做旋转、裁剪、颜色扰动,这也算生成新样本。对表格数据,则可以对特征加入少量噪声,或者用Mixup在样本对之间做线性插值。Mixup和SMOTE的逻辑有点相似,但Mixup不一定局限在同类样本,有时候也会在异类样本之间插值,这在极度不平衡下可以作为正则化手段使用。
我个人的判断标准是:如果样本量少于100条,优先考虑Mixup和简单加噪,其次SMOTE族,最后才是VAE/GAN。如果样本量有几千条,可以尝试生成模型,但必须严格用留出法验证生成样本是否真的提升了验证集的泛化效果。
3. 实操对比:我在一个风控模拟项目中的合成数据实验
3.1 实验设置:数据集、评价指标、基线模型
为了更客观地对比不同合成方法,我做了一个模拟风控项目,用的是脱敏后的行为日志数据,总共约20万条样本,其中风险样本(正样本)只有200条左右,正负比例接近1:1000。特征有27个维,包括操作频次、金额分布、时间熵、登录设备数等,多数是连续特征,少数是类别特征。
我先把原始数据划分为训练集、验证集和测试集,划分时用分层抽样保证测试集中仍然只有约50条正样本。评价指标没有用准确率,而是用了:
- 召回率(Recall):正样本里被正确找出来的比例,这个指标对风控尤其重要。
- 精确率(Precision):被模型判为正的样本里真实为正的比例。
- F1分数:召回率和精确率的调和平均,用来平衡两者。
- PR-AUC:精确率-召回率曲线下面积,综合反映模型在不同阈值下的能力。
基线模型选择了逻辑回归和XGBoost。之所以选这两个,是因为逻辑回归可以看决策边界,XGBoost可以看特征重要性分布,加上GAN这类生成模型生成的表格数据,可以直接喂给树模型做训练,能很好地对比"算法层面"和"数据层面"的差异。
为了公平对比,所有实验都用同一组超参数范围,用验证集调参,最后统一在测试集上报告结果。这里有个细节:合成数据只能在训练集上生成,验证集和测试集必须保持原始的真实分布,否则评估结果会虚高,而且是没有意义的虚高。
3.2 SMOTE与Borderline-SMOTE的效果实测
第一个实验是原始数据直接训练,作为baseline。XGBoost在测试集上的召回率只有0.42,精确率0.80,F1约0.55。看起来精确率很高,但召回率太低,意味着大量真实风险样本被漏掉了。逻辑回归更惨,召回率甚至不到0.2,因为线性模型无法应付极度不平衡下的复杂边界。
然后是SMOTE,我把它用在训练集上,把风险样本过采样到与正常样本等量,也就是合成约19.8万条正样本。训练完成后,XGBoost的召回率提升到了0.72,但精确率掉到了0.51,F1为0.59。召回率明显提升了,但精确率的下降也比较严重,模型开始把不少正常样本错判成风险样本。
Borderline-SMOTE表现略好一些,它只对边界样本做插值,生成的正样本更多集中在决策边界附近,结果是召回率0.68,精确率0.63,F1为0.65。这说明在极度不平衡问题里,精确率和召回率的权衡非常重要,盲目把正样本数量拉平并不一定能得到最好的F1。
SMOTE-ENN更进一步,在SMOTE合成后用近邻法删掉那些和多数类纠缠不清的样本,最终F1达到了0.68,精确率0.66,召回率0.70。这个结果让我意识到:合成之后的数据清理,跟合成本身一样重要。
3.3 基于GAN的合成数据与真实数据混合训练
在对比完SMOTE族后,我尝试了用GAN生成正样本。当时选的是一个简单的条件生成对抗网络,把类别标签作为条件输入。训练GAN时我只用了训练集里的200条正样本,数据太少,所以每个epoch都对少数类做了重复采样,还在生成器里加入了Dropout来增强稳定性。
训练稳定后,我让GAN生成1万条正样本,从中随机抽取3000条与真实正样本混合,再配上正常样本做训练。结果比较微妙:XGBoost在测试集上的F1反而比SMOTE-ENN低一些,只有0.62,但有意思的是,模型的PR-AUC达到了0.81,比原始SMOTE的0.77高。
这说明GAN生成的样本分布整体更接近真实的少数类分布,并没有像SMOTE那样在边界上制造大量"虚假困难样本",所以排序能力(PR-AUC)提升明显,但具体决策阈值上,GAN样本和真实样本还是有分布偏差,导致召回率和精确率的综合表现不如SMOTE-ENN。
我还尝试了一种混合策略:把SMOTE类方法生成的边界样本和GAN生成的分布内样本按1:2混合,总数控制在真实正样本的5到10倍。混合之后,F1提升到了0.71,PR-AUC 0.84,比单一合成方法都要好。这说明不同合成方法各有偏向,混合使用大概率能互补。
3.4 不同合成方法在极度不平衡下的性能对比表
我把实验结果整理成了表格,方便你直接对比:
| 合成方法 | 召回率 | 精确率 | F1 | PR-AUC | 备注 |
|---|---|---|---|---|---|
| 原始数据(不采样) | 0.42 | 0.80 | 0.55 | 0.73 | 召回率低,漏报严重 |
| SMOTE(拉平比例) | 0.72 | 0.51 | 0.59 | 0.77 | 召回率升但噪声增多 |
| Borderline-SMOTE | 0.68 | 0.63 | 0.65 | 0.78 | 边界样本更精准 |
| SMOTE-ENN | 0.70 | 0.66 | 0.68 | 0.79 | 清理后更稳 |
| GAN生成(混合3000条) | 0.60 | 0.64 | 0.62 | 0.81 | 分布更真实但边界不敏感 |
| SMOTE-ENN + GAN混合 | 0.73 | 0.69 | 0.71 | 0.84 | 结合了边界与分布优势 |
这个表格只能作为一个参考,因为不同数据集的特征分布差异很大,但你至少可以看出一个趋势:单一合成方法有局限,混合策略往往能获得更平衡的性能。
细心的朋友会发现,GAN那组实验的PR-AUC高但F1低,这再次说明了评估指标的选择会直接影响我们对方法的判断。如果只看PR-AUC,我可能会迷信GAN,但F1数据提醒我,具体业务场景需要明确到底更在意召回还是精确。
4. 合成数据不能乱用:过拟合陷阱与分布偏置
4.1 为什么SMOTE在极度不平衡下反而可能变差
很多人以为SMOTE是万能的,但在极度不平衡场景里,它有时会让模型变得更差。我之前在做另一个实验时,正负比例是1:20000,SMOTE把正样本拉到和负样本一样多,结果模型在验证集上的效果反而不如不合成。
原因在于:当少数类样本极少、且特征空间重叠严重时,SMOTE在邻近样本之间插值,会生成大量处于多数类腹地的"伪少数类样本"。这些样本本身带有误导性,模型为了迎合训练集,会把决策边界推向多数类一侧,结果验证集上精确率骤降。
另一个问题是,SMOTE假设特征之间是欧几里得空间里的连续关系,但如果特征里包含大量离散型变量、类别型变量或者稀疏特征,线性插值会生成毫无意义甚至非法的特征组合。比如"设备类型=3.7"这种样本,既不属于设备类型1,也不属于设备类型2,模型学到的规律完全是虚假的。
这也是我强调数据预分析的原因。在跑SMOTE之前先看特征分布、检查数据中是否有大量类别特征,如果类别特征过多,应该先做编码处理,或者考虑用其他更适合离散数据的合成方法(如条件表格生成模型)。
4.2 生成数据与真实数据的泄露风险
还有一个很多人忽略的问题:合成数据污染的验证集和测试集。如果你在划分数据集之前就做了全局合成,比如把SMOTE应用在整个数据集上,再划分训练、验证、测试集,那么验证和测试集里也会包含由训练样本插值生成的样本。
这带来一个很隐蔽的泄露问题:测试集中某些"合成样本"可能与训练集的某个原始样本共享生成路径,模型实际上已经见过类似样本,测试分数会虚高得离谱。但到了线上真实环境,模型遇到的全是真实样本,性能立刻跳水。
正确做法是先划分训练集、验证集、测试集,然后只在训练集内部做合成,并且验证集和测试集永远保持原始分布。我在项目里用了一个简单但很有效的审计方法:计算测试集中每个样本和训练集中真实样本的最小距离,如果发现有测试样本和训练样本的距离异常接近,就要检查是不是合成数据泄露了。
4.3 我踩过的坑:合成样本导致的决策边界失衡
说一个具体踩坑经历。在某次尝试中,我把正样本合成了真实数量的20倍,几乎全部都是少数类,然后训练了一个XGBoost。初期验证集表现不错,召回率到了0.85,但后来发现线下性能严重不稳定。
深挖原因后发现,过度合成使模型对少数类特征空间产生了过强的先验,把很多不完全符合该分布的样本也判定为正类。尤其是在测试集中遇到一些带有噪声的正样本时,模型反而不认识它们了,因为它的决策边界已经被"过度理想化"的合成样本挤得很窄。
这个坑的教训是:合成数据的目标不是让训练集平衡,而是让训练集更好地覆盖真实少数类的分布。如果合成数量远超真实样本的合理范围,模型会开始"背答案",而不是学规律。
我后来给自己定了个规矩:合成后的正样本数量与真实正样本数量之比,不超过10:1。对于极度不平衡的数据,这个比例能有效提升召回,同时不过分扭曲决策边界。如果10:1还不够,就去收集更多真实样本,而不是无限合成。
5. 一套可落地的合成数据使用策略
5.1 先评估原始不平衡度:用有效样本比看是否需要合成
拿到不平衡数据集后,不要急着做合成,先评估"原始不平衡度"和"有效样本数"。
有效样本数这个概念值得多说两句。它是指少数类中真正独立、信息量充足的样本数量。如果200条正样本里有150条是相同事件的不同日志,或者高度相关,那么有效样本数可能只有一半。有效样本数越小,合成数据的必要性就越大,但训练生成模型的难度也越大。
一个实用的评估方法:先用原始训练数据跑一次简单模型(比如逻辑回归),记录验证集上的F1和PR-AUC。如果F1已经可以接受(比如0.6以上),那说明原始数据本身可学习性不差,合成数据能带来的增益有限。如果F1只有0.3以下,大概率需要合成数据介入。
5.2 合成比例与混合策略:不是越多越好
合成比例直接决定训练集里少数类占比。我建议先用SMOTE族方法做一个小型网格搜索,比例从1:1、2:1、5:1再到10:1(正样本:真实正样本),不要一上来就1:1拉平。
实验里最常用的组合是:
- 先把真实正样本复制一份作为底数,保证模型能看到真实样本。
- 然后用SMOTE-ENN生成一部分边界样本。
- 如果数据量足够,再用GAN或VAE生成一部分分布内样本,按1:2或1:3的比例混合。
- 总合成样本数控制在真实正样本的3到10倍之间。
为什么不是1:1拉平?因为极度不平衡数据中,多数类样本本身也包含大量复杂模式,拉平会让少数类在训练中过度主导,损失多数类的信息。在风控场景里,正常用户的行为模式也是需要学习的,过度关注风险用户反而会让误报飙升。
5.3 评估闭环:用PR曲线和PR-AUC而非准确率
合成数据效果好不好,必须在同一个评估闭环里比较。我建议的做法是:
- 固定模型(XGBoost或逻辑回归),统一超参数。
- 分别用原始数据、SMOTE数据、GAN数据和混合数据训练。
- 在同一个测试集(保持原始不平衡比例)上计算召回率、精确率、F1、PR-AUC。
- 记录训练曲线,观察验证集损失是否平滑。
在判断"合成数据是否有效"时,我特别看重PR-AUC的相对变化。因为PR-AUC不受分类阈值影响,能反映模型对少数类的整体排序能力。如果一个合成方法能显著提升PR-AUC,说明它确实帮助模型学到了更本质的分布;如果只提升召回率但精确率掉得厉害,那可能是运气成分大过学习成分。
5.4 最终建议流程
综合这些实操经验,我给出一套可复用的流程:
- 划分数据:先分层划分训练集、验证集、测试集,测试集不参与任何合成与调参。
- 评估基线:用原始训练数据训练基线模型,记录F1和PR-AUC。
- 特征分析:检查特征类型、缺失值、相关性和有效样本数,判断是否适合插值类方法。
- 选择合成方法:有效样本数少、特征连续时用SMOTE-ENN;有一定数据量且想提升分布真实性时,加入VAE或GAN;想尝试前沿方案可以引入扩散模型,但注意资源消耗。
- 比例搜索:以3:1到10:1的比例做小规模搜索,用验证集F1和PR-AUC选择最优比例。
- 混合合成:把边界样本和分布内样本按1:2混合,观察是否优于单一方法。
- 最终评估:在测试集上做最终评估,并计算生成样本与真实样本的最短距离,排查泄露。
这套流程就是我在多个项目里反复打磨出来的框架,每一步都有明确目的,不会让你在合成数据的海洋里迷失方向。
如果要说最深的体会,那就是:合成数据只是一个工具,它的上限取决于你对真实数据分布的理解。用SMOTE之前先想清楚特征空间长什么样,用GAN之前先考虑样本量够不够。没有谁比谁高级,只有谁更匹配你的数据规模和业务目标。把这些基本功做到位,合成数据才能真正成为你处理极度不平衡数据集的"第二支箭"。