深度乾貨 | 多維分析中的 UV 與 PV
1. 概念
1.1 UV 與 PV
對於網際網路產品來說,UV 與 PV 是兩個非常常見的指標,並且通常都是分析的最基礎指標。UV 一般來講,是指使用產品(或產品某個功能)的獨立使用者數。PV 則來源於網站時代,一般指網站(或網站某個頁面)的頁面瀏覽量,在移動網際網路時代,則一般會引申表示使用產品(或產品某個功能)的使用者行為或者使用者運算元量。
PV 和 UV 一般而言是互相影響,一起變化的,對於 PV 和 UV 的變化與數字的解讀,也是一門很深的學問。由於本文主要是介紹在多維分析中 UV 和 PV 的計算規則,所以,對於 PV 和 UV 的具體解讀與分析,不做展開論述。
1.2 多維分析
多維分析是在 BI(Business Intelligence)領域廣泛使用的一種分析技術和分析方法,能夠從不同的角度,靈活動態地進行分析。
多維分析中有“指標”和“維度”兩個基本概念,在這裡,我們用一個實際的例子來進行描述。
一個典型的網站,它可能需要從地域、終端、App 版本這三個角度,來考察自己的 PV 和 UV 的情況。那麼,在這個場景下,維度有三個,分別是地域、終端和 App 版本;指標則是兩個,分別是 PV 和 UV。所謂的多維分析,就是可以在維度的任意組合情況下,來看對應的指標的數值:可以看北京的,iOS端的,7.1 版 App 的 PV 和 UV;也可以看湖北的安卓端的 PV 和 UV;也可以看 7.2 版 App 的 PV 和 UV。具體設定查詢條件的時候,維度可以是三個,可以是兩個,也可以是一個。從這個例子可以看出,多維分析是非常靈活的,具有很強的分析能力,可以充分滿足分析人員對於產品的各種細粒度的分析需求。
而為了能夠讓多維分析發揮出更大的價值,一般情況下,都是希望多維分析的查詢結果能夠在一分鐘能就得到,從而可以讓使用者不停地調整查詢條件,快速地驗證自己的猜想。
2. “可加”與“不可加”
正如上面提到的,多維分析對於查詢速度非常敏感,業內也有很多專門的儲存和查詢方案。
而在具體的實現中,有一種最為常見的實現手段,就是把各個維度的所有取值組合下的指標全部預先計算並且儲存好,這種一般可以稱作事實表。然後在具體進行多維查詢的時候,再根據維度的選擇,掃描相對應的資料,並聚合得到最終的查詢條件。
此時,會發現一個比較有意思的問題,就是 PV 這類指標,是“可加”的,而 UV 這類指標,則是“不可加”的。例如,我們把昨天三個維度的可能組合下的所有的 PV 和 UV 都計算並且儲存好,如下表所示:
地域 | 終端 | App 版本 | PV | UV |
---|---|---|---|---|
北京 | 安卓 | 7.1 | 9762 | 743 |
北京 | 安卓 | 7.2 | 7263 | 531 |
北京 | iOS | 7.1 | 6549 | 623 |
北京 | iOS | 7.2 | 5386 | 423 |
湖北 | 安卓 | 7.1 | 29767 | 1437 |
湖北 | 安卓 | 7.2 | 27368 | 1315 |
湖北 | iOS | 7.1 | 22594 | 1236 |
湖北 | iOS | 7.2 | 25368 | 1432 |
那麼,對於 PV 這種指標,是可以通過掃描對應的記錄,然後累加得到最終的結果。例如,我們想分析整個湖北的 PV,則可以把湖北相關的四條記錄中的 PV,累加起來就是整個湖北的 PV 值。
但是,對於 UV 這類指標,卻不能簡單的累加,因為,這個指標並不是在每一個維度上都是正交的。例如,同一個使用者可能先後使用了不同的 App 版本,甚至於有一定機率使用了不同的終端,所以,UV 並不能簡單地累加,通常情況下,真實的 UV 是比加起來的值更小的。
因而,對於 UV 這類不可累加的指標,需要使用其它的計算方案。
3. UV 計算的常見方案
UV 型別的指標,有三種常見的計算方案,我們在這裡分別進行介紹。
3.1 估算方案
所謂的估算方案,就是在上面的表格的基礎上,不再額外記錄更多細節,而是通過估算的方式來給出一個接近真實值的 UV 結果,常見的演算法有很多,例如 HyperLogLog 等。
由於畢竟是估算,最終估算的結果有可能與真實值有較大差異,因此只有一些統計平臺可能會採用,而如我們 Sensors Analytics 之類的以精細化分析為核心的分析系統並不會採用,因此在這裡不做更多描述。
3.2 擴充事實表,以存代算
所謂以存代算,就是在預先計算事實表的時候,將所有需要聚合的結果,都算好。
依然以上面的例子來說明,如果我們想以存代算,預先做完聚合,類似於 Hive 所提供的group by with cube
操作。在擴充完畢後,之前那個表的結果就應該是:
地域 | 終端 | App 版本 | PV | UV |
---|---|---|---|---|
北京 | 安卓 | 7.1 | 9762 | 743 |
北京 | 安卓 | 7.2 | 7263 | 531 |
北京 | iOS | 7.1 | 6549 | 623 |
北京 | iOS | 7.2 | 5386 | 423 |
湖北 | 安卓 | 7.1 | 29767 | 1437 |
湖北 | 安卓 | 7.2 | 27368 | 1315 |
湖北 | iOS | 7.1 | 22594 | 1236 |
湖北 | iOS | 7.2 | 25368 | 1432 |
地域 | 終端 | App 版本 | PV | UV |
---|---|---|---|---|
北京 | 28960 | 1995 | ||
湖北 | 105115 | 4570 | ||
安卓 | 74160 | 4026 | ||
iOS | 59897 | 3510 | ||
7.1 | 68672 | 3321 | ||
7.2 | 65385 | 3079 | ||
北京 | 安卓 | 17025 | 1097 | |
北京 | iOS | 11935 | 989 | |
湖北 | 安卓 | 57135 | 2563 | |
湖北 | iOS | 47962 | 2477 | |
北京 | 7.1 | 6549 | 1233 | |
北京 | 7.2 | 12649 | 907 | |
湖北 | 7.1 | 52361 | 2577 | |
湖北 | 7.2 | 52736 | 2601 | |
安卓 | 7.1 | 39529 | 2011 | |
安卓 | 7.2 | 34631 | 1778 | |
iOS | 7.1 | 29143 | 1801 | |
iOS | 7.2 | 30754 | 1772 | |
北京 | 安卓 | 7.1 | 9762 | 743 |
北京 | 安卓 | 7.2 | 7263 | 531 |
北京 | iOS | 7.1 | 6549 | 623 |
北京 | iOS | 7.2 | 5386 | 423 |
湖北 | 安卓 | 7.1 | 29767 | 1437 |
湖北 | 安卓 | 7.2 | 27368 | 1315 |
湖北 | iOS | 7.1 | 22594 | 1236 |
湖北 | iOS | 7.2 | 25368 | 1432 |
從這個表我們可以看出,假設一共三個維度,每個維度有兩個取值,則之前的事實表一共是 2*2*2=8
條記錄,而現在,則擴充到了 3*3*3-1=26
條記錄,整個規模擴充了很多,會帶來更多的儲存和預計算的代價。
3.3 從最細粒度資料上掃描
之前提出的擴充事實表的方式,的確可以解決多維分析中指標聚合的問題,除此之外,還有一種方案,則是在事實表上,將使用者ID
也做為一個維度,來進行儲存,此時就不需要儲存 UV 了,如下表所示:
地域 | 終端 | App 版本 | PV | UV |
---|---|---|---|---|
北京 | 安卓 | 7.1 | 9762 | 743 |
北京 | 安卓 | 7.2 | 7263 | 531 |
北京 | iOS | 7.1 | 6549 | 623 |
北京 | iOS | 7.2 | 5386 | 423 |
湖北 | 安卓 | 7.1 | 29767 | 1437 |
湖北 | 安卓 | 7.2 | 27368 | 1315 |
湖北 | iOS | 7.1 | 22594 | 1236 |
湖北 | iOS | 7.2 | 25368 | 1432 |
地域 | 終端 | App 版本 | PV | UV |
---|---|---|---|---|
北京 | 28960 | 1995 | ||
湖北 | 105115 | 4570 | ||
安卓 | 74160 | 4026 | ||
iOS | 59897 | 3510 | ||
7.1 | 68672 | 3321 | ||
7.2 | 65385 | 3079 | ||
北京 | 安卓 | 17025 | 1097 | |
北京 | iOS | 11935 | 989 | |
湖北 | 安卓 | 57135 | 2563 | |
湖北 | iOS | 47962 | 2477 | |
北京 | 7.1 | 6549 | 1233 | |
北京 | 7.2 | 12649 | 907 | |
湖北 | 7.1 | 52361 | 2577 | |
湖北 | 7.2 | 52736 | 2601 | |
安卓 | 7.1 | 39529 | 2011 | |
安卓 | 7.2 | 34631 | 1778 | |
iOS | 7.1 | 29143 | 1801 | |
iOS | 7.2 | 30754 | 1772 | |
北京 | 安卓 | 7.1 | 9762 | 743 |
北京 | 安卓 | 7.2 | 7263 | 531 |
北京 | iOS | 7.1 | 6549 | 623 |
北京 | iOS | 7.2 | 5386 | 423 |
湖北 | 安卓 | 7.1 | 29767 | 1437 |
湖北 | 安卓 | 7.2 | 27368 | 1315 |
湖北 | iOS | 7.1 | 22594 | 1236 |
湖北 | iOS | 7.2 | 25368 | 1432 |
地域 | 終端 | App 版本 | 使用者ID | PV |
---|---|---|---|---|
北京 | iOS | 7.1 | 23231 | 2 |
北京 | iOS | 7.1 | 46297 | 3 |
... | ... | ... | ... | ... |
甚至更進一步,我們將 PV 數值也進一步展開,對於使用者的每一個行為,都保留一條資料,如下表:
地域 | 終端 | App 版本 | PV | UV |
---|---|---|---|---|
北京 | 安卓 | 7.1 | 9762 | 743 |
北京 | 安卓 | 7.2 | 7263 | 531 |
北京 | iOS | 7.1 | 6549 | 623 |
北京 | iOS | 7.2 | 5386 | 423 |
湖北 | 安卓 | 7.1 | 29767 | 1437 |
湖北 | 安卓 | 7.2 | 27368 | 1315 |
湖北 | iOS | 7.1 | 22594 | 1236 |
湖北 | iOS | 7.2 | 25368 | 1432 |
地域 | 終端 | App 版本 | PV | UV |
---|---|---|---|---|
北京 | 28960 | 1995 | ||
湖北 | 105115 | 4570 | ||
安卓 | 74160 | 4026 | ||
iOS | 59897 | 3510 | ||
7.1 | 68672 | 3321 | ||
7.2 | 65385 | 3079 | ||
北京 | 安卓 | 17025 | 1097 | |
北京 | iOS | 11935 | 989 | |
湖北 | 安卓 | 57135 | 2563 | |
湖北 | iOS | 47962 | 2477 | |
北京 | 7.1 | 6549 | 1233 | |
北京 | 7.2 | 12649 | 907 | |
湖北 | 7.1 | 52361 | 2577 | |
湖北 | 7.2 | 52736 | 2601 | |
安卓 | 7.1 | 39529 | 2011 | |
安卓 | 7.2 | 34631 | 1778 | |
iOS | 7.1 | 29143 | 1801 | |
iOS | 7.2 | 30754 | 1772 | |
北京 | 安卓 | 7.1 | 9762 | 743 |
北京 | 安卓 | 7.2 | 7263 | 531 |
北京 | iOS | 7.1 | 6549 | 623 |
北京 | iOS | 7.2 | 5386 | 423 |
湖北 | 安卓 | 7.1 | 29767 | 1437 |
湖北 | 安卓 | 7.2 | 27368 | 1315 |
湖北 | iOS | 7.1 | 22594 | 1236 |
湖北 | iOS | 7.2 | 25368 | 1432 |
地域 | 終端 | App 版本 | 使用者ID | PV |
---|---|---|---|---|
北京 | iOS | 7.1 | 23231 | 2 |
北京 | iOS | 7.1 | 46297 | 3 |
... | ... | ... | ... | ... |
地域 | 終端 | App 版本 | 使用者ID | 時間 | 事件 |
---|---|---|---|---|---|
北京 | iOS | 7.1 | 23231 | 2015-01-01 12:03:08.934 | 瀏覽商品 |
北京 | iOS | 7.1 | 23231 | 2015-01-01 12:04:08.934 | 提交訂單 |
... | ... | ... | ... | ... | ... |
雖然這樣一來,需要儲存的資料規模有了數量級上的擴充,並且所有的聚合計算都需要在多維分析查詢的時候再掃描資料並進行聚合,儲存和計算代價都提高了很多,看似是一種很無所謂的舉措。
但是,相比較之前的方案,它卻有一個最大的好處,也即是因為有了最細粒度的使用者行為資料,才有可能計算事件級別的漏斗、留存、回訪等,才有可能在這些資料的基礎之上,進一步做使用者畫像、個性化推薦等等。而這也正是目前 Sensors Analytics 所採用的資料儲存方案,也正因為採用了這種儲存方案,我們才能夠將自己成為精細化使用者行為分析系統,才能夠滿足使用者的最細粒度資料分析和獲取的需求。
在這樣一個數據儲存方案的基礎上,為了提高資料查詢的效能,一般的優化思路有采用列儲存加壓縮的方式減少從磁碟中掃描的資料量,採用分散式的方案提高併發掃描的效能,採用應用層快取來減少不同查詢的公共掃描資料的量等等,這方面的內容我們會在後面的文章裡面做進一步的探討,盡請期待。