ML 系列:多元线性回归 (MLR)(04)

news2024/11/14 15:00:07

图 1.多元线性回归与简单线性回归

一、说明

        线性回归从一维推广到多维,这与单变量线性回归有很多不同,情况更加复杂,而在梯度优化也需要改成向量梯度,同时,数据预处理也成了必要步骤。

二、综述

        多元线性回归是简单线性回归的一种广义形式,它使用多个自变量来预测因变量。根据表 1,使用发动机尺寸 x_1、x_2 的气缸数和燃料消耗量x_3来估计排放的 CO2 气体 (y) 是多元线性回归。多元线性回归公式如公式 1 所示。

多元线性回归的方程 1:

        在等式 1 中,m 指的是自变量的数量,训练模型的过程类似于简单的线性回归,不同之处在于,这里我们不是确定 a 和 b,而是找到 m+1 个合适的数字(b_0、b_1、...b_m)。使用多元线性回归可以显示自变量(x_1、x_2、x_3 等)的有效性x_m) 估计因变量 (y) 并获得每个自变量的变化在改变因变量中的影响。

表 1 显示了多元线性回归中的自变量和因变量:

                                                                图 1.I个因变量和因变量

        如前所述,数据不能用高于三个维度的维度来表示,但可以针对每个自变量 (x_i) 绘制目标数据或标签。我们在本章中介绍的数据有七个特征或特征,如图 2 所示,CO2 气体的因变量 (CO2_Emissions) 与三个特征(自变量)的比较。

图 2.为每个特征绘制因变量数据

        可以看出,数据显示相对分散,它表明因变量 (y) 的输出是几个自变量的函数,换句话说,它不受一个变量的影响,几个变量在确定输出值方面发挥作用。

        我将为一个名为 “50 Startups Data” 的数据集编写一个代码来解析多元线性回归,该数据集适用于多元线性回归的任务。根据 Kaggle 网站:

我们在这里看到的数据集包含有关 50 家初创公司的数据。它有5列:“研发支出”,“管理”,“营销支出”,“状态”,“利润”。
前 3 列表示每家初创公司在研发上花费了多少,他们在营销上花费了多少,以及他们在管理成本上花费了多少,状态列表示初创公司所在的州,最后一列表示初创公司获得的利润。

如果您想访问代码和数据集,请打开我的 GitHub 仓库,并下载“50_Startups.csv”数据集。

首先,我们应该导入一些需要的库:

三、包含库

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LinearRegression

然后我们应该用 pandas 加载 csv 数据集:

四、加载数据集

df = pd.read_csv('./Datasets/50_Startups.csv')
df.head()

图 3. 前 5 行数据

print(df.dtypes)

图 4. 列或特征的类型

我们应该将 “object” 类型转换为 “category” 类型,在 pandas 中使用此命令是可能的:

df['State'] = df['State'].astype('category')
print(df.dtypes)

图 5. 将对象转换为类别

这是清理和预处理数据的时间:

4.1. 检查并处理缺失值

我们可以使用以下命令在 pandas 中看到 null 值:

df.isnull().sum()

图 6. 查看 null 值

        如上图所示,我们在第二列中有两个 null 值,在第三列中也有一个 null 值。要查看缺失值,您可以使用另一个名为 Missingno 的出色库。Missingno 是一个 Python 库,用于可视化数据集中的缺失数据。它提供了一种识别模式和了解数据集中缺失值范围的便捷方法。

import missingno as msno
msno.matrix(df)

图 7. 缺少用于查找缺失值的输出

        您可以使用 fillna() 函数将 pandas DataFrame 中的 NaN 值替换为特定值。用于替换的常见值之一是 median,我将其填充为每列的缺失值。

        检查管理功能:

m = df['Administration'].median()
print(f"Median for Administration feature is:", m)

# Median for Administration feature is: 122699.795

使用以下命令计算每个特征的缺失值数:

print(df['Administration'].isna().sum())
# 2

最后,用这个命令填充它 (fill with median):

df['Administration'].fillna(m, inplace=True)

print(df['Administration'].isna().sum())
# 0

我们应该填补另一个功能 (Marketing Spend) 的缺失值:

med_marketing = df['Marketing Spend'].median()
df['Marketing Spend'].fillna(med_marketing, inplace=True)
df['Marketing Spend'].isna().sum()
# 0

在用每个特征的中位数填充缺失值后,现在我们再次看到 msno 库的结果:

msno.matrix(df)

图 8. Missing 填充缺失值后无输出

4.2. 编码分类特征

在我解释什么是编码以及如何进行编码之前,请先看一下 DataFrame 的输出:

df.head()

图 9. 编码前的数据输出

在机器学习中,包含非数值的分类变量(特征)很常见。但是,大多数机器学习算法都需要数字输入。为了解决这个问题,我们执行了一个称为 “编码分类特征” 的过程,该过程涉及将这些分类变量转换为机器学习模型可以理解和处理的数字表示。

对分类特征进行编码有几种常用方法:

  1. One-Hot Encoding:对于每个分类变量,将为每个唯一类别创建一个新的二进制特征。如果存在类别,则二进制特征的值为 1,否则为 0。独热编码扩展了特征空间,但保留了有关类别的信息。One-Hot Encoding 通常使用 pandas 中的函数执行。例如,我们的数据中有一个名为“State”的列,其类别为“New York”、“California”和“Florida”,使用该列将为每个类别创建新列,并根据类别是否存在分配值 1 或 0。因此,结果将包含“State_California”、“State_Florida”和“State_New York”等列,其中的二进制值指示原始“State”列中每列的存在与否。pd.get_dummies()pd.get_dummies()
  2. Label Encoding:在此方法中,为每个类别分配一个唯一的整数标签。标签的分配方式可以保留类别之间的序号关系(如果有)。我们不需要此方法,因为 State 功能没有任何订单。

这是我们在 Pandas 中使用 One-Hot 编码的方式:

df_encoded = pd.get_dummies(df, columns=['State'], dtype=np.float64)
df_encoded.head()

图 10. 对 'State' 功能进行编码后的数据输出

4.3. 更改列的顺序

        我们的标签是 Profit,标签通常位于最后一列,代码如下:我们可以按自己喜欢的任何顺序放置列:

df_encoded = df_encoded[['R&D Spend', 'Administration', 'Marketing Spend',
                         'State_California', 'State_Florida', 'State_New York', 'Profit']]

df_encoded.head()

图 11. 重新排序的要素

4.4. 重命名列名称,以便它们可以编码

        在数据分析和机器学习中,通常建议避免使用带空格的列名,而是将它们转换为更方便且与编程语言兼容的格式。最常见的方法是将空格替换为下划线或其他合适的字符。

df_encoded.rename(columns={'R&D Spend': 'R&D_Spend',
                          'Marketing Spend': 'Marketing_Spend',
                          'State_New York': 'State_New_York'}, inplace=True)
df_encoded.head()

图 12. 重命名的列

五. 异常值的箱形图

        异常值是明显偏离数据集中大多数数据的数据点。它们可以是与其他值相比异常大或异常小的观测值。异常值可能由于各种原因而发生,例如测量错误、数据损坏或罕见事件。

        在机器学习模型中考虑异常值非常重要,因为它们会对模型的性能和结果产生重大影响。异常值可能会扭曲统计度量,例如平均值和标准差,从而导致估计值有偏差和预测不准确。它们还会影响某些算法的假设,例如线性回归,这些算法假定数据服从正态分布。

        识别和可视化异常值的一种常用技术是箱形图(也称为箱须图)。箱形图通过显示四分位数、中位数和潜在异常值来提供数据集分布的可视化摘要。该框表示四分位距 (IQR),其中包含中间 50% 的数据。晶须从框延伸到一定范围内(通常是 IQR 的 1.5 倍)内的最小和最大数据点。超出此范围的数据点被视为潜在的异常值,并绘制为单个点。

import matplotlib.pyplot as plt

fig, axes = plt.subplots(2, 4, figsize=(20, 8))
axes_flat = axes.flatten()

for i, col in enumerate(df_encoded.columns):
    ax = axes_flat[i]
    ax.boxplot(df_encoded[col])
    ax.set_title(col)

图 13. 用于查找异常值的箱形图

注意:使用独热编码特征时,无需像处理数值特征那样考虑异常值。独热编码特征由二进制值(0 或 1)组成,没有数字分布来评估异常值。独热编码特征不是测量值的大小或偏差,而是关注某个类别的存在或不存在。因此,离群值的概念在 one-hot 编码特征的上下文中是无关紧要的。但是,我为所有特征绘制了箱形图。

