python打卡 DAY 18 推断聚类后簇的类型

目录

聚类结果分析与簇类型推断学习笔记

一、聚类后分析基础流程

1.1 基本分析步骤

1.2 常用可视化工具

二、簇特征分析方法

2.1 数值型特征分析

簇中心对比

雷达图展示

2.2 类别型特征分析

频数统计

卡方检验

三、簇类型推断技术

3.1 基于统计特征的推断

关键指标计算

特征重要性排序

3.2 基于业务规则的标签分配

业务规则示例(电商场景)

3.3 自动化标签生成(NLP技术)

使用TF-IDF生成标签

四、验证与优化方法

4.1 簇稳定性检验

重采样验证

4.2 业务合理性验证

专家评估表设计

五、实战案例:客户分群分析

5.1 RFM模型聚类

5.2 簇类型定义

六、常见问题解决方案

6.1 簇难以解释的情况

6.2 混合型数据处理

作业:接续 day17 内容

5簇的含义

4簇的含义

3簇类型推断

2推断簇的类型

1 推断簇的类型

0推断簇的类型


聚类结果分析与簇类型推断学习笔记

一、聚类后分析基础流程

1.1 基本分析步骤

  1. 可视化检查:降维后观察簇分布

  2. 统计特征:计算各簇的统计量

  3. 对比分析:识别簇间差异特征

  4. 业务解释:结合领域知识赋予语义

1.2 常用可视化工具

import matplotlib.pyplot as plt
from sklearn.decomposition import PCA

# 降维可视化
pca = PCA(n_components=2)
X_pca = pca.fit_transform(X)

plt.scatter(X_pca[:,0], X_pca[:,1], c=labels, cmap='viridis')
plt.title("Cluster Visualization (PCA)")
plt.show()

二、簇特征分析方法

2.1 数值型特征分析

簇中心对比
import pandas as pd

# 计算各簇中心
centers = pd.DataFrame(
    scaler.inverse_transform(kmeans.cluster_centers_),
    columns=feature_names
)

# 可视化
centers.plot(kind='bar', figsize=(12,6))
plt.title("Cluster Centers Comparison")
plt.ylabel("Feature Value (Original Scale)")
plt.xticks(rotation=0)
plt.show()
雷达图展示
from math import pi

# 准备数据
categories = centers.columns
N = len(categories)
angles = [n / float(N) * 2 * pi for n in range(N)]
angles += angles[:1]

fig = plt.figure(figsize=(8,8))
ax = fig.add_subplot(111, polar=True)

for i in range(len(centers)):
    values = centers.iloc[i].values.flatten().tolist()
    values += values[:1]
    ax.plot(angles, values, linewidth=1, label=f'Cluster {i}')
    ax.fill(angles, values, alpha=0.1)

ax.set_xticks(angles[:-1])
ax.set_xticklabels(categories)
plt.legend(loc='upper right')
plt.title("Cluster Profiles (Radar Chart)")
plt.show()

2.2 类别型特征分析

频数统计
# 添加聚类标签到原始数据
data['cluster'] = labels

# 分类变量分析
for col in categorical_cols:
    cross_tab = pd.crosstab(data['cluster'], data[col], normalize='index')
    cross_tab.plot(kind='bar', stacked=True, figsize=(10,4))
    plt.title(f"Distribution of {col} by Cluster")
    plt.ylabel("Proportion")
    plt.show()
卡方检验
from scipy.stats import chi2_contingency

for col in categorical_cols:
    contingency_table = pd.crosstab(data['cluster'], data[col])
    chi2, p, _, _ = chi2_contingency(contingency_table)
    print(f"{col}: χ²={chi2:.1f}, p={p:.3f}")

三、簇类型推断技术

3.1 基于统计特征的推断

关键指标计算
cluster_stats = data.groupby('cluster').agg({
    'age': ['mean', 'std'],
    'income': ['median', 'min', 'max'],
    'purchase_frequency': 'mean'
})

# 标准化比较
normalized_stats = cluster_stats.apply(
    lambda x: (x - x.mean()) / x.std(), 
    axis=0
)
特征重要性排序
# 计算簇间差异最大的特征
feature_importance = {}
for col in numeric_cols:
    f_val, p_val = f_oneway(*[data[data['cluster']==i][col] for i in range(n_clusters)])
    feature_importance[col] = f_val

