Python Gensim LDAMallet CalledProcessError с большим корпусом (отлично работает с небольшим корпусом)

1

Я получаю ошибку CalledProcessError "ненулевое состояние выхода 1", когда я запускаю модель Gensim LDAMallet на моем полном корпусе из ~ 16 миллионов документов. Интересно, что если я выполняю точно такой же код в тестовом корпусе из ~ 160 000 документов, код работает отлично. Поскольку он отлично работает на моем маленьком корпусе, я склонен думать, что код в порядке, но я не уверен, что еще может/может вызвать эту ошибку...

Я попытался отредактировать файл mallet.bat, как предложено здесь, но безрезультатно. Я также дважды проверил пути, но это не должно быть проблемой, учитывая, что он работает с меньшим корпусом.

id2word = corpora.Dictionary(lists_of_words)
corpus =[id2word.doc2bow(doc) for doc in lists_of_words]
num_topics = 30
os.environ.update({'MALLET_HOME':r'C:/mallet-2.0.8/'})
mallet_path = r'C:/mallet-2.0.8/bin/mallet'
ldamallet = gensim.models.wrappers.LdaMallet(mallet_path, corpus=corpus, num_topics=num_topics, id2word=id2word)

Здесь полная трассировка и ошибка:

  File "<ipython-input-57-f0e794e174a6>", line 8, in <module>
    ldamallet = gensim.models.wrappers.LdaMallet(mallet_path, corpus=corpus, num_topics=num_topics, id2word=id2word)

  File "C:\ProgramData\Anaconda3\lib\site-packages\gensim\models\wrappers\ldamallet.py", line 132, in __init__
    self.train(corpus)

  File "C:\ProgramData\Anaconda3\lib\site-packages\gensim\models\wrappers\ldamallet.py", line 273, in train
    self.convert_input(corpus, infer=False)

  File "C:\ProgramData\Anaconda3\lib\site-packages\gensim\models\wrappers\ldamallet.py", line 262, in convert_input
    check_output(args=cmd, shell=True)

  File "C:\ProgramData\Anaconda3\lib\site-packages\gensim\utils.py", line 1918, in check_output
    raise error

CalledProcessError: Command 'C:/mallet-2.0.8/bin/mallet import-file --preserve-case --keep-sequence --remove-stopwords --token-regex "\S+" --input C:\Users\user\AppData\Local\Temp\2\e1ba4a_corpus.txt --output C:\Users\user\AppData\Local\Temp\2\e1ba4a_corpus.mallet' returned non-zero exit status 1.
Теги:
gensim
mallet
lda

1 ответ

0

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

Поскольку ваш код работает с меньшим набором данных, я сначала посмотрю на ваши данные. Маллет является привередливым в том, что он принимает только самые чистые данные, которые он, возможно, попал в нуль, пунктуацию или число с плавающей точкой.

Вы взяли размер выборки из своего словаря или передали весь набор данных?

Это в основном то, что он делает: предложение в слова - слова в числа - затем подсчитывается для частоты, как:

[(3, 1), (13, 1), (37, 1)]

Слово 3 ("помощь") появляется 1 раз. Слово 13 ("оплата") появляется 1 раз. Слово 37 ("учетная запись") появляется 1 раз.

Затем ваш LDA смотрит на одно слово и получает оценку с точки зрения того, как часто это встречается со всеми другими словами в словаре, и он делает это для всего словаря, поэтому, если вы дадите ему взглянуть на миллионы и миллионы слов, он действительно рухнет. быстро.

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

# we create a dictionary of all the words in the csv by iterating through
# contains the number of times a word appears in the training set.

dictionary = gensim.corpora.Dictionary(processed_docs[:])
count = 0
for k, v in dictionary.iteritems():
    print(k, v)
    count += 1
    if count > 10:
        break

# we want to throw out words that are so frequent that they tell us little about the topic 
# as well as words that are too infrequent >15 rows then keep just 100,000 words

dictionary.filter_extremes(no_below=15, no_above=0.5, keep_n=100000)

# the words become numbers and are then counted for frequency
# consider a random row 4310 - it has 27 words word indexed 2 shows up 4 times
# preview the bag of words

bow_corpus = [dictionary.doc2bow(doc) for doc in processed_docs]
bow_corpus[4310]

os.environ['MALLET_HOME'] = 'C:\\mallet\\mallet-2.0.8'

mallet_path = 'C:\\mallet\\mallet-2.0.8\\bin\\mallet'

ldamallet = gensim.models.wrappers.LdaMallet(mallet_path, corpus=bow_corpus, num_topics=20, alpha =.1, 
                                             id2word=dictionary, iterations = 1000, random_seed = 569356958)

Также я бы выделил ваш ldamallet в отдельную ячейку, так как время компиляции медленное, особенно для набора данных такого размера. Я надеюсь, что это помогло, дайте мне знать, если вы все еще ошибаетесь :)

  • 0
    Спасибо за ответ! Чтобы создать свой словарь, я начал со всего набора данных, а затем вычеркнул из своего корпуса наиболее и наименее часто встречающиеся слова (т. Е. Те, которые содержатся в 99,5% документов, и те, которые не содержатся как минимум в 100 документах). Я не думал об одном документе, потенциально создающем проблему. Он работает с 2,5 миллионами документов, поэтому я случайно выбрал 10 различных образцов, и это всегда работало, если у меня не было образца более 2,5 миллионов документов. Так что не похоже, что один документ вызывает ошибку. Что вы имеете в виду, отделяя ячейку ldamallet?
  • 0
    @ctim Я не уверен, какой метод вы используете для очистки ваших данных, но я столкнулся с похожей ошибкой в одном из моих наборов данных, и это произошло потому, что nltk пропустил число в подобной строке 700 000. Я бы включил .dropna () в качестве дополнительной меры

Ещё вопросы

Сообщество Overcoder
Наверх
Меню