該數(shù)據(jù)來源于某網(wǎng)站的消費(fèi)記錄,現(xiàn)針對(duì)該數(shù)據(jù)對(duì)用戶的消費(fèi)趨勢及消費(fèi)行為進(jìn)行分析。
鏈接:https://pan.baidu.com/s/17I7JN579RZS6zvsJCWHOug 提取碼:ydqa
主要內(nèi)容:
1、導(dǎo)入第三方庫及數(shù)據(jù)、觀察數(shù)據(jù)、修改數(shù)據(jù)類型
2、用戶消費(fèi)的趨勢分析
- 每月的消費(fèi)總金額及其變化趨勢
- 每月的消費(fèi)次數(shù)及其變化趨勢
- 每月的消費(fèi)人數(shù)
- 每月用戶平均消費(fèi)金額的趨勢
- 每月用戶平均消費(fèi)次數(shù)的趨勢
3、用戶個(gè)體消費(fèi)分析
- 用戶消費(fèi)金額、消費(fèi)次數(shù)的描述統(tǒng)計(jì)
- 用戶消費(fèi)金額的分布圖
- 用戶消費(fèi)的商品數(shù)的分布圖
- 用戶消費(fèi)金額和商品數(shù)的散點(diǎn)圖
4、用戶消費(fèi)行為分析
- 用戶第一次消費(fèi)及最后一次消費(fèi)
- 用戶購買周期(按第一次和最后一次消費(fèi))
- 多少客戶僅消費(fèi)了一次
- 用戶生命周期描述
- 用戶生命周期分布
- 用戶分層
- RFM
- 新客戶、活躍客戶、不活躍客戶、回流客戶
5、復(fù)購率和回購率分析
1、導(dǎo)入第三方庫及數(shù)據(jù)、觀察數(shù)據(jù)、修改數(shù)據(jù)類型
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline
plt.rcParams['font.sans-serif']=['SimHei']
plt.rcParams['axes.unicode_minus']=False
columns=['user_id','order_dt','order_products','order_amount']
df=pd.read_table(r'C:\Users\f\Desktop\shujufenxi\CDNOW_master.txt',names=columns,sep='\s+')
df.head()

其中各個(gè)字段的含義如下:
?user_id:用戶id
?order_dt:每筆訂單生成的日期
?order_products:每筆訂單中所包含的商品數(shù)
?order_amount:每筆訂單的消費(fèi)總額
df.describe()

- 其中用戶數(shù)有69659,平均每筆訂單中有2.4個(gè)產(chǎn)品,最少的訂單中有1個(gè)產(chǎn)品,最多的有99個(gè)產(chǎn)品,存在一定的極值干擾; 其中每筆訂單的平均消費(fèi)為35元左右,而最小的消費(fèi)額為0,最大的則為1286,也存在一定的極值干擾。
df.info()

- 從表格的各項(xiàng)屬性信息中可以看到,訂單日期的格式為數(shù)字模式,需對(duì)其進(jìn)行修正
df['order_dt']=pd.to_datetime(df.order_dt,format='%Y%m%d')
df['month']=df.order_dt.values.astype('datetime64[M]')
df.head()

- 此處將各個(gè)月份的不同日期所生成的訂單的日期統(tǒng)一歸為同一個(gè)月份,以便后續(xù)進(jìn)行分析使用
df.info()

- 現(xiàn)已將訂單的日期類型修正為正確的數(shù)據(jù)類型
2、用戶消費(fèi)的趨勢分析
每月的消費(fèi)總金額及其變化趨勢
思路:設(shè)置圖標(biāo)格式>>對(duì)月份進(jìn)行分組>>對(duì)每個(gè)月的消費(fèi)金額求和>>制圖
plt.style.use('ggplot')
df.groupby('month')['order_amount'].sum().plot()

- 由消費(fèi)總金額的變化趨勢圖可以看出,97年前三個(gè)月份消費(fèi)金額逐漸上升并達(dá)到高峰,但三月份后出現(xiàn)斷崖式下跌,并于隨后的連續(xù)的月份中呈現(xiàn)出逐漸下降的趨勢??梢娫谌路菘赡艹霈F(xiàn)營銷方面的危機(jī)或者與產(chǎn)品的淡旺季的交替有所相關(guān)。
每月的消費(fèi)次數(shù)及其變化趨勢
思路:對(duì)月份進(jìn)行分組>>求得每個(gè)月進(jìn)行消費(fèi)的用戶總數(shù)>>制圖
df.groupby('month').user_id.count().plot()

