首页 > 其他分享 >线性回归超详解

线性回归超详解

时间:2025-01-15 23:31:03浏览次数:3  
标签:train 回归 list test 详解 theta 线性 np data

目录

一、回归问题 vs 分类问题

二、线性回归

1、一句话理解

2、数学推导

2.1 线性函数表示 

 2.2 损失函数

2.3 梯度下降

2.3.1 什么是梯度

2.3.2 梯度下降目标

 2.3.3 过程

2.3.4 迭代公式

3、特征预处理

3.1 为什么要预处理

3.2 数据归一化方法

1)最小-最大归一化

2)Z-Score 归一化

4、正则化 

4.1 为什么要正则化

4.2 L1 正则化

4.3 L2 正则化

5、回归问题的评估指标

均方误差

均方根误差

平均绝对误差

R 平方

三、代码实现

1、手动实现线性回归

2、使用sklearn库实现


一、回归问题 vs 分类问题

  • 监督学习(Supervised Learning): 样本数据带有标签值, 它从训练样本中学习得到一个模型, 然后用这个模型对新的样本进行预测推断。
  • 无监督学习(Unsupervised Learning): 对没有标签得数据进行分析, 发现样本集的结构或者分布规律。 比如数据降维, 我们会在后面的学习中介绍数据降维算法。
  • 分类问题: 如果样本的标签是整数, 则预测函数是一个向量到整数的映射。我们前面讲的判断水果是猕猴桃还是樱桃的问题就是分类问题。
  • 回归问题: 如果样本的标签是连续实数, 则预测函数是向量到实数的映射 

二、线性回归

1、一句话理解

线性回归是通过拟合一条直线函数(在多维空间中是超平面),来建立自变量和因变量之间线性关系的统计模型,以预测或解释因变量的变化。如下所示。

2、数学推导

以波士顿房价预测为例

输入X有两个特征,分别是房屋面积和卧室数量,输出为房屋价格

2.1 线性函数表示 

直线函数表示为:h(x) = \Theta _0+\Theta _1x_1+\Theta _2x_2 ,简化为h(x) = \sum_{i=0}^{d} \theta_i x_i

  • x_1表示房屋的面积,
  • x_2表示房屋的卧室数量,
  • x = \begin{bmatrix} x_0 \\ x_1 \\ x_2 \end{bmatrix}x_0=1
  • \Theta _i是线性函数的参数
  • \theta = \begin{bmatrix} \theta_0 \\ \theta_1 \\ \theta_2 \end{bmatrix}
  • d表示输入特征的数量

目的是找到合适的 \Theta使给定输入向量 x, 让 h(x)能够等于或者说接近目标值(标签) y。

 2.2 损失函数

作用:用于衡量预测结果与真实结果之间的误差, 它在训练过程中的作用是优化参数; 在预测阶段的作用是衡量模型的性能。

使用均方误差损失函数:

J(\theta) = \frac{1}{2n} \sum_{i=0}^{n} \left( h_{\theta}(x^{(i)}) - y^{(i)} \right)^2   i表示第i个样本

tips:这里有除以2操作,在2.3.4中会说到其作用

2.3 梯度下降

2.3.1 什么是梯度

梯度是导数对多元函数的推广,它是多元函数对每一个自变量偏导数形成的向量。梯度定义为:\nabla f(x) = \left[ \frac{\partial f}{\partial x_1}, \frac{\partial f}{\partial x_2}, \ldots, \frac{\partial f}{\partial x_n} \right]^T

梯度是向量, 因此是有方向的。 梯度的方向是函数值增长最快的方向

梯度下降法是沿着梯度向量的反方向进行迭代以达到函数的极值点。

2.3.2 梯度下降目标

我们的目标是最小化损失函数,即minimizeJ(\theta),当损失函数最小时,\Theta效果最好。使用梯度下降法来最小化损失函数从而计算参数\Theta

 2.3.3 过程

参数用 w 表示, 首先为参数 w 选择一个初始值, 然后不断改变 w的值, 使 J(w)减小。

2.3.4 迭代公式

x_{k+1} = x_k - \gamma \nabla f(x_k)

根据上述公式,知参数\Theta更新过程为:\theta \leftarrow \theta - \alpha \nabla J(\theta)

\alpha在机器学习中称为学习率, 学习率越大参数更新的速度越快, 模型训练的速度就越快, 但有可能导致模型不稳定或者训练效果不好; 学习率越小参数更新的速度越慢, 导致训练的时间过长, 所以在实际训练过程中应该选择合适的学习率。

