日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

ElasticSearch 2 (26) - 语言处理系列之打字或拼写错误

發(fā)布時(shí)間:2025/5/22 编程问答 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 ElasticSearch 2 (26) - 语言处理系列之打字或拼写错误 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

ElasticSearch 2 (26) - 語言處理系列之打字或拼寫錯(cuò)誤

摘要

我們喜歡在對結(jié)構(gòu)化數(shù)據(jù)(如:日期和價(jià)格)做查詢時(shí),結(jié)果只返回那些能精確匹配的文檔。但是,好的全文搜索不應(yīng)該有這樣的限制。相反,我們可以擴(kuò)大范圍,包括更多可能匹配的詞語,使用相關(guān)度評分將更匹配的文檔放置在結(jié)果集的頂部。

事實(shí)上,只做精確匹配的全文搜索很有可能會讓用戶失望,難道我們不希望搜索 “quick brown fox” 可以匹配到包含 “fast brown foxes” 的文檔,“Johnny Walker” 可以匹配 “Johnnie Walker”,“Arnold Shcwarzenneger” 可以匹配 “Arnold Schwarzenegger”?

如果文檔確實(shí)精確包含用戶的搜索條件,那么它們應(yīng)該出現(xiàn)在結(jié)果集的頂部,而弱匹配可以置于結(jié)果列表的稍后地方。如果沒有精確的匹配,至少我們可以為用戶提供潛在匹配的可能,它們甚至可能是用戶搜索的初衷!

我們已經(jīng)在 規(guī)則化標(biāo)記(Normalizing Tokens) 介紹了處理變音詞的匹配方式,在 縮減單詞至詞根形式(Reducing Words to Their Root Form) 中介紹了詞語的詞干提取方式,在 同義詞(Synonyms) 中介紹了同義詞的處理方式,但是所有這些方法都以單詞是正確拼寫這個(gè)條件為前提,或者說每個(gè)詞的拼寫方式只有一種。

模糊匹配允許在查詢時(shí)匹配拼寫錯(cuò)誤的詞,語音標(biāo)記過濾器可以在索引時(shí)用來語音匹配。

版本

elasticsearch版本: elasticsearch-2.x

內(nèi)容

模糊邏輯(Fuzziness)

模糊匹配將兩個(gè)模糊相似的詞作為同一詞語處理,首先,我們須要定義什么是模糊性。

在 1965 年,Vladimir Levenshtein 開發(fā)了 Levenshtein 距離算法,它可以計(jì)算從一個(gè)單詞變成另外一個(gè)單詞時(shí),單個(gè)字符改變的總次數(shù)。它提出了三種類型的單字符修改方式:

  • 將一個(gè)字符替換成為另外一個(gè):f ox → b ox
  • 插入新的字符:sic → sic k
  • 刪除字符:b l ack → back

Frederick Damerau 后來對這些操作進(jìn)行了擴(kuò)展,新增了一種方式:

  • 交換兩個(gè)相鄰字符的位置:st ar → ts ar

