You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

多标签不平衡数据集处理:imblearn SMOTE不支持,求替代方案

多标签分类不平衡问题的SMOTE替代方案

针对多标签分类的不平衡问题,以下是几种可行的SMOTE替代方法:

MLSMOTE(Multi-Label SMOTE)

这是专门为多标签场景设计的过采样方法,核心思路是基于样本的完整标签组合识别少数类,再在同类标签组合的样本中生成合成数据,避免单标签过采样破坏标签间的关联。

你可以通过自定义实现来使用,以下是一个简化的Python实现示例:

import numpy as np
from sklearn.neighbors import NearestNeighbors
from collections import Counter

def mlsmote(X, y, k_neighbors=5, n_samples=100):
    # 统计所有标签组合的出现次数
    label_combos = [tuple(row) for row in y]
    combo_counts = Counter(label_combos)
    # 定义少数类标签组合(这里以中位数为阈值)
    minority_combos = [combo for combo, cnt in combo_counts.items() if cnt < np.median(list(combo_counts.values()))]
    
    synthetic_X = []
    synthetic_y = []
    
    for combo in minority_combos:
        # 提取当前标签组合的所有样本
        sample_idx = np.where([tuple(row) == combo for row in y])[0]
        X_minority = X[sample_idx]
        y_minority = y[sample_idx]
        
        # 拟合KNN模型找近邻
        nn_model = NearestNeighbors(n_neighbors=k_neighbors)
        nn_model.fit(X_minority)
        
        # 生成合成样本
        gen_count = n_samples // len(minority_combos)
        for _ in range(gen_count):
            # 随机选一个基准样本
            base_idx = np.random.randint(0, len(X_minority))
            # 获取其近邻(排除自身)
            neighbor_ids = nn_model.kneighbors(X_minority[base_idx].reshape(1, -1), return_distance=False)[0][1:]
            neighbor_idx = np.random.choice(neighbor_ids)
            # 插值生成新样本
            diff = X_minority[neighbor_idx] - X_minority[base_idx]
            alpha = np.random.rand()
            new_sample = X_minority[base_idx] + alpha * diff
            
            synthetic_X.append(new_sample)
            synthetic_y.append(combo)
    
    # 合并原数据与合成数据
    return np.vstack([X, np.array(synthetic_X)]), np.vstack([y, np.array(synthetic_y)])

基于标签子集的过采样

如果不需要严格保留完整标签组合,可以针对单个标签的少数类分别处理:对每个目标变量,单独识别其少数类样本,用SMOTE生成对应样本后,保留原样本的其他标签值。这种方法实现简单,但可能会引入标签冲突(比如生成的样本在多个标签上同时属于少数类,不符合原数据的标签关联),适合标签独立性较强的场景。

示例代码片段:

from imblearn.over_sampling import SMOTE

def per_label_smote(X, y, sampling_strategy='auto'):
    X_resampled = X.copy()
    y_resampled = y.copy()
    
    for label_col in range(y.shape[1]):
        # 单独处理每个目标标签
        sm = SMOTE(sampling_strategy=sampling_strategy)
        X_temp, y_temp = sm.fit_resample(X_resampled, y_resampled[:, label_col])
        # 合并其他标签列
        y_temp_full = np.zeros((len(X_temp), y.shape[1]))
        y_temp_full[:, label_col] = y_temp
        # 复制其他标签的原有值
        for col in range(y.shape[1]):
            if col != label_col:
                y_temp_full[:, col] = np.concatenate([y_resampled[:, col], y_resampled[:, col][sm.sample_indices_]])
        
        X_resampled, y_resampled = X_temp, y_temp_full
    
    return X_resampled, y_resampled

MLADASYN(Multi-Label ADASYN)

ADASYN的多标签版本,和MLSMOTE类似,但会根据样本的难分类程度调整合成样本数量——对那些被多数类样本包围的少数类样本,生成更多合成数据,提升模型对难分样本的识别能力。实现思路和MLSMOTE接近,只是在生成样本时,给难分样本分配更高的采样权重。

聚类辅助的多标签过采样

先对所有样本进行聚类(比如用K-Means),在每个簇内部识别不平衡的标签组合,再针对簇内的少数类进行过采样。这种方法能保留样本的局部特征分布,避免生成不符合数据分布的合成样本,适合特征空间具有明显聚类结构的数据集。

额外建议

  • 不要单纯依赖过采样,可结合多数类欠采样(比如随机欠采样、聚类欠采样),平衡计算成本与数据分布。
  • 过采样后建议用交叉验证评估模型性能,避免过拟合。

内容的提问来源于stack exchange,提问作者Miuni Nihara

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.24 06:15:32