L0.0 房仲怎麼估價:從例子學規則
本篇重用M1.2天氣預報該報幾度:MSE 的最小值是 Conditional Expectation
起點:房仲為什麼能估價
一位資深房仲看過幾百間房子的成交價。你帶他去一間他沒看過的房子,他站三分鐘,說「大概 2,850 萬」。三週後成交 2,910 萬。
他做了什麼?他不是在背——這一間他沒看過。他也說不出一條公式(「每坪加多少、每老一年扣多少」),問他就是「感覺」。但他的感覺顯然帶著資訊:換一個沒看過房子的人來,誤差會大得多。
你要把他的本領寫成程式。你必須先指定哪些東西?以及,「估得準」到底是什麼意思——準到什麼程度算成功?
多數人的第一版答案是「拿歷史成交資料 fit 一個函數」。這句話不錯,但它把三個可以分別更換的決定壓成了一句話。代價在後面才出現:模型表現不好時,你不知道該加資料、換模型、還是換損失,因為你從來沒把它們分開過。
這一篇會把三個零件拆出來,寫出「學習」在對什麼求極值,並在共用 toy 上示範一件事:經驗風險(訓練誤差)可以一路壓到接近零,而同一個模型在新資料上的誤差同時爆掉八千倍。
「訓練誤差低」從來不是結論。
從例子學規則,你必須先指定哪些東西?
而「估得準」到底是哪一個數字小——
它和你能算的那個數字是同一個嗎?
課堂提問Q1
把上面那兩個問題翻成數學。你要指定哪三樣東西?「學」這個動作是在對什麼東西求極值?
先想一想,再展開看整理後的答案
最常被寫下來的答案是「最小化 」。式子對,但它同時暗藏了三個決定,而且把「能算的」當成了「想要的」。
要指定的三樣:
- 假設空間 :你允許的規則長什麼樣。只准直線?可以彎幾次?可以是深度網路?這是「候選答案的集合」。
- 損失 :單筆估錯要扣多少分。差 10 萬與差 100 萬之間的比例由你宣告,不是天生的(下一篇整篇在講這件事)。
- 資料 :他看過什麼。標準假設是這 筆從某個聯合分佈 獨立同分佈抽出。
「學」= 求極值。 在 裡挑出讓資料上的平均損失最小的那個 :
「估得準」不是這個數字。 你想要的是下一間房子估得準——對還沒抽到的 取期望:。你能算的是資料上的平均,你想小的是期望。這兩個數字不同,整個系列的判斷力都建立在「它們差多少、什麼時候差很多」上面。
三個旋鈕,各自控制不同的東西
把三要素想成三個可以分開轉的旋鈕:
- 假設空間是「你允許他考慮哪些答案」。允許得太少(只准直線),再多資料也估不準——彎的東西用直線描不出來。允許得太多(任意曲線),他可以完美穿過看過的每一點,卻對沒看過的點胡說。
- 損失是「你怎麼替他扣分」。扣分方式一換,同一份資料的最佳答案就換一個位置——天氣預報該報幾度:MSE 的最小值是 Conditional Expectation 那一篇已經把這件事釘死:平方誤差選條件平均,絕對誤差選中位數。
- 資料是「他看過什麼」。看得少、或看的和考的不是同一種房子,前兩個旋鈕調得再好也沒用。
這三個旋鈕解釋了為什麼「模型不夠好」不是一個診斷。它至少有三種病因,處方完全不同,而且互相不能替代:資料太少不會因為換更大的模型而好轉。
能算的那個數字,和想小的那個數字
固定損失 與資料分佈 。一個規則 的母體風險(真正想小的)與經驗風險(能算的)分別是
ERM 就是 。把最終成績拆開,令 是所有函數裡風險最小的那個(貝氏最佳), 是假設空間內最好的:
再加上誰都消不掉的 (不可約誤差)。三塊各對一個旋鈕:空間太小 → approximation 大;空間太大、資料太少 → estimation 大;噪聲本身 → 不可約。 把 放大會壓低第二項、抬高第一項——這個對衝就是下一個 class 的主題。
平方損失下 是誰?M1.2 的三行證明給了答案:,而剩下的 就是不可約誤差。這個句子之後會反覆出現。
在平方損失下,「學習」有一個非常具體的目標:把條件平均這張表估出來。
注意為什麼不直接把假設空間設成「所有函數」
把 設成所有函數,ERM 有一個完美解:對看過的 回答 ,其他地方隨便。它的經驗風險是 ,母體風險則和亂猜差不多。這不是理論上的怪例——下面的實作會看到 的多項式正好是這種東西。
所以 的限制性不是缺點,是它唯一有用的地方:限制讓「在資料上表現好」這件事開始對「在新資料上表現好」有意義。統計學習理論用 VC 維、Rademacher 複雜度等量把這個直覺變成不等式( 某個隨 變大、隨 變大而變小的項)。這一系列不走那條路,改用可以在自己資料上量出來的診斷工具,但腦中的圖是同一張。
回到情境:房仲的三個零件各是什麼
假設空間。 他心裡不是「任意函數」,而是一個相當受限的家族:找幾間可比較的成交案例,再對坪數、樓層、屋齡、面向做加減。這個家族小到讓他幾百筆資料就夠用——限制正是他能學會的原因,不是他的極限。
損失。 他被市場用什麼方式扣分?如果客戶對「低估」(房子賤賣了)的痛苦遠大於「高估」(多等兩週),那他該報的就不是條件平均,而是一個偏高的分位數。他往往憑經驗做對了這件事卻說不出理由;下一篇會把它寫成式子。
資料。 他只看過某一區、某一段時間的房子。「新房子與看過的房子同分佈」這個假設,在換城市、換年份、換房型時就破了——那時前兩個旋鈕調得再好都沒用。這是 台北的房仲去台中:風險與經驗風險 的主題。
這一切依賴什麼假設。 一, 獨立同分佈,而且測試時面對的是同一個 。二, 裡的隨機成分不可預測(否則它其實是你漏掉的特徵)。三,損失真的代表你在意的東西——不是因為它好微分。三個假設在真實專案裡都會壞,而且壞法各自有徵狀,這是接下來八篇的內容。
回到情境:系列共用的 toy
這個系列所有實作都用同一組資料,這樣過擬合、資料切分、學習率、架構差異全部在同一張圖上被看見。存成 ml_toy.py:
import numpy as np
NOISE = 0.15
def toy_1d(n=30, noise=NOISE, seed=0): # 主 toy:一維回歸
rng = np.random.default_rng(seed)
x = np.sort(rng.uniform(0, 1, n))
return x, np.sin(2*np.pi*x) + noise*rng.standard_normal(n)
def truth(m=400): # 密集網格上的真值,用來近似母體風險
x = np.linspace(0, 1, m)
return x, np.sin(2*np.pi*x)
def toy_2d(n=200, noise=0.20, seed=0): # 副 toy:兩個交纏的月牙,二元分類
rng = np.random.default_rng(seed)
t = rng.uniform(0, np.pi, n//2)
X = np.r_[np.c_[np.cos(t), np.sin(t)], np.c_[1-np.cos(t), 0.4-np.sin(t)]]
X = X + noise*rng.standard_normal((n, 2))
return X, np.r_[np.zeros(n//2), np.ones(n//2)].astype(int)
真實函數是 ,噪聲是標準差 的 Gaussian——所以不可約誤差正好是 ,任何模型的母體風險都不可能低於它。這個已知的下界之後會一直當作參考線。
現在做 ERM:假設空間是「次數 的多項式」,損失是平方,資料是那 30 個點。
import numpy as np
from numpy.polynomial import Polynomial # 比 np.polyfit 穩定:內部把 x 縮放到 [-1,1]
from ml_toy import toy_1d, truth, NOISE
x, y = toy_1d() # n = 30
xs, ys = truth()
for d in (1, 3, 9, 25):
f = Polynomial.fit(x, y, d) # ERM:這個空間裡經驗風險最小的那個
print(f"degree {d:2d} 經驗風險 {((f(x)-y)**2).mean():.4f}"
f" 母體風險 ≈ {((f(xs)-ys)**2).mean() + NOISE**2:.4f}")
degree 1 經驗風險 0.2118 母體風險 ≈ 0.2679
degree 3 經驗風險 0.0178 母體風險 ≈ 0.0312
degree 9 經驗風險 0.0122 母體風險 ≈ 0.0285
degree 25 經驗風險 0.0016 母體風險 ≈ 8032.3199
讀這四行:經驗風險單調下降,母體風險先降後爆。 是 approximation error 主導(直線描不出正弦,兩個風險都大且接近); 到 已經逼近不可約誤差 ,多出來的一點是 estimation error; 的經驗風險只有 ——比噪聲的變異數還小,這本身就是警訊,它已經在擬合噪聲——而母體風險是 。
把空間放大到和資料一樣大,退化得更徹底:
f = Polynomial.fit(x, y, len(x)-1) # d = n-1 = 29:剛好能穿過每一個點
print(f"degree 29 經驗風險 {((f(x)-y)**2).mean():.2e}"
f" 母體風險 ≈ {((f(xs)-ys)**2).mean()+NOISE**2:.2e}")
# degree 29 經驗風險 4.28e-04 母體風險 ≈ 1.52e+09
這是刻意違反「 要有限制」的結果:經驗風險小到 ,母體風險 。同一個 print 裡的兩個數字差了十三個數量級,而只有左邊那個是你在訓練時看得到的。房仲版本的翻譯是:一個把每筆成交價背下來、對沒看過的房子就開始亂編的人,在「回答考古題」這個指標上是滿分。
轉三個旋鈕,看兩條風險怎麼分家
互動 demo:拉「樣本數 n」看兩條曲線分開多少,拉「模型複雜度」看它們往相反方向走。
先消化一下
參考文獻
- Hastie, T., Tibshirani, R., Friedman, J. The Elements of Statistical Learning, 2nd ed. Springer 2009, Ch. 2, 7.1–7.3.(監督式學習的框架、風險分解、模型複雜度與誤差的關係。)
- Shalev-Shwartz, S., Ben-David, S. Understanding Machine Learning: From Theory to Algorithms Cambridge University Press 2014, Ch. 2–5.(ERM 的形式化、為什麼需要限制假設空間、approximation–estimation 分解。)
- Vapnik, V. The Nature of Statistical Learning Theory, 2nd ed. Springer 2000.(把「限制假設空間才能學習」變成定量陳述的原始路線。)