POS-тегу LingPipe не хватает памяти

У меня возникают проблемы при использовании POS-тега LingPipe для подсчета наиболее часто используемых частей речи в большом (~180 МБ) корпусе электронных писем. В частности, он потребляет огромные объемы памяти (по крайней мере, 4 ГБ), так что независимо от того, сколько памяти я даю JVM, он выходит из строя с OutOfMemoryError. Перед тем, как сдаться и попробовать другую библиотеку тегов, я подумал, что мне стоит спросить, достаточно ли кто-нибудь здесь знаком с LingPipe, чтобы понять, что я делаю неправильно.

Я начну с чтения объекта HiddenMarkovModel из файла pos-en-general-brown.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() важные; это просто создает список Email объекты из моего файла архива электронной почты 180 МБ, где body поле каждого Email является строкой, содержащей тело письма Обратите внимание, что Multiset это реализация Гуавы.

Если я наблюдаю за использованием памяти Java во время работы моей программы, она начинается с 1 ГБ (уже удивительно высокой), а затем неуклонно поднимается, все больше писем помечается. В нескольких точках он резко скачет, на несколько сотен мегабайт одновременно. Прежде чем он может закончить помечать корпус, он достигает 4 ГБ (объем памяти, который я дал моей JVM) и вылетает.

Должен ли HmmDecoder от LingPipe быть неэффективным с точки зрения памяти? Или я использую это неправильно? Я заметил, что пример, приведенный на (довольно редкой) странице документации LingPipe для пометки POS, всегда показывает, как декодер помечает одно предложение за раз, поэтому является ошибкой передавать весь текст письма в decoder.tag()?

0 ответов

Другие вопросы по тегам