从句子生成 N 元语法

发布于 2024-09-18 17:26:25 字数 534 浏览 11 评论 0原文

如何生成字符串的 n 元语法,例如:

String Input="This is my car."

我想使用此输入生成 n 元语法:

Input Ngram size = 3

输出应该是:

This
is
my
car

This is
is my
my car

This is my
is my car

用 Ja​​va 给出一些想法,如何实现它或者是否有可用的库。

我正在尝试使用 这个 NGramTokenizer 但它给出了 n-gram 的字符序列,而我想要 n-gram 的单词序列。

How to generate an n-gram of a string like:

String Input="This is my car."

I want to generate n-gram with this input:

Input Ngram size = 3

Output should be:

This
is
my
car

This is
is my
my car

This is my
is my car

Give some idea in Java, how to implement that or if any library is available for it.

I am trying to use this NGramTokenizer but its giving n-gram's of character sequence and I want n-grams of word sequence.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

奶茶白久 2024-09-25 17:26:26
public static void main(String[] args) {

    String[] words = "This is my car.".split(" ");
    for (int n = 0; n < 3; n++) {

        List<String> list = ngrams(n, words);
        for (String ngram : list) {
            System.out.println(ngram);
        }
        System.out.println();

    }
}

public static List<String> ngrams(int stepSize, String[] words) {
    List<String> ngrams = new ArrayList<String>();
    for (int i = 0; i < words.length-stepSize; i++) {

        String initialWord = "";
        int internalCount = i;
        int internalStepSize = i + stepSize;
        while (internalCount <= internalStepSize
                && internalCount < words.length) {
            initialWord = initialWord+" " + words[internalCount];
            ++internalCount;
        }
        ngrams.add(initialWord);

    }
    return ngrams;
}
public static void main(String[] args) {

    String[] words = "This is my car.".split(" ");
    for (int n = 0; n < 3; n++) {

        List<String> list = ngrams(n, words);
        for (String ngram : list) {
            System.out.println(ngram);
        }
        System.out.println();

    }
}

public static List<String> ngrams(int stepSize, String[] words) {
    List<String> ngrams = new ArrayList<String>();
    for (int i = 0; i < words.length-stepSize; i++) {

        String initialWord = "";
        int internalCount = i;
        int internalStepSize = i + stepSize;
        while (internalCount <= internalStepSize
                && internalCount < words.length) {
            initialWord = initialWord+" " + words[internalCount];
            ++internalCount;
        }
        ngrams.add(initialWord);

    }
    return ngrams;
}
听不够的曲调 2024-09-25 17:26:26

看看这个:

public static void main(String[] args) {
    NGram nGram = new NGram();
    String[] tokens = "this is my car".split(" ");
    int i = tokens.length;
    List<String> ngrams = new ArrayList<>();
    while (i >= 1){
        ngrams.addAll(nGram.getNGram(tokens, i, new ArrayList<>()));
        i--;
    }
    System.out.println(ngrams);
}

private List<String> getNGram(String[] tokens, int n, List<String> ngrams) {
    StringBuilder strbldr = new StringBuilder();
    if (tokens.length < n) {
        return ngrams;
    }else {
        for (int i=0; i<n; i++){
            strbldr.append(tokens[i]).append(" ");
        }
        ngrams.add(strbldr.toString().trim());
        String[] newTokens = Arrays.copyOfRange(tokens, 1, tokens.length);
        return getNGram(newTokens, n, ngrams);
    }
}

简单的递归函数,更好的运行时间。

Check this out:

public static void main(String[] args) {
    NGram nGram = new NGram();
    String[] tokens = "this is my car".split(" ");
    int i = tokens.length;
    List<String> ngrams = new ArrayList<>();
    while (i >= 1){
        ngrams.addAll(nGram.getNGram(tokens, i, new ArrayList<>()));
        i--;
    }
    System.out.println(ngrams);
}

private List<String> getNGram(String[] tokens, int n, List<String> ngrams) {
    StringBuilder strbldr = new StringBuilder();
    if (tokens.length < n) {
        return ngrams;
    }else {
        for (int i=0; i<n; i++){
            strbldr.append(tokens[i]).append(" ");
        }
        ngrams.add(strbldr.toString().trim());
        String[] newTokens = Arrays.copyOfRange(tokens, 1, tokens.length);
        return getNGram(newTokens, n, ngrams);
    }
}

Simple recursive function, better running time.

私藏温柔 2024-09-25 17:26:25

我相信这会满足您的要求:

import java.util.*;

public class Test {

    public static List<String> ngrams(int n, String str) {
        List<String> ngrams = new ArrayList<String>();
        String[] words = str.split(" ");
        for (int i = 0; i < words.length - n + 1; i++)
            ngrams.add(concat(words, i, i+n));
        return ngrams;
    }

    public static String concat(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 : ngrams(n, "This is my car."))
                System.out.println(ngram);
            System.out.println();
        }
    }
}

输出:

This
is
my
car.

This is
is my
my car.

This is my
is my car.

作为迭代器实现的“按需”解决方案:

class NgramIterator implements Iterator<String> {

