如何計算用戶生命週期價值(Customer Lifetime Value)

在用戶關係管理中,常會遇到些直擊靈魂的問題:

  • 這批用戶到底價值幾何?
  • 為什麼要用這種措施去幹預用戶,而不是另一種方式。
  • 為什麼干預這類用戶,而不去幹預另一類,他們的劃分標準是什麼。

有這些問題,實質是因為對客戶價值不夠了解,缺乏行之有效的劃分方式。

用戶精細化運營價值巨大

隨著人口紅利的消失,增長逐漸見頂,急需在現有用戶池做學問。過去粗放式的買量策略已經不再生效,一是買量成本逐漸高企,二是買量帶來的用戶忠誠度極低。對現有客戶群體的劃分和互相倒流,成為重中之重。行業中的黑話“洗用戶”,即是講的這一策略。

對於如何劃分用戶,不用的職能會有不同的看法。產品有產品的看法,可能基於某項功能偏好;運營有運營的看法,是各種活動玩法的定義;甚至領導還有他的一套看法。但是,無論怎麼切入,商業的核心拿捏住,才會八九不離十。

什麼是商業的本質:商業的本質是獲利。因此,我們從用戶的貨幣價值切入,評估和劃分用戶的生命週期。

用戶生命週期價值,這並不是學界的新鮮產物,該理論在上世紀80年代就已經提出。但對於互聯網,網上可搜尋到的資料少之又少。可能的原因有兩個:一是互聯網在過去20年快速爆發,風口上躺著也能賺錢;二是各家的策略內部不統一,無法形成統一的口徑。

但這些都不是不去應用他的理由,反而說明其中價值巨大。這裡,我們剝離開復雜的商業邏輯,僅從交易入手,分析用戶的生命週期價值,以及用戶所處的狀態。

用戶生命週期價值(CLV)

隨著精細化運營的鋪開,過去粗放式的、買量用戶已經不再買賬。每個用戶所能接受的最低服務各不相同。如何根據用戶價值,進行資源的有效利用。最大化槓桿的使用,成為企業生死的關鍵。

過去,沒有統一的理論出現在互聯網應用或是遊戲中。但是,運用跨學科的思維,就可以發現:市場營銷領域已進行過研究,並給出了精度極高、可解釋性強的模型方法。

這種方法,就叫做用戶生命週期價值,英文名稱 Customer Life Time Value,簡稱 CLV 或者 LTV。

CLV 是什麼

用戶生命週期,是一種刻畫用戶的方法。一般用來解決兩類問題:

  1. 用戶還有多少價值、用以衡量投入產出比
  2. 在干預用戶後,根據用戶生命週期價值的變化,優化資源的投放。

即用戶管理的兩個核心問題:用戶所具備的價值以及策略的有效性。

需要注意的是,CLV 的產品形態要求非合約。合約在國內最有代表的是合約手機。一般互聯網產品,合約形態較為少見。

CLV 的用戶群體需已經產生交易,未付費用戶不納入考量。當然,概念遷移,將付費換成活躍或內容消費,該模型也能處理。

CLV 回答哪些問題

用戶活躍還是流失,用戶還有多少付費潛力,用戶在未來某段時間會否再次購買。這三個問題,是用戶生命週期價值能夠回答的。

如何在自家產品中引入 CLV

應用場景

  • 判斷用戶所處生命週期階段
  • 預測用戶指定週期內購買概率
  • 預測用戶的生命週期價值
  • 通過歷史付費數據,預測未來付費

活躍與流失的定義

定義:

用戶有交互為活躍

用戶一段時間不交互,即為流失

lifetims 工具包引入

安裝 python 的工具包:

<code>pip install lifetimes/<code>

CLV 數據挖掘

用戶生命週期判定,需要三個指標

  1. frequency 用戶登錄的頻率,這裡為週期內的天數
  2. recency 用戶的最大週期,即第一次活躍到最後一次活躍
  3. T 用戶所處階段,第一次活躍到觀察週期結束

對於付費預測,還需要用戶的平均付費金額。

數據獲取

從數據庫獲取

<code>  SELECT
customer_id,
COUNT(distinct date(transaction_at)) - 1 as frequency,
datediff('day', MIN(transaction_at), MAX(transaction_at)) as recency,
AVG(total_price) as monetary_value,
datediff('day', CURRENT_DATE, MIN(transaction_at)) as T
FROM orders
GROUP BY customer_id/<code>

python 處理

<code>  from lifetimes.datasets import load_transaction_data
from lifetimes.utils import summary_data_from_transaction_data

transaction_data = load_transaction_data()
print(transaction_data.head())
"""
date id
0 2014-03-08 00:00:00 0
1 2014-05-21 00:00:00 1
2 2014-03-14 00:00:00 2
3 2014-04-09 00:00:00 2
4 2014-05-21 00:00:00 2
"""

summary = summary_data_from_transaction_data(transaction_data, 'id', 'date', observation_period_end='2014-12-31')

