Обработка естественного языка (NLP) стала проще для Python

Упрощенная обработка естественного языка

Я всегда ищу новые инструменты, которые помогут мне упростить конвейеры обработки естественного языка, поэтому, когда я наткнулся на короткий видеоклип, демонстрирующий функциональные возможности Texthero, я понял, что должен сразу же его попробовать. Texthero разработан как оболочка Pandas, поэтому с ним проще, чем когда-либо, предварительно обрабатывать и анализировать текстовые серии Pandas. Я сразу же открыл документацию, открыл блокнот и загрузил пару тысяч потоков Reddit для анализа и тестирования новой библиотеки.

ПРИМЕЧАНИЕ. Библиотека Texthero все еще находится в стадии бета-тестирования! Могут быть ошибки, и конвейеры могут измениться. Я обнаружил ошибку в функциональности wordcloud и сообщил о ней. Это должно быть исправлено в ближайшем обновлении!

Обзор Texthero

При работе с кодом я рассмотрю их гораздо внимательнее, но для краткого обзора Texthero разбит на четыре функциональных модуля:

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

Модуль Предварительная обработка предназначен для эффективной очистки текстовых серий Pandas. В основном он использует Регулярные выражения (регулярное выражение) под капотом.

НЛП

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

"Представление"

Модуль Представление используется для создания векторов слов с использованием различных алгоритмов. Он также включает такие вещи, как анализ основных компонентов и kMeans. Он использует scikit-learn для TF-IDF и Count, а вложения загружаются предварительно вычисленными из языковых моделей.

"Визуализация"

Модуль Визуализация используется для визуализации представлений в точечной диаграмме или создания облаков слов. Этот модуль в настоящее время имеет только несколько функций и использует Plotly и WordCloud под капотом.

Ознакомьтесь с полным списком функций в документации!



Зависимости и данные

Хотя установка с использованием pip была простой, я столкнулся с конфликтом при попытке установить его в моей среде, в которой есть Apache Airflow, из-за проблемы с версией pandas. Кроме того, установка в новой среде заняла некоторое время, так как на сервере используется очень много других библиотек. Он загружает еще несколько вещей после первого импорта.

Для набора данных я использую PRAW для извлечения данных из Reddit. Прочтите эту статью, если вам нужно напомнить о PRAW.



!pip install texthero
import praw
import pandas as pd 
import texthero as hero
from config import cid, csec, ua #PRAW credentials

Обратите внимание, когда вы впервые импортируете Texthero, вы увидите, что он загружает несколько вещей из NLTK и Spacy:

Получение некоторых данных

Я извлекаю данные из подреддита Преподавание, чтобы узнать, сможем ли мы определить какие-либо темы, вызывающие беспокойство по поводу начала учебы осенью в Америке, страдающей от COVID.

#create a reddit connection
reddit = praw.Reddit(client_id= cid,
                     client_secret= csec,
                     user_agent= ua)
#list for df conversion
posts = []
#return 1000 new posts from teaching
new = reddit.subreddit('teaching').new(limit=1000)
#return the important attributes
for post in new:
    posts.append([post.title, post.score, post.num_comments, post.selftext, post.created, post.pinned, post.total_awards_received])
#create a dataframe
df = pd.DataFrame(posts,columns=['title', 'score', 'comments', 'post', 'created', 'pinned', 'total awards'])
#return top 3 df rows
df.head(3)

PRAW позволяет очень легко извлекать данные из Reddit и загружать их в фрейм данных pandas.
Обратите внимание, что я извлекаю 1000 новых сообщений из преподавания. Вывод фрейма данных при использовании df.head (3) будет выглядеть примерно так:

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

Настоящим преимуществом библиотеки texthero является ее упрощенный конвейер предварительной обработки. Не можете вспомнить синтаксис регулярного выражения? Texthero поможет вам! Просто вызовите метод. clean () и передайте серию фреймов данных:

df['clean_title'] = hero.clean(df['title'])

