ナード戦隊データマン

データサイエンスを用いて悪と戦うぞ

機械学習の数学の基礎: 最急降下法

「勾配の考えを理解できないアホは機械学習を諦めろ」的な発言を聞いたことがあります。といっても、それが基礎だというなら学んでおいて損はないでしょう。

前提として必要な知識は何なのか

線形代数微分積分」を知っていれば問題なく理解できますが、実際のところ、最急降下法を理解するのに必要な知識は以下だけです:

  • 偏微分
  • ベクトル
  • 内積
  • 関数
  • 数列の和
  • 行列とベクトルの積

全体像からつかもう

まず、機械学習とは、「特徴量」と「正解の値」の2つのペアからなるデータから学習し、新しいデータに対して予測を与えるような関数を生成するアルゴリズムのことです。

例えば「住宅価格の予測」という問題を考えた時、特徴量は「部屋の数」「二階があるかどうか」「部屋の広さの合計」「プールがついているか」などのことです。それに対し、正解の値とは「住宅価格」のことです。つまり、これらのデータからモデルを作成すると「特徴量がわかれば、住宅価格が予測できる」というような関数が作られます。

特徴量をA、正解の値をbとしたとき、例として「ある関数h(A)とbの差の大きさ」のことを「損失」とします。損失が少なければ少ないほど、関数hは"訓練データ"においてyを予測する能力を身につけることになります。

つまり、機械学習アルゴリズム(教師あり)の目的は、データ(A, b)が与えられた時、L = (h(A) - b)2を最小化するようなhを見つけることです。このhを見つける方法として、「最急降下法」が使われます。

単純なモデル

ここでのモデルは、特徴量と重みの線型結合によって損失関数を定義します。

L(x) = ||(Ax - b)||^2

言い換えると、この場合の「コスト関数の最小化」とは、「L(x)が最小となるパラメータベクトルxを見つけること」を意味しています。これは以下のように表すことができます。

L(x) = (<a_i, x> - b_i)2 + ... + (<a_m, x> - b_m)2

ただし、<x,y>は内積です。

ヒルライミングによる最適化

学習とは、前述のL(x)のxを更新する作業のことです。以下のようなアルゴリズムにより、xは更新されていきます:

init(x);
忍耐が続く限り次を繰り返す:
    x := x + 変化;
return w;

この「変化」は、L(x)ができるだけ少なくなるようにxを更新することを意味します。つまり、ループが回るごとに関数hが改善されていきます。

勾配

素朴な疑問は、「その"変化”の値をどう決めるのか」ということです。

f([x_1,...,x_n])の勾配とは、関数fを各変数x_iで偏微分し、ベクトルで表示したものを意味します。

∇f = [∂f/∂x_1, ..., ∂f/∂x_n]

勾配は、簡単に言うと「水平面に対する傾きの度合い」のことなので、0より大きければ増加しており、0より小さければ減少しています。そのため、増加している点では「引く」ことでxが改善され、減少している点では「足す」ことでxが改善されます。

つまり、損失関数Lの勾配∇L(x)を「変化」の値に利用することで、関数hを改善していくことができます。

最急降下法

さて、前述の考えをアルゴリズムとして書くと、以下のようになります:

σを小さな値で初期化;
init(x);
忍耐が続く限り、次を繰り返す:
    x := x - σ(∇L(x));
return x;

σは学習係数と呼ばれるものです。σが大きい場合、学習は速いですが、雑になります。σが小さい場合、学習は遅くなりますが、細かくなります。十分に学習に時間がかけられる場合は、σは小さな値で初期化します。

ちなみに、Lの勾配∇L(x)は、

∇L(x) = ∑2(<a_i, x> - b_i)a_i

と表されますが、損失関数が異なれば当然、勾配も変わります。

え、これだけなの?

基本的な数学についての説明なので、実際はもっと細かい話があります。例えば、正則化、多層ニューラルネットワーク、ソフトマックス、クロスエントロピー、活性関数、オンライン学習等については触れていません。

しかし、これらの基本はそれほど大げさなものではないとわかると思います。もしわからない点があれば、単に前提知識に書いたことを知らないだけです。