机器学习算法——回归任务

发布于:2025-03-05 ⋅ 阅读:(36) ⋅ 点赞:(0)

回归分析是估计因变量和自变量之间关系的过程。

目录
1、多元线性回归
2、岭回归
3、Lasso回归
4、弹性网络回归
5、多项式回归
6、指数回归
7、自然对数回归
8、广义线性模型 GLM
9、Cox比例风险模型
10、决策树回归
11、随机森林回归
12、梯度提升回归
13、XGBoost回归
14、LightGBM回归
15、CatBoost回归
16、支持向量回归 SVR
17、K近邻回归 KNN
18、贝叶斯回归
19、神经网络回归
20、对比总结
21、完整代码

1、多元线性回归

       线性回归是一种用于预测分析的统计学方法,它通过建立一个或多个自变量与一个因变量之间的线性关系来预测连续的数值。线性回归的目的是找到最佳拟合直线(在二维空间中)或超平面(在多维空间中),如果有一个自变量,就是一元线性回归;如果有多个自变量,那就是多元线性回归。
在这里插入图片描述

       误差:将理论与实际间的差别表示出来,用ε。
       损失函数:真实值和预测值间的差值。均方误差MSE、均方根误差RMSE、平均绝对误差MAE、决定系数R-squared。

优点:
       简单易懂:线性回归模型结构简单,容易理解和实现。
       计算速度快:计算复杂度低,适用于大规模数据集。
       解释性强:模型参数具有明确的统计意义,可以解释特征对目标变量的影响。

缺点:
       线性假设:假设特征和目标变量之间是线性关系,无法捕捉非线性关系。
       对异常值敏感:异常值会显著影响模型参数的估计。
       多重共线性:特征之间的多重共线性会导致参数估计不稳定。

# 多元线性回归
lr = LinearRegression()
lr.fit(X_train, y_train)
y_pred = lr.predict(X_test)
print("多元线性回归 MSE:", mean_squared_error(y_test, y_pred))

2、岭回归

       在线性回归中加入L2正则化,防止过拟合。
       一种改进的线性回归方法,主要用于处理多重共线性(自变量之间存在高度相关性)的问题。它通过在损失函数中加入一个惩罚项,使得回归系数尽量小,以此来减少模型的复杂度和过拟合风险。
在这里插入图片描述

# 岭回归
ridge = Ridge(alpha=1.0) # alpha正则化强度
ridge.fit(X_train, y_train)
y_pred = ridge.predict(X_test)
print("岭回归 MSE:", mean_squared_error(y_test, y_pred))

3、Lasso回归

       加入L1正则化,适用于特征选择。
       一种改进的线性回归方法,通过引入L1正则化项来进行特征选择和缩减。与岭回归不同,Lasso回归不仅能缩小回归系数,还能将一些回归系数缩减为零,从而实现特征选择。不仅可以防止训练过拟合的正则化器,还强制学习权重的稀疏性。
在这里插入图片描述

       优点:通过特征选择提高模型的解释性、减少模型的复杂度和过拟合、适合处理高维数据。

# Lasso回归
lasso = Lasso(alpha=0.1) # alpha正则化强度
lasso.fit(X_train, y_train)
y_pred = lasso.predict(X_test)
print("Lasso回归 MSE:", mean_squared_error(y_test, y_pred))

4、弹性网络回归

       结合L1和L2正则化,平衡岭回归和Lasso回归的优点。
在这里插入图片描述

# 弹性网络回归
elastic_net = ElasticNet(alpha=0.1, l1_ratio=0.5)# alpha正则化强度;l1_ratioL1和L2正则化的混合比例
elastic_net.fit(X_train, y_train)
y_pred = elastic_net.predict(X_test)
print("弹性网络回归 MSE:", mean_squared_error(y_test, y_pred))

5、多项式回归

       线性回归假设因变量和自变量之间的关系是线性的。当数据之间的关系不是线性时,它无法拟合数据。多项式回归假定自变量和因变量之间存在某种非线性关系,通过将m次多项式拟合到数据点来扩展线性回归的拟合能力。
在这里插入图片描述

