Автор оригинала: Rodolfo Ferro.
ОПИСАНИЕ: В этой статье мы будем:
- Извлеките данные Twitter с помощью tweepy и узнайте, как обращаться с ними с помощью панд.
- Сделайте некоторые базовые статистические данные и визуализации с помощью numpy, matplotlib и seaborn.
- Сделайте анализ настроений извлеченных твитов (Трампа) с помощью textblob.
Фу! Давненько я не писал ничего хорошего. Я надеюсь, что вы найдете это немного полезным и/или интересным. Это основано на семинаре, который я преподавал в Мехико . Я объясню весь пост вместе с кодом самым простым из возможных способов. Во всяком случае, оригинальный пост в блоге можно найти в моем блоге , а весь код можно найти в репо, которое я использовал для этого семинара .
Прежде всего, нам нужно установить Python . Я почти уверен, что весь код будет работать на Python 2.7, но я буду использовать Python 3.6. Я настоятельно рекомендую установить Anaconda , который является очень полезным дистрибутивом Python для управления пакетами, который включает в себя множество полезных инструментов, таких как Записные книжки Jupyter . Я объясню код, предполагая, что мы будем использовать записную книжку Jupyter, но код будет выполняться, если вы программируете простой скрипт из своего текстового редактора. Вам просто нужно будет адаптировать его (это не сложно).
Требования, которые нам нужно будет установить, следующие:
- NumPy : Это фундаментальный пакет для научных вычислений с использованием Python. Помимо очевидного научного использования, NumPy также может использоваться в качестве эффективного многомерного контейнера общих данных.
- Pandas : Это библиотека с открытым исходным кодом, предоставляющая высокопроизводительные, простые в использовании структуры данных и инструменты анализа данных.
- Tweepy : Это простая в использовании библиотека Python для доступа к API Twitter.
- Matplotlib : Это библиотека 2D-графики Python, которая создает показатели качества публикации в различных форматах печатной печати и интерактивных средах на разных платформах.
- Seaborn : Это библиотека визуализации Python, основанная на matplotlib. Он обеспечивает высокоуровневый интерфейс для рисования привлекательной статистической графики.
- Text blob : Это библиотека Python для обработки текстовых данных. Он предоставляет простой API для погружения в общие задачи обработки естественного языка (NLP).
Все они являются ” pip устанавливаемыми “. В конце этой статьи вы сможете найти больше ссылок на эти библиотеки Python.
Теперь, когда у нас есть все требования, давайте начнем!
1.1. Импорт наших библиотек
Это будет самая трудная часть всего поста… – Просто шучу, очевидно, что нет. Это будет так же просто, как скопировать и вставить следующий код в свой блокнот:
# General: import tweepy # To consume Twitter's API import pandas as pd # To handle data import numpy as np # For number computing # For plotting and visualization: from IPython.display import display import matplotlib.pyplot as plt import seaborn as sns %matplotlib inline
Отлично! Теперь мы можем просто запустить эту ячейку кода и перейти к следующему подразделу.
1.2. Создание приложения Twitter
Чтобы извлечь твиты для последующего анализа, нам нужно получить доступ к нашей учетной записи Twitter и создать приложение. Веб-сайт для этого https://apps.twitter.com/ . (Если вы не знаете, как это сделать, вы можете следовать этому учебному видео , чтобы создать учетную запись и приложение.)
Из этого приложения, которое мы создаем, мы сохраним следующую информацию в скрипте под названием credentials.py
:
- Ключ потребителя (ключ API)
- Секрет потребителя (Секрет API)
- Токен доступа
- Секрет маркера доступа
Примером этого сценария является следующее:
# Twitter App access keys for @user # Consume: CONSUMER_KEY = '' CONSUMER_SECRET = '' # Access: ACCESS_TOKEN = '' ACCESS_SECRET = ''
Причина создания этого дополнительного файла заключается в том, что мы хотим экспортировать только значения этих переменных, но невидимые в нашем основном коде (нашей записной книжке). Теперь мы можем использовать API Twitter. Для этого мы создадим функцию, позволяющую нам аутентифицировать наши ключи. Мы добавим эту функцию в другую ячейку кода и запустим ее:
# We import our access keys: from credentials import * # This will allow us to use the keys as variables # API's setup: def twitter_setup(): """ Utility function to setup the Twitter's API with our access keys provided. """ # Authentication and access using keys: auth = tweepy.OAuthHandler(CONSUMER_KEY, CONSUMER_SECRET) auth.set_access_token(ACCESS_TOKEN, ACCESS_SECRET) # Return API with authentication: api = tweepy.API(auth) return api
До сих пор все было так просто, верно? Мы готовы извлечь твиты в следующем разделе.
1.3. Извлечение твитов
Теперь, когда мы создали функцию для настройки API Twitter, мы можем использовать эту функцию для создания объекта ” extractor “. После этого мы будем использовать функцию Tweepy extractor.user_timeline(screen_name, count)
для извлечения из screen_name
пользователя количества count
твитов.
Как указано в названии, я выбрал @realDonaldTrump в качестве пользователя для извлечения данных для последующего анализа. Да, мы хотим, чтобы это было интересно, ЛОЛ.
Способ извлечения данных Twitter заключается в следующем:
# We create an extractor object: extractor = twitter_setup() # We create a tweet list as follows: tweets = extractor.user_timeline(screen_name="realDonaldTrump", count=200) print("Number of tweets extracted: {}.\n".format(len(tweets))) # We print the most recent 5 tweets: print("5 recent tweets:\n") for tweet in tweets[:5]: print(tweet.text) print()
При этом у нас будет результат, аналогичный этому, и мы сможем сравнить результат с учетной записью Twitter (чтобы проверить, насколько мы последовательны): Количество извлеченных твитов: 200.
5 последних твитов:
От имени @FLOTUS Melania и меня, СПАСИБО за сегодняшнее обновление и ОТЛИЧНУЮ РАБОТУ! #SouthernBaptist @SendRelief,... https://t.co/4yZCeXCt6n
Завтра я поеду в Техас и Луизиану с Первой леди. Большой прогресс достигнут! Проводил выходные, работая в Белом доме.
Фондовый рынок растет 5 месяцев подряд!
'Президент Дональд Дж. Трамп объявляет 3 сентября 2017 года Национальным днем молитвы " #HurricaneHarvey #PrayForTexas… https://t.co/tOMfFWwEsN
Техас быстро выздоравливает благодаря всем великим мужчинам и женщинам, которые так усердно работали. Но еще так много нужно сделать. Вернусь завтра!
Теперь у нас есть экстрактор и извлеченные данные, которые перечислены в переменной tweets
. Здесь я должен упомянуть, что каждый элемент в этом списке является объектом tweet
от Tweepy, и мы узнаем, как обрабатывать эти данные в следующем подразделе.
1.4. Создание фрейма данных (pandas)
Теперь у нас есть исходная информация для создания фрейма данных pandas , чтобы очень легко манипулировать информацией.
Функция display
IPython строит вывод удобным способом, а метод head
фрейма данных позволяет нам визуализировать первые 5 элементов фрейма данных (или первое число элементов, которые передаются в качестве аргумента).
Итак, используя понимание списка Python:
# We create a pandas dataframe as follows: data = pd.DataFrame(data=[tweet.text for tweet in tweets], columns=['Tweets']) # We display the first 10 elements of the dataframe: display(data.head(10))
Это создаст результат, подобный этому:
От имени @FLOTUS Melania и меня, ТХА… | 0 |
Завтра я поеду в Техас и Луизиану… | 1 |
Фондовый рынок растет 5 месяцев подряд! | 2 |
“Президент Дональд Трамп Объявляет Сентябрь… | 3 |
Техас быстро выздоравливает благодаря всем gre… | 4 |
…делайте все в рекордно короткие сроки. Много больших … | 5 |
Генерал Джон Келли отлично справляется с ролью чи… | 6 |
Вау, похоже, Джеймс Коми оправдал Хиллари… | 7 |
СПАСИБО всем невероятным ГЕРОЯМ в Т… | 8 |
RT @FoxNews: .@KellyannePolls на Harvey recove… | 9 |
Итак, теперь у нас есть хорошая таблица с упорядоченными данными.
Интересная вещь-это количество внутренних методов, которые структура tweet
имеет в Tweepy:
# Internal methods of a single tweet object: print(dir(tweets[0]))
Это выводит следующий список элементов: ['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getstate__', '__gt__', '__hash__', '__init__','_____________________________________________________________________________________________________________________, "_api", "_json", "автор", "участники", "координаты", "created_at", "уничтожить", "сущности", "избранное", "favorite_count", "избранное", "гео", "id", "id_str", "in_reply_to_screen_name", "in_reply_to_status_id", "in_reply_to_status_id_str", "in_reply_to_user_id", "in_reply_to_user_id_str", "is_quote_status", "lang", "parse", "parse_list", "place", "possibly_sensitive", "retweet", "retweet_count", "retweeted", "retweets", "источник", "source_url", "текст", "усеченный", "пользователь"]
Самое интересное здесь-количество метаданных, содержащихся в одном твите. Если мы хотим получить такие данные, как дата создания или источник создания, мы можем получить доступ к информации с помощью этих атрибутов. Примером может служить следующее:
# We print info from the first tweet: print(tweets[0].id) print(tweets[0].created_at) print(tweets[0].source) print(tweets[0].favorite_count) print(tweets[0].retweet_count) print(tweets[0].geo) print(tweets[0].coordinates) print(tweets[0].entities)
Получение вывода, подобного этому: 903778130850131970
2017-09-02 00:34:32
Twitter для iPhone
24572
5585
Нет
Нет
{'хэштеги': [{'текст': 'SouthernBaptist', 'индексы': [90, 106]}], 'символы': [], 'user_mentions': [{'screen_name': 'FLOTUS', 'name': 'Melania Trump', 'id': 818876014390603776, 'id_str': '818876014390603776', 'индексы': [13, 20]}, {'screen_name': 'sendrelief', 'name': 'Send Relief', 'id': 3228928584, 'id_str': '3228928584', 'индексы': [107, 118]}], 'urls': [{'url': 'https://t.co/4yZCeXCt6n', 'expanded_url': 'https://twitter.com/i/web/status/903778130850131970', 'display_url': 'twitter.com/i/web/status/9...", "индексы": [121, 144]}]}
Теперь мы можем заказать соответствующие данные и добавить их в наш фрейм данных.
1.5. Добавление релевантной информации в наш фрейм данных
Как мы видим, мы можем получить много данных из одного твита. Но не все эти данные всегда полезны для конкретных вещей. В нашем случае мы просто добавим некоторые данные в наш фрейм данных. Для этого мы будем использовать понимание списка Pythons, и новый столбец будет добавлен в фрейм данных, просто добавив имя содержимого в квадратные скобки и назначив содержимое. Код выглядит следующим образом…:
# We add relevant data: data['len'] = np.array([len(tweet.text) for tweet in tweets]) data['ID'] = np.array([tweet.id for tweet in tweets]) data['Date'] = np.array([tweet.created_at for tweet in tweets]) data['Source'] = np.array([tweet.source for tweet in tweets]) data['Likes'] = np.array([tweet.favorite_count for tweet in tweets]) data['RTs'] = np.array([tweet.retweet_count for tweet in tweets])
И чтобы снова отобразить фрейм данных, чтобы увидеть изменения, мы просто…:
# Display of first 10 elements from dataframe: display(data.head(10))
903778130850131970 | 5585 | 144 | 2017-09-02 00:34:32 | 24572 | Twitter для iPhone | От имени @FLOTUS Melania и меня, ТХА… | 0 |
903770196388831233 | 8825 | 132 | 2017-09-02 00:03:00 | 44748 | Twitter для iPhone | Завтра я поеду в Техас и Луизиану… | 1 |
903766326631698432 | 9134 | 34 | 2017-09-01 23:47:38 | 44518 | Twitter для iPhone | Фондовый рынок растет 5 месяцев подряд! | 2 |
903705867891204096 | 15127 | 140 | 2017-09-01 19:47:23 | 47009 | Медиа-студия | “Президент Дональд Трамп Объявляет Сентябрь… | 3 |
903603043714957312 | 15398 | 143 | 2017-09-01 12:58:48 | 77680 | Twitter для iPhone | Техас быстро выздоравливает благодаря всем gre… | 4 |
903600265420578819 | 11424 | 113 | 2017-09-01 12:47:46 | 54664 | Twitter для iPhone | …делайте все в рекордно короткие сроки. Много больших … | 5 |
903597166249246720 | 11678 | 140 | 2017-09-01 12:35:27 | 59840 | Twitter для iPhone | Генерал Джон Келли отлично справляется с ролью чи… | 6 |
903587428488839170 | 35936 | 130 | 2017-09-01 11:56:45 | 110667 | Twitter для iPhone | Вау, похоже, Джеймс Коми оправдал Хиллари… | 7 |
903348312421670912 | 29064 | 110 | 2017-08-31 20:06:35 | 112012 | Twitter для iPhone | СПАСИБО всем невероятным ГЕРОЯМ в Т… | 8 |
903234878124249090 | 6638 | 140 | 2017-08-31 12:35:50 | 0 | Twitter для iPhone | RT @FoxNews: .@KellyannePolls на Harvey recove… | 9 |
Теперь, когда мы извлекли и упорядочили данные в удобном для обработки порядке, мы готовы сделать еще немного манипуляций, чтобы визуализировать некоторые графики и собрать некоторые статистические данные. Первая часть поста закончена.
2.1. Средние показатели и популярность
Сначала мы хотим рассчитать некоторые основные статистические данные, такие как среднее значение длины символов всех твитов, твит с большим количеством лайков и ретвитов и т. Д.
С этого момента я просто добавлю некоторый входной код и вывод прямо под кодом.
Чтобы получить среднее значение, используя numpy:
# We extract the mean of lenghts: mean = np.mean(data['len']) print("The lenght's average in tweets: {}".format(mean))
Средняя длина в твитах: 125,925
Чтобы извлечь больше данных, мы будем использовать некоторые функции панд:
# We extract the tweet with more FAVs and more RTs: fav_max = np.max(data['Likes']) rt_max = np.max(data['RTs']) fav = data[data.Likes == fav_max].index[0] rt = data[data.RTs == rt_max].index[0] # Max FAVs: print("The tweet with more likes is: \n{}".format(data['Tweets'][fav])) print("Number of likes: {}".format(fav_max)) print("{} characters.\n".format(data['len'][fav])) # Max RTs: print("The tweet with more retweets is: \n{}".format(data['Tweets'][rt])) print("Number of retweets: {}".format(rt_max)) print("{} characters.\n".format(data['len'][rt]))
Твит с большим количеством лайков:
Соединенные Штаты осуждают теракт в Барселоне, Испания, и сделают все необходимое, чтобы помочь. Будьте жесткими и сильными, мы любим вас!
Количество лайков: 222205
144 символа.
Твит с большим количеством ретвитов:
Соединенные Штаты осуждают теракт в Барселоне, Испания, и сделают все необходимое, чтобы помочь. Будьте жесткими и сильными, мы любим вас!
Количество ретвитов: 66099
144 символа.
Это обычное дело, но это не обязательно произойдет: твит с большим количеством лайков-это твит с большим количеством ретвитов. То, что мы делаем, заключается в том, что мы находим максимальное количество лайков из столбца ‘Likes’ и максимальное количество ретвитов из ‘RTs’ , используя функцию numpy max
. При этом мы просто ищем индекс в каждом из обоих столбцов, который удовлетворяет максимуму. Поскольку более одного может иметь одинаковое количество лайков/ретвитов (максимум), нам просто нужно взять первый найденный, и именно поэтому мы используем .index[0]
для присвоения индекса переменным fav
и rt
. Чтобы напечатать твит, который удовлетворяет, мы обращаемся к данным так же, как к матрице или любому индексированному объекту.
Теперь мы готовы кое-что спланировать.
2.2. Временные ряды
У Панд есть свой собственный объект для временных рядов. Поскольку у нас есть целый вектор с датами создания, мы можем построить временные ряды с учетом длины твитов, лайков и ретвитов.
То, как мы это делаем,:
# We create time series for data: tlen = pd.Series(data=data['len'].values, index=data['Date']) tfav = pd.Series(data=data['Likes'].values, index=data['Date']) tret = pd.Series(data=data['RTs'].values, index=data['Date'])
И если мы хотим построить временной ряд, у панды уже есть свой собственный метод в объекте. Мы можем построить временной ряд следующим образом:
# Lenghts along time: tlen.plot(figsize=(16,4), color='r');
Это создает следующий вывод:
И построить график лайков по сравнению с ретвитами в одном и том же графике:
# Likes vs retweets visualization: tfav.plot(figsize=(16,4), label="Likes", legend=True) tret.plot(figsize=(16,4), label="Retweets", legend=True);
Это создаст следующий вывод:
2.3. Круговые диаграммы источников
Мы почти закончили со вторым разделом поста. Теперь мы построим источники в виде круговой диаграммы, так как мы поняли, что не каждый твит отправляется из одного и того же источника ( 😱 🤔 ). Сначала мы очищаем все источники:
# We obtain all possible sources: sources = [] for source in data['Source']: if source not in sources: sources.append(source) # We print sources list: print("Creation of content sources:") for source in sources: print("* {}".format(source))
С помощью следующего вывода мы понимаем, что в основном эта учетная запись twitter имеет два источника: Создание источников контента:
* Twitter для iPhone
* Media Studio
Теперь мы подсчитываем количество каждого источника и создаем круговую диаграмму. Вы заметите, что эта ячейка кода не является самой оптимизированной… Пожалуйста, имейте в виду, что было 4 часа утра, когда я проектировал этот семинар. 😅
# We create a numpy vector mapped to labels: percent = np.zeros(len(sources)) for source in data['Source']: for index in range(len(sources)): if source == sources[index]: percent[index] += 1 pass percent /= 100 # Pie chart: pie_chart = pd.Series(percent, index=sources, name='Sources') pie_chart.plot.pie(fontsize=11, autopct='%.2f', figsize=(6, 6));
С помощью этого мы получаем результат, подобный этому:
И мы можем видеть процент твитов на источник.
Теперь мы можем приступить к анализу настроений.
3.1. Импорт текстового блока
Как мы уже упоминали в начале этого поста, textblob позволит нам провести анализ настроений очень простым способом. Мы также будем использовать библиотеку re
из Python, которая используется для работы с регулярными выражениями . Для этого я предоставлю вам две полезные функции: а) очистить текст (что означает, что любой символ, отличный от буквенно-цифрового значения, будет переназначен в новый, удовлетворяющий этому условию), и б) создать классификатор для анализа полярности каждого твита после очистки текста в нем. Я не буду объяснять конкретный способ, которым работает функция очистки, поскольку она будет расширена и может быть лучше понята в официальной re
документации .
Код, который я предоставляю, это:
from textblob import TextBlob import re def clean_tweet(tweet): ''' Utility function to clean the text in a tweet by removing links and special characters using regex. ''' return ' '.join(re.sub("(@[A-Za-z0-9]+)|([^0-9A-Za-z \t])|(\w+:\/\/\S+)", " ", tweet).split()) def analize_sentiment(tweet): ''' Utility function to classify the polarity of a tweet using textblob. ''' analysis = TextBlob(clean_tweet(tweet)) if analysis.sentiment.polarity > 0: return 1 elif analysis.sentiment.polarity == 0: return 0 else: return -1
Это работает так, что textblob уже предоставляет обученный анализатор (круто, правда?). Текстовый blob может работать с различными моделями машинного обучения , используемыми в обработке естественного языка . Если вы хотите обучить свой собственный классификатор (или, по крайней мере, проверить, как он работает), не стесняйтесь проверить следующую ссылку /. Это может быть актуально, поскольку мы работаем с предварительно обученной моделью (для которой мы не используем данные, которые были использованы).
В любом случае, возвращаясь к коду, мы просто добавим дополнительный столбец к нашим данным. Этот столбец будет содержать анализ настроений, и мы можем построить фрейм данных, чтобы увидеть обновление:
# We create a column with the result of the analysis: data['SA'] = np.array([ analize_sentiment(tweet) for tweet in data['Tweets'] ]) # We display the updated dataframe with the new column: display(data.head(10))
Получение нового результата:
903778130850131970 | 1 | 5585 | 144 | 2017-09-02 00:34:32 | 24572 | Twitter для iPhone | От имени @FLOTUS Melania и меня, ТХА… | 0 |
903770196388831233 | 1 | 8825 | 132 | 2017-09-02 00:03:00 | 44748 | Twitter для iPhone | Завтра я поеду в Техас и Луизиану… | 1 |
903766326631698432 | 0 | 9134 | 34 | 2017-09-01 23:47:38 | 44518 | Twitter для iPhone | Фондовый рынок растет 5 месяцев подряд! | 2 |
903705867891204096 | 0 | 15127 | 140 | 2017-09-01 19:47:23 | 47009 | Медиа-студия | “Президент Дональд Трамп Объявляет Сентябрь… | 3 |
903603043714957312 | 1 | 15398 | 143 | 2017-09-01 12:58:48 | 77680 | Twitter для iPhone | Техас быстро выздоравливает благодаря всем gre… | 4 |
903600265420578819 | 1 | 11424 | 113 | 2017-09-01 12:47:46 | 54664 | Twitter для iPhone | …делайте все в рекордно короткие сроки. Много больших … | 5 |
903597166249246720 | 1 | 11678 | 140 | 2017-09-01 12:35:27 | 59840 | Twitter для iPhone | Генерал Джон Келли отлично справляется с ролью чи… | 6 |
903587428488839170 | 1 | 35936 | 130 | 2017-09-01 11:56:45 | 110667 | Twitter для iPhone | Вау, похоже, Джеймс Коми оправдал Хиллари… | 7 |
903348312421670912 | 1 | 29064 | 110 | 2017-08-31 20:06:35 | 112012 | Twitter для iPhone | СПАСИБО всем невероятным ГЕРОЯМ в Т… | 8 |
903234878124249090 | 0 | 6638 | 140 | 2017-08-31 20:06:35 | 0 | Twitter для iPhone | RT @FoxNews: .@KellyannePolls на Harvey recove… | 9 |
Как мы видим, последний столбец содержит анализ настроений ( SA
). Теперь нам просто нужно проверить результаты.
3.2. Анализ результатов
Чтобы иметь простой способ проверить результаты, мы подсчитаем количество нейтральных, положительных и отрицательных твитов и извлекем проценты.
# We construct lists with classified tweets: pos_tweets = [ tweet for index, tweet in enumerate(data['Tweets']) if data['SA'][index] > 0] neu_tweets = [ tweet for index, tweet in enumerate(data['Tweets']) if data['SA'][index] == 0] neg_tweets = [ tweet for index, tweet in enumerate(data['Tweets']) if data['SA'][index] < 0]
Теперь, когда у нас есть списки, мы просто печатаем проценты:
# We print percentages: print("Percentage of positive tweets: {}%".format(len(pos_tweets)*100/len(data['Tweets']))) print("Percentage of neutral tweets: {}%".format(len(neu_tweets)*100/len(data['Tweets']))) print("Percentage de negative tweets: {}%".format(len(neg_tweets)*100/len(data['Tweets'])))
Получение следующего результата: Процент положительных твитов: 51,0%
Процент нейтральных твитов: 27,0%
Процент отрицательных твитов: 22,0%
Мы должны учитывать, что мы работаем только с 200 самыми последними твитами от Д. Трампа (последнее обновление: 2 сентября). Для более точных результатов мы можем рассмотреть больше твитов. Интересная вещь (приглашение читателям) состоит в том, чтобы проанализировать полярность твитов из разных источников, это может быть детерминировано тем, что, рассматривая только твиты из одного источника, полярность приведет к более положительному/отрицательному результату. В любом случае, я надеюсь, что это будет интересно.
Как мы видели, с помощью Python мы можем извлекать, манипулировать, визуализировать и анализировать данные очень простым способом. Я надеюсь, что это оставляет некоторую неопределенность у читателя для дальнейшего изучения с помощью этих инструментов.
Возможно, удастся найти небольшие ошибки в переводе материала (я разработал семинар на испанском языке, первоначально 😅 ). Пожалуйста, не стесняйтесь комментировать или предлагать все, что приходит вам в голову. Это дополнит некоторые идеи, которые я уже имею в виду для дальнейшей работы. 😀
Теперь я оставлю некоторые ссылки на документацию и учебные пособия по используемым библиотекам. Надеюсь услышать от вас!
Рекомендации:
- Официальная документация – Tweepy
- Официальная документация – NumPy
- Официальный учебник – NumPy
- Официальный учебник – Панды
- Официальная документация – Панды
- Официальная документация – Matplotlib
- Официальный учебник – Pyplot
- Официальный сайт – Seaborn
- Официальная документация – TextBlob
- Учебное пособие: Построение системы классификации текста – TextBlob