- 通過對(duì)每月的消費(fèi)次數(shù)的變化趨勢的體現(xiàn)來看,也表現(xiàn)出前三個(gè)月逐漸攀升至頂峰最后出現(xiàn)斷崖式下跌并持續(xù)緩慢下降的趨勢。說明客戶對(duì)于該產(chǎn)品的消費(fèi)意愿在下降,亦有可能是該產(chǎn)品的曝光率突然下跌,導(dǎo)致客戶很難再更好的了解到產(chǎn)品信息,從而出現(xiàn)消費(fèi)次數(shù)下跌的情況等等。
每月的消費(fèi)人數(shù)
思路:對(duì)月份進(jìn)行分組>>運(yùn)用匿名函數(shù)對(duì)用戶id去重并計(jì)算個(gè)數(shù)>>制圖
df.groupby('month').user_id.apply(lambda x:len(x.drop_duplicates())).plot.pie(autopct='%.2f%%')

- 由餅圖可知,前三個(gè)月的消費(fèi)人數(shù)分別占到了14.17%、17.39%、17.20%,其前三個(gè)月的消費(fèi)人數(shù)總合將近等于后續(xù)好幾個(gè)月的消費(fèi)人數(shù)的綜合,占比近百分之50,可見后續(xù)可能是對(duì)顧客的營銷力度或吸引力度做的不到位等等。
每月用戶平均消費(fèi)金額的趨勢
- 制數(shù)據(jù)透視表
df.pivot_table(index='month',
values=['order_products','order_amount','user_id'],
aggfunc={'order_products':'sum',
'order_amount':'sum',
'user_id':'count'}).head()

思路:對(duì)‘月份’及‘用戶id’進(jìn)行分組求和>>去掉表中的索引打平>>再按月份進(jìn)行分組>>對(duì)每月的消費(fèi)金額求平均>>制圖
df.groupby(['month','user_id']).sum().reset_index().groupby('month')['order_amount'].mean().plot()

每月用戶平均消費(fèi)次數(shù)的趨勢
思路:對(duì)‘月份’和‘用戶id’進(jìn)行分組計(jì)數(shù)>>去除索引打平并將其命名為‘user_c’的表>>在‘user_c’表中添加一列‘count’,讓這一列的值等于‘order_products’列的值>>在‘user_c’表中對(duì)月份進(jìn)行分組并對(duì)‘count’求平均值>>制圖
user_c=df.groupby(['month','user_id']).count().reset_index()
user_c['count']=user_c['order_products']
user_c.loc[:,['month','user_id','count']].groupby('month')['count'].mean().plot()

- 綜合用戶每月消費(fèi)金額的數(shù)據(jù)透視表、平均消費(fèi)金額、平均消費(fèi)次數(shù)的圖標(biāo)信息可知。前三個(gè)月的用戶流量較高,消費(fèi)的總商品數(shù)也較多,自然總體的消費(fèi)金額也是相對(duì)較高,但平均到這么大的用戶流量上的時(shí)候,平均消費(fèi)金額及平均消費(fèi)次數(shù)自然也會(huì)相對(duì)較低,說不定這其中還包含有只消費(fèi)一次后續(xù)都不再消費(fèi),而且消費(fèi)金額較低的用戶,這也將大大拉低平均值。但是從平均消費(fèi)金額及平均消費(fèi)次數(shù)的趨勢圖上可以看到,隨著前三個(gè)月的上漲趨勢后是區(qū)域穩(wěn)定的震蕩階段,結(jié)合數(shù)據(jù)透視表可以了解到,后續(xù)的月份的用戶流量及消費(fèi)總金額較穩(wěn)定,這其中可能存在忠實(shí)用戶的貢獻(xiàn)也免不了會(huì)有老客戶的流失的現(xiàn)象。因此,若每個(gè)月想爭取有更高的消費(fèi)金額,應(yīng)積極引流,增大用戶流量,加大營銷力度,促進(jìn)用戶多消費(fèi)。
3、用戶個(gè)體消費(fèi)分析
用戶消費(fèi)金額、消費(fèi)次數(shù)的描述統(tǒng)計(jì)
思路:對(duì)用戶id進(jìn)行分組求和
df.groupby('user_id').sum().describe()

- 由上述表格可知,所有訂單的商品總數(shù)是23570,而其中每個(gè)用戶平均消費(fèi)的商品數(shù)是7筆左右,有75%的用戶的購買的商品數(shù)小于等于7,然而所有用戶中購買到的商品數(shù)的最小值是1,最大值是1033,中位數(shù)3,因此可見會(huì)存在一定的極值干擾。
- 同上,每個(gè)用戶消費(fèi)金額的數(shù)據(jù)分析也呈現(xiàn)出如上的形式,也有可能存在一定的極值干擾。
用戶消費(fèi)金額的分布圖
思路:對(duì)用戶id進(jìn)行分組求和>>對(duì)‘order_amount’列中小于1100的值進(jìn)行制圖
df.groupby('user_id').sum().query('order_amount<1100').order_amount.plot.hist(bins=25)

