真正不懂數學就能理解機器學習其實是個神話。我認為,AI 在商業世界可以不懂數學甚至不懂編程也能應用,但對于技術人員來說,一些基礎數學是必須的。本文收集了我認為理解學習本質所必需的數學基礎,至少在概念層面要掌握。畢竟,機器學習的核心就是數學公式。
在本教程中,我們將涵蓋機器學習中用到的所有數學概念:
- 線性代數
- 設計矩陣
- NumPy 支持
- 線性回歸
- 多項式回歸
- 對數
- 微積分
- 偏導數
- 梯度下降
- 求導法則(鏈式法則、乘積法則、商法則)
- 損失函數
- 概率與不確定性
我們會在合適的地方提供實用代碼示例和可視化,幫助你理解這些概念。
線性代數
一切都始于線性代數,這是研究線性方程(如:
a 1 x 1 + ? + a n x n a_1x_1 + \dots + a_nx_n a1?x1?+?+an?xn?
)、線性映射(如:
( x 1 , … , x n ) ? a 1 x 1 + ? + a n x n (x_1,\dots,x_n) \mapsto a_1x_1 + \dots + a_nx_n (x1?,…,xn?)?a1?x1?+?+an?xn?
)及其在向量空間中通過矩陣表示(如:
\begin{bmatrix}
a_11 & a_12 & a_13\
a_21 & a_22 & a_23\
\vdots & \vdots & \vdots\
a_m1 & a_m2 & a_m3
\end{bmatrix}
)的數學分支。
設計矩陣
手寫每個類似的表達式太繁瑣了,所以我們用"矩陣"記法。雖然嚴格來說矩陣不只是記法,但它極大地簡化了表達。我們用"設計矩陣"來組織數據。著名的 NumPy 庫提供了各種矩陣操作。設計矩陣(通常記為 X X X)是統計和機器學習中的基礎概念,尤其在線性回歸和其他線性模型中。它以便于應用線性模型的方式組織數據。
設計矩陣的關鍵組成
- 行:每一行代表一個觀測或數據點。
- 列:每一列代表一個特征或預測變量。列可以包括:
- 自變量:用于預測因變量的特征。
- 截距項:一列全為 1 的列,用于線性模型的截距。
- 交互項:表示特征間交互的列。
- 多項式項:特征的高階項。
設計矩陣的結構
對于有 n n n 個觀測、 p p p 個特征的數據集,設計矩陣 X X X 是 n × ( p + 1 ) n\times(p+1) n×(p+1) 的矩陣(如果包含截距項)。結構如下:
X = [ 1 x 11 x 12 … x 1 p 1 x 21 x 22 … x 2 p ? ? ? ? ? 1 x n 1 x n 2 … x n p ] X= \begin{bmatrix} 1&x{11}&x{12}&\dots&x{1p}\\ 1&x{21}&x{22}&\dots&x{2p}\\ \vdots&\vdots&\vdots&\ddots&\vdots\\ 1&x{n1}&x{n2}&\dots&x{np}\\ \end{bmatrix} X= ?11?1?x11x21?xn1?x12x22?xn2?……?…?x1px2p?xnp? ?
- 第一列(全為 1)表示截距項。
- 其余列表示特征 x i j x{ij} xij, i i i 為觀測編號, j j j 為特征編號。
示例
考慮一個有 3 個觀測、2 個特征(Length 和 Width)的簡單數據集:
| 觀測 | 長度 | 寬度 |
||||
| 1 | 1 | 2 |
| 2 | 2 | 3 |
| 3 | 3 | 4 |
設計矩陣 X X X(含截距項)為:
X = [ 1 1 2 1 2 3 1 3 4 ] X= \begin{bmatrix} 1&1&2\\ 1&2&3\\ 1&3&4\\ \end{bmatrix} X= ?111?123?234? ?
設計矩陣的重要性
- 線性回歸:設計矩陣 X X X 用于通過公式 β ^ = ( X T X ) ? 1 X T y \hat{\beta}=(X^T X)^{-1}X^T y β^?=(XTX)?1XTy 計算模型系數( y y y 為因變量向量)。
- 廣義線性模型(GLM):設計矩陣也用于 GLM,通過鏈接函數將線性預測變量轉換為響應變量。
- 特征工程:設計矩陣可包含多項式項、交互項等特征變換,以捕捉更復雜的關系。
- 模型解釋:設計矩陣的列直接對應模型中的特征,便于解釋系數。
"""
設計矩陣示例| | 截距 | 長度 | 寬度 |
|-||||
|0| 1 | 1 | 2 |
|1| 1 | 2 | 3 |
|2| 1 | 3 | 4 |
"""
import numpy as np
import pandas as pd# 示例數據
data = {'Length': [1, 2, 3],'Width': [2, 3, 4]
}df = pd.DataFrame(data)# 添加截距項(一列全為 1)
df['Intercept'] = 1# 創建設計矩陣
X = df[['Intercept', 'Length', 'Width']]print("設計矩陣:\n", X)
設計矩陣:Intercept Length Width
0 1 1 2
1 1 2 3
2 1 3 4
矩陣的轉置
矩陣的轉置是指沿主對角線翻轉,將行變為列、列變為行。對于矩陣 A A A,其轉置記為 A T A^T AT。
例如:
- 若 A = [ 1 2 3 4 ] A = \begin{bmatrix} 1 & 2 \\ 3 & 4 \end{bmatrix} A=[13?24?],則 A T = [ 1 3 2 4 ] A^T = \begin{bmatrix} 1 & 3 \\ 2 & 4 \end{bmatrix} AT=[12?34?]。
簡單來說,就是以左上到右下的對角線為軸旋轉,行變列、列變行。
矩陣的逆
矩陣 A A A 的逆記為 A ? 1 A^{-1} A?1,是一個特殊矩陣,滿足 A ? A ? 1 = I A \cdot A^{-1} = I A?A?1=I, A ? 1 ? A = I A^{-1} \cdot A = I A?1?A=I,其中 I I I 為單位矩陣(對角線為 1,其余為 0)。可以理解為"反操作":
例如, A = [ 1 2 3 4 ] A = \begin{bmatrix} 1 & 2 \\ 3 & 4 \end{bmatrix} A=[13?24?],若其逆存在,則 A A A 不是"扁平"的(行列式不為零)。逆矩陣就像"撤銷"操作。
單位矩陣
單位矩陣 I I I 是一個方陣(行列數相等),主對角線為 1,其余為 0。它在矩陣乘法中起到"1"的作用:任何矩陣與 I I I 相乘都不變。
例如:
- 2x2 單位矩陣 I = [ 1 0 0 1 ] I = \begin{bmatrix} 1 & 0 \\ 0 & 1 \end{bmatrix} I=[10?01?]。
- 任意 2x2 矩陣 A A A,有 A ? I = A A \cdot I = A A?I=A, I ? A = A I \cdot A = A I?A=A。
簡單說,就是"什么都不做"的矩陣。
小結
- 設計矩陣是用于線性模型的數據結構化表示。
- 它包含多個個體的多種特征,每行對應一個個體,每列對應一個特征。
- 包含截距項、自變量、可能還有交互項或多項式項。
- 對擬合線性回歸等模型、解釋結果至關重要。
Numpy 矩陣操作
"""
設計矩陣代碼示例
`numpy.matrix.T`:矩陣轉置。
`numpy.matrix.I`:矩陣逆。
"""
import numpy as np
m = np.matrix('[1, 2; 3, 4]')
print(f"原始矩陣:\n {m}")
print(f"轉置矩陣:\n {m.T}")
print(f"逆矩陣:\n {m.I}")
print(m * m.I)
原始矩陣:[[1 2][3 4]]
轉置矩陣:[[1 3][2 4]]
逆矩陣:[[-2. 1. ][ 1.5 -0.5]]
[[1.0000000e+00 0.0000000e+00][8.8817842e-16 1.0000000e+00]]
線性代數 numpy.linalg
這是你進入機器學習編程后離不開的包之一。
@ 運算符
@
運算符用于 NumPy 中的矩陣乘法,等價于 np.dot()
,但更簡潔、可讀性更好。推薦用它做矩陣(二維數組)乘法。
矩陣操作
linalg.inv(a)
:求矩陣的逆。numpy.linalg.matrix_power(a, n)
:矩陣的 n 次冪。numpy.linalg.matrix_rank(M)
:求矩陣秩。numpy.linalg.det(a)
:求行列式。numpy.linalg.eig(a)
:求特征值和特征向量。numpy.linalg.svd(a, full_matrices=True, compute_uv=True, hermitian=False)
:奇異值分解。numpy.linalg.cholesky(a)
:Cholesky 分解。
矩陣乘法
結果矩陣的每個元素由第一個矩陣的行與第二個矩陣的列做點積得到。
[1 2] × [5 6] = [1×5 + 2×7 1×6 + 2×8] = [19 22]
[3 4] [7 8] [3×5 + 4×7 3×6 + 4×8] [43 50]
import numpy as np# 創建兩個矩陣
A = np.array([[1, 2],[3, 4]])
B = np.array([[5, 6],[7, 8]])# 用 @ 做矩陣乘法
C = A @ B
# 或用 np.dot()
C = np.dot(A, B)print(C)
[[19 22][43 50]]
線性回歸
現在我們在講完線性代數后來看線性回歸。回歸是一種統計方法,用于建模和分析因變量(目標)與一個或多個自變量(特征)之間的關系。
線性回歸用于確定最佳擬合直線(多變量時為超平面),描述自變量與因變量的關系。目標是最小化實際值與預測值之間的誤差。
簡單線性回歸 表達式:
y = β 0 + β 1 x + ? y = \beta_0 + \beta_1x + \epsilon y=β0?+β1?x+?
其中:
- y y y:因變量(目標)
- x x x:自變量(特征)
- β 0 \beta_0 β0?:截距(見下)
- β 1 \beta_1 β1?:斜率(系數,見下)
- ? \epsilon ?:誤差項
多元線性回歸:
y = β 0 + β 1 x 1 + β 2 x 2 + ? + β n x n + ? y = \beta_0 + \beta_1x_1 + \beta_2x_2 + \dots + \beta_nx_n + \epsilon y=β0?+β1?x1?+β2?x2?+?+βn?xn?+?
即多個自變量影響因變量。
線性回歸的目標 是估計系數( β \beta β),使得平方誤差和(實際值與預測值的差的平方和)最小,通常用最小二乘法(OLS)實現。
截距與系數
在線性回歸模型中,截距和系數是定義線性關系的基本組成。
截距( β 0 \beta_0 β0? 或 bias)
- 當所有自變量 x x x 都為 0 時,因變量 y y y 的值。
- 表示回歸線在 y y y 軸上的起點( x = 0 x=0 x=0)。
- 可通過模型對象獲得:KaTeX parse error: Expected group after '_' at position 18: …del.intercept\\_?
示例
假設用房價( y y y)建模房屋面積( x x x):
$ price = 50,000 + 200 \times size $
其中 50,000 是截距,表示房屋面積為 0 時土地價格為 50,000。
系數( β 1 , β 2 \beta_1, \beta_2 β1?,β2? 或權重)
- 斜率,表示自變量 x x x 每增加 1 單位, y y y 的變化量(假設其他變量不變)。
- 可通過模型對象獲得:KaTeX parse error: Expected group after '_' at position 13: model.coef\\_?
- x x x 在機器學習中稱為特征。
給定:
$ y = model.intercept\_ + (model.coef_0 \times Feature1) + (model.coef_1 \times Feature2) $
其中:
- y y y 為預測值
當:
- i n t e r c e p t intercept intercept = 2
- c o e f f i c i e n t 0 coefficient_0 coefficient0? = 3
- c o e f f i c i e n t 1 coefficient_1 coefficient1? = 4
則:
- 所有特征為 0 時,預測值為 2,即截距或 β 0 \beta_0 β0? 或 bias
- Feature1 每增加 1,預測值增加 3
- Feature2 每增加 1,預測值增加 4
示例
同樣用房價模型:
$ price = 50,000 + 200 \times size $
其中系數 200 表示每增加 1 平方英尺,價格增加 200 美元。
- 系數為正, x x x 增大, y y y 也增大。
- 系數為負, x x x 增大, y y y 反而減小。
殘差
殘差是指實際觀測值(真實目標)與模型預測值之間的差。它衡量了模型對每個數據點的預測誤差。
形式定義
對于 n n n 個樣本:
- y i y_i yi?:第 i i i 個樣本的真實值
- y ^ i \hat{y}_i y^?i?:模型對第 i i i 個樣本的預測值
第 i i i 個樣本的殘差:
r i = y i ? y ^ i r_i = y_i - \hat{y}_i ri?=yi??y^?i?
殘差的意義
- 模型擬合優度:殘差小表示預測接近真實值,殘差大表示預測差。
- 誤差模式:分析殘差(如繪圖)可發現模式:
- 若殘差隨機分布在 0 附近,模型可能擬合良好。
- 若殘差有系統性模式(如隨預測值增大),說明模型遺漏了某些結構(如非線性或遺漏變量)。
- 假設檢驗:線性回歸中,殘差用于檢驗假設:
- 同方差性:殘差在所有預測值水平上方差應恒定。
- 正態性:殘差應近似正態分布,以便某些統計檢驗有效。
示例
假設用身高預測體重:
- 真實體重( y i y_i yi?):70 kg
- 預測體重( y ^ i \hat{y}_i y^?i?):68 kg
- 殘差( r i r_i ri?):70 - 68 = 2 kg
另一個預測為 72 kg,則殘差為 70 - 72 = -2 kg。
假設線性回歸:
residuals = y - y_pred
其中 y y y 為訓練數據的真實體重,y_pred 為模型預測值。殘差的方差(sigma2)用于估計模型系數的不確定性,幫助量化預測的置信度。
殘差的重要性
- 訓練:用于計算均方誤差(MSE)等指標以優化模型。
- 診斷:幫助診斷過擬合、欠擬合或模型設定問題。
- 不確定性:用于計算協方差矩陣,進而估計預測不確定性。
簡言之,殘差是理解和改進模型性能的基礎。
不確定性
系數的不確定性指模型系數(參數)估計值的變異程度或精度。在線性回歸中,系數表示設計矩陣中每個特征的權重。不確定性反映了我們對這些值的置信程度。
不確定性的影響:
- 模型置信度:高不確定性(系數方差大)說明系數可能變化范圍大,對特征與目標的關系不確定。
- 低不確定性(方差小)說明系數估計更精確,模型解釋性更強。
- 對預測的影響:高不確定性的系數會導致新數據預測的變異性更大。因為輸入數據的微小變化會導致輸出顯著不同。
- 特征重要性:
- 若某系數不確定性高(置信區間包含 0),說明該特征對目標變量影響不顯著。
- 低不確定性且非零系數說明特征對預測有可靠貢獻。
- 數據質量與數量:高不確定性常因數據量少、噪聲大或特征共線性導致。更多或更高質量數據通常能降低不確定性。
- 模型假設:不確定性估計假設模型設定正確(如線性關系)。若模型擬合不好(如殘差有模式),不確定性估計可能誤導。
不確定性計算(系數協方差)
系數不確定性可用系數的協方差矩陣量化。線性回歸中,系數協方差矩陣為:
Cov ( β ^ ) = σ 2 ( X T X ) ? 1 \text{Cov}(\hat{\beta}) = \sigma^2 (X^T X)^{-1} Cov(β^?)=σ2(XTX)?1
其中:
- σ 2 \sigma^2 σ2:殘差方差,表示數據噪聲。
- X X X:設計矩陣。
- ( X T X ) ? 1 (X^TX)^{-1} (XTX)?1:設計矩陣 Gram 矩陣的逆,依賴于輸入特征的分布和相關性。可用 NumPy 的
np.linalg.inv()
求逆。 - β ^ \hat{\beta} β^?:系數估計向量。
- 協方差矩陣對角線元素為每個系數的方差,開方即標準誤差(不確定性度量)。
- 非對角線元素表示系數間的協方差(如特征高度相關,系數協方差大)。
- 可用
multivariate_normal.rvs
從該分布采樣,反映估計不確定性。
殘差方差 σ 2 \sigma^2 σ2 計算公式:
σ 2 = ∑ i = 1 n ( y i ? y ^ i ) 2 n ? p \sigma^2 = \frac{\sum_{i=1}^n (y_i - \hat{y}_i)^2}{n - p} σ2=n?p∑i=1n?(yi??y^?i?)2?
其中:
- y i y_i yi?:觀測值
- y ^ i \hat{y}_i y^?i?:預測值
- n n n:觀測數
- p p p:參數數(含截距)
實踐意義
- 解釋:如 Length 系數為 2.5,標準誤差 0.1,則很有信心其值在 2.5 左右且顯著。若標準誤差為 3.0,則系數可能在 -0.5 到 5.5 之間,Length 是否重要就難說。
- 決策:高不確定性可能促使你收集更多數據、簡化模型(如去除共線特征)或用正則化(如 Ridge 回歸)穩定系數。
- 不確定性傳播:系數不確定性會傳遞到預測(y_pred_std),可用誤差棒可視化,便于表達預測區間。
示例
假設模型預測體重,系數如下:
Length
:2.0(標準誤差 0.5)Width
:1.5(標準誤差 1.2)Height
:3.0(標準誤差 0.2)
不確定性估算的代碼示例(續)
"""
用 Statsmodels 估計不確定性
Statsmodels 是強大的統計庫,能提供詳細回歸分析,包括系數不確定性。
"""
import numpy as np
import pandas as pd
import statsmodels.api as sm# 示例數據
data = {'Length': [1, 2, 3, 4, 5],'Width': [2, 3, 4, 5, 6],'Height': [3, 4, 5, 6, 7],'Weight': [10, 15, 20, 25, 30]
}
df = pd.DataFrame(data)# 設計矩陣和目標變量
design_X = df[['Length', 'Width', 'Height']]
y = df['Weight']# 添加常數項(截距)
design_X = sm.add_constant(design_X)# 擬合 OLS 模型(最小二乘法)
model = sm.OLS(y, design_X).fit()# 獲取預測和置信區間
predictions = model.get_prediction(design_X)
pred_summary = predictions.summary_frame(alpha=0.05) # 95% 置信區間# 可視化實際值、預測值和不確定性
plt.scatter(df['Length'], y, color='blue', label='實際體重')
plt.plot(df['Length'], pred_summary['mean'], color='red', label='預測體重')
plt.fill_between(df['Length'], pred_summary['mean_ci_lower'], pred_summary['mean_ci_upper'], color='red', alpha=0.2, label='95%置信區間')
plt.xlabel('Length')
plt.ylabel('Weight')
plt.legend()
plt.title('帶不確定性的體重預測')
plt.show()# 打印回歸摘要
print(model.summary())
"""
回歸摘要包括:
- 系數:每個變量(如 Length)對 Weight 的影響。
- 標準誤差:不確定性的度量——如果有不同數據,這些系數可能的變化范圍。誤差越小,置信度越高。
- 置信區間:- 系數區間通常以區間[a, b]表示,a為下界,b為上界。- 置信水平:如 95%,表示重復實驗時,真系數有 95% 概率落在該區間。
- P 值:檢驗每個變量的影響是真實的還是隨機噪聲(P 值低=更確定是真實影響)。
"""
"""
用 scikit-learn 的 BayesianRidge 進行貝葉斯線性回歸
BayesianRidge 是貝葉斯線性回歸模型,可為系數提供不確定性估計。
"""
import numpy as np
import matplotlib.pyplot as plt
from sklearn.linear_model import BayesianRidge# 示例數據
data = {'Length': [1, 2, 3, 4, 5],'Width': [2, 3, 4, 5, 6],'Height': [3, 4, 5, 6, 7],'Weight': [10, 15, 20, 25, 30]
}
df = pd.DataFrame(data)X = df[['Length', 'Width', 'Height']]
y = df['Weight']# 擬合貝葉斯嶺回歸模型
model = BayesianRidge(compute_score=True)
model.fit(X, y)# 打印系數及其標準差
print("系數:", model.coef_)
print("系數標準差:", np.sqrt(np.diag(model.sigma_)))# 可視化系數及其不確定性
plt.figure(figsize=(6,4))
plt.errorbar(range(len(model.coef_)), model.coef_, yerr=np.sqrt(np.diag(model.sigma_)), fmt='o', capsize=5, label='估計系數')
plt.title('帶不確定性的系數')
plt.xlabel('系數索引')
plt.ylabel('系數值')
plt.legend()
plt.show()
系數: [1.66666685 1.66666662 1.66666651]
系數標準差: [2.35702053 2.35702053 2.35702053]
"""
用自助法(Bootstrapping)估計不確定性
自助法是一種重采樣技術,可用于估計系數的不確定性。
"""
import numpy as np
import pandas as pd
from sklearn.linear_model import LinearRegression
from sklearn.utils import resample# 示例數據
data = {'Length1': [1, 2, 3, 4, 5],'Width': [2, 3, 4, 5, 6],'Height': [3, 4, 5, 6, 7],'Weight': [10, 15, 20, 25, 30]
}
df = pd.DataFrame(data)X = df[['Length1', 'Width', 'Height']]
y = df['Weight']n_bootstrap_samples = 1000
bootstrap_coefs = np.zeros((n_bootstrap_samples, X.shape[1]))for i in range(n_bootstrap_samples):X_sample, y_sample = resample(X, y)model = LinearRegression()model.fit(X_sample, y_sample)bootstrap_coefs[i] = model.coef_mean_coefs = np.mean(bootstrap_coefs, axis=0)
std_coefs = np.std(bootstrap_coefs, axis=0)print("均值系數:", mean_coefs)
print("系數標準差:", std_coefs)plt.figure(figsize=(6, 4))
plt.errorbar(range(len(mean_coefs)), mean_coefs, yerr=std_coefs, fmt='o', capsize=5, label='自助法系數')
plt.title('自助法下的系數不確定性')
plt.xlabel('系數索引')
plt.ylabel('系數值')
plt.legend()
plt.show()
均值系數: [1.66166667 1.66166667 1.66166667]
系數標準差: [0.09115006 0.09115006 0.09115006]
# 樣本數據生成與線性回歸示例
import numpy as np
import pandas as pd
from sklearn.linear_model import LinearRegression
from sklearn.model_selection import train_test_split
import matplotlib.pyplot as plt
from scipy.stats import multivariate_normalnp.random.seed(42)
n_samples = 50
data = {'Length1': np.random.uniform(1, 10, n_samples),'Width': np.random.uniform(2, 12, n_samples),'Height': np.random.uniform(3, 15, n_samples),'Weight': 2 * np.random.uniform(1, 10, n_samples) + 3 * np.random.uniform(2, 12, n_samples) + np.random.normal(0, 2, n_samples)
}df = pd.DataFrame(data)# 劃分訓練集和測試集
train, test = train_test_split(df, test_size=0.2, random_state=42)X = np.array(train[['Length1', 'Width', 'Height']])
y = train['Weight']# 歸一化設計矩陣,避免數值不穩定
X_mean = np.mean(X, axis=0)
X_std = np.std(X, axis=0)
X_std[X_std == 0] = 1
X_normalized = (X - X_mean) / X_std# 擬合線性回歸模型
model = LinearRegression()
model.fit(X_normalized, y)print("模型系數:", model.coef_)# 計算殘差方差
y_pred = model.predict(X_normalized)
residuals = y - y_pred
sigma2 = np.sum(residuals**2) / (len(y) - X_normalized.shape[1] - 1)
print("殘差方差:", sigma2)# 計算 X^T X 的逆(加正則項避免奇異)
X_T_X = np.dot(X_normalized.T, X_normalized)
reg_term = 1e-6 * np.eye(X_T_X.shape[0]) # 微小正則項
X_T_X_reg = X_T_X + reg_term
X_T_X_inv = np.linalg.inv(X_T_X_reg)# 檢查協方差矩陣是否有 NaN 或 Inf
cov_matrix = sigma2 * X_T_X_inv
if np.any(np.isnan(cov_matrix)) or np.any(np.isinf(cov_matrix)):raise ValueError("協方差矩陣包含 NaN 或 Inf。請調整正則項或數據。")print("系數的協方差矩陣:\n", cov_matrix)# 從多元正態分布采樣多組系數
num_samples = 1000
coefficients_samples = multivariate_normal.rvs(mean=model.coef_, cov=cov_matrix, size=num_samples)# 用采樣系數對測試集做預測
X_test = np.array(test[['Length1', 'Width', 'Height']])
X_test_normalized = (X_test - X_mean) / X_std # 用訓練集均值方差歸一化
y_pred_samples = np.dot(X_test_normalized, coefficients_samples.T)# 計算預測均值和標準差
y_pred_mean = np.mean(y_pred_samples, axis=1)
y_pred_std = np.std(y_pred_samples, axis=1)# 繪制帶不確定性的預測
plt.errorbar(y_pred_mean, test['Weight'], xerr=y_pred_std, fmt='o', color='blue', ecolor='lightgray', capsize=5)
plt.xlabel('預測體重')
plt.ylabel('實際體重')
plt.title('帶不確定性的預測')
plt.show()
模型系數: [0.20950153 0.5294286 0.39841419]
殘差方差: 150.9224046839002
系數的協方差矩陣:[[ 3.80621323 -0.15773098 0.2885645 ][-0.15773098 3.93382621 0.76631224][ 0.2885645 0.76631224 3.94916702]]
對數(Logarithm)
對數是我們小時候學過但常被遺忘的內容,但在機器學習中(如激活函數)會頻繁用到,值得快速回顧。
對數是使底數 b b b 的冪等于某數 n n n 的指數。數學表達為:若 b x = n b^x = n bx=n,則 x = log ? b n x = \log_b n x=logb?n。
例如, 2 3 = 8 2^3 = 8 23=8,所以 3 是 8 以 2 為底的對數,即 3 = log ? 2 8 3 = \log_2 8 3=log2?8。
工資的對數例子
假如你用工作年限預測工資。年限翻倍可能工資增加 10 , 000 10,000 10,000,這就是"工資對年限的對數是線性關系"。所以可以特征工程,新增一列"年限的對數",用它做回歸。
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns# 模擬數據
years_experience = np.array([1, 2, 4, 8, 16, 32])
salary = np.array([40000, 50000, 60000, 70000, 80000, 90000])# 對數變換
log_years_experience = np.log(years_experience)
# 繪制原始關系和對數變換后的關系
plt.figure(figsize=(8,3))
plt.subplot(1,2,1)
plt.scatter(years_experience, salary, color='red')
plt.xlabel("工作年限")
plt.ylabel("工資")
plt.title("未對數變換(非線性)")plt.subplot(1,2,2)
plt.scatter(log_years_experience, salary, color='green')
plt.xlabel("log(工作年限)")
plt.ylabel("工資")
plt.title("對數變換后(線性)")plt.show()
模型評估
平均絕對誤差(MAE)
M A E = 1 n ∑ k = 1 n ∣ y i ? y ^ i ∣ MAE = \frac{1}{n} \sum_{k=1}^n |y_i - \hat{y}_i| MAE=n1?k=1∑n?∣yi??y^?i?∣
- 衡量實際值( y i y_i yi?)與預測值( y ^ i \hat{y}_i y^?i?)的平均絕對差。
- 不像 MSE 那樣對大誤差懲罰更重。
均方誤差(MSE)
M S E = 1 n ∑ i = 1 n ( y i ? y ^ i ) 2 MSE = \frac{1}{n} \sum_{i=1}^{n} (y_i - \hat{y}_i)^2 MSE=n1?i=1∑n?(yi??y^?i?)2
- 與 MAE 類似,但對大誤差更敏感。
R 2 R^2 R2(決定系數)
\begin{equation*}
R^2 = 1 - \frac{\sum (y_i - \hat{y}_i)^2}{\sum (y_i - \bar{y})^2}
\end{equation*}
- y i y_i yi?:實際值
- y ^ i \hat{y}_i y^?i?:預測值
- y ˉ \bar{y} yˉ?:實際值均值
解釋:
- 衡量模型對數據方差的解釋能力。
- R 2 = 1 R^2=1 R2=1:完美擬合。
- R 2 = 0 R^2=0 R2=0:與用均值預測一樣差。
- R 2 < 0 R^2<0 R2<0:比用均值還差。
- 例: R 2 = 0.85 R^2=0.85 R2=0.85,說明模型解釋了 85% 的方差。
多項式回歸(Polynomial Regression)
在 sklearn.preprocessing
的 PolynomialFeatures
中,degree 指生成多項式特征的最高次數。它控制特征變換的復雜度,讓線性模型能擬合非線性關系。
簡單解釋
- 設
degree = n
,PolynomialFeatures
會把原始特征 x x x 變成 x 1 , x 2 , . . . , x n x^1, x^2, ..., x^n x1,x2,...,xn,如果有多個特征還會生成交互項。 - 就像給模型更多"工具"去擬合彎曲的曲線,而不僅僅是直線。
示例
假設有一個特征 Length
,數據為 [1, 2, 3]
。
-
Degree = 1:只用原始特征。
- 輸出:
[Length]
Length=2
時:[2]
- 這是線性模型(直線)。
- 輸出:
-
Degree = 2:加上平方項(默認還有常數項)。
- 輸出:
[1, Length, Length^2]
Length=2
時:[1, 2, 4]
- 可以擬合拋物線。
- 輸出:
-
Degree = 3:再加立方項。
- 輸出:
[1, Length, Length^2, Length^3]
Length=2
時:[1, 2, 4, 8]
- 能擬合更復雜的曲線。
- 輸出:
多特征時
如有 Length
和 Width
兩個特征,degree 還包括交互項:
- Degree = 2:
- 輸出:
[1, Length, Width, Length^2, Length*Width, Width^2]
Length=2, Width=3
時:[1, 2, 3, 4, 6, 9]
- 能捕捉特征間的交互關系。
- 輸出:
為什么重要
- 低 degree(如 1)模型簡單,只能擬合直線或平面。
- 高 degree(如 3 及以上)能擬合復雜非線性,但過高會過擬合噪聲。
在你的 pipeline 里,degree = polyfeatures
意味著每輪循環測試更靈活的模型,尋找最平衡擬合與泛化的 degree。就像決定你的曲線能彎幾次,太彎就過擬合了!
正則化(Regularization)
普通線性回歸會讓系數變得很大以完美擬合訓練數據(甚至擬合噪聲)。Ridge 和 Lasso 通過對大系數加懲罰,讓模型更簡單、泛化能力更強。
Ridge 和 Lasso 都是在線性回歸基礎上加懲罰項,防止模型過于復雜,抑制過擬合。可以理解為"自律版"線性回歸。
Ridge 回歸
- 把系數收縮到接近 0,但不會變成 0。
- 懲罰大系數,抑制極端擬合。
- 適合所有特征都可能有用,只是想讓它們影響別太大。
Lasso 回歸
- 也收縮系數,但可以讓部分系數直接變成 0,相當于自動篩選特征。
- 適合你懷疑有些特征其實沒用,想自動剔除。
- 區別:Ridge 保留所有特征但"軟化"它們,Lasso 直接"踢掉"無用特征。
微積分(Calculus)
微積分是研究變化和累積的數學分支,分為微分和積分兩大部分。
導數(Derivative)
微分關注變化率,即函數輸出隨輸入變化的快慢。比如 f ( x ) = x 2 f(x) = x^2 f(x)=x2,其導數 f ′ ( x ) = 2 x f'(x) = 2x f′(x)=2x,說明 x x x 越大,曲線越陡。
核心思想是極限。微分就是把曲線放大到無限小區間,變成直線,計算這條切線的斜率。這在物理(速度是位移的導數)、經濟(邊際成本)和機器學習(用梯度下降優化模型)中都很重要。
例: s ( t ) = 4 t 2 s(t) = 4t^2 s(t)=4t2,微分得速度 v ( t ) = 8 t v(t) = 8t v(t)=8t, t = 2 t=2 t=2 時速度為 16。
偏導數(Partial Derivatives)
偏導數是多元微積分的概念,表示函數對某個變量的變化率,其他變量保持不變。
定義
設 z = f ( x , y ) z = f(x, y) z=f(x,y),對 x x x 的偏導記為 ? f ? x \frac{\partial f}{\partial x} ?x?f?,對 y y y 的偏導記為 ? f ? y \frac{\partial f}{\partial y} ?y?f?。
計算
對 f ( x , y ) = x 2 + 3 x y f(x, y) = x^2 + 3xy f(x,y)=x2+3xy,對 x x x 求偏導( y y y 看作常數):
? f ? x = 2 x + 3 y \frac{\partial f}{\partial x} = 2x + 3y ?x?f?=2x+3y
對 y y y 求偏導( x x x 看作常數):
? f ? y = 3 x \frac{\partial f}{\partial y} = 3x ?y?f?=3x
規則
- 冪法則: u = x n u = x^n u=xn, ? u ? x = n x n ? 1 \frac{\partial u}{\partial x} = nx^{n-1} ?x?u?=nxn?1
- 乘積法則、商法則、鏈式法則等同普通導數
應用
- 優化:找極值
- 物理工程:描述系統變化
- 經濟學:分析邊際變化
損失函數與梯度下降
損失函數是機器學習的"計分卡",衡量模型預測與真實值的差距。比如回歸常用均方誤差 L = 1 n ∑ ( y true ? y pred ) 2 L = \frac{1}{n} \sum (y_{\text{true}} - y_{\text{pred}})^2 L=n1?∑(ytrue??ypred?)2。目標就是讓損失越小越好。
梯度下降是用來最小化損失函數的工具。損失函數定義了一個"地形",梯度下降用導數(梯度)指示的方向,一步步往最低點走。
- 損失函數給出目標
- 梯度下降用梯度(偏導)指示下降方向
- 每步更新參數 w = w ? η ? ? L ? w w = w - \eta \cdot \frac{\partial L}{\partial w} w=w?η??w?L?, η \eta η 為學習率
向量化梯度下降
梯度下降最小化 J ( w ) J(\mathbf{w}) J(w), w \mathbf{w} w 是參數向量。更新公式:
w : = w ? α ? ? J ( w ) \mathbf{w} := \mathbf{w} - \alpha \cdot \nabla J(\mathbf{w}) w:=w?α??J(w)
- w \mathbf{w} w:權重向量
- α \alpha α:學習率
- ? J ( w ) \nabla J(\mathbf{w}) ?J(w):梯度(各參數的偏導數組成的向量)
梯度 ? J ( w ) \nabla J(\mathbf{w}) ?J(w) 指向 J J J 增長最快的方向,減去它就是下降最快的方向。
例 1:二次函數
J ( w ) = w 1 2 + 2 w 2 2 J(\mathbf{w}) = w_1^2 + 2w_2^2 J(w)=w12?+2w22?, w = [ w 1 , w 2 ] \mathbf{w} = [w_1, w_2] w=[w1?,w2?]
- ? J ? w 1 = 2 w 1 \frac{\partial J}{\partial w_1} = 2w_1 ?w1??J?=2w1?
- ? J ? w 2 = 4 w 2 \frac{\partial J}{\partial w_2} = 4w_2 ?w2??J?=4w2?
- 梯度 ? J = [ 2 w 1 , 4 w 2 ] \nabla J = [2w_1, 4w_2] ?J=[2w1?,4w2?]
- 更新: w 1 : = w 1 ? 2 α w 1 w_1 := w_1 - 2\alpha w_1 w1?:=w1??2αw1?, w 2 : = w 2 ? 4 α w 2 w_2 := w_2 - 4\alpha w_2 w2?:=w2??4αw2?
例 2:三參數線性模型
J ( w ) = 1 2 ( w 1 + w 2 x + w 3 x 2 ? y ) 2 J(\mathbf{w}) = \frac{1}{2} (w_1 + w_2 x + w_3 x^2 - y)^2 J(w)=21?(w1?+w2?x+w3?x2?y)2
- 設 h ( w ) = w 1 + w 2 x + w 3 x 2 h(\mathbf{w}) = w_1 + w_2 x + w_3 x^2 h(w)=w1?+w2?x+w3?x2
- ? J ? w i = ( h ? y ) ? ? h ? w i \frac{\partial J}{\partial w_i} = (h - y) \cdot \frac{\partial h}{\partial w_i} ?wi??J?=(h?y)??wi??h?
- ? h ? w 1 = 1 \frac{\partial h}{\partial w_1} = 1 ?w1??h?=1, ? h ? w 2 = x \frac{\partial h}{\partial w_2} = x ?w2??h?=x, ? h ? w 3 = x 2 \frac{\partial h}{\partial w_3} = x^2 ?w3??h?=x2
- 梯度 ? J = ( h ? y ) ? [ 1 , x , x 2 ] \nabla J = (h - y) \cdot [1, x, x^2] ?J=(h?y)?[1,x,x2]
小結
- 梯度用微分規則計算每個方向的斜率
- 反方向更新參數,損失下降
- 學習率 α \alpha α 控制步長
- 這種向量化方法適用于任意參數數目的模型,是優化復雜模型的基礎