Lucas带你手撕机器学习——套索回归

好的,下面我将详细介绍套索回归的背景、理论基础、实现细节以及在实践中的应用,同时还会讨论其优缺点和一些常见问题。

套索回归(Lasso Regression)

1. 背景与动机

在机器学习和统计学中,模型的复杂性通常会影响其在新数据上的泛化能力。特别是当特征数量多于样本数量时,模型容易过拟合,导致性能下降。为了解决这个问题,引入了正则化技术,以限制模型的复杂性。套索回归就是一种结合了线性回归与L1正则化的回归方法,具有以下特点:

  • 特征选择:由于L1正则化的特性,套索回归能够将一些特征的系数压缩为零,从而实现特征选择。这使得模型更简单、更易解释。

  • 提高泛化能力:通过减少特征数量,套索回归有助于提高模型的泛化能力,尤其在高维数据中表现更好。

2. 理论基础
2.1. 损失函数

套索回归的目标是最小化以下损失函数:
在这里插入图片描述

其中:
在这里插入图片描述
是目标变量与预测值之间的均方误差。
在这里插入图片描述
是L1正则化项,即模型参数的绝对值之和,𝜆 是正则化强度的超参数。

L1正则化会增加较大的惩罚,使得某些特征的系数可能被完全压缩为零,从而实现特征选择。

2.2. 优化算法

由于套索回归的损失函数是非光滑的(L1范数不连续),可以使用次梯度法、坐标下降法或其他优化方法来求解最优参数。坐标下降法是套索回归中一种常用且高效的优化算法。

3. 优缺点
3.1. 优点
  • 特征选择:能够自动选择重要特征,减少不必要的噪声,提高模型的可解释性。
  • 简化模型:减少模型的复杂性,降低过拟合的风险。
  • 适应高维数据:在特征数量远大于样本数量时,仍能有效工作。
3.2. 缺点
  • 可能丢失重要信息:如果正则化参数选择不当,可能会丢失对结果有影响的特征。
  • 对特征标准化敏感:套索回归对特征的尺度非常敏感,通常需要对特征进行标准化处理。
  • 在特征间高度相关时的局限性:在特征高度相关的情况下,套索回归可能随机选择其中一个特征,而忽略其他重要特征。
4. 实践中的应用

套索回归广泛应用于以下场景:

  • 金融风险建模:在预测信用评分或贷款违约的模型中,能够选择对结果影响最大的特征。
  • 生物医学:在基因选择和疾病预测等应用中,通过特征选择来提高模型的可解释性。
  • 文本分类:在文本特征提取中,通过选择重要的单词或短语来构建简化模型。
5. 使用 scikit-learnPyTorch 实现套索回归
5.1. scikit-learn 实现
import numpy as np
import matplotlib.pyplot as plt
from sklearn.model_selection import train_test_split
from sklearn.linear_model import Lasso
from sklearn.datasets import make_regression

# 生成示例数据
X, y, coef = make_regression(n_samples=100, n_features=10, noise=0.1, coef=True, random_state=42)

# 划分数据集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

# 创建套索回归模型
lasso_model = Lasso(alpha=1.0)  # alpha是正则化强度

# 训练模型
lasso_model.fit(X_train, y_train)

# 进行预测
y_pred = lasso_model.predict(X_test)

# 输出模型系数
print("模型系数:", lasso_model.coef_)
print("模型截距:", lasso_model.intercept_)

# 可视化真实值与预测值
plt.scatter(y_test, y_pred)
plt.xlabel("真实值")
plt.ylabel("预测值")
plt.title("真实值与预测值的比较")
plt.plot([y.min(), y.max()], [y.min(), y.max()], '--', color='red')  # 对角线
plt.show()

这段代码使用Python的Scikit-learn库实现了一个套索回归(Lasso Regression)模型,并对模型的性能进行了评估和可视化。以下是对代码的详细解释:

1. 导入必要的库

import numpy as np
import matplotlib.pyplot as plt
from sklearn.model_selection import train_test_split
from sklearn.linear_model import Lasso
from sklearn.datasets import make_regression
  • numpy用于数值计算和数组操作。
  • matplotlib.pyplot用于绘制图形和可视化。
  • train_test_split用于将数据集分割为训练集和测试集。
  • Lasso是套索回归模型的实现。
  • make_regression用于生成回归数据集。

2. 生成示例数据

X, y, coef = make_regression(n_samples=100, n_features=10, noise=0.1, coef=True, random_state=42)
  • make_regression生成一个包含100个样本和10个特征的回归数据集。
  • noise=0.1表示数据中添加的噪声,增加模型的复杂性。
  • coef=True表示返回生成的数据的真实系数,便于后续分析。
  • X是特征矩阵,y是目标变量,coef是生成的数据的真实系数。

3. 划分数据集

X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
  • 使用train_test_split将数据集划分为训练集和测试集,其中20%的数据用于测试,80%的数据用于训练。
  • random_state=42确保每次运行时划分的一致性。

4. 创建套索回归模型

lasso_model = Lasso(alpha=1.0)  # alpha是正则化强度
  • 创建一个套索回归模型对象lasso_model
  • alpha参数控制正则化强度,较高的alpha值会导致更多的特征系数被压缩到零,从而实现特征选择。

5. 训练模型

lasso_model.fit(X_train, y_train)
  • 使用训练集X_train和目标值y_train训练套索回归模型。

6. 进行预测

y_pred = lasso_model.predict(X_test)
  • 使用训练好的模型对测试集X_test进行预测,得到预测结果y_pred

7. 输出模型系数和截距

print("模型系数:", lasso_model.coef_)
print("模型截距:", lasso_model.intercept_)
  • lasso_model.coef_输出模型的特征系数,显示每个特征在模型中的重要性。
  • lasso_model.intercept_输出模型的截距,表示当所有特征都为零时的预测值。

8. 可视化真实值与预测值

plt.scatter(y_test, y_pred)
plt.xlabel("真实值")
plt.ylabel("预测值")
plt.title("真实值与预测值的比较")
plt.plot([y.min(), y.max()], [y.min(), y.max()], '--', color='red')  # 对角线
plt.show()
  • 使用plt.scatter()绘制真实值y_test和预测值y_pred的散点图。
  • plt.xlabel()plt.ylabel()设置X轴和Y轴的标签。
  • plt.title()设置图表标题。
  • plt.plot([y.min(), y.max()], [y.min(), y.max()], '--', color='red')绘制一条红色的对角线(y=x),用于比较真实值与预测值的关系。
  • plt.show()显示可视化结果。
5.2. PyTorch 实现
import torch
import torch.nn as nn
import numpy as np
import matplotlib.pyplot as plt
from sklearn.model_selection import train_test_split
from sklearn.datasets import make_regression

# 生成示例数据
X, y, coef = make_regression(n_samples=100, n_features=10, noise=0.1, coef=True, random_state=42)

# 划分数据集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

# 转换为PyTorch张量
X_train_tensor = torch.tensor(X_train, dtype=torch.float32)
y_train_tensor = torch.tensor(y_train, dtype=torch.float32).view(-1, 1)
X_test_tensor = torch.tensor(X_test, dtype=torch.float32)
y_test_tensor = torch.tensor(y_test, dtype=torch.float32).view(-1, 1)

# 创建套索回归模型
class LassoRegression(nn.Module):
    def __init__(self, input_dim, lambda_reg):
        super(LassoRegression, self).__init__()
        self.linear = nn.Linear(input_dim, 1)
        self.lambda_reg = lambda_reg

    def forward(self, x):
        return self.linear(x)

    def loss_function(self, y_pred, y_true):
        mse_loss = nn.MSELoss()(y_pred, y_true)
        l1_reg = self.lambda_reg * torch.sum(torch.abs(self.linear.weight))
        return mse_loss + l1_reg

