机器学习DAY3 : 线性回归与最小二乘法与sklearn实现 (线性回归完)

线性回归

线性回归是一种较为简单,但十分重要的机器学习方法。掌握线性的原理及求解方法,是深入了解线性回归的基本要求。除此之外,线性回归也是监督学习回归部分的基石,希望你能通过本文掌握机器学习的一些重要的思想。

知识点
  • 一元线性回归
  • 平方损失函数
  • 最小二乘法及代数求解
  • 线性回归实现
  • 最小二乘法的矩阵推导

前面,我们了解了分类和回归问题的区别。也就是说,回归问题旨在实现对连续值的预测,例如股票的价格、房价的趋势等。比如,下方展现了一个房屋面积和价格的对应关系图。 

如上图所示,不同的房屋面积对应着不同的价格。现在,假设我手中有一套房屋想要出售,而出售时就需要预先对房屋进行估值。于是,我想通过上图,也就是其他房屋的售价来判断手中的房产价值是多少。应该怎么做呢?

我采用的方法是这样的。如下图所示,首先画了一条红色的直线,让其大致验证橙色点分布的延伸趋势。然后,我将已知房屋的面积大小对应到红色直线上,也就是蓝色点所在位置。最后,再找到蓝色点对应于房屋的价格作为房屋最终的预估价值。

在上图呈现的这个过程中,通过找到一条直线去拟合数据点的分布趋势的过程,就是线性回归的过程。而线性回归中的「线性」代指线性关系,也就是图中所绘制的红色直线。 

此时,你可能心中会有一个疑问。上图中的红色直线是怎么绘制出来的呢?为什么不可以像下图中另外两条绿色虚线,而偏偏要选择红色直线呢? 

绿色虚线的确也能反应数据点的分布趋势。所以,找到最适合的那一条红色直线,也是线性回归中需要解决的重要问题之一。

通过上面这个小例子,相信你对线性回归已经有一点点印象了,至少大致明白它能做什么。接下来的内容中,我们将了解线性回归背后的数学原理,以及使用 Python 代码对其实现。

上面针对  线性回归 的介绍内容中,我们列举了一个房屋面积与房价变化的例子。其中,房屋面积为自变量,而房价则为因变量。另外,我们将只有 1 个自变量的线性拟合过程叫做一元线性回归。

下面,我们就生成一组房屋面积和房价变化的示例数据。x 为房屋面积,单位是平方米; y 为房价,单位是万元。 

教学代码 

import numpy as npx = np.array([56, 72, 69, 88, 102, 86, 76, 79, 94, 74])
y = np.array([92, 102, 86, 110, 130, 99, 96, 102, 105, 92])

示例数据由 10 组房屋面积及价格对应组成。接下来,通过 Matplotlib 绘制数据点,xx, yy 分别对应着横坐标和纵坐标。

from matplotlib import pyplot as plt
%matplotlib inlineplt.scatter(x, y)
plt.xlabel("Area")
plt.ylabel("Price")

正如上面所说,线性回归即通过线性方程去拟合数据点。那么,我们可以令该 1 次函数的表达式为:

公式 (1) 是典型的一元一次函数表达式,我们通过组合不同的 w0 和 w1​ 的值得到不同的拟合直线。 

接下来,对公式 (1)(1) 进行代码实现:

def f(x, w0, w1):y = w0 + w1 * xreturn y

那么,哪一条直线最能反应出数据的变化趋势呢? 

想要找出对数据集拟合效果最好的直线,这里再拿出上小节图示进行说明。如下图所示,当我们使用 y(x,w)=w0+w1x 对数据进行拟合时,就能得到拟合的整体误差,即图中蓝色线段的长度总和。如果某一条直线对应的误差值最小,是不是就代表这条直线最能反映数据点的分布趋势呢? 

正如上面所说,如果一个数据点为 (xi yi),那么它对应的误差就为: 

上面的误差往往也称之为「残差」。但是在机器学习中,我们更喜欢称作「损失」,即真实值和预测值之间的偏离程度。那么,对 nn 个全部数据点而言,其对应的残差损失总和就为:

更进一步,在线性回归中,我们一般使用残差的平方和来表示所有样本点的误差。公式如下 

