使用者畫像之標籤聚類
使用者畫像是個體系性比較強的內容模組,分一兩次部落格也寫不完,我爭取分多次部落格把各個模組都搭建起來。上次把使用者畫像方面的內容開了一個頭,講了關於標籤權重的計算方法,這次就聊聊標籤聚類的方法。其實聚類不限於方法和形式,只要能將同類物品 / 內容進行準確聚類的,都是好的方法。好啦,開篇結束啦,下面讓我們進入正題吧:
一、應用背景:
繼上一篇中提到的使用者標籤表,儲存了使用者在平臺上每次操作(來自日誌資料)、購買(來自業務資料)等行為帶來的標籤。隨著時間的累計,各使用者在平臺上積累的標籤數以億計,如何對這些不同型別的標籤進行歸類,找到每個標籤所屬的某一類別,是本次講述的重點。
二、標籤聚類:
Step1:從使用者標籤表抽取資料
使用者標籤表結構長這個樣子(字醜 ╥﹏╥)
首先從使用者標籤表抽取兩種型別的標籤(我們暫命名為A類標籤和B類標籤),
建立臨時表1,抽取A類標籤:
create table gdm.tag_relation_cluster_function_01 as select user_id, org_id, org_name, cnt, date_id, tag_type_id, act_type_id from wedw.peasona_user_tag_relation --使用者標籤表 where date_id >='2017-01-01' and date_id <='2017-08-24' and tag_type_id in (1) -- A 類標籤 group by user_id, org_id, org_name, cnt, date_id, tag_type_id, act_type_id
建立臨時表2,抽取B類標籤:
create table gdm.tag_relation_cluster_function_02 as select user_id, org_id, org_name, cnt, date_id, tag_type_id, act_type_id from wedw.peasona_user_tag_relation --使用者標籤表 where date_id >='2017-01-01' and date_id <='2017-08-24' and tag_type_id in (7) -- B 類標籤 group by user_id, org_id, org_name, cnt, date_id, tag_type_id, act_type_id
Step2:計算每類標籤對應的使用者人數
這裡用到了共現矩陣的思想,即兩個標籤上同時擁有的使用者人數。即使用者甲身上既有A類標籤,又有B類標籤則記為數字1,兩兩標籤之間擁有的使用者數越多,說明使用者在平臺上的行為在帶來A類標籤的同時也帶來了B類標籤,即兩個標籤之間的相關性越大。在HQL中的邏輯如圖:
建立臨時表3,計算A類標籤下每個標籤對應的使用者人數:
create table gdm.tag_relation_cluster_function_03 as select org_id, org_name, count(distinct user_id) user_num, row_number() over (order by count(distinct user_id) desc) rank from gdm.tag_relation_cluster_function_01 group by org_id, org_name
建立臨時表4,計算B類標籤下每個標籤對應的使用者人數:
create table gdm.tag_relation_cluster_function_04 as select org_id, org_name, count(distinct user_id) user_num, row_number() over (order by count(distinct user_id) desc) rank from gdm.tag_relation_cluster_function_02 group by org_id, org_name
建立臨時表5,計算A、B兩類標籤共同關注人數的共現矩陣:
create table gdm.tag_relation_cluster_function_05 as select t.org_id_1, t.org_name_1, t.tag_type_id_1, t.org_id_2, t.org_name_2, t.tag_type_id_2, t.num from ( select t1.org_id as org_id_1, t1.org_name as org_name_1, t1.tag_type_id as tag_type_id_1, t2.org_id as org_id_2, t2.org_name as org_name_2, t2.tag_type_id as tag_type_id_2, count(distinct t2.user_id) as num from gdm.tag_relation_cluster_function_01 t1 cross join gdm.tag_relation_cluster_function_02 t2 --on t1.user_id = t2.user_id where t1.org_id <> t2.org_id group by t1.org_id, t1.org_name, t1.tag_type_id, t2.org_id, t2.org_name, t2.tag_type_id ) t
Step3:用餘弦相似度函式計算兩兩標籤之間的相關性
餘弦相似度函式怎麼用,這裡簡單舉個例子:標籤a打在了10000個使用者身上,標籤b打在了20000個使用者身上,有5000個使用者的身上同時使用者a標籤和b標籤,則a、b標籤之間的相似度即為:5000 / sqrt(10000*20000).在HQL語言中執行如下:
create table gdm.tag_relation_cluster_function_06 as select t1.org_id_1 as org_id_1, --標籤a id t1.org_name_1 as org_name_1, --標籤a名稱 t1.tag_type_id_1 as tag_type_id_1, --標籤a type_id t2.user_num_1 as user_num_1, --標籤a 人數 t1.org_id_2 as org_id_2, t1.org_name_2 as org_name_2, t1.tag_type_id_2 as tag_type_id_2, t3.user_num_2 as user_num_2, t1.num as num, -- 同時有兩個標籤的使用者數 (t1.num/sqrt(t2.user_num_1 * t3.user_num_2)) as power, row_number() over(order by (t1.num/sqrt(t2.user_num_1 * t3.user_num_2)) desc) rank from gdm.tag_relation_cluster_function_05 t1 left join (select org_id, user_num as user_num_1 from gdm.tag_relation_cluster_function_03 --標籤a 對應的使用者人數 ) t2 on t1.org_id_1 = t2.org_id left join (select org_id, user_num as user_num_2 from gdm.tag_relation_cluster_function_04 --標籤b 對應的使用者人數 ) t3 on t1.org_id_2 = t3.org_id group by t1.org_id_1, t1.org_name_1, t1.tag_type_id_1, t2.user_num_1, t1.org_id_2, t1.org_name_2, t1.tag_type_id_2, t3.user_num_2, t1.num, (t1.num/sqrt(t2.user_num_1 * t3.user_num_2))
Step4:篩選出與每個A類標籤相關性最大的B類標籤,即將該A類標籤歸類到該B類標籤下:
HQL中通過row_number()方法將權重最大的B類標籤置頂,然後篩選出,語句執行如下:
create table gdm.tag_relation_cluster_function_07 as select org_id_1, org_name_1, tag_type_id_1, org_id_2, org_name_2, tag_type_id_2, power from (select org_id_1, org_name_1, tag_type_id_1, org_id_2, org_name_2, tag_type_id_2, power, row_number() over(partition by org_id_1,org_name_1,tag_type_id_1 order by power desc) row_id from gdm.tag_relation_cluster_function_06 ) t1 where t1.row_id=1
最後,在實際應用中,我將疾病類標籤(ort_name_1)歸類到對應的科室(ort_name_2)下面,看了一下,效果基本上還差不多