Skip to content

知识点卡片:线性回归

基本信息

属性内容
知识点线性回归 (Linear Regression)
掌握程度★★★★★
学习优先级P0
预估时间6小时
面试频率★★★★★

核心原理

模型:y = Xw + b(或 y = Xw,将b并入w)

损失函数(MSE):
L(w) = (1/2n) * ‖Xw - y‖² = (1/2n) * Σ (x_i^T w - y_i)²

梯度:
∂L/∂w = (1/n) * X^T (Xw - y)

闭式解(Normal Equation):
w* = (X^T X)^{-1} X^T y

梯度下降解:
w_{t+1} = w_t - η * (1/n) * X^T (Xw_t - y)

代码实现

从零实现(梯度下降)

python
import numpy as np

class LinearRegression:
    def __init__(self, lr=0.01, n_iters=1000):
        self.lr = lr
        self.n_iters = n_iters

    def fit(self, X, y):
        n, d = X.shape
        self.w = np.random.randn(d) * 0.01
        self.b = 0.0
        self.losses = []

        for _ in range(self.n_iters):
            # 预测
            y_pred = X @ self.w + self.b

            # 梯度
            error = y_pred - y
            dw = (1/n) * X.T @ error
            db = (1/n) * error.sum()

            # 更新
            self.w -= self.lr * dw
            self.b -= self.lr * db

            # 记录损失
            loss = 0.5 * np.mean(error ** 2)
            self.losses.append(loss)

    def predict(self, X):
        return X @ self.w + self.b

    def score(self, X, y):
        y_pred = self.predict(X)
        ss_res = ((y - y_pred) ** 2).sum()
        ss_tot = ((y - y.mean()) ** 2).sum()
        return 1 - ss_res / ss_tot  # R²

闭式解实现

python
class LinearRegressionClosedForm:
    def fit(self, X, y):
        # 添加偏置列
        X_aug = np.hstack([np.ones((X.shape[0], 1)), X])

        # w* = (X^T X)^{-1} X^T y
        self.w = np.linalg.solve(X_aug.T @ X_aug, X_aug.T @ y)

    def predict(self, X):
        X_aug = np.hstack([np.ones((X.shape[0], 1)), X])
        return X_aug @ self.w

sklearn实现

python
from sklearn.linear_model import LinearRegression, Ridge, Lasso, ElasticNet
from sklearn.preprocessing import StandardScaler
from sklearn.pipeline import Pipeline

# 基础线性回归
lr = LinearRegression()
lr.fit(X_train, y_train)
print(f"R²: {lr.score(X_test, y_test):.4f}")
print(f"系数: {lr.coef_}")
print(f"截距: {lr.intercept_}")

# Ridge (L2正则化)
ridge = Ridge(alpha=1.0)
ridge.fit(X_train, y_train)

# Lasso (L1正则化,特征选择)
lasso = Lasso(alpha=0.1)
lasso.fit(X_train, y_train)
print(f"非零系数数量: {(lasso.coef_ != 0).sum()}")

# ElasticNet (L1+L2)
en = ElasticNet(alpha=0.1, l1_ratio=0.5)

正则化对比

方法正则项解的特点何时使用
OLS无偏但高方差样本>>特征
Ridge(L2)λ‖w‖²系数缩小但不为零多重共线性
Lasso(L1)λ‖w‖₁稀疏解特征选择
ElasticNetλ(ρL1+(1-ρ)L2)折中两者兼需

面试高频问题

Q1: 闭式解和梯度下降各在什么情况下使用?

闭式解梯度下降
O(nd² + d³)O(nd * iterations)
d小时快d大时必须用
无超参数需调学习率
精确解近似解

规则:d < 10000 → 闭式解;d > 10000 → 梯度下降

Q2: 线性回归的假设条件?

  1. 线性性:y与x线性相关
  2. 独立性:样本间独立
  3. 同方差性:误差方差恒定
  4. 正态性:误差服从正态分布
  5. 无多重共线性:特征间不高度相关

相关知识点