OpenNLP - Riconoscimento di entità denominate

Il processo di ricerca di nomi, persone, luoghi e altre entità da un determinato testo è noto come Named Entity Rriconoscimento (NER). In questo capitolo, discuteremo come eseguire NER tramite il programma Java utilizzando la libreria OpenNLP.

Riconoscimento di entità denominate utilizzando NLP aperto

Per eseguire varie attività NER, OpenNLP utilizza diversi modelli predefiniti, ovvero en-nerdate.bn, en-ner-location.bin, en-ner-organization.bin, en-ner-person.bin ed en-ner-time. bidone. Tutti questi file sono modelli predefiniti addestrati per rilevare le rispettive entità in un dato testo grezzo.

Il opennlp.tools.namefindIl pacchetto contiene le classi e le interfacce utilizzate per eseguire l'attività NER. Per eseguire attività NER utilizzando la libreria OpenNLP, è necessario:

  • Caricare il rispettivo modello utilizzando il file TokenNameFinderModel classe.

  • Istanziare il file NameFinder classe.

  • Trova i nomi e stampali.

Di seguito sono riportati i passaggi da seguire per scrivere un programma che rilevi le entità del nome da un dato testo grezzo.

Passaggio 1: caricamento del modello

Il modello per il rilevamento della frase è rappresentato dalla classe denominata TokenNameFinderModel, che appartiene al pacchetto opennlp.tools.namefind.

