スパースモデリング (1) 特徴量と冗長な辞書

# はじめに
コロナ社から発行された本「**スパースモデリング- 基礎から動的システムへの応用 -**」の内容に関連することがらやMATLABコードについて，著者（永原正章）がわかりやすく解説します．

<img src="https://qiita-image-store.s3.amazonaws.com/0/202074/0c2267dc-c99f-df02-548f-f01a5c26027c.jpeg" width=25%>
[出版社ページ](http://www.coronasha.co.jp/np/isbn/9784339032222/)
[Amazonページ](https://www.amazon.co.jp/gp/product/4339032220/)

# スパースモデリングとは
最近，[ディープラーニング](https://ja.wikipedia.org/wiki/%E3%83%87%E3%82%A3%E3%83%BC%E3%83%97%E3%83%A9%E3%83%BC%E3%83%8B%E3%83%B3%E3%82%B0)がとても注目されています．データが大量にある場合（[ビッグデータ](https://ja.wikipedia.org/wiki/%E3%83%93%E3%83%83%E3%82%B0%E3%83%87%E3%83%BC%E3%82%BF)），自動的に特徴量が抽出されるというのが，ディープラーニングの最も大きな利点でしょう．

しかし，それほど大量にデータが無い場合（スモールデータまたはミドルデータの場合）はどうすれば良いのでしょうか？本書で詳しく述べていますが，データが少ない場合，ディープラーニングのように学習パラメータが多いと，[過学習（または過剰適合）](https://ja.wikipedia.org/wiki/%E9%81%8E%E5%89%B0%E9%81%A9%E5%90%88)が起き，学習がうまくいきません．

過学習を避けるためには，データの生成メカニズムを調べて，その性質を学習に組み込む必要があります．例えば，ある物体に電気を流して電圧と電流の関係を調べたいとしましょう．電圧と電流のデータが10組取れたとします．
<img src="https://qiita-image-store.s3.amazonaws.com/0/202074/2df7e62e-1e96-8ba4-11f8-3d8fc4015125.png" width=50%>
抵抗値は10Ωですが，少しノイズが乗っています．

これを何も考えずに学習（カーブフィッティング）してしまうと，９次補間多項式が出てきてしまいます．
<img src="https://qiita-image-store.s3.amazonaws.com/0/202074/96cd005a-77df-e813-3cec-82dc106df7fe.png" width=50%>

しかし，我々は[オームの法則](https://ja.wikipedia.org/wiki/%E3%82%AA%E3%83%BC%E3%83%A0%E3%81%AE%E6%B3%95%E5%89%87)を知っています．データが電流と電圧の関係なら，はじめから１次式と仮定して，パラメータを傾きと切片の２つに限定して学習（[最小二乗法](https://ja.wikipedia.org/wiki/%E6%9C%80%E5%B0%8F%E4%BA%8C%E4%B9%97%E6%B3%95)というものを使います）すればうまくいきます．
<img src="https://qiita-image-store.s3.amazonaws.com/0/202074/a13ad2db-77bf-e873-d0a6-b46a7e75cd2f.png" width=50%>

さて，世の中にはデータの生成メカニズムがよくわからない場合のほうが多いと思います．メカニズムがわからないから，データ分析をしたいということがほとんどだと思います．生成のメカニズム（およびノイズの性質）について何も情報がなければ，できることはデータ数と同じだけのパラメータを用意してフィッティングするしかありません．しかし，それでは過学習が起きてしまいます．

そこで，[オッカムのカミソリ](https://ja.wikipedia.org/wiki/%E3%82%AA%E3%83%83%E3%82%AB%E3%83%A0%E3%81%AE%E5%89%83%E5%88%80)という考え方があります．

>同様のデータを説明する仮説が二つある場合、より単純な方の仮説を選択せよ．

というものです．「より単純な」というのは「よりパラメータが少ない」と解釈して良いでしょう．**スパースモデリングはこれを自動的に行います．**データから，自動的に重要なパラメータを選択してくれます．ですので，スパースモデリングでは，データ数に比べて大量の学習パラメータをあえて用意して，パラメータの自動抽出を行うことによって，単純で過学習を起こさないモデルを得ます．魔法のような方法ですね．

ディープラーニングとスパースモデリングの違いをまとめてみましょう．

- **ディープラーニングは自動的に<font color="red">特徴量</font>を抽出する**
- **スパースモデリングは自動的に<font color="red">学習パラメータ</font>を選択する**

注：特徴量は**基底**または**辞書**とも言います．特徴量の抽出と学習パラメータの選択を
同時に行う方法もあり，**スパース辞書学習** ([sparse dictionary learning](https://en.wikipedia.org/wiki/Sparse_dictionary_learning)) と呼ばれています．

上の抵抗値のシミュレーションを行うMATLABコードです．

```matlab:VI_curve.m
%%%% 電流と電圧の関係

%% 初期化
clear

%% データ生成
I = 1:10; % 電流
V = 10*I; % 電圧（抵抗値=10）

%% ノイズ
n = randn(1,length(I))*5; % 平均0, 標準偏差5のガウスノイズ
Vn = V + n; % 電圧データにノイズを付加

%% 補間多項式
A = vander(I); % ヴァンデルモンド行列
p = inv(A)*Vn'; % 補間多項式の係数

%% 最小二乗法
Al = A(:,end-1:end);
p2 = inv(Al'*Al)*Al'*Vn';


%% グラフ表示
II = I(1):0.01:I(end);
VV = polyval(p,II);
VV2 = polyval(p2,II);
figure;plot(II,VV); %補間多項式
hold on
stem(I,Vn);
figure;plot(II,VV2); %最小二乗法
hold on
stem(I,Vn);
```

#ディープラーニングとスパースモデリング
ディープラーニングとスパースモデリングの違いは

- **ディープラーニングは自動的に<font color="red">特徴量</font>を抽出する**
- **スパースモデリングは自動的に<font color="red">学習パラメータ</font>を選択する**

でした．これをもう少し詳しく解説しましょう．

ディープラーニングは大量のデータから特徴量を自動的に抽出します．スパースモデリングでは，それほど多くないデータから学習パラメータを自動的に選択します．より少ないデータから学習できるのなら，スパースモデリングのほうが良いのでは？と思うかもしれません．

スパースモデリングでは，**代わりに<font color="red">多数の特徴量（基底ベクトル）の候補</font>を準備する必要があります**．特徴量をあらかじめ決めておく必要のないディープラーニングとは正反対ですね．特徴量がたくさん準備できる場合，スパースモデリングは有利です．

また，ディープラーニングとスパースモデリングの間には，もう一つ，大きな違いがあります．スパースモデリングは<font color="red">**線形モデル**</font>（パラメータが線形に依存する）なのに対して，ディープラーニングは[活性化関数](https://ja.wikipedia.org/wiki/%E6%B4%BB%E6%80%A7%E5%8C%96%E9%96%A2%E6%95%B0)により<font color="red">**非線形**</font>となることです．この非線形関数は以下の形をしています．
<img src="https://qiita-image-store.s3.amazonaws.com/0/202074/7279bfd2-4a8e-d20e-9daf-73cacecef72e.png" width=50%>
明らかに，この非線形性がディープラーニングの不思議な学習能力の源です（そして，ディープラーニングの数理的解析を難しくしている原因でもあります）．

<details>
ディープラーニングの非線形関数は y=max(0,x) という関数で　**ReLU (Rectified Linear Unit) 関数**と呼ばれています．x=0で尖っているのがミソです（この性質のおかげで，ディープラーニングは層が深くなっても学習が進むようです）．なお，ReLU関数は非負値制約に対する**近接作用素**になっています．[非負値行列分解](https://en.wikipedia.org/wiki/Non-negative_matrix_factorization)とディープラーニングは何か関連があるのでしょうか？（よく知りません）
</details>

まとめましょう．

- **ディープラーニングでは<font color="red">大量のデータ</font>が必要**
- **スパースモデリングでは<font color="red">多数の特徴量（基底ベクトル）の候補</font>が必要**
- **スパースモデリングは<font color="red">線形</font>，ディープラーニングは<font color="red">非線形</font>**

#基底ベクトルと辞書
特徴量と基底ベクトルの話が出てきましたので，スパースモデリングで最も重要な概念である**<font color="red">冗長な辞書</font>**のお話をしましょう．冗長な辞書とは，多数の特徴量の候補からなる集合のことです．

まず，基底ベクトルから．

線形代数で習ったことを思い出してください．N次元空間にはN本の互いに独立なベクトルが必ず存在します．
例えば，3次元空間では
$$
 e_1 = (1,0,0), 
 e_2 = (0,1,0),
 e_3 = (0,0,1)
$$
という3本の独立なベクトルがとれます．3本はこれに限らず，例えば
$$
 f_1 = (1,1,0), f_2 = (1,0,1), f_3 = (0,1,1)
$$
も独立なベクトルです．

このように次元ど同じ数の独立なベクトルのセットを**<font color="red">基底</font>**と呼びます．すなわち，{$e_1$,$e_2$,$e_3$} や {$f_1$,$f_2$,$f_3$} は3次元空間 $R^3$ の基底となります．

さて，つぎのベクトルの集合を考えてみましょう．
$$
 {e_1,e_2,e_3,f_1,f_2,f_3}
$$
6本のベクトルからなるこの集合は$R^3$のベクトルを表現するのには冗長です．このようなベクトルの集合を**<font color="red">冗長な辞書</font>**と呼びます．

「冗長な辞書」とは，たいへんうまいネーミングだと思います．

英語は2000語あれば話せるといいます．ですので，2000語の辞書で十分です．しかし，2000語の辞書に掲載されている単語だけから文章を作るとなると，かなり長くなってしまうでしょう．いっぽう，100万語の辞書から単語を自由に使って良いとなると，表現はかなり簡潔になります．これが，まさに**<font color="red">冗長な辞書からのスパース表現</font>**なのです．

**<font color="red">スパースモデリングとは，冗長な辞書から適切な単語（ベクトル）を自動的に選んできて，短い文章を組み立てる</font>**，そのような仕組みだといえます．「自動的に選んでくる」のは，辞書が膨大になればなかなか大変ですが，それを即座に計算する方法が近年開発され，コンピュータの高速化とあいまって，情報分野のホットトピックとなっているのです．

書籍「**スパースモデリング- 基礎から動的システムへの応用 -**」には，その詳細が記述されています．ぜひ手にとって確認してみてください．

<img src="https://qiita-image-store.s3.amazonaws.com/0/202074/0c2267dc-c99f-df02-548f-f01a5c26027c.jpeg" width=25%>
[出版社ページ](http://www.coronasha.co.jp/np/isbn/9784339032222/)
[Amazonページ](https://www.amazon.co.jp/gp/product/4339032220/)


<a href="https://qiita.com/mnagahara/items/2da9328d2131bfb52f79">→**スパースモデリング (2) CVXの使い方** にすすむ</a>