多变量线性回归的求解方法

189 阅读1分钟

多变量线性回归是一种统计方法,用于预测因变量 yy 与多个自变量 x1,x2,,xk x_1, x_2, \ldots, x_k 之间关系。目标是找到一组参数 w1,w2,,wkw_1, w_2, \ldots, w_k bb,使得模型 z=x1w1+x2w2++xkwk+bz = x_1 w_1 + x_2 w_2 + \cdots + x_k w_k + b 能够最好地拟合数据。例如,在房价预测中,影响因素可能包括居住面积、地理位置、朝向、学区房、周边设施、建筑年份等。

在建立多元线性回归模型时,为了确保模型具有良好的解释能力和预测效果,自变量的选择应遵循以下准则:

  • 自变量必须对因变量有显著影响,并呈现紧密的线性相关性;
  • 自变量与因变量之间的相关性应为真实的,而非形式上的;
  • 自变量之间应具有适度的互斥性,其相关性不应超过自变量与因变量之间的相关性;
  • 自变量应具备完整的统计数据,以便预测值容易确定;

接下来,将讨论两种求解多变量线性回归参数的方法:正规方程解法梯度下降解法


正规方程解法

正规方程解法通过解线性方程组来精确找到参数,基于最小二乘法,旨在最小化预测值与实际值之间的平方误差之和。

给定数据集 x1,x2,,xk,yx_1, x_2, \ldots, x_k, y,假设我们有 nn 个样本,可以将数据表示为矩阵形式:

X=[x11x12x1kx21x22x2kxn1xn2xnk],y=[y1y2yn]X = \begin{bmatrix} x_{11} & x_{12} & \cdots & x_{1k} \\ x_{21} & x_{22} & \cdots & x_{2k} \\ \vdots & \vdots & \ddots & \vdots \\ x_{n1} & x_{n2} & \cdots & x_{nk} \end{bmatrix}, \quad \mathbf{y} = \begin{bmatrix} y_1 \\ y_2 \\ \vdots \\ y_n \end{bmatrix}

其中 XX 是设计矩阵,y\mathbf{y} 是目标向量。

正规方程为:

(XTX)w=XTy(X^T X) \mathbf{w} = X^T \mathbf{y}

其中 w\mathbf{w} 是参数向量 [w1,w2,,wk]T[w_1, w_2, \ldots, w_k]^Tbb 通常通过在模型中添加截距项来处理。

解正规方程得到:

w=(XTX)1XTy\mathbf{w} = (X^T X)^{-1} X^T \mathbf{y}

Python代码实现:

import numpy as np

class LinearRegression:
    def __init__(self):
        self.w = None
        self.b = None

    def fit(self, X, y):
        X = np.concatenate([np.ones((X.shape[0], 1)), X], axis=1)  # 添加截距项
        self.w = np.linalg.inv(X.T.dot(X)).dot(X.T).dot(y)  # 计算参数
        self.b = self.w[0]  # 偏置项

    def predict(self, X):
        X = np.concatenate([np.ones((X.shape[0], 1)), X], axis=1)  # 添加截距项
        return X.dot(self.w)  # 返回预测值

# 示例数据
X = np.array([[1, 2], [2, 3], [3, 4], [4, 5]])
y = np.array([1, 2.5, 3.5, 5])
model = LinearRegression()
model.fit(X, y)
print("Weights:", model.w)
print("Bias:", model.b)


梯度下降解法

梯度下降解法是一种迭代优化算法,旨在找到使成本函数最小化的参数。在多变量线性回归中,成本函数通常为平方误差之和:

J(w,b)=12ni=1n(yi(xi1w1+xi2w2++xikwk+b))2 J(\mathbf{w}, b) = \frac{1}{2n} \sum_{i=1}^n (y_i - (x_{i1} w_1 + x_{i2} w_2 + \cdots + x_{ik} w_k + b))^2

梯度下降通过迭代更新参数来最小化成本函数:

w:=wαJw,b:=bαJb \mathbf{w} := \mathbf{w} - \alpha \frac{\partial J}{\partial \mathbf{w}}, \quad b := b - \alpha \frac{\partial J}{\partial b}

其中 α\alpha 是学习率,Jw\frac{\partial J}{\partial \mathbf{w}}Jb\frac{\partial J}{\partial b} 分别是成本函数相对于 w\mathbf{w}bb 的偏导数。

Python代码实现:

class LinearRegressionSGD:
    def __init__(self, learning_rate=0.01, max_iter=1000):
        self.learning_rate = learning_rate
        self.max_iter = max_iter
        self.w = None
        self.b = None

    def fit(self, X, y):
        X = np.concatenate([np.ones((X.shape[0], 1)), X], axis=1)  # 添加截距项
        self.w = np.zeros(X.shape[1])  # 初始化参数
        
        for iteration in range(self.max_iter):
            gradients = 2 / X.shape[0] * X.T.dot(X.dot(self.w) - y)  # 计算梯度
            self.w -= self.learning_rate * gradients  # 更新参数
            if iteration % 100 == 0:
                loss = np.mean((y - X.dot(self.w)) ** 2)  # 计算损失
                print(f"Iteration {iteration}, Loss: {loss}")

    def predict(self, X):
        X = np.concatenate([np.ones((X.shape[0], 1)), X], axis=1)  # 添加截距项
        return X.dot(self.w)  # 返回预测值

# 示例数据
X = np.array([[1, 2], [2, 3], [3, 4], [4, 5]])
y = np.array([1, 2.5, 3.5, 5])
model = LinearRegressionSGD(learning_rate=0.01, max_iter=1000)
model.fit(X, y)
print("Weights:", model.w)
print("Bias:", model.w[0])

总结

  • 正规方程解法:提供精确解,计算复杂度为 O(k3)O(k^3),适用于较小的数据集。
  • 梯度下降解法:迭代方法,适合处理更大数据集,但需选择合适的学习率和迭代次数。

在实际应用中,选择哪种方法取决于数据集的大小、特征的数量以及计算资源。对于大规模数据集,通常更倾向于使用梯度下降或其变体(如随机梯度下降)。

方法正规方程梯度下降
原理几次矩阵运算多次迭代
特殊要求XXX^⊤X 的逆矩阵存在需要确定学习率
复杂度O(n3)O(n^3)O(n2)O(n^2)
适用样本数m<10000m<10000m10000m≥10000