机器学习-回归分析

·

一、综述

回归分析是一种统计学习方法,用于研究 自变量(X)与因变量(Y)之间的关系

找一个函数 f(X) 最好地拟合真实值 Y,通常表示为:Y=f(X)+ϵ。其中 ϵ 是噪声。

包括:

线性回归(Linear Regression)

逻辑回归(Logistic regressions)

多项式回归(Polynomial Regression)

逐步回归(Step Regression)

岭回归(Ridge Regression)

套索回归(Lasso Regression)

弹性网回归(ElasticNet)

二、线性回归

假设因变量与自变量之间是线性关系,通常采用 最小二乘法(OLS)

特点

  • 实现简单,可解释性强
  • 对异常值敏感
  • 不适用于非线性问题

实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
from sklearn.linear_model import LinearRegression
model = LinearRegression()
model.fit(X, y)
'''
LinearRegression()所创建的对象包含:
.fit():训练模型
.predict():预测
.coef_:系数
.intercept_:截距
(默认参数:fit_intercept=True, copy_X=True, n_jobs=None, positive=False)
fit(X, y)中的X是特征矩阵,y是目标变量,也就是分别存放y=a+bx1+cx2+...中的x和y
最终,我们可以得到:
model.coef_ 各特征的 β1, β2, ... βp
model.intercept_ 截距 β0
'''

三、逻辑回归

用于 分类问题。通过线性组合输入变量,然后用 Sigmoid 函数 转换为概率:
$$
p = \frac{1}{1 + e^{-(\beta_0 + \beta x)}}
$$
分类依据:

p>0.5 → 类别 1;

p<=0.5 → 类别 0

在python库中使用了LBFGS算法作为计算参数时的优化

LBFGS算法:BFGS 用一种近似的方式去“模拟”海森矩阵的逆,从而加速优化。而LBFGS算法即Limited-memory BFGS,是 BFGS 的改良版,它不保存完整的海森矩阵(太大),只保存少量历史梯度信息,这样既快、又省内存,适合高维数据优化(本人尝试了解了下BFGS算法的推导,了解后觉得…怎么证明的呢,数学的脑洞真非人吧…算了线代渣渣还是老老实实直接用吧,何必和自己过不去呢)】

特点

  • 简单高效
  • 可输出概率解释
  • 默认假设线性可分

实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
from sklearn.linear_model import LogisticRegression
model = LogisticRegression()
model.fit(X, y)
'''
默认参数包括:
penalty='l2', # 正则化方式
dual=False,
tol=1e-4, # 收敛精度阈值
C=1.0, # 正则化强度(1/λ)
fit_intercept=True, # 是否学习截距项
intercept_scaling=1,
class_weight=None, # 类别权重(处理不平衡样本)
random_state=None,
solver='lbfgs', # 优化器(默认 LBFGS)
max_iter=100, # 最大迭代次数
multi_class='auto', # 自动选择 one-vs-rest 或 multinomial
n_jobs=None, # 并行 CPU 核数
l1_ratio=None # 弹性网正则(ElasticNet)
'''

四、多项式回归

通过对特征做 多项式扩展 来拟合非线性关系。例如二次模型。

特点

  • 本质上还是“线性回归”
  • 能拟合非线性关系
  • 特征是“人为构造”的
  • 容易过拟合,泛化性差
  • 特征数量增长很快

实现

1
2
3
4
5
6
7
8
9
from sklearn.preprocessing import PolynomialFeatures
from sklearn.linear_model import LinearRegression

poly = PolynomialFeatures(degree=2)
X_poly = poly.fit_transform(X)
'''
本处实现参数扩展,再进行拟合,参数扩展过程见详细实现代码
'''
model = LinearRegression().fit(X_poly, y)

详细实现代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
import numpy as np
from sklearn.preprocessing import PolynomialFeatures
from sklearn.linear_model import LinearRegression

# 假设只有一个特征 x(例如:面积)
X = np.array([[1],
[2],
[3],
[4],
[5]]) # shape = (5, 1)

# 对应的 y(例如:某种非线性关系)
y = np.array([1.2, 1.9, 3.2, 3.9, 5.1])

# ① 生成多项式特征:比如 degree=2(二次项)
poly = PolynomialFeatures(degree=2, include_bias=True)
X_poly = poly.fit_transform(X)

print("原始 X:")
print(X)
print("多项式扩展后的 X_poly:")
print(X_poly) # 会多出 1, x, x^2 这几列

