1、构建训练数据和测试数据
import numpy as np
d = 64
nb = 100000
nq = 10000
np.random.seed(1234)
# 产生0-1之间的随机数,xb为100000*64数组,每个值在0-1之间
xb = np.random.random((nb, d)).astype('float32')
# np.arange()为从0开始,步长为1,截止到100000-1,一个长度为100000的数组
# xb[:, 0]=xb[:, 0]+np.arange(nb)
# 最终得到的xb[:, 0]为一个长度为100000的数组,值是0-1随机数+[0,1,2,3...99999]
xb[:, 0] += np.arange(nb) / 1000.
xq = np.random.random((nq, d)).astype('float32')
xq[:, 0] += np.arange(nq) / 1000.
上面我们构建了shape为[100000,64]的训练数据xb和shape为[10000,64]的查询数据xq
对于xb和xq的第一列进行了差异化的处理
2、构建索引
import faiss
index = faiss.IndexFlatL2(d)
print(index.is_trained)
index.add(xb)
print(index.ntotal)
faiss创建索引是为了对向量进行预处理,提高查询效率
IndexFlatL2是通过L2 欧式距离进行计算
创建索引时必须指定向量的维度d
大部分索引需要训练这一步,但是IndexFlatL2跳过这一步,默认索引为训练好的
当索引创建并训练好之后,我们就可以用add和search方法了
add方法是添加训练时的样本
output
True
100000
3、查找搜索
k = 4
D, I = index.search(xq, k)
print(D.shape)
print(I.shape)
print(I[:5])
print(D[-5:])
search方法主要是寻找相似向量,基于索引便可以进行k近邻查询了,结果矩阵为xq*k,其中第i行表示第i个查询向量,每行包含k个最近邻的ID,同时会返回相同维度的距离矩阵,可以看到距离依次递增
output
(10000, 4)
(10000, 4)
[[ 381 207 210 477]
[ 526 911 142 72]
[ 838 527 1290 425]
[ 196 184 164 359]
[ 526 377 120 425]]
[[6.5315704 6.97876 7.0039215 7.013794 ]
[4.335266 5.2369385 5.3194275 5.7032776]
[6.072693 6.5767517 6.6139526 6.7323 ]
[6.637512 6.6487427 6.8578796 7.0096436]
[6.2183685 6.4525146 6.548767 6.581299 ]]
网友评论