Tweet Emotion: Realtime Tweet Pseudo-Analysis with PubNub Data Stream

Tomomi Imura, @girlie_mac

Realtime Tweet Analysis with PubNub Data Stream

Tomomi Imura

tweet me

"How is America feeling now?"

Visualized cartographic data of the emotional "state" of each state at any given moment

http://pubnub.github.io/tweet-emotion/

Pseudo-analysis

Positive or negative sentiments are loosely determined based on an analysis of keywords used in tweets


positiveWords = [
  'excellent', 'amazing', 'marvelous', 'magnificent', 
  'fabulous', 'astonishing', 'fantastic', 'peaceful', 
  'brilliant', 'glorious', 'cheerful', 'gracious', 
  ...
];

Process

  1. using TopoJSON to display a US state map using d3.js
  2. using PubNub JavaScript API to consume Twitter stream
  3. colorizing the map by moods

GeoJSON

TopoJSON

TopoJSON

Render TopoJSON with D3.js


var svg = d3.select('#map').append('svg')
  .attr('width', 900).attr('height', 550);

var path = d3.geo.path().projection(d3.geo.albersUsa());

Render TopoJSON with D3.js

var g = svg.append('g');

d3.json('us-states.json', function(error, topology) {
  g.selectAll('path')
    .data(topojson.feature(topology, 
      topology.objects.usStates).features)
    .enter().append('path')
    .attr('class', function(d){ 
      return 'states ' + d.properties.STATE_ABBR;} )
    .attr('d', path)
    .attr('fill', 'gray')
});

Getting Realtime Tweets from PubNub Stream

Getting Started with PubNub APIs


<script src="//cdn.pubnub.com/pubnub.min.js"></script>
		
var channel = 'pubnub-twitter';

var pubnub = PUBNUB.init({
  subscribe_key:'sub-c-78806dd4-42a6-11e4-aed8-02ee2ddab7fe'
});
		

Receiving Live JSON Data

To retrieve the live tweets, you simply use PubNub subscribe() API.


pubnub.subscribe({
  channel: channel,
  callback: processData
});
		

Pseudoanalyze Tweets

Create a mini dictionary that describes moods


var positiveWords = [
  'excellent', 'amazing', 'happy', 'magnificent', ':)', 
  ...
];
var negativeWords = [
  'unhappy', 'sorry', 'annoyed', 'dislike', 'anxious', ':(', 
  ...
];
		

Pseudoanalyze Tweets

See if these words are used in each tweet, in the callback function

function processData(data) {
  // looking for US data only for this demo
  if(data.place.country_code !== 'US') return;

  // Check if emotional words are used in the tweet
  if (positiveWords.some(function(v) { 
      return data.text.toLowerCase().indexOf(v) > 0; })) {
    displayData(data, positive);
  } else if
    ...
}
		

Pseudoanalyze Tweets

Create a mini dictionary that describes moods

var positiveWords = [
  'excellent', 'amazing', 'happy', 'magnificent', ':)', 
  ...
];
var negativeWords = [
  'unhappy', 'sorry', 'annoyed', 'dislike', 'anxious', ':(', 
  ...
];
		

Display Data on Map

function displayData(data, emotion) {
  var state = data.place.full_name.substring(
    city.lastIndexOf(',')+1).trim();
		
  if(document.querySelector('.'+state)) {
  var stateEl = document.querySelector('.'+state);
    
  // count
  tally[state] = (tally[state] || {positive:0, negative:0});
  tally[state][emotion] = (tally[state][emotion] || 0) + 1;

  ...
		

...cont'd


  // colorize svg path	
  stateEl.style.fill = (
    tally[state].positive > tally[state].negative) 
      ? 'pink' : 
      ((tally[state].positive < tally[state].negative) 
      ? 'turquoise' : 'beige'); 
    }	
  }
}
		

Full Article

blog.twitter.com

Thank you!

Tomomi Imura @ PubNub

pubnub.com
@pubnub
@girlie_mac
github.com/pubnub

Photo Credit