    String[] words;
    int pos = 0, n;

    public NgramIterator(int n, String str) {
        this.n = n;
        words = str.split(" ");
    }

    public boolean hasNext() {
        return pos < words.length - n + 1;
    }

    public String next() {
        StringBuilder sb = new StringBuilder();
        for (int i = pos; i < pos + n; i++)
            sb.append((i > pos ? " " : "") + words[i]);
        pos++;
        return sb.toString();
    }

    public void remove() {
        throw new UnsupportedOperationException();
    }
}

I believe this would do what you want:

import java.util.*;

public class Test {

    public static List<String> ngrams(int n, String str) {
        List<String> ngrams = new ArrayList<String>();
        String[] words = str.split(" ");
        for (int i = 0; i < words.length - n + 1; i++)
            ngrams.add(concat(words, i, i+n));
        return ngrams;
    }

    public static String concat(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 : ngrams(n, "This is my car."))
                System.out.println(ngram);
            System.out.println();
        }
    }
}

Output:

This
is
my
car.

This is
is my
my car.

This is my
is my car.

An "on-demand" solution implemented as an Iterator:

class NgramIterator implements Iterator<String> {

    String[] words;
    int pos = 0, n;

    public NgramIterator(int n, String str) {
        this.n = n;
        words = str.split(" ");
    }

    public boolean hasNext() {
        return pos < words.length - n + 1;
    }

    public String next() {
        StringBuilder sb = new StringBuilder();
        for (int i = pos; i < pos + n; i++)
            sb.append((i > pos ? " " : "") + words[i]);
        pos++;
        return sb.toString();
    }

    public void remove() {
        throw new UnsupportedOperationException();
    }
}
童话里做英雄 2024-09-25 17:26:25

您正在寻找 木瓦过滤器

更新:链接指向版本3.0.2。在较新版本的 Lucene 中,此类可能位于不同的包中。

You are looking for ShingleFilter.

Update: The link points to version 3.0.2. This class may be in different package in newer version of Lucene.

橘香 2024-09-25 17:26:25

此代码返回给定长度的所有字符串的数组:

public static String[] ngrams(String s, int len) {
    String[] parts = s.split(" ");
    String[] result = new String[parts.length - len + 1];
    for(int i = 0; i < parts.length - len + 1; i++) {
       StringBuilder sb = new StringBuilder();
       for(int k = 0; k < len; k++) {
           if(k > 0) sb.append(' ');
           sb.append(parts[i+k]);
       }
       result[i] = sb.toString();
    }
    return result;
}

例如

System.out.println(Arrays.toString(ngrams("This is my car", 2)));
//--> [This is, is my, my car]
System.out.println(Arrays.toString(ngrams("This is my car", 3)));
//--> [This is my, is my car] 

This code returns an array of all Strings of the given length:

public static String[] ngrams(String s, int len) {
    String[] parts = s.split(" ");
    String[] result = new String[parts.length - len + 1];
    for(int i = 0; i < parts.length - len + 1; i++) {
       StringBuilder sb = new StringBuilder();
       for(int k = 0; k < len; k++) {
           if(k > 0) sb.append(' ');
           sb.append(parts[i+k]);
       }
       result[i] = sb.toString();
    }
    return result;
}

E.g.

System.out.println(Arrays.toString(ngrams("This is my car", 2)));
//--> [This is, is my, my car]
System.out.println(Arrays.toString(ngrams("This is my car", 3)));
//--> [This is my, is my car] 
-残月青衣踏尘吟 2024-09-25 17:26:25
/**
 * 
 * @param sentence should has at least one string
 * @param maxGramSize should be 1 at least
 * @return set of continuous word n-grams up to maxGramSize from the sentence
 */
public static List<String> generateNgramsUpto(String str, int maxGramSize) {

    List<String> sentence = Arrays.asList(str.split("[\\W+]"));

    List<String> ngrams = new ArrayList<String>();
    int ngramSize = 0;
    StringBuilder sb = null;

    //sentence becomes ngrams
    for (ListIterator<String> it = sentence.listIterator(); it.hasNext();) {
        String word = (String) it.next();

        //1- add the word itself
        sb = new StringBuilder(word);
        ngrams.add(word);
        ngramSize=1;
        it.previous();

        //2- insert prevs of the word and add those too
        while(it.hasPrevious() && ngramSize<maxGramSize){
            sb.insert(0,' ');
            sb.insert(0,it.previous());
            ngrams.add(sb.toString());
            ngramSize++;
        }

        //go back to initial position
        while(ngramSize>0){
            ngramSize--;
            it.next();
        }                   
    }
    return ngrams;
}

调用:

long startTime = System.currentTimeMillis();
ngrams = ToolSet.generateNgramsUpto("This is my car.", 3);
long stopTime = System.currentTimeMillis();
System.out.println("My time = "+(stopTime-startTime)+" ms with ngramsize = "+ngrams.size());
System.out.println(ngrams.toString());

输出:

我的时间 = 1 毫秒,ngramsize = 9 [这,是,这是,我的,是我的,这
是我的车,我的车,是我的车]