# ② 用线性回归拟合扩展后的特征
model = LinearRegression()
model.fit(X_poly, y)

# ③ 查看学到的参数
print("coef_(权重):", model.coef_)
print("intercept_(截距):", model.intercept_)

# ④ 预测:给一个新值 x=6
x_new = np.array([[6]])
x_new_poly = poly.transform(x_new)
y_pred = model.predict(x_new_poly)
print("x=6 时的预测值:", y_pred)

五、逐步回归

自动筛选特征:逐步加入或删除自变量。

包括:前向选择(从无到有加入变量)后向剔除(从全到少删除变量)逐步回归(两者结合)

特点

  • 自动特征选择

  • 提升模型简洁性

  • 可能陷入局部最优

  • 计算量较大

实现

这个算法在Sklearn 无直接实现,可通过 statsmodels 或自定义迭代 p-value。

常用指标:

1、AIC

公式:AIC=2k−2ln(L),

k:模型中参数个数(包括截距)

L:模型的最大似然

在逐步回归中,常用“AIC 最小”作为选择标准,寻找一个模型尽可能简单(k尽可能小)与拟合效果尽可能好(L尽可能大)的模型。

2、BIC

公式:BIC=ln(n)k−2ln(L)

k:模型中参数个数(包括截距)

L:模型的最大似然

n:样本数量

相比于AIC,BIC 更偏向“模型简单”,更“保守”,用途与AIC类似,更适合用于担心过拟合的场景内。

3、p-value

系数的显著性检验。算得的结果表示在“变量其实没用(βj=0\beta_j = 0βj=0)”这个前提下,得到当前这么极端的估计结果的概率有多大

一般p<0.05时,认为该参数是有用的。

4、Adjusted R²

调整后的 R² ,公式:
$$
\bar{R}^2 = 1 - \frac{\text{RSS}/(n - k - 1)}{\text{TSS}/(n - 1)}
$$

n:样本数量

k:模型中参数个数(包括截距)

它对自由度做了修正:

  • 加入没用变量时,R可能下降
  • 加入有用变量时,R才会上升

Adjusted R² 越大越好,同时考虑了拟合效果和复杂度。

实现范例:

前向逐步回归,基于 p-value(同理也可以写成基于AIC、BIC、Adjusted R²版本)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
import statsmodels.api as sm
import pandas as pd

def forward_stepwise_selection(X, y,
significance_level=0.05,
verbose=True):
"""
基于 p-value 的前向逐步回归选择变量
X: DataFrame,自变量
y: Series 或 1D array,因变量
significance_level: 进入模型的显著性水平阈值
"""
remaining_vars = list(X.columns) # 还没进模型的变量
selected_vars = [] # 已经选中的变量
current_score = float('inf') # 当前模型的 AIC(初始设为正无穷)
best_new_score = float('inf')

while remaining_vars:
scores_with_candidates = []

# 尝试把每个剩余变量加入模型,看 AIC 和 p-value
for candidate in remaining_vars:
# 当前已经选择的变量 + 新候选变量
formula_vars = selected_vars + [candidate]
X_candidate = sm.add_constant(X[formula_vars])
model = sm.OLS(y, X_candidate).fit()

# 记录:AIC、候选变量、该变量的 p-value
candidate_pvalue = model.pvalues[candidate]
scores_with_candidates.append(
(model.aic, candidate, candidate_pvalue)
)

# 在所有候选里选 AIC 最小的
scores_with_candidates.sort(key=lambda x: x[0])
best_new_score, best_candidate, best_pvalue = scores_with_candidates[0]

if verbose:
print(f"尝试加入变量: {best_candidate}, AIC={best_new_score:.3f}, p-value={best_pvalue:.4f}")

# 如果最好的候选变量在统计上显著,则加入模型
if best_pvalue < significance_level and best_new_score < current_score:
remaining_vars.remove(best_candidate)
selected_vars.append(best_candidate)
current_score = best_new_score
if verbose:
print(f"加入变量: {best_candidate}")
else:
# 没有显著变量可以加入了,停止
if verbose:
print("没有更多显著变量可加入,停止选择。")
break

# 最终拟合模型
X_selected = sm.add_constant(X[selected_vars])
final_model = sm.OLS(y, X_selected).fit()
return final_model, selected_vars

使用:

1
2
3
4
5
6
7
8
9
10
11
# 举例:假设你有一个 DataFrame df
# 其中 'y' 是因变量,其他列是自变量
# 比如:df.columns = ['y', 'x1', 'x2', 'x3', 'x4']

