簡體   English   中英

Pyspark LSH 后跟余弦相似度

[英]Pyspark LSH Followed by Cosine Similarity

我有很多用戶,每個用戶都有一個關聯的向量。 我想計算每個用戶之間的余弦相似度。 這是基於大小的禁止。 似乎 LSH 是一個很好的近似步驟,我知道這將創建存儲桶,在這種情況下,用戶被映射到同一個存儲桶,它們很可能是相似的。 在 Pyspark 中,以下示例:

from pyspark.ml.feature import BucketedRandomProjectionLSH
from pyspark.ml.linalg import Vectors
from pyspark.sql.functions import col

dataA = [(0, Vectors.dense([1.0, 1.0]),),
         (1, Vectors.dense([1.0, -1.0]),),
         (4, Vectors.dense([1.0, -1.0]),),
         (5, Vectors.dense([1.1, -1.0]),),
         (2, Vectors.dense([-1.0, -1.0]),),
         (3, Vectors.dense([-1.0, 1.0]),)]
dfA = ss.createDataFrame(dataA, ["id", "features"])

brp = BucketedRandomProjectionLSH(inputCol="features", outputCol="hashes", bucketLength=1.0, numHashTables=3)
model = brp.fit(dfA)
model.transform(dfA).show(truncate=False)


+---+-----------+-----------------------+
|id |features   |hashes                 |
+---+-----------+-----------------------+
|0  |[1.0,1.0]  |[[-1.0], [0.0], [-1.0]]|
|1  |[1.0,-1.0] |[[-2.0], [-2.0], [1.0]]|
|4  |[1.0,-1.0] |[[-2.0], [-2.0], [1.0]]|
|5  |[1.1,-1.0] |[[-2.0], [-2.0], [1.0]]|
|2  |[-1.0,-1.0]|[[0.0], [-1.0], [0.0]] |
|3  |[-1.0,1.0] |[[1.0], [1.0], [-2.0]] |
+---+-----------+-----------------------+

任何關於如何最好地設置 bucketLength 和 numHashTables 的指針都值得贊賞。

假設我有上面的 3 個哈希表,如果有超過 1 個,我如何確定每個桶中的桶來計算余弦相似度? 我假設在此任務中使用 LSH 是按“哈希”列中的值進行分組,並且只在每個列中執行成對相似性。 這個對嗎?

我假設在此任務中使用 LSH 是按“哈希”列中的值進行分組,並且只在每個列中執行成對相似性。 這個對嗎?

的,LSH 使用一種方法來降低維度,同時保持相似性。 它將您的數據散列到存儲桶中。 然后僅比較最終位於同一存儲桶中的項目。(計算距離)

神奇之處在於調整存儲桶和散列函數的數量,以減少誤報和漏報的數量。 沒有固定的數字,這取決於您的數據。

r是您的存儲桶大小, b是要使用的哈希函數的數量(或者您將用於檢測匹配的存儲桶數量。

這篇幫助我了解發生了什么的文章。

假設您的簽名矩陣有 100 行。 考慮兩種情況:

b1 = 10 → r = 10

b2 = 20 → r = 5

在第二種情況下,2 個 [向量] 至少出現在同一個存儲桶中的機會更高,因為它們有更多的機會(20 對 10)並且比較簽名的元素更少(5 對 10)

如果您需要加入,您可以使用: approxSimilarityJoin並設置可接受的distance (這是您需要調整的另一個參數,距離是已落入至少一個哈希桶的向量之間的距離,使它們可能彼此靠近。)

distance = 300

model.approxSimilarityJoin(df, df2, distance, distCol="EuclideanDistance").select(
    col("datasetA.id").alias("idA"),
    col("datasetB.id").alias("idB"),
    col("EuclideanDistance")).show()

您可以通過查看數據(來自連接)或使用approxNearestNeighbors來了解向量之間的距離的合理性。 如果您想要 10 個最近的鄰居,您可以通過以下方法找到距離:

NumberOfNeigthbors = 10
CandidateVector = Vectors.dense([1.0, 2.0])
model.approxNearestNeighbors(df2, CandidateVector, NumberOfNeigthbors).collect()
[Row(id=4, features=DenseVector([2.0, 2.0]), hashes=[DenseVector([1.0])], distCol=1.0)]

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM