1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

理論も理解しないでデータ解析するんですか??(機械学習チートシート)

Posted at

機械学習チートシート

対象読者:機械学習に関する講義を履修済みの大学生や社会人の方
数式の導出過程に重きを置いていますが、細かい説明や背景は省いているので、これを最初の学習用としないでください
参考までにPythonでのデータ解析用コードを記しています


概要

教師あり学習

  • 入力データと出力データから関数のパラメータを予測

教師なし学習

  • 入力データだけから関数のパラメータを予測

強化学習

  • 与えられた状態において報酬を最大化する行動を推定

データ前処理

標準化

  • 平均が0、標準偏差が1となるように変換
  • 単位や尺度の影響を取り除く

$$
z = \frac{x - \mu}{\sigma}
$$

from sklearn.preprocessing import StandardScaler
import numpy as np

X = np.array([[10, 20], [30, 40], [50, 60]])
scaler = StandardScaler()
X_scaled = scaler.fit_transform(X)
print("標準化前:\n", X)
print("標準化後:\n", X_scaled)

多重共線性

  • 説明変数同士の相関関係が高く、パラメータの推定が不安定になる

過学習

  • 学習データに過剰に適合し、汎化性能が低下する

回帰(Regression)

最小二乗法

  • 以下の損失関数を最小化

$$
L(\mathbf{w}) = | \mathbf{y} - X \mathbf{w} |^2
$$

$$
L(\mathbf{w}) = (\mathbf{y} - X \mathbf{w})^\top (\mathbf{y} - X \mathbf{w})
= \mathbf{y}^\top \mathbf{y} - 2 \mathbf{w}^\top X^\top \mathbf{y} + \mathbf{w}^\top X^\top X \mathbf{w}
$$

$$
\frac{\partial L}{\partial \mathbf{w}} = -2 X^\top \mathbf{y} + 2 X^\top X \mathbf{w} = 0
$$

$$
X^\top X \mathbf{w} = X^\top \mathbf{y}
$$

$$
\mathbf{w} = (X^\top X)^{-1} X^\top \mathbf{y}
$$

$X^\top X$ が正則である必要がある。多重共線性があると解が不安定になる

from sklearn.linear_model import LinearRegression
from sklearn.model_selection import train_test_split
from sklearn.datasets import make_regression

X, y = make_regression(n_samples=100, n_features=1, noise=10, random_state=42)
X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=42)

model = LinearRegression()
model.fit(X_train, y_train)

print("係数:", model.coef_)
print("切片:", model.intercept_)
print("決定係数 R2:", model.score(X_test, y_test))

正則化回帰

  • 訓練データへの過剰な適合を防ぐため、パラメータの大きさにペナルティを与える

Ridge回帰(L2正則化)

$$
L(\mathbf{w}) = | \mathbf{y} - X \mathbf{w} |^2 + \lambda | \mathbf{w} |^2_2
$$

$$
\frac{\partial L}{\partial \mathbf{w}} = -2 X^\top \mathbf{y} + 2 X^\top X \mathbf{w} + 2 \lambda \mathbf{w} = 0
$$

$$
(X^\top X + \lambda I) \mathbf{w} = X^\top \mathbf{y}
$$

$$
\mathbf{w} = (X^\top X + \lambda I)^{-1} X^\top \mathbf{y}
$$

  • 単位行列は正則化するパラメータに対応する対角成分のみ1とする
  • 対角成分を足してランク落ちを防ぐことで、逆行列を安定に計算

Lasso回帰(L1正則化)

$$
L(\mathbf{w}) = | \mathbf{y} - X \mathbf{w} |^2 + \lambda | \mathbf{w} |_1
$$

  • $\mathbf{w}$ の一部を0にする(特徴量選択)
  • 解析的に解けないため、数値計算を行う

# Ridge回帰
from sklearn.linear_model import Ridge