有几种方法可以从数据集中删除异常值,其中一种常见且有用的方法称为 IQR,我将在下面解释它:

  • 通过从第三个四分位数 (Q3) 中减去第一个四分位数 (Q1) 来计算数据集的四分位数间距 (IQR)。
  • 定义下限 (Q1–1.5 * IQR) 和上限 (Q3 + 1.5 * IQR)。
  • 删除低于下限或高于上限的任何数据点。

下图显示 IQR 方法的工作原理:

图 14. 用于异常值检测的 IQR 方法

计算 df_encoded 中每列的第一四分位数 (q1)、第三四分位数 (q3) 和四分位距 (iqr)。这有助于确定大多数数据点所在的范围。

q1 = df_encoded.quantile(0.25)
q3 = df_encoded.quantile(0.75)
iqr = q3 - q1

根据四分位距计算下限和上限截止值。这些截止值用作确定异常值的阈值。低于 cutoff_low 或高于 cutoff_high 的数据点被视为潜在异常值。

cutoff_low  = q1 - (1.5 * iqr)
cutoff_high = q3 + (1.5 * iqr)

创建一个布尔掩码,用于标识哪些数据点 df_encoded 属于截止值定义的可接受范围。对于不被视为异常值的数据点,此掩码为 True;对于潜在异常值,此掩码为 False。

mask = (df_encoded >= cutoff_low) & (df_encoded <= cutoff_high)

应用布尔掩码以从 df_encoded 中筛选出可能的异常值行。mask.all(axis=1) 检查掩码每行中的所有值是否均为 True,这表示该行中的任何列都不包含异常值。生成的df_filtered仅包含没有异常值的行。

df_filtered = df_encoded[mask.all(axis=1)]

用于删除异常值的集成代码如下:

q1 = df_encoded.quantile(0.25)
q3 = df_encoded.quantile(0.75)
iqr = q3 - q1

cutoff_low  = q1 - (1.5 * iqr)
cutoff_high = q3 + (1.5 * iqr)

mask = (df_encoded >= cutoff_low) & (df_encoded <= cutoff_high)

df_filtered = df_encoded[mask.all(axis=1)]
df_filtered.head()

现在是时候创建一个新的 DataFrame 了,其中包含根据布尔掩码识别为异常值的行 df_encoded。

# see outliers with ~ [~mask.all]
df_outliers = df_encoded[~mask.all(axis=1)]
df_outliers.head()

图 15. 包含离群值的新 DataFrame

六、特征选择/缩减

        特征选择或减少与相关性涉及根据特征与目标变量或彼此之间的相关性来识别和选择或减少数据集中的特征。通过检查特征之间关系的强度和方向,这种方法有助于确定与给定任务最相关和信息量最大的特征,从而有可能提高模型性能并降低计算复杂性。

        Pearson 相关系数通常用于测量线性相关,其他相关度量可以捕获不同类型的关系。例如:

  1. 皮尔逊相关系数:它衡量两个连续变量之间线性关系的强度和方向。
  2. Spearman 相关系数:它评估变量之间的单调关系,它捕获变量之间的任何增加或减少趋势,而不管线性如何。
  3. Kendall 的 tau:它度量变量之间的序数关联,适用于排名或有序数据。
correlation = df_filtered.corr(method='pearson')
correlation

图 16. 特征之间的关联

我们需要知道每个功能对标签 (Profit) 的影响,通过这些代码行我们可以做到这一点:

corr = df_filtered.corr()
corr[['Profit']].abs().sort_values(by='Profit', ascending=False)

图 17. 基于标签的排序相关性

        我们想做 Feature selection or reduce with correlation 涉及根据特征与目标变量或彼此之间的相关性来识别和选择或减少数据集中的特征。在本例中,我想删除与标签 (Profit) 相关性较低的特征:

df_copy = df_filtered.copy()
df_copy.drop(['State_California', 'State_Florida', 'State_New_York'], axis=1, inplace=True)
df_copy.head()

图 18. 删除部分特征后的数据集

七、训练测试拆分

        在这里,我们分配 X 和 y 变量,其中 X 特征变量具有自变量,y 特征变量具有因变量。

X = df_copy.iloc[:, :-1].values
y = df_copy.iloc[:, -1].values

然后我们应该分为 train 和 test 集。

from sklearn.model_selection import train_test_split

x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.2, random_state=42, shuffle=True)

x_train.shape, y_train.shape, x_test.shape, y_test.shape
# ((37, 3), (37,), (10, 3), (10,))

7.1 Model

