Comment utiliser OpenNLP avec Java?
Je veux afficher une phrase en anglais et faire un peu de traitement. Je voudrais utiliser openNLP. Je l'ai installé
Quand j'exécute la commande
I:WorkshopProgrammingnlpopennlp-tools-1.5.0-binopennlp-tools-1.5.0>java -jar opennlp-tools-1.5.0.jar POSTagger modelsen-pos-maxent.bin < Text.txt
il donne la sortie POSTagging l'entrée dans le texte.txt
Loading POS Tagger model ... done (4.009s)
My_PRP$ name_NN is_VBZ Shabab_NNP i_FW am_VBP 22_CD years_NNS old._.
Average: 66.7 sent/s
Total: 1 sent
Runtime: 0.015s
j'espère qu'il installé correctement?
MAINTENANT, Comment puis-je faire ce POStagging à partir de l'intérieur d'une application java? J'ai ajouté les openNLPtools, jwnl, maxent jar au projet mais comment puis-je invoquer le POStagging?
3 réponses
voici un (ancien) exemple de code que j'ai créé, avec du code modernisé à suivre:
package opennlp;
import opennlp.tools.cmdline.PerformanceMonitor;
import opennlp.tools.cmdline.postag.POSModelLoader;
import opennlp.tools.postag.POSModel;
import opennlp.tools.postag.POSSample;
import opennlp.tools.postag.POSTaggerME;
import opennlp.tools.tokenize.WhitespaceTokenizer;
import opennlp.tools.util.ObjectStream;
import opennlp.tools.util.PlainTextByLineStream;
import java.io.File;
import java.io.IOException;
import java.io.StringReader;
public class OpenNlpTest {
public static void main(String[] args) throws IOException {
POSModel model = new POSModelLoader().load(new File("en-pos-maxent.bin"));
PerformanceMonitor perfMon = new PerformanceMonitor(System.err, "sent");
POSTaggerME tagger = new POSTaggerME(model);
String input = "Can anyone help me dig through OpenNLP's horrible documentation?";
ObjectStream<String> lineStream =
new PlainTextByLineStream(new StringReader(input));
perfMon.start();
String line;
while ((line = lineStream.read()) != null) {
String whitespaceTokenizerLine[] = WhitespaceTokenizer.INSTANCE.tokenize(line);
String[] tags = tagger.tag(whitespaceTokenizerLine);
POSSample sample = new POSSample(whitespaceTokenizerLine, tags);
System.out.println(sample.toString());
perfMon.incrementCounter();
}
perfMon.stopAndPrintFinalResult();
}
}
La sortie est:
Loading POS Tagger model ... done (2.045s)
Can_MD anyone_NN help_VB me_PRP dig_VB through_IN OpenNLP's_NNP horrible_JJ documentation?_NN
Average: 76.9 sent/s
Total: 1 sent
Runtime: 0.013s
cela fonctionne essentiellement à partir de la classe POSTaggerTool inclus dans OpenNLP. sample.getTags()
est un String
tableau qui a les types d'étiquettes eux-mêmes.
cela nécessite un accès direct aux données de formation, ce qui est vraiment, vraiment boiteux.
un codebase mis à jour pour ceci est un peu différent (et probablement plus utile.)
tout d'Abord, un POM Maven:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.javachannel</groupId>
<artifactId>opennlp-example</artifactId>
<version>1.0-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>org.apache.opennlp</groupId>
<artifactId>opennlp-tools</artifactId>
<version>1.6.0</version>
</dependency>
<dependency>
<groupId>org.testng</groupId>
<artifactId>testng</artifactId>
<version>[6.8.21,)</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>
</project>
et voici le code, écrit comme un test, donc situé dans ./src/test/java/org/javachannel/opennlp/example
:
package org.javachannel.opennlp.example;
import opennlp.tools.cmdline.PerformanceMonitor;
import opennlp.tools.postag.POSModel;
import opennlp.tools.postag.POSSample;
import opennlp.tools.postag.POSTaggerME;
import opennlp.tools.tokenize.WhitespaceTokenizer;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.URL;
import java.nio.channels.Channels;
import java.nio.channels.ReadableByteChannel;
import java.util.stream.Stream;
public class POSTest {
private void download(String url, File destination) throws IOException {
URL website = new URL(url);
ReadableByteChannel rbc = Channels.newChannel(website.openStream());
FileOutputStream fos = new FileOutputStream(destination);
fos.getChannel().transferFrom(rbc, 0, Long.MAX_VALUE);
}
@DataProvider
Object[][] getCorpusData() {
return new Object[][][]{{{
"Can anyone help me dig through OpenNLP's horrible documentation?"
}}};
}
@Test(dataProvider = "getCorpusData")
public void showPOS(Object[] input) throws IOException {
File modelFile = new File("en-pos-maxent.bin");
if (!modelFile.exists()) {
System.out.println("Downloading model.");
download("http://opennlp.sourceforge.net/models-1.5/en-pos-maxent.bin", modelFile);
}
POSModel model = new POSModel(modelFile);
PerformanceMonitor perfMon = new PerformanceMonitor(System.err, "sent");
POSTaggerME tagger = new POSTaggerME(model);
perfMon.start();
Stream.of(input).map(line -> {
String whitespaceTokenizerLine[] = WhitespaceTokenizer.INSTANCE.tokenize(line.toString());
String[] tags = tagger.tag(whitespaceTokenizerLine);
POSSample sample = new POSSample(whitespaceTokenizerLine, tags);
perfMon.incrementCounter();
return sample.toString();
}).forEach(System.out::println);
perfMon.stopAndPrintFinalResult();
}
}
Ce code n'est pas réellement test rien - c'est un essai à la fumée, si quoi que ce soit - mais il devrait servir de point de départ. Une autre (potentiellement) bonne chose est qu'il télécharge un modèle pour vous si vous ne l'avez pas déjà téléchargé.
L'URL http://bulba.sdsu.edu/jeanette/thesis/PennTags.html ne fonctionne plus. J'ai trouvé ce qui suit sur la 14ème diapositive à http://www.slideshare.net/gagan1667/opennlp-demo
La réponse ci-dessus fournit un moyen d'utiliser les modèles existants de OpenNLP mais si vous avez besoin de former votre propre modèle, peut-être au-dessous peut vous aider:
Voici un tutoriel détaillé avec le code complet:
https://dataturks.com/blog/opennlp-pos-tagger-training-java-example.php
selon votre domaine, vous pouvez construire un ensemble de données soit automatiquement, soit manuellement. Construire un tel ensemble de données manuellement peut être très douloureux, des outils comme POS tagger peut aider à rendre le processus beaucoup plus facile.
format des données de formation
données d'Entraînement est transmis sous forme de fichier texte où chaque ligne est un élément de données. Chaque mot dans la ligne doit être étiqueté dans un format comme "word_LABEL", le mot et le nom de l'étiquette est séparé par un underscore '_'.
anki_Brand overdrive_Brand
just_ModelName dance_ModelName 2018_ModelName
aoc_Brand 27"_ScreenSize monitor_Category
horizon_ModelName zero_ModelName dawn_ModelName
cm_Unknown 700_Unknown modem_Category
computer_Category
Train
la classe importante ici est POSModel, qui contient le modèle actuel. Nous utilisons classe POSTaggerME pour faire le bâtiment modèle. Voici le code pour construire un modèle à partir du fichier de données de formation
public POSModel train(String filepath) {
POSModel model = null;
TrainingParameters parameters = TrainingParameters.defaultParams();
parameters.put(TrainingParameters.ITERATIONS_PARAM, "100");
try {
try (InputStream dataIn = new FileInputStream(filepath)) {
ObjectStream<String> lineStream = new PlainTextByLineStream(new InputStreamFactory() {
@Override
public InputStream createInputStream() throws IOException {
return dataIn;
}
}, StandardCharsets.UTF_8);
ObjectStream<POSSample> sampleStream = new WordTagSampleStream(lineStream);
model = POSTaggerME.train("en", sampleStream, parameters, new POSTaggerFactory());
return model;
}
}
catch (Exception e) {
e.printStackTrace();
}
return null;
}
utiliser le model pour faire le tagging.
enfin, nous pouvons voir comment le model peut être utilisé pour tagger les requêtes invisibles:
public void doTagging(POSModel model, String input) {
input = input.trim();
POSTaggerME tagger = new POSTaggerME(model);
Sequence[] sequences = tagger.topKSequences(input.split(" "));
for (Sequence s : sequences) {
List<String> tags = s.getOutcomes();
System.out.println(Arrays.asList(input.split(" ")) +" =>" + tags);
}
}