pythonによる回帰分析〜重回帰モデル入門

こんにちは、デジタルボーイです。前回は機械学習や統計モデルの初めの一歩とも言える、単回帰分析について学習しました。

そして、今回は単回帰モデルからの発展ということで重回帰モデルについて、Pythonとscikit-learnを使い、解説したいと思います!

データ分析を始めたばかりの方にとって、複数の要因が影響する問題を予測するのは少し難しく感じるかもしれません。しかし、「重回帰モデル」を使えば、複数の特徴量を考慮してより正確な予測が可能になります。本記事では、Scikit-learn(sklearn)を使って重回帰モデルを実装し、視覚的にその動作を理解できるように解説します!

記事を書いた人

デジタルボーイです。
データサイエンス歴20年以上のおっさんです。中小企業診断士として、データサイエンス、WEBマーケティング、SEOに関するデータ分析、コンサルティングの仕事をしています。自己紹介の詳細はコチラ

目次

重回帰モデルとは?

重回帰(Multiple Linear Regression)は、複数の説明変数(特徴量)を使って目的変数(予測したい値)を説明するモデルです。基本的な線形回帰と違い、1つの変数だけでなく、複数の変数が影響を与える場合に使われます。

活用例:

  • 住宅価格の予測
    → 家の広さ、部屋数、築年数、周辺の犯罪率などの要因を考慮して価格を予測
  • 売上の予測
    → 広告費、店舗の立地、営業時間、天気などの要素を元に売上を予測
  • 健康診断データからの体脂肪率の予測
    → 年齢、身長、体重、運動習慣などを考慮して体脂肪率を推定

必要なライブラリとインストール方法

まずは必要なライブラリを読み込みましょう。

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LinearRegression
from sklearn.metrics import mean_squared_error, r2_score
from sklearn.datasets import fetch_california_housing

もし、必要なライブラリがインストールされていない場合は、pipでインストールしておきましょう。

pip install numpy pandas matplotlib scikit-learn

pipを使ったインストール方法はこちらになります。

データの読み込みと概要の確認

Scikit-learnの「California housing dataset(カリフォルニア住宅価格データ)」を使用します

# データを取得
data = fetch_california_housing()
df = pd.DataFrame(data.data, columns=data.feature_names)
df["Price"] = data.target  # 住宅価格を追加

# データの概要を表示
print(df.head())
print(df.describe())

コードの解説

  • fetch_california_housing() でScikit-learnの住宅データを取得
  • pd.DataFrame() でデータをPandasのデータフレームに変換
  • df["Price"] = data.target で住宅価格を追加
  • head() でデータの先頭5行を表示
  • describe() で統計情報(平均値・標準偏差・最大値など)を確認

データの初めの5件はこんな感じです。

データの統計情報は以下のように出力されました。

分析の目的とゴール

では、実際のこのデータを使って分析してみましょう。

目的
住宅価格に影響を与える要因(年収、部屋数、築年数など)を分析し、価格を予測するモデルを作成する。

ゴール

  • 特徴量の影響を直感的に理解する
  • 重回帰モデルを作成し、予測精度を評価する
  • 結果をグラフ化し、モデルの出力を解釈する

データの可視化

まず、いくつかの特徴量と価格の関係を可視化してみます。

plt.rcParams["font.family"] = "Hiragino sans"

plt.figure(figsize=(12, 5))

plt.subplot(1, 2, 1)
plt.scatter(df["MedInc"], df["Price"], alpha=0.5)
plt.xlabel("年収中央値 (MedInc)")
plt.ylabel("住宅価格 (Price)")
plt.title("年収と住宅価格の関係")

plt.subplot(1, 2, 2)
plt.scatter(df["AveRooms"], df["Price"], alpha=0.5, color='red')
plt.xlabel("平均部屋数 (AveRooms)")
plt.ylabel("住宅価格 (Price)")
plt.title("平均部屋数と住宅価格の関係")

plt.show()

    

コードの解説

  • plt.rcParams["font.family"] = "Hiragino sans"でMac用の日本語フォントをを指定。Windowsの場合は、plt.rcParams[“font.family”] = “Meiryo”などにする。
  • plt.figure(figsize=(12, 5)) でグラフのサイズを指定
  • plt.subplot(1, 2, 1)は、1枚のプロット画像に複数のグラフ(サブプロット)を描画するための指定。具体的には、カッコ内の数値で「1行2列の1番目にプロットしなさい」という指定。以降に出てくるplt.subplot(1, 2, 2)は「1行2列の2番目にプロットしなさい」という指定。
  • plt.scatter() で散布図を描画
  • alpha=0.5 で透明度を設定し、データの密集度を見やすくする
  • subplot() を使って複数のグラフを並べて表示

アウトプットはこんな感じです。

左側のグラフは年収と住宅価格の関係性をプロットしたものです。縦軸の住宅価格は1,2,3,4,5となっています、おそらく10万ドル単位なのでしょう。また、5のところ(50万ドル)のところで上限が切られているようですね。本来は5以上のデータとして持っているのでしょうが、上限を5に置き換えたデータとしているようです。概ね、収入が上がれば上がるほど、住宅価格は高くなる傾向が見えました。

右側は部屋数と住宅価格のプロットです。0から10くらいの部屋数にびっしりとデータが詰まっているようで、一見するとそれほど関係性は高くなさそうですね。

重回帰モデルの作成と学習

それでは、すべての特徴量を使って、重回帰モデルを作成してみましょう。

# 特徴量とターゲットを設定
X = df.drop(columns=["Price"])  # すべての特徴量を使用
y = df["Price"]

# 訓練データとテストデータに分割
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

# モデルの作成と学習
model = LinearRegression()
model.fit(X_train, y_train)

# 予測
y_pred = model.predict(X_test)

コードの解説

  • drop(columns=["Price"]) で目的変数(住宅価格)を除外し、特徴量だけをXに設定
  • train_test_split() でデータを訓練用とテスト用に分割(80%:20%)
  • LinearRegression() で重回帰モデルを作成
  • fit() でモデルを学習
  • predict() でテストデータを予測

モデルの評価

続いて、構築したモデルの精度をMSE、RMSE、決定係数(R²)で評価してみましょう。

# 評価指標の計算
mse = mean_squared_error(y_test, y_pred)
rmse = np.sqrt(mse)
r2 = r2_score(y_test, y_pred)

print(f"Mean Squared Error (MSE): {mse:.2f}")
print(f"Root Mean Squared Error (RMSE): {rmse:.2f}")
print(f"R² Score: {r2:.2f}")

コードの解説

  • mean_squared_error() でMSE(誤差の2乗の平均)を計算
  • np.sqrt(mse) でRMSE(MSEの平方根)を計算し、誤差の大きさを直感的に理解しやすくする
  • r2_score() で決定係数(R²)を計算し、モデルの説明力を評価(1に近いほど良いモデル)

結果はこんな感じでした。

簡単に、それぞれの評価指標についてみていきましょう。

MSE(平均二乗誤差)は、予測値と実際の値の差を二乗し、それらの平均を取ったものです。数値が小さいほどモデルの誤差が少なく、より正確に予測できていることを意味します。ただし、単位が元のデータの単位の二乗になってしまうため、直感的に解釈しにくいという欠点があります。

RMSE(ルート平均二乗誤差)は、MSEの平方根を取ったものです。MSEと異なり、元のデータと同じ単位になるため、直感的に理解しやすくなります。例えば、住宅価格を予測する場合、RMSEが10万円であれば、平均的に10万円の誤差があると解釈できます。値が小さいほど予測の精度が高いことを意味します。

