Posts Tagged ‘tunkrank’

War on Attention Poverty

Posted: 14 July 2010 in Uncategorized
Tags: , ,

Daniel Tunkelang has posted his slides from his talk at AT&T Labs on TunkRank over at the Noisy Channel. Embedded below for your viewing pleasure:


TunkRank, Meet Tickery

Posted: 5 May 2010 in Uncategorized
Tags: , , ,

Tickery is a rather awesome application of FluidDB that lets you explore Twitter in a number of ways. I mentioned previously in post on recent TunkRank improvements that TunkRank scores would soon be integrated with Tickery, and thanks to Terry Jones and his crew, the time is now!

Full disclosure: I’m a fan of FluidDB. I think it’s an awesomely useful technology and concept and I’m happy that TunkRank scores can be a part of it. One cool thing is that FluidDB’s permission system is designed so that even though Tickery is using TunkRank’s data, TunkRank still owns it. It can be revoked at any time if there was a reason to do so (not that I can imagine such a thing will ever be the case). Also, the data in FluidDB for Tickery and TunkRank are completely independent. Anyone else can come along and add a new set of data for mash-ups that would then use all three, without TunkRank or Tickery having to do a thing.

Playing around with Tickery

Now when you use the advanced search on Tickery, you can filter your results by TunkRank score, letting you do some interesting combinations on the data. For example, if I want to see who I’m following TunkRank scores greater than 50:

has and > 50

There’s lots to play around with there, especially when you start comparing the friends of various users. For example, if you wanted to know who Daniel Tunkelang (@dtunkelang) and I both follow who have TunkRank scores less than 20:

has and
has and < 20

Those people have something clearly in common, and it tells you something about the interests that Daniel and I share. I hope you check it out and let me know what you think.

TunkRank Improvements

Posted: 17 February 2010 in Uncategorized
Tags: , , , , , , , , ,

Over the past few weeks, I’ve been working on a number of improvements to TunkRank that I will be rolling out tonight. First, I’ve secured a server to host it on, rather than my old Dell laptop, so reliability should improve and TunkRank is no longer a slave to dynamic DNS problems. Also, my cable company is less likely to hunt me down. TunkRank has gotten some increased attention over the past few weeks, including from Chris Dixon, CEO of the wonderful website hunch:

Twitter could fix the whole follower obsession by highlighting a more meaningful metric like TunkRank.

Awesome! So with this new version, there are a few changes that will immediately impact you, the end-user. I’ll go into the ones that affect you the most first, followed by some technical points of interest for those who care. Then I’ll conclude with a couple of hints at the future.

Changes to TunkRank

First and foremost, I have changed the main score that is reported. Previously I was using a percentile in the range (1-100). This got a lot of objections and created confusion. Partially because I consider the 100th percentile to be the “top-tier” of users, while standardized testing often reports the 99th percentile to mean you performed better than 99% of the population. Also, most people who actually care about their scores enough to use TunkRank are in the 95-100 percentile range, making more fine-grained comparisons difficult. Neal Richter even posted on his blog some suggestions for improving it (quite a while ago, now).

I took a page out of Neal’s book with the log scores, but I also put it in a range where the most influential twitter user (let’s call her MAX) will always have a score of 100. Your TunkRank Score™ is the ratio of the log of your raw score to the log of MAX’s score. So formulas aside, this means your TunkRank score is directly comparable to other users and is always in perspective of the maximum influence exerted by any user in the Twitterverse. Incidentally, comparing users with a difference of seven TunkRank score points means the user with the higher score is about twice as influential.

Accessing the API has also changed slightly, and I apologize to anyone actually using it at the moment. Basically, I am matching the API calls to more closely conform to the URLs used on the web side, and I’m returning more information with each call. TunkRank also supports XML responses in addition to JSON. You can find all of the documentation here.

Some Technical Notes

As part of the move, I’ve decided to transition from using Merb to Rails. My original decision to use Merb was partially as a learning exercise, but also because Merb appealed to me with its being lightweight. However, I often ran into roadblocks because some useful plugin wasn’t supported (or I couldn’t figure out how to make it work in the limited time I had). Sometimes the documentation for Merb was very good and sometimes it was absent altogether. Rails, on the other hand, has a substantial amount of documentation and people are always blogging about the best way to do things — which makes life as a developer much easier. Rails is my day job, so I knew I could transition quickly and easily.

I also migrated from MySQL to PostgreSQL. The main reason is that I love PostgreSQL — plain and simple. They both have their advantages, but MySQL gives me a sense of uneasiness I don’t have with PostgreSQL. I’ve managed to achieve some nice speed improvements as part of the redesign, though that is not to say that the same speed improvements wouldn’t have been possible with MySQL.

