TowardsDataScience 博客中文翻译 2019(一百二十九)

原文:TowardsDataScience Blog

协议:CC BY-NC-SA 4.0

MODIS 数据的数据分析

原文:https://towardsdatascience.com/data-analytics-with-modis-data-46338cd6e4d2?source=collection_archive---------9-----------------------

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Aerosol Optical Depth imagery over the entire world

MODIS(或中分辨率成像光谱仪)是美国宇航局 Terra 和 Aqua 卫星上的成像传感器,绕地球运行,捕捉图像,以了解和研究地球表面的各种现象。你可以从这些图像中提取一大堆产品,从地理定位、云罩、大气产品到陆地和冰冻圈产品到海面温度产品。这些数据可以极大地帮助理解天气的动态变化、风的模式,甚至是人类在某个地区的影响。

这有什么大不了的?

当我开始时,我发现最大的问题当然是处理这些地理空间数据。我从事大气气溶胶光学厚度(AOD)的研究,试图了解气溶胶通过吸收或散射阳光来减少日照的作用。对于初学者来说,没有一个关于处理这些数据的指南。所以在一个地方编译我找到的那些方法是有意义的,可以对那里的人有所帮助。所以让我们开始吧…

代码可以在这里找到。

但是首先我们得到数据

MODIS 数据可以从这个网站下载。我特别选择了主菜单中的大气产品(因为 AOD 数据应该在那里),然后被重定向到 NASA LAADS 网站。你可以很容易地找到一个 Find Data 选项卡,点击它会导向这里:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

从下拉列表中,选择记录您正在寻找的产品数据的传感器。我选择了 MODIS Terra 传感器(尽管 MODIS Aqua 传感器同样适用于我们的目的),并在这里着陆:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

看看如何从左侧窗格中的各种收藏中进行选择。我简单地选择了气溶胶,它让我有了两个选择——L2 3 公里长的条带和 L2 10 公里长的条带数据。它只是代表了一张地球快照所覆盖的面积(在这样的项目中,将数据想象成地球的图像总是有帮助的,因为这就是它们的真实面目!)。因此,根据您是希望处理 3 公里×3 公里的区域还是 10 公里×10 公里的区域,您可以选择所需的集合。

其余的选项非常简单。该菜单要求您输入持续时间、位置,并显示您可以下载的文件(HDF)格式。文件名包含文件的基本信息:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

What your file name says!

因为我想分析北印度 AOD 一年的情况,所以我下载了一年中每一天所需地区的 HDF 文件。文件可以在我的 Github repo 中找到。

将数据加载到 Python

在经历了许多失败和挫折之后,我遇到了gdal(地理空间数据抽象库),事实证明它在处理上述数据时非常有用。然而,事实证明,使用 Python 的默认包管理器*pip*来安装 gdal 对我来说更加困难。所以我直接将它安装到我的 Anaconda 环境中;只要做好*conda install gdal* 我就好了。

打开单个文件

下面的代码打开路径指向的文件。

下载的每个文件都有许多附属的子数据集。只是为了看看我们得到了什么,*GetSubDatasets()* 可以分别列出不同的数据集,返回一个*path* 打开的数据集和一个*desc* 的数据集。打印描述会告诉您许多关于您正在处理的数据类型的信息:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Just a small number in this screen. There are several others to deal with as well

基本上这些名字都是不言自明的。附加到描述的是数据集被格式化成的矩阵的大小(在左边)和用于存储数据的数据类型(在右边)。因此,让我们编写一些通用函数来加载我们希望加载的任何特定子数据集。

*上述函数获取*FILEPATH* 并从该文件加载*SUBDATASET_NAME* 。例如,要打开文件中的第一个子数据集,只需将*FILEPATH* 指向存储 HDF 文件的目录,并将*Scan_Start_Time mod04(64-bit floating-point)* 传递给*SUBDATSET_NAME* *。这段代码将打开子数据集,将其作为数组读取(*subdataset.ReadAsArray()*),并返回一个 pandas dataframe,供以后处理。

在您希望的位置获取数据

如果您需要整个区域的平均乘积,只需对整个矩阵求平均,这将是当天该区域的 AOD(尽管您需要处理缺失数据)。我们一会儿就会谈到这一点)。但是如果你,只需要提取那张 10 公里 x 10 公里图像的一小部分,你需要找到图像上最接近你要找的位置的像素。

那么你是如何做到这一点的呢?尽管我认为有几种方法可以解决这个问题,但我还是采用了以下方法:

  1. 打开纬度子数据集,找到单元格的行号,它的值最接近我正在寻找的纬度。这个想法来自于这样一种理解,即纬度子数据集中的每个单元代表图像中该像素的纬度。
  2. 现在,使用步骤 1 中的行号,我将在经度子数据集中找到像素的列号,这是离我要寻找的地方最近的。
  3. 所以现在我有了离我瞄准的位置(地理坐标)最近的像素的行号和列号。我现在可以打开其他子数据集,比如说Deep _ Blue _ Aerosol _ Optical _ Depth _ 550 _ Land mod 04(16 位整数)并提取该像素的值。这个值给了我当天使用深蓝检索算法在那个地方测量的 AOD。我们可能希望有 9 到 25 个像素的平均值,以我们刚刚找到的像素为中心,以防万一,该像素当天的值为空(当天该像素上的数据无法记录)。

Finds the latitude pixel

上面的代码找到了像素的行号*,该像素的值(本质上是纬度)是距离我们正在寻找的*CITY_LATIDUDE* 最近的*。**

Finds the longitude pixel

经度也有类似的故事。请注意,我不是在整个矩阵中搜索,而是在我刚刚在前面的函数中找到的行号所在的行中搜索(用*LATITUDE_ROW_NUMBER*表示)。

上面的函数非常简单,给定一个特定的子数据集,latitude 函数找到的行号和 longitude 函数找到的列号,返回子数据集中该像素的乘积值。

我们需要做的最后一件事是以某种方式处理要打开的子数据集,找到像素坐标,并获得所需的平均值(基本上是将上述所有内容放在一起):

*很明显,上面的函数找到了 lat_row 和相应的 *lon_column,决定考虑哪些子数据集,并在 9 个单元格的网格上求平均值(我们的像素在网格的中心)。如下图所示:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

还要注意,在数据集中, -9999 的值表示未能记录该位置的数据。所以我简单地放了一个 0 在那里。

处理大量数据…

上面的驱动代码简单地在一个月内迭代所有 HDF 文件,提取散射角、AOD(深蓝)、云分数、组合(深蓝和暗目标检索算法组合)、*和 A *ngstrom 指数、*将所有内容添加到一个列表中,通过*pd.Series()* *、*将所有内容转换成一个序列,并向*pd.DataFrame()* *添加一个新列。最后,我们可以导出当月的。csv 文件供进一步分析。

分析

以下两个助手例程将帮助我们绘制每个月的数据以及平均参数,以便我们可以查看其在一段时间内的平均变化。我在*plot* 例程中做了几件事情,一个接一个地叠加线条图,检索函数返回的任何内容,从中获取图形(使用*get_figure()*),并将图形保存到文件中,以备将来使用。

这里的一切都很明显。我使用一个字典来跟踪哪个月份以什么顺序被处理(例如,根据文件名,四月是第一个被处理的月份)。它只需要创建一个给定的地图,当追加平均的深蓝 AOD T21 数据时,追加对应于日历中月份的整数。这将有助于排序列表,并返回从 1 月到 12 月的时间变化。

我将分享一些情节和我从中得到的一些感悟。在这里找到其他人。

大势第一

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

上图描绘了平均气溶胶产品的年变化。y 轴报告从深蓝算法中检索的值。为了得到实际值,检索到的值需要用0.001(MODIS 使用的缩放因子)进行缩放。

上图是全年的平均月 AOD 变化。可以看出,AOD 在夏季上升,在雨季下降,在冬季再次上升

2018 年 1 月趋势(注 MODIS 数据使用 0.001 的比例因子。所以实际值是在数据值乘以比例因子时获得的)

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Variation of Deep Blue AOD and Cloud Fraction over January 2018

上图绘制了从深蓝检索算法获得的 AOD 值和获得的云分数数据值。很明显,总的来说,每当云分数高的时候,AOD 往往就低。事实上,这并不低,只是卫星成像传感器无法记录当天的数据。并且在 1 月 2 日左右观察这个峰值。如果你稍微想一想,你就会意识到,新年庆祝活动就是这样!

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Variation of Combined AOD and Cloud Fraction over January 2018

这里可以合理地看出,使用暗目标和深蓝的组合 AOD 给出了对 AOD 的有点不正确的估计。据报道,大部分时间 AOD 都在 0 左右。众所周知,事实并非如此,尤其是在新年前后。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Variation of Deep Blue AOD and Scattering Angle over Januray 2018

深蓝 AOD 和散射角都是 放大 0.001 倍 。这里可以看到 AOD 的一个尖峰信号是如何导致散射角突然增加的,这意味着更多的阳光被阻挡。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Variation of Deep Blue AOD and Angstrom Exponent over January 2018

Angstrom 指数是 AOD 相对于光的各种波长如何变化的量度(称为“光谱相关性”)。这与气溶胶粒子大小有关。较高的值表示颗粒较粗,而较小的值表示颗粒较细。这里,通常较高的值~ 0.5(500 0.001[比例因子 ])表示通常较细的颗粒。一项 PM2.5 研究可以补充这一发现。*

8 月16】数据中发现了奇怪的结果。由于本月持续的高云量,MODIS 未能检索到 AOD 数据。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Variation of Deep Blue AOD and Cloud Fraction over August 2018

正如所料,其他变量也遭受了类似的后果。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Variation of Combined AOD and Cloud Fraction over August 2018

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Variation of Deep Blue AOD and Angstrom Exponent over August 2018

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Variation of Deep Blue AOD and Scattering Angle over August 2018

摘要

最后,让我们在这里得出一些推论:

  • 季风期间AOD 水平的下降是由于强日照,促进了气溶胶的柱状混合。
  • 冬季AOD 气温上升是由于日照减少和寒冷 气温;由于低大气边界层和在陆地附近捕获气溶胶,气溶胶的反向柱状混合。****
  • 夏季更强的对流(主要来自西方扰动和信风)伴随着更深的大气边界层导致夏季坎普尔上空气溶胶聚集。****
  • 云量是 AOD 测量中的一个重要因素。较高的云量通常会导致当天没有数据。在本报告中,这样的日子被 替换为所考虑月份的平均值
  • 美国宇航局的深蓝检索算法在陆地图像上给出了比暗目标检索更准确的结果。
  • 坎普尔的人们在 2018 年的新年和排灯节前夕确实爆了很多饼干!2018 年 1 月 1 日和排灯节的堪普斯太模糊了,甚至无法记录图像来获取数据,2018 年 1 月 2 日看到了约 1.2 AOD。
  • 由于持续的高云量,2018 年 8 月出现了记录 AOD 数据的直接失败。

利用 MODIS 数据,你可以做更多的事情。你可以找到森林覆盖数据,研究海洋,等等。我希望这篇文章能帮助你处理任何 MODIS 产品,你可以没有任何麻烦地完成你的学习。

祝你今天开心!玩的开心!

数据作为设计的新媒介

原文:https://towardsdatascience.com/data-as-a-new-medium-of-design-1d4cbc7bfea1?source=collection_archive---------21-----------------------

第二部分

上接“设计流程中的数据科学”,该研究旨在帮助服务设计师在设计流程的所有阶段使用数据,从使用数据进行研究和分析,到使用数据作为创意媒介和工具。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Image from HSO.com

企业现在将数据视为原材料,宣称“数据是新的石油”,据称这是数学家 Clive Humby 首先说的,他建立了 Tesco Clubcard 忠诚度计划(Marr,2018 年),King 等人(2017 年)将数据称为“当今的货币”。随着这种即将到来的数据商品化趋势,设计师们现在比以往任何时候都更开始使用数据作为一种工具,进一步告知他们的直觉和对用户的定性研究(黄,2016)。

越来越多的设计机构开始将数据整合到为客户设计新服务和产品的过程中。随着数据量的不断增加,开发利用大数据的方法变得至关重要。 Topp (2016),一家来自瑞典的设计和数据实验室,已经开始超越传统的使用数据的方式,将数据用作收集人口统计见解或监控使用情况的来源。Topp 已经开始使用数据作为设计材料,他们认为这开辟了“创造性和战略性的道路,否则这些道路将会被遗忘。”Topp 举办了一系列研讨会,试验基于设计的构思和用数据绘制草图。有趣的是,他们认为强加人类视角和我们创造叙事的能力使我们能够“从数据中阅读故事”,这意味着激发想法,并给设计师提供不同的视角和观点来工作。他们不相信这些故事需要有统计上的相关性,并把对数据的解释作为整个设计过程中使用数据的基础来讨论。一方面,他们认为你不一定要成为数据科学家才能从数据中获得创造性的见解。然而,另一方面,他们承认,他们通过使用数据作为思维工具产生的想法“如果我们是数据科学家,当然会完全是疯狂的言论”。

已故的汉斯·罗斯林以全球卫生教授的身份开始了他的职业生涯,但他以统计学家的工作以及他在世界各地关于统计力量的演讲和介绍而闻名。他出现在一部名为《统计的快乐》的纪录片中,这部纪录片认为,统计让人们看到了一个我们无法通过任何其他方式获得的世界。“统计数据告诉我们,我们认为和相信的事情实际上是否是真的”(罗斯林,2010)。根据 Claeson 的说法(Watts,2017 年引用),“汉斯具有简化复杂问题并以幽默的方式呈现它们的独特品质,这让我们倾听、提问并进行更知情的辩论”。这句话说明了当以一种创造性的、平易近人的方式传达给不太熟悉数据的人时,数据会有多么强大。

Pamela Pavliscak (2016)是 UX 研究和战略公司 Change Sciences 的创始人,她的方法部分是民族志,部分是心理学,部分是数据科学,“将未来的愿景转化为有形的日常可能性”(Change Science,无日期)。她将算法作为一种新的设计媒介。她表示,体验设计师越来越依赖于用算法进行设计,并认为设计越来越多地通过使用算法来增强人类体验和创造更好的情感意识。

此外,数据正在成为一种新的艺术形式,因为“数字技术和‘传统’创作实践之间的界限正在消失”(Murray,2014)。数据正在成为艺术的媒介,艺术家们将它比作颜料或画布,许多人认为数据不应该只留给统计学家和企业界,这凸显了数据在各个行业和学科中的重要性(Murray,2014)。一个这样的例子是 信息是美丽的 *,*一个创建美丽的交互式数据-可视化和信息图表的组织,基于“跨越艺术、科学、健康和流行的模式和联系,揭示隐藏在我们周围的数据、信息&知识中错综复杂、不可见且有时滑稽可笑的故事”(信息是美丽的,没有日期)。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Data visualisation from Information is Beautiful (2018)

随着数据不再仅仅为商业关键决策提供信息,而且还融入到艺术、设计甚至音乐创作中,数据作为一种新媒体的崛起引起了一些评论家的坚定判断,他们认为数据的使用“干扰了创造力”,最好留给商业世界处理(PromptCloud,2017)。

用数据进行设计时道德的作用

“数据本身在最好的情况下是没有意义的,在最坏的情况下是误导性的”——Pardi,2016 年

我们世界的数字化不可否认地被视为一把双刃剑。虽然有些人强调了数字化和数据给我们的社会带来的好处(Sabbagh 等人,2012 年),但其他人强调了它已经并将继续对社会产生的有害影响(Loebbecke,2015 年)。技术进步将继续快速加速(Treseler,2015)。

Murray (2014)认为,大数据不能保证客观真实,因为数据的优势、无处不在和可塑性也是其弱点,人们越来越担心隐私和安全受到侵犯。他指出了“社会实证主义者视野中的缺陷,这些人将数据视为某种治疗世界疾病的灵丹妙药”。

