13

我正在尝试将字符串标记为 ngram。奇怪的是,在NGramTokenizer的文档中,我没有看到将返回已标记化的单个 ngram 的方法。事实上,我只在 NGramTokenizer 类中看到两个返回字符串对象的方法。

这是我拥有的代码:

Reader reader = new StringReader("This is a test string");
NGramTokenizer gramTokenizer = new NGramTokenizer(reader, 1, 3);
  1. 被标记化的 ngram 在哪里?
  2. 如何获得字符串/单词的输出?

我希望我的输出是这样的:这是,是,一个,测试,字符串,这是,是一个,一个测试,测试字符串,这是一个,是一个测试,一个测试字符串。

4

4 回答 4

19

我不认为你会找到你正在寻找的东西,试图找到返回字符串的方法。您需要处理Attribute

应该像这样工作:

Reader reader = new StringReader("This is a test string");
NGramTokenizer gramTokenizer = new NGramTokenizer(reader, 1, 3);
CharTermAttribute charTermAttribute = gramTokenizer.addAttribute(CharTermAttribute.class);
gramTokenizer.reset();

while (gramTokenizer.incrementToken()) {
    String token = charTermAttribute.toString();
    //Do something
}
gramTokenizer.end();
gramTokenizer.close();

但是,如果之后需要重用,请务必重置() Tokenizer。


根据评论对单词分组而不是字符进行标记:

Reader reader = new StringReader("This is a test string");
TokenStream tokenizer = new StandardTokenizer(Version.LUCENE_36, reader);
tokenizer = new ShingleFilter(tokenizer, 1, 3);
CharTermAttribute charTermAttribute = tokenizer.addAttribute(CharTermAttribute.class);

while (tokenizer.incrementToken()) {
    String token = charTermAttribute.toString();
    //Do something
}
于 2012-11-20T23:06:32.220 回答
1

对于最新版本的 Lucene (4.2.1),这是一个有效的干净代码。在执行此代码之前,您必须导入 2 个 jar 文件:

  • lucene-core-4.2.1.jar
  • lucene-analuzers-common-4.2.1.jar

在http://www.apache.org/dyn/closer.cgi/lucene/java/4.2.1找到这些文件

//LUCENE 4.2.1
Reader reader = new StringReader("This is a test string");      
NGramTokenizer gramTokenizer = new NGramTokenizer(reader, 1, 3);

CharTermAttribute charTermAttribute = gramTokenizer.addAttribute(CharTermAttribute.class);

while (gramTokenizer.incrementToken()) {
    String token = charTermAttribute.toString();
    System.out.println(token);
}
于 2013-04-25T05:12:48.367 回答
0

如果不创建测试程序,我猜 incrementToken() 返回下一个标记,它将是 ngram 之一。

例如,使用长度为 1-3 的 ngram 和字符串 'abc d',NGramTokenizer 可以返回:

a
a b
a b c
b
b c
b c d
c
c d
d

其中“a”、“a b”等是生成的 ngram。

[编辑]

您可能还想查看Querying lucene tokens without indexing,因为它谈到了窥探令牌流。

于 2012-11-20T22:33:04.557 回答
0
package ngramalgoimpl;
import java.util.*;

public class ngr {

    public static List<String> n_grams(int n, String str) {
        List<String> n_grams = new ArrayList<String>();
        String[] words = str.split(" ");
        for (int i = 0; i < words.length - n + 1; i++)
            n_grams.add(concatination(words, i, i+n));
        return n_grams;
    }
     /*stringBuilder is used to cancatinate mutable sequence of characters*/
    public static String concatination(String[] words, int start, int end) {
        StringBuilder sb = new StringBuilder();
        for (int i = start; i < end; i++)
            sb.append((i > start ? " " : "") + words[i]);
        return sb.toString();
    }

    public static void main(String[] args) {
        for (int n = 1; n <= 3; n++) {
            for (String ngram : n_grams(n, "This is my car."))
                System.out.println(ngram);
            System.out.println();
        }
    }
}
于 2017-09-19T12:29:26.583 回答