当前位置:   article > 正文

faiss的简单使用_faiss的python库使用

faiss的python库使用

   Faiss全称(Facebook AI Similarity Search)是Facebook AI团队开源的针对聚类和相似性搜索库,为稠密向量提供高效相似度搜索和聚类,支持十亿级别向量的搜索,是目前较成熟的近似近邻搜索库。
     它包含多种搜索任意大小向量集(备注:向量集大小由RAM内存决定)的算法,以及用于算法评估和参数调整的支持代码。
Faiss用C++编写,并提供与Numpy完美衔接的Python接口。除此以外,对一些核心算法提供了GPU实现。

faiss的安装

  1. pip install faiss-cpu==1.7.3
  2. # pip install faiss-gpu==1.7.2

上面的是使用cpu的版本,如果使用GPU可以安装下面语句

faiss的创建步骤

  1. 获取向量文件或者向量库。
  2. 创建faiss的索引index,(训练)将向量添加到索引index中。
  3. 使用faiss进行检索。

  代码及目录结构 github

获取向量文件或者向量库

向量文件存储在item_vec.txt中, 格式是(商品ID,向量),具体结构是下图中展示。

   读取向量文件,返回向量的matrix,由于faiss必须处理np.array的形式,所以进行转换,商品id的一个列表,商品id和序列号的键值对。

  1. import faiss
  2. import os
  3. import sys
  4. import numpy as np
  5. # 从文件中读取向量
  6. """
  7. fea_v_matrix: np.array形式的特征向量矩阵
  8. fea_s_list: id的顺序列表
  9. key_d: id和位置的对应dict
  10. """
  11. def load_fea_from_file(fname):
  12. line_num = 0
  13. fea_s_list = list()
  14. fea_v_list = list()
  15. key_d = dict()
  16. idx = 0
  17. with open(fname, "r", encoding="utf-8", errors="replace") as f:
  18. for row_content in f:
  19. line_num += 1
  20. try:
  21. raw_content_list = row_content.strip().split()
  22. fea_s = raw_content_list[0]
  23. fea_v = np.array(raw_content_list[1:]).astype(np.float32)
  24. except Exception as e:
  25. sys.exit("fail to load file vector")
  26. if fea_s not in key_d:
  27. key_d[fea_s] = idx
  28. idx += 1
  29. fea_s_list.append(fea_s)
  30. fea_v_list.append(fea_v)
  31. fea_v_matrix = np.array(fea_v_list)
  32. return fea_v_matrix, fea_s_list, key_d

创建索引

  检索索引使用的方式可以查看文档,此处创建了一个精度索引refine,提高检索的精度。

  1. def build_index_fun(path):
  2. # path : './item_vec.txt'
  3. fv_mat, fea_s_list, key_d = load_fea_from_file(path)
  4. # cluster_num 是聚类的数量
  5. M = fv_mat.shape[1] // 4
  6. cluster_num = int(fv_mat.shape[0]) // 14
  7. # metric_type
  8. metric_type = faiss.METRIC_INNER_PRODUCT
  9. # 创建索引
  10. index = faiss.index_factory(fv_mat.shape[1], f"IVF{cluster_num},PQ{M}x4fs", metric_type)
  11. # 正则化矩阵特征向量
  12. faiss.normalize_L2(fv_mat)
  13. # 训练索引
  14. index.train(fv_mat)
  15. # 索引添加矩阵向量
  16. index.add(fv_mat)
  17. # 创建一个精度索引, 它细化了距离计算,并根据这些距离对结果重新排序
  18. index_refine = faiss.IndexRefineFlat(index, faiss.swig_ptr(fv_mat))
  19. return index, index_refine, fea_s_list, key_d

保存索引到文件

  将索引保存到文件中,使用的时候能够快速获取和使用, 键值对能够更快的查找

  1. # 将faiss的索引index写到文件中
  2. def write_index(path):
  3. # path = './item_vec.txt'
  4. index, index_refine, keys, key_d = build_index_fun(path)
  5. faiss.write_index(index, './vec/index_m.faiss')
  6. faiss.write_index(index_refine, './vec/index_refine_m.faiss')
  7. # 商品和序列的键值对也写到文件中
  8. with open('./vec/index_key.faiss', "w") as fout:
  9. for ky in keys:
  10. fout.write(ky)
  11. fout.write("\n")
  12. return index, index_refine, keys, key_d
  13. write_index('./item_vec.txt')

加载索引和设置查询参数

  1. def load_index(index_dir):
  2. # 加载索引文件
  3. index = faiss.read_index('./vec/index_m.faiss')
  4. index_refine = faiss.read_index('./vec/index_m.faiss')
  5. # 设置基础索引
  6. index_refine.base_index = index
  7. index_refine.k_factor = 10
  8. index.nprobe = 100
  9. # 商品位置键值对
  10. keys = list()
  11. key_d = dict()
  12. with open("./vec/index_key.faiss") as fin:
  13. idx = 0
  14. for line in fin:
  15. line = line.strip("\r\n")
  16. key_d[line] = idx
  17. idx += 1
  18. keys.append(line)
  19. return index, index_refine, keys, key_d

向量检索

  向量检索必须是矩阵的形式传入。

  1. # 向量检索
  2. def search():
  3. # 推荐的结果集(商品ID,得分)
  4. res_ans = []
  5. # 检索最近邻的数量
  6. k = 10
  7. # 输入一个index库里的向量,进行检索
  8. index, index_refine, keys, key_d = load_index('./item_vec.txt')
  9. # 获取一个商品的id
  10. fs = '653417384213'
  11. i = key_d[fs]
  12. # 根据位置获取
  13. index_refine.make_direct_map()
  14. fv = index_refine.reconstruct(i)
  15. # 检索必须是矩阵的形式
  16. matrix = np.expand_dims(fv, axis=0)
  17. D, I = index_refine.search(matrix, k)
  18. # 获取结果集
  19. res_id_list, res_dis_list = I[0], D[0]
  20. for i in range(len(res_id_list)):
  21. res_ans.append((keys[res_id_list[i]], res_dis_list[i]))
  22. print(res_ans)
  23. # load_fea_from_file('./item_vec.txt')
  24. # build_index_fun('./item_vec.txt')
  25. write_index('./item_vec.txt')
  26. search()

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/菜鸟追梦旅行/article/detail/732524
推荐阅读
相关标签
  

闽ICP备14008679号