# 多项式回归
degree = 2 # degree多项式的阶数
polyreg = make_pipeline(PolynomialFeatures(degree), LinearRegression())
polyreg.fit(X_train, y_train)
y_pred = polyreg.predict(X_test)
print("多项式回归 MSE:", mean_squared_error(y_test, y_pred))

6、指数回归

       一种非线性回归方法,拟合一个指数函数,形如y=a exp(bx)。指数回归通常用于增长率或衰减率随时间变化的场景,如人口增长、放射性衰变等。

# 指数回归(通过对数变换)
y_train_exp = np.log(y_train)
exp_reg = LinearRegression()
exp_reg.fit(X_train, y_train_exp)
y_pred = np.exp(exp_reg.predict(X_test))
print("指数回归 MSE:", mean_squared_error(y_test, y_pred))

7、自然对数回归

       因变量和/或自变量被转换为自然对数形式。
       对数-线性模型:ln(Y)=a+bX+ϵ
       线性-对数模型:Y=a+bln(X)+ϵ
       双对数模型:ln(Y)=a+bln(X)+ϵ

# 自然对数回归
y_train_log = np.log(y_train)
log_reg = LinearRegression()
log_reg.fit(X_train, y_train_log)
y_pred = np.exp(log_reg.predict(X_test))
print("自然对数回归 MSE:", mean_squared_error(y_test, y_pred))

8、广义线性模型GLM

       传统线性回归模型的一种扩展,旨在通过统一的框架处理更广泛的数据类型和分布。线性回归模型假设因变量Y服从正态分布,而广义线性模型不要求因变量Y服从正态分布,可以是其他分布,如二项分布、泊松分布等。
       线性预测器:自变量的线性组合在这里插入图片描述

       链接函数:链接函数是GLM的核心组成部分,它建立了线性预测器(自变量的线性组合)和因变量的期望值之间的联系。
       引入一个链接函数g(μ)将因变量的期望值μ=E[Y]与线性预测器ŋ=Xβ联系起来:g(μ)=Xβ。
       常见链接函数包括:
在这里插入图片描述

       GLM可以看作是普通线性回归模型的扩展,它通过引入链接函数和分布族,能够处理更复杂的数据类型和关系。

# 广义线性模型 (GLM)
X_train_const = add_constant(X_train) # 添加常数项(截距)到特征矩阵
glm = OLS(y_train, X_train_const).fit() # OLS普通最小二乘法
X_test_const = add_constant(X_test)
y_pred = glm.predict(X_test_const)
print("广义线性模型 MSE:", mean_squared_error(y_test, y_pred))

9、Cox比例风险模型

       主要用于研究生存时间与多个自变量之间的关系,尤其适用于处理时间事件(如死亡、疾病复发、设备故障等)的数据。广泛应用于医学(患者的生存时间与治疗方式)、工程(设备的可靠性,预测设备故障)、金融(信用风险评估和保险定价)。
在这里插入图片描述

       h(t,X)表示在t时刻,自变量X的个体风险函数(一个人因为某些因素(比如吸烟、年龄等)的危险程度)。
       h0(t)基线危险,(如果一个人没有任何特殊因素(比如不吸烟、不吃药、身体很健康)危险程度)。Cox模型不关心这个“背景危险”具体是多少,它只关心不同人之间的危险程度的差别。

       举例:
       吸烟人群危险程度是在这里插入图片描述

       不吸烟人群危险程度是在这里插入图片描述

       所以吸烟人群的危险程是不吸烟人群的1.65倍。

# Cox比例风险模型
data = X_train.copy()
data['time'] = y_train  # 假设y_train是生存时间
data['event'] = np.random.randint(0, 2, size=len(y_train))  # 随机生成事件
cph = CoxPHFitter()
cph.fit(data, duration_col='time', event_col='event')
y_pred = cph.predict_expectation(X_test)
print("Cox比例风险模型 MSE:", mean_squared_error(y_test, y_pred))

10、决策树回归

       使用树结构进行预测,通过特征分割数据。一种非参数模型,通过构建树状结构来进行预测。每个节点代表一个特征,分支代表该特征的取值,叶子节点代表预测结果。

       构建步骤:
       1.选择最优特征:根据某种指标(如信息增益、基尼系数)选择最优特征进行分割。
       2.分割数据集:根据选择的特征将数据集分割成子集。
       3.递归构建子树:对子集递归调用上述步骤,直到满足停止条件(如所有数据点属于同一类别或达到最大深度)

       决策树回归适用于处理非线性关系、缺失数据和特征交互复杂的情况。其主要优点包括:易于理解和解释、处理分类和回归任务、对数据预处理要求低。。

# 决策树回归
from sklearn.tree import DecisionTreeRegressor
dt = DecisionTreeRegressor(random_state=42)
dt.fit(X_train, y_train)
y_pred = dt.predict(X_test)
print("决策树回归 MSE:", mean_squared_error(y_test, y_pred))

11、随机森林回归

       通过构建多个决策树并对其结果进行平均,来提高模型的预测性能和稳定性。它通过引入随机性来构建多样化的决策树,从而减少过拟合和提高泛化能力。
       随机森林回归适用于处理非线性关系、大规模数据集和特征间复杂交互的情况。其主要优点包括:高精度预测、对数据预处理要求低、处理缺失数据的能力强、可以评估特征重要性。

# 随机森林回归
rf = RandomForestRegressor(n_estimators=100, random_state=42) # n_estimators: 树的数量
rf.fit(X_train, y_train)
y_pred = rf.predict(X_test)
print("随机森林回归 MSE:", mean_squared_error(y_test, y_pred))

12、梯度提升回归

       一种集成学习方法,通过逐步构建多个弱学习器(通常是决策树),每个新的学习器都在之前学习器的基础上进行改进,以减少预测误差。其核心思想是通过逐步优化损失函数,最终得到一个强学习器。
       XGBoost, LightGBM, CatBoost, NGBoost实际上是对梯度提升方法的不同实现,针对同一目标、做了不同的优化处理。

# 梯度提升回归
gbr = GradientBoostingRegressor(n_estimators=100, random_state=42)) # n_estimators: 树的数量
gbr.fit(X_train, y_train)
y_pred = gbr.predict(X_test)
print("梯度提升回归 MSE:", mean_squared_error(y_test, y_pred))

13、XGBoost回归

       一种增强型的梯度提升算法,通过逐步构建多个决策树,优化损失函数来减少误差,并引入正则化项以防止过拟合(将树模型的复杂度加入到正则项中)。

# XGBoost回归
xgb_reg = xgb.XGBRegressor(n_estimators=100, random_state=42)) # n_estimators: 树的数量
xgb_reg.fit(X_train, y_train)
y_pred = xgb_reg.predict(X_test)
print("XGBoost回归 MSE:", mean_squared_error(y_test, y_pred))

14、LightGBM回归

       一种高效的梯度提升框架,由微软公司开发,XGBoost的升级版,主要用于大数据集和高维数据的处理。LightGBM通过基于直方图的决策树学习算法,显著提高了训练速度和内存效率,同时保持较高的预测精度。

# LightGBM回归
lgb_reg = lgb.LGBMRegressor(n_estimators=100, random_state=42)) # n_estimators: 树的数量
lgb_reg.fit(X_train, y_train)
y_pred = lgb_reg.predict(X_test)
print("LightGBM回归 MSE:", mean_squared_error(y_test, y_pred))

15、CatBoost回归

       专门处理类别特征的梯度提升算法。采用的基模型是对称决策树提高了训练和预测的速度,算法的参数少、支持分类变量,通过可以防止过拟合。内置了复杂的正则化技术,如梯度偏差校正和L2正则化,有效防止过拟合。

# CatBoost回归
cb_reg = cb.CatBoostRegressor(n_estimators=100, random_state=42, verbose=0) # n_estimators: 树的数量
cb_reg.fit(X_train, y_train)
y_pred = cb_reg.predict(X_test)
print("CatBoost回归 MSE:", mean_squared_error(y_test, y_pred))

16、支持向量回归SVR

       支持向量回归SVR是支持向量机SVM的一个变种,用于回归问题。SVR通过在高维空间中寻找一个最佳的超平面,以最小化预测误差。核心思想是通过核函数将低维特征映射到高维特征空间,从而处理非线性回归问题。
在这里插入图片描述

