Data-mining и Твиттер

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

Предлагаю угадать, какую технологию обрамляет это облако слов?

Облако

Используя Твиттер API можно извлекать и анализировать самую разнообразную информацию. Статья о том, как это осуществить с помощью языка программирования R.

Написание кода занимает не так уж много времени, сложности могут возникнуть из-за изменений и ужесточения Твиттер API, судя по всему компания всерьез озаботилась вопросами безопасности после выволочки в Конгрессе США по следам расследования влияния «русских хакеров» на выборы в США в 2016 г.

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

Для начала понятно, что нужно иметь учетную запись Твиттер с указанием номера телефона. Это необходимо для создания приложения, именно этот шаг дает доступ к API.

Заходим на страницу разработчика и жмем на кнопку Create an app. Далее следует страничка на которой надо заполнить информацию о приложении. На данный момент страница состоит из следующих полей.

apps


  • AppName — имя приложения (обязательно).
  • Application description — описание приложения (обязательно).
  • Website URL — страница сайта приложения (обязательно), можно вписать все, что угодно похожее на URL.
  • Enable Sign in with Twitter (check box) — Вход со страницы приложения на Твиттер, можно попустить.
  • Callback URLs — Обратная вызов приложения при аутентификации (обязательно) и необходимо, можно оставить http://127.0.0.1:1410.

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

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


  • Standard — Базовый вариант, можно искать записи на глубину ≤ 7 дней, бесплатный.
  • Premium — Более продвинутый вариант, можно искать записи на глубину ≤ 30 дней и с 2006 г. Бесплатный, но дают не сразу по рассмотрению заявки.
  • Enterprise — Бизнес-класс, платный и надежный тариф.

Я выбрал Premium, ждать одобрения пришлось около недели. Не могу сказать всем-ли подряд дают его, но попытаться стоит в любом случае, а Standard никуда не денется.

После того, как вы создали приложение в закладке Keys and tokens появится набор содержащий следующие элементы. Ниже названия и соответствующие переменные R.

Consumer API keys


  • API key — api_key
  • API secret key — api_secret

Access token & access token secret


  • Access token — access_token
  • Access token secret — access_token_secret

Устанавливаем необходимые пакеты.

install.packages("rtweet")
install.packages("tm")
install.packages("wordcloud")

Эта часть кода будет выглядеть следующим образом.

library("rtweet")
api_key <- ""
api_secret <- ""
access_token <- ""
access_token_secret <- ""
appname=""
setup_twitter_oauth (
  api_key,
  api_secret,
  access_token,
  access_token_secret)

После аутентификации R предложит сохранить коды OAuth на диске, для последующего использования.

[1] "Using direct authentication"
Use a local file to cache OAuth access credentials between R sessions?
1: Yes
2: No

Оба варианта приемлемы, я выбрал 1-й.

tweets <- search_tweets("hadoop", include_rts=FALSE, n=600)

Ключ include_rts позволяет контролировать включение в поиск, или исключение из него ретвитов. На выходе получаем таблицу с множеством полей, в которых есть подробности и детали каждой записи. Вот первые 20.

> head(names(tweets), n=20)
 [1] "user_id"              "status_id"            "created_at"
 [4] "screen_name"          "text"                 "source"
 [7] "display_text_width"   "reply_to_status_id"   "reply_to_user_id"
[10] "reply_to_screen_name" "is_quote"             "is_retweet"
[13] "favorite_count"       "retweet_count"        "hashtags"
[16] "symbols"              "urls_url"             "urls_t.co"
[19] "urls_expanded_url"    "media_url"

Можно составить более сложную строку поиска.

search_string <- paste0(c("data mining","#bigdata"),collapse = "+")
search_tweets(search_string, include_rts=FALSE, n=100)

Результаты поиска можно сохранить в текстовом файле.

write.table(tweets$text, file="datamine.txt")

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

Существует еще одна функция поиска — searchTwitter, для которой требуется библиотека twitteR. В чем-то она удобнее search_tweets, а в чем-то ей уступает.

Плюс — наличие фильтра по времени.

  tweets <- searchTwitter("hadoop", since="2017-09-01", n=500)
  text = sapply(tweets, function(x) x$getText())

Минус — вывод не таблица, а объект типа status. Для того, чтобы его использовать в нашем примере нужно из вывода вычленить текстовое поле. Это и делает sapply во второй строке.

corpus <- Corpus(VectorSource(tweets$text))  
clearCorpus <- tm_map(corpus, function(x) iconv(enc2utf8(x), sub = "byte"))

tdm <- TermDocumentMatrix(clearCorpus, control =
    list(removePunctuation = TRUE,
        stopwords = c("com", "https", "hadoop", stopwords("english")),
        removeNumbers = TRUE,
        tolower = TRUE))

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

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

m <- as.matrix(tdm)
word_freqs <- sort(rowSums(m), decreasing=TRUE)
dm <- data.frame(word=names(word_freqs), freq=word_freqs)

wordcloud(dm$word, dm$freq, scale=c(3, .5),
random.order=FALSE, colors=brewer.pal(8, "Dark2"))

Функция search_string позволяет задать в качестве параметра язык.

search_tweets(search_string, include_rts=FALSE, n=100, lang="ru")

Однако ввиду того, что NLP пакет для R плохо русифицирован, в частности нет списка служебных, или стоп-слов, построение облака слов с поиском на русском у меня не получилось. Буду рад, если в комментариях найдут лучшее решение.

Ну, и собственно…


скрипт целиком
library("rtweet")
library("tm")
library("wordcloud")

api_key <- ""
api_secret <- ""
access_token <- ""
access_token_secret <- ""
appname=""
setup_twitter_oauth (
  api_key,
  api_secret,
  access_token,
  access_token_secret)

oauth_callback <- "http://127.0.0.1:1410"
setup_twitter_oauth (api_key, api_secret, access_token, access_token_secret)
appname="my_app"

twitter_token <- create_token(app = appname, consumer_key = api_key, consumer_secret = api_secret)
tweets <- search_tweets("devops", include_rts=FALSE, n=600)

corpus <- Corpus(VectorSource(tweets$text))
clearCorpus <- tm_map(corpus, function(x) iconv(enc2utf8(x), sub = "byte"))

tdm <- TermDocumentMatrix(clearCorpus, control =
    list(removePunctuation = TRUE,
        stopwords = c("com", "https", "drupal", stopwords("english")),
        removeNumbers = TRUE,
        tolower = TRUE))

m <- as.matrix(tdm)
word_freqs <- sort(rowSums(m), decreasing=TRUE)
dm <- data.frame(word=names(word_freqs), freq=word_freqs)

wordcloud(dm$word, dm$freq, scale=c(3, .5),
random.order=FALSE, colors=brewer.pal(8, "Dark2"))


Использованные материалы.

Краткие ссылки:

Оригинальные ссылки:

https://stats.seandolinar.com/collecting-twitter-data-getting-started/
https://opensourceforu.com/2018/07/using-r-to-mine-and-analyse-popular-sentiments/
http://dkhramov.dp.ua/images/edu/Stu.WebMining/ch17_twitter.pdf
http://opensourceforu.com/2018/02/explore-twitter-data-using-r/
https://cran.r-project.org/web/packages/tm/vignettes/tm.pdf

P.S. Подсказка, ключевое слово облака на КДПВ не используется в программе, оно связано с моей предыдущей статьей.

© Habrahabr.ru