如何正确地用“a”和“an”为单词添加前缀?

时间:2009-08-17 14:34:06

标签: c# nlp linguistics

我有一个.NET应用程序,给定一个名词,我希望它能正确地用“a”或“an”作为前缀。我该怎么做?

在您认为答案是简单地检查第一个字母是否为元音之前,请考虑以下短语:

  • 一个诚实的错误
  • 二手车

25 个答案:

答案 0 :(得分:132)

  1. 下载维基百科
  2. 解压缩并编写一个快速过滤程序,只扫描文章文本(下载通常采用XML格式,同时也包含非文章元数据)。
  3. 查找a(n)....的所有实例,并对下一个单词及其所有前缀进行索引(您可以使用简单的后缀)。这应该区分大小写,你需要一个最大字长--15个字母?
  4. (可选)丢弃所有出现少于5次的前缀或“a”与“an”达到少于2/3多数(或其他一些阈值 - 此处调整)的前缀。最好保留空前缀以避免角落情况。
  5. 您可以通过丢弃其父级共享相同“a”或“an”注释的所有前缀来优化前缀数据库。
  6. 在确定是否使用“A”或“AN”时,找到最长的匹配前缀,并按其引导。如果你没有在步骤4中丢弃空前缀,那么总是是匹配的前缀(即空前缀),否则你可能需要一个完全不匹配的字符串的特殊情况(这样的输入应该非常罕见)。
  7. 你可能不会比这更好 - 它肯定会胜过大多数基于规则的系统。

    修改:我implemented this in JS/C#。您可以try it in your browser,或下载它使用的小型,可重复使用的JavaScript实现。 .NET实现是包AvsAn on nuget。实现是微不足道的,因此如果需要,应该很容易移植到任何其他语言。

    事实证明“规则”比我想象的要复杂得多:

    • 意料之外的结果,但 a 一致投票
    • 诚实的决定,但 a 金银花灌木
    • 符号: 0800号,或 ∞的牛至。
    • 首字母缩略词:它是 a NASA科学家,但 NSA分析师; a 菲亚特汽车,但 FAA政策。

    ......这只是强调基于规则的系统构建起来会很棘手!

答案 1 :(得分:15)

您需要使用例外列表。我不认为所有的例外都有明确的定义,因为它有时取决于说出这个词的人的口音。

一种愚蠢的方式是向谷歌询问两种可能性(使用其中一种搜索API)并使用最受欢迎的:

或者:

因此,“欧洲”和“诚实”是正确的版本。

答案 2 :(得分:14)

如果您能找到单词拼写的单词拼写来源,例如:

"honest":"on-ist"
"horrible":"hawr-uh-buhl, hor-"

您可以根据拼写发音字符串的第一个字符做出决定。 为了提高性能,也许您可​​以使用这样的查找来预先生成异常集,并在执行期间使用那些较小的查找集。

编辑添加:

!!! - 我认为您可以使用它来生成例外: http://www.speech.cs.cmu.edu/cgi-bin/cmudict

当然,并非所有内容都会出现在字典中 - 这意味着并非每个可能的异常都会出现在您的异常集中 - 但在这种情况下,您可以默认为元音/ a用于辅音或使用其他启发式方法更好的赔率。

(通过CMU词典,我很高兴看到它包括适用于国家和其他地方的专有名词 - 所以它将会有像“乌克兰人”,“今日美国报”,“乌拉尔风格画”这样的例子。 ”。)

再次编辑添加:CMU字典不包含常见的首字母缩略词,您必须担心以s,f,l,m,n,u和x开头的字典。但是有许多首字母缩略词列表,比如维基百科,你可以用来添加例外。

答案 3 :(得分:9)

你必须手动实现并添加你想要的例外,例如,如果第一个字母是'H',然后是'O',如诚实,小时......还有相反的,如欧洲,大学,使用过...

答案 4 :(得分:8)

