【Faiss】余弦相似分数等于L2归一化再内积

说明关于余弦相似性的计算

模就是长度的意思

a = [3,4] # a的模是5
b = [5,12] # b的模是13

计算方法1

向量内积/向量的模 = 余弦相似性

(3 ×5 + 4 ×12) / (5 ×13)=0.969

计算方法2

normalize_L2=向量的各自分量/向量的模

a = [3/5,4/5]
b = [5/13,12/13]

normalize_L2 并 向量的内积 -》 余弦相似性

(3/5) ×(5/13 )+( 4/5) × (12/13)= 0.969

如果从式子上看 就是分母通分,两个式子是相同的。


Faiss提供了faiss.METRIC_INNER_PRODUCT 和faiss.METRIC_L2

只需要我们代码加上normalize_L2
IndexIVFFlat在参数选择时,使用faiss.METRIC_INNER_PRODUCT

举例

from faiss import normalize_L2
normalize_L2(xb)
normalize_L2(xq)
nlist=1
quantizer = faiss.IndexFlatL2(d)  # the other index
index = faiss.IndexIVFFlat(quantizer, d, nlist, faiss.METRIC_INNER_PRODUCT)

其他方法对比 

import json
import numpy as np
import datetime
import time
import mkl
from sklearn.metrics.pairwise import cosine_similarity
from faiss import normalize_L2
import faiss
#
def cosine_similarity_custom1(x, y):
    x_y = np.dot(x, y.transpose())
    x_norm = np.sqrt(np.multiply(x, x).sum(axis=1))
    x_norm = x_norm[:, np.newaxis]
    y_norm = np.sqrt(np.multiply(y, y).sum(axis=1))
    y_norm = y_norm[:, np.newaxis]
    result = np.divide(x_y, np.dot(x_norm, y_norm.transpose()))
    return result

def cosine_similarity_custom2(x,y):
    num = x.dot(y.T)
    result = np.linalg.norm(x) * np.linalg.norm(y)
    return num / result



t0 = time.time()
#生成dataset
d = 128#                 # dimension
nb = 1#                  # database size

np.random.seed(1234)             # make reproducible
xb = np.random.random((nb, d)).astype('float32')
xq = np.random.random((nb, d)).astype('float32')
# print(xb)
# print(xq)
result_cosine0 = cosine_similarity(xb,xq)
result_cosine1 = cosine_similarity_custom1(xb,xq)
result_cosine2 = cosine_similarity_custom2(xb,xq)
print('result_cosine0:\n',result_cosine0)
print('result_cosine1:\n',result_cosine1)
print('result_cosine2:\n',result_cosine2)
import numpy as np
from sklearn.metrics.pairwise import cosine_similarity
a=np.array([[3,4]])
b=np.array([[5,12]])
print(cosine_similarity(a,b))


# ===========================================================================


normalize_L2(xb)
normalize_L2(xq)
nlist=1
quantizer = faiss.IndexFlatL2(d)  # the other index
index = faiss.IndexIVFFlat(quantizer, d, nlist,faiss.METRIC_INNER_PRODUCT)

print(index.is_trained)
index.train(xb)
print(index.is_trained)
index.add(xb)                  # add vectors to the index
print(index.ntotal)
k = 1

D, I = index.search(xq, k)     # actual search

print(I)                  
print(D)


参考:

Faiss 相似度搜索使用余弦相似性_faiss 余弦相似度_西西弗Sisyphus的博客-CSDN博客

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值