统计学习

Sep 12, 2025 · 9881 字

导论

统计学习是一门研究如何通过数据推断规律、建立模型并进行预测的学科。它融合了统计学、机器学习和数据挖掘等领域的思想,广泛应用于金融、医疗、互联网等行业。

统计学习的基本任务:

  • 描述数据的分布和特征
  • 建立预测模型
  • 评估模型性能

统计学习的主要类型:

  • 监督学习:有标签数据,目标是预测或分类
  • 无监督学习:无标签数据,目标是发现数据结构

一个贯穿全篇的重要理念是“偏差-方差权衡”(Bias-Variance Trade-off)。在回归任务中,预测误差(期望意义下的测试 MSE)可分解为:

E[(Yf^(X))2]=(Bias[f^(X)])2模型系统性误差+Var[f^(X)]模型不稳定性+σ2不可约误差\mathbb{E}\big[(Y - \hat f(X))^2\big] = \underbrace{\big(\mathrm{Bias}[\hat f(X)]\big)^2}_{模型系统性误差} + \underbrace{\mathrm{Var}[\hat f(X)]}_{模型不稳定性} + \underbrace{\sigma^2}_{不可约误差}

通常,更复杂的模型(低偏差)会带来更高的方差,而更简单的模型(高偏差)方差较低。模型选择与正则化正是为了在二者之间取得平衡。

评价模型精度

模型评估是统计学习中的核心环节,常用指标包括均方误差(MSE)、平均绝对误差(MAE)、决定系数(R2R^2)、准确率、召回率、F1 值、ROC-AUC、PR-AUC、对数损失(log loss)等。合理的评估指标应与任务目标、数据分布(尤其是是否类别不平衡)、业务代价相匹配。

