用戶消費行為分析

用python分析用戶消費行為萨咕,數(shù)據(jù)來源CDNow網(wǎng)站的用戶購買明細谍憔。一共有用戶ID跺撼, 購買日期病线, 購買數(shù)量和購買金額四個字段吓著。通過案例數(shù)據(jù)完成一份基礎(chǔ)的數(shù)據(jù)分析報告


用戶購買明細文檔的數(shù)據(jù)如下所示鲤嫡,這里只展示部分?jǐn)?shù)據(jù):


用戶數(shù)據(jù).png
  • 讀取 用戶購買明細.txt

# 讀取用戶行為數(shù)據(jù)
# 四個列名分別表示用戶ID, 購買日期绑莺, 購買數(shù)量暖眼, 購買金額
columns = ['user_id', 'order_date', 'order_quantity', 'order_amount']
df = pandas.read_csv('data/customer.txt', names=columns, sep='\s+')
用戶數(shù)據(jù).png

數(shù)據(jù)文件為txt格式,用read_csv加載數(shù)據(jù)纺裁,'\s+'表示匹配任意空白字符

print(df.describe())
describe.png

??用戶平均每筆訂單購買2.4個商品诫肠,標(biāo)準(zhǔn)差在2.3,稍稍具有波動性对扶。中位數(shù)在2個商品区赵,75%分位數(shù)在3個商品,說明絕大部分訂單的購買量都不多浪南。最大值在99個,數(shù)字比較高漱受。購買金額大部分都不超過43.7络凿,主要都是小額訂單。
??一般而言昂羡,消費類的數(shù)據(jù)分布絮记,都是長尾形態(tài)。大部分用戶都是小額虐先,然而小部分用戶貢獻了收入的大頭怨愤,俗稱二八。

print(df.info())
info.png

??共有69659條數(shù)據(jù)記錄蛹批,不存在缺失值撰洗,所以不需要進行缺失值處理。

  • 將消費行為數(shù)據(jù)粒度轉(zhuǎn)換成每位用戶

# 將購買日期列進行數(shù)據(jù)類型轉(zhuǎn)換
df['date'] = pandas.to_datetime(df['order_date'], format='%Y%m%d')
df['month'] = df['date'].values.astype('datetime64[M]')

# 根據(jù)用戶id進行分組
user_grouped = df.groupby('user_id').sum()
print(user_grouped.describe())
userGroup.png

??首先腐芍,需對日期列進行數(shù)值類型的轉(zhuǎn)換差导,原始數(shù)據(jù)的日期列只是數(shù)值類型,我們需將其轉(zhuǎn)化為datetime64類型猪勇,便于后續(xù)分析處理(astype將時間格式進行轉(zhuǎn)換设褐,[M]轉(zhuǎn)化成月份。這里將月份作為消費行為的主要事件窗口泣刹,選擇哪種時間窗口取決于消費頻率)助析;其次,根據(jù)用戶id進行分組椅您。
??從用戶角度看外冀,每位用戶平均購買7張CD,最多的用戶購買了1033張襟沮,屬于狂熱用戶了锥惋。用戶的平均消費金額(客單價)100元昌腰,標(biāo)準(zhǔn)差是240。

  • 按月對商品銷量和銷售額進行分析

# 按月的緯度進行分析
# 1. 每月的CD銷量
order_month = df.groupby('month')['order_quantity'].sum()
# 2. 每月的銷售總額
month_total = df.groupby('month')['order_amount'].sum()

plt.rc('font', family='simhei', size=9)
plt.subplot(2, 1, 1)
plt.plot(order_month, 'yellowgreen', label='每月CD銷量')
plt.grid(color='#95a5a6', linestyle='--', linewidth=1, axis='y', alpha=0.4)
plt.legend(loc=1)
plt.subplot(2, 1, 2)
plt.plot(month_total, label='每月銷售總額')
plt.grid(color='#95a5a6', linestyle='--', linewidth=1, axis='y', alpha=0.4)
plt.legend(loc=0)
plt.show()
month_statistic.png

