什么是模型复杂度?比较线性回归与决策树与随机森林
yuyutoo 2024-12-15 17:41 2 浏览 0 评论
使用模拟数据集测试简单和复杂机器学习模型的实用指南。
机器学习模型是一种学习数据集的输入(独立)特征与目标(独立)特征之间关系的系统,可用于将来进行预测。为了测试模型的有效性,引入了一个全新的类似数据集,其中仅包含输入特征,并且模型应基于在训练过程中获得的见解来预测目标变量。然后使用适当的性能指标来比较预测值与实际目标值的匹配程度。在本文中,我们将测试三种复杂度各异的流行模型的有效性。
· 线性回归
· 决策树
· 随机森林
然后,我们将使用两个度量系统检查它们的性能:均方误差和均值绝对误差。
为了实现上述目的,我们需要一个数据集,我们将自己创建一个全新的数据集。要了解为什么创建自己的数据集,让我们首先了解什么是机器学习。机器学习是识别数据模式的过程。您可以将模式视为"事物运作的方式"。机器学习通过了解特征(X)和标签(y)之间的关系来做到这一点。一些模式很简单,例如高温导致冰淇淋销量增加是简单的线性关系,而其他模式则很复杂,例如关于房屋的详细信息以及它们如何影响房价,这就是机器学习的亮点。就我而言,我创建了一个数据集,其中X和y特征之间的关系是余弦曲线。
步骤1:数据集模拟
总的来说,一切都有一定的工作方式,一个好的模型应该揭示这种模式。在我们的例子中,"真实状态"是余弦曲线,即y = cos(x)。然后,我们将添加一些噪声来模拟"真实状态"值,因为现实世界中的情况永远都不是完美的。
第一步是初始化我们的x值。我使用了np.linspace(开始,结束,长度)。我们希望我们的轴从0开始,以2 * pi(即6.3)结束,并具有100个均匀间隔的步距。
x = np.linspace(0, 2*np.pi, 100)
为了获得上面的真实余弦曲线,我使用了y = np.cos(x)。但是,我们将在cos曲线周围的数据中添加噪声,以创建模拟的y值。
true_y = np.cos(x)
为了产生噪音,我使用了np.random.normal(mean,std,length)。这将创建以均值为中心的正态分布随机值,并且仅以std(标准差)与均值发生变化。我将0用作平均值,将0.5用作std,因此噪声值将在-0.5至0.5之间。我将随机种子设置为567,以便所产生的样本噪声可再现,否则,每次运行代码时,都会产生新数据。
np.random.seed(567)
noise = np.random.normal(0, 0.5, 100)
最后一步是将真实的y映射添加到噪声中以创建目标变量y。
y = np.cos(x) + noise
现在我们的值已经准备好,我们将创建一个数据框来保存x和y值。我们将之称为数据框训练,因为这将是训练模型的训练集。
train = pd.DataFrame({'x':x, 'y':y})
现在,我们可以绘制余弦曲线(真实关系)和模拟训练数据。
plt.scatter(train.x, train.y)
plt.plot(train.x, np.cos(train.x), color='k')
plt.xlabel('x')
plt.ylabel('y')
plt.show()
测试集
我们还将模拟一个测试集。这对于通过使用测试集中看不见的x值检查模型可以很好地预测y值来测试模型的有效性非常重要。除了使用不同的随机种子765产生的噪声外,我们创建与训练数据完全相同的测试集。
x = np.linspace(0, 2*np.pi, 100)
np.random.seed(765)
noise = np.random.normal(0, 0.5, 100)
y = np.cos(x)+noise
test = pd.DataFrame({'x':x, 'y':y})
让我们一起绘制训练图(蓝点)和测试图(红点)。
步骤2:建立模型
简单线性回归
该模型拟合数据的直线。y ^ =β0+β1x是表示简单线性回归模型的公式;β0是y截距,β1是x的系数,即直线的斜率。y ^是预测值。截距和系数由模型从数据中获知。因此,该模型的任务是获得代表数据中真实模式的β0和β1的最佳估计。
我使用sci-kit learn实现模型。首先,我们导入库,然后初始化模型的实例。
from sklearn.linear_model import LinearRegression
basic_linear_model = LinearRegression()
接下来,我们将特征(x)与数据集中的目标变量(y)分开。我使用了df.drop('y',axis = 1)。通常的做法是仅删除(删除)目标特征并将其余的列用作输入特征。
features = train.drop('y', axis=1)
target = train.y
最后一步是使模型适合数据。这也称为训练模型,并确定β0和β1的最佳估计。
basic_linear_model.fit(features, target)
您可以通过调用线性回归模型的intercept_和coef_方法来获得β0和β1。
print(basic_linear_model.intercept_)
print(basic_linear_model.coef_)
### Results
0.09271652228649466
[-0.0169538]
为了进行预测,我们使用model.predict(features)。基本函数为β0+β1x,因此我们的预测由一条直线表示,我们可以绘制该直线以及模拟数据集。
y_preds = basic_linear_model.predict(features)
plt.scatter(df.x, df.y)
plt.plot(df.x, y_preds, 'k')
plt.show()
如观察到的,线性回归模型假设数据中存在线性关系,这对于我们的数据而言不是很好的表示。
多项式线性回归-增加复杂度
与简单的线性回归不同,多项式模型通过添加x的多项式因子(例如x2)来向数据添加曲线。
首先,通过将x2作为另一列添加到我们的数据集中,创建一个二阶多项式模型。我们将新列称为x2,现在公式为y ^ =β0+β1x+β2x2。
我创建了数据框的副本以保留原始副本。为了得到x2,我使用了np.power(value,power)
df2 = train.copy()df2['x2'] = np.power(df2['x'], 2)
创建可重用函数:为了避免编写大量代码,我创建了一个函数,该函数初始化模型,将数据集分为特征和目标变量,然后绘制模型的预测。该函数接收一个数据框和一个模型,然后返回经过训练的模型。
def model_fitter(data, model):
features = data.drop('y', axis=1)
target = data.y
model.fit(features, target)
y_preds = model.predict(features)
plt.scatter(data.x, data.y)
plt.plot(data.x, y_preds, 'r--')
return model
现在让我们调用函数并创建我们的二阶多项式模型。
polynomial_second_order = model_fitter(df2, LinearRegression())
哇,看那个!它很好地模拟了数据中的曲线。但是,当我们对全新的看不见的数据进行预测时,我们将了解更多。
我还创建了一个更复杂的三阶多项式模型,其结果几乎与二阶模型相同。通常,如果两个模型的性能相同,则最好选择不太复杂的模型,因为它通常可以更好地推广到新数据。
决策树
决策树通过基于目标变量将数据分为子集来构建模型。这种分支性质允许在数据中建立非常复杂的关系。我们将首先创建一个没有任何参数的决策树。这将创建一个不受约束的决策树,该决策树将继续分裂为越来越小的子集,直到最终叶节点只有1个值。
from sklearn.tree import DecisionTreeRegressor
decision_tree_unconstrained = model_fitter(train,DecisionTreeRegressor())
这些线代表我们的预测值,很明显,该模型已完全了解了训练数据并完美地预测了所有点。这称为过拟合,当提供新数据时,该模型将无法很好地概括。模型的想法是忽略噪声并学习实际信号,但是该模型也学习了噪声。
深度限制决策树
通过限制决策树可以下降到的级别数,我们将为决策树增加一些复杂性。在我们的例子中,我们将最大深度设置为3,这意味着该树将只能向下分支3个级别,然后才能进行预测。
decision_tree_by_depth = model_fitter(train,DecisionTreeRegressor(max_depth = 3))
这是更好的表现。您可以通过步骤看到决策树的分支性质,这与多项式线性回归的平滑曲线不同。让我们使用另一个参数来约束模型。
逐叶约束决策树
在这里,我们将每个叶子在达到预测值之前可以拥有的最小样本数设置为5.这意味着最小子集将具有5个x值,从而避免了我们在无约束决策树中有每个叶子一个样本的情况。节点。
decision_tree_by_leaf = model_fitter(train,DecisionTreeRegressor(min_samples_leaf = 5))
决策树可以使用几个参数。选择最佳模型参数的过程称为超参数优化或调整。
随机森林
您可以将随机森林视为决策树的集合。
随机森林并行训练许多决策树。每个决策树仅在观察值的随机子集上进行训练,并且将预测合并到一个决策树中。这对于防止过度安装非常有效。我们需要在初始化模型时设置random_state以获得可重现的结果,因为每棵树都是在一组随机观测值上训练的。
from sklearn.ensemble import RandomForestRegressor
random_forest_unconstrained = model_fitter(train,
RandomForestRegressor(random_state=111))
不受约束的随机森林仍然是过拟合的,但不如不受约束的决策树那么多。
我们也可以像决策树一样约束随机森林。max_depth = 3和min_samples_leaf = 5。
random_forest_by_depth = model_fitter(train,
RandomForestRegressor(random_state=111,
max_depth=3))
random_forest_by_leaf = model_fitter(train,
RandomForestRegressor(random_state=111,
min_samples_leaf=5))
正如上面的约束随机森林所观察到的,与以步骤显示的决策树相比,预测曲线具有一般的平滑效果。这是因为随机林木是在观测的子集上训练的,然后将这些预测组合起来以创建更好的广义预测。
我们仅探讨了随机森林的两个参数;max_depth和min_samples_leaf。在此处找到扩展列表。
步骤3:在看不见的测试数据集上测试模型性能
我们将使用两种常用的回归机器学习指标来评估模型:均方误差(MSE)和均值绝对误差(MAE)。MSE取平方误差的平均值,并且较大的误差会按比例放大,因此,由于指数的影响,会受到更多的惩罚。MAE取绝对误差的平均值。较低的MSE和MAE是首选。
一般而言,MSE的计算速度要快一些,而MAE则更易于解释。
from sklearn.metrics import mean_squared_error
from sklearn.metrics import mean_absolute_error
现在让我们对测试数据进行预测。我创建了一个函数来使其自动化。该函数接收测试数据集,训练好的模型以及要打印的名称。它将测试集分为特征和目标变量,对测试集进行预测,计算MAE和MSE并打印出来。
def model_performance(data, model, name):
test_features = data.drop('y', axis=1)
test_target = data.y
test_preds = model.predict(test_features)
mae = mean_absolute_error(test_preds, test_target)
mse = mean_squared_error(test_preds, test_target)
print(name)
print('MAE', np.round(mae,3))
print('MSE', np.round(mse, 3))
对于二阶多项式线性模型,我们需要通过将另一列添加到包含x2值的测试数据中来设计与训练数据集相同的功能。我们将首先创建测试数据的副本,然后添加x2列。
test2 = test.copy()
test2['x2'] = np.power(test2.x, 2)
现在,我们将为每个模型运行该函数,并返回均方误差和均值绝对误差。
model_performance(test, basic_linear_model, 'Basic linear regression')
model_performance(test2, polynomial_second_order, 'Second Order Polynomial Model')
model_performance(test, decision_tree_unconstrained, 'Uncontrained Decision Tree Model')
model_performance(test, decision_tree_by_depth, 'Decision Tree Constrained by max_depth = 3')
model_performance(test, decision_tree_by_leaf, 'Decision Tree Constrained by min_samples_leaf = 5')
model_performance(test, random_forest_unconstrained, 'Unconstrained Random Forest')
model_performance(test, random_forest_by_depth, 'Random Forest Constrained by max_depth = 3')
model_performance(test, random_forest_by_leaf, 'Random Forest Constrained by min_samples_leaf = 5')
以下是结果
Basic linear regression
MAE 0.677
MSE 0.669
Second Order Polynomial Model
MAE 0.427
MSE 0.277
Uncontrained Decision Tree Model
MAE 0.523
MSE 0.434
Decision Tree Constrained by max_depth = 3
MAE 0.441
MSE 0.289
Decision Tree Constrained by min_samples_leaf = 5
MAE 0.427
MSE 0.287
Unconstrained Random Forest
MAE 0.47
MSE 0.333
Random Forest Constrained by max_depth = 3
MAE 0.424
MSE 0.28
Random Forest Constrained by min_samples_leaf = 5
MAE 0.416
MSE 0.276
我们可以看到,对于这两个指标,受叶子约束的随机森林的误差最小,因此表现最佳。不出所料,简单线性回归的表现最差,因为数据显然缺乏线性关系。但是,即使曲线看起来拟合得很好,二阶多项式模型还是表现第二好的模型。这说明了为什么随机森林在应用机器学习中如此广泛地被使用。
在本文中,我们模拟了训练和测试数据集,拟合了各种模型(线性模型和基于树的模型),并探讨了各种模型的复杂性;从简单的线性模型到高阶多项式模型,以及受约束的决策树和随机森林。在实践中,您可以基于其他函数(例如y = np.sin(x)或正切的正弦)模拟数据集;y = np.tan(x)。在github上获取完整的代码。https://github.com/suemnjeri/medium-articles/blob/main/Cosine%20Simulated%20Data%20for%20medium%202.ipynb
(本文由闻数起舞翻译自Susan Maina的文章《What is Model Complexity? Compare Linear Regression to Decision Trees to Random Forests》,转载请注明出处,原文链接:https://towardsdatascience.com/what-is-model-complexity-compare-linear-regression-to-decision-trees-to-random-forests-7ec837b062a9)
相关推荐
- YAML配置文件简介及使用(yaml 配置)
-
简介YAML是"YAMLAin'taMarkupLanguage"(YAML不是一种标记语言)的缩写。相比JSON格式的方便。...
- 教你如何解决最常见的58种网络故障排除方法
-
1.故障现象:网络适配器(网卡)设置与计算机资源有冲突。分析、排除:通过调整网卡资源中的IRQ和I/O值来避开与计算机其它资源的冲突。有些情况还需要通过设置主板的跳线来调整与其它资源的冲突。2.故障现...
- 一分钟带你了解服务器网卡(服务器网卡怎么用)
-
今天小编和大家聊一下服务器的网卡。什么是网卡?简单说网卡就是计算机与局域网互连的设备。计算机主要通过网卡接入网络。网卡又称为网络适配器或网络接口卡NIC(NetworkinterfaceCard)...
- linux文件之ssh配置文件的含义与作用
-
ssh远程登录命令是操作系统(包括linux和window系统)下常用的操作命令,可以帮助用户,远程登录服务器系统,查看,操作系统相关信息。linux系统对于ssh命令有专门保存其相关配置的目录和文件...
- Cilium 官方文档翻译 - IPAM(二)Kubernetes Host模式
-
KubernetesHostScopeciliumIPAM的kuberneteshost-scope模式通过选项ipam:kubernetes开启,将集群IP地址分配委托给每个独立的节点,并...
- 域名劫持跳转,域名劫持跳转的解决办法只需5步
-
简单来说,域名劫持就是把原本准备访问某网站的用户,在不知不觉中,劫持到仿冒的网站上,例如用户准备访问某家知名品牌的网上商店,黑客就可以通过域名劫持的手段,把其带到假的网上商店,同时收集用户的ID信息和...
- Linux 磁盘和文件系统管理(linux磁盘管理fdisk)
-
1检测并确认新硬盘...
- windows host文件怎么恢复?局域网访问全靠这些!
-
windowshost文件怎么恢复?windowshost文件是常用网址域名及其相应IP地址建立一个关联文件,通过这个host文件配置域名和IP的映射关系,以提高域名解析的速度,方便局域网用户使用...
- Nginx配置文件详解与优化建议(nginx 配置详解)
-
1、概述今天来详解一下Nginx的配置文件,以及给出一些配置建议,希望能对大家有所帮助。...
- Mac电脑hosts文件锁定,如何修改hosts文件权限
-
有时候我们需要修改hosts文件,但是网上很多教程都行不通,使用sudo命令也不行。其实有一个很简单的方法。打开终端命令行,使用如下命令即可:sudochflags-hvnoschg/etc/...
- windows电脑如何修改hosts文件?(windows 修改hosts文件)
-
先来简单说下电脑host的作用hosts文件的作用:hosts文件是一个用于储存计算机网络中各节点信息的计算机文件;作用是将一些常用的网址域名与其对应的IP地址建立一个关联“数据库”,当用户在浏览器中...
- Vigilante恶意软件行为怪异:修改Hosts文件以阻止受害者访问盗版网站
-
Sophos刚刚报道了一款名叫Vigilante的恶意软件,但其行为却让许多受害者感到不解。与其它专注于偷密码、搞破坏、或勒索赎金的恶意软件不同,Vigilante会通过修改Hosts文件...
- hosts文件无法修改几种现象和解决方法
-
第一种、hosts文件修改完不是直接保存而是弹出另存为窗口解决:1、右击hosts文件——属性——把“只读”前面勾去掉。第二种、打开hosts文件时提示“你没有权限打开该文件,请向文件的所有者或管理员...
- hosts文件位置在哪里,教你hosts文件位置在哪里
-
Hosts是一个没有扩展名的系统文件,其基本作用就是将一些常用的网址域名与其对应的IP地址建立一个关联"数据库",当用户在浏览器中输入一个需要登录的网址时,系统会首先自动从Hosts文件中寻找对应的I...
你 发表评论:
欢迎- 一周热门
-
-
前端面试:iframe 的优缺点? iframe有那些缺点
-
带斜线的表头制作好了,如何填充内容?这几种方法你更喜欢哪个?
-
漫学笔记之PHP.ini常用的配置信息
-
其实模版网站在开发工作中很重要,推荐几个参考站给大家
-
推荐7个模板代码和其他游戏源码下载的网址
-
[干货] JAVA - JVM - 2 内存两分 [干货]+java+-+jvm+-+2+内存两分吗
-
正在学习使用python搭建自动化测试框架?这个系统包你可能会用到
-
织梦(Dedecms)建站教程 织梦建站详细步骤
-
2024PHP在线客服系统源码+完全开源 带详细搭建教程
-
【开源分享】2024在线客服系统PHP源码(安装教程+全新UI)
-
- 最近发表
- 标签列表
-
- mybatis plus (70)
- scheduledtask (71)
- css滚动条 (60)
- java学生成绩管理系统 (59)
- 结构体数组 (69)
- databasemetadata (64)
- javastatic (68)
- jsp实用教程 (53)
- fontawesome (57)
- widget开发 (57)
- vb net教程 (62)
- hibernate 教程 (63)
- case语句 (57)
- svn连接 (74)
- directoryindex (69)
- session timeout (58)
- textbox换行 (67)
- extension_dir (64)
- linearlayout (58)
- vba高级教程 (75)
- iframe用法 (58)
- sqlparameter (59)
- trim函数 (59)
- flex布局 (63)
- contextloaderlistener (56)