截止日期后

截止日期后,Bigram语料库——我们送给你的礼物…

发布于新闻,NLP研究2010年7月20日rsmudge

《最后期限后》的热辣酱汁是我们的语言模型.我们使用我们的语言模型为了改进我们的拼写校正器,过滤不适合语法检查的建议,甚至检测您是否使用了错误的单词。

构建一个语言模型并不难,但可能会很耗时。我们的二进制模型文件始终可以通过GPL获得截止日期后分配.

今天,作为我们的礼物,我们将在创造性共同点归因许可证。没有价格过高的财团可以加入,你也不需要大学附属机构来获得这些文件。

以下是文件:

unigrams.txt.gz格式

此文件包含每个单词标记、一个制表符分隔符和一个计数。76932676个单词中有164834个单词。我们的拼写检查器词典由该列表中出现两次或两次以上的单词组成。

有利地4约兰德12菲尔莫尔的4坎塔2卡伊班达3索利曼2论述92约兰达11劝阻者1

大拉姆斯.txt.gz

这个文件是我们语料库中出现的每个两个单词序列的转储。它有5612483个与计数相关联的单词对。您可以使用此信息计算给定下一个或前一个单词的单词的概率。

军事兼并4军事欺骗1军事语言1军事立法1军事复杂性1军官61军事骚乱1军事阴谋1军人退役2

三角音-同音异义词.txt.gz

这个文件有一组有限的三角图(三个单词的序列)。每个三角图以我们的混淆集文本文件。您将需要来自二元词库的信息来构建这些单词的三元概率。

给小狗14只小狗小狗死了1一只小狗和四只一只名叫2的小狗小狗3岁三只小狗一只小狗一只小狗当2

Creative Commons许可证
本作品根据Creative Commons Attribution 3.0未出口许可.

一种校对软件服务的设计

发布于NLP研究2010年6月9日rsmudge

我星期天在计算语言学与写作研讨会关于写作过程和创作辅助工具NAACL-HLT 2010.我在这里介绍截止日期后。截止日期之后是开源校对软件服务。如果你对上下文语法和拼写检查器的工作原理感到好奇,那么你应该继续阅读。以下是材料:

演示

幻灯片

在Scribd上查看此文档

纸类

在Scribd上查看此文档

更多深度

如果你想要更多的深度,我经常写关于AtD的文章。以下是一些您可能感兴趣的相关博客帖子:

测量实词纠错器

发布于NLP研究2010年4月9日rsmudge

在我们开始之前:你注意到我喜欢的、对SEO友好的帖子标题了吗?语言学家将误用的单词称为真正的单词错误。当我在这篇文章中写真实的单词错误时,我实际上指的是《最后期限之后》中的误用单词检测器。

在《最后期限之后》中,我最喜欢的功能之一是真正的单词纠错器。在这篇文章中,我将讨论此功能及其工作原理。我还将对该工具与Microsoft Word 2007对于具有类似功能的Windows,他们称之为上下文拼写检查器。

混淆集

截止日期后有一个1603个单词的列表。在这个列表中,单词被分为混淆组。混淆集是指在写作过程中可能被误用的两个或多个单词。有些人让我感到惊讶,例如,我看到有人在《黑客新闻》上写肖像,而他们的意思是描绘。“肖像”和“描绘”这两个词就是一个混淆的例子。

混淆集是一种带宽和限制,但它们现在有自己的位置。在一个理想的程序中,该软件会查看您使用的任何单词,并尝试使用各种标准来确定您是否指的是其他单词。“截止日期后”并没有做到这一点,因为这意味着要存储更多关于每个单词以及如何使用的信息,而我谦逊的服务器无法处理这些信息。由于内存(和CPU限制),我根据这些固定的混淆集限制了检查的单词。

查找错误

为了检测真实的单词错误,在截止日期后扫描文档,查找可能被误用的单词列表中的任何单词。当AtD遇到其中一个单词时,它会查看该单词的混淆集,并检查是否有其他单词更适合。

这是怎么发生的?这很简单。AtD查看可能被误用的单词的左边和右边的两个单词,并尝试确定混淆集中的哪个单词最适合。这看起来像:

我承认,网站确实如此肖像可靠性。

在这里,“截止日期后”使用以下统计特征来决定您想要的单词W(肖像或描绘):

P(W |站点,does)
P(W |可信度,结束)
P(W|做)
P(W |可信度)
P(宽)

一个单词给出前两个单词的概率是用三角图计算的。当截止日期后学习一门语言时,它会存储它找到的两个单词的每个序列,以及以混淆集开始或结束的三个单词的序列。要计算一个单词在接下来的两个单词中的概率,需要使用三角图和一点代数贝叶斯原理。我在上写了一篇帖子语言模型早期的。为了将所有这些结合在一起,在截止日期之后使用神经网络将这些统计特征组合成0.0到1.0之间的一个分数。得分最高的单词获胜。为了避免误报,将当前单词乘以10,以确保它在不明确的情况下获胜。

