為了創(chuàng)造更多利潤、實(shí)現(xiàn)數(shù)據(jù)驅(qū)動運(yùn)營,某CD網(wǎng)站擬對18個月以來的近7萬條消費(fèi)數(shù)據(jù)進(jìn)行分析。具體的研究思路如下:
創(chuàng)新互聯(lián)專注于企業(yè)成都全網(wǎng)營銷、網(wǎng)站重做改版、建陽網(wǎng)站定制設(shè)計、自適應(yīng)品牌網(wǎng)站建設(shè)、H5響應(yīng)式網(wǎng)站、購物商城網(wǎng)站建設(shè)、集團(tuán)公司官網(wǎng)建設(shè)、外貿(mào)營銷網(wǎng)站建設(shè)、高端網(wǎng)站制作、響應(yīng)式網(wǎng)頁設(shè)計等建站業(yè)務(wù),價格優(yōu)惠性價比高,為建陽等各大城市提供網(wǎng)站開發(fā)制作服務(wù)。
新增['month']列,便于后續(xù)按月分析。
重新查看,此時的時間列已轉(zhuǎn)換為正常格式。
由上圖可知,
接下來我們用之前清洗好的字段進(jìn)行數(shù)據(jù)分析。
前三個月消費(fèi)訂單數(shù)在10000筆左右,后續(xù)月份的平均則在2500筆。
前三個月產(chǎn)品購買數(shù)在20000以上,后續(xù)月份的產(chǎn)品購買量在6000~8000左右 。
前三個月每月的消費(fèi)人數(shù)在8000-10000之間,后續(xù)月份平均消費(fèi)人數(shù)在2000人不到
上述消費(fèi)趨勢的分析可以通過數(shù)據(jù)透視表分析(不建議數(shù)據(jù)透視表進(jìn)行去重操作)
本章小結(jié)——
趨勢分析:總體來看,消費(fèi)總金額、消費(fèi)次數(shù)、產(chǎn)品購買量、消費(fèi)人數(shù)的趨勢想似:均先上升、下跌、趨于平穩(wěn)并下降。
可以看出網(wǎng)站的流失用戶在增加,采用開源(拉新)節(jié)流(留存)的運(yùn)營方式,來增加銷售收入。
上一部分是按月分析,主要看趨勢;本部分按用戶個體分析,來看消費(fèi)能力。
按用戶消費(fèi)金額進(jìn)行降序排列,由圖可知,共計約25000個用戶:
啟發(fā),只要維護(hù)好這5000個用戶(占比20%)就可以把業(yè)績KPI完成70%,如果能把5000個用戶運(yùn)營的更好就可以占比更高。
通過以上基本數(shù)據(jù)描述分析可以清楚該網(wǎng)站整體的消費(fèi)趨勢和用戶消費(fèi)能力,現(xiàn)在進(jìn)一步挖掘用戶消費(fèi)行為數(shù)據(jù),通過RFM模型、生命周期等方法對用戶進(jìn)行分層,為后續(xù)運(yùn)營管理提供依據(jù)。
首購可以進(jìn)一步依渠道劃分,衡量不同渠道的差異性,從而量化渠道能力,為后期渠道優(yōu)化提供依據(jù)。
用戶第一次購買分布,集中在前三個月(1997年1-3月);其中,在2月11日至2月25日有一次劇烈波動
由圖可知,1997年1-4月新用戶數(shù)量由90%跌落至80%以下;之后幾個月的新用戶量保持在80~82%區(qū)間。
RFM是一個經(jīng)典的用戶分類模型,模型利用通用交易環(huán)節(jié)中最核心的三個維度——最近消費(fèi)(Recency)、消費(fèi)頻率(Frequency)、消費(fèi)金額(Monetary)細(xì)分用戶群體,從而分析不同群體的用戶價值,最終達(dá)到精準(zhǔn)營銷。
RFM從3個維度、分2個等級(均值)得到8類用戶分層。
通過RFM模型,把用戶分為8個類別,分別給用戶打標(biāo)簽、將客戶分為重要價值、重要保持、重要挽留、重要發(fā)展、一般價值、一般保持、一般保留、一般發(fā)展8類客戶。
從RFM分層可知,本網(wǎng)站的大部分用戶為一般挽留客戶(可適當(dāng)放棄這部分低價值客戶、也可進(jìn)一步提高活躍度)、重要保持客戶(企業(yè)優(yōu)質(zhì)的客戶群,采用會員制運(yùn)營)。具體運(yùn)營策略依據(jù)參照如下:
為了避免劃分用戶群體過多(RFM從3個維度、分2個等級得到8類用戶分層的數(shù)據(jù)立方),可能導(dǎo)致針對性的營銷成本負(fù)擔(dān)上升;下面將通過聚類方法,基于RFM模型劃分成4類用戶,更快實(shí)現(xiàn)后期用戶管理。
顯然,歸一化預(yù)處理后,當(dāng)n=2時,輪廓系數(shù)取最大值0.79,僅從模型聚類效果來講分2類合適;而標(biāo)準(zhǔn)正態(tài)化預(yù)處理后顯示,分4類的輪廓系數(shù)最大,達(dá)0.6964(但2-7類的輪廓系數(shù)整理差別波動不大)
參考漏斗模型,針對每個用戶,按18個月內(nèi)的每個月對用戶情況進(jìn)行分類,即新用戶、活躍用戶、回流用戶、流失用戶。
通過下面的數(shù)據(jù)透視表即可得到每個用戶每個月的購買情況,從而進(jìn)行轉(zhuǎn)化分析。
若本月無消費(fèi)(即為0)
若本月有消費(fèi)(即為1)
由上表可知,每月的用戶消費(fèi)狀態(tài)變化
本篇文章以模仿為主, 利用pandas進(jìn)行數(shù)據(jù)處理 ,分析用戶消費(fèi)行為。數(shù)據(jù)來源CDNow網(wǎng)站的用戶購買明細(xì)。一共有用戶ID,購買日期,購買數(shù)量,購買金額四個字段。
分析步驟
第一部分:數(shù)據(jù)類型的處理—字段的清洗
缺失值的處理、數(shù)據(jù)類型的轉(zhuǎn)化
第二部分:按月數(shù)據(jù)分析
每月的消費(fèi)總金額、每月的消費(fèi)次數(shù)、每月的產(chǎn)品購買量、每月的消費(fèi)人數(shù)
第三部分:用戶個體消費(fèi)數(shù)據(jù)分析
用戶消費(fèi)金額和消費(fèi)次數(shù)的描述統(tǒng)計、用戶消費(fèi)金額和消費(fèi)次數(shù)的散點(diǎn)圖、用戶消費(fèi)金額的分布圖(二八法則)、用戶消費(fèi)次數(shù)的分布圖
、用戶累計消費(fèi)金額的占比
第四部分:用戶消費(fèi)行為分析
用戶第一次消費(fèi)時間、用戶最后一次消費(fèi)時間、新老客消費(fèi)比、用戶分層、用戶購買周期、用戶生命周期。
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from datetime import datetime
%matplotlib inline
plt.style.use('ggplot')
加載包和數(shù)據(jù),文件是txt,用read_table方法打開,因為原始數(shù)據(jù)不包含表頭,所以需要賦予。字符串是空格分割,用\s+表示匹配任意空白符。
一般csv的數(shù)據(jù)分隔是以逗號的形式,但是這份來源于網(wǎng)上的數(shù)據(jù)比價特殊,它是通過多個空格來進(jìn)行分隔
columns = ['user_id','order_dt','order_products','order_amount']
df = pd.read_table("CDNOW_master.txt",names = columns,sep = '\s+')
列字段的含義:
user_id:用戶ID
order_dt:購買日期
order_products:購買產(chǎn)品數(shù)
order_amount:購買金額
消費(fèi)行業(yè)或者是電商行業(yè)一般是通過訂單數(shù),訂單額,購買日期,用戶ID這四個字段來分析的。基本上這四個字段就可以進(jìn)行很豐富的分析。
觀察數(shù)據(jù),判斷數(shù)據(jù)是否正常識別。值得注意的是一個用戶可能在一天內(nèi)購買多次,用戶ID為2的用戶在1月12日買了兩次,這個細(xì)節(jié)不要遺漏。
查看數(shù)據(jù)類型、數(shù)據(jù)是否存在空值;原數(shù)據(jù)沒有空值,很干凈的數(shù)據(jù)。接下來我們要將時間的數(shù)據(jù)類型轉(zhuǎn)化。
當(dāng)利用pandas進(jìn)行數(shù)據(jù)處理的時候,經(jīng)常會遇見數(shù)據(jù)類型的問題,當(dāng)拿到數(shù)據(jù)的時候,首先要確定拿到的是正確的數(shù)據(jù)類型,如果數(shù)據(jù)類型不正確需要進(jìn)行數(shù)據(jù)類型的轉(zhuǎn)化,再進(jìn)行數(shù)據(jù)處理。附: 常見pandas數(shù)據(jù)類型轉(zhuǎn)化
用戶平均每筆訂單購買2.4個商品,標(biāo)準(zhǔn)差在2.3,稍稍具有波動性。中位數(shù)在2個商品,75分位數(shù)在3個商品,說明絕大部分訂單的購買量都不多。最大值在99個,數(shù)字比較高。購買金額的情況差不多,大部分訂單都集中在小額。
一般而言,消費(fèi)類的數(shù)據(jù)分布,都是長尾形態(tài)。大部分用戶都是小額,然而小部分用戶貢獻(xiàn)了收入的大頭,俗稱二八。
數(shù)據(jù)類型的轉(zhuǎn)化
df['order_dt'] = pd.to_datetime(df.order_dt,format = '%Y%m%d') #Y四位數(shù)的日期部分,y表示兩位數(shù)的日期部分
df['month'] = df.order_dt.values.astype('datetime64[M]')?
到目前為止,我們已經(jīng)把數(shù)據(jù)類型處理成我們想要的類型了。我們通過四個字段及衍生字段就可以進(jìn)行后續(xù)的分析了。
接下來我們用之前清洗好的字段進(jìn)行數(shù)據(jù)分析。從用戶方向、訂單方向、消費(fèi)趨勢等進(jìn)行分析。
1、消費(fèi)趨勢的分析
每月的消費(fèi)總金額
每月的消費(fèi)次數(shù)
每月的產(chǎn)品購買量
每月的消費(fèi)人數(shù)
目的:了解這批數(shù)據(jù)的波動形式。
01-每月消費(fèi)總金額
grouped_month = df.groupby('month')
order_month_amount = grouped_month.order_amount.sum()
order_month_amount.head()
用groupby創(chuàng)建一個新的對象。這里要觀察消費(fèi)總金額,需要將order_amount求和
按月統(tǒng)計每個月的CD消費(fèi)總金額。從圖中可以看到,前幾個月的銷量非常高漲。數(shù)據(jù)比較異常。而后期的銷量則很平穩(wěn)。
前三個月的消費(fèi)訂單數(shù)在10000筆左右,后續(xù)月份的消費(fèi)人數(shù)則在2500人左右。
每月的產(chǎn)品購買量一樣呈現(xiàn)早期購買量多,后期平穩(wěn)下降的趨勢。為什么會呈現(xiàn)這個原因呢?我們假設(shè)是用戶身上出了問題,早期時間段的用戶中有異常值,第二假設(shè)是各類促銷營銷,但這里只有消費(fèi)數(shù)據(jù),所以無法判斷。
04-每月的消費(fèi)人數(shù)(去重)
方法一:df.groupby('month').user_id.apply(lambdax:len(x.drop_duplicates())).plot()
方法二:df.groupby('month').user_id.nunique().plot()
每月的消費(fèi)人數(shù)小于每月的消費(fèi)次數(shù),但是區(qū)別不大。前三個月每月的消費(fèi)人數(shù)在8000—10000之間,后續(xù)月份,平均消費(fèi)人數(shù)在2000不到。一樣是前期消費(fèi)人數(shù)多,后期平穩(wěn)下降的趨勢。
數(shù)據(jù)透視表是更簡單的方法,有了這個之后大家用里面的數(shù)據(jù)進(jìn)行作圖也是OK的,而且更加的快捷,所以pandas到后面的話解決一個問題會想到兩到三個方法。具體看那個方便,那個簡單。
之前我們維度都是月,來看的是趨勢。有時候我們也需要看個體來看這個人的消費(fèi)能力如何,這里劃分了五個方向如下:
用戶消費(fèi)金額和消費(fèi)次數(shù)的描述統(tǒng)計
用戶消費(fèi)金額和消費(fèi)次數(shù)的散點(diǎn)圖
用戶消費(fèi)金額的分布圖(二八法則)
用戶消費(fèi)次數(shù)的分布圖
用戶累計消費(fèi)金額的占比(百分之多少的用戶占了百分之多少的消費(fèi)額)
從用戶角度看,每位用戶平均購買7張CD,最多的用戶購買了1033張。用戶的平均消費(fèi)金額(客單價)100元,標(biāo)準(zhǔn)差是240,結(jié)合分位數(shù)和最大值看,平均值才和75分位接近,肯定存在小部分的高額消費(fèi)用戶。
如果大家能夠接觸到消費(fèi)、金融和錢相關(guān)的數(shù)據(jù),基本上都符合二八法則,小部分的用戶占了消費(fèi)的大頭
繪制用戶的散點(diǎn)圖,用戶比較健康而且規(guī)律性很強(qiáng)。因為這是CD網(wǎng)站的銷售數(shù)據(jù),商品比較單一,金額和商品量的關(guān)系也因此呈線性,沒幾個離群點(diǎn)。
從上圖直方圖可知,大部分用戶的消費(fèi)能力確實(shí)不高,絕大部分呈現(xiàn)集中在很低的消費(fèi)檔次。高消費(fèi)用戶在圖上幾乎看不到,這也確實(shí)符合消費(fèi)行為的行業(yè)規(guī)律。
雖然有極致干擾了我們的數(shù)據(jù),但是大部分的用戶還是集中在比較低的而消費(fèi)檔次。
到目前為止關(guān)于用戶的消費(fèi)行為有一個大概的了解
按用戶消費(fèi)金額進(jìn)行升序排序,由圖可知50%的用戶僅貢獻(xiàn)了15%的銷售額度。而排名前5000的用戶就貢獻(xiàn)了60%的消費(fèi)額。也就是說我們只要維護(hù)了這5000個用戶就可以把業(yè)績KPI完成60%,如果能把5000個用戶運(yùn)營的更好就可以占比70%—80%之間。
求月份的最小值,即用戶消費(fèi)行為中的第一次消費(fèi)時間。所有用戶的第一次消費(fèi)都集中在前三個月.
觀察用戶的最后一次消費(fèi)時間。用戶最后一次消費(fèi)比第一次消費(fèi)分布廣,大部分最后一次消費(fèi)集中在前三個月,說明很多客戶購買一次就不再進(jìn)行購買。隨著時間的增長,最后一次購買數(shù)也在遞增,消費(fèi)呈現(xiàn)流失上升的情況,用戶忠誠度在慢慢下降。
user_id為1的用戶第一次消費(fèi)時間和最后一次消費(fèi)時間為19970101,說明他只消費(fèi)了一次
有一半的用戶只消費(fèi)了一次
order_products求的是消費(fèi)產(chǎn)品數(shù),把它替換成消費(fèi)次數(shù)也是可以,但是因為我們這里消費(fèi)次數(shù)是比較固定的,所以使用消費(fèi)產(chǎn)品數(shù)的維度。
R表示客戶最近一次交易時間的間隔,客戶在最近一段時間內(nèi)交易的金額。F表示客戶在最近一段時間內(nèi)交易的次數(shù),F值越大,表示客戶交易越頻繁,反之則表示客戶交易不夠活躍。M表示客戶在最近一段時間內(nèi)交易的金額。M值越大,表示客戶價值越高,反之則表示客戶價值越低。
用戶分層,這里使用平均數(shù)
M不同層次客戶的消費(fèi)累計金額,重要保持客戶的累計消費(fèi)金額最高
不同層次用戶的消費(fèi)人數(shù),之前重要保持客戶的累計消費(fèi)金額最高,這里重要保持客戶的消費(fèi)人數(shù)排名第二,但離一般挽留用戶差距比較大,一般挽留用戶有14074人,重要保持客戶4554人
從RFM分層可知,大部分用戶為重要保持客戶,但是這是由于極致的影響,所以RFM的劃分應(yīng)該盡量以業(yè)務(wù)為準(zhǔn)。盡量用小部分的用戶覆蓋大部分的額度,不要為了數(shù)據(jù)好看劃分等級。
RFM是人工使用象限法把數(shù)據(jù)劃分為幾個立方體,立方體對應(yīng)相應(yīng)的標(biāo)簽,我們可以把標(biāo)簽運(yùn)用到業(yè)務(wù)層面上。比如重要保持客戶貢獻(xiàn)金額最多159203.62,我們?nèi)绾闻c業(yè)務(wù)方配合把數(shù)據(jù)提高或者維護(hù);而重要發(fā)展客戶和重要挽留客戶他們有一段時間沒有消費(fèi)了,我們?nèi)绾伟阉麄兝貋?/p>
用戶每個月的消費(fèi)次數(shù),對于生命周期的劃分只需要知道用戶本月是否消費(fèi),消費(fèi)次數(shù)在這里并不重要,需要將模型進(jìn)行簡化
使用數(shù)據(jù)透視表,需要明確獲得什么結(jié)果。有些用戶在某月沒有進(jìn)行過消費(fèi),會用NaA表示,這里用filna填充。
對于尾部數(shù)據(jù),user_id2W+的數(shù)據(jù)是有問題的,因為從實(shí)際的業(yè)務(wù)場景上說,他們一月和二月都沒有注冊三月份才是他們第一次消費(fèi)。透視會把他們一月和二月的數(shù)據(jù)補(bǔ)上為0,這里面需要進(jìn)行判斷將第一次消費(fèi)作為生命周期的起始,不能從一月份開始就粗略的計算
主要分為兩部分的判斷,以本月是否消費(fèi)為界。本月沒有消費(fèi),還要額外判斷他是不是新客,因為部分用戶是3月份才消費(fèi)成為新客,那么在1、2月份他連新客都不是,用unreg表示。如果是老客,則為unactive
本月若沒有消費(fèi),需要判斷是不是第一次消費(fèi),上一個時間窗口有沒有消費(fèi)。可以多調(diào)試幾次理順里面的邏輯關(guān)系,對用戶進(jìn)行分層。
《業(yè)內(nèi)主流寫法》
這里用戶生命周期的狀態(tài)變化是用數(shù)據(jù)透視表一次性做的,但在實(shí)際業(yè)務(wù)場景中我們可能用SQL把它作為中間表來處理。我們有了明細(xì)表,會通過明細(xì)表來計算出狀態(tài)表;也就是它的數(shù)據(jù)上個月是什么樣的情況得出來,比如上個月是新用戶或者回流用戶,我們直接用上個月的狀態(tài)left join本月的狀態(tài)。直接用SQL進(jìn)行對比
可以用pandas將每個月的狀態(tài)計算出來,不是逐行而是月份計算,先算出一月份哪些用戶是新購買的,然后判斷二月份是否購買,兩者left join
由上表可知,每月用戶的消費(fèi)狀態(tài)變化。活躍用戶、持續(xù)消費(fèi)的用戶對應(yīng)的是消費(fèi)運(yùn)營質(zhì)量?;亓饔脩?,之前不消費(fèi)本月才消費(fèi)對應(yīng)的是喚回運(yùn)營。不活躍的用戶對應(yīng)的是流失
這里可以針對業(yè)務(wù)模型下個定義:流失用戶增加,回流用戶正在減少
user_id 1為空值,表示該客戶只購買過一個訂單。user_id為2 的用戶第二筆訂單與第二筆訂單在同一天購買
訂單周期呈指數(shù)分布,用戶的平均購買周期是68天,絕大部分用戶的購買周期都低于100天。
數(shù)據(jù)偏移比較大,中位數(shù)是0天也就是超過50%的用戶他的生命周期是0天只購買了一次,但是平均生命周期有134天,最大值是544天
用戶的生命周期受只購買一次的用戶影響比較厲害(可以排除),用戶均消費(fèi)134天, 中位數(shù)僅0天
篩選出lifetime0,既排除了僅消費(fèi)了一次那些人,有不少用戶生命周期靠攏在0天,部分質(zhì)量差的用戶雖然消費(fèi)了兩次,但是任然無法持續(xù),在用戶首次消費(fèi)30天內(nèi)應(yīng)該盡量引導(dǎo)。少部分用戶集中在50—300天,屬于普通型的生命周期。高質(zhì)量用戶的生命周期,集中在400天以后,這屬于忠誠用戶。
applymap針對DataFrame里的所有數(shù)據(jù)。用lambda進(jìn)行判斷,因為這里設(shè)計了多個結(jié)果,所以要兩個if else
用sum和count相除即可計算出復(fù)購率。因為這兩個函數(shù)都會忽略NAN,而NAN是沒有消費(fèi)的用戶,count不論是0還是1都會統(tǒng)計,所以是總的消費(fèi)用戶數(shù),而sum求何計算了兩次以上的消費(fèi)用戶。這里用了比較巧妙的替代法計算復(fù)購率,SQL中也可以用。
圖上可以看出復(fù)購率在早期,因為大量新用戶加入的關(guān)系,新客的復(fù)購率并不高,譬如1月新客們的復(fù)購率只有6%左右。而在后期,這時的用戶都是大浪淘沙剩下的老客戶,復(fù)購率比較穩(wěn)定,在20%左右.
單看新客和老客,復(fù)購率有三倍左右的差距
接下來計算回購率?;刭徛适悄骋粋€時間窗口內(nèi)消費(fèi)的用戶,在下一個時間窗口人就消費(fèi)的占比。我1月消費(fèi)用戶1000,他們中有300個2月依然消費(fèi),回購率是30%
0代表當(dāng)月消費(fèi)過次月沒有消費(fèi)過,1代表當(dāng)月消費(fèi)過次月依然消費(fèi)
新建一個判斷函數(shù)。data是輸入數(shù)據(jù),既用戶在18個月內(nèi)是否消費(fèi)的記錄,status是空列表,后續(xù)用來保存用戶是否回購的字段。因為有18個月,所以每個月都要進(jìn)行一次判斷,需要用到循環(huán)。if的主要邏輯是,如果用戶本月進(jìn)行過消費(fèi),且下月消費(fèi)過,記為1,沒有消費(fèi)過是0.本月若沒有進(jìn)行過消費(fèi),為NAN,后續(xù)的統(tǒng)計中進(jìn)行排除。apply函數(shù)應(yīng)用在所有行上,獲得想要的結(jié)果。
最后計算和復(fù)購率大同小異,用count和sum求出,從圖中可以看出,用戶的回購率高于復(fù)購,約在30%左右,和老客戶差異不大。從回購率和復(fù)購率綜合分析可以得出,新客的整體質(zhì)量低于老客,老客的忠誠度(回購率)表現(xiàn)較好,消費(fèi)頻次稍次,這是CDNow網(wǎng)站的用戶消費(fèi)特征。
付款成功的邏輯處理在noticy文件里,這個文件不可見,是支付寶付款成功后臺調(diào)用通知你的頁面
return這個文件是付款成功后用戶跳回看到的頁面,
官方的文檔寫的很清楚
//統(tǒng)計當(dāng)天支出總額
$sql_out="select sum(cash) as cashout from my_money where time $dayend and time $daybegin and type=1 group by FROM_UNIXTIME(time,'%y-%m-%d')";
//統(tǒng)計當(dāng)天收入總額
$sql_in="select sum(cash) as cashin from my_money where time $dayend and time $daybegin and type=2 group by FROM_UNIXTIME(time,'%y-%m-%d')";