# 超参数
input_dim = X_train.shape[1]
lambda_reg = 1.0
num_epochs = 1000
learning_rate = 0.01

# 初始化模型和优化器
model = LassoRegression(input_dim, lambda_reg)
optimizer = torch.optim.SGD(model.parameters(), lr=learning_rate)

# 训练模型
for epoch in range(num_epochs):
    model.train()
    optimizer.zero_grad()
    y_pred = model(X_train_tensor)
    loss = model.loss_function(y_pred, y_train_tensor)
    loss.backward()
    optimizer.step()

    if epoch % 100 == 0:
        print(f'Epoch [{epoch}/{num_epochs}], Loss: {loss.item():.4f}')

# 进行预测
model.eval()
with torch.no_grad():
    y_test_pred = model(X_test_tensor)

# 可视化真实值与预测值
plt.scatter(y_test, y_test_pred.numpy())
plt.xlabel("真实值")
plt.ylabel("预测值")
plt.title("真实值与预测值的比较")
plt.plot([y.min(), y.max()], [y.min(), y.max()], '--', color='red')  # 对角线
plt.show()

# 输出模型系数和截距
print("模型权重:", model.linear.weight.data.numpy())
print("模型偏置:", model.linear.bias.data.numpy())

这段代码实现了一个使用PyTorch构建的套索回归(Lasso Regression)模型。通过生成回归数据、训练模型、进行预测以及可视化结果,展示了深度学习框架在回归任务中的应用。以下是对代码的详细解释:

1. 导入必要的库

import torch
import torch.nn as nn
import numpy as np
import matplotlib.pyplot as plt
from sklearn.model_selection import train_test_split
from sklearn.datasets import make_regression
  • torchtorch.nn是PyTorch的主要库,用于构建和训练神经网络。
  • numpy用于数值计算。
  • matplotlib.pyplot用于数据可视化。
  • train_test_split用于将数据集分割为训练集和测试集。
  • make_regression用于生成回归数据集。

2. 生成示例数据

X, y, coef = make_regression(n_samples=100, n_features=10, noise=0.1, coef=True, random_state=42)
  • make_regression生成一个包含100个样本和10个特征的回归数据集。
  • noise=0.1表示数据中添加的噪声,增加模型的复杂性。
  • coef=True表示返回生成的数据的真实系数,便于后续分析。

3. 划分数据集

X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
  • 使用train_test_split将数据集划分为训练集和测试集,其中20%的数据用于测试,80%的数据用于训练。
  • random_state=42确保每次运行时划分的一致性。

4. 转换为PyTorch张量

X_train_tensor = torch.tensor(X_train, dtype=torch.float32)
y_train_tensor = torch.tensor(y_train, dtype=torch.float32).view(-1, 1)
X_test_tensor = torch.tensor(X_test, dtype=torch.float32)
y_test_tensor = torch.tensor(y_test, dtype=torch.float32).view(-1, 1)
  • 将NumPy数组转换为PyTorch张量,以便在PyTorch中使用。
  • view(-1, 1)将目标变量的形状调整为二维张量,适配模型的输出。

5. 创建套索回归模型

class LassoRegression(nn.Module):
    def __init__(self, input_dim, lambda_reg):
        super(LassoRegression, self).__init__()
        self.linear = nn.Linear(input_dim, 1)
        self.lambda_reg = lambda_reg

    def forward(self, x):
        return self.linear(x)

    def loss_function(self, y_pred, y_true):
        mse_loss = nn.MSELoss()(y_pred, y_true)
        l1_reg = self.lambda_reg * torch.sum(torch.abs(self.linear.weight))
        return mse_loss + l1_reg
  • 创建一个名为LassoRegression的类,继承自nn.Module
  • __init__方法初始化线性层和正则化强度lambda_reg
  • forward方法定义前向传播过程,返回线性层的输出。
  • loss_function方法定义了损失函数,包括均方误差(MSE)损失和L1正则化项,旨在实现套索回归的特性。

