机器学习:解释你的模型的重要性
以及为什么它可以提高精度!
一个月前,在做另一个有趣的个人项目时,我写了一篇关于葡萄酒评级分类的文章。结论非常简单:这个模型达到了 97%的精确度,非常好。
在阅读了更多关于 ML 的文章后,我发现了这个名为 Lime 的解释库,超级好用,非常有帮助。让我们回顾一下使用这种工具的步骤和优点。
模型解释
解释该模型最简单的方法是用矢量器和 RandomForestClassifier 创建一个管道。这样,可以用几行代码运行新文本的解释:
Notebook code: From pipeline to explanation
现在,运行它将会得到以下输出:
Lime Text Explanation output
G reat,解释超级简单易懂,你可以看到哪些词影响了决定,以哪种方式等等…
但是等等,什么???我们可以看到像“在”、“的”、“在”等常用词的例子…
TfidfVectorizer 应该会降低这些常用词的权重。一种猜测是,对于小文本,这是不够的,他们仍然在决策中的权重。即使只有百分之几,这些单词也不应该被计算在内。
有什么常用词?
L 在对矢量化进行实际分类之前,让我们改进模型并删除常用词。为此,我们将使用 nltk.corpus,这是一个流行的格式库:
Getting rid of common words (stopword)
N ew 解释:
Explanation after training the model without common words
结束注释
在中,除了提高模型的总体准确性之外,解释您的模型还有助于:
- 为您的模型编写自动化测试:
您想要控制您的模型的精度- >只需安排一个运行解释和一些健全性检查的日常任务 - 证明你的模型/产品正在工作:
在投入生产之前,或者在筹集资金之前,证明你的机器学习模型正在按预期工作,这可能会有所不同。尤其是当你的产品很大程度上依赖于它的时候。
以下是本文中描述的笔记本:
- https://github . com/olivierg 13/ML-Wine-Ratings-Analysis/blob/master/notebooks/Wine _ ML _ explain . ipynb
- https://www . ka ggle . com/olivierg 13/wine-ratings-ml-explaints-using-lime
机器学习提示:使用旋转数据
可能会出现需要使用旋转数据进行预测的情况,无论是作为特征还是作为目标。将学位直接插入到你的模型中似乎可行,但是要小心,这不是你想要的。
为什么机器学习算法讨厌学位
**简单来说,他们不顺利!**我的意思是度数刻度随着它的进行从 359 度瞬移到 0 度。看:
在这种格式中,梯度下降算法不知道 350 度与 0 度相距 10 度,因此永远不会产生鲁棒的模型。
拯救罪恶与罪恶!
为了克服这些问题,我们只需将度数转换成 SIN 和 COS 并使用它们作为我们的特征。现在没有传送,距离被适当地测量:
重要的是要记住,我们可以返回到我们的度数值,因为对于每组 SIN 和 COS 值,只有一个等价的度数值。在下一节中,我将向您展示神奇的 atan2 函数,它将为您完成这种转换。
抓到一个。
一个缺点是,现在如果你想预测一个方向(即方向是你的目标特征),你必须创建两个预测器:一个预测 SIN,一个预测 COS,然后使用**atan2函数将它们组合起来。**
import numpy as npdegrees_array = np.arctan2(sin_array, cos_array) * 180 / np.pi# will be in the range -180 : 180,
# use modulo to wrap it to the range 0 : 360degrees_array_fixed_range = np.mod(degrees_array, 360)
查看使用两个预测器预测旋转值的完整示例:
机器学习类型#2
Machine Learning Type : reference
- 监督学习
Supervised Learning
在监督学习中,我们得到了数据集,并且已经知道我们的正确输出应该是什么样子。监督学习问题分为分类和回归。
- 回归:-在回归中,我们将训练数据拟合到连续函数中,并尝试在连续输出中预测结果,这意味着我们尝试将输入变量映射到某个连续函数。根据面积预测房价。这里价格是房子大小的函数,房子是连续产出。所以这是一个回归问题。
- 分类:-在分类输出中,预测离散值,如是或否、真或假、0 或 1、糖尿病与否、男性或女性、阳性或阴性等。例如在给定的健康数据中预测人是否患有糖尿病是分类的。
2。无监督学习
Unsupervised Learning : reference
与监督学习不同,我们提供数据集而不告诉数据的标签是什么(数据实际上是什么?)并要求从给定的数据集中找出结构。
聚类和鸡尾酒会算法用于发现给定数据集之间的结构。
举例:
聚类:
- Google news 使用聚类算法对与同一主题相关的新闻进行分类。
- 根据在电子商务应用中购买的物品对人进行分割是聚类算法的另一个例子。
- 以 1,000,000 个不同基因的集合为例,找到一种方法来自动将这些基因分组为在某种程度上相似或通过不同变量(如寿命、位置、角色等)相关的组。
非聚类:
- “鸡尾酒会算法”,让你在混乱的环境中找到结构。(即在鸡尾酒会上从声音网格中识别个人声音和音乐)。
3。 半监督学习
半监督学习类型利用标记和未标记的数据进行训练。半监督学习介于无监督学习和监督学习之间。
4。强化学习
强化学习是让一个主体在世界中行动以最大化其回报的问题。例如,考虑教一只狗一个新把戏:你不能告诉它做什么,但如果它做对/错的事情,你可以奖励/惩罚它。它必须弄清楚它做了什么使它得到了奖励/惩罚,这就是众所周知的信用分配问题。我们可以使用类似的方法来训练计算机完成许多任务,例如玩双陆棋或象棋,调度作业,以及控制机器人肢体。
Reinforcement Learning :- reference
机器学习中使用的算法类型
机器学习类型和算法
不同类型的机器学习类型和算法,以及何时何地使用它们。
先决条件: 需要进行机器学习? ( 便于理解 )
Machine Learning
常用术语:
- 带标签的数据: 它由一组数据组成,一个例子将包括一个文件夹中所有带标签的猫或狗的图像,所有基于大小的房屋价格等。
- 分类: 分成有确定值的组,例如 0 或 1,猫或狗或橙等。
- 回归: 估计变量间最可能的值或关系。根据面积对房子价格的估计。
- 关联: 在大型数据库中发现变量间有趣的关系,其中发现的关联至关重要。
有四种类型的机器学习*(有些人可能会说三种,但在这里我们将使用四种 越多越好,对吗!!! ”)。*
- 监督学习:"给定输入的结果或输出在它本身" 之前是已知的 ,机器必须能够将给定输入映射或分配到输出。一只猫,狗,桔子,苹果等的多个图像,这些图像都有标签。它被输入到机器中用于训练,并且机器必须识别它。就像一个人类小孩看到一只猫并被告知如此,当他在其他猫中看到一只完全不同的猫时,仍然把它识别为一只猫,同样的方法在这里被使用。
Supervised learning examples
关键点:
- 回归和分类 问题主要在这里解决。
- 标注的数据 在这里用于训练。
- 流行算法: 线性回归、支持向量机(SVM)、神经网络、决策树、朴素贝叶斯、最近邻。
- 它主要用于 预测建模 。
2。无监督学习:“给定输入的结果或输出未知”,* 这里输入数据给定,模型在其上运行。给定的图像或输入在这里被组合在一起,关于输入的见解可以在这里找到(这是最真实的可用数据)。主要算法有 聚类算法( )和 学习算法。*
grouping of similar data
关键点:
- 它用于 聚类问题( 分组 )、异常检测(银行中的异常交易) 需要找到给定数据之间的关系。
- 无标签数据 用于无监督学习。
- *流行算法: *k-means 聚类,关联规则。
- 它主要用于 描述性建模。
***3。半监督学习:*介于 监督和非监督学习 之间。其中组合用于产生期望的结果,并且在所有可用数据都是 标记和未标记数据 的组合的真实世界场景中是最重要的。
***4。强化学习:*机器被暴露在一个 环境中,在那里它通过试错法 得到训练,在这里它被训练做出一个更加具体的决定。机器从过去的经验中学习,并试图捕捉最好的可能知识,以根据收到的反馈做出 准确的决策 。
Reinforced Learning workflow
关键点:
- 基本强化被模拟为 马尔可夫决策过程
- 这里最常用的算法是 Q-Learning , 深度对抗网络。
- 其实际应用包括电脑玩棋类游戏如 象棋 和围棋自动驾驶汽车也使用这种学习。
简而言之,请查看下图
Machine Learning Types
更多参考文献:
接下来我有 机器学习实现示例 5 分钟后 接下来请务必关注我的 中LinkedInTwitter如果你喜欢这篇文章,请鼓掌并分享它。****
在这里加入我们的 WhatsApp 社区。
机器学习:使用小词
我喜欢异端这个词。这是一种很酷的说法“跳出框框思考,反对主流”。它很好地描述了当很少有研究人员相信这种方法时,Hinton 和其他人如何推进深度学习研究。像异端邪说这样的大词让我想到用更小的词和更简单的词来描述我们所做的事情。
我们在深度学习人工智能方面做的,和人们认为我们做的,差距很大。在最近的一次机器学习活动中,另一家公司的一名高级研究科学家让我很不爽,因为他不相信马文·明斯基和他那一代人在几十年前开创了人工智能领域。客户不关心这些东西。就我个人而言,我更喜欢艾伦·图灵,但他的观点很公平。从 20 世纪 90 年代开始,我通常会想到辛顿、本吉奥和勒村等等。我钦佩的人是那些在失去所有希望时仍有梦想的人;像辛顿、尼克·博斯特伦和埃隆·马斯克这样默默无闻的人。我们这些技术型的人倾向于带着一种技术来参加舞会,直奔有刺的潘趣酒,然后立刻抛弃我们的约会,去找房间里最热门的技术。以这种方式经营有正当的理由,但可能有点残酷。在学术界之外,如果你过于怀旧和忠于旧技术,你很快就会变得无关紧要。问问你的铁匠就知道了。
在机器学习时代,历史发展得太快,几乎无法跟上,我们的客户依赖我们作为顾问来提取关键信息和能力,而不是给他们一个历史背景。我花了很多时间学习最新的东西。
过去几年来,我一直非常关注深度学习的进展,现在,在被深度学习超越所有其他技术的意外成功击败和血洗之后,正统数学和统计学的“旧”智慧正在悄悄回归主流。“真正的”数学家正在夺回汽车的控制权。我认为从现在开始机器学习的改进将遵循类似于软件编译器的分布模型。数学专家将制作新的魔盒,我们可以在像 Keras 这样的框架中使用,类似于 gcc 编译器的贡献者如何将接口暴露给高级语言并抽象掉所有低级的东西。
事实证明,进步不止朝着一个方向发展。有新类型的神经架构(例如 Hinton 的胶囊网络与 s .卷积网络),但也出现了最先进的“旧”模型,用作我们现有模型的升级。例如,新的贝叶斯 BNN 通过网络传播不确定性,而不仅仅依赖于网络输出的梯度损失。这比 DNN 模型强大得多,因为我们可以对事情的概率做出断言,而不是谈论模型与数据的吻合程度。在 DNN 中测量损失的问题在于,它会导致对训练数据的过度拟合,而不是对数据集进行概化。数据科学已经发明了对抗过度拟合的方法,但基本思想是,反向传播标量输出上的梯度是不足以谈论我们对深度学习系统的答案有多确定的信息。这留下了仍然真实存在的大错误的可能性,例如对深度学习系统的像素攻击。
Examples of a good model with some error (left) and an overfitting model with lower error (right). Credit: https://www.cse.unsw.edu.au/~cs9417ml/MLP2/BackPropagation.html
像甘一样,是对的改进,因为它模拟了真实世界的东西,这是不确定的,并遵循概率密度曲线:概率分布。与较新的深度学习材料相比,变量的联合概率是旧的,然而通过提供不确定性测量,BNN 提供了比简单地最小化/观察模型误差更好的模型。我猜深度学习的异端邪说有它的局限性,钟摆现在摆回到有利于纯数学的家伙(和女孩)身上,他们将应用一个巨大的经典数学方法库来击败深度学习,使其从它所占据的霸道地位上退下来。我认为,从大的方面来看,新方法将会增强,而不是削弱现有的深度学习技术。这是一个激动人心的时刻。
从基础 R&D 的飞速发展中退一步,想想我们如何用不那么复杂的语言来表达这些来自研究界的简单想法。作为一名研究深度学习技术的工程师,我认为大型组织是时候将深度学习视为认知计算策略的一个组成部分,而不是一种数据建模工具。这种全面的数据方法包括融合内部企业数据和外部开源数据,然后使用工作流和深度机器学习生成见解。要做到这一切,你不需要华丽的词藻。相反,你需要从数据中获得洞察力。我在 LinkedIn 上看到一个很好的引用,称之为“自我意识数据”。不知何故,许多公司都忘记了,尽管机器学习在从数据中学习方面非常出色,但公司仍然需要理解并利用数据来洞察和采取行动,而不是数字。
采用机器学习的企业应该考虑 ML 是更大的企业工具箱的一小部分。BNNs 之类的“东西”代表工具箱 ML 隔间里的新扳手。但是不要被工具箱里闪亮的扳手分心。你关心的是用工具箱来修补漏洞和制造高速汽车。没人在乎你冲过终点线时用的是什么扳手。
当你开发了一个新的模型,可以综合你不知道的信息,这总是很棒的。不只是拟合数据,你会学到一些新的和意想不到的东西。我计划写更多关于认知计算以及它如何改变做生意的方式。
在那之前,编码快乐!
-丹尼尔
丹尼尔@lemay.ai ←打个招呼。
LEMAY . AI
1(855)LEMAY-AI
您可能喜欢的其他文章:
机器学习 vs .人工智能
它们并不相同,但通常可以互换使用
Photo by Joshua Sortino on Unsplash
在实践中:机器学习和 AI 互换使用**。**通常这两个词都用来表示 监督学习 。
理论上:机器学习是 AI 的一个子领域:一种实现 AI* 的*方式。
机器学习和人工智能:对不同的人有不同的意义
很大一部分困惑是——取决于你和谁交谈——机器学习和人工智能对不同的用户有不同的含义。
现在,人工智能是一个比机器学习更性感的术语,所以在媒体和市场营销中,人工智能(AI)是最常用的术语。但是媒体所指的人工智能的范围非常广泛:
- 专家系统
- 工序自动化
- 机器学习
- 深度学习
- 强化学习
- …以及更多
有趣的一面:媒体上关于人工智能的话题越热,它在商业中的实际应用就越少。
媒体上最热门的话题往往对企业最没有价值。这些通常仍是研究案例,很少用于日常应用。
学术界
对于学者和研究数据科学的人来说,机器学习是更大的人工智能领域的一个子领域。
人工智能指的是一个非常大的研究领域,包括许多旨在开发能够学习和解决问题的计算机的技术:
- 计算机视觉
- 监督和非监督学习
- 强化学习和遗传算法
- 自然语言处理
- 机器人技术(运动)
- …
机器学习是人工智能领域,涉及自行从数据中学习。
商业
在商业上,人工智能和机器学习通常指同一个东西。为什么?因为 AI 的大部分商业应用相当于监督学习,是机器学习的一个子领域。
所以实际上,商业中的AI和商业中的机器学习基本是一回事。
所以…这取决于你问谁
- 机器学习是人工智能的一个子领域。
- 然而,在实践中,使用这两个术语的人往往表示同一个意思。
- 特别是在商业环境中,你可以使用这两个术语来指代能够自己从数据中学习的机器。**
最初发表于T5【www.datarevenue.com】*。*
机器学习与深度学习
人工智能包含非常广泛的范围。你甚至可以将 Dijkstra 的最短路径算法视为人工智能。然而,有两类人工智能经常被混淆:机器学习和深度学习。这两者都是指数据的统计建模,以提取有用的信息或进行预测。在本文中,我们将列出这两种统计建模技术不同的原因,并帮助您进一步构建对这些数据建模范例的理解。
概观
机器学习是一种统计学习方法,其中数据集中的每个实例都由一组特征或属性来描述。相比之下,术语“深度学习”是一种从原始数据中提取特征或属性的统计学习方法。深度学习通过利用具有许多隐藏层的神经网络、大数据和强大的计算资源来实现这一点。这些术语似乎有些可互换,但是,使用深度学习方法,算法会自动构建数据的表示。相比之下,数据表示在机器学习算法中被硬编码为一组特征,需要进一步的处理,如特征选择和提取(如 PCA)。
这两个术语与另一类被称为基于规则的系统的经典人工智能算法形成了鲜明对比,在基于规则的系统中,每个决策都是以类似于统计模型的方式手动编程的。
在机器学习和深度学习中,有许多不同的模型,分为两个不同的类别,有监督的和无监督的。在无监督学习中,k-Means、层次聚类和高斯混合模型等算法试图学习数据中有意义的结构。监督学习涉及与数据集中的每个实例相关联的输出标签。该输出可以是离散的/分类的或实值的。回归模型估计实值输出,而分类模型估计离散值输出。简单的二元分类模型只有两个输出标签,1(正)和 0(负)。被认为是**机器学习的一些流行的监督学习算法:**有线性回归、logistic 回归、决策树、支持向量机、神经网络,还有 k 近邻等非参数模型。
数据量
机器学习和深度学习都能够处理大规模的数据集,然而,机器学习方法对小数据集更有意义。例如,如果你只有 100 个数据点,决策树、k 近邻和其他机器学习模型对你来说将比在数据上拟合深度神经网络更有价值。这是由于下一个话题的差异,可解释性。
可解释性
对深度学习方法和机器学习算法的许多批评,如支持向量机或(也许,因为你至少可以可视化组成输出的成分概率),朴素贝叶斯,是因为它们难以解释。例如,当卷积神经网络在狗与猫的问题中输出“猫”时,似乎没有人知道它为什么这样做。相比之下,当您使用机器学习技术对电子健康记录或银行贷款数据集等数据进行建模时,理解模型预测的推理要容易得多。
可解释性的一个最好的例子是决策树,你可以沿着树的节点进行逻辑测试,直到你做出一个决定。另一种具有高解释性的机器学习算法是 k-最近邻算法。这不是参数学习算法,但仍然属于机器学习算法的范畴。这是非常有可解释性的,因为你很容易为自己推理类似的例子。
结论
总之,上图是对深度学习和机器学习区别的最好概括。一个具体的例子是考虑原始数据形式,如图像中的像素或音频中的正弦波。机器学习方法很难从这些数据中构建语义特征。因此,深度学习方法在这些模型中占主导地位。深度学习还带来了比经典机器学习方法更多的细微差别和无法解释的现象。请告诉我这篇文章是否有助于框定你对机器学习相比深度学习的理解,谢谢你的阅读!
CShorten
Connor Shorten 是佛罗里达大西洋大学计算机科学专业的学生。对人工智能、计算机视觉、软件工程和生物信息学感兴趣。
机器学习-什么,为什么,何时和如何?
最近,很多人开始问我机器学习是怎么回事。今天,我正在写我和我姐姐帕里关于机器学习的最令人恼火的聊天记录之一。Parry 在信息领域有 8 年的经验,而我有 4 年的行业经验。
什么?
帕里:那你最近在忙什么?
我:没事就练机器学习。
帕里:嗯,这是每个人都在谈论的时髦词。你能让我知道这是怎么回事吗?
我:机器学习就是从数据中学习。
帕里:从数据中学习?我不明白。你在和一个门外汉说话,所以请用简单的术语说。我:假设你要去打保龄球,这是你的第一天,那么你认为你会如何表现呢?
帕里:我觉得很糟糕,我记得第一次打保龄球时,我把所有的球都扔到了沟里。我:那今天呢?
帕里:嗯,今天我想我可以轻松地一杆拿下至少 7 分。但是这和机器学习有什么关系呢?
我:我来解释,但是你是怎么提高你的游戏的?
帕里:嗯,很简单。我练习,随着时间的推移,我获得了经验,我知道我需要调整我投球的角度。此外,我需要选择一个更轻的球,以提高精确度。我:嗯,所以随着时间的推移,你通过调整一些参数获得了经验,你的比赛也得到了提高。对吗?这是机器学习。
就某类任务 T 和性能测量 P 而言,如果由 P 测量的计算机程序在 T 任务中的性能随着经验 E 而提高,则称该计算机程序从经验 E 中学习。
帕里:嗯,好!但是机器是如何体验的呢?他们不是人类!
我:对,数据:)经验 E 对应历史数据。任务 T 是一次击中靶心,P 是一次掉落的瓶数!
帕里:嗯,但是你说学习是什么意思?机器也没有大脑。我:没错,这就是数学的用武之地!机器通过一些复杂的数学概念来学习,它们的每个数据都是 0 和 1 的形式。我们不想为我们的程序编写逻辑代码,相反,我们希望机器能够自己从数据中找出逻辑。
Parry:你说我们不需要编写逻辑代码是什么意思?
我:我们不需要像用其他编程语言那样编写硬编码规则。例如:假设我有这个关于公司员工工资的小数据:
Figure 1. Experience-Salary Dataset
现在如果你需要从这些数据中发现什么,你能推断出什么?
帕里:我可以观察到,当经验少于等于 10 年时,这个人的工资是经验的 1.5 倍,当经验从 10 年增加时,这个系数增加到 2。
我:正确你将如何编码?比如你需要预测一个有 8 年 16 年经验的人的工资?
招架:
if (experience < = 10)
{ salary = experience * 1.5 * 100000}
else if(experience >10)
{ salary = experience * 2 * 100000}
我:我们这里不这样!我们不用 ML 写 if,else,因为我们不专注于写算法。
Parry:但是这很简单,甚至我都能找出数据中的关系。
我:嗯当问题的规模增大时,现在说:
Figure 2. Complex Dataset with more Features
现在,你能找到经验、工作级别、稀有技能和薪水之间的关系吗?
帕里:现在有点困难!我:这就是机器出现的地方!您在前面的示例中刚刚计算的 1.5 或 2 的因数称为重量!
Figure 3. Features(In Yellow) and Label (in Red)
黄色栏称为特性,红色栏称为标签。因此,我们计算决定标签的特征的权重。
所以我们使用机器学习来找出一个员工的工资多少取决于经验、工作级别和技能。基本上:
Salary = Experience * Magic_Number_1 + JobLevel * Magic_Number_2 + Skill * Magic_Number_3 + Magic_Number_4
因此,ML 将根据您使用的算法计算幻数!
帕里:但是你刚才说我们不编码算法,我们关注的是数据。
我:其实数据+算法=见解。算法已经为我们开发出来,我们需要知道何时使用哪种算法。这只是机器学习的一种类型,这个领域太大了,有很多数学:)
帕里:好吧,但是再见!我数学零分。这对我没用!我为什么要担心?我已经是 8 年经验丰富的 Informatica 开发人员,对此我很高兴!
为什么?
我:你每天用脸书多少小时?
招架:每日 1 小时左右。我:你知道脸书在用机器学习给你上传的照片中的朋友加标签吗?你知道脸书会根据你的兴趣历史显示定制的视频推荐吗?
Figure 4. Face Tagging in Photos Source
帕里:哦!这是不是所有的新闻提要都不一样的原因?
我:没错,脸书根据历史资料和 ML 当然知道你的好恶:)。你用的是哪个邮箱?
帕里:我正在使用 GMail。我:你知道 gmail 是如何知道某封邮件必须发送到优先邮件、社交邮件、推广邮件或垃圾邮件箱的吗?
帕里:明明是你的机器学习!我:阿雅,它有数百万封被用户标记为特定类别的邮件。因此通过使用 ML,他们观察模式并相应地分类。就连你今天用的键盘都是用 ML 来预测你的下一个单词。
帕里:是吗?我们是否在每次输入时都向谷歌提供数据?
我:是的,谷歌正在做一些令人惊讶的事情!一个这样的例子是在谷歌 IO 2018。看一看。
帕里:太好了!因此,谷歌将莫尔斯电码整合到谷歌键盘中,由于大量翻译数据的存在,它知道现在的转换。
我:是啊!你使用哪个网站购物?
帕里:亚马逊!太神奇了!
我:它神奇但最神奇的是亚马逊的推荐!
Parry:就像我们有视频推荐一样,我们有使用机器学习的产品推荐?我:没错,但是这里的转换率很重要。亚马逊的推荐引擎为它带来了近 350 亿美元的收入!
帕里:哦,天哪!这还不到我现在工作的公司的年收入。
我:你看这就是机器学习的魔力。听说过我们在超市购物不用再排队了吗
帕里:是吗?怎么会?
我:亚马逊 Go!
帕里:太好了!这解决了我大部分的购物问题!!我:那么我们现在在哪里看这个视频呢?
帕里:当然是 YouTube 了!你是在 youtube 上给我推荐的例子吗?
我:没有这次有点困难!你知道 1 分钟内 youtube 上传了多少小时的内容吗?大胆猜测一下
招架:嗯!10?
我:已经接近 500 小时了!你认为 YouTube 有这么多员工,他们可以审查这么多内容的裸体、暴力和版权吗?
帕里:Omg!不,一点也不!我:当问题的规模增加,我们有更多的数据时,机器是我们最后的希望,这就是为什么我们需要人工智能!
帕里:太好了!但所有这些公司都是四大,我的公司永远不会使用这项技术,所以为什么这是更重要的!
我:机器学习不仅仅是一个时髦词,而是一种神奇的技术,可以看到肉眼看不到的东西。你认识这个人吗?
Figure 5. Omar Bin Sultan, Minister of AI, UAE. Source
帕里:不,他是谁?
我:他是阿联酋人工智能部长奥马尔·本·苏丹!
帕里:什么?艾部长?我:他们现在是世界石油供应的领导者,而且石油至少可以使用 100 年,所以为什么他们需要一个 AI 部长?
帕里:也许人工智能是新的石油?
我:哈哈。如果到 2030 年,埃隆·马斯克的愿景成为现实会怎样?如果到 2030 年我们有了电动汽车、电动轮船和电动飞机会怎么样?
帕里:石油需求将会下降!我:没错,这就是他们投资未来技术的原因,所以如果明天石油需求下降,他们有比石油更大的东西来供应整个世界:)
什么时候?
帕里:太好了!告诉我更多关于这项新技术的信息。
我:新技术?这项技术出现于 1959 年。
帕里:什么?这么老的技术?那它为什么不早点长出来呢?
我:若干局限。一个是缺乏数据,另一个是存储数据的成本,另一个是缺乏计算能力。
招架:算力?所以你的意思是我们没有硬件来执行这些机器学习程序?我:没错,机器学习程序是硬件密集型的,因为它们包括大量密集的数学计算,如矩阵乘法等等。随着 GPU 的出现,TPU 和更快的处理器计算不再那么耗时。
Figure 6. GPU computing by NVIDIA has added new power to computational capabilities. Source
帕里:好!你提到缺乏数据?
Me:从 20 世纪 90 年代开始,数据以指数级的速度增长。随着像摄像头这样的传感器的使用增加,数据每天都在增长,数据越多,我们就能从数据中学到越多。
帕里:太好了!显然,海量数据带来了存储问题,对吗?
我:以前是,现在不是了。当云出现时,它解决了许多问题,其中最重要的是数据的存储成本。如今,如果你想在 AWS 上存储 50TB 的数据,大约需要 1200 美元,而在 20 年前,这一成本可能高达近百万美元。
Figure 7. Cloud Computing for storing data. Source
帕里:好!现在我明白了为什么它没有早点长出来。但既然是现在市场上的流行语,那你觉得这项技术的未来会怎样?
我:就回答我 3 个问题!
帕里:我?当然去吧!我:你认为在未来的时间里,数据会增加还是减少?
招架:增幅,很明显!
我:好!你认为在未来的时代,计算能力会增加还是减少?
招架:明显增加,机器一天天变好。
我:爽!你认为在未来的时间里,数据的存储成本会增加还是减少?
招架:明显减少!
我:那么结论是什么?
帕里:好!有了更多的数据、更强的计算能力和更低的数据存储成本,我们将能够推动构建数据驱动型产品。我想你只想听这个?
我:没错,未来是属于那些把数据变成产品的公司或者人的:D
怎么会?
帕里:我超级兴奋!说说这方面怎么入门?我擅长编程,我会在一个月内涵盖一切!
我:一个月内?回去继续你的信息。
帕里:等等!发生了什么事?
我:一个月不够机器学习。我不是打击你的积极性,但这是事实。在当今世界,我们试图快速学习一切,但这需要时间,因为这是一个研究领域,这不是 Java。net,你可以在一个月内学会,这是纯粹的数学和科学的结合,它需要你潜入海洋深处未被探索的领域。
帕里:所以你的意思是说我太老了,现在不能开始了?
我:一点也不,这是开始机器学习职业生涯的绝佳时机,即使你是大一新生,10 年经验或 20 年经验。我想向你解释的一点是,感受你正在做的事情,并有耐心。在做机器学习的时候,你觉得最重要的是什么?
帕里:当然是数据!
我:错!这是问题陈述。专注于你试图解决的问题,而不是算法或数据!
帕里:如果你的说教结束了,请你告诉我该如何开始,否则我会打断你的牙齿。我:对不起,我得去看世界杯了。有志者事竟成!
帕里:你这样是不行的!告诉我!
我:好的,搜索吴恩达,从他的机器学习课程开始。但请先刷新一下你对概率、统计、线性代数的概念。
我有一个关于如何在不到 100 美元的时间内过渡到 ML 领域的计划,我将很快与大家分享(在即将到来的帖子中)。
帕里:我应该现在就开始还是等到你告诉我完整的计划?
我:
冬天来了!别等了,不然就来不及了!现在就开始!!
那都是乡亲们!请留下您宝贵的评论/掌声,或者在 LinkedIn 上与我联系,对本文提出改进/建议。
[## HARVEEN SINGH——专业程序员——Infosys | LinkedIn
查看 HARVEEN SINGH 在全球最大的职业社区 LinkedIn 上的个人资料。哈文有 4 份工作列在…
linkedin.com](http://linkedin.com/in/harveenchadha)
机器学习:从哪里开始…
简介
在谷歌上搜索任何跟有“机器学习”一词的东西,都会得到一个庞大而令人生畏的资源列表,尤其是当你是从商业角度出发或者刚进入这个领域的时候。
我经常看到一页纸的机器学习“备忘单”,上面有选择算法的流程图。我喜欢这个概念,但他们假设先验知识,迎合那些已经精通可能的算法。
这就是这个工具的灵感来源。它不是直接一头扎进数学和算法的世界,而是从询问你试图解决什么样的问题开始。通过首先确定你想要达到的目标,你可以缩小寻找解决方案的范围。
一旦做出选择,该工具将介绍您可能希望在概述最常用算法之前探索的技术类型。
它并不完整,而是向读者介绍概念和术语的起点。我希望这是对好奇的头脑的欢迎,并可以在那些对该领域感兴趣的人和他们的数据科学同事或朋友之间架起一座桥梁。
网上有很多很好的资源,可以提供更多的细节。这个工具的目标是激励,甚至是授权,让你继续探索数据科学这个不可思议的世界!
框架—算法浏览器
所以在这里,享受吧!
注意:这也是一个正在进行的项目,我们希望根据社区的反馈进行迭代。请在这里分享想法或者报告 bug:算法浏览器 github repo
静态页面
如果你想在框架之外参考这个工具的内容,下面的文章会介绍这些内容
非常感谢
尽管我喜欢使用数据科学领域之外的各种技术和工具,但对我来说,寻求前端开发方面的帮助无疑是明智的。我想感谢山姆·罗斯的伟大工作(和耐心!)将我的原始想法转化为更易消费、更精简、更美观的东西。同样,我的绘画技巧还有很多地方需要改进,所以感谢玛丽·金给这部作品增添了艺术魅力!
使用 IBM PowerAI 的机器学习中的图像分类基础(第 1 部分)
介绍
图像分类已经成为展示机器学习的关键试点用例之一。在这篇短文中,我试图描述如何使用 IBM PowerAI 实现这样一个解决方案,并在 IBM Power 系统上运行时比较 GPU 和 CPU 的性能。
人工智能
人工智能目前被视为计算机科学的一个分支,它处理让计算机执行像视觉识别、语音识别、认知决策、语言翻译等传统上被认为是人类智能的任务。
机器学习
机器学习通常被视为人工智能的一种应用,它致力于赋予系统学习和根据经验改进的能力,而无需显式编码所有任务。
深度学习
深度学习是机器学习的一个子集,其中系统可以利用带标签的训练数据(有监督的)或无标签的训练数据(无监督的)进行学习。深度学习通常使用分层的人工神经网络来执行任务。
人工神经网络
人工神经网络是受生物神经网络启发的系统,可以以惊人的精度执行某些任务,如图像分类。例如,对于图像分类,给动物的一组图像提供标记。这是训练数据。人工神经网络通过一系列步骤(或层),帮助系统学习将未标记的图像(本文所示示例中的猩猩图像)分类为属于某个群体的能力,同时得出准确度分数。
深度学习在你的业务中有几个应用,从手机个人助理到自动驾驶汽车,快速变化的模式被用于实时分类物体。
什么是 IBM PowerAI?
IBM PowerAI 软件让您可以在包含 GPU 的 IBM POWER9 服务器上轻松运行所有流行的机器学习框架。CPU 是为串行处理而设计和构建的,包含少量内核,而 GPU 可以包含数千个更小的内核,并依赖于任务的并行处理。用于机器学习的任务是 GPU 的关键应用。看看 IBM Power System AC922 服务器,它被吹捧为市场上运行企业人工智能任务的最佳服务器之一。IBM PowerAI 目前包括以下框架;
Source: https://www.ibm.com/us-en/marketplace/deep-learning-platform
当前设置
对于这个演示,我在一个运行 Ubuntu on Power 的虚拟机上使用了一个容器( ppc64le ),托管在 Nimbix Cloud 上。
容器是图像的运行实例。映像是包含操作系统、软件和应用程序代码的模板,所有这些都打包在一个文件中。使用 Dockerfile 定义映像,docker file 是配置映像的步骤列表。构建 Dockerfile 是为了创建一个映像,运行这个映像是为了获得一个运行容器。要运行映像,您需要在虚拟机上安装和配置 Docker 引擎。
这是我用过的 Dockerfile ,由 Indrajit Poddar 编写。这摘自 this Github 页面。
这用 Jupyter Notebook、iTorch 内核(我们将在第二部分讨论)和一些基本 TensorFlow 示例构建了一个映像。
TensorFlow 是一个面向机器学习应用的开源、可扩展库,基于可以构建和执行的数据流图的概念。一个图可以包含两个部分,节点和边(或张量)。它附带了一个 Python API,很容易组装网络、分配参数和运行训练模型。
以下步骤由英德拉吉特·波德达尔演示。他在 Nimbix Cloud 上构建了一个测试映像,该映像将在部署后几分钟内运行上述服务。
以下命令用于验证 GPU 是否连接到容器。
root@JARVICENAE-0A0A1841:/usr/lib/nvidia-384# **nvidia-smi**Thu Feb 1 23:45:11 2018+ — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — -+| NVIDIA-SMI 384.111 Driver Version: 384.111 || — — — — — — — — — — — — — — — -+ — — — — — — — — — — — + — — — — — — — — — — — +| GPU Name Persistence-M| Bus-Id Disp.A | Volatile Uncorr. ECC || Fan Temp Perf Pwr:Usage/Cap| Memory-Usage | GPU-Util Compute M. ||===============================+======================+======================|| 0 Tesla P100-SXM2… Off | 00000003:01:00.0 Off | 0 || N/A 40C P0 42W / 300W | 299MiB / 16276MiB | 0% Default |+ — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — -+| Processes: GPU Memory || GPU PID Type Process name Usage ||=============================================================================|+ — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — -+
我看到一个英伟达特斯拉 P100 图形处理器连接。以下命令显示了已安装的 Jupyter Notebook 实例以及稍后将用于身份验证的相关令牌。
root@JARVICENAE-0A0A1841:/usr/lib/nvidia-384# jupyter notebook list
Currently running servers:
[http://0.0.0.0:8889/?token=d0f34d33acc9febe500354a9604462e8af2578f338981ad1](http://0.0.0.0:8889/?token=d0f34d33acc9febe500354a9604462e8af2578f338981ad1) :: /opt/DL/torch
[http://0.0.0.0:8888/?token=befd7faf9b806b6918f0618a28341923fb9a1e77d410b669](http://0.0.0.0:8888/?token=befd7faf9b806b6918f0618a28341923fb9a1e77d410b669) :: /opt/DL/caffe-ibm
[http://0.0.0.0:8890/?token=a9448c725c4ce2af597a61c47dcdb4d1582344d494bd132f](http://0.0.0.0:8890/?token=a9448c725c4ce2af597a61c47dcdb4d1582344d494bd132f) :: /opt/DL/tensorflow
root@JARVICENAE-0A0A1841:/usr/lib/nvidia-384#
开始图像分类
什么是咖啡?
Caffe (用于快速特征嵌入的卷积架构)是在伯克利视觉和学习中心开发的。它是一个用于执行图像分类等任务的开源框架。它支持 CUDA ,卷积神经网络,具有预训练的模型,因此是这个演示的一个好选择。
我们将使用 Python 来执行所有的任务。以下步骤是通过 Jupyter 笔记本完成的。首先,让我们设置 Python、 Numpy 和 Matplotlib 。
import numpy as npimport matplotlib.pyplot as plt# display plots in this notebook%matplotlib inline# set display defaultsplt.rcParams[‘figure.figsize’] = (10, 10) # large imagesplt.rcParams[‘image.interpolation’] = ‘nearest’ # don’t interpolate: show square pixelsplt.rcParams[‘image.cmap’] = ‘gray’ # use grayscale output rather than a (potentially misleading) color heatmap# Then, we load Caffe. The caffe module needs to be on the Python path;# we’ll add it here explicitly.import syscaffe_root = ‘../’ # this file should be run from {caffe_root}/examples (otherwise change this line)sys.path.insert(0, caffe_root + ‘python’)import caffe
什么是咖啡因?
Caffenet 是一个卷积神经网络,用来与 CUDA 接口,主要目的是对图像进行分类。Caffenet 是 Alexnet 的变种。Alexnet 的创建者在 2015 年做了一个展示,这里是。在下面的代码中,我们下载了一个预先训练好的模型。
import osif os.path.isfile(caffe_root + ‘models/bvlc_reference_caffenet/bvlc_reference_caffenet.caffemodel’):print ‘CaffeNet found.’else:print ‘Downloading pre-trained CaffeNet model…’!../scripts/download_model_binary.py ../models/bvlc_reference_caffenet
这是输出。
CaffeNet found.
Downloading pre-trained CaffeNet model...
…100%, 232 MB, 42746 KB/s, 5 seconds passed
然后,我们在 CPU 模式下加载 Caffe,并进行输入预处理。
caffe.set_mode_cpu()model_def = caffe_root + ‘models/bvlc_reference_caffenet/deploy.prototxt’model_weights = caffe_root + ‘models/bvlc_reference_caffenet/bvlc_reference_caffenet.caffemodel’net = caffe.Net(model_def, # defines the structure of the modelmodel_weights, # contains the trained weightscaffe.TEST) # use test mode (e.g., don’t perform dropout)
用的是 Caffenet 的‘caffe . io . transformer’。这是所有示例中使用的默认转换器。它根据提供的输入为图像创建一个变换的平均值。Caffenet 被设置为获取 BGR 格式的输入图像,其值在 0 到 255 的范围内。执行转换以加载 RGB 格式的值在 0 到 1 范围内的图像,作为 Matplotlib 所需的输入。
# load the mean ImageNet image (as distributed with Caffe) for subtractionmu = np.load(caffe_root + ‘python/caffe/imagenet/ilsvrc_2012_mean.npy’)mu = mu.mean(1).mean(1) # average over pixels to obtain the mean (BGR) pixel valuesprint ‘mean-subtracted values:’, zip(‘BGR’, mu)# create transformer for the input called ‘data’transformer = caffe.io.Transformer({‘data’: net.blobs[‘data’].data.shape})transformer.set_transpose(‘data’, (2,0,1)) # move image channels to outermost dimensiontransformer.set_mean(‘data’, mu) # subtract the dataset-mean value in each channeltransformer.set_raw_scale(‘data’, 255) # rescale from [0, 1] to [0, 255]transformer.set_channel_swap(‘data’, (2,1,0)) # swap channels from RGB to BGR
换句话说,计算机现在可以通过首先将图像转换为 RGB 值的数组来学习对图像进行分类。然后,扫描这些值以寻找已经与预训练模型中的另一个图像相匹配的值的模式。在比较时,会生成置信度度量,显示分类的准确程度。
这是输出。
mean-subtracted values: [(‘B’, 104.0069879317889), (‘G’, 116.66876761696767), (‘R’, 122.6789143406786)]
分类
这里,我们设置图像的默认大小。这可以根据您的输入进行更改。
net.blobs[‘data’].reshape(50, # batch size3, # 3-channel (BGR) images720, 720) # image size is 720x720
接下来,我们从 Wiki Commons 库中加载一只猩猩的图像。
# download the imagemy_image_url = “https://upload.wikimedia.org/wikipedia/commons/b/be/Orang_Utan%2C_Semenggok_Forest_Reserve%2C_Sarawak%2C_Borneo%2C_Malaysia.JPG" # paste your URL here!wget -O image.jpg $my_image_url# transform it and copy it into the netimage = caffe.io.load_image(‘image.jpg’)transformed_image = transformer.preprocess(‘data’, image)plt.imshow(image)
这是输出。
--2018-02-02 00:27:52-- [https://upload.wikimedia.org/wikipedia/commons/b/be/Orang_Utan%2C_Semenggok_Forest_Reserve%2C_Sarawak%2C_Borneo%2C_Malaysia.JPG](https://upload.wikimedia.org/wikipedia/commons/b/be/Orang_Utan%2C_Semenggok_Forest_Reserve%2C_Sarawak%2C_Borneo%2C_Malaysia.JPG)Resolving upload.wikimedia.org (upload.wikimedia.org)... 198.35.26.112, 2620:0:863:ed1a::2:bConnecting to upload.wikimedia.org (upload.wikimedia.org)|198.35.26.112|:443... connected.HTTP request sent, awaiting response... 200 OKLength: 1443340 (1.4M) [image/jpeg]Saving to: 'image.jpg'image.jpg 100%[===================>] 1.38M 5.25MB/s in 0.3s2018-02-02 00:27:54 (5.25 MB/s) - 'image.jpg' saved [1443340/1443340]
现在,让我们对图像进行分类。
# copy the image data into the memory allocated for the netnet.blobs[‘data’].data[…] = transformed_image# perform classificationoutput = net.forward()output_prob = output[‘prob’][0] # the output probability vector for the first image in the batchprint ‘predicted class is:’, output_prob.argmax()
输出为’预测类为:365 '。
上面的输出将图像分类为类别 365。让我们加载 ImageNet 标签并查看输出。
# load ImageNet labelslabels_file = caffe_root + ‘data/ilsvrc12/synset_words.txt’if not os.path.exists(labels_file):!../data/ilsvrc12/get_ilsvrc_aux.shlabels = np.loadtxt(labels_file, str, delimiter=’\t’)print ‘output label:’, labels[output_prob.argmax()]
这是输出。上课是对的!
output label: n02480495 orangutan, orang, orangutang, Pongo pygmaeus
下面的代码可以帮助你找到其他的顶级类。
# sort top five predictions from softmax outputtop_inds = output_prob.argsort()[::-1][:5] # reverse sort and take five largest itemsprint ‘probabilities and labels:’zip(output_prob[top_inds], labels[top_inds])
这是输出。
probabilities and labels:
[(0.96807814, 'n02480495 orangutan, orang, orangutang, Pongo pygmaeus'),(0.030588957, 'n02492660 howler monkey, howler'),(0.00085891742, 'n02493509 titi, titi monkey'),(0.00015429058, 'n02493793 spider monkey, Ateles geoffroyi'),(7.259626e-05, 'n02488291 langur')]
分析 GPU 性能
这是在纯 CPU 模式下执行分类所花费的时间。
%timeit net.forward()
这是输出。
OUTPUT: 1 loop, best of 3: 3.06 s per loop
每个循环三秒钟相当长。让我们切换到 GPU 模式,执行同样的操作。
caffe.set_device(0) # if we have multiple GPUs, pick the first onecaffe.set_mode_gpu()net.forward() # run once before timing to set up memory%timeit net.forward()
这是输出。
OUTPUT: 1 loop, best of 3: 11.4 ms per loop
这是 3048.6 毫秒的改进!这篇博客的第一部分到此结束。我为语法错误道歉,如果有的话。
在下一部分中,我们将了解如何使用 NVIDIA Digits 训练您自己的模型,以及如何使用 Torch。
如果你喜欢这首曲子,那就鼓掌吧👏🏻(可以不止一次鼓掌)!你也可以在网上的某个地方分享,这样其他人也可以阅读。
免责声明:本网站上的帖子是我自己的,不一定代表 IBM 的立场、策略或观点。
作者:乌彭德拉·拉詹
基于 PySpark 和 MLlib 的机器学习——解决二元分类问题
Photo Credit: Pixabay
Apache Spark ,曾经是 Hadoop 生态系统的一个组成部分,现在正成为企业首选的大数据平台。它是一个强大的开源引擎,提供实时流处理、交互式处理、图形处理、内存处理以及批处理,速度非常快,易于使用,接口标准。
在这个行业中,有一个强大的引擎,可以做到以上所有的需求很大。你的公司或客户迟早会使用 Spark 开发复杂的模型,让你发现新的机会或规避风险。Spark 并不难学,如果你已经了解 Python 和 SQL,入门非常容易。今天就来试试吧!
探索数据
当我们用 Python 构建逻辑回归时,我们将使用相同的数据集,它与一家葡萄牙银行机构的直接营销活动(电话)相关。分类的目标是预测客户是否会认购(是/否)定期存款。数据集可以从 Kaggle 下载。
from pyspark.sql import SparkSession
spark = SparkSession.builder.appName('ml-bank').getOrCreate()
df = spark.read.csv('bank.csv', header = True, inferSchema = True)
df.printSchema()
Figure 1
输入变量:年龄、工作、婚姻、教育、违约、余额、住房、贷款、联系人、日、月、持续时间、活动、pdays、先前、poutcome。
产出变量:存款
先看一下前五个观察结果。熊猫数据框比 Spark DataFrame.show()好看。
import pandas as pd
pd.DataFrame(df.take(5), columns=df.columns).transpose()
Figure 2
我们的班级非常平衡。
import pandas as pd
pd.DataFrame(df.take(5), columns=df.columns).transpose()
Figure 3
数字变量的汇总统计
numeric_features = [t[0] for t in df.dtypes if t[1] == 'int']
df.select(numeric_features).describe().toPandas().transpose()
Figure 4
自变量之间的相关性。
numeric_data = df.select(numeric_features).toPandas()axs = pd.scatter_matrix(numeric_data, figsize=(8, 8));n = len(numeric_data.columns)
for i in range(n):
v = axs[i, 0]
v.yaxis.label.set_rotation(0)
v.yaxis.label.set_ha('right')
v.set_yticks(())
h = axs[n-1, i]
h.xaxis.label.set_rotation(90)
h.set_xticks(())
Figure 5
很明显,没有高度相关的数值变量。因此,我们将为模型保留它们。然而,日和月列并不真正有用,我们将删除这两列。
df = df.select('age', 'job', 'marital', 'education', 'default', 'balance', 'housing', 'loan', 'contact', 'duration', 'campaign', 'pdays', 'previous', 'poutcome', 'deposit')
cols = df.columns
df.printSchema()
Figure 6
为机器学习准备数据
该过程包括类别索引、一键编码和 vector assembler——一种将多个列合并为一个向量列的特征转换器。
from pyspark.ml.feature import OneHotEncoderEstimator, StringIndexer, VectorAssemblercategoricalColumns = ['job', 'marital', 'education', 'default', 'housing', 'loan', 'contact', 'poutcome']
stages = []for categoricalCol in categoricalColumns:
stringIndexer = StringIndexer(inputCol = categoricalCol, outputCol = categoricalCol + 'Index')
encoder = OneHotEncoderEstimator(inputCols=[stringIndexer.getOutputCol()], outputCols=[categoricalCol + "classVec"])
stages += [stringIndexer, encoder]label_stringIdx = StringIndexer(inputCol = 'deposit', outputCol = 'label')
stages += [label_stringIdx]numericCols = ['age', 'balance', 'duration', 'campaign', 'pdays', 'previous']
assemblerInputs = [c + "classVec" for c in categoricalColumns] + numericCols
assembler = VectorAssembler(inputCols=assemblerInputs, outputCol="features")
stages += [assembler]
上面的代码取自 databricks 的官方网站,它使用 StringIndexer 对每个分类列进行索引,然后将索引的类别转换为 one-hot 编码变量。结果输出将二进制向量附加到每一行的末尾。我们再次使用 StringIndexer 将标签编码为标签索引。接下来,我们使用 VectorAssembler 将所有的特性列合并成一个向量列。
管道
我们使用管道将多个转换器和估计器链接在一起,以指定我们的机器学习工作流程。管道的阶段被指定为有序数组。
from pyspark.ml import Pipeline
pipeline = Pipeline(stages = stages)
pipelineModel = pipeline.fit(df)
df = pipelineModel.transform(df)
selectedCols = ['label', 'features'] + cols
df = df.select(selectedCols)
df.printSchema()
Figure 7
pd.DataFrame(df.take(5), columns=df.columns).transpose()
Figure 8
如您所见,我们现在有“功能”列和“标签”列。
将数据随机分为训练集和测试集,并为可重复性设置种子。
train, test = df.randomSplit([0.7, 0.3], seed = 2018)
print("Training Dataset Count: " + str(train.count()))
print("Test Dataset Count: " + str(test.count()))
训练数据集计数:7764
测试数据集计数:3398
逻辑回归模型
from pyspark.ml.classification import LogisticRegressionlr = LogisticRegression(featuresCol = 'features', labelCol = 'label', maxIter=10)
lrModel = lr.fit(train)
我们可以通过使用 LogisticRegressionModel 的属性获得系数。
import matplotlib.pyplot as plt
import numpy as npbeta = np.sort(lrModel.coefficients)plt.plot(beta)
plt.ylabel('Beta Coefficients')
plt.show()
Figure 9
在训练集上总结模型,我们还可以得到接收机操作特性和 areaUnderROC 。
trainingSummary = lrModel.summaryroc = trainingSummary.roc.toPandas()
plt.plot(roc['FPR'],roc['TPR'])
plt.ylabel('False Positive Rate')
plt.xlabel('True Positive Rate')
plt.title('ROC Curve')
plt.show()print('Training set areaUnderROC: ' + str(trainingSummary.areaUnderROC))
Figure 10
精度和召回。
pr = trainingSummary.pr.toPandas()
plt.plot(pr['recall'],pr['precision'])
plt.ylabel('Precision')
plt.xlabel('Recall')
plt.show()
Figure 11
对测试集进行预测。
predictions = lrModel.transform(test)
predictions.select('age', 'job', 'label', 'rawPrediction', 'prediction', 'probability').show(10)
Figure 12
评估我们的逻辑回归模型。
from pyspark.ml.evaluation import BinaryClassificationEvaluatorevaluator = BinaryClassificationEvaluator()
print('Test Area Under ROC', evaluator.evaluate(predictions))
ROC 0.88324614449619下的测试区域
决策树分类器
决策树被广泛使用,因为它们易于解释、处理分类特征、扩展到多类分类、不需要特征缩放,并且能够捕捉非线性和特征交互。
from pyspark.ml.classification import DecisionTreeClassifierdt = DecisionTreeClassifier(featuresCol = 'features', labelCol = 'label', maxDepth = 3)
dtModel = dt.fit(train)
predictions = dtModel.transform(test)
predictions.select('age', 'job', 'label', 'rawPrediction', 'prediction', 'probability').show(10)
Figure 13
评估我们的决策树模型。
evaluator = BinaryClassificationEvaluator()
print("Test Area Under ROC: " + str(evaluator.evaluate(predictions, {evaluator.metricName: "areaUnderROC"})))
ROC 下的测试区域:0.7807240050065357
一个简单的决策树表现不佳,因为它在不同特征的范围内太弱。集成方法可以提高决策树的预测精度,如随机森林和梯度提升树。
随机森林分类器
from pyspark.ml.classification import RandomForestClassifierrf = RandomForestClassifier(featuresCol = 'features', labelCol = 'label')
rfModel = rf.fit(train)
predictions = rfModel.transform(test)
predictions.select('age', 'job', 'label', 'rawPrediction', 'prediction', 'probability').show(10)
Figure 14
评估我们的随机森林分类器。
evaluator = BinaryClassificationEvaluator()
print("Test Area Under ROC: " + str(evaluator.evaluate(predictions, {evaluator.metricName: "areaUnderROC"})))
ROC 下的测试区域:0.8846453518867426
梯度增强树分类器
from pyspark.ml.classification import GBTClassifiergbt = GBTClassifier(maxIter=10)
gbtModel = gbt.fit(train)
predictions = gbtModel.transform(test)
predictions.select('age', 'job', 'label', 'rawPrediction', 'prediction', 'probability').show(10)
Figure 15
评估我们的梯度增强树分类器。
evaluator = BinaryClassificationEvaluator()
print("Test Area Under ROC: " + str(evaluator.evaluate(predictions, {evaluator.metricName: "areaUnderROC"})))
ROC 下的测试区域:0.8940728473145346
梯度提升树取得了最好的结果,我们将尝试用 ParamGridBuilder 和 CrossValidator 调整这个模型。在此之前,我们可以使用 explainParams()打印所有参数及其定义的列表,以了解哪些参数可用于调优。
print(gbt.explainParams())
Figure 16
from pyspark.ml.tuning import ParamGridBuilder, CrossValidatorparamGrid = (ParamGridBuilder()
.addGrid(gbt.maxDepth, [2, 4, 6])
.addGrid(gbt.maxBins, [20, 60])
.addGrid(gbt.maxIter, [10, 20])
.build())cv = CrossValidator(estimator=gbt, estimatorParamMaps=paramGrid, evaluator=evaluator, numFolds=5)# Run cross validations. This can take about 6 minutes since it is training over 20 trees!
cvModel = cv.fit(train)
predictions = cvModel.transform(test)
evaluator.evaluate(predictions)
0.8981050997838095
综上所述,我们已经学习了如何使用 PySpark 和 MLlib Pipelines API 构建二进制分类应用程序。我们尝试了四种算法,梯度提升在我们的数据集上表现最好。
源代码可以在 Github 上找到。我期待听到反馈或问题。
用 Python 进行机器学习:拟合非线性数据的简单而稳健的方法
使用 Python 库、管道特性和正则化进行非线性数据建模的简单而可靠的方法。
非线性数据建模是数据科学和分析领域的一项常规任务。很难找到一个结果随自变量线性变化的自然过程。因此,我们需要一种简单而可靠的方法来快速拟合一组测量数据和一组变量,假设测量数据可能是一个复杂的非线性函数。这应该是数据科学家或机器学习工程师的常用工具。
有几个相关的问题需要考虑:
- 我如何决定尝试拟合什么阶的多项式?多元回归需要包含交叉耦合项吗?有没有一种简单的方法到来自动化这个过程**?**
- 如何确保我不会过度适应数据?
- 我的机器学习模型对测量噪声是否鲁棒?
- 我的模型容易扩展到更高维度和/或更大的数据集吗?
如何确定多项式的阶次及相关难题
“我可以绘制数据并快速浏览一下吗?”
只有当一个人能够清楚地可视化数据时(特征维数是 1 或 2),这才是可以的。对于特征尺寸为 3 或更大的尺寸,这要困难得多。如果影响结果的特性之间存在交叉耦合,这完全是浪费时间。让我用图表展示一下,
显而易见,策划只能让你到此为止。对于一个高维的相互作用的数据集,如果你试图一次查看一个输出与一个输入变量的关系图,你会得出完全错误的结论。而且,没有一种简单的方法可以一次可视化两个以上的变量。因此,我们必须借助某种机器学习技术来生成多维数据集。
事实上,有很多好的解决方案。
线性回归应该是第一个要查的工具,在你尖叫之前“……但是这些是高度非线性的数据集……”,让我们记住,线性回归模型中的‘线性’是指系数,而不是指特征的程度。特征(或独立变量)可以是任何次数,甚至是超越函数,如指数、对数、正弦。而且,使用这些变换和线性模型可以(近似地)模拟大量的自然现象。
因此,假设我们得到以下数据集,它有一个输出和 3 个特征。我们再次展示了这些情节,但是,不出所料,它们没有多大帮助。
因此,我们决定学习具有高达一些高次多项式项的线性模型来拟合数据集。很少有问题会立即浮现出来:
—如何决定什么样的多项式是必要的
—如果我们开始逐个合并一级、二级、三级术语,什么时候停止?
—如何确定任何交叉耦合项是否重要,即我们是否只需要 X 1、 X 2 或 X 1。 X 2 和 X 1 .X3 项也?
—最后,我们是否必须为所有这些多项式变换手动编写方程/函数,并将它们添加到数据集中?
牛逼的 Python 机器学习库来帮忙
幸运的是, scikit-learn ,这个令人敬畏的机器学习库,提供了现成的类/对象来以一种简单而健壮的方式回答上述所有问题。
这里有一个简单的使用 scikit-learn 的线性回归概述视频,这里有一篇不错的中型文章供您审阅。但是在本文中,我们将涵盖比简单的线性拟合更多的内容,所以请继续阅读**。在我的 GitHub repo 上可以找到这篇文章的全部样板代码。**
我们首先从 scikit-learn 导入几个相关的类,
# **Import function to create training and test set splits**
from sklearn.cross_validation import train_test_split# **Import function to automatically create polynomial features!**
from sklearn.preprocessing import PolynomialFeatures# **Import Linear Regression and a regularized regression function**
from sklearn.linear_model import LinearRegression
from sklearn.linear_model import LassoCV# **Finally, import function to make a machine learning pipeline**
from sklearn.pipeline import make_pipeline
让我们快速定义/概括一下我们接下来要使用/实现的必要概念。
训练/测试分割 :这意味着从我们拥有的单个数据集创建两个数据集。其中一个(训练集)将用于构建模型,另一个(测试集)将仅用于测试模型的准确性和稳健性。这对于任何机器学习任务来说都是必不可少的,因此我们不会用我们所有的数据创建模型,并认为模型高度准确(因为它已经‘看到’了所有的数据,并且拟合得很好),但当面对现实世界中新的(“看不见”)数据时,它表现很差**。测试集的准确性比训练集的准确性重要得多。这里有一篇关于这个主题的很好的中间文章供你参考。下面你可以看到谷歌汽车先驱巴斯蒂安·特龙谈论这个概念。**
自动多项式特征生成 : Scikit-learn 为从一组线性特征生成多项式特征提供了一种简洁的方法。您所要做的就是传递一个列表中的线性要素,并指定要生成多项式次数项的最大次数。它还让您可以选择生成所有的交叉耦合交互项,或者只生成主要特征的多项式次数。下面是一个示例 Python 代码描述。
正则化回归 :正则化的重要性不能被夸大,因为它是机器学习中的一个核心概念。在线性回归设置中,基本思想是惩罚模型系数,使其不会变得太大而过度拟合数据,即,使模型对数据中的噪声极其敏感。有两种广泛使用的正则化方法,其中我们正在使用一种叫做套索的方法。这里有一个关于这两种正则化方法的很好的概述。
机器学习管道 :一个机器学习项目(几乎)绝不是单一的建模任务。在最常见的形式中,它包括数据生成/接收、数据清理和转换、模型拟合、交叉验证、模型准确性测试和最终部署**。这里有一个 Quora 答案很好地总结了这个概念。或者,这里有一篇相关的媒介文章。或者,另一篇讨论管道实践重要性的好文章。Scikit-learn 提供了一个管道特性,它可以将多个模型和数据预处理类堆叠在一起,并将原始数据转化为可用的模型。**
如果您有时间,请观看 PyData conference(2015 年,达拉斯)上的这段长视频(1 小时以上),了解所有相关内容。
如何通过将所有这些放在一起建立一个健壮的模型?
这是样板代码快照。您必须对其进行修改,以便为您的数据集正确运行。
**# Alpha (regularization strength) of LASSO regression**
lasso_eps = 0.0001
lasso_nalpha=20
lasso_iter=5000**# Min and max degree of polynomials features to consider**
degree_min = 2
degree_max = 8**# Test/train split**
X_train, X_test, y_train, y_test = train_test_split(df['X'], df['y'],test_size=test_set_fraction)**# Make a pipeline model with polynomial transformation and LASSO regression with cross-validation, run it for increasing degree of polynomial (complexity of the model)**for degree in range(degree_min,degree_max+1):
model = make_pipeline(PolynomialFeatures(degree, interaction_only=False), LassoCV(eps=lasso_eps,n_alphas=lasso_nalpha,max_iter=lasso_iter,
normalize=True,cv=5))
model.fit(X_train,y_train)
test_pred = np.array(model.predict(X_test))
RMSE=np.sqrt(np.sum(np.square(test_pred-y_test)))
test_score = model.score(X_test,y_test)
但是嘿,代码是给机器用的!对于普通人来说,我们需要便利贴。因此,这是相同的注释版本,带有注释和评论:)
为了进一步提炼,下面是更正式的流程…
让我们讨论结果!
对于所有的模型,我们还捕获测试误差、训练误差(均方根)和惯用的 R 系数作为模型精度的度量。这是我们绘图后它们的样子,
****
这些图回答了我们之前的两个问题:
- 我们确实需要 4 次或 5 次多项式来模拟这种现象。线性、二次甚至三次模型对于拟合数据来说都不够复杂。
- 但是,我们不应该需要超越第五度和过于复杂的模型。想一想这个 奥卡姆剃刀边界 为我们的模型。
但是,嘿,这条曲线中熟悉的偏差/方差权衡(又名欠拟合/过拟合)形状在哪里呢?对于过于复杂的模型,为什么测试误差不会急剧上升?
答案在于这样一个事实:使用 LASSO 回归,我们基本上消除了更复杂模型中的高阶项。要了解更多细节,以及为什么会发生这种情况的一些奇妙的直觉推理,请阅读这篇文章或观看下面的视频。事实上,这是套索回归或 L1 范数惩罚的主要优点之一,它将一些模型系数精确地设置为零,而不是仅仅缩小它们。实际上,这会为您执行“自动特征选择”,即让您自动忽略不重要的特征,即使您开始使用高度复杂的模型来拟合数据。
我们可以通过不进行正则化并使用来自 scikit-learn 的简单的线性回归模型类来轻松测试这一点。这是那种情况下的结果。熟悉的偏差-方差形状出现在模型复杂度与误差图中。
那么,有噪声的数据会怎么样呢?
您可以下载我的代码并尝试更改*noise_magnitude*
参数,以查看向数据集添加噪声的影响。噪声使得模型很难无偏差,并且它还将模型推向过拟合,因为模型试图理解有噪声的数据模式,而不是发现真正的模式,它使自己适应噪声。基本上,简单的线性回归模型(w/o 正则化)在这种情况下会惨败。正则化模型仍然表现良好,但是即使正则化模型性能也开始出现偏差-方差权衡。这是总结,
收场白
因此,简而言之,我们讨论了在存在噪声的情况下,将多变量回归模型拟合到具有高度非线性和相互耦合项的数据集的系统方法。我们看到了如何利用 Python 机器学习库来生成多项式要素、归一化数据、拟合模型、防止系数变得过大从而保持偏差-方差平衡,以及绘制回归分数来判断模型的准确性和稳健性。
对于具有非多项式特征的更高级类型的模型,您可以检查 scikit-learn’s stable 的内核回归和支持向量回归机模型。还有,看看这篇关于高斯核回归的漂亮文章。
** [## Tirthajyoti Sarkar - Sr .首席工程师-半导体、人工智能、机器学习- ON…
佐治亚理工学院理学硕士- MS,分析这一 MS 计划传授理论和实践…
www.linkedin.com](https://www.linkedin.com/in/tirthajyoti-sarkar-2127aa7/)
如果您有任何问题或想法可以分享,请通过tirthajyoti[AT]Gmail[DOT]com联系作者。你可以查看作者的 GitHub 资源库 中其他有趣的 Python、R 或 MATLAB 代码片段和机器学习资源。此外,如果你像我一样对机器学习/数据科学/半导体充满热情,请随时在 LinkedIn 上添加我或在 Twitter 上关注我。**
了解面向 TensorFlow 的 Swift
S 用于 TensorFlow 的 wift 由克里斯·拉特纳在 2018 年 TensorFlow 开发峰会上推出。2018 年 4 月 27 日,谷歌团队在他们的 GitHub 知识库上首次向公众社区发布。但 Swift for TensorFlow 仍处于起步阶段。而且开发人员/研究人员在项目中使用它似乎还为时过早。如果您仍有兴趣试用,请从 Swift 官网为 TensorFlow 的快照安装 Swift。
Swift for TensorFlow (Image Source)
在本文中,我将重点解释以下主题:
- 访问 Python APIs 和
PyValue
(Python 的 Swift 动态系统) - Swift 中的自动区分系统
- 对 TensorFlow 的 Swift 中的
Tensor
s 执行计算 - 训练神经网络
Swift for TensorFlow 很可能会像 Swift 和 TensorFlow 独立完成的那样,与开源社区一起快速发展。因此,这可能是一个值得努力去了解它的东西。
注意 :关于 TensorFlow 的 Swift 需要注意的一个主要问题是,它是一个由运行定义的框架。这意味着,尽管 Swift for TensorFlow 在后台创建图表(如 TensorFlow ),但您不必为执行这些图表创建会话。这种方法类似于 TensorFlow 中的急切执行。
1.主要特点
- 自动反向微分(正向尚未实现)
- 运行定义设计(不需要会议)
- Swift 经过优化,包含机器学习特定功能
- 允许 Python APIs 以 Python 方式访问
- 包括用于 Python 的动态系统行为的
PyValue
类型
2.Python 互操作性
借助 Swift for TensorFlow,我们可以以最 Python 化的方式使用 Python APIs。要访问 Python APIs,必须进入程序,如下面的示例代码片段所示。
import Pythonlet np = Python.import("numpy") // akin to `import numpy as np`
let pickle = Python.import("pickle")
let gzip = Python.import("gzip")
而用于 TensorFlow 的 Swift 也有一个名为PyValue
的新类型,它展示了 Python 在 Swift 中的完整动态类型系统行为,而不影响 Swift 中其他类型的行为。
var x: PyValue = 3.14159
print(x * 2) // Prints "6.28318"
x = "string"
print("now a " + x) // Prints "now a string"
更多信息请参考官方的 Python 互操作性文档。
3.自动微分
Swift for TensorFlow 内置了对计算函数相对于其他变量的梯度的支持。该功能已被直接整合到 Swift 的编译器中,以优化行为。它支持两种差分功能:#gradient(of:withRespectTo:)
和#valueAndGradient(of:)
。虽然它对我不起作用😩(还为时过早)但是文档中说要遵循下面的语法。这段代码片段来自官方的 d 文档。
@differentiable(reverse, adjoint: dTanh)
func tanh(_ x: Float) -> Float {
// ... some super low-level assembly tanh implementation ...
}
func dTanh(x: Float, y: Float, seed: Float) -> Float {
return (1.0 - (y * y)) * seed
}// Get the gradient function of tanh.
let dtanh_dx = #gradient(of: tanh)
dtanh_dx(2)
// Get the gradient function of foo with respect to the first parameter.
let dfoo_dx = #gradient(of: foo, withRespectTo: .0)
dfoo_dx(3, 4)
目前仅允许自动反向微分,正向微分正在讨论中。
4.使用张量
作为一个简单的例子,我们将创建一个Tensor
实例,在其上我们使用 TensorFlow 应用一些操作。
import TensorFlowvar x = Tensor([[1, 2], [3, 4]])
for _ in 1...5 {
x += x
}
print(x) // Prints "[[32.0, 64.0], [96.0, 128.0]]"
在上面的代码中使用了基本的+
操作符,它在一个循环中将Tensor
添加到自身中。这之所以成为可能,是因为 Swift 的高级操作符功能为Tensor
实例提供了过载功能。
5.训练一个简单的前馈神经网络
转向神经网络——机器学习在这个时代流行的真正原因。在本节中,我们将教授我们的 3 层完全连接的前馈神经网络来预测来自 MNIST 数据集的图像中的数字。从 Swift 文件中的 tensor flowimport TensorFlow
开始。
注 : 训练代码可以在这里找到如果有人不耐烦的话。
我们的神经网络将有 3 层:
- 输入层:它将输入数据(在我们的例子中是像素值)呈现给神经网络。在我们的例子中,每个图像有 784 个值。
- 隐藏层:它用权重和偏差计算我们输入数据的仿射变换。然后将一个 sigmoid 激活函数应用于变换。我们示例中的隐藏层将有 30 个单元(神经元)。
- 输出层:隐藏层的数据再次经过仿射变换和一个 sigmoid 函数的应用,就像形成输出层之前一样。这是预测发生的地方。我们在这一层有 10 个单元,每个单元代表在图像中成为特定数字的概率。还要注意,我们在该层中使用one-hot/1-of-k编码,其中在一维张量中,除了所有其他值为 0 之外,单个值为 1。例如,[0,0,1,0,0,0,0,0,0,0]表示输出[预测]层图像中的两位数。
仿射变换基本上是数据与权重的点积,然后是偏差的增加,随后是激活函数的逐元素应用。以下是输入数据的仿射变换的方程式 x.
o(x;W,b)= f(wx+b)
在这里, *O(。)*是输出函数, *f(。)*是激活函数(我们这里是 sigmoid), W 是权重矩阵, b 是偏置向量,代表点积。
我们使用 sigmoid 激活函数,因为它将值压缩到限制输出范围的范围[0,1],从而提供输出层图像中可能数字的概率。
5.1 读取 MNIST 数据
让我们读取数据集并构建这些图像和标签的Tensor
实例。我们必须创建Tensor
对象,因为这是 TensorFlow 模型(神经网络)允许流经的对象,因此得名。
let (images, numericLabels) = readMnist(imagesFile: imagesFile,labelsFile: labelsFile)
let labels = Tensor<Float>(oneHotAtIndices: numericLabels, depth: 10)
5.2 超参数
我们定义了 3 个超参数:学习率、训练损失和迭代步骤。
let iterationCount: Int32 = 20
let learningRate: Float = 0.2
var loss = Float.infinity
5.3 可训练参数
接下来,我们根据张量流的Tensor
类型创建 2 个权重矩阵、2 个偏置向量,如下所示。
var w1 = Tensor<Float>(randomUniform: [784, 30])
var w2 = Tensor<Float>(randomUniform: [30, 10])
var b1 = Tensor<Float>(zeros: [1, 30])
var b2 = Tensor<Float>(zeros: [1, 10])
5.4 训练循环
训练循环是神经网络进行学习的代码块。我们通过网络传递图像和标签Tensor
(正向传递)。然后计算预测中的误差,然后将它们反向传播以计算可训练参数的梯度。接下来,我们在学习率的帮助下,使用相应的梯度来降低这些参数。最后计算损失,给出我们离图像的真实标签有多远的概念。每个步骤描述如下。
5.4.1 向前传球
如上所述,输入图像像素值经过仿射变换。这里的值是带权重的点积,然后加上偏差,偏差进一步通过 s 形激活函数(按元素方式应用)。
let z1 = images ⊗ w1 + b1
let h1 = sigmoid(z1)
let z2 = h1 ⊗ w2 + b2
let predictions = sigmoid(z2)
这里需要注意的一点是 Swift 使用⊗ unicode 来表示点积,这表明 Swift 语言实际上是多么酷!坦白说,我真的很喜欢♥️这种编程语言。
5.4.2 反向传递(计算梯度)
反向传递计算预测和真实标签之间的误差。这些误差然后通过网络反向传播,计算可学习参数的梯度。
let dz2 = predictions - labels
let dw2 = h1.transposed(withPermutations: 1, 0) ⊗ dz2
let db2 = dz2.sum(squeezingAxes: 0)
let dz1 = dz2.dot(w2.transposed(withPermutations: 1, 0)) * h1 * (1 - h1)
let dw1 = images.transposed(withPermutations: 1, 0) ⊗ dz1
let db1 = dz1.sum(squeezingAxes: 0)
5.4.3 下降参数
现在,我们用它们的梯度和决定神经网络学习它的参数的速度的学习速率来降低参数,以便在下一次输入图像被馈送给它时预测真实值。
w1 -= dw1 * learningRate
b1 -= db1 * learningRate
w2 -= dw2 * learningRate
b2 -= db2 * learningRate
5.4.4 更新损失
我们更新损失值以查看我们与真实标签的接近程度,以便下次更正确地预测数字图像。
loss = dz2.squared().mean(squeezingAxes: 1, 0).scalarized()
让我们现在打印我们的损失,它告诉我们如何从我们的训练集中学习识别数字图像。越低的损失越好是我们网络识别的任务。
print("Loss: \(loss)") // Prints "0.1"
6.摘要
在本文中,我们了解了用于 TensorFlow 的 Swift,以及它的易用性,因为 Swift 与 Python 非常相似,看起来像脚本语言,但速度非常快。我们看到 Swift for TensorFlow 允许我们使用 Python APIs,而且 Swift 的编译器已经过深度优化,内置了对自动微分的支持,这对机器学习任务非常重要。我们还看到了如何在 Swift 中使用 TensorFlow,我们创建了自己的Tensor
实例,并对它们进行了一些处理(使用基本操作符+
)。最后,我们训练了三层神经网络来解决传统的数字图像识别问题。
7.讨论
似乎 Swift 的名称应该是tensor flow,而不是 TensorFlow 的 Swift。事实并非如此,因为实际上 Swift 的编译器已被修改为支持 TensorFlow,因此 Swift 不仅充当 Python 库和 TensorFlow 的包装器,现在更像是机器学习语言。为了在整个机器学习和数据科学社区中保持工作流的一致性(因为 Python 被大量使用),它还允许以 Python 的方式访问 Python APIs,并且还为 Python 的动态系统类型行为实例提供了一种新的类型。
最后一句话,用于 TensorFlow 的 Swift 是由 Google 开发的,因此它很有可能在未来的时代变得著名。它还试图利用原始 TensorFlow 实现的最佳功能,如 eager-execution。
8.参考
[1] Swift for TensorFlow ,谷歌
Swift.org,苹果
[3] Python 的互操作性
[4]Swift 中的自动微分
[5]Swift 编程语言(Swift 4.1):高级操作员
[6]Swift for tensor flow:MNIST 示例
如果你觉得这篇文章有用/有见识,请鼓掌👏这样其他人也可以找到它,或者你也可以在社交网络上分享它。如果你在我的解释中发现了一些错误(也许我解释错了),或者你从这篇文章中有什么不清楚的地方,你也可以在下面发表评论。
保持【机器】学习,直到你化石燃料!🤘🤖
Google 云平台上 TensorFlow 的机器学习:代码示例
在过去的几个月里,我的团队一直致力于在 Coursera 上创建两个 5 门课程的专业,名为“谷歌云平台上的机器学习”和“GCP 上的高级机器学习”。完整的 10 个课程的旅程将带你从一个战略概述为什么 ML 的重要性,所有的方式来建立定制序列模型和推荐引擎。
The first course in our 10-course specialization on Coursera launched this week, but the labs for all 10 courses are already available for you to use as a starting point for your models.
这些课程提供了一个互动的,实用的,务实的方法来快速有效地开始做 ML。虽然有许多理论上的机器学习课程,但我这个专业的目标是提供实践培训,以便你可以立即投入运行。为了让你快速起步,课程附带了大量的开源示例 TensorFlow 应用,你可以立即学习、培训/部署。
GCP 系列机器学习第一课。 谷歌如何做到 ML ,现已在 Coursera 上直播。请去参加课程,并参加剩余的课程,因为它们每隔几周出现一次。
但是,即使你在等待令人敬畏的演示者团队来教授课程,专业化实验室的源代码已经可用。在这篇博文中,我将列出 GitHub repo 的每个文件夹中的可用内容:
01.谷歌如何做 ML
data_analysis.ipynb 向您展示如何对大型数据集进行数据分析:
mlapis.ipynb 向您展示如何调用预先训练的 ML 模型:
02.启动到 ML
repeatable _ splitting . ipynb说明了数据可重复拆分的重要性
create_datasets.ipynb 向您展示如何使用 Pandas 和 BigQuery 探索和创建数据集
03.张量流简介
a_tfstart.ipynb 向您展示如何使用 TensorFlow 作为数值软件包
b_estimator.ipynb 向您展示如何在 TensorFlow 中编写简单的 ML 模型
c_batched.ipynb 向您展示如何在 TensorFlow 中处理大型数据集
d_traineval.ipynb 向您展示如何使用 TensorFlow 进行分布式训练
debug_demo.ipynb 向您展示如何调试 TensorFlow 程序
e_cloudmle.ipynb 向您展示如何部署 TensorFlow 模型,并使用云 ML 引擎以无服务器的方式进行预测
04.特征工程
a_features.ipynb 说明了正确表示特征的重要性
数据流展示了如何使用 Apache Beam on Cloud 数据流进行预处理
taxifeateng 向您展示如何在 TensorFlow 模型中实现特征工程
05.ML 的艺术与科学
a_handtuning.ipynb 向您展示如何更改与 TensorFlow 模型相关的各种参数,以获得更高的精度
b_hyperparam.ipynb 向您展示如何在 Cloud ML Engine 上自动调优 TensorFlow 模型,这样您就不必进行手动调优。
c_neuralnetwork.ipynb 向您展示如何以最简单的方式在 TensorFlow 中使用分布式神经网络模型进行训练和预测。
d_customestimator.ipynb 向您展示如何采用您在论文中找到的模型,并以分布式和可扩展的方式实现。
06.结构化数据上的端到端机器学习
这套笔记本:
1_explore.ipynb 向您展示了如何使用 Pandas 和 BigQuery 来浏览数据
2_sample.ipynb 向您展示如何重复分割数据
3_tensorflow.ipynb 向您展示如何在数据上构建一个估计器模型
4_preproc.ipynb 向您展示如何使用数据流大规模预处理数据
4_preproc_tft.ipynb 向您展示如何使用 TF 大规模预处理数据。改变
5_train.ipynb 向您展示如何在云 ML 引擎上训练 TensorFlow 模型
6_deploy.ipynb 向您展示如何将训练好的模型部署到云 ML 引擎
服务向您展示如何从 web 应用程序和数据管道中访问 ML 预测。
以上 7 个实验总结了前六个课程在一个现实问题上的经验,带您从数据探索到部署和预测。
07.生产 ML 模型
这一个没有实验—这是关于 ML 模型的设计和架构考虑。
08.图像分类模型
mnist_estimator.ipynb 向您展示如何使用 Estimator API 构建图像分类器
向您展示如何使用所有技巧(卷积层、扩充、批量标准化等)构建一个定制的评估器。)进入一个好的图像分类模型
flowers _ from scratch . ipynb向您展示如何将之前笔记本中的图像模型应用于“真实”图像。
迁移学习和 AutoML 的实验不在 GitHub 中,因为它们不涉及任何编码——只需点击!
09.时间序列和文本序列模型
sinewaves.ipynb 向您展示如何使用包括 CNN 和 LSTMs 在内的各种技术在 TensorFlow 中构建时间序列预测模型。
temperature.ipynb 说明了 LSTMs 有多难做对
txtcls1.ipynb 向您展示了如何使用各种技术(包括 CNN 和 LSTMs)从头开始构建文本分类模型
txtcls2.ipynb 向您展示如何在文本分类模型中使用预训练的单词嵌入。
word2vec.ipynb 向你展示了如何从你自己的数据集中创建一个单词嵌入。
poem . ipynb向您展示如何使用 Tensor2Tensor 解决您自己的文本问题,无论是文本摘要还是文本生成
10.推荐引擎
显示了一个基于内容的推荐系统的例子
wals.ipynb 向您展示如何在 TensorFlow 中构建协同过滤推荐系统
wals_tft.ipynb 通过添加 tf.transform 管道来自动映射唯一的用户标识和项目标识,使协作过滤模型可以投入生产。
随着 ML 的成熟,当然会有更多的实验室,上面的一些实验室可能是不必要的。GitHub repo 是一个动态存储库,我们计划保持它的最新状态,并反映建议的 TensorFlow 实践。因此,如果您正在构建自己的 ML 模型,笔记本(及其相应的模型目录)是一个很好的起点。
探索愉快!
机器学习—使用 Keras 进行单词嵌入和情感分类
在的上一篇文章中,我们讨论了自然语言处理(NLP)中文本处理的各个步骤,并且使用一些经典的 ML 技术实现了一个基本的情感分析器。
深度学习已经在包括 NLP、计算机视觉和游戏在内的各种任务上表现出优异的性能。为了进一步探索,我们将讨论和使用一些基于深度学习的高级 NLP 技术,来创建一个改进的情感分类器。
Courtesy (KDnuggets)
情感分类问题
情感分类的任务是查看一段文本,并判断某人是否喜欢或不喜欢他们正在谈论的事情。
输入 X 是一段文本,输出 Y 是我们想要预测的情感,比如电影评论的星级。
如果我们可以训练一个系统根据上面的标签数据集从 X 映射到 Y,那么这样的系统可以用来预测一个评论者在看完电影后的情绪。
在本帖中,我们将重点关注以下任务:
- 构建深度神经网络进行情感分类。
- 学习单词嵌入:一边训练网络,一边使用 Word2Vec。
体系结构
深度学习文本分类模型架构通常由以下顺序连接的组件组成:
Deep Learning Architecture
- 嵌入层
***Word Embedding*** *is a representation of text where words that have the same meaning have a similar representation. In other words it represents words in a coordinate system where related words, based on a corpus of relationships, are placed closer together.* In the deep learning frameworks such as TensorFlow, Keras, this part is usually handled by an **embedding layer** which stores a lookup table to map the words represented by numeric indexes to their dense vector representations.
- 深层网络
Deep network takes the sequence of embedding vectors as input and converts them to a compressed representation. The compressed representation effectively captures all the information in the sequence of words in the text. The deep neywrok part is usually an RNN or some forms of it like LSTM/GRU. The dropout is added to overcome the tendency to overfit, a very common problem with RNN based networks. Please refer [here](/illustrated-guide-to-lstms-and-gru-s-a-step-by-step-explanation-44e9eb85bf21) for detailed discussion on LSTM,GRU.
- 全连接层
The **fully connected layer** takes the deep representation from the RNN/LSTM/GRU and transforms it into the final output classes or class scores. This component is comprised of fully connected layers along with batch normalization and optionally dropout layers for regularization.
- 输出层
Based on the problem at hand, this layer can have either **Sigmoid** for binary classification or **Softmax** for both binary and multi classification output.
数据集
IMDB 电影评论集可以从这里下载。这个用于二元情感分类的数据集包含用于训练的 25,000 条高度极性的电影评论,以及用于测试的 25,000 条评论。初始预处理后的数据集保存到movie_data.csv
文件。首先,我们加载 IMDb 数据集,文本评论分别被标记为正面和负面情绪的 1 或 0。
IMDb movie review dataset
学习单词嵌入
我们数据集的单词嵌入可以在训练关于分类问题的神经网络时学习。在将文本数据呈现给网络之前,首先对其进行编码,以便每个单词由一个唯一的整数表示。这个数据准备步骤可以使用 Keras 提供的 Tokenizer API 来执行。我们添加填充,使所有的向量长度相同(*max_length*)
。下面的代码将文本转换为整数索引,现在可以在 Keras 嵌入层中使用。
嵌入层需要词汇表大小(vocab_size)
、实值向量空间大小EMBEDDING_DIM = 100
和输入文档最大长度max_length
的规范。
建立模型
我们现在准备定义我们的神经网络模型。该模型将使用一个嵌入层作为第一个隐藏层。嵌入层用随机权重初始化,并将在模型训练期间学习训练数据集中所有单词的嵌入。
该模式的总结是:
出于演示目的,我们使用了一个简单的深层网络配置。您可以尝试不同的网络配置并比较性能。嵌入参数计数12560200 = (vocab_size * EMBEDDING_DIM)
。最大输入长度max_length = 2678
。训练期间的模型将从输入文本中学习单词嵌入。可训练参数总数为 12,573,001。
火车模型
现在让我们在训练集上训练模型,并在测试集上交叉验证。我们可以从下面的训练时期看到,每个时期之后的模型都在提高精度。几个时期之后,我们达到了大约 84%的验证准确度。还不错:)
试验模型
我们可以用一些样本评论来测试我们的模型,以检查它是如何预测每个评论的情绪的。首先,我们必须将文本审查转换为令牌,并使用模型预测如下。
输出给出单词的预测是 1(正面情绪)或 0(负面情绪)。
接近 1 的值是强烈的积极情绪,接近 0 的值是强烈的消极情绪。我可以清楚地看到,模型预测对于 test_sample_7 是错误的,而对于其余的样本却表现得相当好。
在上述方法中,我们学习单词嵌入作为拟合神经网络模型的一部分。
训练 word2vec 嵌入
还有另一种方法来构建情感澄清模型。我们可以先单独学习单词嵌入,然后传递到嵌入层,而不是训练嵌入层。这种方法还允许使用任何预先训练的单词嵌入,并且还节省了训练分类模型的时间。
我们将使用 Word2Vec 的 Gensim 实现。第一步是通过创建单词标记、去除标点符号、去除停用词等来准备用于学习嵌入的文本语料库。word2vec 算法逐句处理文档。
我们的文本语料库中有 50000 条评论。Gensim 的 Word2Vec API 需要一些参数进行初始化。
一.sentences
–句子列表;这里我们通过复习句子列表。
二。我们希望用多少维度来表达我们的话语。这是单词向量的大小。
三。min_count
–只有频率大于min_count
的词才会被纳入模型。通常,你的文本越大越广泛,这个数字就越高。
四。window
–只有出现在窗口-一个句子中某个术语的邻近区域内的术语,才会在训练过程中与之相关联。通常的值是 4 或 5。
动词 (verb 的缩写)workers
–训练并行化中使用的线程数量,以加快训练速度
测试 Word2Vec 模型
在我们在 IMDb 数据集上训练模型之后,它建立了一个词汇表size = 134156
。让我们尝试一些从电影评论数据集学习的单词嵌入模型。
与单词horrible
最相似的单词是:
most similar words
试着对单词 vectors 做些数学计算— woman+king-man=?
让我们找到那个奇怪的单词woman, king, queen, movie = ?
看到我们的 word2vec 模型从文本语料库中学习到的单词嵌入是非常有趣的。下一步是在我们的情感分类模型的嵌入层中直接使用单词嵌入。我们可以保存模型以备后用。
使用预先训练的嵌入
因为我们已经用 IMDb 数据集训练了 word2vec 模型,所以我们已经准备好使用单词嵌入了。下一步是将单词 embedding 作为单词目录加载到 vectors 中。单词 embedding 保存在文件imdb_embedding_word2vec.txt
中。让我们从存储的文件中提取单词 embeddings。
下一步是将单词 embedding 转换成标记化的向量。回想一下,评审文档在传递到嵌入层之前是整数编码的。整数映射到嵌入层中特定向量的索引。因此,重要的是我们在嵌入层中布置矢量,使得编码的字映射到正确的矢量。
现在,我们将把每个单词的嵌入从加载的 word2vec 模型映射到 tokenizer_obj.word_index
词汇表,并创建一个单词向量矩阵。
我们现在已经准备好将训练好的嵌入向量直接用于嵌入层。在下面的代码中,与先前模型的唯一变化是使用embedding_matrix
作为嵌入层的输入并设置trainable = False
,因为嵌入已经被学习。
Model summary with pre- trained Embedding
仔细看,你可以看到型号total params = 13,428,501
而不是trainable params = 12801
。由于该模型使用预训练的单词嵌入,它具有非常少的可训练参数,因此应该训练得更快。
为了训练情感分类模型,我们使用VALIDATION_SPLIT= 0.2
,你可以改变它来观察对模型准确性的影响。
最后,在训练和验证测试集上训练分类模型,我们随着每个历元的运行而获得准确度的提高。我们仅用大约 5 个时期就达到了 88%的准确率。
你可以尝试通过改变超参数、运行更多的历元等来提高模型的准确性。此外,您可以使用其他一些预先训练好的嵌入,这些嵌入是在非常大的文本数据语料库上准备的,您可以直接下载。
结论
在这篇文章中,我们详细讨论了用于情感分类的深度学习模型的架构。我们还训练了一个 word2vec 模型,并将其用作情感分类的预训练嵌入。
感谢阅读,如果你喜欢,请为它鼓掌。
进一步阅读
http://ruder.io/deep-learning-nlp-best-practices
让我们考虑下面的模型。我们试图预测一个新闻标题在……上会有多少转发和点赞
keras.io](https://keras.io/getting-started/functional-api-guide/) [## 如何开发预测电影评论情感的单词嵌入模型
单词嵌入是一种表示文本的技术,其中具有相似含义的不同单词具有相似的…
machinelearningmastery.com](https://machinelearningmastery.com/develop-word-embedding-model-predicting-movie-review-sentiment/)
Rajesh Arumugam 的 Python 自然语言处理实践,Rajalingappaa Shanmugamani,2018 年 7 月
糖尿病数据的机器学习工作流程:第 1 部分
“医疗环境中的机器学习可以帮助显著增强医疗诊断。”
本文将描述如何利用与糖尿病相关的数据来预测一个人是否患有糖尿病。更具体地说,本文将重点关注如何利用机器学习来预测糖尿病等疾病。在本系列文章结束时,您将能够理解数据探索、数据清理、特性选择、模型选择、模型评估等概念,并以实际的方式应用它们。
什么是糖尿病?
糖尿病是一种当血糖水平变高时发生的疾病,最终会导致其他健康问题,如心脏病、肾病等。糖尿病主要是由于食用高度加工食品、不良消费习惯等引起的。据世卫组织报道,这些年来糖尿病患者的数量一直在增加。
先决条件
- Python 3。+
- 蟒蛇(Scikit Learn,Numpy,Pandas,Matplotlib,Seaborn)
- 朱庇特笔记本。
- 对监督机器学习方法的基本理解:特别是分类。
第 0 阶段—数据准备
作为一名数据科学家,我们遇到的最乏味的任务是获取和准备数据集。即使这个时代有大量的数据,仍然很难找到一个合适的数据集来解决你试图解决的问题。如果找不到任何合适的数据集,您可能需要创建自己的数据集。
在本教程中,我们不会创建自己的数据集,相反,我们将使用由 UCI 机器学习资源库(著名的机器学习数据集资源库)提供的名为“ 皮马印第安人糖尿病数据库 ”的现有数据集。我们将使用上面提供的糖尿病数据集执行机器学习工作流。
第一阶段—数据探索
当遇到一个数据集时,首先我们应该分析并"了解"这个数据集。这一步对于熟悉数据、了解潜在特征以及确定是否需要清理数据是必要的。
首先,我们将导入必要的库,并将数据集导入 Jupyter 笔记本。我们可以观察数据集中提到的列。
%matplotlib inline
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as snsdiabetes = pd.read_csv('datasets/diabetes.csv')
diabetes.columns
指数([‘妊娠’,‘血糖’,‘血压’,‘皮肤厚度’,‘胰岛素’,
,‘身体质量指数’,‘糖尿病患者血糖’,‘年龄’,‘结果’],
dtype= ‘对象’)
重要提示:需要注意的是,上述数据集仅包含有限的特征,而实际上有许多特征在起作用。
我们可以使用熊猫的 head() 方法来检查数据集。
diabetes.head()
Fig — Diabetes data set
我们可以使用 panda Dataframes 的“shape”属性找到数据集的维度。
print("Diabetes data set dimensions : {}".format(diabetes.shape))
糖尿病数据集维度:(768,9)
我们可以观察到数据集包含 768 行和 9 列。结果是我们将要预测的列,表示患者是否患有糖尿病。1 表示该人是糖尿病患者,0 表示该人不是。我们可以确定,在 768 人中,500 人被标记为 0(非糖尿病),268 人被标记为 1(糖尿病)
diabetes.groupby('Outcome').size()
Fig— Class distribution
数据可视化是数据科学的一个重要方面。这有助于理解数据,也有助于向他人解释数据。Python 有几个有趣的可视化库比如 Matplotlib,Seaborn 等。
在本教程中,我们将使用构建在 matplotlib 之上的 pandas 可视化工具来查找要素的数据分布。
Fig— Data distribution
我们可以使用下面的代码分别为这两个响应绘制直方图。(此处未显示图像。)
diabetes.groupby(‘Outcome’).hist(figsize=(9, 9))
阶段 2—数据清理
机器学习工作流程的下一个阶段是数据清理。被认为是工作流程的关键步骤之一,因为它可以决定模型的成败。机器学习中有一句谚语**“更好的数据胜过更好的算法”**,这表明更好的数据会给你带来更好的结果模型。
在数据清理过程中,有几个因素需要考虑。
- 重复或不相关的观察。
- 数据标签错误,同一类别出现多次。
- 数据点缺失或为空。
- 意外的异常值。
在本教程中,我们不会详细讨论数据清理过程。
由于我们使用的是标准数据集,我们可以有把握地假设因素 1、2 已经处理过了。意外的异常值要么有用,要么有潜在的危害。
缺失或空数据点
我们可以使用下面的 pandas 函数找到数据集的任何缺失或空数据点(如果有的话)。
diabetes.isnull().sum()
diabetes.isna().sum()
我们可以观察到数据集中没有数据点丢失。如果有,我们应该相应地处理它们。
Fig — Observe missing data
意外异常值
当分析直方图时,我们可以发现在一些列中有一些异常值。我们将进一步分析这些异常值,并确定我们可以做些什么。
**血压:**通过观察数据我们可以看到,血压有 0 个值。很明显,数据集的读数似乎是错误的,因为一个活人的舒张压不可能为零。通过观察数据,我们可以看到值为 0 的 35 个计数。
print("Total : ", diabetes[diabetes.BloodPressure == 0].shape[0])Total : 35print(diabetes[diabetes.BloodPressure == 0].groupby('Outcome')['Age'].count())Outcome
0 19
1 16
Name: Age, dtype: int64
**血浆葡萄糖水平:**即使空腹后血糖水平也不会低至零。因此,零是无效的读数。通过观察数据,我们可以看到值为 0 的 5 个计数。
print("Total : ", diabetes[diabetes.Glucose == 0].shape[0])Total : 5print(diabetes[diabetes.Glucose == 0].groupby('Outcome')['Age'].count())Total : 5
Outcome
0 3
1 2
Name: Age, dtype: int64
**皮褶厚度:**对于正常人来说,皮褶厚度不可能小于 10 mm 最好为零。值为 0: 227 的总计数。
print("Total : ", diabetes[diabetes.SkinThickness == 0].shape[0])Total : 227print(diabetes[diabetes.SkinThickness == 0].groupby('Outcome')['Age'].count())Outcome
0 139
1 88
Name: Age, dtype: int64
身体质量指数:不应该是零或接近零,除非这个人真的体重不足,这可能会危及生命。
print("Total : ", diabetes[diabetes.BMI == 0].shape[0])Total : 11print(diabetes[diabetes.BMI == 0].groupby('Outcome')['Age'].count())Outcome
0 9
1 2
Name: Age, dtype: int64
**胰岛素:**在极少数情况下,一个人可以没有胰岛素,但通过观察数据,我们可以发现总共有 374 个计数。
print("Total : ", diabetes[diabetes.Insulin == 0].shape[0])Total : 374print(diabetes[diabetes.Insulin == 0].groupby('Outcome')['Age'].count())Outcome
0 236
1 138
Name: Age, dtype: int64
以下是处理无效数据值的几种方法:
- 忽略/删除这些情况:这在大多数情况下实际上是不可能的,因为这将意味着丢失有价值的信息。在这种情况下,“皮肤厚度”和“胰岛素”列意味着有许多无效点。但它可能适用于“身体质量指数”、“葡萄糖”和“血压”数据点。
- 放入平均值:这可能对一些数据集有效,但是在我们的例子中,把平均值放入血压列会给模型发送一个错误的信号。
- 避免使用特性:对于模型来说,不使用具有大量无效值的特性是可能的。这可能对“皮肤厚度”有效,但很难预测。
在数据清理过程结束时,我们得出结论,这个给定的数据集是不完整的。由于这是机器学习的演示,我们将对给定的数据进行一些小的调整。
我们将删除“血压”、“身体质量指数”和“葡萄糖”为零的行。
diabetes_mod = diabetes[(diabetes.BloodPressure != 0) & (diabetes.BMI != 0) & (diabetes.Glucose != 0)]print(diabetes_mod.shape)(724, 9)
第 3 阶段—特征工程
特征工程是将收集的数据转换为更好地代表我们试图解决的模型问题的特征的过程,以提高模型的性能和准确性。
特征工程从现有特征中创建更多的输入特征,并组合多个特征以生成更直观的特征来输入模型。
“特征工程使我们能够突出重要的特征,并便于将问题领域的专业知识带到桌面上来。尽管提供了许多输入特征,它还允许避免过度拟合模型”。
我们试图解决的问题领域需要许多相关的特性。由于数据集已经提供,并且通过检查数据,我们不能在这一点上进一步创建或删除任何数据。在数据集中,我们有以下特征。
怀孕’,‘葡萄糖’,‘血压’,‘皮肤厚度’,‘胰岛素’,‘身体质量指数’,‘糖尿病谱系功能’,‘年龄’
通过粗略的观察,我们可以说“皮肤厚度”不是糖尿病的指标。但是我们不能否认在这一点上它是不可用的。
因此,我们将使用所有可用的功能。我们将数据集分成特征和我们将要预测的响应。我们将把特征分配给 X 变量的**,把响应分配给 y 变量的。**
feature_names = ['Pregnancies', 'Glucose', 'BloodPressure', 'SkinThickness', 'Insulin', 'BMI', 'DiabetesPedigreeFunction', 'Age']X = diabetes_mod[feature_names]
y = diabetes_mod.Outcome
通常,特征工程在选择模型之前执行。然而,对于本教程,我们遵循不同的方法。最初,我们将利用数据集中提供给模型的所有功能,我们将再次讨论功能工程,以讨论所选模型的功能重要性。
这篇文章很好地解释了特征工程。
阶段 4—型号选择
模型选择或算法选择阶段是最令人兴奋的,也是机器学习的核心。在这个阶段,我们选择最适合手头数据集的模型。
首先,我们将使用默认参数计算一组给定分类模型的**“分类准确度(测试准确度)”**,以确定哪个模型在糖尿病数据集上表现更好。
我们将为笔记本导入必要的库。我们导入 7 个分类器,即K-最近邻、支持向量分类器、逻辑回归、高斯朴素贝叶斯、随机森林和梯度提升作为最佳分类器的竞争者。
from sklearn.neighbors import KNeighborsClassifier
from sklearn.svm import SVC
from sklearn.linear_model import LogisticRegression
from sklearn.tree import DecisionTreeClassifier
from sklearn.naive_bayes import GaussianNB
from sklearn.ensemble import RandomForestClassifier
from sklearn.ensemble import GradientBoostingClassifier
我们将使用默认参数初始化分类器模型,并将它们添加到模型列表中。
models = []models.append(('KNN', KNeighborsClassifier()))
models.append(('SVC', SVC()))
models.append(('LR', LogisticRegression()))
models.append(('DT', DecisionTreeClassifier()))
models.append(('GNB', GaussianNB()))
models.append(('RF', RandomForestClassifier()))
models.append(('GB', GradientBoostingClassifier()))
例:通常用 Scikit learn 训练模型如下。
KNN = KNeighborsClassifier()
KNN . fit(X _ train,y_train)
评估方法
通常的做法是避免对相同的数据进行训练和测试。原因是模型的目标是预测样本外数据,模型可能过于复杂,导致过度拟合。为了避免上述问题,有两个预防措施。
- 训练/测试分割
- k 倍交叉验证
我们将为训练/测试拆分导入*“train _ test _ split”,为 导入“cross _ val _ score】k 倍交叉验证* *。【accuracy _ score】*是评估训练/测试拆分方法中模型的准确性。
from sklearn.model_selection import train_test_split
from sklearn.model_selection import cross_val_score
from sklearn.metrics import accuracy_score
我们将执行上述方法,以找到性能最佳的基础模型。
训练/测试分割
这种方法将数据集分成两部分:一个训练集和一个测试集。训练集用于训练模型。测试装置用于测试模型,评估精度。
优点:但是,训练/测试分割仍然有用,因为它的灵活性和速度
缺点:提供样本外精度的高方差估计
Fig — Train/Test Split
用 Scikit 学习进行训练/测试分割:
接下来,我们可以将特征和响应分成训练和测试部分。我们对样本进行分层(在此过程中,每个响应类别在每个部分中的比例应该相等)。
X_train, X_test, y_train, y_test = train_test_split(X, y, stratify = diabetes_mod.Outcome, random_state=0)
然后,我们在一个循环中拟合每个模型,并使用*“accuracy _ score”*计算各个模型的精确度。
names = []
scores = []for name, model in models:
model.fit(X_train, y_train)
y_pred = model.predict(X_test)
scores.append(accuracy_score(y_test, y_pred))
names.append(name)tr_split = pd.DataFrame({'Name': names, 'Score': scores})
print(tr_split)
Fig — Train/Test Split Accuracy Scores
K 倍交叉验证
这种方法将数据集分成 K 个等分(“折叠”),然后使用 1 个折叠作为测试集,其他折叠的并集作为训练集。然后测试模型的准确性。该过程将遵循上述步骤 K 次,每次使用不同的折叠作为测试集。该工序的平均测试精度为测试精度。
**优点:**更精确的样本外精度估计。更“有效”地使用数据(每个观察结果都用于训练和测试)
**缺点:**比训练/测试分割慢得多。
Fig— 5-Fold cross validation process
在计算能力不匮乏的情况下,最好使用这种方法。从现在开始我们将使用这种方法。
使用 Scikit Learn 进行 K 倍交叉验证:
我们将继续进行 K-Fold 交叉验证,因为它更准确,并能更有效地利用数据。我们将使用 10 倍交叉验证来训练模型,并计算模型的平均准确度。“cross_val_score”提供了自己的训练和精度计算接口。
names = []
scores = []for name, model in models:
kfold = KFold(n_splits=10, random_state=10)
score = cross_val_score(model, X, y, cv=kfold, scoring='accuracy').mean()
names.append(name)
scores.append(score)kf_cross_val = pd.DataFrame({'Name': names, 'Score': scores})
print(kf_cross_val)
Fig — K-Fold Cross Validation Accuracy Scores
我们可以使用 seaborn 来绘制准确度分数
axis = sns.barplot(x = 'Name', y = 'Score', data = kf_cross_val)
axis.set(xlabel='Classifier', ylabel='Accuracy')for p in axis.patches:
height = p.get_height()
axis.text(p.get_x() + p.get_width()/2, height + 0.005, '{:1.4f}'.format(height), ha="center")
plt.show()
Fig — Accuracy of Classifiers
我们可以看到逻辑回归、高斯朴素贝叶斯、随机森林和梯度推进比其他方法表现得更好。从基础水平上,我们可以观察到逻辑回归比其他算法表现更好。
在基线时,逻辑回归设法实现了 77.64 %的分类准确度。这将被选为下一阶段的主要候选项目。
摘要
在本文中,我们讨论了基本的机器学习工作流程步骤,如使用 Scikit Learn 库进行数据探索、数据清理步骤、特征工程基础知识和模型选择。在下一篇文章中,我将更多地讨论特征工程和超参数调整。
更新
您可以在下面的链接中找到本系列的第 2 部分。
在本系列的上一篇文章中,我们讨论了关于糖尿病数据集的机器学习工作流。还有…
towardsdatascience.com](/machine-learning-workflow-on-diabetes-data-part-02-11262b7f7a5c)
创建这篇文章的源代码可以在下面找到。
这个库包含了各种用 Python 完成的机器学习的例子。
github.com](https://github.com/LahiruTjay/Machine-Learning-With-Python/blob/master/Machine%20Learning%20Workflow%20on%20Diabetes%20Data.ipynb)
如果你对这篇文章有任何问题,请不要犹豫,在下面留言或者给我发电子邮件:lahiru.tjay@gmail.com
希望你喜欢这篇文章。干杯!!!
糖尿病数据的机器学习工作流程:第 2 部分
在本系列的上一篇文章中,我们讨论了关于糖尿病数据集的机器学习工作流。并讨论了诸如数据探索、数据清洗、特征工程基础和模型选择过程等主题。你可以在下面找到之前的文章。
“医疗环境中的机器学习可以帮助显著增强医疗诊断。”
towardsdatascience.com](/machine-learning-workflow-on-diabetes-data-part-01-573864fcc6b8)
选择模型后,我们能够确定逻辑回归比其他选择的分类模型表现更好。在本文中,我们将讨论机器学习工作流的下一阶段,高级特征工程和超参数调整。
第 5 阶段—特征工程(再次访问)
并非所有的功能都必须是赢家。大多数时候,有些特性并不能改善模型。这种情况可以通过进一步分析与模型相关的特征来发现。“一个高度预测的特征可以弥补 10 个哑弹”。
正如在阶段 3 中提到的,在模型选择之后,应该进一步讨论特征工程。因此,我们将分析选择的逻辑回归模型,以及特征重要性如何影响它。
Scikit Learn 提供了有用的方法,通过这些方法我们可以进行特征选择,并找出影响模型的特征的重要性。
- 单变量特征选择 :统计检验可以用来选择那些与输出变量关系最强的特征。
- 递归特征消除 :递归特征消除(或 RFE)的工作原理是递归地删除属性,并在那些保留的属性上建立一个模型。它使用模型精度来确定哪些属性(和属性组合)对预测目标属性贡献最大。
- 主成分分析 :主成分分析(或称 PCA)利用线性代数将数据集转换成压缩形式。通常这被称为数据简化技术。PCA 的一个特性是可以选择变换结果中的维数或主分量。
- 特征重要性:随机森林和额外树等袋装决策树可以用来估计特征的重要性。
在本教程中,我们将使用递归特征消除作为特征选择方法。
首先,我们导入 RFECV,它带有内置的交叉验证特性。与分类器模型相同,RFECV 具有 fit()方法,该方法接受特性和响应/目标。
逻辑回归—特征选择
from sklearn.feature_selection import RFECVlogreg_model = LogisticRegression()rfecv = RFECV(estimator=logreg_model, step=1, cv=strat_k_fold, scoring='accuracy')
rfecv.fit(X, y)
拟合后,它会显示一个属性 grid_scores_ ,该属性会返回每个所选特征的精度分数列表。我们可以用它来绘制一个图表,以查看给定模型的最大精确度的特征数量。
plt.figure()
plt.title('Logistic Regression CV score vs No of Features')
plt.xlabel("Number of features selected")
plt.ylabel("Cross validation score (nb of correct classifications)")
plt.plot(range(1, len(rfecv.grid_scores_) + 1), rfecv.grid_scores_)
plt.show()
Fig — Feature importance of Logistic Regression
通过查看该图,我们可以看到,将 4 个特征输入到模型中会得到最佳的准确度分数。RFECV 展示了 support_ ,这是找出对预测贡献最大的特征的另一个属性。为了找出选择了哪些特性,我们可以使用下面的代码。
feature_importance = list(zip(feature_names, rfecv.support_))new_features = []for key,value in enumerate(feature_importance):
if(value[1]) == True:
new_features.append(value[0])
print(new_features)
[‘妊娠’,‘葡萄糖’,‘身体质量指数’,‘糖尿病血糖功能’]
我们可以看到,给定的特征最适合预测响应类。我们可以对具有原始特征和 RFECV 选定特征的模型进行比较,以查看准确性得分是否有所提高。
# Calculate accuracy scores
X_new = diabetes_mod[new_features]initial_score = cross_val_score(logreg_model, X, y, cv=strat_k_fold, scoring='accuracy').mean()
print("Initial accuracy : {} ".format(initial_score))fe_score = cross_val_score(logreg_model, X_new, y, cv=strat_k_fold, scoring='accuracy').mean()
print("Accuracy after Feature Selection : {} ".format(fe_score))
初始精度:0.7764400711728514
特征选择后的精度:0.2676486766
通过观察精度,在将所选特征输入模型后,精度会略有提高。
梯度增强-要素选择
我们还可以分析我们拥有的第二个最佳模型,即梯度增强分类器,以查看特征选择过程是否提高了模型准确性,以及在该过程之后它是否优于逻辑回归。
我们遵循与逻辑回归相同的程序
gb_model = GradientBoostingClassifier()gb_rfecv = RFECV(estimator=gb_model, step=1, cv=strat_k_fold, scoring='accuracy')
gb_rfecv.fit(X, y)plt.figure()
plt.title('Gradient Boost CV score vs No of Features')
plt.xlabel("Number of features selected")
plt.ylabel("Cross validation score (nb of correct classifications)")
plt.plot(range(1, len(gb_rfecv.grid_scores_) + 1), gb_rfecv.grid_scores_)
plt.show()
Fig — Feature importance of Gradient Boost
我们可以看到,拥有 4 个输入特征可以产生最高的精度。
feature_importance = list(zip(feature_names, gb_rfecv.support_))new_features = []for key,value in enumerate(feature_importance):
if(value[1]) == True:
new_features.append(value[0])
print(new_features)
[‘葡萄糖’,‘身体质量指数’,‘糖尿病胰岛素功能’,‘年龄’]
以上 4 个特征最适合模型。我们可以比较特征选择前后的准确率。
X_new_gb = diabetes_mod[new_features]initial_score = cross_val_score(gb_model, X, y, cv=strat_k_fold, scoring='accuracy').mean()
print("Initial accuracy : {} ".format(initial_score))fe_score = cross_val_score(gb_model, X_new_gb, y, cv=strat_k_fold, scoring='accuracy').mean()
print("Accuracy after Feature Selection : {} ".format(fe_score))
初始精度:0.764091206294081
特征选择后的精度:0.2666766667
我们可以看到,在特征选择之后,准确度有所提高。
然而逻辑回归比梯度推进更准确。因此,我们将在参数调整阶段使用逻辑回归。
阶段 6 —模型参数调整
Scikit Learn 为模型提供了合理的默认参数,从而给出了不错的准确度分数。它还为用户提供了调整参数的选项,以进一步提高精度。
在分类器中,我们将选择逻辑回归进行微调,其中我们更改模型参数,以便可能提高特定数据集模型的准确性。
我们可以使用 GridSearchCV 轻松执行穷举搜索,而不必手动搜索最佳参数,它会执行*“对估计器的指定参数值进行穷举搜索”*。
这显然是一个非常方便的工具,但当要搜索的参数很高时,它会带来计算成本的代价。
重要提示:在使用 GridSearchCV 时,有些模型的参数相互之间不兼容。由于 GridSearchCV 使用所有给定参数的组合,如果两个参数不能相互配合,我们将无法运行 GridSearchCV。
如果发生这种情况,可以提供一个参数网格列表来克服给定的问题。建议您阅读您正在尝试微调的的类文档,以了解参数之间的相互作用。
首先我们导入 GridSearchCV。
from sklearn.model_selection import GridSearchCV
逻辑回归模型有一些超参数,这些超参数不能相互作用。因此,我们提供了一个具有兼容参数的网格列表来微调模型。通过反复试验,找到了以下兼容参数。
逻辑回归类文档可以在这里找到。
# Specify parameters
c_values = list(np.arange(1, 10))param_grid = [
{'C': c_values, 'penalty': ['l1'], 'solver' : ['liblinear'], 'multi_class' : ['ovr']}, {'C': c_values, 'penalty': ['l2'], 'solver' : ['liblinear', 'newton-cg', 'lbfgs'], 'multi_class' : ['ovr']}
]
然后,我们将数据拟合到 GridSearchCV,GridSearchCV 针对给定的参数组合对数据执行 K 重交叉验证。这可能需要一段时间才能完成。
grid = GridSearchCV(LogisticRegression(), param_grid, cv=strat_k_fold, scoring='accuracy')grid.fit(X_new, y)
在训练和评分完成之后,GridSearchCV 提供了一些有用的属性来寻找最佳参数和最佳估计量。
print(grid.best_params_)
print(grid.best_estimator_)
Fig — Best attributes of the Logistic Regression
我们可以观察到最佳超参数如下。
{'C': 1, 'multi_class': 'ovr', 'penalty': 'l2', 'solver': 'liblinear'}
我们可以将最佳参数输入逻辑回归模型,并观察其准确性是否有所提高。
logreg_new = LogisticRegression(C=1, multi_class='ovr', penalty='l2', solver='liblinear')initial_score = cross_val_score(logreg_new, X_new, y, cv=strat_k_fold, scoring='accuracy').mean()
print("Final accuracy : {} ".format(initial_score))Final accuracy : 0.7805877119643279
我们可以得出结论,超参数调整并没有增加它的准确性。也许我们选择的超参数并不具有指示性。但是,欢迎您尝试添加更多的参数组合。
最重要的方面是进行超参数调整的过程,而不是结果本身。在大多数情况下,超参数调谐提高了精度。
我们设法实现了 78.05%的分类准确率,可以说这是非常好的。
结论
我们已经到了文章系列的结尾。在这个系列中,我们经历了整个机器学习工作流程。我们讨论了完成分类任务所需的理论和实践知识。
我们讨论了机器学习的工作流程步骤,如数据探索、数据清理步骤、特征工程基础和高级特征选择、模型选择和使用 Scikit Learn library 的超参数调整。
现在轮到你了!现在,您应该能够使用这些知识来尝试其他数据集。
创建这篇文章的源代码可以在下面找到。
这个库包含了各种用 Python 完成的机器学习的例子。
github.com](https://github.com/LahiruTjay/Machine-Learning-With-Python/blob/master/Machine%20Learning%20Workflow%20on%20Diabetes%20Data.ipynb)
如果你对这篇文章有任何问题,请不要犹豫,在下面留言或者给我发电子邮件:lahiru.tjay@gmail.com
机器学习从零到英雄:第一次在 Kaggle 上竞争所需的一切,循序渐进!
Taken from https://xkcd.com/552/.
我最近偶然看到了瑞秋·托马斯关于写下你所学的东西的重要性和价值的文章,以及 T2 关于为什么以及如何写的建议,因此我决定听从他们的建议,写一篇文章(这是有史以来第一次!).
这篇文章将讲述我希望在一年前就知道的一切,当时我第一次决定学习更多关于数据科学的知识——它是为任何对数据科学感兴趣的人准备的,无论是作为一种爱好还是作为一种潜在的职业。先学习 MOOC 并了解一些基本的 Python 知识将有助于你从本文中获得最大收益,但这并不是必须的。这篇文章不是为了展示什么令人印象深刻的东西(对不起,妈妈、爸爸和潜在的雇主),而是为了复习基础知识,帮助初学者有一个良好的开端。
涵盖话题:
- 引言。
- Kaggle 概述。
- 建立自己的环境。
- 预测房价竞赛综述。
- 加载和检查数据。
- 我们的模型:决策树、偏差-方差权衡和随机森林的解释。
- 预处理数据。
- 把所有的东西放在一起然后提交。
介绍
现在网上有几个高质量的机器学习教程和 MOOCs 是免费的。一年前,我疯狂阅读了 Udacity 的《ML 简介》( Intro to ML )( T7 ),我发现它非常平易近人,对初学者非常友好,它很好地向我介绍了基本的 ML 概念、几种流行的算法和 scikit-learn 的 API。学完课程后,很兴奋能学到更多东西,但又觉得有点失落。
在进行了一些研究后,我决定接下来最好的事情是查看一下 Kaggle ,这是一个受欢迎的谷歌拥有的预测建模竞赛平台。没有什么比通过实践亲自动手学习更好的了!
第一次在 Kaggle 上竞争是令人生畏的,并且经常令人沮丧(获得一个像样的分数更是如此!),所以这篇文章将关注如何参加你的第一场比赛,并利用 Kaggle 最大限度地提高你的个人成长和成功。
Kaggle —概述
House Prices competition landing page.
如果您已经非常熟悉 Kaggle,请随意跳到下一部分。否则:
最适合初学者的两个 Kaggle 比赛(也是作为 Kaggle 版本的“教程”)是泰坦尼克号(预测生存—二进制分类问题),和房价(预测价格—回归问题)。虽然我强烈建议在这两方面都进行检验和竞争,但本文将重点讨论后者。然而,大部分内容是通用的,同样适用于其他 Kaggle 竞赛和数据科学问题,所以如果你喜欢,可以随意选择泰坦尼克号或其他一些竞赛!
- 在每个竞赛的“概述”选项卡上,您可以看到一些关于竞赛及其数据集的背景信息、对提交内容进行评分的评估标准(因竞赛而异)以及特定于竞赛的常见问题。
- 在数据选项卡上,您可以看到数据的简要描述。我们将需要三个文件:
train.csv
、test.csv
和data_description.txt
(这是至关重要的,因为它包含了数据的更详细的描述)——把它们放在一个你可以容易访问的文件夹中。 - “讨论”选项卡就像一个特定于比赛的论坛——但是,不要低估它!在流行的跑步比赛中,它通常包含有价值的信息,因为比赛条款有时要求参与者公开分享他们在讨论板上使用的任何外部信息。例如数据泄露很难避免和处理,在比赛中偶尔发生。一方面,充分利用它对于获得最高分和赢得比赛至关重要,但另一方面,包含数据泄漏的模型对于任何实际目的和比赛的组织者来说通常都是无用的,因为它们包含“非法”信息。通常,一个勤奋的参与者会在讨论板上公开分享泄漏的信息,以平衡竞争环境并消除其竞争优势。除此之外,Kagglers 们经常分享信息,共同努力学习和成长为一个社区。在排行榜上排名靠前的人有时会分享他们的成功方法(通常是在比赛开始时或结束后)。
- 内核选项卡基本上是讨论板的应用的、基于代码的版本,在我看来是初学者要探索的最重要的选项卡。任何人都可以分享任何脚本或笔记本,连接到任何数据集或比赛,并完成文档,解释,可视化和输出,每个人都可以浏览,投票,复制和粘贴,甚至完全在他们的浏览器中运行!前面提到的两个竞赛都有许多有趣的、漂亮的、非常成功的内核,我强烈建议在亲自尝试过之后再去浏览它们。尽管这是一个相对较新的功能,Kaggle 仍在不断改进内核,甚至有一场 $100,000 的竞赛正在以“仅内核”模式进行。然而,内核常常令人不知所措,缺乏概念上的解释,或者假设有先验知识。换句话说,他们经常展示什么是有效的,但有时不是他们如何到达那里或者为什么它有效。
建立我们自己的环境
我强烈推荐使用 Python 3.6,并在 Jupyter Notebook 环境中使用任何与数据科学相关的东西(最流行的发行版称为’ Anaconda ',包括 Python、Jupyter Notebook 和许多有用的库)。然后,您可以随时通过在终端中键入jupyter notebook
来启动环境(或者通过 Anaconda GUI)。否则,这里显示的一切都可以在 Kaggle 网站上的私有内核中完成(完全在您的浏览器中),这本质上与 Jupyter 笔记本相同。
在我们开始之前,一些重要的 Jupyter 笔记本提示:
- 您可以开始键入任何方法名称,然后点击“Tab”来查看所有可能选项的列表。
- 类似地,选择任何一种方法并按几次“Shift-Tab”将会在你的笔记本中打开它的文档。
- 在任何语句前输入
%time
并执行单元格将会打印出执行需要多长时间。 - 类似地,在任何语句前键入
%prun
并执行单元格,将通过 Python 的代码分析器运行该语句并打印结果。
关于“魔法”命令的完整列表,请参考文档。前进!
预测房价的逐步指南
目标概述
这是一个监督学习问题——这意味着我们有一个训练集,它包括许多观察值(行)和关于它们的各种信息(列)。其中一列是我们希望能够预测的,通常称为“目标”变量或“因变量”,在分类问题中有时也称为“标签”或“类别”。在我们的情况下,这是销售价格(惊喜惊喜)。其他列通常被称为“独立”变量,或“特征”。我们也有一个测试集,其中也有许多观察值,除了目标变量之外,列完全相同,目标变量将会丢失,我们的工作是预测。因此,理想情况下,我们希望建立一个模型,该模型可以基于训练集学习自变量和因变量之间的关系,然后使用该知识尽可能准确地预测测试集的因变量(或目标变量)。由于目标变量是连续的——销售价格,它可以取任何值——这个问题被称为“回归”问题。
加载数据并查看一下
现在我们已经有了一个 Jupyter 笔记本,我们要做的第一件事是将数据加载到 Pandas 数据框架中。 Pandas 是一个流行而强大的库,它处理 Python 中与数据分析相关的一切,DataFrame 是它用来存储数据的对象的名称。
Opening documentation by hitting ‘Shift-Tab’ a few times.
最后一行使用方便的 Python 3.6 字符串格式将我们从 Kaggle 下载的 CSV 文件(代表“逗号分隔值”,这是一种常见的格式,也可以用任何标准软件如 Excel 直接查看)加载到 Pandas DataFrame 中。既然你会经常用到read_csv
,我建议现在浏览一下它的文档。一般来说,如果你不止一次遇到任何方法——浏览它的文档是一个好习惯,如上所述,你也可以直接在笔记本上这样做!第一次加载并查看 DataFrame 时,我注意到数据集中的第一列是Id
,表示数据集中该行的索引,而不是一个实际的变量。因此,在将数据加载到 DataFrame 时,我回过头来将index_col=’Id’
作为一个参数传递,以确保 Pandas 将它用作索引,而不是将其视为一个列并在它之前添加一个新的索引列——看看阅读文档是如何变得方便的?
现在,让我们看看训练集是什么样的!
A peek into the training set DataFrame.
如我们所见,Id
现在被正确应用。此外,训练集总共有 80 列(不包括Id
),其中 79 列是自变量,1 列是因变量。因此,我们期望测试集只有 79 列(独立变量),事实确实如此——现在就去检查吧!
这些数字和字符串中的大多数对我们来说还没有多大意义,敏锐的观察者会注意到“Alley”列的值可疑地全部是“NaN”(代表“不是数字”),这意味着这些值是缺失的。别担心,我们最终会解决这个问题的。
下一步是开始考虑我们想要使用什么样的模型。因此,让我们从数据中休息几分钟,谈论一下决策树(当应用于回归问题时,有时被称为‘回归树’)。事后我再来说数据,请大家多多包涵!
建模的简要说明
决策树介绍
这里的基本思想很简单,当学习训练数据(通常称为“拟合”训练数据)时,回归树搜索所有独立变量,然后搜索每个独立变量的所有值,以找到将数据分成两个相似组的最佳变量和值(在数学术语中,树总是选择将两个结果节点的加权平均方差最小化的拆分), 然后计算每个组的分数(基于选择的度量)和因变量的平均值。 然后,该树递归地重复这个过程,直到不再有需要执行的拆分(除非明确指定了 max_depth,如下图所示)。树的最后一级的每个节点被称为“叶子”,并且每个节点与到达该叶子的组中的所有观察值的因变量的平均值相关联。
顺便提一下,这是一个“贪婪”算法的很好的例子——在每次分割时,它都会检查所有选项,然后选择当时看起来最好的选项,希望最终获得一个整体良好的结果。在将树拟合到训练数据之后,我们希望为其预测因变量的值的任何观察都必须遍历树,直到它到达一个叶子(一个结束节点),然后它被赋予该叶子的相应因变量的值。
A visualized example from our dataset, with max_depth set to 3 for ease of visualization.
让我们仔细看看这里显示的树:在每个节点中,第一个元素是该节点的分裂规则(自变量及其值),第二个元素是该节点中所有观测值的均方误差(MSE) ,第三个元素是该节点中的观测值数量(‘样本’)—组的大小。最后一个元素“值”是我们的目标/因变量“销售价格”的自然对数。正如我们所看到的,似乎在每个节点进行局部最佳分裂的贪婪方法确实通常会随着树的扩展而降低 MSE,并且每个叶子都有相关的“销售价格”值。
偏差-方差权衡
让我们回想一下我们在监督学习中的目标。一方面,我们希望我们的模型能够在拟合训练数据时捕捉自变量和因变量之间的关系,以便能够做出准确的预测。但是,模型预测因变量所需的数据必然不同于模型的训练数据。在我们的例子中,它是 Kaggle 测试集。因此,我们希望我们的模型能够捕捉自变量和因变量之间的一般关系,以便它能够推广到看不见的数据并进行良好预测。这有时被称为“偏差——方差权衡”。
Bias —Variance Tradeoff
如果我们的模型没有从训练集中学习到足够的信息,那么它将具有很高的偏差,通常称为“欠拟合”,这意味着它没有捕捉到训练集中可用的所有信息,因此它的预测不会那么好。然而,如果我们的模型对我们的训练数据学习得太好,它将捕获训练集中自变量和因变量之间的特定关系,而不是一般关系,这将具有很高的方差,通常称为“过度拟合”,因此它将很难推广到看不见的数据,其预测也不会很好。显然,我们必须在模型的偏差和方差之间寻求平衡。
决策树过度拟合
想象一下,我们为我们的训练集拟合一棵回归树。这棵树会是什么样子?正如您可能猜到的那样,它将继续分裂,直到每片叶子中只有一个观察点(因为在该点没有更多的分裂可以执行)。换句话说,该树将为训练集中的每个观察值构建唯一的路径,并将为路径末端的叶子提供与其相关联的观察值的相关值。
如果我从我的训练集中删除因变量,并让我的树预测训练集中每个观察值的因变量值,会发生什么?正如您可能想象的那样,它会做得非常完美,基本上达到 100%的准确性和 0 MSE,因为它已经学习了与训练集中的每个观察值相关联的因变量值。
然而,如果我要求树预测未被训练的未被观察的因变量值,它可能会表现不佳,因为任何未被观察的观察结果最终都会从为训练集中的单个特定观察结果构建的叶子中被分配一个因变量值。这就是‘过拟合’的例子。有可能篡改树的参数以减少过度拟合——例如,限制树的 max _ depth——但事实证明有更好的解决方案!
解决方案——随机森林
在 ML 中,我们经常设计元模型,将几个较小模型的预测结合起来,以生成更好的最终预测。这通常被称为‘集合’。具体来说,几个决策树通常以一种集成方法组合在一起,称为‘Bootstrap Aggregating’,或简称为‘Bagging’。由此产生的元模型被称为【随机森林】。
随机森林简单但有效。当适合训练集时,会构建许多决策树,就像上面的一个决策树一样-只有每棵树适合数据的随机子集(“bootstrap sample”,意思是从整个数据集替换而成),并且在每次分裂时只能考虑独立变量(“特征”)的随机子集。然后,为了生成新观察的预测,随机森林简单地对其所有树的预测进行平均,并将其作为预测返回。
但是等等,柳文欢!我们所做的就是建造许多较弱的树,然后取它们的平均值——为什么会这样呢!?
嗯,简单的回答是它非常有效,如果你对统计解释感兴趣,你应该试着多读一些关于随机森林的书。我不太擅长统计学,但我会尝试给出一个基本的解释 bootstrap 采样和特征子集旨在使树尽可能不相关(尽管它们仍然基于相同的数据集和特征集),允许每棵树发现数据中略有不同的关系。这导致它们的平均值比任何单一的树具有更小的方差——更小的过拟合——因此总体上具有更好的泛化和预测能力。
更简单地说,对于一个看不见的观察,每个决策树预测观察结束的叶子的因变量值,这意味着在特定的树空间中最相似的训练集观察的值。正如我们所记得的,每棵树都是根据不同的数据以不同的方式构建的,因此每棵树都会以不同的方式定义相似性,并预测不同的值,因此对于给定的看不见的观察值,所有树的平均值基本上是训练集中与它有些相似的许多观察值的平均值。
此属性的一个结果是,当测试集与训练集有些相似(在相同的值范围内)时,随机森林非常擅长预测,这是通常的情况,但当测试集与训练集在某些基本方面不同(不同的值范围)时,它们在预测方面就很糟糕,例如在时间序列问题中(训练集来自一个时间段,而测试集来自不同的时间段)。
因为在我们的例子中,测试集和训练集具有相同的值范围,所以我们应该可以开始了!
回到比赛
强制预处理
在我们开始随机森林滚动之前,还有最后一件事要做。不幸的是,虽然随机森林理论上能够处理分类特征(非数字,所以是字符串)和缺失数据,但 scikit-learn 实现不支持这两者。现在,我们将使用[pd.interpolate()](https://pandas-docs.github.io/pandas-docs-travis/generated/pandas.DataFrame.interpolate.html#pandas.DataFrame.interpolate)
填充缺失值,然后使用[pd.get_dummies()](https://pandas.pydata.org/pandas-docs/stable/generated/pandas.get_dummies.html)
将分类特征转换为数字特征,这使用了一种称为“一键编码”的方案。这个想法很简单——让我们想象一个有 n 个可能值的分类变量。然后,该列被分成 n 个单独的列,每个列对应于一个原始值(本质上相当于 is _ value?对于每一个原始值)。每个观察值之前都有一个分类变量的字符串值,现在在对应于旧字符串值的列中有一个 1 ,在所有其余的列中有一个 0 (这被称为“One-Hot”)。
我们现在准备构建一个模型,使其适合训练数据,使用它在测试集上进行预测,并将预测提交给 Kaggle!
将所有这些放在一起并提交结果
这是将我们的模型预测提交给 Kaggle 所需的全部代码——大约 20 行!我运行了这段代码,然后将结果提交给 ka ggle——分数是 0.14978,目前大约是 63%。5 分钟的编码一点都不差!我们可以在这里看到随机森林的威力。
import pandas as pd
from sklearn.ensemble import RandomForestRegressorPATH = "Oren/Kaggle/Housing Prices/" #where you put the filesdf_train = pd.read_csv(f'{PATH}train.csv', index_col='Id')
df_test = pd.read_csv(f'{PATH}test.csv', index_col='Id')target = df_train['SalePrice'] #target variabledf_train = df_train.drop('SalePrice', axis=1)df_train['training_set'] = True
df_test['training_set'] = Falsedf_full = pd.concat([df_train, df_test])df_full = df_full.interpolate()
df_full = pd.get_dummies(df_full)df_train = df_full[df_full['training_set']==True]
df_train = df_train.drop('training_set', axis=1)df_test = df_full[df_full['training_set']==False]
df_test = df_test.drop('training_set', axis=1)rf = RandomForestRegressor(n_estimators=100, n_jobs=-1)
rf.fit(df_train, target)preds = rf.predict(df_test)
my_submission = pd.DataFrame({'Id': df_test.index, 'SalePrice': preds})
my_submission.to_csv(f'{PATH}submission.csv', index=False)
说明
在将训练集和测试集加载到单独的数据帧中之后,我保存了目标变量,然后将其从数据帧中删除(因为我想在数据帧中只保留自变量,即特征)。然后,我向训练集和测试集添加了一个新的临时列('training_set'
),以区分它们,这样我现在就可以将它们连接起来(将它们放在同一个数据帧中),以后再将它们分开。然后,我继续将它们连接起来,填充缺失的值,并通过一键编码将分类特征转换为数字特征。如前所述,当训练集和测试集具有相似的值时,随机森林(以及一般情况下的大多数算法)工作得更好,因此每当我修改任何东西时,我都会尝试一起修改这两个集。否则,interpolate
可能会为训练集和测试集填充不同的值,get_dummies
可能会以两种不同的方式对同一分类特征进行编码,这将导致更差的性能。然后,我再次将它们分开,去掉临时列,使用我计算机的所有 CPU 核心(n_jobs=-1
)创建一个有 100 棵树的随机森林(一般来说,树越多,结果越好,但训练需要的时间也越多),使用我的训练集拟合它,使用拟合的随机森林预测我的测试集的目标变量,将结果和它们各自的Id
放在一个数据帧中,并保存到一个 CSV 文件中。然后我去了 Kaggle 上的比赛页面并提交了 CSV 文件。瞧啊。
下一步是什么?
在接下来的文章中,我们将深入探讨这一竞争,并讨论可视化,这是一种更好的预处理、特征工程、模型验证和超参数调整的方法。作为家庭作业,尝试学习更多关于这些主题的知识,也许阅读一两个 Kaggle 内核,看看你是否可以提高分数并进入前 50%,或者提交你对泰坦尼克号比赛的预测。
推荐资源
- 文档!熊猫和 Scikit-Learn 都有大量的文档和许多有趣的讨论。
- 要了解更多关于 Kaggle 成功故事的信息,我推荐 Kaggle 博客,在那里他们经常采访竞赛获胜者,询问他们的方法和途径。
- 对于数据帧的详细摘要,我推荐查看熊猫-摘要和熊猫-简介。
- 对于更高级的随机森林用法的精彩解释,我推荐对随机森林的直观解释。
- 所有相关的 Reddit:r/machine learning, r/learnmachinelearning , r/datascience 。