「はじめての機械学習」-数学知識編 第3版

「はじめての機械学習」シリーズの単回帰分析編です。
このシリーズは、機械学習に初めて取り組むときに、学んだことをシリーズ化してみました。
これから、機械学習に取り組みたいと考えている方のお役にたてれば幸いです。

0. シリーズのコンテンツ


1. 必要な数学の基礎…


機械学習において数学の微分・積分、ベクトルと行列、統計、線形代数を学ぶ必要があるのは、その理論的な基礎と実践的な応用においてこれらの概念が重要な役割を果たすからです。以下では、それぞれの数学の分野が機械学習においてなぜ重要なのかをステップバイステップで説明します。

ステップ1: 微分・積分

微分は、関数の傾きや変化率を測定するための概念です。機械学習では、最適化や勾配降下法などのアルゴリズムが広く使用されています。これらのアルゴリズムは、関数の最小値や最大値を見つけるために微分を使用します。また、微分を使って誤差関数を最小化するためのパラメータの更新も行います。したがって、微分の理解は機械学習アルゴリズムの理解に欠かせません。

機械学習(教師あり学習)では、実際の値と予測値の差(誤差)が小さくなる関数を見つけることです。
この関数は、入力値に重みを掛け合わせる式で表現されます。この重みをモデルとして作ることともいえます。
単回帰分析は、入力が1つなので単純ですが、重回帰分析では、複数の入力を扱うため、引数毎に微分を行う偏微分という考え方も必要になります。
実際には、Pythonの関数を使うだけなので、数学の微分とか偏微分が分からなくても大丈夫です。

積分は、関数の面積や確率密度を計算するための概念です。機械学習では、確率密度関数や累積分布関数を使用してデータの確率分布をモデル化する場合があります。また、積分を使って期待値や条件付き確率を計算することもあります。これらの概念は、ベイズ統計や確率モデルに基づく機械学習アプローチにおいて重要です。

ステップ2: ベクトルと行列

ベクトルと行列は、データの表現や変換において重要な役割を果たします。データは通常、ベクトルや行列の形式で表されます。例えば、画像データはピクセル値の行列として表現され、テキストデータは単語のベクトルや単語の出現頻度の行列として表現されることがあります。

機械学習では、データの特徴量を抽出するために行列演算が使用されます。特徴量行列と呼ばれるデータ行列を用いて、次元削減や特徴量の選択を行います。また、ベクトルや行列を用いた線形代数の操作を通じて、機械学習モデルの訓練や予測を行います。例えば、最小二乗法を使用して回帰モデルを学習する場合、行列の操作を通じてモデルのパラメータを最適化することができます。

ステップ1で説明した例で、重回帰分析では、、誤差を表す方法の1つに、2乗誤差を最小化することで、モデルを作る場合では、[1行N列][N行1列]の行列積で、複数の入力を行列としてとらえることで、複数パラメータの重みをまとめて扱うことができます。
Pythonでは、入力データをCSV形式で入力することで、あとは、Pythonのライブラリを呼び出すだけで、このあたりのことは内部で処理できるので、理解が浅くても、手順がわかればある程度は処理できます。

ステップ3: 統計

統計は、データの収集、要約、および分析において不可欠な役割を果たします。機械学習においては、データセットの特性や分布を理解するために統計的手法が使用されます。例えば、平均、分散、相関係数などの統計量は、データの要約や特徴量の選択に使用されます。

また、機械学習モデルの評価や信頼性の評価にも統計的手法が使用されます。交差検証やブートストラップ法などの統計的手法を用いて、モデルの性能を評価することができます。さらに、統計学の基本的な概念は、確率モデルや統計的学習アプローチの理解にも役立ちます。

ステップ4: 線形代数

線形代数は、機械学習において広範な応用があります。行列の演算や線形方程式の解法、固有値や特異値分解などの概念は、機械学習モデルの理解や最適化に必要です。

