🎉

Deep Learning資格試験 機械学習モデル

2022/01/25に公開

はじめに

日本ディープラーニング協会の Deep Learning 資格試験(E 資格)の受験に向けて、調べた内容をまとめていきます。

線形回帰・非線形回帰

  • 学習種類:教師あり学習
  • タスク:予測問題
  • パラメータ推定:最小2乗法・最尤推定

特徴

  • 表現力の高いモデルに対して正則化すると、予測結果が滑らかになる。
  • 説明変数間に相関があると、良い予測ができない可能性がある。
  • 一般にモデルに入れる説明変数の数が多いほど、表現力が上がる。
  • ラッソ正則化において正則化係数を十分に大きくすると、いくつかの係数は完全に0になる。

ロジスティック回帰

  • 学習種類:教師あり学習
  • タスク:分類問題
  • パラメータ推定:最尤推定

尤度関数

尤度関数が最大となるようにパラメータを学習する。

\begin{aligned} \prod_n \left( p(y_n=1 | x_n)^{y_n} p(y_n = 0 | x_n)^{1-y_n} \right) \end{aligned}
  • 尤度関数は、データ数が多いとき、尤度は桁が非常に小さくなり、アンダーフローを起こす。
  • 尤度は積で表現されているため、勾配を求める際に面倒くさい。

対数尤度関数

\begin{aligned} \sum_n \left( y_n \log p(y_n=1 | x_n) + (1 - y_n) \log p(y_n = 0 | x_n) \right) \end{aligned}

p(y_n = 1 | x_n)は、出力\hat{y}であることから、p(y_n = 0 | x_n)は、1 - \hat{y}と書くことができる。
そのため、全データに対する負の対数尤度は、

\begin{aligned} - \sum_n \left( y_n \log \hat{y} + (1 - y_n) \log (1 - \hat{y}))\right) \end{aligned}

と書くことができる。

パラメータの解釈

学習で得られたパラメータの解釈にはオッズが用いられる。
オッズは、

\begin{aligned} \frac{p(y = 1 | x)}{p(y = 0 | x)} = \frac{\hat{y}}{1 - \hat{y}} \end{aligned}

を使用する。オッズの計算方法は、ロジスティック回帰の出力

\begin{aligned} \hat{y} = \frac{1}{1 + exp(-w^T x -b)} \end{aligned}

を代入する。

\begin{aligned} \frac{p(y = 1 | x)}{p(y = 0 | x)} &= \frac{\hat{y}}{1 - \hat{y}} \\[12px] &= \frac{1}{1 + exp(-w^T x - b)} \div \left( 1 - \frac{1}{1 + exp(-w^T x -b)} \right) \\[12px] &= \frac{1}{1 + exp(-w^T x - b)} \div \left( \frac{1 + exp(-w^T x - b)}{1 + exp(-w^T x - b)} - \frac{1}{1 + exp(-w^T x - b)} \right) \\[12px] &= \frac{1}{1 + exp(-w^T x - b)} \times \frac{1 + exp(-w^T x - b)}{exp(-w^T x - b)} \\[12px] &= \frac{1}{exp(-w^T x - b)} \\[12px] &= exp(w^T x + b) \end{aligned}

k 近傍法

  • 学習種類:教師あり学習

  • タスク:分類問題

  • 予測したいデータから近いk個のデータの多数決によって分類する方法が k 近傍法である。

SVM

  • 学習種類:教師あり学習
  • タスク:分類問題
  • パラメータ推定:マージン最大化
  • 2クラス分類

概要

  • 分類境界を挟んで2つのクラスがどのくらい離れているかをマージンと呼ぶ。
  • マージンが最大となる境界を学習する。
  • マージン上のデータ点をサポートベクトルと呼ぶ。
  • 境界線の計算式の結果が正負でクラスを判断する。

ハードマージン

  • 訓練データを完璧に分類できる決定関数が存在するという前提で分類する。

ソフトマージン

  • 多少の誤りを許容する。

カーネルトリック

  • 非線形問題を扱う場合、射影関数\phiを使って、線形分離できないデータを高次元の特徴空間に変換し、線形分離可能とする。
  • 次元を増やすと計算量が莫大になるため、カーネルトリックを使って計算コストを削減できる。

多項式カーネル

K(x_i,x_j) = \left[ x_i^Tx_j + c \right]^d

ガウスカーネル(動径基底関数、RBF カーネル

)

K(x_i,x_j) = exp \left(- \frac{||x_i-x_j||^2}{\beta} \right)

シグモイドカーネル

K(x_i,x_j) = \frac{1}{1+exp(-\beta x_i^Tx_j)}

k-means

  • 学習種類:教師なし学習
  • タスク:クラスタリング
  • クラスタ数は、はじめに決めておく必要がある。
コード実装

参考:k-means クラスタリングを Python/NumPy で最初から実装する方法を解説!

python
import numpy as np

def kmeans(k, X, max_iter=300):
    """
    k = クラスタ数
    X.shape = (データ数, 次元数)
    """

    X_size,n_features = X.shape

    # セントロイドの初期値(ランダムに重心の初期値を初期化)
    centroids  = X[np.random.choice(X_size, k)]

    # 前の重心と比較するために、仮に新しい重心を入れておく配列を用意
    new_centroids = np.zeros((k, n_features))

    # 各データ所属クラスタ情報を保存する配列を用意
    cluster = np.zeros(X_size)

    # ループ上限回数まで繰り返し
    for epoch in range(max_iter):

        # 入力データ全てに対して繰り返し
        for i in range(X_size):

            # データから各重心までの距離を計算(ルートを取らなくても大小関係は変わらないので省略)
            distances = np.sum((centroids - X[i]) ** 2, axis=1)

            # データの所属クラスタを距離の一番近い重心を持つものに更新
            cluster[i] = np.argsort(distances)[0]

        # すべてのクラスタに対して重心を再計算
        for j in range(k):
            new_centroids[j] = X[cluster==j].mean(axis=0)

        # もしも重心が変わっていなかったら終了
        if np.sum(new_centroids == centroids) == k:
            print("break")
            break
        centroids =  new_centroids
    return cluster

k-means++

  • k-means では初めのセントロイドの位置決めをランダムで行うため、うまく分類できない場合があった
  • 各セントロイド同士の距離がなるべく遠くなるように位置を決めるようにした。

主成分分析

  • 学習種類:教師なし学習

  • タスク:次元削減

  • パラメータ推定:分散最大化

  • 分散共分散行列の固有ベクトルを基に新たな座標軸を複数作成し、新たな座標軸から構成される低次元空間へデータを写像する。

  • 固有値の大きい固有ベクトルの方から第一主成分、第二主成分、・・・と呼ぶ。

  • 各主成分の固有値を固有値の総和で割った値を寄与率と呼ぶ。寄与率は、各主成分がどの程度元のデータを説明できているのかを表す。

コード実装
python
import numpy as np

def pca(X, n_components):

    # データから平均を引く
    X = X - X.mean(axis=0)

    # 共分散行列の作成
    cov = np.cov(X, rowvar=False)

    # 固有値と固有ベクトルを計算
    l, v = np.linalg.eig(cov)

    # 固有値の大きい順に固有ベクトルを並べ替え
    l_index = np.argsort(l)[::-1]
    v_ = v[:,l_index]

    # n_components個の固有ベクトルを取得
    components = v_[:,:n_components]

    # データを低次元空間へ射影
    T = np.dot(X, components)

    return T

Discussion