1、什么是相似推薦?
拿我們身邊的演算法“投喂”為主的頭條、抖音、微信視頻號等舉例,如果你喜歡乒乓球,每天推送給你的都是乒乓球比賽視頻集錦;如果你喜歡成功人士演講,每天都是馬云、馬化騰、劉強東等商業巨鱷的演講,
再拿電商的示例如下:比如我近期購買的吳軍老師推薦的科普經典巨著《從一到無窮大》,京東會給我推薦樊登讀書帶火的書《微積分原理》,

其實,在實際業務實戰環節,或多或少也會有類似的功能,Elasticsearch 有沒有類似功能呢?
大家實戰環節遇到的問題也大致如下:
Q1:ES 有相似搜索這個功能吧?我記得有個 suggester吧?
Q2:ES有沒有處理相似文字的案例?把相似文章聚合起來,
來自《死磕Elasticsearch 知識星球》微信群
2、Elasticsearch 相似推薦功能實作
這里不得不介紹:MLT 檢索,對!你沒看錯,不是:MIT(麻省理工學院),是 Elasticsearch 一種檢索型別 MLT(More Like This Query ),
看下圖,建立個全域認識,MLT 屬于:Query DSL下的專業檢索(Specialized queries)的范疇,

3、More Like This 檢索介紹
More Like This 檢索定義:查找與給定檔案“相似”的檔案,
4、More Like This 底層邏輯
MLT 查詢簡單地從輸入的待查詢文本中提取文本,對其進行分析,通常在欄位中使用相同的分析器,然后選擇具有最高 tf-idf 的前 K 個詞組以形成這些詞組的組合查詢陳述句,
假設我們想找到與給定輸入檔案相似的所有檔案,顯然,輸入檔案本身應該是該型別查詢的最佳匹配,為什么呢?基于 Lucene tf-idf 評分公式計算得出的呀,
如下就是 Lucene tf-idf 評分模型,

如果對此評分不了解的同學,推薦閱讀:
干貨 | 一步步拆解 Elasticsearch BM25 模型評分細節
實戰 | Elasticsearch自定義評分的N種方法
MLT 查詢的本質是:從待檢索陳述句中提取文本,然后用分詞器切分,選擇 tf-idf 分值高的前 K 個術語形成檢索陳述句,基于檢索陳述句回傳的結果就是相似度查詢結果,
為避免歧義,對照的英文如下:
The MLT query simply extracts the text from the input document, analyzes it, usually using the same analyzer at the field, then selects the top K terms with highest tf-idf to form a disjunctive query of these terms.
如果原理還不夠清晰,我將核心 Lucene 原始碼的邏輯簡要說明如下:
步驟 1:根據輸入的待查詢的檔案,抽取詞組單元(term),結合TF*IDF 評分形成優先級佇列,
抽取詞時會過濾掉停用詞、不滿足最小詞頻的詞等不滿足限定條件的詞,
步驟 2:結合步驟 1 的優先級佇列,生成布爾查詢陳述句,

Lucene 原始碼部分截圖
回圈超過最大查詢詞數目,則停止構建查詢陳述句,
最大查詢資料值 max_query_terms 默認是:25,增加此值會以犧牲查詢執行速度為代價提供更高的準確性,
步驟 3:基于步驟2構造的布爾查詢陳述句,獲取查詢結果,
回傳結果就是類似推薦功能的相似文章,
看的出來,這比我們常見的精準匹配 term query 和全文檢索 match query、match_pharse query 都要復雜很多,
5、More Like This 前置條件
執行 MLT 的欄位必須被索引并且型別為 text 或 keyword,此外,當對檔案使用相似度檢索時,必須啟用 _source 或設定為 stored 或存盤為 term_vector,為了加快分析速度,可以在索引時存盤 terrm vectors,
讀者看到這里可能會疑惑:啥叫 term vectors ?
有必要解釋一下:
term vectors 組成:
terms 分詞單元串列,
每個分詞單元的位置 position 和序號,
分詞后的單詞或字在原有串中的起始位置 start_offset 、結束位置 end_offset 和偏移值,
有效載荷,與位置相關的用戶定義的二進制值,
給了一堆術語,還是看不懂,再來?!
給個例子,一看就明白了,
PUT my-index-0000012
{
"mappings": {
"properties": {
"text": {
"type": "text",
"term_vector": "with_positions_offsets"
}
}
}
}
PUT my-index-0000012/_doc/1
{
"text": "Quick brown fox fox"
}
GET /my-index-0000012/_termvectors/1
position 更精確的說法是:序號,
Quick 的 position 為 0;
brown 的 position 為 1;
quick 的 start_offset 為 0;
quick 的 end_offset 為 5,

