Пошаговое руководство по проведению анализа настроений

часть 1: предварительная обработка текстовых данных

По оценкам, 80% мировых данных неструктурированы. Таким образом, получение информации из неструктурированных данных является важной частью анализа данных. Анализ текста - это процесс получения ценной информации из неструктурированных текстовых данных, а анализ тональности - один из претендентов на интеллектуальный анализ текста. Он использует методы обработки естественного языка и машинного обучения для понимания и классификации субъективных эмоций на основе текстовых данных. В бизнес-среде анализ настроений широко используется для понимания отзывов клиентов, обнаружения спама в электронных письмах и т. Д. Эта статья является первой частью учебного пособия, которое знакомит с конкретными методами, используемыми для проведения анализа настроений с помощью Python. Чтобы лучше проиллюстрировать процедуры, я буду использовать один из моих проектов в качестве примера, в котором я провожу анализ настроений в отношении новостей о будущих ценах на нефть марки WTI. Я представлю важные шаги вместе с соответствующим кодом Python.

Некоторая справочная информация

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

1, сбор данных: парсинг новостных статей

2, предварительная обработка текстовых данных (эта статья)

3, векторизация текста: TFIDF

4, анализ настроений с логистической регрессией

5, разверните модель в Heroku с помощью веб-приложения python flask.

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

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

Я использую инструменты из NLTK, Spacy и некоторые регулярные выражения для предварительной обработки новостных статей. Чтобы импортировать библиотеки и использовать готовые модели в Spacy, вы можете использовать следующий код:

import spacy
import nltk
# Initialize spacy ‘en’ model, keeping only component needed for lemmatization and creating an engine:
nlp = spacy.load(‘en’, disable=[‘parser’, ‘ner’])

После этого я использую панды для чтения данных:

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

Токенизация

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

В качестве примера возьмем первую новостную статью в моем наборе данных:

Вы можете использовать токенизатор NLTK:

Или вы можете использовать Spacy, помните, что NLP - это движок Spacy, определенный выше:

После токенизации каждая новостная статья преобразуется в список слов, символов, цифр и знаков препинания. Вы также можете указать, хотите ли вы преобразовать каждое слово в нижний регистр. Следующим шагом будет удаление ненужной информации. Например, символы, цифры, знаки препинания. Я буду использовать spacy в сочетании с регулярным выражением, чтобы удалить их.

import re
#tokenization and remove punctuations
words = [str(token) for token in nlp(text) if not token.is_punct] 
#remove digits and other symbols except "@"--used to remove email
words = [re.sub(r"[^A-Za-z@]", "", word) for word in words]
#remove websites and email address
words = [re.sub(r”\S+com”, “”, word) for word in words]
words = [re.sub(r”\S+@\S+”, “”, word) for word in words]
#remove empty spaces 
words = [word for word in words if word!=’ ‘]

После применения преобразований, описанных выше, исходная новостная статья выглядит так:

Запрещенные слова

После некоторого преобразования новостная статья становится намного чище, но мы по-прежнему видим некоторые слова, которые нам не нужны, например, и, мы и т. Д. Следующим шагом является удаление бесполезных слов, а именно стоп-слов. Стоп-слова - это слова, которые часто встречаются во многих статьях, но не имеют значимого значения. Примеры игнорируемых слов: I, the, a, of. Это слова, которые не будут мешать пониманию статей, если их удалить. Чтобы удалить стоп-слова, мы можем импортировать стоп-слова из библиотеки NLTK. Кроме того, я также включаю другие списки стоп-слов, которые широко используются в экономическом анализе, включая даты и время, более общие слова, не имеющие экономического смысла, и т. Д. Вот как я составляю список стоп-слов:

#import other lists of stopwords
with open(‘StopWords_GenericLong.txt’, ‘r’) as f:
 x_gl = f.readlines()
with open(‘StopWords_Names.txt’, ‘r’) as f:
 x_n = f.readlines()
with open(‘StopWords_DatesandNumbers.txt’, ‘r’) as f:
 x_d = f.readlines()
#import nltk stopwords
stopwords = nltk.corpus.stopwords.words(‘english’)
#combine all stopwords
[stopwords.append(x.rstrip()) for x in x_gl][stopwords.append(x.rstrip()) for x in x_n][stopwords.append(x.rstrip()) for x in x_d]
#change all stopwords into lowercase
stopwords_lower = [s.lower() for s in stopwords]

а затем исключите стоп-слова из новостных статей:

words = [word.lower() for word in words if word.lower() not in stopwords_lower]

Применительно к предыдущему примеру это выглядит так:

Лемматизация

Удалив игнорируемые слова, а также символы, цифры и знаки препинания, каждая новостная статья превратится в список значимых слов. Однако, чтобы подсчитать появление каждого слова, важно удалить грамматическое время и преобразовать каждое слово в его исходную форму. Например, если мы хотим подсчитать, сколько раз слово «открытый» появляется в новостной статье, нам нужно подсчитать появление слов «открыто», «открывается», «открыто». Таким образом, лемматизация - важный этап преобразования текста. Еще один способ преобразования слов в исходную форму называется корчеванием. Вот разница между ними:

Лемматизация - это включение слова в его исходную лемму, а выделение корней - это получение лингвистического корня слова. Я предпочитаю лемматизацию стеммингу, потому что после стемминга некоторые слова становятся трудными для понимания. Для целей интерпретации лемма лучше, чем лингвистический корень.

Как показано выше, лемматизацию очень легко реализовать с помощью Spacy, где я вызываю функцию .lemma_ из spacy в начале. После лемматизации каждая новостная статья преобразуется в список слов в исходной форме. Новостная статья теперь изменилась на это:

Кратко опишите шаги

Давайте подытожим шаги функции и применим ее ко всем статьям:

def text_preprocessing(str_input): 
     #tokenization, remove punctuation, lemmatization
     words=[token.lemma_ for token in nlp(str_input) if not         token.is_punct]
 
     # remove symbols, websites, email addresses 
     words = [re.sub(r”[^A-Za-z@]”, “”, word) for word in words] 
     words = [re.sub(r”\S+com”, “”, word) for word in words]
     words = [re.sub(r”\S+@\S+”, “”, word) for word in words] 
     words = [word for word in words if word!=’ ‘]
     words = [word for word in words if len(word)!=0] 
 
     #remove stopwords     
     words=[word.lower() for word in words if word.lower() not in     stopwords_lower]
     #combine a list into one string   
     string = “ “.join(words)
     return string

Вышеупомянутая функция text_preprocessing () объединяет все шаги предварительной обработки текста, вот вывод с первой новостной статьей:

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

import random
index = random.randint(0, df.shape[0])
text_preprocessing(df.iloc[index][‘Body’])

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

Если все выглядит хорошо, вы можете применить эту функцию ко всем новостным статьям:

df[‘news_cleaned’]=df[‘Body’].apply(text_preprocessing)
df[‘subject_cleaned’]=df[‘Subject’].apply(text_preprocessing)

Некоторые замечания

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

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

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