统计学习
导论
统计学习是一门研究如何通过数据推断规律、建立模型并进行预测的学科。它融合了统计学、机器学习和数据挖掘等领域的思想,广泛应用于金融、医疗、互联网等行业。
统计学习的基本任务:
- 描述数据的分布和特征
- 建立预测模型
- 评估模型性能
统计学习的主要类型:
- 监督学习:有标签数据,目标是预测或分类
- 无监督学习:无标签数据,目标是发现数据结构
一个贯穿全篇的重要理念是“偏差-方差权衡”(Bias-Variance Trade-off)。在回归任务中,预测误差(期望意义下的测试 MSE)可分解为:
通常,更复杂的模型(低偏差)会带来更高的方差,而更简单的模型(高偏差)方差较低。模型选择与正则化正是为了在二者之间取得平衡。
评价模型精度
模型评估是统计学习中的核心环节,常用指标包括均方误差(MSE)、平均绝对误差(MAE)、决定系数()、准确率、召回率、F1 值、ROC-AUC、PR-AUC、对数损失(log loss)等。合理的评估指标应与任务目标、数据分布(尤其是是否类别不平衡)、业务代价相匹配。
回归模型的评估:
-
均方误差(MSE)
-
平均绝对误差(MAE)
-
决定系数()
# 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 定理)。
-
矩阵形式:
-
常见假设(用于推断与置信区间):线性可加、误差独立同分布、同方差、正态性(用于小样本推断)
简单线性回归
假设 。
# 简单线性回归
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):
极大似然估计等价于最小化对数损失(交叉熵):
# 逻辑回归
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)。
朴素贝叶斯
基于贝叶斯定理并假设条件独立:
适用于高维稀疏数据(如文本分类,多项式朴素贝叶斯),对特征独立性不敏感时表现很好。
# 朴素贝叶斯(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 更擅长评估统计量不确定性与小样本稳定性。
线性模型选择与正则化
用于防止过拟合,提高模型泛化能力,并可进行变量选择。
常见模型选择准则(适合线性回归):
- 调整后 :惩罚变量个数;
- AIC / BIC / Mallows’s :
逐步选择(前向/后向/逐步回归)在高维时可能不稳定,正则化更为稳健。
岭回归(Ridge)
在 OLS 基础上加入 L2 惩罚,缩小系数,缓解多重共线性:
# 岭回归(推荐使用 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):
# 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,兼具变量选择与组效应(处理相关特征):
实践要点(嵌入对比):
- 岭:不做变量选择,抗多重共线性强;
- Lasso:做变量选择,但在强相关特征间不稳定;
- 弹性网:折中,常在相关特征较多时优选;
- 需标准化特征;用交叉验证选择 和(或)。
非线性模型
非线性模型可以捕捉更复杂的数据关系。思路包括基函数扩展、局部回归与核方法、以及可加模型(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 的目标(线性核):
核技巧通过在对偶问题中引入核函数 (如 RBF 核)实现非线性分割。关键超参:(间隔-误差权衡)、(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 目标函数:
要点:
- 需要预先给定 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 紧密相关:
解释方差比(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 更适可视化非线性流形结构(但不保持全局距离),多用于探索性分析。