2017-04-12 163 views
1

我在java上使用openNLP API來處理我正在處理的項目。事情是,在我的程序中,我只處理單詞而沒有對應關係。 代碼:openNLP java - 多項葡萄牙語NER

String line = input.nextLine(); 


      InputStream inputStreamTokenizer = new FileInputStream("/home/bruno/openNLP/apache-opennlp-1.7.2-src/models/pt-token.bin"); 
      TokenizerModel tokenModel = new TokenizerModel(inputStreamTokenizer); 

      //Instantiating the TokenizerME class 
      TokenizerME tokenizer = new TokenizerME(tokenModel); 
      String tokens[] = tokenizer.tokenize(line); 


      InputStream inputStream = new FileInputStream("/home/bruno/openNLP/apache-opennlp-1.7.2-src/models/pt-sent.bin"); 
      SentenceModel model = new SentenceModel(inputStream); 

      //Instantiating the SentenceDetectorME class 
      SentenceDetectorME detector = new SentenceDetectorME(model); 

      //Detecting the sentence 
      String sentences[] = detector.sentDetect(line); 

      //Loading the NER-location model 
      //InputStream inputStreamLocFinder = new FileInputStream("/home/bruno/openNLP/apache-opennlp-1.7.2-src/models/en-ner-location.bin");  
      //TokenNameFinderModel model = new TokenNameFinderModel(inputStreamLocFinder); 

      //Loading the NER-person model 
      InputStream inputStreamNameFinder = new FileInputStream("/home/bruno/TryOllie/data/pt-ner-floresta.bin");  
      TokenNameFinderModel model2 = new TokenNameFinderModel(inputStreamNameFinder); 

      //Instantiating the NameFinderME class 
      NameFinderME nameFinder2 = new NameFinderME(model2); 

      //Finding the names of a location 
      Span nameSpans2[] = nameFinder2.find(tokens); 

      //Printing the spans of the locations in the sentence 
      //for(Span s: nameSpans)   
      //System.out.println(s.toString()+" "+tokens[s.getStart()]); 

      Set<String> x = new HashSet<String>(); 
      x.add("event"); 
      x.add("artprod"); 
      x.add("place"); 
      x.add("organization"); 
      x.add("person"); 
      x.add("numeric"); 

      SimpleTokenizer simpleTokenizer = SimpleTokenizer.INSTANCE; 
      Span[] tokenz = simpleTokenizer.tokenizePos(line); 
      Set<String> tk = new HashSet<String>(); 
      for(Span tok : tokenz){ 
       tk.add(line.substring(tok.getStart(), tok.getEnd())); 
      } 

      for(Span n: nameSpans2) 
      { 
       if(x.contains(n.getType())) 
        System.out.println(n.toString()+ " -> " + tokens[n.getStart()]); 

      } 

輸出我得到的是:

Ficheiro com extensao: file.txt 
[1..2) event -> choque[3..4) event -> cadeia[6..7) artprod -> viaturas[13..14) event -> feira[16..18) place -> Avenida[20..21) place -> Porto[24..25) event -> incêndio[2..3) event -> acidente[5..6) artprod -> viaturas[44..45) organization -> JN[46..47) person -> António[47..48) place -> Campos[54..60) organization -> Batalhão[1..2) event -> acidente[6..8) numeric -> 9[11..12) place -> Porto-Matosinhos[21..22) event -> ocorrência[29..30) artprod -> .[4..5) organization -> Sapadores[7..10) organization -> Bombeiros[14..15) numeric -> 15 

什麼即時試圖做的是一個多學期NER,像安東尼坎波斯是一個人,不是人 - >安東尼奧和地點 - > Campos或組織 - > Universidade Nova de Lisboa

回答

0

Stanford-NLP只處理單個詞。即使你給coreNLP一個句子,它也會分解成令牌並逐個處理它們。我從來沒有聽說過NER適用於多學期。

+0

林打破了文成句子,記號化每一個字,所以我的程序只能看每個字分開,這哪裏是我的問題在於,我必須來標記,但我需要看單詞,例如找到Antonio Antonio Campos作爲一個人找到,而不是Antonio作爲一個人,Campos作爲一個地方,或另一個人...... 這同樣適用於像Fernando Pessoa大學這樣的組織,我想找到它作爲一個組織,而不是大學作爲組織,費爾南多作爲人和佩索阿作爲其他人 – Break

+0

好吧,我明白你的問題,但這是如何**斯坦福NLP **的工作。 NER只在完成這個過程之後才工作(tokenize,ssplit,pos,引理)。所以很明顯NER只處理一個小字。可能是這[鏈接](https://stanfordnlp.github.io/CoreNLP/dependencies.html)給你的想法。 –

+0

所以,我只能看單個單詞,這意味着我無法解決我與那個NER的問題? – Break

1

您正在打印錯誤的數據結構。範圍getSart和getEnd將指向屬於實體一部分的標記序列。您只打印第一個標記。

此外,您正在做句子檢測前的標記。

試試下面的代碼:

// load the models outside your loop 
InputStream inputStream = 
    new FileInputStream("/home/bruno/openNLP/apache-opennlp-1.7.2-src/models/pt-sent.bin"); 
SentenceModel model = new SentenceModel(inputStream); 

//Instantiating the SentenceDetectorME class 
SentenceDetectorME detector = new SentenceDetectorME(model); 

InputStream inputStreamTokenizer = 
    new FileInputStream("/home/bruno/openNLP/apache-opennlp-1.7.2-src/models/pt-token.bin"); 
TokenizerModel tokenModel = new TokenizerModel(inputStreamTokenizer); 
//Instantiating the TokenizerME class 
TokenizerME tokenizer = new TokenizerME(tokenModel); 


//Loading the NER-person model 
InputStream inputStreamNameFinder = new FileInputStream("/home/bruno/TryOllie/data/pt-ner-floresta.bin"); 
TokenNameFinderModel model2 = new TokenNameFinderModel(inputStreamNameFinder); 

//Instantiating the NameFinderME class 
NameFinderME nameFinder2 = new NameFinderME(model2); 

String line = input.nextLine(); 

while(line != null) { 

    // first we find sentences 
    String sentences[] = detector.sentDetect(line); 

    for (String sentence : 
     sentences) { 
    // now we find the sentence tokens 
    String tokens[] = tokenizer.tokenize(sentence); 

    // now we are good to apply NER 
    Span[] nameSpans = nameFinder2.find(tokens); 

    // now we can print the spans 
    System.out.println(Arrays.toString(Span.spansToStrings(nameSpans, tokens))); 

    line = input.nextLine(); 
    } 
} 
+0

謝謝你的回答wcolen,我已經tryed,解決辦法,但輸出是: Ficheiro COM extensao:file.txt的 [Ljava.lang.String; @ 6f2b958e [Ljava.lang.String; @ 1eb44e46 [ Ljava.lang.String; @ 6504e3b2 [Ljava.lang.String; @ 515f550a [Ljava.lang.String; @ 626b2d4a [Ljava.lang.String; @ 5e91993f 異常在線程 「主」 java.util.NoSuchElementException :沒有找到行 \t在java.util.Scanner.nextLine(Scanner.java:1540) \t在ner.Wiki.main(Wiki.java:76) 我tryed其他方法,如的toString輸出。和它和以前一樣,我在這裏做錯了什麼?謝謝 – Break

+0

'Span.spansToStrings(...)'返回一個字符串數組。再次使用'Arrays.toString(Span.spansToStrings(nameSpans,tokens))' – wcolen