使用残差平方和的好处在于能保证损失始终是累加的正数,而不会存在正负残差抵消的问题。对于公式 (4)(4) 而言,机器学习中有一个专门的名词,那就是「平方损失函数」。而为了得到拟合参数 w0 和 w1​ 最优的数值,我们的目标就是让公式 (4) 对应的平方损失函数最小。

同样,我们可以对公式 (4) 进行代码实现: 

def square_loss(x, y, w0, w1):loss = sum(np.square(y - (w0 + w1*x)))return loss

如果某条直线拟合样本得到的总损失最小,那么这条直线就是最终想得到的结果。而求解损失最小值的过程,就必须用到下面的数学方法了。

最小二乘法是用于求解线性回归拟合参数 w 的一种常用方法。最小二乘法中的「二乘」代表平方,最小二乘也就是最小平方。而这里的平方就是指代上面的平方损失函数。

PS:最小二乘法(Least Squares Method) 是一种数学优化方法,用于在数据中找到最优的模型参数,使得模型预测值与实际观测值之间的误差平方和最小。

在回归问题中,最小二乘法的目标是找到一条最佳拟合线,使得数据点与拟合线之间的距离(误差)平方和达到最小。

简单来讲,最小二乘法也就是求解平方损失函数最小值的方法。那么,到底该怎样求解呢?这就需要使用到高等数学中的知识。推导如下: 

首先,平方损失函数为: 

我们的目标是求取平方损失函数 min(f) 最小时,对应的 w。首先求 f 的 1 阶偏导数: 

 

 

 到目前为止,已经求出了平方损失函数最小时对应的 w 参数值,这也就是最佳拟合直线。

我们将公式 (7) 求解得到 w 的过程进行代码实现: 

def w_calculator(x, y):n = len(x)w1 = (n*sum(x*y) - sum(x)*sum(y))/(n*sum(x*x) - sum(x)*sum(x))w0 = (sum(x*x)*sum(y) - sum(x)*sum(x*y))/(n*sum(x*x)-sum(x)*sum(x))return w0, w1

于是,可以向函数 w_calculator(x, y) 中传入 x 和 y 得到 w0​ 和 w1​ 的值。

w_calculator(x, y)

当然,我们也可以求得此时对应的平方损失的值:

w0 = w_calculator(x, y)[0]
w1 = w_calculator(x, y)[1]square_loss(x, y, w0, w1)

接下来,我们尝试将拟合得到的直线绘制到原图中: 

x_temp = np.linspace(50, 120, 100)  # 绘制直线生成的临时点plt.scatter(x, y)
plt.plot(x_temp, x_temp*w1 + w0, 'r')

从上图可以看出,拟合的效果还是不错的。那么,如果你手中有一套 150 平米的房产想售卖,获得预估报价就只需要带入方程即可:

f(150, w0, w1)

这里得到的预估售价约为 154 万元。这就是一个最小二乘法求解线性回归问题的完整过程。

sk-learn

上面的内容中,我们学习了什么是最小二乘法,以及使用 Python 对最小二乘线性回归进行了完整实现。那么,我们如何利用机器学习开源模块 scikit-learn 实现最小二乘线性回归方法呢? 

使用 scikit-learn 实现线性回归的过程会简单很多,这里要用到 LinearRegression() 类 。看一下其中的参数: 

使用 scikit-learn 实现线性回归的过程会简单很多,这里要用到 LinearRegression() 类 。看一下其中的参数:

sklearn.linear_model.LinearRegression(fit_intercept=True, normalize=False, copy_X=True, n_jobs=1)
- fit_intercept: 默认为 True,计算截距项。
- normalize: 默认为 False,不针对数据进行标准化处理。
- copy_X: 默认为 True,即使用数据的副本进行操作,防止影响原数据。
- n_jobs: 计算时的作业数量。默认为 1,若为 -1 则使用全部 CPU 参与运算。
from sklearn.linear_model import LinearRegression# 定义线性回归模型
model = LinearRegression()
model.fit(x.reshape(len(x), 1), y)  # 训练,reshape 操作把数据处理成 fit 能接受的形状# 得到模型拟合参数
model.intercept_, model.coef_

