我需要啥算法来找到 n-gram?

Posted

技术标签:

【中文标题】我需要啥算法来找到 n-gram?【英文标题】:What algorithm I need to find n-grams?我需要什么算法来找到 n-gram? 【发布时间】:2011-11-17 01:53:43 【问题描述】:

使用什么算法来查找 ngram?

假设我的输入数据是一个单词数组和我想找到的 ngram 的大小,我应该使用什么算法?

我要代码,优先使用 R。数据存储在数据库中,因此也可以是 plgpsql 函数。 Java 是一种我比较熟悉的语言,所以我可以将它“翻译”成另一种语言。

我并不懒惰,我只是要求代码,因为我不想重新发明***来尝试做一个已经完成的算法。

编辑:重要的是要知道每个 n-gram 出现了多少次。

编辑 2:有用于 N-GRAMS 的 R 包吗?

【问题讨论】:

有一个文本挖掘包(tm)和一个textcat包...library("sos"); findFn("n-gram") related/near-duplilcate question 看cran.r-project.org/web/packages/ngram/vignettes/ngram-guide.pdf 【参考方案1】:

如果要使用R 来识别ngram,可以使用tm 包和RWeka 包。它会告诉您 ngram 在您的文档中出现了多少次,如下所示:

  library("RWeka")
  library("tm")

  data("crude")

  BigramTokenizer <- function(x) NGramTokenizer(x, Weka_control(min = 2, max = 2))
  tdm <- TermDocumentMatrix(crude, control = list(tokenize = BigramTokenizer))

  inspect(tdm[340:345,1:10])

A term-document matrix (6 terms, 10 documents)

Non-/sparse entries: 4/56
Sparsity           : 93%
Maximal term length: 13 
Weighting          : term frequency (tf)

               Docs
Terms           127 144 191 194 211 236 237 242 246 248
  and said        0   0   0   0   0   0   0   0   0   0
  and security    0   0   0   0   0   0   0   0   1   0
  and set         0   1   0   0   0   0   0   0   0   0
  and six-month   0   0   0   0   0   0   0   1   0   0
  and some        0   0   0   0   0   0   0   0   0   0
  and stabilise   0   0   0   0   0   0   0   0   0   1

帽子提示:http://tm.r-forge.r-project.org/faq.html

【讨论】:

【参考方案2】:

对于仍然对这个主题感兴趣的人,起重机上已经有一个包。

ngram:一个 n-gram 胡言乱语

该软件包提供了用于创建、显示和“乱码”n-gram 的实用程序。 babbler 是一个简单的马尔可夫过程。

http://cran.r-project.org/web/packages/ngram/index.html

【讨论】:

【参考方案3】:

通常计算 n-gram 以找到其频率分布。所以是的,n-gram 出现多少次并不重要。

您还需要字符级别的 n-gram 或单词级别的 n-gram。我已经编写了一个代码,用于从 r 中的 csv 文件中查找字符级别的 n-gram。我为此使用了“tau”包。你可以找到它here。

这也是我写的代码:

 library(tau)
temp<-read.csv("/home/aravi/Documents/sample/csv/ex.csv",header=FALSE,stringsAsFactors=F)
r<-textcnt(temp, method="ngram",n=4L,split = "[[:space:][:punct:]]+", decreasing=TRUE)
a<-data.frame(counts = unclass(r), size = nchar(names(r)))
b<-split(a,a$size)
b

干杯!

【讨论】:

【参考方案4】:

编辑:对不起,这是 php。我不太确定你想要什么。我不知道它在java中,但也许以下可以很容易地转换。

这取决于你想要的 ngram 的大小。

我在单个字母方面取得了相当大的成功(对于语言检测尤其准确),这很容易理解:

$letters=str_split(preg_replace('/[^a-z]/', '', strtolower($text)));
$letters=array_count_values($letters);

然后有以下函数用于从一个单词计算 ngram:

function getNgrams($word, $n = 3) 
        $ngrams = array();
        $len = strlen($word);
        for($i = 0; $i < $len; $i++) 
                if($i > ($n - 2)) 
                        $ng = '';
                        for($j = $n-1; $j >= 0; $j--) 
                                $ng .= $word[$i-$j];
                        
                        $ngrams[] = $ng;
                
        
        return $ngrams;

以上内容的来源是here,我推荐你阅读,它们有很多功能可以完全满足你的需求。

【讨论】:

【参考方案5】:

您可以使用 ngram 包。它的用法之一是http://amunategui.github.io/speak-like-a-doctor/

【讨论】:

您好,欢迎来到 SO。这个答案几乎完全依赖于外部链接。如果它们变得无效,您的答案将变得毫无用处。所以请编辑它并至少添加一个可以在那里找到的摘要。谢谢!【参考方案6】:

看看https://cran.r-project.org/web/packages/ngram/vignettes/ngram-guide.pdf

这是一个简单的例子。看小插图的基准是相当快的。

require(ngram)

"hi i am ig" %>% ngram(n = 2) %>% get.ngrams()

【讨论】:

【参考方案7】:

简单的 java 答案如下:

int ngrams = 9;// let's say 9-grams since it's the length of "bonasuera"... 
String string = "bonasuera";
for (int j=1; j <= ngrams;j++)     
    for (int k=0; k < string.length()-j+1;k++ )
        System.out.print(string.substring(k,k+j) + " ");
    System.out.println();

输出:

b o n a s u e r a 
bo on na as su ue er ra 
bon ona nas asu sue uer era 
bona onas nasu asue suer uera 
bonas onasu nasue asuer suera 
bonasu onasue nasuer asuera 
bonasue onasuer nasuera 
bonasuer onasuera 
bonasuera 

【讨论】:

以上是关于我需要啥算法来找到 n-gram?的主要内容,如果未能解决你的问题,请参考以下文章

自然语言处理中的N-Gram模型详解

1.3 n-gram平滑算法:Good-Turning拉普拉斯平滑

ElasticSearch n-gram tokenfilter 未找到部分单词

Python:如何在文本中找到 n-gram 模式?

NLPN-Gram自然语言处理模糊匹配编辑距离

如何使用 n-gram 进行多标签分类?