机器学习详解(3):线性回归之代码详解

news2025/1/16 0:42:06

文章目录

  • 1 数据预处理
  • 2 构建线性回归模型并绘制回归线
    • 初始化方法
    • 前向传播:forward_propagation
    • 代价函数:cost_function
    • 反向传播:backward_propagation
    • 参数更新:update_parameters
    • 训练方法:train
    • 代码运行结果
  • 3 使用Pytorch实现线性回归
  • 4 扩展:正则化
    • 4.1 正则化解释
    • 4.2 正则化实例
  • 5 总结

上一节中,我们介绍了 线性回归的原理,那么这篇文章就来用一个实际的例子来看一下如何用代码实现线性回归。

1 数据预处理

我们事先准备好了数据,保存在csv文件中,大致的数据结构如下,文件中有701行数据。
在这里插入图片描述

首先导入我们本节需要使用的库:

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.axes as ax
from matplotlib.animation import FuncAnimation

接下来读取文件、预处理,然后分割一下训练集和测试集。

(1)读取文件并删除空行

pd.read_csv用来读取csv文件,data.dropna() 删除 DataFrame 中包含缺失值的行。此操作会移除任何含有 NaN 或空值的记录。

csv_dir = '/content/drive/MyDrive/learning/data_for_lr.csv'
data = pd.read_csv(csv_dir)

# Drop the missing values
data = data.dropna()

(2)分割训练集和测试集

# training dataset and labels
train_input = np.array(data.x[0:500]).reshape(500, 1)
train_output = np.array(data.y[0:500]).reshape(500, 1)

# valid dataset and labels
test_input = np.array(data.x[500:700]).reshape(199, 1)
test_output = np.array(data.y[500:700]).reshape(199, 1)
  • data.xdata.y:使用 pd.read_csv(csv_dir) 读取 CSV 文件后,Pandas 会将 CSV 文件的每一列名称作为 DataFrame 中的列名,对应csv中的两列的列名xy
  • 为什么要转化为numpy格式?
    • data 是一个Pandas DataFrame对象,机器学习模型通常要求输入数据为 NumPy 数组,因为它提供高效的矩阵运算和更广泛的数学操作支持。此外,NumPy 与主流机器学习框架(如 Scikit-learn、TensorFlow)更兼容,性能优于 Pandas 数据结构。
  • 以训练集为例:
    • data.x[0:500] 表示取数据集中第 0 到 499 行的 x 列(假设 DataFrame 中有名为 x 的列)。
    • reshape(500, 1) 将一维数组调整为形状为 500 × 1 500 \times 1 500×1 的二维数组,便于与机器学习模型输入格式匹配。
      • 机器学习模型的输入通常是二维数组,形状为 ( n samples , n features ) (n_{\text{samples}}, n_{\text{features}}) (nsamples,nfeatures),表示 n samples n_{\text{samples}} nsamples 个样本,每个样本有 n features n_{\text{features}} nfeatures 个特征。
      • 这里的输入特征只有一个x,输出特征只有一个y,所以两个数组都reshape成 500 × 1 500 \times 1 500×1

2 构建线性回归模型并绘制回归线

步骤:

  1. 在前向传播中,应用线性回归函数 Y = m x + c Y = mx + c Y=mx+c,其中参数 m m m c c c 初始赋值为随机值。
  2. 然后编写一个函数用于计算损失函数,即均值。

现在我们打算实现一个LinearRegression类,即一个简单的线性回归模型,通过梯度下降进行参数优化,包括前向传播、代价函数计算、后向传播以及参数更新等关键步骤。

初始化方法

def __init__(self): 
    self.parameters = {} 
  • 初始化参数字典 self.parameters,即声明并初始化一个空字典,用于存储回归系数 m m m 和截距 c c c

前向传播:forward_propagation

前向传播是机器学习模型从输入数据经过模型参数(如权重和偏置)计算输出预测值的过程,例如线性回归中通过公式 y = m x + c y = mx + c y=mx+c 计算结果。它用于生成预测值,并为损失函数计算提供基础。

def forward_propagation(self, train_input): 
    m = self.parameters['m'] 
    c = self.parameters['c'] 
    predictions = np.multiply(m, train_input) + c 
    return predictions 
  • 通过公式 y = m x + c y = mx + c y=mx+c 计算预测值,训练输入为 t r a i n _ i n p u t train\_input train_input,输出为预测值 p r e d i c t i o n s predictions predictions