让我们衡量一下

好的,那么自然的问题是,这工作得怎么样?每次我在最后期限后重建时,我都会运行一系列测试来检查神经网络评分功能,并告诉我它的正确频率和错误频率。这种评估是一种很好的单元测试,但很难接近真实值单词它的世界表现。

幸运的是,詹妮弗·佩德勒博士 博士论文已经覆盖了我们。在她的论文中,她开发并评估了检测真实单词错误的技术,以帮助患有阅读障碍的作家。她的研究包括收集编写示例来自有阅读障碍的作家,并注释错误以及预期的更正。我查看了她的数据,发现835个错误中有97.8%是真字错误。非常适合评估实词错误校正器。

我们认为语法检查器领域中的许多东西实际上是真实的单词错误。错误包括错误的动词时态(例如build和build)、不定冠词(a和an)和错误的限定词(the、their等),这些都是真正的单词错误。你可能会问,真正的单词错误检测可以应用于语法检查吗?是的,其他人正在努力测试“截止日期后”作为一个完整的系统(语法检查器、误用单词检测器等)纠正这些错误的效果是有意义的。

为了测试截止日期之后,我写了一个睡眠脚本将Pedler博士的错误语料库的更正版本与有错误的原始语料库进行比较。该软件可以测量发现的错误数量和更改为某个内容的次数(召回),以及这些更改的正确频率(精度)。此测试不测量正确或错误更改的注释错误之外的元素数。

要运行它:

grep-v“\-\-\-”corrected.txt>corrected.clean.txt
java-jar sleep.jar measure.sl已更正.clean.txt

现在,我们可以使用佩德勒博士的数据将一种书写系统与另一种进行比较。我们需要做的就是将错误语料库粘贴到系统中,接受每一个建议,并对其运行度量脚本。为了生成错误文件,我编写了另一个脚本,读取Pedler博士的数据并删除注释:

java-jar sleep.jar errors.sl>errors.txt

现在我们准备好了。以下是与Windows上的Microsoft Word 2007、Mac上的Microsoft Word 2008以及MacOS X 10.6中内置的苹果语法和拼写检查器相比的数字。我包括了Microsoft Word 2008和苹果软件,因为这两个软件都没有上下文拼写检查器。他们仍然使用语法检查技术纠正了一些真实的单词错误。

系统 精密度 召回
MS Word 2007–Windows 90.0% 40.8%
截止日期后 89.4% 27.1%
MS Word 2008–MacOS X 79.7% 17.7%
MacOS X拼写和语法检查器 88.5% 9.3%

如您所见,Windows上的Microsoft Word 2007在召回部门表现良好。阅读障碍语料库中的每一个错误,如果不在“截止日期后”的混淆集中,都会自动打击回忆。不过,这两种系统的精度是相似的。

你可以自己试试这个实验。这个代码和数据可用。我还创建了一页在这里,您可以粘贴到文档中,只需单击一次即可接受所有建议。

另一个评估

另一个MS Word 2007的真实错误检测评估由多伦多大学格雷姆·赫斯特于2008年出版。他发现MS Word对错误的回忆能力较低。为了评估MS Word,他在《华尔街日报》语料库中随机插入(1:200个单词)真实错误,然后测量系统性能。这将对研究界(尤其是*咳嗽*我们这些大学以外的人*咳嗽*)如果对可以重新分配的数据进行此类测试。

最后的想法

运行完这个实验后,我添加了与佩德勒博士的困惑集对AtD现有的混淆集,按下神奇的按钮来重建模型,并重新运行这些测试。我看到AtD的召回率上升到33.9%,准确率为86.6%。扩展AtD中使用的混淆集将提高AtD的实际纠错性能。

我将继续在《最后期限之后》中增加混淆集的数量。导入多个单词的整体销售面临的一个挑战是,当使用此处描述的方法进行检查时,某些单词比其他单词产生更多的误报(因此,当向误用单词检测器添加几个未评估的新词时,精确度会下降)。

如果你在Windows上使用Microsoft Word 2007,你会得到很好的帮助。尽管如此,在MSWord2007不可用的情况下,“截止日期后”在实际的错误检测部门中仍具有可比性。

如果你使用Mac,你应该截止日期后使用.

谦逊的起源:PolishMyWriting.com

发布于NLP研究,自言自语2010年3月19日rsmudge

我今天找到了一张旧的截图,想和大家分享一下,让大家了解一下(1)我的设计眼光有多差,以及(2)《最后期限之后》的一些历史。在截止日期之后,我开始了在PolishMyWriting.com上作为网络风格检查器的生活。我的目标是什么?说服人们粘贴他们的文档以即时收到反馈,而我从广告收入中赚了很多钱。当时这似乎是个好主意。

PolishMyWriting.com截图

原创PolishMyWriting.com

