从直觉到公式——线性模型的原理、实现与解释

第四章:从直觉到公式------线性模型的原理、实现与解释

"所有模型都是错的,但有些是有用的。"

------George E.P. Box

而线性模型,正是那个最简单却最有用的起点。


一、为什么从线性模型开始?

在深度学习大行其道的今天,你可能会问:为什么还要学"古老"的线性模型?

答案有三:

  1. 它是理解机器学习的"最小可行单元"

    没有复杂的黑箱,每一步都可解释、可推导、可可视化。

  2. 它在实践中依然强大

    在金融风控、医疗诊断、推荐系统等高可解释性场景中,线性模型仍是首选。

  3. 它是通往复杂模型的桥梁

    逻辑回归 → 神经网络;岭回归 → 正则化思想;特征工程 → 深度学习中的嵌入层。

🎯 本章目标:

  • 掌握线性回归与逻辑回归的数学本质;
  • 亲手从零实现一个线性模型;
  • 理解损失函数、梯度下降、正则化等核心概念;
  • 学会解读模型系数,讲出"为什么"。

二、线性回归:用一条直线预测世界

1. 直觉:找一条"最佳拟合线"

假设你想预测房价。你观察到:

  • 房子越大,价格越高;
  • 但不是严格成正比(有噪声)。

于是你画一条直线,让它尽可能靠近所有数据点------这就是线性回归。

2. 数学表达

对于一个样本 x=[x1,x2,...,xn]\mathbf{x} = [x_1, x_2, ..., x_n]x=[x1,x2,...,xn](如面积、房龄、卧室数),

线性模型预测值为:

y^=w0+w1x1+w2x2+⋯+wnxn \hat{y} = w_0 + w_1 x_1 + w_2 x_2 + \cdots + w_n x_n y^=w0+w1x1+w2x2+⋯+wnxn

或写成向量形式:

y^=w⊤x \hat{y} = \mathbf{w}^\top \mathbf{x} y^=w⊤x

其中:

  • w=[w0,w1,...,wn]⊤\mathbf{w} = [w_0, w_1, ..., w_n]^\topw=[w0,w1,...,wn]⊤ 是权重向量 (w0w_0w0 是偏置项);
  • x=[1,x1,...,xn]⊤\mathbf{x} = [1, x_1, ..., x_n]^\topx=[1,x1,...,xn]⊤(首项为1,用于容纳偏置)。

💡 关键思想 :模型的学习过程,就是找到最优的 w\mathbf{w}w

3. 如何定义"最佳"?------损失函数

我们希望预测值 y^i\hat{y}_iy^i 尽可能接近真实值 yiy_iyi。

常用均方误差(MSE)作为损失函数:

L(w)=1m∑i=1m(y^i−yi)2=1m∑i=1m(w⊤xi−yi)2 \mathcal{L}(\mathbf{w}) = \frac{1}{m} \sum_{i=1}^{m} (\hat{y}i - y_i)^2 = \frac{1}{m} \sum{i=1}^{m} (\mathbf{w}^\top \mathbf{x}_i - y_i)^2 L(w)=m1i=1∑m(y^i−yi)2=m1i=1∑m(w⊤xi−yi)2

其中 mmm 是样本数。

目标 :找到 w∗=arg⁡min⁡wL(w)\mathbf{w}^* = \arg\min_{\mathbf{w}} \mathcal{L}(\mathbf{w})w∗=argminwL(w)

4. 求解方法一:解析解(正规方程)

对 MSE 求导并令导数为零,可得闭式解:

w∗=(X⊤X)−1X⊤y \mathbf{w}^* = (\mathbf{X}^\top \mathbf{X})^{-1} \mathbf{X}^\top \mathbf{y} w∗=(X⊤X)−1X⊤y

其中 X\mathbf{X}X 是 m×(n+1)m \times (n+1)m×(n+1) 的设计矩阵(每行是一个样本)。

✅ 优点:一次计算,精确解;

❌ 缺点:当特征数 nnn 很大时,矩阵求逆 O(n3)O(n^3)O(n3) 计算昂贵,且 X⊤X\mathbf{X}^\top \mathbf{X}X⊤X 可能不可逆。

5. 求解方法二:梯度下降(通用优化框架)

由于解析解不适用于大规模数据,我们采用迭代优化

  1. 随机初始化 w\mathbf{w}w;
  2. 计算损失函数对 w\mathbf{w}w 的梯度;
  3. 沿梯度反方向更新 w\mathbf{w}w;
  4. 重复直到收敛。

梯度计算

∇wL=2mX⊤(Xw−y) \nabla_{\mathbf{w}} \mathcal{L} = \frac{2}{m} \mathbf{X}^\top (\mathbf{X} \mathbf{w} - \mathbf{y}) ∇wL=m2X⊤(Xw−y)

更新规则

w:=w−α∇wL \mathbf{w} := \mathbf{w} - \alpha \nabla_{\mathbf{w}} \mathcal{L} w:=w−α∇wL

其中 α\alphaα 是学习率(learning rate)。

🔑 梯度下降是几乎所有现代机器学习算法的基石,包括神经网络。


三、动手实现:从零写一个线性回归

我们将用 NumPy 实现带梯度下降的线性回归。

python 复制代码
import numpy as np
import matplotlib.pyplot as plt

class LinearRegression:
    def __init__(self, learning_rate=0.01, n_iterations=1000):
        self.lr = learning_rate
        self.n_iters = n_iterations
        self.weights = None
        self.bias = None
        self.losses = []
    
    def fit(self, X, y):
        n_samples, n_features = X.shape
        
        # 初始化参数
        self.weights = np.zeros(n_features)
        self.bias = 0
        
        # 梯度下降
        for _ in range(self.n_iters):
            # 前向传播:预测
            y_pred = np.dot(X, self.weights) + self.bias
            
            # 计算损失(MSE)
            loss = np.mean((y_pred - y) ** 2)
            self.losses.append(loss)
            
            # 计算梯度
            dw = (1 / n_samples) * np.dot(X.T, (y_pred - y))
            db = (1 / n_samples) * np.sum(y_pred - y)
            
            # 更新参数
            self.weights -= self.lr * dw
            self.bias -= self.lr * db
    
    def predict(self, X):
        return np.dot(X, self.weights) + self.bias

# 测试:生成模拟数据
np.random.seed(42)
X = 2 * np.random.rand(100, 1)
y = 4 + 3 * X.flatten() + np.random.randn(100)  # y = 4 + 3x + noise

# 训练模型
model = LinearRegression(learning_rate=0.1, n_iterations=1000)
model.fit(X, y)

# 预测
y_pred = model.predict(X)

# 可视化
plt.scatter(X, y, alpha=0.6, label='Data')
plt.plot(X, y_pred, color='red', label=f'Predicted: y = {model.bias:.2f} + {model.weights[0]:.2f}x')
plt.legend()
plt.title('Linear Regression from Scratch')
plt.show()

# 查看损失变化
plt.plot(model.losses)
plt.title('Loss over Iterations')
plt.xlabel('Iteration')
plt.ylabel('MSE')
plt.show()

✅ 运行结果将显示:

  • 拟合直线接近真实关系(斜率≈3,截距≈4);
  • 损失随迭代逐渐下降并收敛。

四、逻辑回归:用线性模型做分类

❗ 注意:尽管名字叫"回归",逻辑回归是分类算法

1. 问题:线性回归不能直接用于分类

若用线性回归预测"是否患糖尿病"(0 或 1),输出可能是 -0.5 或 2.3------这没有意义。

我们需要一个输出在 [0,1][0,1][0,1] 区间的函数,表示"属于正类的概率"。

2. Sigmoid 函数:引入非线性

定义 Sigmoid 函数:

σ(z)=11+e−z \sigma(z) = \frac{1}{1 + e^{-z}} σ(z)=1+e−z1

性质:

  • 当 z→+∞z \to +\inftyz→+∞,σ(z)→1\sigma(z) \to 1σ(z)→1;
  • 当 z→−∞z \to -\inftyz→−∞,σ(z)→0\sigma(z) \to 0σ(z)→0;
  • σ(0)=0.5\sigma(0) = 0.5σ(0)=0.5。

于是,逻辑回归模型为:

P(y=1∣x)=σ(w⊤x)=11+e−(w⊤x) P(y=1 \mid \mathbf{x}) = \sigma(\mathbf{w}^\top \mathbf{x}) = \frac{1}{1 + e^{-(\mathbf{w}^\top \mathbf{x})}} P(y=1∣x)=σ(w⊤x)=1+e−(w⊤x)1