Zwitter (2014 年)认为,大数据产生了重新思考道德规范的需求,特别是在个人道德责任方面,因为个人失去了理解其潜力和做出明智决定的能力。社交网络数据、可穿戴设备生成的健康数据、电子邮件和手机应用程序的数据都有可能被不道德地滥用。个人不熟悉他们的数字足迹的无意后果。“当大数据集的二次使用可以对过去、现在甚至未来的隐私、保密性和身份的破坏进行逆向工程时,专注于管理个人身份信息的现有隐私保护是不够的”(Richards & King,2014)。新闻和媒体经常报道数据安全漏洞的数量。一个比较突出的例子是,剑桥分析公司非法访问了数百万份脸书个人资料,并设法收集了大量个人数据。他们能够理解甚至试图改变人们的政治观点,这可能影响了最近的美国总统选举(Halpern,2018)。

Pavliscak (2016)提请注意情绪感应应用程序和设备的兴起,并鼓励以极简方式使用数据和基于这些数据创建算法。Halpern (2018)也认识到这种敏感数据的危险,因为它为心理控制奠定了基础,“通过直接诉诸他们的情绪,使用越来越细分和细分的人格类型指定以及基于这些指定的精确定向信息。”

近年来,在数据收集和使用方面受到审查的最著名的组织之一是美国政府机构——国家安全局,也称为 NSA。支持者为其侵入性的电话和互联网记录收集辩护,理由是只收集“唯一”元数据——你给谁打电话,什么时候打,打了多长时间——认为由于对话的实际内容没有被记录,对隐私的威胁无关紧要。这是一个充其量是误导的论点。关于数据的道德使用以及当今元数据如何“告诉你关于某人生活的一切”,最有争议的说法之一可能是美国国家安全局前局长迈克尔·海登将军(2014 年在科尔引用)所说的“我们基于元数据杀人”。这一令人震惊的声明证明了数据不仅可以违反道德标准,还会给人类带来更大的风险。当一组数据因其(元)知识而被用于生死决策时,忽略人的作用也就忽略了移情、价值观、情商和人性的价值。

数据解释的不足

霍华德(Pollack,2012 年引用)说“数据没有给胡说留下任何空间。[……]人们会争论,但你可以给他们看数据。它不会说谎。”然而,Topp (2017)认为,没有人类的解释,数据只是对一个现实的描述。

任何数据都没有内在价值,因为所有信息本身都没有意义。为什么?因为信息不会告诉你该怎么做。
——博·洛托(引自帕迪,2017)

Pardi (2017)对作为设计师、工程师或任何创造事物的角色,单独依赖数据的危险进行了有趣的观察。他指出,数据只是信息,并不代表客观现实。他提出了一个令人信服的事实,即数据是“由进行处理的个人高度语境化的”,因为不同的人会以不同的方式解释数据,而他们的语境对这种解释有很大的影响。他用的例子如下。

朗读课文 :

w at a e y u ea ing n w?

如果你读到“你现在在读什么?”,你做了很多人会用同样的“数据”阅读的事情,尽管句子中没有包含一个英语单词。你的大脑填补了空白,因为你与英语的关系,你被提示“大声朗读课文”,这影响了结果。然而,如果你在吃零食,饿了或者坐在餐馆里,你可能会读到“你现在在吃什么?”。

关键在于,数据科学家的角色正是如此——通过解释来理解数据,并将分析转化为可供组织其他部门采取行动的见解。这个例子表明,数据永远不可能是客观事实,因为它依赖于一个或多个个人的主观解释,所有人都从他们的角度和背景来看待数据。与 King 等人(2017 年)类似,Pardi (2017 年)暗示,当想要创造性地使用数据时,以“驱动”为重点的数据驱动并不是一个好方法。然而,他确实相信数据可以支持创造性和创新性的成果。事实应该通知设计者,以便他们可以试验未来的可能性,发现原始数据无法提供的洞察力。

参考

Cole,D. (2014) 我们根据元数据杀人。可从:https://www . ny books . com/daily/2014/05/10/we-kill-people-based-metadata/(访问时间:2018 年 9 月 27 日)。

黄(2016) *设计师如何利用数据创造出令人惊叹的作品。*可在:https://www . invision app . com/inside-design/how-designers-can-use-data/(访问时间:2018 年 10 月 10 日)。

King,r .,Churchill,e .,Tan,C. (2017),用数据进行设计。加利福尼亚州塞瓦斯托波尔:奥莱利媒体公司。

Loebbecke,c .和皮科特,A. (2015),《对数字化和大数据分析引发的社会和商业模式转型的思考:一项研究议程》,《战略信息系统杂志,第 24 卷第 3 期,第 149-157 页。

Marr,B. (2018) 这就是为什么数据不是新的石油。可从:https://www . Forbes . com/sites/Bernard marr/2018/03/05/heres-why-data-is-not-the-new-oil/# b 00 c 0b 23 aa 96(访问时间:2018 年 11 月 13 日)。

Murray,B. (2014) 设计之美:数据与数字艺术的交集。可从:https://TechCrunch . com/2015/02/27/beauty-by-design-the-crossover-of-data-and-digital-art/(访问时间:2018 年 9 月 27 日)获取。

如果你想有创造力,就不要被数据驱动。可从:https://medium . com/Microsoft-design/if-you-want-to-be-creative-don-be-data-driven-55db 74078 EDA(访问时间:2018 年 10 月 4 日)。

Pavliscak,P. (2016) 算法作为设计的新材料。可从 design.php获得 https://www . UX matters . com/mt/archives/2016/06/algorithms-as-the-new-material-of-(访问时间:2018 年 10 月 12 日)。

n . pol lack(2012)万亿字节革命:Kaggle 如何将数据科学家变成摇滚明星。可从:https://www.wired.co.uk/article/the-exabyte-revolution(访问时间:2018 年 10 月 12 日)。

PromptCloud (2017) 大数据。可从:https://towardsdatascience.com/how-big-data-can-impact-creative-in-the-near-future-95e0a 626840 a(访问时间:2018 年 9 月 4 日)获得。

Sabbagh,k .、Friedrich,r .、El-Darwiche,b .、Singh,m .和 Ganediwalla,S. (2012),《数字化影响最大化》,《全球信息技术报告,第 121-133 页。

Topp (2016) 数据作为创意素材。可从:http://datalab.topp.se/news/2016/6/17/data-as-ideation-tool(访问时间:2018 年 10 月 5 日)。

Treseler,M (2015) 作为数据科学家的设计师。可从:http://radar . oreilly . com/2015/05/designers-as-data-scientists . html(访问时间:2018 年 10 月 15 日)。

瓦特,G. (2017),‘汉斯·罗斯林’,柳叶刀,389 (10070),第 694 页。
张,b .,克雷茨,g .,伊萨克森,m .,尤比洛斯,j .,乌尔达内塔,g .,Pouwelse,j .和埃佩马,D. (2013),《理解 spotify 中的用户行为》,IEEE 会议录,第 220-224 页。

用于深度学习的数据增强

原文:https://towardsdatascience.com/data-augmentation-for-deep-learning-4fe21d1a4eb9?source=collection_archive---------4-----------------------

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Photo by rawpixel.com from Pexels

流行的增强包和 PyTorch 示例概述

拥有大型数据集对于深度学习模型的性能至关重要。然而,我们可以通过增加我们已经拥有的数据来提高模型的性能。深度学习框架通常有内置的数据增强工具,但这些工具可能效率低下或缺乏一些必要的功能。

在这篇文章中,我将概述最流行的图像增强包,专门为机器学习设计的,并演示如何使用这些包与 PyTorch 框架。

对于每一个图像增强包,我都介绍了用二进制遮罩和边界框转换图像、流水线转换以及用 PyTorch 进行转换。我正在使用下面的演示图像:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Demo image

这篇文章的完整代码在这个 Jupyter 笔记本中提供。

imgaug 包

imgaug 是一个强大的图像增强包。它包含:

  • 60 多种图像增强器和增强技术(仿射变换、透视变换、对比度变化、高斯噪声、区域缺失、色调/饱和度变化、裁剪/填充、模糊);
  • 使用分段遮罩、边界框、关键点和热图增强图像的功能。该功能使得将包应用于包含图像的数据集以解决分割和对象检测问题变得非常容易;
  • 复杂的增强管道;
  • 许多增强可视化、转换等辅助功能。

此处提供了 imgaug 包的完整文档

简单的扩充

imgaug 包扩充图像就像这样简单:

Augment an image with imgaug

以下是使用 imgaug 软件包增强的几个图像示例:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Demonstration of sample augmentations: rotation, gaussian noise, crop, hue and saturation adjustment, elastic transform, coarse dropout

Imgaug 帮助处理带有分割遮罩的图像。为了训练深度学习模型,我们必须以相同的方式增强图像和掩模。下面是一个使用二进制分割蒙版变换图像的示例:

Augment an image with mask

以下代码有助于可视化增强图像和增强遮罩:

Visualize the augmented image and mask with imgaug helpers

下图是使用二进制分段遮罩的增强图像示例:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

The result of augmentation of an image with a mask

Imgaug 包在对带有边界框的图像应用变换时也很有帮助。用边界框增加图像的示例代码:

Transformation of an image with a bounding box

以下代码示例可用于可视化结果:

Visualize the augmented image and bounding box with imgaug helpers

下图展示了增强图像和边界框与原始图像相比的外观:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

The result of augmentation of an image with a bounding box

示例中的增强边界框看起来不错,但在某些情况下,增强边界框对旋转的图像不起作用。这里有一个例子:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

The example of augmented bounding box for rotated image

流水线扩充

使用 imgaug 包,我们可以构建一个复杂的图像增强管道。来自管道的增强按顺序应用于每个图像,但是我们可以设置:

  1. 将增强应用于图像的概率。例如,我们可以用它来对 50%的图像进行水平翻转。
  2. 仅对图像应用增强器的子集。例如,应用列表中的 0 到 5 个增强剂。该功能有助于加速数据生成。
  3. 以随机顺序应用增强。

让我们看一个复杂增强管道的例子:

Augmentation pipeline example

以下图像取自上述定义的管道:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Examples of images sampled from the augmentation pipeline

使用 imgaug 和 PyTorch

以下代码示例演示了如何在 PyTorch 数据集中使用 imgaug 增强来生成新的增强图像:

Example of using imgaug with PyTorch

白蛋白包装

albuminations包是基于 numpy、OpenCV、imgaug 编写的。这是一个非常受欢迎的软件包,由 Kaggle masters 编写,在 Kaggle 比赛中广泛使用。而且,这个包效率很高。你可以在这里找到基准测试结果,在这里找到这个包的完整文档

白蛋白包装能够:

  • 超过 60 种像素级和空间级转换;
  • 用遮罩、边界框和关键点变换图像;
  • 将增强组织到管道中;
  • PyTorch 集成。

简单的扩充

来自白蛋白包的增强应用于图像,如下所示:

Augment an image with Albumentations

来自白蛋白包的增强器产生的图像的几个例子:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Demonstration of sample augmentations: gaussian noise, elastic transform, random brightness and contrast, random gamma, CLAHE, blur

albuminations包也可以应用于带有遮罩的图像。这里有一个例子:

Augment an image with mask using Albumentations

下图显示了使用二元分割蒙版的增强图像:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

The result of augmentation of an image with a mask

albuminations包还提供了用边界框转换图像的功能。这里有一个简单的例子:

Transformation of an image with a bounding box

下面的代码示例演示了如何可视化结果:

Visualize the augmented image and bounding box

这是一个带有边界框的增强图像示例:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

The result of augmentation of an image with a bounding box

流水线扩充

Albumentations 包从 numpy、OpenCV 和 imgaug 中提取精华。这就是为什么albuminations包中的流水线与 imgaug 中的流水线相似。下面是一个受Kaggle 内核启发的管道示例:

Augmentation pipeline example

以下图像取自上述定义的管道:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Examples of images sampled from the augmentation pipeline

PyTorch 集成

当使用 PyTorch 时,你可以毫不费力地从 torchvision 迁移到albuminations,因为这个包提供了专门的实用程序供 PyTorch 使用。迁移到albuminations有助于加快数据生成部分,更快地训练深度学习模型。点击查看从 torchvision 迁移到albumations的详细教程。

PyTorch 集成示例:

PyTorch integration

推力增强装置

增强器 包包含的可能增强比本文之前描述的包更少,但它有其突出的特性,如尺寸保持旋转尺寸保持剪切裁剪,更适合机器学习。

增强器包还允许组成增强管道,并与 PyTorch 一起使用。你可以在这里找到增强器的完整文档。

简单的扩充

下面的例子结合了一个简单的增强器流水线应用于一个带有遮罩的图像:

Augment an image with Augmenter

这些图像是在上述代码的帮助下生成的:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

The result of augmentation of an image with a mask

使用 PyTorch 增强器

有一些已知的问题增强器和 PyTorch 有关,但是我们仍然可以一起使用这些库。

这里有一个例子:

Example of using Augmentor package with PyTorch

结论

在本文中,我介绍了专门为机器学习设计的最流行的图像增强包的功能。本文中提供的各种代码示例有助于开始在机器学习项目中使用这些包进行分类、分段和对象检测任务。

用于语音识别的数据扩充

原文:https://towardsdatascience.com/data-augmentation-for-speech-recognition-e7c607482e78?source=collection_archive---------7-----------------------

自动语音识别(ASR)

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Photo by Edward Ma on Unsplash

这个故事发表在 Dev.to 和 Medium 上。

语音识别的目的是将音频转换成文本。这项技术广泛应用于我们的生活中。谷歌助手亚马逊 Alexa 就是将我们的声音作为输入并转换成文本以理解我们意图的一些例子。

与其他自然语言处理问题一样,关键挑战之一是缺乏足够数量的训练数据。它导致过多或难以处理看不见的数据。谷歌大脑(Google Brain)和人工智能(AI)团队通过引入几种用于语音识别的数据增强方法来解决这个问题。本故事将讨论 SpecAugment:一种用于自动语音识别的简单数据增强方法 (Park 等人,2019 年),并将涵盖以下内容:

  • 数据
  • 体系结构
  • 实验

数据

为了处理数据,波形音频转换成声谱图,并馈入神经网络产生输出。执行数据扩充的传统方式通常应用于波形。Park 等人采用了另一种方法,即操纵声谱图。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Waveform audio to spectrogram (Google Brain)

给定一个声谱图,你可以把它看作一幅图像,其中 x 轴是时间,而 y 轴是频率。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Spectrogram representation (librosa)

直观地说,它提高了训练速度,因为没有波形数据到频谱图数据之间的数据转换,而是增加了频谱图数据。

Park 等人推出了用于语音识别中数据增强的SpecAugment。有三种基本方法来扩充数据,即时间弯曲、频率屏蔽和时间屏蔽。在他们的实验中,他们将这些方法结合在一起,并引入了 4 种不同的组合,即 LibriSpeech basic (LB)、LibriSpeech double (LD)、Switchboard mild (SM)和 Switchboard strong (SS)。

时间扭曲

将选择一个随机点,并向左或向右弯曲一段距离 W,该距离从 0 到沿该线的时间弯曲参数 W 的均匀分布中选择。

频率掩蔽

a 频道[f0,F0+f]被屏蔽。F 选自 0 至频率掩模参数 F 的均匀分布,f0 选自(0,νF ),其中ν为频率通道数。

时间掩蔽

t 个连续的时间步长[t0,t0+t]被屏蔽。T 选自 0 至时间屏蔽参数 T 的均匀分布,t0 选自[0,τT]。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

From top to bottom, the figures depict the log mel spectrogram of the base input with no augmentation, time warp, frequency masking and time masking applied. (Park et al., 2019)

基本增强政策的组合

通过结合频率屏蔽和时间屏蔽的增强策略,引入了 4 种新的增强策略。而符号表示:

  • w:时间弯曲参数
  • f:频率屏蔽参数
  • mF:应用的频率屏蔽数量
  • t:时间屏蔽参数
  • mT:应用时间屏蔽的次数

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Configuration for LB, LD, SM and SS (Park et al., 2019)

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