用戶消費(fèi)的商品數(shù)的分布圖
思路:對(duì)用戶id進(jìn)行分組求和>>對(duì)‘order_products’列中小于60的值進(jìn)行制圖
df.groupby('user_id').sum().query('order_products < 60').order_products.plot.hist(bins=35)

用戶消費(fèi)金額和商品數(shù)的散點(diǎn)圖
思路:對(duì)用戶id進(jìn)行分組>>以‘order_amount’為x軸,以‘order_products’為y軸>>制圖
df.groupby('user_id').sum().plot.scatter(x='order_amount',y='order_products')

- 人為去除異常值
df.groupby('user_id').sum().query('order_amount <4000').plot.scatter(x='order_amount',y='order_products')

- 由‘用戶消費(fèi)金額的分布圖’及‘用戶消費(fèi)商品數(shù)的分布圖’可以看出,大部分用戶消費(fèi)的金額在范圍0-200之間,消費(fèi)的商品數(shù)在0-10之間,除個(gè)別大客戶的高消費(fèi)外,吸引、加大一般客戶的消費(fèi)意愿還是至關(guān)重要的,大客戶可以通過專項(xiàng)服務(wù)來維持。最后‘消費(fèi)金額與商品數(shù)的散點(diǎn)圖’中可以看出,去除個(gè)別異常值之后可知:消費(fèi)金額和商品數(shù)之間還是存在一定的正相關(guān),同時(shí)大量的商品數(shù)及金額分布集中在一般用戶的這個(gè)范圍內(nèi),因此最后商品的營銷,用戶的引流是促進(jìn)經(jīng)營、增加營收的重中之重。
4、用戶消費(fèi)行為分析
用戶第一次消費(fèi)及最后一次消費(fèi)
思路:以用戶id進(jìn)行分組>>求出每個(gè)用戶第一次消費(fèi)的時(shí)間>>制圖
df.groupby('user_id').order_dt.min().value_counts().plot()

思路:以用戶id進(jìn)行分組>>求出每個(gè)用戶最后一次消費(fèi)的時(shí)間>>制圖
df.groupby('user_id').max().order_dt.value_counts().plot()

- 由兩圖交叉對(duì)比分析可知:前三個(gè)月的用戶流量中,新增的首次消費(fèi)的用戶中有大量的用戶只消費(fèi)了一次,后續(xù)的月份中就沒有再消費(fèi)了,因此最后一次消費(fèi)的表中,前三個(gè)月的值比較高;第一次消費(fèi)的表中,后續(xù)幾個(gè)月雖然新增用戶有所增加但最后新增的用戶量也在逐漸減少,而最后一次消費(fèi)的表中,用戶量后續(xù)幾個(gè)月雖然不多,但最后也在逐漸增多,此消彼長中大體也可以看出:用戶在逐漸流失。
用戶購買周期
1)多少客戶僅消費(fèi)了一次
思路:對(duì)用戶id進(jìn)行分組>>分別求得用戶購買商品第一次和最后一次的消費(fèi)時(shí)間>>求出兩次時(shí)間都為同一天的用戶的總數(shù)
user_life=df.groupby('user_id').order_dt.agg(['min','max'])
(user_life.loc[:,'min']==user_life.loc[:,'max']).value_counts()

- 以上數(shù)據(jù)表明:僅消費(fèi)一次的用戶所占的比例占到了全部用戶的一半左右。
2)用戶生命周期描述
(user_life['max']-user_life['min']).describe()

- 由以上數(shù)據(jù)表明:用戶平均生命周期為134天,而有50%的用戶生命周期為0天,中位數(shù)為0天,但是卻有75%用戶生命周期在294天及以下,最大的用戶生命周期為544天,可見這其中有大量的客戶是只在一天有消費(fèi)過,后期就沒有再消費(fèi)了,而平均天數(shù)是通過忠實(shí)客戶的生命周期來拉升的。
3)用戶生命周期分布
((user_life['max']-user_life['min'])/np.timedelta64(1,'D')).hist(bins=20)

- 上表印證了生命周期描述的信息,只消費(fèi)一天的用戶占據(jù)著特別大的數(shù)量
#除去只消費(fèi)一天的用戶數(shù)
user_life['a0']=(user_life['max']-user_life['min'])/np.timedelta64(1,'D')
user_life.loc[user_life['a0']>0]['a0'].hist(bins=20)

