凹みTips

C++、JavaScript、Unity、ガジェット等の Tips について雑多に書いています。

オンライン学習ライブラリ oll の node.js アドオンを作って JavaScript で機械学習させてみた

はじめに

OLL によるオンライン学習を試してみた - 凹みTips にて oll (Online-Learning Library) を触ってみた記事を書きましたが、これを元に oll を node.js のアドオン化をしてみました。

ダウンロード

hecomi/node-oll · GitHub

使ってみる

github の README にも書きましたが以下のように使えます。
2012/06/20 0:25 - add の引数を修正

var oll = require('./build/Release/oll');
var PA1  = new oll.PA1();

// 学習とテスト
PA1.add(true,  '0:1.0  1:2.0 2:-1.0');
PA1.add(false, '0:-0.5 1:1.0 2:-0.5');
console.log(PA1.test('0:1.0 1:1.0')); // 0.1714285910129547

// 学習結果をファイルへ保存
PA1.save('test.dat');

// 学習結果をファイルから復元
var PA1_2 = new oll.PA1();
PA1_2.load('test.dat');
console.log(PA1_2.test('0:1.0 1:1.0')); // 0.1714285910129547

こんな感じで学習とテスト、学習結果をファイルへ保存、またその復元が可能です。
学習のさせ方は以下の形式でも可能です。

PA1.add('+1 0:1.0  1:2.0 2:-1.0');
PA1.add('-1 0:-0.5 1:1.0 2:-0.5');

学習手法は以下のものが使えます。

P   : Perceptron
AP  : Averaged Perceptron
PA  : Passive Agressive
PA1 : Passive Agressive I
PA2 : Passive Agressive II
PAK : Kernelized Passive Agressive
CW  : Confidence Weighted

ソースコードの PA1 のところを書き換えれば OK です。
またコンストラクタで初期値の設定も可能です。

var Perceptron  = new oll.P({C: 2.0, bias: 1.0});

C は oll_train の -C パラメータに相当しデフォルトで 1.0、bias は -b パラメータに相当しデフォルトで 0.0 です。

もうちょっとしっかり機械学習させてみる

oll のページに書いてある内容をテストしてみます。
参考:Perceptron を勉強する前にオンライン機械学習ライブラリを試してみる (nakatani @ cybozu labs)
ここに書いてあることと同じようなことをしてみます。
あ、あと getline 的な挙動は以下のページを参考にしました。
node.jsで1行ずつテキストを読み込む方法 - ホワイトぼーど

コード
// ライブラリの読み込み
var fs = require('fs');
var oll = require('./build/Release/oll');
var Perceptron  = new oll.P({C: 2.0, bias: 1.0});

// 学習
var trainData = fs.readFileSync('data/news20.train').toString().split('\n');
for (var i in trainData) {
	Perceptron.add(trainData[i]);
}

// テスト
var testData = fs.readFileSync('data/news20.test').toString().split('\n');
var success = 0, failure = 0;
for (var i in testData) {
	var b = testData[i].charAt(0);
	var result = Perceptron.test(testData[i].substr(3));
	if ( (b == '+' && result > 0) || (b == '-' && result < 0) )
		++success;
	else
		++failure;
}

// 結果
console.log("success\t: " + success);
console.log("failure\t: " + failure);
console.log( (success) / (success + failure) * 100 + "%");
結果
success : 4879
failure : 118
97.63858314988994%

本家と似たような数値が出ました。CW とかでやったら 99% 超えてました。逆に出すぎてあってるのか不安になってくる。。

おわりに

node.js のアドオン化すると v8 単体でやるよりも node.js のいろんな資産が使えて良いですね。Twitter から何か引っ張ってきて学習させるとかも簡単にできそうです。前のエントリで書いた node-mecab とかと組み合わせたりしながら何か面白いこと出来ないかなぁ。。