from sklearn.linear_model import LinearRegression

# create model
model = LinearRegression()

7.2 训练

model.fit(x_train, y_train)
model.intercept_, model.coef_

7.3 测试

# Test model score for train data
model.score(x_train, y_train)
# 0.966
# Test model score for test data
model.score(x_test, y_test)
# 0.91
# Test model score for test data
model.score(x_test, y_test)
# 0.91

7.4 预测

y_hat = model.predict(x_test[[0], :])
y_hat

# array([103132.59393452])

八、结论

        在 第 4 部分 中,我们讨论了多元线性回归以及我们应该如何预处理数据。在第 5 部分:非线性回归,我们讨论了非线性回归是一种回归分析形式,其中观察数据由函数建模,该函数是模型参数的非线性组合,并取决于一个或多个自变量。

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

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

相关文章

C++:分苹果【排列组合】

描述 把M个同样的苹果放到N个同样的盘子里&#xff0c;允许有的盘子空着不放&#xff0c;问共有多少种不同的分法&#xff1f;&#xff08;用K表示&#xff09;&#xff0c;5&#xff0c;1&#xff0c;1和1&#xff0c;5&#xff0c;1是同一种分法。 输入描述 两个整数M和N&…

C语言 | Leetcode C语言题解之第420题强密码检验器

题目&#xff1a; 题解&#xff1a; #define MAX(a, b) ((a) > (b) ? (a) : (b)) #define MIN(a, b) ((a) < (b) ? (a) : (b))int strongPasswordChecker(char * password) {int n strlen(password);bool has_lower false, has_upper false, has_digit false;for …

YOLOv9改进系列,YOLOv9主干网络替换为RepViT (CVPR 2024,清华提出,独家首发),助力涨点

摘要 轻量级视觉变换器(ViTs)在资源受限的移动设备上表现出优越的性能和较低的延迟,相比之下轻量级卷积神经网络(CNNs)稍显逊色。研究人员发现了许多轻量级 ViTs 和轻量级 CNNs 之间的结构联系。然而,它们在块结构、宏观和微观设计上的显著架构差异尚未得到充分研究。在…

【重磅发布】大模型在金融领域的价值、治理和生态进阶之路白皮书

引言 金融行业天然具备数据和信息密集型的特点,在数字化成熟度方面处于领先地位。此外,金融行业的数字化投入持续稳步增长,汇集了大量具备数字化技能的人才。这些优势使得金融行业在AI技术的应用和创新方面具备独特的条件,能够在推动技术革新和提升行业效率方面起到示范作…

NLP(二)-文本表示

One-hot One-hot&#xff08;独热&#xff09;编码是一种最简单的文本表示方式。如果有一个大小为V的词表&#xff0c;对于第i个词$w_i$&#xff0c;可以用一个长度为V的向量来表示&#xff0c;其中第i个元素为1&#xff0c;其它为0.例如&#xff1a; 减肥&#xff1a;[1, 0,…

59.【C语言】内存函数(memmove函数)

目录 2.memove函数 *简单使用 部分翻译 *模拟实现 方案1 方案2 1.有重叠 dest在src左侧 dest在src右侧 2.无重叠 代码 2.memove函数 *简单使用 memove:memory move cplusplus的介绍 点我跳转 对比第59篇的memcpy函数 对比memmcpy函数的介绍如下区别: 部分翻译 m…

【Verilog学习日常】—牛客网刷题—Verilog快速入门—VL59

根据RTL图编写Verilog程序 描述 根据以下RTL图&#xff0c;使用 Verilog HDL语言编写代码&#xff0c;实现相同的功能&#xff0c;并编写testbench验证功能。 输入描述&#xff1a; clk&#xff1a;系统时钟信号 rst_n&#xff1a;复位信号&#xff0c;低电平有效 data_in…

js 获取树节点上某节点的最底层叶子节点数据