6. 超参数设置

input_dim = X_train.shape[1]
lambda_reg = 1.0
num_epochs = 1000
learning_rate = 0.01
  • input_dim为输入特征的数量(10)。
  • lambda_reg为正则化强度,影响模型的复杂性。
  • num_epochs设置为训练的迭代次数(1000次)。
  • learning_rate为学习率,控制模型参数更新的速度。

7. 初始化模型和优化器

model = LassoRegression(input_dim, lambda_reg)
optimizer = torch.optim.SGD(model.parameters(), lr=learning_rate)
  • 创建套索回归模型实例model
  • 使用随机梯度下降(SGD)优化器来优化模型参数。

8. 训练模型

for epoch in range(num_epochs):
    model.train()
    optimizer.zero_grad()
    y_pred = model(X_train_tensor)
    loss = model.loss_function(y_pred, y_train_tensor)
    loss.backward()
    optimizer.step()

    if epoch % 100 == 0:
        print(f'Epoch [{epoch}/{num_epochs}], Loss: {loss.item():.4f}')
  • 在训练循环中,每次迭代:
    • 将模型设置为训练模式。
    • 清除之前的梯度(optimizer.zero_grad())。
    • 进行前向传播计算预测值(y_pred)。
    • 计算损失值(loss)。
    • 进行反向传播以计算梯度(loss.backward())。
    • 更新模型参数(optimizer.step())。
  • 每100次迭代打印当前的损失值。

9. 进行预测

model.eval()
with torch.no_grad():
    y_test_pred = model(X_test_tensor)
  • 将模型设置为评估模式。
  • 使用torch.no_grad()上下文管理器,在推断阶段禁用梯度计算,以节省内存和提高速度。
  • 对测试集进行预测,得到预测结果y_test_pred

10. 可视化真实值与预测值

plt.scatter(y_test, y_test_pred.numpy())
plt.xlabel("真实值")
plt.ylabel("预测值")
plt.title("真实值与预测值的比较")
plt.plot([y.min(), y.max()], [y.min(), y.max()], '--', color='red')  # 对角线
plt.show()
  • 使用plt.scatter()绘制真实值y_test与预测值y_test_pred的散点图。
  • 设置X轴和Y轴的标签,以及图表标题。
  • 绘制一条红色的对角线(y=x),用于比较真实值与预测值之间的关系。
  • 使用plt.show()显示可视化结果。

11. 输出模型系数和截距

print("模型权重:", model.linear.weight.data.numpy())
print("模型偏置:", model.linear.bias.data.numpy())
  • 输出模型的权重(特征系数)和偏置(截距),以便分析模型的结果。

常见问题

  1. 如何选择合适的正则化参数 (\lambda)?

    • 通常使用交叉验证来选择合适的正则化参数。可以尝试多个值并选择在验证集上表现最佳的参数。
  2. 是否需要对特征进行标准化?

    • 是的,特征标准化非常重要,因为套索回归对特征的尺度非常敏感。通常在训练之前对特征进行标准化处理(例如,标准化为均值为0,方差为1的分布)。
  3. 在特征之间高度相关时如何处理?

    • 套索回归可能会随机选择相关特征中的一个,而忽略其他特征。如果特征高度相关,可以考虑使用岭回归或其他方法来处理。

总结

套索回归是一种强大的线性回归工具,通过L1正则化实现特征选择,有助于提高模型的可解释性和泛化能力。在高维数据集上,套索回归表现良好,但需要仔细选择正则化参数并进行特征标准化。通过 scikit-learnPyTorch,我们可以灵活地实现套索回归,以适应不同的需求和应用场景。

如果您还有其他问题或需要更深入的讨论,请随时告诉我!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Lucas在澳洲

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值