ボストン住宅価格を分析・予測
ボストンの住宅価格について、分析・予測していきます。
Jupyterノートブックを使って実行しています。
管理がずさんなので、ログをとっていきたいと思います。
分析等もあまり経験がないので、形式的なやり方を知らないので、意味のわからないことをしていると思いますが・・・
取り敢えずimport
1 2 3 4 5 6 | 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のデータフレームに変換する
01 02 03 04 05 06 07 08 09 10 11 12 13 14 | 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
1 2 3 4 | print ( "説明変数行列のサイズ:{}" . format (data_x.shape)) print ( "被説明変数のサイズ:{}" . format (data_y.shape)) print ( "説明変数の変数の個数:{}" . format (data_x.shape[ 1 ])) coef_n = data_x.shape[ 1 ] |
分析
価格をソートする
価格の高い順・低い順に並べ替えていきます。
1 2 3 4 | #昇順 data_sorted_up = data.sort_values( 'target' , ascending = False ) #降順 data_sorted_down = data.sort_values( 'target' , ascending = True ) |
データを抽出
価格の高い順の50を抽出
1 | data_sorted_up_50 = data_sorted_up.iloc[ 0 : 50 ,:] |
価格の低い順の50
1 | data_sorted_down_50 = data_sorted_down.iloc[ 0 : 50 ,:] |
価格上位と下位を見比べる
1 2 3 4 | 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() |
価格上位と下位の平均の誤差をみる
1 2 3 4 5 6 7 8 | 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 |
相関係数とヒートマップ
1 2 3 4 5 6 | 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
1 2 3 4 5 | 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()は、データ数・平均・標準偏差・最小値・最大値・四分位点を求めることができる
1 2 3 | data.describe() data_sorted_up_50.describe() data_sorted_down_50.describe() |
散布図
1 | sns.pairplot(data) |
予測
回帰
回帰は、係数だけをとりあえず求める
1 | from sklearn.linear_model import LinearRegression,Ridge,Lasso, ElasticNet |
OLS:最小2乗回帰
1 2 | OLS = LinearRegression().fit(data_x, data_y) print (OLS_coefs) |
ridge
1 2 | ridge = Ridge().fit(data_x, data_y) print (ridge.coef_. round ( 2 )) |
lasso
1 2 3 4 5 6 7 8 | 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 )) |
ニューラルネットワーク
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 | 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)) |