From top to bottom, the figures depict the log mel spectrogram of the base input with policies None, LB and LD applied. (Park et al., 2019)

体系结构

听、听、拼(LAS)网络架构

Park 等人使用 LAS 网络架构来验证使用和不使用数据增强的性能。它包括两层卷积神经网络(CNN),注意力和堆叠双向 LSTMs。由于本白皮书的目标是数据扩充,并且利用模型来查看模型的影响,因此您可以从这里深入研究 LAS。

学习费率表

学习率时间表成为决定模型性能的关键因素。类似于倾斜三角形学习率(STLR) ,应用非静态学习率。学习速率将呈指数衰减,直到它达到其最大值的 1/100,并在该点之后保持恒定。一些参数表示为:

  • sr:加速步骤(从零学习率开始)完成
  • si:指数衰减的步骤开始
  • sf:指数衰减的步骤停止。

另一种学习速率调度是统一标签平滑。正确的类别标签被赋予置信度 0.9,而其他标签的置信度相应地增加。参数表示为:

  • 噪声:变权噪声

在后面的实验中,定义了三个标准的学习速率表:

  1. B(asic): (sr,snoise,si,sf ) = (0.5k,10k,20k,80k)
  2. d(double):(Sr,snoise,si,sf ) = (1k,20k,40k,160k)
  3. L(ong): (sr,snoise,si,sf ) = (1k,20k,140k,320k)

语言模型

LM 用于进一步提高模型性能。一般来说,LM 被设计成在给定前一个记号的结果的情况下预测下一个记号。一旦预测到新标记,在预测下一个标记时,它将被视为“前一个标记”。这种方法在很多现代的 NLP 模型中都有应用,比如伯特GPT-2

实验

模型性能通过单词错误率 (WER)来衡量。

从下图中,“Sch”表示学习率计划,而“Pol”表示扩充政策。我们可以看到,具有 6 个 LSTM 层和 1280°嵌入向量的 LAS 表现出最好的结果。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Evaluation of LibriSpeech (Park et al., 2019)

通过将 LAS-6–1280 与 SpecAugment 一起使用,与其他模型和没有数据扩充的 LAS 相比,可获得最佳结果。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Comparing SpecAugment method in LibriSpeech 960h (Park et al., 2019)

在配电盘 300h 中,LAS-4–1024 被用作基准。我们可以看到 SpecAugment 确实有助于进一步提高模型性能。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Comparing SpecAugment method in Switchboard 300h (Park et al., 2019)

拿走

  • 时间扭曲并没有显著提高模型性能。如果资源有限,这种方法将被放弃。
  • 标签平滑导致训练不稳定。
  • 数据扩充将过拟合问题转化为欠拟合问题。从下图中,您可以注意到,没有增强(无)的模型在训练集中表现接近完美,而在其他数据集中没有类似的结果。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

  • 为了便于语音识别的数据扩充, nlpaug 现在支持 SpecAugment 方法。

关于我

我是湾区的数据科学家。专注于数据科学、人工智能,尤其是 NLP 和平台相关领域的最新发展。欢迎在 LinkedIn 上与 me 联系,或者在 MediumGithub 上关注我。

延伸阅读

参考

自然语言处理中的数据扩充

原文:https://towardsdatascience.com/data-augmentation-in-nlp-2801a34dfc28?source=collection_archive---------2-----------------------

文本增强简介

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Photo by Edward Ma on Unsplash

我们拥有的数据越多,我们能够实现的性能就越好。然而,注释大量的训练数据是非常奢侈的。因此,适当的数据扩充有助于提高模型性能。增强在计算机视觉领域非常流行。通过图像增强库,如 imgaug ,可以通过翻转、添加盐等方式轻松增强图像。事实证明,增强是计算机视觉模型成功的支柱之一。

在自然语言处理领域,由于语言的高度复杂性,很难对文本进行扩充。不是每一个词我们都可以用其他词代替,比如 a,an,the。另外,不是每个单词都有同义词。哪怕换一个词,语境也会完全不同。另一方面,在计算机视觉领域生成增强图像相对更容易。即使引入噪声或裁剪掉图像的一部分,该模型仍然可以对图像进行分类。

鉴于我们没有无限的资源来通过人类建立训练数据,作者尝试了不同的方法来实现相同的目标,即生成更多的数据用于模型训练。在这个故事中,我们探索了不同的作者如何通过生成更多的文本数据来增强模型,从而利用增强来刺激 NLP 任务。以下故事将涵盖:

  • 宝库
  • 单词嵌入
  • 回译
  • 语境化的单词嵌入
  • 文本生成

宝库

张等人介绍了用于文本分类的同义词字符级卷积网络。在实验过程中,他们发现一种有效的文本扩充方法是用同义词替换单词或短语。利用现有的词库有助于在短时间内生成大量数据。张等选取一个词,按几何分布用同义词替换。

单词嵌入

王和杨介绍的字相似的算计在真是让人讨厌!!!:基于词汇和框架语义嵌入的数据增强方法,使用#petpeeve Tweets 对恼人的行为进行自动分类。在论文中,王和杨提出利用 k 近邻法和余弦相似度来寻找相似词进行替换。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Imp.: relative improvement to the baseline without data augmentation (Wang and Yang, 2015)

或者,我们可以利用预先训练好的经典单词嵌入,比如 word2vec、GloVe 和 fasttext 来执行相似性搜索。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Most similar words of “fox” among classical word embeddings models

回译

英语是具有大量翻译训练数据的语言之一,而一些语言可能没有足够的数据来训练机器翻译模型。Sennrich 等人使用反向翻译方法来生成更多的训练数据,以提高翻译模型的性能。

假设我们要训练一个翻译英语(源语言)→粤语(目标语言)的模型,而粤语没有足够的训练数据。回译是将目标语言翻译成源语言,并混合源语句和回译语句来训练模型。因此可以增加从源语言到目标语言的训练数据的数量。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Performance result with and without text augmentation (Sennrich et al., 2016)

语境化的单词嵌入

Fadaee 等人没有使用静态单词嵌入,而是使用上下文化的单词嵌入来替换目标单词。他们使用这种文本增强来验证用于低资源神经机器翻译的数据增强中的机器翻译模型。

提出的方法是 TDA,代表翻译数据增强。实验表明,通过利用文本增强,机器翻译模型得到了改进。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Performance result with and without text augmentation (Fadaee et al., 2017)

Kobayashi 提出在语境扩充中使用双向语言模型:通过具有聚合关系的单词进行数据扩充。在选择目标单词后,模型将通过给出周围的单词来预测可能的替换。由于目标存在于句子的任何位置,双向结构被用来学习左右语境。

Kobayashi 用 CNN 和 RNN 在六个数据集上验证了语言模型方法,结果是肯定的。文本增强有助于进一步改进 NLP 模型结果。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Performance result with and without text augmentation (Kobayashi 2018)

文本生成

Kafle 等人介绍了一种不同的方法,通过在视觉问题回答的数据增强中生成增强数据来生成增强数据。与以前的方法不同,Kafle 等人的方法不是替换单个或几个单词,而是生成整个句子。

第一种方法是使用模板扩充,即使用预定义的问题,这些问题可以使用基于规则的方法来生成与模板问题配对的答案。第二种方法利用 LSTM 通过提供图像特征来生成问题。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Performance result with and without text augmentation (Kafle et al. 2017)

建议

上述方法旨在解决作者在他们的问题中所面临的问题。如果你了解你的数据,你应该量身定制增强方法。请记住,数据科学的黄金法则是垃圾进垃圾出。

一般来说,你可以在不完全理解你的数据的情况下尝试同义词库方法。由于上述同义词库方法的限制,它可能不会提高很多。

关于我

我是湾区的数据科学家。专注于数据科学、人工智能,尤其是 NLP 和平台相关领域的最新发展。欢迎在 LinkedIn 上与 me 联系,或者在 MediumGithub 上关注我。

延伸阅读

参考

文本数据扩充库

原文:https://towardsdatascience.com/data-augmentation-library-for-text-9661736b13ff?source=collection_archive---------8-----------------------

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Photo by Edward Ma on Unsplash

在前面的故事中,您了解了为 NLP 任务模型生成更多训练数据的不同方法。在这个故事中,我们将学习如何只用几行代码就能做到这一点。

在自然语言处理领域,由于语言的高度复杂性,对文本进行扩充是非常困难的。不是每一个词我们都可以用其他词来代替,比如 a,an,the。另外,不是每个单词都有同义词。即使改变一个单词,上下文也会完全不同。另一方面,在计算机视觉领域生成增强图像相对容易。即使引入噪声或裁剪掉图像的一部分,模型仍然可以对图像进行分类。

nlpaug 简介

在计算机视觉项目中使用 imgaug 后,我在想我们是否可以有一个类似的库来生成合成数据。因此,我通过使用现有的库和预先训练的模型来重新实现那些研究论文。nlpaug 的基本要素包括:

  • OCR 增强器、QWERTY 增强器和随机字符增强器
  • Word : WordNet 增强器、word2vec 增强器、GloVe 增强器、fasttext 增强器、BERT 增强器、随机单词字符
  • Flow:序列增强器,有时是增强器

直观来看,Character AugmentersWord Augmenters分别专注于字符级和单词级的操控。Flow像管弦乐队一样控制增强流。您可以访问 github 获取库。

性格;角色;字母

在字符级别扩充数据。可能的场景包括图像到文本和聊天机器人。在从图像中识别文本的过程中,我们需要光学字符识别(OCR)模型来实现,但是 OCR 会引入一些错误,如识别“0”和“0”。在聊天机器人中,我们仍然会有打字错误,尽管大多数应用程序都有单词纠正功能。为了克服这个问题,你可以让你的模型在在线预测之前“看到”那些可能的结果。

光学字符识别

当处理 NLP 问题时,OCR 结果可能是您的 NLP 问题的输入之一。例如,“0”可能被识别为“O”或“O”。如果你正在使用单词袋或经典单词嵌入作为一个特征,你将会遇到麻烦,因为你周围的词汇(OOV)现在和将来都是如此。如果你使用最先进的模型,比如伯特和 GPT的话,OOV 问题似乎就解决了,因为 word 将被拆分成子 word。然而,一些信息丢失了。

OCRAug旨在模拟 OCR 错误。它会用预定义的映射表替换目标字符。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

增强的例子

Original:
The quick brown fox jumps over the lazy dog
Augmented Text:
The quick brown fox jumps over the lazy **d0g**

QWERTY 键盘

你可能参与的另一个项目是聊天机器人或其他信息渠道,如电子邮件。虽然拼写检查将被执行,但一些拼写错误仍然存在。可能会伤害到你之前提到的 NLP 模型。

QWERTYAug旨在模拟关键字距离误差。它会将目标字符替换为 1 个关键字距离。您可以配置是否包括数字或特殊字符。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

增强的例子

Original:
The quick brown fox jumps over the lazy dog
Augmented Text:
**Tne 2uick hrown Gox jumpQ ovdr tNe <azy d8g**

随机字符

根据不同的研究,噪声注入有时可能有助于推广您的 NLP 模型。我们可能会在您的单词中添加一些干扰,例如从您的单词中添加或删除一个字符。

RandomCharAug旨在给你的数据注入噪音。与OCRAugQWERTYAug不同,它支持插入、替换和插入。

插入增强的例子

