1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
| # RFM用户价值分层分析
import pandas as pd
import numpy as np
from datetime import datetime, timedelta
class RFMAnalysis:
"""RFM用户价值分析"""
def __init__(self, transactions_df):
"""
transactions_df: 包含用户交易数据
必需列: user_id, order_date, amount
"""
self.df = transactions_df
self.analysis_date = datetime.now()
def calculate_rfm(self):
"""计算RFM指标"""
# 计算最近购买时间
recency = self.df.groupby('user_id')['order_date'].max().reset_index()
recency['recency'] = (
self.analysis_date - recency['order_date']
).dt.days
# 计算购买频率
frequency = self.df.groupby('user_id')['order_date'].count().reset_index()
frequency.columns = ['user_id', 'frequency']
# 计算购买金额
monetary = self.df.groupby('user_id')['amount'].sum().reset_index()
monetary.columns = ['user_id', 'monetary']
# 合并RFM
rfm = recency.merge(frequency, on='user_id').merge(monetary, on='user_id')
rfm = rfm[['user_id', 'recency', 'frequency', 'monetary']]
return rfm
def score_rfm(self, rfm_df, n_quantiles=5):
"""RFM评分(1-5分)"""
# R分数:越小越好(最近购买得分高)
rfm_df['R_score'] = pd.qcut(
rfm_df['recency'],
n_quantiles,
labels=[5, 4, 3, 2, 1],
duplicates='drop'
).astype(int)
# F分数:越大越好
rfm_df['F_score'] = pd.qcut(
rfm_df['frequency'].rank(method='first'),
n_quantiles,
labels=[1, 2, 3, 4, 5],
duplicates='drop'
).astype(int)
# M分数:越大越好
rfm_df['M_score'] = pd.qcut(
rfm_df['monetary'].rank(method='first'),
n_quantiles,
labels=[1, 2, 3, 4, 5],
duplicates='drop'
).astype(int)
# 计算综合RFM分数
rfm_df['RFM_score'] = (
rfm_df['R_score'] * 100 +
rfm_df['F_score'] * 10 +
rfm_df['M_score']
)
return rfm_df
def segment_users(self, rfm_df):
"""用户分群"""
def assign_segment(row):
R, F, M = row['R_score'], row['F_score'], row['M_score']
# 重要价值客户
if R >= 4 and F >= 4 and M >= 4:
return 'Champions'
# 重要保持客户
elif R >= 3 and F >= 3 and M >= 3:
return 'Loyal Customers'
# 潜力客户
elif R >= 3 and F <= 2 and M >= 3:
return 'Potential Loyalist'
# 重要挽留客户
elif R <= 2 and F >= 3 and M >= 3:
return 'At Risk'
# 流失客户
elif R <= 2 and F <= 2 and M <= 2:
return 'Lost'
# 新客户
elif F <= 2 and M <= 2:
return 'New Customers'
else:
return 'Others'
rfm_df['segment'] = rfm_df.apply(assign_segment, axis=1)
return rfm_df
def get_segment_insights(self, rfm_df):
"""分群洞察"""
segments = rfm_df.groupby('segment').agg({
'user_id': 'count',
'recency': 'mean',
'frequency': 'mean',
'monetary': ['mean', 'sum']
}).round(2)
segments.columns = [
'user_count', 'avg_recency', 'avg_frequency',
'avg_monetary', 'total_monetary'
]
segments = segments.sort_values('total_monetary', ascending=False)
return segments
def recommend_strategies(self, segment):
"""分群策略建议"""
strategies = {
'Champions': {
'priority': 'Highest',
'strategy': 'VIP服务',
'actions': [
'专属客服',
'优先功能访问',
'专属折扣',
'推荐计划邀请'
],
'expected_impact': '保持忠诚度,提高复购'
},
'Loyal Customers': {
'priority': 'High',
'strategy': '会员升级',
'actions': [
'忠诚度奖励',
'升级优惠',
'会员特权',
'生日福利'
],
'expected_impact': '提升消费频次'
},
'At Risk': {
'priority': 'High',
'strategy': '挽回激活',
'actions': [
'个性化优惠',
'产品更新通知',
'客服回访',
'限时折扣'
],
'expected_impact': '防止流失,重新激活'
},
'Lost': {
'priority': 'Medium',
'strategy': '重新获客',
'actions': [
'大幅折扣',
'新产品推荐',
'问卷调查',
'改进沟通'
],
'expected_impact': '部分挽回'
},
'New Customers': {
'priority': 'Medium',
'strategy': '新手培养',
'actions': [
'新手引导',
'功能教程',
'首次购买优惠',
'社群邀请'
],
'expected_impact': '转化为活跃用户'
}
}
return strategies.get(segment, {})
|