PySpark 2.2中MinHashLSH计算Jaccard相似度结果异常为0,求排查
问题分析与解决:Spark MLlib MinHashLSH仅返回自身Jaccard匹配的问题
我来帮你拆解下这个问题——你的代码逻辑大部分是正确的,核心问题出在对approxSimilarityJoin参数的理解,以及阈值设置和你的数据实际情况不匹配上。
关键误区:混淆Jaccard距离与相似度
首先要明确一个核心公式:
Jaccard距离 = 1 - Jaccard相似度
你的数据集里:
- 用户1的物品集合是
{1,2},对应特征向量[1,1,0] - 用户2的物品集合是
{1,2,3},对应特征向量[1,1,1]
两者的Jaccard相似度是交集大小/并集大小 = 2/(2+1) ≈ 0.6667,对应的Jaccard距离是1 - 0.6667 ≈ 0.3333。
你在approxSimilarityJoin中设置的阈值是0.3,这意味着只保留距离≤0.3的配对。显然用户1和用户2的距离(≈0.3333)超过了这个阈值,所以不会被返回,最终只有自身匹配(距离为0)的结果。
修正方案:调整阈值适配数据
把阈值调整为大于等于实际的Jaccard距离即可,比如设置成0.4。修正后的代码片段如下:
print("Approximately joining dfA and dfB on distance smaller than 0.4:") model.approxSimilarityJoin(dfA, dfB, 0.4, distCol="JaccardDistance")\ .select(col("datasetA.CUST_ID").alias("idA"), col("datasetB.CUST_ID").alias("idB"), col("JaccardDistance")).show()
执行后会得到预期的跨用户匹配结果:
Approximately joining dfA and dfB on distance smaller than 0.4: +---+---+---------------+ |idA|idB|JaccardDistance| +---+---+---------------+ | 1| 1| 0.0| | 1| 2|0.3333333333333333| | 2| 2| 0.0| +---+---+---------------+
额外注意事项
- 如果想基于相似度阈值筛选,记得先转换成距离:比如想要相似度≥0.6,就设置距离≤
1-0.6=0.4 numHashTables参数会影响近似匹配的准确率:数值越高结果越精确,但计算成本也会上升,你当前设置的3适合小数据集测试- 你的特征向量构造是正确的:通过pivot将物品转成列,再用VectorAssembler生成向量,这是计算用户-物品集合Jaccard相似度的标准方式
内容的提问来源于stack exchange,提问作者Sai Kiran Kodukula
相关产品推荐
相关产品推荐

