Deep Learningで人工知能が実現するとかいってる人たち、あるいはそういう見出しの記事を書きたい記者が正座して読むべき記事

Facebookでケンタロさんに教えてもらった記事。
http://spectrum.ieee.org/automaton/robotics/artificial-intelligence/facebook-ai-director-yann-lecun-on-deep-learning

僕も一時期(2014年の12月から2015年の1月)にDeep Learningについてかなり時間をかけて調べてみたけど、結局明らかに達成されていることは「精度の高い教師あり学習ができる」ということであって、人のように抽象化思考を行う何かがそこから発現するとは思えないと考えていた。(フリーソフトではじめる機械学習の、WEKAでのニューラルネットの章で、オートエンコーダーによってコンピュータが自動的に二進数の概念を獲得するところは興奮したけど。)

We had quite a bit of success with this, but in the end, what ended up actually working in practice was good old supervised learning

また、下記の部分などは僕が好きな苫米地氏がずっと前から表明しているのと同一の見解だと思う。

The bottom line is that the brain is much better than our model at doing unsupervised learning. That means that our artificial learning systems are missing some very basic principles of biological learning.

個人的には、人工知能(強いAI)を作るには、「痛み」「快楽」「生」「死」のような生命の根源に直結する概念、欲求を教えないとダメだと思う。痛みや死から逃げるための判定を最優先させる。このときは低い抽象度で。死から遠いところでの活動には、より抽象度の高い学習や判定を行わせていく。

Advertisements

Continuous Deliveryの時代とJava

かつてバージョン管理やCIなどが存在しなかった頃
人々は手作業で(FTPなどを使い)PHPファイルをアップロードすることで、本番環境へデプロイを行っていた

筆者はJavaプログラマだったので
「本番環境でバグが見つかっても、問題のファイルを修正してアップロードすることで、一瞬で修正できる」
というPHPの利点が非常にうらやましかった
Javaだとjarに固めてアプリケーションサーバにFTPで上げて再起動する、みたいな感じで非常に面倒くさかったのだ

しかし時代は経過し、「ユニットテスト等が行われた後でしか本番環境のファイルが変更されるべきではない」という考え方が常識となってきた
こうなると、「手軽にちょちょいと問題を修正する」というPHPの良さは失われることになる

ウェブアプリケーションを構成するファイル群が全体としてバージョン管理され、テストをパスしたファイル群のみが本番環境に到達できるのだ
まぁそれが正解なのだが、ぶっちゃけ、いざというときの俊敏さは失われることになる
PHPを手作業でアップロードしていた時代、ひどい場合には電話で「なんか問題でてるんだけど」という報告を受けてから数十秒で修正が完了していたケースもあるだろう。

そんなわけで、相対的にJavaでもいいかな、という感じになってきた。


Log4j 2にも採用されたLMAX Disruptorはなぜ狂ったように速いのか?

dis

LMAXという会社はおそらくFX業者で、筆者はLMAXの開発者の講演を、InfoQの動画で何度か見たことがあった。
彼らは非常に特異な集団で、さしずめ「Javaのスピード狂」という感じだ。
印象的なのは、シングルスレッドで仕事を片付けることを強調している点だ。
「Javaならマルチスレッドで並列処理すれば性能が出ると広く思われているが、我々の仕事においてはシングルスレッドが最速だ」というような主張を何度も見た。
ゴールドマンサックスといいLMAXといい、やはり多額の金が動く会社でガチでJavaをやっている連中はカリカリにチューニングするため、技術的には非常に面白い。
彼らがコアのライブラリをOSS化してくれるというのは、金融業界を否定的な目で見る筆者からすると複雑だが、悔しいことに参考になる。

LMAX DisruptorはJavaのライブラリだ。Producer/Consumerパターンであるスレッドから別のスレッドへメッセージを渡す際のパフォーマンスを追求したものである。Log4j2のAsync実装に採用されているようだ。