ridge = Ridge(alpha=1.0)
ridge.fit(X_train, y_train)
print("Ridge回帰 R2:", ridge.score(X_test, y_test))

# Lasso回帰
from sklearn.linear_model import Lasso

lasso = Lasso(alpha=0.1)
lasso.fit(X_train, y_train)
print("Lasso回帰 R2:", lasso.score(X_test, y_test))
print("Lassoで選択された特徴量:", lasso.coef_)


評価指標

MSE(Mean Squared Error)

$$
\text{MSE} = \frac{1}{N} \sum_{n=1}^{N} (y_n - \hat{y}_n)^2
$$


MAE(Mean Absolute Error)

$$
\text{MAE} = \frac{1}{N} \sum_{n=1}^{N} |y_n - \hat{y}_n|
$$


R^2 スコア(決定係数)

$$
R^2 = 1 - \frac{\sum^N _{n-1} (y_i - \hat{y}_i)^2}{\sum^N _{n-1} (y_i - \bar{y})^2}
$$

  • $R^2 = 1$:$y_i=\hat{y}_i$
    完全に説明できている
  • $R^2 = 0$:$\hat{y}_i=\bar{y}$
    平均を使うのと同等

from sklearn.metrics import mean_squared_error, mean_absolute_error, r2_score

y_pred = model.predict(X_test)
print("MSE:", mean_squared_error(y_test, y_pred))
print("MAE:", mean_absolute_error(y_test, y_pred))
print("R2:", r2_score(y_test, y_pred))


ホールドアウト法

  • データを訓練用と検証用にランダムに分割し、汎化性能を検証
from sklearn.model_selection import train_test_split

X_train, X_val, y_train, y_val = train_test_split(X, y, test_size=0.2, random_state=42)

交差検証法(Cross Validation)

  • 元のデータから一つずつ検証用データとして選び、すべてのデータが訓練・検証に一度ずつ使われるように評価する

K-fold交差検証法

  • データをK個の等しいサイズのサブセットに分割し、各サブセットを1回ずつ検証用データとし、残りを訓練用データに使ってK回モデルを評価
from sklearn.model_selection import KFold, cross_val_score
from sklearn.datasets import load_iris
from sklearn.linear_model import LogisticRegression

iris = load_iris()
X, y = iris.data, iris.target == 0

kf = KFold(n_splits=5, shuffle=True, random_state=1)
model = LogisticRegression()

scores = cross_val_score(model, X, y, cv=kf)
print("各Foldのスコア:", scores)
print("平均スコア:", scores.mean())

混同行列(Confusion Matrix)

真値\識別 P N
P TP(True Positive) FN(False Negative)
N FP(False Positive) TN(True Negative)
  • TP: 正しく陽性と判定された数(真陽性)
  • TN: 正しく陰性と判定された数(真陰性)
  • FP: 本当は陰性なのに陽性と判定された数(偽陽性)
  • FN: 本当は陽性なのに陰性と判定された数(偽陰性)

Recall(再現率)

$$
\text{Recall} = \frac{TP}{TP + FN}
$$

  • 実際に陽性だったもののうち、陽性と正しく予測された割合

Precision(適合率)

$$
\text{Precision} = \frac{TP}{TP + FP}
$$

  • 陽性と予測したもののうち、実際に陽性だった割合

Accuracy(正解率)

$$
\text{Accuracy} = \frac{TP + TN}{TP + TN + FP + FN}
$$

  • 全体のうち、正しく分類できた割合。

F1 スコア

$$
F1 = \frac{2 \cdot \text{Precision} \cdot \text{Recall}}{\text{Precision} + \text{Recall}}
$$

  • Precision と Recall の調和平均

from sklearn.metrics import confusion_matrix, classification_report
from sklearn.datasets import load_iris
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import train_test_split

iris = load_iris()
X, y = iris.data, iris.target
# 2クラスに簡略化 (class 0 vs rest)
y_binary = (y == 0).astype(int)

