首页 > 解决方案 > 在python中使用余弦相似度将向量与其他向量进行比较的快速方法?预计算矩阵?LSH 哈希?

问题描述

我正在研究一个需要相似性度量来从更大的集合中提取数据子集以进行进一步分析的问题。

我提取子集的方法是使用高于某个阈值的余弦相似度。下面的玩具套装描述了这个问题:

import numpy as np
import pandas as pd
from sklearn.metrics.pairwise import cosine_similarity

df = pd.DataFrame(np.random.normal(0, 1, (10, 10)))

该矩阵给出了 10 个“样本”与 10 个“特征”的相似性:

similarity_df = pd.DataFrame(cosine_similarity(df))

(例如,比较热图如下所示): 在此处输入图像描述 给定一个新向量:

new_vector = np.array([1.0, 0.49, -0.05, 0.36, -1.0, -1.8, 0.21, 0.31, 0, -1])

我发现使用此功能的相似之处:

def find_similarity(df, search):
    rankings = []
    for i in range(len(df)):
        sim = int(100*cosine_similarity(search.reshape(1,-1), df.iloc[i].values.reshape(1,-1))[0][0])
        rankings.append((i, sim))
    df= pd.DataFrame(rankings)
    df.columns = ['item', 'similarity']
    df.sort_values(by='similarity', inplace=True, ascending=False)
    df.reset_index(drop=True, inplace=True)
    return df

然后返回最相似的项目,高于阈值:

r = find_similarity(df, new_vector)
r[r['similarity']>50]

这很好用,我遇到的问题是我的数据集有超过 100 万行乘 200 列,并且similarity_df 是 100 万乘 100 万。不用说,我的 for 循环中的顺序比较很慢。

for i in range(len(df)):
    sim = int(100*cosine_similarity(search.reshape(1,-1), df.iloc[i].values.reshape(1,-1))[0][0])

由于我需要一次找到大约 100 个向量的相似性,这使情况更加复杂。

有没有更快的方法来做这个搜索/排名?也许是最大化相似性(而不是最小化共谋)的散列函数,例如 LSH?虽然我使用的是余弦相似度,但也许另一个相似度指标做得更好,但现在的问题是一种更快的方法来进行一对多比较。

标签: pythonnumpyscikit-learnlsh

解决方案


推荐阅读