Disruptorの速さの秘密はいくつかのブログで詳細に解説されているので、じっくり知りたい人はソースコードを読むとともにそちらを参照するとよいだろう。

  • ロックを極力排除し、Producerからのアクセスの一ヶ所でしか使用していない
  • データ構造としてリングバッファを使い、メッセージが格納されている領域のインデックスを各Consumer等がシーケンス番号として管理することで、ロックを減らしている

何とも、非常に頭が良い解決方法である。

シーケンス番号はどんどん上がっていくので、配列を用意すると無限の大きさの配列が必要となってしまう。しかしリングバッファをぐるぐる廻して、全Consumerが処理済みの領域を上書きして使っていくことでこの問題を解決している。

どんなConsumerが存在するのか?が中央で管理されているのが面白い。オブジェクト指向的にはイケていないが、ロックを排除するための工夫ということだろう。

2015/01/06追記
最後の「オブジェクト指向的にはイケていないが…」の部分に対して「別にイケていなくてもいいのでは」的な反応を頂いたので追記しておく。

まさしくその通りで、Disruptorはパフォーマンスを極めるためのものなので、「オブジェクト指向的にイケて」いなくてもOKである。
しかし実は筆者ではなく、LMAXの中の人が、この点について(かなり強く)言及しており、ここは大きなポイントだ。
オブジェクト指向的に綺麗に設計する(関心を分離する)ことにこだわることがパフォーマンス劣化(正確にはcontention)につながっている
と、http://lmax-exchange.github.io/disruptor/files/Disruptor-1.0.pdfに記述されている。

Further investigation and a focus on the computer science made us realise that the conflation of concerns inherent in
conventional approaches, (e.g. queues and processing nodes) leads to contention in multi-threaded implementations,
suggesting that there may be a better approach.

同様にこちらのブログの以下の部分も同様。

The ConsumerTrackingProducerBarrier has a list of all the Consumers that are accessing the ring buffer. Now to me this seemed a bit odd – I wouldn’t expect the ProducerBarrier to know anything about the consuming side. But wait, there is a reason. Because we don’t want the “conflation of concerns” a queue has (it has to track the head and tail which are sometimes the same point), our consumers are responsible for knowing which sequence number they’re up to, not the ring buffer. So, if we want to make sure we don’t wrap the buffer, we need to check where the consumers have got to.

筆者の書き方が悪かったのだが、つまり「オブジェクト指向的にきれいな設計を捨てることで性能向上を実現している」という、トレードオフの部分が非常に面白いのだ。(そのため「オブジェクト指向的にはイケていない」と書いたことは文脈的におかしくないし、むしろもっと強調してもよい部分だと考えている。)

ちなみに上記の指摘をされた方からは「アルゴリズム的な話に、オブジェクト指向をもってくるのがナンセンスなんです。」とも言われたのだが、上記PDFの図を見てもらえばわかるようにDisruptorは典型的なオブジェクト指向で書かれたソフトウェアであるので、Disruptorについて言及している本エントリにおいて「オブジェクト指向をもってくるのがナンセンス」と言われても困る。おそらく指摘された方はDisruptorのドキュメントやソース等は読まずに、本エントリだけに脊髄反射されただけだろうと思う。

Disruptorはいわば「守破離」的に、全体としてはオブジェクト指向に従いながら、オブジェクト指向で当たり前とされる「関心の分離」の一部だけをわざと崩すことで最高のパフォーマンスを実現しているところが素晴らしい。


WekaのIBkはデフォルトで正規化してくれる

フリーソフトではじめる機械学習入門という本があります。

フリーソフトではじめる機械学習入門
荒木 雅弘
森北出版
売り上げランキング: 18,141

筆者的にはかなりツボな本で、既に2度ほど読み通しています。
今度は実際に手を動かしながら(Wekaを使ったりJavaのコードを書きながら)もう一度読んでみようかと思っています。