例えば、主成分分析(PCA)は、データの次元削減や特徴量の抽出に使用される一般的な手法です。PCAは、データ行列の固有値と固有ベクトルを計算することに基づいています。また、線形回帰やロジスティック回帰などのモデルは、線形方程式を解くことによってパラメータを推定します。これらの概念を理解することで、機械学習アルゴリズムの背後にある数学的な原理を理解することができます。

以上のように、微分・積分、ベクトルと行列、統計、線形代数は、機械学習において理論と実践の両方において重要な役割を果たします。これらの数学の概念を学ぶことで、機械学習アルゴリズムの理解や開発、データ解析の能力を向上させることができます。数学の基礎をしっかりと理解することは、より高度な機械学習手法や応用に進むための基盤を築くことにつながります。

とはいうものの、機械学習のプログラムの作り方を学ぶ上で、数学の理解が十分でなくても、Pythonで利用できるライブラリを組合わせることで、ある程度流れに沿って作れば、重回帰分析くらいはつくれそうですので、心配しないでください。

2. 演繹法的に説明してみます。


演繹法的に説明すると、機械学習における数学の学習の必要性は次のように述べられます。
前提1: 機械学習では、データとアルゴリズムを組み合わせて予測モデルを構築します。
前提2: 最適な予測モデルを構築するためには、データの特徴を正確に理解し、モデルのパラメータを最適化する必要があります。

  1. 数学の微分・積分の理解が必要です。
    • アルゴリズムの最適化には微分を使用することが一般的です。微分を用いて関数の最小値や最大値を求めることができます。
    • 機械学習では、関数の最小値を求めることで誤差関数を最小化し、モデルのパラメータを更新します。
  2. ベクトルと行列の理解が必要です。
    • データはベクトルや行列の形式で表現されることがあります。例えば、画像データはピクセル値の行列として表現されます。
    • ベクトルや行列を用いた行列演算は、特徴量の抽出やデータの変換に使用されます。特徴量行列を操作することで、次元削減や特徴量の選択を行います。
  3. 統計の理解が必要です。
    • 機械学習では、データの特性や分布を理解するために統計的手法が使用されます。平均や分散などの統計量を使用してデータを要約します。
    • 統計的手法を用いてモデルの評価や信頼性の評価を行います。統計学の概念は確率モデルや統計的学習アプローチの理解に役立ちます。
  4. 線形代数の理解が必要です。
    • ベクトルや行列の操作には線形代数が使用されます。特に、行列の演算や線形方程式の解法は重要です。
    • 主成分分析や線形回帰などの機械学習手法では、線形代数の概念を使用してモデルのパラメータを推定したり、特徴量を抽出したりします。

以上のように、演繹法的に説明すると、微分・積分、ベクトルと行列、統計、線形代数の数学の概念を学ぶことは、データの解析やモデルの構築において不可欠であり、より高度な機械学習の理解や応用に進むための基盤を提供します。

3. 知識のまとめ


機械学習に取り組むために役立つと考える数学知識を列挙します。
その意味を、きちんと理解するためには、きちんと勉強することをお勧めしますが、以前に少しやっていた方は、頭を整理することで、思い出せることも沢山ありますので、参考にしてみてください。

3.1. 線形代数

3.1.1. 【スカラー、ベクトル、行列とは…】

スカラー:通常扱う数値
ベクトル:スカラーを直線状に並べたもので、縦に並べたものと、横に並べたものがあります。
    Pythonでは、Numpyの1次元配列を用いて表現できます。
行列:スカラーを格子上に並べたものです。
   水平方向のスカラーの並びを行、垂直方向のスカラーの並びを列とします。
   Pythonでは、Numpyの2次元配列を用いて表現できます。
テンソル:スカラーを複数次元に並べたものです。
    スカラー、ベクトル、行列を含みます。
     スカラー=0階のテンソル
     ベクトル=1階のテンソル
     行列=2階のテンソル
     3次元配列=3階のテンソル(N次元の場合、N階のテンソル)

