老闆:白茶,你說咱這行業咋就留不住人呢?
白茶:(黑人問号??)老闆,你說的是沒有回頭客麼?
老闆:對對對,就是這個意思,能不能搞一個報表,讓我知道顧客是在哪個階段流失的?
白茶:唔...問題不大!
對于很多新興行業來說,使用者留存都是一個比較突出的問題。因為使用者就代表着市場的占有率,也代表商業的大盤,盤子越大,能産生的價值也越高,是以越來越多的企業開始重視使用者留存的問題。
本期咱們來聊一聊使用者留存的問題,這個問題對于零售快銷、電商行業、以及遊戲行業都具有很高的參考價值。
先來看看本期的案例資料:
資料非常的簡單,隻有基礎的日期列、使用者ID、産品以及售賣金額。
解釋一下什麼叫留存:
簡而言之,顧客今天在我這裡買東西了,明天依然來我這裡買,那麼這兩天對于此使用者就産生了留存的概念;
玩家今天登入用戶端選擇了打遊戲,明天依然登入打遊戲,這個也是使用者留存;
浏覽者今天觀看我直播,明天依然選擇觀看,這個還是留存。
對于大部分企業來說,這個概念習慣稱之為使用者留存,但是從網際網路的角度來說,稱之為流量也可以。
使用者留存,我們需要對使用者的數量進行統計,統計每個周期内的新客數量以及新客持續購買的數量。
編寫基礎的DAX函數:
C.CustomerNumber =
DISTINCTCOUNTNOBLANK ( Fact_Sale[使用者ID] )
複制
有了基礎的計算名額,我們的思路可以擴充一下,使用者留存我們觀測的不是某一個具體的時間點,而是一個階段,比如我選擇2021年8月1日,我更希望看到的是8月1日之前一段時間的資料。
是以我們的模型關系如下:
建立兩張日期表,一張建立關系,一張不建立關系。
編寫如下路徑成本:
階段結束時間:
A.EndNode =
SELECTEDVALUE ( Dim_Date_II[Date] )
複制
建立參數:
注:也可以不建立參數, 這裡是為了擴充性考慮,可以自由的篩選展示階段。
階段開始時間:
B.InitialNode =
TOPN (
1,
FILTER ( ALL ( Dim_Date[Date] ), [Date] <= [A.EndNode] - [Period] ),
'Dim_Date'[Date], DESC
)
複制
階段内使用者數量:
D.CurrentCustomerNumber =
VAR CurrentCustomerNumber =
SUMMARIZE (
'Fact_Sale',
'Fact_Sale'[使用者ID],
Dim_Date[Date],
"@CUSTOMER", [C.CustomerNumber]
)
RETURN
SUMX (
FILTER (
CurrentCustomerNumber,
[Date] >= [B.InitialNode]
&& [Date] <= [A.EndNode]
),
[@CUSTOMER]
)
複制
效果如下:
這樣一個可以展示階段的路徑成本就準備完畢了。
那麼,我們現在需要考慮使用者留存的問題,我們需要知道在當日購買的使用者,次日或者第三日依然選擇購買的使用者有多少。
編寫如下路徑成本:
E.FirstDateCustomerNumber =
VAR FirstDateCustomerNumberTable =
ADDCOLUMNS (
SUMMARIZE ( 'Fact_Sale', 'Fact_Sale'[使用者ID], Dim_Date[Date] ),
"@FirstDateCustomerNumber",
VAR FirstDateKey = [Date] + 1
RETURN
CALCULATE ( [C.CustomerNumber], 'Dim_Date'[Date] = FirstDateKey )
)
VAR FirstDateCustomerNumber =
SUMX (
FirstDateCustomerNumberTable,
IF (
[Date] >= [B.InitialNode]
&& [Date] <= [A.EndNode] - 1,
[@FirstDateCustomerNumber]
)
)
RETURN
IF (
[Period] >= 1,
FirstDateCustomerNumber ,
BLANK ()
)
複制
解釋一下代碼含義:
通過定義一張虛拟表,來減少性能的損耗;
添加“@FirstDateCustomerNumber”虛拟列,來計算次日依然購買的新客數量;
“@FirstDateCustomerNumber”虛拟列中使用VAR定義了一個來自虛拟表上下文的變量,通過内部上下文覆寫外部上下文的方式,實作次日人數的計算;
DAX中的部分數字是為了計算間隔天數,部分是為了階梯式呈現;
最後結果輸出,參照上面的邏輯,我們繼續建構其他路徑成本。
F.SecondDateCustomerNumber =
VAR SecondDateCustomerNumberTable =
ADDCOLUMNS (
SUMMARIZE ( 'Fact_Sale', 'Fact_Sale'[使用者ID], Dim_Date[Date] ),
"@SecondDateCustomerNumber",
VAR SecondDateKey = [Date] + 2
RETURN
CALCULATE ( [C.CustomerNumber], 'Dim_Date'[Date] = SecondDateKey )
)
VAR SecondDateCustomerNumber =
SUMX (
SecondDateCustomerNumberTable,
IF (
[Date] >= [B.InitialNode]
&& [Date] <= [A.EndNode] - 2,
[@SecondDateCustomerNumber]
)
)
RETURN
IF (
[Period] >= 2,
SecondDateCustomerNumber ,
BLANK ()
)
複制
與上面路徑成本的差異就是數字參數不同。
這樣的路徑成本,白茶一共建構了7個,假定留存周期7日為一個周期。
我們來看一下效果:
有一點小瑕疵,當某一天沒有值的時候,該路徑成本白茶希望它消失。
添加一張展示使用的次元表:
編寫如下路徑成本:
L.DisplayNumber =
VAR DisplayIndex =
SELECTEDVALUE ( Dim_Display[Index] )
RETURN
SWITCH (
TRUE (),
DisplayIndex = 1, [D.CurrentCustomerNumber],
DisplayIndex = 2, [E.FirstDateCustomerNumber],
DisplayIndex = 3, [F.SecondDateCustomerNumber],
DisplayIndex = 4, [G.ThirdDateCustomerNumber],
DisplayIndex = 5, [H.FourthDateCustomerNumber],
DisplayIndex = 6, [I.FifthDateCustomerNumber],
DisplayIndex = 7, [J.SixthDateCustomerNumber],
DisplayIndex = 8, [K.SeventhDateCustomerNumber],
BLANK ()
)
複制
我們再來看一下效果:
這樣的話我們就解決了路徑成本空值呈現的問題。
我們不光想知道每日留存的客戶數量,我們還想知道留存率,繼續編寫路徑成本。
M.DisplayRetention =
IF (
[L.DisplayNumber] <> BLANK (),
IF (
SELECTEDVALUE ( Dim_Display[Index] ) = 1,
FORMAT ( [L.DisplayNumber], "0" ),
FORMAT ( [L.DisplayNumber] / [D.CurrentCustomerNumber], "0.00%" )
),
BLANK ()
)
複制
效果如下:
這樣使用者留存的核心模型就已經搭建出來了。
将這個故事完善一下,我們需要知道目前完整周期的時間段、完整周期的新客數量、周期結束使用者留存的數量。
編寫如下路徑成本:
完整周期的時間段:
O.FirstCycle =
FORMAT (
IF (
MINX ( ALL ( Dim_Date[Date] ), [Date] ) >= [A.EndNode] - [Period],
MINX ( ALL ( Dim_Date[Date] ), [Date] ),
[A.EndNode] - [Period]
),
"YYYY-MM-DD"
) & "~"
& FORMAT ( [A.EndNode], "YYYY-MM-DD" )
複制
完整周期的新客數量:
P.BeginCycleNumber =
CALCULATE (
[D.CurrentCustomerNumber],
FILTER (
ALLSELECTED ( 'Dim_Date' ),
'Dim_Date'[Date]
= IF (
MINX ( ALL ( Dim_Date[Date] ), [Date] ) >= [A.EndNode] - [Period],
MINX ( ALL ( Dim_Date[Date] ), [Date] ),
[A.EndNode] - [Period]
)
)
)
複制
周期結束使用者留存的數量:
Q.EndCycleNumber =
LASTNONBLANKVALUE ( ALLSELECTED ( Dim_Display[Index] ), [L.DisplayNumber] )
複制
效果如下:
為了美觀,白茶添加了一個配色的路徑成本:
N.DisplayRetentionColor =
VAR CurrentValue =
IF (
SELECTEDVALUE ( Dim_Display[Index] ) = 1,
[L.DisplayNumber],
[L.DisplayNumber] / [D.CurrentCustomerNumber]
)
VAR Color =
IF (
SELECTEDVALUE ( Dim_Display[Index] ) = 1,
"#0D2248",
IF (
[M.DisplayRetention] <> BLANK (),
SWITCH (
TRUE (),
CurrentValue >= 0.8, "#9C0A0D",
CurrentValue >= 0.6, "#C91014",
CurrentValue >= 0.4, "#E64B47",
CurrentValue >= 0.2, "#FE8664",
CurrentValue >= 0, "#FFD2A0"
)
)
)
RETURN
Color
複制
對報表的整體進行調整,最終效果如下:
閑聊幾句:
其實這個分析模型還是可以繼續擴充的,如果我們可以拿到回訪資訊,那麼搭配每個階段的留存率,是可以直接分析出流失的主要原因;
針對遊戲行業,此模型還可以計算連續活躍天數以及最終活躍,擴充度非常的高。
由于時間關系,本期就到這裡了,喜歡的小夥伴可以自行模拟擴充。
小夥伴們❤GET了麼?
(BOSS:哎,還是好難受。)
這裡是白茶,一個PowerBI的初學者。