是否可以使用 LSH Spark 实现算法来查找句子相似度?我的数据集中有大约16k行,这大约是16k * 16k = 256000 所有行之间不同选项的数量,其中必须计算相似距离,并且这个数字每天都会增加。我首先在计算tfidf后使用nltk,pymorphy2,gensim库进行一些预处理,最后将 idf 稀疏数据应用到LSH算法中。
这是我数据的结构
当我使用我的代码时,
def LSH(Pred_Factors):
brp = BucketedRandomProjectionLSH(inputCol="idf", outputCol="hashes",
bucketLength=1.0, numHashTables=10)
model = brp.fit(Pred_Factors)
Hashed_Factors = model.transform(Pred_Factors)
sim_table = model.approxSimilarityJoin(Hashed_Factors, Hashed_Factors, #hashes computes anyway
threshold=1.2, distCol="EuclideanDistance") \
.select(col("datasetA").alias("idA"),
col("datasetB").alias("idB"),
col("EuclideanDistance")).cache()
return sim_table
sim_table = LSH(tfidf)
由于数据量巨大而无法计算相似性(稀疏数据对于LSH来说是如此巨大,但在某些观点上它可以但需要20分钟,95-100%CPU和3gb内存)。我甚至将分区数量从200更改为1000,并且它没有显着帮助。希望我发现LSH可以在不转换的情况下使用稀疏数据。有(我知道唯一有效的方法)轻轻地做到这一点 - >计算 idf的总和。
##UDF SUM
sum_ = udf(lambda v: float(v.values.sum()))
idf_sum = tfidf('idf_sum', sum_('idf'))
然后我可以使用idf的总和并将其应用于LSH并且一切都很好。可能有人建议更好的方法,或者只是说这是使用LSH计算大量文本行之间的欧几里得相似性的正常方法,我知道余弦相似性更好用于此目的但Spark只实现了Jaccard(Minhash) )&欧几里得LSH算法的相似之处。也许MinHash可以缓解计算压力?
P.S我想留在火花中,感谢任何帮助,建议,建议:)