什么是模型复杂度?比较线性回归与决策树与随机森林
yuyutoo 2024-12-15 17:41 1 浏览 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)
相关推荐
- 了解 SQL 语言特点、分类及规则
-
SQL语言概述SQL全称是结构化查询语言(structuredQueryLanguage),它是一种在关系型数据库中定义和操纵数据的标准语言。最早是由IBM的圣约瑟(Sanjose)研究...
- SQL的语言规范及分类详解
-
SQL:StructureQueryLanguage结构化查询语言,它是使用关系模型的数据库应用语言,由IBM上世纪70年代开发出来。后由美国国家标准局(ANSI)开始着手制定SQL标准,先后有S...
- 2分钟,快速认识什么是SQL
-
结构化查询语言,简称SQL,它是与关系数据库管理系统通信的黄金标准语言。今天就来一起快速认识一下什么是SQL,您可以通过以下的文字内容学习,也可以通过文末的视频学习,希望本文对您有所帮助。...
- SQL语言书写与规则详解
-
SQL语言SQL语言主要包含6个部分,什么是SQL语言?SQL语言被称之为结构化查询语言(StructuredQueryLanguage),它是关系型数据库的**标准语言[所有数据库厂商都要遵守S...
- SQL知识大全(一):数据库的语言分类你都知道吗?
-
点击上方蓝字关注我们今天是数据库语言分类的第一讲,主要会介绍数据库的四类语言,以及其语法,课程大纲详见脑图。...
- 数据查询语言SQL基本语法
-
SQL(StructuredQueryLanguage)即结构化查询语言,是用来管理和处理关系型数据库的标准计算机语言。其语法非常丰富,允许用户执行各种操作,包括但不限于查询、插入、更新和删除数据...
- SQL(structured query language)语言
-
SQL(structuredquerylanguage)关系数据库标准语言-SQL数据库是表的汇集,它用一个或多个SQL模型定义-基本表是实际存储在数据库中的表,视图是由若干个基本表或其他视图导出...
- SQL查询逻辑执行顺序:从FROM到LIMIT,步步解析
-
SQL(StructuredQueryLanguage)作为关系型数据库的标准语言,被广泛应用于数据查询和管理。虽然我们通常按照...
- SQL大宝剑-已燃尽所有SQL的理解
-
作者:京东物流向往一、背景从事数据开发将近四年,过程中有大量任务交接或阅读同事代码的场景。在这些场景中发现有些SQL读起来赏心悦目,可以一目了然地了解业务逻辑,一些复杂的业务需求实现方法也可以做到简...
- 《图解SQL:数据库语言轻松入门》
-
《图解SQL:数据库语言轻松入门》当初入手这本书的时候,我还是蛮有勇气的。毕竟我是一个除了数据库三个汉字会写之外,对数据库一无所知的人。当时我是想到了一个故事,才决定入手这本书的。这个故事你小时候应该...
- 【数据管理】数据库通用概念和常用SQL讲解
-
数据库是计算机领域的专业词汇,大部分人也许觉得和数据库没有交集。但其实每天,甚至连你自己都没有意识到,我们一直在使用数据库。淘宝购物挑选的商品信息,手机通讯录里面的联系人,微信发送的聊天记录等,数据都...
- 慢 SQL 分析与优化
-
背景介绍从系统设计角度看,一个系统从设计搭建到数据逐步增长,SQL执行效率可能会出现劣化,为继续支撑业务发展,我们需要对慢SQL进行分析和优化,严峻的情况下甚至需要对整个系统进行重构。所以我们往...
- SQL学习:实例讲解SQL必会的12个高频语句
-
在数据库查询中,总结了12个高频常用SQL语句,供大家参考学习:1、复制表结构,不包括数据(用于建立同一个表结构)...
- SQL语言包括哪几部分?每部分都有哪些操作关键字?
-
【死记硬背】SQL即StructuredQueryLanguage结构化查询语言,包括数据定义(DDL)、数据操纵(DML)、数据查询(DQL)、数据控制(DCL)、事物控制(TCL)和指针控制(...
- 数据库中sql语句大全
-
结构化查询语言(StructuredQueryLanguage)简称SQL,结构化查询语言是一种数据库查询和程序设计语言,用于存取数据以及查询、更新和管理关系数据库系统;...
你 发表评论:
欢迎- 一周热门
- 最近发表
- 标签列表
-
- 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)