"機械学習","信号解析","ディープラーニング"の勉強

HELLO CYBERNETICS

深層学習、機械学習、強化学習、信号処理、制御工学などをテーマに扱っていきます

【正比例から】基礎からの微分と線形代数への再入門

 

 

f:id:s0sem0y:20170703184638j:plain

 

はじめに

微分と線形代数は機械学習で用いられる数学の基礎です。従ってこの基礎をしっかりと抑えることで、機械学習に出てくる数式をよく理解できるようになります。

 

今回は微分と線形代数に関して初歩から順序立てて説明していきます。ここでは中学生から触ってきている正比例「y=ax」から始まり、次第に微分や線形代数の世界へと発展させていきます。

 

この記事を読む前提として必要な知識は、中学生の数学(正比例)と、高校生の数学(ベクトル)までです。あとはやる気次第で微分や線形代数の概念を理解するところまで到達できるはずです。

 

ベクトルに関しては難しいことを知っている必要はありません。

 

正比例関数

関数とは

関数というのはつまるところ、何かしらの入力xを受け取り、何かしらの出力yを返す装置fのことを言います。この関係を表すために

 

f:x \mapsto y

 

という表記をします。これはfxに作用し、yに変化させることを表しています。あるいはfxを引数にyを返すことを示すため、

 

y=f(x)

 

などとも表記します。

 

今はまだこの入出力装置(関数)fがどのようなものであるかは明記していません。通常は入力がxであった場合には、fがどのような処理を施すのかを示すために下記のように記します。

 

f(x) = ax

 

この場合は、xを入力した時に、それをa倍した処理を施し、axを出力するという意味になります。従って、具体的な出力yに関しては

 

y = ax

 

と表されます。まとめれば

 

y = f(x) = ax

 

なのですが、ココらへんのことはあまり細かいことを言わず、いきなり

 

y = ax

 

と書いたり、fという処理にフォーカスすることが無いのであれば、

 

y(x) = ax

 

yxに依存することを明記しつつ表記したりします。

 

(今はf(x) = axの議論をしているので、最初からy=axで良いじゃないかと思うかもしれません。しかし、もっと一般的な話になり、関数を明確に決めずにいく場合は、y = f(x)と書いておいて、後から「f(x) = ●においては」などと議論した方が都合が良いのです)

 

正比例関数の重要な特徴

正比例関数とは先ほど見たような

 

f(x) = ax

 

の形をした関数です。この関数は入力値を定数倍して出力します。

 

正比例関数には重要な特徴が2つあります。この特徴は「線形」なる概念に発展するための重要なものであるため、必ず覚えておきましょう。

 

分配法則

 

f(u + v) = f(u) + f(v)

 

これは入力したい数が2つあるとき、その2つの数を「足してから関数に入れること」と「関数に入れたから足すこと」が同じ結果になるということを表しています。

 

結合法則

 

f(cx) = cf(x)

 

これは入力したい数に関して、その数を「定数倍してから関数に入れること」と「関数に入れたから定数倍すること」が同じ結果になるということを表しています。

 

 

この2つの法則は非常に特徴的であり、これが上手く成り立つことは他にはありません。例えば、ちょっとだけ違う関数

 

f(x) = ax + b

 

になった途端これは成り立たなくなります。仮に

 

f(x) = x + 1

 

という関数を考えましょう。これは単に、入力に 1 を足すだけの処理です。この関数にx = 1x = 2を入力してみましょう。

 

f(1) = 1 + 1 =2

 

f(2) = 2 + 1 =3

 

当たり前の結果です。しかし、これについて分配法則が成り立つのか見てみましょう。

 

f(1 + 2) = f(3) = 3 + 1 = 4

 

f(1) + f(2) = 2 + 3 = 5

 

となり、違う結果が得られました。すなわち上記の形の関数では、足してから入力するのと、入力してから足すのが違うことになってしまうのです。同様に結合法則も成り立ちません。

 

もしかしたら上手い数字のペアを見つければ成り立つかもしれません。

しかし正比例関数の場合、どのような値を入れても例外なくいつでも分配法則と結合法則が成り立ちます。これは特別なことです。

 

正比例関数のグラフと傾き

正比例について更に良く知るためにグラフを見ていきます。ここでは機械学習でも重要な「傾き」あるいは「勾配」という概念を理解しましょう。

 

y = axのグラフ

y = f(x)に関して、関数fが正比例関数であるとき、そのグラフは以下のようになります。例としてここではf(x) = 2xを用いていきましょう。

f:id:s0sem0y:20170702202237p:plain

 

便宜的に今はf(x)のことを忘れて、y = axという表記を用いて説明していきます。

 

このグラフにおいて、xが1だけ増加するとy2だけ増加しています。グラフを見れば明らかですし、これは中学生の頃から知っている事実です。しかし勾配や微分という概念にいくためにもう少し詳細に調べてみましょう。

 

傾き(勾配)

1だけ増加させる」と数値を指定するのではなく、仮に、Δxだけ増加させた場合にはどうなるでしょうか。結果としてはy2Δxだけ増加することになります。これは正比例関数では、どのようなΔxについても必ず成り立っています。

 

すなわち、xの増加量の2倍だけ、yは増加するということです。

 

従って、xの増加量Δxyの増加量Δyの関係は

 

Δy = 2Δx

 

と表すことができるのです。

もっと一般的に正比例関数y = axでは

 

Δy = aΔx

 

となります。この時、aのことを傾き(勾配)と呼びます。これは見た目上、y=axy,xΔy,Δxに置き換えたような形になっています。

 

しかし、今後のためにも意識しておいて欲しいのは、Δy=aΔxの形になった時のaを傾き(勾配)と呼ぶ」ということです。このことを念頭において置くことが、微分という概念を理解していく上で非常に大切になってきます。

 

そして、この式に関してΔxで両辺を割ると

 

\displaystyle \frac{Δy}{Δx} = a

 

となります。従って、正比例関数における傾き(勾配)はxの増加量分のyの増加量で表現できるということです。これもよく知られた事実ですね。これらを踏まえた上で微分という概念に入っていきます。

 

また、正比例関数は特別な存在であるため、この勾配を正比例関数に限って「比例定数」などとも呼びます。

 

微分

増分から探る

まずは微分とは一体何かを説明します。先ほどまで傾き(勾配)の話をしてきましたので、その流れで説明していきます。以後、傾き(勾配)のことを「勾配」と呼ぶようにします。「傾き」というのはグラフを見る上で直感的に理解しやすい言葉ですが、「勾配」の方がより一般的に使われる言葉ですので統一していきます。

 

先程までy = axについて、xの増加量をΔxyの増加量をΔyと表記してきました。増加量というのは「増分」とも言います。今後は言葉の類似性から増分と言ってみます。

 

 

さて、ここではf(x)=x^2で話を進めましょう。このときy = x^2であり、そのグラフは以下のようになっています。

f:id:s0sem0y:20170702210251p:plain

傾きを求めてやろうと、無邪気にΔx増加したらΔyだけ増加する関係を表してやろうとするとどうなるかを見ますx=0からΔx = 2だけ増やしてみます。するとy=0の状態からy = 4に増えているため、増分Δy=4であることが分かります。

 

Δy = aΔx

 

の形の時にaを勾配と言うのでしたから、今回は4 = 2\cdot 2が成り立っており、a =2が勾配だと思いたいです。しかしそれは本当でしょうか?Δx=1のときでも勾配は[2]だと言えるでしょうか(実際にはこのときΔy=1でありa=1となる)。どうやら、Δxの大きさ次第で勾配の値が変わってしまいそうです。

 

正比例では増分をどれくらいの大きさに取っても構いませんでした。しかし、一般的にはそうではなさそうです。

 

 

 

微分は関数の正比例への近似

 

正比例というのはどうやら人間にとって取っても都合の良い形をしているようです。そうであれば、一般的な関数を正比例の形に近似することはできないでしょうか。

 

この課題にチャレンジしましょう。

 

y=x^2

 

を、なんとかしてy = axの形に持って行きたいのです。そんなことを可能にするとっても良い手段があります。以下のy=x^2のグラフを見てください。

f:id:s0sem0y:20170702212102p:plain

 

直線に見えます。やりました。 これなら正比例に見えなくもありません。ただしグラフの値を見てください。非常に範囲が狭いです。逆に言えば、非常に狭い範囲に着目すれば、一般的な関数を正比例っぽくできるということです。

 

今は、x=2を中心にy = x^2について見ています。この局所的な世界では、増分の大きさをどのように取っても(もちろん世界が局所的なので、増分も比較的小さい値を取ることになるが)勾配がa≒4になっていそうです(厳密には一致しないが、ほとんど同じようなもの)。

 

ともかく、局所的に見ることが正比例への近似の良い手段となりそうです。

 

他の場所についても調べてみましょう。

f:id:s0sem0y:20170702213141p:plain

 

ここではx =1を中心に世界を見ています。勾配はa=1となっていそうです(グラフの値に注意)。どうやら局所的な世界を作る場所によって、勾配は変わるようです。

 

つまり、勾配axに依存しているということです。これを表すためにa(x)と置くことにして、一般的に(局所的に見ることを前提にして)

 

Δy = a(x)Δx

 

ということが言えそうです。

  

という形式を取ります。ここで局所的な世界の増分Δxを新たな変数dxとして、更にΔydyと置くことで、完全にこの世界をdy = a(x)dxという正比例関数と見てしまうことができます。

 

f:id:s0sem0y:20170702230129p:plain

 

すなわち、関数y = f(x)の座標上に、新たにdy=a(x)dxの座表を立てるのです。このような正比例関数dy = a(x)dx(赤い直線)は、局所的な領域が狭まれば狭まるほど(座標の取りうる範囲が狭まるほど)、y = f(x)に一致していきます。

 

dy=a(x)dxは正比例関数であるので、この局所的な世界で勾配a(x)を求めたい場合は

 

\displaystyle \frac{dy}{dx} = a(x)

 

を求めることになります。

 

高校で習う定義式

 

局所的な世界は小さく取れば小さく取るほど正確に正比例関数に近似ができるため、通常はdxを限りなく0に近づけていきます。

 

これをf(x)の世界で直接語るために、a(x)について以下のような式が定義されています(これは高校で最初に習う微分の式だと思われます)。

 

\displaystyle a(x) = \lim_{Δx→0} \frac{f(x + Δx) - f(x)}{x+Δx}

 

これは局所的な世界における\displaystyle f'(x)=\frac{dy}{dx}のことを言っており、「局所的な世界」を表す意味として\lim_{Δx→0}が書かれています。ただし、f(x)の局所的な世界の勾配を議論していることを明示するために、通常はa(x)f'(x)と表記します。

 

従って通常は

 

\displaystyle f'(x) = \lim_{Δx→0} \frac{f(x + Δx) - f(x)}{x+Δx}

 

