solr创建索引_Solr:创建拼写检查器
生活随笔
收集整理的這篇文章主要介紹了
solr创建索引_Solr:创建拼写检查器
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
solr創建索引
在上一篇文章中,我談到了Solr Spellchecker的工作原理,然后向您展示了其性能的一些測試結果。 現在,我們將看到另一種拼寫檢查方法。 與其他方法一樣,此方法使用兩步過程。 相當快速的“候選單詞”選擇,然后對這些單詞評分。 我們將從Solr使用的方法中選擇不同的方法并測試其性能。 我們的主要目標是修正的有效性,第二個方面是提高結果的速度。 考慮到我們正在獲得結果的正確性,我們可以忍受稍慢的性能。 我們的策略是使用特殊的Lucene索引,并使用模糊查詢對其進行查詢以獲取候選列表。 然后,我們將使用Python腳本對候選人進行排名(如果獲得更好的結果,可以輕松地在Solr拼寫檢查器子類中對其進行轉換)。候選人選擇
歷史上,模糊查詢一直被認為是性能較慢的查詢,但是由于在1.4版本中已對其進行了優化,因此對于我們算法的第一部分來說,它們是一個不錯的選擇。 因此,這個想法將非常簡單:我們將構建一個Lucene索引,其中每個文檔都是一個字典單詞。 當我們必須糾正一個拼寫錯誤的單詞時,我們將對該單詞進行簡單的模糊查詢并獲得結果列表。 結果將是與我們提供的單詞相似的單詞(即,編輯距離較小)。 我發現,大約有70名候選人可以使我們獲得出色的成績。 對于模糊查詢,我們涵蓋了所有的錯字,因為正如我在上一篇文章中所說,大多數錯字相對于正確的單詞的編輯距離均為1。 但是,盡管這是人們在鍵入時最常見的錯誤,但還有其他類型的錯誤。我們可以找到三種拼寫錯誤[Kukich] :
簡而言之,對于候選選擇,我們使用以下solr模式構建索引:
<fieldType name="spellcheck_text" class="solr.TextField" positionIncrementGap="100" autoGeneratePhraseQueries="true"><analyzer type="index"><tokenizer class="solr.KeywordTokenizerFactory"/><filter class="solr.LowerCaseFilterFactory"/><filter class="solr.PhoneticFilterFactory" encoder="DoubleMetaphone" maxCodeLength="20" inject="false"/></analyzer></fieldType><field name="original_word" type="string" indexed="true" stored="true" multiValued="false"/><field name="analyzed_word" type="spellcheck_text" indexed="true" stored="true" multiValued="false"/><field name="freq" type="tfloat" stored="true" multiValued="false"/> 如您所見,analyzered_word字段包含單詞的“音似”。 頻率字段將在算法的下一階段中使用。 它只是該術語在語言中的出現頻率。 我們如何估計語言中一個單詞的出現頻率? 計算大文本語料庫中單詞的出現頻率。 在這種情況下,術語的來源是維基百科,我們使用Solr的TermComponents來計算每個術語在維基百科中出現的次數。 但是維基百科是由會出錯的普通人編寫的! 我們如何才能將其視為“正確的字典”? 我們利用撰寫維基百科的人們的“集體知識”。 這個從維基百科提取的術語詞典有很多術語! 超過1.800.00,其中大多數甚至都不是單詞。 維基百科中可能正確拼寫了高頻單詞。 從大量的單詞集構建字典并考慮最正確的單詞的這種方法并不新鮮。 在[Cucerzan]中,他們使用相同的概念,但使用查詢日志來構建字典。 可以看出Google的“您的意思是”使用了類似的概念 。 我們可以在這里添加一些優化。 我發現我們可以刪除一些單詞并獲得良好的結果。 例如,我刪除了頻率為1的單詞和以數字開頭的單詞。 我們可以根據其他條件繼續刪除單詞,但是我們將這樣保留。 因此,建立索引的過程很簡單,我們通過Solr的TermsComponent從Wikipedia索引中提取所有術語以及頻率,然后使用SolrJ在Solr中創建索引。候選人排名
現在的候選人排名。 對于算法的第二階段,我們將利用信息論,尤其是噪聲信道模型 。 應用于這種情況的嘈雜通道假定人類知道一個單詞的正確拼寫,但是通道中的一些噪聲引入了錯誤,結果我們得到了另一個拼寫錯誤的單詞。 我們直觀地知道,在嘗試鍵入“ house”時我們不太可能獲得“ sarasa”,因此嘈雜的渠道模型引入了某種形式來確定錯誤的可能性。 例如,我們拼錯了“ houze”,我們想知道哪一個是我們最想輸入的單詞。 為實現這一點,我們擁有大量可能的單詞詞典,但并非所有單詞都具有相同的可能性。 我們希望獲得打算輸入的可能性最高的單詞。 在數學中稱為條件概率; 假設我們鍵入“ houze”,那么每個正確單詞成為我們想要的單詞的可能性有多高。 條件概率的表示法是:P('house'|'houze')表示給定“ houze”時“ house”的概率 這個問題可以從兩個角度看待:我們可能認為最常見的詞更有可能,例如,“ house”比“ hose”更有可能,因為前者是一個更常見的詞。 另一方面,我們也憑直覺認為“房屋”比“光合作用”更有可能,因為兩個詞的差異很大。 這兩個方面均由貝葉斯定理正式推論: 我們必須最大化這種可能性,并且只有一個參數:正確的候選單詞(在所示情況下為“ house”)。 因此,拼寫錯誤的單詞的概率將是恒定的,我們對此不感興趣。 公式簡化為 為了給它增加更多的結構,科學家給這兩個因素起了名字。 P('houze'|'house')因子是錯誤模型(或通道模型),并且與通道在嘗試寫入第二個單詞時引入此特定拼寫錯誤的可能性有關。 第二個術語P('house')稱為語言模型,它使我們了解單詞在語言中的普遍程度。 到目前為止,我僅介紹了該模型的數學方面。 現在我們必須提出這兩個概率的具體模型。 對于語言模型,我們可以在文本語料庫中使用術語的頻率。 從經驗上我發現,使用頻率的對數比單獨使用頻率要好得多。 也許是因為我們要減少頻繁項的權重,而不是減少頻繁項的權重,而對數正是這樣做的。 不僅存在一種構造渠道模型的方法。 已經提出了許多不同的想法。 我們將使用一個基于Damerau-Levenshtein距離的簡單距離。 但是我也發現,第一階段的模糊查詢在找到候選者方面做得很好。 在某些數據集的一半以上的測試用例中,它首先給出了正確的單詞。 因此,通道模型將是Damerau-Levenshtein距離和Lucene為模糊查詢條件創建的得分的組合。排名公式為:
我編寫了一個小腳本(python),該腳本執行了之前所說的所有操作:
from urllib import urlopen import doubleMethaphone import levenshtain import jsonserver = "http://benchmarks:8983/solr/testSpellMeta/"def spellWord(word, candidateNum = 70):#fuzzy + soundlikemetaphone = doubleMethaphone.dm(word)query = "original_word:%s~ OR analyzed_word:%s~" % (word, metaphone[0])if metaphone[1] != None:query = query + " OR analyzed_word:%s~" % metaphone[1]doc = urlopen(server + "select?rows=%d&wt=json&fl=*,score&omitHeader=true&q=%s" % (candidateNum, query)).read( )response = json.loads(doc)suggestions = response['response']['docs']if len(suggestions) > 0:#scorescores = [(sug['original_word'], scoreWord(sug, word)) for sug in suggestions]scores.sort(key=lambda candidate: candidate[1])return scoreselse:return []def scoreWord(suggestion, misspelled):distance = float(levenshtain.dameraulevenshtein(suggestion['original_word'], misspelled))if distance == 0:distance = 1000fuzzy = suggestion['score']logFreq = suggestion['freq']return distance/(fuzzy*logFreq) 在前面的清單中,我必須做一些說明。 在第2行和第3行中,我們使用Levenshtein距離和變音位算法的第三方庫。 在第8行中,我們正在收集70個候選人的列表。 該特定數字是憑經驗找到的。 候選數越高,算法就越慢,而算法越少,則效果越差。 我們還將第30行的候選單詞中的拼寫錯誤的單詞排除在外。由于我們使用Wikipedia作為來源,因此通常會在字典中找到拼寫錯誤的單詞。 因此,如果Leveshtain距離為0(相同的單詞),我們將其距離加1000。測驗
我使用此算法進行了一些測試。 第一個將使用Peter Norvig在他的文章中使用的數據集。 我在大約80%的情況下都在第一個位置找到了該單詞的正確建議!!! 那是一個非常好的結果。 具有相同數據集(但算法和訓練集不同)的Norvig獲得了67%現在,讓我們重復上一篇文章的一些測試,以查看改進。 在下表中,我向您顯示結果。
| 測試集 | %Solr | %新 | Solr時間[秒] | 新時間[秒] | 改善 | 時間損失 |
| FAWTHROP1DAT.643 | 45,61% | 81,91% | 31,50 | 74,19 | 79,58% | 135,55% |
| batch0.tab | 28,70% | 56,34% | 21,95 | 47,05 | 96,30% | 114,34% |
| SHEFFIELDDAT.643 | 60,42% | 86,24% | 19,29 | 35,12 | 42,75% | 82,06% |
我們可以看到,我們在改正效果方面得到了很好的改進,但是大約需要兩倍的時間。
未來的工作
我們如何改進此拼寫檢查器。 好了,研究候選人名單后,可以發現其中通常包含正確單詞(95%的次數)。 因此,我們所有的努力都應旨在改進評分算法。 我們有許多改進渠道模型的方法; 幾篇論文表明,根據語言統計數據計算更復雜的距離,對不同的字母轉換加權,可以為我們提供更好的度量。 例如,我們知道寫“ houpe”比寫“ houze”的可能性要小。 對于語言模型,可以通過向單詞添加更多上下文來獲得重大改進。 例如,如果我們拼錯了“ nouse”,很難說出正確的單詞是“ house”或“ mouse”。 但是,如果我們添加更多的單詞“畫我的鼻子”,則很明顯,我們所尋找的單詞是“房子”(除非您有與嚙齒動物有關的奇怪習慣)。 這些也稱為ngram(在這種情況下是單詞,而不是字母)。 Google提供了大量ngram,可以下載它們的頻率。 最后但并非最不重要的一點是,可以通過用Java編寫腳本來提高性能。 該算法的一部分在python中。 再見! 作為對所有感興趣的人的更新,Robert Muir在“ Solr用戶”列表中告訴我 ,有一個新的拼寫檢查器DirectSpellChecker,它當時在后備箱中,現在應該是Solr 3.1的一部分。 它使用與本條目中介紹的技術類似的技術,而不會降低性能。 參考資料 [Kukich] Karen Kukich –自動校正文本中的單詞的技術– ACM計算調查–第24卷,第4期,1992年12月 [Cucerzan] S. Cucerzan和E. Brill拼寫校正是一個利用Web用戶集體知識的迭代過程。 2004年7月 Peter Norvig –如何編寫拼寫校正器參考: emmaespina博客上的JCG合作伙伴 Emmanuel Espina 用Solr創建了拼寫檢查 工具 。
翻譯自: https://www.javacodegeeks.com/2012/06/solr-creating-spellchecker.html
solr創建索引
總結
以上是生活随笔為你收集整理的solr创建索引_Solr:创建拼写检查器的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: ddos 软件(可用ddos软件)
- 下一篇: 带有Javaslang的Java 8中的