PolishMyWriting.com没有检查拼写、误用单词或语法。它依据2283条规则来寻找要避免的短语、术语、有偏见的短语、陈词滥调、复杂短语、外来词和多余短语。系统中最复杂的自然语言处理检测到被动语态和隐藏动词。但我不认为它很复杂。我引用了图表并编写了简单的启发法来捕捉不同形式的被动语态。有趣的是,这和今天《最后期限之后》中使用的被动语音检测器是一样的。

此基于规则的系统向最终用户提供其所有建议(无需筛选或重新排序)。A类黑客新闻用户同意50%它不得不说什么,这还不算太糟糕。在今天的截止日期之后,查看它标记的任何短语的上下文,并尝试决定建议是否合适。A类最近的审阅者《最后期限后》的作者表示,他同意其中75%的观点。进步!

PolishMyWriting.com的工作原理

我最喜欢PolishMyWriting.com的部分是它如何存储规则。所有的规则都折叠成一棵树。从文档中的每个单词位置,系统将查找最深匹配的树。这样,PolishMyWriting.com只需评估与文本中给定位置相关的规则。比赛很容易马上失败(嘿,当前单词与规则的任何可能起始单词都不匹配)。有了它,我可以创建任意多的规则,而不会影响系统的性能。今天《最后期限之后》中的规则树有33331个最终状态。还不错。

PolishMyWriting.com规则树

PolishMyWriting.com规则树

上面的规则树匹配六条规则。如果我给它一句话:我不记得写了很多帖子。系统将从意识到无处可去。下一个词是。它会看并检查是否有来自在树上匹配后面的单词在句子中。在这种情况下比赛。系统从以下位置重复此过程。下一个匹配的单词是成功在这里,PolishMyWriting.com将提出以下建议没有成功发送给用户。如果搜索未能找到的结束状态没有成功,系统将前进到从头开始重复这个过程。由于找到匹配项,该过程将从写了很多帖子.结果我[忘了]写[很多很多]博客帖子.

PolishMyWriting.com怎么了?

我最终放弃了PolishMyWriting.com这个名字。主要是因为我不断听到人们在网上(和当面)开玩笑,说我为波兰人开发了一个写作资源是多么棒。它仍然存在,主要是作为一个地方以证明截止日期之后。

别忘了,如果PolishMyWriting.com能帮你。。您可以使用我们的漂亮的横幅图案. 😉

关于语言模型

发布于NLP研究2010年3月4日rsmudge

大多数自然语言处理任务的挑战之一是获取数据并将其分解为可用的模型。准备大型数据集足够硬了。一旦准备好了,就必须将其放入语言模型中。我的旧NLP实验室(由两台我花了100美元从康奈尔大学买来的计算机组成)花了18个小时建立我的语言模型。你可能有比我更好的硬件。

拯救痛苦

如果可以的话,我想帮你省去一些痛苦和麻烦。这就是我今天写博客的原因。你知道截止日期后预先构建的二元语言英语、德语、西班牙语、法语、意大利语、波兰语、印尼语、俄语、荷兰语和葡萄牙语的模型?这是10种语言!

此外,您知道After the Deadline语言模型是一个简单的序列化Java对象吗。事实上,使用它的唯一依赖项是一个Java类。现在我已经让你兴奋了,让我们问一下……你能用语言模型做什么?

语言模型API

二元语法模型具有文本集合中两个单词的每个序列的计数。根据这些信息,你可以计算出各种有趣的东西。

作为管理说明,我将使用睡眠编程语言对于这些示例。这段代码很容易移植到Java,但我在飞机上,太懒了,不想编写编译器。

让我们加载Sleep交互式解释器并加载英语模型。您可以假设所有这些命令都是从After the Deadline源代码发行版的顶级目录中执行的。

$java-Xmx1536M-jar库/sleep.jar>>欢迎使用睡眠脚本语言>相互作用>>欢迎使用交互式模式。键入代码,然后键入“.”在一行上单独执行代码。单独在一行上键入Ctrl+D或“done”以退出交互模式。导入*from:lib/spellutils.jar;$handle=openf('models/model.bin');$model=readObject($handle);关闭($handle);println(“加载的$模型”);.加载org.dashnine.preforitor.LanguageModel@5cc145f9完成

现在你有了它。一个语言模型供你使用。我将向您介绍每个API方法。

统计字数

count方法返回看到指定单词的次数。

示例:

>x[$modelcount:“hello”]153>x[$型号计数:“世界”]26355>x[$型号计数:“the”]3046771

 

单词概率

Pword方法返回单词的概率。Java调用它的方法是model。Pword(“单词”)。

>x[$model Pword:“the”]0.061422322118108906>x[$model Pword:“自动”]8.063923690767558E-7号>x[$model Pword:“fjsljnfnsk”]0

 

带上下文的单词概率

这很简单。当你可以查看上下文时,语言模型的有趣部分就出现了。想象一下这个句子:“我想成为一名演员”。通过语言模型,我们可以比较单词bee与给定上下文的单词的匹配度。上下文概率函数允许您这样做。

