Python案例如何用Pandas做数据分组聚类评估

wen python案例 1

本文目录导读:

Python案例如何用Pandas做数据分组聚类评估

  1. 准备数据和基础分组
  2. 特征标准化和聚类
  3. 聚类评估指标
  4. 寻找最佳K值
  5. 聚类结果分析与可视化
  6. 高级分组聚类分析
  7. 完整的聚类管道
  8. 结果汇总报告
  9. 使用建议

我来详细介绍如何使用Pandas进行数据分组、聚类以及相关评估的完整案例。

准备数据和基础分组

import pandas as pd
import numpy as np
from sklearn.cluster import KMeans
from sklearn.preprocessing import StandardScaler
from sklearn.metrics import silhouette_score, calinski_harabasz_score
import matplotlib.pyplot as plt
import seaborn as sns
# 创建示例数据
np.random.seed(42)
data = {
    'customer_id': range(1, 101),
    'age': np.random.randint(18, 65, 100),
    'income': np.random.randint(20000, 150000, 100),
    'spending_score': np.random.randint(1, 100, 100),
    'purchase_frequency': np.random.randint(1, 20, 100),
    'category': np.random.choice(['A', 'B', 'C'], 100)
}
df = pd.DataFrame(data)
print("原始数据预览:")
print(df.head())
# 基础分组统计
grouped_stats = df.groupby('category').agg({
    'age': ['mean', 'std'],
    'income': ['mean', 'std'],
    'spending_score': ['mean', 'std']
}).round(2)
print("\n按类别分组统计:")
print(grouped_stats)

特征标准化和聚类

# 选择用于聚类的特征
features = ['age', 'income', 'spending_score', 'purchase_frequency']
X = df[features]
# 标准化数据
scaler = StandardScaler()
X_scaled = scaler.fit_transform(X)
# K-means聚类
kmeans = KMeans(n_clusters=3, random_state=42)
df['cluster'] = kmeans.fit_predict(X_scaled)
print("聚类结果分布:")
print(df['cluster'].value_counts())

聚类评估指标

def evaluate_clustering(X, labels):
    """
    计算聚类评估指标
    """
    metrics = {}
    # 轮廓系数 (-1到1,越大越好)
    metrics['silhouette'] = silhouette_score(X, labels)
    # Calinski-Harabasz指数 (越大越好)
    metrics['calinski_harabasz'] = calinski_harabasz_score(X, labels)
    # 惯性 (越小越好)
    metrics['inertia'] = kmeans.inertia_
    return metrics
# 评估当前聚类
metrics = evaluate_clustering(X_scaled, df['cluster'])
print("聚类评估指标:")
for metric, value in metrics.items():
    print(f"{metric}: {value:.3f}")

寻找最佳K值

def find_optimal_k(X, max_k=10):
    """
    通过肘部法则和轮廓系数寻找最佳K值
    """
    inertias = []
    silhouettes = []
    K_range = range(2, max_k + 1)
    for k in K_range:
        kmeans = KMeans(n_clusters=k, random_state=42)
        labels = kmeans.fit_predict(X)
        inertias.append(kmeans.inertia_)
        silhouettes.append(silhouette_score(X, labels))
    # 可视化
    fig, axes = plt.subplots(1, 2, figsize=(12, 4))
    axes[0].plot(K_range, inertias, 'bo-')
    axes[0].set_xlabel('K值')
    axes[0].set_ylabel('惯性')
    axes[0].set_title('肘部法则')
    axes[0].grid(True)
    axes[1].plot(K_range, silhouettes, 'ro-')
    axes[1].set_xlabel('K值')
    axes[1].set_ylabel('轮廓系数')
    axes[1].set_title('轮廓系数分析')
    axes[1].grid(True)
    plt.tight_layout()
    plt.show()
    return inertias, silhouettes
inertias, silhouettes = find_optimal_k(X_scaled)

聚类结果分析与可视化

def analyze_clusters(df, cluster_col='cluster'):
    """
    分析聚类结果
    """
    # 聚类中心分析
    cluster_centers = df.groupby(cluster_col).agg({
        'age': 'mean',
        'income': 'mean', 
        'spending_score': 'mean',
        'purchase_frequency': 'mean'
    }).round(2)
    print("各聚类中心(平均值):")
    print(cluster_centers)
    # 聚类大小
    cluster_sizes = df[cluster_col].value_counts().sort_index()
    print(f"\n聚类大小分布:")
    print(cluster_sizes)
    # 可视化
    fig, axes = plt.subplots(2, 2, figsize=(12, 10))
    # 收入与消费分数散点图
    for cluster in df[cluster_col].unique():
        mask = df[cluster_col] == cluster
        axes[0, 0].scatter(df.loc[mask, 'income'], 
                          df.loc[mask, 'spending_score'],
                          label=f'聚类 {cluster}', alpha=0.6)
    axes[0, 0].set_xlabel('收入')
    axes[0, 0].set_ylabel('消费分数')
    axes[0, 0].set_title('收入 vs 消费分数')
    axes[0, 0].legend()
    axes[0, 0].grid(True)
    # 年龄与购买频次散点图
    for cluster in df[cluster_col].unique():
        mask = df[cluster_col] == cluster
        axes[0, 1].scatter(df.loc[mask, 'age'],
                          df.loc[mask, 'purchase_frequency'],
                          label=f'聚类 {cluster}', alpha=0.6)
    axes[0, 1].set_xlabel('年龄')
    axes[0, 1].set_ylabel('购买频次')
    axes[0, 1].set_title('年龄 vs 购买频次')
    axes[0, 1].legend()
    axes[0, 1].grid(True)
    # 聚类大小柱状图
    axes[1, 0].bar(cluster_sizes.index, cluster_sizes.values)
    axes[1, 0].set_xlabel('聚类')
    axes[1, 0].set_ylabel('样本数')
    axes[1, 0].set_title('各聚类样本数')
    axes[1, 0].grid(True)
    # 特征分布箱线图
    df_box = df.melt(id_vars=[cluster_col], 
                     value_vars=['age', 'income', 'spending_score'],
                     var_name='特征', value_name='数值')
    sns.boxplot(data=df_box, x='特征', y='数值', hue=cluster_col, ax=axes[1, 1])
    axes[1, 1].set_title('各特征在不同聚类的分布')
    axes[1, 1].tick_params(axis='x', rotation=45)
    plt.tight_layout()
    plt.show()
    return cluster_centers