这里,通过 model.intercept_ 可以得到拟合的截距项,即上面的 w0w0​,通过 model.coef_ 得到 xx 的系数,即上面的 w1w1​。对比发现,结果是完全一致的。

同样,我们可以预测 150 平米房产的价格:

model.predict([[150]])

可以看到,这里得出的结果和自行实现计算结果一致。

PS:这里虽然只有一维的数据,但是还是要处理成二维的,因为线性规划就是要二维的数据,如果一维就得升维,如果三维就得降维,下面是个例子:

scikit-learn 的线性回归实现中,数据格式要求:

  • 每一行表示一个 样本
  • 每一列表示一个 特征

二维数组的形式:

  • 形状为 (n_samples, n_features)
    • n_samples 是样本数(行数)。
    • n_features 是特征数(列数)。

对于一维数据:

  • 每个样本只有一个特征,例如 x=[1,2,3,4,5]x = [1, 2, 3, 4, 5]x=[1,2,3,4,5]。
  • 转换为二维时,形状变为 (5, 1),表示有 5 个样本,每个样本只有 1 个特征。

转换后矩阵:

最小二乘法的矩阵推导及实现

 学习完上面的内容,相信你已经了解了什么是最小二乘法,以及如何使用最小二乘法进行线性回归拟合。上面,实验采用了求偏导数的方法,并通过代数求解找到了最佳拟合参数 w 的值。这里,我们尝试另外一种方法,即通过矩阵的变换来计算参数 w。

首先,一元线性函数的表达式为 y(x,w)=w0+w1x,表达成矩阵形式为:

PS:

                                        ​​​​​​​         

(8) 式中,W 为 [w0 w1],而 X 则是 [1,x1 1,x2 ⋯ 1,x9 1,x10][1,x1​ 1,x2​ ⋯ 1,x9​ 1,x10​​] 矩阵。然后,平方损失函数为: 

 

 通过对公式 (9) 实施矩阵计算乘法分配律得到:

在该公式中 y 与 XW 皆为相同形式的 (m,1) 矩阵,由此两者相乘属于线性关系,所以等价转换如下: 

 此时,对  矩阵求偏导数 得到:

我们可以针对公式 (13) 进行代码实现:

def w_matrix(x, y):w = (x.T * x).I * x.T * yreturn w

这里计算时,需要对原 x 数据添加截距项系数 1。 

x = np.matrix([[1, 56], [1, 72], [1, 69], [1, 88], [1, 102],[1, 86], [1, 76], [1, 79], [1, 94], [1, 74]])
y = np.matrix([92, 102, 86, 110, 130, 99, 96, 102, 105, 92])w_matrix(x, y.reshape(10, 1))

可以看到,矩阵计算结果和前面的代数计算结果一致。你可能会有疑问,那就是为什么要采用矩阵变换的方式计算?一开始学习的代数计算方法不好吗?

其实,并不是说代数计算方式不好,在小数据集下二者运算效率接近。但是,当我们面对十万或百万规模的数据时,矩阵计算的效率就会高很多,这就是为什么要学习矩阵计算的原因。

目前,你已经学习了如何使用最小二乘法进行线性回归拟合,以及通过代数计算和矩阵变换两种方式计算拟合系数 w,这已经达到了掌握线性回归方法的要求。接下来,我们将尝试加载一个真实数据集,并使用 scikit-learn 构建预测模型,实现回归预测。 

既然前面的 2 个小节中,都使用了和房价相关的示例数据。这里,我们就采用一个真实的房价数据集,也就是「波士顿房价数据集」。 

数据集介绍及划分 

 波士顿房价数据集 是机器学习中非常知名的数据集,它被用于多篇回归算法研究的学术论文中。该数据集共计 506 条,其中包含有 13 个与房价相关的特征以及 1 个目标值(房价)。

import pandas as pddf = pd.read_csv("https://labfile.oss.aliyuncs.com/courses/1081/course-5-boston.csv")

查看 DataFrame 前 5 行数据。

df.head()

