Содержание


Смысловой анализ в среде больших данных

Comments

Смысловой анализ

Смысловой анализ — это применение методов текстового анализа к изучению данных из различных источников с целью обнаружения содержащихся в них мнений. Смысловой анализ часто применяется к данным, собираемым на web-сайтах и различных социальных платформах. Политические деятели и органы власти зачастую используют смысловой анализ для понимания того, как люди воспринимают их самих и их политики.

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

Работа с большими данными

Чтобы собирать данные в разных форматах (структурированные, полуструктурированные или неструктурированные) из множества источников, необходимо настроить кластер Hadoop и файловую систему Hadoop Distributed File System (HDFS) для хранения данных. HDFS предлагает гибкие возможности управления большими данными:

  • Некоторые из анализируемых данных можно перемещать в существующую реляционную СУБД (например, Oracle или MySQL), чтобы использовать существующие инструменты для бизнес-анализа и формирования отчетов.
  • В HDFS можно сохранять данные для будущего анализа, например, для сравнения старых данных с новыми, проводя такие тесты, как ANOVA.T.
  • Можно отбрасывать данные, если нужен только анализ данных в точке влияния.

Чтобы узнать больше о том, как настраивать кластер Hadoop, перемещать данные в HDFS и анализировать их в среде Hadoop, прочтите мою статью developerWorks Интеграция Hadoop с существующей реляционной СУБД.

Извлечение данных и их сохранение в HDFS

Эффективный смысловой анализ предусматривает использование данных из множества источников. В этой статье описывается извлечение данных из таких источников, как:

  • лента Twitter
  • RSS-лента
  • мобильное приложение.

Кроме того, объясняется, как сохранять данные из различных источников в файловой системе HDFS в кластере Hadoop.

Извлечение данных из ленты Twitter

Популярный сервис микроблогов Twitter имеет набор API-интерфейсов, позволяющих извлекать твиты и работать с ними. Но сначала нужно настроить OAuth-авторизацию в Twitter, чтобы приложение могло получать доступ к Twitter от вашего имени без вашего входа на web-сайт Twitter. Изучите процесс настройки на сайте разработчиков Twitter. В ходе этого процесса вам предоставляются ключи доступа, которые ваше приложение будет использовать для аутентификации от вашего имени. После аутентификации приложения можно будет использовать API-интерфейсы Twitter для выборки твитов.

Данные из ленты Twitter можно выбирать с использованием R или Jaql. Поскольку инструмент Jaql предназначен для обработки данных в формате JSON (а это формат данных твитов по умолчанию), применять Jaql удобнее. Причиной выбора R может быть лишь наличие навыков использования этого языка.

Извлечение данных из Twitter с использованием Jaql

После аутентификации приложения можно использовать API-интерфейс Twitter для выборки твитов.

Поскольку нам нужен потоковый режим, URL-адрес Twitter будет следующим:

url = "https://stream.twitter.com/1.1/statuses/filter.json?track=governmentTopic";

Замените governmentTopic на название анализируемой темы обсуждения. Твиты можно считывать в переменную, используя следующий код:

jsonResultTweets = read(http(url));
jsonResultTweets;

После запуска приведенного сценария Jaql будут выбраны твиты, относящиеся к выбранной теме обсуждения. Твиты возвращаются в формате JSON.

Если требуется понимать масштаб обсуждения темы с учетом местонахождения, можно использовать для выборки твитов следующий фрагмент кода:

governmentTopicDiscussionByLocation = jsonResultTweets -> transform
{location: $.location,user_id: $.from_user_id_str,date_created:
$.created_at,comment:$text} -> group by key = $.location

Затем можно сохранить эту информацию в HDFS с использованием следующего фрагмента кода:

governmentTopicDiscussionByLocation Cnt ->
write(del("/user/governmentTopics/governmentTopic_1Tweets.del", schema =
schema { list_of_comma_seperated_json_fields}

где list_of_comma_seperated_json_fields — это следующие поля через запятую: location, from_user_id_str и created_at.

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

url = "https://stream.twitter.com/1.1/statuses/filter.json?track=governmentTopic"; 
 jsonResultTweets = read(http(url));
jsonResultTweets;
governmentTopicDiscussionByLocation = jsonResultTweets -> 
transform {location: $.location,user_id: $.from_user_id_str,user_name:
  $.user.name,user_location: $.user.location,date_created: $.created_at,comment: $.text} -> 
group by key = $.location 
governmentTopicDiscussionByLocation -> 
write(del("/user/governmentTopics/governmentTopic_1Tweets.del", 
  schema = schema {location,user_id,user_name,user_location,date_created,comment}

Метод transform очищает данные, а метод write сохраняет данные в HDFS. Для работы с потоковыми данными (или данными в движении) необходимо интегрировать этот сценарий с Flume, еще одним инструментом для работы с большими данными в экосистеме Apache Hadoop. (Чтобы узнать больше о Flume, прочтите статью developerWorks Развертывание масштабируемых web-сервисов и их поддержка с помощью Flume.)

Извлечение данных из Twitter с использованием R

Для извлечения твитов с использованием R необходимо установить на систему несколько пакетов. Это можно сделать в RStudio, но в данном примере демонстрируется использование консоли R.

На системе под управлением Ubuntu выполните следующие действия:

  1. Установите пакеты:
    libcurl4-gnutls-dev 
    libcurl4-nss-dev 
    libcurl4-openssl-dev 
    r-base r-base-dev
    r-cran-rjson
  2. Откройте консоль R и выполните следующие команды для получения доступа к Twitter:
    install.packages(“twitteR”)
    install.packages(“ROAuth”)
    install.packages(“RCurl”)
  3. Загрузите в рабочее пространство R следующие библиотеки:
    rm(list=ls())
    library(twitteR)
    library(ROAuth)
    library(RCurl)

Теперь для аутентификации в Twitter можно использовать следующий сценарий R:

download.file(url="http://curl.haxx.se/ca/cacert.pem",destfile="cacert.pem")
requestURL <- "https://api.twitter.com/oauth/request_token"
accessURL <- "https://api.twitter.com/oauth/access_token"
authURL <- "https://api.twitter.com/oauth/authorize"
consumerKey <- myConsumerKeyFromTwitter
consumerSecret <- myConsumerSeccretFromTwitter
myCred <- OAuthFactory$new(consumerKey=consumerKey,
                             consumerSecret=consumerSecret,
                             requestURL=requestURL,
                             accessURL=accessURL,
                             authURL=authURL)

accessToken <- myAccessTokenFromTwitter
accessSecret <- myAccessSecretFromTwitter

setup_twitter_oauth(consumerKey,consumerSecret,accessToken,accessSecret)

Затем для выборки твитов можно использовать следующий фрагмент кода:

govt_sentiment_data <- searchTwitter("#keyWord",since={last_date_pulled}

где keyWord — это анализируемый предмет обсуждения, а last_date_pulled — это дата последней выборки твитов.

Если необходима потоковая доставка данных Twitter с автоматическим извлечением данных через определенные интервалы времени, замените предыдущий фрагмент кода следующим:

govt_sentiment_data <- filterStream( file="tweets_rstats.json",
track="#keyWord", timeout=3600, oauth=myCred)

Для очистки данных можно использовать следующий сценарий R:

govt_sentiment_data_txt = govt_sentiment_data$text
# remove retweet entities
govt_sentiment_data_txt = gsub(“(RT|via)((?:\\b\\W*@\\w+)+)”, “”, tweet_txt)
# remove at people
govt_sentiment_data_txt = gsub(“@\\w+”, “”, tweet_txt)
# remove punctuation
govt_sentiment_data_txt = gsub(“[[:punct:]]”, “”, tweet_txt)
# remove numbers
govt_sentiment_data_txt = gsub(“[[:digit:]]”, “”, tweet_txt)
# remove html links
govt_sentiment_data_txt = gsub(“http\\w+”, “”, tweet_txt)
# remove unnecessary spaces
govt_sentiment_data_txt = gsub(“[ \t]{2,}”, “”, tweet_txt)
govt_sentiment_data_txt = gsub(“^\\s+|\\s+$”, “”, tweet_txt)
govt_sentiment_data_txt=gsub(“[^0-9a-zA-Z ,./?><:;’~`!@#&*’]”,””, tweet_txt)

И наконец, для сохранения очищенных данных в HDFS можно использовать следующий фрагмент кода:

hdfsFile <- hdfs.file("/tmp/govt_sentiment_data.txt", "w")
hdfs.write(govt_sentiment_data_txt, hdfsFile)
hdfs.close(hdfsFile)
write(govt_sentiment_data, "govt_sentiment_data.txt")

Извлечение данных из RSS-лент

Мы также хотим собирать личные мнения и взгляды из новостных статей. Для получения данных из RSS-лент я предлагаю использовать сочетание Java и Rome. Rome — это Java-библиотека, используемая для получения доступа к новостным лентам на web-сайтах и их использования.

В данном примере мы получаем следующую информацию о новостной статье: заголовок, ссылка и описание. Затем мы извлекаем нужную нам информацию из этих элементов данных.

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

Следующий Java-код идентифицирует новостную ленту и использует ранжирование страниц для определения значимости для наших данных:

private static void getFeeds(String newsFeedUrlLink){

File f = new File(“newsFeeds.txt”);
        boolean ok = false;
            try {
                URL feedUrl = new URL(newsFeedUrlLink);
                SyndFeedInput input = new SyndFeedInput();
                InputSource source = new InputSource(feedUrl.openStream());
                SyndFeed feed = input.build(source);
                for (Iterator i = feed.getEntries().iterator(); i.hasNext();) {
                   SyndEntry entry = (SyndEntry) i.next();
		 writeToFile(f,entry);
                       }
                ok = true;

            }
            catch (Exception ex) {
                ex.printStackTrace();
                System.out.println("ERROR: "+ex.getMessage());

            }
        if (!ok) {
            System.out.println();
            System.out.println("FeedReader reads and prints any RSS/Atom feed type.");
            System.out.println("The first parameter must be the URL of the feed to read.");
            System.out.println();

        }

    }

private static void writeToFile(File f, SyndEntry entry) throws IOException {
		FileWriter fw = new FileWriter(f.getName(),true);
		   BufferedWriter bw = new BufferedWriter(fw);
		   bw.write(entry.getTitle()+”\n”);
		   bw.close();

	}

Затем можно использовать приведенный ниже фрагмент кода для сохранения данных в HDFS-файл, созданный с использованием данных из Twitter. Для добавления данных в этот HDFS-файл необходимо изменить значение свойства dfs.support.append в файле hdfs-site.xml, поскольку по умолчанию HDFS не позволяет добавлять данные в файл.

mydata <- readLines("newsFeeds.txt")
myfile <-  hdfs.file("/tmp/govt_sentiment_data.txt", "r")
dfserialized <- hdfs.read(myfile)
df <- unserialize(dfserialized)
hdfs.close(myfile)

//write(mydata, file = "/tmp/govt_sentiment_data.txt",append = TRUE)
hdfs.write(mydata, file = "/tmp/govt_sentiment_data.txt",append = TRUE)
government_sentiment_data <- read.hdfs(“/tmp/govt_sentiment_data.txt”)

Извлечение данных из мобильного приложения

Данные из Twitter и RSS-лент можно дополнить данными из мобильных приложений, содержащих личные мнения и взгляды. В нашем примере предполагается, что вы создали простое мобильное приложение, которое устанавливается на мобильные устройства, позволяя пользователям высказывать свое мнение о государственных политиках и связанных темах. J2ME-приложение можно разместить на WAP-сервере, откуда мобильные устройства (даже такие старые, как Nokia 3310) могут загрузить приложение и установить его. Предоставляемая пользователями информация отправляется в реляционную СУБД и хранится для будущего анализа.

Для перемещения данных с сервера реляционной СУБД в кластер Hadoop можно использовать инструмент Sqoop. Выполните следующий сценарий sqoop в кластере Hadoop:

sqoop import --options-file dbCredentials.txt --connect
jdbc:mysql://217.8.156.117/govt_policy_app --table opinions –-target-dir /tmp \ --append

Флаг --append означает, что Sqoop добавит импортированные данные в уже имеющийся набор данных, полученных прежде из других источников, как это указано флагом --target-dir.

Объединение собранных данных в один источник

Мы собрали данные из Twitter (с использованием Jaql или R), из RSS-лент (с использованием Java) и из мобильного приложения (с использованием Sqoop), записав эти данные в один HDFS-файл. Можно автоматизировать эти сценарии с помощью механизма потока работ Oozie и задать выполнение команд через определенные интервалы или по триггерному событию. Для получения дополнительной информации о настройке Sqoop и Oozie прочтите мою статью developerWorks Интеграция Hadoop с существующей реляционной СУБД.

Поток работ Oozie можно усовершенствовать, введя ограничения для уменьшения дублирования данных, которое естественным образом возникает при сборе данных из разных источников. Например, в наборе данных можно ввести следующие ограничения: одна учетная запись в Twitter для каждой темы и один мобильный номер для каждого мнения.

Смысловой анализ комбинированных данных

Объединение данных позволяет проводить смысловой анализ с использованием одного источника данных, что обеспечивает единообразие, согласованность и точность анализа. Для выполнения такого анализа можно использовать R, Jaql, Pig или Hive. Pig и Hive — это языки с синтаксисом, похожим на SQL, который выполняется на платформе Hadoop. В данном примере для анализа извлеченных данных я решил использовать R, поскольку R имеет развитые встроенные средства моделирования и библиотеки для создания графических представлений, такие как ggplot2.

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

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

sentiment.pos=scan('/Users/charles/Downloads/r/positive-words.txt',what='character',comment.char=';')
sentiment.neg=scan('/Users/charles/Downloads/r/negative-words.txt',what='character',comment.char=';')
pos.words=c(sentiment.pos,'good','reelect','accountable','stable')
neg.words=c(sentiment.neg,'bad','corrupt','greedy','unstable')

Следующий код представляет алгоритм оценки эмоциональной окрашенности:

require(plyr)
require(stringr)
score.sentiment = function(sentences, pos.words, neg.words, .progress='none')
{
sentence = tolower(sentence)
word.list = str_split(sentence, '\\s+')
words = unlist(word.list)
pos.matches = match(words, pos.words)
neg.matches = match(words, neg.words)
pos.matches = !is.na(pos.matches)
neg.matches = !is.na(neg.matches)
score = sum(pos.matches) - sum(neg.matches)
return(score)
}, pos.words, neg.words, .progress=.progress )
scores.df = data.frame(score=scores, text=sentences)
return(scores.df)
}

Затем мы можем вызвать функцию этого алгоритма для оценки эмоциональной окрашенности собранных данных с использованием следующего фрагмента кода:

require(plyr)
opinion.score <- score.sentiment(opinion.txt,pos.words,neg.words,progress='text')

И наконец, можно выполнить дополнительный анализ, применяя встроенные в R средства визуализации, и построить оценочную диаграмму с использованием следующего фрагмента кода:

library("ggplot2")
hist(opinion.scores$score)
qplot(opinion.scores$score)

Анализ данных можно продолжить с использованием BigSheets, компонента платформы IBM InfoSphere BigInsights. Этот инструмент предоставляет пользователям, не имеющим технических навыков, возможность выполнять различные варианты анализа и просматривать данные на диаграммах. Для получения дополнительной информации об использовании инструмента BigSheets прочтите статью developerWorks BigSheets для простого пользователя.

Заключение

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


Ресурсы для скачивания


Похожие темы


Комментарии

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

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=40
Zone=Большие данные и аналитика
ArticleID=1023598
ArticleTitle=Смысловой анализ в среде больших данных
publish-date=12082015