ボストン住宅価格を分析・予測

ボストン住宅価格を分析・予測

ボストンの住宅価格について、分析・予測していきます。

Jupyterノートブックを使って実行しています。
管理がずさんなので、ログをとっていきたいと思います。

分析等もあまり経験がないので、形式的なやり方を知らないので、意味のわからないことをしていると思いますが・・・

取り敢えずimport

import pandas as pd
import matplotlib.pyplot as plt
import numpy as np
from numpy.random import *
from sklearn.linear_model import LinearRegression,Ridge,Lasso, ElasticNet
from sklearn.datasets import load_boston

ボストン住宅価格のデータセット

データセットは、以下のような変数を持ち、これらを説明変数とする。

被説明変数は、住宅価格である。

変数 説明
CRIM 人口1人当たりの犯罪発生数
ZN 25000平方フィート以上の住居区間の占める割合
INDUS 小売業以外の商業が占める面積の割合
CHAS チャーチルズ川によるダミー変数(1:川の周囲、2:それ以外)
NOX NOxの濃度
RM 住居の平均部屋数
AGE 1940年より前に建てられた物件の割合
DIS 5つのボストン市の雇用施設からの距離(重み付け済)
RAD 環状高速道路へのアクセスのしやすさ
TAX $10,000当たりの不動産税率の総計
PTRATIO 町毎の児童と教師の比率
B 町毎の黒人(Bk)の比率1000(Bk-0.63)^2
LSTAT 給与の低い職業に従事する人口の割合

データセットを読み込む

説明変数をdata_x
被説明変数をdata_y

説明変数と被説明変数を統合したデータセットをdata

pandasのデータフレームに変換する

import pandas as pd
from sklearn.datasets import load_boston

# サンプルデータを用意
dataset = load_boston()

# 説明変数データを取得
data_x = pd.DataFrame(dataset.data,columns=dataset.feature_names)

# 被説明変数データを取得
data_y = pd.DataFrame(dataset.target,columns=['target'])

#data_xとdata_yを結合して1つのデータセットにする
data = pd.concat([data_x, data_y], axis=1)

データセットの行数と列数を調べる

説明変数の数:(506, 13)
被説明変数のサイズ:(506, 1)
説明変数の変数の個数:13

print("説明変数行列のサイズ:{}".format(data_x.shape))
print("被説明変数のサイズ:{}".format(data_y.shape))
print("説明変数の変数の個数:{}".format(data_x.shape[1]))
coef_n = data_x.shape[1]

分析

価格をソートする

価格の高い順・低い順に並べ替えていきます。

#昇順
data_sorted_up = data.sort_values('target', ascending=False)
#降順
data_sorted_down = data.sort_values('target', ascending=True)

データを抽出

価格の高い順の50を抽出

data_sorted_up_50 = data_sorted_up.iloc[0:50,:]

価格の低い順の50

data_sorted_down_50 = data_sorted_down.iloc[0:50,:]

価格上位と下位を見比べる

plt.plot(np.array(data_sorted_down_50.mean()), label='down')
plt.plot(np.array(data_sorted_up_50.mean()), 'red', label='up')
plt.legend()
plt.plot()

価格上位と下位の平均の誤差をみる

a = np.array(data_sorted_up_50.mean())
b = np.array(data_sorted_down_50.mean())

error_i = pd.DataFrame((a-b))

c = np.array(data.columns)

error_i.index = c

相関係数とヒートマップ

import matplotlib.pyplot as plt
import seaborn as sns
plt.figure(figsize=(8, 6)) #heatmap size
sns.heatmap(data_sorted_up._50.corr(), annot=True, cmap='plasma', linewidths=.5) 

#sns.heatmap(data_sorted_down_50.corr(), annot=True, cmap='plasma', linewidths=.5) 

VIF

from statsmodels.stats.outliers_influence import variance_inflation_factor

vif = pd.DataFrame()
vif["VIF Factor"] = [variance_inflation_factor(data_x.values, i) for i in range(data_x.shape[1])]
vif["features"] = data_x.columns

データ分析諸々describe()

describe()は、データ数・平均・標準偏差・最小値・最大値・四分位点を求めることができる

data.describe()
data_sorted_up_50.describe()
data_sorted_down_50.describe()

散布図

sns.pairplot(data)

予測

回帰

回帰は、係数だけをとりあえず求める

from sklearn.linear_model import LinearRegression,Ridge,Lasso, ElasticNet

OLS:最小2乗回帰

OLS = LinearRegression().fit(data_x, data_y)
print(OLS_coefs)

ridge

ridge = Ridge().fit(data_x, data_y)
print(ridge.coef_.round(2))

lasso

lasso = Lasso().fit(data_x, data_y)
print(lasso.coef_.round(2))


<h4>elastic_net</h4>

elastic_net = ElasticNet(alpha = 0.5, l1_ratio=0.5).fit(data_x, data_y)
print(elastic_net.coef_.round(2))

ニューラルネットワーク

import numpy as np
#kerasでCNN構築
from keras.models import Sequential
from keras.layers import Conv2D, MaxPooling2D
from keras.layers import Activation, Dropout, Flatten, Dense
from keras.optimizers import Adam
from sklearn.model_selection import train_test_split
#時間計測
import time


'''
データの読み込みと前処理
'''
# サンプルデータを用意
dataset = load_boston()

# 標本データを取得
data_x = pd.DataFrame(dataset.data,columns=dataset.feature_names)

# 正解データを取得
data_y = pd.DataFrame(dataset.target,columns=['target'])

X_train, X_test, y_train, y_test = train_test_split(data_x, data_y, test_size=0.2, random_state=0)


'''
入力+中間層+出力層の3層NNの構築
'''

model = Sequential()

model.add(Dense(10, input_dim=13, activation='relu'))

model.add(Dense(256, activation='relu'))

model.add(Dropout(0.5))

model.add(Dense(256, activation='relu'))

model.add(Dropout(0.5))

model.add(Dense(10, activation='relu'))

model.add(Dense(1, activation='relu'))

model.compile(loss='mean_squared_error', optimizer=Adam(), metrics=['accuracy'])

'''
学習
'''
#計測開始
startTime = time.time()

history = model.fit(X_train, y_train, epochs=50, batch_size=30, verbose=0, validation_data=(X_test, y_test))

score = model.evaluate(X_test, y_test, verbose=0)

#誤り率
print('Test Loss:{0:.3f}'.format(score[0]))
#正解率
print('Test Accuracy:', score[1])
#処理にかかった時間
print("time:{0:.3f}sec".format(time.time() - startTime))