Как выполнить анализ настроений в Python 3 с использованием набора естественных языков (NLTK)

_Автор выбрал фонд Open Internet / Free Speech для получения пожертвования в рамках https://do.co/w4do-cta. [Писать для DOnations] программа.

Вступление

Большой объем данных, генерируемых сегодня, - это unstructured, который требует обработки для генерации идей. Некоторыми примерами неструктурированных данных являются новостные статьи, посты в социальных сетях и история поиска. Процесс анализа естественного языка и его осмысления относится к области обработки естественного языка (NLP). Анализ настроений является распространенной задачей НЛП, которая включает в себя классификацию текстов или частей текстов в заранее определенное мнение. Вы будете использовать The Natural Language Toolkit (NLTK), обычно используемую библиотеку NLP в Python, для анализа текстовых данных.

В этом руководстве вы подготовите набор образцов образцов твитов из пакета NLTK для NLP с различными методами очистки данных. Как только набор данных будет готов к обработке, вы обучите модель предварительно классифицированным твитам и будете использовать модель, чтобы классифицировать образцы твитов на негативные и позитивные настроения.

В этой статье предполагается, что вы знакомы с основами Python (см. Наш https://www.digitalocean.com/community/tutorial_series/how-to-code-in-python. -3 [Как писать код в серии Python 3]), в первую очередь с использованием структур данных, классов и методов. В этом руководстве предполагается, что у вас нет опыта работы с NLP и + nltk +, хотя некоторые знания об этом являются дополнительным преимуществом.

Предпосылки

Шаг 1 - Установка NLTK и загрузка данных

Вы будете использовать пакет NLTK в Python для всех задач НЛП в этом руководстве. На этом этапе вы установите NLTK и загрузите образцы твитов, которые вы будете использовать для обучения и тестирования своей модели.

Сначала install пакет NLTK с помощью менеджера пакетов + pip +:

pip install nltk==3.3

В этом руководстве будут использоваться образцы твитов, которые входят в пакет NLTK. Сначала запустите интерактивный сеанс Python, выполнив следующую команду:

python3

Затем импортируйте модуль + nltk + в интерпретатор python.

import nltk

Загрузите примеры твитов из пакета NLTK:

nltk.download('twitter_samples')

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

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

Если вы хотите использовать свой собственный набор данных, вы можете собирать твиты из определенного периода времени, пользователя или хэштега, используя Twitter API.

Теперь, когда вы импортировали NLTK и загрузили примеры твитов, выйдите из интерактивного сеанса, введя + exit () +. Вы готовы импортировать твиты и начать обработку данных.

Шаг 2 - Токенизация данных

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

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

Для начала создайте новый файл + .py + для хранения вашего скрипта. В этом руководстве будет использоваться + nlp_test.py +:

nano nlp_test.py

В этом файле вы сначала импортируете + twitter_samples +, чтобы вы могли работать с этими данными:

nlp_test.py

from nltk.corpus import twitter_samples

Это импортирует три набора данных из NLTK, которые содержат различные твиты для обучения и тестирования модели:

  • + негативные твиты.json: 5000 твитов с негативным настроением

  • + positive tweets.json: 5000 твитов с позитивными настроениями

  • + твиты.20150430-223406.json +: 20000 твитов без настроений

Затем создайте переменные для + positive_tweets +, + positive_tweets + и + text +:

nlp_test.py

from nltk.corpus import twitter_samples

+ Strings () + метод + twitter_samples + будет печатать все твиты в наборе данных в виде строк. Установка различных коллекций твитов в качестве переменной облегчит обработку и тестирование.

Перед использованием токенизатора в NLTK вам необходимо скачать дополнительный ресурс + punkt +. Модуль + punkt + - это предварительно обученная модель, которая помогает вам токенизировать слова и предложения. Например, эта модель знает, что имя может содержать точку (например, «S. Daityari ») и наличие этого периода в предложении не обязательно заканчивает его. Сначала запустите интерактивный сеанс Python:

python3

Выполните следующие команды в сеансе, чтобы загрузить ресурс + punkt +:

import nltk
nltk.download('punkt')

После завершения загрузки вы готовы использовать токенизаторы NLTK. NLTK предоставляет токенайзер по умолчанию для твитов с методом + .tokenized () +. Добавьте строку для создания объекта, который токенизирует набор данных + positive_tweets.json +:

nlp_test.py

from nltk.corpus import twitter_samples

positive_tweets = twitter_samples.strings('positive_tweets.json')
negative_tweets = twitter_samples.strings('negative_tweets.json')
text = twitter_samples.strings('tweets.20150430-223406.json')

Если вы хотите протестировать скрипт, чтобы увидеть метод + .tokenized + в действии, добавьте выделенный контент в ваш скрипт + nlp_test.py +. Это токенизирует один твит из набора данных + positive_tweets.json +:

nlp_test.py

from nltk.corpus import twitter_samples

positive_tweets = twitter_samples.strings('positive_tweets.json')
negative_tweets = twitter_samples.strings('negative_tweets.json')
text = twitter_samples.strings('tweets.20150430-223406.json')
tweet_tokens = twitter_samples.tokenized('positive_tweets.json')

Сохраните и закройте файл и запустите скрипт:

python3 nlp_test.py

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

Output['#FollowFriday',
'@France_Inte',
'@PKuchly57',
'@Milipol_Paris',
'for',
'being',
'top',
'engaged',
'members',
'in',
'my',
'community',
'this',
'week',
':)']

Здесь метод + .tokenized () + возвращает специальные символы, такие как + @ + и + _ +. Эти символы будут удалены с помощью регулярных выражений позже в этом руководстве.

Теперь, когда вы увидели, как работает метод + .tokenized () +, обязательно закомментируйте или удалите последнюю строку для печати токенизированного твита из скрипта, добавив + # + в начало линия:

nlp_test.py

from nltk.corpus import twitter_samples

positive_tweets = twitter_samples.strings('positive_tweets.json')
negative_tweets = twitter_samples.strings('negative_tweets.json')
text = twitter_samples.strings('tweets.20150430-223406.json')
tweet_tokens = twitter_samples.tokenized('positive_tweets.json')

#print(tweet_tokens[0])

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

Шаг 3 - Нормализация данных

Слова имеют разные формы - например, «беги», «беги» и «беги» - это разные формы одного и того же глагола «беги». В зависимости от требований вашего анализа, все эти версии, возможно, придется преобразовать в одну и ту же форму, «запустить». Normalization в НЛП - это процесс преобразования слова в его каноническую форму.

Нормализация помогает группировать слова с одинаковым значением, но разными формами. Без нормализации слова «беги», «беги» и «беги» будут рассматриваться как разные слова, даже если вы захотите, чтобы они рассматривались как одно и то же слово. В этом разделе вы изучите stemming и lemmaization, которые являются двумя популярными методами нормализации.

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

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

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

python3

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

import nltk
nltk.download('wordnet')
nltk.download('averaged_perceptron_tagger')

http://www.nltk.org/howto/wordnet.html [+ wordnet +] - это лексическая база данных для английского языка, которая помогает сценарию определить базовое слово. Вам нужен ресурс + averaged_perceptron_tagger +, чтобы определить контекст слова в предложении.

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

from nltk.tag import pos_tag
from nltk.corpus import twitter_samples

tweet_tokens = twitter_samples.tokenized('positive_tweets.json')
print(pos_tag(tweet_tokens[0]))

Вот вывод функции + pos_tag +.

Output[('#FollowFriday', 'JJ'),
('@France_Inte', 'NNP'),
('@PKuchly57', 'NNP'),
('@Milipol_Paris', 'NNP'),
('for', 'IN'),
('being', 'VBG'),
('top', 'JJ'),
('engaged', 'VBN'),
('members', 'NNS'),
('in', 'IN'),
('my', 'PRP$'),
('community', 'NN'),
('this', 'DT'),
('week', 'NN'),
(':)', 'NN')]

Из списка тегов приведен список наиболее распространенных элементов и их значения:

  • + NNP +: существительное, собственно, единственное число

  • + NN +: существительное, общее, единственное или массовое

  • + IN +: Предлог или соединение, подчинение

  • + VBG +: глагол, герунд или настоящее причастие

  • + VBN +: глагол, причастие прошлого

В общем случае, если тег начинается с + NN +, слово является существительным, а если оно начинается с + VB +, слово является глаголом. После просмотра тегов выйдите из сеанса Python, введя + exit () +.

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

Обновите файл + nlp_test.py + следующей функцией, которая лемматизирует предложение:

nlp_test.py

...

from nltk.tag import pos_tag
from nltk.stem.wordnet import WordNetLemmatizer

def lemmatize_sentence(tokens):
   lemmatizer = WordNetLemmatizer()
   lemmatized_sentence = []
   for word, tag in pos_tag(tokens):
       if tag.startswith('NN'):
           pos = 'n'
       elif tag.startswith('VB'):
           pos = 'v'
       else:
           pos = 'a'
       lemmatized_sentence.append(lemmatizer.lemmatize(word, pos))
   return lemmatized_sentence

print(lemmatize_sentence(tweet_tokens[0]))

Этот код импортирует класс + WordNetLemmatizer + и инициализирует его в переменную + lemmatizer +.

Функция + lemmatize_sentence + сначала получает тег позиции каждого токена твита. В операторе + if +, если тег начинается с + NN +, токен назначается как существительное. Аналогично, если тег начинается с + VB +, токен назначается как глагол.

Сохраните и закройте файл и запустите скрипт:

python3 nlp_test.py

Вот вывод:

Output['#FollowFriday',
'@France_Inte',
'@PKuchly57',
'@Milipol_Paris',
'for',
'be',
'top',
'engage',
'member',
'in',
'my',
'community',
'this',
'week',
':)']

Вы заметите, что глагол + Being + меняется на свою корневую форму, + be +, а существительное + members + меняется на + member +. Прежде чем продолжить, закомментируйте последнюю строку, которая печатает образец твита из скрипта.

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

Шаг 4 - Удаление шума из данных

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

Шум характерен для каждого проекта, поэтому шум в одном проекте может не совпадать с другим проектом. Например, наиболее распространенные слова в языке называются stop words. Некоторыми примерами стоп-слов являются «есть», «the» и «a». Они, как правило, не имеют отношения к языку обработки, если только конкретный вариант использования не гарантирует их включение.

В этом руководстве вы будете искать use регулярные выражения в Python для поиска и удаления этих элементов:

  • * Гиперссылки * - Все гиперссылки в Twitter преобразуются в сокращатель URL-адреса t.co. Следовательно, хранение их в текстовой обработке не добавит ценности для анализа.

  • * Twitter обрабатывает ответы *. Этим именам пользователей Twitter предшествует символ + @ +, который не несет никакого значения.

  • * Знаки пунктуации и специальные символы * - хотя они часто обеспечивают контекст для текстовых данных, этот контекст часто трудно обрабатывать. Для простоты вы удалите все знаки препинания и специальные символы из твитов.

Чтобы удалить гиперссылки, необходимо сначала найти подстроку, которая соответствует URL-адресу, начинающемуся с + http: // + или + https: // +, за которым следуют буквы, цифры или специальные символы. Как только шаблон сопоставлен, метод + .sub () + заменяет его пустой строкой.

Поскольку мы нормализуем словоформы внутри функции + remove_noise () +, вы можете закомментировать функцию + lemmatize_sentence () + из скрипта.

Добавьте следующий код в файл + nlp_test.py +, чтобы удалить шум из набора данных:

nlp_test.py

...

import re, string

def remove_noise(tweet_tokens, stop_words = ()):

   cleaned_tokens = []

   for token, tag in pos_tag(tweet_tokens):
       token = re.sub('http[s]?://(?:[a-zA-Z]|[0-9]|[$-_@.&+#]|[!*\(\),]|'\
                      '(?:%[0-9a-fA-F][0-9a-fA-F]))+','', token)
       token = re.sub("(@[A-Za-z0-9_]+)","", token)

       if tag.startswith("NN"):
           pos = 'n'
       elif tag.startswith('VB'):
           pos = 'v'
       else:
           pos = 'a'

       lemmatizer = WordNetLemmatizer()
       token = lemmatizer.lemmatize(token, pos)

       if len(token) > 0 and token not in string.punctuation and token.lower() not in stop_words:
           cleaned_tokens.append(token.lower())
   return cleaned_tokens

Этот код создает функцию + remove_noise () +, которая удаляет шум и включает нормализацию и лемматизацию, упомянутые в предыдущем разделе. Код принимает два аргумента: жетоны твита и кортеж стоп-слов.

Затем код использует цикл для удаления шума из набора данных. Чтобы удалить гиперссылки, код сначала ищет подстроку, которая соответствует URL-адресу, начинающемуся с + http: // + или + https: // +, за которым следуют буквы, цифры или специальные символы. Как только шаблон сопоставлен, метод + .sub () + заменяет его пустой строкой или + '' +.

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

Наконец, вы можете удалить пунктуацию, используя библиотеку + string +.

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

Для загрузки этого ресурса выполните следующую команду из интерактивного сеанса Python:

nltk.download('stopwords')

После загрузки ресурса выйдите из интерактивного сеанса.

Вы можете использовать метод + .words () +, чтобы получить список стоп-слов на английском языке. Чтобы проверить функцию, давайте запустим ее в нашем примере твита. Добавьте следующие строки в конец файла + nlp_test.py +:

nlp_test.py

...
from nltk.corpus import stopwords
stop_words = stopwords.words('english')

print(remove_noise(tweet_tokens[0], stop_words))

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

Output['#followfriday', 'top', 'engage', 'member', 'community', 'week', ':)']

Обратите внимание, что функция удаляет все упоминания + @ +, останавливает слова и преобразует слова в нижний регистр.

Прежде чем перейти к упражнению по моделированию на следующем шаге, используйте функцию + remove_noise () + для очистки положительных и отрицательных твитов. Закомментируйте строку, чтобы напечатать вывод + remove_noise () + в примере твита, и добавьте следующее в скрипт + nlp_test.py +:

nlp_test.py

...
from nltk.corpus import stopwords
stop_words = stopwords.words('english')

print(remove_noise(tweet_tokens[0], stop_words))

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

nlp_test.py

...
print(positive_tweet_tokens[500])
print(positive_cleaned_tokens_list[500])

Сохраните и закройте файл и запустите скрипт. Из вывода вы увидите, что пунктуация и ссылки были удалены, а слова были преобразованы в нижний регистр.

Output['Dang', 'that', 'is', 'some', 'rad', '@AbzuGame', '#fanart', '!', ':D', 'https://t.co/bI8k8tb9ht']
['dang', 'rad', '#fanart', ':d']

Есть определенные проблемы, которые могут возникнуть во время предварительной обработки текста. Например, слова без пробелов («iLoveYou») будут рассматриваться как единое целое, и такие слова могут быть затруднены. Кроме того, «Привет», «Hii» и «Hiiiii» будут обрабатываться сценарием по-разному, если только вы не напишите что-то конкретное для решения проблемы. Это обычно для точной настройки процесса удаления шума для ваших конкретных данных.

Теперь, когда вы увидели функцию + remove_noise () + в действии, обязательно закомментируйте или удалите последние две строки из скрипта, чтобы вы могли добавить к нему больше:

nlp_test.py

...
print(positive_tweet_tokens[500])
print(positive_cleaned_tokens_list[500])

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

Шаг 5 - Определение плотности слов

Самая основная форма анализа текстовых данных - вывести частоту слова. Один твит слишком мал для сущности, чтобы определить распределение слов, поэтому анализ частоты слов будет проводиться на всех положительных твитах.

В следующем фрагменте определяется a генераторная функция с именем + get_all_words +, которая принимает список твитов в качестве аргумента, чтобы предоставить список слов во всех жетоны твитов присоединились. Добавьте следующий код в ваш файл + nlp_test.py +:

nlp_test.py

...

def get_all_words(cleaned_tokens_list):
   for tokens in cleaned_tokens_list:
       for token in tokens:
           yield token

all_pos_words = get_all_words(positive_cleaned_tokens_list)

Теперь, когда вы собрали все слова в примере твитов, вы можете узнать, какие слова являются наиболее распространенными, используя http://www.nltk.org/api/nltk.html?highlight=freqdist [+ FreqDist +]. класс НЛТК. Добавление следующего кода в файл + nlp_test.py +:

nlp_test.py

from nltk import FreqDist

freq_dist_pos = FreqDist(all_pos_words)
print(freq_dist_pos.most_common(10))

Метод + .most_common () + перечисляет слова, которые чаще всего встречаются в данных. Сохраните и закройте файл после внесения этих изменений.

Когда вы запустите файл сейчас, вы найдете наиболее распространенные термины в данных:

Output[(':)', 3691),
(':-)', 701),
(':d', 658),
('thanks', 388),
('follow', 357),
('love', 333),
('...', 290),
('good', 283),
('get', 263),
('thank', 253)]

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

Подводя итог, вы извлекли твиты из + nltk +, токенизировали, нормализовали и очистили твиты для использования в модели. Наконец, вы также посмотрели на частоты токенов в данных и проверили частоты первых десяти токенов.

На следующем этапе вы подготовите данные для анализа настроений.

Шаг 6 - Подготовка данных для модели

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

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

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

На этапе подготовки данных вы подготовите данные для анализа настроений, преобразовав токены в словарную форму, а затем разделите данные для обучения и тестирования.

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

Сначала вы подготовите данные для подачи в модель. Вы будете использовать Naive Bayes классификатор в NLTK для выполнения упражнения по моделированию. Обратите внимание, что для модели требуется не просто список слов в твите, а словарь Python со словами в качестве ключей и + True + в качестве значений. Следующая функция выполняет функцию генератора для изменения формата очищенных данных.

Добавьте следующий код, чтобы преобразовать твиты из списка очищенных токенов в словари с ключами в качестве токенов и + True + в качестве значений. Соответствующие словари хранятся в + positive_tokens_for_model + и + positive_tokens_for_model +.

nlp_test.py

...
def get_tweets_for_model(cleaned_tokens_list):
   for tweet_tokens in cleaned_tokens_list:
       yield dict([token, True] for token in tweet_tokens)

positive_tokens_for_model = get_tweets_for_model(positive_cleaned_tokens_list)
negative_tokens_for_model = get_tweets_for_model(negative_cleaned_tokens_list)

Разделение набора данных для обучения и тестирования модели

Затем вам нужно подготовить данные для обучения класса + NaiveBayesClassifier +. Добавьте следующий код в файл для подготовки данных:

nlp_test.py

...
import random

positive_dataset = [(tweet_dict, "Positive")
                    for tweet_dict in positive_tokens_for_model]

negative_dataset = [(tweet_dict, "Negative")
                    for tweet_dict in negative_tokens_for_model]

dataset = positive_dataset + negative_dataset

random.shuffle(dataset)

train_data = dataset[:7000]
test_data = dataset[7000:]

Этот код прикрепляет ярлык + Positive + или + Negative + к каждому твиту. Затем он создает + набор данных +, объединяя положительные и отрицательные твиты.

По умолчанию данные содержат все положительные твиты, за которыми следуют все отрицательные твиты в последовательности. При обучении модели вы должны предоставить образец ваших данных, который не содержит смещения. Чтобы избежать смещения, вы добавили код для случайного расположения данных, используя + .shuffle () + метод + random +.

Наконец, код разбивает перетасованные данные на соотношение 70:30 для обучения и тестирования соответственно. Поскольку количество твитов равно 10000, вы можете использовать первые 7000 твитов из перемешанного набора данных для обучения модели и финальные 3000 для тестирования модели.

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

Шаг 7 - Построение и тестирование модели

Наконец, вы можете использовать класс + NaiveBayesClassifier + для построения модели. Используйте метод + .train () + для обучения модели и метод + .accuracy () + для проверки модели на данных тестирования.

nlp_test.py

...
from nltk import classify
from nltk import NaiveBayesClassifier
classifier = NaiveBayesClassifier.train(train_data)

print("Accuracy is:", classify.accuracy(classifier, test_data))

print(classifier.show_most_informative_features(10))

Сохраните, закройте и выполните файл после добавления кода. Вывод кода будет следующим:

OutputAccuracy is: 0.9956666666666667

Most Informative Features
                     :( = True           Negati : Positi =   2085.6 : 1.0
                     :) = True           Positi : Negati =    986.0 : 1.0
                welcome = True           Positi : Negati =     37.2 : 1.0
                 arrive = True           Positi : Negati =     31.3 : 1.0
                    sad = True           Negati : Positi =     25.9 : 1.0
               follower = True           Positi : Negati =     21.1 : 1.0
                    bam = True           Positi : Negati =     20.7 : 1.0
                   glad = True           Positi : Negati =     18.1 : 1.0
                    x15 = True           Negati : Positi =     15.9 : 1.0
              community = True           Positi : Negati =     14.1 : 1.0

Точность определяется как процент твитов в наборе данных тестирования, для которого модель могла правильно предсказать настроение. Точность 99,5% на тестовом наборе довольно хорошая.

В таблице, которая показывает наиболее информативные функции, каждая строка в выходных данных показывает соотношение вхождения токена в твитах с положительными и отрицательными тегами в наборе обучающих данных. Первая строка в данных означает, что во всех твитах, содержащих токен : (, отношение твитов с отрицательным и положительным составом было от + + 2085,6 + до + 1 + . Интересно, что, похоже, в положительных наборах данных был один токен с `+: (+. Вы можете видеть, что два верхних отличительных элемента в тексте - это смайлики. Кроме того, такие слова, как + sad +, приводят к негативным настроениям, тогда как + welcome + и + glad + ассоциируются с позитивными настроениями.

Далее вы можете проверить, как модель работает на случайных твиттах из Twitter. Добавьте этот код в файл:

nlp_test.py

...
from nltk.tokenize import word_tokenize

custom_tweet = "I ordered just once from TerribleCo, they screwed up, never used the app again."

custom_tokens = remove_noise(word_tokenize(custom_tweet))

print(classifier.classify(dict([token, True] for token in custom_tokens)))

Этот код позволит вам тестировать пользовательские твиты, обновляя строку, связанную с переменной + custom_tweet +. Сохраните и закройте файл после внесения этих изменений.

Запустите скрипт для анализа пользовательского текста. Вот вывод для пользовательского текста в примере:

Output'Negative'

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

nlp_test.py

...
custom_tweet = ''

Вот вывод:

Output'Positive'

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

nlp_test.py

...
custom_tweet = ''

Вот вывод:

Output'Positive'

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

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

Шаг 8 - Очистка кода (необязательно)

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

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

  • Все функции должны быть определены после импорта.

  • Все операторы в файле должны находиться в условии + if name ==" main ": +. Это гарантирует, что операторы не будут выполнены, если вы импортируете функции файла в другой файл.

Мы также удалим закомментированный код, следуя инструкции, вместе с функцией + lemmatize_sentence +, так как лемматизация завершается новой функцией + remove_noise +.

Вот чистая версия + nlp test.py:

from nltk.stem.wordnet import WordNetLemmatizer
from nltk.corpus import twitter_samples, stopwords
from nltk.tag import pos_tag
from nltk.tokenize import word_tokenize
from nltk import FreqDist, classify, NaiveBayesClassifier

import re, string, random

def remove_noise(tweet_tokens, stop_words = ()):

   cleaned_tokens = []

   for token, tag in pos_tag(tweet_tokens):
       token = re.sub('http[s]?://(?:[a-zA-Z]|[0-9]|[$-_@.&+#]|[!*\(\),]|'\
                      '(?:%[0-9a-fA-F][0-9a-fA-F]))+','', token)
       token = re.sub("(@[A-Za-z0-9_]+)","", token)

       if tag.startswith("NN"):
           pos = 'n'
       elif tag.startswith('VB'):
           pos = 'v'
       else:
           pos = 'a'

       lemmatizer = WordNetLemmatizer()
       token = lemmatizer.lemmatize(token, pos)

       if len(token) > 0 and token not in string.punctuation and token.lower() not in stop_words:
           cleaned_tokens.append(token.lower())
   return cleaned_tokens

def get_all_words(cleaned_tokens_list):
   for tokens in cleaned_tokens_list:
       for token in tokens:
           yield token

def get_tweets_for_model(cleaned_tokens_list):
   for tweet_tokens in cleaned_tokens_list:
       yield dict([token, True] for token in tweet_tokens)

if __name__ == "__main__":

   positive_tweets = twitter_samples.strings('positive_tweets.json')
   negative_tweets = twitter_samples.strings('negative_tweets.json')
   text = twitter_samples.strings('tweets.20150430-223406.json')
   tweet_tokens = twitter_samples.tokenized('positive_tweets.json')[0]

   stop_words = stopwords.words('english')

   positive_tweet_tokens = twitter_samples.tokenized('positive_tweets.json')
   negative_tweet_tokens = twitter_samples.tokenized('negative_tweets.json')

   positive_cleaned_tokens_list = []
   negative_cleaned_tokens_list = []

   for tokens in positive_tweet_tokens:
       positive_cleaned_tokens_list.append(remove_noise(tokens, stop_words))

   for tokens in negative_tweet_tokens:
       negative_cleaned_tokens_list.append(remove_noise(tokens, stop_words))

   all_pos_words = get_all_words(positive_cleaned_tokens_list)

   freq_dist_pos = FreqDist(all_pos_words)
   print(freq_dist_pos.most_common(10))

   positive_tokens_for_model = get_tweets_for_model(positive_cleaned_tokens_list)
   negative_tokens_for_model = get_tweets_for_model(negative_cleaned_tokens_list)

   positive_dataset = [(tweet_dict, "Positive")
                        for tweet_dict in positive_tokens_for_model]

   negative_dataset = [(tweet_dict, "Negative")
                        for tweet_dict in negative_tokens_for_model]

   dataset = positive_dataset + negative_dataset

   random.shuffle(dataset)

   train_data = dataset[:7000]
   test_data = dataset[7000:]

   classifier = NaiveBayesClassifier.train(train_data)

   print("Accuracy is:", classify.accuracy(classifier, test_data))

   print(classifier.show_most_informative_features(10))

   custom_tweet = "I ordered just once from TerribleCo, they screwed up, never used the app again."

   custom_tokens = remove_noise(word_tokenize(custom_tweet))

   print(custom_tweet, classifier.classify(dict([token, True] for token in custom_tokens)))

Заключение

Это руководство познакомило вас с базовой моделью анализа настроений с использованием библиотеки + nltk + в Python 3. Сначала вы выполнили предварительную обработку твитов, используя токены, нормализуя слова и удаляя шумы. Затем вы визуализировали часто встречающиеся элементы в данных. Наконец, вы создали модель, чтобы связать твиты с определенным настроением.

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

Related