该数据集统计了波士顿地区各城镇的住房价格中位数,以及与之相关的特征。每列数据的列名解释如下:

  • CRIM: 城镇犯罪率。
  • ZN: 占地面积超过 2.5 万平方英尺的住宅用地比例。
  • INDUS: 城镇非零售业务地区的比例。
  • CHAS: 查尔斯河是否经过 (=1 经过,=0 不经过)。
  • NOX: 一氧化氮浓度(每 1000 万份)。
  • RM: 住宅平均房间数。
  • AGE: 所有者年龄。
  • DIS: 与就业中心的距离。
  • RAD: 公路可达性指数。
  • TAX: 物业税率。
  • PTRATIO: 城镇师生比例。
  • BLACK: 城镇的黑人指数。
  • LSTAT: 人口中地位较低人群的百分数。
  • MEDV: 城镇住房价格中位数。

本次实验中,我们不会使用到全部的数据特征。这里,仅选取 CRIMRMLSTAT 三个特征用于线性回归模型训练。我们将这三个特征的数据单独拿出来,并且使用 describe() 方法查看其描述信息。 describe() 统计了每列数据的个数、最大值、最小值、平均数等信息。 

同样,我们将目标值单独拿出来。训练一个机器学习预测模型时,我们通常会将数据集划分为 70% 和 30% 两部分。

其中,70% 的部分被称之为训练集,用于模型训练。例如,这里的线性回归,就是从训练集中找到最佳拟合参数 w 的值。另外的 30% 被称为测试集。对于测试集而言,首先我们知道它对应的真实目标值,然后可以给学习完成的模型输入测试集中的特征,得到预测目标值。最后,通过对比预测的目标值与真实目标值之间的差异,评估模型的预测性能。 

上图就是一个简单的机器学习模型训练流程。接下来,我们针对数据集的特征和目标进行分割,分别得到 70% 的训练集和 30% 的测试集。其中,训练集特征、训练集目标、测试集特征和测试集目标分别定义为:X_trainy_trainX_testy_test

target = df['medv']  # 目标值数据split_num = int(len(features)*0.7)  # 得到 70% 位置X_train = features[:split_num]  # 训练集特征
y_train = target[:split_num]  # 训练集目标X_test = features[split_num:]  # 测试集特征
y_test = target[split_num:]  # 测试集目标
构建和训练模型

划分完数据集之后,就可以构建并训练模型。同样,这里要用到 LinearRegression() 类。对于该类的参数就不再重复介绍了。

model = LinearRegression()  # 建立模型
model.fit(X_train, y_train)  # 训练模型
model.coef_, model.intercept_  # 输出训练后的模型参数和截距项

 上面的单元格中,我们输出了线性回归模型的拟合参数。也就是最终的拟合线性函数近似为:

medv=0.6998⋅crim+10.1356⋅rm−0.2053⋅lstat−38.0010

其中,x1​, x2​, x3​ 分别对应数据集中 CRIMRM 和 LSTAT 列。接下来,向训练好的模型中输入测试集的特征得到预测值。

preds = model.predict(X_test)  # 输入测试集特征进行预测
preds  # 预测结果

对于回归预测结果,通常会有平均绝对误差、平均绝对百分比误差、均方误差等多个指标进行评价。这里,我们先介绍两个:

平均绝对误差(MAE)就是绝对误差的平均值,它的计算公式如下: 

其中,yi 表示真实值,y^i​ 表示预测值,n 则表示值的个数。MAE 的值越小,说明模型拥有更好的拟合程度。我们可以尝试使用 Python 实现 MAE 计算函数: 

def mae_value(y_true, y_pred):n = len(y_true)mae = sum(np.abs(y_true - y_pred))/nreturn mae

均方误差(MSE)它表示误差的平方的期望值,它的计算公式如下: 

其中,yi 表示真实值,y^​i​ 表示预测值,n 则表示值的个数。MSE 的值越小,说明预测模型拥有更好的精确度。同样,我们可以尝试使用 Python 实现 MSE 计算函数: 

def mse_value(y_true, y_pred):n = len(y_true)mse = sum(np.square(y_true - y_pred))/nreturn mse

于是,我们可以计算出上面模型的平均指标,即预测结果的 MSE 和 MAE 值:

