Searching with Deep Learning 深度学习的搜索应用
作者:Eike Dehling
翻译:杨振涛
本文由来自 Textkernel 的软件与数据工程师 Eike Dehling 于2018年10月23日发布与其Linkedin 的 pulse 上,已获得翻译授权。
英文原文链接:https://www.linkedin.com/pulse/searching-deep-learning-eike-dehling/
目录:
一、Fast Nearest Neighbours
二、Elasticsearch 插件
三、集成工作
四、结论
最近我在帮一个数据科学家同事工程化一个基于深度学习模型的搜索系统。他们的项目是关于在文档嵌入应用深度学习模型,然后使用嵌入向量到我们的搜索系统中来查找相似文档。
一个文档嵌入本质上其实是一个(长的)数值数组,查找相似文档就相当于查找其他与其较相近的(长的)数值数组;可以采用诸如欧氏距离等来衡量相似性。
可以借此来查找相似文档,但是因为不是直接基于关键词而是基于“嵌入”,所以可以自动获得与同义词扩展相媲美的效果。它会查找相关文档,即使它们使用不同的关键词,因此能比关键词检索表现更好。
已经有解决这种问题的工具了,比如 facebook 的 FAISS 库(https://github.com/facebookresearch/faiss)。这个类库速度非常快,并且支持多种智能方法使用嵌入向量实现快速检索。不过它不能友好地集成到类似 Elasticsearch 这样的搜索引擎中。
对于 Elasticsearch 来说,也有一些插件(https://github.com/muhleder/elasticsearch-vector-scoring)提供了相似度计算功能,但是它们的速度并不怎么样,因为它们只计算了向量相似度而没有做过滤。
所以我们自己动手实现了更好的解决方案。
一、Fast Nearest Neighbours
为了更快速检索通常会使用各种“索引”,这种数据结构支持高效地过滤出相关的匹配,而无需单独评估每一个匹配。基于关键词的检索一般使用“倒排索引”;基于地理位置的检索,一般使用一种叫做 KD树 的数据结构。我们也需要诸如此类的机制来快速过滤出最相关的匹配,因此我们只需要在这个较小的集合上计算精确得分。这一点非常重要,因为在一个高维向量的超大集合上计算距离,是代价非常高昂(慢)的操作。
上文提到的 FAISS 库提供了多种方式来解决这个问题:
- PCA 降维
- K 均值聚类
- 局部敏感哈希
- 可能还有其他我不知道方法
这些方法中的每一种都能实现高效的索引方法,因此可以快速地筛选出较近邻的文档,然后通过计算精确的距离来查找最近邻文档。在降维以后就可以使用 KD树,聚类或者局部敏感哈希后也可以使用倒排索引。
上图揭示了如何通过过滤数据集来加速计算,需要计算精确距离的文档数与计算时间之间是线性关系;同时也说明了高效地过滤掉不相似文档多么重要。
当然所有这些方法都是有可能在 Elasticsearch 里得到实现的,其优点是便于和其他检索系统集成。届时就可以组合使用关键词查询或其他基于深度学习的查询结果了。
实验表明在我们的数据集上,结合了 PCA 降维后再使用 KD 树索引,能带给我们速度和精度的最佳y组合。
上图揭示了缩小数据集是如何影响结果精确度的。能够看到,过滤得太狠意味着我们会丢失一些最近邻文档;而如果过滤掉 50k 到 75k 的文档,就可以找到所有的最近邻文档,同时计算时间只占暴力计算所有距离的很小一部分。
二、Elasticsearch 插件
在 Lucene 即 Elasticsearch的底层类库中,KD树的数据结构已经实现了,但还没有通过 Elasticsearch 的 API 暴露出来。已经有插件可以计算精确的向量距离,所以我们只需要开发一个小插件来支持使用这种索引结构即可。参见这里:https://github.com/EikeDehling/vector-search-plugin
三、集成工作
现在集成工作只是相当于把拼图图片按照正确的顺序拼到一起:
- 安装 Elasticsearch 插件
- PCA降维(Python/sklearn 或者 Java/Smile)
- 索引降维后的完整向量到 Elasticsearch 中(以及其他必要属性)
- 整装待发!
安装插件、创建索引以及添加文档请参考这里(https://github.com/EikeDehling/vector-search-plugin)。完成这些步骤后,现在就可以使用我们的嵌入向量了!请注意 pca_reduced_vector 上的范围查询,这才是我们新插件起到的作用。
POST my_index/_search { "query": { "function_score": { "query": { "range": { "pca_reduced_vector": { "from": "-0.5,-0.5,-0.5,-0.5,-0.5,-0.5,-0.5,-0.5", "to": "0.5,0.5,0.5,0.5,0.5,0.5,0.5,0.5" } } }, "functions": [ { "script_score": { "script": { "inline": "vector_scoring", "lang": "binary_vector_score", "params": { "vector_field": "full_vector", "vector": [ 0.0, 0.0716, 0.1761, 0.0, 0.0779, 0.0, 0.1382, 0.3729 ] } } } } ], "boost_mode": "replace" } }, "size": 10 }
四、结论
我们展示了如何应用深度学习向量来实现高效的搜索。这一方法适用于想要寻找相似文档而普通关键词查询不够好的任何应用场景。其中的嵌入向量,可以使用诸如 doc2vec 等来实现。
低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
Hadoop Hive迁移至MaxCompute
本文向您详细介绍如何将 Hadoop Hive 数据迁移到阿里云MaxCompute大数据计算服务上。 一、环境准备 1.1、Hadoop集群环境 在进行 Hadoop Hive 数据迁移前,您需要保证自己的Hadoop集群环境正常。本文使用的Hadoop环境: HDFS 2.8.5 YARN 2.8.5 Hive 3.1.1 Ganglia 3.7.2 Spark 2.3.2 HUE 4.1.0 Zeppelin 0.8.0 Tez 0.9.1 Sqoop 1.4.7 Pig 0.14.0 Knox 1.1.0 ApacheDS 2.0.0 1.2、Hadoop Hive数据准备 Hive脚本: CREATE TABLE IF NOT EXISTS hive_sale( create_time timestamp, category STRING, b
- 下一篇
Flink在饿了么的应用与实践
本文作者:易伟平(饿了么)整理:姬平(阿里巴巴实时计算部) 本文将为大家展示饿了么大数据平台在实时计算方面所做的工作,以及计算引擎的演变之路,你可以借此了解Storm、Spark、Flink的优缺点。如何选择一个合适的实时计算引擎?Flink凭借何种优势成为饿了么首选?本文将带你一一解开谜题。 平台现状 下面是目前饿了么平台现状架构图: 来源于多个数据源的数据写到 kafka 里,计算引擎主要是 Storm , Spark 和 Flink,计算引擎出来的结果数据再落地到各种存储上。 目前 Storm 任务大概有100多个,Spark任务有50个左右,Flink暂时还比较少。 目前我们集群规模每天数据量有60TB,计算次数有1000000000,节点有400个。这里要提一下,Spark 和 Flink都是 on yarn 的,其中Flink o
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- CentOS8编译安装MySQL8.0.19
- CentOS8,CentOS7,CentOS6编译安装Redis5.0.7
- SpringBoot2整合MyBatis,连接MySql数据库做增删改查操作
- SpringBoot2整合Redis,开启缓存,提高访问速度
- SpringBoot2配置默认Tomcat设置,开启更多高级功能
- Hadoop3单机部署,实现最简伪集群
- CentOS7,CentOS8安装Elasticsearch6.8.6
- CentOS6,7,8上安装Nginx,支持https2.0的开启
- Docker使用Oracle官方镜像安装(12C,18C,19C)
- SpringBoot2编写第一个Controller,响应你的http请求并返回结果