参数 \Theta的每一个分量 \Theta_j更新方式表示为如下:

\theta_j \leftarrow \theta_j - \alpha \frac{\partial}{\partial \theta_j} J(\theta)

其中

\frac{\partial}{\partial \theta_j} J(\theta) = \frac{1}{2} \frac{\partial}{\partial \theta_j} (h_\theta(x) - y)^2 = (h_\theta(x) - y) \cdot \frac{\partial}{\partial \theta_j} (h_\theta(x) - y) = (h_\theta(x) - y) \cdot \frac{\partial}{\partial \theta_j} \left( \sum_{i=0}^{d} \theta_i x_i - y \right) = (h_\theta(x) - y) \cdot x_j
从这里可以看出除以2的目的是消除求导过程中产生的数字2,简化计算

\Theta_j更新方式可以简化成:

\theta_j \leftarrow \theta_j - \alpha \left( h_\theta(x^{(i)}) - y^{(i)} \right) x_j^{(i)},这里(i)表示第 i 个训练样本

代码如下:

def gradient_descent(X, y, theta, l, alpha, epoch):
    cost = np.zeros(epoch)  # 初始化一个ndarray,包含每次epoch的cost
    m = X.shape[0]  # 样本数量m
    for i in range(epoch):
        # 利用向量化一步求解
        theta = theta - (alpha / m) * (X * theta.T - y).T * X - (alpha * l / m) * theta  # 添加了正则项
        cost[i] = regularized_loss(X, y, theta, l)  # 记录每次迭代后的代价函数值
    return theta, cost

3、特征预处理

3.1 为什么要预处理

如果特征向量各分量的取值范围相差很大, 会影响算法的精度与训练时的收敛, 在计算时也可能会导致浮点数的溢出。例如h(x) = \Theta _0+\Theta _1x_1+\Theta _2x_2x_1取值在0.1~0.01、x_2取值在1000~2000,那么x_1效果会被x_2掩盖。

3.2 数据归一化方法

1)最小-最大归一化
 

2)Z-Score 归一化

基于数据的均值和标准差进行归一化
 

代码如下:

# 载入数据集
def loadData(filepath):
    """
    :param filepath: csv
    :return: X, y
    """
    data_list = pd.read_csv(filepath)
    # 使用Z-score对数据进行归一化处理
    data_list = (data_list - data_list.mean()) / data_list.std()
    return data_list

4、正则化 

4.1 为什么要正则化

为了防止过拟合, 可以为损失函数加上一个惩罚项, 对复杂的模型进行惩罚,从而降低模型的复杂度。

4.2 L1 正则化

通过向损失函数添加一个与权重向量的 L1 范数成正比的惩罚项来实现。

Loss\_Regularization = Loss(y, y\_pred) + \lambda \|\theta\|_1\lambda为惩罚系数, 是人工设定的大于 0 的数。

L1 范数表示所有分量的绝对值之和,如下:

4.3 L2 正则化

通过向损失函数添加一个与权重向量的 L2 范数成正比的惩罚项来实现。

Loss\_Regularization = Loss(y, y\_pred) + \lambda \|\theta\|_2\lambda为惩罚系数, 是人工设定的大于 0 的数。

L2 范数表示向量模长,如下: 

在实际使用时根号可以不适用以简化计算

代码如下:

# 定义损失函数
def loss_function(X, y, theta):
    inner = np.power(X * theta.T - y, 2)
    return np.sum(inner)/(2*len(X))

# 定义正则化代价函数,防止过拟合
def regularized_loss(X, y, theta, l):
    reg = (l / (2 * len(X))) * (np.power(theta[1:], 2).sum())
    return loss_function(X, y, theta) + reg

代码正则化项中也使用了除以2操作,作用同上 

5、回归问题的评估指标

均方误差

均方根误差

平均绝对误差

R 平方

用于衡量回归模型对测试数据的拟合程度, 其取值范围在 0~1 之间, 越接近 1 表示模型拟合得越好





 

三、代码实现

1、手动实现线性回归

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt

# 载入数据集
def loadData(filepath):
    """
    :param filepath: csv
    :return: X, y
    """
    data_list = pd.read_csv(filepath)
    # 使用Z-score对数据进行归一化处理
    data_list = (data_list - data_list.mean()) / data_list.std()
    return data_list


# 划分训练集与测试集
def splitData(data_list, ratio):
    train_size = int(len(data_list) * ratio)
    # 生成一个随机排列的整数数组
    random_indices = np.random.permutation(len(data_list))
    # 使用随机排列的索引列表重新设定 DataFrame 的行顺序
    data_list = data_list.iloc[random_indices]
    trainset = data_list[:train_size]
    testset = data_list[train_size:]
    X_train = trainset.drop("MEDV", axis=1) #去除最后一列
    y_train = trainset["MEDV"]
    X_test = testset.drop("MEDV", axis=1)
    y_test = testset["MEDV"]
    return X_train, X_test, y_train, y_test


# 定义损失函数
def loss_function(X, y, theta):
    inner = np.power(X * theta.T - y, 2)
    return np.sum(inner)/(2*len(X))


# 定义正则化代价函数,防止过拟合
def regularized_loss(X, y, theta, l):
    reg = (l / (2 * len(X))) * (np.power(theta[1:], 2).sum())
    return loss_function(X, y, theta) + reg


# 定义梯度下降方法
def gradient_descent(X, y, theta, l, alpha, epoch):
    cost = np.zeros(epoch)  # 初始化一个ndarray,包含每次epoch的cost
    m = X.shape[0]  # 样本数量m
    for i in range(epoch):
        # 利用向量化一步求解
        theta = theta - (alpha / m) * (X * theta.T - y).T * X - (alpha * l / m) * theta  # 添加了正则项
        cost[i] = regularized_loss(X, y, theta, l)  # 记录每次迭代后的代价函数值
    return theta, cost


if __name__ == '__main__':
    alpha = 0.01  # 学习率
    epoch = 1000   # 迭代次数
    l = 50  # 正则化参数
    data_list = loadData('housing.csv')
    X_train, X_test, y_train, y_test = splitData(data_list, 0.8)
    # 添加偏置列,同时初始化theta矩阵
    X_train = np.matrix(X_train.values)
    y_train = np.matrix(y_train.values)
    y_train = y_train.reshape(y_train.shape[1], 1)
    X_test = np.matrix(X_test.values)
    y_test = np.matrix(y_test.values)
    y_test = y_test.reshape(y_test.shape[1], 1)
    X_train = np.insert(X_train, 0, 1, axis=1)
    X_test = np.insert(X_test, 0, 1, axis=1)
    theta = np.matrix(np.zeros((1, 14)))  # x的第二维维度为14,所以初始化theta为(1,14)
    final_theta, cost = gradient_descent(X_train, y_train, theta, l, alpha, epoch)
    print(final_theta)

    # 模型评估
    y_pred = X_test * final_theta.T
    mse = np.sum(np.power(y_pred - y_test, 2)) / (len(X_test))
    rmse = np.sqrt(mse)
    R2_test = 1 - np.sum(np.power(y_pred - y_test, 2)) / np.sum(np.power(np.mean(y_test) - y_test, 2))
    print('MSE = ', mse)
    print('RMSE = ', rmse)
    print('R2_test = ', R2_test)

    # 绘制迭代曲线
    plt.plot(np.arange(epoch), cost, 'r')
    plt.title('Error vs. Training Epoch')
    plt.ylabel('Cost')
    plt.xlabel('Iterations')
    plt.show()

    # 图例展示预测值与真实值的变化趋势
    t = np.arange(len(X_test))  # 创建等差数组
    plt.plot(t, y_test, 'r-', label='target value')
    plt.plot(t, y_pred, 'b-', label='predict value')
    plt.legend(loc='upper right')
    plt.title('Linear Regression', fontsize=18)
    plt.grid(linestyle='--')
    plt.show()

2、使用sklearn库实现

import pandas as pd
from sklearn.linear_model import LinearRegression
from sklearn.model_selection import train_test_split
from sklearn import metrics
import math


# 载入数据集
def loadData(filepath):
    """
    :param filepath: csv
    :return: list
    """
    data_list = pd.read_csv(filepath)
    X = data_list.drop("MEDV", axis=1)
    y = data_list["MEDV"]
    return X, y


X, y = loadData('housing.csv')
X_train, X_test, y_train, y_test = train_test_split(X, y, train_size=0.8)

model = LinearRegression()
model.fit(X_train, y_train)
print("parameters:{}".format(model.coef_))
y_pred = model.predict(X_test)
print(y_pred)
print(y_test)

# 均方误差
mse = metrics.mean_squared_error(y_test, y_pred)
print(mse)

# 均方根误差
rmse = math.sqrt(mse)
print(rmse)

