用戶消費行為分析


數據源於CDNOW網站的用戶購買記錄,通過以下字段利用python對CD銷售數據分析

分析需要基於業務,首先需要對數據進行了解

數據字段包括

  • user_id 用戶ID
  • order_dt :購買日期
  • order_products : 購買的產品數量
  • order_amount : 購買金額

      數據:點我獲取數據       提取碼 : h2s4

分析思路:

0、數據預處理

1、數據按月分析

2、用戶個體消費分析

3、用戶消費分析

4、復購率、回購率分析

 

0、數據預處理

導入常用的庫

import pandas as pd import numpy as np import matplotlib.pyplot as plt %matplotlib inline import seaborn as sns plt.rcParams['font.sans-serif']=['SimHei'] #用來正常顯示中文標簽
plt.rcParams['axes.unicode_minus']=False #用來正常顯示負號

導入數據,設置相應的字段

columns = ['user_id','order_dt','order_products','order_amount'] data = pd.read_table('D://CDNOW_master.txt',names=columns,sep='\s+') # 查看數據
data.head() # 數據字段 

# user_id 用戶ID # order_dt: 購買日期 # order_products: 購買產品數 # order_amount: 購買金額

 

  數據的大概格式

# 大概格式了解
data.info()

 

數據中沒有缺失值,order_dt列數據類型是int,需要進一步轉換成datetime類型

 

 

data['order_dt'] = pd.to_datetime(data.order_dt,format='%Y%m%d') # 新增一列月份 (對月進行分析) values(數組形式) 因為很多是進行月份的一個處理
data['month'] = data.order_dt.values.astype('datetime64[M]')

 

修改完數據格式后查看order_dt列的格式

# describe是描述統計
data.describe()

  • 觀察數據,用戶平均訂單數量為2.4個商品,標准差為2.3,略有波動,中位數書為2個商品,說明絕大部分訂單的購買量不多,最大值為99,有一定的極值干擾
  • 用戶消費額均值為35元左右,中位數25元,最大金額達到了1286元,有一定極值干擾

1、按月進數據分析

每月的消費總金額

每月的消費次數

每月的購買產品總數

每月的消費用戶數 

 

# 按月分組
grouped_month = data.groupby('month') fig = plt.figure(figsize = (8,12)) ax1 = fig.add_subplot(4,1,1) ax2 = fig.add_subplot(4,1,2) ax3 = fig.add_subplot(4,1,3) ax4 = fig.add_subplot(4,1,4) # 按月金額數
ax1.plot(grouped_month.order_amount.sum(),c='blue') ax1.set_title('每月消費總金額變化趨勢') # 按月的訂單數
ax2.plot(grouped_month.user_id.count(),c='blue') ax2.set_title('每月訂單數變化趨勢') # 按月產品數
ax3.plot(grouped_month.order_products.sum(),c='blue') ax3.set_title('每月消費產品購買量') # 每月用戶人數 這里需要去重,有些用戶重復購買
ax4.plot(grouped_month.user_id.apply(lambda x:len(x.drop_duplicates())),c='blue') # drop_duplicates去重功能
ax4.set_title('每月用戶數變化趨勢')

 

按月進行統計,下面通過折線圖分別查看數據變化趨勢

圖一:消費總金額在前三個月達最高峰,或許消費金額較為平穩,有輕微下降趨勢

圖二:前三個月訂單數在10000筆左右,后續月份的訂單數在2500左右

圖三:產品購買數量  呈現早期購買量多  后期下降趨勢

圖四:每月消費人數小小於每月的消費次數(訂單數),但是區別不大,前三個月每月的消費人數在8000-10000之間,后續月份平均2000左右,一樣是前期消費人數多,后期平穩下降趨勢

出現這種狀況,假設問題是出現在用戶身上,早期時間段的用戶有異常值,或者由於各類促銷營銷,由於只有消費數據,無法進一步進行判斷

 

數據透視查看,按月根據用戶購買金額,訂單數,用戶人數

data.pivot_table(index='month', values = ['order_products','order_amount','user_id'], aggfunc = {'order_products':'sum', 'order_amount':'sum', 'user_id':'count'})

2、用戶個體分析

  • 用戶消費金額,消費次數描述統計
  • 用戶消費金額和消費次數的散點圖
  • 用戶消費金額的分布圖
  • 用戶消費次數的分布圖
  • 用戶累積消費金額占比(百分之多少的用戶占了百分之多少的消費額)

