機械学習の基礎と実装


はじめに

機械学習は、データから自動的にパターンを学習し、予測や分類を行う技術です。本記事では、機械学習の基本的なアルゴリズムと実装例を紹介します。

線形回帰

線形回帰は、連続値を予測する教師あり学習の基本的な手法です。

数学的基礎

線形回帰モデルは以下の式で表されます:

y^=w0+w1x1+w2x2++wnxn\hat{y} = w_0 + w_1 x_1 + w_2 x_2 + \cdots + w_n x_n

または、ベクトル形式で:

y^=wTx\hat{y} = \mathbf{w}^T \mathbf{x}

最小二乗法による誤差関数は:

J(w)=12mi=1m(y^(i)y(i))2J(\mathbf{w}) = \frac{1}{2m} \sum_{i=1}^{m} (\hat{y}^{(i)} - y^{(i)})^2

ここで mm はサンプル数です。

Pythonでの実装

import numpy as np
from sklearn.linear_model import LinearRegression
from sklearn.metrics import mean_squared_error, r2_score

# データの生成
np.random.seed(42)
X = np.random.randn(100, 3)
true_weights = np.array([2.0, -3.0, 1.5])
y = X @ true_weights + np.random.randn(100) * 0.1

# モデルの構築と訓練
model = LinearRegression()
model.fit(X, y)

# 予測
y_pred = model.predict(X)

# 評価
mse = mean_squared_error(y, y_pred)
r2 = r2_score(y, y_pred)

print(f"MSE: {mse:.4f}")
print(f"R² Score: {r2:.4f}")
print(f"推定されたウェイト: {model.coef_}")

ロジスティック回帰による分類

ロジスティック回帰は二値分類問題に用いられます。

シグモイド関数

ロジスティック回帰は、線形結合にシグモイド関数を適用して確率を得ます:

P(y=1x)=11+ewTxP(y=1|\mathbf{x}) = \frac{1}{1 + e^{-\mathbf{w}^T\mathbf{x}}}

交差エントロピー損失は:

L(w)=1mi=1m[y(i)log(p^(i))+(1y(i))log(1p^(i))]L(\mathbf{w}) = -\frac{1}{m}\sum_{i=1}^{m}\left[y^{(i)}\log(\hat{p}^{(i)}) + (1-y^{(i)})\log(1-\hat{p}^{(i)})\right]

JavaScriptでのニューラルネットワーク実装

class NeuralNetwork {
    constructor(inputSize, hiddenSize, outputSize) {
        this.inputSize = inputSize;
        this.hiddenSize = hiddenSize;
        this.outputSize = outputSize;
        
        // ウェイトの初期化
        this.W1 = this.randomMatrix(inputSize, hiddenSize);
        this.b1 = new Array(hiddenSize).fill(0);
        this.W2 = this.randomMatrix(hiddenSize, outputSize);
        this.b2 = new Array(outputSize).fill(0);
    }
    
    randomMatrix(rows, cols) {
        return Array(rows).fill(0).map(() => 
            Array(cols).fill(0).map(() => Math.random() - 0.5)
        );
    }
    
    sigmoid(x) {
        return 1 / (1 + Math.exp(-x));
    }
    
    relu(x) {
        return Math.max(0, x);
    }
    
    forward(input) {
        // 隠れ層
        this.z1 = this.matmul(input, this.W1);
        this.a1 = this.z1.map(x => x + this.b1[0]).map(x => this.relu(x));
        
        // 出力層
        this.z2 = this.matmul(this.a1, this.W2);
        this.a2 = this.z2.map((x, i) => this.sigmoid(x + this.b2[i]));
        
        return this.a2;
    }
    
    matmul(a, b) {
        // 簡略化された行列積(実装)
        return Array(b[0].length).fill(0).map((_, j) => 
            a.reduce((sum, _, i) => sum + a[i] * b[i][j], 0)
        );
    }
}

// 使用例
const nn = new NeuralNetwork(2, 4, 1);
const input = [1.0, 0.5];
const output = nn.forward(input);
console.log("予測出力:", output);

勾配降下法

パラメータ更新の基本的なアルゴリズムは勾配降下法です:

w:=wαJ(w)\mathbf{w} := \mathbf{w} - \alpha \nabla J(\mathbf{w})

ここで α\alpha は学習率、J\nabla J は勾配です。

モメンタムの導入

勾配降下法の収束を加速させるため、モメンタムを使用することができます:

v:=βvαJ(w)\mathbf{v} := \beta \mathbf{v} - \alpha \nabla J(\mathbf{w}) w:=w+v\mathbf{w} := \mathbf{w} + \mathbf{v}

通常、β=0.9\beta = 0.9 程度の値を使用します。

正則化

過学習を防ぐため、正則化項を追加します:

J(w)=1mi=1mL(y(i),y^(i))+λw2J(\mathbf{w}) = \frac{1}{m}\sum_{i=1}^{m}L(y^{(i)}, \hat{y}^{(i)}) + \lambda \|\mathbf{w}\|^2

  • L2正則化(Ridge):λw22\lambda \|\mathbf{w}\|_2^2
  • L1正則化(Lasso):λw1\lambda \|\mathbf{w}\|_1

実装上の注意点

機械学習モデルを実装する際の重要な考慮事項:

  1. 特徴量スケーリング:入力値を標準化または正規化する
  2. クラスバランス:不均衡なデータセットに対する対策
  3. ハイパーパラメータチューニング:グリッドサーチやベイズ最適化の活用
  4. 交差検証:モデル評価の精度を向上させる
  5. 過学習の検出:訓練誤差とテスト誤差のギャップを監視

まとめ

機械学習は統計学と最適化の融合です。基本的なアルゴリズムを理解することで、より複雑なモデルの学習へと進むことができます。実装時は常にデータの前処理とモデル評価を重視することが重要です。