моделирование n-грамм с помощью хэш-карты Java

Мне нужно смоделировать набор n-грамм (последовательности n слов) и их контексты (слова, которые появляются рядом с n-граммой вместе с их частотой). Моя идея заключалась в следующем:

public class Ngram {

    private String[] words;
    private HashMap<String, Integer> contextCount = new HashMap<String, Integer>();
}

Затем для подсчета всех различных n-грамм я использую другой Hashmap, например

HashMap<String, Ngram> ngrams = new HashMap<String, Ngram>();

и я добавляю к нему при получении текста. Проблема в том, что когда количество n-грамм превышает 10 000 или около того, куча JVM заполняется (максимум 1,5 ГБ), и все очень сильно замедляется.

Есть ли лучший способ сделать это, чтобы избежать такого потребления памяти? Кроме того, контексты должны быть легко сопоставимы между n-граммами, что, я не уверен, возможно с моим решением.


person Nikola    schedule 05.05.2011    source источник
comment
Какой размер мы смотрим на них? Примерно сколько слов на n-грамм? Кроме того, используется ли вспомогательная память, например большая временная память? Не забывайте, что хэш-карта может занимать много памяти при изменении размера!   -  person corsiKa    schedule 05.05.2011
comment
Что именно вы хотите сделать с этими n-граммами? Вы смотрели на lucene с помощью n-gram-tokenfilter? Возможно, вы можете использовать индекс Lucene для выполнения задач, которые вам нужно выполнить. Затем вы можете либо сохранить его в своей памяти, либо сохранить в файловой системе.   -  person csupnig    schedule 05.05.2011
comment
У меня около 50 000 новостных статей, из которых я собираю энграмы. После обработки 6000 статей средний размер Hashmap контекста в Ngram составляет около 13. У меня нет никакой вспомогательной памяти, по крайней мере, я так не думаю :)   -  person Nikola    schedule 05.05.2011
comment
Я пытаюсь найти семантически похожие n-граммы, сравнивая их векторы контекста. Я немного изучил lucene, но кажется, что их определение n-грамм основано на символах, а не на словах, как у меня.   -  person Nikola    schedule 05.05.2011
comment
Если значение contextCount карты обычно невелико, а количество различных контекстов также невелико и фиксировано, рассмотрите возможность изменения контекстов на Enum и использование EnumMap. И String, и HashMap имеют много накладных расходов для небольших данных, на которые может уйти ваша память.   -  person Michał Kosmulski    schedule 25.02.2012


Ответы (2)


Вы можете использовать HADOOP MapReducer для огромной базы данных (обычно для больших данных). используйте Mapper, чтобы разделить входные данные на Ngrams, а также объединитель и mapper, чтобы делать с этими Ngrams все, что вы хотите.

HADOOP uses <Key,value> as like you wish to process with Hashmap.

Я думаю, это что-то вроде классификации. так что вполне подходит. Но для этого нужен кластер.

если возможно, лучше начать с Полного руководства по Hadoop (публикации Orielly).

person Dineshkumar    schedule 10.05.2013

Возможно, вы уже нашли решение своей проблемы, но в этой статье есть очень хороший подход к крупномасштабным языковым моделям:

Сглаженные языковые модели фильтров Блума: терамасштабные LM по дешевке

http://acl.ldc.upenn.edu/D/D07/D07-1049.pdf

person Elmer    schedule 10.05.2013
comment
Ссылка на документ мертва, вот зеркало: learningace.com/doc/1789441 /13c59f831d31425f78311337bd7cb4fa/ - person Crashthatch; 23.05.2014