根據用戶維度進行分析

#01-用戶消費金額和消費次數的描述統計
grouped_user = data.groupby('user_id') grouped_user.sum().describe()

  • 用戶平均購買量7張CD,標准差17,波動比較大,但是中位值只有3,說明小部分用戶購買了大量的CD
  • 用戶平均消費為106元,中位值為43,也有極值干擾
  • 消費的話一般都會符合二八法則
#02 - 用戶消費金額和消費次數散點圖 # 設置排除一些極值的干擾進行觀察 # query 用於數據框選列
grouped_user.sum().query('order_amount < 4000').plot.scatter(x='order_amount',y='order_products')

  • 繪制散點圖,由於產品比較單一,購買金額和產品數呈線性關系
03-用戶消費金額的分布圖(二八法則) grouped_user.sum().order_amount.plot.hist(bins=20) # bins=20,就是分成20塊,最高金額是14000,每個項就是700

  • 由直方圖可知,用戶消費金額,大部分消費金額能力確實不高,絕大部分呈幾種在很低的消費檔次,高消費用戶在圖中基本看不到,這也符合消費行為的行業規律
  • 小部分異常值干擾判斷,可以過濾操作排除異常
#04-用戶消費次數分布圖
grouped_user.sum().query('order_products<92').order_products.hist(bins = 40)

05 -用戶累計消費金額占比 user_cumsum = grouped_user.sum().sort_values('order_amount').apply(lambda x: x.cumsum() / x.sum()) user_cumsum.reset_index().order_amount.plot()

  • 通過觀察,50%的用戶僅僅貢獻了15%的消費額度,而排名前五千用戶就貢獻了%60的消費額
print(user_cumsum.head(8)) print(user_cumsum.tail(8))

  • 上面是一些累積占比的數據,數據中存在金額為0,可能是一些活動贈送等原因

3.用戶消費行為分析

  • 用戶第一次消費(首購)
  • 用戶最后一次消費
  • 新老客戶消費比
    • 多少用戶僅僅消費了一次
    • 每月新客占比
  • 用戶分層
    • RFM
    • 新、老、活躍、回流、流失/不活躍
  • 用戶購買周期(按訂單)
    • 用戶消費周期描述
    • 用戶消費周期分布
  • 用戶生命周期(按第一次 & 最后一次消費)
    • 用戶生命周期描述
    • 用戶生命周期分布
#01-第一次購買時間分布 # min() 時間最小,第一次購買
grouped_user.min().order_dt.value_counts().plot() # 2月發生較大下跌 渠道發生變化,或者其他 可以做一些假設

  • 用戶第一次購買分布,集中在前三個月,其中2月11日至2月25日有一次劇烈波動
# 02-最后一次購買時間分布
grouped_user.order_dt.max().value_counts().plot() # value_counts計算有哪些不同值,並計算每個值有多少個重復值

 

  • 用戶最后一次購買的分布比第一次購買分布廣
  • 大部分最后一次購買在前三個月,說明很多用戶購買一次后就不再進行購買
  • 隨着時間遞增,最后一次購買數在遞增,消費呈線性流失上升的情況
# 03-用戶第一次購買與最后一次購買 新老客的消費比
user_life =grouped_user.order_dt.agg(['min','max']) user_life.head()

(user_life['min'] == user_life['max']).value_counts()

True 第一次購買時間和最后一次購買時間一樣,有一半用戶只消費了一次

rate = (user_life['min'] == user_life['max']).value_counts() # 定義餅圖的標簽,標簽是列表,每個標簽多大會自動去算
labels = ['只消費一次用戶','多次消費用戶'] plt.axis('equal') # 設置x,y軸刻度一致,這樣才會是圓的
plt.pie(rate,explode=(0,0.15),labels=labels,autopct='%2.1f%%',startangle=90,colors=['r','orange'],radius=1.5) # autopct,圓里面的文本格式,%2.1f%%代表整數有兩位,小數有一位 #startangle,起始角度,0,表示從0開始逆時針轉,為第一塊。一般選擇從90度開始比較好看

# 04-用戶分層 # RFM 消費額 次數 最近一次消費 進行透視
rfm = data.pivot_table(index = 'user_id', values = ['order_products','order_amount','order_dt'], aggfunc = {'order_dt':'max', 'order_amount':'sum', 'order_products':'sum'}) rfm.head()

