-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathRFM.py
More file actions
108 lines (79 loc) · 2.38 KB
/
Copy pathRFM.py
File metadata and controls
108 lines (79 loc) · 2.38 KB
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
import pandas as pd
from datetime import timedelta
import matplotlib.pyplot as plt
def build_rfm_base(df):
"""
Construction de la base RFM (même logique que le notebook)
"""
df = df.copy()
df["InvoiceDate"] = pd.to_datetime(df["InvoiceDate"])
df["Montant"] = df["Quantity"] * df["UnitPrice"]
# Date de référence (lendemain du dernier achat)
analysis_date = df["InvoiceDate"].max() + timedelta(days=1)
rfm = df.groupby("CustomerID").agg({
"InvoiceDate": lambda x: (analysis_date - x.max()).days,
"InvoiceNo": "nunique",
"Montant": "sum"
}).reset_index()
rfm.columns = ["CustomerID", "Recence", "Frequence", "Montant"]
return rfm
def compute_rfm_scores(rfm):
"""
Calcul des scores R, F et M par quantiles
"""
rfm = rfm.copy()
rfm["R_Score"] = pd.qcut(
rfm["Recence"], 5, labels=[5, 4, 3, 2, 1]
)
rfm["F_Score"] = pd.qcut(
rfm["Frequence"].rank(method="first"), 5, labels=[1, 2, 3, 4, 5]
)
rfm["M_Score"] = pd.qcut(
rfm["Montant"], 5, labels=[1, 2, 3, 4, 5]
)
rfm["RFM_Score"] = (
rfm["R_Score"].astype(int) +
rfm["F_Score"].astype(int) +
rfm["M_Score"].astype(int)
)
return rfm
def segment_clients(rfm):
"""
Segmentation RFM (interprétation métier)
"""
rfm = rfm.copy()
def segment(row):
if row["RFM_Score"] >= 13:
return "Clients Premium"
elif row["RFM_Score"] >= 10:
return "Clients Fidèles"
elif row["RFM_Score"] >= 7:
return "Clients Potentiels"
elif row["RFM_Score"] >= 5:
return "Clients Occasionnels"
else:
return "Clients à risque"
rfm["Segment"] = rfm.apply(segment, axis=1)
return rfm
def segment_summary(rfm):
return (
rfm.groupby("Segment")
.agg(
Nb_Clients=("CustomerID", "nunique"),
Montant_Moyen=("Montant", "mean"),
Frequence_Moyenne=("Frequence", "mean"),
Recence_Moyenne=("Recence", "mean")
)
.round(1)
.reset_index()
)
def plot_rfm_segments(rfm):
fig, ax = plt.subplots()
rfm["Segment"].value_counts().plot(
kind="bar",
ax=ax
)
ax.set_title("Répartition des segments RFM")
ax.set_xlabel("Segment")
ax.set_ylabel("Nombre de clients")
return fig