18ページあたりから、KnowledgeFlow Environment(KFE)を使ってWekaに格納されているirisのデータをK近傍法で分類する例が始まります。
28ページ真ん中あたりで正規化(1~10程度の値を取る属性と1~1000程度の属性などが混在する場合に、データ間の距離の計算において、後者の属性の影響が強くならないようにすること)が紹介され、下図のようにNormalize(左から3つめ)のが追加されます。

weka-nfe

筆者はまず、本書の通りにKFEを使ってみました。

次に、KFEのようなGUIのツールではなく、JavaのコードからIBkクラスを使ったirisデータの分類をしたかったので、Googleで調べながら独学で進めてみました。これは、特に難しいところはありませんでしたが、その時点で手元で書いてみたコードでは、データの正規化を行っていませんでした。そのためこのときの結果は不正確だろうと考えました。

影響を確認するために、わざと極端にレンジの広い属性と狭い属性を持つデータを用意して分類させてみたのですが、特におかしな結果になりません。仕方ないのでNormalizeクラスの使い方を学んできちんと正規化してみましたが、結果はNormalizeクラスを使っても使わなくても同じで、正常な結果となりました。

原因を調べてみると、どうやらIBkを利用したK近傍法による分類では、デフォルトで正規化を行ってくれるようです。デフォルトではインスタンス間の距離を計算するのにweka.core.EuclideanDistanceクラスが使われますが、こちらのクラスが計算の際に正規化をしてくれます。-Dオプションを渡すと、正規化を行わないという動作になるようです。

そのため、本書の28ページから29ページにかけて行われているNormalizeの追加は、省略しても同じ結果になります。


分類されていない大量データは教師あり学習に使えるのか

手元に大量のデータがあって、それを教師あり学習に使って、最終的には分類器を作りたい。
「教師あり学習」なので、まずはそれぞれのデータについて、人間がラベルをつける必要がある。
しかし、データは大量なので、人間がいちいちひとつずつラベルをつけることができない。

詰んだ…

ってなる気がするのだが、これはどう解決するべきなのだろうか。
やっぱり、大量のデータがラベルなしで存在している場合は、教師なし学習が基本なのか?


Amazon EMRでHive/Impala「思考のスピード」とSQL

Amazon AWSのEMRでHiveとImpalaに触ってみた。

通常なら自分でHadoopクラスタを組んでからHiveやImpalaをインストールして…とやる必要があるのに、EMRだとコンソールからポチポチするだけで、しかもSpot Instanceで超安価にクラスタができあがる。

SSHでログインしてhiveやimpala-shellとコマンドを叩くだけ。AWSのサービスはいくつかあるけど、個人的にEMRは一番凄いと思う。

テスト的に某SaaS型WAFサービスのアクセスログを22億行ほどロードして、impalaでいくつかSQLでクエリを投げてみた。m1.mediumという遅いインスタンス20台のクラスタで、単純な問い合わせが4分くらい。

Hiveに比べれば圧倒的に高速なんだけど、俗に最近のSQL on Hadoopで言われる「思考のスピードで解析する」という感じはしない。4分も経ったら脳みその一時記憶領域は完全にクリアされてしまう。

で、ぶっちゃけ思ったんだけど、数億件以上のアクセスログ的なデータに対して解析目的でSQLを投げる場合って、実際にはサンプリングして1/100~1/1000くらいにサイズダウンさせたデータに対して同じクエリ投げれば、十分に目的を達成できる場合が殆どなんじゃないだろうか。

本当にそのまま数億件以上のデータを扱う必要があるケースというのは、異常検知や、あるいは非常にロングテール的にデータの特徴が多岐に渡るケースになるんだと思う。多くの場合はそうでない気がする。


データサイエンスの本を買ったが一部アツすぎる内容で萎えた話

ビジネス活用事例で学ぶ データサイエンス入門
酒巻 隆治 里 洋平
SBクリエイティブ
売り上げランキング: 7,559