# 表示離最近一次消費的時間間隔
-(rfm.order_dt - rfm.order_dt.max()).head() # 數值越大,離現在的時間越長

# /np.timedelta64(1,'D') 除以1天的事件,消除單位 進行重命名
rfm['R'] = -(rfm.order_dt - rfm.order_dt.max()) / np.timedelta64(1,'D') rfm.rename(columns = {'order_products':'F','order_amount':'M'},inplace=True) rfm.head()

rfm[['R','F','M']].apply(lambda x:x-x.mean()).head()

  

數據解讀: 負數是小於的   正式大於的   

R:離最近一次購買的天數   F:產品數(消費次數) M:消費金額   與均值的對比

def rfm_func(x): level = x.apply(lambda x:'1' if x>= 0 else '0') #   字符串拼接 #   111,R>0,是距離平均消費時間要久,R越大 說明沒有消費時間越久 ,F >0 M>0,消費次數和金額也是較高的,重要價值客戶,依次類推
    label = level.R + level.F + level.M d = { '111':'重要價值客戶', '011':'重要保持客戶', '101':'重要挽留客戶', '001':'重要發展客戶', '110':'一般價值客戶', '010':'一般保持客戶', '100':'一般挽留客戶', '000':'一般發展客戶' } result = d[label] return result # x - x.mean() (具體真實情況可以修改,不一定需要用均值) 切比雪夫也可以 > 200 極值人工處理掉
rfm['label'] = rfm[['R','F','M']].apply(lambda x:x-x.mean()).apply(rfm_func,axis=1) rfm.head()

數據解讀: 1  時間比較長,只消費了一次,消費金額低   一般挽留客戶 

rfm.groupby('label').sum()

重要保持客戶貢獻了159萬左右  等等

rfm.groupby('label').count()

# 各類類型用戶占比
use_c = rfm.groupby('label').count() plt.axis('equal') labels = ['一般價值客戶','一般保持客戶','一般發展客戶','一般挽留客戶','重要價值客戶','重要保持客戶','重要發展客戶','重要挽留客戶'] plt.pie(use_c['M'], autopct='%3.1f%%', labels = labels, pctdistance=0.9, # 百分比占比距離圓心的位置0.9半徑
       labeldistance = 1.2, # 標簽離圓心的位置1.2半徑
       radius=3, startangle = 15)

# 對應標簽,使用不同顏色表示 # 綠色為重要價值客戶,紅色為非重要價值用戶
rfm.loc[rfm.label == '重要價值客戶','color'] = 'g' rfm.loc[~(rfm.label == '重要價值客戶'),'color'] = 'r' rfm.plot.scatter('F','R',c=rfm.color)

rfm.head() # rfm 象限法

rfm.groupby('label').sum()

從RFM分層可知,大部分用戶為一般挽留客戶,但是這是由於極值的影響,所以RFM的划分應該以業務為主

  • 盡量用小部分的用戶覆蓋大部分的額度
  • 不要為了數據好看划分等級
  • 極值會拉均值
  • 根據數據可以和業務相結合,如何提升一些重要的指標
# 06-用戶生命周期
pivoted_counts = data.pivot_table(index = 'user_id', columns = 'month', values = 'order_dt', aggfunc = 'count').fillna(0) # pivoted_counts.head()
pivoted_counts.head() # 按月份進行對比,1月份哪些是購買的,再去對比二月份哪些是購買的

消費過的為1 ,沒消費過的為0 data_purchase = pivoted_counts.applymap(lambda x: 1 if x > 0 else 0) data_purchase.tail() # 透視會補上 第一次從3月分開始購買 前面補成0 , 需要進行判,第一次消費作為生命周期的起始 # se.columns.values

 

