CD網站用戶行為分析項目

閱讀路線:
  • 項目背景
  • 項目目的
  • 數據來源
  • 代碼展示
一、項目背景

公司于1994年2月由雙胞胎兄弟杰森汀和馬修汀共同創立。公司在1994年8月推出telnet服務。公司在1994年9月成為一家零售CD網站。

二、項目目的:

利用python對銷售數據進行分析,根據復購率、回購率、高額消費用戶等指標及模型,獲取高價值客戶,從而進行有針對性的客戶管理和維護。

三、數據來源

數據源于CDNow網站的用戶購買明細
(數據:https://pan.baidu.com/s/1Mr1VyfgTOUyraKe_6z0Orw)

四、代碼展示

(1)基本描述

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline
plt.style.use('ggplot')
columns = ['user_id', 'order_dt', 'order_products', 'order_amount']
# 命名列名為用戶id, 購買日期, 購買數量, 購買金額
df = pd.read_table('CDNOW_master.txt', names = columns, sep='\s+')
df.head()
# 簡單看下數據前五行
df.info()
# 觀察數據的屬性

可以觀察到無缺失值,同時也發現了日期沒有正確識別,等下我再處理。

df.describe()
#數據基本信息

可以觀察到大部分訂單只消費了少量少量商品2.4件。
同時可以看到,用戶的消費金額比較穩定,平均消費了35元,中位數為25元,最大值為1286元,明顯受到了極值干擾,有些右偏分布。

接著我來處理剛剛沒有正確識別的日期列,以及加一列新的月份,方便之后按月來分析。

df['order_dt'] = pd.to_datetime(df.order_dt, format='%Y%m%d')
df['month']=df.order_dt.values.astype('datetime64[M]')
df.head()

(2)按月進行用戶消費趨勢分析

grouped_month = df.groupby('month')
order_month_amount = grouped_month.order_amount.sum()
order_month_amount.head()
# 按月進行分組,并對消費金額進行求和
from matplotlib.font_manager import FontProperties
font = FontProperties(fname='/Users/quincy/Library/Fonts/simhei.ttf')
ax = order_month_amount.plot()
ax.set_xlabel('月份', fontproperties=font)
ax.set_ylabel('消費金額', fontproperties=font)
ax.set_title('不同月份的用戶消費金額', fontproperties = font)
plt.show()

消費金額在前三個月逐步達到頂峰,后續消費額較為穩定,有下降趨勢。

ax = grouped_month.user_id.count().plot()
ax.set_xlabel('月份', fontproperties = font)
ax.set_ylabel('訂單數' , fontproperties=font)
ax.set_title('不同月份的訂單數', fontproperties=font)
plt.show()

前三個月消費訂單數在10000筆左右,后續月份平均消費訂單數在2500筆左右。

由圖片可知,無論是消費金額或者訂單數都呈現大致相同的趨勢,前三個月高,后續月份降低且趨于穩定。由于無法確定源數據從何而來,只能暫且假定前三個月有促銷活動。

(3)用戶個體消費行為分析

#以用戶id為分組聚集
grouped_user = df.groupby('user_id')
grouped_user.sum().describe()

用戶平均購買了7張cd, 但是中位數只有3,標準差較大波動較大,說明小部分用戶買了大量cd,拉高了平均值
用戶平均消費106元,中位數只有43,同樣有極值干擾

ax = grouped_user.sum().query('order_amount <= 4000').plot.scatter(x='order_amount', y='order_products')
ax.set_xlabel('消費金額',font_properties = font)
ax.set_ylabel('CD碟數(張)', font_properties = font)
ax.set_title('單個用戶消費金額與購買個數的關系', font_properties=font)
plt.show()
ax = grouped_user.sum().order_amount.plot.hist(bins=50)
ax.set_xlabel('消費金額(美元)', font_properties = font)
ax.set_ylabel('用戶數(人)', font_properties = font)
ax.set_xlim(0,2000)
ax.set_title('用戶消費金額分布直方圖', font_properties = font)
plt.show()
ax = grouped_user.sum().order_products.plot.hist(bins=50)
ax.set_xlabel('CD碟數(張))', font_properties = font)
ax.set_ylabel('用戶數(人)', font_properties = font)
ax.set_xlim(0,150)
ax.set_title('用戶購買碟數分布直方圖', font_properties = font)
plt.show()

可以從直方圖觀察到,絕大部分呈現集中趨勢。大部分用戶消費能力不高。購買張數在20張以內,金額在250美金以內。

user_cumsum = grouped_user.sum().sort_values('order_amount').apply(lambda x: x.cumsum()/ x.sum())
ax = user_cumsum.reset_index().order_amount.plot()
ax.set_title('總消費占比', font_properties = font)
ax.set_xlabel('消費金額', font_properties = font)
ax.set_ylabel('比例', font_properties = font)
plt.show()

按用戶消費金額進行升序排列,50%的用戶只有15%的消費額度。排名前5000的用戶貢獻了60%的消費額。 只要維護好這前5000個用戶,就能效果很好。

(4) 復購率和回購率分析

#創建數據透視表,對每個用戶每個月訂單數統計
pivoted_counts = df.pivot_table(index='user_id',
                                columns='month', 
                                values='order_dt', 
                                aggfunc='count').fillna(0)
pivoted_counts.head()
# 把購買兩次及以上的轉化為1,購買1次為0,方便之后分析
purchase_r = pivoted_counts.applymap(lambda x: 1 if x>1 else np.NaN if x==0 else 0)
purchase_r.head()

復購率:復購率的定義是在某時間窗口內消費兩次及以上的用戶在總消費用戶中占比。這里的時間窗口是月,如果一個用戶在同一天下了兩筆訂單,這里也將他算作復購用戶。

ax = (purchase_r.sum() / purchase_r.count()).plot(figsize=(10,4))
ax.set_xlabel('時間(月)', font_properties = font)
ax.set_ylabel('百分比(%)', font_properties = font)
ax.set_title('每月用戶復購率圖', font_properties = font)
plt.show()

由圖可知,前三個月由于大量新客戶涌入,新用戶只購買了一次,導致復購率較低。三個月后,復購率趨于穩定,在20%左右。

回購率:回購率是某一個時間窗口內消費的用戶,在下一個時間窗口仍舊消費的占比。

#回購率只需考慮一段時間內是否購買過,所以購買過轉化為1,無則為0
df_purchase = pivoted_counts.applymap(lambda x:1 if x>0 else 0)
df_purchase.head()
#定義函數,每個月都要跟后面一個月對比下,本月有消費且下月也有消費,則本月記為1,下月沒有消費則為0,本月沒有消費則為NaN,由于最后個月沒有下月數據,規定全為NaN
def purchase_back(data):
    status = []
    for i in range(17):
        if data[i] == 1:
            if data[i+1] ==1:
                status.append(1)
            if data[i+1] ==0:
                status.append(0)
        else:
            status.append(np.NaN)
    status.append(np.NaN)
    return pd.Series(status)
purchase_b  = df_purchase.apply(purchase_back, axis=1)
# 中間發現列名出現了問題,重新調整下列名
purchase_b.columns = df_purchase.columns
purchase_b.head()
ax = (purchase_b.sum() / purchase_b.count()).plot()
ax.set_xlabel('時間(月)', font_properties = font)
ax.set_ylabel('百分比(%)', font_properties = font)
ax.set_title('十八個月內用戶回購率圖', font_properties = font)
plt.show()

由圖可知,用戶的回購率大于復購率,約在30%左右上下波動,可能有營銷淡旺季導致。但這部分的回購用戶消費行為大致穩定,與之前的每月復購用戶有一定重合,屬于優質客戶。

(5) 用戶分層
我們按照用戶的消費行為,簡單劃分成幾個維度:未注冊用戶、新用戶、活躍用戶、不活躍用戶、回流用戶。
未注冊用戶(unreg)
新用戶(new):新用戶的定義是第一次消費的用戶。
活躍用戶(active):即連續兩個時間窗口都消費過的用戶。
不活躍用戶(unactive):不活躍用戶則是時間窗口內沒有消費過的活躍用戶,即一二月份都消費過,三月份沒消費過。
回流用戶(return):回流用戶是在上一個窗口中沒有消費,而在當前時間窗口內有過消費。

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')
    return pd.Series(status)
purchase_status = df_purchase.apply(active_status, axis=1)
purchase_status.head()
#去掉未注冊用戶unreg,統計下每個月不同層級用戶人數
purchase_status_ct = purchase_status.replace('unreg', np.NaN).apply(lambda x: pd.value_counts(x))
purchase_status_ct
#把數據轉置并把填充空值為0,看上去更為直觀
purchase_status_ct.fillna(0).T
ax = purchase_status_ct.fillna(0).T.plot.area(figsize = (12,6))
ax.set_xlabel('時間(月)', font_properties = font)
ax.set_ylabel('用戶數(人)', font_properties = font)
ax.set_title('每月各類用戶類型占比面積圖', font_properties = font)
ax.legend(loc='upper left')
plt.show()

由圖可知,黑色的不活躍用戶占據大部分,與我們圖表結果相符。紅色代表的活躍用戶非常穩定,屬于核心用戶。與紫色的回流用戶相加,大致是當月的消費用戶人數。

(6)用戶生命周期
定義第一次消費至最后一次消費為整個用戶生命。我們需要找出每個用戶的第一次消費和最后次消費

user_purchase = df[['user_id','order_products','order_amount','order_dt']]
order_date_min=user_purchase.groupby('user_id').order_dt.min()
order_date_max=user_purchase.groupby('user_id').order_dt.max()
life_time = (order_date_max-order_date_min).reset_index()
life_time.describe()

可以觀察到,用戶平均生命周期為134天,中位數為0。至少存在一般的用戶只消費過一次,也就是低質量的客戶。最大是544天,也就是數據集的總天數,說明從開始到最后都有消費意愿的高質量客戶。

#二次消費以上客戶的生命周期直方圖
life_time['life_time'] = life_time.order_dt/np.timedelta64(1,'D')
ax=life_time[life_time > 0].life_time.plot.hist(bins =100,figsize = (12,6))
ax.set_xlabel('天數(天)', font_properties = font)
ax.set_ylabel('人數(人)', font_properties = font)
ax.set_title('二次消費以上用戶的生命周期直方圖', font_properties = font)
plt.show()

由圖可觀察到直方圖呈雙峰結構,部分質量較差的客戶,雖然消費了兩次,但仍然無法持續。若想提高用戶轉化率,應該在首次消費30天內盡量去引導。少部分用戶集中在50-300天這個區間,屬于普通型的生命周期。高質量用戶的生命周期集中在400天以后,屬于高忠誠客戶,應盡量維護好這批客戶。

(7)平均購買周期

order_diff = grouped_user.apply(lambda x: x.order_dt - x.order_dt.shift())
order_diff.describe()
ax = (order_diff / np.timedelta64(1, 'D')).hist(bins=20)
ax.set_xlabel('時間跨度(天)', font_properties  = font) 
ax.set_ylabel('人數(人)', font_properties = font) 
ax.set_title('用戶平均購買周期直方圖', font_properties = font)
plt.show()

如圖,典型的長尾分布,大部分用戶的消費間隔確實比較短。不妨將時間召回點設為消費后立即贈送優惠券,消費后10天詢問用戶CD怎么樣,消費后30天提醒優惠券到期,消費后60天短信推送。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。