3.1.2. 【ベクトル内積】

ベクトルの相関を求める時に使用します。
Pythonでは、2つのベクトルの内積を求めるには、次のように記述します。
  例)np.dot(a,b)

3.1.3. 【ベクトルのノルム】

ベクトルの大きさを示す量です。
AI分野では、「L2ノルム」と「L1ノルム」があります。
L2ノルム(||x||2):ベクトル各要素の2乗和を行い、その平方根をとります。
        Pythonでの書き方は、np.linalg.norm(a) # aは、Nampyでのベクトル
L1ノルム(||x||1):ベクトル各要素の絶対値の総和を計算します。
        Pythonでの書き方は、np.linalg.norm(a,1) # aは、Nampyでのベクトル

一般化したノルムLpをディープラーニングの「正則化」で利用します。
※正則化:必要以上のネットワークの学習が進むことをパラメータで調整すること

3.1.4. 【行列積】

行列同士の掛け合わせを行います。機械学習では、計算を効率的に行うために使用します。
前の行列の行X後ろの行列の列の結果を、行・列の位置に設定する。
 条件:(M行,N列)(m行,n列)の場合、N=mが成り立つ事。出来上がる行列はM行n列となる
Mとnが1の場合は、演算後の値は、スカラーになります。
このような特徴を使いながら、多数の入力値をベクトルデータ化して与えて、行列演算として処理を行います。
その結果をスカラーとして取得して、その値の動きを使って様々な予測に利用していくことがあります。

3.1.5. 【アダマール積】(要素ごとの積)

行列の要素ごとの積とは、2つの行列の要素を掛け合わせたものです。
Pythonでは、a*bで表現できます。
条件は、2つの行列が同じ形であることだけです。
同様に、和算(+)、減算(-)、除算(/)でも行うことができます。

3.1.6. 【転置】

行列の行と列を入れ替える行列操作です。

 例)Pythonにおける転置操作例
    import numpy as np
    a = np.array([[1,2,3],[4,5,6]])
    print(a.T)

転置を使うと行列積が計算できる場合があります。
この特徴を使うことで、機械学習において、データの複雑な特徴を捉え、またデータの次元を操作することが可能となります。
機械学習での次のようなあ応答があります:

  • 特徴表現:
    行列積は新たな特徴を生成するための手段として使用されます。
    例えば、深層学習のネットワークでは、入力行列(データ)と重み行列の積が新たな特徴を生成する層として作用します。
    これにより、ネットワークは複雑な特徴を学習できます。
  • データの圧縮:
    行列積は、データの次元を低減するのにも使われます。
    主成分分析(PCA)などの次元削減テクニックでは、元のデータ行列とその主成分(固有ベクトル)との積を取ることで、データをより低次元の空間に投影します。
  • 情報のエンコードとデコード:
    自己符号化器のようなモデルでは、行列積は情報のエンコード(圧縮)とデコード(再構成)の両方で使用されます。

3.1.7. 【行列式・逆行列】

機械学習における、行列式と逆行列の役割は、次のようなことがあります。

  • 行列式:
    行列式は行列が持つ一部の性質を示します。
    特に、行列式の値が0であるとき、その行列は「特異行列(singular matrix)」と呼ばれ、逆行列が存在しないことを示します。
    逆行列が存在しない行列に対して逆行列を計算しようとすると問題が発生するため、行列式はそのような状況を回避するためのチェックとして役立つことがあります。
    また、行列式は行列が表す線形変換における”伸縮度合い”を表すため、特徴空間の変換やデータの分布を考える際にも参考にされることがあります。
  • 逆行列:
    逆行列は数多くの機械学習アルゴリズムにおいて重要な役割を果たします。
    逆行列は線形代数方程式(Ax = b)の解を求める際に用いられます。
    特に線形回帰の最小二乗法の解を直接求める際には逆行列が用いられます。また、正則化手法の一つであるリッジ回帰では、逆行列を用いて解を求めることが可能です。

