特徴ベクトル変換器を作った話 #dogenzakalt

27
特徴ベクトル変換器を作った話 2014/03/12 道玄坂LT祭り第2回 (統計、機械学習、データ抽出) @tokoroten

Upload: shinta-nakayama

Post on 15-Jul-2015

6.594 views

Category:

Technology


3 download

TRANSCRIPT

Page 1: 特徴ベクトル変換器を作った話 #dogenzakalt

特徴ベクトル変換器を作った話

2014/03/12

道玄坂LT祭り第2回(統計、機械学習、データ抽出)

@tokoroten

Page 2: 特徴ベクトル変換器を作った話 #dogenzakalt

自己紹介

• ところてん– https://twitter.com/tokoroten

• ZenClerkの雑用

– アドテクの機械学習の論文読んで、EC向けに再実装とかしている

• ZenClerk

– http://www.zenclerk.com/

– ECサイトを見ている人の行動をリアルタイム分析

– 最適なタイミングでインセンティブを提示することでCVRを大きく引き上げるサービス

Page 3: 特徴ベクトル変換器を作った話 #dogenzakalt

目次

• データ分析の処理の流れ

• 二つの世界、本番環境の課題

• ベクトルコンバーターの話

Page 4: 特徴ベクトル変換器を作った話 #dogenzakalt

目次

• データ分析の処理の流れ

• 二つの世界、本番環境の課題

• ベクトルコンバーターの話

Page 5: 特徴ベクトル変換器を作った話 #dogenzakalt

データ分析の流れ

生データ特徴ベクトル

機械学習 パラメータ

分類器推定器

学習結果学習精度

教師データ

テストデータ

前処理

Page 6: 特徴ベクトル変換器を作った話 #dogenzakalt

マエショリスト

生データ特徴ベクトル

機械学習 パラメータ

分類器推定器

学習結果学習精度

教師データ

テストデータ

前処理

データ分析の仕事の多くは前処理前処理の出来が全体の出来を決める

後段の機械学習は、ライブラリに投げられる

Jubatusのfv_converterはすごくよく出来てた……

Page 7: 特徴ベクトル変換器を作った話 #dogenzakalt

前処理のニーズ

• データフォーマットの変換

– 生データを学習器が読み込めるVector型に変換する• JSONから値を引きずり出す

• 画像をベクトル化、グラフを処理してベクトル化

– 異なるデータソースを手動join

• 特徴量チューニングによる精度改善

– 利用する変数の取捨選択、欠損値の対応、異常値の除外

– 変数のクリッピング(最大値、最小値)

– 変数のログスケール変換(負の値の対応)

– 変数を演算して、線形分離しやすい新しい変数を作る

• 正規化、足し算、引き算、割り算、分散

– bool値を0,1に変換

– ラベル変数を0,1に変換

Page 8: 特徴ベクトル変換器を作った話 #dogenzakalt

特徴量チューニングの例

ランダムフォレストのつかいかた – じじいのプログラミングhttp://shindannin.hatenadiary.com/entry/2014/12/24/235530

Page 9: 特徴ベクトル変換器を作った話 #dogenzakalt

前処理を分離

生データ特徴ベクトル

機械学習 パラメータ

分類器推定器

学習結果学習精度

教師データ

テストデータ

前処理

設定ファイル

前処理を設定ファイルに切り出すことで、試行錯誤や、対象ごとのチューニングが行いやすくなる

Page 10: 特徴ベクトル変換器を作った話 #dogenzakalt
Page 11: 特徴ベクトル変換器を作った話 #dogenzakalt

目次

• データ分析の処理の流れ

• 二つの世界、本番環境の課題

• ベクトルコンバーターの話

Page 12: 特徴ベクトル変換器を作った話 #dogenzakalt

二つの世界

本番環境 データ分析環境

言語

Ruby、node などサービスを作りやすい言語

Python、R などデータ分析が行いやすい言語

データ構造JSON、RDB Vector

タイムスケール50ms or dieリアルタイム

夜中にバッチ回して朝確認

機械学習ライブラリ

総合的なものは少ない

総合的なライブラリが存在

Page 13: 特徴ベクトル変換器を作った話 #dogenzakalt

データ分析の本番適用(オフライン)

生データ特徴ベクトル

機械学習 パラメータ

分類器推定器

分類結果

データ分析の世界(Pythonとか、Rとか)

テストデータ

生データ

コピー

本番環境の世界(RubyとかNodeとか)

教師データ

分類結果

コピー

本番システム参照ログ

オフライン系では、バッチで生成された分類結果のみを利用するため、データ分析環境と、本番環境の差は問題になりにくい

前処理

Page 14: 特徴ベクトル変換器を作った話 #dogenzakalt

本番システム

データ分析の世界(Pythonとか、Rとか)

本番環境の世界(RubyとかNodeとか)

データ分析の本番適用(オンライン)

生データ特徴ベクトル

機械学習 パラメータ

分類器推定器

学習精度テストデータ

生データ

コピー

特徴ベクトル

分類器推定器

本番データ結果

教師データ

コピー

オンライン系では、生データに対してリアルタイムに分類を行うデータ分析と、本番環境で同じ前処理が必要になる

前処理

前処理

Page 15: 特徴ベクトル変換器を作った話 #dogenzakalt

