JavaScriptだけでレコメンドシステムを作ってみた


 Follow NowというTwitterのリアルタイムフォロワー推薦ツールを公開しました。
 このツール、サーバーサイド処理はこちらでは一切作っていません。HTML+JavaScript+CSSにWebAPIを組み合わせただけなのです。

Follow Nowの仕組み

 WebAPIとJavaScriptだけでどうやってレコメンドシステムを作っているか、というと、鍵となるのはJSONPでの出力に対応したWebAPIです。
 JSONを使ってクロスドメイン通信をするJSONPでの出力に対応したWebAPIは今質量共にものすごい数に上っていて、中にはTwitterや、Yahooのキーフレーズ解析なども含まれています。これらを使うことで、かなりのことがWebAPIとJavaScriptだけでできます。

 流れとしては次のようになります。

1.アカウント名をもとに、Twitterからユーザーの投稿を取得
2.その投稿一つの文章としてみなしてYahooでキーフレーズ解析
3.重要度と呟いた回数から、その単語を重み付け
4.上位3つをTiwitter検索
5.単語の重みとユーザーの出現回数からユーザーの重み付け
6.上から順に未フォローの人を5人までオススメする

 赤字はWebAPIを利用した分析です

 ただし、2は実際にはGETリクエストにおけるYahoo側の制限があるので、投稿5つを単位として小分けして解析しています。

 また、この方法上、どうしてもAPI数を食うのが難点です。特に面倒なのが未フォロー判定で、一ユーザーにつき一回ずつアクセスしないといけないので、どうしてもAPIと時間を消費します。キーフレーズ解析のあたりはシーケンシャルにやっていましたが、さすがに後のほうは時間がかかりすぎるので非同期通信しています。
 方法としては

1.リクエストする回数を取得
2.処理が終了するたびにカウンタを減らして、結果をプール
3.タイマーで監視して、カウンタが0になったらプールした結果を元に次の処理

 コードとしてはこんな風になります。

var async_search={};
async_search.max=async_search.count=0;
async_search.result=[];
//送信処理
async_search.send=function(endpoint,callback,params){
	this.max++;

	var my=this;
	//コールバック関数を終了処理で包む
	var my_callback=function(data){
			my.count=my.count+1;
			var stack=callback(data);
			my.result.push(stack);
			
	};
	//ここで送信処理。コールバック関数はmy_callbackを使用;

};
//待機処理
async_search.prototype.start_wait=function(next){
		var my=this;
		var monitar=function(){
			
			if(my.count==my.max){
				clearInterval(timer_id);
				next(my.result);
			
			}
		
		};
		var timer_id=setInterval(monitar,100);

};

Google App Engine Pythonを使い慣れた方ならば、URL Fetch APIの非同期通信とほぼ同じ感覚であることに気がつくと思います。
 

この方法のメリット

 やはりサーバーサイド側の処理がシンプルですみ、負荷が軽いことがあげられます。
 実質的にユーザーのCPUパワーを使用しての分散処理ですので、サーバーサイドですと非常にコストのかかるリアルタイム処理を実質ノーコストで行えています。
 もちろん、サーバーにデータを貯めていない関係上精度は最近のつぶやきの度合いに大きく依存するという難点はあるのですが、その代わりに現在の関心に基づいて現在のオススメを判定する、というサーバーサイド処理でやったらとんでもないコストがかかる処理が簡単に実装できています。

 これは比較的単純なケースなのですが、自前でバックエンドを持つことでもっと色々な処理が可能になります。かなり応用は広いのではないかなと。