代价函数:cost_function

def cost_function(self, predictions, train_output): 
    cost = np.mean((train_output - predictions) ** 2) 
    return cost 
  • 使用均方误差(MSE)计算损失: C o s t = 1 n ∑ ( y a c t u a l − y p r e d i c t e d ) 2 Cost = \frac{1}{n} \sum (y_{actual} - y_{predicted})^2 Cost=n1(yactualypredicted)2
    • np.mean用于计算数组元素的平均值
  • 输入:预测值 p r e d i c t i o n s predictions predictions 和训练输出 t r a i n _ o u t p u t train\_output train_output
  • 输出:损失值 c o s t cost cost

反向传播:backward_propagation

def backward_propagation(self, train_input, train_output, predictions): 
    derivatives = {} 
    df = (predictions - train_output) 
    dm = 2 * np.mean(np.multiply(train_input, df)) 
    dc = 2 * np.mean(df) 
    derivatives['dm'] = dm 
    derivatives['dc'] = dc 
    return derivatives 
  • 计算梯度,在上一篇文章中我们计算了下面两个公式:
    • m m m 的梯度: ∂ C o s t ∂ m = 2 n ∑ ( y p r e d i c t e d − y a c t u a l ) ⋅ x i n p u t \frac{\partial Cost}{\partial m} = \frac{2}{n} \sum (y_{predicted} - y_{actual}) \cdot x_{input} mCost=n2(ypredictedyactual)xinput
    • c c c 的梯度: ∂ C o s t ∂ c = 2 n ∑ ( y p r e d i c t e d − y a c t u a l ) \frac{\partial Cost}{\partial c} = \frac{2}{n} \sum (y_{predicted} - y_{actual}) cCost=n2(ypredictedyactual)
  • 输入:训练输入 t r a i n _ i n p u t train\_input train_input,训练输出 t r a i n _ o u t p u t train\_output train_output,预测值 p r e d i c t i o n s predictions predictions
  • 输出:包含梯度 d m dm dm d c dc dc 的字典。

参数更新:update_parameters

def update_parameters(self, derivatives, learning_rate): 
    self.parameters['m'] = self.parameters['m'] - learning_rate * derivatives['dm'] 
    self.parameters['c'] = self.parameters['c'] - learning_rate * derivatives['dc'] 
  • 使用梯度下降法更新参数,在上一篇文章中我们提到要使用下面的公式来更新参数:
    • m = m − α ⋅ ∂ C o s t ∂ m m = m - \alpha \cdot \frac{\partial Cost}{\partial m} m=mαmCost
    • c = c − α ⋅ ∂ C o s t ∂ c c = c - \alpha \cdot \frac{\partial Cost}{\partial c} c=cαcCost
  • 输入:梯度字典 d e r i v a t i v e s derivatives derivatives 和学习率 l e a r n i n g _ r a t e learning\_rate learning_rate

训练方法:train

完整代码如下:

def train(self, train_input, train_output, learning_rate, iters): 
    # Initialize random parameters 
    self.parameters['m'] = np.random.uniform(0, 1) * -1
    self.parameters['c'] = np.random.uniform(0, 1) * -1

    # Initialize loss 
    self.loss = [] 

    # Initialize figure and axis for animation 
    fig, ax = plt.subplots() 
    x_vals = np.linspace(min(train_input), max(train_input), 100) 
    line, = ax.plot(x_vals, self.parameters['m'] * x_vals +
                    self.parameters['c'], color='red', label='Regression Line') 
    ax.scatter(train_input, train_output, marker='o', 
               color='green', label='Training Data') 

    # Set y-axis limits to exclude negative values 
    ax.set_ylim(0, max(train_output) + 1) 

    def update(frame): 
        # Forward propagation 
        predictions = self.forward_propagation(train_input) 

        # Cost function 
        cost = self.cost_function(predictions, train_output) 

        # Back propagation 
        derivatives = self.backward_propagation( 
            train_input, train_output, predictions) 

        # Update parameters 
        self.update_parameters(derivatives, learning_rate) 

        # Update the regression line 
        line.set_ydata(self.parameters['m'] 
                       * x_vals + self.parameters['c']) 

        # Append loss and print 
        self.loss.append(cost) 
        print("Iteration = {}, Loss = {}".format(frame + 1, cost)) 

        return line, 
    # Create animation 
    ani = FuncAnimation(fig, update, frames=iters, interval=200, blit=True) 

    # Save the animation as a video file (e.g., MP4) 
    ani.save('linear_regression_A.gif', writer='ffmpeg') 

    plt.xlabel('Input') 
    plt.ylabel('Output') 
    plt.title('Linear Regression') 
    plt.legend() 
    plt.show() 

    return self.parameters, self.loss

这个训练的函数代码比较长,我们分三部分来讲解:

(1)初始化随机参数和绘制动画的初始设置

# Initialize random parameters 
self.parameters['m'] = np.random.uniform(0, 1) * -1
self.parameters['c'] = np.random.uniform(0, 1) * -1

# Initialize loss 
self.loss = [] 

# Initialize figure and axis for animation 
fig, ax = plt.subplots() 
x_vals = np.linspace(min(train_input), max(train_input), 100) 
line, = ax.plot(x_vals, self.parameters['m'] * x_vals +
self.parameters['c'], color='red', label='Regression Line') 
ax.scatter(train_input, train_output, marker='o', 
color='green', label='Training Data') 

# Set y-axis limits to exclude negative values 
ax.set_ylim(0, max(train_output) + 1) 
  • 初始化随机参数 m m m c c c 分别是线性回归模型的斜率和截距,使用随机负值初始化

  • 初始化损失列表self.loss = [],用于记录每次迭代的损失值。

  • 创建动画图像的坐标轴

    • 使用 plt.subplots() 初始化图形。
    • 使用 np.linspace 在训练数据范围内生成100个等间距的 x x x 值。
    • 用回归线 line 和散点图 scatter 绘制初始数据分布和回归线。
      • 这两个函数不做深入解释了,主要是用动画显示一下结果
  • 设置 y y y 轴范围ax.set_ylim(0, max(train_output) + 1),避免负值干扰图形。


(2)定义动画更新逻辑

def update(frame): 
    # Forward propagation 
    predictions = self.forward_propagation(train_input) 

    # Cost function 
    cost = self.cost_function(predictions, train_output) 

    # Back propagation 
    derivatives = self.backward_propagation( 
    train_input, train_output, predictions) 

    # Update parameters 
    self.update_parameters(derivatives, learning_rate) 

    # Update the regression line 
    line.set_ydata(self.parameters['m'] 
    * x_vals + self.parameters['c']) 

    # Append loss and print 
    self.loss.append(cost) 
    print("Iteration = {}, Loss = {}".format(frame + 1, cost)) 

    return line, 
  • 前向传播:调用 self.forward_propagation(train_input) 计算预测值

  • 计算损失:调用 self.cost_function(predictions, train_output),基于均方误差(MSE)计算损失

  • 反向传播:调用 self.backward_propagation 计算梯度

  • 参数更新:使用学习率 α \alpha α 和反向传播计算出来的梯度更新参数

  • 更新回归线:根据新的 m m m c c c 重新绘制回归线。

  • 记录损失并打印:将当前迭代的损失追加到 self.loss 中,并打印当前迭代信息。


(2)创建动画、保存和显示图像

# Create animation 
ani = FuncAnimation(fig, update, frames=iters, interval=200, blit=True) 

# Save the animation as a video file (e.g., MP4) 
ani.save('linear_regression_A.gif', writer='ffmpeg') 

plt.xlabel('Input') 
plt.ylabel('Output') 
plt.title('Linear Regression') 
plt.legend() 
plt.show() 

return self.parameters, self.loss
  • 创建动画:调用 FuncAnimation 动态展示每次迭代后模型的变化,update 函数在 FuncAnimation 中由 frames=iters 控制,总共被调用 iters 次,每帧调用一次,间隔由 interval=200 毫秒决定。

  • 保存动画:将训练过程保存为 GIF 文件,便于分析。

  • 显示图像:绘制最终的回归线和训练数据分布。

  • 返回结果:最终返回优化后的参数和记录的损失值。

代码运行结果

#Example usage
linear_reg = LinearRegression()
parameters, loss = linear_reg.train(train_input, train_output, 0.0001, 20)

输出:

Iteration = 1, Loss = 4380.455128289033
Iteration = 1, Loss = 534.7906518669206
Iteration = 1, Loss = 71.34622937840669
Iteration = 1, Loss = 15.49613095399081
Iteration = 2, Loss = 8.765584291635278
Iteration = 3, Loss = 7.9544781683945
Iteration = 4, Loss = 7.856729049602253
Iteration = 5, Loss = 7.844947213272631
Iteration = 6, Loss = 7.843525370234688
Iteration = 7, Loss = 7.843352019334563
Iteration = 8, Loss = 7.8433291255257975
Iteration = 9, Loss = 7.843324363635718
Iteration = 10, Loss = 7.843321787040954
Iteration = 11, Loss = 7.843319473999822
Iteration = 12, Loss = 7.843317192921515
Iteration = 13, Loss = 7.843314915896804
Iteration = 14, Loss = 7.843312639562301
Iteration = 15, Loss = 7.843310363512657
Iteration = 16, Loss = 7.843308087699013
Iteration = 17, Loss = 7.843305812115446
Iteration = 18, Loss = 7.8433035367612325
Iteration = 19, Loss = 7.843301261636267
Iteration = 20, Loss = 7.843298986740505

结果图如下,红色曲线为我们最终的回归曲线:

在这里插入图片描述

  • 在本地自己运行上述代码,可以看到曲线红色曲线随着梯度下降更新参数的过程。

线性回归线提供了两个变量之间关系的最佳拟合线,捕获因变量 Y Y Y 随自变量 X X X 变化的总体趋势。

3 使用Pytorch实现线性回归

现在已经有许多优秀的机器学习库,如TensorFlow、Scikit-learn等,它们都能帮助我们快速实现线性回归等模型。本文选择PyTorch作为例子,展示如何更简洁地完成建模与训练,同时体验其灵活性与强大的自动微分功能。下面还是基于刚刚编写的代码,我们来看一下做得一些改动:

(1)库引入

import torch
from torch import nn
  • torch 是 PyTorch 的核心库,提供了张量操作和基本数学计算功能,类似于 NumPy 的作用,但支持自动求导和 GPU 加速。

  • torch.nn 是 PyTorch 中构建神经网络的核心模块,提供了实现深度学习模型所需的基本构件。

(2)数据处理

数据要转化为PyTorch的张量形式:

train_input = torch.tensor(data.x[0:500].values, dtype=torch.float32).view(-1, 1)
train_output = torch.tensor(data.y[0:500].values, dtype=torch.float32).view(-1, 1)

test_input = torch.tensor(data.x[500:700].values, dtype=torch.float32).view(-1, 1)
test_output = torch.tensor(data.y[500:700].values, dtype=torch.float32).view(-1, 1)
  • view(-1, 1)-1 表示根据剩余维度自动计算大小,1 表示将数据重新组织为一列(每个特征在单独的一列中)。

(3)线性回归类

class LinearRegression(nn.Module):
    def __init__(self):
    	# 调用 nn.Module 的 __init__ 方法,初始化父类的属性和功能
        super(LinearRegression, self).__init__()
        # 定义线性层,输入为1,输出为1
        self.linear = nn.Linear(1, 1)
	
	# 前向传播,等价于前面我们写的forward_propagation
    def forward(self, x):
        return self.linear(x)

    def train_model(self, train_input, train_output, learning_rate, iters):
        # 定义损失函数
        criterion = nn.MSELoss()
        # 定义优化器
        optimizer = torch.optim.SGD(self.parameters(), lr=learning_rate)

        # 初始化损失列表
        self.loss = []

        # 初始化图像和动画
        fig, ax = plt.subplots()
        x_vals = torch.linspace(train_input.min(), train_input.max(), 100).view(-1, 1)
        line, = ax.plot(x_vals.numpy(), self.forward(x_vals).detach().numpy(),
                        color='red', label='Regression Line')
        ax.scatter(train_input.numpy(), train_output.numpy(), marker='o',
                   color='green', label='Training Data')
        ax.set_ylim(0, train_output.max().item() + 1)

        def update(frame):
            # 前向传播
            predictions = self.forward(train_input)

            # 计算损失
            loss = criterion(predictions, train_output)

            # 反向传播
            optimizer.zero_grad()
            loss.backward()

            # 更新参数
            optimizer.step()

            # 更新回归线
            line.set_ydata(self.forward(x_vals).detach().numpy())

            # 记录损失
            self.loss.append(loss.item())
            print(f"Iteration = {frame + 1}, Loss = {loss.item()}")

            return line,

        # 创建动画
        ani = FuncAnimation(fig, update, frames=iters, interval=200, blit=True)

        # 保存动画
        ani.save('linear_regression_pytorch.gif', writer='ffmpeg')

        # 显示图像
        plt.xlabel('Input')
        plt.ylabel('Output')
        plt.title('Linear Regression')
        plt.legend()
        plt.show()

        return self.linear.weight.data, self.linear.bias.data, self.loss
  • nn.Module 是 PyTorch 中所有神经网络模型的基类。它为神经网络模型的构建和使用提供了一套通用框架。这里让LinearRegression类继承这个父类
  • nn.Linear(1, 1):定义一个输入维度为 1,输出维度为 1 的线性层
    • 参数存储在 self.linear.weightself.linear.bias 中,可以通过 model.parameters() 访问
