Машина читает Бертрана Рассела

Приложение обработки естественного языка (NLP) с использованием облака слов, тематического моделирования и схожести текста

Одна из моих секретных целей - читать больше работ Бертрана Рассела; Рассел был эрудитом и плодовитым писателем по целому ряду предметов, включая философию, логику, социальные вопросы и математику. Естественно, я подумал, что если попросить мой компьютер прочесть часть информации от моего имени, это поможет, особенно когда мы все еще можем указывать компьютерам, что им делать. Итак, давайте возьмем несколько текстов из Гутенберга и научим машину генерировать некоторые идеи.

Прежде всего, нам нужно импортировать тексты для анализа. Для этого я бы рекомендовал использовать пакет Python Gutenberg вместо общих пакетов импорта файлов, потому что он позволяет легко удалять довольно длинные раскрытия Гутенберга в каждом документе. Если мы имеем дело только с одним текстом, это не было бы такой большой проблемой, так как удаление может быть выполнено вручную, но в этом случае мы принесем более десяти текстов. Чтобы настроить Гутенберга на Google Colab:

Весь код настроен для работы на Colab, поэтому, если вы запускаете его на своем компьютере, игнорируйте фрагменты для пакетов, которые у вас, возможно, уже есть локально. Как вы, возможно, уже знаете, настройки Colab являются временными, и каждый раз нам нужно загружать все, что не предоставляется всем пользователям по умолчанию. Если вы используете Jupyter Notebook на своем компьютере, вы можете настроить ширину окна, как показано ниже (измените проценты в соответствии с вашими предпочтениями):

Рассел думал большой

Предварительная обработка и облако слов

В этом руководстве мы будем использовать библиотеки NLTK, Wordcloud и Scikit-learn, и все они имеют свои собственные списки стоп-слов (очень распространенные и другие слова, которые не добавят особой ценности для нашего анализа) . Для единообразия, давайте просто будем использовать версию scikit-learn на протяжении всего руководства, но добавим несколько дополнительных слов, которые, как я не ожидал, окажутся очень полезными:

Давайте импортируем тексты, предполагая, что пакет Gutenberg уже установлен:

import os                       
from gutenberg.acquire import load_etext                       
from gutenberg.cleanup import strip_headers                                               path = os.getcwd()                       
text_list = [5827, 690, 2529, 25447, 4776, 44932, 37090, 17350, 55610, 52091]                                               
#writes all texts into one file in the TextsPub directory                      os.mkdir(path + '/TextsPub')
with open(path + '/TextsPub/Russell.txt', 'w') as f:
    for text in text_list:
        text = strip_headers(load_etext(text)).strip()
        f.write(text)
#writes texts into separate files in the TextsPub directory
for text in text_list:
    with open(f"{path+'/TextsPub'}/{text}", "w") as f:
        f.write(strip_headers(load_etext(text)).strip())

Используя код из предыдущей статьи о Плутархе, давайте займемся очисткой текста и подсчетом слов, где мы удалим некоторые стоп-слова, короткие слова, числа, синтаксис, разметим текст и посчитаем наиболее часто встречающиеся слова:

Давайте проверим, сколько здесь слов и сколько из них уникальных:

unique = set(words)
print("The text is {} words long and {} unique words".format(len(words), len(unique)))

Мы получаем 216 893 слова, из которых 15 377 уникальные. Используя этот предварительно обработанный текст, чтобы сделать выводы более значимыми, давайте лемматизируем его (т.е. удалим флективные окончания и вернем базовую форму слов) и нарисуем облако слов:

nltk.download('wordnet') #lexical database for English
from nltk.stem import WordNetLemmatizer 
                                              
with open(path + '/TextsPub/Russell_tokens.txt') as f, open(path + '/TextsPub/Russell_lemma.txt', 'w') as out_f:    
    text = f.read()
    tokens = word_tokenize(text)
    lemma = WordNetLemmatizer()
    lemmed = [lemma.lemmatize(word) for word in tokens]
    #print(lemmed[:100])
    new_lem_text = ' '.join(lemmed)
    out_f.write(new_lem_text)
unique_lem = set(lemmed)
print("The lemmatized text is {} words long and {} unique words".format(len(lemmed), len(unique_lem)))

Мы увидим, что, хотя весь текст состоит из 216 893 слов, количество уникальных слов упало до 13 656.

Давайте поместим лемматизированный текст в облако слов:

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

