回帰⑦ (モデルの保存と読み込み)

構築したモデルは、保存したり読み込んだりすることができます。

モデルの保存

pickleというライブラリを使って、モデルを保存してみます。

dumpメソッドを使って、構築したsimple_regモデルの内容を出力しています。(4行目)

[Google Colaboratory]

1
2
3
4
import pickle

file_path = "simple_reg.pkl"
pickle.dump(simple_reg, open(file_path, "wb"))

正常に処理が終了すると、simple_reg.pklというファイルが出力されます。

モデルの読み込み

保存したモデルを読み込みます。

loadメソッドを使って、モデルの読み込みを行います。(2行目)

[Google Colaboratory]

1
2
file_path = "simple_reg.pkl"
model = pickle.load(open(file_path, "rb"))

読み込んだモデルが問題なく使えるかどうかを確認します。

predictメソッドにテストデータを渡して予測を行います。(1行目)

[Google Colaboratory]

1
2
pred = model.predict(X_test)
print(pred[:5])

[実行結果]

問題なく予測結果を取得することができました。

データ量が少ない場合は、学習処理の計算時間はかかりませんが、膨大なデータや複雑なアルゴリズムを扱う場合は計算処理にとても時間がかかります。

そのような場合は毎回学習処理を行うのではなく、学習したモデル(構築したモデル)を保存・読み込んでうまく再利用することをお勧めします。

回帰⑥ (精度評価指標)

精度評価指標

予測値と実測値の差(誤差)の大きさを確認するために精度評価指標を使います。

精度評価指標は次のようなものがあります。

  • 平均絶対誤差(MAE:Mean Absolute Error)
    誤差の絶対値の総和の平均値。
    マイナス誤差の大きさを総和に反映させるため、絶対値を使用。
    値が0に近いほど誤差が小さい。
  • 平均二乗誤差(MSE:Mean Squared Error)
    誤差を二乗した値の総和の平均値。
    マイナス誤差の大きさを総和に反映させるために、二乗を使用。
    二乗しているため、MAE、RMSEよりも大きな値が出る傾向があり、外れ値の影響が大きく出やすい。
    値が0に近いほど誤差が小さい。
  • 二乗平均平方根誤差(RMSE:Root Mean Squared Error)
    MSEを1/2乗した値。
    値が0に近いほど誤差が小さい。
  • 決定係数(R2)
    MSEの尺度を取り直した値。
    0~1の範囲で値をとり、1に近いほど精度が高い。
    明確な基準はなくケースバイケースではあるが、0.7以上であれば比較的精度が高いと判断して良い。
  • 平均絶対パーセント誤差(MAPE:Mean Absolute Percentage Error)
    誤差の度合いを%で表したもの。

精度評価指標の算出(テストデータ)

テストデータの各精度評価指標を算出します。

[Google Colaboratory]

1
2
3
4
5
6
7
8
9
10
11
12
13
from sklearn.metrics import mean_absolute_error, mean_squared_error, r2_score
import numpy as np

mae = mean_absolute_error(y_test, y_test_pred)
mse = mean_squared_error(y_test, y_test_pred)
rmse = np.sqrt(mse)
r2score = r2_score(y_test, y_test_pred)

print("テストデータスコア")
print(f"MAE = {mae}")
print(f"MSE = {mse}")
print(f"RMSE = {rmse}")
print(f"R2 = {r2score}")

[実行結果]

モデルの精度評価はテストデータに対する精度を見て行います。

理由は、機械学習モデルに求められるのは未知のデータを予測する性能(汎化性能)だからです。

(テストデータは未知のデータと見立てているため、学習には使用していません。)

精度評価指標の算出(訓練データ)

訓練データの各精度評価指標も算出します。

[Google Colaboratory]

1
2
3
4
5
6
7
8
9
10
mae_train = mean_absolute_error(y_train, y_train_pred)
mse_train = mean_squared_error(y_train, y_train_pred)
rmse_train = np.sqrt(mse_train)
r2score_train = r2_score(y_train, y_train_pred)

print("訓練データスコア")
print(f"MAE = {mae_train}")
print(f"MSE = {mse_train}")
print(f"RMSE = {rmse_train}")
print(f"R2 = {r2score_train}")

[実行結果]

訓練データのスコアを出す理由は、モデルに過学習の傾向がないかどうかを確認するためです。

過学習とは、訓練データに対して過度に適合し、未知のデータへの予測精度が低くなってしまっている状態のことです。

訓練データのスコアが過度に高く、テストデータのスコアが低いといった場合は、そのモデルは過学習している可能性があります。

今回の回帰モデルでは過学習の傾向は見られませんでしたが、テストデータのR2スコアが0.43とでるなど、モデルの精度が高くない結果となりました、

回帰⑤ (予測結果を可視化)

前回記事で、単回帰モデルの構築と予測を行いました。

今回はその予測結果を可視化し、構築したモデルの精度評価を行います。

散布図(訓練データ)

訓練データの予測結果を散布図で表示します。

[Google Colaboratory]

