【機械学習入門 第2回】最初の予測モデル!Scikit-learnで線形回帰(Linear Regression)に挑戦しよう(住宅価格予測編)
「Scikit-learnのfit
とpredict
の使い方は分かったけど、実際のデータではどう使うの?」
「機械学習で『数値を予測する』って、具体的にどんな手順でやるんだろう?」
「データサイエンスの第一歩として、何か実践的なモデルを作ってみたい!」
こんにちは! AI・機械学習探検隊、隊長のPythonistaです! 前回の第1回では、機械学習の基本的な概念と、Scikit-learnの驚くほどシンプルで一貫したAPI(fit
/predict
)の流れを学びましたね。これで、機械学習モデルを訓練し、予測を行うための「設計図」を手に入れました。
シリーズ第2回の今回は、いよいよその設計図を元に、最初の本格的な予測モデルを構築していきます! 今回挑戦するのは、教師あり学習の一分野である「回帰 (Regression)」です。回帰とは、過去のデータから学習し、新しいデータに対して連続する**数値**(例: 価格、気温、売上など)を予測するタスクです。題材として、現実のデータに近い「カリフォルニアの住宅価格データセット」を使い、最も基本的で強力な回帰モデルである「線形回帰 (Linear Regression)」で、住宅価格の予測に挑戦します。Pythonで家の値段を予測する、そんな未来的な体験を一緒に楽しみましょう!
1. 準備:ライブラリのインポート
まずは、今回使用するライブラリをインポートします。データ探索のためにPandas、可視化のためにMatplotlibも使います。
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns # より美しいグラフのためにSeabornもインポート
# Scikit-learnから必要なモジュールをインポート
from sklearn.datasets import fetch_california_housing
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LinearRegression
from sklearn.metrics import mean_squared_error, r2_score
# 見た目の設定
sns.set_theme(style="whitegrid", palette="pastel")
plt.rcParams['font.family'] = 'IPAexGothic' # 日本語フォント設定
2. ステップ1:データを知る(データの読み込みと探索)
機械学習プロジェクトは、常に「データを知る」ことから始まります。Scikit-learnには練習用のデータセットが付属しており、今回は「カリフォルニアの住宅価格データセット」を使います。
2.1. データの読み込み
fetch_california_housing()
関数でデータセットを読み込みます。このデータセットには、住宅価格に影響を与えそうな様々な特徴量(所得、部屋数など)と、正解ラベルである住宅価格の中央値が含まれています。
# カリフォルニア住宅価格データセットをロード
housing = fetch_california_housing()
# どんなデータか確認
print(housing.DESCR) # データセットの説明を表示
実行すると、データセットの詳細な説明が表示されます。どのような特徴量(MedInc
: 所得の中央値など)があるか、一度目を通しておくと良いでしょう。
2.2. Pandas DataFrameでデータを探索
Scikit-learnのデータセットは、PandasのDataFrameに変換すると非常に扱いやすくなります。
# データをDataFrameに変換
df = pd.DataFrame(housing.data, columns=housing.feature_names)
# ターゲット(目的変数)である住宅価格を新しい列として追加
df['MedHouseVal'] = housing.target
print(f"\nデータフレームの形状: {df.shape}")
print("\n最初の5行:")
print(df.head())
print("\n基本的な統計情報:")
print(df.describe())
.head()
や.describe()
で、データの雰囲気や各特徴量のスケール感を掴みます。
2.3. データを可視化してみる
特徴量と住宅価格の関係を視覚的に見てみましょう。ここでは、最も価格に影響を与えそうな「所得の中央値 (MedInc
)」と「住宅価格 (MedHouseVal
)」の関係を散布図でプロットします。
plt.figure(figsize=(8, 6))
plt.scatter(df['MedInc'], df['MedHouseVal'], alpha=0.1) # alphaで点の透明度を設定
plt.title('所得の中央値と住宅価格の関係')
plt.xlabel('所得の中央値 (MedInc)')
plt.ylabel('住宅価格の中央値 (MedHouseVal)')
plt.show()
グラフを見ると、所得が高いほど住宅価格も高くなる、という正の相関がありそうなことが見て取れますね。線形回帰は、このようなデータに対して「最も当てはまりの良い直線」を見つけ出すアルゴリズムです。
3. ステップ2:データを準備する(訓練用とテスト用に分割)
機械学習における非常に重要なステップが、手持ちのデータを訓練用データ (Training data)とテスト用データ (Test data)に分割することです。
なぜ分割が必要なの?
モデルを訓練したデータと、そのモデルの性能を評価するデータを同じにしてしまうと、モデルが単に「答えを丸暗記」しているだけなのか、それとも未知のデータに対しても正しく予測できる「汎化能力」を持っているのかを正しく評価できません。そのため、カンニングができないように、モデルが一度も見たことのないテスト用データで最終的な性能を評価する必要があるのです。
この分割は、train_test_split()
関数で簡単に行えます。
# 特徴量 X と ターゲット y を定義
X = df.drop('MedHouseVal', axis=1) # ターゲット列以外が特徴量
y = df['MedHouseVal'] # ターゲット列
# データを訓練用とテスト用に分割 (例: 80%を訓練用, 20%をテスト用)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
# random_stateは、毎回同じように分割するための乱数の種。再現性のために指定する。
print(f"訓練データ(X_train)の形状: {X_train.shape}")
print(f"テストデータ(X_test)の形状: {X_test.shape}")
これで、モデルを訓練する準備が整いました!
4. ステップ3:線形回帰モデルの構築と訓練
いよいよ、前回学んだScikit-learnのAPIに沿って、モデルの構築と訓練を行います。
# 1. モデルの選択とインポート (済)
# from sklearn.linear_model import LinearRegression
# 2. モデルのインスタンス化
model = LinearRegression()
# 3. モデルの学習 (fit) - 訓練データのみを使う!
model.fit(X_train, y_train)
print("\n線形回帰モデルの学習が完了しました!")
# 学習したモデルの係数(各特徴量の重み)と切片を確認
print(f"モデルの係数 (Coefficients): {model.coef_}")
print(f"モデルの切片 (Intercept): {model.intercept_}")
model.fit()
を実行すると、モデルはX_train
とy_train
の関係性を学習し、最適なパラメータ(この場合は係数と切片)を見つけ出します。これで、私たちの住宅価格予測モデルが完成しました!
5. ステップ4:モデルの評価
モデルが完成したら、その性能を評価します。ここで、取っておいた**テスト用データ**の出番です。
5.1. テストデータで予測を行う (.predict()
)
学習済みのモデルに、一度も見せたことのないX_test
を入力し、住宅価格を予測させます。
# テストデータを使って予測
y_pred = model.predict(X_test)
# 実際の値と予測値を比較してみる
comparison_df = pd.DataFrame({'実際の価格': y_test, '予測価格': y_pred})
print("\n--- 実際の価格 vs 予測価格 (最初の5件) ---")
print(comparison_df.head())
5.2. 評価指標で性能を定量化
見た目だけでなく、数値的な指標でモデルの性能を評価しましょう。回帰モデルでは、主に以下の指標が使われます。
- 平均二乗誤差 (Mean Squared Error, MSE): 予測値と実際の値の差(誤差)を2乗したものの平均。値が小さいほど良いモデルです。
- 決定係数 (R-squared, R²): モデルがデータのばらつきをどれだけ説明できているかを示す指標。1に近いほど良いモデルです(最大値は1.0)。
# 評価指標を計算
mse = mean_squared_error(y_test, y_pred)
r2 = r2_score(y_test, y_pred)
# model.score(X_test, y_test) でもR2スコアを計算できる
print("\n--- モデルの性能評価 ---")
print(f"平均二乗誤差 (MSE): {mse:.2f}")
print(f"決定係数 (R^2): {r2:.2f}")
決定係数が例えば0.60なら、「このモデルは住宅価格のばらつきの約60%を説明できている」と解釈できます。
5.3. 予測結果を可視化
最後に、実際の価格と予測価格がどれくらい一致しているかを散布図で見てみましょう。完璧な予測なら、全ての点がy=xの直線(赤い線)上に乗るはずです。
plt.figure(figsize=(8, 8))
plt.scatter(y_test, y_pred, alpha=0.3)
plt.plot([y_test.min(), y_test.max()], [y_test.min(), y_test.max()], '--r', linewidth=2) # y=xの理想線
plt.title('実際の価格 vs 予測価格')
plt.xlabel('実際の価格 (Actual Price)')
plt.ylabel('予測価格 (Predicted Price)')
plt.show()
点が赤い線に沿って分布していれば、モデルがある程度うまく予測できていることが分かりますね。
まとめと次回予告
おめでとうございます!あなたは、機械学習プロジェクトの一連の流れを完遂し、最初の予測モデルを構築することができました!
- 回帰 (Regression) とは、連続する数値を予測するタスクであること。
- データを探索・可視化し、特徴を理解することの重要性。
- モデルの性能を正しく評価するための、訓練データとテストデータへの分割。
- Scikit-learnの
fit
/predict
APIを使った、線形回帰モデルの構築と訓練、そして予測。 - MSEやR²スコアといった指標を使った、モデル性能の定量的な評価方法。
今回は最も基本的な線形回帰を使いましたが、Scikit-learnにはさらに強力な回帰モデルがたくさんあります。しかし、どんなに複雑なモデルでも、この「データ準備→訓練→予測→評価」という基本的な流れはほとんど変わりません。この流れをマスターしたことは、非常に大きな一歩です。
さて、今回は数値を予測する「回帰」に挑戦しました。しかし、世の中には「このメールは迷惑メールか否か」「この花の種類は何か」といった、数値を当てるのではなく**カテゴリを当てる**問題もたくさんあります。
次回、第3回では、そのような「分類 (Classification)」の問題に挑戦します!有名なアヤメ(Iris)のデータセットを使い、その花がどの品種に属するかを予測するモデルを、「ロジスティック回帰」や「k近傍法」といった古典的で強力な分類アルゴリズムを使って構築していきます。お楽しみに!
コメント
コメントを投稿