本文首发于 vivo 互联网技术微信公众号 https://mp.weixin.qq.com/s/wLMvJPXXaND9xq-XMwY2Mg
作者: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 等来实现。

更多内容敬请关注 vivo 互联网技术 微信公众号

注:转载文章请先与微信号:labs2020 联系。

Searching with Deep Learning 深度学习的搜索应用的更多相关文章

  1. deep learning深度学习之学习笔记基于吴恩达coursera课程

    feature study within neural network 在regression问题中,根据房子的size, #bedrooms原始特征可能演算出family size(可住家庭大小), ...

  2. A Full Hardware Guide to Deep Learning深度学习电脑配置

     https://study.163.com/provider/400000000398149/index.htm?share=2&shareId=400000000398149( 欢迎关注博 ...

  3. Deep Learning 深度学习 学习教程网站集锦

    http://blog.sciencenet.cn/blog-517721-852551.html 学习笔记:深度学习是机器学习的突破 2006-2007年,加拿大多伦多大学教授.机器学习领域的泰斗G ...

  4. Deep Learning 深度学习 学习教程网站集锦(转)

    http://blog.sciencenet.cn/blog-517721-852551.html 学习笔记:深度学习是机器学习的突破 2006-2007年,加拿大多伦多大学教授.机器学习领域的泰斗G ...

  5. [Deep Learning] 深度学习中消失的梯度

    好久没有更新blog了,最近抽时间看了Nielsen的<Neural Networks and Deep Learning>感觉小有收获,分享给大家. 了解深度学习的同学可能知道,目前深度 ...

  6. (转)Deep Learning深度学习相关入门文章汇摘

    from:http://farmingyard.diandian.com/post/2013-04-07/40049536511 来源:十一城 http://elevencitys.com/?p=18 ...

  7. Deep learning深度学习的十大开源框架

    Google开源了TensorFlow(GitHub),此举在深度学习领域影响巨大,因为Google在人工智能领域的研发成绩斐然,有着雄厚的人才储备,而且Google自己的Gmail和搜索引擎都在使用 ...

  8. 机器学习(Machine Learning)&深度学习(Deep Learning)资料【转】

    转自:机器学习(Machine Learning)&深度学习(Deep Learning)资料 <Brief History of Machine Learning> 介绍:这是一 ...

  9. 机器学习(Machine Learning)&深度学习(Deep Learning)资料(Chapter 2)

    ##机器学习(Machine Learning)&深度学习(Deep Learning)资料(Chapter 2)---#####注:机器学习资料[篇目一](https://github.co ...

随机推荐

  1. 关于memcached

    代振军 http://www.cnblogs.com/daizhj/archive/2009/03/23/1386652.html http://www.cnblogs.com/daizhj/arch ...

  2. Hdu2841 Visible Trees 2017-06-27 22:13 24人阅读 评论(0) 收藏

    Visible Trees Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) To ...

  3. 3、利用GDB进行程序调试

    本文将用一个实际例子讲解如何通过GDB进行程序调试. 首先,我们需要理解的是GDB是GNU开源组织发布的一个强大的UNIX下的程序调试工具,其产生和调试的目的是让调试者知道,程序在执行时内部发生了什么 ...

  4. sdut 3916

    这道题就是二分枚举加贪心,小蓝书上一开始就讲的,但是我给忘了,很难受 #include <iostream> #include <cstdio> #include <cs ...

  5. AngularJS 表单数据验证及错误信息提示

    一.表单验证基本原理 表单验证包括两个主题: 定义验证规则,验证数据有效性. 显示验证结果,把验证结果以友好的方式显示给用户. H5内置一些验证功能,并会显示内置的错误提示信息,先要禁用它,在< ...

  6. Spring中注入bean学习的总结

    1.在类上直接加注解@Component,那么这个类就直接注入到Spring容器中了  ,像@Contrloller,@Service这些本质上都是@Component, 2.@Configurati ...

  7. 行人检测(Pedestrian Detection)资源

    一.论文 综述类的文章 [1]P.Dollar, C. Wojek,B. Schiele, et al. Pedestrian detection: an evaluation of the stat ...

  8. 源自KPI交谈的思考

    说明白一件事情不容易 前言 跟领导谈及下半年KPI的时候,问我什么打算/计划,在交谈过程中,有几个有意思的点 问题 Q: 目标是hold住服务端,那么怎么样才算hold住服务端? Q: 如何推动别人去 ...

  9. C# WPF 用MediaElement控件实现视频循环播放

    在WPF里用MediaElement控件,实现一个循环播放单一视频的程序,同时可以控制视频的播放.暂停.停止. 一种方式,使用MediaElement.MediaEnded事件,在视频播放结束后,自动 ...

  10. [leetcode.com]算法题目 - Restore IP Addresses

    Given a string containing only digits, restore it by returning all possible valid IP address combina ...