この記事は
TensorFlow(tf.keras)を使って、
- 線形回帰モデル
- DNN 回帰モデル
の2つの手法を比較し、実装例を通して違いを解説します。
概要
2つの手法の違い
-
線形回帰
- モデル構造:入力→出力の1層のみ
- 表現力:関数形は常に $y = w x + b $の直線
- 長所:計算コストが低く、結果の解釈が容易
- 短所:非線形データに適用すると誤差が大きくなる
-
DNN 回帰
- モデル構造:隠れ層+活性化関数を複数重ねたネットワーク
- 表現力:非線形関数を近似できる(多項式項や複雑曲線を学習)
- 長所:非線形性の強いデータに対して高精度
- 短所:パラメータ数が増え、過学習リスクやチューニングが必要
サンプルデータの作成
import numpy as np
# 再現性のためのシード固定
np.random.seed(0)
# データ数と入力値
N = 1000
x = np.random.rand(N, 1).astype(np.float32)
# 真の関数:y = 5x + 3x^2 + ノイズ
y = 5 * x + 3 * x**2 + np.random.randn(N, 1).astype(np.float32) * 0.05
# 訓練/テスト分割(80%/20%)
indices = np.arange(N)
np.random.shuffle(indices)
split = int(N * 0.8)
train_idx, test_idx = indices[:split], indices[split:]
X_train, X_test = x[train_idx], x[test_idx]
y_train, y_test = y[train_idx], y[test_idx]
線形回帰の場合
import tensorflow as tf
from tensorflow.keras import layers
# モデル定義:Dense(1) のみ
linear_model = tf.keras.Sequential([
layers.Dense(1, input_shape=(1,))
])
# コンパイル:最適化は SGD、損失は MSE
linear_model.compile(
optimizer='sgd',
loss='mse',
metrics=['mse']
)
# 学習
history_lin = linear_model.fit(
X_train, y_train,
epochs=100,
batch_size=32,
validation_split=0.2,
verbose=0
)
# テスト評価
mse_lin = linear_model.evaluate(X_test, y_test, verbose=0)[0]
print(f"Linear Regression Test MSE: {mse_lin:.4f}")
- ポイント:隠れ層を持たないので、出力は必ず直線。
- 結果:非線形項を捉えられず、MSE は高め。
DNN回帰の場合
# モデル定義:隠れ層2層+ReLU活性化
dnn_model = tf.keras.Sequential([
layers.Dense(64, activation='relu', input_shape=(1,)),
layers.Dense(64, activation='relu'),
layers.Dense(1) # 出力は線形
])
# コンパイル:最適化は Adam、損失は MSE
dnn_model.compile(
optimizer='adam',
loss='mse',
metrics=['mse']
)
# 学習
history_dnn = dnn_model.fit(
X_train, y_train,
epochs=100,
batch_size=32,
validation_split=0.2,
verbose=0
)
# テスト評価
mse_dnn = dnn_model.evaluate(X_test, y_test, verbose=0)[0]
print(f"DNN Regression Test MSE: {mse_dnn:.4f}")
- ポイント:隠れ層+ReLU によって非線形変換を学習。
- 結果:複雑な関数形を近似でき、MSE は線形回帰より小さくなる。
まとめ
-
線形回帰
- シンプルで解釈性が高い
- 非線形関係を表現できず、複雑データでは性能が限られる
-
DNN 回帰
- 高い表現力で非線形データに強い
- パラメータ数が多く、過学習対策やハイパーパラメータ調整が必要
用途やデータの性質に合わせて、適切な手法を選択してください。