改动自己实现Pytorch
前向传播def forward_propagation(self, train_input):
m = self.parameters[‘m’]
c = self.parameters[‘c’]
predictions = np.multiply(m, train_input) + c
return predictions
def forward(self, x):
return self.linear(x)
损失函数def cost_function(self, predictions, train_output):
cost = np.mean((train_output - predictions) ** 2)
return cost
criterion = nn.MSELoss()
反向传播def update_parameters(self, derivatives, learning_rate):
self.parameters[‘m’] = self.parameters[‘m’] - learning_rate * derivatives[‘dm’]
self.parameters[‘c’] = self.parameters[‘c’] - learning_rate * derivatives[‘dc’]
optimizer = torch.optim.SGD(self.parameters(), lr=learning_rate)
PyTorch张量
vs
Numpy
x_vals = torch.linspace(train_input.min(), train_input.max(), 100).view(-1, 1)
line, = ax.plot(x_vals.numpy(), self.forward(x_vals).detach().numpy(),
color=‘red’, label=‘Regression Line’)
ax.scatter(train_input.numpy(), train_output.numpy(), marker=‘o’,
color=‘green’, label=‘Training Data’)
ax.set_ylim(0, train_output.max().item() + 1)
x_vals = np.linspace(min(train_input), max(train_input), 100)
line, = ax.plot(x_vals, self.parameters[‘m’] * x_vals +
self.parameters[‘c’], color=‘red’, label=‘Regression Line’)
ax.scatter(train_input, train_output, marker=‘o’,
color=‘green’, label=‘Training Data’)

# Set y-axis limits to exclude negative values
ax.set_ylim(0, max(train_output) + 1)
  • 在PyTorch中,上面的update中就是用库中定义的前向传播、损失函数和反向传播函数了,就不放在表格中对比了。

最后我们运行一下这段代码:

# 使用示例
linear_reg = LinearRegression()
parameters, bias, loss = linear_reg.train_model(train_input, train_output, 0.0001, 20)

效果是和我们自己实现的差不多的。

  • 由于PyTorch包含整个神经网络的功能,所以这里遇到的PyTorch中预定义的不同的优化器和损失函数,在后续学完所有的机器学习方法后再一起介绍,现在仅了解一下就好。

4 扩展:正则化

4.1 正则化解释

在机器学习和回归模型中,正则化是一种通过在目标函数中添加惩罚项来提高模型泛化能力的技术。主要目的是解决以下两个常见问题:

  1. 过拟合 (Overfitting)
    当模型过于复杂,参数过多时,模型可能会记住训练数据中的噪声,从而导致在新数据上的表现变差。

    • 过拟合的迹象包括训练集上误差很低,但测试集误差很高。
    • 正则化通过惩罚大幅度的参数值,限制模型复杂度,从而减少过拟合的风险。
  2. 多重共线性 (Multicollinearity)
    在回归模型中,如果自变量之间高度相关,可能会导致系数的不稳定性。

    • 正则化可以通过增加惩罚项,使得模型更加鲁棒,从而缓解多重共线性问题。

什么情况下需要正则化

  1. 数据量少但特征多时,模型容易过拟合。
  2. 训练误差和测试误差之间的差异很大时,可能存在过拟合问题。
  3. 存在多重共线性(自变量高度相关)的情况下,系数可能会变得不稳定,需要通过正则化来约束系数。
  4. 希望对模型进行特征选择时,正则化(如 L 1 L1 L1)可以自动选择重要特征,将无关特征的系数压缩为零。

正则化的主要方法

(1)Lasso 回归 (L1 正则化)
Lasso 回归通过在线性回归目标函数中添加惩罚项来防止过拟合。

