ボストン住宅価格を分析・予測
ボストンの住宅価格について、分析・予測していきます。
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)) [python] <h4>elastic_net</h4> [python] 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))