用机器学习预测股市。司机。
亨尼投资
用随机森林预测下一年的收益。
图片由 whyframeshot 拍摄
这项研究进一步有助于用机器学习探索股市。在本文中,我描述了我在以前的文章中介绍的模型的驱动因素:
如果你还没有读过它们,我建议你从“引言”开始。它将引导你按时间顺序阅读这篇文章,并帮助你熟悉问题陈述和我所采用的方法。
我们开始吧!
进展概述
在上一篇文章中,我讨论了我构建的随机森林模型,该模型用于预测明年的收入作为这项研究的基准。我们的目标是获得模型的基线性能,并了解它在不费力的情况下能做得有多好。其基线表现中规中矩,达到了 0.85 的 ROC AUC 。虽然看到良好的性能很好,但更重要的是理解模型如何做出决策,并验证什么驱动模型直观上有意义。****
随机森林特征重要性
我已经用 Python 中的 sklearn 包实现了这个随机森林模型。开箱即用的软件包提供了计算特性重要性的内置功能。在随机森林和其他树 算法中,一般来说,分类特征重要性是基于每个特征在所有树上平均的平均熵减少来计算的。由于它偏向于高基数特性并且忽略了变量交互,所以它不是真正特性重要性的最佳衡量标准。然而,这是一个很好的方法来大致了解正在发生的事情。
我的模型中前 25 个特性的特性重要性如下所示。
Y 轴上显示了建模特征。X 轴显示特征重要性值。建模数据集包含约 100 个特征,涵盖了资产负债表、损益表和现金流量表的所有方面。
我们可以观察到前 13 个特性的特性重要性之间的显著差异。上方地块上cf _ change _ from _ financing _ activities _ n-1下方的特征逐渐变平。这意味着该模型主要依靠前 13 个特征来做出重要决策,而对较低特征做出的决策可能不会对做出正确的预测做出重大贡献。
简化模型
我上面的观察表明,模型可能不需要提供给它的所有信息来完成它的工作。验证此假设的一个好方法是从最不重要的特性开始迭代地删除特性,并评估每一步模型性能的变化,这也是评估特性重要性的另一种方法。
下图显示了 ROC AUC 得分在每次迭代中的演变,其中从最不重要的特征开始移除 5% 的特征。
X 轴显示了的迭代次数,右边的 Y 轴显示了数据集中剩余的个特征,左边的 Y 轴显示了在剩余特征上训练的模型的 ROC AUC 分数。
我们可以看到,在第一次 30 次迭代中删除特性并不会显著影响这个模型的性能。将移除并简化模型是有意义的,给我们留下剩余的 13 特征,我将更详细地研究这些特征。
以下是其余 13 个特性的新特性重要性。
我们可以看到,该图上的大多数功能也出现在全功能模型的顶级功能中。部分变化包括精选车型中的缺席is _ net _ income以及精选车型增加价格的**。发生这些变化是因为在每次迭代中重新计算了特性的重要性。由于基于树的算法的贪婪性*,这不能保证与所有特征模型特征重要性的一致性。*
特性有意义吗?
在这一点上,我已经显著地减少了功能的数量,而没有牺牲模型的性能。人们可以观察到其余的特征具有强烈的直觉。其中大部分是描述业务盈利能力的比率。它们包括基本比率,如资本回报率、有形资产回报率、股息收益比、营业利润率等。
同时,有些特征不应该用于预测下一年的收入。这些特征是价格 _n-1 和价格 _ 收益 _n-1。尽管价格和本益比可能与净收入的增长相关,但重要的是要记住:
相关性不等于因果性
当建立机器学习模型时,因果关系是可靠预测的基础。没有因果关系的相关性不会。收入不取决于股价,而股价可能取决于收入(或者没有收入)。净收入的变化可能是导致、**、**高市盈率的原因,而不是相反。
话虽如此,但值得注意的是,预测时可用的是市盈率。为什么不用呢?
我担心的是,高市盈率意味着市场预期公司未来会赚更多的钱。这意味着市盈率本身是市场对公司业绩预期的一个代表。依靠市场对一家公司收入变化的预期,确实有助于建立稳健的模型。尤其是当市场大部分时间都是错的时候。因此,PE 和价格不应该被用作预测明年收入的模型中的特征。
最后,我还将删除每股收益 n-1 ,因为它与每股收益稀释 n-1 强烈相关,并删除每股收益 n-1 ,因为它与更具体的有形资产收益 n-1 强烈相关。
这给我们留下了一个由 9 个特征驱动的模型,即:
- 资本回报率
- 稀释后每股收益
- 有形资产收益率
- 收益比股息
- 每股收益增长
- 现金
- 营业利润
- 自由现金流对收益
- 非营业费用
新的简化模型的性能
从原始模型中移除 90%的特征后,让我们评估升力曲线的变化。
红色虚线显示了包含所有 100 个特征的模型的升力曲线。红色实线显示了 9 特征模型的升力曲线。接近曲线右侧的性能轻微下降并不明显,而特性数量减少了 90%。这是有利的,因为理解 9 特征之间的关系比理解 100 特征之间的关系简单得多。
结论
在这篇文章中,我调查了预测 2014 年至 2019 年间标准普尔 500 指数公司明年收入的随机森林分类器的驱动因素。我还使用删除特征选择技术将模型中使用的特征数量减少了大约 90%。
在的下一篇文章中,我将更深入地研究剩余的特征,以理解它们究竟如何驱动模型预测,以及寻找成长股的投资者应该追求什么。回头见!
我们连线吧!
我很高兴和与我志同道合的人联系,这是我对财务独立的追求。如果你也在寻求经济独立,或者你想与合作,交换想法或交流思想,请随时联系我们!以下是我管理的一些资源:
- www.vhinny.com—投资研究平台,为您自己的分析提供金融数据
- https://www.linkedin.com/company/vhinny——加入我们 LinkedIn 上的社区,在那里我和其他贡献者分享投资相关的内容
干杯!
用机器学习预测股市。调查结果。
亨尼投资
用机器学习识别高收入成长股
在这篇文章中,我展示了我在 2014 年至 2019 年间预测 S & P500 家公司的明年收入的主要发现。虽然这不是必需的,但我鼓励读者看到我在这里分享的观察结果:
我们开始吧!
知道模型在做什么
设计一个优秀的机器学习模型,关键是要准确知道它在做什么。当使用类似于回归的东西时,达成这种理解可能很容易,而当使用深度学习神经网络时,则非常困难。尽管如此,负责人应该始终致力于了解模特是如何思考的。没有它,模型的预测一文不值。
我的模型在做什么
在的前一篇文章中,我已经将原始模型中使用的功能从 100 个减少到 9 个,而没有牺牲模型的性能。其余的特征是:
- 资本回报率
- 稀释后每股收益
- 有形资产收益率
- 收益比股息
- 每股收益增长
- 现金
- 营业利润
- 自由现金流对收益
- 非营业费用
我使用了随机森林特征重要性来决定哪些特征应该保留,哪些特征应该丢弃。虽然特征重要性帮助我理解了每个变量在预测分数时的权重,但它没有告诉我每个特征究竟如何影响分数。运营利润应该是高还是低?我们期待高股息还是低股息?应该有多少现金?
寻找方向
在基于树的算法中,将方向贡献给特征重要性的一种方法利用了 SHAP 值。如果你不熟悉这项技术,请看这里的。
我的模型的 SHAP 值如下所示。请注意,我已经从上述功能中删除了非运营费用,因为它没有为模型性能增加实际价值。
该图上的 X 轴测量每个特征对预测分数的影响。Y 轴显示了用于生成预测分数的所有特征。颜色条显示该特征的值是高还是低**。例如,高股息收益鼓励模型作出积极的预测(红色,积极的 SHAP 值)。然而,有形资产的高回报鼓励模型做出负面预测(红色,负 SHAP)。**
这个图揭示了对于一个聪明的投资者来说可能不直观的关系。它说,第二年收入翻一番的公司应该有低资本回报率、低有形资产回报率和低营业利润率——所有这些都是糟糕经营业绩的指标。
更进一步
SHAP 值分析允许我在个体 样本水平上查看每个特征如何影响预测。让我们来看看我的模型做出的前 2 位正确预测。
前 2 个积极预测
该模型预测 2013 年星巴克(SBUX)的收入将翻一番。我们来详细看一下。所有 8 个预测值都是红色的,对预测值做出了积极的贡献,将预测值一直推高到 0.96。
正如**“寻找方向”部分所预期的那样,我们的资本回报率** (0.001)可疑地低,而自由现金流对收益 (520)和股息对收益比率(76)可疑地高。
这些比率不在正常范围内,需要进一步调查。该公司有足够的现金支付通常的股息,但收入却不多。让我们通过 Vhinny 的历史比率和数据来看看这与全球情况是如何吻合的。
https://www.vhinny.com/display/SBUX
事实上,2013 年报告的净收入为 830 万美元,与 2012 年的 14 亿美元和 2014 年的 21 亿美元相比大幅下降。更进一步,你会发现星巴克那年记下了 28 亿美元的诉讼费用。虽然 28 亿美元是一个沉重的打击,但星巴克的盈利潜力并没有受到影响。高的自由现金流对收益比率表明企业仍然赚钱,并继续正常运营。果然,第二年净收入恢复正常,证明我的模型的预测是正确的。
是什么导致了负面预测
了解了模型如何做出自信的正面预测,让我们看看它如何做出自信的负面预测。以下是前 2 位负面预测的 SHAP 值。
前两大负面预测
对于这两个示例,所有 8 个预测值都在蓝色中,对预测得分产生负面影响。事实上,这两个例子的预测分数是0.00——低得不能再低了。
看看家得宝(Home Depot),我们可以看到良好的有形资产回报率(T44)和资本回报率(T46),自由现金流与收益之比(1.41)在 1.41 左右,这属于正常范围。特洛伊的海伦(乐和)也有类似的情况。
这三项指标将 HD 和乐和定义为产生高回报的盈利公司。投资者通常喜欢这种类型的公司,因为它们的业务表现强劲。为什么我的模型认为一个好的企业不会在第二年收入翻倍?
虽然优秀的公司年收入翻倍并非不可能,但数据表明,一般来说,具有强大业务特征的公司会逐渐自信地成长。实际上,T2 需要两倍的人在世界各地为家得宝建造房屋,T4 需要两倍的收入。800 亿美元的年销售额,在正常情况下不太可能发生。为了让模型预测收入大幅增长的可能性,需要在数据的异常区中有一些东西,这就是我们在自信的正面例子中看到的。
结论
在这篇文章中,我描述了我建立的预测明年收入的模型如何做出决策。研究结果表明,在正常经营条件下,好的企业不太可能在第二年实现收入翻番。与此同时,由于“一次性”事件而失去收入的企业可能会重新站立起来,继续正常运营。该模型能够通过分析公司在给定年度的收入情况下赚了多少现金来识别这些公司。
如果读者和我一样,希望在数据中找到信号并认同股市,我鼓励读者把我的结果当作想法,进行自己的研究。如果读者对这项特别的研究感兴趣,那么推进我的发现的一个好地方就是看看公司规模如何影响企业在遭受打击后恢复正常的概率。
本文总结了这一系列利用基础财务数据预测下一年收益的。我希望读者发现我在这里分享的见解是有价值的,并在他们自己的选股过程中加以利用。
我将继续研究 2020 年的股市崩盘。下期见!
我们连线吧!
我很高兴和与我志同道合的人联系,这是对财务独立的追求。如果你也在寻求经济独立,或者你想合作,交流想法,请随时联系我们!以下是我管理的一些资源:
- www.vhinny.com—投资研究平台,为您自己的分析提供金融数据
- https://www.linkedin.com/company/vhinny——加入我们 LinkedIn 上的社区,在那里我和其他贡献者分享与投资相关的内容
干杯!
用机器学习预测股市。引言。
亨尼投资
问题陈述和方法。
这篇文章标志着我在金融市场寻找信号之旅的开始,在这里我使用各种统计方法和机器学习来分析股票市场,并识别有吸引力的投资。
千里之行始于足下
如果你不确定我为什么自己去找信号而不去找“专家”,可以看看这篇文章:论精英如何平庸。
财务数据
在这项研究中,我将使用 www.vhinny.com 的历史金融数据。他们的 Alpha 数据集为 S & P500 公司提供从 2011 年开始的 8 年多的基本财务数据,如资产负债表、损益表和现金流量表。
目标
我的目标是找到我能衡量的关于公司的一些特征和股票价格之间的关联**。然而,一个聪明的投资者可能已经观察到,股票价格并不完全与商业表现相关。相反,它会受到许多因素的影响,如大大小小的经济事件、公众的看法、对变化的期望、产品的新趋势、消费者行为的新趋势等等。**
这让我置身于一个充满噪音和统计偏差的房间,因为存在着我无法测量的因素。忠于我的目标,我将暂时离开这个众所周知的强劲对手,股票价格预测,并专注于预测我更有控制的领域——明年的收入。一旦我对市场驱动因素的理解建立了坚实的基础,我就会回来预测股票价格。
明年的收入是一个更容易解决的问题,因为它与公司的基本面有直接关系。这是一个开始熟悉数据并了解财务信息在预测财务表现时是否有任何预测能力的好地方。
定义目标
我在预测明年的收入。为了有一个一致的目标,我将预测收入的年度增长,而不是收入本身。这样,我的预测将适用于所有公司,无论其规模大小。
下面的直方图显示了 S & P500 公司在过去 8 年的收入增长分布。
X 轴代表年度收入增长,定义为当年和上一年之间的净收入变化除以上一年的*收入的比率。*Y 轴显示每个 bin 所占的数据百分比。
我们可以看到,该直方图的峰值高于 0,反映出平均值为 0.20 的和 0.05 的中值**。这具有直观的意义,因为自 2008 年危机以来,股市一直在持续上涨,表明繁荣的经济有利于业务增长。**
回归与分类
我个人更喜欢解决分类问题,而不是回归,因为它们对评估指标有很高的可解释性。对我来说,根据 Lift、PR 和 ROC 曲线做决定比根据 R2 分数做决定更直接。所以,我要把这变成一个分类问题。
更确切的说,我准备把它做成五(5) 分类问题,看我能更好地解决哪一个。我将预测公司是否会
- 将其收入最多减少 100%或增加
- 将其收入最多减少 50%或增加
- 增加其收入至少 0%
- 增加至少 50%的收入
- 增加至少 100%的收入
我还将保持目标的非互斥性,意思是“增加至少 50%”,例如,也将满足前面的 3 个类。
下面的直方图显示了目标按类别的分布。
注意仓如何逐渐减少。这是因为每个下一个箱包含来自前一个箱的数据减去不满足下一个箱的更严格条件的样本。比如“100% >”就是最严格的条件。因此,它的例子最少。同时,此箱中的公司满足所有早期箱的条件。因此,它们也将作为早期箱的例子出现。
待续
这就结束了我对我要解决的问题的介绍。在下一篇文章中,用机器学习预测股市。对标,我在用随机森林模型预测下一年的收入。在那里见。
我们连线吧!
我很高兴与和我有共同道路的人联系,这是对财务独立的追求。如果你也在寻求经济独立,或者你想合作,交流想法,请随时联系我们!以下是我管理的一些资源:
- www.vhinny.com—投资研究平台,为您自己的分析提供金融数据
- https://www.linkedin.com/company/vhinny——加入我们 LinkedIn 上的社区,在那里我和其他贡献者分享与投资相关的内容
干杯!
用递归神经网络预测特朗普的推文
用 LSTM RNN 生成作者和特定任务的文本。
唐纳德·特朗普著名的“covfefe”推文。
唐纳德·特朗普独特的方言是每个美国人都能识别的;然而,我们能建立一个神经网络来模仿特朗普的‘cov fefe’一样的词汇吗?
文本预测只在特朗普的推文、演讲和采访上进行了训练。-mm 909/预测-川普
github.com](https://github.com/mm909/Predicting-Trump)
在 Andrej Karpathy 被高度引用的博文递归神经网络的不合理有效性中,Karpathy 表明递归神经网络(RNNs) 可以作为非常强大的生成模型。他给出了 RNNs 生成莎士比亚戏剧的例子,维基百科关于自然主义的文章,甚至带有真实用户评论的 Linux 源代码。
我们将使用 RNN 来生成新的特朗普推文。
这不是对自然语言处理(NLP)或 RNNs 的深入指导,而是对项目的概述;尽管如此,还是提供了所有的代码,并且有大量的链接可以帮助扩展本文中没有完全解释的主题。
数据
我们首先收集特朗普词汇的例子,越多越好。幸运的是,我们不缺乏数据。特朗普的思想几乎总是保存在推特上,在演讲中,或者在采访中。我们将使用这些推文、演讲和采访的组合来训练角色预测模型。
小鸟叫声
特朗普的推文在几个地方存档。我从 TrumpTwitterArchive 下载了大约 50,000 条他的推文。然后,我通过从推文中删除所有表情符号和网址来清理数据,以帮助提高预测的准确性。以下节选自 cleanTweets.txt :
感谢我们伟大的美国企业为保护我们最脆弱的公民的安全所做的一切!
经双方同意,我们将暂时关闭与加拿大的北部边境,禁止非必要的交通。贸易不会受到影响。详情随后!
同样根据每日来电显示,在佛罗里达州,嗜睡的乔·拜登以 48%对 42%领先。
演讲:GitHub
不幸的是,特朗普的所有演讲都没有一个中心位置,但有几个 GitHub 存储库存有他的演讲子集。下面是一些你可以从哪里得到数据的例子;然而,我只使用了第一个库。
[## unendin/Trump_Campaign_Corpus
特朗普竞选语料库包括唐纳德·特朗普的演讲、采访、辩论、市政厅、新闻发布会…
github.com](https://github.com/unendin/Trump_Campaign_Corpus) [## PedramNavid/trump _ 演讲
特朗普 2015 年 6 月至 2016 年 11 月 9 日的所有演讲——PedramNavid/Trump _ speechs
github.com](https://github.com/PedramNavid/trump_speeches) [## ryanmcdermott/trump-演讲
speechs . txt:1mb 的文本数据摘自唐纳德·特朗普在 2016 年竞选活动中不同时间点的演讲…
github.com](https://github.com/ryanmcdermott/trump-speeches) [## Alex mill/trump _ 抄本
这是唐纳德·特朗普竞选演讲和辩论笔录的半结构化版本,因为…
github.com](https://github.com/alexmill/trump_transcripts)
同样,与 tweet 数据一样,这些数据也需要清理。对于来自 unendin 的存储库的数据,我们需要删除非川普演讲者的所有文本。以下是唐纳德·川普和马克·霍尔珀林在接受采访的节选。
马克·哈尔珀林:人们对你的个性非常感兴趣。很多人,我想你听过这句话,认为你自大或者太自信了。有些人说你极度缺乏安全感,这就是你如此行事的原因。你对任何事情都没有安全感吗?
唐纳德·特朗普:我不知道。也许是两者的结合。
马克·哈尔珀林:你缺乏安全感吗?
唐纳德·特朗普:每个人都没有安全感。
我们可以通过编写一个正则表达式来匹配“SPEAKER: TEXT ”,然后删除除 Donald Trump 之外的所有发言者,从而删除采访中马克·霍尔珀林一方的所有内容。
我还选择删除所有的换行符,因为我觉得它们对文本预测并不重要。由此产生的文字记录只是特朗普在采访中的一面之词。
我不知道。也许是两者的结合。每个人都没有安全感。
然后将所有的演讲连接起来,放入 cleanSpeech.txt
演讲:事实基础
FactBase 是唐纳德·特朗普的演讲和采访档案。可悲的是,FactBase 没有简单的方法一键下载他所有的演讲;然而,这并不重要,因为这些数据很容易被删除。
我们可以使用 Selenium 从 FactBase 中抓取数据。随着时间的推移,这将把特朗普的所有新演讲添加到我们的数据库中。
数据准备
要开始训练我们的模型,我们需要加载和处理文本数据,为网络做好准备。通过这样做,我们将定义两个重要的超参数:序列长度和步长。
加载数据
让我们从把数据载入内存开始。我们将读入数据,并使所有的文本小写。这样,T 和 T 被认为是同一个字母。语料库长度是我们数据库中的字符数。
Corpus length: 23342237
字符词典
模型不会自然地理解文本和标点符号,比如“a”和“?”,但他们确实理解数字。因此,我们需要一种方法将我们所有的文本翻译成数字。
有很多方法可以做到这一点,但我选择使用两本字典。一个把字母变成数字,另一个把数字变成字母。
char_indices['a'] -> 42
indices_char[42] -> 'a'
Unique Chars: 66
序列长度
序列长度是我们的模型得到的上下文窗口的大小。
序列长度定义了有多少个字母,以及有多少上下文,我们要给模型预测下一个字符。序列长度越长,模型在进行预测时就有越多的上下文。序列长度为 20 的示例:
"Today I will be addr"
你可能会猜到这个序列中的下一个字母是 e,句子中的下一个单词是 addressing。这就是我们希望我们的模型预测的。
对于我们的模型,我们将使用长度为 80 的序列。
步长
步长是我们每次迭代滑动上下文窗口的距离。
步长定义了在制作训练样本时,每次迭代要移动多少个字母。下面是一个序列长度为 20,步长为 2,句子为“今天我将向全国发表演讲”的例子:
"Today I will be addr"
"day I will be addres"
"y I will be addressi"
"will be addressing t"
"ll be addressing the"
" be addressing the n"
"e addressing the nat"
"addressing the natio"
"dressing the nation."
对于我们的模型,我们将使用步长 4。
序列长度和步长的权衡
我们希望序列长度尽可能长,以便模型有更多的上下文来预测下一个字符,然而,更长的序列长度意味着更大的模型和更多的处理时间。我选择序列长度为 80,因为我更关心网络拼凑长文本串的能力,而不是网络的处理时间。
步长的权衡更加片面。步长越小越好。较小的步长意味着更多的训练样本和更多的相关句子,然而,只有一定数量的样本可以被存储。我们希望最小化步长,同时仍然将所有的句子放入内存。
***使用数据发生器 ***消除了步长折衷
编码
使用选择的序列长度和步长,我们现在创建一个句子数组来保存所有拆分的句子,创建一个下一个字符数组来保存序列中的下一个字母。
为了更具可读性,我展示的例子是序列长度为 20,步长为 2。句子数组现在看起来像这样:
["Today I will be addr",
"day I will be addres",
"y I will be addressi",
"will be addressing t",
"ll be addressing the",
" be addressing the n",
"e addressing the nat",
"addressing the natio",
"dressing the nation."]
下一个字符数组保存每个句子中的下一个字母:
['e',
's',
'n',
'h',
' ',
'a',
'i',
'n',
'']
这为我们提供了培训示例的总数:
Number of training examples len(sentences): 5835540
最后,我们将热编码这些序列,使它们能够被神经网络处理。
我们现在有( X ,y)对供网络处理。提醒一下,5835540 是训练样本的数量,80 是序列长度,66 是唯一字符的数量。
X.shape: (5835540, 80, 66)
y.shape: (5835540, 66)
模型
我们的模型将是一个长短期记忆(LSTM) RNN 。递归层之后是几个密集层,用比例指数线性单元(SELU) 激活,用批量归一化正则化。
在探索了几种不同的选择之后,我做出了这些决定。
模型图
结果
仅仅过了四个时期,我们就有了一个验证数据准确率为 67.362%的模型。考虑到随机猜测会给我们 1.51%的准确度,该模型表现良好。因此,我们的模型比猜测精确 44 倍。
模型统计
下表显示了对句子“Today I”的预测。
《今日我》预测表
对于第一个字符预测,模型选择“w ”,但它对其决策不是很有信心。这是因为在“今天的我”之后有大量合理的可能性。尽管如此,有 20.53%的把握,这个模型把“今天的我”变成了“今天的我”。
在第一次预测之后,我们继续向模型询问字符。随着可能选项的数量减少,该模型变得更有信心。“今天我要”变成了“今天我要”,然后是“今天我要”。最终,该模型 99%确信最后一个字符是“l ”,从而得到字符串“Today I will”。
预测的句子
以下是不同模型生成的句子示例。所有的模型都在相同的数据集上训练,但是具有不同的架构。这些模型能够理解 twitter 标签、标点、连词、重要日期,甚至反问句。
模型 1
Seed: 'Welcome to America'
Output: 'Welcome to America, right? Well, I would have said that we have to make America great again, but I want to talk about the problem now.'Seed: 'It is really'
Output: 'It is really sad but the fake news media don't want to see the Republican Party continue to prove what we have.'
模型 2
Seed: 'I'
Output: 'I mean, in the middle east, we are going to win. We are going to repeal and replace Obamacare. Hillary is a disaster. We are going to win.'Seed: 'America'
Output: 'America first. Our jobs are going to win on November 8th. Manufacturing jobs have got to do it.'
模型 3
Seed: 'Today I will'
Output: 'Today I will make America great again! @realdonaldtrump is a big thing that is the best in the country and the president is a big deal.'Seed: 'I think that'
Output: 'I think that is a big contract that comes out the world trade center and we have to take care of our country.'
模型 4
Seed: 'I will always'
Output: 'I will always stop the state of the state of Michigan in the state of Michigan'Seed: 'The whitehouse'
Output: 'The whitehouse is not for the state of Michigan'Seed: 'China is a'
Output: 'China is a total crisis and the story in the same thing that I was a great and I will be interviewed by @seanhannity to the @whitehouse!'
披露:我在输出中添加了所有的大写。
结论
我们创造了非常现实的句子,听起来就像真的来自唐纳德·特朗普的推特。我自信地说,这个模型肯定是循环神经网络不合理有效性的另一个例子。在整个过程中,我做了一些重要的观察,并将它们列在下面。
选择性短语
似乎每个模型都选择了一些短语来保持重用。有时这些短语会在一个预测中出现多次。模型 1 不断重复使用短语,“但我现在想谈谈这个问题”和“假新媒体。”对于模型 2,一切都发生在中东。Model 3 总说东西是“全国最好的”。最后,Model 4 讨厌密歇根州。尽管所有这些短语都是唐纳德·特朗普词汇的一部分,但它们在预测中出现得太频繁了,以至于不自然。
一个有趣的观察是,在相同数据集上训练的模型可以专注于不同的短语。这意味着模型更频繁选择的短语与数据集无关。
影响
除了娱乐价值,rnn 还有实际的现实价值。能够生成作者和特定任务的文本,比如 tweets,非常有用。rnn 能够通过给你文本建议来帮助你写更快的电子邮件,比如 Gmail。它们还可以帮助演讲稿撰写人更准确地匹配演讲者词汇。RNNs 和 NLP 之间的交叉非常广泛,应用领域非常广阔。
丰富
**训练时间:**不幸的是,每个纪元需要大约一个小时才能完成,所以我将训练限制在 4 个纪元。虽然从第 3 代到第 4 代的改进很小,但我认为多训练几个小时会产生更精确的模型。
在写这篇文章的时候,我发现了 CuDNNLSTM 。用 CuDNNLSTM 替换 LSTM,可减少 66%的培训时间。我还没有 CuDNNLSTM 如何影响模型准确性的结果;然而,我怀疑 CuDNNLSTM 和 LSTM 会表现相似。
**减少偏差:**模型有大量可避免和不可避免的偏差,正如吴恩达在机器学习向往中所定义的。即使对人类来说,文本预测也是一项艰巨的任务,正因为如此,我们可以预期会有相当高的不可避免的偏差。还有大量可以避免的偏见。这可以通过使用更复杂的模型和添加字嵌入来解决。
**减少差异:**唐纳德·特朗普(Donald Trump)喜欢的“covfefe”词汇的例子越多越好。我希望继续收到更多的推文、演讲和采访。虽然方差目前非常低,但随着模型变得更加复杂,方差将会增加。添加更多的数据将有助于控制差异。
Keras dataGenerator: 我还没有为文本数据实现 Keras 的 dataGenerator 类。实现这个类意味着我们的模型可以总是步长为 1 而不会溢出内存。这意味着我们可以显著增加训练数据库的大小,而不用担心它不适合内存。
所有这些改进将使模型更加精确。
项目存储库
在 GitHub 上注册你自己的个人资料,这是托管代码、管理项目和构建软件的最佳地方…
github.com](https://github.com/mm909)
Seed: 'Today I will'
Output: 'Today I will be the world -- I think.'
用机器学习预测推特情感
推特上的情感分析
🇨🇭·克劳迪奥·施瓦茨| @purzlbaum 在 Unsplash 上拍摄的照片
不可否认的是,社交媒体现在已经成为一个极其重要的平台,帮助企业扩大在线影响力。多年来,营销人员越来越意识到社交媒体平台(如脸书、Twitter、LinkedIn)的重要性,以及它们通过嘴对嘴营销在业务增长中发挥的作用。
许多人也注意到,社交媒体是一个很好的地方,可以在你的客户所在的地方与他们见面,公平地说,一些企业有很好的幽默感…
来源:推特供稿
如果我们回忆一下社交媒体的目的,我将把它概括为将世界任何地方的人们联系在一起,这就可以理解为什么企业纷纷涌向社交媒体,因为他们意识到这是一个交流的好地方,无论这种交流是好消息、坏消息、假新闻还是世界上某个地方发生的紧急情况。
此外,智能手机的普及使人们能够实时宣布这些事件。如果顾客在他们的食物中发现一根头发,你可以打赌它会出现在社交媒体上。因此,越来越多的机构、组织、企业和好奇的个人对有计划地监控各种社交媒体网站以获取对他们重要的信息产生了兴趣。
这方面的一个很好的例子可能是希望检测灾难发生的救灾组织。这显然是一项非常重要的任务,但也非常困难,因为人们并不总是清楚一个人的话是在宣布一场灾难还是对某件有吸引力的事情的夸张描述——在这方面,可以公平地说,话可能非常模糊。
来源:推特供稿
上面的图片显示了一个用户的推文,他说他们想要点燃“天空”。当把“着火”当作动词时,这条推文可以被认为是一场灾难,因为这意味着天空正在猛烈燃烧。然而,根据推文中提供的上下文,我们知道用户指的是形容词版本的“闪亮的”,这意味着他们在说天空非常明亮或明亮。这是显而易见的,但对计算机来说就不一样了。
因此,作为数据科学家(NLP 专家),我们的工作是提出解决方案,尽最大努力克服语言的各种模糊性,这样我们服务的人们就不会不断受到由于语言差异而导致的错误灾难声明的轰炸。
在这一点上,我们将做一些情绪分析结合机器学习来检测来自 Twitter 的灾难推文的情绪。目标是根据推文确定是否有真正的灾难。
注意:对于我的帖子的关注者,你会记得我们一直在一起研究自然语言处理。如果你是新手,这一切都是关于我在 Coursera 上记录的自然语言专业笔记。为了避免我再次解释什么是情绪分析,请回顾一下开始情绪分析的帖子。
数据
我们可以使用 Twitter 的 API 自己检索数据。文档指出" Twitter 的开发者平台使你能够在你自己的应用中利用 Twitter 的开放、全球、实时和历史交流网络的力量。该平台提供工具、资源、数据和 API 产品供您整合,并通过研究、解决方案等扩大 Twitter 的影响。”。这样做意味着我们必须自己处理和标记数据,这更适合现实世界的情况。
对我们来说幸运的是,大部分艰苦的工作已经完成了,因为数据已经被检索并作为逗号分隔值(csv)文件存储在 Kaggle 上。因此,我们的工作只是将数据下载到我们的本地驱动器—要下载数据,访问 真实与否?NLP 与灾难 Tweets 入门竞赛并从数据部分下载数据。
免责声明:本次比赛的数据集包含可能被视为亵渎、粗俗或冒犯的文本。
我们期望在数据中看到的特征如下:
id
—每条推文的唯一标识符。text
—推文的文本keyword
—推文中的一个关键词(虽然这可能是空白的!)location
—发送推文的位置(也可以是空白的)target
—表示一条推文是否是关于真实的灾难(1
)或者不是(0
);只有在train.csv
和sample_submission.csv
评估标准是 F1 分数,详情请见下文。
打破混乱矩阵
towardsdatascience.com](/confusion-matrix-un-confused-1ba98dee0d7f)
构建模型
所有代码都可以通过 Github 访问。
此时您不能执行该操作。您已使用另一个标签页或窗口登录。您已在另一个选项卡中注销,或者…
github.com](https://github.com/kurtispykes/twitter-sentiment-analysis)
第一相
当开始一个项目时,获得快速反馈是非常重要的,因此,我不担心立即获得最佳的准确性。相反,我想找到从数据中获得即时反馈的最佳方式,然后开始更深入地研究,以辨别可以做出哪些改进。
为了通过这个阶段,我首先将我的数据分成训练、开发和测试集——因为这些数据来自 Kaggle,我们已经有了一个测试集,所以我们只需要一个开发集。然而,我将使用分层 Kfold 交叉验证,而不是使用基于维持的开发集——更多关于交叉验证的信息,请参阅我关于交叉验证的文章。
验证机器学习模型的性能
towardsdatascience.com](/cross-validation-c4fae714f1c5)
为了帮助我们编写代码,我制作了一个配置文件,我们将使用它,这样我们就不会在脚本中进行任何硬编码…
现在让我们创建我们的折叠。
该函数读取我们从 Kaggle 接收的原始训练数据,创建一个新列并用-1
填充所有值。之后,我们重组数据,通过标记每个实例所属的文件夹来创建文件夹,最后将其保存为 csv 文件。
创建折叠的过程对我来说很标准。我确实在交叉验证文章中详细描述了我如何选择我的验证策略,但更多的时候,我会对分类问题进行分层——我甚至在我的使用机器学习检测欺诈的故事中使用它。
第二相
快速迭代的下一个阶段是尽可能快地训练一个模型,这意味着我们不会太担心最佳特性工程实践或任何事情。我们只想训练一个简单的模型,做推理。
本质上,我们有 3 个特征(不包括id
),它们是text
、keyword
和location
。我能想到的处理这些问题的最简单的方法就是简单地将关键字和位置附加到文本的末尾。之后,我们对文本进行一些基本的处理,将文本转换成向量,然后建立我们的模型。
为了将我们的文本转换成向量,我们使用了CountVectorizer
,它将一组文本文档转换成一个令牌计数矩阵——参见文档。
我们将使用 2 个不同的模型运行我们的训练脚本,并在我们编写脚本进行推理时,使用每个折叠上具有最佳平均值的模型提交给 Kaggle。我们使用的两个模型是逻辑回归和朴素贝叶斯。
从头开始详述和构建逻辑回归模型
towardsdatascience.com](/algorithms-from-scratch-logistic-regression-7bacdfd9738e) [## 从零开始的算法:朴素贝叶斯分类器
从头开始详述和构建朴素贝叶斯分类器
towardsdatascience.com](/algorithms-from-scratch-naive-bayes-classifier-8006cc691493)
如果您不记得上面的内容,本次比赛的评估标准是 F1 分数:
因此,我们将使用朴素贝叶斯进行推理…
这将输出一个 CSV 文件,我将把它提交给 Kaggle
提交给 Kaggle 的文件(图片由作者提供)
关于这一点需要注意两件事…我们的平均开发集分数和我们的测试分数之间有很大的差异,所以我们必须对我们的交叉验证技术做一些调整。接下来的事情就是我们的分数没有那么大。我的目标是 F1 成绩达到 85 分左右。
在另一篇文章中,我将讨论错误分析,这样我们就可以开始改进我们的模型。
感谢阅读到最后,让我们继续 LinkedIn 上的对话…
[## Kurtis Pykes -数据科学家-自由职业者,自由职业者| LinkedIn
在世界上最大的职业社区 LinkedIn 上查看 Kurtis Pykes 的个人资料。Kurtis 有 3 个工作列在他们的…
www.linkedin.com](https://www.linkedin.com/in/kurtispykes/)
用 DNN 分类器预测终极格斗锦标赛
基于格斗者风格和数据预测综合格斗比赛结果的研究
免责声明:您不应该使用本文中介绍的模型进行赌博或执行任何与赌博相关的活动。我的 GitHub 帐户中发布的这篇文章或代码不构成下注建议。
起初,我认为试图用统计数据来预测 MMA 比赛结果的想法有点愚蠢。我的推理非常简单:拳手有不同的策略来对付不同的对手。如果你在和麦格雷戈比赛,你知道你需要对你的左手做些什么。如果你在和德米安·玛雅战斗,你知道你不能和他一起战斗。如果你的对手是内特·迪亚兹,你需要尽快搞定他,或者最好在你的有氧运动中处于领先地位。
但是我在 You Tube 上看到了一个很好的视频,改变了我的想法。在这个视频中,他谈到了’击败了 Khabib '。他说,除非一名运动员已经具备了相应的技能,否则不可能指导他调整自己的风格来对抗特定的对手。这些技能需要成为他格斗词汇的一部分,3 个月的准备不会改变多年的训练和肌肉记忆。因此,在兴奋的时刻,计划很可能会通过窗口,那些根植于他们 DNA 的运动将会出现。
Chael Sonnen 谈论击败 Khabib Nurmagomedov
数据
在说服自己这个项目不是完全浪费时间之后,我需要得到一些反映每个战士的数据。所以我做了一个机器人从 ufcstats.com 收集数据。
这些数据很棒,因为它们很好地描绘了每个战士的技术和背景。
例如,看看德米安·马亚和豪尔赫·马斯维达尔的故事:
德米安·马亚是一名格斗家,阿九柔道专家,而马斯维达尔是一名跆拳道运动员。这些指标以一种可被 DNN 分类器使用的方式嵌入该信息。
模型
该策略是向 DNN 分类器提供竞争者的统计数据,并训练它根据之前比赛的结果识别谁将获胜。
我没有花很多时间来调整模型,但它基本上是一个 DNN 分类器,有 3 层,每层 30 个单元。数据和我的代码可从以下网址获得:
https://github.com/cunhafh/UFC_bout_prediction
模型精度
该模型使用 30%的可用数据进行训练,评估的准确度约为 80%:
我在最后一场 UFC 夜战上测试了这个模型,它很好地预测了*‘布莱德 Vs 多斯桑多斯’和‘多斯安茹斯 Vs 基耶萨’的结果。*
该模型预测 Blaydes 和 Chiesa 将获胜。不出所料,布莱德斯、专家分析和赔率都对他有利。然而,基耶萨在另一场比赛中处于劣势,没有多少人预计他会击败拉斐尔·多斯安茹斯——该级别的前冠军。如果我要赌那场比赛,我肯定会因为赌多斯安茹斯而输钱。这句话把我带到了下一个话题。
体育博彩和机器学习
免责声明:本文或代码(发布在上述存储库中)仅为科学利益而开发,不应用于赌博或执行任何与赌博相关的活动。
话虽如此,我相信 ML 模型确实有助于增加自己的胜算。让我们深入了解一下。
使用预测模型相对于“凭直觉”的优势是不可否认的。我们偏向于我们最喜欢的拳手,或者认识的时间更长,或者和我们拥有相同的国籍。机器学习可以为你提供一个严格符合逻辑的选择,这个选择来自于一个经过数千次已知精确度测试的模型。
体育博彩中最大的吹毛求疵是风险/回报比。例如,下一场 UFC 赛事“乔恩·琼斯对多米尼克·雷耶斯”的十进制赔率是 1.25(琼斯)和 4.25(雷耶斯)。在琼斯身上下注的风险/回报比是不合理的(对于 100 美元的赌注,有输掉 100 美元最终赚 25 美元的风险)。
因此,下注策略需要考虑赢的部分来弥补输的部分。
盈亏平衡点
在其他作品中,如果我赌 10 场比赛,每场比赛 10 美元,我应该预计会损失 20 美元,其他赌注的回报应该可以弥补这一点。所以,在这种情况下(模型 acc = 80%),如果所有 10 名战士的平均赔率至少为 1.25,我应该可以保本。如果我只决定在赔率至少为 1.4 的拳手身上下注,我应该预计最低回报率为 12%。当然,所有这些都是在模型有 80%的准确率的情况下进行的。
不过,我还没能测试这个策略,因为在我居住的地方,体育博彩是非法的。我计划在某个时候测试它,但那将是另一篇文章!
我希望你喜欢这篇文章,我很想听听你的想法和建议。也可以随时与我联系。
https://www . LinkedIn . com/in/feli PE-Cunha-MSC-PMP-LSS b-2692131 b/
谢谢
用机器学习预测 UFC 格斗
我如何使用 Scrapy、深度学习、Flask 和 React 构建多模型战斗预测器。
迪伦·诺尔特在 Unsplash 上的照片
TL;DR: 亲自检查一下**预测器,看看它在即将到来的 UFC 战斗卡中表现如何,或者检查一下 github 上的代码**
项目概述
作为一个 MMA 爱好者,我经常发现自己试图预测即将到来的战斗卡上的战斗结果。问题是战斗的本质是非常不可预测的。甚至比拳击更重要的是,MMA 比赛的结果可以在一瞬间改变,但当然这也是它如此有趣的原因。
尽管如此,我还是想知道是否有一种方法可以将现代机器学习技术应用于历史格斗数据,并观察一个模型在新的格斗中的表现。
入门指南
当然,像任何 ML 项目一样,我需要数据来处理。幸运的是,我有一个好主意,我可以在哪里找到一些经常在战斗卡后第二天去 www.ufcstats.com 的人,以获得战斗的统计数据。
所以现在我有了我的数据源和一些如何实现这个模型的想法,我想知道是否有其他人已经建立了一个这样的项目,并且看到了这个由田园写的帖子,详细描述了他建立一个战斗预测器的过程。
袁的帖子非常详细和有见地,我抓取统计数据页面的方法很大程度上是受他如何构建自己的抓取工具的启发。谢谢袁!
在袁的预测中,他使用了比赛前可用的比赛数据,我称之为“静态比赛数据”,如年龄,距离,体重,W/L 记录等。然而,UFC 统计页面还详细列出了历史比赛的具体统计数据,如击球、击倒、提交尝试和后卫传球。
由于 UFC 统计页面上没有太多的数据点,我觉得丢弃这些“动态战斗统计”将是一种耻辱。所以我决定建立一个双向预测系统的预测器:
- 第一个模型使用静态统计数据作为战斗机 1 和战斗机 2 的自变量,然后预测因变量,即动态战斗统计数据。(一个** 多目标回归 问题)。**
- 然后,我们将静态和动态的战斗统计数据传递给一个整体赢家模型,该模型预测战斗机 1 或战斗机 2 是赢家。(一个二元分类问题)。
抓取 UFC 统计数据
这个项目的刮刀被分解成两个刺儿头蜘蛛,爬行 UFC 战斗统计的两个部分:
- 关于刮刀
- 战斗机铲运机
****关于刮刀数据对象被分解为以下碎屑项:
class BoutScraperItem(Item):
event_name = Field()
event_date = Field()
event_attendance = Field()
fighter1 = Field()
fighter2 = Field()
str_stat_f1 = Field()
str_stat_f2 = Field()
td_stat_f1 = Field()
td_stat_f2 = Field()
sub_stat_f1 = Field()
sub_stat_f2 = Field()
pass_stat_f1 = Field()
pass_stat_f2 = Field()
weight_class = Field()
win_method_type = Field()
win_method_finish = Field()
round_ = Field()
time = Field()
winner = Field()
回合蜘蛛抓取 UFC 战斗统计的事件部分,并记录每个战士的特定统计,如 str_stat_f1(战士 1 的攻击统计),其中许多将成为我们多目标回归问题的因变量。Fighter1 和 Fighter2 是一场比赛中所涉及的拳手的名字,我们将这些值加入到战斗机数据中。
****战斗机铲运机数据对象分解为:
class FightScraperItem(Item):
fighter_name = Field()
fighter_record = Field()
height = Field()
weight = Field()
reach = Field()
stance = Field()
date_of_birth = Field()
slpm = Field() # strikes landed per min stat td_avg = Field() # takedown average strike_acc = Field() # striking accuracy td_acc = Field() # takedown accuracy
sapm = Field() # strikes absorbed per minute td_def = Field() # takedown defence strike_def = Field() # striking defence sub_avg = Field() # submission average
这里的每一项都是从拳手统计页面中单独抓取的,该页面详细描述了 UFC 回合中每个拳手的职业统计(尽管 UFC 早期的数据填充较少)。
我将这两个数据对象作为表保存到 SQLite 数据库中,并编写了一个小脚本来生成一个组合的 fight-bouts CSV 文件,其中每一行都是 fighter1 和 fighter2 各自的 fighter stats。这个 CSV 以及 fighters 数据对象的 CSV 表示将是我们用来构建这两个模型的两个文件。
如果你有兴趣了解每个蜘蛛的实际抓取逻辑,看看这里的。
预处理
与大多数这类 ML 项目一样,真正的工作是在预处理步骤中完成的,以及如何为建模阶段准备数据。
项目的这一方面经历了无数次迭代。我从 Jupyter 笔记本开始,但随着复杂性的增加,我决定将其作为前端应用程序来实现,我将设计更改为包含 winner predictor 和 stats predictor 的共享预处理方法以及特定于任务的预处理方法的类。
大量的预处理致力于清除丢失的或格式错误的值,例如,高度被表示为字符串,解析字符串斗士记录,以及获得斗士在战斗时的年龄。
预处理中最棘手的一个方面是改变 fighter1 和 fighter2 的统计数据的顺序。我不得不打乱这种顺序的原因是 UFC 的回合数据总是按顺序排列,所以 fighter1 是赢家,所以我必须想出一种方法来随机选择一半的数据集,并将 fighter1 和 fighter2 的统计数据位置相互交换,以便最终的数据集被整齐地分开,这样 fighter1 的 50%是赢家,fighter2 的 50%是赢家。我很乐意整理这种逻辑,如果有人有任何改进的建议,我很乐意听听。
处理器类的另一个重要特性是,它们必须能够在生产中以不同的方式处理数据,因为在生产环境中,数据帧的构造不像训练步骤那样整齐。
在生产中,战斗机的统计数据必须被特别地预测,然后插入到最终的数据帧中,用于胜利者的预测。我的解决方案是为处理器创建额外的子类,以处理特定于生产的情况。
建模
这两个模型都是使用 Keras 构建的,相对简单的架构只包含一个完全连接的隐藏层。我采取了一种启发式的方法来寻找两者的最佳参数,但我渴望使用更新的工具优化工具,如 Keras 调谐器来微调其性能。
统计模型
统计模型采用战斗前双方可用的所有统计的缩放数字表示,其输出层由 8 个特定于战斗的统计组成:
output_cols = [
'pass_stat_f1', 'pass_stat_f2', 'str_stat_f1', 'str_stat_f2', 'sub_stat_f1', 'sub_stat_f2', 'td_stat_f1', 'td_stat_f2' ]
由于这是一个回归问题,统计模型中的最后一层具有线性激活(默认激活)。对于损失,我使用“mse”和 R 作为模型的度量来评估性能。
在验证集上,该模型的 R 通常约为 0.63–64,这还不算太差,但值得注意的是,随着额外的预测值(输出)的增加,R 将始终增加,其中一些可归因于碰巧对齐的随机噪声。为了解决这个问题,我将增加调整后的 R 来惩罚新版本中每一个新输出的模型。
赢家预测模型
像 stats 模型一样,它遵循一个基本的单个全连接隐藏层架构。因变量是 0 (fighter1)或 1 (fighter2),所以我在最后一层添加了一个简单的 sigmoid 激活来预测这些结果之一。
该模型的准确性通常约为 86%,但必须强调的是,这一准确性是通过动态战斗统计的完美信息实现的,这些信息在生产中是预测值,因此不是完美信息,因此统计预测模型的预测能力存在巨大的偶然性。
通过 API 为模特服务
因为我想将模型及其预测作为前端服务,所以我需要构建一些 API 端点来访问模型和可以进行预测的战斗机列表。
使用 Flask,这是相对直接的。有两个主要端点,一个为生成预测的战斗机名称列表服务,另一个为预测管道排队并返回结果。
流水线处理每架战斗机的数据帧,然后将它们连接成正确的形状和顺序,以便进行统计预测。一旦返回了统计预测值,它们就作为具有各自名称和位置的列被添加到数据帧中,并被传递给获胜者预测模型,从而返回与战斗机 1 或 2 相关联的结果。
反应前端
然后,所有 API 的功能都由一个非常简单的 React 前端调用,该前端为用户提供两个可搜索的下拉列表和一个结果显示,显示预测的获胜者和模型对其预测的信心。
在 React 中设置这一点很容易,我发现 React 通常是一种乐趣(我❤胡克)。
我想在前端添加很多东西,比如一个显示用户预测历史的表格,一个显示基本战斗机统计数据的信息图。
包扎
希望这对 ML 爱好者和/或 MMA 爱好者来说都是有益的,正如我已经提到的,我希望在未来的这个项目中增加许多功能,我很想听听你们的想法。谢谢!
另外,也许现在还不要对模型的所有预测结果下赌注。
用机器学习预测二手车价格
从数据收集到模型评估的完整数据科学项目
我打算卖掉我的车,那是一辆 4 年前的大众 polo。二手车通常在土耳其一个名为“ sahibinden ”的网站上出售。“Sahibinden”的意思是“来自车主”,尽管有许多经销商使用这个网站来出售或购买二手车。卖二手车最关键的部分是确定最优价格。有许多网站给你二手车的价格,但你仍然想在定价前搜索市场。此外,还有其他影响价格的因素,如位置、你想以多快的速度卖车、车内吸烟等。在你在网站上发布广告之前,最好先看看类似汽车的价格。然而,这个过程可能会很累,因为网上有太多的广告。因此,我决定利用机器学习提供的便利来创建一个模型,根据“ sahibinden ”上的数据预测二手车价格。它不仅有助于解决我的汽车定价问题,还能帮助我学习和实践许多与数据科学相关的主题。
本项目分为以下 5 个子部分:
- 数据收集
- 数据清理
- 探索性数据分析
- 回归模型与评估
- 进一步改进
所有的数据和代码都可以在 github 知识库上获得。请随意使用或分发。
1。数据收集
在“ sahibinden ”网站上有六千多件大众马球出售。我不得不做网络搜集,从网站上收集数据。我不是网络搜集专家,但我已经学到了足够的知识来获取我需要的信息。我认为,如果你想在数据科学领域工作或正在工作,学习一定水平的网络抓取是非常重要的,因为数据通常不会放在盘子里提供给我们。我们必须得到我们需要的。
我使用了 beautiful soup ,这是一个 python 库,用于从 HTML 和 XML 文件中提取数据。语法非常简单,易于学习。有几个重要的细节你需要注意,特别是如果数据被列在几页上。
总是先导入依赖项:
import pandas as pd
import numpy as np
import requests
from bs4 import BeautifulSoup as bs
我使用 python 的请求库的 get() 方法从源中检索数据,并将其存储在一个变量中。然后我用美汤提取整理了这个变量的内容。由于数据在几个页面上,我不得不创建 list 来帮助解析不同的页面,并启动空列表来保存数据。
#initiate empty lists to save data
model_info = []
ad_title = []
year_km_color = []
price = []
ad_date = []
location = []#create lists to parse through pages
page_offset = list(np.arange(0,1000,50))
min_km = [0, 50000, 85000, 119000, 153000, 190000, 230000]
max_km = [50000, 85000, 119000, 153000, 190000, 230000, 500000]
一个页面上最多可以显示 50 个广告。为了搜集大约 6000 辆汽车的数据,我需要迭代 120 多页。首先,我将代码组织在一个 for 循环中,从 120 页中提取数据。然而,在这个过程完成后,我发现数据在前 1000 个条目后重复。然后,我决定将数据分成更小的部分,每组不超过 1000 个条目,所以我使用“km”标准来区分组。我创建了嵌套的 for 循环来提取大约六千辆汽车的数据,如下所示:
for i, j in zip(min_km, max_km):
for page in page_offset:
r = requests.get(f'https://www.sahibinden.com/volkswagen- polo?pagingOffset=**{page}**&pagingSize=50&a4_**max={j}**&sorting=date_asc&a4_**min={i}**', headers=headers)
soup = bs(r.content,'lxml')
model_info += soup.find_all("td",{"class":"searchResultsTagAttributeValue"})
ad_title += soup.find_all("td",{"class":"searchResultsTitleValue"})
year_km_color += soup.find_all("td",{"class":"searchResultsAttributeValue"})
price += soup.find_all("td",{"class":"searchResultsPriceValue"})
ad_date += soup.find_all("td",{"class":"searchResultsDateValue"})
location += soup.find_all("td",{"class":"searchResultsLocationValue"})
在每次迭代中,使用 page_offset、max_km 和 min_km 列表中的值修改基本 url,以转到下一页。然后根据标签和类别将网站内容分解成预定义的列表。html 中的类和标签可以通过在浏览器上检查网站来显示。
“沙希宾登”网站的 HTML
得到 html 的内容后,我提取了文本部分:
model_info_text = []
for i in range(0,6731):
model_info_text.append(model_info[i].text)
对每个列表都进行了这一过程,然后我将这些列表组合起来构建一个熊猫数据框架:
df = pd.DataFrame({"model":model_info_text, "ad_title":ad_title_text,"year":year_text, "km":km_text, "color":color_text,"price":price_text, "ad_date":ad_date_text, "location":location_text})print(df.shape)
print(df['ad_title'].nunique())
(6731, 8)
6293
Dataframe 包括 6731 个条目,但根据广告的标题,其中 6293 个条目似乎是唯一的,我认为这是区分广告的最佳选择。一些用户可能会重新发布相同的广告,或者一些广告的标题可能完全相同。
2.数据清理
我把从网站上抓取的数据保存为 csv 文件。
df = pd.read_csv('polo_data.csv')
df.head()
必须删除新的线条指示器(\n)。我使用 pandas remove() 函数,其中 regex 参数设置为 True。类似地,在价格单元中代表土耳其货币的 TL 必须被移除以进行数值分析。
df = df.replace('\n','',regex=True)
df.price = df.price.replace('TL','',regex=True)
在尝试进行任何分析之前,我们总是需要寻找缺失值并检查数据类型:
df.isna().any()
model False
ad_title False
year False
km False
color False
price False
ad_date False
location False
dtype: booldf.dtypes
model object
ad_title object
year int64
km float64
color object
price object
ad_date object
location object
dtype: object
日期的数据类型是 object。为了能够正确使用日期,我将数据 dype 转换为日期时间**。数据是土耳其语的,所以在使用 astpye() 函数之前,我将月份的名称改为了英语。我用字典来改变月份的名称。**
months = {"Ocak":"January", "Şubat":"February", "Mart":"March", "Nisan":"April","Mayıs":"May","Haziran":"June","Temmuz":"July","Ağustos":"August","Eylül":"September", "Ekim":"October", "Kasım":"November", "Aralık":"December"}df.ad_date = df.ad_date.replace(months, regex=True)#change the datatype
df.ad_date = pd.to_datetime(df.ad_date)
在读取 csv 文件时,“km”列被截断,该列显示汽车已经行驶了多少公里。这是因为“点”在千中使用。例如,25.000,即 25,000 被检测为 25.0。为了解决这个问题,我将“km”列乘以 1000。为了能够将“km”列的数据类型改为数字(int 或 float),我还删除了“.”和“,”字符。
df.km = df.km * 1000df.iloc[:,5] = df.iloc[:,5].str.replace(r'.','')
df.iloc[:,5] = df.iloc[:,5].str.replace(r',','') #change the datatype
df.price = df.price.astype('float64')
在土耳其,由于人口分布不均,位置可能是决定二手车价格的一个因素。我们的数据框架中的位置数据包括城市和地区。我不认为同一个城市不同区的价格变化。因此,我修改了位置数据,只包含了城市的名称。
位置信息的格式为 CityDistrict(中间没有空格)。地区名称以大写字母开头,用于区分城市和地区。我用的是 python 的 re 模块的 sub() 函数。
import res = df['location']
city_district = []for i in range(0,6731):
city_district.append(re.sub( r"([A-Z, 'Ç', 'İ', 'Ö', 'Ş', 'Ü'])", r" \1", s[i]).split())city_district[:5]
[['Ağrı', 'Merkez'],
['İstanbul', 'Kağıthane'],
['Ankara', 'Altındağ'],
['Ankara', 'Çankaya'],
['Samsun', 'Atakum']]
这个 for 循环以大写字母拆分 location 列的每个单元格中的字符串。土耳其语字母表包含不在英语字母表[A-Z]范围内的字母。我也在 sub 函数中添加了这些字母。输出是两项列表的列表。我使用这个列表的第一项创建了另一个名为“city”的列。
city = []
for i in range(0,6731):
city.append(city_district[i][0])city[:5]
['Ağrı', 'İstanbul', 'Ankara', 'Ankara', 'Samsun']df['city'] = city
nunique() 函数计算对探索性数据分析和结果确认都有用的唯一值。
df.city.nunique()
81
土耳其有 81 个城市,因此数据集包括每个城市至少一辆汽车。
3。探索性数据分析
价格
了解目标变量总是好的。在我们的例子中,目标变量或因变量是价格。
print(df.price.mean())
print(df.price.median())
83153.7379289853
64250.0
平均值远高于中值,这表明存在异常值或极值。让我们同时检查最大值和最小值:
print(df.price.max())
print(df.price.min())
111111111.0
24.0
这种价值观显然是错误的。除非镀金,否则没有超过 1 亿英镑的大众马球。同样,24 土耳其里拉的价值也是不可能的。在使用 sort_values() 函数对 price 列中的值进行排序之后,我检测到了一些异常值,并使用 pandas drop() 函数通过传递要删除的值的索引来删除它们。让我们检查新的平均值和中间值:
print(df.price.mean())
print(df.price.median())
print(df.price.median())66694.66636931311
64275.0
25000.0
平均值仍高于中值,但差异并不极端。我还检查了 mode,这是最常出现的值。平均值高于中值表明数据是正确的或正偏态的,这意味着我们有更多的较低价格和一些具有较高值的异常值。被排序为均值>中值>众数的集中趋势度量是正(右)偏度的指示。我们可以用分布图仔细检查:
x = df.price
plt.figure(figsize=(10,6))
sns.distplot(x).set_title('Frequency Distribution Plot of Prices')
从图中可以看出,数据是右偏的,25000 左右的峰值向我们展示了该模式。检查分布和异常值的另一种方法是箱线图**😗*
plt.figure(figsize=(8,5))
sns.boxplot(y='price', data=df, width=0.5)
蓝框的底部和顶部分别代表第一个四分位数(25%)和第三个四分位数(75%)。第一个四分位数意味着 25%的数据点低于该点。中间的线是中位数(50%)。异常值用最大线上方的点表示。
日期
我不认为日期本身对价格有影响,但网站上广告的等待时间是一个需要考虑的因素。更长的等待时间可能会促使业主降价。如果一个广告在网站上停留了很长时间,这可能是因为价格设置不当。因此,我将添加一个列,表明广告已经在网站上的天数。数据于 2020 年 1 月 18 日报废。
df['ad_duration'] = pd.to_datetime('2020-01-18') - df['ad_date']
Ad_duration 必须是数字数据,因此需要删除数字旁边的“天数”。我用熊猫 replace() 函数去掉了‘天’。
让我们检查广告持续时间数据的分布:
print(df.ad_duration.mean())
print(df.ad_duration.median())
12.641540291406482
10.0
平均值高于中值,有许多异常值。数据是右偏的。为了更好地理解,我还绘制了小于 50 的数据点:
地点
有 81 个不同的城市,但 62%的广告都列在前 10 个城市,伊斯坦布尔占 23%的广告。
a = df.city.value_counts()[:10]
df_location = pd.DataFrame({"city": a , "share": a/6726})df_location.share.sum()
0.6216176033303599
广告数量排名前十的城市
颜色
看起来大众 polo 的最佳颜色选择是白色。一半以上的汽车是白色的,其次是红色和黑色。前三种颜色覆盖了 72%的汽车。
贝亚兹:白色,科勒姆兹:红色,西亚赫:黑色
年
车龄肯定会影响价格。然而,用 is 代替汽车的型号年份更有意义。所以我用当年的“年份”一栏来代替。
df['age'] = 2020 - df['year']
从分布来看,大部分车龄不到 10 年。在 10 处有一个巨大的下降,然后是一个上升的趋势。
公里
公里值显示了车开了多少,所以它绝对是决定价格的一个重要因素。Km 数据近似呈正态分布。
print(df.km.mean())
print(df.km.median())
141011.5676479334
137000.0
广告标题
广告标题是广告的一种说明。卖家试图用数量有限的人物来吸引潜在买家。一旦广告被点击,另一个带有图片和更详细信息的页面就会打开。然而,第一步是让人们点击你的广告,所以广告标题在销售过程中起着至关重要的作用。
我们来看看大家一般都在标题里写些什么。我在这个任务中使用了 wordcloud 。
#import dependencies
from wordcloud import WordCloud, STOPWORDS
WordCloud 唯一需要的参数是一个文本。您可以通过键入“?其他可选参数。我们无法将列表输入到 wordcloud,所以我通过连接 ad_title 列中的所有标题创建了一个文本:
text_list = list(df.ad_title)
text = '-'.join(text_list)
然后用这段文字生成了一个单词云:
#generate wordcloud
wordcloud = WordCloud(background_color='white').generate(text)#plot wordcloud
plt.figure(figsize=(10,6))
plt.imshow(wordcloud, interpolation='bilinear')
plt.axis("off")
plt.show()
无停用词的词云
单词云的想法非常简单。越频繁出现的单词显示得越大。这是一个信息量大、易于理解的文本分析工具。然而,上面的 wordcloud 并没有告诉我们太多,因为“大众”、“大众”和“polo”这些词并不是我们要找的。它们展示了我们正在分析的品牌。在这种情况下,我们要使用 wordcloud 的停用词参数,列出需要排除的词。
stopwords = ['VW', 'VOLKSWAGEN', 'POLO', 'MODEL', 'KM']
wordcloud = WordCloud(stopwords=stopwords).generate(text)plt.figure(figsize=(10,6))
plt.imshow(wordcloud, interpolation='bilinear')
plt.axis("off")
plt.show()
带停用词的单词云
这次我没有使用背景颜色参数,只是为了显示不同之处。这些话是土耳其语,所以我会给一个简短的解释:
- “Hatası”:没有任何问题
- “Sahibinden”:从所有者(这很重要,因为人们倾向于从所有者而不是经销商那里购买)。
- “Otomatik”:自动变速器
- “Boyası”:无油漆(由于裂纹、划痕或维修,汽车的任何部分都没有油漆)
其他的话主要是关于干净,没有任何以前的维修。
型号
型号栏包括三种不同的信息:发动机尺寸、燃料类型和变型。检查完这些值后,我发现对于所有单元,只有引擎大小信息是完整的。大多数单元格都缺少燃料类型和变体,因此我为发动机大小创建了一个单独的列。
空格后的前三个字符代表发动机尺寸。我首先删除了空格,并从 model 列中提取了前三个字符:
#remove spaces
df.model = df.model.replace(' ','',regex=True)engine = [x[:3] for x in df.model]
df['engine'] = engine
让我们来看看不同发动机尺寸的价格变化:
df.engine.value_counts()
1.4 3172
1.6 1916
1.2 1205
1.0 409
1.9 20
1.3 4
Name: engine, dtype: int64df[['engine','price']].groupby(['engine']).mean().sort_values(by='price', ascending=False)
似乎平均价格随着发动机尺寸的增加而降低。1.3 可以忽略,因为只有 4 辆车采用 1.3 发动机。与 1.0 和其他发动机尺寸有很大差距,因为 1.0 是较新的型号。正如你在下面的图表中看到的,发动机尺寸为 1.0 的汽车平均车龄和公里数都最低,这表明它们是较新的车型。
不同发动机尺寸的平均车龄和公里数
4。回归模型
线性回归是一种广泛使用的监督学习算法,用于预测连续的因变量(或目标变量)。根据独立变量的数量,它可以是简单或多元线性回归的形式。我创建了一个多元线性回归模型,因为我使用了许多自变量来预测因变量,即二手车的价格。
我们不应该只是使用所有的独立变量,而没有任何预处理或事先判断。特征选择是决定在模型中使用哪些特征(独立变量)的过程。特征选择是一个非常关键的步骤,因为使用不必要的特征会对性能产生负面影响,而删除重要的特征会妨碍我们获得高精度。
我们可以使用回归图来检查因变量和自变量之间的关系。我检查了 km 和价格之间的关系,我认为这是高度相关的。
plt.figure(figsize=(10,6))
sns.regplot(x='km', y='price', data=df).set_title('Km vs Price')
显而易见,随着公里数的增加,价格下降。然而,也有例外。根据上面的回归图,公里数高于 400000 的汽车可以标记为异常值。为了提高模型的准确性,我去除了这些异常值。离群值往往会使模型过度拟合。
df = df[df.km < 400000]
plt.figure(figsize=(10,6))
sns.regplot(x='km', y='price', data=df).set_title('Km vs Price')
Km 与剔除异常值后的价格
现在好多了!
在对年龄和价格应用相同的步骤后,观察到类似的关系:
剔除异常值后的年龄与价格
我还检查了广告时长和引擎大小与价格之间的关系。发动机尺寸越大,平均价格越低。然而,广告持续时间似乎对价格几乎没有影响。
****
检查变量之间关系的另一种方法是相关矩阵**。熊猫 corr() 函数计算数值变量之间的相关性。**
该值越接近 1,相关性越高。-'号表示负相关。这些值与上面的回归图一致。
我们也可以使用 seaborn 热图来可视化相关矩阵:
corr = df.corr()
plt.figure(figsize=(10,6))
sns.heatmap(corr, vmax=1, square=True)
根据右边的颜色表,两个变量相交处的方框颜色显示相关值。
线性回归模型
在检查了变量的相关性和分布后,我决定用车龄、公里数、引擎大小和广告时长来预测一辆二手车的价格。
我使用了 scikit-learn ,它提供了简单有效的机器学习工具。
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LinearRegression
from sklearn.metrics import r2_score
我提取了要使用的特性(列):
X = df[['age','km','engine','ad_duration']] #independent variables
y = df['price'] #dependent (target) variable
然后使用 scikit-learn 的 train_test_split 函数,我将数据划分为训练和测试子集。分离训练集和测试集是每个机器学习算法中非常重要的一步。否则,如果我们在同一个数据集上训练和测试,我们将要求模型预测它已经知道的东西。
X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=42)
然后我创建了一个 LinearRegression()对象,用训练数据集对它进行了训练。
linreg = LinearRegression()linreg.fit(X_train, y_train)
是时候衡量模型的准确性了。我在训练和测试数据集上测量了模型的准确性。如果训练数据集上的精度远远高于测试数据集上的精度,我们就有一个严重的问题:过拟合。我不会去详细了解过度拟合。这可能是另一个帖子的主题,但我只想简单解释一下。过度拟合意味着模型过于具体,不能很好地概括。过度拟合模型试图捕获训练数据集中的噪声和极值。
linreg.score(X_train, y_train)
0.8351901442035045linreg.score(X_test, y_test)
0.8394139260643358
比分非常接近,这很好。这里的分数是 R 平方 分数,它是确定实际数据点与拟合回归线有多接近的度量。R 平方值越接近 1,我们的模型就越准确。r 平方度量了我们的模型解释了多少目标变量的变化。
****残差图用于检查实际值和预测值之间的误差。如果一个线性模型是合适的,我们期望看到误差被随机传播并且具有零均值。
plt.figure(figsize=(10,6))
sns.residplot(x=y_pred, y=y_test)
实际值和预测值之间的误差
这些点的平均值可能接近于零,但显然它们不是随机分布的。该分布接近 U 形,这表明线性模型可能不是这项任务的最佳选择。
在这种情况下,我想使用 scikit-learn 的 RandomForestRegressor() 来尝试另一个模型。随机森林是建立在决策树上的集成方法。威尔·科尔森的这篇文章对决策树和随机森林做了全面的解释。随机森林通常用于分类任务,但也适用于回归。
from sklearn.ensemble import RandomForestRegressorregr = RandomForestRegressor(max_depth=5, random_state=0, n_estimators=10)
与线性回归不同,随机森林有一些关键的超参数需要优化。max _ depth是一棵树的最大深度(不言自明),它控制着一棵树有多深或者你想要多少个分支。 n_estimator 是一片森林中的树木数量。决策树容易过度拟合,这意味着你很容易使它过于具体。如果 max_depth 太高,可能会导致模型过拟合。我手动更改了 max_depth,以便检查准确性和过度拟合。但是 scikit-learn 提供了非常好的超参数调优工具:RandomizedSearchCV和GridSearchCV。对于更复杂的任务和模型,我强烈推荐使用它。****
**print('R-squared score (training): {:.3f}'
.format(regr.score(X_train, y_train)))
R-squared score (training): 0.902print('R-squared score (training): {:.3f}'
.format(regr.score(X_test, y_test)))
R-squared score (training): 0.899**
测试集上的 r 平方得分是 0.899,这表明与线性回归相比有显著的改进。我还尝试将 max_depth 参数设置为 20,结果是在 overfit 模型上,如下所示。模型在训练集上非常准确,但在测试集上的准确性变得较低。
**regr = RandomForestRegressor(max_depth=20, random_state=0, n_estimators=10)regr.fit(X_train, y_train)print('R-squared score (training): {:.3f}'
.format(regr.score(X_train, y_train)))
R-squared score (training): 0.979print('R-squared score (training): {:.3f}'
.format(regr.score(X_test, y_test)))
R-squared score (training): 0.884**
最后我根据车型查了一下我车的价格:
**regr.predict([[4,75000,1.2,1]])
array([99743.84587199])**
模型建议我以差不多 10 万英镑的价格卖掉我的车,这比我心目中的价格要高。然而,我的车出了事故,经过修理,价格降低了。这些信息没有被作为独立变量考虑,这就把我们带到了本文的最后一部分:进一步改进。
4.进一步改进
有许多方法可以改进机器学习模型。我觉得最根本最有效的一条就是多收集数据。在我们的例子中,我们可以(1)收集更多汽车的数据,或者(2)收集当前数据集中更多汽车的信息,或者两者都收集。对于第一个,有其他网站出售二手车,所以我们可以通过添加新车来增加数据集的大小。对于第二个问题,我们可以从“ sahibinden ”网站收集更多关于汽车的数据。如果我们点击一个广告,另一个有详细信息和图片的页面就会打开。在这一页,人们写下汽车的问题,以前的事故或维修等等。这种信息无疑是有价值的。
另一种改进方法是调整模型超参数。我们可以使用 RandomizedSearchCV 来找到最佳的超参数值。
结论
我试图给你一个机器学习项目如何建立的概述。尽管这不是一项非常复杂的任务,但大多数数据科学项目都遵循类似的模式。
- 定义问题或疑问
- 收集和清理数据
- 进行探索性数据分析,以获得一些关于数据的见解
- 建立一个模型
- 评估模型
- 除非结果令人满意,否则请返回前面的任何步骤。
用机器学习技术预测二手车价格
比较五种不同 ML 模型的性能
你可以在我的 github 页面上找到这项研究的所有 Python 脚本。如果您感兴趣,您还可以在同一个存储库中找到用于该研究的数据清理的脚本。
谁应该读这个?
如果您有兴趣了解从零开始构建机器学习系统,包括:
- 数据清理期间的调整
- 探索性数据分析
- 执行机器学习模型:随机森林,线性回归,岭回归,拉索,KNN,XGBoost
- 模型的性能比较
- 以专业的方式报告研究结果
问题
业内新车的价格由制造商确定,政府以税收的形式支付一些额外的费用。因此,购买新车的客户可以放心,他们投资的钱是值得的。但由于新车价格上涨,以及客户因缺乏资金而无法购买新车,二手车销售在全球范围内呈增长趋势(Pal,Arora 和 Palakurthy,2018)。需要一种二手车价格预测系统来使用各种特征有效地确定汽车的价值。即使有网站提供这种服务,他们的预测方法也不一定是最好的。此外,不同的模型和系统可能有助于预测二手车的实际市场价值。在买卖时,了解它们的实际市场价值是很重要的。
客户端
能够预测二手车的市场价值对买卖双方都有帮助。
**二手车销售商(经销商)😗*他们是可能对本研究结果感兴趣的最大目标群体之一。如果二手车卖家更好地了解什么使一辆车可取,什么是二手车的重要特征,那么他们可能会考虑这些知识,并提供更好的服务。
**在线定价服务:**有些网站提供汽车的估价。他们可能有一个很好的预测模型。然而,拥有第二个模型可能有助于他们向用户提供更好的预测。因此,这项研究中开发的模型可能有助于在线网络服务,告诉二手车的市场价值。
**个人:**有很多人在他们人生的某个阶段对二手车市场感兴趣,因为他们想卖掉自己的车或买辆二手车。在这个过程中,支付过高或低于市场价值出售都是一个大问题。
数据
本项目使用的数据是从 Kaggle 下载的。它是由 Kaggle.com 用户奥斯丁·里斯上传到 Kaggle 上的。奥斯汀·里斯从 craigslist 上搜集了这些数据,目的是为了非盈利。它包含了 Craigslist 提供的关于汽车销售的几乎所有相关信息,包括价格、状况、制造商、纬度/经度等栏目,以及 22 个其他类别。
数据角力
在本节中,我们将讨论如何对 craigslist 二手车数据文件应用数据清理和争论方法。
在进行数据清洗之前,对数据集进行了一些探索和数据可视化。这为如何处理缺失值和极端值提供了一些思路和指导。在数据清理之后,再次应用数据探索,以便理解数据的清理版本。
**数据清理:**数据清理的第一步是删除不必要的特征。为此, ‘url ‘,’ image_url ‘,’ lat ‘,’ long ‘,’ city_url ‘,’ desc ‘,’ city ‘,’ VIN’ 等功能全部被删除。下一步,调查该特性的零点数量和零点数据点的百分比(表 1)。
下一步,极值被删除,因为它们抑制了模型的预测能力。首先,标价超过 10 万美元的汽车被取消了。在 550313 个数据点中,只有 580 个数据点的价格超过 100k。它只能满足一小部分买家的需求。此外,有 61726 辆汽车的价格低于 750 美元。这些值也被从数据集中删除,因为这些价格对数据来说是噪音。其次,里程表值超过 300,000 英里但低于 10 英里的汽车被取消。最后,早于 1985 年的汽车被淘汰。对于我们的分析,这些数据点可以被视为异常值。
第二步,用适当的值填充一些缺失的值。对于缺少的’条件’值,注意根据类别进行填充。计算所有’条件’子类别的平均里程表。然后,通过考虑每个条件子类别的平均里程表值来填补缺失值。另外,车型值高于 2019 年的车填为’新’,2017-2019 年之间填为’如新’。在此过程结束时,清除了“条件”功能中所有缺失的值。
其他的用’ ffill’ 的方法填充。此方法将最后一个有效观察向前传播到下一个有效观察。因此,最后一个已知值在每个时间点都可用。到目前为止,里程表,条件,条件和价格功能的所有缺失值都很清楚。经过这一步,所有数据都变得干净了。在此操作之后,将对数据中的 380,962 个观察值进行研究和分析。
探索性数据分析
在探索数据的同时,我们将借助视觉效果来观察不同的功能组合。这将有助于我们更好地理解我们的数据,并给我们一些关于数据模式的线索。
考察物价走势
价格是我们在这项研究中预测的特征。在应用任何模型之前,看看价格数据可能会给我们一些想法。
通过查看图 1,可以观察到大多数二手车的价格低于 20,000 美元。此外,我们看到仍有相当数量的汽车价格超过 2 万美元。我们可以猜测所有类型的汽车可能便宜或昂贵。但是,仍然优秀,喜欢新的,良好的条件的汽车是最受欢迎的汽车在二手车市场(图 2)。打捞车在流行程度上是遵循这三个类别的。因此,仅仅考虑汽车的类型或状况,很难对汽车的价格做出准确的估计。但我们可以告诉它,某些条件的汽车是受欢迎的和更高的机会出售。
二手车的流行特征
在购买二手车时,人们会认真关注车上的里程表值。我们可以看到里程表显著地改变了汽车的价格(图 3)。另一方面,这并不意味着只销售低里程表汽车。根据价格,高里程表汽车也有买家(图 4)。此外,最受欢迎的二手车是里程表在 100k 左右的车。直到 150k 的里程表,市面上的车很多。
汽车制造商是二手车市场上的另一个重要变量。福特和雪佛兰是北美占主导地位的制造商之一(图 5)。丰田和日产作为大厂商遵循订单。可以得出结论,日系车在二手车市场占有相当大的份额。但是,美国车仍然是按需供应,占主导地位。
**变速器:**变速器是二手车市场中另一个占主导地位的子类别。根据图 6,自动变速器对人们对汽车的偏好有很大的影响。从图 6 中可以看出,2000 年以后,自动变速器汽车在增加。2009 年,这一数字有所下降。全球经济衰退可能会影响二手车市场。另一个有趣的趋势是,2009 年后,其他传播方式在增加。它的市场份额相比自动挡还是那么低,但还是很可观的。其他传输类型增加可能是由几个原因造成的。第一种可能性是无级变速器(CVT)增加。CVT 更环保更省油。这种技术可能会得到推广。另一种可能是 Craigslist 网站上的一些卖家没有填写汽车信息的传输部分。网站可能会直接将他们归入“其他”类别。这也解释了“其他”类别传播的增加。
**传动系统类型:**在评估一辆车的时候,了解是什么影响了它的状况是很重要的。图 7 告诉我们,四轮驱动汽车更加耐用和可靠。可以看出,从数量上看,4wd 的车是最受欢迎的。从长远来看,与 rwd 和 fwd 传动系统相比,它们可以保持更好的运行能力。4wd 在汽车的“优秀”、“像新的一样”和“状况良好”方面的数字最高。另一方面,我们需要记住,与总数相比,很难说四轮驱动汽车具有更高的“优秀”率和“喜欢新汽车”率(图 7)。此外,通过查看表 4,
我们可以看到,对于所有分位数,所有动力传动系统类型的平均里程表彼此非常接近。这也告诉我们,在二手车市场,驾驶类型可能不会影响汽车的里程表。但是它们的受欢迎程度在驾驶员中是不同的(表 3 和图 8)。
检验&假设
为了理解什么影响二手车价格的变化,将通过使用推断统计方法来检查数据 sat 中可用特征之间的关系。基于图表的主要假设是价格必须受到里程表和条件的影响。一定还有其他显著影响价格的特征。这将在研究的后期阶段进行调查。
第一个假设:
空假设:汽车的价格和里程表没有显著的关系
替代假设:价格与里程表之间存在显著关系。
第二个假设 :
无效假设:汽车的价格和状况之间没有显著的关系
替代假设:价格和条件之间有很大的关系。
里程表 vs 价格
首先,检验第一个假设。在检验两个数值变量之间的关系时,独立 t 检验是一种合适的方法。另一方面,这个测试有一些假设。方差齐性是假设之一。为了检查方差齐性假设是否被违反,应用了 Levene 检验。
**检验方差的均匀性:**Levene 检验的结果:
Levene 结果(统计值=335641.8310266318,p 值=0.0)
这意味着方差的同质性被破坏了。在这种情况下,我们需要使用韦尔奇检验。Welch t 检验是一种非参数单变量检验,用于检验两个不相关组的均值之间的显著差异。当方差相等的假设存在违规时,它是独立 t 检验的替代方法。因此,它适用于这种情况。以下是韦尔奇测试的结果:
Welch's t-test= 740.70p-value = 0.00Welch-Satterthwaite Degrees of Freedom= 276855.87
在这里,p 值非常重要。这说明里程表和汽车价格之间有很大的关系。作为参考,进行独立的 t 检验没有坏处。它可以提供一些想法,即使它不是里程表和价格功能的健壮方法。
**检查正态性:**对于检查正态性,q-q 图有助于我们。图 9 告诉我们这违反了常态。这意味着所使用的数据点不是正态分布的。此外,夏皮罗-维尔克检验用于检查正态性。
结果:(0.9586305022239685,0.0)
这里,第一个值是 W 检验统计量,第二个值是 p 值。对于 N > 5000,W 检验统计是准确的,但 p 值可能不准确。通过考虑夏皮罗-维尔克检验的 p 值,可以得出数据不是正态分布的结论。
在这种情况下,我们在初始数据点上有问题。或许,过滤数据可以解决这个问题。为此,远离平均值两个标准差的里程表和价格的值被丢弃,并应用独立 t 检验。
图 9: Q-q 图
如前所述,t 检验在这里是不合适的,因为它违反了方差相等假设和正态假设。另一方面,我们仍然可以解释这个结果,同时记住它是不可靠的。根据表 5,相关性为 0.90。这表明价格和里程表之间有很强的联系。此外,p 值较低,具有统计学意义。效应大小(科恩的 d)是 4.17,这是一个很大的值。d 为 4 表示它们相差 4 个标准差。这意味着两组的平均值相差 4 个标准偏差或更多,因此差异显著。
通过考虑这些韦尔奇检验的结果和表 5,可以得出结论:里程表和价格有显著的关系。因此,第一个假设的零假设被拒绝。拒绝 null 有一些可能的含义:
- 替代假设是真的。
- 可能存在类型 2 错误,这意味着零假设被错误地拒绝
- 是的,有统计学意义。但这并不意味着实际意义。
条件 vs 价格
这项研究的第二个假设关注汽车状况对其价格的影响。为了理解这种关系,表 6 和图 6 可能有用。通过查看图 10,可以说“状况”严重影响了汽车的中值价格。另一方面,在条件值中有许多异常值,这是这样一个 lar 数据集的预期结果。我们在图 10 的底部没有看到异常值。这主要是因为在数据清理期间,价格低于 750 美元的汽车被丢弃。
现在,是时候检查条件和价格之间的关系了。在应用任何线性关系测试之前,必须应用诊断测试。因此,可以检查该关系是否满足四个假设:残差的线性、残差的独立性、残差的正态分布、残差的等方差。为了检验正态性,进行了 Jarque-Bera,为了检验残差的等方差,应用了综合检验。此外,为了检查多重共线性,使用了条件数(condno)检验,为了检测自相关的存在,应用了德班-沃森检验(表 7)。
考虑到表 7,Jarque-Bera p 值和 Omni p 值非常重要。这表明存在违反正态性和方差齐性的情况。此外,Durbin Watson (DW)统计是对统计回归分析中残差的自相关性的测试。德宾-沃森统计值将总是在 0 和 4 之间。值为 2.0 意味着在样本中没有检测到自相关。从 0 到小于 2 的值表示正自相关,从 2 到 4 的值表示负自相关。“条件”和“价格”的德宾沃森得分是 1.49,这表明这是一种微弱但正相关的关系。
对“条件”结果的推断
假设是:
H0 :汽车的价格和状况没有太大的关系
通过考虑测试结果,我们无法拒绝零假设。然而,该假设是基于线性关系。因此,这种情况有几种可能的解释:
“条件”和“价格”之间可以有关系,但不是线性关系。它可以是非线性关系。
可能存在线性关系,但我们的数据可能不具有代表性,使我们看不到这种关系。
零假设是正确的,在“条件”和“价格”之间没有显著的关系。
推断统计学的挑战
在这个数据集中,最大的挑战之一是预测变量的分布违反正态性。这就是为什么,经典的统计方法对分析这些数据帮助不大。此外,数据集中的 14 个变量中只有 3 个数值变量。这限制了我们使用 Pearson-r 相关性的机会。
因此,我们将进入下一部分。在下一节中,将应用机器学习模型,并通过使用平均绝对误差(MAE)、均方误差(MSE)和均方根误差(RMSE)来测试模型的性能。
机器学习模型
本节使用应用机器学习模型作为数据分析的框架。数据集是一种监督数据,指的是将因变量模型拟合到自变量,目的是为未来的观察结果准确预测因变量或了解变量之间的关系(Gareth,Daniela,Trevor,& Tibshirani,2013)。关于数据集,文献表明下列方法可能是合适的。
在本节中,将按顺序应用这些机器学习模型:
随机森林
里脊回归
套索
k-最近邻
XGBoost
此外,在岭回归之前,将应用简单的线性模型并考虑结果。
数据预处理
**标签编码。**在数据集中,有 13 个预测因子。其中两个是数字变量,其余的是分类变量。为了应用机器学习模型,我们需要特征的数字表示。因此,所有非数字特征都被转换成数字形式。
**训练数据。**在此过程中,20%的数据被拆分为测试数据,80%的数据作为列车数据。
**缩放数据。**在研究前几节中的数据时,我们发现数据不是正态分布的。如果不进行缩放,机器学习模型将尝试忽略低值特征的系数,因为与高值特征相比,它们的影响非常小。
在缩放时,使用正确的方法缩放也很重要,因为不适当的缩放会导致不适当的目标量化和不适当的绩效衡量(Hurwitz,e .,& Marwala,2012)。最小-最大缩放器是合适的,特别是当数据不是正态分布,并希望离群值有减少的影响。此外,脊和套索都受到特征大小的影响,以执行正则化。因此,对数据集使用了最小-最大缩放器。
随机森林
随机森林是多个决策树的集合。深度决策树可能会过度拟合,但随机森林通过在随机子集上创建树来防止过度拟合。这就是为什么,这是一个很好的分析模型。
在分析中,创建了 200 棵树。一般来说,树越多,效果越好。结果,获得 4001.8 RMSE 和 2122.92 平均绝对误差(MAE)(表 8)。
图 11:随机森林中的单一决策树
如果我们看一下图 11,我们会看到有七个叶节点。这个树只使用了三个变量:年份、驱动和燃料。叶节点没有问题,因为它们是进行最终预测的地方。要对一个新点进行分类,只需沿着树向下移动,使用该点的特征来回答问题,直到到达一个叶节点,在该叶节点上,类就是预测。
**变量重要性:**为了量化整个随机森林中所有变量的有用性,我们可以看看变量的相对重要性。图 12 是一个简单的特征重要性条形图,用来说明变量相对重要性的差异。对于本研究,达到 90%的累积重要性被视为成功。
**Model with only important features:** Number of features for 90% cumulative importance is 7 (Fig. 13). The features are: year, odometer, make, drive, fuel, manufacturer, cylinders. The ultimate purpose of the modelling is to get a smaller number of features that can give us a strong prediction. At this point, the model was run with only these seven important features. The new RMSE is 3960.11 (Table 9). This score is slightly better than the full model (4001.80 % vs 3960.11). In addition, this performance was obtained just by using 7 features instead of 13\. Therefore, it can be considered as an improvement in both prediction power and computational cost.
线性回归
在应用脊和套索之前,检查线性回归结果可能是有用的(表 10)。
正如我们在表 10 中看到的,与随机森林相比,线性回归的性能并不太好。实际值和预测值之间的差异值得注意(图 14)。这就是为什么我们需要不同的模型来给出更好的预测结果。
岭回归
普通最小二乘法(OLS)给出无偏回归系数(数据集中观察到的最大似然估计)。岭回归和套索允许正则化(“收缩”)系数。在图 15 中,可以看到系数是如何随着α值的增加而缩小的。
为了在岭回归中找到最佳α值,应用了交叉验证。结果如表 11 所示。
与 OLS 相比,里奇的表现几乎相同。考虑图 16,岭回归表明,这六个变量是最重要的:年份,里程表,燃料,气缸,标题状态和驱动器。
拉索
Ridge 缩小了变量的系数,但不会使它们为零。这在某些情况下可能是好的,但在变量数量相当大的情况下,这可能会给模型解释带来挑战(Gareth、Daniela、Trevor 和 Tibshirani,2013)。对于这个数据集,变量的数量并不大,所以不太需要套索模型。然而,看看 lasso 可以给我们另一个视角。而且,除了投入时间和精力之外,对数据集应用套索没有任何坏处。
为了从图 17 中找到最佳λ值,应用了交叉验证。在这次评估中,获得的 RMSE 是 7578.82(表 12)。
与山脊结果相似,拉索也给出了六个显著特征: 年份、里程表、燃料、汽缸、冠军状态、驱动 。在进行最终解释时,可以考虑这一点。
K-最近邻(KNN)
当你的数据集足够小时,可以使用 KNN 分类器,这样 KNN 分类器可以在更短的时间内完成运行。KNN 算法可以与最精确的模型竞争,因为它做出高度精确的预测。因此,我们可以将 KNN 算法用于需要良好预测但不需要人类可读模型的应用程序。预测的质量取决于距离度量。因此,KNN 算法适用于具有足够领域知识的应用程序(IBM 知识中心,n.d .)。因为我们有 13 个用于预测的特征,KNN 是适用于本研究的合适方法。对于 RMSE 值的评估,我们可以看一下表 12。
从表 13 和图 19 可以看出,当 k 为 7 时,RMSE 值最低。另一方面,k 为 2 和 7 的 RMSE 值之间没有显著差异。这里的基本原理是,如果一组 K 值看起来或多或少一样好,那么我们不妨选择最简单的模型——也就是具有最少数量预测值的模型。对于我们的情况,我们可以选择 2 个预测值,因为它具有最低的 RMSE 值(表 13)。但是,考虑到以前的模型,六七个预测器仍然有很强的理由选择,并与它们更加一致。
XGBoost
XGBoost 是梯度推进方法的一个具体实现,它使用更精确的近似来寻找最佳的树模型。它采用了许多巧妙的技巧,使得它异常成功,尤其是在结构化数据方面。XGBoost 还有额外的优势:训练非常快,可以并行化/跨集群分布。因此,XGBoost 是本研究中使用的另一个模型。XGBoost 的性能如表所示(表 14)。
**拟合模型:**第一步,目标参数设置为线性。
下一步,进行三重交叉验证。最大深度选择为 3。因此模型保持简单。最后,将执行升压的次数设置为 50。
图 20:单决策树的 XGBoost 图
图 20 提供了该模型的不同视角。给定值(叶)的最终预测是每个分支预测的总和。另一方面,决策树可能不是为我们的数据集进行预测的稳健方式,因为它试图进行回归,但数据集有许多分类变量。除了决策树之外,特征重要性图(图 21)可以给出评估的另一个角度。通过考虑图 21,可以说里程表、制造商、年份和品牌是包含模型的重要特征。
结论
通过执行不同的模型,旨在获得不同的视角,并最终比较它们的性能。这项研究的目的是通过使用包含 13 个预测值和 380962 个观察值的数据集来预测二手车的价格。在数据可视化和探索性数据分析的帮助下,数据集被揭示,特征被深入探索。检查了特征之间的关系。在最后一个阶段,应用预测模型预测汽车价格的顺序为:随机森林、线性回归、岭回归、lasso、KNN、XGBoost。
通过考虑表 15 中的所有四个指标,可以得出结论,随机森林是预测二手车价格的最佳模型。作为回归模型的随机森林给出了最佳的 MAE、MSE 和 RMSE 值(表 14)。据 random forest 称,以下是最重要的特征:年份、里程表、品牌、驱动、燃料、制造商、气缸。这些功能仅通过使用七个列出的功能就提供了 3960.11 RMSE。
研究的局限性和进一步研究的建议
这项研究使用了不同的模型来预测二手车价格。然而,有一个相对较小的数据集来进行强有力的推断,因为观察值只有 380962。收集更多的数据可以产生更可靠的预测。其次,可能有更多的特征可以作为良好的预测指标。例如,这里有一些可能改进模型的变量:门的数量、汽油/英里(每加仑)、颜色、机械和装饰翻新时间、新旧比率、评估与交易比率。
还有一点需要改进的是,在更多技术信息的帮助下,数据清理过程可以更加严格。例如,不使用“ffill”方法,可能会有一些指标帮助更有意义地填充缺失值。
作为进一步研究的建议,在预处理数据时,可以使用一种热编码器方法,而不是使用标签编码器。因此,所有非数字特征都可以转换为名义数据,而不是序数数据(Raschka & Mirjalili,2017)。这可能会导致预测模型的性能发生重大变化。此外,在训练数据之后,代替最小-最大缩放器,可以执行标准缩放器,并且可以比较结果。可以检查不同的标度是否提高了模型的预测能力。
参考文献
IBM 知识中心。(未注明)。使用 KNN。检索自:https://www . IBM . com/support/knowledge center/SSHRBY/com . IBM . swg . im . dash db . analytics . doc/doc/r _ KNN _ usage . html
Gareth,j .,Daniela,w .,Trevor,h .,和 Tibshirani,R. (2013 年)。统计学简介
学习(第八卷)。https://doi.org/10.1016/j.peva.2007.06.006
赫维茨和马瓦拉(2012 年)。将计算智能和机器学习应用于股票市场建模时的常见错误。 arXiv 预印本 arXiv:1208.4429 。
Pal,n .,Arora,p .,Kohli,p .,Sundararaman,d .,& Palakurthy,S. S. (2018 年 4 月)。我的车值多少钱?使用随机森林预测二手车价格的方法。在信息与通信会议的未来(第 413–422 页)。斯普林格,查姆。
Raschka,s .,& Mirjalili,V. (2017 年)。 Python 机器学习。帕克特出版有限公司
基于集成分类器和自动建模的车辆事故严重度预测
Coursera 上 IBM 数据科学认证的顶点项目摘要
马修·T·雷德在 Unsplash 上的照片
简介/商务问题
这篇文章详细介绍了使用西雅图市交通局登记的车辆事故公开数据集的工作。这项工作通过识别导致各种类型交通事故的因素,预测事故严重程度,并利用这些信息将风险降至最低,从而使美国公众受益。
完整的代码可以在我的 GitHub repo 找到
目标
使用包括汽车和人的数量、交通、天气状况等特征,预测事故的严重程度为“1”或“2”。这是一个分类问题,一旦建模,西雅图市当局就可以获得以前无法获得的事故风险因素的洞察力,也让作者获得必要的完成以获得 Coursera 专业认证。
使用的数据和采取的步骤
所用的原始数据由西雅图交通部提供,采用了以下步骤:
步骤 1: 数据加载和初步观察
**第二步:**特征可视化详细分析。目标是理解潜在的利用输入变量
步骤 3: 特征工程和选择
第四步:模型拟合和训练
步骤 5 :模型评估,使用自动机器学习(也称为 AutoML)进行灵敏度检查
步骤 6 :为客户总结外卖
**第 1 步和第 2 步:**此处一并考虑。使用 Seaborn 可视化工具加载和分析交通数据,我们的目标是了解数据分布、属性和预测车辆事故严重程度的意义。
图 1:。describe()命令应用于数据集
Seaborn 可视化是无信息的,可以在 repo 上找到——它们没有在这里发表,因为这篇文章没有附加价值。因此,我分析了数据和一些解释性的西雅图点文献来破译特征。
我学到了什么?
许多特征是交通部使用的唯一标识符,并在预测事故时提供。这些包括事故钥匙、十字路口钥匙、碰撞细节钥匙、分隔车道钥匙和人行横道钥匙。
ObjectID 的独特之处在于,虽然它也是一个由点提供的分类器,但它不会复制在另一个特性中显式可用的信息。
有许多特征是二进制的和非数字的,即可以通过简单的是或否来回答。这些特征包括检查是否:超速是一个因素,行人有通行权,注意力不集中或酒后驾车是促成因素,或一辆停放的汽车被撞。
最后,还有其他非数字特征,它们有两个以上的可能条目。这些因素包括照明和路况、发生事故的路口类型以及事故发生的日期/时间。出于本文的目的,我将时间归类为非数字,因为它是每个 Python 的一个日期时间对象。
**第三步:**当考虑包括/排除什么以及可能需要什么类型的特征工程时,上面指定的列表要求一种系统的方法。我们希望确保包含有影响的因素,而不增加导致过度拟合的不必要的复杂性
哪种方法保留了最有用的信息,并删除了增加复杂性的不必要的功能?
让我们首先删除作为西雅图点管理工具的特性。这些包括报告号、事件键、交叉键和状态。我们也删除“EXCEPTRSNCODE”和“EXCEPTRSNDESC”列,在这些列中删除有条目的行,这些条目的存在只是为了通知读者某个事件缺少足够的信息。
让我们也去掉坐标 x 和 y,因为它们以一两个特定区域为中心,并被认为没有预测洞察力。
任何非数字特征都需要编码来转换成机器学习算法可以处理的数字。编码可以是顺序的,也可以是一次性的:我选择了后者,因为这些变量都没有我想要保留的固有顺序。受此方法影响的要素包括地址类型、道路和照明条件、停放的汽车是否被撞、碰撞键、天气和交叉口类型。
最后,我使用事件日期和时间提取月份和时间。时间被转换为早上、中午或晚上,随后,这个细节被一次性编码。我认为这是有意义的,因为在深夜/清晨或者季节变化使得道路更难行驶时,驾驶事故会增加
在我们继续进行模型评估之前,让我们看看上面的步骤是如何改变我们数据集中的一些关键特征的。以下是之前的快照:
图 2:显示分类、连续、字母和数字数据的原始数据集快照
这是数据集的快照,在此摘录中,我们看到地址类型被编码为超速和行人是否有通行权。这是训练数据,之前已经完成了训练-测试-分割:
图 3:带编码的原始数据快照
模型拟合和训练
完成必要的特征工程和选择后,我选择了一系列分类器——包括用于基线的虚拟分类器,训练它们,并使用许多指标评估它们在测试集上的性能。代码片段如下。
dum = DummyClassifier()
xgb = XGBClassifier()
dt = DecisionTreeClassifier()
gbc = GradientBoostingClassifier()
rfc = RandomForestClassifier()clfs = [dum,xgb,dt,gbc,rfc]
f1_Scores = []
jaccard_Scores = []
log_loss_Scores = []for clf in clfs:
clf.fit(x_train,y_train)
ypred = clf.predict(x_test)
ypred_proba = clf.predict_proba(x_test)
f1score = f1_score(y_test,ypred)
logloss = log_loss(y_test,ypred_proba)
jaccard = jaccard_score(y_test,ypred)
f1_Scores.append(f1score)
jaccard_Scores.append(jaccard)
log_loss_Scores.append(logloss)
第五步:我在下面的 Excel 表格中总结了模型性能。最佳实践建议使用多个指标来评估性能:
图 4;绩效总结
上表显示了 80 年代中期的 F1 分数和低于 0.5 的对数损失分数,这是对虚拟分类器基线性能的改进。我们将在结论中讨论上述指标对我们客户的影响,但我想先谈谈另外两个话题:
- XGBoost 上的 GridSearchCV 在上述分数上没有提供任何改进
- 我用了 TPOT 的 AutoML 软件包。请参见下面的代码片段,了解由此产生的性能:
%pip install tpot --userimport tpot
from tpot import TPOTClassifier# define model evaluation
cv = RepeatedStratifiedKFold(n_splits=10, n_repeats=3, random_state=1)
# define search
model = TPOTClassifier(generations=5, population_size=50, cv=cv, scoring='f1', verbosity=2, random_state=1, n_jobs=-1)
# perform the search
model.fit(x_train,y_train)
# export the best model
model.export('tpot_capstone_best_model.py')
然后将导出的模型重新引入数据集中进行训练,并在测试集上进行评估。正如在下面的代码片段中观察到的,TPOT 选择对性能最高的 49%的特性使用决策树分类器,结果 F1 值为 0.84,logloss 值为 0.5。 AutoML 更快,但是没有返回比传统方法更有希望的结果。
from sklearn.pipeline import make_pipeline
from tpot.export_utils import set_param_recursive
from sklearn.feature_selection import SelectPercentile, f_classifexported_pipeline = make_pipeline(
SelectPercentile(score_func=f_classif, percentile=49),
DecisionTreeClassifier(criterion="entropy", max_depth=6, min_samples_leaf=19, min_samples_split=7)
)
# Fix random state for all the steps in exported pipeline
set_param_recursive(exported_pipeline.steps, 'random_state', 1)exported_pipeline.fit(x_train, y_train)
tpot_y_pred = exported_pipeline.predict(x_test)
tpot_y_pred_prob = exported_pipeline.predict_proba(x_test)f1score = f1_score(y_test,tpot_y_pred)
logloss = log_loss(y_test,tpot_y_pred_prob)
jaccard = jaccard_score(y_test,tpot_y_pred)
第六步:我们可以给我们的客户——西雅图交通部——一个模型,展示在识别什么会导致特别严重的事故以及什么不会导致特别严重的事故方面的表现。
我们的模型比盲目猜测要好,因为 log_loss 分数 0.47 比基于类分布的“哑分数”0.59 要好。它不仅能够准确地预测严重性,而且能够区分不同的类别——通过超过基准执行者(虚拟分类器)的高 F1 分数来衡量。
西雅图交通部的见解:
- 在预测事故严重程度时,一年中的月份是第二个最有影响力的变量。某些月份天气状况不佳,司机注意力不集中,这是有道理的。西雅图市应该考虑安全计划,在一年中有问题的时候加大交通事故预防力度
- 事故中涉及的人员和车辆数量对严重程度有影响。西雅图市应考虑在一个月或一天的特定时间限制乘客乘车,以最大限度地降低风险。
- 车道钥匙和人行横道钥匙代表事件发生的区域——了解这些特定区域意味着城市可以安装更多的摄像头和更多的标志,以阻止这些特定十字路口的鲁莽行为。
- 注意力不集中的影响明显不如以上这些,但城市仍然可以影响它。西雅图市应该考虑增加对分心驾驶的罚款,并张贴更多的公益广告来阻止这种行为。
- 碰撞的类型对预测严重程度影响最大。这并不奇怪,但这本身并不可行
一如既往,我欢迎想法、建议和反馈。
预测车辆燃油效率
比较 XGBoost(使用 GridSearchCV)和 PyTorch 神经网络来拟合回归模型,并根据汽车特征预测里程
米卡·鲍梅斯特在 Unsplash 上的照片
我的以前的帖子关注的是机器学习和神经网络在石油行业数据集中的应用。这些努力让我有信心成功地实现 XGBoost 和人工神经网络,以预测我工作的炼油厂的重大安全隐患。我非常自豪的重大成功!
为了锻炼一些通用性,我想在这个应用程序中使用 PyTorch 和 GridSearchCV,首先想在一个更简单、更小的数据集上进行实践——即来自 UCI 资源库的 Auto MPG 数据集。
和以前一样,我提出了一个分步的方法来确保系统化的应用:
第一步 =在深入建模之前了解目标和大局。
步骤 2 =加载并获得数据的高级洞察
第三步 =进一步可视化以探索数据。目标:尽早了解最具杠杆作用的特性。
第四步 =建模计划。这里的关键是为训练和测试模型准备好数据。
步骤 5 =执行建模并评估性能。根据需要完成灵敏度分析
第六步 =从工作中得出结论,让最终用户受益
下面是 GitHub repo 中的代码片段和完整代码。
第一步:我们的目标是根据各种特征预测汽车的里程。通过建模工作,我们可以了解是什么使汽车高效,以及如何实现目标里程消耗。
**第二步:**将输入数据读入 Python 并使用。describe(),。head()函数获取关键的统计数据和初步的数据。我还想命名列,因为这在原始数据中是不可用的。
图 1:首先看看数据,有一些高层次的见解
高级外卖:
- 数据集的变量涵盖了很大范围的数字;如果我们使用像 kNN 这样的算法,这表明需要缩放。
- 似乎我们有连续变量和离散变量的混合,其中一个是非数字的。这表明需要某种编码。
- 有 398 个条目,平均里程为 23 英里,3 个可能的来源,5 个可能的车型年。
单独的检查(此处未显示)显示数据集的“马力”特征有 6 个空值。
步骤 3a) 将相关性绘制为 Seaborn 热图
图 2:皮尔逊相关系数的 Seaborn 热图
从上面可以得出什么结论?
- 车重和排量与里程负相关最强。很好地符合直觉,大型悍马不是最有效的汽油使用者
- 马力和气缸数也与里程数呈强烈的负相关关系——这也符合快速跑车比轿车需要更多汽油的直觉
- 汽车产地和车型年份是分类数字变量,让我们用柱状图来形象化这些变量。
出于建模的目的,我将首先使用所有这些特性。然而,如果我想要一个更紧凑的特征集来防止任何潜在的过度拟合,我可以删除气缸/排量/汽车重量(给定高相关系数)。
步骤 3b) 让我们使用柱状图了解更多关于分类数字特征的信息:
图 3:汽车产地和车型年的直方图
从图 3 直方图得出的结论:原产地 1 的汽车更具代表性,这表明 mpg 结果更适合该原产地——无论原产地可能代表什么,例如制造国。我们注意到车型年份分布在 12 年中,1970、1976、1982 比其他年份更有代表性。
这些数字分类变量应该被编码吗?
图 4:汽车产地和车型年与 mpg 的柱状图
从图 4 柱状图得出的结论:mpg 随着汽车来源数量的增加而略微增加。对于车型年来说,相关性更少,但是现在,我不会对这些变量进行编码。我不介意保留这些特性。
步骤 3c) 上面的分析让我对因变量(即目标,即我们试图预测的东西)产生了好奇。这是向哪个方向倾斜的吗?下面的图 4 显示了特征的右偏度,表明我们可能想要对特征数据进行对数转换,以用于建模。
图 mpg 的直方图
步骤 4: 除了做更多的数据准备和为建模创建测试/训练集,我还将设置 GridSearch CV
4a) 输入缺失数据并创建训练和测试集。还要对汽车品牌进行编码,去掉汽车型号——因为后者是无关的细节。
**# The code below one-hot encodes car make and drops car model.**Data['car make'] = Data['car name']
Data['car make'] = Data['car name'].apply(lambda x: x.split()[0])Data.drop(columns=['car name'],inplace=True)Data = pd.get_dummies(Data,columns=['car make'])**# Next: creating x and y below**x_no_log = Data.drop(columns=['mpg'])
y_no_log = Data['mpg']**# Imputing missing car horsepower values.**imp = SimpleImputer(missing_values=np.nan,strategy='median')
x_no_log['horsepower'] = imp.fit(x_no_log['horsepower'].values.reshape(-1, 1)).transform(x_no_log['horsepower'].values.reshape(-1, 1))
4b) 设置 GridSearchCV——这允许我们循环遍历超参数,根据所选评分指标(在我的例子中为均方差)找到最佳组合。GitHub repo 对 RandomForest 进行了类似的操作。
xgb_params = {'nthread':[4],
'learning_rate': [.03, 0.05, .07],
'max_depth': [5, 6, 7],
'min_child_weight': [4],
'subsample': [0.7],
'colsample_bytree': [0.7],
'n_estimators': [500,1000]}
4c) 设置 PyTorch —下面的代码导入必要的包,用输入维度、隐层节点数和输出节点设置神经网络,然后构建模型。
我还将均方误差声明为优化的损失度量,我将在测试集上评估 XGBoost 和 RandomForest 的性能时使用相同的度量。
最后,设置 Adam 优化算法来操纵梯度下降函数,如下图 6 所示。
图 6:使用 PyTorch 的代码摘录
5) 所有设置完成后,是时候实际运行模型并评估结果了。
5a) 我将首先使用 GridCV 和之前设置的超参数网格,根据训练集中的性能找到性能最佳的 XGBoost 模型(GitHub repo 中对 RandomForest 进行了类似的练习)。
然后,我将训练创建的 PyTorch 神经网络
gsXGB = GridSearchCV(xgbr, xgb_params, cv = 7, scoring='neg_mean_squared_error',
refit=True, n_jobs = 5, verbose=True)
gsXGB.fit(xtrain,ytrain)XGB_best = gsXGB.best_estimator_train_error = []
iters = 600Y_train_t = torch.FloatTensor(ytrain.values).reshape(-1,1) #Converting numpy array to torch tensorfor i in range(iters):
X_train_t = torch.FloatTensor(xtrain.values) ***#Converting numpy array to torch tensor***
y_hat = torch_model(X_train_t)
loss = loss_func(y_hat, Y_train_t)
loss.backward()
optimizer.step()
optimizer.zero_grad()
5c) 模型训练完成后,我现在可以根据测试数据评估性能了。
**# Evaluating best-performing XGBoost model on testing data** ypred = XGB_best.predict(xtest)
explained_variance_score(ytest,ypred)
mean_absolute_error(ytest,ypred)
mean_squared_error(ytest,ypred,squared=True)**# Evaluating PyTorch model on testing data**
X_test_t = torch.FloatTensor(xtest.values) ***#Converting numpy array to Torch Tensor.***
ypredict = torch_model(X_test_t)
mean_squared_error(ytest,ypredict.detach().numpy(),squared=True)
通过超参数调整得到的 XGBoost 模型的均方误差为 0.0117 mpg。给定原始数据集中 23.5 mpg 的平均值,这可以解释为99.9%的准确度
PyTorch 神经网络的均方误差为 0.107 mpg 。使用上述方法,这可以转化为 99.5%的准确度。
我们为客户完成了什么?我们有一个模型可以预测各种汽车的燃料里程;我们的客户可以利用这一点来规划达到理想燃油效率水平的汽车。
此外,我们还可以告知我们的客户——根据下图 7——体重是预测里程数的最有影响力的变量,其次是加速度。马力、排量、加速度在影响上比较接近。
图 7:预测里程的特征重要性
有了这些细节,我们的客户可以计划未来的汽车生产或购买计划。
一如既往,我欢迎任何反馈。
用 XGBRegressor 预测每周酒店取消预订
基于 xgb 回归的时间序列预测
XGBoost 最常用于基于分类或回归的问题,其中将特征合并到模型中以预测感兴趣的结果。
也就是说,XGBoost 也可以用于时间序列预测。这是通过使用感兴趣的时间序列的滞后作为模型中的独立特征来实现的。让我们看看如何使用 XGBRegressor 来帮助我们预测酒店取消预订。
数据处理
以下分析基于来自 Antonio、Almeida 和 Nunes (2019)的数据:酒店预订需求数据集。
使用 XGBoost 构建时间序列预测模型的目的是让酒店能够预测每周酒店取消预订的数量。
来源:Jupyter 笔记本输出
数据首先被分成训练和验证分区:
train_size = int(len(df) * 0.8)
val_size = len(df) - train_size
train, val = df[0:train_size,:], df[train_size:len(df),:]
假设我们正在使用一个基于树的模型,在这个例子中,这些特性没有使用 MinMaxScaler 进行规范化。
形成数据集矩阵:
def create_dataset(df, previous=1):
dataX, dataY = [], []
for i in range(len(df)-previous-1):
a = df[i:(i+previous), 0]
dataX.append(a)
dataY.append(df[i + previous, 0])
return np.array(dataX), np.array(dataY)
然后为模型定义一个回望期,也就是说,当预测向前一步时,我们希望模型“回望”多少时间步?
首先,将使用一个 5 的回看周期。根据 RMSE(均方根误差)测量的精度,可以适当地修改回望周期。
lookback = 5
X_train, Y_train = create_dataset(train, lookback)
X_val, Y_val = create_dataset(val, lookback)
以下是 X_train 输出的示例:
array([[ 41., 48., 87., 74., 101.],
[ 48., 87., 74., 101., 68.],
[ 87., 74., 101., 68., 96.],
[ 74., 101., 68., 96., 69.],
[101., 68., 96., 69., 88.]
...
[111., 70., 39., 59., 74.],
[ 70., 39., 59., 74., 57.],
[ 39., 59., 74., 57., 36.]])
XGBRegressor
XGBRegressor 模型定义如下:
from xgboost import XGBRegressormodel = XGBRegressor(objective='reg:squarederror', n_estimators=1000)
model.fit(X_train, Y_train)
以下是定义的模型参数:
来源:Jupyter 笔记本输出
从上面我们可以看到,在训练 XGBRegressor 时,有许多模型参数可以修改。但是,在这种情况下,n_estimators 被设置为 1000。这定义了 XGBoost 模型中树的数量。目标设置为‘reg:squarederror’,即平方损失回归,对极值误差的惩罚更重。
该模型跨训练集和验证集进行训练:
>>> trainpred = model.predict(X_train)
>>> trainpredarray([ 68.00038 , 95.99979 , 69.00168 , 88.00018 , 147.99892 ,
76.000656, 185.99991 , 122.999306, 91.00025 , 197.99966 ,
...
128.99901 , 111.99981 , 118.00009 , 85.00055 , 181.99738 ,
133.9994 , 111.001526, 70.00158 , 39.0001 , 58.99967 ,
74.00109 , 56.999626, 36.001102, 84.00235 ], dtype=float32)>>> valpred = model.predict(X_val)
>>> valpredarray([ 19.767576, 62.593506, 80.718994, 60.782364, 129.0691 ,
112.3979 , 113.64816 , 91.60748 , 105.40695 , 62.221115,
109.42688 , 126.32669 , 94.05386 , 62.81558 ], dtype=float32)
训练集和验证集(预测集和实际集)会相应地进行调整:
>>> Y_train=Y_train.reshape(-1,1)
>>> trainpred=trainpred.reshape(-1,1)>>> Y_val=Y_val.reshape(-1,1)
>>> valpred=valpred.reshape(-1,1)
结果
现在,在 RMSE(均方根误差)的基础上,将预测值与实际抵消值进行比较。
>>> train_mse = mean_squared_error(Y_train, trainpred)
>>> rmse = sqrt(train_mse)
>>> print('RMSE: %f' % rmse)RMSE: 0.000887>>> val_mse = mean_squared_error(Y_val, valpred)
>>> rmse = sqrt(val_mse)
>>> print('RMSE: %f' % rmse)RMSE: 50.142536
在验证集(Y_val)上平均每周有 109 个取消,RMSE 在验证集上达到 50.14。
我们看到,训练集的 RMSE 几乎为 0,但这并不被视为模型性能的基准。毕竟,预测模型已经训练过的数据是一项毫无意义的工作。
这些发现与 LSTM 相比如何?
还使用 5 的回望周期对上述数据运行了 LSTM 模型。
model = tf.keras.Sequential()
model.add(LSTM(4, input_shape=(1, lookback)))
model.add(Dense(1))
model.compile(loss='mean_squared_error', optimizer='adam')
history=model.fit(X_train, Y_train, validation_split=0.2, epochs=20, batch_size=1, verbose=2)
得到的 RMSE 如下:
>>> mse = mean_squared_error(Y_val, predictions)
>>> rmse = sqrt(mse)
>>> print('RMSE: %f' % rmse)RMSE: 36.792552
在这方面,当使用 LSTM 模型时,RMSE 低于 XGBoost,这表明 LSTM 在预测每周酒店取消方面做得稍好。然而,XGBoost 在预测每周取消时仍然表现出相当好的性能。
人们应该注意到,RMSE 对更极端值的错误惩罚更重。例如,如果某一周的取消量碰巧比正常情况高得多,而模型预测明显低估了这一点,那么这将导致更高的 RMSE。
作为参考,当使用 XGBRegressor 时,平均绝对误差在 38 处略低,表明该模型在预测不太极端的值时表现更好。
结论
在本例中,我们看到:
- 如何使用 XGBRegressor 预测时间序列
- 准备数据以使用 XGBoost 模型
- 测量模型精度的方法
非常感谢您的宝贵时间,非常感谢您的任何问题或反馈。
你可以在这里找到这个例子的 Jupyter 笔记本。
此外,我强烈推荐下面的机器学习掌握教程,以进一步了解 XGBRegressor 的使用。
免责声明:本文是在“原样”的基础上编写的,没有任何担保。本文旨在提供数据科学概念的概述,不应被解释为任何形式的专业建议。作者与本文提及的任何第三方无任何关系。
利用机器学习预测《权力的游戏》中谁会死
来自 Pixabay 的 SilentPilot 摄影
“我们该对死神说什么?”
HBO 的《权力的游戏》中的死亡显然是不可预测的。角色死于被龙刺穿、斩首、爆炸,甚至烧烤。但是这些死亡有多不可预测呢?
这篇文章将着眼于使用书中的数据预测《权力的游戏》中的死亡,使用从一个冰与火的维基中搜集的数据。也可以在 Kaggle 上找到数据。
导入库
第一件事是导入我们将使用的所有 Python 和 Scikit-learn 库。 Plotly 是一个构建交互式可视化的伟大工具。
探索数据
该数据有 1946 行和 39 列。首先,让我们看看有百分之多少的人物是活着的。
我们看到将近 75%的角色都活着。还有哪些因素会影响死亡率?再来看性别。
看起来雄性比雌性更容易被杀死。
接下来让我们看看最危险的房子,通过除以房子的大小来计算房子的死亡率。
人物死亡最多的房屋(或群体)是:
- 未知(332)
- 豪斯·弗雷(83)
- 守夜人(60)
- 史塔克家族(50)
一个角色不在书里却在剧里怎么办?它们的存在是为了最终被杀死吗?让我们检查一下这个假设。
只显示角色有大约 20%的几率死亡!
既然我们已经知道了哪些因素可能会增加某人的死亡几率,那么让我们开始清理数据吧。
清理数据
让我们检查一下其他的数字变量。年龄和出生日期是相关的,所以绘制它们应该显示相同的趋势。
看起来有两个字符的年龄为负,这也导致了出生日期列中的异常值。我们将不得不手动修复这些异常值。
这些情节现在没有异常值,但是有几个角色缺少年龄和生日。
让我们用它们的中间值来估算两者。
对于分类变量,让我们用字符串“未知”来估算缺失值
检查空值表明我们不再有任何丢失的值:
机器学习模型
首先让我们得到与活着高度相关的列。
您可以随意更改该阈值,但是在这种情况下,使用 0.2 左右的阈值可以获得最佳结果。
让我们定义一个仅由这些列以及目标列组成的新数据帧。
接下来,我们将把数据集分成 80%用于训练,20%用于测试。
逻辑回归
这种分类器通常用于只有两个类值(在我们的例子中是活的或不活的)的二元分类问题。它将输出一组基于概率的类。
Logistic 回归给出了一个:
- 模型得分为 0.9615
- 训练得分 0.9615
- 测试分数为 0.9524
决策图表
决策树在一个标准(如男性或女性)上创建分裂点,因此每个分支导致一个实例的分类。
决策树分类器给出了:
- 训练得分为 1 分(哦,可能过度适应)
- 测试得分为 0.9282
随机搜索
随机化和网格搜索通过尝试固定数量的设置来优化分类器的超参数。用于预测的参数也通过交叉验证进行优化。
得到的一些最佳随机森林参数是:
- n _ 估计数:600(数字估计数)
- min_samples_split: 4(每次分割的最小样本数)
- max_depth: 6=50(树的最大深度)
随机森林
现在我们有了最佳超参数,我们可以比较基尼和熵随机森林模型。首先,我们来试试基尼。
基尼给出:
- 训练得分 0.9647
- 测试得分为 0.9564
- AUC 分数为 0.9373
将标准改为“熵”给出:
- 训练得分 0.9647
- 测试得分为 0.9564
- AUC 分数为 0.9363
测试精度是相同的,所以现在让我们用基尼。
什么特征最重要?
不出所料,来自危房增加了某人死亡的风险。增加风险的其他因素有:
- 一个只表演的角色
- 男性的
- 流行的
- 年长的
- 在第一册和/或第四册中
- 从一个大房子
结论
我们可以通过流行度排序来检查最重要的模型结果。
模型结果,按受欢迎程度百分比排序
我们看到,模型 正确地 预测了*(剧透提前)*认为:
- 罗柏·史塔克会死的
- 玛格丽·提利尔会死
- 伊里斯·坦格利安(疯狂的国王)会死
- 史坦尼斯·拜拉席恩会死的
- 山姆威尔·塔利会活下来
模型错误地预测到:
- 托曼·拜拉席恩会活下来
- 乔佛里·拜拉席恩会活下来
- 瓦德·佛雷会活下来
为了排序,我们可以根据测试精度对我们使用的模型进行如下排序:
- 优化随机森林(Gini): 95.64%
- 基线随机森林(基尼系数):95.13%
- 基线随机森林(熵):94.36%
- 逻辑回归分析:95.24%
- 决策树分类器:92.82%
使用 Gini 作为我们的最终模型,我们得到的最终测试精度为 0.9564。
这个模型只准确到第六季左右,之后有许多写作的变化,这部剧已经走上了不同于原著的时间线。
你怎么看待人物死亡的风险因素?
用几种分类技术预测葡萄酒质量
带代码的数据科学项目演练!
图片由来自 Pixabay 的 Aline Ponce 拍摄
目录
介绍
随着隔离的继续,我有了一些爱好和兴趣…包括葡萄酒。最近,我喜欢上了葡萄酒,尽管我并不知道什么是好酒。因此,我决定应用一些机器学习模型来弄清楚是什么造就了优质的葡萄酒!
对于这个项目,我使用了 Kaggle 的红酒质量数据集来建立各种分类模型,以预测某一特定红酒是否“质量好”。该数据集中的每种葡萄酒都被赋予 0 到 10 之间的“质量”分数。出于这个项目的目的,我将输出转换为二进制输出,其中每种葡萄酒要么是“优质”(7 分或更高),要么不是(低于 7 分)。葡萄酒的质量由 11 个输入变量决定:
- 固定酸度
- 挥发性酸度
- 柠檬酸
- 残糖
- 氯化物
- 游离二氧化硫
- 二氧化硫总量
- 密度
- pH 值
- 硫酸盐化
- 酒精
目标
该项目的目标如下
- 尝试不同的分类方法,看看哪种分类方法的准确度最高
- 确定哪些特征最能代表优质葡萄酒
说到这里,我们开始吧!
设置
首先,我导入了我将使用的所有相关库以及数据本身。
导入库
import numpy as np
import pandas as pd
import matplotlib as plt
import seaborn as sns
import plotly.express as px
读取数据
df = pd.read_csv("../input/red-wine-quality-cortez-et-al-2009/winequality-red.csv")
理解数据
接下来,我想更好地了解我在做什么。
# See the number of rows and columns
print("Rows, columns: " + str(df.shape))# See the first five rows of the dataset
df.head()
总共有 1599 行和 12 列。通过查看前五行,数据看起来非常干净,但是我仍然想确保没有丢失值。
缺少值
# Missing Values
print(df.isna().sum())
这是一个非常适合初学者的数据集。我不需要处理任何丢失的值,而且在给定这些变量的情况下,也没有太多的灵活性来进行一些特性工程。接下来,我想进一步探索我的数据。
探索变量
“质量”变量直方图
首先,我想看看质量变量的分布。我想确保我的数据集中有足够多的“优质”葡萄酒——稍后你会看到我是如何定义“优质”的。
fig = px.histogram(df,x='quality')
fig.show()
相关矩阵
接下来,我想看看我正在处理的变量之间的相关性。这让我可以很快更好地理解变量之间的关系。
我立即发现了一些与*质量密切相关的变量。*很可能这些变量也是我们的机器学习模型中最重要的特征,但我们稍后再看。
corr = df.corr()
matplotlib.pyplot.subplots(figsize=(15,10))
sns.heatmap(corr, xticklabels=corr.columns, yticklabels=corr.columns, annot=True, cmap=sns.diverging_palette(220, 20, as_cmap=True))
转化为分类问题
回到我的目标,我想比较不同分类技术的有效性,所以我需要将输出变量改为二进制输出。
对于这个问题,我将一瓶葡萄酒定义为质量分数为 7 分或更高的为“质量好”,如果分数低于 7 分,则视为“质量差”。
一旦我将输出变量转换成二进制输出,我就将我的特征变量(X)和目标变量(y)分离成单独的数据帧。
# Create Classification version of target variable
df['goodquality'] = [1 if x >= 7 else 0 for x in df['quality']]# Separate feature variables and target variable
X = df.drop(['quality','goodquality'], axis = 1)
y = df['goodquality']
好酒与劣酒的比例
我想确保有合理数量的优质葡萄酒。根据下面的结果,这似乎是一个公平的数字。在某些应用中,如果数据极度不平衡,可能需要重新采样,但我认为这样做没问题。
# See proportion of good vs bad wines
df['goodquality'].value_counts()
为建模准备数据
标准化特征变量
在这一点上,我觉得我已经准备好了建模的数据。我做的第一件事是标准化数据。标准化数据意味着它将转换数据,使其分布的平均值为 0,标准差为 1。为了均衡数据范围,标准化数据非常重要。
例如,假设数据集有两个输入要素:以毫米为单位的身高和以磅为单位的体重。因为“身高”的值由于其测量而要高得多,所以更强调身高而不是体重,这就产生了偏见。
# Normalize feature variables
from sklearn.preprocessing import StandardScaler
X_features = X
X = StandardScaler().fit_transform(X)
分割数据
接下来,我将数据分成训练集和测试集,这样我就可以交叉验证我的模型,并确定它们的有效性。
# Splitting the data
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=.25, random_state=0)
现在,有趣的部分来了!
系统模型化
对于这个项目,我想比较五种不同的机器学习模型:决策树、随机森林、AdaBoost、Gradient Boost 和 XGBoost。为了这个项目的目的,我想比较这些模型的准确性。
模型 1:决策树
作者创建的图像
决策树是一种流行的模型,用于运筹学、战略规划和机器学习。上面的每个方块称为一个节点,节点越多,你的决策树就越精确(一般来说)。决策树的最后节点,也就是做出决策的地方,被称为树的叶子。决策树直观且易于构建,但在准确性方面有所欠缺。
from sklearn.metrics import classification_report
from sklearn.tree import DecisionTreeClassifiermodel1 = DecisionTreeClassifier(random_state=1)
model1.fit(X_train, y_train)
y_pred1 = model1.predict(X_test)print(classification_report(y_test, y_pred1))
模型 2:随机森林
随机森林是一种基于决策树的集成学习技术。随机森林包括使用原始数据的自举数据集创建多个决策树,并在决策树的每一步随机选择一个变量子集。然后,该模型选择每个决策树的所有预测的模式。这有什么意义?依靠“多数获胜”模型,它降低了单个树出错的风险。
作者创建的图像
例如,如果我们创建一个决策树,第三个,它会预测 0。但是如果我们依赖所有 4 个决策树的模式,预测值将是 1。这就是随机森林的力量。
from sklearn.ensemble import RandomForestClassifier
model2 = RandomForestClassifier(random_state=1)
model2.fit(X_train, y_train)
y_pred2 = model2.predict(X_test)print(classification_report(y_test, y_pred2))
模型 3: AdaBoost
接下来的三个模型是提升算法,将弱学习者转化为强学习者。我不想跑题,解释三者之间的区别,因为这是相当复杂和错综复杂的。也就是说,我将留下一些资源,您可以从中了解 AdaBoost、渐变增强和 XGBoosting。
- StatQuest: AdaBoost
- StatQuest:梯度推进
- StatQuest: XGBoost
from sklearn.ensemble import AdaBoostClassifier
model3 = AdaBoostClassifier(random_state=1)
model3.fit(X_train, y_train)
y_pred3 = model3.predict(X_test)print(classification_report(y_test, y_pred3))
模型 4:梯度推进
from sklearn.ensemble import GradientBoostingClassifier
model4 = GradientBoostingClassifier(random_state=1)
model4.fit(X_train, y_train)
y_pred4 = model4.predict(X_test)print(classification_report(y_test, y_pred4))
模型 5: XGBoost
import xgboost as xgb
model5 = xgb.XGBClassifier(random_state=1)
model5.fit(X_train, y_train)
y_pred5 = model5.predict(X_test)print(classification_report(y_test, y_pred5))
通过比较这五个模型,random forest 和 XGBoost 似乎产生了最高级别的准确性。然而,由于 XGBoost 在预测优质葡萄酒方面有更好的 f1 分数(1),我的结论是 XGBoost 是五个模型中的赢家。
特征重要性
下面,我根据随机森林模型和 XGBoost 模型绘制了特性的重要性。虽然它们略有不同,但前三个特征是相同的:酒精、挥发性酸度和硫酸盐。如果你看下面的图表,我把数据集分成质量好的和质量差的两类,以便更详细地比较这些变量。
通过随机森林
feat_importances = pd.Series(model2.feature_importances_, index=X_features.columns)
feat_importances.nlargest(25).plot(kind='barh',figsize=(10,10))
通过 XGBoost
feat_importances = pd.Series(model5.feature_importances_, index=X_features.columns)
feat_importances.nlargest(25).plot(kind='barh',figsize=(10,10))
比较四大特征
# Filtering df for only good quality
df_temp = df[df['goodquality']==1]
df_temp.describe()# Filtering df for only bad quality
df_temp2 = df[df['goodquality']==0]
df_temp2.describe()
好品质
劣等质量
通过观察细节,我们可以看到,优质葡萄酒的平均酒精含量较高,平均挥发性酸度较低,平均硫酸盐含量较高,平均残糖含量较高。
感谢阅读!
如果你喜欢我的工作并想支持我,我会非常感谢你在我的社交媒体频道上关注我:
- 支持我的最好方式是在媒体T10【这里上关注我。
- 在推特关注我这里。
- 点击这里订阅我的新 YouTube 频道 。
- 在 LinkedIn 上关注我这里。
- 在我的邮箱列表 这里报名。
- 查看我的网站terenceshin.com。