用户画像——标签聚类



转载请注明 AIQ - 最专业的机器学习大数据社区  http://www.6aiq.com

AIQ 机器学习大数据 知乎专栏 点击关注

作者:超人赵,人工智能爱好者社区专栏作者

知乎:

https://www.zhihu.com/people/chao-ji-sai-ya-ren/posts
链接推送: 如何构建用户画像—打用户行为标签
用户画像——数据质量管理

这次想继续和大家聊聊用户画像。用户画像是个体系性比较强的内容模块,分一两次博客也写不完,我争取分多次博客把各个模块都搭建起来。上次把用户画像方面的内容开了一个头,讲了关于标签权重的计算方法,这次就聊聊标签聚类的方法。其实聚类不限于方法和形式,只要能将同类物品 / 内容进行准确聚类的,都是好的方法。好啦,开篇结束啦,下面让我们进入正题吧:

一、应用背景:

继上一篇中提到的用户标签表,存储了用户在平台上每次操作(来自日志数据)、购买(来自业务数据)等行为带来的标签。随着时间的累计,各用户在平台上积累的标签数以亿计,如何对这些不同类型的标签进行归类,找到每个标签所属的某一类别,是本次讲述的重点。

二、标签聚类:

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)下面,看了一下,效果基本上还差不多


更多高质资源 尽在AIQ 机器学习大数据 知乎专栏 点击关注

转载请注明 AIQ - 最专业的机器学习大数据社区  http://www.6aiq.com