如何使用线性模型的【分箱】操作处理非线性问题

news2024/11/20 12:29:52

让线性回归在非线性数据上表现提升的核心方法之一是对数据进行分箱,也就是离散化。与线性回归相比,我们常用的一种回归是决策树的回归。为了对比不同分类器和分箱前后拟合效果的差异,我们设置对照实验。

生成一个非线性数据集前,先导入相应的模块和类:

import numpy as np
import matplotlib.pyplot as plt
from sklearn.linear_model import LinearRegression
from sklearn.tree import DecisionTreeRegressor

设置X的值:

rnd = np.random.RandomState(42) #设置随机数种子
X = rnd.uniform(-3, 3, size=100) #random.uniform,从输入的任意两个整数中取出size个随机数

设置Y值:

#生成y的思路:先使用NumPy中的函数生成一个sin函数图像,然后再人为添加噪音
y = np.sin(X) + rnd.normal(size=len(X)) / 3 #random.normal,生成size个服从正态分布的随机数

画图:

#使用散点图观察建立的数据集是什么样子
plt.scatter(X, y,marker='o',c='k',s=20)
plt.show()

通过在正弦曲线周围添加噪声,我们生成了上图。将数据转为二维后再训练数据:

X = X.reshape(-1, 1)

用不同的分类器训练数据,建立模型:

#使用原始数据进行建模
LinearR = LinearRegression().fit(X, y)
TreeR = DecisionTreeRegressor(random_state=0).fit(X, y)

接下来做对比实验:

#放置画布
fig, ax1 = plt.subplots(1)

#创建测试数据:一系列分布在横坐标上的点
line = np.linspace(-3, 3, 1000, endpoint=False).reshape(-1, 1)

#将测试数据带入predict接口,获得模型的拟合效果并进行绘制
ax1.plot(line, LinearR.predict(line), linewidth=2, color='green',
         label="linear regression")
ax1.plot(line, TreeR.predict(line), linewidth=2, color='red',
         label="decision tree")

#将原数据上的拟合绘制在图像上
ax1.plot(X[:, 0], y, 'o', c='k')

#其他图形选项
ax1.legend(loc="best")
ax1.set_ylabel("Regression output")
ax1.set_xlabel("Input feature")
ax1.set_title("Result before discretization")
plt.tight_layout()
plt.show()

#从这个图像来看,可以得出什么结果?

       结果分析:从图像上可以看出,线性回归无法拟合出这条带噪音的正弦曲线的真实面貌,只能够模拟出大概的趋势,而决策树却通过建立复杂的模型将几乎每个点都拟合出来了。此时此刻,决策树处于过拟合的状态,对数据的学习过于细致, 而线性回归处于拟合不足的状态,这是由于模型本身只能够在线性关系间进行拟合的性质决定的。为了让线性回归在类似的数据上变得更加强大,我们可以使用分箱,也就是离散化连续型变量的方法来处理原始数据,以此来提升线性回归的表现。在应用分箱之前,我们先来讲解什么是分箱:

假设现在的X有100条数据,我们把它转换成二维矩阵:

然后导入分箱的类,实例化后对X进行分箱后将值赋给X_binned:

from sklearn.preprocessing import KBinsDiscretizer

#将数据分箱
enc = KBinsDiscretizer(n_bins=10 #分几类?
                       ,encode="onehot") #ordinal
X_binned = enc.fit_transform(X)

可以看到分箱后的结果是生成了一个100行,10列的列表。我们可以这样来理解分箱的过程:

在这个过程中,每个观察值都被分配到一个"箱子"中,通过创建一个新的二进制特征来表示这个观察值是否在这个箱子中。例如,一个连续的特征,我们创建10个"箱子",每个箱子代表一个范围。然后,对于每个观察值,你会创建一个10维的向量,其中9个元素为0,只有一个元素为1,表示这个观察值落在哪个箱子中。在这个列表中,行索引代表数据点,列索引代表哪个箱子,数据点在哪个箱子,哪个箱子的值就为1,。

接下来,我们做一个对比实验,来判断分箱前后的拟合效果差异,图一是分箱前,图二是分箱后:

#准备数据
enc = KBinsDiscretizer(n_bins=10,encode="onehot")
X_binned = enc.fit_transform(X)
line_binned = enc.transform(line)通常在训练数据上使用fit_transform,在测试数据上使用transform

#将两张图像绘制在一起,布置画布
fig, (ax1, ax2) = plt.subplots(ncols=2
                               , sharey=True #让两张图共享y轴上的刻度
                               , figsize=(10, 4))

#在图1中布置在原始数据上建模的结果
ax1.plot(line, LinearR.predict(line), linewidth=2, color='green',
         label="linear regression")
