Just over a year ago I worked on a project that had a need for what they called “a content personalisation engine”. What they meant by that was some sort of system that could do the following:

  1. Categorise content into a structured hierarchy
  2. Deliver the content to known users
  3. Track each user’s interaction with the content
  4. Analise the interaction and use that information to only send content that each user was interested in.

The clients system was being built to deliver daily content to mobile (cell) phones. Each piece of content was designed to allow users to interact with them in one of the following ways:

  1. Drill down into content
  2. Execute a call to action (phone call, text message, add a calendar appointment, etc)
  3. Skip the content (to see the next piece)
  4. Delete content
  5. Ignore content

The idea was that if we had a known group of users, who we could send content such as news / sports results / etc to, we could track their use of it, we would be able to know things like; “User X likes football but not cricket” and send them more football content.

The reason we wanted to do this is simple: users not only get the content they want without having to search for it, but the more they get the more relevant to them it becomes. Advertisers get extremely targeted audiences to interact with and will pay to reach them (this is how the client company was planning on making money).

In the end the client in question purchased a couple of third party applications and plumbed them together to handle all of this. But, the challenge of tracking a user’s interaction fascinated me and one day while thinking the problem through an idea struck me; the answer may lay in card games.

Black Jack, card counting and personalisation

In the card game Black Jack your objective is to reach the score of 21 using a minimum of two cards. If your cards add up to more than 21 you go “bust”. Whoever is closest to 21 without going bust wins. Being interested in card playing after visiting a Casino in Sydney a few years ago I have read up on several different techniques for improving your game, one of which is “Card Counting”.

The basic premise of card counting (a skill I’ve not even attempted to master I hasten to point out) is that you mentally keep a running total in your head of how many “high cards” have been dealt and how many “low cards” have been dealt. To do this you start with a running total of 0. If a card with a value higher than 7 is dealt you add 1 to your total. If a card with a value or 7 or lower is dealt you add a -1 to your total.

The idea is that if you have a running total that is really low the odds of the next card being of a high value are increased, and visa versa. You can use this knowledge to inform your game.

What has this got to do with content personalisation?

The idea hit me that we could set a score for each of the different interactions a user can have with any content, track those scores and use it to influence what content is sent to the user in the future. For example we could set the following scores for each of the interaction types:

  1. Drill down into content : +1
  2. Execute a call to action : +2
  3. Skip content : -1
  4. Delete content : -10
  5. Ignore content : 0

Then add these values to a running total held against each content type for each user.

For example the table below shows how one user may interact with content sent to them over a five day period, along with the content scores after each day:

Day 1 | Content delivered | User Interaction | Score | |—|—|—| | Music review | Drill down | +1 | | Sports results | Delete | -10 | | Weather | Call to action | +2 | | Content | Running total | |—|—|—| | Music reviews | +1 | | Sports results | -10 | | Weather | +2 | | Stock reports | 0 |
Day 2 | Content delivered | User Interaction | Score | | Weather | Drill down | +1 | | Music review | Ignore | 0 | | Stock reports | Drill down | +1 | | Content | Running total | |—|—|—| | Music reviews | +1 | | Sports results | -10 | | Weather | +3 | | Stock reports | +1 |
Day 3 | Content delivered | User Interaction | Score | | Weather | Call to action | +2 | | Stock reports | Call to action | +2 | | Music review | Drill down | +1 | | Content | Running total | |—|—|—| | Music reviews | +2 | | Sports results | -10 | | Weather | +5 | | Stock reports | +3 |
Day 4 | Content delivered | User Interaction | Score | | Weather | Ignore | 0 | | Stock reports | Ignore | 0 | | Music review | Call to action | +2 | | Content | Running total | |—|—|—| | Music reviews | +4 | | Sports results | -10 | | Weather | +5 | | Stock reports | +3 |
Day 5 | Content delivered | User Interaction | Score | | Weather | Drill down | +1 | | Music review | Ignore | 0 | | Stock reports | Call to action | +2 | | Content | Running total | |—|—|—| | Music reviews | +4 | | Sports results | -10 | | Weather | +6 | | Stock reports | +5 |

As you can see the most popular content ends up with a higher score than the least. If the system is told to send content in order of score the user will get more and more of the content they are interested in.

This example is fairly simple, and for a real system we would need to offer more content and possibly different weights to the scoring, but the principle would be the same.

The method could be further expanded by

  • Adding seeding data to the system - possibly asking users to “opt in” to some content when they first sign up
  • Adding a “decay” to each score. At the end of each day 1 could be subtracted from all positive scores and 1 could be added to all negative scores, meaning that all scores would eventually end up at 0 with no user interaction. This would allow for all content to be re-offered to users over time to see if their preferences had changed.
  • Subcategories could be added to the content so if the category “sports” got a positive score, then all sub categories such as football, rugby, golf would also be given a positive score and those more specific sports could be tracked. This would lead to information such as; “this user prefers football to rugby”.

I’ve not had a chance to pragmatically test this idea, and I’m sure there would be several pitfalls that I’ve not considered if I were to try, but having had the idea, and knowing that I’m not going to get a chance to explore this further in the foreseeable future I thought sharing the thinking here may be helpful to someone facing the same problem. Let me know if that person is you.