Data-mining и Твиттер

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


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


    Облако


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


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


    Получение доступа к API


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


    Для начала понятно, что нужно иметь учетную запись Твиттер с указанием номера телефона. Это необходимо для создания приложения, именно этот шаг дает доступ к 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 keyapi_key
    • API secret keyapi_secret

    Access token & access token secret


    • Access tokenaccess_token
    • Access token secretaccess_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. Подсказка, ключевое слово облака на КДПВ не используется в программе, оно связано с моей предыдущей статьей.

    AdBlock похитил этот баннер, но баннеры не зубы — отрастут

    Подробнее
    Реклама

    Комментарии 8

      0
      бдсм
      0
      API — это очень специфический путь, который может оборваться в любой момент.
      Гораздо интереснее было бы почитать про сбор данных через selenium, благо пакет RSelenium запускается из коробки, без бубна.
        0
        мне в API отказали. Но я честно написал что для исследования и nlp. Теперь придется идти путем селениума)))) Благо аккаунты продаются и стоят не дорого.
          0
          мне в API отказали.

          Вот-вот. Или, как было у меня, работаешь с апи, и вдруг тебе что-то перестают отдавать, потому что __важная_причина_от_владельцев_апи__.
            0
            Ну fb тут впереди планеты всей. Получить список подписчиков своей страницы нельзя теперь никак. В апи методы деприкейтед, а в настройках страницы есть целая табличка но в ней почему-то 20 пользователей, всегда одинаковые, по какому критерию выбраны не понятно(в группе сейчас примерно 1к человек)
          0
          Ну такое. Если есть возможность использовать API, то, имхо, лучше использовать именно API. С Selenium тоже можно регулярно огребать… Обновления дизайна, блокировки по IP(приходится закупать прокси) и всякое прочее. Да и ресурсов больше кушает
          0
          Для русского, стоп-слова есть в пакете tm,
          а стемминг можно сделать из пакета SnowcallC

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

          Самое читаемое