sorted_features = sorted(feature_importance.items(), key=lambda x: -x[1])

3.2 基于业务规则的标签分配

业务规则示例(电商场景)
def assign_cluster_label(row):
    if row['recency'] > 30 and row['frequency'] < 2:
        return '流失风险客户'
    elif row['monetary'] > 500 and row['frequency'] > 5:
        return '高价值客户'
    else:
        return '普通客户'

data['cluster_label'] = data.apply(assign_cluster_label, axis=1)

3.3 自动化标签生成(NLP技术)

使用TF-IDF生成标签
from sklearn.feature_extraction.text import TfidfVectorizer

# 假设有文本型特征
tfidf = TfidfVectorizer(max_features=50)
tfidf_matrix = tfidf.fit_transform(data['text_feature'])

# 聚合每个簇的关键词
for i in range(n_clusters):
    cluster_tfidf = tfidf_matrix[labels==i].mean(axis=0)
    top_words_idx = cluster_tfidf.argsort()[0,-3:][::-1]
    top_words = [tfidf.get_feature_names_out()[i] for i in top_words_idx]
    print(f"Cluster {i} 关键词:", ", ".join(top_words))

四、验证与优化方法

4.1 簇稳定性检验

重采样验证
from sklearn.utils import resample

stability_scores = []
for _ in range(10):
    # 重采样
    X_sample = resample(X, random_state=42)
    
    # 重新聚类
    kmeans_sample = KMeans(n_clusters=3).fit(X_sample)
    
    # 计算相似度(使用调整兰德指数)
    ari = adjusted_rand_score(labels, kmeans_sample.labels_)
    stability_scores.append(ari)

print(f"平均稳定性得分: {np.mean(stability_scores):.3f}")

4.2 业务合理性验证

专家评估表设计
簇ID主要特征假设类型业务合理性(1-5)备注
0高收入低频潜在VIP4需激活消费频率
1低收入高频价格敏感5适合促销活动

五、实战案例:客户分群分析

5.1 RFM模型聚类

# 计算RFM指标
recency = (current_date - purchase_dates).dt.days
frequency = purchase_history.groupby('customer_id').size()
monetary = purchase_history.groupby('customer_id')['amount'].sum()

# 标准化
rfm = pd.DataFrame({'Recency': recency, 'Frequency': frequency, 'Monetary': monetary})
rfm_scaled = StandardScaler().fit_transform(rfm)

# 聚类
kmeans = KMeans(n_clusters=5)
rfm['cluster'] = kmeans.fit_predict(rfm_scaled)

5.2 簇类型定义

RecencyFrequencyMonetary类型标签营销策略
0低(新近)冠军客户专属服务/高端推荐
1高(久远)流失客户唤醒优惠/问卷调查
2潜力客户交叉销售/忠诚计划

六、常见问题解决方案

6.1 簇难以解释的情况

解决方案

  1. 尝试不同聚类算法(如DBSCAN可能发现密度簇)

  2. 增加/减少簇数量

  3. 使用特征选择技术去除噪声特征

  4. 尝试不同的特征组合或衍生新特征

6.2 混合型数据处理

处理流程

from sklearn.compose import ColumnTransformer
from sklearn.pipeline import Pipeline
from sklearn.preprocessing import OneHotEncoder

# 数值型和类别型分别处理
preprocessor = ColumnTransformer(
    transformers=[
        ('num', StandardScaler(), numeric_cols),
        ('cat', OneHotEncoder(), categorical_cols)
    ])

# 构建聚类流水线
cluster_pipe = Pipeline([
    ('preprocess', preprocessor),
    ('cluster', KMeans(n_clusters=3))
])

作业:接续 day17 内容

接续 DAY17 的内容, 对 kmeans 聚类后的簇类型进行分析:

x1= X.drop('KMeans_Cluster',axis=1) # 删除聚类标签列
y1 = X['KMeans_Cluster']
# 构建随机森林,用shap重要性来筛选重要性
import shap
import numpy as np
from sklearn.ensemble import RandomForestClassifier  # 随机森林分类器
model = RandomForestClassifier(n_estimators=100, random_state=42)  # 随机森林模型
model.fit(x1, y1)  # 训练模型,此时无需在意准确率 直接全部数据用来训练了
shap.initjs()

