web-dev-qa-db-fra.com

Comment utiliser OpenNLP avec Java?

Je veux POSTAG 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:\Workshop\Programming\nlp\opennlp-tools-1.5.0-bin\opennlp-tools-1.5.0>Java -jar opennlp-tools-1.5.0.jar POSTagger models\en-pos-maxent.bin < Text.txt

Il donne la sortie POSTagging l'entrée dans Text.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 est correctement installé?

Maintenant, comment puis-je post-taguer depuis une application Java? J'ai ajouté l'openNLPtools, jwnl, maxent jar au projet, mais comment puis-je invoquer le POStagging?

18
shababhsiddique

Voici quelques exemples de code (anciens) que j'ai assemblés, avec le 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 incluse dans OpenNLP. sample.getTags() est un tableau String qui contient les types de balises eux-mêmes.

Cela nécessite un accès direct aux données d’entraînement, ce qui est vraiment, vraiment nul.

Une base de code mise à jour pour cela est un peu différente (et probablement plus utile).

Tout d'abord, un Maven POM:

<?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 sous forme de 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 ne contient pas test quoi que ce soit - c'est un test de fumée, mais il devrait servir de point de départ. Une autre chose (potentiellement) intéressante est qu’elle télécharge un modèle si vous ne l’avez pas déjà téléchargé.

37
Joseph Ottinger

L'URL http://bulba.sdsu.edu/jeanette/thesis/PennTags.html ne fonctionne plus. J'ai trouvé le ci-dessous sur la diapositive 14 à http://www.slideshare.net/gagan1667/opennlp-demo

enter image description here

10
Sagar Mhatre

La réponse ci-dessus fournit un moyen d'utiliser les modèles existants d'OpenNLP mais si vous devez former votre propre modèle, les solutions ci-dessous peuvent peut-être 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 créer un jeu de données automatiquement ou manuellement. Construire manuellement un tel jeu de données peut être très pénible, des outils tels que POS Tagger peuvent aider à rendre le processus beaucoup plus facile.

Format de données de formation

Les données d'apprentissage sont transmises sous forme de fichier texte dans lequel chaque ligne correspond à un élément de données. Chaque mot de la ligne doit être libellé dans un format du type "Word_LABEL", le mot et le nom du libellé étant séparés par un trait de soulignement "_".

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

Modèle de train

La classe importante ici est POSModel, qui contient le modèle actuel. Nous utilisons la classe POSTaggerME pour construire le modèle. Vous trouverez ci-dessous le code permettant de créer un modèle à partir d'un fichier de données d'apprentissage.

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;

}

Utilise le modèle pour effectuer le marquage.

Enfin, nous pouvons voir comment le modèle peut être utilisé pour baliser des 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);
    }
}
1
user439521