# 平均绝对误差
mae = metrics.mean_absolute_error(y_test, y_pred)
print(mae)

# R平方
r = metrics.r2_score(y_test, y_pred)
print(r)

result_file = {"prediction_value": y_pred}
result_file = pd.DataFrame(result_file)
result_file.to_csv("housing_predict.csv", index=False)

标签:train,回归,list,test,详解,theta,线性,np,data
From: https://blog.csdn.net/m0_67804957/article/details/145167664

相关文章

  • 【详解】HadoopHDFS操作实例
    目录HadoopHDFS操作实例环境准备HDFS基本命令1.查看HDFS目录内容2.创建目录3.上传文件4.下载文件5.删除文件或目录6.查看文件内容高级操作1.文件重命名2.设置文件权限3.查看文件系统状态1.创建目录2.上传文件3.下载文件4.删除文件或目录注意事......
  • Wgpu图文详解(05)纹理与绑定组
    前言什么是纹理?纹理是图形渲染中用于增强几何图形视觉效果的一种资源。它是一个二维或三维的数据数组,通常包含颜色信息,但也可以包含其他类型的数据,如法线、高度、环境光遮蔽等。纹理的主要目的是为几何图形的表面提供详细的视觉效果,使其看起来更加真实和复杂。而我们常见的图片......
  • U-Boot启动流程详解
    一、第一部分要分析uboot的启动流程,首先要找到“入口”,找到第一行程序在哪里。程序的链接是由链接脚本来决定的,所以通过链接脚本可以找到程序的入口。打开u-boot.lds文件看到第三行,可以发现_start是代码的入口点。ENTRY(_start)_start在文件arch/arm/lib/vectors.S中有......
  • V-By-One 详解
    文章目录V-BY-ONE概述HTPDN,LOCKN信号V-BY-ONEHSLink系统图V-BY-ONE传输速率计算总比特率计算每通道编码比特率计算V-BY-ONE收发器功能划分V-BY-ONETX模块分析V-BY-ONEfsm模块V-BY-ONETX状态机V-BY-ONERX状态机链路启动流程链路失败流程V-BY-ONECDRtra......
  • 第三节 回归实战
    数据处理超参:人为指定不能改变测试数据只有x没有标签y训练数据拆分,82开,作训练集和验证集(验证模型好坏),模型训练不是一路上升的过程,训练几次验证一次,最好的模型save下来one-hot独热编码猪(100)狗(010)猫(001)defget_feature_importance(feature_data,labe......
  • 【快速入门|文末福利】运筹学|初识线性规划(一条逻辑线,只需初中数学基础)
    导学问题/回忆自测三个核心问题“线性”为何?何谓“标准”?如何“化归”(把一般的线性规划问题转化为标准的线性规划问题)提示字面意思,在三个要素、两个关系之间对三个要素的要求“大”、“大”、“等”反转(乘以-1)/补齐/“分身”逻辑线索(逻辑线索中,发现有不熟悉的名词没关系,......
  • ipify.org:免费IP查询服务详解
    ​https://www.ipify.org/​是一个免费的公共服务网站,专门用于获取用户的公网IP地址。它提供了一个简单易用的API,开发者可以通过HTTP请求获取客户端的IP地址。主要功能获取用户的公网IP地址:用户或开发者可以通过访问ipify​的API,获取当前设备的公网IP地......
  • Java多进程多线程处理详解
    在Java编程中,多进程和多线程是两种常见的并发编程技术,用于提高程序的执行效率和响应速度。本文将详细介绍Java中的多进程和多线程处理,包括理论概述和代码示例。通过本文,你将了解如何在Java中实现多进程和多线程,以及它们在实际应用中的价值和意义。一、理论概述1.多进程与多线程......
  • Google开发者账号注册步骤详解
    注册Google开发者账号的步骤如下:访问GoogleDevelopers网站:打开浏览器,访问GoogleDevelopers网站。登录Google账号:如果你已经有Google账号(如Gmail账号),点击页面右上角的“登录”按钮,使用你的Google账号登录。如果你没有Google账号,点击“创建账号”......
  • 应用回归分析-何晓群
    第1章回归分析概述11.1变量间的统计关系11.2回归方程与回归名称的由来31.3回归分析的主要内容及其一般模型51.4建立实际问题回归模型的过程71.5回归分析应用与发展述评1思考与练习14第2章一元线性回归152.1一元线性回归模型152.2参数(B_0),......