LLまつりに行ってきました
今年もLLイベント「LLまつり」に行ってきました。
今年はLTもしてきました。CROSSの宣伝をしにいくつもりで「CROSSの話かそれがダメならJavaScriptで時系列解析の話で」と申し込むと、後者になっていました。
という訳で僕自身は「JavaScriptで時系列解析」というか前処理の話をしてきました。
内容としてはこんな感じのライブラリです
- データ可視化の時に可視化表現ごとにデータ取り出すと結構コストなので、一回取り出したデータをゴネゴネしていろんな切り口やタイムスパンで見たいときに便利なモジュール
- D3はSVG処理とデータ処理・時間処理を分けたほうがいいと思うので、後者を作りたかった
- plyrとかdata cubeっぽくなんか作ってみたかった(結果としてはd3のアクセサに少し似た形で作った
今後やることはリファクタとドキュメントです。 あとはもう少し分析系(arとかfftでのスペクトラムとか)とか予測周りとか自分に必要な機能をこつこつ作ることとをしたいと思っています。
覚書(というか印象に残ったこと)
- Common LispはC/C++とLLの間
- 「神の言語」とか考えなければ結構便利に使える
- 「それCommon Lispでできるよ」
- Delphiの歴史は一大叙事詩
- D言語のキャラはキモい
- @repeatedly さんの「結構流行ってる」は「D言語界隈では」と解釈する
- Golangにインタープリター「そんなものはありません」
- 100枚の資料も10分で終わる
- 郵便配達→エンジニアとか公務員→エンジニアとかペパボすごい
- 徹夜でハッカソンしたら朝一からLTがおおうけする
- 外人は忍者大好き
- ドラ娘は現地調達できる
上記が本編なのですが、個人的に今回一番心に残ったのは休憩時間話してたすたじおさんの
もりすさんとかかぜぶろさんが障害対応でいろいろやったあとの サーバに入ってhistoryコマンドで勉強してる
という昔の料理人のような姿勢でした。
僕ももっともっと頑張らねば・・・とおもった次第です。
LLイベントの運営のみな様お疲れ様でした! 懇親会でお話させていただいた皆様ありがとうございました!
advent calendar 24日目 selectAll(), data(), enter(), append()に翻弄されるひとたちに
ようやくボクのクリスマスが終わります。
d3は可愛いんですが「selectAll() -> data() -> enter() -> append()」は経験から学ぶのが最も早い、としか答えられません。 クリスマスプレゼントとして、そんな方々のためにUnderstanding selectAll, data, enter, append sequence in D3.jsというエントリが2012/1に出ております。
理解の一助となればと訳しておきました!これほんとに理解できる記事です!
D3.js始めたばっかりの諸君らが、Webで例を見ながら学習するときに、ぶっちゃけ「selectAll(), data(), enter(), append()」という一連の処理はイミフだと思う。そう、これらの関数は、なにをしてるのかわかりづらい。少なくともこれらの機能を理解するのは簡単じゃないと思う。よくわからない諸君らの一助となればと思い例と説明を上げてみることにする。
これらのメソッドが何をしているかを理解するための鍵は、 http://mbostock.github.com/d3/ の[Keys section(今はリンク先には無い)]を見てくれ。
key functionはまた、enterとexitのselectionsを決定する。 古いデータの中に対応するkeyが見当たらない新しいデータはenter selectionとなる。 新しいデータの中に対応するkeyが見当たらなかった古いデータはexit selectionとなる。 どちらにも存在するデータは更新されるselectionとなるのだ。
Mike Bostock氏はこのスレッドの中で言及している。
焦らなくていい。あとで挙げる例と説明を見てもらえれば、多分理解できると思う。 以下の3つの例すべてで HTML paragraph element (
)を生成している。 しかし、D3.jsを使って作っているならば、諸君らが生成するいかなる他のelementで会っても同じ原則が適用される。
次の2つの例とその結果を注意深く見て欲しい。そして、例と結果の違いに着目してくれ。
例1
<!DOCTYPE html> <html> <head> <script type="text/javascript" src="http://mbostock.github.com/d3/d3.js"> </script> <style type="text/css"> p { font-size: 20px; color: orangered; } </style> </head> <body> <div id="example1"></div> <script type="text/javascript"> pdata = [10,12,6,8,15]; selectDIV = d3.select("#example1"); selectDIV.selectAll("p") .data(pdata) .enter() .append("p") .text(function(d){return d;}); </script> </body> </html>
結果1
10 12 6 8 15
例2
<!DOCTYPE html> <html> <head> <script type="text/javascript" src="http://mbostock.github.com/d3/d3.js" ></script> <style type="text/css"> p { font-size: 20px; color: orangered; } </style> </head> <body> <div id="example2"> <p>Already existing paragraph 1</p> <p>Already existing paragraph 2</p> </div> <script type="text/javascript"> pdata = [10,12,6,8,15]; selectDIV = d3.select("#example2"); selectDIV.selectAll("p") .data(pdata) .enter() .append("p") .text(function(d){return d;}); </script> </body> </html>
結果2
Already existing paragraph 1 Already existing paragraph 2 6 8 15
2例のコードの違いは、d3のJavaScriptが呼び出される前に、例2では2つのparagraph element ("Already existing paragraph 1"、"Already existing paragraph 2") の存在だけだ。 そして、与えられたデータの配列では存在しているにもかかわらず、結果2では、10と12は見つけられない。なぜか?これこそが諸君が求めているものだとおもう。
1.
selectDiv.selectAll("p")
はselectDiv
の中にある全ての<p>...</p>
を返す。
例1では空だし、例2ではすでにある2つのparagraph Elementが返される。
2.
.data(pdata)
は2引数を引き受ける
1. data 配列
2. data 配列の要素に関連付けられている key の関数。key
- これこそが enter selection を決定する。.enter().append()
メソッドで指定したノードにデータ配列の中のどの要素をひもづけるかを決める、と考えればよい。
たぶん「は?key functionとかねーし。あと、keyとかいってるけど、それがどうやってenter selectionを決定してるかわかんねーし」と思うと思う。うん、当たり前だと思う。これについて説明しよう。
D3.jsの創造主がこのポストで説明しているが、key functionが.data()
メソッドで明示的に指定されてない場合には、デフォルトの値として、indexが使われるんだ。この場合は、data配列のindexだ。
例えば、例1では key function が指定されていないから、10, 12, 6, 8そして15の key は 0, 1, 2, 3 そして 4となるってことだ。
この key は次のような方法でenter selectionを決定する。data配列(今の場合はpdata
だ)の中の要素のkeyは既存のselection(.selectAll("p")
メソッドで返されるselectionだ)のkeyと比較される。指定したdata配列の中で既存の要素のkeyと異なるkeyを持つすべての要素が、enter selectionとなるのだ。もし、既存の要素のkeyとすべてかぶった場合にはenter selectionは無い。
どちらの例でもkey functionは明示的に指定されていない。つまり、keyはそれぞれの配列のindexとなる。 例1では、.selectAll("p")
はからの配列を返すので、対応するkeyも空だ。ところが指定したpdata
、10, 12, 6, 8, 15に対応するkeyは0, 1, 2, 3, 4だ。すべてのkeyが異なっているので、pdata
のすべての要素がenter selectionになるんだ!
他方で、例2では .selectAll("p")
は2つの配列を返し、これらのkeyは0, 1となる。pdata
のkeyは例1同様0,1,2,3,4となっている。
10と12は既存のp要素と同じkeyを持っているので、10と12はenter selectionには含まれない!!
3.
.enter().append("p")
メソッドはenter selectionの中の要素の数だけ<p>...</p>
を生成する。.append()
で指定した要素が生成されのだ。
例2で 10と12はenter selectionには入らなかったので、これらに対応するp要素は生成されず、結果として見ることができなかったのだ。
例2と似た例3を作ってみた。違いは、key functionを明示的に指定したことだ。これだけのことで、pdata
の要素すべてが結果として現れる。
例3
<!DOCTYPE html> <html> <head> <script type="text/javascript" src="http://mbostock.github.com/d3/d3.js" ></script> <style type="text/css"> p { font-size: 20px; color: orangered; } </style> </head> <body> <div id="example3"> <p>Already existing paragraph 1</p> <p>Already existing paragraph 2</p> </div> <script type="text/javascript"> pdata = [10,12,6,8,15]; selectDIV = d3.select("#example3"); selectDIV.selectAll("p") .data(pdata, function(d){return d;}) .enter() .append("p") .text(function(d){return d;}); </script> </body> </html>
結果3
Already existing paragraph 1 Already existing paragraph 2 10 12 6 8 15
.data()
メソッドの2つ目の引数に注目してくれ。key functionとして値自身を返すようにした。
結果として、要素の値自信がkeyとなる。つまり、要素10のkeyは10だし、12のkeyは12、6のkeyは6だ。
既存のselectionの要素のkeyは無い。結果として、例2とちがって例3では、新しいdata要素は既存の要素とは異なるkeyを持つこととなり、enter selectionになり、.enter().append("p")
で生成されるんだ。
ICML2013 読み会に参加して来ました
ICML2013の論文をみんなでよってたかって紹介しよう、という会に行って来ました。 読み手は埋まらないだろうと思って「埋まらなかったら読みますよー」って言ってたら速攻で8人埋まってびっくりした。
あと、こういう会に40名近く(女子含む)が来るってことは機械学習の裾野が広がってるんだろうなって思った。 自分が研究してた頃は同じ研究室の女子は多分聞いてなかった気がする(心理学系の人)。
PFIの皆様、中川先生、ありがとうございました。
ざざっとまとめたりメモしたものなので間違っていたらご指摘ください。 (あと機械学習の専門ではないので、不安な略語もメモった)
個人的にはHinton+ 2012のdropoutは2005年ごろからニューラルネットワークの研究者は、試行錯誤の末、僕の周りではみんなやってた気がするけどこれが論文になってたことにびっくりした。 ニューラルネットにありがちな過学習を抑制する正則化の意図で実装してた。
18:00-18:20 @sla : "Learning Spatio-Temporal Structure from RGB-D Videos for Human Activity Detection and Anticipation"
ICML紹介
- 招待講演
論文まとめ
- イメージより多いもの (@sla 調べ)
- sparce / deep / random / multi / bandit / active learning / compressed
個人的な感想(@sla)
もうiidはいいのではないか * 時系列要素を入れてる論文が圧倒的に少ない * 実応用は時系列的な要素を含む場合がほとんどではないか
違う方向性
- 3つのワークショップ: Robot Learning / Machine Learning with test-time Budgets / Learning with Sequential Models
- 違うアプローチ: Imitation Learning / Interactive Learning / Reinforcement Learning / Imperative Learning (Data Search / Aggregation)
違うコスト設定: 予測コストがかかる、ラベルを得るコスト、サンプルを得るコスト、Featureを得るコスト
DataSet Aggregator: Data Streaming Ross
論文紹介
- Conditional Random Fields
- Cutting plane training of structural SVMs [Joachims, MLJ2009]
18:20-18:40 @beam2d: "Local Deep Kernel Learning for Efficient Non-linear SVM Prediction"
目的
LDKL
- アンカポイント自体も学習しましょう
- 空間分割も一緒に学習
- 各点でどの分類器を使うかは二分木を探索して得る
- 主空間で最適化 (LLSVM)
- 最適化はSGD
木構造の特徴写像
- sign(θx)分割 入力に対して分割パラメタの内積の正負で分割
18:40-19:00 @conditional: "Vanishing Component Analysis"
19:00-19:20 @jkomiyama_ : "Active Learning for Multi-Objective Optimization"
- 東大 中川研究室
目的
- 学習に時間がかかるので、少ないデータの評価で済ませたい
Gaussian process
- 回帰問題のGPモデル
- 入力と目的関数の関係を予想する確率モデル
- mean function と covariance function
Active learning
- アルゴリズムが欲しい点を能動的に選択
- 各点の評価コストが重い。情報量の高い点から、各ラウンド1点ずつ順番に評価して行く
- 少ない評価点の数で高い精度を出す
Multi-objective optimization
- parateoptimal set
処理
- 不確定性が高い点から学習
理論解析
- information gain
- maximum possible information gain
まとめ
- 既存手法(heuristic)と比較して、強い理論的な保証・高いパフォーマンス
- 精度がハイパーパラメータに結構依存する
[Srinivas+ ICML2010]
19:20-19:40 @kisa12012 : "Large-Scale Learning with Less RAM via Randomization"
- 東大 中川研
- 論文
目的
- 重みベクトルの省メモリ化
- SGDベースのアルゴリズムのサイズを自動調節し省メモリ化しよう!
- 学習時:50%、予測時:95% で同じくらいの精度がでます
- Regretによる理論保証もあり
- L1Cacheでデータ処理可能か?
概要
- 学習時はステップ幅に応じて表現方法を変える(bit数を変化させる 32bitじゃなくてもいい)
アルゴリズム
- bit長の記法の定義
- Qm,n
- n: 仮数部
- m: 指数部
- 1ビットは符号
- (n+m+1)bitsで表現
- ε: 表現可能な点の間のgap (最小表現範囲)
- 確率的に近似値を決定するRandom Round
- SGDを学習させる場合に、ステップ幅を変化 / Per-coordinate learning rates aka AdaGrad [Duchi+ COLT10]
実験
- CTR (非公開の検索広告クリックログデータ)の予測
- Data: 30M / Feature: 20M
- スパースな素性
- Billionでもほとんど同じ結果
まとめ
- FOBOS等への拡張もStraightforward
- 速度は書かれていない
- セカンドの人の特徴量生成の論文
19:40-20:00 @Quasi_quant2010 : "Topic Discovery through Data Dependent and Random Projections"
- perplexy
- topic coherency
- gibbs sampling
- PLSI
- NMF
- LDA
20:00-20:20 @tabe2314 : "Fast Image Tagging"
Image Tagging
- 画像からタグ
難しいところ
- 効果的な特徴が物体によって違う color / edges
- 不完全なアノテーション (Precisionはともかく、Recallが低いデータしか得られない)
- タグの出現頻度の偏り
アルゴリズム
- アノテーションyから真のタグセット zを求めるB (z = By)を求める
- 画像xから真のタグセットzを求めるW(z = Wx)を求める
zはわからないので、確率pでyから落として y = By^としてBを求める
なんか、雑な方法だな…
stackingはbootstrapであることも考えれば、lake -> lake との共起 -> それらからpondが導出
画像特徴
- 特徴
- GIST
- 6種類の色のヒストグラム
- 8種類の極小特徴のBoW
20:20-20:40 @unnonouno : "ELLA: An Efficient Lifelong Learning Algorithm"
概要
- GO-MTL (multi-task learning)
- 目の前のTaskの学習
- 過去のTask全体の学習
- 新たなTaskを過去の組み合わせにマッピングする?要素分解する?学習
20:40-21:00 @sleepy_yoshi : "Distributed Training of Large-scale Logistic Models"
- NTT 数原
- 資料
概要
- タスク:クラス数が大規模な他クラスロジスティック回帰の分散学習
- 拡張ラグランジュ法の適用を検討
- A) Piece-wise Bounds
- B) Log-concavity bound -> Good
- C) Double majorization bound
- D) 拡張ラグランジュ法 (ADMM)
多クラスロジスティック回帰
- LBFGS
- 大規模なデータセットにおいては限界がある
- パラメタ分散の並列計算が不可能
- 直線探索と損失関数評価の繰り返しが必要であるため、パラメタをすべて保持しておく必要
- パラメタだけで最大17GB
- L-BFGSでは過去の勾配情報を保持しておく必要が有る
飛び入り:Maxout Networks 徳永さん
- maxoutおもしろかった。(いつかわからないけど)ニューラルネットが必要になった時に試してみたい
社内環境などでgitプロトコルが使えないときに内部的にgitを使ってるプロダクトでうまくやる
d3.js advent calendar 23日目
ボクのクリスマスはまだ終わっていません!
データベースエンジニア養成読本に
たぶん、最後に「まあ、データってことばに関係するからちょっと混ぜておくか」というノリだと思いますが
データ可視化についての内容で寄稿しました。
データ可視化の歴史とかJavaScriptのライブラリの紹介とか、メトリクスツールとかについて触れたあと、slow-queryを可視化する方法について書きました。 具体的なコードも乗っていますので、このままやってもらえれば、mysql-slow-queryの全体情報が左側に、クエリごとの情報が右側に、時系列で表示されます。
どう見てもデータベースCROSSのような気もしますが他の執筆者の方々の記事を読んでボクも勉強したいと思います。
35歳定年説
先週の23日で晴れてエンジニア定年説となる35歳を迎えることになりました。
ハッピーバースデー俺!
ちらっとここ数年を振り返ってみるとこんな感じ
- CROSSを始めた 2012, 2013
- mongo-hadoopのパッチを送った/発表した mongodb tokyo, hadoop code reading
- fluentdのプラグインを書いた datacalculator, filter, anomalydetect
- d3アドベントカレンダー(継続中) adventar
- d3.jsのトップの翻訳
- データ可視化 Hands On
- データベースエンジニア養成読本
すごいエンジニアの方々とたくさん知り合いになれて、刺激を受けて、自分自身でもいつまでもコードを書き続けることを止めないでいられたし、コードを書き続けたいと思える環境に身を置けていることをすごく楽しめていて、大変うれしいです。
年下のすごいエンジニアの方々は怖いし、先輩諸氏には追いつけないしで、劣等感にまみれていますが、まあ、自分は汚辱にまみれてなにくそと思うような人間なので今が一番エネルギーが出るシチュエーションなんだと思っています。
35歳になって思ったことは
- 夜が眠い
- 体重が増えた
- 白米はいつまでもうまい
ということくらいで、まあ、さほど変わらないので、これからもコードを書きなぐっていければと思っています。
今年も何卒みなさまよろしくお願いいたします。
ウィッシュリストを貼ろうと思ったんですが整理をしてなくて、脳みそと言語発達と言語理論の本ばかりだったのでやめました。 これが欲しいです
Githubでpull request送りたいとき
id:papixさんができる! pull request!という素晴らしいまとめを書いてくださっています。
もっと前に欲しかったw
なんですが、pull request送るぞ!って決めてからforkしてコードを書きなおして・・・ってだるいので、マサカリを担いだ人は多分常識なんでしょうが僕のやり方を…
1. 普通にclone
cloneしてbranch切ってガンガンコード書いてテスト書いてってやります
2-1. なんだかうまくいかなかったり、他のもっと素晴らしいpull reqが現れた時
そこで終了して下さい
2-2. うまくできてpull reqしたくなった時
ここではじめてforkして、github上にリポジトリを作成します。 で、ここまで書いたコードを活かすために
おもむろに
git remote rename origin upstream git remote add origin <forkしたリポジトリ>
とするとpush先が切り替わってくれるので、新たにforkしなおして、cloneして、そのcloneしたものに変更を加えて・・・というのがなくなります。
(∩´∀`)∩ワーイ