solr入門之solr的拼寫檢查功能的應用級別嘗試
今天主要是收集了些拼寫檢查方面的資料和 嘗試使用一下拼寫檢查的功能--=遇到了不少問題
拼寫檢查的四種配置眼下我僅僅算是成功了半個吧
---------------------------------
拼寫檢查功能,能在搜索時,提供一個較好用戶體驗。所以,主流的搜索引擎都有這個功能。在這之前,筆者先簡單的說一下什麽是拼寫檢查,事實上非常好理解。就是你輸入的搜索詞,可能是你輸錯了,也有可能在它的檢索庫裏面根本不存在這個詞。可是這時候它能給你返回,相似或相近的結果來幫助你校正。
舉個樣例。假如你在百度裏面輸入在在線電瓶,可能它的索引庫裏面就沒有,可是它有可能返回在線電影,在線電視,在線觀看等等一些詞。這些。就用到拼寫檢查的功能了。
solr作為一種開源的搜索server,對拼寫檢查,也提供了良好的支持,那麽以下筆者就來講下關於solr4.3的拼寫檢查的配置,在這之前先說明一點。作為拼寫檢查用,為了提高校正的準確率,一般對校正的詞,不要進行分詞,所以用string就好了,拼寫檢查的配置主要是在solrconfig.xml裏面配置.
1,拼寫組件SpellCheckComponent配置
2,在SearchHandler /select裏面配置
3,在SearchHandler /spell裏面配置
依照上面3來,就能夠高速配置好拼寫檢查功能了。事實上筆者上面寫的4步。事實上僅僅配置2,3步就能夠了。另外的第4步用默認值就能夠了。在這裏把它寫出來。僅僅是讓大家有個認識
拼寫組件SpellCheckComponent它事實上是核心的東西。在他的裏面能夠配置1至多個拼寫檢查器,啟動的時候全部的檢查器都會載入。這次筆者主要介紹的有2個拼寫檢查器,一個是默認的僅僅對主索引做拼寫校正,另外一個是自己定義載入spellings.txt拼寫檢查庫。帶拼寫校正索引庫的檢查器,其它的檢查器各位道友想要使用的話就自己去看wiki了。
https://cwiki.apache.org/confluence/display/solr/Spell+Checking
1.配置solrconfig.xml文件的拼寫檢查的幾種方式
<!--拼寫檢查設置 --> <searchComponent name="spellcheck" class="solr.SpellCheckComponent"> <!-- 查詢分析器。假設不指定的話,默認會使用field字段類型的分詞器 --> <str name="queryAnalyzerFieldType">text_spell</str> <lst name="spellchecker"> <str name="name">direct</str> <str name="field">suggest</str> <str name="classname">solr.DirectSolrSpellChecker</str> <str name="distanceMeasure">internal</str> <float name="accuracy">0.5</float> <int name="maxEdits">2</int> <int name="minPrefix">1</int> <int name="maxInspections">5</int> <int name="minQueryLength">2</int> <float name="maxQueryFrequency">0.01</float> </lst> <!-- 讀取拼寫檢查庫的索引進行校正能夠。使用默認配置,取消凝視就可以 --> <lst name="spellchecker"> <str name="classname">solr.FileBasedSpellChecker</str><!--這個組件是載入配置文件來完畢的,檢查源是文件能夠起效的字段呢?--> <str name="name">file</str> <str name="sourceLocation">spellings.txt</str> <str name="characterEncoding">UTF-8</str> <str name="spellcheckIndexDir">spellcheckerFile</str> </lst> <!-- ======================================================================================--> <lst name="spellchecker"> <!-- Optional, it is required when more than one spellchecker is configured. Select non-default name with spellcheck.dictionary in request handler. ame是可選的,假設僅僅有一個spellchecker能夠不寫name 果有多個spellchecker,須要在Request Handler中指定spellcheck.dictionary --> <str name="name">base</str> <!-- The classname is optional, defaults to IndexBasedSpellChecker --> <str name="classname">solr.IndexBasedSpellChecker</str> <!-- Load tokens from the following field for spell checking, analyzer for the field's type as defined in schema.xml are used 以下這個field名字指的是拼寫檢查的根據,也就是說要根據哪個Field來檢查用戶輸入。 --> <str name="field">suggest</str> <!-- Optional, by default use in-memory index (RAMDirectory) SpellCheck索引文件的存放位置,是可選的,假設不寫默認使用內存模式RAMDirectory。 ./spellchecker1指的是:corex\data\spellchecker1 --> <str name="spellcheckIndexDir">./spellchecker-base</str> <!-- Set the accuracy (float) to be used for the suggestions. Default is 0.5 --> <str name="accuracy">0.7</str> <!--何時創建拼寫索引:buildOnCommit/buildOnOptimize --> <str name="buildOnCommit">true</str> </lst> <!-- 還有一個拼寫檢查器,使用JaroWinklerDistance距離算法 類 那個主索引的方式應該也是能建立的吧 --> <lst name="spellchecker"> <str name="name">jarowinkler</str> <str name="classname">solr.IndexBasedSpellChecker</str> <str name="field">suggest</str> <!-- Use a different Distance Measure --> <str name="distanceMeasure">org.apache.lucene.search.spell.JaroWinklerDistance</str> <str name="spellcheckIndexDir">./spellchecker2</str> <str name="buildOnCommit">true</str> </lst> <!-- ======================================================================================--> </searchComponent>
<requestHandler name="/select" class="solr.SearchHandler"> <!-- default values for query parameters can be specified, these will be overridden by parameters in the request --> <lst name="defaults"> <str name="echoParams">explicit</str> <int name="rows">10</int> </lst> <!-- 這行代碼很重要。假設沒有這行,拼寫檢查。是不起作用的--> <arr name="last-components"> <str>spellcheck</str> </arr> </requestHandler>
<!--spell 查詢器 --> <requestHandler name="/spell" class="solr.SearchHandler" startup="lazy"> <lst name="defaults"> <str name="df">suggest</str> <!--默認查詢字段--> <str name="spellcheck.dictionary">direct</str> <!--使用那個組件--> <str name="spellcheck">on</str> <str name="spellcheck.extendedResults">true</str> <str name="spellcheck.collate">true</str> <str name="spellcheck.collateExtendedResults">true</str> </lst> <arr name="last-components"> <str>spellcheck</str> </arr> </requestHandler>
文件方式說明
對於上面的代碼。盡管能夠載入多個校正器。可是在拼寫檢查時,僅僅能指定特定的一個進行校正。那麽為什麽要配置多個校正檢查器呢? 筆者個人感覺這個主要是方便在程序執行能夠動態切換校正器。
在spellings.txt裏面自己定義的拼寫檢查詞,註意編碼的格式一定是要UTF-8無BOM的格式。這裏面的詞。會在solr服務啟動時,自己主動創建spellcheckerFile目錄並把內容載入到
本庫的data文件夾下
3.solr主界面查詢嘗試
這是是使用direct方式 來進行嘗試的 詳細的效果 預計和配置的參數 有非常大的關系
關於其余幾種方式--我主要在嘗試文件夾的方式的載入今天沒有搞定呀
明天的嘗試下:
以下是一些原理方面的資料;
一、糾錯功能。英文叫做spellcheck。在英文上做糾錯比較直接。就是看單詞的編輯距離,目標當然就是對於隨意一個輸入,能在大量正確而靠譜的查詢詞中找出編輯距離滿足要求的一個或者幾個。
面對這種spellcheck任務,模型上就是要推算用戶輸入錯誤單詞w的條件下,是正確單詞c的概率。也就是argmaxc P(c|w)。
一般有兩種方案:一種。是http://norvig.com/spell-correct.html 介紹的辦法,還有一種是lucene-suggest裏spellchecker的方法。
1. 第一種,在norvig介紹的方法中,具體的闡述了argmaxc P(c|w)的轉換和求解辦法。 這個概率不好直接算,但能夠依據貝葉斯定理等價於argmaxc P(w|c)*P(c) / P(w)。由於是比較各個c之間的大小所以P(w)能夠省略,最後就變成求argmaxc P(w|c)*P(c)即可了。P(c)能夠看作是c在文本集合中出現的可能性;P(w|c)意味著本來心裏想成是c結果打成了w的概率。
那就非常好辦了,P(c)能夠從靠譜的語料中統計。P(w|c)能夠用編輯距離來模擬關系,即編輯距離小的概率大。在實現上,對一個輸入word,產生出有編輯距離1的字符串,就包含幾種情況:刪除一個字符、交換臨近字符、把一個字符改成還有一個、添加一個字符。這樣產生的候選集會比較大,接近80%的糾錯要求是滿足了。
假設在編輯距離1的基礎上再產生編輯距離為2的更大的候選集。差點兒就覆蓋全部錯別字了。原文講得比較精細。建模思路也非常清晰。建議細致閱讀,這就不細說了。
2.另外一種方案就是lucene的spellchecker方法。上面方案是把編輯距離的暫時產生到詞典中檢查。這樣的方案就是預先進行詞典索引。當然是ngram的,對一個word隨意2位或者3位字符進行索引,對用戶輸入的一個字符。也同理按2或3位產生字符片段,利用OR的關系去檢索。命中多的word得分更高最可能是拼寫錯誤的。當然由於是OR查詢關系,所以會有非常多也僅僅“沾邊”的詞也被命中。所以最後除了考慮查詢命中高分的。還要對命中的和輸入的進行一步編輯距離閾值過濾。舉個樣例“word”。我們會有n2:wo/n2:or/n2:rd/n3:wor/n3:ord 這些碎片進行索引,當用戶輸入一個worg,會產生n2:wo/n2:or/n2:rg/n3:wor/n3:org,這些檢索條件,會查到非常多work, worth等等。
細節上能夠有一些增強,比方單詞兩頭的字符碎片權重更大等等。
這兩種求解argmax P(c|w)的辦法,norvig的辦法比lucene-spellcheck的辦法在線上的環節多一些,效率上預計還是差一點,但提供了非常巧妙的求解思路,值得細細品味。
二、相關搜索的功能,學術界研究的比較多。有各種提法,query rewrite,query substitution, query extension等等。算法也五花八門,大多為了結果好看添加了復雜的計算,和針對數據情況的考量。
一般project上須要的是通用的辦法,再添加一些特殊的考慮來提高效果。過去以前有幸看到一篇貌似不是非常正規的論文。方法非常easy,思路清晰,非常適合在實際project上應用起來。論文也不記得標題了。只是思想還記得非常清晰:就是尋找query詞之間的強弱聯系。
普通情況下構成query之間的關聯有三種基本的因素:
1. 字面意思的關聯。假設一個query比還有一個query 多了或者少了一個詞。那麽這兩個詞肯定是有關聯的。長短語是短短語的詳細化,反之是泛化。比方“筆記本 內存條 8G”就是“筆記本 內存條”的細化,反過來看“筆記本 內存條”不僅包含“8G”也包含其它容量,是更泛化的查詢詞。
2. 用戶輸入行為的關聯;用戶在一個會話之中連續輸入的多個詞之間能夠覺得是有關聯的,即做一個人的需求反應在查詢詞上。比方用戶查詢了“鍵盤”他可能還有須要去買點別的,比如“鼠標”之類的。假設這種情況出現了多次,那麽“鍵盤”和“鼠標”就能夠看成是有強聯系的。
3. 用戶點擊行為的關聯。用戶為了找一個東西的時候可能詞不正確重復更換查詢詞,或者不同人用不同的表達,假設都點到一個結果。能夠看做用了不同的辦法找到相同的東西,殊途同歸的味道。那麽這些落到同一結果的路徑。即query。也能夠看做是有強關聯的。
這三種是比較通用的關聯關系,也非常直接,而且數據能非常easy獲得或者被日誌記錄下來的。除了這幾種,還能夠依據詳細業務情況添加其它關聯考慮。最後。我們能夠依據經驗或者統計分析調整多種關聯關系的權重。實現上,對一個query。須要讓查那些和它有關聯的queries,都能被找出來。於是想到能夠用檢索系統,傳統的檢索系統是對文檔的內容直接分詞出一個個token後建索引,這裏是對query,進行特殊“分詞”出那些關聯的token去建索引。
最後,假設要把糾錯和相關搜索結合在一起,就有非常多綜合考慮了。總之相關搜索是檢索之外比較影響用戶體驗的一個服務。值得投入精力把它做好。
轉載:http://blog.csdn.net/lgnlgn/article/details/8760785
solr入門之solr的拼寫檢查功能的應用級別嘗試