I’ve also adopted Resque as my background job-processing library. It is backed by Redis, an advanced key-value store that you can think of as a “data structures server.” The important thing for me is that Resque is fast, has a kick-ass web interface, and integrating with Rails is brain-dead easy.

The Road Ahead

I wrote before about the road ahead for TunkRank, and I have mostly held to it. I have many more ideas I want to expand on, including topic-sensitive influence rankings. I like the ideas in the recent WSDM paper (pdf) by Weng et al, but I have a few new ideas I’m eager to try out. TunkRank scores may also be integrated into Tickery in the near future, thanks to some discussions with Terry Jones of FluidDB.  I’m excited!

Earlier today, I was checking out the suggested connections provided by re-searchr (by James Ostheimer, @jostheim).  A discussion arose around ranking suggested users and potentially using a measure like TunkRank as a part of that ranking.  The prospect of James having to reimplement TunkRank encouraged me to implement a part of the TunkRank API I had been planning for a while:  fetching a user’s TunkRank score.

Fortunately, Merb is a framework that makes it particularly easy to render a page in different formats without having to add a lot of new code.  The end result is a very simple first step that returns the raw TunkRank score in JSON format.  You can access it via the following RESTful url:{username}.json

If the user has not had their TunkRank score calculated yet, the return value will be 0, otherwise it will be a number greater than or equal to one. New users are added to a queue and are ranked at various points throughout the day when usage is low. It’s on my TODO list to make this happen more frequently. I can only blame its neglect on forgetfulness.

Daniel already has a write-up on this fledgling API. I’ve been busy watching the first week of In Treatment on DVD — a show that is turning out to be very intriguing. I realize that has nothing to do with the rest of the post, but I liked the show so much I had to tell someone. :)

The Road Ahead for TunkRank

Posted: 6 March 2009 in Uncategorized
Tags: , , , ,

Now that TunkRank has gone live, I am faced with some interesting choices.

First of all, I want to make the code open source. The only barrier to my doing that is that I have passwords saved in version control that really can’t be shared with the outside world. I didn’t even think about that being an issue until I was actually deploying it and saw someone mention it in a blog tutorial. There are ways of getting around this problem, and I’ll have to look into them before I can do it.

Next is the issue of expanding the size of the explored social graph. Right now I have found about 2 million users and know the followers of 500 thousand of those. When I was doing everything in memory, it was very fast for me to expand it and relatively easy to merge them. Now I am using a database (MySQL) and doing operations on it for the social graph are just not fast. So I need something better.

Also, I want to make the TunkRank scores available as a data set or at least via an API, so I need to look into ways of doing that. Merb makes it pretty easy to deliver results as xml or json — I just have to get around to doing it. Right now you can find user jimbob’s TunkRank score either by entering “jimbob” in the search box on the main page or by going to the URL Extracting it via json or xml will be just a matter of going to

I need to provide additional scoring systems other than TunkRank, so that TunkRank can be compared. I’m not sure whether this isn’t something better served by just providing the data set and letting people play around in their own database or if I should provide alternate views. The former is more versatile, the latter will probably reach a larger audience.

Currently I show Google ads on TunkRank, mainly because I have spent a small amount of money on it and wouldn’t mind getting that back. If it starts making any real kind of money, that probably means the traffic has increased significantly and I will need to look at hosting it on EC2 or somewhere. I have no illusions that TunkRank will make me rich. I expect it will make me literally tens of dollars … poorer. :)

Finally, there is the issue of the score I display. I chose to show the percentile ranking because it’s easy to see where you are in comparison to other twitter users. If I just showed you the raw TunkRank score, you would have no frame of reference. My solution was to show you both. The downside is it groups all the “interesting” users into the top three percentiles. @NealRichter has put some thought into this, and I urge you to check out his post, leave some comments and help come up with a scoring mechanism that offers better granularity and yet lets you easily compare yourself to the rest of the world. Thus completes today’s desperate plea for crowdsourcing.

tunkrank-ravenA couple months ago, Daniel Tunkelang posted an algorithm on his blog that attempts to emulate PageRank for Twitter.  I implemented a toy version I dubbed TunkRank, and then suggested that name on his blog.  It got some traction, so I figured what the heck and decided to implement it on

Now, there appeared to be a little debate about just whether it is actually emulating PageRank or something else on Daniel’s blog, but I leave it to you to read the comments  on his post if you’re interested. There are also plenty of ideas there on the best way to establish a measure of influence.  I’ll limit the discussion in this post to the basics.

  1. The amount of attention you can give is spread out among all those you follow. The more you follow, the less attention you can give each one.
  2. Your influence depends on the amount of attention your followers can give you.

As a twitterer, your influence does not depend on how many people you follow. However, your usefulness as a follower does. Having higher influence depends on having many followers who follow relatively few people but are followed by many. Followers like that are more likely to pick up on your tweets, act on them, retweet them, whatever. You gain influence through the social graph thanks to their influence.

