Анализируем Twitter при помощи R

Здравствуйте, уважаемое хабрасообщество!
На Хабре уже несколько раз говорили о возможностях среды R, но я считаю, что дополнительная информация станет полезной, так как R — это очень интересный и мощный инструмент, который может быть применен в самых разных областях. Я попробую это доказать на примере анализа появления одного из трендов Twitter. Для этого нам понадобится библиотека twitteR, которая позволяет работать с Twitter через API. Но для начала расскажу подробнее об R.

Система статистической обработки данных и программирования R ориентирована на использование интерфейса командной строки. Обработка данных в системе R представляет собой последовательность команд для загрузки исходных данных, вычислений и текстового или графического вывода полученных результатов. Такая последовательность может быть сформирована пользователем как с помощью командной строки (интерактивный режим), так и из текстового файла (пакетный режим), а текстовые или графические результаты вычислений могут быть выведены на экран и/или записаны в соответствующие файлы.

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

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

Поздно ночью 26-го февраля среди пользователей начала распространяться информация о трагической гибели известного британского актера Роуэна Аткинсона. Этот факт не был подтвержден, но количество сообщений увеличивалось, и известие о смерти актера, сыгравшего мистера Бина, довольно быстро стало трендом Твиттера. Сообщения о кончине актера содержали фразу R.I.P. Rowan Atkinson. Используя возможности R можно проанализировать рассматриваемое событие и визуализировать этапы распространения информации.
Анализируемые данные представляют собой текстовый массив, содержащий информацию об отправителе, дате, времени и текст сообщения.

Данные получены следующим образом:
library(twitteR)
tweets = searchTwitter("R.I.P. Rowan Atkinson", n=1500)
data = twListToDF(tweets)


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

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


Рисунок 1. Количество сообщений в сутки

График построен следующим образом:
library(ggplot2)
c <- ggplot(data, aes(created))
c + geom_bar()

На рисунке 2 представлено распределение отправленных сообщений по часам. По графику видно, что первые сообщения начали появляться после 20 часов 26-го февраля, а наибольшее количество сообщений приходится на утро 27-го февраля.


Рисунок 2. Распределение отправленных сообщений по часам

График построен следующим образом:
library(ggplot2)
data$month=sapply(data$created, function(x) {p=as.POSIXlt(x);p$mon})
data$hour=sapply(data$created, function(x) {p=as.POSIXlt(x);p$hour})
data$wday=sapply(data$created, function(x) {p=as.POSIXlt(x);p$wday})
ggplot(data)+geom_jitter(aes(x=wday,y=hour))

На рисунке 3 представлено облако из наиболее часто встречающихся слов в сообщениях пользователей.


Рисунок 3. Облако наиболее встречающихся в сообщениях слов

График построен следующим образом:
library("tm")
text = Corpus(DataframeSource(data.frame(data[1])))
text = tm_map(text, removePunctuation)
text = tm_map(text, tolower)
tdm = TermDocumentMatrix(text)
m = as.matrix(tdm)
v = sort(rowSums(m),decreasing=TRUE)
library("wordcloud")
wordcloud(names(v), v^0.3, scale=c(5,0.5),random.order=F, colors="black")


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

В настоящее время реализации R существуют для трех наиболее распространенных семейств операционных систем: GNU/Linux, Apple Mac OS X и Microsoft Windows. В распределенных хранилищах системы CRAN по состоянию на конец сентября 2010 года были доступны для свободной загрузки 2548 пакетов расширения, ориентированных на специфические задачи обработки данных, возникающие в эконометрике и финансовом анализе, генетике и молекулярной биологии, экологии и геологии, медицине и фармацевтике и многих других прикладных областях. Значительная часть европейских и американских университетов в последние годы активно переходят к использованию R в учебной и научно-исследовательской деятельности вместо дорогостоящих коммерческих разработок [1].

Литература

1. Статистический анализ данных в системе R. Учебное пособие /А.Г. Буховец, П.В. Москалев, В.П. Богатова, Т.Я. Бирючинская; Под ред. проф. Буховца А.Г- Воронеж: ВГАУ, 2010. — 124с.
Share post
AdBlock has stolen the banner, but banners are not teeth — they will be back

