Part-of-Speech (POS) Tagging with OpenNLP 1.5.0

Continuing from where I left off, I’m going to quickly touch on part-of-speech tagging before moving on. It’s actually pretty straightforward once you’re set up to run OpenNLP. This all assumes that you’ve already done sentence detection and tokenization. If you haven’t, go back to the beginning. Here are the links to the rest of my posts:

Getting Started

model files

Only one additional model file is needed for part-of-speech tagging.

  • en-pos-maxent.bin

As with all of the model files, it can be found at and are identified by language and component. I’m using the Maxent model (maximum entropy) instead of the Perceptron model because, frankly, I’m not familiar with what the Perceptron model is. If you care, you can read about OpenNLP Maxent here.

I use maven, so these files go into src/main/resources and are loaded with getResourceAsStream, as you’ll see below.

Part-of-Speech Tagging

The description from the OpenNLP SourceForge wiki:

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 can have multiple pos tags depending on the token and the context. The OpenNLP POS Tagger uses a probability model to guess 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.

Code time:

Tokenizer _tokenizer = null;

InputStream modelIn = null;
try {
   // Loading tokenizer model
   modelIn = getClass().getResourceAsStream("/en-pos-maxent.bin");
   final POSModel posModel = new POSModel(modelIn);

   _posTagger = new POSTaggerME(posModel);

} catch (final IOException ioe) {
} finally {
   if (modelIn != null) {
      try {
      } catch (final IOException e) {} // oh well!

And then to use it:


Although the tokenizer only returns an array of string tokens, the tag method is overloaded to accept a list of strings, an array of strings, or a single string.


Here are the expected results for an example taken from the above wiki page (and corrected).


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

Part-of-Speech Tags:

  1. [NNP] [NNP] [,] [CD] [NNS] [JJ] [,] [MD] [VB] [DT] [NN] [IN] [DT] [JJ] [NN] [NNP] [CD] [.]
  2. [NNP] [NNP] [VBZ] [NN] [IN] [NNP] [NNP] [,] [DT] [JJ] [NN] [NN] [.]
Update: These are Penn English Treebank POS tags

Next Step: How to use the OpenNLP 1.5.0 Parser

My source code and test cases can be found at


  1. Your posts are awesome. I am working a project where I need to use a NLP library, your posts made my life easier.
    thanks man

  2. Can you post a legend what the pos tags stand for? At the moment I’m working on a project where I use this and I dont know at the moment how much tags there are and what e.g. “JJ”, “IN” and the rest of them means. This would be very helpful.

    Also thanks a lot for your tutorials :-)!

  3. Thanks a lot for your tutorial, discovering openNLP is easier thanks to you

  4. I’m new in openNLP and I’m trying to use your code just to test the POS Tagger and I have tried your code exactly but the following statement keep coming up. Can you help me on this? your help will be greatly appreciated, thank you.

    Exception in thread “AWT-EventQueue-0” java.lang.IllegalArgumentException: in must not be null!
    at wordprocessor2.WordnTextProcessing.jButton3ActionPerformed(
    at wordprocessor2.WordnTextProcessing.access$200(
    at wordprocessor2.WordnTextProcessing$3.actionPerformed(
    at javax.swing.AbstractButton.fireActionPerformed(
    at javax.swing.AbstractButton$Handler.actionPerformed(
    at javax.swing.DefaultButtonModel.fireActionPerformed(
    at javax.swing.DefaultButtonModel.setPressed(
    at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(
    at java.awt.Component.processMouseEvent(
    at javax.swing.JComponent.processMouseEvent(
    at java.awt.Component.processEvent(
    at java.awt.Container.processEvent(
    at java.awt.Component.dispatchEventImpl(
    at java.awt.Container.dispatchEventImpl(
    at java.awt.Component.dispatchEvent(
    at java.awt.LightweightDispatcher.retargetMouseEvent(
    at java.awt.LightweightDispatcher.processMouseEvent(
    at java.awt.LightweightDispatcher.dispatchEvent(
    at java.awt.Container.dispatchEventImpl(
    at java.awt.Window.dispatchEventImpl(
    at java.awt.Component.dispatchEvent(
    at java.awt.EventQueue.dispatchEventImpl(
    at java.awt.EventQueue.access$000(
    at java.awt.EventQueue$
    at java.awt.EventQueue$
    at Method)
    at java.awt.EventQueue$
    at java.awt.EventQueue$
    at Method)
    at java.awt.EventQueue.dispatchEvent(
    at java.awt.EventDispatchThread.pumpOneEventForFilters(
    at java.awt.EventDispatchThread.pumpEventsForFilter(
    at java.awt.EventDispatchThread.pumpEventsForHierarchy(
    at java.awt.EventDispatchThread.pumpEvents(
    at java.awt.EventDispatchThread.pumpEvents(

    • Wow, that’s a lot of exception code to paste! My guess is that your problem is with loading the model files. Make sure that you downloaded them (see the Getting Started section, above) and put them in a place that your application can load them. Loading resource files is a pretty standard thing that you should be able to find help with on Google if you’re having trouble.

  5. Hi thank you for the post. Is it possible to find the accuracy of the tagging from the program? Currently the only way I know is through the command line.


Leave a Reply

Your email address will not be published / Required fields are marked *