【雑記】学び方について

最近時間ができて学びを促進させようと考えているのですが、どのように機械学習自然言語処理、情報検索に関連する技術や研究動向を学ぶかについて考えていました。結論を先に言ってしまいますと、よく聞く「自分で疑問を持ち、自分で答えられるようにする。また細部を追ってきちんと中身を咀嚼する」になります。結構当たり前なことを書いている、と書いているうちに気がつきましたが、せっかく書いたので公開しておきます。

あるとき、「読む」といったら一字一句──エンジニア・光成 滋生(2)コストをかけられないなら認めちゃえばいい──エンジニア・光成 滋生(4)を読みまして、「自分の学び方は自分に最適化されているのだろうか?本当に学んだことを理解して咀嚼しているのだろうか?」という疑問が湧きました。

自分でざっと思いつくのは以下の通りです:

  1. 自分で実装する
  2. 勉強会等で発表する
  3. 他人のコードを読む
  4. 教科書の練習問題を解く
  5. 論文を読む
  6. 論文やブログ記事を書く
  7. ブログ記事を読む
  8. 考える
  9. 人と研究やコードについて話す
  10. 頭を整理するためにも休む

他にも方法があると思いますが、これらの方法は結局「手段」にしかすぎず、これらの根本としてあるのが「自分で疑問を持ち、自分で答えられるようにする」だと思います。僕はこれこそが「学び」であると考えています。この「自分で疑問を持つ」という部分が一番厄介です。僕の場合はわかった気でいることが多いため、何が疑問か、というのがわからないことが多いです。この「何」の部分を具体化するために上記の10個の方法を用いて「「何が」疑問なのか」を明確化することを促しています。

また明確化する上で重要なのがはじめに挙げた記事でも触れています通り「コストをかけて学ぶこと」が重要だと思います。"Easy come, easy go"ということわざがあるように、コスト(=時間)をかけてこそ、自分の場合は始めて学んだことが身につく、ということを実感しました。 ちなみにこれは多くの方が触れています(これはアイディアの話ですが):

ちなみに同様のことが論文を読む上でも重要だと感じています:


僕が修士在学時は論文を圧倒的に眺めることが多く、細部を追っていない論文についてもわかった気でいました。これがいけなかった。「わかった」=「どの部分を事細かく聞かれてもきちんと他人に説明できること」という風にならなければいけなかった。(無論全部の論文の細部を追うことはできないですが)。

なぜこれが重要かと思ったのかというと、僕は大学2年生あたりでふと、「何でx^2をxで微分すると2xになるのだろう?」と思ったことがあります。高校の頃はテスト対策としてとりあえずこういった簡単な微分の練習問題をより早く解くか、ということに集中していました(他にも物理や化学等でわからないことがたくさんありましたため、数学に全ての時間を使う訳にもいかなかった背景があります。僕はそんなに物覚えが良いほうではないので)*1

これは以下の微分係数の定義を用いて計算できる、と数2(数3)?の教科書に
f'(x)_{h -> 0} = \frac{f(x + h) - f(x)}{h}
\frac{f(x + h) - f(x)}{h} = ((x + h)^2 - x^2) / h = (2xh - h^2) / h = 2x - h -> 2x
と導出されるという至ってシンプルなことがわからなかったことが背景としてあります。はじめの「何でx^2をxで微分すると2xになるのだろう?」という疑問を高校時代に浮かんであろうに、その疑問を放置して忘れてしまっていました。この件で猛省し、「細部を追うこと」「きちんと咀嚼すること」がいかに大事かを実感しました。

僕の中の結論としては自分にとって現状最も重視すべき「学び方」とは「自分で疑問を持ち、自分で答えられるようにする。具体的には、細部を追ってきちんと中身を咀嚼する」ことであり、それらを今後意識していきたいです(まあ当然と言えば当然のことですが)。ちなみに上の10もの方法はどれも大事だと思いますが、とりわけ1.の実装にかける時間が不足している、と自覚しているのでそこに年末年始は時間をかけていくことを意識します。

それにしてもそろそろはてなブログへ移行した方がよさそうな。

他の参考ブログ記事;
機械学習界隈の情報収集方法
社会人が統計学や機械学習を学ぶなら「落下傘方式」で

*1:これだからテスト用に学んだことをすぐに忘れるのだと思います。時間制約の中、きちんと細部を追うこと、咀嚼することを怠っているから

Atilika体験記

自分がいた会社(Atilika)が新しいインターンを探している、ということですのでステマしてみます。自分はもう去りますので、自分のためのドキュメンテーションとしても兼用しているつもりです。


Atilikaの概要:
Atilikaの創業者はFast Search & Transferというノルウェーで企業し、エンタープライズサーチで一世を風靡した会社にいました。Fastは2008年頃にMicrosoftに買収されてなくなりましたが、その際にFastのエンジニアが散らばったという背景があります。
その中でも彼は新しい会社を興した次第です。オフィスに関してですが、入った当初は机と三人でほぼ満員なオフィスにいましたが、最近引っ越したので広くなりました。おすすめです。

入った動機:
僕の目的は
1.実装力を伸ばしたかった、
2.NLPに関係した仕事をしてみたかった、
の二点でしたでした。
どっかに行きたいなー、でも選考通らないなー、と思っていた時にレジュメを投げてみて拾って頂いた次第です。

入った背景:
ググったらインターン募集のページに行き着きました。勤務時間ではHP曰く「6ヶ月、週28時間まで」と書いてあり、まあ通らないだろうなー、と思って試しにレジュメを投げてみたら意外にも返信が帰ってきました。あとで聞いた話ですが、インターンは別に勤務時間は自由で「最大週28時間」ということらしいです。リモートでも働いてよいということでした。

Kuromoji:
https://github.com/atilika/kuromoji

Atilikaが開発したプロダクトの中でおそらくいちばん有名なのは日本語の形態素解析器であるKuromojiです。基本はMeCabに用いられているモデル(UniDic等)をApacheライセンスで検索周りのOSSに組み込むことが目的として開発されました。SolrやLuceneといった検索周りのOSSに組み込むにはJavaがやはりいい、ということで実装&公開されたのがこのプログラムです。
このコードを見て、「NLP関連の実装力が高そうだ。彼らから学べることが絶対あるはずだ」と確信しました。

人に関して:
正規の社員は二人いて二人ともノルウェー人です。僕の印象としては二人ともマネジメントがうまいです。インターンの意見をきちんと聞くうえ、必ず定期的に「今の実装状況、どーよー」という感じで聞いてきます。あと日本語は超絶うまいです*1
僕は技術力がそんなに高くないので正確な評価ができないのですが、私見では二人ともすごいハッカーだと思います。具体的なことは割愛しますので詳しくは彼らまで。

技術に関して:
業務で使う言語はJava, Java, Java。あとはCSSらへんのフロントエンドによく使われる言語です。Javaに抵抗があると厳しいですが、それ以外の方なら大丈夫だと思います。

何をやったのか:
日本語処理に関連するプロジェクトに関して取り組んでいました。オープンにしない方がよい情報もあると思いますので、詳しくは書かない方がよいと思いましたが、直接聞けば教えてくれると思います。

インターンの希望を尊重してくださるので、やりたいことを主張して、会社全体の方針との折り合いつけていくのがいいかと思います。

感想:
1.当たり前のことを当たり前にできる、というのがいかに難しいかを実感しました(例:Viterbiアルゴリズムをさくっと実装する、Patricia-trieをさくっと実装する)。
2.自分の意見をきちんと相手にわかりやすく伝えられる言葉を選ぶことにも苦労しましたし、大変なことだと実感しました。
3.Javaは学部のころからちょこちょこ触っていましたがbuilder class等の使い方は全く知らず、やはり自分より技術力が上のハッカーからアドバイスを受けた方が早く、綺麗なコードが書けることを実感しました。


最後に彼らに言われた言葉のうち、最も印象に残っている言葉を引用して終わります:
"Programming skills are skills that you can learn and we can teach you."
"But the most important thing is to be a nice guy."

With many thanks to Christian, Gaute and others.

*1:少し脱線しますが、アニメ等の影響により英語がうまい日本人より、日本語がうまい外国人の方が多いのでは、と思うぐらいです。

ハッカーという言葉の意味

ハッカーと画家を読んで「ハッカー」という言葉の意味を今まで異なる解釈を持っていたことを実感しました。今まで自分はハッカー=優れたプログラマ=優れたエンジニア、という認識を持っていました。昔@mamorukさんのハッカーを育てるを読んだ時は「ふーん」という感じでしたけど、ハッカーと画家をよんで「ハッカー」の持つ意味を違う風に解釈していたことに気がつきました。ただこの「エンジニア」と「ハッカー」の持つ用語の意味合いが違うらしいです。
(余談ですがこの方の他のエッセイに目を通したことないのですが、中々面白そうです)

以下「ハッカーと画家」で用いられている各用語の意味をリストアップしてみました。本曰く研究者、ハッカー、エンジニア、という3つのくくりが存在します。

ハッカー =絵を描く=美しいソフトウェアをデザインする人
研究者  =新しい絵の具を生み出す
エンジニア=どうやって目的を達成するかを考え、実行する人(=ソフトウェアを実装する人)

つまりエンジニアは「デザインをしないハッカー」という風に解釈しました。「ハッカー一人にソフトウェアをデザインさせるように、コミュニティによってデザインして、企業のハッカー(ここではエンジニアのニュアンスになります)は実装のみする」。coding monkeyに近いイメージでしょうか。このソフトウェアをデザイン、という言葉もソフトウェアの実装上のデザイン(どこからどこまでを同じクラスにするか等)ではなくソフトウェアの方針のデザインということでしょうか。例えば改善要求が山ほどあるソフトウェアでしたら、ここからここまでの要望は聞くけど、こことここの要望は聞かない、ということも方針のデザインの一つ、ということかと思います。

またエッセイのスタンスとしては個人的な解釈ですが、研究者、ハッカーは共有している要素はあるが、ほとんど別、特に目的意識が違うという認識です。これは研究と開発、何が違うのか?ということに関連してきます。とりあえず動くものであり既存のものでも有益であればよいのが開発、新しい分野や手法を切り拓くのが研究というのがざっくりした自分の認識です。(そもそも研究がなんなのか、というのは永遠のテーマかと思いますが)。そしておそらく企業における研究と開発、大学における研究と開発というくくりでも大分内容が変わってくると思います。この辺は企業での経験が少ないので割愛して他の予稿に譲ります。
参考リンク:企業の研究者として働くことの魅力

Paul Grahamのいう「コンピュータサイエンスは色んなものを一緒くたにしすぎている」というのは賛成です。例えば、時々同じ自分と同じコンピュータサイエンスの方なのに、数学の能力が雲泥の差があることがよくあります。一方で圏論に基づく関数型言語があって、一方でWebがある。人に比較的近く泥臭い分野もあれば、計算量理論など純粋な理論によって形成されている分野もあります。

ハッカーを育てるを読んだ時の話に戻りますが、こういった背景知識の差で同じインプットに対しても認識することが違うことがあることを再度実感しました。

Lisbon Machine Learning Summer School (LxMLS)に参加してきました

半分自分用の備忘録として残しておきます。好き勝手書いていますので一個人の感想として受け取ってください。

Lisbon Machine Learning Summer School (LxMLS)に参加してきました。参加した動機としては:
1.国際会議を聴講しても自分の少し専門外になると基礎的な部分や背景がわからないため、「この研究が面白いのか」というのがよくわからない(今も微妙ですが)
2.国際会議にあまり出ていないので、海外の生の研究情報が入ってこない。ヨーロッパの現状を知りたい
というのがありました。

Machine Learning Summer School(MLSS)は有名ですが、そことは別の系統です。MLSS系とは別にポルトガル人の有志が立ち上げたらしいです。主催者の内、一人がNoah Smith研の院生であるのと、もう一人がAmazonの研究者なのでその人達のコネで各分野の第一人者を呼んできたのかな、と想像しました。主催者曰く、MLSS系とは別にNLPに特化しているため、機械翻訳構文解析のレクチャーも多くありました。(余談ですが日本人で論文が引用されていたのは構文解析の論文二枚だけでした。遠い異国の地でMさんとSさんの論文が紹介されていて、ようやくかの方々の凄さを実感しました。)また、参加人数が年々増えているらしく、今年はacceptance rateが60%前後だったらしいです。ただし、修士や博士課程の一年の学生を受け入れることに対してpriorityを置いたらしいので運良く潜り込めました。

基本的に朝の3時間の講義は基礎と応用、午後の3時間は演習、夕方の1.5時間は発展的な内容を紹介する構成になっていました。ただ夕方の講義は頭が少し疲れている上、何の説明もなしに新しい概念がポンと出てきたりするので、ここらへんは少し改善の余地があるかと思いました。(例:Semantic Role labelingにおいてChinese Restaurant Processが現れた)まあ、そもそも基礎から発展的な内容まで7日間に一気にカバーするのでどこかしかに無理は生じてくると思いますが。

また、朝と夕方の講義ですがGoogleがスポンサーについている理由からか、Googleの研究者の講演が半分以上でした。個人的な感想ですが基礎的な講義、という観点からはGoogleの研究者の方よりは大学の助教であるNoah SmithとChris Dyerのレクチャーが一番わかりやすく、面白かったです。あとの方々の発表はどちらかというと国際会議の発表に近い感じでした(もちろん、論文の発表を聞く、という観点からは面白くはあります)。このあたりはやはり大学の講義等での経験の違いなのかな、と思います。(Smithさんは少し喋るのが早かったですが、、、)。
参考リンク:Noah Smithのsequence modelに関する資料
−教師なしHMMの話を初めて詳しく聞きました

演習で用いた資料も枝葉を落として最低限必要な部分のみわかりやすく書かれていてとても読みやすく感じました(例: LBFGSが誕生した背景は勾配法の更新式の収束が遅いのでそれを早くするため)。あそこまで体系立てているのはかなりの時間を使って資料を作成したことが容易に想像できます。また、演習では大学や院生、企業の人などがTAをやっていまして、わからないと聞く感じです。ただ、どんな内容を聞いても必ず答えが帰ってくるのは主催者の4人だけでした。そうでなくても僕にとっては十分でしたが。

レクチャーのビデオとスライド*1や演習のコード*2は公開されているので行く意味はあるのか?と思われるかもしれませんが、特定の方々には行く意味はあると思います。僕の場合は:
1.基礎的なことは大勢でやる方がはかどりやすい。一人でビデオを観ているとついついサボりがちになる。
2.日常の雑務やルーティン等から強制的に開放される。そのため、集中して基礎を固める環境ができる。
3.何よりもレクチャー以外の情報交換や新しい人の出会いが貴重な財産になる。
というメリットがありました。あと、ワインがreceptionとbanquetで大量に出てきて美味しかったです。
(とはいいましても、博士進学した人にとっては物足りないかもしれません。)

トップカンファレンスに通している人達が数人いましたがやはり彼らとの差があるなー、と感じました。講師の方のお一人と話している際に「10日ぐらいでプロトタイプ作って、State of the artと比較して、かなり悪かったら別のことをやる」「2013年になってFailed projectの数よりもSucceeded projectの数が上回った」と言われましたことが一般的に良く言われていることですが、印象深かったです。良い成果や結果があまり出ないのはやはり、着眼点や研究の回し方にまだ改善の余地があるのだと思います。ただし、彼はテーマが大当たりして運が良いうえに頭も良いのであまり参考にしない方が良いかもしれませんが。

最後に渡航費の一部を大学の奨学金によってサポートして頂きました。関連団体の方々に感謝申し上げます。

CRFの目的関数が凹関数(concave function)であるかの証明

先日tkngさんより「CRFの目的関数は凹関数なので局所最適解は存在しない」とご指摘を受けたのですが、「あれ、凹関数であることをどうやって示せばいいのかな?」と考え、調べた結果をまとめます。大学1年生レベルの内容ですが復習がてらです。

Claim:
CRFの目的関数は凹関数である。

まずこれを示すためにはある関数が凹関数であることをどうやって示すのか?

Lemma 1:
凹関数であることを示すには関数の二階微分が正であることを示せばよい。多次元の引数を取る場合、ヘッセ行列が半正定値対称行列であることを示せばよい。

何でこれでよいか?と聞かれるとまだ説明ができませんが、イメージとしてあるのは「傾きが広義単調増加しているから関数がU字型のカーブを描く」というもの。

Lemma 2:
Log-sum-exp は凹関数である。(実数上では)

CRFの目的関数はアンダフローを防ぐため等の理由でlog-sum-expが用いられます。その為、こちらに軸をおいてこの先を進めていきます。まずCRFを用いた博士論文に「log sum expはconcaveである」との記述を見かけました。

Proof. See in Convex Optimization [Boyd & Vandenberghe, 2004].

http://d-nb.info/1043515208/34

ということでググった所、無料公開されていたので3.1.4節のSecond order conditions(71ページ)を見てみました。

Log-sum-exp is convex on R^n

https://www.stanford.edu/~boyd/cvxbook/bv_cvxbook.pdf

いや、だから何でですか。。。と思いかけていた所、授業のスライドが公開されていたのでみてみる。(10枚目のスライドに詳しい式が載っている。)

let and

http://www.stanford.edu/class/ee364a/lectures/functions.pdf

diag(z)はz_kをk列k行の対角成分に並べ、それ以外の要素は0とする行列です。zz^Tになっているのがなるほど、と思いました。z^Tzの場合はただの数値になりますが、この場合はn*nの行列になっています。

とりあえずこのが意味不明でしたので簡単に二次元で計算してみます。

例:
{ \displaystyle f(x) = \log (\exp (x_1) + \exp (x_2)) }
のヘッセ行列を算出する。

 \frac{\partial f}{\partial x_1} = \frac{1}{\exp (x_1) + \exp (x_2)} * \exp (x_1)
 \frac{\partial^2 f}{\partial x_1 \partial x_2} = -(\frac{1}{\exp (x_1) + \exp (x_2)})^2 * (\exp (x_1) * \exp (x_2))
 \frac{\partial^2 f}{\partial x_1^2} = -(\frac{1}{\exp (x_1) + \exp (x_2)})^2 * (\exp (x_1))^2 + \frac{ \exp (x_1)}{ \exp (x_1) + \exp (x_2)}
以下同様にx_2に関しても計算する必要があるのですが、ほぼ同じなので省略します。
三番目の式の第一項がスライドの数式の第二項に、三番目の式の第二項がスライドの数式の第一項に対応しています。あー、なるほどと思いました。意味がわかりますと、なんと簡潔に表現されているのだ!と感動します。

この後スライドの通りヘッセ行列を計算すると半正定値対称行列になります。
証明の過程で用いられているCauchy-Schwartzの式で少し詰まったので行間を後で埋めます。まだ未完成ですので後日追記します。