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

Python中DataFrame行相似性检测:合并分类目标类简化模型

解决多类别分类任务中的类别合并问题

核心目标

通过合并特征相似的类别,将50个类别缩减至更易处理的数量,同时维持原数据集的概率分布基本不变。

具体实现方案

1. 先做类别级特征聚合,而非样本级聚类

不能直接对单条数据行聚类,而是先为每个原始类别生成特征聚合表征:

  • 数值特征:计算该类别下各特征的均值、中位数或分位数统计量
  • 类别特征:统计该类别下各特征的众数或频率分布
    每个原始类别会对应一个固定的特征向量,后续的相似性判断都基于这个向量。

2. 选择适配的相似性度量

根据特征类型选合适的相似性指标:

  • 纯数值聚合特征:用欧氏距离、余弦相似度或曼哈顿距离
  • 混合类型特征:用Gower距离(专门处理数值+类别混合数据的相似性计算)

3. 带分布约束的聚类合并

用聚类算法合并类别时,加入分布保护规则:

  • 层次聚类:通过树状图手动控制合并阈值,优先合并特征最相似的类别,过程中可以实时观察每个合并组的样本占比,确保和原类别占比之和一致
  • K-Means聚类:提前设定目标类别数(比如从50降到20),但需要限制每个聚类组的样本占比,与被合并的原始类别占比总和偏差不超过预设阈值(比如5%)
  • 核心原则:合并后的新类别样本占比 = 被合并的所有原始类别样本占比之和,保证整体概率分布不偏移

4. 分布一致性验证

合并后必须验证分布是否符合要求:

  • 统计原数据集每个类别的样本占比,对比合并后新类别对应的占比之和,用KL散度或卡方检验衡量分布差异,数值越小说明分布越接近
  • 检查特征分布:对每个特征,用KS检验对比原类别组和合并后新类别的特征分布,确保差异在可接受范围内

伪代码示例

# 1. 生成每个类别的特征聚合向量
class_feature_profiles = df.groupby('Y').agg({
    'x1': 'mean',
    'x2': 'median',
    'x3': 'mean'
}).values

# 2. 计算类别间相似性矩阵
from sklearn.metrics.pairwise import cosine_similarity
similarity_matrix = cosine_similarity(class_feature_profiles)

# 3. 层次聚类合并类别
from scipy.cluster.hierarchy import linkage, fcluster
linkage_result = linkage(class_feature_profiles, method='ward')
# 设定合并后的目标类别数为20
cluster_labels = fcluster(linkage_result, t=20, criterion='maxclust')

# 4. 映射原始类别到新类别
class_mapping = {y: f'val_{c}' for y, c in zip(df['Y'].unique(), cluster_labels)}
df['New Y'] = df['Y'].map(class_mapping)

# 5. 验证分布偏差
original_dist = df['Y'].value_counts(normalize=True)
new_dist = df['New Y'].value_counts(normalize=True)
from scipy.stats import entropy
kl_divergence = entropy(original_dist, new_dist)
print(f"分布差异KL散度: {kl_divergence}")

关键注意点

  • 优先合并小样本类别:样本量极少的类别,即使特征差异稍大,也可合并到最相似的类别,避免分布失衡
  • 避免样本级聚类:直接聚类单条数据会打散同一类别的样本,导致合并逻辑混乱
  • 迭代调整:先尝试合并到30个类别,验证分布后再逐步缩减,找到模型性能和分布一致性的平衡点

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.22 20:51:13