*注意)この「べじぱみゅの学習メモ」のカテゴリー記事は、ワタクシ自身がこれまでに勉強したいろいろな項目について、テキストにあんまり書いてない内容などを勝手に妄想したメモです。
ワタクシ自身の備忘録のために書いており「初学者にわかりやすく説明する」というものではございません。
導入なしに唐突に話が始まり、おそらく意味不明な文章かもしれません。
しかし、せっかく考えたことなので、記事の内容がもし誰か1人でもお役に立てれば幸いです。

まずは座学:うまく「判別」したい!

今回は実験データの解析(それこそ流行りの「機械学習」なんかも含めてですが)においてよく遭遇する(必要に駆られる)「データの次元圧縮」について考えます。すでにこのブログでも述べた主成分分析(PCA)はその代表ですが、今回はある意味PCAと双璧?をなす(両者は役割が違いますのでどっちが上とか下とかないですが)フィッシャー線形判別分析(Fisher Linear Discriminant Analysis: FLDA)を取り上げ、PCAと比べてみます。

PCAもFLDAも、ある目的のために元データの線形結合をつくりデータを圧縮する、という点で共通しています。PCAのときと同様、元データをdij(i=1~I, j=1~J)とします。J個の指標(我々理系人にはスペクトルの横軸:波長やエネルギーなどがイメージしやすいと思います)に関してI個の測定を行った、という状況です。各i番目のデータについて、このJ個の指標に関する線形結合
1
により「総合指標」をつくります。このベクトルuをどういう思想に基づいて決めるか、によってPCAやFLDAが得られます。

PCAとFLDAはぱっと見似ているのですが、データ解析のカテゴリーで言うと全く異なります。PCA「教師なし学習」FLDA「教師あり学習」です。FLDAでは「ラベルづけ」されたデータを対象にします。i個の元データに何らかの「ラベルづけ」がされていて、データに加えてその「ラベル」を存分に活かして次元圧縮をします。一方でPCAはラベルを無視し(そもそもラベルのないデータが対象)データ「だけ」を見て次元圧縮をします。文書だけ見てもピンとこないでしょうから後で具体例をやります。

PCAは以前述べたように「データの分散情報をなるべく残す」手法です。以前の記事ではスペクトルの解析によく用いられる「大きさ情報をなるべく残す」手法をメインに解説しましたが厳密にはそれはPCAではなく、ここでは「邪道PCA」(別に悪いことをしているわけではないのですが、名前だけ)と呼んで「本当のPCA」と区別します。PCAについての解説は以前の記事をご参照ください。

今回のメインはFLDAです。FLDAは前述のように「ラベルづけ」されたデータが対象です。データそれぞれに「所属カテゴリー」(機械学習では「クラス」と呼びます)を示す別の指標が紐づいています。例えばスペクトルデータなら、「OK品」「NG品」(2水準)とか、「材料A~E」(5水準)とかがイメージしやすいと思います。

FLDAでは「別々のクラスに所属するデータをなるべく引き離す」というポリシーで次元圧縮をします。具体的にはさっきの重みづけベクトルu
2
が最大になるように決めます。ここで分子の
3
各クラス(k=1~K。Nk個が所属するとする)における平均ベクトル(スペクトルの横軸に対応するJ列ベクトル)と全データの平均ベクトルの差に関する分散行列になっています。つまり「異なるクラス同士の分散具合」に対応する量で「クラス間分散行列」と呼びます。
そして一方の分母ですが
4
こう表せます。大カッコの中身は全データのうちクラスkに属するものと、そのクラスにおける平均ベクトルの差に関する分散になっています。それを全クラスに関して和をとったもので、つまり「クラス内における分散具合」に対応する量で「クラス内分散行列」と呼びます。回帰の問題などで「全変動」を「回帰変動」と「誤差変動」に分けるのと似ていますね。ていうか数式的には同じです。
というわけで先ほどの謎の式
2
の分母は「クラス間分散」、分子は「クラス内分散」に対応します。これを最大化するということは、「同じクラスに属するデータはなるべく近くにまとめ(分散を小さく)、異なるクラスに属するデータはなるべく引き離す(分散を大きく)」ということです。後の具体例でこれを実感していただきます。
数学的な証明は専門のテキストにお任せしますが、この「最大化」は
5
という「一般化固有値問題」に帰着されます。上の式でもしSwが単位行列なら「普通の固有値問題」で何も難しい問題ではないのですが、残念ながらそんなことはなく、これはちょっと複雑です。この件については最後に(軽く)触れるとして、ここではこの問題が「ちゃんと解ける」そして「クラス数-1個」の固有値および固有ベクトルを持つ、ということだけ言っておきます。後者については直感的になんとなく納得できます。FLDAはデータの線形結合によって「線形の分離境界」をつくる作業です。たとえばクラスが2種類なら、それを分離する線形の境界(面)は必然的に1個ですね。クラスが3種類なら線形の分離境界は2個です。

実例をやってみましょう!

さて、ここまで式を延々と述べてきましたが、式だけ見ていてもイマイチわかった気にならないので、具体例をやってみましょう。私がわざとわかりやすく作った「教師データ」(スペクトルデータ)を処理してみます。具体的には横軸(別に何の量でもいいのですがここではとりあえず「波長」としておきます)1001水準(0~1000)、5種類の材料のデータ2000個ずつ、計1万個のスペクトルとします。5種類の「純粋物質」として
10

このようなクラス1~5のスペクトルをベースに適当にノイズを混ぜて2000個に水増ししました。この5種類のスペクトルはいずれも、波長300/500/700/900に同じ強度のピークをもち、さらにぱっと見ではほぼわかりませんが200/400/600/800の強度がクラスごとに若干異なります(クラス2, 3, 4, 5ではそれぞれ200, 400, 600, 800の強度が若干他のものより弱い)。さらに、全クラス共通の変動として6個目に示した波長100のピークが、2000個の教師データごとに高さ0~1で少しずつ変わるようにしました。200/400/600/800のピーク高さは0.05 or 0.1なので(グラフではほぼ気づきませんね)、100のピークの変動より「変動の大きさ」としては桁で小さいことになります。

このデータ(10000×1001)に対してPCA、FLDA、さらに「邪道PCA」を施しました。FLDAは前述のように「クラス数-1」個の固有値をもつので、今回は4個です。手法間の直接比較のため3種類の処理とも成分を4個、としました。まずPCAの結果を示します。
11

PCAはクラスに関係なく、もとのデータの「変動」を抽出する操作です。これを見ると最も寄与の大きい「波長100のピーク」に重みづけがされています。見事に最も大きな変動が抽出されていますね。一緒に示した寄与率(%)も成分1でほとんどを占めています。残り3成分は波長200/400/600/800にほどよく重みづけがされています。では次にFLDAの結果です。
12

(*PCAよりノイジーですが、これはFLDAが「一般化固有値問題」であることに起因する計算精度の問題で今回の話題の本質ではありません)
PCAと違い、波長100に全然重みづけがされておらず、4成分とも波長200/400/600/800にほどよく重みづけがされています。ここにFLDAの特徴が現れています。FLDAは「異なるクラスをなるべく引き離す」ことを主眼に置いた処理です。波長100のピークは全クラス共通で「0~1までだんだん増えていく」ようにしたため「クラス同士の判別」には用いられないのです。「クラス内/クラス間」を無視するPCAとはここが違います。クラス間の判別に有利である一方で、全データにおける最大の変動である波長100の変化が無視されており、純粋な「情報量」としてはPCAに比べ各段に多く失っています

ちなみに、理論的に1001個の固有値をもつPCAに対してFLDAは固有値が4個、ですので4個の固有値の寄与率は足すと100%になります(PCAは微妙に100%になりません)。
13

最後に「邪道PCA」の結果を示します。この手法では元データの「変動」ではなく「大きさ」をなるべく失わないことに重きを置くため、基本的に成分1は「平均値」になります。ここでも成分1は全データの平均値(すべて正の重みづけ)が現れており、成分2に「大きさ」を最も特徴づける波長100のピークに重みづけ、成分3&4には残りの「大きさ」に寄与する波長200/400/600/800にほどよく重みづけがされています。
14

3手法の重みづけ(固有ベクトル)による「スコア」を比較してみます(教師のクラスごとに色分けして2000点ずつプロットしています)。ここでは4個の成分を2個ずつプロットしています(4次元は図示できないので)。

まずPCAでは、成分1(波長100のピーク)のスコアが全クラスでだんだん増えていく(第一成分がどんどん増加する)ことがわかります(逆に言うと全クラスで値が同じ範囲なので「分離」はできていません)。それ以外はクラスをほどよく分離しています。一方FLDAではこのような事象はみられず、4成分ともほどよく分離されています。邪道PCAでは「平均値」の成分1、さらに「波長100のピーク」に相当する成分2が全クラスで同じように変動していることがわかります。「大きさ」の情報は見事に再現していますが「分離」は全くできていません。

なおFLDAの式の説明のところでFLDAは「同じクラスは近くに集め、違うクラスは遠くに離す」と述べました。スコアの図を見るとたしかに同じクラスはまとまっていますね。PCAの結果を見ると、特に成分1なんかは同じクラスのデータでも思いっきり広がっていて、FLDAの思想の特徴がよくわかると思います。

あえて変なデータをいじってみる!

この例で、PCA(正当&邪道)とFLDAの違いがわかったと思います。ではもう一つ、変わったデータを突っ込んでみます。
15

今度は先ほど重要な働きをした「波長100のピーク」を全クラス共通(高さ0.2)にし、クラス内で変動しないようにしました。つまり「クラス内変動」はランダムノイズのみで、事実上クラス間変動(波長200/400/600/800のピーク変動)のみが存在する、というデータです。このデータに関して先ほどと同じことをしてみました。まずはPCA。
16

そしてFLDAの結果です。
17

両者が非常に似ていることがわかります。PCAは「クラス内/クラス間関係なく元のデータの変動を濃縮」する処理、FLDAは「クラス内変動に対するクラス間変動を濃縮」する処理です。今回はクラス内変動がほぼないので、両者とも「クラス間変動を濃縮」することになりほぼ同じ結果となるのです。ちなみにPCAの固有値寄与率がメチャクチャ低くなっていますが、これはそもそものデータにおいて「クラス間変動」と「ノイズ」を同レベルに設定したことにより、全「変動」のほとんどがノイズになっているためです。
18

ちなみに邪道PCAはこんな感じです。スペクトルの「大きさ」に対して変動がものすごく小さいため、成分1「平均値」だけでほぼ全部寄与率100%です。
19

スコアはこんな感じです。前述のようにPCAとFLDAはほとんど差がありません。邪道PCAでは各クラスの教師データに関して成分1の値が似通っています。つまり「ほとんど分離できてない」といえます。

2つの「教師データ」群をPCA、FLDA、邪道PCAで処理しました。これによって

・PCAは教師データの所属クラスによらず、全データの「変動」を濃縮するような重みづけをする
・FLDAは教師データの所属クラス同士をなるべく分離するような重みづけをする
・邪道PCAは教師データの所属クラスによらず、全データの「大どうなった?きさ」をなるべく残すような重みづけをする

が体感できたと思います。

一般化固有値問題はどうなった?

FLDAの表現式であった
5
この一般化固有値問題は、PCAで使ったような「べき乗法」などの簡単な手法では解けません。この件を一般的に論じるのは今回の記事(&私の脳みそ)のキャパを超えるので割愛しますが、一応インチキ手法はあります。データにもよりますが、経験上Swは正則であることがわりと多いので、Swの逆行列を求めて左からかければ
6
となり(SwもSbもJ行J列の正方行列)、これは普通の固有値問題です。ただ一般的に「逆行列を求める」という行為の精度はちょっと怪しいし、不幸にもSwが正則でなかったらこの方法は使えません。
どうしてもこのインチキ手法だけで乗り切りたい、ということであれば、Swが正則でなかったとしても「リッジ補正」(J行J列の単位行列にものすご~く小さい数をかけて足す)をすれば必ず正則になるので強引に解けます。当然「本来求めるべき答え」と違う答えが出ますが、FLDAそのものをパーフェクトにこなすことが目的、というケースはまれであり、例えばその後の機械学習のための「前処理」としてFLDAを使うみたいなケースでは実用上問題にならないことも多いです。

さすがにそれはインチキすぎるだろ、ということでもう少しマシな手法としては、インチキ問題の左辺を
7
とおきます。これを「精度の悪いSw逆行列を直接求めないで解く」ことを考えます。YおよびSbを「1列ごとにベクトル表現」すると
8
こうなります。この表現を使うとYおよびSbのj列目同士は
9
と表せます。この右の「連立一次方程式」を解いてyjを求め、それを全jに対して行うことで行列Yを求めます。連立一次方程式を解くだけなら逆行列を直接求めなくても可能なため、精度は多少マシになります。実は先ほどの具体例はこの方法を使って計算したものです。

このFLDA、理屈が簡単な初歩的手法である割に性能がよくいろんな場面に使えます。是非使ってみましょう!ではまた。


はっぴぃ理系らいふ、いぇい
ヽ(・ε・)人(・ε・)ノ キミモナカマニナロウゼ
   

【文責 べじぱみゅ】