X_train, X_test, y_train, y_test = train_test_split(X, y_binary, random_state=42)
model = LogisticRegression()
model.fit(X_train, y_train)
y_pred = model.predict(X_test)

print("Confusion Matrix:\n", confusion_matrix(y_test, y_pred))
print("Classification Report:\n", classification_report(y_test, y_pred))


ROC曲線・AUC

  • ROC(Receiver Operating Characteristic)
    横軸:False Positive Rate(FPR)
    縦軸:True Positive Rate(TPR)
  • AUC:(Area Under the Curve)
    ROC曲線の下の面積
import matplotlib.pyplot as plt
from sklearn.metrics import roc_curve, auc

y_prob = model.predict_proba(X_test)[:,1]
fpr, tpr, thresholds = roc_curve(y_test, y_prob)
roc_auc = auc(fpr, tpr)

plt.plot(fpr, tpr, label=f'ROC curve (area = {roc_auc:.2f})')
plt.plot([0, 1], [0, 1], linestyle='--')
plt.xlabel('False Positive Rate')
plt.ylabel('True Positive Rate')
plt.title('ROC Curve')
plt.legend()
plt.show()


ロジスティック回帰

  • $y \in {0,1}$ に対して、事後確率をシグモイド関数で表現:

$$
P(\mathbf{x}) = \frac{1}{1 + e^{-(w_0 + \mathbf{w}^T \mathbf{x})}}
$$

$$
L(\mathbf{w}) = \prod_{n=1} ^N P(\mathbf{x}) ^{y_n} (1 - P(\mathbf{x})) ^{1 - y_n}
$$

$$
\log L(\mathbf{w}) = \sum_{n=1}^N \left[ y_n \log P(\mathbf{x}) + (1 - y_n) \log (1 - P(\mathbf{x})) \right]
$$

$$
\mathcal{L}(\mathbf{w}) = -\sum_{n=1}^N \left[ y_n \log P(\mathbf{x}) + (1 - y_n) \log (1 - P(\mathbf{x})) \right]
$$


from sklearn.linear_model import LogisticRegression

model = LogisticRegression()
model.fit(X_train, y_train)

y_pred = model.predict(X_test)
y_prob = model.predict_proba(X_test)[:, 1]

識別

最近傍法

$$
\hat{y} = \arg\min_y (\min_n d(\mathbf{x}-\mathbf{x^{(y)}_n}))
$$

  • データのノイズに強く影響する

k-NN(k近傍法)

  • 入力データに最も近い $k$ 個のサンプルを選び、多数決でクラスを決定
  • 過学習を防止
from sklearn.neighbors import KNeighborsClassifier

knn = KNeighborsClassifier(n_neighbors=3)
knn.fit(X_train, y_train)
print("k-NN 正解率:", knn.score(X_test, y_test))

サポートベクトルマシン(SVM)

ハードマージン

決定境界:

$$
\mathbf{w}^T \mathbf{x} + w_0 = 0
$$

ご分類なしの場合、ラベル $y_i \in {-1, +1}$に対して以下の式が成り立つ:

$$
y_i(\mathbf{w}^T \mathbf{x}_i + w_0) \geq 1 \quad
$$

サポートベクトル $\mathbf{x}_i$ から決定境界への距離:

$$
M = \frac{y_i (\mathbf{w}^T \mathbf{x}_i + w_0)}{|\mathbf{w}|}
$$

Mの最大化は$\mathbf{w}$の最小化と同値である

$$
\min_{\mathbf{w}, w_0} |\mathbf{w}|^2 , y_i (\mathbf{w}^T \mathbf{x}_i + w_0) \geq 1 \quad
$$


ソフトマージン

現実のデータは完全に線形分離できないので、スラック変数 $\xi_i$ を導入:

$$
\begin{align}
\min_{\mathbf{w}, w_0, \boldsymbol{\xi}} \quad & \frac{1}{2} |\mathbf{w}|^2 + C \sum_{i=1}^N \xi_i ,
y_i(\mathbf{w}^T \mathbf{x}_i + w_0) \geq 1 - \xi_i
\end{align}
$$


カーネルトリック(非線形分離)

入力 $\mathbf{x}$ を非線形写像 $\phi(\mathbf{x})$ で高次元空間に写像:

$$
K(\mathbf{x}_i, \mathbf{x}_j) = \phi(\mathbf{x}_i)^T \phi(\mathbf{x}_j)
$$

双対問題の内積をカーネルに置き換えれば非線形SVMが得られる:

$$
f(\mathbf{x}) = \sum_{i=1}^{N} \alpha_i y_i K(\mathbf{x}_i, \mathbf{x}) + b
$$

代表的なカーネル:

  • 線形カーネル:
    $K(\mathbf{x_i}, \mathbf{x_j}) = \mathbf{x_i}^T \mathbf{x_j}$
  • 多項式カーネル:
    $K(\mathbf{x_i}, \mathbf{x_j}) = (\mathbf{x_i}^T \mathbf{x_j} + c)^d$
  • RBFカーネル:
    $K(\mathbf{x_i}, \mathbf{x_j}) = \exp\left(-\gamma{|\mathbf{x_i} - \mathbf{x_j}|^2}\right)$
from sklearn.svm import SVC

svm = SVC(kernel='rbf', C=1.0, gamma='scale')
svm.fit(X_train, y_train)
print("SVM 正解率:", svm.score(X_test, y_test))

決定木

  • 木構造を用いて、ルールに従った分類または回帰を行う
  • $\log_2N$回の分岐でどのような入力データも分類可能

ジニ不純度(Gini Imprity)

  • ある領域に相当するノード$t$において誤分類する確率
  • 誤分類がないとき0で最小、異なるクラスで同じ数だけ誤分類されるとき最大

$$
G(t) = 1 - \sum_{k=1}^{K} P^2(C_k\mid t)
$$

$$
P^2(C_k\mid t) = \frac{N_k(t)}{N(t)}
$$

$$
P^2(C_k\mid t):ノードtでk番目のクラスが選ばれる確率
$$

  • ジニ不純度の差分が最大となる境界値で分割
  • 左右それぞれのノードにおけるジニ不純度を $G(t_L)$, $G(t_R)$ とすると、

$$
\Delta G(t) = G(t)-\left( \frac{N(t_L)}{N(t)} G(t_L) + \frac{N(t_R)}{N(t)} G(t_R) \right)
$$


剪定(Pruning)

  • 決定木の部分木をいくつか削除することで過学習を防止

  • 以下のコスト複雑度を最小化

$$
G_\alpha(T) = G(T) + \alpha |T|
$$

$G(T)$: 木 $T$ による誤分類率
$|T|$: 葉ノードの数(木のサイズ)
$\alpha$: 複雑度に対するペナルティ係数

from sklearn.tree import DecisionTreeClassifier
from sklearn import tree
import matplotlib.pyplot as plt

dt = DecisionTreeClassifier(max_depth=3, random_state=42)
dt.fit(X_train, y_train)

plt.figure(figsize=(12,8))
tree.plot_tree(dt, filled=True, feature_names=iris.feature_names, class_names=['Not class0','Class0'])
plt.show()

バイアス・バリアンス分解

$$
\mathbb{E} \left[ |\hat{\mathbf{y}} - \mathbf{y} |^2 \right]
=\mathbb{E}\left[|\hat{\mathbf{y}} - \mathbb{E}[\hat{\mathbf{y}}]|^2\right]+|\mathbb{E}[\hat{\mathbf{y}}] - \mathbf{y}|^2
$$

  • 第1項はバリアンス
  • 第2項はバイアスの二乗
  • バリアンスとバイアスはトレードオフの関係

アンサンブル学習

  • 複数のモデル(弱学習器)を組み合わせて、精度の向上や過学習の抑制を図る

