一个StringToken Parser,它提供Google搜索样式“你的意思是:”建议

时间:2008-09-25 20:19:43

标签: language-agnostic parsing nlp

寻求方法:

在字符串中取空格分隔的标记;返回建议的Word


即:
Google搜索可以使用“fonetic wrd nterpreterr”
它显示在结果页面的顶部“你的意思是:语音词解释器”

首选任何C *语言或Java的解决方案。


是否有现有的Open Libraries执行此类功能?

或者有没有办法利用Google API来请求建议的字词?

8 个答案:

答案 0 :(得分:11)

在他的文章How to Write a Spelling Corrector中,Peter Norvig讨论了如何实施类似Google的拼写检查程序。本文包含Python中的20行实现,以及C,C ++,C#和Java中几个重新实现的链接。这是一段摘录:

  

一个完整的细节   工业强度法术纠正器   像谷歌一样会更加混乱   比启发,但我想   在飞机上飞回家,不到   一页代码,我可以写一个玩具   达到80或者达到80的拼写校正器   处理速度为90%时的准确度为90%   每秒至少10个字。

使用Norvig的代码和this text作为训练集,我得到以下结果:

>>> import spellch
>>> [spellch.correct(w) for w in 'fonetic wrd nterpreterr'.split()]
['phonetic', 'word', 'interpreters']

答案 1 :(得分:2)

您可以在此处使用雅虎网络服务: http://developer.yahoo.com/search/web/V1/spellingSuggestion.html

然而,它只是一个Web服务...(即没有其他语言的API等..)但它输出JSON或XML,所以...很容易适应任何语言......

答案 2 :(得分:2)

您还可以使用Google API进行拼写检查。有一个ASP实现here(我不赞成这个。)

答案 3 :(得分:2)

首先关闭:

使用您选择的一个。我怀疑它运行查询对一个单词限制正好为1的拼写检查引擎,如果整个查询有效则不执行任何操作,否则它会用该单词的最佳匹配替换每个单词。换句话说,以下算法(空返回字符串表示查询没有问题):

startup()
{
   set the spelling engines word suggestion limit to 1
}

option 1()
{
   int currentPosition = engine.NextWord(start the search at word 0, querystring);

   if(currentPosition == -1)
      return empty string; // Query is a-ok.

   while(currentPosition != -1)
   {
       queryString = engine.ReplaceWord(engine.CurrentWord, queryString, the suggestion with index 0);
       currentPosition = engine.NextWord(currentPosition, querystring);
   }

   return queryString;
}

答案 4 :(得分:2)

由于还没有人提及它,我还会再提一个短语来搜索:“编辑距离”(例如,link text)。 这可以用来找到最接近的匹配,假设它是字母转换,丢失或添加的拼写错误。

但通常这也与某种相关性信息相结合;或者通过简单的流行度(假设最常用的足够接近的匹配很可能是正确的词),或者通过上下文可能性(在前面的正确单词之后,或者在之前的单词之前)。这进入了信息检索;一种开始的方式是查看二元组和三元组(一起看的单词序列)。谷歌拥有非常广泛的免费数据集。

对于简单的初始解决方案,尽管与Levenshtein基于匹配器的词典结合使用的效果非常好。

答案 5 :(得分:2)

你可以插上Lucene,它有一个实现Levenshtein距离法的字典设施。

这是Wiki的一个例子,其中2是距离。

String[] l=spellChecker.suggestSimilar("sevanty", 2);
//l[0] = "seventy"

答案 6 :(得分:1)

如果您将字典存储为trie,则可以通过相当简单的方式查找最佳匹配条目,其中可以插入,删除或替换字符。

void match(trie t, char* w, string s, int budget){
  if (budget < 0) return;
  if (*w=='\0') print s;
  foreach (char c, subtrie t1 in t){
    /* try matching or replacing c */
    match(t1, w+1, s+c, (*w==c ? budget : budget-1));
    /* try deleting c */
    match(t1, w, s, budget-1);
  }
  /* try inserting *w */
  match(t, w+1, s + *w, budget-1);
}

这个想法是,首先你用预算为零调用它,看看它是否打印出来。然后尝试1的预算,依此类推,直到它打印出一些匹配。预算越大,所需的时间越长。您可能只希望达到2的预算。

补充:扩展它以处理公共前缀和后缀并不太难。例如,英语前缀如“un”,“anti”和“dis”可以在字典中,然后可以链接回字典的顶部。对于像“ism”,“s”和“ed”这样的后缀,可以有一个单独的trie只包含后缀,大多数单词都可以链接到后缀trie。然后它可以处理像“antinationalizationalization”这样的奇怪词汇。

答案 7 :(得分:1)