CDNow網(wǎng)站用戶消費行為分析

寫這本篇文章的目的是為了加深對數(shù)據(jù)分析的理解,文章以模仿為主,利用pandas,matplotlib進行數(shù)據(jù)處理和數(shù)據(jù)可視化分析假抄,數(shù)據(jù)來源和鯨社區(qū)分享的CDNow網(wǎng)站的用戶購買明細。一共有用戶ID丽猬,購買日期宿饱,購買數(shù)量,購買金額四個字段脚祟。

1.數(shù)據(jù)處理
2.用戶總體消費分析
3.用戶個體消費數(shù)據(jù)分析
4.用戶消費行為周期分析
5.用戶復購率與回購率

數(shù)據(jù)處理

導入數(shù)據(jù)

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from datetime import datetime
plt.style.use('ggplot')#使用自帶的風格進行美化

導入常用的庫

columns = ['user_id','order_dt','order_products','order_amount']
df = pd.read_table(r'C:\Users\m\Desktop\CDNOW_master.txt',names = columns,sep='\s+')
  • 加載包和數(shù)據(jù)谬以,文件是txt格式,用read_table打開由桌,因為源數(shù)據(jù)不包括表頭为黎,所以需要賦予表頭字段,字符串是空格分隔行您,用\s+表示匹配任意空白符铭乾。
  • 表頭字段分為用戶ID,購買日期娃循,訂單數(shù)炕檩,訂單金額來分析,基本上這四個字段就可以進行豐富的分析淮野。
#默認輸出前五行
df.head()
  • 觀察數(shù)據(jù)捧书,order_dt列表示時間吹泡,但只是一串年月日的數(shù)字骤星,后續(xù)需要數(shù)據(jù)類型轉(zhuǎn)換。
  • 數(shù)據(jù)中存在一個用戶同一天或不同天購買多次爆哑,如用戶ID為2在12號購買了兩次洞难,這個細節(jié)要特別留意。

描述性統(tǒng)計

#匯總各列統(tǒng)計信息
df.describe()

describe是描述統(tǒng)計揭朝,對用戶數(shù)據(jù)進行整體性判斷:

  1. 從描述信息中队贱,用戶每個訂單平均購買2.4個商品,每個訂單平均消費35元
  2. 購買商品的標準差為2.33潭袱,說明數(shù)據(jù)有一定的波動性柱嫌;中位數(shù)為2,75分位數(shù)為3,說明大部分訂單購買數(shù)量不多屯换。最大值為99编丘,購買量比較大与学。購買金額的情況差不多,75分位數(shù)為43嘉抓,大部分都集中在小額索守。

總體數(shù)據(jù)來看,大部分用戶都屬于小額抑片,也貢獻了收入的大頭卵佛,數(shù)據(jù)分布是呈長尾形態(tài),俗稱二八敞斋。

數(shù)據(jù)處理

df.info()

查看數(shù)據(jù)類型截汪、數(shù)據(jù)是否存在空值,原數(shù)據(jù)是很干凈的數(shù)據(jù)渺尘,沒有空值挫鸽。接下來進行時間數(shù)據(jù)類型轉(zhuǎn)換。

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

數(shù)據(jù)類型的轉(zhuǎn)換:

  • pd.to_datetime可以將數(shù)字轉(zhuǎn)換為時間類型鸥跟,format參數(shù)用于匹配丢郊。%Y匹配前四位數(shù)字1997,小寫y只匹配97医咨,%m匹配01枫匾,%d匹配01,返回結(jié)果為1997-01-01拟淮。
  • astype可以將時間類型進行轉(zhuǎn)換干茉,[M]轉(zhuǎn)換為月份,這里取月份窗口作為消費頻率很泊。

    小結(jié)

到該步驟角虫,我們通過描述性統(tǒng)計對數(shù)據(jù)有大概的了解,呈二八形態(tài)委造,也已經(jīng)將數(shù)據(jù)類型處理為合適的類型戳鹅,方便后續(xù)的分析。

用戶總體消費分析

按照月份維度來分析用戶總體消費趨勢

  • 每月的總銷售額
  • 每月的總銷量
  • 每月的消費人數(shù)
month_grouped = df.groupby('month')

按月份進行統(tǒng)計分組