По умолчанию он запускает следующие семь функций при использовании clean ()

  1. fillna(s) Заменить неназначенные значения пустыми пробелами.
  2. lowercase(s) Весь текст в нижнем регистре.
  3. remove_digits() Удалите все блоки цифр.
  4. remove_punctuation() Удалить все строковые знаки пунктуации (! '# $% &' () * +, -. / :; ‹=›? @ [\] ^ _ `{|} ~).
  5. remove_diacritics() Удалите все акценты со строк.
  6. remove_stopwords() Удалите все стоп-слова.
  7. remove_whitespace() Удалите все пробелы между словами.

Индивидуальная очистка

Если по умолчанию не работает то, что необходимо, создать собственный конвейер очистки очень просто. Например, если я хочу сохранить стоп-слова и ограничить включенные слова, я могу закомментировать remove_stopwords и добавить texthero.preprocessing.stem () в конвейер. :

from texthero import preprocessing
#create a custom cleaning pipeline
custom_pipeline = [preprocessing.fillna
                   , preprocessing.lowercase
                   , preprocessing.remove_digits
                   , preprocessing.remove_punctuation
                   , preprocessing.remove_diacritics
                   #, preprocessing.remove_stopwords
                   , preprocessing.remove_whitespace
                   , preprocessing.stem]
#pass the custom_pipeline to the pipeline argument
df['clean_title'] = hero.clean(df['title'], pipeline = custom_pipeline)
df.head()

Обратите внимание, что custom_pipeline - это список функций предварительной обработки. Ознакомьтесь с документацией для получения полного списка функций предварительной обработки!

Проверка самых популярных слов

Проверка верхних слов - это всего лишь одна строка кода, и это то, что мне нравится делать, чтобы увидеть, есть ли дополнительные слова, которые я должен подумать о добавлении в список стоп-слов. В Texthero пока нет встроенных гистограмм, в нем есть только разброс, поэтому я буду использовать Plotly express, чтобы визуализировать верхние слова на гистограмме.

tw = hero.visualization.top_words(df['clean_title']).head(10)
import plotly.express as px
fig = px.bar(tw)
fig.show()
tw.head()

Добавление новых стоп-слов

Выделение слов и добавление « «(обратите внимание на это между учителями и учениками) к стоп-словам, чтобы дать мне больше уникальных слов. Стемминг уже был добавлен в настраиваемый конвейер, но необходимо добавить стоп-слова. Стоп-слова можно добавить в список стоп-слов, используя объединение двух списков:

from texthero import stopwords
default_stopwords = stopwords.DEFAULT
#add a list of stopwords to the stopwords
custom_stopwords = default_stopwords.union(set(["'"]))
#Call remove_stopwords and pass the custom_stopwords list
df['clean_title'] = hero.remove_stopwords(df['clean_title'], custom_stopwords)

Обратите внимание, что список custom_stopwords передается в hero.remove_stopwords (). Я визуализирую это заново и проверю результаты!

Результаты выглядят немного лучше после применения стемминга и дополнительных стоп-слов!

Строительство трубопровода

Благодаря Panda’s .pipe () объединить компоненты модуля Texthero вместе очень просто. Чтобы визуализировать заголовок, я собираюсь использовать Анализ основных компонентов для сжатия векторного пространства. Я также собираюсь запустить кластеризацию K-means, чтобы добавить цвета. Помните, что Texthero принимает Series в качестве входных данных и Series в качестве выходных данных, поэтому я могу настроить выход как новый столбец во фрейме данных.

#Add pca value to dataframe to use as visualization coordinates
df['pca'] = (
            df['clean_title']
            .pipe(hero.tfidf)
            .pipe(hero.pca)
   )
#Add k-means cluster to dataframe 
df['kmeans'] = (
            df['clean_title']
            .pipe(hero.tfidf)
            .pipe(hero.kmeans)
   )
df.head()

Кластеризация PCA и K-средних была применена с использованием всего нескольких строк кода! Теперь данные можно визуализировать с помощью hero.scatterplot ().

#generate scatter plot
hero.scatterplot(df, 'pca', color = 'kmeans', hover_data=['title'] )

Поскольку он использует Plotly под капотом, диаграмма рассеяния настолько интерактивна, насколько и следовало ожидать! При необходимости его можно увеличивать. Пришло время изучить визуализированные результаты и посмотреть, какие идеи можно получить!

Последние мысли

Хотя библиотека все еще находится в стадии бета-тестирования, я вижу многообещающее будущее для Texthero и надеюсь, что она получит заслуженную любовь. Это упрощает очистку и подготовку текста в фреймах данных Pandas. Я надеюсь, что будет добавлено еще несколько вариантов визуализации, но диаграмма разброса - отличное начало. Если вам интересно узнать больше об обработке естественного языка, ознакомьтесь с другими моими статьями, охватывающими некоторые базовые и расширенные темы.







Полный код

Спасибо за прочтение. Вот полный код:

#create a reddit connection
reddit = praw.Reddit(client_id= cid,
                     client_secret= csec,
                     user_agent= ua)
#list for df conversion
posts = []
#return 1000 new posts from teaching
new = reddit.subreddit('teaching').new(limit=1000)
#return the important attributes
for post in new:
    posts.append([post.title, post.score, post.num_comments, post.selftext, post.created, post.pinned, post.total_awards_received])
#create a dataframe
df = pd.DataFrame(posts,columns=['title', 'score', 'comments', 'post', 'created', 'pinned', 'total awards'])
#return top 3 df rows
df.head(3)
from texthero import preprocessing
custom_pipeline = [preprocessing.fillna
                   , preprocessing.lowercase
                   , preprocessing.remove_digits
                   , preprocessing.remove_punctuation
                   , preprocessing.remove_diacritics
                   , preprocessing.remove_stopwords
                   , preprocessing.remove_whitespace
                   , preprocessing.stem]
df['clean_title'] = hero.clean(df['title'], pipeline = custom_pipeline)
df.head()
from texthero import stopwords
default_stopwords = stopwords.DEFAULT
custom_stopwords = default_stopwords.union(set(["'"]))
df['clean_title'] = hero.remove_stopwords(df['clean_title'], custom_stopwords)
hero.visualization.top_words(df['clean_title'])
tw = hero.visualization.top_words(df['clean_title']).head(10)
import plotly.express as px
fig = px.bar(tw)
fig.show()
df['pca'] = (
            df['clean_title']
            .pipe(hero.tfidf)
            .pipe(hero.pca)
   )
df['kmeans'] = (
            df['clean_title']
            .pipe(hero.tfidf)
            .pipe(hero.kmeans)
   )
hero.scatterplot(df, 'pca', color = 'kmeans', hover_data=['title'] )

Благодарю вас!

- Эрик Клеппен