solr创建索引

在上一篇文章中,我谈到了Solr Spellchecker的工作原理,然后向您展示了其性能的一些测试结果。 现在,我们将看到另一种拼写检查方法。
与其他方法一样,此方法使用两步过程。 相当快速的“候选单词”选择,然后对这些单词评分。 我们将从Solr使用的方法中选择不同的方法并测试其性能。 我们的主要目标是修正的有效性,第二个方面是提高结果的速度。 考虑到我们正在获得结果的正确性,我们可以忍受稍慢的性能。
我们的策略是使用特殊的Lucene索引,并使用模糊查询对其进行查询以获取候选列表。 然后,我们将使用Python脚本对候选人进行排名(如果获得更好的结果,可以轻松地在Solr拼写检查器子类中对其进行转换)。

候选人选择

历史上,模糊查询一直被认为是性能较慢的查询,但是由于在1.4版本中已对其进行了优化,因此对于我们算法的第一部分来说,它们是一个不错的选择。 因此,这个想法将非常简单:我们将构建一个Lucene索引,其中每个文档都是一个字典单词。 当我们必须纠正一个拼写错误的单词时,我们将对该单词进行简单的模糊查询并获得结果列表。 结果将是与我们提供的单词相似的单词(即,编辑距离较小)。 我发现,大约有70名候选人可以使我们获得出色的成绩。
对于模糊查询,我们涵盖了所有的错字,因为正如我在上一篇文章中所说,大多数错字相对于正确的单词的编辑距离均为1。 但是,尽管这是人们在键入时最常见的错误,但还有其他类型的错误。

我们可以找到三种拼写错误[Kukich] :

  1. 印刷错误
  2. 认知错误
  3. 语音错误
当人们知道正确的拼写但在打字时却使运动协调失误时,就会出现打字错误。 认知错误是由于人的知识不足引起的。 最后,语音错误是认知错误的一种特殊情况,认知错误是指听起来正确但拼写错误的单词。 我们已经用模糊查询解决了印刷错误,但是我们也可以为语音错误做些事情。 Solr的分析包中有一个语音过滤器,其中除其他外,还具有双重语音识别算法。 以相同的方式执行模糊查询以查找相似的单词,我们可以为该单词的等效语音索引并对其执行模糊查询。 我们必须手动获取该单词的等效词(因为Lucene查询解析器不会分析模糊查询),并使用该单词构造一个模糊查询。

简而言之,对于候选选择,我们使用以下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:创建拼写检查器相关推荐

  1. Solr:创建拼写检查器

    在上一篇文章中,我谈到了Solr Spellchecker的工作原理,然后向您展示了其性能的一些测试结果. 现在,我们将看到另一种拼写检查方法. 与其他方法一样,此方法使用两步过程. 相当快速的&qu ...

  2. [Google API](6)拼写检查器和缓存页面

    作为 Google 创建索引过程的有机组成部分,Google 要检索被建立索引的页面副本,在搜索结果中为用户提供到缓存页面的链接.主要的缺点是用户看不到更新后的内容,但一些优点也是存在的. 检索缓存页 ...

  3. apache lucene_Apache Lucene拼写检查器的“您是不是要”功能

    apache lucene Google的"您是不是要"功能 在上一篇文章中对Lucene进行了介绍之后 ,现在是时候提高它并创建一个更复杂的应用程序了. 您肯定最熟悉Google ...

  4. Apache Lucene拼写检查器的“您是不是要”功能

    Google的"您是不是要"功能 在上一篇文章中对Lucene进行了介绍之后 ,现在是时候提高它,创建一个更复杂的应用程序了. 您肯定最熟悉Google的"您是不是要&q ...

  5. python代码大全p-21行Python代码实现拼写检查器

    引入 大家在使用谷歌或者百度搜索时,输入搜索内容时,谷歌总是能提供非常好的拼写检查,比如你输入 speling,谷歌会马上返回 spelling. 下面是用21行python代码实现的一个简易但是具备 ...

  6. 拼写检查工具是android,Android的文本和输入---拼写检查器(一)-Go语言中文社区...

    Android平台提供能够让你在应用程序中执行和访问拼写检查的拼写检查器框架.这个框架是由Android平台提供的文本服务API之一. 要在应用程序中使用该框架,你就要创建一个特殊的Android服务 ...

  7. python拼写错误20几分钟怎么办_Python | 21行轻松搞定拼写检查器

    引入 大家在使用谷歌或者百度搜索时,输入搜索内容时,谷歌总是能提供非常好的拼写检查,比如你输入 speling,谷歌会马上返回 spelling. 下面是用21行python代码实现的一个简易但是具备 ...

  8. Mindjet MindManager 出现“拼写检查器出错”等类似问题

    在Mindjet MindManager安装好之后可能会出现该问题,也有可能在未知的条件下出现该问题. 虽然该问题可能并不影响使用,但是每次打开都会弹出一次还是会感觉到厌烦的. 该问题复现: 创建新的 ...

  9. Visual Studio 17.5 拼写检查器预览版现已推出,来说说你的看法吧

    写在前面: Visual Studio17.5版本已添加拼写检查器功能,Visual Studio 中的许多功能旨在帮助你编写所需的代码.Visual Studio帮助你确保代码的编译,甚至可以帮助代 ...

最新文章

  1. apk解密工具_手机端操作| Auto.js一键解密/一键加密工具免费分享
  2. 如何选择一个合适的建站系统?
  3. 不想工作就想创业?我劝你看完这档综艺再决定
  4. 开发指南专题十:JEECG微云快速开发平台--表单校验组件ValidForm
  5. 怎样在word中同时输入上下标
  6. POJ 1789(最小生成树)
  7. UI设计灵感|挑战经典!不一样的注册登录页
  8. c++ string 无法通过下标访问_数组下标1你见过吗?
  9. SAP销售订单状态修改(审核) 计划行自动产生需求,产生MD04需求
  10. 2019 ,我的新年Flag
  11. 铁甲雄心机器人建造成本_铁甲雄心最强机器人
  12. 中国的程序员培训是不是有问题?
  13. 【收藏防丢】rar压缩包忘记密码怎么办?手把手教你轻松解决
  14. GitHub 中国区前 100 名到底是什么样的人
  15. javaScript基础语法知识点总结
  16. 线性代数 06 克莱默法则
  17. 粘结剂菱镁板建筑材料英国UKCA认证—EN 14016-1
  18. K3s - 安装部署
  19. 编译Busybox产生的两个错误
  20. 「雕爷学编程」Arduino动手做(25)——MQ2气敏检测模块

热门文章

  1. mysql查询优化explain命令详解
  2. 你必须了解Spring的生态
  3. List转数组toArray方法
  4. 对于自绝对父相的理解
  5. 三个剩两个,两个剩一个,最后一个都没剩下。
  6. java实现打印菱形
  7. 使用Jersey跨服务器上传图片 报405 Method Not Allowed错误
  8. linux container 原理,容器概念与Linux Container原理
  9. 基础笔试编程题(jz)
  10. HDU2059(DP)