Learning Objectives
- 說明殘差與 MSE,並用它們比較兩條直線
- 用 numpy 寫出最小平方法,算出斜率與截距
- 用 RMSE 與 R² 評估模型,並和「一律猜平均」比較
- 讀懂係數:說明它代表的是資料裡的關聯,不是因果
用一條直線預測數字
想用期中分數預測期末分數,答案是連續的數字,所以是迴歸。最簡單的模型是一條直線:
預測值 = w × x + b
x 是特徵,w 是斜率(x 多 1,預測值多多少),b 是截距(x 是 0 時的預測值)。訓練這個模型,就是找出最好的 w 和 b。
什麼叫「最好」?要有一個分數。每一筆資料,實際值減掉預測值叫殘差(residual):
殘差 = 實際值 − 預測值
殘差有正有負,直接加起來會互相抵消,所以先平方再平均,得到均方誤差(mean squared error,MSE):
MSE = 所有殘差平方的平均
MSE 越小,直線離資料越近。先拿兩條猜的直線來算算看。
逐步看:比較兩條猜的直線
六個點(讀書時數與分數,是這裡隨手寫的小資料)。注意右邊的 pred 和 resid:每一步都是對整個陣列一次算完。
最小平方法
一直猜不是辦法。對一條直線來說,讓 MSE 最小的 w 和 b 有公式可以直接算,這個方法叫最小平方法(least squares):
w = Σ(x − x平均)(y − y平均) / Σ(x − x平均)²
b = y平均 − w × x平均
分子看 x 和 y 有沒有一起變大,分母把 x 自己的變動量除掉。第二行代表這條線一定會通過 (x平均, y平均) 這個點。
這條公式是把 MSE 對 w、b 微分、令它等於 0 解出來的,推導不用記;重要的是它一步就算出最佳解,不需要反覆嘗試。不是每個模型都這麼幸運,第 4 課會看到另一種方法。
逐步看:用 numpy 寫最小平方法
同樣六個點。算出來的 MSE 要和上面的 8.5、4.79 比較;最後和 numpy 內建的 np.polyfit 對答案。
模型好不好:RMSE 與 R²
MSE 的單位是「分數的平方」,不好解讀,所以常用另外兩個指標:
| 指標 | 怎麼算 | 怎麼讀 |
|---|---|---|
| RMSE | MSE 開根號 | 單位和 y 相同,大約是預測「平均差幾分」 |
| R² | 1 − 模型的 MSE / 一律猜平均的 MSE | 1 代表完美;0 代表和一律猜平均一樣;在測試資料上也可能是負的,代表比猜平均還差 |
迴歸的基準就是一律猜平均。R² 其實就是在和這個基準比較。
和第 2 課一樣,這些數字都要在測試資料上算:斜率和截距只用訓練資料算,再拿去預測測試資料。
逐步看:用期中分數預測期末分數
這次用 students.csv(程式產生的模擬資料,不是任何學校的真實資料)。程式和上一個範例幾乎相同,差別是切出了測試資料。最後看兩張圖:直線,以及殘差圖。
殘差圖與係數的解讀
殘差圖是檢查模型的好工具。好的模型,殘差應該看起來沒有規律地散在 0 的上下。如果看得出形狀,例如中間高兩邊低的彎曲,代表資料的關係不是直線,模型漏掉了某些東西,第 6 課會處理這種情況。
解讀斜率要小心:
- 斜率 0.823 說的是這份資料裡的關聯,不是因果。它不代表「多考一分期中,期末就會多 0.82 分」:能力好的同學可能兩次都考得好。
- 不要把直線延伸到資料範圍之外。截距 11.6 是「期中 0 分時的預測值」,資料裡根本沒有這樣的同學,這個數字本身沒有意義。
不只一個特徵
特徵有很多個時,模型變成 預測值 = w1×x1 + w2×x2 + … + b,一樣有公式解。np.linalg.lstsq 可以直接解,scikit-learn 的 LinearRegression 也是解同一個問題。
逐步看:多個特徵,numpy 與 scikit-learn 對答案
五個特徵一起預測期末分數。先確認 numpy 和 scikit-learn 算出一樣的係數,再比較只用一個特徵和用五個特徵的 R²。
為什麼讀書時數的係數幾乎是 0?
上面的係數裡,讀書時數是 0.008,幾乎是 0;但只用讀書時數預測時,R² 有 0.164,顯然不是完全無關。
多個特徵時,係數的意思是「其他特徵都固定時,這個特徵多 1,預測值多多少」。期中與小考分數已經在模型裡了,而這份資料裡讀書時數多的同學,這兩項分數也偏高;讀書時數能提供的資訊大多已經包含在裡面,所以固定這些特徵之後,它幾乎沒有額外的資訊。
這不代表「讀書沒有用」。係數只能描述這份資料裡的關聯,而且特徵之間互相有關時,係數會很難解讀。第 5 課會再談怎麼比較係數。
實作:寫 fit_line 與 mse
完成兩個函數:
fit_line(x, y):用最小平方法算出斜率與截距,回傳(w, b);mse(y_true, y_pred):回傳均方誤差。
最後一行印出的是「一律猜平均」的 MSE,可以和上一行的 MSE 比較。
小測驗:殘差與 MSE
下面程式會印出什麼?
import numpy as np
y = np.array([10.0, 20.0, 30.0])
pred = np.array([12.0, 18.0, 30.0])
print(round(((y - pred) ** 2).mean(), 3))
某筆資料實際 70 分,模型預測 75 分,殘差是多少?代表什麼?
在下面的資料加入一個離群值後,斜率會變成多少?
import numpy as np
x = np.array([1.0, 2.0, 3.0, 4.0])
y = np.array([2.0, 4.0, 6.0, 8.0])
w1, b1 = np.polyfit(x, y, 1)
x2 = np.append(x, 5.0)
y2 = np.append(y, 40.0)
w2, b2 = np.polyfit(x2, y2, 1)
print(round(w1, 2), round(w2, 2))
小測驗:評估與解讀
一個迴歸模型在測試資料上的 R² 是 0,這代表什麼?
某個模型預測房租,RMSE 是 2000(元)。最恰當的解讀是?
模型裡「每週打工時數」的係數是 −0.5(課堂的模擬資料)。下面哪個說法最恰當?
重點整理
- 殘差=實際值 − 預測值;MSE 是殘差平方的平均,訓練的目標就是讓它最小。
- 最小平方法一步算出最佳的斜率與截距:
w = Σ(x−x̄)(y−ȳ) / Σ(x−x̄)²、b = ȳ − w·x̄。 - 看 RMSE(單位和 y 相同)與 R²(和一律猜平均比較),都在測試資料上算。
- 殘差圖看得出規律,代表直線不夠用。離群值對最小平方法的影響很大。
- 係數描述的是資料裡的關聯,多個特徵時是「其他特徵固定」的條件下,不是因果。
最小平方法有公式可用,但之後的羅吉斯迴歸與神經網路都沒有這種公式。下一課學梯度下降:不解公式,一步一步往損失變小的方向走。