Pbigram1(“上一个”,“单词”)

此方法计算P(单词|前一个)或指定单词给定前一个单词的概率。这是我们的二元语法模型最直接的应用。毕竟,我们掌握了在我们训练的语料库中看到的所有“前一个单词”的数量。我们只需将其除以之前的计数即可得出答案。在这里,我们使用我们的上下文概率来研究be和bee。

>x[$model Pbigram1:“to”,“bee”]1.8397294594205855E-5型>x[$model Pbigram1:“to”,“be”]0.06296975819264979

 

Pbigram2(“单词”,“下一个”)

此方法计算P(单词|下一个)或指定单词给定下一个单词的概率。它是如何做到的?这是贝叶斯定理的一个简单应用。贝叶斯定理让我们在概率中翻转条件。计算如下:P(单词|下一个)=P(下一个单词)*P(单词)/P(下一步)在这里,我们使用它来进一步研究be与bee的概率:

>x[$model Pbigram2:“蜜蜂”,“安”]0>x[$model Pbigram2:“be”,“an”]0.014840446919206074

 

如果你是一台电脑,你会认为作者的意思是什么?

一个小技巧

这些方法还将在计算概率的参数中接受两个单词的序列。我用这个技巧将拼写错误的单词分段,每对字母之间用空格隔开,并将结果与其他拼写建议进行比较。

>x[$model Pword:“纽约”]3.3241509434266565E-4号>x[$model Pword:“很多”]2.198830392380437E-4号>x[$model Pbigram1:“它”,“很多”]8.972553689218159E-5号>x[$model Pbigram2:“很多”,'0END.0']6.511467636360339E-7号

你会注意到的0结束。0这是一个特殊的单词。它代表一个句子的结尾。0开始。0表示句子的开头。这些模型跟踪的唯一标点符号是','。您可以直接参考。

收集字典

我对语言模型的一个用途是转储拼写检查字典。我通过收集所有出现两次或两次以上的单词来做到这一点。当我添加足够的数据时,我将提高此数字以获得高质量词典。要获取词典:

>x[$模型收获:1000000][a,of,to,and,the,0END.0,0BEGIN.0]

 

此命令收集出现一百万次或更多次的所有单词。正如你所见,没有太多。我现在的语言模型是从7500万个单词的文本中派生出来的。

下一步

简而言之,这就是最后期限后的语言模型。还有一种方法可以根据单词前面的两个单词来计算单词的概率。这是使用三角图来完成的。我没有在这里写这篇文章,因为AtD只存储被误用单词检测器跟踪的单词的三角图。

也就是说,使用这种数据可以获得很多乐趣。

下载截止日期后的开源发布。您可以在models/model.bin中找到英语模型。您也可以从lib目录中获取spellutils.jar。

如果您想尝试其他语言中的双字组截止日期后语言包拥有其他九种语言的训练有素的语言模型。

英语语言模型的培训来源包括古登堡计划维基百科其他语言模型是从各自的维基百科转储中训练出来的。

祝你好运,玩得开心。

截止日期后是一个开源语法、样式和拼写检查器。与其他工具不同,它使用上下文为错误提供明智的建议。插件可用于Firefox、WordPress等。

基于NGramJ的N-Gram语言猜测

发布于多语言AtD,NLP研究2010年2月8日rsmudge

NGramJ公司是用于语言识别的Java库。它使用语言配置文件(字符序列计数)来猜测任意文本是什么语言。在本文中,我将简要介绍如何从命令行和Java API使用它。我还将向您展示如何生成新的语言配置文件。我这样做是为了不必再去想怎么做了。

正在运行

通过在命令行上尝试,您可以了解NGramJ的工作情况。例如:

$猫>a.txt这是一个测试。$java-jar cngram.jar-lang2 a.txt速度:en:0.667 ru:0.000 pt:0.000。。de:0.000|0.0E0|0.0E0 dt=2812$cat>b.txt文件维基百科作者ein Projekt zum Aufbau einer Enzyklopädie aus freien Inhalten in allen Sprachen der Welt。$java-jar cngram.jar-lang2 b.txt速度:de:0.857 ru:0.000 pt:0.000。。英语:0.000|0.0E0|0.0E0 dt=2077

使用

我喜欢这个程序的API,它很简单。它也是线程安全的。您可以实例化库的静态引用,然后从任何线程调用它。这里有一些代码采用自这个Flaptor实用程序库。

导入de.spieleck.app.cngram。NGramProfiles;protected NGramProfiles profiles=新建NGramProfiles();public String getLanguage(字符串文本){NGramProfiles。Ranker-Ranker=档案.getRanker();等级账户(文本);NGramProfiles。排名结果结果=ranker.getRankResult();return result.getName(0);}

现在您已经知道如何使用库进行语言猜测,我将向您展示如何添加新语言。

添加新语言