Original:
The quick brown fox jumps over the lazy dog
Augmented Text:
**T(he quicdk browTn Ffox jumpvs 7over kthe clazy 9dog**

单词

除了字符增强,单词水平也很重要。我们利用 word2vec (Mikolov 等人,2013)、GloVe (Pennington 等人,2014)、fasttext (Joulin 等人,2016)、BERT(Devlin 等人,2018)和 wordnet 来插入和替换相似的单词。Word2vecAugGloVeAugFasttextAug使用单词嵌入来寻找最相似的一组单词来替换原来的单词。另一方面,BertAug利用语言模型预测可能的目标词。WordNetAug用统计的方式找到一组相似的单词。

单词嵌入(word2vec、GloVe、fasttext)

经典的嵌入使用静态向量来表示单词。理想情况下,如果向量彼此靠近,这个词的意思是相似的。其实要看训练数据。比如 word2vec 中的“兔子”类似于“狐狸”,而 GloVe 中的“nbc”类似于“狐狸”。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Most similar words of “fox” among classical word embeddings models

有时,您希望用相似的单词替换单词,以便 NLP 模型不依赖于单个单词。Word2vecAugGloVeAugFasttextAug被设计成基于预先训练的向量来提供“相似”的单词。

除了替换之外,插入还有助于在数据中加入噪声。它从词汇中随机挑选单词。

插入增强的例子

Original:
The quick brown fox jumps over the lazy dog
Augmented Text:
The quick **Bergen-Belsen** brown fox jumps over **Tiko** the lazy dog

替代增强示例

Original:
The quick brown fox jumps over the lazy dog
Augmented Text:
The quick **gray** fox jumps over to lazy dog

语境化的单词嵌入

因为经典的单词嵌入使用静态向量来表示同一个单词。它可能不适合某些场景。因为“福克斯”可以代表动物和广播公司。为了解决这个问题,引入了上下文化单词嵌入来考虑周围的单词,以生成不同上下文下的向量。

BertAug旨在提供此功能来执行插入和替换。与以前的单词嵌入不同,插入是由 BERT 语言模型预测的,而不是随机选取一个单词。替换使用周围的单词作为特征来预测目标单词。

插入增强的例子

Original:
The quick brown fox jumps over the lazy dog
Augmented Text:
the **lazy** quick brown fox **always** jumps over the lazy dog

替代增强示例

Original:
The quick brown fox jumps over the lazy dog
Augmented Text:
the quick **thinking** fox jumps over the lazy dog

同义词

除了神经网络方法之外,同义词库也可以达到类似的目的。同义词的局限性在于有些词可能没有相似的词。来自一个很棒的 NLTK 库的 WordNet 帮助找到同义词。

WordNetAug提供了替换功能来替换目标单词。不是纯粹地寻找同义词,一些初步的检查确保目标单词可以被替换。这些规则是:

  • 不要选择限定词(例如,a、an、the)
  • 不要选择没有同义词的词。

增强的例子

Original:
The quick brown fox jumps over the lazy dog
Augmented Text:
The quick brown fox parachute over the lazy blackguard

随机词

到目前为止,我们没有在单词级引入删除。RandomWordAug可以帮助随机删除一个单词。

增强的例子

Original:
The quick brown fox jumps over the lazy dog
Augmented Text:
The fox jumps over the lazy dog

流动

到此为止,上述增强器都可以单独调用。如果你想把多个增强器组合在一起呢?为了使用多个增强器,有时会引入管道来连接增强器。一个文本可以通过不同的增强器产生不同的数据。

时序

您可以向该流程添加任意数量的增强器,然后Sequential逐个执行它们。例如,你可以将RandomCharAugRandomWordAug组合在一起。

有时

如果您不想一直执行同一组增强器,sometimes每次都会选择一些增强器。

建议

上述方法旨在解决作者在他们的问题中所面临的问题。如果你了解你的数据,你应该量身定做增强方法。请记住,数据科学的黄金法则是垃圾进垃圾出。

一般来说,您可以在不完全理解数据的情况下尝试同义词库方法。由于上述同义词库方法的限制,它可能不会提高很多。

关于我

我是湾区的数据科学家。专注于数据科学、人工智能,尤其是 NLP 和平台相关领域的最新发展。欢迎在 LinkedIn 上与 me 联系,或者在 MediumGithub 上关注我。

延伸阅读

参考

python 中的数据扩充技术

原文:https://towardsdatascience.com/data-augmentation-techniques-in-python-f216ef5eed69?source=collection_archive---------1-----------------------

使用 imgaug 一瞥 Python 中的数据扩充技术

在本文中,我们将使用 imgaug 库探索 Python 中不同的数据扩充技术

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

什么是图像增强?

图像增强是一种非常强大的技术,用于在现有图像中人工创建变化,以扩展现有图像数据集。这从代表可能图像的综合集合的现有图像数据集中创建新的和不同的图像。

这是通过应用不同的变换技术来实现的,如缩放现有图像、将现有图像旋转几度、剪切或裁剪现有图像集等。

为什么我们需要图像增强?

深度学习卷积神经网络(CNN)需要大量的图像来有效地训练模型。这有助于通过更好地概括来提高模型的性能,从而减少过度拟合。大多数用于分类和对象检测数据集的流行数据集具有几千到几百万个图像。

泛化指的是在训练过程中根据以前见过的数据,对照以前从未见过的测试或验证数据来评估模型的性能。

**CNN 由于其方差属性,即使在不同大小、方向或不同照明下可见,也可以对对象进行分类。**因此,我们可以利用图像的小数据集,通过放大或缩小、垂直或水平翻转或改变亮度(只要对对象有意义),将对象转换为不同的大小。这样我们就创建了一个丰富多样的数据集。

图像增强从一小组图像中创建一组丰富多样的图像,用于图像分类、对象检测或图像分割。

在仔细理解问题域之后,需要应用增加训练数据集大小的增强策略。

如果我们正在对不同类型的汽车进行分类,那么通过垂直翻转汽车来应用图像增强对于问题域是没有用的,或者当我们正在对手写数字进行图像分类时,垂直翻转数字 6 不会增加价值

什么时候应用图像增强?

图像增强可以在我们训练模型之前作为预处理步骤来应用,或者可以实时应用。

离线或预处理增强

扩充作为预处理步骤被应用以增加数据集的大小。当我们想要扩展一个小的训练数据集时,通常会这样做。

在较小的数据集上生成增强是有帮助的,但是在应用于较大的数据集时,我们需要考虑磁盘空间

在线或实时增强

顾名思义,增强是实时应用的。这通常适用于较大的数据集,因为我们不需要将增强的图像保存在磁盘上。

在这种情况下,我们以小批量的方式应用转换,然后将其提供给模型。

在线增强模型将在每个时期看到不同的图像。在离线增强中,增强图像是训练集的一部分,它根据历元数多次查看增强图像。

该模型通过在线增强进行更好的概括,因为它在使用在线数据增强进行训练的过程中看到了更多的样本。

我们将使用 imgaug 类来演示图像增强。

imgaug 支持多种数据增强技术

基本数据扩充技术

  • 翻转:垂直或水平翻转图像
  • 旋转:将图像旋转指定的角度。
  • 剪切:像平行四边形一样移动图像的一部分
  • 裁剪:对象以不同的比例出现在图像的不同位置
  • 放大,缩小
  • 改变亮度或对比度

我们现在将使用 imgaug 库来探索这些数据扩充技术

伊姆高格

imgaug 是一个用于图像增强以及关键点/界标、边界框、热图和分割图的库。

安装库

pip install imgaug

在某些情况下,我们得到一个 Shapely 错误,在这种情况下,我们可以尝试以下命令

pip install imgaug — upgrade — no-deps

我们将拍摄一张图像,并使用基本的数据增强技术对其进行转换。

导入所需的库

import imageio
import imgaug as ia
import imgaug.augmenters as iaa
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import matplotlib.patches as patches
import matplotlib
%matplotlib inline

显示原始图像

我们使用 imageio 显示原始图像

image = imageio.imread(“.\\car2.jpeg”)
ia.imshow(image)

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Original Image

旋转图像

我们可以通过指定旋转度数来旋转图像。我们将图像旋转-50 度到 30 度

**rotate=iaa.Affine(rotate=(-50, 30))
rotated_image=rotate.augment_image(image)**
ia.imshow(rotated_image)

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Image rotated by -50 to 30 degrees

向图像添加噪声

我们将从高斯分布采样的不同噪声值按元素添加到图像中。

**gaussian_noise=iaa.AdditiveGaussianNoise(10,20)**
**noise_image=gaussian_noise.augment_image(image)**
ia.imshow(noise_image)

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Adding Gaussian noise

裁剪图像

裁剪会移除图像两侧的像素列/行。在下面的例子中,我们将图像的一边裁剪 30%

**crop = iaa.Crop(percent=(0, 0.3)) # crop image
corp_image=crop.augment_image(image)**
ia.imshow(corp_image)

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

cropped one side of the image by 30%

剪切图像

将图像剪切 0 到 40 度

shear = iaa.Affine(shear=(0,40))
shear_image=shear.augment_image(image)
ia.imshow(shear_image)

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Sheared image by 0 to 45 degrees

翻转图像

我们可以垂直或水平翻转图像。 Fliplr 水平翻转图像

#flipping image horizontally
flip_hr=iaa.Fliplr(p=1.0)
flip_hr_image= flip_hr.augment_image(image)
ia.imshow(flip_hr_image)

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Flipping image horizontally

翻转垂直翻转图像

flip_vr=iaa.Flipud(p=1.0)
flip_vr_image= flip_vr.augment_image(image)
ia.imshow(flip_vr_image)

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Flipping image vertically

改变图像的亮度

我们使用 GammaContrast 通过缩放像素值来调整图像亮度。范围gamma=(0.5, 2.0)内的值似乎是合理的。我们可以使用s 形对比度线性对比度来改变图像的亮度

image = imageio.imread(“.\\img Aug\\car2.jpeg”)
contrast=iaa.GammaContrast(gamma=2.0)
contrast_image =contrast.augment_image(image)
ia.imshow(contrast_image) 

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

adding contrast to the image

缩放图像

我们可以使用缩放来放大或缩小图像。我们将下面的图像缩放到图像高度/宽度的 150%到 80%。我们可以独立缩放每个轴

image = imageio.imread("C:\\Data\\img Aug\\car2.jpeg")
scale_im=iaa.Affine(scale={"x": (1.5, 1.0), "y": (1.5, 1.0)})
scale_image =scale_im.augment_image(image)
ia.imshow(scale_image)

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

scaling image 150% to 80% of its height/width.

用于目标检测的增强

我们绘制物体检测的包围盒。当我们放大图像时,我们希望边界框也相应地更新。

imgaug 提供了对边界框的支持。当我们旋转、剪切或裁剪图像时,对象周围的边界框也会相应地更新。

从 imgaug 导入边界框

from imgaug.augmentables.bbs import BoundingBox, BoundingBoxesOnImage

初始化原图像周围的包围盒

bbs = BoundingBoxesOnImage([
 BoundingBox(x1=10, x2=520, y1=10, y2=300)
], shape=image.shape)

在原始图像的顶部显示边界框

ia.imshow(bbs.draw_on_image(image, size=2))

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

在下面的代码中,我们使用 translate_percentage 移动图像,增大边界框并将其应用到图像上

move=iaa.Affine(translate_percent={"x": 0.1}, scale=0.8)
image_aug, bbs_aug = move(image=image, bounding_boxes=bbs)
ia.imshow(bbs_aug.draw_on_image(image_aug, size=2))

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

bounding box on the augmented image

在应用图像增强后处理图像外部的边界框

边界框有时可能会超出图像,我们需要额外的代码来处理这种情况

我们旋转图像,并尝试在对象周围绘制边界框

rotate_bb=iaa.Affine(rotate=(-50, 30))
image_aug, bbs_aug = rotate_bb(image=image, bounding_boxes=bbs)
ia.imshow(bbs_aug.draw_on_image(image_aug, size=2))

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

部分边界框位于图像之外。在下面的代码中,我们将

  • 将边框完全或部分移出图像
  • 裁剪部分在外的边界框,使它们完全在图像内

我们创建一个填充函数,用 1 个像素的白色和 1 个像素的黑色边框填充图像:

**def pad(image, by)**:
    image_border1 = ia.pad(image, top=1, right=1, bottom=1, left=1,
                           mode="constant", cval=255)
    image_border2 = ia.pad(image_border1, top=by-1, right=by-1,
                           bottom=by-1, left=by-1,
                           mode="constant", cval=0)
    return image_border2

然后,我们在图像上绘制边界框。我们首先通过边界像素扩展图像平面,然后标记图像平面内的边界框

def draw_bbs(image, bbs, border):
    GREEN = [0, 255, 0]
    ORANGE = [255, 140, 0]
    RED = [255, 0, 0]
    **image_border = pad(image, border)**
    for bb in bbs.bounding_boxes:
       ** if bb.is_fully_within_image(image.shape):**
            color = GREEN
        **elif bb.is_partly_within_image(image.shape):**
            color = ORANGE
        else:
            color = RED
        **image_border = bb.shift(left=border, top=border)\
                         .draw_on_image(image_border, size=2, color=color)**return image_border

我们现在对图像应用相同的旋转,并绘制边界框

rotate=iaa.Affine(rotate=(-50, 30))
image_aug, bbs_aug = rotate(image=image, bounding_boxes=bbs)image_after = draw_bbs(image_aug, bbs_aug.remove_out_of_image().clip_out_of_image(), 100)
ia.imshow(image_after)

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

在下一篇文章中,我们将探讨用于图像增强的 Keras imagedata generator

参考资料:

[## imgaug - imgaug 0.3.0 文档

imgaug 是一个用于机器学习实验中图像增强的库。它支持大范围的增强…

imgaug.readthedocs.io](https://imgaug.readthedocs.io/en/latest/index.html)

https://blog . keras . io/building-powerful-image-class ification-models-using-very-little-data . html

https://nano nets . com/blog/data-augmentation-how-to-use-deep-learning-when-you-have-limited-data-part-2/

https://github . com/lexie 88 RUS/augmentation-packages-overview/blob/master/data-augmentation-packages-overview . ipynb

https://link . springer . com/content/pdf/10.1186% 2fs 40537-019-0197-0 . pdf

使用 fastai 的数据增强

原文:https://towardsdatascience.com/data-augmentations-in-fastai-84979bbcefaa?source=collection_archive---------5-----------------------

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

介绍

数据扩充指的是对数据集中的图像随机应用各种变换。这些转换有助于在我们的数据集中引入更多种类。让我们看看这是什么意思。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

考虑一个构建面锁的例子。当你为锁取样时,你现在拍一些照片,你就完成了。然而,当用户想要解锁他的手机时,他并不总是处于相同的照明中(亮度)。或者,用户不会总是以相同的角度面对相机(翘曲)。可能他的照片因为某种原因(抖动)显得模糊。在训练数据时,我们需要考虑这些情况。这正是数据增强带给我们的。

我们从这样一幅图像开始

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

我们最终得到了一堆像这样的照片

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

我们所做的是,不是每次都给模型提供相同的图片,而是做一些小的随机变换(一点旋转、缩放、平移等),这些变换不会改变图像内部的内容(对于人眼而言),但会改变其像素值。用数据扩充训练的模型将更好地概括。在训练样本数量相对较少的情况下,数据扩充也很有用。

工作

全 jupyter 笔记本。

在这篇短文中,我们不会过多关注实现这些转换的代码。相反,我们将可视化各种可用的转换,以理解当我们执行数据扩充时在幕后发生了什么。

我们从查看 fastai 库中的缺省值开始。这些缺省值是以这样一种方式设置的,它们可以很好地用于大多数任务。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

然而,我们可以根据应用程序的性质改变其中的一些(例如do_flip)。

get transforms返回两个转换列表的元组:一个用于训练集,一个用于验证集。但是,我们不想修改验证集中的图片,所以第二个列表仅限于调整图片的大小。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

我们使用一个小助手功能来绘制网格。函数如下所示。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

**kwargs意味着我们可以传递任意数量的命名参数(并且我们事先不知道数量)。要传递的一些有用的参数可以是size,这样所有的图像都是相同的大小,以及padding,以决定如何处理图像中丢失的像素。

现在我们已经把所有的部分都准备好了,让我们来看看我们能做的一些很酷的转换。

随机缩放/裁剪

随机裁剪或缩放图像。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

辐状的

我们在转换中引入的随机性可以通过两种方式实现。

在第一种方法中,我们可以传递一个图像将被变换的概率。基于该概率,图像将被变换或不被变换。在下一个变换中,我们以 50%的概率将图像旋转 30 度。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

在第二种方式中,我们不是传递概率,而是传递一系列值(这里是度数)。然后图像将在两个浮动之间随机旋转一个角度。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

我们也可以把上面提到的 2 种方法结合起来!

聪明

这个转换需要一个名为change.的参数,设置change为 0 将把我们的图像转换成黑色,设置为 1 将把它变成白色

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

对比

与亮度类似,对比度可以使用scale参数进行设置。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

有两个平面的

该变换结合了翻转(水平或垂直)和 90 度倍数的旋转。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

翻转 _lr(镜像)

水平翻转图像。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

振动

这种变换通过用来自邻域的像素随机替换图像的像素来改变图像的像素,从而导致抖动。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

对称翘曲

更改查看图像的角度。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

这些是计算机视觉项目的一些最佳增强。您可以阅读 fastai 文档了解更多信息。

一个有趣的研究领域是其他领域的数据扩充,例如声音数据。

编辑:

混淆:超越经验风险最小化

Mixup 是一个巧妙的数据增强小技巧。在 mixup 中,我们不是提供网络原始图像,而是获取 2 幅图像,并对它们进行线性组合,如下所示:

new_image = t * image1 + (1-t) * image2

其中 t 是介于 0 和 1 之间的浮点数。那么我们分配给该图像的目标是原始目标的相同组合:

new_target = t * target1 + (1-t) * target2

看看下面的图片

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

狗还是猫?这里的正确答案是 70%狗,30%猫!

当执行 mixup 时,实验表明跨类(而不是同一个类)执行通常是个好主意。此外,mixup 一次应用于一个小批量,而不是整个数据集(同样工作良好)。

使用 mixup 的主要优点是它可以用几行代码实现,几乎没有任何计算开销。mixup 所做的是,它迫使你的神经网络偏向于你的类之间的简单线性行为。它使你的神经网络在对抗敌对样本时更加强健,并帮助它更好地调整。

在 fastai 中,使用 mixup 非常简单:

learner = Learner(data, model, metrics=[accuracy]).mixup()

在我目前看到的例子中,通常是和混合精度训练一起使用。阅读这篇研究论文了解更多信息。

这就是本文的全部内容。

如果你想了解更多关于深度学习的知识,可以看看我在这方面的系列文章:

[## 深度学习系列

我所有关于深度学习的文章的系统列表

medium.com](https://medium.com/@dipam44/deep-learning-series-30ad108fbe2b)

~快乐学习。

多伦多的数据职业市场洞察

原文:https://towardsdatascience.com/data-career-market-insights-in-toronto-indeed-ca-1e50cdb88458?source=collection_archive---------27-----------------------

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Figure 0. Indeed Job Search Results on Related Data Career

这是在多伦多寻找梦想职业的绝佳时机。多伦多正在成为大恐龙数码、微软、亚马逊等软件公司的热点(即人工智能中心)。他们希望招聘以下职位的人才,如数据科学家、数据工程师、数据分析师和商业智能角色。对于应届毕业生和转行者来说,最常见的问题是:我如何才能实现我梦想的职业?

在许多情况下,大多数人会去像 Indeed.ca 这样的求职网站,输入一些关键词(例如,职位、一些工具等)。)检索求职结果。然后,人们一个接一个地查看职位描述,尽可能多地提交申请。不对!

有几个原因让你不应该这样做:

1.浪费的努力和时间:你在浪费自己的时间,也在浪费招聘公司的时间,去过滤大量不相关的简历,这些简历可能甚至不适合他们正在看的东西。

2.你想最大化获得面试的机会:你想象过自己不带武器去打仗吗?同样,你必须至少具备招聘经理需要考虑的基本必备工具。

那么我们能做什么呢?不要担心,我们可以通过使用 Python 库(漂亮的汤)有策略地让事情变得简单一点。有了这个库,我们可以创建一个 web scraper 函数来从 Indeed.ca 检索您在多伦多的工作搜索结果。这将有助于我们战略性地提交工作申请,并在未来的工作提交中优先考虑您学习所需工具集的目标。

在我们开始之前,让我们先从 5 个关键问题开始了解一些想法:

1.哪些公司希望聘用这些人才(如数据科学家、数据工程师等)。)

2.这些不同角色的平均工资是多少?

3.这些不同角色所需的前 5 项必备技能是什么?

4.这些不同的角色要求或推荐的教育水平是什么?

5.这些不同角色的首选教育背景(研究领域)是什么?

好了,这里是一个快速概述的数据角力管道,为真正的工作刮刀功能,我建立了回答这 5 个关键问题:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Figure 1. Indeed Scraper Data Pipeline

第一步。连接到职务搜索 URL 页面

第二步。标记化,解析单词,然后做一些文本清理。

第三步。创建主要功能,以收集职位页面描述(职位,地点,工资等)。)

