Как эффективно считать биграммы на нескольких документах в Python - PullRequest
0 голосов
/ 02 июня 2018

У меня есть набор текстовых документов, и я хочу посчитать количество биграмм по всем текстовым документам.

Сначала я создаю список, в котором каждый элемент снова является списком, представляющим слова в одном конкретном документе:

print(doc_clean)
# [['This', 'is', 'the', 'first', 'doc'], ['And', 'this', 'is', 'the', 'second'], ..]

Затем я извлекаю биграммы в документе и сохраняю их вlist:

bigrams = []
for doc in doc_clean:
    bigrams.extend([(doc[i-1], doc[i]) 
                   for i in range(1, len(doc))])
print(bigrams)
# [('This', 'is'), ('is', 'the'), ..]

Теперь я хочу посчитать частоту каждого уникального биграмма:

bigrams_freq = [(b, bigrams.count(b)) 
                for b in set(bigrams)]

Обычно этот подход работает, но он слишком медленный.Список биграмм довольно большой, всего ~ 5 миллионов записей и ~ 300 000 уникальных биграмм.На моем ноутбуке текущий подход требует слишком много времени для анализа.

Спасибо за помощь!

1 Ответ

0 голосов
/ 02 июня 2018

Вы можете попробовать следующее:

from collections import Counter
from nltk import word_tokenize 
from nltk.util import ngrams
from nltk.stem import WordNetLemmatizer
from nltk.corpus import stopwords

stop_words = set(stopwords.words('english'))

doc_1 = 'Convolutional Neural Networks are very similar to ordinary Neural Networks from the previous chapter'
doc_2 = 'Convolutional Neural Networks take advantage of the fact that the input consists of images and they constrain the architecture in a more sensible way.'
doc_3 = 'In particular, unlike a regular Neural Network, the layers of a ConvNet have neurons arranged in 3 dimensions: width, height, depth.'
docs = [doc_1, doc_2, doc_3]
docs = (' '.join(filter(None, docs))).lower()

tokens = word_tokenize(docs)
tokens = [t for t in tokens if t not in stop_words]
word_l = WordNetLemmatizer()
tokens = [word_l.lemmatize(t) for t in tokens if t.isalpha()]

bi_grams = list(ngrams(tokens, 2)) 
counter = Counter(bi_grams)
counter.most_common(5)

Out[82]: 
[(('neural', 'network'), 4),
 (('convolutional', 'neural'), 2),
 (('network', 'similar'), 1),
 (('similar', 'ordinary'), 1),
 (('ordinary', 'neural'), 1)]
...