NGramJ附带了几个语言配置文件,但您可能需要自己生成一个。维基百科是语言数据的重要来源。我写过从维基百科中提取纯文本之前在这里。今天,我需要为印尼语生成一个简介。第一步是创建原始语言配置文件。您可以使用cngram.jar文件执行此操作:

$java-jar cngram.jar-创建id_big id_corpus.txt创建了新的配置文件“idbig.ngp”。

这将创建一个id.ngp文件。我还注意到这个文件很大。与其他语言配置文件的30K相比,有数百KB。下一步是清理语言配置文件。为此,我创建了一个简短的睡眠脚本读取id.ngp文件,并剪切任何出现次数少于20K的3克和4克序列。我选择20K是因为它给我留下了一个大约30K的文件。如果数据较少,则需要向下调整此数字。其他语言配置文件使用1000作为分界点。这让我相信他们接受了6MB文本数据的训练,而我的印尼文本是114MB。

下面是脚本:

%克=ohash();setMissPolicy(%grams,{return@();});$句柄=openf(@ARGV[0]);$banner=readln($handle);readln($handle);#使用ngramcount值而$text(readln($handle)){($gram,$count)=分割('',$text);if(strlen($gram)<=2|$count>20000){推送(%grams[strlen($gram)],@($grams,$count));}}关闭($handle);子排序元组{返回$2[1]<=>$1[1];}println($banner);printAll(map({return join(“”,$1);},sort(&sortTuple,%grams[1]));printAll(map({return join(“”,$1);},sort(&sortTuple,%grams[2]));printAll(map({return join(“”,$1);},sort(&sortTuple,%grams[3]));printAll(map({return join(“”,$1);},sort(&sortTuple,%grams[4]));

要运行脚本,请执行以下操作:

$java-jar库/sleep.jar排序.sl id_big.ngp>id.ngp

最后一步是将id.ngp复制到src/de/spieleck/app/cngram/中,并编辑src/de/spieleck/app/cngram/profiles.lst以包含id资源。类型蚂蚁在NGramJ源代码的顶级目录中重建cngram.jar,然后准备测试:

$猫>c.txt维基百科上的数据来源于印度尼西亚,而非印尼$java-jar cngram.jar-lang2 c.txt速度:id:0.857 ru:0.000 pt:0.000。。de:0.000|0.0E0|0.0E0 dt=1872

正如您所见,NGramJ是一个易于使用的库。如果你需要做语言猜测,我建议你这样做。

我如何尝试提出拼写建议

发布于NLP研究2010年1月29日rsmudge

拼写检查是一个分三步进行的过程。检查字典中是否有单词,生成潜在的建议,然后对建议进行排序——希望在最前面有想要的单词。Peter Norvig博士写了一篇伟大的散文我建议你读一读。

了解了这三个步骤后,你能猜出其中最慢的部分是什么吗?这不是字典检查。这也不是建议的排序。产生潜在的建议是致命的。今天,我将讨论一种使用Tries加快此过程的聪明方法。

问题:我如何提出建议

AtD拼写校正器通过考虑拼写错误单词的两次编辑中的所有单词,生成潜在的建议。编辑是插入、删除或替换字母。转换两个字母也是一种编辑。从我自己的测试中,我发现96%的时候正确的单词是在两次编辑之内。所需单词在三次编辑内的时间为1.5%。除此之外,谁在乎?

为什么这个操作这么慢?天真的算法是对拼写错误的单词生成所有可能的编辑,以便在编辑距离为1的范围内进行每次编辑。对于一个单词的长度n个,我们有54个n个+25次编辑,假设a-z为小写字母。要获得编辑距离为2的所有单词,请对以前生成的编辑应用所有可能的编辑。这个数字很快就会变大,使用这个算法会忘记三次编辑。

三人行

A类尝试是一个树数据结构,用于存储与键关联的值。键的每个字符代表Trie的一个分支。检索值包括查找与键的第一个字符关联的分支,将其截断,并重复此过程,直到没有键为止。尝试很好,因为键的公共值是共享的,这样可以节省存储字典等内容的空间。

这是睡眠构建Trie的代码:

次级试验{本地(“$trie$word$x$root$letter”);$trie=%();每个$word($1){$root=$trie;for($x=0;$x<strlen($word)$x++){$letter=charAt($word,$x);if($letter!in$root){$root[$letter]=%();}$root=$root[$letter];}$root['__']=$word;}返回$trie;}

此函数创建一个表示为睡眠散列Trie中的每个分支都有指向其他Trie分支的字母。表示单词的分支将具有带有关联单词的__键。

通过查找词根分支中单词的第一个字母,将单词添加到Trie中。如果信不在那里,就会建立一个新的分支。然后从单词中删除第一个字母,与该字母关联的分支成为根分支。重复此过程,直到单词中没有字母。此时,__键被设置为标记此分支代表一个完整的单词。