mae = mae_value(y_test.values, preds)
mse = mse_value(y_test.values, preds)print("MAE: ", mae)
print("MSE: ", mse)

这主要是因为我们没有针对数据进行预处理。上面的实验中,我们随机选择了 3 个特征,并没有合理利用数据集提供的其他特征。除此之外,也没有针对异常数据进行剔除以及规范化处理。

当然,掌握好线性回归的原理和实现方法,才是本次实验内容的重点。

总结

在本文中,我们从线性回归原理入手,学习了最小二乘法的两种求解方法,并针对线性回归算法进行了完整实现。在这个过程中,你了解到了机器学习的训练和预测流程,以及背后的数学思想。

总结而来,一个机器学习过程往往包含训练和预测两部分,训练好的模型可用于对未知数据的预测。而训练模型的过程,实际上是应用机器学习算法解决问题的过程。其中,我们通常会定义一个损失函数(平方损失函数),并使用一种数学优化方法(最小二乘法)去求解该损失函数的最优解。这个思想将始终贯穿于机器学习之中。 

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

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

相关文章

Linux下编译安装Kokkos

本文记录在Linux下编译安装Kokkos的流程。 零、环境 操作系统Ubuntu 22.04.4 LTSVS Code1.92.1Git2.34.1GCC11.4.0CMake3.22.1oneAPI2024.2.1 一、安装依赖 二、编译安装 参考文献 Mills R T. PETSc/TAO Developments for Early Exascale Systems[J]. 2024.Josef R. A Stud…

eMMC 存储分区结构解析

一、eMMC 存储分区结构图 分区 用途 Boot Area Partitions 存储引导加载程序,支持安全启动和恢复模式 RPMB Partition 存储安全关键数据,防止重放攻击 General Purpose Partitions OEM 自定义数据分区,用于特定功能或镜像存储 User D…

攻防世界web第一题

最近开始学习网络安全的相关知识,开启刷题,当前第一题 题目为攻防世界web新手题 这是题目 翻译:在这个训练挑战中,您将了解 Robots_exclusion_standard。网络爬虫使用 robots.txt 文件来检查是否允许它们对您的网站或仅网站的一部…

大恒相机开发(2)—Python软触发调用采集图像

大恒相机开发(2)—Python软触发调用采集图像 完整代码详细解读和功能说明扩展学习 这段代码是一个Python程序,用于从大恒相机采集图像,通过软件触发来采集图像。 完整代码 咱们直接上python的完整代码: # version:…

记一次某企业管理系统通用SQL注入挖掘

更多视频教程可看主页和专栏 目录: 一、资产发现 二、通用漏洞挖掘 三、通用漏洞经验总结 一、资产发现 通过漏洞挖掘过程中发现该系统存在sql注入 1.二话不说先来个单引号显示 ‘011111111111111’’) ) 再来一个单号试一试可不可以把他闭合掉 换成报错注入的poc 发现右边…

Mybatis 如何复用 SQL

比如你的Mapper是这样写的: 但这个接口是没有分页的,你还想再写一个有分页的查询接口,两个接口SQL一模一样,只是多了分页特性。你可以直接重载一个方法,增加分页参数,即可复用该SQL。如下:

Redis 介绍和安装

个人主页:C忠实粉丝 欢迎 点赞👍 收藏✨ 留言✉ 加关注💓本文由 C忠实粉丝 原创 Redis 入门介绍 收录于专栏[redis] 本专栏旨在分享学习Linux的一点学习笔记,欢迎大家在评论区交流讨论💌 本章将带领读者进入 Redis 的世…

快速解决VRay渲染慢问题

在3D设计与渲染领域,VRay渲染器无疑是一款强大且广泛使用的工具,但很多小伙伴在使用它进行 CPU 渲染时,都遇到过速度慢得让人抓狂的情况。今天,我就来给大家分享两套切实可行的解决方案。 当我们将 VRay渲染器与 DMAX或Maya搭配使…

《庐山派从入门到...》PWM板载蜂鸣器

《庐山派从入门到...》PWM板载蜂鸣器 配置PWM模块控制板载无源蜂鸣器播放【一闪一闪亮晶晶】播放do re mi 《庐山派从入门到...》PWM控制无源蜂鸣器 PWM(Pulse Width Modulation,脉宽调制)是一种在嵌入式系统中常用的技术,它可以用…

2024-12-24 NO1. XR Interaction ToolKit 环境配置

文章目录 1 软件配置2 安装 XRToolKit3 配置 OpenXR4 安装示例场景5 运行测试 1 软件配置 Unity 版本:Unity6000.0.26 ​ 2 安装 XRToolKit 创建新项目(URP 3D),点击进入 Asset Store。 进入“Unity Registry”页签&#xff0…

安卓15预置第三方apk时签名报错问题解决

有同事反馈集成apk时安装失败 PackageManager: Failed to scan /product/app/test: No APK Signature Scheme v2 signature in package /product/app/test/test.apk 查看编译后的apk签名信息 DOES NOT VERIFY ERROR: JAR signer CERT.RSA: JAR signature META-INF/CERT.SF indi…

【C语言】指针数组、数组指针、函数指针、指针函数、函数指针数组、回调函数

【C语言】函数指针与指针函数 文章目录 [TOC](文章目录) 前言一、指针数组二、数组指针三、函数指针四、指针函数五、函数指针数组六、回调函数七、参考资料总结 前言 使用工具: 1.DEVC 提示:以下是本篇文章正文内容,下面案例可供参考 一、…

【Leetcode】1705. 吃苹果的最大数目

文章目录 题目思路代码复杂度分析时间复杂度空间复杂度 结果总结 题目 题目链接🔗 有一棵特殊的苹果树,一连 n n n 天,每天都可以长出若干个苹果。在第 i i i 天,树上会长出 a p p l e s [ i ] apples[i] apples[i] 个苹果&a…

使用 HTML 和 CSS 实现绚丽的节日烟花效果

文章目录 1. 效果预览2. 核心技术栈3. 核心代码解读3.1 HTML结构3.2 霓虹文字的CSS样式3.2.1 核心样式代码3.2.2 动画效果 3.3 JavaScript 的烟花效果实现3.3.1 烟花上升3.3.2 粒子爆炸 4. 用户交互5. 运行步骤总结 1. 效果预览 打开后输入文本的展示内容 用户点击页面后播放…

基于openEuler22.09部署OpenStack Yoga云平台(一)

OpenStack Yoga部署 安装OpenStack 一、基础准备 基于OpenStack经典的三节点环境进行部署,三个节点分别是控制节点(controller)、计算节点(compute)、存储节点(storage),其中存储…

国自然面上项目分享|基于人工智能和病理组学的早癌筛查算法研究|基金申请·24-12-24

小罗碎碎念 今天分享的项目为【常规面上项目】,执行年限为2018年1月至2021年12月,直接费用为55万元。 今天分享的这个项目很有意思,因为这个项目的成果是团队2020年申报基金委优青的材料,并且还有临床验证和商业转化,值…

SDMTSP:黑翅鸢算法(Black-winged kite algorithm,BKA)求解单仓库多旅行商问题,可以更改数据集和起点(MATLAB代码)

一、黑翅鸢算法BKA 黑翅鸢算法(Black-winged kite algorithm,BKA)由Wang Jun等人于2024年提出,该算法受黑翅鸢的迁徙和掠食行为启发而得。BKA集成了柯西突变策略和领导者策略,增强了算法的全局搜索能力,提…

41 stack类与queue类

目录 一、简介 (一)stack类 (二)queue类 二、使用与模拟实现 (一)stack类 1、使用 2、OJ题 (1)最小栈 (2)栈的弹出压入序列 (3&#xf…

【笔记】深度学习模型评估指标

推荐链接: (0)多分类器的评价指标 (1)泛化误差的评价方法:【机器学习】模型评估与选择(留出法、交叉验证法、查全率、查准率、偏差、方差) (2)机器学习&…

Linux运维常见命令

vi/vim快捷键使用 1)拷贝当前行 yy ,拷贝当前行向下的5行 5yy,并粘贴(输入p)。 2)删除当前行 dd ,删除当前行向下的5行5dd 3)在文件中查找某个单词 [命令行下 /关键字,回车查找 ,输入n就是查找下一个 ] 4)设置文件的行号&…