aman arora
aman arora

Reputation: 273

How to use OpenNLP parser models in an Android app?

I go through this link for java nlp https://www.tutorialspoint.com/opennlp/index.htm

I tried below code in android:

try {
   File file = copyAssets();
   // InputStream inputStream = new FileInputStream(file);
   ParserModel model = new ParserModel(file);
   // Creating a parser
   Parser parser = ParserFactory.create(model);
   // Parsing the sentence
   String sentence = "Tutorialspoint is the largest tutorial library.";
   Parse topParses[] = ParserTool.parseLine(sentence, parser,1);
   for (Parse p : topParses) {
       p.show();
   }
} catch (Exception e) {
} 

i download file **en-parser-chunking.bin** from internet and placed in assets of android project but code stop on third line i.e ParserModel model = new ParserModel(file); without giving any exception. Need to know how can this work in android? if its not working is there any other support for nlp in android without consuming any services?

Upvotes: 0

Views: 1408

Answers (1)

MWiesner
MWiesner

Reputation: 9043

The reason the code stalls/breaks at runtime is that you need to use an InputStream instead of a File to load the binary file resource. Most likely, the File instance is null when you "load" it the way as indicated in line 2. In theory, this constructor of ParserModelshould detect this and an IOException should be thrown. Yet, sadly, the JavaDoc of OpenNLP is not precise about this kind of situation and you are not handling this exception properly in the catch block.

Moreover, the code snippet you presented should be improved, so that you know what actually went wrong.

Therefore, loading a POSModel from within an Activity should be done differently. Here is a variant that takes care for both aspects:

AssetManager assetManager = getAssets();
InputStream in = null;

try {
    in = assetManager.open("en-parser-chunking.bin");
    POSModel posModel;
    if(in != null) {
        posModel = new POSModel(in);
        if(posModel!=null) {
            // From here, <posModel> is initialized and you can start playing with it...
            // Creating a parser
            Parser parser = ParserFactory.create(model);
            // Parsing the sentence
            String sentence = "Tutorialspoint is the largest tutorial library.";
            Parse topParses[] = ParserTool.parseLine(sentence, parser,1);
            for (Parse p : topParses) {
                p.show();
            }
        }
        else {
            // resource file not found - whatever you want to do in this case
            Log.w("NLP", "ParserModel could not initialized.");
        }
    }
    else {
        // resource file not found - whatever you want to do in this case
        Log.w("NLP", "OpenNLP binary model file could not found in assets.");
    }
}
catch (Exception ex) {
    Log.e("NLP", "message: " + ex.getMessage(), ex);
    // proper exception handling here... 
} 
finally {
    if(in!=null) {
         in.close();
    }
}

This way, you're using an InputStream approach and at the same time you take care for proper exception and resource handling. Moreover, you can now use a Debugger in case something remains unclear with the resource path references of your model files. For reference, see the official JavaDoc of AssetManager#open(String resourceName).

Note well:

Loading OpenNLP's binary resources can consume quite a lot of memory. For this reason, it might be the case that your Android App's request to allocate the needed memory for this operation can or will not be granted by the actual runtime (i.e., smartphone) environment. Therefore, carefully monitor the amount of requested/required RAM while posModel = new POSModel(in); is invoked.

Hope it helps.

Upvotes: 1

Related Questions