回归模型的评估:

  • 均方误差(MSE)

    MSE=1ni=1n(yiy^i)2\text{MSE} = \frac{1}{n} \sum_{i=1}^n (y_i - \hat{y}_i)^2
  • 平均绝对误差(MAE)

    MAE=1ni=1nyiy^i\text{MAE} = \frac{1}{n} \sum_{i=1}^n |y_i - \hat{y}_i|
  • 决定系数(R2R^2

    R2=1i=1n(yiy^i)2i=1n(yiyˉ)2R^2 = 1 - \frac{\sum_{i=1}^n (y_i-\hat y_i)^2}{\sum_{i=1}^n (y_i-\bar y)^2}
# R 语言计算 MSE/MAE/R^2
y_true <- c(3, 5, 2.5, 7)
y_pred <- c(2.5, 5, 4, 8)

mse <- mean((y_true - y_pred)^2)
mae <- mean(abs(y_true - y_pred))
r2  <- 1 - sum((y_true - y_pred)^2) / sum((y_true - mean(y_true))^2)

print(list(MSE = mse, MAE = mae, R2 = r2))

分类模型的评估:

  • 混淆矩阵(TP/FP/TN/FN)
  • 准确率、精确率(Precision)、召回率(Recall)、F1 值
  • ROC-AUC(适合类别相对平衡)、PR-AUC(更关注正类且在不平衡数据上更敏感)
  • 校准(Calibration):预测概率与真实频率的一致性
# R 语言混淆矩阵及常用指标
actual <- factor(c("A", "B", "A", "B", "A"))
predicted <- factor(c("A", "A", "A", "B", "B"))
cm <- table(predicted, actual)
cm

accuracy <- sum(diag(cm)) / sum(cm)
precision_A <- cm["A","A"] / sum(cm["A",])
recall_A <- cm["A","A"] / sum(cm[,"A"])
f1_A <- 2 * precision_A * recall_A / (precision_A + recall_A)

print(list(accuracy = accuracy, precision_A = precision_A, recall_A = recall_A, f1_A = f1_A))

何时用什么指标(嵌入对比的直觉):

  • 回归中,MAE 对异常值更鲁棒,MSE/ RMSE 对大误差更敏感;
  • 分类中,类别严重不平衡时应优先看 PR-AUC、F1,而非简单准确率;
  • 概率输出任务(例如信贷违约概率)要关注校准(如可靠性曲线、Brier score)。

R 语言简介

R 是一门专为统计分析和数据可视化设计的编程语言,拥有丰富的统计建模和绘图工具。

基本数据结构:

  • 向量、矩阵、数据框
# 创建数据框
df <- data.frame(
  x = c(1, 2, 3),
  y = c(4, 5, 6)
)
print(df)

常用包:

  • stats:基础统计分析与建模
  • ggplot2:数据可视化
  • caret:统一接口的机器学习训练与验证
  • glmnet:正则化线性/逻辑回归
  • randomForest / ranger:随机森林
  • e1071:SVM、朴素贝叶斯等
  • gbm / xgboost / lightgbm:梯度提升树

数据预处理常见要点:

  • 数值特征标准化/归一化(许多基于距离/正则化/核方法都敏感)
  • 类别变量编码(one-hot、目标编码等)
  • 缺失值处理(删除/插补/模型内处理)
  • 划分训练/验证/测试集,避免数据泄漏(泄漏会导致评估过于乐观)

线性回归

线性回归用于建模因变量与一个或多个自变量之间的线性关系。最小二乘估计(OLS)在经典假设下具有最优无偏性(Gauss–Markov 定理)。

  • 矩阵形式:

    β^=(XX)1Xy,y^=Xβ^\hat{\boldsymbol\beta} = (X^\top X)^{-1} X^\top \mathbf{y}, \quad \hat{\mathbf{y}} = X\hat{\boldsymbol\beta}
  • 常见假设(用于推断与置信区间):线性可加、误差独立同分布、同方差、正态性(用于小样本推断)

简单线性回归

假设 y=β0+β1x+ϵy = \beta_0 + \beta_1 x + \epsilon

# 简单线性回归
x <- c(1, 2, 3, 4, 5)
y <- c(2, 4, 5, 4, 5)
model <- lm(y ~ x)
summary(model)

# 诊断图(残差 vs 拟合值、QQ图等),检查线性/同方差/正态性
par(mfrow = c(2,2))
plot(model)
par(mfrow = c(1,1))

何时优先使用线性回归:

  • 关系近似线性、特征数量不大、解释性要求高;
  • 可通过残差图、Box-Cox 变换、多项式/样条扩展缓解非线性。

多元线性回归

涉及多个自变量,需关注多重共线性(VIF)、变量选择、交互项等。

# 多元线性回归
df <- data.frame(
  y = c(1, 2, 3, 4, 5),
  x1 = c(2, 1, 3, 2, 5),
  x2 = c(5, 3, 2, 4, 1)
)
model <- lm(y ~ x1 + x2, data = df)
summary(model)

# 方差膨胀因子(VIF)评估共线性
# install.packages("car")
# library(car)
# vif(model)

K 最近邻法(KNN)

KNN 是一种基于实例的非参数方法,常用于分类和回归。核心思想是“近朱者赤”:根据最近的 K 个邻居的标签或数值进行投票或平均。

  • 距离度量:欧氏/曼哈顿/闵可夫斯基/余弦等;
  • 特征缩放很重要(不同量纲会主导距离);
  • 维度灾难:维度高时距离退化,KNN 效果下降;
  • 超参数:K 值、权重(距离加权)等通过交叉验证选择。
# KNN 分类示例
library(class)
train_x <- matrix(c(1,2,3,4,5,6), ncol=2, byrow = TRUE)
train_y <- factor(c("A", "A", "B"))
test_x <- matrix(c(2,3), ncol=2, byrow = TRUE)
knn(train = train_x, test = test_x, cl = train_y, k = 1)

直觉对比(与线性模型):

  • KNN 无参数假设,能拟合复杂决边界,但在高维/数据稀疏时表现差;
  • 线性回归易解释、训练快,但拟合非线性能力有限(需做特征工程/基函数扩展)。

分类

分类任务旨在将观测样本分配到预定义类别。

逻辑回归

适用于二分类问题,是线性模型在概率空间的扩展。逻辑回归建模对数几率(log-odds):

Pr(Y=1x)=σ(β0+βx),σ(z)=11+ez\Pr(Y=1|x) = \sigma(\beta_0 + \beta^\top x), \quad \sigma(z) = \frac{1}{1 + e^{-z}}

极大似然估计等价于最小化对数损失(交叉熵):

(β)=i=1n[yilogp^i+(1yi)log(1p^i)]\ell(\beta) = - \sum_{i=1}^n \left[y_i \log \hat p_i + (1 - y_i) \log (1 - \hat p_i)\right]
# 逻辑回归
df <- data.frame(
  y = factor(c(0,1,0,1,0)),  # 也可使用 0/1 数值
  x1 = c(2,3,4,5,6)
)
model <- glm(y ~ x1, data = df, family = binomial)
summary(model)

# 预测概率与阈值选择
probs <- predict(model, type = "response")
pred  <- ifelse(probs > 0.5, 1, 0)
table(pred, df$y)

嵌入对比(与树模型、SVM):

  • 逻辑回归:线性可分近似、可解释性强、概率输出自然;
  • 决策树:非线性、可解释,但单树易过拟合;
  • SVM:最大间隔,核技巧强大,但概率输出需额外校准(Platt scaling)。

朴素贝叶斯

基于贝叶斯定理并假设条件独立:

P(C=kx)P(C=k)j=1pP(xjC=k)P(C=k|x) \propto P(C=k)\prod_{j=1}^p P(x_j|C=k)

适用于高维稀疏数据(如文本分类,多项式朴素贝叶斯),对特征独立性不敏感时表现很好。

# 朴素贝叶斯(GaussianNB 近似)
library(e1071)
data(iris)
model <- naiveBayes(Species ~ ., data = iris)
predict(model, iris[1:5,])

何时偏好朴素贝叶斯:

  • 特征近似条件独立(或相互弱相关);
  • 样本较少、维度较高的场景(如词袋模型)。

重抽样方法

重抽样用于评估模型的稳定性和泛化能力,帮助选择模型与超参数。

交叉验证

将数据分为若干份,轮流作为测试集。常见设置:

  • K 折交叉验证(如 K=5/10)
  • 留一法(LOOCV)
  • 重复 K 折(Repeated CV)
  • 分层 CV(分类时保持类别比例)
  • 时间序列 CV(滚动/扩展窗口,避免泄漏)
# 10 折交叉验证(caret)
library(caret)
data(iris)
train_control <- trainControl(method = "cv", number = 10)
model <- train(Species ~ ., data = iris, method = "lda", trControl = train_control)
print(model)

自助法(Bootstrap)

从原始样本中有放回地抽样。可用于估计统计量的方差与置信区间(如百分位法、BCa),以及估计泛化误差(如 .632 bootstrap)。

# Bootstrap 示例:对均值进行自助重采样
set.seed(123)
x <- iris$Sepal.Length
B <- 1000
boot_means <- replicate(B, mean(sample(x, replace = TRUE)))
quantile(boot_means, c(0.025, 0.975))  # 近似 95% CI

嵌入对比(CV vs Bootstrap):

  • CV 更常用于模型选择与泛化误差评估;
  • Bootstrap 更擅长评估统计量不确定性与小样本稳定性。

线性模型选择与正则化

用于防止过拟合,提高模型泛化能力,并可进行变量选择。

常见模型选择准则(适合线性回归):

  • 调整后 R2R^2:惩罚变量个数;
  • AIC / BIC / Mallows’s CpC_p
    • AIC=2k2logL\text{AIC} = 2k - 2\log L
    • BIC=klogn2logL\text{BIC} = k\log n - 2\log L
    • Cp=1σ^2(RSS+2kσ^2)nC_p = \frac{1}{\hat\sigma^2}(\mathrm{RSS} + 2k\hat\sigma^2) - n

逐步选择(前向/后向/逐步回归)在高维时可能不稳定,正则化更为稳健。

岭回归(Ridge)

在 OLS 基础上加入 L2 惩罚,缩小系数,缓解多重共线性:

minβ RSS+λj=1pβj2\min_{\beta} \ \mathrm{RSS} + \lambda\sum_{j=1}^p \beta_j^2
# 岭回归(推荐使用 glmnet,自动标准化并支持 CV)
library(glmnet)
x <- as.matrix(mtcars[, -1])
y <- mtcars$mpg
set.seed(1)
cvfit_ridge <- cv.glmnet(x, y, alpha = 0)  # alpha=0 => ridge
cvfit_ridge$lambda.min
coef(cvfit_ridge, s = "lambda.min")

Lasso 回归

通过 L1 正则化实现变量选择(部分系数变为 0):

minβ RSS+λj=1pβj\min_{\beta} \ \mathrm{RSS} + \lambda\sum_{j=1}^p |\beta_j|
# Lasso 回归
library(glmnet)
x <- as.matrix(mtcars[, -1])
y <- mtcars$mpg
set.seed(1)
cvfit_lasso <- cv.glmnet(x, y, alpha = 1)  # alpha=1 => lasso
cvfit_lasso$lambda.min
coef(cvfit_lasso, s = "lambda.min")

弹性网(Elastic Net)

同时引入 L1 与 L2,兼具变量选择与组效应(处理相关特征):

minβ RSS+λ[αβj+(1α)βj2]\min_{\beta} \ \mathrm{RSS} + \lambda\left[\alpha\sum|\beta_j| + (1-\alpha)\sum\beta_j^2\right]

实践要点(嵌入对比):

  • 岭:不做变量选择,抗多重共线性强;
  • Lasso:做变量选择,但在强相关特征间不稳定;
  • 弹性网:折中,常在相关特征较多时优选;
  • 需标准化特征;用交叉验证选择 λ\lambda 和(或)α\alpha

非线性模型

非线性模型可以捕捉更复杂的数据关系。思路包括基函数扩展、局部回归与核方法、以及可加模型(GAM)。

多项式与样条(Splines)

# 多项式回归
x <- 1:50
set.seed(1)
y <- 0.1 * x^2 - 3*x + 10 + rnorm(50, sd = 20)
model_poly <- lm(y ~ poly(x, 2))
summary(model_poly)

自然样条与 B 样条能在保持平滑的同时避免高次多项式在边界处的震荡,可用 splines::ns / splines::bs

# 自然样条
library(splines)
model_ns <- lm(y ~ ns(x, df = 4))
summary(model_ns)

局部回归与核回归

  • LOESS/LOWESS:局部加权回归,平滑复杂关系;
  • 核回归:通过核权重对邻域内点加权平均。
# LOESS
df <- data.frame(x = x, y = y)
fit_loess <- loess(y ~ x, data = df, span = 0.3)
pred <- predict(fit_loess, newdata = data.frame(x = x))
# 核回归(ksmooth 在 stats 包中)
set.seed(123)
xk <- sort(runif(100))
yk <- sin(4 * xk) + rnorm(100, sd = 0.2)
fit_k <- ksmooth(xk, yk, kernel = "normal", bandwidth = 0.1)

嵌入对比:

  • 多项式/样条:全局/分段全局拟合,可解释(基函数系数),适于结构化非线性;
  • LOESS/核回归:更“局部”,对带宽/跨度敏感,适合探索性建模与可视化。

基于树的方法

树模型适用于分类和回归任务,具有可解释性强的优点。

决策树

分裂准则:

  • 分类:基尼不纯度、信息增益(熵)
  • 回归:均方误差

剪枝(Cost-Complexity Pruning)控制树的复杂度,防止过拟合。

# 决策树
library(rpart)
data(iris)
model <- rpart(Species ~ ., data = iris,
               control = rpart.control(cp = 0.01, minsplit = 10))
printcp(model)  # 复杂度参数表
plotcp(model)   # 选择最优 cp
plot(model); text(model, use.n = TRUE)

随机森林

集成多棵决策树,使用自助抽样与特征子采样,降低方差。可利用 OOB(袋外)样本估计泛化误差,并提供特征重要性。

# 随机森林
library(randomForest)
data(iris)
set.seed(1)
rf <- randomForest(Species ~ ., data = iris, ntree = 500, mtry = 2, importance = TRUE)
print(rf)
importance(rf)

嵌入对比(树、随机森林、梯度提升):

  • 单树:可解释性极强,但高方差;
  • 随机森林:显著降方差、稳健,概率输出较可靠,解释性一般(可用特征重要性/部分依赖);
  • 梯度提升(GBM/XGBoost):通常精度更高、对超参敏感、训练较慢,适合结构化表格数据的强基线。

支持向量机

支持向量机(SVM)通过最大化间隔实现分类或回归。软间隔 SVM 的目标(线性核):

minw,b,ξ 12w2+Ciξis.t.yi(wϕ(xi)+b)1ξi, ξi0\min_{\mathbf{w},b,\xi} \ \frac{1}{2}\|\mathbf{w}\|^2 + C\sum_{i}\xi_i \quad \text{s.t.} \quad y_i(\mathbf{w}^\top \phi(x_i) + b) \ge 1 - \xi_i, \ \xi_i \ge 0

核技巧通过在对偶问题中引入核函数 K(xi,xj)K(x_i, x_j)(如 RBF 核)实现非线性分割。关键超参:CC(间隔-误差权衡)、γ\gamma(RBF 核宽度)。特征缩放对 SVM 至关重要。

# SVM 分类
library(e1071)
data(iris)
set.seed(1)
model <- svm(Species ~ ., data = iris, kernel = "radial", cost = 1, gamma = 0.1, probability = TRUE)
predict(model, iris[1:5,], probability = TRUE)

嵌入对比(与逻辑回归/树):

  • SVM 在边界复杂但噪声适中时强大;在大量噪声/重叠时可能不如逻辑回归稳健;
  • 与树系模型相比,SVM 对特征缩放敏感、解释性弱,但在中小样本下常有优势。

无监督学习

无监督学习用于发现数据中的结构和模式(又称“非监督学习”)。

聚类分析

K-means 目标函数:

min{Ck}k=1KxiCkxiμk2\min_{\{C_k\}} \sum_{k=1}^K \sum_{x_i\in C_k}\|x_i - \mu_k\|^2

要点:

  • 需要预先给定 K,可用“肘部法则”、轮廓系数(Silhouette)辅助选择;
  • 对缩放敏感,建议标准化;
  • 初始中心影响结果(k-means++ 初始化更稳健)。
# K-means 聚类
data(iris)
set.seed(123)
X <- scale(iris[, -5])
result <- kmeans(X, centers = 3, nstart = 20)
table(result$cluster, iris$Species)

层次聚类(凝聚/分裂)、不同链接方式(单/全/平均/Ward)在簇形状与噪声下的表现不同,可通过树状图(dendrogram)观察。

主成分分析(PCA)

用于降维和特征提取,通过最大化方差方向找到正交主成分。与 SVD 紧密相关:

XRn×p, PCASVD(Xc)=UΣVX \in \mathbb{R}^{n\times p}, \ \text{PCA} \equiv \text{SVD}(X_c) = U\Sigma V^\top

解释方差比(Proportion of Variance Explained, PVE)帮助选择主成分个数。

# PCA
data(iris)
X <- scale(iris[, -5])
pca <- prcomp(X, scale. = FALSE)
summary(pca)       # 含各主成分方差贡献
head(pca$x)        # 主成分得分

嵌入对比(PCA vs t-SNE/UMAP):

  • PCA 线性、可解释、快速,适用于压缩、可视化;
  • t-SNE/UMAP 更适可视化非线性流形结构(但不保持全局距离),多用于探索性分析。

粤ICP备2025414119号 粤公网安备44030002006951号

© 2025 Saurlax · Powered by Astro