python數據分析與數據運營---第五章RFM實戰案例

5.7案例:基於RFM的精細化用戶管理

案例背景:在用戶2015-2018年訂單數據的基礎上,對用戶進行分羣,總結每個組用戶特徵,以便於精細化運營,制定定製化和差異性的營銷和關懷;

分析思路:基於RFM對用戶進行分羣,將三個維度分別作三個區間的離散化

import time
import numpy as np
import pandas as pd
from sklearn.ensemble import RandomForestClassifier
from pyecharts.charts import Bar3D
import pyecharts.options as opts

sheet_names = ["2015","2016","2017","2018","會員等級"]
sheet_datas = [pd.read_excel(r"D:\data_analysis_and_data_operation_with_python\python_book_v2\chapter5\sales.xlsx",sheet_name=i) for i in sheet_names]

#查看各個表是否存在缺失值
#for i in sheet_datas:
#    print(i.info())
for each_name,each_data in zip(sheet_names,sheet_datas):
    print("[data summary for {0:=^50}]".format(each_name))
    print("Overview:","\n",each_data.head())
    print("DESC:","\n",each_data.describe())
    print("NA records",each_data.isnull().any(axis=1).sum())
    
#數據均可以讀取,無格式錯誤。缺失值總共只有一個,可以直接刪除,其次訂單金額分佈極不均衡,根據業務背景,極大值產生是合理的(有貴重商品),其次金額小於1的訂單,沒有實際意義;
#處理缺失值和刪除訂單金額小於1的數據
for ind,each_data in enumerate(sheet_datas[:-1]):
    sheet_datas[ind] = each_data.dropna()
    sheet_datas[ind] = each_data[each_data["訂單金額"]>1]
    #便於計算,最近一購買時間間隔
    sheet_datas[ind]["max_years_date"] = each_data["提交日期"].max()
    
#將年份數據進行縱向合併
data_merge = pd.concat(sheet_datas[:-1],axis=0)
#獲取購買時間與年末的差值(最近一次購買),獲取購買年份
data_merge["date_interval"] = data_merge["max_years_date"] - data_merge["提交日期"]
data_merge["year"] = data_merge["提交日期"].dt.year
#date_interval時間戳轉化爲數字
data_merge["date_interval"] = data_merge["date_interval"].apply(lambda x:x.days)
#提取“購買金額”,“購買次數”,“最近一次購買”時間字段,有兩種方法,數據透視表以及groupby
#rfm_gb = pd.pivot_table(data_merge,index=["year","會員ID"],values=["訂單號","訂單金額","date_interval"],aggfunc=
#                     {"訂單號":"count","訂單金額":"sum","date_interval":"min"}).reset_index()
rfm_gb = data_merge.groupby(["year","會員ID"],as_index=False).agg({
        "date_interval":"min",
        "提交日期":"count",
        "訂單金額":"sum"})
rfm_gb.columns=["year","會員ID","r","f","m"]
#查看屬性分佈
rfm_gb[["r","f","m"]].describe()
  r f m
count 148591 148591 148591
mean 165.524043 1.365002 1323.741329
std 101.988472 2.626953 3753.906883
min 0 1 1.5
25% 79 1 69
50% 156 1 189
75% 255 1 1199
max 365 130 206251.8

數據解讀,最近一次購買時間分佈較爲均勻,購買頻率大部分用戶爲一次,主要是因爲行業屬性(大家電)原因,用戶一年購買一次較爲普遍,那麼最近一次購買時間分佈均爲也是此原因,可以認爲家電購買時間隨機分佈;(個人感覺將最近一次購買時間作爲重要指標不合適)