Therefore, your TunkRank score is a reflection of how much attention your followers can both directly give you and give to you.

I implemented this algorithm in Ruby using Merb, MySQL, Capistrano, nginx, and ActiveRecord (and, of course, Git for version control). While my job involves working on a web app, my role has mostly been on back-end NLP stuff. I’m still quite new to the whole Rails-level-web-app-world. For those who don’t know, Merb is a framework similar Ruby on Rails. So similar they are merging and will become Rails 3. ActiveRecord is an Object-relational Mapping (ORM) that Rails uses. The standard ORM for Merb is DataMapper, but I stuck with something I’m more familiar with to limit the variables in my little project.

There are many aspects of getting a web app up and running that I had only heard about in passing — and many more I’m still lost on. But I figured implementing TunkRank would be an interesting place to start.

Phase I – Data Collection

As I said, I implemented TunkRank as a toy the same night that Daniel posted his algorithm. Things seemed to work out quite nicely and I liked it on theoretical grounds as a measure. When I decided to implement the real version, the task of hammering Twitter millions of times suddenly loomed. I suppose I thought there were maybe about 1 million active accounts on Twitter. I have harvested over 2 million before slowing my harvesting down in favor of other development. I have also collected about 40 million edges in the social graph (user A follows user B is one edge). Of the 2 million users I have encountered, those 40 million edges are for only 25% of them. I still haven’t gotten the followers for the remaining 1.5 million. When I do so, I’m sure I’ll discover another million or three users I haven’t seen yet.

I stopped where I did because I was using Ruby’s marshal functionality to dump the social graph to disk. Each dump was weighing in around 250 MB and it was exceeding Marshal’s ability to function. At this point I threw everything into a MySQL database. Bleh! I can’t even describe the pain in the ass that was. If I were to do that again, I would certainly use PostgreSQL, and may still do so. Better yet, I would use some sort of column store database.  But it’s in the MySQL db now and running ok (just ok, not great or even well). MySQL dies quietly and annoyingly at times.  I hate it.

Doing the operations I was doing before in memory in ActiveRecord instead is mind-bogglingly slow by comparison, as you’d expect. Twitter just released the ability to pull all follower ids in one request, which would have made my life easier, but I still can benefit from it going forward. Also, I should have been storing more information about users than just the twitter username. Having to go back and collect that was slow and annoying, but it’s done.

Phase II – Implementing the Algorithm

The algorithm is simple to compute. Check out this gist for a version that calculates it using ActiveRecord. I’d post it here, but sucks and I’m stuck with it. The code uses ActiveRecord more than I’d like, so I rewrote it in SQL using twitter ids.  The gist for that is here.  The #{p} and #{self.twitter_id} are Ruby variables.

Phase III – Doing the Web App

The web app itself is both the most important step and the least fun for me. I very much enjoyed putting together the code to collect the Twitter social graph and then computing the TunkRank scores, but all the nuts and bolts of getting a web app up and running are tedious. Some of it is interesting. Merb isn’t so bad, though I feel like the documentation is shitty. There is an open source Merb book that is missing stuff in all the sections I needed the most. The API documentation isn’t bad, but isn’t easy to search for high level things that you would normally find in a tutorial. Nor should it be — it’s API documentation not a tutorial.

Fortunately, most things were easy enough that I could find a solution eventually. The whole deploying step is foreign to me, and I’m an apache noob so when it comes to balancing mongrel instances I’m like wtf?  Fortunately, I found a few tutorials I was able to piece together.

So the final product is hosted on my 1.8 GHz dual core Dell laptop with 2 GB RAM running Ubuntu 8.10. If you check it out, hopefully it won’t overtax my pathetic server and bring the site down. My data is becoming a little stale so if your username isn’t found, please be patient. When a new person is encountered, I queue them for processing.

Final Thoughts

You can also follow @tunkrank on Twitter. I originally had that account acting as a bot that tweets scores when it encounters influential users. Also,  I was having it auto-follow anyone it grades, but upon reflection, it occurred to me these two things were just plain spammy. I chalk it up to a bad decision in the dead of night. Instead I will just have it follow anyone who follows it.  See my twitter philosophy for how the account will be managed.  I will post updates there on changes, fixes, and up/downtime.

The TunkRank score itself can grow quite large, especially for users with a high number of followers. I present percentiles as the measure, so everything falls in the interval [0,100]. That does not properly reflect that someone in the 100th percentile can be almost 1000 times more influential than someone in the 99th. I’m open to suggestions about how better to show this information. Neal Richter had a few good ideas, perhaps I’ll try one of those.  Still, though, I’m left feeling a little dissatisfied by all of the scoring mechanisms (my own included). As Neal pointed out, his ideas are starting points and I’d like to hear what other people would like to see before proceeding with a different scoring method.

Let me know what you think.