数理的手法を使いやすくするためのソフトウェア開発

科学技術計算とデータサイエンスについて

Docker で TensorFlow を Ubuntu 16.04 にインストール

職場では Anaconda で TensorFlow をインストール^1 したのですが、自宅では Docker でやってみました^2 ^3。やってみるまで、Anaconda, Docker の何が良くて、どのように使い分けるのか良く分かっていませんでした。なので実践から。

自宅PCはグラフィックボード AMD Radeon HD 7770 を積んでいて、SC15でRadeonでCUDAを使えるようにするよと発表^7 ^8があったと聞いているのですが、まずは、GPUなしでと、CPU版をインストールしました。

Dockerの入門的知識は必要

いきなり、Docker をインストールして、TensorFlowコンテナを実行してみると、いろいろとおかしなことが起きました。

やはり、最低限の知識として、Docker のイメージ・コンテナ管理の基本と、イメージのビルド方法くらいは必要です。今思うと、

Docker入門 – コンテナ型の仮想化技術の解説 ^4

の Quick Start -> Try it! と、

「さわって理解するDocker入門」オージス総研 大西 洋平 ^5

の第1回、第2回くらい、あるいは、

@IT > いまさら聞けないDocker入門 ^6

の第1-3回くらいを、読んでから取り掛かったほうが、早く出来たのかもしれません。

Docker をインストール

まず、必要なパッケージをインストールしました。

$ sudo apt-get update
$ sudo apt-get install -y --no-install-recommends \
    linux-image-extra-$(uname -r) \
    linux-image-extra-virtual
$ sudo apt-get -y --no-install-recommends install curl \
    apt-transport-https \
    ca-certificates \
    software-properties-common

次は、レポジトリをセットアップ。まずはDockerのオフィシャルGPG keyを追加しました。

$ curl -fsSL https://apt.dockerproject.org/gpg | sudo apt-key add -
OK

Key IDの検証。

$ apt-key fingerprint 58118E89F3A912897C070ADBF76221572C52609D
pub   4096R/2C52609D 2015-07-14
      フィンガー・プリント = 5811 8E89 F3A9 1289 7C07  0ADB F762 2157 2C52 609D
uid                  Docker Release Tool (releasedocker) <docker@docker.com>

安定版のレポジトリをセットアップ。

$ sudo add-apt-repository \
       "deb https://apt.dockerproject.org/repo/ \
       ubuntu-$(lsb_release -cs) \
       main"

これで、Dockerをインストールできるようになりました。あとは、

$ sudo apt-get -y install docker-engine

で docker-engine_17.04.0~ce-0~ubuntu-xenial_amd64.deb が入りました。

しかし、このままでは Docker を実行するためのスーパーユーザー権限が必要なので、、Ask ubuntu: problem with docker

After installing Docker you are prompted to add your user to the docker group. Simply run the command shown:

sudo usermod -aG docker $USER
You will need to close your session and log in again to have the change take effect.

にしたがって、sudo usermod -aG docker $USER を実行して、ログアウトして、ログインしました。すると、

$ docker version
Client:
 Version:      17.04.0-ce
 API version:  1.28
 Go version:   go1.7.5
 Git commit:   4845c56
 Built:        Mon Apr  3 18:07:42 2017
 OS/Arch:      linux/amd64

Server:
 Version:      17.04.0-ce
 API version:  1.28 (minimum version 1.12)
 Go version:   go1.7.5
 Git commit:   4845c56
 Built:        Mon Apr  3 18:07:42 2017
 OS/Arch:      linux/amd64
 Experimental: false

のように問題なく version コマンドを実行できました。

TensorFlowコンテナを生成・実行

CPU安定版のDocker イメージからコンテナを生成させて、実行しました。

$ docker run -it -p 8888:8888 tensorflow/tensorflow
Unable to find image 'tensorflow/tensorflow:latest' locally
latest: Pulling from tensorflow/tensorflow
   ;

    Copy/paste this URL into your browser when you connect for the first time,
    to login with a token:
        http://localhost:8888/?token=(毎回、生成されるトークン)

で、最後に表示された「http://localhost:8888/?token=(毎回、生成されるトークン)」にブラウザでアクセスしてみました。

すると、図1のようにJupyter notebook が使えるようになりました。

図1: Jupyter notebook の画面(「TensorFlowが動作するDockerの開発環境を構築する」 ^3からの引用)

ただ、1_hello_tensorflow.ipynb を開いてみると、

Notebook validation failed

An invalid notebook may not function properly. The validation error was:
Notebook validation failed: Additional properties are not allowed (u'metadata' was unexpected):
{
 "output_type": "stream", 
 "text": "result:  [ 3.  3.  3.  3.]\n", 
 "name": "stdout", 
 "metadata": {}
}

というダイアログボックスがポップアップしました。何なのだ?

ともあれ、File -> New Notebook (python 2) で、 サンプルスクリプト

import tensorflow as tf
hello = tf.constant('Hello, TensorFlow!')
sess = tf.Session()
print(sess.run(hello))
a = tf.constant(10)
b = tf.constant(32)
print(sess.run(a+b))

を実行すると、

Hello, TensorFlow!
42

と結果が返ってきました。

ファイル名を sample.ipynb として、 File -> Save and Checkpoint として、ブラウザのタブを閉じて、再び、sample.ipynb を開いてみました。

こんどは、妙なダイアログボックスはポップアップしませんでした。 他のファイル、2_getting_started.ipynb 、 3_mnist_from_scratch.ipynb でも妙なダイアログボックスはポップアップしませんでした。ただ、1_hello_tensorflow.ipynb を開いてみると、今度も妙なダイアログボックスが。

よくわかりませんが、1_hello_tensorflow.ipynb だけのことなので、次に進みます。

Docker コンテナの停止と再スタート

Dockerコンテナを実行したターミナルで、Ctrl+C で、プロセスを止めました。

ps -a コマンドで、コンテナIDを調べて、startコマンドで再スタートさせました。(再スタートのコマンド名は start 、まぎらわしい。。)

$ docker ps -a
CONTAINER ID        IMAGE                   COMMAND                  CREATED             STATUS                     PORTS               NAMES
6a5ed12e18e1        tensorflow/tensorflow   "/run_jupyter.sh -..."   12 minutes ago      Exited (0) 5 minutes ago                       hardcore_goldwasser
$ docker start -i 6a5ed12e18e1

    Copy/paste this URL into your browser when you connect for the first time,
    to login with a token:
        http://localhost:8888/?token=(毎回、生成されるトークン)

http://localhost:8888/?token=(毎回、生成されるトークン)」にアクセスしてみると、 sample.py が前に保存にしたとおりの内容で残っていました。

Dockerイメージ作成

このコンテナを再びCtrl+Cで止めて、新しいDocker イメージをtfplussampleという名前で作ってみました。

$ docker commit 6a5ed12e18e1 tfplussample
sha256:07bddf474593056dee6a4162e67b89fde1015841327af8ff8dee565bb8d21fac
$ docker images
REPOSITORY              TAG                 IMAGE ID            CREATED             SIZE
tfplussample            latest              07bddf474593        10 seconds ago      1.13GB
tensorflow/tensorflow   latest              04f0b1131389        12 days ago         1.13GB

このDocker イメージからコンテナが生成され、実行できることは、

$ docker run -it -p 8888:8888 tfplussample

で確認しました。ここで、前に作った sample.ipynb を sample.py としてホストマシンにダウンロードしました。

Docker イメージをビルド

次のようなDockerfile

FROM tfplussample
COPY ./sample.py /tmp/sample.py

を作成して、 Dockerイメージをビルドしてみました。一行目は、新イメージのベースとなるコンテナ名、二行は、ホストマシンから新イメージのコンテナへのファイルコピーを指定しています。

-tオプションで、イメージ名 tfplussample2 タグ名 tag1 としました。

$ docker build -t tfplussample2:tag1  .Sending build context to Docker daemon  4.096kB
Step 1/2 : FROM tfplussample
 ---> 07bddf474593
Step 2/2 : COPY ./sample.py /tmp/sample.py
 ---> 9de94c7d2502
Removing intermediate container 21067f8210cb
Successfully built 9de94c7d2502

Docker イメージを実行してみると、

$ docker run --rm -it tfplussample2:tag1 python /tmp/sample.py
Hello, TensorFlow!
42

のように、コンテナ内の/tmp/sample.py が実行されました。

まとめ

たしかに、インストールは簡単でした。TensorFlowに関係するファイルがDockerコンテナのなかにまとめられて、ホストマシンのほかのアプリから切り離されているようです。こうなると、他の機械学習関係のアプリやツールを別のコンテナに隔離することで、ライブラリバージョンの衝突などを回避できます。Pythonのバージョンの違いに悩まなくとも良くなるので、これは便利です。

それと、他人の作ったDockerイメージから、コンテナを簡単に自分のマシンに生成できるので、素早くアプリやツールに特化した実行環境を作れるようになります。これも便利です。一方で、Anaconda でも異なるpythonのバージョンを、別の環境に隔離できるのですが、環境を作るのは手作業なので時間がかかります。

ただ、Dockerの使い方を学ぶのに時間がかかりました。私の場合、半日。


参考

^1:Installing TensorFlow on Ubuntu : Installing with Anaconda

^2:Installing TensorFlow on Ubuntu : Installing with Docker

^3:TensorFlowが動作するDockerの開発環境を構築する

^4:Docker入門 – コンテナ型の仮想化技術の解説

^5:「さわって理解するDocker入門」オージス総研 大西 洋平

^6:@IT > いまさら聞けないDocker入門

^7:AMD Launches ‘Boltzmann Initiative’ to Dramatically Reduce Barriers to GPU Computing on AMD FirePro™ Graphics

^8:CUDAをRadeonで動かす(導入編)

計算科学からデータ集約型科学へのワークシフト

この半年、機械学習エンジニアとして仕事をしたいと思ったり ^1 ^2 、 データ分析の仕事のほうがまだ適性があるのではと言われて、 そこを目指そうと思ったりしてきました。

ただ、キャリアを変えるのはなかなか難しいです。 社内公募がないと聞いて落胆したり、 自分にはまだデータサイエンス分野で 仕事を得るためにアピールできるものがないと思い知らされたり。

しかし、チャンスもあるようです。 高性能計算(HPC)の分野では、 昔は、計算科学のためのシステムが大きな割合を占めていましたが、 今では、機械学習ディープラーニングのためのシステムが増えてきているからです。 しかも、計算科学のなかでも機械学習の手法が使われることが増えてきています。

そんなわけで、計算科学分野からデータ集約型科学分野へ ^3 ^4 華麗にキャリアチェンジというわけにはいきませんでしたが、 地味にワークシフト ^5 していきたいと思います。


参考

^1:機械学習エンジニアになるために学ぶべき5つのスキル(海外記事紹介)

^2:Coursera機械学習コースは、仕事を得るための準備としてどれほどのものか?

^3:“The Fourth Paradigm: Data-Intensive Scientific Discovery – Book Released”, eSciece@Microsoft .

^4:計算科学からデータ集約型科学へのシフトで、数理的手法が使いやすくなっている

^5:「ワーク・シフト ― 孤独と貧困から自由になる働き方の未来図」リンダ・グラットン (著), 池村 千秋 (翻訳)

テクノロジーを民主化するには、ソフトウェア開発の民主化から

グーグルなどの言う「機械学習民主化^1 ^2 が文字通りの意味ならば、彼らが目指しているのは、 多数の機械学習エンジニアが、多数の人々の利益のために、 という理想だと思います。 これに対して、現実では、 少数のエンジニアリングを理解しない人々が、少数の人々の利益のために、 ということが起こりがちです。 この理想と現実のギャップを解消することは可能なのでしょうか?

テクノロジー民主化するために

民主化といえば、 リンカーンのゲティスバーク演説 ^3

「人民による、人民のための、人民の統治」

のフレーズが有名です。これにならえば、テクノロジー民主化とは、

「エンジニアによる、エンジニアのための、エンジニアリング」

ではないでしょうか。

リンカーンのフレーズは、フランス革命アメリカ建国によってどのような問題が解決されたかを示しています。問題とは、統治のありかたが、貴族や専制君主によって、人民には不利益が生じるようなかたちで、決定されていたことです。 同様に、テクノロジー民主化が解決するであろう問題とは、 エンジニアリングのありかたが、 エンジニアリングを理解しない人々によって、 エンジニアリングから不利益が生じるようなかたちで、決定されていることです。

ソフトウェア・エンジニアリングを理解しない人々によるエンジニアリング

例えば、日本の家電メーカーには次のような問題があります。

日本経済新聞「日の丸家電、打倒アップルの条件 ソフト重視へ転換せよ」中島聡^14

魅力的なソフトウエアを作り出すための全体仕様(アーキテクチャー)を設計することは、机上だけでは決して不可能だ。シェフが実際の料理を作りながらレシピを作るのと同様に、設計を担当するエンジニア自らがプログラムを書き「作っては壊し」の過程を経てはじめてよいアーキテクチャーを作ることができる。

アップル・アマゾン・グーグルをはじめソフトで勝負をしている企業は、どこもそうした開発体制をとっている。...

一方、日本のメーカーでは自分自身がプログラムを書いたこともない幹部候補生が頭の中だけでソフトを設計し、プログラミング作業は子会社に丸投げしている。...

ここで問題なのは、プログラミングを理解しない人が、 ソフトウェアの設計をして、プログラミングのありかたを決めていることです。 こうして、生み出されるソフトウェアに競争力がないために ^4 、利益率が低くなり、エンジニアの待遇は悪くなっています ^5

そして似たような問題は、伝統的な計算科学分野にもあります。

この分野では、ソフトウェア開発のありかたを決めている人々は ハードウェアについては十分に理解していますが、ソフトウェア開発についての理解はそれほどではありません。 そのために、新しい分野で Fortranのような時代遅れの言語は使われなくなり、 言語も開発手法も新しくなっているのとは対象的に、 伝統的分野では、 未だにFortranで書かれた「秘伝のタレ」を、 フォートラン時代の手法で守っています。 その結果、前時代的な日本発の計算科学アプリケーションは 近代的スタイルで開発された 海外発のアプリケーションとの競争に敗れ、 今や、日本国内ですら、海外発の計算科学シミュレーションが 多く使われています。

ソフトウェア・エンジニアリングを理解する人々によるエンジニアリング

日本に比べて、 アメリカのソフトウェアが高い競争力を持っているのは、 ソフトウェア開発者を理解している人々がソフトウェア開発のありかたを決めているからです ^4

そこには、プログラミングを理解しない人が、 プログラミングのありかたを決めてしまうという愚行はありません。 また、フォートラン時代のプログラミングしか知らない人が、 古い開発言語や手法を若い人々に強要するという蛮行もないのです。

このようなソフトウェア開発の民主化によって、 機械学習民主化も実現されつつあります。

具体的に言うと、 昔は、機械学習のアプリケーションプログラムを書くときに、 CやC++でゴリゴリと書いていたのが、 まず、C++Pythonで包み込んだライブラリやソフトウェアフレームワークが普及して、 scikit-learn ^6 などで python スクリプトによって楽にアプリを開発できるようになりました。 そのうちに、TensorFlow ^7 , Chainer ^8 のようにニューラルネットワーク記述のための 領域特化言語が埋め込まれたフレームワークが出てきて、更に楽になりました。 そして、今では、クラウド機械学習 ^9 ^10 ^11 が提供されて、 アプリ開発はプラモデル並みの気楽さになりつつあります ^12 ^13

これに対して、日本の計算科学分野では、ソフトウェア開発が民主化されていないので、 FortranやCでゴリゴリと書くしかなく、 そのような前近代的なプログラミングスタイルには、 オブジェクト指向フレームワークや領域特化言語を使うことによる 素早さや楽しさはありません。

このように、ソフトウェア開発のありかたが、 フォートラン時代なのか近代的なのかによって、 生み出されるソフトウェアやテクノロジーの競争力はまるで違ってきます。

数理的手法を民主化する鍵は、ソフトウェア開発の民主化

以上のように見ていくと、アメリカで機械学習や科学シミュレーションといった数理的手法 が民主化されつつあるのは、ソフトウェア開発が民主化されていたからだと思います。 近代的なソフトウェア開発手法や、 ソフトウェア部品を利用するというプログラミングスタイルが広まっていたからこそ、 大勢の人々がテクノロジーのアプリケーション開発に参加することができ、 その利益が大勢の人々に分配されるのです。

対照的に、日本では、数理的手法に基づくテクノロジー分野において、 ソフトウェア開発が民主化されていないために、 ソフトウェアの生産性と競争力は低く、 その利益率も低いままです。

このように、経済的な利益からいえば、民主化したほうが良いのに、 日本のソフトウェア開発が民主化されないのは、なぜなのでしょうか?

私はそれは、前近代的な手法であっても、日本経済がそこそこ回っていて、 エンジニアの不満は高まってきてはいても、 爆発するレベルには到達していないからだと思います。 私も、米国企業が知識集約型のビジネスモデルで 高い利益率を達成しているを知り、 日本企業が労働集約型のビジネスモデル ^4 で低い利益率に甘んじているのを苦々しく思いながらも、 勤務先を変えてはいません。

しかし、国や企業が破綻する兆候が見えてくると、 そうも言ってられません。


参考

^1:Quara "Why is it important to democratize machine learning?"

^2:なぜ、機械学習の民主化は重要か?

^3:ゲティスバーク演説 - wiki

^4:gihyo.jp » Software is Beautiful » 第3回 なぜ日本のソフトウェアが世界で通用しないのか

^5:ITエンジニアの地位とは?国別、職種別の年収比較

^6:scikit-learn

^7:TensorFlow

^8:Chainer

^9:Amazon Machine Learning

^10:Machine Learning - Microsoft Azure

^11:Google Cloud Machine Learning at Scale | Google Cloud Platform

^12:Gigazine「Googleが自社で使っている「クラウド機械学習」を一般に開放、こんなスゴイことが簡単にできる」

^13:Cloud Vision APIの凄さを伝えるべくRasPi botとビデオを作った話

^14:日本経済新聞2014/01/15「日の丸家電、打倒アップルの条件 ソフト重視へ転換せよ」中島聡

なぜ、機械学習の民主化は重要か?

この質問に対して、 Googleのデープラーニング研究者(でKeras開発者)であるChollet氏は、 2つの理由を答えています^1

(Quara “Why is it important to democratize machine learning?"への回答の要約)

ひとつは、機械学習からなるべく大きな価値が生み出されるようにするためです。 そのためには、機械学習を研究したり、あるいは、使いこなすだけの意志と知性を もっている人であれば、誰でも、 機械学習の知識やツールにアクセスできるようにする必要があります。

もうひとつは、機械学習によってなるべく大勢の人々が豊かになり、 社会全体が安定するようにするためです。 ただ、近い将来には、これから生み出される仕事や利益は 機械学習サービスを開発している人々(や企業)に集中していきそうです。 ですから、そのような富と力の集中を緩和してバランスをとるために、 機械学習による価値の創造に大勢の人が参加する必要があるのです。

^1:Quara “Why is it important to democratize machine learning?”

機械学習・ディープラーニングのこれからの進展

松尾先生の「人工知能は人間を超えるか」^1を読んで、

  • (1)機械学習・デープラーニングの何がブレークスルーなのか?
  • (2)これから成長するのはどの分野か?

をまとめて、

  • (3)どんな仕事が求められるのか?

を考えてみました。

(1)機械学習によるブレークスルー

これまでの人工知能ブームでは、2つの課題を解決できなかった。

  • 第1次ブーム : 推論、探索

    • 課題1: 迷路などの簡単な問題は解けても、チェス、将棋などでは組み合わせが莫大すぎて、探索しつくすことができないので、解けない。
  • 1回目の冬の時代

    • 現実の問題は、計算機に解かせるには複雑すぎる。
  • 第2次ブーム : エキスパートシステムで計算機に「知識」を入れる。

    • 課題2: 「知識」を書きだそうとすると、どこまで書いても書ききれない。
  • 2回目の冬の時代

    • フレーム問題 : 計算機がタスクを実行しようとすると、計算機は適切な「知識」の範囲を選び出すことができない。「知識」の範囲が狭すぎて失敗するか、あるいは、範囲が広すぎて計算時間が足りなくなる。
    • シンボルグラウンディング問題 : 計算機は「モノ」を抽象化した「記号」は扱うことができる。しかし、「モノ」と「記号」を結びつけることができない。それは「意味」が分かっていないから。

課題1の解決 -- チェス世界チャンピオンとプロ棋士に計算機が勝利

  • 機械学習

    • 論理的推論ではなく統計的推定 : 過去の膨大な棋譜という「ビッグデータ」の活用
    • 良い特徴量の発見 : 将棋の盤面を評価するときには、「2つの駒の関係」だけでなく、「3つの駒の関係」を使う。
  • 弱点

    • 良い特徴量は計算機でなく人間が見つけねばならない。

課題2を解決する目処がつき、機械学習の弱点は克服されつつある

  • 「現実からどの特徴を取り出すか」を人間でなく計算機にさせることができれば、これまでの難問はすべて解決できる。
  • ディープラーニングというブレークスルー : 特徴表現学習
    • 計算機がデータから着目すべき特徴を見つける --> 機械学習の弱点は克服される
    • 計算機が特徴を見つけ出して、その特徴で抽象化されている「モノ」との対応関係を取り出すことができれば、その対応関係が「モノ」の「意味」であり、現実の「モノ」を抽象化された「記号」である特徴と結びつけることができる。 --> シンボルグラウンディング問題の解決
    • 計算機はデータから特徴を取り出すことができるのだから、その特徴がタスクをこなすために必要な範囲の情報となる。 --> フレーム問題の解決

次の課題を解けるか、それとも、3回目の冬の時代か?

  • 課題3 : マルチモーダルな抽象化、時系列データからの文脈抽出
    • 画像・音声・圧力データを連携させることで、計算機に感情を認識させられるか?
    • 生物は視覚・聴覚・触覚を連携させて生きている。
    • 動画をばらばらの画像としてではなく、文脈を持つ時系列として認識させることができるか?
  • 課題4 : 行動と結果の抽象化
    • 機械自身の行為とその結果を、あわせて抽象化できるか?
  • 課題5 : 外界との相互作用の抽象化
  • 課題6 : 言語理解・自動翻訳
  • 課題7 : 知識獲得

(2)成長分野

これまで

  • 課題1の解決
    • チェス、将棋、碁

現在の注目分野

  • 課題2の解決 : データから良い特徴量を自動的に抽出

これからの成長分野

  • 課題3の解決 : マルチモーダルな抽象化
    • 環境認識、行動予測、感情理解
    • 「ペッパー」のようなロボットに接客をさせる。
    • 街中の画像、音声センターからのデータを連携させて、防犯・防災に役立てる。
  • 課題4の解決 : 行動と結果の抽象化
    • 自律的な行動計画
      • 自動運転
      • 物流でお客さんに渡すところまで
      • 農業の自動化

(3)これから求められる仕事

  • 課題3の解決 : 種類の異なるセンサーからのデータ収集と予測モデルの連携
    • IoT組み込みデバイスからのデータ収集と解析
    • 収集したデータによる機械学習、学習させてモデルによる予測、デバイスへのフィードバック
    • データ収集、解析、予測をクラウドで統合

???


参考

^1:「人工知能は人間を超えるか (角川EPUB選書)」松尾 豊 (著)

データ分析入門としてのKaggleコンペ「タイタニック乗客の生存予測」

これまで、Kaggleコンペティション ^1 ,^13 ,^14 は初心者には関係のない場所だと思っていましたが、 そうではありませんでした。 もちろん、賞金付きのコンペでは専門家がデータ解析で競い合っているのですが、 その他の賞金なしのコンペのなかには初心者が楽しめるものがあるのです。 特に、"Titanic: Machine Learning from Disaster"^2というコンペは入門レベルであり、 予備知識としてpython機械学習の基本を理解していれば、 kaggleコンペのプロセスをひととおり体験できます (ただ、賞金獲得だけは体験できません)。

以下で、その体験の内容をかいつまんで紹介します。

"Titanic: Machine Learning from Disaster"とは

このコンペは、1912年4月15日の大惨事にちなんでいます。 タイタニック号は氷山に衝突して沈没し、 2224人の乗員乗客のうち1502人が亡くなりました。 彼らの生死を分けたのは何だったのでしょうか? 幸運でしょうか?それだけではありません。 実は、ある種の属性を持つ人々はそうでない人々よりも生き延びやすかったのです。 例えば、女性、子供、一等船室の人々は生存確率が高かったことが知られています。

なので、乗客の性別、年齢、船室等級が分かれば、 ある程度はその乗客の生死が予測できるのです。 そして、他の属性も考慮すれば、 その生存予測の正確さを更に向上させられるかもしれません。

コンペ参加者は、このように予測の正確さを向上させて、 他の参加者とその正確さを競います。

このコンペは学習用なので、この予測の仕方を様々なチュートリアル ^3 ,^4 ,^5 ,^6 ,^7 ,^8 が指南してくれます。 このなかで私はインタラクティブなチュートアル^8

A free interactive Machine Learning tutorial in Python

をやってみました。 インタラクティブの良いところは、ゲームでステージを次々にクリアしていくように、 チュートリアルを学んでいけるところです。 そのチュートリアルのwebサイトにアクセスすると、セクションごとに説明が現れて、 pythonスクリプトを書いて提出するように求められ、 スクリプトが間違っていればヒントが表示され、 正しければ次のセクションに進めます。 そして、このようにチュートリアルを進んでいくうちに、以下のデータ分析のプロセス

  1. データ加工
  2. モデリング、トレーニングデータによる学習
  3. テストデータによる検証
  4. 特徴エンジニアリング

を体験できます。

必要な予備知識と使用するライブラリ

チュートリアルをこなすためには、pythonについては基本的な構文を理解していて、 機械学習については何らかのモデルを訓練データから作った経験があれば、 問題ないと思います。

3つのPythonライブラリ

  • NumPy  数値計算 (インポートするときはnumpy と表記)
  • Pandas データ加工 (pandas
  • scikit-learn 機械学習 (sklearn) 

を使いますが、それらを使ったことがなくともチュートリアルの説明を読めば、 課題のpythonスクリプトを書くことができますので、 問題なく最後のセクションまで進めます。

また、課題のpythonスクリプトのなかで、3つのライブラリを

import pandas as pd
import numpy as np
from sklearn import tree

のようにインポートすることになりますが、 こうしたスクリプトはwebサイトのなかで実行されるので、 手元のPCにpythonやそのライブラリを用意する必要はありません。

データ加工

訓練データはコンペ主催者によって収集され、csvファイルとして提供されています。 チュートリアルでは、この訓練データを後でモデルの学習に使いますので、 ここではcsvファイルをpython に読み込ませて、 DataFrameオブジェクトを生成します。 DataFrameオブジェクトは表形式のデータ構造を持っていて、データ加工に使うことができます ^9 ,^10

train_url = "http://s3.amazonaws.com/assets.datacamp.com/course/Kaggle/train.csv"
train = pd.read_csv(train_url)

例えば、与えられた訓練データtrainのフィールド(列)"Embarked"には欠けているところがありますので、その欠損値を次のように穴埋めします。

train["Embarked"] = train["Embarked"].fillna("S")

また、trainのフィールド(列)"Embarked"には、はじめは文字型の値"S","C","Q"が入っていますので、それらを機械学習で扱える数値型の値に変換します。

train["Embarked"][train["Embarked"] == "S"] = 0
train["Embarked"][train["Embarked"] == "C"] = 1
train["Embarked"][train["Embarked"] == "Q"] = 2

モデリング、トレーニングデータによる学習

モデリングには様々なやりかたがあるのですが、ここでは決定木を使います。 決定木は、scikit-learnライブラリではDecisionTreeClassifierクラスとして用意されていますので、 そのインスタンスを作成してmy_tree_oneに代入します。

my_tree_one = tree.DecisionTreeClassifier()

決定木モデルを学習させるためには、モデルへの入力となる特徴量ベクトルと、モデルからの出力と照合できるターゲットデータが必要です。 そこで、まず、特徴量として乗客属性"Pclass","Sex","Age","Fare"を使うことにして、それらを訓練データtrainから取り出して、feature_oneに代入します。

features_one = train[ ["Pclass", "Sex", "Age", "Fare"] ].values

次に、ターゲットデータとなる乗客の生死を訓練データtrainから取り出して、targetに代入します。

target = train["Survived"].values

こうして、ターゲットと特徴量ベクトルが揃ったので、 それらを使ってモデルを学習させます。

my_tree_one = my_tree_one.fit( features_one, target)

これで、機械学習によりモデルmy_tree_oneが出来上がりました。

テストデータによる検証

テストデータも訓練データと同様に主催者によってcsvファイルとして用意されています。 しかし、このcsvファイルには乗客の生死のデータは入っておらず、乗客の属性データだけが入っています。 なので、チュートリアルでは検証プロセスのうち、テストデータの乗客の属性データを上で作成したモデルに入力して、乗客の生存予測を出力させるところまでを行います。

実際の検証プロセスであれば、テストデータには乗客の生死データも含まれていて、 これらの生死データとモデルの出力を比較します。 しかし、コンペティションではこの比較をコンペ主催者が行うので、 csvファイルには生死のデータが入っていないのです。

コードは省略しますが、まず、 テストデータのcvsファイルを読み込んでDataFrameオブジェクトtestへと変換して、 欠損値を穴埋めしておきます。 そして、テストデータtestから特徴量ベクトルを取り出します。

test_features = test[ ["Pclass","Sex", "Age", "Fare"] ].values

そのテストデータの特徴量に基づいて、乗客の生死を予測させます。

my_prediction = my_tree_one.predict(test_features)

この予測結果をkaggleに提出するには、csvファイルでなければなりませんので、 予測結果my_predictionを所定のフォーマットのcsvファイルに変換します。

PassengerId =np.array(test["PassengerId"]).astype(int)
my_solution = pd.DataFrame(my_prediction, PassengerId, columns = ["Survived"])
my_solution.to_csv("my_solution_one.csv", index_label = ["PassengerId"])

この生存予測ファイルmy_solution_one.csvチュートリアルのwebサイトからダウンロードできますので、 それをkaggleに提出すると、 実際の乗客の生死データを比較して順位をつけてくれます。

私がやってみたところ、 順位は5,838チームのうちで5,692番目で、スコア(正確さ)は 0.569 でした。 順位が底辺に近いのは、何の工夫もしていないからです。 そこで、 次は特徴エンジニアリングを行います。

特徴エンジニアリング

これまでは、乗客の生死を左右するの属性は、 客室の等級"Pclass",性別"Sex",年齢"Age",運賃"Fare"だけであると 考えてきました。 しかし、他にも重要な属性があるかもしれません。 例えば、一緒に乗船している家族の人数もまた生死を左右していたと考えられます ^11 。 というのは、家族で一緒に旅をしていた人は、救命ボートに乗る順番が回ってきたとしても、 家族全員が揃っていなければ、ボートで脱出せずにタイタニック号に留まっていたのではないかと想像できるからです。 この仮説が正しければ、 大家族であればあるほど救命ボート乗り場に集合するまでに時間がかかるので、 それだけ生存確率が下がるはずです。

この仮説にそって、乗船している家族の人数を訓練データに加えます。

train_two = train.copy()
train_two["family_size"] = train_two["SibSp"] + train_two["Parch"] + 1

こうして更新した訓練データを使って、新たに決定木モデルを学習させます。

features_three = train_two[ ["Pclass", "Sex", "Age", "Fare", "SibSp", "Parch", "family_size"] ].values

my_tree_three = tree.DecisionTreeClassifier()
my_tree_three = my_tree_three.fit( features_three, target)

さて、この新しいモデルmy_tree_threeでは、どのくらい順位が上がるのでしょうか?

このmy_tree_threeにテストデータを入力して、 出力をkaggleに提出してみました。 順位は5,838チームのうちで4,760番目、スコア(正確さ)は 0.756 と、 すこし良くなりました。 しかし、順位はまだまだ悪いです。 それで、上位に入っている人の記事^12を読みますと、 非常に感心させられます。

まとめ

以上で紹介したように、コンペ"Titanic: Machine Learning from Disaster"チュートリアル^8で、主要なデータ解析のプロセス、データ解析、モデリング、学習、検証、特徴エンジニアリング、をひととおり体験できます。 ちなみに、モデリングとして、このブログ記事では、決定木を使う場合だけを書きましたが、 その他に、決定木で過学習を抑制するためのテクニックや、ランダムフォレストを使う場合についても体験できます。

私はやってみて、機械学習アプリ開発だけでなく、 データ解析もけっこう面白いのではないかと思いました。 おすすめです。


参考

^1:Kaggle Competitions

^2:"Titanic: Machine Learning from Disaster"

^3:Getting Started with Excel: Kaggle's Titanic Competition

^4:Getting Started with Python: ...

^5:Getting Started With Python II: ...

^6:Getting Started With Random Forests: ...

^7:Getting Started with R: ...

^8:A free interactive Machine Learning tutorial in Python

^9:Qiita pandasでよく使う文法まとめ

^10:pandas 0.19.1 documentation » API Reference » pandas.DataFrame

^11:Large families not good for Survival - Kaggle

^12:Kaggleのtitanic問題で上位10%に入るまでのデータ解析と所感

^13:賞金稼ぎから仕事探しまで、世界のデータサイエンティストが「Kaggle」に集まる理由

^14:世界のデータサイエンティストが集う「Kaggle」とは?ビッグデータ分析を競い合え!

機械学習エンジニアになるために学ぶべき5つのスキル(海外記事紹介)

機械学習エンジニアにはどのようなスキルが求められるのでしょうか?

あれこれと調べてみたのですが、どうもわかりづらいです。 というのは、ブームが盛り上がるうちに スキル要件の範囲が広くなり、また、レベルが高くなって、 「そのような人材はユニコーン(現実には存在しない生き物)」 ということが言われるほどになっているからです。 そして、このように求められるスキルが増えるのに呼応して、 学ぶべきとされる事柄と読むべきとされる書籍のリストも非常に長くなりつつあります。 これでは、何から学ぶかを決めるのも一苦労です。

そこで、 スキル要件をもっとコンパクトに書き表している記事^1

5 Skills You Need to Become a Machine Learning Engineer | Udacity

を、機械学習を学ぶときの参考にするべく、以下で紹介します。 この記事の著者、Chakrabortyさんは コンピュータービジョンの研究で学位を取得して、 Udacity^2(米国のオンライン学習サイト)で、 人工知能機械学習のオンラインコースを作っているという専門家です。 そして、 機械学習エンジニアに求められるスキルを整理して、具体的なリストとしてまとめています。

機械学習に関わるプロジェクトとは?

この記事ではスキル要件について説明するために、次のような機械学習プログジェクトを想定しています。

Let’s say you’re working for a grocery chain, and the company wants to start issuing targeted coupons based on things like the past purchase history of customers, with a goal of generating coupons that shoppers will actually use. ... The Machine Learning approach would be to write an automated coupon generation system.

生鮮食料品チェーン店の販売支援プロジェクト

  • 目標)顧客の過去の購入履歴に基づいて、(レジで)クーポンを発行できるようにする。
  • 手段)機械学習アプリを開発して、購入履歴の分析とクーポンの発行を自動的に行なわせる。

But what does it take to write that system, and have it work? You have to understand the whole ecosystem—inventory, catalog, pricing, purchase orders, bill generation, Point of Sale software, CRM software, etc.

Ultimately, the process is less about understanding Machine Learning algorithms—or when and how to apply them—and more about understanding the systemic interrelationships, and writing working software that will successfully integrate and interface. ...

  • 必要な実務スキル)
    • チェーン店のビジネスに対する理解・洞察
      • 商品の在庫、カタログ、値付け、発注、レシート発行、POSシステム(レジ)での会計、顧客情報の管理など
    • 実用的なソフトウェアを開発

必要なスキル構成は担当パートによって異なる

上記のようなプロジェクトでは、メンバーは

というように、異なったタイプの仕事をこなすことになります。 そこで、担当する仕事ごとに、プロジェクトメンバに求められる基盤スキルの構成は、 次の表のように違ってきます。

データ解析 機械学習アルゴリズム 機械学習アプリ 情報システム
統計学 -
モデリング
機械学習アルゴリズム利用
計算機科学
ソフトウェア工学 -

表1 : 仕事のタイプに対して求められるスキルの構成。スキルの相対的な重みを、◎:上級,◯:中級, △:初級,-:入門者レベルのように示しています。(原文での表^3を日本語訳)

3種類の機械学習エンジニア

ちなみに、Chakrabortyさんが書いた表^3では、機械学習エンジニアとして3つのタイプ、core ML enginer、applied ML enginnerと、software engineer - MLが示されています。 しかし、それらのエンジニアの担当については詳しく書かれていなかったので、 私は、core ML enginer が機械学習アルゴリズムの研究開発を担当し、 applied ML enginner がアプリの試作を担当し、 software engineer - MLが情報システム全体へアプリを統合する担当である、 と解釈しています。

データ分析者と機械学習エンジニアの分業

すると、これら3種類の機械学習エンジニアとデータ分析者が 一緒のプロジェクトで仕事をするときには、 担当する仕事がデータの解析から情報システムへの統合へと変わっていくにつれて、 重点的に求められるスキルもまた統計学からソフトウェア工学へとシフトしていきます。

例えば、データ解析を担当するメンバは、 仕事として、顧客情報を統計的に分析してデータモデリングを行いますから、 スキルとしては、統計学モデリングの専門家であることを求められます。 そして、このメンバの仕事ではプログラミングはそれほど重要ではありませんから、 スキルとしてソフトウェア工学はそれほど求められてはいないわけです。 (ただ、データ収集のためのSQL文を書けるくらいのプログラミングスキルは必要でしょうから、要求レベルはゼロではないのでしょうが。) これに対して、機会学習アプリのプロトタイピングを担当するメンバは、 仕事として、機械学習のソフトウェア部品を使ってアプリの試作を繰り返すので、 スキルとしては、機械学習アルゴリズムの使用と計算機科学についての専門家であることを 求められます。 そして、このメンバの仕事では統計的分析はそれほどの重みはありませんので、 スキルとしては、データ分析者のように統計学の専門家であることを求められないのです。

このように、プロジェクトメンバが自分の専門に特化して、 それぞの強みと弱みを補いあうことで ^7 、 プロジェクトの生産性を上げることができるのだと思います。

基盤スキルの内訳

表1に掲げられた5つの基盤スキルの内訳を、Chakrabortyさんは以下のように説明しています。 (ただし、他のスキル要件についての記事 ^4,^5 を参考にして、私が追加したり書きなおした箇所があります。)

  1. 統計学
  2. データモデリングと評価
    • パターン、構造の発見(相関、クラスター、固有ベクトル(主成分解析)、...)
    • 予測(分類、回帰、異常検知などによる)
    • 精度、誤差の解析(log-loss for classification, 最小二乗法の誤差(sum-of-squared-errors for regression), ...)
    • 検証(標本データの分割(トレーニングデータ、テストデータ)、逐次(? = sequential cross-validation)/ ランダム化交差検証(? = randomized cross-validation)、...)
    • 誤差伝搬? (ニューラルネットワークでの逆伝搬計算)
  3. 機械学習アルゴリズム&ライブラリの利用
  4. 計算機科学
    • データ構造、アルゴリズム(検索、ソート、最適化問題(目的関数、制約条件の違いによるクラス分け(連続、離散))、動的計画法、...)
    • 計算量、計算複雑性(P vs NP, NP完全問題, big O-記法, ...)
    • ハードウェア アーキテクチャー(メモリ階層、キャッシュ、バンド幅、並列処理、マルチプロセス、マルチスレッド、ベクトル演算、...)
  5. ソフトウェア工学

まとめ

機械学習・データサイエンスの仕事に就くためのスキル要件について、ふたつの対照的な見解があるようです。

ひとつは、こうした分野で働くためには、あらゆるスキルを身につけて、プロジェクトで必要となるすべてのタイプの仕事をひとりでこなせるようなるべき、という見解です。 もうひとつは、上で紹介した記事のように、仕事のタイプに応じて、異なったスキルに専門化することが求められ、プロジェクトにおいては、メンバが互いに強みと弱みを補い合って分業する、という見解 ^1 ,^6 ,^7 です。

ただ、どちらが現実に近いのかは、まだ機械学習の仕事をしていないので分かりません。 しかし、私が機械学習について学ぼうとするとき、 何を優先して何を後回しにするかという指針になるのは、 後者の見解(Chakrabortyさんの記事)のほうです。


参考

^1:5 Skills You Need to Become a Machine Learning Engineer | Udacity

^2:Udacity - Free Online Classes & Nanodegrees(いわゆる、MOOCs(massive open online courses)のサイト。)

^3:Relative importance of core skills for different Machine Learning job roles

^4:From PhD to Data Scientist: 5 Tips for Making the Transition

^5:「未経験者はどうすればデータサイエンティストになれるか」

^6:データ分析のためのチームビルディング--情シスとマーケの重要スキルセット

^7:Tips for Beginner Machine Learning/Data Scientists Feeling Overwhelmed