这是一篇关于回归与迭代优化的文章,主要内容包括线性回归、逻辑回归、梯度下降、牛顿法等。
Linear Regression
线性回归 (Linear Regression)是一种用于建立输入变量与输出变量之间关系的线性模型。线性回归的目标是找到一条直线,使得所有数据点到直线的距离之和最小。这个距离可以是点到直线的垂直距离的平方和,也可以是点到直线的水平距离的平方和。
线性回归的目标函数 / 估计函数 (Hypothesis)可以表示为:
h θ ( x ) = θ 0 + θ 1 x 1 + θ 2 x 2 + ⋯ + θ n x n h_{\theta}(x) = \theta_0 + \theta_1 x_1 + \theta_2 x_2 + \cdots + \theta_n x_n
h θ ( x ) = θ 0 + θ 1 x 1 + θ 2 x 2 + ⋯ + θ n x n
简单起见,我们把截距项 θ 0 \theta_0 θ 0 也加入到 θ \theta θ 中,这样可以统一表示为:
h θ ( x ) = θ T x h_{\theta}(x) = \theta^T x
h θ ( x ) = θ T x
其中
x = [ 1 x 1 x 2 ⋮ x n ] , θ = [ θ 0 θ 1 θ 2 ⋮ θ n ] x = \begin{bmatrix} 1 \\ x_1 \\ x_2 \\ \vdots \\ x_n \end{bmatrix}, \quad \theta = \begin{bmatrix} \theta_0 \\ \theta_1 \\ \theta_2 \\ \vdots \\ \theta_n \end{bmatrix}
x = 1 x 1 x 2 ⋮ x n , θ = θ 0 θ 1 θ 2 ⋮ θ n
Idea :最小化损失
我们常用均方误差(Mean Squared Error)平方误差作为损失函数(Loss Function):
L ( h θ ( x ) , y ) = ( h θ ( x ) − y ) 2 L(h_{\theta}(x), y) = (h_{\theta}(x) - y)^2
L ( h θ ( x ) , y ) = ( h θ ( x ) − y ) 2
我们的目标是找到一组参数 θ \theta θ ,使得所有样本的损失函数之和最小:
E ( θ ) = ∑ i = 1 m ( h θ ( x ( i ) ) − y ( i ) ) 2 E(\theta) = \sum_{i=1}^{m} (h_{\theta}(x^{(i)}) - y^{(i)})^2
E ( θ ) = i = 1 ∑ m ( h θ ( x ( i ) ) − y ( i ) ) 2
改为矩阵表示:
E ( θ ) = ∣ ∣ X θ − y ∣ ∣ 2 = ( X θ − y ) T ( X θ − y ) = θ T X T X θ − 2 θ T X T y + y T y E(\theta) = ||X\theta - y||^2 = (X\theta - y)^T(X\theta - y) = \theta^T X^T X \theta - 2 \theta^T X^T y + y^T y
E ( θ ) = ∣∣ Xθ − y ∣ ∣ 2 = ( Xθ − y ) T ( Xθ − y ) = θ T X T Xθ − 2 θ T X T y + y T y
让我们把 X T X X^T X X T X 记为 A A A ,X T y X^T y X T y 记为 b b b ,y T y y^T y y T y 记为 c c c ,则:
E ( θ ) = θ T A θ − 2 θ T b + c E(\theta) = \theta^T A \theta - 2 \theta^T b + c
E ( θ ) = θ T A θ − 2 θ T b + c
我们对目标函数 E ( θ ) E(\theta) E ( θ ) 求导,得到:
∂ E ( θ ) ∂ θ = 2 A θ − 2 b \frac{\partial E(\theta)}{\partial \theta} = 2 A \theta - 2 b
∂ θ ∂ E ( θ ) = 2 A θ − 2 b
即
∂ E ( θ ) ∂ θ = 2 X T X θ − 2 X T y \frac{\partial E(\theta)}{\partial \theta} = 2 X^T X \theta - 2 X^T y
∂ θ ∂ E ( θ ) = 2 X T Xθ − 2 X T y
所以,现在我们的目标是找到 θ \theta θ ,使得 ∂ E ( θ ) ∂ θ = 0 \frac{\partial E(\theta)}{\partial \theta} = 0 ∂ θ ∂ E ( θ ) = 0
正规方程法(Normal Equation)
这可以分为两种情况:
当 X T X X^T X X T X 可逆时,即 X T X X^T X X T X 是满秩矩阵,这时 θ = ( X T X ) − 1 X T y \theta = (X^T X)^{-1} X^T y θ = ( X T X ) − 1 X T y ,这里的 ( X T X ) − 1 X T (X^T X)^{-1} X^T ( X T X ) − 1 X T 称为伪逆矩阵(Pseudo Inverse Matrix)。
当 X T X X^T X X T X 不可逆时,可以使用正则化(Regularization)来使得 X T X X^T X X T X 可逆,或者使用梯度下降(Gradient Descent)等迭代优化方法。
总之,线性回归可以分为三步:
构造特征矩阵 X X X 和标签 y y y
求解伪逆矩阵 ( X T X ) − 1 X T (X^T X)^{-1} X^T ( X T X ) − 1 X T
计算 θ \theta θ 并进行预测即, θ = ( X T X ) − 1 X T y \theta = (X^T X)^{-1} X^T y θ = ( X T X ) − 1 X T y
这种方法有时候也称为正规方程法。在简单情况下,即损失函数是一个凸函数时,我们可以直接解出导数为 0 的点,因此可以使用这种方法。
当然,由于要求逆矩阵,这种方法的时间复杂度会比较高
在实现中,主要的复杂度在于求逆矩阵,如何求逆矩阵是一个线性代数课程中的重要内容,这里不再赘述,因为,如果我是一个大一新生,或许我还会,但现在我是一个大二老东西,我只会调用 numpy.linalg.inv
函数。
代码实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 import numpy as npfrom sklearn.metrics import r2_scorefrom typing import Optional from sklearn.model_selection import train_test_splitfrom sklearn import datasetsclass LinearRegression_normal : def __init__ (self ): self .coef_: Optional [np.ndarray] = None self .intercept_: Optional [float ] = None self ._theta: Optional [np.ndarray] = None def fit (self, X_train: np.ndarray, y_train: np.ndarray ) -> None : assert X_train.shape[0 ] == y_train.shape[0 ], "the size of X_train must be equal to the size of y_train" X_b = np.hstack([np.ones((X_train.shape[0 ], 1 )), X_train]) if np.linalg.matrix_rank(X_b) == X_b.shape[1 ]: pseudo_inverse = np.linalg.inv(X_b.T.dot(X_b)).dot(X_b.T) else : raise ValueError("the matrix is not full rank" ) self ._theta = pseudo_inverse.dot(y_train) self .intercept_ = self ._theta[0 ] self .coef_ = self ._theta[1 :] def predict (self, X_predict: np.ndarray ) -> np.ndarray: def _hypothese (theta: np.ndarray, X: np.ndarray ) -> np.ndarray: return X.dot(theta) assert self ._theta is not None , "must fit before predict" assert X_predict.shape[1 ] == len (self .coef_), "the feature number of X_predict must be equal to X_train" X_b = np.hstack([np.ones((X_predict.shape[0 ], 1 )), X_predict]) return _hypothese(self ._theta, X_b) def score (self, X_test: np.ndarray, y_test: np.ndarray ) -> float : y_predict = self .predict(X_test) return r2_score(y_test, y_predict) def __repr__ (self ) -> str : return "LinearRegression_normal()" breast = datasets.load_breast_cancer() X = breast.data y = breast.target X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2 , random_state=666 ) lr = LinearRegression_normal() lr.fit(X_train, y_train) print (lr.score(X_test, y_test))
Logistic Regression
逻辑回归(Logistic Regression)是一种用于解决分类问题的线性模型。逻辑回归的目标是找到一个函数,使得输入变量的线性组合映射到一个概率值,显然概率的值域是 0 到 1 之间。
首先引入 Sigmoid 函数(Logistic Function):
σ ( z ) = 1 1 + e − z \sigma(z) = \frac{1}{1 + e^{-z}}
σ ( z ) = 1 + e − z 1
这个函数的图像是一条 S 型曲线,值域在 0 到 1 之间。
我们知道,线性回归可以将输入变量映射到输出变量,通常输出的值域是实数域。然而,在分类问题中,我们需要的是一个离散值,即 0 或 1。
逻辑回归的思想是将线性回归的输出通过 Sigmoid 函数映射到 0 到 1 之间,然后根据阈值来判断类别。
回顾线性回归的估计函数:
h θ ( x ) = θ T x h_{\theta}(x) = \theta^T x
h θ ( x ) = θ T x
我们将其通过 Sigmoid 函数映射到 0 到 1 之间,即为逻辑回归的估计函数 :
y = 1 1 + e − θ T x y = \frac{1}{1 + e^{-\theta^T x}}
y = 1 + e − θ T x 1
可以变化为:
l n y 1 − y = θ T x ln \frac{y}{1-y} = \theta^T x
l n 1 − y y = θ T x
若将 y 视为正类的概率,1-y 视为负类的概率,那么两者的比值 y / ( 1 − y ) y / (1-y) y / ( 1 − y ) 称为几率(Odds)。几率的对数称为对数几率(Log Odds),也称为对数几率比(Log Odds Ratio)。对数几率比可以看作是输入变量的线性组合。
则,我们可以继续重写为
l n p ( y = 1 ∣ x ) 1 − p ( y = 1 ∣ x ) = θ T x ln \frac{p(y = 1|x)}{1 - p(y = 1|x)} = \theta^T x
l n 1 − p ( y = 1∣ x ) p ( y = 1∣ x ) = θ T x
显然有
p ( y = 1 ∣ x ) = e θ T x 1 + e θ T x p(y = 1|x) = \frac{e^{\theta^T x}}{1 + e^{\theta^T x}}
p ( y = 1∣ x ) = 1 + e θ T x e θ T x
p ( y = 0 ∣ x ) = 1 1 + e θ T x p(y = 0|x) = \frac{1}{1 + e^{\theta^T x}}
p ( y = 0∣ x ) = 1 + e θ T x 1
于是,我们可以得到逻辑回归的似然函数(Likelihood Function):
L ( θ ) = ∏ i = 1 m p ( y ( i ) ∣ x ( i ) ; θ ) L(\theta) = \prod_{i=1}^{m} p(y^{(i)}|x^{(i)};\theta)
L ( θ ) = i = 1 ∏ m p ( y ( i ) ∣ x ( i ) ; θ )
我们可以使用最大似然估计(Maximum Likelihood Estimation)来求解 θ \theta θ ,即:
θ = arg max θ L ( θ ) \theta = \arg \max_{\theta} L(\theta)
θ = arg θ max L ( θ )
通过 Cross-entropy loss 的定义,我们可以得到逻辑回归的损失函数:
E ( θ ) = − ∑ i = 1 m [ − y ( i ) θ T x ( i ) + l n ( 1 + e θ T x ( i ) ) ] E(\theta) = - \sum_{i=1}^{m} [ -y^{(i)} \theta^T x^{(i)} + ln(1 + e^{\theta^T x^{(i)}})]
E ( θ ) = − i = 1 ∑ m [ − y ( i ) θ T x ( i ) + l n ( 1 + e θ T x ( i ) )]
为了使得损失函数最小,我们对损失函数求导:
∂ E ( θ ) ∂ θ = − ∑ i = 1 m [ − y ( i ) x ( i ) + e θ T x ( i ) 1 + e θ T x ( i ) x ( i ) ] \frac{\partial E(\theta)}{\partial \theta} = - \sum_{i=1}^{m} [ -y^{(i)} x^{(i)} + \frac{e^{\theta^T x^{(i)}}}{1 + e^{\theta^T x^{(i)}}} x^{(i)}]
∂ θ ∂ E ( θ ) = − i = 1 ∑ m [ − y ( i ) x ( i ) + 1 + e θ T x ( i ) e θ T x ( i ) x ( i ) ]
观察到我们可以利用 Sigmoid 函数的性质来简化上式:
设 Sigmoid 函数为 z = 1 1 + e − θ T x z = \frac{1}{1 + e^{-\theta^T x}} z = 1 + e − θ T x 1 ,则有:
∂ E ( θ ) ∂ θ = − ∑ i = 1 m [ z ( θ T x ( i ) ) − y ( i ) ] x ( i ) = 0 \frac{\partial E(\theta)}{\partial \theta} = - \sum_{i=1}^{m} [ z({\theta^T x^{(i)}}) - y^{(i)}] x^{(i)} = 0
∂ θ ∂ E ( θ ) = − i = 1 ∑ m [ z ( θ T x ( i ) ) − y ( i ) ] x ( i ) = 0
注意到导数为 0 的条件是 z ( θ T x ( i ) ) = y ( i ) z({\theta^T x^{(i)}}) = y^{(i)} z ( θ T x ( i ) ) = y ( i ) ,这正是我们的目标。
迭代优化(Iterative Optimization)
然而,逻辑回归的损失函数是非凸函数,无法直接求解最优解。我们可以使用迭代优化 (Iterative Optimization)的方法
迭代优化分为两种
确定性方法 (Deterministic Methods)
随机性方法 (Stochastic Methods)
对于 Deterministic Methods,分为:
First Order Methods:methods that use only the gradient.
Second Order Methods:methods that use the gradient and the Hessian matrix.
其中 Hessian 矩阵是损失函数的二阶导数矩阵,即:H ( f ) i , j = ∂ 2 ∂ x i ∂ x j f ( x ) H (f)_i,_j = \frac{\partial^2}{\partial x_i \partial x_j} f(x)
H ( f ) i , j = ∂ x i ∂ x j ∂ 2 f ( x )
Gradient Descent
Motivation: to minimize the local first-order Taylor approximation of 𝑓
梯度下降 (Gradient Descent,Cauchy 1847) 是一种 First Order Methods,运用了 Taylor 展开式,其想法就是最小化损失函数的局部一阶泰勒展开式,即:
m i n x f ( x ) ≈ m i n x f ( x 0 ) + ∇ f ( x 0 ) T ( x − x 0 ) min_{x} f(x) \approx min_{x} f(x_0) + \nabla f(x_0)^T (x - x_0)
mi n x f ( x ) ≈ mi n x f ( x 0 ) + ∇ f ( x 0 ) T ( x − x 0 )
那么更新规则即为:
x t + 1 = x t − η t ∇ f ( x t ) x_{t+1} = x_t - \eta _t \nabla f(x_t)
x t + 1 = x t − η t ∇ f ( x t )
其中 η t > 0 \eta _t > 0 η t > 0 为步长 (Step Size),也称为学习率 (Learning Rate)。
通过不断迭代,最终我们可以找到损失函数的临界点(Critical Points),即梯度为 0 的点,又称为稳定点(Stationary Points),即驻点。
当然,如果我们可以直接解出导数为 0 的点,比如在线性回归 (矩阵满秩)中,我们可以直接求解出最优解为 θ = ( X T X ) − 1 X T y \theta = (X^T X)^{-1} X^T y θ = ( X T X ) − 1 X T y ,这时候我们可以直接求解出最优解。
Newton’s Methods
牛顿法 (Newton’s Methods ,Newton 1685)是一种 Second Order Methods,其想法是最小化损失函数的局部二阶泰勒展开式,即:
m i n x f ( x ) ≈ m i n x f ( x 0 ) + ∇ f ( x t ) T ( x − x t ) + 1 2 ( x − x t ) T ∇ 2 f ( x t ) ( x − x t ) min_{x} f(x) \approx min_{x} f(x_0) + \nabla f(x_t)^T (x - x_t) + \frac{1}{2} (x - x_t)^T \nabla^2 f(x_t) (x - x_t)
mi n x f ( x ) ≈ mi n x f ( x 0 ) + ∇ f ( x t ) T ( x − x t ) + 2 1 ( x − x t ) T ∇ 2 f ( x t ) ( x − x t )
对两边求导得到
∂ f ( x ) ∂ x = ∇ f ( x t ) + ∇ 2 f ( x t ) ( x − x t ) = 0 \frac{\partial f(x)}{\partial x} = \nabla f(x_t) + \nabla^2 f(x_t) (x - x_t) = 0
∂ x ∂ f ( x ) = ∇ f ( x t ) + ∇ 2 f ( x t ) ( x − x t ) = 0
更新规则为
x = x t − [ ∇ 2 f ( x t ) ] − 1 ∇ f ( x t ) x = x_t - [\nabla^2 f(x_t)]^{-1} \nabla f(x_t)
x = x t − [ ∇ 2 f ( x t ) ] − 1 ∇ f ( x t )
Go back to Logistic Regression
现在我们学习了 迭代优化的方法,让我们回到难住我们的那个问题:
我这里将 \theta 换成 w,和 ppt 保持一致
∇ E ( w ) = − ∑ i = 1 m [ − y ( i ) x ( i ) + e w T x ( i ) 1 + e w T x ( i ) x ( i ) ] \nabla E(w) = - \sum_{i=1}^{m} [ -y^{(i)} x^{(i)} + \frac{e^{w^T x^{(i)}}}{1 + e^{w^T x^{(i)}}} x^{(i)}]
∇ E ( w ) = − i = 1 ∑ m [ − y ( i ) x ( i ) + 1 + e w T x ( i ) e w T x ( i ) x ( i ) ]
∇ E ( w ) = − ∑ i = 1 m [ z ( w T x ( i ) ) − y ( i ) ] x ( i ) = X T ( z ( X w ) − y ) = 0 \nabla E(w) = - \sum_{i=1}^{m} [ z({w^T x^{(i)}}) - y^{(i)}] x^{(i)} = X^T (z(Xw) - y) = 0
∇ E ( w ) = − i = 1 ∑ m [ z ( w T x ( i ) ) − y ( i ) ] x ( i ) = X T ( z ( Xw ) − y ) = 0
让我们用 牛顿法 来解决这个问题
还记得我们的更新规则吗?
x = x t − [ ∇ 2 f ( x t ) ] − 1 ∇ f ( x t ) x = x_t - [\nabla^2 f(x_t)]^{-1} \nabla f(x_t)
x = x t − [ ∇ 2 f ( x t ) ] − 1 ∇ f ( x t )
(这里引入 Hessian 矩阵以使得式子更简洁)
回顾梯度 (Gradient)的定义: 梯度是一个向量,其每个元素是函数在对应坐标轴上的偏导数。
而海森矩阵 (Hessian Matrix)是一个矩阵,其每个元素是函数在对应坐标轴上的二阶偏导数。
我们接下来来求这几个东西
数学演算
损失函数
E ( w ) = − ∑ i = 1 m [ − y ( i ) w T x ( i ) + l n ( 1 + e w T x ( i ) ) ] E(w) = - \sum_{i=1}^{m} [ -y^{(i)} w^T x^{(i)} + ln(1 + e^{w^T x^{(i)}})]
E ( w ) = − i = 1 ∑ m [ − y ( i ) w T x ( i ) + l n ( 1 + e w T x ( i ) )]
梯度(损失函数的一阶导数)
∇ E ( w ) = X T ( z ( X w ) − y ) \nabla E(w) = X^T (z(Xw) - y)
∇ E ( w ) = X T ( z ( Xw ) − y )
Hessian 矩阵(损失函数的二阶导数)
这里不会写就不解了,直接给出结果:
H ( w ) = ∑ i = 1 m x i z ( w T x i ) z ( − w T x i ) x i T = X T R X H(w) = \sum_{i=1}^{m} x_i z(w^T x_i) z(-w^T x_i) x_i^T = X^T R X
H ( w ) = i = 1 ∑ m x i z ( w T x i ) z ( − w T x i ) x i T = X T RX
其中 R 是一个对角矩阵,对角线上的元素为 R i i = z ( w T x i ) z ( − w T x i ) R_{ii} = z(w^T x_i) z(-w^T x_i) R ii = z ( w T x i ) z ( − w T x i )
更新规则
综上,我们就可以得到逻辑回归的更新规则:
w = w t − H ( w t ) − 1 ∇ E ( w t ) w = w_t - H(w_t)^{-1} \nabla E(w_t)
w = w t − H ( w t ) − 1 ∇ E ( w t )
其中 H(w) 是损失函数的 Hessian 矩阵,∇ E ( w ) \nabla E(w) ∇ E ( w ) 是损失函数的梯度。
与 Linear Regression 的比较
对于线性回归
损失函数
E ( w ) = ∣ ∣ X w − y ∣ ∣ 2 = ( X w − y ) T ( X w − y ) E(w) = ||Xw - y||^2 = (Xw - y)^T(Xw - y)
E ( w ) = ∣∣ Xw − y ∣ ∣ 2 = ( Xw − y ) T ( Xw − y )
Gradient
∇ E ( w ) = X T X w − X T y \nabla E(w) = X^T X w - X^T y
∇ E ( w ) = X T Xw − X T y
Hessian
H = ∇ 2 E ( w ) = X T X H = \nabla^2 E(w) = X^T X
H = ∇ 2 E ( w ) = X T X
可以看到,线性回归的 Hessian 矩阵是一个常数矩阵,如果我们使用牛顿法
w = w t − ( X T X ) − 1 ( X T X w t − X T y ) = ( X T X ) − 1 X T y w = w_t - (X^T X)^{-1} (X^T X w_t - X^T y) = (X^T X)^{-1} X^T y
w = w t − ( X T X ) − 1 ( X T X w t − X T y ) = ( X T X ) − 1 X T y
牛顿法直接求解出了最优解,这正好与我们之前提到的正规方程法一致。
而逻辑回归的 Hessian 矩阵是一个变化的矩阵,因此我们需要不断迭代求解。
参考资料