You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何在Python中查看K-modes聚类的特征重要性?

分析K-modes聚类中各分类变量的贡献方法

针对你用K-modes聚类12个分类变量得到3个簇后,想分析每个变量对聚类结果的贡献这个问题,我整理了几个实用的方法,都是分类聚类场景下常用的思路:

方法1:基于卡方检验的类别关联分析

K-modes的核心是利用分类变量的类别分布区分簇,所以一个变量对聚类的贡献越大,它和簇标签的关联性就越强。卡方检验正好可以量化这种关联性——卡方值越大,说明变量的类别分布在不同簇间的差异越显著,对聚类的区分作用越强。

操作步骤:

  • 对每个分类变量,构建它与簇标签的列联表(即每个类别在各簇中的样本数)
  • 计算卡方统计量和对应的p值:p值小于0.05(常规显著性水平)说明变量和簇显著相关,卡方值的排序能直接反映变量的贡献优先级

代码示例(Python):

from scipy.stats import chi2_contingency
import pandas as pd

# 假设你的数据集是df,簇标签列名为'cluster'
for col in df.columns[:-1]:  # 遍历所有分类变量,排除簇标签列
    # 构建列联表
    contingency_table = pd.crosstab(df[col], df['cluster'])
    # 计算卡方检验结果
    chi2, p_value, dof, expected = chi2_contingency(contingency_table)
    print(f"变量【{col}】:卡方值 = {chi2:.2f},p值 = {p_value:.4f}")

方法2:基于簇模式差异的直观分析

K-modes每个簇都会生成一个“模式”(cluster centroid,即每个变量在簇中出现频率最高的类别)。如果某个变量在不同簇的模式差异越大,说明它越能帮助区分不同簇。

操作步骤:

  • 从训练好的K-modes模型中提取各簇的模式(比如kmodes库中,模型的cluster_centroids_属性就是各簇的模式矩阵)
  • 对每个变量,分析其在不同簇间的模式差异:比如统计不同模式的数量,或者计算各簇类别频率的标准差(标准差越大,差异越显著)

代码示例(Python):

from kmodes.kmodes import KModes
import pandas as pd

# 假设已经训练好K-modes模型km,数据集是df,簇标签列是'cluster'
cluster_modes = km.cluster_centroids_
variables = df.columns[:-1]

for idx, var in enumerate(variables):
    # 获取该变量在所有簇中的模式
    var_modes = cluster_modes[:, idx]
    # 统计模式的唯一值数量:数量越多,簇间差异越大
    unique_mode_count = len(set(var_modes))
    # 计算该变量在各簇的类别频率标准差
    freq_table = pd.crosstab(df[var], df['cluster']).apply(lambda x: x/x.sum(), axis=0)
    avg_freq_std = freq_table.std(axis=1).mean()
    
    print(f"变量【{var}】:簇间唯一模式数 = {unique_mode_count},类别频率平均标准差 = {avg_freq_std:.4f}")

方法3:基于置换检验的特征重要性评估

这是最直接衡量变量贡献的方法:通过打乱某个变量的取值,模拟“移除该变量信息”的场景,观察聚类成本(K-modes的成本是所有样本到对应簇模式的不匹配变量数之和)的变化。如果打乱后成本上升越多,说明该变量对聚类的贡献越大。

操作步骤:

  • 记录原始聚类的成本(模型的cost_属性)
  • 对每个变量,随机打乱其所有取值,保持其他变量不变
  • 计算打乱后的聚类成本,对比原始成本的变化比例,比例越大说明变量越重要

代码示例(Python):

from kmodes.kmodes import KModes
import pandas as pd
import numpy as np

# 假设已经训练好模型km,数据集是df,簇标签是km.labels_
original_cost = km.cost_
variables = df.columns[:-1]

def calculate_cluster_cost(df, cluster_modes, cluster_labels):
    """计算给定数据和簇模式的K-modes成本"""
    total_cost = 0
    for i, label in enumerate(cluster_labels):
        # 计算当前样本到对应簇模式的不匹配数
        mismatch_count = sum(df.iloc[i] != cluster_modes[label])
        total_cost += mismatch_count
    return total_cost

for var in variables:
    # 复制数据集并打乱当前变量的取值
    df_shuffled = df.copy()
    df_shuffled[var] = df_shuffled[var].sample(frac=1).values.reset_index(drop=True)
    # 计算打乱后的成本
    shuffled_cost = calculate_cluster_cost(df_shuffled, km.cluster_centroids_, km.labels_)
    # 计算成本增加比例
    cost_increase_ratio = (shuffled_cost - original_cost) / original_cost
    print(f"变量【{var}】:成本增加比例 = {cost_increase_ratio:.2%}")

方法总结

  • 如果想快速筛选和簇显著相关的变量,优先用卡方检验
  • 如果想直观理解变量在簇间的区分逻辑,选簇模式差异分析
  • 如果要最准确衡量变量对聚类性能的影响,置换检验是最优选择

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

火山引擎 最新活动