TowardsDataScience-博客中文翻译-2020-八十-
TowardsDataScience 博客中文翻译 2020(八十)
原文:TowardsDataScience Blog
协议:CC BY-NC-SA 4.0
机器学习&图像到音频字幕
原文:https://towardsdatascience.com/machine-learning-image-to-audio-captioning-964dc0f63df9?source=collection_archive---------40-----------------------
杰森·罗斯韦尔在 Unsplash 上的照片
关于机器学习如何用于将图像直接翻译成语音的简要文献综述。
机器学习已经扩展到许多不同的领域和学科。尝试新的领域是成长和学习新事物的最好方式。以下是研究人员如何应用机器学习直接从图像中生成音频描述的总结。
图像 2 语音:自动生成图像的音频描述
研究人员在不使用文本作为中间形式的情况下为图像生成音频字幕。
Clustergen、VGG16、LSTM、MSCOCO、语音-COCO、XNMT、Flickr、Flickr-Audio
丹尼尔·山特维克在 Unsplash 上的照片
摘要和导言
研究人员提出了人工智能的一个新领域,图像 2speech。他们将主要任务定义为:
" Image2Speech 系统应该直接生成图像的语音描述,而不需要首先生成文本."
以前,image2speech 问题被分解为两个步骤:image2txt,然后 txt2speech。但是,一些语言没有书面形式(例如阿尔及利亚语、摩洛哥语、黎凡特语、各种阿拉伯语等),因此传统的 img 2 语音翻译不适用于这些语言。
方法
研究人员使用标准的开源库、软件和数据来开发他们的模型。图一。展示了这些技术是如何相互关联的。
- VGG16 (从图像中提取 CNN 特征)
- XNMT (从 CNN 特征生成语音单元)
- ClusterGen (将语音单元转换成音频)
- Kaldi 和 Eesen (自动语音识别,将音频翻译成语音单元)
- Flickr 图像数据集和 Flickr 音频
- MSCOCO 和演讲-COCO
图一。图像速度的实验方法。来源:作者
Image2Speech 系统由三个独立的网络组成(VGG16、XNMT 和 Clustergen)。整个网络根据图像和音频描述对进行训练。
作者使用 VGG16 提取图像特征,然后 XNMT 将这些图像特征转化为语音单元,最后 Clustergen 将语音单元转化为音频。
" XNMT(可扩展机器翻译工具包)专门用于训练序列对序列神经网络."
数据
数据来自两个不同的来源。它们都有一个图像数据集(Flickr 和 MSCOCO)和一个音频数据集(Flickr-Audio 和 SPEECH-MSCOCO)。因此,每个图像都伴随有文本字幕和该文本字幕的音频朗读。
示例图像 1000268201。来源:公共领域
上图的字幕是由亚马逊土耳其机械公司的工人制作的:
- 一个穿着粉色连衣裙的孩子正在入口通道爬上一组楼梯。
- 一个女孩走进一栋木制建筑。
- 一个小女孩爬进木制玩具屋。
- 一个小女孩爬楼梯去她的玩具屋
- 一个穿着粉色连衣裙的小女孩走进了一个小木屋。
MSCOCO 是最大的 image2txt 和 text2speech 数据集。它是如此之大,以至于研究人员在训练过程中无法将它全部包含进来。
结果
在所有模型被训练之后,它们实现了 78.8%的电话错误率。作者将此描述为:
“不是完全自然的,而是由可理解的单词组成的可理解的句子”
结论
作者定义了一个新的人工智能领域,比传统的 image2speech 更具挑战性和限制性。在没有任何中间文本的情况下,从图像生成语音是新应用的独特问题。在本文中,作者提出了第一个此类模型,并希望鼓励其他人继续构建更有趣的模型。
机器学习和更多
[## 机器学习和听力损失
关于机器学习如何使听力损失者受益的简要文献综述。
towardsdatascience.com](/machine-learning-hearing-loss-d60dab084e3f)
参考文件
Mark Hasegawa-Johnson,Alan Black,Lucas Ondel,Odette Scharenborg,Francesco Ciannella,《图像 2speech:自动生成图像的音频描述》,载于 inter speach(2020)http://www . cs . CMU . edu/~ awb/papers/Hasegawa Johnsons 17 icnlssp . pdf
坚果壳中的机器学习
原文:https://towardsdatascience.com/machine-learning-in-a-nut-shell-df251f480f77?source=collection_archive---------20-----------------------
图片由肖恩·巴蒂通过 pixabay.com 提供
怎么这么热闹?
机器学习是一个概念,也是当今科技环境中经常被丢弃的热门词汇,就解释而言,它还有很多需要改进的地方。人们经常把机器学习算法称为黑匣子;虽然机器学习的某些方面可能缺乏透明度,但通过了解机器学习的一些背景知识,可以减轻很多沮丧或困惑。
作为一门学科,机器学习比你想象的要简单得多,并且可以简化为许多组成部分。当机器学习在您的业务、项目或组织的背景下提出时,拥有这种高层次的视角将允许您理解并参与对话。
机器学习是由什么组成的?
机器学习有两个主要领域,我们将在这里进行分解。你遇到的大多数“ML”解决方案都属于这两类:监督学习和非监督学习
监督学习
监督机器学习问题的想法是,你实际上有一个预定义的数据集,其中包含所谓的因变量和响应变量。因变量是你想要理解的,自变量是你可以用来理解事物的。
监督学习的世界又分为两个子类:回归和分类。当我给出这些例子时,监督学习的全貌应该会变得更加清晰
回归
当我们在监督学习子类的上下文中谈论回归时,我们实际上谈论的是连续变量的预测。换句话说,不是预测某个东西是不是垃圾邮件,是不是猫,是不是什么即分类;那么我们预测的是一个可以“持续”的数字。
让我们用几个例子来说明这一点
假设你想预测个人收入。你有一个数据集,它详细描述了某人的经历、教育、技能等等..在此基础上,你可以利用这些变量来预测他们可能会生产什么。
另一个经典的例子是房价。您想知道您的房子在给定市场中的价格,因此您可以传递该市场的房屋销售数据来创建一个模型,该模型使用房间数、平方英尺、地块大小、建造年份等数据点来预测房屋价值。
希望这锁定了回归&也提高了分类。
分类
还记得我说的那些不是回归吗?那些东西是分类的。我们在这里仍然使用监督学习,但它不是预测一个连续的数字。
我们试图预测类别或阶层。这又引入了一个难题,但是当涉及到分类时;你可以试着预测某样东西属于或不属于某个类;即二进制分类,或者你可以预测一个记录属于哪一类;即多类分类。
对于二元分类,您可能希望预测一个机会/交易的结果是赢还是输。
你可以根据收视率、票房和预算来预测电影类型。
无监督学习
当谈到无监督学习时;模型会自己识别自然模式,而不是命令你的模型去理解什么。
使聚集
可能最流行的无监督学习方法被称为聚类。类似于我刚才描述的回归;假设您正在查看住房数据,但您希望了解住房的自然分组,而不是预测给定的变量,聚类将允许您根据与定义的组的最大相似性和与其他组的最大不相似性来识别住房的自然分组。
有了住房数据,你可以指定你关心平方英尺和房子的价值;你可能会看到自然分组可能是房屋类型、不同市场、年龄等的指标。
结论
机器学习活动还可能属于另外两个新兴的、不太流行的类别。那些是强化学习和半监督的。我不会在这里深入探讨这两个问题,但是如果你觉得这很有帮助,并且想要更多类似的内容,可以看看我在 datasciencelessons.com 的博客。
感谢阅读!祝数据科学快乐!
学术研究与实践中的机器学习
原文:https://towardsdatascience.com/machine-learning-in-academic-research-v-s-practical-5e7b3642fc06?source=collection_archive---------21-----------------------
典型工业机器学习项目的阶段
安迪·凯利在 Unsplash 上的照片
作为解决大数据世界问题的关键技术之一,机器学习肯定越来越受欢迎。作为一名博士毕业生,我来自这个领域的学术方面。然而,自从我开始尝试在实践中应用我的“知识”以来,我发现建立一个 ML 模型来解决一个业务问题和写一篇论文之间有相当大的区别。
学术研究通常只关注理论。我们曾经试图将模型的精度提高一点点。即使我们在某个特定的课题上只迈出了一小步,也不妨碍我们写出一篇优秀的学术论文并发表。
实际上,对于一个基于行业的项目,只关注机器学习的一个方面是不够的。我们通常需要按照一定的步骤来解决问题,根据我过去的经验,如下所示:
因此,以下这些常用短语对于典型的工业 ML 项目至关重要:
- 问题建模
- 特色工程
- 型号选择
- 模型组装
在本文中,我将在其余部分介绍这些阶段,并说明为什么这些步骤对于解决实际问题是必要的,以及学术研究和工业项目在这些方面有什么不同。
问题建模
照片由Olav Ahrens rtne在 Unsplash 上拍摄
在开始解决问题之前,我们需要对问题进行建模,因为实际问题通常很复杂。这是实践和学术研究的显著区别之一。当我们专注于学术研究的理论时,使用一些公共数据集是很常见的。这可以节省我们收集数据的时间和预算,并使我们能够从其他类似研究的相同基线开始,这有利于以后的评估。
问题建模从收集信息开始,以便理解它,然后将问题抽象成可预测的东西。
我们需要为问题建模做的具体步骤
- 阐明业务逻辑(领域知识)
- 提取现有要素(输入)
- 定义要预测的内容(输出)
- 选择合适的评估指标
- 选择原始数据集的最相关子集(采样)
- 基于评估指标交叉验证模型
就我而言,有很多数据科学家和机器学习工程师通常会从一个 ML 问题的特征工程开始,这被认为是一个不合适的过程。
问题建模不应该被忽略的原因有很多,但是我发现下面两个子步骤是主要的。
评估指标
评估方法有很多种,如混淆矩阵、ROC/AUC、MAE 和 MSE。在学术研究项目中,选择任何有意义的人都是常见的,最重要的是,与其他算法相比,你的算法在这些指标下显示出最佳结果。这实际上并不尴尬,因为我相信所有的研究人员都想强调他们已经取得的进步,尽管他们可能也想在“未来工作”部分展示一些局限性。一般来说,这就是在学术研究中使用评估指标的方式,以强调贡献。
说到行业,这样评价你的模式会很危险。你可以向你的老板展示该模型在特定评估指标下的先进性。但是,如果您没有选择最适合问题的适当方法,该模型可能最终在实验中非常有效(当您向您的老板炫耀时),但在实践中却不有效(生产使用)。想象一下,如果您的模型是对患者进行分类,以确定他们是否患有疾病,如果该模型在实践中运行不佳,可能会产生巨大的影响甚至危及生命的后果。
因此,我们需要选择能够最好地反映问题空间的评估指标,以及能够产生与原始数据集最相似的波动的评估指标。选择一个正确的度量标准可以确保您有一个合适的方法来评估您的模型,不仅针对您的测试数据集,而且针对您的实际使用。此外,它将极大地提高 ML 模型迭代的效率。
交叉验证
在学术研究中,大多数时候,小样本数据集不会成为问题,除非你的研究主题是使用有限的样本训练一个好的模型。然而,在实践中只有很小的样本量是很常见的。这可能是因为您的信息系统冷启动,或者您的企业还没有太多的用户,或者只是因为一些限制,如隐私政策,不允许您有足够的样本。
假设我们的样本数据集中只有 100 个条目,基于这个数据集训练了两个不同的模型。模型 A 有 98%的准确率,模型 B 有 92%的准确率。我们是否可以简单地说 A 型比 B 型“更好”?答案是否定的。
样本数据集太小,所以它没有足够的信心来确定哪个模型比另一个更先进。交叉验证是增加这种信心的技术之一。最常见的方法是保留,它将样本数据集分成训练集和测试集。还有一些其他方法,如 K 倍交叉验证和 bootstrap 抽样。这些交叉验证技术有助于使用相对较小的样本数据集使您的模型更接近实际用途。
特征工程
米卡·鲍梅斯特在 Unsplash 上的照片
如果你的学术研究课题不是关于特征工程的,你大概不会被这个困扰。您可以下载公共数据集,如 MovieLens 等。然后,使用您的算法训练一个模型,并将其与在同一数据集上使用其他算法训练的模型进行比较,以显示您的算法是如何进步的。然而,特征工程对于工业 ML 项目总是必要的,因为所收集的数据集对于您的企业来说是唯一的,并且大多数时候甚至不能直接用于训练可用的模型。
例如,一个制造工厂可能有 100 多个与设备相关的传感器,您需要训练一个模型来预测设备何时会出现异常。您可能会发现,在特征工程阶段,可能只有 20 个传感器会导致“异常”。此外,有些传感器可能无法独立工作。它必须与其他传感器一起转换,以便与该设备的“异常”相关联。因此,在实践中几乎不可能准备好原始数据集。为了在模型可以被很好地训练之前找到有意义的特征,特征工程对于大多数项目是强制性的。
通常,存在各种因素,机器学习工程师需要应用不同的原则和方法来执行特征工程任务,例如在问题建模阶段或业务逻辑本身中选择不同的模型。
因此,在我们完成了问题建模、数据过滤和清理之后,是时候开始特性工程了。这是一项关键但困难的任务,通常依赖于对 ML 的经验以及对领域知识的透彻理解。不夸张的说,大部分成功的机器学习项目都有优秀的特征工程。
型号选择
瑞安·昆塔尔在 Unsplash 上拍摄的照片
虽然特征工程很重要,但它仍然不是成功的工业机器学习模型的唯一因素。也就是说,选择不同的模型会导致完全不同的预测结果。换句话说,如果我们为问题选择的模型不合适,那么迭代模型变得实用可能是非常低效的,或者最有可能的是,永远没有一个有用的模型。
这在学术研究中很少困扰我,因为大多数时候,我们会分析特定类型的 ML 模型。我们甚至可能会寻找一个合适的数据集,以确保它更适合模型,而不是相反。然而,在一个工业 ML 项目中,我们正在解决一个特殊的问题,因此我们不能选择数据集。因此,我们只能为所提供的数据集选择模型。
我们应该根据不同的情况选择不同的模式。例如,逻辑回归可能适用于布尔型预测目标,随机森林通常适用于一些分类问题,深度学习通常是图像/语音识别的最佳选择。
因此,在一系列特征工程任务之后,我们还需要考虑哪种类型的模型可以从具有最佳潜在结果的特征中学习潜在模式。毫无疑问,选择一个合适的模型需要对大多数流行的模型有深刻的理解,并有丰富的行业经验。
模型装配
照片由迈克·彼得鲁奇在 Unsplash 上拍摄
同样,除非你的研究课题是关于模型组装的,那么你就不会担心这个问题。然而,当涉及到一个行业项目时,你会发现为一个 ML 问题集合不同的模型是非常有效的。
正如在模型选择一节中提到的,我们需要选择一个最适合问题的模型。然而,这也是因为不同的模型在从特征中捕捉不同类型的潜在模式方面各有所长。很多时候,我们需要组装多个模型才能有一个更优的模型。
ML 模型有多种组装方法,如加权、投票、装袋和堆叠。与模型选择类似,模型组装也依赖于对模型的深刻理解和数据科学家的个人经验来优化组装的模型。
结论
总之,在如何利用机器学习模型方面,学术研究和基于行业的项目之间存在明显的差异。
对于学术研究,我们通常只关注机器学习的一个方面,并尽力改善这一单一方面。对于我们的研究论文中没有涉及的其他方面,我们可以不花力气,或者只花很少的力气。
对于一个基于行业的机器学习项目,如果你来自学术背景,就不要被困住。也就是说,不要只关注一个方面,而是遵循典型的阶段来建模问题,执行特征工程,选择合适的模型并进行优化组装。
让我们建立实用的机器学习模型!
[## 通过我的推荐链接加入 Medium 克里斯托弗·陶
作为一个媒体会员,你的会员费的一部分会给你阅读的作家,你可以完全接触到每一个故事…
medium.com](https://medium.com/@qiuyujx/membership)
如果你觉得我的文章有帮助,请考虑加入 Medium 会员来支持我和成千上万的其他作者!(点击上面的链接)
金融中的机器学习:使用图形套索识别国际股票交易所交易基金中的交易对
原文:https://towardsdatascience.com/machine-learning-in-action-in-finance-using-graphical-lasso-to-identify-trading-pairs-in-fa00d29c71a7?source=collection_archive---------15-----------------------
TL;博士: 在这篇文章中,我将尝试解决识别相关股票投资组合的问题,这通常是 pairs 交易策略的第一步,也是最重要的一步。这种方法利用了图形 lasso 算法,该算法已被证明是许多实际问题的强大机器学习解决方案,如识别共同变化的大脑区域,社交媒体网络分析等。这是关于这个主题的系列教程中的第一篇,重点是它的一个应用; 我的第二篇帖子 以血淋淋的细节阐述了其背后的美丽理论,未来的帖子将展示该算法如何带来令人惊讶的营销洞察力。所以请关注我,敬请期待。
马库斯·斯皮斯克在 Unsplash 上拍摄的照片
股票投资的世界是诱人的,我们许多有技术的人都希望进入其中。然而,浪费我们的时间去筛选股票宇宙的基本面,比如说,仅仅在 SP500,对于有创造力的头脑来说,这本身就过于乏味和卑微了。
幸运的是,凭借编码知识和对机器学习的兴趣,你完全有能力在量化投资领域大展拳脚。下面,我将说明如何,作为创建自己的交易策略的第一步,使用一种称为图形套索的强大的机器学习算法,在国际股票 ETF 报价机中识别有意义的配对和聚类,以创建一个投资组合,这将是建立自己的配对交易策略的第一步,也是最重要的一步。
在整个教程中,我将把细节保持在最低限度和有意义的可行范围内,以便让您快速入门,您可以自由探索该算法的更多可能性。
系好安全带,让我们上路吧!
照片由迭戈·希门尼斯在 Unsplash 上拍摄
图形套索简介
还记得名为 lasso 的回归方法吗?该方法用于通过添加 L1 正则化项来导出回归问题的稀疏解。图形套索是它在图形世界的延伸。
图形套索不是估计回归问题中独立变量的系数,而是估计数据的精度(逆协方差)矩阵。因此,它不是像 lasso 回归中那样将许多系数推至 0,而是将矩阵中的许多值推至 0。
为什么是“图形化”?因为精度矩阵可以显示为唯一地对应于一个无向图(在后面的部分中有更多的介绍)。
换句话说,图形化套索的目标是从你的数据中归纳出一个具有稀疏连接的无向图。这个事实将在我们稍后尝试说明 ETF 图并识别可能的集群时派上用场。
关于算法更具体的数学处理,请参考我在这个系列的第二篇文章,它一步一步地分析了算法。
数据准备
在这个实验中,让我们使用报价机的每日收盘价。我们将使用雅虎财经提供的历史数据。例如,要将股票行情系统 QQQ 的历史数据下载到您的本地机器上,您可以导航到 https://finance.yahoo.com/quote/QQQ/history?p=QQQ 的,选择日期范围,然后点击“下载”。在我们的实验中,假设我们对某些国家特别好奇,并检索以下国家 ETF 的数据:
#Setting up the mapping from ticker to country
etfs = {"EWJ":"Japan","EWZ":"Brazil",
"FXI":"China","EWY":"South Korea",
"EWT":"Taiwan","EWH":"Hong Kong",
"EWC":"Canada","EWG":"Germany",
"EWU":"United Kingdom","EWA":"Australia",
"EWW":"Mexico","EWL":"Switzerland",
"EWP":"Spain","EWQ":"France",
"EIDO":"Indonesia","ERUS":"Russia",
"EWS":"Singapore","EWM":"Malaysia",
"EZA":"South Africa","THD":"Thailand",
"ECH":"Chile","EWI":"Italy",
"TUR":"Turkey","EPOL":"Poland",
"EPHE":"Philippines","EWD":"Sweden",
"EWN":"Netherlands","EPU":"Peru",
"ENZL":"New Zealand","EIS":"Israel",
"EWO":"Austria","EIRL":"Ireland","EWK":"Belgium"}
然后,我们做一些整理工作来简化数据格式,以便于以后的处理:
symbols, names = np.array(sorted(etfs.items())).T
现在,您应该已经下载了这些国家 ETF 的数据文件。下一步是将它们整理成一个大数据文件,其中列是股票代号,如上面排序的“EWK”,行是时间顺序的日期。你可以使用一个简单的 Python 脚本或者其他你喜欢的工具来实现。
让我们将整理好的文件读入熊猫数据帧:
#Read in series of daily closing prices
#The file 'input.csv' uses the tickers above as columns, and dates #as index in df
df = pd.read_csv("input.csv", index_col='Date')
数据处理
在应用算法之前,我们需要注意一件事:
#Convert price series to log return series
df = np.log1p(df.pct_change()).iloc[1:]
这一行代码将每日收盘价的时间序列转换成一系列的对数回报。请注意,这一步不是强制性的,但在这种情况下通常是一种良好的做法。可以论证如下:
虽然股票价格不是正态分布,但对数回报也不是,而是比价格更接近正态分布。应用数学家喜欢正态性,因为当他们使用不同的分析工具/算法处理数据时,它减轻了很多痛苦,其中大部分都假设数据正态性能够有意义地发挥作用。
底线:学会热爱高斯,获得对他的分布的品味,尽你所能在你的数据中发现它。
核心
现在我们准备应用算法:
#Calling Glasso algorithm
edge_model = covariance.GraphicalLassoCV(cv=10)
df /= df.std(axis=0)
edge_model.fit(df)
#the precision(inverse covariance) matrix that we want
p = edge_model.precision_
这里我们利用 Python 中的 sklearn 包来方便地实现图形化套索。请注意我是如何检索得到的精度(逆协方差)矩阵的,这是我们这里的重点。我们选择精确(逆协方差)矩阵,而不是协方差矩阵的原因是图形套索与其他无聊算法的区别,也是我下一篇文章的主题。现在,它足以说:
(1)是的,大多数人做协方差分析,但那可能是因为他们只知道这些。既然你已经听说过逆协方差,请从现在开始把它用到你的优势上。
(2)精度矩阵可以唯一定义一个无向图:其单元格( i , j )的值,如果等于 0,则表示变量 i 和 j,之间的条件独立性,如果不为零,则表示条件(不)依赖的程度;并且这些依赖关系映射到无向图,使得如果两个顶点是条件独立的,则它们之间没有链接。
说了这么多,让我们看看使用 Seaborn 是什么样子的:
sns.heatmap(p)
我们得到了:
x 和 Y 标签遵循 ETF 的排序顺序
它看起来不错,但实际上并没有告诉我们太多。图形套索的强大之处在于它能够学习精确矩阵,然后将矩阵映射到图形。
所以让我们这样做:
#prepare the matrix for network illustration
p = pd.DataFrame(p, columns=cols, index=cols)
links = p.stack().reset_index()
links.columns = ['var1', 'var2','value']
links=links.loc[ (abs(links['value']) > 0.17) & (links['var1'] != links['var2']) ]
#build the graph using networkx lib
G=nx.from_pandas_edgelist(links,'var1','var2', create_using=nx.Graph())
pos = nx.spring_layout(G, k=0.2*1/np.sqrt(len(G.nodes())), iterations=20)
plt.figure(3, figsize=(30, 30))
nx.draw(G, pos=pos)
nx.draw_networkx_labels(G, pos=pos)
plt.show()
上面的代码片段将精度矩阵转换为图形,并使用 Python 中的 Networkx 包来绘制它。我已经尝试让节点尽可能稀疏,这样节点标签就不会重叠,但还是不太令人满意。你自己试试看。
为了解决这个问题,让我们再做一步,将图形导出到 Gephi 中:
nx.write_gexf(G, 'graph.gexf')
在 Gephi 中打开文件并调整其布局,我们得到了以下有趣的国家 ETF 集群:
集群:混乱中的秩序
天真的是,你可以把这三个集群视为三个独立的投资组合,然后计算出每个组合的套期保值比率。或者更好的是,您可能想要尝试添加边权重并说明节点之间的结合强度,并基于该信息进一步将大型集群划分为较小的集群。请随意添加更多的数据和股票代码,并开始自己的研究。
群集布局看起来很有趣。它与地理位置非常匹配,这并不奇怪,因为地理上聚集在一起的国家往往会形成紧密结合的共同市场,并往往有大致共同变化的股票市场。同样有趣的是,东亚市场如何首先通过新加坡,然后通过澳大利亚和加拿大连接到欧洲集群。我无法深入分析这些联系,现在就把它留给好奇的读者去娱乐或困惑。
克里斯汀·罗伊在 Unsplash 上的照片
请记住,随着世界的发展和国家之间不断的友好或不友好,集群会发生变化。这是对任何交易算法的期望,以解释世界上的范式转变。
做你自己的实验,并把它作为你建立自己的交易算法的第一步。请继续关注这方面的更多信息,以及机器学习、金融和更多其他有趣的话题。
来自《走向数据科学》编辑的提示: 虽然我们允许独立作者根据我们的 规则和指导方针 发表文章,但我们并不认可每个作者的贡献。你不应该在没有寻求专业建议的情况下依赖一个作者的作品。详见我们的 读者术语 。
面向初学者的 Apache Spark 中的机器学习—医疗保健数据分析
原文:https://towardsdatascience.com/machine-learning-in-apache-spark-for-beginners-healthcare-data-analysis-diabetes-276156b97e92?source=collection_archive---------36-----------------------
图片由皮克斯拜的 Gerd Altmann 提供
大数据/数据科学/教程/指南/ Apache Spark /机器学习
使用 Databricks 在 Apache Spark 中构建第一个机器学习模型的分步指南
简介:
Apache Spark 是一个集群计算框架,旨在实现快速高效的计算。它可以用相对较低的计算能力处理数百万个数据点。Apache Spark 构建在 Hadoop 的 Map-Reduce 之上,是其扩展,可以有效地使用不同的集群计算组合。Spark 的主要特性是内存集群计算,它提高了应用程序的速度,包括交互式查询和流处理。
这篇文章是使用数据块在 Spark 中开发预测模型的快速入门指南。
图:数据块:统一数据分析
我将使用 Databricks 的免费社区版本,感谢他们!
关于数据/背景信息:
在这篇文章中,我将使用机器学习来帮助我们预测患者患糖尿病的概率。数据集是从UCI 机器学习库下载的。
在这里,我使用提供的关于患者的信息来预测糖尿病的概率。这是一个二元分类问题,我将尝试预测属于糖尿病类别的观察值的概率。
我将首先演示最少量的探索性分析,然后跳转到机器学习模型(即回归和基于树的模型),并比较和总结结果。
数据预处理和探索;
以下代码行加载数据并创建 dataframe 对象。将 Inferschema 设置为 true 可以很好地猜测每一列的数据类型。
#The Applied options are for CSV files
df = spark.read.format("csv") \
.option("inferSchema","true") \
.option("header","true") \
.option("sep",",") \
.load(file_location)
我还创建了一个字典来存储与数据类型相关的特性。在我们的例子中,我们有一个“整型”和“双精度型”。
from collections import defaultdictdata_types = defaultdict(list)
for entry in df.schema.fields:
data_types[str(entry.dataType)].append(entry.name)
查看列及其数据类型的代码输出
让我们看看数据集的前 5 行。
display(df.limit(5))
糖尿病数据集由 768 个数据点组成,每个数据点有 9 个特征:
“结果”是我们要预测的特征,其中 0 表示患者没有糖尿病,1 表示患者确实有糖尿病。在这 768 个数据点中,500 个标记为 0,268 个标记为 1。
display(df.groupby('Outcome').count())
使用 Databricks 的一个优点是,它有助于将查询可视化为一些基本的绘图选项,以便更好地理解数据和代码。
我们有一个完整的数据集,没有任何缺失值,但是要找到更多关于处理缺失数据的信息,您可以参考这篇文章:
https://www . analyticsvidhya . com/blog/tag/missing-values-treatment/
处理分类数据:
在我们的数据中,我们只有一个分类列,即超过 17 个类别的“怀孕”。下面的代码显示了如何将分类列/特征转换为一键编码。在 Spark 中,使用“字符串索引器”为每个类别分配一个唯一的整数值。0 被分配给最频繁的类别,1 被分配给下一个最频繁的类别,依此类推。
from pyspark.ml import Pipeline
from pyspark.ml.feature import OneHotEncoder, StringIndexerstage_string = [StringIndexer(inputCol= c, outputCol=
c+"_string_encoded") for c in strings_used]
stage_one_hot = [OneHotEncoder(inputCol= c+"_string_encoded",
outputCol= c+ "_one_hot") for c in strings_used]ppl = Pipeline(stages= stage_string + stage_one_hot)
df = ppl.fit(df).transform(df)
在上面的代码中,我使用了一个管道,它可以在一次迭代中有效地处理一系列任务。人们可以列出任务清单,管道会处理所有事情。
一般来说,机器学习管道描述了编写代码、将其发布到生产、进行数据提取、创建训练模型和调整算法的过程。在 ML 平台上工作是一个连续的过程。但是对于 Apache Spark 来说,管道是一个将步骤转换、评估和装配到一个对象中的对象。这些步骤被称为 ml 工作流。
向量汇编程序:
这里的想法是将一个给定的列列表组装成一个向量列,并将它们捆绑在一起。这是 Spark 的机器学习模型所需的额外步骤。这一步骤通常在数据探索和预处理步骤结束时执行。在这个阶段,我正在使用一些原始的和一些转换的特征来训练一个模型。
from pyspark.ml.feature import VectorAssemblerfeatures = ['Pregnancies_one_hot','Glucose','BloodPressure',
'SkinThickness','Insulin','BMI','DiabetesPedigreeFunction','Age']vector_assembler = VectorAssembler(inputCols = features,
outputCol= "features")
data_training_and_test = vector_assembler.transform(df)
模型拟合:
我们有几个内置的分类器,包括随机森林、提升树、逻辑回归等。首先,作为一个例子,我实现了 Random Forest,指定了分类器中树的数量,并将其余参数保留为默认值。
为了评估我们模型的性能,我使用 ROC 曲线度量。您可以选择自己喜欢的“metricName”。
该模型的准确率为 82.5%。这表明我们的模型在默认参数下运行良好。
from pyspark.ml.classification import RandomForestClassifier
from pyspark.ml.evaluation import BinaryClassificationEvaluator(training_data, test_data) = data_training_and_test.randomSplit([0.7, 0.3], 2017)
rf = RandomForestClassifier(labelCol = "Outcome",
featuresCol = "features", numTrees = 20)
rf_model = rf.fit(training_data)predictions = rf_model.transform(test_data)
evaluator= BinaryClassificationEvaluator(labelCol = "Outcome", rawPredictionCol="probability", metricName= "areaUnderROC")
accuracy = evaluator.evaluate(predictions)print("Accuracy:",accuracy*100)
功能选择:
特征选择过程有助于过滤掉不太重要的变量,从而得到更简单、更稳定的模型。在 Spark 中,实现特性选择不像在 Python 的 scikit-learn 中那样简单,但是可以通过将特性选择作为管道的一部分来管理。这个想法是:
- 首先安装分类器。例如,您可以选择回归模型或基于树的模型,任何您选择的模型。
- 如果使用随机森林,则查找要素重要性;如果使用逻辑回归,则查找系数。
- 将最重要的功能集存储在列表中。
- 从 ml 库中使用' VectorSlicer '方法,并从刚才选择的列表中创建一个新的 vector。
下面的代码显示了如何从我们之前拟合的模型中创建一个重要特性的列表。大于 0.03 的特征被保留,rf_model 是拟合的随机森林模型。
importance_list = pd.Series(rf_model.featureImportances.values)
sorted_imp = importance_list.sort_values(ascending= False)
kept = list((sorted_imp[sorted_imp > 0.03]).index)
取 0.03 是随机的,可以基于 AUC 度量尝试不同的值。后来我用矢量切片器收集所有重要性大于 0.03 的特征。
from pyspark.ml.feature import VectorSlicer
vector_slicer = VectorSlicer(inputCol= "features",
indices= kept, outputCol= "feature_subset")
with_selected_feature = vector_slicer.transform(training_data)rf_modified = RandomForestClassifier(numTrees=20,
labelCol = "Outcome", featuresCol="feature_subset")
test_data = vector_slicer.transform(test_data)
prediction_modified = rf_modified.fit(with_selected_feature)
.transform(test_data)evaluator_modified = BinaryClassificationEvaluator(labelCol = "Outcome",rawPredictionCol="probability", metricName= "areaUnderROC")
accuracy = evaluator_modified.evaluate(prediction_modified)print("Accuracy: ",accuracy*100)
通过特征选择,我们看到准确率提高了 1%,总体准确率为 83%。从完整的特征集中,我们得到了 82%的准确率。在处理大数据时,即使 1%的改进也很重要。
最后,我只想说,Apache Spark 是一个简洁易用的开源框架。
感谢您抽出时间阅读!
我总是期待着学习和成长,如果您有任何问题或建议,请联系我!
领英|sagardaswani1703@gmail.com|Github
计算流体力学中的机器学习
原文:https://towardsdatascience.com/machine-learning-in-computational-fluid-dynamics-7018941414b9?source=collection_archive---------17-----------------------
我的暑期实习经历!
从我在日内瓦和平区坐过的桌子上看到的景色。图片鸣谢:Moi。
2018 年夏天,我获得了一个在瑞士日内瓦高等教育学院实习的绝佳机会。
我花了几乎三个月的时间用机器学习解决了一个问题,在我见过的最美丽的国家之一,遇到了这么多了不起的人。有什么不喜欢的,对吧?
该项目
顾名思义,该项目涉及用机器学习模型取代格子玻尔兹曼方法中的复杂计算,以提高名为 帕拉博斯—ParallelLatticeBoltzmannSolver 的模拟器的性能。
我在这里会完全诚实;当我在那里得知这个项目时,我有点不知所措。我没有物理学背景,对机器学习也相当陌生。我不认为我有足够的资格做这样的事情——冒名顶替综合征的可用性必须是 100%,似乎从不错过任何机会!无论如何,我决定全力以赴,看看我能走多远,因为这是我们学习的方式。
背景
格子 Boltzmann 方法(LBM)是计算流体动力学(CFD)中模拟单相和多相流体流动的并行算法。它有助于模拟复杂的边界条件和多相界面。
它将流体建模为虚拟粒子,这些粒子在离散网格上执行连续的碰撞和流动步骤。常用的点阵命名为 DnQm,这意味着点阵具有 n 的空间维度和 m 的离散速度。在每个时间步中,任何节点上的粒子只能以一种离散速度移动到它们最近的相邻位置。一旦粒子移动到它们相邻的位置之一,它们将与同时到达同一位置的其他粒子发生碰撞。
LBM 的粒子运动。来源。
在直接数值模拟中——计算流体动力学中的一种模拟——在没有任何湍流模型的情况下数值求解纳维尔-斯托克斯方程。
大涡模拟(LES)是计算流体力学中用于模拟湍流的数学模型。计算域的大小应至少比表征湍流能量的尺度高一个数量级,同时计算网格应足够精细,以解决最小的动态有效长度尺度,从而进行精确模拟。
如果通过使用非常精细的网格直接求解纳维尔-斯托克斯方程来精确地解决所有的涡流(网格应该比最小的湍流涡流更精细,湍流涡流本质上是水的环流),则会导致很高的计算成本。为了克服这些计算成本,在 LES 中,仅直接计算大尺度运动(大涡流),而小尺度(亚网格尺度(SGS))运动被建模。
最后,LBM 告诉我们,我们可以将流体想象为空间和时间中的虚拟粒子,DNS 告诉我们如何模拟每个粒子的行为——给定系统的物理条件——在每个时间步长,les 通过近似亚网格尺度的涡流,使得在尺度范围变化很大时对湍流做这些事情成为可能。
我花了大约两周的时间学习它背后的物理学,设置我的系统(最初默认语言为法语),获得 IDE——使用一个名为 Qt 的 IDE,浏览软件代码以了解更高层次上发生的事情。
问题陈述
使用机器学习来学习大涡模拟中亚网格尺度(SGS)运动的模型,并将其与现有模拟器集成,以取代当前的亚网格计算。
- 使用的语言:C++,因为它很快。
- 该模型需要体积小、速度快,以便可以轻松部署,而不会增加内存负载或延迟模拟。
- 建议不要使用外部框架,如 TensorFlow 或 PyTorch。
解决办法
解决一个大而复杂的问题的最好方法是把它分解成更小更简单的问题。我做了同样的事情,把我的问题分成以下三个问题:
- 设计一个简单的结构来模拟亚网格尺度的运动。
- 根据时间和其他约束来训练和优化模型。
- 将模型与现有软件集成。
子问题#1 -模型架构和训练数据:
训练数据有九个输入属性:
1:密度
2–3:速度
4–6:应力
7:涡度
8–9:密度梯度
输出有 3 个代表残余应力张量的属性。它有大约一百万个字节组。
该架构的目标是在不牺牲性能的情况下尽可能保持简单。我决定使用最简单的神经网络,称为感知器模型。它由输入层、输出层和隐藏层组成。
在神经网络模型的输入层之前添加了一个缩放层,以便在将训练数据输入模型之前对其进行标准化。由于预测输出是一个回归问题,因此在预测新的未知数据的值时,在输出层之后添加了一个未缩放层。
下一个任务是找到模型中每一层的尺寸。输出层有 3 个节点,每个节点对应于训练数据输出部分的一个属性。
我将输入节点的数量保持为 9,并开始研究隐藏节点的数量,以找到隐藏层的最佳大小,同时跟踪平均平方误差和测试所需的时间。我从极端情况开始,保持隐藏节点的数量非常低和非常高——保持学习速率、时期数和其他变量不变——然后通过遵循非常类似于二分搜索法的方法缩小范围。然后我发现中值也是如此,然后是(低,中)和(中,高)的中值,这两个中误差较小的一个成为我们新的搜索空间。
一旦决定了隐藏节点的最佳数量,我还会考虑模型的输入数量。令人惊讶的是,如果我将输入减少到 6,结果并没有大幅下降。因此,如果需要进一步缩小模型尺寸,我也有这个选择。几年后,我了解到这就是所谓的“消融研究”,即移除模型的特征并评估其对输出的影响,这是一个值得遵循的良好实践。
以上所有工作都是在原始训练数据的子集上完成的,以确保项目的顺利进行。
在这一部分,我花了大约两周的时间,熟悉了 OpenNN 库,编写了模型代码,并对数据集进行了试验,以获得上述值。
子问题#2 -训练模型:
一旦我们的模型架构最终确定,我发现自己在寻找数据集子集上给定架构的最佳学习率。同样,我遵循了一个非常类似于二分搜索法的策略——从极端开始,然后从那里缩小范围。我使用了拟牛顿法进行权重优化,这可以在 C++的 OpenNN 库中找到。
一旦这样做了,我就开始学习上面练习中发现的三个最小的错误。然后,对于每个学习率,我在整个数据集上训练模型。我重复了五次,最终选择了在这五次运行中表现最好的学习率。
这是一个缓慢的过程,因为每次训练大约需要一天的 0.5-0.75 分钟。我在这上面花了大约三个星期。
子问题#3 -与 Palabos 集成:
第一件事是在没有任何 IDE 的情况下运行代码;我更新了所需包的路径,并链接了所需的库。
一旦完成,模型被调用,而不是模拟亚网格尺度漩涡的函数。我们尝试在几个场景下运行该模块,并将性能与我们从模拟漩涡中获得的结果进行比较。
总体体验
我在实习期间过得很愉快。做这个项目我学到了很多;比如如何解决一个大问题,为给定问题开发人工智能解决方案的方法,等等。
外卖:
——如果现在让我再做一次,我还会以同样的方式做事吗?大部分,是的。但是我会更加重视项目的测试和验证方面。如果我有更多的时间,我可能也会这样做,但如果我现在这样做,我会确保在计划期间专门为此分配一些时间——包括整合之前和之后。
-我意识到我喜欢使用 ML,并将其应用于新问题或改进现有解决方案。所以,是的,我现在正在寻找更经常地做这件事的方法——人工智能/人工智能的新应用!有一个好的导师会有很大的不同。我是唯一参与这个项目的人。但是我的导师真的很有帮助。他会听我说些什么,然后指导我。我完全可以控制我想如何做这个项目,但同时我总是让他指导我。我想这就是这次经历如此充实和令人满意的原因。
我也遇到了一些非常善良和了不起的人,他们现在仍然是我的朋友。谢谢你 2018 年夏天给了我难忘的美好经历。❤
参考资料和更多信息
- 了解 LES 的更多深入解释。
- LES——另一种资源。
- OpenNN 库
我认为你会喜欢:D 的其他文章
- 是的,你应该听听 Andrej Karpathy,了解反向传播
- 利用深度学习检测恶意软件
- 在深度学习中获得注意力
我很高兴你坚持到了这篇文章的结尾。🎉我希望你的阅读体验和我写这篇文章时一样丰富。💖**
请点击这里查看我的其他文章。
如果你想联系我,我会选择 Twitter。
优惠券推荐中的机器学习
原文:https://towardsdatascience.com/machine-learning-in-coupon-recommendation-2bdae281d840?source=collection_archive---------21-----------------------
演职员表:模拟世界
多臂强盗如何帮助星巴克向顾客发送个性化的优惠。
你多久会等一次优惠券来购买一件商品?在一些无趣的交易之后,你是否想放弃使用这项服务?
优惠券系统已被广泛用于提高消费者对基于数字的平台的参与度。通过向用户提供挑战和相应的奖励,公司的服务不仅变得更有吸引力,而且最重要的是,它可以使用户成为常客,从而增强品牌对其客户的影响。然而,知道提供哪种优惠券可能是一项相当复杂的任务,因为每个客户对每个优惠的反应都不同,经常向他们提供糟糕的交易可能会将他们从您的业务中拖走。
为了克服这个问题,可以使用机器学习技术来建立数据驱动的客户档案,并开发更好的优惠券推荐。就此而言,这篇文章展示了如何在星巴克移动奖励应用程序中使用 K-Means 聚类结合多臂强盗来构建优惠券推荐系统。
这篇文章是提交给 Udacity 的机器学习工程师 Nanodegree 的 capstone 项目的结果,其源代码可以在这个资源库中找到。有关更多技术信息,如参数扫描和数据集预处理,请参考关于存储库的详细报告。
所以事不宜迟,言归正传!
学分:免费
星巴克奖励手机 App
每隔一天,星巴克都会向用户发送可过期的优惠,这些优惠有自己的难度和过期日期。每个报价可以通过多种营销渠道(电子邮件、手机、社交媒体和网页)发送,一旦完成报价挑战,他们将获得与难度级别一样高的奖励金额。
当用户查看优惠时,他们可以决定:
- 完成挑战:)
- 忽略挑战,但仍然在没有优惠券的情况下进行购买:|
- 忽略一切:(
以下是几周以来 app 营销漏斗中流量的一瞥:
星巴克奖励应用中顾客流的桑基图(图片由作者提供)。
发送报价后,我们有兴趣根据每个营销渠道进行分析:
- 该要约未被转换;
- 这变成了购买;
- 这导致了未来的购买
- 这些都被忽略了,但用户仍然从应用程序中购买。
在样本数据集中,100%的报价都被浏览过——很可能是因为报价是通过多种渠道发送的。高比例的浏览报价带来了一个积极的特点,即让顾客了解品牌和他们提议的报价。当这些建议导致购买行为时,可以推断出顾客不仅知道该品牌的服务,而且也被它所吸引。
然而,相当多的购买是在没有使用优惠券的情况下进行的。这表明即使使用了适当的营销渠道,奖励提议对用户也没有吸引力,这更多地涉及产品的特性而不是营销策略本身。也许通过使用相同的渠道改变发送的报价(这将是我们的推荐系统的任务),客户将接受报价并因此获得奖励。
在漏斗的末端,要约提议可以实现的最重要的任务之一是说服客户进行未来购买。这可以作为一种代理,吸引客户成为品牌的拥护者[2]。
当客户倾向于重复购买某个公司的产品时,他/她可能会说服他们的同行尝试某个产品,从而在市场上产生更多的品牌认知度和吸引力。
请注意,这是移动奖励应用程序的一个相当大的缺陷,因为只有来自 111k 的 22.9k 才会导致未来的购买。
请记住,在发送要约后,用户参与漏斗的各个步骤所需的时间与销售线索状态高度相关。销售线索是潜在买家,其状态可以是冷淡、热情或合格[3]。用户一看到报价,就可能被认为是潜在客户,因为他对此感兴趣。
例如,当客户打开电子邮件报价时,他可能会被其标题内容所吸引——因此我们认为他是在为热身。然而,如果他/她不继续接受这份工作,他会变得越来越冷淡,这意味着他对接受这份工作的兴趣会逐渐减少。
理想情况下,用户应该花很短的时间从查看和提供并完成它。这是我们数据集的运行时间分布:
从(a)发送和提供到观看它和(b)观看和提供并完成它(作者的图像)的时间推移分发。
请注意从查看要约到完成要约的时间分布(以小时计)大致遵循长尾分布。这意味着大多数购买来自于迅速完成的报价。为了分析分布的尾部有多长,我们可以将数据拟合到一个幂律分布,其概率分布函数定义如下
其中参数 α 越低,尾巴越长。对于我们的数据集,在第一个时间间隔中α = 10.57,在第二个时间间隔中α = 7.01。自然地,这些经过的时间很大程度上受要约的属性影响,如难度和持续时间,这只会影响用户查看要约时的延时——因此解释了为什么我们在延时中有更长的尾巴(b)。
这个营销方面的概述帮助我们创建一个定制函数,该函数指示给定客户的报价有多合适:我们将把它称为 MAB 奖励函数 ,其算法描述如下。
(图片由作者提供)
多股武装匪徒(MAB)
MAB 算法在统计学中已经被广泛研究了一段时间,用来解决老丨虎丨机问题。想象一下,你有一个代理人(强盗),他可以重复地从 k 台可用的机器中拉出一只手臂,并可能从中获得奖励。
当强盗与吃角子老丨虎丨机互动时,他注意到其中一个似乎给了更多的奖励,因此很想利用这个杠杆。然而,其他机器可能会给予更多奖励。在这种情况下,他需要决定是否
- 利用一台迄今为止累计回报最高的机器,或者
- 探索其他机器,从长远来看,它们可能会带来更好的累积回报。
理论上,代理人是在试图估计每台机器的报酬概率分布函数,而不是在那些期望报酬低的人身上浪费太多的尝试。
在其最简单的数学公式中,MAB 由 k 个机器组成,它们有自己的概率分布 p 、预期回报μ和方差σ——所有这些对代理人来说最初都是未知的。在每个时期T∈【1,T 】一个手臂 a_i 被拉动,并且获得奖励。然后,强盗遵循一个策略来选择下一条手臂:到目前为止给出最高回报的手臂或者另一条可能带来更好回报的手臂。第轮 T 的最高收益由下式给出
其中μ*是最佳臂的预期回报。换句话说,他需要做出开采-勘探权衡的决策。
已经采用了几种技术来解决这个问题,其中之一是ϵ-greedy 方法[1]。在这个经典的方法中,每一轮强盗选择概率为 1 的具有最高经验平均值的手臂——ϵ,或者选择概率为ϵ.的随机手臂
可以推断,ϵ参数对开采-勘探权衡有很大影响。对于更高的ϵ,选择最高经验均值臂的贪婪行为被选中的概率更低,从而导致土匪探索更多的选项。相反,在ϵ较低的情况下,算法倾向于选择贪婪动作。
ϵ-greedy 是无数算法的基础。为了在最初的几轮中有更多的勘探和在以后的几轮中有更多的开发,可以用衰减ϵ-greedy 方法应用一个轮变β。在这种情况下,第 n 轮的ϵ定义为
其中β控制ϵ减少的速度, n 是当前回合。此外,可以定义阈值λ,以便在后面的回合中限制最小探索。
MAB 算法已经在许多需要进行顺序决策的应用中使用,例如推荐系统。在这种情况下,MAB 被用于建模消费简档,考虑向用户(代理)提供若干项目(老丨虎丨机),并且他们可以根据奖励概率分布函数来消费它。
对于当前的 Starbucks 奖励项目,它们将用于建立客户档案模型,将每只手臂视为一个要约和一个定制的奖励函数,该函数定义为掌握获得的优惠券奖励和营销成就,这将在后面看到。
在星巴克的奖励应用中应用 MAB
将 MAB 应用于一个问题的一个关键步骤是定义它的回报函数。正如我们所见,客户进入营销漏斗的深度在很大程度上表明了优惠策略的好坏。在这个意义上,可以使用下面的奖励函数:
其中所有变量都是二进制的,除了提供奖励。该等式的下限为 0,这发生在要约未被查看时(使得 offerCompleted = 0 和 futurePurchase = 0 )。当给出一个高报价奖励,并且所有的二元变量都是 1,包括未来的购买,这是营销策略的圣杯时,最好的奖励就来了。
一旦我们建立了这个功能,我们就可以考虑以下变量来创建数据驱动的客户档案:
- 年龄,收入
- 订阅后的年数
- 每种产品的平均mab 奖励
在对用户进行聚类之后,每一组都被建模为一个 MAB,有要约作为可拉的手臂。下图描绘了 MAB 训练的 20 个实现的平均回报演变(所有参数决策在项目报告中讨论,此处):
ϵ-greedy 衰减表示 20 次实现的平均奖励(图片由作者提供)。
注意平均报酬是如何上升的,直到一个收敛区域。这是勘探-开采权衡变化的结果:开始时,我们尽可能多地勘探,以便找到更好的武器。随着时代的推移,利用最好的武器变得更加频繁,直到没有观察到平均奖励的显著提高。
最后,用户群可以被预测,他们的报价推荐可以通过 MAB 的帮助来完成。由于每次迭代只能拉动一只手臂,自然会出现对产品多样性的关注。那么,在培训阶段选择报价的频率如何呢?我们用下图来核对一下:
按类别选择的武器数量(图片由作者提供)。
可以看出,10 个选项中有 3 个被大多数集群高度选中,这意味着,一般来说,30%的产品组合是被推荐的。这个数字受 MAB 收敛后勘探速度的影响很大。当探索度较低时,该模型倾向于仅推荐已经显示提供最高回报的报价。更高的探索可以为该推荐器带来更好的多样性,然而这可能在使用预测方面影响模型的性能。
包扎
我们已经看到优惠券如何成为一种强大的参与工具,让用户更接近公司的服务。通过瞄准正确的线索和客户,不仅可以提高转化率,而且最重要的是,可以与他们建立长期关系。然而,制定成功的目标战略可能需要建立数据驱动的客户档案。这就是公司依靠机器学习的力量来提供个性化建议的地方。
在无数的推荐算法中,多臂强盗因其使用手工制作的奖励函数的灵活性而被广泛探索,例如我们用于 graps 营销方面的函数。如果你想深入研究一种更强大的 MAB 方法,我强烈推荐阅读 Spotify 研究人员开发的关于 BaRT(作为治疗方法的替代物)[4]的文章。
[1]萨顿,理查德 s 和巴尔托,安德鲁 G. 强化学习:导论 (2018),麻省理工学院出版社。
[2] P. Kotler,H. Kartajaya 和 I. Setiawan,营销 4.0:从传统走向数字 (2016)
【3】冷、暖、合格引线的区别
[4] J. McInerney,B. Lacker,S. Hansen,K. Higley,H. Bouchard,A. Gruson,R. Mehrotra。探索、利用和解释:用强盗个性化可解释的推荐 (2018),ACM 推荐系统会议(RecSys) 。
数据科学面试中的机器学习
原文:https://towardsdatascience.com/machine-learning-in-data-science-interviews-e03f26904375?source=collection_archive---------63-----------------------
5 个需要研究的挑战性问题和主题
凯文·Ku 在 Unsplash 上的图片
概观
机器学习问题通常是数据科学面试中最难的部分,这是有充分理由的。这篇文章将强调几个示例问题,对机器学习的一般评论,以及在理论和应用方面需要研究的主题。讨论的问题来自 https://datascienceprep.com/的,涵盖了顶级科技公司的面试问题。
5 个挑战性问题
- 假设我们使用高斯混合模型(GMM)对欺诈性交易进行异常检测,将传入的交易分为 K 类。用公式描述模型设置,以及如何评估后验概率和对数似然。我们如何确定一项新交易是否应被视为欺诈?
- 假设您正在对具有 K 个类的一些数据运行线性判别分析(LDA)模型。从数学上描述你如何将形心投影到 L < K-1 维的子空间。
- 描述核平滑的思想和数学公式。如何计算核回归估计量?
- 假设我们正在运行概率线性回归,它很好地模拟了一些 y 和 x 之间的潜在关系。现在假设所有输入都添加了一些噪声ε,这与训练数据无关。新的目标函数是什么?你是怎么计算的?
- k-means 聚类中对于 k 个聚类和 n 个样本点使用的损失函数是什么?使用 1)批量梯度下降,2)使用学习率ε对聚类 k 的聚类均值进行随机梯度下降来计算更新公式。
一般评论
机器学习并不适用于每个数据科学角色,因为数据科学是一个广阔的领域,但对于相关角色来说,它是一个既有深度又有广度的重要研究领域。然而,无论角色如何,我认为对任何数据科学家或有抱负的数据科学家来说,研究机器学习都是有用的,原因有三:
- 它是数学、计算机科学和统计学的交叉,每一个都是一个丰富的研究领域,是一生坚实知识的基石。
- 机器学习提供了理论和应用的完美结合——有无数的事情值得好奇,也有事物如何在实践中运行和使用。
- 正如软件已经颠覆了世界范围内的商业格局一样,机器学习已经颠覆了,并将继续帮助现有的企业取得巨大的进步,并带来一系列令人惊叹的未来企业。
研究机器学习
有两个与机器学习相关的主要关注领域:理论和应用。理论需要模型背后的所有数学基础,以及它们为什么以及如何以这种方式工作,而应用需要所有真实世界的用例,从而大规模技术可以利用这种模型。学习和精通这两者同样重要。
理论上,有大量的教科书和其他在线资源可供你使用。有必要理解各种算法和框架背后的数学,以便了解模型如何调整和运行背后的模式。这样做将导致对应用程序的更好理解,并且熟悉如何考虑对各种模型的不同适应。此外,熟悉所有技术细节肯定有助于机器学习面试问题的理论方面。
对于应用程序,假设您可以获得足够的感兴趣的数据(Kaggle 和 Open AWS 提供了许多数据集),则有无数的实际项目可以研究!)——如果不可行,也值得了解一下有多少公司大量利用机器学习(例如,阅读关于网飞使用推荐系统的文章)。这将加强你的理论理解,并提供对一些世界顶级企业如何使用机器学习来大规模产生大量价值的见解。
要研究的主题
下面的列表并不详尽,但包含了从鸟瞰的角度来看什么是好的话题的想法:
- 对模型的一般理解:偏差-方差权衡,评估模型拟合,抽样,交叉验证等。
- 线性模型:回归(简单和多重),模型选择,收缩方法
- 分类:线性方法(LDA,逻辑回归等。)和非线性(支持向量机、决策树等。)
- 神经网络:反向传播,CNN,RNNs,LSTMs 等。
- 无监督学习:聚类(K-means)、PCA、因子分析等。
当学习每一种方法时,一定要沉浸在事物的应用方面——有许多真正有趣的公司在他们业务的核心部分使用上述各种方法。例如:许多企业利用欺诈检测—在那里可以运行和使用哪些模型?推荐引擎呢?投放广告?客户终身价值分析?
注意:还有很多其他领域(强化学习,计算机视觉,博弈论话题等。)为了简洁起见,在上面的列表中省略了它们。
感谢阅读!
如果你有兴趣在数据科学采访中进一步探索机器学习,请查看这个发给你练习问题的时事通讯。
医疗保健中的机器学习:检测黑色素瘤
原文:https://towardsdatascience.com/machine-learning-in-healthcare-detecting-melanoma-70147e1b08de?source=collection_archive---------26-----------------------
通过应用若干机器学习算法,使用患者的诊断报告和皮肤病变图像来检测病变是癌性的还是非癌性的。
国家癌症研究所在 Unsplash 上拍摄的照片
皮肤癌是最常见的癌症。它的发生是由于皮肤细胞的异常生长,通常是在暴露于阳光的区域。有三种主要类型的皮肤癌——基底细胞癌、鳞状细胞癌和黑色素瘤。特别是黑色素瘤,尽管它是最不常见的皮肤癌,但却造成了 75%的皮肤癌死亡。
黑色素瘤是一种致命的疾病,但如果早期发现,大多数黑色素瘤可以通过小手术治愈。
在本文中,我们将通过应用几种机器学习算法将病变分类为良性或恶性,从患者的诊断记录和皮肤病变的图像中识别黑色素瘤。更好地检测黑色素瘤有机会对数百万人产生积极影响。
注意:下面的代码是使用 Kaggle 提供的数据集 SIIM-ISIC 黑色素瘤分类 在 Kaggle 内核上实现的。你可以在这里找到完整的代码。
我们将遵循以下步骤来实现该算法。
导入库
让我们通过在 Kaggle 内核中导入所需的库来开始实现,如下所示:
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
import cv2
import pydicom as dicom
import pandas as pd
import numpy as np
from sklearn.metrics import accuracy_score, confusion_matrix
from sklearn.metrics import mean_squared_error, r2_score
导入的 pydicom 库用于处理数据集中提供的图像。这些图像属于 DICOM(医学数字成像和通信)类型,这是传输、存储、检索、打印、处理和显示医学成像信息的国际标准。
分析数据集
下一步是导入 Kaggle 提供的数据集 SIIM-ISIC 黑色素瘤分类 。
df = pd.read_csv('/kaggle/input/siim-isic-melanoma-classification/train.csv')
df.head()
SIIM-ISIC 黑色素瘤分类数据集
从上面给出的数据集,我们可以推断黑色素瘤的分类取决于两件事,即患者的详细信息和患者皮肤损伤的图像。整个过程解释如下。
源 1 、源 2 、源 3 、源 4
我们获取患者的详细信息和皮肤病变图像,然后应用机器学习算法来检测此人是否患有癌症。
图像分类
让我们从检测数据集中提供的图像中存在的黑色素瘤开始。
黑色素瘤迹象包括:
- 带有深色斑点的褐色大斑点
- 颜色、大小或感觉改变或出血的痣
- 边缘不规则的小病灶,部分呈现红色、粉色、白色、蓝色或蓝黑色
- 发痒或灼烧的疼痛损伤
- 手掌、脚底、指尖或脚趾,或口腔、鼻子、阴道或肛门粘膜上的黑色病变
来源
使用这些迹象,机器学习算法将皮肤损伤分类为良性或恶性。
让我们从从整个数据集中抽取一小部分数据样本来开始实现。
s0 = df.target[df.target.eq(0)].sample(50).index
s1 = df.target[df.target.eq(1)].sample(60).indexdf = df.loc[s0.union(s1)]
df['target'].value_counts()
这是我们新生成的数据集,我们将使用它来训练我们的机器学习模型。
现在让我们来看看这些图片。这些图像以 DICOM 格式呈现,因此我们使用由 pydicom 库提供的 dicom.dcmread() 函数来读取图像。
image = '/kaggle/input/siim-isic-melanoma-classification/train/' + df['image_name'][1512] +'.dcm'ds = dicom.dcmread(image)plt.imshow(ds.pixel_array)
显示恶性和良性癌症区别的图片
下一步是训练我们的机器学习模型。为了做到这一点,图像应该首先以模型能够理解的格式表示。为此,我们需要将图像转换成像素格式。
因此,对于数据集中的每个图像,我们使用 dicom.dmread() 读取图像,并使用 ds.pixel_array 提取像素。这些像素是多维的,因此我们使用 flatten 函数将其转换为一维数组。然后,我们将这些像素格式的图像添加到一个名为 images 的列表中。
images = []for x in df['image_name']:
image = '/kaggle/input/siim-isic-melanoma-classification/train/' + x +'.dcm'
ds = dicom.dcmread(image)
pixels = ds.pixel_array
images.append(pixels.flatten())
使用像素表示图像
现在,出现的问题是每个图像都有不同数量的像素,因此生成的数组具有不均匀的长度。为了解决这个问题,我们使用填充技术,要么向数组添加额外的值,要么丢弃某些值,以使数组的长度等于指定的最大长度。
import tensorflow as tf
images = tf.keras.preprocessing.sequence.pad_sequences(
images,
maxlen = 720,
dtype = "int32",
padding = "pre",
truncating = "pre",
value = 0
)
我们还需要一个包含图像的测试数据集来测试我们的模型。我们可以如下生成测试数据集。
test = df.tail(50)
test.head()
测试数据集
一旦我们准备好数据集,我们就重复上面显示的过程。也就是说,我们首先将图像转换为其像素格式,然后应用填充技术,使图像具有相同数量的像素。
test_images = []
count = 0for x in test['image_name']:
image = '/kaggle/input/siim-isic-melanoma-classification/train/' + x +'.dcm'
ds = dicom.dcmread(image)
pixels = ds.pixel_array
test_images.append(pixels.flatten())
count +=1
print(count)test_images = tf.keras.preprocessing.sequence.pad_sequences(
test_images,
maxlen = 720,
dtype = "int32",
padding = "pre",
truncating = "pre",
value = 0
)
最后,是时候训练我们的模型了。
我们将使用几种机器学习算法来训练我们的模型,然后测试它以查看准确性得分。
我们将设置的值
X =图像(包含像素格式图像的列表)
y = NP . array(df[' target '])(表示图像中的病变是良性还是恶性的值)
1。逻辑回归
from sklearn.linear_model import LogisticRegressionX = images
y = np.array(df['target'])
classifier_lr = LogisticRegression()
classifier_lr.fit(X,y)X_test = test_images
y_test = np.array(test['target'])
y_pred_lr = classifier_lr.predict(X_test)print('Accuracy Score: ',accuracy_score(y_test,y_pred_lr))
print('Confusion Matrix: \n',confusion_matrix(y_test,y_pred_lr))
逻辑回归算法给出的精确度
2。支持向量机
from sklearn import svm
X = images
y = np.array(df['target'])
classifier_svm = svm.SVC()
classifier_svm.fit(X,y)X_test = test_images
y_test = np.array(test['target'])
y_pred_svm = classifier_svm.predict(X_test)print('Accuracy Score: ',accuracy_score(y_test,y_pred_svm))
print('Confusion Matrix: \n',confusion_matrix(y_test,y_pred_svm))
支持向量机算法给出的精度
3。决策树
from sklearn.tree import DecisionTreeClassifier
X = images
y = np.array(df['target'])
classifier_dt = DecisionTreeClassifier()
classifier_dt.fit(X,y)X_test = test_images
y_test = np.array(test['target'])
y_pred_dt = classifier_dt.predict(X_test)print('Accuracy Score: ',accuracy_score(y_test,y_pred_dt))
print('Confusion Matrix: \n',confusion_matrix(y_test,y_pred_dt))
决策树算法给出的精确度
4。随机森林
from sklearn.ensemble import RandomForestClassifier
X = images
y = np.array(df['target'])
classifier_rf = RandomForestClassifier()
classifier_rf.fit(X,y)X_test = test_images
y_test = np.array(test['target'])
y_pred_rf = classifier_rf.predict(X_test)print('Accuracy Score: ',accuracy_score(y_test,y_pred_rf))
print('Confusion Matrix: \n',confusion_matrix(y_test,y_pred_rf))
随机森林算法给出的精确度
5。自适应增压
from sklearn.ensemble import AdaBoostClassifier
X = images
y = np.array(df['target'])
classifier_ab = AdaBoostClassifier()
classifier_ab.fit(X,y)X_test = test_images
y_test = np.array(test['target'])
y_pred_ab = classifier_ab.predict(X_test)print('Accuracy Score: ',accuracy_score(y_test,y_pred_ab))
print('Confusion Matrix: \n',confusion_matrix(y_test,y_pred_ab))
自适应升压算法给出的精度
6。梯度增强
from sklearn.ensemble import GradientBoostingClassifier
X = images
y = np.array(df['target'])
classifier_gb = GradientBoostingClassifier()
classifier_gb.fit(X,y)X_test = test_images
y_test = np.array(test['target'])
y_pred_gb = classifier_gb.predict(X_test)print('Accuracy Score: ',accuracy_score(y_test,y_pred_gb))
print('Confusion Matrix: \n',confusion_matrix(y_test,y_pred_gb))
由梯度推进算法给出的精度
在使用几种机器学习算法对图像进行训练和测试后,我们得到了不同的准确度。有些算法会使数据过拟合,而有些算法会使数据欠拟合。因此,我们继续使用逻辑回归算法,因为它既不过度拟合也不欠拟合数据,给出 96%的准确度。
显示使用机器学习算法获得的精确度的条形图
使用病历进行分类
为了方便起见,我们先将“anatom _ site _ general _ challenge”重命名为“site”。
df = df.rename(columns = {'anatom_site_general_challenge':'site'})
为了开始数据的训练,我们首先需要理解数据。让我们应用一些可视化和数据清理技术来更好地解释我们的数据。
首先,让我们使用以下代码删除数据集中所有缺失的值
df = df.dropna(axis=0, how = 'any')
考虑到 age_approx 并作为一个因素,我们可以使用下面的代码来创建如下所示的图表。
age = []
for i in range(df.shape[0]):
try:
if df['target'][i] == 1:
age.append(df['age_approx'][i])
except:
passplt.figure(figsize=(15,5))plt.subplot(1,2,1)
sns.distplot(age)
plt.title('Distribution of age of people having malignant cancer')plt.subplot(1,2,2)
sns.countplot(y = age)
plt.ylabel('Age')
plt.title('Count plot of age of people having malignant cancer')
使用 age_approx 作为因子创建的图表
从上面的图表中可以推断出以下几点:
- 大多数恶性肿瘤患者的年龄在 40 至 80 岁之间
- 年龄值大于 60 岁的癌症患者人数最多,其次是年龄值在 55 至 60 岁之间的人。
- 患有癌症且年龄值低于 10 岁的患者数量非常少。
考虑到站点,作为一个因素,我们可以使用下面的代码来创建下图。
site = []
for i in range(df.shape[0]):
try:
if df['target'][i] == 1:
site.append(df['site'][i])
except:
passsns.countplot(y = site)sns.countplot(y = site,palette="rocket")
plt.title('Graph showing count of patients having cancer and the site it is located in')
plt.ylabel('Site')
使用站点作为因素创建的图表
从上面的图表中可以推断出以下几点:
- 大多数病人的躯干都有皮肤损伤
- 极少数患者的手掌/溃疡或口腔/生殖器部位出现皮肤损伤。
如您所见,属性性别、位置和诊断包含分类数据。因此,我们使用 pandas.get_dummies() 将分类数据转换为模型可以理解的虚拟变量或指示变量。
我们还删除了不需要的列,良性 _ 恶性和患者 id 。
这可以通过以下方式完成:
df = pd.get_dummies(df, columns = ['sex'],drop_first=True)df = pd.get_dummies(df, columns = ['site'],drop_first=True)df = pd.get_dummies(df, columns = ['diagnosis'],drop_first=True)
df = df.drop('diagnosis_unknown', axis = 1)df = df.drop(['benign_malignant', 'patient_id'], axis = 1)
df.head()
我们的数据集现在包含 16 个属性。下一步是选择正确的属性来训练我们的模型。我们可以通过找出属性和目标之间的相关性来做到这一点。为此,让我们使用以下代码生成一个热图:
plt.figure(figsize = (10,10))
sns.heatmap(df.corr()[['target']].sort_values('target').tail(16), annot = True)
显示属性和目标之间相关性的热图
从上面的热图可以推断出以下几点:
- 诊断 _ 黑色素瘤与目标值直接相关。因此,如果一个人被诊断患有黑色素瘤,他就患有癌症,如果一个人没有被诊断患有黑色素瘤,他就没有癌症。
- 年龄 _ 近似值、性别 _ 男性和部位 _ 上肢与目标正相关。
- 诊断痣、部位下肢和部位躯干与目标呈负相关。
这也可以从下图中得到解释。
显示属性和目标之间相关性的图形
现在让我们训练我们的机器学习模型。我们将使用几种机器学习算法来训练我们的模型,然后测试它以查看准确性得分。
我们首先创建训练和测试数据集。
X = df[['diagnosis_melanoma','site_torso','diagnosis_nevus','site_lower extremity','site_upper extremity', 'sex_male', 'age_approx']]y = df['target']from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size = 0.3, random_state = 1)
现在,我们需要应用分类算法,该算法采用这些属性并根据目标值训练模型。这可以通过使用上面使用的相同算法和程序来训练具有皮肤损伤图像的模型来完成。
在成功训练算法之后,我们获得以下准确度分数:
正如你所看到的,支持向量机算法没有过度拟合数据,并给出了 98%的准确率,我们选择它进行进一步处理。
我们选择了逻辑回归算法来从图像中预测癌症,我们选择了支持向量机来基于患者的医疗细节和诊断来预测癌症。
在我们的下一步也是最后一步,我们测试患者的全部记录,并检测他或她是否患有癌症。
患者记录如下:
image_name = ISIC_0149568
年龄 _ 大约= 55 岁
sex_male = 0
站点 _ 下肢= 0
site_torso = 0
场地 _ 上肢= 1
诊断 _ 黑色素瘤= 1
诊断 _ 痣= 0
image_path = '/kaggle/input/siim-isic-melanoma-classification/train/ISIC_0149568.dcm'
details = [[55,0,0,0,1,1,0]]
image_to_test = []
ds = dicom.dcmread(image_path)
pixels = ds.pixel_array
plt.imshow(pixels)
image_to_test.append(pixels.flatten())image_to_test = tf.keras.preprocessing.sequence.pad_sequences(
image_to_test,
maxlen = 720,
dtype = "int32",
padding = "pre",
truncating = "pre",
value = 0
)print(train2.predict(image_to_test))if train1.predict(details) == [1]:
result1 = 'Malignant'
else:
result1 = 'Benign'if train2.predict(image_to_test) == [1]:
result2 = 'Malignant'
else:
result2 = 'Benign'print('Result from patient details: ', result1)
print('Result from patient image: ', result2)
图像路径存储图像名称的路径
详细信息存储患者记录的详细信息
训练 1 是使用患者记录训练的模型。
train2 是使用患者皮肤病变图像训练的模型。
执行代码后,我们得到如下结果:
最终测试后的输出
正如你所看到的,算法正确地检测出病人患有癌症。因此,我们可以推断,机器学习算法可以有效地用于医疗保健和医疗领域。
点击此处查看完整代码。
如果你想知道如何使用神经网络而不是机器学习算法对图像进行分类点击这里。
参考
[## SIIM-国际标准工业分类黑素瘤分类
识别病变图像中的黑色素瘤
www.kaggle.com](https://www.kaggle.com/c/siim-isic-melanoma-classification/overview) [## 皮肤癌——症状和原因
皮肤癌——皮肤细胞的异常生长——通常发生在暴露在阳光下的皮肤上。但是这种常见的形式…
www.mayoclinic.org](https://www.mayoclinic.org/diseases-conditions/skin-cancer/symptoms-causes/syc-20377605)
Java 中的机器学习
原文:https://towardsdatascience.com/machine-learning-in-java-e335b9d80c14?source=collection_archive---------2-----------------------
如何在 Java 中构建和部署 ML 模型?
迈克·肯尼利在 Unsplash 上的照片
机器学习(ML)已经在学术界和工业界的不同领域获得了重大承诺。随着时间的推移,ML 在图像、语音识别、模式识别、优化、自然语言处理和推荐等众多应用领域的参与度不断提高。
给计算机编程以从经验中学习,最终将消除对这种细致编程工作的需求。阿瑟·塞缪尔 1959 年。
机器学习可以分为四种主要技术:回归、分类、聚类和强化学习。这些技术主要以两种形式解决不同性质的问题:监督学习和非监督学习。监督学习要求在训练模型之前对数据进行标记和准备。无监督学习可以方便地处理未标记的数据或具有未知特征的数据。本文不描述 ML 的概念,也不深入描述这个领域中使用的术语。如果你是全新的,请看看我以前的文章开始你的 ML 学习之旅。
Java 中的机器学习库
这里是一个众所周知的用于 ML 的 Java 库的列表。我们将逐一描述它们,并给出使用其中一些框架的真实例子。
- Weka
- 阿帕奇看象人
- 深度学习 4j
- 木槌
- 火花 MLlib
- Encog 机器学习框架
- 金属氧化物避雷器
在每个库的旁边,下面的图标将指示每个框架中默认提供的算法的主要类别。
新西兰黑秧鸡
Weka GUI 工具包的截图。
Weka 是由新西兰怀卡托大学开发的开源图书馆。Weka 是用 Java 编写的,对于通用机器学习来说非常有名。Weka 提供了一种数据文件格式,称为 ARFF。ARFF 分为两部分:报头和实际数据。标题描述了属性及其数据类型。
阿帕奇看象人
Apache Mahout 提供了一个可扩展的机器学习库。Mahout 使用 MapReduce 范式,可用于分类、协作过滤和聚类。Mahout 利用 Apache Hadoop 处理多个并行任务。除了分类和聚类之外,Mahout 还提供了推荐算法,比如协作过滤,从而促进了快速构建模型的可伸缩性。
深度学习 4j
Deeplearning4j 是另一个专注于深度学习的 java 库。这是一个很棒的 Java 深度学习开源库。它也是用 Scala 和 Java 编写的,可以与 Hadoop 和 Spark 集成,提供高处理能力。当前的版本是测试版,但是有很好的文档和快速入门的例子(点击这里)。
木槌
Mallet 代表语言工具包的机器学习。它是少数几个用于自然语言处理的专门工具包之一。它提供了主题建模、文档分类、聚类和信息提取的能力。有了 Mallet,我们可以用 ML 模型来处理文本文档。
火花 MLlib
众所周知,Spark 可以提高处理大量数据的可伸缩性和整体性能。Spark MLlib 还拥有高性能算法,可在 Spark 上运行,并嵌入 Hadoop 工作流。
Encog 机器学习框架
Encog 是一个用于 ML 的 Java 和 C#框架。Envog 有用于构建 SVM、神经网络、贝叶斯网络、HMM 和遗传算法的库。Encog 已经开始作为一个研究项目,并得到了近 1000 个关于谷歌学术的引用。
恐鸟
海量在线分析(MOA)提供了用于分类、回归、聚类和推荐的算法。它还提供了异常检测和漂移检测的库。它是为实时处理产生的数据流而设计的。
Weka 示例:
我们将使用一个小型糖尿病数据集。我们将首先使用 Weka 加载数据:
import weka.core.Instances;
import weka.core.converters.ConverterUtils.DataSource;
public class Main {
public static void main(String[] args) throws Exception {
// Specifying the datasource
DataSource dataSource = new DataSource("data.arff");
// Loading the dataset
Instances dataInstances = dataSource.getDataSet();
// Displaying the number of instances
*log*.info("The number of loaded instances is: " + dataInstances.numInstances());
*log*.info("data:" + dataInstances.toString());
}
}
数据集中有 768 个实例。我们来看看如何得到属性(特征)的数量,应该是 9。
*log*.info("The number of attributes in the dataset: " + dataInstances.numAttributes());
在构建任何模型之前,我们希望确定哪一列是目标列,并查看在该列中找到了多少个类:
// Identifying the label index
dataInstances.setClassIndex(dataInstances.numAttributes() - 1);
// Getting the number of
*log*.info("The number of classes: " + dataInstances.numClasses());
加载数据集并确定目标属性后,现在是构建模型的时候了。我们来做一个简单的树分类器,J48。
// Creating a decision tree classifier
J48 treeClassifier = new J48();
treeClassifier.setOptions(new String[] { "-U" });
treeClassifier.buildClassifier(dataInstances);
在上面的三行中,我们指定了一个选项来指示一个未修剪的树,并为模型训练提供了数据实例。如果我们在训练后打印生成的模型的树结构,我们可以遵循模型如何在内部构建它的规则:
plas <= 127
| mass <= 26.4
| | preg <= 7: tested_negative (117.0/1.0)
| | preg > 7
| | | mass <= 0: tested_positive (2.0)
| | | mass > 0: tested_negative (13.0)
| mass > 26.4
| | age <= 28: tested_negative (180.0/22.0)
| | age > 28
| | | plas <= 99: tested_negative (55.0/10.0)
| | | plas > 99
| | | | pedi <= 0.56: tested_negative (84.0/34.0)
| | | | pedi > 0.56
| | | | | preg <= 6
| | | | | | age <= 30: tested_positive (4.0)
| | | | | | age > 30
| | | | | | | age <= 34: tested_negative (7.0/1.0)
| | | | | | | age > 34
| | | | | | | | mass <= 33.1: tested_positive (6.0)
| | | | | | | | mass > 33.1: tested_negative (4.0/1.0)
| | | | | preg > 6: tested_positive (13.0)
plas > 127
| mass <= 29.9
| | plas <= 145: tested_negative (41.0/6.0)
| | plas > 145
| | | age <= 25: tested_negative (4.0)
| | | age > 25
| | | | age <= 61
| | | | | mass <= 27.1: tested_positive (12.0/1.0)
| | | | | mass > 27.1
| | | | | | pres <= 82
| | | | | | | pedi <= 0.396: tested_positive (8.0/1.0)
| | | | | | | pedi > 0.396: tested_negative (3.0)
| | | | | | pres > 82: tested_negative (4.0)
| | | | age > 61: tested_negative (4.0)
| mass > 29.9
| | plas <= 157
| | | pres <= 61: tested_positive (15.0/1.0)
| | | pres > 61
| | | | age <= 30: tested_negative (40.0/13.0)
| | | | age > 30: tested_positive (60.0/17.0)
| | plas > 157: tested_positive (92.0/12.0)Number of Leaves : 22Size of the tree : 43
Deeplearning4j 示例:
此示例将构建一个卷积神经网络(CNN)模型来对 MNIST 图书馆进行分类。如果你不熟悉 MNIST 或者 CNN 是如何对手写数字进行分类的,我推荐你快速浏览一下我之前的帖子,它详细描述了这些方面。
像往常一样,我们将加载数据集并显示其大小。
DataSetIterator MNISTTrain = new MnistDataSetIterator(batchSize,true,seed);
DataSetIterator MNISTTest = new MnistDataSetIterator(batchSize,false,seed);
让我们仔细检查一下我们是否从数据集中获得了 10 个唯一的标签:
*log*.info("The number of total labels found in the training dataset " + MNISTTrain.totalOutcomes());
*log*.info("The number of total labels found in the test dataset " + MNISTTest.totalOutcomes());
接下来,让我们配置模型的架构。我们将使用两个卷积层加上一个输出扁平化层。Deeplearning4j 有几个选项可以用来初始化权重方案。
// Building the CNN model
MultiLayerConfiguration conf = new NeuralNetConfiguration.Builder()
.seed(seed) // random seed
.l2(0.0005) // regularization
.weightInit(WeightInit.*XAVIER*) // initialization of the weight scheme
.updater(new Adam(1e-3)) // Setting the optimization algorithm
.list()
.layer(new ConvolutionLayer.Builder(5, 5)
//Setting the stride, the kernel size, and the activation function.
.nIn(nChannels)
.stride(1,1)
.nOut(20)
.activation(Activation.*IDENTITY*)
.build())
.layer(new SubsamplingLayer.Builder(PoolingType.*MAX*) // downsampling the convolution
.kernelSize(2,2)
.stride(2,2)
.build())
.layer(new ConvolutionLayer.Builder(5, 5)
// Setting the stride, kernel size, and the activation function.
.stride(1,1)
.nOut(50)
.activation(Activation.*IDENTITY*)
.build())
.layer(new SubsamplingLayer.Builder(PoolingType.*MAX*) // downsampling the convolution
.kernelSize(2,2)
.stride(2,2)
.build())
.layer(new DenseLayer.Builder().activation(Activation.*RELU*)
.nOut(500).build())
.layer(new OutputLayer.Builder(LossFunctions.LossFunction.*NEGATIVELOGLIKELIHOOD*)
.nOut(outputNum)
.activation(Activation.*SOFTMAX*)
.build())
// the final output layer is 28x28 with a depth of 1.
.setInputType(InputType.*convolutionalFlat*(28,28,1))
.build();
架构设置好之后,我们需要初始化模式,设置训练数据集,触发模型训练。
MultiLayerNetwork model = new MultiLayerNetwork(conf);
// initialize the model weights.
model.init();
*log*.info("Step2: start training the model");
//Setting a listener every 10 iterations and evaluate on test set on every epoch
model.setListeners(new ScoreIterationListener(10), new EvaluativeListener(MNISTTest, 1, InvocationType.*EPOCH_END*));
// Training the model
model.fit(MNISTTrain, nEpochs);
在训练期间,分数收听者将提供分类准确度的混淆矩阵。让我们看看十次训练后的准确度:
=========================Confusion Matrix=========================
0 1 2 3 4 5 6 7 8 9
---------------------------------------------------
977 0 0 0 0 0 1 1 1 0 | 0 = 0
0 1131 0 1 0 1 2 0 0 0 | 1 = 1
1 2 1019 3 0 0 0 3 4 0 | 2 = 2
0 0 1 1004 0 1 0 1 3 0 | 3 = 3
0 0 0 0 977 0 2 0 1 2 | 4 = 4
1 0 0 9 0 879 1 0 1 1 | 5 = 5
4 2 0 0 1 1 949 0 1 0 | 6 = 6
0 4 2 1 1 0 0 1018 1 1 | 7 = 7
2 0 3 1 0 1 1 2 962 2 | 8 = 8
0 2 0 2 11 2 0 3 2 987 | 9 = 9
木槌示例:
如前所述,Mallet 是一个强大的自然语言建模工具包。我们将使用 Mallet 包中的工具 David Blei 提供的样本语料库。Mallet 有一个专门的库,用于为分类标注文本标记。在我们加载数据集之前,Mallet 有管道定义的概念,您定义管道,然后提供要通过的数据集。
ArrayList<Pipe> pipeList = new ArrayList<Pipe>();
管道被定义为一个“数组列表”,它包含了我们在构建主题模型之前通常要做的步骤。文档中的每个文本都将通过以下步骤:
- 小写关键字
- 标记文本
- 删除停用词
- 映射到要素
pipeList.add( new CharSequenceLowercase() );
pipeList.add( new CharSequence2TokenSequence(Pattern.*compile*("\\p{L}[\\p{L}\\p{P}]+\\p{L}")) );
// Setting the dictionary of the stop words
URL stopWordsFile = getClass().getClassLoader().getResource("stoplists/en.txt");
pipeList.add( new TokenSequenceRemoveStopwords(new File(stopWordsFile.toURI()), "UTF-8", false, false, false) );
pipeList.add( new TokenSequence2FeatureSequence() );
一旦定义了管道,我们将传递代表每个文档原始文本的实例。
InstanceList instances = new InstanceList (new SerialPipes(pipeList));
现在到了传递输入文件来填充实例列表的步骤。
URL inputFileURL = getClass().getClassLoader().getResource(inputFile);
Reader fileReader = new InputStreamReader(new FileInputStream(new File(inputFileURL.toURI())), "UTF-8");
instances.addThruPipe(new CsvIterator (fileReader, Pattern.*compile*("^(\\S*)[\\s,]*(\\S*)[\\s,]*(.*)$"),
3, 2, 1)); // data, label, name fields
从最后一个命令行中,您可以注意到我们提供了关于 CSV 文件如何构造的说明。资源文件夹中的源文件大约有 2000 行。每行代表一个原始文档文本,由逗号分隔的三个属性组成(名称、标签和文档内容)。我们可以使用以下命令打印在输入文档中找到的实例数量:
*log*.info("The number of instances found in the input file is: " + instances.size());
现在,让我们为文档的主题建模。假设我们在 2k 文档中有 100 个不同的主题。Mallet 使我们能够设置两个变量:alpha 和 beta 权重。Alpha 控制主题词分布的集中程度,beta 表示主题词分布上的前词权重。
int numTopics = 100;// defining the model
ParallelTopicModel model = new ParallelTopicModel(numTopics, 1.0, 0.01);
// adding the instances to the model
model.addInstances(instances);
我们在这个例子中选择的模型是 LDA(潜在狄利克雷分配)的实现。该算法使用一组观察到的关键词相似度来分类文档。
我喜欢 Mallet 的一点是它的 API 功能可以很容易地设计并行处理。在这里,我们可以为每个子样本定义多线程处理。
model.setNumThreads(2);
我们现在只剩下两件事,定义模型训练的迭代次数,并开始训练。
model.setNumIterations(50);
model.estimate();
关于如何在 github 上的完整示例中显示主题建模结果,我留下了更多的细节。
进一步阅读
- 【书】:botjan kalu la 著,O'Reilly 出版的 Java 中的机器学习。
- 【书籍】:机器学习:Java 开发者端到端指南,作者:Richard M. Reese,Jennifer L. Reese,Bostjan Kaluza,Uday Kamath 博士,Krishna Choppella。
- 【教程】 Spark MLlib 示例。
- 【教程】 用木槌进行机器学习。
本帖中提供的所有例子都可以在my Githubreprasority 上找到。
朱莉娅的机器学习
原文:https://towardsdatascience.com/machine-learning-in-julia-5bca700e0348?source=collection_archive---------2-----------------------
Julia 中机器学习入门的完整指南
由凯文·Ku在 Unsplash 上拍摄的照片
朱莉娅是什么?
Julia 是一种相对较新的编程语言,它在机器学习领域越来越受欢迎。随着它变得越来越受欢迎,我想写这篇文章来深入概述为什么以及如何在 Julia 中开始机器学习。
由茱莉亚项目—https://julialang.org,公共领域,https://commons.wikimedia.org/w/index.php?curid=87405047
为什么要用 Julia 做机器学习?
速度和编译
Julia 相对于其他机器学习语言的主要优势是速度。Julia 的速度优势有两个主要原因,首先,它是一种编译语言。其次,它是为并行性而设计的。
类似脚本的语法
尽管有速度优势,但 Julia 的语法并不是很复杂。它感觉更像一种脚本语言,从 Python 或 R 背景转换到 Julia 相对容易。
社区、开发和图书馆
朱莉娅越来越受欢迎,也越来越成熟。随着这种增长,社区也在增长。尽管仍然远远小于 Python 社区,但看到社区和可用库数量的增长是一个好迹象。
在 Jupyter 笔记本上运行 Julia
Julia 的另一个优点是,它可以在 Jupyter 笔记本上运行。而且非常容易安装!以下是将 Julia 安装到 Jupyter 笔记本的方法:
- 从他们的网站下载并安装 Julia
- 打开 Julia 命令行
- 运行命令
using Pkg
- 运行命令
Pkg.add("IJulia")
- 启动一个 Jupiter 笔记本,你可以在笔记本的右上角选择 Julia(参见图片)
Julia 中虹膜数据集的数据准备
在进入真正的机器学习部分之前,需要把数据导入并准备好。这里我将只介绍三个基本步骤:导入一个 csv 文件,对一个分类变量进行热编码,以及进行训练测试分割。
数据准备 1 —在 Julia 中导入 CSV 文件
在 Julia 中入门的第一步是导入数据。在这种情况下,我们使用一个包含虹膜数据的 csv 文件。要将 csv 文件作为数据框导入,您需要添加如下所示的“CSV”和“DataFrames”库。然后,您使用“CSV。File”函数读取 csv 文件,DataFrame 函数将其转换为数据帧。
数据准备 2-一个热编码因变量(品种)
对于某些模型,您将需要一个分类变量的热编码。为此,您可以使用“车床”库。它具有 OneHotEncode 函数,可将数据帧转换为 OneHotEncode 数据帧。之后,您可以使用“选择”功能删除原始列。
数据准备 3-列车测试分离
对于模型评估,您将需要一个训练测试分割。下面的代码使用库“Random”来实现这一点。基本上,它会选择一个随机的索引子集,并将它们视为训练集,而未选择的索引将作为测试集:
朱莉娅的机器学习
Julia 中用于机器学习的资源仍然相对分布在不同的包中。Julia 还不像其他机器学习编程语言那样受欢迎,有时要找到特定的模型可能需要一些工作。寻找(或编写)在 Python 和 r 中容易获得的某些基本数据准备函数也可能需要更多的努力。
好消息是,有人倡议在更大的图书馆中重组机器学习模型。在这一点上,有两个库正在激烈竞争成为 Julia 的首选机器学习库:MLJ 和 Scikit Learn。
这两项倡议是伟大的,但它们尚未完全完成。因此,对于某些模型,它们只是向其他更小的机器学习库提供包装器。正因为如此,我发现涵盖其中两个较小的库也很重要:用于广义线性模型的“GLM”和用于许多基于树的模型的“决策树”。我将从较小的库开始,以较大的项目结束。
Julia 使用 GLM 图书馆的逻辑回归
以下示例使用 GLM 库对 Iris 数据拟合三个逻辑回归模型。GLM 使用“公式”接口,这在面向统计的库中很常见。我们可以指定一个族(在这种情况下为二项式)和一个链接类型(在这种情况下为 Logit 链接),以便创建所需的 GLM 类型。这是在下面代码片段的第一部分完成的。
在该片段的最后,三个模型的预测水平连接,以便为一对所有多类分类的应用做准备。
以下是打印出来的串联预测概率(这是“preds”变量中的内容):
在下面的代码片段中,我们将每行的三个预测概率转换为每行一个类别预测。该决定基于三个预测概率中的每一个之间的最高预测概率:
这是重新分类的“preds_cat”数组的外观:
作为最后一步,下面是如何使用一个简短的 for-loop 来计算我们在测试集上的 GLM 预测的准确性:
Julia 中的决策树使用 DecisionTree.jl 库
在下面的代码片段中,您将看到如何在 Julia 中构建决策树。首先,它重新导入 Iris 数据,因为决策树支持使用分类变量。如介绍中所述,这是使用 Julia 的一个优势。
然后,该模型被创建为决策树分类器的实例。我们可以给出几个超参数,例如本例中使用的 max_depth。感叹号的 fit 语法非常特殊。
最后两步是使用 predict 函数对测试集进行预测,并计算准确性,与前面的模型一样。
Julia 中的随机森林使用 DecisionTree.jl 库
正如您将看到的,随机森林模型的应用方式几乎与决策树相同。一开始可能会比较混乱,但是随机森林模型也是决策树库的一部分!
Julia 中机器学习的主要包
现在我们已经看到了如何在 Julia 中使用两个很大但很小的库来进行机器学习,让我们来看看更大的库。如前所述,有两个主要的软件包在竞争成为 Julia 的首选 ML 库:Scikit Learn 和 MLJ。我们去查查他们俩。
Julia 中用于机器学习 Scikit Learn
很多人都知道 Scikit 是从 Python 中学习的。它是 Python 中用于机器学习的包,在 Julia 中拥有它也很棒。如果我们能使用和 Python 一样的语法,那就简单多了!
让我们看一个在 Julia 中学习 Scikit 的例子。这个代码片段从导入 Scikit 学习库开始。下一步是加载您想要使用的模型(在这种情况下是逻辑回归)。使用“适合!”语法(注意感叹号),模型训练好了。
之后,使用预测函数用训练好的模型预测测试集。最后,计算精度。
在 Julia 中使用 Scikit Learn 也有它的缺点。例如,我们可以在 Julia 中使用的 Scikit Learn 库的很大一部分实际上只是 Python 的包装。除了一些已经在 Julia 中实现的模型,Julia 模型实际上使用 Pycall 来调用 Python 代码。
但是,如果我们想换成朱丽亚,应该是为了拥有朱丽亚的好处。Julia 的一个主要优势是相对于 Python 的速度优势,调用 Python 代码真的不是我们应该在这里做的。如果只是一个 Python 包装器,我们还不如直接用 Python 学习 Scikit。
另一个缺点是 Scikit Learn 中的 Python 模型不支持分类变量。除了对它们进行编码之外,在 Scikit Learn 中真的没有什么可以做的,这确实是一个缺点(特别是对于基于树的模型)。正如您在整个例子中看到的,Julia 允许我们将分类变量视为一个变量,而不是一组热编码的虚拟变量。所以当我们把 Julia 仅仅作为 Python 包装器时,Julia 的优势也将消失。
茱莉亚的机器学习 MLJ
Julia 中机器学习的一个竞争对手是 MLJ 包。它承诺解决分类变量的问题,它是纯粹的-朱莉娅。这使得探索变得非常有趣。它还得到了艾伦图灵基金会的大力支持,这让我相信这个图书馆会一直存在下去。
现在,让我们在下面的代码片段中看看机器学习中 MLJ 的例子。有几件事和平常不一样。特别是,创建机器是一种语法选择,对许多人来说是新的。更不寻常的是必须加载一个模型,而不是导入一个包。
但是在这些语法差异之后,MLJ 库的使用并没有本质上的不同。MLJ 语法很容易学习,在 MLJ 的文档网站上有很好的文档。
结论
在这篇文章中,我们看到了 Julia 中的四个机器学习库。其中两个库(MLJ 和 Scikit Learn)似乎是接管 Julia 机器学习领域的真正竞争对手。
Scikit Learn 拥有 Python 实现中熟悉的语法的巨大优势,并获得了社区的信任。另一方面,Scikit Learn 通常只是简单地调用 Python 代码,这首先就剥夺了使用 Julia 的大部分优势。
作为一个真正的朱莉娅项目,MLJ 有很大的优势。它的语法有点新,但是差别似乎很小。对 MLJ 来说,真正的挑战是赢得更大社区的信任和欢迎。
我希望这篇文章已经给了你开始使用 Julia 所需要的一切,我祝你好运!
朱莉娅的机器学习终于有所进步
原文:https://towardsdatascience.com/machine-learning-in-julia-is-finally-getting-better-ab5cac68015b?source=collection_archive---------14-----------------------
最近的软件包开发使数据处理变得切实可行。
(src = julia-lang.org)
自从我第一次开始使用 Julia,我和其他许多来自 Python 和 R 等具有强大生态系统的语言的叛逃者都有一个问题,那就是数据处理。在 Julia 中,数据处理似乎被忽视了,通常用单独的包来解决一个问题,而有些问题则被完全忽略了。有时已经有可用的函数,但是它们非常难以使用,要求您在通过任何预处理算法之前断言类型并转换数据。由于这个原因,不仅训练一个模型很困难,而且将一个模型放入一个管道并部署它也是完全不可能的。
然而,随着 Julia 开发人员所取得的超前和令人兴奋的进步,预处理已经比我原先想象的可能发展得更远。因此,Julia 已经成为机器学习的一个更可行的选择。随着对 Genie 及其相应文档的大量添加,部署 API 已经成为一种
蛋糕漫步。
Genie 为您管理所有的虚拟环境,现在文档已经发布,并由出色的开发人员 Essenciary (Adrian Salceanu)不断改进,使 Julia 更适合作为日常 web 框架使用。
(src = http://genieframework.com)
PyCall
这可能令人惊讶,但 Julia 目前面临的最大挑战之一是 PyCall.jl。这是因为就其现状而言,太多的包依赖于它,反过来又依赖于 Python。虽然我完全理解,Python 的生态系统要比 Julia 的生态系统大得多,但反过来,Julia 失去了所有获得的速度,使用 PyCall 甚至比使用 Python 本身还慢,
那为什么还要用朱莉娅呢?
训练-测试-拆分
训练-测试-分割是一个基本的工具,对于机器学习的任何延伸都是完全需要的。为了验证一个算法,你必须首先有一个训练集和一个测试集,有些人甚至选择了一个验证集。参考这个线程,
[## 用于训练测试拆分简单工具
我暗暗希望这个问题至少在一周内不要出现,直到我找到时间写文档…
discourse.julialang.org](https://discourse.julialang.org/t/simple-tool-for-train-test-split/473)
关于 Julia 的论述,我认为很明显,数据帧的测试序列分割在某种程度上被忽略了。MLDataUtils 可能是大多数人用于训练-测试-分割的包,相信我的话:
它当然可以更好。
幸运的是,几个月来,已经有更好的从模块车床。
using Lathe.preprocess: TrainTestSplit
train, test = TrainTestSplit(df)
我们甚至可以调整我们的分割百分比,就像这样:
train, test = TrainTestSplit(df,0.5)
这将为我们的测试和训练集把数据分成两半。
特征缩放
我认为在 Julia 模块中最常见的是 SkLearn 形式。我不认为我们应该从一个完全独立的语言中,在一个完全独立的范例中,接受或强制这种构造。一个很好的例子是 Julia 中的特征标量。大多数(如果不是全部)特征标量符合 SkLearn 的写作风格,该风格自 2010 年以来一直定义 Python 机器学习模块。但是 SkLearn 的标量如此表现的原因只有一个,那就是 SkLearn 的奇妙管道。
在 Julia 中,我们没有类,反过来我们也不能让方法成为一个对象的子对象。取而代之的是,我们有一些结构,它们可以采用一个方法来对该结构保存的数据执行一个操作。此外,Julia 必须提供的唯一管道是语法管道——这很好,但肯定消除了与 SkLearn 一致的点,因为它们不使用相同的方法。为了正确理解这一点,以下是标准标量(Z 分数规格化器)的公式:
有了这样一个简单的公式,fit 只需要计算样本均值和标准差。以 Julia 的速度,这些计算当然可以在微秒内完成,就像在 Python 中一样。无论如何,这都不是一个困难的计算,只需一个简洁的 for 循环和另外两行代码就可以完成。幸运的是,车床用一种简单的方法再次罢工,采取任何数组:
using Lathe.preprocess: StandardScalar
scaledX = StandardScalar(trainX)
很简单,对吧?
除了标准标量之外,Lathe 还附带了大量其他标量,将来还计划实现一个单位长度标量。到目前为止,用?()方法将显示所有可用的标量:
- 重新标度
- 任意重新标度
- 均值归一化
分类编码器
分类编码器是 Julia 生态系统中另一个极度缺乏的领域。只有一个编码器可用,通常通过 Flux 使用,称为 one hot 编码器。为了让你了解复杂的 Flux 的 one hot encoder 有多无聊,你可以看看这里的源代码:
[## FluxML/Flux.jl
放松点。Flux 是不会让你 tensor - FluxML/Flux.jl 的 ML 库
github.com](https://github.com/FluxML/Flux.jl/blob/master/src/onehot.jl)
该文件中的代码总共有 130 行,在我看来,这个大小根本没有必要。要使用车床的 one hot 编码器,我们只需调用方法“OneHotEncode”:
using Lathe.preprocess: OneHotEncode
encoded_df = OneHotEncode(df,:columnname)
下面是计算它的代码,总共只有 7 行:
管道
ipelines 对于 SkLearn 和机器学习整体来说是一个非常重要的特性。Julia 严重缺乏使用管道的真正好的库。Julia 中的大多数管道不采用构造模型,也不允许任何简单的序列化读写。然而,对于车床,实际上存在使用与车床模型的其余部分相同的预测函数的管道,并且允许一组可迭代的步骤以及用于预测的模型。如果你想阅读一个完整的,虽然过时的车床管道教程,你可以在这里查看:
[## 在 Julia 中用车床 0.0.7 构建管道(不稳定)
数据科学的很大一部分是数据科学的一个子集,称为数据工程。数据工程(DE)包括…
towardsdatascience.com](/building-pipelines-with-lathe-0-0-7-unstable-in-julia-f7ba1850bde3)
此外,对于有价值的文档,您可以简单地使用?()方法在车床.模型.管道上
结论
我相信很多 Julia 模块都有很多不尽人意的地方。一些不提供任何数据帧兼容性,而另一些通过使简单的算法变得过于复杂而制造了更多的问题。Julia 语言非常灵活,这不仅在笔记本中对我们有利,在模块中也是如此。我认为,正是因为这个原因,Julia 的生态系统让很多新人对这门语言望而却步,这让我很沮丧。事实是,就包而言,现在 Python 轻而易举地做得更好。我认为这很容易改变,展望未来,我对朱莉娅的生态系统,包括车床的未来感到非常兴奋!
Max 中的机器学习:分类
原文:https://towardsdatascience.com/machine-learning-in-max-classification-fb8b2bdb3933?source=collection_archive---------54-----------------------
如何使用 ml.lib 包在 Max 中执行简单机器学习任务的分步指南。
机器学习已经成为一个热门话题有一段时间了,像“人工智能”、“神经网络”和“深度学习”这样的词在任何地方都被用来描述项目的前沿性质和系统的所谓的智能。这些词的误用并不能抹杀这样一个事实,即机器学习可以成为在我们的系统中实现的一个非常有趣和强大的工具。在这篇文章中,我将概述如何通过 ml.lib 包在 Max 环境中使用机器学习分类算法。我将使用这篇文章的循序渐进的性质来描述和探索机器学习和分析算法的一些基本方面,而不会太专业!最后,尽管本教程将使用 Max 和从 Max 包管理器中获得的 ml.lib 包,但在从 Deken 包管理器中安装 ml.lib 的纯数据上可以遵循相同的步骤。
ml.lib
ml.lib 启动窗口:提供的所有类型的机器学习算法的概述。
ml.lib 或机器学习库是一个 Max 包,它在 Max 环境中提供了许多机器学习算法。所提供的算法属于不同的类别,即:特征提取、分类、回归和时间序列分类。在这篇文章中,我将把重点放在分类算法上,但是本文中包含的大部分知识也可以应用于大多数其他 ml.lib 对象。
分类
分类算法是称为监督学习的机器学习分支的一部分。监督学习与无监督学习的不同之处在于,它是基于基础事实的。换句话说,在监督学习算法中,我们使用带标签的数据集来训练我们的机器学习算法,给定数据样本和期望的输出,我们要求算法近似输入和输出之间的关系( David Soni 有一篇很棒的文章详细介绍了监督学习和非监督学习之间的差异,如果你对这个主题感兴趣,应该去看看)。这些算法可能是最容易理解和使用的,这就是为什么我们要把它们作为我们机器学习之旅的起点。
ml.lib 为我们提供了 7 种不同的分类算法,每种算法都有自己的优缺点。然而,在本文中,我们将只关注 ml.svm 的使用,原因有二:
- 支持向量机(SVM)算法是一个标准的和众所周知的算法,学习它的优点和缺点可能在其他环境中派上用场。
- 由于 ml.lib 的工作方式,所有分类算法都以完全相同的方式工作,并接受相同的数据。因此,通过学习如何使用一个,我们不仅能够使用它们,而且一旦我们创建了模型,我们还能够交换对象,以查看一个是否比另一个执行得更好。
事不宜迟,我们走吧。
入门指南
ml.svm.maxhelp 文件概述以及 ml.lib 附带的分类示例。
虽然 ml.lib 附带了一些帮助文件和一组示例,但是密集的补丁可能会吓到您。因此,本教程将从头开始,一步一步地构建一个最小的示例。
添加、训练、地图
除了时序分类对象,几乎所有的 ml.lib 对象都遵循相同的三个原则:添加、训练、映射。这些对象要求用户(1)添加一些数据,然后用作(2)训练数据,以便能够(3)将新的输入数据映射到预测的输出。
增加
正如我们之前在简介中提到的,ml.svm 是一种分类算法,属于监督学习类别。这意味着对象将期望添加的数据被标记。让我们看看这在 Max 中是什么样子的。
携带属于类别 1 的大小为 3 的特征向量的 add 消息的剖析。
需要传递给 ml 对象的 add 消息需要包含三个元素:
- 附加字,指定了我们要传递的信息的种类,
- 类别号,也就是我们给被传递数据的标签,
- 我们希望机器学习对象将其作为输入并在训练阶段使用以从数据中学习的特征向量或特征列表。
就是这样,这是为了将你的数据添加到 ml 对象中你唯一需要知道的事情。然而,考虑到解释的抽象性,让我们看一个实际的例子,看看这些概念是如何在补丁中转移的。
一个简单的 3 类场景的展示:3 个多滑块设置在 3 个不同的位置,三个 add 消息携带滑块的值,并分别将它们分配给类 1、2 和 3,并全部输入 ml.svm 对象。
在这个实际例子中,我们可以看到几乎什么都没有改变。我们向 svm 对象提供 3 条添加消息,每条消息都有不同的类。这些添加消息包含长度为 3 的特征向量,该向量表示与其连接的滑块的 3 个值。在类 1 中,所有滑块都接近其最大值,在类 2 中,它们被放置在 0 值附近,在类 3 中,它们都接近其最小值。这个小例子设置了一个场景,我们的 ml 对象将能够识别三个滑块的位置。
火车
现在我们已经将数据添加到 ml 对象中,我们需要训练它。训练是为 ml 对象(在我们的例子中是 ml.svm)提供学习和生成模型所需的数据的行为。模型是作为训练过程的结果而产生的人工制品,并且将负责输入数据的预测。
考虑到我们已经在“添加”阶段添加了数据,我们只需要训练模型。为此,向模型传递一条带有“train”一词的消息,等待一段时间(取决于添加的数据量)然后瞧!你的模特已经训练好了,准备好了。
地图
现在我们的模型已经准备好了,我们可以通过使用“map”消息来测试它。
携带大小为 3 的特征向量的地图消息的剖析。
map 消息的结构类似于没有类别号的 add 消息。这是因为该类将是 ml 对象在接收到一些输入数据后所要预测的对象。因此,在添加和训练了具有长度为 3 的特征向量的 ml 对象之后,通过 map 消息作为输入传递的任何长度为 3 的特征向量都将被分析,并且类别将被预测。让我们使用上面的滑块例子来看看这在实践中是如何工作的。
把所有的放在一起
从开始到结束:添加,训练和映射和 ml.svm 对象。
从上面的 gif 可以看出,这三个步骤正是本文所概述的:添加、训练、映射。一旦创建了模型,通过地图消息输入到 ml 对象中的 3 个滑块的任何位置都将被分析,并且预测的类将被输出。
与简单的查找表不同,这将使您能够预测原始添加数据中没有的滑块位置的类别。如果滑块没有对齐怎么办?机器学习算法将近似并提供给你一个类别预测。
虽然这不一定是最令人印象深刻的机器学习示例,但它展示了 Max 用户在他们的补丁中实现机器学习算法是多么容易。
最后一点
考虑到这个复杂的主题,试图让本教程尽可能简单是一个艰难的挑战。出于这个原因,我有目的地在文章的结尾留下了一些次要但重要的东西,以便感兴趣的读者能够获得开始玩机器学习所需的所有信息。
使您的模型更加健壮
正如你在最终的 gif 中所看到的,我为每一个类提供了带有许多稍微不同的滑块位置的添加消息。我可以简单地将第一类的所有滑块设置为最大,将第二类的所有滑块设置为中间,将第三类的所有滑块设置为最小,但是我决定提供数据中有一点“噪声”的多个示例。我们不需要深入 ml 概念来理解:
我们提供给 ml 对象的数据越少,生成的模型就越难正确预测类。
出于这个原因,提供多个彼此稍有不同的类的例子总是好的,允许 ml 对象从同一个类的多个实例中学习。然而,注意不要给你的 ml 对象太多的数据,因为这可能导致无限的训练时间和糟糕的结果。关键是提供大量的好数据。
清除、写入和读取
有一些重要的信息值得一提,尽管它们没有出现在文章的主要部分。清除允许您清除模型中的数据。无论你是搞砸了一条添加信息,还是只想重新开始,这都是你想要记住的信息。
相反,写和读允许您保存和加载您创建的数据和模型。保存和加载数据将使您避免将所有的类重新添加到 ml 对象中,但是更重要的是,保存预先训练的模型将使您避免训练阶段。这对于需要一段时间训练的大型数据集非常有用。
把一个模型换成另一个
正如本文开头提到的,ml.lib 捆绑的所有分类算法都以完全相同的方式工作。这意味着,如果您最初选择的算法没有您想象的那么好,您可以保存您已经添加的数据,并将其替换为同一类别中的任何其他算法(即任何其他分类算法)。一旦新算法到位,你需要做的就是读取之前保存的数据,重新训练模型。
最后但同样重要的是…
如果您想要复制上面显示的示例 patch,请记住从“检查器”标签中启用您的多滑块上的“鼠标移动时连续数据输出”。
修补愉快!
医学中的机器学习:学会信任
原文:https://towardsdatascience.com/machine-learning-in-medicine-learning-to-trust-dba42e883b71?source=collection_archive---------67-----------------------
Pexels
机器学习正迅速在医疗保健行业的许多方面发挥主导作用,从诊断到治疗,甚至是人口层面的流行病学。直到最近,医学还是由自学和经验推动的。然而,随着数据库规模的增长和人工智能实施变得更加强大,在医学和医疗保健领域应用机器学习的好处正变得越来越为人所知。
医疗管道的几乎每个方面都受到了 ML 平台涌入的影响。经历显著增长的三个领域是皮肤病诊断、人群水平的疾病爆发预测和种族差异的改善。
Pexels
作为医学诊断工具的 ML 算法
机器学习在医学中的第一个应用是用于诊断皮肤肿瘤的图像分析。发表于 2019 年,该研究使用了一组由专家医生人工标记的超过 10,000 张图像来训练算法。在某些情况下,训练有素的算法甚至可以以比当前执业医生更高的准确率诊断皮肤癌病变。
在这项研究中专门测试的前三种算法能够区分七种预定义的疾病,包括基底细胞癌,一种常见的皮肤癌。然而,重要的是要注意,分类器对于分布外图像的性能有所下降,并且仍然需要有经验的医生的专业知识。然而,随着标记数据集在更广泛的疾病中变得更加可用,在这些边缘情况下,人和机器之间的当前差异可能会减少。
有趣的是,尽管许多诊所没有在诊断中积极使用机器学习预测算法,但 ML 的原则仍被引入医学院课程。一种特殊类型的皮肤病称为色素性光化性角化病,其特征是鳞状斑块。这是算法比训练有素的医生更擅长诊断的疾病之一,事实证明,算法比平时更关注瑕疵周围的皮肤,而不是瑕疵本身。
在指导学生在他们自己的诊断程序中关注相似的区域后,准确率提高了三分之一以上。这个例子和其他例子展示了医生和 ML 平台如何能够一起优化诊断。
Pexels
人口水平的疫情预测
ML 在医疗保健中的另一个日益增长的应用是监控人群水平的健康,特别是用于跟踪和预测疫情和流行病。这可以从最近世界各地公共卫生部门部署的众多新冠肺炎预测模型中看出。
这些模型既有回顾性的作用,也有前瞻性的作用。利用过去的数据,这些模型可以帮助研究人员了解疾病的起源(通常被称为零号病人),以及它是如何在人与人之间传播的。然后,它可以帮助预测疾病将如何继续传播,以及哪些人群最容易受到感染。在群体水平上,这些问题的复杂性和所涉及的变量的数量使得没有 ML 的帮助很难完成。
然而,早在新冠肺炎疫情爆发之前,用于人口层面健康监测的机器学习就已投入使用。神经网络已经被用于预测寨卡的传播,以协助政府有效分配监控资源。对于这个特定的模型,疾病地理扩张的准确性超过 85%,即使有 12 周的扩展预测窗口。
甚至早在 2016 年,机器学习就被用来预测印度的疟疾疫情。支持向量机和神经网络允许研究人员纳入天气、相关案例和社会经济数据等广泛的参数,以提前 20 天预测传播。
机器学习在医学中对抗种族差异的应用
在公共卫生领域,一个越来越重要的考虑因素是卫生保健资源对所有人群的可用性。最近,华盛顿特区乔治华盛顿大学的米尔肯公共卫生学院开始开发一个机器学习管道来理解和预测医疗保健中普遍存在的种族差异。
不幸的是,在护理方面存在许多差距,这意味着某些种族或社会经济背景的人得不到同等水平或可用性的护理。例如,临床试验通常排除某些种族、性别或社会经济群体,这意味着结果并不像预期的那样广泛适用。因此,这个新研究小组的目标是探索这些健康的社会决定因素,并确定哪些环境因素影响健康风险和结果。这将有助于回答持续的研究问题,如为什么美国黑人更容易患癌症等慢性病。
然而,这个项目的最大障碍是缺乏正确标记和组织的数据。例如,大型国家数据库缺少关于患者种族的信息,这被认为是差异的一个重要指标。
无论如何,研究小组的第一个目标是了解与全关节置换术相关的死亡率,这是美国最常见的外科手术之一。这种方法是骨质疏松症的一种常见治疗方法,预计在未来几年需求将会增长。如果成功,该模型可以扩展到其他常见的程序,以预测种族和社会经济因素对结果的影响。
Pexels
在医学中应用机器学习的危险和弱点
很明显,ML 在医疗保健中扮演着越来越重要的角色。但是,在引入这项技术时,仍然需要记住一些复杂的问题。首先,当然是医疗数据的隐私。根据健康保险流通与责任法案(HIPAA ),对于什么样的健康数据可以共享以及数据的匿名程度有严格的指导原则。这可能会限制研究的应用范围。
对算法的过度依赖也应该被阻止,特别是当它们仍然容易出错的时候。例如,在一个为预测皮肤癌而开发的初步算法中,输入训练数据集的不正确甚至恶意操作被证明会导致完全误诊。不幸的是,这可能被用于欺诈利益,因此医疗团队和患者必须注意这种危险。
然而,为了应对这些风险,一些算法正在建立一个制衡系统,以尊重人类专家的意见。事实上,在某些情况下,人类-人工智能混合诊断工具的性能比单独使用任何一种工具都要好。很明显,医疗保健的未来取决于训练有素的人类专家和经验与机器学习算法的预测能力的集成。
这个故事最初发表在 Lionbridge.ai,你可以在这里 阅读故事原文,了解更多关于 Lionbridge 。
使用 PyCaret 实现 Power BI 中的机器学习
原文:https://towardsdatascience.com/machine-learning-in-power-bi-using-pycaret-34307f09394a?source=collection_archive---------2-----------------------
几分钟内在 Power BI 中实现机器学习的分步教程
机器学习遇上商业智能
PyCaret 1.0.0
上周我们宣布了 PyCaret ,这是一个用 Python 编写的开源机器学习库,它在低代码环境中训练和部署机器学习模型。在我们之前的帖子中,我们演示了如何在 Jupyter Notebook 中使用 PyCaret 来训练和部署 Python 中的机器学习模型。
在本帖中,我们展示了一个关于如何将 PyCaret 集成到 Power BI 中的逐步教程,从而允许分析师和数据科学家在他们的仪表板和报告中添加一层机器学习,而无需任何额外的许可或软件成本。PyCaret 是一个开源的免费使用的 Python 库,它提供了一系列专门为 Power BI 构建的函数。
在本文结束时,您将了解如何在 Power BI 中实现以下内容:
- 聚类 —对具有相似特征的数据点进行分组。
- 异常检测 —识别数据中罕见的观察值/异常值。
- 自然语言处理 —通过主题建模分析文本数据。
- 关联规则挖掘 —在数据中发现有趣的关系。
- 分类 —预测二进制(1 或 0)的分类类标签。
- 回归 —预测连续值,如销售额、价格等
“PyCaret 通过为业务分析师、领域专家、公民数据科学家和经验丰富的数据科学家提供免费、开源和低代码的机器学习解决方案,使机器学习和高级分析的使用民主化”。
Microsoft Power BI
Power BI 是一种业务分析解决方案,可让您在整个组织中可视化数据和共享见解,或将它们嵌入到您的应用程序或网站中。在本教程中,我们将通过将 PyCaret 库导入 Power BI 来使用 Power BI 桌面进行机器学习。
开始之前
如果您以前使用过 Python,很可能您的计算机上已经安装了 Anaconda 发行版。如果没有,单击此处下载 Python 3.7 或更高版本的 Anaconda 发行版。
https://www.anaconda.com/distribution/
设置环境
在我们开始在 Power BI 中使用 PyCaret 的机器学习功能之前,我们必须创建一个虚拟环境并安装 pycaret。这是一个三步走的过程:
✅ 步骤 1——创建一个蟒蛇环境
从开始菜单打开 Anaconda 提示符并运行以下代码:
conda create --name **myenv** python=3.6
Anaconda 提示符—创建环境
✅ 步骤 2 —安装 PyCaret
在 Anaconda 提示符下运行以下代码:
conda activate **myenv**
pip install pycaret
安装可能需要 10-15 分钟。
✅t16】第三步——在 Power BI 中设置 Python 目录
创建的虚拟环境必须与 Power BI 链接。这可以使用 Power BI Desktop 中的全局设置来完成(文件→选项→全局→ Python 脚本)。默认情况下,Anaconda 环境安装在以下位置:
C:\Users\ 用户名\ AppData \ Local \ Continuum \ anaconda 3 \ envs \ myenv
文件→选项→全局→ Python 脚本
📘示例 Power BI 中的集群
聚类是一种机器学习技术,它将具有相似特征的数据点分组。这些分组对于探索数据、识别模式和分析数据子集非常有用。集群的一些常见业务用例有:
以营销为目的的✔客户细分。
促销和折扣的✔顾客购买行为分析。
✔在诸如新冠肺炎的流行病爆发中识别地理群集。
在本教程中,我们将使用 PyCaret 的 github 资源库中的' jewellery . CSV’文件。您可以使用 web 连接器加载数据。(Power BI 桌面→获取数据→来自 Web)。
链接到 csv 文件:https://raw . githubusercontent . com/py caret/py caret/master/datasets/jewellery . CSV
Power BI 桌面→获取数据→其他→ Web
来自 jewellery.csv 的样本数据点
K-均值聚类
为了训练聚类模型,我们将在 Power Query Editor 中执行 Python 脚本(Power Query Editor→Transform→Run Python script)。
超级查询编辑器中的功能区
将以下代码作为 Python 脚本运行:
from **pycaret.clustering** import *****
dataset = **get_clusters**(data = dataset)
超级查询编辑器(转换→运行 python 脚本)
输出:
聚类结果(代码执行后)
最终输出(点击表格后)
包含标签的新列‘集群’被附加到原始表格。
一旦您应用了查询(Power Query Editor→Home→Close & Apply),以下是您如何在 Power BI 中可视化集群:
默认情况下,PyCaret 训练一个具有 4 个聚类的 K-Means 聚类模型(即表中的所有数据点都被分为 4 组)。默认值可以很容易地更改:
- 要更改聚类数,您可以使用 get_clusters( ) 函数中的num _ clusters参数。
- 要更改模型类型,使用 get_clusters( ) 内的 模型 参数。
请参见下面的示例代码,该代码用于训练具有 6 个群集的 K-Modes 模型:
*from **pycaret.clustering** import *
dataset = **get_clusters**(dataset, model = 'kmodes', num_clusters = 6)*
PyCaret 中有 9 种现成可用的聚类算法:
训练一个聚类模型所需的所有预处理任务,如缺失值插补(如果表中有任何缺失值或空值),或归一化,或一次热编码,都是在训练一个聚类模型之前自动执行的。单击此处了解更多关于 PyCaret 预处理功能的信息。
💡在这个例子中,我们使用了 get_clusters( ) 函数来分配原始表中的分类标签。每次刷新查询时,都会重新计算分类。实现这一点的另一种方法是使用 predict_model( ) 函数,使用 Python 或 Power BI 中的预训练模型来预测聚类标签(参见下面的示例 5,以了解如何在 Power BI 环境中训练机器学习模型)。
💡如果你想学习如何使用 Jupyter 笔记本在 Python 中训练一个聚类模型,请参见我们的聚类 101 初学者教程。(不需要编码背景)。**
📘示例 2 —电力 BI 中的异常检测
异常检测是一种机器学习技术,用于通过检查表中与大多数行明显不同的行来识别稀有项目、事件、、或观察值。通常,异常项目会转化为某种问题,如银行欺诈、结构缺陷、医疗问题或错误。异常检测的一些常见业务用例有:
✔欺诈检测(信用卡、保险等。)使用财务数据。
✔入侵检测(系统安全、恶意软件)或监控网络流量的起伏。
✔识别数据集中的多元异常值。
在本教程中,我们将使用 PyCaret 的 github 资源库中的anomaly . CSV’文件。您可以使用 web 连接器加载数据。(Power BI 桌面→获取数据→来自 Web)。
链接到 csv 文件:https://raw . githubusercontent . com/py caret/py caret/master/datasets/anomaly . CSV
来自 anomaly.csv 的样本数据点
k 近邻异常检测器
与聚类类似,我们将从 Power Query Editor 运行 python 脚本(转换→运行 Python 脚本)来训练异常检测模型。将以下代码作为 Python 脚本运行:
*from **pycaret.anomaly** import *****
dataset = **get_outliers**(data = dataset)*
超级查询编辑器(转换→运行 python 脚本)
输出:
异常检测结果(代码执行后)
最终输出(点击表格后)
两个新列附加到原始表。标签(1 =异常值,0 =内部值)和分数(具有高分数的数据点被归类为异常值)。
应用查询后,以下是如何在 Power BI 中可视化异常检测的结果:
默认情况下,PyCaret 用 5%的分数训练一个K-最近邻异常检测器(即表中总行数的 5%将被标记为异常值)。默认值可以很容易地更改:
- 要更改分数值,您可以使用 get_outliers( ) 函数中的 分数 参数。
- 要更改模型类型,使用 get_outliers( ) 内的 模型 参数。
请参见以下代码,用于训练分数为 0.1 的隔离林模型:
*from **pycaret.anomaly** import *
dataset = **get_outliers**(dataset, model = 'iforest', fraction = 0.1)*
PyCaret 中有超过 10 种现成的异常检测算法:
训练异常检测模型所需的所有预处理任务,例如缺失值插补(如果表中有任何缺失值或空值),或归一化,或一热编码,它们都在训练异常检测模型之前自动执行。单击此处了解更多关于 PyCaret 预处理功能的信息。
💡在本例中,我们使用了 get_outliers( ) 函数来分配离群值标签和分数以进行分析。每次刷新查询时,都会重新计算离群值。实现这一点的另一种方法是使用 predict_model( ) 函数,使用 Python 或 Power BI 中预训练的模型来预测异常值(参见下面的示例 5,了解如何在 Power BI 环境中训练机器学习模型)。
💡如果你想学习如何使用 Jupyter 笔记本在 Python 中训练一个异常检测器,请参见我们的异常检测 101 初学者教程。(不需要编码背景)。**
📘示例 3 —自然语言处理
有几种技术被用来分析文本数据,其中主题建模是一种流行的技术。主题模型是一种用于在文档集合中发现抽象主题的统计模型。主题建模是一种常用的文本挖掘工具,用于发现文本数据中隐藏的语义结构。
在本教程中,我们将使用 PyCaret 的 github 资源库中的‘kiva . CSV’文件。您可以使用 web 连接器加载数据。(Power BI 桌面→获取数据→来自 Web)。
链接到 csv 文件:https://raw . githubusercontent . com/py caret/py caret/master/datasets/kiva . CSV
潜在狄利克雷分配
在超级查询编辑器中以 Python 脚本的形式运行以下代码:
*from **pycaret.nlp** import *****
dataset = **get_topics**(data = dataset, text = 'en')*
超级查询编辑器(转换→运行 python 脚本)
‘en’是表格‘kiva’*中包含文本的列的名称。*
输出:
主题建模结果(代码执行后)
最终输出(点击表格后)
一旦代码被执行,带有主题权重和主导主题的新列被附加到原始表。在 Power BI 中,有许多方法可以可视化主题模型的输出。请参见下面的示例:
默认情况下,PyCaret 使用 4 个主题训练一个潜在的 Dirichlet 分配模型。默认值可以很容易地更改:
- 要更改主题数量,您可以使用 get_topics( ) 函数中的 num_topics 参数。
- 要更改模型类型,使用 get_topics( ) 中的 模型 参数。
参见训练具有 10 个主题的非负矩阵分解模型的示例代码:
*from **pycaret.nlp** import *
dataset = **get_topics**(dataset, 'en', model = 'nmf', num_topics = 10)*
PyCaret 有以下现成的主题建模算法:
📘示例 Power BI 中的关联规则挖掘
关联规则挖掘是一种基于规则的机器学习技术,用于发现数据库中变量之间的有趣关系。它旨在使用兴趣度来识别强规则。关联规则挖掘的一些常见业务用例有:
✔购物篮分析,了解经常一起购买的项目。
✔医学诊断,用于帮助医生确定给定因素和症状下疾病的发生概率。
在本教程中,我们将使用 PyCaret 的 github 库中的‘France . CSV’文件。您可以使用 web 连接器加载数据。(Power BI 桌面→获取数据→来自 Web)。
链接到 csv 文件:https://raw . githubusercontent . com/py caret/py caret/master/datasets/France . CSV
来自法国的样本数据点. csv
Apriori 算法
现在应该清楚了,所有 PyCaret 函数都是作为 python 脚本在 Power 查询编辑器中执行的(转换→运行 Python 脚本)。运行以下代码,使用 Apriori 算法为关联规则模型定型:
*from **pycaret.arules** import *
dataset = **get_rules**(dataset, transaction_id = 'InvoiceNo', item_id = 'Description')*
超级查询编辑器(转换→运行 python 脚本)
‘invoice no’是包含交易 id 的列,‘Description’*包含感兴趣的变量,即产品名称。*
输出:
关联规则挖掘结果(代码执行后)
最终输出(点击表格后)
它返回一个包含前因和后果的表格,以及相关的指标,如支持度、信心、提升等。点击这里了解更多关于 PyCaret 中的关联规则挖掘。
📘示例 5 —功率 BI 的分类
分类是一种受监督的机器学习技术,用于预测分类类别标签(也称为二元变量)。分类的一些常见业务用例有:
✔预测客户贷款/信用卡违约。
✔预测客户流失(客户会留下还是离开)
✔预测患者结果(无论患者是否患有疾病)
在本教程中,我们将使用 PyCaret 的 github 资源库中的‘employee . CSV’文件。您可以使用 web 连接器加载数据。(Power BI 桌面→获取数据→来自 Web)。
链接到 csv 文件:https://raw . githubusercontent . com/py caret/py caret/master/datasets/employee . CSV
目标:表格‘员工’包含一家公司中 15,000 名在职员工的信息,如在该公司工作的时间、每月平均工作时间、晋升历史、部门等。基于所有这些列(在机器学习术语中也称为特征,目标是预测员工是否会离开公司,由列‘left’*表示(1 表示是,0 表示否)。*
与聚类、异常检测和非监督机器学习下的 NLP 示例不同,分类是一种监督的技术,因此它分两部分实现:
第 1 部分:在 Power BI 中训练分类模型
第一步是在 Power Query Editor 中创建一个表‘employee’的副本,用于训练模型。
超级查询编辑器→右键单击“员工”→复制
在新创建的复制表' employee(model training)'中运行下面的代码来训练一个分类模型:
*# import classification module and setup environmentfrom **pycaret.classification** import *****
clf1 = **setup**(dataset, target = 'left', silent = True)# train and save xgboost modelxgboost = **create_model**('xgboost', verbose = False)
final_xgboost = **finalize_model**(xgboost)
**save_model**(final_xgboost, 'C:/Users/*username*/xgboost_powerbi')*
超级查询编辑器(转换→运行 python 脚本)
输出:
该脚本的输出将是一个保存在指定位置的 pickle 文件。pickle 文件包含整个数据转换管道以及经过训练的模型对象。
💡另一种方法是在 Jupyter 笔记本电脑中训练模型,而不是 Power BI。在这种情况下,Power BI 将仅用于使用 Jupyter notebook 中预训练的模型在前端生成预测,该模型将作为 pickle 文件导入 Power BI(遵循下面的第 2 部分)。要了解更多关于在 Python 中使用 PyCaret 的信息,点击这里。
💡如果你想学习如何使用 Jupyter Notebook 在 Python 中训练一个分类模型,请看我们的二进制分类 101 入门教程。(不需要编码背景)。**
PyCaret 中有 18 种现成可用的分类算法:
第 2 部分:使用训练好的模型生成预测
我们现在可以使用原始‘employee’表上的训练模型来预测该员工是否会离开公司(1 或 0)以及概率%。以 python 脚本的形式运行以下代码来生成预测:
*from **pycaret.classification** import *****
xgboost = **load_model**('c:/users/*username*/xgboost_powerbi')
dataset = **predict_model**(xgboost, data = dataset)*
输出:
分类预测(代码执行后)
最终输出(点击表格后)
两个新列附加到原始表。‘Label’列表示预测,‘Score’列表示结果的概率。
在本例中,我们预测的数据与我们用于训练模型的数据相同,但仅用于演示目的。在实际设置中,‘左’列是实际结果,在预测时未知。
在本教程中,我们已经训练了一个极端梯度推进 ('xgboost') 模型,并使用它来生成预测。我们这样做只是为了简单。实际上,您可以使用 PyCaret 来预测任何类型的模型或模型链。
PyCaret 的 predict_model( ) 函数可以与使用 PyCaret 创建的 pickle 文件无缝协作,因为它包含整个转换管道以及经过训练的模型对象。点击这里了解更多关于预测 _ 模型功能的信息。
💡训练分类模型所需的所有预处理任务,如缺失值插补(如果表中有任何缺失值或空值),或一键编码,或目标编码,它们都在训练模型之前自动执行。单击此处了解更多关于 PyCaret 预处理功能的信息。
📘示例 6—功率 BI 的回归
回归是一种受监督的机器学习技术,用于在给定过去数据及其相应的过去结果的情况下,以最佳可能的方式预测连续结果。与用于预测二元结果(如是或否(1 或 0))的分类不同,回归用于预测连续值,如销售额、价格、数量等。
在本教程中,我们将使用 pycaret 的 github 资源库中的‘Boston . CSV’文件。您可以使用 web 连接器加载数据。(Power BI 桌面→获取数据→来自 Web)。
链接到 csv 文件: https://raw . githubusercontent . com/py caret/py caret/master/datasets/Boston . CSV
目标:表格【波士顿】包含波士顿 506 所房屋的信息,如平均房间数、财产税税率、人口等。基于这些列(在机器学习术语中也称为特征,目标是预测由列‘medv’*表示的房屋的中值。*
第 1 部分:在 Power BI 中训练回归模型
第一步是在 Power Query Editor 中创建一个‘Boston’表的副本,用于训练模型。
以 python 脚本的形式在新的重复表中运行以下代码:
*# import regression module and setup environmentfrom **pycaret.regression** import *****
clf1 = **setup**(dataset, target = 'medv', silent = True)# train and save catboost modelcatboost = **create_model**('catboost', verbose = False)
final_catboost = **finalize_model**(catboost)
**save_model**(final_catboost, 'C:/Users/*username*/catboost_powerbi')*
输出:
该脚本的输出将是保存在指定位置的 pickle 文件。pickle 文件包含整个数据转换管道以及经过训练的模型对象。
PyCaret 中提供了 20 多种现成的回归算法:
第 2 部分:使用训练好的模型生成预测
我们现在可以使用训练好的模型来预测房屋的中值。在原始表【波士顿】中运行以下代码作为 python 脚本:
*from **pycaret.classification** import *****
xgboost = **load_model**('c:/users/*username*/xgboost_powerbi')
dataset = **predict_model**(xgboost, data = dataset)*
输出:
回归预测(代码执行后)
最终输出(点击表格后)
包含预测的新列‘标签’被附加到原始表。
在本例中,我们预测的数据与我们用于训练模型的数据相同,但仅用于演示目的。在实际设置中,‘medv’列是实际结果,在预测时是未知的。
💡训练回归模型所需的所有预处理任务,如缺失值插补(如果表格中有任何缺失值或空值),或一键编码,或目标转换,它们都在训练模型之前自动执行。单击此处了解更多关于 PyCaret 预处理功能的信息。
下一个教程
在使用 PyCaret 系列的 Power BI 中的机器学习的下一篇教程中,我们将更深入地探讨 PyCaret 中的高级预处理特性。我们还将看到如何在 Power BI 中生产机器学习解决方案,并在 Power BI 的前端利用 PyCaret 的力量。
如果你想了解更多,请保持联系。
在我们的 Linkedin 页面上关注我们,订阅我们的 Youtube 频道。
另请参见:
初级 Python 笔记本:
聚类
异常检测 自然语言处理
关联规则挖掘
回归
分类
开发管道中有什么?
我们正在积极改进 PyCaret。我们未来的开发管道包括一个新的时间序列预测模块,与 TensorFlow、的集成,以及对 PyCaret 可扩展性的重大改进。如果您想分享您的反馈并帮助我们进一步改进,您可以在网站上填写这张表格或者在我们的 Github 或 LinkedIn 页面上发表评论。
想了解某个特定模块?
从第一个版本 1.0.0 开始,PyCaret 有以下模块可供使用。点击下面的链接,查看 Python 中的文档和工作示例。
分类
回归 聚类
异常检测 自然语言处理
关联规则挖掘
重要链接
用户指南/文档
Github 资源库 安装 PyCaret
笔记本教程
贡献于 PyCaret
如果你喜欢 PyCaret,请给我们 github 回购的⭐️。
在媒介上跟随我:https://medium.com/@moez_62905/
生产中的机器学习
原文:https://towardsdatascience.com/machine-learning-in-production-79e02a43b273?source=collection_archive---------55-----------------------
从生产分类模型中学到的有用技巧
照片由 Wojciech 然后在 Unsplash 上拍摄
在生产中,风险很高。人们将会阅读模型的输出。输出更有意义。
最近,我和我的团队创建了一个 NLP 分类器,并在一个大型保险数据集上投入使用。它使用 TfidfVectorizer 和 LinearSVC 对自由文本进行分类。
但我很快意识到,把东西投入生产与理论是如此不同。
图片由 Juan C. Antúnez 在 flprobatelitigation 上拍摄
我认为,在生产中,获得模型预测的概率非常重要。例如,如果您的模型以 50%的概率对某件事情进行分类,那么应该有人对该预测进行调查。如果他们发现一个错误,你阻止了模型破坏公司的一个关键系统。
但是获得一个预测的概率并不总是那么简单。
在本文中,我将介绍一种从 scikit-learn 的 SVM 分类器中提取概率的方法。
这对于将我们的模型投入生产至关重要。
概率校准
我们不仅想要预测的类别标签,还想要预测的概率。Scikit-learn 在他们的文档中有一个关于这个主题的有趣章节。
我们需要创建一个回归器(或校准器),将分类器的输出映射到一个介于0
和1
之间的值。这个校准器会给我们每次预测的概率。
本质上,校准器将试图预测:
其中f
是分类器的输出。
或者更直白地说:给定我们的分类器的输出,我们对这个输出 100%确定的概率是多少?
约翰·普拉特的这篇论文指出,sigmoid 函数可以用作回归变量。我们得到以下结果:
为了找到 A 和 B,我们可以使用最大似然估计。这将涉及最小化负对数可能性:
其中ti
是目标概率。
给我看看代码
代码非常简单。Scikit-learn 隐藏了抽象层背后的大部分复杂性。
你需要做的就是这个:
# from: https://stackoverflow.com/questions/26478000/converting-linearsvcs-decision-function-to-probabilities-scikit-learn-pythonsvm = LinearSVC()
clf = CalibratedClassifierCV(svm)
clf.fit(X_train, y_train)
CalibratedClassifierCV 将使用 k 重交叉验证方法来拟合训练数据。默认值为 5 倍。点击查看更多信息。
然后,我们将提取所有 k 倍预测类的平均概率。predict_proba
是我们这里需要的函数。虽然函数本身看起来像一个未完成的句子,但它非常有用。
y_proba = clf.predict_proba(X_test)
要得到预测的类,我们可以简单地使用预测函数。
clf.predict(X_test)
评估校准品
校准器与数据的吻合程度如何?我们怎么知道?
为此,我们可以使用sklearn.metrics.brier_score_loss
。更多信息可在这里找到。
如果这个分数非常高,那么我们就不能查看校准器的概率输出——它们是无用的。相反,我们需要寻找更好的方法来安装校准器。这篇文章提供了一些安装校准器的好方法。
结束
真的就是这样!
我相信,随着我们继续保持这种模式,我会有更多的内容要添加。我想分享这个帮助我们有效地将模型投入生产的小技巧。希望有人会觉得它有用。
如果我犯了一个错误,或者你有兴趣寻求帮助,请随时通过推特联系我。
原载于 2020 年 9 月 30 日https://spiyer 99 . github . io。
使用 Apache Airflow 在生产中进行机器学习
原文:https://towardsdatascience.com/machine-learning-in-production-using-apache-airflow-91d25a4d8152?source=collection_archive---------21-----------------------
如何使机器学习项目在生产中具有健壮性和可解释性的实际案例
田宽在 Unsplash 上拍照
目录:
- 简介
- 数据验证
- 模型验证
- 总结
1。简介
“所有的模型都是错的,但有些是有用的。”—乔治·博克斯。
使用机器学习(ML)来构建解决方案本身就是一项复杂的任务。虽然学术 ML 源于 20 世纪 80 年代的研究,但机器学习系统在生产中的实际实现仍然相对较新。
今天,我想分享一些关于如何使用 Apache Airflow 使您的 ML 管道健壮且可解释的想法。整个项目可以在 Github 上找到。代码被 dockerized ,所以即使你不熟悉这项技术,使用它也很简单。
这个题目是复杂的,多方面的。在本文中,我将只关注任何 ML 项目的两个部分——数据验证和模型评估。目标是分享实用的想法,你可以在你的项目中相对简单地引入,但仍然可以获得很大的好处。
这个主题非常广泛,所以我们来介绍几个限制条件:
- 我们将使用 Apache Airflow 作为管道编排工具;
- 我们将考虑一个 ML 培训管道。
- 我们将关注大多数项目中常见的实际问题。
如果您不熟悉 Airflow,它是一个以编程方式创作、调度和监控工作流的平台[1]。气流工作流被构建为任务的有向无环图(Dag)。Airflow scheduler 在遵循指定依赖关系的同时,对一组工作线程执行您的任务。命令行实用程序使在 Dag 上执行复杂的手术变得轻而易举。用户界面使得可视化生产中运行的管道、监控进度以及在需要时解决问题变得容易。
2.数据有效性
数据验证是确保数据存在、正确和有意义的过程。在任何组织中,通过自动验证检查来确保数据质量是构建数据管道的关键步骤。
在模型训练之前需要数据验证步骤,以决定是否可以训练模型或停止管道的执行。如果管道识别出以下情况,则自动做出该决定[2]:
- 数据模式偏差:这些偏差被认为是输入数据中的异常,这意味着下游管道步骤,包括数据处理和模型训练,接收到不符合预期模式的数据。模式偏差包括接收到意外的功能、没有接收到所有预期的功能或接收到具有意外值的功能。
- 数据值偏斜:这些偏斜是数据统计属性的显著变化,这意味着数据模式发生了显著变化,您需要检查这些变化的性质。
数据验证的重要性:
- 模型的质量取决于数据的质量。
- 通过量化数据质量增加对数据质量的信心。
- 校正训练好的 ML 模型可能是昂贵的——预防胜于治疗。
- 如果数据无效,则停止训练新的 ML 模型。
Airflow 提供了一组检查操作符,使我们能够轻松验证数据质量。让我们看看如何在实际例子中使用这样的操作符。
2.1 检查操作员
CheckOperator 期望一个返回单行的 SQL 查询。第一行中的每个值都使用 python bool 转换进行计算。如果任何值返回 False,则检查失败,并显示错误。因此,只需在管道中添加一个任务,我们就可以检查特定日期的数据是否存在。
2.2 IntervalCheckOperator
对于更复杂的检查,气流有间隔检查操作器。检查以 SQL 表达式形式给出的度量值是否在之前“ days_back ”中度量值的特定容差范围内。
这项检查的一个关键点是比率公式——使用哪个公式来计算两个指标之间的比率。你可以从两种可能中选择:
max _ over _ min:max(cur,ref) / min(cur,ref)
relative _ diff:计算 abs(cur-ref) / ref
IntervalCheckOperator 允许您同时检查一些特定表的不同比率的不同指标。
2.3 ValueCheckOperator
一个简单而强大的操作符。它使用 SQL 代码执行纯值检查。您可以使用任何复杂度的 SQL 查询来获取任何值。如果计算值等于传递值,且有一定的容差,则检查通过。
使用来自 Airflow 的检查操作符,当您看到检查失败时,更容易理解问题出在哪里,而不是处理代码中的错误。
管道开始处的数据检查列表
在当前示例中,我使用所有检查来测试输入数据。但是您也可以检查任何输出值。此外,将检查添加到 ETL 管道中也很有用。
3.模型验证
给定新数据,成功训练模型后,会发生此步骤。在推广到生产之前,我们会对模型进行评估和验证。理想情况下,离线模型验证步骤应该包括[2]:
- 使用测试数据集上的训练模型产生评估度量值,以评估模型的预测质量。
- 将新训练的模型与当前模型(例如,生产模型、基线模型或其他业务需求模型)生成的评估度量值进行比较。在将其推广到生产之前,您要确保新模型比当前模型产生更好的性能。
- 确保模型的性能与数据的各个部分一致。
3.1 现实中的模型验证
实际上,保留代表性的测试数据集可能很难,而且成本很高。但是我们仍然要监控重新训练的模型的质量。
我们能做的最简单的事情就是使用训练数据集计算指标。这个想法是,研究人员知道原型制作最后一步的训练集和测试集的误差度量值。如果下一次训练后的误差值变得更高或更低,我们不应在生产中使用该模型。另外,如果你观察到误差值的上升趋势,可能意味着模型的退化。
3.2 模型的元数据监控
想法是一样的。您希望能够对您的模型进行快速诊断,这将持续很长时间。模型的元数据可以让您看到模型生命周期的一些关键时刻。
我们希望有一些简单但有用的解决方案,我们甚至可以为现有的项目快速实现。您可以开始监视这些属性:
- 训练数据的数量;
- 范畴特征的多样性;
- 数字特征的标度、平均值、最小值、最大值;
- 算法的学习属性。例如:SGDClassifier[3]的“coef _”或 RandomForestRegressor [4]的“feature _ importances _”;
这里有一个使用 sklearn 的例子:
例如,根据您公司的技术堆栈,您可以将值存储到数据库并构建 Grafana 仪表板,或者如果您使用 Datadog,只需记录值并构建仪表板。
4.摘要
在投产新项目时,您应该记住的主要观点是:
- 数据验证步骤非常重要。校正已训练的 ML 模型可能是昂贵的——如果数据无效,则停止训练新的 ML 模型。
- Airflow 是一个强大的工具,它允许我们用最少的实现工作来检查数据。
- 分配代表性的测试数据集既困难又昂贵。监控训练数据集上的误差值仍然是一个很好的替代方案。
- 存储模型的元数据可以帮助我们看到模型本质的关键变化。
您可以在资源库DanilBaibak/ml-in-production中找到该项目的代码。
参考资料:
- 阿帕奇气流文档
- MLOps:机器学习中的连续交付和自动化管道
- SGD 分类器
- RandomForestRegressor
- 气流检查操作员
关于生产中的机器学习主题的其他有用参考:
- ML 测试分数:ML 生产准备和技术债务削减的指标 (2017) Breck 等。(谷歌)
- 机器学习的软件工程:案例研究 (2019) Amershi 等。(微软)
- 监控生产中的机器学习模型
- 气流最佳实践
使用 PyCaret 在 SQL 中进行机器学习
原文:https://towardsdatascience.com/machine-learning-in-sql-using-pycaret-87aff377d90c?source=collection_archive---------37-----------------------
通过在 SQL Server 中集成 PyCaret 将您的 ML 代码发送到数据
这篇文章是一个关于如何使用【py caret】(Python 中的一个低代码 ML 库)在 SQL Server 中训练和部署无监督机器学习聚类模型的分步教程。****
我们将在本文中讨论的内容:
1.如何免费下载并安装 SQL Server
2.如何创建新数据库并将数据导入数据库
3.如何在数据库中启用和使用 Python 脚本
4.如何训练聚类分析算法,以便为数据集中的每个观察值分配分类标签
一、将代码带入数据——ML 使用数据库的案例
执行 ML 实验的首选工具/环境是命令行、ide 或笔记本。然而,当数据变得非常大时,或者当需要将 ML 模型投入生产时,这样的工具/环境可能会造成限制。迫切需要能够对数据所在的模型进行编程和训练。MS SQL Server 在其 SQL Server 2019 版中引入了这一功能。使用 SQL Server 进行机器学习的独特优势在于:
I .从系统中提取大量数据既繁琐又耗时。在服务器上进行 ML 实验将代码转化为数据,而不是将数据转化为代码
二。ML 实验大多在计算机/cpu 内存中执行。在大型数据集上训练 ML 算法时,大多数机器都遇到了性能上限。SQL Server 数据库上的 ML 避免了这种情况
三。很容易将 ML 管道与其他 ETL 过程集成和部署在一起
二。SQL 服务器
SQL Server 是一个微软关系数据库管理系统。作为数据库服务器,它执行存储和检索不同应用程序请求的数据的主要功能。在本教程中,我们将通过在 SQL Server 中导入 PyCaret 库,使用SQL Server 2019****Developer进行机器学习。
三。下载软件
如果您以前使用过 SQL Server,很可能您已经安装了它,并且可以访问数据库。如果没有, 点击此处 下载 SQL Server 2019 Developer 或其他版本。
四。设置环境
在 SQL Server 中使用 PyCaret 功能之前,您需要安装 SQL Server 和 PyCaret。这是一个多步骤的过程:
步骤 1 —安装 SQL Server
下载 SQL Server 2019 开发者版文件“SQL2019-SSEI-Dev.exe
打开文件并按照说明进行安装(建议使用自定义安装选项)
选择新的 SQL Server 独立安装
在实例特性选项中,选择包括机器学习服务和语言扩展和机器学习服务器(单机版)下的 Python 在内的特性
点击接受,同意安装 Python
安装可能需要 15-20 分钟
步骤 2 —安装 Microsoft SQL Server Management Studio(SSMS)
点击这里 或者打开 SQL Server 安装中心下载“SQL Server 管理工具”文件SSMS-Setup-ENU.exe
打开“SSMS-Setup-ENU.exe文件开始安装
安装可能需要 5-10 分钟
步骤 3-为机器学习创建一个数据库
一旦您安装了所有的东西,您将需要启动服务器的一个实例。为此,请启动 SSMS。在登录阶段,会要求您输入 SQL Server 的名称,您可以从下拉菜单中选择。一旦建立了连接,您就可以看到服务器上的所有对象。如果您是第一次下载 SQL Server,并且没有可以使用的数据库,则需要先创建一个新数据库。
在对象资源管理器面板中,右键单击数据库,然后选择新建数据库
输入数据库名称和其他信息
设置可能需要 2-3 分钟,包括创建数据库、用户和设置所有权
步骤 4 —导入 CSV 文件
现在,您必须使用 SQL Server Management Studio 将 CSV 文件导入数据库。
在数据库中创建一个表"珠宝"
右击数据库,选择任务 - > 导入数据
对于数据源,选择平面文件源。然后使用浏览按钮选择 CSV 文件。在点击下一个按钮之前,花一些时间配置数据导入。
对于目标,请选择正确的数据库提供程序(例如 SQL Server Native Client 11.0)。输入服务器名称;勾选使用 SQL Server 认证,输入用户名、密码,以及数据库,然后点击下一步按钮。
在选择源表和视图窗口中,您可以在单击下一个按钮之前编辑映射。
检查立即运行并点击下一个按钮
单击“完成”按钮运行包
数据加载结果
步骤 5-为 Python 脚本启用 SQL Server
我们将通过使用sp _ execute _ external _ script系统存储过程在 SQL Server“内部”运行 Python。首先,您需要打开一个'新查询'。在实例中执行以下查询,以启用远程脚本执行过程:
EXEC sp_configure ‘external scripts enabled’, 1RECONFIGURE WITH OVERRIDE
注意:在继续下一步之前,重新启动实例。
可以执行以下 SQL 语句来检查 Python 路径并列出已安装的包。
检查 Python 路径:
EXECUTE sp_execute_external_script@language =N’Python’,@script=N’import sys; print(“\n”.join(sys.path))’
脚本执行结果
列出已安装的软件包:
EXECUTE sp_execute_external_script@language = N’Python’,@script = N’import pkg_resourcesimport pandas as pdinstalled_packages = pkg_resources.working_setinstalled_packages_list = sorted([“%s==%s” % (i.key, i.version) for i in installed_packages])df = pd.DataFrame(installed_packages_list)OutputDataSet = df’WITH RESULT SETS (( PackageVersion nvarchar (150) ))
脚本执行结果
步骤 6-将 PyCaret Python 包添加到 SQL Server
要安装 PyCaret 包,请打开命令提示符并浏览到安装 SQL Server 的 Python 包的位置。默认位置是:
C:\Program Files\Microsoft SQL Server\MSSQL15.MSSQLSERVER\PYTHON_SERVICES
导航到“脚本目录,使用 pip 命令安装 PyCaret 包
pip.exe install pycaret
命令提示符— PyCaret 安装
命令提示符— PyCaret 安装结束
注意:确保您有权访问 SQL Server 目录以安装软件包和/或更改配置。否则,软件包安装将会失败。
安装可能需要 5-10 分钟
注意:万一运行 SQL 脚本时遇到“ lightgbm ”模块丢失的问题。请遵循以下说明:
一、卸载“ lightgbm
pip.exe uninstall lightgbm
二。重新安装“灯 gbm
pip.exe install lightgbm
执行以下 SQL 以从 SQL Server 验证 PyCaret 安装:
EXECUTE sp_execute_external_script@language = N’Python’,@script = N’import pkg_resourcespckg_name = “pycaret”pckgs = pandas.DataFrame([(i.key) for i in pkg_resources.working_set], columns = [“key”])installed_pckg = pckgs.query(‘’key == @pckg_name’’)print(“Package”, pckg_name, “is”, “not” if installed_pckg.empty else “”, “installed”) ’
脚本执行结果
动词 (verb 的缩写)ML 实验示例 SQL Server 中的集群
聚类是一种机器学习技术,它将具有相似特征的数据点分组。这些分组对于探索数据、识别模式和分析数据子集非常有用。集群的一些常见业务用例有:
以营销为目的的✔客户细分。
促销和折扣的✔顾客购买行为分析。
✔在诸如新冠肺炎的流行病爆发中识别地理群集。
在本教程中,我们将使用 PyCaret 的 Github 存储库中的“jewellery . CSV”文件。
珠宝数据集中的样本数据点
1.k 均值聚类
在 SQL Server 中运行以下 SQL 代码:
EXECUTE sp_execute_external_script@language = N’Python’,@script = N’dataset = InputDataSetimport pycaret.clustering as pcdataset = pc.get_clusters(data = dataset)OutputDataSet = dataset’,@input_data_1 = N’SELECT [Age], [Income], [SpendingScore], [Savings] FROM [jewellery]’WITH RESULT SETS(([Age] INT, [Income] INT, [SpendingScore] FLOAT, [Savings] FLOAT, [Cluster] varchar(15)));
2.输出
SQL 语句结果
包含标签的新列' Cluster' '被附加到原始表。
默认情况下,PyCaret 训练一个具有 4 个聚类的 K-Means 聚类模型(即表中的所有数据点都被分为 4 组)。默认值可以很容易地更改:
要更改聚类数,可以使用 get_ clusters()函数中的 num_clusters 参数。
要更改模型类型,请使用 get_clusters()中的模型参数。
3。k 模式
使用 6 个集群训练 K-Modes 模型参见以下代码:
EXECUTE sp_execute_external_script@language = N’Python’,@script = N’dataset = InputDataSetimport pycaret.clustering as pcdataset = pc.get_clusters(data = dataset, model=”kmodes”, num_clusters = 6)OutputDataSet = dataset’,@input_data_1 = N’SELECT [Age], [Income], [SpendingScore], [Savings] FROM [jewellery]’WITH RESULT SETS(([Age] INT, [Income] INT, [SpendingScore] FLOAT, [Savings] FLOAT, [Cluster] varchar(15)));
按照这些步骤,您可以为珠宝数据集中的每个观测点分配聚类值。您也可以对其他数据集使用类似的步骤,对它们执行聚类。
不及物动词结论
在这篇文章中,我们学习了如何在 SQL Server 中运行 Python 库(PyCaret)来构建集群模型。类似地,根据业务问题的需要,您可以构建和运行其他类型的监督和非监督 ML 模型。
您可以进一步查看 PyCaret 网站,获取关于其他监督和非监督实验的文档,这些实验可以在 SQL Server 中以类似的方式实现。
我以后的帖子将是在 SQL Server 中使用 Python 和 Pycaret 探索监督学习技术(回归/分类)的教程。
七。重要链接
PyCaret
PyCaret:用户指南和文档
PyCaret:教程
我的 LinkedIn 个人资料
股票中的机器学习。重新定义公司集团。
原文:https://towardsdatascience.com/machine-learning-in-stocks-re-defining-company-groups-1b4872459458?source=collection_archive---------76-----------------------
亨尼投资
应用聚类开发识别可比公司的新方法
图片作者文字
在投资界的一个普遍信念是,被低估的公司提供了一个巨大的机会来获得高于平均水平的利润。我们这个时代最成功的投资者,包括沃伦·巴菲特、霍华德·马克斯和菲尔·费舍尔,都非常依赖这种方法为自己和客户创造财富。
识别被低估的公司非常具有挑战性,因为这涉及到进行定量预测预测未来 5-10 年的情况。幸运的是,对许多人来说,情况并不总是如此。霍华德·马克斯将这一概念与市场周期的概念联系起来。有些时候所有东西都很便宜。你只需要买些东西,除非你的判断非常错误,否则你会做得很好。
避免大错特错的一个方法是了解哪种公司不太可能是好的投资选择。
产业作为群体是没有用的
目前,我们按照公司做什么来给公司分组。我们认为科技股,如苹果公司(T16)、谷歌公司(T19)、微软公司(T20)、T21 公司()是一个群体,石油公司(T30)和天然气公司(如雪佛龙公司(T22)、埃克森美孚公司(T25)或西方石油公司(T27)是一个群体,以及许多其他基于行业的群体。
这些分组对于将一家公司与商业活动联系起来是有意义的,但在根据其规模、结构和种类来确定类似的公司时,它们也是相当无用的。
例如,在新冠肺炎危机中,一个诱人的问题是:
哪些公司****在价格下降最多?
哪些 公司****不太可能破产?
商业中被低估的和?这是一个好的机会吗?
很好地理解行业分类不太可能在回答这些问题时提供切实的价值。我们已经观察到航空公司和游轮公司的股票价格遭受了巨大的损失,而像 Zoom 这样的“远程工作”技术却使它们的价格翻了一番。
https://www.vhinny.com/display/ZM
虽然这些都是激动人心的机会,但现在和要问的一个重要问题是:
- 处于底部的公司可能非常便宜。在它们回升之前,我应该买哪些?
- 处于顶端的公司可能被高估。在价格回落之前,我应该卖出哪些股票来固定利润?
为了回答这些问题,作为一名数据科学家,我建议开发一种更好的方法,根据公司的业务表现而不是业务活动来定义公司集团。
价值【10 b+】美元的公司很可能与那些价值低于【500】美元的公司截然不同。拥有高比例有形资产的公司不同于根本没有有形资产的公司。与负债少的公司相比,负债多的公司面临更大的风险。这些属性的各种组合呢?
在这项研究中,我将特别使用机器学习和无监督聚类来定义这些属性,并开发一种新的股票分组方法。
选择维度
有了 Vhinny 的财务数据,我有~100 个功能可以选择。不像之前的研究,我用它们来预测明年的收入,聚类要求我从一开始就有选择性。更不用说处理许多功能的计算 复杂性了,两位数的功能很难评估。
首先,我根据自己的投资直觉选择了几个特征,来捕捉最能让公司与众不同的主要方面。看完完整的清单后,我的选择落在了:
- 净收入—获取盈利能力
- 总资产—获取规模
- 负债权益比——捕捉融资结构
- 营业利润——捕捉盈利的难度
- 每股收益增长(EPS) —捕捉逐年增长
让我们来看看这些功能是如何相互关联的:
这个斯皮尔曼相关图表明,除了资产和净收入之外,大多数特征都不相关。这在直觉上是有道理的,因为赚很多钱通常需要大量资产来维持这种收入水平。
拥有相关特征不太可能帮助我提高聚类提供的洞察力。为了减轻这一点,我将删除净收入。没有它,我的公司简介就无法了解公司的盈利能力。让我们将净收入转换成盈利能力,盈利能力简单地定义为公司当年的收入是正还是负。
这是新的相关矩阵:
看起来不错。用盈利能力代替净收入后,我得到了包含独立特征的数据集,同时代表了所有感兴趣的维度。
这是一个煮咖啡或绕着街区转一圈的好时机。在下一篇文章中,我将研究这些特性之间的分布,并做简单的预处理,为集群做好准备。
顺便说一下…
我们连线吧!
我很高兴和那些和我一样走向财务独立的人联系。如果你也在寻求经济独立,或者你想合作、交流想法,请联系我们!以下是一些可以找到我的地方:
- www.vhinny.com—投资研究平台,为您自己的分析提供金融数据
- https://www.linkedin.com/company/vhinny——加入我们 LinkedIn 上的社区,在那里我和其他贡献者分享与投资相关的内容
干杯!
用 PyCaret 实现 Tableau 中的机器学习
原文:https://towardsdatascience.com/machine-learning-in-tableau-with-pycaret-166ffac9b22e?source=collection_archive---------23-----------------------
在几分钟内设置 ML 管道的逐步集成指南
PyCaret 是最近发布的 Python 开源机器学习库,它在低代码环境中训练和部署机器学习模型。要了解更多关于 PyCaret 的信息,请阅读这个公告。
本文将展示 PyCaret 如何与 Tableau Desktop 和 Tableau Prep 集成,这为分析师和数据科学家向其仪表板、报告和可视化添加一层机器学习开辟了新途径。通过减少编码所需的时间以及购买额外软件的需求,快速原型制作现在可以在整个组织的分析师已经熟悉和可用的环境中实现。
学习目标
- 训练有监督的机器学习模型,并在 PyCaret 中创建 ML 管道
- 将经过培训的 ML 管道加载到 Tableau 桌面和 Tableau 准备中
- 创建一个仪表板,传达来自模型的见解
- 了解如何使用 Tableau 将模型部署到生产中
直销业务背景
此处的示例将重点介绍如何建立一个基本的直接营销倾向模型,该模型使用分类算法来预测哪些客户在通过文本或电子邮件收到要约后最有可能主动拜访。
然后将创建一个仪表板,它可以采用经过训练的模型,并预测新活动可能会有多成功,这对设计促销计划的营销人员来说是有价值的。
通过使用 PyCaret 和 Tableau,企业可以快速设置报告产品,使用现有软件和最少的前期开发时间持续生成预测视图。
开始之前
需要遵循的软件:
1 — Tableau 桌面
Tableau Desktop 是一款可视化分析工具,用于连接数据、构建交互式仪表盘以及在整个组织内分享见解。
2 —表格准备
Tableau Prep 提供可视化界面,通过设置流程和时间表来组合、清理和调整数据。
3 — Python 3.7 或更高版本
Anaconda 是用于数据科学的 Python 编程语言的免费开源发行版。如果你以前没用过,可以在这里下载。
https://www.anaconda.com/distribution/
4 — PyCaret Python 库
要安装 PyCaret 库,请在 Jupyter notebook 或 Anaconda 提示符下使用以下代码。
pip install pycaret
这可能需要 15 分钟。如果遇到任何问题,请查看 project GitHub 页面了解已知问题。
5—tabby Python 库
TabPy 是运行 python 脚本所需的 Tableau 支持的库。
从 GitHub 页面:
tabby(Tableau Python 服务器)是一个分析扩展实现,它通过允许用户执行 Python 脚本和通过 Tableau 的表计算保存的函数来扩展 Tableau 的功能。
要安装 TabPy,请在 Anaconda 提示符或终端中使用以下代码。
pip install tabpy
安装后,使用下面的代码启动一个使用默认设置的本地服务器。
tabpy
要将 Tableau 连接到 TabPy 服务器,请转到“帮助”>“设置和性能”>“管理分析扩展连接”。选择 TabPy 并输入 localhost、端口 9004(默认)并测试连接。
Python 脚本现在可以通过输出为表计算的计算字段在 Tableau 中运行。
有关自定义服务器选项,请参考 TabPy GitHub 页面。在外部服务器和/或云上运行 TabPy 和配置 Tableau 服务器将不会在这篇文章中讨论,但是请看这里了解更多信息。
直接营销数据
将使用的数据集包含通过文本和电子邮件发送给客户的各种营销优惠信息。它包含组织成 ID 列的 64000 条记录、与客户或发送的消息相关的 10 个特征以及指示是否有访问发生的二进制目标。数据可以在这里下载。
预先训练一个模型
虽然可以在 Tableau 中执行模型训练过程,但这通常不是首选方法,因为每次刷新数据或用户与视图交互时,脚本都会重新运行。这是有问题的,因为:
- 当用新数据重新训练模型时,预测可能会发生意外变化。
- 不断重新运行脚本会影响仪表板的性能。
更合适的方法是在 Tableau 中使用预训练模型来生成对新数据的预测。在这个例子中,我们将使用 Jupyter notebook 来演示如何使用 PyCaret 来直接完成这个过程。
在 PyCaret 中构建模型
在 Jupyter Notebook 中运行以下代码将训练一个朴素贝叶斯分类模型,并创建一个保存为 pickle 文件的 ML 管道。
注意,建立和保存模型只用了 4 行代码。完整的笔记本可以在这里下载。
包含训练模型和管道的 Pickle 文件
看不见的数据将用于模拟尚未收到报价的新客户列表。当仪表板部署到生产环境中时,它将连接到包含新客户信息的数据库。
请注意,在设置阶段,PyCaret 执行自动预处理,在这种情况下,通过一次热编码将功能数量从 10 个扩展到 39 个。
这只是 PyCaret 内置功能的皮毛,因此强烈建议查看 PyCaret 网站上的分类模块和教程。这里不涉及所选型号的具体细节。
将模型加载到 Tableau 桌面
现在,看不见的数据将被传递给训练好的模型,并在 Tableau 桌面中进行标记。
说明:
1)打开 Tableau 并连接到在上面的代码中创建的文本文件 new_customer.csv。这只是一个例子,但理想情况下,新的或未标记的客户数据将驻留在数据库中。
2)在新的工作表中,选择分析>创建计算字段,或在数据窗格中单击鼠标右键。输入以下代码:
SCRIPT_INT("
import pandas as pd
import pycaret.classificationnb = pycaret.classification.load_model('C:/Users/owner/Desktop/nb_direct')X_pred = pd.DataFrame({'recency':_arg1, 'history_segment':_arg2, 'history':_arg3, 'mens':_arg4, 'womens':_arg5,'zip_code':_arg6, 'newbie':_arg7, 'channel':_arg8, 'segment':_arg9, 'DM_category':_arg10})
pred = pycaret.classification.predict_model(nb, X_pred)
return pred['Label'].tolist()",
SUM([recency]),
ATTR([history_segment]),
SUM([history]),
SUM([mens]),
SUM([womens]),
ATTR([zip_code]),
SUM([newbie]),
ATTR([channel]),
ATTR([segment]),
SUM([DM_category])
)
- 脚本函数指定将从计算中返回的数据类型。在这种情况下,它是访问的二元预测标签。
- PyCaret 中的 load_model()函数加载先前保存的模型和转换管道,该管道被保存为 pickle 文件。
- X_pred 是一个 dataframe,它将通过 _arg1、_arg2、_arg3…符号将连接到 Tableau 的数据映射为输入。这些字段列在脚本的末尾。
- predict_model()采用定型模型并根据新的数据输入进行预测。注意,新数据是通过 PyCaret 设置阶段(编码)创建的转换管道传递的。
- 然后,标签以列表的形式返回,可以在 Tableau 中查看。
3)通过将 ID 和标签列拖动到视图中,可以看到模型预测。
重要的是要理解输出是一个有一些限制的表格计算:
- 该脚本只有在拖到视图中时才会运行。
- 除非两者都在视图中,否则不能用作进一步计算的基础。
- python 生成的数据不能追加到 Tableau 提取中。
- 每次视图更改时都会运行该脚本,这可能会导致长时间的等待。
这些缺点非常明显,因为当每个记录都必须包含在视图中时,仪表板选项变得有限,在这种情况下,脚本运行 3200 条记录需要大约 4 分钟。
可行的应用包括生成可以导出的评分列表或如下所示的摘要视图。
由此得出的一个例子是,高消费客户最有可能光顾,这在商业上是有道理的,但也可能是不必要折扣的一个指标。
将模型加载到 Tableau 准备中
绕过在 Tableau Desktop 中直接运行脚本的限制的一个很好的替代方法是使用 Tableau Prep。可以连接新数据,然后将其传递给模型,不同的是,这一次预测的标签被附加到输出中。当连接到 Tableau 时,新列可以正常使用,而不是作为表计算。
说明:
1)打开 Tableau Prep 并连接到在上述代码中创建的文本文件 new_customer.csv。
2)在流窗格中选择文件旁边的“+”按钮,并添加脚本选项。像在 Tableau Desktop 中一样,使用 localhost 和 9004 连接到应该还在后台运行的 TabPy 服务器。
3)接下来,需要创建以下 python 脚本,并使用浏览选项连接到 prep。可以在这里下载。
创建一个加载 pickle 文件的函数,该文件包含保存的模型和转换管道。装载到 prep 中的数据自动保存在 df 对象中,并传递给模型。
PyCaret 输出将返回初始数据集和两个新追加的列;标签(预测)和分数(预测的概率)。输出模式确保将列和数据类型正确读入 prep。
然后必须将函数名输入到 prep 中。
4)选择脚本图标旁边的“+”号,然后选择输出。可以发布为. tde 或。将 hyper 文件发送到 Tableau 服务器,这是生产环境中的首选方法,但在本例中,会将. csv 文件发送到桌面。
请注意 label 和 score 列现在是如何追加到原始数据集的。选择“运行流程”以生成输出。此处可以下载的流量文件。
在服务器环境中,可以安排流运行的时间,并在数据到达实际的 Tableau 仪表板之前自动完成评分过程。
将流输出加载到 Tableau 中
新标记的数据现在可以连接到 Tableau Desktop,而没有表计算限制和变慢。
可以创建聚合和任何其他所需的计算,以设计显示各种预测指标的摘要仪表板:
一旦数据和 ML 管道建立,营销人员和高管将能够快速跟踪即将到来的活动可能如何进行,只需最少的干预。包含示例仪表板和早期脚本的 Tableau 文件可以从这里下载。
结束语
本文展示了 PyCaret 如何与 Tableau Desktop 和 Tableau Prep 集成,以便在现有工作流中快速添加一层机器学习。
通过使用组织和 PyCaret 库熟悉的工具,可以在几分钟内建立完整的 ML 管道,从而使预测分析原型快速启动。
有用的链接
PyCaret
PyCaret:用户指南和文档
PyCaret:教程
PyCaret: Youtube
领英
浏览器中的机器学习
原文:https://towardsdatascience.com/machine-learning-in-the-browser-7fc08858640?source=collection_archive---------20-----------------------
由安妮·斯普拉特在 Unsplash 上拍摄
在线构建可共享的机器学习模型
Jupyter 笔记本是用于构建机器学习模型的最常见的环境之一。然而,它们也有一些缺点。Jupyter 笔记本非常适合在本地开发机器学习模型,但很难分享和协作使用该工具生成的代码。
此外,还需要合理的设置,尤其是如果您不是 python 的当前用户。您需要设置一个 python 环境,安装 Jupyter 及其依赖项,以及您可能需要的任何其他 python 包。
幸运的是,有一些工具可以让您在笔记本上直接在浏览器中运行和开发 python 代码,而不需要任何设置。在这篇文章中,我将简要介绍其中的两个工具;
- 谷歌联合实验室
- Kaggle 内核
谷歌合作实验室
Google Colaboratory ,通常被称为 colab,是 Google 创建的一个产品,允许任何人在浏览器中创建和运行 python 代码。它有许多内置的标准机器和数据科学库,包括 pandas 和 scikit-learn。您还可以在每个笔记本中安装几乎任何其他 python 库。
要访问 colab,你需要注册一个谷歌账户,然后你就可以免费访问笔记本环境和包括 GPU 在内的计算资源。
让我们快速演示一下。
登录到您的 Google 帐户后,转到 drive 并选择新的 Google 协作室。
这将打开一个新的空笔记本。
您可以通过运行pip freeze
来查看预安装的软件包。
如果你需要安装任何还没有的包,你可以通过运行pip install package
来完成。
有多种方法可以导入数据,包括直接从 Google drive 加载文件。让我们看一个从本地 CSV 文件导入数据的例子。
首先,我们运行这段代码。
from google.colab import filesuploaded = files.upload()
然后,您会看到一个按钮,用于选择存储在本地系统上任何位置的文件。
您现在可以自由地编写代码来创建您的机器学习模型。
Google colab 笔记本可以通过链接共享,就像你可以共享任何 Google 文档一样。链接的接收者可以运行和编辑您的代码。
Kaggle 内核
Kaggle 内核需要一个 Kaggle 帐户,但也可以完全免费使用。它们与 Google colab 笔记本非常相似,但一个优点是它们包括版本控制。
一旦你创建了一个帐户,你可以导航到网站的内核部分,并选择新笔记本。
和 colab 一样,Kaggle 内核提供了许多标准的 python 库,你可以用pip freeze
查看。导入其他库使用与 colab 完全相同的方法,安装包也是如此。
加载数据非常简单。首先选择文件,然后添加或上传数据。
现在你有很多选择。您可以使用 Kaggle 数据集、内核输出文件或上传您自己的本地 CSV 文件。
正如我提到的,Kaggle 内置了版本控制。这意味着您可以将更改提交到您的内核或其他人的内核,并在需要时跟踪和恢复到以前的版本。这有助于合作。
这是对这些工具中可用选项和功能的简要介绍。这两者的功能都值得进一步研究。我经常使用浏览器内笔记本向他人提供我的工作演示,尤其是那些可能不会使用 Jupyter 笔记本或 python 的非数据科学家。这两个工具也可以成为学习机器学习和数据科学的好方法,而无需在本地设置 python 和笔记本环境的开销。
感谢阅读!
我每月发送一份时事通讯,如果你想加入,请点击此链接注册。期待成为您学习旅程的一部分!
云中的机器学习与内部部署
原文:https://towardsdatascience.com/machine-learning-in-the-cloud-vs-on-premises-452c9c34e6fd?source=collection_archive---------31-----------------------
云只是别人的电脑
开发人员之间流传着一个笑话,云只是别人电脑的一个词。但事实是,通过利用云,您可以获得使用本地服务器场无法实现的优势。
超级云提供商(AWS、Azure、GCP)能够提供更低的总拥有成本,同时提供从可扩展性到安全性的卓越功能。当你只能在需要的时候从货架上拿下来的时候,在内部构建所有东西是没有经济意义的。云供应商不断创新解决方案,例如只按使用时间计费的服务器,而不是按运行和等待请求的时间计费的服务器。他们还能够吸引可扩展性和安全性等方面的专业人才,这是其他所有供应商无法做到的。
云和机器学习
大多数机器学习实验都是从理解你笔记本电脑上的数据开始的,不需要那么多计算能力。但是很快你就会遇到超出你的本地 CPU 所能提供的需求。云是迄今为止更具可扩展性的进行机器学习的地方。您将获得最新的 GPU,甚至是您自己无法负担和维护的 TPU。
但是,当您的需求满足以下一些标准时,本地服务器场是一种有效的替代方案:
- 您需要 24/7 的计算能力(例如,由于大型团队或大型模型)
- 出于合规性或其他原因,您拥有不能离开数据中心的敏感数据
在许多情况下,混合解决方案也可能是可行的,其中初步模型测试在内部完成,生产就绪模型在更强大的云机器上开发,或者通过在推断之前尝试数百个不同的模型来开发。在大多数情况下,使用正确的工具,云是进行原型开发和生产就绪机器学习的最快方式。
在云中进行机器学习的三个主要原因:
- 灵活的资源使用以应对尖锐的硬件资源需求
- 只需点击一个按钮,即可访问最新的硬件
- 不受限于特定硬件的解耦架构
ML 云实施的最佳实践
在与数百家从事机器学习的公司合作后,我们已经看到了内部硬件和云计算的好处。关键要点如下:
- 云提供商之间存在差异,尤其是对于寻求数据隐私的企业而言,找到最适合您的提供商
- 确保您的数据与您要使用的计算位于同一个云数据中心。如果您的数据需要从世界各地的本地数据存储进行传输以进行计算,则大型数据集上的训练模型会变得很慢。如果您使用 AWS EC2 来最小化延迟等,请将您的数据存储在 S3。
- 对于结构化数据(数据库或 Spark 集群中的表格数据),使用预处理步骤,首先将数据转储到平面文件中。文件为数据库查询提供了持久层,从而在训练模型时提高了版本控制和可重用性。遵循“提取一次,无限训练”的黄金原则。
- 混合解决方案是一种最佳实践:如果你已经有本地硬件,不管是一个 Tesla V100 还是一个 Titan RTXs 的服务器群,都可以使用它们。向云的过渡不会一蹴而就,这很好。
- 获得一个机器学习平台,将硬件从数据科学家那里抽象出来。
- 让您的数据科学家专注于数据科学,而不是 DevOps 或 MLOps,无论他们使用哪种云或本地硬件。
最初发表于【https://blog.valohai.com】。
网络分析中的机器学习——谷歌分析变得更好了吗?
原文:https://towardsdatascience.com/machine-learning-in-web-analytics-has-google-analytics-changed-for-better-1419e187042f?source=collection_archive---------18-----------------------
谷歌分析 4 最近推出,它具有先进的机器学习能力。未来 5 年,ML 会统治网络分析的世界吗?
图片由 janjf93 来自 Pixabay
企业一直试图以更好的方式了解客户及其买家的旅程,以推动更好的转化率和增加终身价值 。而且,在当今世界,当买家的大部分旅程都在网上时,网络分析变得比以往任何时候都更加重要。
网络分析与机器学习能力结合在一起,对企业来说确实非常了不起。谷歌分析 4 已经在这条路上走了一英里。
在这篇文章中,我将谈论谷歌分析 4 以及新引入的机器学习功能如何更好地改变分析。
但在我们开始之前,让我们回顾一下机器学习是如何改变网络分析的!
网络分析中的机器学习
除非能够分离和处理,否则收集的数据毫无用处。随着网络用户数量的不断增加,网站间的平均流量也在不断增加。
在使用机器学习的大数据分析(BDA)出现之前,分析这些庞大的数据集是一件痛苦的事情。
大数据分析(BDA)
一篇名为《 关于将大数据分析整合到大洞察以创造价值的调查 》的研究论文提到了大数据分析的七个特征,具体如下:
BDA 的七个特征包括“量”(支持非常大的数据量)、“速度”(快速分析数据流)、“多样性”(支持不同种类的数据)、“准确性”(支持高数据质量)、“价值”(洞察和利益的价值)、“可变性”(支持不断变化)和“价”(支持数据的连通性)。
说到这里,我们大多数人都知道,两种最常见的数据分析算法是有监督的 ML 算法和无监督的 ML 算法。
对于一些不知道这两者之间区别的人来说,简单地说,这里有监督 ML 和非监督 ML 算法。
无监督方法/算法是自我学习模型,主要用于发现未检测到的信息/模式。
另一方面,监督 ML 算法采用已知的输入数据&该数据的已知输出,并使用该信息来训练模型,以便为全新的数据集生成合理的预测。
这两者结合在一起,已经完全改变了企业使用网络分析的方式,并且变得更好。
大数据分析在企业决策方面使用网络分析的重要性与日俱增。这相应地增加了机器学习算法在网络分析中的应用的紧迫性,用于价值创造和 有机业务增长 。
谷歌分析和机器学习
谷歌分析是网络分析领域的领导者,分析收集的两种主要数据类型是——用户属性/维度和事件。
企业一直在使用这些数据,通过更好地了解用户来优化网站数据。
在用户维度类别中,Google Analytics 收集的一些数据类型有— 年龄、性别、国家、设备型号/类别等。Google Analytics 收集的一些事件类型有— 搜索、选择内容、注册、点击、文件下载、首次访问等。
数以百万计的小型和大型企业使用谷歌分析以更好的方式了解他们的客户,并为他们创造更好的用户体验。
在网络分析中使用机器学习绝对不是一件新鲜事,但是在谷歌分析 4 中使用机器学习的方式是全新的!
多年来,人们已经在网络分析中使用机器学习功能,以更好的方式理解网络流量。
例如,我们之前已经了解过数据科学— 将 Google Analytics 命中级别数据发送到 BigQuery 和 自动将数据导入到 Google Analytics 。
除此之外,我们已经看到监督或无监督聚类如何帮助我们以更全面的方式理解 web 流量。
如果你不熟悉如何使用聚类——一种理解网络流量的机器学习技术,这里有一篇 Russ Thompson 的文章,可以帮助你获得基本的想法。
但当我们谈论在网络分析中使用机器学习时,你应该知道每个机器学习模型都需要几个元素来实现最大影响:
- 你需要你的 ML 模型来回答的问题。
- 准备数据馈入你的模型。人们更喜欢使用 R 从 Google Analytics 或任何其他来源收集网络分析数据。
- 评估您的 ML 模型的产出。虽然你可能理解 web analytics 中的机器学习模型产生的数据,但你必须实现数据可视化,以便管理层和非技术团队成员都能理解。
- 利用数据获得更好的投资回报。提高商业投资回报率是在网络分析中使用机器学习的核心原因之一。
但是,如果谷歌分析自己开始使用 机器学习 并通过以比以往任何时候都更容易理解的格式使用数据来展示见解,从而帮助你最大限度地利用它,会怎么样呢?好消息是——谷歌分析 4 正在这么做!
谷歌分析 4:机器学习如何改变谷歌分析?
2020 年 10 月,谷歌使 谷歌分析 4 在公共领域 可用。然而,类似的东西的测试版于 2019 年 7 月发布。
最初的想法是将应用和网络分析结合起来,从总体上激发 更好的营销 和业务投资回报率。
来源
在 Google Analytics 中测试机器学习的可用性 1 年多之后,Google 终于在测试期推出了 Google Analytics 4,即所谓的 App+Web Properties。
在 Analytics 4 之前,你可以问这样的问题:“上个月哪些产品的购买量超过了 100 次?”分析智能将使用其 ML 功能生成结果。
但下面是引入机器学习后,Google Analytics 4 的新功能。
实时监控流量
您现在可以用所有支持的语言提问,以实时生成结果。您可以使用属性“实时”来获取过去 30 分钟的分析数据。例如,你可以监控一天促销活动的网站/应用流量。
您还可以监控您正在开展的活动的即时效果,或者最近在您的网站或应用程序上所做的更改对其有何影响。
搜索即时答案
你可以用自然语言询问分析数据,以在谷歌分析 4 中获得即时答案。您可以指定属性、指标、时间范围或维度。
例如,您可以搜索 “亚利桑那州上周转化率” 或 “美国上周移动用户” 以获得报告、数据、见解等。
跨平台分析
“应用+网络属性”和现在的谷歌分析 4 的一个关键亮点是它能够通过结合你的网络和应用用户的数据向你展示洞察力。使用机器学习功能,Google Analytics 4 可以根据您选择的任何属性(指标、维度等)为您提供即时数据可视化。
您可以使用 Google Analytics 4 在您的用户漏斗中定义多达 10 个步骤,并清晰地可视化您的用户在每个步骤中是如何进入或退出的。这将帮助你找到对你的网络或 移动应用 用户来说什么有用,什么没用的答案!
智能提醒
如果您的网站或应用程序使用机器学习功能看到用户的显著增加/减少或您的网络/应用程序数据的变化趋势,新的 Google Analytics 4 会提醒您。
这些智能警报将帮助您在用户数量突然增加或突然减少时采取任何即时措施。此外,新的 Analytics 4 可以帮助您提前预测您的用户行为。例如,它可以让你预测特定用户群的收入——流失概率。
来源
谷歌信号
虽然谷歌信号并不新鲜,但在谷歌分析 4 中打开谷歌信号确实可以帮助你提高营销投资回报率,并采取措施进行 实时线索生成 。
例如,使用来自打开广告个性化的用户的谷歌数据,Analytics 4 在谷歌信号打开时生成更准确的用户计数报告。
这些只是在引入机器学习功能后,新的谷歌分析 4 中引入/改变的一些东西。话虽如此,Google Analytics 引入 ML 只是一个开始。
总的来说,机器学习在谷歌分析以及网络分析的未来中扮演着重要的角色。
机器学习在未来网络分析中的作用
你知道吗 微软 Clarity——微软 的网络分析工具将于 2020 年 10 月公开发售。
来源
虽然谷歌分析 4 和微软 Clarity 的全面比较尚未公布,但可以肯定地说,鉴于其分析应用数据的能力,分析 4 也优于 Clarity。
话虽如此,甚至微软 Clarity 也增加了机器学习功能,允许其用户使用“过量记录”、“死点击”等参数来过滤网站数据和会话记录。
网络分析中的机器学习绝对是未来,而且前景光明。随着自然语言处理的新进展,如谷歌的大鸟,机器学习肯定会彻底改变我们今天看待和使用网络分析的方式。
[## 理解大鸟——它是 NLP 的另一个重要里程碑吗?
谷歌研究人员最近在 arXiv 上发表了一篇题为《大鸟:更长序列的变形金刚》的论文。
towardsdatascience.com](/understanding-bigbird-is-it-another-big-milestone-in-nlp-e7546b2c9643)
谷歌和微软正式将先进的机器学习和人工智能纳入网络分析的好处是,它将使营销人员和企业更容易执行和衡量活动。
此外,它还将帮助 降低企业的营销成本 ,通过实时优化投资回报率,以及消除使用第三方人工智能/人工智能工具进行更智能的网络分析的需求。
[## 新发现的友谊的故事:艾、曼梯·里和疫情
这篇文章讲述了这个疫情如何给了人工智能-ML 阿朵急需的推动,以及这个新发现的…
towardsdatascience.com](/the-story-of-newly-found-friendship-ai-ml-and-the-pandemic-6ceb02376ebd)
机器学习对于保持家庭照明变得越来越重要
原文:https://towardsdatascience.com/machine-learning-is-becoming-increasingly-important-to-keep-your-homes-lit-7bd2e62ca2b?source=collection_archive---------58-----------------------
机器学习超越了图像分类和语音识别。了解为我们的家庭供电变得多么重要。
演职员表:作者修改自维基百科
你有没有想过,为什么每当你打开灯,它们就会工作?发电站怎么知道你要按下 3 中的开关..2..1…嗯,他们没有!每当你按下开关来点亮你的房间或打开空调,你就向整个电网发送振荡信号。对于一个灯泡来说,这些振荡可能微不足道,但当你考虑整个建筑一起被点亮时,它可能会在整个城镇的电网中发送电波——我们作为电力工程师,真的很担心这一点。如果这些波浪不停下来会发生什么?
演职员表:修改自维基百科
有什么问题?
作为一个孩子,这个问题对我来说似乎是一个更可怕的问题——当我跑向我的妈妈和爸爸,从黑暗中想象的幽灵手中拯救自己的时候。但是当我长大到可以攻读这个领域的博士学位时,我意识到它远不止于此。这个问题会让美国这样的国家每年损失 1500 亿美元。但是你认为问题出在哪里?— 如此庞大的电力系统的复杂性。不信你看下图。
演职员表: GENI
你能数出那些线吗?——肯定不是。这代表了美国互联电网。现在再想一想——如果你突然点亮一栋大楼,这样一个由输电线路和发电站组成的复杂网络将如何识别和处理我之前告诉你的电波,并满足你的电力需求?
当电网比现在小得多、简单得多、也不像现在这样互联互通时,传统的控制方法在控制电网方面已经被证明是成功的。然而,对于更复杂的系统,分布式私人发电,如太阳能和风能,不确定性被证明是这种稳定电网的传统技术的风险。
这就是机器学习的用武之地!
我非常确定,每当你听到 ML,你的脑海中就会浮现一些想法。
这是给计算机科学家的。
像谷歌和脸书这样的大公司使用这个。
它用于语音和图像识别。或许还能预测股票价值。
别担心,几年前我也戴着同样的帽子。当我听到 ML 和神经网络时,我不能想到任何其他事情。我承认,我也不明白,但不管是谁知道,他们对我来说都是神奇的神。但是我确信即使是上帝也不知道有一天我会在这个领域获得博士学位,而且我会喜欢这样做。
从现在开始,它可能会变得有点技术性,但我保证让每个人都能理解它,并为这个研究领域激发一些聪明的头脑。
电力系统最大似然研究的现状
美国现代电力工业始于 1879 年托马斯·爱迪生发明的第一只实用灯泡。很快,第一座集中式火力发电厂建成,并在纽约州投入使用。从那以后,很多事情都变了。公司从直流电(DC)转向交流电(AC)。更多的家庭,更多的工厂成为网络系统的一部分。直到大约二十年前,电网仍然主要由化石燃料供电。然而,可再生技术和其他替代发电资源的最新进展使得电网变得更加复杂,也为令人惊叹的新奇研究工作开辟了领域。我将试着强调几个我认为最令人兴奋的 ML 研究正在发生的主要领域——但是请注意,我向你保证还有更多!
广域监控系统(WAMS)
WAMS 由传感器、服务器和算法组成,它们在广域范围内发挥作用,就像完整的北美电网一样,保持系统的稳定性,这样你和我就可以在炎热的天气里继续操作我们的空调。在过去的十年中,安装了大量被称为相量测量单元(PMU)的快速采样传感器,从而实现了对整个系统的实时监测和控制。
[## 相量测量装置及其在电力系统保护和控制中的应用
本文简要介绍了相量测量单元(PMU)的概念。PMU 的起源可以追溯到…
link.springer.com](https://link.springer.com/article/10.1007/s40565-018-0423-3)
学分:环评
电网的庞大规模、大量的数据流以及由不同的功耗和太阳能和风能的渗透引起的系统中广泛的不确定性,对稳定此类系统的传统控制提出了挑战。因此,研究人员正朝着基于 ML 的控制和监控这种巨大系统的方向发展。
大量工作正在进行,以使用神经网络的通用函数近似(UFA)属性,通过从 PMU接收的大量数据来近似电力系统的未知动态。这不仅能够更好地洞察系统的特性,而且有助于做出实时和更明智的控制决策。这个问题不仅让控制理论家感兴趣,甚至大数据科学家和电力工程师也需要携手合作来解决这个庞大的问题。
演职员表: SlidePlayer
以图中所示系统的闭环控制为例。我们希望跟踪输入参考信号,然而,由于系统中的不确定性,传统的控制器无法提供理想的结果。另一方面,神经控制器,其基本上将误差信号( e )作为输入,并向系统输出致动信号。学习块通过使用期望的性能度量评估跟踪信号来评估该神经控制器的性能,并相应地调整神经控制器的参数。这在控制社区中也被称为“强化学习”,这是另一个被电力公司广泛采用的非常流行的研究。
不仅仅是针对神经网络,一般来说,在使用强化学习(RL)方面也正在进行一些令人惊讶的研究——这是 ML 和系统识别技术的应用,以解决这个具有挑战性的问题。如果你从来不知道这些术语也是 ML 的一部分,恭喜你!—你只需要知道 ML 有多多样化。
负荷预测
预测用电量对于有效的能源需求管理至关重要。糟糕的预测和不正确的决策不仅会给发电公司造成数百万美元的损失,还会让消费者几个小时没有电,导致业务和生产力损失。
传统的负荷预测方法依赖于时间序列分析和回归模型。这些模型在过去给出了令人满意的结果,但是最近它们的可信度和可靠性开始受到质疑。虽然这不是唯一的原因,但很大程度上是由于电网中大量可再生能源的涌入。
学分: Unsplash
这种可再生能源的发电不仅不确定,而且非常依赖的短期和长期天气预报。更麻烦的是,天气、国家节假日、最近电动汽车的繁荣等因素。使得准确预测变得更加困难。当被迫考虑如此大量的参数进行预测时,传统方法表现不佳。
演职员表:月亮、智勋和朴、成宇和罗、成民和黄、恩俊。(2019).建筑能耗预测的人工神经网络结构比较分析。国际分布式传感器网络杂志。15.
在过去的十年中,许多研究人员对使用复杂的 ML 结构解决这个复杂的问题产生了兴趣,例如使用神经网络的深度学习。Moon 等人的图显示了如何使用神经网络,使用各种信息作为输入,如日期、天气甚至节假日,来进行负荷预测。准确的负荷预测问题对电力工程师来说是如此迷人和关键,以至于研究人员研究了各种各样的 ML 技术,而不仅限于预测的深度学习。例如,一种流行的神经网络结构,称为长短期记忆(LSTM)框架,已被大量研究用于处理时间序列信息,以做出准确的短期负荷预测,这在电力公司的日常规划中变得非常重要。
[## 利用 LSTM 网络进行短期负荷预测
随着负荷需求的增加和电站的复杂化,提前了解电力系统的运行状况是非常必要的。
www.sciencedirect.com](https://www.sciencedirect.com/science/article/pii/S1876610219310008)
能源市场
演职员表: Pixabay
你可能听说过也可能没有听说过这个术语。本质上,能源市场是处理能源或电力贸易和供应的市场。对能源的投标在决定电力公司的利润方面起着重要作用。这个市场非常依赖准确的负荷预测。一般来说,大多数市场都有提前一天定价和实时定价。这取决于各种因素,如预期的能源成本、拥挤和传输损耗、可靠性等。运营商根据这些信息和他得到的报价,决定买卖能源和合适的价格。然而,这种定价的动态性高度非线性,运营商很难实时决定“最优”定价。
运营商依靠算法来为他们做出这个决定。机器学习,特别是被称为深度学习极值理论(DL-EVT)的深度学习框架正被广泛用于寻找非线性动力学的最优解,以便运营商做出购买或出售电力的最佳价格的决定。
智能电网
演职员表: Pixabay
如果你读过一些关于电学和最近研究的东西,你可能肯定听说过这个术语。智能电网基本上是一组分布在电网中的传感器和执行器,允许信息在消费者和电力公司之间来回流动。这种信息交换允许对电网进行自动实时控制,使其高度可靠和稳定。在线和实时做出决策的能力高度依赖于机器学习架构来做出最佳决策,以最小化成本约束,如传输损耗、稳定性约束甚至客户舒适度。
什么?—客户舒适度?怎么会?
一些公用事业公司通过传感器和致动器远程有效地控制它们的空调单元来控制大型建筑物的温度。这给了公用事业公司实时控制电网的某个部分的完全杠杆作用,以确保整个系统能够满足电力需求和稳定性要求,同时建筑物所有者看到他们的电费有很大折扣让公用事业公司控制。智能电网已经成为电力行业的一个重要方面,顶级研究人员和工业家称之为电力的未来。随着可再生能源、分布式能源(如电池储能、智能电网)的涌入,保持弹性和性能是前进的方向。猜猜看,这是一个热门的研究领域,尤其是对那些对大数据和机器学习感兴趣的人来说。
没有大数据科学家和 ML 工程师,智能电网的未来是不完整的。
[## 家庭- IEEE 智能电网
IEEE 的智能电网网站提供有关智能电网的信息、资源和专业知识。IEEE 已经在…
smartgrid.ieee.org](https://smartgrid.ieee.org/)
我希望你喜欢这篇文章,它让你对机器学习如何被广泛用于我们的电网有了深入的了解。如果它让你兴奋,那很好。如果它让你感到困惑,那就更好了——因为老实说,即使在这个领域做了两年的研究,我仍然不理解其中的许多内容!如果你想和我联系或问我任何事情,请发邮件到【jishnudeep.kar@gmail.com】或在insta gram上 DM 我。
如果你喜欢这个,你可能也会喜欢这些。
[## 从印度到美国的文化冲击——一个学生的视角
如果你计划去美国,并且对那里的文化太过好奇,这可能是你最好的剧透!
medium.com](https://medium.com/illumination/cultural-shock-visiting-the-usa-from-india-a-students-perspective-1f901df99984) [## 为什么我要辞去 7 万美元的工作,过“无聊”的生活?
在进入印度最负盛名的 IIT 德里学院后,我唯一的梦想就是获得高薪…
medium.com](https://medium.com/the-innovation/why-i-left-my-70k-job-for-a-boring-life-160129d42f21) [## 新冠肺炎会扼杀美国梦吗?
不,还没有结束。保持你的梦想。是时候和这个疫情战斗了,迎头痛击!
medium.com](https://medium.com/illumination/will-covid-19-kill-the-american-dream-daad8f6c5cea)
机器学习变得越来越容易。软件工程仍然很难
原文:https://towardsdatascience.com/machine-learning-is-getting-easier-software-engineering-is-still-hard-d4e8320bc046?source=collection_archive---------6-----------------------
意见
为什么这对软件工程师有利,对 ML 工程师不利
来自 Pexels 的 Andrea Piacquadio 的照片
免责声明:这是一篇观点文章。也有失偏颇。我认为,如果有更多的多面手和创造者(而不是专家)来制造东西和解决问题,这个世界会变得更好。
在过去的 5 年里,机器学习变得更加容易。同时,软件工程比以往更加复杂。
这对软件工程师来说是一件好事。但不适合 ML 专家。
这是 ML 向软件工程和数据科学向数据分析的进展。
机器学习工具变得越来越平易近人
谷歌很乐意让每个人都可以接触到训练 ML 模型,不管他们的技术知识如何(见:技术民主化)。
随着 ML 变得触手可及,云服务的市场也在增长,而理解算法的价值却在侵蚀。
从前,我们手工编写算法。然后 Sklearn 允许用几行代码做同样的事情。
最初的张量流很难使用。Keras 使它变得容易。
谷歌、微软和亚马逊现在都在云中提供选择、训练和调整模型的服务,然后立即在 API 后面提供模型。
要有人能训练人工智能还需要一段时间。但是随着复杂性的降低,它变成了经验丰富的软件工程师放在口袋里的另一个工具。
机器学习的发展集中在几种语言中
语言是一条护城河。句号。
你知道 COBOL 吗?如果是的话,你有一份终身工作。世界金融体系有赖于此。没有人再学习 COBOL 了。
大多数机器学习都是用 Python 实现的,而软件开发则分散在大量语言中。
https://www.tiobe.com/tiobe-index/
如果每个 ML 工程师都有 Python 经验,那么你就是在和每个 ML 工程师竞争。在软件方面,你只与使用相同技术的工程师竞争。
我总是惊讶地看到许多高薪的 Ruby on Rails 工作。它几年前就过时了,但是许多大公司(Shopify、Instacart、Kickstarter 等)因为传统原因还在使用它。
你完全可以也应该学习多种语言。成为一名优秀的软件工程师就靠它了。
软件工程包含更大范围的技能
我们期望软件工程师至少对所有的事情都有一些了解。
速写
后端工程师仍然知道浏览器是如何工作的。一个前端工程师有一些数据库的概念。两者都可以防止像 SQL 注入那样的安全漏洞。
对软件有一个整体的理解,更容易改变专业。它还让您能够构建端到端的解决方案。
广泛的技能组合使软件工程师更适合模糊的环境。随着需求的增加,软件工程师通常会转向数据科学。相比之下,数据科学家不太可能开发软件。
随着人们开始将 ML 视为硬编码条件逻辑的替代方案,我们将会看到更多的软件工程师从事 ML 工作。
成为一名合格的全栈开发人员需要数年时间
并且包含许多独立的技能。
优化数据库、构建 API 微服务和打造响应性前端毫无共同之处。它们可能用三种不同的语言实现。
我们在这些领域很少看到自动化。
相比之下,全栈 ML 工程师现在正在完成日益强大的 AutoML,为此我可以写一个 SOP,并委托一个实习生训练分类器。
软件工程技能组合中的所有部分自动化消失还需要一段时间。
机器学习是对产品的补充,而不是产品本身(通常)
少数公司将人工智能作为其核心产品,但大多数公司使用它来补充现有产品。
Medium 可能会使用机器学习进行文章推荐,但核心产品是写作/发布平台。
有趣的是,大多数公司将 ML 用于简单和相似的用例。这使得单个公司很容易将所述用例作为 SaaS 产品来提供。突然之间,创业公司不再需要在内部构建它了。
相比之下,像基础设施这样的问题就非常复杂和定制化。AWS 上没有现成的解决方案可以很快处理 Medium 的基础设施。
基础设施变得异常复杂
AWS 已经扩展到 200 多种不同的云服务。
Heroku 在云中运行应用程序的 PaaS 方法非常棒。但是在任何大规模下都变得非常昂贵。
因此,现在我们有一个全新的云堆栈需要管理(网络、数据库、服务器),其中的一个小失误就可能导致巨大的安全漏洞。
有一个完整的开发子集叫做“云工程”,其工作是让软件在 AWS、GCP 或 Azure 上工作。
在较小的公司中,基础设施通常落在高级开发人员的肩上。
这是复杂的东西。但这也意味着工作和难以复制的技能。
前端开发是不断发展的
独自站在前端开发的顶端是一种技能。
当我开始开发时,用 jQuery 构建响应性前端是可以的。然后公司开始转向 Angular 或 React。Angular 变成 Angular 2(带有突变)。React 从类转移到功能组件,并增加了挂钩。
所有上述框架/库的工作方式完全不同。
有几家公司正在研究基于实体模型的自动生成前端。但同事们一致认为,他们离生产质量还有很长的路要走。
前端开发中的技术能力,加上对完美的感觉,令人惊讶地感觉暂时是合理的。
结论
软件开发是复杂的,包含各种各样的问题。这种复杂性有利于就业。
但更重要的是,广泛的技能组合赋予了端到端解决实际问题的能力。
为了建立一个典型的人能够解决他们自己社区中的问题的社会,软件工程是一个很好的起点。
机器学习有一席之地吗?绝对的。但是解决问题不仅仅是训练一个模型
学软件工程。制造东西。解决问题。
机器学习并不总是数据问题的解决方案
原文:https://towardsdatascience.com/machine-learning-is-not-always-the-solution-to-a-data-problem-7f07c000f15?source=collection_archive---------48-----------------------
大数据和机器学习
概观
有人给了我一个很大的文件数据集,有人称之为大数据,并让我想出一个数据问题的解决方案。人们经常将大数据与机器学习联系在一起,并自动跳转到机器学习解决方案。然而,在处理了这个数据集之后,我意识到机器学习不是解决方案。这个数据集是作为一个案例研究提供给我的,我必须完成这个案例研究,这是一个 4 步面试过程的一部分。
任务描述
该数据集由一组跟踪多个建筑项目中的电子邮件活动的文件组成。所有数据都被匿名了。任务是探索数据集,并报告任何见解。我被告知,客户关心的是项目的持续时间和现场说明的数量,以及在项目中看到的变化,因为这些通常都要花钱。
数据 ETL
首先,通信数据被读入并附加在一起。对数据进行了重复检查。未找到重复项。
由于客户关心项目的持续时间,要求响应的日期和发送日期之间的差异是以天计算的。但是,有相当多的“要求响应日期”和“发送日期”值缺失。这些记录被排除在外;因此,数据集从 7 个变量的 20,006,768 条记录减少到 3,895,037 条。然后,将通信数据与邮件类型文件相结合,以确定通信类型是否对持续时间有影响。最后,合并一个包含每个项目记录数量的文件。
通常,在没有正当理由的情况下排除数据不是好的做法;然而,由于该数据集是作为工作申请流程的一部分分配给我的,我没有机会更好地理解该数据集以估算日期。
正如您可以从下面导入数据集的代码中看到的,除了项目 ID、记录数、类型 ID 和类型名之外,我们没有太多关于电子邮件的信息。
作为大量的。csv 文件必须从单个目录读入,我使用 lapply 和 fread 函数读入文件,并使用 rbindlist 追加文件列表。
将统一数据集对象保存为 R 对象是一种很好的做法,这样可以避免以后必须重新运行导入代码,因为根据文件的数量,此过程可能会非常耗时。
特征工程
创建了新的变量来理解项目持续时间。这些是以天为单位的持续时间,以及项目是否在日期要求的响应后提交。如果是,那么就是晚了,否则就是早了或者准时了。
然后将唯一的通信数据集连接到通信类型 ID(主键)上的邮件类型文件。这后来被加入到项目 ID 的主文件中。
加入后,我的初步见解如下:
- 通信 id 是唯一的,因此不需要汇总,也不会有助于分析。
- 有太多的组织 id,没有合理的方法对它们进行分组,因此将排除作为预测器。
- 有太多的用户标识——不是一个有用的预测器,尤其是一些只有 1 的频率计数。也被排除在预测因素之外。
为了为每个通信 ID、项目 ID 和类型名创建一个唯一的行,我需要聚集其他特性。我通过计算延迟提交的次数或计数、早期提交的次数以及计算汇总统计数据(如最大值、最小值和平均持续天数)来实现这一点。
系统模型化
对数据进行分组将 7 个变量的数据集大小减少到 51,156 个观察值。目前的样本量太小,但是,由于错过了回复日期,大部分数据都减少了,包括每个项目 ID 的每条记录将是每个组织和用户 ID 的比较。客户似乎对现场说明和变更感兴趣,这可能在通信类型 ID 和类型名称中找到,而项目 ID 中的数据对于任务要求来说太细了。
我们确实有一个问题,我们不知道每个 ID 代表什么,以及它是否重要。
运行两种类型的模型:
GLM(高斯)用于确定可能对平均持续天数的增加或减少产生影响的最佳预测值的线性组合。
运行 GBM(高斯)来再次确定最佳预测值以及它们与平均项目持续时间(天数)的关系
运行多个模型是一种良好的做法,以确保选择具有更高准确性和可解释性的模型。
我首先使用随机拆分将数据集划分为训练集(70%)和测试集(30%)。回想起来,我可以按日期分割模型,以确定我的模型在预测未来平均持续时间方面的表现。
由于我的笔记本电脑速度很慢,我使用了 H2O 软件包中的 glm 和 gbm 函数来利用该软件包提供的并行处理云服务器。我对我的训练集进行了五重交叉验证。在这种方法中,训练集被分成 5 个等价集。在每一轮中,一组用作测试组,所有其他组用于训练。然后在剩余的四组上训练该模型。在下一轮中,另一组被用作测试组,剩余的组被用于训练。然后,该模型计算测试集上五个模型中每个模型的准确性,并提供平均模型准确性度量。
glm 模型的输出如下所示。对于连续的目标变量,RMSE 和 R 平方通常用作精度度量。我们希望 RMSE 尽可能接近 0,R 平方值尽可能接近 1。在我们的例子中,我们可以看到,对于这两个指标,我们的模型精度都很糟糕。
现在,让我们看看 gbm 的输出。这个模型的结果稍微好一点,但没有什么值得夸耀的。
结果显示,在模型中输入的 1500 个预测因子(1500 个是由于分类变量的二元化)中,有 672 个预测因子具有一定程度的影响。尽管模型可以选择多次运行以产生最佳输出,但只运行了 2 次迭代。这样做的原因是因为在两次迭代后达到了λ的最佳值,给出了 0.38% R 平方的差模型准确度分数(拟合优度分数)。
虽然平均记录数在 glm 中不是一个重要的预测因子,但在 gbm 中它似乎是最重要的,其次是通信类型和类型名称。
由于两个模型的低精度,我不想从输出中做任何扣除。
我决定通过绘制最佳预测值来进一步研究输出。从下面的方框图中,我们可以看到,与持续时间通常接近于零的电子邮件和传真相比,PM 审批请求样本的平均持续时间最长,变化也最大。
在下面的方框图中,我们可以看到付款索赔的平均持续时间比设计查询和不符合项通知的平均持续时间长。
结论
模型的质量取决于数据质量及其特征。在这种情况下,我们从非常少的要素开始,并且对数据集的理解非常差,这导致尽管进行了一些要素工程,但还是移除了大部分数据集和较差的模型准确性。
在本例中,我们发现,仅仅探索数据集就可以回答企业提出的问题,即什么影响项目持续时间,付款持续时间和 PM 审批请求示例会导致持续时间增加。
每个项目的站点说明和变化的数量可以通过项目 ID 和类型名计算频率来再次探索。
这是一个不需要预测模型的例子。为了构建精度更高的模型,需要额外的要素/数据集以及对数据集的更好理解。
我很想听听你的想法,以及我是否可以用不同的方式处理这个问题!😃
所有代码都可以在这里找到:https://github . com/shedoedatascience/email _ analysis/blob/master/email _ analysis _ documentation。Rmd
机器学习就是股票。建立无监督的公司分类。
原文:https://towardsdatascience.com/machine-learning-is-stocks-pre-processing-for-unsupervised-company-classification-8f35ce8343f?source=collection_archive---------65-----------------------
亨尼投资
实现有意义的公司集群所需的数据探索和处理
图片作者新非洲
这篇文章的想法是建立一个新的,数据驱动的公司分类基于他们的财务状况,而不是他们做的业务类型。
这项研究的前提是基于这样一个想法,即值得购买的优秀股票在同行中会更优秀。在这种情况下,我将同行群体定义为具有相似财务结构(例如,小市值、大量债务、盈利)的一组公司。
如果你没有读过介绍,我建议你在这里读一下我为这项研究写的前言:
- 机器学习就是股票。重新定义公司集团
加快速度
在上一篇文章中,我选择了 5 个维度来定义公司的财务结构:
- 盈利能力——捕捉公司是否赚钱
- 总资产——捕捉公司规模
- 负债权益比——捕捉融资结构
- 营业利润——捕捉盈利的难度
- 每股收益增长(EPS) —捕捉逐年增长
我还确保了这些维度是独立的。这是一个重要的考虑因素,因为我想衡量一家公司在各个独立领域的表现,而不考虑它在其他领域的表现。这是我之前展示过的 Spearman 相关图:
来自 Vhinny 的财务数据
数据探索
在我进入集群之前,让我们评估一下这 5 个特性的分布。理解分布对于选择合适的聚类算法至关重要。它还会显示出我将在预处理过程中处理的数据中的潜在流。
以下是所有五(5) 特征在单一图上的分布:
选择功能的分布
X 轴显示每个特征的值。 Y 轴显示落入每个对应箱的公司数量。对于这项分析,每家公司都在 2019 年报告了一次财务状况。本研究中使用的公司总数约为 4,000 家。
有几个观察可能会引起人们的注意:
- 负债转股
- 高得惊人的比例债务对股权低于 0.5
- 资产和债转股的偏态分布
负债转股并不常见,但也是可能的。虽然债务不能为负,但如果总负债超过公司总资产,权益可以为负。
偏斜分布也可以,只是我们在选择聚类算法时必须记住这一点。一些算法依赖于正态分布的假设,这在这里不成立。
大多数低于 0.5 的债务权益比率确实令人担忧。许多上市公司严重依赖债务融资,债务融资往往超过股东权益。经过进一步的研究,我在这个特性中发现了许多 0,表明在数据提取过程中存在潜在的流动。纵观我选择的所有特征,除了盈利能力,我认为它们都不为零。
用空值代替所有的 0 后,我们看到债务与股本比率发生了显著变化。其他功能没有受到显著影响:
选择功能的分布
该图与之前的图相同,除了深蓝色图表仅使用非零值构建。将蓝色图表放在红色图表之上,唯一明显的区别是债转股的特征。我会相信蓝色前进,依靠我的商业意识。
选择聚类算法
聚类练习一般是一半艺术,一半科学。因为没有一致的度量来评估算法的性能,所以在找到可行的解决方案之前,经常尝试许多算法。虽然一些距离测量可以用于比较,但它仍然是相当抽象的。流行的聚类方法的一个很好的概述可以在这里找到。
我为这项研究选择的方法是 K-means 聚类,因为它的计算效率、 O(n) 和相对简单的配置。我要做的唯一决定是关于簇的数量,它可以通过实验以一种非常简单的方式确定。
集群前的最后步骤
在数据探索阶段,我们已经看到了资产和债转股特征的偏态分布。由于 K-means 算法是基于寻找数据中的最优均值,因此偏态分布是危险的,因为异常值可能会不可控地将这些均值拉向自己的方向。
处理这个问题的一个方法是去除异常值。由于 4,000 个示例并不是过多的数据,因此删除数据点是不可取的。相反,我可以在分布中强制执行最大值和最小值以减小它们与平均值的距离。
一种方法是使用分位数和四分位间距来限定分布中的最小和最大值。在这种情况下,我使用了
- Q1-3 * IQR 封顶分钟
- Q3+3*IQR 到上限最大值
其中 Q1 和 Q3 以及第一个(25%)和第三个(75%)分位数和 IQR 是四分位间距。我为 IQR 任意选择了 3 的倍数,以保持上限相对远离中间值,从而不会显著扰乱原始分布。
下面是此操作的示例代码,以更好地说明这种方法。
此封顶过程应用于数据集中的所有要素。资产和债务对权益比率的最终分配如下所示:
原始分布尾部封顶的效果
后续步骤
本分析的数据探索和预处理阶段到此结束。在下一篇文章中,我将根据数据确定最佳的集群数量,并确定公司的特征。
顺便说一下…🤚
我们连线吧!
我很高兴与那些和我分享通往财务独立之路的人联系。如果你也在寻求经济独立,或者你想与人合作,交流想法,请联系我们!以下是一些可以找到我的地方:
- www.vhinny.com—投资研究平台,为您自己的分析提供金融数据
- https://www.linkedin.com/company/vhinny——加入我们 LinkedIn 上的社区,在那里我和其他贡献者分享与投资相关的内容
干杯!
深入研究支持向量机
原文:https://towardsdatascience.com/machine-learning-iv-support-vector-machines-kaggle-dataset-with-svms-57d7c885652a?source=collection_archive---------47-----------------------
以及用支持向量机求解的 Kaggle 数据集
内容
在本帖中,我们将介绍:
(一)支持向量在支持向量机中的作用
(二)支持向量机的成本函数
(iii)支持向量机作为大幅度分类器
(iv)在核的帮助下通过支持向量机的非线性决策边界
(v)使用支持向量机的欺诈性信用卡交易欺诈数据集检测
在之前的帖子中,我们仔细研究了机器学习中的高偏差和方差问题,并讨论了正则化以及其他一些技术如何在解决这些问题中发挥重要作用。在本帖中,我们将详细了解另一种被称为支持向量机的监督学习算法。在本帖的后面,我们将解决一个 Kaggle 数据集,以检测使用 SVM 的欺诈性信用卡交易。
支持向量机(SVM)
SVM 是一种受监督的机器学习方法,解决回归和分类问题。然而,它主要用于分类问题,其中它在 n 个特征维度中构造超平面。n 维特征空间有一个 n-1 维的超平面。例如,在具有两个特征的数据集中(二维特征空间),由 SVM 构建的超平面是曲线(直线、圆等)。)如果我们正在解决两个类的分类问题,那么 SVM 分类器的工作是找到使两个类之间的间隔最大化的超平面。在我们了解支持向量机的工作原理之前,我们先来了解一下支持向量机这个名字的由来。
SVM 在行动(来源
什么是支持向量?
我们知道 SVM 分类器为分类构建超平面。但是 SVM 分类器是如何构造超平面的呢?让我们通过只考虑两个类来发展直觉。我们知道超平面必须从两个类中间的某个地方通过。这些类之间的良好分离通过超平面来实现,该超平面与来自两个类的最近训练数据点具有最大距离。在旁边的图中,标记每个类的极端的 2 条虚线构成了每个类的支持向量。这些支持向量有助于在它们的支持向量的帮助下找到最大化超平面与两个类别中的每一个的距离(余量)的超平面。
支持向量机的工作原理
支持向量机可以拟合线性和非线性决策边界作为分类器,并且与逻辑回归相比,支持向量机的主要优势之一是,由于成本函数大大简化,它们可以快速计算训练参数。
价值函数
让我们回忆一下逻辑回归中用于二元分类的二元交叉熵代价函数。这里,为了简化起见,我们将忽略偏差项,因此我们通过逻辑回归对总共“m”个训练示例中的第 I 个训练示例进行的最终预测将表示为 h(x(i)) = sigmoid(W * x(i))
这个成本函数可以分为两部分:当 y(i) = 1 时,项(1-y(I))* log(1-h(x(I)))变为 0,当 y(i) = 0 时,项 y(i)*log(h(x(i))变为 0。这些方程(成本对 W * x)的对应图表(不包括正则项,因为它对两者都是通用的)是:
SVM 使用了这个成本函数的轻微修改,这提供了它比逻辑回归计算的优势。对于 y = 1 的情况,我们看到,当 W * x >= 1 时,成本函数的所有值都更接近于 0,当 W * x < 1, the -log(h(x)) function values are approximated by a straight line by calculating the derivative of the cost function when W * x = 0. Similarly for the case y = 0, we see that the cost function has all its values closer to 0 when W * x <= -1 and when W * x > 1 时,通过计算 W * x = 0 时成本函数的导数,log(1-h(x))值由直线近似。
现在,由于我们不再使用对数成本函数,让我们将逻辑回归成本函数中的对数部分重命名。我们把 -log(h(x))换成 cost1(h(x)) ,把 -log(1 — h(x))换成 cost0(h(x)) 。我们在这里忽略常数(1/m ),因为它不影响我们的最小化目标,并有助于我们简化计算。因此,支持向量机的最终成本函数如下所示:
这导致成本函数的以下数学等式:
与输出概率值的逻辑回归不同,支持向量机输出 0/1。当 h(x) >=1 时,SVM 输出 1,当 h(x) <= -1, the SVM outputs 0. In logistic regression, we saw that when h(x) > 0 时,输出为概率> 0.5,四舍五入为 1,当 h(x) < 0, the output was a probability < 0.5 which was rounded-off to 0. The range of (-1, 1) is an 时,额外的安全系数允许支持向量机做出比逻辑回归更有把握的预测。
现在让我们稍微重新参数化一下成本函数。目前,我们的成本函数是 A + λB 的形式,其中 A 是成本函数,B 是正则项。我们把它转换成 CA + B 的形式吧,这里 C 的作用类似于 1/λ。
SVM 作为一个大幅度分类器
前面,我们读到了支持向量在寻找一个超平面中的作用,该超平面作为一个分类器,与两个类中的每一个都有最大的距离。这种分类器被称为大幅度分类器。大范围分类器是以更大的置信度预测给定数据点的类别的分类器。逻辑回归的情况并非如此。让我们看看为什么这种情况会发生在 SVM 身上。
我们将 SVM 成本函数重新参数化为 C*A + B ,其中 A 是与 SVM 输出(成本分量)相关联的损失, B 是正则化项(正则化分量),并且 C 起到类似于 1/λ的作用。当我们选择 C 非常大的时候,那么我们的模型就容易过拟合。为了应对这一点,我们希望 A 应该接近零,否则将会有不希望的巨大成本。由于 A 的值与参数 W(在图中用‘θ’表示)成正比,这意味着参数本身将具有非常小的值。因此,在 C 较大的情况下,优化目标只是找到 B 中出现的训练参数的最小值。正式定义,这种情况下的最小化目标是:
在 SVMs 的实现中,使用向量化,并且计算向量 W(图中的“θ”)和特征向量(X)的点积。从矩阵乘法的知识中,我们知道当计算两个向量(假设 u 和 v 的点积时,我们得到向量 u 在向量 v 上的投影。同样,当计算 W 和 X 的点积时,我们得到矢量 X 在 W 上的投影,并且投影的长度( P )等于
其中||thetha||是θ的 L2 范数。这个等式可以表示为:
因此,最小化目标可以重新表述如下:
现在让我们举个例子来看看这个最小化目标是如何在 SVM 产生大幅度分类器的。
考虑下面的二元分类问题,其中“X”表示特征 x1,“O”表示特征 x2。根据我们当前的优化目标,我们知道只有当 p.||theta|| <= -1 for y = 0 (x1) and p.||theta|| > = 1 且 y = 1 (x2)时,SVM 才能最小化成本函数,即训练样本的投影和参数向量之间的角度分别在 900–1800°和 2700–3600°之间。
在下图中,考虑左图(绿色)中的决策边界。参数向量(θ向量)与其垂直,因为参数向量右侧的区域具有 900–1800°的角度,而决策边界左侧的区域具有 2700–3600°的角度。对于这个决策边界,我们看到训练样本(用红色和粉红色表示)的投影长度相当小。在这种情况下,为了满足 p . | |θ| |<= -1 for y = 0 (x1) and p.||theta|| >= 1(x2)的条件,θ需要具有大的值。因此,成本函数的值并未最小化,因此左侧图像中以绿色表示的决策边界不会被 SVM 选择。
现在,考虑下图右边的决策边界(绿色)。对于相同的训练示例,我们看到它们在参数向量上的投影与之前的决策边界相比更大。现在为了满足 p.||theta|| <= -1 for y = 0 (x1) and p.||theta|| > = 1 (x2)的条件,我们已经有了一个很大的投影向量值‘p’。这意味着小的θ值就足够了,这反过来也最小化了成本函数。因此,右图所示的决策边界最有可能被 SVM 选择用于二元分类任务,通过比较两个决策边界,我们可以清楚地看到,SVM 选择的分类器确实是一个大间隔分类器。
让我们记住,当 SVM 方程 C*A + B 中的参数 C 非常大时,证明了我们上面得出的结论。当 C 的值很小时,我们可以得到类似的结果,因此我们推广了这一说法。我鼓励读者思考这个问题。这将有助于进一步阐明 SVM 背后的数学原理。
非线性决策边界的 SVM
到目前为止,我们已经看到了 SVM 被用作具有线性决策边界的分类器的场景。SVM 使用内核方法来完成这项任务。在讨论核方法之前,让我们理解为什么复杂的多项式特征不适用于非线性 SVM 分类。让我们借助线性回归对它有一个直观的认识。
在线性回归中,对于具有“n”个输入特征的训练数据,我们将输出表示如下:
y = W1x1 + W2x2 + W3x3 + ………+ Wnxn。
对于“m”个训练示例,我们得到的输出是一条直线。那么,我们怎样才能得到一个非线性的决策边界呢?我们知道,次数大于 1 的多项式会产生非线性输出。但是使用这些多项式作为输入特征存在以下问题:
(I)对于小至 5 个特征的数量,有无数种选择特征的可能性。输出的示例表示可以是 y = w1x 1+w2x 2 x3+w3x 1 x4 X5+w4x2x 4+………(可能有几吨)。请记住,5 次多项式不需要具有 5 次多项式的所有特征。
(ii)对于如此复杂的特征表示,不能直观地确定决策边界,这使得难以调整特征以获得更好的结果。
(iii)此外,计算这些复杂的特征在计算上非常昂贵,因此是不期望的。
核心方法
由于上述非线性分类器的多项式特征向量的所有缺点,SVMs 通过结合使用核方法提供了一种非常智能和有效的方法来生成非线性决策边界。内核的神奇之处在于找到一个函数,避免了高维计算所隐含的所有麻烦。在机器学习中,核方法是一类用于模式分析的算法,其最著名的成员是支持向量机。内核方法需要用户指定的内核,即原始表示中成对数据点的相似性函数。核方法优于特征向量,因为它们在计算复杂的非线性决策边界时大大减少了计算时间。内核方法的输出是一个标量。
在这里,虽然我们将核的使用限制在 SVM,但需要注意的一件重要事情是,可以使用点积表示的每个机器学习算法都可以用核来代替。然后,我们可以使用这些带有内核的机器学习算法中的任何一种,这两种算法都能提供更快、更好的结果。尽管有不同类型的内核方法,我将使用高斯内核做进一步说明。
生成非线性决策边界
如果内核不进行如此复杂的计算,那么它们是如何生成如此好的非线性决策边界的呢?为训练示例定义一些界标,并且使用相似性函数(内核)使用每个定义的界标来计算每个示例的相似性。训练样本 xi 和地标 lj 的高斯核或高斯相似度函数表示为 exp(-||xi — lj||2 / 2σ2) 。由此,我们可以看到,对于靠近地标的训练示例 xi ,其特征值 fi 接近 1,而对于远离地标的训练示例 xi 其特征值接近 0,这似乎是相似性的良好度量。
使用高斯核计算的相似性值被认为是各个训练示例的新特征值,然后可以将其与它们的权重参数(W/θ)相联系,以计算最终的输出类别。在帖子的前面,我们看到最小化目标受制于权重向量和输入特征向量的点积> =1 或<= -1. After computing the new feature values using kernels, the conditions of the optimization objective change a bit. Although the inequality values remain the same, the dot product is now computed between the weight vector and the new feature vector computed using Gaussian kernel. Just to clarify, although the output of the kernel method is a scalar value, that scalar value is computed against a single landmark. Against L landmarks, L values are computed which then form a feature vector for a given training example.
Minimization objective when C > > 1 的条件,并且使用了核方法
考虑一个训练数据集(具有 2 个仅用于演示目的的要素),该数据集具有 2 个没有线性决策边界的输出类。让我们看看在训练集上定义几个界标(假设 3 个)如何帮助解决非线性决策边界。在下图中,我们看到,对于粉红色的训练示例 X,与地标 L2 和 L3 相比,它非常接近地标 L1。对于这个例子,使用高斯核计算相似性,我们得到对应于 L1 的特征值 f1 接近 1,对应于 L2 和 L3 的特征值(f2 和 f3)接近 0。根据上面的等式,我们预测一个当θ* f > = 1 时。现在,如果对应于这些特征的θ值是 2、0.5 和 1,则 21 + 0.50 +1*0 = 2 即> = 1。对多个训练示例执行相同的步骤给我们提供了具有高精度的适当的非线性决策边界。
选择地标
我们看到了界标结合核方法如何帮助定义支持向量机中复杂的非线性决策边界。现在,选择地标的明显问题出现了。选择标志的一种方式是将所有训练示例转换为标志,然后通过使用高斯核计算训练示例和每个标志之间的相似性来计算每个训练示例的特征向量。
地标测绘训练示例
一旦选择了这些标志并且计算了这些新的特征向量,最终的优化目标被修改为:
其中 f(i)表示使用高斯核计算的新特征向量。这里要注意的一点是,特征向量的数量(n)将等于训练样本的数量(m ),因为每个训练样本都是地标。
计算权重参数
在线性和逻辑回归中,我们看到了如何使用梯度下降来计算权重。我们不能使用原始形式的梯度下降来计算支持向量机的最优权重参数,因为 SVM 中的成本函数在所有点上都不可微。因此,为了计算 SVM 的权重参数,使用了梯度下降的一些变体,如亚梯度下降,甚至各种复杂的算法。次梯度下降中的权重更新看起来像:
W = W — alpha * subgradient_wrt_W(J),其中“alpha”是学习率。
求解次导数不像偏导数那么简单,需要我们很好地理解极限和不等式。斯坦福大学的这份 pdf 文件的前 2 页是一个很好的资源,它会给你一个如何计算次导数的直觉。
一旦计算出分类任务的最佳权重参数,我们就可以运行 SVM 分类器,计算训练和测试精度,以评估模型的性能。
在这篇文章中,我在 coursera 上教授支持向量机时使用了 Andrew NG sir 的各种例子,以及我提供直觉的能力。如果你有时间的话,我推荐你去看看他开设的机器学习课程。
到目前为止,我们已经了解了很多关于支持向量机的知识。我们从支持向量的作用开始,然后深入理解 SVM 的成本函数如何隐含地倾向于大间隔分类器,随后使用核技巧来计算非线性决策边界,通过各种示例使事情易于理解。最后,我们了解到普通(普通)梯度下降在计算权重参数时是如何不起作用的,因此需要使用次梯度下降。学了这么多之后,现在是时候将我们的注意力转移到信用卡交易 Kaggle 数据集上,以巩固我们的概念并了解 SVM 的运行情况。
问题陈述
在本节中,我们将使用 SVM 来确定欺诈性信用卡交易。这个问题的数据集可以在这里找到。这里需要注意的一点是,该数据集的特征已经作为 PCA(主成分分析,我们将在后面的帖子中看到)转换的结果进行了计算。它有两方面的帮助:
(I)维护用户数据的机密性。
(ii)由于 PCA 变换,数据集中的特征相互独立。
让我们从将数据集作为数据帧加载到内存开始。
import numpy as np
import pandas as pd
import matplotlib.pyplot as pltfrom sklearn import preprocessing, svm
from sklearn.metrics import confusion_matriximport os
for dirname, _, filenames in os.walk(‘/kaggle/input’):
for filename in filenames:
print(os.path.join(dirname, filename))
df = pd.read_csv(“/kaggle/input/creditcardfraud/creditcard.csv”)
df.head()
数据集有 31 个列/特征,其中 28 个是通过 PCA 变换计算的,其他特征只是数字特征。现在让我们看看欺诈性和非欺诈性交易在数据集中是如何分布的。
print(df[‘Class’].value_counts())
与 284315 笔非欺诈性(0)交易相比,有 492 笔欺诈性(1)交易,这是一个很大的偏差。显然,我们需要对我们的数据进行重新采样,否则我们可以通过简单地将每个交易预测为 0(非欺诈性)来实现高准确性。
print(“Accuracy by predicting all transactions as non-fraudulent: “ + str((284315 / (284315 + 492)) * 100) + “%”)
因为所有的欺诈交易都被忽略了,所以这样的系统没有用。我们需要等量的欺诈性和非欺诈性交易进行训练,以便更好地捕捉这两种交易的特征。首先,让我们从“时间”和“金额”两个方面来分析欺诈交易数据。
df_fraud = df[df[‘Class’] == 1]
plt.figure(figsize=(15, 12))
plt.scatter(df_fraud[‘Time’], df_fraud[‘Amount’])
plt.title(“Fraudulent transactions”)
plt.xlabel(“Time”)
plt.ylabel(“Amount”)
plt.show()
在任何时候,我们都有一些欺诈性交易,在预测它们时,时间是一个不相关的因素。此外,从上图可以看出,大多数欺诈交易的金额都非常小。
df_huge_fraud_amounts = df_fraud[df_fraud[‘Amount’] > 1000]print(“Number of fraudulent transactions over the amount of 1000 are: “ + str((df_huge_fraud_amounts.shape[0])))
给定的数据集表明这些特征是使用 PCA 变换计算的,因此它们应该是相互独立的。让我们通过计算特征之间的相关性来检查是否是这种情况。
import seaborn as snsplt.figure(figsize = (15, 12))
df_correlation = df.corr()
sns.heatmap(df_correlation)
plt.title(“Heatmap representing correlations”)
plt.show()
热点图的对角线代表最高的相关性(接近 1.0),即要素与其自身的相关性。其他特征对之间的相关性具有-0.2 到 0.2 之间的值,这对应于非常小的相关性。这表示所提到的特性实际上是相互独立的,因此没有一个特性可以基于它们之间的依赖关系而被删除。
由于与非欺诈性交易相比,欺诈性交易的总数太小,我们需要对数据集进行重新采样。通过应用过采样,我们重复欺诈交易,直到它们在数量上接近非欺诈交易。通过应用欠采样,我们消除了一些非欺诈性交易,因此非欺诈性交易的最终数量与数据集中的欺诈性交易大致相同。通过对此数据集应用过采样,训练数据集将变得巨大(284315 个非欺诈性交易,相比之下只有 492 个欺诈性交易),因此我们使用欠采样。
df_train = df[:200000]
df_train_fraud = df_train[df_train[‘Class’] == 1]
df_train_not_fraud = df_train[df_train[‘Class’] == 0]print(df_train_fraud.shape[0]) # 385
由于有 385 个欺诈交易,我们将把非欺诈交易减少到这个数字左右,以使每种交易的训练示例数量相等。
df_sample = df_train_not_fraud.sample(400)
df_train_final = df_train_fraud.append(df_sample)
df_train_final = df_train_final.sample(frac = 1).reset_index(drop = True)df_train_final.head()
我们现在可以看到“Class”列既有 0 也有 1。我们从数据集中抽取了前 200,000 个样本,并从总共 284,315 笔非欺诈交易中随机选择了 400 笔(接近 385 笔)非欺诈交易。因此,我们已经成功地实现了欠采样,并且我们的最终训练集包括 785 个训练样本。欠采样会导致数据中一些重要特征的丢失。但是首先,让我们看看应用 SVM 分类器得到的结果。现在让我们将数据分成训练集和测试集。
X_train = df_train_final.drop([‘Time’, ‘Class’],axis=1)
y_train = df_train_final[‘Class’]X_train = np.asarray(X_train)
y_train = np.asarray(y_train)df_test = df[200000:]
X_test = df_test.drop([‘Time’, ‘Class’],axis=1)
y_test = df_test[‘Class’]X_test = np.asarray(X_test)
y_test = np.asarray(y_test)print(df_test[‘Class’].value_counts())
我们看到测试数据集包含 107 个欺诈交易。如果 SVM 分类器在非欺诈性交易上表现相当好,并且还可以检测到许多这些欺诈性交易,我们可以说我们的模型做得相当好。
classifier = svm.SVC(kernel=’linear’)
classifier.fit(X_train, y_train)
predictions = classifier.predict(X_test)
现在,我们已经对训练数据集应用了 SVM 分类器,并将测试数据集的预测结果存储在“预测”变量中。为了评估模型的性能,让我们绘制混淆矩阵并确定以下内容:
(i) 真正:原始输出类为正例(此处为非欺诈交易),预测输出类也为正例(此处为非欺诈交易)。
(ii) 误报 : 原始输出类是正例(此处为非欺诈交易),但预测输出类是负例(此处为欺诈交易)。
(iii) 假阴性:原输出类为负例(此处为欺诈交易),但预测输出类为正例(此处为非欺诈交易)。
(iv) 真否定:原始输出类是否定示例(此处为欺诈交易),预测输出类也是否定示例(此处为欺诈交易)。
对于一个银行系统来说,如果一些非欺诈性交易被检测为欺诈性交易,他们会进行调查,但如果欺诈性交易被标记为非欺诈性交易,那么这可能会导致巨大的损失。因此,我们的目标是尽可能地减少假阴性的总数,同时也尽量降低假阳性的数量。现在,让我们画出混淆矩阵。
import itertoolsclasses = np.array([‘0’,’1'])def plot_confusion_matrix(cm, classes,title=’Confusion matrix’, cmap=plt.cm.Blues):
plt.imshow(cm, interpolation=’nearest’, cmap=cmap)
plt.title(title)
plt.colorbar()
tick_marks = np.arange(len(classes)) plt.xticks(tick_marks, classes, rotation=45)
plt.yticks(tick_marks, classes) fmt = ‘d’
thresh = cm.max() / 2. for i, j in itertools.product(range(cm.shape[0]), range(cm.shape[1])):
plt.text(j, i, format(cm[i, j], fmt),
horizontalalignment=”center”,
color=”white” if cm[i, j] > thresh else “black”)plt.tight_layout()
plt.ylabel(‘True label’)
plt.xlabel(‘Predicted label’)cm = confusion_matrix(y_test, predictions)
plot_confusion_matrix(cm,classes)
混淆矩阵有
(一)81746 真阳性
㈡3224 次误报
㈢11 次假阴性
㈣96 张真正的底片
由此,我们可以得出结论,大多数欺诈性交易都已被捕获,只有 11 个交易被错误分类,这比我们之前在解决此问题时讨论的产生极高准确性但没有捕获任何欺诈性交易的模型要好得多。
print(‘Total fraudulent transactions detected: ‘ + str(cm[1][1]) + ‘ / ‘ + str(cm[1][1]+cm[1][0]))
print(‘Total non-fraudulent transactions detected: ‘ + str(cm[0][0]) + ‘ / ‘ + str(cm[0][1]+cm[0][0]))print(‘Probability to detect a fraudulent transaction: ‘ + str(cm[1][1]/(cm[1][1]+cm[1][0])))
print(‘Probability to detect a non-fraudulent transaction: ‘ + str(cm[0][0]/(cm[0][1]+cm[0][0])))print(“Accuracy of the SVM model : “+str(100*(cm[0][0]+cm[1][1]) / (sum(cm[0]) + sum(cm[1]))) + “%”)
这篇文章的完整代码可以在这里找到。
我们的主要关注点是尽可能多地捕获欺诈交易,鉴于我们在整个数据集中只有大约 800 个欺诈案例,我们通过检测 96/107 欺诈交易完成了出色的工作。
这个帖子到此为止。我们深入研究了支持向量机的概念,我确保为每一部分都提供了直觉,以便读者更好地快速理解。我们唯一没有详细讨论的主题是次梯度下降,但是相信我,所有实现 SVM 的 python 包,只要你知道 SVM 是如何工作的,有了它们的所有参数,次梯度下降在这些包中是自动实现的。在下一篇文章中,我们将深入研究随机森林和决策树,并使用它们解决一个 Kaggle 数据集。
机器学习作业不会因为你盯着它们而跑得更快
原文:https://towardsdatascience.com/machine-learning-jobs-dont-run-faster-because-you-stare-at-them-ef8b8fe07349?source=collection_archive---------31-----------------------
在您做更多令人兴奋的事情时,让您的 python 脚本文本状态更新和警告消息。
图片由 Free-Photos 来自 Pixabay
尽管很吸引人,但我没有时间坐下来看长时间运行的数据管道时钟、模型训练和 python 脚本来处理我的任务。通常,我们希望确保没有需要关注的失败。这个问题的一个解决方案是发送一封电子邮件或文本来获取你想要的任何状态更新。你可以放心地去做其他的事情。
关于如何从 python 脚本发送电子邮件和文本有几个很好的教程。根据您是在组织内工作还是在项目中工作,设置会有所不同。对于本例,我将设置一个 Twilio 电话号码,并在 python 脚本运行期间使用该帐户向自己发送文本更新。
设置 Twilio 帐户后,您可以访问您的帐户 id 和 API 令牌。要通过 API 发送文本,您需要请求一个 Twilio 电话号码。整个过程大约需要 2 分钟。非常快!
下面的脚本是典型的机器学习类型的脚本。在这种情况下,autoML 脚本使用 mljar 包运行。我不仅想知道脚本何时完成运行,还想在出现故障时得到提醒。
# Example of sending text status updates while running an autoML script.import pandas as pd
# scikit learn utilites
from sklearn.metrics import accuracy_score
from sklearn.model_selection import train_test_split# mljar-supervised package
from supervised.automl import AutoML######################################################
# [https://www.twilio.com/docs/python/install](https://www.twilio.com/docs/python/install)
from twilio.rest import Client# Your Account Sid and Auth Token from twilio.com/console
# DANGER! This is insecure. See [http://twil.io/secure](http://twil.io/secure)
account_sid = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'
auth_token = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'
client = Client(account_sid, auth_token)
#######################################################try:
input_df = pd.read_csv('train.csv')
input_df.fillna(0)
print('Input file columns: ' + str(input_df.columns))train_data = input_df[['id', 'keyword', 'location', 'text']]train_label = input_df[['target']]print('train data : ' + str(train_data.head(1)))
print('train label: ' + str(train_label.head(1)))X_train, X_test, y_train, y_test = train_test_split(
pd.DataFrame(train_data), train_label, stratify=train_label, test_size=0.25,
random_state=27
)
except:
message = client.messages.create(
body='mljar data load and split failed',
from_='+1xxxxxxxxxx', #twilio #
to='+1xxxxxxxxx'
)
print(message.sid)try:
automl = AutoML(mode="Explain")
automl.fit(X_train, y_train)
message = client.messages.create(
body='mljar Explain completed',
from_='+xxxxxxxxxx',
to='+1xxxxxxxx'
)
except:
except:
message = client.messages.create(
body='mljar Explain failed',
from_='+xxxxxxxxx',
to='+1xxxxxxxxxx'Nothing is more disappointing than logging onto your computer after waiting hours for a model to train and finding that it failed hours ago! Prevent this by setting up text or email alerts. It’s simple, fast, and is satisfying when you get the ‘successful completion’ text.
没有什么比提交一个脚本运行后登录到您的计算机上,发现它几个小时前就失败了更令人失望的了!通过设置文本或电子邮件提醒来防止这种情况。当你收到“成功完成”的信息时,这是简单、快速和令人满意的。
机器学习乐高图像识别:使用虚拟数据和 YOLOv3
原文:https://towardsdatascience.com/machine-learning-lego-image-recognition-using-virtual-data-and-yolov3-f12e0544012?source=collection_archive---------9-----------------------
我最近一直在做乐高和 3D 模型。对于我目前的项目,我希望建立一个乐高图像识别程序。我的理想场景是抓起一把乐高,把它们扔在桌子上,拍张照片,然后让程序给它们分类。
(乐高是乐高集团的注册商标,乐高集团并不赞助、认可或授权此事。登陆乐高官方网站【http://www.lego.com】。)
我在任何机器学习项目中遇到的最大挑战是收集和格式化训练数据。我很确定这是每个人在机器学习中遇到的最大挑战。以正确的格式获得正确的数据总是交易杀手。
因此,我将使用乐高积木的虚拟 3D 模型来创建训练数据。
乐高分拣机
有几个很酷的例子,人们用乐高图像识别和机器学习来建造乐高分拣机。我的场景有点不同,因为我想从一张图片中同时识别多个 LEGO。不然我的场景和分拣机很像。第一个例子是这里的和。他们似乎采取了暴力手段。手动标记一堆部件,训练算法,在乐高部件上重新运行…清洗,重复…直到你有工作解决方案。这是一个不错的方法,我以前在其他项目中使用过!但我一直在玩几个乐高 3D 建模程序,我在想它可能会创建虚拟数据。我最近遇到了一台通用乐高分拣机,它引用了“虚拟”的积木,所以我猜他们的想法和我类似。[注:在我完成这个项目后,我发现了一个丹尼尔·韦斯特的精彩视频,他解释说他确实使用了合成乐高数据用于他的通用分类机。]
虚拟训练数据
好的,那么我需要哪些训练数据呢?我们需要大量的乐高图片,并标上乐高编号。我想从多个角度拍摄每件作品的照片。当我把一组乐高积木扔到桌子上时,它们会以不同的方向落地。正面朝上、颠倒、不同的旋转等。通常我会希望在一张图片中有多个乐高玩具的训练图片,每个图片上都有边界框。但是我要做几个简化的假设来开始。
正如我提到的,我花了很多时间在乐高建模软件上。有一些令人惊讶的开源和免费软件程序。我从 LDRAW.org 下载了一套这样的软件包。LDRAW 是一种被广泛接受“砖块”格式。(砖块是乐高,和乐高兼容的,塑料部件。)你真的应该花点时间探索一下 LDRAW 社区的创作,超级有创意!
我最终选定了 LDCad ,这是罗兰·梅尔克特的一个很棒的程序。保养得很好。伟大的工具。我首先考虑使用其他开源的选项。我最初计划弄清楚一个命令行工具,最好是 python,它将从 LDRAW LEGO 模型自动生成图像。WebGL 的东西看起来很有前途。但是最终我意识到投资去真正理解底层脚本将会花费比我所能得到的更多的时间。LDCad 使用 LUA,这是一种脚本格式,有很多可用的脚本示例。这使得快速学习变得容易多了。
使用 LDCad
让我们保持简单。我编写了一个 LUA 脚本,它遍历 LDRAW 文件中的一系列片段。对于每一个乐高积木,脚本通过一系列角度旋转相机来捕捉整个积木的图像。动画实际上看起来像作品本身在旋转,但它实际上是相机。
让我们来看看这是如何实现的。
LDCad 将脚本称为“动画”。我把我的动画游行叫做。为了方便起见,我将动画放在 LDCad 提供的 samples.lua 脚本文件中。
剧本分为两个主要部分:onParadeStart()和 onParadeFrame()。LDCad 中脚本的结构让我想起了微控制器状态机。基本上,onParadeStart()在用户启动动画时运行一次。并且 onParadeFrame()在动画的每一帧上运行。
所以在 onParadeStart()中,我初始化了 LDRAW 文件并定义了像 unViewPosition 和 ViewPosition 这样的常量。我还初始化了计数器,用于循环显示作品和相机视角。
onParadeStart()
在 onParadeFrame()中,我构建了一系列 if … else … if 来充当 switch 语句。它循环遍历所有的片段。循环所有动画模式。循环通过所有的摄像机视角。递增计数器并随着它的进行更新摄像机位置。
onParadeFrame()
我将每秒帧数(FPS)设置为 8,因为这给了我 8 张不同的图片,每张图片来自不同的相机视角,用于每个相机观察循环。动画的长度基于片段的数量乘以相机观察循环的数量。当你为机器学习训练阶段提取图片时,你将需要所有这些信息。
一旦设置并注册了游行脚本,它将作为一个菜单选项出现在 LDCad 程序中。您可以在 LDCad 中打开 LDRAW 文件,然后运行游行动画。LDCad 允许您将动画导出为一系列 png 图像文件。不错!
制作乐高图像
我拿了一个我在家里没有打开过的小乐高玩具。31072-极限引擎。
31072 —极限引擎
这是一个较小的套件,共有 109 件,49 个独特的作品。我认为这将是一个很好的项目测试。我使用了一个 python 脚本和 rebrickable.com 的API来下载这个特定套件的零件清单。
rebrickable.com
在 API 返回的 JSON 部件列表中,是 LEGO 部件 id 和相应的 LDRAW 部件 id。可重新点击 api 文档表明可重新点击零件号“主要”基于 LDRAW。深入研究 api 调用的 JSON 输出,我发现可重复调用的部分 id 是比 external_ids:LDraw 下面列出的 id 更可靠的 LDRAW id。不是 100%确定为什么,但它对这个项目来说已经足够好了。我编写了创建 LDRAW 文件的脚本,每个唯一的 LDRAW 部件 id 对应一行。
LDRAW 格式要求每行上的每个片段都有一个位置和方向。尽管这些坐标对我们的动画来说并不重要,但格式确实需要符合“子文件参考线”的 LDRAW 文件格式
1
x y z a b c d e f g h i
- 1 表示“子文件参考线”
- x y z 是位置坐标
- a b c d e f g h i 是标准 4x4 齐次变换矩阵的左上 3×3 矩阵。
- 我选了 4(红色)作为颜色。(颜色不应该影响识别。)
- 例如……1 4 0 0 0 1 0 0 1 0 0 0 0 0 0 1 3023 . dat
一旦构建了 LDRAW 文件,我就在 samle.lua 脚本的注册函数中将动画长度设置为 245 秒。因为时长应该是(件数)*(相机循环次数)
49 * 5 = 245
在 LDCad 程序中,我加载了我的 LDRAW 文件,并运行动画来检查它。然后我选择会话->动画->OpenGL 导出选项。我设置了 300X300 的图像尺寸。也许比需要的要大,但是我想要足够的像素来适应不同的尺寸。我把背景设置为#FFFFFF(白色)。并导出到我选择的文件夹中。
导出动画后,我有了 1960 张图片。49 件独特作品各 40 张图片。这可能有些矫枉过正。或者它可能在角度和照明方面没有足够的变化。创新和实验将是反复的。
现在我们有了一些图像,让我们转向机器学习!
YOLOv3 物体检测
我将使用 YOLOv3 算法进行训练。尽管 YOLO 特别限制“小对象”被“紧密地”组合在一起,但我认为这种实现方式会很好。小和靠在一起是相对的。如果我们试图在一张桌子上辨认出乐高积木,并且在图像中有更大的物体,这些限制将会是一个问题。但是如果整张图片是一个类似大小的乐高积木的集合,那么就没问题了。仅供参考——YOLO 绝对是矫枉过正。
YOLO(你只看一次)是速度优化。最常见的应用是实时或近实时视频分析。我们可以为这个项目选择 fast-CNN 或其他单镜头探测器。但是我想用 YOLOv3,因为我没用过,尝试新事物很好玩!
我找到了一个关于“如何从头开始训练自己的 YOLOv3 探测器”的快速演练。
让我们试一试吧!
培训数据格式
YOLOv3 需要一组带有边界框的带标签的训练图像。以及描述训练数据和图像的文本文件。文本文件所需的格式要求每个训练图像占一行,包含…绝对文件路径、xmin、ymin、xmax、ymax、label_id。x 和 y 坐标是要识别的对象的边界框。label_id 是对 data_classes 的引用。最终,label_id 将是每个 LEGO 块的部件 id 的引用。但是我们将把零件 id 放在 Data_classes.txt 文件中。
所以我构建了一个简短的 python 脚本,从部分 id 列表中创建 Data_classes.txt 文件。并将该文件放在“数据- >模型 _ 权重- >数据 _ 类. txt ”中
我有图像文件路径,可以从用于构建 Data_classes.txt 文件的零件号数组中获取 label_id。但是我也需要边界框。我确信有许多有效的方法来完成这项任务。但是我用了 PIL 的图片。这是一种作物用途。并且由于训练数据是人工的并且包含统一的背景,裁剪图像提供了与紧密边界框相同的坐标。
我创建了一个 python 脚本,将所有这些信息放在一个 data_train.txt 文件中。然后把那个文件放到“Training _ Images->vott-CSV-export->data _ train . txt”中。
在 YOLOv3 这样的模型上,可以尝试无数的调整和优化。如果您从上面链接的参考实现开始,设置这两个文件将允许您训练第一次迭代。
现在可以从命令行运行 Train_YOLO.py。
结果!
所以模型训练了很久。102 个时代。在我的家庭服务器上呆了 48 个小时。再说一次,我相信还有很多很多的优化要做。
我打开我的乐高盒子,抓了一把积木,扔在桌子上,拍了张照片,然后进行推理。
推理检测
我的天啊。不算太坏。在第一次训练中,它就答对了几道题!
正如所料,灯光和阴影扮演了重要角色。零件的方向也被考虑在内。越是独特的部分,比如车轮,越能被准确、频繁地挑选出来。
我认为这是一个很好的开始!没有任何模型调整,并使用简单的虚拟数据相机旋转动画程序。在这个项目快结束的时候,我发现了一段丹尼尔·韦斯特的视频,他解释说他确实在他的通用分类机器中使用了合成乐高数据。他谈到了虚拟数据的挑战以及通过混合一些真实数据来改善结果的技巧。也许我会尝试一下。但是我也想到了另一个利用乐高和机器学习的酷项目。一天的时间永远不够。
机器学习:使用 Pyspark 的线性回归
原文:https://towardsdatascience.com/machine-learning-linear-regression-using-pyspark-9d5d5c772b42?source=collection_archive---------7-----------------------
https://unsplash.com
简介:
PySpark 是用 Python 编写的 Python API,用于支持 Apache Spark。Apache Spark 是一个分布式框架,可以处理大数据分析。Spark 是用 Scala 写的,可以和 Python,Scala,Java,R,SQL 语言集成。Spark 基本上是一个计算引擎,通过并行和批处理系统处理大量数据。当你下载 spark 二进制文件时,会有单独的文件夹来支持上述语言。
基本上有两种主要类型的算法-转换器:转换使用输入数据集,并使用转换()将其修改为输出数据集。
估计器是采用输入数据集并使用 fit()生成经过训练的输出模型的算法。
在这一节,我将展示使用 Spark 和 Python 的机器学习实现。我将在这里重点介绍在 Spark 环境中实现的基本 ML 算法线性回归。该程序已在独立服务器中执行。
首先,如下所示导入库。最重要的是给出 Spark 二进制文件在系统中的路径。否则,您可能会在执行代码时遇到问题。
火花时段:
这是 Dataframe API & dataset 编程火花的入口点。它允许您使用 spark 执行各种任务。spark 上下文、hive 上下文、SQL 上下文,现在所有这些都封装在会话中。在 spark 2.0 之前,sparkContext 用于访问所有 spark 功能。spark 驱动程序使用 sparkContext 通过资源管理器连接到集群。sparkConf 创建 sparkContext 对象,该对象存储配置参数,如 appName(用于标识 spark 驱动程序)、应用程序、内核数量以及在 worker 节点上运行的执行器的内存大小。从 spark 2.0 开始,这两个特性被封装在 spark 会话中。因此,每次您想使用 spark 执行任务时,您都需要创建一个会话,并且在执行之后,您必须结束该会话。
现在使用 read.csv()读取数据集,您可以允许 spark 读取数据集并在需要时执行。这里我使用了一个 r[real estate dataset](http://Real estate.csv)used。
在这里,您可以注意到诸如 No 和 X1 交易日期之类的列与房屋价格无关,并且在数据集中没有正确给出交易日期。因此,我们将删除这些列
colm = ['No','X1 transaction date']
df = dataset.select([column **for** column **in** dataset.columns **if** column **not** **in** colm])
有一个很酷的 spark 语法可以做到这一点。如果您在 select()中应用列表理解,您将获得所需的数据框。此数据框不同于熊猫数据框。嗯,和《星火》和《熊猫》里创造的物体有关。
Spark 数据帧是分布式的,因此在处理大型数据集时,您将获得并行处理和处理速度的优势。
Spark 确保容错。因此,如果您的数据处理在处理之间中断/失败,spark 可以从沿袭中重新生成失败的结果集。
df.printSchema()#outputroot
|-- X2 house age: string (nullable = true)
|-- X3 distance to the nearest MRT station: string (nullable = true)
|-- X4 number of convenience stores: string (nullable = true)
|-- X5 latitude: string (nullable = true)
|-- X6 longitude: string (nullable = true)
|-- Y house price of unit area: string (nullable = true)
如果您查看数据集的模式,它是字符串格式的。让类型转换浮动。
**from** **pyspark.sql.functions** **import** coldf = df.select(*(col(c).cast('float').alias(c) **for** c **in** df.columns))
让我们检查空值。
df.select([count(when(col(c).isNull(), c)).alias(c) **for** c **in** df.columns]).show()
太好了!不存在空值。但是列名有点长。所以我们现在将用我们自己的自定义名称来替换它们。重命名列名有几种技术,我使用 reduce()来实现。你可以用另一种方式表演。
**from** **functools** **import** reduce
oldColumns = df.schema.names
newColumns = ['Age','Distance_2_MRT','Stores','Latitude','Longitude','Price']
df = reduce(**lambda** df, idx: df.withColumnRenamed(oldColumns[idx], newColumns[idx]),range(len(oldColumns)), df)
尝试不同的技术,也让我知道。
分享就是关爱: )
现在,我们将进行分割以获得要素和标签列。
向量汇编器:
VectorAssembler 是一个转换器,它将给定的列列表合并成一个向量列。这对于将原始特征和由不同特征转换器生成的特征组合成单个特征向量以训练 ML 模型是有用的。
**from** **pyspark.ml.feature** **import** VectorAssembler
*#let's assemble our features together using vectorAssembler*
assembler = VectorAssembler(
inputCols=features.columns,
outputCol="features")
output = assembler.transform(df).select('features','Price')
这将转换目标和功能列。现在我们将它分成训练和测试数据集。
train,test = output.randomSplit([0.75, 0.25])
现在让我们应用一个线性回归模型
**from** **pyspark.ml.regression** **import** LinearRegression
lin_reg = LinearRegression(featuresCol = 'features', labelCol='Price')
linear_model = lin_reg.fit(train)print("Coefficients: " + str(linear_model.coefficients))
print("**\n**Intercept: " + str(linear_model.intercept))#Output
Coefficients: [-0.2845380180805475,-0.004727311005402087,1.187968326885585,201.55230488460887,-43.50846789357342]
Intercept: 298.6774040798928
我们得到的每一列和截距的系数。
trainSummary = linear_model.summary
print("RMSE: **%f**" % trainSummary.rootMeanSquaredError)
print("**\n**r2: **%f**" % trainSummary.r2)#Output
RMSE: 9.110080
r2: 0.554706
用于测试数据集
**from** **pyspark.sql.functions** **import** abs
predictions = linear_model.transform(test)
x =((predictions['Price']-predictions['prediction'])/predictions['Price'])*100
predictions = predictions.withColumn('Accuracy',abs(x))
predictions.select("prediction","Price","Accuracy","features").show()
r-测试数据集的平方值
**from** **pyspark.ml.evaluation** **import** RegressionEvaluatorpred_evaluator = RegressionEvaluator(predictionCol="prediction", \
labelCol="Price",metricName="r2")
print("R Squared (R2) on test data = **%g**" % pred_evaluator.evaluate(predictions))#output
R Squared (R2) on test data = 0.610204
现在让我们检查调整后的 R 平方。
调整后的 R-square:
调整的 R 平方是 R 平方的修改版本,已经针对模型中预测器的数量进行了调整。只有当新项对模型的改进超过偶然预期时,调整后的 R 平方才会增加。当预测者对模型的改进小于预期时,它会减少。我们使用调整后的 R2 值来惩罚与输出数据不相关的此类特征的过度使用。
r2 = trainSummary.r2
n = df.count()
p = len(df.columns)
adjusted_r2 = 1-(1-r2)*(n-1)/(n-p-1)
我们得到调整后的 r 平方值 0.54 用于训练和测试。
现在,让我们进一步探索 spark 中的 LinearRegression()。
lin_reg = LinearRegression(featuresCol = 'features', labelCol='Price',maxIter=50, regParam=0.12, elasticNetParam=0.2)
linear_model = lin_reg.fit(train)
在这里你可以应用套索,山脊,弹性网正则化,阿尔法值你可以修改。有一篇关于这些概念的非常好的文章。这是一个用于学习 Apache Spark Notes 的共享存储库。这个共享存储库主要包含文强在 IMA 数据科学奖学金期间的自学和自学笔记。感谢乔治·冯,ML 实验室的高级数据科学家。
我将在未来的故事中分享其他 spark 实现的 ML 算法。
对于建议,我将在LinkedInGmailTwiiter&关注我在GitHub的工作。**
PyCaret 简化了机器学习
原文:https://towardsdatascience.com/machine-learning-made-easier-with-pycaret-907e7124efe6?source=collection_archive---------15-----------------------
PyCaret 的工作
我们经常被困在时间紧迫的场景中,无法完成任务。在机器学习中,在这种情况下非常有用的库是 PyCaret 。
PyCaret 是 Python 中的一个开源库,对于一些机器学习活动非常有用。它可以帮助你从数据预处理到模型的部署。PyCaret 如此有用和方便的原因是,任何事情都可以用很少几行代码实现,并且代码非常容易理解。我们可以更专注于对数据进行实验,而不是写几行代码。除了有助于数据预处理、编码分类特征之外,PyCaret 还通过考虑尽可能少的性能指标(如准确性、F1 分数、召回率等)来了解哪个模型更好。
在 Unsplash 上 Prateek Katyal 拍摄的照片
让我们深入 PyCaret 的工作。
1.安装:
PyCaret 的安装非常容易。它就像任何其他 python 库一样。可以通过在命令行中运行以下命令来安装它:
pip install pycaret
如果您使用的是 Google Collab,那么 PyCaret 可以通过以下方式安装:
!pip install pycaret
安装 PyCaret 将自动为您安装以下所有依赖项。
如果您不知道这些依赖性,您不必担心,因为 PyCaret 会处理这些依赖性。
一旦你安装了 PyCaret,你可以使用 import pycaret 将它导入到你的 jupyter 笔记本中
import pycaret
2.准备好数据
一旦 PyCaret 被导入,我们必须为构建模型准备好数据。我们可以通过以下两种方式加载数据:
1。熊猫数据框
2。来自 PyCaret 存储库的数据
让我们首先讨论如何使用 Pandas dataframe 加载数据。Pycaret 支持 pandas dataframe,可以通过使用“read_csv”和文件路径轻松加载数据。
import pandas as pd
data = pd.read_csv("data/train.csv")
data.head()
以类似的方式,我们可以加载 pandas 支持的所有其他类型的数据。
加载数据的另一种方法是使用 PyCaret 的存储库。它由可以非常容易地导入的数据集组成。如果您想了解 PyCaret 存储库中的数据集,请点击此处。
from pycaret.datasets import get_data
nba = get_data('nba')
3.环境设置
在设置环境之前,我们必须为数据集导入适当的模块。PyCaret 支持 6 个模块,这些模块中的任何一个都可以用一行代码导入。
PyCaret 支持以下 6 个模块。
Pycaret 环境的核心设置在于一个名为 setup()的函数。
setup()函数启动环境和管道来处理用于建模和部署的数据。在 PyCaret 中执行其他函数之前,必须启动该函数。
大约有 50 个参数被输入到 setup()函数中,但是我们不必担心,因为大多数参数都被设置为默认值,并且是可选的。只有两个强制参数需要输入,它们是 dataframe {类似数组的稀疏矩阵}和目标列。
setup()函数在后台自动进行 数据预处理和 数据采样。它在默认参数下运行,但是这些参数可以根据个人需求进行更改。
在我们的例子中,我们取一个名为【NBA】的数据集,其中目标变量为【TARGET _ 5Yrs】,这是一个二元分类问题。因此,我们使用导入分类模块
from pycaret.classification import *
pycar = setup(nba, target = 'TARGET_5Yrs')
一旦您运行上面的命令,您的数据集就被设置为一个分类模型,并且您可以看到输出消息声明 “设置成功完成!” 你会看到一组参数及其描述和与之对应的值。
现在让我们来看看 setup()函数的功能:
setup()函数对输入数据帧执行数据预处理。在任何 ml 模型中,数据预处理在构建 ml 模型中起着至关重要的作用。所以在 setup()函数中,PyCaret 为机器学习准备了超过 20 个特征的数据。机器学习管道是基于 setup()函数中定义的参数构建的。现在,我将详细解释 setup()函数中涉及的预处理步骤。如果你不知道这些,不要惊慌,因为我们的朋友 PyCaret 为我们做了这些。
PyCaret 为您处理的预处理功能有:
—取样和分割
—缩放和变换
—数据准备
—特征工程
—无人监管
让我详细阐述一下 PyCaret 能够完成的预处理步骤。
- 取样和分割
(一)列车试分裂:
机器学习中的任何数据集都被分成训练和测试数据集。这样做是因为当给定一个看不见的数据时,知道机器学习模型的工作是很重要的。在 PyCaret 中,默认情况下,70%的数据属于训练数据集,30%的数据属于测试数据集。
from pycaret.classification import *
reg1 = setup(data = nba, target = 'TARGET_5Yrs')
输出:
但是,只需在函数中传递 train_size 参数,就可以改变这些数据集的大小。
参数:列车尺寸
from pycaret.classification import *
reg1 = setup(data = nba, target = 'TARGET_5Yrs', train_size = 0.6)
分割后的数据(分割= 60%):
输出:
(二)采样:
如果数据集的样本/数据点很大,即超过 25,000 个样本,则 PyCaret 会自动进行采样。构建了具有各种样本大小的基本估计量,并获得了显示每个样本的性能度量的图。然后,可以在文本框中输入所需的样本大小。Sampling 是一个布尔参数,默认值为 True。
取样示例:
from pycaret.datasets import get_data
income = get_data('income')
from pycaret.classification import *
model = setup(data = income, target = 'income >50K')
此功能仅在 pycaret.classification 和 pycaret.regression 模块中可用。
- 数据准备
在执行机器学习流水线时,拥有正确的数据非常重要。很多时候,数据可能会损坏,可能会有一些丢失的值,或者应该对数据进行分类。所有这些在构建模型中起着至关重要的作用,需要在使用数据本身之前解决。
(一)缺失值插补:
数据中缺少记录是非常常见的,默认情况下,机器学习算法无法处理这个问题。PyCaret 自动进行缺失值插补。用于数字特征的缺省插补技术是“平均值”,用于分类特征的缺省值是“常数”。setup()函数中的参数名称是
参数:
数值 _ 插补:字符串,默认= '均值'
分类 _ 插补:字符串,默认值= '常量'
只要在 setup()函数中给出参数,就可以根据问题改变这些参数。
#import the hepatitis dataset from PyCaret repository
from pycaret.datasets import get_data
nba = get_data('hepatitis')
启动设置( )之前:
启动安装程序( )后:
㈡改变数据类型:
PyCaret 自动检测数据集中存在的要素的数据类型。这些值有时可能是错误的。因此,这个问题可以通过给定一个参数来解决,例如
参数:
numeric_features = ['列名']
category _ features =[' column _ name ']或 date _ features = ' date _ column _ name
ignore _ features =[' column _ name ']
这些参数可用于覆盖 PyCaret 检测到的数据类型。当我们不想考虑任何特性时,可以使用另一个参数 ignore_features 。
示例:如果特性“GP”是分类的,但是 PyCaret 将其解释为数字,那么它可以被覆盖。
代码片段(从数字到分类):
from pycaret.classification import *
pycar = setup(nba, target = 'TARGET_5Yrs', categorical_features = ['GP'])
输出:
ignore_features 的示例:
这里我们将忽略数据帧的 MIN 列。
代码段(忽略数据集中的“MIN”列):
from pycaret.classification import *
pycar = setup(nba, target = 'TARGET_5Yrs', ignore_features = ['MIN'])
输出(“MIN”列已被忽略):
㈢一个热编码:
分类特征不能直接用于机器学习算法。必须使用一次性编码对它们进行分类。PyCaret 使用一键编码自动对分类特征进行编码。
示例:
在这里,名称是一个分类特征。因此 PyCaret 对其进行编码。
输出(' Name '列已被一键编码):
㈣序数编码:
与其他分类特征相比,遵循“差、好、优”等顺序的分类特征应进行不同的编码。这是由 PyCaret 通过发送一个参数来完成的
参数:序数 _ 特征:字典
默认值为无。
代码:
from pycaret.datasets import get_data
emp = get_data('employee')
from pycaret.classification import *
model = setup(data = emp, target = 'left', ordinal_features = {'salary' : ['low', 'medium', 'high']})
输出:
model[0]
㈤基数编码:
通过使用一键编码,可以为邮政编码或国家等特征获得非常大的稀疏向量。因此,我们可以使用基数编码来解决这个问题。Pycaret 在 setup()中有一个参数,它为您进行基数编码。参数是
参数:high_cardinality_features:字符串,默认值=无
代码:
from pycaret.datasets import get_data
inc = get_data('income')
from pycaret.classification import *
model = setup(data = inc, target = 'income >50K', high_cardinality_features = ['native-country'])
输出:
㈥处理未知水平:
我们多次遇到这样的情况,测试数据具有新的级别,而这些级别在训练数据中并不存在。这由 PyCaret 通过给定“最频繁”或“最不频繁”的值来自动处理。setup()函数中的参数是
参数:
handle _ unknown _ categorical,default = True
unknown _ category _ method:string,default = ' least _ frequent '
- 缩放和变换
比例和变换非常重要,因为有时数据可能会有很大的变化范围或不同的比例。
( i)正常化:
归一化是一个非常重要的预处理步骤,它将确保数值不会分布得太广。当参数 normalize 设置为 true 时,PyCaret 进行归一化。有几种方法可以标准化数据。参数 normalize_method 的默认值是 z 值,其中平均值为 0,标准差为 1。其他值包括 min-max(值的范围为 0 到 1)、maxabs(确保每个要素的最大绝对值为 1)、robust(根据四分位数范围进行归一化,如果存在异常值,则更好)。
参数:规格化,normalize_method
归一化示例(使用默认的 normalize_method: Z-score):
代码:
from pycaret.classification import *
pycar = setup(nba, target = 'TARGET_5Yrs', normalize = True)
输出:
normalize_method 的示例:
代码(使用“最小最大”方法进行标准化):
from pycaret.classification import *
pycar = setup(nba, target = 'TARGET_5Yrs', normalize = True, normalize_method = 'minmax')
输出:
pycar[0]
㈡转型:
转换用于将数据转换为高斯或近似高斯分布。当参数转换设置为 true 时,PyCaret 进行规范化。有几种方法可以转换数据。参数 transformation_method 的默认值是 yeo-johnson。transformation _ method 的另一个值是分位数。
参数:转换,转换方法
示例:
from pycaret.classification import *
pycar = setup(nba, target = 'TARGET_5Yrs', transformation = True)pycar[0]
输出:
- 特征工程
特征工程是机器学习的创造性方面。特征工程是利用乘法、三角函数、对数函数等特征的组合,将数据转换到另一个空间。
(一)特色互动:
PyCaret 允许通过使用现有功能创建新功能。两个要素可以彼此相乘或相除以形成新的要素。使用的参数有 特征 _ 交互(乘法),特征 _ 比率(除法) 。默认情况下,这两个参数都设置为 false。这些参数可在 setup()功能中更改,以获得特征交互。
参数:
feature_interaction: bool,default = False
feature_ratio: bool,default = False
interaction_threshold: bool,默认值= 0.01
示例:
从 PyCaret 存储库导入“血液”数据集
代码:
from pycaret.classification import *
model = setup(data, target = 'Class',feature_interaction = True, feature_ratio = True)
model[0]
输出:
㈡多项式特征:
就像在特征交互中一样,新特征是使用多项式次数(a)创建的。使用的参数是多项式 _ 特征,默认设置为假,多项式 _ 次数是一个整数,默认设置为 2。这些参数可以在 setup()函数中更改,以获得多项式特征。
参数:
多项式 _features: bool,default = False
多项式次数:int,默认值= 2
多项式 _ 阈值:浮点,默认值= 0.1
示例:
从 PyCaret 存储库导入“血液”数据集
代码:
from pycaret.classification import *
model = setup(data, target = 'Class', polynomial_features = True)
model[0]
输出:
(三)三角学特征:
这与多项式特征非常相似。使用的参数是trigon metric _ features,默认设置为 false。可以在 setup()函数中更改该参数,以获得三角函数特征。
参数:三角学 _features: bool,default = False
(四)群体特征:
当特征彼此相关时,可以使用 setup()函数中的 group_features 参数对这些特征进行分组。使用该参数可以获得平均值、中位数等信息。特性列表在参数 group_features 中传递。
参数:
group_features:列表或列表列表,默认值=无
group_names: list,默认值= None
(五)Bin 数字特征:
有时,连续要素可以有很大范围的值。在这种情况下,我们使用特征宁滨。setup()函数中使用的参数是 bin_numeric_features ,用于对数字特征进行绑定。
参数:bin_numeric_features: list,默认值= None
㈥结合稀有水平:
前面我们已经看到了一种热编码,其中像国家这样的特征在编码成数值时会生成一个稀疏矩阵。在这种情况下,模型的计算时间会随着要素数量的增加而增加。在这种情况下,特性中具有高基数的罕见级别被组合在一起。
参数:
combine_rare_levels: bool,default = False
稀有级别阈值:浮点型,默认值= 0.1
- 功能选择
选择好的和有用的特征是非常重要的,因为它有助于模型的解释。
(一)特征重要性:
它用于确定在预测目标变量时最重要的特征。setup()函数中使用的参数是 feature_selection ,默认为假。另一个名为的参数 feature_selection_threshold 存在,需要使用,尤其是在使用多项式或特征交互时。默认值为 0.8。
参数:
feature_selection: bool,default = False
feature _ selection _ threshold:float,默认值= 0.8
㈡消除多重共线性:
当一个要素与另一个要素高度相关时,就存在多重共线性。这将导致模型不稳定。因此,可以通过使用参数移除多重共线性将其移除,该参数在 setup()函数中默认设置为 false。可使用参数多重共线性 _ 阈值设置阈值以删除特征的数量,默认设置为 0.9。
参数:
remove_multicollinearity: bool,default = False
多重共线性 _threshold: float,默认值= 0.9
(三)主成分分析:
这主要用于降维。当数据集由许多维度组成时使用它。但是当使用 PCA 时,存在信息损失。这里使用的参数是 pca_method ,其默认值是线性的。其他可以使用的方法是 RBF 和增量。下一个参数是 pca_components ,它可以接受 int 和 float 值。如果给定一个整数值,那么它意味着要出现的特征的数量,如果存在浮点值,那么它意味着要保留的信息的百分比。
参数:
pca: bool,default = False
pca_method: string,default = 'linear '
pca_components: int/float,默认值= 0.99
㈣忽略低方差:
在多分类特征具有偏斜分布并且一个或两个特征相对于其他特征占优势的情况下,模型获得的方差将非常低。在这种情况下,我们可以忽略该功能。
在忽略特征之前,应满足以下标准 (参考) :
—特征/样本大小中唯一值的计数< 10%
— Count of most common value / Count of second most common value > 20 次。
参数:ignore_low_variance: bool,default = False
- 无人监管
㈠创建集群:
聚类对于无监督学习非常重要。通过将 create_cluster 值设置为 true,数据集中的每个点都被分配给一个特定的聚类,并且每个聚类都被用作一个新要素。Cluster_iter 参数用于控制用于形成一个聚类的迭代次数。
参数:
create_clusters: bool,default = False
cluster_iter: int,默认值= 20
㈡消除异常值:
离群值会影响模型的性能,因此需要移除。PyCaret 使用 SVD 通过 PCA 去除异常值。可以通过将参数 remove_outliers 设置为 true 来移除离群值。异常值的百分比可以由参数 outlier_threshold 控制,其默认值为 0.5。
参数:
remove_outliers: bool,default = False
outliers_threshold: float,默认值= 0.05
设置使用所有 belowinput 参数,但请记住,只需输入两个强制参数,即数据和目标,其余所有值均设置为默认值/可选值。
设置 ( data,target, train_size = 0.7,sample_estimator = None,categorical _ features = None,category _ attraction = ' constant ',ordinal_features = None,high_cardinality_features = None,high _ cardinality _ method = ' frequency ',numeric_features = None,numeric _ attraction = ' mean ',date_features = None,ignore_features = None,normalize = False,normalize rare_level_threshold = 0.10,bin_numeric_features = None,remove_outliers = False,outliers_threshold = 0.05,remove _ multi 共线性= False,multi 共线性 _threshold = 0.9,create_clusters = False,cluster_iter = 20,polynomial_features = False,polynomial_degree = 2,trigonometry _ features = False,多项式 _threshold = 0.1,group_features = None,group_names = None,feature_selection = False,feature _ sel
简而言之,你可以只使用下面的代码,而不是给出所有这些参数。
设置(数据、目标)
4.比较模型
PyCaret 的一个主要用途就是可以用来比较几种基于性能指标的机器学习模型。因此可以确定最佳模型。这些模型通过使用 10 倍交叉验证进行计算。这对于了解模型的行为以及哪个模型更适合非常有用。比较模型的代码非常简单。
比较模型()
compare_models()
结果:该函数返回一个分数网格,指定每个性能指标的最佳模型。
用于分类的性能度量是准确度、AUC、召回率、精确度、F1、Kappa。
用于回归的性能指标有 MAE、MSE、RMSE、R2、RMSLE、MAPE
该表按精度排序,但可以通过在排序参数中给定不同的值来修改。默认情况下,折叠值为 10。这可以根据我们正在解决的问题而改变。
5。创建模型
一旦我们了解了哪个模型更好,就该创建模型了。创建模型的代码非常简单。
create_model('模型名称')
输出是一个 knn 模型和一个分数网格,它说明了准确性、AUC、召回率、精确度、F1 和 kappa 值。
knn_model = create_model('knn')
结果:
我在 create _ model(‘KNN’)函数中使用‘KNN’表示构建了一个 K-NN 模型。同样,您可以通过在 create_model('model name ')中使用以下任一表示来构建其他模型。
默认情况下,模型是使用 10 倍 CV 创建的。相反,我们可以通过使用折叠参数来改变它。
创建模型(使用 7 折 CV):
knn_model = create_model('knn ',fold = 7)
knn_model = create_model('knn',fold = 7)
输出:获得的结果 knn_model 将在 7 折交叉验证上训练。
创建模型(四舍五入到小数点后两位):
我们可以在创建模型功能中使用舍入参数来舍入性能指标。
knn_model = create_model('knn ',round = 2)
knn_model = create_model('knn',round = 2)
结果:分数网格中的指标将四舍五入到两位数。
6.调整模型
顾名思义,我们可以使用 tune_model()函数来优化模型,在 create_model()函数中,模型是使用默认的超参数创建的。tune_mode()函数的功能是,它将自行调整模型的超参数,并生成一个分数网格作为输出。
调谐前:
knn_model = create_model('knn')
调谐后:
tuned_knn = tune_model('knn')
Tuning_model(使用优化):
使用的默认优化方法是 accuracy,但是我们可以通过使用 tuned_model()函数的优化参数来更改它。
tuned_knn = tune_model('knn ',optimize='AUC ')
tuned_knn = tune_model('knn',optimize='AUC')
以类似的方式,我们可以使用其他优化措施,如“召回”、“精度”、“F1”。
结果:绩效评估值的得分有所提高。
7.集合一个模型
PyCaret 还执行模型的集合。由于集成提高了模型的性能(在大多数情况下),我们可以在 PyCaret 中使用打包、提升、混合和堆叠来集成我们的模型。
集合 _ 模型(模型 _ 名称)
示例:对于这个示例,我们将构建一个简单的决策树,并在其上执行集成。
创建一个简单的决策树:
代码:
dt = create_model('dt')
组装后:
代码:
bag_dt = ensemble_model(dt)
我们可以看到组装后的显著差异。装袋是默认技术。
以类似的方式,我们可以执行增强、混合和堆叠。点击此处获取更多信息。
8.绘制和评估模型:
在一个模型被创建之后,绘制模型的性能度量并对其进行分析是非常容易的。使用 plot_model 可以实现不同类型的可视化,如 AUC、精度-召回曲线、决策边界等。
plot_model(model_name,plot = "type ")
绘图代码:
logreg = create_model('lr')
plot_model(logreg, plot = 'boundary')
我们在代码中使用了 plot = "boundary ",它表示决策边界。以类似的方式,我们可以使用其他图使用他们的字符串类型。下表是 PyCaret 支持的绘图类型。
此外,对于包含概率的模型,我们可以在校准的分类器的帮助下使用模型校准来预测结果的真实概率。提供概率值增加了可解释性并减少了不确定性。
校准型号(型号名称)
代码:
#Create a simple decision tree
dt = create_model('dt')#Calibrate the model
calib_dt = calibrate_model(dt)
除此之外,还有一个非常有用的函数 evaluate_model(model) ,用于显示所有的可视化效果。这只适用于 jupyter 笔记本界面。它提供了一个交互式用户界面,我们可以在其中选择我们需要的可视化类型。
代码:
evaluate_model(logreg)
以下是 evaluate_model 工作方式的视频演示。
这些可视化对于不同的机器学习模块是不同的。点击此处了解更多可视化信息。
9.解释模型
在 PyCaret 中也可以对模型进行解释。使用 shap 值来确定特征的重要性。形状值中的图形由 x 轴和 y 轴组成。x 轴由 shap 值组成,这些值以积极或消极的方式显示功能的影响。y 轴由特征值组成。
model = create_model('xgboost')
interpret_model(model)
shap 值主要用于确定某个要素对于预测分类标注的重要性。右侧的红色表示该功能做出了积极的贡献。
10.预测模型
到目前为止,所有的结果都是基于 k 倍交叉验证(训练数据集)。现在,我们将在测试数据集上预测模型的性能。
代码:
rf_holdout_pred = predict_model(rf)
创建模型后的输出:
在测试数据集上预测模型后的输出:
11.保存模型
PyCaret 使我们能够使用 save_model(name,model_name = ' ')将整个模型管道保存到二进制 pickle 文件中。一旦保存了模型,我们就可以使用 load_model()随时加载它。我们将保存在步骤 9 中创建的 xgboost 模型,命名为‘py caret _ model’。
代码:
save_model(model, 'pycaret_model')
我们可以通过使用 load_model()函数简单地加载这个保存的模型。
代码:
load_saved_model = load_model('pycaret_model')
#Now our previous model is loaded into **saved_model** and is ready to predict/classify.
除了只保存模型,还可以使用 save _ experiment(experiment _ name = ' py caret _ experiment ')以类似于保存模型的方式保存整个实验。通过这样做,您可以保存所有的模型及其输出。
load_experiment(experiment_name='pycaret_experiment'
也可以实现实验的加载。
load_saved_exp = load_experiment(‘pycaret_experiment’)
这就是了,你最终训练好的模型/实验可以用一行代码调用和使用。我们还可以在 AWS 中部署构建好的模型。因此,我们可以使用非常少的代码行构建一个完整的管道模型。
结论
总之,PyCaret 是一个非常有用的库,可以帮助您节省大量的时间,因为您已经基本了解了机器学习中的概念,如算法如何工作、性能指标、数据预处理等。PyCaret 在很短的时间内产生显著的结果。我肯定会建议探索 PyCaret ,因为这是值得的!
我要感谢 Moez Ali 和 PyCaret 的团队提供了这个库。
感谢阅读到最后。如果有任何错误或建议,请不吝赐教。
如果你想联系我,请通过 LinkedIn 联系我。
参考文献:
[## 宣布 PyCaret:一个用 Python 编写的开源低代码机器学习库
Python 中的开源低代码机器学习库。
towardsdatascience.com](/announcing-pycaret-an-open-source-low-code-machine-learning-library-in-python-4a1f1aad8d46) [## 预处理- PyCaret
PyCaret 是一个部署就绪的 Python 库,这意味着当您执行一个实验时,所有步骤都会自动…
pycaret.org](https://pycaret.org/preprocessing/) [## 函数- PyCaret
函数是 PyCaret 中按顺序执行任务的一组操作。PyCaret 中的所有函数都接受一个输入…
pycaret.org](https://pycaret.org/functions/)
PyCaret 让机器学习变得简单
原文:https://towardsdatascience.com/machine-learning-made-easy-by-pycaret-5be22394b1ac?source=collection_archive---------40-----------------------
10 行代码的整个机器学习管道。
PyCaret 是由 Moez Ali 创建的 python 开源低代码机器学习库,于 2020 年 4 月发布。它实际上是一个低代码库,允许用很少几行代码创建一个完整的机器学习管道。PyCaret 本质上是一个基于常见 python 机器学习库(如 scikit-learn、XGBOOST 等等)的包装器。
PyCaret 实现的是一个非常简单的函数式语法。例如,我们可以用一行代码比较 18 个分类模型。在本文中,我将使用 PyCaret 带您完成一个分类任务,并解释每个步骤的细节。
让我们从安装 PyCaret 开始:
!pip install pycaret
如果您使用 google colab 作为您的 IDE,并计划在笔记本中呈现交互式可视化,则需要执行以下代码:
from pycaret.utils import enable_colab
enable_colab()
我们将使用的数据集是 kaggle 上提供的“电信客户流失”数据集。导入 numpy 和 pandas 后,我们可以将数据集读入 pandas 数据帧:
import numpy as np
import pandas as pddf = pd.read_csv("/content/Customer-churn.csv")
df.shape
(7043, 21)
数据集有 7043 个观察值(行)和 21 列。以下是列的列表:
“CustomerID”没有任何提供信息的能力,因为它只是分配给每个客户的随机消息。“总费用”列是“任期”和“每月费用”列的乘积,因此我们也不需要此列。我们只删除这两列:
df.drop(['customerID','TotalCharges'], axis=1, inplace=True)
任务是使用提供的功能预测客户是否会流失(即离开公司)。我将跳过 EDA 过程,因为这篇文章的重点是如何使用 PyCaret。先来导入 PyCaret 的分类模块:
from pycaret.classification import *
设置
PyCaret 工作流总是从setup
函数开始,该函数为整个机器学习流水线准备环境。因此,setup
必须在任何其他功能之前执行。
值得一提的是,setup 函数会推断数据类型,如果推断的数据类型正确,它会提示您按 enter 键。如果推断的数据类型有错误,您可以键入“quit”。有两个选项可以确定正确的数据类型:
- 使用 pandas 函数和方法手动更改数据类型
- 使用设置功能的数字特征和分类特征参数
exp_clf = setup(data = df, target = 'Churn', session_id=111)
在我的例子中,数据类型是正确的,所以我按 enter 键。设置功能所需的参数有:
- 数据:数据帧的名称
- Target:目标列的名称(因变量)
- Session_id:一个随机数,用作以后再现的种子
执行设置功能后,我们会得到一个关于环境和参数设置的长长的信息列表。
从列表中可以看出,这些参数允许您处理数据预处理步骤。它还将数据分成训练集和测试集。
对比车型
一旦设置被执行,我们可以使用compare_models
来简单评估 PyCaret 模型库中所有模型的性能。有 18 个分类器可用。Compare_models 函数训练所有模型,并在 6 个常用分类指标下评估它们的性能。
用一行(实际上是两个单词)代码,我们能够在 6 个不同的度量下比较 18 个模型。
最佳的 15 个被显示。排序基于“准确性”指标,但可以使用排序参数进行更改。分数通过 10 倍分层交叉验证来计算。使用折叠参数可以改变折叠次数。
我们刚刚做了一个粗略的评估。下一步是从这个列表中挑选一些算法来进一步改进。我们选择什么取决于手头的任务。为了简单起见,我将根据精确度指标选择最佳算法,即逻辑回归。
请记住,最佳评估指标可能会因任务和数据而异。准确度可能不是分类任务的最佳选择,尤其是当我们有不平衡的数据集时。
创建模型
下一步是用选择的算法使用create_model
函数创建一个模型。我们只需要传入模型的缩写。您可以检查函数的 docstring 来查找缩写。
help(create_model)
是时候创建一个逻辑回归模型了。
logreg = create_model('lr')
它返回一个数据框架,其中包含 10 重交叉验证的结果和 6 个不同的指标。平均值是我们从compare_models
函数中得到的值。
tune _ modelvscreate _ model
模型性能的一个关键因素是调整超参数。对于某些模型,超参数对模型的精度影响很大。此外,它们在防止模型过拟合或欠拟合方面起着关键作用。 Create_model 函数使用超参数的默认设置。PyCaret 提供了 tune_model 函数,该函数在预定义的搜索空间内调整超参数。tune_model 函数有两个要点:
- 与 create_model 函数一样,Tune_model 将模型名称作为输入。它不需要您首先训练一个模型,然后调整它。
- 默认情况下,tune_model 试图优化精度指标,但可以使用优化参数进行更改。
可以按如下方式创建优化的逻辑回归模型:
tuned_logreg = tune_model('lr')
剧情模式
Plot_model 函数提供了进一步分析模型性能的工具。它将经过训练的模型作为输入,并返回指定的绘图。让我们复习一些例子。
plot_model(logreg, plot='auc')
这是一个接收器工作特性(ROC)曲线,它通过组合所有阈值的混淆矩阵,总结了不同阈值下的模型性能。ROC 曲线的 x 轴是真阳性率(灵敏度),ROC 曲线的 y 轴是假阳性率(1-特异性)。
我们只是提供了一个估计器(一个训练过的模型)和一种类型的图给plot_model
,它产生了一个信息可视化。有 15 种不同的地块可供选择。让我们也创建混淆矩阵和特征重要性图:
plot_model(logreg, plot='confusion_matrix')
plot_model(logreg, plot='feature')
注意:Evaluate_model 函数产生一个用户界面,其中包含给定模型的所有可用图。它只需要一个估计器(一个训练好的模型)作为输入。
预测并最终确定模型
Predict_model 函数用于对测试集进行预测。回想一下,我们在开始时运行的 setup 函数将数据集分为训练集和测试集。
除了测试集上的评估指标之外,predict_model
还返回带有两个新列的 dataframe:
- 标签:预测
- 得分:预测的概率
默认情况下,预测是在测试集上进行的,但是我们可以使用数据参数提供要预测的新观察值:
predict_model(logreg, data=new_data)
一旦我们对训练集和测试集的性能感到满意,我们就可以使用带有 finalize_model 函数的整个数据集(训练+集)来重新训练模型。目的是在部署模型之前利用整个数据集。请注意,在执行 finalize_model 函数之后,评估测试集的性能是没有意义的,因为模型已经看到了训练集和测试集中的所有观察值。确保在最终确定模型之前使用 predict_model。
final_logreg = finalize_model(logreg)
保存和加载模型
Save_model 函数,顾名思义,将训练好的模型与整个管道一起保存。
我们可以使用 load_model 函数加载已保存的模型。
结论
我们已经讨论了整个机器学习管道,并实验了 PyCaret 如何简化编码。我们能够用大约 10 行代码创建和评估一个体面的模型。使用 PyCaret 的典型管道可以按顺序使用以下函数创建:
- 设置()
- 比较模型()
- create_model()或 tune_model()
- 绘图模型()
- 预测模型()
- save_model()和 load_model()
感谢您的阅读。如果您有任何反馈,请告诉我。
参考文献
- pycaret.org
用 Excel 简化机器学习
原文:https://towardsdatascience.com/machine-learning-made-simple-with-excel-1bffd7901502?source=collection_archive---------3-----------------------
对 ML 的简单介绍——不需要编程或数学。
照片由像素上的 Pixabay 拍摄
到本教程结束时,您将已经实现了您的第一个算法,而无需接触一行代码。您将使用机器学习技术,通过 Excel 中的基本函数对真实数据进行分类。你不必成为天才或程序员才能理解机器学习。尽管自动驾驶汽车、杀手机器人和面部识别的应用已经普及,但机器学习(ML)的基础非常简单。这是一个尝试并了解这些新技术力量的机会。
关于 Excel 的免责声明
所有的数据科学家可能都对本教程的标题感到畏缩。对于严肃的数据分析来说,Excel 通常被认为是一个糟糕的工具。它无法处理我们在现实世界中处理的大型数据集,并且缺乏编程语言和机器学习库的一些关键功能。你会看到本教程中给出的许多公式都很复杂,以适应 Excel 的不足和特性。我使用 Excel 的原因是为了让非程序员也能理解这个介绍,因为我们大多数人都有这个工具的基本知识。那些选择更认真地追求机器学习和数据科学的人最终会升级到使用 Python 或 R,但从简单开始没有坏处。
我们的最终目标
本教程的最终目标是使用机器学习,通过实现 k-最近邻(KNN)算法,在一组真实数据上构建分类模型。不要不知所措,让我们一点一点地分解那是什么意思。
机器学习
机器学习是优化模型的技术集合。换句话说,机器学习采用我们建立的模型,并使用真实世界的数据来“学习”如何根据训练数据微调模型的参数,使其在真实世界的场景中最有用。在本教程中,我们将把机器学习应用于分类模型。如果你现在还不完全清楚,不要担心,在本教程结束时,你会确切地知道我在说什么。
训练集与测试集
机器学习算法基于一组训练数据来调整模型。训练数据是一个数据集,它包含我们所有可用的变量以及正确的分类。训练集可以用多种方式开发,但在本教程中,我们将使用由人类专家分类的训练集。重要的是要记住,机器学习模型只和训练数据一样好。你的训练数据越准确,越多越好。换句话说,垃圾进,垃圾出。
测试集通常是训练数据的子集,因为它还包含所有变量和正确的分类。区别在于我们如何使用它。虽然训练集有助于开发模型,但测试集会在真实世界场景中对其进行测试,并观察其效果如何。有很多复杂的方法来测量误差和测试模型,但是只要你掌握了基本的概念,我们就可以继续下去。
分类模型
分类模型只是一种数学工具,它根据一组变量或输入来确定您正在处理的事物的类别。例如,如果我想对一种动物是猫还是鱼进行分类,我可能会使用诸如该动物是否游泳、是否有皮毛以及是否进食等变量来确定它属于哪个类别。你会注意到两件事。首先,变量越多越好。有了更多的信息,你就可以更加确信你的分类是正确的。其次,有些变量比其他变量更有用或更有预测性。以最后一个例子为例,无论动物是否进食。不经意的观察者知道鱼和猫都吃,所以拥有这些数据对确定动物的种类没有用处。在这种情况下,机器学习的目标是在给定可用数据的情况下创建最有用的分类模型,并剔除不会提高模型有效性的输入。
k 个最近邻居
k 近邻(KNN)是一种特定类型的分类模型。直觉很容易理解。该模型获取关于未知数据点的所有可用数据,并将其与数据的训练集进行比较,以确定该训练集中未知点最相似或最接近的点。其思想是未知数据点将最有可能与它最相似的已知数据点属于同一类。KNN 只是一种确定两个数据点之间相似性的数学方法。
虹膜数据集
对于本教程,我们将使用一个用于教授机器学习的经典数据集,称为虹膜数据集。这是一个关于三种鸢尾花的数据集合和关于它们的四个数据片段:萼片长度、萼片宽度、花瓣长度和花瓣宽度。数据集已经准备好了,让初学者很容易直接进入。您可以通过点击右上角的“下载 zip”并在 excel 中打开内容,在此链接下载兼容 Excel 格式的数据。
准备我们的数据
正如我提到的,这个数据集应该易于使用。前 4 列(A-D)中的每一列都是数据的一个维度或特征。第五列 E 是花的种类。每一行都有自己的记录或数据点。如你所见,我们有 150 个已知的数据点要处理。
我们需要做出一个重要的决定:我们如何将这个数据集分成一个训练集和一个测试集。给定一个更大的数据集,我们可以使用优化技术来做出这个决定。因为这个数据集很小,而且是为初学者设计的,所以按照惯例,我们将把它分成 70/30。换句话说,我们将使用 70%的数据,即 105 个数据点作为训练集,剩余的 45 个数据点作为测试集。
我们现在将使用 Excel 随机抽取 70%的数据。首先,在工作表中添加一个名为“Random Value”的列,并使用 RAND()函数在 0 和 1 之间随机选择一个值。请记住,每次工作表重新计算时,RAND()函数都会重新选择一个新数字。为了避免这种情况,在生成我的数字后,我将复制它们(Ctrl+C ),然后将它们作为值(Ctrl+Shift+V)进行特殊粘贴,以便它们保持固定。我们将从单元格 F2 开始,向下拖动到最后一个数据点。
=RAND()
接下来,我将使用 Excel 的 rank()函数对它们进行 1 到 150 的排序,从如下所示的单元格 G2 开始,一直拖动到最后一个数据点。确保通过点击 F4 或手动添加$符号来锁定参考框架,否则这个公式不会像我们预期的那样工作。
=RANK(F2, $F$2:$F$15)
现在,每个数据点都有一个介于 1 和 150 之间的唯一值。因为我们希望我们的训练集有 105 个值,所以我们将再添加一列,并使用快速 IF()函数为我们的训练集选择从 1 到 105 的值。否则,我们将把这个值添加到我们的测试集中。同样,我们将从 H2 开始,向下拖动到最后一个数据点。
=IF(G2<=105,”Training”, “Test”)
此时,您的数据集应该像屏幕截图一样设置好了。请记住,因为我们每个人都采取了不同的随机样本,所以 F-H 列中的特定值对您来说会有所不同。您还应该花点时间为我们的下一步添加过滤器。
作者截图
接下来,我们将把两组数据分解到各自的工作表(或标签)中,以保持有序。创建一个名为“Training Set”的新工作表,并在原始工作表中筛选“Training”数据。将这些数据与标题一起复制并粘贴到您的“训练集”中您应该有 106 行(105 个值+标题行)。对工作表“测试集”执行相同的操作您应该有 46 行(45 个值+标题行)。
此时,您可以删除“Iris”工作表,并删除其余两个工作表中的 F-H 列,因为我们已经分离了数据。最后,我将在每个工作表的开头添加一个“ID”列,并通过简单地键入数字来分别标记每个数据点 1-105 和 1-45(向下拖动填充柄将是您的朋友,以节省您的工作)。这将有助于我们在下一节中进行计算。确保你的每一套都按照下面的例子来安排。
作者截图
构建模型
我们的数据现在已经准备好了,我们可以继续构建我们的模型。提醒一下,该模型通过将我们希望分类的未知数据点与其最近或最相似的邻居进行比较来工作。要做到这一点,我们需要在测试集中取每个点,并计算它到训练集中每个点的距离。
距离的概念
距离是数学家确定 n 维空间中哪些点最相似的方法。直觉告诉我们,两点之间的距离越小,它们就越相似。我们大多数人习惯于在二维空间中计算距离,例如 x,y 坐标系或使用经度和纬度。有几种方法可以计算距离,但为了简单起见,我们将使用欧几里德距离。下面是二维空间中欧几里得距离公式的可视化。如您所见,该公式的工作原理是在两点之间创建一个直角三角形,并确定斜边的长度,斜边是三角形的最长边,如箭头所示。
作者的图解
我们的数据集是四维的。我们很难想象超过 3 维的空间,但是不管你是否能想象,我们仍然可以用同样的方法计算两点之间的距离,不管维数是多少。欧几里德距离的通用公式如下:
知识共享许可下的维基百科截图
简单地说,这意味着两点之间的欧几里德距离 q & p 可以通过对每个点取每个维度来确定,从第一维开始,迭代求它们之间的差的平方,直到对所有维度都这样做,并将差加在一起。然后我们求这个和的平方根,就得到欧几里德距离。这听起来很复杂,但是一旦我们回到数据中,你会发现它实际上非常简单。
计算距离
在我们的工作簿中,创建一个名为“距离”的新工作表我们的目标是创建一个 45X105 矩阵,表示测试集和训练集中每个数据点之间的距离。在我们的例子中,每一行对应于测试集中的一个数据点,每一列对应于训练集中的一个数据点。从 A2 开始,逐行向下,直到到达 A46,用数字 1-45 填充每个单元格。同样,填充柄在这里很有用,所以你不必一个接一个地输入数字。现在,从 B1 开始,然后一列一列地横向排列,直到你到达 DB1,用数字 1-105 填充每一列。你的矩阵应该看起来像下面的截图,其中显示了一小部分。
作者截图
在继续之前,您需要将您的矩阵转换为表格,以便我们可以保持事情有组织。选择整个矩阵并按 Ctrl+T,然后将表格命名为“Distance_Table ”,并选择创建带有标题的表格。接下来,您需要将第一列命名为“Test ID ”,方法是在单元格 A1 中键入该名称。
既然桌子已经摆好,我们可以开始计算了。我们将从单元 B2 开始,它将计算训练集中的第一个点(ID #1)和测试集中的第一个点(ID #1)之间的距离。我们可以使用 excel 中的 VLOOKUP 函数来快速应用欧几里德距离公式,找到每个维度的值,然后根据需要进行计算。最好将此公式复制并粘贴到单元格 B2 中的编辑栏,因为它可以处理 Excel 中表格功能的一些特性,但请确保您理解此公式所做的一切是应用我们之前讨论的欧几里德距离公式。如前所述,您可以拖动它来填充整个表格。
=SQRT(((VLOOKUP(NUMBERVALUE(Distance_Table[[#Headers],[1]]), ‘Training Set’!$A$1:$F$106, 2, FALSE)-VLOOKUP(Distance_Table[@[Test ID]:[Test ID]], ‘Test Set’!$A$1:$F$46, 2, FALSE)) ^ 2+(VLOOKUP(NUMBERVALUE(Distance_Table[[#Headers],[1]]), ‘Training Set’!$A$1:$F$106, 3, FALSE)-VLOOKUP(Distance_Table[@[Test ID]:[Test ID]], ‘Test Set’!$A$1:$F$46, 3, FALSE)) ^ 2+(VLOOKUP(NUMBERVALUE(Distance_Table[[#Headers],[1]]), ‘Training Set’!$A$1:$F$106, 4, FALSE)-VLOOKUP(Distance_Table[@[Test ID]:[Test ID]], ‘Test Set’!$A$1:$F$46, 4, FALSE)) ^ 2+(VLOOKUP(NUMBERVALUE(Distance_Table[[#Headers],[1]]), ‘Training Set’!$A$1:$F$106, 5, FALSE)-VLOOKUP(Distance_Table[@[Test ID]:[Test ID]], ‘Test Set’!$A$1:$F$46, 5, FALSE)) ^ 2))
您应该会得到这样的结果:
作者截图
查找最近的邻居
在这个阶段,我们已经计算了测试集中的每个点和训练集中的每个点之间的距离。现在,我们需要确定测试集中每个点的最近邻居。创建一个名为“Nearest Neighbors”的新工作表,从 A2 开始逐行向下,用数字 1-45 填充单元格,以对应我们测试集中的点。我们的专栏不会像在以前的表单中那样代表训练集。相反,这些将代表 6 个最近的邻居,从第一最近的开始,然后是第二最近的,依此类推。第一个最近的邻居距离最小,第二个最近的邻居距离第二小,依此类推。您的工作表应该如下所示:
作者截图
正如我们之前所做的,我们将在 B2 单元格中编写一个公式,可以拖动它来填充矩阵的其余部分。我们的方法是识别距离表中对应行(2)中的最小值,找到该值的列号,然后返回列名,因为这将为我们提供定型集中该值的 ID。我们将使用索引和匹配函数的组合来实现这一点。请注意,我们能够使这个公式变得简单,因为我们有先见之明,将距离矩阵设置为 Excel 中的一个表格,因此我们可以轻松地获取标题。
=INDEX(Distance_Table[#Headers], MATCH(SMALL(Distance!$B2:$DB2, **1**), Distance!2:2, FALSE))
拖动此公式以填充最近邻矩阵的第一行。您需要手动调整 SMALL()函数中的粗体值来表示我们正在寻找的邻居。例如,要找到第二个最近的邻居,公式如下。
=INDEX(Distance_Table[#Headers], MATCH(SMALL(Distance!$B2:$DB2, **2**), Distance!2:2, FALSE))
请记住,您的值将是不同的,因为您用来形成测试集的随机样本与我的不同。
作者截图
在这个阶段,我通常会花一分钟时间,在可行的情况下手动仔细检查其中一行,以确保我的公式按预期运行。在大规模测试中,你会想要使用自动化测试,但是现在我们保持简单。
我们还有最后一步:我们需要确定每个最近邻居的分类。我们将回到 B2 的公式,并对其进行修改,以在训练集中对 ID 进行 VLOOKUP,并返回分类。然后我们将拖动它来填充矩阵。
=VLOOKUP(NUMBERVALUE(INDEX(Distance_Table[#Headers], MATCH(SMALL(Distance!$B2:$DB2, 1), Distance!2:2, FALSE))), ‘Training Set’!$A$1:$F$106, 6, FALSE)
后退一步
让我们后退一步,看看我们已经完成了什么。现在,您已经为测试集中的每个点确定了 6 个最近邻的分类。您可能会注意到,对于所有或几乎所有的数据点,6 个最近的邻居都属于相同的分类。这意味着我们的数据集是高度聚集的。在我们的例子中,我们的数据高度聚集有两个原因。首先,正如我们在教程开始时所讨论的,数据集被设计成易于使用。其次,这是一个低维数据集,因为我们只处理 4 个维度。当您处理现实世界中的数据时,您通常会发现数据的聚集程度要低得多,尤其是随着维度数量的增加。数据的聚类越少,构建有用模型所需的训练集就越大。
利用机器学习进行优化
如果我们的数据总是像 Iris 数据集一样整齐地聚集在一起,就不需要机器学习了。我们将简单地使用我们的公式找到最近的邻居,并使用它来确定每个未知数据点的分类。由于通常情况下不会这样,机器学习通过一次查看多个邻居来帮助我们更准确地预测未知数据点的分类。但是我们应该看多少邻居呢?这就是 K-最近邻中的“K”出现的地方。k 描述了在预测未知数据点的分类时我们将考虑的邻域数。
邻居太少或太多
直觉上,理解这个问题为什么棘手很重要。可能看的邻居太少,也可能看的邻居太多。特别是当维数增加时,最近邻可能并不总是正确的分类。查看太少的邻居会限制模型可用于做出决定的信息量。考虑太多的邻域实际上会降低模型用作输入的信息的质量。这是因为随着更多邻居的引入,数据中也引入了噪声。试想一下,在我们的示例中考虑所有 104 个邻居是没有意义的!请参见下面这个概念的可视化表示。
作者提供的图片
因此,这成为一个经典的优化问题,我们试图找到 K 值,给出最多的信息,而不是太高或太低。
使用您的测试集
对于本教程,我们将使用一个非常简单的试错过程来确定最佳 K 值。在我们继续之前,我建议看看你的最近邻工作表,猜测一下最佳 k 值可能是多少,只是为了好玩。我们很快就会知道你是否正确!
设置算法
算法只是计算机根据一组定义好的规则反复重复的一组步骤。在这种情况下,我们将告诉计算机尝试不同的 K 值,使用我们的测试集计算每个值的错误率,然后最终返回产生最低错误率的值。为此,我们需要创建一个名为“KNN 模型”的新工作表我们将如下设置它,用 1–45 为每个测试数据点标记 A4 到 A48 行。
作者截图
让我们从 b 列的预测值开始。我们需要这个公式根据 K 值进行调整。在 K 值为 1 的情况下,公式很简单,我们只取最近的邻居。
=’Nearest Neighbors’!B2
在 K 值大于 1 的情况下,我们将采用最常见的邻居。如果邻居的出现是平均分布的,例如当 K=6 时,如果 3 个邻居是 Setosa,3 个邻居是 Virginica,我们将支持最近邻居的分类。K=2 的公式如下。我们使用 IFERROR 是因为对于给定的 K 值,当有两个邻居出现相同次数时,该公式会返回错误。
=IFERROR(INDEX(‘Nearest Neighbors’!B2:C2,MODE(MATCH(‘Nearest Neighbors’!B2:C2,’Nearest Neighbors’!B2:C2,0))), ‘Nearest Neighbors’!B2)
您将需要在单元格 B4 中使用下面的扩展公式,该公式允许您使用 K 值,最大为 K=6。不需要担心这个公式的细节,只需复制并粘贴它。顺便说一下,不得不使用复杂、挑剔、难以理解的公式是我前面提到的 Excel 的局限性之一。这在 Python 中是小菜一碟。请注意,如果 K 中没有值或值不在 1 和 6 之间,此公式将返回错误。你应该把这个公式从单元格 B4 复制到 b 列。
=IFS($B$1=1, 'Nearest Neighbors'!B2, $B$1=2, IFERROR(INDEX('Nearest Neighbors'!B2:C2,MODE(MATCH('Nearest Neighbors'!B2:C2,'Nearest Neighbors'!B2:C2,0))), 'Nearest Neighbors'!B2), $B$1=3, IFERROR(INDEX('Nearest Neighbors'!B2:D2,MODE(MATCH('Nearest Neighbors'!B2:D2,'Nearest Neighbors'!B2:D2,0))), 'Nearest Neighbors'!B2), $B$1=4, IFERROR(INDEX('Nearest Neighbors'!B2:E2,MODE(MATCH('Nearest Neighbors'!B2:E2,'Nearest Neighbors'!B2:E2,0))), 'Nearest Neighbors'!B2), $B$1=5, IFERROR(INDEX('Nearest Neighbors'!B2:F2,MODE(MATCH('Nearest Neighbors'!B2:F2,'Nearest Neighbors'!B2:F2,0))), 'Nearest Neighbors'!B2),$B$1=6, IFERROR(INDEX('Nearest Neighbors'!B2:G2,MODE(MATCH('Nearest Neighbors'!B2:G2,'Nearest Neighbors'!B2:G2,0))), 'Nearest Neighbors'!B2))
接下来,我们想要引入每个测试点的实际的、已知的分类,这样我们就可以确定我们的模型是否正确。为此,我们在 C 列中使用快速 VLOOKUP,从 C4 单元格开始向下拖动。
=VLOOKUP(A4, ‘Test Set’!$A$1:$F$46, 6, FALSE)
然后,我们将在 D 列中设置一个公式,如果预测不正确或出错,则返回 1,如果预测正确,则返回 0。您将从 D4 单元格开始,向下拖动公式。
=IF(B4=C4, 0, 1)
最后,我们将使用单元格 B2 中的公式,通过将错误数除以数据点总数来计算错误率。按照惯例,我们将把它格式化为一个百分比。
=SUM(D4:D48)/COUNT(D4:D48)
运行算法
我们现在准备好运行不同 K 值的算法。因为我们只测试 6 个值,所以可以手工测试。但是这一点也不好玩,更重要的是不可扩展。在我们继续之前,您需要按照本文中的说明启用 Excel 的规划求解加载项。
现在,导航到数据功能区并单击求解器按钮。求解器按钮根据我们的指令自动为我们试错。您将看到一个参数或说明对话框,您需要按照如下所示进行设置。我们对它进行了设置,以便它在测试 1 到 6 之间的值时,只测试整数值,从而寻求最小化错误率。
作者截图
Excel 将旋转一分钟,在出现此对话框之前,您可能会看到它在屏幕上闪现一些值。您应该单击“确定”以保留规划求解解。
作者截图
解释错误率和求解器解决方案
由于数据具有多个最小值或最大值,许多优化算法具有多个解。这发生在我身上。事实上,在我的特殊情况下,从 1 到 6 的所有整数值都代表误差率约为 2%的最小值。那我们现在怎么办?
一些事情在我脑海中闪过。首先,这个测试集不是很好。该模型没有从测试集中获得任何优化好处,因此,我可能会重新进行测试,并再次尝试,看看我是否会得到不同的结果。我也会考虑使用更复杂的测试方法,比如交叉验证。
在我的测试集中,错误率如此之低,我也开始担心过度拟合。过度拟合是机器学习中出现的一个问题,当一个模型太适合特定训练或测试数据集的细微差别时。当一个模型过度拟合时,当在野外遇到新数据时,它就不那么有预测性或有效了。当然,对于这样的学术数据集,我们希望我们的错误率相当低。
接下来要考虑的是,如果我已经确定了几个最小值,选择哪个值。虽然在这个特定的例子中测试并不有效,但通常我会选择最少数量的邻居,这是为了节省计算资源。如果我的模型必须考虑更少的邻居,它将运行得更快。对于小数据集来说,这不会有什么不同,但是像这样的决策可以节省大量的资源。
结论
太棒了。您已经学习了机器学习的基础知识,并且实现了 KNN 算法,所有这些都没有脱离 Excel 的限制。请记住,Excel 仅仅是一个工具,重要的是您理解使这种方法起作用的直觉和概念。当你更深入地钻研数据科学和机器学习并开始开发自己的模型时,理解这些基础知识将有助于你。
机器学习匹配
原文:https://towardsdatascience.com/machine-learning-matchmaking-4416579d4d5e?source=collection_archive---------30-----------------------
利用机器学习寻找与 R 相容的伙伴
金智秀在 Unsplash 上的照片
一个简单的问题,比如“你如何找到合适的伴侣?”是什么促使我尝试做这个项目,以便为人群中的任何人找到一个兼容的伴侣,这篇博客帖子背后的动机是以尽可能清晰的方式解释我对这个问题的方法。
你可以在这里 找到项目笔记本 。
如果我让你找一个搭档,你下一步会怎么做?如果我让你找一个合适的合作伙伴呢?这会改变事情吗?
一个简单的词如兼容可以让事情变得棘手,因为显然人类是复杂的。
数据
由于我们找不到任何可以涵盖人物角色变化的单一数据集,我们求助于使用大五个性数据集、兴趣数据集(也称为年轻人调查数据集)和婴儿名字数据集。
Big5 个性数据集:我们选择 Big5 数据集的原因仅仅是因为它通过 Big5/OCEAN 个性测试提供了一个关于任何个人的个性的想法,该测试向受访者提出了 50 个问题,每个问题有 10 个关于开放性、尽责性、外向性、宜人性&神经质的问题,以 1-5 为尺度进行衡量。你可以在这里阅读更多关于 Big5 的内容。
兴趣数据集:,它通过要求人们对 50 个不同的兴趣领域(如艺术、阅读、政治、体育等)进行评分,涵盖了一个人的兴趣&爱好。)在 1-5 的范围内。
婴儿名字数据集:帮助分配一个真实和独特的名字给每个回答者
这个项目是用 R 语言(版本 4.0.0)
在 dplyr 和集群包的帮助下完成的
处理
加载 Big5 数据集,该数据集有 19k+个观察值,57 个变量,除了个性问题外,还包括种族、年龄、性别、国家。
删除那些没有回答一些问题的回答者&一些年龄值模糊的回答者,例如:412434,223,999999999
以 5000 名受访者的健康样本为例,因为当我们希望找到数千个观察值之间的欧几里德距离以进行聚类时,我们不想让笔记本电脑去度假:)
加载婴儿姓名数据集,并添加 5000 个唯一的真实姓名,以将每个观察结果识别为一个人,而不仅仅是一个数字。
加载兴趣数据集,数据集有 50 个变量,每个变量都是兴趣或爱好
热图向我们展示了一些领域,如医学、化学;戏剧、音乐剧;和政治、历史表现出某种关联。这个观察很重要,因为我们将在前面使用这个知识。
加载完所有数据集后,我们将它们合并到一个主数据帧中,并将其命名为 train,,此处显示了 107 个变量:
一些图表来看看我们的数据是如何按照年龄和性别排列的
我们可以看到大多数受访者是年轻人,女性受访者多于男性
主成分分析
还记得我们在热图中看到了很少的相关性吗?这就是主成分分析发挥作用的地方。PCA 将一些相似变量的影响组合成一个主成分列或 PC。
对于不知道什么是主成分分析的人;
PCA 是一种降维技术,它专注于通过一个方程从所有变量中创建一个全新的变量或主成分(简称 PC ),以从数据中抓住最大可能的变化。
简单地说,主成分分析将帮助我们只使用几个考虑到最重要和最易变的变量的成分,而不是使用所有 50 个变量。你可以在这里了解更多关于 PCA 的知识。
重要 :我们分别对兴趣变量和 Big5 变量运行 PCA,因为我们不想混合兴趣&个性。
在对利息变量进行主成分分析后,我们得到的是 50 个。现在有趣的部分来了,我们不会使用所有的变量,原因如下:第一台 PC 将是最强的,即一个变量将掌握我们数据中的大部分变化,第二台 PC 将较弱,将掌握较小的变化,以此类推,直到第 50 台 PC。
我们的目标是找到使用 0 到 50 个 PCs 之间的最佳点,我们将通过绘制 PCs 解释的方差来实现:
这些图向我们展示了每个 PC 解释的变化比例。左图:显示了每台电脑的单独性能(例如,第一台电脑解释了我们数据中约 10%的变化,但第 15 台电脑仅解释了 2%)
右图:左侧图表的累积版本。
我们看到,10 件之后,个人贡献非常低。
但是我们会稍微延伸一下,以覆盖 60%的差异&取出 14 件。
结果呢?我们刚刚将变量数量从 50 个缩减到 14 个,这解释了原始利息变量中 60%的变化。
同样,我们对五大变量进行主成分分析:
我们再次看到第一个 PC 是最强的,并且解释了超过 16%的方差。
当斜率在第 8 个 PC 后开始变平时,我们将使用 12,以掌握大约 60%的方差。
既然我们已经将 Big5 中的变量从 50 个减少到 14 个,将中的变量从 50 个减少到 12 个,我们将它们组合成一个不同于 train 的数据框架。我们称之为 pcatrain。
带有变量名的 pcatrain 数据帧一瞥
使聚集
作为一个好的实践,我们首先使用层次聚类来找到一个好的 k 值(聚类的数量)
分层聚类
什么是层次聚类?这里有一个例子:想象一个 100 人的家庭聚会,现在我们从每个人代表一个人的集群开始。下一步?我们将站得最近的两个人/群组合成一个群,然后我们将另外两个最近的群标记为一个群,等等。最后,我们从 100 个集群发展到 1 个集群。分层聚类所做的是根据聚类之间的距离形成聚类,然后我们可以在树形图中看到该过程。
红线可能是一个分界点
在进行了层次聚类之后,我们可以在这里看到我们自己的聚类树状图,当我们从底部到顶部时,我们看到每个聚类都在收敛,每个聚类离另一个聚类越远,收敛所需的步骤就越长;你可以通过观察垂直连接看到。
根据距离,我们用红线将一个健康的群体分为 7 个不同的集群。7 后面的原因是,7 个集群需要更长的步骤来收敛,即集群是遥远的。
k 均值聚类
我们使用 K-Means 中的 肘方法 来确保取 7 个左右的聚类是一个好的选择,我们不会深入研究它,但是总结一下:个体之间的聚类内距离的边际总和&聚类中心之间的边际距离在 6 个聚类中最好 。
具有 6 个聚类的 k-均值聚类
我们运行 K 均值聚类,K = 6;检查每个群集的大小;前 10 个人被分配到哪个组。最后,我们将这个集群变量添加到我们的 pcatrain 数据帧中,现在我们的数据帧有 33 个变量。
最后的步骤
既然我们已经分配了聚类,我们可以开始为任何个体寻找接近的匹配。
我们选择 Penni 作为随机个体,我们将从她的集群(即集群 2)中为其找到匹配
在左边,我们首先从 Penni 的集群中找到人,然后过滤掉那些与 Penni 在同一个国家、性别相反、属于 Penni 年龄类别的人。
有些人和彭尼属于同一个群体,同一个国家,同一个年龄组
好了,现在我们已经过滤掉了人,是吗?
不记得我们一开始问的问题吗?
“你如何找到一个合适的伴侣?”
即使我们已经找到了有相同兴趣和年龄组的人,我们也必须找到与 Penni 个性最相似的人。
这就是五大性格变量派上用场的地方。
通过 Big5,我们将能够找到与 Penni 具有相同开放、尽责、外向、随和和神经质水平的人。
我们在这里所做的是为每个人格变量找到 Penni 的反应和过滤后的人的反应之间的差异,然后将所有变量的差异相加。
例如:Brody 的 sumdifference = 8.9,即在 Big5 的 50 个问题中,Brody 的回答与 Penni 的回答仅相差 8.9 分。
所以现在我们知道了,如果 Penni 正在寻找伴侣,她应该首先设法与 Brody 见面。
我们为 Penni 寻找合适人选所做工作的总结:
- 根据兴趣把人们聚集在一起。
- 找到了和 Penni 兴趣相投、年龄相仿的人。
- 根据他们的个性与 Penni 的个性的匹配程度对那些被过滤的人进行了排名。
谢谢你坚持到最后!
您可以通过以下方式与我联系:
Github
领英
帮助应对冠状病毒的机器学习方法
原文:https://towardsdatascience.com/machine-learning-methods-to-aid-in-coronavirus-response-70df8bfc7861?source=collection_archive---------4-----------------------
用数据科学和人工智能对抗冠状病毒
每个人都担心冠状病毒,迫使我们几乎所有人都呆在室内,ML 社区的许多人想知道他们如何才能提供帮助。虽然有其他关于用人工智能对抗冠状病毒的文章,但很少有人提供真正全面的观点。因此,我决定汇集一份应用于冠状病毒的机器学习的数据集和用例列表。我理解有人批评说,当你有一把锤子时,每个问题看起来都像钉子;换句话说,对于机器学习实践者/数据科学家来说,每个问题似乎都有一个 ML 解决方案。尽管如此,我相信机器学习和数据分析可以帮助加快解决方案,并结合所有其他伟大的研究和规划,将病毒的影响降至最低。
正如我们将在下面看到的,机器学习可以帮助加快药物开发过程,提供对当前抗病毒药物可能带来的好处的见解,预测感染率,并帮助更快地筛选患者。此外,虽然目前没有研究,我认为还有其他几个适当的应用领域。也就是说,存在许多障碍,这些障碍与缺乏有限的训练数据、将复杂结构集成到 DL 模型中的能力以及可能最重要的是对可用数据的访问有关。我不打算详述下面的技术(因为我的化学/药物开发知识严重缺乏,所以我不能),而是旨在总结不同的资源。此外,我将创建一个中央 GitHub 知识库,列出使用人工智能对抗冠状病毒的资源。如果您发现其他对您有帮助的资源/数据集,请随时提出拉取请求。
首先,我要快速提醒你几个注意事项:
- 这里提到的几乎所有论文和数据集都是最近的,因此没有经过同行评审或验证。用怀疑的态度对待索赔。
- 除了我们在机器学习中使用的正常最佳实践,我建议至少咨询一位相关领域的专家(例如,流行病学家、化学家、生物学家等)。这提供了一个健全性检查,因为有时机器学习研究人员可能会误解需要解决的问题。此外,重要的是不要助长已经存在的大量错误信息。
数据集和机器学习对冠状病毒的应用
大多数应用属于以下四个领域之一:
(A)预测蛋白质的结构及其与化学化合物的相互作用,以促进新的抗病毒药物/疫苗或推荐当前的药物。
这里的方法依赖于对蛋白质等分子应用深度学习。这是一个有点小众的领域,通常需要很高的学习曲线才能理解。然而,这方面的突破可能为疫苗或有效的抗病毒药物铺平道路。下面列出的大多数技术以某种方式使用卷积神经网络来模拟分子或分子相互作用。然而,
1。基于深度学习的新型冠状病毒 2019-nCov 药物筛选(张等)。这篇文章研究了使用深度学习来预测当前哪些抗病毒药物可能有助于冠状病毒患者。作者使用改进的 DenseNet(用完全连接的层代替卷积)来预测蛋白质-配体相互作用。然后,他们可以使用冠状病毒的 RNA 序列和化学化合物的模型来预测哪种药物效果最好。作者得出结论,更多的研究是必要的,但建议腺苷,维达布雷,和其他化合物可能有帮助。
2.预测市场上可买到的抗病毒药物,这些药物可能会对人类产生影响。新型冠状病毒(2019-nCoV),中国武汉,通过药物-靶标相互作用深度学习模型这与上面讨论的论文类似,但是作者研究了市售药物,并采取了完全不同的建模方法。在这里,作者使用了一个名为“分子转换器-药物靶标”或 MT-DTI 的网络。有趣的是,熟悉 BERT 的人可能已经猜到其核心是相同的架构。然而,在这种情况下,网络是在微笑数据集上训练的,这是一个将分子表示为文本以编码和解码每个分子的大型数据集。这实际上可以形成分子的有效表示,就像文本数据一样。然后,作者对这个预先训练的模型进行了微调,以预测“商业可用的抗病毒药物和目标蛋白之间的结合亲和力值。”他们发现“2019-nCoV 3C 样蛋白酶被预测与 atazanavir 结合。”具体来说,atazanavir 是一种用于治疗艾滋病毒/艾滋病的抗病毒药物。这为如何适应不同领域的新深度学习架构提供了一个很好的用例(尽管显然这不应被视为医学建议)。
3。Deepmind 使用来自 GISAid 和他们的 AlphaFold 库的可用数据来预测新冠肺炎病毒的蛋白质结构。AlphaFold 是一个计算化学的深度学习库。有了这些蛋白质结构(如果正确的话),研究人员将深入了解病毒的分子结构,这可能为更快地找到疫苗或抗病毒药物铺平道路。
(B)预测感染率和传播/病人预后,使医院/卫生官员能够更好地规划资源和应对措施。
实际上还没有太多的模型(至少是公开记录的模型)明确地试图模拟冠状病毒的传播。然而,大量先前的研究已经研究了预测季节性流感和其他疾病的爆发。有趣的是,目前用于预测疾病传播和患者死亡率的大量方法都是基于浅层方法。我认为使用具有注意力+转移学习(对相关流感爆发数据)的深度学习模型在这一领域取得更好的结果有很大的潜力。
- 使用三种临床特征预测严重新冠肺炎感染患者的危急程度:基于机器学习的武汉临床数据预后模型:在这篇文章中,作者描述了使用 XG-Boost 模型根据年龄和其他风险因素预测感染新冠肺炎的患者是否会存活。这有助于形成关于谁应该最大程度地与疾病隔离的建议。
- 从小数据集发现准确的早期预测模型:2019-nCoV 新型冠状病毒爆发案例:
- 基于数据的新冠肺炎疫情分析、建模和预测
- 利用卡尔曼滤波器预测冠状病毒的传播
(C)帮助诊断 x 光或 CT 等医学图像是否显示冠状病毒。
从 CT 扫描中诊断冠状病毒相关肺炎的病例可以潜在地缩短诊断时间并实现更好的治疗。随着创纪录数量的患者涌入 ICU,放射科医生很快就会不知所措。对成像的深度学习可以帮助减轻负担。此外,了解疾病在 CT 扫描中的表现有助于对疾病本身有更多的了解。
图自基于深度学习的 2019 新型冠状病毒肺炎检测模型
- 基于深度学习的模型在高分辨率计算机断层扫描上检测 2019 新型冠状病毒肺炎:一项前瞻性研究(陈等)在这里,作者使用 UNet++从 ct 扫描中提取相关特征并进行分类。作者在 106 名住院患者的 40k 扫描数据上训练了该模型。作者发现,该模型在精确度和召回率方面表现良好。具体来说:“该模型实现了每个患者的灵敏度为 100%,特异性为 93.55%,准确性为 95.24%,PPV 为 84.62%,NPV 为 100%;在回顾性数据集中,每个图像的敏感性为 94.34%,特异性为 99.16%,准确性为 98.85%,PPV 为 88.37%,NPV 为 99.61%。对于 27 名预期患者,该模型取得了与专家放射科医生相当的性能。在模型的辅助下,放射科医生的阅读时间大大减少了 65%。”因此,总之,该模型在优化放射科医生的工作流程方面非常有效。这是人工智能在现实世界中产生积极影响的一个很好的例子。因此,放射科医生可以在相同的时间内检查更多的 CT。然而,值得注意的是,在只有 27 名患者进行前瞻性测试和 44 名患者进行回顾性测试的测试组中,异常的分数似乎是存在的。此外,所有这些患者都来自同一家医院。虽然这表明该模型学到了一些东西,但尚不清楚它在更大和更多样化的测试人群中有多稳健。
- 一种利用 CT 图像筛查冠状病毒疾病的深度学习算法(新冠肺炎)
图自论文 一种利用 CT 图像筛查冠状病毒疾病的深度学习算法(新冠肺炎)
- 深度学习系统筛查冠状病毒疾病 2019 肺炎 这篇文章与上面两篇类似除了数据集中的患者总数稍大一点。他们从中国三家医院的大约 509 名患者(包括 175 名健康者)中收集样本。有趣的是,他们的准确率和召回率显著低于陈等人。艾尔。一个原因可能是,尽管有更多的患者,他们使用明显更少的扫描来训练模型。
(D)挖掘社交媒体数据,以更好地估计传播/症状和一般公众感知
这一领域的工作重点是挖掘社交媒体数据,以获取有关疾病的相关信息。虽然社交媒体在某些方面非常嘈杂,但它可能包含更多关于症状/在公众中传播的信息。在这一点上,再一次没有人(至少公开地)对挖掘社交媒体数据明确用于冠状病毒追踪进行过研究。然而,有许多关于相关事件的出版物。
通过社交网站进行流感检测和预测的综述
使用实时社交媒体流预测流感水平
利用 Twitter 数据样本进行地区流感预测
数据集
以下是与冠状病毒相关的数据集列表,上面列出了相应的类别。
冠状病毒基因组链接(需要一个 GisAid 账户,不幸的是,除非你有学术背景,否则很难获得这个账户)。这就是 Deepmind 用来预测蛋白质结构的方法,也是张等人获得 RNA 序列的地方。(一)。
Kaggle 上的冠状病毒基因组(一)
新冠肺炎开放研究数据集 Challeng e (CORD-19) (B,C,D)这是今天(3/16/20)在 Kaggle 上发布的一个有趣的新数据集。它包含超过 29,000 篇关于新冠肺炎、SARS、MERS 和相关病毒的学术文章。比赛分为 10 个独立的部分,每个部分都有自己的获胜者。我不会在这里一一列出,但是你可以在这个链接看到它们。竞赛的主要目的是从这个庞大的数据集中提取与这种疾病最相关的信息。你可以在 Kaggle 上正式加入比赛。
Chemdiv 数据库不同化合物的数据库。(一)
GitHub 冠状病毒这个 GitHub repo 是每日约翰·霍普斯金数据的链接,全部是 CSV 数据格式。(二)
新冠肺炎韩国数据集&综合医疗数据集&可视化器:这是一个综合数据集,包含了韩国所有关于该疾病的可用数据。(二)
新冠肺炎脆弱性指数 (B)一套开源模型,可用于测试个人感染冠状病毒的风险。
新冠肺炎图像数据收集 (C)该数据集包含冠状病毒和其他肺部疾病的 X 射线和 CT 扫描。
冠状病毒推特数据集 (D)
其他资源/文章
来自《麻省理工评论》的关于 CDC 如何预测冠状病毒的非技术性文章。不幸的是,他们似乎没有提供任何关于他们模型的额外细节。然而,他们强调了小数据的问题。
CT Angel 这似乎是一个链接到论文的中文网站,允许用户上传 CT 扫描并查看模型是否检测到冠状病毒(尽管如前所述,这尚未经过同行评审,不应被用作医疗建议)。
TWIML 播客本播客详细介绍了专注于传染病监测的多伦多人工智能初创公司 BlueDot 如何帮助预测冠状病毒的爆发和传播。不幸的是,似乎没有任何链接到他们的数据或他们的方法的进一步描述。
利用深度学习算法预测武汉 2019 新型冠状病毒的传染性 这与其说是遏制当前疫情的方法,不如说是一种帮助预防未来疫情的可能方法;这个模型在未来可能会被证明是强大的。在这里,作者打算建立一个模型,从动物体内的病毒中提取 DNA 链,并预测它是否有可能感染人类。
其他想法和建议。
我认为这次爆发表明,需要从相对较少的例子中学习并快速适应分布变化的稳健模型。例如,假设您已经在 MIMIC-III 重症监护数据集上训练了一个模型来预测患者住院时间和死亡风险。现在,您预计冠状病毒患者将涌入您医院的 ICU,但只有来自其他几家医院的非常有限的关于冠状病毒患者轨迹的数据(甚至根本没有数据)。这是一个很好的例子,说明由于培训和生产分配之间的转变,许多模型将完全崩溃。这也是像无监督领域适应和元学习这样的最新技术可以证明非常强大的地方。例如,如果相反,我们已经训练了一个深度学习模型来学习如何使用流行的元学习策略进行学习(例如,通过 ICD 代码将数据集划分为任务分布),该模型可能能够适应预测只有五个左右患者的患者轨迹。此外,一些技术,如连续域适应 n 可以使模型持续适应到来的分布变化(没有任何新数据)。不幸的是,这些方法通常仅应用于非常受限的图像分类情况(尽管本文确实展示了使用 DA 分割不同患者群体的肺部 X 射线的潜力)。然而,总的来说它们在野外的表现还有待观察。
医疗保健中机器学习的另一个未被充分利用的领域是医院整体运营。这部分是因为医院不愿意分享他们的数据(稍后会有更多关于这一点的内容),但在我看来,也是因为这比简单地将胸部 x 光片交给 CNN 要困难得多。在这种情况下,医院可以被认为是一个大规模的强化学习问题,其中只有有限数量的床位、人员和其他资源。强化学习或优化问题本质上是学习最有效地利用可用资源来改善患者的结果。这在诸如当前医院被推到边缘的危机中可能特别有用。此外,通过在历史数据(和其他类似的医院)上运行这些模型,它将有望帮助医院识别缺点,以便在未来提供更好的管理资源,特别是当与前述疾病爆发模型相结合时。
最后,也许是最重要的:为了取得进展,我认为地方需要开始共享他们的数据。数据绝对应该去匿名化,去除个人身份信息,但之后,医院/诊所应该公开共享。太多的医疗数据继续闭门不出,或者只有在提交“详细的合作建议”后才可用此外,像 GISAID 这样声称可以公开访问的网站,实际上需要公开访问,而不是只对少数人开放。edu 电子邮件地址和一个学术部门网页。保护病人的隐私很重要,但是研究小组经常把它作为关闭他们数据的一个方便的借口。此外,作者需要确保他们清楚地解释如何访问原始数据(如果有的话)。如果数据是专有的或需要注册,这应该在附录中清楚地注明。仅仅在链接到另一项研究的前一项研究上附加一条引文,就会导致作者徒劳地试图找到原始数据来源。虽然其中一些变化可能会有争议,但我相信它们是必要的,以使人工智能能够解决这种规模的健康挑战。
总之,有许多机器学习的潜在有效应用来对抗新冠肺炎,然而,大多数仍处于早期阶段。此外,缺乏数据共享继续抑制各种医学研究问题的整体进展。然而,我相信利用元学习、领域适应和强化学习等东西,同时放松对医疗保健数据的限制,可以让 ML 在遏制/应对冠状病毒和未来大流行方面发挥重要作用。与此同时,大家注意安全!
编者按:towardsdatascience.com 是一家主要基于数据科学和机器学习研究的中型出版物。我们不是健康专家或流行病学家。想了解更多关于疫情冠状病毒的信息,可以点击 这里 。
使用遗传算法寻找重要特征
原文:https://towardsdatascience.com/machine-learning-mini-project-4-finding-important-features-using-genetic-algorithms-for-heart-d069e205305f?source=collection_archive---------10-----------------------
机器学习迷你项目
(用于心力衰竭存活预测)
国立癌症研究所在 Unsplash 上拍摄的照片
原文如下:
机器学习可以仅从血清肌酐和射血分数预测心力衰竭患者的存活率。 BMC Med 通知 Decis Mak 20, 16 (2020)。https://doi.org/10.1186/s12911-020-1023-5
这个数据集有 12 个特征,你可以从 UCI 机器学习库下载。它是一个二元分类、监督学习问题,以“死亡 _ 事件”为目标变量,1 表示死亡,0 表示幸存。
问题来了:寻找最佳学习者(算法)和最佳特征子集的最高效方法是什么?有时,令人惊讶的是,一小部分功能比全部功能表现得更好。找到那个集合的最好方法是什么?
首先,让我们把最好的学习者的问题放在一边。我们知道的一件事是,有些学习者比其他人训练得更快。如果您想测试用于特征选择的遗传学习算法,您会发现使用逻辑回归是最快的方法,而像 Random Forest 或 LightGBM 这样基于树的方法需要更长的时间,甚至可能无法正常工作,这取决于您使用的库。
纸质结果
奇克和朱尔曼的发现是:
- 随机森林是最好的算法
- 统计和机器学习方法都表明射血分数和血清肌酸酐是最重要的特征之一,你可以仅仅根据这些特征建立一个模型。
这个实验的结果
- 遗传算法可以挑选各种特征子集
- 由此得出的结果取决于您为算法选择的超参数,但这也需要您使用某种形式的交叉验证评分来仔细审查每个候选项。甚至您的交叉验证参数(折叠次数和重复次数)也会改变结果。
- 血清肌酸酐和射血分数,正如他们所说,非常重要。该论文的第一个实验没有使用时间特征,这是随访后几个月的时间,因为它本身不是一个临床特征。然而,在他们论文的第二个实验中,他们确实包括了它。对于这个项目,我是 排除 的时间特性。
安装库
大多数情况下, sklearn-genetic 用于遗传算法(GA)方法,如果你想使用一些 autoML 类型的方法,安装 pycaret 。除此之外,我们只需要熊猫和熊猫。
什么是遗传算法?
来自维基媒体
基本上,在我们的例子中,我们将一个特性的包含或排除视为一个二进制字符串,即一个由 1 和 0 组成的字符串,其中 1 表示该特性被包含,0 表示它不被包含。这意味着,由于我们有 12 个特性,显然有 2 种可能性或整个特性集的子集需要考虑。遗传算法的要点不是测试所有这些,而是考虑几个子集——让我们称之为几个“个体”——然后评估它们的“适应度”值,这当然意味着一个数学函数。因此,让我们说,我们不是使用 2 个“个体”,而是使用大约 20 或 50 个个体,找到那些具有更大“适应度”值的个体,让它们“繁殖”,并产生具有其父母某些特征的后代,同时还允许随机突变——生物学 101!当然,多少混合和变异是你可以控制的,这是随机的,但概率是你可以调整的算法的超参数。你还可以决定你想要多少代——显然,你的代数越多,你找到全局最优解的机会就越大,这是一个基因“最适合”的群体。你还需要考虑一些提前停止的标准,这样这个过程就不会陷入局部极小值或者比需要的时间更长。下图解释了一般过程:
交叉率决定了基因如何传递给后代——也就是说,后代在什么点上,以什么概率从父母那里获得基因。换句话说,它决定了父母和后代之间的“混合”程度或基因相似程度。显然,你不希望后代成为他们父母的副本——你可能也希望有一些突变的后代,只是为了在混合物中加入更多的遗传多样性,希望在某个时候,不屈不挠的适应性的完美突变出现,随之而来的是你无法超越的机器学习模型。所以你也有突变率作为超参数。
你可以在这里阅读对遗传算法[的更好的解释。让我们来看一个简单的方法来解决这个监督学习问题。](http://Introduction to Genetic Algorithms — Including Example Code ...towardsdatascience.com › introduction-to-genetic-algor...)
逻辑回归+遗传算法
这是遗传算法的代码,它将为我们选择一个特征子集:
代码中需要注意的事项:
- 学习者的选择:这件事可能需要很长时间。为了节省时间,首先要做的是:使用逻辑回归(LR) ,因为它总是训练速度最快的方法之一。论文的作者提到随机森林模型是好的,但是如果你在这个 GA 过程中使用 RF,你会发现它比 LR 花费更多的时间。然而,基于树的模型可以考虑功能交互和其他可能影响功能选择的因素。因此,您可能希望在特性选择过程中包括 RF,以确保不会遗漏任何东西。
- 交叉验证方案。开始的时候少尝试劈叉,意思是 5 折交叉,开始的时候不要做那么多重复。当然,你最好能重复 100 或 1000 次,但也许一开始做 1 次、5 次或 20 次会让你充分意识到哪些特性是重要的。
- 人口设定为 50。你可以更高,比如 100,200,500。变异率——变异率越高,你获得多样性的机会就越多,但这并不能保证你会得到最佳选择。这取决于需要多少代的变异和交叉来创造更多合适的候选者。
- 每个实验的分数来自 selector.generation_score,它是每一代分数(Matthews 相关系数)的列表,通常分数会在每一代中提高,所以我只使用最后一个分数作为模型的最终分数(selector.generation_score[-1])
长话短说——摆弄参数。这张表格显示了我的最终结果:
GA 算法发现 4 或 5 个特征子集工作良好。
这个算法的“赢家”:基数为 5 的特征子集,具有{年龄,肌酸酐 _ 磷酸激酶,糖尿病,射血分数,血清肌酸酐} 作为特征。我们可以预计 MCC 值约为 0.40。现在让我们使用 pycaret 更彻底地测试一下,这是一个 autoML 类型的包,让一切都变得容易。
比较模型函数向我们展示了这一点:
因此,你可以看到,正如论文作者所声称的那样,随机森林分类器是最好的。这是使用 5 折 20 次重复的方案。让我们看看当我们创建一个随机森林模型时会发生什么,但是有 5 个分裂和 50 个重复,即 250 个训练模型:
随机森林模型,5 重 CV 和 50 次重复。
您可以看到 标准差为 0.1305,相当高 。它表明,虽然 RF 比大多数更好,但在给定的 train/val 集合上,它可能并不总是表现得更好。
在学习者对比表中可以看到,XGBoost 和 LightGBM 似乎全线 0。我不确定这是为什么,但我只是使用常规的 sklearn 和相同的 cross-val 方案进行了实验。在本次实验中,XGBoost 得分为 0.359,LGBM 得分为 0.378 ,处于群体中间。
基线—无特征选择
没有任何特性选择,pycaret 向我们展示了这一点
这是针对所有特征的,没有特征选择。整体性能下降。还有,CatBoost 和 RF 一样好。
我们可以看到,整体的 MCC 分数低于遗传特征选择时的分数。这也与论文中所声称的一致。
当您这样做,但是 py caret“feature _ selection”参数设置为 True(它执行自己的特征选择)时,我们会发现
pycaret,但 feature_selection = True。艾达绕过这个。
这有点令人惊讶,因为不仅 LDA 是最好的模型,而且 RF 和其他 GBM 也不如它们通常的表现。
从模型中选择
从模型中选择是 sklearn 内置的特征选择方法之一。我们用它作为与气体比较的手段。它选择的特征是:{ '年龄','肌酐 _ 磷酸激酶','射血分数','血小板','血清肌酐','血清钠' } 。然后,我们将这个特性集再次通过 pycaret 运行,下面是我们的发现:
使用“从模型中选择”功能比较模型
所以这个特征子集也不错,但是比来自遗传算法的更小的子集略胜一筹。有一点是清楚的:有特征选择倾向于提高分数。更多详情,请看我打开的 Google Colab 笔记本。
因此,您可以看到,虽然在 GA 算法评分过程中,特征子集是按性能排序的,但这并不意味着当 cross_val 更改为 100 次重复时,它们会按该顺序评分。最高分来自第 6 个候选人,其选择的特征为 {“年龄”、“肌酐 _ 磷酸激酶”、“射血分数”、“血清肌酐”、“吸烟”、“时间”} ,得分为 a 0.868 。
也就是说,除了最后一个都在 0.86 以上。其实倒数第二个的分数是 0.863 ,只有特征 {“射血分数”、“血清肌酐”、“性别”、“时间”} 。这意味着,如果您正在尝试或需要一个更简洁的模型,那么使用这个特性子集是合理的。这些模型中的任何一个即使不比具有所有特性的基线模型更好,也一样好,所以没有压倒性的理由将所有特性保留在模型中。
逻辑回归+从模型中选择
这是 sklearn 中的 SelectFromModel:
从这个过程来看,胜出者是 {“年龄”、“射血分数”、“血清 _ 肌酐”、“时间”} ,得分 0.864。
从各种功能组合的模型得分结果中进行选择。
逻辑回归+顺序浮动特征选择(SFSS)
这种方法有点贵,涉及一种测试各种功能组合的算法,尽管与 GA 不同,它不涉及任何交叉或变异过程,它基本上是,找到一个好的功能,再添加一个,看看是否有帮助,如果有帮助,就保留它并添加另一个,当添加更多功能似乎没有帮助时停止。这种算法的“浮动”版本允许您去掉它们没有帮助的功能,这允许您通过替换可能看起来不错但后来发现不“玩得好”的功能来测试更多的组合,添加更新的功能。这有点像在团队运动中进行替换或交易——有时你必须移除一名优秀的球员,因为没有这名球员可能会有更好的组合。
你可以从 sklearn 的一个实验版本中得到 SFSS,但是我刚刚从 mlxtend 中得到它,这对我来说更容易。这里有一个链接,链接到我的 Colab 笔记本中有我的代码的单元格。
通过四个简单的步骤将机器学习模型部署为 REST API
原文:https://towardsdatascience.com/machine-learning-model-deployment-as-rest-api-in-four-easy-steps-e65764f7c5c?source=collection_archive---------6-----------------------
分四步部署您的机器学习模型
在我之前关于机器学习集成建模的博客中,我们开发了一个分类模型,根据病史和诊断,如患者的怀孕次数、身体质量指数、胰岛素水平、年龄等,将患者分类为糖尿病或非糖尿病患者。
下面是文章的链接:
[## 集成学习
集成技术在通过 bagging 减少方差、通过 boosting 减少偏倚和提高预测精度方面具有强大的功能
medium.com](https://medium.com/sanrusha-consultancy/ensemble-learning-bagging-f9329e07fc22)
以下是该博客中创建最佳模型的数据来源和练习摘要:
数据源:
[## 皮马印第安人糖尿病数据库
基于诊断方法预测糖尿病的发病
www.kaggle.com](https://www.kaggle.com/uciml/pima-indians-diabetes-database/data)
下面是模型的 Python 代码:
import pandas as pd
import numpy as np
from sklearn.ensemble import RandomForestClassifier# Read data into pandas dataframe
df=pd.read_csv(r'C:\Machinelearning\diabetes.csv')
#Define Feature Matrix (X) and Label Array (y)
X=df.drop(['Outcome'],axis=1)
y=df['Outcome']lr=RandomForestClassifier(n_estimators=53, n_jobs=1,random_state=8)
lr.fit(X,y)
好了,我们准备好模型了。现在是时候部署它了。
在现实生活的项目中,机器学习模型被其他应用程序使用。这些应用程序可以是任何东西,可以是面向客户的运营应用程序(如公司网站)或后台应用程序(如 ERP ),也可以是数据分析应用程序。这些应用程序应该能够向模型发送特征变量值并获得预测。
虽然有各种各样的方法来实现它,但在这篇博客中,我将带你经历通过 REST API 部署机器学习模型的步骤。一旦模型可以通过 REST API 进行交互,任何应用程序都可以通过 API 调用传递特征值来寻求模型的预测。
下图显示了我们将要遵循的步骤。步骤 1 已经完成。
步骤 2:序列化模型
运行下面的 Python 代码行来完成步骤 2。
#Serialize the model and save
from sklearn.externals import joblib
joblib.dump(lr, 'randomfs.pkl')
print("Random Forest Model Saved")#Load the model
lr = joblib.load('randomfs.pkl')# Save features from training
rnd_columns = list(X_train.columns)
joblib.dump(rnd_columns, 'rnd_columns.pkl')
print("Random Forest Model Colums Saved")
输出:
Random Forest Model Saved
Random Forest Model Colums Saved
现在,您应该会发现在您的系统上创建了以下两个文件。如果你使用的是 Windows 操作系统,并且没有设置 Python 路径到别的地方,你会在 C:\Users\
到目前为止一切顺利!
确保将步骤 1 和步骤 2 中的 python 代码组合在一个文件中,并存储在与上面相同的目录中。让我们将这个文件命名为 randomfs.py
总之,下面是文件 randomfs.py 的内容
import pandas as pd
import numpy as np
from sklearn.ensemble import RandomForestClassifier# Read data into pandas dataframe
df=pd.read_csv(r'C:\Machinelearning\diabetes.csv')
#Define Feature Matrix (X) and Label Array (y)
X=df.drop(['Outcome'],axis=1)
y=df['Outcome']lr=RandomForestClassifier(n_estimators=53, n_jobs=1,random_state=8)
lr.fit(X,y) #Serialize the model and save
from sklearn.externals import joblib
joblib.dump(lr, 'randomfs.pkl')
print("Random Forest Model Saved")#Load the model
lr = joblib.load('randomfs.pkl')# Save features from training
rnd_columns = list(X_train.columns)
joblib.dump(rnd_columns, 'rnd_columns.pkl')
print("Random Forest Model Colums Saved")
第三步:网络服务
如果你想知道什么是 web 服务,这里有一个来自维基百科的简短解释
web 服务是运行在计算机设备上的服务器,在网络上的特定端口监听请求,提供 Web 文档(HTML、JSON、XML、图像),并创建 Web 应用服务,用于解决 web (www、internet、HTTP)上的特定领域问题。
如果你现在更困惑,我会说,现在不要太担心它。就当是网站运行的服务器吧。网站可以通过这些称为 Web 服务的服务与其他应用程序对话。
好了,现在我们已经完成了这一部分,让我们来了解一下第三步需要做什么。
Python 有一个非常有用的库 Flask,这是一个 web 服务开发框架。如果您使用的是 Anaconda 发行版,Flask 已经为您安装好了。
现在真正的行动开始了。在您选择的记事本中写下代码行,并将其保存为. py 文件。不要使用 Jupyter 笔记本进行此操作。如果你使用 Jupyter 笔记本来做这件事,你可能会得到错误。
#Install Libraries
from flask import Flask, request, jsonify
from sklearn.externals import joblib
import traceback
import pandas as pd
import numpy as npapplication = Flask(__name__)@application.route(‘/prediction’, methods=[‘POST’])#define functiondef predict():
if lr:
try:
json_ = request.json
print(json_)
query = pd.get_dummies(pd.DataFrame(json_))
query = query.reindex(columns=rnd_columns, fill_value=0)predict = list(lr.predict(query))return jsonify({‘prediction’: str(predict)})except:return jsonify({‘trace’: traceback.format_exc()})
else:
print (‘Model not good’)
return (‘Model is not good’)if __name__ == ‘__main__’:
try:
port = int(sys.argv[1])
except:
port = 12345 lr = joblib.load(“randomfs.pkl”)
print (‘Model loaded’)
rnd_columns = joblib.load(“rnd_columns.pkl”) # Load “rnd_columns.pkl”
print (‘Model columns loaded’)app.run(port=port, debug=True)
我将它作为 rndfsapi.py 保存在存储其他三个文件的同一目录中。
现在打开 Anaconda 提示符并运行命令 python rndsfapi.py,这将编译文件并在提到的端口 12345 启动 Web 服务。
我们已经完成了这一步的活动。让我们进入下一步。
步骤 4:测试 REST API
对于这一步,您将需要一个像 Postman 这样的 REST API 测试工具。你可以从下面的链接下载邮差。
[## 邮递员|工具
为您的 API 创建详细的、可通过 web 查看的文档,设置为公共或私有。帮助开发人员使用您的 API…
www.getpostman.com](https://www.getpostman.com/tools)
下载完成后,启动 postman。在发布操作旁边输入显示 URL,然后单击发送按钮。您将看到如下所示的内容。
现在,在 body 部分输入以下特征值。这就是调用应用程序发送需要预测的特征值的方式。
[
{“Pregnancies”:7,”Glucose”:120,”BloodPressure”:90,”SkinThickness”:23,”Insulin”:135,”BMI”:28,”DiabetesPedigreeFunction”:0.5,”Age”:45}
]
在正文中输入这些特征值,然后单击发送按钮。
您可以在突出显示的正文部分查看下面的预测。这个病人没有糖尿病。
恭喜你!
现在您知道如何将机器学习模型部署为 REST API。
参考资料:
[## 机器学习实践课程
加入最全面的机器学习实践课程,因为现在是开始的时候了!从基础…
www.udemy.com](https://www.udemy.com/course/applied-machine-learning-hands-on-course/?referralCode=00F08274D257B06E3201) [## 端到端机器学习
Sanrusha 是基于机器学习和人工智能的解决方案的领先提供商。我们努力通过使用人工智能让生活变得更美好。
www.youtube.com](https://www.youtube.com/c/endtoendmachinelearning)
解释 ML 黑盒模型
原文:https://towardsdatascience.com/machine-learning-model-from-local-explanation-to-global-understanding-fd7fd06d7677?source=collection_archive---------36-----------------------
机器学习模型的可解释性
部分相关图和 SHapley 加法解释
作者图片
https://sarit-maitra.medium.com/membership
T 对现代最大似然法最大的批评是关于它的黑箱性质——输入数据,输出预测/预报,简单来说,这就是最大似然算法的工作方式。复杂性来了——当我们有一个高度非线性的相互作用的模型时,我们怎么可能希望对这个模型正在做什么有一个简单的理解呢?随着机器学习的成熟和广泛采用,建立用户能够理解的模型变得越来越重要。这在医疗保健等高风险应用以及银行&金融等高数据敏感领域非常普遍。
让我们再来回顾一下我们的保险索赔欺诈数据:欺诈索赔概率。我们这里的数据来自汽车保险。是/否之间的答案是一个二元分类任务。因此,此处的报告将使用分类算法来检测欺诈交易。
数据摄取和探索
该数据集有 1000 行和 40 列,有许多独特的变量,如下所示。
*#load & view raw data*
data = pd.read_csv('insurance_claims.csv')
data.shapeOut:(1000, 40)data.columns
不幸的是,在一些应用的最大似然应用中,平衡的数据极其罕见,由于数据代表性不足和严重的类别分布偏斜,需要各种形式的外推。
从上图来看,像大多数欺诈数据集一样,标签分布是偏斜的。近 25%的数据集被报告为欺诈。
数据处理和特征工程:
让我们执行一些基本的转换,然后在训练和测试中将它们分开。在这里,我们并没有过多关注数据分析和建模部分;相反,我们将把重点放在解释部分,这是 ML / AI 工作中最困难的任务。
# feature engineering
data['fraud_reported'].replace(to_replace='Y', value=1, inplace = True)
data['fraud_reported'].replace(to_replace='N', value=0, inplace = True)
data['csl_per_person'] = data.policy_csl.str.split('/', expand=True)[0]
data['csl_per_accident'] = data.policy_csl.str.split('/', expand = True)[1]
data['vehicle_age'] = 2020 - data['auto_year']
# Deriving the age of the vehicle based on the year value
bins = [-1, 3, 6, 9, 12, 17, 20, 24]
# Factorize according to the time period of the day.
names = ["past_midnight", "early_morning", "morning", 'fore-noon', 'afternoon', 'evening', 'night']
data['incident_period_of_day'] = pd.cut(data.incident_hour_of_the_day, bins, labels = names).astype(object)# dropping unimportant columns
data = data.drop(columns = ['policy_number', 'policy_csl', 'insured_zip','policy_bind_date','incident_date','incident_location,'_c39','auto_year','incident_hour_of_the_day'], axis=1)
data.head(2)
这里我们将把分类特征转换成数值。通常最好将这些类型的分类值转换为虚拟值,因为它们在大小上没有关系,但由于它们太多,特征的大小将会增长,这将需要永远训练。然而,为了保持简单,我使用了下面的过程。
# turning object columns type to categorical for easing the transformation process
categorical = data.select_dtypes(include= ['object']).columns
for col in categorical:
data[col] = data[col].astype('category')# categorical values ==> numeric values
data[categorical] = data[categorical].apply(lambda x: x.cat.codes)
data._get_numeric_data().columns
建模:
我们在这个实验中使用了 XGBoostXGBoost 以其在分类任务上的出色性能而闻名,但另一方面,它的输出非常复杂且难以解释。
X = data.drop(columns = ['fraud_reported'], axis=1) # predictor variables
y = pd.DataFrame(data['fraud_reported']) # target variable
X_train, X_test, y_train, y_test = train_test_split(X, y, train_size=0.8, random_state=7)
print('length of X_train and X_test: ', len(X_train), len(X_test))
print('length of y_train and y_test: ', len(y_train), len(y_test))
我们使用额外的维持数据进行训练/测试分割,以防止任何过度拟合。让我们使用 10 重交叉验证快速检查模型的性能。我们将训练一个基本的 XGBoost 分类器,不需要太多的超参数调整。
print("Training XGB Classifier...")
tic = time()
model = XGBClassifier(early_stopping=True)
model.fit(X_train, y_train)
print("done in {:.3f}s".format(time() - tic))
print('Model trained')
AccuracyScore = cross_val_score(model, X_train, y_train, cv=10)
print('Accuracy score:', format(round(AccuracyScore.mean(),2)))
BalancedScore = cross_val_score(model, X_train, y_train, cv=10, scoring="balanced_accuracy")
print('Accuracy balance:', format(round(BalancedScore.mean(),2)))
print("done in {:.3f}s".format(time() - tic))
传统上,最大似然模型的质量是通过交叉验证测试数据的准确性来衡量的。有趣的是,准确度分数给出了 82%的 10 倍平均准确度,而准确度平衡给出了 77%。我们意识到我们的目标变量是不平衡的。
在这种情况下,正确的验证方法非常重要,因为它可能会错误地指出一个好的模型。然而,由于 ML 模型容易受到过于自信的外推的影响,因此具有健壮的验证度量只能部分解决问题。
现在我们已经创建了模型,接下来将解释它到底做了什么。
功能重要性:
知道哪些特性是重要的是有用的。
在这里,我们看到前 3 个特征是被保险人 _ 爱好、保单 _ 年度 _ 保费、事故 _ 严重性。虽然特征重要性可以让我们了解模型发现哪些变量有价值,但它们不会告诉我们这些特征如何影响我们的模型预测。除了知道重要的特征,我们还想知道不同的值是如何影响预测结果的。
模型的可解释性意味着什么?
理解为什么 ML 模型做出某种预测或建议是至关重要的,因为它提供了做出决定的信心,这将导致新的假设和最终新的科学见解。为了可靠的使用,我们需要严格量化 ML 性能的能力。
排列重要性(PI):
PI 是在拟合模型上计算的。我们使用 PI 来计算特性的重要性,方法是测量当一个特性不可用时分数是如何降低的。这是在测试数据上完成的,并通过随机改变一个特性的值,同时保持其他值不变,来打破特性和目标变量之间的依赖关系。它非常直观,并且与模型无关。
perm_train = PermutationImportance(model, scoring='accuracy',
n_iter=100, random_state=1)
# fit and see the permuation importances
perm_train.fit(X_train, y_train)
eli5.explain_weights_df(perm_train, feature_names = X_train.columns.tolist()).head()
# top 5 important features
因此,简单地说,如果改变某个特征会增加模型误差,那么它就是重要的。在这种情况下,模型很大程度上依赖于这个特征来做出正确的预测。我们看到置换已经把事件 _ 严重程度&投保 _ 爱好作为两个最重要的特征,这与 XGBoost 特征重要性不同。
perm_train_df = pd.DataFrame(data=perm.results_, columns=X.columns)
(sns.boxplot(data=perm_train_df).set(title='Permutation Importance Distributions (training data)', ylabel='Importance'));
plt.xticks(rotation=90)
这里我们可以看到,事件 _ 严重程度 & 被保险人 _ 爱好是欺诈 _ 报告的两个最重要的变量
perm = PermutationImportance(model, random_state = 0).fit(X_test, y_test)
eli5.show_weights(perm, feature_names = X_test.columns.tolist())
这里,最重要的特性是 incident_severity 。每行中的第一个数字显示了随机洗牌后模型性能下降的程度(在本例中,使用“准确性”作为性能度量)。我们通过多次洗牌重复这个过程来测量随机性。
在确定了最相关的变量之后,下一步是试图理解近似值对其联合值的依赖性的性质。
缺点:
在这里,我们不确定是使用训练集还是测试集来衡量特性的重要性。此外,由于排列的原因,在重复计算时,处理结果可能变化很大。然而,我认为,我们不能根据训练集上的性能来判断特征的重要性,因为重要性与错误有着内在的联系。最终,这一切都归结为我们是否想知道模型依靠什么特征来进行预测,或者每个特征对看不见的数据的预测能力?
部分相关性图(PDP):
由于基于树的梯度增强模型通常能够捕捉非线性关系,这些图形成了一种有用的方法来识别预测值上升或下降的要素中的热区。
PDP 显示特性对基于预测的模型的结果的影响。它将特征分布上的模型输出边缘化,以提取感兴趣特征的重要性。PDP 可以捕捉目标变量和感兴趣的特征之间的线性、单调和复杂的关系。让我们从连续变量开始分析。
假设:
这种重要性计算基于一个重要的假设,即感兴趣的特征与所有其他特征(除了目标)不相关。这样做的原因是它将显示很可能是不可能的数据点。
相关性:
让我们检查特性之间的相关性,以确保没有问题。
# Checking Correlation of "fraud_reported" with other variables on a different plot
sns.set(style='darkgrid', context='talk', palette='Dark2')
plt.figure(figsize=(15,5))
data.corr()['fraud_reported'].sort_values(ascending = False).plot(kind='bar')
让我们首先从连续变量‘month _ as _ customer’对目标的影响开始。
fig, axes, summary_df = info_plots.target_plot(\
df=data, feature='months_as_customer',
feature_name='months_as_customer', target='fraud_reported',
show_percentile=True)
该图显示,在原始数据中,在 141–178、254–285 和 359–479 个月期间,客户似乎有更高的欺诈索赔概率。
fig, axes, summary_df = info_plots.actual_plot(\
model, X_train, feature='months_as_customer', feature_name = 'MonthsAsCustomer',predict_kwds={})
这个数字证实了前一个的发现。这一发现表明,我们的拟合模型能够捕捉数据模式,并且应该能够很好地概括测试数据。
实际预测图:
实际预测图通过 2 个预测的不同特征值显示实际预测的中间值。
fig, axes, summary_df = info_plots.target_plot_interact(\
df=data, features=['insured_education_level', 'age'],
feature_names=['insured_education_level', 'age'],
target='fraud_reported')
这里,气泡的颜色提供了两个自变量如何影响因变量的深刻见解。颜色越深意味着举报欺诈的可能性越大。
fig, axes, summary_df = info_plots.target_plot_interact(\
df=data,
features=['vehicle_age', 'months_as_customer'],
feature_names=['vehicle_age', 'months_as_customer'],
target='fraud_reported')
现在,我们可以创建一个 PDP 来分析不同特征对欺诈索赔概率的影响。
pdp_limit = pdp.pdp_isolate(\
model, dataset=X_test,model_features=X_test.columns, feature = 'months_as_customer')
fig, axes = pdp.pdp_plot(\
pdp_limit, 'months_as_customer', frac_to_plot=0.2, plot_lines=True, x_quantile=True, show_percentile=True, plot_pts_dist=True)
plt.tight_layout()
黄色和黑色的线给出了预测的平均效果(欺诈案例),具体取决于作为客户的月份。通过查看这条线,我们可以看到,作为客户的月份可能不会对目标变量产生影响。
然而,看下面的图,我们可以清楚地看到事件的严重性
pdp_limit = pdp.pdp_isolate(\
model, dataset=X_test, model_features=X_test.columns, feature='incident_severity')
fig, axes = pdp.pdp_plot(\
pdp_limit, 'incident_severity', frac_to_plot=0.2, plot_lines=True, x_quantile=True, show_percentile=True, plot_pts_dist=True)
在这里,通常我们应该检查两个训练/测试分割,以进行完整的分析。训练数据揭示了模型所获得的洞察,而检查测试集的结果则揭示了这些模式的可概括程度。
沙普利添加剂解释(SHAP):
Shapley 值形成了标准特征重要性机制的更好的替代方案。SHAP 价值观通过在全球和地方层面提供可解释性来增加模型的透明度。总体而言,他们估计每个变量对目标变量的贡献,无论是正面还是负面的。在局部上,它们解释了为什么一个给定的观察值被指定为属于一个类,以及变量的贡献。
汇总图:
柱状图是通过获取每个特征的 SHAP 值的平均绝对值绘制的。
shap_values = shap.TreeExplainer(model).shap_values(X_test)
shap.summary_plot(shap_values, X_test, plot_type="bar")
事故严重程度和被保险人爱好是理赔最重要的两个特征
shap.initjs()
j = 1 # j will be the record we explain
explainerXGB = shap.TreeExplainer(clf)
shap_values_XGB_test = explainerXGB.shap_values(X_test)
shap.force_plot(explainerXGB.expected_value, shap_values_XGB_test[j], X_test.iloc[[j]])
如果我们只是将所有正面的特征重要性堆叠在左边,而将所有负面的特征重要性堆叠在右边,就可以得到最终的模型预测值-2.84,如下所示。由于大多数目标都是 0,所以看到基值为负并不奇怪。将预测值推高的要素显示为红色,将预测值推低的要素显示为蓝色。
我们可以清楚地看到对这个实例的最终输出贡献最大的特性。请注意,这与我们基于上述置换特征进行的分析是一致的。将图上方旋转 90 度,并排堆叠所有可能的值,我们得到图下方。
shap.initjs()
shap.force_plot(explainerXGB.expected_value, shap_values, X_test)
上图显示了所有可能数据点的全局视图及其相对于总体平均值(-2.37)的 SHAP 贡献。该图实际上是交互式的,我们可以滚动每个数据点并检查 SHAP 值。
汇总图:
该图显示了所有要素上 SHAP 值分布的另一个全局汇总。对于每个特性(水平行),我们可以鸟瞰特性的重要性以及驱动它的因素。在下图中,X 轴表示 Shapley 值,其中正值表示较高的默认概率,负值表示较低的默认概率,而 Y 轴具有按要素重要性排序的要素;最后,使用从蓝色(较低的特征值)到红色(较高的特征值)的渐变为这些点着色。因此,如果特征在水平轴上呈现从蓝色到红色的变化,则 Shapley 值增加,然后存在关于欺诈 _ 报告风险的单调增加的关系。
显示了所有要素的 SHAP 值分布的另一个全局汇总。对于每个特性(水平行),您可以看到特性重要性的分布。
对于事件严重性和被保险人爱好,我们可以找到一个外围的红点,它打破了单调性,表示严重事件增加了欺诈索赔的风险。令人惊讶的是,被保险的爱好与欺诈索赔联系在一起。其余特征对模型的预测能力有轻微影响。
关键要点:
模型可解释性,其中线性模型可解释性很容易,但是提供最高准确性的复杂模型很难解释。基于特征重要性的可解释的 ML 方法仍然需要领域知识来理解模型/决策解释,这可能受到人为偏见的影响。然而,我们可以看到,SHAP 值是非常有用的,并有一些明显的优势,如公平分布,对比解释,坚实的理论基础,全球模型解释和快速实施。特别是对于 XGBoost,SHAP 进行了优化,实现起来非常快。
我这里可以连接。
机器学习模型实现:评估模型间的可变重要性
原文:https://towardsdatascience.com/machine-learning-model-implementation-assessing-variable-importance-across-models-30c282d143ec?source=collection_archive---------36-----------------------
实践中的机器/深度学习模型系列的第 1 部分
太好了!因此,您完成了您的机器学习(ML)管道,希望通过仔细的验证程序为每个模型选择您的调整参数,并且已经收敛到您认为每个策略的最终模型。下一步是什么?在本系列的第一部分中,我将讨论 ROC 曲线下区域之外的一些度量和图形,它们有助于实现我们的项目目标。有时候,作为数据科学家,我们对数据和建模的狭隘看法,或者至少是其他人对我们的这种看法,会限制我们作为沟通者和战略家的潜在效力。我将在这些文章中演示的元素将帮助你通过你的合作者的眼睛看到你工作中的问题,并为你提供具体的方法来解决他们的关注和你的 ML 工作的目标。具体来说,在本文中,我们将:
- 讨论为什么探索机器学习中可变重要性的统一框架很重要!
- 显示 R 代码,使用一组 ML 模型的结果生成一个可变重要性图。
可变重要性的重要性
希望你已经明白了在处理预测问题时尝试不同方法的重要性。拟合不同复杂程度的模型(例如线性和非线性)可以确定最简洁的模型,为我们正在处理的数据提供良好的预测性能。然而,应用不同模型带来的好处的另一面可能是比较这些不同策略的结果的明显困难。用于拟合模型的预测因素如何呢——如何评估这些预测因素以确定什么是重要的?作为一名数据科学家,我要求你找到一名主题专家,尽管你可能会提供一个预测相当好的模型,但他对幕后发生的事情没有好奇心!您的最终模型可能对参数系数有直接的解释,例如对于线性模型,但对于更复杂的非线性策略,情况并非总是如此。幸运的是,尽管模型有不同的参数化和优化策略,但相对变量重要性是一个统一的概念,可以允许对模型之间的特性进行比较。关于如何计算不同模型的重要性的更多细节可以在 Max Kuhn 和 Kjell Johnson 的应用预测建模(http://appliedpredictivemodeling.com)中找到,并且可以在 r
基本上,这种统一是这样实现的:尽管变量的重要性对于每个模型来说是不同的,但对于每个策略来说,最重要的变量被赋予了 100 分,就像“100%”,因此将这些重要性分数描述为相对分数是最准确的。然后,下一个重要变量被赋予一个 0 到 100 之间的相对值,其接近 100 表示其重要性与第一个变量的接近程度。这在整个预测器中进行,除了在相对少量的模型的情况下,这些模型通过模型拟合程序执行它们自己的变量选择。对于这些模型,对于模型中不包括的任何特征,变量重要性为零。
关于相对变量重要性,需要注意的一个重要警告是,它最好被认为是绝对值的指标,而不是效果的符号或方向。重要预测值可能与结果正相关或负相关。
数据
在本文中,我将使用 7 ML 模型的结果来分析 R caret 包中可用的德国信用分类数据。它由 1000 个被确定为信用良好(n=700)或信用不良(n=300)的个人的观察结果组成。有 61 个预测因子,涵盖了可能与信贷有关的各种因素,如贷款特征、银行信息、人口统计、就业等。数据被分成 70% — 30%的训练测试部分,保留了两者中 70%的良好信用频率。注意,计算变量重要性仅涉及来自训练集的数据,该训练集被分成 5 个 CV 集,重复 5 次,以确定最佳调整参数。建模是使用 r 中的 caret 包完成的。
*线性判别分析(LDA)
*偏最小二乘(PLS)
*支持向量机(SVM,带径向核函数)
*神经网络(NN)
*递归分割(Rpart,单树)
*随机森林(RF)
*梯度推进机(GBM)
在本系列的下一篇文章中,我将更多地讨论这些模型的表现。为了我们的目的,现在模型显示了交叉验证性能中的合理信号,因此有理由查看相对变量重要性。
在 R 中,可以使用 varImp()函数从 caret 模型对象中提取可变的重要性度量。不过,在这里,我们将从一个. csv 文件的代码中选取一些内容,该文件包含每个模型的前 10 个重要变量,以及它们的重要性值,因此,如果您从其他来源有这样的文件,可以在 R 中加入这些代码。
require(tidyverse)
require(ggplot2)
require(ggrepel)varImp_all <- read_csv('varImp.csv')
varImp_all## # A tibble: 70 x 3
## model imp_vars Importance
## <chr> <chr> <dbl>
## 1 lda CheckingAccountStatus.lt.0 100
## 2 lda CheckingAccountStatus.none 87.8
## 3 lda InstallmentRatePercentage 54.3
## 4 lda Duration 49.9
## 5 lda CreditHistory.Critical 47.4
## 6 lda Telephone 42.2
## 7 lda SavingsAccountBonds.lt.100 38.7
## 8 lda OtherInstallmentPlans.None 38.3
## 9 lda Age 36.5
## 10 lda Housing.Own 34.8
## # … with 60 more rows
在接下来的步骤中,对数据进行处理,以获得图中捕捉的 3 个维度:
- 该功能出现在前 10 位的型号数量
- 该功能在模型中的平均排名
- 跨模型的特征的平均相对重要性值
# Variable importance figure
# create rankings for important variables in each model
varImp_all$rank <- sequence(rle(as.character(varImp_all$model))$lengths)
# compute average importance and ranking for all variables
varImpSummary <- aggregate(varImp_all[,3:4], list(varImp_all$imp_vars), mean)
colnames(varImpSummary) <- c('var','avg_imp','avg_rank')
varImpSummary <- varImpSummary %>%
mutate(avg_imp = round(avg_imp,2),
avg_rank = round(avg_rank,2))# count frequency of important variable across models
varImpTable <- data.frame(table(varImp_all$imp_vars))
varImpOrder <- varImpTable[order(varImpTable$Freq, decreasing = T),]
colnames(varImpOrder) <- c("var", "num_models")varImp_dat <- merge(varImpSummary,varImpOrder)
varImp_dat <- varImp_dat[order(varImp_dat$avg_imp, decreasing = TRUE),]
下面是 ggplot2 代码。可能最棘手的部分是在一个图例中同时获得尺寸和颜色。此外,我们将反转 y 轴的正常方向,这样一来,排名 1 将位于顶部。这将在图表的右上角创建一个最佳位置,在这里多个模型中排名最高的特性将聚集在一起。同样,左下角将代表最不重要的变量。
p <- ggplot(varImp_dat, aes(x = num_models, y = avg_rank)) +
geom_point(aes(color = avg_imp, size = avg_imp)) +
scale_size_continuous(range = c(1,30)) +
scale_color_gradient(low = "yellow", high = "hotpink", na.value = NA, guide = 'legend') +
guides(color=guide_legend(reverse = TRUE), size = guide_legend(reverse = TRUE)) +
scale_y_continuous(trans = "reverse") +
labs(title = "Variable Importance Across Models",
x = "Number of Models Where Variable Appeared in Top 10",
y = "Average Ranking", color = "Average\nImportance", size = "Average\nImportance")
这部分绘图代码标记了预测值。ggrepel 包中的 geom _ label _ repel()函数有助于战略性地放置标注(即不要一个放在另一个上面)。
p <- p + geom_label_repel(aes(label = var),
box.padding = 0.35,
point.padding = 0.5,
segment.size = 0.5,
size = 6,
segment.color = 'grey50')
最后是一些主题调整:
p <- p +
theme(plot.title = element_text(color="black",face="bold",size=18,hjust=0),
axis.title = element_text(color="black",face="bold",size=12),
legend.title = element_text(color="black",face="bold",size=12),
legend.position = "right",
axis.text=element_text(size=12))
最后,我们直观地总结了本分析中模型所指示的重要变量。可能不足为奇的是,拥有一个余额小于零的支票账户,或者根本没有支票账户是多种模型中的重要因素。此外,贷款本身的特征,包括分期付款率和期限,似乎在所有模型中都很重要。在发现它的模型中,出现频率较低但很重要的是贷款的数量。只有一个模型(碰巧是神经网络)将贷款的目的选择为提供家具和设备,但它显示了相对较高的重要性值。也许神经网络正在获取像餐馆这样有较高失败倾向的商业贷款。这些类型的见解有可能简化数据收集,并提出改进贷款审批流程以减少违约的方法。
总之,如果您建模的目的是确定改进流程性能的方法,而不仅仅是监控和预测,那么对结果的驱动因素有一些了解将是非常有价值的。能够显示相对变量重要性可能会激起对模型效用的兴趣,并允许更具战略性的实现。
机器学习模型实现:精度/召回率和概率截止值
原文:https://towardsdatascience.com/machine-learning-model-implementation-precision-recall-and-probability-cut-offs-49429ed644c5?source=collection_archive---------36-----------------------
实践中的机器/深度学习模型系列的第 2 部分
祝贺您完成机器学习(ML)管道!在本系列的第二部分中,我将讨论 ROC 曲线下区域之外的一些度量标准和图形,这些度量标准和图形有助于选择我们希望向前发展并在实践中实现的模型,同时牢记我们项目的目标。具体来说,在本文中,我们将:
1.讨论为什么精确度/召回率的权衡可能是许多问题的最佳框架,以及
2。展示图形和摘要,这些图形和摘要可以将预测性建模练习转化为对实践中的决策非常有影响的东西。
什么是精准和召回(我以前见过吗)?
如果你一直在处理分类问题,你可能以前见过回忆,因为它也被称为敏感性。回顾一下,假设我们有兴趣预测一个 2 级事件,赢或输。那么回忆=灵敏度=一个真实的胜利被预测为胜利的概率;本质上,它是我们在预测的成功案例中成功捕获的真实成功案例的比例。接下来,Precision 也称为正预测值(PPV ),我觉得它更具描述性。对于 PPV,我们把事情颠倒过来,说:好吧,在我预测的胜利中,哪些是真正的胜利。当然,这两者都很重要:我们希望在我们的预测成功桶中捕获所有真正的成功,并且所有预测的成功都变成真正的成功。但是正如你所预料的,这两者之间会有一些冲突,它们之间的权衡体现在精确召回(PR)曲线中。我们可以计算这条曲线下的面积(AUC ),就像我们计算 ROC 曲线的 AUC 一样。ROC 曲线有一条从 0 到 1 的参考斜线,表示模型性能相当于掷硬币,而 AUC PR 曲线的参考线是一条水平线,表示真正获胜的频率。
既然我们已经了解了精确召回的权衡,为什么它会如此重要呢?在许多分类问题中,有一个事件比另一个结果更令人感兴趣,或者与更大的成本或回报相关联。因此,虽然 AUC ROC 曲线很重要,但 AUC PR 曲线可能与许多预测问题的模型性能和选择更密切相关。此时你可能会说,“你一直在谈论交易,但我该如何进行这些交易呢?”正是通过改变概率截止水平,我们需要称之为“赢”该级别设置得越低,敏感度/召回率就越高(“我们已经正确地将大多数真正的成功捕获为预测的成功”),但可能会有许多误报。截止值越高,精确度/PPV 越高(“大多数预测的成功实际上是真实的成功”),但是大量真实的成功不会被归类为真实的成功(假阴性)。好了,在这个讨论变得太抽象之前,让我们继续一个例子。
数据
在本文中,我将使用 7 个机器学习(ML)模型的结果,这些模型分析了 R caret 包中可用的德国信用分类数据。它由 1000 个被确定为信用良好(n=700)或信用不良(n=300)的个人的观察结果组成。有 61 个预测因子,涵盖了可能与信贷有关的各种因素,如贷款特征、银行信息、人口统计、就业等。数据被分成 70%-30%的训练-测试部分,保留了两者中 70%的良好信用频率。将训练集分成 5 个 CV 集,重复 5 次,以确定最佳调谐参数。建模是使用 r 中的 caret 包完成的。
*线性判别分析(LDA)
*偏最小二乘(PLS)
*支持向量机(SVM,带径向核函数)
*神经网络(NN)
*递归分割(Rpart,单树)
*随机森林(RF)
*梯度推进机(GBM)
以下是应用于保留测试集的七个 ML 学习拟合的 AUC ROC 和 AUC PR 曲线(即不涉及模型交叉验证)。除了单个树 Rpart 模型之外,测试集中的模型性能在 fits 之间是相似的。看一下实际的精确-回忆曲线,权衡变得明显:当我们的回忆或敏感度较低时,我们不能正确预测许多良好的信用主体,但我们归类为良好的信用主体实际上大多是良好的。这相当于使用高值作为“好”的概率截止值。随着我们降低截止概率,敏感度/召回率提高,但以精确度/PPV 为代价(许多预测的良好信用主体实际上具有不良信用)。
德国信贷问题中的数据是一个不平衡的分类惩罚结构的例子。在这种情况下,更糟糕的是,当一个主体的信用实际上很差时,将其归类为信用良好。这可能导致有人收到贷款或信用卡,他们很可能会拖欠。另一方面,向那些有能力履行信贷条件的人发放贷款和发放信贷是有利可图的,但成功的贷款所带来的损失不如不成功的贷款所带来的损失多。
另一个直观的方法是,通过它们的基本事实来检查我们的测试数据的预测概率的分布。下面是一个例子:Rpart 模型已被删除,以改善数字缩放,垂直的绿线代表一个潜在的临界值,可用于确定模型预测的阳性(此处为 0.7)。这种类型的图形允许以易于理解的方式显示真阳性和假阳性区域。从图中可以清楚地看出,这些模型将需要不同的概率截止值来实现相同的性能。例如,PLS 模型需要较低的临界值,以实现与其他模型相似的灵敏度和 PPV。该图的另一个启示是,除了最高的截止值之外,所有的截止值都会保留一些假阳性,并且对于一些模型来说,它们可能无法完全消除。
在我们有了大图之后,我们可以更深入地研究细节,检查模型以找到满足我们目标的最佳点。例如,如果 76%的 PPV 值是可容忍的(即 24%的假阳性),RF 模型表明这可以使用 0.5 的截止值在 93%的灵敏度下实现。(请注意,这些值应被视为取自一个测试样本的估计值。另一种方法是为每个 CV 维持样本计算这些值,并检查它们的分布。然而,这个假阳性率可能太高了,如果我们不太担心错过真正的阳性,我们可能更喜欢光谱的另一端。截止值为 0.7 的 PLS 模型将仅捕获 22%的真阳性,但是 95%被分类为阳性的真阳性。我们的风险函数的性质以及与我们的模型实现相关联的实际约束可以引导我们做出最佳选择。在信贷示例中,可以假设好的和坏的信贷的美元(或欧元)预期收益和损失,并为每个截止选项进行计算。
总之,战略性地考虑精确召回、预测的概率分布和不同截止点的模型性能分析,以及我们开发的模型将如何在实践中使用,将导致机器学习管道,这些管道有真正的机会影响更大的商业目标和目的。
实践中的机器学习模型正则化:以 Keras 和 TensorFlow 2.0 为例
原文:https://towardsdatascience.com/machine-learning-model-regularization-in-practice-an-example-with-keras-and-tensorflow-2-0-52a96746123e?source=collection_archive---------15-----------------------
一步一步的教程,使用 L2 正则化和辍学,以减少过度拟合的神经网络模型。
摇滚猴子在 Unsplash 上的照片
在本文中,我们将重点关注将正则化纳入我们的机器学习模型,并查看一个示例,说明我们如何在 Keras 和 TensorFlow 2.0 的实践中做到这一点。
正规化的简明介绍
事实证明,许多人害怕数学,尤其是初学者和将职业道路转向数据科学的人。
让我们避开数学,试着用更温和的方式解释正则化。如果你正在寻找正规化的完整解释(带有大量数学表达式),你可能会发现以下文章很有用:
- 机器学习中的正则化
- 正则化:机器学习中的一个重要概念
正则化是一种对抗机器学习中 过拟合 问题的技术。 过拟合 ,也称为 高方差, 指的是对训练数据学习得太好,但未能推广到新数据的模型。例如,下面的绿线是过度拟合的模型,黑线代表正则化的模型。
绿线代表过度拟合的模型,黑线代表正则化的模型。来源于维基百科
过拟合 可以通过标图训练和验证损失来诊断。例如,在下图中,训练错误显示为蓝色,验证错误显示为红色,两者都是训练时期数的函数。如果验证误差增加,而训练误差稳定减少,则可能出现过拟合的情况。
过度拟合可以通过绘制训练和验证损失来诊断。来源于维基百科
一旦诊断出过度拟合,就应该尝试不同的正则化技术和参数,看看它们是否有帮助。最广泛使用的正则化技术有:
- L1 正则化 给损失函数增加了绝对值作为惩罚项。有人说 L1 可以帮助压缩模型。但在实践中,L1 正则化使你的模型稀疏,只有一点点帮助。L2 正则化只是用得更多。
- L2 正则化 (也称为权重衰减)将平方量级作为惩罚项添加到损失函数中,它比 L1 使用得更频繁。
- Dropout 是深度学习中广泛使用的正则化技术。它在每次迭代中随机关闭一些神经元。
- 数据增加 增加额外的假训练数据。更多的训练也有助于减少过度配合。
- 提前停止 是深度学习中另一种广泛使用的正则化技术。当泛化误差增加时,它停止训练。
在下面的文章中,我们将结合 L2 正则化和辍学,以减少神经网络模型的过度拟合。
环境设置、源代码和数据集准备
为了运行本教程,您需要安装
TensorFlow 2,numpy,pandas,sklean,matplotlib
它们都可以直接安装在 vis PyPI 上,我强烈建议创建一个新的虚拟环境。关于创建 Python 虚拟环境的教程
- 使用“virtualenv”创建虚拟环境,并将其添加到 Jupyter 笔记本中
- 使用“conda”创建虚拟环境,并将其添加到 Jupyter 笔记本中
源代码
这是一个循序渐进的教程,所有的说明都在这篇文章中。源代码请查看我的 Github 机器学习报告。
数据集准备
本教程使用安德森鸢尾花(iris) 数据集进行演示。该数据集包含五个属性下的一组 150 条记录:萼片长度、萼片宽度、花瓣长度、花瓣宽度、和类别(从 sklearn 数据集称为目标)。
首先,让我们导入库并从 scikit-learn 库中获取虹膜数据集。你也可以从 UCI 虹膜数据集下载。
import tensorflow as tf
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split**iris = load_iris()**
为了研究数据,让我们将数据加载到一个数据帧中
# Load data into a DataFrame
**df = pd.DataFrame(iris.data, columns=iris.feature_names)** # Convert datatype to float
**df = df.astype(float)** # append "target" and name it "label"
**df['label'] = iris.target** # Use string label instead
**df['label'] = df.label.replace(dict(enumerate(iris.target_names)))**
并且df
应该如下所示:
我们注意到 标签 列是一个分类特征,需要将它转换成一次性编码。否则,我们的机器学习算法将无法直接将其作为输入。
# label -> one-hot encoding
**label = pd.get_dummies(df['label'], prefix='label')**
**df = pd.concat([df, label], axis=1)**
# drop old label
df.drop(['label'], axis=1, inplace=True)
现在,df
应该是这样的:
接下来,让我们创建X
和y
。Keras 和 TensorFlow 2.0 只接受 Numpy 数组作为输入,所以我们必须将 DataFrame 转换回 Numpy 数组。
# Creating X and y**X = df[['sepal length (cm)', 'sepal width (cm)', 'petal length (cm)', 'petal width (cm)']]**
# Convert DataFrame into np array
**X = np.asarray(X)****y = df[['label_setosa', 'label_versicolor', 'label_virginica']]** # Convert DataFrame into np array
**y = np.asarray(y)**
最后,让我们使用来自 sklearn 库中的**train_test_split()**
将数据集拆分成训练集(80%)和测试集(20%)。
X_train, X_test, y_train, y_test = **train_test_split**(
**X,
y,
test_size=0.20**
)
太好了!我们的数据已经准备好建立一个机器学习模型。
1.建立非正则化神经网络模型
在应用正则化之前,让我们建立一个没有正则化的神经网络,看看过拟合问题。
用 Keras 和 Tensorflow 2 创建机器学习模型有 3 种方法。由于我们正在构建一个简单的全连接神经网络,为了简单起见,让我们使用最简单的方法:带有Sequential()
的顺序模型。
让我们继续创建一个名为create_model()
的函数来返回一个序列模型。
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Densedef **create_model()**:
model = Sequential([
Dense(64, activation='relu', **input_shape=(4,)**),
Dense(128, activation='relu'),
Dense(128, activation='relu'),
Dense(128, activation='relu'),
Dense(64, activation='relu'),
Dense(64, activation='relu'),
Dense(64, activation='relu'),
**Dense(3, activation='softmax')**
])
return model
注意到
- 第一层(也称为输入层)有
input_shape
来设置输入大小(4,)
- 输入层有 64 个单元,接着是 3 个密集层,每个层有 128 个单元。然后还有 3 个密集层,每个层有 64 个单元。所有这些层都使用 ReLU 激活功能。
- 输出密集层有 3 个单元和 softmax 激活功能。
通过跑步
model = create_model()
model.summary()
应该打印出模型摘要。
1.1 培训模型
为了训练一个模型,我们首先必须使用compile()
配置我们的模型,并传递以下参数:
- 使用 Adam (
adam
)优化算法作为优化器 - 对于我们的 多类分类 问题,使用分类交叉熵损失函数(
categorical_crossentropy
- 为简单起见,使用
accuracy
作为我们在训练和测试期间评估模型的评估指标。
model.compile(
**optimizer='adam',
loss='categorical_crossentropy',
metrics=['accuracy']**
)
之后,我们可以调用model.fit()
来使我们的模型适合训练数据。
history = model.fit(
X_train,
y_train,
**epochs=200,
validation_split=0.25,
batch_size=40,**
verbose=2
)
如果一切顺利,我们应该得到如下输出
Train on 90 samples, validate on 30 samples
Epoch 1/200
90/90 - 1s - loss: 1.0939 - accuracy: 0.4333 - val_loss: 1.0675 - val_accuracy: 0.5333
Epoch 2/200
90/90 - 0s - loss: 1.0553 - accuracy: 0.6556 - val_loss: 1.0160 - val_accuracy: 0.7000
......
......
Epoch 200/200
90/90 - 0s - loss: 0.0624 - accuracy: 0.9778 - val_loss: 0.1874 - val_accuracy: 0.9333
1.2 模型评估
一旦训练完成,就该看看模型是否适合模型评估了。模型评估通常包括
- 绘制损失和准确性指标的进度
- 用从未用于训练的数据来测试我们的模型。这就是我们之前搁置的测试数据集
X_test
发挥作用的地方。
让我们创建一个函数plot_metric()
来绘制度量标准。
%matplotlib inline
%config InlineBackend.figure_format = 'svg'def **plot_metric(history, metric)**:
train_metrics = history.history[metric]
val_metrics = history.history['val_'+metric]
epochs = range(1, len(train_metrics) + 1)
plt.plot(epochs, train_metrics)
plt.plot(epochs, val_metrics)
plt.title('Training and validation '+ metric)
plt.xlabel("Epochs")
plt.ylabel(metric)
plt.legend(["train_"+metric, 'val_'+metric])
plt.show()
通过运行plot_metric(history, 'accuracy')
绘制精度进度。
通过运行plot_metric(history, 'loss')
绘制损失进度。
从上面的图表中,我们可以看到,模型过度拟合了训练数据,因此它的表现优于验证集。
在测试集上评估模型
# Evaluate the model on the test set
model.**evaluate**(**X_test**, **y_test**, verbose=2)
我们应该得到如下所示的输出
30/1 - 0s - loss: 0.0137 - accuracy: 1.0000
[0.01365612167865038, 1.0]
2.添加 L2 正规化和辍学
首先,让我们从 TensorFlow Keras 包中导入L2转正
*from tensorflow.keras.**layers** import **Dropout**
from tensorflow.keras.**regularizers** import **l2***
然后,我们创建一个名为create_regularized_model()
的函数,它将返回一个类似于我们之前构建的模型。但是,这次我们将添加 L2 正则化 和 辍学 层,所以这个函数需要 2 个参数:一个 L2 正则化factor
和一个辍学rate
。
- 让我们添加 L2 正则化 在所有层除了输出层[1]。
- 让我们在每两个密集层之间添加层。**
**def **create_regularized_model**(**factor**, **rate**):
model = Sequential([
Dense(64, **kernel_regularizer=l2(factor)**, activation="relu", input_shape=(4,)),
**Dropout(rate),**
Dense(128, **kernel_regularizer=l2(factor)**, activation="relu"),
**Dropout(rate),**
Dense(128, **kernel_regularizer=l2(factor)**, activation="relu"),
**Dropout(rate),**
Dense(128, **kernel_regularizer=l2(factor)**, activation="relu"),
**Dropout(rate),**
Dense(64, **kernel_regularizer=l2(factor),** activation="relu"),
**Dropout(rate),**
Dense(64, **kernel_regularizer=l2(factor),** activation="relu"),
**Dropout(rate),**
Dense(64, **kernel_regularizer=l2(factor),** activation="relu"),
**Dropout(rate),**
Dense(3, activation='softmax')
])
return model**
让我们使用参数 L2 因子 0.0001 和辍学率 0.3 来创建模型
**model = create_regularized_model(1e-5, 0.3)
model.summary()**
2.1 培训
正则化模型可以像我们构建的第一个模型一样被训练。
**# First configure model using model.compile()
model.compile(
**optimizer='adam',
loss='categorical_crossentropy',
metrics=['accuracy']**
)# Then, train the model with fit()
history = model.fit(
X_train,
y_train,
**epochs=200,
validation_split=0.25,
batch_size=40,**
verbose=2
)**
如果一切顺利,我们应该得到如下输出
**Train on 90 samples, validate on 30 samples
Epoch 1/200
90/90 - 2s - loss: 1.0855 - accuracy: 0.3333 - val_loss: 1.0873 - val_accuracy: 0.3000
Epoch 2/200
90/90 - 0s - loss: 1.0499 - accuracy: 0.3778 - val_loss: 1.0773 - val_accuracy: 0.3000
......
......
Epoch 200/200
90/90 - 0s - loss: 0.1073 - accuracy: 0.9556 - val_loss: 0.1766 - val_accuracy: 0.9000**
2.2 模型评估
现在,让我们画出损失的进度
**plot_metric(history, 'loss')**
从图中我们可以看出,过度拟合并没有完全解决,但是与非正则化模型相比,有了显著的改善。
最后,在测试集上评估模型
**model.evaluate(X_test, y_test, verbose=2)**
应该会输出类似于
**30/1 - 0s - loss: 0.0602 - accuracy: 0.9667
[0.06016349419951439, 0.96666664]**
好了
感谢阅读。
请在我的 Github 上的笔记本中查看源代码。
如果你对机器学习的实用方面感兴趣,请继续关注。
参考资料:
- [1] Keras 层权重正则化子
机器学习:模型选择和超参数调整
原文:https://towardsdatascience.com/machine-learning-model-selection-and-hyperparameter-tuning-736158357dc4?source=collection_archive---------30-----------------------
网格搜索是发现更好的超参数的一种简单明了的方法
图片由 andreas160578 来自 Pixabay
在我的日常研究中,我经常面临的一个问题是选择一个合适的统计模型来拟合我的数据。大多数情况下,我会使用统计模型来消除 DNA 数据中的错误信号,我相信选择一个模型来解释数据的行为是数据科学爱好者的共同关注。我认为分享如何使用现成的库来解决这种情况是有用的。此外,选择一个模型是不够的,除非你知道最合适的超参数进展。让我们看一个简单的场景来理解它是如何实现的。
预测要求
预测要求可以有几种。主要我们可以看到两种插值和外推。在插值中,我们尝试预测缺失变量值的标签值。简而言之,我们知道周围的数据点,并尝试预测同一功能域内的不同数据点。相反,外推旨在预测稍微偏离现有数据点的值。例如,根据前两天和今天的降雨量,预测明天的降雨量。
一个示例场景
模拟这种场景的最简单的方法是使用一个已知的函数并检查它的行为。让我们以y = 5000*sin(x)
为例。如果我们看看生成的代码和图,它看起来像下面这样。
import numpy as np
import matplotlib.pyplot as pltx = np.arange(0,6,0.005)
y = np.sin(x)*5000fig = plt.figure(figsize=(10,5))
plt.plot(x, y, label="y=sin(x)")
plt.xlabel("X")
plt.ylabel("sin(X)")
plt.legend(loc="upper left")
y =正弦(x)曲线
可能的回归变量
现在,我们已经看到了图表或趋势,让我们假设我们只有数据点,我们需要开发一个回归变量,可以满足x=8
。
随机森林回归
随机森林是一种流行的回归技术。然而,随机森林对于过度适应的问题(对于训练集来说过于专门化)是相当流行的。下面是使用随机森林回归的代码和预测。
from sklearn.ensemble import RandomForestRegressor
from sklearn.model_selection import train_test_splitx_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.33, random_state=10)forest_reg = RandomForestRegressor(n_estimators=1, random_state=10)
forest_reg.fit(x_train.reshape(-1, 1), y)
y_hat = forest_reg.predict(x_test.reshape(-1, 1))fig = plt.figure(figsize=(10,5))
plt.scatter(x_test, y_test, label="Truth")
plt.scatter(x_test, y_hat, label="Prediction")
plt.xlabel("X")
plt.ylabel("Y")
plt.legend(loc="upper left")
对一组值的预测
我们可以清楚地看到,模型非常接近预测值。这是好事。请注意,我们将训练集和测试集分开,以确保没有明显的过度拟合。然而,如果我们看看未来的预测,我们可以看到一些有趣的事情。
x_next = np.arange(0,7,0.005)
y_next = np.sin(x_next)*5000y_next_hat = forest_reg.predict(x_next.reshape(-1, 1))
fig = plt.figure(figsize=(10,5))
plt.plot(x_next, y_next, label="y=sin(x)", alpha=0.5)
plt.plot(x_next, y_next_hat, label="Predicted", alpha=0.5)
plt.xlabel("X")
plt.ylabel("Y")
plt.legend(loc="upper left")
未来预测
哎呀!。我们可以看到,超出训练极限的数值是没有意义的。这是因为随机森林学会了只在训练范围内预测,或者只是插值。这就是多项式回归派上用场的地方。
多项式回归
多项式回归试图用多项式函数来表达数据。然而,多项式拟合的次数是一个无法学习的超参数。让我们来看看数据的多项式拟合。
from sklearn.linear_model import Ridge
from sklearn.preprocessing import PolynomialFeatures
from sklearn.pipeline import make_pipelinemodel = make_pipeline(PolynomialFeatures(3), Ridge())
model.fit(x_train.reshape(-1, 1), y_train)
y_next_hat = model.predict(x_next.reshape(-1, 1))x_next = np.arange(0,7,0.005)
y_next = np.sin(x_next)*5000fig = plt.figure(figsize=(10,5))
plt.plot(x_next, y_next, label="y=sin(x)")
plt.plot(x_next, y_next_hat, label="Predicted")
plt.xlabel("X")
plt.ylabel("Y")
plt.legend(loc="upper left")
plt.savefig("poly_fit.png")
三次多项式拟合
我们可以看到,虽然我对多项式次数为 3 的猜测不是很合理。然而,我可以继续输入值并进行测试。但是 sklearn 有一个更聪明的方法。
超参数调谐的网格搜索
Sklearn 库为我们提供了定义参数网格和选择最佳参数的功能。让我们看看如何用它来决定我们预测的适当程度。
from sklearn.model_selection import GridSearchCV
from sklearn.pipeline import Pipelineparam_grid = [
{'poly__degree': [2, 3, 4, 5, 6, 7, 8, 9]}
]pipeline = Pipeline(steps=[('poly', PolynomialFeatures()), ('ridge', Ridge())])grid_search = GridSearchCV(pipeline, param_grid, cv=5,
scoring='neg_mean_squared_error',
return_train_score=True)grid_search.fit(x_train.reshape(-1, 1), y_train)
这里我们选择 2 到 8 度进行实验。这种网格搜索可以用于任何其他模型,您可以拥有尽可能多的参数。在这种情况下,我们试图找到使neg_mean_squared_error
最小的一组参数,或者选择具有最小均方误差的点。然而,对于更大的参数空间,推荐使用随机化搜索。
>> grid_search.best_params_
{'poly__degree': 5}
best_params_
将输出最佳参数集作为 python 字典。就这么简单。
y_next_hat = grid_search.predict(x_next.reshape(-1, 1))x_next = np.arange(0,7,0.005)
y_next = np.sin(x_next)*5000fig = plt.figure(figsize=(10,5))
plt.plot(x_next, y_next, label="y=sin(x)")
plt.plot(x_next, y_next_hat, label="Predicted")
plt.xlabel("X")
plt.ylabel("Y")
plt.legend(loc="upper left")
现在,如果我们使用grid_search
进行预测,我们可以看到我们对潜在的未来 X 值有一个更好的估计。
五次多项式拟合
我们可以看到,预测的多项式仅在远离训练集的较小范围内成立。这是因为我们的函数sin(x)
是一个周期函数,除非我们提供所有可能的实数值,否则不存在完美的多项式拟合。
我希望这篇文章能够帮助您使用 python 内置的网格搜索功能进行超参数调优。这也可以用于更复杂的场景,例如具有预定义集群大小的集群、用于优化的可变ε值等。
如果您正在寻找一个支持参数调整的 ML 工具,请查看下面的链接;
[## Optuna vs Hyperopt:应该选择哪个超参数优化库?- neptune.ai
思考应该选择哪个库进行超参数优化?使用远视有一段时间了,感觉像…
海王星. ai](https://neptune.ai/blog/optuna-vs-hyperopt)
你好。
向一个五岁的孩子解释机器学习模型
原文:https://towardsdatascience.com/machine-learning-models-explained-to-a-five-year-old-f2f540d9dcea?source=collection_archive---------8-----------------------
尽可能简单地解释 ML 模型是如何工作的
如果你是数据科学的新手,这个标题并没有侮辱你的意思。这是我的第二篇帖子,主题是一个流行的面试问题,大概是这样的:“像一个五岁的孩子一样给我解释一下[插入技术话题]。”
事实证明,达到五岁儿童的理解水平是相当困难的。因此,虽然这篇文章对幼儿园的孩子来说可能不是非常清楚,但对那些几乎没有数据科学背景的人来说应该是清楚的(如果到最后还不清楚,请在评论中告诉我)。
我将首先解释什么是机器学习,以及不同类型的机器学习,然后我将解释常见的模型。我不会深入研究任何数学问题,但是我正在考虑在以后的另一篇文章中这样做。尽情享受吧!
机器学习的定义
机器学习的图解
机器学习是指你将大量数据加载到计算机程序中,并选择一个模型来“拟合”这些数据,这使得计算机(在没有你的帮助下)能够做出预测。计算机制作模型的方式是通过算法、算法,这些算法可以从简单的方程(如直线方程)到非常复杂的逻辑/数学系统,让计算机做出最佳预测。
机器学习的名字很恰当,因为一旦你选择了要使用的模型并对其进行调整(也就是通过调整来改进),机器就会使用该模型来学习你的数据中的模式。然后,你可以输入新的条件(观察),它会预测结果!
监督机器学习的定义
监督学习是一种机器学习,其中你放入模型的数据被“标记”标记仅仅意味着观察的结果(也称为数据行)是已知的。例如,如果您的模型试图预测您的朋友是否会去打高尔夫球,您可能会有一些变量,如温度、星期几等。如果你的数据有标签,如果你的朋友真的去打高尔夫了,你也有一个值为 1 的变量,如果他们没有去打高尔夫,变量的值为 0。
无监督机器学习的定义
正如你可能已经猜到的,当涉及到标记数据时,无监督学习与监督学习相反。在无监督学习的情况下,你不知道你的朋友是否去打高尔夫了——这是由计算机通过模型找到模式,猜测发生了什么或预测将会发生什么。
监督机器学习模型
【需要成人监督】
逻辑回归
当你有一个分类问题时,使用逻辑回归。这意味着你的目标变量(也就是你想预测的变量)是由类别组成的。这些类别可以是“是/否”,或者类似于代表客户满意度的 1 到 10 之间的数字。
逻辑回归模型使用一个等式来创建数据曲线,然后使用该曲线来预测新观察的结果。
逻辑回归图解
在上图中,新观测值的预测值为 0,因为它位于曲线的左侧。如果您查看此曲线所基于的数据,这是有意义的,因为在图表的“预测值为 0”区域,大多数数据点的 y 值为 0。
线性回归
线性回归通常是人们学习的第一批机器学习模型之一。这是因为当只使用一个 x 变量时,它的算法(即幕后的方程)相对容易理解——它只是在制作一条最佳拟合线,这是小学教授的概念。然后,该最佳拟合线用于预测新的数据点(见图)。
线性回归图解
线性回归类似于逻辑回归,但是当你的目标变量是连续的时使用,这意味着它基本上可以取任何数值。事实上,任何具有连续目标变量的模型都可以归类为“回归”连续变量的一个例子是房子的销售价格。
线性回归也很好解释。模型方程包含每个变量的系数,这些系数表示自变量(x 变量)的每个微小变化对目标变量的影响。以房价为例,这意味着您可以查看您的回归方程,并说“哦,这告诉我,房子大小(x 变量)每增加 1 英尺,销售价格(目标变量)就会增加 25 美元。”
k 最近邻(KNN)
该模型可用于分类或回归!名称“K 个最近邻居”不是为了混淆。模型首先绘制出所有的数据。标题中的“K”部分是指模型为确定预测值而查看的最近相邻数据点的数量(请参见下图)。作为未来的数据科学家,你可以选择 K,你可以摆弄这些值,看看哪一个给出了最好的预测。
K 个最近邻的图示
K=__ 圆中的所有数据点都获得了关于这个新数据点的目标变量值应该是什么的“投票”。获得最多投票的值就是 KNN 为新数据点预测的值。在上图中,2 个最近的邻居是类 1,而 1 个邻居是类 2。因此,该模型将预测该数据点的类别 1。如果模型试图预测一个数值而不是一个类别,那么所有的“投票”都是被平均以得到预测的数值。
支持向量机
支持向量机通过在数据点之间建立一个边界来工作,其中一个类别的大部分落在边界的一边(在 2D 的情况下也称为线),而另一个类别的大部分落在另一边。
支持向量机图解
其工作方式是机器寻找具有最大余量的边界。边距定义为每个类的最近点与边界之间的距离(见图示)。然后绘制新的数据点,并根据它们落在边界的哪一侧放入一个类中。
我对这个模型的解释是针对分类情况的,但是你也可以用 SVMs 进行回归!
决策树和随机森林
我已经在以前的文章中解释过这些了——请点击这里查看(决策树和随机森林就在最后):
[## 向五岁儿童解释数据科学概念
在采访中简单描述技术概念
towardsdatascience.com](/data-science-concepts-explained-to-a-five-year-old-ad440c7b3cbd)
无监督机器学习模型
【慎用】
现在,我们正冒险进入无监督学习(也称为深层,一语双关)。提醒一下,这意味着我们的数据集没有被标记,所以我们不知道我们观察的结果。
k 表示聚类
当使用 K 均值聚类时,首先必须假设数据集中有 K 个聚类。由于您不知道数据中实际有多少组,因此您必须尝试不同的 K 值,并使用可视化和度量来查看哪个 K 值有意义。K means 最适用于圆形且大小相似的簇。
K 均值算法首先选择最佳的 K 个数据点来形成 K 个聚类中每个聚类的中心。然后,对每个点重复以下两个步骤:
- 将数据点分配给最近的聚类中心
- 通过取现在该聚类中的所有数据点的平均值来创建新的中心
K 均值聚类图
DBSCAN 聚类
DBSCAN 聚类分析模型与 K 均值聚类分析模型的不同之处在于,它不要求您输入 K 值,而且它还可以查找任何形状的聚类(请参见下图)。您不需要指定聚类的数量,而是输入您想要在一个聚类中的最小数据点数和数据点周围的半径来搜索一个聚类。DBSCAN 将为您找到集群!然后,您可以更改用于构建模型的值,直到获得对数据集有意义的聚类。
此外,DBSCAN 模型会为您分类“噪音”点(即远离所有其他观察值的点)。当数据点非常接近时,该模型比 K 均值更好。
神经网络
在我看来,神经网络是最酷、最神秘的模型。它们被称为神经网络,因为它们是模仿我们大脑中神经元的工作方式。这些模型在数据集中寻找模式;有时他们会发现人类可能永远也不会认识到的模式。
神经网络可以很好地处理图像和音频等复杂数据。从面部识别(停止令人毛骨悚然,脸书)到文本分类,它们是我们这些天一直看到的许多软件功能的背后。神经网络可以与已标记的数据(即监督学习应用)或未标记的数据(非监督学习)一起使用。
对于本文来说,即使只是触及神经网络如何运作的表面也可能过于复杂。如果你想了解更多,这里有一个“初学者”指南:【https://pathmind.com/wiki/neural-network】T4。
结论
希望这篇文章不仅增加了你对这些模型的理解,也让你意识到它们是多么的酷和有用!当我们让计算机做工作/学习时,我们可以坐下来看看它找到了什么样的模式。有时这可能会令人困惑,因为即使是专家也不明白确切的逻辑为什么计算机会得出这样的结论,但在某些情况下,我们所关心的只是它擅长预测!
然而,有些时候我们确实关心计算机是如何得到它的预测的,比如我们是否在使用这个模型来决定哪些求职者将获得第一轮面试。关于这方面的更多信息,这里有一个很棒的 TED 演讲,你不必是数据科学家也能理解或欣赏:
来自www.ted.com(使用条款)
一如既往,非常感谢你的阅读,如果你觉得这篇文章有用,请分享!😃
所有的图形都是我在www.canva.com(用爱)制作的。如果您想获得使用许可,请联系我。
也大喊到 肖恩·达文斯科特·克罗格多顿·奥帕西纳&巴努·耶拉 通过我们的数据科学面试练习环节帮助我更好地理解这些模型。**
物理学和工程学的机器学习模型
原文:https://towardsdatascience.com/machine-learning-models-for-physics-and-engineering-e77cdfbe68aa?source=collection_archive---------47-----------------------
物理学的主要目标是了解自然,而实现这一目标的一种方法是建立感兴趣的自然现象的模型。几个世纪以来,物理学家一直在挑战我们知识的极限,近年来,我们普遍开始遇到挑战,我们的物理驱动模型要么不够精确,要么太复杂,无法使用。在这些情况下,机器学习模型可以提供帮助。
模型是现实中一些相关部分的表示。一尊雕像是一个人的模型,一个词是一个事物的模型。在物理学中,我们对数学模型感兴趣——描述世界的方程。这些模型帮助我们理解现象并预测它们的行为。模型是基于假设的现实的简化。只要假设是合理的,模型预测就应该是准确的。力=质量 x 加速度是一个著名的模型,它对许多日常场景非常有效,但对微小物体(电子)、大质量物体(黑洞)或快速物体(光子)无效。
准确性和简单性是评估模型的两个重要因素。大多数情况下,这两者之间会有所取舍。按照 1:1 的比例绘制的城市地图可能非常精确,但非常复杂,因此完全没有用。因此,对于有用的模型来说,它应该高于一定的精度,并且低于一定的复杂度,其中规格取决于应用。
作为一个例子,让我们看看地球形状的 3 种模型:扁平,球形,扁球体(图 1)。随着精度的提高,模型的计算复杂性也随之增加。
图 1 三种不同的地球形状模型。
选择使用哪种模型在很大程度上取决于应用程序。尽管我们不是“地球是平的”,但我们实际上认为地球是“平的”,用于我们的许多日常活动,如去超市。但对于许多其他活动,如发射卫星,我们需要更精确的模型,我们可以负担更多的计算复杂性。我们的应用程序指定了我们希望模型所在的蓝色阴影区域(图 2)。
图 2 接受两种不同应用的模型空间(蓝色阴影区域)。注意,对于去超市,约束是计算复杂度的上限,而对于发射卫星,约束是准确度的下限。
我们经常遇到这样的情况:我们的物理模型不够精确(模型 X,图 3),或者计算过于复杂(模型 Y,图 3),无法满足我们的应用(蓝色阴影区域,图 3)。机器学习可以在两个基本方面提供帮助(图 3): (1)它可以提高准确性,而不增加复杂性。(2)它可以在不损失准确性的情况下降低复杂性。让我们来看看两者的一些例子。
图 3 两个基于物理的模型 X 和 Y 不符合规范。机器学习有两种方式可以帮助(1)提高准确性或(2)降低计算复杂性。
在我们最近的一个建造新型粒度分析仪的项目中,基于 Mie 理论的颗粒散射模型对于应用来说不够精确。使用机器学习模型(随机森林),我们能够构建满足规格的颗粒尺寸预测模型。你可以在我们的报纸上读到更多。在这种情况下,我们能够在不增加计算复杂性的情况下提高模型精度(图 3,(1))。在另一个与显微镜相关的项目中,基于物理衍射定律的图像重建算法需要大约 10 分钟才能运行,这阻碍了显微镜提供“实时”图像的能力。我们通过开发深度学习模型来帮助我们的合作者,该模型可以在不到 1 秒的时间内实现相同的构建。在这里,我们能够简化计算的计算复杂性,同时不牺牲任何精度(图 3,(2))。
但是机器学习如何实现这些令人印象深刻的结果呢?正如我们所讨论的,每个模型都需要假设。通常,你做的假设越多/越强,你失去的准确性就越多。物理模型需要一些强有力的假设(没有多重散射,粒子是完美的球体,等等。)而对于构建机器学习模型,你做出较弱的假设(这个随机森林有足够的能力从这个数据集中学习分散关系)。至于计算复杂性,当然,它不会消失。而是把它推到机器学习模型开发的训练阶段。换句话说,创建模型可能需要时间,但一旦模型经过训练并准备好使用,它就会非常快地生成新的预测。
机器学习有可能改变许多领域:从传感到材料发现,到成像,到动态系统的最优控制。
你可以在推特上找到我 @malicannoyan 。
机器学习监控:它是什么,我们错过了什么
原文:https://towardsdatascience.com/machine-learning-monitoring-what-it-is-and-what-we-are-missing-e644268023ba?source=collection_archive---------23-----------------------
部署后有生命吗?
图片作者。
部署后有生命吗?
恭喜你!您的机器学习模型现已上线。很多模特都没走那么远。有些声称,高达 87%的从未部署。考虑到从一个概念到一个可行的应用程序是多么的困难,庆祝是当之无愧的。
这可能感觉像是最后一步。
事实上,甚至机器学习课程的设计和机器学习工具的前景也增加了这种看法。他们广泛地处理数据准备、迭代模型构建和(最近的)部署阶段。尽管如此,无论是在教程中还是在实践中,模型投入生产后发生的事情通常都取决于运气。
图片作者。
这种忽视的简单原因是缺乏成熟。
除了少数与机器学习息息相关的技术巨头,大多数行业才刚刚起步。现实生活中的机器学习应用经验有限。许多公司第一次整理出许多东西,然后匆忙部署,这让他们不知所措。数据科学家做从数据清理到 A/B 测试设置的所有事情。模型操作、维护和支持通常只是事后的想法。
机器学习来世的一个关键但经常被忽视的组成部分是监控。
为什么监控很重要
一盎司的预防抵得上一磅的治疗——本杰明·富兰克林
用我们现在使用的学习技术,一个模型永远不会是最终的。在训练中,它学习过去的例子。一旦释放到野外,它就可以处理新数据:这可以是用户点击流、产品销售或信用申请。随着时间的推移,这些数据会偏离模型在训练中看到的数据。迟早,即使是最精确和经过仔细测试的解决方案也会开始退化。
最近的疫情非常生动地说明了这一点。
有些案件甚至上了头条:
- 由于购物习惯的巨大转变,Instacart 的模型预测商店商品可用性的准确性从 93%下降到 61%。
- 银行家质疑在繁荣时期训练的信贷模型是否能适应压力情景。
- 交易算法因市场波动而失灵。一些基金下跌了 21%。
- 图像分类模型不得不学习新的标准:一家人在笔记本电脑前意味着“工作”,而不是“休闲”
- 甚至天气预报也不太准确,因为有价值的数据随着商业航班的减少而消失了。
2020 年,你的图像分类模型可能需要学习“办公室工作”的新概念。
(图片由 赖图 上 像素 )
除此之外,实时数据会出现各种各样的问题。
存在输入错误和数据库中断。数据管道断裂。用户人口统计的变化。如果模型接收到错误或不寻常的输入,它将做出不可靠的预测。或者很多很多。
模型故障和未经处理的腐烂会造成损害。
有时这只是一个小麻烦,比如一个愚蠢的产品推荐或错误的标签照片。在高风险领域,比如招聘、评级或信贷决策,这种影响要深远得多。即使在营销或供应链等“低风险”领域,表现不佳的模式在规模化经营时也会严重冲击底线。公司在错误的广告渠道浪费金钱,显示不正确的价格,库存不足,或者损害用户体验。
监控来了。
我们不只是部署我们的模型一次。我们已经知道它们会断裂和降解。为了成功地操作它们,我们需要实时了解它们的性能。它们是否按预期工作?是什么导致了这种变化?是时候介入了吗?
这种可见性不是一件好事,而是循环中的一个关键部分。监控贯穿于模型开发生命周期,将生产与建模联系起来。如果我们发现质量下降,我们可以触发再培训或回到研究阶段发布一个模型重制。
图片作者。
让我们提出一个正式的定义:
机器学习监控 是一种跟踪和分析生产模型性能以确保用例定义的可接受质量的实践。它提供有关性能问题的早期警告,并帮助诊断问题的根本原因,以便进行调试和解决。
机器学习监控有何不同
有人可能会想:我们部署软件已经很久了,监控也不是什么新鲜事。用你的机器学习工具做同样的事情。为什么这么大惊小怪?
这话有几分道理。部署的模型是一个软件服务,我们需要跟踪通常的健康指标,比如延迟、内存利用率和正常运行时间。但除此之外,机器学习系统还有其独特的问题需要关注。
图片作者。
首先,数据增加了额外的复杂性。
我们应该担心的不仅仅是代码,还有数据质量及其依赖性。更多移动部件——更多潜在故障模式!通常,这些数据源完全不受我们的控制。即使管道得到了完美的维护,环境的变化也会悄悄进入管道,导致性能下降。
世界变化太快了吗?在机器学习监控中,这个抽象的问题开始被应用。我们密切关注数据变化,并随意量化变化的程度。这与检查服务器负载是完全不同的任务。
更糟糕的是,模型经常无声无息地失败。
不存在“坏网关”或“404”。尽管输入数据是奇数,系统也可能会返回响应。个人预测可能看起来有道理——尽管是有害的、有偏见的或错误的。
想象一下,我们依靠机器学习来预测客户流失,而模型却功亏一篑。可能需要几周的时间来了解事实(例如有风险的客户最终是否会离开)或注意到对业务 KPI 的影响(例如季度续订量下降)。只有这样,我们才会怀疑系统需要运行状况检查!你几乎不会错过这么长时间的软件中断。在不受监控的模型领域,这种看不见的停机时间是一种令人担忧的现象。
为了扭转局面,你必须及早做出反应。这意味着只评估输入的数据和模型的反应:一种特殊的半盲监测。
图片作者。
“好”和“坏”之间的区别并不明显。
一个偶然的异常值并不意味着模型失控,需要紧急更新。与此同时,稳定的准确性也会产生误导。隐藏在聚合数字后面的模型可能会在一些关键数据区域悄然失效。
图片作者。
没有上下文,度量是没有用的。
可接受的性能、模型风险和错误成本因用例而异。在贷款模式中,我们关心公平的结果。在欺诈检测中,我们几乎不能容忍假阴性。有了补货,多订购可能比少订购好。在营销模式中,我们希望密切关注高端市场的表现。
所有这些细微差别都反映了我们的监控需求、需要关注的具体指标以及我们解释它们的方式。
因此,机器学习监控介于传统软件和产品分析之间。我们仍然关注“技术”性能指标——准确性、平均绝对误差等等。但我们的主要目标是检查机器学习支持的决策的质量:它是否令人满意、公正,以及是否服务于我们的业务目标。
简单地
只看软件度量是太少了。再看下游产品或业务 KPI 就来不及了。机器学习监控是一个独特的领域,它需要适当的实践、策略和工具。
谁应该关心机器学习监控?
简而言之:所有关心模型对商业影响的人。
当然,数据科学家在第一线。但一旦模型离开实验室,它就成为公司产品或流程的一部分。现在,这不仅仅是一些技术上的人工制品,而是为用户和利益相关者提供的实际服务。
该模型可以向外部客户呈现输出,例如电子商务网站上的推荐系统。或者它可以是一个纯粹的内部工具,例如为您的需求计划人员提供的销售预测模型。在任何情况下,都有一个业务所有者——产品经理或业务线团队——依靠它来交付成果。以及其他一些相关人员,从数据工程师到支持人员。
数据和业务团队都需要跟踪和解释模型行为。
图片作者。
对于数据团队来说,这关乎效率和影响。你希望你的模型做出正确的判断,并让企业采纳它们。你也希望维护是没有麻烦的。通过充分的监控,您可以快速检测、解决、预防事故,并根据需要刷新模型。可观察性工具有助于保持秩序,并节省你建造新东西的时间。
对于商业和领域专家来说,最终归结为信任。当你根据模型预测采取行动时,你需要一个理由来相信它们是正确的。您可能想要探索特定的结果,或者对模型的弱点有一个大致的了解。您还需要对正在进行的模型价值有清晰的认识,并对风险得到控制感到安心。
如果你从事医疗保健、保险或金融行业,这种监管就会变得正式。合规部将仔细检查模型的偏差和漏洞。由于模型是动态的,它不是一劳永逸的测试。您必须不断地对实时数据进行检查,以了解每个模型是如何跟上的。
我们需要生产模式的完整视图。
适当的监控可以做到这一点,并为每一方提供正确的度量和可视化。
图片作者。
让我们面对现实吧。企业采用可能是一场斗争。并且它通常只在模型部署之后才开始。这是有原因的。
在理想世界中,您可以将所有业务目标转化为一个优化问题,并达到使人工干预过时的模型精度。
在实践中,你经常会遇到一个混合系统和一堆其他的标准需要处理。这些是稳定性、伦理、公平性、可解释性、用户体验或边缘情况下的性能。你不能简单地将它们混合在你的误差最小化目标中。他们需要持续的监督。
有用的模型是被使用的模型。
如果生产系统永远做不到,神奇的沙盒准确性也没什么区别。
除了“速赢”试点项目之外,还必须实现价值。为此,您需要透明度、利益相关者的参与和正确的协作工具。
能见度是有回报的。
这种共享的环境提高了采用率。当事情偏离轨道时,它也会有所帮助。
假设一个模型返回一个“奇怪”的响应。这些是领域专家,他们会帮助你定义你是否可以忽略它。或者,你的模型在特定人群中失败了。你们可以一起集思广益,想出新的功能来解决这个问题。
想深入了解新兴的数据漂移吗?调整分类器决策阈值?找出如何通过调整产品特性来弥补模型缺陷?
所有这些都需要协作。
只有当整个团队都能够获得相关的见解时,这种参与才有可能。模型不应该是晦涩的黑箱系统。相反,你把它当作一个机器学习产品,一个可以审计和监督的产品。
如果处理得当,模型监控不仅仅是技术上的错误跟踪。它服务于许多团队的需求,并帮助他们在模型支持和风险缓解方面进行协作。
监测差距
现实中,存在着痛苦的不匹配。调查显示公司只监控三分之一的模型。至于其他的?我们似乎被蒙在鼓里。
故事通常是这样展开的。
首先,一名数据科学家负责照看模型。在部署之后,人们经常需要收集反馈并重复细节,这让你很忙。然后,模型被认为是完全可操作的,它的创建者离开去了一个新的项目。监控任务悬而未决。
一些团队会定期重新访问模型以进行基本的健康检查,并错过其间发生的任何事情。其他人只是从他们的用户那里发现问题,然后匆忙灭火。
解决方案是定制的和部分的。
对于最重要的型号,您可能会找到一个专用的自制仪表板。基于团队遇到的每一个连续的失败,他们经常成为定制检查的弗兰肯斯坦。为了描绘一幅完整的画面,每个模型监视器还将有一个定制的界面,而业务 KPI 存在于单独的孤立报告中。
如果业务团队中有人要求更深入的模型洞察,这将意味着定制脚本和耗时的分析工作。或者经常,请求被简单地取消。
很难想象依赖于抽查和人工审查的关键软件。但是这些脱节的、零碎的解决方案在现代数据科学世界中出奇地普遍。
为什么会这样?
一个原因是对部署的模型缺乏明确的责任。在传统的企业环境中,您有一个 DevOps 团队负责任何新软件。对于机器学习来说,这是一个灰色地带。
当然,它可以监视服务的健康状况。但是,当输入数据发生变化时——这是谁的地盘?一些方面涉及数据工程,而另一些方面更接近于运营或产品团队。
每个人的事就是没人的事。
数据科学团队通常会承担监控责任。但是他们已经处理了太多的事情,很少有动力把维护放在第一位。
最后,我们经常会掉球。
企业数据科学家的一天。图片作者。
盯紧 AI
我们应该立即用以生产为中心的工具和实践来解决这个差距。
随着应用数量的增长,整体模型监控变得至关重要。你可以手持一个模型,但不是一打。
让团队负起责任也很重要。我们部署机器学习来提供商业价值——我们需要一种在生产中清晰展示它的方式!以及让人们意识到停机时间的成本以及支持和改进工作的重要性。
当然,整个的数据科学过程都是混乱的。
我们很少记录实验。我们对部署管理不当。机器学习操作(又名 MLOps)是一种逐步解决这种混乱的新兴实践。监控在某种程度上是在最末端。然而,我们认为我们应该尽早解决这个问题。理想的情况是,你的第一个模型一出货。
当一位高级领导问你 AI 项目进展如何时,你不想花一天时间来回应。也不是最后一个知道模型失败的人。
无缝生产、可见收益和满意的用户是让机器学习获得规模化声誉的关键。除非在纯粹的研究中,那是我们的目标。
总结
监控可能很无聊,但却是成功的关键。
做得好,做得快。
本博客最初发表于https://evidentlyai.com。
机器学习监控正是我们在 看得出来要解决的 AI 。在 Github 中查看我们的 开源工具 !
想留在圈子里吗? 报名 获取我们的更新和产品消息,关注我们的Twitter和Linkedin获取更多关于生产机器学习的内容,或者加入我们的 不和谐社区 进行聊天和连线。
机器学习:通过预测菲亚特 500 的价格来观察线性模型是如何工作的
原文:https://towardsdatascience.com/machine-learning-observe-how-a-linear-model-works-by-predicting-the-prices-of-the-fiat-500-fb38e0d22681?source=collection_archive---------61-----------------------
用实例研究机器学习
图尔古特·阿利耶夫在 Unsplash 上的照片
简介
在本文中,我想通过向您介绍我做的一个真实项目来谈论线性模型。你可以在 my Github 中找到的项目包括预测菲亚特 500 的价格。
我的模型的数据集有 8 列,如下图所示,1538 行。
- 型号:流行、休闲、运动
- 发动机功率:发动机的千瓦数
- 车龄天数:车龄天数
- 公里:汽车行驶的公里数
- previous_owners:以前所有者的数量
- lat:卖家所在的纬度(意大利的汽车价格从该国北部到南部各不相同)
- lon:卖家的经度(意大利的汽车价格从该国北部到南部各不相同)
- 价格:销售价格
在本文中,我们将在第一部分看到关于线性回归、岭回归和套索回归的一些概念。然后,我将向您展示我对我考虑的数据集的基本见解,最后但同样重要的是,我们将看到我用来评估模型性能的准备工作和指标。
第一部分:线性回归、岭回归和套索回归
线性模型是一类使用输入要素的线性函数进行预测的模型。
关于回归,我们知道一般公式如下:
正如你已经知道的,x[0]到 x[p]代表单个数据点的特征。相反, m a b 是学习的模型参数, ŷ 是模型做出的预测。
回归有很多线性模型。这些模型之间的区别在于如何从训练数据中学习模型参数 m 和 b 以及如何控制模型复杂度。我们将看到三种回归模型。
- 线性回归(普通最小二乘法) →在训练集上找到使预测和真实回归目标 y 之间的均方误差最小的参数 m 和 b 。MSE 是预测值和真实值之间的平方差之和。下面介绍如何用 scikit-learn 计算它。
from sklearn.linear_model import LinearRegression X_train, X_test, y_train, y_test=train_test_split(X, y, random_state=0)lr = LinearRegression()lr.fit(X_train, y_train)print(“lr.coef_: {}”.format(lr.coef_)) print(“lr.intercept_: {}”.format(lr.intercept_))
- 岭回归 →它用于预测的公式与用于线性回归的公式相同。在岭回归中,系数(m)被选择用于很好地预测训练数据,但也适合附加约束。我们希望 m 的所有条目都接近于零。这意味着每个特征应该对结果有尽可能小的影响(小斜率),同时仍然预测良好。这种约束被称为正则化,这意味着限制模型以避免过度拟合。这种特殊的岭回归正则化称为 L2。岭回归在 linear_model 中实现。山脊如下图所示。特别是,通过增加 alpha,我们将系数移向零,这降低了训练集的性能,但可能有助于泛化并避免过度拟合。
from sklearn.linear_model import Ridge ridge = Ridge(alpha=11).fit(X_train, y_train)print(“Training set score: {:.2f}”.format(ridge.score(X_train, y_train))) print(“Test set score: {:.2f}”.format(ridge.score(X_test, y_test)))
- 套索回归 →另一种正则化方法是套索。与岭回归一样,使用套索也将系数限制为接近于零,但方式略有不同,称为 L1 正则化。L1 正则化的后果是,当使用套索时,某些系数恰好为零。这意味着模型完全忽略了一些特征。
from sklearn.linear_model import Lasso lasso = Lasso(alpha=3).fit(X_train, y_train) print(“Training set score: {:.2f}”.format(lasso.score(X_train, y_train))) print(“Test set score: {:.2f}”.format(lasso.score(X_test, y_test))) print(“Number of features used: {}”.format(np.sum(lasso.coef_ != 0)))
第二部分:我发现的见解
在看到关于模型的准备和评估的部分之前,看一下数据集的情况是有用的。
在下面的散点图中,我们可以观察到一些特征之间有一些特殊的相关性,如公里数、使用年限和价格。
作者图片
相反,在下面的相关矩阵中,我们可以很好地看到特征之间的相关结果。
特别是在年龄天数和价格或者公里数和价格之间,我们有很大的相关性。
这是构建我们的模型的起点,并知道哪个机器学习模型可能更适合。
作者图片
第三部分:准备并评估模型的性能
为了训练和测试数据集,我使用了线性回归。
**from** **sklearn.linear_model** **import** **LinearRegression**
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=0)
lr = LinearRegression()
lr.fit(X_train, y_train)
出局:
LinearRegression(copy_X=True, fit_intercept=True, n_jobs=None, normalize=False)
在下表中,有我为我的模型考虑的每个特征的系数。
coef_df = pd.DataFrame(lr.coef_, X.columns, columns=['Coefficient'])
coef_df
出局:
现在,是时候对模型进行评估了。在下图中,以 30 个数据点的样本为特征,我们可以观察预测值和实际值之间的比较。正如我们所见,我们的模型相当不错。
作者图片
R 平方是模型输入解释因变量变化的能力的良好度量。在我们的例子中,我们有 85%。
**from** **sklearn.metrics** **import** **r2_score** round(sklearn.metrics.r2_score(y_test, y_pred), 2)
出局:
0.85
现在,我计算 MAE、MSE 和 RMSE,以便更精确地了解模型的性能。
**from** **sklearn** **import** **metrics** print(‘Mean Absolute Error:’, metrics.mean_absolute_error(y_test, y_pred)) print(‘Mean Squared Error:’, metrics.mean_squared_error(y_test, y_pred))print(‘Root Mean Squared Error:',
np.sqrt(metrics.mean_squared_error(y_test, y_pred)))
最后,通过比较训练集得分和测试集得分,我们可以看到我们的模型是如何执行的。
print("Training set score: {:.2f}".format(lr.score(X_train, y_train)))print("Test set score: {:.2f}".format(lr.score(X_test, y_test)))
出局:
Training set score: 0.83 Test set score: 0.85
结论
线性模型是在实践中广泛使用的一类模型,并且在过去几年中被广泛研究,特别是对于机器学习。所以,有了这篇文章,我希望你已经获得了一个良好的起点,以便提高自己,创建自己的线性模型。
感谢你阅读这篇文章。您还可以通过其他方式与我保持联系并关注我的工作:
- 订阅我的时事通讯。
- 也可以通过我的电报群 初学数据科学 联系。
机器学习:通过预测意大利葡萄酒的品种来观察 KNN 是如何工作的
原文:https://towardsdatascience.com/machine-learning-observe-how-knn-works-by-predicting-the-varieties-of-italian-wines-a64960bb2dae?source=collection_archive---------62-----------------------
做中学
凯尔西·钱斯在 Unsplash 上的照片
简介
在这篇文章中,我想用一个实际的例子向你介绍 KNN。
我会考虑我的一个项目,你可以在我的 GitHub 简介中找到。对于这个项目,我使用了来自 Kaggle 的数据集。
该数据集是对意大利同一地区种植的葡萄酒进行化学分析的结果,但这些葡萄酒来自三个类别的三个不同品种。分析是通过考虑在三种类型的葡萄酒中发现的 13 种成分的数量来完成的。
本文将分为三个部分。在第一部分中,我将对 KNN 进行理论描述,然后我将专注于探索性数据分析部分,以便向您展示我发现的见解,最后,我将向您展示我用来准备和评估机器学习模型的代码。
第一部分:什么是 KNN,它在数学上是如何工作的?
k-最近邻算法不是复杂的算法。KNN 预测和分类数据的方法包括浏览训练数据,并找到最接近新点的 k 个训练点。然后,它将最接近的训练数据的类别标签分配给新数据。
但是 KNN 是如何运作的呢?要回答这个问题,我们必须参考两点之间的欧几里德距离公式。假设你需要计算笛卡尔平面上两点 A(5,7)和 B(1,4)之间的距离。您将应用的公式非常简单:
好吧,但是我们如何把它应用到机器学习中呢?假设你是一名书商,你想给一本名为《菲利普·K·蒂克的 Ubick》的新书分类,该书有 240 页,售价 14 欧元。正如你在下面看到的,有 5 个可能的类来放置我们的新书。
作者图片
为了知道哪个类最适合于 Ubick,我们可以使用欧几里德公式来计算数据集中每个观察值的距离。
公式:
作者图片
输出:
作者图片
正如你在上面看到的,最近的 Ubick 类是 C 类。
第二部分:我发现的创建模型的见解
在开始谈论我用来创建模型和预测葡萄酒品种的算法之前,让我简要地向你们展示一下我发现的主要见解。
在下面的热图中,不同功能之间存在关联。这对于初步了解我们数据集的情况以及了解是否有可能应用分类算法非常有用。
作者图片
乍一看,热图很棒,但这还不够。我还想知道是否有一些元素的绝对相关和很低,以便在训练机器学习模型之前删除它们。所以,我构建了一个直方图,如下图所示。
可以看到,有三个元素的总绝对相关度很低。元素是灰、镁和颜色强度。
作者图片
由于这些观察,现在我们确信有可能应用 KNN 算法来创建预测模型。
第三部分:使用 scikit-learn 进行预测
在这一部分中,我们将通过 scikit-learn 了解如何准备模型并对其进行评估。
下面你可以观察到我把模型分成两部分:80%用于训练,20%用于测试。我选择这个比例是因为数据集不大。
出局:
X_train shape: (141, 10)
y_train shape: (141,)X_test shape: (36, 10)
y_test shape: (36,)
你要知道 scikit-learn 中所有的机器学习模型都是在自己的类中实现的。例如,k-最近邻分类算法是在 KNeighborsClassifier 类中实现的。
第一步是将类实例化为一个对象,我称之为 cli ,如下图所示。该对象包含我将用来根据训练数据构建模型并对新数据点进行预测的算法。它还包含算法从训练数据中提取的信息。
最后,为了在训练集上构建模型,我们调用了 cli 对象的拟合方法。
出局:
KNeighborsClassifier(algorithm='auto', leaf_size=30, metric='minkowski',metric_params=None, n_jobs=None, n_neighbors=1, p=2,weights='uniform')
在 fit 方法的输出中,您可以看到创建模型时使用的参数。
现在,是时候对模型进行评估了。下面,第一个输出向我们展示了模型预测了 89%的测试数据。相反,第二个输出为我们提供了每个类的精确度的完整概述。
出局:
Test set score: 0.89
出局:
结论
我认为学习东西的最好方法是实践。所以在我的情况下,我从 Kaggle 下载数据集,这是找到一个好的数据集的最好地方之一,你可以在其上应用你的机器学习算法并了解它们是如何工作的。
感谢你阅读这篇文章。您还可以通过其他方式与我保持联系并关注我的工作:
- 订阅我的时事通讯。
- 也可以通过我的电报群 初学数据科学 联系。
AWS SageMaker 上的机器学习
原文:https://towardsdatascience.com/machine-learning-on-aws-sagemaker-b23e32503106?source=collection_archive---------27-----------------------
如何用线性回归预测员工工资
Photo by @ 你好我是 Nik 上Unsplash
在本教程中,我们将使用亚马逊 SageMaker Studio 在 AWS SageMaker 上创建一个 ML 模型,根据多年的经验来预测员工的工资。
问题陈述
想象一下,一个潜在的员工已经通过了面试,现在 HR 想要给他们一份工作。薪水会是多少?
假设:对薪水有影响的唯一因素是多年的经验。
成果概述
在本教程中,我将提出一个简单的线性回归模型。你在这个模型中输入多年的经验,它会做出相应的工资预测。
注:你可以在这里找到我之前的帖子 TK 中关于线性回归的完整解释。
案例研究—结果概述
使用的数据 : 卡格尔-工资-数据
为了让这更令人兴奋,我们将在 Amazon SageMaker 上构建、训练和部署 ML 模型——耶!
亚马逊 SageMaker 工作室
Sagemaker Studio 是一个用于机器学习的完全集成的开发环境(IDE),它允许我们编写代码、跟踪实验、可视化数据和执行调试。
跟随:
- 从 AWS 管理控制台搜索栏中找到 SageMaker 服务。
- 点击亚马逊 SageMaker 工作室。
- 点击左上角的+图标,启动你的 Jupyter 笔记本。
第一步:这项研究的目的是什么?
- 根据经验年限预测员工工资。
- 我们使用简单的线性回归模型:根据多年的经验(变量 X,独立变量)预测工资(变量 Y,独立变量)。
步骤 2:导入库和数据集
**#import required libraries**
import pandas as pd
import numpy as np
import seaborn as sns
import matplotlib.pyplot as plt**#if you need to install some packages, use this command:**
!pip install tensorflow**#read the Dataset**
salary_df = pd.read_csv('salary.csv')
salary_df.head(10)
salary_df.tail(10)
数据集的头部和尾部
第三步:探索性数据分析和可视化
**#get some information about our DataSet** salary_df.info()
salary_df.describe()**#check if there are any Null values**
salary_df.isnull().sum()
信息-描述-并检查是否有空值
**#visualizing data**
sns.pairplot(salary_df)
sns.heatmap(salary_df.corr(), annot=True)sns.regplot(salary_df['YearsExperience'], salary_df['Salary'], data = salary_df )
配对图-热图-正则图
第四步:将数据集分成训练集和测试集
我们使用Train
集合让算法学习数据的行为,然后我们在Test
集合上检查我们的模型的准确性。
Features(X)
:插入到我们模型中的列将用于进行预测。Prediction(y)
:将由特征预测的目标变量
**#define X variables and our target(y)**
X = salary_df[['YearsExperience']]
y = salary_df[['Salary']]**#splitting Train and Test**
from sklearn.model_selection import train_test_splitX_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.33, random_state=0)**#need to have y_train & y_test as an vector(for SageMaker linear learner)** y_train = y_train[:,0]
y_test = y_test[:,0]
第五步:使用 SageMaker 训练线性学习模型
在我们开始之前,让我们解释一下我们需要准备什么——我保证,我会很快的!
设置准备
亚马逊 S3
- 亚马逊 S3 是一种存储服务,允许我们在目录(桶)中存储和保护我们的数据。我们将需要这项服务继续前进
- bucket:是存储在亚马逊 S3 的对象的容器,每个 bucket 都有全局唯一的名称。
创建桶
- 首次搜索 S3 服务。
- 选择创建一个存储桶,并给它一个名称和区域。
- 点击下一步,直到您得到配置选项,您将阻止所有公共访问,并创建您的桶。
【创建前缀(桶内子文件夹)
在创建的桶中,点击“创建文件夹”并给它一个名字。
所以,我们有:
- 斗:斗:
sagemaker-practical-m
- 前缀:
IAM(身份和访问管理)
我们需要给我们的 Sagemaker 一个 IAM 角色,这样它就可以代表我们执行任务(例如,读取训练结果,从 S3 存储桶中调用模型工件,以及将训练结果写入 S3)
让我们回到我们的代码:
**#import required kits** import sagemaker
import boto3 **#create a Sagemaker session**
sagemaker_session = sagemaker.Session()**#define the S3 bucket and prefix(subfolder within the bucket)** bucket = 'sagemaker-practical-m'
prefix = 'linear-learner' **#define IAM role**
role = sagemaker.get_execution_role()
print(role)
运行上述代码后的结果。
Boto3 一个 AWS Python SDK,允许开发者编写使用亚马逊 S3 或 EC2 等服务的应用程序。
让我们将训练数据转换成 Sagemaker 兼容的输入格式(RecordIO)。更多关于这个的信息请点击。
**#import module in terms of dealing with various types of I/O** import io**#import sagemaker common library** import sagemaker.amazon.common as smac **#converts the data in numpy array format to RecordIO format** buf = io.BytesIO()
smac.write_numpy_to_dense_tensor(buf, X_train, y_train)
**#reset in-memory byte arrays to zero** buf.seek(0)
最后一个命令用于清除内存缓冲区。
在我们的数据被转换成记录格式并包含在缓冲区中之后。我们现在可以将数据上传到 S3:
**#import module**
import os
**#Key refers to the name of the file** key = 'linear-train-data'**#uploads the data in record-io format to S3 bucket** boto3.resource('s3').Bucket(bucket).Object(os.path.join(prefix, 'train', key)).upload_fileobj(buf)**#training data location in s3**
s3_train_data = 's3://{}/{}/train/{}'.format(bucket, prefix, key)print('uploaded training data location: {}'.format(s3_train_data))
我们刚刚创建了“train”文件夹,其中包含我们上传的数据(linear-train-data)。
让我们回到 S3 仓库,检查文件是否在那里:
我们需要指定 S3 位置来存储我们的线性学习器输出:
**#create an output location in S3 bucket to store the linear learner output** output_location = 's3://{}/{}/output'.format(**bucket**, **prefix**)print('Training artifacts will be uploaded to: {}'.format(output_location))
现在,要获得对线性学习器容器的引用,只需指定算法名:
**#specify the name of the algorithm, that we want to use** from sagemaker.amazon.amazon_estimator import get_image_uricontainer = get_image_uri(boto3.Session().region_name, 'linear-learner')
然后,我们传递希望用于训练的容器和实例类型。已经定义了输出路径和 SageMaker 会话变量。
linear = sagemaker.estimator.Estimator(container,
role,
train_instance_count = 1,
train_instance_type = 'ml.c4.xlarge',
output_path = output_location,
sagemaker_session = sagemaker_session)
这些参数可以调整:
- 传入的要素数。
- 预测器的类型(
regressor
或classifier
)。 - 小批量(每个小批量的观察次数)。
**#Train 32 different versions of the model and will get the best out of them** linear.set_hyperparameters(feature_dim = 1,
predictor_type = 'regressor',
mini_batch_size = 5,
epochs = 5,
num_models = 32,
loss = 'absolute_loss')**#pass in the training data from S3 to train the linear learner model** linear.fit({'train': s3_train_data})
步骤 6:部署训练好的线性学习模式
linear_regressor = linear.deploy(initial_instance_count = 1,
instance_type = 'ml.m4.xlarge')
为了在我们的模型中进行推理,我们需要将数据转换成文本/CSV 格式。在这里阅读更多。
from sagemaker.predictor import csv_serializer, json_deserializerlinear_regressor.content_type = 'text/csv'
linear_regressor.serializer = csv_serializer
linear_regressor.deserializer = json_deserializer
对测试集的预测:
**# making prediction on the test data** result = linear_regressor.predict(X_test)
result
让我们取出结果编号并保存在Prediction
板变量中:
**#access the scores by iterating through the scores in predictions** predictions = np.array([r['score'] for r in result['predictions']])
predictions
让我们检查结果作为一个DataFrame
:
**#compare actual output values with predicted values** df = pd.DataFrame({'Actual': y_test.flatten(), 'Predicted': predictions.flatten()})
df
**# visualize comparison result as a bar graph** df1 = df.head(20)
df1.plot(kind='bar',figsize=(12,8))
plt.grid(which='major', linestyle='-', linewidth='0.5', color='green')
plt.grid(which='minor', linestyle=':', linewidth='0.5', color='black')
plt.show()
**#prediction vs test set**
plt.scatter(X_test, y_test, color='blue')
plt.plot(X_test, predictions, color='red', linewidth=2)
plt.xlabel('Years of Experience (Testing Dataset)')
plt.ylabel('salary')
plt.title('Salary vs. Years of Experience')
plt.show()
差不多就是这样!
重要:如果不想被亚马逊收费,永远记得删除端点!
**# Delete the end-point** linear_regressor.delete_endpoint()
我希望这篇文章能帮助你更好地理解这个话题。欢迎任何反馈,因为它让我获得新的见解!
Azure 上带有自动预测的机器学习
原文:https://towardsdatascience.com/machine-learning-on-azure-with-automated-predictions-51d1721210f5?source=collection_archive---------17-----------------------
利用各种 Azure 服务创建端到端的生产机器学习管道
加州 17 英里路 Lone Cypress
我最近有机会在一家使用微软 Azure 作为人工智能平台的公司担任数据科学实习生。在我的一个项目中,我不得不推荐一个最优策略(设定点),在一个制造工厂中并行运行多个蒸汽锅炉。例如,在给定的特定条件下,以 100%(全容量)运行锅炉 1,以 50%运行锅炉 2,依此类推。目标是以最小的累积燃料输入满足工厂蒸汽需求。
由于这个问题的性质,锅炉的设定点将会 24/7 每分钟更新。
为了实现这一点,我在 Azure 上创建了一个端到端的机器学习(ML)管道。我所说的管道是指:
- 将数据从本地服务器获取到云
- 使用云计算创建预测模型,并将其部署为 API 端点
- 每周 7 天、每天 24 小时自动进行预测,并将其存储回本地服务器(这被证明是很棘手的)
- 创建用于监控性能的仪表板
在构建这个管道时,我发现微软的文档分散在几个产品中,而且不够直观,所以我认为分享我的工作流程并提供适当资源的链接会有所帮助。
工作流程可以总结在下图中。
这个博客的目的不是讨论 ML 方法论,而是理解如何利用不同的微软产品来创建端到端的生产管道。
那么,我们开始吧。
获取数据
在开始构建 ML 模型之前,我需要从本地 SQL server 查询相关的历史数据,并将其存储在云中。在这里,Azure Data Factory v2 ( ADF )派上了用场。ADF 允许您连接到本地数据库并编写 t-SQL 查询来将数据存储在 Azure Blob 存储中(Blob)。ADF 的 复制 工具(在移动和变换活动下)允许您复制所需的数据。
预测建模
一旦将所需数据存储在 blob 存储中,就可以使用 Azure 为开发 ML 模型提供的机器学习服务工作空间( ML Services )平台。如果你熟悉 Jupyter 笔记本环境,那么你会很高兴地知道 ML Services 允许你创建预装了重要库的笔记本。因此,您不需要担心环境的设置。
建立预测模型需要以下步骤:
- 创建你的 Azure 机器学习工作空间,根据你的数据大小和计算需求指定虚拟机(VM)的大小。我使用了一个 3M 乘 13 的数据集,需要创建多个 ML 模型。因此,我决定使用 8 核 28 GB 虚拟机(V2 D4 标准)
- 接下来,创建一个 Jupyter 笔记本和连接到 blob 存储器。一旦连接上,就可以很容易地将 blob 数据转换成 pandas 数据框架
- 创建一个 Azure 机器学习计算目标,它将并行运行多个作业,以加速训练和超参数调优
- 创建一个训练脚本,它将导入库、接受用户定义的参数、执行数据转换(如果有)、调整超参数、记录度量值等。基本上,它是在计算目标上运行的代码,用于训练您的模型
- 创建一个评估器,其中包含训练脚本的位置、用户定义的参数值、所需的 conda 和/或 pip 库,以及计算目标
- 使用定义的超参数搜索空间、提前终止策略、主要指标、最大超参数运行和最大并发作业,配置您的超参数调整实验。此外,提供将使用采样超参数调用的估计器(在上面的步骤中创建)
- 提交实验并实时可视化超参数调整进度
- 最后,群集返回最佳模型。使用完整的数据集重新训练它,注册最终模型用于部署
好的教程可以在这里找到。
部署模型
一旦最终的模型在工作空间中注册,我们需要将它部署为一个 API 端点,我们可以查询它以获得几乎即时的预测。为了创建 API,我使用了 Azure 容器实例( ACI )。
除了最终模型之外,您还需要以下内容来使用 ACI 成功部署模型:
- 入口脚本:该脚本将通过部署的 web 服务提交的数据传递给最终模型。然后,它将输出返回给客户端
- 依赖关系:创建一个. yml 文件,其中包含模型进行推理所需的包
- 部署配置:这描述了 API 的计算资源,例如内核和内存的数量
一旦您有了最终的模型、入口脚本、依赖项和部署配置,您就可以创建一个 docker 映像并部署模型。
全天候自动预测
这是有趣的部分。我需要 24/7 每分钟向本地服务器数据库提交预测,所以我必须自动化预测部分。为此,我创建了一个 Databricks 笔记本(参见下面的代码示例),它获取输入,向 API 提交请求,并提交预测。流程可以总结如下:
- 使用 ADF 将预测数据从本地服务器复制到云
- 运行 databricks 记事本,并根据您的需求将预测存储在 blob 存储或 SQL 数据库中(我将在下面讨论这两者)
- 使用 ADF 将预测从 blob 复制到本地 SQL 数据库
我的 ADF 管道快照,用于每分钟自动进行预测。绿色箭头确保前一个活动完成后,下一个活动才开始
为了每分钟都自动完成这个流程,您可以安排一个触发(触发的频率、开始和停止的时间等等。)在 ADF 中。跟随这个了解更多关于如何添加数据块到 ADF 的细节。
我的 Databricks 笔记本看起来像这样:
## Connect to the storage account containing input datastorage_account_name = 'storage_account_name' storage_account_access_key = 'access_key' spark.conf.set("fs.azure.account.key."+storage_account_name+".blob.core.windows.net", storage_account_access_key)
这将允许您连接到 blob 存储。接下来,我连接到特定的 blob 并将其转换为 pandas 数据帧。
## To read in the blob as spark dataframedf = spark.read.csv(“wasbs://folder@storage_account_name.blob.core.windows.net/blob_name”, header = True)
df_panda = df.toPandas()
现在,你有了熊猫数据框架中的数据。如果有的话,进行必要的数据转换。然后,调用 API 端点来获得预测。
## Post requests to API end-point to get predictions
uri = ‘API_end_point’
test_samples = json.dumps({‘input data feature’: values})
test_samples = bytes(test_samples, encoding=’utf8')
fitness_ga = requests.post(uri, test_samples, headers = {‘Content-Type’: ‘application/json’})
ng_pred = [fitness_ga.json()]
pd_df = spark.createDataFrame(pd.DataFrame(ng_pred))
这里 pd_df 是包含预测的火花数据帧。最后,您可以将这些预测保存到 Azure SQL Server 数据库或 blob,如下所示。
将数据块连接到 Azure SQL Server 数据库
## Connecting to SQL server database from databricks
jdbcHostname = ‘your_sql_server_name.database.windows.net’
jdbcDatabase = ‘sql_server_database_name’
jdbcPort = 1433
jdbcUsername=’your_sql_server_username’
jdbcPassword=’your_sql_server_password’jdbcUrl = “jdbc:sqlserver://{0}:{1};database={2}”.format(jdbcHostname, jdbcPort, jdbcDatabase)
connectionProperties = { “user” : jdbcUsername,
“password” : jdbcPassword,
“driver” : “com.microsoft.sqlserver.jdbc.SQLServerDriver”} ## append spark dataframe to SQL database
mode=’append’
pd_df.write.jdbc(url=jdbcUrl, table=”sql_table_name”, mode=mode, properties=connectionProperties)
将数据块连接到 Azure Blob 存储
## Connecting Databricks to Azure blob storage
output_container_path = “wasbs://folder@storage_account_name.blob.core.windows.net”
output_blob_folder = output_container_path+”/temporary_blob_name” ## overwrite the blob, this creates a bunch of files
pd_df.coalesce(1).write.mode(“overwrite”).option(‘header’, ‘true’).format(‘com.databricks.spark.csv’).save(output_blob_folder) ## move the required data to blob where you want predictions finally
files = dbutils.fs.ls(output_blob_folder)output_file = [x for x in files if x.name.startswith(‘part-’)]
dbutils.fs.mv(output_file[0].path, output_container_path+’/blob_name’)
仪表盘
一旦开始用预测填充本地数据库,就可以用 PowerBI 连接本地数据库。PowerBI 让您只需从数据库表中拖放字段,就可以创建令人惊叹的可视化效果。一旦您在 PowerBI 中获得了所需的数据,您就可以计算和可视化关键性能指标(KPI)来衡量您的模型的性能。例如,在我的例子中,一个 KPI 可以是一段时间内的产出与投入(效率)的比率。创建后,您可以在数据库更新时自动更新仪表板。
事实上,在分析您的数据时,PowerBI 非常方便,可以节省您的时间和编码工作,同时创建出版物质量的交互式图表。
重要的考虑和学习
- 成本 :涉及两大成本,ML 服务的虚拟机(VM)和数据块集群。根据数据的大小和建模的复杂程度,您必须决定虚拟机内核和内存的最佳数量。同样,选择大于所需的 Databricks 集群可能会导致更高的成本。此外,确保在不使用时停止 ML 服务工作区和 Databricks 集群,以节省不必要的额外成本
- 延迟与模型复杂性:在我的情况下,我有多个 ML 模型,每分钟都需要预测(从本地服务器获取数据到将预测提交回本地服务器需要 1 分钟)。因此,我需要选择一个预测时间最短的模型,同时又不影响预测的准确性。 LightGBM 对我很有效
- 为什么是数据砖块? :我知道我可以使用 ADF 自动触发一个管道,ADF 允许我使用 Databricks notebook 作为活动。因为我可以用 Databricks 编写 python 和 spark 代码,所以这对我来说是一条自然的道路
- 从内部部署到云 :从内部部署的 SQL 数据库向云查询大量数据可能非常耗时。因此,确保将查询的数据保存在云上的某个地方。例如,如果您想在 3 个月后重新训练您的模型,您只需要查询最近 3 个月的附加数据
- 数据块到数据库 :我无法直接从数据块将预测写入本地数据库。但是,能够使用 ADF 将预测从 azure blob 存储写入本地数据库
- 输出错误日志 : Azure 在出错时输出错误日志。例如,如果您在超参数调整或部署模型时遇到错误,阅读错误日志可以节省您大量的调试时间
- XGBoost 风扇 :在 ML 服务中,XGBoost 不会预装 Jupyter 笔记本。要获得 XGBoost,将下面的代码复制粘贴到 jupyter 笔记本中,它应该可以工作了
*import sys
!conda install — yes — prefix {sys.prefix} py-xgboost
!conda install -y anaconda py-xgboost*
从头开始设计如此复杂的管道可能很难,尤其是如果你是 Azure 的新手。希望这篇博客能帮助你开始。您可以创建一个 Microsoft Azure 免费帐户,并开始使用他们的大部分服务。关于如何开始的更多细节,请跟随这个。
最后,我想真诚地感谢我的合作者 Radek Rybicki,他帮助我定义了这个项目,并指导我完成了它的不同阶段。
这是我的第一个数据科学博客,我真的很兴奋能继续写博客。如果您有任何意见和/或建议,请告诉我。我们可以稍后更详细地讨论管道的每个方面。
机器学习或回归的意想不到的优点
原文:https://towardsdatascience.com/machine-learning-or-the-unexpected-virtue-of-regression-b466a341acac?source=collection_archive---------51-----------------------
我希望在艰难地学会 ML 之前就知道的事情
照片由张秀坤镰刀在 Unsplash 上拍摄
计算机可以学习的想法激发了我们的想象力。我们看到机器人,自动驾驶汽车,我们想知道这怎么可能?好的,我们可以试着对我们的笔记本电脑说“来吧,伙计,跟着我学”。这是个好主意,不是吗?哦,你是对的,它不是那样工作的…暂时。
理解计算机如何能够学习东西可能是相当令人生畏的。我去过那里,努力研究人工神经网络是如何工作的。最后,所有元素都点击了。然而,我学得越多,就越明白我应该从一个不同的位置开始,让学习变得更容易、更有效。
这就是为什么我分享一个解释我们的计算机如何学习的故事。你也会发现回归并不总是意味着坏事。实际上,它会给你一个坚实的开端,让你进入机器学习的迷人世界。
闪回
想象一个典型的计算机科学学生。戴着眼镜,穿着极客 t 恤,因为熬夜和学习(或者玩电子游戏)看起来很累。主要的光源是一台来自计算机的显示器,太阳不是他的朋友。那是我,几年前。我已经了解了神经网络是如何工作的,我将参加关于更高级智能系统的实验室。实验开始了,我拿到任务,开始阅读:
实施一种智能方法…
这个简单的句子打动了我。什么是智能方法?我试图按照 费曼手法【1】去学习东西:
第一步:选择一门你想学的学科,开始学习。
第二步:试着像对孩子解释一样解释。
我无法完成第二步,所以我决定问问我的讲师。他是这么回答的:
“嗯,我认为每一种需要某种训练的方法都是智能的或机器学习的方法。你知道,动物和人通常被认为是聪明的。我们需要训练来掌握我们需要的技能。你的程序也努力训练,为你解决问题。”
这个简单的,非正式的定义是辉煌的。只是模仿一个程序,把它看作一个运动员或学生,他们通过试错变得越来越好。而且在实现目标的过程中非常执着。这就是机器学习的大视野。
记住这幅图,让我们来解释机器学习的主要方法之一,即监督学习。
回到学校
我喜欢把监督学习比作被老师思考。让我们回到我们上小学的时候。坐在教室里,等待老师教我们如何识别不同种类的树叶,如何命名和书写字母和数字。
疾控中心在 Unsplash 上拍摄的照片
可能你的老师给了你一些例子。例如,他们给你看不同树的叶子,并给这些树命名。此外,它们可以让你注意到叶子的一些特征,如形状、颜色或结构。上完这一课后,你可以在公园散步时摘一片叶子,给一棵树命名。
这个想法适用于监督学习。首先,你是老师。你想解决某个任务,想教某人如何去做。这意味着你需要一个学生。在机器学习世界中,它通常是一个数学模型(比如一个方程或一组以特定方式组合的数字)。
然后,你要准备你的例子和每个例子的正确答案。这个数据集对于解决你的任务应该是有用的(例如,如果你想有一个识别它们的程序,树叶的照片)。
有了这个数据集,你就可以向你的模型展示你的例子了。您检查模型的反应,并将其与正确答案进行比较。最后,您必须调整您的模型参数(通常是许多数字),以便它正确响应。
呈现示例、将模型的响应与正确答案进行比较以及调整参数的过程是迭代的。你重复它直到你的模型学习正确的答案。
寓教于乐
现在我们可以进入更多的细节,并尝试使用 ML 解决一个问题。所以作为一名教师,你想激发学生学习 ML 的好奇心。大概很多同学都爱超级英雄(我也爱他们)。你可以在任何地方找到它们,它们成为了我们文化的一部分。
照片由 Ali Kokab 在 Unsplash 上拍摄
所以我们来公式化一个你想解决的问题。你想知道超级英雄服装和他们的受欢迎程度之间有什么关系。
首先,我们来准备我们的例题和正确答案。为了做到这一点,我们需要弄清楚我们可以使用什么样的数据来建立服装和流行之间的关系。
幸运的是,浏览互联网会给你带来一个绝妙的主意。金钱可以很好地反映受欢迎程度。让我们试一试。选择大约 50 个超级英雄,检查我们需要为每个超级英雄服装支付多少钱。
然后你可以找到超级英雄出现的漫画书数量,并假设他们出现的越多越好。为了找到这样的数据,我们将使用下面的【2】。
综合来看,排名中的每个超级英雄都有两个数字。服装价格(x),漫画出镜率(y):
超级英雄数据集。(图片由作者提供)
这是我们的数据集。因为每行有两个数字,我们可以画一个图,看看它在 2D 是什么样子。
2D 的超级英雄。
现在是时候选择我们的学生了,一个将学习如何解决任务的机器学习模型。如果你看我们的情节,你可能会看到这个趋势,越贵的服装越多的漫画出现。如果我给你一支笔,让你画出这个趋势,你可以画一条简单的直线。
用我们自己的大脑画出一个趋势。(图片由作者提供)
它非常符合我们的数据,不是吗?所以让我们用一条线作为我们的 ML 模型。
是鸟…是飞机…是线性回归!
我们将要使用的方法的正式名称是线性回归[3]。这是一种建模变量之间关系的方法。你可以用它来检查房子的大小与价格的关系,或者电流与电压的关系。我们想知道服装价格和漫画形象之间的关系。
我们的模型是一个线性方程(f(x)-漫画书发行数量),有两个参数θ₀,θ₁(thetas)和变量 x(服装价格)。
线方程。(图片由作者提供)
它是如何工作的?让我们假设θ₀= 1,θ₁= 1。这意味着如果我们把 0 作为 x,我们有 0 乘以 1 等于 0,加上 1 等于 1。对于 x = 2,它是 2 乘以 1,加上 1 就是 3。我们可以用这些点(0,1),(2,3)来画一条线。
θ₀= 1,θ₁= 1 的线性函数草图(图片由作者提供)
如果我们改变参数,我们的线将通过不同的点。当然,在我们的机器学习风味的线性回归中,我们希望自动找到最佳参数。我们的程序将尝试不同的θ值,它需要知道这些参数正常意味着什么。这就是为什么我们需要一个目标函数。
测试你的学生
在 ML 中,能够评估你的模型是非常重要的。你只需要知道它的表现是好是坏。我们使用所谓的目标函数来实现。让我们定义我们的线性回归目标函数。
线性回归目标函数。(图片由作者提供)
目标函数 Q 取决于在我们的程序寻找解决方案时改变的 thetas 参数,以及代表超级英雄的数据点(点是不变的,它们是真理的来源)。
按照这个公式,我们需要遍历所有的数据点(按照 jᵗʰ指数编号)。所以拿第一点来说,得到它的服装价格(xʲ)并计算函数 f 的一个值。然后减去这一点的漫画书发行数量(yʲ).将结果平方,并将其添加到总和中。对我们数据集中的每一点都这样做。
为了更容易理解,让我们看看这些例子。从我们的数据集中抓取一个点。想象一下,f(xʲ对这一点给你 4,而 yʲ等于 2。将这些值代入目标函数公式:
图片作者。
如你所见,在计算了这个特定点的目标函数公式后,我们得到了 4。这意味着我们需要在总和上加 4。好了,和在增长,去下一个点。
图片作者。
函数 f(xʲ的时间值是 1,而我们期望的是 1 (yʲ=1).如你所见,根据目标函数公式,我们在这一点上得到了 0。这意味着我们不需要添加任何东西到我们的总和,它保持在同一水平。
这就是我们的目标函数的工作方式!总和越接近 0 越好。如果数据点的函数值 f(x)接近或等于期望值(y),这意味着我们找到了最佳θ参数。换句话说,当例子与正确答案相匹配时,我们会很高兴。所以我们需要最小化目标函数(总和应该很低)来解决我们的问题。
机器学习的超级英雄
为了最小化我们的目标函数,我们将使用梯度下降算法【3,4】。对我来说,它是 ML 中的主要算法之一。其背后的基本思想通常用于复杂而强大的 ML 方法,如深度学习[4]。幸运的是,我们可以用一种非常简单的方式将它用于线性回归任务,并理解它是如何工作的。
首先,梯度下降是一种迭代算法。在每次迭代中,我们按照神秘的公式更新θ参数:
图片作者。
图片作者。
别担心,它看起来比实际复杂得多。开始之前,我们将θ初始化为一些随机值。然后我们开始更新它们。θ₀(t)和θ₁(t)是当前迭代(t)中θ参数的值。我们通过减去α,也称为学习步长(小实数,如 0.25),乘以我们的目标函数的偏导数(∂q/∂θ)来改变它们。好吧,这听起来不简单,为什么我们需要衍生品?
关于导数你需要知道的最重要的事情是,函数的导数告诉你函数是如何变化的。如果你的函数是递增的,这个函数在这一点的导数将是正的。如果它在减少,导数将是负的。
为了简单起见,让我们假设我们的目标函数是一个简单的抛物线。其值取决于θ参数(θ轴)。如果我们计算函数 f 在抛物线上升点的导数,导数的值将是正的。在梯度下降公式中,它成立:-α乘以正导数。负乘以正得出一个负值
(例如-4 * 3 = -12)。这意味着我们需要从当前的θ中减去一些东西。
在下一次迭代中,我们计算一个新点的导数,如果它是正的,我们再从θ中减去一些。这就是我们如何在几个步骤中达到最小值。为了更好的理解,我们来形象化一下。
当从抛物线的上升边缘开始时,通过减法更新θ。(图片由作者提供)
如果我们把起点选在抛物线的递减边缘,我们的导数将是负的。所以当我们遵循梯度下降公式时,我们有-α倍的负导数。负乘以负得出正值(例如(-2)*(-3) = 6)。所以现在我们在θ上加一些东西。加法意味着我们在θ轴上向右移动。按照同样的步骤,我们最终达到最小值。这是视觉效果。
当从抛物线的递减边缘开始时,通过增加来更新θ。(图片由作者提供)
这就是如何使用梯度下降来最小化目标函数并找到最佳θ。想象你正在下山。不管你在哪里,计算导数的值,反方向(-α)到达山谷。把这个想法记在脑子里。计算机就是这样学习的。
买一套超级英雄服装要花多少钱?
最后,我们有了拼图的所有元素:
- 数据集(代表超级英雄的点)
- 模型(直线方程)
- 目标函数(对我们所有的点进行巧妙的求和)
- 学习算法(梯度下降)
让我们运行梯度下降 1000 次迭代。这意味着我们将更新这两个标签 1000 次。那么我们的程序应该已经有最好的 thetas 了。
我们的最佳 thetas 是:
最佳 thetas。(图片由作者提供)
当我们将它们代入线方程时,我们得到:
我们数据集的最佳直线方程。(图片由作者提供)
这就是我们的模型从数据集中学到的,但我同意这不是很有用。为了让它更实用,我们可以让它来回答我们的问题。假设你想投资 1 000 美元购买超级英雄服装(这是一大笔钱,但超级英雄的崇拜者会这么做)。一张图胜过千言万语,让我们画出最佳路线:
基于机器学习的服装价格对商品图书发行的线性回归模型。(图片由作者提供)
多亏了我们的模型,我们看到,如果我们投资如此昂贵的服装,它预测大约 8000 本漫画书会出现。不错啊,我们可以跻身出版最多的超级英雄前 10 名了!
你要去冒险了
关于老师,学生,识别树叶,解决超级英雄问题的故事到此结束。然而,这是你进入机器学习世界的旅程的开始。现在你对计算机如何学习有了直觉,并且熟悉了最强大的 ML 概念之一,梯度下降算法。如果你对本文介绍的 ML 风格线性回归的实际实现感兴趣,请查看我的 Github 库 [5]。
是时候更进一步了,认识新的算法,概念,问很多问题。也许值得检查一下当教室里没有老师时会发生什么?如果是这样,理解无监督学习应该是你的下一步。
参考书目:
- https://interesting engineering . com/learn-like-an-engineer-the-Feynman-technique
- https://www . ranker . com/list/super heroes-rank-by-most-comic-book-appearances/ranker-comics
- Grus Joel,《从零开始的数据科学》,第二版,奥赖利媒体公司。
- 帕特森乔希,吉布森亚当,深度学习,奥莱利媒体公司。
- https://github.com/rauluka/mluvr-regression
机器学习感知器实现
原文:https://towardsdatascience.com/machine-learning-perceptron-implementation-b867016269ec?source=collection_archive---------34-----------------------
Python 使用增量规则(梯度下降)
照片由摄影师在 Unsplash 上拍摄
在这篇文章中,我们将看看用numpy
用Python3
写的一个程序。我们将讨论什么是感知器的基础知识,什么是 delta 规则以及如何使用它来收敛感知器的学习。
什么是感知器?
感知器是二元分类器监督学习的算法(让我们假设{1, 0}
)。我们有一个权重向量和输入数据向量的线性组合,它通过一个激活函数,然后与一个阈值进行比较。如果线性组合大于阈值,我们预测该类为1
,否则为0\. Mathematically,
资料来源:stackexchange.com
感知器只代表线性可分的问题。如果训练样本不是线性可分的,它们就不能收敛。这就带来了德尔塔法则。
delta 规则向目标概念的最佳近似收敛。其核心思想是利用 梯度下降 搜索所有可能权重向量的假设空间。
注意:这为“反向传播”算法提供了基础。
现在,让我们讨论一下手头的问题。程序将读取一个数据集(制表符分隔文件),并将第一列视为目标概念。目标概念中存在的值是 A 和 B,我们将把 A 视为+ve 类或1
,把 B 视为-ve 类或0
。该程序以批处理模式实现感知器训练规则,具有恒定的学习速率和退火(随着迭代次数的增加而减少)学习速率,从学习速率为 1 开始。
其中 Y(x,w)是被错误分类的样本集。我们将使用错误分类点的计数或数量作为我们的错误率(即| Y(x,w)|)。输出也将是包含每次迭代误差的制表符分隔(tsv)文件,即它将有 100 列。同样,它将有 2 行,一行用于正常学习率,一行用于退火学习率。
现在,理解什么是感知机,什么是德尔塔法则,以及我们将如何使用它。让我们开始实施Python3
。
在程序中,我们从命令行提供两个输入。它们是:
1.数据 —数据文件的位置。
2.输出—tsv 解决方案的写入位置
因此,程序应该能够这样启动:
python3 perceptron.py --data data.tsv --output solution.tsv
该程序由 8 部分组成,我们将一次看一个。
进口报表
import argparse # to read inputs from command line
import csv # to read and process dataset
import numpy as np # to perform mathematical functions
代码执行初始化程序块
# initialise argument parser and read arguments from command line with the respective flags and then call the main() functionif __name__ == '__main__':
parser = argparse.ArgumentParser()
parser.add_argument("-d", "--data", help="Data File")
parser.add_argument("-o", "--output", help="output")
main()
[main()](https://gist.github.com/tarunlnmiit/744221fb4289efc5d1e02d2a20b251d1)
功能
main()
功能的流程如下:
- 将各自的命令行输入保存到变量中
- 设置开始学习率= 1
- 使用
csv
和delimiter='\t'
读取数据集,在X
中存储自变量,在Y
中存储因变量。我们将1.0
作为偏差添加到我们的独立数据中 - 独立数据和从属数据被转换为浮点型
- 重量向量用与
X
维数相同的零初始化 - normal error和anneal error通过调用各自的方法来计算****
- 最后,输出保存到一个 tsv 文件中
calculateNormalBatchLearning()函数
calculateNormalBatchLearning()
的流程如下:
- 初始化变量
e
以存储错误计数 - 循环运行 100 次迭代
- 使用calculatecopredictedvalue()方法,根据之前描述的感知器规则计算预测值
- 使用 calculateError() 方法计算错误计数
- 使用 calculateGradient() 方法根据上述等式更新权重
calculateanelbatchlearning()函数
calculateNormalBatchLearning()
的流程如下:
- 初始化变量
e
以存储错误计数 - 循环运行 100 次迭代
- 使用calculatecopredictedvalue()方法,根据之前描述的感知器规则计算预测值
- 使用 calculateError() 方法计算错误计数
- 学习率除以迭代次数
- 使用 calculateGradient() 方法根据上述等式更新权重
calculated predicted value()函数
如感知器图像所述,如果W
和X
的线性组合大于0
,那么我们预测类为1
否则为0
。
calculateError() 函数
我们计算预测值和真实值不匹配的情况的数量,这成为我们的错误计数。
calculateGradient() 函数
该方法是上述权重更新公式的翻译。
我将免费赠送一本关于一致性的电子书。在这里获得你的免费电子书。
现在,所有的代码都在外面。让我们来看看程序的执行情况。
下面是输出的样子:
最终程序
如果你喜欢阅读这样的故事,并想支持我成为一名作家,可以考虑注册成为一名媒体会员。每月 5 美元,你可以无限制地阅读媒体上的故事。如果你注册使用我的链接,我会赚一小笔佣金,不需要你额外付费。
**** [## 加入我的推荐链接-塔伦古普塔
作为一个媒体会员,你的会员费的一部分会给你阅读的作家,你可以完全接触到每一个故事…
tarun-gupta.medium.com](https://tarun-gupta.medium.com/membership)
这是我的故事索引:
[## 标记故事列表的快速链接—感谢您的访问
我也有一份以快节奏出版为目标的出版物。读书成为作家。
tarun-gupta.medium.com](https://tarun-gupta.medium.com/thank-you-for-visiting-my-profile-9f708062c75e)****
使用 Kubeflow 的机器学习管道
原文:https://towardsdatascience.com/machine-learning-pipelines-with-kubeflow-4c59ad05522?source=collection_archive---------5-----------------------
如何使用 Kubeflow 管道自动化机器学习工作流
为什么是机器学习管道?
现在,人们对机器学习管道的想法给予了很多关注,这意味着自动化和协调训练机器学习模型所涉及的各种步骤;然而,将机器学习工作流建模为自动化管道的好处并不总是很清楚。
当承担训练新的 ML 模型的任务时,大多数数据科学家和 ML 工程师可能会从开发一些新的 Python 脚本或交互式笔记本开始,这些脚本或笔记本执行必要的数据提取和预处理,以构建一组干净的数据来训练模型。然后,他们可能会创建几个额外的脚本或笔记本来尝试不同类型的模型或不同的机器学习框架。最后,他们将收集和探索指标,以评估每个模型在测试数据集上的表现,然后确定将哪个模型部署到生产环境中。
人工机器学习工作流程。(图片由作者提供)
这显然是对真正的机器学习工作流的过度简化,但关键是这种通用方法需要大量的人工参与,并且除了最初开发它的工程师之外,任何人都无法重用或轻松重复。
我们可以使用机器学习管道来解决这些问题。我们可以将这个工作流程视为一系列独立的模块化步骤,每个步骤都专注于一个特定的任务,而不是将数据准备、模型训练、模型验证和模型部署视为针对我们正在工作的特定模型的单个代码库。
机器学习管道。(图片由作者提供)
将我们的机器学习工作流建模为机器学习管道有许多好处:
- 自动化:通过消除人工干预的需要,我们可以安排我们的管道以特定的节奏重新训练模型,确保我们的模型适应训练数据随时间的漂移。
- 重用:由于管道的步骤与管道本身是分离的,我们可以很容易地在多个管道中重用单个步骤。
- 可重复性 : 任何数据科学家或工程师都可以重新运行管道,然而,通过手动工作流,现在可能总是很清楚不同脚本或笔记本需要以什么顺序运行。
- 环境的解耦:通过保持机器学习流水线的步骤解耦,我们可以在不同类型的环境中运行不同的步骤。例如,一些数据准备步骤可能需要在大型机器集群上运行,而模型部署步骤可能在单台机器上运行。
如果你有兴趣深入研究机器学习管道及其优势,Google Cloud 有一篇很棒的文章,描述了更好、更自动化的实践(包括 ML 管道)的自然进展,团队可以采用它来完善他们的 ML 工作流: MLOps:机器学习中的连续交付和自动化管道
什么是库伯流?
Kubeflow 是一个基于 Kubernetes 的开源平台,旨在简化机器学习系统的开发和部署。在官方文档中被描述为 Kubernetes 的 ML 工具包,Kubeflow 由几个组件组成,跨越了机器学习开发生命周期的各个步骤。这些组件包括笔记本开发环境、超参数调优、功能管理、模型服务,当然还有机器学习管道。
Kubeflow 中央仪表盘。(图片由作者提供)
在本文中,我们将只关注 Kubeflow 的管道组件。
环境
为了运行示例管道,我使用了在裸机上运行的 Kubernetes 集群,但是您可以在安装了 Kubeflow 的任何 Kubernetes 集群上运行示例代码。
本地唯一需要的依赖项是 Kubeflow Pipelines SDK。您可以使用 pip 安装 SDK:
pip install kfp
库伯弗洛管道公司
Kubeflow 中的管道由一个或多个组件组成,它们代表管道中的各个步骤。每个组件都在自己的 Docker 容器中执行,这意味着管道中的每个步骤都可以有自己的依赖集,独立于其他组件。
对于我们开发的每个组件,我们将创建一个单独的 Docker 映像,它接受一些输入,执行一个操作,然后公开一些输出。我们还将有一个单独的 python 脚本,pipeline.py
,它从每个 Docker 映像创建管道组件,然后使用这些组件构建一个管道。
我们将总共创建四个组件:
- 预处理-数据 : 该组件将从
sklearn.datasets
加载波士顿住房数据集,然后将数据集拆分为训练集和测试集。 - train-model :该组件将训练一个模型,使用波士顿住房数据集来预测波士顿房屋的中值。
- 测试模型:该组件将计算并输出测试数据集上模型的均方误差
- deploy-model :在本文中,我们不会关注模型部署或服务,所以这个组件只会记录一条消息,说明它正在部署模型。在真实的场景中,这可能是将任何模型部署到 QA 或生产环境的通用组件。
ML 管道图视图。(图片由作者提供)
如果所有这些关于组件和 Docker 图像的讨论听起来令人困惑:不要担心,当我们进入代码时,它们应该会变得更有意义。
组件:预处理数据
我们管道中的第一个组件将使用sklearn.datasets
加载波士顿住房数据集。我们将使用 Sci-kit learn 的train_test_split
函数将这个数据集分成训练集和测试集,然后我们将使用np.save
将我们的数据集保存到磁盘,以便它可以被后面的组件重用。
到目前为止,这只是一个简单的 Python 脚本。现在我们需要创建一个 Docker 映像来执行这个脚本。我们将编写一个 Dockerfile 文件来构建映像:
从python:3.7-slim
基础映像开始,我们将使用pip
安装必要的包,将预处理 Python 脚本从我们的本地机器复制到容器,然后将preprocess.py
脚本指定为容器入口点,这意味着当容器启动时,它将执行我们的脚本。
建设管道
现在我们开始管道工程。首先,您需要确保我们上面定义的 Docker 映像可以从您的 Kubernetes 集群中访问。出于这个例子的目的,我使用了 GitHub Actions 来构建图像并将其推送到 Docker Hub 。
现在让我们定义一个组件。每个组件都被定义为一个返回类型为ContainerOp
的对象的函数。这种类型来自我们之前安装的kfp
SDK。下面是我们管道中第一个组件的组件定义:
注意,对于image
参数,我们传递由上面的 Docker 文件定义的 Docker 图像的名称,对于file_outputs
参数,我们指定由组件 Python 脚本保存到磁盘的四个.npy
文件的文件路径。
通过将这四个文件指定为文件输出,我们使它们可用于管道中的其他组件。
注意:在我们的组件中硬编码文件路径并不是一个很好的做法,因为,正如你从上面的代码中看到的,这要求创建组件定义的人知道关于组件实现的具体细节(也就是包含在 Docker 映像中的实现)。让我们的组件接受文件路径作为命令行参数会干净得多。这样,定义组件的人可以完全控制输出文件的位置。我以这种方式对它进行了硬编码,希望可以更容易地看到所有这些部分是如何组合在一起的。
定义了第一个组件后,我们可以创建一个使用预处理数据组件的管道。
管道定义是一个用@dsl.pipeline
注释修饰的 Python 函数。在函数中,我们可以像使用任何其他函数一样使用组件。
为了执行管道,我们创建一个kfp.Client
对象并调用create_run_from_pipeline_func
函数,传入定义管道的函数。
如果我们执行这个脚本,然后导航到 Kubeflow 中央仪表板的 Pipelines 部分中的 Experiments 视图,我们将看到我们的管道的执行。我们还可以通过在管道的图形视图中单击组件来查看来自预处理数据组件的四个文件输出。
Kubeflow 管道用户界面。(图片由作者提供)
因此,我们可以执行我们的管道,并在 GUI 中可视化它,但是只有一个步骤的管道并不那么令人兴奋。让我们创建剩余的组件。
剩余组件
对于 train-model 组件,我们将创建一个简单的 python 脚本,它使用 Sci-kit learn 训练一个回归模型。这应该类似于预处理组件的 python 脚本。最大的区别是,这里我们使用argparse
接受训练数据的文件路径作为命令行参数。
同样,docker 文件与我们用于第一个组件的文件非常相似。我们从基本映像开始,安装必要的包,将 python 脚本复制到容器中,然后执行脚本。
另外两个组件测试模型和部署模型遵循相同的模式。事实上,它们与我们已经实现的两个组件非常相似,为了简洁起见,我不会在这里展示它们。如果你感兴趣,你可以在这个 GitHub 仓库中找到管道的所有代码:https://github.com/gnovack/kubeflow-pipelines
就像前面的预处理-数据组件一样,我们将从这三个组件中构建 Docker 映像,并将它们推送到 Docker Hub:
- 列车型号:gnovack/Boston _ pipeline _ train
- 测试模型:gnovack/Boston _ pipeline _ test
- 部署模型:gnovack/Boston _ pipeline _ deploy
完整的管道
现在是时候创建完整的机器学习管道了。
首先,我们将为训练模型、测试模型和部署模型组件创建组件定义。
train-model 组件的定义与之前的预处理数据组件的定义之间唯一的主要区别是 train-model 接受两个参数,x_train
和y_train
,这两个参数将作为命令行参数传递给容器,并将在使用argparse
模块的组件实现中解析出来。
现在定义测试模型和部署模型组件:
定义了四个管道组件后,我们现在将重温前面的boston_pipeline
函数,并一起使用我们所有的组件。
让我们来分解一下:
- 注意第 6 行的,当我们调用
preprocess_op()
函数时,我们将函数的输出存储在一个名为_preprocess_op
的变量中。为了访问预处理数据组件的输出,我们调用_preprocess_op.outputs['NAME_OF_OUTPUT']
。 - 默认情况下,当我们从一个组件访问
file_outputs
时,我们得到的是文件的内容而不是文件路径。在我们的例子中,由于这些不是纯文本文件,我们不能仅仅将文件内容作为命令行参数传递给组件 Docker 容器。为了访问文件路径,我们使用dsl.InputArgumentPath()
并传入组件输出。
现在,如果我们从管道创建一个运行,并导航到 Kubeflow central 仪表板中的管道 UI,我们应该会看到管道图中显示的所有四个组件。
Kubeflow 管道用户界面。(图片由作者提供)
结论
在本文中,我们创建了一个非常简单的机器学习管道,它加载一些数据,训练一个模型,在维持数据集上评估它,然后“部署”它。通过使用 Kubeflow 管道,我们能够将工作流中的每个步骤封装到管道组件中,每个组件都运行在自己的、隔离的 Docker 容器环境中。
这种封装促进了我们的机器学习工作流中各步骤之间的松散耦合,并为在未来的管道中重用组件提供了可能性。例如,在我们的培训组件中没有任何东西是专门针对波士顿住房数据集的。我们可以在任何时候使用 Sci-kit learn 训练回归模型时重用这个组件。
我们只是触及了 Kubeflow 管道的表面,但是希望本文能帮助您理解组件的基础,以及我们如何一起使用它们来创建和执行管道。
如果您有兴趣探索本文中使用的全部代码库,您可以在 GitHub repo 中找到它们:https://github.com/gnovack/kubeflow-pipelines
参考文献
- https://kube flow-pipelines . readthedocs . io/en/latest/index . html
- https://www . kube flow . org/docs/pipelines/SDK/build-component/
- MLOps:机器学习中的连续交付和自动化管道
感谢阅读!如有任何问题或意见,请随时联系我们。
使用 Scikit-Learn 的机器学习管道
原文:https://towardsdatascience.com/machine-learning-pipelines-with-scikit-learn-d43c32a6aa52?source=collection_archive---------3-----------------------
构建机器学习管道的分步教程
照片由昆腾·德格拉夫在 Unsplash 拍摄
概观
这篇文章将作为一步一步的指南来建立流水线,简化机器学习的工作流程。我将在本教程中使用臭名昭著的泰坦尼克号数据集。数据集是从 Kaggle 获得的。目标是预测一个给定的人是否幸存。我将实现各种分类算法,以及网格搜索和交叉验证。该数据集包含每位乘客的记录,由 10 个变量组成(见下面的数据字典)。出于本教程的目的,我将只使用train
数据集,它将被分成训练集、验证集和测试集。
(图片由作者提供)
为什么是管道?
机器学习工作流由数据准备的许多步骤组成(例如,处理缺失值、缩放/编码、特征提取)。当第一次学习这个工作流程时,我们一次执行一个步骤的数据准备。这可能会变得很耗时,因为我们需要对训练和测试数据都执行准备步骤。管道允许我们通过编译准备步骤来简化这个过程,同时减轻模型调整和监控的任务。Scikit-Learn 的 Pipeline 类提供了一种结构,用于应用一系列数据转换,然后是一个估计器(Mayo,2017)。有关更详细的概述,请查看 文档 。实现管道有很多好处:
- 便利性和封装性:我们只对数据调用一次
fit
和predict
,以适应整个估计器序列。 - 联合参数选择:我们可以对管道中所有估计器的参数进行网格搜索。
- 交叉验证:管道有助于避免数据在交叉验证过程中从测试数据泄露到训练好的模型中。这是通过确保使用相同的样本来训练变压器和预测器来实现的。
是时候看看管道的运行了!下面,我将安装并导入必要的库。然后继续加载数据集并处理缺失值。一旦数据准备好了,我将为不同的数据类型创建转换器,并创建一个列转换器来封装预处理步骤。最后,我将编写一个函数来训练一个具有交叉验证的模型,以及一个类似的函数,包括网格搜索交叉验证。
- 安装 Scikit-Learn
!pip install -U scikit-learn
- 导入必要的库
***# Standard Imports*** import pandas as pd
import seaborn as sns
import numpy as np
import matplotlib.pyplot as plt
import pickle
***# Transformers*
from sklearn.preprocessing** import LabelEncoder, OneHotEncoder, StandardScaler, MinMaxScaler
***# Modeling Evaluation*
from sklearn.model_selection** import train_test_split, cross_val_score, KFold, GridSearchCV
**from sklearn.metrics** import accuracy_score, precision_score, recall_score,f1_score, confusion_matrix, classification_report
**from IPython.display** import display, Markdown
***# Pipelines***
**from sklearn.pipeline** import Pipeline, FeatureUnion
**from sklearn.base** import BaseEstimator, TransformerMixin
**from sklearn.compose** import ColumnTransformer
***# Machine Learning***
**from sklearn.tree** import DecisionTreeClassifier
**from sklearn.ensemble** import RandomForestClassifier
**from** **sklearn.model_selection** **import** KFold
**from** **sklearn.neighbors** **import** KNeighborsClassifier
- 加载数据并查看前 5 行
**df =** pd.read_csv("titanic.csv")
df.head()
作者图片
- 检查缺失值
df.isna().sum()
在Age
列中有 891 个缺失值中的 177 个。出于本管道教程的目的,我将继续用平均年龄填充缺失的Age
值。在Cabin
列中有 891 个缺失值中的 687 个。我正在删除这个特性,因为大约 77%的值丢失了。Embarked
特性只缺少 2 个值,所以我们可以用最常见的值来填充它们。Name
和Ticket
功能对每个乘客都有独特的价值,预测分类不需要这些功能,因此也将被删除。
- 下降特性
df.drop(["Name", "Ticket", "Cabin"], axis=1, inplace=True)
- 填充 na 值为
**Embarked**
特征中出现频率最高的值,**S**
。
**df.Embarked =** df.Embarked.fillna(value='S')
既然我们已经处理了数据集中的缺失值,我们可以继续定义连续变量和分类变量。
- 为数据帧中的列定义变量,以执行训练测试分割。
**columns =** ['Pclass', 'Sex', 'SibSp', 'Parch', 'Fare', 'Embarked']**numerical_columns =** ['Age', 'Fare']**categorical_columns =** ["Pclass", "Sex",
"SibSp", "Parch", "Embarked"]
接下来,我将创建两个函数。第一个函数cross_validate
将接受一个分类器和 cv(交叉验证器),将训练数据分成训练集和测试集,使分类器适合训练,并对其进行预测。然后,该函数将对保留验证集进行预测,并返回来自训练集和测试集的分数。
管道允许我们在一个步骤中执行预处理(例如标准化、编码、模型拟合)。一个管道可以接受任意数量的预处理步骤,每个步骤都有.fit()
和.transform()
方法。下面,我正在创建两个变压器,一个标准的定标器和一个热编码器。两个不同的转换器将用于不同的数据类型。
**#Creating** **ss** **transformer to scale the continuous numerical data with** **StandardScaler()****ss =** Pipeline(steps=[('ss', StandardScaler())])--------------------------------------------------------------------**#Creating ohe transformer to encode the categorical data with** **OneHotEncoder()****ohe =** Pipeline(steps=[('ohe', OneHotEncoder(drop='first'))])--------------------------------------------------------------------**#Creating preprocess column transformer to combine the ss and ohe pipelines****preprocess =** ColumnTransformer(
transformers=[
('cont', ss, numerical),
('cat', ohe, categorical)
])
- 创建评估函数以绘制混淆矩阵并返回准确度、精确度、召回率和 f1 分数
def evaluation(y, y_hat, title = 'Confusion Matrix'):
cm = confusion_matrix(y, y_hat)
precision = precision_score(y, y_hat)
recall = recall_score(y, y_hat)
accuracy = accuracy_score(y,y_hat)
f1 = f1_score(y,y_hat)
print('Recall: ', recall)
print('Accuracy: ', accuracy)
print('Precision: ', precision)
print('F1: ', f1)
sns.heatmap(cm, cmap= 'PuBu', annot=True, fmt='g', annot_kws= {'size':20})
plt.xlabel('predicted', fontsize=18)
plt.ylabel('actual', fontsize=18)
plt.title(title, fontsize=18)
plt.show();
- 对数据执行 train _ test _ split
**X =** df.drop(['Survived'], axis=1)
**y =** df.Survived
**y =** LabelEncoder().fit_transform(y)
**X_train, X_test, y_train, y_test =** train_test_split(X, y, random_state=42)
创建cross_validate
功能
- 定义带有预处理和分类器管道的完整管道
- 遍历交叉验证器中的每个折叠(默认为 5)
- 将分类器安装在训练装置上,
train_ind
(防止测试装置的数据泄漏) - 根据训练集进行预测
- 对验证集进行预测
- 打印一份评估报告,其中包含混淆矩阵以及训练集和验证集的平均准确度分数
def cross_validate(classifier, cv):
pipeline = Pipeline(steps=[
('preprocess', preprocess),
('classifier', classifier)
])
train_acc = []
test_acc = []
for train_ind, val_ind in cv.split(X_train, y_train):
X_t, y_t = X_train.iloc[train_ind], y_train[train_ind]
pipeline.fit(X_t, y_t)
y_hat_t = pipeline.predict(X_t) train_acc.append(accuracy_score(y_t, y_hat_t)) X_val, y_val = X_train.iloc[val_ind], y_train[val_ind]
y_hat_val = pipeline.predict(X_val) test_acc.append(accuracy_score(y_val, y_hat_val))
print(evaluation(y_val, y_hat_val))
print('Training Accuracy: {}'.format(np.mean(train_acc)))
print('\n')
print('Validation Accuracy: {}'.format(np.mean(test_acc)))
print('\n')
在函数中,我使用交叉验证器来分割训练数据,以便得到一个支持测试集(X_test,y_test)。现在我们可以通过输入想要的分类器和交叉验证器来使用上面的函数。
cross_validate(DecisionTreeClassifier(), KFold())
输出:
作者图片
- 用 K 最近邻分类器
cross_validate(KNeighborsClassifier(), KFold())
输出:
作者图片
网格搜索
假设我们想在管道中找到模型的最佳参数,我们可以创建一个网格搜索管道。要复习网格搜索,请查看 文档 。我们可以创建一个类似上面的函数来进行交叉验证,但是要稍微修改一下来执行网格搜索。该函数将接收所需的分类器、参数网格和交叉验证器。然后,将通过网格搜索完成与cross_validate
功能相同的过程。
def grid_search(classifier, param_grid, cv):
search = GridSearchCV(Pipeline(steps=[
('preprocess', preprocess),
('classifier', classifier)
]), param_grid, cv=cv)
train_acc = []
test_acc = []
for train_ind, val_ind in cv.split(X_train, y_train):
X_t, y_t = X_train.iloc[train_ind], y_train[train_ind]
search.fit(X_t, y_t)
y_hat_t = search.predict(X_t) train_acc.append(accuracy_score(y_t, y_hat_t)) X_val, y_val = X_train.iloc[val_ind], y_train[val_ind]
y_hat_val = search.predict(X_val) test_acc.append(accuracy_score(y_val, y_hat_val))
print(evaluation(y_val, y_hat_val))
print('Training Accuracy: {}'.format(np.mean(train_acc)))
print('\n')
print('Validation Accuracy: {}'.format(np.mean(test_acc)))
print('\n')
print('Grid Search Best Params:')
print('\n')
print(search.best_params_)
- GridSearchCV 与随机森林
为管道中的模型创建参数网格时,需要将模型名称附加到每个参数上。在下面的代码块中,我添加了'classifier__'
来匹配管道中模型的名称(在管道中命名为模型‘classifier’)。
**#Creating parameter grid for Random Forest** rand_forest_parms = {'classifier__n_estimators': [100, 300, 500],
'classifier__max_depth':[6, 25, 50, 70],
'classifier__min_samples_split': [2, 5, 10],
'classifier__min_samples_leaf': [1, 2, 10]}**#Calling the grid_search function using the parameters above** grid_search(RandomForestClassifier(), rand_forest_parms)
输出:
在模型训练期间,重要的是执行特征选择,以确保模型具有最强的预测能力,并确保我们的模型不会太复杂。我们可以使用eli5
库来检查管道中分类器的特征重要性。为此,我们需要创建一个包含数字特征列和编码列的列表。然后,用网格搜索管道的best_estimator_
和它的named_steps
调用eli5.explain_weights_df
。当然,我们可以将它添加到我们的网格搜索函数中,通过修改该函数来接受一个将打印出这些特性的布尔值,从而返回前十个特性的重要性。
具有特征重要性的网格搜索功能
- 在下面的函数中包含特性重要性的修改以粗体显示。
def grid_search(classifier, param_grid, cv, ***print_feat=False***):
cv = cv
search = GridSearchCV(Pipeline(steps=[
('preprocess', preprocess),
('classifier', classifier)
]), param_grid, cv=cv)
train_acc = []
test_acc = []
for train_ind, val_ind in cv.split(X_train, y_train):
X_t, y_t = X_train.iloc[train_ind], y_train[train_ind]
search.fit(X_t, y_t)
y_hat_t = search.predict(X_t) train_acc.append(accuracy_score(y_t, y_hat_t)) X_val, y_val = X_train.iloc[val_ind], y_train[val_ind]
y_hat_val = search.predict(X_val) test_acc.append(accuracy_score(y_val, y_hat_val))
***if print_feat:
ohe_cols = list(search.best_estimator_.named_steps['preprocess'].named_transformers_['cat'].named_steps['ohe'].get_feature_names(
input_features=categorical))
num_feats = list(numerical)
num_feats.extend(ohe_cols)
feat_imp = eli5.explain_weights_df(search.best_estimator_.named_steps['classifier'], top=10, feature_names=num_feats)
print(feat_imp)***
print('\n')
print(evaluation(y_val, y_hat_val))
print('Training Accuracy: {}'.format(np.mean(train_acc)))
print('\n')
print('Validation Accuracy: {}'.format(np.mean(test_acc)))
print('\n')
print('Grid Search Best Params:')
print('\n')
print(search.best_params_)
- 执行网格搜索并返回前十个重要特征及其权重
grid_search(RandomForestClassifier(), rand_forest_parms, KFold(), print_feat=True)
输出:
假设网格搜索管道中的随机森林分类器表现最好。下一步将是观察经过训练的模型在坚持测试数据上的表现。我们需要做的就是用 GridSearchCV 创建一个最终的管道,并使其适合整个 X_train 和 y_train。然后,在 X_test 上预测。
- 将最终管线拟合到
**X_train**
和**y_train**
,并预测到**X_test**
final_pipeline = GridSearchCV(Pipeline(steps=[
('preprocess', preprocess),
('classifier', RandomForestClassifier())
]), rand_forest_parms, cv=KFold())**#Fit and predict on train data**final_pipeline.fit(X_train, y_train)
train_pred = final_pipeline.best_estimator_.predict(X_train)
print('Evaluation on training data \n')
print(evaluation(y_train, train_pred))
print('\n')**#Predict on test data**test_pred = final_pipeline.best_estimator_.predict(X_test)
print('Evaluation on testing data \n')
print(evaluation(y_test, test_pred))
输出:
作者图片
结论
管道封装了我们的预处理步骤和模型,使机器学习工作流程变得更加容易。如果需要,我们可以在管道中拟合模型之前应用多个预处理步骤。对我来说,主要的好处是能够回到一个项目,并遵循我用管道设置的工作流程。在我了解管道之前,这个过程需要几个小时。我希望本教程能够成为学习管道工作流的有用资源。
资源
- 使用 Scikit-learn 管道管理机器学习工作流第 1 部分:简介。(未注明)。检索自https://www . kdnugges . com/2017/12/managing-machine-learning-workflows-sci kit-learn-pipelines-part-1 . html
- 柯恩,S. (2019 年 08 月 09 日)。构建机器学习管道。检索自https://towards data science . com/architecting-a-machine-learning-pipeline-a 847 f 094 D1 c 7
- sk learn . pipeline . pipeline .(n . d .)。检索自https://scikit-learn . org/stable/modules/generated/sk learn . pipeline . pipeline . html
- M,S. (2019 年 12 月 13 日)。机器学习中的流水线是什么?如何创建一个?检索自https://medium . com/analytics-vid hya/what-A-pipeline-in-machine-learning-how-to-create-one-BDA 91d 0 ce ACA #:~:text = A机器学习管道用于帮助机器学习工作流程自动化。&text =机器学习(ML)流水线组成,并实现一个成功的算法。
- 泰坦尼克号:机器从灾难中学习。(未注明)。检索自https://www.kaggle.com/c/titanic/data
- 3.2。调整估计器的超参数。(未注明)。检索自https://scikit-learn.org/stable/modules/grid_search.html
- 概述。(未注明)。检索自【https://eli5.readthedocs.io/en/latest/overview.html】
机器学习陷阱
原文:https://towardsdatascience.com/machine-learning-pitfalls-e54ac3edc25?source=collection_archive---------23-----------------------
你的 ML 项目有多强就有多弱
Jelleke Vanooteghem 在 Unsplash 上拍摄的照片。
机器学习(ML)系统是复杂的,系统越复杂,故障模式就越多。知道什么会出错对于构建健壮的 ML 系统是至关重要的。我们将一起使用具体的例子来探索在 5 个不同的成熟度级别上可能出现的陷阱。
0 级—问题定义【T11 级—你的第一个 ML 模型
2 级—泛化
3 级—系统级性能
4 级— 性能不是 o 输出结果
这篇文章的最后一部分将讨论如何避免这些陷阱。专注于避免陷阱比从你的模型中榨取每一点准确性更好。
“值得注意的是,像我们这样的人通过努力保持不愚蠢,而不是努力变得非常聪明,获得了多少长期优势。”
—查理·芒格
0 级问题定义
现实世界的问题很少表现为易处理的数据科学问题。因此,对于任何 ML 项目来说,第一步都是制定问题,换句话说,就是将一个高层次的目标转化为一个定义良好的数据科学问题。
在这个层次上最大的威胁是提出一个问题定义,当它被解决时,实际上对任何人都没有帮助。这篇文章中有两个例子:
1)大多数将深度学习应用于超声心动图分析的研究试图超越医生预测疾病的能力。但是,预测正常的心脏功能实际上会通过识别不需要他们专业知识的患者来节省心脏病专家的更多时间。
2)许多将机器学习应用于葡萄栽培的研究旨在优化葡萄产量,但酿酒师“想要合适的糖和酸水平,而不仅仅是大量大而含水的浆果”。
第一级你的第一个 ML 模型
这一关是让一个 ML 模型在你的笔记本电脑上的测试集上工作。这不是一件容易的事情,但是大部分的内容已经集中在这一点上,因此我将只提到一个陷阱:
陷阱 1.1 假设更多的数据可以解决所有的问题
不相关的要素或低质量的数据会降低您可以达到的上限性能,这无法通过更多的数据来解决。
由于模型容量低而导致的拟合不足是另一个更多数据没有帮助的情况。
二级概括
这就是有趣的地方。假设您有一个模型,它在您的测试集上运行得非常好,但是在使用外部数据集进行测试时,它的性能会急剧下降。以下陷阱或许可以解释其中的原因:
陷阱 2.1 虚假关联
如果数据集包含与标注相关的信号(即噪声)之外的任何内容,您的模型将学习利用它进行预测。
在下面的例子中,神经网络将图像分类为“马”在看文本,而不是马。一旦文字被删除,图像就不会被归类为“马”。
Lapuschkin 等人的图片来自揭露聪明的 Hans 预测器并评估机器真正学习什么。
陷阱 2.2 非代表性数据集
你用来训练你的 ML 模型的样本应该代表你计划使用它的人群。
假设您正在基于光散射数据构建一个粒子大小预测器,并且您只使用球形粒子对其进行了训练。如果在实践中人们也将它用于非球形粒子,模型性能将显著下降。
缺陷 2.3 测试和用例之间的数据不匹配
ImageNet 是一个包含数百万张图片和数千个类的数据库。年复一年,研究人员在 ImageNet challenge 上开发了性能更好的模型,这导致一些人说“视觉是一个已解决的问题”。
然而,当在 ObjectNet 上测试时,这些算法的性能下降了大约 40%。原因是 ObjectNet 有适当的控制,对象在所有可能的旋转背景和视点。这是 ImageNet 所缺乏的。看一下样本数据集以了解差异。
隐患 2.4 列车测试泄漏
假设你正在从断层图像中检测某种疾病。您可能会有多个属于同一个患者的图像。如果您将所有图像随机分为训练集和测试集,来自同一患者的一些图像可能会进入训练集,而其他图像可能会进入测试集。在这种情况下,在训练集上训练的模型在测试集上可能具有高性能,因为您的模型识别患者,而不是疾病。
陷阱 2.5 随时间改变数据生成分布
数据生成过程会随时间而变化。10 年前的手机摄像头和今天大不一样。因此,如果一个模型是使用 10 年前的手机图像数据集开发的,但在今天测试,性能可能会有所不同。
大多数统计和机器学习算法都假设数据是从平稳分布中抽取的随机样本。不幸的是,今天大多数可用于挖掘的大型数据库违背了这一假设。它们是在几个月或几年内收集的,在此期间,产生它们的基本过程发生了变化,有时是彻底的变化。来源。
3 级系统级性能
我们开发机器学习模型,但它们通常作为另一个系统的一部分投入使用。因此,仅仅验证您的模型是不够的,您还应该验证您的系统。这一级别的陷阱是由于没有系统方法而产生的。
缺陷 3.1 错误输入
如果输入被破坏,完美的模型将产生错误的预测。导致两架 737 Max 飞机相隔五个月坠毁的防失速软件(MCAS)依靠单一传感器进行输入。一个传感器的故障导致 346 人死亡。
它没有冗余:它一次只从一个 AoA 传感器获取输入。这使得 MCAS 完全无法应对传感器故障。如果原始来源发生故障,它无法根据第二个传感器对其数据进行“健全检查”或切换到备份。它只是相信给它的任何数据,,即使那些数据是坏的,这就是发生在狮航 610 航班和埃塞俄比亚航空 302 航班上的事情。来源。
缺陷 3.2 没有为失败做准备
继续波音公司的例子,MCAS 系统并不是直接覆盖,飞行员也没有接受过适当的培训。
这个系统的存在,潜伏在 Max 的软件套件中的某个地方,是足够令人震惊的。更可怕的是,波音公司只向航空公司和飞行员提供了最低限度的信息。公告没有给出系统的名称,也没有解释它在正常操作中的作用。它只是说,有时它会出现故障,这可能会使你的飞机坠毁。
“这有点像,'好吧,飞行员,祝你好运,想出办法,【T13]'”Einsetler 说。来源。
缺陷 3.3 对系统其他部分的不利影响
最近,特斯拉 autopilot 在驾驶员专注度方面获得了一个低分:
“不幸的是,有些驾车者认为他们今天可以购买一辆无人驾驶汽车。这是一种危险的误解,认为太多的控制权交给了没有准备好应对所有情况的车辆,”Thatcham Research 的欧洲 NCAP 董事会成员兼研究主管马修·艾弗里说。来源
这种错误的安全感可能会降低驾驶员的表现,导致撞车:
[## 一家联邦机构表示,对特斯拉自动驾驶仪的过度依赖导致了一起致命事故
揭示和解释我们的数字世界是如何改变的,以及如何改变我们。国家运输安全委员会…
www.vox.com](https://www.vox.com/2017/9/12/16294510/fatal-tesla-crash-self-driving-elon-musk-autopilot)
四级表现不欧 utcome
表现不是结果。采用在问题定义期间设定的指标并不能保证达到预期的结果。
隐患 4.1 隐藏分层
一个具有高整体性能的癌症检测模型可能会持续遗漏一种罕见的癌症亚型,这被称为隐藏分层问题。整体绩效隐藏了小组绩效的可变性。
陷阱 4.2 人口统计偏见
作用于人类数据的机器学习模型容易受到人口统计学偏见的影响。亚马逊意识到他们的人工智能招聘工具对女性有偏见,即使性别没有在简历上明确标出。
[## 据报道,亚马逊废除了歧视女性的内部人工智能招聘工具
即使对于亚马逊这样在人工智能方面有丰富经验的公司,机器学习的偏见也可能是一个问题。根据…
www.theverge.com](https://www.theverge.com/2018/10/10/17958784/ai-recruiting-tool-bias-amazon-report)
陷阱 4.3 违反法规
一个技术上完美的模型,如果违反了规定,可能就没用了。
[## 在加利福尼亚州,在设定汽车保险费率时不再考虑性别(2019 年发布)
加州本月加入了六个州的行列,禁止在评估风险时使用个人性别…
www.nytimes.com](https://www.nytimes.com/2019/01/18/your-money/car-insurance-gender-california.html)
但最重要的是:你想这样做吗?
即使你建立了一个技术上完美的 ML 系统并产生了预期的商业结果,你对它的存在感到高兴吗?
这是网飞(2015) 的一篇很棒的论文,解释了他们的推荐系统以及商业成果。他们估计该系统每年为他们节省 10 亿美元。
但是你真的想造一个和睡眠竞争的让人上瘾的数码产品吗?你可能会,也可能不会,关键是要在构建它之前考虑它,而不是在事后考虑。
[## 网飞首席执行官雷德·哈斯汀斯:睡眠是我们的竞争
网飞已经成为了疯狂观看的代名词——一整季疯狂观看陌生事物的行为
www.fastcompany.com](https://www.fastcompany.com/40491939/netflix-ceo-reed-hastings-sleep-is-our-competition)
以 YOLO 物体检测算法闻名的 Redmon 在今年早些时候发表了以下声明:
解决方案?
以下是我在 Ipsumio 日常工作中使用的一些技巧。
提示 0:如果没有必要,不要使用 ML
我多次被要求用 ML 解决不需要 ML 的问题。如果没有必要,你可以通过不使用机器学习来避免上述所有挑战。
同样,如果一个有 3 个参数的 ML 模型解决了问题,不要使用有数千个参数的神经网络。
技巧 1:迭代地构建项目
而不是完善项目阶段,线性推进,反反复复。尽快部署概念证明,然后重新开始。
技巧 2:让领域专家参与进来
这是必须的。几乎项目的所有阶段都需要领域知识。如果不是:
技巧 3:让软件专家参与进来
将一个 ML 模型转变成一个系统并不简单。你的模型代码只是整个系统的一小部分。
ML 代码只是现实生产 ML 系统的一小部分。来自机器学习速成班。
技巧 4:跨专业交流
我参与了一个关于识别从皮肤损伤处收集的某些细胞的研究项目(赞克试验)。作为数据科学家,我阅读了几十篇关于赞克测试的研究论文和两本书。除此之外,我给了项目中的皮肤科医生一个关于 ML 的短期培训。这有助于我们在项目的所有阶段相互理解,从问题定义到结果解释。
[## TzanckNet:一个卷积神经网络,用于识别细胞学中的细胞…
赞克涂片试验是一种低成本、快速和可靠的工具,可用于许多疾病的诊断
www.nature.com](https://www.nature.com/articles/s41598-020-75546-z)
技巧 5:考虑可解释性和可解释性
对于某些应用程序,高性能本身就足够了,但是当风险很高时,可解释性和可解释性就变得不可或缺了。
在的播客中,Arnaud Hubaux 解释了他们是如何在 ASML 将物理学和 ML 结合起来的。他提到他们的客户看重因果关系多于相关性。在没有解释的情况下,他们不关心准确性的提高。因此,他们将物理定律用于特征工程和解释输出。
医疗保健是黑盒解决方案产生问题的另一个领域。例如,这条推文围绕这个问题引发了一场激烈的辩论:
技巧 6:错误分析
一个简单但有效的提示。看看你所有的错误,看看有没有系统性的错误。假设您正在开发一个汽车分类器,并意识到所有的假阴性都属于被物体遮挡的汽车。您可以注明“模型在遮挡情况下无法工作”,也可以增加训练数据中被遮挡的汽车图像,并尝试解决该问题。
技巧 7:用外部数据集测试模型
如果您使用来自一家医院的数据集开发模型,请考虑使用外部数据集按以下顺序测试您的模型:来自同一家医院的预期数据,来自同一医疗保健系统中不同医院的数据,来自不同医疗保健系统中不同医院的数据…
技巧 8:测试系统
仅仅测试模型是不够的,要把它作为一个系统来测试,看看它将如何与系统的其他部分及其环境发生反应。
技巧 9:检查子组性能
在标记数据的过程中,也让领域专家定义和注释子集。然后在这些子集中分析您的模型性能。
技巧 10:仔细创建数据集
查明
- 你要找的信号在数据里面
- 它是人口的代表
- 如果你正在生成数据集,模拟现实,而不是创建一个完美的数据集。(例如,如果实际使用低分辨率显微镜,不要用昂贵的显微镜创建数据集)。
技巧 11:利用 MLOps
随着我们开始看到更多的生产 ML,部署和维护这些系统吸引了更多的注意力。在您的工作流程中使用 MLOps 原则。
[## 机器学习系统中隐藏的技术债务
机器学习为快速构建有用的复杂预测系统提供了一个非常强大的工具包。这个…
dl.acm.org](https://dl.acm.org/doi/10.5555/2969442.2969519)
关键要点:
- 成功的机器学习项目需要的不仅仅是回溯测试集上的高性能模型。
- 因此,不要关注模型性能的增量收益,而要关注预防、检测和修复所有成熟度级别的缺陷。
“我只想知道我会死在哪里,所以我永远不会去那里。”—查理·芒格
机器学习过程
原文:https://towardsdatascience.com/machine-learning-process-7beab5c4f31b?source=collection_archive---------27-----------------------
艾萨克·史密斯在 Unsplash 上拍摄的照片
尽管有许多机器学习算法,每一个都有不同的方法,但有一个通用的程序可以用来解决任何机器学习问题。在本文中,我们将了解所有这些是如何发生的。
如果你想在此之前获得机器学习的一般介绍,请查看这篇文章:
[## 那么什么是机器学习呢?
我相信到现在为止,你一定听说过这个术语,如果不出所料的话,只要看看…的演讲就知道了
thedatascienceportal.com](https://thedatascienceportal.com/so-what-is-machine-learning/)
既然我们理解了什么是机器学习,那么现在让我们来学习如何应用机器学习来解决任何问题。
这是用于将机器学习应用于任何问题的基本过程
数据采集
解决任何机器学习问题的第一步是收集相关数据。它可能来自不同的来源,并采用不同的格式,如纯文本、分类或数字。数据收集很重要,因为这一步的结果直接影响我们问题的性质。
在大多数情况下,数据并不是放在现成的银盘上交给我们的,也就是说,通常情况下,我们认为相关的数据可能不会马上可用。我们很有可能必须进行某种练习或受控实验来收集我们可以使用的数据。我们还必须记住,我们正在收集的数据来自合法的程序,因此所有相关方都非常清楚正在收集的内容。
为了本文的目的,让我们假设我们已经收集了关于汽车的数据,并且我们正在尝试在机器学习的帮助下预测一辆新车的价格。
数据预处理
既然我们已经收集了与手头问题相关的数据,我们必须让它进入同质状态。我们的数据的当前形式可以包括各种类型的数据集,可能是由一千行和多列汽车数据组成的表格,或者可能是不同角度的汽车照片。保持事情简单并处理一种特定类型的数据总是明智的,也就是说,如果我们感觉有点太冒险,我们应该在开始处理我们的算法之前决定我们是要处理图像数据、文本数据还是视频数据!
数据类型。作者照片。
像每个计算机程序一样,机器学习算法也只理解 1 和 0。因此,为了运行任何这样的算法,我们必须首先将数据转换成机器可读的格式。如果我们把我们的照片放在幻灯片上,它根本不会理解!我们可以使用任何类型的数据——数字、图像、视频或文本——但我们必须对其进行配置,使其能够被机器理解。我们通过对数据进行编码来确保这一点——在这个过程中,我们将所有类型的数据用数字表示出来。
有关数据预处理和所有相关步骤的简单易懂的介绍,请查阅本文:
[## 数据预处理
标签:当我们谈论数据时,我们通常会想到一些包含大量行和列的大型数据集。而那个…
thedatascienceportal.com](https://thedatascienceportal.com/data-preprocessing/)
训练和测试数据
在我们开始构建机器学习模型之前,我们必须首先确定我们的特征,并决定我们的目标。特性是数据的属性,告诉我们数据中不同的实体。例如,我们可能有一个关于汽车的庞大数据集,使用机器学习来预测新车的价格。由于这些汽车是实体,在这种情况下,特征可能是发动机功率、里程、最高速度、颜色、座位容量、汽车类型等。等等..在这种情况下,目标或目标变量将是汽车的价格。
当我们处理任何机器学习问题时,我们总是将我们拥有的数据集分成训练集和测试集,通常分别是(70/30)或(80/20)分割。训练集,顾名思义,是用来训练模型的。当我们“训练”模型时,它试图理解数据集的所有特征如何形成目标变量——在监督学习的情况下,或者所有特征之间的关系和相关性——在非监督学习的情况下。在此之后,测试集将用于找出模型对数据的理解程度。
机器学习算法选择
在转换数据,使其变得清晰和可行之后,我们会对解决问题的方法有更好的想法,并尝试实现它。这是因为实际上是数据决定了我们能使用什么,不能使用什么。
比如说我们想造一个聊天机器人。聊天机器人将按照用户的询问进行回答。因此,我们可以说,任何对话的第一步都将是聊天机器人试图识别用户的意图,这是我们的第一个机器学习问题——意图分类。
这个问题要求我们使用一种特殊类型的数据——基于文本的数据。我们选择的机器学习算法一定是一种分类算法,即它根据已经看到的数据,将新输入的数据分类到某个标签类。当然,在这一步之前,来自用户的文本将被编码并经过所有必要的数据预处理步骤,然后将被输入到机器学习算法中。尽管我们必须小心选择我们的机器学习算法,但在选择最终的算法之前,探索所有可用的选项并使用各种合适的机器学习算法是很好的——无论如何,这都被认为是最佳实践。
价值函数
简而言之,成本函数是一个数学函数,它给出成本的度量;正如你可能已经听说的那样,我们做出的每一个决定都是有代价的。
“成本函数或损失函数是将一个事件或一个或多个变量的值映射到一个实数上的函数,该实数直观地表示与该事件相关的一些“成本”——百科
该功能用于量化任何程序中每一步对应的惩罚。就优化问题而言,我们必须致力于最小化该成本值。
让我们来看一个例子——
假设你正在爬下一个悬崖。在任何时候,你都有几条路可以走,但你会:
- 从该点寻找最佳路径
- 拒绝所有让你超越自我的道路
如果我们将上涨与惩罚或成本联系起来,那么如果上涨,我们将增加总成本(就时间和精力而言)。因此,如果我们要设计一个数学函数来量化这个成本指标,我们可以潜在地将时间和精力作为因素。
另一个例子-
假设你开车从 A 地到 B 地,同样,我们有多条路径到达 B 地,但是我们:
- 寻找最短的路径
- 拒绝所有带我们去其他地方的路(很明显!)
如果我们把这种情况与成本联系起来,如果我们忽略了上面提到的两点,我们将会有很高的成本。在这里,我们可以将时间和油钱作为组成成本函数的因素,并判断此后采取的路径。
照片由维达尔·诺德里-马西森在 Unsplash 拍摄
机器学习中的代价函数
任何机器学习算法都必须达到一个最优状态才能正常运行。成本函数帮助我们确定我们的模型是否处于最佳状态。通过不断比较模型假设值和训练集中的原始值,模型找出最佳状态。哇…退后!什么!?
别担心,我们会仔细研究所有概念!
假设功能
任何机器学习模型的背后本质上都是一个数学函数,它解释了数据中各种特征的作用,以形成目标变量或形成不同特征之间的相关性。
假设函数。作者照片。
如前所述,在训练期间,机器学习模型试图理解训练数据特征的值的不同组合如何形成相应的目标变量。为了更好地理解,让我们以一个培训记录为例,培训本质上意味着获取该记录的所有特征,并以某种方式将其映射到该培训记录的目标值。一个很好的例子就是我们之前讨论的汽车数据集。符号方面,特征取为 X,目标变量取为 y。
在此过程中,训练数据被输入到学习算法中,该算法是根据我们试图解决的问题选择的。这可能是一个分类问题,一个回归问题,或者完全是别的什么问题。输出这个假设函数是这个学习算法的工作。
假设函数。来源: CS229 吴恩达讲稿
对于一个两变量的问题,这可能是我们的假设函数。所有θ值都是参数或权重,选择这些参数或权重是为了使我们获得最接近每条记录的相应目标值的估计值。
然后,假设函数从每个训练记录中获取特征,并尝试估计相应的目标值。这个函数可以是简单的线性函数,也可以是复杂的函数,这取决于数据和所用的算法类型。并且因为它是一个估计函数,所以输出值不期望与目标值完全相等,至少在第一次尝试中不期望。
让我们再次使用汽车数据集,如果我们在这个数据集上使用一个学习算法,并尝试使用这些功能来训练它,我们将获得数据集中每辆汽车的价格估计值。由于这是一个训练数据集,我们已经将每辆车的价格作为目标变量。
假设趋势线的估计值用蓝色切割接近目标值用红色。作者照片。
成本函数
这就是成本函数发挥作用的地方。我们希望训练数据中的估计值和实际目标值之间的差异尽可能低,只有这样,我们才能说我们的模型是一个强模型,这意味着它将给出正确的目标值,或者至少返回一个非常非常接近特定训练记录的目标值的值。
所以,这就变成了一个最小化的问题。区别就是所谓的成本,而最小化函数就是所谓的成本函数。有几种方法可以达到极小的状态。我们可以简单地最小化整个训练集上的估计值和目标值之间的差异,或者我们可以采用平方差,或者其他一些变化来实现相同的事情。最广为接受且相当合理的成本函数之一是这样一个函数,如果你正在研究机器学习算法,你会很容易发现它:
成本函数。来源: CS229 吴恩达讲稿
这个函数适用于大多数回归问题。是的,我知道,我知道我说过我会保持简单,不会用奇怪的方程式吓到你。别担心,如果你这么正式,我们不会用公式或公式填满一块巨大的黑板。我给你简单解释一下,把一切都说得清清楚楚。
J(θ) —成本函数符号
m —训练记录数
hθ —假设函数
x(ᶦ)- iᵗʰ训练数据记录
hθ(x(ᶦ)——iᵗʰ训练记录的假设函数值
y(ᶦ)- iᵗʰ目标值
- 正如我之前提到的,我们将成本定义为假设函数值和目标值之间的差值
- 我们必须最终将我们从每个训练记录中得到的所有平方差相加,以得到整个训练数据的总成本
- 我们对每种情况下的差值进行平方,这有两个显著的优点
- 假设函数的估计值和目标值之间的差异可能是负的,对其求平方消除了我们降低总成本值的可能性,同时对我们从每个训练记录中获得的差异求和,仅仅因为其中一些是负的。
|请注意,我们也可以采用绝对值,但这导致了一个问题——绝对值函数比平方函数更难进行数学分析——如果您需要进一步的解释,请在评论中告诉我——基本上,绝对值函数在所有点上都是不可微的,这是找到成本函数处于最小值的点所必需的| - 平方也更加强调较大的差异,因为这些差异的影响也是平方的。因此,这些较大差异的贡献增加并突出。
- 通过在θ值上对函数求微分来执行最小化将移除公式中存在的 1/2
机器学习模型
如上面的假设趋势线图所示,最小化成本函数的主要目标是获得一条覆盖大部分目标值的直线趋势线,或者至少尽可能接近这些点。这就是为什么我们计算差异,并编写一个成本函数来减少它们。
而且这不是一次性的过程,更多的是一个迭代的过程,在这个过程中我们为假设函数选择我们的参数,计算估计值,然后用代价函数找出代价。之后,我们最小化这个成本,并再次执行整个活动。通过这种方式,我们重新进行整个计算,以达到我们认为具有最佳功能的点。我们可以随时检查当前结果的状态,只需对照目标值绘制函数。
然而,这整个迭代过程是当今所有优化算法的核心,因此您不必重复执行这一活动。最流行的一种,你可能听说过,是梯度下降。
[## 梯度下降:机器学习最流行的算法之一介绍
梯度下降是迄今为止在机器学习和深度学习中使用的最流行的优化策略
builtin.com](https://builtin.com/data-science/gradient-descent)
当我们确实有一个假设函数,它的估计值最接近目标值时,我们可以采用这个函数,并声称它是以尽可能好的方式拟合数据的函数。这就是我们的模型!
在这篇文章中,我想写的是解决任何机器学习问题和建立机器学习模型时遵循的一般过程。这更多的是一个理论上的解释,但我有更多的技术指南。
我希望你喜欢这篇文章。如果你对内容有任何疑问,请在评论中告诉我!
感谢阅读!
原载于 2020 年 8 月 7 日【https://thedatascienceportal.com】。更多此类内容请访问数据科学门户网站。
* [## 数据科学门户
大家好,欢迎来到数据科学门户。这个空间致力于学习和理解所有令人兴奋的…
thedatascienceportal.com](https://thedatascienceportal.com/)*
机器学习项目管理—决策者指南— 2d3d.ai
原文:https://towardsdatascience.com/machine-learning-project-management-a-decision-makers-guide-2d3d-ai-6fbd59504bb1?source=collection_archive---------51-----------------------
我们为许多不同的客户从事许多机器学习(ML)项目,并与其他同行和 ML 专家讨论 ML 项目管理的性质,我们认识到,有时,对在其业务中实施 ML 感兴趣的决策者的期望与实际可以做什么、在什么时间范围以及可能需要多少努力和成本之间存在差距。因此,我们决定为经理、首席执行官、产品副总裁、业务分析师、初创公司创始人以及一般来说任何考虑雇佣内部或外部人员帮助开发 ML 算法来解决问题的人编写本指南。
在本指南中,您将学习:
- 在你的公司开始一个机器学习项目时,你会期待什么?
- 你应该警惕什么?
- 使用机器学习的机会在哪里?
- 你的团队需要做哪些努力才能成功?
- 一个机器学习项目要花你多少钱?
- 如何认可好的 ML 工程师?
我们需要的一些定义
机器学习的形式-目前的行业趋势定义了几种不同形式的机器学习:
- 深度学习,或称神经网络——一种计算机被编程为以类似于生物大脑中神经元细胞的方式运行的形式。有一个由计算机编程的神经元组成的网络,这些神经元相互连接,形成一个图形,网络的一端接收输入,另一端发出输出
- 统计分析——这些是老派的技术,例如,回归或方差分析。今天,在行业中,他们通常被认为是 ML 的一部分。
- 机器学习多次涉及更复杂的统计分析方法,如 SVM、决策树、聚类算法等方法。要理解本指南的其余部分,您不需要知道这些特定的关键字😊
特征—样本的单个数据点,或者说,数据样本的特定特征。示例:
- 物体的大小——宽度以米计,高度以厘米计,等等..
- 对一个物体的分类测量——男性\女性、汽车\公共汽车\自行车\卡车等..
- 价格,例如以美元计算的销售价格。
- 一个像素的颜色值(0,0,0)-具有 3 个特征的 RGB
- 1 个时间点的信号测量—声音信号的幅度(1db)等..
- 机器学习的形式-目前的行业趋势定义了几种不同形式的机器学习:
- 特征—样本的单个数据点,或者说,数据样本的特定特征。示例:
技术考虑
TL/DR 版本
- 经验法则——如果一个人在看数据时不能识别一个模式,那么 ML 可能也不能
- 两种类型的算法—需要培训或预培训
- 非监督或异常检测算法很少工作,除非你有非常干净的数据
- 另一方面,标记组的组分离有简单的实现
- 训练数据越多越好,最小数据量随项目要求和实现的算法而变化
- 数据格式化、检查和转换大约占工作的 70%
- 深度学习不会解决你的问题,除非你做视觉\信号处理
- 黑仔特征比算法更重要
经验法则——如果一个人在看数据时不能识别一个模式,那么 ML 可能也不能
在运行机器学习算法之前,如果你能可视化数据,亲眼看到重复的模式,会有所帮助。这可以是图表的形式,显示一个清晰可见的趋势线,如在左边。
我们的一些客户有时会开发基于规则的内部决策机。例如,如果一位顾客买了一张餐桌,他们会意识到他可能也对一把椅子感兴趣,并在软件中输入一条规则,为购买餐桌的顾客提供椅子。这很好,这意味着数据中确实有重复的模式。
机器学习可以帮助你找到更多你错过的模式。或者,细化您找到的模式定义,使模式识别更准确,对您更具可操作性。
训练或使用预先训练的算法
ML 以算法的训练周期而闻名——你提供自己的数据,或一些其他现有的数据集,然后你 训练算法 识别你感兴趣的数据中的模式。有时,人们会使用“受监督的”和“不受监督的”这两个短语:
监督意味着你的训练数据被分类到不同的组。例如,如果你开发了一个算法来识别照片和猫和狗,在监督方法中,你会有猫的照片,标记为猫,狗的图像,标记为狗,你会根据这个训练数据训练一个 ML 算法来识别猫和狗。
无监督表示你有训练数据,但是没有分类。在猫和狗的例子中,你有猫和狗的照片,但是没有猫和狗的标签。你只知道照片的标签有两种可能。在这种情况下,您将训练算法来区分训练数据中的两个组。
注意,监督和非监督方法都需要训练算法。
第二种选择是使用 预训练算法 ,或者不需要训练的算法。这些都是预先准备好的算法,随时可以使用。例如,已经存在用于图像识别的算法,这些算法使用庞大的学术界数据集进行训练,以识别图像中的不同对象。另一个例子是文本索引和搜索软件,尽管不完全是机器学习,而是一种人工智能方法。这些程序具有分析不同语言文本的能力,不需要你提供训练文本样本。
预先培训的方法更通用,可以很容易地在每个公司实施。这种方法的问题是:
- 许可—有时您无法使用预训练的算法,因为它是使用具有使用许可限制的专有数据训练的。
- 该算法对您的数据的预测\估计\分类质量可能会更差,因为该算法不是针对您的数据进行训练的。
- 预训练算法只存在于一组特定的问题和特定的数据结构中,很多时候你可能找不到一个符合你确切需求的预训练算法。相比之下,训练自己的算法是非常通用的,可以用于任何所需的数据分析问题。
最好是使用您自己的特定和自定义数据来训练算法。但是,很多时候,公司没有足够的数据进行训练,所以他们被迫使用预先训练好的算法。
值得一提的是,如果一个算法的实现为另一家公司或另一项研究工作,那么为你的公司做同样的事情可能需要一个完全不同的项目,这完全取决于你拥有的数据集。
非监督或异常检测算法很少工作,除非你有非常干净的数据
这些方法是一种“机器学习魔法”,应该如此对待。正如所料,试图将一堆数据输入算法,希望会有好的结果出现,这是独一无二的。
如果我们试图识别的不同组之间存在真正的差异,并且这种差异清楚地显示在特征中,那么无监督学习就可以工作(参考上面关于人类查看数据的经验法则)。此外,通常我们必须事先知道在数据中我们会遇到多少不同的组。
这里可以看到一个有趣的例子,以一种无监督的方式将手写数字图像聚类到不同的组:
摘自本张量流链接
异常检测 可能会起作用,如果有足够多的我们正在试图识别的独特场合的样本,并且这些样本确实比标准(非异常)情况大得多。
另一方面,标记组的组分离有简单的实现
有时,从不同的组中获得样本并训练机器学习算法来识别来自未知组的新样本可能非常容易。例如,在心理行为研究中,统计学家多年来一直使用这些技术来识别不同行为、行为组合和群体归属之间的相关性。
培训需要多少数据?
在这种情况下,多多益善。更具体地说,它确实随着你试图解决的问题而改变。这通常是算法实现的一部分——检查手头的特定数据、要解决的特定问题,并查看哪些算法可以工作以及需要多少数据。
当有一个大的数据集,但它不是均匀分布时,就会出现一个常见的问题。例如,当一家公司想要识别哪些功能会导致更多的客户销售转换时,该公司可能有关于成千上万潜在客户的信息,但只有少数购买了的客户。在这种情况下,运行任何类型的机器学习算法来带来有意义的结果可能很难,如果不是不可能的话。在另一个例子中,基于声音、压力测量、温度或其他物理测量来识别重型机械故障可能是不可能的,如果当机器工作不正常时有少数样本,而当机器工作良好时有其余样本。
来自我们个人经验的一些基准:
- 在预测和趋势分析中,为了能够识别季节性(年度)趋势,至少需要 f 2 年的样本。这是因为大体上 1 年用于基线估计,另一年用于趋势估计。
- 在 3D 建模中(你可以看看我们的中帖作为例子)——至少需要 5000 个特定物体的 3D 模型(5000 个椅子模型)
- 在视频分析方面——当我们在从事唇读初创公司的工作时,我们发现我们需要至少 70,000 小时的人说话视频(这是大约 10tb 的数据)来让我们的神经网络学习任何东西。
不仅仅是数据量,还有数据的格式
很多时候,一个 ML 项目开始于清理提供的数据,改变它,简化它的结构。在这一阶段,在数据中发现了许多错误和问题。最初准备或保存数据的方式可能存在意外问题,或者数据导出的方式存在其他问题。所有这些都需要时间和努力,并且必须非常小心地完成。因为,否则我们可能会在完全不正确的信息上训练算法,得不到任何好的结果,并将其归咎于算法而不是原始训练数据。
在项目中,70%的实际工作处于数据重新格式化和测试的阶段。
深度学习不会解决你的问题,除非你做视觉\信号处理
有时,客户开始与我们交谈,他们会谈论他们在网上看到的关于深度学习和神经网络的不同事情,他们希望我们为他们实现这些事情。深度学习只是另一种可以尝试的机器学习算法。构建和优化一个深度学习算法来解决一个问题,通常比使用一些更简单的方法,如逻辑回归或正则回归(取决于手头的问题),需要更多的时间和精力。大多数情况下,实现深度学习是矫枉过正。深度学习是必须的情况是在技术上困难的情况下,例如图像分析、文本分析、信号处理、生物数据分析或其他类型的项目,其中特征很复杂,通常每个数据样本有数千个特征。
黑仔特征比算法更重要
很多时候,更值得做的是开发新功能,测试它们,尝试开发新功能。通常如果你有一个好的特征,最简单的算法就足够了。例如,在上面的例子中,一个顾客在买桌子的同时也会买一把椅子,如果你有这个特征——最后售出的物品的类别(在我们的例子中是桌子),那么,即使一个简单的逻辑回归模型也可能识别出下一个售出的类别是椅子。
这意味着对于一个 ML 工程师来说,非常擅长简单的数据分析和数据工程比了解所有不同的 ML 算法并实现它们更重要。
时间表、定价和招聘考虑因素
最简单的情况下,初始数据检查至少需要 1 个小时到 2 周的全职工作。
研究特定算法或学术界发布的新算法所需的时间:
- 至少要花 4 天时间阅读最相关的研究论文和信息。
- 半天到 2 周的时间来实现基本的开源代码,如果有的话。
- 根据手头问题的复杂程度、训练数据的质量(或缺乏训练数据)和所需的 KPI,定制算法或对数据进行训练可能需要几个月时间。
在某些情况下,例如异常检测,不可能定义可操作的技术 KPI,因为即使是最好的算法也不知道有多准确。
定制项目可能很贵,价格从每小时 120 美元到 300 美元不等。
通常从小处开始,快速简单地取得胜利,然后如果你看到实现机器学习的价值,就继续前进。在看到任何进展之前,不要花几个月的时间去开发是明智的。尝试 1-2 个月,专注于可实现的短期目标,甚至可能是一份简单的报告,使用简单的工具。如果这行得通,那就前进到更复杂的东西。
如何识别合适的 ML 公司\顾问\雇佣
- 他们告诉你和上面写的一样的东西。
- 他们从向您显示数据的图表和仪表盘开始,而不是深入开发。
- 如果他们认识到数据集不够好,他们会说不,如果你感兴趣,他们会给你一些提示,告诉你如何仍然可以进行机器学习,你需要关注什么。
- 它们很贵。
- 他们用简单易懂的语言解释基本概念,帮助你理解这个项目,它的范围和它的局限性。
关于我们
我们是datask.co——背后的人你问数据,我们答——一家机器学习即服务公司。我们还经营博客 2d3d.ai 和 ML 咨询公司abelians.com
原载于 2020 年 4 月 13 日https://2d3d . ai。
针对类别不平衡的机器学习重采样技术
原文:https://towardsdatascience.com/machine-learning-resampling-techniques-for-class-imbalances-30cbe2415867?source=collection_archive---------11-----------------------
如何为一个更好的预测模型期待意想不到的事情
让我们面对现实吧。不平等糟透了。我甚至还没有谈到这样一个事实:尽管非洲裔美国人和西班牙裔美国人占美国总人口的 32%,但他们却占美国监狱人口的 56%;也没有提到 T2 比尔·盖茨、杰夫·贝索斯和沃伦·巴菲特的财富总和比美国最底层的 50%的人的财富总和还要多。
尽管我很想对这些事实感到愤怒,但现在我谈论的是机器学习分类模型背景下的阶级不平衡。根据维基百科的说法,算法偏差“可能由于许多因素而出现,包括但不限于算法的设计,或者与数据编码、收集、选择或用于训练算法的方式有关的无意或意外使用或决策。”使用高度不平衡的数据训练模型可能会偏向多数类,这可能会产生严重的影响。
以 Kaggle 的宫颈癌风险分类数据集为例。
在数据集中包含的所有诊断中,只有 2%被发现是癌症。在执行简单的随机森林分类模型后,该模型的准确率为 99%!
from sklearn.ensemble import RandomForestClassifier
from sklearn.metrics import accuracy_score, recall_score, classification_report
from sklearn.model_selection import train_test_splitX = df.drop('Cancer', axis=1).dropna()
y = df['Cancer'].dropna()X_train, X_test, y_train, y_test = train_test_split(X, y, test_size = 0.25)random_forest = RandomForestClassifier(n_estimators=500).fit(X_train, y_train)
y_pred = random_forest.predict(X_test)
print('Accuracy score: ' + str(accuracy_score(y_test, y_pred)))
print('Recall score: ' + str(recall_score(y_test, y_pred)))
print(classification_report(y_test, y_pred))
那不太可能。让我们再深入一点。让我们在模型中只包括 36 列中的两列。
X = df.loc[:,['Smokes', 'Hormonal Contraceptives']]
y = df['Cancer'].dropna()X_train, X_test, y_train, y_test = train_test_split(X, y, test_size = 0.25)
random_forest = RandomForestClassifier(n_estimators=500).fit(X_train, y_train)
y_pred = random_forest.predict(X_test)
print('Accuracy score: ' + str(accuracy_score(y_test, y_pred)))
print('Recall score: ' + str(recall_score(y_test, y_pred)))
print(classification_report(y_test, y_pred))
但是准确率只降到了 97%!我们随机选择的两个特征能够以 97%的准确率预测癌症的可能性非常小。
我们已经知道 2%的患者被诊断患有癌症,但是我们的第二个模型预测没有患者会患有癌症。看到这怎么会成为一个问题了吗?
你应该用什么标准来评估?
在严肃的医疗诊断模型、惩罚性模型如 COMPAS 、累犯风险模型和欺诈检测中,都存在悬而未决的人命问题。在这些情况下,最好谨慎行事,保护尽可能多的人——无论这是否意味着降低误报或漏报的数量。
当考虑如何优化这些类型的模型时,我们可以解读一些指标。
回想一下:以宫颈癌风险数据集为例,您可以问自己这个模型— 在所有实际被诊断患有癌症的患者中,我们的模型预测患有癌症的比例是多少?
然而,回忆并不能让你了解全貌。假设你的模型将每个人都归类为患有癌症,包括那些没有患癌症的人,那么你的得分就是 100%。低召回分数表示高数量的假阴性。
Precision: Precision 提出了相反的问题——在所有被模型预测为患有癌症的患者中,有多少人确实患有癌症?
如果你的模型预测 10 名患者患有癌症,如果所有的预测都是正确的,我们的得分将是 100%,即使还有 1000 多名患者没有得到诊断。低精度分数表示高数量的假阳性。
准确性:准确性是一个更可靠的评估指标,因为它衡量真实预测的总数,包括正面和负面预测。这是分类任务中最常见的指标。
F1 得分:F1 得分是另一个非常有用的指标。因为它衡量的是“精确度和召回率的调和平均值”,如果精确度和召回率都不高,它就不可能高,这表明模型整体表现良好。但是,F1 分数可以格式化,以解决二进制、多类和不平衡分类问题,在sk learn . metrics. F1 _ score 方法中使用以下参数:
- 二进制— 用于二进制分类问题。
- 微— 统计总的真阳性、假阴性和假阳性。
- 宏— 计算所有类别的未加权平均值(对于多类别问题。)
- 加权— 通过对每个类别的真阳性进行加权并取平均分数来说明类别不平衡。
- 样本— 查找每个类的每个指标的平均分。
让我们对抗不平等,一次一个重采样方法!
有了这些信息,我们将优化二进制 F1 分数,因为我们只有两个类。你可能会想“如果我们的数据如此严重不平衡,为什么不使用加权 F1 分数?”这就是重采样方法的用武之地!
我们将探讨三种简单而有用的方法(尽管还有更多)——对多数采样不足、对少数采样过采样和 SMOTE(合成少数采样过采样技术)。我们将使用的每种方法都旨在创建一个对半分布的训练集,因为我们正在处理一个二元分类问题。这些方法可用于为四个类别的多类别问题创建 25–25–25–25 分布,而不考虑类别的初始分布,或其他可能训练您的模型以获得更好结果的比率。
在重新采样之前,请确保将您的数据分成训练集和测试集! 如果你不这样做,你会因为数据泄露而损害模型的质量,导致过度拟合和泛化能力差。
*# Import the resampling package*
from sklearn.utils import resample*# Split into training and test sets*
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size = 0.25)*# Returning to one dataframe*
training_set = pd.concat([X_train, y_train], axis=1)*# Separating classes*
cancer = training_set[training_set.Cancer == 1]
not_cancer = training_set[training_set.Cancer == 0]
欠采样多数
欠采样可以定义为减少多数类的数量。这种技术最适用于有数千甚至数百万个数据点的数据。通常,您不希望减少正在处理的数据量,但是如果您可以牺牲一些训练数据,这种技术将非常有用。下面是它在宫颈癌数据集上的工作原理:
*# Undersampling the majority*
undersample = resample(not_cancer,
replace=True,
n_samples=len(cancer), #set the number of samples to equal the number of the minority class
random_state=42)*# Returning to new training set*
undersample_train = pd.concat([cancer, undersample])undersample_train.Cancer.value_counts(normalize=True)
我们有均匀分布的班级!现在我们可以在随机森林分类器上测试它。
*# Separate undersampled data into X and y sets*
undersample_x_train = undersample_train.drop('Cancer', axis=1)
undersample_y_train = undersample_train.Cancer*# Fit model on undersampled data*
undersample_rf = RandomForestClassifier(n_estimators=500).fit(undersample_x_train, undersample_y_train)*# Make predictions on test sets*
y_pred = random_forest.predict(X_test)print('Accuracy score: ' + str(accuracy_score(y_test, y_pred)))
print('Average Recall score: ' + str(recall_score(y_test, y_pred, average='macro')))
print(classification_report(y_test, y_pred))
不完全是最好的结果,但因为我们减少了多数类的数量,我们只在 28 个实例上训练我们的模型,这对于样本大小来说太小了。接下来,我们将尝试对少数进行过采样。
过采样少数
对少数民族进行过采样将增加少数民族类中的数据点数量,同样旨在均匀分布训练集中的类。我们将重复和以前一样的过程。
*# Oversampling the minority*
oversample = resample(cancer,
replace=True,
n_samples=len(not_cancer), #set the number of samples to equal the number of the majority class
random_state=42)*# Returning to new training set*
oversample_train = pd.concat([not_cancer, oversample])oversample_train.Cancer.value_counts(normalize=True)
*# Separate oversampled data into X and y sets*
oversample_x_train = oversample_train.drop('Cancer', axis=1)
oversample_y_train = oversample_train.Cancer*# Fit model on oversampled data*
oversample_rf = RandomForestClassifier(n_estimators=500).fit(oversample_x_train, oversample_y_train)*# Make predictions on test sets*
y_pred = oversample_rf.predict(X_test)
print('Accuracy score: ' + str(accuracy_score(y_test, y_pred)))
print('Average Recall score: ' + str(recall_score(y_test, y_pred, average='macro')))
print(classification_report(y_test, y_pred))
不幸的是,我们的结果只是稍微好一点。我们还有一项技术可以尝试。
SMOTE(合成少数过采样技术)
SMOTE 从现有的少数类池中合成数据点,并将它们添加到数据集中。这种技术通过为模型创建新的、不可见的数据点进行训练,确保了数据泄漏非常少。
*# Import the SMOTE package*
from imblearn.over_sampling import SMOTE*# Synthesize minority class datapoints using SMOTE*
sm = SMOTE(random_state=42, sampling_strategy=’minority’)
smote_x_train, smote_y_train = sm.fit_resample(X_train, y_train)*# Separate into training and test sets*
smote_x_train = pd.DataFrame(smote_x_train, columns = X_train.columns)
smote_y_train = pd.DataFrame(smote_y_train, columns = ['Cancer'])smote = RandomForestClassifier(n_estimators=1000).fit(smote_x_train, smote_y_train)
*# Predict on training set*
smote_preds = smote.predict(X_test)*# Checking accuracy and recall*
print('Accuracy Score: ', accuracy_score(y_test, smote_preds),'\n\n')
print('Averaged Recall Score: ', recall_score(y_test, smote_preds, average='macro'), '\n\n')
print(classification_report(y_test, smote_preds))
准确性和 f1 分数有所提高,但回忆分数略有下降。根据您的模型用例,此时您必须决定哪个模型保护的人最多。
AOC 是美国下层的冠军,但是 ROC AUC 是模型评测的冠军
可视化模型质量的最佳方法之一是检查 ROC 曲线。ROC(受试者工作特性)曲线绘出了真阳性率 TPR 与假阳性率 FPR 的关系。最佳预测将在没有假阳性(成本)和 100%真阳性(收益)的点(0,1)处找到。
包括在图中的是无描述线,它展示了随机猜测,类似于抛硬币的概率。线上的点是“好的”猜测,因为它们在点(0,1)上更接近完美的结果。反之亦然,线以下的点表示预测不佳。
AUC,或曲线下面积,是可分离程度的定量度量。预测越接近理想结果,AUC 就越大。当 AOC 告诉我们不要退而求其次时,她是在告诉我们将 AUC 定在接近 1%或 100%的水平。
这是一个用 SMOTE 重采样训练集训练的随机森林分类器的例子(阅读文档此处):
y_score = smote.fit(smote_x_train, smote_y_train).predict_proba(X_test)[:,1]fpr, tpr, thresholds = roc_curve(y_test, y_score)
print('AUC: {}'.format(auc(fpr, tpr)))
不算太差!仍有很大的改进空间,但我们可以从图中看出这一点:
plt.figure(figsize=(10, 8))
lw = 2
plt.plot(fpr, tpr, color=’darkorange’,
lw=lw, label=’ROC curve’)
plt.plot([0, 1], [0, 1], color=’navy’, lw=lw, linestyle=’ — ‘)
plt.xlim([0.0, 1.0])
plt.ylim([0.0, 1.05])
plt.yticks([i/20.0 for i in range(21)])
plt.xticks([i/20.0 for i in range(21)])
plt.xlabel(‘False Positive Rate’)
plt.ylabel(‘True Positive Rate’)
plt.title(‘Receiver operating characteristic (ROC) Curve’)
plt.legend(loc=’lower right’)
plt.show()
理想情况下,我们希望看到橙色线更加陡峭,直到它非常接近(0,1)时才会变平,但这是一个很好的起点。
与所有机器学习项目一样,这个过程是迭代的。在您决定采用哪种方法之前,还有其他方法可以对您的模型进行重新采样和验证。彻底考虑哪种性能指标符合您的目的,选择一种适合您的数据类型的算法,并根据部署后危害最小的算法来评估您的模型。
请在下面评论,告诉我你重新采样数据的其他方法!
机器学习路线图——我的旅程和进化
原文:https://towardsdatascience.com/machine-learning-roadmap-my-journey-and-evolution-a76ae656969?source=collection_archive---------12-----------------------
我从机械工程师到机器学习科学家的旅程和职业转型,以及经验教训
尼克·莫里森在 Unsplash 上拍摄的照片
人工智能、机器学习、深度学习、物联网等。是过去几年的流行语。如果有人在战略,商业或 IT 咨询,不知道至少基本的信息技术,那么我想他们是非常多余的。
为了跟上两年前的潮流,我决定熟悉机器学习和深度学习。
我们中的许多人希望转行到机器学习/人工智能领域,或者来自非科学背景,因此发现获得必要的知识具有挑战性。在这篇文章中,我将分享我的旅程和进化,以及帮助我获得这方面知识的资源。我希望它能提供洞察力,帮助你构建你的学习路径。
我的挑战
20 年前我学的是机械工程。工程学位让我能够用理性的方式进行系统思考。我在工程系学过高等微积分和线性代数,这些年来我忘记了大部分概念。很快就变得很明显,我需要学习一些东西作为先决条件,甚至在开始学习机器的 ABC 或深度学习之前。
- 复习线性代数、微积分和概率的概念
- 学习基本统计学
- 选择主要语言
- 学习地图
我没有精力去读数学课本,因此为了复习,我看了可汗学院和麻省理工学院开放课件上的线性代数、微积分和概率的视频。我将特别推荐吉尔伯特·斯特朗教授的讲座。
[## 麻省理工学院开放式课程|免费在线课程材料
麻省理工学院开放式课程是一个基于网络的出版物,包含了几乎所有的麻省理工学院课程内容。开放式课程是开放的,可供…
ocw.mit.edu](https://ocw.mit.edu/index.htm)
由于大量的库和开发者支持,我将 python 作为我的主要编程语言。
一旦我修改了数学概念,我就开始学习 Python。我以前用 C 语言做过编程,我已经知道了循环、条件语句等概念。
我发现 Eric Matthes 的书《 Python 速成班:基于项目的编程入门 》非常有助于理解语法和基本概念。我用来磨练我的基本 python 技能的另一本书是 Al Sweigart 的用 Python 自动化枯燥的东西,第二版:完全初学者实用编程】。
在对 python 有了一个良好的基础之后,我把重点放在了用于机器学习的 python 包的三位一体上,即 NumPy、pandas 和 matplotlib/seaborn。
用于机器学习的 Python 三位一体库—图片由作者提供
所有三个软件包的官方文档都写得非常好,即使对于初学者也很容易理解。我从 NumPy 开始,然后去了 Pandas,最后去了 matplotlib/seaborn,以获得关于数据可视化的想法。
我花了大约 2 个月的时间,花了大约 3 个小时阅读,才达到这一点。在那之前,我从未学过统计学,我对统计学的全部知识仅限于平均值和众数。
我发现 David Spiegelhalter 的书《统计的艺术:从数据中学习》很有帮助。它不仅帮助我以非数学的方式了解统计学,而且在数据科学可视化方面也有很大帮助。它教会了我如何基于不同的数据可视化,基于相同的数据点传达不同的信息。
带着对基本统计学的概念性理解,我阅读了《数据科学家实用统计学:使用 R 和 Python 的 50+基本概念》一书,以建立程序化的实践知识。**
作者的机器学习地图-按作者分类的图片
经过三个月的学习,我终于准备好开始学习机器学习了。如果我能说出一本书加速了我的学习并解释了从初学者到高级水平的概念,那么它就是 Aurelien Geron 的“用 Scikit-Learn、Keras 和 TensorFlow 进行机器学习:构建智能系统的概念、工具和技术”。
一旦你遵循了我上面提到的从 python 到 pandas 和 matplotlib 的学习路径,那么这本书里没有一行是你不能理解的。这本书里没有数学术语的完整的动手方法对没有高级数学知识的人很有帮助。
我一共花了六个月的时间达到中级机器学习的熟练程度,又花了两个月的时间了解深度学习的基础知识。
我的旅程中的主要收获和收获
机器学习和数据科学的熟练程度取决于对以下领域的扎实知识
- 至少具备中级 python 编程知识
- 关于 Numpy 、 Pandas 和Matplotlib/SeabornPython 库的高级知识
不要急于开始机器学习图书馆和书籍,如果你还没有完全掌握这些图书馆的话。这些领域的全面知识将使你的机器学习变得迅速和愉快。
从线性回归等更简单、更知名的算法开始你的机器学习。不要试图用一个最复杂的鲜为人知的算法来显得博学并给别人留下深刻印象。
Scikit-learn 是一个非常强大和通用的机器学习库。从初学者的角度来看,它也是非常用户友好的,并且是可用的文档最丰富的库之一。我强烈建议从 Scikit-learn 开始,并在转到其他库之前花大量时间熟悉它。
在涉足深度学习世界之前,先熟悉机器学习。在没有很好地理解机器学习的情况下急于进行深度学习,从长远来看是没有帮助的。
从深度学习的 Keras 库开始,你可以把 TensorFlow 放在后面。
最后,在机器和深度学习上利用 Coursera 和 Edx 上的免费学习资源。
我希望开始机器和深度学习之旅的读者能够从本文概述的我的旅程中获得一些关于学习方法的见解,并能够构建他们的学习路径。
我有兴趣知道机器学习的其他专家和学生的学习地图、关键资源和方法。
机器学习:关于交叉验证的一些注意事项
原文:https://towardsdatascience.com/machine-learning-some-notes-about-cross-validation-4a0315599f2?source=collection_archive---------35-----------------------
交叉验证的不同方法概述
制造者在 Unsplash 上 NESA 的照片
简介
如您所知,当我们将数据分为训练集和测试集时,我们的主要目标是了解模型在面对与训练阶段使用的数据不同的新数据时的预测能力。
无论如何,有一个可靠的方法来评估我们的模型的性能。这种方式被称为交叉验证。交叉验证是一种评估泛化性能的统计技术,它比使用分为训练集和测试集的方法更稳定。
在本文中,我们将了解一些交叉验证方法,如 K 倍交叉验证、分层 K 倍交叉验证和留一交叉验证。
第一部分:K 倍交叉验证
k 重交叉验证是最常用的交叉验证方法之一。在这个方法中, k 表示为了测试和训练我的数据,我想要尝试的实验(或折叠)次数。
例如,假设我们想要用由 1000 条记录组成的数据进行 5 次实验(或性能)。因此,在第一个实验中,我们测试或验证前 200 条记录,然后训练剩余的 800 条记录。当第一个实验完成时,我获得了一定的精度。然后,我们进行第二个实验,测试我之前测试的记录之后的 200 条记录,并训练剩余的 800 条记录。
我用一组 200 个记录继续实验,直到我完成所有 5 个实验。请记住,我们总是测试先前记录的下 200 个记录,并训练剩余的记录直到结束。
在我的 5 次实验结束时,我将获得 5 次精度,最终精度将是所有精度的平均值。
下面你可以看到一个直观的例子。
作者图片
交叉验证是在 scikit-learn 中使用来自 model_selecion 模块的 cross_val_score 函数实现的。 cross_val_score 函数的参数是我们想要评估的模型、训练数据和目标。下面是一个逻辑回归的例子:
from **sklearn.model_selection** import **cross_val_score**from **sklearn.linear_model** import **LogisticRegression**logreg = LogisticRegression()scores = cross_val_score(logreg, X,y,cv=5)
第二部分:分层 K 褶交叉验证
考虑到前面 1000 条记录的例子,有时从测试前 200 条记录开始并不总是一个好主意。事实上,在一个数据集中,我们可以发现前三分之一的数据指向同一个类。
假设我们有三个类(0、1 和 2),如下所示:
[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2]
可以看到,第一个第三类是 0,第二个是 1,第三个是 2。现在想象做 3 个实验(k=3)。在我们的第一个实验中,测试集只在类 0 中,训练集只在类 1 和 2 中。所以,你可以知道精度是 0。
为了处理这个问题,我们可以使用分层 k 倍交叉验证。在分层交叉验证中,我们对数据进行分割,使每个折叠中的类之间的比例与它们在整个数据集中的比例相同,如下图所示。在该图中,对 k 倍交叉验证和分层交叉验证进行了比较:
作者图片
Scikit-learn 帮助我们进行分层折叠。所以:
from **sklearn.model_selection** import **StratifiedKFold**skf = StratifiedKFold(n_split=5, random_state=None)# X is the feature set and y is the target
for train_index, test_index in skf.split(X,y):
print("Train:", train_index, "Test:", test_index)
X_train, X_test = X.iloc[train_index], X.iloc[test_index]
y_train, y_test = y[train_index], y[test_index]
第三部分:留一交叉验证
另一个有趣的交叉验证方法是留一法。这种方法类似于我们之前看到的 k-fold,但是对于每个实验(或表演),我们只取一个样本进行测试,而不是像以前那样取 200 个记录。
下面,我们可以用 LeaveOneOut 在 scikit-learn 中找到实现。
from **sklearn.model_selection** import **LeaveOneOut**loo = LeaveOneOut()cross_val_score(logreg, X, y, cv=loo)
结论
在本文中,您已经看到了机器学习中用于评估模型准确性的最常见的交叉验证方法。无论如何,还有一些其他的方法,如混洗-分裂交叉验证,分组交叉验证和时间序列交叉验证,在某些情况下非常有用。
感谢你阅读这篇文章。您还可以通过其他方式与我保持联系并关注我的工作:
- 订阅我的时事通讯。
- 也可以通过我的电报群 数据科学初学者 联系。
机器学习:循序渐进
原文:https://towardsdatascience.com/machine-learning-step-by-step-6fbde95c455a?source=collection_archive---------1-----------------------
使用随机森林、PCA 和超参数调整的 Python 机器学习分类分步指南——带代码!
图像来源
作为数据科学家,我们有许多选择来创建分类模型。最流行和可靠的方法之一是使用随机森林。我们可以对 随机森林 执行 超参数调整 来尝试优化模型的性能。
在将我们的数据拟合到模型之前,尝试【PCA】也是常见的做法。但是我们为什么还要增加这一步呢?随机森林的全部意义不就是帮助我们容易地解释特征重要性吗?
是的,当我们分析随机森林模型的“特征重要性”时,PCA 会使解释每个“特征”变得更加困难。但是,PCA 执行降维,这可以减少随机森林要处理的要素数量,因此 PCA 可能有助于加快随机森林模型的训练。请注意,计算成本是随机森林的最大缺点之一(运行模型可能需要很长时间)。主成分分析会变得非常重要,尤其是在处理成百上千个预测特征的时候。因此,如果最重要的事情是简单地拥有性能最好的模型,并且可以牺牲解释特征重要性,那么 PCA 可能是有用的尝试。
现在,让我们开始我们的例子。我们将使用 Scikit-learn“乳腺癌”数据集。 我们将创建 3 个模型,并相互比较它们的性能:
- 1.随机森林
- 2.PCA 降维的随机森林
- 3.PCA 降维的随机森林&超参数调整
1.输入数据
首先,我们加载数据并创建一个数据框架。由于这是来自 Scikit-learn 的预先清理过的“玩具”数据集,我们可以继续进行建模过程了。但是,作为最佳实践,我们应该始终做到以下几点:
- 使用 df.head() 浏览新的数据帧,确保它看起来像预期的那样。
- 使用 df.info() 来了解每一列中的数据类型和计数。您可能需要根据需要转换数据类型。
- 使用 df.isna() 来确保没有 NaN 值。您可能需要根据需要估算值或删除行。
- 使用 df.describe() 了解每一列的最小值、最大值、平均值、中值、标准偏差和四分位间距。
名为“cancer”的列是我们希望使用模型预测的目标变量。“0”表示“没有癌症”,“1”表示“癌症”。
import pandas as pd
from sklearn.datasets import load_breast_cancercolumns = ['mean radius', 'mean texture', 'mean perimeter', 'mean area', 'mean smoothness', 'mean compactness', 'mean concavity', 'mean concave points', 'mean symmetry', 'mean fractal dimension', 'radius error', 'texture error', 'perimeter error', 'area error', 'smoothness error', 'compactness error', 'concavity error', 'concave points error', 'symmetry error', 'fractal dimension error', 'worst radius', 'worst texture', 'worst perimeter', 'worst area', 'worst smoothness', 'worst compactness', 'worst concavity', 'worst concave points', 'worst symmetry', 'worst fractal dimension']dataset = load_breast_cancer()
data = pd.DataFrame(dataset['data'], columns=columns)
data['cancer'] = dataset['target']display(data.head())
display(data.info())
display(data.isna().sum())
display(data.describe())
上面是乳腺癌数据框架的一部分。每一行都有关于患者的观察结果。名为“癌症”的最后一列是我们试图预测的目标变量。 0 表示“没有癌症”,1 表示“癌症”。
2.训练/测试分割
现在,我们使用 Scikit-learn 的“train_test_split”函数分割数据。我们希望为模型提供尽可能多的数据来进行训练。然而,我们还想确保我们有足够的数据让模型进行自我测试。通常,随着数据集中行数的增加,我们可以提供给定型集的数据就越多。
例如,如果我们有数百万行,我们可以有 90%的训练/ 10%的测试分割。然而,我们的数据集只有 569 行,这对于训练或测试来说并不是一个非常大的数据集。因此,为了公平对待训练和测试,我们将数据分成 50%训练和 50%测试。我们设置分层=y 以确保训练集和测试集与原始数据集具有相同比例的 0 和 1。
from sklearn.model_selection import train_test_splitX = data.drop('cancer', axis=1)
y = data['cancer']
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.50, random_state = 2020, stratify=y)
3.缩放数据
在建模之前,我们需要通过缩放来“居中”和“标准化”我们的数据。我们按比例控制,因为不同的变量在不同的比例上测量。我们进行缩放,以便每个预测者可以在决定重要性时相互“公平竞争”。见此文。我们还将“y_train”从 Pandas“Series”对象转换为 NumPy 数组,以便模型稍后接受目标训练数据。
import numpy as np
from sklearn.preprocessing import StandardScalerss = StandardScaler()
X_train_scaled = ss.fit_transform(X_train)
X_test_scaled = ss.transform(X_test)
y_train = np.array(y_train)
4.适合“基线”随机森林模型
现在我们创建一个“基线”随机森林模型。该模型使用所有预测功能以及在 Scikit-learn 随机森林分类器文档中定义的默认设置。首先,我们对模型进行实例化,并对缩放后的数据进行拟合。我们可以根据我们的训练数据来衡量模型的准确性。
from sklearn.ensemble import RandomForestClassifier
from sklearn.metrics import recall_scorerfc = RandomForestClassifier()
rfc.fit(X_train_scaled, y_train)
display(rfc.score(X_train_scaled, y_train))# 1.0
如果我们想知道哪些特征对随机森林模型预测乳腺癌最重要,我们可以通过调用 "feature_importances_" 方法来可视化和量化重要性:
feats = {}
for feature, importance in zip(data.columns, rfc_1.feature_importances_):
feats[feature] = importanceimportances = pd.DataFrame.from_dict(feats, orient='index').rename(columns={0: 'Gini-Importance'})
importances = importances.sort_values(by='Gini-Importance', ascending=False)
importances = importances.reset_index()
importances = importances.rename(columns={'index': 'Features'})sns.set(font_scale = 5)
sns.set(style="whitegrid", color_codes=True, font_scale = 1.7)
fig, ax = plt.subplots()
fig.set_size_inches(30,15)
sns.barplot(x=importances['Gini-Importance'], y=importances['Features'], data=importances, color='skyblue')
plt.xlabel('Importance', fontsize=25, weight = 'bold')
plt.ylabel('Features', fontsize=25, weight = 'bold')
plt.title('Feature Importance', fontsize=25, weight = 'bold')display(plt.show())
display(importances)
5.主成分分析
现在,我们如何改进我们的基线模型?使用降维,我们可以用更少的变量逼近原始数据集,同时降低运行模型的计算能力。使用主成分分析,我们可以研究这些特征的累积解释方差比率,以了解哪些特征解释了数据中的最大方差。
我们实例化 PCA 函数,并设置我们想要考虑的组件(特征)的数量。我们将它设置为“30 ”,以查看所有生成组件的解释差异,然后决定在哪里进行切割。然后,我们将缩放后的 X_train 数据“拟合”到 PCA 函数。
import matplotlib.pyplot as plt
import seaborn as sns
from sklearn.decomposition import PCApca_test = PCA(n_components=30)
pca_test.fit(X_train_scaled)sns.set(style='whitegrid')
plt.plot(np.cumsum(pca_test.explained_variance_ratio_))
plt.xlabel('number of components')
plt.ylabel('cumulative explained variance')
plt.axvline(linewidth=4, color='r', linestyle = '--', x=10, ymin=0, ymax=1)
display(plt.show())evr = pca_test.explained_variance_ratio_
cvr = np.cumsum(pca_test.explained_variance_ratio_)pca_df = pd.DataFrame()
pca_df['Cumulative Variance Ratio'] = cvr
pca_df['Explained Variance Ratio'] = evr
display(pca_df.head(10))
该图显示,超过 10 个成分后,我们没有获得太多的解释方差。
该数据帧显示了累积方差比(解释了数据的总方差)和解释方差比(每个 PCA 成分解释了数据的总方差)。
看上面的数据框架,当我们使用主成分分析将 30 个预测变量减少到 10 个成分时,我们仍然可以解释超过 95%的方差。其他 20 个成分解释了不到 5%的方差,因此我们可以剔除它们。使用这个逻辑,我们将使用 PCA 将 X_train 和 X_test 的组件数量从 30 个减少到 10 个。我们将把这些重新创建的“降维”数据集分配给“X_train_scaled_pca”和“X_test_scaled_pca”。
pca = PCA(n_components=10)
pca.fit(X_train_scaled)X_train_scaled_pca = pca.transform(X_train_scaled)
X_test_scaled_pca = pca.transform(X_test_scaled)
每个分量都是原始变量与相应“权重”的线性组合。通过创建数据帧,我们可以看到每个 PCA 成分的“权重”。
pca_dims = []
for x in range(0, len(pca_df)):
pca_dims.append('PCA Component {}'.format(x))pca_test_df = pd.DataFrame(pca_test.components_, columns=columns, index=pca_dims)
pca_test_df.head(10).T
6.PCA 后适合“基线”随机森林模型
现在,我们可以将我们的 X_train_scaled_pca 和 y_train 数据拟合到另一个“基线”随机森林模型,以查看我们是否对模型的预测有任何改进。
rfc = RandomForestClassifier()
rfc.fit(X_train_scaled_pca, y_train)display(rfc.score(X_train_scaled_pca, y_train))# 1.0
7.第一轮超参数调整:RandomSearchCV
在执行 PCA 之后,我们还可以尝试一些超参数调整来调整我们的随机森林,以获得更好的预测性能。超参数可以被认为是模型的“设置”。一个数据集的完美设置对于另一个数据集是不一样的,所以我们必须“调整”模型。
首先,我们可以从 RandomSearchCV 开始考虑广泛的值。随机森林的所有超参数都可以在 Scikit-learn 随机森林分类器文档中找到。
我们生成一个“param_dist ”,其中包含一系列值,用于尝试每个超参数。RandomSearchCV 被实例化,我们的随机森林模型首先被传入,然后是我们的“param_dist”、要尝试的迭代次数以及要执行的交叉验证的次数。
“详细”超参数在模型运行时为您提供或多或少的输出(比如状态更新)。 "n_jobs" 超参数让您决定要使用多少个处理器内核来运行模型。设置“n_jobs = -1”将使模型运行得最快,因为它使用了您所有的计算机核心。
我们将调整这些超参数:
- n_estimators: 我们的随机森林中“树”的数量。
- max_features: 每次分割的特征数量。
- max_depth: 每棵树可以拥有的最大“分裂”数。
- min_samples_split: 树的节点可以自我分裂之前所需的最小观察次数。
- min_samples_leaf: 每棵树末端的每片叶子所需的最小观察次数。
- bootstrap: 是否使用 bootstrap 为随机森林中的每棵树提供数据。(Bootstrapping 是从数据集中随机取样并替换。)
from sklearn.model_selection import RandomizedSearchCVn_estimators = [int(x) for x in np.linspace(start = 100, stop = 1000, num = 10)]max_features = ['log2', 'sqrt']max_depth = [int(x) for x in np.linspace(start = 1, stop = 15, num = 15)]min_samples_split = [int(x) for x in np.linspace(start = 2, stop = 50, num = 10)]min_samples_leaf = [int(x) for x in np.linspace(start = 2, stop = 50, num = 10)]bootstrap = [True, False]param_dist = {'n_estimators': n_estimators,
'max_features': max_features,
'max_depth': max_depth,
'min_samples_split': min_samples_split,
'min_samples_leaf': min_samples_leaf,
'bootstrap': bootstrap}rs = RandomizedSearchCV(rfc_2,
param_dist,
n_iter = 100,
cv = 3,
verbose = 1,
n_jobs=-1,
random_state=0)rs.fit(X_train_scaled_pca, y_train)
rs.best_params_# {'n_estimators': 700,
# 'min_samples_split': 2,
# 'min_samples_leaf': 2,
# 'max_features': 'log2',
# 'max_depth': 11,
# 'bootstrap': True}
在 n_iter = 100 和 cv = 3 的情况下,我们创建了 300 个随机森林模型,随机采样上面输入的超参数的组合。我们可以调用 "best_params_" 来获得性能最好的模型的参数(显示在上面代码框的底部)。然而,这个阶段的“最佳参数”可能不会给我们最好的洞察力来获得一系列参数,以尝试下一轮的超参数调整。为了获得接下来要尝试的一系列值,我们可以很容易地获得 RandomSearchCV 结果的数据框架。
rs_df = pd.DataFrame(rs.cv_results_).sort_values('rank_test_score').reset_index(drop=True)
rs_df = rs_df.drop([
'mean_fit_time',
'std_fit_time',
'mean_score_time',
'std_score_time',
'params',
'split0_test_score',
'split1_test_score',
'split2_test_score',
'std_test_score'],
axis=1)
rs_df.head(10)
现在,让我们在 x 轴上创建每个超参数的条形图,以及在每个值上建立的模型的平均得分,以查看平均而言哪些值是最成功的:
fig, axs = plt.subplots(ncols=3, nrows=2)
sns.set(style="whitegrid", color_codes=True, font_scale = 2)
fig.set_size_inches(30,25)sns.barplot(x='param_n_estimators', y='mean_test_score', data=rs_df, ax=axs[0,0], color='lightgrey')
axs[0,0].set_ylim([.83,.93])axs[0,0].set_title(label = 'n_estimators', size=30, weight='bold')sns.barplot(x='param_min_samples_split', y='mean_test_score', data=rs_df, ax=axs[0,1], color='coral')
axs[0,1].set_ylim([.85,.93])axs[0,1].set_title(label = 'min_samples_split', size=30, weight='bold')sns.barplot(x='param_min_samples_leaf', y='mean_test_score', data=rs_df, ax=axs[0,2], color='lightgreen')
axs[0,2].set_ylim([.80,.93])axs[0,2].set_title(label = 'min_samples_leaf', size=30, weight='bold')sns.barplot(x='param_max_features', y='mean_test_score', data=rs_df, ax=axs[1,0], color='wheat')
axs[1,0].set_ylim([.88,.92])axs[1,0].set_title(label = 'max_features', size=30, weight='bold')sns.barplot(x='param_max_depth', y='mean_test_score', data=rs_df, ax=axs[1,1], color='lightpink')
axs[1,1].set_ylim([.80,.93])axs[1,1].set_title(label = 'max_depth', size=30, weight='bold')sns.barplot(x='param_bootstrap',y='mean_test_score', data=rs_df, ax=axs[1,2], color='skyblue')
axs[1,2].set_ylim([.88,.92])
axs[1,2].set_title(label = 'bootstrap', size=30, weight='bold')plt.show()
查看上面的图表,我们可以了解每个超参数的每个值平均表现如何。
n_estimators: 300,500,700 似乎平均得分最高。
min_samples_split: 像 2 和 7 这样的较小值似乎得分较高。23 岁也有高分。我们可以尝试 2 以上的几个值,23 左右的几个值。
min_samples_leaf: 较小的值似乎与较高的分数相关…我们可以尝试 2-7 之间的值。
max _ features:“sqrt”平均分最高。
max_depth: 没有明确的模式,但是数值 2,3,7,11,15 似乎做的不错。
bootstrap: “假”平均分最高。
因此,现在我们可以将这些见解^,并进入第二轮超参数调整,以进一步缩小我们的选择。
8.第二轮超参数调优:GridSearchCV
在使用 RandomSearchCV 之后,我们可以使用 GridSearchCV 对我们的最佳超参数进行更精确的搜索。超参数是相同的,但是现在我们使用 GridSearchCV 执行更“详尽”的搜索。在 GridSearchCV 中,尝试超参数值的每一个组合,这比 RandomSearchCV 需要更多的计算能力,在 RandomSearchCV 中,我们可以直接控制我们想要尝试的迭代次数。例如,为我们的 6 个参数中的每一个仅搜索 10 个不同的参数值,使用三重交叉验证将需要 10⁶ x 3 或 3,000,000 次模型拟合!这就是为什么我们在使用 RandomSearchCV 之后执行 GridSearchCV,以帮助我们首先缩小搜索范围。
因此,使用我们从随机搜索 CV 中了解到的信息,让我们插入每个超参数的平均最佳表现范围:
from sklearn.model_selection import GridSearchCVn_estimators = [300,500,700]
max_features = ['sqrt']
max_depth = [2,3,7,11,15]
min_samples_split = [2,3,4,22,23,24]
min_samples_leaf = [2,3,4,5,6,7]
bootstrap = [False]param_grid = {'n_estimators': n_estimators,
'max_features': max_features,
'max_depth': max_depth,
'min_samples_split': min_samples_split,
'min_samples_leaf': min_samples_leaf,
'bootstrap': bootstrap}gs = GridSearchCV(rfc_2, param_grid, cv = 3, verbose = 1, n_jobs=-1)
gs.fit(X_train_scaled_pca, y_train)
rfc_3 = gs.best_estimator_
gs.best_params_# {'bootstrap': False,
# 'max_depth': 7,
# 'max_features': 'sqrt',
# 'min_samples_leaf': 3,
# 'min_samples_split': 2,
# 'n_estimators': 500}
在^,我们正在对 3x 1 x 5x 6 x 6 x 1 = 540 个模型拟合执行三重交叉验证,总共有 1,620 个模型拟合!现在,在执行了 RandomizedSearchCV 和 GridSearchCV 之后,我们可以调用“best_params_”来获得一个最佳模型来尝试和预测我们的数据(显示在上面代码框的底部)。
9.根据测试数据评估模型的性能
现在,我们可以评估我们根据测试数据建立的每个模型。请记住,我们正在测试 3 种模型:
- 1.基线随机森林
- 2.PCA 降维的基线随机森林
- 3.使用 PCA 降维的基线随机森林和超参数调整
让我们生成每个模型的预测:
y_pred = rfc.predict(X_test_scaled)
y_pred_pca = rfc.predict(X_test_scaled_pca)
y_pred_gs = gs.best_estimator_.predict(X_test_scaled_pca)
现在,让我们为每个模型创建混淆矩阵,看看每个模型预测乳腺癌的能力如何:
from sklearn.metrics import confusion_matrixconf_matrix_baseline = pd.DataFrame(confusion_matrix(y_test, y_pred), index = ['actual 0', 'actual 1'], columns = ['predicted 0', 'predicted 1'])conf_matrix_baseline_pca = pd.DataFrame(confusion_matrix(y_test, y_pred_pca), index = ['actual 0', 'actual 1'], columns = ['predicted 0', 'predicted 1'])conf_matrix_tuned_pca = pd.DataFrame(confusion_matrix(y_test, y_pred_gs), index = ['actual 0', 'actual 1'], columns = ['predicted 0', 'predicted 1'])display(conf_matrix_baseline)
display('Baseline Random Forest recall score', recall_score(y_test, y_pred))
display(conf_matrix_baseline_pca)
display('Baseline Random Forest With PCA recall score', recall_score(y_test, y_pred_pca))
display(conf_matrix_tuned_pca)
display('Hyperparameter Tuned Random Forest With PCA Reduced Dimensionality recall score', recall_score(y_test, y_pred_gs))
下面,我们有我们劳动的最终成果:
我们使用召回作为我们的性能指标,因为我们正在处理癌症诊断,并且最关心的是最小化我们模型中的假阴性预测错误。
考虑到这个^,看起来我们的基线随机森林模型做得最好,具有最高的召回分数 94.97% 。给定我们的测试数据集,基线模型正确预测了总共 179 名实际患有癌症的人中有 170 名患者患有癌症。
这个案例研究提出了一个重要的注意事项:有时,在 PCA 之后,或者甚至在广泛的超参数调优之后,一个调优的模型的性能可能不如一个普通的老式“普通”模型。但是尝试是很重要的。你永远不知道哪种模式会做得最好,除非你都尝试过。就预测癌症而言,模型越好,就能拯救越多的生命。
希望这有所帮助!快乐造型!
学校不教机器学习的东西
原文:https://towardsdatascience.com/machine-learning-stuff-schools-do-not-teach-f2869f964b78?source=collection_archive---------11-----------------------
现实生活中的机器学习项目不仅仅是机器学习。
马库斯·温克勒在 Unsplash 上的照片
如果你是一个渴望进入这一领域的机器学习/数据科学爱好者,那么很有可能你一定上过 Coursera 或 Fast.ai 的深度学习专业,或者来 Kaggle 练习和打磨过你的技能。这些都是很好的学习材料,将为你提供扎实的知识和良好的培训经历。
然而,从训练场到战场还有很大的距离。学校、课程、竞赛只关注机器学习算法,这在现实生活中的机器学习项目中只占很小一部分。还有一些其他的东西,课程和比赛是帮不上忙的,只有当你的脚在现实世界中站稳了,你才能学会。
作为一名机器学习工程师,一年的工作极大地影响了我的思维模式和机器学习项目应该如何执行的实践。在这篇文章中,我将分享我在第一年学到的一些经验。
问题陈述
培训:让我们解决问题。现实生活:什么问题?
在上课或参加比赛时,我通常会收到由机器学习专家制作的机器学习 问题和问题。自然,它带有非常清楚的说明:目标、数据集、背景和解释等。我的工作只是处理数据并产生结果,没有任何问题被问及。
在现实生活中,我遇到的是业务团队和/或产品团队要求的业务问题。因此,应该预料到,在没有提供说明的情况下,问题陈述可能会令人困惑和含糊不清。即使事情看起来很清楚,也不能确定我解释问题的方式和业务团队的是一样的。所以,我的第一个任务不是解决问题,而是向提问。
举个例子:我在一家电子商务公司工作。一天,一位产品经理给了我一件购物品,让我在市场上找出最相似的商品。在考虑协同过滤或其他奇特的算法之前,我需要问一些非常基本的问题,比如:
- 定义物品 X 和物品 y 的“相似度”,同一个品牌?相同的产品类型?还是买产品 X 的用户总是买产品 Y?
- 商业目的是什么?来推荐类似的物品?建立收藏?或者检测重复的项目?
- 我是在建立在线服务还是离线数据库?
- 任务的时间表和路线图是什么?
随着我获得的经验越来越多,我需要开始采取主动,即确定业务需求、提出问题、问自己这些问题并找到自己的答案。
数据集
培训:我们来分析数据。现实生活:什么数据?
在训练或比赛中,这是一个公平的游戏,每个人都可以平等地访问相同的数据集。结果的质量很大程度上取决于算法。
现实生活不是一个公平的游戏。对于许多企业来说,数据是他们最大的资产,决定项目成功的是数据,而不是模型。我工作得越多,就越发现自己问了一些在学校时从未被关注过的问题:
- 有哪些可用的数据来源?如何访问它们?
- 数据有标签吗?如果没有,如何给它们贴标签?如果是,标签质量好吗?
- 我的算法有足够的数据吗?如果没有,如何获取更多数据?如果有,如何处理这么大的数据?
数据的可用性、质量和数量对项目的每一步都有决定性的影响。如果数据不好,那么每个机器学习模型看起来都是糟糕的选择。如果数据是好的,那么即使-否则规则也能起作用。我经常听到人们说数据科学家花 80%的时间寻找和处理数据,现在我知道他们说的是实话。
刚开始工作的时候,经常问同事用什么算法/库。这些天,我问的第一个问题是:“你是如何获得你的训练数据的?”
算法
培训:让我们建立模型。现实生活:让我们建立管道。
在训练中,数据量小到可以装进单机,项目范围小到可以压缩到单台笔记本。因此,在 Pandas、Pytorch Dataloader 等工具的帮助下,几行代码就可以为模型准备好我的数据。
在现实生活中,事情要完成得多。数据量和项目复杂性要求我处理数据加载、数据处理、模型评估等。,每个都有单独的组件。有时我还需要担心设置机器、调度、数据版本控制、代码版本控制等等。正如谷歌在这篇论文中所阐述的,机器学习只是项目的一个非常小的组成部分,因此,最好不要在开始时过多关注它。
机器学习组件只是整个管道的一小部分。图片来自这篇论文。
随着时间的推移,我形成了一种习惯,即当开始一个项目时,当务之急是快速建立一个完整的端到端管道,并用一个小数据集进行测试。此时,我只需要运行东西,性能还不是我关心的。这不仅适用于机器学习组件,也适用于管道的其他部分。一旦事情开始运行,需要改进的地方就可以被识别出来,然后一次一个地进行改进。这有助于我轻松确定瓶颈,并为项目制定更好的计划。
训练:让我们使用先进的模型,像职业选手一样。现实生活:让我成为 noob。
我曾经认为,使用先进的模型,或者更确切地说,从零开始构建它们,是专业知识的标志。因此,在训练中,为了完善我的投资组合,或者在排行榜上获得 0.01 分,我倾向于选择更复杂、更花哨的模型。我有时间,而且数据集很小,为什么不试试呢?
然而,在现实生活中这样做可能是愚蠢的表现。复杂的模型不太适用,原因有很多:
- 培训要花公司更多的钱。
- 它需要花费更多的时间来设置,并且对于每次训练迭代来说更是如此。这减少了我发现问题并做出改进的反馈循环的数量。
- 其结果更难解释。想象一下,如果我使用 XLNet 进行垃圾邮件检测,结果会变得很糟糕,我不知道在这 340 万个参数中,哪里出错了。
- 我的瓶颈可能是别的,而不是模型。想象一下,如果我花了 2 周时间构建多层集成模型,只是为了意识到糟糕的性能是因为我的地面真实数据被错误地标记了。
因此,我目前选择机器学习模型的程序如下:
我选择算法的程序。
我学到的关于算法的其他一些经验:
- 领域知识和良好的数据可以击败任何模型。
- 目标不是建立模型,而是在合理的时间和资源内解决问题,并产生合理的结果。
估价
训练:预测完成,工作完成。现实生活:没那么快!
在培训中,评估指标与问题一起明确定义。还有一个排行榜,用来比较我的型号和其他型号的性能。因此,当我的模型输出结果时,我可以马上提交结果,瞧,任务完成了。
在现实生活中,事情不会在预测完成后就停止。
- 更多的时候,我需要自己定义评估指标,这并不总是微不足道的。
- 输入数据通常是有噪声的,因此来自训练测试分割的结果可能是不可靠的。因此,需要一种更有说服力的评估方法,如人工检查,或 A/B 测试。
- 模特的良好表现是一回事,得到经理的认可是另一回事。恰当的沟通,好的故事,以及具体的支持数据,总是需要的。
- 输出的数据/模型/服务需要正确地传递给管道的下一个过程,以及正确的文档。
结论
很多课程只是关注机器学习算法,大部分比赛只是建立机器学习模型。然而,算法和模型只是现实项目中非常小的一部分。一个执行良好的项目还需要适当的问题陈述、良好的数据源、坚实的工程结构、顺畅的数据管道、可解释的结果以及可靠、令人信服的评估指标。
以上只是我作为机器学习工程师工作第一年后学到的许多宝贵经验之一。查看我以前的一些帖子这里和这里,并继续关注更多有趣的故事。
感谢您的阅读。
机器学习:监督学习
原文:https://towardsdatascience.com/machine-learning-supervised-learning-8c5331c485f5?source=collection_archive---------60-----------------------
图片由亚历山德罗·迪·克雷迪科 在 Unsplash 上拍摄
就像人类能区分果酱和果冻一样(或者我们能吗?),在机器学习的帮助下,现在机器也可以对它们看到的物体进行标记和分类。但是他们必须为此接受训练。让我们看看这意味着什么…
在这篇文章中,我想回顾一下机器学习中一个非常重要的话题——监督学习。这是业内使用的最流行的机器学习形式。看完这个帖子:
- 你将能够理解什么是监督学习以及它是如何工作的
- 你将了解监督学习的类型
- 您将了解一些示例算法和实际应用
我们可能想先从基础开始,快速浏览机器学习的定义,以涵盖所有基础。
机器学习
机器学习是一个与构建系统或程序有关的研究领域,这些系统或程序能够在没有明确编程的情况下学习。机器学习系统接收大量数据,然后从中学习模式和标签,基本上是根据从未见过的数据预测信息。
从感悟中学习| 形象由 布拉塞克 上 下
下面是机器学习的一个流行定义:
如果由 P 测量的计算机程序在 T 中的任务上的性能随着经验 E 而提高,则称该计算机程序从关于某类任务 T 和性能测量 P 的经验 E 中学习
汤姆·米切尔
我知道这很难完全理解,所以让我把它分解成更简单的术语。将经验视为数据,将任务视为利用该数据预测某事,将绩效评估视为预测实际上是否正确的答案。
让我们举个例子。假设我们正试图为 Google 构建下一代垃圾邮件过滤系统,以便直接在 Gmail 中使用。这将意味着体验将接收数百万封电子邮件,任务将预测特定电子邮件是否是垃圾邮件,而性能将通过分析该系统的预测实际上是否正确来衡量。
垃圾邮件与非垃圾邮件|图片由埃克塞特大学提供
机器学习模型
机器学习模型是一种算法,它已经用某种特定类型的历史数据进行了训练,通过将它应用于从未见过的数据来预测某些事情。它可能是一个类别标签、一个数值,甚至可能是数据中一些有趣的模式,以构建有影响力的见解。
机器学习模型的这项任务完全取决于手头的问题,这也决定了我们要使用什么样的数据。我们试图解决的机器学习问题也决定了我们实际上如何处理这个问题。
我们在训练数据中有输出吗?
如果是,输出什么样的数据?离散类还是数值?
作者的完美(角色)模型| 图片
培训记录由特征组成。顾名思义,它们是我们正在处理的数据的属性——数据所涉及的对象的特征或属性。
一个标签是一种告诉机器学习模型它应该在新数据中寻找的东西是否实际存在于这个特定的训练记录中的方式——这就是我们正在预测的。这些是离散值,机器学习模型可以预测从未见过的数据。对于这样的机器学习问题,特征是输入,标签是输出。
机器学习模型可以工作的另一种方式是通过预测数值。假设我们正在处理汽车数据。我们有过去 10 年的汽车价格数据。该数据包含诸如公司、制造年份、功率、汽车类型等特征。等等。作为特征,当然汽车价格作为输出。在这种情况下,我们将建立一个机器学习模型,它会吸收所有这些特征,并告诉我们新车的价格。
你认为这要花多少钱?|图片由 Yerson Retamal 来自 Pixabay
回到我们的 Gmail 垃圾邮件过滤器,我们会用数百万封电子邮件来训练机器学习模型。在这种情况下,特征将是电子邮件主题、电子邮件正文、电子邮件:发件人字段等。每封邮件我们都会贴上“垃圾邮件”或“非垃圾邮件”的标签。通过这种方式,模型可以区分哪些电子邮件要通过,哪些电子邮件要过滤掉。
当然,会有大量的数据预处理,以编码或嵌入的形式将文本和电子邮件内容的其余部分转换为机器学习模型可以理解的内容。如果你想更深入地了解机器学习或数据预处理的定义,一定要看看这些文章
[## 那么什么是机器学习呢?
你可以很容易地找到许多机器学习的流行用例。我敢肯定,当你需要购买新的…
thedatascienceportal.com](https://thedatascienceportal.com/posts/so-what-is-machine-learning/) [## 数据预处理:概念
本文的目的是介绍数据预处理中使用的概念,数据预处理是机器…
thedatascienceportal.com](https://thedatascienceportal.com/posts/data-preprocessing/)
机器学习有两种形式:
- 监督机器学习
- 无监督机器学习
本文的范围仅仅是解决有监督的学习,但是不要担心,当你向下滚动时,你会发现一篇专门讨论无监督学习的文章的链接🙂
监督学习
监督学习是机器学习的一种形式,其中我们的机器学习模型的输入和输出对我们来说都是可用的,也就是说,我们通过简单地查看数据集就知道输出会是什么样子。“受监督”这一名称意味着输入要素与其各自在数据中的输出之间存在关系。我们实现的任何机器学习算法的目标都是通过估计这种关系来预测从未见过的数据的新的但相似的输出。
大图描绘的数据集| 图片由 Unsplash 组成
例如,像识别任何图像中是否存在橙子这样的问题是机器学习模型可以处理的。另一个,可能更有用一点,可以识别某段文本是否包含亵渎。
你可以看到这两个问题显然是非常不同的。让我们看看下表:
数据集比较|按作者分类的图像
但同时,这两个问题又很相似……怎么会呢?
在这两种情况下,我们将使用数据训练一个机器学习模型,其中每个训练记录和实际数据都包含一个标签。该标签将告诉我们橙色是否出现在图像中(是/否),或者在特定文本中是否确实存在亵渎(干净/肮脏)。换句话说,机器学习模型应该从一组已知的可能结果中选择结果。这组可能的结果由数据中存在的标签组形成。该模型试图在其训练期间学习输入特征和输出标签之间的关系。
- 在垃圾邮件检测问题中,该模型将分析新邮件,并为其给出“垃圾邮件”或“非垃圾邮件”的标签
- 在橙色检测问题中,模型将分析新图像,并告诉我们图像中是否存在橙色——“是”——或“否”
现在,如果我们重温之前的汽车价格预测问题,我们会注意到它也有些类似。这里的数据也包含了每辆汽车的特性,如公司、制造年份等。等等。随之而来的是价格。在这种情况下,机器学习模型应该根据它在训练期间从历史数据中学习的关系来估计或预测新车的价格。
基于此,现在让我们进入本文的最后一部分。监督机器学习问题可以有两种类型:
- 分类
- 回归
分类
垃圾邮件过滤器、橙色检测问题和亵渎检测问题是机器学习问题,其中我们似乎有正确定义和离散的标签作为输出。因此,机器学习模型只需根据它在训练期间从历史数据中学习到的内容来告诉我们标签。这种监督学习称为分类。
那些离散的标签通常被称为类,任何这样的监督机器学习问题都被称为分类问题。一些最流行和最广泛使用的机器学习用例是分类问题,因此一些最广泛使用和实现的机器学习算法是分类算法。仅举几个例子:
- 朴素贝叶斯分类器
- k-最近邻
- 逻辑回归
- 支持向量机
- 决策树
- 随机森林
- 神经网络
分类 vs 回归| 图像通过 分析 Vidhya
回归
之前的汽车价格预测问题是一个机器学习问题,其中我们没有离散的标签或类别,而是根据每辆汽车的价格,我们有连续的数值。通过对历史汽车价格数据进行训练,机器学习模型将学习汽车功能与其价格之间的关系。然后,它将能够通过观察新车的特征来预测其价格。
在这种情况下,我们有一个连续的输出变量,一个数值,它直接取决于存在的特征。对于监督回归问题,人们谈论最多的用例之一是股票价格预测。虽然很难找到训练模型的完美数据集,但人们使用样本数据的回归技术来粗略估计真实世界的情况,以便在股市中做得更好。回归中的一些算法:
- 线性回归
- 多变量回归
- 套索回归
- 里脊回归
我希望这篇文章能让你对监督机器学习这个话题有所了解。这是数据科学和机器学习中一个非常重要的话题,比其他一些很酷的东西更容易理解和解释——这在商业世界中非常有价值。在商业世界中,ML 模型的可解释性是非常可取的,因为大量的资金被投入到每一件事情中,并且期望模型输出不仅被商业界理解,而且被消费者理解。
感谢您的阅读!
原载于 2020 年 11 月 15 日【https://thedatascienceportal.com】。如果您喜欢这篇文章并希望看到更多此类内容,请访问数据科学门户网站!
无监督的机器学习—
[## 机器学习:无监督学习
这里发生的事情是,我们完全基于我们真正看到的东西进行模式识别,这也是…
thedatascienceportal.com](https://thedatascienceportal.com/posts/unsupervised-learning/) [## 数据科学门户
我肯定你上过网飞、脸书和 YouTube。你看到你喜欢的东西,你和它互动-你喜欢一个…
thedatascienceportal.com](https://thedatascienceportal.com)
图上的机器学习任务
原文:https://towardsdatascience.com/machine-learning-tasks-on-graphs-7bc8f175119a?source=collection_archive---------19-----------------------
可以分为有监督/无监督学习吗?没那么简单…
缺少友谊联系的动物友谊网络。图标由图标 8
相关文章
- 图的特征提取
- 走向可解释图神经网络
- 图形神经网络的 10 大学习资源
图表是一种有趣的数据类型。我们本可以认为,我们可以用与“正常”数据相同的方式进行预测和训练模型。令人惊讶的是,机器学习任务在图上的定义非常不同,我们可以将其分为 4 种类型:节点分类、链接预测、整个图的学习和社区检测。在这篇文章中,我们仔细研究了它们是如何定义的,并理解了为什么它们与标准的机器学习任务如此不同。
节点分类
让我们想象一下,我们有一个动物之间的友谊网络。动物可以是一只狗,一只猫,或者一只鸭,我们可以用额外的特征来描述它,例如体重、和颜色。两种特定动物之间的联系意味着它们彼此喜欢。鉴于这种友谊网络和特征,我们的目标是预测动物的缺失类型。这种预测任务被称为节点分类。
缺失节点标签的动物友谊网络。图标由图标 8 表示
让我们将符号形式化。数学上,我们可以把这个动物友谊网络定义为 G = (V,ε),其中 V 是节点(动物),E 是边(友谊连接)。此外,每个节点具有各自的特征向量xI(重量、高度和颜色),其中 i 意味着该向量属于节点VI。节点分类任务的目标是给定节点V i 及其邻居,预测标签 y i 。
现在,我们如何使用机器学习模型来预测这些动物类型?大部分机器学习模型都是基于数据点相互独立的事实( i.i.d 假设)。这里这个假设失败了,因为节点标签(动物类型)可能依赖于其他相邻节点[1]。例如,更有可能的是,更靠近猫的集群的节点也是猫。相似的节点通常靠得更近,这就是所谓的。
因为在这种情况下数据独立性不再起作用,所以我们不能将这种分类任务归类为监督学习。它经常被研究人员称为半监督学习,因为我们可以使用来自相邻节点的信息来预测某个节点【1】。
链接预测
链路预测的目的是确定两个节点之间是否存在连接。在我们之前的动物友谊图的例子中,它只是预测相邻的动物是否是朋友。
缺少友谊联系的动物友谊网络。图标按图标 8
类似于节点分类,我们也可以利用邻域信息来预测两个节点之间的链接。一组流行的链路预测方法被称为启发式方法【2】。他们从图本身计算某些分数,并将其转换为两个节点之间链接的可能性。启发式方法可以被必须发生的邻居跳的最大数量所划分[2]。例如,公共邻居是一种一阶试探法,因为它只需要节点的直接邻居来计算分数(而不是邻居的邻居)。在下图中,我们可以看到节点V1 和 V 3 的第一邻域。
V 1 和 V 3 节点有两个公共邻居: V 6 和 V 2。图标由图标 8
青蛙 V 1 和 V 3 有两个共同的朋友(相邻节点): V 6 和 V 2。利用这个简单的分数,公共邻居算法决定两个节点之间是否有链接。
当然,还有更复杂的方法,例如,资源分配(二阶试探法),它使用来自二阶跳跃的信息[2]。在节点 V 5 的情况下,RA 将使用其算法 V 4 和 V 6 从第一个邻域和 V 1 和 V 3 其他方法可以使用更高阶的试探法来生成用于链接预测的图形特征。
类似于节点分类,链接预测也被称为半监督学习,因为我们使用邻域信息来预测两个节点之间的链接。
对整个图形的学习:分类、回归、聚类
我们换个例子。考虑一下,我们现在有一个分子数据,我们的任务是预测给定的分子是否有毒。下图显示了如何使用图形神经网络来设计此分类任务。
图形数据分类任务概述。每个分子可以表示为一个单独的图形,并被视为 i.i.d 数据点。分子的图片取自【3】。突出显示的红色部分显示了引发毒性反应的分子部分。这与本文无关,所以请忽略这个突出显示的红色部分。如果你有兴趣了解更多,请看[3]
我们可以把每个分子看作一个独立的图,其中一个原子是一个节点,原子之间的连接是一条边。这是一个在整个图中进行分类任务的例子。这里的不同之处在于,我们得到了不同图形的多个实例,并在这些实例上训练我们的模型[1]。我们学习整个图形,而不是预测单个图形中的特定组件,如节点或边。
在多个图形实例上的学习任务的引人注目之处在于,数据点被认为是I . I . d .。这意味着图形上的学习任务与标准机器学习问题中使用的分类、回归和聚类任务非常相似,如果不是相同的话。这对我们来说是个好消息,因为我们可以重用标准机器学习算法的方法,如 RandomForest、SVMs 或 XGBoost。
社区检测
简而言之,图的社区检测可以被认为是一个单个图中节点的聚类任务。让我们看看下面的一个例子,展示了一个科学家网络,他们至少共同撰写了一篇论文。
这张图片展示了一个科学家网络,他们至少共同撰写了一篇论文。我们可以看到在不同领域工作的科学家聚集在一起。图片取自【5】。
在这里,社区检测的任务将是识别这些在不同领域工作的科学家集群。虽然看起来很直观,但社区的聚类定义相当模糊,并且在不同的数据集之间大小和形状不同[4]。社区也可能重叠,这使得区分它们变得更加困难。
凭直觉,我们可以怀疑社区内部的节点将有更多的连接到相邻的边。还会有边更少的节点连接不同的社区。这些是大多数社区发现算法所基于的理论基础。有许多不同类型的社区检测算法,但最流行的是基于谱聚类、统计推断、优化和动态【6】的方法。
总结
我们已经看到,在图上有 4 种主要类型的机器学习任务:节点分类、链接预测、整个图的学习和社区检测。这些任务中的大多数与正常的监督/非监督学习非常不同。这是因为图形是相互连接的,数据独立性假设不成立。研究人员称之为半监督学习。
关于我
我是阿姆斯特丹大学的人工智能硕士学生。在我的业余时间,你可以发现我摆弄数据或者调试我的深度学习模型(我发誓这很有效!).我也喜欢徒步旅行:)
如果你想了解我的最新文章和其他有用的内容,以下是我的其他社交媒体资料:
- 领英
- Github
参考
[1] 林子幸·汉密尔顿的《图形表示学》一书
[2] 基于图形神经网络的链路预测
[3] 用于学习分子指纹的图上的卷积网络
[4] 图中的社区检测
[5] 社会和生物网络中的社区结构
[6] 网络中的社区检测:用户指南
用于调查报告的机器学习技术
原文:https://towardsdatascience.com/machine-learning-techniques-for-investigative-reporting-344d74f69f84?source=collection_archive---------22-----------------------
一个简短的机器教程,介绍了一系列分析数据、发现偏差和做出预测的技术,以及所有这些如何有助于向编辑推销新故事。
来源:Dreamstime
当你想到新闻业中的机器学习(ML)时,你听到的例子往往是大胆的。有些非常复杂,并且是为非常具体的用例定制的。例如,机器学习模型可以被记者用来识别泄露给国际调查记者联盟的 20 万份文件中的商业计划、财务报表或纳税申报表。
诸如此类的例子令人眼花缭乱。但问题是,对于刚刚起步的人来说,它们真的没有什么帮助。为了探索机器学习在数据新闻中的用途,我们需要从更基础的层面开始。本教程将从这个层次开始,并希望展示如何让 ML 作为一个记者为你工作。
为什么是这个教程?去年关于“为你的调查性报道提供开源卫星数据的教程非常成功,今年的教程采用了类似的机器学习方法。三个部分,从简单开始,越来越复杂。
机器学习和特征选择
我们来看看机器学习和特征选择(特征选择的解释者这里)。目标是在以自动化方式分析数据的过程中帮助您。更不是胡乱预测。听起来有点适得其反?您将很快看到它在数据调查中是如何有用的。
在我们开始之前,我想强调我不是专家,只是一个爱好者。我在我的报道中使用了一些技巧,真的只是为了让我的生活更轻松。数据科学的复杂性有一个完全不同的世界。我们只会触及表面,让它变得实用和有用
你需要什么:
您需要在笔记本电脑上安装 R:
= >下面是如何在 Mac OC 和 Windows 上安装 R。
= >如何安装 R 的集成开发环境 R-Studio
我们将向您展示如何为分类和回归任务进行特征选择。数据科学家一直使用它来提高模型的性能,同时优化训练时间。但是在这里我们不太关心这个。对我们和我们的读者来说,更有趣的是我们的数据是如何运转的。在几个例子中,我们将向您展示如何回答诸如“是什么让我们的数据中的某些人口统计数据投票给英国退出欧盟?’(第一部分),什么对臭氧读数影响最大?’(第二部分)和’什么特征让人们赚得更多(以及)我们在数据中是否发现了偏见的痕迹?’(第三部分)。
“递归划分和回归树”方法:
一个两秒钟的介绍,介绍 journos 如何在他们的故事中使用树模型和可视化:
阿曼达·考克斯的故事就是一个最好的例子。她在为《纽约时报》报道美国大选结果时使用了这个词。
阿曼达·考克斯·NYT
另一个例子是 Stefano Ceccon 的。他为《泰晤士报》数据团队建立了一个英国选举分类树。
几年前,我使用 R-Studio svg 输出功能为英国《金融时报》一项关于中国 iPhone 购买习惯的消费者调查绘制了一幅可视化图。
2017 英尺件
决策树模型在记者中很受欢迎,因为它们本质上很简单,更容易向读者解释。有人称之为直觉。为什么直观?有人说它们类似于人类在分类方面的决策。如果一个人知道数据中的所有概率,他或她会采取类似的行动。用于回归和分类任务的其他模型类型可能与此非常不同。决策树的图形输出也有助于向编辑推销。我们在上面看到了一些例子。
决策树模型从一开始就有一些缺点:与其他模型类型相比,它们的预测准确性可能较低。此外,数据中的微小变化可能会导致最终树的显著变化,从而降低树的健壮性。在我们下面的随机 Forrest 编码示例中,我们将展示如何通过在一个模型中聚集许多树而不是一个来克服这个问题。还有像装袋和助推这样的方法可以帮助你的模型。
1.英国退出欧盟的例子
我们将使用英国选区的数据集来调查哪些因素促成了英国的英国退出欧盟投票。我们考虑各种年龄和投票人口统计。我们想知道哪些列对投票最有预测性。
我合并了人口普查数据和 2016 年英国退出欧盟公投的数据。现在,想象一下这个包含 32 列的数据集放在您的桌子上。你的编辑要求你调查你的后续报道应该密切关注哪些人口统计数据。
对脱欧投票最有预测力的是什么?
这里的主要关注点是选民是否投票支持脱欧。所以二进制分类。如果投票份额高于 50 %,则“Leave.percent”采用因子值“Leave ”,如果低于 50 %,则采用“remain”。
让我们用下面的代码将数据加载到 R-studio 环境中。
我们在数据中的变量的品尝者:
- 类型: 苏格兰 或 英格兰/威斯区
- 人口的年龄: 年龄. 0 至. 4 , 年龄. 5 至. 9 , 年龄. 10 至. 14 …
- 计票: 有效票、否决票%等。
- 最终变量,输出结果变量:' '百分比。离开’。'要么' 离开 '要么' 留在 '
现在我们需要一个模型。这是一个分类任务。决定' 是离开 还是' 保持。 所以我们选择决策树模型。这是监督学习中使用最广泛、最实用的方法之一(简短说明此处)。为了适应决策树模型,我们使用了 rpart 包(rpart 包的插图)。
rpart 只是在 r 中创建“递归分区和回归树”的一个选项。运行它的一般格式是(不要运行它):
该函数的第一个参数是一个模型公式,符号{(波浪号)代表“被建模为”。在波浪符号的左边,我们告诉模型结果变量。在我们的例子中是“百分比”。离开”(这是‘离开’还是‘留下’)。在右边,我们命名所有我们希望模型考虑的变量。
因为我们想探索对“百分比”来说什么是最重要的。“离开”,我们将所有其他 31 个变量/列抛向模型。我们用“百分比”来表示。离开。”(圆点是数据中“所有其他变量”的缩写。它节省了我们的工作,因为我们不必写出数据中的所有变量:*'百分比。离开类型+编码+全部。居民+0 岁至 4 岁+10 岁至 14 岁…'。*
我们需要把数据分成两组。我们稍后会检查准确性。我们对我们的测试和训练数据应用 70:30 的分割(这不是一成不变的,而是通用的方法。有人不同意这里。如你所料,训练集[英国退出欧盟 _ 训练]是用来训练模型的。测试集[英国退出欧盟测试]是一个虚拟的生产环境,以测试预测,评估准确性和条件。
现在,在加载包之后,让我们构建。我们的英国退出欧盟 _ 模型如下:
在 R-Studio 控制台上,您现在应该可以看到所有分割的统计数据。
让我们用 rpart.plot 可视化我们的决策树(vignette 这里):
我们可以改变我们的决策树可视化,以获得更有说服力的演示。一个选择是 ggparty 包,在引擎盖下使用 ggplot (向新 ggparty 包的创建者马丁·博尔科维克和尼亚兹·马丁致敬,同时查看路易斯·维德·阿雷戈蒂亚关于此事的帖子)。
ggparty 型号:ctree
这种表示法的好处是,我们可以在节点级别获得关于观察值数量的明确数据,以及定义分裂的预测值(Arregoitia)。
从上面的两个视图中,我们已经可以看出类型以及一个特定的年龄人口统计比其他 29 列更重要。**
修剪树:
修剪决策树意味着修补我们的决策树 rpart 模型中的 CP 参数。我们想减少交叉验证的误差。为了得到最优 CP,我们使用plot CP来绘制它。**
printcp 和 plotcp 揭示了每个 nsplit 的交叉验证误差,并可用于“修剪树”。交叉验证误差(xerror)最小的一个就是 CP 的最佳值。
****
最佳复杂度参数(CP)值在具有最低 xerror 值的行中。
我们相应地更新了基本模型:
有了我们修剪过的树模型,让我们计算树的 精确度 。请记住,我们测试的是之前放在一边的看不见的测试数据:
**[Output]: 0.9292035**
我对自己 92%的准确率感到满意。你叫什么?
但是如果我们想快速知道哪些变量在你训练好的 rpart 决策树模型中最重要呢?我们可以简单地获取variable . importance参数并用 ggplot 可视化它。这可能是编辑在决定是否把故事委托给你时唯一真正感兴趣的部分。
啊!我们发现,对于我们的车型类型(威尔士/英格兰或苏格兰)以及 25 至 34 岁年龄段的人口统计数据,有一些最大的“信号”。本身并不是突破性的新闻。但是请在您的下一个包含数百个列的分析速度的背景下查看它。您自己的数据探索过程现在仅使用几行代码来告诉您的编辑数据框中有什么。
Boruta 方法:决定放弃哪个特征,保留哪个特征:
另一种选择特性的方法是使用 Boruta 和同名的 R 包。“Boruta”可以用来决定变量是否重要。这是一个基于 随机福里斯特 模型的特征选择算法(下面是一个详细的例子)。
有趣的事实:博鲁塔这个名字来自斯拉夫神话中的一个恶魔,据说他住在松树林里。没印象?更多在此贴。
让我们执行 Boruta 搜索:
**[Output]:
# Boruta performed 99 iterations in 15.63705 secs.
# 29 attributes confirmed important: Age.0.to.4,
# Age.10.to.14, Age.15.to.19, Age.20.to.24,
# Age.25.to.29 and 24 more;
# 1 attributes confirmed unimportant:
# Writing.or.Mark;
# 1 tentative attributes left: No.Official.Mark;**
绘制它:
用于功能选择的 Boruta 包
太好了!右边是你非常重要的特征。令人高兴的是,箱线图还显示了异常值,亮绿色的最小值、最大值、第一个和第三个四分位数、中间值以及四分位数之间的范围(关于箱线图的信息此处为)。
2。数值数据:通过'相对重要性 ': 找到有价值的变量**
示例:臭氧数据集
如果你有数字数据要分析和预测,一个选择是线性模型(lm,这里是解释者)。我们可以使用它来执行回归任务,也可以用于单层方差分析和协方差分析。相对重要性为我们提供了一种方法来决定哪些变量对我们的研究有最大的价值。
首先,我们将臭氧水平数据读入 R(感谢塞尔瓦·普拉巴卡兰的 GitHub 账户)。
现在,因为我们所有的列都是数字数据,所以我们可以运行一个关联图来查看哪些列相关。您可以使用 PerformanceAnalytics 包来实现这一点(但是还有许多其他的包)。
PerformanceAnalytics viz(作者的红线和绿线)
假设我们对作为结果变量的臭氧水平感兴趣。从图中我们已经可以看出哪些特征与臭氧读数相关。那么,哪一个数值变量(与之前英国退出欧盟数据中的分类变量相反)对臭氧水平影响最大呢?
使用 calc.relimp { relaimpo },输入 lm 模型的变量的相对重要性,我们可以确定相对百分比:
我们的模型表明,“温度 _ 艾尔蒙特”相对来说比“温度 _ 桑德堡”更重要(尽管在我们的相关图中相关系数略高)。从这里,您可以开始更传统的数据驱动的报告,并调查为什么这个变量会出现在顶部。
3。途径 【随机森林】
示例:带有随机福里斯特的收入数据集
在最近的一次调查中,我检查了西米德兰兹郡警察罪犯预测模型是否可能因在训练模型中包含有争议的数据集而遭受种族偏见。运行随机 Forrest 可以帮助您发现执法数据模型中使用的数据的偏差。
下面我们看到了西米德兰兹郡警察部队的模型中最重要的预测因素列表。如果你对可能有争议的模型进行调查,我建议让数据科学家公开他们的特征重要性。这可能会带来有价值的报道。
E&T 关于西米德兰兹郡警察罪犯预测模型的调查
出于我们的目的,我们将使用一个关于人口统计和工资的普通数据集。但这种数据可能来自泄漏或数据泄露。我们的数据列出了超过 8,000 个人的各种人口统计数据(这是一个常用于训练模型的数据集)。让我们假设一个告密者把这些数据通过电子邮件发给你。也许它来自你正在调查的一个有争议的实体。你的编辑要求你检查人们工资背后的驱动力。偏见有什么合理的说法吗?
在收入数据集中,我们有 14 个变量(包括性别,婚姻。状态等。).
我们将建立一个随机福里斯特模型来分类收入阶层。然后检查特征重要性。我们还将优化我们的模型,并针对传统的决策树模型运行它(类似于本教程第一部分中关于英国退出欧盟数据的内容)。哪个表现更好?).
让我们把数据载入并混洗一下。然后替换 NAs(空单元):
我们运行一个简单的随机福里斯特模型,并在适当的位置设置默认参数。现在到了有趣的部分。哪些栏目最能说明各种收入类别?
不出所料,所有的专栏都贡献了一些份额。但有些人比其他人多得多。职业似乎是最能说明问题的特征,还有年龄。顺便说一句,这类似于天普大学的研究人员在什么对未来财富影响最大的问题上的发现。如果性别和种族排名靠前(或靠后),这就提出了一些有趣的问题,我们作为记者可能想继续调查。
我们不是为此而来。但是它可以给你一个钩子来进一步调查对群体的偏见或不公平待遇。
其他后续调查可能需要说明哪些职业在每个收入类别中被提及的频率最高?我们为此创建了一个模式函数。你看到我看到的了吗?
**[Output]:
INCOME mode
1 -10.000) Student, HS or College
2 [10.000–15.000) Clerical/Service Worker
3 [15.000–20.000) Professional/Managerial
4 [20.000–25.000) Professional/Managerial
5 [25.000–30.000) Professional/Managerial
6 [30.000–40.000) Professional/Managerial
7 [40.000–50.000) Professional/Managerial
8 [50.000–75.000) Professional/Managerial
9 [75.000- Professional/Managerial**
优化随机福里斯特模型
随机森林模型使用如上所示的默认参数运行,但仍有改进的空间。我们可以通过改变“mtry”输入标度(在每个阶段、每个分割点随机采样的变量数量)来微调我们的模型。同时,我们将尝试改变“Ntree”输入(我们种植的树的数量)。).
为了方便起见,我们将只对收入阶层进行两种分类:一种是 30,000 英镑以上,另一种是 30,000 英镑以下。
为了找到最佳的“mtry”值,我们将遍历每个模型并检查准确性:
您的 mtry 值具有最高的平均准确度。
****关于“Ntree”输入的补充说明:你不应该把它做得太小,以确保每个输入行至少被预测几次。
****对比其他模型:我们这样做是为了看看哪种模型效果最好。决策树和随机福里斯特模型的区别?检查下面。还有大量的其他模型类型(查看模型列表,caret 包可以帮助你)。这些只是其中比较简单的一些。
使用 RPART,这个用来建模分类和回归树的包,我们得到了一个被变量分成不同分支的树。为了预测结果,我们对最常见的结果进行了拆分和预测。如第一个示例所示,我们借助 bucket 参数控制了拆分的数量。
另一方面,随机森林稍微高级一些。它也适用于分类和回归树,但使用集成学习算法来预测结果。Random Forest 在编译所有树的结果之前构建多个决策树,这些结果最终得出最终结果。
随机福里斯特模型与决策树模型:
**[1] 0.7341071**
把这个和你的随机福里斯特模型比较一下:
**[1] 0.7757143**
好样的。你的哪个模特赢了?
很好地完成了教程。
其他特征选择技术
还有许多其他的特征选择技术。一种叫做信息价值和证据权重。** R 的信息值包用于二进制分类。它提供了计算分类变量的证据权重和信息值的函数。还有来自earth packe 的 MARS ,用于实现基于广义交叉验证(GCV)、变量出现的子集模型数(nsubsets)和残差平方和(RSS)的变量重要性。还有逐步回归。假设您有大量的预测值(列> 15),这有助于您将输入数据分成十个预测值的部分,每个块包含响应值。**
R 语言中的机器学习
我们只检查了决策树、lm 和随机福里斯特模型。但是还有各种各样的其他模型类型。R caret 包提供了一种以标准方式处理许多模型类型的实用方法。如果你有兴趣,可以看看它的在线手册(这里),你可以使用的模型(这里)和一个整洁的 R 备忘单(这里)。Caret 是开始其他建模任务的一个很好的资源。祝你好运。
教程的数据源和内容:
从 Kaggle 网站下载的人口普查数据和公投结果数据。林克在这里。一些内容受到了 R-statistics.co 和塞尔瓦·普拉巴卡兰以及其他作者发布的代码的启发,比如这位 r-blogger 发布的代码。
检查我们的 Selva Prabhakaran 材料。他的网站上有些有价值的东西。收入。臭氧数据集也来自Selva Prabhakaran的 Github repo 。
关于用 Python 做类似的事情:
随机森林模型的特征选择可以在 Eryk Lewinson 的教程中找到。
本教程是由 Techjournalist 的一名调查记者为 2020 年 伦敦记者见面会 的一次活动编写的。
5 分钟机器学习技巧
原文:https://towardsdatascience.com/machine-learning-techniques-in-5-minutes-9f4ad7d1733c?source=collection_archive---------35-----------------------
5 分钟的机器学习技巧
马库斯·温克勒在 Unsplash 上的照片
今天,在神经网络的时代,你可能没有太多的时间来研究机器学习技术的细节。但是,你仍然可能想知道机器学习算法是如何工作的,机器学习中最流行的算法是什么,以及算法之间的关键区别是什么。
在本文中,我将帮助您介绍不同的机器学习算法及其用法、关键因素和局限性。我们还将看到一些有助于验证算法的基本指标。
线性回归
在线性回归中,我们试图建立一个模型来解释因变量(Y)和自变量(X)之间的关系。我们的 Y 应该是归一化的,X 和 Y 之间应该是线性关系。
使用的损失函数:RMSE(均方根误差)、MSE(均方误差)、MAPE(平均绝对百分比误差)、MAE(平均绝对误差)
作者图片
误差计算:我们使用误差的平方和(残差)来计算误差,这里的主要目标是最小化残差。我们使用梯度下降来实现,梯度下降使用 Y 轴上的残差和 X 轴上的截距来定义误差平方和最小的点。
逻辑回归
这个算法是线性回归的扩展。我们用它来解决分类问题。在这里,Y aka 因变量没有被标准化,并且它与 X 变量没有线性关系。这里的第一步是归一化 Y,我们可以用不同的连接函数来做。在二进制分类的情况下,链接函数的名称是“logit”。并且,95%的分类问题仅基于二元分类。
用于验证的矩阵:精确度、召回率、灵敏度、特异性。
为了定义不同类别的阈值,我们使用 AUC(曲线下面积)和 ROC(受试者操作者特征)。我们用它们来描述使用不同阈值的灵敏度和 1-特异性之间的曲线。无论哪种算法在不同的曲线中提供最大的面积,我们都选择它来用我们的数据建模。
作者图片
决策图表
当数据变得复杂时,我们的线性模型无法将数据分成不同的类别。这引入了对非线性的需求。决策树为我们提供了在数据中引入非线性的方法。在这里,我们可以根据不同的决策拆分数据。我们可以使用决策树进行回归、分类和填充缺失值。决策树的优点是易于实现和解释。但是一旦条件增加,模型就变得复杂,这在模型中引入了高方差,导致决策树中的过度拟合问题。
作者图片
制袋材料
当决策树面临过拟合问题时,就出现了集成的概念。装袋有助于克服过度拟合问题,使模型不那么复杂。
在这里,我们使用了引导样本的概念,我们通过替换从数据集中获取样本数据。意味着下一次我们可能会再次得到同样的样本。
作者图片
我们获取具有相似列的数据集的引导样本(替换),并基于不同的引导样本,我们创建不同的决策树并获取合并输出。这种合并的方法有助于在合并结果时减少模型的差异,但是模型变得很难解释。
随机森林
在 bagging 中,我们使用一组相似的列来获取样本数据,这导致了几乎相同的模型,因为数据的根节点将是相同的,因此,拆分将随之而来。在这里的随机森林中,我们使用一组随机的列进行随机采样,这些列指向不同模型中的不同根节点,最终提供更好的准确性。当我们的模型中存在过度拟合时,随机森林非常有用。这种方法在不同的比赛中也是有帮助的。
adaboost 算法
当我们的模型中存在拟合不足的问题时,我们使用增强模型。这些是连续模型。提升方法有助于提升不正确输出样本的输出,给予这些样本更高的优先级。Adaboost (Adapting Boosting)是 Boosting 机制的一种,它是基于决策树的,在这里,我们试图给样本更高的权重,这给出了错误的预测。
最终型号= W1M1+W2M2+W3M3+…..WnMn
作者图片
这里,M1 是第一个决策树,W1 是与 M1 关联的权重。每个模型都将有助于校正样本预测集。最后,我们将所有模型结合起来,以获得样本的最终预测值。
梯度增强
梯度增强是 Adaboost 的一种改进机制。这里,我们试图通过减少误差来增加/提高模型精度。第一个模型试图找到残差/误差,下一个模型试图解释残差。这样,在即将到来的下一个模型中,误差开始减少。梯度增强处理模型中的欠拟合问题。
XGBoost
XGBoost 就像全才。它解决了欠装配和过装配问题。它还有许多其他功能,如缺失数据处理、内置的交叉验证机制和正则化。
最后
最后,我们已经涵盖了机器学习的所有强大的算法概念。我们观察到,随机森林非常适合过拟合问题,而梯度增强则适合欠拟合问题。最后,我们引入 XGBoost 来处理欠拟合和过拟合问题。
如果你是深度学习技术的爱好者,我有一些优秀的最新资源,可能会让你更好地了解深度学习能力。
- 构建&部署自定义对象检测模型
- 增加物体探测的每秒帧数
- 物体检测中的数据增强
- 物体检测的数据标注
- 语言翻译模型深度学习
- Azure 数据科学家认证 DP-100 提示
继续探索数据科学!
你无法回避的机器学习术语
原文:https://towardsdatascience.com/machine-learning-terms-you-cant-avoid-3528b2a41489?source=collection_archive---------40-----------------------
无论你多么努力…
安迪·凯利在 Unsplash 上的照片
介绍
J 就像上图中的小女孩一样,她将无法避免机器人技术对她未来的影响,作为机器学习从业者,我们无法简单地避免某些术语。
这些是机器学习领域的基本术语。他们参与神经网络的实现、训练、改进和评估。
花一些时间来学习每个术语,并进一步研究每个词如何对机器学习模型的开发不可或缺。
学习率
学习率是神经网络不可或缺的组成部分,因为它是一个值因子,决定了网络权重值的更新级别。
在可视化练习中,要求解的函数可以被描述为 n 维参数空间中的双曲线,学习率是影响当前参数值朝向局部/全局最小值的步长的分量。因此,学习速率直接影响训练期间网络的收敛速率。
如果学习率太低,网络可能需要几次迭代和历元才能收敛,相反,如果学习率太高,则有超过最小值的风险,因此我们的训练不会收敛。
选择合适的学习速率可能是一个漫长的过程,尽管有一些技术可以优化这个过程。
学习率计划
在神经网络的训练期间,可以利用恒定的学习速率,但是这可能增加为了达到最佳神经网络性能而必须进行的训练量。
通过利用学习速率表,我们在训练期间引入学习速率的适时降低或增加,以达到神经网络的最佳训练结果。
学习率衰减
学习率衰减减少了梯度下降过程中朝向局部最小值采取的步长的振荡。
通过将学习率降低到与训练开始时使用的学习率值相比更小的值,我们可以将网络引向在最小值附近的更小范围内振荡的解。
消失梯度
消失梯度问题是神经网络性能和精度的一个限制因素。它是反向传播过程中梯度值不稳定的产物,影响神经网络中的早期层。
消失梯度更具体地存在于深度神经网络(具有若干层的网络)的训练中。所以这是大多数深度学习解决方案中普遍存在的问题。
在反向传播期间,优化算法通过考虑来自网络中后面层的梯度的累积积来导出梯度。具体来说,对于消失梯度的问题,来自网络的较后层的梯度具有 0 和 1 之间的值。因此,梯度的乘积产生了更小的量。
这些小值用于更新网络中较早层的权重,这实际上对当前权重值几乎没有改变。
早期层中神经网络权重的最小变化限制了网络可以学习的程度。此外,网络的训练可能需要更长的时间,因为网络需要更长的时间来收敛并达到最优解。
爆炸梯度
类似于消失梯度问题,爆炸梯度问题是反向传播期间神经网络内梯度不稳定的结果。
在爆炸梯度的情况下,如果网络中后面层的单个梯度分量大于 1,那么在反向传播期间用于计算前面层的梯度的后面层的乘积将是巨大的。
这使得对早期层中的权重的更新具有更高的值;因此,神经网络超过了最优解,并且训练不收敛。
批量标准化
传统的归一化是将要素输入值放置在同一组等价尺度上的过程。因此,对于通过网络转发的图像输入值,像素值被归一化为 0 到 1 范围内的值。
Christian Szegedy 和 Sergey Ioffe 在 2015 年发表的论文中提出了批量标准化技术。通过在神经网络层引入输入值的内部标准化,批量标准化被作为加速深度神经网络训练阶段的解决方案。
可以在激活函数之前或之后对神经网络层的输入应用批处理规范化。在任一情况下,图层的输出都是归一化的。
批量标准化过程分为两个阶段,标准化和规范化。以下是对输入值进行操作的步骤:
- 通过减去平均值并除以标准偏差量,零点将输入值居中。这提供了运行中的当前输入批次,其平均值为 0,标准偏差为 1
- 缩放输入值
- 偏移输入值
通过批量标准化,标准化数据的过程不再局限于网络的输入层,现在是神经网络的内部组成部分。表示批量标准化操作中的偏移和刻度的参数值也可以在训练期间学习。
通过可学习的批量归一化参数,每一层的输入值被最佳地归一化。
它被称为“批量”规范化,因为所执行的操作是基于通过网络输入的每一批输入值。
渐变剪辑
梯度裁剪是一种用于调节神经网络内梯度值不稳定性的技术。这是通过对梯度值施加阈值来实现的。
阈值通常指定在选定的最小值和最大值之间。并且在反向传播期间,梯度值取定义的最小值和最大值内的值。
梯度裁剪主要用于在训练深度神经网络时防止梯度爆炸。它调节从梯度下降优化算法得到的步长,防止其取大值。这确保了我们不会超过全球最小值
结论
我们已经学习了七个标准的机器学习术语,并深入了解了每个术语的表层细节。
展望未来,我建议探索一下在流行的深度学习库中,如 Keras、Pytorch 和 TensorFlow,提到的每个术语是如何实现的。
下面是几篇文章,你可以阅读,以获得更多关于机器学习的知识。
[## 使用 TensorFlow 2.0 进行(深入)机器学习图像分类
理解实现用于图像分类的神经网络的过程。
towardsdatascience.com](/in-depth-machine-learning-image-classification-with-tensorflow-2-0-a76526b32af8) [## 理解机器学习中的运动分析
一篇关于运动分析基础的简短文章,以及机器学习如何被用来解决这个计算机…
towardsdatascience.com](/understanding-motion-analysis-in-machine-learning-f504e9987413)
机器学习:大图景
原文:https://towardsdatascience.com/machine-learning-the-big-picture-fbdfa2b3c6f9?source=collection_archive---------24-----------------------
亲身体验机器如何学习。
演职员表: ahmedgad @ pixabay
动机
毫无疑问,你听说过“机器学习”这个术语。它如何成为下一个重大技术,它将如何解决人类将面临的每一个问题。关于这个话题有很多夸张的说法,很多流行词汇满天飞,新闻以惊人的速度产生。
忽略所有的宣传,机器学习真的是一个非常通用的概念。从医学图像的诊断到无人驾驶汽车,它被用于各种主题。
连接不同领域的概念性理解
每个人都有自己的专业领域。机器学习是一个只有当它与特定领域的知识相结合时才会变得生动的话题。因此,对任何人来说,理解它的基本原理是非常重要的。
这种理解使任何人都能在自己的专业领域找到机器学习的应用和自动化的机会。
任何人都可以做
好消息是:从概念上理解机器学习如何工作不需要任何数学知识,也不是特别难理解。
不要误解:围绕机器学习建立业务、实施或进行研究是困难的。但是了解足够的基础知识,以确定其应用的机会?每个人都能做到。
为了证明这个观点,我将描述一个实验,在这个实验中,你是学习的机器。根据那个实验的结果,我将制定机器学习算法遵循的一般框架。
更好的消息是:一旦你理解了机器学习的一般框架,理解最终会出现的趋势或流行词汇就容易多了。
举个例子:
有人在谈论汽车。他们吹嘘说他们把 V8 引擎换成了 V12 引擎。即使你不知道那些具体的术语是什么意思,你也对汽车的工作原理有一个概念性的了解。简单地说,引擎就是让汽车行驶的东西。考虑到这一点,您可以简化原始语句:
我把 V8 换成了 V12
我换了引擎
我换了能让汽车行驶的东西
实验
先说实验。你是测试对象。我将向您展示几张不同的图片,您的目标是告诉我它们属于以下哪个类别:
- 拉德巴布
- Bigelbub
这些名字对你来说不应该有任何意义,因为它们是我刚刚编出来的。
第一阶段
这是第一张照片。是 Radebarb 还是 Bigelbub?
Bigelbub 还是 Radebarb?
即使你不确定这将走向何方,现在就选一门课吧。
正确答案是…拉德巴布。在接下来的实验中要记住这一点。
第二阶段
下面是下一张图:
Bigelbub 还是 Radebarb?
正确答案是…又是拉德巴。
第 3 阶段
再来两个,就大功告成了:
Bigelbub 还是 Radebarb?
答案是…第一张是 Bigelbub,第二张是 Radebarb。
分析
那么我们来分解一下实验中刚刚发生的事情。首先,请注意以下两点:
- 你应该区分两个阶级。类名对你来说没有任何意义。
- 你得到的照片在开始时对你来说没有任何意义。没有熟悉的物体或形状,只有一堆像素
这些都是机器学习模型在训练时面临的前提条件。它没有内在的知识,不知道在它显示的照片上什么可能是重要的,也不知道这些类之间的关系是什么。
第一阶段
在这个阶段,你看到了第一张图片。你在这里最多只能猜测。如果我让你写下你对自己的猜测有多确定,答案应该是这样的:
- 50%拉德巴布
- 50% Bigelbub
第二阶段
你已经在最后阶段收到了第一点信息。你看到的照片是 Radebarb。在第二阶段,你会看到另一幅图像。
它看起来和上一个没有太大的不同,但是你仍然不知道要找什么。所以也许你对这些课程的信心是这样的:
- 60%拉德巴布
- 40% Bigelbub
第 3 阶段
现在越来越清晰了。一张图看起来和前两张一模一样,但另一张图看起来完全不同。这肯定动摇了你的信心:
- 99% Bigelbub 第一张图片
- 第二张图片的 99% Radebarb
学习过程
起初,你所能做的就是随机猜测。每次猜中后,正确的类别就会显示出来。有了这些信息,你更新了对‘rade barb’和‘bigel bub’的概念,对这两个类的特征越来越有把握。
这是监督学习的基本概念。下一节将这个概念形式化,并介绍一些常用的符号。
机器学习的一般框架
请看下面的流程图:
机器学习的基本框架
这个流程图总结了实验中发生的事情。让我们用它来推导机器学习如何工作的一般框架。
- 训练集。对于任何要发生的机器学习,我们需要已知它们属于哪一类的示例图像。最左边的两个框显示了两个这样的图像/标签对。用于训练模型的所有图像/标签对的集合被称为训练集。
- 车型。在实验中,你是模型。最初,你对要解决的任务一无所知。向模型显示一幅图像,并预测它可能属于哪一类。模型的一个例子是神经网络。
- 损失函数。最右边的方框将模型的预测与预期标签进行比较。有多种方法可以量化模型预测的“正确或错误程度”。计算你“有多错/对”的具体方法叫做损失函数。损失函数的一个例子是 均方误差损失 。
- 优化器。有了预测的错误/正确程度的信息,下次必须更新模型以做得更好。有多种方法可以完成这些更新。一般来说,从损失函数中获取误差并更新模型的东西称为优化器。优化器的一个例子是 随机梯度下降 。
就是这样!你知道对机器学习如何工作有一个基本的了解。在接下来的文章中,我将使用这个框架来描述当实际使用机器学习来解决现实世界的任务时出现的困难,所以如果你对此感兴趣,请继续关注!
机器学习&冠状病毒
原文:https://towardsdatascience.com/machine-learning-the-coronavirus-9cb8352e1b36?source=collection_archive---------14-----------------------
我们如何利用 AI 更好地了解 COVIV-19。
最近我们脑海中的热门话题是新型冠状病毒,或新冠肺炎。它影响了我们许多人的生活,并导致了整个金融市场的巨大动荡。
作为一名数据科学家,有一样东西是我可以一直依赖的,即使是在这些困难时期——数据。幸运的是,关于新冠肺炎价差的数据可以在网上找到。
虽然数据科学和机器学习方法已经在许多领域实际解决了长期存在的问题(语言翻译、图像识别和情感分析等),但这些方法不可能神奇地“解决”冠状病毒危机;然而,对其行为的更好理解、基于数据的更仔细分析和有意义的预测可能有利于决策和政策制定。
那么…这里我们可以应用哪些 ML 方法呢?
1.数据可视化
当开始处理新数据时,良好的可视化可以在许多方面提供帮助。有时候这就是你所需要的!但它总能在处理数据时提供见解和想法,并节省大量时间。
我推荐的一个很酷的地理可视化 Python 库是follow,它可以用来创建交互式世界地图。
在以下示例中,我绘制了自 2 月中旬以来的新冠肺炎病例数:
还可以创建不同国家的病例数条形图。对于这些类型的地块, seaborn 是一个易于使用且有用的库:
(在这个特定的图中,中国仅指湖北地区,美国仅指纽约)。
许多其他创造性的可视化可以被制作出来,它们经常为我们提供容易理解的有用信息!
2.时间序列预测模型
预测模型可用于预测时间序列数据的不同未来方案。通常,这些模型需要对数据进行几个假设,虽然我不会在这里讨论这些假设,但人们必须意识到这些模型的局限性和适当的用法。此外,还有几个重要的概念需要考虑:
- 缩放,在这种情况下应该是对数(想想为什么!).
- 数据清理,即去除极端异常值或无效数据。例如,病例数量的急剧增加导致检测数量的突然增加,而不是新患者的实际数量,这可能会误导预测模型。
- 数据中有没有季节性?
几个库(Python 和 R 中都有)可以用来完成这样的任务。我特别喜欢的一本是《先知》(fbprophet,作者脸书)。以下是日本的病例数,按正常比例和对数比例:
下面是一个使用 prophet 对总病例数进行短期预测的示例。我假设了病例数的对数的逻辑模型;我们知道,病例数有一个峰值,然后下降,所以从长期来看,活跃的病例数将会有所不同。
3.监督学习,一个例子:冠状病毒和天气
我记得读过的一篇关于这种病毒的早期文章将它的潜在传播与天气联系起来,希望更温暖的气候可以最小化它的有效性。
我想更深入地挖掘这一点,并了解“天气”如何影响病毒。这是一种监督学习问题:使用几个其他自变量描述和预测一个因变量。
然而,“天气”是一个有许多含义的概念,比如说,不太清楚从原始温度数据中应该做什么样的特征工程。
一个好的开始方式是看一个例子,所以我从检查武汉的天气开始,这是 2019 年 12 月病毒首次出现的地方。我找到了过去几个月的温度监测站数据(ID CHM00057494 ),并得到了下图:
一个有趣的观察结果是,平均温度在 1 月至 3 月期间似乎相当不稳定;而且,有几个尖锐的“滴”或“刺”;这可能暗示我们,温度的这种“波动性”可能是我们模型的一个好特征。
应该用什么 ML 型号?这总是一个很好的问题,并且由于存在各种各样的模型,选择哪一个并不总是很清楚(合理的方法是有时尝试许多模型,并根据其在测试集上的性能选择最好的一个!).
考虑到之前的观察,我将根据不同国家的气候进行划分:热带、干燥、潮湿的亚热带、潮湿的大陆性气候(以及极地气候,但不要太多!).我将使用 KNN 算法,它有时(不合理地)不被考虑。它依赖于对具有相似或“接近”统计数据的数据点进行平均,以获得对所需数据点的预测。我将使用的特征是一个时间窗口内的案例数量和气候类型;KNN 算法的简单性可以防止过度拟合结果,并且适用于这些情况。我将数据划分到 3 月 10 日之前和之后(火车-测试在时间上分裂)。sklearn 库实现了 KNN 算法(sk learn . neighbors . kneighborsregressor ),但我决定编写自己的版本来定制距离度量,因为这是一个实现起来相当简单的算法。
我得到的结果很有意思——一个 8.5% 病例数的预测值与实际值的相对误差。基线(定义该基线总是很重要),该基线仅取同一国家的前一天,具有 15.8% 的相对误差。所以我们实际上得到了一个重要的(!)通过使用 KNN 和气候数据的改进。
昨天(3 月 20 日)模型预测的一些轶事:
- 预测马提尼克岛有 33 例;实际人数是 32 人。
- 预测波多黎各有 16 例;实际人数是 14 人。
- 预计关岛有 13 例;实际人数是 14 人。
总之,通过机器学习,我——我不是传染病方面的专家——能够更好地了解这种病毒,甚至使用纯 ML 方法获得合理的预测方法。
保持安全和健康!
编者按: 走向数据科学 是一份以数据科学和机器学习研究为主的中型刊物。我们不是健康专家或流行病学家,本文的观点不应被解释为专业建议。想了解更多关于疫情冠状病毒的信息,可以点击 这里 。
机器学习技巧:处理不平衡数据集
原文:https://towardsdatascience.com/machine-learning-tips-handling-imbalanced-datasets-328422ef3054?source=collection_archive---------61-----------------------
处理数据不平衡的不同方法
菲德尔·费尔南多在 Unsplash 上的照片
假设您有一项任务,要创建一个模型来检测欺诈性的信用卡交易。提供给你的数据集包含 100 万笔交易,但其中只有 3 万笔被标记为欺诈,这使得数据集不平衡。这是欺诈检测任务类别的典型比例。否则,我们会有更严重的问题要解决。
数据不平衡通常是分类问题中的一个问题,它表示类别分布不均匀。如果这是一个二元分类问题,我们可能有 95%的 A 类和 5%的 b 类。如果分类模型是在不平衡的数据集上训练的,它将高度偏向主导类。因此,该模型将反映潜在的类别分布。为了有一个准确的模型,我们需要解决不平衡问题。作为解决方案,有不同的使用方法。
在本帖中,我们将讨论和解释最常用的方法,并提及适用于不平衡数据集的评估指标。
重采样
重采样可以有两种不同的形式,欠采样和过采样。
欠采样仅从多数类中选择一些观察值(行)来匹配少数类中的观察值数量。
让我们看一个例子。我将使用 kaggle 上的信用卡欺诈检测数据集。我们首先将数据集读入熊猫数据帧。
import numpy as np
import pandas as pddf = pd.read_csv("/content/creditcard.csv")df.Class.value_counts()
0 284315
1 492
有 492 笔交易被标记为欺诈,近 285,000 笔交易不是欺诈。让我们想象一下“类别”列:
#data visuzalization libraries
import matplotlib.pyplot as plt
import seaborn as sns
sns.set(style='darkgrid')
%matplotlib inlineplt.figure(figsize=(8,5))
plt.title('Credit Card Transactions')
sns.countplot('Class', data=df)
欺诈(1)交易的数量如此之少,以至于我们甚至无法在图上看到。在这种情况下,我们可以通过随机选择 492 个观察值(少数类中的观察值数量)对多数类(0)进行欠采样。
df = df.sample(frac=1, random_state=42)
fraud = df[df.Class == 1]
nonfraud = df[df.Class == 0].sample(n=492, random_state=32)
df_new = pd.concat([fraud, nonfraud])df_new.Class.value_counts()
1 492
0 492
Name: Class, dtype: int64
我们执行的步骤:
- 使用 sample 函数混洗整个数据集,并通过过滤数据帧来分离类。
- 使用样本函数随机选择 492 行非原始数据帧。
- 用 concat 功能合并两个数据帧。
最后,我们有一个等类分布的欠采样数据帧。
过采样是欠采样的反义词。我们使用少数类的观察值生成合成数据。过采样过程比欠采样稍微复杂一点。当生成新的观察值时,我们需要保持在少数类的特征空间内。例如,如果一个特征的范围在 10 到 30 之间,那么对于一个合成样本来说,该特征具有 100 是没有意义的。
有不同的过采样技术。其中最常见的是 SMOTE (合成少数过采样技术)。SMOTE 算法根据已有的样本创建新的样本。它需要两个或更多相似的观察值,并通过一次改变一个属性来创建一个综合观察值。变化量是随机的,但会将新观测值保持在所用现有观测值的相邻距离内。在不平衡学习库中可以找到 SMOTE 的实现。
等级权重
一般来说,分类模型对每个类别的权重是相等的。因此,每一个错误分类的观察结果都会导致不同类别的等量损失(不考虑概率)。但是,我们可以改变类的权重,使得少数类中观察值的错误分类超过多数类的错误分类。
大多数机器学习模型都有一个名为 class_weight 的参数来调整权重。我们只需要通过字典来确定权重。
from sklearn.linear_model import LogisticRegressionweights = {0:1, 1:10}
lr = LogisticRegression(class_weight = weights)
我们创建了一个逻辑回归模型,负类和正类的类权重分别为 1 和 10。在这种情况下,当一个正类被错误分类时,该模型比错误分类一个负类的情况受到更多的惩罚。
不平衡数据集的评估指标
不平衡的数据集需要特殊的评估指标。仅仅使用准确性并不能提供彻底的评估。假设我们正在创建一个模型,对一个具有不平衡类分布的数据集执行二元分类。93%的数据点属于负类,7%属于正类。如果一个模型只预测负类,它将达到 93%的准确率,这是非常好的。然而,它只是反映了类分布,而不是学习观察值之间的关系。这种情况被称为准确性悖论。
如果正确地检测阳性类别是至关重要的,并且我们不能对它们中的任何一个进行错误分类(即癌症预测),该怎么办?在这些情况下,我们需要其他指标来评估我们的模型。
混淆矩阵
混淆矩阵不是评估模型的指标,但它提供了对预测的洞察。学习混淆矩阵对于理解其他分类度量是很重要的,例如精确度和召回率。
混淆矩阵通过显示每个类别的正确和错误(即真或假)预测,比分类准确性更深入。在二进制分类任务的情况下,混淆矩阵是 2×2 矩阵。如果有三个不同的类,那就是一个 3x3 的矩阵,以此类推。
假设 A 类是正类,B 类是负类。混淆矩阵的关键术语如下:
- 真阳性(TP) :预测阳性类别为阳性(ok)
- 假阳性(FP) :将阴性类别预测为阳性(不正常)
- 假阴性(FN) :预测阳性类别为阴性(不正常)
- 真阴性(TN) :预测阴性类为阴性(ok)
混淆矩阵用于计算精度和召回率。
精度和召回
精确度和召回率度量将分类准确性向前推进了一步,并允许我们获得对模型评估的更具体的理解。选择哪一个取决于任务和我们的目标。
精度表示有多少正面预测是正确的。
精度的焦点是正面预测。
Recall 表示所有肯定类别中有多少被正确预测。
召回的重点是实际正班。
我们不能试图同时最大化精确度和召回率,因为它们之间有一个平衡。提高精度会降低召回率,反之亦然。我们可以根据任务来最大化精确度或回忆。对于垃圾邮件检测模型,我们试图最大限度地提高精确度,因为我们希望在电子邮件被检测为垃圾邮件时是正确的。我们不想将一封普通的电子邮件标记为垃圾邮件(即误报)。另一方面,对于肿瘤检测任务,我们需要最大化召回率,因为我们希望尽可能多地检测到阳性类别。
还有一个将精确度和召回率结合成一个数字的方法,那就是 F1 分数。
F1 得分
F1 分数是精确度和召回率的加权平均值。
对于类别分布不均匀的问题,F1 分数是比准确度更有用的度量,因为它考虑了假阳性和假阴性。
f1 得分的最佳值是 1,最差值是 0。
卡帕(科恩的卡帕)
Kappa 是通过考虑类别不平衡而归一化的分类精度。
感谢您的阅读。如果您有任何反馈,请告诉我。
用机器学习解决多类分类问题
原文:https://towardsdatascience.com/machine-learning-to-help-water-crisis-24f40b628531?source=collection_archive---------65-----------------------
用 Python 预测坦桑尼亚的水点状况
玛格达莱娜·库拉·曼切在 Unsplash 上的照片
根据 Water.org和国际生命之水的数据,在坦桑尼亚 5700 万人口中,有 2500 万人无法获得安全的饮用水。妇女和儿童必须每天多次前往取水,而水源的安全甚至没有保障。2004 年,坦桑尼亚 12%的死亡是由水传播疾病造成的。
尽管为解决坦桑尼亚的水危机付出了多年努力和大量资金,但问题依然存在。使用可收集的数据预测坦桑尼亚供水点状况的能力将使我们能够制定计划,有效地利用资源来发展可持续的基础设施,这将影响许多人的生活。
数据
作为解决这一问题的一项举措, DrivenData 利用开源平台 Taarifa 从坦桑尼亚水利部收集的数据,发起了一场基于勘探的竞赛。该项目的目标是预测三种不同类别的每个供水点的状态:功能正常、不正常和需要修复。
我们的数据集显示,59,400 个供水点中有 62%有功能,而 38%没有功能。在这些功能性供水点中,12%需要维修。
探索性数据分析
在清理了数据并处理了缺失值和异常值之后,我们研究了单个要素如何与水点的状况相关联。以下是我们探索性数据分析的一些观察结果。
旧的供水点没有得到维护
这是不同建设年份的用水点分布。我们可以看到,大多数可以使用的供水点都是最近建成的,这可能是因为近年来投入了大量资金。但是,事实上,即使是最近建成的核电站也有可能不像旧的核电站那样发挥作用,这是非常令人担忧的。
付款事宜。
稳定的付款计划似乎是一个强有力的指标,表明供水点是否会得到维持。问题是,虽然维护供水点的责任留给了每个社区,但坦桑尼亚的大多数社区没有足够的钱来维护这些供水点。
位置很重要
根据坦桑尼亚的这张地图,我们可以看到水点条件往往集中在不同的区域。这告诉我们,位置是这个问题的重要预测因素。
特征工程
基于我们的探索性数据分析,我们决定扩展包含位置信息的特性。首先,我们根据它的名字找到了盆地的位置,并计算了从水点到盆地的距离。
使用 Geopy 的的包找到位置,该包使用 OpenStreetMap 数据。
然后我们使用测地线距离 Geopy 计算距离。
此外,我们还设计了其他几个特征,包括位置是在城市还是农村地区,以及村里其他井的总数。
预处理
重采样
我们的数据有一个等级不平衡的问题,这意味着功能水点比需要修复的水点多得多。这可能会使预测偏向多数类,因此我们使用 SMOTE(合成少数过采样技术)对数据进行重新采样。简而言之,通过合成与同一类中现有样本距离较近的新样本,对过采样进行 SMOTE。
除了重采样之外,我们还将分类特征转换为二元虚拟特征,并对所有特征进行标准化。
特征选择
我们的原始数据有许多分类特征,这导致在对分类特征进行一次热编码后产生相对大量的特征。为了优化计算,我们决定运行基于树的特征选择。
模型评估
评估指标
决定与项目目标一致的评估指标是非常重要的(如果您需要复习,请参见这里的)。我们处理这个问题有两个主要目的,一个是建立一个具有最高整体精度的模型,另一个是建立一个成功预测维修需求的模型。后者很重要,因为准确预测维修需求与影响坦桑尼亚许多人生活的变化直接相关。但是在这篇文章中,我将从整体准确性的角度来评估模型。
虚拟分类器
首先,我们首先安装一个虚拟分类器作为基线模型。我们的虚拟分类器使用分层方法,这意味着它根据每个类别的比例进行预测。
请注意,这段代码中的 X_test 指的是我们的验证集。我们已经搁置了维持集,以便在最后测试最终模型。
**# Dummy result: Accuracy: 0.33**
我们的假人表现出大约 33%的准确性,这是假人对三个类别进行分类的预期性能。
k-最近邻
我们测试的第一个模型是 K 近邻(KNN)。KNN 基于第 k 个最接近观测值的类别进行分类。超参数调谐是通过 Optuna 实现的。我们测试了 GridSearchCV 和 Optuna 的性能,发现 Optuna 更加通用和高效。
**# KNN Result - Accuracy: 0.752**
随机森林分类器
接下来,我们用 Optuna 超调测试了随机森林分类器。随机森林在数据子集上同时拟合多个决策树,然后聚合结果。
**# Random Forest Results - Accuracy : 0.74**
对于这个问题,KNN 的性能优于随机森林分类器。但是,尽管这里没有报道,随机森林分类器在对少数民族分类方面比 KNN 分类器做得好得多。
XGBoost
因为我们测试了一个打包方法,所以我们也使用 XGBoost 测试了一个增强方法。这是一个梯度推进模型的实现,它根据预测误差迭代训练弱学习者。
**# XGBoost Results - Accuracy: 0.78**
XGboost 在准确性得分方面有所提高,其预测少数民族类别的敏感性也高于其他两个模型。
投票分类器
最后,我们将所有之前的模型进行投票。当使用投票分类器时,我们可以结合每个模型对每个类别概率的预测(软)或使用其对每个类别的二元选择(硬)。在这里,我们使用软投票。
**# Voting Classifier - Accuracy: 0.79**
投票分类器为少数类返回稍高的准确度和相似的召回率。我们决定继续使用投票分类器作为我们的最终模型,并测试维持测试集。
最终模型性能
我们的最终模型显示对维持组的预测准确率为 80%(基线为 45%),对少数类的召回率接近 50%,比基线模型的 6%召回率有了显著提高。
照片由 Unsplash 上的 ngozi Assata 拍摄
额外奖励:口译
因为我们的最终模型涉及在距离算法和基于树的集成之间投票,所以很难解释我们模型的特征重要性。但是,使用弹性网络正则化和 SGD 训练的逻辑回归的附加分析表明,足够的水量、公共竖管的使用和最近建成是功能性供水点的重要预测因素。
另一方面,位置是非功能性供水点的重要预测因素。尤其是靠近维多利亚湖的一些北部地区,与无法运行的供水点高度相关。最后,非功能性和需要修复的水点之间的 GPS 高度显示出不同的模式。有必要进行进一步的调查,以确定 GPS 高度的重要性,无论它是否与特定的政府区域相关,或者可访问性的差异,或者它是否对某些提取类型有任何技术影响。
这个项目是与我的同事 dolcikey 合作完成的。
利用机器学习预测黄金价格
原文:https://towardsdatascience.com/machine-learning-to-predict-gold-price-returns-4bdb0506b132?source=collection_archive---------11-----------------------
黄金预测
用 PyCaret 预测黄金价格
介绍
十多年来,我一直是金融市场的学生,一直在研究不同的资产类别及其在不同经济条件下的行为。很难找到比黄金更具两极分化的资产类别。有喜欢它的人,也有讨厌它的人,更多的时候,他们永远停留在同一个阵营。由于黄金本身没有什么基本面(这又是一个两极分化的来源),在这个多部分系列中,我将尝试使用几种机器学习技术来预测黄金价格回报。以下是我(目前)对该系列的设想:
第一部分:确定方法,收集和准备数据
第二部分:使用 PyCaret 的回归建模
第三部分:使用 PyCaret 分类建模
第四部分:时间序列建模使用 Prophet(脸书)
第五部分:评估方法整合
“请注意,在一个竞争极其激烈的市场中,黄金是一种交易非常广泛的资产。长期从任何策略中持续赚钱是极其困难的,如果不是不可能的话。这篇文章只是分享我的经验,而不是投资或交易的处方或倡导。然而,对于像我这样的该领域的学生来说,这个想法可以通过个人努力扩展和发展成交易算法。”
背景
几个世纪以来,黄金一直是人类最初的价值储存手段和交易媒介,直到几个世纪前纸币取代了黄金。然而,直到 1971 年布雷顿森林协定被废除,世界货币成为真正的′𝐹𝑖𝑎𝑡′货币之前,大多数可持续的纸币都是由黄金支持的。
然而,黄金不仅作为珠宝的首选金属,而且作为价值储存手段和多样化投资组合中通常可取的一部分,继续引起人们的兴趣,因为它往往是一种有效的通胀对冲和经济经历艰难时期的避风港。
方法
在这个系列中,我们将采用不同的方法来预测黄金价格的回报,使用机器学习正如引言部分所强调的
首先,我们将走回归路线来预测未来 2 周和 3 周的黄金回报。我们将通过使用不同工具的历史回报来实现这一点,我认为这将影响黄金的前景。根本原因是,我将黄金称为一种“反动”资产。它几乎没有自己的基本面,价格的变动通常是投资者如何看待其他资产类别(股票、大宗商品等)的衍生品。).
导入数据
在本次和后续练习中,我们将需要过去 10 年中几种工具的收盘价。我们可以使用各种付费资源(路透社、彭博)和免费资源(IEX、Quandl、Yahoofinance、谷歌财经)来导入数据。由于这个项目需要不同类型的资产类别(股票、商品、债务和贵金属),我发现'Yahoo financials'软件包非常有用且简单明了。
***#Importing Libraries***
import pandas as pd
from datetime import datetime
import matplotlib.pyplot as plt
from yahoofinancials import YahooFinancials
我准备了一份需要导入数据的仪器清单。Yahoo financials包需要 Yahoo 股票代码。该列表包含股票代号及其说明。包含列表的 excel 文件可以在这里找到,文件名为“Ticker List”。我们导入该文件,并将股票代码和名称提取为单独的列表。( 见笔记本 )
ticker_details = pd.read_excel(“Ticker List.xlsx”)
ticker = ticker_details['Ticker'].to_list()
names = ticker_details['Description'].to_list()
ticker_details.head(20)
有了列表后,我们需要定义需要导入数据的日期范围。我选择的期限是 2010 年 1 月至 2020 年 3 月 1 日。我之所以没有提取之前的数据,是因为 2008-09 年的全球金融危机(GFC) 极大地改变了经济和市场格局。那段时期之前的关系现在可能没那么重要了。
我们创建一个日期范围,并将其写入一个名为 values 的空数据帧,我们将从 yahoofinancials 中提取并粘贴数据。
***#Creating Date Range and adding them to values table***
end_date= “2020–03–01”
start_date = “2010–01–01”
date_range = pd.bdate_range(start=start_date,end=end_date)
values = pd.DataFrame({ ‘Date’: date_range})
values[‘Date’]= pd.to_datetime(values[‘Date’])
一旦我们在 dataframe 中有了日期范围,我们就需要使用 ticker 符号从 API 中提取数据。 yahoofinancials 以 JSON 格式返回输出。下面的代码循环遍历股票代码列表,只提取所有历史日期的收盘价,并将它们添加到在日期上水平合并的 dataframe 中。鉴于这些资产类别可能有不同的地区和交易假期,每次数据提取的日期范围可能不相同。通过合并,我们最终会有几个 NAs ,稍后我们将填充。
***#Extracting Data from Yahoo Finance and Adding them to Values table using date as key*** for i in ticker:
raw_data = YahooFinancials(i)
raw_data = raw_data.get_historical_price_data(start_date, end_date, “daily”)
df = pd.DataFrame(raw_data[i][‘prices’])[[‘formatted_date’,’adjclose’]]
df.columns = [‘Date1’,i]
df[‘Date1’]= pd.to_datetime(df[‘Date1’])
values = values.merge(df,how=’left’,left_on=’Date’,right_on=’Date1')
values = values.drop(labels=’Date1',axis=1)***#Renaming columns to represent instrument names rather than their ticker codes for ease of readability***
names.insert(0,’Date’)
values.columns = names
print(values.shape)
print(values.isna().sum()) ***#Front filling the NaN values in the data set***
values = values.fillna(method="ffill",axis=0)
values = values.fillna(method="bfill",axis=0)
values.isna().sum()***# Coercing numeric type to all columns except Date***
cols=values.columns.drop('Date')
values[cols] = values[cols].apply(pd.to_numeric,errors='coerce').round(decimals=1)
values.tail()
值表的尾部
准备数据
在上述方法中,我们强调了我们将使用上市工具的滞后回报来预测黄金的未来回报。在这里,我们继续计算所有工具的短期历史回报和少数选定工具的长期历史回报。
其背后的基本思想是,如果某项资产表现优异或表现不佳,投资组合重新平衡的可能性更大,这将影响未来其他资产类别的回报。如果股票市场(比如说 S & P500)在过去的 6 个月中表现出惊人的回报,资产经理可能会希望记录利润,并分配一些资金到贵金属上,为股票市场的调整做准备。下图显示了在不同的市场条件下,黄金和标普 500 之间的价格变动和相关性。
资料来源:彭博、ICE 基准管理机构、世界黄金协会。链接
从上面我们可以看到,当 S&P500 出现极端的负向运动时,黄金表现出负相关性。最近股市的大幅下跌也凸显了类似的关系,当金价因预期下跌而上涨时,年初至今金价上涨了 11%,而 S&P500 年初至今下跌了 11%。
然而,我们将使用机器学习来评估假设。您可以直接从我的 git-hub repo 下载文件名为‘Training Data _ Values’的数值数据
imp = [‘Gold’,’Silver’, ‘Crude Oil’, ‘S&P500’,’MSCI EM ETF’]***# Calculating Short term -Historical Returns***
change_days = [1,3,5,14,21]data = pd.DataFrame(data=values[‘Date’])
for i in change_days:
print(data.shape)
x= values[cols].pct_change(periods=i).add_suffix(“-T-”+str(i))
data=pd.concat(objs=(data,x),axis=1)
x=[]
print(data.shape)***# Calculating Long term Historical Returns***
change_days = [60,90,180,250]for i in change_days:
print(data.shape)
x= values[imp].pct_change(periods=i).add_suffix(“-T-”+str(i))
data=pd.concat(objs=(data,x),axis=1)
x=[]
print(data.shape)
除了滞后回报,我们还可以看到不同窗口的当前金价离其移动平均线有多远。这是技术分析中非常常用的指标,移动平均线为资产价格提供支撑和阻力。我们使用简单移动平均线和指数移动平均线的组合。然后,我们将这些移动平均值添加到现有的特征空间。
***#Calculating Moving averages for Gold***
moving_avg = pd.DataFrame(values[‘Date’],columns=[‘Date’])
moving_avg[‘Date’]=pd.to_datetime(moving_avg[‘Date’],format=’%Y-%b-%d’)
***#Adding Simple Moving Average***
moving_avg[‘Gold/15SMA’] = (values[‘Gold’]/(values[‘Gold’].rolling(window=15).mean()))-1
moving_avg[‘Gold/30SMA’] = (values[‘Gold’]/(values[‘Gold’].rolling(window=30).mean()))-1
moving_avg[‘Gold/60SMA’] = (values[‘Gold’]/(values[‘Gold’].rolling(window=60).mean()))-1
moving_avg[‘Gold/90SMA’] = (values[‘Gold’]/(values[‘Gold’].rolling(window=90).mean()))-1
moving_avg[‘Gold/180SMA’] = (values[‘Gold’]/(values[‘Gold’].rolling(window=180).mean()))-1***#Adding Exponential Moving Average*** moving_avg[‘Gold/90EMA’] = (values[‘Gold’]/(values[‘Gold’].ewm(span=90,adjust=True,ignore_na=True).mean()))-1
moving_avg[‘Gold/180EMA’] = (values[‘Gold’]/(values[‘Gold’].ewm(span=180,adjust=True,ignore_na=True).mean()))-1
moving_avg = moving_avg.dropna(axis=0)
print(moving_avg.shape)
moving_avg.head(20)
移动平均数据帧的输出
***#Merging Moving Average values to the feature space***
data[‘Date’]=pd.to_datetime(data[‘Date’],format=’%Y-%b-%d’)
data = pd.merge(left=data,right=moving_avg,how=’left’,on=’Date’)
print(data.shape)
data.isna().sum()
这都是关于特性的。现在我们需要创建目标,也就是我们想要预测的。因为我们在预测回报,所以我们需要选择一个我们需要预测回报的时间范围。我选择了 14 天和 22 天的时间范围,因为其他更小的时间范围往往非常不稳定,缺乏预测能力。然而,你也可以尝试其他的地平线。
***#Calculating forward returns for Target***
y = pd.DataFrame(data=values[‘Date’])
y[‘Gold-T+14’]=values[“Gold”].pct_change(periods=-14)
y[‘Gold-T+22’]=values[“Gold”].pct_change(periods=-22)
print(y.shape)
y.isna().sum()***# Removing NAs***
data = data[data[‘Gold-T-250’].notna()]
y = y[y[‘Gold-T+22’].notna()]***#Adding Target Variables***
data = pd.merge(left=data,right=y,how=’inner’,on=’Date’,suffixes=(False,False))
print(data.shape)
现在我们有了完整的数据集,可以开始建模了。在下一部分中,我们将使用极其创新和高效的 PyCaret 库来试验不同的算法。我还将展示如何创建一个管道来不断导入新数据,以使用训练好的模型生成预测。
利用机器学习预测黄金价格
使用 PyCaret 的第二部分回归建模
在第一部分中,我们讨论了从开源免费 API 导入数据,并以一种适合我们预期的机器学习练习的方式准备它。您可以参考第一部分的代码,或者从 github repo 导入文件名为“Training Data”的最终数据集。
PyCaret 是 Python 中的一个开源机器学习库,可以在任何笔记本环境中使用,并大大减少了编码工作,使过程变得非常高效。在下面的部分我们将看到py caret如何为任何机器学习实验增压。首先,您需要使用以下命令安装 PyCaret:
*!pip install pycaret*
22 天模型
我们以 22 天为目标。这意味着,根据历史数据,我们将尝试预测未来三周的黄金回报。
****#If you are importing downloaded dataset***
data = pd.read_csv("Training Data.csv")from pycaret.regression import ****#We have two target columns. We will remove the T+14 day Target*** data_22= data.drop(['Gold-T+14'],axis=1)*
设置
要在 PyCaret 中开始任何建模练习,第一步是“设置”功能。这里的强制变量是数据集和数据集中的目标标签。所有基本和必要的数据转换,如丢弃 id、一次性编码分类因子和缺失值插补,都在后台自动进行。PyCaret 还提供了 20 多个预处理选项。对于这个例子,我们将在设置中使用基础知识,并在后面的实验中尝试不同的预处理技术。
*a=setup(data_22,target='Gold-T+22',
ignore_features=['Date'],session_id=11,
silent=True,profile=False);*
在上面的代码中,数据集作为“data_22”传递,目标指向标记为“Gold-T+22”的列。我特别提到要忽略“日期”列,以防止 PyCaret 在日期列上创建基于时间的功能,这在其他情况下可能非常有用,但我们现在不评估这一点。如果您想查看变量之间的分布和相关性,您可以保留参数“profile=True”,它显示一个 panda profiler 输出。我特意提供了‘session _ id = 11 ’,以便能够重新创建结果。
魔法命令....compare _ models()**
下一步,我将使用 PyCaret 的一个我最喜欢的特性,它将数百行代码缩减为两个字——“compare _ models”。该函数使用所有算法(目前有 25 种)并使它们适合数据,运行 10 重交叉验证,并为每个模型提供 6 个评估指标。所有这些只用两个字。为了节省时间,函数中还可以使用另外两个参数:
a. turbo=False —默认为真。当 turbo=True 时,比较模型不会评估一些更昂贵的算法,即核脊(kr)、自动相关性确定(ard)和多层感知器(mlp)
b .黑名单 —在这里,可以传递算法缩写的列表(参见 docstring ),这是众所周知的耗时更长且性能改善很小的方法。下面,我已经把尼尔森回归器(tr)列入了黑名单
*compare_models(blacklist=['tr'],turbo=True)*
比较模型的输出
这里我们将使用 R 平方(R2)作为度量标准。我们看到 ET、Catboost 和 KNN 是前三名的模型。下一步,我们将调整三个模型的超参数。
调整模型超参数
PyCaret 为每个算法都预定义了一个网格,并且 tune_model() 函数使用随机网格搜索来查找优化指标选择的参数集(此处为 Rsquare ),并显示优化模型的交叉验证分数。它不接受经过训练的模型,并且需要作为字符串传递的估计量的缩写。我们将调整额外树(et)、K 最近邻(knn)和 CatBoost (catboost)回归器。
*et_tuned = tune_model(‘et’)*
*catb_tuned = tune_model(‘catboost’)*
*knn_tuned = tune_model(‘knn’,n_iter=150)*#I have increased the iteration in knn because increasing iterations have shown to perform better for knn rather than other models in question without significantly increasing the training time.**
上面我们可以看到,knn 的 R2 在调优后大幅提升至 87.86%,远高于调优后没有提升的 et 和 catboost。这可能是因为网格搜索过程中的随机化。在一些非常高的迭代次数下,它们可能会改进。
我还会创建一个基本的额外树(et)模型,因为它的原始性能(调优前)非常接近调优后的 knn。我们将使用 PyCaret 中的create _ model()函数来创建模型。
*et = create_model(‘et’)*
评估模型
对训练好的模型进行一些模型诊断是很重要的。我们将使用 PyCaret 中的 evaluate_model() 函数来查看绘图集和其他诊断信息。它接受经过训练的模型,以返回模型诊断图和模型定义的选择。我们将对我们的两个顶级模型进行模型诊断,即 knn_tuned 和 et。
库克距离图 knn_tuned
上面,我们可以清楚地看到,在前 500 个观察值中,有许多异常值,它们不仅影响模型性能,还可能影响未来的模型泛化。因此,去除这些异常值可能是值得的。但在此之前,我们将通过 et 来了解特征重要性(knn 不提供特征重要性)
我们认为,白银和新兴市场 ETF 的回报率具有最高的特征重要性,突显出白银和黄金通常成对波动,而投资组合配置确实在新兴市场股票和黄金之间转移。
去除异常值
要移除异常值,我们需要回到设置阶段,使用 PyCaret 内置的异常值移除器,并再次创建模型以查看影响。
*b=setup(data_22,target=’Gold-T+22', ignore_features=[‘Date’], session_id=11,silent=True,profile=False,remove_outliers=True);*
如果' remove _ outliers '参数设置为 true,PyCaret 使用奇异值分解(SVD)技术删除通过 PCA 线性降维识别的离群值。默认杂质水平为 5%。这意味着它将删除 5%的观察值,它认为是离群值。
移除异常值后,我们再次运行我们的顶级模型,看看是否有任何性能改进,显然有。
***
剔除异常值后的 et 和 knn_tuned 结果*
我们看到 et 的性能从 85.43%提高到 86.16%,knn_tuned 的性能从 87.86%提高到 88.3%。褶皱间的标准差也有所降低。
集合模型
我们还可以尝试看看 bagging/boosting 是否可以提高模型性能。我们可以使用 PyCaret 中的ensemble _ model()函数,通过下面的代码快速查看集成方法如何改善结果:
*et_bagged = ensemble_model(et,method=’Bagging’)
knn_tuned_bagged = ensemble_model(knn_tuned, method='Bagging')*
上述代码将显示类似的交叉验证分数,但没有显示出太大的改进。回购中的笔记本链接可以看到结果。
混合模型
我们可以混合前 2 个模型(et 和 knn_tuned)来看看混合模型是否可以表现得更好。人们经常看到,混合模型经常学习不同的模式,并且它们一起具有更好的预测能力。为此我将使用 PyCaret 的blend _ models()函数。它接受一个训练模型列表,并返回一个混合模型和 10 倍交叉验证分数。
*blend_knn_et = blend_models(estimator_list=[knn_tuned,et])*
混合模型的结果
在上表中,我们看到混合的 knn_tuned 和 et 返回比两者更好地表示 R2。与 knn_tuned 相比,R2 的平均 R2 增加了 1.9%,标准差减少了 1.9%,这意味着跨褶皱的性能更好、更一致。
90.2%的平均 R2 意味着我们的模型能够从我们提供的特征中捕捉平均 90.2%的黄金回报变化。
堆叠模型
虽然混合模型的结果很好,但我想看看是否有可能从数据中提取更多的 R2 基点。为此,我们将建立一个多层次的模型堆栈。这不同于混合,因为模型层是按顺序堆叠的,因此一层中模型的预测将与原始要素一起传递到模型的下一层(如果 restack = True)。一组模型的预测极大地帮助了后续模型的预测。链的末端是元模型(默认是线性的)。PyCaret guide 有更多关于主题的细节。在笔记本中,我尝试了几种架构。下面展示的是性能最佳的产品:
*stack2 = create_stacknet(estimator_list=[[catb,et,knn_tuned],[blend_knn_et]], restack=True)*
堆叠 2 的结果(多层堆叠)
正如我们在上面看到的, stack2 模型比 blend_knn_et 有 1%的 R2,我们将选择 stack2 作为最佳模型,并保存它用于预测。
保存模式
一旦模型定型,我们需要保存模型,以便在新数据上使用它来进行预测。我们可以通过 save_model()来实现。这会将模型保存在当前目录或任何已定义的路径中。下面的代码将模型和预处理管道保存为名称【22 天回归器】**
*save_model(model=stack2, model_name=’22Day Regressor’)*
对新数据进行预测
一旦我们保存了我们的模型,我们将希望在新数据到达时对其进行预测。我们可以依靠 yahoofinancials 软件包来给出所有工具的收盘价,但是,我们需要再次准备新的数据,以便能够使用该模型。这些步骤与我们在准备培训数据时所做的类似,唯一的区别是我们将导入最新的数据,并且我们不会创建标签(我们不能创建标签,因为我们没有未来的价格)。下面的代码 chuck 应该导入并调整数据,使其为预测做好准备。
****#Importing Libraries***
import pandas as pd
from datetime import datetime
import matplotlib.pyplot as plt
from yahoofinancials import YahooFinancialsticker_details = pd.read_excel("Ticker List.xlsx")
ticker = ticker_details['Ticker'].to_list()
names = ticker_details['Description'].to_list()***#Preparing Date Range***
end_date= datetime.strftime(datetime.today(),'%Y-%m-%d')
start_date = "2019-01-01"
date_range = pd.bdate_range(start=start_date,end=end_date)
values = pd.DataFrame({ 'Date': date_range})
values['Date']= pd.to_datetime(values['Date'])***#Extracting Data from Yahoo Finance and Adding them to Values table using date as key***
for i in ticker:
raw_data = YahooFinancials(i)
raw_data = raw_data.get_historical_price_data(start_date, end_date, "daily")
df = pd.DataFrame(raw_data[i]['prices'])[['formatted_date','adjclose']]
df.columns = ['Date1',i]
df['Date1']= pd.to_datetime(df['Date1'])
values = values.merge(df,how='left',left_on='Date',right_on='Date1')
values = values.drop(labels='Date1',axis=1)***#Renaming columns to represent instrument names rather than their ticker codes for ease of readability***
names.insert(0,'Date')
values.columns = names***#Front filling the NaN values in the data set***
values = values.fillna(method="ffill",axis=0)
values = values.fillna(method="bfill",axis=0)***# Co-ercing numeric type to all columns except Date***
cols=values.columns.drop('Date')
values[cols] = values[cols].apply(pd.to_numeric,errors='coerce').round(decimals=1)
imp = ['Gold','Silver', 'Crude Oil', 'S&P500','MSCI EM ETF']***# Calculating Short term -Historical Returns***
change_days = [1,3,5,14,21]data = pd.DataFrame(data=values['Date'])
for i in change_days:
x= values[cols].pct_change(periods=i).add_suffix("-T-"+str(i))
data=pd.concat(objs=(data,x),axis=1)
x=[]***# Calculating Long term Historical Returns***
change_days = [60,90,180,250]for i in change_days:
x= values[imp].pct_change(periods=i).add_suffix("-T-"+str(i))
data=pd.concat(objs=(data,x),axis=1)
x=[]***#Calculating Moving averages for Gold***
moving_avg = pd.DataFrame(values['Date'],columns=['Date'])
moving_avg['Date']=pd.to_datetime(moving_avg['Date'],format='%Y-%b-%d')
moving_avg['Gold/15SMA'] = (values['Gold']/(values['Gold'].rolling(window=15).mean()))-1
moving_avg['Gold/30SMA'] = (values['Gold']/(values['Gold'].rolling(window=30).mean()))-1
moving_avg['Gold/60SMA'] = (values['Gold']/(values['Gold'].rolling(window=60).mean()))-1
moving_avg['Gold/90SMA'] = (values['Gold']/(values['Gold'].rolling(window=90).mean()))-1
moving_avg['Gold/180SMA'] = (values['Gold']/(values['Gold'].rolling(window=180).mean()))-1
moving_avg['Gold/90EMA'] = (values['Gold']/(values['Gold'].ewm(span=90,adjust=True,ignore_na=True).mean()))-1
moving_avg['Gold/180EMA'] = (values['Gold']/(values['Gold'].ewm(span=180,adjust=True,ignore_na=True).mean()))-1
moving_avg = moving_avg.dropna(axis=0)***#Merging Moving Average values to the feature space***data['Date']=pd.to_datetime(data['Date'],format='%Y-%b-%d')
data = pd.merge(left=data,right=moving_avg,how='left',on='Date')
data = data[data['Gold-T-250'].notna()]
prediction_data = data.copy()*
准备好数据后,我们需要加载模型并进行预测。为了加载模型,我们将再次使用 PyCaret 的回归模块。下面的代码将加载模型,对新数据进行预测,并使用数据集中每个日期的历史价格、预计回报和 3 周内的预测价格。
*from pycaret.regression import ****#Loading the stored model*** regressor_22 = load_model("22Day Regressor");***#Making Predictions*** predicted_return_22 = predict_model(regressor_22,data=prediction_data)
predicted_return_22=predicted_return_22[['Date','Label']]
predicted_return_22.columns = ['Date','Return_22']***#Adding return Predictions to Gold Values***
predicted_values = values[['Date','Gold']]
predicted_values = predicted_values.tail(len(predicted_return_22))
predicted_values = pd.merge(left=predicted_values,right=predicted_return_22,on=['Date'],how='inner')
predicted_values['Gold-T+22']=(predicted_values['Gold']*(1+predicted_values['Return_22'])).round(decimals =1)***#Adding T+22 Date*** from datetime import datetime, timedeltapredicted_values['Date-T+22'] = predicted_values['Date']+timedelta(days = 22)
predicted_values.tail()*
上表输出显示,黄金在 2020 年 4 月 17 日的收盘价为 1,694.5 美元,模型预测在接下来的 22 天内,回报将为-2.3%,导致 2020 年 5 月 9 日的价格目标为 1,655 美元。我为预测建立了一个单独的笔记本,标题为 “黄金预测新数据—回归” ,可以在回购这里找到。
我们可以使用相同的概念和技术来预测 T+14 天。代码和输出可以在 Jupyter 笔记本标题 “黄金预测实验回归—py caret”中找到,在 repo 这里。
重要链接
链接第三部分— 预测金价暴跌
链接到 Github 资源库
关注我上LinkedIn
指南py caret
简化的机器学习
原文:https://towardsdatascience.com/machine-learning-use-cases-an-overview-for-business-users-c5b786a91604?source=collection_archive---------44-----------------------
弗兰基·查马基在 Unsplash 上拍摄的照片
商业用户概述
正如我们之前讨论过的,机器学习指的是用于识别数据中模式的算法。但是我们所说的“模式”到底是什么意思,我们能用 ML 做什么,以及所有这些关于“模型”和“训练”它们的术语是什么。在这篇文章中,我将尝试解释这一切,而不会变得太专业,以及作为一个商业用户,你应该知道的关于机器学习的知识。
从什么是不同类型的 ML 用例开始:
机器学习用例
监督学习
监督学习意味着用例,我们有一个目标,我们试图预测给定的数据。举个例子,
- 信用卡公司试图根据客户的个人资料和信用记录计算出信用额度
- 一家汽车制造公司利用天气和宏观经济数据估算拖拉机销量
- 一家数字媒体公司预测客户是否会因其在平台上的活动而流失,或者
- Gmail 根据邮件正文、主题和发件人预测邮件的类别。
监督算法使我们能够使用输入数据(客户的信用历史、天气和宏观经济状况、客户在平台上的活动、邮件规格)来预测目标(例如,估计的信用额度、拖拉机销量、客户是否会流失,或者邮件类别)。
有两种监督算法
监督学习算法的类型
这些变量根据目标变量的类型而有所不同:
- 如果目标变量是一个数字(例如信用额度或拖拉机销量),这个问题被称为回归问题。
- 如果目标是一个类别(此人是否会流失—是或否;邮件所属的文件夹—主要、更新、促销、论坛或垃圾邮件),这个问题被称为分类问题。
回归和分类问题都有模型,即可以解决这些类型问题的算法。但是他们是怎么解决的,机器到底“学习”了什么。让我们试着用我们钟爱的线性回归的例子来探索一下
示例使用案例
假设作为一家汽车制造公司,我们想预测拖拉机的销售,根据我们的专业知识,我们知道降雨量会影响销售。检查去年的数据,我们得到以下图表
我们注意到某种程度上的线性关系,并决定“拟合”一个线性回归模型。 [【数学预警]] 即考虑我们的目标(销售额)为 y ,输入变量(降雨量)为 x ,我们可以将数据表示为:
y = mx +c
或者换句话说
销售= 坡度 * 降雨量+ 截留量
m 和 c 的不同值可能会给我们不同的线,但是我们想要给我们最接近我们的数据点的线的值。
从所有不同的可能线条(其中一些以灰色显示)中,我们注意到其中一条(红色粗体)与我们的数据最接近,也就是说,如果我们使用这条线条来估计降雨量的销售额,我们将得到最接近实际销售额的预测。注意,我们找到的这个解也只是某个 m(斜率)和 c(截距)。
因此,对于下一年,如果我们知道降雨量,我们可以预测一个地区的销售额如下
销售额= m *降雨量+ c
使用我们找到的值 m 和 c 作为我们的解。
延伸这个例子,如果我们想包括更多的变量,比如回购利率(贷款利率的代理),那么我们的等式应该是
销售额= m1 *(降雨量)+ m2 *(回购利率)+ c
该模型必须计算参数的最佳值— m1、m2 和 c 以根据输入数据预测销售额。
这些斜率(m’s)和截距(c)的最佳值如何给出最接近我们数据的图,以及我们如何准确定义这种接近度涉及到相当多的数学问题,因此超出了本文的范围,但重要的是这些是我们的线性回归“模型”已经学习的“参数”,它们可以用来从我们的输入数据预测我们的目标变量。
就像线性回归试图在我们的数据上拟合直线一样,不同的模型会试图在我们的数据上拟合不同的函数,即,试图找到最接近数据点的曲线,就像线性回归中的斜率和截距一样,我们试图找到其他参数的最佳值,这使我们与数据最接近。
分类算法的工作方式类似,唯一的区别是它们试图调整参数,使我们获得最大的准确性,或者为尽可能多的数据点分配正确的类别。
您可能已经听说过所有模型的名称——线性回归、逻辑回归、支持向量机、决策树、随机森林、神经网络(或深度学习模型),这些模型都只是试图估计一个能给出最接近数据的预测的函数,并找到该函数的最佳参数值,这个找到最佳参数值的过程称为“训练”
这里需要注意一些事情:
- 数据的数量和质量很重要:如果我们只有很少的数据点,由于缺乏证据,我们不能非常确定我们的预测。但是,仅仅有大量的数据点并不能保证有好的预测,如果我们的降雨量比历史上任何时候都多,我们就不能准确地预测销售额,因为模型从未见过这个输入范围内的值。背景也很重要-一个为印度训练得很好的模型,可能在一定程度上适用于类似的发展中国家人口,但在一个完全不同的地方,比如说美国,会给出错误的预测。
- 领域专业知识:模型的选择及其实现是获得良好预测的一部分,但是更重要的因素是发送到模型的数据,这就是领域专业知识发挥作用的地方。例如,在上面的例子中,非常了解汽车销售的人可能能够说出到底是什么影响了拖拉机的销售,并且将这些变量作为输入数据发送会比使用输入数据与拖拉机销售没有很好关系的非常复杂的模型给出更好的结果。
无监督学习
这意味着在数据中没有目标的问题,我们的目标是探索数据的分布。无监督学习的一个主要用例是聚类
使聚集
顾名思义,它在数据中识别聚类。例如,如果一家银行有以下关于客户年龄和工资的数据。
该银行希望对相似的用户进行分组,以便围绕这些用户群制定营销和产品策略
注意:y 轴(工资)不要和目标混淆,和回归的情况一样。我们的任务不是根据年龄数据预测工资,而是将年龄和工资相似的人分组。
聚类算法可能会给出以下结果
在这里,每个数据点(或客户)现在都与一个集群相关联(用颜色表示),这使得围绕每个产品制定策略变得更加容易。
注意:本例中仅考虑了两个变量(年龄和薪水)来说明这一点,因此,即使在没有任何算法的情况下,也有可能直观地探索数据并进行聚类,但在现实中,我们处理多个(任何超过 3 个)变量,不可能直观地显示数据。
同样,有几种算法可以对数据进行聚类,每种算法都适用于不同的数据分布和用例,但它们都试图实现相同的目标——在没有任何目标的情况下识别数据中相似点的组。
其他 ML 算法
除了聚类之外,还有其他无监督学习算法,例如降维。但是由于它们的业务用例有限,并且主要用于提高其他模型的性能,所以我在这里不讨论它们。
强化学习是一种完全不同的 ML 算法,用于在相对不太动态的环境中决定最大化长期回报的行动。详细讨论它超出了本文的范围,但是到目前为止,它们在业务应用程序中相对较少使用。
因此,大多数 ML 用例可以被设计为回归、分类或聚类任务之一
离别的思绪
我希望这能让你更好地理解什么是机器学习,以及它能做什么。实施这些 ML 模型的数据科学家必须了解不同模型的本质,它们是如何工作的,以及它们都可以用在哪里。但是,作为一名业务用户,了解您可以从您拥有的数据中获得的所有见解可能是开始与您的分析部门或顾问讨论的良好第一步,以帮助您的组织开始做出更好的数据驱动型决策
深入决策树和随机森林
原文:https://towardsdatascience.com/machine-learning-v-decision-trees-random-forest-kaggle-dataset-with-random-forest-3ebfe6d584be?source=collection_archive---------48-----------------------
以及带有随机森林的已解 Kaggle 数据集
内容
在本帖中,我们将介绍:
- 决策树术语
- 测量杂质的方法
- CART 算法
- 使用 CART 手工构建决策树
- 为什么选择随机森林而不是决策树
- 随机森林中决策树的多样化
- 利用随机森林改进海量数据分类器
在之前的帖子中,我们详细讨论了支持向量机,还解决了 Kaggle 的欺诈性信用卡交易数据集。在这篇文章中,我们将会看到另外两种监督学习算法:决策树和随机森林。在完成这篇文章后,我们将几乎涵盖了业内所有广泛使用的监督机器学习算法。
决策树
决策树这个术语是不言自明的,它的工作方式类似于人的决策能力。人类是如何做决定的?首先,人类定义目标。在机器学习中,特定任务的目标由数据集决定。一旦人们有了一个明确的目标,他们就会回答各种问题/执行各种任务,以实现这个目标。为实现目标而执行的第一个任务类似于决策树的根节点。它代表了决策树的目标。根节点分支到某个选项集,每个选项都有自己的选项集。这个过程一直持续到我们做出最后的决定。现在,这些选项中的每一个都类似于一个决策节点,最终决策由一个叶节点表示。在几乎所有情况下,根节点也充当决策节点。对于巨大的决策树,一个决策节点的输出是许多决策节点,除了在树的最深层,它是叶节点。
决策树建模是一种监督学习算法,可用于回归和分类问题中的连续和离散值数据集。最常见的是,决策树被用作分类器,递归地将数据划分到类别中。决策树是一个有向树,即一旦我们到达树中的特定节点,我们就不能回溯到前一个节点,即父节点不能从子节点访问。
决策树示例(来源)
看到上面这个决策树的例子后,我们可以看到,算法决定最先问的问题是汽车的颜色。所有其他问题也遵循一定的顺序。提问的顺序非常重要,否则对于如上所示的简单场景,决策树会变得非常复杂。决策树如何确定它需要问的问题的顺序?提问的顺序取决于哪个问题会导致该级别数据的良好分割。每个节点上的数据分割方式类似于二分搜索法。在根节点,我们有整个数据集。根节点应该将馈送给它的数据分成两个或更多个组,其中每个组中的数据具有相似的属性。假设根节点将数据分割成 3 组,那么这 3 组将是根节点的 3 个子节点,并且这 3 个节点中的每一个都将执行分割数据的操作,创建更多的子节点,并且对每个节点进行该过程,直到该节点不再有分割要做(叶节点),这是进行预测的点。
决策树如何决定哪个问题导致好的拆分,哪个问题没有?这是通过测量杂质来量化的。
不纯
学习最优决策树的问题是 NP 完全的,所以为了更好地模仿最优解,杂质的概念应运而生。杂质是对数据同质性的一种度量。如果数据只包含一个类,则称之为纯数据或同质数据。数据中的类越多,越不纯。除了叶节点之外,决策树中的每个节点都包含有可能分裂成更多组的数据,即每个节点都有与数据相关的某种杂质。不纯程度较低的节点需要较少的信息来描述它们,而不纯程度较高的节点需要更多的信息来描述它们。因此,节点的子节点比它们的父节点具有更高的纯度。
测量杂质
有各种方法来衡量杂质,但最常用的是信息增益和基尼指数。我们一个一个来看。
信息增益
信息增益用于确定哪个特征/属性给了我们关于一个类的最大信息。它基于熵的概念。统计学中的熵类似于热力学中的熵,熵表示无序。熵越高,随机性越大(即纯度越低),从给定信息中得出结论变得越困难。对于完全纯的数据样本,即当仅存在一个类别时,熵最小(0),如果数据平均分布在所有类别之间,则熵最大(1)。
我们为逻辑回归定义的二元交叉熵损失函数与熵非常相似。对于具有“c”个不同类的数据集,熵的度量如下:
计算熵(来源)
其中 pi 表示给定类别 I 中示例的分数。在上图的示例中,有 2 个类别,因此 c=2。p(是)= 9/14 (0.64),p(否)= 5/14 (0.36)。一旦计算出节点的熵,则给定特定特征的特定输出的信息增益被计算为:
其中,S 是输出类,A 是数据集的特定要素,P 与上面定义的含义相同(对于 pi)。由于对数函数的高计算时间,基尼指数在实际应用中优于信息增益。
基尼指数
从形式上来说,基尼指数衡量的是随机选择某个变量时,该变量被错误分类的概率。概率值为 0 意味着变量不会被错误分类,只有当我们只有一个输出类时才有可能,即数据是 100%纯的。随着基尼指数值的增加,由于杂质的增加,特定变量被错误分类的可能性也增加。这些值传达的信息与熵值产生共鸣。对于具有“c”类的数据集,基尼指数定义为:
其中 pi 表示给定类别 I 中实例的分数,这类似于熵定义。
还有更多的杂质测量方法,如卡方、分类误差等。但这里的主要思想是让读者熟悉杂质测量方法。这里需要注意的一点是,这些杂质测量函数的作用类似于成本函数。
构建决策树
构建决策树实际上是对输入数据特征的划分,这导致 2 个或更多子节点,并且该过程对每个子节点递归地进行。一旦创建了这个树,就已经在所有节点上划分了特征。
用于分类的各种决策树算法沿着以下路线进行比较:
㈠分割标准
㈡消除/减少过度拟合的技术
㈢处理不完整的数据
用于决策树构造的各种算法有 CART、ID3、C4.5、C5.0、CHAID、MARS 等。在本帖中,我们将详细讨论 CART。CART 是应用最广泛、最高效的决策树算法之一。
分类和回归树
顾名思义,CART 算法用于生成分类和回归决策树。我们将在这里集中讨论分类部分。它用于解决多类分类问题(对于二分类,它生成一棵二叉树),并使用基尼指数作为度量来评估决策树中一个特征节点的分裂。
在 CART 算法中,目标是最小化每个节点的成本函数(基尼指数)。以贪婪的方式选择决定每个节点的特定分割的输入变量/特征的选择,以最小化成本函数。以这种贪婪的方式,考虑具有不同组变量/特征的多个分裂点,并且选择在该节点处导致基尼指数的最小值(即,更同质的分裂)的分裂。对树中的所有子节点递归地执行该过程。
这个过程可能永远继续下去,并可能导致许多不必要的子节点的形成,因此需要停止。为此,我们计算通过树的每个节点的训练示例的总数。这个数是一个超参数,根据数据集进行调整,这个数的最佳选择导致健壮决策树的形成。给一些直觉,如果树的节点只有一个通过它的训练示例,这意味着生成的决策树正遭受过度拟合,因为它对一个示例给予了如此多的重要性,以至于它调用了它的单独节点。这种决策树需要降低其复杂性,这可以通过剪枝来实现。
决策树剪枝是一种通过删除对分类目标没有什么帮助的部分来减小决策树大小的技术。2 流行的修剪方法有:
㈠减少错误修剪(自下而上)
㈡成本复杂性削减(自上而下)
更多关于这些修剪方法可以在这里找到。现在我们已经知道了 CART 算法背后的底层逻辑,让我们来看一个二进制分类的例子,如何使用 CART 构造决策树。让我们使用 UCI 机器学习动物园动物分类数据集的 10 条记录来手工构建一个决策树。给定特征“牙齿”、“毛发”、“呼吸”、“腿”,决策树应该输出动物的种类(哺乳动物/爬行动物)。
让我们一个一个地从每个特性开始。我们在数据中观察到,所有输入特征都由布尔值表示。
(i) 齿状:让我们总结一下‘齿状’特征值的输出(种类)。
基尼指数(齿状=真)= 1—{(5/8)+(3/8)} = 1–0.39–0.14 = 0.47
基尼指数(锯齿=假)= 1—{(1/2)+(1/2)} = 1–0.25-0.25 = 0.5
为了获得“有齿物种”的最终基尼指数,我们使用上述计算值的加权和,如下所示:
基尼指数(有齿)=(8/10)* 0.47+(2/10)* 0.5 = 0.38+0.1 =0.48
(二)头发:让我们总结一下输出(种类)wrt 的‘头发’特征值。
基尼指数(hair = true)= 1—{(5/5)+(0/5)} = 1–1–0 = 0
基尼指数(hair = false)= 1—{(1/5)+(4/5)} = 1–0.04–0.64 = 0.32
为了获得“物种”相对于“毛发”的最终基尼指数,我们使用上述计算值的加权和,如下所示:
基尼指数(头发)=(5/10)* 0+(5/10)* 0.32 =0.16
(三)呼吸:总结一下‘呼吸’特征值的输出(物种)。
基尼指数(呼吸=真实)= 1—{(6/9)+(3/9)} = 1–0.45–0.11 = 0.44
基尼指数(breats = false)= 1—{(0/1)+(1/1)} = 1–0–1 = 0
为了获得“物种”相对于“呼吸”的最终基尼指数,我们使用上述计算值的加权和,如下所示:
基尼指数(呼吸)=(9/10)* 0.44+(1/10)* 0 =0.40
(iv) legs :让我们总结一下‘legs’特征值的输出(种类)。
基尼指数(legs = true)= 1—{(6/7)+(1/7)} = 1–0.73–0.02 = 0.25
基尼指数(breats = false)= 1—{(0/3)+(3/3)} = 1–0–1 = 0
为了获得“物种”对“腿”的最终基尼系数,我们使用上述计算值的加权和,如下所示:
基尼指数(呼吸)=(7/10)* 0.25+(3/10)* 0 =0.18
现在,我们已经针对所有 4 个输入特征计算了输出变量的基尼指数,我们需要选择根节点。选择根节点使得它具有最小的基尼指数。基尼指数越低,早期预测答案的几率就越高(由于节点的纯度更高)。所以在这里,我们选择头发作为根节点。此时的决策树看起来像这样:
让我们首先考虑“头发”取值为 TRUE 的情况。
当 hair 取值为 TRUE 时,让我们针对输入特征(不包括头发特征)计算输出的基尼指数。
(i) 齿状:让我们总结一下当 hair = TRUE 时“齿状”特征值的输出(种类)
基尼指数(头发=真&牙齿=真)= 1—{(4/4)+(0/4)} = 1–1–0 = 0
基尼指数(头发=真&牙齿=假)= 1—{(1/1)+(0/1)} = 1–1–0 = 0
为了获得“头发=真”的“物种”wrt“有齿”的最终基尼指数,我们使用上述计算值的加权和作为:
基尼指数(齿牙&头发=真)=(4/5)* 0+(1/5)* 0 = 0+0 =0
(ii) 呼吸:让我们总结一下当 hair = TRUE 时“呼吸”特征值的输出(种类)
基尼指数(头发=真实,呼吸=真实)= 0
基尼指数(头发=真,呼吸=假)= 0
为了获得“头发=真”的“物种”wrt“呼吸”的最终基尼指数,我们使用上述的加权和。
基尼指数(呼吸和头发=真实)= 0
(iii) legs :让我们总结一下当 hair = TRUE 时‘legs’特征值的输出(种类)
基尼指数(头发=真&腿=真)= 0
基尼指数(头发=真&腿=假)= 0
为了获得“头发=真”的“物种”对“腿”的最终基尼指数,我们使用上述的加权和。
基尼指数(腿和头发=真)= 0
在上述所有情况下,基尼系数等于 0。这意味着,如果我们预测该物种有毛发,则可以基于给定的数据集以高置信度将其归类为“哺乳动物”。此时,决策树看起来像这样:
现在,让我们考虑“头发”取值为 FALSE 的情况。
当头发的值为 FALSE 时,让我们针对输入特征(不包括头发特征)计算输出的基尼指数。
(i) 齿状:让我们总结一下当 hair = FALSE 时‘齿状’特征值的输出(物种)
基尼指数(头发=假&牙齿=真)= 1—{(1/4)+(3/4)} = 1–0.06–0.56 = 0.38
基尼指数(头发=假&牙齿=假)= 1—{(0/1)+(1/1)} = 1–0–1 = 0
为了获得“头发=假”的“物种”wrt“有齿”的最终基尼指数,我们使用上述计算值的加权和作为:
基尼指数(齿牙&头发=假)=(4/5)* 0.38+(1/5)* 0 = 0.3+0 =0.3
(ii) 呼吸:让我们总结一下当 hair = FALSE 时‘呼吸’特征值的输出(种类)
基尼指数(头发=假,呼吸=真)= 1—{(1/4)+(3/4)} = 1–0.06–0.56 = 0.38
基尼指数(头发=假&呼吸=假)= 1—{(0/1)+(1/1)} = 1–0–1 = 0
为了获得“头发=假”的“物种”wrt“呼吸”的最终基尼指数,我们使用上述计算值的加权和作为:
基尼指数(呼吸和头发=假)=(4/5)* 0.38+(1/5)* 0 = 0.3+0 =0.3
(iii) 腿:让我们总结一下当 hair = FALSE 时‘腿’特征值的输出(物种)
基尼指数(头发=假&腿=真)= 1—{(1/2)+(1/2)} = 1–0.25–0.25 = 0.5
基尼指数(头发=假&腿=假)= 1—{(0/3)+(3/3)} = 1–0–1 = 0
为了获得“头发=假”的“物种”wrt“腿”的最终基尼指数,我们使用上述计算值的加权和作为:
基尼指数(齿牙&头发=假)=(2/5)* 0.5+(3/5)* 0 = 0.2+0 =0.2
在上述 3 个案例中,我们看到,在“头发=假”的条件下,“腿”特征的基尼指数最小。因此,当“hair=FALSE”时,选择“legs”作为子节点。此时,决策树看起来像这样:
为了更进一步,让我们考虑 legs = TRUE(现在隐含 hair = FALSE)的情况。
当头发取值为假而腿取值为真时,让我们针对输入特征计算基尼指数,不包括头发和腿特征。
(i) 齿状:让我们总结一下头发=假,腿=真时‘齿状’特征值的输出(物种)。
基尼指数(头发=假&腿=真&牙齿=真)= 0
基尼指数(头发=假&腿=真&牙齿=假)= 0
为了获得“头发=假”和“腿=真”的“物种”wrt“有齿”的最终基尼指数,我们使用上述的加权和。
基尼指数(牙齿&头发=假&腿=真)= 0
(二)呼吸:总结一下头发=假,腿=真时‘呼吸’特征值的输出(物种)。
基尼指数(头发=假&腿=真&呼吸=真)= 1—{(1/2)+(1/2)} = 1–0.25–0.25 = 0.5
基尼指数(头发=假&腿=真&呼吸=假)= 0
为了获得“头发=假”和“腿=真”的“物种”wrt“有齿”的最终基尼指数,我们使用上述的加权和。
基尼指数(牙齿&头发=假&腿=真)= (2/2) * 0.5 + (0/2) * 0 = 0.5
在上面的 2 个例子中,我们看到‘齿状’的基尼指数较低,所以当‘legs = TRUE’时,它被选为子节点。决策树现在看起来像这样:
现在,让我们考虑“legs”取值为 FALSE 的情况。
从上面的场景中,我们可以清楚地看到,当“头发=真”和“腿=假”时,输出的“物种”在所有情况下都是“爬行动物”。因此,我们无需计算基尼指数,就可以有把握地得出结论,为决策树生成的子节点将是值为“爬虫”的叶节点。(请记住,当我们考虑“头发=真”的情况时,我们看到所有输出的“物种”值都是“哺乳动物”,通过计算基尼指数,我们直接生成了一个值为“哺乳动物”的叶节点)
进一步来说,让我们考虑“锯齿=真”的情况。这里隐含了“头发=假”和“腿=真”的情况。
在这里,我们只有一个被归类为哺乳动物的记录。因此,这种特征的组合导致输出的“物种”是“哺乳动物”。
考虑到“齿状=假”的情况,我们得到
以类似的方式,我们可以得出结论,这组特征的输出“物种”是“爬行动物”。现在,我们终于构建了一个决策树,我们可以在其上抛出一些测试数据来进行预测。
如果到目前为止您已经仔细观察过,您可能已经观察到该数据集中的所有变量都是分类变量(即,要素具有一组有限的不同值(2),如 TRUE 和 FALSE)。在你在中遇到的数据集中,真实生活混合了分类变量和连续变量。为了从具有连续值的数据集构建决策树,通过定义某个阈值将这些连续值转换成分类值。利用这一点,可以为任何类型的数据构建决策树。
为什么不使用决策树
尽管决策树创建起来非常直观和简单,但是它们有以下缺点。
1.它们是不稳定的,这意味着数据的微小变化会导致最优决策树结构的巨大变化。
2.计算可能会变得非常复杂,尤其是当许多值不确定和/或许多结果相互关联时。
3.决策树倾向于非常快地过度适应训练数据,并且可能变得非常不准确。
随机森林
由于决策树的上述缺点,使用随机森林算法来代替决策树。随机森林算法使用大量决策树,这些决策树作为集合运行。机器学习集成只由具体的有限的备选模型集组成,但通常允许在这些备选模型中存在更加灵活的结构。
随机森林算法是基于群体智慧的概念。在计算机科学的各种任务中,群体智慧是一种非常有效的技术。事实上,维基百科(完全众包,每个人都可以编辑)和大英百科全书(完全由专家编写)的质量标准水平相当,这证明了群体智慧的力量。人群中的每个人都做出了带有一定误差的预测。因为所有的个体都是独立行动的,所以他们的错误也是相互独立的。换句话说,这些误差是不相关的,也就是说,当考虑到一堆误差时,这些误差相互抵消,我们得到的是一个良好、准确的预测。这就是随机森林算法的工作方式。
随机森林简体(来源)
随机森林算法的工作
随机森林算法使用来自给定数据集的大量决策树(创建一个森林),这些决策树彼此独立/不相关,总体上优于其任何组成树。森林中的组成树木之间的这种很少甚至没有的相关性为这种集合方法赋予了随机的元素,这产生了一种奇妙的效果,即保护树木免受它们各自错误的影响。但是我们需要确保我们为随机森林工作而随机制作的各种决策树的输出不应该是完全随机的。为了确保这一点,我们需要确保:
(I)为了使随机决策树有效,输出应该依赖于所有的训练特征,而不仅仅是其中的一些。
(ii)每个决策树做出的预测应该彼此具有低相关性,以便使群体智慧概念起作用。
第一点是我们收集的数据集的特征。那么,作为一名数据科学家,我们如何确保组成决策树尽可能多样化呢?为此,随机森林使用以下两种技术:
㈠装袋
(二)特征随机性
制袋材料
决策树的一个主要缺点是,它们对数据的微小变化都不够稳健,这使得它们容易过度拟合。我们来了解一下装袋是如何解决这个问题的。考虑具有 M ( > > 50)个训练示例的训练数据集,为了简单起见,让我们考虑这些是 1 到 50 范围内的 M 个数字。如果我们想要将 B 决策树用于随机森林,那么通过 bagging,每个 B 决策树由 M 个训练样本组成,但是不是使用所有的 M 个训练样本,而是使用这些训练样本的随机子集(这里数字在 1 到 50 的范围内),并且来自该子集的数字被随机重复,直到总共 M 个训练样本被创建。
装袋有什么帮助?通过创建大量的决策树,其中大量的训练示例随机分布在决策树中,聚集的结果是随机森林模型,该模型即使对数据的微小变化也是健壮的,从而消除了决策树的主要缺点之一(通过使用决策树)。
特征随机性
使用随机训练样本的想法也可以应用于训练数据的特征。回想一下,在构造决策树时,当决定每个节点的分裂时,我们考虑了所有的特征。如果训练数据集具有 N 个特征,那么在特征随机性中,在创建每个 B 决策树时,通过使用这 N 个特征的随机子集而不是使用所有 N 个特征来做出分裂节点的决定。
当 bagging 和特征随机性都用于为随机森林生成决策树森林时,每个决策树由训练样本的随机子集以及特征的随机子集构成。这种随机性通过确保形成不相关的决策树来保护彼此免受其错误的影响,从而为随机森林分类器增加了很多鲁棒性和稳定性。一旦所有这些组成决策树做出预测,就会进行多数表决,以获得分类器的最终预测。
到目前为止,我们已经看了很多概念。从决策树背后的数学到手动创建一个决策树,然后看看如何在随机森林中使用决策树,我们已经走了很长的路。现在是我们实践随机森林分类器的时候了,在这篇文章中,我们不会处理一个新的数据集,相反,我们将改进我们的逻辑回归模型,我们在这篇文章中对泰坦尼克号数据集进行了训练。这是实际机器学习任务的执行方式。尝试了各种机器学习模型,并且在实践中使用了效果最好并且证明了所获得的结果的模型。记住,坚持是关键。所以让我们开始吧。
问题陈述
泰坦尼克号问题的数据集可以在这里找到。我们必须预测泰坦尼克号上的一名乘客能否生还,给出相应的数据。我们已经在这个岗位应用了数据预处理和逻辑回归。现在,我们将使用前一篇文章中相同的预处理数据,但这次将应用随机森林分类。预处理后的数据集如下所示:
在应用了递归特征消除(RFE) 之后,我们获得了将有助于训练随机森林分类器的前 8 个最重要的特征。更多关于 RFE 的信息可以在这里找到。
from sklearn.ensemble import RandomForestClassifier
from sklearn.feature_selection import RFEcols = [“Age”, “SibSp”, “Parch”, “Fare”, “Pclass_1”, “Pclass_2”, “Pclass_3”, “Embarked_C”, “Embarked_Q”, “Embarked_S”, “Sex_male”]X = final_train[cols]
y = final_train[‘Survived’]model = RandomForestClassifier()*# selecting top 8 features* rfe = RFE(model, n_features_to_select = 8)
rfe = rfe.fit(X, y)print(‘Top 8 most important features: ‘ + str(list(X.columns[rfe.support_])))
现在我们已经有了应该用于训练分类器的特征列表,让我们对数据集应用随机森林分类器。与逻辑回归不同,随机森林有大量需要输入模型的参数。最重要的参数是:
1.n_estimators =前集中的树的数量
2.max_features =分割结点时考虑的最大要素数
3.max_depth =每个决策树中的最大级别数
4.min_samples_split =分割节点前放置在节点中的最小数据点数
5.min_samples_leaf =叶节点中允许的最小数据点数
6.bootstrap(如 bagging) =采样数据点的方法(有或没有替换)
这些参数很多,很难手动获得它们的最优值。因此,我们通过向模型传递每个参数的一组值来利用计算能力,参数将这些值应用于数据集并选择最佳值。对于这个数据集,使用随机超参数网格技术,我花了大约 5 分钟来获得最佳值。
*# Number of trees in random forest* n_estimators = [int(x) for x **in** np.linspace(start = 200, stop = 2000, num = 10)]*# Number of features to consider at every split* max_features = ['auto', 'sqrt']*# Maximum number of levels in tree* max_depth = [int(x) for x **in** np.linspace(10, 110, num = 11)]
max_depth.append(None)*# Minimum number of samples required to split a node* min_samples_split = [2, 5, 10]*# Minimum number of samples required at each leaf node* min_samples_leaf = [1, 2, 4]*# Method of selecting samples for training each tree (bagging)* bootstrap = [True, False]*# Creating random grid* random_grid = {'n_estimators': n_estimators, 'max_features': max_features, 'max_depth': max_depth, 'min_samples_split': min_samples_split, 'min_samples_leaf': min_samples_leaf, 'bootstrap': bootstrap}
在每次迭代中,算法将选择特征的不同组合。总共有 2 * 12 * 2 * 3 * 3 * 10 = 4320 个设置!然而,随机搜索的好处是,我们不是在尝试每一种组合,而是随机选择大范围的值进行采样。
*# First create the base model to tune* rf = RandomForestClassifier()*# Random search of parameters, using 3 fold cross validation,
# search across 100 different combinations, and use all available cores*rf_random = RandomizedSearchCV(estimator = rf, param_distributions = random_grid, n_iter = 100, cv = 3, verbose=2, random_state=42, n_jobs = -1)*# Fit the random search model* rf_random.fit(final_train[selected_features], final_train['Survived'])
rf_random.best_params_
现在,我们已经从提供给算法的给定范围中获得了一组最佳参数,让我们使用 sci-kit learn 提供的默认值和我们获得的值来训练随机森林分类器。
X = final_train[selected_features]
y = final_train['Survived']X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.15, random_state=2)*# fitting both base random forest model and RandomizedSearchCV random forest model* base_model = RandomForestClassifier()
base_model.fit(X_train, y_train)best_random = RandomForestClassifier(n_estimators = 2000, min_samples_split= 5, min_samples_leaf = 1, max_features = 'sqrt', max_depth = 100, bootstrap = True)best_random.fit(X_train, y_train)
现在我们已经训练了这些模型,让我们使用下面定义的评估函数来评估它们。
def evaluate(model, test_features, test_labels):
predictions = model.predict(test_features)
errors = abs(predictions - test_labels)
accuracy = accuracy_score(test_labels, predictions) * 100
print('Model Performance')
print('Average Error: **{:0.4f}** degrees.'.format(np.mean(errors)))
print('Accuracy = **{:0.2f}**%.'.format(accuracy)) return accuracybase_accuracy = evaluate(base_model, X_test, y_test)
random_accuracy = evaluate(best_random, X_test, y_test)
我们观察到,基础模型的测试精度为 84.33%,而我们提供随机搜索获得的参数的模型的测试精度为 81.34%,这应该高于基础模型的精度。这可能是因为训练数据集不够大,或者我们提供给随机搜索选择的值可能包含了最佳值的范围。不过,我们肯定可以用它来提高我们的准确性。
类似地,我还应用了 GridSearchCV 来检查分类器的准确性,同样是 81%左右。相对较低的准确性可能是由于上述原因造成的。
但是,从这个练习中得到的关键收获是,我们将模型在测试集上的准确性从使用逻辑回归的 77.6%提高到使用随机森林算法的大约 84%,这确实证明了我们上面对随机森林算法的讨论是正确的。当我在 Kaggle 上提交这个模型的结果时,我收到了 0.7751 的公开分数,这比我们收到的逻辑回归分类器的分数(0.7703)要好,虽然差不了多少,但足以向前迈出一步,以改进已经存在的健壮分类器。
这篇文章的完整代码可以在这里找到。
这个帖子到此为止。在迄今为止的所有帖子中,我们已经非常详细地探索了最常用的监督机器学习算法。从的下一篇文章开始,我们将深入无监督学习的基础知识,并学习各种无监督学习算法,从 K-means 聚类开始。
无监督学习和深入 K-Means
原文:https://towardsdatascience.com/machine-learning-vi-unsupervised-learning-k-means-kaggle-dataset-with-k-means-1adf5c30281b?source=collection_archive---------42-----------------------
以及用 K-Means 求解的 Kaggle 数据集
内容
在本帖中,我们将了解:
- 无监督学习
- K 均值的工作示例
- K 均值的代价函数
- 集群的初始化方法
- 肘法(试凑法)
- Kaggle 的信用卡数据集来映射用户的消费活动
到目前为止,在关于机器学习的系列文章中,我们已经看了到目前为止最流行的监督算法。在之前的帖子中,我们详细讨论了决策树和随机森林。这篇文章和接下来的几篇文章将重点关注无监督学习算法,它们背后的直觉和数学,最后是一个求解的 Kaggle 数据集。
无监督学习
在没有监督的情况下完成的学习任务是无监督学习。与有监督的机器学习算法不同,无监督学习的训练数据中不存在监督机器学习模型性能的标签。但是,像监督学习算法一样,非监督学习用于离散和连续数据值。形式上,无监督学习是一种机器学习算法,用于从由没有标记响应的输入数据组成的数据集进行推断。
(来源
无监督学习有两种类型:判别模型和生成模型。辨别模型只能告诉你,如果你给它 X,那么结果是 Y,而生成模型可以告诉你,你将同时看到 X 和 Y 的总概率。
所以区别如下:判别模型给输入分配标签,没有预测能力。如果你给它一个不同的 X,它从来没有见过,它不知道 Y 会是什么,因为它还没有学会。有了生成模型,一旦你设置好它并找到基线,你可以给它任何输入并要求预测。因此,它具有预测能力。
无监督学习的两个常见用例是:
(一)聚类分析,又称探索性分析
(二)主成分分析
聚类分析或聚类的任务是以这样一种方式将数据点分组,即一个聚类中的数据点与其他聚类中的数据点相似而不同。聚类有多种应用,例如在市场细分、模式识别、词向量、检测网络攻击等许多领域。
主成分分析用于降低数据集的维度(特征的数量)。除了降低维度,主成分分析还将数据转换成人类难以理解的数字形式。通过主成分分析,模型的训练时间可以在很大程度上减少,而精度只有非常轻微的下降。
无监督学习的一些常见例子是 K-means、主成分分析(PCA)、自动编码器等。在这篇文章中,我们将详细介绍 K-means 算法。
无监督学习示例(来源)
k 均值
让我们首先掌握术语“K-Means”的用法。在统计学中,“平均值”是指一组给定数据点的平均值。这意味着该算法处理“K”平均值。但是,“K”平均值意味着什么呢?我们通常只有一个代表整个数据的平均值。拥有“K”个平均值意味着我们已经对“K”个数据段执行了“均值”运算,每个数据段都可以被视为一个单独的独立单元。因此,只有当给定数据被分成“K”个部分/组/簇时,才有可能获得“K”个平均值。术语 K-means 本身足以描述它是一种聚类算法,因此我们应该避免将术语“聚类”与 K-means 一起使用。稍后我们会看到这正是 K-means 背后的数学原理。
从形式上来说,K-Means 是一种无监督学习算法,它采用具有“m”条记录的未标记数据集,并将其分组为“K”个子集/聚类,其中每个聚类都具有具有相似属性和 K < m. The algorithm however is not intelligent enough to determine the number of clusters in the data automatically and hence requires a predefined number of clusters (K) to divide the data into ‘K’ coherent groups. That being said, K-means is still one of the most widely used clustering algorithms due to its simplicity and fast computation time.
K-means algorithm works in 2 steps.
(i) Cluster assignment
(ii) Move centroid
Both of these steps are repeated until the algorithm converges.
K-Means Working Example
To better understand the 2 steps of K-means, let’s look at how K-means works through an example and the optimization objective (cost function) involved. In order to visualize things, we’ll assume that the data we’re using just has 2 features i.e. 2-dimensional data. Let us divide the data into 2 clusters, so K = 2.
K-Means Working (源的记录
给定图(a)中原始数据的散点图,首先在图上选择 2 个随机点(聚类质心)(图 b)。一旦选择了这些点,就计算所有数据点到所选聚类点的接近度。有许多方法可以计算邻近度,最简单的方法之一是使用欧几里德距离。一旦计算出所有的欧几里德距离,就将数据点分配给离它们最近的那些聚类质心。在图 c 中,基于数据点与聚类质心的接近度,将数据点分配给红色/蓝色聚类质心。这是聚类分配步骤,其中每个数据点被分配给一个聚类。但是这些聚类分配不是最优的,因为聚类质心的初始值是随机选择的。为了克服这个问题,计算属于一个聚类的所有数据点的中心值,并将聚类质心移动到这个新位置,如图 d 所示。这是移动质心步骤。到目前为止,我们已经执行了一次聚类分配和移动质心步骤的迭代,还没有将数据点很好地划分成聚类。为了使 K-means 算法收敛,我们需要对这两个步骤进行多次迭代。图 e 对图 d 中获得的新的聚类质心执行“聚类分配步骤”,然后图 f 执行“移动质心步骤”以给出新的最佳聚类质心。此时,经过这些步骤的 2 次迭代,我们似乎已经达到了给定数据点的最佳聚类分组。实际上,要达到最佳的集群分组需要大量的迭代。
上述 K-means 聚类的整个过程可以通过下面的伪代码来总结。
Initialize cluster centroids µ(1), µ(2), µ(3), ……, µ(k) **∈ R**n randomly, where **R**n represents a feature vector of n-dimensions.Repeat until convergence:
{
for i = 1 to m
c(i) = cluster centroid closest to training example x(i)
for k = 1 to K
µ(k) = average (mean) of points assigned to cluster k
}
价值函数
现在我们知道了 K-means 中涉及的步骤如何导致聚类,让我们尝试通过这些步骤背后的直觉来获得所涉及的优化目标(成本函数)。在一行中,K-means 算法确定每个数据点的聚类质心,然后将聚类质心移动到该聚类的中心位置,并且重复这两个步骤,直到算法收敛。因此,成本函数应该最小化每个聚类质心与其对应数据点的总距离;服从于“群集分配步骤”和“移动质心步骤”中出现的条件。
在正式定义 K-means 的代价函数之前,让我们看一下用来定义代价函数的符号。
c(i) =训练示例 x(i)当前被分配到的分类号(在 1 和 K 之间)
(k) =群集质心的表示((k) ∈ R n)
(c(i)) =训练示例 x(i)已被分配到的聚类的聚类质心的表示。
成本函数的参数是 c(i)和(k)(也是 c(i)),因为通过改变这些参数,我们可以得到不同的聚类,并且目标是得到通过最小化成本函数可以得到的最佳聚类。K 均值的最小化目标是:
并且成本函数产生最小值的 c(i)和(k)的值是这些参数的最佳值。在“聚类分配步骤”期间,在参数 c(i)保持(k)固定的情况下最小化成本函数(即成本函数对 c(i)变量取偏导数),并且在“移动质心”步骤期间,在参数 c(i)保持固定的情况下最小化成本函数(即成本函数对(k)变量取偏导数)。
梯度下降算法然后在计算这两个偏导数的总和之后更新成本函数,并使我们能够达到全局最小值/良好的局部最小值。
初始化集群
在 k-means 的伪代码中,我们看到了聚类分配步骤和移动质心步骤如何协同工作来生成 k 个聚类,但我们仍然没有讨论如何随机初始化聚类质心,这是伪代码的第一行。就像我们在线性和逻辑回归中随机初始化参数‘W’和‘b’一样,这里,随机初始化参数 c(i)和(k)有不同的方式。让我们逐一讨论。
(i) Forgy 初始化 : Forgy 初始化是一种很好的快速初始化参数的方法。对于 K 个聚类,Forgy 方法从训练数据集中随机选择 K 个观测值,并将其作为初始均值(聚类质心)。Forgy 初始化是一种用于初始化聚类质心的非常直观的技术,因为聚类质心将位于训练数据点附近的某处,然而在实践中,它倾向于将初始均值展开,即算法需要更多的步骤来收敛。
(ii) 随机划分:该方法将每个数据点随机分配到 K 个聚类中的一个,同组的数据点组合在一起形成组,取其平均值来确定初始的聚类质心。随机划分方法通常是模糊 k-means 的首选,但对于标准 k-means,forgy 初始化工作良好。
(iii) K-means++ :这种方法背后的直觉是,展开 K 个初始聚类质心是一件好事。从被聚类的数据点中均匀随机地选择第一个聚类质心,之后从剩余的数据点中选择每个后续的聚类质心,其概率与其到该点最近的现有聚类中心的距离的平方成比例。这种方法优于 Forgy 初始化和随机分区方法,是首选方法。更多关于 K-means++的信息可以在这里找到。
局部最优问题
尽管上面提到的随机初始化对于 K-means 工作得很好,但是它们可能导致 K-means 收敛到成本函数的不良局部最优(一些局部最优接近全局最优,一些不接近全局最优),从而导致较差的聚类形成。事实上,在所有具有随机初始化步骤的算法中,它们都有陷入局部最优的风险,甚至是线性和逻辑回归算法。请看下图,当算法陷入糟糕的局部最优时,K-means 形成的聚类的一个例子。
这些坏的局部最优对模型的性能是有害的。我们需要避免这种情况。解决方案很简单。对于 2–10 之间的 K 值,我们可以通过运行 10 到 1000 次 K 均值迭代来解决这个问题,每次使用不同的初始随机初始化,并选择一个模型,对于该模型,获得的参数集(c(i)和(K))导致成本函数的最小值。然而,这种方法不适用于大 K 值,因为我们想要的聚类越多,算法收敛到局部最优的机会就越大。因此,在这种情况下,我们不需要应用 K-means 很多次,因为每次都有很高的机会收敛到局部最小值。对于大 K 值,K 均值的单次迭代给出了令人满意的结果。
选择 K
由于未标记的数据,我们无法评估 K-means 模型的性能,变量 K 的选择变得具有挑战性。在这种情况下,最明智的做法是使用试凑法。在用于 K-means 的试凑法中,我们选择 K 值的范围(假设 1 到 10),并通过在所选范围内的每个可能的 K 值运行 K-means 来计算总成本。成本函数急剧下降的 K 值,以及在此之后成本函数缓慢下降的 K 值,可以被认为是 K 的最佳值。这种方法被称为肘方法,但我喜欢称之为试凑法。然而,并不强制选择该拐点作为 K 的最佳值。成本函数值随着 K 值的增加而减小,并且当 K = m(训练数据点的总数)时达到 0,这发生在每个数据点是其自身唯一聚类的一部分时。虽然我们不希望 K = m,但是我们可以根据我们手头的计算能力、数据量和数据复杂度来超越肘点。
肘法举例(来源
附加注释
到目前为止,我们已经非常详细地讨论了 K-means,我想把你的注意力吸引到我们刚刚开始讨论 K-means 的时候。我提到过 K-means 的局限性之一是它不能自动捕获所有的聚类,并且需要一个明确的聚类数目值。然而,这也可以成为一种优势。考虑这样一个数据集,我们需要为一项任务(如市场细分)找到聚类,但数据点是均匀分散的。在这种情况下,自动捕获聚类的算法更有可能失败。但是通过提供给 K-means 的明确的聚类数,我们可以期望该算法得出甚至人类都无法找到的良好分组。这就是 K-means 的妙处。
关于 K-means 需要注意的另一件重要事情是,K-means 导致聚类的线性分离。这可能令人吃惊,但没什么可担心的。聚类(在一组数据点周围手工绘制的代表聚类的曲线形状)仍然与我们目前所描绘的非常相似。下图会让事情更清楚。
聚类的线性分离(来源)
至此,我们结束了对 K-means 的讨论。现在,让我们使用 Kaggle 的一个未标记的信用卡数据集,并使用它来确定不同信用卡持有者的信用卡使用模式。
问题陈述
我们将使用 Kaggle 上的信用卡数据集来确定地图消费活动。数据集可以在这里找到。按照惯例,我们需要对数据进行预处理,以便将其输入 K-means 算法。首先,让我们将数据读入熊猫数据帧。
import numpy as np
import pandas as pdimport matplotlib.pyplot as plt
from sklearn.preprocessing import StandardScaler
from sklearn.cluster import KMeans
from sklearn.decomposition import PCA
import osfor dirname, _, filenames in os.walk('/kaggle/input'):
for filename in filenames:
print(os.path.join(dirname, filename))
df = pd.read_csv(‘/kaggle/input/ccdata/CC GENERAL.csv’)
print(df.shape)
df.head()
df.describe()
数据集中有 18 个特征很难放入单个图像中。但是,从 df.describe()的输出中,我们可以看到,对于所有的列/特征,标准偏差都很高,最小值和最大值相差太远,分布偏向较低值,这可以从 75%标记、平均值和最大值中看出。这意味着给定的数据集包含离群值,需要处理这些离群值。简单地忽略离群值会导致大量数据丢失。
在我们处理异常值之前,让我们检查数据中缺失的值并估算它们。
df.isna().sum()
只有两列有空值。缺失值是整个数据集(1/8950)和(313/8950)的一小部分,因此很容易估算。我们将使用平均值估算 CREDIT_LIMIT,由于 MINIMUM_PAYMENTS 是一个偏向下侧的连续变量,我们可以使用平均值或中值估算它。这应该不会有太大的差别,因为丢失值的比例非常小。我们会用平均值来估算。
df[‘MINIMUM_PAYMENTS’].fillna(df[‘MINIMUM_PAYMENTS’].mean(skipna=True), inplace=True)df[‘CREDIT_LIMIT’].fillna(df[‘CREDIT_LIMIT’].mean(skipna=True), inplace=True)
既然我们已经处理了丢失的值,让我们把注意力放回到异常值上。让我们将整个数据集的值转换为分类值。由于我们对通过分类寻找相似性感兴趣,所以将特定范围内的值分组并给它们分配一个类别是一个好主意。稍后,我们还将对这些类别值进行标准化,以确保任何列中没有大值主导/扭曲聚类结果。
columns = ['BALANCE', 'PURCHASES', 'ONEOFF_PURCHASES', 'INSTALLMENTS_PURCHASES', 'CASH_ADVANCE', 'CREDIT_LIMIT','PAYMENTS', 'MINIMUM_PAYMENTS'] # All features with outlandish valuesfor c in columns:
Range = c+'_RANGE'
df[Range]=0
df.loc[((df[c]>0)&(df[c]<=500)),Range]=1
df.loc[((df[c]>500)&(df[c]<=1000)),Range]=2
df.loc[((df[c]>1000)&(df[c]<=3000)),Range]=3
df.loc[((df[c]>3000)&(df[c]<=5000)),Range]=4
df.loc[((df[c]>5000)&(df[c]<=10000)),Range]=5
df.loc[((df[c]>10000)),Range]=6columns=['BALANCE_FREQUENCY', 'PURCHASES_FREQUENCY', 'ONEOFF_PURCHASES_FREQUENCY', 'PURCHASES_INSTALLMENTS_FREQUENCY', 'CASH_ADVANCE_FREQUENCY', 'PRC_FULL_PAYMENT']for c in columns:
Range=c+'_RANGE'
df[Range]=0
df.loc[((df[c]>0)&(df[c]<=0.1)),Range]=1
df.loc[((df[c]>0.1)&(df[c]<=0.2)),Range]=2
df.loc[((df[c]>0.2)&(df[c]<=0.3)),Range]=3
df.loc[((df[c]>0.3)&(df[c]<=0.4)),Range]=4
df.loc[((df[c]>0.4)&(df[c]<=0.5)),Range]=5
df.loc[((df[c]>0.5)&(df[c]<=0.6)),Range]=6
df.loc[((df[c]>0.6)&(df[c]<=0.7)),Range]=7\
df.loc[((df[c]>0.7)&(df[c]<=0.8)),Range]=8
df.loc[((df[c]>0.8)&(df[c]<=0.9)),Range]=9
df.loc[((df[c]>0.9)&(df[c]<=1.0)),Range]=10columns=['PURCHASES_TRX', 'CASH_ADVANCE_TRX']for c in columns:
Range=c+'_RANGE'
df[Range]=0
df.loc[((df[c]>0)&(df[c]<=5)),Range]=1
df.loc[((df[c]>5)&(df[c]<=10)),Range]=2
df.loc[((df[c]>10)&(df[c]<=15)),Range]=3
df.loc[((df[c]>15)&(df[c]<=20)),Range]=4
df.loc[((df[c]>20)&(df[c]<=30)),Range]=5
df.loc[((df[c]>30)&(df[c]<=50)),Range]=6
df.loc[((df[c]>50)&(df[c]<=100)),Range]=7
df.loc[((df[c]>100)),Range]=8
因为我们已经修改了所有现有的特性名称,所以我们可以删除现有的特性名称。
df.drop(['CUST_ID', 'BALANCE', 'BALANCE_FREQUENCY', 'PURCHASES', 'ONEOFF_PURCHASES', 'INSTALLMENTS_PURCHASES', 'CASH_ADVANCE', 'PURCHASES_FREQUENCY', 'ONEOFF_PURCHASES_FREQUENCY', 'PURCHASES_INSTALLMENTS_FREQUENCY', 'CASH_ADVANCE_FREQUENCY', 'CASH_ADVANCE_TRX', 'PURCHASES_TRX', 'CREDIT_LIMIT', 'PAYMENTS', 'MINIMUM_PAYMENTS', 'PRC_FULL_PAYMENT' ], axis=1, inplace=True)X= np.asarray(df)df.head()
我们可以画出所有特征的频率分布。你可以在笔记本这里查看。上图显示,较低值的频率较高,因为数据中的大多数值都很小。这从我们通过 df.describe() 获得的数据分布的最小值、第一四分位数、第三四分位数中值和最大值中可以明显看出。然而,这个过程需要一定数量的试验,但并没有消耗太多时间。现在,我们将所有值标准化,以在 0–1 的范围内调整它们。
scaler = StandardScaler()
X = scaler.fit_transform(X)
既然我们已经将数据从连续值转换为离散值,并将其降低到一个特定的范围内,我们已经确保对所有的特征给予同等的重视。现在,我们可以继续应用 K-means。让我们用肘法来选择 k 的一个最优值。
clusters = 25
cost = []for i in range(1,clusters):
kmeans = KMeans(i)
kmeans.fit(X)
cost.append(kmeans.inertia_)plt.plot(cost, ‘ro-’)
当 K = 6 时,我们似乎到达了一个拐点。在这个 K 值之后,成本下降得非常慢。
kmeans = KMeans(6)
kmeans.fit(X)labels = kmeans.labels_
这一步的输出是一个“集群”变量,它包含数据集的每个记录/行的集群号。让我们在数据帧的末尾添加这个变量。
clusters = pd.concat([df, pd.DataFrame({‘cluster’:labels})], axis=1)
为了可视化所创建的集群并查看它们是否定义良好,我们需要降低数据的维度,因为在 2 维空间中很难可视化 n 维数据。然而,在降低数据维数的同时,我们希望确保尽可能多地获取原始数据集的特征。为此,我们使用主成分分析(PCA),这有助于我们实现上述目标。关注下一篇文章,深入了解 PCA。
pca = PCA(2)
principalComponents = pca.fit_transform(X)
x, y = principalComponents[:, 0], principalComponents[:, 1]
print(principalComponents.shape)colors = {0: ‘red’, 1: ‘blue’, 2: ‘green’, 3: ‘yellow’, 4: ‘orange’, 5:’purple’}
final_df = pd.DataFrame({‘x’: x, ‘y’:y, ‘label’:labels})
groups = final_df.groupby(labels)
最后,我们将所有的集群绘制成一个单独的情节中不同的支线剧情。
fig, ax = plt.subplots(figsize=(15, 10))for name, group **in** groups:
ax.plot(group.x, group.y, marker='o', linestyle='', ms=5, color=colors[name], mec='none')
ax.set_aspect('auto')
ax.tick_params(axis='x',which='both',bottom='off',top='off',labelbottom='off')
ax.tick_params(axis= 'y',which='both',left='off',top='off',labelleft='off')ax.set_title(“Customers Segmentation based on their Credit Card usage bhaviour.”)plt.show()
成绩还过得去。我们有 6 个明显不同的集群。我们看到,如果我们将聚类数选择为 5,绿色的聚类可以是黄色和紫色聚类的一部分。此外,我们还可以通过绘制聚类中每个特征的频率分布图,然后比较和对比这些图来确定每个聚类的含义。这篇文章的完整代码可以在这里找到。
这个帖子到此为止。在这篇文章中,我们对 K-means 算法进行了详细的分析。在的下一篇文章中,我们将深入探讨主成分分析,这是最流行和最广泛使用的无监督学习算法之一。
机器学习可视化
原文:https://towardsdatascience.com/machine-learning-visualization-fcc39a1e376a?source=collection_archive---------6-----------------------
入门
收集了一些有趣的技术,可以用来可视化机器学习管道的不同方面。
介绍
作为任何数据科学项目的一部分,数据可视化在了解更多可用数据和识别任何主要模式方面发挥着重要作用。
如果有可能让机器学习也成为分析的一部分,那不是很好吗?
在本文中,我们将探讨一些技术,可以帮助我们面对这一挑战,如:平行坐标图,汇总数据表,绘制人工神经网络图和更多。
本文使用的所有代码都可以在我的 Github 和 Kaggle 账户上免费获得。
技术
超参数优化
超参数优化是机器/深度学习中最常见的活动之一。机器学习模型调整是一种优化问题。我们有一组超参数(如学习率、隐藏单元数等),我们的目标是找出它们值的正确组合,这可以帮助我们找到函数的最小值(如损失)或最大值(如精度)。
在我之前的文章中,我详细介绍了我们可以在这个领域使用什么样的技术,以及如何在 3D 空间中测试它们,在这篇文章中,我将向您展示我们如何在 2D 空间中完成报告。
此类任务的最佳解决方案之一是使用平行坐标图(图 1)。使用这种类型的图,我们实际上可以很容易地比较不同的变量(如特征),以发现可能的关系。在超参数优化的情况下,这可以作为一个简单的工具来检查什么参数组合可以给我们最大的测试精度。平行坐标图在数据分析中的另一个可能用途是检查数据框中不同要素之间的值关系。
在图 1 中,有一个使用 Plotly 创建的实例。
import plotly.express as px
fig = px.parallel_coordinates(df2, color="mean_test_score",
labels=dict(zip(list(df2.columns),
list(['_'.join(i.split('_')[1:]) for i **in** df2.columns]))),
color_continuous_scale=px.colors.diverging.Tealrose,
color_continuous_midpoint=27)
fig.show()
图 1:平行坐标超参数优化图。
可以使用不同的技术在 Python 中创建平行坐标图,例如使用 Pandas、Yellowbrick、Matplotlib 或 Plotly。使用所有这些不同方法的一步一步的例子都可以在我的笔记本中找到,网址是这个链接。
最后,另一种可能的解决方案是使用权重&偏差扫描功能来创建这种类型的图。weights&bias 是一款免费工具,可用于为个人或团队自动创建不同机器学习任务的图表和日志(如学习曲线、绘图模型等)。
数据包装器
Data Wrapper 是一款为专业图表创作设计的免费在线工具。例如,纽约时报、Vox 和 WIRED 等杂志的文章中就使用了这一工具。不需要登录,所有的过程都可以在网上完成。
今年已经为这个工具额外创建了一个 Python 包装器。这可以通过以下方式轻松安装:
pip install datawrapper
为了使用 Python API,我们还需要注册 Data Wrapper,进入设置并创建一个 API 密钥。使用这个 API 键,我们就能够远程使用数据包装器。
此时,我们可以很容易地创建一个条形图,例如,通过使用下面几行代码并传递一个 Pandas 数据帧作为我们的 create_chart 函数的输入。
from datawrapper import Datawrapper
dw = Datawrapper(access_token = "TODO")*games_chart = dw.create_chart(title = "Most Frequent Game Publishers", chart_type = 'd3-bars', data = df)**dw.update_description(*
*games_chart['id'],*
*source_name = 'Video Game Sales',*
*source_url = 'https://www.kaggle.com/gregorut/videogamesales',*
*byline = 'Pier Paolo Ippolito',*
*)**dw.publish_chart(games_chart['id'])*
生成的图表如下图所示。
图 2:数据包装条形图
一旦发布了我们的图表,我们就可以在我们的数据包装器帐户上创建的图表列表中找到它。点击我们的图表,我们会发现一个不同选项的列表,我们可以使用这些选项来轻松地共享我们的图表(例如,嵌入、HTML、PNG 等)。所有不同类型的受支持图表的完整列表可在此链接获得。
Plotly 预测表
当处理时间序列数据时,能够快速了解我们的模型在哪些数据点上表现不佳,以便尝试了解它可能面临的限制,有时会非常方便。
一种可能的方法是创建一个汇总表,其中包含实际值和预测值,以及某种形式的指标,用于总结数据点预测的好坏。
使用 Plotly,这可以通过创建一个绘图函数来轻松完成:
import chart_studio.plotly as py
import plotly.graph_objs as go
from plotly.offline import init_notebook_mode, iplot
init_notebook_mode(connected=True)
import plotlydef predreport(y_pred, Y_Test):
diff = y_pred.flatten() - Y_Test.flatten()
perc = (abs(diff)/y_pred.flatten())*100
priority = []
for i in perc:
if i > 0.4:
priority.append(3)
elif i> 0.1:
priority.append(2)
else:
priority.append(1) print("Error Importance 1 reported in ", priority.count(1),
"cases\n")
print("Error Importance 2 reported in", priority.count(2),
"cases\n")
print("Error Importance 3 reported in ", priority.count(3),
"cases\n")
colors = ['rgb(102, 153, 255)','rgb(0, 255, 0)',
'rgb(255, 153, 51)', 'rgb(255, 51, 0)'] fig = go.Figure(data=[go.Table(header=
dict(
values=['Actual Values', 'Predictions',
'% Difference', "Error Importance"],
line_color=[np.array(colors)[0]],
fill_color=[np.array(colors)[0]],
align='left'),
cells=dict(
values=[y_pred.flatten(),Y_Test.flatten(),
perc, priority],
line_color=[np.array(colors)[priority]],
fill_color=[np.array(colors)[priority]],
align='left'))]) init_notebook_mode(connected=False)
py.plot(fig, filename = 'Predictions_Table', auto_open=True)
fig.show()
调用这个函数将产生以下输出(请随意测试图 3 中的表格!):
Error Importance 1 reported in 34 cases
Error Importance 2 reported in 13 cases
Error Importance 3 reported in 53 cases
图 3:预测表
决策树
决策树是最容易解释的机器学习模型之一。由于它们的基本结构,通过查看树的不同分支上的条件,可以很容易地检查算法如何做出决定。此外,考虑到算法将认为对我们期望的分类/回归任务最有价值的特征放在树的顶层,决策树也可以用作特征选择技术。以这种方式,树底部的特征可以被丢弃,因为携带较少的信息。
可视化分类/回归决策树最简单的方法之一是使用export _ graphvizfromsk learn . tree。 在本文中,使用 dtreeviz 库提供了一种不同且更完整的方法。
使用这个库,只需使用下面几行代码就可以创建一个分类决策树:
from dtreeviz.trees import *
viz = dtreeviz(clf,
X_train,
y_train.values,
target_name='Genre',
feature_names=list(X.columns),
class_names=list(labels.unique()),
histtype='bar',
orientation ='TD')
viz
结果图如图 4 所示。
图 4:分类决策树
在图 4 中,不同的类别用不同的颜色表示。所有不同类别的特征分布在树的起始节点中表示。只要我们向下移动每个分支,算法就会尝试使用每个节点图下面描述的功能来最好地分离不同的分布。沿着分布生成的圆表示在跟随某个节点之后被正确分类的元素的数量,元素的数量越大,圆的大小就越大。
图 5 显示了一个使用决策树回归器的例子。
图 5:决策树回归器
决策界限
决策边界是以图形方式理解机器学习模型如何进行预测的最简单方法之一。在 Python 中绘制决策边界的最简单方法之一是使用 Mlxtend 。这个库实际上可以用于绘制机器学习和深度学习模型的决策边界。图 6 显示了一个简单的例子。
from mlxtend.plotting import plot_decision_regions
import matplotlib.pyplot as plt
import matplotlib.gridspec as gridspec
import itertoolsgs = gridspec.GridSpec(2, 2)
fig = plt.figure(figsize=(10,8))
clf1 = LogisticRegression(random_state=1,
solver='newton-cg',
multi_class='multinomial')
clf2 = RandomForestClassifier(random_state=1, n_estimators=100)
clf3 = GaussianNB()
clf4 = SVC(gamma='auto')
labels = ['Logistic Regression','Random Forest','Naive Bayes','SVM']
for clf, lab, grd **in** zip([clf1, clf2, clf3, clf4],
labels,
itertools.product([0, 1], repeat=2)):
clf.fit(X_Train, Y_Train)
ax = plt.subplot(gs[grd[0], grd[1]])
fig = plot_decision_regions(X_Train, Y_Train, clf=clf, legend=2)
plt.title(lab)
plt.show()
图 6:绘制决策边界
Mlxtend 的一些可能的替代方案是:Yellowbrick、Plotly 或普通的 Sklearn 和 Numpy 实现。使用所有这些不同方法的一步一步的例子都可以在我的笔记本中找到,网址是这个链接。
此外,在我的网站链接上可以看到训练期间决策界限融合的不同动画版本。
绘制决策边界的主要限制之一是,它们只能在二维或三维中容易地可视化。由于这些限制,在绘制决策边界之前,大多数时候可能需要减少输入特征的维数(使用某种形式的特征提取技术)。
人工神经网络
当创建新的神经网络架构时,另一个非常有用的技术是可视化它们的结构。这可以使用 ANN Visualiser 轻松完成(图 7)。
from keras.models import Sequential
from keras.layers import Dense
from ann_visualizer.visualize import ann_viz
model = Sequential()
model.add(Dense(units=4,activation='relu',
input_dim=7))
model.add(Dense(units=4,activation='sigmoid'))
model.add(Dense(units=2,activation='relu'))
ann_viz(model, view=True, filename="example", title="Example ANN")
图 7:人工神经网络图
活线图
在训练和验证过程中,能够自动绘制实时神经网络损失和准确性,这对于立即查看网络是否随着时间推移取得任何进展非常有帮助。这可以通过使用 Livelossplot 轻松完成。
在图 8 中,提供了一个在 Pytorch 中实时创建的损耗图示例,同时训练一个变分自动编码器(VAE)。
图 8:现场 VAE 培训
使用 Livelossplot,这可以通过将我们想要记录的所有指标存储在一个字典中并在每次迭代结束时更新绘图来轻松完成。如果我们对创建多个图表感兴趣,可以应用相同的过程(例如,一个用于损失,一个用于总体精度)。
from livelossplot import PlotLossesliveloss = PlotLosses()for epoch in range(epochs):
logs = {}
for phase in ['train', 'val']:
losses = []
if phase == 'train':
model.train()
else:
model.eval()
for i, (inp, _) in enumerate(dataloaders[phase]):
out, z_mu, z_var = model(inp)
rec=F.binary_cross_entropy(out,inp,reduction='sum')/
inp.shape[0]
kl=-0.5*torch.mean(1+z_var-z_mu.pow(2)-torch.exp(z_mu))
loss = rec + kl
losses.append(loss.item())
if phase == 'train':
optimizer.zero_grad()
loss.backward()
optimizer.step()
prefix = ''
if phase == 'val':
prefix = 'val_' logs[prefix + 'loss'] = np.mean(losses) liveloss.update(logs)
liveloss.send()
Livelossplot 还可以与其他库一起使用,如 Keras、Pytorch-Lightin、Bokeh 等
可变自动编码器
变分自动编码器(VAE)是一种概率生成模型,用于创建一些输入数据(例如图像)的潜在表示,能够简明地理解原始数据并从中生成全新的数据(例如,用汽车设计的不同图像训练 VAE 模型,然后使模型能够创建全新的富有想象力的汽车设计)。
继续使用 Livelossplot 训练的示例 variable auto encoder,我们甚至可以通过检查潜在空间(图 9)如何从一次迭代到另一次迭代而变化(以及因此我们的模型在区分不同类别方面随着时间的推移改进了多少)来使我们的模型更有趣。
这可以通过在之前的训练循环中添加以下函数来轻松完成:
def latent_space(model, train_set, it=''):
x_latent = model.enc(train_set.data.float())
plt.figure(figsize=(10, 7))
plt.scatter(x_latent[0][:,0].detach().numpy(),
x_latent[1][:,1].detach().numpy(),
c=train_set.targets)
plt.colorbar()
plt.title("VAE Latent Space", fontsize=20)
plt.xlabel("X", fontsize=18)
plt.ylabel("Y", fontsize=18)
plt.savefig('VAE_space'+str(it)+'.png', format='png', dpi=200)
plt.show()
图 9: VAE 潜在空间演变
最后,可以应用类似的程序来实时可视化我们的 VAE 在生成真实图像时是如何逐迭代改进的(图 10)。
def manifold(model, it='', n=18, size=28):
result = torch.zeros((size * n, size * n)) # Defyining grid space
s, s2 = torch.linspace(-7, 7, n), torch.linspace(7, -7, n)
grid_x, grid_y = torch.std(s)*s, torch.std(s2)*s2 for i, y_ex in enumerate(grid_x):
for j, x_ex in enumerate(grid_y):
z_sample = torch.repeat_interleave(torch.tensor([
[x_ex, y_ex]]),repeats=batch_size, dim=0)
x_dec = model.dec(z_sample)
element = x_dec[0].reshape(size, size).detach()
result[i * size: (i + 1) * size,
j * size: (j + 1) * size] = element plt.figure(figsize=(12, 12))
plt.title("VAE Samples", fontsize=20)
plt.xlabel("X", fontsize=18)
plt.ylabel("Y", fontsize=18)
plt.imshow(result, cmap='Greys')
plt.savefig('VAE'+str(it)+'.png', format='png', dpi=300)
plt.show()
图 10:随着时间的推移,创造新数字的 VAE 改进
一个使用 ONNX 在线部署的变分自动编码器的实际演示,可以在我的个人网站上的链接获得。
单词嵌入
神经网络嵌入是一类神经网络,旨在学习如何将某种形式的分类数据转换为数字数据。考虑到在转换数据时,他们能够了解数据的特征,因此构建更简洁的表示(创建潜在空间),使用嵌入比使用其他技术(如一个热编码)更有优势。两种最著名的预训练单词嵌入类型是 word2vec 和 Glove。
作为一个简单的例子,我们现在要绘制一个嵌入空间来表示不同的书籍作者。首先,我们需要在一些可用的数据上创建一个训练模型,然后访问模型嵌入层的训练好的权重(在这种情况下称为 嵌入 )并将它们存储在一个数据帧中。这个过程完成后,我们只需绘制三个不同的坐标(图 11)。
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import axes3d, Axes3Dembedding_weights=pd.DataFrame(model.embed.weight.detach().numpy())
embedding_weights.columns = ['X1','X2','X3']fig = plt.figure(num=None, figsize=(14, 12), dpi=80,
facecolor='w', edgecolor='k')
ax = plt.axes(projection='3d')
for index, (x, y, z) in enumerate(zip(embedding_weights['X1'],
embedding_weights['X2'],
embedding_weights['X3'])):
ax.scatter(x, y, z, color='b', s=12)
ax.text(x, y, z, str(df.authors[index]), size=12,
zorder=2.5, color='k')ax.set_title("Word Embedding", fontsize=20)
ax.set_xlabel("X1", fontsize=20)
ax.set_ylabel("X2", fontsize=20)
ax.set_zlabel("X3", fontsize=20)
plt.show()
图 11:单词嵌入
在这个例子中,网络的嵌入维度已经被直接设置为 3,以便随后容易地创建 3D 可视化。另一个可能的解决方案是使用更高的嵌入输出大小,然后应用某种形式的特征提取技术(例如 t-SNE、PCA 等)来可视化结果。
另一个可以用来可视化分类数据的有趣技术是单词云(图 12)。例如,这种类型的表示可以通过创建图书作者姓名及其各自在数据集中的频率计数的字典来实现。在数据集中出现频率较高的作者将在图中以更大的字体显示。
from wordcloud import WordCloudd = {}
for x, a in zip(df.authors.value_counts(),
df.authors.value_counts().index):
d[a] = xwordcloud = WordCloud()
wordcloud.generate_from_frequencies(frequencies=d)
plt.figure(num=None, figsize=(12, 10), dpi=80, facecolor='w',
edgecolor='k')
plt.imshow(wordcloud, interpolation="bilinear")
plt.axis("off")
plt.title("Word Cloud", fontsize=20)
plt.show()
图 12: Wordcloud 示例
和往常一样,完整的代码可以在我的 Github 账户上找到。
可解释的人工智能
可解释的人工智能如今是一个不断发展的研究领域。人工智能在决策应用(如就业)中的使用最近引起了个人和当局的一些关注。这是因为,当使用深度神经网络时,当前不可能(至少在完全程度上)理解算法在必须执行预定任务时执行的决策过程。由于决策过程缺乏透明度,公众可能会对模型本身的可信度产生困惑。因此,为了防止在人工智能模型中出现任何形式的偏见,对可解释人工智能的需求正在成为下一个预定的进化步骤。
在过去的几年中,为了使机器学习更容易解释,已经引入了不同的可视化技术,例如:
- 探索卷积神经网络滤波器和特征映射。
- 图形网络。
- 基于贝叶斯的模型。
- 应用于机器学习的因果推理。
- 本地/全球代理模型。
- 引入局部可解释的模型不可知解释(LIME)和 Shapley 值。
如果你有兴趣了解更多关于如何使机器学习模型更具可解释性的信息,目前 Python 中最有趣的两个库是 Pytorch 的 Captum 和 XAI 。
由于这一研究领域在不断改进,我将致力于在未来的一篇专门讨论可解释人工智能的文章中涵盖所有这些不同的主题(以及更多)。
结论
如果您有兴趣了解更多机器学习可视化技术,Pythonyellow brick library高度关注这个主题。提供的可视化工具的一些例子是:特征排序、ROC/AUC 曲线、K 肘图和各种文本可视化技术。
最后,在过去的几年里,为了使机器学习可视化更容易,不同的框架已经开始被开发,例如: TensorBoard 、Weights&bias和 Neptune.ai 。
希望您喜欢这篇文章,感谢您的阅读!
联系人
如果你想了解我最新的文章和项目,请在 Medium 上关注我,并订阅我的邮件列表。以下是我的一些联系人详细信息:
- 领英
- 个人博客
- 个人网站
- 中等轮廓
- GitHub
- 卡格尔
机器学习-可视化
原文:https://towardsdatascience.com/machine-learning-visualized-11965ecc645c?source=collection_archive---------20-----------------------
理解机器学习的视觉方法
列宁·艾斯特拉达在 Unsplash 上的照片
机器学习导论
在传统的硬编码方法中,我们通过编程让计算机执行某项任务。当它收到某个输入时,我们准确地告诉它该做什么。用数学术语来说,这就像是我们编写了 f(x) 这样当用户将输入 x 输入到 f(x) 中时,它会给出正确的输出 y 。
然而,在机器学习中,我们有一大组输入 x 和相应的输出 y 但没有函数 f(x) 。这里的目标是找到将输入转换为输出的 f(x) 嗯,这可不是件容易的事。在本文中,我们将了解这是如何发生的。**
资料组
为了可视化数据集,让我们制作我们的合成数据集,其中每个数据点(输入 x )是三维的,使其适合绘制在 3D 图表上。我们将在以原点(0,0,0)为中心的簇中生成 250 个点(簇 0)** 。生成一个类似的 250 个点的群集(群集 1) ,但不以原点为中心。两个集群都相对接近,但有一个清晰的分离,如下图所示。这两个聚类是两类数据点。大绿点代表整个数据集的质心。**
作者图片
生成数据集后,我们将通过减去平均值并除以标准差来对其进行归一化。这样做是为了使数据以零为中心,并将数据集中每个维度的值映射到一个公共比例。这加快了学习的速度。
数据将保存在数组 X 中,其中包含标准化点的 3D 坐标。我们还将生成一个数组 Y ,根据 3D 点属于哪个簇,每个索引的值为 0 或 1。
可学习功能
现在我们已经准备好了数据,我们可以说我们有了 x 和 y. 我们知道数据集是线性可分的,这意味着有一个平面可以将数据集分成两个聚类,但是我们不知道这样一个最优平面的方程是什么。现在,我们就随便坐一架飞机吧。
函数 f(x)应该将一个 3D 坐标作为输入,并输出一个介于 0 和 1 之间的数字。如果该数字小于 0.5,则该点属于聚类 0,否则,它属于聚类 1。让我们为这个任务定义一个简单的函数。
x :形状的输入张量(num_points,3)
W:随机选择的形状(3,1)的权重(参数)
B:随机选择的形状(1,1)的偏差(参数)
Sigmoid:映射 0 和 1 之间的值的函数
让我们花一点时间来理解这个函数的含义。在应用 sigmoid 函数之前,我们只是创建了一个从 3D 坐标(输入)到 1D 输出的线性映射。因此,该功能会将整个 3D 空间挤压到一条线上,这意味着原始 3D 空间中的每个点现在都会位于这条线上的某个位置。由于这条线将延伸到无穷大,我们使用 Sigmoid 函数将其映射到 [0,1] 。因此,对于每个给定的输入, f(x) 将输出一个介于 0 和 1 之间的值。
记住 W 和 B 是随机选择的,所以 3D 空间会被挤压到一条随机的线上。这个变换的判定边界是使 f(x) = 0.5 的点集。想想为什么!当 3D 空间被挤压到 1D 线上时,整个平面被映射到线上的值 0.5。这个平面是 f(x)的判定边界。理想情况下,它应该将数据集分成两个集群,但是由于随机选择了 W 和 B ,因此该平面随机定向,如下所示。
作者图片
我们的目标是为 W 和 B 找到正确的值,以将数据集划分为两个集群的方式来定位该平面(决策边界)。完成后,生成如下所示的平面。
作者图片
失败
所以,我们现在处于起点(随机决策边界),我们已经定义了目标。我们需要一个指标来决定我们离目标有多远。分类器的输出是形状张量(num_points,1),其中每个值在【0,1】之间。如果你仔细想想,这些值只是属于聚类 1 的点的概率。所以,我们可以说:
- f(x) = P(x 属于簇 1)
- 1-f(x) = P(x 属于群集 0)
说[ 1-f(x),f(x) ]分别在簇 0 和簇 1 上形成概率分布也不会错。这是预测的概率分布。我们确切地知道数据集中的每个点属于哪个聚类(从 y )。所以,我们也有了真实概率分布为:
- [0,1]当 x 属于簇 1 时
- [1,0]当 x 属于群集 0 时
计算两个概率分布之间不一致的一个很好的度量是交叉熵函数。因为我们只处理两个类,所以我们可以使用二元交叉熵(BCE)。py torch 的 torch.nn 模块中有此功能。如果预测的概率分布与真实的概率分布非常相似,则该函数将返回一个小值,反之亦然。我们可以对所有数据点的这个值进行平均,并将其用作测试分类器性能的参数。
这个值称为损耗,从数学上讲,我们现在的目标是最小化这个损耗。
培养
既然我们已经从数学上定义了我们的目标,那么我们如何实际地达到我们的目标呢?换句话说,我们如何找到 W 和 B 的最佳值?为了理解这一点,我们将看一看一些基本的微积分。回想一下,我们目前有随机值用于 W 和 B 。学习或训练或达到目标或减少损失的过程可以分为两步:
- ****前向传播:我们通过分类器 f(x) 输入数据集,并使用 BCE 找到损失。
- ****反向传播:利用损失,调整 W 和 B 的值,使损失最小。
以上两步会反复重复,直到损失停止减少。在这种情况下,我们说我们已经达到了目标!
反向传播
前向传播很简单,上面已经讨论过了。然而,有必要花点时间来理解反向传播,因为它是机器学习的关键。回想一下,我们在 W 中有 3 个参数(变量),在 B 中有 1 个。因此,我们总共有 4 个值要优化。
一旦我们有了前向传播的损失,我们将计算损失函数相对于分类器中每个变量的梯度。如果我们为每个参数的不同值绘制损失图,我们可以看到,在每个参数的特定值处,损失最小。我绘制了每个参数的损失与参数的关系图。
作者图片
这里需要注意的一点是,对于这些参数中的每一个参数,在特定值时损耗最小,如红点所示。
让我们考虑第一个情节,讨论 w1 将如何优化。对于其他参数,该过程保持不变。最初,W 和 B 的值是随机选择的,因此 (w1,loss) 将被随机放置在这条曲线上,如绿点所示。
作者图片
现在,目标是到达红点,从绿点开始。换言之,我们需要走下坡路。观察曲线在绿点处的斜率,我们可以看出,增加 w1(向右移动)会降低损耗,从而使绿点更靠近红点。在数学术语中,如果损失相对于 w1 的梯度为负,则增加 w1 以向下移动,反之亦然。因此,w1 应更新为:
上面的方程被称为梯度下降方程。这里, learning_rate 控制我们想要增加或减少 w1 的多少。如果 learning_rate 很大,更新也会很大。这可能导致 w1 越过红点,从而错过最佳值。如果该值太小,w1 将永远无法到达红点。你可以尝试不同的学习速率值,看看哪个效果最好。一般来说,像 0.01 这样的小值在大多数情况下都适用。
在大多数情况下,单次更新不足以优化这些参数;因此,向前传播和向后传播的过程循环重复,直到损耗停止进一步降低。让我们来看看实际情况:
作者 Gif
要做的一个重要观察是,最初绿点移动很快,当它逐渐接近最小值时慢下来。最初几个时期(当绿点远离最小值时)期间的大斜率(梯度)是对参数的大更新的原因。随着绿点接近最小值,梯度减小,因此更新变得缓慢。其他三个参数以完全相同的方式并行训练。另一个重要的观察结果是,曲线的形状随时代而变化。这是因为其他三个参数 (w2,w3,b) 也在并行更新,并且每个参数都对损耗曲线的形状有贡献。
设想
让我们看看决策边界是如何随着参数的更新而实时更新的。
作者 Gif
那都是乡亲们!
如果你成功了,向你致敬!在这篇文章中,我们采用了一种视觉方法来理解机器学习是如何工作的。到目前为止,我们已经看到了如何使用简单的 3D 到 1D 映射,【f(x),来将决策边界(2D 平面)拟合到线性可分离数据集(3D)。我们讨论了如何使用前向传播来计算损耗,然后使用反向传播来计算损耗相对于参数的梯度,并在训练循环中重复更新参数。
有什么建议请留言评论。我定期写文章,所以你应该考虑关注我,在你的订阅中获得更多这样的文章。
如果你喜欢这篇文章,你可能也会喜欢这些:
** [## 用 Pytorch 检测人脸标志点
想知道 Snapchat 或 Instagram 如何将惊人的滤镜应用到你的脸上吗?该软件检测你的关键点…
towardsdatascience.com](/face-landmarks-detection-with-pytorch-4b4852f5e9c4) [## 主成分分析-可视化
使用主成分分析(PCA)的数据压缩
towardsdatascience.com](/principal-component-analysis-visualized-17701e18f2fa)
访问我的网站,了解更多关于我和我的工作。**
机器学习 Web 应用程序部署的 5 个步骤
原文:https://towardsdatascience.com/machine-learning-web-application-deployment-in-5-steps-d8eb6a389cdd?source=collection_archive---------23-----------------------
数据科学冲刺
你已经建立了一个模型和一个应用程序;现在是时候让世界看看了!学习使用 AWS 免费部署 ML web 应用程序。
让我给你描述一下:
你花了两个月的时间在一个非常令人兴奋的数据科学应用上。它涉及高级数据收集、耗时的数据争论、数小时的培训和无尽的模型微优化。一旦你完成了,你就拥有了你真正满意的东西。但是今天,你的重磅炸弹模型已经完成 3 个月了,它只是和你的研究笔记本和半文档代码一起放在 GitHub 的仓库里。你已经获得了 12 颗星和 2 把叉子,但是你想知道,“是这个吗?这个世界上只有 14 个人关心我建造的这个伟大的东西吗?我应该做些不同的事情吗?如果有,是什么?”
如果你有过这样的经历,创造了一些美好的东西,只有少数人与之互动,甚至更少人给你反馈,你并不孤单。我经常犯这种错误,我有很多从事数据科学的朋友也有类似的经历。现在,我不想贬低那些喜欢研究理论问题并在研究环境中茁壮成长的人们,但我确实认为有一些数据科学家需要向全世界展示他们的工作。这不仅有助于招聘人员等非技术人员看到并理解你的工作,还能打开接收项目真实反馈的大门。
在本文中,我将分享如何在没有 Amazon Beanstalk 的情况下将机器学习 web 应用程序部署到 Amazon AWS EC2 实例,以保持我们的部署完全自由分层。你可以点击 查看我们最终产品 的现场演示。
虽然您可以使用自己的模型和应用程序来跟进,但我将使用我以前的一个项目,我首先构建了一个情感分析分类器,然后在此基础上构建了一个 flask web 应用程序。你可以在这个库中找到我的模型的所有代码,在这个库中找到我的 web 应用程序的所有代码。我强烈推荐基于 flask 的开发技术栈,因为它最容易部署到 AWS,并且应该足以满足任何基本的应用程序。
部署步骤
让我们现实一点,亚马逊网络服务(AWS)对于以前从未使用过网络技术和后端服务的人来说可能是超级可怕的。老实说,我是一名专业的全栈 web 开发人员,我仍然很难导航和开始使用 AWS,因为它提供了太多不同的服务!你需要 S3 水桶吗?负载管理器怎么样?你必须使用 Lambda 请求,对吗?
快速提示:本指南并不针对生产或企业级解决方案,只应用于基本的个人项目。如果您对更适合生产的部署指南感兴趣,请随意发表评论,这样我(或其他媒体读者)可以为您指出正确的方向。在本文中,我真正关注的是个人使用的精益应用程序部署。我们将使用 AWS EC2 实例,它基本上是一个虚拟服务器。它是 AWS 提供的免费层的一部分,因此通过下面提到的步骤部署您的项目将是绝对免费的。
说完这些细节,让我们来讨论一下如何通过 5 个简单的步骤在一个普通 EC2 实例上部署我们的基本应用程序。
ML web 应用部署的 5 个步骤
从很高的层面来看,我们的部署步骤可以在上图中看到。我们将从设置一个 EC2 实例开始,我们的应用程序将在该实例上运行。这将涉及利用一些指南,但我会帮助你通过这一点,并提到常见的错误,以节省您的时间和挫折。接下来,我们将连接到我们的实例,并将我们的代码迁移到它。在这里,我将分享我们今天将使用的应用程序,带您浏览我们的 Flask 目录设置和 API。之后,我们将安装项目依赖项,然后设置一个本地 Apache 服务器在我们的 EC2 实例上运行,该实例将用于在 EC2 服务器提供的公共端口上为我们的应用程序提供服务。我们开始吧!
EC2 实例设置
在 AWS 上设置 EC2 实例并不太难,在 TDS 和其他领域的许多不同文章中都有介绍,所以我不会再浪费您的时间了。相反,我将指向对我帮助最大的指南,并浏览一些在安装过程中出现的常见错误/问题。请记住,这一步的目标是:
- 创建一个 AWS 帐户(如果您还没有)
- 使用我将在下面提到的教程和指南启动 EC2 服务器
- 确保实例设置正确无误
下面是帮助你设置实例的官方指南: AWS 官方 EC2 实例设置指南。您需要对设置进行一些关键的更改,如下所示。
在步骤 1:选择一个亚马逊机器镜像(AMI) ,选择 Ubuntu 服务器 16.04 LTS (HVM)。
本文中使用的 AMI
坚持使用免费层选项(t2.micro ),因为它有足够的计算能力用于大多数小规模的个人项目。不要选择查看和启动按钮,点击不同的配置选项,并在步骤 6:配置安全组停止。在这里,使用以下设置添加一个新的安全组:
第一个安全组应该已经存在,添加具有相同设置的第二个安全组:HTTPTCP80;任何地方;违约;描述(可选)
这将允许世界上任何地方的用户能够使用 HTTP 访问正在运行的 EC2 实例上的端口,这对我们的 web 应用程序来说是完美的。现在,当您完成这一步后,查看并单击启动按钮,您将看到以下对话框:
密钥对屏幕
确保选择“创建新的密钥对”(如果您还没有),并将此.pem
文件保存在一个安全的位置。你以后会需要这个的。恭喜,您的 EC2 实例现在已经启动并运行了!是时候连接到它并迁移您的应用程序了。
连接到 EC2
现在我们的实例已经启动并运行,我们可以连接到它了。基于你的操作系统,连接过程会有所不同,所以我不能为 Mac/Linux 用户提供太多的帮助,但是这里有一个很棒的页面为你们提供资源。我将主要介绍 Windows 安装过程,并再次向您介绍一些好的资源,同时提到一些障碍和额外的步骤。我强烈建议使用 PuTTY 作为您的 SSH 客户端,因为它易于使用和简单。完成连接顺序的最佳指南还是 AWS 官方指南,所以请随意完成。
一旦你完成了你的。您的 ppk 密钥。pem 键并准备好连接到您的实例,以下详细信息将有所帮助:
**Hostname**: ubuntu@*your_public_dns_name*
您可以在 AWS EC2 主页上点击“运行实例”找到您的公共 DNS 名称:
AWS EC2 运行实例页:用于查找您的公共 DNS
指南中涉及的连接到 EC2 实例的其余步骤相当简单,但是请确保将您的设置保存在 PuTTY 页面中,这样您就不必每次都进行设置。注意:您的连接类型是 SSH,在保存您的设置之前,请确保您的.ppk
文件连接在 Connection > SSH > Auth 下。
如果一切顺利,在这一步之后,您将能够使用 PuTTY 客户机访问您的实例。这将是一个黑色的 70 年代 DOS 风格的屏幕,这正是我们要找的!
太好了,您已经在 EC2 实例中了!
将应用程序代码迁移到 EC2
正如我在文章前面提到的,我们将部署一个机器学习 web 应用程序,它是我在过去两周内构建的。在我们进入代码迁移之前,关于模型、应用程序和项目结构的一些知识是必要的。该模型是具有增量学习能力的基本情感分析分类器。我们在此基础上创建了一个单页面应用程序来帮助用户与我们的模型进行交互。我们有两个 Flask API 路径,允许用户输入评论/想法并接收情感分析,并向模型提供反馈,从而允许持续学习。
项目结构
项目结构可以在右图中看到。我们所有的资产(图像、模型等。)在同一个主文件夹static
的不同子文件夹中,我们的 HTML 页面在templates
文件夹中,我们的app.py
文件在python
文件夹中。
我们将使用SCP
命令来帮助我们将文件从本地计算机(windows)传输到 EC2 实例。在此之前,使用以下命令在/home/ubuntu
中创建一个目录(我称之为我的 web_app,我建议使用相同的名称以避免任何混淆),您的应用程序将存在于该目录中
mkdir web_app
因此,您希望实例上的部署位置是/home/ubuntu/web_app
。现在,您必须将上面提到的应用程序下载并解压缩到您的本地机器上。您可以在这个 GitHub repo 中找到项目代码。一旦在本地机器上有了项目文件,就可以使用下面的SCP
命令(从 windows 终端)将文件从本地机器移动到 AWS EC2 实例:
scp -i **<path/to/pem/key>** -r **<local/path/to/project/folder>** [ubuntu@](mailto:ubuntu@ec2-54-235-0-36.compute-1.amazonaws.com)**<instance/public/DNS>**:/home/ubuntu/web_app
注意:如果您遇到一个错误,显示如下消息“对‘私有密钥’的权限太开放了”,请查看这篇很棒的文章来解决这个问题。
太好了!此时,您的项目文件应该都在 EC2 实例中了。确保文件夹结构/路径正确(例如:/home/ubuntu/web_app/python/app.py
等)。)现在我们可以进入下一步了。
依赖安装
现在,这一步可能是人们最困惑的,因为 python 环境、模块和其他安装可能会很快变得复杂和相互依赖。为了简单起见,我们将这一部分分为两个主要步骤:
- 安装 pip 和其他 python 依赖项
- 在我们的 EC2 实例上安装 Apache 和 mod_wsgi
让我们从确保运行 Python 3 并安装正确版本的 Pip 开始。您的 EC2 实例应该预装了 python3。要进行检查,请使用以下命令:
python3 -V
您应该会看到高于 3.5 的版本。如果是这样,你可以继续下一步。如果没有,看看这个官方指南。一旦安装了 python3,就需要下载并安装正确的 pip 版本。为此,请使用以下命令(按顺序):
curl -O [https://bootstrap.pypa.io/get-pip.py](https://bootstrap.pypa.io/get-pip.py)
sudo python3 get-pip.py
现在,您应该已经安装了 python3 和 pip。在进入下一步之前,运行以下命令以确保所有内容都是最新的:
sudo apt-get update
我们将通过使用以下命令安装我们的 web 应用程序依赖项(Flask 和 Scikit-learn)来完成这一步:
sudo pip install Flask
sudo pip install scikit-learn
现在我们可以进入下一步:安装 Apache 和 mod_wsgi 。
要设置 Apache,您需要两个模块:Apache2 和 mod_wsgi。Apache2 是我们的简单 web 服务器,mod_wsgi 是用于基于 Python 的 web 应用程序的 Apache 模块。要安装 python3 的正确版本,请使用以下命令:
sudo apt-get install apache2
sudo apt-get install libapache2-mod-wsgi-py
Apache 默认页面。恭喜,您的服务器已经启动并运行了!
此时,Apache 服务器应该在 AWS EC2 公共 DNS 上提供默认页面。要验证这一点,请注意 AWS 控制台中的公共 DNS ( ec2-xx-xxx-xx-xxx.compute-x.amazonaws.com/
)并在浏览器中访问它。您应该会看到一个类似左边的屏幕。
如果您可以看到 Apache 的默认屏幕,那就高兴吧,因为您就快到了!如果没有,请随意使用评论区,这样我和其他人可以帮助你。您还可以查看 Apache 日志文件(/var/log/apache2/error.log
)来尝试调试自己。
您已经设置了 python3 和 pip,安装了 Apache 及其所需的模块,并且已经提供了一个页面。现在,剩下的就是设置 Apache,将它指向您的项目文件夹,并授予它访问这些文件的权限。
Apache 设置和部署
为了让我们的应用程序在服务器上运行,我们需要设置一些 Apache 配置。这包括两个步骤:设置服务器配置/权限和设置 mod_wsgi 配置。
要设置您的服务器配置,您需要编辑以下文件:/etc/apache2/sites-enabled/000-default.conf
。这是一个受限文件,因此你必须使用 sudo 来编辑它。使用以下命令:
sudo vi /etc/apache2/sites-enabled/000-default.conf
在第ServerAdmin webmaster@localhost
行之后添加以下代码块:
DocumentRoot /home/ubuntu/web_appWSGIDaemonProcess flaskapp threads=5 python-home=/usr/local/lib/python3.5/site-packages/ user=ubuntu
WSGIScriptAlias / /home/ubuntu/web_app/static/flaskapp.wsgi<Directory /home/ubuntu/web_app>
WSGIProcessGroup flaskapp
WSGIApplicationGroup %{GLOBAL}
Require all granted
</Directory><Directory python>
Require all granted
</Directory><Directory static>
Require all granted
</Directory><Directory static/models>
Require all granted
</Directory>
这些配置设置应该将 Apache 指向我们的 web 应用程序的位置,并给予它与我们的文件和模型进行交互所需的所有权限。
Apache 设置的最后一步是配置 mod_wsgi 来支持基于 Flask 的应用程序。为此,您必须在静态文件夹中创建一个名为flaskapp.wsgi
的文件。将以下代码放入该文件:
import sys
import site
site.addsitedir(‘/home/ubuntu/.local/lib/python3.5/site-packages’)
sys.path.insert(0, ‘/home/ubuntu/web_app/python’)
from app import app as application
这些是 Apache 定位 python 依赖项和项目文件夹所需的配置。一旦您创建/修改了这些文件并输入了适当的代码,您的应用程序就可以运行了。使用以下命令重新启动服务器,以查看更改是否生效:
sudo apachectl restart
希望在这一点上,您的 web 应用程序成功地运行在您的 EC2 公共 DNS 上,并准备好与外界进行交互!如果您看到 403 或 500 错误代码,请尝试查看 Apache 日志文件(/var/log/apache2/error.log
)来寻找出错的线索。和往常一样,你也可以在评论区分享错误,我会尽力帮忙。如果一切顺利,当您在浏览器中访问您的公共 DNS 时,您应该会看到我们的应用程序:
你可以点击 查看T5 的现场演示。
结束语
我认为互联网应该充满真实世界的项目,这些项目是人们为了公开交流他们最感兴趣的想法而建造的。学习如何从零开始构建一个模型,围绕它设计和开发一个 web 应用并最终部署到网上让全世界看到,这是朝着那个目标迈出的一大步。我希望你们中的一些人受到启发,建立并分享自己的东西,如果你这样做了,不要忘记通过鼓励其他人做同样的事情来回报它。
我希望你喜欢读这篇文章,就像我喜欢把它放在一起一样。如果您有任何问题、反馈或意见,请随时通过 LinkedIn 或我的网站与我联系。此外,如果您最终构建并部署了自己的应用程序,请与我分享,因为我很想看到它!
用 5 行 JavaScript 实现机器学习
原文:https://towardsdatascience.com/machine-learning-with-5-lines-of-javascript-5daa0727a25?source=collection_archive---------58-----------------------
是的,你没听错。
就是这样。嗯,如果你想成为超级雄心勃勃的人,那应该是三行😅
介绍
我想,与其让你(读者)通读整篇文章,我现在就兑现承诺(****)。
极其简单,到了近乎恐怖的地步…
但是,什么是“ml5”?
ml5,或
[**ml5.js**](https://ml5js.org/)
,是一个建立在**tensorflow.js**
之上的高级机器/深度学习框架。
最好把 **ml5.js**
比作 Keras;两者都是高级 API,使 ML/DL 比以往任何时候都更容易,并且主要使用 TensorFlow 作为后端框架,但仍然在抽象级别和(当然)编程语言上有所不同。
深入调查
考虑到 JS 的简单性,使用 JS 可能看起来就像是用预先训练好的模型将你的输入发送到服务器。预训练模型的概念是正确的,但不是服务器。预训练模型的所有计算都在用户计算机的浏览器上完成*** 。尽管这可能导致基于 JavaScript(例如 V8 vs SpiderMonkey )引擎&用户设备的不一致和/或较慢的性能,但这也意味着开发者不需要创建或维护后端服务器来处理分类查询。***
你实际上是如何使用 ml5.js 的?
如前所述,**ml5.js**
脚本旨在嵌入网站中,通过浏览器执行。访问**ml5.js**
API 非常简单,只需使用 CDN 并将其插入你的 html* <head>
😗**
*<script src="https://unpkg.com/ml5@0.4.3/dist/ml5.min.js"></script>*
从那里,你可以做一些非常简单的分类任务。例如,您可以将一幅图像作为输入传递给预先训练好的 MobileNet ,并在 JavaScript 控制台上输出该图像的预测。这是一个 HTML 网页的例子:
只有一张图片的非常简单的 HTML 网页
网页在左边,结果在右边。看起来模型预测的很正确。照片由约翰·普莱斯在 Unsplash 上拍摄
应用程序
让我们把之前的东西,变成一个简单的互动网站,好吗?事实上,我已经这么做了:去 https://ml5demo.netlify.app/看一看😋
由“ml5.js
”支持的示例网站;一个简单的具有可信度的目标检测分类器。谢尔盖·塞明在 Unsplash 上拍摄的照片
作为参考,下面的 github repo 中提供了这方面的所有代码(无论如何,它相对较短)。
*** [## 理查德森 21/ml5 _ 演示
在 GitHub 上创建一个帐户,为 richardso21/ml5_demo 开发做贡献。
github.com](https://github.com/richardso21/ml5_demo)
考虑到在**ml5.js**
中只需要 5 行代码就可以拥有一个工作的预训练分类器,很明显,对于这样一个功能性网站来说,使用这个库是非常容易的。现在我再次提醒您,分类是在浏览器的机器上进行的,而不是在远程服务器上!如果你访问网站,你发现网站先“加载”几秒钟。 这是因为这个库实际上正在将实际的预训练 MobileNet(及其所有的权重和参数)加载到您的浏览器实例中。 确实很酷!
除了图像分类,**ml5.js**
还支持大量不同的图像相关的 DL/ML 架构,如 UNET、DCGAN 和 FaceAPI。**ml5.js**
也不限于图像;它支持声音分类模型以及基于文本的数据的 rnn。最后,如果你没有从他们的预置中找到你需要的,你总是可以用他们的 API 从头开始构建一个神经网络。
潜在的
考虑到它可能是深度学习框架/库的下一个“Keras”,T2 拥有很大的潜力。与使用**tensorflow.js**
相比,高级 API 使得在网站上直接开发简单的分类器变得不那么令人生畏,并且这可能意味着在尝试部署分类器模型上花费更少的时间和金钱。尽管如此,不用说,深度学习模型将完全依赖于它运行的硬件和网络引擎。
尽管如此,去给
**ml5.js**
一个自己的尝试,看看你能从中得到什么!***
Android 11 的机器学习:新功能
原文:https://towardsdatascience.com/machine-learning-with-android-11-whats-new-e8c829e9452?source=collection_archive---------40-----------------------
带 Android 11 的 ML:有什么新功能
这篇博客展示了你如何使用专门随 Android 11 推出的工具或插件开始使用设备上的 ML。如果您以前在 Android 中使用过 ML,您将会探索将 ML 应用程序与 Android 应用程序集成的更简单的方法。如果你以前没有在 Android 中使用过 ML,这可能是你这样做的一个起点,并开始用机器学习为你的 Android 应用程序提供强大的动力。在这篇博客中,我主要展示了 Android 11 的两个最大的更新: ML 模型绑定插件和新的 ML 套件。我们下面讨论的所有示例应用程序代码都出现在 GitHub repo 中。
你也可以在这里查看我关于这个话题的演讲。
[## rishit-dagli/ML-with-Android-11
特别感谢-谁帮助我整理和回顾了演讲的幻灯片。我在 Android 上的会话…
github.com](https://github.com/Rishit-dagli/ML-with-Android-11/blob/master/talks.md)
为什么要关心 Android 中的 on-device ML?
你可能已经注意到,我们在这里主要关注设备上的 ML,Android 11 对设备上的 ML 有很多很酷的更新,但让我们简单地谈谈为什么你应该关心它,你也会理解为什么会有这样一个关于设备上的 ML 或 ML on edge 的炒作。
设备上 ML 背后的理念
这里的想法是使用 ML,这样与传统的方法相反,我不再将我的数据发送到服务器或一些基于云的系统,然后这些系统执行 ML,然后将输出返回给我。相反,我从设备本身的 ML 模型中获得输出或推断,即我不再从设备本身发送数据。我还在移动设备上完成所有的处理和推理。
设备上 ML 背后的理念
您不会直接将该模型用于您的边缘设备。您需要压缩它或优化模型,以便可以在边缘设备上运行它,因为它具有有限的计算能力、网络可用性和磁盘空间。然而,在本文中,我们将不讨论优化过程。我们将部署一个.tflite
模型文件。你可以阅读更多关于 TensorFlow Lite 的和 TensorFlow Lite 的模型优化过程。
片上 ML 的优势
这里我列出了使用设备上 ML 的一些优点:
- 功率消耗
因此,您首先想到的是功耗,您需要花费大量的电力向服务器连续发送或传输视频数据,有时这样做是不可行的。然而,同样值得一提的是,当您使用大量预处理时,有时反过来也是正确的。
- 推理时间
另一个需要考虑的重要事情是我获得输出或者运行模型所花费的时间。对于实时应用程序,这是一个需要考虑的非常重要的方面。不用发送数据和接收数据,我也加快了我的推理时间。
- 网络可用性
就网络可用性而言,使用传统方法也很昂贵。我应该有带宽或网络来持续发送数据并从服务器接收推断。
- 安全性
最后是安全性,我不再向服务器或基于云的系统发送数据,也不再从设备中发送数据,因此加强了安全性。
ML 模型绑定插件
注意:你需要 Android Studio 4.1 或以上版本才能使用模型绑定插件
模型绑定插件关注什么?
你可以从“模型构建”这个名字中做出一个合理的猜测,那么 ML 模型绑定插件将会做什么来允许我们非常容易地使用定制的 TF Lite 模型。这使得开发人员可以导入任何 TFLite 模型,读取模型的输入/输出签名,并通过调用开源 TensorFlow Lite Android 支持库的几行代码来使用它。
ML 模型绑定插件让你在应用中使用 TF 模型变得非常简单。您需要编写的调用 TensorFlow Lite Android 支持库的代码要少得多。如果您使用过 TensorFlow Lite 模型,您可能知道您首先需要将所有内容转换为ByteArray
,您不再需要使用 ML 模型绑定插件将所有内容转换为ByteArray
。
我喜欢这个新插件的另一点是,你可以很容易地使用 GPU 和 NN API。有了模型绑定插件,使用它们变得前所未有的简单。使用它们现在仅仅是一个依赖调用,一行代码并不像你用模型绑定插件所做的那样酷。随着 Android 11 的神经网络 API,您还可以支持无符号整数权重和新的服务质量(QOS) API,也支持更多的边缘场景。当然,使用我们刚刚谈到的特性,这将使您的开发速度大大加快。
使用模型绑定插件
现在让我们看看我们如何能够实现我们谈到的所有内容。
所以第一步是导入一个带元数据的 TensorFlow Lite 模型。Android Studio 现在有了一个导入 TensorFlow 模型的新选项,只需右键单击要导入的模块,就会在others
下看到一个名为TF Lite model
的选项。
导入模型选项
您现在可以只传递您的tflite
模型的路径,它将为您将模型导入到您之前选择的名为ml
的模块的目录中,从那里您将能够使用该模型。添加依赖性和 GPU 加速也只是一个点击。
导入 tflite 模型
因此,现在从我的模型元数据,我也可以知道输入,输出形状,以及更多我需要使用它的信息,你可以通过在 Android Studio 中打开tflite
模型文件来查看这些信息。所以在这张截图中,我正在使用我制作的开源模型来对石头、布、剪刀进行分类。所以你只要在摄像机前把手拿出来,它就能识别出是石头纸还是剪刀,这也是我在这里演示的。
查看模型元数据
让我们最后开始使用这个模型,所以对于一个流式推理,这是你最可能想要做的;现场图像分类。最简单的方法是使用摄像机 X,并将每一帧传递给一个可以执行推理的函数。所以我现在感兴趣的是做推理的函数。你将会看到做这件事是多么容易,当你导入一个你可以使用的 TF Lite 模型时,一个样例代码也是如此。
private val rpsModel = RPSModel.newInstance(ctx)
因此,我们将首先实例化一个rps
模型(石头剪刀布模型的简称),并向其传递上下文。有了这个插件,我的模型名称是RPS Model.tflite
,所以会为你创建一个完全相同名称的类,所以我有一个名为RPS Model
的类。
val tfImage = TensorImage.fromBitmap(toBitmap(imageProxy))
一旦你这样做了,你需要把你的数据转换成我们可以使用的形式,所以我们将把它从bitmap
转换成Tensor Image
,如果你使用了 TF 解释器,你知道你需要把你的图像转换成ByteArray
,你不需要再这样做了,你将输入一个图像代理
val outputs = rpsModel.process(tfImage)
.probabilityAsCategoryList.apply {
sortByDescending { it.score } // Sort with highest confidence first
}.take(MAX_RESULT_DISPLAY) // take the top results
现在,我们将数据传入模型,首先我们将处理来自模型的图像并获得输出,我们基本上将获得一个概率数组,并对其执行降序排序,因为我们希望显示具有最大概率的标签,然后选择要显示的第一个n
结果。
for (output in outputs) {
items.add(
Recognition(
output.label,
output.score
)
)
}
最后,我想向用户显示标签,所以我将在输出中添加对应于每个条目的标签。这就是你所需要的🚀
利用 GPU 加速
如果你想再次使用 GPU 加速,这对于你来说非常容易,所以你将创建一个options
对象,我指定它使用 GPU 并构建它。在实例化部分,我将把它作为一个参数传入,你可以使用 GPU。这也使得使用 NN API 进行加速变得非常容易,甚至可以在 Android 11 上做更多的事情。
private val options = Model.Options.Builder().setDevice(Model.Device.GPU).build()
private val rpsModel = rpsModel.newInstance(ctx, options)
新的 ML 套件
你现在不再需要一个 Firebase 项目来使用 ML 工具包,它现在甚至可以在 Firebase 之外使用。
另一个值得注意的更新实现 TensorFlow Lite 模型的另一种方式是通过 ML 工具包。在我继续之前,ML 工具包现在已经可以使用了,即使不使用 Firebase 项目,你也可以使用 ML 工具包。
正如我之前提到的,由于我之前提到的好处,Android 11 中的许多更新都集中在设备上的 ML。新的 ML 套件现在对设备上的 ML 具有更好的可用性。ML 套件图像分类和对象检测和跟踪(ODT) 现在也支持定制模型,这意味着现在你也可以拥有一个tflite
模型文件。这也意味着如果你正在处理一些通用的用例,比如一种特定的对象检测,ML 工具包是最好的选择。
使用 ML 套件
让我们在代码中看到这一点,并看到一个这样的例子。作为一个例子,我建立了一个模型,可以对不同的食物进行分类,
private localModel = LocalModel.Builder()
.setAssetFilePath("lite-model_aiy_vision_classifier_food_V1_1.tflite").
.build()
所以我将首先设置模型并为其指定tflite
模型文件路径。
private val customObjectDetectorOptions = CustomObjectDetectorOptions
.Builder(localModel)
.setDetectorMode(CustomObjectDetectorOptions.STREAM_MODE)
.setClassificationConfidenceThreshold(0.8f)
.build()
这个tflite
模型将在带有 ML 工具包的对象检测模型之上运行,因此您可以对这些选项进行一些定制。这里我特别使用了STREAM_MODE
,因为我想处理流输入并指定置信度阈值。
private val objectDetector = ObjectDetection.getClient(customObjectDetectorOptions) objectDetector.process(image)
.addOnFailureListener(Log.d(...))
.addOnSuccessListener{
graphicsOverlay.clear()
for (detectedObject in it){
graphicsOverlay.add(ObjectGraphic(graphicsOverlay, detectedObject))
}
graphicsOverlay.postInvalidate()}
.addOnCompleteListenerl imageProxy.close() }
让我们进入运行模型的部分,你可能会看到一些类似于上一个例子的语法。我将处理我的图像,这里需要注意的是,所有这些失败或成功的监听器都是重要的任务,所以每次运行都需要连接它们。这就是你需要做的,我们完成了🚀
寻找模型
我们讨论了很多,在建立模型之后,让我们看看如何为你的用例找到模型。
- TF Lite 模型制作工具
TensorFlow 团队在 2020 年早些时候宣布了 TF Lite 模型制造商。这使得制作好的模型非常容易使用,提供了高性能,并且还允许大量的定制。您可以简单地传入数据并使用很少的代码来构建一个tflite
模型。你可以看看回购中出现的 TensorFlow Lite 模型制作者示例。
- 张量流集线器
TensorFlow Hub 是一个开源的存储库,其中存储了最新的和有据可查的模型。我们用 ML Kit 搭建的食品分类 app,TF Hub 上也有。你也可以使用社区的模型。你可以在 tfhub.dev 找到这些。
tfhub.dev 上的一些出版商
TF Hub 中的过滤器
如果您只想查找基于图像或文本的模型,您可以在 TF Hub 中使用许多过滤器搜索模型,如问题域,如果您想在 web、edge 设备或 Corals 上运行模型格式,过滤架构、使用的数据集等等。
你还可以直接从 TF Hub 下载这些模型,或者用你自己的数据很容易地对它们进行迁移学习。然而,由于这个博客的范围,我们将不涉及 TF Hub 的迁移学习,你可以在我的这个博客中了解更多。
还有更多!有很多服务,像可教机器、自动等等,但这些是主要的。
所有的代码在这里展示了关于 TF Lite 模型制造商的例子是在这个报告。我还在回购中为您提供了一些经过培训的模型,供您开始使用和尝试。
[## rishit-dagli/ML-with-Android-11
一个展示 Android 11 for ML 中所有新特性的存储库,以及如何在您自己的用例中试用它
github.com](https://github.com/Rishit-dagli/ML-with-Android-11)
关于我
大家好,我是里希特·达格利。用回购里的内容或者这篇博文做了点东西,在 Twitter 上给我贴标签,分享给我!
推特
网站
如果你想问我一些问题,报告任何错误,建议改进,给我反馈,你可以发邮件给我
- rishit.dagli@gmail.com
- hello@rishit.tech
基于日期时间特征工程的机器学习:预测医疗预约失约
原文:https://towardsdatascience.com/machine-learning-with-datetime-feature-engineering-predicting-healthcare-appointment-no-shows-5e4ca3a85f96?source=collection_archive---------0-----------------------
让我们根据日期和时间为我们的模型制作特写!
日期和时间是可用于机器学习模型的丰富信息源。然而,这些日期时间变量确实需要一些特性工程来将它们转换成数字数据。在这篇文章中,我将演示如何用内置的熊猫函数为你的机器学习模型创建日期时间特性。
当我在东北大学教授机器学习课程时,我的几个学生使用了一个非常有趣的数据集(医疗预约失约),我将在这篇博文中探讨这个数据集。医疗预约失约是医疗保健领域的一个大问题,因为大约五分之一的患者会错过预约(来源)。这对每个相关的人来说都是一个问题:1)被安排的患者大概需要被看,否则他们不会有预约,2)其他患者希望有那个位置但是不能,3)医疗服务提供者必须花费额外的时间来联系和重新安排患者,以及浪费他们用于准备就诊的任何时间。
项目定义
给定排班日和预约日的日期和时间,预测患者是否会错过他们的医疗预约。
资料组
这里,我们将使用 Kaggle(https://www.kaggle.com/joniarroba/noshowappointments)上的医疗预约缺席。该数据集包含超过 110,000 个医疗预约。我们将为此项目使用的三个主要列是 ScheduledDay(安排约会的日期和时间)、AppointmentDay(约会的日期,不包括时间)、No-Show(指示他们是否未出现的二进制标志)。出于本文的目的,我们将忽略其余的数字特征(尽管老实说,它们没有增加 AUC 的价值)。
数据准备
让我们首先加载我们的数据集,创建一个输出列(1 =不显示,0=显示),并将我们的 datetime(当前为字符串)转换为 python datetimes。
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
在这里,我假设您从 Kaggle 下载了数据,并将其放在“data”文件夹中:
df = pd.read_csv(‘data/KaggleV2-May-2016.csv’)
我们可以用value_counts
调查未出现的列
让我们定义一个二进制列 OUTPUT_LABEL 来表示 Yes = 1,No = 0。
df[‘OUTPUT_LABEL’] = (df[‘No-show’] == ‘Yes’).astype(‘int’)
我们可以检查我们的 OUTPUT_LABEL 的流行程度:
def calc_prevalence(y):
return (sum(y)/len(y))
这意味着五分之一的病人将错过他们的预约。
现在,让我们通过查看 ScheduledDay 和 AppointmentDay 的前 5 行来处理 datetime 列
如您所见,两列的 dtype 都是object
,这意味着 pandas 当前将这些值视为字符串。需要指出的另一点是,ScheduledDay 中的约会日的所有时间都是 00:00:00。我们也许应该处理这个问题,但是我发现他们没有把约会的时间包括在数据集中有点奇怪。据推测,约会的时间也是可以预测的。
要将这些字符串转换成内部日期时间,我们可以使用 pandas 函数to_datetime
。我喜欢用 format 参数来明确表示格式。如果使用 format 参数,则必须指定如何处理错误。在这里,我将把任何错误转换成非日期时间(NaT)。一般来说(虽然这里不是这样),使用 format 参数会加快这一行的执行速度。
df[‘ScheduledDay’] = pd.to_datetime(df[‘ScheduledDay’],
format = ‘%Y-%m-%dT%H:%M:%SZ’,
errors = ‘coerce’)
df[‘AppointmentDay’] = pd.to_datetime(df[‘AppointmentDay’],
format = ‘%Y-%m-%dT%H:%M:%SZ’,
errors = ‘coerce’)
我以前没有见过标准格式的 T 和 Z,所以我只是把它们放在格式字符串中。如果有人知道如何更好地处理这些,请告诉我。
每当我使用 format 参数时,如果我假设所有行都应该有日期,我喜欢放一个断言语句来验证我没有得到不正确的格式。
assert df.ScheduledDay.isnull().sum() == 0, ‘missing ScheduledDay dates’
assert df.AppointmentDay.isnull().sum() == 0, ‘missing AppointmentDay dates’
如果您现在检查 dtype,您将看到它是 datetime64,这正是我们想要的,因为它向我们展示了 pandas 中的所有 datetime 属性。
我注意到的一件事是,目前大约有 40k 个约会被安排在约会日期之后。
我认为这是因为所有的预约时间都设置在最早的时间(00:00:00 ),而这些时间包含在 ScheduledDay 中。为了适应这种情况,让我们把所有的约会时间移到一天的最后。如果我是为了工作而做这个项目,我会去了解预约时间。
df[‘AppointmentDay’] = df[‘AppointmentDay’] +pd.Timedelta(‘1d’) — pd.Timedelta(‘1s’)
通过这一更改,只有 5 行的计划日期时间在约会日期之后。我们把这几行删掉吧。
工程师日期时间功能
通过将字符串转换为 datetimes,这将公开所有熊猫 dt 属性。
来源:https://pandas . pydata . org/pandas-docs/version/0.23/API . html # datetime like-properties
基本上你可以把日期分开,得到年、月、周、日、小时、分钟、秒等。还可以得到星期几(星期一= 0,星期日= 6)。请注意一年中的第几周,因为如果该周开始于前一年,则一年的第几天可能是 53。让我们将其中一些属性应用到我们的两个 datetime 列中。
df[‘ScheduledDay_year’] = df[‘ScheduledDay’].dt.year
df[‘ScheduledDay_month’] = df[‘ScheduledDay’].dt.month
df[‘ScheduledDay_week’] = df[‘ScheduledDay’].dt.week
df[‘ScheduledDay_day’] = df[‘ScheduledDay’].dt.day
df[‘ScheduledDay_hour’] = df[‘ScheduledDay’].dt.hour
df[‘ScheduledDay_minute’] = df[‘ScheduledDay’].dt.minute
df[‘ScheduledDay_dayofweek’] = df[‘ScheduledDay’].dt.dayofweekdf[‘AppointmentDay_year’] = df[‘AppointmentDay’].dt.year
df[‘AppointmentDay_month’] = df[‘AppointmentDay’].dt.month
df[‘AppointmentDay_week’] = df[‘AppointmentDay’].dt.week
df[‘AppointmentDay_day’] = df[‘AppointmentDay’].dt.day
df[‘AppointmentDay_hour’] = df[‘AppointmentDay’].dt.hour
df[‘AppointmentDay_minute’] = df[‘AppointmentDay’].dt.minute
df[‘AppointmentDay_dayofweek’] = df[‘AppointmentDay’].dt.dayofweek
您可以验证这是否有效:
在这一点上,这将是一个很好的探索我们的日期了。
正如你在这里看到的,约会是在 2016 年的 4 月、5 月和 6 月,从周一到周六,周日没有约会。我永远不会使用年份作为一个特征(但还是显示了它),因为我们可能希望在未来使用这个预测模型,而这些未来的年份不会包含在数据集中。然而,我有点失望,这几个月只是一年中的几个月。这意味着月(以及一年中的周)可能也不应该被用作一个特性。如果我是为了工作而这样做,我会回到数据库,得到一整年(或许多年)的数据。我可以想象,一年中的某些时候(即假期前后)会影响不露面的比率。
让我们快速检查一下 dayofweek 是否预示着失约:
看起来更多的人在周五和周六跳过他们的约会,尽管效果不大。
熊猫日期时间表示的另一个好处是你可以计算日期时间之间的“时间”。让我们创建一个新特性,即计划日期和约会日期之间的天数。
df[‘delta_days’] = (df[‘AppointmentDay’]-df[‘ScheduledDay’]).dt.total_seconds()/(60*60*24)
注意这里我用的是total_seconds
。有一个函数 dt.days,但是我习惯使用 total_seconds,因为 1) dt.days 舍入到最近的一天,2) dt.days 过去花费的时间比 total_seconds 长得多。第二点似乎在熊猫后期版本中已经修复。
我们可以在这个变量上绘制两个类的直方图:
plt.hist(df.loc[df.OUTPUT_LABEL == 1,’delta_days’],
label = ‘Missed’,bins = range(0,60,1), normed = True)
plt.hist(df.loc[df.OUTPUT_LABEL == 0,’delta_days’],
label = ‘Not Missed’,bins = range(0,60,1), normed = True,alpha =0.5)
plt.legend()
plt.xlabel(‘days until appointment’)
plt.ylabel(‘normed distribution’)
plt.xlim(0,40)
plt.show()
这种分布对我来说有点奇怪,因为大多数没有错过预约的患者都在同一天安排了预约。我有点想知道这个数据集中是否包括预约。我的猜测是,这个模型只会在 1 天画一条线,并说如果你在同一天安排它,就不会错过。
我们现在准备分割我们的样本并训练一个模型!
分割样本
为了简单起见,我只分成两个数据集:训练(70%)和验证(30%)。打乱你的样本是很重要的,因为你可能是按照日期顺序得到数据的。
# shuffle the samples
df = df.sample(n = len(df), random_state = 42)
df = df.reset_index(drop = True)df_valid = df.sample(frac = 0.3, random_state = 42)
df_train = df.drop(df_valid.index)
我们可以查一下每个地区的患病率约为 20%:
print(‘Valid prevalence(n = %d):%.3f’%(len(df_valid),calc_prevalence(df_valid.OUTPUT_LABEL.values)))
print(‘Train prevalence(n = %d):%.3f’%(len(df_train), calc_prevalence(df_train.OUTPUT_LABEL.values)))
鉴于该数据仅来自 2016 年 4 月至 6 月,且无预约时间,我们将仅使用这些列:
col2use = [‘ScheduledDay_day’, ‘ScheduledDay_hour’,
‘ScheduledDay_minute’, ‘ScheduledDay_dayofweek’,
‘AppointmentDay_day’,
‘AppointmentDay_dayofweek’, ‘delta_days’]
“日”特征甚至可能是可疑的,但是现在让我们离开。
如果我们具备以下条件,这一范围还可以扩大:
- 整个日历年的约会
- 约会时间
现在,我们可以构建用于训练和验证的 X(输入)和 Y(输出):
X_train = df_train[col2use].values
X_valid = df_valid[col2use].valuesy_train = df_train[‘OUTPUT_LABEL’].values
y_valid = df_valid[‘OUTPUT_LABEL’].valuesprint(‘Training shapes:’,X_train.shape, y_train.shape)
print(‘Validation shapes:’,X_valid.shape, y_valid.shape)
训练一个机器学习模型
因为这篇文章的重点是关于日期时间的特性,我们将在这里训练一个随机的森林模型。注意如果要使用其他类型的模型,可能需要对数据进行缩放或规范化。您可能想做的另一件事是通过一键编码将 dayofweek 转换成分类变量。但是对于基于树的方法,我们不需要做这些事情。
from sklearn.ensemble import RandomForestClassifier
rf=RandomForestClassifier(max_depth = 5, n_estimators=100, random_state = 42)
rf.fit(X_train, y_train)
然后我们可以得到我们的预测:
y_train_preds = rf.predict_proba(X_train)[:,1]
y_valid_preds = rf.predict_proba(X_valid)[:,1]
评估绩效
在这里,我们将评估模型的性能。如果你是分类指标的新手,我推荐你看看我关于这些指标的帖子(技术帖子或非技术帖子)。
from sklearn.metrics import roc_auc_score, accuracy_score, precision_score, recall_score
def calc_specificity(y_actual, y_pred, thresh):
# calculates specificity
return sum((y_pred < thresh) & (y_actual == 0)) /sum(y_actual ==0)def print_report(y_actual, y_pred, thresh):
auc = roc_auc_score(y_actual, y_pred)
accuracy = accuracy_score(y_actual, (y_pred > thresh))
recall = recall_score(y_actual, (y_pred > thresh))
precision = precision_score(y_actual, (y_pred > thresh))
specificity = calc_specificity(y_actual, y_pred, thresh)
print(‘AUC:%.3f’%auc)
print(‘accuracy:%.3f’%accuracy)
print(‘recall:%.3f’%recall)
print(‘precision:%.3f’%precision)
print(‘specificity:%.3f’%specificity)
print(‘prevalence:%.3f’%calc_prevalence(y_actual))
print(‘ ‘)
return auc, accuracy, recall, precision, specificity
使用这个print_report
函数,我们可以评估训练和验证的性能。在这里,我将阈值设置为患病率 0.201
我们可以用它来绘制 ROC
from sklearn.metrics import roc_curvefpr_train, tpr_train, thresholds_train = roc_curve(y_train, y_train_preds)
auc_train = roc_auc_score(y_train, y_train_preds)fpr_valid, tpr_valid, thresholds_valid = roc_curve(y_valid, y_valid_preds)
auc_valid = roc_auc_score(y_valid, y_valid_preds)plt.plot(fpr_train, tpr_train, ‘r-’,label =’Train AUC:%.3f’%auc_train)
plt.plot(fpr_valid, tpr_valid, ‘b-’,label =’Valid AUC:%.3f’%auc_valid)
plt.plot([0,1],[0,1],’k — ‘)
plt.xlabel(‘False Positive Rate’)
plt.ylabel(‘True Positive Rate’)
plt.legend()
plt.show()
这表明,仅使用日期时间特征,我们就可以获得 0.71 的 AUC。这条摇摆曲线有点奇怪,因为它有肘部。
我们可以通过查看主要特性来对此进行一些研究
feature_importances = pd.DataFrame(rf.feature_importances_,
index = col2use,
columns=[‘importance’]).sort_values(‘importance’,
ascending=False)num = min([50,len(col2use)])
ylocs = np.arange(num)
# get the feature importance for top num and sort in reverse order
values_to_plot = feature_importances.iloc[:num].values.ravel()[::-1]
feature_labels = list(feature_importances.iloc[:num].index)[::-1]plt.figure(num=None, figsize=(6, 6), dpi=80, facecolor=’w’, edgecolor=’k’);
plt.barh(ylocs, values_to_plot, align = ‘center’)
plt.ylabel(‘Features’)
plt.xlabel(‘Importance Score’)
plt.title(‘Feature Importance Score — Random Forest’)
plt.yticks(ylocs, feature_labels)
plt.show()
这表明 delta_days 基本上是模型中使用的唯一特征。这证实了我们上面的怀疑,即模型可能会因为那些同一天的约会而陷入困境。
由于我们的训练和验证分数非常相似,这意味着我们处于高偏倚的情况下。为了改进这个模型,我们将需要额外的功能,所以我将在这里结束这个项目。
结论
在这个项目中,我们通过解包日期时间变量来预测患者是否会缺席,从而创建了许多新功能。根据我的经验,日期时间功能对医疗保健机器学习模型有很大的影响。我强烈建议在你的下一个项目中尝试一下。如果你对这篇文章有任何问题或疑虑,请联系我们。
Jupyter 机器学习:使用开放平台解决工作流管理问题
原文:https://towardsdatascience.com/machine-learning-with-jupyter-solving-the-workflow-management-problem-using-open-platforms-e1cb70ba85ef?source=collection_archive---------36-----------------------
臭名昭著的数据科学工作流程包含数据获取、争论、分析和报告的相互关联的循环,低估了这些组件的多重连接性和非线性。机器学习和深度学习工作流也是如此。我理解在陈述和执行摘要中过度简化的必要性。然而,它可能会描绘出不切实际的画面,隐藏 ML 开发的复杂性,并掩盖混乱的现实。这让我想到了行业工具,或者更通常被称为人工智能的基础设施,它是所有图书馆、实验、设计和创造性思维相遇的载体。这些简陋的基础设施往往被忽视和低估,但它们的重要性怎么强调都不为过。我将解释这些工具中的几个,它们可以协同使用来改进您的工作流、数据探索的责任,并减少从概念验证(POC)到部署的时间和资源。
简化的 ML/DL 管道
开源软件
在你穿着高领衬衫和休闲蓝色牛仔裤上台展示你的数据密集型突破性产品之前,第一步是选择软件来应对机器学习的复杂地形。幸运的是,有优秀的开放软件平台,如 Apache Spark、Jupyter、TensorFlow、PostgreSQL,以及更多可以帮助您入门的平台。我的清单上最近增加了快板列车,我是它的大力支持者。作为一名工作数据科学家,在选择使用开源软件之前,我有五个标准。这些是:
- POC 的可用性和易用性
- 再现性和协作
- 跨平台兼容性
- 资源优化
- 相对于学习率的生产力提升。
本着这些标准的精神,让我们来探索 Jupyter 和 Trains。
Jupyter 和 Allegro 火车
Jupyter 笔记本是有抱负的数据科学家和工程师实现交互式计算的事实上的门户。它以错误或视觉显示的形式提供快速反馈,并允许用户测试他们的基本想法。除了语言无关性和通过 Markdown 单元格提供文本之外,它无疑是 POC 的完美工具。Jupyter Lab 为笔记本电脑增加了模块化,因此您不必为每台笔记本电脑打开多个标签。还有 JupyterHub ,允许多个用户共享笔记本。这些都是获得一些实践经验的好平台。
当您处理复杂的项目时,问题就来了,其中需要大量的迭代和试验、关键的代码和资源优化、版本控制和协作,以及数据集成和部署。这些是将数据驱动产品推向市场的瓶颈。因此,除了上述五个标准之外,结合这些功能的人工智能架构成为加快 R&D 上市速度、提高投资回报率的必要条件。
图 1:通过 Trains 进行机器学习项目管理
为什么快板火车?
看看图 1 中的虚拟四个项目,想象一下如果你在 Jupyter 上运行这些项目,保持每个笔记本目的的难度很快就变成了它自己的任务。您可以通过建立一个 git 存储库来处理您的版本需求和管理您的进度,从而解决这个问题。您还可以安装一个内存分析器来管理每个任务的资源分配。自动化你的 ML 模型怎么样?你可以探索越来越多的汽车。如果你开始意识到你的 ML 项目的复杂性随着每一步的完成而增加,那么你不是唯一的一个。这是一个常见的问题,解决方案应该由一个单独的项目中心来解决。这正是为什么快板火车被开发。
Allegro Trains 解决了这些常见的基础设施问题。与其用无数的模块来修补你的问题,不如用一个包容的解决方案来使 ML 成熟。Trains 提供了一个简单的 MLOps 和 AI 基础设施解决方案,以加快机器/深度学习项目从 R&D 到部署的速度。它允许数据专业人员负责实施创造性的见解,而无需担心凌乱的笔记本、解决版本问题的中断、模型比较、自动日志记录、性能跟踪,甚至 CPU/GPU/IO 资源分配。简而言之,它符合我使用开源软件的五个标准。它还具有自动加速实验的功能,以及从 Web 用户界面终止资源密集型或性能不佳的任务的能力。
我想留给你最后一句话。利用开放平台将你激动人心的想法和 R&D 推向市场的能力已经变成了一个简单的安装问题。Jupyter 可以满足您的探索需求,而 Allegro Trains 可以跟踪您的每一个进展,从概念验证到优化和跨团队协作,再到使用 Trains 服务器进行部署。
用 PySpark 和亚马逊 EMR 进行机器学习
原文:https://towardsdatascience.com/machine-learning-with-pyspark-and-amazon-emr-3149dbc847ae?source=collection_archive---------22-----------------------
想象一下,你有客户如何与你的在线服务互动的详细数据。数据包括客户访问过的页面、他们在每个页面上花费的时间以及客户人口统计数据。一切都在那里。
现在你的老板想利用这些数据。你的公司最近失去了相当多的客户,他希望你提供一个关于剩余客户的预测,这些客户很可能会流失。
熊猫,Scikit-learn,Matplotlib 没什么搞不定的吧?
不对。
在您查看了数据集之后,您会注意到一个重要的细节。该数据有 1 亿行。没有一台机器能处理这么多数据。那你是做什么的?
推荐的方法是使用多台机器。这就是 PySpark 和 EMR 非常有用的地方。
在本文中,我将指导您如何分析一个非常大的数据集(大数据),以及如何针对这些数据运行一些计算量很大的 ML 算法。最终目标是将数据转化为有用的见解,例如,提供关于客户流失的预测。
分析
1.建立
本文中执行的分析依赖于 PySpark 和 AWS EMR 技术。您可能需要遵循和复制分析的所有技术信息都可以在本文本中找到。该文本是如何设置 AWS EMR(创建您的集群)、启用 PySpark 和启动 Jupyter 笔记本的分步指南。
2.数据
用于分析的数据是用户日志的集合。这些日志来源于用户与一家名为 Sparkify 的虚拟在线音乐流媒体公司的互动。数据集有 12 GB,超过 2000 万行,来自 Udacity ,在亚马逊 S3 服务器上公开提供:
" s3n://uda city-dsnd/spark ify/spark ify _ event _ data . JSON "
数据集预览
数据集中大多数列的名称都是不言自明的。注册是客户加入服务的时间。ts 是客户进入特定网页时的时间戳。注册和 ts 都以 Unix 时间给出(自 1970 年以来的秒数)。l ength 是用户在特定页面上花费的秒数。每个会话是用户活跃的特定时间段。 itemInSession 是客户在会话期间的页面/网络互动数量。列级别显示用户是否为服务付费。
数据集中最重要的列可能是第页。它保存了客户访问过的所有 Sparkify 页面。
页面总访问量
通过统计单个页面的访问量,我们可以注意到页面 NextSong 是最常被访问的(这是有道理的,因为 Sparkify 是一个在线音乐流媒体服务)。然而,更重要的是了解到达取消确认页面的客户。这些都是客户,任务是建立一个可以识别他们的预测模型。
在解释了项目的目标和数据集的基本特征之后,现在开始分析的一切都准备好了。
3.预处理
上述数据需要一些预处理。在我的 g ithub 库中的 Sparkify_Big.ipynb 文件中详细记录了通常的第一步,如包安装、包导入、数据清理、数据标记和重命名。我将跳过这里的预处理,而是专注于:
- 如何将给定的庞大数据集转化为对预测模型有用的输入(特征工程)
- 如何对数据集应用分类算法(机器学习)
4.特征工程
为了获得好的预测结果,适当的特征工程通常比 ML 模型的后续选择更重要。理解数据集并强调最有判别潜力的特征(在分类的情况下)非常重要。
最终,我们的模型应该预测潜在的流失客户,因此日志数据应该聚合到 UserId 级别。我将原始数据集(经过预处理后)转换成 13 个特征,这些特征按每个用户 Id 聚合(大部分是平均的),并将作为模型的输入。下面列出了这些功能:
功能列表
如果您对我如何将原始数据从日志级别提升到 UserId 级别感兴趣,这里有一些好消息:PySpark 支持 SQL 语法。在运行模型之前,我广泛地使用它来准备数据。SQL 语法的替代方法是本机 PySpark 语法。PySpark 语法也很直观,但它允许更多的自由。最好能很好地掌握这两种语法。
预处理数据然后聚合数据的完整代码在前面提到的 github 库中。在这里,我只是想证明,如果您对 SQL 有基本的了解,PySpark 中的数据操作确实是轻而易举的事情。
PySpark 中使用 SQL 的特征工程
经过这种操作后,数据现在是适当的格式,并从大约 2000 多万行减少到大约 22K 行(用户 id 的数量)。
聚合和特征工程后的数据
标签是因变量,目的是通过使用提供的 13 个特征来预测它。
我的假设是,在客户流失发生前不久,流失客户和非流失客户的行为应该是不同的。对于每个用户,我丢弃了自上次交互以来超过 14 天的所有数据。我想在客户流失前抓住他们的行为。
我的期望是流失客户经历更多的错误,发起更多的“反对”,并且通常与非流失客户不同。以下是 13 个特征的平均值,分别针对有不良反应和无不良反应的客户(0 表示无不良反应,1 表示有不良反应):
流失和非流失客户的平均特征值
我将上表中的数据按列标准化,为蝴蝶图准备数据。
按列标准化的平均特征值
下图显示了两个用户类别之间存在的差异。对于流失客户来说,错误、降级和否决的数量更高,这是有道理的。然而,起初,我发现大多数其他功能对客户流失有更高的价值是不寻常的。一个看似合理的解释是,流失客户确实是更活跃的用户,他们离开了 Sparkify,用更好的音乐替代了它。换句话说,也许顾客在离开之前对 Sparkify 并不完全满意。或许 Sparkifys 的竞争更胜一筹。
用户特征的蝶形图
该图证明了这两个用户群之间确实存在明显的差异,因此分类模型可能会成功预测流失的客户。
5.建模
我们准备试用一些精选的型号。PySpark 有一个非常好的机器学习库,它支持一系列的 ML 算法。
对于客户流失分析,以下软件包就足够了:
导入一些 PySpark ML 包
在第一行中,我们导入 VectorAssembler。这是 PySpark 特有的步骤,因为 Pyspark 要求将所有特征值作为一个列表添加到一个输入列中,输入到模型中。
然后,我们导入我们想要尝试的模型,以及它们的评估者。还引入了流水线方法,这有助于训练过程更加连贯。最后导入 CrossValidator、ParameterGridBuilder 等模型训练优化的工具。
我们可以开始构建 ML 基础设施。
PySpark 中的 ML 设置步骤
此阶段通常的设置步骤是:
- 将数据分为训练和测试。
- 创建保存所有特征值的列( inputFeatures) 。
- 特征值然后被归一化并传递到输出列(特征)
- 模特被称为
- 这些步骤都被连接成一个管道
我们已经准备好训练模型,让我们从简单的逻辑回归开始
逻辑回归的模型训练
在 ML 流程的这一部分,我们正在运行模型训练并优化参数。
步骤:
- 创建参数网格(可选,但推荐)
- 将评估指标传递给分类评估员
- 定义交叉验证器中的折叠数(可选,但推荐)
ParamGridBuilder 对象可以保存特定 ML 算法支持的所有参数值。在上面的逻辑回归的例子中,我决定设置正则化参数和最大迭代次数的值。您可以设置许多其他值和参数,但请注意,对于给定的每个参数值,模型训练都将再次运行(这可能代价很高)。
为手头的任务选择的度量是 F1。
在交叉验证步骤中,我加入了前面的两个步骤,并设置了 K 倍交叉验证参数的值。K-fold 参数定义了训练将被重复多少次,每次使用不同的测试数据子集。
模型被训练和拟合。最终结果是,我们的 F1 指标产生了 0.69
对于第一次尝试来说还不错。
让我们使用更高级的模型,比如随机森林分类器****
随机森林的 F1 度量
随机森林产生更好的结果 F1= 0.8
这次我跳过了参数网格的输入,因为(即使在 AWS EMR 上)训练过程相当慢。加快速度的一个方法是增加集群的大小。你可以随意自己做,你可以在这里找到要调整的参数。
我尝试的最后一个模型是梯度提升树分类器****
GBT 分类器的 F1 度量
GBT 分类器的表现略好于随机森林,F1= 0.81
看起来我们有一个赢家!
6.形象化
让我们可视化我们获胜模型的 ROC 曲线,只是为了证明 AWS EMR 上的 Jupyter 笔记本可以支持可视化,正如预期的那样。
我们将使用 Matplotlib 进行可视化,但是我们需要首先在 AWS EMR 上安装这个包。这里需要注意的一点是,软件包安装不能与通常的 pip 安装一起工作。相反,软件包的安装如下所示:
PySpark 上的软件包安装
最后要考虑的是,AWS EMR 上 Jupyter 中的 plot 命令需要括在PLT . clf()和 %matplot plt 魔法函数之间。
注意 plt.clf()和%matplot plt 神奇函数
这是我们的 ROC 曲线
GBT 分类器的 ROC 曲线
结论
我们的分析已经结束了!
我们设法利用 PySpark 和 AWS EMR 的强大功能,通过庞大的数据集,对其进行压缩并提取有用的特征。最后,我们训练了一个模型,预测客户流失与体面的表现!
但是没有一个 ML 过程是完全结束的,并且总是有改进的空间。我们的分析也可以在几个方面得到加强:
- 一些共享强相关性的特征应该被排除在模型之外
- 新的和更复杂的特征可以被设计并添加到模型中
- 尝试其他 ML 算法
- 在参数网格中包含更多参数值
我希望这篇文章能让你更熟悉在处理大数据时可以采用的分析/ML 方法。PySpark 和 AWS EMR 是强大的技术,使大数据处理对更广泛的公众可用且负担得起。下次这个庞大的数据集出现时,您将做好准备!
本文有意省略了一些数据处理部分,以便更加关注围绕模型训练的 PySpark 步骤。如果您希望详细查看客户流失分析,您可以在此 找到代码 。
用 Python 进行机器学习:分类(完整教程)
原文:https://towardsdatascience.com/machine-learning-with-python-classification-complete-tutorial-d2c99dc524ec?source=collection_archive---------0-----------------------
数据分析和可视化、特征工程和选择、模型设计和测试、评估和解释
摘要
在本文中,我将使用数据科学和 Python 解释分类用例的主要步骤,从数据分析到理解模型输出。
由于本教程对于初学者来说是一个很好的起点,我将使用著名的 Kaggle 竞赛中的“ Titanic dataset ”,其中为您提供了乘客数据,任务是建立一个预测模型来回答这个问题:“什么样的人更有可能幸存?”(下面链接)。
[## 泰坦尼克号:机器从灾难中学习
从这里开始!预测泰坦尼克号上的生存并熟悉 ML 基础知识
www.kaggle.com](https://www.kaggle.com/c/titanic/overview)
我将展示一些有用的 Python 代码,这些代码可以很容易地用于其他类似的情况(只需复制、粘贴、运行),并通过注释遍历每一行代码,这样您就可以很容易地复制这个示例(下面是完整代码的链接)。
[## mdipietro 09/data science _ 人工智能 _ 实用工具
permalink dissolve GitHub 是 4000 多万开发人员的家园,他们一起工作来托管和审查代码,管理…
github.com](https://github.com/mdipietro09/DataScience_ArtificialIntelligence_Utils/blob/master/machine_learning/example_classification.ipynb)
特别是,我将经历:
- 环境设置:导入库并读取数据
- 数据分析:理解变量的意义和预测能力
- 特征工程:从原始数据中提取特征
- 预处理:数据划分、处理缺失值、编码分类变量、缩放
- 特征选择:只保留最相关的变量
- 模型设计:训练、调整超参数、验证、测试
- 绩效评估:阅读指标
- 可解释性:理解模型如何产生结果
设置
首先,我需要导入以下库。
**## for data**
import **pandas** as pd
import **numpy** as np**## for plotting**
import **matplotlib**.pyplot as plt
import **seaborn** as sns**## for statistical tests**
import **scipy**
import **statsmodels**.formula.api as smf
import statsmodels.api as sm**## for machine learning**
from **sklearn** import model_selection, preprocessing, feature_selection, ensemble, linear_model, metrics, decomposition**## for explainer**
from **lime** import lime_tabular
然后我会把数据读入熊猫数据框。
dtf = pd.read_csv('data_titanic.csv')
dtf.head()
有关列的详细信息可以在所提供的数据集链接中找到。
请注意,表格的每一行代表一个特定的乘客(或观察)。如果您正在处理一个不同的数据集,它没有这样的结构,其中每一行代表一个观察,那么您需要汇总数据并转换它。
现在一切都设置好了,我将从分析数据开始,然后选择特征,建立机器学习模型并进行预测。
我们开始吧,好吗?
数据分析
在统计学中,探索性数据分析是对数据集的主要特征进行总结的过程,以了解数据在正式建模或假设检验任务之外还能告诉我们什么。
我总是从获得整个数据集的概述开始,特别是我想知道有多少分类和数值变量,以及缺失数据的比例。识别变量的类型有时会很棘手,因为类别可以用数字表示(Su rvived c 列由 1 和 0 组成)。为此,我将编写一个简单的函数来完成这项工作:
**'''
Recognize whether a column is numerical or categorical.
:parameter
:param dtf: dataframe - input data
:param col: str - name of the column to analyze
:param max_cat: num - max number of unique values to recognize a column as categorical
:return
"cat" if the column is categorical or "num" otherwise
'''**
def **utils_recognize_type**(dtf, col, max_cat=20):
if (dtf[col].dtype == "O") | (dtf[col].nunique() < max_cat):
return **"cat"**
else:
return **"num"**
这个功能非常有用,可以用在很多场合。为了举例说明,我将绘制 dataframe 的 [热图](http://Heat map) ,以可视化列类型和缺失的数据。
dic_cols = {col:**utils_recognize_type**(dtf, col, max_cat=20) for col in dtf.columns}heatmap = dtf.isnull()
for k,v in dic_cols.items():
if v == "num":
heatmap[k] = heatmap[k].apply(lambda x: 0.5 if x is False else 1)
else:
heatmap[k] = heatmap[k].apply(lambda x: 0 if x is False else 1)sns.**heatmap**(heatmap, cbar=False).set_title('Dataset Overview')
plt.show()print("\033[1;37;40m Categerocial ", "\033[1;30;41m Numeric ", "\033[1;30;47m NaN ")
有 885 行和 12 列:
- 表中的每一行都代表一个由 PassengerId 标识的特定乘客(或观察),所以我将它设置为 index(或 SQL 爱好者的表的主键)。
- 幸存的是我们想要理解和预测的现象(或目标变量),所以我将该列重命名为“Y”。它包含两个类别:如果乘客幸存,则为 1,否则为 0,因此这个用例是一个二元分类问题。
- 年龄和费用是数字变量,而其他是分类变量。
- 只有年龄和舱室包含缺失数据。
dtf = dtf.set_index("**PassengerId**")dtf = dtf.rename(columns={"**Survived**":"**Y**"})
我相信可视化是数据分析的最好工具,但是你需要知道什么样的图更适合不同类型的变量。因此,我将提供代码来为不同的示例绘制适当的可视化。
首先,让我们看看单变量分布(只有一个变量的概率分布)。一个 条形图 适用于理解单个分类变量的标签频率。例如,让我们绘制目标变量:
**y = "Y"**ax = dtf[y].value_counts().sort_values().plot(kind="barh")
totals= []
for i in ax.patches:
totals.append(i.get_width())
total = sum(totals)
for i in ax.patches:
ax.text(i.get_width()+.3, i.get_y()+.20,
str(round((i.get_width()/total)*100, 2))+'%',
fontsize=10, color='black')
ax.grid(axis="x")
plt.suptitle(y, fontsize=20)
plt.show()
多达 300 名乘客幸存,大约 550 人没有,换句话说,存活率(或人口平均值)是 38%。
此外,一个 直方图 完美地给出了单个数值数据的基本分布密度的粗略感觉。我推荐使用一个 箱线图 来图形化地描绘数据组的四分位数。让我们以年龄变量为例:
**x = "Age"**fig, ax = plt.subplots(nrows=1, ncols=2, sharex=False, sharey=False)
fig.suptitle(x, fontsize=20)**### distribution**
ax[0].title.set_text('distribution')
variable = dtf[x].fillna(dtf[x].mean())
breaks = np.quantile(variable, q=np.linspace(0, 1, 11))
variable = variable[ (variable > breaks[0]) & (variable <
breaks[10]) ]
sns.distplot(variable, hist=True, kde=True, kde_kws={"shade": True}, ax=ax[0])
des = dtf[x].describe()
ax[0].axvline(des["25%"], ls='--')
ax[0].axvline(des["mean"], ls='--')
ax[0].axvline(des["75%"], ls='--')
ax[0].grid(True)
des = round(des, 2).apply(lambda x: str(x))
box = '\n'.join(("min: "+des["min"], "25%: "+des["25%"], "mean: "+des["mean"], "75%: "+des["75%"], "max: "+des["max"]))
ax[0].text(0.95, 0.95, box, transform=ax[0].transAxes, fontsize=10, va='top', ha="right", bbox=dict(boxstyle='round', facecolor='white', alpha=1))**### boxplot**
ax[1].title.set_text('outliers (log scale)')
tmp_dtf = pd.DataFrame(dtf[x])
tmp_dtf[x] = np.log(tmp_dtf[x])
tmp_dtf.boxplot(column=x, ax=ax[1])
plt.show()
平均而言,乘客相当年轻:分布偏向左侧(平均值为 30 岁,第 75 百分位为 38 岁)。加上箱形图中的异常值,左尾部的第一个尖峰表示有大量的儿童。
我将把分析进行到下一个层次,并研究双变量分布,以了解年龄是否具有预测 Y 的预测能力。这就是绝对( Y )对数值(年龄 ) 的情况,因此我将这样进行:
- 将总体(整个观察集)分成 2 个样本:Y = 1 (存活)和 Y = 0 (未存活)的乘客部分。
- 绘制并比较两个样本的密度,如果分布不同,则变量是可预测的,因为两组具有不同的模式。
- 将数值变量(年龄)分组到箱(子样本)中,并绘制每个箱的组成,如果所有箱中 1 的比例相似,则该变量不具有预测性。
- 绘制并比较两个样本的箱线图,找出异常值的不同行为。
**cat, num = "Y", "Age"**fig, ax = plt.subplots(nrows=1, ncols=3, sharex=False, sharey=False)
fig.suptitle(x+" vs "+y, fontsize=20)
**### distribution**
ax[0].title.set_text('density')
for i in dtf[cat].unique():
sns.distplot(dtf[dtf[cat]==i][num], hist=False, label=i, ax=ax[0])
ax[0].grid(True)**### stacked**
ax[1].title.set_text('bins')
breaks = np.quantile(dtf[num], q=np.linspace(0,1,11))
tmp = dtf.groupby([cat, pd.cut(dtf[num], breaks, duplicates='drop')]).size().unstack().T
tmp = tmp[dtf[cat].unique()]
tmp["tot"] = tmp.sum(axis=1)
for col in tmp.drop("tot", axis=1).columns:
tmp[col] = tmp[col] / tmp["tot"]
tmp.drop("tot", axis=1).plot(kind='bar', stacked=True, ax=ax[1], legend=False, grid=True)**### boxplot **
ax[2].title.set_text('outliers')
sns.catplot(x=cat, y=num, data=dtf, kind="box", ax=ax[2])
ax[2].grid(True)
plt.show()
这 3 个图只是结论年龄具有预测性的不同角度。年轻乘客的存活率更高:1s 分布的左尾有一个尖峰,第一个箱(0-16 岁)包含最高百分比的幸存乘客。
当“视觉直觉”无法说服你时,你可以求助于古老的统计数据来进行测试。在这种分类(Yvs 数值(年龄)的情况下,我会使用一个on-way ANOVA 检验 。基本上是检验两个或两个以上独立样本的均值是否显著不同,所以如果 p 值足够小(< 0.05)样本的零假设意味着相等可以被拒绝。
**cat, num = "Y", "Age"**model = smf.**ols**(num+' ~ '+cat, data=dtf).fit()
table = sm.stats.**anova_lm**(model)
p = table["PR(>F)"][0]
coeff, p = None, round(p, 3)
conclusion = "Correlated" if p < 0.05 else "Non-Correlated"
print("Anova F: the variables are", conclusion, "(p-value: "+str(p)+")")
显然,乘客的年龄决定了他们的生存。这是有道理的,因为在生命受到威胁的情况下,当救生艇等生存资源有限时,妇女和儿童的生命将被首先拯救,通常是弃船(代码"妇女和儿童优先)。
为了检查第一个结论的有效性,我必须分析性别变量相对于目标变量的行为。这是一个分类( Y ) vs 分类(性别 ) 的例子,所以我将绘制两个条形图,一个是两个类别性别(男性和女性)中 1 和 0 的数量,另一个是百分比。
**x, y = "Sex", "Y"**fig, ax = plt.subplots(nrows=1, ncols=2, sharex=False, sharey=False)
fig.suptitle(x+" vs "+y, fontsize=20)**### count**
ax[0].title.set_text('count')
order = dtf.groupby(x)[y].count().index.tolist()
sns.catplot(x=x, hue=y, data=dtf, kind='count', order=order, ax=ax[0])
ax[0].grid(True)**### percentage**
ax[1].title.set_text('percentage')
a = dtf.groupby(x)[y].count().reset_index()
a = a.rename(columns={y:"tot"})
b = dtf.groupby([x,y])[y].count()
b = b.rename(columns={y:0}).reset_index()
b = b.merge(a, how="left")
b["%"] = b[0] / b["tot"] *100
sns.barplot(x=x, y="%", hue=y, data=b,
ax=ax[1]).get_legend().remove()
ax[1].grid(True)
plt.show()
200 多名女性乘客(占机上女性总数的 75%)和约 100 名男性乘客(不到 20%)幸存。换句话说,女性的存活率是 75%,男性是 20%,因此性别是可以预测的。此外,这证实了他们优先考虑妇女和儿童。
就像之前一样,我们可以测试这两个变量的相关性。由于它们都是分类的,我将使用 C 卡方检验: 假设两个变量是独立的(零假设),它将检验这些变量的列联表的值是否是均匀分布的。如果 p 值足够小(< 0.05),可以拒绝零假设,我们可以说这两个变量可能是相关的。可以计算 C ramer 的 V t 这是从该测试得出的相关性度量,它是对称的(就像传统的皮尔逊相关性),范围在 0 和 1 之间(不像传统的皮尔逊相关性,没有负值)。
**x, y = "Sex", "Y"**cont_table = pd.crosstab(index=dtf[x], columns=dtf[y])
chi2_test = scipy.stats.**chi2_contingency**(cont_table)
chi2, p = chi2_test[0], chi2_test[1]
n = cont_table.sum().sum()
phi2 = chi2/n
r,k = cont_table.shape
phi2corr = max(0, phi2-((k-1)*(r-1))/(n-1))
rcorr = r-((r-1)**2)/(n-1)
kcorr = k-((k-1)**2)/(n-1)
coeff = np.sqrt(phi2corr/min((kcorr-1), (rcorr-1)))
coeff, p = round(coeff, 3), round(p, 3)
conclusion = "Significant" if p < 0.05 else "Non-Significant"
print("Cramer Correlation:", coeff, conclusion, "(p-value:"+str(p)+")")
年龄和性别都是预测特征的例子,但并不是数据集中的所有列都是这样。例如,舱似乎是一个无用变量,因为它不提供任何有用的信息,有太多的缺失值和类别。
应该对数据集中的每个变量进行这种分析,以决定哪些应该作为潜在特征保留,哪些因为不具有预测性而可以放弃(查看完整代码的链接)。
特征工程
是时候使用领域知识从原始数据创建新要素了。我将提供一个例子:我将尝试通过从 Cabin 列中提取信息来创建一个有用的特征。我假设每个舱号开头的字母(即“ B 96 ”)表示某种区域,也许有一些幸运区域靠近救生艇。我将通过提取每个舱室的截面来按组总结观察结果:
**## Create new column**
dtf["**Cabin_section**"] = dtf["**Cabin**"].apply(lambda x: str(x)[0])**## Plot contingency table** cont_table = pd.crosstab(index=dtf["**Cabin_section"**],
columns=dtf["**Pclass**"], values=dtf["**Y**"], aggfunc="sum")sns.**heatmap**(cont_table, annot=True, cmap="YlGnBu", fmt='.0f',
linewidths=.5).set_title(
'Cabin_section vs Pclass (filter: Y)' )
该图显示了幸存者在客舱各部分和各等级中的分布情况(7 名幸存者在 A 区,35 名在 B 区……)。大多数区段被分配给第一类和第二类,而大多数缺失区段(" n" )属于第三类。我将保留这个新特性,而不是列 Cabin:
预处理
数据预处理是准备原始数据以使其适合机器学习模型的阶段。特别是:
- 每个观察必须用一行来表示,换句话说,不能用两行来描述同一个乘客,因为它们将被模型分别处理(数据集已经是这样的形式,所以✅).而且每一列都应该是一个特征,所以你不应该用 PassengerId 作为预测器,这就是为什么这种表叫做“特征矩阵”。
- 数据集必须划分为至少两组:模型应在数据集的重要部分(所谓的“训练集”)上进行训练,并在较小的数据集(“测试集”)上进行测试。
- 缺失值应该用东西替换,否则你的模型可能会出问题。
- 分类数据必须编码,这意味着将标签转换成整数,因为机器学习期望的是数字而不是字符串。
- 对数据进行缩放是一种很好的做法,这有助于在特定范围内对数据进行标准化,并加快算法的计算速度。
好的,让我们从划分数据集开始。当把数据分成训练集和测试集时,你必须遵循一个基本规则:训练集中的行不应该出现在测试集中。这是因为模型在训练过程中会看到目标值,并使用它来理解现象。换句话说,模型已经知道训练观察的正确答案,在这些基础上测试就像作弊。我见过很多人推销他们的机器学习模型,声称有 99.99%的准确率,但实际上却忽略了这条规则。幸运的是,S cikit-learn 包知道:
**## split data**
dtf_train, dtf_test = **model_selection**.**train_test_split**(dtf,
test_size=0.3)**## print info**
print("X_train shape:", dtf_train.drop("Y",axis=1).shape, "| X_test shape:", dtf_test.drop("Y",axis=1).shape)
print("y_train mean:", round(np.mean(dtf_train["Y"]),2), "| y_test mean:", round(np.mean(dtf_test["Y"]),2))
print(dtf_train.shape[1], "features:", dtf_train.drop("Y",axis=1).columns.to_list())
下一步:年龄列包含一些需要处理的缺失数据 (19%)。在实践中,您可以用一个特定的值来替换丢失的数据,比如 9999,它可以跟踪丢失的信息,但会改变变量的分布。或者,你可以使用列的平均值,就像我要做的。我想强调的是,从机器学习的角度来看,首先分成训练和测试,然后仅用训练集的平均值替换 NAs 是正确的。
dtf_train["Age"] = dtf_train["Age"].**fillna**(dtf_train["Age"].**mean**())
仍然有一些分类数据应该被编码。两种最常见的编码器是标签编码器(每个唯一的标签映射到一个整数)和一位热编码器(每个标签映射到一个二进制向量)。第一种方法只适用于普通数据。如果应用于没有普通性的列,如 Sex ,它会将向量【male,female,female,male,male,…】转换为【1,2,2,1,…】,我们会得到那个 female > male,平均值为 1.5,这是没有意义的。另一方面,One-Hot-Encoder 会将之前的示例转换为两个虚拟变量(二分量化变量):Mal e [1 ,0,0,1,…]和 Fem ale [0 ,1,1,0,…]。它的优点是结果是二进制的而不是有序的,并且一切都位于正交向量空间中,但是具有高基数的特性可能会导致维数问题。我将使用 One-Hot-Encoding 方法,将 1 个具有 n 个唯一值的分类列转换为 n-1 个虚拟列。让我们以编码性别为T21 为例:
**## create dummy**
dummy = pd.get_dummies(dtf_train["**Sex**"],
prefix="Sex",drop_first=True)
dtf_train= pd.concat([dtf_train, dummy], axis=1)
print( dtf_train.filter(like="Sex", axis=1).head() )**## drop the original categorical column**
dtf = dtf_train.drop("**Sex**", axis=1)
最后但同样重要的是,我将缩放特征。有几种不同的方法可以做到这一点,我将只介绍最常用的方法:标准缩放器和最小最大缩放器。第一种假设数据呈正态分布,并对其进行重新调整,使分布以 0 为中心,标准差为 1。然而,当计算缩小特征值范围的经验平均值和标准偏差时,离群值具有影响,因此该缩放器不能在离群值存在时保证平衡的特征尺度。另一方面,最小最大缩放器重新缩放数据集,使所有特征值都在同一范围内(0–1)。它受离群值的影响较小,但压缩了一个狭窄范围内的所有内联值。因为我的数据不是正态分布的,所以我将使用最小最大缩放器:
scaler = **preprocessing**.**MinMaxScaler**(feature_range=(0,1))
X = scaler.fit_transform(dtf_train.drop("Y", axis=1))dtf_scaled= pd.DataFrame(X, columns=dtf_train.drop("Y", axis=1).columns, index=dtf_train.index)
dtf_scaled["Y"] = dtf_train["Y"]
dtf_scaled.head()
特征选择
特征选择是选择相关变量的子集来构建机器学习模型的过程。它使模型更容易解释,并减少过度拟合(当模型适应训练数据过多,并且在训练集之外表现不佳时)。
在数据分析期间,我已经通过排除不相关的列进行了第一次“手动”特征选择。现在会有一点不同,因为我们假设矩阵中的所有特性都是相关的,我们想去掉不必要的特性。当一个特性不是必需的时候。答案很简单:当有更好的对等物,或者做同样工作但更好的对等物时。
我用一个例子来解释: Pclass 与 Cabin_section 高度相关,因为,正如我们之前看到的,某些部分位于一等舱,而其他部分位于二等舱。让我们计算相关矩阵来看看:
corr_matrix = dtf.copy()
for col in corr_matrix.columns:
if corr_matrix[col].dtype == "O":
corr_matrix[col] = corr_matrix[col].factorize(sort=True)[0]corr_matrix = corr_matrix.**corr**(method="pearson")
sns.heatmap(corr_matrix, vmin=-1., vmax=1., annot=True, fmt='.2f', cmap="YlGnBu", cbar=True, linewidths=0.5)
plt.title("pearson correlation")
Pclass 和 Cabin_section 中的一个可能是不必要的,我们可以决定丢弃它并保留最有用的一个(即具有最低 p 值的一个或最能降低熵的一个)。
我将展示两种不同的方法来执行自动特征选择:首先,我将使用正则化方法并将其与之前已经提到的 ANOVA 测试进行比较,然后我将展示如何从集成方法中获得特征重要性。
套索正则化 是一种回归分析方法,执行变量选择和正则化,以提高准确性和可解释性。
X = dtf_train.drop("Y", axis=1).values
y = dtf_train["Y"].values
feature_names = dtf_train.drop("Y", axis=1).columns**## Anova**
selector = **feature_selection.SelectKBest**(score_func=
feature_selection.f_classif, k=10).fit(X,y)
anova_selected_features = feature_names[selector.get_support()]
**## Lasso regularization**
selector = **feature_selection.SelectFromModel**(estimator=
linear_model.LogisticRegression(C=1, penalty="l1",
solver='liblinear'), max_features=10).fit(X,y)
lasso_selected_features = feature_names[selector.get_support()]
**## Plot** dtf_features = pd.DataFrame({"features":feature_names})
dtf_features["anova"] = dtf_features["features"].apply(lambda x: "anova" if x in anova_selected_features else "")
dtf_features["num1"] = dtf_features["features"].apply(lambda x: 1 if x in anova_selected_features else 0)
dtf_features["lasso"] = dtf_features["features"].apply(lambda x: "lasso" if x in lasso_selected_features else "")
dtf_features["num2"] = dtf_features["features"].apply(lambda x: 1 if x in lasso_selected_features else 0)
dtf_features["method"] = dtf_features[["anova","lasso"]].apply(lambda x: (x[0]+" "+x[1]).strip(), axis=1)
dtf_features["selection"] = dtf_features["num1"] + dtf_features["num2"]
sns.**barplot**(y="features", x="selection", hue="method", data=dtf_features.sort_values("selection", ascending=False), dodge=False)
蓝色要素是通过方差分析和 LASSO 选择的要素,其他要素是通过两种方法中的一种选择的。
随机森林 是一种集成方法,由许多决策树组成,其中每个节点都是单个要素上的一个条件,旨在将数据集一分为二,以便相似的响应值最终出现在同一组中。特征重要性是根据每个特征减少树中熵的多少来计算的。
X = dtf_train.drop("Y", axis=1).values
y = dtf_train["Y"].values
feature_names = dtf_train.drop("Y", axis=1).columns.tolist()**## Importance**
model = ensemble.**RandomForestClassifier**(n_estimators=100,
criterion="entropy", random_state=0)
model.fit(X,y)
importances = model.**feature_importances_****## Put in a pandas dtf**
dtf_importances = pd.DataFrame({"IMPORTANCE":importances,
"VARIABLE":feature_names}).sort_values("IMPORTANCE",
ascending=False)
dtf_importances['cumsum'] =
dtf_importances['IMPORTANCE'].cumsum(axis=0)
dtf_importances = dtf_importances.set_index("VARIABLE")
**##** **Plot**
fig, ax = plt.subplots(nrows=1, ncols=2, sharex=False, sharey=False)
fig.suptitle("Features Importance", fontsize=20)
ax[0].title.set_text('variables')
dtf_importances[["IMPORTANCE"]].sort_values(by="IMPORTANCE").plot(
kind="barh", legend=False, ax=ax[0]).grid(axis="x")
ax[0].set(ylabel="")
ax[1].title.set_text('cumulative')
dtf_importances[["cumsum"]].plot(kind="line", linewidth=4,
legend=False, ax=ax[1])
ax[1].set(xlabel="", xticks=np.arange(len(dtf_importances)),
xticklabels=dtf_importances.index)
plt.xticks(rotation=70)
plt.grid(axis='both')
plt.show()
很有意思的是,年龄和票价、这两个这次最重要的特征,以前并不是最重要的特征,相反客舱 _ E 段、 F 和 D 在这里似乎并不太有用。
就我个人而言,我总是尽量少用一些功能,所以在这里我选择了以下几个,并继续进行机器学习模型的设计、训练、测试和评估:
X_names = ["Age", "Fare", "Sex_male", "SibSp", "Pclass_3", "Parch",
"Cabin_section_n", "Embarked_S", "Pclass_2", "Cabin_section_F", "Cabin_section_E", "Cabin_section_D"]X_train = dtf_train[X_names].values
y_train = dtf_train["Y"].valuesX_test = dtf_test[X_names].values
y_test = dtf_test["Y"].values
请注意,在使用测试数据进行预测之前,您必须对其进行预处理,就像我们对训练数据所做的那样。
模型设计
最后,是时候建立机器学习模型了。首先,我们需要选择一种算法,它能够从训练数据中学习如何通过最小化一些误差函数来识别目标变量的两个类别。
来源: scikit-learn
我建议总是尝试一个 渐变提升 算法(像 XGBoost)。这是一种机器学习技术,它以弱预测模型的集合的形式产生预测模型,通常是决策树。基本上,它类似于一个随机的森林,不同之处在于每棵树都符合前一棵树的误差。
来源: scikit-learn
有很多超参数,没有什么是最好的通用规则,所以你只需要找到更适合你的数据的正确组合。您可以手动进行不同的尝试,或者让计算机通过 GridSearch(尝试每种可能的组合,但需要时间)或 RandomSearch(随机尝试固定次数的迭代)来完成这项繁琐的工作。我将尝试对我的超参数调整进行随机搜索:机器将通过训练数据迭代 n 次(1000 次)以找到参数组合(在下面的代码中指定),最大化用作 KPI(准确性,正确预测数与输入样本总数的比率)的评分函数:
**## call model**
model = ensemble.**GradientBoostingClassifier**()**## define hyperparameters combinations to try** param_dic = {'**learning_rate**':[0.15,0.1,0.05,0.01,0.005,0.001], *#weighting factor for the corrections by new trees when added to the model* '**n_estimators**':[100,250,500,750,1000,1250,1500,1750], *#number of trees added to the model*
'**max_depth**':[2,3,4,5,6,7], *#maximum depth of the tree*
'**min_samples_split**':[2,4,6,8,10,20,40,60,100], *#sets the minimum number of samples to split*
'**min_samples_leaf**':[1,3,5,7,9], *#the minimum number of samples to form a leaf* '**max_features**':[2,3,4,5,6,7], *#square root of features is usually a good starting point*
'**subsample**':[0.7,0.75,0.8,0.85,0.9,0.95,1]} *#the fraction of samples to be used for fitting the individual base learners. Values lower than 1 generally lead to a reduction of variance and an increase in bias.***## random search**
random_search = model_selection.**RandomizedSearchCV**(model,
param_distributions=param_dic, n_iter=1000,
scoring="accuracy").fit(X_train, y_train)print("Best Model parameters:", random_search.best_params_)
print("Best Model mean accuracy:", random_search.best_score_)model = random_search.best_estimator_
酷,这是最好的模型,平均精度为 0.85,因此在测试集上可能有 85%的预测是正确的。
我们还可以使用 k 倍交叉验证来验证该模型,该过程包括将数据分成 k 次训练和验证集,并且针对每次分割对模型进行训练和测试。它用于检查模型通过一些数据进行训练的能力,以及预测未知数据的能力。
我想澄清一下,我称验证集为一组用于调整分类器超参数的例子,从分割训练数据中提取。另一方面,测试集是一个模拟模型在生产中的表现,当它被要求预测以前从未见过的观察时。
通常为每个折叠绘制一个 ROC 曲线,该图说明了二元分类器的能力如何随着其区分阈值的变化而变化。它是通过在各种阈值设置下绘制真阳性率(正确预测的 1)与假阳性率(预测的 1 实际上是 0)来创建的。AUC(ROC 曲线下的面积)表示分类器将随机选择的阳性观察值( Y=1 )排序高于随机选择的阴性观察值( Y=0 )的概率。
现在,我将展示一个 10 次折叠的示例(k=10):
cv = model_selection.StratifiedKFold(n_splits=10, shuffle=True)
tprs, aucs = [], []
mean_fpr = np.linspace(0,1,100)
fig = plt.figure()i = 1
for train, test in cv.split(X_train, y_train):
prediction = model.fit(X_train[train],
y_train[train]).predict_proba(X_train[test])
fpr, tpr, t = metrics.roc_curve(y_train[test], prediction[:, 1])
tprs.append(scipy.interp(mean_fpr, fpr, tpr))
roc_auc = metrics.auc(fpr, tpr)
aucs.append(roc_auc)
plt.plot(fpr, tpr, lw=2, alpha=0.3, label='ROC fold %d (AUC =
%0.2f)' % (i, roc_auc))
i = i+1
plt.plot([0,1], [0,1], linestyle='--', lw=2, color='black')
mean_tpr = np.mean(tprs, axis=0)
mean_auc = metrics.auc(mean_fpr, mean_tpr)
plt.plot(mean_fpr, mean_tpr, color='blue', label=r'Mean ROC (AUC =
%0.2f )' % (mean_auc), lw=2, alpha=1)
plt.xlabel('False Positive Rate')
plt.ylabel('True Positive Rate')
plt.title('K-Fold Validation')
plt.legend(loc="lower right")
plt.show()
根据这一验证,在对测试进行预测时,我们应该预期 AUC 分数在 0.84 左右。
出于本教程的目的,我认为性能很好,我们可以继续使用随机搜索选择的模型。一旦选择了正确的模型,就可以在整个训练集上对其进行训练,然后在测试集上进行测试。
**## train**
model.**fit**(X_train, y_train)**## test**
predicted_prob = model.**predict_proba**(X_test)[:,1]
predicted = model.**predict**(X_test)
在上面的代码中,我做了两种预测:第一种是观察值为 1 的概率,第二种是标签(1 或 0)的预测。为了得到后者,你必须决定一个概率阈值,对于这个阈值,一个观察可以被认为是 1,我使用默认的阈值 0.5。
估价
关键时刻到了,我们要看看所有这些努力是否值得。重点是研究模型做出了多少正确的预测和错误类型。
我将使用以下常用指标来评估该模型:准确性、AUC、 精度和召回 。我已经提到了前两个,但我认为其他的更重要。精度是模型在所有预测的 1(或 0)中正确预测的 1(或 0)的分数,因此它可以被视为预测 1(或 0)时的一种置信度。召回是模型在测试集中所有 1(或 0)中正确预测的 1(或 0)的部分,基本上它是真正的 1 率。将精确度和召回率与调和平均值相结合,就得到 F1 分数。
让我们看看模型在测试集上的表现:
**## Accuray e AUC**
accuracy = metrics.**accuracy_score**(y_test, predicted)
auc = metrics.**roc_auc_score**(y_test, predicted_prob)
print("Accuracy (overall correct predictions):", round(accuracy,2))
print("Auc:", round(auc,2))
**## Precision e Recall**
recall = metrics.**recall_score**(y_test, predicted)
precision = metrics.**precision_score**(y_test, predicted)
print("Recall (all 1s predicted right):", round(recall,2))
print("Precision (confidence when predicting a 1):", round(precision,2))
print("Detail:")
print(metrics.**classification_report**(y_test, predicted, target_names=[str(i) for i in np.unique(y_test)]))
正如预期的那样,模型的总体准确率在 85%左右。它以 84%的精度正确预测了 71%的 1,以 85%的精度正确预测了 92%的 0。为了更好地理解这些指标,我将把结果分解成一个混淆矩阵:
classes = np.unique(y_test)
fig, ax = plt.subplots()
cm = metrics.**confusion_matrix**(y_test, predicted, labels=classes)
sns.heatmap(cm, annot=True, fmt='d', cmap=plt.cm.Blues, cbar=False)
ax.set(xlabel="Pred", ylabel="True", title="Confusion matrix")
ax.set_yticklabels(labels=classes, rotation=0)
plt.show()
我们可以看到,该模型预测了 85 (70+15)个 1,其中 70 个是真阳性,15 个是假阳性,因此在预测 1 时,它的精度为 70/85 = 0.82。另一方面,该模型在测试集中的所有 96 个(70+26)1 中得到了 70 个 1,因此其召回率为 70/96 = 0.73。
选择阈值 0.5 来决定预测是 1 还是 0 导致了这种结果。换一个会不一样吗?当然可以,但是没有一个阈值可以让准确率和召回率都达到最高分,选择一个阈值意味着在这两个指标之间进行折衷。我将通过绘制测试结果的 ROC 曲线和精确回忆曲线来说明我的意思:
classes = np.unique(y_test)
fig, ax = plt.subplots(nrows=1, ncols=2)**## plot ROC curve**
fpr, tpr, thresholds = metrics.**roc_curve**(y_test, predicted_prob)
roc_auc = metrics.auc(fpr, tpr)
ax[0].plot(fpr, tpr, color='darkorange', lw=3, label='area = %0.2f' % roc_auc)
ax[0].plot([0,1], [0,1], color='navy', lw=3, linestyle='--')
ax[0].hlines(y=recall, xmin=0, xmax=1-cm[0,0]/(cm[0,0]+cm[0,1]), color='red', linestyle='--', alpha=0.7, label="chosen threshold")
ax[0].vlines(x=1-cm[0,0]/(cm[0,0]+cm[0,1]), ymin=0, ymax=recall, color='red', linestyle='--', alpha=0.7)
ax[0].set(xlabel='False Positive Rate', ylabel="True Positive Rate (Recall)", title="Receiver operating characteristic")
ax.legend(loc="lower right")
ax.grid(True)**## annotate ROC thresholds**
thres_in_plot = []
for i,t in enumerate(thresholds):
t = np.round(t,1)
if t not in thres_in_plot:
ax.annotate(t, xy=(fpr[i],tpr[i]), xytext=(fpr[i],tpr[i]),
textcoords='offset points', ha='left', va='bottom')
thres_in_plot.append(t)
else:
next**## plot P-R curve**
precisions, recalls, thresholds = metrics.**precision_recall_curve**(y_test, predicted_prob)
roc_auc = metrics.auc(recalls, precisions)
ax[1].plot(recalls, precisions, color='darkorange', lw=3, label='area = %0.2f' % roc_auc)
ax[1].plot([0,1], [(cm[1,0]+cm[1,0])/len(y_test), (cm[1,0]+cm[1,0])/len(y_test)], linestyle='--', color='navy', lw=3)
ax[1].hlines(y=precision, xmin=0, xmax=recall, color='red', linestyle='--', alpha=0.7, label="chosen threshold")
ax[1].vlines(x=recall, ymin=0, ymax=precision, color='red', linestyle='--', alpha=0.7)
ax[1].set(xlabel='Recall', ylabel="Precision", title="Precision-Recall curve")
ax[1].legend(loc="lower left")
ax[1].grid(True)**## annotate P-R thresholds** thres_in_plot = []
for i,t in enumerate(thresholds):
t = np.round(t,1)
if t not in thres_in_plot:
ax.annotate(np.round(t,1), xy=(recalls[i],precisions[i]),
xytext=(recalls[i],precisions[i]),
textcoords='offset points', ha='left', va='bottom')
thres_in_plot.append(t)
else:
next
plt.show()
这些曲线的每一点都代表用不同阈值(曲线上印的数字)获得的混淆矩阵。我可以使用 0.1 的阈值,获得 0.9 的召回率,这意味着该模型将正确预测 90%的 1,但精度将下降到 0.4,这意味着该模型将预测大量的假阳性。因此,这实际上取决于用例的类型,尤其是假阳性是否比假阴性的成本更高。
当数据集是平衡的,并且项目涉众没有指定度量标准时,我通常选择最大化 F1 分数的阈值。方法如下:
**## calculate scores for different thresholds**
dic_scores = {'accuracy':[], 'precision':[], 'recall':[], 'f1':[]}
XX_train, XX_test, yy_train, yy_test = model_selection.train_test_split(X_train, y_train, test_size=0.2)
predicted_prob = model.fit(XX_train, yy_train).predict_proba(XX_test)[:,1]thresholds = []
for threshold in np.arange(0.1, 1, step=0.1):
predicted = (predicted_prob > threshold)
thresholds.append(threshold)
dic_scores["accuracy"].append(metrics.accuracy_score(yy_test, predicted))
dic_scores["precision"].append(metrics.precision_score(yy_test, predicted))
dic_scores["recall"].append(metrics.recall_score(yy_test, predicted))
dic_scores["f1"].append(metrics.f1_score(yy_test, predicted))
**## plot** dtf_scores = pd.DataFrame(dic_scores).set_index(pd.Index(thresholds))
dtf_scores.plot(ax=ax, title="Threshold Selection")
plt.show()
在继续这篇长教程的最后一节之前,我想说我们还不能说这个模型是好是坏。精度 0.85,高吗?相比什么?你需要一个基线来比较你的模型。也许你正在做的项目是关于建立一个新的模型来取代一个可以用作基线的旧模型,或者你可以在同一训练集上训练不同的机器学习模型,并在测试集上比较性能。
可解释性
你分析并理解了数据,你训练了一个模型并测试了它,你甚至对性能感到满意。你以为你完了吗?不对。项目利益相关者很有可能不关心你的指标,不理解你的算法,所以你必须证明你的机器学习模型不是黑盒。
石灰包可以帮助我们建造一个讲解器。为了举例说明,我将从测试集中随机观察,看看模型预测了什么:
print("True:", y_test[4], "--> Pred:", predicted[4], "| Prob:", np.max(predicted_prob[4]))
模型认为这个观察值是 1,概率为 0.93,事实上这个乘客确实活了下来。为什么?让我们使用解释器:
explainer = lime_tabular.LimeTabularExplainer(training_data=X_train, feature_names=X_names, class_names=np.unique(y_train), mode="classification")
explained = explainer.explain_instance(X_test[4], model.predict_proba, num_features=10)
explained.as_pyplot_figure()
该特定预测的主要因素是乘客是女性(性别 _ 男性= 0)、年轻(年龄≤ 22)并且乘坐头等舱旅行(Pclass_3 = 0 和 Pclass_2 = 0)。
混淆矩阵是显示测试进行情况的一个很好的工具,但是我也绘制了分类区域来直观地帮助我们了解模型正确预测了哪些观察结果,以及它错过了哪些观察结果。为了绘制二维数据,需要进行一定程度的降维(通过获得一组主要变量来减少特征数量的过程)。我将给出一个例子,使用 PCA 算法将数据总结为两个变量,这些变量是通过特征的线性组合获得的。
**## PCA**
pca = decomposition.PCA(n_components=2)
X_train_2d = pca.fit_transform(X_train)
X_test_2d = pca.transform(X_test)**## train 2d model**
model_2d = ensemble.GradientBoostingClassifier()
model_2d.fit(X_train, y_train)
**## plot classification regions**
from matplotlib.colors import ListedColormap
colors = {np.unique(y_test)[0]:"black", np.unique(y_test)[1]:"green"}
X1, X2 = np.meshgrid(np.arange(start=X_test[:,0].min()-1, stop=X_test[:,0].max()+1, step=0.01),
np.arange(start=X_test[:,1].min()-1, stop=X_test[:,1].max()+1, step=0.01))
fig, ax = plt.subplots()
Y = model_2d.predict(np.array([X1.ravel(), X2.ravel()]).T).reshape(X1.shape)
ax.contourf(X1, X2, Y, alpha=0.5, cmap=ListedColormap(list(colors.values())))
ax.set(xlim=[X1.min(),X1.max()], ylim=[X2.min(),X2.max()], title="Classification regions")
for i in np.unique(y_test):
ax.scatter(X_test[y_test==i, 0], X_test[y_test==i, 1],
c=colors[i], label="true "+str(i))
plt.legend()
plt.show()
结论
这篇文章是演示如何用数据科学处理分类用例的教程。我以泰坦尼克号数据集为例,经历了从数据分析到机器学习模型的每一步。
在探索部分,我分析了单个分类变量、单个数值变量以及它们如何相互作用的情况。我举了一个从原始数据中提取特征的特征工程的例子。关于预处理,我解释了如何处理缺失值和分类数据。我展示了选择正确特征的不同方法,如何使用它们来构建机器学习分类器,以及如何评估性能。在最后一节,我就如何提高你的机器学习模型的可解释性给出了一些建议。
一个重要的注意事项是,我还没有介绍在您的模型被批准部署之后会发生什么。请记住,您需要构建一个管道来自动处理您将定期获得的新数据。
现在,您已经知道如何处理数据科学用例,您可以将这些代码和方法应用于任何类型的二进制分类问题,执行您自己的分析,构建您自己的模型,甚至解释它。
我希望你喜欢它!如有问题和反馈,或者只是分享您感兴趣的项目,请随时联系我。
👉我们来连线👈
本文是系列用 Python 进行机器学习的一部分,参见:
** [## Python 机器学习:回归(完整教程)
数据分析和可视化、特征工程和选择、模型设计和测试、评估和解释
towardsdatascience.com](/machine-learning-with-python-regression-complete-tutorial-47268e546cea) [## 聚类地理空间数据
使用交互式地图绘制机器学习和深度学习聚类
towardsdatascience.com](/clustering-geospatial-data-f0584f0b04ec) [## Python 深度学习:神经网络(完整教程)
用 TensorFlow 建立、绘制和解释人工神经网络
towardsdatascience.com](/deep-learning-with-python-neural-networks-complete-tutorial-6b53c0b06af0) [## 基于神经网络的现代推荐系统
使用 Python 和 TensorFlow 构建混合模型
towardsdatascience.com](/modern-recommendation-systems-with-neural-networks-3cc06a6ded2c)**
Python 机器学习:回归(完整教程)
原文:https://towardsdatascience.com/machine-learning-with-python-regression-complete-tutorial-47268e546cea?source=collection_archive---------2-----------------------
数据分析和可视化、特征工程和选择、模型设计和测试、评估和解释
摘要
在本文中,我将使用数据科学和 Python 解释回归用例的主要步骤,从数据分析到理解模型输出。
我将展示一些有用的 Python 代码,这些代码可以很容易地用于其他类似的情况(只需复制、粘贴、运行),并通过注释遍历每一行代码,这样您就可以很容易地复制这个示例(下面是完整代码的链接)。
[## mdipietro 09/data science _ 人工智能 _ 实用工具
permalink dissolve GitHub 是 4000 多万开发人员的家园,他们一起工作来托管和审查代码,管理…
github.com](https://github.com/mdipietro09/DataScience_ArtificialIntelligence_Utils/blob/master/machine_learning/example_regression.ipynb)
我将使用“房价数据集”(链接如下),其中为您提供了描述一些住宅不同方面的多个解释变量,任务是预测每套住宅的最终价格。
[## 房价:高级回归技术
预测销售价格并实践特征工程、RFs 和梯度推进
www.kaggle.com](https://www.kaggle.com/c/house-prices-advanced-regression-techniques/data)
特别是,我将经历:
- 环境设置:导入库并读取数据
- 数据分析:理解变量的意义和预测能力
- 特征工程:从原始数据中提取特征
- 预处理:数据划分、处理缺失值、编码分类变量、缩放
- 特征选择:只保留最相关的变量
- 模型设计:基线、训练、验证、测试
- 绩效评估:阅读指标
- 可解释性:理解模型如何做出预测
设置
首先,我需要导入以下库。
**## for data**
import **pandas** as pd
import **numpy** as np**## for plotting**
import **matplotlib**.pyplot as plt
import **seaborn** as sns**## for statistical tests**
import **scipy**
import **statsmodels**.formula.api as smf
import statsmodels.api as sm**## for machine learning**
from **sklearn** import model_selection, preprocessing, feature_selection, ensemble, linear_model, metrics, decomposition**## for explainer**
from **lime** import lime_tabular
然后我会把数据读入一个熊猫数据帧。原始数据集包含 81 列,但是出于本教程的目的,我将使用 12 列的子集。
dtf = pd.read_csv("data_houses.csv")cols = ["OverallQual","GrLivArea","GarageCars",
"GarageArea","TotalBsmtSF","FullBath",
"YearBuilt","YearRemodAdd",
"LotFrontage","MSSubClass"]dtf = dtf[["Id"]+cols+["SalePrice"]]
dtf.head()
有关列的详细信息可以在所提供的数据集链接中找到。
请注意,表格的每一行代表一个特定的房子(或观察)。如果您正在处理一个不同的数据集,它没有这样的结构,其中每一行代表一个观察,那么您需要汇总数据并转换它。
现在一切都设置好了,我将从分析数据开始,然后选择特征,建立机器学习模型并进行预测。
我们开始吧,好吗?
数据分析
在统计学中,探索性数据分析是对数据集的主要特征进行总结的过程,以了解数据在正式建模或假设检验任务之外还能告诉我们什么。
我总是从获得整个数据集的概述开始,特别是,我想知道有多少个分类和数值变量以及缺失数据的比例。识别变量的类型有时会很棘手,因为类别可以用数字表示。为此,我将编写一个简单的函数来完成这项工作:
**'''
Recognize whether a column is numerical or categorical.
:parameter
:param dtf: dataframe - input data
:param col: str - name of the column to analyze
:param max_cat: num - max number of unique values to recognize a column as categorical
:return
"cat" if the column is categorical or "num" otherwise
'''**
def **utils_recognize_type**(dtf, col, max_cat=20):
if (dtf[col].dtype == "O") | (dtf[col].nunique() < max_cat):
return **"cat"**
else:
return **"num"**
这个功能非常有用,可以用在很多场合。为了举例说明,我将绘制 dataframe 的 [热图](http://Heat map) ,并可视化列类型和缺失的数据。
dic_cols = {col:**utils_recognize_type**(dtf, col, max_cat=20) for col in dtf.columns}heatmap = dtf.isnull()
for k,v in dic_cols.items():
if v == "num":
heatmap[k] = heatmap[k].apply(lambda x: 0.5 if x is False else 1)
else:
heatmap[k] = heatmap[k].apply(lambda x: 0 if x is False else 1)sns.**heatmap**(heatmap, cbar=False).set_title('Dataset Overview')
plt.show()print("\033[1;37;40m Categerocial ", "\033[1;30;41m Numeric ", "\033[1;30;47m NaN ")
有 1460 行和 12 列:
- 表中的每一行都代表一个由 Id 标识的特定房屋(或观察),所以我将它设置为索引(或者为 SQL 爱好者设置表的主键)。
- SalePrice 是我们想要了解和预测的因变量,所以我将该列重命名为“Y”。
- 总体质量、车库、全浴和ms 子类是分类变量,其他是数值变量。
- 只有 LotFrontage 包含缺失数据。
dtf = dtf.set_index("**Id**")dtf = dtf.rename(columns={"**SalePrice**":"**Y**"})
我相信可视化是数据分析的最好工具,但是你需要知道什么样的图更适合不同类型的变量。因此,我将提供代码来为不同的示例绘制适当的可视化。
首先,让我们看看单变量分布(只有一个变量的概率分布)。一个 直方图 完美地给出了单个数值数据的底层分布密度的粗略感觉。我推荐使用一个 方框图 来图形化地描绘数据组通过它们的四分位数。例如,让我们绘制目标变量:
**x = "Y"**fig, ax = plt.subplots(nrows=1, ncols=2, sharex=False, sharey=False)
fig.suptitle(x, fontsize=20)**### distribution**
ax[0].title.set_text('distribution')
variable = dtf[x].fillna(dtf[x].mean())
breaks = np.quantile(variable, q=np.linspace(0, 1, 11))
variable = variable[ (variable > breaks[0]) & (variable <
breaks[10]) ]
sns.distplot(variable, hist=True, kde=True, kde_kws={"shade": True}, ax=ax[0])
des = dtf[x].describe()
ax[0].axvline(des["25%"], ls='--')
ax[0].axvline(des["mean"], ls='--')
ax[0].axvline(des["75%"], ls='--')
ax[0].grid(True)
des = round(des, 2).apply(lambda x: str(x))
box = '\n'.join(("min: "+des["min"], "25%: "+des["25%"], "mean: "+des["mean"], "75%: "+des["75%"], "max: "+des["max"]))
ax[0].text(0.95, 0.95, box, transform=ax[0].transAxes, fontsize=10, va='top', ha="right", bbox=dict(boxstyle='round', facecolor='white', alpha=1))**### boxplot**
ax[1].title.set_text('outliers (log scale)')
tmp_dtf = pd.DataFrame(dtf[x])
tmp_dtf[x] = np.log(tmp_dtf[x])
tmp_dtf.boxplot(column=x, ax=ax[1])
plt.show()
这个群体的平均房价是 181,000 美元,分布是高度偏斜的,两边都有异常值。
此外,一个 条形图 适于理解单个分类变量的标签频率。让我们以全浴室(浴室数量)变量为例:它具有普通性(2 个浴室> 1 个浴室),但它不是连续的(一个家庭不可能有 1.5 个浴室),所以它可以作为一个范畴来分析。
**x = "Y"**ax = dtf[x].value_counts().sort_values().plot(kind="barh")
totals= []
for i in ax.patches:
totals.append(i.get_width())
total = sum(totals)
for i in ax.patches:
ax.text(i.get_width()+.3, i.get_y()+.20,
str(round((i.get_width()/total)*100, 2))+'%',
fontsize=10, color='black')
ax.grid(axis="x")
plt.suptitle(x, fontsize=20)
plt.show()
大多数房子有 1 个或 2 个浴室,也有一些离群值有 0 个和 3 个浴室。
我将把分析带到下一个层次,并研究二元分布,以了解 FullBath 是否具有预测 Y 的预测能力。这就是分类(全浴)对数字( Y ) 的情况,因此我将这样进行:
- 将人口(整套观察结果)分成 4 个样本:有 0 间浴室(全浴= 0)、 1 间浴室(全浴= 1) 的房屋部分,以此类推…
- 绘制并比较 4 个样本的密度,如果分布不同,则变量是可预测的,因为 4 组具有不同的模式。
- 将数值变量( Y )分组到箱(子样本)中,并绘制每个箱的组成,如果所有箱中类别的比例相似,则该变量不具有预测性。
- 绘制并比较 4 个样本的箱线图,找出异常值的不同行为。
**cat, num = "FullBath", "Y"**fig, ax = plt.subplots(nrows=1, ncols=3, sharex=False, sharey=False)
fig.suptitle(x+" vs "+y, fontsize=20)
**### distribution**
ax[0].title.set_text('density')
for i in dtf[cat].unique():
sns.distplot(dtf[dtf[cat]==i][num], hist=False, label=i, ax=ax[0])
ax[0].grid(True)**### stacked**
ax[1].title.set_text('bins')
breaks = np.quantile(dtf[num], q=np.linspace(0,1,11))
tmp = dtf.groupby([cat, pd.cut(dtf[num], breaks, duplicates='drop')]).size().unstack().T
tmp = tmp[dtf[cat].unique()]
tmp["tot"] = tmp.sum(axis=1)
for col in tmp.drop("tot", axis=1).columns:
tmp[col] = tmp[col] / tmp["tot"]
tmp.drop("tot", axis=1).plot(kind='bar', stacked=True, ax=ax[1], legend=False, grid=True)**### boxplot **
ax[2].title.set_text('outliers')
sns.catplot(x=cat, y=num, data=dtf, kind="box", ax=ax[2])
ax[2].grid(True)
plt.show()
FullBath 似乎具有预测性,因为 4 个样本的分布在价格水平和观察次数上有很大不同。房子里的浴室越多,价格就越高,但我想知道 0 浴室样本和 3 浴室样本中的观察值是否有统计学意义,因为它们包含的观察值很少。
当“视觉直觉”无法说服你时,你可以求助于古老的统计数据来进行测试。在这种分类(full bathvs 数值( Y )的情况下,我会使用一个on-way ANOVA 检验 。基本上是检验两个或两个以上独立样本的均值是否显著不同,所以如果 p 值足够小(< 0.05)样本的零假设意味着相等可以被拒绝。
**cat, num = "FullBath", "Y"**model = smf.**ols**(num+' ~ '+cat, data=dtf).fit()
table = sm.stats.**anova_lm**(model)
p = table["PR(>F)"][0]
coeff, p = None, round(p, 3)
conclusion = "Correlated" if p < 0.05 else "Non-Correlated"
print("Anova F: the variables are", conclusion, "(p-value: "+str(p)+")")
我们可以得出结论,浴室的数量决定了房子的价格。这是有道理的,因为更多的浴室意味着更大的房子,而房子的大小是一个重要的价格因素。
为了检查第一个结论的有效性,我必须分析目标变量相对于 GrLivArea (以平方英尺为单位的地上居住面积)的行为。这是一个数值( GrLivArea ) vs 数值( Y ) 的例子,所以我将生成两个图:
- 首先,我将把 GrLivArea 值分组到箱中,并比较每个箱中 Y 的平均值(和中值),如果曲线不平坦,则变量是预测性的,因为箱具有不同的模式。
- 第二,我将使用散点图,图中两边是两个变量的分布。
**x, y = "GrLivArea", "Y"****### bin plot** dtf_noNan = dtf[dtf[x].notnull()]
breaks = np.quantile(dtf_noNan[x], q=np.linspace(0, 1, 11))
groups = dtf_noNan.groupby([pd.cut(dtf_noNan[x], bins=breaks,
duplicates='drop')])[y].agg(['mean','median','size'])
fig, ax = plt.subplots(figsize=figsize)
fig.suptitle(x+" vs "+y, fontsize=20)
groups[["mean", "median"]].plot(kind="line", ax=ax)
groups["size"].plot(kind="bar", ax=ax, rot=45, secondary_y=True,
color="grey", alpha=0.3, grid=True)
ax.set(ylabel=y)
ax.right_ax.set_ylabel("Observazions in each bin")
plt.show()**### scatter plot**
sns.jointplot(x=x, y=y, data=dtf, dropna=True, kind='reg',
height=int((figsize[0]+figsize[1])/2) )
plt.show()
GrLivArea 是预测性的,有一个清晰的模式:平均来说,房子越大,价格越高,即使有一些超出平均水平的异常值和相对较低的价格。
就像之前一样,我们可以测试这两个变量之间的相关性。既然都是数值,我就 t est 皮尔逊相关系数 :假设两个变量是独立的(零假设),检验两个样本是否有线性关系。如果 p 值足够小(< 0.05),可以拒绝零假设,我们可以说这两个变量可能是相关的。
**x, y = "GrLivArea", "Y"**dtf_noNan = dtf[dtf[x].notnull()]
coeff, p = scipy.stats.**pearsonr**(dtf_noNan[x], dtf_noNan[y])
coeff, p = round(coeff, 3), round(p, 3)
conclusion = "Significant" if p < 0.05 else "Non-Significant"
print("Pearson Correlation:", coeff, conclusion, "(p-value: "+str(p)+")")
FullBath 和 GrLivArea 是预测特性的例子,因此我将保留它们用于建模。
应该对数据集中的每个变量进行这种分析,以决定哪些应该作为潜在特征保留,哪些因为不具有预测性而可以放弃(查看完整代码的链接)。
特征工程
是时候使用领域知识从原始数据创建新要素了。我将提供一个例子: MSSubClass 列(building 类)包含 15 个类别,这是一个很大的数目,在建模过程中会导致维度问题。让我们看看:
sns.**catplot**(x="MSSubClass", y="Y", data=dtf, kind="box")
有许多类别,很难理解每个类别中的分布情况。因此,我将把这些类别分组为簇:具有较高 Y 值的类(如 MSSubClass 60 和 120 )将进入“最大”簇,价格较低的类(如 MSSubClass 30、45、180 )将进入“最小”簇,其余的将进入“平均”簇。
**## define clusters**
MSSubClass_clusters = {"**min**":[30,45,180], "**max**":[60,120], "**mean**":[]}**## create new columns**
dic_flat = {v:k for k,lst in MSSubClass_clusters.items() for v in lst}
for k,v in MSSubClass_clusters.items():
if len(v)==0:
residual_class = k
dtf[x+"_cluster"] = dtf[x].apply(lambda x: dic_flat[x] if x in
dic_flat.keys() else residual_class)**## print**
dtf[["MSSubClass","MSSubClass_cluster","Y"]].head()
这样,我将类别的数量从 15 个减少到 3 个,这样更便于分析:
新的分类特性更易于阅读,并且保持了原始数据中显示的模式,因此我将保留 MSSubClass_cluster 而不是列 MSSubClass 。
预处理
数据预处理是准备原始数据以使其适合机器学习模型的阶段。特别是:
- 每个观察必须用一行来表示,换句话说,不能用两行来描述同一个乘客,因为它们将被模型分别处理(数据集已经是这样的形式,所以✅).而且每一列都应该是一个特征,所以你不应该用 Id 作为预测器,这就是为什么这种表叫做“特征矩阵”。
- 数据集必须分割成至少两个集合:模型应该在你的数据集的一个重要部分上训练(所谓的“训练集”),在一个较小的集合上测试(“测试集”)。
- 缺少的值应该用东西替换,否则,你的模型可能会出问题。
- 分类数据必须编码,这意味着将标签转换为整数,因为机器学习期望的是数字,而不是字符串。
- 对数据进行缩放是一种很好的做法,这有助于在特定范围内对数据进行标准化,并加快算法中的计算速度。
好的,让我们从划分数据集开始。当把数据分成训练集和测试集时,你必须遵循一个基本规则:训练集中的行不应该出现在测试集中。这是因为模型在训练过程中会看到目标值,并使用它来理解现象。换句话说,模型已经知道训练观察的正确答案,在这些基础上测试就像作弊。
**## split data**
dtf_train, dtf_test = **model_selection**.**train_test_split**(dtf,
test_size=0.3)**## print info**
print("X_train shape:", dtf_train.drop("Y",axis=1).shape, "| X_test shape:", dtf_test.drop("Y",axis=1).shape)
print("y_train mean:", round(np.mean(dtf_train["Y"]),2), "| y_test mean:", round(np.mean(dtf_test["Y"]),2))
print(dtf_train.shape[1], "features:", dtf_train.drop("Y",axis=1).columns.to_list())
下一步: LotFrontage 列包含一些需要处理的缺失数据 (17%)。从机器学习的角度来看,首先分成训练和测试,然后用训练集的平均值替换 NAs 是正确的。
dtf_train["*LotFrontage*"] = dtf_train["*LotFrontage*"].**fillna**(dtf_train["*LotFrontage*"].**mean**())
我创建的新列 MSSubClass_cluster 包含应该被编码的分类数据。我将使用 One-Hot-Encoding 方法,将 1 个具有 n 个唯一值的分类列转换为 n-1 个虚拟列。
**## create dummy**
dummy = pd.**get_dummies**(dtf_train["*MSSubClass_cluster*"],
prefix="*MSSubClass_cluster*",drop_first=True)
dtf_train= pd.concat([dtf_train, dummy], axis=1)
print( dtf_train.filter(like="*MSSubClass_cluster*",axis=1).head() )**## drop the original categorical column**
dtf_train = dtf_train.drop("*MSSubClass_cluster*", axis=1)
最后但同样重要的是,我将缩放特征。对于回归问题,通常需要转换输入变量和目标变量。我将使用鲁棒定标器,它通过减去中值然后除以四分位数范围(75%值-25%值)来转换特征。这个定标器的优点是它受异常值的影响较小。
**## scale X**
scalerX = preprocessing.**RobustScaler**(quantile_range=(25.0, 75.0))
X = scaler.fit_transform(dtf_train.drop("Y", axis=1))dtf_scaled= pd.DataFrame(X, columns=dtf_train.drop("Y",
axis=1).columns, index=dtf_train.index)**## scale Y** scalerY = preprocessing.**RobustScaler**(quantile_range=(25.0, 75.0))
dtf_scaled[y] = scalerY.fit_transform(
dtf_train[y].values.reshape(-1,1))dtf_scaled.head()
特征选择
特征选择是选择相关变量的子集来构建机器学习模型的过程。它使模型更容易解释,并减少过度拟合(当模型适应训练数据过多,并且在训练集之外表现不佳时)。
在数据分析期间,我已经通过排除不相关的列进行了第一次“手动”特征选择。现在会有一点不同,因为我们必须处理多重共线性问题,这是指多元回归模型中两个或更多解释变量高度线性相关的情况。
我用一个例子来解释: GarageCars 与 GarageArea 高度相关,因为它们给出的信息都是一样的(车库有多大,一个是根据能停多少车,另一个是根据平方英尺)。让我们计算相关矩阵来看看:
corr_matrix = dtf_train.**corr**(method="pearson")
sns.heatmap(corr_matrix, vmin=-1., vmax=1., annot=True, fmt='.2f', cmap="YlGnBu", cbar=True, linewidths=0.5)
plt.title("pearson correlation")
GarageCars 和 GarageArea 中的一个可能是不必要的,我们可以决定丢弃它并保留最有用的一个(即具有最低 p 值的那个或最能降低熵的那个)。
线性回归 是一种对标量响应和一个或多个解释变量之间的关系进行建模的线性方法。单变量线性回归测试广泛用于测试许多回归变量中每一个的个体效应:首先,计算每个回归变量和目标之间的相关性,然后进行 ANOVA F-测试。
岭正则化 对于缓解线性回归中的多重共线性问题特别有用,这种问题通常出现在具有大量参数的模型中。
X = dtf_train.drop("Y", axis=1).values
y = dtf_train["Y"].values
feature_names = dtf_train.drop("Y", axis=1).columns**## p-value**
selector = **feature_selection.SelectKBest**(score_func=
feature_selection.f_regression, k=10).fit(X,y)
pvalue_selected_features = feature_names[selector.get_support()]
**## regularization**
selector = **feature_selection.SelectFromModel**(estimator=
linear_model.Ridge(alpha=1.0, fit_intercept=True),
max_features=10).fit(X,y)
regularization_selected_features = feature_names[selector.get_support()]
**## plot** dtf_features = pd.DataFrame({"features":feature_names})
dtf_features["p_value"] = dtf_features["features"].apply(lambda x: "p_value" if x in pvalue_selected_features else "")
dtf_features["num1"] = dtf_features["features"].apply(lambda x: 1 if x in pvalue_selected_features else 0)
dtf_features["regularization"] = dtf_features["features"].apply(lambda x: "regularization" if x in regularization_selected_features else "")
dtf_features["num2"] = dtf_features["features"].apply(lambda x: 1 if x in regularization_selected_features else 0)
dtf_features["method"] = dtf_features[["p_value","regularization"]].apply(lambda x: (x[0]+" "+x[1]).strip(), axis=1)
dtf_features["selection"] = dtf_features["num1"] + dtf_features["num2"]
dtf_features["method"] = dtf_features["method"].apply(lambda x: "both" if len(x.split()) == 2 else x)sns.barplot(y="features", x="selection", hue="method", data=dtf_features.sort_values("selection", ascending=False), dodge=False)
蓝色的特征是由方差分析和岭选择的,其他的是由第一种统计方法选择的。
或者,您可以使用集成方法来获得特征重要性。 集成方法 使用多种学习算法来获得比单独使用任何一种成分学习算法所能获得的更好的预测性能。我将给出一个使用 梯度推进 算法的例子:它以向前逐级的方式建立一个加性模型,并在每个阶段在给定损失函数的负梯度上拟合一个回归树。
X = dtf_train.drop("Y", axis=1).values
y = dtf_train["Y"].values
feature_names = dtf_train.drop("Y", axis=1).columns.tolist()**## call model**
model = ensemble.**GradientBoostingRegressor**()**## Importance**
model.fit(X,y)
importances = model.**feature_importances_****## Put in a pandas dtf**
dtf_importances = pd.DataFrame({"IMPORTANCE":importances,
"VARIABLE":feature_names}).sort_values("IMPORTANCE",
ascending=False)
dtf_importances['cumsum'] =
dtf_importances['IMPORTANCE'].cumsum(axis=0)
dtf_importances = dtf_importances.set_index("VARIABLE")
**##** **Plot**
fig, ax = plt.subplots(nrows=1, ncols=2, sharex=False, sharey=False)
fig.suptitle("Features Importance", fontsize=20)
ax[0].title.set_text('variables')
dtf_importances[["IMPORTANCE"]].sort_values(by="IMPORTANCE").plot(
kind="barh", legend=False, ax=ax[0]).grid(axis="x")
ax[0].set(ylabel="")
ax[1].title.set_text('cumulative')
dtf_importances[["cumsum"]].plot(kind="line", linewidth=4,
legend=False, ax=ax[1])
ax[1].set(xlabel="", xticks=np.arange(len(dtf_importances)),
xticklabels=dtf_importances.index)
plt.xticks(rotation=70)
plt.grid(axis='both')
plt.show()
非常有趣的是, OverallQual、GrLivArea 和 TotalBsmtSf 在所有呈现的方法中占主导地位。
就我个人而言,我总是试图使用尽可能少的功能,因此在这里我选择以下功能,并继续设计、训练、测试和评估机器学习模型:
X_names = ['OverallQual', 'GrLivArea', 'TotalBsmtSF', "GarageCars"]X_train = dtf_train[X_names].values
y_train = dtf_train["Y"].valuesX_test = dtf_test[X_names].values
y_test = dtf_test["Y"].values
请注意,在使用测试数据进行预测之前,您必须对其进行预处理,就像我们对训练数据所做的那样。
模型设计
最后,是时候建立机器学习模型了。我将首先运行一个简单的线性回归,并将其用作更复杂模型的基线,如梯度推进算法。
我通常使用的第一个指标是 R 的平方 ,它表示自变量中可预测的因变量方差的比例。
我将使用 k 倍交叉验证来比较线性回归 R 的平方与梯度推进的平方,这是一个将数据分成 k 次训练和验证集的过程,对于每次分割,模型都被训练和测试。它用于检查模型通过一些数据进行训练的能力,以及预测未知数据的能力。
我将通过绘制预测值与实际值 Y 来可视化验证的结果。理想情况下,所有的点都应接近预测值=实际值的对角线。
**## call model**
model = linear_model.**LinearRegression**()**## K fold validation**
scores = []
cv = model_selection.KFold(n_splits=5, shuffle=True)
fig = plt.figure()
i = 1
for train, test in cv.split(X_train, y_train):
prediction = model.fit(X_train[train],
y_train[train]).predict(X_train[test])
true = y_train[test]
score = metrics.r2_score(true, prediction)
scores.append(score)
plt.scatter(prediction, true, lw=2, alpha=0.3,
label='Fold %d (R2 = %0.2f)' % (i,score))
i = i+1
plt.plot([min(y_train),max(y_train)], [min(y_train),max(y_train)],
linestyle='--', lw=2, color='black')
plt.xlabel('Predicted')
plt.ylabel('True')
plt.title('K-Fold Validation')
plt.legend()
plt.show()
线性回归的平均 R 平方为 0.77。让我们看看梯度推进验证是如何进行的:
梯度推进模型表现出更好的性能(平均 R 平方为 0.83),因此我将使用它来预测测试数据:
**## train**
model.**fit**(X_train, y_train)**## test**
predicted = model.**predict**(X_test)
请记住,数据是经过缩放的,因此为了将预测值与测试集中的实际房价进行比较,它们必须是未经缩放的(使用逆变换函数):
predicted = scalerY.**inverse_transform**(
predicted.reshape(-1,1) ).reshape(-1)
估价
关键时刻到了,我们要看看所有这些努力是否值得。重点是研究模型能解释多少 Y 的方差,以及误差是如何分布的。
我将使用以下常用度量来评估该模型:R 平方、平均绝对误差(MAE) 和均方根误差(RMSD) 。后两个是表达同一现象的成对观察值之间的误差度量。由于误差可能是正的(实际>预测)也可能是负的(实际<预测),您可以测量每个误差的绝对值和平方值。
**## Kpi**
print("R2 (explained variance):", round(metrics.r2_score(y_test, predicted), 2))
print("Mean Absolute Perc Error (Σ(|y-pred|/y)/n):", round(np.mean(np.abs((y_test-predicted)/predicted)), 2))
print("Mean Absolute Error (Σ|y-pred|/n):", "{:,.0f}".format(metrics.mean_absolute_error(y_test, predicted)))
print("Root Mean Squared Error (sqrt(Σ(y-pred)^2/n)):", "{:,.0f}".format(np.sqrt(metrics.mean_squared_error(y_test, predicted))))**## residuals** residuals = y_test - predicted
max_error = max(residuals) if abs(max(residuals)) > abs(min(residuals)) else min(residuals)
max_idx = list(residuals).index(max(residuals)) if abs(max(residuals)) > abs(min(residuals)) else list(residuals).index(min(residuals))
max_true, max_pred = y_test[max_idx], predicted[max_idx]
print("Max Error:", "{:,.0f}".format(max_error))
该模型解释了目标变量 86%的方差。平均而言,预测误差为 2 万美元,或者说误差为 11%。测试集上的最大误差超过 17 万美元。我们可以通过绘制预测值与实际值和每个预测值的残差(误差)来可视化误差。
**## Plot predicted vs true**
fig, ax = plt.subplots(nrows=1, ncols=2)
from statsmodels.graphics.api import abline_plot
ax[0].scatter(predicted, y_test, color="black")
abline_plot(intercept=0, slope=1, color="red", ax=ax[0])
ax[0].vlines(x=max_pred, ymin=max_true, ymax=max_true-max_error, color='red', linestyle='--', alpha=0.7, label="max error")
ax[0].grid(True)
ax[0].set(xlabel="Predicted", ylabel="True", title="Predicted vs True")
ax[0].legend()
**## Plot predicted vs residuals**
ax[1].scatter(predicted, residuals, color="red")
ax[1].vlines(x=max_pred, ymin=0, ymax=max_error, color='black', linestyle='--', alpha=0.7, label="max error")
ax[1].grid(True)
ax[1].set(xlabel="Predicted", ylabel="Residuals", title="Predicted vs Residuals")
ax[1].hlines(y=0, xmin=np.min(predicted), xmax=np.max(predicted))
ax[1].legend()
plt.show()
这就是-170k 的最大误差:模型预测的误差约为 320k,而实际观测值约为 150k。似乎大多数误差位于 50k 和-50k 之间,让我们更好地看看残差的分布,看看它是否近似正态:
fig, ax = plt.subplots()
sns.distplot(residuals, color="red", hist=True, kde=True, kde_kws={"shade":True}, ax=ax)
ax.grid(True)
ax.set(yticks=[], yticklabels=[], title="Residuals distribution")
plt.show()
可解释性
你分析并理解了数据,你训练了一个模型并测试了它,你甚至对性能感到满意。你可以多走一步,证明你的机器学习模型不是一个黑盒。
这个石灰包可以帮助我们建造一个讲解器。为了举例说明,我将从测试集中随机观察,看看模型预测了什么:
print("True:", "{:,.0f}".format(y_test[1]), "--> Pred:", "{:,.0f}".format(predicted[1]))
该模型预测这栋房子的价格为 194,870 美元。为什么?让我们使用解释器:
explainer = lime_tabular.LimeTabularExplainer(training_data=X_train, feature_names=X_names, class_names="Y", mode="regression")
explained = explainer.explain_instance(X_test[1], model.predict, num_features=10)
explained.as_pyplot_figure()
这个特殊预测的主要因素是房子有一个大的地下室(TotalBsmft > 1.3k),它是用高质量的材料建造的(总体质量> 6),而且是最近建造的(建造年份> 2001)。
预测值与实际值的对比图是显示测试进行情况的一个很好的工具,但是我也绘制了回归平面来直观地帮助观察模型没有正确预测的异常值。由于线性模型效果更好,我将使用线性回归来拟合二维数据。为了绘制二维数据,需要进行一定程度的降维(通过获得一组主要变量来减少特征数量的过程)。我将给出一个例子,使用 PCA 算法将数据总结为两个变量,这些变量是通过特征的线性组合获得的。
**## PCA**
pca = decomposition.PCA(n_components=2)
X_train_2d = pca.fit_transform(X_train)
X_test_2d = pca.transform(X_test)**## train 2d model**
model_2d = linear_model.LinearRegression()
model_2d.fit(X_train, y_train)**## plot regression plane**
from mpl_toolkits.mplot3d import Axes3D
ax = Axes3D(plt.figure())
ax.scatter(X_test[:,0], X_test[:,1], y_test, color="black")
X1 = np.array([[X_test.min(), X_test.min()], [X_test.max(),
X_test.max()]])
X2 = np.array([[X_test.min(), X_test.max()], [X_test.min(),
X_test.max()]])
Y = model_2d.predict(np.array([[X_test.min(), X_test.min(),
X_test.max(), X_test.max()],
[X_test.min(), X_test.max(), X_test.min(),
X_test.max()]]).T).reshape((2,2))
Y = scalerY.inverse_transform(Y)
ax.plot_surface(X1, X2, Y, alpha=0.5)
ax.set(zlabel="Y", title="Regression plane", xticklabels=[],
yticklabels=[])
plt.show()
结论
这篇文章是一个教程,展示了如何用数据科学处理回归用例。我以房价数据集为例,经历了从数据分析到机器学习模型的每个步骤。
在探索部分,我分析了单个分类变量、单个数值变量的情况,以及它们如何相互作用。我举了一个从原始数据中提取特征的特征工程的例子。关于预处理,我解释了如何处理缺失值和分类数据。我展示了选择正确特性的不同方法,如何使用它们来构建回归模型,以及如何评估性能。在最后一节,我就如何提高你的机器学习模型的可解释性给出了一些建议。
一个重要的注意事项是,我还没有介绍在您的模型被批准部署之后会发生什么。请记住,您需要构建一个管道来自动处理您将定期获得的新数据。
现在,您已经知道如何处理数据科学用例,您可以将这些代码和方法应用于任何类型的回归问题,执行您自己的分析,构建您自己的模型,甚至解释它。
我希望你喜欢它!如有问题和反馈,或者只是分享您感兴趣的项目,请随时联系我。
👉我们来连线👈
本文是用 Python 进行机器学习系列的一部分,参见:
[## 用 Python 进行机器学习:分类(完整教程)
数据分析和可视化、特征工程和选择、模型设计和测试、评估和解释
towardsdatascience.com](/machine-learning-with-python-classification-complete-tutorial-d2c99dc524ec) [## 聚类地理空间数据
使用交互式地图绘制机器学习和深度学习聚类
towardsdatascience.com](/clustering-geospatial-data-f0584f0b04ec) [## Python 深度学习:神经网络(完整教程)
用 TensorFlow 建立、绘制和解释人工神经网络
towardsdatascience.com](/deep-learning-with-python-neural-networks-complete-tutorial-6b53c0b06af0) [## 基于神经网络的现代推荐系统
使用 Python 和 TensorFlow 构建混合模型
towardsdatascience.com](/modern-recommendation-systems-with-neural-networks-3cc06a6ded2c)
带 R 的机器学习:线性回归
原文:https://towardsdatascience.com/machine-learning-with-r-linear-regression-558fa2edaaf0?source=collection_archive---------10-----------------------
机器学习基础和 r .和一堆其他的东西。
我决定用 R 开始关于机器学习的整个系列。不,这并不意味着我要退出 Python (但愿不会如此),但我最近一直在探索 R ,它并没有我最初想象的那么糟糕。所以,让我们从基础开始——线性回归。
照片由内森·安德森在 Unsplash 上拍摄
如果你想知道我对编程语言的最初印象,这里有几周前的一篇文章:
[## 我第一次尝试 R——有多糟糕?
空前的 Pythonista 尝试 R——包括与 Python 的比较。
towardsdatascience.com](/ive-tried-r-for-the-first-time-how-bad-was-it-ba344f22e90b)
这应该是一个有趣的系列。我打算涵盖所有主要的机器学习算法,将“奇怪”的部分与其 Python 替代方案进行比较,并在这个过程中学习很多东西。
这篇文章的结构如下:
- 线性回归简介
- 数据集介绍和加载
- 基础 EDA
- 模型训练和评估
- 结论
如果你更喜欢视频,我可以帮你搞定:
还有,你可以在这里获得源代码。
我们有很多东西要讲,所以让我们马上开始吧!
线性回归简介
我会抓住机会说,这可能不是你第一次接触线性回归。这是不应该的,因为这篇文章不会在理论上做太多的深入。不过,我们将从算法的高级概述开始。
线性回归是最初在统计领域开发的简单算法。它被作为理解输入和输出变量之间关系的模型来研究。顾名思义,它是一个线性模型,所以它假设输入变量和单个(连续)输出变量之间是线性关系。
该输出变量被计算为输入变量的线性组合。
存在两种主要类型的线性回归:
- 简单线性回归 —当我们只有一个输入变量时
- 多元线性回归 —当有多个输入变量时
训练线性回归模型实质上是为每个输入变量添加一个系数,该系数决定了输入变量的重要性。然后将输入变量的值乘以相应的系数,并将偏差(截距)项添加到总和中。这基本上是我们的预测值。
厉害!线性回归有一些假设,我们作为数据科学家必须意识到它们:
- 线性假设 —模型假设变量之间的关系是线性的
- 无噪声 —模型假设输入和输出变量没有噪声——因此如果可能的话移除异常值
- 无共线性-当输入变量高度相关时,模型会过度拟合
- 正态分布-如果输入和输出变量呈正态分布,模型将做出更可靠的预测。如果不是这样,试着对你的变量进行一些变换,使它们看起来更正常
- 重定标输入 —使用定标器或规格化器进行更可靠的预测
这就是高级概述。现在让我们继续好东西。
数据集介绍和加载
我们将使用鱼市场数据集来构建我们的模型。是的,我也是第一次用,所以你不是一个人。下载数据集并将其存储在友好的位置。
现在我们可以从进口开始:
library(dplyr)
library(ggplot2)
library(caTools)
library(corrgram)
简而言之——dplyr
用于数据操作,ggplot2
用于可视化,caTools
用于训练/测试分割,corrgram
用于制作简洁的相关矩阵图。
我们现在可以读入数据集,并检查前几行看起来如何:
df <- read.csv('data/Fish.csv')
head(df)
厉害!一切似乎都很好,所以我们可以继续进行基本的探索性数据分析。
基础 EDA
我们需要做的第一件事是检查丢失的值。这个过程和使用 Python 一样简单:
any(is.na(df))
执行这段代码会在控制台中产生一个大写的 FALSE ,表示没有丢失值——因此我们可以继续进行分析。
接下来让我们做几个可视化。没什么复杂的,只是感受一下我们的数据集的行为。第一个可视化是鱼的重量与高度的散点图,用鱼的种类来着色。下面的代码片段实现了这个目的:
ggplot(data=df, aes(x=Weight, y=Height)) +
geom_point(aes(color=Species, size=10, alpha=0.7))
仅仅从颜色上,我们可以看到鱼的种类被很好的分开了(在大多数情况下)。接下来,让我们检查属性之间的相关性。在这里,corrgram 库就派上了用场。代码如下:
corrgram(df, lower.panel=panel.shade, upper.panel=panel.cor)
情节是这样的:
几乎所有属性之间的相关性都高得惊人。但是我们不会做任何事情,因为本文的目的是讨论线性回归,而不是探索性的数据分析。
请记住——这最有可能导致模型过度拟合,但稍后会有更多相关内容。
EDA 部分到此结束,我们可以继续实际建模。
模型训练和评估
这将是迄今为止最长的部分,所以给自己一杯咖啡。我们将从培训/测试拆分开始。我们希望将数据集分成两部分,一部分(较大)用于训练模型,另一部分(较小)用于模型评估。
在我们做任何事情之前,让我们设置一个随机种子。训练/测试分割是一个随机过程,seed 确保随机化在您和我的计算机上的效果相同:
set.seed(42)
太好了!让我们现在进行分割。70%的数据用于训练,剩下的 30%用于测试。代码如下:
sampleSplit <- sample.split(Y=df$Weight, SplitRatio=0.7)
trainSet <- subset(x=df, sampleSplit==TRUE)
testSet <- subset(x=df, sampleSplit==FALSE)
执行代码后,您应该会在右上面板中看到另外两个变量:
因此,我们总共有 159 行,其中 111 行分配给模型训练,其余 48 行用于测试模型。
我们现在可以进行模型训练了。
R 对线性回归模型使用以下语法:
model <- lm(target ~ var_1 + var_2 + ... + var_n, data=train_set)
没关系,但是想象一下我们有 100 个预测值,那么把每一个都写到等式里将是一场噩梦。相反,我们可以使用以下语法:
model <- lm(target ~. , data=train_set)
请记住,这只有在您决定使用所有预测器进行模型训练时才有效。相应地,我们可以这样训练模型:
model <- lm(formula=Weight ~ ., data=trainSet)
简而言之,我们试图将权重属性预测为所有其他属性的线性组合。r 也自动处理分类属性。接招吧,蟒蛇!
接下来,我们可以看看我们模型的总结:
summary(model)
这里最有趣的是 P 值,显示在Pr(>|t|)
列中。这些值显示变量对预测不重要的概率。通常使用 5%的显著性阈值,因此如果 P 值为 0.05 或更低,我们可以说它对分析不显著的可能性很低。抱歉否定,假设就是这么形成的。
厉害!接下来,我们可以制作一个残差图,或者更精确的残差直方图。这里我们期望看到近似正态分布的东西。让我们看看直方图是什么样子的:
modelResiduals <- as.data.frame(residuals(model)) ggplot(modelResiduals, aes(residuals(model))) +
geom_histogram(fill='deepskyblue', color='black')
嗯,由于最右边的值有一点偏斜,但目测之后,我们可以得出结论,残差近似正态分布。
现在我们终于可以预测了!这样做很容易:
preds <- predict(model, testSet)
现在我们可以评估。首先,我们将创建一个实际值和预测值的数据框架:
modelEval <- cbind(testSet$Weight, preds)
colnames(modelEval) <- c('Actual', 'Predicted')
modelEval <- as.data.frame(modelEval)
下面是前几行的样子:
这不是最好的模型——至少在没有任何调整的情况下不是,但我们仍然得到了不错的结果。多体面?这就是像 MSE 和 RMSE 这样的指标会告诉我们的。以下是计算结果:
mse <- mean((modelEval$Actual - modelEval$Predicted)²)
rmse <- sqrt(mse)
我们得到的 RMSE 值是 95.9,MSE 是它的平方。这意味着我们平均错了 95.9 个重量单位。我会让你来决定这是好是坏。
在我看来,由于输入变量之间的相关系数较大,该模型过度拟合了训练数据。此外,列车组的判定值系数(R2)高得惊人(0.93+)。
这就足够了。让我们在下一部分总结一下。
在你走之前
我希望这篇文章很容易理解。我们讨论了最简单的机器学习算法,并略微涉及了探索性数据分析。我知道对于一篇文章来说有很多东西需要消化,但是这个主题并不难。
我们接下来将讨论逻辑回归,大约在 3-4 天内,如果你对此感兴趣,请继续关注。
感谢阅读。
加入我的私人邮件列表,获取更多有用的见解。
喜欢这篇文章吗?成为 中等会员 继续无限制学习。如果你使用下面的链接,我会收到你的一部分会员费,不需要你额外付费。
[## 通过我的推荐链接加入 Medium-Dario rade ci
作为一个媒体会员,你的会员费的一部分会给你阅读的作家,你可以完全接触到每一个故事…
medium.com](https://medium.com/@radecicdario/membership)
原载于 2020 年 9 月 25 日 https://betterdatascience.com。
带 R 的机器学习:逻辑回归
原文:https://towardsdatascience.com/machine-learning-with-r-logistic-regression-152ec20351db?source=collection_archive---------19-----------------------
包括 R 代码中的分类基础知识
我们和 R 的机器学习小旅程还在继续!今天的主题是逻辑回归——作为机器学习分类任务的介绍。我们将涵盖众所周知的泰坦尼克号数据集的数据准备、建模和评估。
照片由阿伦·范德波尔在 Unsplash 拍摄
如果您想从头开始阅读本系列,这里有以前文章的链接:
- 带 R 的机器学习:线性回归
这篇文章的结构如下:
- 逻辑回归简介
- 数据集介绍和加载
- 数据准备
- 模型训练和评估
- 结论
你可以在这里下载源代码。简介部分到此结束,我们有许多内容要讲,所以让我们直接进入正题。
逻辑回归简介
逻辑回归是从统计学领域借用的二元分类(两个类值)的一个很好的介绍性算法。该算法得名于其底层机制——逻辑函数(有时称为 sigmoid 函数)。
逻辑函数是在统计中开发的 S 形函数,它接受任何实数值并将其映射到 0 到 1 之间的值。这正是我们进行二元分类所需要的,因为我们可以将阈值设置为 0.5,并根据逻辑函数的输出进行预测。
下面是逻辑函数的样子:
如果你感兴趣,下面是逻辑函数的方程式。记住——它接受任何实数值,并将其转换为 0 到 1 之间的值。
这对于理论来说已经足够了。我重复一遍——这篇文章的目的不是覆盖理论,因为有太多的理论文章/书籍。是纯动手的作品。
数据集介绍和加载
好了,现在我们对逻辑回归有了基本的了解,我们可以从编码部分开始了。如前所述,我们将使用泰坦尼克号数据集。你不必下载它,因为 R 已经为我们下载了。
下面是库导入和数据集加载的代码片段:
library(dplyr)
library(stringr)
library(caTools)
library(caret) df <- read.csv('https://raw.githubusercontent.com/datasciencedojo/datasets/master/titanic.csv')
下面是前几行的样子:
厉害!数据集需要做一些准备才能转换成 ml 格式,所以这是我们接下来要做的。
数据准备
我们必须做几件重要的事情:
- 从名称属性中提取标题
- 照常/不寻常地重新映射提取的标题
- 将小屋属性转换为二进制 HasCabin
- 删除不必要的属性
这个来自 Kaggle 的片段对标题提取和重新映射有很大帮助,只需稍加修改。其他要点相对简单,如下面的代码片段所示:
maleNobleTitles <- c('Capt', 'Col', 'Don', 'Dr', 'Jonkheer', 'Major', 'Rev', 'Sir')
femaleNobleTitles <- c('Lady', 'Mlle', 'Mme', 'Ms', 'the Countess') df$Title <- str_sub(df$Name, str_locate(df$Name, ',')[ , 1] + 2, str_locate(df$Name, '\\.')[ , 1] - 1)
df$Title[df$Title %in% maleNobleTitles] <- 'MaleNoble'
df$Title[df$Title %in% femaleNobleTitles] <- 'FemaleNoble'
df$HasCabin <- ifelse(df$Cabin == '', 0, 1)
df <- df %>% select(-PassengerId, -Name, -Ticket, -Cabin)
我们实际上为贵族头衔创建了两个数组,一个用于男性,一个用于女性,将头衔提取到 title 列,并用表达式“MaleNoble”和“FemaleNoble”替换贵族头衔。
此外,ifelse 函数帮助创建了HasCabin
属性,如果 Cabin 的值不为空,则该属性的值为 1,否则为 0。最后,我们只保留了与分析相关的特性。
以下是数据集现在的样子:
厉害!接下来我们来处理缺失值。
处理缺失数据
下面一行代码打印出每个属性有多少个缺失值:
lapply(df, function(x) { length(which(is.na(x))) })
属性Age
是唯一包含缺失值的属性。由于本文涵盖了机器学习而不是数据准备,我们将用一个简单的平均值来进行插补。以下是片段:
df$Age <- ifelse(is.na(df$Age), mean(df$Age, na.rm=TRUE), df$Age)
这就是归罪。只剩下一件事要做了,准备工作。
因子转换
我们的数据集中有许多分类属性。r 提供了一个简单的factor()
函数,将分类属性转换成算法可以理解的格式。
以下是我们的数据集在转换前的结构:
下面是执行转换的代码片段:
df$Survived <- factor(df$Survived)
df$Pclass <- factor(df$Pclass)
df$Sex <- factor(df$Sex)
df$SibSp <- factor(df$SibSp)
df$Parch <- factor(df$Parch)
df$Embarked <- factor(df$Embarked)
df$Title <- factor(df$Title)
df$HasCabin <- factor(df$HasCabin)
数据准备部分已经完成,现在我们可以继续建模了。
模型训练和评估
在实际的模型训练之前,我们需要在训练和测试子集上分割数据集。这样做可以确保我们有一个数据子集来评估,并且知道模型有多好。代码如下:
set.seed(42) sampleSplit <- sample.split(Y=df$Survived, SplitRatio=0.7)
trainSet <- subset(x=df, sampleSplit==TRUE)
testSet <- subset(x=df, sampleSplit==FALSE)
上面的代码将原始数据集分成 70:30 的子集。我们将对大多数(70%)进行训练,对其余的进行评估。
我们现在可以用函数来训练模型。我们将使用所有的属性,用点表示,列是目标变量。
model <- glm(Survived ~ ., family=binomial(link='logit'), data=trainSet)
就这样——我们成功地训练了这个模型。让我们通过调用它的summary()
函数来看看它是如何执行的:
summary(model)
这里最令人兴奋的是 P 值,显示在 Pr( > |t|) 列中。这些值表示变量对预测不重要的概率。通常使用 5%的显著性阈值,因此如果 P 值为 0.05 或更低,我们可以说它对分析不显著的可能性很低。
我们可以看到,最重要的属性/属性子集是Pclass3
、、、、、、、、、、、SibSp4
、、、、和HasCabin1
。
我们现在对我们的模型有了更多的信息——我们知道决定一名乘客是否在泰坦尼克号事故中幸存的最重要的因素。现在,我们可以继续评估以前未见过的数据—测试集。
我们故意保持这个子集不变,只是为了模型评估。首先,我们需要计算预测概率和基于这些概率的预测类别。我们将设定 0.5 作为阈值——如果生还的机会小于 0.5,我们就说乘客没有在事故中幸存。代码如下:
probabs <- predict(model, testSet, type='response')
preds <- ifelse(probabs > 0.5, 1, 0)
现在很容易在此基础上进行构建。分类任务的主要方法是建立一个混淆矩阵——一个 2×2 矩阵,显示第一个和第四个元素的正确分类,以及第二个和第三个元素的错误分类(从左到右、从上到下阅读)。下面是如何通过代码获得它:
confusionMatrix(factor(preds), factor(testSet$Survived))
因此,总的来说,我们的模型在大约 84%的测试案例中是正确的——对于几分钟的工作来说还不错。让我们在下一部分总结一下。
在你走之前
到目前为止,我们已经介绍了最基本的回归和分类机器学习算法。我知道这是一个相当乏味的过程,但却是为后面更复杂的算法和优化奠定基础所必需的。
KNN 系列的下一篇文章将在几天后发表,敬请关注。
感谢阅读。
加入我的私人邮件列表,获取更多有用的见解。
喜欢这篇文章吗?成为 中等会员 继续无限制学习。如果你使用下面的链接,我会收到你的一部分会员费,不需要你额外付费。
[## 通过我的推荐链接加入 Medium-Dario rade ci
作为一个媒体会员,你的会员费的一部分会给你阅读的作家,你可以完全接触到每一个故事…
medium.com](https://medium.com/@radecicdario/membership)
原载于 2020 年 10 月 4 日 https://betterdatascience.com。
使用 Spark 的机器学习
原文:https://towardsdatascience.com/machine-learning-with-spark-f1dbc1363986?source=collection_archive---------20-----------------------
综合指南
分布式机器学习框架
这是一个关于使用 Spark 分布式机器学习框架构建可扩展 ML 数据管道的综合教程。我将介绍在 Spark MLlib 库中实现的基本机器学习算法,通过本教程,我将在 python 环境中使用 PySpark。
作者使用 Canva.com 的图片
在几乎每个商业领域,机器学习在解决现实世界的问题方面越来越受欢迎。它有助于解决使用数据的问题,这些数据通常是非结构化的、有噪声的和巨大的。随着数据大小和各种数据源的增加,使用标准技术解决机器学习问题带来了巨大的挑战。Spark 是一个分布式处理引擎,使用 MapReduce 框架来解决与大数据及其处理相关的问题。
Spark framework 有自己的机器学习模块,名为 MLlib。在本文中,我将使用 pyspark 和 spark MLlib 来演示使用分布式处理的机器学习。读者将能够通过真实的例子学习下面的概念。
- 在谷歌联合实验室中建立火花
- 机器学习的基本概念
- 使用 Spark 进行预处理和数据转换
- 使用 pySpark 进行 spark 聚类
- pyspark 分类
- pyspark 回归方法
将提供一个工作的 google colab 笔记本来重现结果。
由于本文是一个实践教程,在一个会话中涵盖了使用 pyspark 进行转换、分类、聚类和回归,因此本文的长度比我以前的文章要长。一个好处是您可以一口气完成基本概念和实现。
什么是阿帕奇火花?
据阿帕奇星火和三角洲引擎盖下的湖泊
Apache Spark 是一个统一的计算引擎和一组用于在计算机集群上进行并行数据处理的库。截至本文撰写之时,Spark 是针对这一任务开发的最活跃的开源引擎;使其成为任何对大数据感兴趣的开发人员或数据科学家的实际工具。Spark 支持多种广泛使用的编程语言(Python、Java、Scala 和 R),包括从 SQL 到流和机器学习等各种任务的库,可以在从笔记本电脑到数千个服务器集群的任何地方运行。这使它成为一个易于启动和扩展到大数据处理或超大规模的系统。
作者图片
在 Google 联合实验室中设置 Spark 3.0.1
作为第一步,我用 spark 安装配置 google colab 运行时。详细内容,读者可以在 Google Colab om medium 阅读我的文章入门 Spark 3.0.0。
我们将安装以下程序
- Java 8
- 火花-3.0.1
- Hadoop3.2
- Findspark
您可以使用下面的命令集安装最新版本的 Spark。
# Run below commands
!apt-get install openjdk-8-jdk-headless -qq > /dev/null
!wget -q http://apache.osuosl.org/spark/spark-3.0.1/spark-3.0.1-bin-hadoop3.2.tgz
!tar xf spark-3.0.1-bin-hadoop3.2.tgz
!pip install -q findspark
环境变量
安装完 spark 和 Java 之后,设置安装 Spark 和 Java 的环境变量。
import os
os.environ["JAVA_HOME"] = "/usr/lib/jvm/java-8-openjdk-amd64"
os.environ["SPARK_HOME"] = "/content/spark-3.0.1-bin-hadoop3.2"
火花安装试验
让我们在 google colab 环境中测试 spark 的安装。
import findspark
findspark.init()
from pyspark.sql import SparkSession
spark = SparkSession.builder.master("local[*]").getOrCreate()
# Test the spark
df = spark.createDataFrame([{"hello": "world"} for x in range(1000)])
df.show(3, False)/content/spark-3.0.1-bin-hadoop3.2/python/pyspark/sql/session.py:381: UserWarning: inferring schema from dict is deprecated,please use pyspark.sql.Row instead
warnings.warn("inferring schema from dict is deprecated,"
+-----+
|hello|
+-----+
|world|
|world|
|world|
+-----+
only showing top 3 rows# make sure the version of pyspark
import pyspark
print(pyspark.__version__)3.0.1
机器学习
一旦我们在 google colab 中设置了 spark,并确保它运行的是正确的版本,即 3.0.1。在这种情况下,我们可以开始探索基于 Spark 开发的机器学习 API。PySpark 是一个更高级的 Python API,可以将 Spark 与 Python 结合使用。对于本教程,我假设读者对机器学习和用于模型构建和训练的 SK-Learn 有基本的了解。Spark MLlib 使用了与 SK-Learn 中相同的拟合和预测结构。
为了重现结果,我已经把数据上传到我的 GitHub 上,可以方便地访问。
边做边学:使用 colab 笔记本自己运行它
Spark 中的数据准备和转换
本节涵盖将输入要素数据转换为机器学习算法接受的格式所涉及的基本步骤。我们将讨论 SparkML 库带来的转换。要了解或阅读更多关于 3.0.3 中可用的 spark 转换,请点击下面的链接。
[## 提取、转换和选择特征
本节介绍处理要素的算法,大致分为以下几组:提取:提取…
spark.apache.org](https://spark.apache.org/docs/3.0.1/ml-features.html)
规范化数字数据
MinMaxScaler 是大多数机器学习库中最受欢迎的类之一。它在 0 和 1 之间缩放数据。
from pyspark.ml.feature import MinMaxScaler
from pyspark.ml.linalg import Vectors# Create some dummy feature data
features_df = spark.createDataFrame([
(1, Vectors.dense([10.0,10000.0,1.0]),),
(2, Vectors.dense([20.0,30000.0,2.0]),),
(3, Vectors.dense([30.0,40000.0,3.0]),),
],["id", "features"] )features_df.show()+---+------------------+
| id| features|
+---+------------------+
| 1|[10.0,10000.0,1.0]|
| 2|[20.0,30000.0,2.0]|
| 3|[30.0,40000.0,3.0]|
+---+------------------+# Apply MinMaxScaler transformation
features_scaler = MinMaxScaler(inputCol = "features", outputCol = "sfeatures")
smodel = features_scaler.fit(features_df)
sfeatures_df = smodel.transform(features_df)sfeatures_df.show()+---+------------------+--------------------+
| id| features| sfeatures|
+---+------------------+--------------------+
| 1|[10.0,10000.0,1.0]| (3,[],[])|
| 2|[20.0,30000.0,2.0]|[0.5,0.6666666666...|
| 3|[30.0,40000.0,3.0]| [1.0,1.0,1.0]|
+---+------------------+--------------------+
标准化数字数据
StandardScaler 是另一个著名的用机器学习库编写的类。它将-1 和 1 之间的数据标准化,并将数据转换为钟形数据。你可以贬低数据和规模的一些差异。
from pyspark.ml.feature import StandardScaler
from pyspark.ml.linalg import Vectors# Create the dummy data
features_df = spark.createDataFrame([
(1, Vectors.dense([10.0,10000.0,1.0]),),
(2, Vectors.dense([20.0,30000.0,2.0]),),
(3, Vectors.dense([30.0,40000.0,3.0]),),
],["id", "features"] )# Apply the StandardScaler model
features_stand_scaler = StandardScaler(inputCol = "features", outputCol = "sfeatures", withStd=True, withMean=True)
stmodel = features_stand_scaler.fit(features_df)
stand_sfeatures_df = stmodel.transform(features_df)stand_sfeatures_df.show()+---+------------------+--------------------+
| id| features| sfeatures|
+---+------------------+--------------------+
| 1|[10.0,10000.0,1.0]|[-1.0,-1.09108945...|
| 2|[20.0,30000.0,2.0]|[0.0,0.2182178902...|
| 3|[30.0,40000.0,3.0]|[1.0,0.8728715609...|
+---+------------------+--------------------+
存储数字数据
真实的数据集具有不同的范围,有时在插入机器学习算法之前,最好将数据转换为定义明确的桶。
Bucketizer 类可以方便地将数据转换成不同的存储桶。
from pyspark.ml.feature import Bucketizer
from pyspark.ml.linalg import Vectors# Define the splits for buckets
splits = [-float("inf"), -10, 0.0, 10, float("inf")]
b_data = [(-800.0,), (-10.5,), (-1.7,), (0.0,), (8.2,), (90.1,)]
b_df = spark.createDataFrame(b_data, ["features"])b_df.show()+--------+
|features|
+--------+
| -800.0|
| -10.5|
| -1.7|
| 0.0|
| 8.2|
| 90.1|
+--------+# Transforming data into buckets
bucketizer = Bucketizer(splits=splits, inputCol= "features", outputCol="bfeatures")
bucketed_df = bucketizer.transform(b_df)bucketed_df.show()+--------+---------+
|features|bfeatures|
+--------+---------+
| -800.0| 0.0|
| -10.5| 0.0|
| -1.7| 1.0|
| 0.0| 2.0|
| 8.2| 2.0|
| 90.1| 3.0|
+--------+---------+
标记文本数据
自然语言处理是机器学习的主要应用之一。自然语言处理的第一步是将文本标记成单词或标记。我们可以利用 SparkML 中的 Tokenizer 类来执行这项任务。
from pyspark.ml.feature import Tokenizersentences_df = spark.createDataFrame([
(1, "This is an introduction to sparkMlib"),
(2, "Mlib incluse libraries fro classfication and regression"),
(3, "It also incluses support for data piple lines"),
], ["id", "sentences"])sentences_df.show()+---+--------------------+
| id| sentences|
+---+--------------------+
| 1|This is an introd...|
| 2|Mlib incluse libr...|
| 3|It also incluses ...|
+---+--------------------+sent_token = Tokenizer(inputCol = "sentences", outputCol = "words")
sent_tokenized_df = sent_token.transform(sentences_df)sent_tokenized_df.take(10)[Row(id=1, sentences='This is an introduction to sparkMlib', words=['this', 'is', 'an', 'introduction', 'to', 'sparkmlib']),
Row(id=2, sentences='Mlib incluse libraries fro classfication and regression', words=['mlib', 'incluse', 'libraries', 'fro', 'classfication', 'and', 'regression']),
Row(id=3, sentences='It also incluses support for data piple lines', words=['it', 'also', 'incluses', 'support', 'for', 'data', 'piple', 'lines'])]
TF-IDF
词频-逆文档频率(TF-IDF)是一种广泛应用于文本挖掘的特征矢量化方法,用于反映语料库中某个词对文档的重要性。使用上面标记化的数据,让我们应用 TF-IDF
from pyspark.ml.feature import HashingTF, IDFhashingTF = HashingTF(inputCol = "words", outputCol = "rawfeatures", numFeatures = 20)
sent_fhTF_df = hashingTF.transform(sent_tokenized_df)sent_fhTF_df.take(1)[Row(id=1, sentences='This is an introduction to sparkMlib', words=['this', 'is', 'an', 'introduction', 'to', 'sparkmlib'], rawfeatures=SparseVector(20, {6: 2.0, 8: 1.0, 9: 1.0, 10: 1.0, 13: 1.0}))]idf = IDF(inputCol = "rawfeatures", outputCol = "idffeatures")
idfModel = idf.fit(sent_fhTF_df)
tfidf_df = idfModel.transform(sent_fhTF_df)tfidf_df.take(1)[Row(id=1, sentences='This is an introduction to sparkMlib', words=['this', 'is', 'an', 'introduction', 'to', 'sparkmlib'], rawfeatures=SparseVector(20, {6: 2.0, 8: 1.0, 9: 1.0, 10: 1.0, 13: 1.0}), idffeatures=SparseVector(20, {6: 0.5754, 8: 0.6931, 9: 0.0, 10: 0.6931, 13: 0.2877}))]
用户可以根据手头问题的要求进行各种变换。
使用 PySpark 进行聚类
聚类是一种机器学习技术,其中使用输入特征将数据分组到合理数量的类中。在本节中,我们将使用 spark ML 框架研究集群技术的基本应用。
from pyspark.ml.linalg import Vectors
from pyspark.ml.feature import VectorAssembler
from pyspark.ml.clustering import KMeans, BisectingKMeans
import glob# Downloading the clustering dataset
!wget -q 'https://raw.githubusercontent.com/amjadraza/blogs-data/master/spark_ml/clustering_dataset.csv'
使用 spark 加载以 csv 格式存储的聚类数据
# Read the data.
clustering_file_name ='clustering_dataset.csv'
import pandas as pd
# df = pd.read_csv(clustering_file_name)
cluster_df = spark.read.csv(clustering_file_name, header=True,inferSchema=True)
使用VectorAssembler
将表格数据转换成矢量化格式
# Coverting the input data into features column
vectorAssembler = VectorAssembler(inputCols = ['col1', 'col2', 'col3'], outputCol = "features")
vcluster_df = vectorAssembler.transform(cluster_df)vcluster_df.show(10)+----+----+----+--------------+
|col1|col2|col3| features|
+----+----+----+--------------+
| 7| 4| 1| [7.0,4.0,1.0]|
| 7| 7| 9| [7.0,7.0,9.0]|
| 7| 9| 6| [7.0,9.0,6.0]|
| 1| 6| 5| [1.0,6.0,5.0]|
| 6| 7| 7| [6.0,7.0,7.0]|
| 7| 9| 4| [7.0,9.0,4.0]|
| 7| 10| 6|[7.0,10.0,6.0]|
| 7| 8| 2| [7.0,8.0,2.0]|
| 8| 3| 8| [8.0,3.0,8.0]|
| 4| 10| 5|[4.0,10.0,5.0]|
+----+----+----+--------------+
only showing top 10 rows
一旦数据被准备成 MLlib 可以用于模型的格式,现在我们可以定义和训练聚类算法,例如 K-Means。我们可以定义集群的数量并初始化种子,如下所示。
# Applying the k-means algorithm
kmeans = KMeans().setK(3)
kmeans = kmeans.setSeed(1)
kmodel = kmeans.fit(vcluster_df)
培训结束后,让我们打印中心。
centers = kmodel.clusterCenters()
print("The location of centers: {}".format(centers))The location of centers: [array([35.88461538, 31.46153846, 34.42307692]), array([80\. , 79.20833333, 78.29166667]), array([5.12, 5.84, 4.84])]
MLlib 中实现了各种聚类算法。对分 K-均值聚类是另一种流行的方法。
# Applying Hierarchical Clustering
bkmeans = BisectingKMeans().setK(3)
bkmeans = bkmeans.setSeed(1)bkmodel = bkmeans.fit(vcluster_df)
bkcneters = bkmodel.clusterCenters()bkcneters[array([5.12, 5.84, 4.84]),
array([35.88461538, 31.46153846, 34.42307692]),
array([80\. , 79.20833333, 78.29166667])]
要阅读更多关于在 MLlib 中实现的集群方法,请点击下面的链接。
[## 使聚集
本页描述 MLlib 中的群集演算法。基于 RDD 的 API 中的集群指南也有相关的…
spark.apache.org](https://spark.apache.org/docs/3.0.1/ml-clustering.html)
使用 PySpark 分类
分类是广泛使用的机器算法之一,几乎每个数据工程师和数据科学家都必须了解这些算法。一旦加载并准备好数据,我将演示三种分类算法。
- 朴素贝叶斯分类
- 多层感知器分类
- 决策树分类
我们使用虹膜数据探索监督分类算法。我已经把数据上传到我的 GitHub 来重现结果。用户可以使用下面的命令下载数据。
# Downloading the clustering data
!wget -q "https://raw.githubusercontent.com/amjadraza/blogs-data/master/spark_ml/iris.csv"df = pd.read_csv("https://raw.githubusercontent.com/amjadraza/blogs-data/master/spark_ml/iris.csv", header=None)df.head()
spark.createDataFrame(df, columns)DataFrame[c_0: double, c_1: double, c_2: double, c_3: double, c4 : string]
预处理虹膜数据
在本节中,我们将使用 IRIS 数据来理解分类。为了执行 ML 模型,我们对输入数据应用预处理步骤。
from pyspark.sql.functions import *
from pyspark.ml.feature import VectorAssembler
from pyspark.ml.feature import StringIndexer# Read the iris data
df_iris = pd.read_csv("https://raw.githubusercontent.com/amjadraza/blogs-data/master/spark_ml/iris.csv", header=None)
iris_df = spark.createDataFrame(df_iris)iris_df.show(5, False)+------------+-----------+------------+-----------+-----------+
|sepal_length|sepal_width|petal_length|petal_width|species |
+------------+-----------+------------+-----------+-----------+
|5.1 |3.5 |1.4 |0.2 |Iris-setosa|
|4.9 |3.0 |1.4 |0.2 |Iris-setosa|
|4.7 |3.2 |1.3 |0.2 |Iris-setosa|
|4.6 |3.1 |1.5 |0.2 |Iris-setosa|
|5.0 |3.6 |1.4 |0.2 |Iris-setosa|
+------------+-----------+------------+-----------+-----------+
only showing top 5 rows# Rename the columns
iris_df = iris_df.select(col("0").alias("sepal_length"),
col("1").alias("sepal_width"),
col("2").alias("petal_length"),
col("3").alias("petal_width"),
col("4").alias("species"),
)# Converting the columns into features
vectorAssembler = VectorAssembler(inputCols = ["sepal_length", "sepal_width", "petal_length", "petal_width"],
outputCol = "features")
viris_df = vectorAssembler.transform(iris_df)viris_df.show(5, False)+------------+-----------+------------+-----------+-----------+-----------------+
|sepal_length|sepal_width|petal_length|petal_width|species |features |
+------------+-----------+------------+-----------+-----------+-----------------+
|5.1 |3.5 |1.4 |0.2 |Iris-setosa|[5.1,3.5,1.4,0.2]|
|4.9 |3.0 |1.4 |0.2 |Iris-setosa|[4.9,3.0,1.4,0.2]|
|4.7 |3.2 |1.3 |0.2 |Iris-setosa|[4.7,3.2,1.3,0.2]|
|4.6 |3.1 |1.5 |0.2 |Iris-setosa|[4.6,3.1,1.5,0.2]|
|5.0 |3.6 |1.4 |0.2 |Iris-setosa|[5.0,3.6,1.4,0.2]|
+------------+-----------+------------+-----------+-----------+-----------------+
only showing top 5 rowsindexer = StringIndexer(inputCol="species", outputCol = "label")
iviris_df = indexer.fit(viris_df).transform(viris_df)iviris_df.show(2, False)+------------+-----------+------------+-----------+-----------+-----------------+-----+
|sepal_length|sepal_width|petal_length|petal_width|species |features |label|
+------------+-----------+------------+-----------+-----------+-----------------+-----+
|5.1 |3.5 |1.4 |0.2 |Iris-setosa|[5.1,3.5,1.4,0.2]|0.0 |
|4.9 |3.0 |1.4 |0.2 |Iris-setosa|[4.9,3.0,1.4,0.2]|0.0 |
+------------+-----------+------------+-----------+-----------+-----------------+-----+
only showing top 2 rows
朴素贝叶斯分类
一旦数据准备好了,我们就可以应用第一个分类算法了。
from pyspark.ml.classification import NaiveBayes
from pyspark.ml.evaluation import MulticlassClassificationEvaluator# Create the traing and test splits
splits = iviris_df.randomSplit([0.6,0.4], 1)
train_df = splits[0]
test_df = splits[1]# Apply the Naive bayes classifier
nb = NaiveBayes(modelType="multinomial")
nbmodel = nb.fit(train_df)
predictions_df = nbmodel.transform(test_df)predictions_df.show(1, False)+------------+-----------+------------+-----------+-----------+-----------------+-----+------------------------------------------------------------+------------------------------------------------------------+----------+
|sepal_length|sepal_width|petal_length|petal_width|species |features |label|rawPrediction |probability |prediction|
+------------+-----------+------------+-----------+-----------+-----------------+-----+------------------------------------------------------------+------------------------------------------------------------+----------+
|4.3 |3.0 |1.1 |0.1 |Iris-setosa|[4.3,3.0,1.1,0.1]|0.0 |[-9.966434726497221,-11.294595492758821,-11.956012812323921]|[0.7134106367667451,0.18902823898426235,0.09756112424899269]|0.0 |
+------------+-----------+------------+-----------+-----------+-----------------+-----+------------------------------------------------------------+------------------------------------------------------------+----------+
only showing top 1 row
让我们评估训练好的分类器
evaluator = MulticlassClassificationEvaluator(labelCol="label", predictionCol="prediction", metricName="accuracy")
nbaccuracy = evaluator.evaluate(predictions_df)
nbaccuracy0.8275862068965517
多层感知器分类
我们将研究的第二个分类器是一个多层感知器。在本教程中,我不打算详细介绍这个问题的最优 MLP 网络,但是在实践中,你可以研究适合手头问题的最优网络。
from pyspark.ml.classification import MultilayerPerceptronClassifier# Define the MLP Classifier
layers = [4,5,5,3]
mlp = MultilayerPerceptronClassifier(layers = layers, seed=1)
mlp_model = mlp.fit(train_df)
mlp_predictions = mlp_model.transform(test_df)# Evaluate the MLP classifier
mlp_evaluator = MulticlassClassificationEvaluator(labelCol="label", predictionCol="prediction", metricName="accuracy")
mlp_accuracy = mlp_evaluator.evaluate(mlp_predictions)
mlp_accuracy0.9827586206896551
决策树分类
ML 家族中另一个常见的分类器是决策树分类器,在本节中,我们将探讨这个分类器。
from pyspark.ml.classification import DecisionTreeClassifier# Define the DT Classifier
dt = DecisionTreeClassifier(labelCol="label", featuresCol="features")
dt_model = dt.fit(train_df)
dt_predictions = dt_model.transform(test_df)# Evaluate the DT Classifier
dt_evaluator = MulticlassClassificationEvaluator(labelCol="label", predictionCol="prediction", metricName="accuracy")
dt_accuracy = dt_evaluator.evaluate(dt_predictions)
dt_accuracy0.9827586206896551
除了上面三个演示的分类算法,Spark MLlib 还有许多其他分类算法的实现。实现的分类算法的细节可以在下面的链接中找到
[## 分类和回归
\newcommand
spark.apache.org](https://spark.apache.org/docs/3.0.1/ml-classification-regression.html#classification)
强烈建议尝试一些分类算法,以便动手操作。
使用 PySpark 进行回归
在本节中,我们将使用 pyspark 探索回归问题的机器学习模型。回归模型有助于使用过去的数据预测未来的值。
我们将使用联合循环发电厂数据集来预测每小时净电力输出(EP)。我已经把数据上传到我的 GitHub 上,这样用户就可以重现结果了。
from pyspark.ml.regression import LinearRegression
from pyspark.ml.feature import VectorAssembler# Read the iris data
df_ccpp = pd.read_csv("https://raw.githubusercontent.com/amjadraza/blogs-data/master/spark_ml/ccpp.csv")
pp_df = spark.createDataFrame(df_ccpp)pp_df.show(2, False)+-----+-----+-------+-----+------+
|AT |V |AP |RH |PE |
+-----+-----+-------+-----+------+
|14.96|41.76|1024.07|73.17|463.26|
|25.18|62.96|1020.04|59.08|444.37|
+-----+-----+-------+-----+------+
only showing top 2 rows# Create the feature column using VectorAssembler class
vectorAssembler = VectorAssembler(inputCols =["AT", "V", "AP", "RH"], outputCol = "features")
vpp_df = vectorAssembler.transform(pp_df)vpp_df.show(2, False)+-----+-----+-------+-----+------+---------------------------+
|AT |V |AP |RH |PE |features |
+-----+-----+-------+-----+------+---------------------------+
|14.96|41.76|1024.07|73.17|463.26|[14.96,41.76,1024.07,73.17]|
|25.18|62.96|1020.04|59.08|444.37|[25.18,62.96,1020.04,59.08]|
+-----+-----+-------+-----+------+---------------------------+
only showing top 2 rows
线性回归
我们从最简单的回归技术开始,即线性回归。
# Define and fit Linear Regression
lr = LinearRegression(featuresCol="features", labelCol="PE")
lr_model = lr.fit(vpp_df)# Print and save the Model output
lr_model.coefficients
lr_model.intercept
lr_model.summary.rootMeanSquaredError4.557126016749486#lr_model.save()
决策树回归
在本节中,我们将探讨机器学习中常用的决策树回归。
from pyspark.ml.regression import DecisionTreeRegressor
from pyspark.ml.evaluation import RegressionEvaluatorvpp_df.show(2, False)+-----+-----+-------+-----+------+---------------------------+
|AT |V |AP |RH |PE |features |
+-----+-----+-------+-----+------+---------------------------+
|14.96|41.76|1024.07|73.17|463.26|[14.96,41.76,1024.07,73.17]|
|25.18|62.96|1020.04|59.08|444.37|[25.18,62.96,1020.04,59.08]|
+-----+-----+-------+-----+------+---------------------------+
only showing top 2 rows# Define train and test data split
splits = vpp_df.randomSplit([0.7,0.3])
train_df = splits[0]
test_df = splits[1]# Define the Decision Tree Model
dt = DecisionTreeRegressor(featuresCol="features", labelCol="PE")
dt_model = dt.fit(train_df)
dt_predictions = dt_model.transform(test_df)dt_predictions.show(1, False)+----+-----+-------+-----+------+--------------------------+-----------------+
|AT |V |AP |RH |PE |features |prediction |
+----+-----+-------+-----+------+--------------------------+-----------------+
|3.31|39.42|1024.05|84.31|487.19|[3.31,39.42,1024.05,84.31]|486.1117703349283|
+----+-----+-------+-----+------+--------------------------+-----------------+
only showing top 1 row# Evaluate the Model
dt_evaluator = RegressionEvaluator(labelCol="PE", predictionCol="prediction", metricName="rmse")
dt_rmse = dt_evaluator.evaluate(dt_predictions)
print("The RMSE of Decision Tree regression Model is {}".format(dt_rmse))The RMSE of Decision Tree regression Model is 4.451790078736588
梯度推进决策树回归
梯度推进是 ML 专业人士的另一个普遍选择。让我们在本节中尝试一下 GBM。
from pyspark.ml.regression import GBTRegressor# Define the GBT Model
gbt = GBTRegressor(featuresCol="features", labelCol="PE")
gbt_model = gbt.fit(train_df)
gbt_predictions = gbt_model.transform(test_df)# Evaluate the GBT Model
gbt_evaluator = RegressionEvaluator(labelCol="PE", predictionCol="prediction", metricName="rmse")
gbt_rmse = gbt_evaluator.evaluate(gbt_predictions)
print("The RMSE of GBT Tree regression Model is {}".format(gbt_rmse))The RMSE of GBT Tree regression Model is 4.035802933864555
除了上面演示的回归算法,Spark MLlib 还有许多其他回归算法的实现。实现回归算法的细节可以在下面的链接中找到。
[## 分类和回归
\newcommand
spark.apache.org](https://spark.apache.org/docs/3.0.1/ml-classification-regression.html#regression)
强烈建议您尝试一些回归算法,亲自动手操作并使用这些参数。
一个有效的 Google Colab
结论
在本教程中,我试图让读者有机会学习和使用 PySpark 实现基本的机器学习算法。Spark 不仅提供了分布式处理的好处,还可以处理大量的待处理数据。总之,我们已经讨论了以下主题/算法
- 在 Google Colab 中设置 Spark 3.0.1
- 使用 PySpark 进行数据转换概述
- 使用 PySpark 的聚类算法
- 使用 PySpark 的分类问题
- 使用 PySpark 的回归问题
参考资料/阅读/链接
- https://spark.apache.org/docs/latest/ml-features.html
- https://spark . Apache . org/docs/3 . 0 . 1/ml-class ification-regression . html # regression
- https://spark.apache.org/docs/3.0.1/ml-clustering.html
- https://spark . Apache . org/docs/3 . 0 . 1/ml-class ification-regression . html # class ification
SQL 机器学习——回归完全指南
原文:https://towardsdatascience.com/machine-learning-with-sql-a-complete-guide-to-regression-b0e5e2db22da?source=collection_archive---------37-----------------------
数据库内机器学习?这比你想象的要容易
似乎每个人都知道如何用像 Python 、 R 和 Julia 这样的语言来训练预测模型。但是 SQL 呢?如何利用一种众所周知的数据库语言来进行机器学习?
托拜厄斯·凯勒在 Unsplash 上拍摄的照片
不想看书?看看我关于这个主题的视频:
SQL 已经存在了几十年,但仍然没有被认为是机器学习的语言。当然,我会在一周的任何一天选择 Python,但有时数据库中的机器学习是唯一的选择。
在本文中,我们将使用 Oracle 云。这是免费的,所以请注册并创建一个 OLTP 数据库实例(版本 19c,有 0.2TB 的存储)。一旦完成,通过SQL Developer Web或任何其他工具建立连接。
我们将使用一个著名的房价数据集的稍加修改的版本——你可以在这里下载。我选择了这个数据集,因为它不需要任何广泛的准备,所以重点可以立即转移到预测建模。
这篇文章的结构如下:
- 数据集加载和准备
- 模型设置
- 模型训练和评估
- 结论
数据集加载和准备
如果你正在跟随,我希望你已经下载了数据集。你需要用自己选择的工具将它加载到数据库中——我使用的是 Oracle Cloud 提供的免费工具 SQL Developer Web 。
加载过程很简单——点击上传按钮,选择 CSV 文件,然后点击几次下一个:
图 1 —使用 Oracle SQL Developer Web 加载数据集(图片由作者提供)
我的现在存储在housingprices
表中。下面是前几行的样子:
图片 2-加载的数据集的前 10 行(作者提供的图片)
甲骨文机器学习 (OML)在创建模型方面有点奇怪。您的数据表必须包含具有 ID 的列,ID 是从序列中生成的数字。默认情况下,我们的数据集没有这个,所以让我们手动添加它:
图 3 —添加了一列行 ID(按作者分类的图像)
这一部分只剩下一件事要做:训练/测试分割。在 SQL 中,这是通过创建两个视图来完成的。第一个视图随机抽取了 75%的数据,第二个视图抽取了剩余的 25%。百分比是任意选择的:
我们现在已经创建了两个视图——housing_train_data
用于训练,housing_test_data
用于测试。在模型训练之前还有一件事要做:为模型指定设置。让我们在下一节做这件事。
模型设置
Oracle 使用这种设置表样式来训练预测模型。设置表由两列组成,一列用于名称,另一列用于值。
下面是创建表格的方法:
以下信息将存储在该表中:
- 模型类型—让我们使用一个广义线性模型 (GLM)
- 诊断表名称-用于模型统计
- 数据准备技术——让我们用自动的
- 功能选择—禁用或启用,让我们选择启用
- 特征生成-与特征选择相同
是的,你没看错——所有这些都是自动完成的,不需要你的帮助。接下来让我们填写设置表:
这是表格的样子:
图 4-模型设置表(作者图片)
就是这样!我们继续模特训练吧。
模型训练和验证
模型训练归结为单个过程调用。代码如下:
如您所见,您需要首先命名您的模型。GLMR_Regression_Housing
这个名字完全是随意取的。大约一秒钟后,模型被训练。不要害怕 Oracle 创建的表的数量。这些是模型正常工作所必需的。
接下来,我们来看一下火车布景上的模特表演。它可以通过以下查询获得:
图 5-列车组的模型性能(图片由作者提供)
平均来说,这个模型有 7.2 个单位的价格是错误的,它捕捉了超过 70%的方差。
接下来让我们看看最重要的特性。如果该特征的 P 值接近 0(小于 0.05 即可),则可将其归类为对预测有意义。以下是查询:
图片 6 —特征重要性(作者图片)
如您所见,这些要素最初并不存在于数据集中,而是由 Oracle 的要素生成器自动创建的。
最后,让我们将这个模型应用于测试集:
结果存储在housing_test_predictions
表中:
图 7 —测试集上的预测(图片由作者提供)
不知道科学记数法是怎么回事,但它足够好,可以进一步评估。我将把它留给你,因为你只需要在housing_test_data
视图和housing_test_predictions
表之间创建一个UNION
来看看结果有多好。
离别赠言
机器学习不再是 Python 或 R 特有的东西。对于数据科学家来说,采用 SQL 不是最直观的,文档也很糟糕,但数据库内 ML 为业务用户提供了一种接触预测建模的极好方式。
不要错过 ML with SQL 系列的其他内容:
- 使用 SQL 的机器学习(分类)
- 用 SQL 进行时间序列预测
欢迎在下面的评论区留下你的想法。
加入我的私人邮件列表,获取更多有用的见解。
喜欢这篇文章吗?成为 中等会员 继续无限制学习。如果你使用下面的链接,我会收到你的一部分会员费,不需要你额外付费。
[## 通过我的推荐链接加入 Medium-Dario rade ci
作为一个媒体会员,你的会员费的一部分会给你阅读的作家,你可以完全接触到每一个故事…
medium.com](https://medium.com/@radecicdario/membership)
原载于 2020 年 11 月 10 日 https://betterdatascience.com**。
使用 SQL 进行机器学习——比你想象的要简单
原文:https://towardsdatascience.com/machine-learning-with-sql-its-easier-than-you-think-c6aae9064d5a?source=collection_archive---------6-----------------------
当 Python 不是一个选项时该做什么。包括代码。
如果你一直在学习数据科学,很可能你知道如何用像 Python 、 R 和 Julia 这样的语言来执行机器学习任务。但是,当速度是关键,硬件有限,或者您工作的公司将 SQL 作为预测分析的唯一选择时,您能做些什么呢?数据库中的机器学习是答案。
照片由王浩在 Unsplash 上拍摄
在本文中,我们将使用 Oracle 云。这是免费的,所以请注册并创建一个 OLTP 数据库实例(版本 19c,有 0.2TB 的存储)。完成后,下载云钱包并通过 SQL Developer 或任何其他工具建立连接。
这将花费你至少 10 分钟,但这是一件相当简单的事情,所以我不会在这上面浪费时间。
我们将使用甲骨文机器学习(OML) 在众所周知的虹膜数据集上训练一个分类模型。我选择它是因为它不需要任何准备—我们只需要创建表并插入数据。
让我们接下来做那件事。
数据准备
如前所述,我们需要创建一个表来保存 Iris 数据集,然后我们需要向其中加载数据。 OML 要求一列用作行 ID(序列),所以让我们记住这一点:
CREATE SEQUENCE seq_iris;
CREATE TABLE iris_data(
iris_id NUMBER DEFAULT seq_iris.NEXTVAL,
sepal_length NUMBER,
sepal_width NUMBER,
petal_length NUMBER,
petal_width NUMBER,
species VARCHAR2(16)
);
厉害!现在我们可以下载数据并加载它:
当弹出一个模态窗口时,只需提供下载 CSV 的路径,然后点击几次 Next 。没有你的帮助,SQL 开发人员应该可以把事情做好。
完成后,我们加载并准备好数据集:
现在让我们继续有趣的部分。
模特培训
现在我们可以接触有趣的东西,这就是训练分类模型。这被分解成多个步骤,例如训练/测试分割、模型训练和模型评估。先说最简单的。
训练/测试分割
Oracle 喜欢用两个视图来完成这个步骤——一个用于训练数据,一个用于测试数据。我们可以用一点 PL/SQL 魔法轻松地创建它们:
BEGIN
EXECUTE IMMEDIATE
‘CREATE OR REPLACE VIEW
iris_train_data AS
SELECT * FROM iris_data
SAMPLE (75) SEED (42)’;
EXECUTE IMMEDIATE
‘CREATE OR REPLACE VIEW
iris_test_data AS
SELECT * FROM iris_data
MINUS
SELECT * FROM iris_train_data’;
END;
/
这个脚本做两件事:
- 创建一个列车视图——以随机种子 42 (
SEED (42)
)分割 75%的数据(SAMPLE (75)
) - 创建一个测试视图——作为整个数据集和训练视图的差异
我们的数据存储在名为iris_train_data
和iris_test_data
的视图中——你可以猜猜哪个视图包含什么。
让我们快速检查一下每一行有多少行:
SELECT COUNT(*) FROM iris_train_data;
**>>> 111** SELECT COUNT(*) FROM iris_test_data;
**>>> 39**
我们已经准备好训练模型了,接下来让我们开始吧。
模特培训
模型训练最简单的方法是通过DBMS_DATA_MINING
包,只需执行一个程序,无需创建额外的设置表。
我们将使用决策树算法来训练我们的模型。方法如下:
DECLARE
v_setlst DBMS_DATA_MINING.SETTING_LIST;
BEGIN
v_setlst(‘PREP_AUTO’) := ‘ON’;
v_setlst(‘ALGO_NAME’) := ‘ALGO_DECISION_TREE’;
DBMS_DATA_MINING.CREATE_MODEL2(
‘iris_clf_model’,
‘CLASSIFICATION’,
‘SELECT * FROM iris_train_data’,
v_setlst,
‘iris_id’,
‘species’
);
END;
/
CREATE_MODEL2
过程(奇怪的是为什么它没有被命名为CREATE_MODEL_FINAL_FINAL89
)接受很多参数。让我们解释一下我们输入的:
iris_clf_model
—你的型号的简单名称。可以是任何东西CLASSIFICATION
—我们正在进行的机器学习任务的类型。出于某种原因必须大写SELECT * FROM iris_train_data
—指定存储训练数据的位置v_setlst
—以上为我们的模型声明的设置列表iris_id
—序列类型列的名称(每个值都是唯一的)species
—目标变量的名称(我们试图预测的)
执行这个代码块需要一两秒钟,但是一旦完成,就可以开始评估了!
模型评估
让我们使用这个脚本来评估我们的模型:
BEGIN
DBMS_DATA_MINING.APPLY(
‘iris_clf_model’,
‘iris_test_data’,
‘iris_id’,
‘iris_apply_result’
);
END;
/
它将iris_clf_model
应用于看不见的测试数据iris_test_data
,并将评估结果存储到iris_apply_result
表中。这张桌子看起来是这样的:
它有更多的行(39 x 3),但你得到了要点。这还不是最直观的,所以让我们以稍微不同的方式显示结果:
DECLARE
CURSOR iris_ids IS
SELECT DISTINCT(iris_id) iris_id
FROM iris_apply_result
ORDER BY iris_id;
curr_y VARCHAR2(16);
curr_yhat VARCHAR2(16);
num_correct INTEGER := 0;
num_total INTEGER := 0;
BEGIN
FOR r_id IN iris_ids LOOP
BEGIN
EXECUTE IMMEDIATE
‘SELECT species FROM
iris_test_data
WHERE iris_id = ‘ || r_id.iris_id
INTO curr_y;
EXECUTE IMMEDIATE
‘SELECT prediction
FROM iris_apply_result
WHERE iris_id = ‘ || r_id.iris_id ||
‘AND probability = (
SELECT MAX(probability)
FROM iris_apply_result
WHERE iris_id = ‘ || r_id.iris_id ||
‘)’ INTO curr_yhat;
END;
num_total := num_total + 1;
IF curr_y = curr_yhat THEN
num_correct := num_correct + 1;
END IF;
END LOOP;
DBMS_OUTPUT.PUT_LINE(‘Num. test cases: ‘
|| num_total);
DBMS_OUTPUT.PUT_LINE(‘Num. correct : ‘
|| num_correct);
DBMS_OUTPUT.PUT_LINE(‘Accuracy : ‘
|| ROUND((num_correct / num_total), 2));
END;
/
是的,很多,但是上面的脚本不能再简单了。让我们来分解一下:
CURSOR
—获取所有不同的 iris _ ids(因为我们在iris_apply_results
表中复制了它们curr_y
、curr_yhat
、num_correct
、num_total
是用于存储每次迭代中的实际物种和预测物种、正确分类数以及测试项目总数的变量- 对于每个独特的
iris_id
,我们得到实际物种(来自iris_test_data
,其中 id 匹配)和预测物种(其中预测概率在iris_apply_results
表中最高) - 然后很容易检查实际值和预测值是否相同,这表明分类是正确的
- 变量
num_total
和num_correct
在每次迭代中被更新 - 最后,我们将模型的性能打印到控制台
以下是该脚本的输出:
厉害!解释为:
- 测试集有 39 个案例
- 在这 39 个中,37 个被正确分类
- 这导致了 95%的准确率
这就是模型评估的基本内容。
在你走之前
现在你有了它——用 SQL 从头开始编写的机器学习项目。并不是所有人都有特权在工作中使用像 Python 这样的东西,如果一个机器学习任务出现在你的办公桌上,你现在知道如何通过 SQL 来解决它。
当然,这只是一个简单的分类任务,脚本还可以进一步改进,但是您已经明白了。我希望你已经设法跟上了。如有任何问题和意见,请参考评论部分。
感谢阅读。
加入我的私人邮件列表,获得更多有用的见解。
喜欢这篇文章吗?成为 中等会员 继续无限制学习。如果你使用下面的链接,我会收到你的一部分会员费,不需要你额外付费。
[## 通过我的推荐链接加入 Medium-Dario rade ci
作为一个媒体会员,你的会员费的一部分会给你阅读的作家,你可以完全接触到每一个故事…
medium.com](https://medium.com/@radecicdario/membership)
【https://betterdatascience.com】原载于 2020 年 9 月 6 日。
用泰坦尼克号数据集进行机器学习
原文:https://towardsdatascience.com/machine-learning-with-the-titanic-dataset-7f6909e58280?source=collection_archive---------4-----------------------
预测泰坦尼克号乘客生存的端到端指南
从我的观点来看,初学者的教程应该让读者继续自己的观点。为此,我想和大家分享一个著名的泰坦尼克号 Kaggle 比赛的教程。如果你这样做,你最终会得到一个合理的分数,但我也会展示一些你可以轻松提高分数的类别。在你读完之后,你可以拿着这个模型自己改进它。如果你对机器学习感兴趣,泰坦尼克号的戏剧性沉没是你自己数据科学之旅的一个很好的起点。祝你好运!
入门指南
如果你对 Kaggle 完全陌生,请查看的这个教程,了解设置过程。你会在这里找到数据集等等。
在 Kaggle 内核中加载文件之后:
哪些变量在我们的数据集中:
Kaggle 注意到:
pclass :社会经济地位(SES)的代表
1st =上层
2nd =中层
3rd =下层
sibsp :数据集以这种方式定义家庭关系……
兄弟姐妹=兄弟、姐妹、继兄弟、继姐妹
配偶=丈夫、妻子(情妇和未婚夫被忽略)
parch :数据集以这种方式定义家庭关系……
Parent =母亲,father
Child =女儿,儿子,继女,继子
有些孩子只和保姆一起旅行,因此 parch=0。
1.数据质量检查
第一步,我们将调查泰坦尼克号的数据集。Kaggle 提供了一个训练和一个测试数据集。训练数据集包含所有特征(可能的预测值)和目标(我们想要预测结果的变量)。测试数据集用于提交,因此缺少目标变量。让我们看一下数据集:
我在引言中已经写道,目标变量“幸存”在测试数据集中是缺失的。所有其他列都出现在两个数据图表中。总的来说,我们有 11 个不同的变量,可用作预测目标结果的特征。你一眼就能看出《小屋》有遗漏。遗漏会刺激我们的算法,因此在第一步中清理数据是重要的任务。
在训练数据中,我们在年龄、客舱和登机栏中有遗漏。在测试数据集中,年龄、费用和舱位列中有缺失。我们将连接两个数据集,并对整个数据集执行数据清理。
2.数据清理
2.1 年龄
我们的年龄栏有 20%的人失踪了。让我们来看看分布情况:
我们不想删除所有缺少年龄值的行,因此我们将替换缺少的行。正如你所看到的,我们有一个年龄的右螺旋分布,中位数应该是一个很好的替代选择。
一个论点是,乘客等级的年龄中位数不同。职业发展通常伴随着年龄和经验的增长。因此,社会经济地位较高的人平均年龄较大。如果我们按性别划分,我们会发现仍然存在差异,因为女性总体上更年轻。在最后一步中,我检查了案例的数量,以确保每个类别中仍有足够的案例。我们将使用这些中间值来代替缺失值。
2.2 票价
在整个数据集中,我们只有一个缺失的票价值。托马斯先生乘坐三等舱,独自旅行,在南汉普顿上船。我们将从这一类别的人群中选取其他案例,并用这一组的中间值替换缺失的票价。
2.3 客舱
有很多缺失值,但我们应该使用客舱变量,因为它可以是一个重要的预测值。正如你在下图中看到的,一等舱在甲板 A、B 或 C 上,混合舱在 D 或 E 上,三等舱主要在 f 或 g 上。我们可以通过第一个字母来识别甲板。
存活率有显著差异,因为上层甲板的游客在救生艇上速度更快。我们将把一些甲板集合起来。
2.4 已上船
登船的人只有两个失踪。由于我们已经尝试了 fare 案例,我们可以查找类似的案例来替换丢失的值。有理由认为,那些支付了类似金额,也有一等舱机票,在同一个甲板上,从同一个位置上船的人。我还在 Kaggle 论坛上看到,你可以谷歌个人乘客,所以我试了一下:
陈月娇小姐:https://www . encyclopedia-titanica . org/titanic-survivor/Amelia-icard . html
乔治·尼尔森夫人:https://www . encyclopedia-titanica . org/titanic-survivor/Martha-Evelyn-stone . html
关于链接的文章都在南汉普顿登船。数据科学也是关于研究的!
2.5 结论
我们已经填充了数据集中所有缺失的值,还没有删除任何一列。我们使用了年龄和票价的统计方法,为客舱创建了一个新的类别,并对船上的缺失做了一些研究。让我们再检查一下是否一切正常。
3.特征工程
特征工程是一门艺术,也是广阔的机器学习领域中最令人兴奋的事情之一。我真的很喜欢研究 Kaggle 子论坛,探索所有伟大的想法和创造性的方法。泰坦尼克号数据集提供了很多可能性来尝试不同的方法,并提高您的预测得分。我们将关注一些标准,我将详细解释每一步。
迄今为止我们将使用的技术:
-宁滨连续变量(例如年龄)
-从现有变量中创建新特征(例如标题)
-非数字特征(例如性别)的标签编码
-类别特征(例如 Pclass)的一个热编码
3.1 宁滨
如你所见,年龄和费用都有异常值。与年龄相比,票价的取值范围要高得多。我们将把分布切割成小块,这样离群值就不会影响我们的算法。对于票价,我们将为每个类别分配相同数量的案例,对于年龄,我们将根据变量的值建立类别。这也是 cut 和 qcut 的区别。使用 cut,不管有多少事例属于一个类别,都会根据变量的值来形成箱。使用 qcut,我们分解一个分布,以便在每个类别中有相同数量的案例。
平均而言,较年轻的乘客有更高的生存机会,票价较高的人也是如此。年轻人可能最先获救,票价较高的人最先登上救生艇。
3.2 从现有变量中创建新特征
3.2.1 家庭规模
在我们的数据集中有两个有趣的变量告诉我们一些关于家庭规模的事情。SibSp 定义了一个乘客有多少兄弟姐妹和配偶,以及多少父母和子女。我们可以将这些变量汇总,并(为每个路人)加 1,得到家庭规模。
一个论点是,家庭比单身有更高的生存机会,因为他们能够更好地养活自己,并优先得到救助。然而,如果家庭太大,在特殊情况下协调可能会非常困难。
门票
我们预计购票频率和存活率之间存在关联,因为相同的票号表明人们一起旅行过。
正如所料,每种机票频率的存活率有所不同。
标题
这个名字为我们提供了关于乘客社会经济地位的非常重要的信息。我们可以回答这个问题:某人是否结婚,或者某人是否有正式的头衔,这可能是更高社会地位的标志。
在我们的数据集中有很多不同的标题。我们只考虑超过 10 个案例的标题,所有其他的我们将分配到“杂项”类别。
3.2.4 存活率
这个 Kaggle 竞争允许我们使用来自测试数据集的信息。在这一点上,我们想指出的是,要获得高分,你必须对数据有创造性。这几乎就像一场黑客马拉松。在现实世界的任务中,你通常没有机会这样做。我们会识别乘客的姓氏。然后,我们可以查看是否有任何家庭成员同时出现在训练和测试数据集中。
拥有硕士学位的人和女性存活的几率要高得多,平均而言,他们同时拥有更大的家庭。我们假设,如果一个主人或女人在训练数据集中被标记为幸存者,测试数据集中的家庭成员也将幸存。
在有两个或更多家庭成员的妇女中,大多数情况下她们全部死亡或没有死亡。
这同样适用于头衔为 master 的乘客家属。
3.3 标签和一个热编码
大多数算法不能对字符串做任何事情,所以变量通常在建模前被重新编码。标签编码将非数字值映射到数字。例如,对于 sex,0 和 len(sex)-1,即 1。
这就引出了另一个问题。许多算法假设一个列中有一个逻辑序列。然而,这并不总是用数字比率来表示。因此,之后需要对变量进行一次热编码。然后,性别列变成了 Sex_1 和 Sex_2 两列,其中用二进制编码表示某人是男性还是女性。因此该算法通常可以更好地处理信息。
4.建模和预测
对于我们的第一个预测,我们选择一个随机福里斯特分类器。RFC 易于理解,是用于分类任务的成熟工具。
我们仍然定义建模时不需要考虑的列。例如,对于 apollowed,我们已经创建了虚拟列,所以我们可以删除原来的 apollowed 列。作为培训/测试划分,我们选择 75%和 25%。我们用训练数据集训练算法,然后用测试数据集测试预测能力。
RFC 括号中的标准不是强制性的,如果您忽略它们,将使用默认设置。给定的参数已经过优化,因此我们的分类器比默认参数工作得更好。
我们的预测分数几乎是 86%,这意味着我们在 86%的情况下正确预测了我们的目标,即存活率。这已经是一个很好的值,您现在可以进一步优化它。请在下面找到我们的随机福里斯特树的可视化。
5.结论
我们在一个小型数据科学项目中完成了整个旅程。我们探索了数据,清理了数据,然后我们修改了特征并创建了新的特征,最后一步我们用随机森林树分类器进行了预测。但是还有很多要做,接下来你可以测试以下几样:
-其他算法的表现更好吗?
-能不能根据年龄和票价更好的选择箱柜?
-票变量可以用得更合理吗?
-有没有可能进一步调整存活率?
-我们真的需要所有的功能吗,还是我们制造了干扰我们算法的不必要的噪音?
下面你可以找到一些很好的资源。
6.更多阅读材料和资源:
[## 泰坦尼克号数据科学解决方案
使用 Kaggle 笔记本探索和运行机器学习代码|使用《泰坦尼克号:灾难中的机器学习》中的数据
www.kaggle.com](https://www.kaggle.com/startupsci/titanic-data-science-solutions) [## 数据科学框架:实现 99%的准确性
使用 Kaggle 笔记本探索和运行机器学习代码|使用《泰坦尼克号:灾难中的机器学习》中的数据
www.kaggle.com](https://www.kaggle.com/ldfreeman3/a-data-science-framework-to-achieve-99-accuracy) [## 泰坦尼克号-高级特征工程教程
使用 Kaggle 笔记本探索和运行机器学习代码|使用《泰坦尼克号:灾难中的机器学习》中的数据
www.kaggle.com](https://www.kaggle.com/gunesevitan/titanic-advanced-feature-engineering-tutorial)
如果您喜欢中级数据科学,并且还没有注册,请随时使用我的推荐链接加入社区。
机器学习:单词嵌入和预测
原文:https://towardsdatascience.com/machine-learning-word-embedding-and-predicting-e603254e4d7b?source=collection_archive---------20-----------------------
通过开发简单的单词预测器来理解单词嵌入
图片由来自 Pixabay 的 Quinn Kampschroer 提供
单词嵌入是一种将稀疏表示向量转换成密集的更小向量的流行技术。这大大增加了计算时间,并节省了资源。在本文中,让我们看看如何开发一个预测引擎,并在工作流中利用单词嵌入的知识。
一点背景
错别字更正
这是将单个单词调整为最匹配的正确单词的地方。在大多数情况下,这种方法试图解决拼写问题。比如你输入【helo】,很有可能你的手机会变成 【你好】 。
单词预测
这是一种新的方法,可以纠正你的语法。单词被替换以使句子更自然。例如,如果你说 “你很漂亮” 我们可以有一个合理的逻辑,这个词可能会变成 【人】 。事实上,这应当完成为 【你是一个美丽的人】 。在本文中,我们将关注这种使用上下文信息的自动更正。这比修复错别字要复杂一些。我希望你们都是手机这个功能的受害者/使用者。让我们自己造一个吧!
查找训练数据集
有一次,我偶然发现了这个网址,它指引我找到了名为《变形记》的电子书。这是一个 ASCII 编码(UTF 8)的文本文档,可以免费下载。从今以后,我将引用这个源作为我的训练数据集。重要的事情先来!让我们快速地进行预处理和标记化,这样我们就可以开始了。我将使用以下 python 库进行预处理(以防您还没有它们)。
numpy
tensorflow
keras (comes as the API for tensorflow backend)
初步了解
我们要执行的第一步是对训练集中的单词进行标记化。这是因为我们应该将整个语料库中的所有单词放在一个有限的空间中,以便进行下游处理。通常,神经网络在一个值范围内表现更好。因此,我们应该将所有这些数据嵌入到密集的向量中。我们的单词符号更像是对空间的压缩。让我们看看它是如何工作的。
嵌入技术
- TF-IDF 矢量化
这是通过考虑单词在文档中的频率及其在语料库中的出现频率来嵌入单词的非常常见的方法。向量的大小将等于所考虑的唯一单词的数量。通常使用稀疏矩阵来实现。让我们看看下面的示例代码。
from sklearn.feature_extraction.text import TfidfVectorizer, CountVectorizer
import pandas as pdtexts = ["Data Science is a popular field.",
"Data Science is useful in predicting financial performance of economies",
"Performance is important in data science"]vectorizer = CountVectorizer()
counts = vectorizer.fit_transform(texts)
tfidf = TfidfVectorizer()
features = tfidf.fit_transform(texts)pd.DataFrame(counts.todense(),columns=vectorizer.get_feature_names())
pd.DataFrame(features.todense(),columns=tfidf.get_feature_names())
这将在终端中打印以下输出(在这里阅读更多关于理论)。
每个文档中的字数
TF-IDF 单词向量
通过这个向量的外观,你会看到它们是高维的,因此需要大量的计算资源。
单词嵌入
这就是我们使用嵌入层的地方,它将稀疏表示压缩到一个目标维度中,形成一个更小的表示。让我们看一个例子。
from tensorflow.keras.preprocessing.text import Tokenizer
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Embeddingdocs = ["Data Science is a popular field.",
"Data Science is useful in predicting financial performance of economies",
"Performance is important in data science"]tokenizer = Tokenizer()
tokenizer.fit_on_texts(docs)
vocab_size = len(t.word_index) + 1model = Sequential()
model.add(Embedding(vocab_size, 3, input_length=1))
model.compile('rmsprop', 'mse')input_array = tokenizer.texts_to_sequences(["Data"])
output_array = model.predict(input_array)output_array
接下来是输出;
array([[[0.02056189, 0.04136733, 0.03566055]]], dtype=float32)
你可以看到我们看到一个形状为 N,1,3 的张量,这是因为我们的目标维度是 3,我们有一个单词。多个单词会增加张量的第二维度。这些将是你学习模型的超参数。现在,你将拥有包含三维单词的句子,与之前的词汇大小形成对比。
实施我们的模型
既然我们已经掌握了初步步骤的专业知识,让我们来构建模型。
基本进口
from numpy as np
import tensorflow as tf
from tensorflow.keras.preprocessing.text import Tokenizer
from tensorflow.keras.utils import to_categorical
加载训练数据
我们将使用前面提到的书 【蜕变】 作为语料库来加载数据和分词。我们将考虑 3 个连续的单词。模型的输入是前两个单词,输出将是每组 3 个单词的最后一个单词。
data = ""
with open("./metamorphosis.txt") as f:
data = f.read().strip()tokenizer = Tokenizer()
tokenizer.fit_on_texts([data])# determine the vocabulary size
vocab_size = len(tokenizer.word_index) + 1
print('Vocabulary Size: %d' % vocab_size)# create line-based sequences
sequences = list()for encoded in tokenizer.texts_to_sequences(data.split("\n")):
if len(encoded) > 0:
for i in range(0, len(encoded) - 2):
sequences.append(encoded[i:i+3])
print('Total Sequences: %d' % len(sequences))
sequences = np.array(sequences)X, y = sequences[:,:-1], to_categorical(sequences[:,-1], num_classes=vocab_size)
构建模型
让我们为我们的培训建立一个简单的模型。在本文中,我将开发一个非常简单的模型,它将考虑前面的两个单词来预测或纠正下一个单词。我的输出将以分类二进制格式来预测下一个单词。我将使用我喜欢使用的 Keras 功能 API 。
# define model
i = tf.keras.layers.Input(shape=(X.shape[1]))e = tf.keras.layers.Embedding(vocab_size, 10, input_length=max_length)(i)l = tf.keras.layers.LSTM(10)(e)d = tf.keras.layers.Dense(vocab_size, activation='softmax')(l)model = tf.keras.Model(inputs=i, outputs=[d])print(model.summary())# compile network
model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])
tf.keras.utils.plot_model(model)
注意,我们使用 分类交叉熵 ,因为我们正在训练预测二进制分类值。一位将指示特定索引中的一个项目。
当我们运行代码时,我们将能够看到下面的模型。
Model: "model"
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
input_1 (InputLayer) [(None, 2)] 0
_________________________________________________________________
embedding_4 (Embedding) (None, 2, 10) 2700
_________________________________________________________________
lstm (LSTM) (None, 10) 840
_________________________________________________________________
dense (Dense) (None, 270) 2970
=================================================================
Total params: 6,510
Trainable params: 6,510
Non-trainable params: 0
可视化网络
我们可以使用下面几行代码启动培训程序。
model.fit(X, y, epochs=1000, verbose=2)
预言
现在我们已经训练了模型,我们可以开始预测下一个单词并进行纠正。让我们看看如何根据训练好的模型进行预测。
text = " there's still **so**"
text = " ".join(text.split(" ")[:3])encoded = tokenizer.texts_to_sequences([text])[0]
encoded = array([encoded])next = model.predict(encoded, verbose=0)for x in next:
next_word_token = np.argmax(x) # map predicted word index to word
for word, index in tokenizer.word_index.items():
if index == next_word_token:
print(word + " ")
这里用粗体表示,我把 写成了 ,这是打了一半的最后一个单词(用于模拟用户输入)。请注意,我认为前两个词是预测。我们的预测者会预测单词 【某】 。所以完整的句子会是 【还有一些】 。我们使用 argmax 来挑选预测的类别,并在 tokenizer 字典中查找单词。
让工作流程更智能
我们天真地选择了最有可能的项目。然而,如果我们有了 【还有一些 fo】,下一个单词很容易就是【food】。对此,最简单的解决方法是挑选最可能的项目集,而不选择 argmax 。然后查找单词并指定最接近的匹配。为此,您可以使用余弦距离。
提示
为了清晰起见,尝试绘制您的 Keras 模型。
找到一个好的语料库进行训练(我选择的是天真的)
在分类编码不适合的地方,使用二进制编码和 二进制交叉熵 。
我希望你喜欢阅读这篇文章!你好。
机器学习对儿童电视剧角色的痴迷
原文:https://towardsdatascience.com/machine-learnings-obsession-with-kids-tv-show-characters-728edfb43b3c?source=collection_archive---------27-----------------------
埃尔默、伯特和玛吉(辛普森饰)不仅仅是你在成长过程中最喜欢的电视角色——他们也是机器学习和自然语言处理模型
斯蒂芬·格雷奇在 Unsplash 上拍摄的照片
巴特.埃尔莫。伯特。科米。玛吉。他们有什么共同点?
他们都是我们许多人年轻时看过的电视节目中受人喜爱的虚构人物。但这还不是全部——它们也都是人工智能模型。
2018 年,艾伦研究所的研究人员发表了语言模型 ELMo 。主要作者马特·皮特斯说,该团队为他们的模型集思广益了许多首字母缩写词,ELMo 立即成为了一个“异想天开但令人难忘的”选择。
起初只是一个内部玩笑的事情已经成为一种全面发展的趋势。
Google AI 随后推出了 BERT ,这是一个非常强大并且现在广泛使用的基于 Transformer 的语言模型。然后,更多的还有:厄尼、 KERMIT 、巴特、格罗弗等。OpenAI 差点把 GPT-2 命名为“Snuffleupagus,或简称 Snuffy”就在上个月,脸书·艾出版了《玛吉与 T21》。
这篇文章对所有这些模型进行了概述,当然,下面是它们的角色灵感:
ELMo (2018):来自语言模型的嵌入
开创这一趋势的是一种深度上下文化的单词表示方法,它能够捕捉更多关于单词的特征(语法、语义等等)。
将单词表示为向量(“单词嵌入”)的一个大挑战是,无论在什么上下文中使用,单词都将由相同的向量表示。然而,“当前”在“你的当前工作是什么?”对比“那是一条很强的河流海流”——我们不能只用一个固定的表示法来表示两个“海流”!
因此,上下文化的单词嵌入被创建来捕捉单词在其表示中的上下文。ELMo 不是一次只阅读一个单词,而是在给每个单词分配嵌入之前阅读整个句子的上下文,这是使用双向 LSTM 完成的。
ELMo 是使用语言建模的自然语言处理(NLP)研究的一大进步。对于 ELMo 的图解说明,我强烈推荐这个资源。
在机器学习和 NLP 之外,Elmo 是儿童节目芝麻街中一个可爱的毛茸茸的红色布偶。埃尔莫喜欢惊喜、披萨和泡泡浴,并且获得了金像奖最长傻笑奖。它于 1980 年首次出现在银幕上。
左:芝麻街的 Elmo 右:埃尔莫
BERT (2019):变压器的双向编码器表示
谷歌通过引入 BERT 进一步转变了 NLP 中的预训练,这是一种新的基于 Transformer 的语言模型,首次允许****双向和无监督表示。
深度双向意味着在捕捉上下文嵌入时,BERT 使用每个单词的上一个和下一个上下文来表示它。(相比较而言,ELMo 是浅双向的。)简单地根据每个单词的前一个和下一个单词来调节每个单词可能会有问题,因此 BERT 随机屏蔽一些单词,并双向调节每个单词以预测被屏蔽的单词。
在最初的版本中,BERT 已经在问答和自然语言理解任务中取得了令人印象深刻的成果。BERT 和其他基于变压器的架构是过去一年 NLP 研究的基石。
在机器学习和 NLP 之外,Bert 是芝麻街上一个友好的黄色角色。闲暇时,他喜欢读无聊的故事,吃燕麦粥,研究鸽子。
左:芝麻街的伯特;右:伯特
厄尼(2019):双重麻烦
你不能没有伯特最好的伙伴恩尼——好事研究人员开发了恩尼(孙等人)、恩尼(张等人),甚至恩尼 2.0 !
第一个 ERNIE (通过知识整合增强表示)提出了一个语言模型,将 BERT 的单词屏蔽策略扩展到实体级和短语级屏蔽。这样做,这个 ERNIE 可以在训练过程中隐式地学习短语、实体以及它们之间的关系的先验知识。
不到两个月后,第二个 ERNIE (带有信息实体的增强语言表示)出版了。这个 ERNIE 提出了一个语言模型,它结合了知识图来优化获取尽可能多的信息。知识图是表示数据点和将它们链接在一起的关系的强大方法。
在机器学习和 NLP 之外,厄尼是一个麻烦制造者,他的人生使命是在芝麻街上惹恼伯特。他非常喜欢他的橡胶鸭子,曾经说过一句著名的话“我听不见你说什么,我耳朵里有根香蕉!”
左:芝麻街的厄尼;右:厄尼
KERMIT (2019):通过插入变换进行的 Kontextuell 编码器表示
KERMIT 是一个基于插入的生成架构,它将联合分布、分解(即它的边界)和条件一起建模。研究人员发现,KERMIT 在一些特定的任务中表现出色,包括机器翻译。
如果你像我一样好奇,“kontextuell”在瑞典语中是“上下文”的意思。我们知道研究人员在这个命名上是相当故意的,因为在论文的后面,他们写道“然后,像它的朋友 ELMo (Peters 等人,2018),BERT (Devlin 等人,2019),和 ERNIE (Sun 等人,2019),我们也可以使用……”
在机器学习和 NLP 之外,Kermit 是一只标志性的唱歌青蛙,它已经为许多布偶作品增光添彩( Sam and Friends,芝麻街,布偶秀等)。)和迷因(但那不关我的事、邪柯密特等。).克米特于 1955 年首次亮相,是该榜单上年龄最大的电视角色。
左:科米蛙;右: KERMIT
BART (2019):双向和自回归变压器
脸书·艾在伯特、GPT 和之前的 NLP 预训练工作的基础上创建了 BART ,这是一个用于文本生成和理解的新的预训练模型,它结合了双向和自动回归转换器。
BERT 在其双向编码器中使用掩蔽,这意味着掩蔽/丢失的单词是独立预测的。因此,BERT 不能用于文本生成。
相比之下,GPT 是自回归的,这意味着它在向前的方向上从给定上下文的一组单词中预测未来的单词。结果,GPT 无法学习双向互动。
BART 将这些基本思想结合在一起:1)用掩码替换随机文本跨度的文档被双向编码,然后 2)用自回归解码器预测文档未被修改的可能性。
在机器学习和 NLP 之外,巴特是电视上最知名的年轻反叛者之一。你可以在《辛普森一家》中找到巴特和他没完没了的恶作剧电话。
左图:《辛普森一家》中的巴特;右:巴特
格罗弗(2019)
近年来,NLP 领域发展非常迅速,以实现高度可信的摘要和翻译。然而,这些技术也可以用于不太积极的目的,例如人工智能生成的假新闻和宣传。
为了解决这个问题,研究人员创造了 GROVER,这是一个公开的生成器,可以写真实的可控假新闻。GROVER 的目的是让其他人可以针对它进行实践,以开发更好的技术来区分人工智能生成的假新闻和真实的人类撰写的新闻。当时,最好的鉴别器只能以 73%的准确率区分人工智能生成的假新闻和真实新闻。
(在一个令人困惑的命名决定中,这里没有首字母缩写——它被称为 GROVER 只是因为。)
在机器学习和 NLP 之外,Grover 是一个毛茸茸的蓝色芝麻街人物,他喜欢帮助(或试图帮助)别人。希望格罗弗能像帮助他的朋友一样,帮助人工智能世界解决虚假信息。
左:芝麻街的格罗弗;右:格罗弗
MARGE (2020):多语言自动编码器,检索和生成
最近由脸书·艾、发表的 MARGE 是一个新的“预训练的序列到序列模型,通过无监督的多语言多文档解释目标学习。”
更简单地说,它是一个预先训练好的语言模型,通过 1) 检索其他语言中的相关文本,2) 通过在原始文本中寻找模式来重构原始文本来生成文本。
研究人员发现,MARGE 可以成功地执行释义、翻译、多文档摘要和信息检索任务,而无需任何微调。MARGE 在 BLEU (双语评估替补)上的得分高达 35.8,这是一个衡量语言翻译的指标,对于一个没有微调的模型来说,这被认为是相当高的。
在机器学习和 NLP 之外,Marge 是《辛普森一家》中的一个虚构角色。玛吉是三个孩子(包括巴特)的母亲,她也因身材高挑、蓝色(蓝色?👀)头发。
(有了巴特和玛吉,也许脸书·艾非常喜欢《辛普森一家》?)
左图:《辛普森一家》中的玛吉;右:玛姬
最后的想法
研究人员以这种有趣、无害的方式向以前的作品致敬,这很酷。也许未来最先进的机器学习模型将被命名为赫敏或祖寇——我热切期待人工智能研究人员扩展到其他小说领域的那一天。
如果有其他以虚构人物命名的 AI 模型,告诉我!
感谢您的阅读!订阅阅读更多关于人工智能的研究、资源和问题。
** [## GPT-3 有多偏?
尽管它的表现令人印象深刻,但世界上最新的语言模型反映了性别、种族和…
medium.com](https://medium.com/fair-bytes/how-biased-is-gpt-3-5b2b91f1177) [## 我们需要改变图像数据集的管理方式
为什么许多黄金标准的计算机视觉数据集,如 ImageNet,有缺陷
medium.com](https://medium.com/fair-bytes/we-need-to-change-how-image-datasets-are-curated-b325642394df)
凯瑟琳·杨(Catherine Yeo)是哈佛大学计算机科学专业的本科生,她对人工智能/人工智能/自然语言处理、公平和道德以及其他相关领域感兴趣。随意提出想法或者在 Twitter 上跟她打招呼@ catherinehyeo。**
机器学习唯一(几乎)免费的午餐
原文:https://towardsdatascience.com/machine-learnings-only-almost-free-lunch-b9da72e04ae8?source=collection_archive---------67-----------------------
照片由 Riho Kroll 在 Unsplash 上拍摄
集成:机器学习中唯一(几乎)免费的午餐
由德米特里玛丽亚·博罗达科娃 — 17 分钟阅读
在这篇文章中,我将讨论集成优化这个有些被忽视的话题。我首先简要概述了一些常见的合奏技术,并概述了它们的弱点。然后,我介绍了一个简单的集成优化算法,并演示了如何用 Python 和 PyTorch 将它应用于构建神经网络集成。
丹尼斯·约翰逊在 Unsplash 上拍摄的照片
用 Python 创建漂亮的交互式可视化效果
丽贝卡·维克里——5 分钟阅读
Plotly 是一个交互式的 Python 库,它提供了一个简单的界面,提供了广泛的可视化功能。Python 中有许多不同的可视化库。与 Matplotlib 相比,Plotly 与众不同的是其情节的交互性、可视化的丰富性和多样性、相对简单性,以及使用 Dash 模块将可视化部署为 web 应用的能力。
Roberta keiko Kitahara Santana 在 Unsplash 上拍摄的照片
把 AI 搬到现实世界
由阿龙·博奇曼 — 9 分钟读取
如果你符合这些条件之一,这篇文章就是为你准备的:
● 你是数据科学经理。你想通过一些最佳实践来提高团队的生产力。
● 你是数据科学家。你想知道下游发生了什么:你的模型如何变成产品。
照片由 Unsplash 上的 Morning Brew 拍摄
人工智能助力平台商业时代的客户偏好
由扬·泰希曼 — 9 分钟阅读
营销和产品团队的任务是了解客户。为了做到这一点,他们着眼于客户的偏好——动机、期望和倾向——结合客户的需求来驱动他们的购买决策。
pixabay.com
什么是数据科学?
由杰夫·黑尔 — 10 分钟阅读
什么是数据科学?是一个简单的问题,但答案往往令人困惑。我经常听到人们说数据科学只不过是穿上奇装异服的统计学。数据科学被戏称为 Mac 上的统计学。住在加州的数据科学家被称为数据分析师。
机器阅读伯特兰·罗素
原文:https://towardsdatascience.com/machine-reads-bertrand-russell-ff4eb63bc25c?source=collection_archive---------35-----------------------
Giammarco Boscaro 在 Unsplash 上拍摄的照片
使用词云、主题建模和文本相似性的自然语言处理(NLP)应用
我的一个秘密目标就是多看伯特兰·罗素的作品;罗素是一个多才多艺的作家,他涉猎广泛,包括哲学、逻辑、社会问题和数学。自然地,我认为让我的电脑替我做一些阅读会有所帮助,特别是当我们仍然可以告诉电脑做什么的时候。因此,让我们从古腾堡那里抓取一些文本,并教机器生成一些见解。
首先,我们需要导入要分析的文本。为此,我推荐使用 Python 的 Gutenberg 包而不是通用的文件导入包,因为它允许轻松删除 Gutenberg 在每个文档中相当长的披露。如果我们只处理一个文本,这没什么大不了的,因为删除可以手动完成,但在这种情况下,我们会带来十多个文本。要在 Google 的 Colab 上设置 Gutenberg:
整个代码被调整为在 Colab 上运行,所以如果您正在您的机器上运行它,忽略您可能已经在本地拥有的包的片段。正如你可能已经知道的,Colab 设置是临时的,每次我们都需要上传默认情况下没有提供给所有用户的东西。如果在您的计算机上使用 Jupyter 笔记本,您可能希望按照以下方式调整窗口宽度(根据您自己的喜好更改百分比):
拉塞尔胸怀大志
预处理和词云
在本教程中,我们将使用 NLTK 、 Wordcloud 和 Scikit-learn 库,它们都有自己的停用词列表(非常常见的词和其他不会给我们的分析增加太多价值的词)。为了保持一致,我们在整个教程中只使用 scikit-learn 版本,但包括一些我不认为非常有用的额外单词:
假设已经安装了 Gutenberg 包,让我们导入文本:
import os
from gutenberg.acquire import load_etext
from gutenberg.cleanup import strip_headers path = os.getcwd() text_list = [5827, 690, 2529, 25447, 4776, 44932, 37090, 17350, 55610, 52091] #writes all texts into one file in the TextsPub directory os.mkdir(path + '/TextsPub')
with open(path + '/TextsPub/Russell.txt', 'w') as f:
for text in text_list:
text = strip_headers(load_etext(text)).strip()
f.write(text)#writes texts into separate files in the TextsPub directory
for text in text_list:
with open(f"{path+'/TextsPub'}/{text}", "w") as f:
f.write(strip_headers(load_etext(text)).strip())
利用上一篇关于 Plutarch 的文章中的代码,让我们进行文本清理和字数统计,我们将删除一些停用词、短词、数字、语法,对文本进行标记,并统计最常用的词:
让我们检查一下有多少单词,其中有多少是独特的:
unique = set(words)
print("The text is {} words long and {} unique words".format(len(words), len(unique)))
我们得到 216,893 个单词,其中 15,377 个是唯一的。使用这个预处理过的文本,为了使见解更有意义,让我们用对进行词汇化(即去除词尾变化,返回单词的基本形式)并绘制一个单词云:
nltk.download('wordnet') #lexical database for English
from nltk.stem import WordNetLemmatizer
with open(path + '/TextsPub/Russell_tokens.txt') as f, open(path + '/TextsPub/Russell_lemma.txt', 'w') as out_f:
text = f.read()
tokens = word_tokenize(text)
lemma = WordNetLemmatizer()
lemmed = [lemma.lemmatize(word) for word in tokens]
#print(lemmed[:100])
new_lem_text = ' '.join(lemmed)
out_f.write(new_lem_text)unique_lem = set(lemmed)
print("The lemmatized text is {} words long and {} unique words".format(len(lemmed), len(unique_lem)))
我们会看到,虽然整个文本有相同的 216,893 个单词,但独特的单词减少到了 13,656 个。
让我们将词条化的文本放入词云:
“thing”这个词变得非常突出,大概是由于将“thing”和“things”结合在一起,所以我们不妨检查一下它的使用频率:
下面的输出表明“thing”现在是最频繁的;光看“云”这个词是看不出来的:
[('thing', 1301), ('point', 1234), ('relation', 1146), ('space', 1140), ('world', 1044), ('fact', 1025), ('object', 930), ('men', 895), ('time', 870), ('knowledge', 856), ('case', 844), ('belief', 805), ('state', 775), ('form', 773), ('law', 756), ('certain', 747), ('number', 744), ('question', 737), ('different', 732), ('life', 727), ('present', 718), ('sense', 692), ('view', 677), ('word', 673), ('possible', 668), ('mean', 665), ('man', 664), ('make', 663), ('way', 655), ('thought', 651), ('true', 635), ('mind', 624), ('matter', 613), ('know', 598), ('given', 579), ('geometry', 560), ('work', 549), ('desire', 542), ('doe', 539), ('kind', 535)]
罗素的顶级词汇是概括和抽象的:事物、点、关系、空间、世界、事实等。总的来说,顶级词汇代表了科学、哲学和政治词汇的混合,表明了文本中固有的多样性。
布尔什维克主义与几何学非常不同
主题建模和文本相似性
在我们继续之前,让我们将古腾堡索引中的 10 个文本复制并重命名为类似于实际名称的名称,然后只提取和排序没有路径和文件扩展名的文本标题:
['Analysis_Mind',
'Bolshevism',
'Foundations_Geometry',
'Free_Thought',
'Knowledge',
'Mysticism_Logic',
'Political_Ideals',
'Problems_Philosophy',
'Roads_Freedom',
'Why_Fight']
有相当多的主题建模技术,如非负矩阵分解(NMF)潜在语义分析(截断奇异值分解)潜在狄利克雷分配和稀疏主成分分析 —出于篇幅的考虑,在本教程中我们将触及第一个,并在 Github 代码中涵盖其他三个。
所有的方法都非常不同,所以检查和操作它们的组成部分是非常重要的,因为人们试图实现更好的结果。例如,scikit-learn 为 NMF 显示了以下内容:
*class* sklearn.decomposition.NMF(*n_components=None*, *init=None*, *solver='cd'*, *beta_loss='frobenius'*, *tol=0.0001*, *max_iter=200*, *random_state=None*, *alpha=0.0*, *l1_ratio=0.0*, *verbose=0*, *shuffle=False*)
例如对于 beta-loss(测量 NMF 和目标矩阵之间的距离),我们有三种选择:除了默认的 Frobenius 范数,我们还可以尝试 Kullback-Leibler 散度和板仓-斋藤距离。解算器本身也可以改变,从默认的坐标下降到乘法更新解算器(板仓-斋藤需要)。
出于缩短本教程的错误原因,我们这次将跳过术语化——但是技术与上面显示的一样。让我们对文本进行矢量化,并创建一个 numpy 数组,因为上面提到的一些方法不能处理稀疏矩阵(NMF 对这两种方法都可以,但稀疏需要更长的时间来处理):
然后,让我们创建主题:
这是我们得到的结果:
让我们看看各种文本是如何处理四大主题的:
以下是输出:
(幸运的是)在布尔什维克主义和几何学的文本之间没有重叠;几何学的主题与精神分析、知识、神秘主义和逻辑的文本有很好的匹配。与此同时,处理布尔什维克主义的文件与关于政治理想、人类为何而战和自由之路的文本分享了热门话题。
最后但同样重要的是,让我们运行 TF-IDF(术语频率-逆文档频率)来测量这十个文本之间的成对相似性:
在将包含相似性得分的矩阵转换成 Pandas 数据框架后,我们可以很容易地直观检查结果:
是的,几何和布尔什维克主义还是很不一样的!
结论
在这个简短的教程中,我们利用流行的 NLP 技术从文本中提取信息,包括词云、主题建模和文本相似性。我们利用了 NLTK、Wordcloud 和 Scikit——一路学习。本教程涉及的代码(以及更多)可从 Github 上获得。
参考资料:
- 人文社会科学主题模型文本分析
- 自然语言处理在行动
基于 seq2seq 模型的机器翻译:不同的方法
原文:https://towardsdatascience.com/machine-translation-with-the-seq2seq-model-different-approaches-f078081aaa37?source=collection_archive---------22-----------------------
自然语言处理|深度学习
使用 seq2seq 模型讨论两种不同的机器翻译方法。
杰西卡·鲁斯切洛在 Unsplash 上的照片
机器翻译是计算语言学的一个子领域,它研究如何使用软件将文本或语音从一种语言翻译成另一种语言。机器翻译在简单的层面上用一种语言中的单词机械地替换另一种语言中的单词,但这本身很少能产生有效的翻译,因为它涉及到对整个句子及其在目标语言中最接近的对应物的理解。两种给定的语言可能具有完全不同的结构。一种语言中的单词在另一种语言中没有对应的单词。而且,许多单词有不止一个意思。用神经技术解决这个问题是一个快速发展的领域,可以带来更好的翻译,它可以处理习语和类型学翻译中的差异。
在本文中,我们将构建一个翻译器,可以将英语句子翻译成印地语句子。您可以通过简单地更改我们将在这里使用的数据集,为不同的语言创建您的翻译器。我们将使用递归神经网络主题— seq2seq,即编码器-解码器模型。在下面的文章中,seq2seq 模型用于构建一个生成性聊天机器人。
[## 使用 seq2seq 模型的生成型聊天机器人!
聊天机器人是一种为用户提供真实对话体验的软件。有封闭域聊天机器人…
towardsdatascience.com](/generative-chatbots-using-the-seq2seq-model-d411c8738ab5)
机器翻译或多或少类似于上面文章中所做的。构建生成型聊天机器人和机器翻译器的主要区别在于数据集和文本预处理。也就是说,我们在这里遵循的步骤将类似于下面文章中的步骤。
这里有两种方法可以用来做机器翻译。我们将在接下来的章节中讨论它们。
机器翻译 seq2seq 方法简介
seq2seq 模型也称为编码器-解码器模型,使用长短期记忆 LSTM 从训练语料库中生成文本。seq2seq 模型在机器翻译应用中也很有用。seq2seq 或编码器-解码器模型用简单的话来说是做什么的?它预测用户输入中给定的单词,然后使用该单词出现的可能性来预测接下来的每个单词。在构建我们的生成式聊天机器人时,我们将使用这种方法来生成用户输入中给出的文本。
使用编码器-解码器模型的机器翻译
编码器输出最终状态向量(存储器),该向量成为解码器的初始状态。我们使用一种叫做 的方法,教师强迫 来训练解码器,使其能够按照前面单词中给定的目标序列来预测后面的单词。如上所示,状态通过编码器传递到解码器的每一层。“我”、“做”、“不”和“知道”被称为输入标记,而'मुझे'、'नहीं'和'पता'被称为目标标记。令牌'पता'的可能性取决于先前的字和编码器状态。我们正在添加'< END >'标记,让我们的解码器知道何时停止。你可以在这里了解更多关于 seq2seq 车型的信息。
让我们从头开始构建我们的翻译器吧!我们要做的第一项任务是预处理我们的数据集。
预处理数据集
这里使用的数据集是在 GitHub 上的一个公共存储库中的数据集的帮助下自己创建的。您可以从本文末尾给出的项目链接中找到代码和数据集。该数据集包含 10,000 个英语句子和相应的印地语翻译。
首先,我们必须在正则表达式的帮助下清理我们的语料库。然后,我们将需要像英语-印地语这样的配对,以便我们可以训练我们的 seq2seq 模型。我们将如下所示执行这些任务。
import re
import random
data_path = "/Data/English.txt"
data_path2 = "/Data/Hindi.txt"# Defining lines as a list of each line
with open(data_path, 'r', encoding='utf-8') as f:
lines = f.read().strip().split('\n')
with open(data_path2, 'r', encoding='utf-8') as f:
lines2 = f.read().strip().split('\n')lines = [" ".join(re.findall(r"[A-Za-z0-9]+",line)) for line in lines]
lines2 = [re.sub(r"%s|\(|\)|<|>|%|[a-z]|[A-Z]|_",'',line) for line in lines2]# Grouping lines by response pair
pairs = list(zip(lines,lines2))
random.shuffle(pairs)
创建对子后,我们也可以在训练前洗牌。我们的对子现在看起来像这样:
[('he disliked that old black automobile', 'उन्होंने उस पुराने काले ऑटोमोबाइल को नापसंद किया।'), ('they dislike peaches pears and apples', 'वे आड़ू, नाशपाती और सेब को नापसंद करते हैं।'),...]
这里,“他不喜欢那辆旧的黑色汽车”是输入序列,'उन्होंनेउसपुरानेकालेऑटोमोबाइलकोनापसंदकिया।'是目标序列。我们必须为输入序列和目标序列创建单独的列表,我们还需要为数据集中的唯一标记(输入标记和目标标记)创建列表。对于目标序列,我们将在序列的开头添加'
import numpy as np
input_docs = []
target_docs = []
input_tokens = set()
target_tokens = set()
for line in pairs:
input_doc, target_doc = line[0], line[1]
# Appending each input sentence to input_docs
input_docs.append(input_doc)
**# Splitting words from punctuation
target_doc = " ".join(re.findall(r"[\w']+|[^\s\w]", target_doc))**
# Redefine target_doc below and append it to target_docs
target_doc = '<START> ' + target_doc + ' <END>'
target_docs.append(target_doc)
# Now we split up each sentence into words and add each unique word to our vocabulary set
for token in re.findall(r"[\w']+|[^\s\w]", input_doc):
if token not in input_tokens:
input_tokens.add(token)
for token in target_doc.split():
if token not in target_tokens:
target_tokens.add(token)input_tokens = sorted(list(input_tokens))
target_tokens = sorted(list(target_tokens))
num_encoder_tokens = len(input_tokens)
num_decoder_tokens = len(target_tokens)
两种不同的方法
这里需要注意的一个关键点是,在创建 target_doc 时,我们将单词与标点符号分开。这意味着नाशपातीऔरसेबकोनापसंदकरतेहैं।''वेआड़ू的目标序列将变成नाशपातीऔरसेबकोनापसंदकरतेहैं।'.'वेआड़ू这是在我们执行字符级预测时完成的。预处理我们的目标序列的另一个选择是简单地按原样附加序列。当我们想要训练我们的模型来预测来自训练语料库的固定单词(单词级预测)时,就要这样做。要使用这种方法,请注释掉上面代码片段中的粗体语句。当我们进行字符级预测时,我们得到 200 个编码器标记和 238 个解码器标记,而在单词级预测中,我们得到 200 个编码器标记和 678 个解码器标记。我们将在后面的部分讨论这两个选项之间的性能差异,同时讨论模型的准确性和损失。现在,让我们坚持前一个(角色级别)选项。
现在,我们的数据集有了唯一的输入标记和目标标记。现在,我们将创建一个输入特征字典,将输入标记存储为键-值对,单词是键,值是索引。类似地,对于目标标记,我们将创建一个目标特性字典。特征字典将帮助我们把我们的句子编码成一个热点向量。毕竟计算机只懂数字。为了对句子进行解码,我们需要创建逆向特征字典,将索引存储为键,将单词存储为值。
input_features_dict = dict(
[(token, i) for i, token in enumerate(input_tokens)])
target_features_dict = dict(
[(token, i) for i, token in enumerate(target_tokens)])reverse_input_features_dict = dict(
(i, token) for token, i in input_features_dict.items())
reverse_target_features_dict = dict(
(i, token) for token, i in target_features_dict.items())
培训设置
为了训练我们的 seq2seq 模型,我们将使用三个独热向量矩阵,编码器输入数据、解码器输入数据和解码器输出数据。我们使用两个矩阵作为解码器的原因是 seq2seq 模型在训练时使用的一种称为 的方法,即教师强制 。这背后的想法是什么?我们有一个来自前一个时间步的输入令牌来帮助模型训练当前的目标令牌。让我们创建这些矩阵。
#Maximum length of sentences in input and target documents
max_encoder_seq_length = max([len(re.findall(r"[\w']+|[^\s\w]", input_doc)) for input_doc in input_docs])
max_decoder_seq_length = max([len(re.findall(r"[\w']+|[^\s\w]", target_doc)) for target_doc in target_docs])encoder_input_data = np.zeros(
(len(input_docs), max_encoder_seq_length, num_encoder_tokens), dtype='float32')
decoder_input_data = np.zeros(
(len(input_docs), max_decoder_seq_length, num_decoder_tokens),
dtype='float32')
decoder_target_data = np.zeros(
(len(input_docs), max_decoder_seq_length, num_decoder_tokens), dtype='float32')for line, (input_doc, target_doc) in enumerate(zip(input_docs, target_docs)):
for timestep, token in enumerate(re.findall(r"[\w']+|[^\s\w]", input_doc)):
#Assign 1\. for the current line, timestep, & word in encoder_input_data
encoder_input_data[line, timestep, input_features_dict[token]] = 1.
for timestep, token in enumerate(target_doc.split()):
decoder_input_data[line, timestep, target_features_dict[token]] = 1.
if timestep > 0:
decoder_target_data[line, timestep - 1, target_features_dict[token]] = 1.
为了清楚地了解编码器 _ 输入 _ 数据的尺寸是如何工作的,请参见上述文章中的下图。解码器 _ 输入 _ 数据和解码器 _ 目标 _ 数据同样具有尺寸。
编码器-解码器模型的训练设置
我们的编码器模型需要一个输入层和一个 LSTM 层,输入层定义了一个用于保存独热向量的矩阵,而层具有一些隐藏状态。解码器模型结构与编码器几乎相同,但这里我们将状态数据与解码器输入一起传入。
from tensorflow import keras
from keras.layers import Input, LSTM, Dense
from keras.models import Model
#Dimensionality
dimensionality = 256
#The batch size and number of epochs
batch_size = 256
epochs = 100
#Encoder
encoder_inputs = Input(shape=(None, num_encoder_tokens))
encoder_lstm = LSTM(dimensionality, return_state=True)
encoder_outputs, state_hidden, state_cell = encoder_lstm(encoder_inputs)
encoder_states = [state_hidden, state_cell]#Decoder
decoder_inputs = Input(shape=(None, num_decoder_tokens))
decoder_lstm = LSTM(dimensionality, return_sequences=True, return_state=True)
decoder_outputs, decoder_state_hidden, decoder_state_cell = decoder_lstm(decoder_inputs, initial_state=encoder_states)
decoder_dense = Dense(num_decoder_tokens, activation='softmax')
decoder_outputs = decoder_dense(decoder_outputs)
您可以在这里了解更多关于如何编码编码器-解码器模型的信息,因为对它的完整解释超出了本文的范围。
建立和训练 seq2seq 模型
现在,我们将创建 seq2seq 模型,并使用编码器和解码器数据对其进行训练,如下所示。
#Model
training_model = Model([encoder_inputs, decoder_inputs], decoder_outputs)
#Compiling
training_model.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy'], sample_weight_mode='temporal')
#Training
training_model.fit([encoder_input_data, decoder_input_data], decoder_target_data, batch_size = batch_size, epochs = epochs, validation_split = 0.2)
这里,我们使用亚当作为优化器,使用分类交叉熵作为损失函数。我们称之为。fit()【方法】通过给定编码器和解码器的输入数据(X/input)和解码器的目标数据(Y/label)。
两种不同的方法—性能比较
经过训练后,我们得到了 53.35%的训练准确率和 52.77%的验证准确率,而训练损失和验证损失分别为 0.0720 和 0.1137。看训练过程中准确率和损耗的曲线图。
我们得到的单词级预测的训练和验证准确率分别为 71.07%和 72.99%,而训练和验证损失分别为 0.0185 和 0.0624。看训练过程中准确率和损耗的曲线图。
在字符级预测的情况下,准确度曲线非常平滑,而在单词级预测的情况下,曲线包含许多尖峰。我们在开始时获得了非常高的精度,但损耗也很高,随着损耗的下降,精度也趋于波动和下降。这告诉我们不要依赖后一种方法,即使它的精度高于前一种方法,因为尖峰会给性能带来不确定性。
测试设置
现在,为了处理模型没有看到的输入,我们需要一个逐步解码的模型,而不是使用教师强制,因为我们创建的模型只有在目标序列已知的情况下才能工作。在生成型聊天机器人应用程序中,我们不知道对用户传入的输入会产生什么样的响应。为此,我们将不得不构建一个 seq2seq 模型。让我们首先用编码器输入和编码器输出状态构建一个编码器模型。我们将在之前训练好的模型的帮助下完成这项工作。
from keras.models import load_model
training_model = load_model('training_model.h5')encoder_inputs = training_model.input[0]
encoder_outputs, state_h_enc, state_c_enc = training_model.layers[2].output
encoder_states = [state_h_enc, state_c_enc]
encoder_model = Model(encoder_inputs, encoder_states)
接下来,我们将需要为解码器输入状态创建占位符,因为我们不知道我们需要解码什么或者我们将得到什么隐藏状态。
latent_dim = 256
decoder_state_input_hidden = Input(shape=(latent_dim,))
decoder_state_input_cell = Input(shape=(latent_dim,))
decoder_states_inputs = [decoder_state_input_hidden, decoder_state_input_cell]
现在,我们将借助之前培训的解码器 LSTM 和密集层来创建新的解码器状态和输出。
decoder_outputs, state_hidden, state_cell = decoder_lstm(decoder_inputs, initial_state=decoder_states_inputs)
decoder_states = [state_hidden, state_cell]
decoder_outputs = decoder_dense(decoder_outputs)
最后,我们有解码器输入层,来自编码器的最终状态,来自解码器密集层的解码器输出,以及解码器输出状态,它是网络从一个字到下一个字期间的存储器。我们现在可以将所有这些放在一起,并设置如下所示的解码器模型。
decoder_model = Model([decoder_inputs] + decoder_states_inputs, [decoder_outputs] + decoder_states)
测试我们的模型
最后,我们将创建一个函数,它接受我们的文本输入,并使用我们创建的编码器和解码器生成响应。在下面的函数中,我们传入表示文本句子的 NumPy 矩阵,并从中获取生成的响应。我为几乎每一行代码都添加了注释,以便您快速理解。下面的函数是这样的:1。)我们从编码器 2 中检索输出状态。)我们将输出状态传递给解码器(这是解码器的初始隐藏状态),以逐字解码句子 3。)在解码每个字之后更新解码器的隐藏状态,以便我们可以使用先前解码的字来帮助解码新的字
一旦我们遇到我们在预处理任务中添加到目标序列的'
def decode_response(test_input):
#Getting the output states to pass into the decoder
states_value = encoder_model.predict(test_input)
#Generating empty target sequence of length 1
target_seq = np.zeros((1, 1, num_decoder_tokens))
#Setting the first token of target sequence with the start token
target_seq[0, 0, target_features_dict['<START>']] = 1.
#A variable to store our response word by word
decoded_sentence = ''
stop_condition = False
while not stop_condition:
#Predicting output tokens with probabilities and states
output_tokens, hidden_state, cell_state = decoder_model.predict([target_seq] + states_value)
#Choosing the one with highest probability
sampled_token_index = np.argmax(output_tokens[0, -1, :])
sampled_token = reverse_target_features_dict[sampled_token_index]
decoded_sentence += " " + sampled_token#Stop if hit max length or found the stop token
if (sampled_token == '<END>' or len(decoded_sentence) > max_decoder_seq_length):
stop_condition = True
#Update the target sequence
target_seq = np.zeros((1, 1, num_decoder_tokens))
target_seq[0, 0, sampled_token_index] = 1.
#Update states
states_value = [hidden_state, cell_state]
return decoded_sentence
把它们放在一起——机器翻译
让我们创建一个包含运行翻译器所需方法的类。
class Translator:
exit_commands = ("quit", "pause", "exit", "goodbye", "bye", "later", "stop")
#Method to start the translator
def start(self):
user_response = input("Give in an English sentence. :) \n")
self.translate(user_response)
#Method to handle the conversation
def translate(self, reply):
while not self.make_exit(reply):
reply = input(self.generate_response(reply)+"\n")#Method to convert user input into a matrix
def string_to_matrix(self, user_input):
tokens = re.findall(r"[\w']+|[^\s\w]", user_input)
user_input_matrix = np.zeros(
(1, max_encoder_seq_length, num_encoder_tokens),
dtype='float32')
for timestep, token in enumerate(tokens):
if token in input_features_dict:
user_input_matrix[0, timestep, input_features_dict[token]] = 1.
return user_input_matrix
#Method that will create a response using seq2seq model we built
def generate_response(self, user_input):
input_matrix = self.string_to_matrix(user_input)
chatbot_response = decode_response(input_matrix)
#Remove <START> and <END> tokens from chatbot_response
chatbot_response = chatbot_response.replace("<START>",'')
chatbot_response = chatbot_response.replace("<END>",'')
return chatbot_response
#Method to check for exit commands
def make_exit(self, reply):
for exit_command in self.exit_commands:
if exit_command in reply:
print("Ok, have a great day!")
return True
return False
translator = Translator()
在上面的代码中,所有方法都是不言自明的。下面是我们的翻译器的最终输出!
两种不同的方法—最终输出比较
字级预测输出
字符级预测输出
上面的快照显示了我们的翻译人员为两种不同的方法所做的翻译。
照片由格雷格·布拉在 Unsplash 上拍摄
你可以找到上面所有的代码以及来自 GitHub 的数据集。你也可以在 LinkedIn 上和我联系。如果有任何疑问,您可以在这里或我的 LinkedIn 收件箱中回复。
结论
我们设法在字符级预测的情况下获得了大约 53%的准确率,在单词级预测的情况下获得了 73%的准确率。自然语言处理是一个需要大量数据的领域,尤其是机器翻译任务。它正在开发和训练神经网络,以模拟人脑处理语言的方式。这种深度学习策略可以让计算机更有效地处理人类语言。有像谷歌和微软这样的公司在机器翻译任务中提供人类水平的准确性。与我们在这里创建的网络相比,这些公司使用的网络要复杂得多。
MachineRay:用人工智能创造抽象艺术
原文:https://towardsdatascience.com/machineray-using-ai-to-create-abstract-art-39829438076a?source=collection_archive---------8-----------------------
我如何使用公共领域绘画训练 GAN
机器阵列的样本输出
在过去的三个月里,我一直在探索人工智能(AI)和机器学习(ML)的最新技术来创作抽象艺术。在我的调查中,我了解到创作抽象绘画需要三样东西:(A)源图像,(B)ML 模型,以及(C)在高端 GPU 上训练模型的大量时间。在我讨论我的工作之前,让我们先来看看一些先前的研究。
这是我关于人工智能如何用于创造性努力的系列文章的第一部分。第二部分是关于如何使用 ML 为新的故事生成情节,这里有的。
背景
人工神经网络
早在 1943 年,沃伦麦卡洛克和沃尔特皮茨就为神经网络(NNs)创建了一个计算模型[1]。他们的工作导致了对大脑中生物过程和人工智能中神经网络使用的研究。理查德·纳吉菲在这篇文章中讨论了人工神经网络(ann)和生物大脑之间的差异。他描述了一个恰当的类比,我将在这里总结一下:神经对于大脑就像飞机对于鸟类一样。尽管这些技术的发展受到了生物学的启发,但是实际的实现是非常不同的!
视觉类比mikemacmarketin CC BY 2.0 的神经网络芯片图稿、biologycorner CC BY-NC 2.0 的大脑模型、Moto@Club4AG CC BY 2.0 的平面照片、ksblack99 CC PDM 1.0 的鸟类照片
人工神经网络和生物大脑都从外部刺激中学习,以理解事物和预测结果。一个关键的区别是,人工神经网络处理浮点数,而不仅仅是神经元的二进制触发。对于人工神经网络,它是数字输入和数字输出。
下图显示了典型人工神经网络的结构。左边的输入是包含输入刺激的数值。输入层连接到一个或多个包含先前学习记忆的隐藏层。输出层,在这种情况下只有一个数字,连接到隐藏层中的每个节点。
典型人工神经网络图
每个内部箭头代表数字权重,这些数字权重用作乘数,在网络中从左到右处理图层时修改图层中的数字。用输入值和预期输出值的数据集来训练该系统。权重最初被设置为随机值。对于训练过程,系统多次运行训练集,调整权重以实现预期的输出。最终,系统不仅能从训练集中正确预测输出,还能预测未知输入值的输出。这就是机器学习(ML)的本质。智慧在砝码中。关于人工神经网络培训过程的更详细的讨论可以在康纳麦当劳的帖子中找到,这里。
生成对抗网络
2014 年,蒙特利尔大学的 Ian Goodfellow 和七名合著者提交了一篇关于生成性对抗网络(GANs)的论文[2]。他们想出了一种训练两个人工神经网络的方法,这两个人工神经网络可以有效地相互竞争,以创建像照片、歌曲、散文,是的,还有绘画这样的内容。第一个人工神经网络称为生成器,第二个称为鉴别器。生成器试图创建逼真的输出,在这种情况下,是一幅彩色绘画。鉴别器试图从训练集中辨别真实的绘画,而不是从生成器中辨别伪造的绘画。这是 GAN 架构的样子。
生成性对抗网络
一系列随机噪声被送入发生器,然后发生器使用其训练的权重来生成结果输出,在这种情况下,是彩色图像。通过在处理预期输出为 1 的真实绘画和预期输出为-1 的伪造绘画之间交替来训练鉴别器。在每幅画被发送到鉴别器后,它会发回详细的反馈,说明为什么这幅画不是真实的,生成器会根据这些新知识调整其权重,以尝试下次做得更好。GAN 中的两个网络以对抗的方式被有效地一起训练。生成器在试图将假图像冒充为真实图像方面变得更好,鉴别器在确定哪个输入是真实的,哪个是假的方面变得更好。最终,生成器在生成逼真的图像方面变得非常出色。你可以在 Shweta Goyal 的帖子这里阅读更多关于 GANs 的内容,以及他们使用的数学。
用于大图像的改进的 GANs
尽管上述基本 GAN 适用于小图像(即 64×64 像素),但对于大图像(即 1024×1024 像素)存在问题。由于像素的非结构化性质,基本 GAN 架构难以收敛到大图像的良好结果。它从树上看不到森林。英伟达的研究人员开发了一系列改进的方法,允许用更大的图像训练 GANs。第一种叫做【3】。
关键的想法是逐步增加生成器和鉴别器:从低分辨率开始,我们添加新的层,随着训练的进行,这些层可以模拟越来越精细的细节。这既加快了训练的速度,又极大地稳定了训练,使我们能够拍摄出前所未有的高质量图像。——特罗·卡拉斯等人。艾尔。,英伟达
NVIDIA 的团队继续他们的工作,使用 GANs 生成大的、真实的图像,将他们的架构命名为StyleGAN【4】。他们以渐进增长的 GANs 作为基础模型,并添加了一个风格映射网络,将不同分辨率的风格信息注入到生成器网络中。
StyleGAN 组件图
该团队利用 StyleGAN 2 进一步改善了图像创建结果,使 GAN 能够高效地创建高质量的图像,减少不必要的伪影[5]。你可以在 Akria 的帖子“从 GAN basic 到 StyleGAN2 ”中了解更多关于这些发展的信息。
以前的工作,创造艺术与甘斯
自 GAN 于 2014 年推出以来,研究人员一直在寻求使用 GAN 来创作艺术。任伟·谭等人在 2017 年发表了一个名为 ArtGAN 的系统的描述。艾尔。来自日本长野信州大学[6]。他们的论文建议延长 GANs…
…综合生成更具挑战性和更复杂的图像,如具有抽象特征的艺术品。这与大多数当前的解决方案形成对比,当前的解决方案侧重于生成自然图像,如室内、鸟、花和脸。——任伟谭等。艾尔。信州大学
Drew Flaherty 在澳大利亚布里斯班的昆士兰科技大学为他的硕士论文进行了一项关于使用 GANs 创作艺术的更广泛的调查[7]。他尝试了各种 GAN,包括基本 GAN、cycle gan【8】、BigGAN【9】、 Pix2Pix 和 StyleGAN。在他尝试的所有方法中,他最喜欢斯泰勒根。
这项研究的最佳视觉效果来自 StyleGAN。…考虑到模型仅进行了部分训练,输出的视觉质量相对较高,早期迭代的渐进改进显示了更明确的线条、纹理和形式、更清晰的细节以及更全面的构图。昆士兰科技大学的德鲁·弗莱厄蒂
为了他的实验,弗莱厄蒂使用了从各种来源收集的大量艺术作品,包括WikiArt.org、谷歌艺术项目、萨奇艺术和 Tumblr 博客。他指出,并非所有的源图像都在公共领域,但他讨论了合理使用原则及其对 ML 和 AI 的影响。
机器射线
概观
在我的名为 MachineRay 的实验中,我从 WikiArt.org 收集了一些抽象画的图像,对它们进行处理,然后以 1024x1024 的尺寸输入到 StyleGAN2 中。我用 Google Colab 在 GPU 上训练了 GAN 三周。然后,我通过调整纵横比来处理输出图像,并通过另一个人工神经网络进行超分辨率调整。生成的图像宽或高为 4096 像素,具体取决于长宽比。这是组件图。
机床部件图
收集源图像
为了收集源图像,我写了一个 Python 脚本来收集 WikiArt.org 的抽象画。请注意,我过滤了图像,只得到被标记为“抽象”流派的绘画,以及被标记为公共领域的图像。这些包括 1925 年之前出版的图像或 1950 年之前去世的艺术家创作的图像。该系列中的顶级艺术家包括瓦西里·康丁斯基、特奥·凡·杜斯堡、保罗·克利、卡齐米尔·马列维奇、亚诺什·马蒂斯·托奇、贾科莫·巴拉和皮特·蒙德里安。下面是 Python 代码的一个片段,完整的源文件是这里是。
我收集了大约 900 张图片,但是我删除了那些有代表性的或者太小的图片,把数量减少到了 850 张。这是源图像的随机抽样。
公共领域中来自 WikiArt.org 的抽象画的随机样本
移除框架
正如你在上面看到的,一些画在图像中保留了它们的木制框架,但是一些画的框架被裁剪掉了。例如,你可以在亚瑟·多佛的风暴云中看到这个框架。为了使源图像一致,并允许 GAN 专注于绘画的内容,我使用 Python 脚本自动移除了帧。下面是片段,完整的脚本是这里是。
该代码打开每幅图像,并在边缘周围寻找与大部分绘画颜色不同的正方形区域。一旦找到边缘,图像将被裁剪以忽略该帧。下面是一些拆框前后的源画图片。
自动裁剪的图片来自 WikiArt.org 公共领域
图像增强
虽然 850 张图片看起来很多,但对于训练一只 GAN 来说,这还远远不够。如果没有足够多种类的图像,GAN 可能会过度拟合模型,这将产生较差的结果,或者更糟糕的是,陷入可怕的“模型崩溃”状态,这将产生几乎相同的图像。
StyleGAN2 具有从左到右随机镜像源图像的内置功能。因此,这将有效地将样本图像的数量增加一倍,达到 1,700 个。这是更好的,但仍然不是很大。我使用了一种称为图像增强的技术,将图像数量增加了 7 倍,达到 11,900 张。下面是我使用的图像增强的代码片段。完整的源文件是这里的。
该增强使用随机旋转、缩放、裁剪和温和的颜色校正来在图像样本中创建更多种类。请注意,在应用图像增强之前,我将图像的大小调整为 1024 乘 1024。我将在这篇文章中进一步讨论长宽比。以下是一些图像增强的例子。原文在左边,右边还有六个附加变奏。
图像增强的例子在公共领域描绘来自 WikiArt.org 的图像
训练 GAN
我使用 Google Colab Pro 运行了培训。使用这项服务,我可以在高端 GPU 上运行长达 24 小时,这是一款 16 GB 内存的 NVIDIA Tesla P10。我还使用 Google Drive 来保留运行之间正在进行的工作。训练 GAN 花了大约 13 天的时间,通过系统发送了 500 万幅源图像。这是随机抽样的结果。
【MachineRay 的样本输出
你可以从上面的 28 幅图像样本中看到,MachineRay 创作了各种风格的画作,尽管它们之间有一些视觉上的共性。在源图像中有风格的提示,但是没有精确的拷贝。
调整纵横比
虽然原始源图像有各种长宽比,从较薄的肖像形状到较宽的风景形状,但我将它们都做成方形,以帮助训练 GAN。为了让输出图像有多种长宽比,我在放大之前增加了一个新的长宽比。我没有选择一个纯粹随机的纵横比,而是创建了一个函数,它根据源图像中纵横比的统计分布来选择纵横比。这是分布图。
宽高比分布来自 WikiArt.org 公共领域的图片。
上图描绘了所有 850 幅源图像的纵横比。它的范围从大约 0.5 到大约 2.0,前者是较窄的 1:2 比率,后者是较宽的 2:1 比率。图表显示了四个源图像,以指示它们在图表上的水平位置。下面是我的 Python 代码,它根据源图像的分布将 0 到 850 之间的一个随机数映射成一个纵横比。
我调整了上面的 MachineRay 输出,使下面的图片具有不同的纵横比。你可以看到这些图像看起来更自然,不那么同质,只有这一点小小的变化。
具有不同纵横比的 MachineRay 的样本输出
超分辨率尺寸调整
从 MachineRay 生成的图像的最大高度或宽度为 1024 像素,这对于在计算机上查看是可以的,但是对于打印来说是不可以的。在 300 DPI 时,它只能以大约 3.5 英寸的尺寸打印。这些图像可以放大,但是如果以 12 英寸打印,看起来会很柔和。有一种使用人工神经网络来调整图像大小并保持清晰特征的技术,称为图像超分辨率(ISR)。更多关于超分辨率的信息,请点击这里查看 Bharath Raj 的帖子。
德国 Idealo 公司有一个很好的开源 ISR 系统,带有预先训练好的模型。他们的 GANs 模型使用在照片上训练过的 GANs 进行 4 倍的尺寸调整。我发现在 ISR 之前给图像添加一点随机噪声会产生一种绘画效果。下面是我用来对图像进行后处理的 Python 代码。
你可以在这里看到添加噪声和图像超分辨率调整的结果。注意纹理细节看起来有点像笔触。
左图:添加噪声和 ISR 后的样本图像。右图:细节特写
查看附录 A 中的图库,查看 MachineRay 的高分辨率输出示例。
后续步骤
其他工作可能包括以大于 1024x1024 的尺寸运行 GAN。将代码移植到张量处理单元(TPUs)而不是 GPU 上运行会使训练运行得更快。此外,来自 Idealo 的 ISR GAN 可以使用绘画而不是照片进行训练。这可能会给图像添加更真实的绘画效果。
感谢
我要感谢詹尼弗·林和奥利弗·斯特瑞普对这个项目的帮助和反馈。
源代码
这个项目的所有源代码都可以在 GitHub 上获得。一个用于生成图像的 Google Colab 在这里可用。源代码在 CC BY-NC-SA 许可证下发布。
署名-非商业性使用-类似分享
参考
[1] W .麦卡洛克,w .皮茨,“神经活动中内在的思想逻辑演算”,数学生物物理学通报。5(4):115-133,1943 年 12 月
[2]伊恩,好伙计。“生成性对抗网络。”让·普吉-阿巴迪、迈赫迪·米尔扎、徐炳、戴维·沃德-法利、谢尔吉尔·奥泽尔、亚伦·库维尔、约舒阿·本吉奥,第一版,2014 年 6 月
[3] T. Karras、T. Aila、S. Laine 和 J. Lehtinen,“为提高质量、稳定性和变化性而逐步种植甘蔗”,CoRR,第 abs/1710.1 卷,2017 年 10 月
[4] T. Karras,S. Laine,T. Aila,“基于风格的生成对抗网络生成器架构”,CVPR2019,2019 年 3 月
[5] T. Karras、S. Laine、M. Aittala、J. Hellsten、J. Lehtinen 和 T. Aila,“分析和提高 StyleGAN 的图像质量”,2020 年 3 月
[6] W. R. Tan、C. S. Chan、H. E. Aguirre 和 K. Tanaka,“ArtGAN:使用条件分类 GAN 的艺术作品合成”,2017 年 4 月
[7] D. Flaherty,“机器学习的艺术方法”,昆士兰科技大学,硕士论文,2020 年
[8]朱军,帕克,伊索拉和,“使用循环一致的对抗网络进行不成对的图像到图像翻译”,2018 年 11 月
[9] A. Brock,J. Donahue 和 K. Simonyan,“高保真自然图像合成的大规模 GAN 训练”,2019 年 2 月
附录 A —机器射线结果图库
为了无限制地访问 Medium 上的所有文章,成为会员,每月支付 5 美元。非会员每月只能看三个锁定的故事。
能看见和听见的机器
原文:https://towardsdatascience.com/machines-that-can-see-and-hear-443d70852f19?source=collection_archive---------79-----------------------
苹果 | 谷歌 | SPOTIFY | 其他
Roland Memisevic 在 TDS 播客上
编者按:迈向数据科学播客的“攀登数据科学阶梯”系列由 Jeremie Harris 主持。Jeremie 帮助运营一家名为sharpes minds的数据科学导师初创公司。可以听下面的播客:
机器学习最近最有趣的趋势之一是将不同类型的数据结合起来,以便能够解锁深度学习的新用例。如果 2010 年是计算机视觉和语音识别的十年,那么 2020 年很可能是我们最终发现如何制造能够看到和听到周围世界的机器的十年,使它们更加具有上下文意识,甚至可能更像人类。
整合不同数据源的努力已经引起了学术界和企业的广泛关注。其中一家公司是 200 亿神经元公司,它的创始人 Roland Memisevic 是我们最新一集《走向数据科学》播客的嘉宾。罗兰是一名前学者,早在 2012 年 AlexNet 引发大肆宣传之前,他就已经深入深度学习了。他的公司一直在研究深度学习驱动的开发工具,以及结合视频和音频数据的自动化健身教练,以使用户在整个锻炼过程中保持参与。
以下是今天节目中我最喜欢的一些带回家的东西:
- 在 2012 年之前开始走深度学习道路的学者经常被嘲笑。2000 年代的世界由表格数据主导,决策树和支持向量机等简单模型非常适合这些数据,因此大多数人错误地从中归纳出经典的统计机器学习工具比神经网络更有前途。尽管遇到了所有这些阻力,但让深度学习爱好者继续前进的是一种信念,即深度学习应该有潜力处理人类一直在消耗的一种信息,但机器很少遇到,特别是在当时:视频和音频数据。
- 对于正在开发面向消费者的机器学习新应用的公司来说,移动设备带来的计算限制是一个重要的考虑因素。当 200 亿神经元启动时,移动设备无法处理他们需要的设备上的机器学习能力,如果他们要运行他们的自动化健身教练软件,那么他们面临着一个选择:找到一种压缩他们的模型的方法,以便他们可以在设备上运行,或者等待硬件赶上他们的软件。最终,200 亿美元选择了选项 2,这带来了回报:2018 年,苹果手机开始携带一种芯片,可以解锁他们所需的设备上处理。
- 如果你对试验包含多种数据类型的数据集感兴趣,Roland 推荐查看“某物某物”数据集,可从这里公开获得。
你可以在这里的 Twitter 上关注的 200 亿神经元或者在 LinkedIn 上关注这里你也可以在 Twitter 上关注我这里。
如果你对他们即将推出的健身应用感到好奇,你也可以在 Instagram 上点击关注他们。
订阅《走向数据科学》的 月刊 直接在你的邮箱✨里接收我们最好的文章、视频和播客
宏观经济和金融因素与普通最小二乘回归
原文:https://towardsdatascience.com/macroeconomic-financial-factors-and-ordinary-least-square-regression-4831302e7b69?source=collection_archive---------32-----------------------
基于普通最小二乘回归的多因素模型
利用套利定价理论的计量经济学模型
图片由 Sarit Maitra 提供
一个目标定价理论被表示为一个带有跨方程限制的多元回归模型。它是一种多因素资产定价模型,认为资产的收益可以通过资产的预期收益与捕捉系统风险的宏观经济变量之间的线性关系来预测。
我们这里的数据是布伦特原油指数,S&P500 指数,美国国债利率 3 个月和 10 年(短期和长期),美国国债利率(信用风险),消费者价格指数,工业生产指数的月度股票价格。
我们想在这里检验一下,布伦特原油价格是否可以用一组宏观经济和金融变量的意外变化来解释。处理股票价格的最佳实践是使用调整值,因为它们考虑了可能的公司行为,如股票分割。
combine = pd.concat([h['SP500'], g, f['DGS10'], e['DTB3'], d['TEDRATE'], b['TOTALSL'],a['CPALTT01USM657N'], i['Brent spot price']], axis=1)
combine.set_index('DATE', inplace=True)
combine.index = pd.to_datetime(combine.index)
combine.dropna(inplace=True)
让我们为每个变量生成一组变化或差异。变量的意外值可以定义为变量的实际值与其期望值之间的差值。
陶和布鲁克斯发表了一篇很好的关于套利定价分析的文章,我在文章的最后添加了参考文献。
日志返回
我们将在这里使用对数回报,因为它们随着时间的推移而聚集;给定月份的日志回报是该月内各天的日志回报之和。
这里,rt 是收益,Pt 是资产在时间 t 的价格。
data = DataFrame({'ted_spread' : combine['TEDRATE'] - combine['TEDRATE'].shift(1), 'consumer_credit' : combine['TOTALSL'] - combine['TOTALSL'].shift(1),'indprod' : combine['INDPRO'] - combine['INDPRO'].shift(1),'cr_crude' : np.log(combine['Brent spot price'].diff().dropna()),# (cr_crude) continuously compounded returns for crude oil
'cr_sp' : np.log(combine['SP500']).diff().dropna()# (cr_sp) continuously compounded returns for S&P500
'inflation' : np.log(combine['CPALTT01USM657N']).diff().dropna(),# (inflation) continuously compounded returns for consumer price index
'dgs_dtb' : combine['DGS10'] - combine['DTB3'],
'inflation_diff' : np.log(combine['CPALTT01USM657N']).diff().dropna() - np.log(combine['CPALTT01USM657N']).diff().dropna().shift(1),
'dtb' : combine['DTB3']/12,
'dgs_dtb_shift' : (combine['DGS10'] - combine['DTB3']) - (combine['DGS10'] - combine['DTB3']).shift(1),
'crude_dtb' : np.log(combine['Brent spot price']).diff().dropna() - combine['DTB3']/12,# (crude_dtb3) to transform the returns, (Crude continuously compounded returns) - (3-month US Treasury bill rate)
# = risk free rate
'sp_dtb' : np.log(combine['SP500']).diff().dropna() - combine['DTB3']/12})# (sp_dtb3) (SP continuously compounded returns) - (3-month US Treasury bill rate)
普通最小二乘(OLS)回归
OLS 回归通常作为最大似然算法的一个很好的原型。这是一种受监督的算法,有一个训练过程和一个部署过程。在某些情况下,它可能会过度适合。它与其他更现代的函数逼近算法共享这些特性。然而,OLS 的局限性在于,当训练过度时,没有办法停止训练。
我们将使用普通最小二乘(OLS)回归来估计自变量和因变量(此处为原油)之间的关系,方法是最小化配置为直线的因变量的观察值和预测值之间的差值的平方和。
data = data[~data.isin([np.nan, np.inf, -np.inf]).any(1)]
X = data [['cr_sp', 'indprod', 'consumer_credit', 'inflation_diff', 'ted_spread', 'dgs_dtb_shift']]
y = data['cr_crude']
model = sm.OLS(y, sm.add_constant(X))
model_fit = model.fit()
model_fit.summary()
回归 F 统计值为 10.71。p 值< 0.05 for indprod & dgs_dtb_shift means, null hypothesis can be rejected for these variables. p-values for rest of the variables are > 0.05。让我们使用 f 检验来检验这四个变量的参数共同为零的零假设。
f 检验统计值为 2.764;p 值 0.028,有四个限制和 239 个可用观测值。这表明不能拒绝零假设。
诊断图
使用模型的残差绘制诊断图。让我们将这些图可视化,看看我们的回归模型如何拟合数据,以及是否违反了 OLS 模型的任何基本假设。诊断图以四种不同的方式显示残差。
# model values
y_fitted = model_fit.fittedvalues# model residuals
model_residuals = model_fit.resid# normalized residuals
model_norm_residuals = model_fit.get_influence().resid_studentized_internal# absolute squared normalized residuals
model_norm_residuals_abs_sqrt =np.sqrt(np.abs(model_norm_residuals))# absolute residuals
model_abs_resid = np.abs(model_residuals)# leverage, from statsmodels internals
model_leverage = model_fit.get_influence().hat_matrix_diag# cook's distance, from statsmodels internals
model_cooks = model_fit.get_influence().cooks_distance[0]
残差与拟合
dataframe = pd.concat([X, y], axis=1)
plot_lm_1 = plt.figure()
plot_lm_1.axes[0] = sns.residplot(y_fitted, dataframe.columns[-1], data=dataframe, lowess=True, scatter_kws={'alpha': 0.5}, line_kws={'color': 'red', 'lw': 1, 'alpha': 0.8})
plot_lm_1.axes[0].set_title('Residuals vs Fitted')
plot_lm_1.axes[0].set_xlabel('Fitted values')
plot_lm_1.axes[0].set_ylabel('Residuals');
虽然我们从上面的图中看不到任何独特的模式,但似乎模型的一些非线性特征没有被很好地捕捉,这意味着我们对模型拟合不足。但是,我们将检查 QQ 图以确定常态假设。
正常 Q-Q 图
此图显示残差是否呈正态分布。一个好的正常 QQ 图的所有残差都位于红线上或接近红线。
QQ = ProbPlot(model_norm_residuals)
plot_lm_2 = QQ.qqplot(line='45', alpha=0.5, color='#4C72B0', lw=1)
plot_lm_2.axes[0].set_title('Normal Q-Q')
plot_lm_2.axes[0].set_xlabel('Theoretical Quantiles')
plot_lm_2.axes[0].set_ylabel('Standardized Residuals');# annotations
abs_norm_resid = np.flip(np.argsort(np.abs(model_norm_residuals)), 0)
abs_norm_resid_top_3 = abs_norm_resid[:3]
for r, i in enumerate(abs_norm_resid_top_3):
plot_lm_2.axes[0].annotate(i,
xy=(np.flip(QQ.theoretical_quantiles, 0)[r],
model_norm_residuals[i]));
这里,大部分数据点落在红线上;当然,它们不会是一条完美的直线,看起来正态假设得到了满足。
让我们看看直方图,检查一个正态分布;这里我们期望残差的直方图是钟形的(没有异常值)。
直方图证实残差的分布大致类似于钟形;虽然,我们也发现有一些大的负异常值可能会导致相当大的负偏度。
SkewnKurtosis 测量任一尾部的极值。标准正态分布的峰度是 3。峰度值为 6.11 意味着残差超过正态分布的尾部。然而,一般来说,这些推论可能是错误的;我们的样本可能足够大,所以我们不需要像小样本那样担心。
比例位置
此图显示残差是否沿预测值范围平均分布。我们可以检验等方差的假设,即同方差。
plot_lm_3 = plt.figure()
plt.scatter(model_fitted_y, model_norm_residuals_abs_sqrt, alpha=0.5);
sns.regplot(model_fitted_y, model_norm_residuals_abs_sqrt, scatter=False, ci=False,lowess=True, line_kws={'color': 'red', 'lw': 1, 'alpha': 0.8});
plot_lm_3.axes[0].set_title('Scale-Location')
plot_lm_3.axes[0].set_xlabel('Fitted values')
plot_lm_3.axes[0].set_ylabel('$\sqrt{|Standardized Residuals|}$');# annotations
abs_sq_norm_resid = np.flip(np.argsort(model_norm_residuals_abs_sqrt), 0)
abs_sq_norm_resid_top_3 = abs_sq_norm_resid[:3]
for i in abs_norm_resid_top_3:
plot_lm_3.axes[0].annotate(i,xy=(model_fitted_y[i],model_norm_residuals_abs_sqrt[i]));
残差出现随机分布,这是同质性的指示。这里,误差项在自变量的所有值上都是相同的。这种同方差假设是线性回归模型的核心。
残差图
plt.figure(figsize = (20,5))
plt.plot(model_fit.resid)
plt.xlabel('Date')
plt.ylabel('Residuals')
plt.grid(True)
通过检查残差随时间变化的模式,我们还可以确认残差的同方差性质。
布鲁赫-异教徒测试
从检验统计数据和 p 值来看,两个检验都得出结论:对于我们的模型,残差具有同方差性质,p 值分别为 0.0001 和 8.21。
残差与杠杆
该图有助于我们发现异常值(如果有的话)。即使数据有极值,它们也可能对确定回归线没有影响。这意味着,如果我们在分析中包括或排除它们,结果不会有太大的不同。我们检查右上角或右下角的异常值。这些点是案例对回归线有影响的地方。
plot_lm_4 = plt.figure();
plt.scatter(model_leverage, model_norm_residuals, alpha=0.5);
sns.regplot(model_leverage, model_norm_residuals,scatter=False, ci=False,lowess=True, line_kws={'color': 'red', 'lw': 1, 'alpha': 0.8});
plot_lm_4.axes[0].set_xlim(0, max(model_leverage)+0.01)
plot_lm_4.axes[0].set_ylim(-3, 5)
plot_lm_4.axes[0].set_title('Residuals vs Leverage')
plot_lm_4.axes[0].set_xlabel('Leverage')
plot_lm_4.axes[0].set_ylabel('Standardized Residuals');# annotations
leverage_top_3 = np.flip(np.argsort(model_cooks), 0)[:3]
for i in leverage_top_3:
plot_lm_4.axes[0].annotate(i,xy=(model_leverage[i], model_norm_residuals[i]));
我们只需要找到距离大于 0.5 的杠杆作用点。在这个情节中,所有的情况都在厨师的能力范围之内。该图将有影响的观察结果标识为#245。如果我们从分析中排除第 245 种情况,斜率和 R2 值可能会大大提高。
控制过拟合的正向逐步回归
通过一步一步,我们将迭代地构建回归模型,其中涉及自变量的自动选择。Python 的 statsmodels 没有通过正向选择选择线性模型的内置方法。我从 这里 取了这段代码。我已经用 p 值阈值< 0.20 过滤了。
formula = 'cr_crude ~ cr_sp + indprod + consumer_credit + inflation_diff + ted_spread + dgs_dtb_shift'
results = smf.ols(formula, data).fit()def forward_selected(data, endog, exg):
remaining = set(data.columns)
remaining = [e for e in remaining if (e not in endog)&(e not in exg)]
exg = [exg]
scores_with_candidates = []
for candidate in remaining:
formula = '{} ~ {}'.format(endog,' + '.join(exg + [candidate]))
score = model_fit.pvalues[2]
scores_with_candidates.append((score, candidate))
scores_with_candidates.sort()
for pval,candidate in scores_with_candidates:
if pval < 0.2:
exg.append(candidate)
formula = '{} ~ {}'.format(endog, ' + '.join(exg))
model = smf.ols(formula, data).fit()
return modelmodel = forward_selected(data,'cr_crude','cr_sp')
print(model.model.formula)cr_crude ~ cr_sp + consumer_credit
可以看出,回归公式 crude ~ cr_sp + consumer_credit,表明 S&P500 和 CPI 是原油价格的唯一决定因素。
测试该模型中错误的最佳方法是不依赖模型的F-统计量、显著性或 R2,而是根据测试集评估模型。精确度通常以实际标准误差、MAPE(平均绝对百分比误差)或预测值与测试数据中的实际值之间的平均误差来衡量。
残差与拟合值
从图中,我们可以感觉到一些异常值的存在;尤其是在 2008 年相当明显。如果我们看看所有变量的 IQR 盒图,我们会有一个更好的想法。
在这里,我们可以清楚地看到一些异常值。让我们确定异常值的确切日期。
我们可以看到,两个最大的异常值出现在 2008 年 10 月和 11 月。让我们用异常值创建 5 个额外的变量,并将这些变量添加到现有的数据框中,再次运行回归。
data['nov_2008'] = np.where(data.index == '2008-11-01', 1, 0)
data['oct_2008'] = np.where(data.index == '2008-10-01', 1, 0)
data['dec_2014'] = np.where(data.index == '2014-12-01', 1, 0)
data['jan_2015'] = np.where(data.index == '2015-01-01', 1, 0)
data['apr_2000'] = np.where(data.index == '2000-04-01', 1, 0)formula = 'cr_crude ~ cr_sp + indprod + consumer_credit + inflation_diff + ted_spread + dgs_dtb_shift +nov_2008 + oct_2008 + dec_2014 + jan_2015 + apr_2000'
model = smf.ols(formula, data).fit()
model.summary()
这里,我们看到,所有增加的变量都是高度显著的 p 值< 0.05)。如果我们比较结果,我们可以看到,在这种情况下,其余变量的系数估计保持不变。重要参数保持与 indpro、dgs_dtb_shift 参数相同;可调 R2 值从 19.2%提高到 34.6%。
多重共线性
col = data[['indprod', 'consumer_credit', 'inflation_diff', 'ted_spread', 'dgs_dtb_shift']]plt.figure(figsize = (10,6))
pearsoncorr = col.corr(method='pearson')
sns.heatmap(pearsoncorr, xticklabels=pearsoncorr.columns,
yticklabels=pearsoncorr.columns,
cmap='RdBu_r',annot=True,linewidth=0.5)
这里,观察到的最大相关性是 consumer_credit 和 inddprod 变量之间的 0.37,以及 inddprod 和 inflation_diff 之间的-0.017。两者的实际价值都很小,可以忽略不计。
结论
我们使用了不同的宏观经济因素和金融变量来估计布伦特原油的月度回报是否可以考虑这些变量的意外变化。回归结果表明,原油收益率与我们选择的自变量之间存在相当小的差异。我们的统计分析表明,在我们选择用于分析布伦特原油价格月度回报的变量中,只有短期和长期美国国债收益率指数和工业生产指数的变化是显著的。然而,回归结果表明,股票收益率与所检验的宏观经济和金融变量之间不存在显著的定价关系。
接我这里。
参考:
- 高斯,卡尔·弗里德里希。[1809] 2004.天体以圆锥曲线绕太阳运动的理论。纽约州米尼奥拉:多佛。
- 陶,r .&布鲁克斯,C. (2019)。金融计量经济学导论 Python 指南。可向 SSRN 3475303 查询。
基于卡尔曼滤波的宏观经济临近预报
原文:https://towardsdatascience.com/macroeconomic-nowcasting-with-kalman-filtering-557926dbc737?source=collection_archive---------28-----------------------
未来就在眼前
临近预测新加坡的实际 GDP 增长率
根据 MTI 的预先估计,2020 年 Q1 经济预计将收缩 10.6%(季度环比,经季节调整后的年化增长率&)。他们的方法主要涉及计算 2020 年 1 月和 2 月的数据,以作为该季度 GDP 增长的早期指标。当获得更全面的数据时,还会对其进行修订。GDP 是一个滞后指标,因为它是在季度后一个月才正式发布的,这使得它现在很难用于评估经济。新加坡政府机构定期发布宏观经济数据,研究分析师一直在试图解读这些数据,以评估当前的经济状况。他们试图从噪音中分离出有意义的信号,识别数据中的共同模式,检测商业周期的波动,形成对市场走向的预期,并在新的经济数据出人意料地出现时进行调整。
宏观经济临近预报
我受到了纽约联邦储备银行工作人员 now cast 的启发,模拟了分析师在本地背景下对实际 GDP 增长进行估计的行为。临近预报依赖于系统理论中的状态空间表示,以一种依赖于其过去值和其他变量演变的方式来表示变量随时间的演变。它是处理混合频率(每月/每季度/每年)和非同步数据发布的自然表示。然后使用卡尔曼滤波和平滑算法进行临近预报。它提取时间序列数据中的共同运动作为潜在因素,使用它来估计观察数据的过去和现在的值,在新数据到来时进行校正,并立即预测变量的当前状态和值。
数据
我参考纽约联邦储备银行的文件,从新加坡统计局选择了主要的宏观经济指标。通过取对数的差/差/对数的二阶差来转换指标,使其稳定(,其中时间序列的统计特性不随时间变化),以产生更可靠的结果。
数据从 1995 年 3 月开始,到 2020 年 3 月结束(现有最新数据)。
状态空间模型
python 的“stats models . TSA . statespace . dynamic _ factor”模块根据多时间序列分析新介绍的第 18 节实现了表示和算法。
摘自多时间序列分析新入门
总的想法是,观察到的 y(经济因素)取决于未观察到的状态 z(潜在因素),其中 v 和 w 是假设为噪声的误差。h 是当前状态和当前观察变量之间的无噪声连接。b 是当前状态和过去状态之间的无声联系。G / F 表示外生变量 x 与观察到的/状态的联系。然而,我们假设上表中没有外生变量,并且它们的值的变化相互依赖。
卡尔曼滤波和平滑
下面描述了在正态条件下,根据观察和潜在因素的条件期望和方差的观察和转移方程的形式。然后使用期望最大化(EM)算法获得所有参数的最大似然估计(MLE)。
摘自多时间序列分析新入门
每一步背后的直觉如下:
- 预测:根据潜在因子的过去值估计潜在因子的当前值,根据潜在因子的当前值估计被观测的当前值。
- 校正:根据估计观测值和实际观测值的误差,更新潜在因子的当前值。误差的影响取决于卡尔曼增益,卡尔曼增益是测量的相对可变性与状态的可变性。如果测量值的可变性相对较大,则估计值的可信度较低,误差的影响也较弱。
- 预测:也是临近预测步骤,它根据当前潜在因子估计当前观测值(给出到目前为止的所有估计值)。
- 平滑:根据在每个后续步骤中对潜在因素的最终估计程度,使用回顾的全部数据来更新潜在因素的过去估计值。
结果
橙色圆点代表实际 GDP 增长,用于平滑步骤,以获得对潜在因素的更好估计。指标的变化用上表中的转换来表示。
根据我的模型,2020 年新加坡在 Q1 的实际 GDP 增长现在预测为 -5.55% (季度环比,年化&未经季节调整),而新加坡经济产业省的 -10.6% (季度环比,年化&经季节调整),以及彭博调查的经济学家预测中值 -8.2% 。2020 年 3 月的更新反映了外汇储备、国债收益率、价格水平和商业预期的大幅下降。由于最近工业生产和贸易的增长,这些更新可能呈现出稍微乐观的情景。即使这些指标可能也不能充分“实时”地反映当前市场。该模型仅限于我们输入的经济数据,最多只能估计推动我们经济的潜在力量。这个模型提出了一个系统化的方法,这个方法不受人为偏见的影响,并且有可能提供一个更加一致的替代方案来评估我们的经济。
mad Maps——可视化地理数据以获得最大影响
原文:https://towardsdatascience.com/mad-maps-visualizing-geographical-data-for-maximum-impact-d7e2b5ff2471?source=collection_archive---------29-----------------------
入门
如何使用 Python(包括代码和数据)在地图上有效地交流数据,以获得清晰、深刻的见解
美国总统大选又要来临了。毫无疑问,地图已经淹没了你的 Twitter 时间轴和新闻源,11 月 3 日之后的几周内,这种情况将会升级。
如今,我们认为地图是理所当然的,不难看出为什么。智能手机已经商品化了技术,可以准确定位我们,并提供到最近的 5 家评分至少为 4.0 的日本餐馆的实时路线。地图从未像现在这样融入我们的生活,尽管就在十年前,人们还在使用的街道目录。(颤抖)
但是,如果说谷歌地图是地图的最终进化,那将是对制图学领域的极大伤害。这与事实相去甚远,虽然有用,但这只是地图能做的的一小部分。
地图是人类智慧的杰作,可以帮助获得独特的见解,并有效地传达它们,无论是人口统计、经济、健康,还是真正的政治。
想象一下,作为一名早期的制图师,从地面精确地描绘出我们世界的表面轮廓。想象一下,你是第一批探索世界某些地区的人,并在页面上捕捉他们的形态、居民、植物和动物,以便下一批到达的人可以更安全、更快速地在世界上导航。想象一下,创造一些东西来帮助通知和指导从渔民到将军的每一个人会是什么感觉。
换句话说,制图学创造了视觉辅助工具,帮助用户在变幻莫测的数据海洋中导航,这是数据可视化更广阔领域的先驱。数据可视化的第一个已知示例之一是(霍乱爆发的)增强地图这一知识也具有某种完整循环的性质,尤其是考虑到当前的疫情和仪表板的扩散。
约翰·斯诺的霍乱爆发地图
有了这张相对简单的地图,John Snow 能够可视化疾病发病率数据,并说明爆发的中心位置(以及位于那里的水泵)很可能是霍乱病例的原因。
快进到今天,已经有惊人的数据可视化工具(如 Plotly 、 DataWrapper 或 Tableau )能够绘制出不仅信息丰富,而且视觉效果惊人的地图。
举个例子,看看这幅美国农作物的图片:
各县用于种植各种作物的土地百分比(截图:比尔·兰金
或者这张疫情期间各国政府提供的收入补助图:
OurWorldInData.Org 新冠肺炎时期的政府支持(截图:)
地图是可视化数据的真正神奇的工具。因此,在本文中,让我们来看看如何创建我们自己的地图来可视化空间数据。
在开始之前
要跟进,安装plotly
、pandas
和numpy
。用一个简单的pip install [PACKAGE_NAME]
安装每一个(在您的虚拟环境中)。
使用以下内容导入相关模块:
import pandas as pd
import numpy as np
import plotly.express as px
你可以在这里找到所有需要的数据和代码(请看draw_map.py
文件):
[## databyjp/mad_maps
此时您不能执行该操作。您已使用另一个标签页或窗口登录。您已在另一个选项卡中注销,或者…
github.com](https://github.com/databyjp/mad_maps)
我们的第一张地图
加载基础地图数据
在本文中,我们将在美国县级地图上绘制数据。要做到这一点,我们需要一个基本数据集布局县的位置。让我们使用 Plotly 推荐的 GeoJSON 文件:
from urllib.request import urlopen
import json
with urlopen('https://raw.githubusercontent.com/plotly/datasets/master/geojson-counties-fips.json') as response:
counties = json.load(response)
加载数据
一个容易获得的县级数据集是按收入分类的。我已经对数据集(来自美国人口普查)进行了预处理,并将其保存到一个数据帧中,所以只需像这样将其加载到这里:
data_df = pd.read_csv("srcdata/proc_data.csv", index_col=0)
通过运行data_df.head()
、data_df.info()
等命令,检查是否包含适当的数据和正确的行数/列数:
(数据帧应包括 3223 行,每行应包括一个 fips 代码。)
示例输出的前几行—来自。信息()方法
最简单,也是最显而易见的做法是尊重地理边界,将数据绘制到所谓的 choropleth 地图上。Choropleth 地图根据所描述的质量给每个区域着色。
这是我的例子:
我在这里做的事情很简单。数据作为第一个参数(data_df
)传递;其中fips
列和Median_Household_Income_2018
列分别作为位置和颜色数据被传递;而counties
变量是我们之前下载的 GeoJSON 数据。
update_layout
和update_traces
方法是出于美学原因而运行的;设置地图样式、缩放级别、位置和图形边距。
美国各县家庭收入的 choropleth 地图(图片:作者)
你可能已经注意到,我将这里的颜色范围设置为 0 到 100,000 之间。我选择这个值是因为 50,000 大约是数据集的中间值。它旨在使那些“中间”值看起来尽可能的中性。
这是一张好看的地图!你可以清楚地看到全国的总体趋势。
编辑: 这里有一些东西,是一个 超级乐于助人的 Redditor 能够从刚才看的地图中挑出来的( 完整评论此处 ):
看到新墨西哥州北部那个小小的蓝点了吗?那是洛斯阿拉莫斯县。它包括两个镇,其经济围绕着当地的国家实验室,该实验室雇佣了数千名科学家和工程师。洛斯阿拉莫斯的人均博士数量是所有县中最高的。
DC 地区那块巨大的蓝色区域向我们展示了美国八个最富裕的县中有五个与 DC 接壤。他们有几十个联邦机构,这些机构的雇员并不依靠良好的经济来保住他们的工作……也没有任何迎合他们的当地企业。因此,DC 是不受衰退影响的城市。
肯塔基州东部和西弗吉尼亚州南部的橙色斑点是生活贫困的下岗矿工和阿巴拉契亚人。
南达科他州的橘色地区和四角地区是印第安人保留地。这些地方长期以来遭受贫困的打击最大。
沿着密西西比三角洲和南方腹地的黑带清晰可见。农村的非洲裔美国人挣扎着维持生计,并且不成比例地患有艾滋病、糖尿病和肥胖症。
是不是很神奇?再次提醒您, 数据在上下文中无限丰富, ,并且数据来自真实的人。如果你对他们还知道什么感兴趣,你可以在这里找到评论者(亚历克斯)。
让我们更进一步。如果我们想确定某些人口统计数据,如低收入或高收入县,会怎么样?我们可以从这张地图中得到一些想法,但我们可以做得更好。
实现这一点的一种方法是过滤数据帧。由于 Plotly 将简单地忽略丢失的数据点(正如您可能已经注意到的上面那个没有颜色的县),我们甚至不需要用占位符替换丢失的值。
您会注意到代码或多或少是完全相同的。我在这里做的唯一不同的事情是过滤数据并传递过滤后的数据帧。瞧啊。
美国低收入县的 choropleth 地图(图片:作者)
我们可以做类似的改变来绘制高收入县的地图。
美国高收入县的 choropleth 地图(图片:作者)
这些地图在突出显示数据子集方面做得更好——大多数低收入县在南方,许多高收入县在沿海地区。
只绘制该数据子集的另一个优点是,通过操纵色阶,可以更容易地看到子集内的梯度。看一看:
我在这里所做的是压缩范围(到 20,000 到 40,000 之间),然后将色阶改为顺序色阶(橙色),反过来使较低的颜色更暗。下面是结果:
突出显示美国低收入县的 choropleth 地图(图片:作者)
收入较高的县也是如此,但颜色是蓝色和未绑定的颜色(因此它自然延伸到数据集的界限)。
突出显示美国高收入县的 choropleth 地图(图片:作者)
有了这些地块,收入最低的县和收入最高的县才真正能够凸显出来。
不仅仅是一匹只会一招的小马
但是可能存在其他什么模式呢?这就是 choropleth 地图开始显示其局限性的地方。它只允许一个变量被绘制到固定区域。
为了研究数据,让我们通过将数据点(县)分组来简化数据的表示;在这种情况下,根据县人口规模和家庭收入。
例如,我们可以使用pd.qcut
函数按四分位数分割县:
x = pd.qcut(tmp_df["POP_ESTIMATE_2018"], 4)
这将按县的数量对数据进行分组。然而,这可能不是我们想要的——因为较小的县在人口方面的代表性不足。
我们已经可以看到,第二个情节揭示了第一个没有的细节。虽然我们看不出地理和变量之间有太多的相关性,但后一张图显示了明显的相关性。通过这个简单的图表,我们可以看到县人口对典型收入有一些影响。
那么,我们如何将这样的数据绘制到特定的地理位置上呢?
不仅仅是大小的问题
尽管 choropleth 地图很棒,但它确实有一个很大的缺陷。T2 的大小总是很重要。由于我们的大脑自然倾向于将大小作为地图上重要性的指标,所以 choropleth 地图上每个区域的大小总是看起来很重要。即使真正重要的数字可能是,比如说,人口而不是规模。
这可能有点抽象,所以这里有一个真实的例子。这是一张世界各国的地图。我们都见过无数次了:
世界地图(图片:维基百科)
这是世界,这里的边界是根据人口来划分的。请注意某些地方,比如我的祖国(澳大利亚)是如何缩小到被遗忘的,而其他地方,比如印度尼西亚,现在却大得多。
按人口划分的世界(图片: OurWorldInData
想象用收入之类的东西给第一张地图着色,而不是用同样的东西给第二张地图着色。它们看起来会非常不同。
因此,让我们建立一个气泡图。我是泡泡图的超级粉丝;它允许我们用气泡大小来表示另一个维度的数据。
因此,本着同样的精神,让我们将我们的县地图绘制成一个气泡图,其中一个气泡代表一个县,其大小基于人口。我们不会像上面那样调整地图的大小,但是会调整绘制到地图中的内容。
在表面冒泡
第一步是为每个县选择一个位置来容纳每个泡泡。作为一个粗略的解决方案,我将选择每个 GeoJSON 形状的边界框的中心。
这需要熟悉 GeoJSON 数据格式,但是一旦你花几秒钟浏览它,你就会明白这里发生了什么。
基本上,数据是以嵌套列表的形式存在的(在字典中),所以这个脚本遍历列表以获得左下(min,min)边界和右上(max,max)坐标。随后,我们收集盒子的中心,并建立一个带有 fips 代码的数据框架。
您应该有一个如下所示的 county_df:
从那时起,抓取收入和人口数据,并绘制图表是一件小事。
我在这里选择使用[.join](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.join.html)
方法来做,然后简单地绘制数据。注意,我在这里使用的 Ploty Express 函数是scatter_mapbox
,而不是choropleth_mapbox
,但是这里的一切应该是不言自明的。
我唯一需要修改的是size_max
属性;这或多或少取决于个人喜好。
我们得到了这张漂亮的图表:
美国各县家庭收入的 choropleth 地图(图片:作者)
为了视觉效果,我压缩了这里的范围;但是这幅图与上面的完全不同,上面画的是同样的数据,没有人口。看看这个对比:
两次观想的比较——印象非常不同(图片:作者)
随着对县人口的关注,该国中部的大部分完全消失,沿海地区被突出显示。另一方面,关注县的规模会让你的目光立即投向南部各州。
我并不是说观想更好。我想指出的是,它确实强调了相同(收入)数据的可视化表示看起来会有很大不同。
作为这些图表的创作者,值得思考如何最好地支持你的信息。
作为读者,可能值得考虑的是,你可能从视觉效果中得出的结论是否真的有根据。
这只是一个旁注,但我认为在我们这个视觉世界中这是一个重要的问题。
如果你喜欢这个,在 twitter 上打招呼/关注,或者点击这里更新。ICYMI:我还写了这篇关于 Streamlit 和 Dash 的文章,这两个包非常流行,用于使用 Python 创建在线仪表盘。
[## Plotly Dash 与 Streamlit——哪个是构建数据仪表板 web 应用程序的最佳库?
用于共享数据科学/可视化项目的两个顶级 Python 数据仪表板库的比较——
towardsdatascience.com](/plotly-dash-vs-streamlit-which-is-the-best-library-for-building-data-dashboard-web-apps-97d7c98b938c)
这是另一篇关于地理数据可视化的文章——这次是可视化 NBA 旅行!
[## NBA 的 6 度分离——为什么暂停它是不可避免的
用 Python 可视化 NBA 的旅游连接链(带数据和代码)
towardsdatascience.com](/6-degrees-of-separation-in-the-nba-why-suspending-it-was-inevitable-9c646db99e4c)
保持安全;下次再见!