month_grouped.order_amount.sum().plot()
plt.title('總銷售額')
plt.show()
  • 按月統(tǒng)計CD的銷量金額昏兆,從圖中可以知道枫虏,前三個月的銷量金額非常高。數(shù)據(jù)比較異常爬虱,而后期的銷量金額則很平穩(wěn)
month_grouped.order_dt.count().plot()
plt.title('消費次數(shù)')
plt.show()
  • 圖中可知前三個月的消費訂單數(shù)在10000~12000筆區(qū)間中隶债,訂單數(shù)非常高漲,后期平均維持在2500筆左右跑筝。
month_grouped.order_products.sum().plot()
plt.title('總銷量')
plt.show()
  • 和銷量金額一樣死讹,每月的產(chǎn)品銷量呈現(xiàn)早期銷量非常大,后期平穩(wěn)下降的趨勢曲梗。

三個折線圖的整體趨勢基本一致赞警,可以看出逛腿,前三個月的銷量特別高漲,而三月份之后驟然下降仅颇,而后趨于平穩(wěn)单默。為什么會出現(xiàn)驟然下降原因呢?第一假設用戶數(shù)據(jù)出現(xiàn)問題忘瓦,早期時間段的用戶中存在異常值搁廓。第二假設是各類促銷活動,但這里只有消費數(shù)據(jù)耕皮,所以無法判斷境蜕。

month_grouped.user_id.apply(lambda x:len(x.unique())).plot()
plt.title('消費人數(shù)')
plt.show()


另一方面,通過消費人數(shù)的折線圖看出在2月到3月消費人數(shù)稍有下降凌停,但總銷量與總銷量金額依然上升粱年,是不是說明3月份存在高價值的客戶。
小結(jié)

上面四個折線圖的整體趨勢一致罚拟,呈現(xiàn)二八形態(tài)台诗。通過消費人數(shù)分析了解到3月份存在高價值的客戶,也說明我們應該重點挖掘3月份中的用戶赐俗,重點發(fā)展高價值客戶拉队。

用戶個體消費數(shù)據(jù)分析

前面我們是按月份維度進行整體來看數(shù)據(jù)趨勢。接下來我們需要看個體消費能力如何阻逮,我們劃分了五個方向:

  1. 用戶消費金額粱快,消費次數(shù)的描述性統(tǒng)計
  2. 用戶消費金額,消費次數(shù)的散點圖
  3. 用戶消費金額的分布圖(二八法則)
  4. 用戶消費次數(shù)的分布圖
  5. 用戶累計消費金額的占比(百分之多少的用戶占了百分之多少的消費額)

用戶消費金額叔扼,消費次數(shù)的描述統(tǒng)計

用戶的描述性統(tǒng)計
group_user = df.groupby('user_id')
print(group_user.sum().describe())

從用戶角度來看事哭,每位用戶平均購買7張CD,購買量的最大值購買了1033張瓜富。用戶的平均消費金額是100元左右鳍咱,標準差為240。兩者結(jié)合分位數(shù)和最大值看食呻,平均數(shù)和75分位數(shù)接近流炕,存在小部分高消費用戶澎现,符合二八法則仅胞。

用戶消費金額和消費次數(shù)的散點圖

group_user.sum().plot.scatter(x='order_amount',y='order_products')
plt.title('用戶散點圖')
plt.show()
  • 從圖上看用戶比較健康而且規(guī)律性很強,整體符合CD網(wǎng)站商品單一的銷售數(shù)據(jù)剑辫,金額和商品呈線性干旧,沒幾個離散點。

用戶消費金額的分布圖(二八法則)

group_user.sum().order_amount.plot.hist(bins = 20)
plt.show()
  • 從圖中看用戶的消費呈集中趨勢妹蔽,可能是有個別的極大值干擾導致椎眯∧咏可以排除極大值再看看分布。
group_user.sum().query("order_amount <800").order_amount.plot.hist(bins = 20)
plt.show()
  • 從直方圖圖可知编整,絕大部分用戶呈現(xiàn)集中在低的消費檔次舔稀,將近半數(shù)的用戶消費金額不超過40元,高消費用戶(>200元)不超過2000人掌测,高消費在圖中幾乎看不到内贮,符合消費行為的行業(yè)規(guī)律。

用戶消費次數(shù)的分布圖(二八法則)

group_user.sum().query("order_products <100").order_products.plot.hist(bins = 40)
plt.show()
  • 大部分用戶購買CD的數(shù)量在7張內(nèi)汞斧,大量購買CD的用戶數(shù)量很低夜郁。