??按月對每月的CD銷量和銷售額進行統(tǒng)計膀跌。觀察圖表遭商,發(fā)現(xiàn)前三個銷量非常高,數(shù)據(jù)比較異常捅伤,后面則趨于平穩(wěn)劫流。月銷售額也呈現(xiàn)一樣的趨勢,前幾個月高丛忆,后幾個月平穩(wěn)祠汇,為什么會出現(xiàn)這種情況呢?第一種假設(shè)熄诡,早期用戶存在異常值可很。第二種假設(shè),早期有各種促銷優(yōu)惠活動凰浮。但這里只有消費數(shù)據(jù)我抠,無法對第二種假設(shè)作出判斷。

  • 分析為什么前三個月銷量異常

1. 用戶購買量和消費額度分析(散點圖和直方圖)

# 假設(shè)1 : 早期時間段的用戶有異常值
user_buy = df.groupby('user_id').sum()
plt.rc('font', family='simhei', size=9)
plt.figure(figsize=(6, 8))
plt.subplot(2, 1, 1)
plt.scatter(df['order_amount'], df['order_quantity'])
plt.grid(color='#95a5a6', linestyle='--', linewidth=1, alpha=0.4)
plt.legend(['購買數(shù)量和消費金額'], loc=2)
plt.subplot(2, 1, 2)
plt.scatter(user_buy['order_amount'], user_buy['order_quantity'])
plt.grid(color='#95a5a6', linestyle='--', linewidth=1, alpha=0.4)
plt.legend(['各用戶購買數(shù)量和消費金額'], loc=2)
plt.show()

# 各用戶消費金額和消費數(shù)量直方圖
plt.rc('font', family='simhei', size=9)
plt.figure(figsize=(12, 4))
plt.subplot(1, 2, 1)
df['order_amount'].hist(bins=20)
plt.legend(['消費金額'], loc=1)
plt.subplot(1, 2, 2)
df.groupby('user_id')['order_quantity'].sum().hist(bins=20)
plt.legend(['購買數(shù)量'], loc=1)
plt.show()
scatter.png

??從每筆訂單的散點圖中觀察袜茧,訂單消費金額和訂單商品量呈規(guī)律性菜拓。訂單的極值較少,超出1000的就幾個笛厦。顯然不是前三個月數(shù)據(jù)異常的罪魁禍?zhǔn)住?br> ??從用戶的散點圖觀察纳鼎,用戶也比較健康,而且規(guī)律性比訂單更強裳凸。因為這是CD網(wǎng)站的銷售數(shù)據(jù)贱鄙,商品比較單一,金額和商品量的關(guān)系也因此呈線性登舞,沒幾個離群點贰逾。消費能力特別強的用戶有,但是數(shù)量不多菠秒。為了更好的觀察疙剑,用直方圖

hist.png

??從直方圖看,大部分用戶的消費能力確實不高践叠,高消費用戶在圖上幾乎看不到言缤。這也確實符合消費行為的行業(yè)規(guī)律。
??以上就是對用戶消費的金額和購買量的觀察禁灼,接下來看消費的時間節(jié)點管挟。

2.用戶第一次和最后一次消費時間

# 用戶消費的時間節(jié)點
# 用戶第一次消費時間
first = df.groupby('user_id').month.min().value_counts()  # Series.value_counts返回的是該Series對象中獨一無二的元素的個數(shù)。
# 用戶最后一次消費
last = df.groupby('user_id').month.max().value_counts()
first_buy.png

??用groupby函數(shù)將用戶分組弄捕,并且求月份的最小值僻孝,最小值即用戶消費行為中的第一次消費時間导帝。結(jié)果顯示,所有用戶的第一次消費都集中在前三個月穿铆。我們可以這樣認(rèn)為您单,案例中的訂單數(shù)據(jù),只是選擇了某個時間段消費的用戶在18個月內(nèi)的消費行為荞雏。


last_buy.png

