はじめに
このページでは、機械学習の基本的な手法である単回帰分析を用いて、カリフォルニア州の住宅価格を予測する方法を学びます。初めてプログラミングや機械学習に触れる方でも理解できるよう、ステップバイステップで解説していきます。
使用するデータセットは、カリフォルニア州の住宅に関する情報です。この中から、世帯の平均収入(MedInc)を用いて住宅価格を予測するモデルを構築します。
それでは、実際にPythonコードを見ながら、単回帰分析の流れを詳しく見ていきましょう。
ライブラリのインポート
まず、必要なライブラリをインポートします。
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
from sklearn import datasets
from sklearn.metrics import mean_squared_error, r2_score
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LinearRegression
各ライブラリの役割を説明します:
matplotlib.pyplot
: データの可視化に使用します。グラフを描画するのに便利です。numpy
: 数値計算や多次元配列の操作に使用します。pandas
: データの操作や分析に使用します。表形式のデータを扱うのに適しています。sklearn
(scikit-learn): 機械学習のアルゴリズムや関連する機能を提供するライブラリです。datasets
: サンプルデータセットを提供します。metrics
: モデルの性能評価に使用する指標を計算します。model_selection
: データの分割やモデル選択に関する機能を提供します。linear_model
: 線形回帰モデルを含む、様々な回帰モデルを提供します。
これらのライブラリをインポートすることで、データの読み込みから分析、モデリング、評価まで一連の作業を行うことができます。
データセットのインポート
次に、scikit-learnに用意されているカリフォルニア住宅データセットをインポートします。
dataset = datasets.fetch_california_housing()
fetch_california_housing()
関数を使用して、カリフォルニア住宅データセットをダウンロードし、dataset
変数に格納します。このデータセットには、カリフォルニア州の各地域の住宅に関する様々な特徴量と、それに対応する住宅価格の中央値が含まれています。
データセットの確認
データセットの内容を確認します。
print('特徴量:', dataset.feature_names)
print('目的変数:', dataset.target_names)
pd.set_option('display.max_columns', None)
df = pd.DataFrame(dataset.data, columns=dataset.feature_names)
df[dataset['target_names'][0]] = dataset.target
df.head()
出力
特徴量: ['MedInc', 'HouseAge', 'AveRooms', 'AveBedrms', 'Population', 'AveOccup', 'Latitude', 'Longitude']
目的変数: ['MedHouseVal']