y = df['y']
X = df.drop(columns=['y'])

final_model, selected_vars = forward_stepwise_selection(X, y, significance_level=0.05)

print("\n最终选择的变量:", selected_vars)
print(final_model.summary())

summary() 里可以看到:每个变量的 系数、标准误差、t 值、p-value以及模型整体的 R²、Adjusted R²、AIC、BIC

六、 岭回归

在线性回归的损失中加入 L2 正则项,防止过拟合。

公式:
$$
\min_{\beta} \left[ \sum (y_i - \hat{y_i})^2 + \lambda \sum \beta_j^2 \right]
$$
其中 λ 控制惩罚力度。

特点

  • 解决多重共线性
  • 系数更稳定
  • 不会将系数缩到 0

实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
from sklearn.linear_model import Ridge
model = Ridge(alpha=1.0)
'''
默认参数:
alpha=1.0,
*,
fit_intercept=True,
copy_X=True,
max_iter=None,
tol=1e-4,
solver='auto',(Scikit-Learn 会根据 X 的大小与稀疏性自动选择最适合的 solver,等价于:稠密的小数据 → 'svd' 或 'cholesky;'稀疏矩阵 → 'sparse_cg';大规模高维数据 → 'sag' 或 'saga')
positive=False,
random_state=None
'''
model.fit(X, y)

七、套索回归

损失加入 L1 正则项

公式:
$$
\min_{\beta} \left[ \sum (y_i - \hat{y_i})^2 + \lambda \sum \beta_j^2 \right]
$$
其中 λ 控制惩罚力度。

特点

  • 可以把部分系数变为 0(实现特征选择)
  • 更稀疏的模型
  • 对共线性敏感

【与岭回归区别:

Ridge(L2):

  • 会让相关特征共同分担权重(共享系数)
  • 稳定性极强
  • 常用于存在强共线性的数据
  • 正则约束的结果是一个“圆形”

Lasso(L1):

  • 会“二选一”地删除部分相关特征
  • 对多重共线性可能不稳定
  • 当特征之间高度相似时,Lasso 的选择会有随机性
  • 正则约束的结果是一个方形,结果更易落在角上,导致出现0

总结:

岭回归(Ridge):把所有特征的系数都缩小 → 防止过拟合,多用于特征高度相关(多重共线性问题)、特征都可能有用(不希望删除任何特征)、噪声不大,样本量多的场景

套索回归(Lasso):把不重要的特征的系数直接压成 0 → 自动特征选择,多用于特征数量很多(尤其是大于样本数)、希望让模型自动筛选特征、特征中可能有很多无效变量的场景】

实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
from sklearn.linear_model import Lasso
model = Lasso(alpha=0.1)
'''
默认参数:
alpha=1.0,(这里改为了0.1)
*,
fit_intercept=True,
copy_X=True,
max_iter=1000,
tol=1e-4,
warm_start=False,
positive=False,
random_state=None,
selection='cyclic'
'''
model.fit(X, y)

八、弹性网回归

结合 L1(Lasso)和 L2(Ridge)

公式:
$$
\min_{\beta} \Big( \sum (y-\hat{y})^2 + \lambda_1 \sum |\beta_j| + \lambda_2 \sum \beta_j^2 \Big)
$$

特点

  • 既能选择特征(L1)
  • 又能处理共线性(L2)
  • 适用于高维数据(p > n)

实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
from sklearn.linear_model import ElasticNet
model = ElasticNet(alpha=1.0, l1_ratio=0.5)
'''
默认参数:
alpha=1.0,
l1_ratio=0.5,(这个参数设置为1.0是纯Lasso,设置为0是纯Ridge,设置为0.2-0.8则是典型的ElasticNet,即弹性网)
*,
fit_intercept=True,
copy_X=True,
max_iter=1000,
tol=1e-4,
warm_start=False,
positive=False,
random_state=None,
selection='cyclic'
'''
model.fit(X, y)

九、总结

方法 是否线性 是否支持非线性 是否正则化 特征选择 典型用途
线性回归 基本预测
逻辑回归 L2为主 分类
多项式回归 ✔(通过特征扩展) 非线性关系
逐步回归 自动变量筛选
岭回归 L2 多重共线性
套索回归 L1 稀疏模型
弹性网 L1+L2 高维数据

机器学习-回归分析
http://example.com/2025/11/14/机器学习-回归分析/
作者
oxygen
发布于
2025年11月14日
许可协议