hidekatsu-izuno 日々の記録

プログラミング、経済政策など伊津野英克が興味あることについて適当に語ります(旧サイト:A.R.N [日記])

機械学習をさらに理解する

前回のエントリで機械学習とは空間に線を引く作業に他ならないと書いた。これはこれで正しいとは思うのだけれど、さらに調べていくと例外も当然ある。具体的にはベイズ統計を用いた機械学習モデルがそれにあたる。

古典的な確率論では、誤差に分布があるだけで、真の境界は線上にあると考えるが、ベイズな世界では、境界線自体に分布がある状態こそが真であると考える。だから、出力となる結果は値ではなく確率分布となる。

とはいえ、線が確率分布となるだけなので、脳内イメージ的には、ぼんやりとした線が引かれると考えればそう大きな飛躍があるわけではない。

ベイズ的な確率論を含めた機械学習では、機械学習を「識別関数」「確率的識別モデル」「確率的生成モデル」に分類して説明するのが一般的なようだ。「識別関数」と呼ばれるものが古典的な確率論をベースにした機械学習法、「確率的識別モデル」「確率的生成モデル」はベイズ的な確率論がベースとしたモデルだ。「確率的識別モデル」が条件付き確率分布を直接推定するのに対し、「確率的生成モデル」は、データの尤度と事前確率分布を推定し、そこから条件付き確率分布を導出するものを言う。

「識別関数」も対ベイズとしてはひとつにまとめられているが、「線形識別関数」、線形識別関数に非線形変換を組み合わせた「間接的非線形識別関数」、直接的に非線形識別関数を推定する「直接的非線形識別関数」の三種類に分類できるようだ。

ただ、このように分類したところで、どれがどのように良いのかと言われるとよくわからないところがある。線形よりは非線形の方がより細かい分類が可能だろうとか、ベイズ確率のほうがより現実的な感じもする、といった感覚はあるのだけれど、こういう問題にはこの方法を使うべき、という指針らしきものはあるのだろうか。

機械学習を理解する

機械学習には昔から興味がありSVMとかちょくちょく調べてはいたのだけど、体系的理解がなく、全体としてはもやもやした感想を持っていた。

先日、特にきっかけがあったわけでもないのだけれど、急に思いたち機械学習で用いられる手法を整理すれば何かわかるのではないかと、いろいろ調べてみた。

まず、機械学習がどのような目的に用いられているかを調べるのがいいのでは思い機械学習チートシートをひとつひとつ紐解いていくと、概ね次のようなものに集約されることが見えてきた。

最初は、この目的と教師あり/教師なし/強化学習を組み合わせればパターン分けできるのではないか、と思ったのだけれどもどうにもしっくりこない。クラス分類で用いられる手法は概ね回帰でも利用できたりするし、異常検出に至っては他の目的の応用例ともいえるくらい多様な手法が導入されている。

いろいろ考えてみた結果、見方を変える必要があるという気になり、最終的に落ち着いたのが次の説明となる。

  • 機械学習とは、入力データをうまく分割できるよう、空間に線を引く作業に他ならない
  • 分割した線上の値に注目するのが回帰分析(予測)
  • 分割した領域に注目するのが識別(クラス分類やクラスタリングなど)

2クラス分類であれば一本の線を引けばよいし、複数クラス分類についても、複数本の線を引くだけのことだ。線を引くということは関数のパラメータを推定する、ということに他ならないわけだから最終的には機械学習とは、

  • 入力データをうまく分割する関数のパラメータを推定する

ということを意味することになる。この説明のよいところは、教師あり/教師なし/強化学習の意味合いも教師データの違いとして説明可能なところだ。

  • 入力データと出力データの組から関数のパラメータを推定するのが教師あり学習
  • 入力データと分割終了条件から関数のパラメータを推定するのが教師なし学習
  • 入力データと出力データの評価の組から関数のパラメータを推定するのが強化学習

学習というとフィードバックがあるかのような前提を想定してしまうが、フィードバックのありなしはオンライン学習(あるいはミニバッチ学習)が可能か、という手法の問題であって本質的な話ではない。

