產(chǎn)品運(yùn)營中Oneid的實(shí)現(xiàn),如何合理標(biāo)識用戶的唯一性?
編輯導(dǎo)語:產(chǎn)品運(yùn)營的基礎(chǔ)是埋點(diǎn),這一過程中要對用戶進(jìn)行唯一性標(biāo)識。為何要對用戶進(jìn)行標(biāo)識?什么是用戶標(biāo)識?如何合理標(biāo)識用戶的唯一性?帶著這些疑問,我們來看看作者的回答。
“平生不修善果,只愛殺人放火。忽地頓開金繩,這里扯斷玉鎖。錢塘江上潮信來,今日方知我是我”,這是魯智深生前在杭州六合寺對自己的人生總結(jié)和一生的感悟。
仿佛在此之前的魯智深處于一種非常混沌的狀態(tài),不清楚自己是誰,像隱匿了自己身份的一個人。直至到了六合寺聽到錢塘江上潮信的瞬間,頓時參透人生真諦,把之前所有的事情關(guān)聯(lián)起來,找到了最真實(shí)的自己。
那么,魯智深的事情與本文要提及的產(chǎn)品運(yùn)營中Oneid的實(shí)現(xiàn)有什么關(guān)系呢?
我們都知道產(chǎn)品運(yùn)營的基礎(chǔ)是埋點(diǎn),埋點(diǎn)中對用戶進(jìn)行唯一性標(biāo)識猶如魯智深在聽到錢塘潮信悟透自己的平生一樣,即在某種場景下觸發(fā)匿名身份的用戶和真實(shí)身份用戶之間的關(guān)聯(lián),進(jìn)而把兩種狀態(tài)下用戶行為歸集為一個用戶,完成用戶的唯一性標(biāo)識。
用戶唯一標(biāo)識,是用戶唯一的身份ID,相同的身份ID,就會被當(dāng)做是相同的一個用戶。在進(jìn)行埋點(diǎn)數(shù)據(jù)采集方案設(shè)計(jì)時,如何對用戶唯一性進(jìn)行標(biāo)識對數(shù)據(jù)準(zhǔn)確性影響較大。
即如何區(qū)分某個用戶是此用戶,而非彼用戶是至關(guān)重要的,因?yàn)槿绻霾坏綄τ脩舻奈ㄒ恍赃M(jìn)行識別,那么凡是涉及到用戶的數(shù)據(jù)將都是不準(zhǔn)確的,比如:累計(jì)用戶量、新增用戶量、活躍用戶量。
因此,選取合適的用戶標(biāo)識對于提高用戶行為分析的準(zhǔn)確性顯得尤為重要,尤其是諸如漏斗、留存、分群等用戶相關(guān)的分析。
在互聯(lián)網(wǎng)高速發(fā)展的今天,我們都在積極主動的融入這個世界,信息在高速流轉(zhuǎn),不再像以前那樣閉塞。
各類互聯(lián)網(wǎng)產(chǎn)品也在以一種前所未有的開放態(tài)度擁抱其用戶,用戶在觸達(dá)一款應(yīng)用時,可以在匿名(非登錄)狀態(tài)下使用應(yīng)用中的大部分功能,此時用戶的匿名ID一般是指設(shè)備ID。
在支付、充值、積分等一些關(guān)鍵的業(yè)務(wù)環(huán)節(jié),應(yīng)用會要求用戶以某種方式進(jìn)行登錄。目前比較常見的登錄方式主要是手機(jī)號,金融、政務(wù)、醫(yī)療、教育相關(guān)的應(yīng)用除手機(jī)號以外,還支持身份證號、卡號等登錄方式,我們稱之為登錄ID,下圖是我們中原銀行手機(jī)銀行登錄界面示例。
目前常見的需要做用戶唯一性標(biāo)識進(jìn)而提升數(shù)據(jù)準(zhǔn)確性的場景大致如下:
比如:用戶A在移動設(shè)備X上使用中原銀行手機(jī)銀行瀏覽并購買了我行的中原如意寶這款年化高、可自主選擇投資期限、比較符合自己投資意愿的理財(cái)產(chǎn)品,購買過程包含匿名訪問、登錄等操作。
一周后,用戶A在另外一個移動設(shè)備Y上登錄我行的手機(jī)銀行查看了其購買的理財(cái)?shù)氖找媲闆r。若不對用戶進(jìn)行唯一性標(biāo)識,埋點(diǎn)數(shù)據(jù)上報的用戶量是2個,而實(shí)際應(yīng)該是1個用戶。
在進(jìn)行埋點(diǎn)方案設(shè)計(jì)時,為了對用戶唯一性進(jìn)行標(biāo)識,需要在方案中寫明如何采集用戶匿名狀態(tài)下的ID(設(shè)備ID)及登錄狀態(tài)下的登錄ID,這里分別以first_id、second_id命名,后續(xù)文中涉及到的first_id、second_id均指匿名ID、登錄ID。
基于采集到的與用戶相關(guān)的first_id與second_id,在行為分析系統(tǒng)后臺通過一定的關(guān)聯(lián)規(guī)則,生成一個能夠唯一標(biāo)識用戶的user_id,在以后的分析過程中,與用戶量有關(guān)的指標(biāo)均以user_id為基礎(chǔ)進(jìn)行統(tǒng)計(jì)分析。
匿名ID即設(shè)備ID,在不同類型的客戶端上有所不同,且同一類型的客戶端上,設(shè)備ID也并非是唯一的。例如 Web 端的 Cookies 有可能被各種安全衛(wèi)士清空,而 iOS 端的 IDFV 在不同廠商的 App 間是不同的。
1)Android端
安卓系統(tǒng)經(jīng)過多次升級,對權(quán)限控制越來越嚴(yán)格,唯一識別手機(jī)的方法也在不斷發(fā)生變化。
Android端適合作為設(shè)備ID標(biāo)識符的有OAID、Android_id、UUID、IMEI,IMEI是最適合做設(shè)備唯一標(biāo)識的,但獲取IMEI需要授予權(quán)限且Android 10以后不再開放IMEI的權(quán)限,App 卸載重裝 UUID會發(fā)生變化。
綜合起來,Android端比較適合作為標(biāo)識符的是Android_id,如果 Android_Id 獲取不到,則獲取隨機(jī)的UUID。
2)iOS端
蘋果系統(tǒng),可用于識別唯一設(shè)備的標(biāo)識不像Andriod那樣多。綜合起來,蘋果系統(tǒng)生成設(shè)備ID的標(biāo)識符先后順序應(yīng)該是IDFA -> IDFV ->UDID,即優(yōu)先獲取IDFA,獲取不到再獲取IDFV,獲取不到時,再獲取UUID。
3)JavaScript
默認(rèn)情況下使用 cookie_id,存貯在瀏覽器的cookie中。
4)微信小程序
一般使用UUID,但是刪除小程序,UUID 會變。為了保證設(shè)備 ID 不變,建議獲取并使用 openid。
如果選擇使用 openid 的話,請注意操作暫存,由于獲取 openid 是一個異步的操作,但是冷啟動事件等會先發(fā)生,所以我們會把先發(fā)生的操作,暫存起來,等獲取到 openid 后才會發(fā)送數(shù)據(jù)。
在介紹用戶標(biāo)識的實(shí)現(xiàn)方法前,先帶大家了解一下,當(dāng)前行為數(shù)據(jù)分析系統(tǒng)數(shù)據(jù)儲存的模型。
目前主流的數(shù)據(jù)儲存模型是用一張events表存儲與用戶相關(guān)的事件,其中event表中有個distinct_id字段,在事件發(fā)生時用戶如處于匿名狀態(tài),則記錄設(shè)備ID,登錄狀態(tài)下記錄登錄ID,用users表用來儲存用戶的匿名ID(設(shè)備ID)、登錄ID、基于關(guān)聯(lián)規(guī)則生成的user_id等用戶屬性。
這樣通過events表和users表,就可以成功的把用戶與事件聯(lián)系在一起。
適用場景:適合沒有用戶注冊體系,或者極少數(shù)用戶會進(jìn)行多設(shè)備登錄的產(chǎn)品,如工具類產(chǎn)品、搜索引擎、部分電商等。
場景舉例:
行為序列說明:
某用戶在華為手機(jī)上新安裝了 App,并進(jìn)行了一系列操作,events表中distinct_id為設(shè)備ID,記為X,分配得到的user_id為1,同時把1、X分別存入users表中的user_id、first_id中。
該用戶進(jìn)行了注冊并登錄,設(shè)備未變,發(fā)送的 distinct_id 仍為 X,user_id仍為1。
該用戶登錄之后繼續(xù)進(jìn)行一系列操作,發(fā)送的 distinct_id 仍 為 X,user_id仍為1。
該用戶把手機(jī)送給朋友了,朋友用自己的賬號登錄設(shè)備 X,發(fā)送的distinct_id 仍為 X,user_id仍為1。
該用戶的朋友一直使用自己的賬號在設(shè)備 X 上進(jìn)行了一系列操作,由于設(shè)備未變,所以user_id仍為1。
該用戶更換了新的小米手機(jī),進(jìn)行一系列操作,此時設(shè)備ID 變?yōu)閅,發(fā)送的 distinct_id 為 Y,分配的user_id為 2,則將user_id 2、設(shè)備ID Y 存入 users 表的 id, first_id 字段。該用戶登錄之后的后續(xù)操作,都會以user_id 2標(biāo)識,只要不更換設(shè)備。
在上述場景中,僅使用設(shè)備 ID 識別用戶的好處就是邏輯很簡單,當(dāng)然局限性也很明顯:
當(dāng)用戶換手機(jī)后,用戶換手機(jī)前后的行為無法關(guān)聯(lián)上。
當(dāng)用戶把手機(jī)送給朋友后,朋友的行為卻仍記在該用戶下。
適用場景:成功關(guān)聯(lián)設(shè)備 ID 和登錄 ID 之后,用戶在該設(shè)備 ID 上或該登錄 ID 下的行為就會貫通,被認(rèn)為是一個user_id發(fā)生的。在進(jìn)行事件、漏斗、留存等用戶相關(guān)分析時也會算作一個用戶。所以一般來說,當(dāng)遇到以下場景時,考慮一對一的關(guān)聯(lián):
需要貫通一個用戶在一個設(shè)備上注冊前后的行為。
需要貫通一個注冊用戶在不同設(shè)備上登錄之后的行為。
場景舉例:
行為序列說明:
某用戶在小米手機(jī)上新安裝了 App,并進(jìn)行了一系列操作,對應(yīng)的設(shè)備ID為 X,事件表中 distinct_id 為 X,對應(yīng)分配的user_id為 1,則將user_id 1、設(shè)備ID X 存入 users 表的user_id,,first_id 字段。
該用戶進(jìn)行了注冊并登錄,其登錄ID為A,事件表中 distinct_id 為A,設(shè)備ID X 和登錄 ID A 關(guān)聯(lián)成功,將登錄ID A存入users 表的 second_id 字段,use_id仍為1。
該用戶登錄后繼續(xù)進(jìn)行一系列操作,事件表中distinct_id為 A,user_id仍為1。
該用戶把手機(jī)送給朋友了,朋友用自己的賬號登錄設(shè)備 X,登錄ID為B,將設(shè)備 ID X與登錄ID B進(jìn)行關(guān)聯(lián),由于 X 已與 A 關(guān)聯(lián),所以此次關(guān)聯(lián)會失敗,同時會分配一個新的user_id 2來標(biāo)識此用戶,并將登錄ID B 同時存入users 表的 first_id 和 second_id 字段(用戶的朋友賬號上之前未關(guān)聯(lián)過別的設(shè)備,且首次登錄設(shè)備關(guān)聯(lián)失敗,則將登錄 ID 同時記錄到 first_id 上),此時又稱自關(guān)聯(lián)。
之后,該用戶的朋友一直使用賬號B在設(shè)備 X 上進(jìn)行了一系列操作,事件表中的 distinct_id為B,后續(xù)會用user_id 2來標(biāo)識此用戶。
該用戶更換了一個新的蘋果手機(jī),并進(jìn)行一系列操作,在未登錄前,用新設(shè)備ID Y來標(biāo)識用戶,events表中的distinct_id 為Y,對應(yīng)分配的user_id為3,將user_id 3 、設(shè)備ID Y 存入 users 表的 id, first_id字段。
該用戶在蘋果手機(jī)上使用賬號A進(jìn)行登錄,此時將嘗試將設(shè)備ID Y與登錄ID A 進(jìn)行關(guān)聯(lián),由于 A 已經(jīng)與 X 關(guān)聯(lián),因此會關(guān)聯(lián)失敗,但是依然會切換到以A 為登錄ID的用戶,其對應(yīng)的user_id為1。
該用戶登錄之后的后續(xù)操作,事件表中的distinct_id 為A,所以仍以user_id 1 標(biāo)識。
在上述場景中,很大程度上已經(jīng)實(shí)現(xiàn)了跨設(shè)備的用戶貫通,但仍存在局限性:
當(dāng)用戶換手機(jī)后,雖然登錄賬號之后的行為與換手機(jī)之前的行為已經(jīng)貫通,但是在新設(shè)備上首次登錄之前的行為仍沒法貫通,仍被識別為新的用戶的行為。
當(dāng)用戶把舊手機(jī)送給朋友之后,由于舊手機(jī)已被關(guān)聯(lián)到自己的登錄ID,無法再與朋友的登錄 ID 關(guān)聯(lián)。后續(xù)使用這臺舊手機(jī)的用戶們,若不登錄就操作應(yīng)用,則都會被識別為同一個用戶(舊手機(jī)成功關(guān)聯(lián)的登錄 ID)。
一對一雖然已經(jīng)實(shí)現(xiàn)了跨設(shè)備的用戶貫通,但是對于某些應(yīng)用場景還是不夠準(zhǔn)確,因此產(chǎn)生了另外一種關(guān)聯(lián)方案,支持一個登錄 ID 綁定多個設(shè)備 ID 的方案,從而實(shí)現(xiàn)更準(zhǔn)確的用戶追蹤。
適用場景:一個用戶在多個設(shè)備上進(jìn)行登錄是一種比較常見的場景,比如 Web 端和 App 端可能都需要進(jìn)行登錄。支持一個登錄 ID 下關(guān)聯(lián)多設(shè)備 ID 之后,用戶在多設(shè)備下的行為就會貫通,被認(rèn)為是一個user_id發(fā)生的。
場景舉例:
行為序列說明:
某用戶在小米手機(jī)上新安裝了 App,并進(jìn)行了一系列操作,對應(yīng)的設(shè)備ID為 X,事件表中 distinct_id 為 X,對應(yīng)分配的user_id為 1,則將user_id 1、設(shè)備ID X 存入 users 表的user_id,,first_id 字段。
該用戶進(jìn)行了注冊并登錄,其登錄ID為A,事件表中 distinct_id 為A,設(shè)備ID X 和登錄 ID A 關(guān)聯(lián)成功,將登錄ID A存入users 表的 second_id 字段,use_id仍為1。
該用戶登錄后繼續(xù)進(jìn)行一系列操作,事件表中distinct_id為A,user_id仍為1。
該用戶把手機(jī)送給朋友了,朋友用自己的賬號登錄設(shè)備 X,登錄ID為B,將設(shè)備 ID X與登錄ID B進(jìn)行關(guān)聯(lián),由于 X 已與 A 關(guān)聯(lián),所以此次關(guān)聯(lián)會失敗,同時會分配一個新的user_id 2來標(biāo)識此用戶,并將登錄ID B 同時存入users 表的 first_id 和 second_id 字段(用戶的朋友賬號上之前未關(guān)聯(lián)過別的設(shè)備,且首次登錄設(shè)備關(guān)聯(lián)失敗,則將登錄 ID 同時記錄到 first_id 上),此時又稱自關(guān)聯(lián)。
之后,該用戶的朋友一直使用賬號B在設(shè)備 X 上進(jìn)行了一系列操作,事件表中的 distinct_id為B,后續(xù)會用user_id 2來標(biāo)識此用戶。
該用戶更換了一個新的蘋果手機(jī),并進(jìn)行一系列操作,在未登錄前,用新設(shè)備ID Y來標(biāo)識用戶,events表中的distinct_id 為Y,對應(yīng)分配的user_id為3,將user_id 3 、設(shè)備ID Y 存入 users 表的 id, first_id字段。
該用戶在蘋果手機(jī)上使用賬號A進(jìn)行登錄,此時將嘗試將設(shè)備ID Y與登錄ID A 進(jìn)行關(guān)聯(lián),關(guān)聯(lián)成功,其對應(yīng)的user_id為依然1,同時將設(shè)備ID Y 添加到 users表中user_id 1 的 $device_id_list 字段。
該用戶登錄之后的后續(xù)操作,事件表中的distinct_id 為A,所以仍以user_id1 標(biāo)識。
后續(xù)的修復(fù)如下:
由于設(shè)備 Y 被關(guān)聯(lián)到登錄 ID A 下,修復(fù)設(shè)備 Y 上登錄之前的數(shù)據(jù):user_id 3 -> user_id 1。
將users表中user_id 3的用戶屬性合并到user_id 1上,并刪除 users 表user_id 3 這條數(shù)據(jù)。進(jìn)行屬性合并時,如果user_id 1的用戶該屬性有值,則不會修改該屬性的值;如果user_id 1 的用戶該屬性沒值,且user_id 3 的用戶該屬性有值,則將對應(yīng)的值合并到user_id 1 的用戶上,并刪除 users 表中user_id 3 這條數(shù)據(jù)。
在上述場景中,真正實(shí)現(xiàn)了跨設(shè)備的用戶貫通,通過修復(fù)解決了方案二中換手機(jī)登錄之前的行為貫通問題,但仍存在局限性:
一個設(shè)備只能關(guān)聯(lián)到一個登錄 ID 下,當(dāng)用戶把舊手機(jī)送給朋友之后,由于舊手機(jī)已被關(guān)聯(lián)到自己的登錄 ID 了,無法再與朋友的登錄 ID 關(guān)聯(lián)。后續(xù)使用這臺舊手機(jī)的用戶們,若不登錄就操作,則都會被識別為同一個用戶(舊手機(jī)成功關(guān)聯(lián)的登錄 ID)。
而事實(shí)上,舊手機(jī)上后續(xù)的匿名登錄很難識別到底是誰,可能歸為匿名登錄之前最近一次登錄的用戶會更合理一些。
綜合起來看,以上三種對用戶唯一性進(jìn)行識別的方案沒有對與錯,在決定采取哪種識別方案時,結(jié)合產(chǎn)品的具體應(yīng)用場景以及埋點(diǎn)復(fù)雜度來選擇合適的方案即可。
作者:中原數(shù)據(jù)老工匠,一名金融科技從業(yè)者;微信公眾號:數(shù)匠筆談
本文由 @中原數(shù)據(jù)老工匠 原創(chuàng)發(fā)布于人人都是產(chǎn)品經(jīng)理。未經(jīng)許可,禁止轉(zhuǎn)載
題圖來自Unsplash,基于CC0協(xié)議
給作者打賞,鼓勵TA抓緊創(chuàng)作!1人打賞