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

機械学習




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

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

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))
タイトルとURLをコピーしました