例如,將單詞 bieber 轉(zhuǎn)換成 beaver 需要以下步驟:

  • 將 b 替換成 v : bie b er → bie v er
  • 將 i 替換成 a : b i ever → b a ever
  • 交換 a 和 e 的位置: b ae ver → b ea ver
  • 這三步用 Damerau-Levenshtein 法表示的距離是 3 。

    顯然,bieber 與 beaver 有很長一段距離,它們相距太遠(yuǎn)而不能被認(rèn)為是簡單的拼寫錯(cuò)誤。Damerau 觀察到 80% 的人為拼寫錯(cuò)誤的距離是 1 。換句話說,有 80% 的拼寫錯(cuò)誤可以通過單次字符修改得到原始的字符串。

    Elasticsearch 支持一個(gè)最大的編輯距離是 2 ,可以通過參數(shù) fuzziness 來指定。

    當(dāng)然,單次修改的影響還取決于被修改字符串的長度。單詞 hat 經(jīng)兩次修改可以變成 mad ,所以允許長度為 3 的字符串修改兩次有點(diǎn)過度。參數(shù) fuzziness 可以被設(shè)置成 AUTO ,代表以下三中最大編輯距離:

    • 0 對于長度為 1 或 2 的字符串
    • 1 對于長度為 3、4 或 5 的字符串
    • 2 對于長度大于 5 的字符串

    當(dāng)然,可能會發(fā)現(xiàn) 2 步修改仍然過度,返回的結(jié)果看上去并不相關(guān)。當(dāng)最大 fuzziness 值為 1 時(shí),我們可能會得到更好的搜索結(jié)果和更好的性能。

    模糊查詢(Fuzzy Query)

    fuzzy 查詢和使用 term 查詢的 fuzzy 特性是等價(jià)的。通常我們很少會自己直接使用它,但是理解它的工作方式有助于我們在高層 match 查詢中利用模糊的特性。

    為了理解它是如何工作的,我們先新建索引一些文檔:

    POST /my_index/my_type/_bulk{ "index": { "_id": 1 }}{ "text": "Surprise me!"}{ "index": { "_id": 2 }}{ "text": "That was surprising."}{ "index": { "_id": 3 }}{ "text": "I wasn't surprised."}

    現(xiàn)在我們就可以運(yùn)行 fuzzy 查詢搜索 surprize:

    GET /my_index/my_type/_search{"query": {"fuzzy": {"text": "surprize"}}}

    fuzzy 查詢是一個(gè)詞項(xiàng)級別的查詢,所以它沒有做任何分析的工作。它接收單個(gè)詞項(xiàng),并且根據(jù)指定的模糊邏輯在字典中查找匹配的所有詞項(xiàng)。默認(rèn)的 fuzziness 值是 AUTO。

    在我們的例子中,surprize 距離 2 以內(nèi)的詞有 surprise 和 surprised,所以文檔 1 和 3 是匹配的。我們可以通過以下查詢將匹配結(jié)果縮小至 surprise :

    GET /my_index/my_type/_search{"query": {"fuzzy": {"text": {"value": "surprize","fuzziness": 1}}}}

    提升性能(Improving Performance)

    fuzzy 查詢接受原始詞項(xiàng)并為其構(gòu)建一個(gè) Levenshtein 自動(dòng)機(jī)(automaton) ,這個(gè)結(jié)構(gòu)有如一個(gè)圖,它能表示與原始字符串相距指定編輯距離值以內(nèi)的所有可能字符串。

    模糊查詢隨后使用這個(gè)自動(dòng)機(jī)逐步高效的在字典中匹配所有詞項(xiàng),一旦收集到字典里所有的匹配詞項(xiàng),它便能計(jì)算出所有與之匹配的文檔。

    當(dāng)然,由于索引里存儲的數(shù)據(jù)類型不同,一個(gè)編輯距離為 2 可以與大量詞匹配,性能也會非常差。以下兩個(gè)參數(shù)可以用來限制對性能的不良影響:

    • prefix_length

      設(shè)置字符串不會被“模糊化”的起始長度。多數(shù)拼寫錯(cuò)誤出現(xiàn)在詞語的末尾處,而不是開始處。比如,當(dāng) prefix_length 的值為 3 時(shí),我們可以大大減少需要匹配詞項(xiàng)的數(shù)目。

    • max_expansions

      如果模糊查詢擴(kuò)展到三或四個(gè)選項(xiàng)的時(shí)候,這些新選項(xiàng)可能還是有意義的,但當(dāng)它生成 1,000 個(gè)選項(xiàng)時(shí),它們實(shí)際上毫無意義。用 max_expansions 來限制生成選項(xiàng)的總數(shù),模糊查詢會搜集匹配的詞項(xiàng),直到找不出更多匹配或詞項(xiàng)數(shù)目達(dá)到 max_expansions 數(shù)值的限制。

    模糊匹配查詢(Fuzzy match Query)

    match 查詢自帶支持模糊匹配的功能:

    GET /my_index/my_type/_search{"query": {"match": {"text": {"query": "SURPRIZE ME!","fuzziness": "AUTO","operator": "and"}}}}

    查詢字符串首先經(jīng)過分析,然后生成詞項(xiàng) [surprize, me],最后每個(gè)詞項(xiàng)用指定的 fuzziness(模糊邏輯) 進(jìn)行模糊化處理。

    類似地,multi_match 查詢也支持模糊邏輯,但它只支持兩種類型 best_fields 或 most_fields:

    GET /my_index/my_type/_search{"query": {"multi_match": {"fields": [ "text", "title" ],"query": "SURPRIZE ME!","fuzziness": "AUTO"}}}

    match 和 multi_match 查詢都能支持 prefix_length 和 max_expansions 參數(shù)。

    小貼士

    模糊邏輯只能使用于兩種基本查詢 match 和 multi_match,而無法使用于短語匹配,常用詞項(xiàng)或跨字段匹配。

    模糊度的評分(Scoring Fuzziness)

    用戶喜歡模糊查詢,他們以為這些查詢總會奇妙的找到正確的拼寫結(jié)果。不幸的是,事實(shí)卻無法激動(dòng)人心。

    假設(shè)我們有 1,000 個(gè)文檔包含詞語 “Schwarzenegger”,其中只有 1 個(gè)文檔里有錯(cuò)誤拼寫 “Schwarzeneger”,根據(jù) TF/IDF 的理論,這個(gè)錯(cuò)誤拼寫比正確拼寫更具相關(guān)性,因?yàn)樗谖臋n里出現(xiàn)的次數(shù)要少得多!

    換句話說,如果我們同等對待模糊匹配和其他匹配,那么我們就會更偏向錯(cuò)誤拼寫而不是正確拼寫,這會使用戶感到抓狂的。

    小貼士

    模糊匹配不應(yīng)用于以評分為目的的查詢,而只能當(dāng)有錯(cuò)誤拼寫時(shí),用于擴(kuò)大匹配詞項(xiàng)的匹配范圍。

    默認(rèn)情況下,match 查詢給所有模糊匹配的分?jǐn)?shù)總是 1 。這足以使?jié)撛诘钠ヅ涑霈F(xiàn)在結(jié)果的末尾,而不用影響到非模糊查詢的相關(guān)度評分計(jì)算。

    小貼士

    模糊查詢本身并沒有剛開始看起來那么有用,它們最好作為高級功能的一部分,例如 輸入即搜索 completion 完成建議器 或 你想查找 詞組建議器。

    語音匹配(Phonetic Matching)

    最后,令人絕望的是,試圖匹配那些聽上去相似的詞,這些詞的拼寫甚至是不同的。

    現(xiàn)存一些算法可以將詞語轉(zhuǎn)換成語音形式表示。Soundex 算法是它們的始祖,其他所有類似算法都是 Soundex 的改進(jìn)或定制形式,例如 Metaphone 和 Double Metaphone (它對語音匹配擴(kuò)展到其他語言而不只是英語),Caverphone 算法可以匹配新西蘭姓名,Beider-Morse 算法以 Soundex 算法為基礎(chǔ),但它能更好的匹配德語和依地語姓名,K?lner Phonetik 對德語詞支持更好。

    我們從上面一串算法中要學(xué)到的是語音算法都相當(dāng)粗糙,太依賴于它們針對設(shè)計(jì)的語言,這些語言可以是英語,也可以是德語,這限制了它們的可用性。不過,如果與其他技術(shù)相結(jié)合,為了處理某種問題,語音匹配也可以是個(gè)有用的工具。

    首先,我們需要從下面網(wǎng)址安裝語音分析插件 https://www.elastic.co/guide/en/elasticsearch/plugins/current/analysis-phonetic.html ,為集群每個(gè)節(jié)點(diǎn)都安裝,然后重啟每個(gè)節(jié)點(diǎn)。

    安裝后,我們可以創(chuàng)建一個(gè)自定義分析器,嘗試使用其中一個(gè)語音標(biāo)記過濾器:

    PUT /my_index{"settings": {"analysis": {"filter": {"dbl_metaphone": { #1"type": "phonetic","encoder": "double_metaphone"}},"analyzer": {"dbl_metaphone": {"tokenizer": "standard","filter": "dbl_metaphone" #2}}}}}

    #1 首先,配置自定義 phonetic 語音標(biāo)記過濾器以及 double_metaphone 編碼器。

    #2 然后在自定義分析器中使用自定義的標(biāo)記過濾器。

    現(xiàn)在使用 analyze API 對其測試:

    GET /my_index/_analyze?analyzer=dbl_metaphoneSmith Smythe

    Smith 和 Smythe 在同一位置各生成兩個(gè)標(biāo)記:SM0 和 XMT。分析 John、Jon 和 Johnnie 會都生成兩個(gè)標(biāo)記 JN 和 AN,但 Jonathon 會生成標(biāo)記 JN0N 和 ANTN。

    語音分析器和其他分析器的使用方式類似,首先為字段設(shè)置映射,然后在對數(shù)據(jù)建立索引:

    PUT /my_index/_mapping/my_type{"properties": {"name": {"type": "string","fields": {"phonetic": { #1"type": "string","analyzer": "dbl_metaphone"}}}}}PUT /my_index/my_type/1{"name": "John Smith"}PUT /my_index/my_type/2{"name": "Jonnie Smythe"}

    #1 name.phonetic 字段使用自定義的 dbl_metaphone 分析器。

    用 match 查詢來搜索:

    GET /my_index/my_type/_search{"query": {"match": {"name.phonetic": {"query": "Jahnnie Smeeth","operator": "and"}}}}

    這個(gè)查詢同時(shí)返回兩個(gè)文檔,這樣表明語音查詢是有多粗糙。使用語音算法進(jìn)行評分通常也沒有多大意義。使用語音算法的目的不在于提高精度,而在于提高召回,擴(kuò)大撒網(wǎng)范圍從而獲得任何可能匹配的文檔。

    通常將語音算法的結(jié)果作為其他算法或計(jì)算機(jī)的輸入信息,要比直接將結(jié)果給人使用要靠譜得多。

    參考

    elastic.co: Typoes and Mispelings

    轉(zhuǎn)載于:https://www.cnblogs.com/richaaaard/p/5282630.html

    總結(jié)

    以上是生活随笔為你收集整理的ElasticSearch 2 (26) - 语言处理系列之打字或拼写错误的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。