# Part-of-Speech Tagger

## Tagging

The Part of Speech Tagger marks tokens with their corresponding word type based on the token itself and the context of the token. A token might have multiple pos tags depending on the token and the context. The OpenNLP POS Tagger uses a probability model to predict the correct pos tag out of the tag set. To limit the possible tags for a token a tag dictionary can be used which increases the tagging and runtime performance of the tagger.

### POS Tagger Tool

The easiest way to try out the POS Tagger is the command line tool. The tool is only intended for demonstration and testing. Download the English maxent pos model and start the POS Tagger Tool with this command:

    $ opennlp POSTagger en-pos-maxent.bin

The POS Tagger now reads a tokenized sentence per line from stdin. Copy these two sentences to the console:

    Pierre Vinken , 61 years old , will join the board as a nonexecutive director Nov. 29 .
    Mr. Vinken is chairman of Elsevier N.V. , the Dutch publishing group .

The POS Tagger will now echo the sentences with pos tags to the console:

    Pierre_NNP Vinken_NNP ,_, 61_CD years_NNS old_JJ ,_, will_MD join_VB the_DT board_NN as_IN
        a_DT nonexecutive_JJ director_NN Nov._NNP 29_CD ._.
    Mr._NNP Vinken_NNP is_VBZ chairman_NN of_IN Elsevier_NNP N.V._NNP ,_, the_DT Dutch_NNP publishing_VBG group_NN

The tag set used by the English pos model is the Penn Treebank tag set.

### POS Tagger API

The POS Tagger can be embedded into an application via its API. First the pos model must be loaded into memory from disk or another source. In the sample below it is loaded from disk.

    try (InputStream modelIn = new FileInputStream("en-pos-maxent.bin"){
      POSModel model = new POSModel(modelIn);
    }

After the model is loaded the POSTaggerME can be instantiated.

    POSTaggerME tagger = new POSTaggerME(model);

The POS Tagger instance is now ready to tag data. It expects a tokenized sentence as input, which is represented as a String array, each String object in the array is one token.

The following code shows how to determine the most likely pos tag sequence for a sentence.

    String sent[] = new String[]{"Most", "large", "cities", "in", "the", "US", "had",
                                 "morning", "and", "afternoon", "newspapers", "."};
    String tags[] = tagger.tag(sent);

The tags array contains one part-of-speech tag for each token in the input array. The corresponding tag can be found at the same index as the token has in the input array. The confidence scores for the returned tags can be easily retrieved from a POSTaggerME with the following method call:

    double probs[] = tagger.probs();

The call to probs is stateful and will always return the probabilities of the last tagged sentence. The probs method should only be called when the tag method was called before, otherwise the behavior is undefined.

Some applications need to retrieve the n-best pos tag sequences and not only the best sequence. The topKSequences method is capable of returning the top sequences. It can be called in a similar way as tag.

    Sequence topSequences[] = tagger.topKSequences(sent);

Each Sequence object contains one sequence. The sequence can be retrieved via Sequence.getOutcomes() which returns a tags array and Sequence.getProbs() returns the probability array for this sequence.

## Training

The POS Tagger can be trained on annotated training material. The training material is a collection of tokenized sentences where each token has the assigned part-of-speech tag. The native POS Tagger training material looks like this:

    About_IN 10_CD Euro_NNP ,_, I_PRP reckon_VBP ._.
    That_DT sounds_VBZ good_JJ ._.

Each sentence must be in one line. The token/tag pairs are combined with "_". The token/tag pairs are whitespace separated. The data format does not define a document boundary. If a document boundary should be included in the training material it is suggested to use an empty line.

The Part-of-Speech Tagger can either be trained with a command line tool, or via an training API.

### Training Tool

OpenNLP has a command line tool which is used to train the models available from the model download page on various corpora.

Usage of the tool:

    $ opennlp POSTaggerTrainer
    Usage: opennlp POSTaggerTrainer[.conllx] [-type maxent|perceptron|perceptron_sequence] \
                   [-dict dictionaryPath] [-ngram cutoff] [-params paramsFile] [-iterations num] \
                   [-cutoff num] -model modelFile -lang language -data sampleData \
                   [-encoding charsetName]

    Arguments description:
            -type maxent|perceptron|perceptron_sequence
                    The type of the token name finder model. One of maxent|perceptron|perceptron_sequence.
            -dict dictionaryPath
                    The XML tag dictionary file
            -ngram cutoff
                    NGram cutoff. If not specified will not create ngram dictionary.
            -params paramsFile
                    training parameters file.
            -iterations num
                    number of training iterations, ignored if -params is used.
            -cutoff num
                    minimal number of times a feature must be seen, ignored if -params is used.
            -model modelFile
                    output model file.
            -lang language
                    language which is being processed.
            -data sampleData
                    data to be used, usually a file name.
            -encoding charsetName
                    encoding for reading and writing text, if absent the system default is used.

The following command illustrates how an English part-of-speech model can be trained:

    $ opennlp POSTaggerTrainer -type maxent -model en-pos-maxent.bin \
                               -lang en -data en-pos.train -encoding UTF-8

### Training API

The Part-of-Speech Tagger training API supports the training of a new pos model. Basically three steps are necessary to train it:

- The application must open a sample data stream

- Call the POSTagger.train method

- Save the POSModel to a file

The following code illustrates that:

    POSModel model = null;

    try (InputStream dataIn = new FileInputStream("en-pos.train")){
      ObjectStream<String> lineStream = new PlainTextByLineStream(dataIn, StandardCharsets.UTF_8);
      ObjectStream<POSSample> sampleStream = new WordTagSampleStream(lineStream);

      model = POSTaggerME.train("en", sampleStream, TrainingParameters.defaultParams(), null, null);
    }

The above code performs the first two steps, opening the data and training the model. The trained model must still be saved into an OutputStream, in the sample below it is written into a file.

    try (OutputStream modelOut = new BufferedOutputStream(new FileOutputStream(modelFile))){
      model.serialize(modelOut);
    }

### Tag Dictionary

The tag dictionary is a word dictionary which specifies which tags a specific token can have. Using a tag dictionary has two advantages, inappropriate tags can not been assigned to tokens in the dictionary and the beam search algorithm has to consider less possibilities and can search faster.

The dictionary is defined in an xml format and can be created and stored with the POSDictionary class. Please for now checkout the javadoc and source code of that class.

Note: The format should be documented and sample code should show how to use the dictionary. Any contributions are very welcome. If you want to contribute please contact us on the mailing list or comment on the jira issue OPENNLP-287.

## Evaluation

The built-in evaluation can measure the accuracy of the pos tagger. The accuracy can be measured on a test data set or via cross validation.

### Evaluation Tool

There is a command line tool to evaluate a given model on a test data set. The following command shows how the tool can be run:

    $ opennlp POSTaggerEvaluator -model pt.postagger.bin -data pt.postagger.test -encoding utf-8

This will display the resulting accuracy score, e.g.:

    Loading model ... done
    Evaluating ... done

    Accuracy: 0.9659110277825124

There is a command line tool for cross-validation of the test data set. The following command shows how the tool can be run:

    $ opennlp POSTaggerCrossValidator -lang pt -data pt.postagger.test -encoding utf-8

This will display the resulting accuracy score, e.g.:

    Accuracy: 0.9659110277825124