В рамках своей работы я работаю с очень большими текстовыми файлами и, частично, анализирую их на предмет частотности слов и фраз. Я сталкиваюсь с трудностями, связанными со временем вычислений, ограничениями памяти и извлечением релевантной информации.
Для этой программы я беру большой текстовый файл (скажем, 50 МБ), который уже очищен, переведен в нижний регистр. Но в остальном это просто неструктурированный текст. Я пытаюсь составить списки "биграмм", "триграмм", "квадрограмм" и "пятиграмм" - соответственно, комбинаций повторяющихся фраз из двух, трех, четырех и пяти слов (например, "я" - биграмма, "я свободен" - триграмма, "я свободен всегда" - квадрограмма).
Что я делаю в настоящее время?
Вот мой текущий код, где inputlower
- это строка со всеми строчными буквами (выскобленные веб-данные с помощью Mathematica).
inputlower=Import["/directory/allTextLowered.txt"];
bigrams =
Sort[Tally[Partition[inputlower, 2, 1]], #1[[2]] > #2[[2]] &];
Export["/directory/bigrams.txt", bigrams];
Clear[bigrams];
trigrams =
Sort[Tally[Partition[inputlower, 3, 1]], #1[[2]] > #2[[2]] &];
Export["/directory/trigrams.txt", trigrams];
Clear[trigrams];
quadgrams =
Sort[Tally[Partition[inputlower, 4, 1]], #1[[2]] > #2[[2]] &];
Export["/directory/quadrams.txt", quadgrams];
Clear[quadgrams];
fivegrams =
Sort[Tally[Partition[inputlower, 5, 1]], #1[[2]] > #2[[2]] &];
Export["/directory/fivegrams.txt", fivegrams];
В некотором смысле, это работает хорошо: Я действительно получаю сгенерированную информацию, и на небольших масштабах я обнаружил, что этот код работает достаточно быстро, чтобы я мог иметь что-то приближенное к работоспособной программе Manipulate[]
. Но когда мы имеем дело с большими входными данными...
Что не так, когда я использую большие файлы?
Самое главное, мои выходные файлы слишком велики, чтобы их можно было использовать. Есть ли способ указать точку разрыва в коде: например, я не хочу никаких "биграмм", которые появляются только один раз? Если окажется, что это все равно оставляет слишком много информации, можно ли указать, что я не хочу, чтобы в файле были биграммы, если они появляются не более 10 раз? Например, если "мой сыр" появляется 20 раз, я хочу знать об этом, но если "i pad" появляется только один раз, возможно, потеря этого слова сделает файл более управляемым?
Во-вторых, эти процессы занимают много времени: только на генерацию биграмм ушло более двух или трех часов. Эффективно ли я подхожу к решению этой проблемы?
В-третьих, если бы у меня был большой файл биграмм (~650MB+), содержащий всю информацию, есть ли способ для системы Mathematica получить доступ к информации, не загружая ее всю в память - т.е. взять файл bigrams.txt, узнать, что он содержит {{"i", "am"},55}
, не перегружая систему?
Редактировать
.[По состоянию на 7 дек 11, я удалил файл примера, который я выложил - спасибо всем еще раз]