More
Ads

Comments 38

    +2
    спасибо за статью, но после R.I.P Rowan Atkinson, полез искать что же с ним случилось :)
      +2
      Пожалуйста! Совсем забыл написать, что с ним все хорошо, а этот тренд следствие слухов. Как кто-то сказал: Твиттер убил больше людей, чем Гитлер.
    • UFO just landed and posted this here
        0
        Интересный факт, не знал об этом. Спасибо!
          +2
          И не только в подборке. Посмотрите комментарий выше.
            0
            В визуализации по времени неплохо было бы пометить цветом упоминания гитлера.
            –1
            Я свой диплом по статистике и регрессионному анализу делал с помощью R. Отличный инструмент :)

              –1
              А тема моего диплома связана с анализом возможностей применения R в учебном процессе :)
              0
              Хороший язык для статистов
              • UFO just landed and posted this here
                0
                Пример с Аткинсоном вы сами придумали или перевели уже существующий текст?
                  0
                  Статья оригинальная, т.е. написана мной, за исключением части текста, на который дана ссылка в литературе.
                    0
                    26 февраля если не ошибаюсь, в трендах вышло что Аткинсон умер… это правда
                    0
                    Хотелось бы увидеть тестовый набор данных, чтобы самостоятельно запустить на нем предложенный Вами код.
                      +2
                      Да, конечно, пожалуйста: данные
                        0
                        Спасибо.
                      0
                      Действительно очень полезный наглядный пример, Оочень захотелось побаловаться с «R». Лень конечно ставить. Думаю на выходных займусь этим. Мне нужно стонить специальное чтобы к реальным данным твиттера подключиться знать?
                        0
                        Спасибо! Специального ничего не надо. Нужно лишь установить дополнительные библиотеки, т. к. их нет в базовом наборе. Для этой статьи это: twitteR, ggplot2, wordcloud, tm.
                        Устанавливается так: install.packages(«название библиотеки»)
                          0
                          Не добрался в эти выходные до программки. Но все равно охота разобраться. Так что еще вернусь обязательно.

                          Мы кстати написали на хабре как у нас в команде используется твиттер, может быть тоже будет интересно.
                          Там как раз вопрос про кластеризацию задают. Порекомендовал им R попробывать. Вообще да нужно будет нашим прогерам рассказать им наверно это все проще будет делать. Я честно скажу вообще дестопные приложения давно не ставил, как-то меня это все ламает. браузер естьи клево.
                            0
                            Тема анализа Твиттера очень интересна и обширна. Планирую еще написать на эту тему. Возможно и что-нибудь о кластерном анализе напишу.
                        0
                        А где, собственно, анализ настроений? :)

                        Вообще забавно наблюдать за тенденциями в IT-мире. Буквально за последние пол года связка твиттер + анализ настроений получила ну просто дикое распространение. По крайней мере мне штук 5 приглашений на подобные проекты присылали. Что также приятно, растёт и комьюнити у R — инструмент действительно очень приятный и удобный. Расстраивает только плохая масштабируемость — для действительно больших данных (а R как статистическая тулза по идее должна специализироваться именно на них) всё равно приходится брать Mahout или что-нибудь подобное.
                          0
                          Да, согласен, анализ настроений это несколько иное. В данном случае можно сказать, что это просто демонстрация скорости распространения слухов. На счет масштабируемости согласен. Хотя есть Revolution R и вроде однопользовательские лицензии для пользователей академических учреждений предоставляются бесплатно, но я пока не пробовал этот продукт.
                            0
                            Ну, насколько я понял, Revolution R масштабируется на несколько ядер внутри одной машины, но не на кластер. А на одной машине всё равно жёстко стоит ограничение по памяти — на моей машине с 8Gb на той же задаче анализа настроений уже при матрице документов 10k * 14k начинает лезть в своп, а документов по-хорошему нужно не 10k, а хотя бы 200-300k. Так что либо mahout, либо подключать БД и переделывать алгоритмы для инкрементальной работы.
                              0
                              Судя по этой публикации, поддерживается обработка данных по узлам вычислительного кластера.
                                0
                                Ого, не видел. Ну это совсем другое дело, спасибо за ссылку!
                          +7
                          Кстати, несколько замечаний для людей, заинтересовавшихся R (как раз недавно хотел об этом развёрнутую статью написать, но всё времени нет).

                          Во-первых, для R есть замечательная среда разработки — RStudio. Как и сам R доступна для всех трёх основных платформ, плюс есть серверная версия для работы через бразер. Преимущества — есть редактор файлов с подсветкой синтаксиса, список созданных объектов, графики и документация открываются в отдельной области, ну и в целом поприятней голой консоли.

                          Во-вторых, R во многом похож на Scheme, только с JavaScript-подобным синтаксисом и без макросов. Зато с такой же системой environment-ов, с такой же нежёсткой типизацией, символами (symbols) и выражениями (expressions) и т.д. Последние 2 фичи, кстати, позволяют решать многие из задач, решаемых в Лиспах за счёт макросов.

                          В-третьих, сразу стоит понимать, что R — язык с историей, т.е. многие его «странности» объясняются именно историческими причинами. Например, в R есть сразу 2 системы объектно-ориентированного программирования — S3 и S4 (про их отличия был вопрос на StackOverflow). При этом нельзя сказать, что одна система вляется устаревшей — отнюдь, обе используются довольно часто. Историческими же причинами объясняется и отсутствие единой конвенции кода: изначально в R было принято писать всё маленькими буквами и разделять слова точками ("." в R — вполне законный символ в имени, так же, как "_" в Си, например). Но потом пришла S3, в которой точка использовалась при диспетчеризации методов объектов, и имена функций с точками стали не очень очевидными.

                          В-четвёртых, типизация в R может поначалу сломать мозг. В R у каждого объекта есть как минимум 2 атрибута типа — mode и class (их можно узнать с помощью одноимённых функций — mode() и class()). Грубо говоря, class — это тип самого объекта (например, matrix или table), а mode — это тип примитивов, хранимых в объекте (например, numeric или character). При этом numeric, integer, character и т.д. — это не число, целое и чар, как это принято в других языках, а вектор этих значений. И даже `5` — это не просто число, а вектор из одно элемента. В общем, что касается типов, в R всё очень и очень необычно :)

                          В-пятых, в R обращение к данным производится посредствам индексации. Например, к пятому элементу (привет, Мила Йовович) вектора `x` можно обратиться как `x[5]`. Но у вектора также может быть атрибут `names`, и тогда к тому же элементу можно обратиться, например, `x[«fifth_element»]`. Кроме оператора `[ ]` есть оператор `[[ ]]` (в основном используется для поиска по спискам — lists) и оператор `$`, который работает только для обращения через имя элемента, но и то не для всех типов. Так что не удивляйтесь, а внимательно читайте документацию и/или туториалы.
                          Кроме того, обратите внимание, что у любого объекта кроме основного значения может быть любое количество атрибутов. Например, class и mode — это просто атрибуты объекта (которые, кстати, можно перезаписывать). Часто можно встретить и такие атрибуты как dim, names/dimnames и др.

                          В-шестых, R использует pass-by-promise механизм. Для тех, кто незнаком с ленивыми вычислениями поясню: в функцию передаётся не сам объект, а специальная «обёртка», которая «обещает» вычислить объект, когда он понадобится. Впрочем, данные во внутренних структурах R преобразуются настолько часто, что эффект ленивых вычислений практически незаметен и в целом механизм становится похож на pass-by-value.

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

                          * векторы (numeric, character) — на них строится всё. Пример создания числового вектора: `c(1, 2, 3, 4)`
                          * списки (list) — то же самое, но может хранить элементы любого типа
                          * матрицы и дейта фреймы (matrix и data.frama, соответственно) — для хранения двумерных данных. Матрицы быстрее и «легче», но могут хранить только один тип данных. Дейта фреймы просто удобней — в разных колонках можно хранить разные типы, плюс можно обращаться к колонкам по имени, плюс ещё несколько приятностей. Про сравнение матриц и дейта фреймов можно также почитать на StackOverflow.
                          * факторы (factor) — для представления категориальных данных. Например, есть у вас данные о нарушениях ПДД с колонкой «цвет сфетофора», которые могут принимать всего три значения — green, yellow и red. Вы можете создать фактор с тремя «уровнями» (не спрашивайте почему такие названия — это что-то из глубоких понятий статистики):

                          factor(«green», c(«green», «yellow», «red»))
                          [1] green
                          Levels: green yellow red

                          [1] green — [одномерный] строковый вектор green — значение вектора
                          Levels: green yellow red — уровни фактора

                          * выражения (expressions) — обычно вводятся с помощью символа тильды (~). Например, если вы видите выражение `z ~ x + log(y)`, это значит, что мы задаём зависимость переменной `z` от `x` и `y` как сумму первого и логарифм от второго. Смотрите примеры, будет понятней.

                          Топ-10 функций R, которые лучше выучить сразу:

                          mode
                          class
                          print
                          summary
                          attributes и attr
                          apply и sapply
                          plot
                          library и install.package
                          dim
                          [], [[]], $

                          Приятного изучения :)
                            +2
                            Хм, в окне отправки сообщения казалось меньше текста 0_о
                              0
                              Полноценный пост :)
                                +1
                                Спасибо.

                                Отдельный пост, с форматированием и ссылками написать стоило.

                                Топ-10 функций у каждого свой. У меня на первом месте str
                                  +2
                                  Относительно небольшой пост про линейную регрессию я пишу уже 2 месяца, пост про R должен был идти следующим :)

                                  Скажем так, это короткий список тех функций, знание которых облегчит начало работы с R. А так да, по частоте использования (особенно в консоли) str однозначно в десятке.
                                    +1
                                    В какой блог писать будете? Подпишусь на него :)
                                      +1
                                      Думаю, это к Data Mining ближе всего.
                                      0
                                      а про нелинейную регрессию будет? Там все же интереснее :)
                                        0
                                        Вообще изначально была цель создать ряд материалов по машинному обучению, которые с одной стороны будут просты для понимания, а с другой — достаточно подробны, чтобы начать применять знания без дополнительной литературы. Статья по линейной регрессии — это своеобразное введение, в котором можно рассказать про способы представления данных, функцию ошибки, методы её минимизации и т.д., при этом сохранив читабельный объём. Поэтому в ближайшей статье скорее всего нелинейная регрессия будет на уровне «совсем как линейная, только формула сложнее». Если хватит сил и времени, то позже напишу и про нелинейную, и про SVM-регрессию, и про связь с нейронными сетями и многое другое. Но там всё друг за друга цепляется — SVM-регрессию проще понять после SVM-классификатора, к классификаторам же относится и логистическая регрессия, нейронки затрагивают и регрессию, и классификацию, да ещё и кластеризацию, и всё это нужно пробовать на каких-то инструментах (R, Weka, Mahout). Так что как-то так.
                                    +2
                                    впервые воспользовался функцией «избранный комментарий», спасибо!
                                    0
                                    Я, конечно, с R на «Вы», но вот тот факт, что я не смог с помощью функции searchTwitter пакета twitteR найти твиты с нужными мне словами на русском языке, несколько смущает. Притом, что с поиском английских ключевых слов всё работает прекрасно.
                                      0
                                      Прошу прощения за это упущение :) Если необходимо искать на каком-то конкретном языке нужно указывать параметр lang. Значения параметра: en, ru, de, it, etc.
                                      Например:
                                      > searchTwitter('Россия', n=25, lang='ru')
                                        0
                                        Дома я поигрался с этим параметром, но всё равно в результатах поиска оказывался какой-то откровенный спам, а не то, что выдаёт сам твиттер на поисковый запрос.

                                        На работе при запуске вашего скрипта получил следующую ошибку:
                                        Ошибка в curlPerform(curl = curl, .opts = opts, .encoding = .encoding):
                                        couldn't connect to host

                                        Разумею, что из-за фаерволла.

                                    Only users with full accounts can post comments. Log in, please.