# 支持向量回归 (SVR)
svr = SVR(kernel='rbf') # kernel: 核函数类型
svr.fit(X_train, y_train)
y_pred = svr.predict(X_test)
print("支持向量回归 MSE:", mean_squared_error(y_test, y_pred))

17、K近邻回归 KNN

       在训练空间中找到距离新数据点最近的K个数据点,然后根据k个最近数据点中多数类别对新数据点进行分类,将一个样本的类别归于它的邻近样本。
KNN方法既可以做分类,也可以做回归。在分类预测时,一般采用多数表决法。在做回归预测时,一般使用平均值法。
在这里插入图片描述

       在KNN回归中,因变量是连续的,分布在整个特征空间中。当有新的数据点红色点出现时,会使用某种距离度量(如欧几里得距离、曼哈顿距离、闵可夫斯基距离)接近的新数据点的K个近邻样本。找到这些邻居后,新数据点的预测值通过计算这些邻居的因变量值的平均值来确定。

# K近邻回归 (KNN)
knn = KNeighborsRegressor(n_neighbors=5) # n_neighbors:邻居数量。
knn.fit(X_train, y_train)
y_pred = knn.predict(X_test)
print("K近邻回归 MSE:", mean_squared_error(y_test, y_pred))

18、贝叶斯回归

       使用贝叶斯方法估计参数,提供概率解释。线性回归目标是找到一组解释数据的确定性权重值(β)。贝叶斯回归不是为每个权重找到一个值,而是尝试在假设先验的情况下找到这些权重的分布。
       从权重的初始分布开始,并根据数据,利用贝叶斯定理将先验分布与基于可能性和证据的后验分布联系起来,将分布推向正确的方向。

# 贝叶斯回归
from sklearn.linear_model import BayesianRidge
br = BayesianRidge()
br.fit(X_train, y_train)
y_pred = br.predict(X_test)
print("贝叶斯回归 MSE:", mean_squared_error(y_test, y_pred))

19、神经网络回归

       利用多层感知机(MLP)等结构,通过反向传播算法调整权重,优化预测精度。

20、对比总结

       根据数据规模、特征维度、非线性程度及计算资源,选择合适的回归模型。

  • 线性问题:多元线性回归、岭回归、Lasso回归、弹性网络回归。
  • 非线性问题:多项式回归、指数回归、自然对数回归、GLM、树模型(决策树、随机森林、梯度提升)、SVR、神经网络。
  • 生存分析:Cox比例风险模型。
  • 高维数据:Lasso回归、弹性网络回归、树模型、SVR。
  • 小样本:贝叶斯回归、SVR。
  • 大规模数据:树模型(XGBoost、LightGBM、CatBoost)、神经网络。

21、完整代码

import numpy as np
import pandas as pd
from sklearn.datasets import load_boston
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LinearRegression, Ridge, Lasso, ElasticNet
from sklearn.preprocessing import PolynomialFeatures
from sklearn.pipeline import make_pipeline
from sklearn.ensemble import RandomForestRegressor, GradientBoostingRegressor
from sklearn.svm import SVR
from sklearn.neighbors import KNeighborsRegressor
from sklearn.metrics import mean_squared_error
from statsmodels.api import OLS, add_constant
from lifelines import CoxPHFitter
import xgboost as xgb
import lightgbm as lgb
import catboost as cb