と習うでしょう。(同様に局所的な正比例関数はdy = f'(x) dx

 

微分、導関数、微分係数の言葉の違い

「微分」とか「導関数」とか「微分係数」という言葉が似たような意味で使われます。混同している人も多いかもしれません。

 

本来、単に「微分」と言ったら、局所的なyの増分であるdyのことになります。これは増分の微小な量であるという雰囲気で覚えればいいでしょう。(Δydyと置き換えた)

 

しかし、大抵興味あるのはdy = f'(x)dxf'(x)の方なので、微分した結果求まるf'(x)のことを微分と呼ぶケースが多いです。本来はf'(x)のことをf(x)の導関数と呼びます(この言葉の違いを知っておくことが、多変数になったときに混乱を招かないために大事であると思う)。

 

また、局所的な世界はxの値によって指定されます。仮にxの値をx=cなどと指定してしまえば、局所的な世界の正比例関数がdy = f'(c)dxと定まりf'(c)は何らかの定数になります。このように具体的に微分dy = f'(c)dxが決まった時のf'(c)を微分係数と呼びます(正比例関数y=axではaを比例定数と言った)。

 

まとめれば、

 

微分:dy = f'(x)dx

 

導関数:f'(x)

 

微分係数:f'(c)

 

ということになります。

 

接線の方程式

関数y=f(x)の接線の方程式に関して、高校生では以下の公式を覚えるかもしれません。

 

y=f(x)x = cにおける接線の方程式は

 

y = f'(c)(x-c) + f(c)

 

あるいは

 

y - f(c) = f'(c)(x-c)

 

と表現されているかもしれません。

 

これは実は微分そのものになります。微分とは正比例関数dy = f'(x)dxのことでした。今、x = cにおける微分を考えましょう。そうすれば、

 

dy = f'(c)dx

 

となります。これは局所的には正比例関数ですが、こいつの原点は今どこにあるのかというと、(c,f(c))という場所になります。

 

f:id:s0sem0y:20170702231756p:plain

dy = f'(c)dxは局所的な世界に定義された正比例関数(直線)でしたが、この局所的な世界を飛び出すことを許してしまえばすぐに接線の方程式が得られます。上記のグラフにおいて、dy = y - f(c)であり、dx = x-cです(座標dy-dxの原点に着目)。こいつをdy = f'(c)dxに代入してやることで、

 

y-f(c) = f'(c)(x-c)

 

が得られます。局所的にしか定義していなかった正比例関数を延長してやれば接線が得られるというわけです。

 

 

微分のまとめ

 

微分はy = f(x)に対してdy = f'(x)dxという局所的な正比例関数への近似を行います。このときのdyを微分、f'(x)を導関数、x=cにおける導関数f'(c)を微分係数といい、微分係数はx=c付近の局所的な世界における勾配に相当します。

 

「正比例関数への近似」と述べてきましたが、これからは格好つけて「線形近似」と言うと良いです。「微分は局所的な線形近似」、「微分は局所的な線形近似」と唱えましょう。

 

(普通に勾配を求めるものだと思っても良いのですが、関数の線形近似と考えれば近似後の勾配を議論できるのは当たり前ですし、後に多変数になっととき明らかに理解が早い)

 

 

微分の計算方法

 

y = f(x)の微分がdy = f'(x)dxなのは良いとして、どうやってf'(x)を求めるのかという話題があるでしょう。実は、これは普通はかなり難しいのです。

 

\displaystyle f'(x) = \lim_{Δx→0} \frac{f(x + Δx) - f(x)}{x+Δx}

 

がまさにそれであるのですが、これを計算するのは普通は厳しいです。

例えば下記のような公式

 

f(x) = x^a

 

f'(x) = ax^{a-1}

 

などは、誰かが気づき、証明してくれたものです。中には病的な見た目をした関数もあり、そいつらは微分するのが困難であったり、そもそも微分できるのか(線形近似できるのか)謎なものもあります。

 

微分の計算そのものはもはや覚えるしかありません。過去の偉人の成果を有りがたく使いましょう。ただし、計算だけをしていると、結局それが何なのかわからなくなってしまうので注意が必要です(そのための入門記事であります)。

 

導関数は「関数」

 

関数fとは入力xを出力yに変化させる装置f:x \mapsto yのことでした。そして、入出力関係を明示するときにy = f(x)と表記します。なぜf'(x)のことを「導関数」と呼ぶのかというと、紛れもなくf'が関数であるからです。

 

f'は「入力xを受け取った時に、y=f(x)の局所的な世界の正比例関数dy = adxの勾配aを出力する関数」と捉えるわけです。つまりf':x \mapsto aであり、a = f'(x)であることを、めんどうなので省略してdy = f'(x)dxとしているわけです。

 

導関数や微分の別の表記

 

導関数f'(x)について更に追記します。y = f(x)の導関数については\frac{dy}{dx}という表現もありますが、ここからyを分離させた\frac{d}{dx}なるものを考えることができます。本来dxとかdyなどの表現で「1つの量」であり、増分から発展した微分なる概念でした。これを

 

\displaystyle \frac{dy}{dx}=\frac{d}{dx} y

 

と書くようにしてしまい、「\frac{d}{dx}yに作用させる」と呼ぶようにするのです。これが言わば「微分する」ということです。

 

 

また、こうなるとy = f(x)の方はもはやどうでも良くなり、\frac{d}{dx}の方だけを詳細に語ることでできるようになります。

 

この\frac{d}{dx}を「微分演算子」とか「微分作用素」などと呼び、これ自体を個別に扱うことで演算子法なる便利な微分方程式の解法が生まれました(後にラプラス変換と関連付けられる)。

 

 

(実は、流派の違いであって、最初から「微分する」という演算をDで表現してDf(x)などと作用素の形で書く場合もある。しかし、一番馴染みが良いのはdxとかdyという増分から入ることだと思う。)

 

 

微分できないときもある

中には線形近似(≒微分)できない関数もあると述べました。

例えばy = |x|なんかは代表的な例です。こういうのは微分不可能とか言いますが、なぜかというとx = 0の付近はどう頑張っても正比例関数に見ることができないためです。

f:id:s0sem0y:20170703002418p:plain

 

x = 0以外だったら正比例関数に近似できます(というか正比例関数)。一箇所でもダメな場所があると微分不可能と呼ばれますが、仮にx=0を全く考慮しなくても良いようなケースなら、右側で勾配1、左側で勾配-1で微分できると考えてもいいでしょう。

 

上記のような単純な関数ならばいいです。どこを無視して良さそうかも明白です。しかし、もっと複雑な関数や、多変数で図示ができないようなときに、線形近似できるか否かを見た目で判断してしまうのはかなり怪しいので、これを厳密に議論できるようにしたのがε-δ論法です。

 

 

s0sem0y.hatenablog.com

 

スポンサーリンク

   

 

線形代数

正比例関数の拡張

さて、次は線形代数の話に入ります。

再び関数fの話から行きましょう。こいつはxyに変えてくれる入出力装置f:x\mapsto yでありました。正比例関数の場合はこれが

 

f:x\mapsto ax

 

という入出力装置になっているということでした。今まではいっつも入力がxという1つの値でした。1つしか入力を受け付けないなんて限定的過ぎると思いませんか。

 

 

多入力の関数

 

2つの入力を受け付ける関数

 

f:x_1,x_2 \mapsto y

 

を考えましょう。正比例関数のノリで拡張をするために、

 

f:x_1,x_2 \mapsto a_1x_1 + a_2x_2

 

という形式にしてみましょう。慣れ親しんだ形で書くならば

 

y = a_1x_1 + a_2x_2

 

という形式です(あるいはf(x_1,x_2) = a_1x_1+a_2x_2)。とても単純です。このような計算を、正比例関数y = axの形式に似せるために

 

y = \bf a \cdot x

 

と表記することにします。太字\bf a,xはそれぞれ{\bf a}=(a_1,a_2){\bf x} = (x_1,x_2)であり、いわゆるベクトルというやつです。「\cdot」は内積と呼ばれる計算であり、ベクトルを成分毎に掛け算した後に和を取ります。

 

もっと入力の数を増やしたいならば、同じようにベクトルの成分の数を増やしていけば良いだけです。見た目の表記y=\bf a \cdot xを変更する必要はありません。

 

こうして、正比例を拡張した多入力の関数fを獲得することに成功しました。

 

f:{\bf x} \mapsto \bf a\cdot x

 

内積というのは左側が横ベクトルであり、右側が縦ベクトルの順に並んでいます。ベクトルの成分を明示的にするならば

 

{\bf a \cdot x} = (a_1,a_2) \left( \begin{array}{c} x_1 \\ x_2 \end{array}\right)

 

となります。多くの場合、単にベクトル\bf xと言った場合には

 

{\bf x} = \left( \begin{array}{c} x_1 \\ x_2 \end{array}\right)

 

のように縦ベクトルを表すことが多いです。従って内積計算を以下のように書くことも多いことを覚えておくと良いです。

 

{\bf a \cdot x} = \bf a^T x

 

a^Tとは縦ベクトル\bf aを横ベクトルに変えることを表す転置と呼ばれるものです。(実は内積というのは結構種類がありますので、「\cdot」と単に書いた場合にはその計算内容は文脈によったりします。これに対して横ベクトルと縦ベクトルを並べるのは計算の内容が明確です)

 

多入力多出力関数

 

例えば、入力x_1x_2の2つを受け取るときに、2つの数

 

a_1x_1+a_2x_2

 

b_1x_1+b_2x_2

 

という結果を返して欲しいとします。多入力の話を応用して、

 

{\bf a}=(a_1,a_2)

 

{\bf b} = (b_1,b_2)

 

{\bf x}=(x_1,x_2)

 

と置くことで、以下の2つの関数

 

f_1 : {\bf x} \mapsto \bf a^T x

 

f_2 : {\bf x} \mapsto \bf b^T x  

 

を準備してやればひとまず一歩前に進むことができます。y_1 = f_1({\bf x})y_2 = f_2({\bf x})を計算すればいいということです。あとは、y_1y_2を格納するベクトル{\bf y}=(y_1,y_2)を考えてやればよく、出力を

 

{\bf y} = \left( \begin{array}{c} {\bf a^T x}  \\  {\bf b^T x}\end{array}\right)

 

と表記してやれば良いことになります。確かに多出力になりました。しかしこれは2つの関数f_1f_2を使って2つの出力を並べたに過ぎません。そうではなく、1つの関数で多出力を実行するのが今の目標なのです。いま、作った形を少し変形してやります。

 

{\bf y} = \left( \begin{array}{c} {\bf a^T x} \\ {\bf b^T x}\end{array}\right)

 

これは上の成分も下の成分も\bf xとの内積をとっているだけに過ぎないので、まずは\bf xで括ってみます。

 

{\bf y} =\left( \begin{array}{c} {\bf a^T} \\ {\bf b^T}\end{array}\right) \bf x

 

そうすると、ベクトル\bf xを受け取ったら

 

\left( \begin{array}{c} {\bf a^T} \\ {\bf b^T}\end{array}\right)

 

という謎の係数を掛けて出力する関数fを考えることができます。謎の係数の中身は、横ベクトルが2つ格納されているため、この横ベクトルを素直に表記すれば

 

\left( \begin{array}{c} a_1 a_2 \\ b_1 b_2 \end{array}\right)

 

という形をしていますので、それをそのまま\bf Aと置いて採用することにしましょう。これからは

 

\bf y =Ax

 

という計算をしていると考えることにしたのです。今、f: \bf x \mapsto \bf Axという新たな関数を手にしました。このときの\bf Aを行列と呼びます。行列は多入力多出力を達成してくれる関数の一種であるわけです。

 

 

 

行列の計算の仕方

これまでの話で構築してきた新たな関数\bf y = Axは、成分を全て明示した場合は以下のような形式をしています。

 

\left( \begin{array}{c} y_1 \\ y_2 \end{array}\right) = \left( \begin{array}{c} a_1 a_2 \\ b_1  b_2 \end{array}\right) \left( \begin{array}{c} x_1 \\ x_2\end{array}\right)= \left( \begin{array}{c} a_1x_1 + a_2x_2  \\ b_1x_1 + b_2x_2 \end{array}\right)

 

行列の計算の仕方に奇妙さを覚える人がいるかもしれませんが、今まで見てきたとおり、多入力1出力の計算を内積\bf a^Tx, b^Txで表しておいて、あとでそれをくっつけて多入力多出力にしたために上記のような計算となっています(上記ではabの2つのアルファベットを使っているため分かりやすい)。

 

しかし確かにf:{\bf x \mapsto Ax}を手に入れた今、2つの内積をくっつけたという名残は不必要です。従って、行列\bf A

 

{\bf A} = \left( \begin{array}{c} a_{11} a_{12} \\ a_{21}  a_{22} \end{array}\right)

 

と表すようにします。成分の添字はa_{行番号,列番号}となるようにしているわけです。そうなると、行列の計算の記述は

 

{\bf y = Ax} =\left( \begin{array}{c} a_{11} a_{12} \\ a_{21}  a_{22} \end{array}\right) \left( \begin{array}{c} x_1 \\ x_2\end{array}\right)= \left( \begin{array}{c} a_{11}x_1 + a_{12}x_2 \\ a_{21}x_1 + a_{22}x_2\end{array}\right)

 

などと現れます。大抵はいきなりこの計算方法を与えれるためややこしく感じるわけです。

 

n入力m出力

この話の流れを理解していれば、n入力m出力の関数を行列の形で表現するのは非常に簡単だと感じるはずです。

 

まず2入力を達成するために成分数2のベクトルを考えました。

 

{\bf a} = (a_1,a_2)

 

そして、2出力を達成するためにベクトルを2つ準備したのです。あとはそれを並べたわけです。

 

\left( \begin{array}{c} {\bf a^T} \\ {\bf b^T}\end{array}\right)

 

そうともあれば、n入力m[tex:]出力は、まずn入力を達成するために

 

{\bf a_1} = (a_1,...,a_n)_{\bf 1}

 

を作り、そんなふうにしてできたベクトルをm個並べて

 

\left( \begin{array}{c} {\bf a^T _1} \\ \vdots \\ {\bf a^T _m}\end{array}\right)

 

となります。

 

すなわちn入力m出力を作りたいならば、m行n列の行列を作ることになります。

 

行列の重要な性質

行列の計算の成り立ちについて見てきました。多入力多出力を達成する関数を行列が提供してくれることを強調してきましたが、正比例関数っぽい計算を拡張してきたことを忘れてはいけません。

 

正比例関数f(x) = axには重要な特徴がありました。その特徴が、実はf({\bf x}) =\bf Axという関数にも見事に成り立ちます。

 

分配法則

 

f({\bf u + v}) = f({\bf u}) + f({\bf v})

 

これは入力したい数が2つあるとき、その2つの数を「足してから関数に入れること」と「関数に入れたから足すこと」が同じ結果になるということを表しています。

 

結合法則

 

f(c{\bf x}) = cf({\bf x})

 

これは入力したい数に関して、その数を「定数倍してから関数に入れること」と「関数に入れたから定数倍すること」が同じ結果になるということを表しています。

 

 

線形性

今、単なる1入力1出力の正比例から、多入力多出力の正比例らしきものを手に入れたのです。正比例が特別なのは、上記のような綺麗な性質を持ち合わせているからです(別に正比例という名前に意味があるわけではありません)。

 

通常、関数fが分配法則と結合法則を満たすとき、「線形性を有する」と表現して、その関数を特別扱いしていきます。

 

数学ではこのような性質(あるいは定理)の方に重要性を見出して、そちらを基礎に再出発することで一般化を進めていくケースが多々あります(これからは正比例とは線形性のごく限られた特殊なケースであるという見方をすることにした)。

 

ちなみに分配法則と結合法則を同時に表現して

 

f(c({\bf u + v})) = cf({\bf u}) + cf({\bf v})

 

を線形性を有する定義とする場合もあります(どっちも一緒ですが参考程度に)。

 

グラフ

多入力多出力と見た行列に関して、まずは便宜的に2入力1出力の行列を見ましょう。これは単に内積f: {\bf x} \mapsto \bf a^Txという関数を見るということです。

 

今回はf({\bf x})=x_1 + 2 x_2という関数を見ることにします。ベクトルを使えば、

 

f({\bf x}) = (1,2) \left( \begin{array}{c} x_1 \\ x_2 \end{array} \right)

 

という表記になります。この関数のグラフは縦軸をf(\bf {x} )で下の軸を[tex:x_1,x_2の2つとして以下のような形状をしています。

 

f:id:s0sem0y:20170703033249p:plain

 

さてここで理解して欲しいのはこれが平面になっているということです。係数ベクトル\bf aの成分が変われば面の方向は変わりますが、y = \bf a^Txはいつでも必ず平面となります。

 

これは

 

y=a_1x_1 + a_2x_2

 

という関数について、x_1Δx_1だけ増えるとya_1Δx_1だけ増え、x_2Δx_2だけ増えるとya_2Δx_2だけ増えるということが、常に成り立っていることを表しています。

 

当然この点も正比例の拡張だけあって、似たような性質を持ち合わせているというわけです。

 

これはΔx_1Δx_2を同時に増やしても構いません。単に個々の増加が合わさって、まとめると

 

Δy=a_1Δx_1 + a_2Δx_2

 

となっているのです。

 

逆のこの式からスタートした場合は、一方のΔx0と置いて、片方を増やしてやれば知りたいaの値が分かります。

 

計算例

 

y=x_1 + 2 x_2において、

 

(x_1,x_2)=(1,1)とすればy =1+2= 3です。

(x_1,x_2)=(3,1)とすればy=3 + 2 =5です。

(x_1,x_2)=(1,3)とすればy=1 + 6 = 7です。

(x_1,x_2)=(3,3)とすればy= 3+6 = 9です。

 

Δx_1=2Δy=5-3=2

Δx_2=2Δy=7-3=4

 

これらの結果を見れば

 

Δy=a_1Δx_1 + a_2Δx_2

 

a_1 = 1であり、a_2=2であることは明白です(片方をだけを変化させた結果)。念ののために同時に変化させた結果を見ましょう。

 

Δx_1=2Δx_2=2Δy=9-3=6

 

個々に変化させた時の和になっています。

 

 

多入力(多次元)の微分

はじめに

微分の章では「微分は線形近似dy = f'(x)dx」というのをかなり強調しました。そして普段は濫用される「微分・導関数・微分係数」についても、わざわざ区別して言いました。

 

更に線形代数の章では、正比例の拡張(一般形)として\bf y = Axあるいはy = \bf a^Txがあるという話をしました。

 

これらを強調したことのありがたみは、実は多入力の微分(あるいは多次元の微分)を考えるときになって初めて理解できます。そしてこれらを理解することは、機械学習の分野で数式に立ち向かう上では「必ず」必要です。

 

では本題に入ります。

 

多入力関数の微分(全微分)

正比例関数y = axの勾配はどストレートにaであることを見ました。そして一般的なy=f(x)では、微分を考えた時のdy = f'(x) dxという世界におけるf'(x)が勾配と呼ばれるのでした。

 

さて、多入力の関数f(x_1,x_2)を考える上でも、同じように「微分」の世界を考えて、勾配を見ていきたいと思います。その前に、やはり1入力のときと同じように増分から入りましょう。線形代数の章で最後にグラフを見ました。あの結果の通り、y = a_1x_1 + a_2x_2という線形関数においては、その増分Δy

 

Δy = a_1Δx_1 + a_2Δx_2

 

と表記できます。正比例同様、これはどのような大きさのΔxを取ってもいつでも成り立っており、これがグラフが平面である理由でした。

 

さあ、次はもっと一般の多入力関数f(x_1,x_2)を見ていきます

例としてf(x_1,x_2) = x_1^2 + 2x_1x_2 - x_2^2を見ておきましょう。これだけでも何か複雑な曲面になっていそうです。

 

f:id:s0sem0y:20170703040741p:plain

 

さて微分dyとは線形近似のことだと言いました(1入力では正比例近似)。そしてそのアイデアの根幹は「局所的に見る」というものです。上記の関数も局所的に見てみましょう。

 

f:id:s0sem0y:20170703042131p:plain

 

 

局所的に見たら平面的に見えます。微分への扉が少し開いたということです。

さあ。増分Δdの形に置き換え

 

dy = a_1dx_1 + a_2dx_2

 

としてやりましょう。更に1入力の時と同様に、x_1,x_2の位置によってa_1a_2の値は変わってくるはずです。従って

 

dy = a_1(x_1,x_2)dx_1 + a_2(x_1,x_2)dx_2

 

としておくべきでしょう。もしもこの係数aたちが、特にxに依存することが無いならば、それはそれでラッキーだったということです。それがハッキリするまでは依存することにしておきましょう。

 

このdyのことを全微分と呼びます。

 

 

多入力関数の導関数(偏導関数)

普通の線形の式

 

y = a_1x_1 + a_2x_2

 

においては、Δx_1だけ増加したらΔy=a_1Δx_1であり、Δx_2だけ増加したらΔy = a_2Δx_2であり、同時に増加したら、こいつらの和

 

Δy = a_1Δx_1 + a_2Δx_2

 

で表されることを述べました。更にa_1を知りたいのであればΔx_2=0としてΔx_2だけ変化させれば知ることができるのを見ました。従って一般の関数y = f(x)を変化させた場合の全微分(線形近似)

 

dy = a_1(x_1,x_2)dx_1 + a_2(x_1,x_2)dx_2

 

に関しても同じことが言えます(ただし局所的な世界でのみ)。つまり局所的な世界のa_1を知りたいのならばdx_2=0としてしまい、

 

dy = a_1(x_1,x_2)dx_1

 

を考えることにするのです。これでa_1を求められる形になっています(もはやa_1が傾きの一入力正比例関数に見える)。ここで

 

\displaystyle \frac{dy}{dx_1} = a_1(x_1,x_2)

 

として求まるわけですが、元々の関数がy = f(x_1,x_2)という2入力の関数であったわけで、今は便宜的に局所的な近似を行い、しかも片方の変数のことを完全に無視しています。そのことを忘れないためにもdの記号を\partialに変更し

 

\displaystyle \frac{\partial y}{\partial x_1} = a_1(x_1,x_2)

 

と書きます。あるいはa_1(x_1,x_2)y=f(x_1,x_2)の全微分に関して、x_1に着目していることを明示して、f'_{x_1}(x_1,x_2)と表記して

 

\displaystyle \frac{\partial y}{\partial x_1} = f'_{x_1}(x_1,x_2)

 

と書き、このf'_{x_1}(x_1,x_2)のことをx_1による偏導関数と呼びます。また、f'_{x_1}(c,d)のように具体的に場所が決まっている時には偏微分係数と呼びます。

 

 

f'_{x_2}(x_1,x_2)に関しても同様の手続きをすることで求めることができます。また、f'_{x_1}などを求めることを「偏微分する」と言うことが多いです。

 

 

 

具体的な計算

 

f(x_1,x_2) = x_1^2 + 2x_1x_2 - x_2^2

 

f'_{x_1}(x_1,x_2)=\frac{\partial y}{\partial x_1} を求めてみます。

 

記号の形は変わっていますが、x_1(だけ)を変化させて、yの変化がどれくらいかを見積もればよかったのでした。ここではもはやx_2の方は単なる定数であり、

 

f(x_1,d) = x_1^2 + 2dx_1 -d^2

 

です(慣れれば別に定数で置く必要はない)。勝手に定数で置いていること以外は単なる微分する操作と同じであり、

 

f'_{x_1}(x_1,d) = 2x_1+2d

 

となります。dは元に戻してやりましょう。

 

f'_{x_1}(x_1,x_2)=2x_1+2x_2

 

となります。

 

これは一般的にはx_1の偏導関数の具体的な値(偏微分係数の値)が、x_2の値をどこで固定するかにも左右されるということです。

 

 

(おまけ)接平面の方程式

微分が線形近似となっているので、全微分という概念は曲面に対して局所的に平面で近似を行います。これまでの話の通り、y = f(x,y)の全微分は以下

 

dy = f'_{x_1}(x_1,x_2)dx_1 + f'_{x_2}(x_1,x_2)dx_2

 

で表されます。x_1=cx_2=dの点における座標原点は(x_1,x_2,y) = (c,d,f(c,d))となっており、この局所的な座標上でdx_1,dx_2を、局所的な範囲を飛び出て使えるようにしてやれば、

 

y - f(c,d) = f'_{x_1}(x_1,x_2)(x_1-c) + f'_{x_2}(x_1,x_2)(x_2-d)

 

と表すことができます。これは全く接線の方程式の話と同様ですね。

 

勾配

多入力1出力の線形関数を

 

y = \bf a^Tx

 

と書いたことを思い返せば、y = f(x_1,x_2)も似たような便利な記法にできるはずです。その手続きは、まず以下のように全微分を求めることから始まります。

 

dy = f'_{x_1}(x_1,x_2)dx_1 + f'_{x_2}(x_1,x_2)dx_2

 

こうしてしまえば、局所的には単なる線形関数と同じ扱いができます。従って、局所的な新たな変数dx_1,dx_2f'_{x_1},f'_{x_2}を明確に区別した形式

 

dy = (f'_{x_1},f'_{x_2}) \left( \begin{array}{c} dx_1 \\ dx_2 \end{array} \right)

 

という形式にして、 f'({\bf x})=(f'_{x_1},f'_{x_2}) というベクトルとd{\bf x} = (dx_1,dx_2)というベクトルを考えてやることで

 

dy = f'({\bf x)^T} d{\bf x}

 

という表記にしてやることができます。

これがy=f({\bf x})の導関数であり、ようやく勾配が求まりました。多入力では

 

\displaystyle f'({\bf x)^T}=(\frac{\partial y}{\partial x_1}, \frac{\partial y}{\partial x_2})

 

が勾配(ベクトル)になります。

 

勾配とはdy = f'(x)dxの形にしたときのf'(x)が勾配に相当するものだとずっと言ってきました(線形近似し、線形代数の表記だからこそ感じることのできる一貫性です)。この勾配は要するにd\bf xを増やした時にdyが増える量を最大にする方向を表しています。 

 

機械学習では

 

\displaystyle \frac{L}{d{\bf w}} 

 

という表記が頻繁に出るかもしれません。これは導関数のことであり、微分するという操作を表し、かつ勾配のことを指しています。

 

特に機械学習では勾配という意味が合いが強く、L({\bf w})の増加量(すなわちdL)を最大にする方向を求めています。実際にはLを減少させるのが機械学習の目的であることが多いため、 -\frac{L}{d{\bf w}}と方向が反転して使われます。

 

多変数における便利な記法2

あるいは、 f'({\bf x})=(f'_{x_1},f'_{x_2}) の成分に関して

 

\displaystyle f'({\bf x})=(\frac{\partial y}{\partial x_1},\frac{\partial y}{\partial x_2})

 

の表記を使っておいて、\frac{dy}{dx} = \frac{d}{dx}yと分離して考えたように

 

\displaystyle f'({\bf x})=(\frac{\partial y}{\partial x_1},\frac{\partial y}{\partial x_2})=(\frac{\partial }{\partial x_1}y,\frac{\partial }{\partial x_2})y ={\bf ∇}y

 

{\bf ∇} = (\frac{\partial }{\partial x_1},\frac{\partial }{\partial x_2})

 

とした演算子を導入することもあります(∇はナブラと読む)。演算子の導入は便利だからこそされるわけであって、機械学習ではほとんどこの表記はされることはありません(する意味がない。便利な記法1で十分です。けどPRMLはたまに出てくる。)。

 

 ベクトル解析という分野では、このような演算子を導入することによって普通の微分(全微分)以外の色々な微分を考えることができるようになります。

 

スポンサーリンク

   

 

発展:多入力多出力関数の微分

 

多入力多出力を線形近似から作る

更に線形代数の表記の恩恵を受ける時が来ました。線形代数の章では多入力多出力の線形関数は、多入力1出力の線形関数を並べて実現できることを見ました。

従って、{\bf y} = f({\bf x})なる多入力の一般的な関数があった場合は、これらの出力を1つ1つ考えて

 

y_1 = f_1({\bf x})

 

y_2 = f_2({\bf x})

 

と並べてから、全微分を内積の形式で表して

 

dy_1 = f_1'({\bf x)^T} d{\bf x}

 

dy_2 = f_2'({\bf x)^T} d{\bf x}

 

と並べることで、d{\bf x}で括って

 

d{\bf y} = \left( \begin{array}{c} f_1'({\bf x)^T} \\ f_2'({\bf x)^T} \end{array}\right) d{\bf x}

 

と表記してやることができます。

 

従って一般的に{\bf y} = f({\bf x})という関数に対して、微分(線形近似)を行った上で、相性の良い線形代数の表記を使った場合、

 

g: \bf x \mapsto y'(x)

 

という形式の関数(導関数)を考えることができます。この多入力多出力関数の導関数は「多入力一出力」の偏導関数ベクトルを並べたものになっているので、行列の形をしています。つまり、多入力多出力の導関数は、ベクトルを引数に行列を返す関数となっています(従って多入力多出力では「勾配行列」になる)。

 

もしも関数が全領域で微分可能ならば、このようにとりあえず表記が便利な線形代数の世界で語ることのできる形で局所的に色々議論してから、議論する場所を少しずつずらして網羅してしまえば良いということになります(勿論、どうすれば網羅できるのかが更なる課題になるが)。

 

 

ベクトル場とスカラー場

多入力1出力の関数をスカラー場、多入力多出力の関数をベクトル場と表現することがあります。特に物理学や工学で使われる言葉です。場とは何らかの作用が空間的に連続的に起こっているときの影響あるいは影響を受けている空間のことを指して言います。

 

スカラー場とは、空間上の各点ごとにその影響が1つの値(スカラー値)として出てくる場のことです。例えば地図上の山の高さはスカラー場です(場所を指定したら高さが出てくる)。これは今まで引数を2つ取り、1つの値を第3の軸で表現してきた通り、多入力1出力のことになります。

 

f:{\bf x} \mapsto y

 

f:id:s0sem0y:20170703040741p:plain

 

 

一方ベクトル場は、空間上の各点ごとにその影響が複数の値(ベクトル値)として出てくる場のことです。例えば川に対して場所を指定すると、場所ごとに水の流れる方向と大きさ(ベクトル)が得られ、ベクトル場だと考えることができます。

これは複数の値を引数に複数の値を出力する関数と見ることができます。

 

f:{\bf x} \mapsto \bf y

 

 

ベクトル解析へ

y = f(\bf x)における導関数がf':{ \bf x} \mapsto \frac{dy}{d{\bf x}}というベクトル場になっていることに着目してみましょう。これは勾配を求める手続きでした。

 

この導関数は言わば勾配であって、他にも綺麗な体系が作れるのではないかということで、色々なことがベクトル解析で調べられました。実はこれが演算子{\bf ∇ }= (\frac{\partial }{\partial x_1},\frac{\partial }{\partial x_2})]の導入で違う話へ発展していきます。

 

まず勾配は\bf ∇をスカラー値yに作用させることでした。

 

{\bf ∇}y = (\frac{\partial }{\partial x_1}y,\frac{\partial }{\partial x_2}y)

 

これを勾配(grad)と呼んでいたわけです。

 

今度は、\bf ∇がせっかくベクトルの形をしているので、ベクトルに作用させても良さそうです。ベクトルとベクトルの計算では、内積がすぐ思いつくでしょう。

 

{\bf ∇}\cdot{\bf y} = \frac{\partial }{\partial x_1}y_1+\frac{\partial }{\partial x_2}y_2

 

これを発散(divergence)と呼びます(私は湧き出しの方が好きですが)。

 

もう1つがベクトルとベクトルの外積という計算になります。

 

{\bf ∇}\times {\bf y} = (\frac{\partial }{\partial x_2}y_1 - \frac{\partial }{\partial x_1}y_2,\frac{\partial }{\partial x_1}y_2) - \frac{\partial }{\partial x_2}y_1

 

今は2次元でやっていますが、物理では3次元で、数学ではもっと高次元でやります。

 

 

 

ベクトル解析 (ちくま学芸文庫)

ベクトル解析 (ちくま学芸文庫)

 

 

 

 

最後に

正比例・微分・線形代数

以下のようなストーリーによって話を進めてきました。

 

f:id:s0sem0y:20170703183657p:plain

 

機械学習の場合、ベクトル解析に入る手前(あるいはちょっと入ったくらい)の知識でひとまず十分でしょう。その後の数学の取り回しは、機械学習に触れながら実践的に学んでいけばよく、それができるだけの素養は、もしもここまで読破したのであれば付いていると思います。

 

確率・統計

機械学習の数学で、1つごっそり抜けているとすれば「確率・統計」に関することが足りていないと言えます。ただガチガチの確率モデル出ない限りは、「●●確率」が何のことか少し覚えるくらいで済むでしょう(大抵、確率を出力しているとみなしている程度の話で、実は確率の理論は後付の方が多い。ニューラルネットもそう)。

 

基本的な手法の多くは、微分と線形代数を使うことができれば、その延長の計算だと考えて進めることができます。ただし生成モデルなどをやる場合はしっかり確率の計算や考え方などを抑えて置いたほうが良いです。

 

s0sem0y.hatenablog.com

s0sem0y.hatenablog.com

 

 

 

 

機械学習の教科書 (数式ベース)

 

 

標準的に使われているのは、機械学習ならば以下。

自然言語のことが具体例として出てきますが、機械学習の話題としては広く一般的な内容を取り扱っています。数式も比較的丁寧に展開してくため、手頃な難易度になっています。

言語処理のための機械学習入門 (自然言語処理シリーズ)

言語処理のための機械学習入門 (自然言語処理シリーズ)

 

 

深層学習ならば以下の教科書。

ディープラーニングの基本を数式ベースで抑えるための本であり、実装をすぐにできるものでもなければ、最新の手法が載っているわけでもありません。しかし基本はいつでも大事です。

深層学習 (機械学習プロフェッショナルシリーズ)

深層学習 (機械学習プロフェッショナルシリーズ)

 

 

 

実装ベースの教科書

数式を疎かにせずに、かつコードを書きながらということになればもっと違う良い本もあります。

 

TensorFlowやKerasを使っていくならば

s0sem0y.hatenablog.com

  

NumPyでもっとスクラッチしていくならば

s0sem0y.hatenablog.com

 

 

 

 

数学関連記事

 

s0sem0y.hatenablog.com

s0sem0y.hatenablog.com

s0sem0y.hatenablog.com

s0sem0y.hatenablog.com

s0sem0y.hatenablog.com