如何限制 Jaccard 项目相似度计算的输入数据?

机器算法验证 分布 数据挖掘
2022-04-06 03:47:40

我正在尝试使用Jaccard(特别是 Tanimoto)在格式的大型数据列表上计算项目相似度

(userid, itemid)

如果我有一个 userid-itemid 对,则该项目被视为已评级。我有大约 80 万用户和 7900 个项目,以及 357 万个“评分”。我已将我的数据限制为对至少 n 个项目(通常是 10 个)进行评分的用户。但是,我想知道是否应该对评级的项目数量设置上限。当用户对 1000 个或更多项目进行评分时,每个用户生成 999000 个项目的成对组合以在我的计算中使用,假设计算

n! / (n-r)!

添加这么多输入数据会大大减慢计算过程,即使工作负载是分布式的(使用 hadoop)。我在想,对很多项目进行评分的用户不是我的核心用户,可能会稀释我的相似度计算。

我的直觉告诉我将数据限制在评分在 10 到 150-200 项之间的客户,但我不确定是否有更好的方法来统计确定这些界限。

以下是有关我的源数据分布的更多详细信息。请随时就我可能已经屠杀的任何统计术语来启发我!

我的用户 itemCounts 的分布: alt text http://www.neilkodner.com/images/littlesnapper/itemsRated.png

> summary(raw)
   itemsRated      
 Min.   :   1.000  
 1st Qu.:   1.000  
 Median :   1.000  
 Mean   :   4.466  
 3rd Qu.:   3.000  
 Max.   :2069.000  

> sd(raw)
itemsRated 
  16.46169 

如果我将数据限制为对至少 10 个项目进行评分的用户:

> above10<-raw[raw$itemsRated>=10,]
> summary(above10)
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
  10.00   13.00   19.00   34.04   35.00 2069.00 
> sd(above10)
[1] 48.64679
> length(above10)
[1] 64764

如果我进一步将我的数据限制为评分在 10 到 150 项之间的用户:

> above10less150<-above10[above10<=150]
> summary(above10less150)
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
  10.00   13.00   19.00   28.17   33.00  150.00 
> sd(above10less150)
[1] 24.32098
> length(above10less150)
[1] 63080

编辑:我不认为这是一个异常值的问题,因为数据是正偏的。

2个回答

我很困惑:你不应该只需要 7900^2 项相似性,你使用所有用户的评分,这仍然很稀疏吗?

更新

我仍然认为有一种更有效的方法可以做到这一点,但也许我只是太密集了。具体来说,考虑项目 A 和项目 B。对于项目 A,生成一个由 0 和 1 组成的 U 维向量,其中 U 是数据集中的用户数,当且仅当用户 i 评分时,维度 i 为 1项目 A。对项目 B 做同样的事情。然后你可以很容易地从这些向量中为你的方程生成 AB、A 和 B 项。重要的是,这些向量非常稀疏,因此如果编码正确,它们可以生成非常小的数据集。

  1. 迭代项目 ID 以生成它们的交叉产品:(ItemAID,ItemBID)
  2. 将此对映射到此 n 元组: (ItemAID, ItemBID, ItemAVector, ItemBVector)
  3. 将此 n 元组简化为您的相似性度量: (ItemAID,ItemBID,SimilarityMetric)

如果您在开始时设置 ItemXVector 的缓存,则此计算应该非常快。

我已经用专门设计用于近似 Jaccard 距离的MinHash解决了类似的问题。想法很简单,使用 MinHash 概率特征将数据分组为更小的组(具有相同的哈希),然后评估组内的成对距离(矩阵的块结构)。最终答案并不准确,但您可以通过更改哈希的深度和数量来控制它与精确的接近程度。