3. 损失函数:交叉熵(Cross-Entropy)

不能用 MSE!因为 Sigmoid + MSE 会导致非凸优化问题(多个局部最优)。

正确选择是对数似然损失(即交叉熵):

L(w)=−1m∑i=1m[yilog⁡(y^i)+(1−yi)log⁡(1−y^i)] \mathcal{L}(\mathbf{w}) = -\frac{1}{m} \sum_{i=1}^{m} \left[ y_i \log(\hat{y}_i) + (1 - y_i) \log(1 - \hat{y}_i) \right] L(w)=−m1i=1∑m[yilog(y^i)+(1−yi)log(1−y^i)]

其中 y^i=σ(w⊤xi)\hat{y}_i = \sigma(\mathbf{w}^\top \mathbf{x}_i)y^i=σ(w⊤xi)。

✅ 该损失函数是凸的,梯度下降可找到全局最优。

4. 梯度形式(惊人地简洁!)

尽管损失函数复杂,其梯度却与线性回归形式相同:

∇wL=1mX⊤(y^−y) \nabla_{\mathbf{w}} \mathcal{L} = \frac{1}{m} \mathbf{X}^\top (\hat{\mathbf{y}} - \mathbf{y}) ∇wL=m1X⊤(y^−y)

这是巧合吗?不,这是指数族分布的优美性质。


五、使用 scikit-learn 快速建模

实际项目中,我们使用成熟库:

python 复制代码
from sklearn.linear_model import LinearRegression, LogisticRegression
from sklearn.model_selection import train_test_split
from sklearn.metrics import mean_squared_error, accuracy_score, classification_report
from sklearn.datasets import load_boston, load_iris

# 回归示例:波士顿房价
boston = load_boston()
X, y = boston.data, boston.target
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

lr = LinearRegression()
lr.fit(X_train, y_train)
y_pred = lr.predict(X_test)
print("RMSE:", np.sqrt(mean_squared_error(y_test, y_pred)))

# 分类示例:鸢尾花
iris = load_iris()
X, y = iris.data, (iris.target == 0).astype(int)  # 二分类:Setosa vs others
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

log_reg = LogisticRegression()
log_reg.fit(X_train, y_train)
y_pred = log_reg.predict(X_test)
print("Accuracy:", accuracy_score(y_test, y_pred))
print(classification_report(y_test, y_pred))

六、解读模型:系数告诉你"为什么"

线性模型的最大优势:可解释性

以房价预测为例:

特征 系数(权重) 解读
房屋面积(㎡) +3.2 面积每增加1㎡,房价平均上涨3.2万元
房龄(年) -0.5 房龄每增加1年,房价平均下降0.5万元
是否近地铁 +15.0 近地铁的房子贵15万元

🔍 注意:系数大小受特征尺度影响!务必先标准化,再比较重要性。

特征重要性可视化

python 复制代码
import pandas as pd

# 假设已训练好模型 lr
feature_names = boston.feature_names
coef_df = pd.DataFrame({
    'feature': feature_names,
    'coef': lr.coef_
}).sort_values('coef', key=abs, ascending=False)

plt.figure(figsize=(8, 6))
plt.barh(coef_df['feature'], coef_df['coef'])
plt.title('Linear Regression Coefficients (Feature Importance)')
plt.xlabel('Coefficient Value')
plt.show()

七、过拟合与正则化:让模型更稳健

当特征很多或数据很少时,线性模型也会过拟合(在训练集上完美,测试集上差)。

解决方案:正则化(Regularization)

在损失函数中加入惩罚项,限制权重大小。

1. 岭回归(Ridge Regression)--- L2 正则化

Lridge=MSE+α∑j=1nwj2 \mathcal{L}{\text{ridge}} = \text{MSE} + \alpha \sum{j=1}^{n} w_j^2 Lridge=MSE+αj=1∑nwj2

  • 惩罚大权重,但不会让权重变为0
  • 适用于所有特征都可能有用,但希望平滑的情况。
2. Lasso 回归 --- L1 正则化