# 加载波士顿房价数据集
boston = load_boston()
X = pd.DataFrame(boston.data, columns=boston.feature_names)
y = pd.Series(boston.target, name='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("多元线性回归 MSE:", mean_squared_error(y_test, y_pred))

# 岭回归
ridge = Ridge(alpha=1.0) # alpha正则化强度,控制模型复杂度
ridge.fit(X_train, y_train)
y_pred = ridge.predict(X_test)
print("岭回归 MSE:", mean_squared_error(y_test, y_pred))

# Lasso回归
lasso = Lasso(alpha=0.1)
lasso.fit(X_train, y_train)
y_pred = lasso.predict(X_test)
print("Lasso回归 MSE:", mean_squared_error(y_test, y_pred))

# 弹性网络回归
elastic_net = ElasticNet(alpha=0.1, l1_ratio=0.5) # alpha正则化强度;l1_ratioL1和L2正则化的混合比例
elastic_net.fit(X_train, y_train)
y_pred = elastic_net.predict(X_test)
print("弹性网络回归 MSE:", mean_squared_error(y_test, y_pred))

# 多项式回归
degree = 2 # degree多项式的阶数
polyreg = make_pipeline(PolynomialFeatures(degree), LinearRegression())
polyreg.fit(X_train, y_train)
y_pred = polyreg.predict(X_test)
print("多项式回归 MSE:", mean_squared_error(y_test, y_pred))

# 指数回归(通过对数变换)
y_train_exp = np.log(y_train)
exp_reg = LinearRegression()
exp_reg.fit(X_train, y_train_exp)
y_pred = np.exp(exp_reg.predict(X_test))
print("指数回归 MSE:", mean_squared_error(y_test, y_pred))

# 自然对数回归
y_train_log = np.log(y_train)
log_reg = LinearRegression()
log_reg.fit(X_train, y_train_log)
y_pred = np.exp(log_reg.predict(X_test))
print("自然对数回归 MSE:", mean_squared_error(y_test, y_pred))

# 广义线性模型 (GLM)
X_train_const = add_constant(X_train) # 添加常数项(截距)到特征矩阵
glm = OLS(y_train, X_train_const).fit() # OLS普通最小二乘法
X_test_const = add_constant(X_test)
y_pred = glm.predict(X_test_const)
print("广义线性模型 MSE:", mean_squared_error(y_test, y_pred))

# Cox比例风险模型
data = X_train.copy()
data['time'] = y_train  # 假设y_train是生存时间
data['event'] = np.random.randint(0, 2, size=len(y_train))  # 随机生成事件
cph = CoxPHFitter()
cph.fit(data, duration_col='time', event_col='event')
y_pred = cph.predict_expectation(X_test)
print("Cox比例风险模型 MSE:", mean_squared_error(y_test, y_pred))

# 决策树回归
from sklearn.tree import DecisionTreeRegressor
dt = DecisionTreeRegressor(random_state=42)
dt.fit(X_train, y_train)
y_pred = dt.predict(X_test)
print("决策树回归 MSE:", mean_squared_error(y_test, y_pred))

# 随机森林回归
rf = RandomForestRegressor(n_estimators=100, random_state=42)
rf.fit(X_train, y_train)
y_pred = rf.predict(X_test)
print("随机森林回归 MSE:", mean_squared_error(y_test, y_pred))

# 梯度提升回归
gbr = GradientBoostingRegressor(n_estimators=100, random_state=42)
gbr.fit(X_train, y_train)
y_pred = gbr.predict(X_test)
print("梯度提升回归 MSE:", mean_squared_error(y_test, y_pred))

# XGBoost回归
xgb_reg = xgb.XGBRegressor(n_estimators=100, random_state=42)
xgb_reg.fit(X_train, y_train)
y_pred = xgb_reg.predict(X_test)
print("XGBoost回归 MSE:", mean_squared_error(y_test, y_pred))

# LightGBM回归
lgb_reg = lgb.LGBMRegressor(n_estimators=100, random_state=42)
lgb_reg.fit(X_train, y_train)
y_pred = lgb_reg.predict(X_test)
print("LightGBM回归 MSE:", mean_squared_error(y_test, y_pred))

# CatBoost回归
cb_reg = cb.CatBoostRegressor(n_estimators=100, random_state=42, verbose=0)
cb_reg.fit(X_train, y_train)
y_pred = cb_reg.predict(X_test)
print("CatBoost回归 MSE:", mean_squared_error(y_test, y_pred))

# 支持向量回归 (SVR)
svr = SVR(kernel='rbf')
svr.fit(X_train, y_train)
y_pred = svr.predict(X_test)
print("支持向量回归 MSE:", mean_squared_error(y_test, y_pred))

# K近邻回归 (KNN)
knn = KNeighborsRegressor(n_neighbors=5)
knn.fit(X_train, y_train)
y_pred = knn.predict(X_test)
print("K近邻回归 MSE:", mean_squared_error(y_test, y_pred))

# 贝叶斯回归
from sklearn.linear_model import BayesianRidge
br = BayesianRidge()
br.fit(X_train, y_train)
y_pred = br.predict(X_test)
print("贝叶斯回归 MSE:", mean_squared_error(y_test, y_pred))