Solr:创建拼写检查器
生活随笔
收集整理的這篇文章主要介紹了
Solr:创建拼写检查器
小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
在上一篇文章中,我談到了Solr Spellchecker的工作原理,然后向您展示了其性能的一些測(cè)試結(jié)果。 現(xiàn)在,我們將看到另一種拼寫檢查方法。 與其他方法一樣,此方法使用兩步過程。 相當(dāng)快速的“候選單詞”選擇,然后對(duì)這些單詞評(píng)分。 我們將從Solr使用的方法中選擇不同的方法并測(cè)試其性能。 我們的主要目標(biāo)是校正的有效性,第二個(gè)方面是結(jié)果的速度。 考慮到我們正在獲得結(jié)果的正確性,我們可以忍受稍慢的性能。 我們的策略是使用特殊的Lucene索引,并使用模糊查詢對(duì)其進(jìn)行查詢以獲取候選列表。 然后,我們將使用Python腳本對(duì)候選人進(jìn)行排名(如果獲得更好的結(jié)果,可以在Solr拼寫檢查器子類中輕松對(duì)其進(jìn)行轉(zhuǎn)換)。 印刷錯(cuò)誤 認(rèn)知錯(cuò)誤 語音錯(cuò)誤 當(dāng)人們知道正確的拼寫但在打字時(shí)卻使運(yùn)動(dòng)協(xié)調(diào)失誤時(shí),就會(huì)出現(xiàn)打字錯(cuò)誤。 認(rèn)知錯(cuò)誤是由于人的知識(shí)不足引起的。 最后,語音錯(cuò)誤是認(rèn)知錯(cuò)誤的一種特殊情況,認(rèn)知錯(cuò)誤是指聽起來正確但拼寫錯(cuò)誤的單詞。 我們已經(jīng)用模糊查詢解決了印刷錯(cuò)誤,但是我們也可以為語音錯(cuò)誤做些事情。 Solr的分析軟件包中有一個(gè)語音過濾器,其中除其他外,還具有雙重語音識(shí)別算法。 以相同的方式執(zhí)行模糊查詢以找到相似的單詞,我們可以為該單詞的等效語音索引并對(duì)其執(zhí)行模糊查詢。 我們必須手動(dòng)獲取該單詞的等效詞(因?yàn)長(zhǎng)ucene查詢解析器不會(huì)分析模糊查詢),并使用該單詞構(gòu)造一個(gè)模糊查詢。
候選人選擇
歷史上,模糊查詢一直被認(rèn)為是與其他查詢相比性能較慢的查詢,但由于它們已在1.4版本中進(jìn)行了優(yōu)化,因此對(duì)于我們算法的第一部分而言,它們是一個(gè)不錯(cuò)的選擇。 因此,這個(gè)想法將非常簡(jiǎn)單:我們將構(gòu)建一個(gè)Lucene索引,其中每個(gè)文檔都是一個(gè)字典單詞。 當(dāng)我們必須糾正一個(gè)拼寫錯(cuò)誤的單詞時(shí),我們將對(duì)該單詞進(jìn)行簡(jiǎn)單的模糊查詢并獲得結(jié)果列表。 結(jié)果將是與我們提供的單詞相似的單詞(即,編輯距離較小)。 我發(fā)現(xiàn),大約有70名候選人可以使我們獲得出色的成績(jī)。 對(duì)于模糊查詢,我們涵蓋了所有錯(cuò)別字,因?yàn)檎缥以谏弦黄恼轮兴f,大多數(shù)錯(cuò)字相對(duì)于正確單詞的編輯距離均為1。 但是,盡管這是人們?cè)阪I入時(shí)最常見的錯(cuò)誤,但還有其他類型的錯(cuò)誤。我們可以找到三種拼寫錯(cuò)誤[Kukich] :
簡(jiǎn)而言之,對(duì)于候選選擇,我們使用以下solr模式構(gòu)建索引:
<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字段包含單詞的“音似”。 頻率字段將在算法的下一階段中使用。 它只是該術(shù)語在語言中的出現(xiàn)頻率。 我們?nèi)绾喂烙?jì)語言中一個(gè)單詞的出現(xiàn)頻率? 計(jì)算大文本語料庫中單詞的出現(xiàn)頻率。 在這種情況下,術(shù)語的來源是維基百科,我們使用Solr的TermComponents來計(jì)算每個(gè)術(shù)語在維基百科中出現(xiàn)的次數(shù)。 但是維基百科是由會(huì)出錯(cuò)的普通人編寫的! 我們?nèi)绾尾拍軐⑵湟暈椤罢_的字典”? 我們利用撰寫維基百科的人們的“集體知識(shí)”。 這個(gè)從維基百科提取的術(shù)語詞典有很多術(shù)語! 超過1.800.00,其中大多數(shù)甚至都不是單詞。 維基百科中可能正確拼寫了高頻單詞。 從大量的單詞庫構(gòu)建字典并考慮最正確的單詞的這種方法并不新鮮。 在[Cucerzan]中,他們使用相同的概念,但使用查詢?nèi)罩緛順?gòu)建字典。 可以看出Google的“您的意思是”使用了類似的概念 。 我們可以在這里添加一些優(yōu)化。 我發(fā)現(xiàn)我們可以刪除一些單詞并獲得良好的結(jié)果。 例如,我刪除了頻率為1的單詞和以數(shù)字開頭的單詞。 我們可以根據(jù)其他條件繼續(xù)刪除單詞,但是我們將像這樣保留它。 因此,建立索引的過程很簡(jiǎn)單,我們通過Solr的TermsComponent從Wikipedia索引中提取所有術(shù)語以及頻率,然后使用SolrJ在Solr中創(chuàng)建索引。候選人排名
現(xiàn)在的候選人排名。 對(duì)于算法的第二階段,我們將利用信息論,尤其是噪聲信道模型 。 應(yīng)用于這種情況的嘈雜通道假定人類知道一個(gè)單詞的正確拼寫,但是通道中的一些噪聲會(huì)引入錯(cuò)誤,結(jié)果我們得到另一個(gè)拼寫錯(cuò)誤的單詞。 我們憑直覺知道在嘗試鍵入“ house”時(shí)我們不太可能會(huì)收到“ sarasa”,因此嘈雜的渠道模型引入了某種形式來確定錯(cuò)誤的可能性。 例如,我們拼錯(cuò)了“ houze”,我們想知道哪一個(gè)是我們最想輸入的單詞。 為了實(shí)現(xiàn)這一點(diǎn),我們擁有大量可能的單詞詞典,但并非所有單詞都具有同等的可能性。 我們希望獲得打算輸入的可能性最高的單詞。 在數(shù)學(xué)中稱為條件概率; 假設(shè)我們鍵入“ houze”,那么每個(gè)正確單詞成為我們想要的單詞的可能性有多高。 條件概率的表示法是:P('house'|'houze')表示給定“ houze”時(shí)“ house”的概率 這個(gè)問題可以從兩個(gè)角度看待:我們可能認(rèn)為最常見的詞更有可能,例如,“ house”比“ hose”更有可能,因?yàn)榍罢呤且粋€(gè)更常見的詞。 另一方面,我們也憑直覺認(rèn)為“房屋”比“光合作用”更有可能,因?yàn)閮蓚€(gè)詞之間的差異很大。 這兩個(gè)方面均由貝葉斯定理正式推導(dǎo): 我們必須最大化這種可能性,并且只有一個(gè)參數(shù):正確的候選單詞(在所示情況下為“ house”)。 因此,拼寫錯(cuò)誤的單詞的概率將是恒定的,我們對(duì)此不感興趣。 公式簡(jiǎn)化為 為了增加更多的結(jié)構(gòu),科學(xué)家給這兩個(gè)因素命名。 P('houze'|'house')因子是錯(cuò)誤模型(或通道模型),并且與通道在嘗試寫入第二個(gè)單詞時(shí)引入此特定拼寫錯(cuò)誤的可能性有關(guān)。 第二個(gè)術(shù)語P('house')稱為語言模型,它使我們了解單詞在語言中的普遍程度。 到目前為止,我僅介紹了該模型的數(shù)學(xué)方面。 現(xiàn)在我們必須提出這兩個(gè)概率的具體模型。 對(duì)于語言模型,我們可以在文本語料庫中使用術(shù)語的頻率。 從經(jīng)驗(yàn)上我發(fā)現(xiàn),使用頻率的對(duì)數(shù)比單獨(dú)使用頻率要好得多。 也許這是因?yàn)槲覀円炔唤?jīng)常使用的術(shù)語減少更多頻繁使用的術(shù)語的權(quán)重,而對(duì)數(shù)正是這樣做的。 不僅存在一種構(gòu)造渠道模型的方法。 已經(jīng)提出了許多不同的想法。 我們將使用一個(gè)基于Damerau-Levenshtein距離的簡(jiǎn)單距離。 但是我也發(fā)現(xiàn),第一階段的模糊查詢?cè)谡业胶蜻x者方面做得很好。 在某些數(shù)據(jù)集的一半以上的測(cè)試用例中,它首先給出了正確的單詞。 因此,通道模型將是Damerau-Levenshtein距離和Lucene為模糊查詢條件創(chuàng)建的得分的組合。排名公式為:
我編寫了一個(gè)小腳本(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個(gè)候選人的列表。 該特定數(shù)字是根據(jù)經(jīng)驗(yàn)找到的。 候選數(shù)越高,算法就越慢,而算法越少,則效果越差。 我們還將第30行的候選單詞中的拼寫錯(cuò)誤的單詞排除在外。由于我們使用Wikipedia作為來源,因此常見的是在詞典中找到了拼寫錯(cuò)誤的單詞。 因此,如果Leveshtain距離為0(相同的單詞),我們將其距離加1000。測(cè)驗(yàn)
我使用此算法進(jìn)行了一些測(cè)試。 第一個(gè)將使用Peter Norvig在他的文章中使用的數(shù)據(jù)集。 我在大約80%的情況下都在第一個(gè)位置找到了該單詞的正確建議!!! 那是一個(gè)非常好的結(jié)果。 具有相同數(shù)據(jù)集(但算法和訓(xùn)練集不同)的Norvig獲得了67%現(xiàn)在,讓我們重復(fù)上一篇文章的一些測(cè)試,以查看改進(jìn)。 在下表中,我向您顯示結(jié)果。
| 測(cè)試集 | %Solr | %新 | Solr時(shí)間[秒] | 新時(shí)間[秒] | 改善 | 時(shí)間損失 |
| 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% |
我們可以看到我們?cè)诟恼Ч矫娴玫搅撕芎玫母倪M(jìn),但是大約需要兩倍的時(shí)間。
未來的工作
我們?nèi)绾胃倪M(jìn)此拼寫檢查器。 好了,研究候選人名單后,可以發(fā)現(xiàn)其中通常包含正確單詞(95%的次數(shù))。 因此,我們所有的努力都應(yīng)旨在改進(jìn)評(píng)分算法。 我們有許多改善渠道模型的方法; 幾篇論文表明,根據(jù)語言統(tǒng)計(jì)數(shù)據(jù)計(jì)算更復(fù)雜的距離,對(duì)不同的字母變換加權(quán),可以為我們提供更好的度量。 例如,我們知道寫'houpe'的可能性比寫'houze'的可能性小。 對(duì)于語言模型,可以通過向單詞添加更多上下文來獲得重大改進(jìn)。 例如,如果我們拼錯(cuò)了“ nouse”,很難說出正確的單詞是“ house”或“ mouse”。 但是,如果我們添加更多的單詞“畫我的鼻子”,則很明顯,我們所尋找的單詞是“房子”(除非您有與嚙齒動(dòng)物有關(guān)的奇怪習(xí)慣)。 這些也稱為ngram(在這種情況下是單詞,而不是字母)。 Google已提供了大量ngram,可以下載它們的頻率。 最后但并非最不重要的一點(diǎn)是,可以通過用Java編寫腳本來提高性能。 該算法的一部分在python中。 再見! 作為對(duì)所有感興趣的人的更新,Robert Muir在“ Solr用戶”列表中告訴我 ,有一個(gè)新的拼寫檢查器DirectSpellChecker,當(dāng)時(shí)在后備箱中,現(xiàn)在應(yīng)該是Solr 3.1的一部分。 它使用與本條目中介紹的技術(shù)類似的技術(shù),而不會(huì)降低性能。 參考文獻(xiàn) [Kukich] Karen Kukich –自動(dòng)糾正文本中的單詞的技巧– ACM計(jì)算調(diào)查–第24卷第4期,1992年12月 [Cucerzan] S. Cucerzan和E. Brill拼寫校正是一個(gè)利用Web用戶集體知識(shí)的迭代過程。 2004年7月 Peter Norvig –如何編寫拼寫校正器參考: emmaespina博客上的JCG合作伙伴 Emmanuel Espina 用Solr創(chuàng)建了拼寫檢查 工具 。
翻譯自: https://www.javacodegeeks.com/2012/06/solr-creating-spellchecker.html
創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎(jiǎng)勵(lì)來咯,堅(jiān)持創(chuàng)作打卡瓜分現(xiàn)金大獎(jiǎng)總結(jié)
以上是生活随笔為你收集整理的Solr:创建拼写检查器的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 我的世界电脑版生存模式合成表(我的世界生
- 下一篇: Grails动态下拉菜单