Per caricare un modello NER -

  • Creare un InputStream oggetto del modello (creare un'istanza di FileInputStream e passare il percorso del modello NER appropriato in formato String al suo costruttore).

  • Istanziare il file TokenNameFinderModel class e passare il InputStream (oggetto) del modello come parametro del suo costruttore, come mostrato nel seguente blocco di codice.

//Loading the NER-person model 
InputStream inputStreamNameFinder = new FileInputStream(".../en-nerperson.bin");       
TokenNameFinderModel model = new TokenNameFinderModel(inputStreamNameFinder);

Passaggio 2: creazione di un'istanza della classe NameFinderME

Il NameFinderME classe del pacchetto opennlp.tools.namefindcontiene metodi per eseguire le attività NER. Questa classe utilizza il modello Entropia massima per trovare le entità nominate nel testo grezzo fornito.

Crea un'istanza di questa classe e passa l'oggetto modello creato nel passaggio precedente come mostrato di seguito:

//Instantiating the NameFinderME class 
NameFinderME nameFinder = new NameFinderME(model);

Passaggio 3: trovare i nomi nella frase

Il find() metodo del NameFinderMEclass viene utilizzata per rilevare i nomi nel testo grezzo passato ad essa. Questo metodo accetta una variabile String come parametro.

Richiamare questo metodo passando il formato String della frase a questo metodo.

//Finding the names in the sentence 
Span nameSpans[] = nameFinder.find(sentence);

Passaggio 4: stampa degli intervalli dei nomi nella frase

Il find() metodo del NameFinderMEclass restituisce un array di oggetti del tipo Span. La classe denominata Span diopennlp.tools.util pacchetto viene utilizzato per memorizzare il file start e end numero intero di insiemi.

È possibile memorizzare le campate restituite da find() nell'array Span e stamparli, come mostrato nel seguente blocco di codice.

//Printing the sentences and their spans of a sentence 
for (Span span : spans)         
System.out.println(paragraph.substring(span);

NER Example

Di seguito è riportato il programma che legge la frase data e riconosce gli intervalli dei nomi delle persone in essa contenuti. Salva questo programma in un file con il nomeNameFinderME_Example.java.

import java.io.FileInputStream; 
import java.io.InputStream;  

import opennlp.tools.namefind.NameFinderME; 
import opennlp.tools.namefind.TokenNameFinderModel; 
import opennlp.tools.util.Span;  

public class NameFinderME_Example { 
   public static void main(String args[]) throws Exception{ 
      /Loading the NER - Person model       InputStream inputStream = new 
         FileInputStream("C:/OpenNLP_models/en-ner-person.bin"); 
      TokenNameFinderModel model = new TokenNameFinderModel(inputStream);
      
      //Instantiating the NameFinder class 
      NameFinderME nameFinder = new NameFinderME(model); 
    
      //Getting the sentence in the form of String array  
      String [] sentence = new String[]{ 
         "Mike", 
         "and", 
         "Smith", 
         "are", 
         "good", 
         "friends" 
      }; 
       
      //Finding the names in the sentence 
      Span nameSpans[] = nameFinder.find(sentence); 
       
      //Printing the spans of the names in the sentence 
      for(Span s: nameSpans) 
         System.out.println(s.toString());    
   }    
}

Compilare ed eseguire il file Java salvato dal prompt dei comandi utilizzando i seguenti comandi:

javac NameFinderME_Example.java 
java NameFinderME_Example

All'esecuzione, il programma di cui sopra legge la stringa data (testo grezzo), rileva i nomi delle persone in essa e visualizza le loro posizioni (intervalli), come mostrato di seguito.

[0..1) person 
[2..3) person

Nomi insieme alle loro posizioni

Il substring() metodo della classe String accetta il begin e il end offsetse restituisce la rispettiva stringa. Possiamo usare questo metodo per stampare i nomi e le loro estensioni (posizioni) insieme, come mostrato nel seguente blocco di codice.

for(Span s: nameSpans)        
   System.out.println(s.toString()+"  "+tokens[s.getStart()]);

Di seguito è riportato il programma per rilevare i nomi dal testo grezzo fornito e visualizzarli insieme alle loro posizioni. Salva questo programma in un file con il nomeNameFinderSentences.java.

import java.io.FileInputStream; 
import java.io.InputStream;  

import opennlp.tools.namefind.NameFinderME; 
import opennlp.tools.namefind.TokenNameFinderModel; 
import opennlp.tools.tokenize.TokenizerME; 
import opennlp.tools.tokenize.TokenizerModel; 
import opennlp.tools.util.Span;  

public class NameFinderSentences {  
   public static void main(String args[]) throws Exception{        
      
      //Loading the tokenizer model 
      InputStream inputStreamTokenizer = new 
         FileInputStream("C:/OpenNLP_models/entoken.bin");
      TokenizerModel tokenModel = new TokenizerModel(inputStreamTokenizer); 
       
      //Instantiating the TokenizerME class 
      TokenizerME tokenizer = new TokenizerME(tokenModel); 
       
      //Tokenizing the sentence in to a string array 
      String sentence = "Mike is senior programming 
      manager and Rama is a clerk both are working at 
      Tutorialspoint"; 
      String tokens[] = tokenizer.tokenize(sentence); 
       
      //Loading the NER-person model 
      InputStream inputStreamNameFinder = new 
         FileInputStream("C:/OpenNLP_models/enner-person.bin");       
      TokenNameFinderModel model = new TokenNameFinderModel(inputStreamNameFinder);
      
      //Instantiating the NameFinderME class 
      NameFinderME nameFinder = new NameFinderME(model);       
      
      //Finding the names in the sentence 
      Span nameSpans[] = nameFinder.find(tokens);        
      
      //Printing the names and their spans in a sentence 
      for(Span s: nameSpans)        
         System.out.println(s.toString()+"  "+tokens[s.getStart()]);      
   }    
}

Compilare ed eseguire il file Java salvato dal prompt dei comandi utilizzando i seguenti comandi:

javac NameFinderSentences.java 
java NameFinderSentences

All'esecuzione, il programma precedente legge la stringa data (testo grezzo), rileva i nomi delle persone in essa contenute e visualizza le loro posizioni (intervalli) come mostrato di seguito.

[0..1) person  Mike

Trovare i nomi della posizione

Caricando vari modelli, è possibile rilevare varie entità con nome. Di seguito è riportato un programma Java che carica il fileen-ner-location.binmodel e rileva i nomi delle posizioni nella frase data. Salva questo programma in un file con il nomeLocationFinder.java.

import java.io.FileInputStream; 
import java.io.InputStream;  

import opennlp.tools.namefind.NameFinderME; 
import opennlp.tools.namefind.TokenNameFinderModel; 
import opennlp.tools.tokenize.TokenizerME; 
import opennlp.tools.tokenize.TokenizerModel; 
import opennlp.tools.util.Span;  

public class LocationFinder { 
   public static void main(String args[]) throws Exception{
 
      InputStream inputStreamTokenizer = new 
         FileInputStream("C:/OpenNLP_models/entoken.bin"); 
      TokenizerModel tokenModel = new TokenizerModel(inputStreamTokenizer); 
       
      //String paragraph = "Mike and Smith are classmates"; 
      String paragraph = "Tutorialspoint is located in Hyderabad"; 
        
      //Instantiating the TokenizerME class 
      TokenizerME tokenizer = new TokenizerME(tokenModel); 
      String tokens[] = tokenizer.tokenize(paragraph); 
       
      //Loading the NER-location moodel 
      InputStream inputStreamNameFinder = new 
         FileInputStream("C:/OpenNLP_models/en- ner-location.bin");       
      TokenNameFinderModel model = new TokenNameFinderModel(inputStreamNameFinder); 
        
      //Instantiating the NameFinderME class 
      NameFinderME nameFinder = new NameFinderME(model);      
        
      //Finding the names of a location 
      Span nameSpans[] = nameFinder.find(tokens);        
      //Printing the spans of the locations in the sentence 
      for(Span s: nameSpans)        
         System.out.println(s.toString()+"  "+tokens[s.getStart()]); 
   }    
}

Compilare ed eseguire il file Java salvato dal prompt dei comandi utilizzando i seguenti comandi:

javac LocationFinder.java 
java LocationFinder

All'esecuzione, il programma di cui sopra legge la stringa data (testo grezzo), rileva i nomi delle persone in essa e visualizza le loro posizioni (intervalli), come mostrato di seguito.

[4..5) location  Hyderabad

Probabilità di NameFinder

Il probs()metodo del NameFinderME class viene utilizzata per ottenere le probabilità dell'ultima sequenza decodificata.

double[] probs = nameFinder.probs();

Di seguito è riportato il programma per stampare le probabilità. Salva questo programma in un file con il nomeTokenizerMEProbs.java.

import java.io.FileInputStream; 
import java.io.InputStream; 
import opennlp.tools.tokenize.TokenizerME; 
import opennlp.tools.tokenize.TokenizerModel; 
import opennlp.tools.util.Span; 
public class TokenizerMEProbs { 
   public static void main(String args[]) throws Exception{     
      String sent = "Hello John how are you welcome to Tutorialspoint"; 
       
      //Loading the Tokenizer model 
      InputStream inputStream = new 
         FileInputStream("C:/OpenNLP_models/en-token.bin"); 
      TokenizerModel tokenModel = new TokenizerModel(inputStream); 
       
      //Instantiating the TokenizerME class 
      TokenizerME tokenizer = new TokenizerME(tokenModel); 
       
      //Retrieving the positions of the tokens 
      Span tokens[] = tokenizer.tokenizePos(sent); 
       
      //Getting the probabilities of the recent calls to tokenizePos() method 
      double[] probs = tokenizer.getTokenProbabilities(); 
       
      //Printing the spans of tokens 
      for( Span token : tokens) 
         System.out.println(token +" 
            "+sent.substring(token.getStart(), token.getEnd()));      
         System.out.println("  "); 
      for(int i = 0; i<probs.length; i++) 
         System.out.println(probs[i]);          
   } 
}

Compilare ed eseguire il file Java salvato dal prompt dei comandi utilizzando i seguenti comandi:

javac TokenizerMEProbs.java 
java TokenizerMEProbs

Durante l'esecuzione, il programma precedente legge la stringa data, tokenizza le frasi e le stampa. Inoltre, restituisce anche le probabilità dell'ultima sequenza decodificata, come mostrato di seguito.

[0..5) Hello 
[6..10) John 
[11..14) how 
[15..18) are 
[19..22) you 
[23..30) welcome 
[31..33) to 
[34..48) Tutorialspoint 
   
1.0 
1.0 
1.0 
1.0 
1.0 
1.0 
1.0 
1.0