1
2
3
4
5
plt.scatter(X_train, y_train_pred)
plt.xlabel("X")
plt.ylabel("y")
plt.title("simple_reg")
plt.show()

[実行結果]

上図のように直線で表される結果となりました。

単回帰は学習によって y = ax + b傾き(a)切片(b)を算出します。

学習によって導き出された式に、検証データの説明変数(x)を代入することで予測値(y)が算出されます。

そのため結果はこの直線上にのることになります。

散布図(訓練データ・テストデータ)

訓練データの予測結果と合わせてテストデータの予測結果も散布図で表示します。

[Google Colaboratory]

1
2
3
4
5
6
7
plt.scatter(X_train, y_train_pred, label="train")
plt.scatter(X_test, y_test_pred, label="test")
plt.xlabel("X")
plt.ylabel("y")
plt.title("simple_reg")
plt.legend()
plt.show()

[実行結果]

テストデータの予測結果も、訓練データの予測結果と同じように直線状にのることが確認できました。

傾きと切片

この直線の傾き(a)切片(b)は出力することができます。

[Google Colaboratory]

1
2
print(f"a = {simple_reg.coef_[0][0]}")
print(f"b = {simple_reg.intercept_[0]}")

[実行結果]

予測のプロット

実際の値と予測値を合わせて可視化します。

[Google Colaboratory]

1
2
3
4
5
6
7
8
9
plt.scatter(X_train, y_train, label="train")
plt.scatter(X_test, y_test, label="test")
plt.plot(X_test, y_test_pred, color="red")

plt.xlabel("X")
plt.ylabel("y")
plt.title("simple_reg")
plt.legend()
plt.show()

[実行結果]

赤い直線が回帰によって算出されたものです。

実測値と直線の距離が近いほど、モデルの精度が高いことになります。

上図より、多くは直線付近に分布していますが、一部は直線から大きく離れていることが分かります。

残差プロット

予測値と実測値の差に焦点をあてて可視化を行います。

残差プロットという手法を使います。

[Google Colaboratory]

1
2
3
4
5
6
7
8
plt.scatter(y_train_pred, y_train_pred - y_train, label="train")
plt.scatter(y_test_pred, y_test_pred - y_test, label="test")
plt.plot([0, 50], [0,0] ,color="red")
plt.xlabel("Pred")
plt.ylabel("Pred - True")
plt.title("Residual Plot")
plt.legend()
plt.show()

[実行結果]

残差プロットでは、予測値と実測値の差が0である理想的な状態(赤い線)から、実際の差がどれだけばらついているかという傾向を視覚的に把握することができます。

上図より、密集部分でも-10~20と範囲が広く、中には±20を超える外れ値もあり、ばらつきが大きい状態となっていることが分かります。

回帰④ (単回帰モデルの構築)

単回帰モデルの構築を行います。

モデルとは、入力されたデータを何らかの基準に基づいて計算し結果を出力する仕組みのことです。

機械学習では訓練データの傾向から、この何らかの基準にあたる部分を定義します。

こうすることにより説明変数を入力すれば、予測値を出力する機械学習モデルが完成します。

データ分割

まずはデータを説明変数目的変数に分割します。

前回記事で予告した通り、説明変数にはRM(平均部屋数)を使用します。

[Google Colaboratory]

1
2
3
4
5
X = df[["RM"]]
y = df[["MEDV"]]

display(X.head())
display(y.head())

[実行結果]

次に、説明変数を訓練データテストデータに分割します。

  • 訓練データ
    学習に使用するデータ
  • テストデータ
    訓練データの学習によって構築されたモデルの精度評価を行うデータ

訓練データとテストデータは、7:3の割合で分割します。(3行目のtest_size=0.3で指定)

test_sizeは小数で指定すると割合、整数で指定すると個数として認識されます。

random_stateには再現性を確保するため0を指定しています。

[Google Colaboratory]

1
2
3
4
5
6
7
8
from sklearn.model_selection import train_test_split

X_train, X_test, y_train, y_test = train_test_split(X, y,test_size=0.3,random_state=0)

print(len(X_train))
display(X_train.head())
print(len(X_test))
display(X_test.head())

[実行結果]

訓練データ数が354、テストデータ数が152に分割されました。

単回帰モデルの構築

訓練データとテストデータの準備が完了しましたので、単回帰モデルの構築を行います。

scikit-learnLinearRegressionクラスを使用します。

[Google Colaboratory]

1
2
3
from sklearn.linear_model import LinearRegression

simple_reg = LinearRegression().fit(X_train, y_train)

3行目のfitメソッドで訓練データを学習させています。

これでモデルの構築はあっさり完了です。

モデルを使った予測

構築した単回帰モデルを使って予測結果を出力します。

predictメソッドに説明変数となるデータを渡すことで、予測を行うことができます。

[Google Colaboratory]

1
2
3
4
5
6
7
y_train_pred = simple_reg.predict(X_train)
y_test_pred = simple_reg.predict(X_test)

print(len(y_train_pred))
print(y_train_pred[:5])
print(len(y_test_pred))
print(y_test_pred[:5])

[実行結果]