↑この本を買ったのだが、95ページ周辺にむちゃくちゃな事が書いてあって萎えた。

統計学では「仮説検定」という手法があります。

しかし、仮説検定は(中略)、人数が(サンプルサイズ)が多い場合には、ほとんどの結果が「統計的に有意な差がある」という結果になります。

差がわずかしかない二つの集団を比べる場合は、そんなことはない。

そもそも「サンプルサイズが多い場合」の定義が書かれていない。「多い」ってどのくらい?

「ほとんど」ってどのくらい?

結局、著者の個人的な経験にのみ基づく内容であって、データ「サイエンス」とタイトルに付く本に書くような話じゃない。

このページの暴走はすごくて、続いて次のような記述もある。

ビッグデータと騒がれているような現在においては(中略)、「仮説検定をしないと統計的に差があるかわからない」くらいの差は意味があるとは言いがたいのです。

お前は何を言(ry

続いて、次も95ページから。

この本の著者に限らず、仮説検定の使い方を理解していない人が仮説検定について誤解しやすいポイントが次の部分。

「統計的に有意な差」があっても、ビジネスとして意味のある差とは限りません。

この事自体は正しいのだが、そもそも考える順番が違うのである。仮説検定とは「もし統計的に有意な差があったら、ビジネス的に意味がある」ことに対して使うための道具なのだ。

この「アツい」95ページはA/Bテストの章の一部である。このA/Bテストの章で取り上げている例が不適切である点もかなり気になった。この部分については本書内の前提の説明が(このブログでやるには)結構大変になるので、興味のある人は実際にこの本を当たってほしい。

AとB、2つのバナーを設置したところ、AとBのクリック率(それぞれ0.080%、0.115%)に統計的に有意な差があって…というのはお約束の流れでよいのだが、結局のところ、この差はどうでもよくて、「目標はクリック率12%です。Bは約12%だからOKです!」と締めくくられる。

約12%? 

しかしデータによると、このBのクリック数は43790回のうち5056回である。

> binom.test(5056,43790)

Exact binomial test

data: 5056 and 43790

number of successes = 5056, number of trials = 43790, p-value < 2.2e-16

alternative hypothesis: true probability of success is not equal to 0.5

95 percent confidence interval:

0.1124811 0.1184903

sample estimates:

probability of success

0.1154602

このように、「12%」のラインは95%信頼区間に含まれない。

> binom.test(5056,43790,conf.level=0.9965)

Exact binomial test

data: 5056 and 43790

number of successes = 5056, number of trials = 43790, p-value < 2.2e-16

alternative hypothesis: true probability of success is not equal to 0.5

99.65 percent confidence interval:

0.1110425 0.1199839

sample estimates:

probability of success

0.1154602

数値をさらに厳しくしてみて99.65%の信頼区間まで広げても、12%のラインは入らないのだ。

つまり、「約12%」とは言っているが、実際にクリック率が12%を達成する可能性は非常に低いのである。

まさか0.1154は四捨五入すると0.12だから約12%でOK…ということなのだろうか…それってデータサイエンスなのか…

さてずいぶん文句ばかり書いてしまったが、この本のスタイルは文句なしに素晴らしい。Rのコードとデータがあり、解析に入る前の実際のビジネスの状況や悩み、思考の過程などが各章において同じ形式で用意されていて、追試しやすい。皆様ぜひご一読を。

2014/08/17追記

「サンプル数が大きくなると統計的に有意であると判断する確率が高まる傾向がありそうだ」といっていいように思えるんだが。

というツッコミをいただきました。この点については異論はないです。その通りの傾向があると思います。しかし、それと

ほとんどの結果が「統計的に有意な差がある」という結果になります。

という書き方だと、だいぶニュアンスが違うように感じますね。上記繰り返しになっちゃいますが「ほとんど」ってどのくらい?ということになります。まぁ「ほとんど」ってサイエンスじゃないですよね。