目次

• データ分析の処理の流れ

• 二つの世界、本番環境の課題

• ベクトルコンバーターの話

Page 16: 特徴ベクトル変換器を作った話 #dogenzakalt

本番システム

ベクトルコンバータによる解決

生データ特徴ベクトル

機械学習 パラメータ

分類器推定器

学習精度テストデータ

生データ

コピー

特徴ベクトル

分類器推定器

本番データ結果

教師データ

コピーベクトルコンバーター

前処理

前処理

動作が同じであることを保証した前処理を生成して解決

設定ファイル

Page 17: 特徴ベクトル変換器を作った話 #dogenzakalt

ベクトルコンバーターの概要• 設定ファイルを読み込んで、JSONの生データを特徴ベクトルに変換する簡易Forthインタプリタ– Forthは言語仕様がコンパクトなので、他言語への移植や、機能追加が容易

• JSやPythonのコードに、Source to Sourceコンパイル可能

• 特徴量チューニングで利用される主要な操作をカバー

生データ

特徴ベクトル

ベクトルコンバータ

設定ファイル

JSの前処理コード

特徴ベクトル

JSのコードを出力

生データ

Page 18: 特徴ベクトル変換器を作った話 #dogenzakalt

Forth

http://ja.wikipedia.org/wiki/Forth

Page 19: 特徴ベクトル変換器を作った話 #dogenzakalt

コード例:単純参照

{a: 10.0,b: 200.0,c: 50.0,e: {

hoge: 1000}

}

abcde.hoge

10.0200.0 50.0 0.01000

入力されるjson 設定ファイル 出力特徴ベクトル

JSONに対して、透過的にアクセス可能入れ子になっている変数もアクセス可能

欠損値は自動的に0.0になる変数の取捨選択はこれだけでOK

Page 20: 特徴ベクトル変換器を作った話 #dogenzakalt

コード例:演算

a b adda b suba b diva c add log1pa b div log1pa 100 200 chop

210.0-190.00.054.11080.0487100.0

入力されるjson 設定ファイル 出力特徴ベクトル

a + ba – ba / blog((a + c) + 1)log((a / b) + 1)max(100, min(200, a))

中置記法による疑似コード

※chopの実態は sorted([a,100,200])[1]

{a: 10.0,b: 200.0,c: 50.0,e: {

hoge: 1000}

}

演算は逆ポーランド記法(簡易Forth)で行われる

Page 21: 特徴ベクトル変換器を作った話 #dogenzakalt

コード例:簡易Forthによる処理例入力されるjson

{a: 10.0,b: 200.0,c: 50.0,e: {

hoge: 1000}

}

a c add log1p

10.0 10.0

50.0

a c

60.0

add

4.110

log1p

4.110

• forthはスペースセパレータで、ワード単位で実行• ワードが予約語であれば、予約語を実行• ワードが予約語でなければ、入力されたjsonを参照• 入力されたjsonに値が存在すれば、スタックに積む• 入力されたjsonに値が存在しなければ、0.0を積む

※log1p(x)は、log(x+1)と等価

をステップ実行してみる

スタックの一番上が取り出される

Page 22: 特徴ベクトル変換器を作った話 #dogenzakalt

等価なJavaScriptの出力

a c add log1p

function(target_obj) {var t1, t2, t3;var stack = new Array();stack.push(target_obj.a === undefined ? 0.0 : target_obj.a);stack.push(target_obj.c === undefined ? 0.0 : target_obj.c);stack.push(stack.pop() + stack.pop())t1 = stack.pop();stack.push(t1 > -1.0 ? Math.log(t1 + 1.0) : -744.4400719213812);return stack.pop();

}

forthの処理がすべて1つの関数に展開される元となるオブジェクトに関数を適用すると、特徴変数が得られる

JITで最適化されるといいなぁ・・・

Page 23: 特徴ベクトル変換器を作った話 #dogenzakalt

等価なJavaScriptの実行結果

Page 24: 特徴ベクトル変換器を作った話 #dogenzakalt

まとめ

• データ分析の課題– 前処理の試行錯誤のために、前処理を外部に切り出す必要がある

• 本番環境の課題– 本番環境は、データ分析環境と別言語であることが多い

– 別言語の環境で、同質の前処理の再実装が必要

• ベクトルコンバータの提案– 前処理を記述するForth風の言語

• Python上で動くForthインタプリタとして実装• 同質なJSを出力する機能を持つ

– 同質の前処理をデータ分析環境と、本番環境に提供

Page 25: 特徴ベクトル変換器を作った話 #dogenzakalt

https://github.com/tokoroten/forth_fv_converter

githubで公開中

Page 26: 特徴ベクトル変換器を作った話 #dogenzakalt
Page 27: 特徴ベクトル変換器を作った話 #dogenzakalt

データ分析の世界(Pythonとか、Rとか)

本番環境の世界(RubyとかNodeとか)

(付録)本番適用の本当の課題

生データ特徴ベクトル

機械学習 パラメータ

分類器推定器

学習精度テストデータ

生データ

コピー

特徴ベクトル

分類器推定器

本番データ結果

教師データ

コピー

同じパラメータが利用できる分類器ってみんなどうしてるの?

前処理

前処理