バギング

  • バリアンスが大きく、バイアスが小さい弱学習器を集めてモデルを作成
  • 無相関な決定木の多数決や平均により予測
  • 元の訓練データから重複ありの復元抽出を行うブートストラップ法を行う
from sklearn.ensemble import BaggingClassifier
from sklearn.tree import DecisionTreeClassifier

bagging = BaggingClassifier(base_estimator=DecisionTreeClassifier(), n_estimators=10, random_state=42)
bagging.fit(X_train, y_train)
print("バギング 正解率:", bagging.score(X_test, y_test))


ブースティング

  • バイアスが大きく、バリアンスが小さい弱学習器を集めてモデルを作成
from sklearn.ensemble import AdaBoostClassifier

ada = AdaBoostClassifier(n_estimators=50, random_state=42)
ada.fit(X_train, y_train)
print("AdaBoost 正解率:", ada.score(X_test, y_test))

ランダムフォレスト(Random Forest)

  • バギングに説明変数のランダムサンプリングを加えることで、バリアンスを抑え、過学習を防ぐ
  • 各決定木の分岐時に説明変数$p$個からランダムに$\sqrt{p}$ 個だけ選ぶ
from sklearn.ensemble import RandomForestClassifier

rf = RandomForestClassifier(n_estimators=100, random_state=42)
rf.fit(X_train, y_train)
print("ランダムフォレスト 正解率:", rf.score(X_test, y_test))

クラスタリング

k-meansクラスタリング

  • 各データ点 $\mathbf{x}_i$ を $K$ 個のクラスタに分類する手法

以下の損失関数を最小化:
$$
L(\mu_k) = \sum_{k=1}^{K} \sum_{\mathbf{x}_n \in C_k} | \mathbf{x}_i - \boldsymbol{\mu}_k |^2
$$

$$
\mathbf{\mu_k} = \frac{1}{|C_k|} \sum^N_{n=1,\mathbf{x_n} \in C_k} \mathbf{x_n}
$$

  • $C_k$: クラスタ $k$
  • $\boldsymbol{\mu}_k$: クラスタ $k$ の中心(Centroid)
  • ランダムな初期値に依存するため、局所解に陥ることがある
from sklearn.cluster import KMeans
import numpy as np

X = np.array([[1, 2], [1, 4], [1, 0],
              [4, 2], [4, 4], [4, 0]])

kmeans = KMeans(n_clusters=2, random_state=42)
kmeans.fit(X)

print("クラスタ割当:", kmeans.labels_)
print("クラスタ中心:", kmeans.cluster_centers_)

エルボー法

  • 最適なクラスタ数 $K$ を選ぶ方法
  • クラスタ数の増加に伴う損失関数の減少度合いが緩やかになるKを選択する
import matplotlib.pyplot as plt
from sklearn.cluster import KMeans
from sklearn.datasets import make_blobs

# サンプルデータ作成
X, _ = make_blobs(n_samples=300, centers=4, cluster_std=0.60, random_state=0)

# SSE (Within-Cluster Sum of Squares) の計算
sse = []
k_range = range(1, 11)
for k in k_range:
    kmeans = KMeans(n_clusters=k, random_state=0)
    kmeans.fit(X)
    sse.append(kmeans.inertia_)  # inertia_ はSSE

# プロット
plt.plot(k_range, sse, 'bx-')
plt.xlabel('クラスタ数 k')
plt.ylabel('SSE (Within-cluster sum of squares)')
plt.title('エルボー法によるクラスタ数決定')
plt.show()

生成モデル

  • 観測データ$x$の母集団の確率分布をモデル化する
  • モデルの表現力向上のため、潜在変数を導入

EMアルゴリズム(Expectation-Maximization Algorithm)

  • 潜在変数を含む確率モデルのパラメータ推定に用いられる反復最適化手法
  • Eステップ:隠れ変数の分布の期待値を計算
  • Mステップ:期待値で得られた分布を用いてパラメータを最適化
  • 局所最適に収束するが、大域最適とは限らない

