Data Mining при помощи R: пример анализа twitter-сообщений
Созданный нами объект rdmTweets является списком. Каждый элемент этого списка содержит отдельное сообщение, например:
Для удобства дальнейшей работы с этими сообщениями список rdmTweets стоит преобразовать в таблицу данных. Эта операция легко выполняется при помощи функции twListToDF() из пакета twitteR :
Далее нам нужен будет пакет tm (от text mining), имеющий широкие возможности для анализа текстовой информации (как обычно, его можно установить при помощи команды install.packages("tm") ). Обработка twitter-сообщений, хранящихся теперь в текстовом векторе tweets , потребует нескольких функций из этого пакета. Первым шагом должно стать создание т.н. "корпуса", т.е. сведение всех имеющихся небольших текстов (сообщений) в один объект:
С корпусом текстов можно выполнять разнообразные операции, что осуществляется через интерфейс функции tm_map() из пакета tm . Для начала стоит удалить из анализируемых сообщений все знаки пунктуации, которые не несут никакой смысловой нагрузки (функция removePunctuation() ):
Теперь сделаем так, чтобы все слова в анализируемых сообщениях были представлены прописными буквами:
Следующий шаг - очень важный. Он состоит в том, чтобы удалить из сообщений как можно больше т.н. "стоп-слов", или "шумовых слов", т.е. слов, не несущих смысловой нагрузки (например, "это", "я", "мы", "тут", "возможно" "один", "два", и т.п.). Если бы мы работали с англоязычными текстами, можно было бы воспользоваться хорошо работающим готовым решением из пакета tm : tw.corpus <- tm_map(tw.corpus, removeWords, stopwords("english")) . Теоретически, в приведенной команде можно было бы заменить "english" на "russian" , но практика показывает, что это дает неудовлетворительные результаты. Однако имеется возможность применить и пользовательский список стоп-слов. Один из таких списков я нашел здесь (скачать его в виде текстового файла можно здесь). После загрузки этого списка в R и сохранения его под именем my.stopwords (в виде текстового вектора), выполняем следующую команду:
Все приведенные команды, использующие функцию tm_map() , можно объединить в одну более крупную функцию, которую будет удобно использовать при выполнении аналогичных анализов в будущем. Например:
Эта новая функция позволяет быстро подготовить корпус twitter-сообщений для дальнейшего анализа, например, так:
Далее будем работать именно с объектом my.corpus . В этой статье я покажу, как выполнить контент-анализ twitter-сообщений путем создания и визуального анализа облака наиболее часто встречающихся в этих сообщениях слов. Для создания облака слов воспользуемся возможностями пакета wordcloud (установите при помощи команды install.packages("wordcloud") ; потребуется также пакет RColorBrewer для создания палитры цветов - установите и его). Подобно функции generateCorpus() , создадим для удобства работы функцию generateWordcloud() :
Теперь у нас все готово для создания облака слов. Но перед тем как его нарисовать, следует еще раз вернуться к стоп-словам. Дело в том, что помимо упомянутых выше шумовых слов, в анализируемых нами сообщениях следует ожидать и ряда специфичных "шумов". Предварительный анализ показал, что стоит удалить как минимум следующие слова:
Эти дополнительные стоп-слова мы можем лекго добавить к стандартным при вызове функции generateCorpus() :
Создаем облако слов (число 15 в приведенной ниже команде соответствует минимальной частоте встречаемости, ниже которой то или иное слово в облако включено не будет; очевидно, что варьируя этот порог, можно получать несколько различающиеся варианты облаков):
Как видно из рисунка, одним из ключевых слов в сообщениях, опубликованных белорусскими пользователями сервиса Twitter 11 апреля 2012 г. примерно к 7 часам вечера, было minskblast . Фактически, это слово было хэштегом, которым отмечались многие сообщения в этот день. Вторая часть в этом составном слове - blast - значит "взрыв". Как известно, ровно год назад в минском метро произошло трагическое событие - теракт, в котором погибли 15 человек. Безусловно, это событие не могло не стать важной темой для обсуждений в белорусском обществе 11 апреля в этом году, что отразилось и в сообщениях среди белорусских пользователей Twitter'a.
Светлая память погибшим.
25 КомментарииЧто-то у меня такая ситуация:
> cred <- OAuthFactory$new(consumerKey="blabla", consumerSecret="blablabla", requestURL="https://api.twitter.com/oauth/request_token", accessURL="https://api.twitter.com/oauth/access_token", authURL="https://api.twitter.com/oauth/authorize" )> cred$handshake()Ошибка в function (type, msg, asError = TRUE) : SSL certificate problem, verify that the CA cert is OK. Details:error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed
Сергей, спасибо за наглядный пример.Хотелось бы узнать, есть ли в свободном доступе информация для более подробного изучения Text Mining: книги, блоги, видеокурсы и т. п. Что можете посоветовать?
И ещё давно интересует вопрос о том, как и какими средствами происходит сбор данных. В данном примере Вы указали Twitter, который предоставляет доступ к сообщениям, но ведь как-то анализируют информацию из социальных сетей, новостных ресурсов, блогов и так далее. То есть, анализ анализом, но как эта информация собирается и импортируется в R?
По поводу Вашего первого вопроса: свободно доступной информации в Сети по этой теме очень много - Гугл в помощь, как говорится. Если конкретно интересует информация по R - начните с поиска на r-bloggers.com и stackoverflow.com. Кроме того, на CRAN есть целый раздел, где перечислены основыне пакеты для анализа текстовых данных: http://cran.r-project.org/web/views/NaturalLanguageProcessing.html
Вторй вопрос: есть несколько пакетов, обеспечивающих "связь" R с социальными сервисами, в частности рассмотренный в этом пример twitteR и Rfacebook. Насчет новостных ресурсов - не знаю.
Сергей, я хотел бы поделится любопытными наблюдениями, с которыми столкнулся при работе с русскоязычным текстом.
1. При очистке текста от знаков пунктуации, цифр, и т. д. имеет место проблема "слипания соседних слов".Например: при чистке строки, которая содержит "и/или", функция removePunctuation() преобразует эту часть строки в "иили". Таже проблема возникает, если в сообщении пропущен пробел после запятой, точки и любого другого знака пунктуации. Тоже самое касается чисел, которые встроены в текст без пробела.Решил эту проблему с помощью функции str_replace_all() из пакета "stringr". В качестве замены символов выбираю пробел, а затем с помощью функции str_trim() удаляю лишние пробелы. Так слова остаются разделены, но при этом не слипаются. Правда делать все это приходится со строками не формируя корпус.
2. Буквы "ё" и "ч", почему-то, классифицируются R как знаки пунктуации - они удаляются из текстовых строк, при чистке пунктуаций. Над решением этой проблемы пока не думал.
Интересно узнать Ваше мнение по этим комментариям. Может я слишком все усложняю, и на самомо деле есть простое решение этих неудобств.
Сергей, всегда рад помочь:)Ещё забыл упомянуть о таком наблюдении: при выполнении функции removeWords(), чистка текста от шумовых слов происходит последовательно по списку стоп-слов. Из за того, что есть глюк с буквами "ё" и "ч", слова содержащие эти буквы могут быть очищены не корректно.
Приведу пример:> removeWords("Он очень ждал встречи с ней", c("о", "очень"))[1] "Он чень ждал встречи с ней"> removeWords("Он очень ждал встречи с ней", c("очень", "о"))[1] "Он ждал встречи с ней"
Как видите, в первом случае из слова "очень" выпала только буква "о" - в результате образовалось некорректное слово. Во втором случае, слово "очень" было корректно удалено из текста.Очевидно, на функцию влияет порядок стоп-слов. Поэтому, имеет смысл упорядочивать список со словами по убыванию количества символов. Тогда из текста будут, сначала, удалятся более специфические (длинные) слова, а затем более простые и односложные.Примерно так: MyStopWord[rev(order(nchar(MyStopWord)))]
Вполне может быть, что проблема имеет место и с другими словами, но я пока их не обнаружил.В общем, стоит быть внимательным с пакетом "tm". И Вы правы - лучше использовать регулярные выражения, и самому корректировать особенности чистки.
Сергей,спешу поделится радостью. Кажется удалось разобраться с проблемой выпадания букв при работе с русскоязычным текстом. Очевидно проблема в кодировке - нужно преобразовывать текстовые строки в кодировку UTF-8. Оказывается, для этого есть отдельная функция enc2utf8(). Подробнее можно почитать при запросе: ?Encoding
Пытался задать преобразование объекта в UTF-8 на этапе чтения файла .csv - почему-то не получилось, строки превращаются в набор бессмысленных символов. Если будете разбираться с этим вопросом - напишите пожалуйста, как должен выглядеть набор аргументов при чтении файла.
Сергей, добрый день! Нашла этот пост через гугл. Не могу разобраться вот с чем: если писать в searchstring запрос кириллицей, то в результате выдаются последние твиты согласно другим условиям, но без собственно слова-запроса.
Например по запросу searchTwitter(searchString="НБУ", lang="uk", n = 3)Выдается:[[1]] [1] "sparzicin: решебник ефимов демидович часть 1: решебник ефимов демидович часть 1"[[2]] [1] "anna_ponomaren: Шахтар - Фенербахче, вболіваймо за наших!!"[[3]] [1] "anthonyeyepecak: Реформа прокуратуры глазами юристов"
Сталкивались ли вы с таким, как это можно исправить? В сети вижу примеры с кириллицей только на Java, но не в R