$java-jar库/sleep.jar>>欢迎使用睡眠脚本语言>>相互作用>>欢迎使用交互式模式。键入代码,然后键入“.”在一行上单独执行代码。在一行中单独键入Ctrl+D或“done”以退出交互模式。include(“trie.sl”);$trie=trie(@(“苹果”,“蝙蝠”,“巴特”,”battle“,”cat“);println($trie);.%(b=>%(a=>%(t=>%(t=>%(l=>%(e=>%(__=>“战斗”))),__=>“bat”),r=>%(t=>%(__=>“巴特”)))),c=>%(a=>%),a=>%(p=>%))

如果你以前接触过Tries,你可能见过他们用来检查字典中是否有单词。以下是测试单词的睡眠代码:

sub英寸Trie{本地(“$x$word$trie$letter”);($word,$trie)=@_;for($x=0;$x<strlen($word)$x++){$letter=charAt($word,$x);if($trie中的$letter!){回报;}$trie=$trie[$letter];}返回iff($trie['__']eq$1);}

此函数使用类似于添加单词的过程来遍历Trie。如果当前字母没有分支,则测试失败。如果我们浏览了所有的字母,就会检查__键,看看是否确实有单词匹配。

通常__不包含单词。它通常是一个布尔标志。不过我很懒,把这个词放在这个槽中是为了让调试Trie代码更容易,并让我在测试Trie中是否有单词时更容易。

生成建议

AtD使用此Trie结构为拼写错误的单词生成所有编辑。Trie很好,因为我只需要遍历可能产生单词的路径,而且不需要在内存中保留大量遍历信息。代码如下:

子编辑{本地(“$trie$word$results$depth$root$branch$letter”);($trie,$word,$results,$depth)=@_;if(strlen($word)==0&&$depth>=0&$trie['__']ne''){$results[$trie['__']]=1;}如果($depth>=1){#删除。[删除当前字母,然后在当前分支上尝试它--看看会发生什么]if(strlen($word)>1){编辑($trie、substr($word,1)、$results、$depth-1);}其他{编辑($trie,“”,$results,$depth-1);}foreach$letter=>$branch($trie){if($字母eq'__'){continue;}#插入。[将当前单词(无更改)传递给每个分支进行处理]编辑($branch、$word、$results、$depth-1);#替代。[将当前单词无首字母传递给每个分支进行处理]if(strlen($word)>1){编辑($branch、substr($word,1)、$results、$depth-1);}其他{编辑($branch,“”,$results,$depth-1);}}#换位。[互换第一个和第二个字母]if(strlen($word)>2){编辑($trie,charAt($word,1)。charAt($word,0)。substr($word,2),$results,$depth-1);}else if(strlen($word)==2){编辑($trie,charAt($word,1)。charAt($word,0),$results,$depth-1);}}#继续读下一封信。(未进行编辑)if(strlen($word)>=1&&charAt($word,0)in$trie){$letter=charAt($2,0);如果(strlen($word)>1){编辑($trie[$letter],substr($word,1),$results,$depth);}else if(strlen($word)==1){编辑($trie[$letter],“”,$results,$depth);}}#结果存储在散列中以防止重复单词返回键($results);}

此函数考虑四种编辑类型:删除、插入、替换和换位。此函数返回指定单词N次编辑中的单词列表。它通过考虑单词的第一个字母、单词的其余部分以及Trie的当前分支来实现这一点。

它通过将此函数应用于当前Trie分支和单词的其余部分来处理删除。通过这种方式,可以找到删除此信件可能产生的所有编辑。

每次调用编辑时,该函数都会从最大深度计数器中减去1。当最大深度值为零时,不允许对Trie进行更多的遍历。此计数器确保只生成所需编辑次数内的单词。

Insertion遍历所有子分支(表示每个可能的下一个字母),并将编辑函数应用于以当前作为参数的那些分支。通过这种方式,每个分支都被视为单词中当前字母之前的可能插入。

替换遍历每个子分支,并将编辑函数应用于这些分支,将单词的其余部分作为参数。

转置交换当前单词的第一个和第二个字母,并使用当前分支对此新词应用编辑功能。

当使用单词的空字符串调用Trie分支时,映射到单词的Trie分支将添加到建议池中,并且深度计数器大于零(这意味着我们在允许的编辑次数范围内)。

完成这些步骤后,算法将查找单词中下一个字母的Trie分支,并使用该分支作为Trie和单词的其余部分调用编辑。深度计数器没有更改,因为没有进行任何编辑,这只是将算法推进到下一个字母。

这是一份打印出来的编辑应用于“成功”,使用的是1939年韦伯斯特词典公共领域的Trie。

$java-jar库/sleep.jar>>欢迎使用睡眠脚本语言>相互作用>>欢迎使用交互式模式。键入您的代码,然后键入“。”在一行上单独执行代码。在一行中单独键入Ctrl+D或“done”以退出交互模式。include(“trie.sl”);$dictionary=readAll(openf(“/usr/share/dict/words”);println(大小($dictionary));.98569$trie=trie($dictionary);printAll(编辑($trie,“成功”,%(),2));.最可靠的没有阳光酱汁烂透了酱汁的过量的凹陷强调卢斯的西塞斯接近胁迫碟子公爵夫人超级猜测起诉人吸盘成功起诉

我发现这种方法比天真的编辑生成算法更快。让我知道它是如何为你工作的。

此代码来自LGPL许可下提供的截止日期后软件服务。您可以在以下位置找到系统其余部分的代码:http://open.afterthedeadline.com

关于一个小型上下文拼写检查器的思考

发布于NLP研究rsmudge于2009年12月9日

拼写检查员的口碑不好,因为他们给出的建议很差,没有捕捉到真正的单词错误,并且通常有过期的字典。在最后期限之后,我在这三个问题上取得了进展。通过像AtD的上下文拼写检查器那样查看上下文,可以解决建议不足的问题。AtD再次使用上下文帮助检测真实单词错误。它不是完美无缺的,但也不坏。AtD还通过查询多个数据源(如维基百科)来查找缺失的单词,在词典方面取得了进展。

问题陈述

尽管如此,上下文拼写检查并不常见。我相信这是因为上下文拼写检查需要一个语言模型。语言模型跟踪大型文本中两个单词的每个序列。拼写检查器可以根据这些数据计算P(currentWord | previousWord)P(currentWord | nextWord)。对于客户端应用程序,此信息相当于大量内存或磁盘空间。

是否可以在较小的软件包中提供上下文拼写检查器的优点?

为什么有人要这样做?如果能做到这一点,那么就有可能将小型上下文拼写检查器嵌入到Firefox、OpenOffice等程序中。键入时进行拼写检查很容易,而且响应迅速,因为客户端可以下载库并执行客户端的所有操作。

建议的解决方案

我相信可以降低语言模型的准确性,而不会大大影响其优点。上下文在拼写检查时起着重要作用(因为它是额外的信息),但我认为“这个单词在这个上下文中出现的次数比另一个多很多”这一想法就足以帮助拼写检查。通常拼写检查器会在3-6个单词之间做出选择。

存储低保真度语言模型信息的一种方法是将每个单词与一些bloom过滤器相关联。每个bloom过滤器将代表一个概率带。例如,一个单词可以有三个与之关联的bloom过滤器,以跟踪前25%、中50%和后25%中出现的单词。这意味着拼写检查器的数据大小为N*|字典|但这比语言模型趋向于|词典|^2.

A类布卢姆过滤器是用于跟踪某个对象是否属于某个集合的数据结构。它们很小,取舍是它们可能会给出假阳性,但不会给出假阴性。它也很容易计算假阳性率在给定预期集合项目数、bloom过滤器大小和使用的哈希函数数的bloom过滤器中。为了优化空间,可以根据语言模型确定每个波段和单词的bloom过滤器的大小。

如果这项技术适用于拼写,它是否也适用于误用单词检测?想象一下,使用bloom过滤器跟踪每个潜在误用单词的三角图(三个单词的序列)。

在进一步研究之后,看起来其他人已经解决了使用bloom过滤器来表示语言模型这使得这种方法现在更加有趣。

关闭注释关于一个小型上下文拼写检查器的思考

从维基百科生成纯文本语料库

发布于多语言AtD,NLP研究rsmudge于2009年12月4日

AtD*以数据为基础,维基百科是各种数据的最佳去处之一。这篇文章描述了如何从完整的维基百科转储中生成纯文本语料库。此过程是对从维基百科中提取文本通过埃文·琼斯.

Evan的帖子展示了如何从英文维基百科中提取顶级文章并制作纯文本文件。在这里,我将展示如何通过两个有用的约束从维基百科转储中提取所有文章。每一步都应该:

  • 在我到领取社会保险金的年龄之前完成
  • 容忍错误并在没有我干预的情况下完成

今天,我们将学习法语维基百科。我正在研究多语言的AtD,法语似乎是一门有趣的语言。我们的系统人员,斯特凡会说法语。这是一个很好的理由。

步骤1:下载维基百科提取器工具包

Evan提供了一组从维基百科提取明文的代码。为了实现上述两个目标,我做了一些修改*。所以你想做的第一件事是下载此工具包并将其提取到某个位置:

wget公司http://www.polishmywriting.com/download/wikipedia2text_rsm_mods.tgztar zxvf维基百科2text_rsm_mods.tgz光盘wikipedia2text

(*请参阅CHANGES文件以了解所做的修改)

步骤2:下载并提取维基百科数据转储

你可以从http://download.wikimedia.org/。任何语言的存档都是*pages-articles.xml.bz2。以下是我所做的:

wget公司http://download.wikimedia.org/frwiki/20091129/frwwiki-20091129-pages-articles.xl.bz2下载bunzip2 frwiki-20091129-pages-articles.xml.bz2

步骤3:从维基百科数据中提取文章数据

现在您有了一个包含所有维基百科文章的大XML文件。祝贺 你。下一步是提取文章并剥离所有其他内容。

为输出创建一个目录,并对运行xmldump2files.py。您在上一步中获得的XML文件:

mkdir输出./xmldump2files.py frwiki-20091129-pages-articles.xml输出

根据硬件的不同,此步骤需要几个小时。

步骤4:将文章Wiki标记解析为XML

下一步是获取提取的文章,并将Wikimedia标记解析为XML格式,以便稍后从中恢复纯文本。有一个shell脚本可以为out目录中的所有文件生成XML文件。如果你有一台多核机器,我不建议运行它。我更喜欢为每个核心使用shell脚本,在文件集的一部分执行Wikimedia to XML命令(也称穷人的并发编程)。

要生成这些shell脚本,请执行以下操作:

查找-键入f|grep'\.txt$'>fr.files

将此fr.文件拆分为多个.sh文件。

java-jar sleep.jar到8.sl fr.files

您可能会发现创建launch.sh文件来启动into8.sl创建的shell脚本很有帮助。

cat>启动.sh./files0.sh文件&./文件1.sh&./files2.sh文件&..../files15.sh文件&^D类

接下来,启动这些shell脚本。

./启动.sh

不幸的是,这段旅程充满了危险。这些脚本对每个文件运行的命令有以下注释:将wiki格式的Wikipedia文章转换为XML格式。有时它可能会分段或进入“无限”循环。这句话是真的。PHP进程将冻结或崩溃。我第一次经历这个过程时,我必须手动监视顶部并消除错误的进程。这使得该过程花费的时间超过了应有的时间,而且非常耗时。为了有所帮助,我编写了一个脚本,可以终止任何运行超过两分钟的php进程。要启动它:

java-jar sleep.jar watchthem.sl

只要让这个程序运行,它就会完成它的工作。根据您的硬件,预计此步骤需要12个或更多小时。

第5步:从文章中提取纯文本

接下来,我们要从XML文件中提取文章明文。为此,请执行以下操作:

./wikiextract.py out法语_plaintext.txt

此命令将创建一个名为french_plaintext.txt的文件,其中包含法语维基百科的整个纯文本内容。根据您的硬件,此命令可能需要几个小时。

第6步(可选):将纯文本拆分为多个文件以便于处理

如果您计划在AtD中使用此数据,您可能希望将其拆分为多个文件,以便AtD可以对其进行分段解析。我包含了一个脚本来执行此操作:

mkdir语料库java-jar sleep.jar makecorpus.sl法语plaintext.txt语料库

就这样。你现在有一个从维基百科中提取的语言语料库。

从错误中学习-一些想法

发布于NLP研究由rsmudge于2009年11月23日

我经常被问到,AtD使用得越多,它是否变得越聪明。答案是还没有。为了激发想象力,并对即将发生的事情给出一个想法,这篇文章提出了一些关于AtD如何在你使用它的时候学习更多的想法。

我可以立即获得两个来源:你发送的文本和你忽略的短语。

从提交的文本中学习

您发送的文本是AtD从正在检查的确切写作类型中学习的机会。该过程将包括保存通过某些正确性过滤器的部分提交文档,并检索这些文档以供以后在AtD语言模型中使用。

提交的文档可以直接添加到AtD训练语料库中,这将对几乎所有功能产生积极影响。AtD使用来自训练数据的统计信息来查找最佳拼写建议,检测误用的单词,并查找风格和语法规则的例外。

更多的数据可以让我创建一个拼写检查字典,减少拼写错误或无关的单词。一个更大的训练语料库意味着更多的单词可以用来派生拼写检查器词典。AtD的拼写检查要求一个单词在被包括在拼写检查字典中之前被看到一定次数。有了足够的自动获取的数据,AtD可以找到最高阈值,从而生成约12万个单词的字典。

从被忽视的短语中学习

单击“始终忽略”时,此首选项将保存到数据库中。我可以为WordPress.com用户和经历了一次看看我能学到什么。

此信息可用于查找要添加到AtD中的新单词。任何被多人忽略的单词都可能是AtD字典中缺少的正确拼写。我可以设置一个阈值,即一个单词在添加到AtD单词列表之前必须忽略多少次。这是一个很难解决的问题,因为我不希望经常被忽视的错误,比如“很多”会进入到AtD字典中,所以有必要对此进行一些保护。

标记为忽略的误用单词表示有机会将数据收集工作重点放在该单词上。这很难,但我可以查询类似以下的服务沃德尼克以获得该单词的更多上下文,并将额外的上下文添加到AtD语料库中。如果一个单词超过了被很多人忽略的门槛,那么考虑自动将其从误用单词列表中删除可能也是一个好主意。统计检测方法对某些单词不起作用。

瞄准更高

这些想法代表了让AtD在您使用服务时学习的一些低效成果。让我们想象一下,我可以让AtD跟踪任何行为及其周围的上下文。当你接受建议时,有很好的学习机会,如果上下文与你接受或忽略建议有关,那么被误用的单词功能有更多的改进机会。

这些是我的想法,你的是什么?