第四步。遍历每个页面的 URL 和存储的信息。

第五步。创建字典来获取所需的技能、教育水平等。计算每个特定术语的频率,然后将结果可视化!

让我们深入探讨从结果中获得的 5 个重要见解。

A .数据科学家职位的招聘公司和平均薪酬列表:

首先,各行各业都有数据科学家的工作。大多数工作都在 金融或保险公司 像道明、丰业银行、阳光人寿金融等。其他职业也有类似的趋势。只不过,不同的公司在招聘人才。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Figure 2. List of Hiring Companies

其次,据报道,多伦多数据科学家的平均年薪为 91,000 美元。然而,这一薪资比 Indeed.ca 的平均薪资低了 5%。这是因为一些调查还包括了高级数据科学家的薪资。实际上,入门级数据科学家的平均年薪应该在 80 到 85K 之间。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Figure 3. Average Salaries of a Data Scientist in Toronto

B .数据科学家与数据工程师的比较:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Figure 4. Bar Charts Comparison between Data Scientist vs. Data Engineer

该图代表了每个职业要求最高的五项技能、DevOps 和云工具。以下是基于共性(相似性)和差异的两个职位之间的总结。

通用性:

在列出的前 5 项技能中,数据科学家和数据工程师都需要了解像 Python、Spark、Hadoop 和 SQL 这样的工具。其中 Python 和 SQL 是基本工具,而 Spark 和 Hadoop 对于拥有大数据存储的公司来说是必不可少的。

差异:

对于数据科学家角色,招聘公司更专注于查看 其他数据分析工具和数据可视化经验(即 SAS、Tableau 等。)。另一方面,数据工程师的角色主要集中在类似 云平台(AWS)和 DevOps (Jenkins,Kubernetes,Docker) 的工具上。

这种差异主要有两个原因。首先,数据工程师创建通向由数据科学家创建的生产 ML 模型的数据管道。他们需要具备 DevOps 工具经验。这有助于他们以最有效的方式在不同的修复和发布之间实现模型/代码部署生命周期的敏捷实践。其次,由于灵活性和成本效益,大多数初创公司或大公司都使用 AWS 等云平台,而不是内部解决方案(内部数据仓库)。不过,这在很大程度上取决于其他因素,如公司的业务/战略路线图、系统架构和环境。

C .数据科学家的教育要求和背景

关于教育水平,数据科学家是大多数招聘公司倾向于聘用具有博士学位的申请人的唯一职业(左图)。对于其他职业,如数据工程师、数据分析师和商业智能角色,学士学位教育足以胜任工作。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Figure 5. Education Levels of Data Scientist Job Posted on Indeed.ca

此外,许多求职者会想知道什么样的教育背景或研究领域对数据科学家来说是理想的?从分析来看,似乎大多数招聘公司都希望应聘者来自科学、技术、工程和数学等科学、技术、工程和数学领域。特别是对于数据科学家来说,很多公司希望应聘者有数学背景,其次是计算机科学、工程等等。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Figure 6. Educational Backgrounds Posted on Data Scientist Positions from Indeed.ca

那么,这为什么会成为数据科学家的一种趋势呢?

我通过自己的研究从出版的期刊、数据科学会议和与数据科学家导师的闲聊中收集了一些见解。让我们从一个问题开始,为什么大多数招聘公司都想要博士级别的候选人。

首先,随着人工智能(AI)趋势的复苏,有很多公司有兴趣建立自己的人工智能/深度学习(DL)研究和产品开发团队。他们想要拥有先进的人工智能和人工智能算法知识的人。不要只使用 R 和 Python 中已有的库和包。这些数据科学家必须能够从零开始调整和实现新的算法,以解决特定的业务问题并构建数据产品。

第二,数学似乎是许多公司希望雇佣的最著名的学科,其次是计算机科学和工程学位。这与数据科学家角色的性质密切相关。作为数据科学家,必须能够很好地理解不同领域的数学,如线性代数、微积分和统计。因为所有的 ML 算法都是关于理解如何将这些算法应用于数据集,并为解决特定的业务问题制定独特的解决方案。还有,数据科学家一定要做好编程。这就是为什么许多公司希望应聘者拥有计算机科学或工程学位的原因。大多数代码/模型开发都是在 Python/R 上完成的,作为一名数据科学家,在生产环境中编写高效且可扩展的代码对于完成工作来说至关重要。

感谢阅读这篇文章。我希望许多读者会对此感兴趣。我强烈鼓励其他行业的读者考虑学习 Python,并为您的行业市场洞察力构建一个 web scraper 函数

R 降价中缺失值的数据清理、检测和插补—第 2 部分

原文:https://towardsdatascience.com/data-cleaning-and-detecting-missing-values-from-australian-open-tennis-data-in-r-part-2-b4f6f32beffd?source=collection_archive---------12-----------------------

使用 2000 年至 2018 年男子巡回赛的澳大利亚网球公开赛数据在 R 中进行数据清洗和转换变量。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Photo by The Creative Exchange on Unsplash

今天是第 4 天,标志着我的# 29 Day 数据科学项目训练营和我在数据科学中学到的东西的继续。这是一个清洗和预处理 2000 年至 2019 年澳大利亚网球公开赛网球数据的教程指南,以使用 r 预测谁可能获胜。昨天,我们合并了多个 csv 文件,并子集化了您可能会关注的数据此处来自博客帖子。

什么是 CRISP-DM 方法论?

如果你在大会上一堂数据分析课,在你的大学上一门数据科学算法的数据科学课程,选修一门感兴趣的 IT 选修课,学习一门在线课程,或者你可能为你的教授做一个数据挖掘项目,你会遇到 CRISP-DM 的数据挖掘原理。

CRISP-DM 是数据挖掘的跨行业流程**。这也是我在悉尼大会上学到的一个规定的分析工作流程,当你在政府部门咨询时,这些原则会被用在数据科学项目中。**

这是 CRISP-DM 方法的工作流程,用于指导您解决数据分析和数据科学问题。您可以回顾 2018 年欧洲智能视觉展的每个步骤。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Source: Smart Vision 2018

商业理解

这不是一个商业问题,但问题陈述的范围是根据 2000 年至 2018 年的数据预测今年澳大利亚网球公开赛决赛的冠军。

数据理解

以前,我们获得了一个数据字典,并通过分析数据的整体结构来研究数据。

以下是变量的数据字典:

ATP = Tournament number (men)
WTA = Tournament number (women)
Location = Venue of tournament
Tournament = Name of tounament (including sponsor if relevant)
Data = Date of match (note: prior to 2003 the date shown for all matches played in a single tournament is the start date)
Series = Name of ATP tennis series (Grand Slam, Masters, International or International Gold)
Tier = Tier (tournament ranking) of WTA tennis series.
Court = Type of court (outdoors or indoors)
Surface = Type of surface (clay, hard, carpet or grass)
Round = Round of match
Best of = Maximum number of sets playable in match
Winner = Match winner
Loser = Match loser
WRank = ATP Entry ranking of the match winner as of the start of the tournament
LRank = ATP Entry ranking of the match loser as of the start of the tournament
WPts = ATP Entry points of the match winner as of the start of the tournament
LPts = ATP Entry points of the match loser as of the start of the tournament
W1 = Number of games won in 1st set by match winner
L1 = Number of games won in 1st set by match loser
W2 = Number of games won in 2nd set by match winner
L2 = Number of games won in 2nd set by match loser
W3 = Number of games won in 3rd set by match winner
L3 = Number of games won in 3rd set by match loser
W4 = Number of games won in 4th set by match winner
L4 = Number of games won in 4th set by match loser
W5 = Number of games won in 5th set by match winner
L5 = Number of games won in 5th set by match loser
Wsets = Number of sets won by match winner
Lsets = Number of sets won by match loser
Comment = Comment on the match (Completed, won through retirement of loser, or via Walkover)

数据准备—数据清理

通过分类变量的编码、转换变量和缺失值的检测,对数据进行了清理。我们已经合并了原始数据,并使用 StringAsfactors =FALSE 将“aus_open.csv”数据帧读入 R 中,以确保所有变量不会自动作为因子读取。

###################################
# Pre-Processing the Training Data
###################################

# Exported aust_open.csv file was exported and a new column was created in Excel to extract the year from the data with non-standardised formatting

a <- read.csv("aus_open.csv",stringsAsFactors = FALSE,header = TRUE)

探索性数据分析

使用 Hadley Wickham 的 dplyr 包,我使用函数 glimpse()探索了数据的结构。

#############################
# Exploratory Data Analysis
#############################

glimpse(a)  # view the structure of the training data

描述统计学

下面提供了描述性统计的输出,是所有数值变量和缺失值的汇总。

summary(a) # descriptive statistics
      ATP      Location          Tournament            Date          
 Min.   :6   Length:2413        Length:2413        Length:2413       
 1st Qu.:6   Class :character   Class :character   Class :character  
 Median :6   Mode  :character   Mode  :character   Mode  :character  
 Mean   :6                                                           
 3rd Qu.:6                                                           
 Max.   :6                                                           

      Year         Series             Court             Surface         
 Min.   :2000   Length:2413        Length:2413        Length:2413       
 1st Qu.:2004   Class :character   Class :character   Class :character  
 Median :2009   Mode  :character   Mode  :character   Mode  :character  
 Mean   :2009                                                           
 3rd Qu.:2014                                                           
 Max.   :2018                                                           

    Round              Best.of     Winner             Loser          
 Length:2413        Min.   :5   Length:2413        Length:2413       
 Class :character   1st Qu.:5   Class :character   Class :character  
 Mode  :character   Median :5   Mode  :character   Mode  :character  
                    Mean   :5                                        
                    3rd Qu.:5                                        
                    Max.   :5                                        

     WRank           LRank                 W1             L1           
 Min.   :  1.00   Length:2413        Min.   :    0   Length:2413       
 1st Qu.: 10.00   Class :character   1st Qu.:    7   Class :character  
 Median : 28.00   Mode  :character   Median :  860   Mode  :character  
 Mean   : 46.97                      Mean   : 1863                     
 3rd Qu.: 65.00                      3rd Qu.: 2145                     
 Max.   :768.00                      Max.   :16790                     
                                     NA's   :128                       
       W2              L2              W3              L3       
 Min.   :0.000   Min.   :0.000   Min.   :0.000   Min.   :0.000  
 1st Qu.:6.000   1st Qu.:3.000   1st Qu.:6.000   1st Qu.:2.000  
 Median :6.000   Median :4.000   Median :6.000   Median :4.000  
 Mean   :5.687   Mean   :4.027   Mean   :5.743   Mean   :3.903  
 3rd Qu.:6.000   3rd Qu.:6.000   3rd Qu.:6.000   3rd Qu.:6.000  
 Max.   :7.000   Max.   :7.000   Max.   :7.000   Max.   :7.000  
 NA's   :10      NA's   :10      NA's   :33      NA's   :33     
       W4              L4              W5               L5        
 Min.   :0.000   Min.   :0.000   Min.   : 0.000   Min.   : 0.000  
 1st Qu.:6.000   1st Qu.:2.000   1st Qu.: 6.000   1st Qu.: 2.000  
 Median :6.000   Median :4.000   Median : 6.000   Median : 4.000  
 Mean   :5.753   Mean   :3.734   Mean   : 5.883   Mean   : 3.813  
 3rd Qu.:6.000   3rd Qu.:6.000   3rd Qu.: 6.000   3rd Qu.: 6.000  
 Max.   :7.000   Max.   :7.000   Max.   :21.000   Max.   :19.000  
 NA's   :346     NA's   :346     NA's   :1440     NA's   :1440    
     Wsets            Lsets        Comment         
 Min.   : 0.000   Min.   : 0.0   Length:2413       
 1st Qu.: 3.000   1st Qu.: 0.0   Class :character  
 Median : 3.000   Median : 1.0   Mode  :character  
 Mean   : 4.192   Mean   : 1.7                     
 3rd Qu.: 6.000   3rd Qu.: 2.0                     
 Max.   :22.000   Max.   :20.0                     
 NA's   :1444     NA's   :1444

转换和编码分类变量

从上面的结构可以看出,一些数据属性没有转换成正确的数据类型。这是我最喜欢的部分转换变量的机会!开始了…

# Transform character variables into numeric variables a$W1 <- as.numeric(a$W1)
a$L1 <- as.numeric(a$L1)
a$WRank <- as.numeric(a$WRank)
a$LRank <- as.numeric(a$LRank)

##########################################################
# encoding categorical features
##########################################################

# Convert categorical variables into factors to represent their levels
a$Location <- factor(a$Location)
a$Tournament <- factor(a$Tournament)
a$Series <- factor(a$Series)
a$Court <- factor(a$Court)
a$Surface <- factor(a$Surface)
a$Best.of <- factor(a$Best.of)
a$Round <- factor(a$Round)
a$Winner <- factor(a$Winner)
a$Loser <- factor(a$Loser)
a$Comment <- factor(a$Comment)

glimpse(a)  # check that structure of categorical variables have converted with levels

#为两级以上的分类变量创建虚拟变量

library(dummies)

Round <- dummy(a$Round)
Best.of <- dummy(a$Best.of)
Winner <- dummy(a$Winner)
Loser <- dummy(a$Loser)
Comment <- dummy(a$Comment)

head(a)   # check that the values are been converted to dummy variables
str(a)

总结描述性统计数据,并检查转换变量的结构

# Descriptive statistics
summary(a)# View the structure of the transformed variables the 'dplyr' way

 > glimpse(a)Observations: 2,413
Variables: 27
$ ATP        <int> 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, ...
$ Location   <fct> Melbourne, Melbourne, Melbourne, Melbourne, Melbourne,...
$ Tournament <fct> Australian Open, Australian Open, Australian Open, Aus...
$ Date       <chr> "1/17/00", "1/17/00", "1/17/00", "1/17/00", "1/17/00",...
$ Year       <int> 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, ...
$ Series     <fct> Grand Slam, Grand Slam, Grand Slam, Grand Slam, Grand ...
$ Court      <fct> Outdoor, Outdoor, Outdoor, Outdoor, Outdoor, Outdoor, ...
$ Surface    <fct> Hard, Hard, Hard, Hard, Hard, Hard, Hard, Hard, Hard, ...
$ Round      <fct> 1st Round, 1st Round, 1st Round, 1st Round, 1st Round,...
$ Best.of    <fct> 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, ...
$ Winner     <fct> Agassi A., Alami K., Arazi H., Behrend T., Bjorkman J....
$ Loser      <fct> Puerta M., Manta L., Alonso J., Meligeni F., Stoltenbe...
$ WRank      <dbl> 1, 35, 41, 106, 76, 151, 39, 54, 30, 64, 98, 29, 34, 6...
$ LRank      <dbl> 112, 107, 111, 28, 81, 57, 22, 66, 51, 155, 119, 257, ...
$ W1         <dbl> 6, 6, 6, 6, 6, 7, 3, 7, 7, 7, 6, 6, 6, 6, 6, 7, 6, 6, ...
$ L1         <dbl> 2, 4, 3, 2, 7, 6, 6, 6, 6, 6, 4, 7, 7, 4, 3, 6, 4, 3, ...
$ W2         <int> 6, 7, 7, 4, 6, 6, 6, 6, 6, 5, 6, 7, 6, 6, 6, 6, 7, 6, ...
$ L2         <int> 2, 6, 6, 6, 4, 1, 1, 4, 4, 7, 4, 6, 3, 4, 3, 3, 6, 3, ...
$ W3         <int> 6, 7, 6, 6, 6, 6, 6, NA, 6, 6, 7, 1, 7, 7, 4, 7, 4, 6,...
$ L3         <int> 3, 5, 2, 7, 4, 4, 4, NA, 4, 3, 6, 6, 5, 6, 6, 6, 6, 2,...
$ W4         <int> NA, NA, NA, 6, 0, NA, 7, NA, NA, 7, NA, 6, 6, NA, 7, N...
$ L4         <int> NA, NA, NA, 3, 6, NA, 6, NA, NA, 5, NA, 3, 1, NA, 6, N...
$ W5         <int> NA, NA, NA, 6, 6, NA, NA, NA, NA, NA, NA, 6, NA, NA, N...
$ L5         <int> NA, NA, NA, 0, 4, NA, NA, NA, NA, NA, NA, 1, NA, NA, N...
$ Wsets      <int> 3, 3, 3, 3, 3, 3, 3, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, ...
$ Lsets      <int> 0, 0, 0, 2, 2, 0, 1, 0, 0, 1, 0, 2, 1, 0, 1, 0, 2, 0, ...
$ Comment    <fct> Completed, Completed, Completed, Completed, Completed,...

