POS 横断ミニケース| RFM / ABC / デシルを小さなデータで一気に演習
TL;DR
- 目的: 1 つの小データから RFM/ABC/デシルの“違い”と“読み方”を体感
- 手順: サンプルを読み込み → 指標作成 → RFM/ABC/デシルを順に実行 → 意味を読む
サンプルデータ(10 行)
import pandas as pd
from datetime import datetime
df = pd.DataFrame({
'customer':['A','B','C','D','E','F','G','H','I','J'],
'last_purchase_days':[10,45,5,120,60,15,200,8,30,70],
'frequency':[6,3,10,1,2,5,1,8,4,2],
'monetary':[52000,18000,98000,3000,8000,42000,1500,76000,25000,12000],
'sku':['s1','s2','s3','s4','s5','s1','s2','s3','s4','s5'],
'sales':[120000,80000,60000,15000,5000,40000,22000,9000,30000,70000]
})
1) RFM(顧客の最近性 × 頻度 × 金額)
import numpy as np
def qcut_score(x, q=5, reverse=False):
s = pd.qcut(x.rank(method='first'), q, labels=False) + 1
return (q - s + 1) if reverse else s
df['R_score'] = qcut_score(df['last_purchase_days'], reverse=True)
df['F_score'] = qcut_score(df['frequency'])
df['M_score'] = qcut_score(df['monetary'])
df['RFM'] = 100df['R_score'] + 10df['F_score'] + df['M_score']
print(df[['customer','R_score','F_score','M_score','RFM']].sort_values('RFM', ascending=False))
読み方: R 小さいほど良、F/M 大きいほど良。高スコアはロイヤル候補。
2) ABC(SKU の寄与で 3 区分)
df_abc = df[['sku','sales']].groupby('sku', as_index=False).sum().sort_values('sales', ascending=False)
df_abc['share'] = df_abc['sales'] / df_abc['sales'].sum()
df_abc['cum_share'] = df_abc['share'].cumsum()
def abc(c):
if c <= 0.7: return 'A'
if c <= 0.9: return 'B'
return 'C'
df_abc['ABC'] = df_abc['cum_share'].apply(abc)
print(df_abc)
読み方: A は重点管理、C は長尾最適化。
3) デシル(顧客を 10 等分)
df_dec = df[['customer','monetary']].sort_values('monetary', ascending=False).copy()
df_dec['decile'] = pd.qcut(df_dec['monetary'].rank(method='first', ascending=False), 10, labels=False) + 1
summary = df_dec.groupby('decile').agg({'monetary':['sum','mean','count']})
summary.columns = ['sum','mean','n']
summary['share'] = summary['sum']/summary['sum'].sum()
print(summary)
読み方: 上位デシルの寄与が大なら VIP 施策、均等ならマス施策。
練習問題(理解を定着)
- RFM とデシルで「上位」と出る顧客が違う。なぜ?
- ヒント: 指標が異なる(最近性/頻度/金額 vs 金額のみ)。目的に応じて使い分け
- ABC で C に戦略 SKU が入った。どうする?
- ヒント: 粗利で再評価、例外リスト運用
- セール期間を含めると結果が大きく変動。対策は?
- ヒント: 期間分割、キャンペーン別集計
関連記事
POSデータ分析についてのご相談はこちら