def active_status(data): status = [] for i in range(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') #   這里需要對返回的值進行轉換,將列表轉為Series
    return pd.Series(status, index = pivoted_counts.columns)
  • 若本月沒有消費
    • 若之前是未注冊,則依舊未注冊
    • 若之前有消費,則為流失/不活躍
    • 其他情況,為未注冊
  • 若本月有消費
    • 若是第一次消費,則為新用戶
    • 如果之前有過消費,則上個月為不活躍,則為回流
    • 如果上個月為未注冊,則為新用戶
    • 除此之外,為活躍
purchase_stats = data_purchase.apply(active_status,axis=1,result_type ='expand') # df.rename(columns={ df.columns[2]: "new name" }, inplace=True) # purchase_stats.rename(columns={purchase_stats.columns:data_purchase.columns})
purchase_stats.head()

purchase_status_ct = purchase_stats.replace('unreg',np.NaN).apply(lambda x : pd.value_counts(x)) purchase_status_ct # 未注冊不希望參與處理 設置我空值

數據解讀: 一月份有7846個用戶   然后2月份分叉為不活躍用戶 和 活躍用戶    有8476個新用戶 等等

 新用戶轉換為是否活躍等等 流失用戶在增加

# 各個狀態的占比 
purchase_status_ct.fillna(0).T.apply(lambda x:x/x.sum(),axis=1) purchase_status_ct.fillna(0).T.plot.area()

 

由上表可知,每月的用戶消費轉變

活躍用戶,持續消費的用戶,對應的是消費質量

回流用戶,之前是不消費的本月才消費,采取喚回運營

不活躍用戶,對應的是流失

用戶購買周期 data.order_dt.head(10)
# 把所有的數據進行一個錯位 
data.order_dt.shift().head(10)

 

# 一個用戶可能多個訂單 每個訂單的間隔 
order_diff = grouped_user.apply(lambda x:x.order_dt - x.order_dt.shift()) order_diff.head(10)

數據解讀:ID為2     0天當天購買兩次或以上,間隔為0     

     ID為3的用戶          3-4間隔了87天   

NaT表示一個訂單

order_diff.describe()

每個用戶的平均訂單是68天  中位值31天 最大值533天

# 去除單位 間隔天數分布圖
(order_diff / np.timedelta64(1,'D')).hist(bins=20)

(user_life['max'] - user_life['min']).describe() # 整體的生命周期

((user_life['max'] - user_life['min']) / np.timedelta64(1,'D')).hist(bins = 40)

  • 用戶的生命周期受只購買一次的用戶影響比較厲害 (可以進行排除 當特殊情況,想提取出購買一次以上的用戶)
  • 用戶均消費134天,中位數僅為0
  • u_l = ((user_life['max'] - user_life['min']).reset_index()[0] / np.timedelta64(1,'D')) u_l[u_l > 0].hist(bins=40)

  • 左邊比較高,還是有些用戶的生命周期是比較短的,例如10、20天等
  • 有不少用戶生命周期也是比較穩定

 

4.復購率和回購率分析

  • 復購率
    • 自然月內,購買多次的用戶占比
  • 回購率
    • 曾今購買過的用戶在某一時期內的再次購買占比
pivoted_counts.head()

# 購買大於1次的 賦值為1 ,然后小於等於1 的 如果是購買次數是0,則賦值為空,否則 就是購買一次,賦值為0
purchase_r = pivoted_counts.applymap(lambda x: 1 if x > 1 else np.NaN if x == 0 else 0) purchase_r.head() 

# sum() 0 不計數,count() 0計數
(purchase_r.sum() / purchase_r.count()).plot(figsize = (10,4))

  • 復購率穩定在20% 左右,前三個月因為有大量新用戶涌入,而這些用戶只購買了一次,所以導致復購率較低
# 回購率 只需要0 1 代表
data_purchase.head()

def purchase_back(data): status = [] for i in range(17): if data[i] == 1: # 本月進行過消費
            if data[i+1] == 1: # 下一月是否進行消費
                status.append(1) #消費為1 回購了
            if data[i+1] == 0: status.append(0) # 未消費則為0 沒有回購
        else: status.append(np.NaN) # 之前沒消費則不計
    status.append(np.NaN) # 最后一個月沒有判斷需要補上
    return pd.Series(status,data_purchase.columns) purchase_b = data_purchase.apply(purchase_back, axis =1) purchase_b.head(5)

  • 0 表示上個月購買了,下個月沒有進行消費,則是沒有回購 ,
  • 1代表當月消費過次月依舊消費,表示回購了
  • NAN表示當月沒有消費(不進行計算)
# sum() 0 1進行求和,表示次月消費過的
(purchase_b.sum() / purchase_b.count()).plot(figsize = (10, 4))

  •  回購率在30%左右波動,比復購率要高,綜合分析得出,新客整體質量低於老客,老客忠誠度(回購率)表現較好,消費頻次稍次,這個是是CDNow網站的用戶消費特征


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM