北野坂備忘録

主にインストールやプログラミングのメモを載せています。

「おらいりーちほー」のサーバルちゃん

 良く聞かれたのでメモ。
 O'Reillyでサーバルが表紙を飾っているのは『Javaパフォーマンスチューニング 第2版』です。

仮想環境ソフトAnacondaの歴史(2017/3/10バージョン)

 Anacondaは「先導的なオープンデータサイエンスのプラットホーム」らしいです。開発元によれば。

Download Anaconda Now! | Continuum

 対応しているのはPython, R, Scala
 
 で、このAnacondaに「我々の名高い」パッケージ&依存&環境マネージャであるcondaが含まれているとのこと。
 Anacondaは仮想環境構築のために使われていることが多いと思いますが、実際はこのcondaが仮想環境管理を担当してるんですね。

 ちらっと調べてみるとAnacondaにも反対派がいるようです。「他の仮想環境構築プロジェクトと合流せよ」みたいな。確かにPythonを使う上で仮想環境構築パッケージは種類が多い。
 ただ、生き残るのは

・インストールしやすい
・ライブラリが揃っている
・便利な(使いやすい)

パッケージなので、機械学習向けにこれらを(今のところ)兼ね備えているAnacondaがいきなりコケることはないと思います。

 Anacondaを長い間使ってくるとどのあたりで大きな変更があったのか、かつて自分が構築した仮想OS上のAnacondaがどのバージョンか(PythonのバージョンよりもNumPyのバージョンは何か等)知りたくなるので、チェンジログを拾い読んで興味のある部分だけピックアップしてみました。(実に備忘録的な使い方だ)


2012-07-17:0.8.0:
 リリース開始。

2012-08-21:0.9.0:
 MacOSXサポート追加。

2012-09-06:1.0.0:
 Windowsサポート追加。

2013-03-12:1.4.0:
 全てのプラットフォームでPython2.6, 2.7, 3.3をサポート。

2013-05-08: 1.5.0:
 重要なパッケージを全てアップデート:python, numpy, scipy, ipython, matplotlib, pandas, cython

2013-11-05: 1.8.0:
 Windowsインストールで管理者権限が不要になる。

2014-02-10: 1.9.0:
 NumPyのバージョンが1.8になる。

2015-07-02 2.3.0:
 Python が2.7.10に、 Pandasが 0.16.2にアップデート。

2015-11-02 2.4.0:
 Python 3.5サポート追加
 NumPyが1.10にアップデート。

2016-02-05 2.5.0:
 インテルの数値演算ライブラリMKLが追加。numpy, scipy, scikit-learn, numexprのバックエンドになる。

2016-03-29 4.0.0:
 バージョンがいきなり4.0.0にブッ飛ぶ。Anacondaに含まれるPythonのバージョンと混乱を引き起こさないようにするためとのこと。

2016-06-28 4.1.0:
 Jupyter Notebook Extensions追加。

2016-09-28 4.2.0:
 QTのメジャーバージョンが4から5に。
 IPythonが4.2から5.1にアップデート。

2017-01-31 4.3.0: 
 Anaconda3 のインストーラーはPython 3.6に基づく。
 Anaconda 4.3 はPython 2.7, 3.4, 3.5, 3.6をサポートするが、次回リリースからPython3.4は含まれなくなる。


 QTのメジャーバージョン変わってたのかー。
 チェンジログを丁寧に見返すなんて滅多にないんですが、こうやって眺めるとパッケージの方向性が見えて面白いですね。

ロジスティック関数とシグモイド関数

 ロジスティック関数はもともと生物の個体数の変化を表すモデルに用いられる関数でした。
 なので、「時間 t = 0 における初期個体数を加えた形」がもとのロジスティック関数です。
 ところが、機械学習で用いるロジスティック関数は初期個体数を加えません。
 なぜなら、もとの初期個体数を加えたバージョンのロジスティック関数は、Sの字にならないことがあるからです。さらに、(0,1)に圧縮できません。
 機械学習で欲しいのは、

・S字カーブをする
・(0,1)に圧縮できる

関数です。
 機械学習で用いられる

σ(x) = 1 / ( 1 + exp(-x) )

という形をしたロジスティック関数、いわゆる「狭義のシグモイド関数」はこれを満たしています。ただし、これはもとのロジスティック関数側から見るとかなり特殊なケースになります。
 「ではシグモイド関数と呼べばよいのか?」というと、ややこしいことに「シグモイド」は機械学習で用いられるロジスティック・シグモイド関数だけではなく、累積正規分布関数なども含まれます。これはシグモイドというのは「ギリシア語のシグマの語末形(アルファベットでいうとS)に似た形」ということを意味しているからです。
 もっと言うと、正確な「シグモイド関数」は、

σ(x) = 1 / ( 1 + exp(-ax) )

というa(ゲイン)が入った形で、このうちゲインが1のものを「標準シグモイド関数」と言います。

 ということで、機械学習系の人は

σ(x) = 1 / ( 1 + exp(-x) )

を「ロジスティック関数」と気軽に読んでいますが、ロジスティック関数の特殊な形であるロジスティック・シグモイド関数の、さらに特殊な(ゲインが1である)形であるこの関数を「ロジスティック関数」と呼ぶのはやめて、より厳密な「標準シグモイド関数」と呼びませんか、というのが提案です。
 でも現状だと「ロジスティック関数」にしておかないと検索にひっかからないのよね……。

『Python機械学習プログラミング』のKerasで引っかかる

 『Python機械学習プログラミング』をおすすめした人から、Kerasのところでつまづいたとのこと。

 エラー文を見せてもらうと、

from keras.utils import np_utils
Using TensorFlow backend.
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/home/***/.pyenv/versions/anaconda3-4.1.0/envs/anaconda3/lib/python3.5/site-packages/keras/__init__.py", line 2, in <module>
    from . import backend
  File "/home/***/.pyenv/versions/anaconda3-4.1.0/envs/anaconda3/lib/python3.5/site-packages/keras/backend/__init__.py", line 67, in <module>
    from .tensorflow_backend import *
  File "/home/***/.pyenv/versions/anaconda3-4.1.0/envs/anaconda3/lib/python3.5/site-packages/keras/backend/tensorflow_backend.py", line 1, in <module>
    import tensorflow as tf
ImportError: No module named 'tensorflow'

 ファッ!?
 なぜtensorflow?
 と思ったら、KerasのデフォルトのバックエンドがTensorFlowになってる〜!
 確かにこれはTheanoしか入れてなきゃ動かないわ。

studylog.hateblo.jp

 はーなるほど。KerasがTensorFlowに統合されつつあるのね。
 Kerasがいつかの段階でバックエンドにTheanoだけでなくTensorFlowを選べるようになっていて、しかもデフォルトがTensorFlowになっているので『Python機械学習プログラミング』のとおりにやってもコケると。
 TensorFlowを入れてもいいんですが今回はバックエンドの変更で済ませました。

バックエンド - Keras Documentation

 『Python機械学習プログラミング』は2016年7月発売の本なんですけどねぇ。時代はもうこんなに変わっているのか……。

プログラマから見たソフトマックス関数

 機械学習において、ソフトマックス関数はロジスティック回帰の一般化としてとして現れます。ロジスティック関数のあとで説明されるのが通例です。
 式はこちら。
ソフトマックス関数 - 機械学習の「朱鷺の杜Wiki」

 多クラス分類問題に用いられます。

 以前から、「なぜこの関数を一般化ロジスティック関数と呼ばずにソフトマックス関数と呼ぶのか?」と思っていました。
 
 理由は「高校数学の美しい物語」で分かりました。
mathtrain.jp

 こちらの「ソフトマックス関数の性質」の項で、

例えば,x=(10,2,1) とすると,y=(0.9995⋯,0.0003⋯,0.0001⋯) となります。マックス関数(一番大きい成分を 1 にして,それ以外のものは 0 にする関数をこう呼ぶことにする)をソフトにしたという感じです。

と解説されています。
 これで腑に落ちました。

 プログラミングをしている人ならMAX関数と言えばすぐに理解できると思います。このMAX関数をソフトにしたものがソフトマックス関数であり、

・MAX関数と違ってベクトルで返す。
・大きな成分が過大に(1に近く)評価され、小さな成分が過少に(0に近く)評価される。

関数だということが分かります。

 プログラマからすると、ソフトマックス関数はロジスティック関数から説明されるよりMAX関数から説明してもらったほうが分かりやすいですし、下手をするとソフトマックス関数の説明をしてもらってからその特別な場合としてロジスティック関数の説明をしてもらったほうが理解しやすいかもしれません。
 

目標値を{-1,1}にする理由

 問題によって、目標値{ t_n}を{0,1}ではなく{-1,1}にするときがあります。
 こうすることによって、{ t_n^2}が1になります。式中から{ t_n^2}を吹き飛ばすことができるわけです。
 微分を行う場合、計算が楽になるように係数に1/2を入れておくのと同じようなテクニックですね。

機械学習(カーネル法)におけるグラム行列

 数学的(線形代数学的)にはグラム行列とは正方行列Aが与えられたときに、その随伴行列A*とAを掛け合わせたA*A(この*は掛け算ではなく随伴行列記号)のことをAのグラム行列と言います。
 随伴行列とは複素数を成分にとる m×n 行列 A に対して、

1) 転置して
2) その成分の複素共軛(実部はそのままで虚部の符号を反転する)をとった

n×m 行列 A* のことです。
 ただし、グラム行列の場合はAが正方行列(n×n 行列)という制限がかかりますので、随伴行列もn×n 行列になります。


 これに対し、機械学習の分野でグラム行列とは単に

{ x_n , x_m }カーネル{ k(x_n , x_m) } を n,m 成分とする行列のこと

であり、「{ k(x_n , x_m) }を要素に持つグラム行列」と表現されることもあります。
 イメージ的にはカーネル関数を行列で表したもの」と思えばいいでしょう。
 具体的には「n個のデータに対する全相互カーネル値の一覧」です。
 こう言われると、

「ああ、いかにもカーネル法のいろんなところで出てきそうな行列だなあ」
「n(データ数)が増えたら計算が大変だろうなあ」

ということが一発で分かると思います。

 グラム行列を使うと何がうれしいかと言うと、元の空間の次元が高くても(無限次元でも)計算量があまり増えないということです。逆にデータ数が多いほど計算に時間がかかります。
 となると、今度は効率化として

・近似
・データ量を減らす

などが出てくるわけです。
 グラム行列計算の効率化についてはこれまた巨大な分野なので今回はここまで。