Вот результат, показывающий, что «вещь» сейчас является самой частой; невозможно было сказать, глядя только на облако слов:

[('thing', 1301), ('point', 1234), ('relation', 1146), ('space', 1140), ('world', 1044), ('fact', 1025), ('object', 930), ('men', 895), ('time', 870), ('knowledge', 856), ('case', 844), ('belief', 805), ('state', 775), ('form', 773), ('law', 756), ('certain', 747), ('number', 744), ('question', 737), ('different', 732), ('life', 727), ('present', 718), ('sense', 692), ('view', 677), ('word', 673), ('possible', 668), ('mean', 665), ('man', 664), ('make', 663), ('way', 655), ('thought', 651), ('true', 635), ('mind', 624), ('matter', 613), ('know', 598), ('given', 579), ('geometry', 560), ('work', 549), ('desire', 542), ('doe', 539), ('kind', 535)]

Основные слова Рассела являются общими и абстрактными: вещь, точка, отношение, пространство, мир, факт и т. Д. В целом, верхняя лексика представляет собой смесь научных, философских и политических слов, что указывает на разнообразие, присущее тексту.

Большевизм очень отличается от геометрии

Тематическое моделирование и подобие текста

Прежде чем мы продолжим, давайте скопируем и переименуем десять отдельных текстов из индексов Гутенберга во что-то, что напоминало бы настоящие имена, а затем извлечем и отсортируем только текстовые заголовки без пути и расширений файлов:

['Analysis_Mind',
 'Bolshevism',
 'Foundations_Geometry',
 'Free_Thought',
 'Knowledge',
 'Mysticism_Logic',
 'Political_Ideals',
 'Problems_Philosophy',
 'Roads_Freedom',
 'Why_Fight']

Существует довольно много техник тематического моделирования, таких как Факторизация неотрицательной матрицы (NMF), Скрытый семантический анализ (усеченная декомпозиция по сингулярным значениям), Скрытое распределение Дирихле и Анализ разреженных главных компонентов. Интерес к космосу, в этом уроке мы коснемся первого, а остальные три рассмотрим в коде Github.

Все методы очень разные, поэтому проверка и управление их составными частями очень важны, поскольку каждый пытается достичь лучших результатов. Например, scikit-learn показывает следующее для NMF:

class sklearn.decomposition.NMF(n_components=None, init=None, solver='cd', beta_loss='frobenius', tol=0.0001, max_iter=200, random_state=None, alpha=0.0, l1_ratio=0.0, verbose=0, shuffle=False)

Например. для бета-потерь (измерение расстояния между NMF и целевой матрицей) у нас есть три варианта: в дополнение к стандартной Норме Фробениуса, мы также можем попробовать Дивергенцию Кульбака-Лейблера и Расстояние Итакура-Сайто. Сам решатель также может быть изменен с координатного спуска по умолчанию на решатель мультипликативного обновления (требуется для Итакура-Сайто).

На этот раз мы пропустим лемматизацию из-за неправильной причины, по которой этот учебник будет короче, но техника такая же, как показано выше. Давайте векторизуем текст и создадим массив numpy, поскольку некоторые из вышеупомянутых методов не могут обрабатывать разреженные матрицы (NMF подходит для любого из них, но для обработки разреженных требуется больше времени):

Затем давайте создадим темы:

И вот что мы получаем:

Давайте посмотрим, как различные тексты относятся к четырем основным темам:

Вот результат:

(К счастью) нет наложения текста о большевизме и геометрии; Темы по геометрии хорошо сочетаются с текстами по анализу разума, знаниям, а также по мистицизму и логике. Между тем, документ, посвященный большевизму, разделяет главные темы с текстом «Политические идеалы», «Почему люди борются» и «Дороги к свободе».

И последнее, но не менее важное: давайте запустим TF-IDF (Term Frequency – Inverse Document Frequency), чтобы измерить попарное сходство между десятью текстами:

После преобразования матрицы, содержащей оценки сходства, в фреймворк Pandas, мы можем легко визуально изучить результаты:

Да, геометрия все же сильно отличается от большевизма!

Вывод

В этом коротком руководстве мы использовали популярные методы НЛП для извлечения информации из текстов, включая облако слов, моделирование тем и схожесть текстов. На этом пути мы использовали NLTK, Wordcloud и Scikit-Learn. Код, описанный в этом руководстве (и других), доступен на Github.

Использованная литература: