首页 > 其他分享 >线性回归初步理解

线性回归初步理解

时间:2024-11-23 21:35:22浏览次数:7  
标签:plot plt 回归 random 初步 np path 线性 theta

章节 1 线性回归算法

简单线性回归

线性回归是一种经典的有监督学习算法,用于研究因变量(目标变量)和一个或多个自变量(影响因素)之间的线性关系。简单线性回归关注单一自变量对目标变量的影响,而多元线性回归则处理多个自变量的情况。

目标变量(y)是需要预测的值,可以是连续值;自变量(X)是影响目标变量的因素,可以是连续值或离散值。

简单线性回归模型公式为 y = a + bx,其中a是截距,b是斜率。

看一个美国人发火箭的例子

Actual value:真实值,即已知的 y

Predicted value:预测值,是把已知的 x 带入到公式里面和猜出来的参数 a,b 计算得到的

Error:误差,预测值和真实值的差距

最优解:尽可能的找到一个模型使得整体的误差最小,整体的误差通常叫做损失 Loss

Loss:整体的误差,loss 通过损失函数 loss function 计算得到

最优解是通过最小化整体误差(损失)来找到最佳模型。

真实值(Actual value)、预测值(Predicted value)和误差(Error)的关系用于评估模型效果。

多元线性回归

现实生活中,往往有多个因素影响结果y。这时,自变量的数量从X1变为Xn,简单线性回归的公式不再适用。

多元线性回归公式为 y = XW + ε,其中W是特征的权值向量,ε是误差向量。

举例:训练一个模型预测一个人有多漂亮,历史数据包含人的一些指标和已知得分。

在多元线性回归中 W 是一维向量,代表的是 W0 到 Wn,我们也可以用线性代数的方式去 表达公式,这时算法要求解的就是这个向量,如果维度很多我们当然需要计算机帮助我们来求解了。

章节2 从代码理解线性回归

通过anaconda环境打开jupyter notebook

正规方程处理线性回归

# 支持python2和3
from __future__ import division, print_function, unicode_literals

# 导入必要的库
import numpy as np
import os

# 设置随机数种子,让每一次用相同的数据进行训练时输出的结果一致
np.random.seed(42)

# 设置可视化的参数
%matplotlib inline
import matplotlib as mpl
import matplotlib.pyplot as plt
mpl.rc('axes', labelsize=14)
mpl.rc('xtick', labelsize=12)
mpl.rc('ytick', labelsize=12)

# 设置文件保存路径
PROJECT_ROOT_DIR = "."
CHAPTER_ID = "training_linear_models"

# 无视一些不重要的警告
import warnings
warnings.filterwarnings(action="ignore", message="^internal gelsd")

用y=4+3x+y=4+3x+高斯噪声来生成数据点(x0x0为1)

import numpy as np

X = 2 * np.random.rand(100, 1) #X中所有点的范围在0-2之间
y = 4 + 3 * X + np.random.randn(100, 1)

# 绘制定义好的方程
plt.plot(X, y, "b.")
plt.xlabel("$x_1$", fontsize=18)
plt.ylabel("$y$", rotation=0, fontsize=18)
plt.axis([0, 2, 0, 15])
# save_fig("generated_data_plot")
plt.show()

通过求解MSE的最小值^θ=(XT⋅X)−1⋅XT⋅yθ^=(XT⋅X)−1⋅XT⋅y 求解θθ值(这就是一个模型的训练过程)

X_b = np.c_[np.ones((100, 1)), X]  # add x0 = 1 to each instance
theta_best = np.linalg.inv(X_b.T.dot(X_b)).dot(X_b.T).dot(y)
theta_best
array([[4.21509616],
       [2.77011339]])

把x0=1x0=1带入可计算出y值(这里面因为有X_new是二维的,所以x0也是二维的)这里X_new是两个数据点

X_new = np.array([[0], [2]])
X_new_b = np.c_[np.ones((2, 1)), X_new]  # add x0 = 1 to each instance
y_predict = X_new_b.dot(theta_best)
y_predict
array([[4.21509616],
       [9.75532293]])
plt.plot(X_new, y_predict, "r-", linewidth=2, label="Predictions")
plt.plot(X, y, "b.")
plt.xlabel("$x_1$", fontsize=18)
plt.ylabel("$y$", rotation=0, fontsize=18)
plt.legend(loc="upper left", fontsize=14)
plt.axis([0, 2, 0, 15])
plt.show()

LinearRegression是基于最小二乘方法的线性模型(训练过程使用正规方程求解)

from sklearn.linear_model import LinearRegression
lin_reg = LinearRegression()
lin_reg.fit(X, y)
lin_reg.intercept_, lin_reg.coef_
(array([4.21509616]), array([[2.77011339]]))
lin_reg.predict(X_new)
array([[4.21509616],
       [9.75532293]])
梯度下降训练线性回归
eta = 0.1
n_iterations = 1000
m = 100
theta = np.random.randn(2,1)

for iteration in range(n_iterations):
    gradients = 2/m * X_b.T.dot(X_b.dot(theta) - y)
    theta = theta - eta * gradients
theta
array([[4.21509616],
       [2.77011339]])

预测

X_new_b.dot(theta)
array([[4.21509616],
       [9.75532293]])

绘制不同学习率下的学习过程

theta_path_bgd = []
# 函数 绘制不同学习率下的学习过程
def plot_gradient_descent(theta, eta, theta_path=None):
    m = len(X_b)
    plt.plot(X, y, "b.")
    n_iterations = 1000
    for iteration in range(n_iterations):
        if iteration < 10:
            y_predict = X_new_b.dot(theta)
            style = "b-" if iteration > 0 else "r--"
            plt.plot(X_new, y_predict, style)
        gradients = 2/m * X_b.T.dot(X_b.dot(theta) - y)
        theta = theta - eta * gradients
        if theta_path is not None:
            theta_path.append(theta)
    plt.xlabel("$x_1$", fontsize=18)
    plt.axis([0, 2, 0, 15])
    plt.title(r"$\eta = {}$".format(eta), fontsize=16)
np.random.seed(42)
theta = np.random.randn(2,1)  # random initialization

plt.figure(figsize=(10,4))
plt.subplot(131); plot_gradient_descent(theta, eta=0.02)
plt.ylabel("$y$", rotation=0, fontsize=18)
plt.subplot(132); plot_gradient_descent(theta, eta=0.1, theta_path=theta_path_bgd)
plt.subplot(133); plot_gradient_descent(theta, eta=0.5)

plt.show()

这里面绘制了前10次迭代的情况,可以看到第一幅图,由于学习率很小,梯度下降进展很慢。第二幅图,可以看到当学习率适中时,梯度下降可以快速开始寻找最优解。第三幅图,当学习率比较大时,梯度下降很可能永远找不到最优解。

随机梯度下降

每次用所有样本来梯度下降依然很慢,可以每次只用其中一个值,尽管会引入一些不规律性,算法也没法收敛到最优解,但通常最后的参数还不错,另外,也可以帮助跳出局部最优解。一个优化的方法是逐渐的减小学习率,这个过程称为模拟退火。


theta_path_sgd = []
m = len(X_b)
np.random.seed(42)

n_epochs = 50
t0, t1 = 5, 50  # learning schedule hyperparameters

def learning_schedule(t):
    return t0 / (t + t1)

theta = np.random.randn(2,1)  # random initialization

for epoch in range(n_epochs):
    for i in range(m):
        if epoch == 0 and i < 20:                    # not shown in the book
            y_predict = X_new_b.dot(theta)           # not shown
            style = "b-" if i > 0 else "r--"         # not shown
            plt.plot(X_new, y_predict, style)        # not shown
        random_index = np.random.randint(m)
        xi = X_b[random_index:random_index+1]
        yi = y[random_index:random_index+1]
        gradients = 2 * xi.T.dot(xi.dot(theta) - yi)
        eta = learning_schedule(epoch * m + i)
        theta = theta - eta * gradients
        theta_path_sgd.append(theta)                 # not shown

plt.plot(X, y, "b.")                                 # not shown
plt.xlabel("$x_1$", fontsize=18)                     # not shown
plt.ylabel("$y$", rotation=0, fontsize=18)           # not shown
plt.axis([0, 2, 0, 15])                              # not shown
plt.show()  
theta
array([[4.21076011],
       [2.74856079]])

sklearn库中可以使用函数实现随机梯度下降SGDRegressor()

from sklearn.linear_model import SGDRegressor
sgd_reg = SGDRegressor(max_iter=50, tol=-np.infty, penalty=None, eta0=0.1, random_state=42)
sgd_reg.fit(X, y.ravel())
SGDRegressor(eta0=0.1, max_iter=50, penalty=None, random_state=42, tol=-inf)
sgd_reg.intercept_, sgd_reg.coef_
(array([4.16782089]), array([2.72603052]))
小批量梯度下降

在迭代的每一步,批量梯度使用整个训练集,随机梯度使用仅仅一个实例,在小批量梯度下降中,它则使用一个随机的小型实例集。它比随机梯度的主要优点在于你可以通过矩阵运算的硬件优化得到一个较好的训练表现,尤其当你使用 GPU 进行运算的时候。

theta_path_mgd = []

n_iterations = 50
minibatch_size = 20

np.random.seed(42)
theta = np.random.randn(2,1)  # random initialization

t0, t1 = 200, 1000
def learning_schedule(t):
    return t0 / (t + t1)

t = 0
for epoch in range(n_iterations):
    shuffled_indices = np.random.permutation(m)
    X_b_shuffled = X_b[shuffled_indices]
    y_shuffled = y[shuffled_indices]
    for i in range(0, m, minibatch_size):
        t += 1
        xi = X_b_shuffled[i:i+minibatch_size]
        yi = y_shuffled[i:i+minibatch_size]
        gradients = 2/minibatch_size * xi.T.dot(xi.dot(theta) - yi)
        eta = learning_schedule(t)
        theta = theta - eta * gradients
        theta_path_mgd.append(theta)  
theta
array([[4.25214635],
       [2.7896408 ]])

三个方法的训练过程数据

theta_path_bgd = np.array(theta_path_bgd)
theta_path_sgd = np.array(theta_path_sgd)
theta_path_mgd = np.array(theta_path_mgd)
# 可视化 三个方法的训练过程数据
plt.figure(figsize=(7,4))
plt.plot(theta_path_sgd[:, 0], theta_path_sgd[:, 1], "r-s", linewidth=1, label="Stochastic")
plt.plot(theta_path_mgd[:, 0], theta_path_mgd[:, 1], "g-+", linewidth=2, label="Mini-batch")
plt.plot(theta_path_bgd[:, 0], theta_path_bgd[:, 1], "b-o", linewidth=3, label="Batch")
plt.legend(loc="upper left", fontsize=16)
plt.xlabel(r"$\theta_0$", fontsize=20)
plt.ylabel(r"$\theta_1$   ", fontsize=20, rotation=0)
plt.axis([2.5, 4.5, 2.3, 3.9])
plt.show()

从图中可以看出随机梯度下降法的稳定性较差,波动较大;批量梯度下降法虽然整体性能最优,但是训练过程的时耗最大;小批量梯度下降法则是两者的折中,在大多数任务下的使用率最高。 

标签:plot,plt,回归,random,初步,np,path,线性,theta
From: https://blog.csdn.net/yuange1666/article/details/143998705