用戶累計消費金額的占比

前面的分析對用戶的消費行為有一個大概的了解,接下來分析用戶質(zhì)量粘勒。因為消費行為有明顯的二八傾向竞端,我們需要知道高質(zhì)量用戶為消費貢獻了多少份額。

user_amount = df.groupby('user_id').order_amount.sum().sort_values().reset_index()
user_amount['amount_cumsum'] = user_amount.order_amount.cumsum()
print(user_amount.tail())
  • 按用戶的消費金額升序庙睡,使用cumsum累加函數(shù)事富。逐行計算累計的金額,獲取最后的總消費金額為2500315乘陪。
amount_total = user_amount.amount_cumsum.max()
user_amount['prop'] = user_amount.apply(lambda x:x.amount_cumsum / amount_total,axis = 1)
print(user_amount.tail())

轉(zhuǎn)換用戶貢獻消費金額百分比

user_amount.prop.plot()
plt.xlabel('用戶數(shù)量')
plt.ylabel('用戶累計貢獻百分比')
plt.show()
  • 繪制趨勢圖赵颅,橫坐標是以貢獻金額大小排序的用戶,縱坐標則是用戶累計貢獻百分比暂刘。前面知道總體用戶為24000左右饺谬,圖中可以看到前20000個用戶貢獻40%,后面4000位用戶貢獻了60%谣拣,確實呈現(xiàn)二八傾向募寨。也就是說我們維護這4000個用戶就可以達到業(yè)績KPI完成60%。

小結(jié)

到此我們大概可以了解用戶個體消費呈現(xiàn)二八形態(tài)森缠,大部分用戶都屬于小金額用戶拔鹰,符合消費行業(yè)的行規(guī)律。通過用戶累計消費金額占比趨勢圖有大概4000個用戶貢獻了總體的60%贵涵,如果能把4000個用戶運營的更好就可以提高到占比70%左右列肢,更容易提高業(yè)績。

用戶消費行為周期分析

  • 用戶第一次消費(首購)
  • 用戶最后一次消費
  • 新老客戶消費比
  • 用戶生命周期
  • 用戶購買周期
  • 用戶復購率與回購率

新用戶第一次消費

group_user.month.min().value_counts()
  • 按用戶分組求月份的最小值宾茂,即用戶消費行為中的第一次消費時間瓷马。圖中可知所有用戶的第一次消費都集中在前三個月。

用戶最后一次消費

group_user.month.max().value_counts()
group_user.month.max().value_counts().plot()
plt.xlabel('月份')
plt.ylabel('最后一次消費人數(shù)')
plt.show()
  • 觀察用戶的最后一次消費時間跨晴。絕大部分數(shù)據(jù)依然集中在前三個月欧聘,后續(xù)的時間段內(nèi)有用戶消費,但增長緩慢遞增端盆,存在一定的用戶回購怀骤。
  • 前面提到的第一假設的異常趨勢得到解釋费封,但這只是部分用戶的訂單數(shù)據(jù),所以有一定局限性蒋伦。

新舊用戶消費比

user_new_old = group_user.order_date.agg(['min','max'])
new_old = (user_new_old['min'] == user_new_old['max']).value_counts()
print(new_old)
  • 按用戶分組弓摘,計算用戶第一消費和最后一次消費時間,如果新舊時間一致痕届,說明只消費了一次衣盾。統(tǒng)計數(shù)據(jù)可知有一半的用戶只消費一次。
plt.pie(x = new_old,
        labels=['僅消費一次','多次消費'],
        autopct= '%.1f%%',
        shadow= True,
        explode=[0.08,0],
        textprops={'fontsize':11})
plt.title('新老用戶消費比')
plt.show()
  • 繪制餅圖更直觀反映現(xiàn)象爷抓,超過一半用戶僅消費一次势决,這也說明留存用戶效果不好,營運效果不佳蓝撇。

用戶購買周期

order_diff = group_user.apply(lambda x:x['order_date']-x['order_date'].shift())
print(order_diff.head(10))
  • 每個用戶的每次購買時間間隔果复,用戶1只購買一次,所以為空值渤昌,用戶2的第一筆訂單與第二筆訂單在同一天購買的虽抄。
order_diff.describe()
  • 每個用戶的購買時間間隔平均是68天,間隔最長的是533天独柑。想要召回用戶迈窟,在60天左右的消費間隔也是比較好的。

消費周期分布

(order_diff/ np.timedelta64(1,'D')).hist(bins =20)
plt.show()
  • 數(shù)據(jù)呈指數(shù)分布忌栅,大部分用戶的消費周期確實比較短车酣,低于100天。

用戶生命周期

orderdate_min = group_user.order_date.min()
orderdate_max = group_user.order_date.max()
user_life = orderdate_max-orderdate_min
print(user_life.head())
(orderdt_max-orderdt_min).describe()
  • 所有的用戶平均生命周期有134天索绪,中位數(shù)為0天也就是說有一半用戶的生命周期只購買了一次湖员。接下來看一下分布情況。
((orderdate_max-orderdate_min)/np.timedelta64(1,'D')).hist(bins=15)
  • 有一半的用戶只消費一次瑞驱,所以生命周期的大頭都集中在0天娘摔。
  • 不妨將只消費了一次的新客排除,來計算所有消費過兩次以上的老客的生命周期唤反。
life_time = (orderdate_max - orderdate_min).reset_index()
print(life_time.head())
life_time['life_time'] = life_time.order_date / np.timedelta64(1,'D')
life_time[life_time.life_time > 0].life_time.hist(bins = 100)
plt.show()
  • 這是雙峰趨勢圖凳寺。20天內(nèi)生命周期的用戶是一個高峰,但無法持續(xù)彤侍,在用戶首次消費30天內(nèi)應該盡量引導肠缨,延長其生命周期。少部分用戶集中在50天~300天拥刻,屬于普通型的生命周期怜瞒。高質(zhì)量用戶的生命周期父泳,集中在400天以后般哼,這已經(jīng)屬于忠誠用戶了吴汪。
用戶復購率與回購率

復購率

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

pivoted_df = df.pivot_table(index= 'user_id',
                            columns='month',
                            values='order_date',
                            aggfunc='count').fillna(0)
print(pivoted_df.head())
  • 每個用戶在每月的訂單數(shù),其中這里沒有消費過的標記0楞卡。
pivoted_df_tranf = pivoted_df.applymap(lambda x: 1 if x>1 else np.nan if x ==0 else 0 )

  • 數(shù)據(jù)轉(zhuǎn)換一下霜运,消費2次以上記為1,消費1次記為0蒋腮,消費0次記為NAN
(pivoted_df_tranf.sum() / pivoted_df_tranf.count()).plot(figsize = (10,4))
plt.show()
  • 這里用sum和count相除即可計算出復購率淘捡。因為這兩個函數(shù)都會忽略NaN,而NaN是沒有消費的用戶池摧。count計算的是總的消費用戶數(shù)焦除,sum計算了兩次以上的消費用戶。
  • 圖上可以看到早期的復購率并不高作彤,是因為早期大量新用戶加入膘魄,如一月份的復購率只有6%左右。而到后期竭讳,這是的復購率就相對穩(wěn)定创葡,在20%左右。
  • 單看新客和老客绢慢,復購率有三倍左右的差距灿渴。

回購率
接下來計算回購率,回購率是某一個時間窗口內(nèi)消費的用戶胰舆,在下一個時間窗口人就消費的占比逻杖。

pivoted_amount = df.pivot_table(index = 'user_id',
                                columns = 'month',
                                values = 'order_amount',
                                aggfunc = 'mean').fillna(0)
columns_month = df.month.sort_values().astype('str').unique()
pivoted_amount.columns = columns_month
print(pivoted_amount.head())
  • 這里利用每個用戶每個月平均消費金額作為練習。
pivoted_purchase = pivoted_amount.applymap(lambda x:1 if x>1 else 0)
print(pivoted_purchase.head())
  • 再次轉(zhuǎn)換數(shù)據(jù)思瘟,只要有過購買荸百,記為1,反之為0滨攻。
