一種計算使用者留存的方法
使用者留存分析是網際網路時代常用的一種資料分析方法。而很多快速發展的公司並沒有相應的方法論沉澱,這就導致了在計算使用者留存的時候會出現下面的一些問題:1)使用者留存的定義不明確,不同的研發有自己的理解;2)沒有保留計算過程的中間表,資料可複用程度低;3)不同研發的開發習慣不同,導致計算過程和表設計不統一。
鑑於以上問題, 本文將指出一種通用的使用者留存定義,並提供通用的計算流程以及具體的表結構設計。
0x01 簡介
使用者留存在不同的業務場景有不同的定義方式,比如說使用者註冊留存和使用者活躍留存等。雖說定義方式不同,但大致思路和計算方式基本相同,本文將以使用者活躍留存為例進行說明。
使用者留存分析一般會分析兩個指標:使用者留存數和使用者留存率。以 2048年05月12日 的留存分析為例,
-
20480512的次日留存數 = 20480512日活躍使用者 交集 20480513日的活躍使用者數
-
20480512的次日留存率 = 20480512的次日留存數/20480512的總活躍數
在留存分析中,除了次日留存以外,最常用的分析指標是3日留存、7日留存和30日留存。其中7日留存和30日留存可以理解為是周留存和月留存。下面是具體的定義:
3日留存率 = (第1日活躍的使用者,在第3日還活躍的使用者數)/第1日的活躍使用者數 7日留存率 = (第1日活躍的使用者,在第7日還活躍的使用者數)/第1日的活躍使用者數 30日留存率 = (第1日活躍的使用者,在第30日還活躍的使用者數)/第1日的活躍使用者數
0x02 計算
首先說一下使用者留存的 計算難點 在哪裡。使用者留存計算的時候,每天要重新整理之前日期的資料,比如說今天數2048年5月30號,那我們今天要算出這幾個指標:20480530當天活躍使用者數,20480529的1日留存數,20480527的3日留存數,20480523的7日留存數,以及20480430的30日留存數。並且,這些資料要分別放到對應那一天的報表裡面。這就要求我們每天的任務要更新歷史某天的資料項。
基於上面說的難點,我們做如下設計。我們講使用者留存的計算設計分為三部分:資料流設計、表結構設計和通用程式碼設計。
一、資料流和表結構
資料流和表結構可以放在一起討論,為了簡單說明,我設計了最簡單能說明觀點的表結構。
如下圖,是整個計算流程,我們設計了兩張表:使用者留存中間表和使用者留存報表。注意一下使用者留存表中的type欄位,它表示的使用者留存的型別,看註釋可知每個取值的含義。
我們設計使用者留存中間表的原因是這樣可以將中間表提供給資料分析使用,方便用該表和各種資料做交集使用者,因此保留了uid的粒度。
使用者留存報表使用這種豎表的設計方式,主要是為了考慮每天要修改歷史資料的原因。如果用橫表(即多個欄位分別表示使用者當日活躍、1日留存、7日留存等資料),那每天就要重新重新整理多天資料分割槽中的所有資料,使用豎表則會減少很多的計算量並且更容易維護,只需在報表系統中將豎錶轉成橫表展示即可。
二、通用程式碼設計
按照上面的設計,我們可以設計一套十分簡單的程式碼來計算留存,比如1日、3日、7日和30日留存,可以用同一套程式碼完成,只要傳入引數不同即可。如下是留存中間表的核心程式碼邏輯,報表的邏輯類似就不再展示。
程式碼清單1:留存計算通用程式碼
def _rt_sql(cur_date, user_type): ''' user_type:留存型別,0表示當天活躍,1表示次日留存 ''' start_date = dateDelta(cur_date, user_type*-1) # start_date 表示的n日留存的那一天的日期。 sql = ''' insert overwrite table table_name partition(p_{start_date}, p_{user_type}) select {start_date} as ds, {user_type} as user_type, p_0.uid from 使用者活躍天表 partition(p_{start_date}, p_0) p_0 -- 當時的活躍 join 使用者留存中間表 partition(p_{cur_date}) p_now -- 今天活躍 on p_0.uid = p_now.uid '''.format(cur_date=cur_date, user_type=str(user_type), start_date=start_date) exec_sql(sql)## 封裝了執行sql的程式碼
程式碼清單2:整體計算邏輯
def _run(cur_date): _user_act_sql(cur_date) ## 計算當日活躍的使用者,程式碼就不再寫了 _rt_sql(cur_date, 1) ## 1日留存 _rt_sql(cur_date, 3) ## 3日留存 _rt_sql(cur_date, 7) ## 7日留存 _rt_sql(cur_date, 30) ## 30日留存
OK,通用程式碼就是這麼簡單。整體也就是幾十行程式碼的量。
0xFF 總結
使用者留存是資料分析常用而且十分簡單有效的一種分析方法,但是很多公司對於留存的定義和計算方式都沒有形成自己的方法論。
比如說留存的定義,有的資料分析理解為連續留存,以7日留存為例,那麼7日留存的計算邏輯是第一日活躍,後7日內凡事有活躍的使用者都算是7日留存。而另外一些資料分析就會用我們本文中提的 使用者點留存 ,即只看第7天當天十分活躍。 然後再輔助於使用者流失和迴流等指標一同分析。
計算邏輯同樣如此,不同的研發在計算留存的時候也使用了不同的方式,這就導致了最終提供給業務方或者其它研發的表十分不宜用。
因此本文指出一種常用且比較通用的使用者留存計算方式,並提供一套可行的留存計算通用程式碼,旨在提高開發和資料分析效率,保證資料口徑的一致和資料的易用。