カリフォルニア住宅価格データセットで回帰分析

カリフォルニアの住宅情報からニューラルネットワークを用いた回帰分析で価格を予測するプログラムを作成します。実行環境は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件で、ボストン住宅価格データセットよりもデータ数が圧倒的に多くなっていることがわかります。
データ型は単精度浮動小数型です。
```Python
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件になります。
```Python
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を用いてニューラルネットワークの回帰分析を実行するコードを作りました。
```Python:California.py
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()
```
# 結果
赤い線が実際の価格、緑の線が予測した価格です。今回は高い精度が出せなかったので、今後精度を改善していこうと思います。
![Figure_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3644510/0c7edacb-7643-467f-a777-748a60f5d2c2.png)

# 参考
https://www.borndigital.co.jp/book/14383/
https://note.com/miya0207/n/n4f29266b83ef