通常訓練完模型之後,要怎麼判斷訓練成果呢?我們可能就是直接拿另一組資料,來檢查看看模型的預測力。
其實,除了看預測結果之外,我們還可以看「預測結果跟標準答案的差」,也就是殘差(Residual)。透過畫出所有資料的殘差,能夠讓我們更清楚知道模型訓練成果到底好不好。
一、何謂殘差
這是一個比較容易忽略的觀念。殘差(Residual)是指「預測值」跟「測量值」的差異;而誤差(Error)是指「測量值」跟「實際值」的差異。
舉例來說,有一個身高170公分、體重50公斤的人,穿了很重的衣服,量體重後發現是50.2公斤,同時有一個模型看到身高170公分就預測體重是50.3公斤。此時,殘差是「50.3公斤減50.2公斤 = 0.1公斤」,誤差是「50.2公斤減50公斤 = 0.2公斤」。
二、用殘差圖判斷一個訓練良好的模型
首先,我們準備func_gen_data函式來產生虛擬資料,這個函式的引數有資料筆數N,還有一個mode。mode為0時特徵跟標籤的關係是線性,mode為1時特徵跟標籤的關係就不是線性。
import numpy as np
import matplotlib.pyplot as plt
from sklearn.linear_model import LinearRegressiondef func_gen_data(N, mode):
x = np.random.normal(loc = 0.0, scale = 1.0, size = N)
e = np.random.normal(loc = 0.0, scale = 0.1, size = N)
if(mode == 0):
y = x + e
else:
y = np.sign(x) * abs(x) ** 1.4 + e
return x, y
接著,我們準備一個線性迴歸模型,這個模型會傳回訓練資料跟測試資料的預測結果。
def func_model(x_train, y_train, x_test):
model = LinearRegression().fit(x_train.reshape(-1, 1), y_train) y_pred = model.predict(x_train.reshape(-1, 1)) y_test = model.predict(x_test.reshape(-1, 1))
return y_pred, y_test
最後,我們準備一個畫圖函式。函式分為兩個部分,上半部分是將原始資料點以及模型的預測畫出來;下半部分則是畫出殘差。
def func_plot(x_train, y_train, residual, x_test, y_test):
fig1 = plt.figure(1)
frame1 = fig1.add_axes((.1,.3,.8,.6))
plt.scatter(x_train, y_train, label = "Data")
plt.plot(x_test, y_test, label = "Decision Boundary")
plt.grid()
plt.legend() frame2 = fig1.add_axes((.1,.1,.8,.2))
plt.scatter(x_train, residual, label = "Residual")
plt.grid()
plt.legend()
plt.show()
準備好函式之後,我們就來訓練一個線性模型吧!將mode設定為0,預期可以得到一個訓練良好的模型。
計算殘差的方式很簡單,就直接把訓練資料的標籤(y_train)跟模型預測值(y_pred)相減即可。
np.random.seed(1)N = 100x_train, y_train = func_gen_data(N, 0)x_test = np.linspace(start = min(x_train),
stop = max(x_train),
num = 100)y_pred, y_test = func_model(x_train, y_train, x_test)residual = y_train - y_predfunc_plot(x_train, y_train, residual, x_test, y_test)
得到結果如下圖。當我們的殘差看起來沒有什麼結構(structureless),代表模型已經抓到資料的性質,剩下的預測值跟標籤的差異,可能只是測量資料時候的隨機誤差(random error)。
三、用殘差圖判斷一個訓練不良的模型
接下來,我們把mode設定為1,重新執行上述的流程。
x_train, y_train = func_gen_data(N, 1)y_pred, y_test = func_model(x_train, y_train, x_test)residual = y_train - y_predfunc_plot(x_train, y_train, residual, x_test, y_test)
得到的結果圖如下。從殘差圖可以明顯看出殘差並非隨機散佈,這些殘差的分布看起來很像是一個三次多項式。如果殘差看起來有些特性,就代表模型訓練成果並不是很良好。加入殘差圖的判斷,可以讓我們有更多資訊判斷模型的訓練成果。
關於作者
Chia-Hao Li received the M.S. degree in computer science from Durham University, United Kingdom. He engages in computer algorithm, machine learning, and hardware/software codesign. He was former senior engineer in Mediatek, Taiwan. His currently research topic is the application of machine learning techniques for fault detection in the high-performance computing systems.