作者 | 王富森
一、問題思考
在流量分析型產品的用戶分析模塊中,留存、互訪、新老客構成等數據都是有效衡量用戶粘性與促活召回的關鍵性指標;但是,我們發現在很多流量運營的業務場景中,留存分析建模都顯著存在著設計和計算上的諸多問題,例如:各種歷史庫版本迭代的高額運維與存儲成本、暴力計算、頻繁計算、數據冷啟動等問題。總結下來,有三個方面需要特別關注:
1.場景理解:在非常多的業務場景中,模型研發人員偏向于通過構建用戶粒度的全量歷史庫,再去聚合用戶的新老標簽或歷史累計次數,但關鍵問題是,在這些場景中基于歷史行為計算的新老客標簽和歷史累計指標,并不適用于該業務場景下的精細化運營。比如,在用戶增長領域的流失召回等場景策略中,長周期外仍然未有回訪的用戶顯然不具備再運營的潛質(如180天等);那么,相比基于歷史庫圈選新用戶,改為基于動態滑動窗口的圈選策略,更具有可運營的潛質和解釋性;并且,這種計算模式還可以有效地規避歷史庫回刷與冷啟動問題。
2.計算模式:在計算模型的設計和模式構建上,大多數同學普遍缺少模型抽象與精細化設計。就累計去重指標或周期留存指標的計算實現來講,大致有4種建模范式(想知道第5種請繼續看下去):
- 歷史庫方式:基于T+1全量和當日增量構建全量歷史庫,基于歷史庫再聚合
- 輕度聚合后再聚合:構建T+1的輕度聚合模型,多周期掃描再聚合
- 歷史周期計拉鏈:以固定時間窗口方式構建用戶標簽表,計算時關聯標簽表再聚合
- 位圖模式計算:以滑動時間窗口方式構建用戶標簽表,并以位圖存儲窗口周期信息
3.模型易用:以上模型的實現都存在一定的研發成本,需要有豐富的場景實踐和經驗積累。如果能夠沉淀一套敏捷的標準化模型計算組件,讓新人可以在分鐘級就完成留存模型的智能研發,那么,就能以標準化的建模范式解決很多業務場景下的建模研發的效率問題。
此外,豐富的場景實踐和持續的技術思考對于建模范式的演進都是非常重要的。在某個節點之前,我們曾認為位圖設計已經是最優實踐了,但是之后又在業務實踐中發現很多場景中需要計算更長業務周期的用戶新老標簽或留存分析。這時候,由于基于二進制bigint存儲的位圖只能支持到64位,在180天等長周期留存計算時就會溢出,因此,就需要更加通用且高效的模型計算抽象。總之,能夠高效支撐業務是最好的實踐標準,驅動我們可以在建模范式上是不斷超越和顛覆。
二、用戶故事
螞蟻版生意參謀是面向支付寶商家的重要對客產品,當時在20年12月份底,我們計劃在2月份全量上線B站,留給研發的時間非常吃緊。而由于是對客產品,在架構設計、數據質量、產出時效等各個方面都有更高標準的要求。此外,我們也必須基于新的數據資產架構對螞蟻生意參謀的產品數據體系進行全盤的重構與升級。其中,流量模塊就涉及到了上文中提到的留存/互訪/新老等關鍵指標的各類計算,我們需要在短時間內快速消化和解決存量的應用層鏈路中存在的很多問題。而最終我們通過用戶留存的建模組件,以“重設計、快實現”的方式,在不到2天的時間內就高效完成了小程序、生活號和電子名片等整體數據鏈路的重構與升級,而且在模型設計、模型存儲和模型治理等方面,也取得了很多核心改變。特別是,經過模型重構后,生意參謀的產品數據體系變得異常精簡、收斂和高效。那么,我們是怎么做到的呢?接下來,我們就詳細介紹留存建模組件的設計思路。
三 、設計實現
- 目標抽象:用戶留存模型的建模抽象與組件構建(支持超過64位圖的1/7/30/180天等周期性PV-UV、留存、互訪、新老客等指標的一站式計算);
- 解決問題:存在大量的暴力掃描、低效計算、高昂歷史回刷成本、數據冷啟動等問題,而高效的留存模型的設計和研發門檻高(位圖計算方式等)、缺少標準化的模型沉淀;
- 解決方案:提煉窗口滑動計算的建模范式、沉淀留存建模組件,顯著提升研發效率(0.5人日),支持留存/互訪/新老客等一站式計算;
1.模型抽象
- 維度抽象:用戶留存模型是典型的輕度聚合模型DWS,顯然要有聚合維度列。
- 設計抽象:滑動窗口設計:首先需要記錄時間窗口內的用戶行為分布(UV或PV),并通過某種數據結構來保存(如bit的Long值存儲或者是Array);其次要設計好窗口滑動的更新邏輯;
- 信息抽象:關鍵聚合信息,如新客的判斷(N+1的時間窗口內,第N天首次訪問就是新用戶);last_date的數值化信息保留(累計多少天未訪問,有效減少存儲);累計訪問天數(支持訪問天數分布的人群分析);
2.模型組件
建模組件的設計就是將模型抽象的結果參數化與模板化實現,具體實現細節不詳述。
組件名 | 使用場景 | 提效結果 | 核心改變 |
用戶留存模型 | 生意參謀等1/7/30/180天PV-UV、留存、互訪、新老、交叉留存矩陣等指標的一站式計算 | 研發提效提效前:0.5人日提效后:2 Min | 新人也可以毫無門檻地建模研發 |
Dataworks任務節點參考:
- 節點ID:發布后的ODPS任務節點號
- 節點名稱:留存模型的表名(可自定義指定)
- 節點類型:ODPS SQL
節點任務配置:
jar -classpath 云端文件/res?id=xxx 類名.tools.OdpsCltWrapper
"--class" <留存模型的jar包>
"--properties-file" 云端文件/res?id=xxx
"--conf" <spark配置文件>
"--conf" "spark.executor.extraJavaOptions=-Dfile.encoding=UTF-8 -Dsun.jnu.encoding=UTF-8"
"--conf" "spark.driver.extraJavaOptions=-Dfile.encoding=UTF-8 -Dsun.jnu.encoding=UTF-8"
"--master" yarn-cluster
云端文件/res?id=xxx "--rTable" <輸入表的表名> "--wTable" <輸出表的表名: 即構建的留存模型> "--stat_date" ${bizdate} "--window" 180;
3.下游使用
基于留存建模組件,基礎的模型結構和計算范式都是標準且統一的,能夠在一個參數化邏輯中一站式實現所有指標的計算,非常便捷;而下游相關的數據模型也變得異常精簡、收斂和高效。
通過參數化視圖統一封裝指標的一體化計算邏輯,下游不需要關注計算中的復雜邏輯,直接面向消費,簡潔易用,如:
--報表引用
insert overwrite table <留存矩陣_接口表> partition (dt='${bizdate}')
select spm,
date_row,
date_col,
retn_vst_uv_1d
from 留存矩陣分析_參數化視圖(留存模型table_name,'20211208')
where spm = 'XXX'
;
--計算引用
insert overwrite table <留存概覽_接口表> partition (dt='${bizdate}')
select vst_uv_1d,vst_uv_7d,vst_uv_30d,fst_uv_1d,retn_vst_uv_matrix,...
from 基礎留存分析_參數化視圖(留存模型table_name,'20211208')
where spm = 'XXX'
;
四、簡要總結
核心改變:基于模型組件,可高效構建用戶留存模型(0.5人日降低至2分鐘),且支持超過64位圖的留存/互訪/新老指標的標準化計算、避免下游多周期掃描與重復計算,尤其相比歷史庫表可減少4倍存儲(前:62字節 vs 后后:16字節)。
建標準:構建了基于滑動窗口實現的標準化留存模型,實現模型設計和數據計算上的改進,有效解決了歷史庫版本迭代的高額運維與存儲成本、下游的多周期掃描、頻繁計算和歷史庫冷啟動等一系列問題。
提效率:研發效率顯著提升(分鐘級實現用戶流量模型的標準化構建),讓我們在及實現。
提效率:30min左右即可完成100億的留存模型計算。
降存儲:相比歷史庫設計可有效降低4倍存儲、且信息更完備。