用戶分層
1)RFM
rfm=df.pivot_table(index='user_id',
values=['order_products','order_amount','order_dt'],
aggfunc={'order_dt':'max',
'order_amount':'sum',
'order_products':'sum'})
rfm['R']=-(rfm.order_dt-rfm.order_dt.max())/np.timedelta64(1,'D')
rfm.rename(columns={'order_products':'F','order_amount':'M'},inplace=True)
def rfm_func(x):
level1=x.apply(lambda x:'1' if x>= 0 else '0')
lable=level1.R+level1.F+level1.M
d={'111':'重要價(jià)值客戶',
'011':'重要保持客戶',
'101':'重要挽留客戶',
'001':'重要發(fā)展客戶',
'110':'一般價(jià)值客戶',
'010':'一般保持客戶',
'100':'一般挽留客戶',
'000':'一般發(fā)展客戶'}
result=d[lable]
return result
rfm['lable']=rfm[['R','F','M']].apply(lambda x:x-x.mean()).apply(rfm_func,axis=1)
rfm.head()

rfm.groupby('lable').sum()

- 由表中數(shù)據(jù)可以看出:‘重要保持客戶’的消費(fèi)金額和消費(fèi)產(chǎn)品數(shù)都是比較多,需要商家去重點(diǎn)維護(hù);而‘一般挽留客戶’雖然消費(fèi)金額及消費(fèi)產(chǎn)品數(shù)都不是很突出,但是其消費(fèi)間隔時(shí)間較長,說明對(duì)產(chǎn)品依賴性、或者說是支持度較高;‘重要挽留客戶’雖然消費(fèi)的產(chǎn)品數(shù)不多,但卻貢獻(xiàn)了相對(duì)較多的消費(fèi)金額,對(duì)產(chǎn)品的依賴性也不低,可以對(duì)其進(jìn)行維護(hù)和發(fā)展。
rfm.reset_index().groupby('lable')['user_id'].count().plot.pie(autopct='%.2f%%')

- 由餅圖可知:‘一般挽留客戶’占到全部客戶數(shù)的過半的比例,加之對(duì)比RFM表可知,該客戶群對(duì)產(chǎn)品的支持度高,也貢獻(xiàn)了較大一部分的消費(fèi)金額,可針對(duì)其進(jìn)行適當(dāng)?shù)臓I銷,促進(jìn)其消費(fèi);‘重要保持客戶’占到了全部顧客數(shù)的近五分之一,憑借該客戶群高消費(fèi)能力,為保障商店的大部分營收,也應(yīng)對(duì)其重點(diǎn)維護(hù)。
2)新客戶、活躍客戶、不活躍客戶、回流客戶
pivoted_counts=df.pivot_table(index='user_id',
columns='month',
values='order_dt',
aggfunc='count').fillna(0)
df_purchase=pivoted_counts.applymap(lambda x: 1 if x>0 else 0)
def active_status(data):
status=[]
for i in range(18):
#若本月沒有消費(fèi)
if data[i] ==0:
if len(status) > 0:
if status[i-1] == '未注冊(cè)':
status.append('未注冊(cè)')
else:
status.append('不活躍')
else:
status.append('未注冊(cè)')
#若本月有消費(fèi)
else:
if len(status) ==0:
status.append('新客戶')
else:
if status[i-1] == '不活躍':
status.append('回流')
elif status[i-1] == '未注冊(cè)':
status.append('新客戶')
else:
status.append('活躍')
data.iloc[0:]=status
return data
purchase_stats=df_purchase.apply(active_status,axis=1)
purchase_stats.tail()

purchase_stats_ct=purchase_stats.replace('unreg',np.NaN).apply(lambda x:pd.value_counts(x))
purchase_stats_ct.T.fillna(0).head()

purchase_stats_ct.T.fillna(0).plot.area()

- 由該面積圖可知:前三個(gè)月的新客戶和回流客戶暴增的同時(shí)不活躍的用戶也在逐漸攀升,加之活躍用戶上升的較平緩,可見必將會(huì)有一大部分用戶是單次消費(fèi)的客戶;隨后,新用戶在三月份出現(xiàn)斷崖式下跌,同時(shí)活躍用戶和回流用戶也有所下降,但不活躍用戶卻趨于平穩(wěn),這也必將導(dǎo)致銷量的下跌。
5、復(fù)購率和回購率分析
1)復(fù)購率
purchase_r=pivoted_counts.applymap(lambda x: 1 if x>1 else np.NaN if x==0 else 0)
(purchase_r.sum()/purchase_r.count()).plot(figsize=(10,4))

- 由圖可知:前三個(gè)月的復(fù)購率逐漸上升,并最終穩(wěn)定在20%~22%的范圍內(nèi)。
2)回購率
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)
data.iloc[0:]=status
return data
purchase_b=df_purchase.apply(purchase_back,axis=1)
(purchase_b.sum()/purchase_b.count()).plot(figsize=(10,4))

- 由上圖可知:回購率在前兩個(gè)月上升平穩(wěn),在三月份時(shí)出現(xiàn)大幅度的上升,最終在30%這一百分值的范圍出現(xiàn)較大幅度的震蕩。