辞書学習とは
LASSOとは、とが与えられたとき、を最小化するようなを見つける問題でした。これは、に対して、観測値は説明変数のうち少ないものの組み合わせで表現できるはずだという仮定に基づいています。
今回紹介する辞書学習は、観測値が与えられたとき、これらの観測値は辞書と呼ばれる典型的なパターンが少数組み合わさることで表現できるはずだという仮定に基づいています。
辞書学習では、観測値をいくつか集めてきて行列を作り、ここから、となるように、典型的なパターンを意味する辞書の行列と、辞書の少数の組み合わせ方を示すスパースコードの行列に分解を行います。
このような行列の分解を行うアルゴリズムはいくつか知られており、スパースコードを正則化を使って求めるscikit learnに実装されている方法や、正則化を使って求めるMODアルゴリズムやK-SVDアルゴリズムなどがあります。ここでは、シンプルで強力なK-SVDアルゴリズムを使ってみましょう。
K-SVDアルゴリズム
K-SVDアルゴリズムは、scikit learnなどには実装がないため、筆者がコミッタをつとめるオープンソースのスパースモデリング用のライブラリであるspm-imageを使うことにします。
まずは、ランダムな100 x 200の行列を作って、それにK-SVDアルゴリズムを適用してみましょう。実装の都合上、行優先(Row-major)で、と扱われることに注意してください。つまり、は200次元の観測値を縦に100個並べたものと解釈します。
そして、以下のコードを実行することで、100 x 50のスパースコードの行列と50 x 200の辞書の行列が得られます。
import numpy as np from spmimage.decomposition import KSVD Y = np.random.rand(100, 100) ksvd = KSVD(n_components = 50, transform_n_nonzero_coefs = 5) X = ksvd.fit_transform(Y) D = ksvd.components_
得られたスパースコードの行列と辞書の行列を可視化した様子です。の各行を辞書といい、これが、観測値を構成するための少数のパターンを表しています。はほとんどの値が0の疎な行列となっており、の行目は、の行目の観測値を表現するための辞書の組み合わせ方を示しています。
しかし、残念ながら、今回の観測値はランダムな行列であるため有益な辞書は得られていないようです。これは、再構成誤差を計算してみると、その誤差が大きいことからわかります。実際、は各要素の値が0~1のランダムな値ですが、再構成誤差について、MAE(Mean Absolute Error、平均絶対誤差)を計算してみると、
np.mean(np.abs(Y - X.dot(D)))
0.12821788379791452
が得られ、これは無視できない大きさであることがわかります。
辞書学習では、観測値は辞書と呼ばれる典型的なパターンが少数組み合わさることで表現できるはずだという仮定に基づいていますが、そもそもこの仮定に当てはまっていないものに対しては意味のある結果を得ることができません。では、どういうときに使えばいいのでしょうか。その一つとして、画像データへの応用があります。