データ分析には, 様々なモデルがを用いることができます. 今回は, California House Priceのデータ分析を, いくつかのモデルで行います.
方法
次のモデルを用いて, California House Priceのデータの分析を行います.
- RIDGE
- LASSO
- 単純ベイズ
- SVM
実験
ライブラリとデータの準備
ここでは, Google Colaboratoryにデフォルトで入っている, California House Priceのデータを用いて, カリフォルニアの住宅の価格予測を行います.
まずは, 必要なライブラリをインストールします.
import warnings
warnings.filterwarnings("ignore")
import pandas as pd
import numpy as np
from sklearn.preprocessing import StandardScaler
from sklearn.metrics import mean_squared_error
California House Priceのデータを準備します. ここで使うデータは, Google Colaboratoryにてデフォルトで用意されているものです.
train_df = pd.read_csv("./sample_data/california_housing_train.csv")
test_df = pd.read_csv("./sample_data/california_housing_test.csv")
データの中身を表示します.
train_df.head()
データに対して, 前処理をおこないます.
train_df.fillna(train_df.mean(), inplace=True)
test_df.fillna(train_df.mean(), inplace=True)
訓練データについて, 予測したいものと, 予測するために用いるデータ(特徴量)とに分けます. それぞれを表示してみます.
X_train = train_df.drop("median_house_value", axis=1)
y_train = train_df["median_house_value"]
X_train.head()
y_train.head()
テストデータについても, 同様にします.
X_test = test_df.drop("median_house_value", axis=1)
y_test = test_df["median_house_value"]
RIDGE
まずは, リッジ回帰を行ってみます. 参考サイト:https://panda-clip.com/boston-ridge/
予測の精度は, 決定係数という指標で示しています. 決定係数R2とは, 各データの回帰直線からの距離の総和を考えることで求まります. 決定係数の値が大きい程, 予測の精度が高いと言うことができます. さらに, RMSEも表示しています. これは, 予測値と正解値の差を2乗して, 全てのデータについて和を取ったもので, この値が小さい程, 予測の精度が高いと言えます.
from sklearn import linear_model
# Ridge回帰
reg = linear_model.Ridge(alpha=0).fit(X_train, y_train)
print("alpha=0")
print("訓練データへの決定係数 :{:.7f}".format(reg.score(X_train, y_train)))
print("テストデータへの決定係数:{:.7f}".format(reg.score(X_test, y_test)))
y_pred_reg = reg.predict(X_test)
print("RMSE:{:.3f}".format(np.sqrt(mean_squared_error(y_pred_reg, y_test))))
reg = linear_model.Ridge(alpha=0.1).fit(X_train, y_train)
print("alpha=0.1")
print("訓練データへの決定係数 :{:.7f}".format(reg.score(X_train, y_train)))
print("テストデータへの決定係数:{:.7f}".format(reg.score(X_test, y_test)))
y_pred_reg = reg.predict(X_test)
print("RMSE:{:.3f}".format(np.sqrt(mean_squared_error(y_pred_reg, y_test))))
reg = linear_model.Ridge(alpha=0.5).fit(X_train, y_train)
print("alpha=0.5")
print("訓練データへの決定係数 :{:.7f}".format(reg.score(X_train, y_train)))
print("テストデータへの決定係数:{:.7f}".format(reg.score(X_test, y_test)))
y_pred_reg = reg.predict(X_test)
print("RMSE:{:.3f}".format(np.sqrt(mean_squared_error(y_pred_reg, y_test))))
reg = linear_model.Ridge(alpha=1).fit(X_train, y_train)
print("alpha=1")
print("訓練データへの決定係数 :{:.7f}".format(reg.score(X_train, y_train)))
print("テストデータへの決定係数:{:.7f}".format(reg.score(X_test, y_test)))
y_pred_reg = reg.predict(X_test)
print("RMSE:{:.3f}".format(np.sqrt(mean_squared_error(y_pred_reg, y_test))))
上の結果の通り, 回帰のパラメータαを変化させても, あまり予測の精度に影響はありません. 中では, テストデータへの決定係数が最も大きく, RMSEが最も小さい, alpha=1の予測が一番精度が高いと言えます.
# 通常の最小二乗法による線形回帰
reg2 = linear_model.LinearRegression().fit(X_train, y_train)
y_pred_reg2 = reg2.predict(X_test)
print("RMSE:{:.3f}".format(np.sqrt(mean_squared_error(y_pred_reg2, y_test))))
上で試した, Ridge回帰のalpha=1の場合の方が, RMSEが小さいことが分かります.
LASSO
次に, LASSO回帰を行います. 参考サイト:https://qiita.com/muscle_nishimi/items/901ed94f3cdf1c8d893a
上のRidge回帰では, 学習パラエータであるalphaを, こちら側が指定して学習を行っていましたが, 今度は, 最も良い値を探し, それを学習に採用する方法を取ります. 次の関数で, 最も良いパラメータを求めます.
from sklearn.linear_model import Lasso
from sklearn.pipeline import make_pipeline
from sklearn.preprocessing import StandardScaler
def lasso_tuning(train_x, train_y):
# alphaパラメータのリスト
param_list = [0.001, 0.01, 0.1, 1.0, 10.0, 100.0, 1000.0]
for cnt, alpha in enumerate(param_list):
# パラメータを設定したラッソ回帰モデル
lasso = Lasso(alpha=alpha)
# パイプライン生成
pipeline = make_pipeline(StandardScaler(), lasso)
# 学習
pipeline.fit(X_train, y_train)
# RMSE(平均誤差)を計算
train_rmse = np.sqrt(mean_squared_error(y_train, pipeline.predict(X_train)))
test_rmse = np.sqrt(mean_squared_error(y_test, pipeline.predict(X_test)))
# ベストパラメータを更新
if cnt == 0:
best_score = test_rmse
best_param = alpha
elif best_score > test_rmse:
best_score = test_rmse
best_param = alpha
# ベストパラメータのalphaと、そのときのMSEを出力
print("alpha : " + str(best_param))
print("RMSE : " + str(round(best_score, 4)))
# ベストパラメータを返却
return best_param
# best_alphaにベストパラメータのalphaが渡される。
best_alpha = lasso_tuning(X_train, y_train)
上で試したRidgeよりもRMSEが低く, 予測の精度が高いことがわかります.
単純ベイズ
from sklearn.naive_bayes import GaussianNB
gnb = GaussianNB().fit(X_train, y_train)
y_pred_gnb = gnb.predict(X_test)
np.sqrt(mean_squared_error(y_pred_gnb, y_test))
単純ベイズでの学習では, 誤差が非常に大きくなりました.
サポートベクトルマシン
from sklearn.svm import SVC
svc = SVC(kernel="linear", random_state=None).fit(X_train, y_train)
y_pred_svc = svc.predit(X_test)
np.sqrt(mean_squared_error(y_pred_svc, y_test))
あとがき
LASSOで行ったパラメータチューニングが今回最も精度の高い予測を導いたことから, データ分析の際は, パラメータの最適化をするとよい事がわかりました.