如何使用OpenNLP创建自定义模型?

时间:2013-07-31 07:17:29

标签: java nlp stanford-nlp apache-tika opennlp

我正在尝试使用 OpenNLP Java API 从文档中提取实体,例如名称,技能。但它没有提取适当的名称。我正在opennlp sourceforge link

上使用模型

这是一段java代码 -

public class tikaOpenIntro {

    public static void main(String[] args) throws IOException, SAXException,
            TikaException {

        tikaOpenIntro toi = new tikaOpenIntro();
        toi.filest("");
        String cnt = toi.contentEx();
        toi.sentenceD(cnt);
        toi.tokenization(cnt);

        String names = toi.namefind(toi.Tokens);
        toi.files(names);

    }

    public String Tokens[];

    public String contentEx() throws IOException, SAXException, TikaException {
        InputStream is = new BufferedInputStream(new FileInputStream(new File(
                "/home/rahul/Downloads/rahul.pdf")));
        // URL url=new URL("http://in.linkedin.com/in/rahulkulhari");
        // InputStream is=url.openStream();
        Parser ps = new AutoDetectParser(); // for detect parser related to

        BodyContentHandler bch = new BodyContentHandler();

        ps.parse(is, bch, new Metadata(), new ParseContext());

        return bch.toString();

    }

    public void files(String st) throws IOException {
        FileWriter fw = new FileWriter("/home/rahul/Documents/extrdata.txt",
                true);
        BufferedWriter bufferWritter = new BufferedWriter(fw);
        bufferWritter.write(st + "\n");
        bufferWritter.close();
    }

    public void filest(String st) throws IOException {
        FileWriter fw = new FileWriter("/home/rahul/Documents/extrdata.txt",
                false);

        BufferedWriter bufferWritter = new BufferedWriter(fw);
        bufferWritter.write(st);
        bufferWritter.close();
    }

    public String namefind(String cnt[]) {
        InputStream is;
        TokenNameFinderModel tnf;
        NameFinderME nf;
        String sd = "";
        try {
            is = new FileInputStream(
                    "/home/rahul/opennlp/model/en-ner-person.bin");
            tnf = new TokenNameFinderModel(is);
            nf = new NameFinderME(tnf);

            Span sp[] = nf.find(cnt);

            String a[] = Span.spansToStrings(sp, cnt);
            StringBuilder fd = new StringBuilder();
            int l = a.length;

            for (int j = 0; j < l; j++) {
                fd = fd.append(a[j] + "\n");

            }
            sd = fd.toString();

        } catch (FileNotFoundException e) {

            e.printStackTrace();
        } catch (InvalidFormatException e) {

            e.printStackTrace();
        } catch (IOException e) {

            e.printStackTrace();
        }
        return sd;
    }


    public void sentenceD(String content) {
        String cnt[] = null;
        InputStream om;
        SentenceModel sm;
        SentenceDetectorME sdm;
        try {
            om = new FileInputStream("/home/rahul/opennlp/model/en-sent.bin");
            sm = new SentenceModel(om);
            sdm = new SentenceDetectorME(sm);
            cnt = sdm.sentDetect(content);

        } catch (IOException e) {
            e.printStackTrace();
        }

    }

    public void tokenization(String tokens) {

        InputStream is;
        TokenizerModel tm;

        try {
            is = new FileInputStream("/home/rahul/opennlp/model/en-token.bin");
            tm = new TokenizerModel(is);
            Tokenizer tz = new TokenizerME(tm);
            Tokens = tz.tokenize(tokens);
            // System.out.println(Tokens[1]);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

}

我想做的是:

  • 我正在使用 Apache Tika 将PDF文档转换为纯文本文档。
  • 我正在传递句子边界检测的纯文本文档。
  • 标记化
  • 之后
  • 名称实体提取
  • 之后

但它正在提取名字和其他词语。 不提取专有名称。如何创建自定义模型以从游泳,编程等文档中提取技能?

给我一些想法!

非常感谢任何帮助!

4 个答案:

答案 0 :(得分:3)

听起来你对OpenNLP的预建名称模型的性能不满意。但是(a)模型永远不会是完美的,即使是最好的模型也会错过一些应该抓住的东西,并抓住一些本应该错过的东西; (b)如果模型所训练的文件与你试图标记的文件,类型和文本风格相匹配,模型将表现最佳(因此,对混合案例文本进行训练的模型在所有方面都不会很好 - 对文本进行限制,对新闻文章进行过培训的模型在推文方面效果不佳。您可以尝试其他公开可用的工具,例如Stanford NE工具包或LingPipe;他们可能会有更好的模特。但它们都不会是完美的。

要创建自定义模型,您需要生成一些训练数据。对于OpenNLP,它看起来像

I have a Ph.D. in <START:skill> operations research <END>

对于特定的内容,您可能需要自己提供这些数据。你需要很多东西; OpenNLP文档推荐大约15,000个例句。有关更多详细信息,请参阅OpenNLP文档。

答案 1 :(得分:1)

这篇文章可能会有所帮助

OpenNLP: foreign names does not get recognized

它展示了如何使用名为“modelbuilder-addon”的非常新的OpenNLP插件生成模型

你给它一个句子文件,一个已知名字的文件,并告诉它放置模型的位置。 HTH

答案 2 :(得分:0)

您可以这样做的一种方法是保留可以出现在文档中的已知专有名称列表。这也是一种很好的技巧方法。当您识别命名实体时,您应该检查它是否出现在列表中。

另一种方法是编写自己的组件来提取比OpenNLP更好的命名实体,但它可能要困难得多。

答案 3 :(得分:0)

我听说人们在Apache UIMA上取得了很好的成功。前一天在这里讨论过这个问题:how to use Entity Recognition with Apache solr and LingPipe or similar tools

您可能想要查看的链接很少。