检测缺失值

我们将尝试一些方法来检测缺失值,例如计算每列缺失值的数量、求和并取平均值。

# Sum the number of missing values> sum(is.na(a)) 
[1] 6810# average of the missing values in each column> mean(is.na(a)) 
[1] 0.1045264# Count the number of missing values per column> colSums(is.na(a))        ATP   Location Tournament       Date       Year     Series      Court 
         0          0          0          0          0          0          0 
   Surface      Round    Best.of     Winner      Loser      WRank      LRank 
         0          0          0          0          0          0          5 
        W1         L1         W2         L2         W3         L3         W4 
       128        131         10         10         33         33        346 
        L4         W5         L5      Wsets      Lsets    Comment 
       346       1440       1440       1444       1444          0

获取缺失值的百分比

在检测缺失值时,5%是每列的可接受阈值。输出确认了 L4、W4、L5、W5、Wsets 和 Lsets 列的缺失值大于 5%,可以删除或估算。

sapply(a, function(df){
  sum(is.na(df) ==TRUE)/length(df);
 })
        ATP    Location  Tournament        Date        Year      Series 
0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 
      Court     Surface       Round     Best.of      Winner       Loser 
0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 
      WRank       LRank          W1          L1          W2          L2 
0.000000000 0.002072109 0.053046001 0.054289266 0.004144219 0.004144219 
         W3          L3          W4          L4          W5          L5 
0.013675922 0.013675922 0.143389971 0.143389971 0.596767509 0.596767509 
      Wsets       Lsets     Comment 
0.598425197 0.598425197 0.000000000

我们通过 install . packages(“Amelia”)将 Amelia 包安装到控制台中,以帮助绘制可视化缺失值的地图。从该图中,我们观察到从以下各列中检测到缺失值:

  • Lsets —失败者集合
  • Wsets —获胜者集合
  • W5——第五盘的获胜者
  • 第五盘输了
  • l4——第四盘输了
  • W4——第四盘的赢家

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Plot of the percentage of missing values

为什么我没有删除所有丢失的值?

我试过了,但是最后一行代码帮助我创建了一个向量来删除 NAs,但是它也删除了我 50%以上的训练数据,所以它没有帮助!

view(a)# view missing values
complete . cases(a)# view missing values
which(complete . cases(a))# view 哪个行有全行值位于
哪个(!complete.cases(a)) #查看哪一行的值为 l

na_vec na_vec < -哪个(!complete.cases(a)) #创建 NA 值的向量

移除 na 行的[-na_vec] # vector。

如何估算缺失数据?—数字变量

绘制估算数据是为了理解原始数据的分布。我遵循的估算技术来自作者 Michy Alice 的博客。这些是步骤:

# Impute missing values with "pmm" - predicted mean matching. m=5 imputed data sets is defaultimputed_Data <- mice(a.mis, m=5, maxit = 50, method = 'pmm', seed = 500)
summary(imputed_Data)

# inspect that missing data has been imputed
imputed_Data$imp$Lsets

# check imputed method
imputed_Data$meth# Plot the imputed data and inspect the distributionxyplot(imputed_Data,WRank ~ W1+L1+W2+L2+W3+L3+W4+L4+L5+W5+LRank,pch=18,cex=1)

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

探索性数据分析

ggplot 数值变量的密度图

我使用 ggplot 来检查缺失值少于 5%的数值属性,以便通过密度图进行可视化。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Lsets had > 5% of missing values.

p1 <- ggplot(a, aes(x=a$Year)) + geom_histogram() + ggtitle(" Histogram of Year")
p1

p2 <- ggplot(a, aes(x=a$WRank)) + geom_histogram()+ ggtitle(" Histogram of Winner's Ranking")
p2

p3 <- ggplot(a, aes(x=a$LRank)) + geom_histogram()+ ggtitle(" Histogram of Loser's Ranking")
p3

p4 <- ggplot(a, aes(x=a$W1)) + geom_histogram()+ ggtitle(" Histogram of Winner in the first set")
p4

p5 <- ggplot(a, aes(x=a$L1)) + geom_histogram()+ ggtitle(" Histogram of Loser in the first set")
p5

p6 <- ggplot(a, aes(x=a$W2)) + geom_histogram()+ ggtitle(" Histogram of Winner in the second set")
p6

p7 <- ggplot(a, aes(x=a$L2)) + geom_histogram()+ ggtitle(" Histogram of Loser in the second set")
p7

p8 <- ggplot(a, aes(x=a$W3)) + geom_histogram()+ ggtitle(" Histogram of Winner in the third set")
p8

p9 <- ggplot(a, aes(x=a$L3)) + geom_histogram()+ ggtitle(" Histogram of Loser in the third set")
p9

可视化已被虚拟编码或一次性编码的分类变量

p16 <- plot(x = a$Comment,
     main = "Distribution of Comment", xlab = "Comment",
     ylab = "count")
p16

p17 <- plot(x= a$Winner,main = "Distribution of Winner", xlab = "Winner",
     ylab = "count")
p17

p18 <- plot( x = a$Loser, main = "Distribution of Loser", xlab = "Loser",
      ylab = "Count")
p18

p19 <- plot( x = a$Best.of, main = "Distribution of Best.of", xlab = "Best Of",
      ylab = "Count")
p19

p20 <- plot( x = a$Round, main = "Distribution of Tennis Round", xlab = "Round",
      ylab = "Count")
p20

这是估算数字数据的密度图:

密度图(估算数据)

关键:洋红色(估算数据)和蓝色(观察数据)

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Density plot of the imputed data containing numeric variables

# View the data as individual points
stripplot(imputed_Data, pch = 20, cex = 1.2)

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Stripplot of the individual imputed variables containing numeric variables

这个预处理和 EDA 的 R 脚本Github 上分享。

R Markdown 脚本也保存在 Github 中,并且可以通过命令 Knit to html 查看为 Html 文件,这在网络浏览器上对所有数据属性的绘图特别有用。

**给自己的提示:

1。使用 R Markdown 时,根据下面的截图,在 {r cars}下面插入 R 代码,确切地说是第 23 行:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

2。其次,我将与 图表 相关的第二段 R 代码插入到````{r pressure,echo=FALSE}部分下面,代码插入到第 214 行。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

在我们可视化了 R 中的数据之后,我们希望使用其他分析工具,比如 Tableau,来探索和可视化澳大利亚网球公开赛的数据。

快乐编码,我们将在第 3 部分继续 Tableau 的下一篇文章!

Python 中的数据清理和要素工程

原文:https://towardsdatascience.com/data-cleaning-and-feature-engineering-in-python-b4d448366022?source=collection_archive---------5-----------------------

为预测旧金山房价建立更好的机器学习模型

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

房价数据为机器学习提供了很好的介绍。任何买了房子甚至租了公寓的人都很容易理解它的特点:更大的空间,更多的房间,通常会导致更高的价格。

因此,开发一个模型应该很容易——但有时并不容易,不是因为机器学习很难,而是因为数据很乱。此外,在同一城市的不同社区,即使只有一英里远,完全相同的房子也可能有明显不同的价格。处理这种情况的最佳方法是设计数据,以便模型可以更好地处理这种情况。

由于寻找数据可能是机器学习中最困难的问题,我们将使用 Github 上另一个数据科学项目的一个很好的样本集,这是旧金山的一组房价,主要是在过去几年里,从旧金山纪事报房屋销售清单中刮出来的。这个数据集可以在这里找到:https://github . com/Ruichang 123/Regression _ for _ house _ price _ estimation/blob/master/final _ data . CSV

首先,我们将从文件的本地副本加载数据。

**import** **pandas** **as** **pd** housing = pd.read_csv("final_data.csv")

现在,让我们来看一下这个数据集的一些图表,这些图表按照最后的销售价格绘制了房间总数。

**import** **matplotlib.pyplot** **as** **plt** x = housing['totalrooms']
y = housing['lastsoldprice']
plt.scatter(x,y)
plt.show()

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

右下角的那个点是异常值。它的值如此极端,以至于扭曲了整个图表,以至于我们甚至看不到主数据集的任何变化。这将扭曲任何在这个数据集上训练机器学习算法的尝试。我们需要更仔细地观察这个数据点,并考虑如何处理它。如果我们按照房间总数对数据进行排序,这是我们上面的一个轴,应该会很突出。

housing['totalrooms'].sort_values()

结果如下:

7524        1.0
11223       1.0
3579        1.0
2132        1.0
5453        1.0
2827        1.0
            ...2765       23.0
8288       24.0
9201       24.0
6860       24.0
4802       26.0
8087       26.0
11083      27.0
2601       28.0
2750       28.0
10727      28.0
11175      33.0
8300       94.0
8967     1264.0
Name: totalrooms, Length: 11330, dtype: float64

事实上,这个数据点确实很突出。这是列表中的最后一个值,这是一个有 1264 个房间的房子!这是非常可疑的,特别是因为情节显示它有一个相当低的价格。至少它与其他数据大相径庭。显示 94 个房间的前一个值可能也是这种情况。我们可以用下面的命令仔细看看这两栋房子,通过它们的数字标识符把它们拉出来。

首先让我们来看看这座据称有 1264 个房间的房子:

df = pd.DataFrame(housing)
df.iloc[[8967]]

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

这个查询显示出更可疑的东西,即“finishedsqft”字段是也是 1264.0 *。*换句话说,这显然只是一个错误,可能是数据输入上的错误——当创建原始数据集时,有人意外地对 finishedsqft 和 totalrooms 使用了相同的值。

现在,让我们看看它前面的值,有 94 个房间:

df.iloc[[8300]]

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

这个据称有 94.0 个房间的家只有两个卧室和两个浴室!同样,这是一个错误。不清楚这是怎么进来的,但我们可以非常肯定,如果我们去这所房子,它没有 94 个房间,只有两个卧室和两个浴室。我们需要消除这两个数据点,但首先让我们再来看一张完成的图表:

x = housing['finishedsqft']
y = housing['lastsoldprice']
plt.scatter(x,y)
plt.show()

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

右下角还有一个异常值。让我们仔细看看这些数据:

housing['finishedsqft'].sort_values()

这是结果

1618         1.0
3405         1.0
10652        1.0
954          1.0
11136        1.0
5103         1.0
916          1.0
10967        1.0
7383         1.0
1465         1.0
8134       243.0
7300       244.0
...
9650      9699.0
8087     10000.0
2750     10236.0
4997     27275.0
Name: finishedsqft, Length: 11330, dtype: float64

第一,出乎意料,有十套房子挂牌 1.0 平方英尺。这显然是错误的。请注意,这些不可能在图表中看到,我们必须查看实际值。此外,上述结果显示最大的房子为 27,275.0 平方英尺。事实证明,这是一栋只有 2.0 间卧室和 2.0 间浴室的房子,尽管它的上市面积为 27,275 平方英尺,所以这几乎肯定是一个错误,或者至少是一个极端的异常值。让我们排除所有这些异常值,再看一下图表。

housing = housing.drop([1618])     
housing = housing.drop([3405])     
housing = housing.drop([10652])     
housing = housing.drop([954])     
housing = housing.drop([11136])     
housing = housing.drop([5103])     
housing = housing.drop([916])     
housing = housing.drop([10967])     
housing = housing.drop([7383])     
housing = housing.drop([1465])     
housing = housing.drop([8967])     
housing = housing.drop([8300])     
housing = housing.drop([4997])       
x = housing['finishedsqft']
y = housing['lastsoldprice']
plt.scatter(x,y)
plt.show()

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

这看起来好多了。这里仍然可能有一些异常值,如果我们真的想的话,我们可以更仔细地调查它们,但在这个视图中没有任何单个数据点会扭曲图表,可能也没有(我们可以看到的)会扭曲机器学习模型。

现在我们已经清理了数据,我们需要做一些特性工程。这包括将数据集中的值转换为机器学习算法可以使用的数值。

以“lastsolddate”值为例。在当前数据集中,这是一个“mm/dd/yyyy”形式的字符串我们需要将它改为一个数值,这可以通过下面的 Pandas 命令来实现:

housing['lastsolddateint'] = pd.to_datetime(housing['lastsolddate'], format='%m/**%d**/%Y').astype('int')
housing['lastsolddateint'] = housing['lastsolddateint']/1000000000
housing = housing[housing['lastsolddateint'].notnull()]

现在让我们为我们的数据创建一个检查点,以便我们以后可以引用它。

clean_data = housing.copy()

此外,还有一些我们不能或不应该使用的字段,因此我们将删除它们。

我更喜欢创建函数来做这种我们可能会反复做的工作,正如我们将在下面看到的,以便在我们尝试不同的假设时简化代码。

出于多种原因,我们删除了 remove_list 中的列。其中一些是我们无法处理的文本值(info,address,z_address,zipcode,zpid)。纬度和经度字段在某种形式上可能是有用的,但是对于这个例子来说,它可能会使事情变得复杂——但是没有理由不在将来尝试它。zestimate 和 zindexvalue 字段实际上是由其他数据科学技术(可能来自 Zillow)生成的,因此使用它们就是欺骗!最后,我们将删除 usecode(例如,house,condo,mobile home ),它可能非常有用,但我们不会在本例中使用它。

**def** drop_geog(data, keep = []):     
    remove_list = ['info','address','z_address','longitude','latitude','neighborhood','lastsolddate','zipcode','zpid','usecode', 'zestimate','zindexvalue']
    **for** k **in** keep:
        remove_list.remove(k)
    data = data.drop(remove_list, axis=1)
    data = data.drop(data.columns[data.columns.str.contains('unnamed',case = **False**)],axis = 1)
     **return** data housing = drop_geog(housing)

现在我们已经清理了数据,让我们看看一些算法是如何管理使用它的。我们将使用 scikit-learn。

首先,我们需要将数据分成测试集和训练集,再次使用我们以后可以重用的函数。这确保了当我们测试数据时,我们实际上是在用以前从未见过的数据测试模型。

**from** **sklearn.model_selection** **import** train_test_split

**def** split_data(data):
    y = data['lastsoldprice']
    X = data.drop('lastsoldprice', axis=1)
    *# Return (X_train, X_test, y_train, y_test)*
    **return** train_test_split(X, y, test_size=0.2, random_state=30)housing_split = split_data(housing)

我们先试试线性回归。

**import** **sys**
**from** **math** **import** sqrt
**from** **sklearn.metrics** **import** mean_squared_error, mean_absolute_error, r2_score
**from** **sklearn.model_selection** **import** GridSearchCV
**import** **numpy** **as** **np**

