Scikit-learn 回归算法
回归是监督学习的重要任务,用于预测连续数值型目标变量。与分类问题预测离散类别不同,回归关注的是预测具体的数值。
回归问题概述
回归的目标是预测连续值:
- 简单线性回归:预测单个数值(如房价预测)
- 多元回归:使用多个特征预测(如基于面积、房间数预测房价)
- 多项式回归:捕捉非线性关系
线性回归
1. 普通最小二乘法(OLS)
线性回归是最基础的回归方法,它试图找到一条直线(或超平面)使得预测值与真实值之间的误差平方和最小。
数学原理:
线性回归要最小化以下目标函数:
其中 是系数向量, 是特征矩阵, 是目标变量。
为什么是最小二乘法?
最小二乘法选择使残差平方和最小的直线。从统计角度看,当误差服从均值为零的正态分布时,最小二乘估计是最优的(最大似然估计)。
from sklearn.linear_model import LinearRegression
from sklearn.datasets import make_regression
from sklearn.model_selection import train_test_split
from sklearn.metrics import mean_squared_error, r2_score
import numpy as np
# 生成回归数据
X, y = make_regression(
n_samples=200,
n_features=1,
noise=10,
random_state=42
)
# 划分训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(
X, y, test_size=0.2, random_state=42
)
# 创建并训练模型
model = LinearRegression()
model.fit(X_train, y_train)
# 预测
y_pred = model.predict(X_test)
# 评估
print(f"斜率 (系数): {model.coef_[0]:.4f}")
print(f"截距: {model.intercept_:.4f}")
print(f"R² 分数: {r2_score(y_test, y_pred):.4f}")
print(f"均方误差: {mean_squared_error(y_test, y_pred):.4f}")
参数说明:
fit_intercept:是否计算截距,默认为 Truecopy_X:是否复制 X,默认为 Truen_jobs:用于计算的 CPU 核心数
2. 岭回归(Ridge Regression)
岭回归在普通线性回归的基础上添加了 L2 正则化项,用于处理多重共线性问题和防止过拟合。
数学原理:
其中 是正则化参数,控制系数收缩的程度。
为什么要用岭回归?
- 处理多重共线性:当特征之间高度相关时,普通线性回归的系数会变得不稳定
- 防止过拟合:正则化项会惩罚大的系数,使模型更简单
- 处理特征数多于样本数的情况:普通线性回归在这种情况下无法求解
from sklearn.linear_model import Ridge
# 创建岭回归模型
ridge = Ridge(alpha=1.0)
ridge.fit(X_train, y_train)
# 预测和评估
y_pred = ridge.predict(X_test)
print(f"R² 分数: {r2_score(y_test, y_pred):.4f}")
参数说明:
alpha:正则化强度,必须是非负浮点数,值越大,正则化越强solver:求解方法,可选 'auto', 'svd', 'cholesky', 'lsqr', 'sparse_cg', 'sag', 'saga'
3. Lasso 回归
Lasso(Least Absolute Shrinkage and Selection Operator)使用 L1 正则化,它的一个重要特性是可以将一些系数压缩为零,从而实现特征选择。
数学原理:
Lasso 的独特优势:
- 特征选择:自动将不重要的特征系数变为零
- 稀疏性:产生的模型更稀疏,便于解释
- 处理高维数据:在特征数多于样本数时依然有效
from sklearn.linear_model import Lasso
# 创建 Lasso 模型
lasso = Lasso(alpha=0.1)
lasso.fit(X_train, y_train)
# 预测和评估
y_pred = lasso.predict(X_test)
print(f"R² 分数: {r2_score(y_test, y_pred):.4f}")
print(f"非零系数数量: {np.sum(lasso.coef_ != 0)}")
4. 弹性网络(ElasticNet)
弹性网络结合了 L1 和 L2 正则化,兼顾 Lasso 的特征选择能力和 Ridge 的稳定性。
数学原理:
其中 是 l1_ratio 参数,控制 L1 和 L2 的混合比例。
from sklearn.linear_model import ElasticNet
# 创建弹性网络模型
elastic = ElasticNet(alpha=0.1, l1_ratio=0.5)
elastic.fit(X_train, y_train)
y_pred = elastic.predict(X_test)
print(f"R² 分数: {r2_score(y_test, y_pred):.4f}")
非线性回归
1. 多项式回归
当数据呈现非线性关系时,可以使用多项式回归来拟合。
from sklearn.preprocessing import PolynomialFeatures
from sklearn.linear_model import LinearRegression
from sklearn.pipeline import Pipeline
import numpy as np
# 创建一个非线性数据集
X = np.sort(np.random.rand(50, 1) * 5, axis=0)
y = np.sin(X).ravel() + np.random.normal(0, 0.1, X.shape[0])
# 创建多项式回归管道
poly_model = Pipeline([
('poly', PolynomialFeatures(degree=3)),
('linear', LinearRegression())
])
poly_model.fit(X, y)
y_pred = poly_model.predict(X)
print(f"R² 分数: {r2_score(y, y_pred):.4f}")
2. 核岭回归(Kernel Ridge Regression)
核岭回归结合了岭回归和核技巧,可以处理非线性问题。
from sklearn.kernel_ridge import KernelRidge
# 使用 RBF 核
krr = KernelRidge(alpha=1.0, kernel='rbf', gamma=0.1)
krr.fit(X_train, y_train)
y_pred = krr.predict(X_test)
print(f"R² 分数: {r2_score(y_test, y_pred):.4f}")
决策树回归
决策树
决策树可以用于回归任务,通过划分特征空间来预测连续值。
from sklearn.tree import DecisionTreeRegressor
# 创建决策树回归模型
tree = DecisionTreeRegressor(max_depth=5, random_state=42)
tree.fit(X_train, y_train)
y_pred = tree.predict(X_test)
print(f"R² 分数: {r2_score(y_test, y_pred):.4f}")
参数说明:
max_depth:树的最大深度min_samples_split:节点分裂所需的最小样本数min_samples_leaf:叶节点的最小样本数
随机森林回归
随机森林是集成多棵决策树的回归模型,通常能提供更好的预测性能。
from sklearn.ensemble import RandomForestRegressor
# 创建随机森林回归模型
rf = RandomForestRegressor(
n_estimators=100,
max_depth=10,
random_state=42
)
rf.fit(X_train, y_train)
y_pred = rf.predict(X_test)
print(f"R² 分数: {r2_score(y_test, y_pred):.4f}")
# 查看特征重要性
print("特征重要性:", rf.feature_importances_)
梯度提升回归(Gradient Boosting)
梯度提升是一种强大的集成方法,通过逐步训练弱学习器来减少残差。
from sklearn.ensemble import GradientBoostingRegressor
# 创建梯度提升回归模型
gb = GradientBoostingRegressor(
n_estimators=100,
learning_rate=0.1,
max_depth=5,
random_state=42
)
gb.fit(X_train, y_train)
y_pred = gb.predict(X_test)
print(f"R² 分数: {r2_score(y_test, y_pred):.4f}")
模型评估指标
回归问题有多种评估指标:
1. 均方误差(MSE)
from sklearn.metrics import mean_squared_error
mse = mean_squared_error(y_test, y_pred)
print(f"均方误差: {mse:.4f}")
2. 均方根误差(RMSE)
RMSE 是 MSE 的平方根,与目标变量的单位相同,更容易解释。
import numpy as np
rmse = np.sqrt(mean_squared_error(y_test, y_pred))
print(f"均方根误差: {rmse:.4f}")
3. 决定系数(R²)
R² 表示模型解释目标变量方差的比例,取值范围通常是 0 到 1。
from sklearn.metrics import r2_score
r2 = r2_score(y_test, y_pred)
print(f"R² 分数: {r2:.4f}")
4. 平均绝对误差(MAE)
from sklearn.metrics import mean_absolute_error
mae = mean_absolute_error(y_test, y_pred)
print(f"平均绝对误差: {mae:.4f}")
完整示例:房价预测
from sklearn.datasets import load_diabetes
from sklearn.model_selection import train_test_split, cross_val_score
from sklearn.preprocessing import StandardScaler
from sklearn.linear_model import LinearRegression, Ridge, Lasso
from sklearn.ensemble import RandomForestRegressor, GradientBoostingRegressor
from sklearn.metrics import mean_squared_error, r2_score
import pandas as pd
# 加载糖尿病数据集
data = load_diabetes()
X = data.data
y = data.target
feature_names = data.feature_names
# 划分数据集
X_train, X_test, y_train, y_test = train_test_split(
X, y, test_size=0.2, random_state=42
)
# 特征标准化
scaler = StandardScaler()
X_train_scaled = scaler.fit_transform(X_train)
X_test_scaled = scaler.transform(X_test)
# 比较多个模型
models = {
"线性回归": LinearRegression(),
"岭回归": Ridge(alpha=1.0),
"Lasso": Lasso(alpha=0.1),
"随机森林": RandomForestRegressor(n_estimators=100, random_state=42),
"梯度提升": GradientBoostingRegressor(n_estimators=100, random_state=42)
}
results = []
for name, model in models.items():
model.fit(X_train_scaled, y_train)
y_pred = model.predict(X_test_scaled)
mse = mean_squared_error(y_test, y_pred)
r2 = r2_score(y_test, y_pred)
# 交叉验证
cv_scores = cross_val_score(
model, X_train_scaled, y_train,
cv=5, scoring='r2'
)
results.append({
"模型": name,
"测试 MSE": mse,
"测试 R²": r2,
"交叉验证 R² (均值)": cv_scores.mean()
})
# 显示结果
df = pd.DataFrame(results)
print(df)
算法选择建议
| 场景 | 推荐算法 |
|---|---|
| 简单基线模型 | 线性回归 |
| 特征相关性强 | 岭回归 |
| 需要特征选择 | Lasso |
| 特征既相关又需要选择 | 弹性网络 |
| 非线性关系 | 多项式回归、核岭回归 |
| 需要可解释性 | 线性回归、决策树 |
| 追求预测精度 | 随机森林、梯度提升 |
| 大规模数据 | 随机梯度下降(SGDRegressor) |