本文目录导读:

我来详细介绍如何使用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)
使用建议
- 数据预处理: 确保处理缺失值、异常值,标准化特征
- 特征选择: 选择与业务目标相关的特征
- K值选择: 使用肘部法则和轮廓系数综合判断
- 结果验证: 使用多种评估指标交叉验证
- 业务解释: 确保聚类结果具有业务可解释性
这个案例展示了如何使用Pandas配合sklearn进行完整的数据分组聚类评估流程,包括数据准备、聚类执行、评估分析和结果可视化。