def purchase_return(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,index=columns_month)
pivoted_purchase_return = pivoted_purchase.apply(purchase_return,axis=1)
print(pivoted_purchase_return.head())
  • 創(chuàng)建一個判斷函數(shù)够话。data是輸入的數(shù)據(jù),status是空列表光绕,用來保存用戶是否回購的字段女嘲。
  • 判斷邏輯:如果用戶本月進行過消費,且下月消費過诞帐,記為1欣尼,沒有消費過是0。本月若沒有進行過消費,為NaN愕鼓,后續(xù)的統(tǒng)計中進行排除钙态。
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.show()
  • 上圖可以看出聪蘸,在初期用戶的回購率并不高形娇,1月的回購率只有15%左右,4月份起回購率穩(wěn)定在30%左右商源,波動性也較強磺送。
  • 對回購率的分析驻子,再次說明了對于新用戶,在其第一次消費后的三個月內(nèi)是一段重要的時期估灿,需要營銷策略積極引導其再次消費及持續(xù)消費崇呵。
  • 另外,對于有持續(xù)消費的老客馅袁,也要適時推出反饋老客戶的優(yōu)惠活動演熟,以加強老客的忠誠度。

小結(jié)
到此用戶消費行為周期分析已完成司顿,通過新舊用戶消費比芒粹,發(fā)現(xiàn)CDNOw網(wǎng)站留存用戶的效果不高,營運效果不佳大溜,進一步通過用戶的復購率和回購率的分析化漆,說明在新用戶消費后的三個月是營銷的好時段,應做好營銷策略引導用戶再次消費以及持續(xù)消費钦奋,也要適當推出優(yōu)惠活動座云,保持老用戶的支持度。

到此CDNow網(wǎng)站用戶消費行為分析以完成付材,后續(xù)學習更多再來補充朦拖!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市厌衔,隨后出現(xiàn)的幾起案子璧帝,更是在濱河造成了極大的恐慌,老刑警劉巖富寿,帶你破解...
    沈念sama閱讀 222,000評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件睬隶,死亡現(xiàn)場離奇詭異,居然都是意外死亡页徐,警方通過查閱死者的電腦和手機苏潜,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,745評論 3 399
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來变勇,“玉大人恤左,你說我怎么就攤上這事。” “怎么了飞袋?”我有些...
    開封第一講書人閱讀 168,561評論 0 360
  • 文/不壞的土叔 我叫張陵戳气,是天一觀的道長。 經(jīng)常有香客問我授嘀,道長物咳,這世上最難降的妖魔是什么锣险? 我笑而不...
    開封第一講書人閱讀 59,782評論 1 298
  • 正文 為了忘掉前任蹄皱,我火速辦了婚禮,結(jié)果婚禮上芯肤,老公的妹妹穿的比我還像新娘巷折。我一直安慰自己,他們只是感情好崖咨,可當我...
    茶點故事閱讀 68,798評論 6 397
  • 文/花漫 我一把揭開白布锻拘。 她就那樣靜靜地躺著,像睡著了一般击蹲。 火紅的嫁衣襯著肌膚如雪署拟。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,394評論 1 310
  • 那天歌豺,我揣著相機與錄音推穷,去河邊找鬼。 笑死类咧,一個胖子當著我的面吹牛馒铃,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播痕惋,決...
    沈念sama閱讀 40,952評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼区宇,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了值戳?” 一聲冷哼從身側(cè)響起议谷,我...
    開封第一講書人閱讀 39,852評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎堕虹,沒想到半個月后柿隙,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,409評論 1 318
  • 正文 獨居荒郊野嶺守林人離奇死亡鲫凶,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,483評論 3 341
  • 正文 我和宋清朗相戀三年禀崖,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片螟炫。...
    茶點故事閱讀 40,615評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡波附,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情掸屡,我是刑警寧澤封寞,帶...
    沈念sama閱讀 36,303評論 5 350
  • 正文 年R本政府宣布,位于F島的核電站仅财,受9級特大地震影響狈究,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜盏求,卻給世界環(huán)境...
    茶點故事閱讀 41,979評論 3 334
  • 文/蒙蒙 一抖锥、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧碎罚,春花似錦磅废、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,470評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至憔购,卻和暖如春宫峦,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背玫鸟。 一陣腳步聲響...
    開封第一講書人閱讀 33,571評論 1 272
  • 我被黑心中介騙來泰國打工导绷, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人鞋邑。 一個月前我還...
    沈念sama閱讀 49,041評論 3 377
  • 正文 我出身青樓诵次,卻偏偏與公主長得像,于是被迫代替她去往敵國和親枚碗。 傳聞我的和親對象是個殘疾皇子逾一,可洞房花燭夜當晚...
    茶點故事閱讀 45,630評論 2 359

推薦閱讀更多精彩內(nèi)容