# 初始化 SHAP 解释器
explainer = shap.TreeExplainer(model)
shap_values = explainer.shap_values(x1) # 这个计算耗时
shap_values.shape # 第一维是样本数,第二维是特征数,第三维是类别数

SHAP 特征重要性条形图,挑选出最重要的四个特征进行分析 

# --- 1. SHAP 特征重要性条形图 (Summary Plot - Bar) ---
print("--- 1. SHAP 特征重要性条形图 ---")
shap.summary_plot(shap_values[:, :, 0], x1, plot_type="bar",show=False)  #  这里的show=False表示不直接显示图形,这样可以继续用plt来修改元素,不然就直接输出了
plt.title("SHAP Feature Importance (Bar Plot)")
plt.show()

 

 判断一下这几个特征是离散型还是连续型:

# 此时判断一下这几个特征是离散型还是连续型
import pandas as pd
selected_features = [ 'slope','sex',  'target', 'thalach']

for feature in selected_features:
    unique_count = X[feature].nunique() # 唯一值指的是在某一列或某个特征中,不重复出现的值
    # 连续型变量通常有很多唯一值,而离散型变量的唯一值较少
    print(f'{feature} 的唯一值数量: {unique_count}')
    if unique_count < 10:  # 这里 10 是一个经验阈值,可以根据实际情况调整
        print(f'{feature} 可能是离散型变量')
    else:
        print(f'{feature} 可能是连续型变量')

总样本中的前四个重要性的特征分布图 

# X["Purpose_debt consolidation"].value_counts() # 统计每个唯一值的出现次数
import matplotlib.pyplot as plt

# 总样本中的前四个重要性的特征分布图
fig, axes = plt.subplots(2, 2, figsize=(12, 8))
axes = axes.flatten()

for i, feature in enumerate(selected_features):
    axes[i].hist(X[feature], bins=20)
    axes[i].set_title(f'Histogram of {feature}')
    axes[i].set_xlabel(feature)
    axes[i].set_ylabel('Frequency')

plt.tight_layout()
plt.show()

 

# 绘制出每个簇对应的这四个特征的分布图
X[['KMeans_Cluster']].value_counts()

查看簇数 

 

# 分别筛选出每个簇的数据
X_cluster0 = X[X['KMeans_Cluster'] == 0]
X_cluster1 = X[X['KMeans_Cluster'] == 1]
X_cluster2 = X[X['KMeans_Cluster'] == 2]
X_cluster3 = X[X['KMeans_Cluster'] == 3]
X_cluster4 = X[X['KMeans_Cluster'] == 4]
X_cluster5 = X[X['KMeans_Cluster'] == 5]

 绘制簇0的分布图

# 先绘制簇0的分布图

import matplotlib.pyplot as plt

# 总样本中的前四个重要性的特征分布图
fig, axes = plt.subplots(2, 2, figsize=(12, 8))
axes = axes.flatten()

for i, feature in enumerate(selected_features):
    axes[i].hist(X_cluster0[feature], bins=20)
    axes[i].set_title(f'Histogram of {feature}')
    axes[i].set_xlabel(feature)
    axes[i].set_ylabel('Frequency')

plt.tight_layout()
plt.show()

绘制簇1的分布图

# 绘制簇1的分布图

import matplotlib.pyplot as plt

# 总样本中的前四个重要性的特征分布图
fig, axes = plt.subplots(2, 2, figsize=(12, 8))
axes = axes.flatten()

for i, feature in enumerate(selected_features):
    axes[i].hist(X_cluster1[feature], bins=20)
    axes[i].set_title(f'Histogram of {feature}')
    axes[i].set_xlabel(feature)
    axes[i].set_ylabel('Frequency')

plt.tight_layout()
plt.show()

 绘制簇2的分布图

# 先绘制簇2的分布图

import matplotlib.pyplot as plt

# 总样本中的前四个重要性的特征分布图
fig, axes = plt.subplots(2, 2, figsize=(12, 8))
axes = axes.flatten()

