第一個機器學習模型:線性迴歸預測房價
經過前面兩章的資料準備,現在我們終於要訓練第一個機器學習模型了!
我們要解決的問題是:給定房屋的各種特徵(收入中位數、房屋年齡、房間數等),預測該房屋的 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),可以載入模型並預測新房價。」
本日總結
在本章中,你學到了:
- ✅ 線性迴歸原理:用一條直線(或超平面)來擬合資料
- ✅ Scikit-Learn API:fit → predict 的統一流程
- ✅ 評估指標:MAE、RMSE、R² 的意義與解讀
- ✅ 特徵權重分析:了解哪些因素對預測結果影響最大
- ✅ 模型儲存:使用 Joblib 儲存訓練好的模型
下一章,我們將學習分類問題——預測客戶是否會流失!