我正在尝试计算user_id
用户表中的给定表与电影表中的另一个表之间的余弦相似度,以便挑选出最相似的电影来推荐。
余弦相似度:=dot(a,b) / (norm(a) * norm(b))
或dot(a,b)/sqrt((dot(a)*dot(b))
df = self.given_user.crossJoin(self.movies_df)
df = df.select('userId', 'movieId', 'user_features', 'movie_features')
df = df.rdd.map(lambda x: (x[0], x[1], x[2], x[3], float(np.dot(np.array(x[2]), np.array(x[3]))))).toDF(df.columns + ['dotxy'])
df = df.rdd.map(lambda x: (x[0], x[1], x[2], x[3], x[4], float(np.dot(np.array(x[2]), np.array(x[2]))))).toDF(df.columns + ['dotxx'])
df = df.rdd.map(lambda x: (x[0], x[1], x[2], x[3], x[4], x[5], float(np.dot(np.array(x[3]), np.array(x[3]))))).toDF(df.columns + ['dotyy'])
output = df.withColumn('cosine_sim', F.col("dotxy") / F.sqrt(F.col("dotxx") * F.col("dotyy")))
output.select('userId', 'movieId', 'dotxy', 'dotxx', 'dotyy', 'cosine_sim').orderBy('cosine_sim', ascending=False).show(5)
结果输出如下所示:
+------+-------+-----+-----+-----+----------+
|userId|movieId|dotxy|dotxx|dotyy|cosine_sim|
+------+-------+-----+-----+-----+----------+
| 18| 1430| 1.0| 0.5| 2.0| 1.0|
| 18| 2177| 1.0| 0.5| 2.0| 1.0|
| 18| 1565| 1.0| 0.5| 2.0| 1.0|
| 18| 415| 1.0| 0.5| 2.0| 1.0|
| 18| 1764| 1.0| 0.5| 2.0| 1.0|
+------+-------+-----+-----+-----+----------+
PySpark 1.6中是否存在更有效/更紧凑的余弦相似度函数实现方式?
您可以使用更多numpy
功能。
import numpy as np
df = spark.createDataFrame([(18, 1, [1, 0, 1], [1, 1, 1])]).toDF('userId','movieId','user_features','movie_features')
df.rdd.map(lambda x: (x[0], x[1], x[2], x[3], float(np.dot(np.array(x[2]), np.array(x[3])) / (np.linalg.norm(np.array(x[2])) * np.linalg.norm(np.array(x[3])))))).toDF(df.columns + ['cosine_sim']).show()
+------+-------+-------------+--------------+------------------+
|userId|movieId|user_features|movie_features| cosine_sim |
+------+-------+-------------+--------------+------------------+
| 18| 1| [1, 0, 1]| [1, 1, 1]|0.8164965809277259|
+------+-------+-------------+--------------+------------------+
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句