Friday, October 4, 2013

Visual story about a Zebra (d3.js + animal movements)

I was on adding some data related cover image to this blog and I found a database about animal movements.  They are tracking several animals all over the world and the tracking data is publicly available. After short browsing I downloaded the track record (.csv) of a Zebra in the heart of Africa.

As I was interested only in the time and position data I made some preprocessing in python. The final output was 4 data columns: the longitude, latitude, the seconds to the next tracking point and the hour if the day. I included the sample code if you are interested in the details:


Finally I just included the result in the JS file as a JS array. After we have the data points in an array it's quite easy to draw the tracking points. Of course I wanted to use d3.js as it is my favorite visualization "tool" :)

The idea was not just simply draw the points but additionally:
  • Small arrows display the directions.
  • The size of the points are the function of the time elapsed to the next tracking point. If the tracking points are recorded more rarely the points are bigger.
  • The color of the points depend on the time of the day when the tracking events were recorded. Green for the early morning, yellow for morning, orange around noon, read for the afternoon and purple for nigth.
So instead this:

Something like this:

Datails about the d3.js code:

Nodes are generated with gradients to make them really nice. And also partially transparent to visualize overlapping. Here is a magnified part:


This circles are drawn like this:
The connection of the circles was a bit mor complicated. Originally I intended to use svg path for the lines, but with it I had problems to drow the small arrows so I had to draw each line separately.

You can check the endresult in the header ;) It was also interesting to see that the visualization inspired ideas about the locations: The big yellow and orange circles are located mostly around a limited area in lower middle part. Probably there is a pasture or some water where is a good place for the zebras to spend the day. Interestingly the zebra is wandering a lot in the night and early morning. I also think they are sleaping at a different location than they are spending the day at. Of course this are just presumptions but it was good to see that a more sofisticated visualization can tell so much more about the data.

The full image:

Wednesday, October 2, 2013

Upside down funnel 2: satisfied customer leads to leads

“I told my friend that we discovered this “upside down funnel” approach in the early days, and never really grew out of it (because it’s worked). When you see our strange billboards that don’t even say our name, or when you see our random “high five” shirts, vinyl toys, or hear ridiculous radio ads, just know that they defy logic because they’re for our existing customers. We’re not going for new leads, let alone conversions or whatever they teach you in Marketing 101. We’re going for customer service. Which, by the way, leads to leads.” - Ben Chestnut, Co-Founder Mailchimp
Read Ben’s full post. It’s wonderful.

Wednesday, September 11, 2013

The engagement pyramid - flipping your funnel upside down

So, why don’t we flip that 100% winnowed to 30% winnowed to 5% funnel? Rather than starting by thinking about how to reach or broadcast to as many people as possible to get to those who matter, what if we began with engaging those who matter the most. We could prioritize surfacing the 5% — and make our entire plan better by learning from their interactions and leaning on their advocacy to expand our reach in a smarter way... 
 By turning the reach-driven funnel upside down, we’re in effect creating an ‘engagement pyramid’. The engagement pyramid isn’t just about retention and growth of our existing customer base. It’s about starting with the 5% who will be most interested in what we have to say and most willing to speak for us. This group not only includes current customers, but also those most likely to influence others toward your brand. This is the group whose insights and advocacy can better inform and enhance our broader media plan, maximizing our overall engaged reach.



read more: the engagement project (google)

Sunday, September 8, 2013

Correlation of investment funds - python pandas

While playing around with python data mining framework Pandas I really liked how easy it is to calculate pairwise correlation in data series. Let's check out a sample. As data we can download historical investment fund data and we will calculate the correlation between them.

note 1.: If you are using windows the easiest way to install python with every necessary packages is the Anaconda distribution. Just download and run the installer from here and you are ready to start :)


note 2.: It wasn't easy to find historical data about investment funds. Finally I get the data from Bloomberg website. It was a kind of reserve engineering by checking the network communication when the site was drawing the graphs so there is no warranty that the data format won't change in the future. If somebody know better way to get this data I would be happy to hear about it.

Let's download first the data into an array:


Now we load it into a Pandas DataFrame and plot it (maybe you have to import matplotlib first):


