2010-09-07 10 views
28

Làm thế nào để tạo ra một n-gram một chuỗi như:thế hệ N-gram từ một câu

String Input="This is my car." 

Tôi muốn tạo ra n-gram với đầu vào này:

Input Ngram size = 3 

Output nên :

This 
is 
my 
car 

This is 
is my 
my car 

This is my 
is my car 

Đưa ra một số ý tưởng trong Java, cách triển khai hoặc nếu có bất kỳ thư viện nào cho nó.

Tôi đang cố gắng sử dụng this NGramTokenizer nhưng cung cấp n-gram chuỗi ký tự và tôi muốn n-gam chuỗi từ.

Trả lời

23

Bạn đang tìm kiếm ShingleFilter.

Cập nhật: Liên kết trỏ đến phiên bản 3.0.2. Lớp này có thể nằm trong gói khác trong phiên bản mới hơn của Lucene.

38

Tôi tin rằng điều này sẽ làm những gì bạn muốn:

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 "theo yêu cầu" giải pháp thực hiện như một 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(); 
    } 
} 
6

Mã này trả về một mảng của tất cả các Chuỗi có độ dài đã cho:

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

Ví dụ:

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] 
+2

'ngrams ("Đây là xe của tôi", -3) '(xin lỗi, không thể cưỡng lại) – wds

+0

' ngrams (" Đây là của tôi xe ", -3)' hoạt động tốt. 'ngrams (" Đây là chiếc xe của tôi ", 6)' tuy nhiên, kết quả trong một 'NegativeArraySizeException'. – aioobe

+6

Bạn mong đợi điều gì trong những trường hợp này? Tôi muốn đề nghị đặt một thử nghiệm ở đầu phương thức và trả về một mảng trống. Nói chung tôi thấy vài câu trả lời SO với một xử lý lỗi phức tạp. – Landei

1
/** 
* 
* @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; 
} 

Gọi:

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 với ngramsize = 9 [này, được, Đây là, tôi, là của tôi, Đây là là của tôi, ô tô, xe hơi của tôi, là xe của tôi]

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

Đây là mã của tôi để tạo n-gram. Trong trường hợp này, n = 2, 3. n-gam các chuỗi từ nhỏ hơn giá trị ngưỡng sẽ bỏ qua từ tập kết quả. Đầu vào là danh sách các câu, sau đó nó phân tích cú pháp sử dụng một công cụ của OpenNLP

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