向量检索/向量相似性计算方法(持续更新ing...)

诸神缄默不语-个人优快云博文目录

本文介绍各种用于向量检索的向量相似性计算方法,将会简单介绍各种方法的优缺点等信息,并用toy example给出代码示例。

1. 余弦相似度

使用sklearn.metrics.pairwise.cosine_similarity实现。
最终得到的值会在[-1,1]之间。

API官方文档:sklearn.metrics.pairwise.cosine_similarity — scikit-learn 1.1.2 documentation
对计算公式的介绍:https://scikit-learn.org/stable/modules/metrics.html#cosine-similarity

计算公式:
k ( x , y ) = x y ⊤ ∥ x ∥ ∥ y ∥ k(x, y) = \frac{x y^\top}{\|x\| \|y\|} k(x,y)=x∥∥yxy

计算一组向量之间的两两相似度,代码撰写方法:

from sklearn.metrics.pairwise import cosine_similarity
cos_sim_matrix = cosine_similarity(train_feature)
#入参是一个二维矩阵,每行是一个样本特征

2. 线性核(点积)

2.1 sklearn实现

使用sklearn.metrics.pairwise.linear_kernel实现。

API官方文档:sklearn.metrics.pairwise.linear_kernel — scikit-learn 1.1.2 documentation

计算公式:
k ( x , y ) = x ⊤ y k(x, y) = x^\top y k(x,y)=xy

3. 向量检索

解决方案

  1. Faiss包:L2和/或点积向量。速度飞快
    原理:聚合键,基于簇中心查找邻居
    facebookresearch/faiss: A library for efficient similarity search and clustering of dense vectors.
  2. annoy库:可以在大规模数据上检索(200W条已试可用)
    spotify/annoy: Approximate Nearest Neighbors in C++/Python optimized for memory usage and loading/saving to disk
    pip install annoy
    示例代码:
#用TFIDF做向量(一个做文本表征的示例),然后用annoy算法计算相似度

#TFIDF部分
from sklearn.feature_extraction.text import TfidfVectorizer

tfidf=TfidfVectorizer(max_features=500)
sp_tfidf=tfidf.fit_transform(corpus)  #corpus是一个文本列表

#annoy部分
from annoy import AnnoyIndex
from tqdm import tqdm

#存储
f=sp_tfidf.shape[1]  # Length of item vector that will be indexed

t = AnnoyIndex(f, 'angular')
for i in tqdm(range(len(corpus))):
    t.add_item(i, sp_tfidf[i].toarray().squeeze())  #第2个元素是一个数组

t.build(10) # 10 trees
t.save('存储路径.ann')

#调用
u = AnnoyIndex(f, 'angular')
u.load('存储路径.ann') # super fast, will just mmap the file
print(u.get_nns_by_item(0, 1000)) # will find the 1000 nearest neighbors
#返回值是向量的索引
#如果用get_nns_by_vector的话第一个入参就改成向量,如sp_tfidf[0].toarray().squeeze()

理论和术语

  1. 单调性

4. 排序

一般来说顺序是先检索(返回一个集合)然后再排序

  1. 拟合回归模型并计算MSE
    参考资料:Recommending movies: ranking | TensorFlow Recommenders
  2. Listwise ranking
    参考资料:Listwise ranking | TensorFlow Recommenders

5. 向量存储(向量数据库)

  1. VBASE

其他参考资料

  1. 我还没看:
    1. 最近邻搜索(NN)、最大内积搜索(MIPS)与(A)LSH算法 - 知乎
    2. ChatGPT盛行的当下,向量数据库为大模型配备了一个超级大脑
    3. (2021 NeurIPS) SPANN: Highly-efficient Billion-scale Approximate Nearest Neighbor Search
    4. (2020 SIGIR) ColBERT: Efficient and Effective Passage Search via Contextualized Late Interaction over BERT
    5. facebookresearch/contriever: Contriever: Unsupervised Dense Information Retrieval with Contrastive Learning
    6. (2023 TMLR) Unsupervised Dense Information Retrieval with Contrastive Learning
### 感知哈希技术的工作原理 感知哈希(Perceptual Hash, pHash)是一种用于比较两个数据对象相似性的算法。它通过提取输入数据的关键特征并将其转换为固定长度的指纹来实现这一目标[^1]。pHash 的主要应用领域包括图像检索、音频匹配以及视频分析。 #### 工作流程概述 以下是感知哈希的核心工作流: 1. **预处理阶段**: 输入的数据通常会经过一系列标准化操作,比如调整大小、灰度化或者降噪等。这些步骤旨在减少不必要的细节干扰,从而突出重要特性[^2]。 2. **特征提取**: 这一步骤涉及从原始数据中抽取有意义的信息片段。对于图片来说,可能采用离散余弦变换 (DCT),而针对声音文件则可能是梅尔频率倒谱系数(MFCC)[^3]。 3. **量化与压缩**: 提取出的高维向量会被进一步简化成低维度表示形式——即所谓的“hash value”。此过程不仅降低了存储需求还提高了计算效率[^4]。 4. **距离测量**: 当两份资料被转化为它们各自的 hash 值之后,就可以利用汉明距离(Hamming Distance)或其他适当的方法衡量两者之间的差异程度。较小的距离意味着更高的相似性水平[^5]。 下面给出了一张简单的流程图表描述上述四个部分如何串联起来形成完整的 perceptual hashing 流程: ```plaintext +-------------------+ | Input Data | +---------+--------+ | Preprocessing --> Feature Extraction --> Quantization & Compression --> | ^ v | +---------------------------------------------+ | | Calculate Hamming Distance Between Hashes |<------+ +---------------------------------------------+ ``` 请注意以上只是一个抽象概念模型,在实际开发过程中每步的具体实施方案可能会依据具体应用场景有所变化。 ### Python 实现示例 这里提供了一个基于 PIL 和 numpy 库的小型 python 脚本作为演示用途,该脚本能生成给定图像对应的 dHash(difference hash): ```python from PIL import Image import numpy as np def compute_dhash(image_path): image = Image.open(image_path).convert('L').resize((9,8),Image.ANTIALIAS) pixels = list(image.getdata()) diff_bits = [] width,height= image.size for row in range(height): for col in range(width-1): left_pixel_index =row*width +col right_pixel_index=row*width+(col+1) if pixels[left_pixel_index]>pixels[right_pixel_index]: bit='1' else: bit='0' diff_bits.append(bit) return ''.join(diff_bits) if __name__ == "__main__": img_hash = compute_dhash("example.jpg") print(f"The difference hash of the example image is {img_hash}.") ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

诸神缄默不语

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值