\begin{aligned}
\ln p(\mathbf{x};\theta)
&= \sum_{\mathbf{z}} q(\mathbf{z}) \ln p(\mathbf{x};\theta) \\
&= \sum_{\mathbf{z}} q(\mathbf{z}) \ln  \frac{p(\mathbf{x}, \mathbf{z};\theta)}{p(\mathbf{z}|\mathbf{x};\theta)} \\
&= \sum_{\mathbf{z}} q(\mathbf{z}) \ln  \frac{p(\mathbf{x}, \mathbf{z};\theta)}{q(\mathbf{z})} \cdot \frac{q(\mathbf{z})}{p(\mathbf{z}|\mathbf{x};\theta)}  \\
&= \sum_{\mathbf{z}} q(\mathbf{z}) \ln \frac{p(\mathbf{x}, \mathbf{z};\theta)}{q(\mathbf{z})} + \sum_{\mathbf{z}} q(\mathbf{z}) \ln \frac{q(\mathbf{z})}{p(\mathbf{z}|\mathbf{x};\theta)} \\
&= \underbrace{\mathcal{L}(q,\theta)}_{\text{ELBO}} + \underbrace{D(q\|p)}_{\text{KL - divergence}}
\end{aligned}

$D(q|p)=0$より$q(\mathbf{z}) = p(\mathbf{z}|\mathbf{x}; \theta)$

$$
\mathcal{L}(q, \theta) = \sum_{\mathbf{z}} p(\mathbf{z}|\mathbf{x}; \theta) \ln p(\mathbf{x}, \mathbf{z}; \theta) - \sum_{\mathbf{z}} p(\mathbf{z}|\mathbf{x}; \theta) \ln q(\mathbf{z})
$$

第二項は定数と見なせるため、第一項(完全データ対数尤度の期待値)を最大化する:

$$
Q(\theta, \theta^{\text{old}}) = p(\mathbf{z}|\mathbf{x}; \theta) \ln p(\mathbf{x}, \mathbf{z}; \theta)
$$


混合ガウス分布(GMM)

$$
p(\mathbf{x}) = \sum_{k=1}^{K} \pi_k \mathcal{N}(\mathbf{x} \mid \boldsymbol{\mu}_k, \boldsymbol{\Sigma}_k)
$$

  • $\pi_k$: 混合比 $\sum_{k=1}^{K} \pi_k =1$
  • $\mathcal{N}$: 多変量正規分布
import numpy as np
import matplotlib.pyplot as plt
from sklearn.mixture import GaussianMixture
from sklearn.datasets import make_blobs

# データ作成
X, y_true = make_blobs(n_samples=400, centers=3, cluster_std=0.60, random_state=42)

# GMM モデルの作成と学習
gmm = GaussianMixture(n_components=3, covariance_type='full', random_state=42)
gmm.fit(X)

# 各データ点のクラスタ予測
labels = gmm.predict(X)

# 結果の可視化
plt.scatter(X[:, 0], X[:, 1], c=labels, s=40, cmap='viridis')
plt.title("Gaussian Mixture Model (EMアルゴリズム)によるクラスタリング")
plt.show()

階層的クラスタリング(Hierarchical Clustering)

  • クラスタ間距離が最も近いクラスタを段階的に統合

全てのペア $(i,j)$ に対して距離を計算し、$n \times n$ の距離行列 $\mathbf{D}$ を得る:

$$
\mathbf{D}_{ij} = d(\mathbf{x}_i, \mathbf{x}_j)
$$


クラスタ間距離

単連結(Single Linkag)

$$
D(C_i, C_j) = \min_{x \in C_i, y \in C_j} d(x_i, y_j)
$$

完全連結(Complete Linkage)

$$
D(C_i, C_j) = \max_{x \in C_i, y \in C_j} d(x_i, y_j)
$$

