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

rye*_*guy 91 c# nlp linguistics

我有一个.NET应用程序,给定一个名词,我希望它正确地用"a"或"an"作为该单词的前缀.我该怎么办?

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

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

Eam*_*nne 135

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

你可能不会比这更好 - 它肯定会击败大多数基于规则的系统.

编辑:在JS/C#中实现了这个.您可以在浏览器中尝试它,或下载它使用的小型,可重用的JavaScript实现..NET实现是AvsAnnuget上的包.实现是微不足道的,因此如果需要,应该很容易移植到任何其他语言.

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

  • 这是一个意想不到的结果,但这一致的投票
  • 这是一个诚实的决定,但一个金银花灌木
  • 符号:它是一个 0800数字,或者是一个 ∞的牛至.
  • 缩略语:这是一个美国航空航天局的科学家,而是一个国家安全局分析师; 一个 FIAT车,但一个美国联邦航空局的政策.

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

  • 鉴于维基百科下载解压缩到(当前)2.8太字节,如果使用此方法的任何人公开发布结果数据将是很好的,因此该过程不必重复太多. (26认同)
  • 这个答案并不完全严重,但是我做了类似的事情,维基百科的.xml文件与原始wikimarkup只是大约40GB(最新的一个总是有点大),而不是2.8TB - 所有在一个文件中 - 不要下载扩展的.html版本或任何图像,也许这是2.8TB的版本?在任何情况下,只要你不挑剔标记,解析它实际上是非常可行的. (9认同)

rjm*_*nro 15

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

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

要么:

因此,"欧洲"和"诚实"是正确的版本.

  • 这实际上是允许使用还是要求被禁止?对IIRC来说,经常这样的使用肯定是不受欢迎的. (6认同)
  • 最糟糕的?有一个非常强烈的论据,即复制"常见误用"正是自然语言系统应该努力的结果.在_Consider the Lobster_中,参见David Foster Wallace的论文"权威与美国用法".有比谷歌更好的语料库,但这是一个不同的问题. (6认同)
  • 除了显而易见的技术困难(以这种方式自动使用搜索引擎输出是不允许的并且会被快速阻止),这并没有以正确的方式解决问题 - 最坏的情况是它会复制常见的误用句法. (2认同)
  • "酒店"和"女主角"对我来说都是正确的.我猜你是从一个略带cockney口音的角度出发的.不同的口音意味着对这些词中的某些词没有正确的答案. (2认同)

Ano*_*non 14

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

"honest":"on-ist"
"horrible":"hawr-uh-buhl, hor-"
Run Code Online (Sandbox Code Playgroud)

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

编辑添加:

!- 我想你可以用它来产生例外:http: //www.speech.cs.cmu.edu/cgi-bin/cmudict

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

(通过CMU词典,我很高兴地看到它包括适用于国家和其他地方的专有名词 - 所以它将会出现像"乌克兰语","今日美国报","乌拉尔风格的绘画"等例子.)

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

  • 无法自拔,但`hawr-uh-buhl` 总是让我发笑。 (2认同)

Ahm*_*rid 9

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


Pat*_*son 8

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

  1. 如果单词的第一个字母是辅音 - >'a'
  2. 如果单词的第一个字母是元音 - >'an'
  3. 保留一份例外情况(心脏,X光,房子),如rjumnro所说.


Dan*_*plo 5

您需要查看不定冠词的语法规则(英语语法中只有两个不定冠词-“ a”和“ an”),您可能不同意这些听起来正确,但是英语语法的规则非常明确

“ a和an词是不定冠词。我们使用不定冠词a以元音开头(a,e,i,o,u)开头的不定冠词,而不定冠词a以辅音开头(所有其他字母)。”

注意,这意味着一个元音的声音,而不是一个元音字母。例如,以无声的“ h”开头的单词(例如“ honour”或“ heir”)被视为元音,因此以“ an”开头-例如,“见到您很荣幸”。以辅音开头的单词以-开头,这就是为什么您说“二手车”而不是“二手车”的原因-因为“二手车”的声音是“洋洋”而不是“呃”。

因此,作为程序员,这些是要遵循的规则。您只需要确定一种方法即可确定单词的发音,而不是字母。我已经看到了这样的示例,例如Jaimie Sirovich 在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'; 
}
Run Code Online (Sandbox Code Playgroud)

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


小智 5

伙计,我意识到这可能是一个已解决的争论,但我认为它比使用维基百科的临时语法规则更容易解决,维基百科最多只能导出白话语法。

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

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

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