/**
 * 
 * @param sentence should has at least one string
 * @param maxGramSize should be 1 at least
 * @return set of continuous word n-grams up to maxGramSize from the sentence
 */
public static List<String> generateNgramsUpto(String str, int maxGramSize) {

    List<String> sentence = Arrays.asList(str.split("[\\W+]"));

    List<String> ngrams = new ArrayList<String>();
    int ngramSize = 0;
    StringBuilder sb = null;

    //sentence becomes ngrams
    for (ListIterator<String> it = sentence.listIterator(); it.hasNext();) {
        String word = (String) it.next();

        //1- add the word itself
        sb = new StringBuilder(word);
        ngrams.add(word);
        ngramSize=1;
        it.previous();

        //2- insert prevs of the word and add those too
        while(it.hasPrevious() && ngramSize<maxGramSize){
            sb.insert(0,' ');
            sb.insert(0,it.previous());
            ngrams.add(sb.toString());
            ngramSize++;
        }

        //go back to initial position
        while(ngramSize>0){
            ngramSize--;
            it.next();
        }                   
    }
    return ngrams;
}

Call:

long startTime = System.currentTimeMillis();
ngrams = ToolSet.generateNgramsUpto("This is my car.", 3);
long stopTime = System.currentTimeMillis();
System.out.println("My time = "+(stopTime-startTime)+" ms with ngramsize = "+ngrams.size());
System.out.println(ngrams.toString());

Output:

My time = 1 ms with ngramsize = 9 [This, is, This is, my, is my, This
is my, car, my car, is my car]

故事未完 2024-09-25 17:26:25
    public static void CreateNgram(ArrayList<String> list, int cutoff) {
    try
    {
        NGramModel ngramModel = new NGramModel();
        POSModel model = new POSModelLoader().load(new File("en-pos-maxent.bin"));
        PerformanceMonitor perfMon = new PerformanceMonitor(System.err, "sent");
        POSTaggerME tagger = new POSTaggerME(model);
        perfMon.start();
        for(int i = 0; i<list.size(); i++)
        {
            String inputString = list.get(i);
            ObjectStream<String> lineStream = new PlainTextByLineStream(new StringReader(inputString));
            String line;
            while ((line = lineStream.read()) != null) 
            {
                String whitespaceTokenizerLine[] = WhitespaceTokenizer.INSTANCE.tokenize(line);
                String[] tags = tagger.tag(whitespaceTokenizerLine);

                POSSample sample = new POSSample(whitespaceTokenizerLine, tags);

                perfMon.incrementCounter();

                String words[] = sample.getSentence();

                if(words.length > 0)
                {
                    for(int k = 2; k< 4; k++)
                    {
                        ngramModel.add(new StringList(words), k, k);
                    }
                }
            }
        }
        ngramModel.cutoff(cutoff, Integer.MAX_VALUE);
        Iterator<StringList> it = ngramModel.iterator();
        while(it.hasNext())
        {
            StringList strList = it.next();
            System.out.println(strList.toString());
        }
        perfMon.stopAndPrintFinalResult();
    }catch(Exception e)
    {
        System.out.println(e.toString());
    }
}

这是我创建 n-gram 的代码。在这种情况下,n = 2, 3。小于截止值的n-gram单词序列将从结果集中忽略。输入是句子列表,然后使用 OpenNLP 工具进行解析

    public static void CreateNgram(ArrayList<String> list, int cutoff) {
    try
    {
        NGramModel ngramModel = new NGramModel();
        POSModel model = new POSModelLoader().load(new File("en-pos-maxent.bin"));
        PerformanceMonitor perfMon = new PerformanceMonitor(System.err, "sent");
        POSTaggerME tagger = new POSTaggerME(model);
        perfMon.start();
        for(int i = 0; i<list.size(); i++)
        {
            String inputString = list.get(i);
            ObjectStream<String> lineStream = new PlainTextByLineStream(new StringReader(inputString));
            String line;
            while ((line = lineStream.read()) != null) 
            {
                String whitespaceTokenizerLine[] = WhitespaceTokenizer.INSTANCE.tokenize(line);
                String[] tags = tagger.tag(whitespaceTokenizerLine);

                POSSample sample = new POSSample(whitespaceTokenizerLine, tags);

                perfMon.incrementCounter();

                String words[] = sample.getSentence();

                if(words.length > 0)
                {
                    for(int k = 2; k< 4; k++)
                    {
                        ngramModel.add(new StringList(words), k, k);
                    }
                }
            }
        }
        ngramModel.cutoff(cutoff, Integer.MAX_VALUE);
        Iterator<StringList> it = ngramModel.iterator();
        while(it.hasNext())
        {
            StringList strList = it.next();
            System.out.println(strList.toString());
        }
        perfMon.stopAndPrintFinalResult();
    }catch(Exception e)
    {
        System.out.println(e.toString());
    }
}

Here is my codes to create n-gram. In this case, n = 2, 3. n-gram of words sequence which smaller than cutoff value will ignore from result set. Input is list of sentences, then it parse using a tool of OpenNLP

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文