print(summary.head())
"""
frequency recency T
id
0 0.0 0.0 298.0
1 0.0 0.0 224.0
2 6.0 142.0 292.0
3 0.0 0.0 147.0

4 2.0 9.0 183.0
"""

bgf.fit(summary['frequency'], summary['recency'], summary['T'])
# <lifetimes.betageofitter>


from lifetimes.datasets import load_cdnow_summary
data = load_cdnow_summary(index_col=[0])

print(data.head())
"""
frequency recency T
ID
1 2 30.43 38.86
2 1 1.71 38.86
3 0 0.00 38.86
4 0 0.00 38.86
5 0 0.00 38.86
"""/<lifetimes.betageofitter>/<code>

BG/NBD 模型

BG/NBD 是一個經典模型改進型,詳細的數學論證參見:A Note on Deriving the Pareto/NBD Model and Related Expressions

該模型有如下假設:


如何計算用戶生命週期價值(Customer Lifetime Value)

通過模型擬合,得到4個參數。

<code>from lifetimes import BetaGeoFitter

# similar API to scikit-learn and lifelines.
bgf = BetaGeoFitter(penalizer_coef=0.0)
bgf.fit(data['frequency'], data['recency'], data['T'])
print(bgf)
"""
<lifetimes.betageofitter>
"""
bgf.summary/<lifetimes.betageofitter>/<code>


如何計算用戶生命週期價值(Customer Lifetime Value)

效果可視化

<code>from lifetimes.plotting import plot_probability_alive_matrix

plot_probability_alive_matrix(bgf)/<code>


如何計算用戶生命週期價值(Customer Lifetime Value)

右下角為最佳客戶,交易頻率高。交易跨度大;右上的客戶短時多次交易,極可能已流失。

預測單個用戶的購買行為

<code>t = 10 #predict purchases in 10 periods
individual = summary.iloc[20]
# The below function is an alias to `bfg.conditional_expected_number_of_purchases_up_to_time`
bgf.predict(t, individual['frequency'], individual['recency'], individual['T'])
# 0.0576511/<code>

生命週期價值預測

在預測價值時,需要第四個參數:用戶交易的次均金額。

該模型有個重要前提:購買頻次和購買金額無相關性。具體可參考 The Gamma-Gamma Model of Monetary Value

<code>from lifetimes.datasets import load_cdnow_summary_data_with_monetary_value

summary_with_money_value = load_cdnow_summary_data_with_monetary_value()
summary_with_money_value.head()
returning_customers_summary = summary_with_money_value[summary_with_money_value['frequency']>0]

print(returning_customers_summary.head())
"""
frequency recency T monetary_value
customer_id
1 2 30.43 38.86 22.35
2 1 1.71 38.86 11.77
6 7 29.43 38.86 73.74
7 1 5.00 38.86 11.77
9 2 35.71 38.86 25.55
"""/<code>

相關性檢驗

<code>returning_customers_summary[['monetary_value', 'frequency']].corr()
"""
monetary_value frequency
monetary_value 1.000000 0.113884
frequency 0.113884 1.000000
"""/<code>
<code>from lifetimes import GammaGammaFitter

ggf = GammaGammaFitter(penalizer_coef = 0)
ggf.fit(returning_customers_summary['frequency'],
returning_customers_summary['monetary_value'])

print(ggf)
"""
<lifetimes.gammagammafitter>
"""/<lifetimes.gammagammafitter>/<code>

次均估計

<code>print(ggf.conditional_expected_average_profit(
summary_with_money_value['frequency'],
summary_with_money_value['monetary_value']
).head(3))
"""
customer_id
1 24.658619
2 18.911489
3 35.170981/<code>

總價值估計

最後,使用 DCF 現金流折現,得到用戶總體價值的當下估值。

<code># refit the BG model to the summary_with_money_value dataset
bgf.fit(summary_with_money_value['frequency'], summary_with_money_value['recency'], summary_with_money_value['T'])

print(ggf.customer_lifetime_value(
bgf, #the model to use to predict the number of future transactions
summary_with_money_value['frequency'],
summary_with_money_value['recency'],
summary_with_money_value['T'],
summary_with_money_value['monetary_value'],
time=12, # months
discount_rate=0.01 # monthly discount rate ~ 12.7% annually
).head(3))
"""
customer_id
1 140.096211
2 18.943467
3 38.180574
Name: clv, dtype: float64
"""/<code>

總結

用戶生命週期價值模型,不同於其它模型。該模型對每個用戶單獨建模,而不是硬性的按流失天數劃分,有極強的靈活性。在得到用戶生命週期階段、以及用戶的生命週期價值,下一步就是具體應用了。

落地場景多種多樣,但要推動上下游,仍需要足夠信服的理由。這裡給到的建議是,去模擬歷史的數據表現,用數據說明效果。

喜歡本文的朋友,別忘了點贊 、喜歡 ❤ +關注 哦,您的小小舉動,是對作者最大的支持~


分享到:


相關文章: