ミクの歌って覚える多変量解析
第1話 ∫ニョロっと伸びるはエネルギー、バネは答を知っている
2008/12/05  

おっはよー、こんにちわー、こんばんわー!
また、あなたに会えて、ミクはとっても嬉しいの。
ミクはやっぱり歌が好き。
これからも、ずっとずっと歌い続けていきたいな。
未来って、過去の積み重ねからできてるんだ。
過去の積み重ねを一直線に、未来に延ばしていったら、どこに届くんだろう。
そんな未来を予測するのが、回帰分析。
今日、おとどけするのは、回帰分析の歌でーす。

PLAY: 最小二乗法の歌 (MP3 Download)
バネの力は二乗でたまる 二乗でたまるはエネルギー
肩の凝らないリラックス それがいちばんいいかたち
自然のフシギは最小原理 バネは答を知っている
力をためるは積分計算 微分で答を見つけるの
   回帰分析って何だろな?

回帰分析っていうのは、よーするに
 「グラフの上にプロットしたデータの点々を、えいやっと一本の線で結ぶ方法」
のことなんだ。

単回帰分析とは
一個一個のデータはただの「点」、点と点をを結んで「線」にして、はじめて傾向が読み取れるじゃない。
その線をずーっと延ばしてみれば、どこに届くか予測できるってわけ。
もちろん人間がグラフを見て、直感で「ここじゃー」ってな感じに線を引いてもいいんだけど、それを直感にたよらず、しっかりと計算で引こうっていうのが回帰分析なんだ。
一口にグラフっていったけど、回帰分析に使うグラフには「原因」と「結果」が入ってないといけません。
一番簡単なのは、横軸 x が原因で、縦軸 y が結果になってるグラフ。
たとえば x が「やりこみ時間」で、y が「経験値」だったら、「時間をかけるほど -> 経験値が上がる」っていう「原因->結果のストーリー」ができるでしょ。 そんな感じ。
今日は、回帰分析の中でも一番簡単な、X->Yのグラフに直線を引く単回帰分析(直線回帰)をやってみるよ。

   回帰分析は輪ゴムとわりばしで

それじゃあ、さっそく回帰分析用のプログラムを用意しなきゃ・・・
・・・って、ちょっと待ったぁ!
分析ができるのは、何もパソコンとは限らないのです。
今回は小学生気分で、工作を使って分析しちゃいましょう。
ここでフシギなポッケ(?!)から取り出しちゃうのは「直線あてはめマシーン!」(ドラえもん風)

直線あてはめマシーン
用意するもの:板、画びょう、輪ゴム、わりばし。
 1.板の上にグラフを書いて、データをプロットします。
 2.プロットしたデータに画びょうをさして、輪ゴムをひっかけちゃう。
 3.輪ゴムにわりばしを通して・・・
 4.手を離せば、ほら、回帰分析のできあがり!
輪ゴムがひっぱる力のバランスをとって、わりばしが止まったところが「最もあてはまりのよい直線」ってわけ。
ねっ、パソコンよりも簡単でしょ。
回帰分析って、こういうことだったんです。

でも、この「直線あてはめマシーン」、簡単なだけにちょっぴりずるしちゃってるの。

・ずるっこ その1.
ほんとは輪ゴムは斜めに伸びてはいけないんです。
縦方向だけに、垂直に伸びるのが本来の回帰分析なの。
正確にしたかったら、クシみたいに縦にミゾの入った板を用意して、ゴムが縦だけにしか動けないようにしないといけません。
こうなると、作るのはかなり大変だね。

・ずるっこ その2.
ほんとは輪ゴムよりもバネの方がいいんです。
「バネばかり」っていうのはあるけれど、「ゴムばかり」って聞いたことないでしょ。
ゴムは加えた力の通りに、正確に比例して伸びないの。
なので、加えた力に比例して伸びるバネを使うのがGoodなんです。
もっとぜいたく言うと、力がゼロのとき、バネの長さもゼロになっているのが理想なんですねー。
でも長さゼロのバネなんて実際にありっこないから、うんと短いバネでがまんするしかないのです。
この辺が「直線あてはめマシーン」の限界かな。

「輪ゴムとわりばし」は簡単なんだけど、やっぱり限界があって、あまり正確じゃありません。
そこで「輪ゴムとわりばし」がやっていたのと同じことを、正確に計算する方法を考えちゃおうってわけ。
でわでわ〜、「ひっぱる力がバランスをとる」っていうのを、どうやったら計算できるんだろう。
輪ゴム、もう少し正確には、バネがどうなったときに、わりばしは止まるのかな?
ハイ、そこ、居眠りしてると指しちゃうからね(ビシィーッ!)。
なになに、バネの長さを全部合わせて、いちばん短くなったとき・・・なのかな?
長さは変わらない うーん、おしい。
よぉーく考えてみて。
例えばデータの点が3つしかなかったら、わりばしの角度が変わっても、バネの長さの合計はいっしょだよ。
これだとわりばしは1カ所で止まらないよね。
長さじゃなかったら、「何の合計」が一番小さくなったときなんだろう。
きっと、バネがいちばんリラックスしているとき、引っ張って溜め込んだ力が一番小さいときに、わりばしは止まるんだよね。
引っ張って溜め込んだ力の合計・・・これって実は、バネに溜まったエネルギーのことじゃない。
 「バネに溜まったエネルギーの合計が一番小さくなったとき、わりばしは止まる。」
ということで、「最もあてはまりのよい直線」を探す計算っていうのは、実はバネに溜まったエネルギーを計算することだったんだ。

   バネのエネルギーは積分で

それじゃあ、バネに溜まったエネルギーって、どうやって計算したっけ。
なんか、昔、学校で習ったような気がするなー・・・(遠い目)。
あのときは、こんな計算が何の役に立つんだ!って思ってたけど、けっこー意外なところに使えるんだね。
エネルギーって力を溜め込んだものだから、バネにかかった力を最初からぜんぶ足し合わせれば、それがエネルギーになっているはず。
バネって伸びれば伸びるほど引っ張る力が強くなるから、伸びと力をグラフにすると、こんな風になるよね。

バネのエネルギー
バネに溜め込んだ力っていうのは、グラフの上では・・・三角形の面積のことだ!
どうして三角形の面積になるかっていうと、、、
最初のスタートの時点では、引っ張る力はゼロ。
1ミリの地点では、引っ張る力が1。
2ミリの地点では、引っ張る力が2。。
3ミリの地点では、引っ張る力が3。。。
そんなかんじに、1ミリずつ小さな階段を足し合わせていけば、ほとんど三角形といっしょになるでしょ。
あれ〜、これって、昔、学校で聞いたことがあるよーな気がするなー・・・(遠い目)。
そう、この「力を足し合わせる」計算のことを、学校では「積分」って呼んでるんだ。
記号に書くと
∫x dx = 1/2 x^2 + C
ってな感じ。( + C はバネに力がかかっていないときの長さ。この例だと C=0 になってます。)
記号にすると一気に難易度アップしたみたいに見えるけど、これって要するに三角形の面積のこと。
あの∫うにょろ〜って記号を見ただけで、ニョロニョロ虫みたいに毛嫌いする人がいるけど、実は全然たいしたことないんだね。
ちなみに、ニョロニョロ虫にはインテグラル(Integral)っていうカッコイイ名前が付いてるぞ。
名前がカッコイイと、式までカッコよく見えちゃうから、ふしぎだニョロ。
{バネに溜まったエネルギー}
  = {バネの力を積分したもの}
  = {三角形の面積}
  = 1/2 x {バネの引っ張る力} x {バネの長さ}
  = 1/2 x {バネの固さ} x {バネの長さ} x {バネの長さ}
これを世間一般の記号で書けば、
E = 1/2 k X^2
   E : エネルギー
   k : バネの固さ
   X : バネの長さ
ってなります。
この式の中で大事なのは、「エネルギーはバネの長さの二乗になっている」ってこと。
バネの固さとか、1/2 っていうのは、このさい無視しちゃってOK。
だって、バネの固さが違っても、最後にわりばしが止まる場所は同じでしょ。
エネルギーを最小にするっていう方法は、この二乗ってところから「最小二乗法」って呼ばれてまーす。

   微分で探すわりばしの位置

さて、バネのことがわかったら、次はわりばしの位置にチャレンジしてみよっか。
わりばしの位置はよくわかんないけど直線だから、きっと

y = a x + b
っていう形の式に書けるはず。
a は直線の傾き、b は直線がスタートする位置(切片)。
この a と b が決まれば、わりばしの位置がわかっちゃう。
ってことは、a と b が最後に知りたい答になってるんだよ。
次のステップは、データの画びょうがささっている位置から、わりばしまでの長さ。
たとえば x = 20, y = 50 っていうデータから、わりばしまでの長さはどれだけかな?
x = 20 のとき、わりばしの位置(yの値)は、
y = 20 a + b
だよね。
なので、データからわりばしまで、バネの長さは
{バネの長さ} = {データの位置} - {わりばしの位置} = 50 - (20 a + b)
になるよ。
同じことを、今度は記号で書いてみるね。
x = x1, y = y1 っていうデータがあったとして、そこからわりばしまでの長さは
{バネの長さ} = y1 - (x1 a + b)
バネのエネルギーは、バネの長さの二乗ってことで
{バネのエネルギー} = {y1 - (x1 a + b)} ^ 2
これが1個のデータについてのエネルギー。
それじゃあ、データが10個あったら、どうなるんだろう。
そのときには、(x1, y1) (x2, y2) (x3, y3) ... (x10, y10) っていう10個の数字の組があって、似たよーな式が10個できちゃいます。
全エネルギーは、その10個の式をぜーんぶ合わせたもの。
つまり10本のバネのエネルギーを合わせたことになるよね。
式が10倍に増えても、中身は同じことの繰り返しだから、きまじめに全部書かなくってもいいんだよ。
こういうときに便利なのがΣ(シグマ)っていう記号。
Σは「同じ式を、中身の値だけ変えて、繰り返し足し合わせる」って意味なんだ。
{10本のバネのエネルギー}
 = Σ[ {yi - (xi a + b)} ^ 2 ]   (i=1〜10)
 = Σ[ {yi - xi a - b} ^ 2 ]
ふぅっ、これでやっと全エネルギーの式ができました。
なんだかすごく複雑な式だにゃあ・・・
でも、めげずによーく見てみると、これって a の二次式になってることに気付いたかな?
2次式の最小値 二次式って、放物線をひっくり返したおわん型になってるでしょ。
だから、そのおわんの谷底が知りたかった答になってるの。
b についてもやっぱり二次式だから、おわんの谷底に答があるんだね。
さて、おわんの谷底になっている、エネルギーが一番小さくなるような a と b を探すには、どおすればいいのかなー?
そんなとき、とっても強力な常套手段は「微分する」ってこと。
谷底は平らになってるから、傾きがゼロ。
つまり、微分してゼロになるところがエネルギー最小ポイントなのです。
あれっ、そういえばどこかで、そんな話を聞いたことがあるよーな、ないよーな・・・(はるかに遠い目)。
でしょ、でしょ。
覚えてる人は記憶をたよりに、教わったことがない人は努力と根性で、エネルギーの式を微分しちゃおう。

{10本のバネのエネルギー}を a で微分すると、
Σ[ {yi - xi a - b} ^ 2 ] / ∂a
= 2 Σ[ xi ( xi a + b - yi ) ]
{10本のバネのエネルギー}を b で微分すると、
Σ[ {yi - xi a - b} ^ 2 ] / ∂b
= 2 Σ[ b + xi a - yi ]
a と b、それぞれの微分結果がゼロになる答を探していたんだから、イコールゼロ(= 0)ってすると、2本の式が出てくるよ。
2 Σ[ xi ( xi a + b - yi ) ] = 0
2 Σ[ b + xi a - yi ] = 0
この2つの連立方程式を、すごい努力と根性で解くと、知りたかった答の a と b が出てくるんだ。
でも、努力と根性は最近あんまり流行ってないみたいだから、ワープして一気に答えにいっちゃえ。
(努力と根性が好きな頭脳派体育会系?!は、下の方の計算を見てね。)
直線の傾き : a = Σ[ (xi - x~)(yi - y~) ] / Σ[ (xi - x~)^2 ]
直線の切片 : b = y~ - a x~
   xi : 個々のデータの x 値
   yi : 個々のデータの y 値
   x~ : x の平均値
   y~ : y の平均値
これが直線回帰の公式。
パソコンのソフトなんかは、実はこの「答の公式」を実行しているだけなんだ。

   試しに使ってみよう

せっかく出した公式なんだから、試しに使ってみよっか。

やりこみ時間[x] 経験値[y]
3 200
5 400
8 720
17 850

{xの平均値} x~ = (3 + 5 + 8 + 17) / 4 = 8.25
{yの平均値} y~ = (200 + 400 + 720 + 850) / 4 = 542.5

Σ(xi - x~)(yi - y~)
= (3 - 8.25)(200 - 542.5) + (5 - 8.25)(400 - 542.5) + (8 - 8.25)(720 - 542.5) + (17 - 8.25)(850 - 542.5)
= 4907.5

Σ[ (xi - x~)^2 ]
= (3 - 8.25)^2 + (5 - 8.25)^2 + (8 - 8.25)^2 + (17 - 8.25)^2
= 114.75

{傾き} a = 4907.5 / 114.75 = 42.77
{切片} b = 542.5 - 42.77 * 8.25 = 189.65

求める回帰直線の式は
y = 42.77 x + 189.65
この調子で3日間寝ずに72時間やりこんだら、経験値は
  y = 42.77 * 72 + 189.65
   = 3269.09
と予想されるんだよねぇ・・・

やりすぎに注意!
それじゃ、まったね〜!



   努力と根性で解く わりばし計算

{10本のバネのエネルギー}を a で微分すると、
   Σ[ {yi - xi a - b} ^ 2 ] / ∂a
  = Σ[ {xi a + b - yi} ^ 2 ] / ∂a      ・・・符号を変えて並べ直して
  = Σ[ xi^2 a^2 + 2 (b - yi) xi a + (b - yi)^2 ] / ∂a      ・・・a の順番に整理して
  = Σ[ 2 xi^2 a + 2 (b - yi) xi ]      ・・・a で微分
  = 2 Σ[ xi^2 a + (b - yi) xi ]      ・・・2をくくりだして
  = 2 Σ[ xi ( xi a + b - yi ) ]      ・・・共通項 xi でまとめました

{10本のバネのエネルギー}を b で微分すると、
   Σ[ {yi - xi a - b} ^ 2 ] / ∂b
  = Σ[ {b + xi a - yi} ^ 2 ] / ∂b      ・・・符号を変えて並べ直して
  = Σ[ b^2 + 2 (xi a - yi) b + (xi a - yi)^ 2 ] / ∂b      ・・・b の順番に整理して
  = Σ[ 2 b + 2 (xi a - yi) ]      ・・・b で微分
  = 2 Σ[ b + xi a - yi ]      ・・・2をくくりだし

まず、b の微分結果 = 0 から
  Σ[ b + xi a - yi ] = 0
  Σ b = Σ[ yi - a xi ]      ・・・ b の付いたものだけまとめる
  b = Σ[ yi - a xi ] / n      ・・・ n はデータの個数、ここでの例では10個

これでとりあえず b の答が出てきたね。
残るは a の答え。

上の方の、a の微分結果 = 0 から
  Σ[ xi ( xi a + b - yi ) ] = 0
  Σ[ xi^2 a + xi b - xi yi ] = 0
  Σ[ xi^2 ] a + Σ[ xi ] b - Σ[ xi yi ] = 0
b の答を代入して、b を消去するね。
  Σ[ xi^2 ] a + Σ[ xi ] Σ[ yi - a xi ] / n - Σ[ xi yi ] = 0
  Σ[ xi^2 ] a + Σ[ xi ] Σ[ yi ] / n - a Σ[ xi ]^2 / n - Σ[ xi yi ] = 0
a の付いたものだけ集めてきます。
  a { Σ[ xi^2 ] - Σ[ xi ]^2 / n } + Σ[ xi ] Σ[ yi ] / n - Σ[ xi yi ] = 0
  a { Σ[ xi^2 ] - Σ[ xi ]^2 / n } = - Σ[ xi ] Σ[ yi ] / n + Σ[ xi yi ]
  a { Σ[ xi^2 ] - Σ[ xi ]^2 / n } = Σ[ xi yi ] - Σ[ xi ] Σ[ yi ] / n
これでやっと a が出てくるよ。
  a = { Σ[ xi yi ] - Σ[ xi ] Σ[ yi ] / n } / { Σ[ xi^2 ] - Σ[ xi ]^2 / n }

確かにこれが a の答なんだけど、長くてちょっと見にくいよね。
もう少しわかりやすく整理してみよっか。
整理するのにデータの平均って記号があると便利なので、
x の平均は Σxi / n だから、この平均を x~ って記号で書くね。
y の平均は Σyi / n だから、この平均を y~ って記号で書くね。

まず、答の式の分母 { Σ[ xi^2 ] - Σ[ xi ]^2 / n } の意味を考えてみよー。
データの二乗の和から、各データの二乗の平均値を引いたもの、、、
これって x の分散ってことじゃないかしら。
(正確には分散をn倍したもの、偏差平方和)
分散には、
  1/n Σ[ xi^2 ] - (x~)^2 = 1/n Σ[ (xi - x~)^2 ]
っていう関係があるから、よく見比べてみると、同じだね。
  Σ[ xi^2 ] - Σ[ xi ]^2 / n = Σ[ (xi - x~)^2 ]

次に、a の答の分子 { Σ[ xi yi ] - Σ[ xi ] Σ[ yi ] / n } はどうなってるんだろう。
平均の記号を使って書き直すと、ちょっとだけ簡単になるよ。
  分子 = { Σ[ xi yi ] - n x~ y~ }
これは、x と y の掛け算から、平均値を引いたもの、つまり共分散ってことかな。
(正確には共分散をn倍したもの、偏差積和)
共分散には、
  1/n Σ[ xi yi ] - x~ y~ = 1/n Σ[ (xi - x~)(yi - y~) ]
って関係があるから、よく見比べると、やっぱりおんなじだ。
  Σ[ xi yi ] - n x~ y~ = Σ[ (xi - x~)(yi - y~) ]

これで全部がそろったね。
じゃんじゃじゃーん、これが最後の答でーす!

a = Σ[ (xi - x~)(yi - y~) ] / Σ[ (xi - x~)^2 ]
b = y~ - a x~

ページ先頭に戻る▲