效果图 数据为某一个节点对象 递归代码 function getLeafNodes(node) {if (!node.children || node.children.length 0) {// 如果是叶子节点&#xff0c;返回它的数据return [node.data];}// 如果节点有子节点&#xff0c;递归获取所有叶子节点的数据return node.children.…

基于误差状态的卡尔曼滤波

基于误差状态的卡尔曼滤波ESKF 注意这里的观测方程&#xff0c;是IMU的误差状态和激光定位的差值得到的。

JavaWeb---三层架构

文章目录 1. 为什么需要分层&#xff1f;2.软件设计中的分层模式3.分层4.三层架构&#xff1a;显示层、业务逻辑层、数据访问层3. 案例&#xff1a;利用三层架构原理实现编写web程序的流程 摘自&#xff1a;https://blog.csdn.net/qq_64001795/article/details/124112824 1. 为…

Qt日志输出及QsLog日志库

目录 Qt日志输出及QsLog日志库日志输出格式化日志普通格式化条件格式化环境变量设置格式化日志输出位置日志输出对象信息禁用输出 QsLog日志库使用方法1. 将QsLog目录添加到项目中2. 配置CMakeLists.txt文件3. 配置.pro文件4. 日志记录器的配置5. 运行程序6. 启用行号和文件名C…

Why is OpenAI image generation Api returning 400 bad request in Unity?

题意&#xff1a;为什么 OpenAI 图像生成 API 在 Unity 中返回 400 Bad Request 错误&#xff1f; 问题背景&#xff1a; Im testing out dynamically generating images using OpenAI API in Unity. Amusingly, I actually generated most of this code from chatGPT. 我正在…

idea中.git文件夹存在但是没有git功能列表

1.问题&#xff1a; 该项目中已经将.git文件夹置入了&#xff0c;但是idea中却没有git相关的功能列表&#xff0c;如图&#xff1a; 2.解决办法&#xff1a; 在【文件】-【设置】-【版本控制】-【目录映射】中添加目录映射应用就好了 &#xff08;【File】 -> 【S…

网络资源模板--Android Studio 图书借阅App

目录 一、项目演示 二、项目测试环境 三、项目详情 四、完整的项目源码 一、项目演示 网络资源模板--图书借阅App 二、项目测试环境 三、项目详情 首页 这段代码是一个 Android 应用的 MainActivity 类&#xff0c;功能简要总结如下&#xff1a; 1. **界面设置**&#xf…

Hutool:Java开发者的瑞士军刀

有想念&#xff0c;才是团圆&#xff1b;在一起&#xff0c;便是中秋。 在Java的世界里&#xff0c;有这样一个工具库&#xff0c;它小巧而强大&#xff0c;功能丰富且易于使用&#xff0c;它就是Hutool。Hutool是一个Java工具包&#xff0c;旨在减少Java开发人员在开发过程中…

Oracle数据库逻辑与物理结构操作

一、实验步骤 1、查询所有DBA和USER开头的静态数据字典 2、查询所有V$动态性能视图 3、查询当前数据库中的表空间信息 ①查询和TABLESPACE相关的数据字典 ②通过动态性能视图查询表空间信息 ③通过数据字典查询表空间信息 4、操作数据文件 &#xff08;1&#xff09;向 ORC…

JavaWeb JavaScript 11.XML —— 配置文件

生活想埋没我&#xff0c;没想到我是颗种子 —— 24.9.19 一、XML 1.什么是XML XML是EXtensible Markup Languge的缩写&#xff0c;翻译过来就是可扩展标记语言。所以很明显&#xff0c;XML和HTML一样都是标记语言&#xff0c;也就是说它们的基本语法都是标签 可扩展 三个字…

网络:UDP协议

个人主页 &#xff1a; 个人主页 个人专栏 &#xff1a; 《数据结构》 《C语言》《C》《Linux》 文章目录 前言UDP协议报头和有效载荷分离的问题有效载荷向上交付的问题&#xff0c;也就是交给哪个进程&#xff1f;怎么确定把报文收全了&#xff1f;UDP报头是如何封装的呢&…

JavaWeb纯小白笔记02:Tomcat的使用:发布项目的三种方式、配置虚拟主机、配置用户名和密码

通过Tomcat进行发布项目的目的是为了提供项目的访问能力&#xff1a;Tomcat作为Web服务器&#xff0c;能够处理HTTP请求和响应&#xff0c;将项目的内容提供给用户进行访问和使用。 一.Tomcat发布项目的三种方式&#xff1a; 第一种&#xff1a;直接在Tomcat文件夹里的webapp…

数学建模 第一讲 - 概论

一、什么是数学模型 一个栗子 例 1.1 一只装满水的圆柱型桶&#xff0c;底半径为 1米&#xff0c;高为 2米&#xff0c;底部有一直径为 0.1 米的洞。问桶流空要多少时间? 数学模型是对于一个特定的对象为了一个特定目标&#xff0c;根据事物的内在规律&#xff0c;作出一些必…