だから何だ、という話に感じる人もいるかもしれない(し、実は全然間違っている説明なのかもしれない)けれども、私の中ではうまく整理できたような感覚を持った。人工知能と言うと何かすごいもののような気もするけれど、その内実は関数近似の延長線上の話なんだ、と考えるとちょっとはわかった気になれるというものだ。

データモデリング・テクニック

社内勉強会用に流用するつもりではあるんだけど、一度データモデリングについては考えをまとめておきたかったので、資料化してみました。

 データモデリングについては、昔読んだ本を読み返したりもしたのだけど、なんとなく共通的な基盤がありながらも、これが標準と言えるような方法論がないのが難しいところ。私個人としては、「楽々ERDレッスン」の著者の羽生章洋さんがWeb+DBプレスに書いていた記事とか当時のブログに強く影響を受けました。

自分の考えが絶対に正しいというつもりはないんだけど、わりとトラディショナルな考え方をベースにいろんな人のノウハウっぽいものを詰め込んで書いたので、新人向けの教育資料としては手頃なんじゃないかと思ったりもしています。

まぁ、データモデリングは関しては、強い意見を持っている人も多いとは思うので、ご意見あればこのブログなりTwitter なりにお寄せいただければ、と。

楽々ERDレッスン (CodeZine BOOKS)

楽々ERDレッスン (CodeZine BOOKS)

 

 [2016/10/24追記] 用語の説明が足りてなかったところや非正規化の補足を追加しました。 

「科学が役に立つ」について思うこと

ノーベル医学・生理学賞の受賞が決まった大隅教授の

「科学が『役に立つ』という言葉が社会を駄目にしている。本当に役立つのは100年後かもしれない。将来を見据え、科学を一つの文化として認めてくれる社会を願っている」 

 という言葉が注目を集めている。とはいいつつも、科学系で日本人がノーベル賞受賞すると毎度同じようなことは言っている気はするけれど。

私も理工系の出身なので、その意見には賛同したい気もするのだけれど、やっぱり間違ってるよなぁ、と思ってしまう。この手の言い分は「企業は利益のためだけではなく、周辺社会や従業員の生活のためにも存在している」に通底するように思う。

例えば、誰から見ても一点の曇もなく役に立たない研究があったとしよう。具体的に思いつかなければ、「トリビアの泉」で紹介されるトリビアの種をひとつ念頭に置いていただきたい。通常、大学の教授ともなれば、1000万円程度の年収はあるだろう。この誰から見ても言っての曇りもなく役に立たない研究に政府は、年間1000万円を拠出しても構わないだろうか。日本にも貧困に苦しむ人はいくらでもいる。その人に渡した方がいいかもしれない。

文化として認めてほしいという言葉にも微妙なところがある。夜這いのようにすでに滅びた日本文化もあれば、一部のイスラム教国に見られる非人道的な規則も文化といえば文化だ。ゲームやアニメのように、かつては文化として認められなかったものが文化として浸透する場合もある。文化とは人々が自然と培っていくものであり、認めてもらえるようお願いするものではないように思う。

企業の目的は「収益を最大化すること」だ。だから、周辺社会や従業員の生活に気をかけるのは、そうすることが最終的には自社の利益に繋がるからと考えるのが筋だろう。

同じように、科学者は「私には今は思いつかないけれど、長い目でみれば役に立つんです。こういう地道な研究が社会の生産性を向上させるんです」というべきなのではないだろうか。一見、直接的には役には立たなそうな宇宙科学や歴史学であっても、多くの人の知的好奇心を満たすのであれば、経済学的な考えに沿って人々がその知的好奇心に支払ってもよいと考える金額に相応した費用を投じることは正当化できる。

言い方だけの問題かもしれないけれど、科学者にはもっと自信を持って「役に立つんです」と言ってほしいと個人的には思うのだ。

才能か努力か(おかわり)

以前のエントリーで「超一流になるのは才能か努力か?」を取り上げたけれども、その後、バランスを取るためにこれも読め、というツィートで紹介されていたのが次の本。

スポーツ遺伝子は勝者を決めるか?──アスリートの科学 (ハヤカワ・ノンフィクション文庫)

スポーツ遺伝子は勝者を決めるか?──アスリートの科学 (ハヤカワ・ノンフィクション文庫)

 

 「超一流…」本が努力すれば誰でも一流になれるという本に対して、この本はスポーツには遺伝子が重要であると主張する著者により書かれていて一見対極にある主張に見える。だけれども、読んでみるとむしろ「超一流…」本を補完する内容であることに気付かされる。

この本で書かれていることは、特に身体能力がそのまま成功につながる特に陸上競技のようなスポーツにおいては、遺伝によって形成される身体的特徴が決定的に重要であるということだ。具体的には次のよう例が紹介されている。

  • マラソンランナーは、酸素吸収能力が重要
  • バスケット選手は、身長と身体の横幅が重要
  • 高跳びの選手は、アキレス腱の長さが重要
  • 野球のバッターは、視力が重要

身長や骨格、アキレス腱の長さなどの身体的特徴は、遺伝の影響が極めて大きく、訓練だけでは、その形質を獲得することができない。そのため、トップアスリートになるには、素質が極めて重要になるということのようだ。データからは、幼いころ足の遅い人が、その後の練習によって速くなるケースはないとさえ結論されている。

だが、この本の面白さはそこで終わらないところにある。素質があると考えられるケースであっても、生まれながらにトップアスリート並みの能力を持つ突然変異的な人もいれば、練習量に応じて爆発的に能力が増加するタイプの人もいる、であったり、環境的要因、たとえば毎日ゲームや甘いものに囲まれた生活ではもし素質を持っていたとしても、それを開花させる環境にないため、結果的に貧しい地域の出身者にトップアスリートが生まれやすいという、遺伝子の複雑さやそれをとりまく様々な環境との相互作用が説明される。

さらに、逆のケース、優れた遺伝的形質を持っているが故に上手くいかないケースも紹介されている。サッカーのコーチは皆、足の速いアスリートを求めるが、速筋線維の多い選手は大腿屈筋群を痛め怪我するケースが多く、結果的に速筋線維の少ない選手のみが残ってしまう。痛みを感じない家系の話などは(不謹慎な話ではあるが)とても興味深い。

別の遺伝子が、一〇代のパキスタン人ストリートパフォーマーの才能を追求した科学者によって発見された。

パキスタンのラホールにある病院の関係者は、この少年をよく知っていた。自分の腕にナイフを突き通したり、燃えている炭の上に立ったりした後にやって来ては、傷口を元通りに縫い合わせてもらっていた。ただし、痛みから救うために治療を行ったのではない。少年は痛みをまったく感じることができなかったのだ。

イギリスの遺伝学者が少年を研究するためにパキスタンを訪れる前に、彼は一四歳ですでになくなっていた。友だちの気を引こうとして屋根から飛び降りたのだ。

(中略)

生まれつき痛みに対する感覚がない人間はそれほど長くは生きられない傾向にある。座ったり、眠ったり、立ったりするときに、私たちが無意識にするように体重移動をせず、それがもとで関節感染症を起こして死んでしまうのだ。

この本で語られる内容と「超一流…」本をあわせて考えれば、どこまでが遺伝子の影響で、どこまでが努力の結果なのか、何となく想像できる。結局、コンピュータのハードウェア、ソフトウェアの関係と同じということなのだろう。

ハードウェアの性能は遺伝で決まり、大きくは変えられない。だからハードウェアの能力が決定的に重要な場合には、ソフトウェアでいくらカバーしようとしてもカバーできない。それはファイルI/O性能ではHDDがSSDに太刀打ちできないのと同じことだ。

しかし、いくらSSDのファイルI/O性能が良くても、常に同期書き込みをするようなことをしていたら、HDDにも劣る性能になるかもしれない。性能を活かすには、それ相応のソフトウェアが必要となる。

特にトップアスリートでは、ソフトウェアは極限までチューニングしている状態に等しく差がつかない。だからハードウェアの性能が決定的に重要になる。

一方で、ソフトウェアについては、「頭のでき―決めるのは遺伝か、環境か」などからも、個々の人々でさほど差が出ないことが伺える。実際には遺伝により多少の差はあるのかもしれないが、ソフトウェアはアルゴリズムの優秀さで大きな差が出る。訓練により専用回路を獲得してしまえば、多少の素質の差は問題にならないということなのかもしれない。頭脳や戦術が重要な分野では、「超一流…」本の内容は引き続き有効ということになる。

とはいえ、多少気になる記載もある。それは、「脳科学は人格を変えられるか?」でも議論となっていた楽観的/悲観的、あるいはやる気の部分だ。「超一流…」本では、意志の力の差などない、と結論づけられていたが、本書では少なくともスポーツに関してはもっと運動したいという「やる気」に関する形質が存在することが明らかにされている。誰でも努力すれば成長できるけれども、努力する気持ちは遺伝によって決まっているのだとすると悲しいものがある。では、ドーピングで改善できれば良いのか、というと自由意志の問題にも発展しかねない。なかなか難しい問題だ。 

超一流になるのは才能か努力か?

超一流になるのは才能か努力か?

 

 

Rust 言語で JNI ライブラリを作る

Java にはプラットフォーム固有のライブラリを利用するために JNI (Java Native Interface) という機構が用意されている。この機構の問題点は、どこのプラットフォームにバイナリを持っていっても同じように動くという Java の最大の利点を失わせてしまうことにもちろんある。それはそうなのだけれど、最大の問題は様々な環境用のバイナリを用意するにはそれぞれコンパイル環境を用意する必要があり、現実的には難しいという点にある。

そこで考えたのだが、Rust はクロスコンパイルができるようになったと聞いた覚えがある。ということは単一環境(例えば、普段デスクトップとして使っているWindows PC)からでも各環境に対応した共有ライブラリが生成できるのではなかろうか。

まずは、Rust で JNI ができるのか調べてみた。すると出てきたのが次のサイト。

nitschinger.at

問題なくできるようだ。さらに調べたところ、

github.com

を使えば、jni.h の定義を Rust 用にいちいち手動変換する必要もないこともわかった。

Rust 付属のパッケージマネージャーは npm と似た仕組みになっているので、簡単にライブラリを追加できる。Cargo.toml に次の記述を追加する。

[lib]
crate-type = ["cdylib"]

[dependencies]
jni-sys = "0.1"

はじめは、crate-type = ["dylib"] と指定していたのだけれど、JNIで呼び出す場合は、Rust からの呼び出しは必要ないので、外部呼び出し専用の cdylib で構わない。これを指定するだけでファイルサイズが 2.2MB から 22KB になる。

さて、前述のサイトの add メソッドを jni-sys を使用して書き直すとこうなるになる。

extern crate jni_sys;

use jni_sys::*;

#[no_mangle]
#[allow(unused_variables, non_snake_case)]
pub extern fn Java_RustTest_add(jre: *mut JNIEnv, class: jclass, v1: jint, v2: jint) -> jint {
    v1 + v2
}

あとは普通に cargo build --release するだけでいい。予想以上に簡単。

この記述を見ればわかるように、プラットフォームに依存する記述はないため、この時点で少なくともマルチプラットフォームに対応できていることになる。

あとは、クロスコンパイル……と行きたいところなのだけれど、残念ながら現時点ではうまく行っていない。どうもランタイム環境は必要となるらしく、Windows 上で Linux バイナリを作るのは難しいようだ(Windows Subsystem for Linux を使えばできるはずだけれども)。 とほほ。

当初の思惑とは外れたとはいえ、予想外に簡単に JNI が実現できたことがわかったのは良かった。あとは SQLite とか各種ライブラリが Rust に移植されてくるといろんなことができるようになって面白くなるのだけど、そういう未来は来るのだろうか。

プロジェクトマネージャーが本当に気にすべきこと

仕事柄、プロジェクト管理についてはいつも関心を向けているのだけど、私自身があまりプロジェクト全体を管理する立場にないこともあり(基本、アーキなので)、なかなか考えをまとめる機会もなかった。たまたま、本屋でパラパラと PMBOK の本を眺めていて思ったことがあったので、書き留めてみることにする。

PMBOK 自体は辞典的な定義付けという意味では理解できるところは多いのだけど、実践的という観点からするとあまりにも表面的な内容に思えあまり意味があるように思えない。

例えば(といいつつ本題に入るのだけれど)、PMBOK には9つの知識領域というものがあり、これを管理すれば網羅的だよ、という言い方がされる。具体的には次のものが管理対象として挙げられている。

  • スコープ
  • タイム
  • コスト
  • 品質
  • 人的資源
  • コミュニケーション
  • リスク
  • 調達
  • ステークホルダー

たしかに嘘ではない。嘘ではないだが、正直ピンとこない。実際にPMになったとき、これを見ても何をすればいいのかがよくわからないのではないだろうか。

私が思うに、本当の管理対象はこうだ。

  • 顧客
  • 体制
  • タスク
  • 品質

一見して、QCDのCとD、通常最も重視されるコストと納期がないじゃないか、と即座にツッコミが入ると思うのだけれども、外したのには理由がある。

第一に、コストと納期は結果に過ぎない、と考えているからだ。管理してなんとかなものであれば、超優秀なPMを雇えば100円で明日までに100万人月のプロジェクトを成功させることだって可能なはずだが、もちろんそんなことは起きない。

不必要にコストを使っている(プロジェクトの経費で毎日銀座を飲み歩いている、とか)、不必要に期間を費やしている(メンバーが皆、毎日新聞を読みに会社に来ている、とか)というのであれば、管理せざるを得ないとは思うが、そんなことはめったになく、皆最大限に努力しているにも関わらずうまくいかないというのがだいたいのところだろう。

第二に、コストと納期はプロジェクトが始まる前には概ね決着しているということもある。標準工期という概念はあるにしろ、特に業務システムは決算期の切り替え時期やシステム更改の時期があるため、納期は顧客から指定される場合がほとんどとなる。コストについても、近年はコンペや相見積りが必須となる場合が多く、PMがアサインされる頃にはコストの枠は決まってしまっていて変えることは困難だ。

プロジェクトマネージャーの仕事とは、あらかじめ決められたコスト、納期を実現するために別の何かを管理するということなのではないかな、と思うわけだ。

ついでに言えば、リスクも管理対象ではない。というのも、コストも期間も限られている中、起こるかどうかわからないことに対処することは事実上不可能だからだ。リスクに対処するにはそれ相応のお金を積むしかなく、お金を積むのであれば見積り時点で考慮する必要がある。コストが管理対象でないことは前述の通り。

さて、本筋に戻ろう。まず「顧客」である。顧客を管理すると言うと大変失礼な言い方になってしまうが、例えば JUAS のソフトウェアメトリクス調査を見ると、工期遅延理由の半分は要件あるいは開発規模の増大に起因するという結果が出ていたりする。このことを踏まえれば、顧客は発注者であると同時に最大のプロジェクト失敗要因という言い方もできる。もちろん、逆の言い方をすれば、プロジェクトの成功を決めるのも顧客であるとも言えるわけだから、その関係を円滑にすることが重要でないわけがない。

PMBOKで言えば、ステークホルダー、スコープ、コミュニケーションが対応する。

次に「体制」。この体制は、ベンダーサイドの体制を意図している。昔、どこかで「あの男は優秀なPMだと思っていたから、今年の新人を全員投入してプロジェクトを任せたら炎上している」みたいな話を聞いたが、どんなにPMが優秀でも、メンバがまったく使い物にならないのではプロジェクトの成功はおぼつかない。むしろ、PMは並だが、メンバが優秀な人ばかり、という場合のほうがよほど成功しやすいだろう*1

きちんとした体制さえ組めれば、コミニュケーションは自然と改善するものではと個人的には思っている*2PMBOKで言えば、人的資源、コミニュケーション、調達が対応する(人的でない資源の調達は、実際のプロジェクトではそこまでボトルネックになるケースは少ないのではないかと考え一旦無視している)。

「顧客」と「体制」は人的側面の両面であるが、「タスク」と「品質」も構築対象の両面を表している。

「タスク」管理が重要なことはライフハック系の話で必ず言及されることから明らかであるが、プロジェクト管理の側面で言うと期限が重視されすぎなのではと感じる。個人的な経験から言えば、これはまったく間違っている。

タスクとその優先順位が明確になっていれさえすれば、あとは最善の努力でそれをこなすということが重要なのであって、期限自体はある種の目安に過ぎない。困難なタスクはどう期限を切ろうが簡単には終わらないし、そのようなタスクほどあらかじめ作業時間の見込みを立てるのは難しい。そのタスクができるだろうと踏んだ人に任せたら終わるまで待つしかなく、終わる見込みがなければ別の人に頼むしかない。期限は守れたが品質はボロボロというのでは、むしろプロジェクトの失敗に貢献しているとさえ言える。最近、CCPMという制約理論(TOC)に基づく進捗管理手法に言及されることがあるが、この観点からもなかなか良い手法なのではないかと思い始めている。

一方の「品質」は、成功の指標であるQCDのひとつではあるものの、他のふたつが客観的で明白な指標であるのに品質はあまり明確ではなく、見えにくいという点がキモである。コストと期間が制約されている状況下では、その結果が品質の低下として現れるのは必然ではある。とはいえ、多少の品質劣化であれば、必ずしも大きな問題とはなるわけではない。業務的にカバーできる内容であれば、リリース後に修正してもよいわけだし、めったに使わない機能に存在する不具合の場合、誰も気付かないことだってありうる。また、システム開発の裁判においても、納品後も不具合が残ることは一般的であり、それ自体はプロジェクト中断の理由とはならないとされている。

問題はユーザの利用を妨げるほど著しく品質が悪い場合だ。開発がわからないプロジェクトマネージャーのつまづきポイントがここにある。タスクとスケジュールだけを管理し、品質をまったく見ずに進めた結果、完成したと思われていたはずのものが実は完成していないというオチがおとずれる。どんなボタンを押しても例外が発生するという明らかな不具合から、すべての金額計算が浮動小数点型で行われているといった細かい問題もある。魂は細部に宿るではないけれど、ミクロだが致命的な問題は見えづらいがゆえに、納期直前に発覚する事が多く致命傷になることもある。途中でソースコードレビューを行ったからといって、すべての不具合が検出できるわけではもちろんないが、成果物の品質水準や開発者のレベルはある程度わかる*3

まぁ、私自身はプロジェクト管理の経験が豊富とは言えないので、今まで傍から見てきた感想と思っていただきたい。

TOC/CCPM標準ハンドブック クリティカルチェーン・プロジェクトマネジメント入門

TOC/CCPM標準ハンドブック クリティカルチェーン・プロジェクトマネジメント入門

 

 

*1:前述のJUASの調査によれば、ベンダー側PMの能力はソフトウェアの品質に大きく影響するという結果が出ているので、PMが重要でないと言いたいわけではもちろんない

*2:宮﨑駿は、人間関係もふまえアニメーターの座席を自ら決めるそうだが、それはやりすぎな気がするし万人におすすめするような手法とも思えない。

*3:よく品質は自動チェックツールで判断すればよいのでは、という話が出るのだが、自動チェックツールはコンピュータでしか気付けないような不具合の発見に得意な反面、さきほどの浮動小数点型の利用といった業務的な観点での不具合は見つけてくれないため、実際のところ品質の判定には使えない気がする。むしろコーディング規約の違反に開発者のスキルレベルが現れやすい感がある。