6、More Like This 實戰一把
光說不練是假把式,實戰一把,一探究竟,
插入一批資料,資料來源:百度熱點新聞 ,
DELETE news
PUT news
{
"mappings": {
"properties": {
"title": {
"type": "text",
"analyzer": "ik_smart"
}
}
}
}
POST news/_bulk
{ "index": { "_id":1 }}
{"title":"演唱會突發意外!知名男星受傷,本人最新回應"}
{ "index": { "_id":2 }}
{"title":"張杰演唱會主辦方道歉:舞臺升降設備出現故障"}
{ "index": { "_id":3 }}
{"title":"謝娜發文回應張杰受傷"}
{ "index": { "_id":4 }}
{"title":"張杰回應受傷:不會有大礙,請歌迷和家人朋友們放寬心"}
{ "index": { "_id":5 }}
{"title":"張杰表演時從電梯墜落 手指血流不止"}
{ "index": { "_id":6 }}
{"title":"謝娜回應張杰受傷:他問的第一句話就是怕嚇到女兒"}
{ "index": { "_id":7 }}
{"title":"張杰演唱會出意外后,發長文給粉絲報平安,謝娜透露張杰本人..."}
{ "index": { "_id":8}}
{"title":"張杰明星資料大全愛奇藝泡泡"}
PS:以上僅是百度公開的熱點新聞,以此舉例相似查詢,別無其他用途,特此說明,
執行 MLT:
POST news/_search
{
"query": {
"more_like_this": {
"fields": [
"title"
],
"like": [
"張杰開演唱會從升降機上掉落"
],
"analyzer": "ik_smart",
"min_doc_freq": 2,
"min_term_freq": 1
}
}
}
回傳結果如下:

以如上截圖最后一條資料為例,強調說明一下:注意到一個細節,回傳結果只是相似,并沒有真正做到語意相關,
7、More Like This 核心語法詳解
引數看著很好解釋,但著實非常難理解,特此解讀如下:
"min_doc_freq": 2
最小的檔案頻率,默認為 5,
什么意思呢?
就拿上面的示例來說,至少得有兩篇文章才可以,不管這兩篇文章與輸入相關與否,
更具體點說,如果bulk 寫入僅一篇document,哪怕和標題一致也無法回傳結果,
"min_term_freq": 1
檔案中詞組的最低頻率,默認是2,低于此頻率的會被忽略,
什么意思呢?
就是待檢索陳述句的其中一個分詞單元的詞頻的最小值,
PUT news
{
"mappings": {
"properties": {
"title": {
"type": "text",
"analyzer": "ik_smart"
}
}
}
}
POST news/_bulk
{ "index": { "_id":1 }}
{"title":"張杰演唱會突發意外!知名男星受傷,本人最新回應"}
{ "index": { "_id":2 }}
{"title":"hello kitty"}
POST news/_search
{
"query": {
"more_like_this": {
"fields": [
"title"
],
"like": [
"張杰回應張杰受傷"
],
"analyzer": "ik_smart",
"min_doc_freq": 1,
"min_term_freq": 2
}
}
}
上面的例子更有說服力,
更為具體的說,like部分待檢索陳述句的分詞詞頻要至少有一個 >=2 ,
更多引數建議參考官方檔案,不再贅述,
8、Elasticsearch 相似推薦其他的實作方案
在第 6 部分提及,more like this 并沒有實作完全的相關度推薦,出現了“噪音” 資料,
所以,實戰環節使用 more like this 多半基于燃眉之急,
如果想深入的實作相似度推薦,推薦方案:
基于類似 simhash 的方式,給每個檔案打上 hash 值,基于海明距離實作相似度推薦,
如果想再深入就需要借助:
基于協同過濾的推薦演算法、基于關聯規則的推薦演算法、基于知識的推理演算法或者組合推理演算法實作,
9、小結
本文介紹了 Elasticsearch 中實現相似推薦的 More Like This 檢索方法、實作原理、案例解讀,
目的是給大家業務系統實作相似推薦提供了理論和實踐支撐,
大家實戰環節如何實作的相似推薦呢?歡迎留言討論細節,
參考
https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-mlt-query.html
https://spoon-elastic.com/all-elastic-search-post/more-like-this-query-mlt-suggest-similar-content-with-elasticsearch/
https://qbox.io/blog/mlt-similar-documents-in-elasticsearch-more-like-this-query/
https://spoon-elastic.com/all-elastic-search-post/more-like-this-query-mlt-suggest-similar-content-with-elasticsearch/
https://newbedev.com/elasticsearch-more-like-this-query
https://www.linkedin.com/pulse/finding-similar-documents-elasticsearch-morelikethis-fl%C3%A1vio-knob?articleId=6657988773374111744
《Lucene 原理與代碼分析》
推薦
1、重磅 | 死磕 Elasticsearch 方法論認知清單(2021年國慶更新版)
2、Elasticsearch 7.X 進階實戰私訓課(口碑不錯)

更短時間更快習得更多干貨!
已帶領70位球友通過 Elastic 官方認證!
中國僅通過百余人

比同事搶先一步學習進階干貨!
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/323381.html
標籤:其他