??觀察用戶的最后一次消費時間虐秦。絕大部分?jǐn)?shù)據(jù)依然集中在前三個月。后續(xù)的時間段內(nèi)凤优,依然有用戶在消費悦陋,但是緩慢減少。
??異常趨勢的原因獲得了解釋。因為用戶的第一次和最后一次消費大部分集中在前三個月,所以就有了上面我們所看到的前三個月數(shù)據(jù)異常高的情況纤房。
??接下來分析消費中的復(fù)購率和回購率。

  • 復(fù)購率

1. 首先將用戶消費數(shù)據(jù)進行數(shù)據(jù)透視痒钝。

# 首先將消費數(shù)據(jù)進行數(shù)據(jù)透視
pivot_counts = df.pivot_table(
    index='user_id',
    columns='month',
    values='order_date',
    aggfunc='count'
).fillna(0)
print(pivot_counts.head())
pivot_table.png

**2. 計算復(fù)購率

# 計算復(fù)購率
pivot_counts_tf = pivot_counts.applymap(lambda x: 1 if x > 1 else numpy.NaN if x == 0 else 0)  # apply() 和applymap()是DataFrame數(shù)據(jù)類型的函數(shù),map()是Series數(shù)據(jù)類型的函數(shù)痢毒。apply()的操作對象是DataFrame的一列或者一行數(shù)據(jù), applymap()是element-wise的蚕甥,作用于每個DataFrame的每個數(shù)據(jù)哪替。 map()也是element-wise的,對Series中的每個數(shù)據(jù)調(diào)用搜索一次函數(shù)菇怀。
repurchase_tb = pivot_counts_tf.sum() / pivot_counts_tf.count()
plt.plot(repurchase_tb)
plt.grid(color='#95a5a6', linestyle='--', linewidth=1, alpha=0.4)
plt.show()
復(fù)購率.png

??復(fù)購率指某個時間段內(nèi)重消費兩次及以上的用戶在總消費用戶中的占比凭舶,這里的時間窗口是月,如果一個用戶在同一天下了兩筆訂單爱沟,這里也將他算作復(fù)購用戶帅霜。將數(shù)據(jù)轉(zhuǎn)換一下,消費兩次及以上記為1呼伸,消費一次記為0身冀,沒有消費記為NaN。
??用sum和count相除即可計算出復(fù)購率括享。因為這兩個函數(shù)都會忽略NaN搂根,而NaN是沒有消費的用戶,count不論0還是1都會統(tǒng)計铃辖,所以是總的消費用戶數(shù)剩愧,而sum求和計算了兩次以上的消費用戶。
??圖上可以看出復(fù)購率在早期娇斩,因為大量新用戶加入的關(guān)系仁卷,新客的復(fù)購率并不高穴翩,譬如1月新客們的復(fù)購率只有6%左右。而在后期锦积,這時的用戶都是大浪淘沙剩下的老客芒帕,復(fù)購率比較穩(wěn)定,在20%左右充包。單看新客和老客副签,復(fù)購率有三倍左右的差距。
??接下來計算回購率基矮∠ⅲ回購率是某一個時間窗口內(nèi)消費的用戶,在下一個時間窗口仍舊消費的占比家浇。

  • 回購率

# 計算回購率
pivot_amount = df.pivot_table(
    index='user_id',
    columns='month',
    values='order_amount',
    aggfunc='mean'
).fillna(0)

pivot_amount_tf = pivot_amount.applymap(lambda x: 1 if x > 0 else 0)