決定係数(R²)は、モデルがどれだけデータをうまく説明できているかを示す指標です。値は0から1の範囲を取り、1に近いほどモデルの予測が正確であることを示します。0に近い場合は、「単に平均値を予測するのと変わらない」ことを意味し、モデルの説明力が低いことを示します。一般的に0.7以上であれば良いモデルと考えられます。今回のモデルの結果から、R²スコア(決定係数)が 0.58 というのは、このモデルが住宅価格のばらつきの 58% を説明できていることを意味します。R²の値は1に近いほど良いモデルで、0.7以上であれば良好とされることが多いですが、今回の 0.58 ではやや説明力が不足している可能性があります。

結果の可視化

では、実測値と予測値の関係を散布図で見てみましょう。

plt.scatter(y_test, y_pred, alpha=0.5)
plt.xlabel("住宅価格の実測値")
plt.ylabel("住宅価格の予測値")
plt.title("実測値と予測値の関係")
plt.show()

コードの解説

  • scatter(y_test, y_pred) で実際の価格と予測値を比較
  • 完璧な予測なら、点が直線的に並ぶはず

結果はこんな感じです。

実データでは住宅価格は5を上限に置き換えられている一方、予測値は5以上の値も予測しているため、右端のデータの分布が歪な形状になっています。それ以外は概ね、実際の価格が上がるにつれ、予測値も上がっており大まかな関係性はモデルで説明しているようですね!

具体的に実測値と予測値の関係を相関係数で測定してみましょう。

# y_test, y_predの相関係数
correlation = np.corrcoef(y_test, y_pred)[0, 1]
print(f"相関係数: {correlation:.2f}")

コードのnp.corrcoef(y_test, y_pred)[0, 1]でy_testとy_predのデータの相関関係を計算しています。アウトプットはこんな感じです。

相関係数が0.76なので強い相関(xの直線的な増加に対して、yが直線的に増加する関係)が見られます。

相関係数については以下にも詳しく書いてあるので、よかったら見てください。

モデルの解釈

続いて、構築した重回帰モデルの中身を見ていきましょう。

# 切片(Intercept)を出力
print(f"Intercept (切片): {model.intercept_}")

# 各変数の回帰係数を出力
coefficients = pd.DataFrame({"Feature": X.columns, "Coefficient": model.coef_})
print(coefficients)

コード解説

  • model.intercept_回帰式の切片 を表す。
  • model.coef_各説明変数の回帰係数(影響度) を示す。 pd.DataFrame() を使って、特徴量の名前(X.columns)と対応する回帰係数を一覧化し、見やすく整理。
  • print(coefficients) で、どの変数が住宅価格にどの程度影響を与えるかを確認できる。

実際の結果はこんな感じでした。

内容は以下のように解釈します。

  • 切片(Intercept)
    model.intercept_ の値は -37.02となっています。これは、すべての説明変数が 0 のときの住宅価格を示します。まあ、実際には意味のある値ではないことが多いです。
  • 回帰係数(Coefficient)
    model.coef_ の値は、それぞれの特徴量が価格に与える影響を示しています。例えば、MedInc(世帯の中央値所得) の係数が 0.448675 なら、世帯所得が1単位増加すると住宅価格が約0.44上昇する ことを意味します。逆に、Longitude(経度) の係数が -0.433708 なら、経度が1単位増加すると価格が約0.43下がる ことを示します。

回帰係数を詳しく分析することで、どの要因が住宅価格にどの程度影響を与えているのかが見えてきます。

まとめ

以上、重回帰分析の概要について見てみました!今回学んだことは以下となります。

学んだこと

  • 重回帰モデルとは? → 複数の特徴量を使って予測する線形回帰モデル
  • 現実での活用例 → 住宅価格、売上、健康データの予測など
  • 実装方法 → Scikit-learnのLinearRegressionを使う
  • 結果の解釈 → MSE、RMSE、R²でモデルを評価

重回帰モデルは、実データの分析で非常によく使われる基本モデルです。次のステップとして、特徴量の選択や正則化手法(Lasso, Ridge)を試してみると、より精度の高いモデルを作れるようになります!

目次