Llasso=MSE+α∑j=1n∣wj∣ \mathcal{L}{\text{lasso}} = \text{MSE} + \alpha \sum{j=1}^{n} |w_j| Llasso=MSE+αj=1∑n∣wj∣

  • 可将部分权重压缩至0 ,实现自动特征选择
  • 适用于高维稀疏数据(如文本)。

📌 参数 α\alphaα 控制正则化强度:

  • α=0\alpha = 0α=0 → 无正则化(普通线性回归);
  • α→∞\alpha \to \inftyα→∞ → 所有权重趋近0。
python 复制代码
from sklearn.linear_model import Ridge, Lasso

ridge = Ridge(alpha=1.0)
lasso = Lasso(alpha=0.1)

ridge.fit(X_train, y_train)
lasso.fit(X_train, y_train)

print("Ridge non-zero coeffs:", np.sum(ridge.coef_ != 0))  # 通常 = 总特征数
print("Lasso non-zero coeffs:", np.sum(lasso.coef_ != 0))  # 可能 < 总特征数

八、线性模型的局限与超越

局限性

  • 只能捕捉线性关系 :无法拟合 y=x2y = x^2y=x2 这类曲线;
  • 对异常值敏感:MSE 会放大大误差的影响;
  • 特征需人工构造:无法自动发现"面积 × 房龄"这类交互项。

如何超越?

  • 特征工程 :手动添加多项式特征(PolynomialFeatures);
  • 广义加性模型(GAM):允许每个特征有非线性函数;
  • 树模型或神经网络:自动学习非线性与交互。

但请记住:在满足线性假设的场景下,线性模型往往是最优解------因为它稳定、快速、可解释。


九、结语:简单,是一种高级的智慧

线性模型没有炫目的准确率,没有复杂的架构,但它教会我们:

  • 模型的目标不是拟合数据,而是理解数据
  • 可解释性有时比精度更重要
  • 最强大的工具,往往藏在最简单的形式里

在下一篇文章中,我们将进入决策树与集成方法的世界------那里有更强的非线性能力,也有新的可解释性挑战。

但在那之前,请确保你真正掌握了线性模型。因为所有复杂模型,都是对"线性+非线性"的不同组合


行动建议

  1. 用真实数据集(如波士顿房价、泰坦尼克号)训练线性/逻辑回归
  2. 尝试添加多项式特征,观察是否提升性能
  3. 对比 Ridge 与 Lasso 的系数,理解 L1 的稀疏性
  4. 向非技术人员解释你的模型:"为什么这个人被预测为高风险?"

真正的掌握,不在于你能写多少代码,而在于你能讲清多少道理。


全文约 3,800 字(不含代码)|总字符数约 11,000


现在所有公式均已使用 $...$(行内)或 $$...$$(块级)格式 ,可在支持 MathJax/KaTeX 的 Markdown 渲染器中正常显示。

如您需要纯文本版本(无公式)、HTML 版本,或转换为 Jupyter Notebook,也可以告诉我!

相关推荐
大模型任我行2 小时前
美团:统一生成理解多模态大模型
人工智能·计算机视觉·语言模型·论文笔记
deep_drink2 小时前
【论文精读(十八)】SPoTr:拒绝盲目采样,自定位探针(Self-Positioning)如何“以点带面”?(CVPR 2023)
深度学习·神经网络·计算机视觉·3d·point cloud
不一样的故事1262 小时前
1. 公司质量体系的维护与申办监管•
大数据·运维·人工智能
向量引擎小橙2 小时前
数字孪生进阶版:“全脑城市”如何改变我们的生活
大数据·人工智能·深度学习·生活·集成学习
白日做梦Q2 小时前
图像去噪算法对比:传统方法与深度学习方法
人工智能·深度学习·算法
百锦再2 小时前
开发抖音小程序组件大全概述
人工智能·python·ai·小程序·aigc·notepad++·自然语言
GEO AI搜索优化助手2 小时前
数据、AI与人的新协同——构建GEO时代的智能营销引擎
人工智能·算法·搜索引擎·生成式引擎优化·geo搜索优化
大千AI助手2 小时前
DeepSeek V3.2 能不能真正跑 Agent?
人工智能·机器学习·agent·智能体·deepseek·deepseek-v3.2·大千ai助手
会挠头但不秃2 小时前
深度学习(7)LeNet与AlexNet原理
人工智能·深度学习