The two dataframe has to contain data for the same period of time so we can simply merge them:

The result is:

Finally let's calculate the correlation:

And we get the pairwise correlation of the numeric columns:

Friday, August 30, 2013

Django unchained - python in the cloud

I was experimenting with the django web framework. First I found this helpful tutorial: http://effectivedjango.com/tutorial/getting-started.html. I really liked that it's starting from the basics which makes it usable for python beginners too.

After reading the tutorial I wanted to create a django project in the cloud. My first idea was to use Google App Engine because it has python support and it's free for small projects. I found this tutorial http://www.allbuttonspressed.com/projects/djangoappengine about running django projects on Google App Engine but I realized that I have to extend django with support for non relational databases. I found this step a bit complicated. There was an other tutorial to run django with Google Cloud SQL but it turned out to have no free version.

So keep the story short after spending several hours to find out how to run my django project on Google App Engine I find myself in searching for other free django hosting solutions. And I come across pythonanywhere.com and it was a really nice surprise for me. It doesn't have so many features like Google App Engine but it's optimized for python. I finished the registration in 5 minutes and it was really easy to find a description how to run django project here (https://www.pythonanywhere.com/wiki/DjangoTutorial). It took me just 30 minutes to configure everything end write a hello world application from the scratch in their in browser console (yes, they have an in browser bash console) and open it in my browser for the first time.

So just to summarize my positive impressions about pythonanywhere.com:
  • free plan with mysql support
  • web based bash console
  • really easy to set up
  • good tutorial (first I missed how to refresh the server, but it was just at the end of the tutorial)
  • they have dropbox sync which makes synchronization very straightforward
  • easy way to check access and error logs
I also heard good things about heroku. They also have a good getting started guide. Maybe worth to try it as well:  https://devcenter.heroku.com/articles/django

Additionally here is a really short introduction video:

Tuesday, August 13, 2013

Simple A/B test in Google Analytics

Google has it's A/B testing solution called "Content Experiments". Originally it was designed to test different page alternatives. In this case you had to build two different version of the whole page or website (link). This can be quite complicated. Google announced his new "Content Experiment API" which is more flexible but for me it's also a bit complicated for very simple tests. On the other side there is a really simple way to implement A/B tests on a website. Let's see how!

For the A/B testing we will use a couple of lines of JavaScript code. You can do any kind of split on your users but for now we will use a simple random split. The result of the split is stored in a long living cookie.


After having the A/B test cookie, the only thing you have to do, is changing your site behavior based on the cookie and passing the group value to the Google Analytics.
Very simple content experiment. ]]>
To have the same groups in the Google Analytics you only have to add this two lines to your original GA tracking code (more description in GA help): ]]>
To check the result in GA you only have to define custom filters in GA. Here are some screen shots how to do this:



Sunday, July 21, 2013

Vectorize Image with Python scikit-image

Short story: a friend of mine wanted to display an interactive dental chart on the web but most of the images he found was some hand-drawn image which wasn't fit into his site look-and-feel. So decided to vectorize one image, it shouldn't be a hard task ...
After some research I end up here:  http://scikit-image.org/docs/dev/auto_examples/ and I succeeded to get vectorized outlines in an hour. Lets go through it step-by-step:

0. This is an image with teeth I wanted to get in vectorized format, each tooth separately:


I have anaconda on my windows machine but if you have python with the general science tools (numpy, matplotlib, skimage, skipy) this code should work for you.

1. Loading the image from the file. With imread we get a 3D numpy array. In the 3rd dimension are the RGB values:


2. In the samples the algorithms where used on grayscale images, so firstr I had to convert the image to grayscale. This means I get a 2D array from the 3D one.

If it's needed the image can be croped simply with array slice (e.g.: cropedimg = gimg[330:480, 50:480]) and with matplotlib the image can be displayed any time just calling imshow(gimg).

3. Detecting the contours with skimage.

As result we get an array containing the vector representation of all found contour lines separately. Let's display the results:

4. For me the contour line was too detailed and rough so I wanted to have a more schematic result. With the tolerance parameter it's possible to set how detailed is the approximation. Finally we print an original and an approximated contour.