Статьи

Анализ Twitter в реальном времени

API Twitter — отличный инструмент для анализа твитов по коду. В частности, потоковый API предоставляет доступ в реальном времени к глобальному потоку твитов и, в отличие от обычного REST API, используется через постоянное соединение с серверами Twitter. Поэтому требуется постоянное HTTP-соединение, открытое до тех пор, пока вам нужно собирать твиты. Типичный рабочий процесс приложения, использующего этот API, следующий: 

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

from __future__ import division
from collections import defaultdict
from pylab import barh,show,yticks
import pycurl
import simplejson
import sys
import nltk
import re




def plot_histogram(freq, mean):
 # using dict comprehensions to remove not frequent words
 topwords = {word : count 
             for word,count in freq.items() 
             if count > round(2*mean)}
 # plotting
 y = topwords.values()
 x = range(len(y))
 labels = topwords.keys()
 barh(x,y,align='center')
 yticks(x,labels)
 show()




class TwitterAnalyzer:
 def __init__(self):
  self.freq = defaultdict(int)
  self.cnt = 0
  self.mean = 0.0
  # composing the twitter stream url
  nyc_area = 'locations=-74,40,-73,41'
  self.url = "https://stream.twitter.com/1.1/statuses/filter.json?"+nyc_area




 def begin(self,usr,pws):
  """ 
    init and start the connection with twitter using pycurl
    usr and pws must be valid twitter credentials
  """
  self.conn = pycurl.Curl()
  # we use the basic authentication, 
  # in future oauth2 could be required
  self.conn.setopt(pycurl.USERPWD, "%s:%s" % (usr, pws))
  self.conn.setopt(pycurl.URL, self.url)
  self.conn.setopt(pycurl.WRITEFUNCTION, self.on_receive)
  self.conn.perform()




 def on_receive(self,data):
  """ Handles the arrive of a single tweet """
  self.cnt += 1
  tweet = simplejson.loads(data)
  # a little bit of natural language processing
  tokens = nltk.word_tokenize(tweet['text']) # tokenize
  tagged_sent = nltk.pos_tag(tokens) # Part Of Speech tagging
  for word,tag in tagged_sent:
   # filter sigle chars words and symbols
   if len(word) > 1 and re.match('[A-Za-z0-9 ]+',word):
    # consider only adjectives and nouns
    if tag == 'JJ' or tag == 'NN':
     self.freq[word] += 1 # keep the count
  # print the statistics every 50 tweets
  if self.cnt % 50 == 0:
   self.print_stats()




 def print_stats(self):
  maxc = 0
  sumc = 0
  for word,count in self.freq.items():
   if maxc < count:
    maxc = count
   sumc += count
  self.mean = sumc/len(self.freq)
  print '-------------------------------'
  print ' tweets analyzed:', self.cnt
  print ' words extracted:', len(self.freq)
  print '   max frequency:', maxc
  print '  mean frequency:', self.mean




 def close_and_plot(self,signal,frame):
  print ' Plotting...'  
  plot_histogram(self.freq,self.mean)
  sys.exit(0)

В конструкторе этого класса мы инициализируем словарь, который будет содержать частоту каждого слова, строку, содержащую URL-адрес службы, которую мы должны вызвать (составленной для запроса твиттера в твиттере в Нью-Йорке), и переменные 
cnt  и 
означает  отслеживать количество проанализированных твитов и среднюю частоту по всем словам.

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

Метод 
print_stats  используется для печати нашей статистики на консоли, в то время как
close_and_plot  строит гистограмму с использованием частот в словаре и закрывает программу. 

Давайте использовать этот класс:

import signal
usr ='supersexytwitteruser'
pws ="yessosexyiam"

ta =TwitterAnalyzer()# invoke the close_and_plot() method when a Ctrl-D arrives
signal.signal(signal.SIGINT, ta.close_and_plot)
ta.begin(usr,pws)# run the analysis

В приведенном выше коде создается 
экземпляр  объекта TwitterAnalyzer , его метод 
close_and_plot  регистрируется как обработчик для сигнала SIGINT и, наконец, 
 вызывается
начало

Этот код запускает программу, которая анализирует все твиты в районе Нью-Йорка в реальном времени и печатает статистику каждые 50 твитов, как показано ниже:

-------------------------------
 tweets analyzed: 50
 words extracted: 110
   max frequency: 8
  mean frequency: 1.12727272727
-------------------------------
 tweets analyzed: 100
 words extracted: 200
   max frequency: 22
  mean frequency: 1.235
-------------------------------
 tweets analyzed: 150
 words extracted: 286
   max frequency: 29
  mean frequency: 1.26573426573
-------------------------------
 tweets analyzed: 200
 words extracted: 407
   max frequency: 39
  mean frequency: 1.31203931204
-------------------------------
 tweets analyzed: 250
 words extracted: 495
   max frequency: 49
  mean frequency: 1.37575757576

Нажав Cntrl-D, мы можем остановить программу и построить гистограмму обнаруженных прилагательных и существительных. Вот что я получил утром 21 марта 2013 года: 


[a href = «http://2.bp.blogspot.com/-CqZfNQDCgvY/UUnTMFHCWtI/AAAAAAAAAk4/y7I_7HWt57M/s1600/twitterHistogram.png» imageanchor = «1» style = «text-художественное оформление: нет цвет: нет; 125, 24, 30); «]

Мы видим, что очень часто можно публиковать ссылку в твиттере (оказалось, что http в большинстве случаев считается существительным) и что слова день, сегодня, добро и утро были наиболее часто используемыми при анализе.