#臨界點劃分,r和m以四分位點劃分即可,f則以[0,2,5,130]進行劃分;
#定義區間邊界,注意最小值,python進行區間分割時,是左開右閉區間
r_bins = [-1,79,255,365]
f_bins = [0,2,5,130]
m_bins = [-1,69,1199,206252]
#確定rfm因子權重,基於會員等級給予權重
rfm_merge = pd.merge(rfm_gb,sheet_datas[-1],on="會員ID",how="inner")
clf = RandomForestClassifier()
clf = clf.fit(rfm_merge[["r","f","m"]],rfm_merge["會員等級"])
weights = clf.feature_importances_
#rfm分箱,並將分類屬性轉化爲數值屬性
rfm_gb["r_score"] = pd.cut(rfm_gb["r"],r_bins,labels = [i for i in range(len(r_bins)-1,0,-1)])
rfm_gb["f_score"] = pd.cut(rfm_gb["f"],f_bins,labels = [i+1 for i in range(len(f_bins)-1)])
rfm_gb["m_score"] = pd.cut(rfm_gb["m"],m_bins,labels = [i+1 for i in range(len(m_bins)-1)])
#計算RFM加權得分
rfm_gb = rfm_gb.apply(np.int32)
rfm_gb["rfm_score"] = rfm_gb["r_score"]*weights[0] + rfm_gb["f_score"]*weights[1]+rfm_gb["m_score"]*weights[2]
#計算RFM組合分羣,
rfm_gb["r_score"] = rfm_gb["r_score"].astype(np.str)
rfm_gb["f_score"] = rfm_gb["f_score"].astype(np.str)
rfm_gb["m_score"] = rfm_gb["m_score"].astype(np.str)
rfm_gb["rfm_group"] = rfm_gb["r_score"].str.cat(rfm_gb["f_score"]).str.cat(rfm_gb["m_score"])
#保存數據文件
rfm_gb.to_excel(r"D:\data_analysis_and_data_operation_with_python\sales_rfm_score.xlsx")
#RFM圖形展示,只展示年份,rfm分組,用戶數量
display_data = rfm_gb.group_by(["rfm_group","year"],as_index=False)["會員ID"].count()
display_data.columns = ["rfm_group","year","number"]
display_data["rfm_group"] = display_data["rfm_group"].astype(np.int32)
#畫圖
bar3d = Bar3D(init_opts=opts.InitOpts(width="900px", height="600px"))
range_color = ["#313695","#4575b4","#74add1","#abd9e9","#e0f3f8","#ffffbf",
              "#fee090","#fdae61","#f46d43","#d73027","#a50026"]

bar3d.add(
        series_name="rfm分組結果",
        data = [d.tolist() for d in display_data.values]
        ).set_global_opts(
        visualmap_opts=opts.VisualMapOpts(
            max_=display_data["number"].max(),
            range_color=range_color,
        ))
bar3d.render(r"D:\data_analysis_and_data_operation_with_python\sales_rfm_score.html")


結果分析:

用戶標籤 用戶數量佔比 用戶消費金額佔比 運營思路
212 24.79% 5.58% 可發展的一般性羣體,通過運營手段維持並提升其消費狀態
211 12.80% 0.32% 可發展的低價值羣體,通過運營手段提升其購買金額
312 12.55% 2.86% 有潛力的一般性羣體,購買新近度高,單忠誠度一般,通過其最近購買的商品,推薦相關商品
112 11.34% 2.53% 可挽回的一般性羣體,通過多種方式觸達客戶並挽回
213 11.02% 31.48% 可發展的高價值羣體,發展重點是提高其購物頻率
311 6.24% 0.16% 有潛力的低價值羣體,可以通過分析其渠道,加大相應渠道的投入,引導客戶復購
111 6.14% 0.16% 各個維度都比較差的羣體,主要通過多種策略挽回客戶(資源足夠的情況下)
313 5.61% 16.57% 有潛力的高價值羣體,發展重點是提高其購物頻率
113 5.07% 14.19% 可挽回的高價值羣體,可適當的進行人工介入
123 1.30% 4.80%
333 0.33% 4.53% 絕對忠誠的高價值各戶,應爲其提供相應的VIP服務
233 0.70% 9.21% 一般性的高價值客戶,重點在於提升新近購買度
133 0.32% 4.66%
223 0.25% 1.33%
322 0.28% 0.09% 有潛力的普通羣體,需要提升購買頻次,和額度
323 0.25% 1.14%
332 0.02% 0.01%

總結:1,個人認爲該案例數據不太實用RFM模型,因爲數據北京是大家電行業,大型的家用電器一般屬於耐用品,屬於絕對的低頻消費,因此在購買頻次這個指標很難看出客戶的價值,其次也很難通過運營提高購買頻次;最近的購買時間也是如此,如果你購買的時間越短,反而不會再進行購買;是否可以根據產品的生命週期,提醒客戶更新換代,並推出相應的以舊換新服務;

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章