平均連結(Average Linkage)

$$
D(C_i, C_j) = \frac{1}{|C_i||C_j|} \sum_{x \in C_i,y \in C_j} d(x_i, y_j)
$$

ウォード連結(Ward Linkage)

$$
D(C_i, C_j) = \sum_{x \in C_i \cup C_j} ( x - \mu_{C_i \cup C_j} )^2 - \left( \sum_{x \in C_i} ( x - \mu_{C_i} )^2 + \sum_{x \in C_j} ( x - \mu_{C_j} )^2 \right)
$$


系統樹(dendrogram)

  • 階層的クラスタリングにおける統合過程を視覚化
from scipy.cluster.hierarchy import dendrogram, linkage
import matplotlib.pyplot as plt
import numpy as np

X = np.array([[1, 2], [3, 4], [5, 6], [8, 8]])
Z = linkage(X, 'ward')

plt.figure(figsize=(6, 4))
dendrogram(Z)
plt.show()


主成分分析(Principal Component Analysis: PCA)

  • 多次元データをより少ない次元に射影して、元のデータの分散をできるだけ保持する次元削減

中心化(平均0)したデータの$\mathbf{w}$への射影の二乗が最大になるような$\mathbf{w}$を求める:

$$
|\mathbf{Xw}|^2 = (\mathbf{Xw})^T\mathbf{Xw}=\mathbf{w^T X^T}\mathbf{Xw}
$$

$$
|\mathbf{w}|^2 = \mathbf{w^T w} = 1
$$

Lagrange未定乗数を導入:

$$
L(\mathbf{w}, \lambda) = \mathbf{w}^T \mathbf{X}^T \mathbf{X} \mathbf{w} - \lambda (\mathbf{w}^T \mathbf{w} - 1)
$$

このラグランジュ関数を $\mathbf{w}$ で偏微分してゼロとおくと、

$$
\frac{L}{\partial \mathbf{w}} = 2 \mathbf{X}^T \mathbf{X} \mathbf{w} - 2 \lambda \mathbf{w} = \mathbf{0}
$$

$$
\mathbf{X}^T \mathbf{X} \mathbf{w} = \lambda \mathbf{w}
$$

$\mathbf{w}$ は 共分散行列$\mathbf{X}^T \mathbf{X}$ の固有ベクトル、$\lambda$ は対応する固有値となる
この固有値問題を解いて、最大の固有値に対応する固有ベクトルが第一主成分の射影方向


寄与率(Explained Variance Ratio)

  • 各主成分がデータ全体の分散のうちどれだけを説明しているかを示す

$$
\frac{\lambda_i}{\sum_{i=1}^p \lambda_i}
$$

累積寄与率(Cumulative Explained Variance Ratio)

