Github13K!相似搜索百宝箱,文本匹配入门必备!
每个人都有网购的经历,当你打开淘宝、京东app进入店铺,是怎样找到自己心仪商品的呢?
最直白的方法,拉到“全部商品”页,从头一件件看。但这样做明显效率不高,如果有上千件商品,可能想买的没买到,还加购了一堆自己原本不想买的东西。
所以,你一般会直接在已有分类栏中选择感兴趣的类别,比如“男鞋”,“女大衣”;或者在搜索框中输入关键词。总之,目的只有一个:缩小搜索范围,避免无关商品刷屏。
在自然语言处理基础任务文本匹配中,也存在搜索问题。例如,现在有一个包含了1000个常见高频问题(即FAQ)的问答知识库,用户提出一个新问题,工程师们希望以最快速定位知识库中和它最相似的问题,并返回答案。
当数据规模在1K或1W时,线性搜索(暴力法)是一种省事儿的好方法。但是当数据增加到百万、千万级别时,O(n)的时间开销可能会让用户们抓狂,内存中也无法存放所有的数据。当数据涨到亿级别,问题更加棘手了。
莫慌,今天小徐我来推荐一个牛X的开源项目。通过简单的讲解,只用不到10行代码,就能实现任意规模数据集的相似搜索。
0.Faiss是什么?
1.Faiss如何使用?
2.项目小结
上车出发。
0. 一个神奇的相似搜索工具
Faiss:集众多算法于一身的相似搜索工具箱
Github Star:12.8K
特点:算法丰富,安全可靠,底层C++实现,提供完整Python接口;部分算法支持GPU加速
项目连接:
https://github.com/facebookresearch/faiss
使用文档:
https://faiss.ai/
FaceBook在推荐新闻和用户时,使用了自家研究院开发的Faiss库。Faiss是一个高效的相似性搜索(KNN)和密集向量聚类库,包含的算法可以在任意大小的向量集合中进行搜索。
官方推荐使用anaconda包和conda指令安装Faiss:
# CPU-only version
$ conda install -c pytorch faiss-cpu# GPU(+CPU) version
$ conda install -c pytorch faiss-gpu
测试后发现国内会有网络不通畅的问题,易安装失败。这里我推荐另一种方法,使用pip和国内镜像,约1分钟搞定。
# CPU-only version
$ pip install faiss-cpu -i https://pypi.douban.com/simple# GPU(+CPU) version
$ pip install faiss-gpu -i https://pypi.douban.com/simple
1. Faiss使用教程
Faiss构建索引一般分为基于原始数据构建全量索引,以及加入新的数据构建增量索引。"Train"在某些算法中可以省略,“Add”是必须的。
下面,我以线性搜索和乘积量化算法为例,介绍Faiss的上手方法。
IndexFlatl2:暴力搜索
最简单的方法是基于欧式距离度量的暴力搜索法。
首先,指定特征向量的维度d,通过词向量或预训练语言模型获取原始文本的语义特征。随后,构建 IndexFlatl2 索引对象,并将文本特征加入到索引。属性“ntotal”,可以查看当前索引中到数据规模。
import faiss
d = 768 # embedding 维度
# 构建 IndexFlatL2 索引,它是最简单的索引类型,只执行强力L2距离搜索
faiss_l2_index = faiss.IndexFlatL2(d)
print(faiss_l2_index.is_trained) # True# 在索引中添加原始特征
# faq_texts_emb 是特征向量,维度 [6417, 768]
faiss_l2_index.add(faq_texts_emb)
print(faiss_l2_index.ntotal) # 查看数据规模:6417
下面开始KNN搜索流程。指定需返回的最相似数据量k,假设现在用户输入了新问题q,通过编码器获得特征向量后,直接调用faiss索引,可以得到原始数据中和q最相似的k个问题,以及相应的空间距离。
# 查找 k 近邻
k = 3
q = '我咋没收到交费的通知呢?'
q_emb = bc.encode([q]) # 获得特征
# dis_res:距离矩阵,由小到大排序
# idx_res:数据索引id
dis_res, idx_res = faiss_l2_index.search(q_emb, k)
print(idx_res.shape, dis_res.shape) # [1,3], [1,3]
为了检验结果是否正确,可以打印变量的值看看:
print(idx_res) # [[107, 111, 75]]
print(dis_res) # [[18.602684 20.919521 21.184694]]
# labels[i] 先映射到训练集文本对应的真实意图 label_id,再转换为 label 标签
print(list(id2name[labels[i]] for i in idx_res[0]))
"""['未收到催费短信', '未收到催费短信', '未收到催费短信']"""
查找的topk标准问题都是“未收到催费短信”,和真实提问“我咋没收到交费的通知呢”一致。
IndexPQ:乘积量化
Faiss调用的套路基本是类似的。再来看另一种更高效的搜索方法,乘积量化。
所谓量化,就是将连续的空间离散化,目的是为了优化距离计算的速度。对原理感兴趣对小伙伴,可以阅读参考文献[1],之后小徐会单独开一篇文章介绍,欢迎关注!
这里先介绍调用方法。乘积量化有一个聚类过程,所以需要显式调用索引对象的“train”方法,再添加向量文件。预测过程,和“暴力搜索”类似。
# m: 特征拆分子空间的数量
m, d = 8, 768
# 每一个子空间分配的bit大小
n_bits = 8
# 创建乘积量化索引
faiss_pq_index = faiss.IndexPQ(d, m, n_bits)
# train 阶段
faiss_pq_index.train(faq_texts_emb)
# add 阶段
faiss_pq_index.add(faq_texts_emb)k = 3
q = '我妹夫家的租户不交电费,这样子会影响我妹夫的信用不?'
q_emb = bc.encode([q])
dis_res, idx_res = faiss_pq_index.search(q_emb, k)
print(idx_res.shape, dis_res.shape) # [1,3], [1,3]
print(idx_res) # [[2563 2575 2547]]
print(dis_res) # [[11.660806 11.660806 11.660806]]
print(list(id2name[labels[i]] for i in idx_res[0]))
"""['租户不交电费是否影响户主信用', '租户不交电费是否影响户主信用', '租户不交电费是否影响户主信用']"""
最终结果和预期一致。
Faiss中还有非常多好用高效的相似搜索方法,例如点积计算IndexFlatIP、改进版乘积量化、加入倒排索引的量化搜索“IndexIVFPQ”等等,更多????可以查看Github上的tutorial文件夹。
对源码感兴趣又有C++基础的同学,可以从 AutoTone.cpp 文件开始,阅读源码。
2. Faiss 项目总结
回顾Faiss框架,这是一个用于相似检索的算法集大成者。检索目标不仅仅是文本,还包括图片、音频、视频等等多模态形式,只要能将目标转换为特征向量。
除了开源项目,作者还提供了完整的文档体系[2],方便大家快速上手。
如果你的实验或项目中涉及相似匹配任务,不妨尝试一下Faiss框架,毕竟FaceBook自家产品都在用,质量还是有保障滴。如果通过调用接口,顺便弄懂了算法原理,恭喜你,在检索匹配领域你离成为巨佬又近了一步!
一起交流
想和你一起学习进步!『NewBeeNLP』目前已经建立了多个不同方向交流群(机器学习 / 深度学习 / 自然语言处理 / 搜索推荐 / 图网络 / 面试交流 / 等),名额有限,赶紧添加下方微信加入一起讨论交流吧!(注意一定要备注信息才能通过)
参 考 文 献
[1] Faiss-PQ/IVF介绍:https://blog.csdn.net/u013066730/article/details/106252573
[2] Faiss文档:https://faiss.ai/
- END -
如何利用多任务学习提升模型性能?
2021-03-17
无心插柳 | 聊聊我的 ACL2020 论文
2021-03-11
如何提升BERT在下游任务中的性能
2021-03-09
FLAT——中文NER该怎么做
2021-02-19
Github13K!相似搜索百宝箱,文本匹配入门必备!相关推荐
- laravel 分词搜索匹配度_DSSM文本匹配模型在苏宁商品语义召回上的应用
文本匹配是自然语言处理中的一个核心问题,它不同于MT.MRC.QA 等end-to-end型任务,一般是以文本相似度计算的形式在应用系统中起核心支撑作用1.它可以应用于各种类型的自然语言处理任务中,例 ...
- Linux操作系统学习笔记【入门必备】
Linux操作系统学习笔记[入门必备] 文章目录 Linux操作系统学习笔记[入门必备] 1.Linux入门 2.Linux目录结构 3.远程登录 3.1 远程登录Linux-Xshell5 3.2 ...
- Java基础入门必备词汇汇
#Java基础入门必备词汇汇 一 1.Public ['pʌblik] 公开 2.Static ['stætik] 静态 3.void [vɔid] 无返回 4.main [main] 主要的,主方法 ...
- 第一篇 入门必备 (Android学习笔记)
第一篇 入门必备 第1章 初识Android 第2章 搭建你的开发环境 第3章 创建第一个程序--HelloWorld 第4章 使用Android工具 ●Android之父 Android安迪·罗宾( ...
- 文本匹配(语义相似度)综述
本文转载自公众号"夕小瑶的卖萌屋",专业带逛互联网算法圈的神操作 ----->我是传送门 关注后,回复以下口令: 回复[789] :领取深度学习全栈手册(含NLP.CV海量综 ...
- 【NLP】文本匹配相关方向打卡点总结
点击上方,选择星标或置顶,每天给你送干货! 阅读大概需要27分钟 跟随小博主,每天进步一丢丢 来自:夕小瑶的卖萌屋 Motivation 前不久小夕在知乎上写了一个回答<NLP有哪些独立研究方向 ...
- 文本匹配相关方向总结(数据,场景,论文,开源工具)
Motivation 前不久小夕在知乎上写了一个回答<NLP有哪些独立研究方向>,于是有不少小伙伴来问分类和匹配的参考资料了,鉴于文本分类的资料已经超级多了,就不写啦(不过分类相关的tri ...
- 文本匹配相关方向打卡点总结
Motivation 前不久小夕在知乎上写了一个回答<NLP有哪些独立研究方向>[1],于是有不少小伙伴来问分类和匹配的参考资料了,鉴于文本分类的资料已经超级多了,就不写啦(不过分类相关的 ...
- nmt模型源文本词项序列_「自然语言处理(NLP)」阿里团队--文本匹配模型(含源码)...
来源:AINLPer微信公众号 编辑: ShuYini 校稿: ShuYini 时间: 2019-8-14 引言 两篇文章与大家分享,第一篇作者对通用文本匹配模型进行探索,研究了构建一个快速优良的文本 ...
- 深度文本匹配在智能客服中的应用
参加2018 AI开发者大会,请点击↑↑↑ 作者 | 云知声 目录 一. 深度文本匹配的简介 1. 文本匹配的价值 2. 深度文本匹配的优势 3. 深度文本匹配的发展路线 二. 智能客服的简介 1. ...
最新文章
- 微信小程序request合法域名怎么配置啊
- Python中可以使用静态类变量吗?
- 投资者建议三星电子一分为二 股价创历史新高
- maven的环境搭建
- 使用Google Guava Cache进行本地缓存
- 多线程多进程解析:Python、os、sys、Queue、multiprocessing、threading
- HiveQL: 数据定义
- P1029 [NOIP2001 普及组] 最大公约数和最小公倍数问题(2022.02.02) --- python3实现
- qq头像计算机系,QQ头像
- Programe_Of_Beauty:2.14 求数组的子数组之和的最大值
- 前台setcookie之后从后台取出来_后台设置Cookie值,前台进行获取
- 05引用类型以及特殊引用类型string
- [课后作业] 第032讲:异常处理:你不可能总是对的
- RTP包里面得到H.264数据和AAC数据的方法
- ll1语法分析程序c语言,c语言语法分析器,实现ll1分析
- 查找图片中隐藏的flag
- tap10.app cn.html,Tap连点器
- react-native之react-native-vector-icons
- 还在用PPT做组织架构图?公司都在用的架构图软件是什么?
- 【Unity3D】使用 FBX 格式的外部模型 ③ ( FBX 模型中的材质重映射 | FBX 模型使用外部材质 | FBX 模型的分解重组 )
热门文章
- gmx一定要在linux下运行么,gmx_mmpbsa使用说明
- gmx_MMPBSA--计算蛋白-配体自由能及能量分解
- I/O模型(同步、非同步、阻塞、非阻塞)总结
- 前端开发工程师的前传
- CheXNet-master:CUDA out of memery
- js 前端实现打印功能
- 解决Github不能下载,下载速度慢的小妙招
- 大数据高级开发工程师——大数据相关工具之一 Sqoop
- android system.img userdata.img文件解包打包及设置
- 配置计算机老是重启,电脑无缘无故重启是什么原因_电脑老是无故自动重启如何解决-win7之家...