6 重回帰分析
6.1 重回帰分析
次に、特徴量が3つ(気温と湿度とイベント参加人数)のデータを回帰分析してみます。このような特徴量が複数ある回帰分析を重回帰分析といいます。
気温、湿度、イベント人数とアイスクリームの売り上げです。 ファイル ice2.ipynb に以下を記述します。
import pandas as pd
df = pd.read_csv("ice2.csv")
df
気温・湿度・イベント人数と売上の相関関係を散布図行列で確認してみましょう。
import matplotlib.pyplot as plt
import seaborn as sns
sns.set_theme(font=["Meiryo"])
sns.pairplot(data=df, kind="reg")
plt.show()
気温が上がると売上が上がります。湿度、イベント人数も同様です。
6.2 重回帰分析の学習
では、モデルを構築し、学習してみましょう。そのやり方は単回帰分析と変わりません。
まずは特徴量を x に、正解ラベルを y に入れ、学習用とテスト用のデータに分割し学習を行います。
x = df[["気温", "湿度", "イベント人数"]]
y = df["売上"]
from sklearn.model_selection import train_test_split
x_train, x_test, y_train, y_test = train_test_split(x, y, test_size = 0.2, random_state=0)
from sklearn.linear_model import LinearRegression
model = LinearRegression()
# 学習する
model.fit(x_train, y_train)
予測するときには、気温と湿度、イベント人数を指定します。 気温30度、湿度60%、イベント人数2000人の予測を行ってみます。
model.predict([[30, 60, 2000]])
決定係数を見てみましょう。
model.score(x_test, y_test)
6.3 影響度
重回帰分析でも回帰式は同様です。ただし、特徴量が複数になります。
- 特徴量1×係数1+特徴量2×係数2+特徴量3×係数3+切片
係数 model.coef_ 切片 model.intercept_ を確認しましょう。係数は複数あります。
# データフレームで係数表示
import pandas as pd
pd.DataFrame(model.coef_, index=x_train.columns, columns=["係数"])
#切片
model.intercept_
例えば係数が[2.83, 1.32, 0.006]、切片が-159 の場合、以下のようにして売上を計算しています。
- 気温×2.83+湿度×1.32+イベント人数×0.006 - 159
上の例の場合、気温は1度上がるたびに売上が2.83増えます。湿度が1上がるたびに売上が1.32増えます。
6.4 標準化
係数の大きさを売上に与える影響度と考えると、イベント人数は売上にほとんど影響を与えないとなりますが、果たしてそうでしょうか。散布図を見るとイベント人数が増えると売上が明らかに増えているのにおかしい感じがします。
これはイベント人数の数値と気温や湿度の数値に大きな差があるため起きる現象です。イベント人数は何千人もの数値が普通にあるのに、気温は二桁しかありません。数値の大きさが大幅に異なるのでイベント人数の影響度は大きく下がってしまったのです。
このような数値の大きさによる影響を避けるために、全ての数値を一定の平均値になるように変換する処理を行います。これを標準化といいます。具体的には平均値を0、分散1になるように数値を変換します。
これもscikit-learnで行うことが出来ます。 まず、x_trainを標準化してみます。
from sklearn.preprocessing import StandardScaler
# 標準化モデル生成
sc_model = StandardScaler().fit(x_train)
# 標準化
sc_x = sc_model.transform(x_train)
# 標準化されたx_trainを確認
sc_x
0を平均とした値になります。 この標準化した値を元に学習を行います。
# 学習する
model.fit(sc_x, y_train)
決定係数はx_testを標準化したもので行います。結果は標準化前と同じです。
sc_x_test = sc_model.transform(x_test)
model.score(sc_x_test, y_test)
しかし、係数を出すと標準化前とは大きく異なる値が出ているはずです。
import pandas as pd
pd.DataFrame(model.coef_, index=x_train.columns, columns=["係数"])
これにより影響度の大きさを正しく算出することが出来ます。