$$
\frac{\sum_{i=1}^{p'}\lambda_i}{\sum_{i=1}^p \lambda_i}\quad (q'\leq q)
$$

from sklearn.decomposition import PCA
import numpy as np

X = np.random.rand(100, 5)
pca = PCA(n_components=2)
X_pca = pca.fit_transform(X)

print("寄与率:", pca.explained_variance_ratio_)
print("変換後データ形状:", X_pca.shape)

ニューラルネットワーク(Neural Networks)

  • 多層のノードと活性化関数で構成されるモデル

活性化関数

  • ReLU
    $$
    f(x) = \max(0, x)
    $$
  • Sigmoid
    $$
    f(x) = \frac{1}{1 + e^{-x}}
    $$
    出力は0から1の範囲
    勾配消失問題あり
  • tanh
    $$
    f(x) = \tanh(x) = \frac{e^{x} - e^{-x}}{e^{x} + e^{-x}}
    $$
    出力範囲は -1 から 1
import torch
import torch.nn as nn
import torch.optim as optim

class SimpleNN(nn.Module):
    def __init__(self):
        super().__init__()
        self.fc1 = nn.Linear(10, 5)
        self.relu = nn.ReLU()
        self.fc2 = nn.Linear(5, 1)

    def forward(self, x):
        x = self.relu(self.fc1(x))
        x = self.fc2(x)
        return x

model = SimpleNN()
criterion = nn.MSELoss()
optimizer = optim.SGD(model.parameters(), lr=0.01)

# ダミーデータ
x = torch.randn(3, 10)
y = torch.randn(3, 1)

# 学習ステップ例
optimizer.zero_grad()
output = model(x)
loss = criterion(output, y)
loss.backward()
optimizer.step()

勾配降下法

  • パラメータ $w$ を損失関数 $L(w)$ の勾配に沿って更新:

$$
w \leftarrow w - \eta \nabla L(w)
$$

$\eta$:学習率


誤差伝播法

  • 多層ネットワークで出力層から入力層へ誤差を逆伝播し、各パラメータの勾配を効率的に計算

$$
\frac{\partial y}{\partial x} = \frac{\partial y}{\partial y} \cdot \frac{\partial y}{\partial a} \cdot \frac{\partial a}{\partial b} \cdot \frac{\partial b}{\partial x}
$$

$$
\delta_j^{(l)} = \sum_k \delta_k^{(l+1)} \frac{\partial u_k^{(l+1)}}{\partial u_j^(l)}
$$


確率勾配降下法

  • データの一部をランダムにバッチとして選び、バッチを用いて勾配降下法を行う
  • 局所解に陥ることを防ぐ

スキップ接続

  • 深いネットワークで勾配消失を防ぐために、層をまたいで入力を後の層に直接渡す
  • 出力 $y = F(x) + x$

Dropout

  • 過学習防止のため、学習時にランダムに一部のニューロンの結合を削除

CNN(畳み込みニューラルネットワー)

  • 画像や時系列データなどの局所特徴抽出に適したネットワーク

畳み込み演算(Convolution)

入力画像 $I$ とフィルタ $K$ の畳み込み:

$$
S(i,j) = (I * K)(i,j) = \sum_m \sum_n I(i-m, j-n) K(m,n)
$$


パディング

  • 畳み込み時に画像の端を拡張し、ゼロパディングなどを施すことで出力サイズを調整

ストライド

  • フィルタをスライドさせる移動幅
  • 出力サイズの調整や計算効率の効率化を行う

プーリング

  • 特徴マップの空間サイズを縮小し、計算負荷を削減
  • 最大値プーリング、平均値プーリングなどが用いられる

VAE(変分オートエンコーダ)

  • 入力 $x$ を潜在変数 $z$ にエンコードし、デコードする生成モデル

損失関数:

$$
ELBO(x;\theta,\phi) = -\frac{1}{2}\sum^D_{d=1}(x_d-\hat{x_d})^2 + \frac{1}{2}\sum^H_{h=1}(1+\log\delta_n^2-\mu_h^2-\delta_n^2)+condt
$$

第一項:再構成誤差
第二項:正則化項


ベイズ推論

  • パラメータ $\theta$ に対する事後確率を計算して推論を行う:

$$
P(\theta|D) = \frac{P(D|\theta) P(\theta)}{P(D)}
$$

$P(D|\theta)$:尤度
$P(\theta)$:事前確率
$P(D)$:エビデンス


import torch.nn as nn

class SimpleCNN(nn.Module):
    def __init__(self):
        super().__init__()
        self.conv1 = nn.Conv2d(in_channels=3, out_channels=16, kernel_size=3, padding=1)
        self.relu = nn.ReLU()
        self.pool = nn.MaxPool2d(kernel_size=2, stride=2)
        self.fc = nn.Linear(16 * 16 * 16, 10)  # 例: 32x32画像の場合

    def forward(self, x):
        x = self.pool(self.relu(self.conv1(x)))
        x = x.view(x.size(0), -1)
        x = self.fc(x)
        return x
1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?