相关文章

  • 【Solution】用C语言代码绘制线性函数包围图
    题目:绘制左边图的众多*输出图像,函数已给出:y=1,y=-x+2n,y=x。解决方案: 思路对于原来的坐标几何图形,2<=n,y<=x<=2n-y,1<=y<=x。我们用来写C代码的函数首先要确定三角形高的范围,至少要2。将图形分隔成上下两部分。从最高的顶点到三角形高的部分,和其下面的部分。使用line......
  • 分段回归:处理数据结构性变化的有力工具
    分段回归:处理数据结构性变化的有力工具一、引言1.1问题背景现实数据中的结构性变化政策影响导致的突变自然现象的阈值效应经济周期的转折点传统线性回归的局限性无法捕捉数据的突变点对结构性变化敏感可能导致严重的拟合偏差1.2算法概述分段回......
  • 广义加性模型(GAM):灵活的非线性建模框架
    广义加性模型(GAM):灵活的非线性建模框架一、引言1.1问题背景现实世界中的非线性关系普遍存在传统线性模型和GLM的局限性需要在可解释性和灵活性之间取得平衡多维特征的非线性效应难以建模1.2算法概述GAM是GLM的自然扩展将线性项替换为平滑函数保持可加性结构基本形式......
  • LSTM-ANN基于长短期记忆神经网络结合人工神经网络的多变量回归预测Matlab
    LSTM-ANN基于长短期记忆神经网络结合人工神经网络的多变量回归预测Matlab目录LSTM-ANN基于长短期记忆神经网络结合人工神经网络的多变量回归预测Matlab预测结果评价指标基本介绍程序设计参考资料预测结果评价指标训练集数据的R2为:0.99805测试集数据的R2为:0.9......
  • python实战(二)——房屋价格回归建模
    一、任务背景    本章将使用一个经典的Kaggle数据集——HousePrices-AdvancedRegressionTechniques进行回归建模的讲解。这是一个房价数据集,与我们熟知的波士顿房价数据集类似,但是特征数量要更多,数据也要更为复杂一些。下面,我们将使用这个房价数据进行机器学习中......
  • FS4056E是一款单节锂离子电池恒流/恒压线性充电芯片支持NTC温度
    FS4056E是一款单节锂离子电池恒流/恒压线 性充电芯片,简单的外部应用电路非常适合便携 式设备应用,适合USB电源和适配器电源工作, 内部采用防倒充电路,不需要外部隔离二极管。 热反馈可对充电电流进行自动调节,以便在大功 率操作或高环境温度条件下对芯片温度加以限制 。FS4056E充......
  • C++入门Day5 ~ 6:简单变量 & 数据类型 part 1 <8000字长文带你初步理解数据类型>
    这是我在学习中的一个小问题,希望对你也有所帮助:        问:数据类型和简单变量属于oop的基本概念吗?        答:不是!数据类型和简单变量本身并不属于面向对象编程(OOP)的基本概念,但它们是编程中的基础概念,面向对象编程会基于这些基础概念来构建更复杂的结构。......
  • 数据结构与算法之线性表的基本操作
    数据结构之线性表的基本操作初始化,插入,获取#include<stdio.h>#include<stdlib.h>#include<malloc.h>#defineOK1#defineOVERFLOW-1#defineLIST_INIT_SIZE100#defineLISTINCREMENT10typedefintElemType;typedefstruct{ ElemType*elem; intlength; i......
  • 83. 删除排序链表中的重复元素 线性法&快慢双指针
    83.删除排序链表中的重复元素给定一个已排序的链表的头 head , 删除所有重复的元素,使每个元素只出现一次 。返回 已排序的链表 。示例1:输入:head=[1,1,2]输出:[1,2]示例2:输入:head=[1,1,2,3,3]输出:[1,2,3]提示:链表中节点数目在范围 [0,300] 内-100<=......
  • 【MATLAB代码】二维情况下的EKF滤波,非线性状态方程和非线性的观测方程
    文章目录代码运行结果代码介绍:扩展卡尔曼滤波(EKF)二维滤波主要功能应用场景总结代码以下代码,复制粘贴到MATLAB上即可运行:%EKF二维滤波%date:2024-10-17/Ver1clear;clc;closeall;%清除变量、命令行和图形窗口rng(0);%设置随机数种子......