应用 Lasso 回归后的目标函数为:
J ( θ ) = 1 2 m ∑ i = 1 m ( y ^ i − y i ) 2 + λ ∑ j = 1 n ∣ θ j ∣ J(\theta) = \frac{1}{2m} \sum_{i=1}^m (\hat{y}_i - y_i)^2 + \lambda \sum_{j=1}^n | \theta_j | J(θ)=2m1i=1m(y^iyi)2+λj=1nθj

  • 第一项表示最小二乘误差 (预测值和实际值之间平方差)。
  • 第二项是 L 1 L1 L1 正则化项,惩罚回归系数的绝对值之和。
  • 优点:Lasso 可以将一些系数缩减为零,从而实现特征选择。
  • 缺点:对于特征数大于样本数时,Lasso 的表现可能不稳定。

(2)Ridge 回归 (L2 正则化)
Ridge 回归通过向目标函数添加正则化项来防止过拟合,尤其适用于高多重共线性的数据集。

应用 Ridge 回归后的目标函数为:
J ( θ ) = 1 2 m ∑ i = 1 m ( y ^ i − y i ) 2 + λ ∑ j = 1 n θ j 2 J(\theta) = \frac{1}{2m} \sum_{i=1}^m (\hat{y}_i - y_i)^2 + \lambda \sum_{j=1}^n \theta_j^2 J(θ)=2m1i=1m(y^iyi)2+λj=1nθj2

  • 第一项表示最小二乘误差。
  • 第二项惩罚回归系数平方值之和。
  • 优点:Ridge 能够很好地处理多重共线性问题,使模型更加稳定。
  • 缺点:Ridge 不能将系数压缩到零,无法进行特征选择。

(3)Elastic Net 回归
Elastic Net 回归结合了 L 1 L1 L1 L 2 L2 L2 正则化的优点。

目标函数为:
J ( θ ) = 1 2 m ∑ i = 1 m ( y ^ i − y i ) 2 + α λ ∑ j = 1 n ∣ θ j ∣ + ( 1 − α ) 2 λ ∑ j = 1 n θ j 2 J(\theta) = \frac{1}{2m} \sum_{i=1}^m (\hat{y}_i - y_i)^2 + \alpha \lambda \sum_{j=1}^n |\theta_j| + \frac{(1 - \alpha)}{2} \lambda \sum_{j=1}^n \theta_j^2 J(θ)=2m1i=1m(y^iyi)2+αλj=1nθj+2(1α)λj=1nθj2

  • 第一项是最小二乘误差。
  • 第二项是 L 1 L1 L1 正则化,第三项是 Ridge 回归。
  • λ \lambda λ 控制整体正则化强度。
  • α \alpha α 控制 L 1 L1 L1 L 2 L2 L2 正则化的混合比例。
  • 优点:适用于高维数据和特征数量远大于样本数量的场景,综合了 Lasso 和 Ridge 的优势。

总结
正则化是解决机器学习中过拟合和多重共线性问题的重要方法。在模型复杂或数据稀疏的情况下,正则化不仅能提升模型的泛化能力,还能实现特征选择。根据具体需求,可以选择 Lasso、Ridge 或 Elastic Net。

4.2 正则化实例

我们以一个简单的数据集为例,模拟房价预测:

房屋面积位置评分噪音等级装修评分价格
1000847300,000
1200956350,000
850738280,000
1300957370,000
900746290,000
  • 特征:房屋面积、位置评分、噪音等级、装修评分。
  • 目标:价格。

正则化前后的对比

(1)正则化之前

  • 使用普通的线性回归训练模型。
  • 现象:
    • 模型可能为每个特征赋予较大的权重。
    • 噪音等级(对房价的影响较小)也可能被分配较大的系数,增加模型复杂度。
    • 训练集的误差很小,但在测试集上表现差(过拟合)。
特征权重(未正则化)
房屋面积:100
位置评分:50
噪音等级:30
装修评分:20

(2)正则化之后

  • 使用 Lasso 正则化 来限制不重要特征的影响。
  • 现象
    • 噪音等级的系数被压缩为 0(表示对价格预测影响很小)。
    • 保留对价格有显著影响的特征,如房屋面积和位置评分。
    • 模型更加简单,泛化能力更强,在测试集上表现更好。
特征权重(Lasso 正则化后)
房屋面积:90
位置评分:40
噪音等级:0
装修评分:15

正则化总结

  • 未正则化时:所有特征都会被赋予权重,容易导致模型复杂且过拟合。
  • 正则化后:通过缩减或移除不重要的特征,提高模型的简洁性和泛化能力。

5 总结