これらの役割を理解しておくことは、機械学習アルゴリズムの動作を理解し、より適切なモデル設定やデータ処理を行うために重要です。

 ・[単位行列]
   左上から右下に1が並び、その他の要素が0の正方行列です。
   単位行列は、行列の前後に行列積を掛けても行列は変化しない特徴があります。
   生成方法:
     import numpy as np
     np.eye(2)  # 2×2の単位行列を生成

 ・[逆行列]
   逆行列とは、行列に掛けると単位行列になる行列です。
   
 ・[行列式]
   行列によっては、逆行列が存在しない場合がり、その判定を行列式により判定できます。
   行列式が0の場合に、逆行列は存在しません。
   行列式の求め方:
     import numpy as np
     a = np.array([[1,2],
           [3,4]])
     print(np.linalg.det(a))  # 行列式の値=-2.0
     b = np.array([[1,2],
           [0,0]])
     print(np.linalg(b))    # 行列式の値=0
   逆行列の求め方:
    逆行列が存在する場合に次の方法でPythonで逆行列を生成できます。
    PythonのNumpyのlinalg.inv()関数で簡単に求めることができます。
     import numpy as np
     a = np.array([[1,2],
           [3,4]])
     print(np.linalg.inv)   # 逆行列
     

3.1.8. 【線形変換】

機械学習における線形変換は、データの特徴量や表現を変換するために使用される重要な操作です。線形変換は、入力データのベクトルに対して行列の積を適用することで実現されます。以下に、線形変換の主な意味を説明します。

  • 特徴空間の変換:
    線形変換は、特徴空間を変換するために使用されます。
    特徴空間は、データの属性や特徴を表すベクトル空間です。
    線形変換を用いることで、特徴空間の次元を変更したり、特徴のスケーリングや正規化を行ったりすることができます。
    たとえば、主成分分析(PCA)では、線形変換を使用してデータをより低次元の空間に射影し、特徴の相関を最小化することでデータの主要な情報を抽出します。
  • データの前処理:
    機械学習では、データの前処理が重要です。
    線形変換は、データのスケーリングや正規化、欠損値の処理など、データの前処理手法の一部として使用されます。
    たとえば、データの各次元を平均0、分散1に変換するために、線形変換である標準化(Standardization)を使用することがあります。
  • 特徴量の抽出:
    線形変換は、特徴量の抽出や表現学習にも使用されます。
    線形変換を用いることで、元の特徴空間から新たな特徴空間を構築することができます。
    このような特徴空間の構築によって、データの重要な特徴やパターンを抽出しやすくなります。
    たとえば、線形判別分析(LDA)では、線形変換を使用してクラス間の分散を最大化し、クラス内の分散を最小化することで、データのクラス分離を促進します。
  • 線形モデルと最適化:
    線形変換は、線形モデルや最適化手法とも密接に関連しています。線形モデルは、入力データとパラメータの線形結合に基づいて予測を行います。この線形結合は、線形変換として解釈できます。線形モデルのパラメータを最適化するための最小二乗法や勾配降下法といった最適化手法では、線形変換が使用されます。

線形変換は、特徴空間の変換やデータの前処理、特徴量の抽出、線形モデルの構築や最適化など、機械学習のさまざまな側面において重要な役割を果たします。これらの変換は、データの表現やモデルの性能向上に寄与する有用な手法となっています。

3.1.9. 【行列の固有値】

