本文首發於 vivo 互聯網技術微信公衆號 mp.weixin.qq.com/s/wLMvJPXXa…git
做者:Eike Dehlinggithub
翻譯:楊振濤數組
本文由來自 Textkernel 的軟件與數據工程師 Eike Dehling 於2018年10月23日發佈與其Linkedin 的 pulse 上,已得到翻譯受權。微信
英文原文連接:www.linkedin.com/pulse/searc…數據結構
目錄:
1、Fast Nearest Neighbours
2、Elasticsearch 插件
3、集成工做
4、結論elasticsearch
最近我在幫一個數據科學家同事工程化一個基於深度學習模型的搜索系統。他們的項目是關於在文檔嵌入應用深度學習模型,而後使用嵌入向量到咱們的搜索系統中來查找類似文檔。工具
一個文檔嵌入本質上實際上是一個(長的)數值數組,查找類似文檔就至關於查找其餘與其較相近的(長的)數值數組;能夠採用諸如歐氏距離等來衡量類似性。學習
能夠藉此來查找類似文檔,可是由於不是直接基於關鍵詞而是基於「嵌入」,因此能夠自動得到與同義詞擴展相媲美的效果。它會查找相關文檔,即便它們使用不一樣的關鍵詞,所以能比關鍵詞檢索表現更好。搜索引擎
已經有解決這種問題的工具了,好比 facebook 的 FAISS 庫(github.com/facebookres…)。這個類庫速度很是快,而且支持多種智能方法使用嵌入向量實現快速檢索。不過它不能友好地集成到相似 Elasticsearch 這樣的搜索引擎中。插件
對於 Elasticsearch 來講,也有一些插件(github.com/muhleder/el…)提供了類似度計算功能,可是它們的速度並不怎麼樣,由於它們只計算了向量類似度而沒有作過濾。
因此咱們本身動手實現了更好的解決方案。
爲了更快速檢索一般會使用各類「索引」,這種數據結構支持高效地過濾出相關的匹配,而無需單獨評估每個匹配。基於關鍵詞的檢索通常使用「倒排索引」;基於地理位置的檢索,通常使用一種叫作 KD樹 的數據結構。咱們也須要諸如此類的機制來快速過濾出最相關的匹配,所以咱們只須要在這個較小的集合上計算精確得分。這一點很是重要,由於在一個高維向量的超大集合上計算距離,是代價很是高昂(慢)的操做。
上文提到的 FAISS 庫提供了多種方式來解決這個問題:
這些方法中的每一種都能實現高效的索引方法,所以能夠快速地篩選出較近鄰的文檔,而後經過計算精確的距離來查找最近鄰文檔。在降維之後就可使用 KD樹,聚類或者局部敏感哈希後也可使用倒排索引。
上圖揭示瞭如何經過過濾數據集來加速計算,須要計算精確距離的文檔數與計算時間之間是線性關係;同時也說明了高效地過濾掉不類似文檔多麼重要。
固然全部這些方法都是有可能在 Elasticsearch 裏獲得實現的,其優勢是便於和其餘檢索系統集成。屆時就能夠組合使用關鍵詞查詢或其餘基於深度學習的查詢結果了。
實驗代表在咱們的數據集上,結合了 PCA 降維後再使用 KD 樹索引,能帶給咱們速度和精度的最佳y組合。
上圖揭示了縮小數據集是如何影響結果精確度的。可以看到,過濾得太狠意味着咱們會丟失一些最近鄰文檔;而若是過濾掉 50k 到 75k 的文檔,就能夠找到全部的最近鄰文檔,同時計算時間只佔暴力計算全部距離的很小一部分。
在 Lucene 即 Elasticsearch的底層類庫中,KD樹的數據結構已經實現了,但尚未經過 Elasticsearch 的 API 暴露出來。已經有插件能夠計算精確的向量距離,因此咱們只須要開發一個小插件來支持使用這種索引結構便可。參見這裏:github.com/EikeDehling…
如今集成工做只是至關於把拼圖圖片按照正確的順序拼到一塊兒:
安裝插件、建立索引以及添加文檔請參考這裏(github.com/EikeDehling…)。完成這些步驟後,如今就可使用咱們的嵌入向量了!請注意 pca_reduced_vector 上的範圍查詢,這纔是咱們新插件起到的做用。
咱們展現瞭如何應用深度學習向量來實現高效的搜索。這一方法適用於想要尋找類似文檔而普通關鍵詞查詢不夠好的任何應用場景。其中的嵌入向量,可使用諸如 doc2vec 等來實現。
更多內容敬請關注 vivo 互聯網技術 微信公衆號
注:轉載文章請先與微信號:labs2020 聯繫。