Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/apache-spark/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Spark Python:如何计算RDD中每一行之间的Jaccard相似性?_Python_Apache Spark_For Loop_Pyspark_Pairwise - Fatal编程技术网

Spark Python:如何计算RDD中每一行之间的Jaccard相似性?

Spark Python:如何计算RDD中每一行之间的Jaccard相似性?,python,apache-spark,for-loop,pyspark,pairwise,Python,Apache Spark,For Loop,Pyspark,Pairwise,我有一个大约50k行和2列的表。您可以将每一行视为一部电影,列视为该电影的属性——“ID”:该电影的ID,“Tags”:该电影的一些内容标签,以每部电影的字符串列表的形式出现 数据如下所示: 电影("浪漫","喜剧","英语"),; 电影2,[《动作》、《功夫》、《中国人》] 我的目标是首先根据每部电影对应的标签计算出它们之间的jacquard相似性,一旦计算完成,我将能够知道每部电影(例如,我选择了Movie_1),与这部电影(本例中为Movie_1)最相似的前5部电影是什么。我想要的结果不仅

我有一个大约50k行和2列的表。您可以将每一行视为一部电影,列视为该电影的属性——“ID”:该电影的ID,“Tags”:该电影的一些内容标签,以每部电影的字符串列表的形式出现

数据如下所示:

电影("浪漫","喜剧","英语"),; 电影2,[《动作》、《功夫》、《中国人》]

我的目标是首先根据每部电影对应的标签计算出它们之间的jacquard相似性,一旦计算完成,我将能够知道每部电影(例如,我选择了Movie_1),与这部电影(本例中为Movie_1)最相似的前5部电影是什么。我想要的结果不仅是电影1本身的前五名,而且是所有电影的前五名

我已经尝试使用Python来解决这个问题,但是运行时在这里是一个很大的挑战。即使我使用多处理,在6个内核上运行,总运行时间仍然超过20小时

Python代码如下:

将熊猫作为pd导入
从收款进口柜台
将numpy作为np导入
来自多处理导入池
导入时间
col_name=['movie_id','tag_name']
df=pd.read\u csv(“movies.csv”,name=col\u name)
movie_id=df['movie_id'].tolist()
标签列表=df['tag\u name'].tolist()
def jaccard_相似性(string1、string2):
交叉点=集合(string1)。交叉点(集合(string2))
并集=集合(字符串1)。并集(集合(字符串2))
返回长度(交叉)/浮动(长度(联合))
def jc_结果(电影id):
结果=计数器()
此索引=电影id.index(电影id)
对于电影\u id中的另一个\u id:
该索引=电影id.index(另一个id)
如果另一个\u id==电影\u id:
持续
其他:
tag_1=tag_列表[此索引]
tag_2=tag_列表[该索引]
jaccard=jaccard\u相似性(标签1、标签2)
结果[(电影id,另一个id)]=jaccard
返回结果。最常见(10)
来自多处理导入池
游泳池=游泳池(6)
结果={}
对于电影id中的电影id:
结果[movie\u id]=池。应用异步(jc\u结果,args=(movie\u id,)
pool.close()
pool.join()
对于电影id,res in results.items():

results[movie_id]=res.get()
您可以尝试类似的解决方案,但由于您的数据已经标记化(字符串列表),因此不需要执行该步骤或ngram步骤

我还要提到pyspark中的approxSimilarityJoin计算的是Jaccard距离,而不是Jaccard相似度,但是如果您特别需要,您可以从1中减去以转换回相似度

您的代码最终看起来类似于:

from pyspark.ml import Pipeline
from pyspark.ml.feature import HashingTF, MinHashLSH
import pyspark.sql.functions as f

db = spark.createDataFrame([
        ('movie_1', ['romantic','comedy','English']),
        ('movie_2', ['action','kongfu','Chinese']),
        ('movie_3', ['romantic', 'action'])
    ], ['movie_id', 'genres'])


model = Pipeline(stages=[
        HashingTF(inputCol="genres", outputCol="vectors"),
        MinHashLSH(inputCol="vectors", outputCol="lsh", numHashTables=10)
    ]).fit(db)

db_hashed = model.transform(db)

db_matches = model.stages[-1].approxSimilarityJoin(db_hashed, db_hashed, 0.9)

#show all matches (including duplicates)
db_matches.select(f.col('datasetA.movie_id').alias('movie_id_A'),
                 f.col('datasetB.movie_id').alias('movie_id_B'),
                 f.col('distCol')).show()

#show non-duplicate matches
db_matches.select(f.col('datasetA.movie_id').alias('movie_id_A'),
                 f.col('datasetB.movie_id').alias('movie_id_B'),
                 f.col('distCol')).filter('movie_id_A < movie_id_B').show()

你找到解决这个问题的方法了吗?我也在寻找类似的问题。请让我知道,如果你找到任何解决方案this@AnilKumar请在下面查看我的答案。你能解释一下numHashTables表示什么以及为什么选择10吗?@ShirinYavari此链接对此有很好的解释:。总之,我选择了10个有点随意。10表示代码将从每个记录创建10个独立的minhash值,然后approxSimilarityJoin将比较每行的10个值,以查看每行中有多少相同或不同,从而得出相似性分数。如果选择小于10,则行之间计算的相似度将不太准确,如果选择大于10,则会更准确。非常感谢您的解释和链接。我一定会调查的。
+----------+----------+-------+
|movie_id_A|movie_id_B|distCol|
+----------+----------+-------+
|   movie_3|   movie_3|    0.0|
|   movie_1|   movie_3|   0.75|
|   movie_2|   movie_3|   0.75|
|   movie_1|   movie_1|    0.0|
|   movie_2|   movie_2|    0.0|
|   movie_3|   movie_2|   0.75|
|   movie_3|   movie_1|   0.75|
+----------+----------+-------+

+----------+----------+-------+
|movie_id_A|movie_id_B|distCol|
+----------+----------+-------+
|   movie_1|   movie_3|   0.75|
|   movie_2|   movie_3|   0.75|
+----------+----------+-------+