川雲さんの分析ブログ

興味のあることの分かりにくい要約です。最近は機械学習、データ分析など。

「モデリングとしての機械学習」のアプローチ

1. 機械学習の二つのアプローチ

ベイズ推論を用いた機械学習の入門書として、須山さんの「ベイズ推論による機械学習入門」を読んでいます。 その中で、世間で言われている機械学習を大きく二つに分類されていました。

機械学習スタートアップシリーズ ベイズ推論による機械学習入門 (KS情報科学専門書)

機械学習スタートアップシリーズ ベイズ推論による機械学習入門 (KS情報科学専門書)

1) ツールとしての機械学習

汎用的なアルゴリズムに、様々なデータを与えてモデルを学習させる手法です。 アルゴリズムを使いまわせるので、データを取りあえず入れれば何かしらのモデルを簡単に構築することが出来ます。 一方で、高性能なモデルを手に入れるには、特徴量抽出に精を出すこと、ハイパーパラメータのチューニングをすることが必要です。 scikit-learnに含まれるサポートベクターマシン、ランダムフォレストや、Kaggleで猛威を振るっているXGBoostやLightGBMが含まれます。

2) モデリングとしての機械学習

データ毎に特化した統計モデルを作り上げる手法です。 問題毎に異なるモデルを作るため高性能なモデルが期待できる一方で、ある程度の数学知識や計算時間、メモリコストの問題があります。 時系列モデル、隠れマルコフモデル、線形動的システムや深層学習が代表格です。

因みに、著者のブログには4つと書かれていました。 よろしければどうぞ。

machine-learning.hatenablog.com

以前に「ツールとしての機械学習」のアプローチについては簡単にご紹介しました。 本日はその続きで、「モデリングとしての機械学習」のアプローチの一つであるベイズ推論のお話をしたいと思います。

rio-cloud.hatenablog.com

2. 頻度主義とベイズ主義

まずは、統計学の二つの考え方である頻度主義とベイズ主義についてお話します。 これはものの見方の違いであり、永遠の論争を続けています。 個人的には柔軟に使っていきたいところですが。 この二つは、確率分布のパラメータをどのように考えるかが違います。

頻度主義

パラメータは唯一絶対であり不動であると考えます。 我々は、確率分布から生成されたデータを用いて真のパラメータを推定するという見方です。 例えば、95%信頼区間は、信頼区間がその中に真のパラメータを含む確率が95%という解釈をします。 つまり、パラメータは不動であり信頼区間が動くということです。

ベイズ主義

パラメータも確率分布に従うと考えます。 つまり、データの従う確率分布とパラメータの従う確率分布の二つを考えて、データからパラメータの確率分布を推論していきます。 例えば、95%ベイズ信頼区間は、パラメータがその信頼区間の中にある確率が95%という解釈をします。

3. ベイズの定理

では、ベイズの基礎となる定理をご紹介します。 まず、同時確率の定義から、

 p(x, y) = p(x|y)p(y) = p(y|x)p(x)

これを変形して、

 p(x|y) = \dfrac{p(y|x)p(x)}{p(y)}

これがベイズの定理と呼ばれています。 実際には、xの代わりに\thetaを、yの代わりにDを入れて、以下のように扱われます。

 p(\theta|D) = \dfrac{p(D|\theta)p(\theta)}{p(D)}

ここで、\thetaはパラメータ、Dはデータのことです。 また、 p(\theta|D)は事後分布、p(D|\theta)は尤度関数、p(\theta)は事前分布と呼ばれています。 つまりこの定理は、パラメータの事前分布を、そのパラメータから尤度関数に従って生成されたデータでもって、データが得られたという情報を得た後の事後分布に更新することを意味しています。 このように、データでパラメータの分布を更新するのがベイズ推論です。

また、データが得られたときに新しいデータを生成することも出来ます。 これは予測分布と呼ばれます。新しいデータをxとすると、以下のように表されます。

 p(x |D) = \int p(x |\theta)p(\theta|D) d\theta

つまり、データを得られた後のパラメータの分布(事後分布)と尤度関数を用いて、新しいデータを生成しています。 このデータ生成プロセスもベイズ統計の魅力の一つだと思います。

以上のように、事前分布、尤度関数、事後分布、予測分布が一つの組として扱われます。

4. 確率分布

では、具体的な確率分布をご紹介します。 確率分布は多くの種類があり、一つの表にまとめるのが中々難しいのが実情です。 今回は、よく登場する分布を無理矢理二つの観点で纏めました。 一つ目は変数が離散か連続か、二つ目は変数の範囲です。 これを表にすると以下のようになります。

離散変数 連続変数
単次元 多次元 単次元 多次元
0 ≦ x ≦ 1 単試行 ベルヌーイ カテゴリ ベータ ディリクレ
多試行 二項 多項
0 ≦ x ポアソン ガンマ
-∞ ≦ x ≦ ∞ ガウス 多次元ガウス

また、この表には載りませんでしたがウィシャート分布、負の二項分布、スチューデントのt分布もよく使われます。

前の章で述べたように、ベイズ推論においては事前分布、尤度関数、事後分布の3個をそれぞれ適切に選ぶ必要があります。そして、その組み合わせから予測分布が導かれます。 ただし、このうち事前分布と事後分布に同じ確率分布を選ぶことも可能であり、そのような事前分布を共役事前分布と呼びます。 従って基本的には、共役事前分布、尤度関数、予測分布の3個の組を選べばよいのです。

5. ベイズ推論の一例

では、具体的な例を用いてベイズ推論を説明致します。 今回は、事前共役分布にベータ分布、尤度関数にベルヌーイ分布を選びます。 また、ここから計算すると予測分布はベルヌーイ分布となります。 ただし、尤度関数と予測分布が同じ確率分布になったのは偶然です。

まず、ベータ分布とベルヌーイ分布を表します。

 Beta(\mu|a, b) = C_B (a, b) \mu^{a-1} (1 - \mu)^{b - 1}

 Bern(x|\mu) = \mu^{x} (1 - \mu)^{1 - x}

ここで、xはデータ、\muはパラメータ、 a, bはハイパーパラメータ(パラメータの分布のパラメータ)と呼ばれます。

すると、ベイズの定理よりデータとパラメータの関係は以下のように表されます。

 p(\mu|X) = \dfrac{p(X|\mu)p(\mu)}{p(X)} = \dfrac{\sum_{n=1}^{N} p(x_n|\mu)p(\mu)}{\sum_{n=1}^{N} p(x_n)}

ただし、 X = {x_1, ... , x_N}です。 計算の簡単のために両辺の対数を取り、求めたいパラメータ \muに関係の無い項を定数項としてまとめると以下のように変形されます。


\ln p(\mu | X) \\
= \sum_{n=1}^{N} \ln p(x_n|\mu) + \ln p(\mu) + const.  \\
= \sum_{n=1}^{N} {x_n \ln \mu + (1-x_n) \ln (1-\mu) } + (a-1) \ln \mu + (b-1) \ln (1 - \mu) + const. \\
= (\sum_{n=1}^{N} x_n + a - 1) \ln \mu + (N - \sum_{n=1}^{N} x_n + b - 1) \ln (1-\mu) + const.