cluster_centers = analyze_clusters(df)

高级分组聚类分析

def advanced_group_clustering(df, group_col='category', features=['age', 'income', 'spending_score']):
    """
    对每个组进行独立的聚类分析
    """
    results = {}
    for group in df[group_col].unique():
        group_data = df[df[group_col] == group]
        X_group = group_data[features]
        # 标准化
        scaler = StandardScaler()
        X_scaled = scaler.fit_transform(X_group)
        # 对每组进行聚类
        kmeans = KMeans(n_clusters=2, random_state=42)
        labels = kmeans.fit_predict(X_scaled)
        results[group] = {
            'size': len(group_data),
            'silhouette_score': silhouette_score(X_scaled, labels),
            'cluster_distribution': pd.Series(labels).value_counts().to_dict()
        }
    # 转换为DataFrame
    results_df = pd.DataFrame(results).T
    print("各组聚类结果:")
    print(results_df)
    return results_df
group_results = advanced_group_clustering(df)

完整的聚类管道

class ClusteringPipeline:
    """
    完整的聚类分析管道
    """
    def __init__(self, features, n_clusters=3):
        self.features = features
        self.n_clusters = n_clusters
        self.scaler = StandardScaler()
        self.kmeans = KMeans(n_clusters=n_clusters, random_state=42)
    def fit_predict(self, df):
        """执行完整的聚类流程"""
        X = df[self.features]
        X_scaled = self.scaler.fit_transform(X)
        df['cluster'] = self.kmeans.fit_predict(X_scaled)
        # 计算评估指标
        metrics = {
            'silhouette': silhouette_score(X_scaled, df['cluster']),
            'calinski_harabasz': calinski_harabasz_score(X_scaled, df['cluster']),
            'inertia': self.kmeans.inertia_
        }
        return df, metrics
    def predict_new(self, df):
        """预测新数据"""
        X = df[self.features]
        X_scaled = self.scaler.transform(X)
        return self.kmeans.predict(X_scaled)
# 使用管道
pipeline = ClusteringPipeline(features=['age', 'income', 'spending_score', 'purchase_frequency'])
df_result, metrics = pipeline.fit_predict(df.copy())
print("管道执行结果:")
print(f"轮廓系数: {metrics['silhouette']:.3f}")
print(f"Calinski-Harabasz指数: {metrics['calinski_harabasz']:.3f}")
print(f"惯性: {metrics['inertia']:.3f}")

结果汇总报告

def generate_clustering_report(df, cluster_col='cluster'):
    """
    生成聚类分析报告
    """
    report = []
    print("=" * 60)
    print("聚类分析报告")
    print("=" * 60)
    print(f"\n数据基本信息:")
    print(f"总样本数: {len(df)}")
    print(f"聚类数: {df[cluster_col].nunique()}")
    print(f"\n聚类分布:")
    for cluster in sorted(df[cluster_col].unique()):
        cluster_data = df[df[cluster_col] == cluster]
        print(f"聚类 {cluster}: {len(cluster_data)} 样本 ({len(cluster_data)/len(df)*100:.1f}%)")
        # 该聚类的特征描述
        desc = cluster_data.describe()
        report.append({
            'cluster': cluster,
            'size': len(cluster_data),
            'percentage': f"{len(cluster_data)/len(df)*100:.1f}%",
            'avg_age': f"{desc['age']['mean']:.1f}",
            'avg_income': f"${desc['income']['mean']:.0f}",
            'avg_spending': f"{desc['spending_score']['mean']:.1f}"
        })
    report_df = pd.DataFrame(report)
    print(f"\n聚类特征摘要:")
    print(report_df.to_string(index=False))
    return report_df
report = generate_clustering_report(df)

使用建议

  1. 数据预处理: 确保处理缺失值、异常值,标准化特征
  2. 特征选择: 选择与业务目标相关的特征
  3. K值选择: 使用肘部法则和轮廓系数综合判断
  4. 结果验证: 使用多种评估指标交叉验证
  5. 业务解释: 确保聚类结果具有业务可解释性

这个案例展示了如何使用Pandas配合sklearn进行完整的数据分组聚类评估流程,包括数据准备、聚类执行、评估分析和结果可视化。

抱歉,评论功能暂时关闭!