我需要什么算法来查找n-gram?

14

如何找到N-grams?

假设我的输入数据是一个单词数组,我想要找到的N-grams的大小是多少,则应使用什么算法?

我需要代码,并希望使用R语言。数据存储在数据库中,因此也可以是plgpsql函数。 Java是我比较熟悉的语言,所以我可以将其“转换”为另一种语言。

我不是懒,只是希望得到代码,因为我不想重新发明轮子,尝试做已经完成的算法。

编辑:重要的是知道每个N-gram出现的次数。

编辑2:是否有R包可以处理N-GRAMS?


6
有一个文本挖掘包(tm)和一个textcat包... library("sos"); findFn("n-gram") - Ben Bolker
请查看 https://cran.r-project.org/web/packages/ngram/vignettes/ngram-guide.pdf。 - Indranil Gayen
7个回答

24

如果您想使用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


8

对于仍然对此话题感兴趣的人,cran上已经有一个包了。

ngram: 一个n-gram Babbler

此包提供了用于创建、显示和“babbling” n-grams的实用工具。Babbler是一个简单的马尔可夫过程。

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


3

通常计算n-grams以查找其频率分布。因此,n-gram出现的次数确实很重要。

您还想要字符级别的n-gram或单词级别的n-gram。我编写了一段代码,在r中从csv文件中查找字符级别n-gram。我使用了包“tau”。您可以在此处找到它。

以下是我编写的代码:

 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

干杯!


1

编辑:抱歉,这是PHP。我不太确定你想要什么。我不知道Java中的情况,但以下内容可能很容易转换。

好吧,这取决于您想要的ngrams的大小。

我在单个字母方面取得了相当大的成功(特别适用于语言检测),可以使用以下简单方法获得:

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

接下来是用于从单词计算ngrams的以下函数:

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;
}

上述内容的来源是这里,我建议您阅读一下,它们有很多函数可以完全满足您的需求。

0

0

你好,欢迎来到SO。这个答案几乎完全依赖于外部链接。如果它们变得无效,你的答案将变得无用。因此,请编辑并至少添加一个可以在那里找到的摘要。谢谢! - Fabio says Reinstate Monica

0

这里是简单的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 

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接