def purchase_return(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(numpy.NaN)
    status.append(numpy.NaN)
    return status
pivot_purchase_return = pivot_amount_tf.apply(purchase_return, axis=1)
plt.plot(pivot_purchase_return.sum() / pivot_purchase_return.count())
plt.grid(color='#95a5a6', linestyle='--', linewidth=1, alpha=0.4)
plt.show()

首先將消費金額進行數(shù)據(jù)透視本砰,接著用applymap+lambda轉(zhuǎn)換數(shù)據(jù),只要有過購買钢悲,記為1点额,反之為0;最后新建一個判斷函數(shù)莺琳。data是輸入的數(shù)據(jù)还棱,即用戶在18個月內(nèi)是否消費的記錄,status是空列表惭等,后續(xù)用來保存用戶是否回購的字段珍手。
??因為有18個月,所以每個月都要進行一次判斷辞做,需要用到循環(huán)琳要。if的主要邏輯是,如果用戶本月進行過消費秤茅,且下月消費過稚补,記為1,沒有消費過是0框喳。本月若沒有進行過消費课幕,為NaN,后續(xù)的統(tǒng)計中進行排除帖努。用apply函數(shù)應(yīng)用在所有行上撰豺,獲得想要的結(jié)果。

回購率.png

??最后的計算和復(fù)購率大同小異污桦,用count和sum求出。從圖中可以看出匙监,用戶的回購率高于復(fù)購率小作,約在30%左右静秆,波動性也較強巡李。新用戶的回購率在15%左右侨拦,和老客差異不大殊橙。
??將回購率和復(fù)購率綜合分析,可以得出狱从,新客的整體質(zhì)量低于老客膨蛮,老客的忠誠度(回購率)表現(xiàn)較好,消費頻次稍次季研,這是CDNow網(wǎng)站的用戶消費特征敞葛。
??接下來進行用戶分層,我們按照用戶的消費行為与涡,簡單劃分成幾個維度:新用戶制肮、活躍用戶、不活躍用戶递沪、回流用戶。

  • 用戶分層

新用戶的定義是第一次消費综液】羁活躍用戶即老客,在某一個時間窗口內(nèi)有過消費谬莹。不活躍用戶則是時間窗口內(nèi)沒有消費過的老客檩奠。回流用戶是在上一個窗口中沒有消費附帽,而在當(dāng)前時間窗口內(nèi)有過消費埠戳。以上的時間窗口都是按月統(tǒng)計。
??比如某用戶在1月第一次消費蕉扮,那么他在1月的分層就是新用戶整胃;他在2月消費國,則是活躍用戶喳钟;3月沒有消費屁使,此時是不活躍用戶在岂;4月再次消費,此時是回流用戶蛮寂,5月還是消費蔽午,是活躍用戶。
unreg-潛在用戶(注冊了酬蹋,但為消費)及老,new-新用戶(已經(jīng)消費過一次),unactive-不活躍用戶范抓, active- 活躍用戶骄恶, 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 status
pivot_purchase_status = pivot_amount_tf.apply(active_status, axis=1)

purchase_status_counts = pivot_purchase_status.\
    replace('unreg', numpy.NaN).apply(lambda x: pandas.value_counts(x))

#purchase_status_counts.T.plot.area()

return_rate = purchase_status_counts.apply(lambda x: x / x.sum(), axis=1)
plt.rc('font', family='simhei', size=9)
plt.subplot(211)
plt.title('回流用戶占比')
plt.plot(return_rate.loc['return'])
plt.subplot(212)
plt.title('活躍用戶占比')
plt.plot(return_rate.loc['active'])
plt.show()

分為兩部分的判斷,以本月是否消費為界尉咕。本月沒有消費叠蝇,還要額外判斷他是不是新客,因為部分用戶是3月份才消費成為新客年缎,那么在1悔捶、2月份他應(yīng)該連新客都不是,用unreg表示单芜。如果是老客蜕该,則為unactive。
??本月若有消費洲鸠,需要判斷是不是第一次消費堂淡,上一個時間窗口有沒有消費。對用戶進行分層扒腕,邏輯確實不會簡單绢淀,而且這里只是簡化版本的。


area.png

??生成面積圖瘾腰,比較丑皆的。因為它只是某時間段消費過的用戶的后續(xù)行為,藍色和灰色區(qū)域都可以不看蹋盆。只看紫色回流和紅色活躍這兩個分層费薄,用戶數(shù)比較穩(wěn)定。這兩個分層相加栖雾,就是消費用戶占比(后期沒新客)楞抡。

回購率&活躍率.png

??用戶回流占比在5%~8%,有下降趨勢析藕。所謂回流占比召廷,就是回流用戶在總用戶中的占比。另外一種指標(biāo)叫回流率,指上個月多少不活躍/消費用戶在本月活躍/消費柱恤。因為不活躍的用戶總量近似不變数初,所以這里的回流率也近似回流占比。
??活躍用戶的下降趨勢更明顯梗顺,占比在3%~5%間泡孩。這里用戶活躍可以看作連續(xù)消費用戶,質(zhì)量在一定程度上高于回流用戶寺谤。
??結(jié)合回流用戶和活躍用戶看仑鸥,在后期的消費用戶中,60%是回流用戶变屁,40%是活躍用戶/連續(xù)消費用戶眼俊,整體質(zhì)量還好,但是針對這兩個分層依舊有改進的空間粟关,可以繼續(xù)細化數(shù)據(jù)疮胖。
??接下來分析用戶質(zhì)量,因為消費行為有明顯的二八傾向闷板,我們需要知道高質(zhì)量用戶為消費貢獻了多少份額澎灸。

  • 用戶質(zhì)量分析

# 計算高質(zhì)量用戶貢獻了多少份額(28傾向)
user_amount = df.groupby('user_id')['order_amount'].sum().sort_values().reset_index()
user_amount['amount_cumsum'] = user_amount['order_amount'].cumsum()

amount_total = user_amount['amount_cumsum'].max()
user_amount['percentage'] = user_amount['amount_cumsum'] / amount_total

# 統(tǒng)計銷量
user_count = df.groupby('user_id')['order_quantity'].sum().sort_values().reset_index()
user_count['count_cumsum'] = user_count['order_quantity'].cumsum()
count_total = user_count['count_cumsum'].max()
user_count['percentage'] = user_count['count_cumsum'] / count_total
plt.rc('font', family='simhei', size=9)
plt.subplot(211)
plt.title('消費額占比')
plt.plot(user_amount['percentage'])
plt.grid(color='#95a5a6', linestyle='--', linewidth=1, alpha=0.4)
plt.subplot(212)
plt.title('銷量占比')
plt.plot(user_count['percentage'])
plt.grid(color='#95a5a6', linestyle='--', linewidth=1, alpha=0.4)
plt.show()

新建一個對象,按用戶的消費金額生序遮晚。使用cumsum性昭,它是累加函數(shù)。逐行計算累計的金額县遣,最后的2500315便是總消費額糜颠。并轉(zhuǎn)換成百分比。
??制趨勢圖萧求,橫坐標(biāo)是按貢獻金額大小排序而成其兴,縱坐標(biāo)則是用戶累計貢獻。

用戶質(zhì)量.png

??可以很清楚的看到夸政,前20000個用戶貢獻了40%的消費忌警。后面4000位用戶貢獻了60%,確實呈現(xiàn)28傾向秒梳。
??統(tǒng)計一下銷量,前兩萬個用戶貢獻了45%的銷量箕速,高消費用戶貢獻了55%的銷量酪碘。在消費領(lǐng)域中,狠抓高質(zhì)量用戶是萬古不變的道理盐茎。
??接下來計算用戶生命周期兴垦,這里定義第一次消費至最后一次消費為整個用戶生命。

  • 用戶生命周期

# 計算用戶生命周期
order_date_min = df.groupby('user_id').date.min()
order_date_max = df.groupby('user_id').date.max()
print((order_date_max - order_date_min).mean())

# 生命周期分布
plt.figure(1)
plt.hist((order_date_max - order_date_min) / numpy.timedelta64(1, 'D'), bins=15)

1.統(tǒng)計出用戶第一次消費和最后一次消費的時間,相減探越,得出每一位用戶的生命周期狡赐。因為數(shù)據(jù)中的用戶都是前三個月第一次消費,所以這里的生命周期代表的是1月~3月用戶的生命周期钦幔。因為用戶會持續(xù)消費枕屉,所以理論上,隨著后續(xù)的消費鲤氢,用戶的平均生命周期會增長搀擂。
??2.求一下平均,所有用戶的平均生命周期是134天卷玉,比預(yù)想的高哨颂,但是平均數(shù)不靠譜,還是看一下分布吧相种。

1.png

??因為這里的數(shù)據(jù)類型是timedelta時間威恼,它無法直接作出直方圖,所以先換算成數(shù)值寝并。換算的方式直接除timedelta函數(shù)即可箫措,這里的np.timedelta64(1, 'D'),D表示天食茎,1表示1天蒂破,作為單位使用的。因為max-min已經(jīng)表示為天了别渔,兩者相除就是周期的天數(shù)附迷。
??上表可看到,大部分用戶只消費了一次哎媚,所有生命周期的大頭都集中在了0天喇伯。但這不是我們想要的答案,不妨將只消費了一次的新客排除拨与,來計算所有消費過兩次以上的老客的生命周期稻据。

# 排除只消費了一次的用戶
life_time = (order_date_max - order_date_min).reset_index()
life_time['life_time'] = life_time.date / numpy.timedelta64(1, 'D')
plt.figure(2)
plt.hist(life_time[life_time['life_time'] > 0].life_time, bins=100)
plt.show()

# 消費兩次及以上的用戶平均生命周期
print(life_time[life_time['life_time'] > 0].life_time.mean())

先轉(zhuǎn)換成DataFrame,再篩選出lifetime>0买喧,即排除了僅消費了一次的那些人捻悯。做直方圖。

2.png

??這個圖比上面的靠譜多了淤毛,雖然仍舊有不少用戶生命周期靠攏在0天今缚。這是雙峰趨勢圖。部分質(zhì)量差的用戶低淡,雖然消費了兩次姓言,但是仍舊無法持續(xù)瞬项,在用戶首次消費30天內(nèi)應(yīng)該盡量引導(dǎo)。少部分用戶集中在50天~300天何荚,屬于普通型的生命周期囱淋,高質(zhì)量用戶的生命周期,集中在400天以后餐塘,這已經(jīng)屬于忠誠用戶了妥衣。
??消費兩次以上的用戶生命周期是276天,遠高于總體唠倦。從策略看称鳞,用戶首次消費后應(yīng)該花費更多的引導(dǎo)其進行多次消費,提供生命周期稠鼻,這會帶來2.5倍的增量冈止。
??再來計算留存率,留存率也是消費分析領(lǐng)域的經(jīng)典應(yīng)用候齿。它指用戶在第一次消費后熙暴,有多少比率進行第二次消費。和回流率的區(qū)別是留存傾向于計算第一次消費慌盯,并且有多個時間窗口周霉。

  • 留存率

# 計算留存率
user_purchase = df[['user_id', 'order_quantity', 'order_amount', 'date']]
user_purchase_retention = pandas.merge(
    left=user_purchase,
    right=order_date_min.reset_index(),
    how='inner',
    on='user_id',
    suffixes=('', '_min')
)
user_purchase_retention['order_date_diff'] = user_purchase_retention.date - user_purchase_retention.date_min

# 將日期列轉(zhuǎn)換成時間數(shù)據(jù)類型
date_trans = lambda x: x / numpy.timedelta64(1, 'D')
user_purchase_retention['date_diff'] = user_purchase_retention.order_date_diff.apply(date_trans)

??這里用到merge函數(shù),它和SQL中的join差不多亚皂,用來將兩個DataFrame進行合并俱箱。我們選擇了inner 的方式,對標(biāo)inner join灭必。即只合并能對應(yīng)得上的數(shù)據(jù)狞谱。這里以on=user_id為對應(yīng)標(biāo)準(zhǔn)。這里merge的目的是將用戶消費行為和第一次消費時間對應(yīng)上禁漓,形成一個新的DataFrame跟衅。suffxes參數(shù)是如果合并的內(nèi)容中有重名column,加上后綴播歼。除了merge伶跷,還有join,concat秘狞,用戶接近叭莫,查看文檔即可。
??并將order_date和order_date_min相減烁试。獲得一個新的列雇初,為用戶每一次消費距第一次消費的時間差值。
??最后廓潜,將日期列轉(zhuǎn)換成時間數(shù)據(jù)類型。接著進行以下操作


# 將時間差值分組
bin = [0, 3, 7, 15, 30, 60, 90, 180, 365]
user_purchase_retention['date_diff_bin'] = pandas.cut(user_purchase_retention.date_diff, bins=bin)
# 用pivot_table數(shù)據(jù)透視, 獲得的結(jié)果是用戶在第一次消費之后辩蛋,在后續(xù)各時間段的消費總額
pivot_retention = user_purchase_retention.pivot_table(
    index='user_id',
    columns='date_diff_bin',
    values='order_amount',
    aggfunc=sum
)

將時間差值分桶呻畸。我這里分成0~3天內(nèi),3~7天內(nèi)悼院,7~15天等伤为,代表用戶當(dāng)前消費時間距第一次消費屬于哪個時間段呢。這里date_diff=0并沒有被劃分入0~3天据途,因為計算的是留存率绞愚,如果用戶僅消費了一次,留存率應(yīng)該是0颖医。另外一方面位衩,如果用戶第一天內(nèi)消費了多次,但是往后沒有消費熔萧,也算作留存率0糖驴。
??用pivot_table數(shù)據(jù)透視,獲得的結(jié)果是用戶在第一次消費之后佛致,在后續(xù)各時間段內(nèi)的消費總額贮缕。

# 用戶在后續(xù)各時間段的平均消費
print(pivot_retention.mean())

??計算一下用戶在后續(xù)各時間段的平均消費額,這里只統(tǒng)計有消費的平均值俺榆。雖然后面時間段的金額高感昼,但是它的時間范圍也寬廣。從平均效果看罐脊,用戶第一次消費后的0~3天內(nèi)定嗓,更可能消費更多。
??但消費更多是一個相對的概念爹殊,我們還要看整體中有多少用戶在0~3天消費蜕乡。


pivot_retention_trans = pivot_retention.fillna(0).applymap(lambda x: 1 if x > 0 else 0)
(pivot_retention_trans.sum() / pivot_retention_trans.count()).plot.bar()
plt.show()

??依舊將數(shù)據(jù)轉(zhuǎn)換成是否,1代表在該時間段內(nèi)有后續(xù)消費梗夸,0代表沒有层玲。
??只有2.5%的用戶在第一次消費的次日至3天內(nèi)有過消費,3%的用戶在3~7天內(nèi)有過消費反症。數(shù)字并不好看辛块,CD購買確實不是高頻消費行為。時間范圍放寬后數(shù)字好看了不少铅碍,有20%的用戶在第一次消費后的三個月到半年之間有過購買润绵,27%的用戶在半年后至1年內(nèi)有過購買。從運營角度看胞谈,CD機營銷在教育新用戶的同時尘盼,應(yīng)該注重用戶忠誠度的培養(yǎng)憨愉,放長線掉大魚,在一定時間內(nèi)召回用戶購買卿捎。

怎么算放長線掉大魚呢配紫?我們計算出用戶的平均購買周期。


# 計算用戶的平均購買周期
def diff(group):
    d = abs(group.date_diff - group.date_diff.shift(-1))
    return d
last_diff = user_purchase_retention.groupby('user_id').apply(diff)
print(last_diff.head(10))
print('用戶的平均購買周期:', last_diff.mean())
plt.hist(last_diff, bins=20)
plt.show()

定義一個計算間隔的函數(shù)diff午阵,輸入的是group躺孝,分組后的數(shù)據(jù)依舊是DataFrame。我們將用戶上下兩次消費時間相減將能求出消費間隔了底桂。shift函數(shù)是一個偏移函數(shù)植袍。
??x.shift()是往上偏移一個位置,x.shift(-1)是往下偏移一個位置籽懦,加參數(shù)axis=1則是左右偏移于个。當(dāng)我想將求用戶下一次距本次消費的時間間隔,用shift(-1)減當(dāng)前值即可猫十。案例用的diff函數(shù)便借助shift方法览濒,巧妙的求出了每位用戶的兩次消費間隔,若為NaN拖云,則沒有下一次贷笛。
??然后就簡單了,用mean函數(shù)即可求出用戶的平均消費間隔時間是68天宙项。想要召回用戶乏苦,在60天左右的消費間隔是比較好的。


??看一下直方圖尤筐,典型的長尾分布汇荐,大部分用戶的消費間隔確實比較短。不妨將時間召回點設(shè)為消費后立即贈送優(yōu)惠券盆繁,消費后10天詢問用戶CD怎么樣掀淘,消費后30天提醒優(yōu)惠券到期,消費后60天短信推送油昂。這便是數(shù)據(jù)的應(yīng)用了革娄。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市冕碟,隨后出現(xiàn)的幾起案子拦惋,更是在濱河造成了極大的恐慌,老刑警劉巖安寺,帶你破解...
    沈念sama閱讀 211,265評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件厕妖,死亡現(xiàn)場離奇詭異,居然都是意外死亡挑庶,警方通過查閱死者的電腦和手機言秸,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,078評論 2 385
  • 文/潘曉璐 我一進店門软能,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人举畸,你說我怎么就攤上這事埋嵌。” “怎么了俱恶?”我有些...
    開封第一講書人閱讀 156,852評論 0 347
  • 文/不壞的土叔 我叫張陵,是天一觀的道長范舀。 經(jīng)常有香客問我合是,道長,這世上最難降的妖魔是什么锭环? 我笑而不...
    開封第一講書人閱讀 56,408評論 1 283
  • 正文 為了忘掉前任聪全,我火速辦了婚禮,結(jié)果婚禮上辅辩,老公的妹妹穿的比我還像新娘难礼。我一直安慰自己,他們只是感情好玫锋,可當(dāng)我...
    茶點故事閱讀 65,445評論 5 384
  • 文/花漫 我一把揭開白布蛾茉。 她就那樣靜靜地躺著,像睡著了一般撩鹿。 火紅的嫁衣襯著肌膚如雪谦炬。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,772評論 1 290
  • 那天节沦,我揣著相機與錄音键思,去河邊找鬼。 笑死甫贯,一個胖子當(dāng)著我的面吹牛吼鳞,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播叫搁,決...
    沈念sama閱讀 38,921評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼赔桌,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了常熙?” 一聲冷哼從身側(cè)響起纬乍,我...
    開封第一講書人閱讀 37,688評論 0 266
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎裸卫,沒想到半個月后仿贬,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,130評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡墓贿,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,467評論 2 325
  • 正文 我和宋清朗相戀三年茧泪,在試婚紗的時候發(fā)現(xiàn)自己被綠了蜓氨。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,617評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡队伟,死狀恐怖穴吹,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情嗜侮,我是刑警寧澤港令,帶...
    沈念sama閱讀 34,276評論 4 329
  • 正文 年R本政府宣布,位于F島的核電站锈颗,受9級特大地震影響顷霹,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜击吱,卻給世界環(huán)境...
    茶點故事閱讀 39,882評論 3 312
  • 文/蒙蒙 一淋淀、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧覆醇,春花似錦朵纷、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,740評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至常摧,卻和暖如春革屠,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背排宰。 一陣腳步聲響...
    開封第一講書人閱讀 31,967評論 1 265
  • 我被黑心中介騙來泰國打工似芝, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人板甘。 一個月前我還...
    沈念sama閱讀 46,315評論 2 360
  • 正文 我出身青樓党瓮,卻偏偏與公主長得像,于是被迫代替她去往敵國和親盐类。 傳聞我的和親對象是個殘疾皇子寞奸,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,486評論 2 348

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