LingPipe POS标记符内存不足

时间:2015-01-02 19:43:43

标签: java memory nlp pos-tagger lingpipe

我无法使用LingPipe POS tagger来计算大型(~180MB)电子邮件语料库中最常用的词性。具体来说,它消耗了大量的内存(至少4GB),这样无论我给JVM多少内存,它都会失败并出现OutOfMemoryError。在我放弃并尝试使用不同的标记库之前,我想我会问这里是否有人熟悉LingPipe以了解我做错了什么。

我首先从文件pos-en-general-brown.HiddenMarkovModel中读取一个HiddenMarkovModel对象,该文件包含在LingPipe库中,该文件是样板Java序列化代码。然后我尝试使用它:

HmmDecoder decoder = new HmmDecoder(hmm, new FastCache<String, double[]>(1000),
    new FastCache<String, double[]>(1000));

List<Email> emails = FileUtil.loadMLPosts(new File(args[1])); 
Multiset<String> rHelpTagCounts = countTagsInEmails(decoder, emails);

countTagsInEmails的定义如下:

static TokenizerFactory TOKENIZER_FACTORY = IndoEuropeanTokenizerFactory.INSTANCE;

public static Multiset<String> countTagsInEmails(HmmDecoder decoder, List<Email> emails) {
    Multiset<String> tagCounts = HashMultiset.create();        
    for(Email email : emails) {
        char[] bodyChars = email.body.toCharArray();
        Tokenizer tokenizer = TOKENIZER_FACTORY.tokenizer(bodyChars, 0, bodyChars.length);
        List<String> bodyTokens = new ArrayList<>();
        tokenizer.tokenize(bodyTokens, new ArrayList<String>()); //Throw away the whitespaces list, we don't care
        Tagging<String> taggedTokens = decoder.tag(bodyTokens);
        tagCounts.addAll(taggedTokens.tags());
    }
    return tagCounts;
}

我不认为FileUtil.loadMLPosts()的细节是重要的;这只是从我的180MB电子邮件存档文件中创建Email个对象的列表,其中每个body的{​​{1}}字段是包含电子邮件正文的字符串。请注意,Email是Guava的实现。

如果我在运行我的程序时观察Java的内存使用情况,它的启动速度为1GB(已经非常高),然后稳定地爬上标记的电子邮件越多。在几个点上,它一下子跳跃了几百兆。在它完成标记语料库之前,它达到4GB(我给JVM的内存量)并崩溃。

LingPipe的HmmDecoder应该是这种内存效率低的吗?或者我使用它错了?我注意到在LingPipe(相当稀疏)的POS标记文档页面上给出的示例总是显示解码器一次标记一个句子,所以将整个电子邮件正文传递给Multiset是错误的吗?

0 个答案:

没有答案