线性回归广泛应用于金融、经济学、心理学等领域,以理解和预测变量行为。例如,在金融领域,线性回归可用于研究公司股票价格与收益之间的关系,或根据过去的表现预测未来的货币价值。 优点与缺点如下:

优点

  • 简单易懂,易于实现,系数具有可解释性。
  • 计算效率高,适合处理大数据集,非常适合实时应用。
  • 与其他算法相比,对异常值较为鲁棒。
  • 常作为更复杂模型的基线模型。
  • 历史悠久,广泛应用于各种机器学习库。

缺点

  • 假设因变量与自变量之间是线性关系,若该假设不成立,模型表现可能较差。
  • 对多重共线性敏感,可能导致系数方差膨胀和预测不稳定。
  • 需要对特征进行预处理,确保输入数据适合模型使用。
  • 容易发生过拟合或欠拟合。过拟合时,模型学习训练数据过好,无法泛化到新数据;欠拟合时,模型过于简单,无法捕获数据的潜在关系。
  • 对于复杂变量关系,解释能力有限。

结论
线性回归是一种基础的机器学习算法,因其简单性、可解释性和高效性而备受推崇。它对于理解变量关系和进行预测非常有用。然而,其线性假设和对多重共线性的敏感性在使用时需要注意。如果这些限制条件被充分考虑,线性回归可以成为数据分析和预测的强大工具。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2256512.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

基于openzeppelin插件的智能合约升级

一、作用以及优点 部署可升级合约,插件自动部署proxy和proxyAdmin合约,帮助管理合约升级和交互;升级已部署合约,通过插件快速升级合约,脚本开发方便快捷;管理代理管理员的权限,只有proxyAdmin的…

游戏引擎学习第36天

仓库 :https://gitee.com/mrxiao_com/2d_game 回顾之前的内容 在这个程序中,目标是通过手动编写代码来从头开始制作一个完整的游戏。整个过程不使用任何库或现成的游戏引擎,这样做的目的是为了能够全面了解游戏执行的每一个细节。开发过程中&#xff0…

试题转excel;pdf转excel;试卷转Excel,word试题转excel

一、问题描述 一名教师朋友,偶尔会需要整理一些高质量的题目到excel中 以往都是手动复制搬运,几百道题几乎需要一个下午的时间 关键这些事,枯燥无聊费眼睛,实在是看起来就很蠢的工作 就想着做一个工具,可以自动处理…

16-01、JVM系列之:内存与垃圾回收篇(一)

JVM系列之:内存与垃圾回收篇(一) ##本篇内容概述: 1、JVM结构 2、类加载子系统 3、运行时数据区之:PC寄存器、Java栈、本地方法栈一、JVM与JAVA体系结构 JAVA虚拟机与JAVA语言并没有必然的联系,它只是与特…

2030. gitLab A仓同步到B仓

文章目录 1 A 仓库备份 到 B 仓库2 B 仓库修改main分支的权限 1 A 仓库备份 到 B 仓库 #!/bin/bash# 定义变量 REPO_DIR"/home/xhome/opt/git_sync/zz_xx_xx" # 替换为你的本地库A的实际路径 REMOTE_ORIGIN"http://192.168.1.66:8181/zzkj_software/zz_xx_xx.…

服务器上部署前端页面-实现IP+端口/index.html在线访问你的网页

首先一点,不管是那个框架开发的网页前端,最后都需要Build,构建完毕以后都是原始的HTML CSS JS 三样文件! 所以不管用原始的三剑客(HTML CSS JS)开发的前端还是用各类框架开发的前端界面(只是让开发简单…

树莓派 PICO RP2040 MACOS 使用

文章参考: Developing in C on the RP2040: macOS | Wellys Dev 这里会提示报错:ln: /bin/picotool: Operation not permitted 参考:Mac ln命令报错:Operation not permitted_ln operation not permitted-CSDN博客 放在 usr/lo…

顶顶通电话机器人开发接口对接大语言模型之实时流TTS对接介绍

大语言模型一般都是流式返回文字,如果等全部文字返回了一次性去TTS,那么延迟会非常严重,常用的方法就是通过标点符号断句,返回了一句话就提交给TTS。随着流TTS的出现,就可以直接把大模型返回的文字灌给流TTS&#xff0…

git使用-创建本地仓库、绑定远程仓库

文章目录 1. 创建git仓库2. commit提交到本地3. 创建远程仓库4. 关联远程仓库5. push代码至远程仓库6. 完成初始化 git作为版本控制工具,在开发过程中经常使用到。这里以github为例,简单介绍下仓库的创建及绑定,方便忘记了能快速的想起来。 1…

JavaScript 中通过Array.sort() 实现多字段排序、排序稳定性、随机排序洗牌算法、优化排序性能,JS中排序算法的使用详解(附实际应用代码)

目录 JavaScript 中通过Array.sort() 实现多字段排序、排序稳定性、随机排序洗牌算法、优化排序性能,JS中排序算法的使用详解(附实际应用代码) 一、为什么要使用Array.sort() 二、Array.sort() 的使用与技巧 1、基础语法 2、返回值 3、…

为什么Unity里的变体数和UWA工具测出来的不一样

1)为什么Unity里的变体数和UWA工具测出来的不一样 2)使用TextureArray为什么会导致L1 Cache Miss率变高 3)Gfx.PresentFrame耗时异常高 4)AO方案中哪个更适合移动端 这是第412篇UWA技术知识分享的推送,精选了UWA社区的…

