Sql 蜂窝中的Jaccard相似性计算

Sql 蜂窝中的Jaccard相似性计算,sql,hive,Sql,Hive,我的数据如下: CustomerId Category 100 2 100 2 100 3 100 6 100 4 200 3 200 6 200 7 300 2 所以我想要的输出是: Jaccard(100200)=2(共享项)/5(项的并集) Jacca

我的数据如下:

CustomerId   Category
  100            2
  100            2
  100            3
  100            6
  100            4
  200            3
  200            6
  200            7
  300            2
所以我想要的输出是:

  • Jaccard(100200)=2(共享项)/5(项的并集)
  • Jaccard(100300)=1(共享项)/4(项的并集)
  • Jaccard(200300)=0(项目共享)/4(项目并集)
我最初尝试的是找到术语的并集和交集,但我不确定这是否是最有效的方法。另外,我希望避免像Jaccard(100300)和Jaccard(300100)这样的重复出现在一起。有人能帮忙吗

     select t1.customer_id, t2.customer_id,
              sum(case when t1.category_id = t2.category_id then 1 else 0 end) intersection,
sum(case when t1.category = t2.category then 1
         when t1.category <> t2.category then 1 else 0 end)
union
    from t t1 cross join
         t t2
  Where t1.customer_id <> t2.customer_id
    group by t1.customer_id, t2.customer_id
选择t1.customer\u id,t2.customer\u id,
求和(t1.category\u id=t2.category\u id然后为1或0结束时的情况)交点,
总和(t1.category=t2.category时的情况,然后为1
当t1.category t2.category时,则为1,否则为0结束)
联盟
从t1交叉连接
t2
其中t1.customer\u id t2.customer\u id
按t1.customer\u id分组,t2.customer\u id分组

不幸的是,我还检查了一位客户是否购买了同一类别的多个商品。因此,我编辑了该表,以反映Customer 100在类别2中有两个项目。但是,它不应更改Jaccard相似性度量值。

您不需要交叉连接。通过计算一对的不同类别id的总和并从中减去相交的类别id来获得分母

SELECT t1.customer_id AS id1,
       t2.customer_id AS id2,
       1.0*sum(CASE WHEN t1.category_id = t2.category_id THEN 1 ELSE 0 END)
     / (count(DISTINCT t1.category_id)+count(DISTINCT t2.category_id)-sum(CASE WHEN t1.category_id = t2.category_id THEN 1 ELSE 0 END)) AS jaccard_similarity
FROM t t1
JOIN t t2 ON t1.customer_id<t2.customer_id
GROUP BY t1.customer_id, t2.customer_id
如果您只需要跨对的交叉点计数,下面的查询就足够了

select t1.customer_id as id1, t2.customer_id as id2
,sum(case when t1.category_id = t2.category_id then 1 else 0 end) as intersection
from t t1 
join t t2 on t1.customer_id<t2.customer_id
group by t1.customer_id, t2.customer_id
选择t1.customer\u id作为id1,t2.customer\u id作为id2
,求和(当t1.category\u id=t2.category\u id然后为1或0结束时的情况)作为交点
从t1开始

在t1.customer_id上加入t2,因此(100200)的相似性应为2/5..而不是2/4..correct?使用
t1.customer_id
;这避免了
(100100)
(300100)
。我不知道是否为您添加了任何内容-可能不会。在Hive中,上述内容不起作用,因为非相等连接不起作用什么不起作用?连接中的不平等?我用一个
交叉连接编辑了答案。应该可以。是的,我想我可以在where条件下使用交叉连接?问题是在我的情况下,Jaccard相似度实际上大于1,因为我有同一个客户购买多个项目。我想交叉口的计算不准确。@vkaul11。。我对答案进行了编辑,以便每对只计算不同的项目。这应该会产生预期的结果。
select t1.customer_id as id1, t2.customer_id as id2
,sum(case when t1.category_id = t2.category_id then 1 else 0 end) as intersection
from t t1 
join t t2 on t1.customer_id<t2.customer_id
group by t1.customer_id, t2.customer_id
SELECT t1.customer_id AS id1,
       t2.customer_id AS id2,
       1.0*COUNT(DISTINCT CASE WHEN t1.category_id = t2.category_id THEN t1.category_id END)
       / (COUNT(DISTINCT t1.category_id)+COUNT(DISTINCT t2.category_id)
         -COUNT(DISTINCT CASE WHEN t1.category_id = t2.category_id THEN t1.category_id END)) AS jaccard_similarity
FROM t t1
CROSS JOIN t t2 
WHERE t1.customer_id<t2.customer_id
GROUP BY t1.customer_id, t2.customer_id