カリフォルニアの住宅情報からニューラルネットワークを用いた回帰分析で価格を予測するプログラムを作成します。実行環境はVisual Studio Community 2022のバージョン17.7.4です。
使用したPythonとライブラリのバージョンは以下の通りです。
・Python 3.9.13
・Numpy 1.26.4
・Pandas 1.5.1
・TensorFlow 2.16.1
・Matplotlib 3.6.2
データの確認
カリフォルニア住宅価格データセットのシェイプとデータ型を確認します。
訓練データ16512件、テストデータ4128件で、ボストン住宅価格データセットよりもデータ数が圧倒的に多くなっていることがわかります。
データ型は単精度浮動小数型です。
from tensorflow.keras.datasets import california_housing
(train_data, train_labels), (test_data, test_labels) = california_housing.load_data()
print(train_data.shape) #(16512, 8)
print(train_labels.shape) #(16512,)
print(test_data.shape) #(4128, 8)
print(test_labels.shape) #(4128,)
print(train_data.dtype) #float32
print(train_labels.dtype) #float32
print(test_data.dtype) #float32
print(test_labels.dtype) #float32
pandsを用いて訓練データの中身を確認します。head(n)関数を使うと上からn件のデータを取得できます。引数を指定しなければ自動的に5件になります。
from tensorflow.keras.datasets import california_housing
import pandas as pd
(train_data, train_labels), (test_data, test_labels) = california_housing.load_data()
train_df = pd.DataFrame(train_data)
labels_df = pd.DataFrame(train_labels, columns=['price'])
df = pd.concat([train_df, labels_df], axis=1)
print(df.head())
'''
0 1 2 3 4 5 6 7 price
0 -118.269997 34.090000 52.0 2327.0 555.0 1048.0 491.0 3.7847 252300.0
1 -118.360001 33.959999 21.0 1802.0 556.0 1286.0 557.0 2.7284 146900.0
2 -122.389999 37.759998 52.0 1877.0 427.0 712.0 398.0 3.9722 290900.0
3 -117.949997 33.919998 11.0 3127.0 706.0 1594.0 694.0 4.3426 141300.0
4 -122.519997 37.919998 24.0 421.0 64.0 163.0 75.0 14.5833 500001.0
'''
訓練データは8個の特徴量を持っていることがわかります。ラベルには住宅の価格が記録されています。
学習
TensorFlowを用いてニューラルネットワークの回帰分析を実行するコードを作りました。
import numpy as np
import matplotlib.pyplot as plt
from tensorflow.keras.datasets import california_housing
from tensorflow.keras.callbacks import EarlyStopping
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense, Dropout
from tensorflow.keras.optimizers import Adam
epochs = 500; #エポック数
learning_rate = 0.001 #学習率
early_stop = EarlyStopping(monitor='val_loss', patience=20) #20エポック間で誤差の改善が見られなければ学習終了
(train_data, train_labels), (test_data, test_labels) = california_housing.load_data() #カリフォルニア住宅価格データセットをダウンロード
#データの偏りをなくすためにシャッフルする
order = np.argsort(np.random.random(train_labels.shape))
train_data = train_data[order]
train_labels = train_labels[order]
#データセットの正規化
train_mean = train_data.mean(axis=0)
test_mean = test_data.mean(axis=0)
train_std = train_data.std(axis=0)
test_std = test_data.std(axis=0)
train_data = (train_data - train_mean) / train_std
test_data = (test_data - test_mean) / test_std
#モデルを定義
model = Sequential()
model.add(Dense(32, activation='relu', input_shape=train_data[1].shape)) #入力層
model.add(Dense(128, activation='relu')) #隠れ層
model.add(Dropout(rate=0.2)) #過学習を防ぐためニューロンを20%無効にする
model.add(Dense(1)) #出力層
#損失関数を平均二乗誤差、最適化関数をAdam、評価指標を平均絶対誤差にしてコンパイル
model.compile(loss='mse', optimizer=Adam(learning_rate=learning_rate), metrics=['mae'])
#学習の実行
model.fit(train_data, train_labels, epochs=epochs, validation_split=0.2, callbacks=[early_stop])
test_data = test_data[0:100] #テストデータを先頭の100件抽出
test_predictions = model.predict(test_data).flatten() #推論の実行
x = list(range(100))
plt.style.use('dark_background')
plt.plot(x, test_labels[0:100], color='red', label='target') #住宅価格の実際の値をプロット
plt.plot(x, test_predictions, color='green', label='prediction') #住宅価格の推論の値をプロット
plt.ylabel('price')
plt.legend()
plt.show()
結果
赤い線が実際の価格、緑の線が予測した価格です。今回は高い精度が出せなかったので、今後精度を改善していこうと思います。
参考
https://www.borndigital.co.jp/book/14383/
https://note.com/miya0207/n/n4f29266b83ef