Визуальное представление содержимого текстового документа является одной из наиболее важных задач в области интеллектуального анализа текста (также называемого исследовательским анализом текста). Как специалист по данным или специалист по НЛП, мы не только исследуем содержимое документов с разных сторон и на разных уровнях детализации, но и резюмируем один документ, показываем слова и темы, выявляем события и создаем сценарии.
Однако существуют расхождения между визуализация данных неструктурированные (текстовые) и структурированные данные. Например, многие текстовые визуализации не представляют текст напрямую, они представляют собой выходные данные языковой модели (количество слов, длина символов, последовательности слов и т. д.).
В этой статье мы будем использовать набор данных «Обзоры электронной коммерции женской одежды» и попытаемся изучить и визуализировать как можно больше, используя графическую библиотеку Plotly Python и библиотеку визуализации Bokeh. Мы будем не только исследовать текстовые данные, но и визуализировать числовые и категориальные признаки.
После краткого изучения данных мы обнаружили, что нам необходимо выполнить ряд предварительных обработок данных.
Удалите функцию «Заголовок».
Удалите строки, в которых отсутствует «Текст обзора».
Очистите столбец «Текст редакции».
Использование TextBlob для вычисления полярности тональности, которая находится в диапазоне [-1,1], где 1 означает позитивную тональность, а -1 — негативную тональность.
Создайте новую функцию на время экзамена.
Создайте новую функцию для подсчета слов на экзамене.
Чтобы проверить, работает ли оценка полярности настроений, мы случайным образом выбираем 5 отзывов с наивысшей оценкой полярности настроений (1):
print('5 случайных отзывов с самой высокой полярностью положительных настроений: \n')
cl = df.loc[df.polarity == 1, ['Текст обзора']].sample(5).values
для с в кл:
печать (с [0])

Затем случайным образом выберите 5 отзывов с наиболее нейтральной полярностью настроений (ноль):
print('5 случайных отзывов с наиболее нейтральной (нулевой) полярностью настроений:\n')
cl = df.loc[df.polarity == 0, ['Текст обзора']].sample(5).values
для с в кл:
печать (с [0])

Было только 2 отзыва с самым негативным показателем полярности настроений:
print('2 отзыва с самой отрицательной полярностью: \n')
cl = df.loc[df.polarity == -0.97500000000000009, ['Текст обзора']].sample(2).values
для с в кл:
печать (с [0])

Кажется, это работает
Одномерная визуализация
Визуализация с одной переменной или одномерная визуализация — это простейший тип визуализации, состоящий из наблюдений за одним объектом или атрибутом. Одномерная визуализация включает гистограмму, гистограммы и линейные графики.
Подавляющее большинство оценок полярности настроений выше нуля, что означает, что большинство из них весьма положительные.
Ноты выровнены по шкале полярности, т. е. большинство нот довольно высокие в 4 или 5 диапазонах.
То же самое можно сделать с возрастом рецензентов, количеством символов в рецензии и количеством слов в рецензии, но это не основная задача данного руководства.
N-граммы
Теперь мы подошли к интересующей нас функции, прежде чем исследовать эту функцию, нам нужно извлечь функции N-Gram. N-граммы используются для описания количества слов, используемых в качестве точек наблюдения, например, униграмма означает одно слово, биграмма означает предложение из двух слов, а триграмма означает предложение из трех слов. Для этого мы используем функцию CountVectorizer из scikit-learn.
Для анализа униграмм очень важно очистить текст от стоп-слов.
деф get_top_n_words(корпус, нет=Никто): | |
с = CountVectorizer(стоп_слова = 'английский').поместиться(корпус) | |
bag_of_words = с.трансформировать(корпус) | |
сумма_слов = bag_of_words.сумма(ось=0) | |
слова_частота = [(слово, сумма_слов[0, IDX]) за слово, IDX в с.запас слов_.Предметы()] | |
слова_частота =отсортированный(слова_частота, ключ = лямбда Икс: Икс[1], задний ход=Истинный) | |
возвращаться слова_частота[:нет] | |
распространенные слова = get_top_n_words(дф[«Просмотреть текст»], 20) | |
за слово, частота в распространенные слова: | |
Распечатать(слово, частота) | |
дф2 = пд.кадр данных(распространенные слова, столбцы = [«Обзор текста» , 'считать']) | |
дф2.группа по(«Обзор текста»).сумма()['считать'].sort_values(Восходящий=ЛОЖЬ).иплан( | |
Добрый='бар', yTitle='Считать', цвет линии=черный, заглавие=«20 лучших слов в обзоре после удаления стоп-слов») |

деф get_top_n_bigram(корпус, нет=Никто): | |
с = CountVectorizer(ngram_range=(2, 2), стоп_слова='английский').поместиться(корпус) | |
bag_of_words = с.трансформировать(корпус) | |
сумма_слов = bag_of_words.сумма(ось=0) | |
слова_частота = [(слово, сумма_слов[0, IDX]) за слово, IDX в с.запас слов_.Предметы()] | |
слова_частота =отсортированный(слова_частота, ключ = лямбда Икс: Икс[1], задний ход=Истинный) | |
возвращаться слова_частота[:нет] | |
распространенные слова = get_top_n_bigram(дф[«Просмотреть текст»], 20) | |
за слово, частота в распространенные слова: | |
Распечатать(слово, частота) | |
df4 = пд.кадр данных(распространенные слова, столбцы = [«Обзор текста» , 'считать']) | |
df4.группа по(«Обзор текста»).сумма()['считать'].sort_values(Восходящий=ЛОЖЬ).иплан( | |
Добрый='бар', yTitle='Считать', цвет линии=черный, заглавие=«20 лучших биграмм в обзоре после удаления стоп-слов») |

Часть речи
Тегирование части речи (POS) — это процесс присвоения частей речи каждому слову, например существительному, глаголу, прилагательному и т. д.
капля = TextBlob(ул(дф[«Просмотреть текст»])) | |
pos_df = пд.кадр данных(капля.теги, столбцы = ['слово' , 'поз']) | |
pos_df = pos_df.поз.value_counts()[:20] | |
pos_df.иплан( | |
Добрый='бар', | |
xНазвание="POS", | |
yTitle='считать', | |
заглавие=«20 лучших тегов частей речи для корпуса обзоров») |

Анализ по классам
Блочная диаграмма используется для сравнения оценки полярности настроений, рейтинга, длины текста обзора каждого отдела или подразделения интернет-магазина.
Наивысший показатель полярности настроений был достигнут всеми шестью отделами, кроме отдела трендов, а самый низкий показатель полярности настроений был достигнут отделом Tops. А отдел трендов имеет самый низкий средний показатель полярности. Если вы помните, у отдела Trend меньше всего отзывов. Это объясняет, почему он не имеет такого широкого разнообразия распределения баллов, как другие отделы.
За исключением отдела «Тенденции», медианный рейтинг для всех остальных отделов составил 5. В целом рейтинги высоки, а настроения в этом наборе обзорных данных положительные.
И так далее.
Двумерный анализ
Двумерная визуализация — это тип визуализации, состоящий из сразу двух характеристик. Он описывает связь или взаимосвязь между двумя характеристиками.
Давайте посмотрим на анализ настроений, основанный на том, рекомендует ли человек продукт.
х1 = дф.место[дф[«Рекомендуемый ИНД»] == 1, «полярность»] | |
х0 = дф.место[дф[«Рекомендуемый ИНД»] == 0, «полярность»] | |
трассировка1 = идти.Гистограмма( | |
Икс=х0, имя='Не рекомендуется', | |
непрозрачность=0.75 | |
) | |
след2 = идти.Гистограмма( | |
Икс=х1, имя = 'Рекомендуемые', | |
непрозрачность=0.75 | |
) | |
данные = [трассировка1, след2] | |
макет = идти.макет(бармен='наложение', заглавие=«Распределение полярности настроений отзывов на основе рекомендаций») | |
Рис = идти.фигура(данные=данные, макет=макет) | |
иплан(Рис, имя файла=«наложенная гистограмма») |

трассировка1 = идти.Разброс( | |
Икс=дф[«полярность»], там=дф['Рейтинг'], мода=маркеры, имя='точки', | |
маркер=сказать(цвет='ргб(102,0,0)', размер=2, непрозрачность=0.4) | |
) | |
след2 = идти.Гистограмма2DКонтур( | |
Икс=дф[«полярность»], там=дф['Рейтинг'], имя='плотность', контуры=20, | |
цветовая гамма='Горячий', обратная шкала=Истинный, выставочный масштаб=ЛОЖЬ | |
) | |
след3 = идти.Гистограмма( | |
Икс=дф[«полярность»], имя=«Плотность полярности настроений», | |
маркер=сказать(цвет='ргб(102,0,0)'), | |
яксис='у2' | |
) | |
след4 = идти.Гистограмма( | |
там=дф['Рейтинг'], имя=«Рейтинговая плотность», маркер=сказать(цвет='ргб(102,0,0)'), | |
ось x='х2' | |
) | |
данные = [трассировка1, след2, след3, след4] | |
макет = идти.макет( | |
шоулегенда=ЛОЖЬ, | |
авто размер=ЛОЖЬ, | |
ширина=600, | |
высота=550, | |
ось x=сказать( | |
домен=[0, 0.85], | |
сетка=ЛОЖЬ, | |
нулевая линия=ЛОЖЬ | |
), | |
яксис=сказать( | |
домен=[0, 0.85], | |
сетка=ЛОЖЬ, | |
нулевая линия=ЛОЖЬ | |
), | |
поле=сказать( | |
ты=50 | |
), | |
режим наведения='ближайший', | |
сделка=0, | |
xось2=сказать( | |
домен=[0.85, 1], | |
сетка=ЛОЖЬ, | |
нулевая линия=ЛОЖЬ | |
), | |
яксис2=сказать( | |
домен=[0.85, 1], | |
сетка=ЛОЖЬ, | |
нулевая линия=ЛОЖЬ | |
) | |
) | |
Рис = идти.фигура(данные=данные, макет=макет) | |
иплан(Рис, имя файла='2dhistogram-2d-density-plot-subplots') |

