You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在PySpark DataFrame中计算用户间余弦相似度(不使用sklearn)

PySpark计算用户两两余弦相似度(大数据场景)

直接用PySpark内置函数实现,完全适配大数据场景,无需依赖sklearn。具体步骤如下:

1. 转换特征为向量

先把用户的数值特征列合并成向量格式,方便后续计算:

from pyspark.ml.feature import VectorAssembler

# 将val1、val2、val3合并为特征向量列
assembler = VectorAssembler(inputCols=["val1", "val2", "val3"], outputCol="features")
df_features = assembler.transform(df).select("id", "features")

2. 生成不重复用户配对

通过自连接生成所有非重复的用户对,排除自身配对和双向重复配对:

from pyspark.sql import functions as F

# 用a.id < b.id的条件避免重复计算同一对用户
df_pairs = df_features.alias("a").join(df_features.alias("b"), on=(F.col("a.id") < F.col("b.id")), how="inner")

3. 计算余弦相似度

利用PySpark的向量内置函数计算点积、模长,最终得到余弦得分:

# 计算点积、模长并推导余弦相似度
df_similarity = df_pairs.select(
    F.col("a.id").alias("user1"),
    F.col("b.id").alias("user2"),
    F.expr("dot(a.features, b.features)").alias("dot_product"),
    F.expr("norm(a.features, 2)").alias("norm_a"),
    F.expr("norm(b.features, 2)").alias("norm_b")
).withColumn(
    "cosine_similarity",
    F.col("dot_product") / (F.col("norm_a") * F.col("norm_b"))
).select("user1", "user2", "cosine_similarity")

结果示例

执行后输出的结果格式如下(保留三位小数示例):

+------+------+-------------------+
|user1 |user2 |cosine_similarity  |
+------+------+-------------------+
|user1 |user2 |0.998              |
|user1 |user3 |0.997              |
|user1 |user4 |0.999              |
|user2 |user3 |0.999              |
|user2 |user4 |0.999              |
|user3 |user4 |0.999              |
+------+------+-------------------+

关键优化点

  • 用a.id < b.id的连接条件,将计算量减少一半,避免重复计算双向用户对
  • 所有计算基于Spark分布式引擎执行,适配大数据量场景,不会出现单机内存溢出问题

内容的提问来源于stack exchange,提问作者Vignesh A

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.13 18:05:26