第一個機器學習模型:線性迴歸預測房價

經過前面兩章的資料準備,現在我們終於要訓練第一個機器學習模型了!

我們要解決的問題是:給定房屋的各種特徵(收入中位數、房屋年齡、房間數等),預測該房屋的 median 房價。

這是一個典型的 迴歸問題 (Regression)——我們要預測一個連續的數值。

線性迴歸的直覺理解

線性迴歸 (Linear Regression) 是最簡單也最基礎的迴歸演算法。它的核心概念就是:畫一條最符合資料趨勢的直線。

想像你在紙上畫了許多點(每個點代表一間房子,X 軸是面積,Y 軸是價格),線性迴歸就是在找一條「最接近所有點的直線」。

這條直線的數學式很簡單:

$$y = mx + b$$

  • $y$:預測價格(輸出)
  • $x$:房屋面積(輸入特徵)
  • $m$:斜率(權重)——面積每增加一單位,價格增加多少
  • $b$:截距——當面積為 0 時的基礎價格

當我們有多個特徵時(面積、房間數、屋齡),公式就變成:

$$y = w_1x_1 + w_2x_2 + ... + w_nx_n + b$$

線性迴歸的「學習」過程,就是在自動找出最佳的 $w$(權重)與 $b$(截距),讓預測值與真實值的誤差最小。

使用 Scikit-Learn 訓練模型

Scikit-Learn 是 Python 中最流行的機器學習函式庫,它的 API 設計得非常簡單一致:

# 1. 導入你想使用的演算法
from sklearn.linear_model import LinearRegression

# 2. 建立模型物件
model = LinearRegression()

# 3. 訓練模型(餵資料)
model.fit(X_train, y_train)

# 4. 進行預測
y_pred = model.predict(X_test)

沒錯,就這麼簡單!

完整程式碼

import pandas as pd
import numpy as np
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_absolute_error, mean_squared_error, r2_score
import matplotlib.pyplot as plt

# === 1. 載入資料 ===
housing = fetch_california_housing()
X = pd.DataFrame(housing.data, columns=housing.feature_names)
y = housing.target

# === 2. 分割資料 ===
X_train, X_test, y_train, y_test = train_test_split(
    X, y, test_size=0.2, random_state=42
)

# === 3. 訓練模型 ===
model = LinearRegression()
model.fit(X_train, y_train)

# === 4. 預測 ===
y_pred = model.predict(X_test)

# === 5. 評估 ===
mae = mean_absolute_error(y_test, y_pred)
mse = mean_squared_error(y_test, y_pred)
rmse = np.sqrt(mse)
r2 = r2_score(y_test, y_pred)

print(f"平均絕對誤差 (MAE): {mae:.4f}")
print(f"均方根誤差 (RMSE): {rmse:.4f}")
print(f"R² 分數: {r2:.4f}")

# === 6. 畫出預測 vs 真實值 ===
plt.figure(figsize=(8, 6))
plt.scatter(y_test, y_pred, alpha=0.5)
plt.plot([y_test.min(), y_test.max()], [y_test.min(), y_test.max()], 'r--')
plt.xlabel('真實價格')
plt.ylabel('預測價格')
plt.title('線性迴歸:預測值 vs 真實值')
plt.show()

如何解讀模型評估指標?

訓練完模型後,最重要的問題是:這個模型到底準不準?

1. 平均絕對誤差 (MAE)

$$MAE = \frac{1}{n}\sum_{i=1}^{n}|y_i - \hat{y}_i|$$

MAE 的意思是:「平均每次預測,誤差了多少錢(或多少單位)。」

  • 如果 MAE = 0.5,代表平均每次預測的房價誤差為 5 萬美元
  • 優點:直觀易懂
  • 缺點:對大誤差的懲罰不夠重

2. 均方根誤差 (RMSE)

$$RMSE = \sqrt{\frac{1}{n}\sum_{i=1}^{n}(y_i - \hat{y}_i)^2}$$

RMSE 跟 MAE 類似,但它會對「大誤差」給予更重的懲罰(因為誤差先平方再開根號)。

  • 如果 RMSE 遠大於 MAE,代表模型在某些資料上出現了非常大的誤差

3. R² 分數(最重要的指標!)

R² 代表「模型能解釋多少比例的資料變異性」:

  • R² = 1.0:完美預測(實務上不可能)
  • R² = 0.8:模型能解釋 80% 的房價變動,相當不錯
  • R² = 0.5:模型只能解釋一半,勉強可用
  • R² = 0.0:模型跟隨便亂猜差不多
  • R² < 0.0:模型比亂猜還糟(代表有問題)

對於房價預測這種高度複雜的問題,R² 在 0.6 - 0.8 之間就已經是相當不錯的模型了。

查看模型學到了什麼

訓練完成後,我們可以查看每個特徵的「權重」(coefficients),了解哪些因素對房價影響最大:

# 特徵名稱(加州房價資料集)
feature_names = [
    '收入中位數', '房屋年齡', '房間數', '臥室數',
    '人口', '家庭數', '緯度', '經度'
]

# 查看每個特徵的權重
coefficients = pd.DataFrame({
    '特徵': feature_names,
    '權重': model.coef_
})
print(coefficients.sort_values('權重', ascending=False))

# 查看截距
print(f"\n截距 (b): {model.intercept_:.4f}")

輸出範例:

     特徵      權重
0  收入中位數  0.4375
2    房間數    0.0102
4    人口     -0.0007
3    臥室數   -0.0064
7    經度     -0.0412
1  房屋年齡   -0.0058
6    緯度     -0.0421
5    家庭數   -0.0090

這告訴我們:

  • 收入中位數對房價的正面影響最大(收入越高,房價越高)
  • 緯度與經度也有顯著影響(地點很重要!)
  • 臥室數的權重為負值(房間越多不一定越貴?可能是因為小坪數但多隔間的套房較多)

使用 Vibe Coding 訓練模型

不想手寫程式?讓 AI 幫你:

🔥 【模型訓練詠唱範例】 「我有一個 clean_house_data.csv,請幫我: 1. 使用 LinearRegression 訓練房價預測模型。 2. 計算 MAE、RMSE、R² 並輸出。 3. 畫出預測值 vs 真實值的散佈圖。 4. 輸出每個特徵的權重,並解釋哪個特徵對房價影響最大。 5. 使用 Joblib 儲存模型為 house_price_model.pkl。 6. 寫一個預測函式 load_and_predict(features),可以載入模型並預測新房價。」

本日總結

在本章中,你學到了:

  1. 線性迴歸原理:用一條直線(或超平面)來擬合資料
  2. Scikit-Learn API:fit → predict 的統一流程
  3. 評估指標:MAE、RMSE、R² 的意義與解讀
  4. 特徵權重分析:了解哪些因素對預測結果影響最大
  5. 模型儲存:使用 Joblib 儲存訓練好的模型

下一章,我們將學習分類問題——預測客戶是否會流失!

解鎖完整教學內容

本章為付費內容。加入專案即可解鎖超過 5000 字的深度解析,包含 10 個以上神級 Prompt 與真實 Source Code 範例!