Тематическое моделирование — это математический процесс получения абстрактных тем для корпуса на основе слов, присутствующих в каждом документе. Это своего рода неконтролируемая модель машинного обучения, пытающаяся найти текстовую корреляцию между документами. Существуют различные модели для выполнения тематического моделирования, такие как латентное распределение Дирихле, латентный семантический анализ и т. Д. В этой статье мы рассмотрим функционирование и работу латентного семантического анализа. Мы также рассмотрим математику, лежащую в основе метода.

Скрытый семантический анализ

Скрытая семантическая модель — это статистическая модель для определения связи между набором документов и терминами, присутствующими в этих документах, путем получения семантической связи между этими словами. Здесь мы формируем матрицу документа-термина из корпуса текста. Каждая строка в столбце представляет уникальные слова в документе, а каждый столбец представляет собой один документ. Процесс достигается с помощью разложения по сингулярным значениям.

Математика модели

Латентный семантический анализ работает на основе разложения по единичным значениям. Это метод разложения матрицы на три матрицы. Рассмотрим матрицу A, которую нужно разложить на множители. Затем она разлагается на три уникальные матрицы U, L и V, где U и V — ортонормированные матрицы, а L — сингулярная матрица. Матрица определяется как сингулярная матрица, если ее определитель не существует или необратим.

Например, посмотрите на приведенные ниже матрицы.

Здесь X — матрица терминов-документов, состоящая из всех слов, присутствующих в каждом из документов. Матрицы транспонирования U и V — это ортонормированные матрицы, в которых каждая строка представляет собой ортогональные векторы. S представляет собой диагональную матрицу с сингулярными значениями, собственные значения которой расположены вдоль диагонали. Каждая строка матрицы V Transpose представляет темы, а значения для конкретной темы в каждом столбце представляют важность и взаимосвязь этого слова в соответствующем документе [Примечание: каждый столбец представляет уникальный документ].

Реализация Python

Реализация Python для разложения по сингулярным значениям приведена ниже. Мы будем использовать пакет scipy SVD для выполнения операции. Сначала давайте импортируем необходимые пакеты и определим нашу матрицу A.

import numpy as np
from scipy.linalg import svd

A = np.array([[1, 2], [3, 4], [5, 6]])
print(A)

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

U, S, VT = svd(A)
print(U)
print(S)
print(VT)

Анализ текста

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

Прежде всего, давайте импортируем все необходимые пакеты для выполнения проекта.

import re
import numpy as np
import pandas as pd
from scipy import linalg, spatial
from sklearn.cluster import KMeans
from sklearn.decomposition import PCA, SparsePCA, TruncatedSVD
from sklearn.feature_extraction.text import (CountVectorizer, TfidfTransformer, TfidfVectorizer)
from sklearn.cluster import KMeans

from sklearn.utils.extmath import randomized_svd

from nltk.tokenize import word_tokenize
from nltk.corpus import stopwords

Теперь мы импортируем текст, который собираемся анализировать. Текст представляет собой выдержку из Википедии о Роберте Дауни-младшем. Для ясного понимания рабочего процесса используется лишь небольшой отрывок текста. Этот процесс можно масштабировать до больших текстов с помощью пакетов request и BeautifulSoup.

corpus = [

          "With all of the critical success Downey had experienced throughout his career, he had not appeared in a blockbuster film. That changed in 2008 when Downey starred in two critically and commercially successful films, Iron Man and Tropic Thunder. In the article Ben Stiller wrote for Downey's entry in the 2008 edition of The Time 100, he offered an observation on Downey's commercially successful summer at the box office.",
          "On June 14, 2010, Downey and his wife Susan opened their own production company called Team Downey. Their first project was The Judge.",
          "Robert John Downey Jr. is an American actor, producer, and singer. His career has been characterized by critical and popular success in his youth, followed by a period of substance abuse and legal troubles, before a resurgence of commercial success in middle age.",
          "In 2008, Downey was named by Time magazine among the 100 most influential people in the world, and from 2013 to 2015, he was listed by Forbes as Hollywood's highest-paid actor. His films have grossed over $14.4 billion worldwide, making him the second highest-grossing box-office star of all time."
          
          ]

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

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

Теперь мы разделим весь документ на отдельные слова с помощью токенизатора. Затем отдельные токены вводятся в словарь Python filtered_text.

filtered_document= []
filtered_text = []

for document in corpus:
    
    clean_document = " ".join(re.sub(r"[^A-Za-z \—]+", " ", document).split())
    
    document_tokens = word_tokenize(clean_document)

    for word in document_tokens:
        if word not in stop_words:
            filtered_document.append(word)

    filtered_text.append(' '.join(filtered_document))

Теперь мы сформируем матрицу частоты слов, чтобы подсчитать использование разных слов в разных документах корпуса.

vectorizer = CountVectorizer()

counts_matrix = vectorizer.fit_transform(filtered_text)

feature_names = vectorizer.get_feature_names()

count_matrix_df = pd.DataFrame(counts_matrix.toarray(), columns=feature_names)
count_matrix_df.index = ['Document 1','Document 2','Document 3','Document 4']

print("Word frequency matrix: \n", count_matrix_df)

Вывод этого кода выводит матрицу, которая показывает частоту появления каждого слова в каждом документе.

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

vectorizer = TfidfVectorizer(stop_words=stop_words,max_features=10000, max_df = 0.5,
                                    use_idf = True,
                                    ngram_range=(1,3))

X = vectorizer.fit_transform(filtered_text)
print(X.shape)
print(feature_names)

num_clusters = 4

km = KMeans(n_clusters=num_clusters)
km.fit(X)
    
clusters = km.labels_.tolist()
print(clusters)

Теперь сгенерируем темы для корпуса с помощью SVD.

U, Sigma, VT = randomized_svd(X, n_components=10, n_iter=100, random_state=122)

svd_model = TruncatedSVD(n_components=2, algorithm='randomized', n_iter=100, random_state=122)

svd_model.fit(X)
    
print(U.shape)

for i, comp in enumerate(VT):
    terms_comp = zip(feature_names, comp)
    sorted_terms = sorted(terms_comp, key= lambda x:x[1], reverse=True)[:7]
    print("Cluster "+str(i)+": ")
    for t in sorted_terms:
        print(t[0])
    print(" ")

Результат, полученный от программы, прикреплен ниже. Это показывает, как темы получаются на основе семантической связи между словами.

Cluster 0: 
american
age
actor
article
ben
billion
called

Cluster 1: 
actor
article
ben
billion
called
career
changed

Cluster 2: 
american
age
actor
among
appeared
blockbuster
box

Cluster 3: 
american
actor
abuse
article
ben
billion
called

Вывод

В этой статье мы рассмотрели латентный семантический анализ и его реализацию на Python. мы также рассмотрели математическую модель Singular Value Decomposition.

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

01. https://en.wikipedia.org/wiki/Robert_Downey_Jr.

02. https://en.wikipedia.org/wiki/Скрытый_семантический_анализ

03. https://www.datacamp.com/community/tutorials/discovering-hidden-topics-python