由于“a”和“an”是由语音规则而不是拼写惯例决定的,我可能会这样做:

  1. 如果该单词的第一个字母是辅音 - > 'A'
  2. 如果单词的第一个字母是元音 - > '一个'
  3. 将例外情况(心脏,X光,房屋)列为rjumnro says

答案 5 :(得分:4)

你需要查看不定文章的语法规则(英语语法中只有两篇不定的文章 - “a”和“an”。你可能不同意这些听起来正确,但是English grammar are very clear的规则:

  

“单词a和an是无限期的   文章。我们使用无限期   文章a开头的话   用元音(a,e,i,o,u)和   不言而喻的文章a之前的文字   以辅音开始(全部   其他字母)。“

注意这意味着元音声音,而不是元音字母。例如,以“h”开头的单词,例如“honor”或“heir”被视为元音,因此以“an”开头 - 例如,“很荣幸见到你”。以辅音开头的单词以前缀为前缀 - 这就是为什么你说“二手车”而不是“二手车” - 因为“used”有一个“yoose”声而不是“呃”声。

因此,作为程序员,这些是遵循的规则。你只需要找出一种方法来确定一个单词的开头是什么,而不是用什么字母。我见过这样的例子,例如Jaimie Sirovich的this one in PHP

function aOrAn($next_word) 
{ 
    $_an = array('hour', 'honest', 'heir', 'heirloom'); 
    $_a = array('use', 'useless', 'user'); 
    $_vowels = array('a','e','i','o','u'); 

    $_endings = array('ly', 'ness', 'less', 'lessly', 'ing', 'ally', 'ially'); 
    $_endings_regex = implode('|', $_endings); 

    $tmp = preg_match('#(.*?)(-| |$)#', $next_word, $captures); 
    $the_word = trim($captures[1]); 
    //$the_word = Format::trimString(Utils::pregGet('#(.*?)(-| |$)#', $next_word, 1)); 

    $_an_regex = implode('|', $_an); 
    if (preg_match("#($_an_regex)($_endings_regex)#i", $the_word)) { 
        return 'an'; 
    } 

    $_a_regex = implode('|', $_a); 
    if (preg_match("#($_a_regex)($_endings_regex)#i", $the_word)) { 
        return 'a'; 
    } 

    if (in_array(strtolower($the_word{0}), $_vowels)) { 
        return 'an';     
    } 

    return 'a'; 
}

最简单的方法是创建规则,然后创建一个例外列表并使用它。我不认为会有那么多。

答案 6 :(得分:3)

男人,我意识到这可能是一个固定的论点,但我认为它可以比使用维基百科的特殊语法规则更容易解决,这些规则最多可以得出白话语法。

似乎最好的解决方案是使用或触发基于音素的后续单词匹配,某些音素始终与“an”相关联,其余属于“a”。

卡内基梅隆大学有一个很棒的在线工具可以进行这类检查 - http://www.speech.cs.cmu.edu/cgi-bin/cmudict - 以及125k字的匹配39个音素。插入一个单词提供整个音素集,其中只有第一个是重要的。

如果单词未出现在词典中,例如“NSA”并且全部大写,那么系统可以假设该单词是首字母缩略词并使用第一个字母来确定基于相同原稿使用哪个不定冠词规则集。

答案 7 :(得分:3)

@Nathan Long: 下载维基百科实际上并不是一个坏主意。不需要所有图像,视频和其他媒体。

我在php和javascript(!)中编写了一个(糟糕的)程序来阅读整个瑞典维基百科(或者至少所有可以从数据中获取的关于数学的文章,这是我的蜘蛛的开始。)

我收集了数据库中的所有单词和内部链接,并且还跟踪每个单词的频率。我现在将其用作各种任务的单词数据库: *查找可以从给定字母集(包括通配符)创建的所有单词 *为瑞典语创建了一个简单的语法文件(不在数据库中的所有单词都被认为是不正确的。)

哦,下载整个wiki花了大约一个星期的时间,使用我的笔记本电脑大部分时间运行,使用10Mbit连接。

当你在这里时,记录所有与英语不一致的事件,看看是否有一些是错误的。去修复它们并回馈社区。

答案 8 :(得分:2)

看看Perl的Lingua::EN::Inflect。请参阅源代码中的sub _indef_article

答案 9 :(得分:2)

我从Python(最初来自CPAN包Lingua-EN-Inflect)移植了一个函数,该函数正确地确定了C#中的元音,并将其作为问题Programmatically determine whether to describe an object with a or an?的答案发布。您可以看到代码段here

答案 10 :(得分:2)

请注意,美国和英国方言之间存在差异,正如语法女郎在她的第A Versus An集中指出的那样。

  

一个复杂因素是英语和美国英语中的单词发音不同。例如,某种植物的词在美式英语中是“erb”,在英式英语中是“herb”。在极少数情况下,这是一个问题,请使用您所在国家或大多数读者所期望的表格。

答案 11 :(得分:1)

你能得到一个英文字典,用于存储用常规字母表写的字,以及International Phoenetic Alphabet吗?

然后使用phoenetics找出单词的开始声音,从而“a”或“an”是否合适?

不确定这是否比统计维基百科方法更容易(或同样有趣)。

答案 12 :(得分:0)

选择a或a取决于单词的发音方式。通过查看单词,您不一定能说出正确的发音,例如一个术语或缩写等。 其中一种方法是使用支持音素的字典,并使用与该字相关的音素信息来确定是否应该使用“a”或“an”。

答案 13 :(得分:0)

我无法确定它是否有适当的信息来区分“a”和“an”,但普林斯顿的WordNet数据库恰好存在于类似的任务目的,所以我认为它是可能是数据在那里。它有成千上万的单词和成千上万的关系(IIRC;我找不到网站上的当前统计数据)。看看吧。它可以免费下载。

答案 14 :(得分:0)

如何?怎么样?获取附有文章的名词。以特定形式提出要求。

在文章中询问名词。许多MUD代码库将项目存储为包含以下内容的信息:

  • 一个或多个关键字
  • 简短表格
  • 长篇

关键字表格可能是“短剑生锈”。简短形式将是“一把剑”。长形将是“生锈的短剑”。

您是在撰写“一对一”的Web服务吗?退后一步,看看你是否可以进一步向上游攻击这个漏洞。你可以建造一座大坝,但除非你阻止它流动,它最终会溢出。

确定这是多么重要,正如其他人所建议的那样,选择“快速而粗糙”,或“昂贵但坚固”。

答案 15 :(得分:0)

检查单词是以元音还是指针开头。 “u”通常是辅音和元音(“yu”),因此属于辅音组。

字母“h”代表法语中的gottal stop(辅音)和英语中使用的法语单词。你可以列出那些(事实上,包括“荣誉”,“荣誉”和“小时”可能就足够了)并将它们视为从元音开始(因为英语不能识别声门停止)。

还将“欧盟”视为辅音等。

这并不太难。

答案 16 :(得分:0)

规则很简单。如果下一个单词以元音开头,则使用'an',如果它以辅音开头,则使用'a'。困难的是我们学校的元音和辅音分类不起作用。 '荣誉'中的'h'是一个元音,但'医院'中的'h'是一个辅音。

更糟糕的是,某些像“诚实”这样的词语从元音或辅音开始,取决于谁在说它们。更糟糕的是,对于某些发言者来说,有些词会根据周围的词语而改变。

问题仅限于您想要花费多少时间和精力。您可以在几分钟内使用'aeiou'作为元音写一些东西,或者您可以花几个月时间对目标受众进行语言分析。在他们之间有大量的启发式,这对于一些发言者是正确的而对其他人来说是错误的 - 但是因为不同的发言者对同一个词有不同的决定,所以无论你怎么做都不可能一直都是正确的。它

答案 17 :(得分:0)

我不认为你可以只填写一些锅炉板的东西,如'a / an'作为一步到位的全部。否则你最终将会出现假设错误,例如所有单词都带有'h'继续'o'得'a'而不是'a'就像'home' - (一个家?)。基本上,你最终会包含英语语言的逻辑,或偶尔会发现一些让你看起来很愚蠢的罕见案例。

答案 18 :(得分:0)

我只是看起来像一套启发式。它需要更复杂一点并回答一些我从来没有得到过好答案的事情,例如你如何处理缩写(“RPM”或“RPM”?我一直认为后者更有意义)。< / p>

对语言库进行了快速搜索,讨论了如何处理英语单数前缀,但如果你挖得足够多,你可能会找到一些东西。如果没有 - 您可以随时编写自己的变形库并获得世界声誉:-)。

答案 19 :(得分:0)

理想的方法是在线找到可以给你答案的地方,动态查询并缓存答案。你可以用几百个单词为系统启动系统。

(我不知道这样的在线资源,但如果有的话,我不会感到惊讶。)

答案 20 :(得分:0)

我会使用基于规则的算法尽可能多地覆盖,然后使用例外列表。如果你想获得幻想,你可以尝试从你的例外列表中确定一些新的“规则”。

答案 21 :(得分:0)

因此,无需下载所有互联网即可实现合理的解决方案。这就是我的所作所为:

我记得Google发布了Google图书N-Gram频率here的原始数据。所以我下载了2-gram文件&#34; a _&#34;和&#34;一个&#34;。如果我没记错的话,大概有26场演出。从那时起,我制作了一个字符串列表,其中绝大多数情况下都是您期望的相反文章(如果我们期望元音采用&#34;&#34;)。最终的单词列表,我能够存储在7千字节以下。

答案 22 :(得分:0)

我倾向于重新编写包含不定冠词的语句,而不是编写可能依赖于文化并且有许多例外的代码。例如,与其说“该客户想要住在单户住宅中。”,不如说“该客户想要‘单户住宅’的住房类型”。这样,不定冠词不依赖于变量 - 例如,“该客户想要‘公寓’的住房类型。”

答案 23 :(得分:0)

我想综合一些给出的答案,并贡献我自己的解决方案。

让我们从一些基本的启发式开始:

  1. 从单词的第一个字母开始。

    • 如果它以“a”、“i”或“o”开头,则使用“an”。据我所知,这些字母总是以真正的元音开头。
    • 如果它以“b”、“c”、“d”、“g”、“k”、“p”、“q”、“t”、“v”、“w”或“ z",那么它肯定是辅音,并且发音像辅音。
    • 如果它以“f”、“l”、“m”、“n”、“r”、“s”或“x”开头,可以用元音发音,但仅如果是首字母缩略词。否则,它肯定会发音为辅音。
    • 如果它以“u”开头,或者以“h”、“j”或“y”开头,那么它就属于极端情况。
  2. 确定该词是否为首字母缩略词。

  • 如果单词是首字母缩写词,则假定它包含多个连续的大写字母,或包含句点。这可以通过一个简单的正则表达式(例如 [A-Z][A-Z]+)解决。
    • 如果该词是首字母缩略词,则在转到第 3 步之前先将其转换为更“类似单词”的形式(即,并非全部大写,不包含句点)。如果它不是首字母缩略词,请参阅回到步骤 1 中的信息。
  1. 使用字典!
    • 如果单词在 this dictionary 中,并且以“a”、“e”、“i”、“o”或“u”开头,则它以元音开头。否则,它是一个辅音。
    • 维基词典和维基百科使用 IPA 来表示单词的发音。如果单词以 one of these letters, 开头,则它以元音开头。

希望这会有所帮助。我怀疑它比任何单个选项占用的资源更少,因为其中大部分都可以通过简单的“等于”语句(例如 word[0] == 'a')或正则表达式(例如 {{1} }),以及一些简单的语言学知识和pronunciations of the English letter names。如果这个词不属于一个简单的案例,那么使用其他回答者提供的更复杂的解决方案之一。

答案 24 :(得分:-2)

每当下一个单词不是元音时,你会使用“a”吗?只要有元音,你就用“an”吗?

话虽如此,你不能只做一个正常的表达,比如“a \ s [a,e,i,o,u]。*”吗?然后用“an?”替换它。