OpenNLP - Reconhecimento de Entidade Nomeada

O processo de localização de nomes, pessoas, lugares e outras entidades a partir de um determinado texto é conhecido como Named Entity Recognição (NER). Neste capítulo, discutiremos como realizar NER por meio do programa Java usando a biblioteca OpenNLP.

Reconhecimento de entidade nomeada usando PNL aberto

Para realizar várias tarefas NER, o OpenNLP usa diferentes modelos predefinidos, a saber, en-nerdate.bn, en-ner-location.bin, en-ner-organization.bin, en-ner-person.bin e en-ner-time. bin. Todos esses arquivos são modelos predefinidos que são treinados para detectar as respectivas entidades em um determinado texto bruto.

o opennlp.tools.namefindpacote contém as classes e interfaces que são usadas para executar a tarefa NER. Para executar a tarefa NER usando a biblioteca OpenNLP, você precisa -

  • Carregue o respectivo modelo usando o TokenNameFinderModel classe.

  • Instancie o NameFinder classe.

  • Encontre os nomes e imprima-os.

A seguir estão os passos a serem seguidos para escrever um programa que detecta as entidades de nome de um determinado texto bruto.

Etapa 1: Carregando o modelo

O modelo para detecção de frases é representado pela classe chamada TokenNameFinderModel, que pertence ao pacote opennlp.tools.namefind.

Para carregar um modelo NER -

  • Criar um InputStream objeto do modelo (instancie o FileInputStream e passe o caminho do modelo NER apropriado no formato String para seu construtor).

  • Instancie o TokenNameFinderModel classe e passar no InputStream (objeto) do modelo como um parâmetro para seu construtor, conforme mostrado no bloco de código a seguir.

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

Etapa 2: instanciando a classe NameFinderME

o NameFinderME classe do pacote opennlp.tools.namefindcontém métodos para executar as tarefas NER. Esta classe usa o modelo de Entropia Máxima para encontrar as entidades nomeadas no texto bruto fornecido.

Instancie esta classe e passe o objeto modelo criado na etapa anterior, conforme mostrado abaixo -

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

Etapa 3: Encontrar os nomes na frase

o find() método do NameFinderMEclasse é usada para detectar os nomes no texto bruto passado a ela. Este método aceita uma variável String como parâmetro.

Chame este método passando o formato String da frase para este método.

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

Etapa 4: imprimir as extensões dos nomes na frase

o find() método do NameFinderMEclass retorna uma matriz de objetos do tipo Span. A classe chamada Span of theopennlp.tools.util pacote é usado para armazenar o start e end número inteiro de conjuntos.

Você pode armazenar os vãos retornados pelo find() na matriz Span e imprima-os, conforme mostrado no bloco de código a seguir.

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

NER Example

A seguir está o programa que lê a frase dada e reconhece a extensão dos nomes das pessoas nela. Salve este programa em um arquivo com o 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());    
   }    
}

Compile e execute o arquivo Java salvo no prompt de comando usando os seguintes comandos -

javac NameFinderME_Example.java 
java NameFinderME_Example

Ao ser executado, o programa acima lê a String fornecida (texto bruto), detecta os nomes das pessoas nela e exibe suas posições (spans), conforme mostrado abaixo.

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

Nomes junto com suas posições

o substring() método da classe String aceita o begin e a end offsetse retorna a respectiva string. Podemos usar esse método para imprimir os nomes e seus intervalos (posições) juntos, conforme mostrado no bloco de código a seguir.

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

A seguir está o programa para detectar os nomes do texto bruto fornecido e exibi-los junto com suas posições. Salve este programa em um arquivo com o 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()]);      
   }    
}

Compile e execute o arquivo Java salvo no prompt de comando usando os seguintes comandos -

javac NameFinderSentences.java 
java NameFinderSentences

Ao ser executado, o programa acima lê a String fornecida (texto bruto), detecta os nomes das pessoas nela e exibe suas posições (spans) conforme mostrado abaixo.

[0..1) person  Mike

Encontrar os nomes do local

Ao carregar vários modelos, você pode detectar várias entidades nomeadas. A seguir está um programa Java que carrega oen-ner-location.binmodelo e detecta os nomes dos locais na frase dada. Salve este programa em um arquivo com o 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()]); 
   }    
}

Compile e execute o arquivo Java salvo no prompt de comando usando os seguintes comandos -

javac LocationFinder.java 
java LocationFinder

Ao ser executado, o programa acima lê a String fornecida (texto bruto), detecta os nomes das pessoas nela e exibe suas posições (spans), conforme mostrado abaixo.

[4..5) location  Hyderabad

Probabilidade de NameFinder

o probs()método do NameFinderME classe é usada para obter as probabilidades da última sequência decodificada.

double[] probs = nameFinder.probs();

A seguir está o programa para imprimir as probabilidades. Salve este programa em um arquivo com o 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]);          
   } 
}

Compile e execute o arquivo Java salvo no prompt de comando usando os seguintes comandos -

javac TokenizerMEProbs.java 
java TokenizerMEProbs

Ao ser executado, o programa acima lê a String fornecida, transforma as frases em token e as imprime. Além disso, também retorna as probabilidades da última sequência decodificada, conforme mostrado a seguir.

[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