目錄
一.項目背景與數據來源
二、提出問題
三. 數據處理
3.1 導入數據
--3.1.1 導入常用的庫
--3.1.2 導入源數據
--3.1.3 查看數據的基本信息
3.2 描述性統計
3.3 數據處理
--3.3.1 缺省值
--3.3.2 數據清洗
四. 用戶總體消費趨勢分析
每月的總銷售額、每月的消費次數、每月的銷量、每月的消費人數波動
五.用戶個體消費數據分析
5.1 用戶消費金額和消費次數的描述統計
5.2 用戶消費金額和消費次數的散點圖
5.3 用戶消費金額的分布圖(二八法則)
5.4 用戶消費次數的分布圖(二八法則)
六.用戶消費周期分析
6.1 用戶購買周期(按訂單)
--6.1.1 用戶消費周期描述
--6.1.2 用戶消費周期分布
6.2 用戶生命周期(按第一次&最后一次消費)
-- 6.2.1 用戶生命周期描述
--6.2.2 用戶生命周期分布
七.用戶分層
7.1 按用戶價值分層---RFM模型
7.2 按用戶活躍程度分層---新用戶、活躍用戶、不活躍用戶、回流用戶
八.用戶質量分析
8.1 多少用戶僅消費一次?
8.2 復購率
8.3 回購率
8.4 分析留存率(3,7,15,30,90,365天為周期)
8.5 大客戶的貢獻率
--8.5.1 用戶銷售額貢獻情況
--8.5.2 用戶銷量貢獻情況
九.結論
一、項目背景
CDNow曾經是一家在線音樂零售平臺,后被德國波泰爾斯曼娛樂集團公司出資收購,其資產總價值在最輝煌時曾超過10億美元。本文主要通過分析CDNow網站的用戶購買明細來分析該網站的用戶消費行為,使運營部門在營銷時更加具有針對性,從而節省成本,提升效率。
數據來源
本次分析數據來源CDNow網站的用戶在1997年1月1日至1998年6月30日期間內購買CD交易明細。
數據下載地址——提取碼: va7h
數據集一共有用戶ID,購買日期,訂單數,訂單金額四個字段。
二、提出問題
對用戶進行消費特征分析。分析框架如下:
三.數據處理
3.1 導入數據
3.1.1 導入常用的庫:
#導入常用的庫
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from datetime import datetime
%matplotlib inline #‘%’內置的命令,jupyter專有的定義,比如在pycharm不常用到,inline意思是做圖之后可以在html頁面的單元格進行顯示
plt.style.use('ggplot') #更改設計風格,使用自帶的形式進行美化,這是一個r語言的風格
3.1.2 導入源數據
數據中未包含列標題,因此在導入數據時要設置列標題。分隔符為空格。
#導入源數據
columns = ['用戶ID','購買日期','訂單數','訂單金額']
df = pd.read_table("CDNOW_master.txt",names = columns,sep = '\s+')
- 加載包和數據,文件是txt,用read_table方法打開,因為原始數據不包含表頭,所以需要賦予。字符串是空格分割,用\s+表示匹配任意空白符。
- 一般csv的數據分隔是以逗號的形式,但是這份來源于網上的數據比價特殊,它是通過多個空格來進行分隔
- 消費行業或者是電商行業一般是通過訂單數,訂單額,購買日期,用戶ID這四個字段來分析的。基本上這四個字段就可以進行很豐富的分析。
3.1.3 查看數據的基本信息
#默認輸出前五行
df.head()
- 觀察數據,購買日期列表示時間,但現在它只是年月日組合的一串數字,數據不是時間類型,沒有時間含義,需要轉換。購買金額是小數。
- 數據中存在一個用戶在同一天或不同天下多次訂單的情況,如用戶ID為2的用戶就在1月12日買了兩次。
3.2 描述性統計
#數值列的匯總統計信息
df.describe()
describe是描述統計,對用戶數據特征進行整體性判斷:
- 從數據的統計描述信息中可以看出,用戶每個訂單平均購買2.41個商品,每個訂單平均消費35.89元。
- 購買商品數量的標準差為2.33,說明數據具有一定的波動性;中位數為2個商品,75分位數為3個商品,說明大部分訂單的購買數量都不多。最大值在99個,數字比較高。購買金額的情況差不多,大部分訂單都集中在小額。
- 一般而言,消費類的數據分布,都是長尾形態。大部分用戶都是小額,然而小部分用戶貢獻了收入的大頭,俗稱二八。
3.3 數據處理
3.3.1 缺省值
#索引,數據類型和內存信息
df.info()
- 查看數據類型、數據是否存在空值;原數據沒有空值,很干凈的數據。接下來我們要將時間的數據類型轉化。
- 當利用pandas進行數據處理的時候,經常會遇見數據類型的問題,當拿到數據的時候,首先要確定拿到的是正確的數據類型,如果數據類型不正確需要進行數據類型的轉化,再進行數據處理。附:常見pandas數據類型轉化
3.3.2 數據清洗
將時間進行數據類型轉換,并增加月度列。
# 將購買日期列進行數據類型轉換
df['購買日期'] = pd.to_datetime(df.購買日期,format = '%Y%m%d') #Y四位數的日期部分,y表示兩位數的日期部分
df['月份'] = df.購買日期.values.astype('datetime64[M]')
df.head()
- pd.to_datetime可以將特定的字符串或者數字轉換成時間格式,其中的format參數用于匹配。例如19970101,%Y匹配前四位數字1997,如果y小寫只匹配兩位數字97,%m匹配01,%d匹配01。
- 另外,小時是%h,分鐘是%M,注意和月的大小寫不一致,秒是%s。若是1997-01-01這形式,則是%Y-%m-%d,以此類推。
-
astype也可以將時間格式進行轉換,比如[M]轉化成月份。我們將月份作為消費行為的主要事件窗口,選擇哪種時間窗口取決于消費頻率。
檢查有無空值
df.info()
四.用戶總體消費趨勢分析
#解決中文顯示參數設置
plt.rcParams['font.sans-serif']=['SimHei'] #用來正常顯示中文標簽
plt.rcParams['axes.unicode_minus'] = False #用來正常顯示負號
# 設置圖的大小,添加子圖
plt.figure(figsize=(20,15))
# 每月的總銷售額
plt.subplot(221)
df.groupby('月份')['訂單金額'].sum().plot(fontsize=24)
plt.title('總銷售額',fontsize=24)
#每月的消費次數
plt.subplot(222)
df.groupby('月份')['購買日期'].count().plot(fontsize=24)
plt.title('消費次數',fontsize=24)
#每月的銷量
plt.subplot(223)
df.groupby('月份')['訂單數'].sum().plot(fontsize=24)
plt.title('總銷量',fontsize=24)
#每月的消費人數
plt.subplot(224)
df.groupby('月份')['用戶ID'].apply(lambda x:len(x.unique())).plot(fontsize=24)
plt.title('消費人數',fontsize=24)
plt.tight_layout() # 設置子圖的間距
plt.show()
- 四個折線圖的整體趨勢基本一致,可以看出來,1997年前3個月的銷量特別高,隨之而來的銷售額也是暴漲,在3月份之后驟然下降,接近平穩。
- 為什么會呈現這個原因呢?我們假設是用戶身上出了問題,早期時間段的用戶中有異常值,第二假設是各類促銷營銷,但這里只有消費數據,所以無法判斷。
另一方面,在2月到3月這段期間,可以發現消費人數稍有下降,但總銷量與總銷售額卻依然上升,是不是說明3月份的用戶中有我們需要重點發展的高價值客戶呢? - Python繪圖如何顯示中文標題
五. 用戶個體消費數據分析
之前我們維度是用戶整體,看的是趨勢。有時候我們也需要看個體來看這個人的消費能力如何,這里劃分了五個方向如下:
5.1 用戶消費金額,消費次數的描述統計
# 根據用戶id進行分組
group_user = df.groupby('用戶ID').sum()
group_user.describe()
- 從用戶角度看,每位用戶平均購買7張CD,最多的用戶購買了1033張。用戶的平均消費金額(客單價)100元,標準差是240,結合分位數和最大值看,平均值才和75分位接近,肯定存在小部分的高額消費用戶,這也符合二八法則。
5.2 用戶消費金額和消費次數的散點圖
#查詢條件:訂單金額 < 4000
group_user.query('訂單金額 < 4000').plot.scatter(x='訂單金額',y='訂單數')
- 繪制用戶的散點圖,用戶比較健康而且規律性很強。因為這是CD網站的銷售數據,商品比較單一,金額和商品量的關系也因此呈線性,沒幾個離群點。
5.3 用戶消費金額的分布圖(二八法則)
group_user.訂單金額. plot.hist(bins = 20)
#bins = 20,就是分成20塊,最高金額是14000,每個項就是700
從圖上看出,用戶的消費呈集中趨勢,可能是有個別的極大值干擾導致。
可以排除極大值再看看分布情況
group_user.query("訂單金額< 800")['訂單金額'].plot.hist(bins=20)
篩選出了消費金額小于800的用戶,我們可以看到:
- 大部分用戶的消費能力并不高,將近半數的用戶消費金額不超過40元,高消費用戶( >200元 )不超過2000人。
- 從上圖直方圖可知,大部分用戶的消費能力確實不高,絕大部分呈現集中在很低的消費檔次。高消費用戶在圖上幾乎看不到,這也確實符合消費行為的行業規律。
- 雖然有極端數據干擾,但是大部分的用戶還是集中在比較低的消費檔次。
5.4 用戶消費次數的分布圖(二八法則)
group_user.query('訂單數 < 100').訂單數.hist(bins = 40)
- 大部分用戶購買CD的數量都是在3張以內,購買大量CD的用戶數量并不多。
六.用戶消費周期分析
6.1 用戶購買周期(按訂單)
6.1.1 用戶消費周期描述
#每個用戶的每次購買時間間隔
order_diff = df.groupby('用戶ID').apply(lambda x:x['購買日期'] - x['購買日期'].shift())
order_diff.head(10)
這是每個用戶的每次購買時間間隔。
order_diff.describe()
- 平均每個用戶的購買時間間隔是68天,間隔最長的是533天。想要召回用戶,在60天左右的消費間隔是比較好的。
- 絕大部分用戶的消費周期都低于100天。
6.1.2 用戶消費周期分布
plt.figure(figsize=(15,5))
plt.hist((order_diff / np.timedelta64(1, 'D')).dropna(), bins = 50)
plt.xlabel('消費周期',fontsize=24)
plt.ylabel('頻數',fontsize=24)
plt.title('用戶消費周期分布圖',fontsize=24);
- 典型的(指數)長尾分布,大部分用戶的消費間隔確實比較短。不妨將時間召回點設為消費后立即贈送優惠券,消費后10天詢問用戶禮品怎么樣,消費后20天提醒優惠券到期,消費后30天短信推送。
6.2 用戶生命周期(按第一次&最后一次消費)
6.2.1 用戶生命周期描述
接下來計算每一位用戶生命周期,這里定義第一次消費至最后一次消費為整個用戶生命。
orderdt_min=df.groupby('用戶ID').購買日期.min()#第一次消費
orderdt_max=df.groupby('用戶ID').購買日期.max()#最后一次消費
(orderdt_max-orderdt_min).head()
計算用戶的平均生命周期。
(orderdt_max-orderdt_min).mean()
- 所有用戶的平均生命周期是134天,比預想的高,但是平均數不具有代表性,接下來還是看一下分布情況。
6.2.2 用戶生命周期分布
((orderdt_max-orderdt_min)/np.timedelta64(1,'D')).hist(bins=15)
#因為數據類型是timedelta時間,無法直接作出直方圖,所以先換算成數值。換算的方式直接除timedelta函數即可,np.timedelta64(1, ‘D’),D表示天,1表示1天,作為單位使用的。因為max-min已經表示為天了,兩者相除就是周期
- 大部分用戶只消費了一次,所有生命周期的大頭都集中在了0天。
但這不是我們想要的答案,不妨將只消費了一次的新客排除,來計算所有消費過兩次以上的老客的生命周期。
#計算所有消費過兩次以上的老客的生命周期
life_time = (orderdt_max - orderdt_min).reset_index()
life_time.head()
轉換成DataFrame
#用戶生命周期分布圖
plt.figure(figsize=(10,5))
life_time['life_time'] = life_time.購買日期 / np.timedelta64(1,'D')
life_time[life_time.life_time > 0].life_time.hist(bins = 100, figsize = (12,6))
- 上圖可見,用戶生命周期呈現雙峰趨勢,20天內生命周期的用戶是一個高峰,400至500天內生命周期的用戶是另一個高峰。
- 根據此情況,應該在20天內對客戶進行引導,促進其再次消費并形成消費習慣,延長其生命周期;在100至400天的用戶,也要根據其特點推出有針對性的營銷活動,引導其持續消費。
分析去掉0天生命周期的用戶之后的用戶生命周期的平均值。
#去掉0天生命周期的用戶之后的用戶生命周期的平均值
life_time[life_time.life_time>0].購買日期.mean()
- 可見,若在用戶首次消費后,加強對其再次消費的引導,可將其生命周期延長至原來的兩倍。
七.用戶分層
7.1 按用戶價值分層---RFM模型
為了進行精細化運營,可以利用RMF模型對用戶價值指數(衡量歷史到當前用戶貢獻的收益)進行計算,其中
最近一次消費-R:客戶最近一次交易時間的間隔。R值越大,表示客戶交易發生的日期越久,反之則交易發生的日期越近。
消費頻率-F:客戶在最近一段時間內交易的次數。F值越大,表示客戶交易越頻繁,反之則表示客戶交易不夠活躍。
消費金額-M:客戶在最近一段時間內交易的金額。M值越大,表示客戶價值越高,反之則表示客戶價值越低。
根據上述三個維度,對客戶做細分
rfm = df.pivot_table(index = '用戶ID',
values = ['訂單金額','購買日期','訂單數'],
aggfunc = {'訂單金額':'sum',
'購買日期':'max',
'訂單數':'sum'})
rfm.head()
# 日期的最大值與當前日期的差值為R
rfm['R'] = (rfm['購買日期'].max() - rfm['購買日期']) / np.timedelta64(1,'D')
rfm.rename(columns = {'訂單金額':'M',
'訂單數':'F'},
inplace=True)
# 構建rfm模型公式
def get_rfm(x):
level = x.apply(lambda x:'1' if x>=0 else '0')
label = level['R'] + level['F'] + level['M']
d = {'111':'重要價值客戶',
'011':'重要保持客戶',
'101':'重要挽留客戶',
'001':'重要發展客戶',
'110':'一般價值客戶',
'010':'一般保持客戶',
'100':'一般挽留客戶',
'000':'一般發展客戶'}
result = d[label]
return result
rfm['label'] = rfm[['R','F','M']].apply(lambda x:(x-x.mean()) / x.std()).apply(get_rfm,axis=1)
rfm.head()
#求和
rfm.groupby('label').sum()
- M列中不同層次客戶的消費累計金額,重要保持客戶的累計消費金額為159203.62,排名最高
rfm.groupby('label').size()
- 以上為不同層次用戶的消費人數,一般挽留用戶的消費人數排名第一,有14074人,重要保持客戶排名第二,有4554人,與一般挽留用戶差距比較大,但累計消費金額最多,業務方可以根據結果對客戶分類運營,降低營銷成本,提高ROI。
7.2 按用戶活躍程度分層---新用戶、活躍用戶、不活躍用戶、回流用戶
- 新用戶的定義是第一次消費。
- 活躍用戶即老客,在某一個時間窗口內有過消費。
- 不活躍用戶則是時間窗口內沒有消費過的老客。
- 回流用戶是在上一個窗口中沒有消費,而在當前時間窗口內有過消費。
#將用戶消費數據進行數據透視:
#用戶活躍程度分層
#將用戶消費數據進行數據透視:
df1 = df.pivot_table(index = "用戶ID",
columns = "月份",
values = '購買日期',
aggfunc = 'count').fillna(0)
df1.head()
- 圖中的數字(0,1,2)代表了當月的消費次數。
df2 = df1.applymap(lambda x:1 if x>0 else 0)
df2.tail()
- 0代表當月沒有消費,1代表有消費。
def active_status(data):
status=[]
for i in range(18): #共18個月
#若本月沒有消費
if data[i]==0:
if len(status)>0:#前面某月消費過,是老客
if status[i-1]=='unreg':#前一個月不是首次消費,不是新客
status.append('unreg')#則本月也不是新客
else:
status.append('unactive')#前一個月是首次消費,屬于新客,則本月為不活躍用戶
else:
status.append('unreg')#前面某月沒有消費過,則本月也不是新客
#若本月消費
else:
if len(status)==0:#前面沒有消費過
status.append('new')#則為新客
else:#前面消費過
if status[i-1] =='unactive':#前一個月沒有消費,是不活躍用戶
status.append('return')#本月為回流用戶
elif status[i-1]=='unreg':#前一個月沒有消費,不是新客
status.append('new')
else:#前一個月是首次消費
status.append('active')#本月為活躍用戶
return status
#可得到一張不同用戶在不同月份的不同狀態(new=新、active=活躍、return=回流、unactive=流失),unreg相當于未注冊,指這個用戶在這個月及以前從未購買過產品,主要為了統計起來更加方便而加進去。
indexs=df['月份'].sort_values().astype('str').unique()
df3=df2.apply(lambda x:pd.Series(active_status(x),index=indexs),axis=1)
df3.head()
#把unreg替換成NaN,再用fillna(0)把空值填為0。然后轉置,把月份作為索引行,狀態作為列,得到如下的表
df4=df3.replace('unreg',np.NaN).apply(lambda x:pd.value_counts(x)).fillna(0).T
df4
- 從表中可以看出,新客都是集中在前三個月,回流用戶整體在1000左右,而不活躍用戶數量隨時間稍有上升。
#作出非堆積效果圖:
u =df4.reset_index()
labels = u[['active','new','return','unactive']].columns
plt.figure(figsize=(15,5))
plt.stackplot(u['index'].astype(str).apply(lambda x:x[:-3]), u['active'],u['new'],u['return'],u['unactive'], labels=labels)
plt.xlabel('月份')
plt.ylabel('消費人數')
plt.title('每月的消費人數')
plt.legend(loc = 'upper left');
df5=df4.apply(lambda x:x/x.sum(),axis=1)#每一層用戶占總用戶的比例
df5
由上表可知,每月的用戶消費狀態變化:
- 新客用戶:僅在前三個月,后續再無新增客戶。
- 活躍用戶:比例持續下降,說明持續消費的用戶數量在減少,也說明運營部門的促活效果并不好。
- 回流用戶:比例也稍有下降,在4%左右波動。
- 不活躍用戶:比例稍有上升,流失較大。
八.用戶質量分析
8.1 多少用戶僅消費了一次? (一天內消費多次記作一次)
a = df.groupby('用戶ID')['購買日期'].agg(['min','max']).reset_index()
new_old = (a['min'] == a['max']).value_counts().values
plt.pie(x = new_old,
autopct = '%.1f%%',
shadow = True,
explode = [0.08,0],
textprops = {'fontsize' : 11})
plt.axis('equal')
plt.legend(['僅消費一次','多次消費'])
- 有超過一半的用戶僅消費了一次,這也說明了運營不利,留存效果不好。
8.2 復購率
復購率的定義:在某時間窗口內消費兩次及以上的用戶在總消費用戶中占比。這里的時間窗口是月,如果一個用戶在同一天下了兩筆訂單,這里也將他算作復購用戶
#每個用戶在每月的訂單數
pivoted_df=df.pivot_table(index='用戶ID',columns='月份',values='購買日期',#pivot_table透視表
aggfunc='count').fillna(0)#某些用戶在某月沒有消費過,用nan表示,這里用0填充
pivoted_df.head()
#轉換:消費2次以上記為1,消費1次記為0,消費0次記為NAN
#applymap針對dataframe所有數據
pivoted_df_transf=pivoted_df.applymap(lambda x: 1 if x>1 else np.nan if x==0 else 0)
pivoted_df_transf.head()
#count統計所有非空數據個數表示總消費用戶數,sum計算非0數據的和表示消費兩次以上的用戶數
df_duplicate =pd.DataFrame(pivoted_df_transf.sum()/pivoted_df_transf.count()).reset_index()
df_duplicate.columns = ['Date', 'DuplicatedRate']
df_duplicate['Date'] = df_duplicate.Date.astype(str).apply(lambda x:x[:-3])
plt.figure(figsize = (15,6))
plt.plot(df_duplicate.Date, df_duplicate.DuplicatedRate)
plt.xlabel('時間', fontsize=24)
plt.ylabel('復購率',fontsize=24)
# plt.ylim(0,1)
plt.title('復購率的變化',fontsize=24)
- 說明:圖上可以看出復購率在早期,因為大量新用戶加入的關系,新客的復購率并不高,如1月新客們的復購率只有6%左右。而在后期,這時的用戶都是大浪淘沙剩下的老客,復購率比較穩定,在20%左右。單看新客和老客,復購率有三倍左右的差距。
8.3 回購率
回購率:是某一個時間窗口內消費的用戶,在下一個時間窗口仍舊消費的占比。比如,我1月消費用戶1000,他們中有300個2月依然消費,回購率是30%。
#回購率
#每個用戶每個月平均消費金額
pivoted_money=df.pivot_table(index='用戶ID',columns='月份',values='訂單金額',
aggfunc='mean').fillna(0)
columns_month=df.月份.sort_values().astype('str').unique()
pivoted_money.columns=columns_month
pivoted_money.head()
#將有消費的記為1,沒有消費的記為0
pivoted_purchase=pivoted_money.applymap(lambda x:1 if x>0 else 0)
pivoted_purchase.head()
#如果本月進行消費,下月也進行消費,則記為1;如果下月沒有消費,則記為0,若本月沒有記為消費,則記為nan
def purchase_return(data):
status=[]
for i in range(17):#循環17個月
if data[i]==1:#若本月消費
if data[i+1]==1:#下個月也消費
status.append(1)#就記為1
if data[i+1]==0:#下個月不消費,就記為0
status.append(0)
else:
status.append(np.nan)
status.append(np.nan)
return pd.Series(status, index=columns_month)
pivoted_purchase_return=pivoted_purchase.apply(purchase_return,axis=1)#axis=1表示計算方向在行的方向上,左右運算
pivoted_purchase_return.head()
df_purchase = (pivoted_purchase_return.sum() / pivoted_purchase_return.count()).reset_index()
df_purchase.columns = ['Date', 'PurchaseRate']
df_purchase['Date'] = df_purchase.Date.astype(str).apply(lambda x:x[:-3])
plt.figure(figsize = (15,5))
plt.plot(df_purchase.Date, df_purchase.PurchaseRate)
plt.xlabel('時間', fontsize=24)
plt.ylabel('回購率', fontsize=24)
plt.title('回購率的變化', fontsize=24);
- 上圖可以看出,在初期用戶的回購率并不高,1月的回購率只有15%左右,4月份起回購率穩定在30%左右。
從每月有回購消費的用戶數數據可以看出,回購用戶數整體有下降趨勢。 - 對回購率的分析,再次說明了對于新用戶,在其第一次消費后的三個月內是一段重要的時期,需要營銷策略積極引導其再次消費及持續消費。
- 另外,對于有持續消費的老客,也要適時推出反饋老客戶的優惠活動,以加強老客的忠誠度。
8.4 分析留存率(3,7,15,30,90,365天為周期)
留存率:它指用戶在第一次消費后,有多少比率進行第二次消費。
消費日期 - 第一次消費日期 = 第二次消費與第一次消費的時間間隔 ,再將天數轉化為數值
#分析留存率
#新建一個對象,并增加用戶第一次消費時間的列,merge將兩個dataframe合并
data_t=df[['用戶ID','購買日期','訂單數','訂單金額']]
user_purchase_retention=pd.merge(left=data_t,right=orderdt_min.reset_index(),
how='inner',on='用戶ID',suffixes=('','_min'))
user_purchase_retention.head(5)
增加一列,表示訂單日期與用戶首次消費日期間的間隔時間
#每一次消費時間與第一次消費時間間隔
user_purchase_retention['order_date_diff']=user_purchase_retention['購買日期']-user_purchase_retention['購買日期_min']
#將timedelta轉換為數值型
user_purchase_retention['date_diff']=user_purchase_retention.order_date_diff.apply(lambda x:x/np.timedelta64(1,'D'))
user_purchase_retention.head(5)
將時間差值分桶處理:
分成0~3天內,3~7天內,7~15天……代表用戶當前消費時間距第一次消費屬于哪個時間段
#將時間間隔分桶(0-3)(3-7)等
bin=[0,3,7,15,30,60,90,180,365]
user_purchase_retention['date_diff_bin']=pd.cut(user_purchase_retention.date_diff,bins=bin)
user_purchase_retention.head(10)
這里date_diff=0并沒有被劃分入0~3天,因為計算的是留存率,如果用戶僅消費了一次,留存率應該是0。另外,如果用戶第一天內消費了多次,但是往后沒有消費,也算作留存率0。
pivot_table數據透視,Pandas函數pivot_table會默認刪除含有空值的行,用dropna=False保持NaN的值。
#用戶第一次消費之后,后續各時間段的消費總額
pivoted_retention=user_purchase_retention.pivot_table(index='用戶ID',
columns='date_diff_bin',values='訂單金額',aggfunc=sum,dropna=False)
pivoted_retention.head()
獲得的結果是用戶在第一次消費之后,在后續各時間段內的消費總額:
pivoted_retention.mean()#各時間段的平均消費額
- 雖然后面時間段的金額高,但是它的時間范圍也寬廣。從平均效果看,用戶第一次消費后的0~3天內,更可能消費更多。
依舊將數據轉換成是否,1代表在該時間段內有后續消費,0代表沒有:
#1代表有消費,0代表沒有
pivoted_retention_trans=pivoted_retention.applymap(lambda x:1 if x>0 else 0)
pivoted_retention_trans
#每筆訂單離第一筆訂單的時間間隔
(pivoted_retention_trans.sum()/pivoted_retention_trans.count()).plot.bar(figsize=(10,5))
plt.xlabel('消費時間間隔')
plt.title('留存率')
- 只有2.5%的用戶在第一次消費的次日至3天內有過消費,3%的用戶在3~7天內有過消費。數字并不好看,CD購買確實不是高頻消費行為。有20%的用戶在第一次消費后的三個月到半年之間有過購買,27%的用戶在半年后至1年內有過購買。
- 從運營角度看,CD機營銷在服務新用戶的同時,應該注重用戶忠誠度的培養,放長線掉大魚,在一定時間內召回用戶購買。
8.5 大客戶的貢獻率
因為消費行為有明顯的二八傾向,想知道高質量用戶為消費貢獻了多少份額?
8.5.1 用戶銷售額貢獻情況:
按照用戶id分組,對用戶的消費金額進行累計求和 ,然后與總銷售額比,得到比率,橫坐標是用戶的id。
#先將用戶消費金額按升序排列,逐行計算用戶累計金額,最后一行是總消費金額
user_money=df.groupby('用戶ID').訂單金額.sum().sort_values().reset_index()
user_money['money_cumsum']=user_money.訂單金額.cumsum()
money_total=user_money.money_cumsum.max()
#轉行成百分比
user_money['prop']=user_money.apply(lambda x:x.money_cumsum/money_total,axis=1)#apply用在每個行上
user_money.tail()
user_money.prop.plot()
plt.xlabel('用戶ID', fontsize=24)
plt.ylabel('比率', fontsize=24)
plt.title('用戶累計銷售額貢獻比', fontsize=24);
- 說明:前20000個用戶,大約80%的用戶貢獻了40%的銷售額,20%的用戶貢獻了60%的銷售額
8.5.2 用戶銷量貢獻情況:
#先將用戶銷量按升序排列,逐行計算用戶累計銷量,最后一行是總銷量
user_productsSum=df.groupby('用戶ID').訂單數.sum().sort_values().reset_index()
user_productsSum['products_cumsum']=user_productsSum.訂單數.cumsum()
productsSum_total=user_productsSum.products_cumsum.max()
#轉行成百分比
user_productsSum['prop']=user_productsSum.apply(lambda x:x.products_cumsum/productsSum_total,axis=1)#apply用在每個行上
user_productsSum.tail()
user_productsSum.prop.plot()
plt.xlabel('用戶ID', fontsize=24)
plt.ylabel('比率', fontsize=24)
plt.title('用戶累計銷量貢獻比', fontsize=24);
說明:跟銷售額十分接近。
- 前20000名用戶貢獻了40%的消費,而后3500名用戶貢獻了60%的消費。符合二八趨勢。也就是說我們只要維護了這3500個用戶就可以把業績KPI完成60%,如果能把3500個用戶運營的更好就可以占比70%—80%之間。
九.結論
- 1.整體趨勢:按年的月份趨勢銷量和銷售額在1-3月份相對極高,然后驟降,原因可能跟這段時間的大力促銷或與商品的季度屬性有關。
- 2.用戶個體特征:每筆訂單的金額和商品購買量都集中在區間的低段水平,都是小金額小批量進行購買,此類交易群體,可在豐富產品線和增加促銷活動提高轉換率和購買率。
- 3.大部分用戶的消費總額和購買總量都集中剛在低段,長尾分布,這個跟用戶需求有關,可以對商品進行多元文化價值的賦予,增強其社交價值屬性,提高用戶的價值需求。
- 4.用戶的消費周期:有二次以上消費的用戶,平均68天,所以在50天到60天期間,應該對這批用戶進行刺激召回,細致點,比如10天回復滿意度,30天發放優惠券,55天的時候提醒優惠券的使用。
- 5.用戶的生命周期:有二次及以上消費的用戶的平均生命周期是276天。用戶的生命周期分別在20天內與400至500天間,應該在20天內對客戶進行引導,促進其再次消費并形成消費習慣,延長其生命周期;在100至400天的用戶,也要根據其特點推出有針對性的營銷活動,引導其持續消費。
- 6..新客戶的復購率約為6%,老客戶的復購率在20%左右;新客戶的回購率在15%左右,老客戶的回購率在30%左右,需要營銷策略積極引導其再次消費及持續消費。
- 7.用戶質量:用戶個體消費有一定規律性,大部分用戶的消費集中在2000以下,用戶消費反應了2/8法則,消費排名前20%的用戶貢獻了80%的消費額。所以說,狠抓高質量用戶是萬古不變的道理,這些高質量客戶都是“會員”類型,需要專門為會員優化購物體驗,比如專線接聽、特殊優惠等等。
7.留存率來看,一半的用戶會流失,所以應該注重對用戶的忠誠度的培養,比如打卡簽到,積分制度,老用戶打折制度會員升級制度。