ax1.plot(line, TreeR.predict(line), linewidth=2, color='red',
         label="decision tree")
ax1.plot(X[:, 0], y, 'o', c='k')
ax1.legend(loc="best")
ax1.set_ylabel("Regression output")
ax1.set_xlabel("Input feature")
ax1.set_title("Result before discretization")

#使用分箱数据进行建模
LinearR_ = LinearRegression().fit(X_binned, y)
TreeR_ = DecisionTreeRegressor(random_state=0).fit(X_binned, y)

#进行预测,在图2中布置在分箱数据上进行预测的结果
ax2.plot(line #横坐标
         , LinearR_.predict(line_binned) #分箱后的特征矩阵的结果
         , linewidth=2
         , color='green'
         , linestyle='-'
         , label='linear regression')

ax2.plot(line, TreeR_.predict(line_binned), linewidth=2, color='red',
         linestyle=':', label='decision tree')

#绘制和箱宽一致的竖线
ax2.vlines(enc.bin_edges_[0] #x轴
           , *plt.gca().get_ylim() #y轴的上限和下限
           , linewidth=1
           , alpha=.2)

#将原始数据分布放置在图像上
ax2.plot(X[:, 0], y, 'o', c='k')

#其他绘图设定
ax2.legend(loc="best")
ax2.set_xlabel("Input feature")
ax2.set_title("Result after discretization")
plt.tight_layout()
plt.show()

       从图像上可以看出,离散化后线性回归和决策树上的预测结果完全相同——线性回归比较成功地拟合了数据的分布,而决策树的过拟合效应也减轻了。由于特征矩阵被分箱,因此特征矩阵在每个区域内获得的值是恒定的,因此所有模型对同一个箱中所有的样本都会获得相同的预测值。与分箱前的结果相比,线性回归明显变得更加灵活,而决策树的过拟合问题也得到了改善。但注意,一般来说我们不使用分箱来改善决策树的过拟合问题,因为树模型带有丰富而有效的剪枝功能来防止过拟合。

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

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

相关文章

Java计算数据百分比