予測結果が出力されました。

次回は、今回構築した単回帰モデルがどれくらいの精度で予測できているのかを評価します。

回帰③ (ボストン住宅価格データの相関)

ボストン住宅価格データの変数同士の相関係数を確認します。

相関とは、2つの変数間で一方が変わればそれにつられてもう一方も変わるという関係性のことです。

その相関度合いを数値化したものが相関係数です。

機械学習において、相関係数は説明変数を選択する上で重要な指標となります。

相関係数

pandascorrメソッドを使うと、相関係数を簡単に算出することができます。

[Google Colaboratory]

1
2
df_corr = df.corr()
display(df_corr)

[実行結果]

相関関係のヒートマップ

相関関係の大小を視覚的に確認するためヒートマップで可視化します。

[Google Colaboratory]

1
2
3
4
5
6
import seaborn as sns

plt.figure(figsize=(15,10))
sns.heatmap(df_corr, annot=True)
plt.title("Corr Heatmap")
plt.show()

[実行結果]

相関係数は-1~1の範囲の値をとります。

相関係数では次のような関係を意味します。

  • 正の相関
    一方が上がればもう一方も上がる関係
  • 負の相関
    一方が上がればもう一方が下がる関係
  • 相関係数の絶対値
    絶対値が大きいほど、相関関係が強い

ヒートマップから、目的変数であるMEDVと特に相関の強い変数はRM(0.7)LSTAT(-0.74)であることが分かります。

次回の単回帰分析では、データのばらつきが小さく、MEDVとの相関が強いRMを説明変数としてモデルを構築していきます。

回帰② (ボストン住宅価格データの概要)

前回準備したボストン住宅価格データの概要を見ていきます。

ボストンの住宅価格データの概要

pandasdescribeメソッドを使ってデータの概要を確認することができます。

[Google Colaboratory]

1
df.describe()

[実行結果]

count(データ数)mean(平均値)など代表的な数値が表示されました。

この数値から次のようなことが分かります。

  • 前回確認したデータ数と、各変数のcount(データ数)が一致しているので、欠損値はない。
  • CRIMとZNは第三四分位数と最大値に乖離があり、外れ値の存在が予想される。

もしも欠損値が含まれている場合は学習処理ができないので、除去や保管などであらかじめ対処しておく必要があります。

ヒストグラムによるばらつき確認

データのばらつきや外れ値を把握するために、ヒストグラムで表示して視覚的にデータを確認してみます。

[Google Colaboratory]

1
2
3
4
5
6
7
8
9
10
import matplotlib.pyplot as plt
%matplotlib inline

plt.figure(figsize=(20,5))
for i, col in enumerate(df.columns):
plt.subplot(2,7,i+1)
plt.hist(df[col])
plt.title(col)
plt.tight_layout()
plt.show()

[実行結果]

ヒストグラムから、CRIMやZNで外れ値があることが分かります。

またRMは比較的正規分布に近く、ばらつきが少ないようです。

目的変数であるMEDVも正規分布に近い形状ではありますが、一部外れ値が含まれているようです。

回帰① (ボストン住宅価格データ)

教師あり学習の回帰を行います。

今回は、回帰の問題を解くのに適したボストンの住宅価格データを準備します。

ボストンの住宅価格データは、機械学習のライブラリであるscikit-learnにサンプルデータとして含まれています。

ボストンの住宅価格が目的変数となっていて、それに寄与する犯罪率、平均部屋数等が説明変数として用意されています。

ボストンの住宅価格データの読み込み

ボストンの住宅価格データを読みこむソースコードは下記のようになります。

[Google Colaboratory]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
from sklearn.datasets import load_boston
boston = load_boston()

print("説明変数")
print(f"{len(boston.data)}件")
print(boston.data[:5])

print("目的変数")
print(f"{len(boston.target)}件")
print(boston.target[:5])

print("変数名")
print(f"{len(boston.feature_names)}件")
print(boston.feature_names)

[実行結果]

13種類の説明変数と1種類の目的変数がそれぞれ506件あることが確認できました。

データの内容を下記の一覧にまとめます。

カラム名内容
CRIM犯罪率
ZN25,000平方フィート以上の住宅区画割合
INDUS非小売業種の土地面積割合
CHASチャールズ川沿いかどうか
NOX窒素酸化物濃度
RM平均部屋数
AGE1940年より前の建物割合
DIS5つのボストン雇用施設への重み付き距離
RAD高速道路へのアクセス容易性
TAX10,000ドルあたりの不動産税率
PTRATIO生徒/教師の割合
B黒人割合
LSTAT低所得者割合
MEDV住宅価格(中央値)※目的変数

データフレーム化

読み込んだボストン住宅価格データをデータフレームに格納します。

目的変数はMEDVという項目名にしています。

[Google Colaboratory]

1
2
3
4
5
import pandas as pd

df = pd.DataFrame(boston.data,columns=boston.feature_names)
df["MEDV"] = boston.target
display(df.head())

[実行結果]

次回は、データフレーム化したデータを使ってデータの概要を確認します。


Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×