for i, feature in enumerate(selected_features):
    axes[i].hist(X_cluster2[feature], bins=20)
    axes[i].set_title(f'Histogram of {feature}')
    axes[i].set_xlabel(feature)
    axes[i].set_ylabel('Frequency')

plt.tight_layout()
plt.show()

 绘制簇3的分布图

# 先绘制簇3的分布图

import matplotlib.pyplot as plt

# 总样本中的前四个重要性的特征分布图
fig, axes = plt.subplots(2, 2, figsize=(12, 8))
axes = axes.flatten()

for i, feature in enumerate(selected_features):
    axes[i].hist(X_cluster3[feature], bins=20)
    axes[i].set_title(f'Histogram of {feature}')
    axes[i].set_xlabel(feature)
    axes[i].set_ylabel('Frequency')

plt.tight_layout()
plt.show()

 绘制簇4的分布图

# 先绘制簇4的分布图

import matplotlib.pyplot as plt

# 总样本中的前四个重要性的特征分布图
fig, axes = plt.subplots(2, 2, figsize=(12, 8))
axes = axes.flatten()

for i, feature in enumerate(selected_features):
    axes[i].hist(X_cluster4[feature], bins=20)
    axes[i].set_title(f'Histogram of {feature}')
    axes[i].set_xlabel(feature)
    axes[i].set_ylabel('Frequency')

plt.tight_layout()
plt.show()

 绘制簇5的分布图

# 先绘制簇5的分布图

import matplotlib.pyplot as plt

# 总样本中的前四个重要性的特征分布图
fig, axes = plt.subplots(2, 2, figsize=(12, 8))
axes = axes.flatten()

for i, feature in enumerate(selected_features):
    axes[i].hist(X_cluster5[feature], bins=20)
    axes[i].set_title(f'Histogram of {feature}')
    axes[i].set_xlabel(feature)
    axes[i].set_ylabel('Frequency')

plt.tight_layout()
plt.show()

6个簇的总结与定义

5簇的含义

该簇代表高风险心脏病患者群体,典型特征为:

  • 男性为主,心电图ST段斜率异常,确诊心脏病比例极高。

  • 可能伴随心率异常(如运动耐受性差),需进一步临床干预。

4簇的含义

该簇代表低风险或健康人群,典型特征为:

  • 女性为主,心电图ST段斜率正常,未确诊心脏病。

  • 心率可能正常,无显著心脏疾病风险。

3簇类型推断:中等风险疑似病例

该簇很可能代表:

  • 具有部分心脏病风险因素但未明确诊断的人群

  • 或已确诊但症状较轻的心脏病患者

2推断簇的类型

  • 健康男性簇:该簇主要由男性组成,且大多数为非心脏病患者。甲状腺体积在120-160之间,斜率特征在1.0和2.0附近有两个主要的集中区域。

       该簇的含义可以总结为:

  • 健康男性:该簇中的样本主要是健康的男性,甲状腺体积在正常范围内,斜率特征在1.0和2.0附近有两个主要的集中区域。

  • 非心脏病患者:该簇中的样本大多数为非心脏病患者,表明这些特征组合与心脏病的发生没有显著关联。

1 推断簇的类型

根据上述特征分布,我们可以推断该簇的类型如下:

  • 心脏病女性簇:该簇主要由女性组成,且大多数为心脏病患者。甲状腺体积在140-180之间,斜率特征在1.0和2.0附近有两个主要的集中区域。

    该簇的含义可以总结为:

  • 心脏病女性:该簇中的样本主要是心脏病女性,甲状腺体积在140-180之间,斜率特征在1.0和2.0附近有两个主要的集中区域。

  • 心脏病患者:该簇中的样本大多数为心脏病患者,表明这些特征组合与心脏病的发生有显著关联。

0推断簇的类型

根据上述特征分布,我们可以推断该簇的类型如下:

  • 健康男性簇:该簇主要由男性组成,且大多数为非心脏病患者。甲状腺体积在120-150之间,斜率特征主要集中在1.0附近。

     该簇的含义可以总结为:

  • 健康男性:该簇中的样本主要是健康的男性,甲状腺体积在120-150之间,斜率特征主要集中在1.0附近。

  • 非心脏病患者:该簇中的样本大多数为非心脏病患者,表明这些特征组合与心脏病的发生没有显著关联。

@浙大疏锦行

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值