機械学習において、固有値は、次のような役割がありますので、理解することをお勧めします。

  • 特徴量の選択:
    固有値は、行列が持つ特徴量の情報を提供します。
    行列の固有値は、行列の性質や特徴を理解するための重要な指標となります。
    特に、固有値の絶対値の大きさは、行列がどれだけ変換を強くかけるかを示し、固有ベクトルはその変換の方向を示します。
    機械学習では、データの次元削減や特徴量の選択に固有値を使用することがあります。
    固有値の絶対値が大きい固有ベクトルに対応する特徴量は、元のデータの変動の大部分を表す可能性が高くなります。
  • 行列の対角化:
    固有値は、行列を対角行列に変換するために使用される重要な要素です。
    対角行列に変換することで、行列の操作や解析が簡単になります。
    行列の対角化は、固有値と固有ベクトルを使用して行われます。
    対角化により、行列の累乗や指数関数の計算、行列の逆行列の求め方などが容易になります。
  • 状態遷移と動的モデル:
    固有値は、状態遷移行列や動的モデルの安定性や挙動を分析するために使用されます。
    例えば、マルコフ過程や線形時間不変システムの状態遷移行列の固有値は、そのシステムの安定性や長期的な挙動を示す重要な情報となります。
    固有値が1よりも小さい場合、システムは安定しており、長期的な振る舞いを持ちます。
  • 次元削減と主成分分析:
    固有値は主成分分析(PCA)などの次元削減手法において重要な役割を果たします。
    PCAでは、固有値と固有ベクトルを使用してデータを新しい座標系に変換し、データの分散を最大化する主成分を見つけます。
    固有値は、各主成分の寄与度や次元削減後のデータの情報量を示す指標として使用されます。

行列の固有値は、特徴量の選択や行列の対角化、状態遷移の解析、次元削減など、機械学習のさまざまなアプリケーションにおいて重要な役割を果たします。固有値の解析は、データの解釈やモデルの性能向上に寄与する有用な手法です。

Pythonで固有値の求め方

Numpy linalg.elg()関数からの戻り値配列の0番目で取得可能

  import numpy as np
  a = np.array([[1,2],
        [3,4]])
  v = np.linalg.elg(a)
  print(e[0])  # 固有値
  print(e[1])  # 固有ベクトル

3.1.10. 【固有ベクトル】

機械学習において、固有値は、次のような役割がありますので、理解することをお勧めします。

  • 特徴量の変換:
    固有ベクトルは、行列の線形変換における変換の方向を示します。
    特に、固有ベクトルに対応する固有値の絶対値が大きい場合、その固有ベクトルに沿ってデータが最も変換されます。
    この性質を利用して、固有ベクトルを使用してデータの特徴量を新たな座標系に変換することができます。
    主成分分析(PCA)などの次元削減手法では、固有ベクトルを使用してデータをより低次元の空間に射影し、データの情報を保持しつつ次元を削減します。
  • ノイズの除去:
    固有ベクトルは、データ行列や相関行列の固有ベクトルによってノイズや冗長性を特定するのに役立ちます。
    固有ベクトルに対応する固有値が小さい場合、それに対応する特徴量はノイズや冗長性を持つ可能性が高くなります。
    このため、固有ベクトルのランク付けや閾値処理を行うことで、ノイズの除去やデータの要約を行うことができます。
  • 状態遷移と動的モデル:
    固有ベクトルは、状態遷移行列や動的モデルの挙動や性質を示すのに使用されます。
    特に、固有ベクトルはシステムの安定性や長期的な振る舞いを表す重要な指標となります。
    固有ベクトルに対応する固有値が1よりも小さい場合、その固有ベクトルはシステムの安定な状態を表し、時間の経過とともに指数的に減衰します。
  • クラスタリングと分類:
    固有ベクトルは、クラスタリングや分類問題においてデータを分割するのに役立ちます。
    固有ベクトルを使用してデータを新たな座標系に変換することで、データの相対的な位置関係や構造を把握しやすくなります。
    これにより、クラスタリングアルゴリズムや分類器がデータをより効果的に分割し、グループ化することができます。

