Я пытаюсь ускорить свое приложение, и я обнаружил, что простая небольшая функция ниже (compute_ave_freq) на самом деле является одним из самых больших часовых свиней. Преступник, похоже, когда он рассыпает NLTK FreqDist; это требует непристойного количества времени.Более быстрый способ хранения NLTK FreqDict?
Конечно, даже это непристойное количество времени меньше половины того, что потребуется для вычисления FreqDist заново. Есть ли лучший способ сохранить объект NLTK FreqDist? Я попробовал сериализовать его как JSON, но это сохраняет его как простой словарь, теряя много функциональности NLTK, которые мне нужны.
Вот код:
def compute_ave_freq(word_forms):
fd = pickle.load(open("data/fd.txt", 'rb'))
total_freq = 0
for form in word_forms:
freq = fd.freq(form)
total_freq += freq
try:
ave_freq = total_freq/len(word_forms)
except ZeroDivisionError:
ave_freq = 0
return ave_freq
А вот выход LineProfiler:
Total time: 0.197121 s
File: /home/username/development/appname/filename.py
Function: compute_ave_freq at line 25
Line # Hits Time Per Hit % Time Line Contents
==============================================================
25 def compute_ave_freq(word_forms, debug=False):
26 # word_forms is a list of morphological variations of a word, such as
27 # ['كتبوا', 'كتبو', 'كتبنا', 'كتبت']
28
29 1 78580 78580.0 79.1 fd = pickle.load(open("data/fd.txt", 'rb'))
30 1 3 3.0 0.0 total_freq = 0
31 5 10 2.0 0.0 for form in word_forms:
32 4 20676 5169.0 20.8 freq = fd.freq(form)
33 4 9 2.2 0.0 if debug==True:
34 print(form, '\n', freq)
35 4 6 1.5 0.0 total_freq += freq
36 1 1 1.0 0.0 try:
37 1 3 3.0 0.0 ave_freq = total_freq/len(word_forms)
38 except ZeroDivisionError:
39 ave_freq = 0
40 1 1 1.0 0.0 return ave_freq
Спасибо!
Unpickling загружается в оперативную память, и это довольно трудно проблемой справиться, но как только он загружен, это хорошо. Возможно, включение его в некоторые БД (например, SQL/Mongo) было бы лучшим способом работы с большими наборами данных. В противном случае просто подождите некоторое время, чтобы загрузить его в ОЗУ. – alvas
Я думаю, что общее правило может заключаться в том, что «Если у вас есть набор данных, который можно полностью загрузить в ОЗУ без особого напряжения, то на самом деле это не так уж и важно, и время, затраченное на индексирование/запрос БД, может быть не существенным». – alvas
Переместить 'fd = pickle.load (open (" data/fd.txt ", 'rb'))' вне функции и просто передать ее функции, если 'fd' изменяется, то есть' def compute_ave_freq (word_forms, fd) : '. В противном случае, если 'fd' не изменяется, просто сделайте' fd' глобальную переменную и загрузите ее один раз. – alvas