これをよく見ると、事後分布はベータ分布の対数をとったものと同じ形をしていることがわかります。 つまり、尤度関数びベルヌーイ分布に対して共役事前分布であるベータ分布を選択したために、事後分布も同じベータ分布になることが確かめられました。

この結果は、事前分布のパラメータ a, bが、データ Xを観測することで次のように更新されたと解釈できます。


\hat a = \sum_{n=1}^{N} x_n + a \\
\hat b = N - \sum_{n=1}^{N} x_n + b

つまり、適当に定めたハイパーパラメータをデータで更新することでパラメータの分布をデータにフィットさせていると言えます。 これがベイズ推論のモデリングの手法です。

次に、予測分布を計算してみましょう。予測分布の定義から以下のように計算できます。 ただし、ここではパラメータの事前分布を用いました。


p(x) \\
= \int p(x |\mu)p(\mu) d\mu \\
= \int Bern (x |\mu)Beta(\mu|a, b) d\mu \\
= C_B (a, b) \int  \mu^{a-1} (1 - \mu)^{b - 1} \mu^{x} (1 - \mu)^{1 - x} d\mu \\
= C_B (a, b) \int  \mu^{x + a -1} (1 - \mu)^{1 - x + b - 1} d\mu \\
= (省略) \\
= Bern(x|\dfrac{a}{a+b})

また、あるデータ Xが得られた後の予測データを求めるには、事前分布の代わりに事後分布を使います。上記の結果を事後分布に適用するには、事前分布のパラメータ a, bを先程求めた事後分布のパラメータに置き換えればよく、以下のように表されます。


p(x|D) = Bern(x|\dfrac{\hat a}{\hat a + \hat b})

今回は、ベータ分布とベルヌーイ分布を用いましたが、他の分布を用いても基本的な考え方は同じです。 以上のように、パラメータの事前分布のハイパーパラメータをデータで更新する、さらに新しいデータを生成することが出来るのがベイズ推論の魅力だと思います。

6. 最後に

今回は、ベイズ推論の基礎として最も簡単な事例をご紹介致しました。ですが、実際には解析的にパラメータの更新をすることが出来ないことも多く、変分推論やMCMC (Markov Chain Mpnte Carlo)を用いて近似計算することが多いそうです。最近はStan*1などの確率的プログラミング言語が登場しているので、これらを使用するとよいかもしれません。

以上です。

TalkingDataの上位入賞者の手法をおさらい

TalkingDataコンペ

先日、TalkingDataコンペが終了しました。
TrainとTest合わせて8GB程度の大きいデータセットを扱うコンペでした。
初参加のコンペで色々戸惑ったためにランクはダメダメでしたが、他の人のカーネルを見るのは面白かったです。

コンペが終了して上位入賞者のアイデアが公開されましたので、それをまとめようと思います。
初心者の私が読んで理解できる範囲でしかまとめておりませんので、見落としがあるかもしれません。
悪しからず。

2位 FeiYangさん

https://www.kaggle.com/c/talkingdata-adtracking-fraud-detection/discussion/56328

  • 初期段階では、データの5%を抜き出して使用した。
  • 特徴量は、他のカーネルで使用されているものとほぼ同じ。count, cumcount, time-delta, unique-countなど。サブサンプリングのおかげで、200個の特徴量を使用することが出来た。
  • モデルはLightGBMとNN。
  • 異なるモデルから出てきた結果を単純に重み付きで平均した。

3位 bestfittingさん

https://www.kaggle.com/c/talkingdata-adtracking-fraud-detection/discussion/56262

  • 23個の特徴量をLightGBMに入れて0.9817を達成(これだけでもすごい)。
  • 同じ特徴量をNNに入れると0.9820。
  • クリック差分が重要であると考えて、前後5個のクリックを考慮するRNNモデルを使うと0.9821。
  • 最後は全てのデータをRNNに入れて学習させた。

4位 KazAnovaさん

https://www.kaggle.com/c/talkingdata-adtracking-fraud-detection/discussion/56243

  • LightGBMやNNでモデリングをした。
  • チームメイトで別々の特徴量を用いたことで、アンサンブルしたときに上手くいった。

5位 pocketさん

https://www.kaggle.com/c/talkingdata-adtracking-fraud-detection/discussion/56319

  • Pseudo LabelingやData Augumentation等の他のコンペで有用であったテクニックは、今回は役に立たなかった。
  • 30個程度の特徴量を使用した。
  • 最後は各自のモデルを持ち寄りアンサンブルをして、最も良い結果を得た。

6位 CPMPさん

https://www.kaggle.com/c/talkingdata-adtracking-fraud-detection/discussion/56283

  • 使用したモデルはLightGBMのみ。
  • 時間配分は80%が特徴量抽出、10%が評価値作成、5%がハイパーパラメータのチューニング、5%がアンサンブル。
  • 使用したマシンは20コアXeon、メモリ64GBとスワップ64GB。
  • Overfitを避けるために、評価モデルを二つ用意し、さらにLBも使用した。
  • 使用した特徴量は50個弱。これ以上はメモリに載り切らなかった。
  • 特徴量を一つずつ削除しては評価値が下がるかを確認した。コンペのほとんどの時間は特徴量選出に用いた。
  • 時間は、中国の現地時間に変換した。
  • Matrix Factorizationで新しい特徴量を作り出した。使用したライブラリはKerasの中のlibfm。

9位 Darraghさん

https://www.kaggle.com/c/talkingdata-adtracking-fraud-detection/discussion/56279

  • モデルはLightGBM (public score 0.9821)とNeural Network (public score 0.9816)の二つ。
  • 時間に関する特徴量に注目した。

11位 tkm2261さん

https://www.kaggle.com/c/talkingdata-adtracking-fraud-detection/discussion/56250

  • 特徴量抽出ではBiqQueryを利用した。20分しかかからないので非常に速く処理できる。(ソースコードの共有あり)
  • GCPでメモリ100GB、16コアのマシンを用意した。
  • 訓練データはday9より前、評価データはday9、テストデータがday10。
  • モデルはLightGBM。

その他

このコンペの締切直前に、上位入賞可能なカーネルが公開されたことが議論を呼んでいます。
問題点は以下の二つかと。

  • それをコピーするだけで上位入賞が出来てしまう。
  • カーネルの内容が、他の人のsubmissionファイルを重み付き平均しただけ。

なんかなーという感じです。

最後に

このコンペではLightGBMがメインで使われていますね。
KaggleではXGBoostが人気だと聞いたのですが、両者の使われ方の違いがあるのかもしれません。

また、今回は上位入賞者に日本人が多いですね。
確か1位の方も日本人だったはずです。
DeNAの影響で(私のように)Kaggleに熱を入れる人が増えたのでしょうか?

dena.ai

以上です。

データ分析の勉強のための自分用読書録

読書遍歴

データ分析を勉強し始めてからまだ1年も経っていませんが、取りあえず集めた書籍を羅列しようと思います。
名だたるデータサイエンティストの方々のブログの方が参考になるでしょうが。

機械学習

Pythonではじめる機械学習 ―scikit-learnで学ぶ特徴量エンジニアリングと機械学習の基礎

Pythonではじめる機械学習 ―scikit-learnで学ぶ特徴量エンジニアリングと機械学習の基礎

機械学習の代名詞とも言える程有名なPythonライブラリであるscikit-learnの使い方を学べる書籍です。
研究対象とするのではない人にとっては使えることが一番の課題だと思いますので、これをまず読んで使い始めるとよいと思います。 また、他のライブラリもscikit-learnのAPIを真似ていることも多いので、これを基礎とするのが宜しいかと。

はじめてのパターン認識

はじめてのパターン認識

先述のscikit-learn本と違い、こちらは数式が出てきます。 各アルゴリズムがどのような数式で動いているのかを知ることが出来、理解の助けとなります。

また、最近のはやりの勾配ブースティングは勉強しておいて損はないかと思います。
Kaggleでも、とりあえずデータを突っ込んでおけという風潮もあるそうです(要出典)。
有名なのはGXBoostとLightGBMです。

XGBoost Documents

Welcome to LightGBM’s documentation! — LightGBM documentation

深層学習

流行りのDeep Learningです。
この書籍では、特に画像分野で広く使われているConvolutional Neural Networkをゼロからスクラッチで書くことに挑戦します。
フルスクラッチで書くことで原理が分かりますので、まずはここからだと思います。 なお、最近はResNetやLSTM、GAN、VAE、Wave netなど様々なネットワークがあるので、それらも勉強しないとなーと思っております。

深層学習 Deep Learning (監修:人工知能学会)

深層学習 Deep Learning (監修:人工知能学会)

深層学習の技術の概要を知ることが出来ます。
もちろん数式も出てくるので、読み応えは十分にあります。
特に、画像、音声、自然言語といった応用分野の紹介もあるので、深層学習を使う人にも価値ある情報が提供されると思います。

ベイズ統計

機械学習スタートアップシリーズ ベイズ推論による機械学習入門 (KS情報科学専門書)

機械学習スタートアップシリーズ ベイズ推論による機械学習入門 (KS情報科学専門書)

最近出版された本ですが、分かり易いと評判です。
確かに、ベイズ推論が何をしたいのかがすっと理解できました。
また、応用例やソースコードの紹介もあるので、深く理解するための入り口に最適だと思います。

パターン認識と機械学習 上

パターン認識と機械学習 上

名著と呼ばれている書籍です。
英語名からPRML (Pattern Recognition and Machine Learning)とも呼ばれています。
ベイズ推論による機械学習が書かれています。
読み応えがありすぎてまだまだ読み途中です。

なお、「完全にベイズ統計学ではない」「初歩的なことしか書かれていない」という批評がありますが、その真意はいつになったら理解できるのでしょうか。

こちらも評判の書籍です。
一般化線形モデル(Generalized Linear Model, GLM)について書かれています。

Stanという確率モデル用のプログラムを使うための書籍です。
買ったはいいものの、全く読めていません。

異常検知と変化検知 (機械学習プロフェッショナルシリーズ)

異常検知と変化検知 (機械学習プロフェッショナルシリーズ)

教師無し学習の応用例の一つである異常検知について書かれた書籍です。
これは既に産業応用が盛んに進んでいるので興味があります。

こちらもただ興味があったために買いました。
必須の書籍ではないと思います。

データ分析

データ分析において作業時間の8割を占めると言われる前処理の方法について書かれた本です。
著者の経験に基づいてまとめられているそうなので、実務的な内容が多くすぐに使えるテクニックが満載です。

欠測データの統計科学――医学と社会科学への応用 (調査観察データ解析の実際 第1巻)

欠測データの統計科学――医学と社会科学への応用 (調査観察データ解析の実際 第1巻)

こちらも実務的な本です。
データには欠損値が含まれることも多いので、それをどう処理するかというお話です。

Webページ

書籍ではありませんが、私のよく参考にするページを上げます。

Kaggle

Kaggle: Your Home for Data Science

とにかくデータ分析に精通したければKaggleをやれというネットの甘言に惑わされて、Kaggleをやっています。
特に参考になるのはEDA (Exploratory Data Analysis)というデータの可視化をしたものです。
データを可視化すると色々見えてくることも多く、また実務では可視化で結果を伝えるので、これは参考になります。

scikit-learn

scikit-learn: machine learning in Python — scikit-learn 0.19.1 documentation

scikit-learnの公式ドキュメントです。
使い方、モデルのハイパーパラメータ、数式など、困ったらまずはここを見ています。

Keras

Keras Documentation

Deep Learningのライブラリの一つです。
別にTensorflowでもKerasでもPyTorchでもChainerでもいいのですが、「ユーザが多い」かつ「APIがわかりやすい」という理由で私はKerasを使っています。

最後に

とりあえず私の手元にある書籍を列挙しました。
基本的には評判の高いものだけを選んでいるつもりです。
内容はまだまだ理解できていない部分が多いので、まだまだ勉強ですね。
評判が高いけど読んでいない書籍はまだまだあるので、そちらにも早く手を出したいものです。

以上です。

参考:データサイエンティストもしくは機械学習エンジニアを目指すならお薦めの初級者向け6冊&中級者向け15冊(2017年春版) - 六本木で働くデータサイエンティストのブログ

特徴量抽出 - カテゴリ変数と数値変数の取り扱い方

1. 特徴量抽出とは

特徴量抽出(Feature Engineering)は機械学習の実応用において重要な工程です。
機械学習分野の大家であるAndrew Ng先生は次のように仰ったそうです(出典が見つからないので本当かは分かりません)。

"Coming up with feature is difficult, time-consuming, requires expert knowledge.
'Applied machine learning' is basically feature engineering."

実際に、Kaggleでも良い特徴量を見つけられるかどうかが順位を左右することがあるそうです。
しかしながら、特徴量抽出はアカデミックな研究対象ではないので、網羅的な解説が中々見つかりません。
そんな中で良い資料がありましたので、この内容を簡単にまとめます。
ただし、前半のカテゴリ値と数値の取り扱いのみです。

www.slideshare.net

2. 尺度水準

特徴量抽出の前に、まずは統計学の測定尺度についておさらいします。
測定尺度とは、データセットの中の数値を4種類に分類したものです。
それぞれの尺度で許される処理が異なるので注意が必要です。

尺度水準 - Wikipedia

  1. 名義尺度:数字をただの名前と考えたものです。例えばID、電話番号などです。カテゴリ値とも言われます。
  2. 順序尺度:順序を表す数字です。例えばレースの準位、地震の震度、成績表などが当てはまります。数字の大小に意味はありますが、差や比は意味を成しません。順序付きのカテゴリ値とも呼べるでしょう。
  3. 間隔尺度:間隔に意味のある数字です。「値の比」に意味はありませんが、「値の間隔の比」には意味があります。有名なのは℃単位の温度です。例えば「夏の最高気温30℃は春の最高気温15℃より2倍大きい」と言うことに意味はありませんが、「夏の一日の寒暖差(最高気温と最低気温の"間隔")6℃は、春の寒暖差12℃より2倍小さい」と言うことは可能です。
  4. 比例尺度:四則演算が全て使える数字です。物理学の数式に登場するほとんどの物理量はこれに属します。例えば、先程の温度も絶対温度K(ケルビン)に直せば比例尺度になります。年齢、金額、期間などもこれに属します。

機械学習においては数式上で四則演算を行うので、基本的に全ての値を比例尺度に変換する必要があります。
(ただし、モデルによってはカテゴリ値も扱えます。例えば決定木ベースのXGBoostやLightGBMではカテゴリ変数を扱うオプションがあります。)
従って、1.~3.の尺度を比例尺度に変換することが特徴量抽出の一つの目標となります。
なお、元の資料との整合の都合上、カテゴリ値と数値という分け方をします。

3. カテゴリ値の扱い

ここでは、カテゴリ値を扱います。
先程もお話した通りカテゴリ値はただの名前ですから、何かしらの処理が必要です。
ここではカテゴリを表す文字列を例として扱いますが、(ID等の)数字の場合でも同じ処理が可能です。

3.1. One-hot encoding

最初に挙げられる基本的な手法がOne-hot encodingです。
カテゴリ毎に列を作り、その内の一つだけを1、それ以外を0にします。
スパース行列ですのでメモリをあまり使いませんが、それでもカテゴリ数が大きくなると大変です。

国名 国名=JP 国名=US 国名=UK
JP 1 0 0
US 0 1 0
UK 0 0 1

3.2. Hash Encoding

上記のOne-hot encodingでは、カテゴリ数に応じて列数が増えることや、新しい値が出現する度に列数を増やす必要があることが問題点として挙げられます。
これを解決するために、ハッシュ関数を用いて固定の配列に変換するのがHash encodingです。
ハッシュ関数とは、ある値(キー)を別の値(ハッシュ)にマッピングする操作です。
このマッピングを予め設定しておくことで、一意な変換が可能です。
しかし、長さ(ハッシュ値の数)を固定するので、カテゴリ数の方が大きい場合は複数のカテゴリが同じハッシュ値マッピングされ得ます(これを衝突と呼びます)。
そこで、複数のハッシュ関数を用意して、最も精度の良いものを選ぶそうです。

もっとも、衝突は必ずしも悪いことではありません。
例えば、複数形(catとcats)や表現の違い(JapanとJP)は同じことを指しているので、同じハッシュ値になった方が良い表現だと言えます。
One-hotでは複数の列に割り振られてしまうものを一つに纏められるのがHash encodingの強みでもあります。

参考:PFI Seminar 2012/03/15 カーネルとハッシュの機械学習

  • hash('JP') = 2
  • hash('US') = 4
  • hash('UK') = 1
国名 hash_1 hash_2 hash_3 hash_4 hash_5
JP 0 1 0 0 0
US 0 0 0 1 0
UK 1 0 0 0 0

3.3. Label encoding

カテゴリを表す文字列を数字に置き換えます。

国名 hash_1
JP 1
US 2
UK 3

3.4. Count encoding

ラベルの出現回数で置き換えます。
名義尺度を比例尺度に置き換えているとも言えます。
ただし、元々は違う値だったものが同じ値に変換され得ます。

国名 国名_count
JP 4
US 2
UK 1
JP 4
JP 4
US 2
JP 4

3.5. Label-Count encoding

ラベルの出現回数の順序に置き換えます。
つまり、名義尺度を順序尺度に置き換えています。
下の例では、出現回数の少ない方からランキングしています。

国名 国名_count
JP 3
US 2
UK 1
JP 3
JP 3
US 2
JP 3

3.6. Target encoding

ターゲット変数の平均値で置き換えます。
これも、名義尺度を比例尺度に置き換えています。
二値、もしくは回帰問題の場合に使える手法です。

国名 ターゲット 国名_count
JP 1 0.75
US 0 0.5
UK 1 1.0
JP 0 0.75
JP 1 0.75
US 1 0.5
JP 1 0.75

3.7. Category Embedding

Neural Networkを使って密な表現を作ります。
詳しくは、arXivの論文をご参照下さい。

[1604.06737] Entity Embeddings of Categorical Variables

3.8. NaN encoding

欠損値のある場合の対処法です。
欠損値は、その名の通りデータの値がなくNaNとなっているものを指します。
欠損値を補完する方法もあるのですが、そもそも欠損していることに意味がある場合もあります。
例えば、室温を測る温度センサーを測るときに40℃を超えるとデータが欠損する場合などです。
これをMNAR(Missing Not At Random)と言います。
(参考:前処理大全

では欠損値をどのように扱うのかというと、One-hot encodingで欠損値用の列を用意すればいいわけです。

国名 国名=JP 国名=US 国名=NaN
JP 1 0 0
US 0 1 0
JP 1 0 0
UK 0 0 1
US 0 1 0

3.9. Polynomial encoding

カテゴリ変数同士の組み合わせの特徴量を新しく作ります。
この動機は、単純な線形回帰などではXORの演算が出来ない点にあります。

A B ターゲット A=1*B=1 A=1*B=0 A=0*B=1 A=0*B=0 ターゲット
1 1 1 1 0 0 0 1
1 0 0 0 1 0 0 0
0 1 0 0 0 1 0 0
0 0 1 0 0 0 1 1

3.10. Expansion encoding

一つの長い特徴量から複数の特徴量を分割します。
例えば、長い文章に含まれる単語を抜き出すことが挙げられます。

WIndows10, Python 3.6, Chrome

OS Coding Browser
Windows10 Python Chrome

3.11. Consolidation encoding

複数のカテゴリ値を同じ変数に変換します。
スペルミス、ほぼ同じ内容の表現などをまとめることが出来ます。

名前 地域 国名
Japan Asia Japan
JP Asia Japan
Japn Asia Japan
US North America USA
USA North America USA
America North America USA

4. 数値の扱い

数値の場合は、基本的にこのままアルゴリズムで学習させることが可能です。
従って、いかに述べる操作は必須ではないかもしれません。

4.1. Rounding

数値を丸め込みます。
よくあるのは小数点以下の切り捨てですが、例えば1の位を切り捨てるとカテゴリ変数のようにも扱えます。

年齢 年齢1 年齢2
22.25 22 2
29.10 29 2
25.52 25 2
19.80 19 1
15.41 15 1

4.2. Binning

連続値を、特定の区間毎に区切ります。

年齢 20歳以下 20~25歳 26歳以上
22.25 0 1 0
29.10 0 0 1
25.52 0 0 1
19.80 1 0 0
15.41 1 0 0

4.3. Scaling

値を特定の範囲内に変換します。
* Standard Scaling: 正規化のことです。平均0、分散1の範囲に値が収まります。
* MinMax Scaling: 値の範囲が[0, 1]に収まります。 * Log Scaling: (1を足して)対数をとる。

4.4. Imputation

欠損値を埋める方法です。
平均値・中央値で埋める、無視する、線形回帰モデルを使うなどの手法があります。

5. 他のデータの取り扱い方

この他にも、日付、位置情報、自然言語の特徴量抽出が紹介されています。
そちらは理解できていない部分がありますので、ここでは割愛致します。

6. 最後に

ここでは特徴量抽出の基本的な処理の仕方を述べました。
しかし、最初のNg先生の言葉にもあるように、特徴量抽出には各分野特有のドメイン知識が必要なことも多々あることと思います。
これは経験を積んで身に付けるしかないのかもしれません。

なお、他の特徴量抽出手法や、実際のコーディングなどは前処理大全という書籍に詳しく載っています。
よろしければどうぞ。

以上です。

「ツールボックスとしての機械学習」のアプローチ

1. 機械学習の二つのアプローチ

最近読んだベイズ推論による機械学習入門の中で、機械学習の代表的なアプローチが二つ紹介されていました。

機械学習スタートアップシリーズ ベイズ推論による機械学習入門 (KS情報科学専門書)

機械学習スタートアップシリーズ ベイズ推論による機械学習入門 (KS情報科学専門書)

1) ツールボックスとしての機械学習

既存のアルゴリズムにデータを与えて予測するものです。
汎用的なアルゴリズムを様々なデータに使いまわせるので、比較的簡単にモデルを構築することが出来ます。
一方で高性能なモデルを手に入れるには、特徴量抽出に精を出すことや、様々なアルゴリズムを試して最も性能の良いものを選択するなどの作業が必要です。
scikit-learnなどのライブラリに含まれるサポートベクターマシン、ブースティング、ランダムフォレストがその代表です。

2) モデリングとしての機械学習

データに関するモデルを事前に構築して、モデルの含むパラメータや構造をデータから学習するものです。
解きたい問題毎に異なるモデルを構築するので、ツールボックスを使うときよりも高性能なモデルが期待できるそうです。
一方でこのアプローチを使いこなすには、ある程度の数学の知識が必要であることや、計算時間やメモリコストの問題があるそうです。
時系列モデル、隠れマルコフモデル、線形動的システムや深層学習がこちらに含まれます。

因みに、著者である須山さんのブログには4つと書かれていました。
興味がある方はどうぞ。

machine-learning.hatenablog.com

この本は後者の「モデリングとしての機械学習」を解説した書籍ですが、今回は前者をまとめます。
後者はまた追々に機会があれば。

2. ツールボックスとしてのscikit-learnの使い方

機械学習の最も有名なツールの一つがscikit-learnです。
大抵の機械学習の書籍にはこのツールの使い方が書かれていると思います。
私も「Pythonで始める機械学習」という本で勉強しました。
大雑把な使い方は以前まとめましたが、あまりに説明が少ないと思いましたのでもう一度記します。

Pythonではじめる機械学習 ―scikit-learnで学ぶ特徴量エンジニアリングと機械学習の基礎

Pythonではじめる機械学習 ―scikit-learnで学ぶ特徴量エンジニアリングと機械学習の基礎

rio-cloud.hatenablog.com

2.1. scikit-learnのインポート

前回と同様、有名なデータセットであるirisデータをSupport Vector Machineで分類します。
他にも様々なデータセットがscikit-learnには含まれています。

5. Dataset loading utilities — scikit-learn 0.19.1 documentation

# Data set
from sklearn.datasets import load_iris

# Model
from sklearn.svm import SVC

# Utilities
from sklearn.pipeline import Pipeline
from sklearn.preprocessing import MinMaxScaler
from sklearn.model_selection import GridSearchCV, train_test_split

2.2. データ準備

では、データを読み込みます。
まずすべきことは、データを訓練とテスト用に分割することです。

これは、過学習を防ぐために必要なことです。
例えば、受験勉強の場合を考えてみましょう。
よく赤本などで大学の過去問を勉強しますが、その目的は他に応用できる普遍的な何かを学び取ること、つまり「汎化」することです。
もし過去問しか解けないのであれば、それは過去問に「過学習」していると言えます。
では、過学習しているか否かをどう判断するかというと、まだ見たことのない新しい問題を解けるか試せばよいのです。
この「新しい問題」のことをテストデータと呼びます。

# Data preparation
iris = load_iris()
X = iris.data
y = iris.target
X_train, X_test, y_train, y_test = train_test_split(X, y)

2.3. スケーリングとパイプライン

次に、モデルの準備をします。
モデルの準備にも色々ありますが、今回はスケーリングだけを扱います。

2.3.1. スケーリング

スケーリングとは、データのスケール(値の大きさ)を揃える作業です。
例えば、身長と体重から血圧を予測する回帰式を仮定しましょう(そんなことは出来ないでしょうけれど)。
一人を例にとると、 120 (mmHg) = w_1 * 65 (kg) + w_2 * 1.75 (m)のような回帰式になります。
この式を見ると、「単位」と「値の大きさ」が揃っていない所が気になります。
数式だけを考えた場合、単位はどうでもよいことです(元々物理学を学んでいた身からすると気持ち悪いことですが)。
一方で、値の大きさや範囲、すなわちスケールが異なることは回帰式にとって重大なマイナスポイントとなります。

値のスケールが異なることは、例えば正規化項をモデルに導入したときに問題を生じさせます。
正規化とは、モデルのバリアンスを下げるために目的関数に導入されるものです。
例えば、有名なL2ノルム正則化では、パラメータのL2ノルム(ベクトルの大きさ)を小さくする項を導入します。

 ||w||_2 = (w_{1}^2 + w_{2}^2)^{1/2}

ここで重要なことは、w_{1}w_{2}の値の大きさが揃っていないと ||w||_{2}が変わってしまうことです。
例えば先程の血圧の例ですと、仮にw_{1} = 1とした場合はw_{2} = 31.43となり、従って ||w||_2 = 31.44となります。
つまり、L2ノルムのほとんどを w_{2}が占めているので、L2ノルムを小さくするには w_{2}だけを小さくすればよいことになります。
従って、身長は係数が小さいために殆ど考慮されず体重のみで血圧を予測するようになるのです。

このように、スケールが異なると正しい正則化が困難になります。
ですから、スケーリングして各値の大きさと範囲を揃えるのです。

スケーリングにも幾つか種類があり、代表的なものを挙げます。
名前はscikit-learnに実装されているクラス名と対応しています。

  1. Standard Scaler: 標準正規分布に従うように値を変換します。具体的には、平均で引いた後に標準偏差で割ります。z値などとも呼ばれています。
  2. MinMax Scaler: 値を[0, 1]の範囲に収めます。計算式は(x - min) / (max - min)です。
  3. Normalizer: ベクトルのノルムを1にします。例えば、L2ノルム(ベクトルの長さ)を1にすると、全ての点が球面上に張り付きます。

どれを使うかは、モデルがどのような仮定を置いているかに依存すると思われます。
例えば、線形回帰ではデータが正規分布に従うと仮定しているので、Standard Scalerが良いでしょう。
今回扱うサポートベクターマシンにはMinMax Scalerが良いそうです。
その理由を私なりに解釈すると、サポートベクターマシンは各データ点間の距離を元にして識別関数をチューニングするので、全てのデータ点がある一定の範囲内に収まってくれると距離の値が大きくなりすぎず、計算に都合が良いのでしょう。

2.3.2. パイプライン

スケーリングとセットで使うのがパイプラインです。
パイプラインとは、一連の処理を一纏めにしたオブジェクトのことです。
今回は、スケーリングとモデルを一纏めにしたパイプラインを作成します。

何故パイプラインが必要なのでしょうか?
それは、「情報の漏洩」を防ぐためです。
「情報の漏洩」とは、テストデータの値を使って訓練データを加工することを指します。
今回ですと、テストデータを含んだデータの分布を使って訓練データをスケーリングすると、訓練データはテストデータを「知っている」ことになります。
これがどのような弊害をもたらすのかは、今回の参考資料である「Pythonで始める機械学習」に興味深い例題が掲載されているのでそちらをご参照ください。

# Pipeline
pipe = Pipeline([('scaler', MinMaxScaler()), ('clf', SVC())])

2.4. グリッドサーチと交差検証

そしていよいよモデルを学習していきます。
ここでは、グリッドサーチと交差検証という二つのテクニックを用います。

2.4.1. グリッドサーチ

グリッドサーチとは、ハイパーパラメータを調整するためのテクニックです。
そもそもモデルには、パラメータとハイパーパラメータという二つの自由に設定できる値があります。

  • パラメータ: データから学習する定数(例:線形回帰の係数)
  • ハイパーパラメータ: モデルに対して人が任意に与える定数(例:最近傍法の近傍数)

ハイパーパラメータは決め打ちで何か与えないといけないのですが、この値がまずいとモデルの精度が出ません。
そこで、このハイパーパラメータを調整するテクニックがグリッドサーチなのです。
具体的には、ハイパーパラメータを数パターン用意してそれぞれのモデルを作成し、最も性能の良いモデルを採用します。
当然ですが、パターンが多いとより詳細にハイパーパラメータを計算できますが、計算時間もかかります。
一般的なハイパーパラメータの調整方法があるので、それを参考にして効率よく計算したいものです。

2.4.2. 交差検証(Cross Validation)

そして、「モデルの性能」をより正確に見積もるためのテクニックが交差検証です。
交差検証では、訓練データを更に二分して、「既知のデータ(訓練データ)」と「未知のデータ(評価データ)」に分割します。
この分け方を何通りも行うのが交差検証です。
例えば訓練データを5分割した場合、4グループ(全データの80%)を訓練データにしてモデルを学習させ、残りの1グループ(20%)を評価データとして性能を評価します。
このプロセスを、評価データに選ばれる1グループを入れ替えながら5回行えば全てのデータを使って評価できます。
このように、限りあるデータ数を減らさずに効率よくかつ精密にモデルの評価を行う手法が交差検証です。

以下のプログラムでは、サポートベクターマシンのハイパーパラメータであるCとgammaの値をグリッドサーチで調べています。
さらに、GridSearchCVで一つのモデルを5分割の交差検証で評価しています。
つまり、ハイパーパラメータ二つを各7パターン、かつそれぞれ5分割交差検証ということで、7 * 7 * 5 = 245個のモデルを作成しています。
このように、計算時間との兼ね合いでハイパーパラメータの候補数、交差検証の回数を決めるとよいでしょう。

# Grid search
param_grid = {'clf__C': 10 ** np.arange(-3, 3, 1.),
              'clf__gamma': 10 ** np.arange(-3, 3, 1.)}
grid = GridSearchCV(pipe, param_grid, cv=5)

# Model fitting
grid.fit(X_train, y_train)

2.5. 予測

これで最適なモデルが出来ました。
grid.fit()関数は、ハイパーパラメータのグリッドサーチが終了すると最も性能の良かったハイパーパラメータを採用し、全ての訓練データを使ってモデルを学習してくれます。
つまり、現段階でgridは最高のモデルであるはずです。
このモデルを使って最初に分割して残しておいたテストデータを評価します。
テストデータは最後の最後に汎化性能を測るために使うのがセオリーだそうです。
今回はスコアが0.92と出ました。

# Predict
grid.score(X_test, y_test)

ちなみに、データ分析コンペのKaggleではテストデータを更に二つ(publicとprivate)に分割します。
コンペの開催期間中はpublicのテストデータで性能を評価し、この値を良くするようにモデルを改善します。
そして、コンペの終了後にprivateのテストデータでもう一度モデルの汎化性能を評価するのです。
これは、テストデータに対する識別性能を良くしようとするがために、テストデータに過学習するのを防ぐための措置です。

3. 最後に

これでscikit-learnの基本的な使い方は述べたつもりです。
しかし、教師無し学習などは触れていません。
中々評価しにくいですからね。

今後は、「ベイズ推論による機械学習入門」の本題である「モデリングとしての機械学習」もまとめたいと思います。

以上です。

Kaggle用のGoogle Cloud Platform事始め

始めに

Kaggleでは、通常のPCで扱うのが難しいほど大きいデータ(数GB程度)を扱うことがあります。
メモリコストのかかる処理をすると、普通にPCがフリーズします。
そのようなときにはサーバを使うといいよと伺ったので、個人用に立ち上げてみました。

サーバサービスは各種IT大手が展開しています。

人気なのはAWSなのだそうですが、私はGCPを選びました。
特に理由はありません。
どちらも最初の1年間の無料使用枠を付与してもらえるので、来年はAWSを使いましょうか(笑)

GCPの登録

サービスへの登録は簡単です。
恐らく誰もが持っているだろうGoogleアカウントでログインします。
以下のクラウドサービスの右上の「コンソール」をクリックすると、GCPのページに飛ぶことが出来ます。

cloud.google.com

中でも、今回用いるのは以下の3個です。

  • Storage: ファイルサーバです。Kaggleのデータを取りあえず保存しておきます。
  • Compute Engine: コンピュータのことです。LinuxなどのOSを動かすことが出来ます。
  • BigQuery: 大規模データセットSQLで処理することが出来ます。前処理で使います。

f:id:rio-cloud:20180429124745p:plain

GCP等のサーバサービスの良いところは、このCompute Engineでハイスペックなコンピュータを選べるところです。
メモリが30GBや60GBのコンピュータを手軽に用意できるのは、クラウドの魅力でしょう。

Storage

では、それぞれのサービスの使い方を述べます。
まずはStorageです。
ストレージの単位はバケットという、言わばプロジェクトのようなものです。
先程と同様に、バケットを世界中のどこかのサーバに設置します。
バケットを作成」ボタンを押すと、以下のような画面が表示されます。

  • 名前: 世界中で一意の名前を付けます。自分の名前でも入れないと、中々一意にはなれません。
  • デフォルトのストレージクラス: ストレージの種類を決めます。種類によって値段が変化します。今回は、ストレージ費用が安く、かつ取得コストが無料のRegional(場所はアメリカ)を選択します。

f:id:rio-cloud:20180429120922p:plain

あとは、Kaggleのcsvファイルをドラッグ&ドロップで放り込むだけです。
ただし、大きいデータは'csv.gz'に圧縮してからアップした方が速いです。
圧縮にgzを選ぶ理由は、後述のBigQueryではcsv.gzの圧縮のみが有効だからです。

Compute Engineの使い方

次にCompute Engineです。
Compute Engineでは、インスタンスというものを扱います。
インスタンスとは、言わば一つのコンピュータのことです。
インスタンスを作成」ボタンを押すと、以下のような画面が開きます。
ここでコンピュータのスペックやOSの種類を決めます。

  • 名前: 適当に付けます。
  • ゾーン: サーバの置いてあるゾーン(アメリカ、ヨーロッパなど)を決めます。どこでも構いませんが、ゾーンによって値段が違うので注意が必要です。今回はアメリカにします。
  • マシンタイプ: マシンのスペックを決めます。最低でもメモリは16GB以上欲しいところです。せっかくなので30GBを選択しました。
  • ブートディスク: OSを決めます。今回はUbuntuを選択しました。また、サイズは余裕をもって100GBとしました。サイズが小さいと巨大なデータセットが処理できませんので、注意が必要です。
  • アクセス範囲: いまいちよく分かりませんが、とりあえず全てのCloud APIが使えればよいでしょう。

以上のオプションでインスタンスを作成します。

f:id:rio-cloud:20180429120142p:plain

あとは、接続ボタンを押せばターミナルが開きます。
この後は、Gitのような便利ツール、vimemacsのようなエディタ、Anacondaのようなプログラミング環境を整えれば完成です。
これは普通のLinux OSと同じですので割愛します。

BigQuery

最後にBugQueryをご紹介します。
BigQueryは、アナリティクスデータウェアハウスと呼ばれるもので、ビッグデータ解析に優れています。
特に、データベース用の言語であるSQLを使って素早い処理が可能であることが特徴です。
実際に使ってみると、Python等での処理より圧倒的に速いです。

BigQueryでは、データセットと呼ばれる単位を扱います。
その下に、各種テーブルが保存されるという構造です。
言わば、データセットがフォルダ、テーブルがファイルのようなものですね。

新しいデータセットを以下のように作ります。

  • Dataset ID: 適当に名前を付けます。
  • Data location: よくわかりませんが、アメリカを選択しました。
  • Data expiration: 適当な期限でデータセットを削除するかを選択します。Kaggleのコンペは月単位で続くので、Neverでよいでしょう。しかしながら、BigQueryではデータセットの大きさに応じて課金されるので、コンペが終わったら削除した方が良さそうです。

f:id:rio-cloud:20180429122644p:plain

データセットが作られたら、その下にテーブルを作ります。

  • Location: どこからファイルをアップロードするかです。小さいファイルは直接アップ出来ますが、大きいファイルは先ほどのStorage経由でアップロードします。gs://の続きに、Storageのバケット以下のファイルへのパスを書き込めばよいです。ここで、.csv.gzファイルは解凍せずにそのままアップ出来ます。
  • File format: ここはcsvでよいかと。
  • Table name: 適当に名前を付けます。
  • Schema: テーブルの構造を指定できるそうです。難しくてよくわからないので、Automatically detectedにチェックを入れると良しなにしてくれるでしょう。
  • Header rows to skip: Kaggleのcsvファイルは1行目がヘッダ行になっていることが多いので、そこはデータではないよという意味を込めて1行飛ばします。

これでCreate Tableを押せば完了です。

f:id:rio-cloud:20180429123759p:plain

あとは、Compose Queryボタンを押してSQLでテーブルを処理します。

最後に

以上でサーバ環境が整いました。
後は、データ分析のフローを簡単に記します。

  1. ファイルをStorageにアップする
  2. 前処理を行う。特に大きいファイルはBigQueryで処理した方が早い。
  3. Compute EngineでPythonを動かして機械学習→提出ファイルの作成を行う。
  4. 作成したファイルをローカルにダウンロードしてから、KaggleのHP上で提出する。

もちろん、SQLで提出ファイルを作成したり、Pythonで前処理をすることも可能です。
PythonではなくRという方もいらっしゃるでしょう。
そこは適当にどうぞ。

以上です。

参考:Takami Satoさんの動画

www.youtube.com

CNNのテクニック

0. 始めに

CNNの各種テクニックをまとめた論文「Recent Advances in Convolutional Neural Networks」を、さらにまとめます。
この論文は、CNNの原理や基本的な構造(VGG, GoogLeNet, ResNetなど)を理解した上で、細かいテクニックを知りたい方が読むと収穫が多いと思います。
私自身が勉強途中であるので、話半分に読んで頂ければ幸いです。

ref) [1512.07108] Recent Advances in Convolutional Neural Networks

以下の図が、論文の構成を端的に示しています。 紹介されている技術は8項目あります。

f:id:rio-cloud:20180311114127p:plain

  1. Convolutional Layer: 畳み込み層
  2. Pooling Layer: プーリング層
  3. Activation Function: 活性化関数
  4. Loss Function: 損失関
  5. Regularization: 正則化項di
  6. Optimization: 最適化手法
  7. Fast Processing: 計算手法
  8. Applications: 応用

1. Convolutional Layer

まずは畳み込み層の種類からです。
CNNで一番大切な技術です。

a) 普通の畳み込み層
一般的な畳み込み層のことです。
小さな範囲の画像とフィルタとの畳み込み積分を実行します。

b) Tiled Convolution
複数の畳み込み層を用意することで、画像の回転やスケーリングに対して頑健な特徴を抽出します。

c) Dilated Convolution
dilateとは「広げる」の意味です。
フィルタの要素の間に0の値を入れることで、より広い範囲を見ることが出来ます。

d) Transposed Convolution (= deconvolution)
畳み込むと普通は画像が小さくなりますが、この手法では逆に画像を大きくします。
この意味で、deconvolution = 逆畳み込みという名前がついています。
具体的には、まずpaddingという手法を用いて元画像の周囲に0の画素を足した後に畳み込むと、画像サイズが大きくなります。

f:id:rio-cloud:20180311114637p:plain

e) Network in Network
Network in Networkとは、文字通りネットワークの中に小さいネットワークが含まれている形式の一般的な名前です。
今回は、CNNの畳み込み層にMulti Layer Perceptron (MLP)を用います。
この意味で、mlpconvとも呼ばれるそうです。

f:id:rio-cloud:20180311121345p:plain

f) Inception Module
複数の畳み込み層で計算してから、concatenate = 統合します。

f:id:rio-cloud:20180311121857p:plain

2. Pooling Layer

次に、プーリング層です。
プーリングの役割は、画像サイズを小さくして計算コストを下げることです。

a) L_p pooling
L_pノルムでプーリングを行います。
p = 1で平均プーリング、p=∞でマックスプーリングと等しくなります。

b) Mixed Pooling
上記の平均プーリングとマックスプーリングの値を任意の割合で混合します。

c) Stochastic Pooling
プーリングの範囲の中から、ランダムに一つの値を採用します。

d) Spectral Pooling
画像をフーリエ変換し、特定の周波数範囲のみを抜き出した後にもう一度逆フーリエ変換をすることで画像に戻します。
一般に、周波数範囲の抜き出しはローパスフィルタを用います。
つまり、画像の中から高周波のノイズ成分を抜き出して低周波の意味ある特徴を抜き出すと言えます。

e) Spatial Pyramid Pooling
従来のようにプーリングの窓サイズを固定するのではなく、プーリングされた後の画像のサイズを固定します。
こうすることで、異なる大きさの入力画像を扱えます。

f) Multi-scale Orderless Pooling
すいません、わかりませんでした。

3. Activation Function

次に、活性化関数です。
以前はtanhやsigmoid等も使われていましたが、今はほぼReLU一色かと思われます。

a) ReLU
Rectified Linear Units (ReLU)のことです。 入力が非負ならば素通り、負ならば0にします。
 a = max(z, 0)

b) Leaky ReLU
負の領域も、少しだけ値を通します。
ReLUでは値が0になるために初めから0をとるノードの重みが更新されないという問題があったので、
それを解決すべく負の領域も値をとるようにしました。
λの値は決め打ちです。
 a = max(z, 0) + \lambda min(z, 0)

c) Parametric ReLU
上記のLeaky ReLUのハイパーパラメータλも、普通のパラメータと同様に学習過程で更新します。

d) Randomized ReLU
上記のLeaky ReLUのハイパーパラメータλを、学習データ毎にランダムに選びます。
すなわち訓練段階では、学習データそれぞれに対して異なるλの値でネットワークが学習されます。
一方で、テストの過程ではその内の一つの値に固定します。

e) ELU
Exponential Liner Unitのことです。
目的はLeaky ReLUと同じで、負領域は指数関数を採用しています。
これにより負領域で出力aの値が飽和するので、よりノイズに対してロバストになるそうです。
 a = max(z, 0) + min( \lambda  (e^{z}-1), 0)

f:id:rio-cloud:20180311133814p:plain

f) Maxout
同じ位置における複数のチャネルの内、最も高い値をとった値を全てのチャネルで採用します。

g) Probout
活性しない(=出力の値に0をかける)かどうかを確率的に決めます。

4. Loss Function

ネットワークの最適化の指標となる損失関数です。
損失関数が小さくなるように各パラメータは更新されます。

a) Hinge Loss
SVMなどでも良く使われる損失関数です。
\delta(y, j)は、y=jのときは1、y!=jのときは-1を出力します。

 L_{hinge} = \frac{1}{N} \sum (max(0, 1-\delta(y, j) w^{T}x)^{p}

b) Softmax Loss
確率pをソフトマックス関数を用いて求めます。

 L_{softmax} = \frac{1}{N} \sum 1(y = j) \log p

c) Contrastive Loss
Siameseネットワークの損失関数としてよく使われるそうです。
データ間の類似度を測ります。

 L_{contrastive} = \frac{1}{2N} \sum (y) d + (1 - y) max(m - d, 0)

d) Triplet Loss
三点a, p, nの間の距離を考慮します。
下式において、dは二点間の距離です。

 L_{triplet} = \frac{1}{N} \sum max (d_{a, p} - d_{a, n}+ m, 0)

e) Kullback-Leibler Divergence
二つの確率分布間の距離を定義します。

 D_{KL}(p||q) = -H(p(x)) - E(\log q(x)) = \sum p(x) \log \frac{p(x)}{q(x)}

これを用いて、AE (Autoencoder), VAE (Variational Autoencoder)の損失関数は以下で表されます。

 L_{vae} = E(\log p(x | z)) - D_{KL}(q(z | x) || p(z))

KL-Divergenceは距離とは言うものの、上式の定義より非対称です。
従って、pとqをひっくり返したものとの平均をとることで対称となります。
これをJensen-Shannon Divergenceと呼びます。

 D_{JS}(p||q) = \frac{1}{2} D_{KL}(p(x) || \frac{p(x) + q(x)}{2}) + \frac{1}{2} D_{KL}(q(x) || \frac{p(x) + q(x)}{2})

GAN (Generative Adversarial Network)の損失関数は、このJS-Divergenceを用いて以下で表されます。

 min_{G} max_{D} L_{gan}(D, G) = E_{p(x)}(\log D(x)) - E_{q(z)}(\log (1 - D(G(z))) )

5. Regularization

過学習を避けるための技術です。

a)  l_{p} norm
Ridgeなどと同様に、損失関数に l_{p}ノルムの正則化項を加えます。

b) Dropout
ノードの出力をランダムに0にします。

c) DropConnect
ノードの入力(正確には結合の重み)をランダムに0にします。
つまり、 y = a(w * x)のwの項の幾つかをランダムに0にすることで、入力をDropoutします。

6. Optimization

CNNの最適化のための技術です。

a) Data Augumentation
鏡像反転、回転、横移動などを行い、「同じクラスに分類されるけれど少し異なる画像」を多く用意することでデータ数を稼ぐ手法です。

b) Weight Initialization
重みの初期値の決定は重要な要素だそうです(パラメータが多く存在するので)。
例えば、平均0のガウス分布などを用いて初期化します。

c) Stochastic Gradient Descent
誤差逆伝搬(Back Propagation)におけるパラメータ更新手法の一つです。
通常のGradient Descentは損失関数の期待値の微分をもちいてパラメータを更新しますが、
データセットの大きさが膨大になると全てのデータから損失関数の期待値を求めることは困難です。
従って、ランダムに(= Stochastic)選ばれた一部のサンプルで求められた損失関数の微分を用います。

d) Barch Normalization
バッチ(=学習で一度に与えられるデータセット)毎に画像を標準化、すなわち平均0, 分散1のデータに変換します。

e) Shortcut Connections
出力にあるトリガーをかけて、そのトリガー次第で値が変化するそうです。
LSTM (Long Short Term Memory)でも同じアイディアを採用しているそうです。
すいません、よく理解できませんでした。

7. Fast Processing

ネットワークの計算のお話です。

a) FFT
画像をフーリエ変換し、その空間でネットワークを最適化します。 これにより計算時間は短くなりますが、周波数空間の特徴量を覚えるために追加のメモリが必要になります。

b) Structured Transforms
低ランクの行列に分解します。
モデルのメモリサイズが小さくなります。

c) Low Precision
float型はメモリを食うので、二値表現(=1bit)を使うBinarized Neural Network (BNN)を用います。
入力活性化、重み、出力活性化の三カ所で二値表現が使われ得ます。

d) Weight Compression
パラメータの数を減らします。
例えば、Vector Quantization (VQ)は複数の重みを一つの値で代表させます。

e) Sparse Convolution
疎なフィルター、すなわち多くの項が0であるフィルターを用いて畳み込みます。

8. Applications

ここからは、CNNの応用例の紹介です。

a) Image Classification
言わずと知れた画像の種類の分類です。
ILSVRCでの大規模画像データセットの分類がよく紹介されます。

b) Object Detection
画像の中に写っている物体を検出する応用です。
近年は、YOLO (You Only Look Once)やSSD (Single Shot Multibox)が有名です。

c) Object Tracking
動画の中に移っている物体を追跡します。

d) Pose Estimation
画像の中に移っている人の姿勢を推定します。
Deep Poseというのが有名だそうです。

e) Text Detection and Recognition
画像に移っている文字を検出、テキストに変換します。

f) Visual Saliency Detection
画像に移っている物体の輪郭を検出します。

g) Action Recognition
画像、もしくは動画に移っている人間の行動をクラス分けします。

h) Scene Labeling
semantic class=抽象的な分類(例:道、水、海)を分類します。

i) Automatic Speech Recognition
音声を文字に変換する手法です。
入力が画像ではなく音声です。
ただし、フーリエ変換などで周波数軸を追加すると縦軸=周波数、横軸=時間の画像になるので、
画像と同様にCNNに入力することが出来ます。
縦軸の特徴量にはMel Frequency Cepstral Coefficients (MFCC)がよく使われます。
(これは周波数単位ではありませんが)

j) Statistical Parametric Speech Synthesis
上記とは逆に、文字を音声に変換する手法です。
WaveNetという生成モデルが有名だそうです。

k) Statistical Language Modeling
こちらは自然言語処理(Natural Language Processing, NLP)の分野に属します。
頻繁に用いられるのはLSTMです。
理由は、単語間の依存関係など、離れた所にあるデータを覚えておく必要があるからです。
しかし、LSTMに似せた工夫を凝らすことで、CNNをNLPに応用しています。

l) Text Classification
文書の内容毎にクラス分けするタスクです。

9. 終わりに

CNNに関わる技術を羅列しましたが、私自身が理解できていません。
理解するにはここで引用されている元論文まで遡る必要があると思いました。

以上です。