public class CalculatePCT {public static void main(String[] args) {System.out.println(getPercent(9, 100));System.out.println(getPercent2(3, 7));}/*** 方式一:使用java.text.NumberFormat实现*/public static String getPercent(int x, int y) {double d1…

ACM练习——第二天

今天又是一天课,满课,很累哈,计组真的挺难的,但是多学学还是可以学明白。行吧,继续进入今天的ACM练习,现阶段都是主要练习Java到C的语言过渡。 因为今天的题目多半都是昨天的延伸,我就不提供Jav…

Java主流分布式解决方案多场景设计与实战

Java的主流分布式解决方案的设计和实战涉及到多个场景,包括但不限于以下几点: 分布式缓存:在Java的分布式系统中,缓存是非常重要的一部分。常用的分布式缓存技术包括Redis、EhCache等。这些缓存技术可以用来提高系统的性能和响应…

2023软件测试面试跳槽必备

你眼中的软件测试岗位是怎样的?大部分人可能会给出这样的回答:“测试?简单啊,没什么技术含量,无非就是看需求、看业务手册、看设计文档、然后点点功能是否实现,麻烦点的就是测试下部署安装是否出现兼容性问…

开讲:长江航道工程局举办首届云表无代码培训班

11月9日至10日,公司联合珠海乐图软件有限公司在总部机关举办了首届云表无代码编程开发初级培训班。公司所属单位工程、成本、财务等相关业务部门及项目部管理人员参加培训,公司总工程师张晏方作开班动员讲话。 张晏方指出,公司自主开发的云表…

java生成docx文档, docx文档动态饼图

背景: 最近接了个需求, 要求生成日报, 大概如下图所示: 其中*表示变量, 看到要动态生成doc给我难受坏了,为什么会有这种需求? 然后看到里面还要动态生成饼图, oh, no.........没有办法, 硬着头皮上吧. 于是就搜了下java生成docx的方式, 看到的, 比较靠谱的一种通过freemake…

【每日一题】1334. 阈值距离内邻居最少的城市-2023.11.14

题目: 1334. 阈值距离内邻居最少的城市 有 n 个城市,按从 0 到 n-1 编号。给你一个边数组 edges,其中 edges[i] [fromi, toi, weighti] 代表 fromi 和 toi 两个城市之间的双向加权边,距离阈值是一个整数 distanceThreshold。 …

[Linux] ssh远程访问及控制

一、ssh介绍 1.1 SSH简介 SSH(Secure Shell)是一种安全通道协议,主要用于实现远程登录、远程复制等功能的字符接口。SSH 协议包括用户在登录时输入的用户密码、双方之间的通信。 加密数据传输,SSH 是一种建立在应用层和传输层上…

<MySQL> 查询数据进阶操作 -- 聚合查询

目录 一、聚合查询概述 二、聚合函数查询 2.1 常用函数 2.2 使用函数演示 2.3 聚合函数参数为*或列名的查询区别 2.4 字符串不能参与数学运算 2.5 具有误导性的结果集 三、分组查询 group by 四、分组后条件表达式查询 五、MySQL 中各个关键字的执行顺序 一、聚合查询…

【2013年数据结构真题】

highlight: a11y-dark 41题 王道解析: 算法的策略是从前向后扫描数组元素,标记出一个可能成为主元素的元素Num 。然后重新计数,确认Num是否是主元素。算法可分为以下两步: 选取候选的主元素:依次扫描所给数组中的每个…

【数据结构 | 链表】leetcode 2. 两数相加

个人主页:兜里游客棉花糖 欢迎 点赞👍 收藏✨ 留言✉ 加关注💓本文由 兜里游客棉花糖 原创 收录于专栏【LeetCode】 原题链接:点击直接跳转到该题目 目录 题目描述解题代码 题目描述 给你两个 非空 的链表,表示两个非…

降低城市内涝风险,万宾科技内涝积水监测仪的作用

频繁的内涝会削弱和损坏城市的关键基础设施,包括道路、桥梁和公用设施。城市内涝风险降低可以减少交通中断事件,也可以保护居民安全并降低路面维修等成本,进一步确保城市基本服务继续发挥作用。对城市可持续发展来讲有效减少内涝的风险是重要…

ESP32网络开发实例-将DS18B20传感器读数发送到InfluxDB

将DS18B20传感器读数发送到InfluxDB 文章目录 将DS18B20传感器读数发送到InfluxDB1、InfluxDB、DS18B20介绍2、软件准备3、硬件准备4、代码实现在本文中,我们将介绍如何将 DS18B20传感器读数发送到 InfluxDB 时间序列数据库。 使用 InfluxDB 数据库的一大特点是可以在确定的时…

python 爬虫之requests 库以及相关函数的详细介绍

get 函数 当你使用 requests.get 函数时,你可以按照以下步骤来发起一个 GET 请求: 导入 requests 模块: 在你的 Python 脚本或程序中,首先导入 requests 模块。 import requests指定目标 URL: 设置你要请求的目标 URL…

4路光栅尺磁栅尺编码器解码转换5MHz高速差分信号转Modbus TCP网络模块 YL97-RJ45

特点: ● 光栅尺磁栅尺解码转换成标准Modbus TCP协议 ● 光栅尺5V差分信号直接输入,4倍频计数 ● 模块可以输出5V的电源给光栅尺供电 ● 高速光栅尺磁栅尺计数,频率可达5MHz ● 支持4个光栅尺同时计数,可识别正反转 ● 可网…

啊?印第安碳纤维限量款?复古与性能的结合吗Indian FTR x 100% R Carbon

印第安作为美国的老牌摩托车厂大家都不陌生了,和哈雷有一点比较大的区别是印第安的车还是考虑马力性能的,也是敢于标出自己的马力参数数据,就比如印第安的FTR系列。 以泥地赛道为灵感设计的印第安FTR运动街车发布了最新的限量联名款车型&…

spring cloud alibaba 简介

微服务搭建组件选型 1.服务注册中心 Nacos(spring-cloud-alibaba) 2.服务通信 OpenFeign(spring-cloud) 3.服务熔断、降级、限流 Sentinel(spring-cloud-alibaba) 4.网关 Gateway(spring-cloud) 5.服务配置中心 …

ARM64 linux并发与同步之经典自旋锁

1.3 经典自旋锁 在实际项目中临界区数据有可能会修改一个数据结构或者链表中的数据,在整个过程中要保证原子性,才不会影响数据的有效性,这个过程使用原子变量不合适,需要使用锁机制来完成,自旋锁(spinlock&…

深度学习实战59-NLP最核心的模型:transformer的搭建与训练过程详解,手把手搭建与跑通

大家好,我是微学AI,今天给大家介绍一下深度学习实战59-NLP最核心的模型:transformer的搭建与训练过程详解,手把手搭建与跑通。transformer是一种基于自注意力机制的深度学习模型,由Vaswani等人在2017年的论文《Attention is All You Need》中提出。它最初被设计用来处理序…

香港科技大学广州|机器人与自主系统学域博士招生宣讲会—电子科技大学专场!!!(暨全额奖学金政策)

在机器人和自主系统领域实现全球卓越—机器人与自主系统学域 硬核科研实验室,浓厚创新产学研氛围! 教授亲临现场,面对面答疑解惑助攻申请! 一经录取,享全额奖学金1.5万/月! 🕙时间:…