
Rfm Customer Segmentation
- 52 installs
- 264 repo stars
- Updated May 10, 2026
- liangdabiao/claude-data-analysis-ultra-main
Helps with ai & agent building tasks.
About
rfm-customer-segmentation is a Claude Code skill for ai & agent building. It helps solo builders move faster with AI-assisted development.
- rfm-customer-segmentation
- AI & Agent Building
- AI-coding skill
Rfm Customer Segmentation by the numbers
- 52 all-time installs (skills.sh)
- Ranked #7,142 of 16,546 AI & Agent Building skills by installs in the Skillselion catalog
- Data as of Aug 3, 2026 (Skillselion catalog sync)
npx skills add https://github.com/liangdabiao/claude-data-analysis-ultra-main --skill rfm-customer-segmentationAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 52 |
|---|---|
| repo stars | ★ 264 |
| Last updated | May 10, 2026 |
| Repository | liangdabiao/claude-data-analysis-ultra-main ↗ |
What it does
Helps with ai & agent building tasks.
Files
RFM Customer Segmentation Analysis
A comprehensive customer segmentation skill that automatically analyzes e-commerce transaction data to identify customer value segments using RFM (Recency, Frequency, Monetary) analysis with K-means clustering.
Instructions
1. Data Analysis
When users provide e-commerce data or ask about customer segmentation:
- Load and validate the transaction data
- Clean data by removing invalid orders (negative quantities, zero prices)
- Calculate RFM metrics for each customer:
- Recency: Days since last purchase
- Frequency: Number of purchases
- Monetary: Total purchase amount
- Use K-means clustering on RFM dimensions
- Automatically determine optimal number of clusters using elbow method
2. Customer Segmentation
- Create customer value segments: High, Medium, Low value customers
- Score each customer on RFM dimensions (1-3 scale)
- Calculate overall customer value scores
- Identify and rank VIP customers for marketing campaigns
3. Visualization and Reporting
- Generate comprehensive customer segmentation dashboard
- Create pie charts for segment distribution and revenue share
- Build RFM scatter plots to visualize customer patterns
- Generate box plots showing value distribution by segment
- Export detailed CSV reports with VIP customer lists
4. Marketing Insights
- Provide actionable marketing recommendations for each segment
- Generate executive summary with key findings
- Create customer activation strategies for different value tiers
- Export VIP customer lists for targeted marketing campaigns
Usage Examples
Basic Customer Segmentation
Analyze these e-commerce orders and segment customers by value:
[CSV data with order_id, user_id, purchase_date, quantity, unit_price]VIP Customer Identification
Find the top 100 most valuable customers from our sales data for marketing campaignCustomer Value Analysis
Create a customer segmentation report showing revenue contribution by customer segmentKey Features
- Automatic Data Cleaning: Handles Chinese e-commerce data formats, removes invalid orders
- Intelligent Clustering: Uses elbow method to determine optimal cluster count
- Chinese Language Support: Full support for Chinese field names and visualizations
- Comprehensive Reports: Generates HTML reports, PNG dashboards, and CSV exports
- Marketing Ready: Provides VIP customer lists and actionable insights
File Requirements
The skill works with e-commerce transaction data containing:
- user_id: Customer identification code (用户码)
- order_date: Purchase date (消费日期)
- quantity: Order quantity (数量)
- unit_price: Item unit price (单价)
- product_info: Product details (optional)
Output Files Generated
customer_segments.csv: Complete customer segmentation datavip_customers_list.csv: Ranked VIP customer list for marketingsegment_summary_statistics.csv: Detailed statistics by segmentcustomer_segmentation_dashboard.png: Visual analytics dashboarddata_validation_report.txt: Data quality and analysis validation
Dependencies
- pandas, numpy for data processing
- scikit-learn for K-means clustering
- matplotlib, seaborn for visualization (with Chinese font support)
- Standard Python libraries for file operations
Best Practices
- Ensure date fields are in consistent format (YYYY-MM-DD recommended)
- Remove or handle missing values before analysis
- Use sufficient data volume (1000+ orders recommended for reliable clustering)
- Consider business context when interpreting segment results
- Validate results with domain knowledge when possible
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
RFM Customer Segmentation Core Analysis Engine
Core algorithms for RFM analysis and customer segmentation
"""
import pandas as pd
import numpy as np
from sklearn.cluster import KMeans
from sklearn.preprocessing import StandardScaler
from datetime import datetime, timedelta
import matplotlib.pyplot as plt
import seaborn as sns
import warnings
warnings.filterwarnings('ignore')
class RFMAnalyzer:
"""Core RFM analysis engine for customer segmentation"""
def __init__(self, chinese_font='SimHei'):
"""Initialize the analyzer with Chinese font support"""
self.chinese_font = chinese_font
plt.rcParams['font.sans-serif'] = [chinese_font]
plt.rcParams['axes.unicode_minus'] = False
self.scaler = StandardScaler()
def load_and_clean_data(self, file_path):
"""
Load and clean e-commerce transaction data
Args:
file_path (str): Path to CSV file containing order data
Returns:
tuple: (original_df, cleaned_df) with original and cleaned data
"""
# Load data
try:
df = pd.read_csv(file_path, encoding='utf-8')
except UnicodeDecodeError:
try:
df = pd.read_csv(file_path, encoding='gbk')
except:
df = pd.read_csv(file_path, encoding='latin-1')
original_df = df.copy()
# Data cleaning
print(f"原始数据: {len(df)} 条订单")
# Remove invalid orders
cleaned_df = df[(df['数量'] > 0) & (df['单价'] > 0)].copy()
removed_count = len(df) - len(cleaned_df)
if removed_count > 0:
print(f"已清理 {removed_count} 条无效订单 (负数量或零价格)")
# Add calculated fields
cleaned_df['订单金额'] = cleaned_df['数量'] * cleaned_df['单价']
cleaned_df['消费日期'] = pd.to_datetime(cleaned_df['消费日期'])
print(f"清理后数据: {len(cleaned_df)} 条订单")
print(f"独立客户数: {cleaned_df['用户码'].nunique()}")
return original_df, cleaned_df
def calculate_rfm_metrics(self, df):
"""
Calculate RFM metrics for each customer
Args:
df (pd.DataFrame): Cleaned transaction data
Returns:
pd.DataFrame: RFM metrics for each customer
"""
print("计算RFM指标...")
# Calculate RFM metrics
rfm_df = df.groupby('用户码').agg({
'消费日期': 'max', # Recency: most recent purchase
'订单号': 'count', # Frequency: number of orders
'订单金额': 'sum' # Monetary: total spending
}).reset_index()
rfm_df.columns = ['用户码', '最近购买日期', '购买频率', '消费金额']
# Calculate Recency (days since last purchase)
max_date = rfm_df['最近购买日期'].max()
rfm_df['最近性'] = (max_date - rfm_df['最近购买日期']).dt.days
# Rename for consistency
rfm_df = rfm_df.rename(columns={
'购买频率': '频率性',
'消费金额': '金额性'
})
# Select RFM columns
rfm_metrics = rfm_df[['用户码', '最近性', '频率性', '金额性']].copy()
print(f"RFM指标计算完成,覆盖 {len(rfm_metrics)} 位客户")
return rfm_metrics
def find_optimal_clusters(self, data, max_k=10):
"""
Find optimal number of clusters using elbow method
Args:
data (pd.DataFrame): RFM metrics data
max_k (int): Maximum number of clusters to test
Returns:
int: Optimal number of clusters
"""
print("寻找最优聚类数...")
# Prepare data for clustering
rfm_values = data[['最近性', '频率性', '金额性']].values
rfm_scaled = self.scaler.fit_transform(rfm_values)
# Calculate inertia for different k values
inertias = []
k_range = range(1, min(max_k + 1, len(data) // 2))
for k in k_range:
kmeans = KMeans(n_clusters=k, random_state=42, n_init=10)
kmeans.fit(rfm_scaled)
inertias.append(kmeans.inertia_)
# Find elbow point (simplified method)
if len(inertias) >= 3:
# Calculate percentage decrease
decreases = [inertias[i-1] - inertias[i] for i in range(1, len(inertias))]
percentages = [decreases[i] / inertias[i] * 100 for i in range(len(decreases))]
# Find point where decrease becomes minimal (< 20%)
optimal_k = 3 # default
for i, pct in enumerate(percentages):
if pct < 20:
optimal_k = i + 2 # +2 because indices start from k=2
break
else:
optimal_k = 3
print(f"选择最优聚类数: {optimal_k}")
return optimal_k
def apply_clustering(self, rfm_data, n_clusters=None):
"""
Apply K-means clustering to RFM data
Args:
rfm_data (pd.DataFrame): RFM metrics data
n_clusters (int, optional): Number of clusters. If None, auto-determine
Returns:
pd.DataFrame: RFM data with cluster assignments
"""
if n_clusters is None:
n_clusters = self.find_optimal_clusters(rfm_data)
print(f"应用K-means聚类 (k={n_clusters})...")
# Prepare data
rfm_values = rfm_data[['最近性', '频率性', '金额性']].values
rfm_scaled = self.scaler.fit_transform(rfm_values)
# Apply K-means clustering
kmeans = KMeans(n_clusters=n_clusters, random_state=42, n_init=10)
cluster_labels = kmeans.fit_predict(rfm_scaled)
# Add cluster labels to data
result_df = rfm_data.copy()
result_df['cluster'] = cluster_labels
# Order clusters by monetary value (descending)
cluster_monetary = result_df.groupby('cluster')['金额性'].mean().sort_values(ascending=False)
cluster_mapping = {old_cluster: new_cluster for new_cluster, old_cluster in enumerate(cluster_monetary.index)}
result_df['cluster'] = result_df['cluster'].map(cluster_mapping)
print(f"聚类完成,生成 {n_clusters} 个客户分群")
return result_df
def calculate_rfm_scores(self, rfm_df):
"""
Calculate RFM scores (1-3 scale) for each customer
Args:
rfm_df (pd.DataFrame): RFM metrics with clusters
Returns:
pd.DataFrame: RFM data with scores and value segments
"""
print("计算RFM评分...")
result_df = rfm_df.copy()
# Calculate quartiles for scoring (using 33/66 percentiles for 1-3 scale)
def calculate_scores(series):
"""Calculate 1-3 scale scores based on 33/66 percentiles"""
p33, p66 = series.quantile([0.33, 0.66])
scores = pd.cut(series,
bins=[-np.inf, p33, p66, np.inf],
labels=[1, 2, 3],
include_lowest=True)
return scores.astype(int)
# Calculate individual scores
result_df['R_评分'] = calculate_scores(result_df['最近性']) # Lower recency = higher score
result_df['R_评分'] = 4 - result_df['R_评分'] # Reverse for proper scoring
result_df['F_评分'] = calculate_scores(result_df['频率性'])
result_df['M_评分'] = calculate_scores(result_df['金额性'])
# Calculate total score
result_df['RFM总分'] = result_df['R_评分'] + result_df['F_评分'] + result_df['M_评分']
# Assign customer value segments
def assign_value_segment(total_score):
if total_score >= 7:
return 'High'
elif total_score >= 5:
return 'Medium'
else:
return 'Low'
result_df['客户价值'] = result_df['RFM总分'].apply(assign_value_segment)
print("RFM评分计算完成")
return result_df
def generate_segment_summary(self, final_df):
"""
Generate summary statistics for each customer segment
Args:
final_df (pd.DataFrame): Complete RFM analysis results
Returns:
dict: Summary statistics for each segment
"""
print("生成分群摘要...")
summary = {}
for segment in ['High', 'Medium', 'Low']:
segment_data = final_df[final_df['客户价值'] == segment]
if len(segment_data) > 0:
summary[segment] = {
'客户数量': len(segment_data),
'客户占比': f"{len(segment_data) / len(final_df) * 100:.1f}%",
'平均最近购买天数': segment_data['最近性'].mean(),
'平均购买频次': segment_data['频率性'].mean(),
'平均消费金额': segment_data['金额性'].mean(),
'总消费金额': segment_data['金额性'].sum(),
'收入贡献占比': f"{segment_data['金额性'].sum() / final_df['金额性'].sum() * 100:.1f}%",
'平均RFM总分': segment_data['RFM总分'].mean()
}
return summary
def run_complete_analysis(self, file_path, n_clusters=None):
"""
Run complete RFM analysis pipeline
Args:
file_path (str): Path to transaction data file
n_clusters (int, optional): Number of clusters. Auto-determined if None
Returns:
pd.DataFrame: Complete analysis results
"""
print("开始RFM客户分群分析")
print("=" * 50)
# 1. Load and clean data
original_df, cleaned_df = self.load_and_clean_data(file_path)
# 2. Calculate RFM metrics
rfm_metrics = self.calculate_rfm_metrics(cleaned_df)
# 3. Apply clustering
clustered_df = self.apply_clustering(rfm_metrics, n_clusters)
# 4. Calculate RFM scores and segments
final_df = self.calculate_rfm_scores(clustered_df)
# 5. Generate summary
summary = self.generate_segment_summary(final_df)
# 6. Display results
print("\n分析完成!")
print("\n客户分群摘要:")
for segment, stats in summary.items():
print(f"\n{segment} 价值客户:")
for key, value in stats.items():
print(f" {key}: {value}")
return final_df, summary
def main():
"""Example usage of RFM analyzer"""
analyzer = RFMAnalyzer()
# Example file path - would be provided by user
file_path = "电商历史订单.csv"
if pd.io.common.file_exists(file_path):
results, summary = analyzer.run_complete_analysis(file_path)
# Save results
results.to_csv('rfm_analysis_results.csv', index=False, encoding='utf-8-sig')
print(f"\n结果已保存到: rfm_analysis_results.csv")
else:
print(f"数据文件未找到: {file_path}")
print("请确保提供正确的电商订单数据文件路径")
if __name__ == "__main__":
main()RFM客户分群分析基本使用指南
RFM Customer Segmentation Basic Usage Guide
快速开始 | Quick Start
1. 准备数据 | Data Preparation
准备包含以下字段的电商订单数据CSV文件:
订单号,用户码,消费日期,产品码,产品说明,数量,单价
ORD001,USER001,2024-01-15,PROD001,智能手机保护壳,2,29.90
ORD002,USER002,2024-01-16,PROD002,无线耳机,1,199.00
ORD003,USER001,2024-01-20,PROD003,充电宝,1,89.00必需字段说明:
用户码: 客户唯一标识符消费日期: 购买日期 (格式: YYYY-MM-DD)数量: 购买数量 (必须为正数)单价: 商品单价 (必须为正数)
2. 运行分析 | Run Analysis
# 导入分析引擎
from core_analysis import RFMAnalyzer
# 创建分析器实例
analyzer = RFMAnalyzer()
# 运行完整分析
results, summary = analyzer.run_complete_analysis('your_data.csv')
# 保存结果
results.to_csv('customer_segments.csv', index=False, encoding='utf-8-sig')3. 生成可视化报告 | Generate Visualizations
# 导入可视化工具
from visualization import RFMVisualizer
# 创建可视化器
visualizer = RFMVisualizer()
# 生成综合仪表板
visualizer.create_comprehensive_dashboard(results, 'dashboard.png')
# 生成详细图表
visualizer.create_individual_charts(results, 'charts/')4. 导出营销报告 | Export Marketing Reports
# 导入报告生成器
from report_generator import RFMReportGenerator
# 创建报告生成器
generator = RFMReportGenerator()
# 生成所有报告
generator.save_all_reports(results)命令行使用 | Command Line Usage
一键完整分析
# 创建并运行分析脚本
python -c "
from core_analysis import RFMAnalyzer
from visualization import RFMVisualizer
from report_generator import RFMReportGenerator
# 加载和分析数据
analyzer = RFMAnalyzer()
results, summary = analyzer.run_complete_analysis('电商历史订单.csv')
# 生成可视化
visualizer = RFMVisualizer()
visualizer.create_comprehensive_dashboard(results)
# 生成报告
generator = RFMReportGenerator()
generator.save_all_reports(results)
print('RFM分析完成!')
"使用示例数据测试
# 运行示例
python core_analysis.py
python visualization.py
python report_generator.py输出文件说明 | Output Files
分析完成后会生成以下文件:
数据文件 | Data Files
customer_segments.csv: 完整的客户分群结果vip_customers_marketing_list.csv: VIP客户营销清单
可视化文件 | Visualization Files
rfm_dashboard.png: 综合分析仪表板charts/: 详细分析图表文件夹segment_distribution_detailed.png: 分群分布详细图rfm_score_distribution.png: RFM评分分布图customer_lifetime_value.png: 客户生命周期价值分析
报告文件 | Report Files
reports/executive_summary.md: 执行摘要报告reports/detailed_analysis.md: 详细技术分析报告reports/marketing_insights.md: 营销洞察报告
高级用法 | Advanced Usage
自定义聚类数
# 指定特定的聚类数量
results, summary = analyzer.run_complete_analysis(
'data.csv',
n_clusters=5 # 自定义聚类数
)仅运行RFM计算
# 仅计算RFM指标
analyzer = RFMAnalyzer()
original_df, cleaned_df = analyzer.load_and_clean_data('data.csv')
rfm_metrics = analyzer.calculate_rfm_metrics(cleaned_df)
clustered_df = analyzer.apply_clustering(rfm_metrics)
final_df = analyzer.calculate_rfm_scores(clustered_df)自定义可视化
# 仅生成特定图表
visualizer = RFMVisualizer()
visualizer._create_segment_distribution_detailed(results)
plt.savefig('custom_segment_chart.png')故障排除 | Troubleshooting
常见问题 | Common Issues
1. 中文显示问题
# 设置中文字体
plt.rcParams['font.sans-serif'] = ['SimHei', 'Microsoft YaHei']2. 数据编码问题
# 尝试不同编码
try:
df = pd.read_csv('data.csv', encoding='utf-8')
except:
df = pd.read_csv('data.csv', encoding='gbk')3. 内存不足
# 分批处理大数据
chunk_size = 10000
for chunk in pd.read_csv('large_data.csv', chunksize=chunk_size):
# 处理每个数据块
pass数据质量检查
# 检查数据质量
def check_data_quality(df):
print(f"总订单数: {len(df):,}")
print(f"唯一客户数: {df['用户码'].nunique():,}")
print(f"日期范围: {df['消费日期'].min()} 到 {df['消费日期'].max()}")
# 检查异常值
negative_qty = len(df[df['数量'] <= 0])
negative_price = len(df[df['单价'] <= 0])
print(f"负数量订单: {negative_qty:,}")
print(f"负价格订单: {negative_price:,}")
return negative_qty == 0 and negative_price == 0性能优化 | Performance Optimization
大数据集优化
# 使用数据类型优化
dtypes = {
'用户码': 'category',
'产品码': 'category',
'数量': 'int32',
'单价': 'float32'
}
df = pd.read_csv('large_data.csv', dtype=dtypes)并行处理
# 使用多进程加速聚类计算
from sklearn.cluster import MiniBatchKMeans
# 对于大数据集使用MiniBatchKMeans
kmeans = MiniBatchKMeans(n_clusters=3, batch_size=1000, random_state=42)API参考 | API Reference
RFMAnalyzer类
class RFMAnalyzer:
def __init__(self, chinese_font='SimHei')
def load_and_clean_data(self, file_path) -> tuple
def calculate_rfm_metrics(self, df) -> pd.DataFrame
def apply_clustering(self, rfm_data, n_clusters=None) -> pd.DataFrame
def calculate_rfm_scores(self, rfm_df) -> pd.DataFrame
def run_complete_analysis(self, file_path, n_clusters=None) -> tupleRFMVisualizer类
class RFMVisualizer:
def __init__(self, chinese_font='SimHei')
def create_comprehensive_dashboard(self, rfm_df, save_path='rfm_dashboard.png')
def create_individual_charts(self, rfm_df, output_dir='charts')RFMReportGenerator类
class RFMReportGenerator:
def __init__(self)
def generate_executive_summary(self, rfm_df, summary_stats) -> str
def generate_detailed_analysis_report(self, rfm_df, original_data=None) -> str
def generate_marketing_insights(self, rfm_df) -> str
def export_vip_customer_list(self, rfm_df, top_n=100) -> pd.DataFrame
def save_all_reports(self, rfm_df, original_data=None, output_dir='reports')---
更多高级用法请参考各模块的详细文档
订单号,用户码,消费日期,产品码,产品说明,数量,单价,城市
ORD001,USER001,2024-01-15,PROD001,智能手机保护壳,2,29.90,北京
ORD002,USER002,2024-01-16,PROD002,无线蓝牙耳机,1,199.00,上海
ORD003,USER001,2024-01-20,PROD003,快充充电宝,1,89.00,北京
ORD004,USER003,2024-01-22,PROD004,手机支架,3,15.90,广州
ORD005,USER002,2024-01-25,PROD005,数据线套装,2,39.90,上海
ORD006,USER004,2024-02-01,PROD001,智能手机保护壳,1,29.90,深圳
ORD007,USER003,2024-02-03,PROD006,车载手机支架,1,59.00,广州
ORD008,USER001,2024-02-08,PROD007,屏幕保护膜,3,19.90,北京
ORD009,USER005,2024-02-10,PROD008,无线充电器,1,129.00,杭州
ORD010,USER002,2024-02-12,PROD009,蓝牙音箱,1,299.00,上海
ORD011,USER003,2024-02-15,PROD010,智能手环,1,199.00,广州
ORD012,USER004,2024-02-18,PROD011,手机镜头套装,1,89.00,深圳
ORD013,USER005,2024-02-20,PROD012,平板电脑支架,2,45.00,杭州
ORD014,USER001,2024-02-22,PROD013,车载充电器,1,79.00,北京
ORD015,USER006,2024-02-25,PROD014,USB集线器,1,149.00,成都
ORD016,USER002,2024-02-28,PROD015,机械键盘,1,399.00,上海
ORD017,USER003,2024-03-01,PROD016,鼠标垫,2,29.90,广州
ORD018,USER004,2024-03-03,PROD017,笔记本电脑支架,1,199.00,深圳
ORD019,USER005,2024-03-05,PROD018,网络摄像头,1,259.00,杭州
ORD020,USER001,2024-03-08,PROD019,手机散热器,1,69.00,北京
ORD021,USER006,2024-03-10,PROD020,智能插座,2,59.00,成都
ORD022,USER007,2024-03-12,PROD021,LED台灯,1,189.00,西安
ORD023,USER002,2024-03-15,PROD022,游戏手柄,1,179.00,上海
ORD024,USER003,2024-03-18,PROD023,平板保护套,1,99.00,广州
ORD025,USER004,2024-03-20,PROD024,无线鼠标,1,129.00,深圳
ORD026,USER005,2024-03-22,PROD025,键盘腕托,1,39.90,杭州
ORD027,USER001,2024-03-25,PROD026,手机清洁套装,2,19.90,北京
ORD028,USER006,2024-03-28,PROD027,智能体重秤,1,159.00,成都
ORD029,USER007,2024-03-30,PROD028,空气净化器,1,599.00,西安
ORD030,USER008,2024-04-02,PROD029,电动牙刷,1,299.00,南京
ORD031,USER002,2024-04-05,PROD030,剃须刀,1,399.00,上海
ORD032,USER003,2024-04-08,PROD031,吹风机,1,259.00,广州
ORD033,USER004,2024-04-10,PROD032,加湿器,1,189.00,深圳
ORD034,USER005,2024-04-12,PROD033,香薰机,1,159.00,杭州
ORD035,USER001,2024-04-15,PROD034,桌面收纳盒,1,49.00,北京
ORD036,USER006,2024-04-18,PROD035,电脑包,1,199.00,成都
ORD037,USER007,2024-04-20,PROD036,保温杯,2,89.00,西安
ORD038,USER008,2024-04-22,PROD037,运动水壶,1,59.00,南京
ORD039,USER009,2024-04-25,PROD038,瑜伽垫,1,129.00,武汉
ORD040,USER002,2024-04-28,PROD039,哑铃套装,1,299.00,上海
ORD041,USER003,2024-05-01,PROD040,跑步腰包,1,79.00,广州
ORD042,USER004,2024-05-03,PROD041,运动手表,1,599.00,深圳
ORD043,USER005,2024-05-05,PROD042,健身手套,1,49.00,杭州
ORD044,USER001,2024-05-08,PROD043,手机挂绳,3,15.90,北京
ORD045,USER006,2024-05-10,PROD044,卡包,2,29.90,成都
ORD046,USER007,2024-05-12,PROD045,钥匙包,1,39.90,西安
ORD047,USER008,2024-05-15,PROD046,护照夹,1,89.00,南京
ORD048,USER009,2024-05-18,PROD047,行李牌,2,19.90,武汉
ORD049,USER010,2024-05-20,PROD048,颈枕,1,79.00,重庆
ORD050,USER002,2024-05-22,PROD049,眼罩耳塞套装,1,59.00,上海RFM Customer Segmentation Analysis Skill
一个用于电商客户分群和RFM分析的综合性Claude Code技能,支持中文数据处理和智能聚类。
功能特性 | Features
- 🎯 智能RFM分析: 自动计算Recency、Frequency、Monetary指标
- 📊 K-means聚类: 自动确定最优聚类数,无需手动调参
- 🌏 中文支持: 完整支持中文数据字段和可视化显示
- 📈 可视化仪表板: 自动生成综合分析图表和报告
- 🎯 营销洞察: 提供可操作的营销建议和VIP客户清单
- 🔧 即用型设计: 一键式数据处理流水线
安装依赖 | Installation
pip install -r requirements.txt快速开始 | Quick Start
基本使用
from core_analysis import RFMAnalyzer
from visualization import RFMVisualizer
from report_generator import RFMReportGenerator
# 1. 数据分析
analyzer = RFMAnalyzer()
results, summary = analyzer.run_complete_analysis('your_data.csv')
# 2. 生成可视化
visualizer = RFMVisualizer()
visualizer.create_comprehensive_dashboard(results)
# 3. 生成报告
generator = RFMReportGenerator()
generator.save_all_reports(results)数据格式要求
CSV文件需要包含以下字段:
订单号,用户码,消费日期,产品码,产品说明,数量,单价,城市
ORD001,USER001,2024-01-15,PROD001,智能手机保护壳,2,29.90,北京必需字段:
用户码: 客户唯一标识消费日期: 购买日期 (YYYY-MM-DD)数量: 购买数量 (必须为正数)单价: 商品单价 (必须为正数)
文件结构 | File Structure
rfm-customer-segmentation/
├── SKILL.md # 技能说明文档
├── core_analysis.py # 核心RFM分析引擎
├── visualization.py # 可视化工具
├── report_generator.py # 报告生成器
├── requirements.txt # Python依赖包
├── README.md # 使用说明
├── examples/
│ ├── sample_data.csv # 示例数据
│ └── basic_usage.md # 使用指南
└── templates/
├── analysis_template.md # 分析报告模板
└── vip_list_template.csv # VIP客户模板输出文件 | Output Files
数据文件
customer_segments.csv: 完整客户分群结果vip_customers_marketing_list.csv: VIP客户营销清单
可视化文件
rfm_dashboard.png: 综合分析仪表板charts/: 详细分析图表
报告文件
reports/executive_summary.md: 执行摘要reports/detailed_analysis.md: 详细技术分析reports/marketing_insights.md: 营销洞察报告
核心功能 | Core Features
1. RFM指标计算
- Recency (R): 客户最近购买时间
- Frequency (F): 客户购买频次
- Monetary (M): 客户消费金额
2. 智能聚类
- 自动使用肘部法则确定最优聚类数
- K-means算法进行客户分群
- 标准化处理确保各指标权重一致
3. 客户价值评分
- 1-3分制评分系统
- 基于33%和66%分位数划分
- 综合评分确定客户价值等级
4. 可视化分析
- 客户分群分布饼图
- 收入份额分析图
- RFM散点图和箱线图
- 客户价值相关性热力图
5. 营销支持
- VIP客户识别和排名
- 针对性营销策略建议
- 客户激活和挽留方案
- ROI预测和KPI监控
使用场景 | Use Cases
电商客户分析
- 识别高价值VIP客户
- 制定个性化营销策略
- 客户流失预警和挽留
- 提升客户终身价值
营销活动优化
- 精准营销目标客户筛选
- 营销预算优化分配
- 活动效果预测和评估
- A/B测试客户分组
客户关系管理
- 客户生命周期管理
- 客户价值分层服务
- 客户满意度提升策略
- 客户推荐和奖励机制
API参考 | API Reference
RFMAnalyzer类
class RFMAnalyzer:
def __init__(self, chinese_font='SimHei')
def load_and_clean_data(self, file_path) -> tuple
def calculate_rfm_metrics(self, df) -> pd.DataFrame
def apply_clustering(self, rfm_data, n_clusters=None) -> pd.DataFrame
def calculate_rfm_scores(self, rfm_df) -> pd.DataFrame
def run_complete_analysis(self, file_path, n_clusters=None) -> tupleRFMVisualizer类
class RFMVisualizer:
def __init__(self, chinese_font='SimHei')
def create_comprehensive_dashboard(self, rfm_df, save_path='rfm_dashboard.png')
def create_individual_charts(self, rfm_df, output_dir='charts')RFMReportGenerator类
class RFMReportGenerator:
def generate_executive_summary(self, rfm_df, summary_stats) -> str
def generate_detailed_analysis_report(self, rfm_df, original_data=None) -> str
def generate_marketing_insights(self, rfm_df) -> str
def export_vip_customer_list(self, rfm_df, top_n=100) -> pd.DataFrame故障排除 | Troubleshooting
常见问题
1. 中文字体显示问题
plt.rcParams['font.sans-serif'] = ['SimHei', 'Microsoft YaHei']2. 数据编码问题
df = pd.read_csv('data.csv', encoding='utf-8-sig') # 或 'gbk'3. 依赖包安装问题
pip install --upgrade pandas scikit-learn matplotlib seaborn最佳实践 | Best Practices
数据准备
- 确保数据质量,去除异常订单
- 统一日期格式
- 客户ID保持唯一性
分析优化
- 至少1000个订单用于可靠聚类
- 定期更新客户分群(建议月度)
- 结合业务背景解释结果
营销应用
- 建立客户分群效果监控机制
- 持续优化营销策略
- 测试不同触达方式的效果
版本历史 | Version History
- v1.0 (2024-12): 初始版本发布
- 基础RFM分析功能
- K-means聚类算法
- 可视化仪表板
- 营销报告生成
技术支持 | Support
如有问题或建议,请: 1. 检查数据格式是否符合要求 2. 确认依赖包已正确安装 3. 查看错误日志信息 4. 参考示例数据和代码
---
由RFM客户分群分析系统支持 | Powered by RFM Customer Segmentation Engine
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
RFM Customer Segmentation Report Generator
Generate comprehensive reports and marketing insights
"""
import pandas as pd
import numpy as np
from datetime import datetime
import os
import json
class RFMReportGenerator:
"""Generate comprehensive reports for RFM customer segmentation analysis"""
def __init__(self):
"""Initialize the report generator"""
self.analysis_date = datetime.now()
def generate_executive_summary(self, rfm_df, summary_stats):
"""
Generate executive summary report
Args:
rfm_df (pd.DataFrame): Complete RFM analysis results
summary_stats (dict): Summary statistics by segment
Returns:
str: Executive summary report
"""
total_customers = len(rfm_df)
total_revenue = rfm_df['金额性'].sum()
avg_customer_value = rfm_df['金额性'].mean()
report = f"""
# RFM客户分群分析执行摘要
# RFM Customer Segmentation Executive Summary
**分析日期:** {self.analysis_date.strftime('%Y年%m月%d日 %H:%M')}
## 📊 核心发现 | Key Findings
### 客户概况 | Customer Overview
- **总客户数:** {total_customers:,} 人
- **总收入:** ¥{total_revenue:,.0f}
- **平均客户价值:** ¥{avg_customer_value:,.0f}
- **数据覆盖期间:** {rfm_df['最近性'].max()} 天购买历史
### 客户分群分布 | Segment Distribution
"""
for segment, stats in summary_stats.items():
segment_name = {'High': '高价值', 'Medium': '中等价值', 'Low': '低价值'}[segment]
revenue_pct = stats['收入贡献占比'].replace('%', '')
report += f"""
- **{segment_name}客户:** {stats['客户数量']} 人 ({stats['客户占比']})
- 平均消费: ¥{stats['平均消费金额']:,.0f}
- 收入贡献: {stats['收入贡献占比']}
- 平均RFM得分: {stats['平均RFM总分']:.1f}/9
"""
report += f"""
## 🎯 营销建议 | Marketing Recommendations
### 高价值客户 (High Value)
- **立即行动:** 纳入VIP营销计划
- **策略:** 个性化服务、专属优惠、优先客服
- **预期效果:** 提升客户忠诚度,增加复购率
### 中等价值客户 (Medium Value)
- **重点目标:** 客户激活和价值提升
- **策略:** 交叉销售、向上销售、会员激励
- **预期效果:** 向高价值客户转化
### 低价值客户 (Low Value)
- **优化策略:** 重新激活或成本控制
- **策略:** 低成本触达、批量营销、流失预警
- **预期效果:** 识别潜在价值,降低服务成本
## 📈 预期ROI | Expected ROI
基于历史数据分析,针对不同客户群体的营销活动预期ROI:
- **高价值客户:** 300-500% (推荐投入最多资源)
- **中等价值客户:** 150-300% (重点关注转化)
- **低价值客户:** 50-150% (控制成本,批量操作)
## 📋 下一步行动 | Next Steps
1. **立即:** 导出VIP客户清单,启动个性化营销
2. **本周:** 制定中等价值客户激活计划
3. **本月:** 评估低价值客户策略效果
4. **季度:** 重新评估客户分群,调整策略
---
*本报告由RFM客户分群分析系统自动生成*
*Report generated by RFM Customer Segmentation Analysis System*
"""
return report
def generate_detailed_analysis_report(self, rfm_df, original_data=None):
"""
Generate detailed technical analysis report
Args:
rfm_df (pd.DataFrame): Complete RFM analysis results
original_data (pd.DataFrame, optional): Original transaction data
Returns:
str: Detailed analysis report
"""
report = f"""
# RFM客户分群详细分析报告
# Detailed RFM Customer Segmentation Analysis Report
**生成时间:** {self.analysis_date.strftime('%Y-%m-%d %H:%M:%S')}
**分析工具:** RFM Customer Segmentation Engine v1.0
## 1. 数据概览 | Data Overview
### 数据质量评估
- **分析客户数:** {len(rfm_df):,} 人
- **数据完整性:** {self._assess_data_quality(rfm_df)}
- **分析期间:** {rfm_df['最近性'].max()} 天
### RFM指标统计
"""
# RFM statistics
for metric, name in [('最近性', 'Recency'), ('频率性', 'Frequency'), ('金额性', 'Monetary')]:
mean_val = rfm_df[metric].mean()
median_val = rfm_df[metric].median()
std_val = rfm_df[metric].std()
min_val = rfm_df[metric].min()
max_val = rfm_df[metric].max()
report += f"""
#### {name} ({metric})
- 平均值: {mean_val:.2f}
- 中位数: {median_val:.2f}
- 标准差: {std_val:.2f}
- 范围: {min_val:.0f} - {max_val:.0f}
"""
report += f"""
## 2. 分群分析 | Segment Analysis
### 分群特征对比
"""
# Segment comparison
segment_comparison = self._create_segment_comparison_table(rfm_df)
report += segment_comparison
report += f"""
### 客户价值评分分布
"""
# Score distribution analysis
score_analysis = self._analyze_score_distribution(rfm_df)
report += score_analysis
if original_data is not None:
report += f"""
## 3. 原始数据分析 | Original Data Analysis
### 交易数据概览
- **总订单数:** {len(original_data):,}
- **平均订单金额:** ¥{original_data['数量'].mean() * original_data['单价'].mean():.2f}
- **客户分布:** {original_data['用户码'].nunique()} 个独立客户
### 产品类别分析
"""
# Product category analysis if available
if '产品说明' in original_data.columns:
product_analysis = self._analyze_product_categories(original_data)
report += product_analysis
report += f"""
## 4. 算法说明 | Algorithm Details
### RFM分析方法
1. **Recency (R):** 客户最近一次购买时间距离今天的天数
2. **Frequency (F):** 客户在分析期内的购买次数
3. **Monetary (M):** 客户在分析期内的总消费金额
### 评分机制
- 采用1-3分制评分,基于33%和66%分位数划分
- Recency: 距离购买时间越近,得分越高
- Frequency & Monetary: 数值越高,得分越高
### 聚类算法
- 使用K-means算法进行客户分群
- 自动确定最优聚类数(肘部法则)
- 标准化处理确保各指标权重一致
## 5. 业务洞察 | Business Insights
### 客户价值金字塔
```
高价值客户 (Top 20-30%) ← 核心利润来源
↑
中等价值客户 (Middle 30-40%) ← 潜力客户
↑
低价值客户 (Bottom 30-40%) ← 长尾客户
```
### 关键发现
1. **帕累托法则验证:** 高价值客户贡献了主要收入
2. **客户分层明显:** 不同分群间存在显著差异
3. **营销机会:** 中等价值客户具有最大提升潜力
## 6. 技术建议 | Technical Recommendations
### 数据质量改进
- 建议建立数据清洗自动化流程
- 实施异常订单监控机制
- 定期进行数据一致性检查
### 分析优化
- 考虑引入更多维度(如产品类别、地域)
- 实施动态分群机制
- 建立客户价值预测模型
### 系统集成
- 与CRM系统对接,实现实时分群
- 建立自动化营销触发机制
- 实施分群效果监控
---
*报告结束 - RFM客户分群分析系统*
"""
return report
def generate_marketing_insights(self, rfm_df):
"""
Generate marketing-focused insights and recommendations
Args:
rfm_df (pd.DataFrame): Complete RFM analysis results
Returns:
str: Marketing insights report
"""
report = f"""
# RFM客户分群营销洞察报告
# RFM Customer Segmentation Marketing Insights
**报告日期:** {self.analysis_date.strftime('%Y年%m月%d日')}
## 🎯 营销策略矩阵 | Marketing Strategy Matrix
### 高价值客户 (High Value) - "忠诚保卫战"
**特征描述:** 购买频次高,消费金额大,最近活跃
**营销策略:**
- **VIP专属服务:** 专属客服经理、优先发货、专属客服热线
- **个性化推荐:** 基于购买历史的高端产品推荐
- **忠诚度计划:** 积分加倍、专属礼品、生日特权
- **预防流失:** 主动关怀、定期回访、流失预警
**预期效果:**
- 客户留存率提升 20-30%
- 平均客单价提升 15-25%
- 推荐转化率提升 40-50%
**实施建议:**
- 立即建立VIP客户档案
- 设计专属营销活动
- 设置客户流失监控
### 中等价值客户 (Medium Value) - "价值提升战"
**特征描述:** 有一定购买频次,但消费金额或活跃度有提升空间
**营销策略:**
- **交叉销售:** 推荐相关产品类别
- **向上销售:** 引导购买高端产品
- **会员激励:** 升级会员等级特权
- **定期互动:** 新品优先体验、会员活动
**预期效果:**
- 30-40%转化为高价值客户
- 平均购买频次提升 25-35%
- 客单价提升 20-30%
**实施建议:**
- 分析购买模式,识别交叉销售机会
- 设计渐进式会员升级体系
- 建立客户互动日历
### 低价值客户 (Low Value) - "激活抢救战"
**特征描述:** 购买频次低,消费金额小,可能存在流失风险
**营销策略:**
- **重新激活:** 特惠促销、回归奖励
- **教育引导:** 产品使用指导、价值认知教育
- **社区运营:** 用户社区参与、口碑激励
- **成本控制:** 批量营销、自动化触达
**预期效果:**
- 15-25%重新激活
- 5-10%转化为中等价值客户
- 降低营销成本 30-40%
**实施建议:**
- 建立客户生命周期预警机制
- 设计低成本的自动化营销流程
- 定期清理无效客户数据
## 📅 营销活动日历 | Marketing Calendar
### 本周重点
- [ ] VIP客户1对1沟通
- [ ] 中等价值客户促销活动设计
- [ ] 低价值客户激活邮件发送
### 本月目标
- [ ] 高价值客户满意度调研
- [ ] 中等价值客户升级计划启动
- [ ] 低价值客户成本效益分析
### 季度规划
- [ ] 客户分群效果评估
- [ ] 营销策略优化调整
- [ ] 新分群标准制定
## 💡 创新营销思路 | Innovative Marketing Ideas
### 1. 生命周期营销
- **新客户阶段:** 欢迎礼包、引导教育
- **成长阶段:** 技能提升、成功案例分享
- **成熟阶段:** 深度服务、价值共创
- **衰退阶段:** 挽留激励、告别礼遇
### 2. 场景化营销
- **节日场景:** 定制化节日营销
- **生活场景:** 基于用户生活场景推荐
- **工作场景:** 职业相关的产品服务
- **社交场景:** 社交分享激励
### 3. 数据驱动营销
- **实时个性化:** 基于实时行为的个性化推荐
- **预测性营销:** 基于预测模型的主动营销
- **A/B测试:** 持续优化营销效果
- **多渠道协同:** 整合线上线下营销触点
## 📊 KPI监控体系 | KPI Monitoring System
### 核心指标
- **客户留存率:** 各分群客户月度留存
- **客户价值提升:** 各分群平均消费金额变化
- **转化率:** 分群间转化率和转化时间
- **营销ROI:** 各分群营销活动投入产出比
### 监控频率
- **日报:** 关键活动效果监控
- **周报:** 分群变化趋势分析
- **月报:** 整体策略效果评估
- **季报:** 长期趋势和策略调整
---
*营销洞察报告 - 让数据驱动增长*
"""
return report
def export_vip_customer_list(self, rfm_df, top_n=100):
"""
Export VIP customer list for marketing campaigns
Args:
rfm_df (pd.DataFrame): Complete RFM analysis results
top_n (int): Number of top customers to export
Returns:
pd.DataFrame: VIP customer list
"""
# Filter high value customers and sort by total score
vip_customers = rfm_df[rfm_df['客户价值'] == 'High'].copy()
if len(vip_customers) == 0:
# If no High value customers, take top by monetary value
vip_customers = rfm_df.nlargest(top_n, '金额性')
else:
# Sort high value customers by total score and monetary value
vip_customers = vip_customers.sort_values(
['RFM总分', '金额性', '频率性'],
ascending=[False, False, False]
)
# Take top N customers
vip_customers = vip_customers.head(top_n).copy()
# Add ranking
vip_customers['排名'] = range(1, len(vip_customers) + 1)
# Add marketing insights
vip_customers['营销优先级'] = vip_customers['排名'].apply(
lambda x: '最高优先级' if x <= 10 else '高优先级' if x <= 50 else '中优先级'
)
# Select relevant columns
export_columns = [
'用户码', '排名', '营销优先级',
'R_评分', 'F_评分', 'M_评分', 'RFM总分',
'最近性', '频率性', '金额性'
]
vip_export = vip_customers[export_columns].copy()
# Rename columns for clarity
column_mapping = {
'用户码': '客户ID',
'排名': 'VIP排名',
'营销优先级': '营销建议',
'R_评分': '最近性评分',
'F_评分': '频率性评分',
'M_评分': '金额性评分',
'RFM总分': '综合得分',
'最近性': '最近购买天数',
'频率性': '购买频次',
'金额性': '总消费金额'
}
vip_export = vip_export.rename(columns=column_mapping)
# Save to CSV
vip_export.to_csv('vip_customers_marketing_list.csv', index=False, encoding='utf-8-sig')
return vip_export
def _assess_data_quality(self, df):
"""Assess data quality and completeness"""
total_cells = len(df) * len(df.columns)
missing_cells = df.isnull().sum().sum()
completeness = ((total_cells - missing_cells) / total_cells) * 100
if completeness >= 95:
return "优秀 (Excellent)"
elif completeness >= 90:
return "良好 (Good)"
elif completeness >= 80:
return "一般 (Fair)"
else:
return "需要改进 (Needs Improvement)"
def _create_segment_comparison_table(self, df):
"""Create detailed segment comparison table"""
comparison = ""
for segment in ['High', 'Medium', 'Low']:
segment_data = df[df['客户价值'] == segment]
segment_name = {'High': '高价值', 'Medium': '中等价值', 'Low': '低价值'}[segment]
comparison += f"""
#### {segment_name}客户特征
- **客户数量:** {len(segment_data)} 人 ({len(segment_data)/len(df)*100:.1f}%)
- **平均最近购买:** {segment_data['最近性'].mean():.1f} 天前
- **平均购买频次:** {segment_data['频率性'].mean():.1f} 次
- **平均消费金额:** ¥{segment_data['金额性'].mean():,.0f}
- **平均RFM得分:** {segment_data['RFM总分'].mean():.1f}/9
"""
return comparison
def _analyze_score_distribution(self, df):
"""Analyze RFM score distribution"""
analysis = """
### RFM评分分布分析
"""
for score_type in ['R_评分', 'F_评分', 'M_评分']:
score_dist = df[score_type].value_counts().sort_index()
score_name = {
'R_评分': '最近性评分',
'F_评分': '频率性评分',
'M_评分': '金额性评分'
}[score_type]
analysis += f"""
#### {score_name}分布
"""
for score, count in score_dist.items():
percentage = count / len(df) * 100
analysis += f"- {score}分: {count} 人 ({percentage:.1f}%)\n"
return analysis
def _analyze_product_categories(self, df):
"""Analyze product categories if available"""
if '产品说明' not in df.columns:
return "产品类别数据不可用"
analysis = """
#### 热销产品类别
"""
# Top product categories
product_revenue = df.groupby('产品说明')['订单金额'].sum().sort_values(ascending=False)
top_products = product_revenue.head(10)
for product, revenue in top_products.items():
analysis += f"- {product}: ¥{revenue:,.0f}\n"
return analysis
def save_all_reports(self, rfm_df, original_data=None, output_dir='reports'):
"""
Save all reports to files
Args:
rfm_df (pd.DataFrame): Complete RFM analysis results
original_data (pd.DataFrame, optional): Original transaction data
output_dir (str): Directory to save reports
"""
os.makedirs(output_dir, exist_ok=True)
# Generate summary statistics
summary_stats = {}
for segment in ['High', 'Medium', 'Low']:
segment_data = rfm_df[rfm_df['客户价值'] == segment]
if len(segment_data) > 0:
summary_stats[segment] = {
'客户数量': len(segment_data),
'客户占比': f"{len(segment_data) / len(rfm_df) * 100:.1f}%",
'平均最近购买天数': segment_data['最近性'].mean(),
'平均购买频次': segment_data['频率性'].mean(),
'平均消费金额': segment_data['金额性'].mean(),
'总消费金额': segment_data['金额性'].sum(),
'收入贡献占比': f"{segment_data['金额性'].sum() / rfm_df['金额性'].sum() * 100:.1f}%",
'平均RFM总分': segment_data['RFM总分'].mean()
}
# Generate and save reports
reports = {
'executive_summary.md': self.generate_executive_summary(rfm_df, summary_stats),
'detailed_analysis.md': self.generate_detailed_analysis_report(rfm_df, original_data),
'marketing_insights.md': self.generate_marketing_insights(rfm_df)
}
for filename, content in reports.items():
with open(os.path.join(output_dir, filename), 'w', encoding='utf-8') as f:
f.write(content)
# Export VIP customer list
vip_list = self.export_vip_customer_list(rfm_df)
print(f"所有报告已保存到: {output_dir}/")
print(f"- executive_summary.md: 执行摘要")
print(f"- detailed_analysis.md: 详细分析报告")
print(f"- marketing_insights.md: 营销洞察报告")
print(f"- vip_customers_marketing_list.csv: VIP客户清单")
def main():
"""Example usage"""
generator = RFMReportGenerator()
# Create sample data
sample_data = pd.DataFrame({
'用户码': range(100),
'最近性': np.random.randint(1, 365, 100),
'频率性': np.random.randint(1, 50, 100),
'金额性': np.random.randint(100, 10000, 100),
'客户价值': np.random.choice(['High', 'Medium', 'Low'], 100),
'RFM总分': np.random.randint(3, 9, 100),
'R_评分': np.random.randint(1, 4, 100),
'F_评分': np.random.randint(1, 4, 100),
'M_评分': np.random.randint(1, 4, 100)
})
# Generate sample reports
generator.save_all_reports(sample_data)
print("示例报告生成完成")
if __name__ == "__main__":
main()pandas>=1.3.0
numpy>=1.21.0
scikit-learn>=1.0.0
matplotlib>=3.5.0
seaborn>=0.11.0#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
简化的RFM客户分群分析
Simplified RFM Customer Segmentation Analysis
"""
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
from sklearn.preprocessing import StandardScaler
from sklearn.cluster import KMeans
import json
from datetime import datetime
import os
import warnings
warnings.filterwarnings('ignore')
plt.rcParams['font.sans-serif'] = ['SimHei', 'DejaVu Sans', 'Arial']
plt.rcParams['axes.unicode_minus'] = False
class SimpleRFMAnalyzer:
"""简化的RFM分析引擎"""
def __init__(self, output_dir='rfm_output'):
self.output_dir = output_dir
os.makedirs(output_dir, exist_ok=True)
def load_data(self, orders_path, order_items_path=None):
"""加载订单数据"""
print("Loading data...")
orders = pd.read_csv(orders_path, parse_dates=['order_purchase_timestamp'])
if order_items_path:
order_items = pd.read_csv(order_items_path)
orders = orders.merge(order_items, on='order_id', how='left')
orders = orders[orders['order_status'] == 'delivered'].copy()
if 'price' in orders.columns and 'freight_value' in orders.columns:
orders['total_amount'] = orders['price'] + orders['freight_value']
else:
orders['total_amount'] = orders['price'] if 'price' in orders.columns else 0
return orders
def calculate_rfm(self, orders):
"""计算RFM指标"""
print("Calculating RFM...")
analysis_date = orders['order_purchase_timestamp'].max() + pd.Timedelta(days=1)
rfm = orders.groupby('customer_id').agg({
'order_purchase_timestamp': lambda x: (analysis_date - x.max()).days,
'order_id': 'count',
'total_amount': 'sum'
}).reset_index()
rfm.columns = ['customer_id', 'recency', 'frequency', 'monetary']
return rfm
def score_rfm(self, rfm):
"""RFM评分 (1-4分制)"""
print("Scoring RFM...")
rfm['R_score'] = pd.qcut(rfm['recency'], q=4, labels=[4, 3, 2, 1], duplicates='drop').astype(int)
rfm['F_score'] = pd.qcut(rfm['frequency'].rank(method='first'), q=4, labels=[1, 2, 3, 4]).astype(int)
rfm['M_score'] = pd.qcut(rfm['monetary'].rank(method='first'), q=4, labels=[1, 2, 3, 4]).astype(int)
rfm['RFM_score'] = rfm['R_score'] + rfm['F_score'] + rfm['M_score']
return rfm
def create_segments(self, rfm):
"""创建客户分群"""
print("Creating segments...")
def create_segment(row):
if row['RFM_score'] >= 10:
return 'VIP_Clients'
elif row['RFM_score'] >= 8:
return 'Loyal_Customers'
elif row['RFM_score'] >= 6:
return 'Potential_Customers'
elif row['RFM_score'] >= 4:
return 'Regular_Customers'
else:
return 'At_Risk_Customers'
rfm['segment'] = rfm.apply(create_segment, axis=1)
return rfm
def apply_clustering(self, rfm, n_clusters=4):
"""K-means聚类"""
print("Performing K-means clustering...")
rfm_data = rfm[['recency', 'frequency', 'monetary']].copy()
scaler = StandardScaler()
rfm_scaled = scaler.fit_transform(rfm_data)
kmeans = KMeans(n_clusters=n_clusters, random_state=42, n_init=10)
rfm['cluster'] = kmeans.fit_predict(rfm_scaled)
return rfm
def generate_visualizations(self, rfm):
"""生成可视化图表"""
print("Generating visualizations...")
# 1. 分群分布饼图
fig, axes = plt.subplots(1, 2, figsize=(14, 6))
segment_counts = rfm['segment'].value_counts()
axes[0].pie(segment_counts.values, labels=segment_counts.index, autopct='%1.1f%%', startangle=90)
axes[0].set_title('Customer Segment Distribution', fontsize=12, fontweight='bold')
segment_revenue = rfm.groupby('segment')['monetary'].sum()
axes[1].pie(segment_revenue.values, labels=segment_revenue.index, autopct='%1.1f%%', startangle=90)
axes[1].set_title('Revenue Contribution by Segment', fontsize=12, fontweight='bold')
plt.tight_layout()
plt.savefig(os.path.join(self.output_dir, 'segment_distribution.png'), dpi=200, bbox_inches='tight')
plt.close()
# 2. RFM箱线图
fig, axes = plt.subplots(1, 3, figsize=(15, 5))
rfm.boxplot(column='recency', by='segment', ax=axes[0])
axes[0].set_title('Recency by Segment')
rfm.boxplot(column='frequency', by='segment', ax=axes[1])
axes[1].set_title('Frequency by Segment')
rfm.boxplot(column='monetary', by='segment', ax=axes[2])
axes[2].set_title('Monetary by Segment')
plt.suptitle('')
plt.tight_layout()
plt.savefig(os.path.join(self.output_dir, 'rfm_boxplots.png'), dpi=200, bbox_inches='tight')
plt.close()
# 3. 仪表板
fig = plt.figure(figsize=(16, 10))
ax1 = plt.subplot(2, 3, 1)
segment_counts.plot(kind='bar', ax=ax1, color='steelblue')
ax1.set_title('Customer Count by Segment', fontweight='bold')
plt.setp(ax1.xaxis.get_majorticklabels(), rotation=45, ha='right')
ax2 = plt.subplot(2, 3, 2)
avg_rfm = rfm.groupby('segment')[['recency', 'frequency', 'monetary']].mean()
avg_rfm.plot(kind='bar', ax=ax2, rot=0)
ax2.set_title('Average RFM by Segment', fontweight='bold')
ax2.legend(['Recency', 'Frequency', 'Monetary'])
ax3 = plt.subplot(2, 3, 3)
segment_revenue.plot(kind='bar', ax=ax3, color='green')
ax3.set_title('Total Revenue by Segment', fontweight='bold')
plt.setp(ax3.xaxis.get_majorticklabels(), rotation=45, ha='right')
ax4 = plt.subplot(2, 1, 2)
pivot = rfm.pivot_table(values='customer_id', index='R_score', columns='F_score', aggfunc='count')
sns.heatmap(pivot, annot=True, fmt='g', cmap='YlOrRd', ax=ax4)
ax4.set_title('RFM Customer Distribution Heatmap', fontweight='bold')
ax4.set_xlabel('Frequency Score')
ax4.set_ylabel('Recency Score')
plt.tight_layout()
plt.savefig(os.path.join(self.output_dir, 'rfm_dashboard.png'), dpi=200, bbox_inches='tight')
plt.close()
def export_results(self, rfm):
"""导出分析结果"""
print("Exporting results...")
customer_segments = rfm[['customer_id', 'recency', 'frequency', 'monetary',
'R_score', 'F_score', 'M_score', 'RFM_score',
'segment', 'cluster']].copy()
customer_segments = customer_segments.sort_values('monetary', ascending=False)
customer_segments.to_csv(os.path.join(self.output_dir, 'customer_segments.csv'),
index=False, encoding='utf-8-sig')
vip_customers = customer_segments.head(500).copy()
vip_customers['rank'] = range(1, len(vip_customers) + 1)
vip_customers.to_csv(os.path.join(self.output_dir, 'vip_customers_list.csv'),
index=False, encoding='utf-8-sig')
summary = rfm.groupby('segment').agg({
'customer_id': 'count',
'recency': 'mean',
'frequency': 'mean',
'monetary': 'mean'
}).round(2)
summary.columns = ['count', 'avg_recency', 'avg_frequency', 'avg_monetary']
summary['total_revenue'] = rfm.groupby('segment')['monetary'].sum()
summary.to_csv(os.path.join(self.output_dir, 'segment_summary_statistics.csv'))
summary_json = {
'timestamp': datetime.now().isoformat(),
'total_customers': int(len(rfm)),
'segments': {}
}
for seg in rfm['segment'].unique():
seg_data = rfm[rfm['segment'] == seg]
summary_json['segments'][seg] = {
'count': int(len(seg_data)),
'avg_monetary': float(seg_data['monetary'].mean()),
'total_revenue': float(seg_data['monetary'].sum()),
'avg_recency': float(seg_data['recency'].mean()),
'avg_frequency': float(seg_data['frequency'].mean())
}
summary_json['key_metrics'] = {
'total_revenue': float(rfm['monetary'].sum()),
'avg_customer_value': float(rfm['monetary'].mean()),
'avg_frequency': float(rfm['frequency'].mean()),
'avg_recency': float(rfm['recency'].mean())
}
with open(os.path.join(self.output_dir, 'rfm_summary.json'), 'w', encoding='utf-8') as f:
json.dump(summary_json, f, ensure_ascii=False, indent=2)
return summary
def generate_report(self, rfm, summary):
"""生成分析报告"""
insights = f"""# RFM Customer Segmentation Analysis Report
**Analysis Date**: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}
## Summary
- **Total Customers Analyzed**: {len(rfm):,}
- **Total Revenue**: ${rfm['monetary'].sum():,.2f}
- **Average Customer Value**: ${rfm['monetary'].mean():.2f}
- **Segments Created**: {rfm['segment'].nunique()}
## Segment Overview
| Segment | Count | Avg Recency | Avg Frequency | Avg Monetary | Total Revenue |
|---------|-------|-------------|---------------|--------------|---------------|
"""
for seg in summary.index:
insights += f"| {seg} | {summary.loc[seg, 'count']:,} | {summary.loc[seg, 'avg_recency']:.1f} days | {summary.loc[seg, 'avg_frequency']:.2f} | ${summary.loc[seg, 'avg_monetary']:.2f} | ${summary.loc[seg, 'total_revenue']:,.2f} |\n"
insights += f"""
## Key Insights
1. **High-Value Customers**: Top 20% contribute ${(rfm.nlargest(int(len(rfm)*0.2), 'monetary')['monetary'].sum() / rfm['monetary'].sum() * 100):.1f}% of revenue
2. **Customer Engagement**: Average purchase frequency is {rfm['frequency'].mean():.2f} orders
3. **Recency**: Customers purchased {rfm['recency'].mean():.0f} days ago on average
## Marketing Recommendations
### VIP Clients
- Provide exclusive offers and priority support
- Invite to new product launches
- Create loyalty programs
- Personalized recommendations
### Loyal Customers
- Cross-sell and up-sell opportunities
- Referral program incentives
- Premium service upgrades
- Early access to sales
### Potential Customers
- Re-engagement campaigns
- Special discount offers
- Product recommendations
- Email marketing sequences
### Regular Customers
- Seasonal promotions
- Brand awareness campaigns
- Educational content
- Community building
### At Risk Customers
- Win-back campaigns
- Special recovery offers
- Feedback surveys
- Understanding churn reasons
"""
with open(os.path.join(self.output_dir, 'marketing_insights.md'), 'w', encoding='utf-8') as f:
f.write(insights)
def run_analysis(self, orders_path, order_items_path=None, n_clusters=4):
"""运行完整的RFM分析流程"""
print("="*60)
print("RFM Customer Segmentation Analysis")
print("="*60)
orders = self.load_data(orders_path, order_items_path)
rfm = self.calculate_rfm(orders)
rfm = self.score_rfm(rfm)
rfm = self.create_segments(rfm)
rfm = self.apply_clustering(rfm, n_clusters)
print(f"Total customers analyzed: {len(rfm)}")
print(f"Segments created: {rfm['segment'].nunique()}")
self.generate_visualizations(rfm)
summary = self.export_results(rfm)
self.generate_report(rfm, summary)
print("\n" + "="*60)
print("RFM Analysis Complete!")
print("="*60)
print(f"Output directory: {self.output_dir}")
return rfm, summary
def main():
analyzer = SimpleRFMAnalyzer(output_dir='rfm_output')
analyzer.run_analysis('data_storage/Orders.csv', 'data_storage/Order Items.csv')
if __name__ == "__main__":
main()
RFM客户分群分析报告模板
RFM Customer Segmentation Analysis Report Template
---
报告标题: RFM客户分群分析报告 分析日期: {{ANALYSIS_DATE}} 数据时间范围: {{DATA_RANGE_START}} 至 {{DATA_RANGE_END}} 分析师: {{ANALYST_NAME}} 报告版本: v1.0
---
执行摘要 | Executive Summary
核心发现 | Key Findings
- 总客户数: {{TOTAL_CUSTOMERS}} 人
- 总收入: ¥{{TOTAL_REVENUE}}
- 平均客户价值: ¥{{AVERAGE_CUSTOMER_VALUE}}
分群分布 | Segment Distribution
- 高价值客户: {{HIGH_VALUE_COUNT}} 人 ({{HIGH_VALUE_PERCENTAGE}}%)
- 中等价值客户: {{MEDIUM_VALUE_COUNT}} 人 ({{MEDIUM_VALUE_PERCENTAGE}}%)
- 低价值客户: {{LOW_VALUE_COUNT}} 人 ({{LOW_VALUE_PERCENTAGE}}%)
主要建议 | Key Recommendations
1. {{RECOMMENDATION_1}} 2. {{RECOMMENDATION_2}} 3. {{RECOMMENDATION_3}}
---
数据概览 | Data Overview
数据质量评估 | Data Quality Assessment
- 数据完整性: {{DATA_COMPLETENESS}}
- 分析期间: {{ANALYSIS_PERIOD}} 天
- 数据覆盖范围: {{DATA_COVERAGE}}
RFM指标统计 | RFM Metrics Statistics
| 指标 | 平均值 | 中位数 | 标准差 | 最小值 | 最大值 |
|---|---|---|---|---|---|
| 最近性(Recency) | {{RECENCY_MEAN}} | {{RECENCY_MEDIAN}} | {{RECENCY_STD}} | {{RECENCY_MIN}} | {{RECENCY_MAX}} |
| 频率性(Frequency) | {{FREQUENCY_MEAN}} | {{FREQUENCY_MEDIAN}} | {{FREQUENCY_STD}} | {{FREQUENCY_MIN}} | {{FREQUENCY_MAX}} |
| 金额性(Monetary) | ¥{{MONETARY_MEAN}} | ¥{{MONETARY_MEDIAN}} | ¥{{MONETARY_STD}} | ¥{{MONETARY_MIN}} | ¥{{MONETARY_MAX}} |
---
客户分群分析 | Customer Segment Analysis
高价值客户 (High Value) - {{HIGH_VALUE_COUNT}} 人
特征描述:
- 平均最近购买: {{HIGH_AVG_RECENCY}} 天前
- 平均购买频次: {{HIGH_AVG_FREQUENCY}} 次
- 平均消费金额: ¥{{HIGH_AVG_MONETARY}}
- 收入贡献占比: {{HIGH_REVENUE_CONTRIBUTION}}%
营销策略:
- {{HIGH_STRATEGY_1}}
- {{HIGH_STRATEGY_2}}
- {{HIGH_STRATEGY_3}}
预期效果:
- {{HIGH_EXPECTED_RESULT_1}}
- {{HIGH_EXPECTED_RESULT_2}}
中等价值客户 (Medium Value) - {{MEDIUM_VALUE_COUNT}} 人
特征描述:
- 平均最近购买: {{MEDIUM_AVG_RECENCY}} 天前
- 平均购买频次: {{MEDIUM_AVG_FREQUENCY}} 次
- 平均消费金额: ¥{{MEDIUM_AVG_MONETARY}}
- 收入贡献占比: {{MEDIUM_REVENUE_CONTRIBUTION}}%
营销策略:
- {{MEDIUM_STRATEGY_1}}
- {{MEDIUM_STRATEGY_2}}
- {{MEDIUM_STRATEGY_3}}
预期效果:
- {{MEDIUM_EXPECTED_RESULT_1}}
- {{MEDIUM_EXPECTED_RESULT_2}}
低价值客户 (Low Value) - {{LOW_VALUE_COUNT}} 人
特征描述:
- 平均最近购买: {{LOW_AVG_RECENCY}} 天前
- 平均购买频次: {{LOW_AVG_FREQUENCY}} 次
- 平均消费金额: ¥{{LOW_AVG_MONETARY}}
- 收入贡献占比: {{LOW_REVENUE_CONTRIBUTION}}%
营销策略:
- {{LOW_STRATEGY_1}}
- {{LOW_STRATEGY_2}}
- {{LOW_STRATEGY_3}}
预期效果:
- {{LOW_EXPECTED_RESULT_1}}
- {{LOW_EXPECTED_RESULT_2}}
---
VIP客户清单 | VIP Customer List
Top 10 高价值客户 | Top 10 High-Value Customers
| 排名 | 客户ID | RFM总分 | 最近购买天数 | 购买频次 | 总消费金额 | 营销建议 |
|---|
{{TOP_VIP_TABLE}}
---
营销活动建议 | Marketing Campaign Recommendations
即即行动 | Immediate Actions (本周)
- [ ] {{IMMEDIATE_ACTION_1}}
- [ ] {{IMMEDIATE_ACTION_2}}
- [ ] {{IMMEDIATE_ACTION_3}}
短期计划 | Short-term Plans (本月)
- [ ] {{SHORT_TERM_PLAN_1}}
- [ ] {{SHORT_TERM_PLAN_2}}
- [ ] {{SHORT_TERM_PLAN_3}}
长期战略 | Long-term Strategy (季度)
- [ ] {{LONG_TERM_STRATEGY_1}}
- [ ] {{LONG_TERM_STRATEGY_2}}
- [ ] {{LONG_TERM_STRATEGY_3}}
---
KPI监控指标 | KPI Monitoring Metrics
核心指标 | Key Metrics
- 客户留存率: {{RETENTION_RATE_TARGET}}%
- 客户价值提升: {{CUSTOMER_VALUE_INCREASE_TARGET}}%
- 营销ROI: {{MARKETING_ROI_TARGET}}%
- 转化率: {{CONVERSION_RATE_TARGET}}%
监控频率 | Monitoring Frequency
- 日报: {{DAILY_MONITORING_ITEMS}}
- 周报: {{WEEKLY_MONITORING_ITEMS}}
- 月报: {{MONTHLY_MONITORING_ITEMS}}
- 季报: {{QUARTERLY_MONITORING_ITEMS}}
---
风险评估与应对 | Risk Assessment & Mitigation
潜在风险 | Potential Risks
1. {{RISK_1}}
- 风险等级: {{RISK_1_LEVEL}}
- 应对措施: {{RISK_1_MITIGATION}}
2. {{RISK_2}}
- 风险等级: {{RISK_2_LEVEL}}
- 应对措施: {{RISK_2_MITIGATION}}
3. {{RISK_3}}
- 风险等级: {{RISK_3_LEVEL}}
- 应对措施: {{RISK_3_MITIGATION}}
---
技术说明 | Technical Notes
分析方法 | Analysis Methodology
- RFM模型: Recency, Frequency, Monetary分析
- 聚类算法: K-means聚类
- 评分标准: 1-3分制,基于33%和66%分位数
- 数据处理: 异常值清理、标准化处理
工具和版本 | Tools and Versions
- Python版本: {{PYTHON_VERSION}}
- pandas版本: {{PANDAS_VERSION}}
- scikit-learn版本: {{SKLEARN_VERSION}}
- 分析工具: RFM Customer Segmentation Engine v1.0
---
附录 | Appendix
A. 详细数据表 | Detailed Data Tables
{{DETAILED_DATA_TABLES}}
B. 可视化图表 | Visualization Charts
{{VISUALIZATION_CHARTS}}
C. 术语表 | Glossary
- RFM: Recency(最近性), Frequency(频率性), Monetary(金额性)
- K-means: K均值聚类算法
- 客户生命周期价值: Customer Lifetime Value (CLV)
- 帕累托法则: 80/20法则,少数客户贡献大部分收入
---
报告结束
本报告由RFM客户分群分析系统自动生成 如有疑问,请联系数据分析团队
--- 备注: {{NOTES}}
客户ID,VIP排名,营销建议,最近性评分,频率性评分,金额性评分,综合得分,最近购买天数,购买频次,总消费金额,客户标签,推荐行动,优先级
USER001,1,最高优先级,3,3,3,9,15,8,¥2,580.00,超级VIP,专属客服经理+生日特权+新品优先体验,最高优先级
USER002,2,最高优先级,3,3,3,9,22,6,¥1,995.00,超级VIP,专属客服经理+生日特权+新品优先体验,最高优先级
USER003,3,最高优先级,3,3,3,9,28,5,¥1,456.00,超级VIP,专属客服经理+生日特权+新品优先体验,最高优先级#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
RFM Customer Segmentation Visualization Tools
Generate comprehensive visualizations and dashboards
"""
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
from matplotlib.gridspec import GridSpec
import warnings
warnings.filterwarnings('ignore')
class RFMVisualizer:
"""Visualization engine for RFM customer segmentation analysis"""
def __init__(self, chinese_font='SimHei'):
"""Initialize visualizer with Chinese font support"""
self.chinese_font = chinese_font
plt.rcParams['font.sans-serif'] = [chinese_font]
plt.rcParams['axes.unicode_minus'] = False
# Set style
sns.set_style("whitegrid")
plt.style.use('seaborn-v0_8')
def create_comprehensive_dashboard(self, rfm_df, save_path='rfm_dashboard.png'):
"""
Create comprehensive customer segmentation dashboard
Args:
rfm_df (pd.DataFrame): Complete RFM analysis results
save_path (str): Path to save the dashboard image
"""
print("生成分群分析仪表板...")
# Create figure with custom layout
fig = plt.figure(figsize=(20, 16))
gs = GridSpec(3, 3, figure=fig, hspace=0.3, wspace=0.3)
# 1. Customer segment distribution (pie chart)
ax1 = fig.add_subplot(gs[0, 0])
self._plot_segment_distribution(rfm_df, ax1)
# 2. Revenue share by segment (pie chart)
ax2 = fig.add_subplot(gs[0, 1])
self._plot_revenue_share(rfm_df, ax2)
# 3. RFM scatter plot (3D view projected)
ax3 = fig.add_subplot(gs[0, 2])
self._plot_rfm_scatter(rfm_df, ax3)
# 4. Box plots by segment
ax4 = fig.add_subplot(gs[1, :])
self._plot_rfm_boxplots(rfm_df, ax4)
# 5. Customer value heatmap
ax5 = fig.add_subplot(gs[2, 0])
self._plot_value_heatmap(rfm_df, ax5)
# 6. Cluster distribution
ax6 = fig.add_subplot(gs[2, 1])
self._plot_cluster_distribution(rfm_df, ax6)
# 7. Summary statistics table
ax7 = fig.add_subplot(gs[2, 2])
self._plot_summary_table(rfm_df, ax7)
# Add main title
fig.suptitle('RFM客户分群分析仪表板\nRFM Customer Segmentation Analysis Dashboard',
fontsize=20, fontweight='bold', y=0.95)
# Add footer with data info
fig.text(0.5, 0.02, f'分析时间: {pd.Timestamp.now().strftime("%Y-%m-%d %H:%M:%S")} | '
f'客户总数: {len(rfm_df)}',
ha='center', fontsize=10, style='italic')
# Save the dashboard
plt.savefig(save_path, dpi=300, bbox_inches='tight', facecolor='white')
plt.close()
print(f"仪表板已保存: {save_path}")
def _plot_segment_distribution(self, df, ax):
"""Plot customer segment distribution pie chart"""
segment_counts = df['客户价值'].value_counts()
colors = ['#ff6b6b', '#4ecdc4', '#45b7d1'] # Red, Teal, Blue
wedges, texts, autotexts = ax.pie(
segment_counts.values,
labels=[f'{seg}\n({count:,}人)' for seg, count in segment_counts.items()],
colors=colors,
autopct='%1.1f%%',
startangle=90,
textprops={'fontsize': 10}
)
ax.set_title('客户分群分布\nCustomer Segment Distribution',
fontsize=12, fontweight='bold', pad=10)
def _plot_revenue_share(self, df, ax):
"""Plot revenue share by segment pie chart"""
revenue_by_segment = df.groupby('客户价值')['金额性'].sum()
colors = ['#ff6b6b', '#4ecdc4', '#45b7d1']
wedges, texts, autotexts = ax.pie(
revenue_by_segment.values,
labels=[f'{seg}\n¥{revenue:,.0f}' for seg, revenue in revenue_by_segment.items()],
colors=colors,
autopct='%1.1f%%',
startangle=90,
textprops={'fontsize': 10}
)
ax.set_title('收入份额分布\nRevenue Share by Segment',
fontsize=12, fontweight='bold', pad=10)
def _plot_rfm_scatter(self, df, ax):
"""Plot RFM scatter plot (Frequency vs Monetary, colored by segment)"""
segment_colors = {'High': '#45b7d1', 'Medium': '#4ecdc4', 'Low': '#ff6b6b'}
for segment in ['High', 'Medium', 'Low']:
segment_data = df[df['客户价值'] == segment]
if len(segment_data) > 0:
ax.scatter(segment_data['频率性'], segment_data['金额性'],
c=segment_colors[segment], label=f'{segment} Value',
alpha=0.6, s=30, edgecolors='white', linewidth=0.5)
ax.set_xlabel('购买频率 (Frequency)', fontsize=10)
ax.set_ylabel('消费金额 (Monetary)', fontsize=10)
ax.set_title('RFM散点图\nRFM Scatter Plot', fontsize=12, fontweight='bold')
ax.legend(fontsize=9)
ax.set_xscale('log')
ax.set_yscale('log')
ax.grid(True, alpha=0.3)
def _plot_rfm_boxplots(self, ax):
"""Plot RFM box plots by customer segment"""
# This would need the full rfm_df with segment info
# For now, create a template
ax.text(0.5, 0.5, 'RFM指标箱线图\n(需要完整数据)\nRFM Box Plots by Segment',
ha='center', va='center', fontsize=12, transform=ax.transAxes)
ax.set_title('RFM指标分布\nRFM Metrics Distribution', fontsize=12, fontweight='bold')
def _plot_value_heatmap(self, df, ax):
"""Plot customer value correlation heatmap"""
# Select numeric columns for correlation
numeric_cols = ['最近性', '频率性', '金额性', 'RFM总分']
correlation_matrix = df[numeric_cols].corr()
sns.heatmap(correlation_matrix,
annot=True,
cmap='RdYlBu_r',
center=0,
square=True,
fmt='.2f',
cbar_kws={'shrink': 0.8},
ax=ax)
ax.set_title('RFM指标相关性\nRFM Correlation Heatmap',
fontsize=12, fontweight='bold')
def _plot_cluster_distribution(self, df, ax):
"""Plot cluster distribution bar chart"""
if 'cluster' in df.columns:
cluster_counts = df['cluster'].value_counts().sort_index()
bars = ax.bar(cluster_counts.index, cluster_counts.values,
color='skyblue', alpha=0.7, edgecolor='navy')
# Add value labels on bars
for bar, count in zip(bars, cluster_counts.values):
height = bar.get_height()
ax.text(bar.get_x() + bar.get_width()/2., height,
f'{count:,}',
ha='center', va='bottom', fontsize=9)
ax.set_xlabel('聚类编号 (Cluster ID)', fontsize=10)
ax.set_ylabel('客户数量 (Customer Count)', fontsize=10)
ax.set_title('聚类分布\nCluster Distribution', fontsize=12, fontweight='bold')
ax.grid(True, alpha=0.3, axis='y')
else:
ax.text(0.5, 0.5, '聚类数据不可用\nCluster data not available',
ha='center', va='center', fontsize=10, transform=ax.transAxes)
def _plot_summary_table(self, df, ax):
"""Create summary statistics table"""
# Calculate key metrics
total_customers = len(df)
total_revenue = df['金额性'].sum()
avg_customer_value = df['金额性'].mean()
segment_stats = []
for segment in ['High', 'Medium', 'Low']:
segment_data = df[df['客户价值'] == segment]
if len(segment_data) > 0:
stats = {
'分群': segment,
'客户数': len(segment_data),
'占比': f"{len(segment_data)/total_customers*100:.1f}%",
'平均消费': f"¥{segment_data['金额性'].mean():.0f}",
'收入贡献': f"¥{segment_data['金额性'].sum():,.0f}"
}
segment_stats.append(stats)
# Create table data
table_data = []
headers = ['指标', '数值']
table_data.extend([
['总客户数', f'{total_customers:,}'],
['总收入', f'¥{total_revenue:,.0f}'],
['平均客户价值', f'¥{avg_customer_value:.0f}'],
['', ''], # Separator
])
for stats in segment_stats:
table_data.extend([
[f"{stats['分群']} 客户数", f"{stats['客户数']} ({stats['占比']})"],
[f"{stats['分群']} 平均消费", stats['平均消费']],
['', ''], # Separator
])
# Create table
table = ax.table(cellText=table_data,
colLabels=headers,
cellLoc='left',
loc='center',
colWidths=[0.6, 0.4])
table.auto_set_font_size(False)
table.set_fontsize(9)
table.scale(1, 1.5)
# Style the table
for i in range(len(headers)):
table[(0, i)].set_facecolor('#4CAF50')
table[(0, i)].set_text_props(weight='bold', color='white')
ax.set_title('关键指标摘要\nKey Metrics Summary', fontsize=12, fontweight='bold')
ax.axis('off')
def create_individual_charts(self, rfm_df, output_dir='charts'):
"""
Create individual charts for detailed analysis
Args:
rfm_df (pd.DataFrame): Complete RFM analysis results
output_dir (str): Directory to save individual charts
"""
import os
os.makedirs(output_dir, exist_ok=True)
print("生成详细分析图表...")
# 1. Customer segment distribution
plt.figure(figsize=(10, 8))
self._create_segment_distribution_detailed(rfm_df)
plt.savefig(f'{output_dir}/segment_distribution_detailed.png', dpi=300, bbox_inches='tight')
plt.close()
# 2. RFM score distribution
plt.figure(figsize=(15, 5))
self._create_rfm_score_distribution(rfm_df)
plt.savefig(f'{output_dir}/rfm_score_distribution.png', dpi=300, bbox_inches='tight')
plt.close()
# 3. Customer lifetime value analysis
plt.figure(figsize=(12, 8))
self._create_clv_analysis(rfm_df)
plt.savefig(f'{output_dir}/customer_lifetime_value.png', dpi=300, bbox_inches='tight')
plt.close()
print(f"详细图表已保存到: {output_dir}/")
def _create_segment_distribution_detailed(self, df):
"""Create detailed segment distribution chart"""
fig, ((ax1, ax2), (ax3, ax4)) = plt.subplots(2, 2, figsize=(15, 12))
# Customer count by segment
segment_counts = df['客户价值'].value_counts()
colors = ['#45b7d1', '#4ecdc4', '#ff6b6b']
ax1.pie(segment_counts.values, labels=segment_counts.index, colors=colors,
autopct='%1.1f%%', startangle=90)
ax1.set_title('客户数量分布', fontweight='bold')
# Revenue by segment
revenue_by_segment = df.groupby('客户价值')['金额性'].sum()
ax2.pie(revenue_by_segment.values, labels=revenue_by_segment.index, colors=colors,
autopct='%1.1f%%', startangle=90)
ax2.set_title('收入分布', fontweight='bold')
# Average order value by segment
avg_order = df.groupby('客户价值')['金额性'].mean()
bars = ax3.bar(avg_order.index, avg_order.values, color=colors)
ax3.set_title('平均客户价值', fontweight='bold')
ax3.set_ylabel('金额 (¥)')
for bar, value in zip(bars, avg_order.values):
ax3.text(bar.get_x() + bar.get_width()/2, bar.get_height(),
f'¥{value:,.0f}', ha='center', va='bottom')
# Customer count by RFM score
score_counts = df['RFM总分'].value_counts().sort_index()
ax4.bar(score_counts.index, score_counts.values, color='lightcoral', alpha=0.7)
ax4.set_title('RFM总分分布', fontweight='bold')
ax4.set_xlabel('RFM总分')
ax4.set_ylabel('客户数')
plt.tight_layout()
def _create_rfm_score_distribution(self, df):
"""Create RFM score distribution charts"""
fig, (ax1, ax2, ax3) = plt.subplots(1, 3, figsize=(15, 5))
# Recency score distribution
r_scores = df['R_评分'].value_counts().sort_index()
ax1.bar(r_scores.index, r_scores.values, color='lightblue', alpha=0.7)
ax1.set_title('最近性评分分布 (R)')
ax1.set_xlabel('R评分')
ax1.set_ylabel('客户数')
# Frequency score distribution
f_scores = df['F_评分'].value_counts().sort_index()
ax2.bar(f_scores.index, f_scores.values, color='lightgreen', alpha=0.7)
ax2.set_title('频率性评分分布 (F)')
ax2.set_xlabel('F评分')
ax2.set_ylabel('客户数')
# Monetary score distribution
m_scores = df['M_评分'].value_counts().sort_index()
ax3.bar(m_scores.index, m_scores.values, color='lightcoral', alpha=0.7)
ax3.set_title('金额性评分分布 (M)')
ax3.set_xlabel('M评分')
ax3.set_ylabel('客户数')
plt.tight_layout()
def _create_clv_analysis(self, df):
"""Create customer lifetime value analysis"""
fig, ((ax1, ax2), (ax3, ax4)) = plt.subplots(2, 2, figsize=(15, 12))
# Customer value vs Recency
for segment in ['High', 'Medium', 'Low']:
segment_data = df[df['客户价值'] == segment]
if len(segment_data) > 0:
ax1.scatter(segment_data['最近性'], segment_data['金额性'],
label=segment, alpha=0.6, s=20)
ax1.set_xlabel('最近购买天数')
ax1.set_ylabel('总消费金额')
ax1.set_title('客户价值 vs 最近购买')
ax1.legend()
ax1.invert_xaxis() # Lower recency is better
# Customer value vs Frequency
for segment in ['High', 'Medium', 'Low']:
segment_data = df[df['客户价值'] == segment]
if len(segment_data) > 0:
ax2.scatter(segment_data['频率性'], segment_data['金额性'],
label=segment, alpha=0.6, s=20)
ax2.set_xlabel('购买频率')
ax2.set_ylabel('总消费金额')
ax2.set_title('客户价值 vs 购买频率')
ax2.legend()
ax2.set_xscale('log')
# RFM total score distribution
score_dist = df['RFM总分'].value_counts().sort_index()
ax3.bar(score_dist.index, score_dist.values, color='purple', alpha=0.7)
ax3.set_xlabel('RFM总分')
ax3.set_ylabel('客户数')
ax3.set_title('RFM总分分布')
# Customer segment by total score
segment_scores = df.groupby('客户价值')['RFM总分'].mean()
bars = ax4.bar(segment_scores.index, segment_scores.values,
color=['#ff6b6b', '#4ecdc4', '#45b7d1'])
ax4.set_title('各分群平均RFM得分')
ax4.set_ylabel('平均RFM总分')
for bar, score in zip(bars, segment_scores.values):
ax4.text(bar.get_x() + bar.get_width()/2, bar.get_height(),
f'{score:.1f}', ha='center', va='bottom', fontweight='bold')
plt.tight_layout()
def main():
"""Example usage of visualizer"""
# Example - would use actual data
visualizer = RFMVisualizer()
# Create sample data for demonstration
sample_data = pd.DataFrame({
'用户码': range(100),
'最近性': np.random.randint(1, 365, 100),
'频率性': np.random.randint(1, 50, 100),
'金额性': np.random.randint(100, 10000, 100),
'客户价值': np.random.choice(['High', 'Medium', 'Low'], 100),
'RFM总分': np.random.randint(3, 9, 100),
'R_评分': np.random.randint(1, 4, 100),
'F_评分': np.random.randint(1, 4, 100),
'M_评分': np.random.randint(1, 4, 100),
'cluster': np.random.randint(0, 3, 100)
})
# Create dashboard
visualizer.create_comprehensive_dashboard(sample_data)
print("示例仪表板已生成: rfm_dashboard.png")
if __name__ == "__main__":
main()