行列の固有ベクトルは、特徴量の変換やノイズの除去、状態遷移の解析、クラスタリングや分類など、機械学習のさまざまなタスクにおいて重要な役割を果たします。固有ベクトルの分析は、データの解釈やモデルの改善に貢献する有用な手法です。

Pythonで固有ベクトル値の求め方

Numpy linalg.elg()関数からの戻り値配列の0番目で取得可能

  import numpy as np
  a = np.array([[1,2],
        [3,4]])
  v = np.linalg.elg(a)
  print(e[0])  # 固有値
  print(e[1])  # 固有ベクトル


3.2. 微分

機械学習では、モデルのパラメータを調整するために、最適化アルゴリズム(多くは勾配降下法)が使われます。これらのアルゴリズムは、誤差関数(損失関数)を最小化するパラメータを探す際に微分を用います。微分は関数の変化率を測定し、誤差関数の最小値を効率的に見つける方向を示します。
このような目的のために、微分についてを少し整理しましょう。

【微分】

関数 y=f(x) において、xの変化量に対して、yの変化量を考える時、xの変化量を極限まで小さくしたときのyの変化量を Δy/Δx として、f'(x)と表し導関数と呼びます。f(x)からf'(x)を求めることをf(x)を微分すると言います。
1つの変数の関数に対する微分を常微分といいます。
この微分の意味は、関数f(x)の接線の傾きを表します。この傾きが0になる点を、極値といいます。

[微分公式]
  元の関数:f(x) = xr
  微分表記:’

  公式(1) 関数の微分:    f'(x) = rx(r-1)
  公式(2) 関数の和の微分:  (f(x)+g(x))’ = f'(x) + g'(x)
  公式(3) 関数の積の微分:  (f(x)g(x))’ = f(x)g'(x) + f'(x)g(x)

[連鎖律]
  複雑な関数も単純な関数を合成したという「合成関数」ととらえることができます。
  y=(x2+4x+1)2 → y=u2 と u=x2+4x+1  の合成関数と考えると。。。
  それぞれの関数の微分(導関数)を行い、掛け合わせることで、元の関数の微分を導き出せます。
  これを「連鎖律」といいます。
  ニューラルネットワークに大切な概念です。

【偏微分】

多変数関数を1つの変数で微分することを偏微分といいます。
AIでは、1つのパラメータの変化が全体に及ぼす影響を求めるために利用します。
実際に対象となる入力値が多数あるものを学習して、そこから予測を行う場合など、予測値と実際の差を最小にするための式(モデル)を導き出すため、各入力値への重みを求めることになります。
もちろん、重みだけではなく、入力値のスケールの調整も必要になりますが、多数の入力値の影響具合を調整することが、AIにおける学習ということともいえます。

複数の変数を持つ関数に対する1つの変数による微分を偏微分と呼びます。
偏微分を行う対象の変数以外は、定数として微分を行うことになります。

【全微分】

多変数関数の微小変化を全ての変数の微小変化により求めます。

[求め方]
  ①多変数関数を、各変数で偏微分を求める
  ②各変数の偏微分に、各変数の微小変化を掛ける
  ③②の総和を求める


AIにおいては、全微分を使い、予測を行います。

【多変数合成関数の連鎖律】

AIでは多変数の合成関数を扱いますが、連鎖律により各変数が関数に与える影響を求めることができます。

【ネイピア数】

ネイピア数とは、円周率πのように無限に桁が続く少数のことです。
ℯで表現します。
  y = exp(x) あるいは y = ℯx
特徴として、微分しても式が変わらないという性質があります。

[Pythonでの表現]
  import numpy as np
  print(np.e)  # ネイピア数
  print(np.exp(1)) # ℯの1乗

[自然対数]
  y = ℯx を左辺がxにすると
  x = loge y  # xはℯを累乗してyになる数

  y = loge x  # 自然対数

[Pythonでの表現]
  import numpy as np
  print(np.log(1))  # 1の自然対数