如何可视化Pandas DataFrame跨列分类值差异并重排类别名称?
分类结果对比实现方案
原始数据
首先加载示例数据,每列对应一种分类算法的输出,行是待分类的索引条目:
import pandas as pd df = pd.DataFrame(index = ['a', 'b', 'c', 'd', 'e', 'f', 'g']) df['A'] = ['a1', 'a1', 'a2', 'a2', 'a3', 'a4', 'a4'] df['B'] = ['b2', 'b2', 'b2', 'b1', 'b4', 'b3', 'b3'] df['C'] = ['c4', 'c4', 'c4', 'c3', 'c2', 'c2', 'c1']
原始数据预览:
A B C a a1 b2 c4 b a1 b2 c4 c a2 b2 c4 d a2 b1 c3 e a3 b4 c2 f a4 b3 c2 g a4 b3 c1
第一步:跨列类别重排对齐
不同列的类别标签是独立命名的,比如A列的a1、B列的b2、C列的c4标签名完全不同,但包含的样本高度重合,直接对比原始标签无法判断分类相似性。需要基于类别包含样本的重合度,把不同列中匹配度最高的类别映射为统一序号,消除标签命名的干扰。
实现逻辑是用Jaccard系数计算不同列类别之间的样本重合度,通过匈牙利算法做全局最优匹配,完成标签对齐:
import numpy as np from scipy.optimize import linear_sum_assignment # 选A列作为对齐基准,也可替换为其他列 base_col = 'A' base_cats = df[base_col].unique() aligned_df = df.copy() for col in df.columns: if col == base_col: # 基准列直接映射为从0开始的连续序号 aligned_df[col] = aligned_df[col].map({cat:idx for idx, cat in enumerate(base_cats)}) continue cur_cats = df[col].unique() # 构建相似度矩阵:值为两个类别的Jaccard相似度(交集大小/并集大小) sim_matrix = np.zeros((len(base_cats), len(cur_cats))) for i, bc in enumerate(base_cats): base_sample_set = set(df[df[base_col] == bc].index) for j, cc in enumerate(cur_cats): cur_sample_set = set(df[df[col] == cc].index) sim_matrix[i,j] = len(base_sample_set & cur_sample_set) / len(base_sample_set | cur_sample_set) # 全局最优匹配:最大化总相似度,因此用负相似度作为成本矩阵 row_idx, col_idx = linear_sum_assignment(-sim_matrix) # 生成当前列的类别映射表 cat_map = {cur_cats[col_idx[i]]: row_idx[i] for i in range(len(row_idx))} aligned_df[col] = aligned_df[col].map(cat_map)
对齐后,不同列中样本重合度最高的类别会被映射为同一个数字ID,消除了原始标签名的顺序、命名差异。
第二步:分类差异可视化
以下几种可视化方式比传统维恩图更适合多分类算法的结果对比:
- 聚类热图(最推荐)
行对应样本,列对应不同分类算法,用颜色代表对齐后的类别ID,单元格内可以标注原始类别标签,同一行颜色越统一说明不同算法对该样本的分类一致性越高。示例代码:import seaborn as sns import matplotlib.pyplot as plt sns.heatmap(aligned_df, annot=df.values, cmap='Set2', cbar=False, fmt='') plt.xlabel('分类算法') plt.ylabel('样本索引') plt.title('多算法分类结果对齐对比') plt.show() - Upset图(维恩图最优替代方案)
传统维恩图在集合数超过3个时可读性会急剧下降,Upset图专门用于展示多集合的交集大小:可以将每个算法下的同一类别作为一个集合,统计不同分类组合对应的样本数量,清晰展示有多少样本在所有算法中分类一致、多少样本存在分类分歧。 - 桑基图
不需要提前做类别对齐,按算法顺序排列列,用流的宽度代表两个类别之间重合的样本数量,可以直观看到不同算法类别之间的对应关系、错配样本的规模。
内容的提问来源于stack exchange,提问作者MathMan 99
相关产品推荐
相关产品推荐