**from** **sklearn.linear_model** **import** LinearRegression

**def** train_eval(algorithm, grid_params, X_train, X_test, y_train, y_test):
    regression_model = GridSearchCV(algorithm, grid_params, cv=5, n_jobs=-1, verbose=1)
    regression_model.fit(X_train, y_train)
    y_pred = regression_model.predict(X_test)
    print("R2: **\t**", r2_score(y_test, y_pred))
    print("RMSE: **\t**", sqrt(mean_squared_error(y_test, y_pred)))
    print("MAE: **\t**", mean_absolute_error(y_test, y_pred))
    **return** regression_model

train_eval(LinearRegression(), {}, *housing_split)

train_eval函数可用于任何任意的 scikit-learn 算法,用于训练和评估。这是 scikit-learn 的一大好处。函数的第一行包含一组我们想要评估的超参数。在这种情况下,我们传入{},这样我们就可以在模型上使用默认的超参数。该函数的第二行和第三行执行实际工作,拟合模型,然后对其运行预测。然后打印报表显示一些我们可以评估的统计数据。让我们看看我们如何公平。

R2: 0.5366066917131977
RMSE: 750678.476479495
MAE: 433245.6519384096

第一个得分 R 也称为决定系数,是对模型的一般评估,它显示了可以由特征解释的预测中的变化百分比。一般来说,R 值越高越好。另外两个统计是均方根误差和平均绝对误差。这两个只能与其他模型上相同统计的其他评估相关联地进行评估。话虽如此,一个 0.53 的 R,和其他几十万的统计数据(对于可能价值一两百万的房子来说)并不是很好。我们可以做得更好。

让我们看看其他几个算法的表现。首先,K-最近邻(KNN)。

**from** **sklearn.neighbors** **import** KNeighborsRegressor
knn_params = {'n_neighbors' : [1, 5, 10, 20, 30, 50, 75, 100, 200, 500]}
model = train_eval(KNeighborsRegressor(), knn_params, *housing_split)

如果线性回归是平庸的,KNN 是可怕的!

R2: 0.15060023694456648
RMSE: 1016330.95341843
MAE: 540260.1489399293

接下来我们将尝试决策树。

**from** **sklearn.tree** **import** DecisionTreeRegressor

tree_params = {}
train_eval(DecisionTreeRegressor(), tree_params, *housing_split)

这就更惨了!

R2: .09635601667334437
RMSE: 1048281.1237086286
MAE: 479376.222614841

最后,我们来看看《随机阿甘正传》。

**from** **sklearn** **import** ensemble
**from** **sklearn.ensemble** **import** RandomForestRegressor
**from** **sklearn.datasets** **import** make_regression

forest_params = {'n_estimators': [1000], 'max_depth': [**None**], 'min_samples_split': [2]}
forest = train_eval(RandomForestRegressor(), forest_params, *housing_split)

这个好一点,但我们还可以做得更好。

R2: 0.6071295620858653
RMSE: 691200.04921061
MAE: 367126.8614028794

我们如何改进这些结果?一种选择是尝试其他算法,也有很多,有些会做得更好。但是我们实际上可以通过使用特征工程的数据来微调我们的结果。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

让我们重新考虑一下数据中的一些特征。邻居是一个有趣的领域。这些值类似于“波特雷罗山”和“南海滩”这些不能简单地排序(从最贵到最便宜的邻域),或者至少,这样做不一定会产生更好的结果。但是我们都知道,两个不同小区的同一个房子,会有两个不同的价格。所以我们想要这些数据。我们如何使用它?

Python 的 Pandas 库为我们提供了一个简单的工具来创建这些值的“一次性编码”。这将采用“neighborhood”这一列,并为原始“neighborhood”列中的每个值创建一个新列。对于这些新行中的每一行(具有新的列标题名称,如“Portrero Hill”和“South Beach”),如果一行数据在原始列中具有该邻域的值,则它被设置为 1,否则它被设置为 0。机器学习算法现在可以构建与该邻域相关联的权重,如果数据点在该邻域中(如果该列的值为 1),则应用该权重,否则不应用该权重(如果该列的值为 0)。

首先,我们需要检索我们的检查点数据,这次保留“neighborhood”字段。

housing_cleaned = drop_geog(clean_data.copy(), ['neighborhood'])

现在我们可以为“neighborhood”字段创建一个一次性编码。

one_hot = pd.get_dummies(housing_cleaned['neighborhood'])
housing_cleaned = housing_cleaned.drop('neighborhood',axis = 1)

我们将保留“one_hot”值,稍后再添加它。但首先,我们必须做两件事。我们需要将数据分成训练集和测试集。

(X_train, X_test, y_train, y_test) = split_data(housing_cleaned)

最后一步,我们需要对数据进行缩放和居中。

**from** **sklearn.preprocessing** **import** StandardScalerscaler = StandardScaler()
scaler.fit(X_train)
X_train[X_train.columns] = scaler.transform(X_train[X_train.columns])
X_train = X_train.join(one_hot)
X_test[X_test.columns] = scaler.transform(X_test[X_test.columns])
X_test = X_test.join(one_hot)

housing_split_cleaned = (X_train, X_test, y_train, y_test)

让我们稍微解释一下这个步骤。

首先,我们应用 StandardScaler()。对于每列中的所有数据点,此函数通过减去列的平均值并除以列的标准偏差来缩放和居中数据。这将所有数据标准化,使每一列呈正态分布。它还会缩放数据,因为有些字段会在 0 到 10,000 之间变化,如“finishedsqft”,而其他字段只会在 0 到 30 之间变化,如房间数。缩放将把它们都放在相同的比例上,这样一个特性就不会仅仅因为它具有较高的最大值而任意地扮演比其他特性更大的角色。对于一些机器学习算法,正如我们将在下面看到的,这对于获得哪怕是半个像样的结果都是至关重要的。

其次,需要注意的是,我们必须在训练特性 X_train 上“安装”缩放器。也就是说,我们获取训练数据的平均值和标准偏差,用这些值拟合 scaler 对象,然后使用拟合的 scaler 转换训练数据和测试数据。我们不希望在测试数据上安装缩放器,因为那样会将测试数据集中的信息泄露给训练好的算法。我们可能最终得到看起来比实际情况更好的结果(因为算法已经在测试数据上进行了训练)或看起来更差的结果(因为测试数据是根据它们自己的数据集进行缩放的,而不是根据测试数据集)。

现在,让我们用新设计的功能重建我们的模型。

model = train_eval(LinearRegression(), {}, *housing_split_cleaned)

现在,在线性回归下,我们拥有的最简单的算法,结果已经比我们之前看到的任何结果都要好。

R2: 0.6328566983301503
RMSE: 668185.25771193
MAE: 371451.9425795053

下一个是 KNN。

model = train_eval(KNeighborsRegressor(), knn_params, *housing_split_cleaned)

这是一个巨大的进步。

R2: 0.6938710004544473
RMSE: 610142.5615480896
MAE: 303699.6739399293

决策树:

model = train_eval(DecisionTreeRegressor(), tree_params,*housing_split_cleaned)

还是很糟糕,但比以前好了。

R2: 0.39542277744197274
RMSE: 857442.439825675
MAE: 383743.4403710247

最后,随机福里斯特。

model = train_eval(RandomForestRegressor(), forest_params, *housing_split_cleaned)

这又是一个不错的进步。

R2: 0.677028227379022
RMSE: 626702.4153226872
MAE: 294772.5044353021

从额外的特征工程到尝试额外的算法,可以利用这些数据做更多的事情。但是,从这个简短的教程中得到的教训是,寻求更多的数据或在文献中寻找更好的算法并不总是正确的下一步。首先从一个更简单的算法中获取尽可能多的数据可能更好,这不仅是为了比较,也是因为数据清理可能会在未来带来回报。

最后,尽管它很简单,K-最近邻可以是相当有效的,只要我们用适当的方式对待它。

使用 Python 和 Pandas 库进行数据清理

原文:https://towardsdatascience.com/data-cleaning-with-python-using-pandas-library-c6f4a68ea8eb?source=collection_archive---------1-----------------------

就数据科学而言,数据清理和组织占总权重的 57%

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

整个数据清理过程分为如下所示的子任务。

  1. 导入所需的库。
  2. 从不同的源(Kaggle)获取数据集并显示数据集。
  3. 删除不使用或不相关的列。
  4. 根据我们的方便重命名列名。
  5. 替换行的值并使其更有意义。

尽管这个教程很小,但它是一个从小事开始,以后再动手做的好方法。我将确保所有没有 python 编程经验或者不知道什么是数据科学或数据清理的人都能很容易地理解本教程。我一开始并不了解 python,所以即使对我来说,这也是一个很好的起点。python 的一个特点是代码是不言自明的,你的关注点不应该是代码做了什么,因为代码很大程度上说明了它做了什么,而应该告诉你为什么选择这样做,这个" why 因素比" what 因素更重要。而且完整的源代码可以在我的 GitHub 上找到。

步骤 1:导入所需的库。

这一步包括导入所需的库,它们是熊猫numpyCSV 。谈到数据科学,这些是必要的库。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

步骤 2:从不同的来源获取数据集并显示数据集。

这一步包括从不同的来源获取数据集,数据集的链接如下。

数据集下载

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

注意:如果你使用 Jupyter 笔记本 来练习本教程,那么阅读 CSV 文件应该没有问题。但是如果你像我一样是一个谷歌迷,那么你应该使用 谷歌 Colab 这是我认为最好的,用于实践数据科学,然后你必须遵循一些步骤来加载或读取 CSV 文件。所以这篇文章帮你解决这个问题。我个人推荐大家通读这篇文章。我按照第二步阅读了那篇文章中的 CSV 文件。选择最好的一个,开始工作。

步骤 3:删除未使用或不相关的列

这一步包括删除不相关的列,如 cp、fbs、thalach 等等,代码基本上是不言自明的。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

步骤 4:为了方便起见,重命名列名。

这一步包括重命名列名,因为许多列名有点混乱,难以理解。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

步骤 5:如有必要,替换行的值。

这一步包括替换不完整的值或使值更具可读性,例如这里的性别字段由值 10 组成,其中 1 为男性,而 0 为女性,但对于第三人来说,这通常看起来不明确,因此将值更改为可理解的值是一个好主意。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

以上是总体简单的数据清理过程,显然这不是行业级别的实际清理过程,但这是一个良好的开端,所以让我们从小数据集开始,然后再处理大型数据集,这将涉及更多的清理过程。这只是从初学者的角度给出了数据清理过程的一个概念。感谢你们花时间阅读我的文章,请关注更多更新。请在下面的评论区告诉我你对这个教程的看法。另外,如果你对代码有任何疑问,评论区都是你的。祝你有愉快的一天。

用 R 和 Tidyverse 清理数据:检测缺失值

原文:https://towardsdatascience.com/data-cleaning-with-r-and-the-tidyverse-detecting-missing-values-ea23c519bc62?source=collection_archive---------0-----------------------

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

数据清洗是数据科学最重要的一个方面。

作为一名数据科学家,你可能会花费 80%的时间清理数据。

在之前的一篇文章中,我使用 Python 和 Pandas 库完成了许多数据清理任务。

这篇文章引起了如此多的关注,我想在 r。

在这篇文章中,你将学习如何使用来自 Tidyversetidyrdplyr 包来检测缺失值。

Tidyverse 是数据科学的最佳 R 包集合,所以您应该熟悉它。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

入门指南

开始任何数据科学项目的一个好方法就是感受数据。

这只是快速查看变量名和预期的变量类型。查看数据的维度也很有用。

探索性数据分析(EDA)极其重要,因此它值得拥有自己的博文。在本文中,我们不会讨论完整的 EDA。

在我们开始之前,先去我们的 github 页面获取一份数据。确保将副本放在 R 代码所在的工作目录中。

下面快速浏览一下我们的数据:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

这是一个小型的客户流失数据集。

为了便于学习,该数据集展示了一些丢失值的真实示例。

首先,加载 tidverse 库并读入 csv 文件。

library(tidyverse)# set working directory
path_loc <- "C:/Users/Jonathan/Desktop/data cleaning with R post"
setwd(path_loc)# reading in the data
df <- read_csv("telecom.csv")

通常数据被读入 dataframe,但是 tidyverse 实际上使用了tibles

这些类似于数据帧,但也略有不同。要了解更多关于 tibbles 的信息,请查看数据科学的 R 中的这一章

我喜欢使用glimpse函数来查看变量名和类型。

# taking a quick look
glimpse(df)> glimpse(df)
Observations: 10
Variables: 5
$ customerID     chr "7590-VHVEG", "5575-GNVDE", "3668-QPYBK", "7...
$ MonthlyCharges dbl 29.85, 56.95, NA, 42.30, 70.70, NaN, 89.10, ...
$ TotalCharges   chr "109.9", "na", "108.15", "1840.75", NA, "820...
$ PaymentMethod  chr "Electronic check", "Mailed check", "--", "B...
$ Churn          chr "yes", "yes", "yes", "no", "no", "yes", "no"...

我们可以看到有 5 个变量。

  • customerID
  • MonthlyCharges
  • TotalCharges
  • PaymentMethod
  • Churn

还有对每个变量类型的描述:

  • customerID: chr代表字符,字符串的别称
  • MonthlyCharges: dbl代表 double,是一种数值类型
  • TotalCharges: chr性格
  • PaymentMethod: chr人物
  • Churn: chr人物

有 10 个观察值,这意味着有 10 行数据。

现在我们已经快速地熟悉了数据,让我们回顾一些基本的数据操作。

数据操作的语法:dplyr

在我们开始处理缺失值之前,让我们先来看一下 dplyr 库

这只是一个快速介绍,所以请务必查看官方的 dplyr 文档以及来自数据科学的 R 的第 5 章数据转换

这个库使用了“数据操作语法”,这基本上意味着有一组带有逻辑动词名称的函数来完成你想做的事情。

例如,也许您想只查看顾客。您可以过滤流失率值等于“是”的数据。

我们可以使用 dplyr 中的filter函数快速完成这项工作。

# filter on customers that churned
df %>%
  filter(Churn=="yes") # A tibble: 5 x 5
  customerID MonthlyCharges TotalCharges PaymentMethod    Churn
  chr                  dbl  chr          chr              chr
1 7590-VHVEG           29.8 109.9        Electronic check yes
2 5575-GNVDE           57.0 na           Mailed check     yes
3 3668-QPYBK           NA   108.15       --               yes
4 9305-CDSKC          NaN   820.5        --               yes
5 6713-OKOMC           NA   N/A          NA               yes

看一看,我们可以看到 R 返回了一个有组织的 tibble,其中只包含了客户。

如果你不熟悉%>%操作员,也被称为“管道操作员”,看看这篇的博文

管道是 magritter 包中的一个有用的操作符。它允许我们通过消除嵌套括号来组织我们的代码,从而使我们的代码更具可读性。

例如,假设我们有以下计算:

# nested functions
log(sin(exp(2))) > log(sin(exp(2)))
[1] -0.1122118

由于所有的括号,这不是很可读。现在让我们看一个管道示例。

# piped functions
2 %>% exp() %>%
  sin() %>%
  log()

显而易见,管道示例可读性更好。

好了,回到 dplyr。

我们只是使用了 filter 函数来快速过滤掉流失值等于“yes”的行。

也许我们也想只选择customerIDTotalCharges列。我们也可以使用select功能快速完成这项工作。

# filter on customers that churned,
# select customerID and TotalCharges columns
df %>%
  filter(Churn=="yes") %>%
  select(customerID, TotalCharges) # A tibble: 5 x 2
  customerID TotalCharges
  chr        chr
1 7590-VHVEG 109.9
2 5575-GNVDE na
3 3668-QPYBK 108.15
4 9305-CDSKC 820.5
5 6713-OKOMC N/A

