ライブドア製レコメンデーション・エンジン Cicindela の動作を確かめるために、簡単なAjaxアプリケーションを作ってみました。
前回の続きです。
JavaScript: Logger
Cicindela との連携部分を作る前に、簡単な Logger を作っておきます。ログの出力先には TEXTAREA 要素を想定しています。
var Logger = { clear: function() { $('#log').val(""); }, append: function(text) { var dom = $('#log').get(0); dom.value+= text + "\n"; dom.scrollTop = dom.scrollHeight; } };
Cicindela への入力
まずは入力部分から作っていきます。このアプリケーションにおいて必要な操作は「あるユーザがアイテムを選択した」、「あるアイテムをあるカテゴリに所属させる」の2つです。これらの操作を抽象化するために、Cicindela Web APIに対する Proxy となるオブジェクトを作ります。
var Cicindela = { base: '/cicindela/', set: 'sample', _insert_op_url: function(op, item) { return this.base +"record?set="+ this.set +"&item_id="+ item + "&op="+ op; }, _send_req: function(url, cb) { Logger.append("send Request to " + url); $.ajax({ type: "GET", url: url, success: cb, complete: function(xhr, status) { Logger.append("receive Response["+ xhr.status +"] from "+ url); } }); }, set_category: function(item, category) { this._send_req(this._insert_op_url("set_category", item) + "&category_id="+ category); }, insert: function(user, item) { this._send_req(this._insert_op_url("insert_pick", item) + "&user_id="+ user); } };
insert がアイテム選択、set_category がカテゴリ登録のためのメソッドです。実際にリクエスト送信を行うのは _send_req メソッドで、送信先URLと成功時に呼び出されるコールバック関数とを引数にとります。set プロパティには集計セットの名前を書いておいてください。
あとは「insert」ボタンが押されたときに、これらの API を呼び出します。
// $(document).ready において $('button#insert').click( function(e) { var user_id = $('#username').val(); if(user_id == "") { return false; } $.each(data, function(category_name, category_data) { var category_id = category_data.id; var container = $("#"+ category_name); var values = container.val(); $.each(values, function(i, v) { Cicindela.set_category(v, category_id); Cicindela.insert(user_id, v); $('#username').val(""); }); }); return false; });
このアプリケーションの場合、カテゴリ登録はデータの初期化時にまとめて行った方が効率的なのですが、「同じアイテムを、何度同じカテゴリに登録しても問題ない」ことを確かめるために、あえてアイテム選択時に毎回登録を実行しています。
これで Cicindela への入力準備が整いました。ユーザ名を入力して、適当にアイテムを選択して「insert」ボタンを押してみます。成功すれば次のようなログが出力されるはずです。
send Request to /cicindela/record?set=sample&item_id=Ruby&op=set_category&category_id=1 send Request to /cicindela/record?set=sample&item_id=Ruby&op=insert_pick&user_id=cicindela receive Response[204] from /cicindela/record?set=sample&item_id=Ruby&op=insert_pick&user_id=cicindela receive Response[204] from /cicindela/record?set=sample&item_id=Ruby&op=set_category&category_id=1
またMySQLサーバにログインして、categories テーブルや picks テーブルにデータが入っていることを確認します。
Cicindela からの出力
続いて Cicindela からレコメンデーション・データを取り出してみます。必要なのは「特定アイテムに対するレコメンデーション(関連アイテム)取得 (=item to item)」なので、次のような get_for_item メソッドを Cicindela オブジェクトに追加します。
var Cicindela = { /* ...略... */ get_for_item: function(item, category, cb) { var url = this.base +'recommend?set='+ this.set +'&op=for_item&item_id='+ item +"&category_id="+ category; this._send_req(url, cb); } };
そして「get」ボタンが押されたときにこのメソッドを呼び出します。第3引数として渡すコールバック関数は、正常にレスポンスが受信できたときに受信データを引数として呼び出されます。Cicindela からのレスポンスは改行区切りの文字列データです。ここでは単に出力用の要素に html メソッドで書き込んでおきます。
// $(document).ready において $('#get').click( function(){ var item_id = $('#items').val(); $.each(data, function(category_name, category_data) { Cicindela.get_for_item(item_id, category_data.id, function(data) { $("#output-"+ category_name).html(data) }); }); });
以上で一通りの機能が完成しました。ユーザ名と選択アイテムを変えて何度か入力を行い、レコメンデーションを取得してみましょう。その際には自分なりに”シナリオ”を決めて、そのシナリオに沿った結果になるか試してみると面白いです。例えば:「Perl好きはEmacsやVimを使う」、「WindowsユーザにもMacユーザにもLinuxユーザにもJava好きはいる」、「EmacsとVimを両方ともよく使うユーザは少ない」などなど。
完全なソースを gist に置いておきます。