终极人工智能战略指南
Strategy and AI are terms that are hard to pin down — they mean different things to different people. Combine AI and Strategy — 人工知能 战略 — and now you have a harder problem to tackle! The goal of this post is to bring in the best advice out there about AI strategy and add a practitioner’s point of view for a successfully crafting AI strategy.
这篇文章分为三个部分。战略和规划,构建模块——启动和维持人工智能的技术、人员/文化和路线图。
在过去的几年里,人工智能将成为商业的一个主要因素已经变得非常清楚。Gartner 将人工智能纳入了 2019 年十大战略技术趋势。大多数公司都敏锐地意识到,他们至少应该有一个人工智能战略。不说别的,追随人工智能对手的倾向很高[1]。
围绕这项技术的激烈竞争表明,观望策略可能是一个代价高昂的错误。为了从人工智能到 2030 年将产生的 1 万亿美元的全球利润池中分得一杯羹,麦肯锡全球研究所表示,公司应该在未来三年内开始大规模采用人工智能。
然而,企业正在努力制定正确的人工智能战略,这非常像他们在 90 年代末采用电子商务时遇到的挑战。新生技术的采用可能会导致许多问题——选择或花费在错误的计划上,没有找到合适的人才,选择了错误的方向。
战略与人工智能基础
首先,让我们明确战略的定义。我喜欢鲁梅尔特定义战略的方式,并将遵循他的不废话、务实的方法。在《好策略,坏策略》中,鲁梅尔特写道,一个策略有三个关键部分,它们构成了策略核心。
- 诊断——出了什么问题,为什么?将技术与商业战略联系起来
- 指导政策—基础、治理、文化、道德
- 一致的行动—资源分配、实施、购买/建造决策、流程编排、人才培养/雇用/保留、文化和变革管理
其次,让我们来定义人工智能:广义上讲,人工智能包括用于教计算机学习、推理、感知、推断、交流和做出类似于或优于人类的决策的技术。人工智能领域包括智能自动化、机器学习(经典机器学习和现代深度学习,也称为深度神经网络)和机器人技术。自动驾驶汽车结合了许多现代人工智能的象征。
这是我的一行人工智能商业方程式。
A I =数据+算法+计算→业务问题→结果
困难的问题是制定一个适合你特定业务环境的人工智能策略——也就是说,它考虑了所有的外部因素和内部因素。吴恩达建议“成为你所在行业的领先人工智能公司,开发独特的人工智能能力将让你获得竞争优势。”
安德鲁补充说,人工智能如何影响你公司的战略将因行业和情况而异。
许多专家指出,你不能把人工智能战略作为第一步,因为你需要发展对人工智能的理解,而这需要在不确定的情况下进行实验。这有通过 AI 的所谓良性循环学习的好处。
From Andrew Ng — AI Transformation Playbook [4] — Link
就像任何坚固建筑的建筑要求一样,你需要从地面条件开始,并确保你建立一个坚固的基础。否则,无论你建造什么上层建筑,将来都会遇到代价高昂的问题。
接下来的部分将更多地讨论如何利用适合您情况的数据、算法和计算基础设施来构建数字基础。你需要具有不同背景、教育和技能的人——例如,你需要具有数据专业知识和机器学习知识的人,但也需要擅长沟通业务和技术问题的人,也称为“翻译”你需要强大的流程。
对人工智能的好处和局限性要现实。人工智能有很好的用例,也有可能让你陷入没有清晰价值路径的兔子路。一家公司可以采取一种渐进的方式,比如在参与更复杂的项目之前,尝试机器人流程自动化。
“人工智能将改善产品和流程,并使决策更加明智——这是重要但基本上不可见的任务。”托马斯·达文波特[10]
正如鲁梅尔特指出的,看看糟糕策略的例子会有所帮助,这样你就可以避免它。以下是一些常见的不良策略。
- 把目标误认为战略——不要只是说你想要人工智能的领导地位,要创造条件让你达到目标
- 模糊的战略目标——一长串要做的事情,却没有如何实现的明确计划,缺乏对精力和资源的关注
- 缺乏协调的行动-重复工作、所有权政治、发出混合信号的决策、高级管理人员缺乏对人工智能的基本理解
- 无法选择和区分优先顺序——哪些项目适合人工智能?我们应该选择什么样的管理和组织结构?
了解构建模块—技术
记住,战略就是采取行动克服障碍或抓住机遇。任何人工智能努力都将依赖于三个主要组成部分:数据、基础设施和人才。
- 数据是当今人工智能驱动洞察力的基本元素——在许多情况下超过算法本身。需要付出巨大的努力和投资才能让您的数据基础正确。提高数据质量和管理数据是一项复杂而长期的工作。对于所有行业的管理者来说,数据所有权都是一个令人头疼的问题。一些数据是专有的,其他数据是跨数据源的碎片,需要整合并与多个其他组织达成协议,以便获得更完整的信息来训练人工智能系统。
跨客户群和渠道链接数据,而不是让数据在孤岛中枯萎,对于创造价值尤为重要。——麦肯锡[15]
- **计算基础设施,**包括软件和硬件,必须到位以有效运行机器学习模型。ML 需要专门的硬件(GPU、FPGA 或 ASIC),无论是在云中还是在内部(由于法规或其他业务原因)。)
- 人工智能在有效利用机器学习方面至关重要。虽然不是每个公司都会寻求建立一个内部人工智能组织,但接触经验丰富的数据科学家、数据工程师、数据产品经理和人工智能开发运营专家是推动人工智能价值并将其扩展到盈利能力的关键。
吴恩达[4]建议说,一个公司要想在人工智能方面表现出色,它必须具备:
在多个有价值的人工智能项目上系统执行的资源——无论是外包的还是内部的技术和人才。
对人工智能有足够的了解:应该对人工智能有一个总体的了解,有适当的过程来系统地识别和选择有价值的人工智能项目。
战略方向:为了在人工智能驱动的未来取得成功,公司的战略是否大体一致**?**
建筑材料——人与文化
你可能认为技术是人工智能战略的关键,但是人和文化对你的人工智能战略的成功和技术一样重要。在 O’Reilly 最近的一份调查报告中,很明显文化是人工智能采用的主要挑战。首先,人工智能需要不同的团队一起工作,如果合作文化不存在,人工智能计划就会受到影响。
人工智能还意味着对人们的工作和流程的改变和破坏。伴随人工智能的自动化可以取代许多工作,并迫使其他人学习新技能。大多数时候它是一个黑盒,对于某些场景,它的价值是未经证实的。难怪许多工作人员担心人工智能,并随着人工智能的实施感到脱离了他们的舒适区。
算法需要新的治理模式。正如任何文化变革一样,在做出重大改变之前,要小心谨慎。
根据 O’Reilly Media 的调查结果,不承认需求、缺乏数据和人才短缺的企业文化阻碍了人工智能在各组织中的广泛采用。
**瓶颈。大量受访者(23%)表示,公司文化是采用人工智能的主要障碍,19%表示最大的问题是缺乏数据或数据质量,18%表示缺乏技术人员和难以雇用人才,17%表示难以确定适当的业务用例,8%表示是技术基础设施挑战。
人才招聘和管理仍然是一个关键因素。在你开始招聘之前,定义一下合适的团队是什么样的?你需要有深度、多种技能、经验丰富、多元化的人。正如本帖[12]所指出的,正确的团队应该包括领域专家和社会科学家,他们可以提供互补的观点并支持技术团队。不要沉迷于雇佣 AI 的摇滚明星而不创造成功的条件。
正如在[6]中提到的,人工智能技术管理还有更多。
人工智能技术的管理还涉及新的领导技能,包括实施嵌入人工智能的现代流程所需的技能。成功接受人工智能的公司致力于转型计划,高层管理人员接受变革,跨职能管理团队准备重新定义他们的流程和活动。
创建和鼓励跟踪和揭示人工智能决策的方法——最好使用行动审计跟踪和可视化或解释结果的功能。让设计师和 UI / UX 专家参与进来。确保非技术经理很好地理解解释。
当然,良好的沟通或缺乏沟通是问题的主要原因[9]。
人工智能战略之所以失败,是因为人工智能是一种手段,而不是目的。“你有人工智能战略吗?”就像问“我们有 Excel 战略吗?”但对于公司来说,要想摆脱炒作,专注于人工智能提供的真正潜力,他们必须从如何沟通开始。
要注意的差距
注意 3 个关键差距:业务-IT 差距、数据分析差距和老手-新手差距(稍后会有更多关于人员和文化的部分)。在人工智能中建立信任和检测并消除偏见仍然是人工智能采用的最大挑战之一。
正如 Moldoveanu 在这篇 HBR 的文章[9]中提到的,技术人员和商业人士之间有非常不同的工作方式。
开发人员希望清晰、精确的指令能够很容易地翻译成代码或伪代码。业务发展主管为他们提供故事和趣闻。
Credit: Avanade.com
还有一个不容忽视的风险因素。如果你的人工智能策略有负面后果或监管问题,它可能会适得其反。请看[13]了解更多信息,以及[14]如何降低这种风险。
道德、公平和包容性需要认真考虑。在华盛顿邮报的专栏中,黑石集团首席执行官苏世民推荐了一种道德驱动的人工智能方法,告诉消费者人工智能何时被使用,避免偏见,解决隐私问题,并寻求为被技术取代的工人创造机会。
这些都是热门话题,有许多不同的观点,详细的讨论超出了本文的范围——参见我关于公平和负责任的人工智能的初级读本[11]中对关键问题的总结。
启动和维持人工智能计划的路线图
以上几节谈到了技术、人员、文化和道德。现在,让我们讨论一些部署和扩展人工智能计划的实用方法以及企业面临的常见挑战。成功执行战略的关键成功因素包括有效的流程和治理、管理资源和规避风险。本节包括一系列工具和资源,帮助你走上人工智能应用的正确道路。
- 共同的挑战
- 结构
- 推荐
- 清单
- 数字成熟度评估
挑战——不要低估人工智能成功所需的挑战和努力
有了这么多的宣传和炒作,公司可能会很容易加入进来,认为人工智能可以很快产生有利的结果。研究表明,组织往往会低估克服复杂性和让人工智能起飞所需的时间。
人工智能的实验和学习可能比其他数字计划需要更长的时间,成功和失败的可变性更高。
根据 2017 年年度企业调查的结果,目前正在试点人工智能项目的公司中,58%的受访者表示花了两年或更长时间才达到试点阶段,只有 28%的受访者报告说在第一年就通过了规划阶段。
一些组织迷失在许多不同的原型和 POC 中,无法扩展—您不会经常听到失败的项目或计划,它们开始时有很多讨论,但后来因为结果的质量或缺乏明确的 ROI 而失败。较大的组织在创建卓越中心和提供监督但允许业务单位自治的组织结构方面取得了成功。
通过与你的同行交谈和倾听从业者,而不仅仅是倾向于过分强调成功故事的分析师和作者,来获得一些现实。
信任是一个主要因素。你如何让非技术团队相信人工智能解决方案是可靠和可依赖的?深度学习是一个热门领域,但众所周知,很难解释它如何做出决定。要做到这一点,需要精心的规划和沟通。
如果你的人工智能策略引发负面后果或导致监管问题,它可能会适得其反。请看[13]了解更多信息,以及[14]如何降低这种风险。
人工智能战略规划
这个简单的图表抓住了人工智能战略计划的关键要素。
Credit: Gartner, Inc. [5]
人工智能框架
最好从业务成果的角度来考虑人工智能战略,然后再回到常见的企业功能和解决方案领域。例如,如果你有一个很好的聊天机器人用例,那么这项技术可以被多个群体使用。
管理人工智能团队
存在许多模型——集中式和分布式模型各有利弊。
AI 策略建议
- 数字成熟度:你在数字成熟度曲线上处于什么位置?你如何能加速它,以便你能加快人工智能能力的步伐?
- ****评估业务潜力:什么是正确的用例?是否有足够的价值?深入思考用例,评估多种场景
- 渐进方法:对人工智能之旅采取分阶段的方法。在短期内,专注于具有成熟技术的用例;中期,试验技术以评估其价值;从长远来看,与尖端技术合作可以给企业带来先发优势。记住,人工智能技术还不成熟,不要期望马上就有投资回报
- 领导能力:抵制让技术团队单独负责人工智能项目的诱惑。发展应该由商业和技术领导者共同领导[麦肯锡]
- 制造 vs 购买:你应该建造、购买还是外包?你有理解各种新方法的天赋吗?正如任何被大肆宣传的新技术一样,新创造的解决方案和顾问并不缺乏。在整个组织中发展核心领导力和知识,同时根据需要从外部专家那里获得帮助
人工智能战略清单
这里有一个 Gartner 关于人工智能采用的简单清单。
Credit: Gartner, Inc. [5]
人工智能数字成熟度评估
即使是在有着大量集成新技术和管理数据历史的行业,人工智能采用的障碍也可能难以克服。人工智能需要更激进的思维,因为它影响了基于知识和判断的职业。这篇来自麻省理工斯隆评论的文章问道:是什么阻止了组织采用 AI?
关于作者:Sam Ransbotham 是卡罗尔学校信息系统系的副教授…
sloanreview.mit.edu](https://sloanreview.mit.edu/projects/reshaping-business-with-artificial-intelligence/)
它定义了四个不同的组织成熟度集群:先锋、调查者、实验者和被动者
- 先锋(19%): 既了解又采用 AI 的组织。这些组织在将人工智能纳入其组织的产品和内部流程方面处于领先地位。
- 调查人员(32%): 了解人工智能但没有在试点阶段之后部署它的组织。他们对人工智能可能提供什么的调查强调先看后跳。
- 实验者(13%): 在没有深入了解的情况下,正在试点或采用 AI 的组织。这些组织在实践中学习。
- 被动型(36%): 对 AI 没有采用或了解不多的组织。他们还没有找到符合他们投资标准的可靠的商业案例。领导层可能不同意。
结论
这篇文章展示了人工智能策略的许多方面。最终,最重要的是愿景和领导力、开放性和变革能力、长期思维、业务和技术战略的紧密结合,以及克服障碍和适应新技术的文化。
参考资料:
- 雅克·布欣**。观望可能是一种代价高昂的人工智能策略。麻省理工斯隆评论,2018。https://Sloan review . MIT . edu/article/wait-and-see-be-a-cost-ai-strategy/**
- 好策略,坏策略。皇冠出版社,2011 年。(也可以看这篇关于这本书的 r 兴高采烈的帖子。)
- 微软 AI 商学院。在线看https://www.microsoft.com/en-us/ai/ai-business-school
- 吴恩达。AI 改造剧本(可从https://landing.ai/ai-transformation-playbook/获得),登陆 AI。2019.
- Bern Elliott,在企业中应用人工智能的框架(网络研讨会演示文稿),Gartner.com,2018 年。
- 雅克·布欣和埃里克·哈赞。从人工智能中获得最大收益的五种管理策略。McKinsey.com 和麻省理工斯隆管理评论,2017。https://www . McKinsey . com/mgi/overview/in-the-news/five-management-strategies-for-get-the-most-from-ai
- 人工智能战略家指南。普华永道战略+业务,2017。
- 编辑惠特·安德鲁斯。构建人工智能商业案例。首席信息官在企业中实施人工智能的战略和商业案例指南。Gartner.com。2018.
- 米尼亚·莫尔多瓦努。为什么人工智能表现不佳,公司可以做些什么。HBR,2019。https://HBR . org/2019/03/why-ai-表现不佳,公司能做些什么?
- 托马斯·达文波特。人工智能的优势:如何将人工智能革命付诸实施。麻省理工出版社。2018.
- 巴巴尔·巴蒂。公平负责的 ML 和 AI 入门。https://towards data science . com/ai-policy-making-part-4-a-primer-on-fair-and-responsible-ai-28f 52 b 32190 f
- 卡西·科兹尔科夫。为什么企业在机器学习上失败。https://hacker noon . com/why-business-fail-at-machine-learning-fbff 41 c 4d db
- 迈克尔斯潘塞。2019 年人工智能的危险。https://medium . com/future sin/the-dangeries-of-artificial-intelligence-in-2019-19e 14 fa 45 aa 4
- 伯恩哈德·巴贝尔、凯文·布勒、亚当·皮冯卡、布莱恩·理查德森和德里克·瓦尔德罗。衍生机器学习和人工智能。麦肯锡,2019。https://www . McKinsey . com/business-functions/risk/our-insights/derisking-machine-learning-and-artificial-intelligence
- 迈克尔·楚伊(Michael Chui)、詹姆斯·马尼伊卡(James Manyika)、迈赫迪·米雷马迪(Mehdi mire madi)尼古拉·亨克(Nicola us Henke)、丽塔·钟(Rita Chung)、彼得·内尔(Pieter Nel)和桑卡普·马尔霍特拉(Sankalp Malhotra)。麦肯锡,2018。https://www . McKinsey . com/featured-insights/artificial-intelligence/notes-from-the-ai-frontier-applications-and-value-of-deep-learning**
数据搜集、清理和可视化初学者终极指南
如何简单地通过清理和预处理数据,让您的模型从不起眼变得令人惊叹
Photo by Nitin Sharma from Pexels
如果你有一个结果可以接受但并不惊人的模型,看看你的数据吧!花时间以正确的方式清理和预处理您的数据可以让您的模型成为明星。
为了更详细地了解搜集和预处理,让我们来看看“你就是你发的微博:通过 Twitter 使用检测社交媒体中的抑郁症”中的一些工作这样,我们可以真正检查抓取推文,然后清理和预处理推文的过程。我们还将做一些探索性的可视化,这是一种更好地了解您的数据的方式!我们将在这里做一些最基本的清理和预处理工作:当你建立你的模型时,真正把这些 Tweets 按顺序整理好是你自己的事!
通过 Twitter 使用检测社交媒体中的抑郁症
towardsdatascience.com](/you-are-what-you-tweet-7e23fb84f4ed)
一点背景
超过 3 亿人患有抑郁症,只有一小部分人接受了适当的治疗。抑郁症是全球残疾的主要原因,每年有近 80 万人死于自杀。自杀是 15-29 岁人群的第二大死因。抑郁症的诊断(和随后的治疗)经常被延迟、不精确和/或完全错过。
不一定要这样!社交媒体为转变早期抑郁症干预服务提供了前所未有的机会,特别是在年轻人中。
每秒钟,Twitter 上大约有 6000 条推文,相当于每分钟发送 35 万条推文,每天 5 亿条推文,每年约 2000 亿条推文。皮尤研究中心指出,目前,72%的公众使用某种类型的社交媒体。该项目捕捉并分析与抑郁症状的发作和持续相关的语言标记,以建立一种可以有效预测抑郁的算法。通过建立一种可以分析表现出自我评估抑郁特征的推文的算法,个人、父母、护理人员和医疗专业人员将有可能分析社交媒体帖子,以寻找标志着精神健康恶化的语言线索,这远远早于传统方法。分析社交媒体帖子中的语言标记可以进行低调的评估,这种评估可以补充传统服务,并且可以比传统方法更早地意识到抑郁迹象。
我们从哪里开始?
我们需要数据!
Photo by Quang Nguyen Vinh from Pexels
收集数据
为了建立一个抑郁症检测器,需要两种推文:不一定表明抑郁症的随机推文和表明用户可能患有抑郁症和/或抑郁症状的推文。随机推文的数据集可以来源于 Kaggle 上可用的sensition 140 数据集,但对于这种二进制分类模型,这种利用 sensition 140 数据集并提供一组二进制标签的数据集被证明是建立稳健模型的最有效方法。没有公开可用的表明抑郁的推文数据集,所以使用 Twitter 抓取工具 TWINT 检索“抑郁”推文。手动检查抓取的推文的相关性(例如,推文表明情绪而非经济或气氛抑郁),并清理和处理推文。通过搜索与抑郁症特别相关的术语,特别是 De Choudhury 等人在 unigram 中确定的词汇术语,来收集推文。艾尔。
TWINT 是一款非常简单易用的工具!
您可以使用以下命令从命令行下载它:
pip install twint
例如,如果您想要搜索 2019 年 7 月 20 日的术语“抑郁症”,并将数据存储为名为“抑郁症”的新 csv,您可以运行类似以下的命令:
twint -s "depression" --since 2019-07-20 -o depression —csv
一旦你收集了推文,你就可以开始清理和预处理它们。您可能会得到大量不需要的信息,比如对话 id 等等。您可以决定创建多个想要合并的 CSV。我们会谈到这一切的!
模特表现如何?
一开始?没那么令人印象深刻。在对数据进行基本的清理和预处理之后,最好的结果(即使在花费时间对模型进行微调之后)徘徊在 80%左右。
在我检查了词频和二元模型后,这个原因真的很有意义。探索您的数据!当我看到单词本身时,我意识到以正确的方式清理和准备数据集需要大量的工作,并且这样做是绝对必要的。部分清洁过程必须手动完成,所以不要害怕进去弄脏你的手。这需要时间,但是值得!
最后呢?使用逻辑回归对该模型的准确性进行评估,并与二元分类基线模型进行比较。分析模型的准确性,并运行分类报告以确定精确度和召回分数。数据被分成训练集、测试集和验证集,模型的准确性是根据模型对测试数据的性能来确定的,测试数据是分开保存的。虽然使用相同的数据、学习率和时期,基准逻辑回归模型的性能为 64.32%,但 LSTM 模型的性能明显更好,为 97.21%。
那么,我们是如何从抓取的推文得到结果的呢?
练习,练习,练习!(还有一些正经工作。)
(如果你是数据科学、机器学习和人工智能的新手,你可能想看看 NumPy 的终极初学者指南!)
开始使用 NumPy 需要知道的一切
towardsdatascience.com](/the-ultimate-beginners-guide-to-numpy-f5a2f99aef54)
基本清洁和预处理
比方说,我们在 Twitter 上搜索“抑郁”、“沮丧”、“无望”、“孤独”、“自杀”和“抗抑郁”等搜索词,并将这些搜索到的推文文件保存为文件“tweets.csv”中的“抑郁”等。
我们将从几个进口开始
**import** **pandas** **as** **pd**
**import** **numpy** **as** **np**
**import** **pandas** **as** **pd**
**import** **numpy** **as** **np**
**import** **matplotlib.pyplot** **as** **plt**
plt.style.use('fivethirtyeight')
%matplotlib inline
%config InlineBackend.figure_format = 'retina'
**import** **re**
**from** **nltk.tokenize** **import** WordPunctTokenizer
tok = WordPunctTokenizer()
我们将阅读我们的一个 CSV 文件,并看看头部。
hopeless_tweets_df = pd.read_csv('hopeless/tweets.csv')
hopeless_tweets_df.head()
首先,我们应该去掉数据集中存储的任何不必要的信息。对于这个项目,我们不需要名称、id、对话 id、地理位置等等。我们可以通过以下方式将它们取出:
hopeless_tweets_df.drop(['date', 'timezone', 'username', 'name', 'conversation_id', 'created_at', 'user_id', 'place', 'likes_count', 'link', 'retweet', 'quote_url', 'video', 'user_rt_id', 'near', 'geo', 'mentions', 'urls', 'photos', 'replies_count', 'retweets_count'], axis = 1, inplace = **True**)
现在有了这个,就好处理多了!
现在,只需对您使用搜索词创建的所有 CSV 进行上述操作,我们就可以将我们单独的数据集合并为一个!
df_row_reindex = pd.concat([depression_tweets_df, hopeless_tweets_df, lonely_tweets_df, antidepressant_tweets_df, antidepressants_tweets_df, suicide_tweets_df], ignore_index=**True**)
df_row_reindex
在我们继续之前,让我们放弃重复
depressive_twint_tweets_df = df.drop_duplicates()
并将我们的数据集保存为新的 CSV 格式!
export_csv = depressive_twint_tweets_df.to_csv(r'depressive_unigram_tweets_final.csv')
更高级的预处理
在模型中使用数据之前,有必要展开缩写、删除链接、标签、大写和标点符号。需要处理否定。这意味着创建一个否定字典,这样被否定的单词就可以被有效地处理。链接和网址需要删除连同空白。此外,需要删除标准 NLTK 停用词以外的停用词,以使模型更加健壮。这些单词包括一周中的日子及其缩写、月份名称,以及单词“Twitter”,令人惊讶的是,当单词 clouds 被创建时,它作为一个突出的单词出现。然后将推文标记化,并使用 PorterStemmer 来阻止推文。
让我们去掉所有对我们没有帮助的东西!
当然是进口
**import** **pandas** **as** **pd**
**import** **numpy** **as** **np**
**import** **matplotlib.pyplot** **as** **plt**
**import** **seaborn** **as** **sns**
**import** **itertools**
**import** **collections
import** **re
import** **networkx** **as** **nx****import** **nltk** nltk.download(['punkt','stopwords'])
**from** **nltk.corpus** **import** stopwords
stopwords = stopwords.words('english')
**from** **nltk.corpus** **import** stopwords
**from** **nltk** **import** bigrams
**import** **warnings**
warnings.filterwarnings("ignore")
sns.set(font_scale=1.5)
sns.set_style("whitegrid")
**from** **vaderSentiment.vaderSentiment** **import** SentimentIntensityAnalyzer
analyzer = SentimentIntensityAnalyzer()%matplotlib inline
%config InlineBackend.figure_format = 'retina'
阅读您的新 CSV
pd.read_csv('depressive_unigram_tweets_final.csv')
把它变成熊猫的数据框
df2 = pd.read_csv('depressive_unigram_tweets_final.csv')
现在让我们看看是否有空值。我们来清理一下吧!
我们将快速删除推文中的停用词
df_new['clean_tweet'] = df_new['tweet'].apply(**lambda** x: ' '.join([item **for** item **in** x.split() **if** item **not** **in** stopwords]))
如果你愿意,你可以分析这些推文来获得 VADER 情绪分析分数!
df_new['vader_score'] = df_new['clean_tweet'].apply(**lambda** x: analyzer.polarity_scores(x)['compound'])
在那里,您还可以创建标签。对于二进制分类模型,您可能需要二进制标签系统。但是,要注意你的数据!情绪得分本身并不表明抑郁,假设负得分表明抑郁也太简单了。事实上,快感缺失是抑郁症极其常见的症状。中性或平淡的推文,如果不是更有可能,至少也是抑郁症的一个指标,不应被忽视。
出于实验的目的,您可能想要设置一个这样的情感分析标签。请随意使用它!
positive_num = len(df_new[df_new['vader_score'] >=0.05]) negative_num = len(df_new[df_new['vader_score']<0.05])df_new['vader_sentiment_label']= df_new['vader_score'].map(**lambda** x:int(1) **if** x>=0.05 **else** int(0))
如果你需要,扔掉你不需要的东西
df_new = df_new[['Unnamed: 0', 'vader_sentiment_label', 'vader_score', 'clean_tweet']]df_new.head()
继续保存一个 csv!
df_new.to_csv('vader_processed_final.csv')
我们继续玩吧!
df_new['text'] = df_new['clean_tweet']
df_new['text']
我们可以删除网址
**def** remove_url(txt):
**return** " ".join(re.sub("([^0-9A-Za-z **\t**])|(\w+:\/\/\S+)", "", txt).split())all_tweets_no_urls = [remove_url(tweet) **for** tweet **in** df_new['text']]
all_tweets_no_urls[:5]
现在让我们把所有的东西都变成小写,把推文分开。
*#lower_case = [word.lower() for word in df_new['text']]*
sentences = df_new['text']all_tweets_no_urls[0].split()words_in_tweet = [tweet.lower().split() **for** tweet **in** all_tweets_no_urls]
words_in_tweet[:2]
手工清洗
这不好玩,也不漂亮,但是手工清洁是至关重要的。这花了几个小时,但是去掉了对热带低气压和经济低气压的引用改进了模型。删除电影标题的推文改进了模型(你可以在下面的二元图中看到“X 特遣队”)。删除包含搜索术语的引用新闻标题改进了模型。感觉要花很长时间才能完成,但是这一步对模型的健壮性产生了巨大的影响。
探索性可视化和分析
现在我们来看性格和词频!
分析数据集中最常见的单词相当容易。去掉停用词后,很明显有些词比其他词出现得更频繁。
来统计一下我们最常用的单词吧!
*# List of all words*
all_words_no_urls = list(itertools.chain(*words_in_tweet))
*# Create counter*
counts_no_urls = collections.Counter(all_words_no_urls)
counts_no_urls.most_common(15)
并把它们转换成数据帧。
clean_tweets_no_urls = pd.DataFrame(counts_no_urls.most_common(15),
columns=['words', 'count'])
clean_tweets_no_urls.head()
嗯。停用词太多。让我们来处理这些。
stop_words = set(stopwords.words('english'))*# Remove stop words from each tweet list of words*
tweets_nsw = [[word **for** word **in** tweet_words **if** **not** word **in** stop_words]
**for** tweet_words **in** words_in_tweet]
tweets_nsw[0]
让我们再看一看。
all_words_nsw = list(itertools.chain(*tweets_nsw)) counts_nsw = collections.Counter(all_words_nsw) counts_nsw.most_common(15)
好些了,但还不够好。这些单词中的一些并没有告诉我们太多。再做几个调整吧。
collection_words = ['im', 'de', 'like', 'one']
tweets_nsw_nc = [[w **for** w **in** word **if** **not** w **in** collection_words]
**for** word **in** tweets_nsw]
现在
*# Flatten list of words in clean tweets*
all_words_nsw_nc = list(itertools.chain(*tweets_nsw_nc))
*# Create counter of words in clean tweets*
counts_nsw_nc = collections.Counter(all_words_nsw_nc)
counts_nsw_nc.most_common(15)
好多了!让我们将它保存为数据帧。
clean_tweets_ncw = pd.DataFrame(counts_nsw_nc.most_common(15),
columns=['words', 'count'])
clean_tweets_ncw.head()
那看起来像什么?我们来形象化一下吧!
fig, ax = plt.subplots(figsize=(8, 8))
*# Plot horizontal bar graph*
clean_tweets_no_urls.sort_values(by='count').plot.barh(x='words',
y='count',
ax=ax,
color="purple")
ax.set_title("Common Words Found in Tweets (Including All Words)")
plt.show()
让我们来看看一些大人物!
**from** **nltk** **import** bigrams
*# Create list of lists containing bigrams in tweets*
terms_bigram = [list(bigrams(tweet)) **for** tweet **in** tweets_nsw_nc]
*# View bigrams for the first tweet*
terms_bigram[0]*# Flatten list of bigrams in clean tweets*
bigrams = list(itertools.chain(*terms_bigram))
*# Create counter of words in clean bigrams*
bigram_counts = collections.Counter(bigrams)
bigram_counts.most_common(20)bigram_df = pd.DataFrame(bigram_counts.most_common(20), columns=['bigram', 'count']) bigram_df
某些二元模型也非常常见,包括微笑和宽阔,出现 42,185 次,害怕和孤独,出现 4,641 次,感觉和孤独,出现 3,541 次。
这只是清理、预处理和可视化数据的开始。在构建我们的模型之前,我们还可以从这里做很多事情!
一旦清理了推文,通过用清理过的推文创建单词云,很容易看出两个数据集之间的差异。仅通过 TWINT Twitter 的简短抓取,两个数据集之间的差异就很明显:
随机推文词云:
郁啾词云:
在这个过程的早期,很明显,为了获得更准确的结果,优化模型的最重要部分是数据收集、清理和预处理阶段。在对推文进行适当的清理之前,该模型的准确性并不令人印象深刻。通过更加仔细地清理和处理推文,模型的鲁棒性提高到了 97%。
如果您对了解数据清理和预处理的绝对基础感兴趣,可以看看这篇文章!
如何在几分钟内为机器学习模型成功准备数据
towardsdatascience.com](/the-complete-beginners-guide-to-data-cleaning-and-preprocessing-2070b7d4c6d)
感谢阅读!和往常一样,如果你用这些信息做了什么很酷的事情,请在下面的评论中让每个人都知道,或者随时联系我们!
下一个 Golang 项目的终极设置
注:这最初发布在martinheinz . dev
对我来说,当开始一个新项目时,最大的困难总是试图“完美地”完成这个项目。我总是试图使用最好的目录结构,这样一切都很容易找到,导入工作也很好,设置所有命令,这样我总是一次点击/命令就可以完成所需的操作,为我正在使用的语言/库找到最好的 linter、formatter、测试框架…
这个清单还在继续,但我从来没有对这个设置感到满意过…除了这个最终的和最好的 Golang 设置!
注意:这个设置工作得很好,部分原因是它基于现有的项目,这些项目可以在 这里 和 这里 找到。
TL;博士:这是我的知识库—https://github.com/MartinHeinz/go-project-blueprint
目录结构
首先,让我们回顾一下我们的项目的目录结构。有几个顶级文件和 4 个目录:
pkg
-让我们从简单的开始-pkg
是一个 Go 包,它只包含全局版本字符串。这将替代在构建过程中根据提交哈希计算的实际版本。config
-接下来,有一个配置目录,其中包含所有必要的环境变量。任何文件类型都可以使用,但是我推荐 YAML 的文件,因为它们可读性更好。build
-该目录包含构建和测试应用程序以及为代码分析工具生成报告所需的所有 shell 脚本cmd
-真实源代码!按照惯例,源目录被命名为cmd
,里面有另一个项目名称的目录——在本例中是blueprint
。接下来,在这个目录中有一个运行整个应用程序的main.go
,和它一起的还有所有其他被划分成模块的源文件(稍后会详细介绍)。
注:从一些反馈中,我发现很多人更喜欢使用 *internal*
和 *pkg*
目录来存放他们所有的源代码。我个人觉得这是不必要和多余的,因此我把一切都放进 *cmd*
,但各归各的。
除了目录之外,还有相当多的文件,我们将在下面的章节中讨论它们。
Go 模块实现完美的依赖性管理
项目使用各种各样的依赖管理策略。然而,从版本 1.11 开始 Go 有了官方的依赖管理解决方案。我们所有的依赖项都列在go.mod
文件中,这个文件可以在根目录中找到。这可能是它看起来的样子:
你可能会问*“文件是如何被依赖关系填充的?”*。很简单,你只需要一个命令:
该命令根据go.mod
文件和 Go 源代码的状态重置主模块的供应商目录,以包含构建和测试所有模块包所需的所有包。
实际源代码和配置
现在我们终于开始讨论源代码了。如上所述,源代码被分成模块。每个模块都是源根目录下的一个目录。每个模块都有源文件和测试文件,例如:
这种结构有助于提高可读性和可维护性,因为它将代码分成了更容易遍历合理的块。至于配置,在这个设置中我使用了 Viper ,它是 Go 配置库,可以处理各种格式、命令行标志、环境变量等。
那么我们这里怎么用(蝰蛇)呢?我们来看看config
套餐:
这个包由一个文件组成。它声明了一个保存所有配置变量的函数struct
,还有一个加载配置的函数LoadConfig
。它采用配置文件的路径,在我们的例子中,我们将使用路径到config
目录,该目录位于项目根目录中,包含我们的 YAML 文件(如上所述)。我们如何使用它?我们在main.go
中首先运行它:
简单快速的测试
仅次于代码本身的第二重要的东西?质量测试。为了愿意编写大量好的测试,您需要一个能让您轻松做到这一点的设置。为了实现这一点,我们将使用名为test
的Makefile
目标,它收集并运行cmd
子目录中的所有测试(所有带有_test.go
后缀的文件)。这些测试也会被缓存,所以它们只有在相关代码发生变化时才会运行。这是至关重要的,如果测试太慢,你将(很可能)最终停止运行和维护它们。除了单元测试之外,make test
还可以帮助您维护一般的代码质量,因为它还会在每次测试运行时运行gofmt
和go vet
。go fmt
强制你正确格式化你的代码,而go vet
使用试探法发现任何可疑的代码结构。示例输出:
总是在 Docker 中运行
人们经常说*“它在我的机器上工作(而不是在云中)……”,为了避免这一点,我们有一个简单的解决方案——总是在 docker 容器中运行。当我说总是时,我是认真的——在容器中构建,在容器中运行,在容器中测试。其实上一节我没提,但是make test
真的是“就】* docker run
。
那么,这里是怎么运作的?让我们从项目根中的Dockerfiles
开始——我们有两个,一个用于测试(test.Dockerfile
),一个用于运行应用(in.Dockerfile
):
test.Dockerfile
-在理想情况下,我们应该只有一个 docker 文件来运行和测试应用程序。然而,在运行测试时,可能需要对环境进行一些小的调整。这就是为什么我们在这里有这个图像——允许我们安装额外的工具和库,以防我们的测试需要它。例如,让我们假设我们有一个正在连接的数据库。我们不希望每次测试运行都启动整个 PostgreSQL 服务器,也不希望依赖主机上运行的一些数据库。因此,我们可以使用内存数据库进行测试。但是,你猜怎么着? SQLite 二进制要求。那么,我们该怎么办?我们只需安装gcc
和g++
,翻转CGO_ENABLED
标志,就可以开始了。in.Dockerfile
-如果你在存储库中查看这个Dockerfile
,它只是一堆参数和将配置复制到映像中-那么,那里发生了什么?当我们运行make container
时,in.Dockerfile
仅在Makefile
中使用,在那里参数被填充。现在,是时候看看Makefile
本身了,它为我们做了所有的docker
事情。👇
用 Makefile 把它们结合在一起
很长一段时间以来,Makefiles
对我来说似乎很可怕,因为我只见过它们与C
代码一起使用,但它们并不可怕,可以用于很多事情,包括这个项目!现在让我们探索一下Makefile
中的目标:
-
make test
-工作流中的第一步-应用构建-在bin
目录中构建二进制可执行文件: -
make test
-下一个是测试-它再次使用几乎相同的docker run
,唯一的区别是test.sh
脚本(仅相关部分):
上面几行是文件的重要部分。首先,它们使用给定的路径作为参数来收集测试目标。第二行运行测试并将输出打印到 std out。剩下的两行分别运行go fmt
和go vet
,收集错误(如果有)并打印出来。
make container
-现在,最重要的部分-创建可部署的容器:
这个目标的代码非常简单,它首先替换in.Dockerfile
中的变量,然后运行docker build
来生成带有*【dirty】和【latest】*标签的图像。最后,它将容器名打印到标准输出中。
- 接下来,当我们有图像时,我们需要把它存储在某个地方,对吗?因此,
make push
所做的就是将图像推送到 Docker 注册表。 make ci
—Makefile
的另一个好用途是在我们的 CI/CD 管道中利用它(下一节)。这个目标与make test
非常相似——它也运行所有的测试,但是除此之外,它还生成覆盖报告,这些报告随后被用作代码分析工具的输入。make clean
-最后,如果我们想要清理我们的项目,我们可以运行make clean
,这将删除由先前的目标生成的所有文件。
我将省略其余的,因为正常工作流程不需要它们,或者它们只是其他目标的一部分。
CI/CD 带来终极编码体验
最后,但绝对不是最不重要的— CI/CD 。有了这么好的设置(如果我自己这么说的话),省略一些花哨的管道将是一种耻辱,这些管道可以为我们做大量的事情,对吗?我不会对管道中的内容进行过多的详细描述,因为您可以在这里自己查看(我还包括了几乎每一行的注释,所以一切都有解释),但是我想指出几件事:
这个 Travis 构建使用矩阵构建和 4 个并行作业来加速整个过程
- 构建和测试我们验证应用程序是否按预期工作
- SonarCloud 生成覆盖报告,并将其发送到 SonarCloud 服务器
- 这里,和上一个一样,我们生成报告并发送给 CodeClimate
- 推送到注册表 —最后,我们将容器推送到 GitHub 注册表(敬请关注关于此事的博文!)
结论
我希望这篇文章能对你未来的编码冒险有所帮助。如果你想看到更多的细节,请点击查看仓库。此外,如果您有任何反馈或改进的想法,请不要犹豫,提交问题,签署回购协议或给一颗星,这样我知道再多做一点工作是有意义的。🙂
在下一部分中,我们将看看如何扩展这个蓝图来轻松构建 RESTful APIs,使用内存数据库进行测试,并设置 swagger 文档(您可以先睹为快,在库的[rest-api](https://github.com/MartinHeinz/go-project-blueprint/tree/rest-api)
分支中)。
解除数据装瓶
探索葡萄酒的大数据世界。
动机
在这篇博文中,我们将使用关于葡萄酒的数据来研究几种不同的数据探索方法!我们将展示一步一步的代码,并解释我们的过程。在我们开始深入研究代码之前,我们为自己提出了几个问题,我们希望回答关于葡萄酒数据集的问题:
- 哪些国家的葡萄酒评论最多?
- 世界上最好的葡萄酒来自哪里?
- 最贵的葡萄酒来自哪里?
- 酒价和积分有关联吗?
- 有哪些词描述了 10 大葡萄酒类型?
- 描述能预测葡萄酒的一个特征吗?
这些问题和其他发现将在博客文章的剩余部分使用自然语言处理(NLP)、文字云、地图可视化和 Python 中的其他计算来解决。
数据
我们在 Kaggle 上找到了我们的数据集“葡萄酒评论”。该数据集包含超过 130,000 条葡萄酒评论条目。每个条目都包含葡萄酒来自的国家,葡萄酒的描述,名称(葡萄来自的酒厂内的葡萄园),葡萄酒爱好者在 1-100 的范围内给葡萄酒评分的点数,一瓶葡萄酒的价格,葡萄酒来自的省或州,葡萄酒产区或葡萄酒种植区,葡萄酒评论的标题,用于酿造葡萄酒的葡萄的品种或类型,最后是酒厂。下面可以看到部分原始数据。
wine_reviews = pd.read_csv(“winemag-data_first150k.csv”)
wine_reviews.dropna() # drop any empty entries
del wine_reviews['Unnamed: 0'] # delete first column
wine_reviews.head()
The first five entries from the Wine Reviews dataset.
哪些国家的葡萄酒评论最多?
排名前 10 位的国家有 143,344 篇评论,占所有评论的 95%。数据集中总共有 46 个国家。
在这个数据集中,美国拥有最多的葡萄酒评论,有 62397 条评论(41.34%)。这并不令人惊讶,因为数据集来自纽约的 wine fessor 公司。紧随美国之后的是意大利(15.56%)、法国(13.98%)、西班牙(5.48%)和智利(3.85%)。
下面的地图是交互式的,请访问 这个链接 来看看它在行动。
世界上最好的葡萄酒来自哪里?
令人惊讶的是,英国以平均 92.89 分的葡萄酒评论分数高居榜首。有趣的是,美国没有进入前十名。回顾频率数据,英国只有 9 篇评论,与美国的 62397 篇相比太少了。我们的数据有偏差,这不是最公平的比较。
下面的地图是互动的,请访问 这个链接 来看看它在行动。
最贵的葡萄酒来自哪里?
英国以平均 47.50 美元的价格成为最贵葡萄酒的第一名。法国紧随其后,平均价格为 45.61 美元,匈牙利以 44.20 美元紧随其后。美国排名第 8,均价 33 美元。
下面的地图是交互式的,请访问 这个链接 来看看它的作用。
酒价和积分有关联吗?
首先,我们可以查看一些价格和积分的汇总统计数据。
wine_reviews.describe()
我们来形象化一下酒价和积分的分布。
plt.figure(figsize=(15,5))
plt.subplot(1, 2, 1)
plt.hist(wine_reviews[‘price’], color='#ba281e')
plt.xlabel(“Price”)
plt.ylabel(“Frequency”)
plt.title(“Distribution of Wine Prices”)plt.subplot(1, 2, 2)
plt.hist(wine_reviews[‘points’], color='#ba281e')
plt.xlabel(“Points”)
plt.ylabel(“Frequency”)
plt.title(“Distribution of Wine Review Points”)plt.tight_layout()
plt.show()
我们现在可以看看变量 price 和 points 之间的关系。使用 seaborn 软件包,我们可以可视化变量之间的关系。
import seaborn as snsplt.figure(figsize=(10,14))
ax = sns.jointplot(x='price', y='points', data=x[x['price'] < 200], kind='hex', gridsize=20, cmap='Reds')
plt.tight_layout()
plt.show()
积分和价格之间存在正相关关系——随着葡萄酒价格的上涨,给予葡萄酒的积分也会增加。平均价格在 20 美元左右,平均积分在 88 分左右。我们还可以查看获得 100 分的葡萄酒的分布情况。我们看到即使是再便宜的酒也能拿满分!
# prices of wines that received perfect points
perfect_score = wine_reviews[‘points’]==100
perfect_wines = wine_reviews[perfect_score]
plt.hist(perfect_wines['price'], color ='#ba281e')
plt.xlabel("Price")
plt.ylabel("Frequency")
plt.title("Wines with 100 Points")
plt.show()
有哪些词描述了 10 大葡萄酒类型?
利用词云,我们分析了 10 大葡萄酒类型的描述。我们去掉了像葡萄酒、瓶子、玻璃杯、香料、葡萄、倒酒、啜饮、和品尝这样的词,这样我们只剩下了描述词。下面的代码展示了我们是如何创建这两个单词云的。其余的单词云也是用同样的方法创建的。
# creates the word clouds
bordeaux_wc = wordcloud.WordCloud(background_color=”white”, max_words=1000, mask=transformed_wine_mask, contour_width=3, contour_color=’firebrick’).generate(bordeaux_style_white_blend)syrah_wc = wordcloud.WordCloud(background_color=”white”, max_words=1000, mask=transformed_wine_mask, contour_width=3, contour_color=’firebrick’).generate(syrah)
从上面的词云可以看出,排名前 10 的葡萄酒的热门词包括果味、辛辣、干、甜味、香气、口感、药草、单宁。一些葡萄酒有更具体的描述:
- 波尔多风格白葡萄酒:苹果、柑橘、蜂蜜、葡萄柚、酸度
- 西拉:胡椒,复杂,甘草,年轻,优雅
- 麝香葡萄:甜品,酸度均衡,杏子,金银花
- Prugnolo: 皮革、烟、烟草、脆、厚
描述能预测葡萄酒的一个特征吗?
为了解决这个问题,我们研究了数据,寻找可用于预测的特征。我们发现变量省和品种在很大程度上呈偏态分布,而点呈正态分布。我们决定用这个描述来预测一款酒的得分。
创建和训练模型: 首先,我们使用来自预训练的全局向量文本文件的单词嵌入对描述文本进行预处理,该全局向量文本文件根据单词之间的关系对单词进行评级。然后,我们使用 3 种不同的模型来评估如何根据描述预测点数。这些模型包括 1D 卷积神经网络(CNN)、具有长短期记忆(LSTM)层的 1D CNN 和具有门控递归单元(GRU)的 1D CNN。CNN 是阅读单词嵌入的基本模型。LSTM 擅长在单词序列中寻找模式。GRU 是另一种递归神经网络架构,与 LSTM 类似,GRU 擅长理解单词上下文。我们没有使用纯粹的 LSTM 模型,因为它们在情绪预测方面表现不佳。下面的代码是 1D 有线电视新闻网。
*# set parameters:*
max_features = vocab_size
maxlen = 132
BATCH_SIZE = 128
embedding_dims = 50
filters = 250
kernel_size = 3cnn = Sequential()
*# start with an efficient embedding layer which maps*
*# vocab indices into embedding_dims dimensions*
embedding_layer = Embedding(vocab_size, 100, weights=[embedding_matrix], input_length=maxlen , trainable=**False**)
cnn.add(embedding_layer)
*# we add a Convolution1D, which will learn filters*
*# word group filters of size filter_length:*
cnn.add(Conv1D(BATCH_SIZE,
kernel_size,
padding='valid',
activation='relu',
strides=1))*# we use max pooling:*
cnn.add(GlobalMaxPooling1D())
*# We add a vanilla hidden layer:*
cnn.add(Dense(BATCH_SIZE))
cnn.add(Activation('relu'))
*# We project onto a single layer*
cnn.add(Dense(1))
cnn.compile(loss='mse',
optimizer='adam',
metrics=['accuracy'])
Model summary output for 1D CNN.
评估模型: 表现最好的模型是 1D CNN,其在验证集上获得了 30%的准确度和 3 点的平均误差(基于均方误差的误差)。我们还尝试在 5 分的范围内将分数分成几类。使用这种方法,模型的准确率为 62%,平均误差为 0.3 点。我们的结果告诉我们,对于一个给定的描述,很难预测一个精确的点值,因为有太多的变化。然而,我们似乎可以很好地预测一定范围内的描述。
问题: 给出的描述对预测有些什么问题。只有 20 位独特的审查者对该数据集做出了贡献。每个评论者都有自己的写作风格,使得预测问题变得更具挑战性。
反光
这个项目对我们来说是一个很好的机会,可以使用我们在大数据计算分析课上学到的大部分技能。不幸的是,我们无法访问不关注美国葡萄酒的数据集。如果时间允许,我们也想做一个针对美国的分析。我们希望使用更好的数据集来进行其他预测,例如查看葡萄酒的原产地如何影响其评级。
参考
[## 屏蔽的 word cloud-word cloud 1 . 6 . 0 . post 1+g 8217 e 20 文档
amueller.github.io](https://amueller.github.io/word_cloud/auto_examples/masked.html#sphx-glr-auto-examples-masked-py) [## 气泡图 D3 图形库
如何用 Javascript 和 D3.js 构建顶部带有标记的地图:从最基本的例子到高度定制化…
www.d3-graph-gallery.com](https://www.d3-graph-gallery.com/bubblemap.html) [## API 参考- seaborn 0.9.0 文档
在 FacetGrid 上绘制关系图的图形级界面。
seaborn.pydata.org](https://seaborn.pydata.org/api.html)
由 Derek Albosta、Woo Jung、Emma Sheridan 和 Erik Tacam 完成的大数据计算分析课程项目。这个项目的源代码可以在 GitHub 上找到。在 这里可以找到 的交互式地图可视化。
不炒作 AI
问我们任何事情
让我们一劳永逸地揭开艾的神秘面纱。它的根源是什么?AI 真的在这里吗?如果不是,那么当前的现实是什么?
我担任 TDS 的编辑助理已经有几年了,我很高兴看到的内容质量让我深受鼓舞,最重要的是,我从中学习。我还意识到,对于这个不断发展的学科中的所有技术专长,我们也需要回答一些关于人工智能的基本问题。我将在“向我们提问”中回答这些问题。欢迎大家的评论。尽情享受吧!
人工智能真的存在吗?
在最纯粹的定义里,人工智能还没有到来。
谷歌大脑的负责人杰弗里·辛顿认为,计算机可以像人类一样思考,使用直觉,而不是规则。表示[这个](https://cacm.acm.org/news/225209-mr-robot/fulltextcornerstones of):
我们是机器……我们只是被生物制造出来的。大多数做人工智能的人都不会怀疑我们是机器。我们只是极其奇特的机器。而我不应该说只是。我们是特别的、奇妙的机器。
顾名思义,这就是人工智能之父约翰·麦卡锡所说的:
人工智能是制造智能机器,尤其是智能计算机程序的科学和工程。
因此,计算机支持的系统将处理信息,以类似于人类在学习、决策和解决问题中的思维过程的方式产生结果。以下是人工智能的基石:
- 从经验中学习
- 它使用学习推理
- 它感知——意义,识别图像,声音等等。
- 解决复杂的问题
- 理解语言及其细微差别
- 创建透视图
- 随着时间的推移,它降低了错误率
事实上,人工智能是一个宽泛的术语,出现于 20 世纪 50 年代,当时人们试图让计算机执行人类任务。当我们朝着这个目标前进的时候,我们离这个现实要远得多。
我们今天对人工智能的大多数认同包括大规模的数字处理,它考虑了比人类可能更多的变量,以对输入的数据进行分类,并能够做出相当好的预测。
以下是人工智能的阶段:
- **狭义 AI(ANI)——**专门协助或接管特定任务。
- 通用 AI (AGI) —机器有自我意识,有能力执行通用智能动作。AI 将军将会有效地处理你扔给它的任何问题。
- 超级 AI(ASI)——比人类聪明一个数量级的机器。
- 奇点——在这个阶段,关键词是超越和“由 ASI 实现的指数发展道路可能导致人类能力的大规模扩展
今天,机器被训练。人类编写代码是为了创造一个能够学习一件事的系统。我们正处在这样一个时代,我们正在教机器做一件或几件事情,做得和人类一样好,甚至比人类更好。
Robot Thinker — AI Progress via Deposit Photos
AI 的根源是什么?
生物神经元和人类如何处理信息
为了理解人工智能如何进化,我们还需要理解人脑,一直到单个神经元——这是人工智能的心脏。神经元是大脑和神经系统的特化细胞,在全身传递信号。他们的互动定义了我们是什么样的人。神经元会感知内部和外部刺激。神经元也将处理信息并在全身传递信号。它们会将这些信号以命令的形式发送到我们的肌肉,指导我们的行动。
我们从内部和外部收到的每一个刺激都会将这些信号发送到我们系统中的其他神经元。考虑到普通人每分钟有 48.6 个想法,相当于每天 70,000 个想法。如果这些想法中有 10%在全身传递信号,那么超过 7000 个信号可以发出命令,促使身体肌肉执行诸如去商店、给朋友打电话、搜索信息等功能。因此,通过人工智能,这种方法是通过计算机复制生物神经元的行为:神经元中的每个节点都代表着向网络中的其他节点发出信号的信息。这些信号以难以想象的速度处理网络中的信息,并激活其他神经元的信号…等等…
人脑由大约 10 亿个神经元组成。每个神经元与其他神经元形成约 1000 个连接,总计超过 1 万亿个连接。
据《科学美国人》报道:
如果每个神经元只能存储一个单一的记忆,空间不足将是一个问题。你可能只有几千兆字节的存储空间,类似于 iPod 或 USB 闪存驱动器中的空间。然而,神经元结合在一起,每个神经元同时帮助许多记忆,以指数方式将大脑的记忆存储容量增加到大约 2.5 千兆字节(或 100 万千兆字节)。相比之下,2.5 兆字节相当于大约 300 万小时的电视节目。如果你的大脑像 PVR 一样工作,2.5 千兆字节将足以容纳 300 万小时的电视节目。你必须让电视连续运行 300 多年才能用完所有的存储空间。
计算机能思考到什么程度?
现实检验:计算机的表现和它们被训练的数据一样好。机器学习和深度学习都取得了重大进展。
机器学习 —可以定义为一种通过系统实现人工智能的方法,该系统可以从经验中学习,以在一组数据中找到模式。这意味着,通过例子教计算机识别模式,而不仅仅是用特定的规则给它编程。在常见的例子中,机器学习可以用来训练计算机识别图像,并通过计算机视觉进行分类,理解和分析人类语言,包括文本和语音(自然语言处理)。
理解神经元的功能对 Hinton 在深度学习实践中创建神经网络有着重要的贡献。根据的定义,神经网络是一套算法,大致模仿人脑,设计用来识别模式一个神经网络通常包括大量并行运行的处理器和分层排列的:
- 输入层 —第一层接收原始输入信息——这类似于人类视觉处理中视神经的功能。
- 隐藏层 —中间层是由神经元无止境的组合和连接而产生的。每一个连续的层接收来自它前面的层的输出。根据神经元连接的体积和组合,可能有许多隐藏层。隐藏层的作用是将输入转换成输出层可以使用的东西。
- 输出层 —最后一层产生系统的输出,即输入层和隐藏层交互的结果(或动作)。通过反向传播,输出层也将隐藏层激活转换为输出函数所需的比例。当他们学习和吸收更多关于世界的信息时,他们会改变自己。
我们试图用这种机械的方式来模仿人脑的功能。我们的大脑分布在一个巨大的细胞网络上,由无尽的神经元地图连接,沿着十亿条路径放电、连接和传输。”
要回答这个问题,计算机无法思考,至少在人类的水平上是如此。随着更多信息的获取,计算机能够在数据和表面见解中寻找模式。计算机做不到的是准确定义上下文。人类的认知很容易区分演员汤姆·克鲁斯和一艘游轮。随着时间的推移,计算机需要大量的数据输入才能始终如一地做出这些简单的区分。为了做到这一点,他们还需要时间来成熟,并被他们的前辈——是的,被辛顿视为人类的“特殊奇妙的机器”)抚养长大
感谢阅读。如果您有任何问题想问我们的团队,您可以在这里提问。
拆箱机器学习:黑盒模型的特征重要性
Source: unsplash — Free stock images
因为当我们理解事物时,生活会更美好
在之前的一篇文章中,讨论了在进行数据科学和机器学习时良好的绘图技巧的重要性,我写了一点关于我们应该如何认真对待可解释性和可解释性。正如我之前已经说过的:你可能是一个天才,但是如果你不能向第三方解释你是如何以及为什么得到那些美妙的预测,那么你可能什么都没有。想象一下,告诉某人她或他有超过 90%的可能性患有致命疾病,但却无法解释她/他你是如何得出这个结论的,或者是什么具体症状导致你得出这样的结论。
事实上,在我最近阅读的一本名为《赤裸裸的统计数据》的书中,作者 Charles Wheelon 花了很多时间讲述医疗费用的增加是如何给在卫生行业工作的数据科学家带来压力的。为什么?历史上,当谈到假阳性与假阴性的权衡时,这个行业是作为一个例子给出的。因为当然,如果我们必须选择,我们总是希望开发一个具有高召回率的模型——最大限度地减少假阴性(即人们患有疾病,但被归类为没有疾病)的数量,而不是一个具有高精确度的模型——最大限度地减少假阳性(即人们没有患病,但被归类为患有疾病)的数量。然而,Wheelon 解释了如今让某人进入医疗系统进行研究和治疗的成本也给尽可能实现更高的精确度带来了很大的压力。对于任何在卫生行业工作的人来说,实现“完美”模型的高压也意味着越来越多的内部和外部需求,以了解为什么机器学习模型会提出这样或那样的建议。在外部,这意味着越来越多的利益相关者要求解释,而在内部,对模型更好的理解通常会导致更好的建模本身。
事实上,在过去几年中,关于机器学习中可解释性主题的论文数量一直在稳步增长:
Source: http://people.csail.mit.edu/beenkim/papers/BeenK_FinaleDV_ICML2017_tutorial.pdf
现在,最大的问题是,今天机器学习世界中一些最准确的模型是我们所说的“黑盒”模型。这些模型缺乏可解释性和可解释性,因为它们通常的工作方式意味着除了一组规则或参数集之外,机器的一个或几个层在没有人类监督的情况下做出决策。并且通常,甚至该领域中最专业的专家也不能理解例如通过训练神经网络实际产生的功能。从这个意义上说,一些最经典的机器学习模型更好。
例如,线性/逻辑回归为我们提供了一个非常清晰的数学方程,当试图最小化损失函数时,每个特征对我们的预测有多大影响。决策树有一个非常清晰的方法来选择特征,根据它们在不同阈值下区分数据成员的有用程度。然而,考虑到 ML 材料的可解释性和可解释性通常与通过查看特征重要性和相关性来分析模型特征相关联,我们如何用简单的英语解释当使用这些复杂的模型之一,甚至是集成工具如 Bagging 或 Boosting 时,哪些特征在驱动我们的预测?
事实上,对于 2018 年 Kaggle DS 和 ML 调查,数千名数据行业的专业人士表达了他们对在什么情况下探索模型洞察力和解释模型预测的看法,尽管原因可能不同,但他们都至少提到了一个对他们的业务很重要的场合:
Source: 2018 Kaggle DS and ML Survey
考虑到分析特征重要性的日益增长和共享的重要性,在这篇文章的剩余部分,我们将看到一个叫做“排列重要性”的工具。
置换重要性为我们提供了一种方法,通过测量当一个特性不可用时得分如何降低来计算任何黑盒估计器的特性重要性。这个想法是这样的:当一个特性不可用时,特性的重要性可以通过查看分数降低多少来衡量。为此,可以从数据集中移除一个特征,重新训练估计器并检查分数。但是这样做的计算量很大。相反,我们可以用随机噪声替换每个特征,并在每个特征的每次迭代中再次评分。这就是为什么这种了解特征重要性的方法也被称为“平均降低准确度(MDA)”。
正如你所想象的,从头开始这样做是完全可能的,但幸运的是,我们在你的机器学习项目中实现了排列重要性,你可以只导入下面的库:
from eli5.sklearn import PermutationImportance
使用它非常简单,一旦你训练了你的模型,你唯一要做的就是再次拟合你的数据,调用你的模型,如下所示:
permutation_importance = PermutationImportance(your_model, random_state=1).fit(X_train_data, y_train_data)
考虑到您将对数据集的多个版本进行重新评分,因此该算法将需要一段时间来运行。
一旦 PermutationImportance 完成了它的工作,您可以获得两个有趣的东西:
- 当然,您可以通过调用以下命令来获得特性的重要性:
permutation_importance.feature_importances_
- 您还可以通过调用以下命令来获取要素重要性的标准差:
permutation_importance.feature_importances_std_
正如你所看到的,这是一个简单而强大的工具。的确,在现实中,当使用高度复杂的模型时,它并没有解决与模型可解释性和可解释性相关的背景问题。然而,它让我们更接近理解我们的数据,以及我们的每个特征对我们的模型有什么贡献。这已经是一个开始了!
最后,别忘了看看我最近的一些文章,比如提高你绘图技能的 10 个技巧、我在使用火车测试分割或5 分钟内抓取网页时犯的 6 个业余错误。在我的中等档案中可以找到所有这些以及更多信息。另外,如果你想直接在你的邮箱里收到我的最新文章,只需 订阅我的简讯 😃
也可以通过…取得联系
- 领英:https://www.linkedin.com/in/gferreirovolpi/
- GitHub:https://github.com/gonzaferreiro(那里有我所有的代码)
下一篇文章再见!
神经网络的不确定性估计——贝叶斯近似下的丢失
本文的主题是,你可以利用辍学来建立预测信心。
这篇文章主要讲的是我如何从优步的论文*开始对优步的时间序列进行深刻而自信的预测。*使用神经网络解释模型并不是一件容易的事情,了解神经网络的可信度对企业来说非常重要。尽管这一系列论文中有许多复杂的证明,但它们都试图回答一个简单的问题
我的模型对某个特定的预测有多大把握?
目录
背景
我们正在处理一些商业预测问题,因此我们正在研究预测的新方法,特别是神经网络的新方法。(我知道 LSTM/编码器-解码器/seq2seq,但我没有听到它的很多令人兴奋的性能)。我能找到的大公司关于时间序列的公开讨论不多**,**我能找到最接近的是脸书的 预言家 ,这是一种纯粹的统计基数预测方法。
优步在优步 有一篇论文 对时间序列进行了深刻而自信的预测,这篇论文引起了我们的注意,因为他们是在概率编程上投入大量资源的行业参与者之一。经过一番研究,我发现优步还赢得了M4 竞赛(一个著名的时间序列竞赛)M4 竞赛不仅需要准确的预测,还需要预测的置信区间。他们也开放了源代码 Pyro ,这是一个概率编程库,所以结合这些事实,我有理由相信他们正在做一些有趣的(实际上有用的)工作。
我没有很深的统计学背景,“贝叶斯”这个词对我来说几乎毫无意义,我只知道它与条件概率有关,仅此而已。我非常努力地回忆我关于贝叶斯和频率主义者的统计,这个奇妙的线索很好地解释了这一点。
优步时间序列的深度自信预测
优步已经写了一篇关于这项工作的博文,我从第一篇论文开始,但最后又读了几篇论文(一些是早期的基础工作,一些是后续工作)。我不会花太多的话来解释这些文件,因为我不能理解每一个步骤。相反,我将只强调我的研究旅程中的重要部分,并鼓励你们通读这篇论文。
我们表明,在神经网络中使用脱落(及其变体)可以被解释为一个众所周知的概率模型的贝叶斯近似:高斯过程(GP)
我个人并不是 100%相信这项工作,但他们已经显示出巨大的实际效果,这是最重要的部分。(像 BatchNorm 一样,人们长期以来一直在思考为什么它会以错误的理由工作,但这并不能阻止任何人使用它,因为它的确提高了模型的收敛性)
研究过的论文:
- 优步时间序列深度自信预测
- 优步时间序列极端事件神经网络预测
- 作为贝叶斯近似的漏失:表示深度学习中的模型不确定性
- 变分贝叶斯辍学:陷阱与修正
- 变分高斯漏失不是贝叶斯
- 深度学习中的风险与不确定性:贝叶斯、自助和辍学的危险
其他资源:
- M4 竞赛:结果、发现、结论和前进方向
- 深度学习中的不确定性 (亚林·加尔的论文)
在阅读一系列材料时,有一个时间线是很有用的。
Timeline
不确定性估计
贝叶斯的一个关键区别是参数是分布而不是固定的权重。
误差=模型不确定性+模型错误设定+固有噪声
贝叶斯神经网络将不确定性分解为模型不确定性、模型误设定和固有噪声。
MCDropout
MCDropout
贝叶斯的一个关键是一切都是概率分布,而不是点估计。这意味着你的体重也有不确定性。
他们使用 MCDropout 来处理模型不确定性和错误设定。基本上,他们已经声称在推断时间使用 Dropout 相当于做贝叶斯近似。这里的关键思想是让辍学者在**培训和测试时间做同样的事情。**在测试的时候,你会重复 B 次(如论文所说的几百次),也就是把相同的输入以随机的丢包传递给网络。然后,利用您的预测,您可以使用这些# of B 预测生成一个预测间隔。MC 指的是蒙特卡罗,因为退出过程类似于对神经元进行采样。
固有噪音
Inherent Noise
他们还引入了术语固有噪声,指的是不可减少的噪声。简而言之,他们使用一种非常常见的技术来模拟这种错误——拒绝验证。他们称之为自适应方法,谈论平滑和先验,但是我看不出与 ML 社区熟悉的标准训练/验证实践有任何区别。最后,你会把两个误差项合并,得到最终的不确定项。
讨论
你可以在 Reddit 上找到一个有趣的讨论,它从理论的角度提供了一些反驳。事实上,我并不完全相信优步的论文。然而,他们在国内的和 M4 的比赛中都取得了不错的成绩。像深度学习中许多进步一样,理论晚于实际结果。如果您感兴趣,请随意尝试,实现应该相对容易,因为您只需要在推理时保持 dropout。
结论
要点是,不确定性不仅存在于你的模型中,也存在于你的体重中。贝叶斯神经网络试图将权重建模为分布。
MCDropout 提供了一种新的简便的方法来估计不确定性,在大多数现有的网络变化最小。在最简单的情况下,您只需要在测试时保持 dropout on,然后多次传递数据并存储所有预测。不利的一面是,这可能计算量很大,尽管优步声称这增加了不到 10 毫秒。他们没有讨论他们如何实现这一点,但我猜测他们会进行大量的并行计算,因为你可以想象数据的多次传递不会按顺序进行,所以这个过程很容易并行。
我非常渴望听到更多关于最新的时间序列预测和用神经网络估计不确定性的方法的讨论,如果你知道一些更好的方法,请告诉我!
附录
从哪里开始?google 的关键字名称:
- Yarin Gal(他在论文中提出使用脱落进行贝叶斯近似)
- slawek Smyl(M4 竞赛获奖者)
如果你只想了解申请。快速浏览一下[2]然后[1],由于[1]是为[1]做铺垫,有些背景是重复的。
[4]很好地概述了使用辍学的一些陷阱
- 优步时间序列深度自信预测
- 优步时间序列极端事件神经网络预测
- 作为贝叶斯近似的漏失:表示深度学习中的模型不确定性
- 变分贝叶斯辍学:陷阱与修正
- 变分高斯漏失不是贝叶斯
- 深度学习中的风险与不确定性:贝叶斯、自助和辍学的危险
https://tensor chiefs . github . io/BBS/files/dropouts-brown bag . pdf(亚林加尔)
不确定性采样备忘单
当有监督的机器学习模型做出预测时,它通常会给出该预测的置信度。如果模型是不确定的(低置信度),那么人类的反馈可以有所帮助。当一个模型不确定时,获得人类的反馈是一种被称为不确定性采样的主动学习。
备忘单中涵盖的四种不确定性采样类型是:
- **最不自信:**最自信预测和 100%自信之间的差异
- **置信区间:**两个最有把握的预测之间的差异
- **置信度:**最有把握的两个预测之间的比率
- **熵:**所有预测之间的差异,由信息论定义
本文分享了这四种计算不确定性的常用方法的备忘单,包括示例、等式和 python 代码。下次你需要决定如何计算你的模型的置信度时,把它作为一个参考!
数据科学家通常使用不确定性采样来对项目进行采样,以便进行人工审查。例如,想象一下,你负责一个机器学习模型来帮助自动驾驶汽车理解交通。你可能有数百万张从汽车前部摄像头拍摄的未标记图像,但你只有时间或预算来标记 1000 张。如果你随机采样,你可能会得到大部分来自高速公路驾驶的图像,自动驾驶汽车已经很自信,不需要额外的训练。因此,您将使用不确定性采样来查找 1,000 个最“不确定”的图像,其中您的模型最混乱。
Confusing traffic lights
当您使用新标记的示例更新您的模型时,它应该会变得更智能、更快。
An uncertain robot
这篇备忘单摘自我的书《人在回路中的机器学习:https://www . manning . com/books/人在回路中的机器学习
有关每种方法的更多细节和比标记更复杂的问题,如预测文本序列和图像的语义分割,请参见这本书。不确定度的原理是一样的,但是不确定度的计算会不一样。
这本书还涵盖了其他主动学习策略,如多样性抽样,以及解释你的模型概率分布的最佳方式(*提示:*你可能无法相信你的模型的可信度)。
下载代码和备忘单:
您可以从这里下载代码:
针对不确定性的常见主动学习策略的 NumPy 实现对四种不确定性进行采样…
github.com](https://github.com/rmunro/uncertainty_sampling_numpy)
您可以在此下载 PDF 版本的备忘单:
我还将在以后发布 PyTorch 中的代码,以及更多种类的算法。
编辑:PyTorch 版本的备忘单现已发布:http://robertmunro . com/Uncertainty _ Sampling _ cheat sheet _ py torch . pdf
进一步阅读
不确定性抽样已经存在很长时间了,有很多好的文献。一篇关于最不自信的优秀早期论文是:
阿伦·库洛塔和安德鲁·麦卡勒姆。2005.减少结构化预测任务的标记工作。 AAAI 。https://people . cs . umass . edu/~ McCallum/papers/multi choice-aaai 05 . pdf
一篇关于置信区间的优秀早期论文是:
托拜厄斯·谢弗,克里斯蒂安·德科曼和斯特凡·弗罗贝尔。2001.用于信息抽取的主动隐马尔可夫模型。伊达。https://link . springer . com/content/pdf/10.1007/3-540-44816-0 _ 31 . pdf
将信息论用于基于熵的采样的一篇好的早期论文是:
伊多·达甘和肖恩·p·恩格尔森。1995.用于训练概率分类器的基于委员会的采样。95 年的 ICML。http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.30.6148
更一般地说,不确定性采样的基础文件是:
戴维·刘易斯和威廉·盖尔。1994.一种训练文本分类器的顺序算法。94 年的 SIGIR。https://arxiv.org/pdf/cmp-lg/9407020.pdf
要获得更多关于不确定性抽样的学术论文,请查找引用上述论文的被广泛引用的近期工作。
这些例子在我自己的文章中也有涉及:
罗伯特·芒罗。2020 年(预计)。人在回路中的机器学习。曼宁出版公司。https://www . manning . com/books/human-in-the-loop-machine-learning
我文本中的章节是按照他们所写的内容出版的——不确定性抽样章节现在已经出版,多样性抽样章节将是下一个。我会边走边分享摘录,就像我最近在机器学习知识象限中做的那样:
迁移学习、不确定性采样和多样性采样来改进您的机器学习模型。
towardsdatascience.com](/knowledge-quadrant-for-machine-learning-5f82ff979890)
实施不确定性采样
备忘单中的所有方程返回[0,1]范围内的不确定性分数,其中 1 是最不确定的。许多学术论文没有对分数进行标准化,所以你可能会在上面的论文中看到不同的方程。但是,我建议您为任何用于非研究目的的代码实现规范化的[0–1]等式:[ 0–1]范围使下游处理、单元测试和抽查结果更容易。
本文和 GitHub 库中共享的代码都是开源的,所以请使用它来入门!
罗伯特·芒罗
2019 年 7 月
用于真实世界机器或深度学习项目的不寻常的数据清理器
Cleaning Tools
介绍
数据清理是您的实体课程或在线课程中简要涉及的一个主题。然而,在您作为数据工程师或数据科学家的工作中,您将花费大量时间准备(预处理)数据,以便可以将数据输入到您的模型中。
在大学工程课程中,我的头反复撞在 2 米长的金属杆上,从中吸取了教训
towardsdatascience.com](/what-70-of-data-science-learners-do-wrong-ac35326219e4)
企业数据科学仍然是一个新领域。许多学者还没有为真正的企业解决真正的问题。因此,他们以一种脱离数据和商业背景的方式教授教科书算法。这可能是智力上的乐趣。但是,如果学生认为这些课程为他们成为数据科学家做好了准备,那他们就错了。
Paso 将提供你清理数据所需的许多工具,但不是全部。
仅仅因为帕索提供了一个工具并不意味着你应该在你的数据集上使用它。例如,删除具有高密度 nan 的行将导致更差的损失度量或不希望的偏差,但并非总是如此。
不同清洗策略(管道)的迭代是 Paso 的基本目标。讨论分为以下几个主要部分:
- 首先,我们用一个 Paso 输入器加载
boston
数据集。它具有相对少的行数,同时具有少于十个特征,以产生快速清洁。 - 接下来,我通过管理相对干净的
boston
数据集来演示每一个清理器。 - 最后,我们总结一下 Paso’’ 数据清理器以及我们对未来文章和 Paso 版本的计划。
[## paso 为您的 Python 项目提供日志记录和参数服务
paso 为您的 Python 项目提供日志记录和参数服务
paso 为您的 Python Projectmedium.com 提供日志记录和参数服务](https://medium.com/@dr.bruce.cottman/pasos-offering-of-logging-and-parameter-services-for-your-python-project-c3ae2fd6869a)
正如我们在上面标题为 的文章中看到的,paso 为您的 Python 项目提供日志记录和参数服务,我们应该启动 paso 服务。
*import pandas as pd
from paso.base import Paso,Log,PasoError
from loguru import logger
session = Paso(parameters_filepath='../parameters/default-lesson.2.yaml').startup()*
我们将使用Inputer,
,只是说明它是一个通用类,用于将数据输入到 pandas dataframe 中。描述文件描述的数据集:city.yaml
。在下面的媒体文章中会更详细地讨论Inputer
和描述文件:
数据扩充很重要,因为它从我们当前现有的数据集生成(准确地)人工数据。的…
medium.com](https://medium.com/@dr.bruce.cottman/part-1-balancing-and-augmenting-structured-data-4ade0df38662)
from paso.pre.inputers import Inputers
dataset_name = 'boston'
inputer = Inputers(description_filepath='../descriptions/pre/inputers/'+dataset_name+'.yaml')
dataset = inputer.transform()
inputer.target'MEDV'
管理数据集
通常情况下,我们获取数据并必须清理它。这样的数据集是专有的。毕竟,没有人愿意向公众展示他们的肮脏数据(呻吟)。
为了展示这些数据清理器是如何工作的,我们可以找点乐子,整理一个干净的数据集。
清除程序:缺少值
检测和纠正缺失值和异常值(好的或坏的)是一个不断发展的研究领域。我们将在关于Pasoscaler 的文章中讨论异常值。对于本文,我们将只关注丢失的值。
不同的值可以表示缺少一个值。举个例子,
999
在某些功能中可能表示“未回答”。NA
可能表示不适用于此功能/记录。-1
可能意味着缺少此功能/记录。- 诸如此类。
在这里你可以找到更多关于缺失数据的熊猫指南的细节。
对于第一个显示的 cleaner,我们添加了特性asv
,它具有所有相同的值999
。
from paso.pre.cleaners import Cleaners
c = Cleaners()
dataset['asv'] = 999.0
c.values_to_nan(dataset,values=[999.,11999.],inplace=True)
dataset.head()
c.values_to_nan on dataset
该清洁剂,c.values_to_nan
将所有999
值更改为NaN
。还要注意的是,作为inplace=True
,数据集是自己改变的,通过避免复制dataset
来节省内存。
清洁器:计算比率
缺失值(观察值)比率较大的行在统计上不相关。同样,您可能希望估算缺失值,即将缺失值更改为其他值。
每行缺失值的数量是信息,这本身表明它应该是该数据集的一个新特性。
使用此Cleaner
,不删除带有NaN
的行,而是为每一行计算 number _ of _ nulls/total _ row _ count,并将一个新特征NaN_ratio
添加到返回的 pandas 数据帧中。
我们将再次使用同一个Cleaner
实例c
。同样,让我们通过将第一行的第一个和第二个特性设置为NaN
来对dataset
进行更多的修改。
Cleaner calculate_NaN_ratio transforming dataset
注意这里有一个新的特性,NaN_ratio
。正如我们所料,第一行的NaN/total_row_count
比率不同于第二行和后面的行。
Cleaner
属性column_missing_value_ratio
包含每个特征的缺失值比率。提示:您可以在堆叠合奏中使用这些。我们将在另一篇文章中讨论这个问题。
估算:将 NaN 更改为值
将NaN
设置为最佳近似值是您数据清理工作的关键,并进一步降低您的预测准确性和能力。关于这个主题的一篇流行文章:
统计估算数据集中缺失值的常用策略。
towardsdatascience.com](/6-different-ways-to-compensate-for-missing-values-data-imputation-with-examples-6022d9ca0779)
由于各种原因,许多现实世界的数据集可能包含缺失值。它们通常被编码为名词、空格或任何其他占位符。使用具有大量缺失值的数据集来训练模型会极大地影响机器学习模型的质量。一些算法,如 scikit-learn 估计器,假设所有的值都是数字的,并且拥有有意义的值。
处理这个问题的一个方法是去掉有缺失数据的观测值。但是,您可能会丢失包含有价值信息的数据点。更好的策略是估算缺失值。换句话说,我们需要从数据的现有部分推断出那些缺失的值
另一篇关于归因的文章:
为什么缺少数据
medium.com](https://medium.com/ibm-data-science-experience/missing-data-conundrum-exploration-and-imputation-techniques-9f40abe0fd87)
各国:
为了让我们充分理解缺失数据的重要性,我们需要全面地确定缺失数据发生的原因。第一步是了解你的数据,更重要的是了解数据收集过程。这可以导致减少数据收集错误的可能性。缺失数据的性质或机制可以分为三大类。
1)完全随机缺失(MCAR)
2)随机缺失(MAR)
3)非随机缺失(MNAR
我们提供了估算策略的大杂烩,如Imputers().imputers()
所示。我建议您阅读这些和其他关于输入缺失值的文章,这样您就可以最好地使用这些工具。
我们决定在给定的特性列表上进行转换,因为估算策略会随着特性子集的变化而变化。
注意,极端梯度推进(xgboost
)将根据所用的训练损失函数,自动学习缺失数据的最佳(不能证明是最佳,但实际上良好 足够)插补值。
作者在其名称中使用了eXtreme
,主要是因为这种能力。它是一个工作非常好的黑匣子,你可以通过研究源代码来打开它。
我建议你先试试xgboost
,然后用这里显示的估算和其他数据清理器来提高你的预测。
这里,我将使用一个简单的most_frequent
策略,因为它处理分类和连续特征类型。
imputer_file = “../descriptions/pre/cleaners/most_frequent_impute.yaml”
imp = Imputers(description_filepath = imputer_file)
imp.transform(dataset)
first 4 rows of dataset after imputation. Notice, fist row of CRIM and ZN havechanged from NAN
删除 _ 重复 _ 要素
在机器学习竞赛中,你很少会看到两个或更多具有相同值的特征。然而,您几乎总是会在拥有大型和/或多个数据库和/或 ot 数据仓库和/或数据湖的企业中看到它。
随着企业数据库或数据湖的老化,不同的人添加不同的数据源,重复的特性是相当标准的。
如果一个要素与另一个要素具有相同的索引值,则应删除其中一个要素。重复特征是多余的,并且没有预测能力。
Cleaner delete_Duplicate_Features
将多余的特征减少为一个独特的特征。
注意,任何NaNs
在被传递给这个方法之前都会被从数据集中删除,根据定义,Python 中的NaN
不等于另一个NaN
。早先,我们遇到了可以删除、替换或Impute
NaN
值的数据清理器。
我们将创建特征CRIM1
和CRIM2
,它们的值与CRIM
相同。
dataset['CRIM1'] = dataset['CRIM12'] = dataset['CRIM']
dataset.head(n=2)
Added CRIM1 and CRIM2 features
c.delete_Duplicate_Features(dataset, inplace=True)
dataset.head(n=2)
Deleted CRIM1 and CRIM2 features
不出所料,delete_Duplicate_Features
删除了功能CRIM1
和CRIM2.
删除具有单一唯一值的要素
将常数存储在数据中是常见的做法。常数显示为具有唯一值的特征/列。
NaN
为空值,因此不是常量或值。
该方法查找所有只有一个唯一值的特征。值之间的变化为零。所有这些特征都从数据帧中删除,因为它们没有预测能力。
在这里,我将一个常量放入数据集中,并用delete_Features_with_Single_Unique_Value.
删除它
delete_Features_with_Single_Unique_Value
删除具有所有唯一值的要素
当一个要素的每个值都不相同时,它在回归任务中只具有预测值,并且这些值必须是浮点型或整数型。
商品的 SKU、id 或名称是字符串或对象类型,没有预测能力,只会拖学习者的后腿。应该从数据集中移除这些要素。
在这个例子中,我将索引变成一个 ID,这样我就可以删除它。
delete_Features_with_All_Unique_Values
特征 _ 统计
Cleaner.feature_Statistics
将计算每个特征的一组预定统计数据,并返回一个数据帧。
这组统计数据如下所示:
Cleaner.feature_Statistics
这种方法是一种诊断工具(concat = False
),用于确定标准偏差或任何其他统计数据是否太小,从而没有显著的预测能力。
它还可以添加到数据集(concat=True
),其中统计信息部分描述了行值的分布。特征必须是数字(整数或浮点数)。
您可能希望也可能不希望目标成为分布的一部分。由于测试没有目标,该目标不应该是训练数据集中分布的一部分,因为您正在将目标泄露到训练数据集中。
您可能希望移除目标要素,然后将其放回数据集中。
使用Cleaner.column_stats
您可以获得每个特性的统计数据。如果您想与其他学员进行叠加(合奏),可以稍后使用此功能。现在不要担心组装;我们将在后面的文章中讨论这一点。
Cleaner.column_stats
注意:在传递给这个方法之前,任何NaNs
都应该从数据集中删除,根据定义,Python 中的NaN
不等于另一个NaN
。
注意:我们已经介绍了可以删除、替换或Impute
NaN
值的数据清理器。
布尔型到整数型
学习者,除了树,还有其他函数,需要将True/False
或value_1/value_0
的布尔值(特性将只有 2 个值)转换成整数1/0
才能正常工作…
类实例方法boolean_to_integer
转换所有布尔特征。因为它不影响非布尔特征,所以它可以在任何数据集上运行。
boolean_to_integer
特征 _ 特征 _ 相关性
通过使用seaboard.pairplot(dataset).
在数据集中绘制成对关系,可以直观地看到线性和/或非线性行为。您也可以使用dataset.profiling_report
来提供关于数据集的更多信息,这是开始 EDA 的好方法。
seaboard.pairplot(dataset)
我们可以用feature_Feature_Correlation
来计算一个数据集的关联矩阵,关联矩阵是与所有其他特征相关的所有特征。根据计算,相关性是线性相关性,并不量化任何两个特征之间的非线性行为。
两个特征之间的相关性越高,相关系数越接近绝对值 1.0(开区间-1.0,1.0)。特征本身的值为 1.0,因为它与自身相关。如果它有负值,那么它是反相关的。反相关特征对意味着如果一个特征的值增加,那么另一个特征的值将减少
特征的线性预测强度是它与目标特征的相关程度。然而,特征对(非目标)的相关性越高,特征之一的预测值将降低。
通常,使用皮尔逊相关系数,其仅对两个特征之间的线性关系(或一阶)敏感。
皮尔逊相关系数-0.85 是强负相关,而相关系数 0.15 是弱正相关。此外,如果某个特征与目标的相关系数为|0.99|,那么它的预测值非常高,甚至可能太高。应检查该数据集,尤其是该特征是否有错误。
Spearman 的等级相关系数是衡量两个变量之间的关系能够被单调函数描述的程度。
肯德尔等级相关系数是用于测量两个测量特征之间的顺序关联的统计量。
Spearman 的等级相关系数是对单调函数如何描述两个变量之间关系的度量。
在大多数情况下,对 Kendall 和 Spearman 等级相关系数的解释与 Pearson 相关系数非常相似,因此通常会导致相同的诊断。feature_Feature_Correlation 类计算数据集所有要素对的皮尔逊、斯皮尔曼或肯德尔相关系数。
同样,这个类实例方法是一个诊断工具,它指示一个特征是具有低预测能力还是与另一个特征具有高冗余。
在移除任何特征之前,查看 SHAP 值、相对方差和相关系数,以决定移除特征。
阅读这篇文章可以很好地了解相关性:
探索数据科学的核心。理解计算相关性的重要性至关重要
medium.com](https://medium.com/fintechexplained/did-you-know-the-importance-of-finding-correlations-in-data-science-1fa3943debc2)
您可以使用feature_Feature_Correlation.
计算数据集的特征-特征相关矩阵
feature_Feature_Correlation
您可以使用 plot_corr .
绘制数据集的要素-要素相关性矩阵
删除 _ 功能
我应该在这里提一下, sklearn 有一些不同的算法用于特征选择。在移除任何功能之前,您可能需要查看这些内容。
然而,我发现 paso 中给出的特征诊断工具可以处理非线性数据。 SHAP 在确定 2018 财年车型中某个特征的重要性方面是最先进的,而且据我所知仍然是最先进的
如果你有更好的了解,请告诉我们,我们可以添加到帕索。这个领域正在迅速发展。
根据您的分析,您现在可以从 pandas 数据框架中移除要素了。
我将创建一个特征asv
,然后用delete_features.
移除它
delete_Features
移除训练和测试中不常见的功能
如果训练或测试数据集具有特征,而另一个没有,则这些特征将没有预测能力,并从两个数据集中移除。例外情况是目标特征存在于训练数据集中,但不在监督问题的测试中。
一个数据集中的特征(训练或测试)而不是另一个数据集中的特征(训练或测试)可能指出这些数据集中的其他问题。您应该检查数据加载的步骤。
我最常看到的是来自上游服务(Kafka、Google PubSub、Amazon Kinesis Stream、PySpark 和 RabbitMQ 等)的测试数据集。测试数据集的特征被改变,而预训练模型(以及训练集)不具有这些新特征。根据您的错误处理,通常会发生无法预测的情况。
使用:
- 移除了训练和测试数据集的特征差异。
- 删除的特征将被记录下来,以便以后进行协调。
- 预训练模型成功处理了来自输入测试数据集的预测。数据流的一个很好的概述在:
数据已经不仅仅是一组二进制数字,而是每个人日常决策的必要组成部分…
medium.com](https://medium.com/analytics-vidhya/data-streams-and-online-machine-learning-in-python-a382e9e8d06a)
为了创建测试和训练数据集,我们可以使用 30%的City
作为测试,剩下 70%的City
作为训练。
Clean extra feature in test
摘要
从 Python 3.6 ( PEP 484 )开始,引入了类型提示。类型提示(注意:不是强类型检查)使得对 Python 代码进行静态类型检查成为可能。
Python 语言解释器使用 而不是 类型提示,除了检查正确的语法。类型提示更多地被下游工具使用,比如PyCharm
和Mypy.
更好的文档和在运行时发生类型错误之前将其捕获是您将从第一波工具中看到的一些好处。
你可以打赌,有人正在为 Python 开发编译器,以使它在运行时更快。接下来,您可以想象用类型化符号转换动态类型化 Python 的工具。
你可以打赌,有人正在为 Python 开发编译器,以使它在运行时更快。接下来,您可以想象用类型化符号转换动态类型化 Python 的工具。
真正美妙的是一种语言,它将输入放到下游工具中,使软件工程师能够专注于为什么而将很大一部分如何留给工具。
使用类型提示,Cleaners
和Imputers
类方法调用签名被总结如下:
from paso.pre.cleaners import Cleaners
c = Cleaners()# 1
c.values_to_nan(self, X: pd.DataFrame, values: List[str]=[], inplace:bool=True, verbose:bool=True) -> pd.DataFrame:#2
c.delete_NA_Features(self, X: pd.DataFrame, threshold:float =1.0, inplace:bool=True, verbose:bool=True) -> pd.DataFrame:#3
c.calculate_NaN_ratio(self, X:pd.DataFrame, inplace:bool=True, verbose:bool=True) -> pd.DataFrame:#4
c.delete_Duplicate_Features(self, X:pd.DataFrame, ignore:List[str], inplace:bool=True, verbose:bool=True) -> pd.DataFrame:#5
c.delete_Features_with_Single_Unique_Value(self, X:pd.DataFrame, ignore:List[str], inplace:bool=True, verbose:bool=True) -> pd.DataFrame:#6
c.delete_Features_with_All_Unique_Values(self, X:pd.DataFrame, ignore:List[str], inplace:bool=True, verbose:bool=True) -> pd.DataFrame:#7
c.statistics() -> List[str]#8
c.feature_Statistics(self, X:pd.DataFrame, statistics:str="all", concat:bool=True, inplace:bool=True, verbose:bool=True
) -> pd.DataFrame:#9
c.boolean_to_integer(self, X:pd.DataFrame, inplace:bool=True, verbose:bool=True) -> pd.DataFrame:#10
c.feature_Feature_Correlation(self, X:pd.DataFrame, method:str="pearson", verbose:bool=True) -> pd.DataFrame#11
c.plot_corr(self, X: pd.DataFrame, kind:str="numeric", mirror:bool=False, xsize:float=10, ysize:float=10)-> None:#12
c.delete_Features(self, X:pd.DataFrame, features:List[str]=[], verbose:bool=True, inplace:bool=True) -> pd.DataFrame:#13
c.delete_Features_not_in_train_or_test(self):self, train:pd.DataFrame, test:pd.DataFrame, ignore:List[str]=[], verbose:bool=True, inplace:bool=True) -> pd.DataFrame:#14
imputer_file = "../descriptions/pre/cleaners/most_frequent_impute.yaml
**imp** = **Imputers**(description_filepath: str = imputer_file)**imp.imputers**() -> List[str]:#15 **imp.transform**(self, X: pd.DataFrame, verbose: bool = True, inplace: bool = True, features: List[str] = None, **kwargs) -> pd.DataFrame
本文的代码在[.ipynb](https://github.com/bcottman/paso/blob/master/lessons/lesson-2.ipynb)
和.[p](https://github.com/bcottman/paso/blob/master/paso/pre/cleaners.py)y
文件中给出。
您已经看到 paso 为生产数据工程师和研究数据科学家提供了数据清理方法。 paso 支持流数据以及批量提取数据清理。你可以期待 paso 继续为数据清理提供最先进的工具。
关于帕索的其他文章有:
[## paso 为您的 Python 项目提供日志记录和参数服务
paso 为您的 Python 项目提供日志记录和参数服务
paso 为您的 Python Projectmedium.com 提供日志记录和参数服务](https://medium.com/@dr.bruce.cottman/pasos-offering-of-logging-and-parameter-services-for-your-python-project-c3ae2fd6869a) [## 第 1 部分:平衡和扩充结构化数据
数据扩充很重要,因为它从我们当前现有的数据集生成(准确地)人工数据。的…
medium.com](https://medium.com/@dr.bruce.cottman/part-1-balancing-and-augmenting-structured-data-4ade0df38662)
将来,我们将会发表更多关于 paso 功能的文章。
- 第 2 部分:结构化数据的高级扩充。
- 第二部分:深度学习输入。
- 还有更多…
如果你有一个服务或功能或看到一个错误,然后离开帕索项目一个注意。*
通过探索性数据分析发现隐藏的宝石
用熊猫、海鸟和树叶进行基本侦察
Photo by Ilze Lucero on Unsplash
数据科学家的关键特质之一是好奇。在本文中,我们将使用一些流行的 Python 工具探索一个有趣的数据集,但也会尝试用非常规的术语来思考数据。对于欺诈检测等领域,以意想不到的方式连接数据可以梳理出模式,即使数据可能看起来不完整。理想情况下,你会提出一些能打开新商机的见解。
在 Kaggle 寻找供应链数据集时,我发现了一个名为供应链数据,副标题为进口和装运数据。向下扫描页面,我看到数据源名为 walmart-import-data.csv 。嗯,可能会很有趣。啊哦,“关于这个文件”说“还没有描述”。这就是调查开始的地方——我们甚至没有数据字典。
通常当你在做探索性的数据分析时,这是因为你有一个特定的问题,你正试图使用数据来回答,例如上个月有多少箱菠萝从巴哈马群岛运出,但在这里我们将让我们的想象力天马行空,看看数据可能会揭示什么秘密。
为了保持这篇文章的可读性,下面只显示了一些关键的代码片段。Python Jupyter 笔记本在 GitHub 这里,Kaggle 内核在这里。为了清楚起见,我还将大量使用后见之明来简化我通过反复试验发现的一些事情,例如,我如何知道原始数据文件中大约 9%的行都是 NA。我最初发现某些列有很多 NaN 值,但是进一步检查后发现整行都是 NaN。
预赛
为了能够跟随 Jupyter 笔记本,您将需要从 GitHub 这里克隆或下载资源库。或者,您可以为本文运行 Kaggle 内核。
如果您走第一条路,在您克隆了存储库之后,您需要从这里的 Kaggle 下载数据文件,并将文件Walmart-import-data-full . CSV移动到存储库中的 data/raw 子目录。
第一步
目前还不清楚为什么会发布这个数据集,而且它也不是最近才发布的(最近一次发布是在 2013 年 9 月 9 日)。对于我们的目的来说,这很好,如果出现了更新的数据集,这些技术将适用。我们能得到什么样的见解?让我们从加载数据开始。
xdata = pd.read_csv(raw_data_path / 'walmart-import-data-full.csv', low_memory=False)
# About 9% of the rows are all NA; drop them
xdata.dropna(axis=0, how='all', inplace=True)
我们指定 low_memory=False 来避免关于包含混合类型数据的某些列的警告。如果我们超越探索性数据分析(EDA)阶段,我们可以花一些时间均匀化这些列,并为 read_csv 创建一个定制的 dtypes 参数。像往常一样,我们先看一下前几行,以便对数据集有一个大致的了解:
xdata.head(3)
The first few rows and 13/34 columns of the data
查看 xdata.shape 可以看到,数据集中有 175713 行和 34 列,其中 NA 行已被删除。从 xdata.columns 中,我们可以大致了解列中的内容,这些列的名称相当有意义。看看‘原产国’怎么样?看看 2013 年沃尔玛的商品来自哪里可能会很有趣。描述功能对 EDA 非常有用:
xdata['COUNTRY OF ORIGIN'].describe().to_dict(){'count': 174093, 'unique': 71, 'top': 'China', 'freq': 125366}
我们看到,最大的原产国是中国,占出货量的 72%(按数量计算)。然而,有 71 个独特的国家,那么还有谁在向沃尔玛销售呢?
沃尔玛全球供应商的可视化
我们可以看直方图,但在地图上看会更有视觉冲击力。
为了做到这一点,我们可以制作一个 choropleth 地图,用不同的颜色显示每个国家的发货百分比。我们将使用leavy,它使用 Python 和 Leaflet.js 库来创建用于数据可视化的交互式地图。
一个 follow Choropleth 地图需要一个数据框和两列:一列用于索引 JSON 映射数据,另一列包含一个值,该值用于选择地图上的阴影颜色。
虽然我确信有许多更有效的方法可以做到这一点,但由于这是一个探索性的数据分析,而且数据集并不是很大,我们可以使用 groupby、describe 和 xs 来快速制作一个数据框架,其中包含制作一个叶子地图所需的列。如果你很难理解我是如何得出下面这个表达式的,把它分成几个部分,然后显示每个部分。我现在并不真正关心“重量(KG)”列,只是我们可以使用它的“计数”字段。
countries_of_origin = xdata.groupby('COUNTRY OF ORIGIN').describe().xs('WEIGHT (KG)', axis=1).copy()
countries_of_origin.reset_index(level=0, inplace=True)coo_record_count = sum(countries_of_origin['count'])
countries_of_origin['pct'] = countries_of_origin['count'].apply(lambda cnt: 100*cnt/coo_record_count)
countries_of_origin['logpct'] = countries_of_origin['count'].apply(lambda cnt: np.log(100*cnt/coo_record_count))
# We will use the sorting later
countries_of_origin.sort_values(by==['count'])
The first three entries in countries_of_origin, by count
现在我们有了有用格式的数据,让我们用 let 制作一个地图:
# Initialize the map:
m = folium.Map(location=[30, 0], zoom_start=2, no_wrap=True)# geo_data is the map data# Add the color for the chloropleth:
_ = folium.Choropleth(
geo_data=folium_world_data.as_posix(),
name='Choropleth',
data=countries_of_origin,
columns=['COUNTRY OF ORIGIN', 'pct'],
key_on='feature.properties.name',
fill_color='YlGn',
fill_opacity=0.7,
line_opacity=0.2,
nan_fill_color='white',
legend_name='Country of Origin (%)'
).add_to(m)
# Save to html
map_path = reports_path / 'walmart_folium_chloropleth_pct.html'
m.save(map_path.as_posix())
m
Countries of origin for Walmart shipments, by count
这不是很有用,因为中国控制得如此彻底,其他一切都接近于零。白色区域是根本没有向沃尔玛发货的国家(至少在数据中是这样)。黄色区域向沃尔玛发货,但百分比为个位数。
我在上面的原产国中增加了两列是有原因的。让我们再次绘制地图,但这次使用装运百分比的记录。为了简洁起见,我将省略代码,但我只是用‘log pct’替换了列参数中的第二个元素。
Countries of origin for Walmart shipments, by log(count)
这更有指导意义,因为它显示了亚军之间的相对位置。看着这张地图,我对那些几乎为零但又不完全为零的国家感到好奇。从视觉上看,沙特对我来说是一个奇迹。
xdata[xdata['COUNTRY OF ORIGIN']=='Saudi Arabia']['PRODUCT DETAILS'].describe().to_dict(){'count': 3,
'unique': 3,
'top': '320 BAGS, 19,200 KG OF ETHIOPI A ARABICA COFFEE SIDAMO GRAD- 2 TOP QUALITY REF P2006A, PA CKAGE: JUTE BAGS OF 60 KGS EA CH DELIVERY TERMS: FOB DJIBOU TI NET SHIPPED WEIGHT FDA R EGISTRATION NO. 11826035706 S',
'freq': 1}
啊哈,好像是从埃塞俄比亚转运过来的咖啡。看了一眼其他两件物品,显示花岗岩板和个人物品,而不是预期的 pertroleum 产品。另一件值得注意的事情是,“产品详细信息”条目有一些奇怪的断词问题(不限于此条目)。
看着分类数据框的尾端,我看到了韩国,考虑到它们在电子领域的规模,我想它们应该有不止一批货。
countries_of_origin.sort_values(by=['count'], axis=0, ascending=False).tail(4)
果然,韩国在数量上是第三名,如果我们用上面的头(3)替换尾(4),我们会看到这一点,这意味着韩国的单独发货是一个数据输入错误。另请参见中国台湾和台湾。向这些数据的所有者提供的一些反馈是,在输入数据时需要标准的国家名称。
在我们离开映射部分之前,我想指出 leav 的一个奇怪之处,我花了一些时间才弄明白。为了正确设置 choropleth 函数的 key_on 参数,我查看了 leav 数据文件leav/examples/data/world-countries . JSON以查找数据结构中的名称,给出了key _ on = ’ feature . properties . name '。
重要的事情
现在我们已经确定了哪些国家运送的物品数量最多,让我们来看看运送最重物品的国家。熊猫分组食谱对理解下面的表达很有帮助。
top_by_weight = countries_of_origin.sort_values(by=['max'], axis=0,
ascending=False)[0:10]['COUNTRY OF ORIGIN'].valuestw3 = xdata.groupby(['COUNTRY OF ORIGIN']).apply(
lambda subf:
subf.sort_values('WEIGHT (KG)',
ascending=False).head(3))cols_of_interest = ['COUNTRY OF ORIGIN', 'WEIGHT (KG)',
'PRODUCT DETAILS', 'ARRIVAL DATE']# [https://www.wolframalpha.com/input/?i=3e%2B07+kg](https://www.wolframalpha.com/input/?i=3e%2B07+kg)
# ≈ (0.7 to 1) × mass of a Handy size cargo ship
mass_handy_size = 3.0e+07 #kgtw3.loc[(tw3['COUNTRY OF ORIGIN'].isin(top_by_weight)) & (tw3['WEIGHT (KG)']>mass_handy_size)][cols_of_interest]
回想一下原产国是用 groupby 和‘重量(KG)’构成的,所以这里的 max 指的是重量。我不得不承认,我对排名靠前的国家感到非常惊讶,但当我看到这些产品时,我感到更加惊讶。
来自委内瑞拉的装运量最大,高出两个数量级。因为 dataframe 显示截断了“产品详情”栏,所以我们要确保我们在这里谈论的不是橄榄油…
list(xdata[xdata['WEIGHT (KG)']>1e+09]['PRODUCT DETAILS'])[0]'5,550.023 METRIC TONS (49,849 BBLS) LIGHT VIRGIN NAPHTHA'
石油石脑油是一种源自原油精炼的中间烃液体流。通过查看产品详细信息,我们看到出货量最大的是石油产品(烷基化油、汽油、石脑油)、建筑材料(岩石和水泥)和颗粒尿素(!?).把我搞得屁滚尿流他们用那个做了什么……
对我来说,这里隐藏的宝石是供应石油产品的各种意想不到的国家,以及一个预期的石油出口国(科威特)运送尿素。由 Wolfram Alpha 提供的另一个有趣的事实是,从委内瑞拉运来的石脑油几乎和吉萨大金字塔一样重。
停止
因为我们有“重量(KG)”和“集装箱数量”字段,所以我们可以计算出标准集装箱中的装运百分比。
考虑到“重量(KG)”几乎涵盖了 10 个数量级,并且还包括一些零值,我们会发现添加一列“log_weight_kg”很有用。
xdata['log_weight_kg'] = xdata['WEIGHT (KG)'].apply(lambda x: np.log(max(1, x)))
用 xdata[‘体重(公斤)’]。describe() 我们看到,一批货物的平均重量为 48815.86 千克,Wolfram Alpha 称这大约是一架波音 747–200 f 飞机载重量的一半。绘制“log_weight_kg”列的直方图可以得出:
其中红色虚线是中间值。
接下来,让我们来看看可能用标准 20 或 40 英尺集装箱装运的货物,按重量计算。这里我假设‘重量(千克)’是货物的净重*。*
向数据集中添加一个“kg_per_container ”,在这里我们对缺失值进行标准化,以便我们为每批货物至少准备一个集装箱。
xdata['kg_per_container'] = xdata.apply(calc_kg_per_container, axis = 1)
containerizable = xdata[xdata['kg_per_container'] <= NW_KG_DRY_CONTAINER_40FT]
如果它符合 40 英尺集装箱的重量要求,我们认为它是“可装箱的”,简单的计算表明 99.6%的装运都是如此。通过将我们的注意力缩小到这一大部分出货量,将大的异常值放在一边,我们可以对这些较小的出货量有一个更精细的了解。
每个集装箱的重量基本上稳步下降,除了在 19000 公斤/集装箱左右有一个小高峰。这可能是一个值得进一步研究的有趣领域。
另一个维度
为了强调为每个数据集创建数据字典的重要性,我们现在考虑“M.UNIT”列。我假设‘M . UNIT’是‘MEASUREMENT’列的单位(如果是这样,这种关系应该记录在数据字典中)。
xdata['M.UNIT'].value_counts().to_dict(){'CM': 93812, 'X': 47585, 'CF': 321, 'M': 128, 'F': 24, 'CC': 11, 'MM': 4, 'SS': 3, 'XX': 3, 'FF': 1}
我们可以猜测‘CM’的意思是立方米,‘CF’是立方英尺,但是其他的呢?重复我最初的观点,我们不应该去猜测;这些应该在数据字典中给出。既然看来我们必须猜测,让我们从不太常见的测量开始。
low_units = ['F', 'CC', 'MM', 'SS', 'XX', 'FF']
cols_of_interest = ['COUNTRY OF ORIGIN', 'WEIGHT (KG)', 'QUANTITY', 'CONTAINER COUNT',
'MEASUREMENT', 'M.UNIT', 'PRODUCT DETAILS'] # , 'ARRIVAL DATE'
pd.set_option('display.max_colwidth', 125)
pd.set_option('display.max_rows', 50)
xdata[xdata['M.UNIT'].isin(low_units)][cols_of_interest]
The first few entries of the less common M.UNIT collection
对于 low_units 中的六个不太常见的“M.UNIT”值,我可以容易地辨别的唯一模式是,如果“M.UNIT”是“F”、“FF”或“MM”,那么“MEASUREMENT”是零,所以这些可能是可忽略的。其他人将不得不保持神秘,直到我们可以与数据所有者交谈。
我们可以快速了解所有使用 seaborn 制造剥离场的单位的分布情况。我们将自己限制在一个 40 英尺集装箱的数据子集内。
xic = xdata[(xdata['CONTAINER COUNT']>0) & (xdata['WEIGHT (KG)']>0) & (xdata['kg_per_container']<=NW_KG_DRY_CONTAINER_40FT)]g = sns.stripplot(x='MEASUREMENT', y='M.UNIT', data=xic)
sns.despine() # remove the top and right line in graph
g.figure.set_size_inches(6,4)
plt_path = figures_path / 'measure_stripplot.png'
plt.savefig(plt_path.as_posix(), format='png'
Distribution of MEASUREMENT values by M.UNIT
我们将在下面更详细地观察“CM”的分布。
现在让我们来看看最常见的“公制单位”,“厘米”。使用 describe() ,我们知道如果‘M . UNIT’=‘CM’,那么‘MEASUREMENT’有非常大的值和零值,所以我们取一个子集:
xdata_cm = xdata[(xdata['M.UNIT'] == 'CM') & (xdata['MEASUREMENT'] > 0.0)].copy()
xdata_cm['logmeasure'] = xdata_cm['MEASUREMENT'].apply(lambda mm: np.log10(mm))
我们可以在这个子集上使用 seaborn 包来给我们一个漂亮的箱线图,这是一个与我们在上面看到的 stripplot 不同的视图。
max_logmeasure = xdata_cm.logmeasure.max()
max_logmeasure_shipment_id = xdata_cm['logmeasure'].idxmax()g = sns.boxplot(x = xdata_cm['logmeasure'])
# remove the top and right line in graph
sns.despine()_ = plt.annotate(s = max_logmeasure_shipment_id,
xy = (max_logmeasure,0),
xytext=(0.85, 0.65), textcoords='axes fraction', # bottom, left
# Shrink the arrow to avoid occlusion
arrowprops = {'facecolor':'gray', 'width': 1, 'shrink': 0.09, 'headlength':9},
backgroundcolor = 'white')g.figure.set_size_inches(6,4)
# plt.show()
plt_path = figures_path / 'logmeasure_box.png'
plt.savefig(plt_path.as_posix(), format='png')
我们添加的注释显示了这个极端异常值的行 id。我们还可以从该图和 describe() 中看到,四分位数范围是 58(从 7 到 65),大约有 2000-50000 个异常值,然后还有几个高于这个值。
cols_of_interest = ['SHIPPER', 'WEIGHT (KG)', 'QUANTITY', 'MEASUREMENT', 'CONTAINER COUNT', 'PRODUCT DETAILS']
xdata_cm.sort_values(by='logmeasure', ascending=False)[cols_of_interest].head(10)
The largest values of log(MEASUREMENT)
最上面的条目,我们的极端异常值,看起来非常可疑。如果“测量”以立方米为单位,这将相当于每年全球石油装运量的 10%左右。更令人难以置信的是“数量”字段。如果消息属实,光是这批货物就能为地球上三分之一的人提供一台 40 英寸的高清液晶电视。我就是不信。
再看看“迈耶工业”,我们得出的单位重量为 13.2 千克,这对于一套铝制炊具来说似乎是合理的。然而,我仍然不能使“测量”字段工作。从重量的角度来看,这批货物可能只装在 6 个 40 英尺的集装箱里,少于报道的 16 个。然而,16 个 40 英尺的集装箱只有 1083 立方米的容积,远远小于“测量”区域的 29000 立方米。
“CM”的“M.UNIT”是立方米,我们的猜测有可能是正确的吗?让我们来看看第三个分位数的一些值。
xdata_cm_sm = xdata_cm[xdata_cm['MEASUREMENT'] < CAPACITY_CONTAINER_40FT]
xdata_cm_sm.sort_values(by='logmeasure', ascending=False)[cols_of_interest].head(10)
Measurement should indicate that it would fit in a 40ft container
纯属巧合的是,这份清单中的第一项也是炊具,每箱重量为 13.2 公斤,同上。快速检查亚马逊上的 18 件套炊具,我们得到的产品尺寸为 11.5 x 22.8 x 13 英寸(3409 英寸或 0.05586 米),运输重量为 21.9 磅。这比这里装运的炊具要轻一点,如果我们按重量差异的比例放大体积,我们得到 0.074225 立方米。所有 942 套,完美包装,则需要大约 69.92 立方米的体积,这在“测量”值 67 的大致范围内(超出 4.3%)。
我们可以看更多的例子,但是有证据表明“CM”的意思是立方米。本节更重要的一点是,该数据集在用于预测之前似乎需要大量清理。
欺诈检查
在我们对最重的货物的探索中,来自巴哈马的物品让我惊讶——当我想到巴哈马时,我会想到蓝色的海水和沙滩,而不是石油出口。对巴哈马最大出口量的描述是“1 大堆 277328.140 桶烷基化油”。烷基化油是车用汽油的高辛烷值调和成分。为了便于讨论,让我们假设审计团队想要检查这可能的欺诈。看起来似乎没有足够的有用数据,但让我们看看是否可以帮助审计团队将这些数据从黄色标志(可疑)变为红色标志(欺诈)或绿色标志(正常交易)。)
我们将把“发货人”和“收货人地址”这样的字段留给我们的私家侦探精英团队,同时我们来看看一些更深奥的东西。需要指出的重要一点是:我不是石油运输方面的专家,所以我在这里做了很多假设。
顺便提一下,当我查看每个集装箱的重量时,我对这个条目产生了兴趣;“容器计数”是 1,但重量很大,所以它弄乱了我漂亮的直方图。
从“产品详情”中,我们得到数量:277328.140 桶。烷基化物的密度取决于温度。如果我们假设密度在 15–38°C 范围内呈线性变化,我们可以推导出一个给定重量和密度的温度公式。
Photo by Manki Kim on Unsplash
我们有桶的数量,事实上一桶是 42 美国标准加仑,换算后我们得到升的数量。我们从“重量(千克)”栏中得到重量,除以重量得到密度。将它代入我们的线性公式,我们发现温度是 21.24 摄氏度(这些计算在 Jupyter 笔记本上有详细说明)。
“抵达日期”是 2013 年 1 月 31 日。一艘轻便的船以大约 14 节的速度行驶;使用这个站点我们看到从巴哈马拿骚到纽约的旅行时间是 3.2 天,2013 年 1 月 27 日的天气在拿骚最低 21°C,最高 27°C。所以重量和产品细节似乎是可信的。
要最终确定这一点,必须看一下合同。我在 SEC 档案中找到的一份协议(不涉及沃尔玛)有这样一个条款:
“Barrel” — 42 U.S. standard gallons measured at 60 degrees Fahrenheit [15.556 °C].
如果我们假设同样的温度适用于这里,我们会有多远?简单的代数告诉我们,如果是这样的话,他们的出货量比必要的多出 0.7%。我想我们可以告诉审计员用绿旗做标记。
最后的想法
如果您将数据想象成一个多维的尖球:
Wolfram Mathematica Version 12 Spikey
您可以这样或那样转动它,看看哪些尖峰最突出(异常值)。之后,如果你去掉尖峰,你可以看看你的更典型的数据的形状。在本文中,我们已经通过观察计数和重量异常值做到了这一点。
如果您正在发布一个数据集,无论是内部的还是外部的,总是要包含一个数据字典,即使这些值看起来很明显。下面的参考资料部分有几个不错的资源。
令人惊讶的是,人们可以对许多数据集做些什么,即使它们似乎有不完整或有限的数据。通过使用来自不同列的数据,扫描一些文本字段,并使用外部来源,人们通常可以梳理出一些有趣的花絮。
感谢你和我一起踏上这个有趣的数据集的漫无边际的旅程。我希望我在这里概述的技术能够对您探索自己的数据集有所帮助。
参考资料和进一步阅读
源代码库中提供了一组完整的链接。这两个探索性数据分析参考都使用 R 语言,但是即使您只使用 Python,也值得一看。
- 如何制作数据字典,开放科学框架
- 数据字典:如何与最佳实践,卡尔·安德森
- 数据字典,美国地质调查局
- 探索性数据分析与 R ,罗杰·婷·彭
- 探索性数据分析,约翰·霍普金斯大学 via Coursera
- 针对每个数据集的 3 种出色的可视化技术、 Rahul Agarwal
- GeoJSON 和 choropleth,Felipe,Frank Conengmo,Joshua Cano,FloChehab
机器学习中的奇异值分解:欠定最小二乘
理解 SVD 如何帮助导出超定和欠定线性系统的一致最小二乘权重向量
Source: Tim Hill on Pixabay
本文讨论了超定和欠定线性系统中最小二乘权重向量的差异,以及如何应用奇异值分解 (SVD)来导出一致的表达式。它在很大程度上基于 Rebecca Willet 教授的课程机器学习的数学基础,并且假设了线性代数的基础知识。
“典型”最小二乘法
最小二乘可以描述为:给定形状 n × p 的特征矩阵 X 和形状 n × 1 的目标向量 y 我们要找到一个形状 n × 1 的系数向量***w’***直觉上,最小二乘法试图通过最小化每个单个方程结果的残差平方和来近似线性系统的解。
在大多数情况下,我们假设 n ≥ p 并且 rank( X ) = p. 换句话说,观测值的数量不小于特征的数量并且没有一个特征是其他特征的线性组合(没有“冗余”特征)。一个线性系统 y = Xw 如果 n ≥ p 则超定。我们可以用 法方程 得到w’:
但是,如果 n < p 或者当 X 中的某些列是线性依赖时,矩阵 A 可能不可逆。当特征数大于观测数时,我们称线性系统 y = Xw 欠定。
欠定最小二乘
当 n < p 、秩( X ) = n 时,系统 y = Xw 有无穷多个解。在这些解中,我们可以通过拉格朗日乘子法找到一个范数最小的解,并将其作为欠定线性系统的最小二乘权向量。
然而,为什么最小范数解是可取的?想象一个简单的例子,当你有下面的训练特征矩阵和目标向量时:
以下两个权重向量为训练数据提供了完美的拟合:
看这个的一种方式是:第三个特征是规模小。如果它容易受到测量误差的影响,并且我们对它赋予了很大的权重,那么我们对未知数据的预测可能会因为第三个特征而产生很大的偏差,从而远离真正的目标。所以第一种方案比较好。
下面展示了我们如何用拉格朗日乘数法导出最小范数解:我们想要在约束条件为 y = Xw 的情况下最小化∨w∨。介绍拉格朗日乘数 L :
在最佳条件下:
欠定最小二乘的权向量方程与超定最小二乘的权向量方程非常不同。
奇异值分解
本节提供了对 SVD 的基本介绍。考虑一个形状为n×p 的矩阵 X 。总是存在矩阵****【σ】**V使得:
当 U 和 V 正交时:
**σ是对角线:
U 的列是左奇异向量,它们构成了 X 列的正交基。
**σ的对角元素称为奇异值(σ₁≥σ₂≥…≥σₚ≥0)。非零奇异值的个数是矩阵 X 的秩,σ的列是 X 的行的基础。
V 的行称为右奇异向量,它们是uσ列上的基系数,用来表示 X 的每一列。
奇异值分解和最小二乘法
使用 SVD,我们可以重写最小二乘权重向量。以欠定最小二乘法为例:
上面的表达式看起来有点吓人,但是如果我们仔细看看:
这里σ⁺是σ的伪逆,形状为 p × n 。我们可以通过转置σ并取其对角元素的倒数来得到它。那么欠定线性系统的最小二乘向量可以重写为:
超定最小二乘法也是如此(随意验证)。有了 SVD,我们就有了权重向量的一致表达式。
确认
为了验证我们的发现,我们将使用 Jester 数据集的子样本。样本包含 100 个观察值和 7200 个特征,可在这里获得。每个观察都是一个笑话,每个特征都是现有用户对该笑话的已知评级,等级为-10 到 10。
假设我们为一家公司工作,该公司根据客户的已知评级向他们推荐笑话。对于评价了 25 个笑话的新客户 Joan,我们希望能够知道她喜欢剩下的 75 个笑话,并向她推荐预测评价最高的笑话。
要做到这一点,考虑一下我们已知的对 100 个笑话的评分的用户。他们代表了不同的品味。我们可以将 Joan 的评级看作这些客户评级的加权和。然后,我们将使用这些 m 客户的 25 个笑话评级作为特征,并将 Joan 的已知评级作为目标来训练回归变量。它应该能够推广到琼还没有预测好的其他笑话,以便我们可以推荐预测得分最高的笑话。琼的评分在这里可以找到。
加载数据,并使用以下块将其分为训练集和测试集。请注意,琼的未知评级表示为-99。
当 m = 20 时,为了简单起见,我们将使用前 20 个用户作为我们的代表用户。我们将根据琼对 25 个笑话的评价来计算权重,并将琼的评价作为目标。线性系统是超定的。当 m = 7200 时,线性系统欠定。使用以下代码准备数据。
使用 SVD 的 scikit-learn 型最小二乘估计器实现如下:
计算权重向量,并将其与从正规方程获得的权重向量进行比较:
对于 m = 20 和 m = 7200,我都得到“真”。你可以自己验证。
为了说明欠定最小二乘法如何提供对训练数据的完美拟合,我们可以在训练集和测试集上可视化预测值和真实目标。在这里有相应的代码。
这篇文章是何坤宇写的。昆玉目前是芝加哥大学的硕士生。他发现理解统计建模和机器学习技术、将它们应用于真实世界的数据并帮助创建金融服务行业的端到端解决方案是一件有趣的事情。在 LinkedIn 上联系昆玉!🐷
* [## 昆玉何-即将上任的全球量化策略非周期分析师-美银美林…
芝加哥大学正在接受理学硕士计算分析项目培训的数据科学家。对…充满热情
www.linkedin.com](https://www.linkedin.com/in/kunyuhe/)*
机器学习中的欠拟合和过拟合以及如何处理!!!
Photo by Markus Spiske on Unsplash
机器学习中模型性能不佳的原因是数据过拟合或欠拟合。
在这个故事中,我们将发现机器学习中的泛化概念以及随之而来的过拟合和欠拟合问题。
我们开始吧!!!
机器学习中的泛化
泛化指的是机器学习模型学习的概念在多大程度上泛化到模型尚未看到的特定示例或数据。
举个例子,假设我给你看一张猫的图片,让你给我“分类”;假设你正确地识别出它像一只猫,如果我把猫向左移动三个像素,你还能识别出它是一只猫吗?如果我把它翻过来呢?如果我把它换成一只不同品种的猫,你还能认出它吗?几乎可以肯定,所有这些问题的答案都是因为我们作为人类,我们以不可思议的轻松进行概括。另一方面,机器学习很难做到这些事情;它只在对一个特定图像进行分类时有效。
虽然机器学习可能能够在某个领域实现超人的性能,但除了它明确创建的领域之外,底层算法在任何其他领域都不会有效,因为它没有能力在该领域之外进行推广。从这个意义上来说,概括指的是智力的抽象特征,它使我们能够同时在数千个学科中发挥作用。
当我们谈论机器学习模型对新数据的学习和推广情况时,有一个机器学习中使用的术语,即过拟合和欠拟合。
过拟合和欠拟合是机器学习算法性能差的两个最大原因。
适合度
在统计学中,a 的拟合优度描述了它对一组观察值的拟合程度。
统计学通常描述拟合优度,它是指用于估计函数的近似值与目标函数匹配程度的度量。
过度拟合与欠拟合
我们可以通过观察相反的问题——欠拟合来更好地理解过拟合。
当模型过于简单(由太少的特征提供信息或太多的正则化信息)时,会发生欠拟合,这使得它在从数据集学习时不灵活。
简单的学习者倾向于在他们的预测中有较少的变化,但是更多偏向错误的结果。另一方面,复杂的学习者倾向于在他们的预测中有更多的变化。
让我给你打个比方来解释过度拟合和欠拟合。
过度拟合的模型就像主题专家:
他们对某个特定领域非常了解,例如主题专家。你问他们关于他们工具功能的任何问题(甚至是细节),他们可能会非常准确地回答你。但是当你问他们为什么油价会波动时,他们可能会做出明智的猜测,并说出一些奇怪的话。
就机器学习而言,我们可以将它们表述为过于关注训练集(程序员)和学习复杂的关系,而这些关系通常对新数据(测试集)可能无效。
不称职的模特就像那些想成为板球运动员但被父母强迫从事工程的工程师。他们对工程和板球都不太了解。他们对自己所做的事情从来都不感兴趣,对所有的事情都没有足够的了解。
就机器学习而言,我们可以说它们对训练集关注太少。既不适合培训也不适合测试。
如何检测欠拟合?
当一个模型试图建模的数据过于简单时,它就不适合。
检测这种情况的一种方法是使用偏差-方差法,它可以表示为:
当你有一个高偏差时,你的模型是不适合的。
如何避免不合身:
更多的数据通常不会有帮助。事实上,这可能会增加训练误差。因此,我们应该增加更多的功能。因为这扩大了假设空间。这包括从现有要素创建新要素。同样,更多的参数也可以扩展假设空间。
如何检测过度拟合?
过度拟合和一般机器学习的一个关键挑战是,在我们实际测试之前,我们无法知道我们的模型在新数据上的表现如何。
为了解决这个问题,我们可以将初始数据集分成单独的训练和测试子集。这种方法可以估计我们的模型在新数据上的表现。
如果我们的模型在训练集上比在测试集上表现得更好,那么我们很可能过度拟合了。
例如,如果我们的模型在训练集上有 95%的准确率,但在测试集上只有 48%的准确率,这将是一个很大的危险信号。
如何防止过度拟合
检测过度拟合是有用的,但不能解决问题。幸运的是,您有几个选择可以尝试。
以下是一些最流行的过度拟合解决方案:
- **交叉验证:**找出样本外预测误差的标准方法是使用 5 重交叉验证。
- **提前停止:**它的规则为我们提供了在学习者开始过度适应之前可以运行多少次迭代的指导。
- **剪枝:**剪枝在构建相关模型时被广泛使用。它只是删除了对当前问题没有多少预测能力的节点。
- **正则化:**它引入了一个代价项,用于在目标函数中引入更多的特征。因此,它试图将许多变量的系数推至零,从而减少成本项。
- **移除特征:**有些算法内置了特征选择。对于没有概化的要素,您可以通过移除不相关的输入要素来手动提高它们的概化能力。一个有趣的方法是讲述一个关于每个特性如何适应模型的故事。这就像数据科学家在软件工程师的橡皮鸭调试技术上的旋转,他们通过对橡皮鸭逐行解释来调试代码。
- **用更多的数据训练:**不是每次都管用,但是用更多的数据训练可以帮助算法更好的检测信号。在早期的儿童身高与年龄模型的例子中,很明显采样更多的学校将有助于你的模型。当然,情况并不总是这样。如果我们只是添加更多的噪声数据,这种技术不会有帮助。这就是为什么您应该始终确保您的数据是干净的和相关的。
- **集成:**集成是用于组合来自多个独立模型的预测的机器学习方法。有几种不同的组装方法,但最常用的两种是:
装袋 试图减少复杂模型过拟合的机会。
- 它并行培养了大量的“强”学习者。
- 强学习者是一种相对不受约束的模式。
- Bagging 然后将所有强学习者结合在一起,以便“平滑”他们的预测。
Boosting 试图提高简单模型的预测灵活性。
- 它按顺序训练出大量的“弱”学习者。
- 弱学习者是一个受约束的模型(也就是说,你可以限制每个决策树的最大深度)。
- 序列中的每一个都着重于从之前的错误中学习。
- 然后,Boosting 将所有弱学习者组合成一个强学习者。
虽然 bagging 和 boosting 都是整体方法,但它们从相反的方向处理问题。
Bagging 使用复杂的基础模型,并试图“平滑”他们的预测,而 boosting 使用简单的基础模型,并试图“提高”他们的总体复杂性。
如果你想了解更多关于集合模型的知识,集合模型的重要技术:bagging 和 boosting。请在下面的链接中浏览我以前的故事。
装袋和助推是全球各种数据爱好者常用的术语。但是到底装袋和…
medium.com](https://medium.com/@sainikhilesh/difference-between-bagging-and-boosting-f996253acd22)
我希望这篇文章能让你对这个话题有一个坚实的理解。在这篇文章中,你已经了解了机器学习中过度拟合和欠拟合的泛化术语。
你有任何关于过度合身、不够合身或与这篇文章相关的问题吗?留下评论,提出你的问题,我会尽力回答。
感谢阅读!❤
理解使用时间序列数据的数据分析和可视化。
《让数据和时间说话》
Photo by Dylan Clifton on Unsplash
H 人类有幸拥有人工智能和数据科学,因为它帮助我们解决日常问题。我们经常会遇到大量的时间序列数据,这些数据与我们的日常活动非常相似。
在本帖中,我们将学习如何使用数据分析来洞察数据,并了解数据的行为。
我们使用了*【Junglee Rummy business】时间序列数据集,在这里下载 。数据集归**【Junglee Games】***所有。访问 链接 以获得数据集的概述。你也可以 玩 游戏。
我们必须了解与数据集相关的术语。让我们来看看:-
- 入场费:这是玩家以卢比支付的入场费。
- 座位:可以坐在桌子上的最大玩家数量,即数据集的 2,6 人。
- 组成:实际加入牌桌的玩家数量。
- 日期:2018 年 7 月 1 日至 2018 年 9 月 30 日的数据集,给出了每个表配置的每日数据。
- 配置:定义为入场费—席位—构成的组合。
- Cut % %:从每个用户的每场游戏中扣除的年龄金额。
- '#Users ':当天至少玩了一场牌桌配置游戏的玩家(唯一玩家)的不同计数。
- 用户现金游戏计数:当日用户在牌桌配置上玩的游戏总数。如果用户 A、B、C 一起玩一个游戏,那么值将是 3。
- Rake:该日期从表配置中生成的收入总额。
- 赌注:用户根据参加游戏的费用支付的总金额。
我们开始吧!
我们会加载重要的库,让我们来看一看数据。
***import******pandas******as******pd******import******seaborn******as******sns******import******matplotlib.pyplot******as******plt******import******numpy******as******np****# reading the data using pandas*
df = pd.read_excel('BI Skill Test - Data Set.xlsx')
df.head()
数据集非常直观。如果不能理解,请阅读上面的专栏描述。我们将把Cut%
乘以 100,使其计算简单。
*# Multiplying cut% with 100 to make it easy for computation*
df['Cut %'] = df['Cut %'] * 100
基本统计
现在我们对数据有了一个简单的了解。分析数据集的基本统计数据是非常必要的。
*# Basic statistics of tha data*
pd.options.display.float_format = '**{:.0f}**'.format
df.describe()
在数据科学中,这些统计数据对于深入了解数据起着至关重要的作用。通过上表中的数字后,观察到的一些情况如下:
- 入场费: 用户玩一个游戏平均支付的入场费为 854 卢比,最低入场费为 5 卢比,最高入场费为 10000 卢比。大多数时候,用户支付 100 卢比作为入场费来玩游戏。
- 坐席: 坐在一起的玩家平均人数是 5 人,其中,平均 4 人上场。而最多有 6 名玩家。
- ***削减%***平均削减%为 13%。大多数玩家支付 15%作为提成。
- 【用户数量: 平均每天至少玩一个游戏的用户数量为 165,而每天至少玩一个游戏的用户数量最多为 1155。
- Rake: 公司平均每天赚的钱数是 10137 卢比。公司一天赚的最多的钱是 271200 卢比。公司大部分时间赚 3195 卢比。
- 赌注: 玩家投入游戏的最高金额是 4520000 卢比,而大多数时候用户支付 24000 卢比。
仅仅一行代码就包含了大量的信息。感谢熊猫。
将一些信息进一步可视化会很有趣。我们将使用matplotlib
python 库来执行同样的操作。
让我们从用户支付的作为游戏入门费的总金额开始。
plt.figure(figsize=(9, 8))
sns.distplot(df['Wager'], color='g', bins=100, hist_kws={'alpha': 0.4})
plt.title("Total amount paid by the users in terms of Entry Fees to play the game")
根据上面的图表,我们观察到大部分时间用户在某一天支付大约 25000 卢比。
现在,让我们来看看该日期从表配置中产生的总收入。
plt.figure(figsize=(9, 8))
sns.distplot(df['Rake'], color='b', bins=100, hist_kws={'alpha': 0.4})
plt.title("Total amount generated in revenue from a table configuration for the date")
通过上面的图表和基本的统计数据,可以认识到公司每天大部分时间的收入在 3000 卢比左右。
B 用户支付卢比进入游戏
num_bins = 60
plt.hist(df['Entry Fee'], num_bins, facecolor='blue', alpha=0.5)
plt.title("Buy-in (money user pays) in rupees to enter the game")
plt.show()
我们观察到,大多数人购买票价低于 1000 卢比的门票。有一些用户花 10000 卢比作为入门费来玩这个游戏。
时间序列分析
数据分析和可视化让我们深入了解数据,在某些情况下,我们可能会遇到奇迹。因此,让我们深入数据集,执行时间序列分析。
我们主要关注的是数据的行为。
我们会将日期(按字母顺序书写)转换为对应的数字,并为日期、月份和年份创建单独的列。使用数字数据很容易进行数据分析。
我们将使用datetime
python 类将日期转换为datetime
格式。让我们看看它是如何工作的。
*# introducing datetime*
**from** **datetime** **import** datetime, date, time
datetime.strptime('July 1, 2018', '%B **%d**, %Y')
输出:
datetime.datetime(2018, 7, 1, 0, 0)
现在,我们将对整个日期列执行相同的操作。
*# converting date to datetime format*
date = []
**for** d **in** df['Date']:
x = datetime.strptime(d, '%B **%d**, %Y')
date.append(x)
df['my_date'] = date
print(df['my_date'][0].month)
print(df['my_date'][0].day)
print(df['my_date'][0].year)Output:7
1
2018
将日期时间转换为单独的列
*# converting datetime to individual columns*
day = []
month = []
year = []
**for** i **in** df['my_date']:
day.append(i.day)
month.append(i.month)
year.append(i.year)df['day'] = day
df['month'] = month
df['year'] = yeardf.head(2)
现在,我们已经将日期转换为日期、月份和年份的个人列。让我们进行时间序列分析。
按月销售
*#sale by month*
sales_by_month = df.groupby('month').size()
print(sales_by_month)*#Plotting the Graph*
plot_by_month = sales_by_month.plot(title='Monthly Sales',xticks=(1,2,3,4,5,6,7,8,9,10,11,12))
plot_by_month.set_xlabel('Months')
plot_by_month.set_ylabel('Total Sales')
plt.title("Monthly sales analysis")
据观察,与其他月份相比,一月份的销售数量较高。随着时间的推移,销售额下降了。
白天销售
*#Sale by Day*
sales_by_day = df.groupby('day').size()
plot_by_day = sales_by_day.plot(title='Daily Sales',xticks=(range(1,31)),rot=55)
plot_by_day.set_xlabel('Day')
plot_by_day.set_ylabel('Total Sales')
plt.title("Daily sales analysis")
我们观察到,与其他月份相比,本月前五天的销售额较高。
如果我们能够获得每小时的数据,我们可以更好地分析销售行为。
每月玩家人数
观察每个月参与游戏的用户数量是个好主意。我们将使用boxplot
来可视化相同的内容。
*# number of users played per month*
sns.boxplot(x='month', y='# Users', data=df)
plt.title("Number of users played per month")
plt.show()
随着时间的推移,每月的用户数量逐渐增加。如果我们关注分位数,一月份平均每天大约有 100 人。但最多也就 400 人左右。在 9 月份,平均每天大约有 220 个用户,而每天大约有 1200 个用户。其他月份也是如此。
每月在桌面配置中玩的用户数
*# Number of users played in table configuration per month.*
sns.boxplot(x='month', y='User Cash Game Count', data=df)
plt.title("Number of users played in table configuration per month")
plt.show()
同样,如果我们关注一张桌子上每个月玩的游戏数量。一月份一天大约有 100 人玩,而一天最多有 800 人玩。我们注意到在四月份玩的游戏数量有轻微的下降。在九月份,平均有 500 人在桌上玩,而最多有 3000 人在桌上玩,75%的时间有 900 人在桌上玩游戏。
公司每月赚取的利润
*# Profit earned by company every month*
sns.boxplot(x='month', y='Rake', data=df)
plt.title("Profit earned by company every month")
plt.show()
如果我们观察箱线图,公司在 9 月份平均获得了大部分利润。我们还看到,5 月份一次赚取的最大利润约为 300000 英镑。在二月份,公司收入最少。
用户每月支付的作为玩游戏入门费的总金额。
*# total amount payed by users as entry fee to play games per month.*
sns.boxplot(x='month', y='Wager', data=df)
plt.title("Total amount payed by users as entry fee to play games per month")
plt.show()
我们观察到与上述 RAGE 图相同的情况。在 5 月份,用户玩游戏花费的金额最大。平均而言,9 月份的记录不错。
现在让我们进行日间分析,看看我们是否能得到任何进一步的重要信息。
*# number of cash games played by users per day.*
plt.figure(figsize=(20,18))
df.plot(kind='scatter', x='day', y='User Cash Game Count');
plt.title("Number of cash games played by users per day")
plt.show()
*# Revenue earned by users in days of month*
df.plot(kind='scatter', x='day', y='Rake');
plt.title("Revenue earned by users in days of month")
plt.show()
*# Amount spent by user every day of the month.*
df.plot(kind='scatter', x='day', y='Wager');
plt.title("Amount spent by user every day of the month")
plt.show()
我们对时间序列数据进行了基本的数据分析,可以从中获得很多信息。这只是操纵数据和灌输思想的游戏。
结论和意见
- 入场费:首先,最高人数花费 100 卢比进入游戏。
- 座位:一张桌子最多可以坐 6 个玩家,其中 3 个玩家大部分时间都在玩。
- Cut%:在大多数情况下,每个用户要扣除 15%的金额。
- 用户数量:每天至少有 112 名玩家玩桌上游戏。
- 用户现金游戏:在大多数情况下,一天有 212 名玩家玩桌上游戏。
- Rake:公司平均每天赚 3195 卢比。
- 赌注:每天用户平均花费 24000 卢比。
- 我们观察到,大多数用户花不到 1000 卢比玩游戏。
- 据观察,与其他月份相比,一月份的销售数量较高。随着时间的推移,销售额下降了。
- 我们观察到,与其他月份相比,本月前五天的销售额较高。
- 我们观察到,随着时间的推移,用户的数量逐渐增加。但 5 月份的用户参与度比前几个月高得多。
- 我们看到,公司在五月份创造了非常高的收入。
- 我们已经观察到,该月的每一天都显示出公司的统一收入生成。
- 总的来说,我们发现 5 月份是公司盈利能力最好的月份。它在这方面显示出显著的增长。而就盈利能力而言,二月份对公司来说有点奇怪。
源代码可以在我的 Github repo 上找到。我期待听到任何反馈或问题。感谢您阅读这篇文章。
在 LinkedIn 上关注我。