我们可以看到使用这些 dplyr 函数来操作我们的数据是多么容易。

垂直地将函数链接在一起使得我们的代码非常易读。

这种编码方式一开始可能看起来有点奇怪,但是经过一点实践之后,它会变得非常有用。

标准缺失值

现在我们对管道操作符和 dplyr 稍微熟悉了一些,让我们开始检测丢失的值。

我们将从 R 识别的标准缺失值开始。

去看看MonthlyCharges栏吧。

我们可以看到有三个值丢失了。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

有两个空牢房,一个写着“南”。这些显然是缺失的价值观。

我们可以看到 R 如何使用is.na函数来识别这些。

首先让我们打印出该列,然后应用is.na

# looking at MonthlyCharges
df$MonthlyCharges
is.na(df$MonthlyCharges) > df$MonthlyCharges
 [1]  29.85  56.95     NA  42.30  70.70    NaN  89.10     NA 104.80
[10]  54.10
> is.na(df$MonthlyCharges)
 [1] FALSE FALSE  TRUE FALSE FALSE  TRUE FALSE  TRUE FALSE FALSE

我们可以看到,两个缺失的单元格被识别为“NA”,另一个带有 NaN 的缺失值被 R 识别为“Nan”。

当我们运行is.na函数时,R 识别两种类型的缺失值。我们可以看到这一点,因为当我们运行is.na时,会返回三个TRUE值。

注意“那”和“南”的区别是很重要的。我们可以使用帮助功能来仔细查看这两个值。

# using the help function to learn about NA
help(NA)

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

看一下右下方的窗口,我们可以看到“NA”或“不可用”用于表示缺失值。

“NaN”或“非数字”用于数值计算。如果一个值是未定义的,比如 0/0,“NaN”是表示它的合适方式。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

还有一个is.nan功能。试着用“NA”和“NaN”来运行它。您将看到它为“NaN”返回 TRUE 值,但为“NA”返回 FALSE 值。

另一方面,is.na函数更加通用,因此它将检测两种类型的缺失值。

让我们继续使用 dplyr 来稍微总结一下我们的数据。

我们可以使用distinct函数来查看显示在MonthlyCharges列中的不同值。

# looking at the distinct values
df %>%
  distinct(MonthlyCharges) # A tibble: 9 x 1
  MonthlyCharges
             dbl
1           29.8
2           57.0
3           NA
4           42.3
5           70.7
6          NaN
7           89.1
8          105.
9           54.1

我们可以看到有 9 个不同的值。有 10 行数据,但是“NA”出现了两次,所以有 9 个不同的值。

如果我们想快速计算不同的值,我们可以使用summarise函数。

# counting unique values
df %>%
  summarise(n = n_distinct(MonthlyCharges)) # A tibble: 1 x 1
      n
     int
1     9

这将返回一个简单的 tibble,其中有一列我们命名为“n ”,用于计算MonthlyCharges列中不同值的数量。

我们真正追求的是丢失值的计数。我们可以使用summarise函数和is.na来计算缺失值。

# counting missing values
df %>%
  summarise(count = sum(is.na(MonthlyCharges)))# A tibble: 1 x 1
  count
     int
1     3

正如我们在上面看到的,缺失值的数量是 3。

也许我们想同时做多件事。假设我们想要得到唯一值、缺失值以及MonthlyCharges的中值的计数。

下面是我们如何使用summarise实现这一点:

# counting unique, missing, and median values
df %>% summarise(n = n_distinct(MonthlyCharges),
                 na = sum(is.na(MonthlyCharges)),
                 med = median(MonthlyCharges, na.rm = TRUE)) # A tibble: 1 x 3
      n    na   med
     int   int  dbl
1     9     3  57.0

这产生了我们的汇总数据的一个有组织的小 tibble。

既然我们已经确定了缺失值,让我们用MonthlyCharges的中值来替换它们。为此,我们可以使用 dplyr 的mutate函数。

# mutate missing values
df %>%
  mutate(MonthlyCharges
         = replace(MonthlyCharges,
                   is.na(MonthlyCharges),
                   median(MonthlyCharges, na.rm = TRUE))) # A tibble: 10 x 5
   customerID MonthlyCharges TotalCharges PaymentMethod    Churn
    chr                 dbl  chr          chr              chr
 1 7590-VHVEG           29.8 109.9        Electronic check yes
 2 5575-GNVDE           57.0 na           Mailed check     yes
 3 3668-QPYBK           57.0 108.15       --               yes
 4 7795-CFOCW           42.3 1840.75      Bank transfer    no
 5 9237-HQITU           70.7 NA           Electronic check no
 6 9305-CDSKC           57.0 820.5        --               yes
 7 1452-KIOVK           89.1 1949.4       Credit card      no
 8 6713-OKOMC           57.0 N/A          NA               yes
 9 7892-POOKP          105\.  3046.05      Electronic check no
10 8451-AJOMK           54.1 354.95       Electronic check no

我们可以看到,在三个不同的点上,缺失值被替换为中值 57。

只是为了再次检查这是否有效,让我们再次打印出整个 tibble。

df# A tibble: 10 x 5
   customerID MonthlyCharges TotalCharges PaymentMethod    Churn
    chr                 dbl  chr          chr              chr 
 1 7590-VHVEG           29.8 109.9        Electronic check yes
 2 5575-GNVDE           57.0 na           Mailed check     yes
 3 3668-QPYBK           NA   108.15       --               yes
 4 7795-CFOCW           42.3 1840.75      Bank transfer    no
 5 9237-HQITU           70.7 NA           Electronic check no
 6 9305-CDSKC          NaN   820.5        --               yes
 7 1452-KIOVK           89.1 1949.4       Credit card      no
 8 6713-OKOMC           NA   N/A          NA               yes
 9 7892-POOKP          105\.  3046.05      Electronic check no
10 8451-AJOMK           54.1 354.95       Electronic check no

看起来所有丢失的值都回来了。发生了什么事?

这引出了重要的一点。dplyr 包不会就地修改数据。

基本上,这意味着如果我们用一个管道操作符将一个mutate应用于一些数据,它将向我们显示数据的一个修改视图,但这不是一个永久的修改。

为了永久地修改数据,我们需要使用赋值操作符<-将 mutate 赋值给原始数据。

我们会这样做:

# mutate missing values, and modify the dataframe
df <- df %>%
  mutate(MonthlyCharges = replace(MonthlyCharges,
                                  is.na(MonthlyCharges),
                                  median(MonthlyCharges, na.rm = TRUE)))

现在,如果我们再看一下数据,它应该会被修改。

df # A tibble: 10 x 5
   customerID MonthlyCharges TotalCharges PaymentMethod    Churn
    chr                 dbl  chr          chr              chr
 1 7590-VHVEG           29.8 109.9        Electronic check yes
 2 5575-GNVDE           57.0 na           Mailed check     yes
 3 3668-QPYBK           57.0 108.15       --               yes
 4 7795-CFOCW           42.3 1840.75      Bank transfer    no
 5 9237-HQITU           70.7 NA           Electronic check no
 6 9305-CDSKC           57.0 820.5        --               yes
 7 1452-KIOVK           89.1 1949.4       Credit card      no
 8 6713-OKOMC           57.0 N/A          NA               yes
 9 7892-POOKP          105\.  3046.05      Electronic check no
10 8451-AJOMK           54.1 354.95       Electronic check no

这次MonthlyCharges列被永久修改。请记住,当您想要使用 dplyr 永久地变更您的数据时,您需要将 mutate 分配给原始数据。

非标准缺失值

很多时候,你不会幸运地拥有 R 能马上识别的所有标准缺失值类型。

让我们快速浏览下一篇专栏文章TotalCharges,了解我的意思。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

我们可以看到有三个不同的缺失值,“na”、“NA”和“N/A”。

在前面的例子中我们看到 R 将“na”识别为缺失值,但是“NA”和“N/A”呢?

让我们看看这个列,并使用is.na来看看 R 是否将所有这些都识别为缺失值。

# looking at missing values
df$TotalCharges
is.na(df$TotalCharges) > is.na(df$TotalCharges)
 [1] FALSE FALSE FALSE FALSE  TRUE FALSE FALSE FALSE FALSE FALSE

查看结果,我们可以看到 R 只将“NA”标识为缺失值。

让我们使用summarise函数来看看 R 找到了多少个丢失的值。

# counting missing values
df %>%
  summarise(count = sum(is.na(TotalCharges)))# A tibble: 1 x 1
  count
     int
1     1

结果证实 R 只找到一个丢失的值。

我们需要用“na”替换“NA”和“N/A ”,以确保 R 将所有这些都识别为缺失值。

让我们使用mutate函数将这些替换为正确的缺失值类型。请记住,我们需要使用赋值操作符来确保更改是永久性的。

# replacing with standard missing value type, NA
df <- df %>%
  mutate(TotalCharges = replace(TotalCharges, TotalCharges == "na", NA)) %>%
  mutate(TotalCharges = replace(TotalCharges, TotalCharges == "N/A", NA))

如果我们再看一下这一列,我们可以看到所有缺失的值都被 r 正确地识别出来了。

# taking another look
df$TotalCharges
is.na(df$TotalCharges)> df$TotalCharges
 [1] "109.9"   NA        "108.15"  "1840.75" NA        "820.5"
 [7] "1949.4"  NA        "3046.05" "354.95"
> is.na(df$TotalCharges)
 [1] FALSE  TRUE FALSE FALSE  TRUE FALSE FALSE  TRUE FALSE FALSE

现在我们可以看到 R 选择了所有三个丢失的值。

在我们替换丢失的值之前,还有另一个问题。

r 认为列值是字符。我们可以用glimpse函数来确认这一点。

> glimpse(df$TotalCharges)
 chr [1:10] "109.9" NA "108.15" "1840.75" NA "820.5" "1949.4" NA ...

让我们把它们改成数字类型。

# changing to numeric type
df$TotalCharges <- as.numeric(df$TotalCharges)
glimpse(df$TotalCharges) > df$TotalCharges <- as.numeric(df$TotalCharges) 
> glimpse(df$TotalCharges)
 num [1:10] 110 NA 108 1841 NA ...

最后,让我们用中间值替换缺失值。

# replace missing values with median
df <- df %>%
  mutate(TotalCharges = replace(TotalCharges,
                                is.na(TotalCharges),
                                median(TotalCharges, na.rm = T)))
df$TotalCharges> df$TotalCharges
 [1]  109.90  820.50  108.15 1840.75  820.50  820.50 1949.40  820.50
 [9] 3046.05  354.95

更改所有缺失值的一个更简单的方法是在执行任何操作之前将列更改为 numeric。

让我们再次导入数据,这样我们就又有丢失的值了。

# importing the data again
df <- read_csv("telecom.csv")
df$TotalCharges> df$TotalCharges
 [1] "109.9"   "na"      "108.15"  "1840.75" NA        "820.5"
 [7] "1949.4"  "N/A"     "3046.05" "354.95"

现在让我们试着将该列改为数字。

# change TotalCharges to numeric type
df$TotalCharges <- as.numeric(df$TotalCharges)
df$TotalCharges> df$TotalCharges <- as.numeric(df$TotalCharges)
Warning message:
NAs introduced by coercion 
> df$TotalCharges
 [1]  109.90      NA  108.15 1840.75      NA  820.50 1949.40      NA
 [9] 3046.05  354.95

这一次,所有不同的缺失值类型都被自动更改。

虽然这有点短,但我并不总是喜欢这种解决方案。

这对于我们的特定示例是有效的,但是如果您试图检测异常或其他脏数据,这可能不是一个好的解决方案。

请务必阅读 R 控制台上类似这样的警告。它可以提供有价值的信息。

更多缺失值

到目前为止,我们已经查看了像“NA”这样的标准缺失值和像“n/a”和“N/A”这样的非标准值。

还有许多其他方法来表示丢失的数据。

也许我是手动输入数据,并选择使用“—”来表示缺少的值。

另一方面,也许你更喜欢将单元格留空。

让我们了解一下如何检测这些更不常见的缺失值类型。

看一看PaymentMethod栏目:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

我们可以看到有三个值丢失了。

两个用“—”表示,一个只是一个空单元格。

看看 R 对这些怎么看:

# looking at PaymentMethod
df$PaymentMethod
is.na(df$PaymentMethod) > is.na(df$PaymentMethod)
 [1] FALSE FALSE FALSE FALSE FALSE FALSE FALSE  TRUE FALSE FALSE

r 只是为了识别一个丢失的值,即空单元格。

让我们继续使用 mutate 将“—”改为 NA。

# replacing "--" with NA
df <- df %>%
  mutate(PaymentMethod = replace(PaymentMethod, PaymentMethod ==  "--", NA))
is.na(df$PaymentMethod)
df$PaymentMethod> df$PaymentMethod
 [1] "Electronic check" "Mailed check"     NA
 [4] "Bank transfer"    "Electronic check" NA
 [7] "Credit card"      NA                 "Electronic check"
[10] "Electronic check"

现在我们可以看到所有三个缺失的值都显示出来了。

到目前为止,我们要么不考虑缺失值,要么用中间值代替它们。

如何处理字符类型列中的缺失值?

因为PaymentMethod列中的所有条目都是字符串,所以没有中间值。

让我们将 NAs 转换为一个新的类别,称为“不可用”,而不仅仅是排除丢失的值。

# replace NA with "unavailable"
df <- df %>%
  mutate(PaymentMethod = replace(PaymentMethod, is.na(PaymentMethod), "unavailable"))df$PaymentMethod> df$PaymentMethod
 [1] "Electronic check" "Mailed check"     "unavailable"     
 [4] "Bank transfer"    "Electronic check" "unavailable"     
 [7] "Credit card"      "unavailable"      "Electronic check"
[10] "Electronic check"

现在我们可以看到,我们的三个缺失值 NA 已经被转换为一个新的类别“不可用”。

有时值丢失是有原因的,所以保留这些信息以查看它如何影响我们的机器学习模型中的结果是很好的。

我们不会在这篇文章中讨论这些细节,但是请记住,丢弃丢失的值可能并不总是一个好主意。

结论

在这篇文章中,我们了解了数据科学中最重要的技能之一数据清理

具体来说,我们着眼于检测不同类型的缺失值。

我们还学习了如何替换数字和字符类型的缺失值。

您可能会花费高达 80%的时间来清理数据,因此这是一项非常有价值的技能。

有关使用 Python 清理数据和检测缺失值的信息,请查看这篇文章

### 回答1: Active Directory服务是种由微软公司开发的网络服务,它提供了种集中管理和控制网络资源的方式。它可以在中集中管理用户、计算机、应用程序和其他网络资源,从而提高了网络的安全性和可管理性。Active Directory服务还提供了些高级功能,如单点登录、组策略管理和名系统(DNS)集成等,使得网络管理员可以更加轻松地管理和维护网络。 ### 回答2: Active Directory服务(Active Directory Domain Services,简称AD DS)是微软公司的项用于管理和组织网络资源的目录服务。它是种基于LDAP(轻量级目录访问协议)的目录服务,可以让用户和管理员方便地管理和访问网络中的资源。 AD DS的主要功能包括用户身份认证、访问控制、组管理和资源管理等。通过AD DS,管理员可以集中管理和配置用户和计算机的访问权限,确保系统安全。同时,AD DS还提供了的集中管理功能,管理员可以通过控制器管理中的所有对象,并在中实施策略。 AD DS还支持单点登录功能,用户只需在登录到之后,即可自动访问到所属中的资源,而无需再次输入用户名和密码。这大大提高了用户的工作效率。 此外,AD DS还支持多架构,可以通过建立信任关系实现跨资源的访问和管理。管理员可以维护多个之间的信任关系,实现用户和资源的统管理。 总而言之,AD DS是种强大的目录服务,可以实现用户和资源的集中管理和访问控制,提高网络系统的稳定性和安全性。它是企业网络管理的重要组成部分,为企业提供了高效的身份认证和资源管理功能,增强了企业的生产力和安全性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值