ここでは以下の操作を行っています:
- データセットの特徴量(説明変数)と目的変数の名前を表示します。
- pandasの表示オプションを設定し、全ての列を表示できるようにします。
- データセットの特徴量をpandas DataFrameに変換します。
- 目的変数(住宅価格の中央値)をDataFrameに追加します。
- データの最初の5行を表示して、内容を確認します。
これらの操作により、データセットの構造や内容を把握することができます。
説明変数と目的変数に分割
次に、分析に使用する説明変数と目的変数を選択し、データを分割します。
select_features = ['MedInc']
X = df.loc[:1000, select_features].values
y = df.loc[:1000, dataset['target_names'][0]].values
ここでは以下の操作を行っています:
select_features
に、使用する説明変数(この場合は’MedInc’のみ)を指定します。X
に説明変数のデータを格納します。ここでは最初の1000行のみを使用しています。y
に目的変数(住宅価格の中央値)のデータを格納します。同じく最初の1000行のみです。
説明のために1000行に制限していますが、実際の分析では全データを使用することが一般的です。
訓練データとテストデータに分割
データを訓練用とテスト用に分割します。
X_train, X_test, y_train, y_test = train_test_split(
X, y, test_size=0.3, random_state=0)
train_test_split
関数を使用して、データを訓練用とテスト用に分割します。
test_size=0.3
: テストデータの割合を30%に設定します。random_state=0
: 乱数のシードを固定し、毎回同じ結果が得られるようにします。
データを分割する理由は、モデルの汎化性能を適切に評価するためです。訓練データでモデルを学習し、テストデータで性能を評価することで、未知のデータに対する予測性能を推定できます。
訓練データによるモデルの学習
線形回帰モデルを作成し、訓練データを使って学習させます。
regressor = LinearRegression()
regressor.fit(X_train, y_train)
LinearRegression()
で線形回帰モデルのインスタンスを作成します。fit()
メソッドを使用して、訓練データ(X_train, y_train)でモデルを学習させます。
この過程で、モデルは訓練データの特徴量(MedInc)と目的変数(住宅価格)の関係を学習し、最適な回帰直線を見つけ出します。
新しいデータポイントでの予測
学習したモデルを使って、新しいデータポイントでの予測を行います。
new_data = [[4.0]]
pred_label = regressor.predict(new_data)[0]
print(f'予測した{dataset.target_names}の値: {pred_label:.3f}')
出力
予測した['MedHouseVal']の値: 2.146
ここでは、世帯の平均収入(MedInc)が4.0の場合の住宅価格を予測しています。predict()
メソッドを使用して予測を行い、結果を小数点以下3桁まで表示しています。
テストデータで予測
次に、テストデータ全体に対して予測を行います。
y_pred = regressor.predict(X_test)
predict()
メソッドを使用して、テストデータ(X_test)に対する予測を行い、結果をy_pred
に格納します。これにより、モデルの性能を評価する準備が整います。
モデルの性能評価
モデルの性能を評価するために、平均二乗誤差(MSE)とR二乗(R^2)スコアを計算します。
print(f'MSE: {mean_squared_error(y_test, y_pred):.3f}' )
print(f'R^2: {r2_score(y_test, y_pred):.3f}')
出力
MSE: 0.341
R^2: 0.604
- 平均二乗誤差(MSE):予測値と実際の値の差(誤差)の二乗の平均です。0に近いほど良いモデルとされています。
- R二乗(R^2)スコア:モデルの当てはまりの良さを示す指標です。1に近いほど良いモデルで、0に近いほど悪いモデルとされています。負の値の場合は非常に悪いモデルを意味します。
これらの指標を用いることで、モデルがどの程度正確に予測できているかを数値的に評価できます。
性能評価の可視化
最後に、モデルの性能を視覚的に評価するためのグラフを描画します。
def calculate_bounds(X):
X_min, X_max = X.min() - (X.max() - X.min()) / 20, X.max() + (X.max() - X.min()) / 20
return X_min, X_max
def plot_data(ax, X_set, y_set, X_min, X_max, regressor, kind):
X_range = np.linspace(X_min, X_max, 100).reshape(-1, 1)
y_pred = regressor.predict(X_range)
ax.scatter(X_set, y_set, color='red', alpha=0.5, marker='o', edgecolor='black', label='Actual')
ax.plot(X_range, y_pred, color='blue', label='Prediction')
ax.set_xlabel(select_features[0])
ax.set_ylabel(dataset['target_names'][0])
ax.set_title(f'Linear Regression ({kind})')
ax.legend(loc='best')
def plot_regression_performance(X_train, X_test, y_train, y_test, regressor):
X_combined = np.vstack((X_train, X_test))
X_min, X_max = calculate_bounds(X_combined)
fig, ax = plt.subplots(1, 2, figsize=(12, 6))
plot_data(ax[0], X_train, y_train, X_min, X_max, regressor, "Training set")
plot_data(ax[1], X_test, y_test, X_min, X_max, regressor, "Test set")
plt.tight_layout()
plt.show()
plot_regression_performance(X_train, X_test, y_train, y_test, regressor)
出力

この部分では、以下の操作を行っています:
calculate_bounds()
: データの範囲を少し広げて、グラフの見栄えを良くします。plot_data()
: 実際のデータ点と予測線をプロットします。plot_regression_performance()
: 訓練データとテストデータそれぞれについて、データ点と予測線を別々のグラフにプロットします。
これらの関数を使用して、訓練データとテストデータそれぞれについて、実際のデータ点(赤)と予測線(青)を描画します。この可視化により、モデルがデータにどの程度フィットしているか、過学習や適合不足の問題がないかなどを視覚的に確認できます。
まとめ
このチュートリアルでは、カリフォルニア住宅データセットを使用して、単回帰分析の基本的な流れを学びました。
この例では、世帯の平均収入(MedInc)のみを使用して住宅価格を予測するシンプルなモデルを作成しました。実際の分析では、より多くの特徴量を使用したり、より複雑なモデルを適用したりすることで、予測精度を向上させることができます。
単回帰分析は機械学習の基礎となる重要な手法です。この手法を理解することで、より複雑な分析手法への足がかりとなります。ぜひ、このコードを基に様々なデータセットで実験を行い、理解を深めてください。
[mathjax]
本コンテンツへの意見や質問