Контентное моделирование
Наконец, мы хотим изучить алгоритм тематического моделирования для этого набора данных, чтобы увидеть, принесет ли он пользу и согласуется ли он с тем, что мы делаем для нашей функциональности текста обзора.
Мы поэкспериментируем с техникой скрытого семантического анализа (LSA) в моделировании. тематический.
- Генерация нашей матрицы терминов документа из текста обзора в матрицу функций TF-IDF.
- Модель LSA заменяет необработанные значения в матрице терминов документа оценкой TF-IDF.
- Выполните уменьшение размерности матрицы терминов документа с помощью усеченного SVD.
- Поскольку количество отделов равно 6, мы устанавливаем n_topics=6.
- Взяв argmax каждого текста обзора в этом массиве тем, вы получите предсказанные темы каждого текста обзора в данных. Затем мы можем отсортировать их по номеру каждой темы.
- Чтобы лучше понять каждый предмет, мы найдем три наиболее часто встречающихся слова в каждом предмете.
переиндексированные_данные = дф[«Просмотреть текст»] | |
tfidf_vectorizer = TfidfVectorizer(стоп_слова='английский', use_idf=Истинный, smooth_idf=Истинный) | |
переиндексированные_данные = переиндексированные_данные.ценности | |
document_term_matrix = tfidf_vectorizer.fit_transform(переиндексированные_данные) | |
n_topics = 6 | |
lsa_model = Усеченный СВД(n_components=n_topics) | |
lsa_topic_matrix = lsa_model.fit_transform(document_term_matrix) | |
деф get_keys(тема_матрица): | |
'' | |
возвращает целочисленный список предсказанной темы | |
категории для заданной матрицы темы | |
'' | |
ключи = тема_матрица.argmax(ось=1).список() | |
возвращаться ключи | |
деф keys_to_counts(ключи): | |
'' | |
возвращает кортеж категорий тем и их | |
сопровождающие величины для данного списка ключей | |
'' | |
count_pairs = Прилавок(ключи).Предметы() | |
категории = [вглядеться[0] за вглядеться в count_pairs] | |
считает = [вглядеться[1] за вглядеться в count_pairs] | |
возвращаться (категории, считает) | |
lsa_keys = get_keys(lsa_topic_matrix) | |
lsa_categories, lsa_counts = keys_to_counts(lsa_keys) | |
деф get_top_n_words(нет, ключи, document_term_matrix, tfidf_vectorizer): | |
'' | |
возвращает список из n_topic строк, где каждая строка содержит n наиболее распространенных | |
слова в прогнозируемой категории, в порядке | |
'' | |
top_word_indices = [] | |
за нить в аккуратный(n_topics): | |
temp_vector_sum = 0 | |
за я в аккуратный(тогда(ключи)): | |
если ключи[я] == нить: | |
temp_vector_sum += document_term_matrix[я] | |
temp_vector_sum = temp_vector_sum.массив() | |
top_n_word_indices = н.п..кувырок(н.п..сортировка аргументов(temp_vector_sum)[0][–нет:],0) | |
top_word_indices.добавить(top_n_word_indices) | |
top_words = [] | |
за нить в top_word_indices: | |
тема_слова = [] | |
за индекс в нить: | |
temp_word_vector = н.п..нули((1,document_term_matrix.форма[1])) | |
temp_word_vector[:,индекс] = 1 | |
слово = tfidf_vectorizer.inverse_transform(temp_word_vector)[0][0] | |
тема_слова.добавить(слово.кодировать('аски').декодировать('утф-8')) | |
top_words.добавить( » « .присоединиться(тема_слова)) | |
возвращаться top_words | |
top_n_words_lsa = get_top_n_words(3, lsa_keys, document_term_matrix, tfidf_vectorizer) | |
за я в аккуратный(тогда(top_n_words_lsa)): | |
Распечатать("Тема{}:" .формат(я+1), top_n_words_lsa[я]) |

top_3_words = get_top_n_words(3, lsa_keys, document_term_matrix, tfidf_vectorizer)
labels = ['Тема {}: \n'.format(i) + top_3_words[i] для i в lsa_categories]рис, топор = plt.subplots (figsize = (16,8))
ax.bar(lsa_categories, lsa_counts);
ax.set_xticks(lsa_categories);
ax.set_xticklabels (метки);
ax.set_ylabel('Количество текста отзыва');
ax.set_title('Подсчет тем LSA');
табл.показать();

Глядя на наиболее часто встречающиеся слова в каждом предмете, у нас возникает ощущение, что мы, возможно, не достигнем какой-либо степени разделения между предметными категориями. Другими словами, мы не могли разделить экзаменационные тексты по отделам, используя методы тематического моделирования.
Методы тематического моделирования имеют ряд важных ограничений. Начнем с того, что термин «тема» является несколько двусмысленным, и, возможно, теперь ясно, что тематические модели не будут давать очень детализированную текстовую классификацию для наших данных.