web-dev-qa-db-ja.com

文からのN-gramの生成

次のような文字列のn-gramを生成する方法:

String Input="This is my car."

この入力でn-gramを生成したい:

Input Ngram size = 3

出力は次のようになります。

This
is
my
car

This is
is my
my car

This is my
is my car

Javaでいくつかのアイデア、それを実装する方法、またはライブラリが利用できるかどうかを教えてください。

this NGramTokenizer を使用しようとしていますが、n-gramの文字シーケンスとn-gramのWordシーケンスが必要です。

28
Preetam Purbia

ShingleFilter を探しています。

更新:リンクはバージョン3.0.2を指します。このクラスは、Luceneの新しいバージョンでは異なるパッケージに含まれている場合があります。

24
Shashikant Kore

私はこれがあなたが望むことをするだろうと信じています:

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();
    }
}
42
aioobe

このコードは、指定された長さのすべての文字列の配列を返します。

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] 
6
Landei
    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グラムは、結果セットから無視されます。入力は文のリストであり、OpenNLPのツールを使用して解析します

1
Dung TQ
/**
 * 
 * @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());

出力:

Ngramsize = 9で私の時間= 1ミリ秒

1
tozCSS

これをチェックしてください:

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

シンプルな再帰関数、実行時間の改善。

0
Jagesh Maharjan
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;
}
0
M Sach