BigARTM --- открытая библиотека для тематического моделирования текстовых коллекций, реализующая теорию аддитивной регуляризации тематических моделей (ARTM). Основной сайт проекта http://bigartm.org/.
Здесь показан пример использования пользовательского Python API библиотеки. Мы проведём демонстрационный эксперимент.
Построим две тематические модели коллекции текстовых документов, ARTM и PLSA, сравним качество полученных моделей.
Важным функционалом является перплексия коллекции. Тем не менее, это далеко не единственная величина, характеризующая качество обучения. В BigARTM реализованы следующие функционалы:
Мы будем использовать первые четыре. Более сильные разреженности матриц и более высокие средние значения чистоты и контрастности способствуют большей интерпретируемости модели.
Попробуем обучить модель ARTM таким образом, чтобы, в сравнении с PLSA, улучшить значения разреженностей и ядровых характеристик и не сильно ухудшить перплексию.
Основным инструментом для корректирования процесса обучения являются регуляризаторы. Список имеющихся в BigARTM регуляризаторов:
В этом эксперименте для обучения ARTM воспользуемся первыми тремя регуляризаторами. ARTM без регуляризации соответствует PLSA.
Воспользуемся небольшой коллекцией 'kos', доступной в репозитории UCI https://archive.ics.uci.edu/ml/machine-learning-databases/bag-of-words/. Параметры коллекции следующие:
Для начала подключим все необходимые модули (убедитесь, что путь к Python API BigARTM находится в вашей переменной PATH):
%matplotlib inline
import glob
import matplotlib.pyplot as plt
import artm
Прежде всего необходимо подготовить входные данные. BigARTM имеет собственный формат документов для обработки, называемый батчами. В библиотеки присутствуют средства по созданию батчей из файлов в форматах Bag-Of-Words UCI и Vowpal Wabbit (подробности можно найти в http://docs.bigartm.org/en/latest/formats.html).
В Python API, по аналогии с алгоритмами из scikit-learn, входные данные представлены одним классом BatchVectorizer. Объект этого класса принимает на вход батчи или файлы UCI / VW и подаётся на вход всем методам. В случае, если входные данные не являются батчами, он создаёт их и сохраняет на диск для последующего быстрого использования.
Итак, создадим объект BatchVectorizer:
batch_vectorizer = None
if len(glob.glob('kos' + "/*.batch")) < 1:
batch_vectorizer = artm.BatchVectorizer(data_path='', data_format='bow_uci', collection_name='kos', target_folder='kos')
else:
batch_vectorizer = artm.BatchVectorizer(data_path='kos', data_format='batches')
ARTM --- это класс, представляющий собой Python API BigARTM, и позволяющий использовать практически все возможности библиотеки в стиле scikit-learn. Создадим две тематические модели для нашего эксперимента. Наиболее важным параметром модели является число тем. Опционально можно указать списки регуляризаторов и функционалов качества, которые следует использовать для данной модели. Если этого не сделать, то регуляризаторы и функционалы всегда можно добавить позднее. Обратите внимание, что каждая модель задаёт своё пространство имён для названий регуляризаторов и функционалов качества.
model_plsa = artm.ARTM(num_topics=15,
scores=[artm.PerplexityScore(name='PerplexityScore',
use_unigram_document_model=False,
dictionary_name='dictionary')])
model_artm = artm.ARTM(num_topics=15,
scores=[artm.PerplexityScore(name='PerplexityScore',
use_unigram_document_model=False,
dictionary_name='dictionary')],
regularizers=[artm.SmoothSparseThetaRegularizer(name='SparseTheta', tau=-0.15)])
Следующий шаг — инициализация моделей. Сделаем это по словарю, что означает, что
Надо отметить, что этот шаг является опциональным, поскольку модель может быть автоматически инициализирована во время вызовов fit_offline() / fit_online().
Словарь --- это объект BigARTM, содержащий информацию о коллекции (словарь коллекции, различные величины и счётчики, связанные со словами).
model_plsa.load_dictionary(dictionary_name='dictionary', dictionary_path='kos/dictionary')
model_plsa.initialize(dictionary_name='dictionary')
model_artm.load_dictionary(dictionary_name='dictionary', dictionary_path='kos/dictionary')
model_artm.initialize(dictionary_name='dictionary')
Как уже было сказано, ARTM предоставляет возможность использовать все функционалы качества, имеющиеся в BigARTM. Если функционал подключен к модели, то модель будет сохранять все его значения, полученные на момент каждого обновления матрицы $\Phi$. Добавим функционалы качества, нужные для нашего эксперимента, которые отсутствовали в конструкторах:
model_plsa.scores.add(artm.SparsityPhiScore(name='SparsityPhiScore'))
model_plsa.scores.add(artm.SparsityThetaScore(name='SparsityThetaScore'))
model_plsa.scores.add(artm.TopicKernelScore(name='TopicKernelScore', probability_mass_threshold=0.3))
model_artm.scores.add(artm.SparsityPhiScore(name='SparsityPhiScore'))
model_artm.scores.add(artm.SparsityThetaScore(name='SparsityThetaScore'))
model_artm.scores.add(artm.TopicKernelScore(name='TopicKernelScore', probability_mass_threshold=0.3))
Аналогично поступим с регуляризаторами для model_artm (зададим им стартовые коэффициенты регуляризации, которые можно будет позже изменить при необходимости):
model_artm.regularizers.add(artm.SmoothSparsePhiRegularizer(name='SparsePhi', tau=-0.1))
model_artm.regularizers.add(artm.DecorrelatorPhiRegularizer(name='DecorrelatorPhi', tau=1.5e+5))
Теперь попробуем обучить модели в оффлайн-режиме (т.е. обновляя Фи раз за проход по коллекции). Инициируем пятнадцать проходов:
model_plsa.fit_offline(batch_vectorizer=batch_vectorizer, num_collection_passes=15, num_document_passes=1)
model_artm.fit_offline(batch_vectorizer=batch_vectorizer, num_collection_passes=15, num_document_passes=1)
Проверим результаты первой итерации обучения, сравнив финальные значения функционалов, а также графики перплексии (опишем печать в виде функции для возможности повторного использования):
def print_measures(model_plsa, model_artm):
print 'Sparsity Phi: {0:.3f} (PLSA) vs. {1:.3f} (ARTM)'.format(
model_plsa.score_tracker['SparsityPhiScore'].last_value,
model_artm.score_tracker['SparsityPhiScore'].last_value)
print 'Sparsity Theta: {0:.3f} (PLSA) vs. {1:.3f} (ARTM)'.format(
model_plsa.score_tracker['SparsityThetaScore'].last_value,
model_artm.score_tracker['SparsityThetaScore'].last_value)
print 'Kernel contrast: {0:.3f} (PLSA) vs. {1:.3f} (ARTM)'.format(
model_plsa.score_tracker['TopicKernelScore'].last_average_contrast,
model_artm.score_tracker['TopicKernelScore'].last_average_contrast)
print 'Kernel purity: {0:.3f} (PLSA) vs. {1:.3f} (ARTM)'.format(
model_plsa.score_tracker['TopicKernelScore'].last_average_purity,
model_artm.score_tracker['TopicKernelScore'].last_average_purity)
print 'Perplexity: {0:.3f} (PLSA) vs. {1:.3f} (ARTM)'.format(
model_plsa.score_tracker['PerplexityScore'].last_value,
model_artm.score_tracker['PerplexityScore'].last_value)
plt.plot(xrange(model_plsa.num_phi_updates), model_plsa.score_tracker['PerplexityScore'].value, 'b--',
xrange(model_artm.num_phi_updates), model_artm.score_tracker['PerplexityScore'].value, 'r--', linewidth=2)
plt.xlabel('Iterations count')
plt.ylabel('PLSA perp. (blue), ARTM perp. (red)')
plt.grid(True)
plt.show()
print_measures(model_plsa, model_artm)
Sparsity Phi: 0.022 (PLSA) vs. 0.605 (ARTM) Sparsity Theta: 0.000 (PLSA) vs. 0.406 (ARTM) Kernel contrast: 0.523 (PLSA) vs. 0.550 (ARTM) Kernel purity: 0.378 (PLSA) vs. 0.452 (ARTM) Perplexity: 1510.217 (PLSA) vs. 1540.619 (ARTM)
Видно, что улучшения разреженностей и ядровых характеристик есть, а ухудшение перплексии невелико. Попробуем увеличить по модулю значения коэффициентов регуляризации при регуляризаторах:
model_artm.regularizers['SparsePhi'].tau = -0.2
model_artm.regularizers['SparseTheta'].tau = -0.2
model_artm.regularizers['DecorrelatorPhi'].tau = 2.5e+5
Кроме того, подключим к каждой из моделей функционал TopTokensScore, который позволит взглянуть на самые вероятные слова в каждой теме:
model_plsa.scores.add(artm.TopTokensScore(name='TopTokensScore', num_tokens=6))
model_artm.scores.add(artm.TopTokensScore(name='TopTokensScore', num_tokens=6))
Продолжим обучение моделей, инициировав 25 проходов по коллекции, после чего снова посмотрим на значения функционалов качества:
model_plsa.fit_offline(batch_vectorizer=batch_vectorizer, num_collection_passes=25, num_document_passes=1)
model_artm.fit_offline(batch_vectorizer=batch_vectorizer, num_collection_passes=25, num_document_passes=1)
print_measures(model_plsa, model_artm)
Sparsity Phi: 0.332 (PLSA) vs. 0.740 (ARTM) Sparsity Theta: 0.082 (PLSA) vs. 0.602 (ARTM) Kernel contrast: 0.530 (PLSA) vs. 0.568 (ARTM) Kernel purity: 0.396 (PLSA) vs. 0.531 (ARTM) Perplexity: 1365.804 (PLSA) vs. 1475.455 (ARTM)
Кроме того, для наглядности построим графики изменения разреженностей матриц по итерациям:
plt.plot(xrange(model_plsa.num_phi_updates), model_plsa.score_tracker['SparsityPhiScore'].value, 'b--',
xrange(model_artm.num_phi_updates), model_artm.score_tracker['SparsityPhiScore'].value, 'r--', linewidth=2)
plt.xlabel('Iterations count')
plt.ylabel('PLSA Phi sp. (blue), ARTM Phi sp. (red)')
plt.grid(True)
plt.show()
plt.plot(xrange(model_plsa.num_phi_updates), model_plsa.score_tracker['SparsityThetaScore'].value, 'b--',
xrange(model_artm.num_phi_updates), model_artm.score_tracker['SparsityThetaScore'].value, 'r--', linewidth=2)
plt.xlabel('Iterations count')
plt.ylabel('PLSA Theta sp. (blue), ARTM Theta sp. (red)')
plt.grid(True)
plt.show()
Кажется, что достигнутых результатов достаточно. Регуляризация позволила добиться улучшения всех характеристик, ухудшив перплексию в пределах разумного. Взглянем на топ-слова слова моделей:
for topic_name in model_plsa.topic_names:
print topic_name + ': ',
print model_plsa.score_tracker['TopTokensScore'].last_topic_info[topic_name].tokens
@topic_0: [u'bush', u'tax', u'states', u'president', u'party', u'political'] @topic_1: [u'iraq', u'war', u'military', u'troops', u'soldiers', u'iraqi'] @topic_2: [u'november', u'poll', u'house', u'governor', u'electoral', u'account'] @topic_3: [u'senate', u'republican', u'race', u'democrats', u'gop', u'republicans'] @topic_4: [u'time', u'people', u'general', u'election', u'speech', u'specter'] @topic_5: [u'dean', u'kerry', u'edwards', u'primary', u'clark', u'democratic'] @topic_6: [u'state', u'race', u'district', u'elections', u'candidate', u'party'] @topic_7: [u'administration', u'bush', u'years', u'president', u'jobs', u'marriage'] @topic_8: [u'campaign', u'dean', u'democratic', u'party', u'media', u'people'] @topic_9: [u'house', u'million', u'republican', u'money', u'delay', u'committee'] @topic_10: [u'november', u'voting', u'vote', u'kerry', u'republicans', u'electoral'] @topic_11: [u'iraq', u'bush', u'war', u'administration', u'president', u'intelligence'] @topic_12: [u'bush', u'poll', u'kerry', u'percent', u'polls', u'voters'] @topic_13: [u'media', u'news', u'time', u'people', u'white', u'house'] @topic_14: [u'bush', u'kerry', u'general', u'president', u'bushs', u'campaign']
for topic_name in model_artm.topic_names:
print topic_name + ': ',
print model_artm.score_tracker['TopTokensScore'].last_topic_info[topic_name].tokens
@topic_0: [u'party', u'tax', u'political', u'law', u'court', u'issue'] @topic_1: [u'military', u'troops', u'soldiers', u'killed', u'army', u'service'] @topic_2: [u'labor', u'account', u'governor', u'profile', u'poll', u'parecommend'] @topic_3: [u'senate', u'republican', u'gop', u'senator', u'republicans', u'carson'] @topic_4: [u'specter', u'toomey', u'speech', u'signs', u'yesterday', u'workers'] @topic_5: [u'dean', u'edwards', u'clark', u'primary', u'kerry', u'democratic'] @topic_6: [u'race', u'state', u'candidate', u'candidates', u'nader', u'district'] @topic_7: [u'administration', u'years', u'jobs', u'commission', u'white', u'year'] @topic_8: [u'campaign', u'media', u'unions', u'union', u'press', u'endorsement'] @topic_9: [u'house', u'million', u'money', u'delay', u'republican', u'committee'] @topic_10: [u'november', u'vote', u'voting', u'electoral', u'account', u'voter'] @topic_11: [u'iraq', u'war', u'administration', u'iraqi', u'american', u'intelligence'] @topic_12: [u'bush', u'kerry', u'poll', u'general', u'president', u'bushs'] @topic_13: [u'time', u'people', u'media', u'john', u'news', u'political'] @topic_14: [u'percent', u'states', u'voters', u'ohio', u'election', u'voter']
Видно, что темы примерно одинаково интерпретируемы, но в модели ARTM они существенно разнообразнее.
Извлечём матрицу $\Phi$ в виде pandas.DataFrame и напечатаем её (в случае необходимости, можно извлекать части матрицы с помощью метода ARTM.get_phi()):
print model_artm.phi_
@topic_0 @topic_1 @topic_2 @topic_3 @topic_4 @topic_5 \ aarp 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 abandon 0.000350 0.000000 0.000000 0.000239 0.000000 0.000162 abandoned 0.000183 0.000000 0.000036 0.000000 0.000000 0.000044 abandoning 0.000054 0.000000 0.000000 0.000171 0.000000 0.000167 abb 0.000657 0.000000 0.000000 0.000000 0.000000 0.000000 abc 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 abcs 0.000000 0.000066 0.000000 0.000167 0.000000 0.000000 abdullah 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 ability 0.000490 0.000000 0.000000 0.000100 0.000000 0.000236 aboard 0.000000 0.000347 0.000000 0.000000 0.000261 0.000000 abortion 0.003113 0.000000 0.000000 0.000417 0.000000 0.000000 abortions 0.000524 0.000000 0.000000 0.000000 0.000000 0.000000 abraham 0.000000 0.000000 0.000000 0.000000 0.000989 0.000000 abrams 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 abroad 0.000000 0.000702 0.000000 0.000081 0.000311 0.000000 absence 0.000000 0.000000 0.000000 0.000000 0.000000 0.000179 absent 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 absentee 0.000000 0.000000 0.000206 0.000000 0.000000 0.000000 absolute 0.000000 0.000000 0.000000 0.000000 0.000364 0.000000 absolutely 0.000000 0.000002 0.000000 0.000000 0.000763 0.000049 abstain 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 absurd 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 abu 0.000000 0.000103 0.000000 0.000000 0.000000 0.000000 abuse 0.000000 0.000740 0.000000 0.000000 0.000000 0.000000 abuses 0.000000 0.001875 0.000000 0.000000 0.000000 0.000000 academy 0.000251 0.000171 0.000000 0.000000 0.000000 0.000150 accent 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 accept 0.000000 0.000000 0.000000 0.000000 0.000000 0.000074 acceptable 0.000236 0.000208 0.000043 0.000064 0.000000 0.000000 acceptance 0.000000 0.000000 0.000000 0.000000 0.001041 0.000000 ... ... ... ... ... ... ... yanks 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 yard 0.000000 0.000000 0.000041 0.000000 0.000000 0.000249 yeah 0.000000 0.000000 0.000000 0.000410 0.001217 0.000000 year 0.001763 0.002559 0.000000 0.000006 0.000000 0.000135 years 0.003812 0.001410 0.000030 0.000000 0.000000 0.000477 yell 0.000000 0.000000 0.000000 0.000000 0.000000 0.000303 yellin 0.000000 0.000000 0.000000 0.000000 0.000000 0.000517 yesterday 0.000000 0.000553 0.000000 0.000426 0.004497 0.000212 yesterdays 0.000000 0.000070 0.000000 0.000046 0.000205 0.000000 yield 0.000123 0.000000 0.000000 0.000000 0.000000 0.000000 york 0.000000 0.000307 0.001702 0.000000 0.002027 0.000000 yorker 0.000051 0.000442 0.000000 0.000000 0.000000 0.000000 yorkers 0.000000 0.000360 0.000000 0.000000 0.000000 0.000000 youd 0.000000 0.000287 0.000000 0.000083 0.000000 0.000000 youll 0.000411 0.000000 0.000083 0.000000 0.000000 0.000171 young 0.000161 0.000813 0.000000 0.000430 0.000591 0.000160 younger 0.000592 0.000000 0.000000 0.000000 0.000000 0.000354 youre 0.000597 0.000000 0.000368 0.000650 0.001955 0.000000 youth 0.000000 0.000000 0.000000 0.000000 0.000573 0.000112 youve 0.000064 0.000000 0.000122 0.000000 0.000952 0.000081 yucca 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 yup 0.000029 0.000000 0.000000 0.000000 0.000000 0.000000 zahn 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 zarqawi 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 zell 0.000000 0.000000 0.000000 0.002560 0.000000 0.000000 zimbabwe 0.000000 0.000323 0.000000 0.000000 0.000000 0.000000 zogby 0.000000 0.000000 0.004862 0.000000 0.000000 0.003687 zogbys 0.000000 0.000000 0.000000 0.000000 0.000000 0.000680 zone 0.000000 0.000907 0.000136 0.000049 0.000000 0.000181 zones 0.000000 0.000395 0.000033 0.000000 0.000000 0.000000 @topic_6 @topic_7 @topic_8 @topic_9 @topic_10 @topic_11 \ aarp 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 abandon 0.000152 0.000000 0.000000 0.000000 0.000000 0.000000 abandoned 0.000000 0.000321 0.000054 0.000000 0.000025 0.000000 abandoning 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 abb 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 abc 0.000000 0.000000 0.001623 0.000000 0.000059 0.000155 abcs 0.000000 0.000134 0.000000 0.000000 0.000000 0.000000 abdullah 0.000000 0.000000 0.000000 0.000000 0.000000 0.000202 ability 0.001144 0.000000 0.000432 0.000119 0.000088 0.000535 aboard 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 abortion 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 abortions 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 abraham 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 abrams 0.000000 0.000433 0.000000 0.000000 0.000000 0.000099 abroad 0.000177 0.000439 0.000000 0.000000 0.000000 0.000000 absence 0.000285 0.000000 0.000000 0.000000 0.000074 0.000141 absent 0.000000 0.000149 0.000000 0.000000 0.000100 0.000000 absentee 0.000799 0.000000 0.000000 0.000000 0.000000 0.000000 absolute 0.000093 0.000000 0.000078 0.000000 0.000052 0.000089 absolutely 0.000000 0.000050 0.000176 0.000000 0.000000 0.000000 abstain 0.000000 0.000000 0.000000 0.000000 0.003154 0.000000 absurd 0.000000 0.000000 0.000326 0.000051 0.000000 0.000000 abu 0.000000 0.000000 0.000000 0.000000 0.000000 0.003674 abuse 0.000000 0.000000 0.000000 0.000272 0.000000 0.001229 abuses 0.000000 0.000000 0.000000 0.000000 0.000000 0.000393 academy 0.000000 0.000040 0.000000 0.000000 0.000000 0.000000 accent 0.000000 0.000000 0.000109 0.000000 0.000000 0.000000 accept 0.000000 0.000193 0.000000 0.000420 0.000000 0.000618 acceptable 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 acceptance 0.000050 0.000000 0.000000 0.000000 0.000000 0.000000 ... ... ... ... ... ... ... yanks 0.000000 0.000000 0.000161 0.000000 0.000000 0.000000 yard 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 yeah 0.000306 0.000272 0.000565 0.000256 0.000000 0.000264 year 0.001171 0.007419 0.002169 0.002629 0.000000 0.000156 years 0.001371 0.009146 0.000000 0.000484 0.000000 0.000789 yell 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 yellin 0.000267 0.000000 0.000000 0.000731 0.000147 0.000095 yesterday 0.000000 0.000239 0.000000 0.001537 0.000000 0.000939 yesterdays 0.000000 0.000000 0.000068 0.000000 0.000000 0.000000 yield 0.000098 0.000000 0.000000 0.000000 0.000000 0.000000 york 0.000000 0.000000 0.002198 0.001391 0.000000 0.000352 yorker 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 yorkers 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 youd 0.000228 0.000000 0.000289 0.000000 0.000000 0.000000 youll 0.000000 0.000000 0.000854 0.000098 0.000000 0.000083 young 0.000150 0.000000 0.000000 0.000298 0.000000 0.000000 younger 0.000083 0.000000 0.000000 0.000000 0.000000 0.000000 youre 0.000546 0.000000 0.000808 0.000000 0.000000 0.000161 youth 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 youve 0.000333 0.000000 0.000416 0.000000 0.000000 0.000397 yucca 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 yup 0.000000 0.000000 0.000000 0.000000 0.000000 0.000050 zahn 0.000000 0.000000 0.000072 0.000000 0.000000 0.000078 zarqawi 0.000000 0.000000 0.000000 0.000000 0.000000 0.000488 zell 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 zimbabwe 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 zogby 0.000000 0.000000 0.000000 0.000000 0.000141 0.000000 zogbys 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 zone 0.000465 0.000000 0.000000 0.000000 0.000000 0.000000 zones 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 @topic_12 @topic_13 @topic_14 aarp 0.000000 0.000411 0.000000 abandon 0.000000 0.000000 0.000083 abandoned 0.000000 0.000000 0.000231 abandoning 0.000000 0.000000 0.000270 abb 0.000000 0.000000 0.000000 abc 0.000859 0.000000 0.000228 abcs 0.000149 0.000000 0.000000 abdullah 0.000000 0.000000 0.000000 ability 0.000000 0.000263 0.000000 aboard 0.000000 0.000154 0.000000 abortion 0.000000 0.000000 0.000000 abortions 0.000000 0.000000 0.000000 abraham 0.000000 0.000000 0.000000 abrams 0.000000 0.000000 0.000000 abroad 0.000000 0.000000 0.000000 absence 0.000000 0.000000 0.000008 absent 0.000000 0.000157 0.000174 absentee 0.000000 0.000000 0.000000 absolute 0.000000 0.000315 0.000000 absolutely 0.000136 0.000288 0.000000 abstain 0.000000 0.000000 0.000000 absurd 0.000000 0.000000 0.000000 abu 0.000000 0.000000 0.000000 abuse 0.000000 0.000395 0.000000 abuses 0.000000 0.000000 0.000000 academy 0.000000 0.000000 0.000000 accent 0.000000 0.000040 0.000290 accept 0.000408 0.000000 0.000092 acceptable 0.000000 0.000157 0.000000 acceptance 0.000258 0.000227 0.000000 ... ... ... ... yanks 0.000051 0.000000 0.000256 yard 0.000000 0.000000 0.000224 yeah 0.000421 0.000050 0.000000 year 0.001416 0.000171 0.002756 years 0.000767 0.001817 0.005628 yell 0.000000 0.000000 0.000172 yellin 0.000000 0.000000 0.000000 yesterday 0.000547 0.000000 0.000000 yesterdays 0.000315 0.000253 0.000000 yield 0.000000 0.000306 0.000000 york 0.000368 0.000000 0.003268 yorker 0.000000 0.000000 0.000000 yorkers 0.000000 0.000000 0.000000 youd 0.000022 0.000000 0.000000 youll 0.000022 0.000842 0.000000 young 0.000334 0.001980 0.000000 younger 0.000000 0.000000 0.000000 youre 0.000280 0.002244 0.000660 youth 0.000000 0.000000 0.000000 youve 0.000228 0.001252 0.000000 yucca 0.000000 0.000376 0.000000 yup 0.000119 0.000000 0.000000 zahn 0.000000 0.000000 0.000000 zarqawi 0.000017 0.000000 0.000000 zell 0.000000 0.000042 0.000000 zimbabwe 0.000000 0.000000 0.000000 zogby 0.002645 0.000000 0.000024 zogbys 0.000277 0.000000 0.000000 zone 0.000000 0.000000 0.000000 zones 0.000000 0.000000 0.000000 [6906 rows x 15 columns]
Модель можно сохранить с возможностью последующей загрузки:
model_artm.save(filename='kos_artm_model') # save the model to disk
# model = artm.ARTM(...) # create new model
# model.load(filename='kos_artm_model') # load saved model into new instance
Дополнительно извлечём $\Theta$ в виде pandas.DataFrame и напечатаем её:
theta_matrix = model_artm.fit_transform()
print theta_matrix
2001 2002 2003 2004 2005 2006 \ @topic_0 0.067481 0.000000 0.000000 0.000000 0.000000 0.000000 @topic_1 0.000000 0.000000 0.000000 0.207492 0.000000 0.000000 @topic_2 0.000000 0.000000 0.000000 0.000000 0.000000 0.761782 @topic_3 0.008255 0.000000 0.000000 0.000000 0.000000 0.000000 @topic_4 0.000000 0.000000 0.000000 0.098357 0.000000 0.000000 @topic_5 0.100168 0.444500 0.711200 0.015994 0.633351 0.000000 @topic_6 0.020800 0.143583 0.000000 0.000000 0.090034 0.000000 @topic_7 0.000000 0.000000 0.000000 0.293395 0.000000 0.000000 @topic_8 0.071087 0.265716 0.267102 0.000000 0.000000 0.000000 @topic_9 0.660074 0.000000 0.000000 0.118694 0.000000 0.000000 @topic_10 0.014342 0.000000 0.021698 0.000000 0.000000 0.218897 @topic_11 0.000000 0.000000 0.000000 0.056249 0.000000 0.000000 @topic_12 0.057793 0.000000 0.000000 0.000000 0.276615 0.019321 @topic_13 0.000000 0.000000 0.000000 0.054615 0.000000 0.000000 @topic_14 0.000000 0.146202 0.000000 0.155204 0.000000 0.000000 2007 2008 2009 2010 ... 3421 \ @topic_0 0.000000 0.000000 0.199291 0.000000 ... 0.000000 @topic_1 0.139264 0.000000 0.000000 0.000000 ... 0.312308 @topic_2 0.000000 0.000000 0.000000 0.000000 ... 0.000000 @topic_3 0.000000 0.000000 0.000000 0.000000 ... 0.244082 @topic_4 0.038610 0.000000 0.073896 0.092537 ... 0.000000 @topic_5 0.112434 0.802891 0.022171 0.000000 ... 0.000000 @topic_6 0.416537 0.048166 0.085764 0.000000 ... 0.000000 @topic_7 0.000000 0.000000 0.385716 0.047028 ... 0.000000 @topic_8 0.260371 0.127574 0.024974 0.297582 ... 0.092366 @topic_9 0.032784 0.000000 0.016041 0.000000 ... 0.129875 @topic_10 0.000000 0.021369 0.000000 0.000000 ... 0.000000 @topic_11 0.000000 0.000000 0.136654 0.000000 ... 0.117937 @topic_12 0.000000 0.000000 0.055491 0.047457 ... 0.103432 @topic_13 0.000000 0.000000 0.000000 0.515396 ... 0.000000 @topic_14 0.000000 0.000000 0.000000 0.000000 ... 0.000000 3422 3423 3424 3425 3426 3427 \ @topic_0 0.000000 0.000000 0.000000 0.000000 0.000000 0.039310 @topic_1 0.088784 0.080694 0.000000 0.000000 0.000000 0.000000 @topic_2 0.009682 0.037034 0.048171 0.000000 0.000000 0.000000 @topic_3 0.000000 0.112404 0.219774 0.000000 0.066308 0.000000 @topic_4 0.101495 0.000000 0.000000 0.000000 0.040677 0.000000 @topic_5 0.000000 0.000000 0.000000 0.000000 0.008462 0.090352 @topic_6 0.000000 0.000000 0.106319 0.041240 0.000000 0.000000 @topic_7 0.000000 0.030733 0.000000 0.000000 0.000000 0.000000 @topic_8 0.000000 0.043644 0.229049 0.000000 0.000000 0.080275 @topic_9 0.000000 0.147402 0.052955 0.000000 0.000000 0.000000 @topic_10 0.691181 0.000000 0.000000 0.000000 0.026972 0.000000 @topic_11 0.000000 0.093647 0.000000 0.077098 0.000000 0.000000 @topic_12 0.108858 0.171321 0.343731 0.667596 0.773543 0.688500 @topic_13 0.000000 0.272353 0.000000 0.133350 0.000000 0.000000 @topic_14 0.000000 0.010770 0.000000 0.080716 0.084038 0.101563 3428 3429 3430 @topic_0 0.432546 0.430796 0.156186 @topic_1 0.000000 0.000000 0.064176 @topic_2 0.000000 0.000000 0.000000 @topic_3 0.000000 0.316691 0.288642 @topic_4 0.000000 0.000000 0.000000 @topic_5 0.000000 0.000000 0.000000 @topic_6 0.000000 0.029191 0.000000 @topic_7 0.030102 0.000000 0.000000 @topic_8 0.000000 0.000000 0.070009 @topic_9 0.144588 0.000000 0.000000 @topic_10 0.011323 0.000000 0.000000 @topic_11 0.050171 0.067022 0.210310 @topic_12 0.102622 0.156299 0.210677 @topic_13 0.228648 0.000000 0.000000 @topic_14 0.000000 0.000000 0.000000 [15 rows x 3430 columns]
Можно использовать модель для определения векторов $\theta_d$ для новых документов с помощью метода ARTM.transform():
test_batch_vectorizer = artm.BatchVectorizer(data_format='batches', data_path='kos_test', batches=['test_docs.batch'])
test_theta_matrix = model_artm.transform(batch_vectorizer=test_batch_vectorizer)
print test_theta_matrix
3001 3002 3003 3004 3005 3006 \ @topic_0 0.091626 0.051341 0.084178 0.113109 0.062232 0.013974 @topic_1 0.078571 0.042425 0.025621 0.033497 0.044191 0.021204 @topic_2 0.011039 0.044933 0.011057 0.027369 0.036670 0.295919 @topic_3 0.052996 0.039658 0.055971 0.097226 0.060337 0.030398 @topic_4 0.107471 0.063107 0.059513 0.055636 0.037655 0.014663 @topic_5 0.026716 0.028380 0.053424 0.052916 0.058957 0.021769 @topic_6 0.061239 0.046306 0.091071 0.069617 0.064477 0.027188 @topic_7 0.060626 0.072943 0.027753 0.045421 0.034514 0.012981 @topic_8 0.046049 0.036000 0.049218 0.085700 0.039967 0.016622 @topic_9 0.075803 0.373726 0.028326 0.141573 0.185461 0.035030 @topic_10 0.024496 0.027005 0.122641 0.044386 0.050464 0.381458 @topic_11 0.149485 0.050984 0.078244 0.057471 0.081199 0.012682 @topic_12 0.074925 0.050844 0.184449 0.093292 0.119310 0.058822 @topic_13 0.054886 0.042338 0.037857 0.046660 0.091642 0.030833 @topic_14 0.084071 0.030010 0.090676 0.036127 0.032924 0.026456 3007 3008 3009 3010 ... 3421 \ @topic_0 0.135083 0.040394 0.070500 0.054120 ... 0.053217 @topic_1 0.033187 0.026365 0.031285 0.051316 ... 0.188329 @topic_2 0.014831 0.006156 0.025022 0.015693 ... 0.018047 @topic_3 0.149433 0.111226 0.111084 0.077831 ... 0.117872 @topic_4 0.032542 0.047830 0.035773 0.049776 ... 0.047223 @topic_5 0.035800 0.073704 0.062772 0.052942 ... 0.028251 @topic_6 0.205175 0.289144 0.163030 0.071736 ... 0.051952 @topic_7 0.038034 0.024754 0.042682 0.071886 ... 0.035179 @topic_8 0.025486 0.029871 0.039220 0.064998 ... 0.080373 @topic_9 0.087366 0.194811 0.221564 0.253696 ... 0.078390 @topic_10 0.032463 0.024156 0.032925 0.020051 ... 0.018027 @topic_11 0.045937 0.022048 0.034563 0.049819 ... 0.112073 @topic_12 0.052789 0.052914 0.051892 0.050814 ... 0.074052 @topic_13 0.040613 0.037710 0.032525 0.052787 ... 0.054900 @topic_14 0.071261 0.018918 0.045164 0.062534 ... 0.042118 3422 3423 3424 3425 3426 3427 \ @topic_0 0.029688 0.056136 0.030656 0.037794 0.033733 0.065057 @topic_1 0.044970 0.083241 0.058157 0.031748 0.010574 0.021766 @topic_2 0.170558 0.040457 0.043998 0.008223 0.040032 0.008721 @topic_3 0.033000 0.092317 0.094547 0.083945 0.057029 0.051220 @topic_4 0.062132 0.037539 0.086836 0.075058 0.061395 0.075814 @topic_5 0.023858 0.039621 0.027054 0.039687 0.074499 0.048541 @topic_6 0.029032 0.037871 0.072648 0.062533 0.051166 0.069541 @topic_7 0.026313 0.064232 0.030583 0.073252 0.056748 0.071994 @topic_8 0.018689 0.070856 0.092027 0.058238 0.043525 0.070542 @topic_9 0.023774 0.085163 0.078939 0.052960 0.026771 0.040209 @topic_10 0.369834 0.015975 0.034444 0.009358 0.061814 0.050535 @topic_11 0.033076 0.084772 0.041239 0.082667 0.040756 0.037102 @topic_12 0.077779 0.103942 0.125025 0.235061 0.308191 0.212962 @topic_13 0.016357 0.131226 0.143185 0.098799 0.036963 0.046091 @topic_14 0.040940 0.056652 0.040662 0.050675 0.096804 0.129903 3428 3429 3430 @topic_0 0.216935 0.181619 0.083660 @topic_1 0.049587 0.034619 0.071326 @topic_2 0.021753 0.007940 0.009281 @topic_3 0.052247 0.195912 0.143868 @topic_4 0.059768 0.024548 0.047320 @topic_5 0.035378 0.048469 0.042357 @topic_6 0.025609 0.087325 0.068865 @topic_7 0.065516 0.041504 0.054057 @topic_8 0.049607 0.036873 0.074177 @topic_9 0.085877 0.053949 0.037463 @topic_10 0.022597 0.012686 0.010203 @topic_11 0.072966 0.065032 0.134728 @topic_12 0.083369 0.107953 0.133119 @topic_13 0.101585 0.058545 0.052958 @topic_14 0.057206 0.043026 0.036616 [15 rows x 430 columns]
Задача построения тематической модели имеет бесконечно большое множество решений. Это даёт большую свободу действий, и регуляризаторы позволяют использовать её для получения результата, удовлетворяющего сразу нескольким требованиям (разреженность, интерпретируемость, удовлетворительное значение перплексии и т.п.).
Приведённый выше пример является демонстрационным, можно пробовать более гибкие стратегии регуляризации для получения ещё более хорошего результата. По аналогичной схеме можно производить эксперименты с более крупными коллекциями.