汽车免拆案例 | 2007款宝马650i车发动机偶尔无法起动

故障现象 一辆2007款宝马650i车,搭载N62B48B发动机,累计行驶里程约为26万km。车主反映,发动机偶尔无法起动,故障频率较低,十几天出现1 次,且故障出现时起动机不工作。 故障诊断  接车后试车,…

DataEase 是开源的 BI 工具

DataEase 是开源的 BI 工具,帮助用户快速分析数据并洞察业务趋势,从而实现业务的改进与优化。DataEase 支持丰富的数据源连接,能够通过拖拉拽方式快速制作图表, DataEase 的优势: 开源开放:零门槛&#xf…

【C#设计模式(17)——迭代器模式(Iterator Pattern)】

前言 迭代器模式可以使用统一的接口来遍历不同类型的集合对象,而不需要关心其内部的具体实现。 代码 //迭代器接口 public interface Iterator {bool HashNext();object Next(); } //集合接口 public interface Collection {Iterator CreateIterator(); } //元素迭…

在LabVIEW中如何利用FPGA提升算法性能

在LabVIEW中利用FPGA的性能进行算法开发,能极大提升数据处理和实时计算的速度。LabVIEW提供了针对FPGA的开发工具,如LabVIEW FPGA Module,可以使开发者将算法部署到FPGA硬件上,从而实现并行计算和低延迟操作。以下是如何在LabVIEW…

Day7 苍穹外卖项目 缓存菜品、SpringCache框架、缓存套餐、添加购物车、查看购物车、清空购物车

目录 1.缓存菜品 1.1 问题说明 1.2 实现思路 1.3 代码开发 1.3.1 加入缓存 1.3.2 清除缓存 1.3.2.1 新增菜品优化 1.3.2.2 菜品批量删除优化 1.3.2.3 修改菜品优化 1.3.2.4 菜品起售停售优化 1.4 功能测试 1.4.1 加入缓存 1.4.2 菜品修改 1.5 代码提交 2.缓存套餐 2.1 Spring C…

HCIA-openGauss_2_2连接与认证

设置客户端认证策略 设置配置文件参数 gssql客户端连接-确定连接信息 客户端工具通过数据库主节点连接数据库,因此连接前,需要获取数据库主节点的在服务器的IP地址及数据库主节点的端口号信息。 步骤1:以操作系统用户omm登录数据库主节点。…

上海理工大学《2024年867自动控制原理真题》 (完整版)

本文内容,全部选自自动化考研联盟的:《上海理工大学867自控考研资料》的真题篇。后续会持续更新更多学校,更多年份的真题,记得关注哦~ 目录 2024年真题 Part1:2024年完整版真题 2024年真题

SpringMVC纯注解快速开发

此文章适合具有一定的java基础的同学看哦,如果有看不懂的基本代码还是先补补java基础哦。 此教程带您不使用xml文件而是纯注解开发,易懂、快捷、迅速,从0开始搭建,很快就能构建起一个SpringMVC项目,能学到两种使用tom…

Linux-音频应用编程

ALPHA I.MX6U 开发板支持音频,板上搭载了音频编解码芯片 WM8960,支持播放以及录音功能!本章我们来学习 Linux 下的音频应用编程,音频应用编程相比于前面几个章节所介绍的内容、其难度有所上升,但是笔者仅向大家介绍 Li…