【问题标题】:Java Lucene NGramTokenizerJava Lucene NGramTokenizer
【发布时间】:2012-11-17 18:50:27
【问题描述】:

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

这是我的代码:

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

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

【问题讨论】:

    标签: java lucene tokenize n-gram


    【解决方案1】:

    我不认为你会找到你正在寻找的东西试图找到返回字符串的方法。您需要与Attributes 打交道。

    应该像这样工作:

    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。


    对每个 cmets 的单词分组而不是字符进行标记:

    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
    }
    

    【讨论】:

    • 就属性而言,我可以用字符串而不是字符做什么?那么我的输出将类似于:This, is, a, test, string, This is, is, a, test, ... a test string。
    • 好吧,这不是 Lucene 的 NGramTokenizer 旨在处理的。我认为你想要使用的是 ShingleFilter 与 StandardTokenizer 的结合。我会更新我的答案,在那里更容易表达......
    • 你知道我可以在标记化过程中使用的任何停用词过滤器吗?
    • 我认为标准是StopFilter。顺便说一下,另一个非常典型的过滤器是StandardFilter。我认为 StandardFilter,然后 StopFilter,然后 ShingleFilter 可能会得到很好的结果。
    • 查看了我关于 StopFilter 的最新帖子:stackoverflow.com/questions/13501421/…
    【解决方案2】:

    对于最新版本的 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);
    }
    

    【讨论】:

      【解决方案3】:

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

      例如,使用长度为 1-3 的 ngram 和字符串 'a b c 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,因为它谈到了窥探令牌流。

      【讨论】:

        【解决方案4】:
        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();
                }
            }
        }
        

        【讨论】:

        • 请提供上下文,这段代码有什么作用以及它如何提供问题的答案?
        • @KevinKloet 查看问题并给出答案
        猜你喜欢
        • 2018-07-18
        • 2010-11-18
        • 1970-01-01
        • 2023-03-12
        • 1970-01-01
        • 1970-01-01
        • 2016-09-01
        • 1970-01-01
        • 2010-09-17
        相关资源
        最近更新 更多