数据对于 21 世纪就像混凝土对于 20 世纪一样
Photo by Joel Filipe on Unsplash
那些在 20 世纪建造大城市中心的人是在大量新技术的推动下做到这一点的。电力、汽车、混凝土和电梯都推动了新的生活方式,使城市和郊区与之前的城市和郊区有了根本的不同。
新的生活空间是围绕汽车的优势而建立的,它们伸向更高的天空,它们使人们能够通过电力将生活从传统的时钟中解放出来。这对人类心理产生了深远的影响——我们的文化发生了转变,我们的工作生活变得不同,我们的期望也发生了变化。随着新技术(喷气式飞机、计算机)继续驱动我们生活的物理布局,我们将自己塑造成新的世界,并不断变化。
在 21 世纪,我们已经可以看到,驱动技术集群(越来越快的电信网络、传感器、自动化、机器人和人工智能)正在创造新的数字世界结构,人类将按照这种结构塑造自己。我们现在选择花费时间的结构是由数据构建的。这包括痴迷的 Instagrammer 或在线游戏玩家,以及等待下一份零工经济工作的工人和通过虚拟现实会议系统合作的专业人士。
随着算法的进一步推出和数据聚合的大规模回归,我们将发现越来越多的生活被缓和、改变和影响,就像“软件吞噬世界”一样。曾经,企业通过闪亮的实体形象来定义自己——零售商店骄傲地站在大街上——现在,推动企业成功的是数据驱动的 UX 个性化。精心制作的反馈回路确保用户被温和地拉拢到最佳路径。优步的司机评级、Twitter 上的点赞和转发、Apple watch 上的健康数据,都是数据驱动的个性化反馈的例子,我们下意识地根据这些反馈塑造自己。
语言上的相似之处令人着迷。我们谈论建造建筑物的建筑师和工程师——现在用同样的词语来描述那些建造我们新的软件家园的人。
与此同时,流向位置良好的土地的巨大经济回报现在流向了战略数据集。开采水泥的艰难任务现在有了血汗工厂的数据标签。风险资本家和企业家捕捉金融想象力的方式曾经是房地产大亨可以做到的。
Charlie Chaplin being data processed
这对我们意味着什么?如果我们将要生活在一系列的算法中,那么我们将改变我们的生活来匹配它们。我们的祖先对汽车做了同样的事情——新交通工具的经济利益意味着社会让个人屈从于新的范式。乱穿马路成了一种犯罪。行人知道他们的位置。我们仍然接受每年数百万人死亡,因为这种交换似乎是值得的。
我们将为我们将要生活的新数据结构做同样的事情。总的来说,我们的生活会变得更好——就像 20 世纪是 19 世纪的进步一样(有一些明显的军事技术驱动的例外,也可能与我们即将到来的时代相似)。
但是我们将生活在数字建筑中。随着 AR 和 VR 的起飞,它们将变得越来越真实。重要的聚会将在我们曾经拥有会议室的虚拟现实中举行。娱乐将把我们拖入沉浸式的互动世界,有些人将挣扎着浮出水面。购物将在网上自动完成。
相比之下,我们周围的建筑会显得越来越单调、沉闷和空旷。直到,在某个阶段,本世纪中叶对“真实”的渴望将把这一切带回到焦点…
数据湖和 SQL???
不是悖论。SQL 正被用于分析和转换数据湖中的大量数据。
随着数据量越来越大,推动因素是更新的技术和模式变化。与此同时,SQL 仍然是主流。在这里,我将探讨 SQL 如何用于数据湖和新的数据生态系统。
TL;灾难恢复版本:随着数据和复杂性的增长,SQL 比以往任何时候都更适合分析和转换数据湖中的数据。
SQL Code — Photo by Caspar Camille Rubin on Unsplash
记得 NoSQL 吗?
NoSQL 数据库出现了,承诺了巨大的可伸缩性和简单性。
如果我们必须高速处理种类繁多、数量庞大的大量数据,我们被告知 NoSQL 是唯一的出路。供应商一直在喋喋不休地谈论 SQL 和中间件代码之间的阻抗不匹配。
我们现在发现大多数 NoSQL 供应商在多年贬低连接之后引入了 SQL 层。一些供应商引入了 SQL 的方言,使事情变得更糟。
看起来,在 NoSQL 引入这个 SQL 层是因为害怕像 Google Spanner 这样的新一代数据库,以及提供 JSON、XML 作为一级数据类型的数据库供应商。
Hadoop 呢?
Hadoop 为开发人员提供了 map-reduce 接口,带来了一些巨大的进步,但也带来了许多恐慌。(参见— MapReduce:一个重大的退步— DeWitt 和 Stonebraker )。
使用 map-reduce 在 Hadoop 上进行数据处理,还有很多不足之处。性能调优、处理数据不对称、获得最佳吞吐量,所有这些都需要修改太多的裸机代码。
尝试了多种受 SQL 启发的方法
- Apache Pig:类似 SQL 的语法,FOREACH 代替 FROM,GENERATE 代替 SELECT
- Hive:类似 MySQL 的 SQL-in-Hadoop 语法,将 SQL 转换为 map-reduce
- Drill、Impala、Presto 和 Pivotal 的 HAWQ:Hadoop 上的 SQL,绕过 map-reduce
- Spark SQL:Spark 上的 SQL
- Apache Phoenix:h base 上的 SQL
- Hadoop 作为现有数据库的外部表:Oracle 大数据 SQL、Teradata SQL-H
在经历了许多“大数据年”以及一些 Hadoop 合并和破产之后,我们现在看到了这些技术的幸存者。Hadoop 技术现在更多地存在于云中,而不是本地。现在在组织中很少看到完整的 Cloudera 或 HortonWorks 堆栈。取而代之的是,一些精选的技术蓬勃发展,现在在云数据栈中广泛使用。
数据湖上的 SQL
Stonebraker 很久以前就指出,数据库的性能问题和可伸缩性与 SQL 关系不大,更多的是与数据库本身的设计有关(NoSQL 的讨论与 SQL 无关)。
SQL 的最大优势是它提供了熟悉性和分析数据的表现力。SQL 的健壮性来自关系代数和集合论的基础。
有了数据湖,这就是我们看到的技术。
- Hive metastore 是最受欢迎的数据目录。
- 在 SQL 层中,Presto 作为查询层胜出,并在 Amazon Athena、Google Cloud DataProc、Qubole 中广泛使用。
- Spark 和 Spark SQL 也被广泛使用。
- Hadoop 文件系统(HDFS)用得不多,云存储(Azure Blob、谷歌云存储、AWS S3)更受欢迎,有 CSV、Avro 和 Parquet 文件格式。
云数据仓库和数据湖
原始文件系统上存储的经济性鼓励了数据湖的创建。SQL 用于分析这些数据。
亚马逊红移光谱可以查询 S3 数据。
Snowflake DB 可以使用 VARIANT 列在数据库内部存储 XML、JSON 或 ORC 数据,还可以使用外部表指向 S3 中的数据。
Google BigQuery 和 Azure SQL 数据仓库也支持外部表。
SQL 和 ELT(提取负载转换)
数据处理的 ELT(提取-加载-转换)范式将数据转换步骤放在了最后。首先从源系统中提取并加载到数据库中。
RBAR(逐行处理)的旧的 ETL 方式与关系数据库执行的基于集合的处理形成了直接对比,而基于集合的处理构成了 SQL 的基础。
在 ELT 中,我们现在从源数据库中提取数据,并将其放入数据湖中。
SQL 转换在云数据仓库中或使用 Presto 完成,转换后的数据被加载到目标表中。
通过 GoldenGate、AWS DMS 或使用 Workato/Jitterbit/StitchData 之类的工具或 Kafka 之类的健壮事件管道的涓涓细流都被输入到数据湖或数据仓库中。源系统和装载区之间的转换最小。然后使用 SQL 将这些数据转换并加载到仓库和分析层。
这个 ELT 工具链使用 DAG(有向无环图)工具,如 Apache AirFlow 和无服务器函数,而不是旧的 ETL 工具链的类似 AutoSys 的调度程序。
DBT 是另一个正在转型领域流行的工具。像 FiveTran 和 Matillion 这样的云数据处理工具也使用 SQL 和 ELT。Domo 对 SQL 进行排序以创建转换管道。Looker 基于 LookML 生成 SQL。
参考
- 德威特博士和斯通布雷克博士(2008 年)。MapReduce:一大退步。数据库列, 1 ,23。
- 斯通布雷克,M. (2009 年)。“NoSQL”的讨论与 SQL 无关。ACM 的通信。
机器学习中的数据泄漏
如何防止降低模型质量和/或导致不一致结果的问题
https://media.giphy.com/media/EHcpe9guGONCU/giphy.gif
介绍
当训练机器学习模型时,我们通常会瞄准在某些指标上得分最高的模型,例如准确性。自然地,当我们训练一个在我们的验证或测试数据集上表现很好的模型时,我们选择它作为一个表现良好的模型,并生产/最终确定它。
但是,您是否遇到过这样的情况:一个模型在测试期间表现良好,但在实际使用中却无法达到相同的性能水平?例如,您的模型在测试期间是否达到了 99%的准确性,但是一旦它被生产出来并作用于真实数据,它就无法达到那个性能水平?
测试性能和真实性能之间的这种差异通常可以用一种叫做数据泄漏的现象来解释。
数据泄露
数据泄漏是指机器学习模型的创建者犯下的错误,其中他们意外地在测试和训练数据集之间共享信息。通常,当将数据集划分为测试集和训练集时,目标是确保两者之间没有数据共享。这是因为测试集的目的是模拟真实世界中看不见的数据。然而,当评估一个模型时,我们确实可以完全访问我们的训练集和测试集,所以由我们来确保训练集中没有数据出现在测试集中。
数据泄漏通常会导致测试集的性能达到不切实际的高水平,因为模型是基于它在训练集中已经看到的数据(在某种程度上)运行的。该模型有效地记忆训练集数据,并且能够容易地正确输出那些测试数据集示例的标签/值。显然,这并不理想,因为它误导了评估模型的人。当这种模型用于真正看不见的数据时,性能会比预期的低得多。
数据泄露的原因
现在我将提到一些数据泄漏的常见原因。在训练你自己的模型时,避免这些情况是很重要的。一般来说,您应该避免对您的训练集做任何涉及测试集知识的事情。
预处理
人们犯的一个很常见的错误是在机器学习的数据预处理步骤中泄露信息。重要的是,这些转换只知道训练集,即使它们也应用于测试集。例如,如果您决定将运行 PCA 作为预处理步骤,那么您应该只让 PCA 模型适合训练集。然后,要将它应用到您的测试集,您只需在测试集上调用它的transform
方法(在 scikit-learn 模型的情况下)。相反,如果您在整个数据集上安装您的预处理器,您将从测试集中泄漏信息,因为预处理模型的参数将与测试集的知识相适应。
复制
另一个错误是数据重复,当您的数据集来自嘈杂的真实数据时,这种错误尤其常见。当数据集包含几个具有相同或接近相同数据的点时,会出现这种情况。例如,如果您的数据集包含消息平台上的用户消息,重复的消息可能对应于向许多用户发送相同消息的垃圾邮件发送者。在这种情况下,您可能会遇到数据泄漏,这仅仅是因为您的训练集和测试集可能包含相同的数据点,即使它们可能对应于不同的观察值。这可以通过在分割成训练集和测试集之前消除数据集的重复来解决。您可以通过删除完全重复的内容,或者使用模糊匹配方法(例如通过编辑文本数据的距离)来删除近似匹配的内容。
时态数据(隐式泄漏)
即使您没有明确地泄漏信息,如果您的测试和训练集之间存在依赖关系,您仍然可能会遇到数据泄漏。一个常见的例子是时间数据,即时间是一个相关因素的数据,如时序数据。考虑下面的玩具例子:你的训练集由两个数据点 A 和 C 组成,你的训练集由一个数据点 B 组成。现在,假设这些数据点的时间顺序是 A → B → C 。在这里,我们很可能通过创建训练集和测试集的方式造成了数据泄漏。通过在点 C 上的训练和在点 B 上的测试,我们创建了一个不切实际的情况,在这种情况下,我们根据相对于测试集时间点的未来知识来训练我们的模型。因此,我们已经泄露了信息,因为在现实世界的场景中,我们的模型显然不知道未来。为了解决这个问题,您应该确保您的测试序列分割也是跨时间分割的。因此,训练集中的所有内容都应该出现在测试集中的所有内容之前。这将创建一个更加真实的训练环境,并允许您正确地评估您的模型,就像它正在处理输入的真实世界数据一样。
数据日志:数据的统一抽象
Photo by Alice Donovan Rouse on Unsplash
日志是按时间排序的记录序列。它被配置为允许越来越多的记录被附加到末尾:
日志记录了所有的事情。计算环境中有各种各样的日志:
服务器日志很重要。他们跟踪访问互联网内容和应用的设备。
当您的设备访问一个网站时,托管该网站的服务器会从您的设备获取并保留一系列详细信息,包括设备访问了哪些资源(网页)、设备访问这些资源的时间以及访问这些资源的设备的 IP 地址。
这些日志的标准被称为“通用日志格式”,如下所示:
这可能看起来不多,但从这些日志中,您可以推断出访问资源的设备的配置文件,它如何浏览您的网站,将它们与特定的地理位置联系起来,等等。
这是一个名为“点击流数据”的用户跟踪日志集合。对于脸书、网飞和优步等面向消费者的技术公司而言,点击流日志是它们的命脉。早在 2010 年,脸书就在收集这些数据,并使用 Flume(Hadoop 的开源日志流解决方案)来收集这些数据,并将其传输到各种系统进行分析。每个公司都用日志做东西:优步、Airbnb、网飞,以及几乎每一个电子商务公司。
到目前为止,收集最多日志的组织会胜出,因为从表面上看,研究这些日志可以让他们了解用户在什么时候做了什么,并调整网站以允许用户做更多的事情。
完成更多购买。完成更多的 MOOC 课程。
将免费用户转化为付费用户。
想办法让更多的用户点击“喜欢”按钮。
然后,这些组织可以撰写漂亮的博客文章,介绍他们为收集这些日志而构建的所有数据工程平台,以及他们能够在这些平台上进行分析的数据科学。
真正的幕后赢家是参与处理日志数据的组织。例如,*杰伊的公司,*为 Kafka 提供支持,Kafka 是一种流处理解决方案,在过去五年左右的时间里真正起飞。但是还有数百家公司专门研究点击流处理工具链的每一个组成部分。围绕收集、存储和分析日志数据的需求,整个行业已经发展起来。看看今年的数据就知道了。
所有这些(日志收集、数据科学、工具货币化)对于收集日志的组织和构建工具来收集日志的公司来说都非常令人惊讶,直到最近发生了一些事情。
首先,剑桥分析公司丑闻——不知何故做了不可思议的事,至少改变了部分反对脸书的主流情绪。这意味着媒体最近报道了越来越多关于科技巨头的负面文章,这反过来又导致了立法者的负面抱怨。例如,就在两年前,看到任何人谈论拆分科技巨头都令人难以置信,更不用说作为总统平台的积极组成部分了。
其次,GDPR 登陆了——在欧洲,这是一件大事。谷歌已经因为违反它被罚款了。较小的公司举步维艰。第三方广告和跟踪已关闭。
在美国,除了在人们的收件箱里乱丢通知之外,GDPR 并没有产生太大的影响。但是 CCPA 会。CCPA 是加利福尼亚州的隐私法,将于明年 1 月生效。
该法案是目前各州颁布的最强的隐私立法,在隐私数据方面给予消费者更多的权力。随着各种主要科技巨头总部设在加利福尼亚州,包括谷歌和脸书(这两家公司最近都遭受了数据泄露), AB 375 准备对数据隐私产生深远的影响。 AB 375 将于 2020 年 1 月 1 日全面生效。
届时,在加州运营的公司基本上必须能够完全告知消费者他们在收集什么,并允许他们通过删除所有数据来选择退出。这意味着删除成千上万的日志,并弄清楚如何重新搭建日志收集系统的平台,以便能够删除数据。
CCPA 的天才之处在于,如果一个大型组织在加州运营,那么它很可能在其他各州也有运营。天哪,很难在州/辖区级别分离混合的日志数据,这意味着要么公司将迁移其总部,要么必须遵守 CCPA 对其所有数据的更严格的法规。
日志是个有趣的东西——一方面,它们非常有用。另一方面,因为它们被设计成指数级增长,永远不会减少,而且它们似乎无处不在,就像你无法摆脱的面包屑。跟踪、存储、清理、绑定到其他数据,以及同样重要的用于数据科学目的的采样,都是一个巨大的麻烦。
CCPA 本质上给这个日志存储和分析系统带来了压力。
在我看来,我们将要看到的结果是,收集更多的日志是不好的。保留的越多,要删除的就越多。你就越需要回馈给顾客。GDPR 揭露的这类违规行为的责任就越大。
公司和工程师仍然在谈论收集和分析日志的复杂方法,黑客新闻充满了围绕分布式流收集和分析系统的讨论。但是,主流媒体开始谈论一些其他的东西——日志收集如何在社交上影响我们,以及如何解散从事这种日志收集的科技公司。
日志还不是一种责任形式,但很快就会成为。正是这一点,比任何复杂的流架构都更值得公司认真思考。
这里的问题(从我作为一名付费数据科学家的角度来看)是——这对数据科学意味着什么?迄今为止,数据科学的迅猛发展一直基于解码日志以获取用户行为的艺术。这是否意味着数据科学以及支持它的工具生态系统正在消失?
我不这么认为,但我认为数据科学在未来五到十年的发展将与前十年有根本的不同。
如果数据科学的第一个十年是关于收集和分析一切,那么第二个十年将是关于如何对收集和分析的数据进行深思熟虑和有选择性的处理。*
我想在这里提两个思路作为起点。采样的艺术,以及删除和隐藏用户数据的艺术。
首先是抽样——早在 2000 年,Jakob Nielsen 就在一篇令人惊讶的、非常被低估的文章中谈到了为什么只需要五个用户来执行测试。乍一看,这似乎有些疯狂。你怎么可能推断出脸书的 10 亿用户,在地理、经济和种族上的多样性,会在网站上做什么呢?我不知道五个是否足够,但这篇文章背后的指导原则是,一旦用户超过一定数量,你收集的数据只是额外的噪音,这是正确的。真正的挑战将是如何收集足够的数据,使其在统计上有效,而不是多收集一个日志。
其次,删除和隐藏数据的能力将变得更加重要——我还没有看到任何关于如何正确配置系统以增量方式删除数据的讨论。但是这将变得非常重要,因为,如果你从不收集它,你就永远不能放弃这些数据。Snapchat 的想法是正确的,我(乐观地)期待更多短暂的数据收集工具出现。
我实际上看到更多的是围绕类似于差分隐私的讨论,或者在使用用户数据进行统计分析时隐藏用户数据的做法——在谷歌(谷歌在这方面有很大的既得利益)正在真正起飞。差分隐私本质上是将白噪声——虚假数据——添加到真实数据集中,直到真实数据在统计上仍然有效,但你无法从中推断出任何一个真实用户。
随着 CCPA 的到来和组织开始处理日志问题,请继续关注。
数据管理策略:简介
你想知道的关于它和它的主要演员的一切
Picture from Unsplash
介绍
这一系列文章的目标是清楚地了解实施数据管理计划的好处、需求和挑战。
数据管理项目将是横向的,并将联系组织的不同部门。一个主要的挑战是让所有的业务信息都可用。
需要指出的是,数据管理方法关注的是应该做什么,而不是如何做。数据管理经理管理这些变化,但他们不是执行这些变化的人。
即便如此,他们在这种类型的项目中,尤其是在数据治理中,将会扮演非常重要的角色。他们应该行动起来,并被视为推动数字化之旅的领导者
在本系列结束时,您将能够理解与数据管理相关的主要概念,即:
- 政府
- 体系结构
- 质量
- 安全性
- 建模
- 主数据
在这些概念中,我们将从以下角度探讨基本观点:
- 相关人员(组织)
- 流程(活动)
- 技术(技术解决方案在每个阶段必须具备的最低要求)
在第一篇文章中,我们将重点关注开发结构良好的数据管理策略背后的一般概念和动机,这是组织内数字化之旅的关键组成部分。
为什么是数据管理?
近年来,所有组织中的数据都出现了巨大的增长。数据已经成为许多公司竞争力、生产力、增长和创新的基础。脸书、亚马逊、Spotify 和网飞是我们可以思考的几个例子,由于其数据战略,它们已经彻底改变了这个行业。
公司运营系统中不断增长的数据量以及互联网、社交媒体和多媒体的出现,正在引发一场对客户及其偏好和需求的知识的革命。以及深入了解公司的内部流程,因为我们现在能够清楚地跟踪和监控哪些部分表现良好,更重要的是,哪些部分表现不佳。
如此庞大的数据量将我们置于一个特殊的环境中,在这个环境中,数据管理成为一个基本部分,因为数据已经成为公司的资产。
目前,数据管理是组织中的优先事项,并且为了满足公司的战略目标,拥有高质量的公司信息数据变得比以往任何时候都更加必要。
数据管理意味着整个公司在数据定义和管理方面的策略、角色、流程和职责的定义。有效的数据治理模型需要一个完整的结构来促进技术和业务之间的协作。
了解数据治理在所有组织中的重要性及其对业务信息整体愿景的影响非常重要。
此外,了解在定义有效的数据治理时要考虑的关键因素,以及了解实现数据治理技术的技术和方法方面也是至关重要的。
数据管理的目标是通过数据治理增加组织数据的价值。
新知识领域
在过去的几年里,我们经历了与数据科学相关的技术的兴起,其中一些是:
数据工程
数据工程的重点是建立适当的基础设施,以促进组织内部的数据流动,并使这些数据准备成为有用的格式。
数据分析
数据分析侧重于从数据中发现有用的信息。数据科学的这一分支涉及对数据的描述和诊断分析,解释发生了什么以及为什么会发生。它还涉及数据可视化方面(这是一个完全独立的领域)
机器学习
机器学习是专注于让计算机从数据中学习的科学(和艺术)。他们通过学习导致特定结果的过去数据的特定特征之间的相关性来做到这一点,因此当向他们提供新数据时,他们可以做出准确的预测。
深度学习
深度学习是机器学习的一个子领域,专注于复制智能生物用于学习的学习机制。他们通过用简单的概念解构复杂的概念来做到这一点,因此,以一种分层的方式学习。使用人工神经网络来实现这一点。
由于已经获得的技术和实时数据处理能力,这些知识领域已经改变了游戏规则。我们在更短的时间内从更多的来源获得了更多的数据。此外,计算能力的民主化使我们能够跟上这些数据的处理,这要归功于亚马逊网络服务、谷歌云平台和 Azure(仅举几例)等技术。
基础设施开发不再是不可能完成的任务,新的挑战是从这些数据中获取价值。定义生成哪些模型来从中提取商业价值。
数据可以从社交网络、传感器、移动设备中提取…为了让这些经过处理的信息对我们有利,我们必须开发分析技术和数据管理,以提供公司信息的 360 度视角。
这将通过我们组织中的数据治理计划来实现。
谁将领导这项倡议?
Gartner 的一项调查发现了组织中的一个新人物,即 CDO 或首席数据官。
这种 CDO 是变革的代理,旨在提高数据的价值。数据的存在是为了提取商业价值和改进决策。这些角色属于组织和创新的最高管理层。CDO 将负责所有数据治理,并为组织的数字化转型做好准备,这将涉及数据的集成,以前这些数据是分散的。
CDO 的任务是:
- 定义数据治理
- 让整个组织做好准备并参与进来,以拓展数据文化。
CDO 将通过确保数据是高质量信息的来源并执行所有决策以使信息可信来协助决策。
尽管目前他们的角色还没有完全定义,但是在几年后,不应用数据治理技术的组织将会很少,并且肯定会比那些应用它们的组织处于明显的劣势。
什么是数据管理?
它是定义有效的方法,以便信息在我们需要它的地方,在我们需要它的时候,并且具有我们需要的特征。
数据治理是管理层和 IT 部门的共同责任。
数据治理需要持续的改进和发展。为此,它使用了最佳实践框架。
企业数据管理是关于有效管理整个数据生命周期。我们从捕获、存储、转换、不同系统之间的移动以及数据的用途来说。
定义数据治理模型对公司来说是必要的,这是客户所期望的,也是政府所要求的。这是一个必须解决的需要。
这是一个循环过程,需要不断确保数据的质量。
DAMA 框架
这是管理数据管理的拟议参考框架。DAMA 是一个监督 DM 结构的国际组织。这是数据管理良好实践的汇编。它确定了成功数据管理的 11 项功能
Source: DAMA International
- 数据架构
- 数据建模和设计
- 数据存储和操作
- 数据安全
- 数据集成和互操作性
- 文档和内容管理
- 主数据和参考
- 数据仓库和商业智能
- [计]元数据
- 数据质量
这些功能将被浓缩为以下几个,以便有一个更加实用和灵活的方法:
Figure by Author
数据管理策略中使用了哪些技术?
数据管理计划中使用的技术选择将根据每个组织的特定需求和基础架构而有所不同。然而,一些最常见和最常用的技术是:
- 数据库 : Oracle Database 12c 和 PostgreSQL
- 建模:使用 SQL Developer 的数据建模器
- 数据质量 : Talend 准备和 Trifacta 牧马人
- 数据集成 : Oracle 数据集成器和 Talend 数据集成
在接下来的文章中,我们将深入其中的每一个领域,了解谁是主要参与者,以及在数据管理之旅的每一步中使用的最佳实践和技术。
你可以在下面找到该系列文章的链接。
最后的话
如果你喜欢这篇文章,那么你可以看看我关于数据科学和机器学习的其他文章 这里 。
如果你想了解更多关于机器学习、数据科学和人工智能的知识 请关注我的 Medium ,敬请关注我的下一篇帖子!
数据管理策略:第 1 部分
数据治理和元数据管理
Picture from Unsplash
介绍
这是一系列文章的第 1 部分,这些文章涉及在一个有抱负的数字组织中执行和实施成功的数据管理策略。
你可以在这里找到这个系列的介绍。
在本文中,我们将关注以下主题:
- 数据治理
- 元数据管理
这些是每个数据管理计划的关键方面,我们将深入讨论每一个方面。具体来说,我们将从以下几个方面来探讨这些问题:
- 相关人员(组织)
- 流程(活动)
- 技术(技术解决方案在每个阶段必须具备的最低要求)
所以,事不宜迟,让我们投入进去吧!
数据治理
数据治理是数据管理策略中最基本的功能,因为它是其他功能的中心和领导者。
这里,我们应该区分两个经常被误解的概念:
- 数据治理负责定义数据管理策略
- 数据管理是执行既定策略
虽然数据治理是一个技术性较低的功能,但它可以利用元数据和建模工具的力量来定义数据管理的某些方面。这些工具将用于更好地理解将要使用的数据和数据流的整体架构。
根据 DAMA 的说法,数据治理指的是对组织内使用的数据的可用性、可用性、完整性和安全性的一般管理。
数据治理包括:
- 管理机构(理事会)
- 一套标准和政策
- 实施这些标准和政策的计划。
数据治理计划在整个组织中建立流程,以在系统和应用程序中提供标准,例如术语定义和一致的业务规则。
它确定参与需求定义的合适人员,并建立数据标准和数据使用的定义。
数据治理确保在整个组织中定义和应用相同的数据标准和策略。
数据管理的一般原则
为了确保整个企业符合定义的标准,必须建立一个数据治理组织。
数据治理的组织涉及多个级别的业务和技术角色的组合:
- 发起人:为数据治理工作提供领导和资金
- 数据管理委员会:鼓励控制和流程的采用和实施
- 角色:为数据
标准建立角色并明确定义职责;明确定义并发布的标准和政策 - 监督:建立跟踪、审计和报告符合标准和政策的过程。
- 变更控制:建立评估、批准和沟通标准和政策变更的过程。
- 高管支持:确保高管参与并与数据治理计划保持一致。
数据治理流程
Figure by Author
1.数据治理组织的建立
- 确定数据治理计划的执行发起人
- 建立数据治理委员会
- 让数据治理计划的主要利益相关者(数据所有者、管理者、保管者、架构师)参与进来
2.定义标准和数据策略
- 定义数据标准
- 定义数据策略
3.数据标准和政策合规性
- 在整个组织中应用标准和数据策略
4.定义标准和数据策略
- 定期执行审计和控制操作
- 数据治理控制性能的监控和测量。
数据治理的技术工具
元数据支持和数据质量支持工具用于实现数据治理。市场上很少有被认为是特定的工具。
数据治理的一个重要功能是设计可用于实现数据标准和策略的工作流。
另一个重要功能是设计仪表板,用于监控和控制数据治理活动。
Figure by Author
[计]元数据
元数据管理是成功的数据管理策略的另一个关键功能。在彻底讨论之前,让我们先介绍一下元数据的概念及其不同类型:
元数据基本概念:
根据维基百科的定义,元数据是“提供关于其他数据的信息的数据信息”。换句话说,它是关于数据的数据,提供关于该数据的一个或多个方面的信息的数据。
元数据用于总结有助于跟踪和使用数据的基本信息。
作为一个例子,我们可以考虑一个数字图像。它的元数据可以是图像的大小、分辨率、存储位置、生成时间等等。
元数据概念中有两个基本组成部分:数据元素(DE)和关键数据元素(CDE)。
数据元素
数据元素(DE)是由一组属性组成的数据的原子单位:
- 定义
- 识别
- 表现
- 允许值
关键数据元素(CDE)
关键数据元素是对特定业务领域或业务流程的成功至关重要的数据元素。
数据元素成为关键的标准是什么?
- 业务数据对于组织的负责人来说至关重要。
- 关键业务流程数据及其组成部分,例如联系客户。
- 高级业务报告中使用的关键数据。
- 公司重要事物的唯一标识符,如客户 ID。
元数据管理
它涉及管理关于其他数据的数据,如数据模型和结构,而不是内容。它包括管理关于不同模型的数据结构及其关联的信息,例如:
- 词汇表中的商业术语
- 数据逻辑模型或数据库表和列中的属性,以及它们的关联
有业务和技术元数据,下图总结了它们的特征:
Picture by Author
业务元数据
它们从业务使用的角度描述数据元素,包括诸如带有术语和定义、同义词、首字母缩写词、业务规则和职责的业务术语表等信息。我们所说的业务元数据是指:
- 商业术语表和分类
- 商业规则
- 责任
元数据管理中的角色
有几个角色参与其中:
- 业务所有者:最终负责数据的定义、质量和数据价值。他们负责确认数据的使用符合一般数据策略。(数据治理)。他们还负责驱动活动和
数据管理流程。 - 数据管理员:或 Data Stewart 负责数据的运营监控、与整个组织内各领域专家的互动,以及确定标准化、测量和监控数据质量的
方法。它负责确认已经定义了数据标准。并且已经实施了流程和实践 - 技术负责人:是技术专家,最终负责确保来自系统的数据按照定义的数据标准进行管理和使用。包括遵守商业规则、政策和程序。
- **数据保管人:**是负责系统中数据安全管理的技术专家。它负责确认定义的数据标准得到应用。
技术元数据
它们从技术角度描述数据元素,包括逻辑数据模型、源和目标系统、表和字段结构以及系统依赖关系等信息。
操作元数据告知应用程序的轴心:频率、记录帐户、分析的组件和用于审计目的的其他统计数据。
CDE 标准报
技术和业务元数据代表 CDE 标准,这意味着关键数据元素从技术和业务角度得到了充分描述。
CDE 标准也被称为 CDE 的 360 度视角。通过获得 CDE 的 360°视图,为整个组织的数据管理提供了最佳条件,这是数据管理的最终目标。
一旦做到这一点,就有可能回答如下问题:
- CDE 的定义是什么?
- 谁拥有 CDE 的生意?
- CDE 存放在哪里?
- 在哪些报告中使用了 CDE?
- CDE 的最终来源是什么系统?
元数据管理流程
Figure by Author
元数据流程活动涵盖了 DM 中现有人员、流程和技术视角内的流程视角。
1。——辨认 CDE 的
它包括通过与利益相关者的访谈来分析业务需求和确定最相关的 CDE 的活动。
2。-收集 CDE的业务元数据
对于相关的 CDE 定义业务术语,同义词、首字母缩写词、定义和分类法也定义了业务规则,并负责任地确定这些规则。
3。-收集 CDE的技术元数据
对于相关的 CDE,确定数据系统中的 CDE 表示,确定数据源和数据谱系。
4。-创建 CDE 标准(360°视角)
为了让 CDE 创建业务和技术元数据之间的关联,验证 CDE 数据标准。
5。-应用 CDE 标准
确保符合 CDE 标准,以确保管理每个 CDE 并由定义的标准(数据治理)使用。
系统开发的生命周期
指计划、创建、测试和部署信息的过程。
重要的是,来自系统开发生命周期的元数据必须得到定义,并成为元数据功能流程的一部分。
Figure by Author
元数据的技术工具
最低技术要求是:
- 建立和部署集中式元数据存储库的能力。
- 能够通过词汇表的层次结构定义一致的术语、有效定义、有效值和数据域。
- 能够通过数据建模工具、商业智能工具和 ETL 从最流行的数据库管理系统(Oracle、SQLServer、NoSQL)中提取元数据。
- 能够管理来自多个来源和技术的元数据版本。
Figure by Author
结论
这是数据管理策略系列的第 1 部分,在下一篇文章中,我们将讨论数据质量和数据架构的功能。
如果到目前为止你已经喜欢这个系列,不要错过这里的介绍并且不要忘记留下掌声,所以这将激励我继续制作内容并且它将到达更多的人:)
如果你喜欢这个帖子,你可以看看我关于数据科学和机器学习的其他帖子 这里 。
如果你想了解更多关于机器学习、数据科学和人工智能的知识 请在 Medium 上关注我,敬请关注我的下一篇帖子!
数据管理策略:第 3 部分
数据集成、安全性和主数据
Picture from Unsplash
介绍
这是一系列文章的第 3 部分,这些文章涉及在一个有抱负的数字组织中执行和实施成功的数据管理策略。
你可以在这里找到这个系列的介绍。
在本文中,我们将关注以下主题:
- 数据集成
- 数据安全
- 主数据
这些是每个数据管理计划的关键方面,我们将深入讨论每一个方面。具体来说,我们将从以下几个方面来探讨这些问题:
- 相关人员(组织)
- 流程(活动)
- 技术(技术解决方案在每个阶段必须具备的最低要求)
所以,没有进一步的行动,让我们投入进去吧!
数据集成
数据集成是指将数据从源数据系统转移到目标数据系统的过程和技术。在这个过程中,数据被转换成信息以满足业务需求。
这些数据必须可以在需要时从任何来源获得,并具有所需的功能。
数据集成场景— ETL
ETL(提取、转换和加载)指的是数据集成方法,其中数据从源系统中提取,然后经过转换过程,最后加载到目标系统中。
典型的 ETL 场景通常用在数据仓库系统中。
Figure by Author
数据集成场景— ELT
EL-T(提取、加载和转换)指的是数据集成方法,其中数据从源系统中提取,然后不经转换就加载到目标系统中。数据转换稍后在目标系统中执行。ELT 场景是大数据/Hadoop 系统的典型场景。
传统 ETL 架构
- 性能下降
- 成本更高
- 转换硬件
Figure by Author
ODI — ELT 架构
- 更好的性能
- 单负载
- 没有额外的硬件成本
数据集成中的批处理与实时
一批
- 在批处理中,在一次执行中收集一大组事务并处理数据。
- 由于数据量很大,所以必须在资源不太忙的时候执行这个过程(这个步骤通常在晚上进行)。
- 批处理会延迟对数据的访问,需要密切监控,并且数据可能在一段时间内不可用。
- 由于数据访问的延迟,在处理完成之前,知识会丢失。
- 批处理过程中出现的问题会延迟整个过程,因此您需要人员支持来监控它的运行。
实时
- 实时处理按需处理小组事务。
- 实时处理的优势在于,它可以用更少的资源提供对数据运行的即时访问,并提高正常运行时间。
- 借助实时数据集成,您可以在交易发生时了解自己的业务。
- 如果出现错误,可以立即处理。
- 实时处理设计更加复杂。
- 虽然实时处理系统需要更多的努力来设计和实现,但对企业的好处是巨大的。
数据集成角色
数据集成专家主要负责执行与数据集成相关的活动。他们将与业务负责人、数据经理、技术负责人、数据保管人、MDM 专家和数据架构师密切合作。
他的主要职责涉及数据集成应用程序的设计和实现,包括映射规范的定义、数据集成作业的设计和实现…
Figure by Author
数据集成工具
对每个数据集成技术工具的最低要求是:
- 能够执行批处理和实时处理。
- 能够执行数据更改检测(识别修改的记录)。
- 能够执行结构化和非结构化数据的强大转换。
- 整体错误处理操作的能力。
Figure by Author
主数据和参考数据
主数据
主数据指的是在整个组织内符合和共享的数据。例如:客户数据、员工、产品…
参考数据
参考数据是主数据的子集,指的是定义其他数据字段可以使用的一组允许值的数据。例如:国家代码、工业活动分类…
这些数据的功能保证了这些数据的集中管理,这些数据由不同的部门共享。
主数据管理
每个成功的主数据管理都有 3 个关键步骤:
- 识别可能匹配的记录
- 主数据管理应用业务规则来组合和合并记录
- 主数据管理人员创建具有可信属性的主记录
参考数据管理
每个成功的主数据管理都有 3 个关键步骤:
- 参考数据管理确定要搜索的记录
- 参考数据管理为搜索提供参考表
- 参考数据管理根据业务标准更新记录
区分主数据和参考数据的标准是:
Table by Author
主数据和参考数据管理角色
主数据管理(MDM)专家是负责执行与主数据和参考数据管理相关的活动的主要角色。尽管这是一个特定于主数据和参考数据管理的角色,但主数据管理专家与业务所有者、数据管理员、技术所有者和数据保管者密切合作。
MDM 专家的主要职责与 MDM 产品的设计和实现相关(例如,定义 MDM 中的属性、创建 MDM 映射文档等)。
Figure by Author
主数据和参考工具
每个主数据和参考工具必须具备的最低要求是:
- 支持多个领域,如客户、产品、位置和帐户。
- 有效管理领域之间的关系,例如从客户到产品。
- 主数据实体的分类、分组和层次结构。
- 识别重复数据及其级联消除的强大算法。
- 能够根据组织要求轻松配置关键数据元素以识别数据匹配。
- 通过创建单个数据记录或黄金记录,能够配置业务规则以使信息尽可能保持最新。
Figure by Author
数据安全
数据安全(数据保护或数据隐私),是指保护机密信息免受内部和外部未经授权的访问所必需的流程、政策和技术。
机密信息的示例:医疗保健号、出生日期、种族、信用卡号、销售计划…
数据治理指的是如何构建内容的规则。
数据安全指的是如何保护和使用内容的规则。
敏感信息与非敏感信息
非敏感信息
- 公共信息:已经在公共领域的信息(例如,性犯罪者登记和选民登记档案)。
- 常规业务信息:不受任何特殊保护的业务信息,通常可以与公司内外的任何人共享。
敏感信息
- 个人和私人信息:指属于私人的信息,但此人可能出于个人或业务原因选择与他人共享(例如,ss 号码)。
- 商业机密信息:披露后可能影响公司的信息(销售和营销计划)。
- 机密信息:通常是指许多国家政府强制实施的特殊安全法规中的机密信息。
数据安全流程
每个成功的数据安全流程的四个建议步骤是:
- 定义数据安全政策
确定与数据隐私相关的要求,定义数据保护政策,定义数据安全实施指南。
2。提供技术支持
实施适当的技术工具以支持数据保护政策的实施
3。实施数据安全政策
并对人员进行适当培训
4。监督和控制数据安全策略的应用
确保数据保护策略中定义的标准适用于整个组织
数据安全角色
It 是负责实施数据保护策略的关键角色。虽然这一职能专门针对数据安全,但数据隐私官将与所有其他数据管理职能密切合作。
主要职责包括:
- 制定和实施数据安全政策
- 就所有个人数据的处理提供信息和指导。
- 为员工制定“最佳实践”指南。
- 向员工提供培训
- 处理、协调和回应所有信息请求
Figure by Author
数据安全的技术工具
电子邮件保护
- 入站邮件过滤
- 自动过滤和删除垃圾邮件
- B2B 通信的附件和加密分析
杀毒
- 为员工提供互联网接入
- 可在网络中的所有计算机上执行
防火墙
- 提高组织中计算机网络安全性的硬件系统
加密 Wi-Fi
- 如果公司中有 Wi-Fi 网络配置,则必须对网络进行加密,只有授权人员才能使用访问代码进行访问。
云中的数据存储
- 在云端保存和处理文档
- 启用云安全工具,让多个用户能够更轻松地从移动设备或远程位置访问文档和文件。
安全网络访问
- 保护和访问组织中的互联网
- 保护服务器和系统免受黑客攻击非常重要。
结论
这是关于如何在组织中实施成功的数据管理策略的最后一篇文章。如果你喜欢这篇文章,不要错过这里的介绍。
如果你喜欢这篇文章,那么你可以看看我关于数据科学和机器学习的其他文章 这里 。
如果你想了解更多关于机器学习、数据科学和人工智能的知识 请关注我的 Medium ,敬请关注我的下一篇帖子!
数据管理策略:第 2 部分
数据质量和架构
Picture from Unsplash
介绍
这是与在一个有抱负的数字组织中实施和实现成功的数据管理策略相关的系列文章的第 2 部分。
你可以在这里找到这个系列的介绍。
在本文中,我们将关注以下主题:
- 数据质量
- 数据架构
- 数据集成
这些是每个数据管理计划的关键方面,我们将深入讨论每一个方面。具体来说,我们将从以下几个方面来探讨这些问题:
- 相关人员(组织)
- 流程(活动)
- 技术(技术解决方案在每个阶段必须具备的最低要求)
所以,没有进一步的行动,让我们投入进去吧!
数据质量
实现数据质量不是一件容易的事情,特别是当数据来自多个来源、采用不同的技术格式和处于非常不同的环境中时。这是当前大多数组织的现实。
在我们需要的地方、时间和方式拥有它们通常是一个挑战。此外,数据通常是“脏的”:充满错误、遗漏或干扰。这些错误可能意味着信息和电信项目以及公司数据开发的失败。
不幸的是,这个数据层是一个经常被忽视或忽略的关键组件。确保组织中数据的质量、完整性和准确性应该是任何数据管理战略的主要目标之一,因为这是实现战略目标的一个关键因素。
糟糕的数据质量会带来实实在在的经济影响。数据的提取、转换和加载过程(ETL)可能会占用数据项目开发时间的 80%。此外,拥有不能准确代表现实的数据,意味着基于这些数据开发的任何应用程序实际上都是无用的。
出于所有这些原因,理解数据策略这一方面的至关重要性至关重要。你的数据质量就是你从中获得的一切的质量。
数据质量管理
数据质量管理指的是组织使用的方法、政策和流程,以确保公司内系统和数据流中数据的以下一些关键属性。
应对每个关键数据元素或 CDE 提出以下问题,以满足数据质量要求:
- 准确吗?→准确性
- 是否有效?→有效性
- 是最新的吗?→当前
- 完成了吗?→完整性
- 是独一无二的吗?→单一性
- 符合吗?→一致性
并非所有数据质量维度都适用于所有关键数据元素或 CDE(例如,出生日期将定义有效性和完整性维度的数据质量)。
数据质量维度
为了深入探索前面的数据维度,我们应该更全面地定义它们。
数据质量维度指的是可以评估并用于衡量数据质量的数据方面或属性。有 6 个关键维度:
精度
这意味着数据准确地代表了真实世界。例如:拼写错误。
有效期
这意味着数据符合其定义的辛塔克斯(格式、类型和范围)。例如:不正确的客户性别和类型值。
电流
从时间的角度来看,数据代表现实。它们是最新的可用信息。例如:7 月 1 日发生的客户地址变更,并在 7 月 15 日引入系统。
完整性
这意味着就业务重要性而言,数据是完整的。例如:缺少邮政编码的客户地址。
单一性
数据被正确识别并只登记一次。例如:唯一的客户用不同的 id 在数据库中注册了两次。
一致性
数据在整个数据集中以相同的方式表示。例如:删除客户的帐号,但有一个采购订单与该帐户相关联。
数据质量规则
它们是业务规则,目标是确保数据维度在准确性、有效性、完整性、唯一性和一致性方面的合规性。
让我们看一个客户的 CDE 出生日期的例子:
Figure by Author
数据质量过程
Figure by Author
定义 DQ 要求
- 执行数据分析以帮助发现数据频率和格式。
- 可以使用专门的工具或查询语言对数据源(SQL)进行数据分析。
- 数据质量问题可能在分析过程中被发现,但是分析的目的是发现用于数据质量评估的信息。
DQ 评价
- 为准确性、有效性、完整性等定义数据质量规则。以及质量阈值。
- 通过遵守现有数据集中的数据质量规则来执行数据质量评估。
- 识别数据质量问题并更新问题记录。
DQ 问题求解
- 对于在数据质量评估期间发现的问题,执行根本原因分析(RCA)以确定问题的根本原因。
- 通过消除问题的根本原因来解决问题。
- 如有必要,审查数据策略和程序。
DQ 监控
定义和开发数据质量 KPI 仪表板,以执行数据的跟踪和监控。
数据质量的主要角色
数据质量分析师代表数据质量的关键角色,负责执行与数据质量流程相关的活动。
虽然它是唯一的特定数据质量角色,但它将与业务所有者、数据管理者、技术所有者和数据保管者密切合作。
除其他外,其职能包括定义数据质量规则、分析结果、分析、评价、调查数据质量问题的原因等。
Figure by Author
确保数据质量的技术工具
最低要求是:
- 能够执行数据分析,包括数据集的统计分析。
- 能够为关键数据的质量控制定义和执行数据质量规则。
- 存储数据质量评估和结果的能力。
- 执行解决和发现问题过程的能力。
- 能够创建和可视化数据质量记分卡。
Figure by Author
数据架构
数据架构指的是模型、策略、规则或标准,这些模型、策略、规则或标准控制着收集什么数据,如何在组织的系统中存储、组织和使用这些数据。它涵盖了每个功能如何适应整体数据管理框架。
Figure by Author
数据架构角色
数据架构师主要负责设计数据架构。尽管这个角色特定于数据架构,但是数据架构师将与所有其他数据管理角色密切合作。
这个角色的主要职责包括跨数据架构层设计和优化数据架构。
数据架构师还提出支持企业架构和数据管理功能所需的技术。
Figure by Author
结论
这就是数据管理策略系列的第 2 部分。我们将在下一篇文章中继续探索更多关于数据架构和主要数据集成工具的内容。
如果你已经喜欢这个系列,不要错过这里的介绍。
如果你喜欢这篇帖子,那么你可以看看我在数据科学和机器学习方面的其他帖子。
如果你想了解更多关于机器学习、数据科学和人工智能的知识 在 Medium 上关注我 ,敬请关注我的下一篇帖子!
熊猫机器学习的数据处理
熊猫提供的用于机器学习项目的一些数据工具的介绍
Photo by Michael Fenton on Unsplash
python 熊猫库是一个开源项目,提供了各种易于使用的数据操作和分析工具。在实际建立任何模型之前,任何机器学习项目都必须花费大量时间来准备数据,分析基本趋势和模式。在接下来的文章中,我想简单介绍一下 pandas 中的各种工具,这些工具用于在开始建模之前处理、清理、转换和分析数据。
在整篇文章中,我将使用来自 drivendata.org 的数据集这里。这也可以从克利夫兰心脏病数据库下载。训练数据包括两个单独的 csv 文件,一个包含关于许多患者的特征,第二个包含二进制标签“heart_disease_present ”,其表示患者是否患有心脏病。
导入数据
Pandas 提供了从各种来源读取数据的工具。因为我使用的数据集是一个 csv 文件,所以我将使用 read_csv 函数。这个函数有大量的选项用于解析数据。对于大多数文件来说,默认选项很好——这里就是这种情况。
import pandas as pdtrain_values = pd.read_csv('train_values.csv')
train_labels = pd.read_csv('train_labels.csv')
为了分析数据,我需要将 train_values 和 train_labels 合并到一个数据帧中。Pandas 提供了一个合并功能,可以连接列或索引上的数据帧。在下面的代码中,我使用 patient_id 执行内部合并,将正确的值与正确的标签连接起来。
train = pd.merge(train_values, train_labels, left_on='patient_id', right_on='patient_id', how='inner')
缺失数据
Pandas 提供了许多处理缺失数据的功能。首先,我们可以使用isna()
函数来了解我们的数据中有多少缺失值。
它的基本功能是查看每一行和每一列中的每一个值,如果缺少就返回True
,如果没有就返回false
。因此,我们可以编写一个函数,返回每一列中缺失值的分数。
train.apply(lambda x: sum(x.isna()/len(train)))
在该数据集中,实际上不存在任何缺失值。但是,如果有,我们可以使用DataFrame.fillna()
替换为另一个值,或者使用DataFrame.dropna()
删除包含缺失值的行。
使用fillna()
时,你有很多选择。您可以用静态值替换,该值可以是字符串或数字。您也可以用平均值之类的计算来替换。根据数据类型和丢失值的数量,很可能必须对不同的列使用不同的策略。在下面的代码中,我演示了如何使用其他一些方便的熊猫函数,select_dtypes
和DataFrame.columns
,只用平均值填充数值。
train[train.select_dtypes(include=['int64', 'float64']).columns] = train[train.select_dtypes(include=['int64', 'float64']).columns].apply(lambda x:x.fillna(x.mean()))
可视化数据
在熊猫身上绘图并不特别,但是如果你想从数据中快速识别一些趋势,这通常是最有效的方法。
基本的绘图功能只是在系列或数据帧上调用plt.plot()
。pandas 中的绘图引用了 matplotlib API,因此您需要首先导入 matplotlib 来访问它。该功能支持许多不同的可视化类型,包括线形图、条形图、直方图、箱线图和散点图。pandas 中的绘图功能真正有用的地方是当您将它与其他数据聚合功能结合使用时。下面我举几个例子。
将value_counts()
与柱状图选项结合使用,可快速显示分类特征。在下面的代码中,我用这种方法查看了 thal(流向心脏的血液量)的分布。
import matplotlib.pyplot as plt
% matplotlib inlinetrain['thal'].value_counts().plot.bar()
使用 groupby 函数,我们可以通过峰值运动 st 段斜率来绘制平均静息血压。
train.groupby("slope_of_peak_exercise_st_segment")['resting_blood_pressure'].mean().plot(kind='bar')
Pandas 数据透视表也可以用来提供聚合数据的可视化。在这里,我比较了胸痛类型的平均血清胆固醇毫克每分升,以及与心脏病的关系。
import numpy as nppd.pivot_table(train, index='chest_pain_type', columns= 'heart_disease_present', values= "serum_cholesterol_mg_per_dl", aggfunc=np.mean).plot(kind= 'bar')
特征转换
Pandas 还有许多功能,可用于您可能需要进行的大多数功能转换。
例如,最常用的机器学习库要求数据是数值型的。因此,有必要转换任何非数字特征,一般来说,最好的方法是使用热编码。熊猫对此有一种方法叫做get_dummies
。该函数在应用于一列数据时,会将每个唯一值转换为一个新的二进制列。
train = train.drop('patient_id', axis=1)
train = pd.get_dummies(train, columns=train.select_dtypes('object').columns)
可能需要为机器学习转换特征的另一种方式是宁滨。这个数据集中的一个例子是年龄特征。将年龄分组到模型要学习的范围(或箱)中可能更有意义。熊猫还有一个功能pd.cut
可以用来做这个。
bins = [0, 30, 40, 50, 60, 70, 100]
train['age_group'] = pd.cut(train['age'], bins)
train['age_group'].value_counts().plot(kind='bar')
这只是对 pandas 中用于机器学习项目早期阶段的一些功能的介绍。数据操作和分析以及熊猫图书馆本身还有很多方面。这通常是一个非常耗时的阶段,我发现 pandas 提供了各种各样的功能和工具,可以帮助提高这个过程的效率。
R 中的数据操作
查看 R 中操作数据的主要函数,例如如何对数据框进行子集化、创建新变量、记录分类变量和重命名变量
Photo by Campaign Creators
介绍
并非所有数据框都像您预期的那样整洁。因此,在将数据集导入 RStudio 后,大多数情况下,您需要在执行任何统计分析之前准备好数据集。当数据质量很差时,数据处理有时甚至会比实际分析花费更长的时间。
数据操作包括广泛的工具和技术。我们在这里详细介绍了您在 r 中的项目最有可能需要的操作。如果您发现其他数据操作很重要,以便我可以添加它们,请不要犹豫让我知道(例如作为本文结尾的评论)。
在本文中,我们展示了在 r 中操作数据的主要函数。我们首先在向量、因子和列表上说明这些函数。然后我们举例说明在 r 中操作数据帧和日期/时间的主要函数。
向量
串联
我们可以用c()
连接(即组合)数字或字符串:
c(2, 4, -1)## [1] 2 4 -1c(1, 5 / 6, 2^3, -0.05)## [1] 1.0000000 0.8333333 8.0000000 -0.0500000
请注意,默认情况下,R 显示 7 位小数。可以用options(digits = 2)
(两位小数)修改。
也可以创建一系列连续的整数:
1:10## [1] 1 2 3 4 5 6 7 8 9 10# is the same than
c(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)## [1] 1 2 3 4 5 6 7 8 9 10# or
c(1:10)## [1] 1 2 3 4 5 6 7 8 9 10
seq()
和rep()
seq()
允许制作一个由序列定义的向量。您可以选择增量:
seq(from = 2, to = 5, by = 0.5)## [1] 2.0 2.5 3.0 3.5 4.0 4.5 5.0
或者它的长度:
seq(from = 2, to = 5, length.out = 7)## [1] 2.0 2.5 3.0 3.5 4.0 4.5 5.0
另一方面,rep()
创建一个向量,它是数字或字符串的重复:
rep(1, times = 3)## [1] 1 1 1rep(c("A", "B", "C"), times = c(3, 1, 2))## [1] "A" "A" "A" "B" "C" "C"
您也可以创建一个数字和字符串重复的向量:
rep(c("A", 2, "C"), times = c(3, 1, 2))## [1] "A" "A" "A" "2" "C" "C"
但是在这种情况下,数字 2 也将被视为一个字符串(而不是一个数字),因为向量中至少有一个字符串。
分配
在 R 中有三种分配对象的方法:
<-
=
assign()
# 1st method
x <- c(2.1, 5, -4, 1, 5)
x## [1] 2.1 5.0 -4.0 1.0 5.0# 2nd method
x2 <- c(2.1, 5, -4, 1, 5)
x2## [1] 2.1 5.0 -4.0 1.0 5.0# 3rd method (less common)
assign("x3", c(2.1, 5, -4, 1, 5))
x3## [1] 2.1 5.0 -4.0 1.0 5.0
也可以将一个向量指定给另一个向量,例如:
y <- c(x, 10, 1 / 4)
y## [1] 2.10 5.00 -4.00 1.00 5.00 10.00 0.25
向量的元素
我们可以通过在方括号中指定向量的位置来选择向量的一个或多个元素:
# select one element
x[3]## [1] -4# select more than one element with c()
x[c(1, 3, 4)]## [1] 2.1 -4.0 1.0
注意,在 R 中,索引的编号从 1 开始(不像其他编程语言那样从 0 开始),所以x[1]
给出了向量x
的第一个元素。
我们也可以使用布尔值(即TRUE
或FALSE
)来选择向量的一些元素。该方法仅选择与TRUE
相对应的元素:
x[c(TRUE, FALSE, TRUE, TRUE, FALSE)]## [1] 2.1 -4.0 1.0
或者我们可以把元素撤回来:
x[-c(2, 4)]## [1] 2.1 -4.0 5.0
类型和长度
向量的主要类型有数字、逻辑和字符。关于每种类型的更多细节,参见 R 中不同的数据类型。
class()
给出矢量类型:
x <- c(2.1, 5, -4, 1, 5, 0)
class(x)## [1] "numeric"y <- c(x, "Hello")
class(y)## [1] "character"
正如您在上面看到的,只有当 vector 的所有元素都是数字时,它的类才会是数字。只要一个元素是一个字符,向量的类就是一个字符。
z <- c(TRUE, FALSE, FALSE)
class(z)## [1] "logical"
length()
给出一个向量的长度:
length(x)## [1] 6
所以要选择一个向量的最后一个元素(以动态的方式),我们可以使用length()
和[]
的组合:
x[length(x)]## [1] 0
寻找向量类型
我们可以用is.type
函数族找到向量的类型:
is.numeric(x)## [1] TRUEis.logical(x)## [1] FALSEis.character(x)## [1] FALSE
或者用更通用的方式使用is()
功能:
is(x)## [1] "numeric" "vector"
类型和长度的修改
我们可以用as.numeric()
、as.logical()
和as.character()
功能改变矢量的类型:
x_character <- as.character(x)
x_character## [1] "2.1" "5" "-4" "1" "5" "0"is.character(x_character)## [1] TRUEx_logical <- as.logical(x)
x_logical## [1] TRUE TRUE TRUE TRUE TRUE FALSEis.logical(x_logical)## [1] TRUE
也可以改变它的长度:
length(x) <- 4
x## [1] 2.1 5.0 -4.0 1.0
如你所见,向量的第一个元素是守恒的,而所有其他元素都被移除了。在本例中,第一个 4 是因为我们指定了长度 4。
数值运算符
基本数值运算符如+
、-
、*
、/
和^
可以应用于向量:
x <- c(2.1, 5, -4, 1)
y <- c(0, -7, 1, 1 / 4)x + y## [1] 2.10 -2.00 -3.00 1.25x * y## [1] 0.00 -35.00 -4.00 0.25x^y## [1] 1.00e+00 1.28e-05 -4.00e+00 1.00e+00
也可以计算矢量的最小、最大、和、积、累积和以及累积积:
min(x)## [1] -4max(x)## [1] 5sum(x)## [1] 4.1prod(x)## [1] -42cumsum(x)## [1] 2.1 7.1 3.1 4.1cumprod(x)## [1] 2.1 10.5 -42.0 -42.0
也可以应用以下数学运算:
sqrt()
(平方根)cos()
(余弦)sin()
(正弦)tan()
(相切)log()
(对数)log10()
(以 10 为底的对数)exp()
(指数型)abs()
(绝对值)
cos(x)## [1] -0.5048461 0.2836622 -0.6536436 0.5403023exp(x)## [1] 8.16616991 148.41315910 0.01831564 2.71828183
如果需要四舍五入,可以使用round()
、floor()
和ceiling()
功能:
round(cos(x), digits = 3) # 3 decimals## [1] -0.505 0.284 -0.654 0.540floor(cos(x)) # largest integer not greater than x## [1] -1 0 -1 0ceiling(cos(x)) # smallest integer not less than x## [1] 0 1 0 1
逻辑运算符
R 中最常见的逻辑运算符是:
- 否定:
!
- 比较:
<
、<=
、>=
、>
、==
(相等)、!=
(不同) - 还有:
&
- 或者:
|
x## [1] 2.1 5.0 -4.0 1.0x <= c(1, 6, 3, 4)## [1] FALSE TRUE TRUE TRUEx <= 1## [1] FALSE FALSE TRUE TRUE(x == 1 | x > 4)## [1] FALSE TRUE FALSE TRUE!(x == 1 | x > 4)## [1] TRUE FALSE TRUE FALSE
all()
和any()
顾名思义,如果所有元素都满足条件,all()
将返回TRUE
,而如果 vector 的任何元素都满足条件,any()
将返回TRUE
:
x## [1] 2.1 5.0 -4.0 1.0x <= 1## [1] FALSE FALSE TRUE TRUEall(x <= 1)## [1] FALSEany(x <= 1)## [1] TRUE
字符串向量上的操作
您可以将至少两个向量粘贴在一起:
code <- paste(c("BE", "BE", "FR", "EN", "BE"), 1:5, sep = "/")
code## [1] "BE/1" "BE/2" "FR/3" "EN/4" "BE/5"
参数sep
代表separator
,允许指定用于分隔每个字符串的字符或符号。
如果不想指定分隔符,可以使用sep = ""
或paste0()
功能:
paste(c("BE", "BE", "FR", "EN", "BE"), 1:5, sep = "")## [1] "BE1" "BE2" "FR3" "EN4" "BE5"paste0(c("BE", "BE", "FR", "EN", "BE"), 1:5)## [1] "BE1" "BE2" "FR3" "EN4" "BE5"
要找到包含给定字符串的元素的位置,使用grep()
函数:
grep("BE", code)## [1] 1 2 5
为了根据开始和结束位置提取字符串,我们可以使用substr()
函数:
substr(code,
start = 1,
stop = 3
) # extract characters 1 to 3## [1] "BE/" "BE/" "FR/" "EN/" "BE/"
使用sub()
功能,用另一个字符串替换向量中存在的字符串:
sub(
pattern = "BE", # find BE
replacement = "BEL", # replace it with BEL
code
)## [1] "BEL/1" "BEL/2" "FR/3" "EN/4" "BEL/5"
使用strsplit()
功能根据特定符号分割字符串:
strsplit(c("Rafael Nadal", "Roger Federer", "Novak Djokovic"),
split = " "
)## [[1]]
## [1] "Rafael" "Nadal"
##
## [[2]]
## [1] "Roger" "Federer"
##
## [[3]]
## [1] "Novak" "Djokovic"strsplit(code,
split = "/"
)## [[1]]
## [1] "BE" "1"
##
## [[2]]
## [1] "BE" "2"
##
## [[3]]
## [1] "FR" "3"
##
## [[4]]
## [1] "EN" "4"
##
## [[5]]
## [1] "BE" "5"
要将字符向量转换为大写和小写:
toupper(c("Rafael Nadal", "Roger Federer", "Novak Djokovic"))## [1] "RAFAEL NADAL" "ROGER FEDERER" "NOVAK DJOKOVIC"tolower(c("Rafael Nadal", "Roger Federer", "Novak Djokovic"))## [1] "rafael nadal" "roger federer" "novak djokovic"
顺序和向量
我们可以从最小到最大或者从最大到最小对向量的元素进行排序:
x <- c(2.1, 5, -4, 1, 1)
sort(x) # smallest to largest## [1] -4.0 1.0 1.0 2.1 5.0sort(x, decreasing = TRUE) # largest to smallest## [1] 5.0 2.1 1.0 1.0 -4.0
order()
给出应用于向量的排列,以便对其元素进行排序:
order(x)## [1] 3 4 5 1 2
可以看到,向量的第三个元素最小,第二个元素最大。这由输出开始时的 3 和输出结束时的 2 表示。
像sort()
一样,也可以添加decreasing = TRUE
参数:
order(x, decreasing = TRUE)## [1] 2 1 4 5 3
在这种情况下,输出中的 2 表示向量的第二个元素最大,而 3 表示第三个元素最小。
rank()
给出了元素的等级:
rank(x)## [1] 4.0 5.0 1.0 2.5 2.5
向量的最后两个元素的秩为 2.5,因为它们是相等的,并且它们在第一个秩之后但在第四个秩之前。
我们也可以颠倒元素(从最后一个到第一个):
x## [1] 2.1 5.0 -4.0 1.0 1.0rev(x)## [1] 1.0 1.0 -4.0 5.0 2.1
因素
R中的因子是具有一系列级别的向量,也称为类别。因素对于定性数据很有用,如性别、公民身份、眼睛颜色等。
创造因素
我们用factor()
函数创建因子(不要忘记c()
):
f1 <- factor(c("T1", "T3", "T1", "T2"))
f1## [1] T1 T3 T1 T2
## Levels: T1 T2 T3
我们当然可以从现有的向量中创建一个因子:
v <- c(1, 1, 0, 1, 0)
v2 <- factor(v,
levels = c(0, 1),
labels = c("bad", "good")
)
v2## [1] good good bad good bad
## Levels: bad good
我们还可以通过添加ordered = TRUE
参数来指定级别的顺序:
v2 <- factor(v,
levels = c(0, 1),
labels = c("bad", "good"),
ordered = TRUE
)
v2## [1] good good bad good bad
## Levels: bad < good
请注意,级别的顺序将遵循在labels
参数中指定的顺序。
性能
要了解级别的名称:
levels(f1)## [1] "T1" "T2" "T3"
对于级别数:
nlevels(f1)## [1] 3
在 R 中,第一级始终是参考级。该参考水平可通过relevel()
进行修改:
relevel(f1, ref = "T3")## [1] T1 T3 T1 T2
## Levels: T3 T1 T2
您会看到“T3”现在是第一个,因此也是参考电平。更改参考级别会影响它们在统计分析中的显示或处理顺序。例如,将箱线图与不同的参考电平进行比较。
处理
要了解每个级别的频率:
table(f1)## f1
## T1 T2 T3
## 2 1 1# or
summary(f1)## T1 T2 T3
## 2 1 1
请注意,相对频率(即比例)可通过组合prop.table()
和table()
或summary()
找到:
prop.table(table(f1))## f1
## T1 T2 T3
## 0.50 0.25 0.25# or
prop.table(summary(f1))## T1 T2 T3
## 0.50 0.25 0.25
记住,一个因子在 R 中被编码为一个数字向量,即使它看起来像一个字符向量。我们可以用as.numeric()
函数将一个因子转换成它的等值数字:
f1## [1] T1 T3 T1 T2
## Levels: T1 T2 T3as.numeric(f1)## [1] 1 3 1 2
用as.factor()
或factor()
函数可以将数值向量转换成因子:
num <- 1:4
fac <- as.factor(num)
fac## [1] 1 2 3 4
## Levels: 1 2 3 4fac2 <- factor(num)
fac2## [1] 1 2 3 4
## Levels: 1 2 3 4
factor()
的优点是可以为每个级别指定一个名称:
fac2 <- factor(num,
labels = c("bad", "neutral", "good", "very good")
)
fac2## [1] bad neutral good very good
## Levels: bad neutral good very good
列表
列表是一个向量,它的元素可以有不同的性质:向量、列表、因子、数字或字符等。
创建列表
功能list()
允许创建列表:
tahiti <- list(
plane = c("Airbus", "Boeing"),
departure = c("Brussels", "Milan", "Paris"),
duration = c(15, 11, 14)
)
tahiti## $plane
## [1] "Airbus" "Boeing"
##
## $departure
## [1] "Brussels" "Milan" "Paris"
##
## $duration
## [1] 15 11 14
处理
有几种方法可以从列表中提取元素:
tahiti$departure## [1] "Brussels" "Milan" "Paris"# or
tahiti$de## [1] "Brussels" "Milan" "Paris"# or
tahiti[[2]]## [1] "Brussels" "Milan" "Paris"# or
tahiti[["departure"]]## [1] "Brussels" "Milan" "Paris"tahiti[[2]][c(1, 2)]## [1] "Brussels" "Milan"
要将列表转换为向量:
v <- unlist(tahiti)
v## plane1 plane2 departure1 departure2 departure3 duration1 duration2
## "Airbus" "Boeing" "Brussels" "Milan" "Paris" "15" "11"
## duration3
## "14"is.vector(v)## [1] TRUE
获取对象的详细信息
attributes()
给出元素的名称(它可以用在每个 R 对象上):
attributes(tahiti)## $names
## [1] "plane" "departure" "duration"
str()
给出关于元素的简短描述(也可用于每个 R 对象):
str(tahiti)## List of 3
## $ plane : chr [1:2] "Airbus" "Boeing"
## $ departure: chr [1:3] "Brussels" "Milan" "Paris"
## $ duration : num [1:3] 15 11 14
数据帧
R 中每个导入的文件都是一个数据帧(至少如果你不使用包将你的数据导入 R )。数据框是列表和矩阵的混合:它具有矩阵的形状,但是列可以有不同的类。
记住,数据帧的黄金标准是:
- 列代表变量
- 线对应于观察值和
- 每个值必须有自己的单元格
Structure of a data frame. Source: R for Data Science by Hadley Wickham & Garrett Grolemund
在本文中,我们使用数据框架cars
来说明主要的数据操作技术。请注意,数据框是默认安装在 RStudio 中的(因此您不需要导入它),我在整篇文章中使用通用名称dat
作为数据框的名称(参见此处的为什么我总是使用通用名称而不是更具体的名称)。
以下是整个数据框:
dat <- cars # rename the cars data frame with a generic name
dat # display the entire data frame## speed dist
## 1 4 2
## 2 4 10
## 3 7 4
## 4 7 22
## 5 8 16
## 6 9 10
## 7 10 18
## 8 10 26
## 9 10 34
## 10 11 17
## 11 11 28
## 12 12 14
## 13 12 20
## 14 12 24
## 15 12 28
## 16 13 26
## 17 13 34
## 18 13 34
## 19 13 46
## 20 14 26
## 21 14 36
## 22 14 60
## 23 14 80
## 24 15 20
## 25 15 26
## 26 15 54
## 27 16 32
## 28 16 40
## 29 17 32
## 30 17 40
## 31 17 50
## 32 18 42
## 33 18 56
## 34 18 76
## 35 18 84
## 36 19 36
## 37 19 46
## 38 19 68
## 39 20 32
## 40 20 48
## 41 20 52
## 42 20 56
## 43 20 64
## 44 22 66
## 45 23 54
## 46 24 70
## 47 24 92
## 48 24 93
## 49 24 120
## 50 25 85
该数据帧有 50 个带有 2 个变量的观察值(speed
和distance
)。
您可以分别使用nrow()
和ncol()
检查观察值和变量的数量,或者使用dim()
同时检查两者:
nrow(dat) # number of rows/observations## [1] 50ncol(dat) # number of columns/variables## [1] 2dim(dat) # dimension: number of rows and number of columns## [1] 50 2
行名和列名
在操作数据框之前,了解行和列的名称很有意思:
dimnames(dat)## [[1]]
## [1] "1" "2" "3" "4" "5" "6" "7" "8" "9" "10" "11" "12" "13" "14" "15"
## [16] "16" "17" "18" "19" "20" "21" "22" "23" "24" "25" "26" "27" "28" "29" "30"
## [31] "31" "32" "33" "34" "35" "36" "37" "38" "39" "40" "41" "42" "43" "44" "45"
## [46] "46" "47" "48" "49" "50"
##
## [[2]]
## [1] "speed" "dist"
要只知道列名:
names(dat)## [1] "speed" "dist"# or
colnames(dat)## [1] "speed" "dist"
并且只知道行名:
rownames(dat)## [1] "1" "2" "3" "4" "5" "6" "7" "8" "9" "10" "11" "12" "13" "14" "15"
## [16] "16" "17" "18" "19" "20" "21" "22" "23" "24" "25" "26" "27" "28" "29" "30"
## [31] "31" "32" "33" "34" "35" "36" "37" "38" "39" "40" "41" "42" "43" "44" "45"
## [46] "46" "47" "48" "49" "50"
子集 a 数据帧
首次或最后一次观察
- 要仅保留前 10 个观察值:
head(dat, n = 10)## speed dist
## 1 4 2
## 2 4 10
## 3 7 4
## 4 7 22
## 5 8 16
## 6 9 10
## 7 10 18
## 8 10 26
## 9 10 34
## 10 11 17
- 要仅保留最后 5 次观察:
tail(dat, n = 5)## speed dist
## 46 24 70
## 47 24 92
## 48 24 93
## 49 24 120
## 50 25 85
随机观察样本
- 要抽取 4 个观察值的样本而不替换:
library(dplyr)
sample_n(dat, 4, replace = FALSE)## speed dist
## 1 7 22
## 2 8 16
## 3 20 48
## 4 10 18
基于行号或列号
如果您知道要保留哪些观察结果或列,则可以使用行号或列号对数据框进行分组。我们用几个例子来说明这一点:
- 保留第三次观察的所有变量:
dat[3, ]
- 为所有观察值保留第二个变量:
dat[, 2]
- 您可以混合使用上述两种方法,只保留第 3 次观察的第 2 个变量:
dat[3, 2]## [1] 4
- 保持几次观察;例如观察结果 1 至 5、所有变量的第 10 和第 15 个观察结果:
dat[c(1:5, 10, 15), ] # do not forget c()## speed dist
## 1 4 2
## 2 4 10
## 3 7 4
## 4 7 22
## 5 8 16
## 10 11 17
## 15 12 28
- 删除观察结果 5 至 45:
dat[-c(5:45), ]## speed dist
## 1 4 2
## 2 4 10
## 3 7 4
## 4 7 22
## 46 24 70
## 47 24 92
## 48 24 93
## 49 24 120
## 50 25 85
- 提示:如果只保留最后一次观察,请用
nrow()
代替行号:
dat[nrow(dat), ] # nrow() gives the number of rows## speed dist
## 50 25 85
这样,无论观察多少次,你都会选择最后一次。使用一段代码而不是特定值的技术是为了避免“硬编码”。通常不建议硬编码(除非您想要指定一个您确信永远不会改变的参数),因为如果您的数据框改变了,您将需要手动编辑您的代码。
正如您现在可能已经知道的,您可以通过运行dataset_name[row_number, column_number]
来选择数据集的观测值和/或变量。当行(列)号为空时,选择整个行(列)。
请注意,上述所有示例也适用于矩阵:
mat <- matrix(c(-1, 2, 0, 3), ncol = 2, nrow = 2)
mat## [,1] [,2]
## [1,] -1 0
## [2,] 2 3mat[1, 2]## [1] 0
基于变量名
要根据名称而不是列号选择数据集中的一个变量,请使用dataset_name$variable_name
:
dat$speed## [1] 4 4 7 7 8 9 10 10 10 11 11 12 12 12 12 13 13 13 13 14 14 14 14 15 15
## [26] 15 16 16 17 17 17 18 18 18 18 19 19 19 20 20 20 20 20 22 23 24 24 24 24 25
如果您打算修改数据库的结构,强烈建议使用第二种方法访问数据框中的变量,而不是第一种方法。事实上,如果在数据框中添加或删除一列,编号将会改变。因此,变量通常是通过其名称而不是位置(列号)来引用的。此外,更容易理解和解释写有变量名的代码(用一个简洁但清晰的名字调用变量的另一个原因)。我仍然使用列号的原因只有一个;如果变量名称预期会改变,而数据帧的结构不会改变。
为了选择变量,也可以使用强大的dplyr
包中的select()
命令(由于head()
命令,为了简洁起见,仅显示前 6 个观察结果):
head(select(dat, speed))## speed
## 1 4
## 2 4
## 3 7
## 4 7
## 5 8
## 6 9
这等同于删除距离变量:
head(select(dat, -dist))## speed
## 1 4
## 2 4
## 3 7
## 4 7
## 5 8
## 6 9
基于一个或多个标准
您也可以根据一个或多个标准对数据框进行子集化,而不是根据行/列号或变量名对数据框进行子集化:
- 只保留速度大于 20 的观察值。第一个参数引用数据框的名称,而第二个参数引用子集标准:
subset(dat, dat$speed > 20)## speed dist
## 44 22 66
## 45 23 54
## 46 24 70
## 47 24 92
## 48 24 93
## 49 24 120
## 50 25 85
- 仅保留距离小于或等于 50 且速度等于 10 的观测值。注意平等标准的
==
(而非=
):
subset(dat, dat$dist <= 50 & dat$speed == 10)## speed dist
## 7 10 18
## 8 10 26
## 9 10 34
- 使用
|
只保留距离小于 20 或速度等于 10 的观测值;
subset(dat, dat$dist < 20 | dat$speed == 10)## speed dist
## 1 4 2
## 2 4 10
## 3 7 4
## 5 8 16
## 6 9 10
## 7 10 18
## 8 10 26
## 9 10 34
## 10 11 17
## 12 12 14
- 要过滤掉一些观察结果,使用
!=
。例如,保持速度不等于 24 和距离不等于 120 的观察值(由于tail()
命令,为了简洁起见,只显示最后 6 个观察值):
tail(subset(dat, dat$speed != 24 & dat$dist != 120))## speed dist
## 41 20 52
## 42 20 56
## 43 20 64
## 44 22 66
## 45 23 54
## 50 25 85
注意,也可以用split()
对数据帧进行子集化:
split(dat, dat$factor_variable)
上述代码会将您的数据框分割成几个数据框,每个数据框对应因子变量的一个级别。
创建一个新变量
通常,可以通过基于初始数据框中的其他变量创建新变量来增强数据框,或者通过手动添加新变量来增强数据框。
在这个例子中,我们创建了两个新变量;一个是速度乘以距离(我们称之为speed_dist
),另一个是速度的分类(我们称之为speed_cat
)。然后,我们用 4 个变量显示这个新数据框的前 6 个观察值:
# create new variable speed_dist
dat$speed_dist <- dat$speed * dat$dist# create new variable speed_cat
# with ifelse(): if dat$speed > 7, then speed_cat is "high speed", otherwise it is "low_speed"
dat$speed_cat <- factor(ifelse(dat$speed > 7,
"high speed", "low speed"
))# display first 6 observations
head(dat) # 6 is the default in head()## speed dist speed_dist speed_cat
## 1 4 2 8 low speed
## 2 4 10 40 low speed
## 3 7 4 28 low speed
## 4 7 22 154 low speed
## 5 8 16 128 high speed
## 6 9 10 90 high speed
注意,在编程中,字符串通常用引号括起来(如"character string"
),R 也不例外。
将连续变量转换为分类变量
dat$speed_quali <- cut(dat$speed,
breaks = c(0, 12, 15, 19, 26), # cut points
right = FALSE # closed on the left, open on the right
)dat[c(1:2, 23:24, 49:50), ] # display some observations## speed dist speed_dist speed_cat speed_quali
## 1 4 2 8 low speed [0,12)
## 2 4 10 40 low speed [0,12)
## 23 14 80 1120 high speed [12,15)
## 24 15 20 300 high speed [15,19)
## 49 24 120 2880 high speed [19,26)
## 50 25 85 2125 high speed [19,26)
例如,当年龄(连续变量)被转换为代表不同年龄组的定性变量时,这种转换通常在年龄上进行。
行中的总和与平均值
在使用李克特量表(除其他外,用于心理学)的调查中,通常情况下,我们需要根据多个问题计算每个受访者的分数。分数通常是所有感兴趣问题的平均值或总和。
这可以通过rowMeans()
和rowSums()
来完成。例如,让我们计算变量speed
、dist
和speed_dist
的平均值和总和(当然,变量必须是数字,因为总和和平均值不能在定性变量上计算!)并将它们存储在变量mean_score
和total_score
下:
dat$mean_score <- rowMeans(dat[, 1:3]) # variables speed, dist and speed_dist correspond to variables 1 to 3
dat$total_score <- rowSums(dat[, 1:3])head(dat)## speed dist speed_dist speed_cat speed_quali mean_score total_score
## 1 4 2 8 low speed [0,12) 4.666667 14
## 2 4 10 40 low speed [0,12) 18.000000 54
## 3 7 4 28 low speed [0,12) 13.000000 39
## 4 7 22 154 low speed [0,12) 61.000000 183
## 5 8 16 128 high speed [0,12) 50.666667 152
## 6 9 10 90 high speed [0,12) 36.333333 109
列中的总和与平均值
也可以用colMeans()
和colSums()
按列计算平均值和总和:
colMeans(dat[, 1:3])## speed dist speed_dist
## 15.40 42.98 769.64colSums(dat[, 1:3])## speed dist speed_dist
## 770 2149 38482
这相当于:
mean(dat$speed)## [1] 15.4sum(dat$speed)## [1] 770
但是它允许一次对几个变量进行处理。
分类变量和标签管理
对于分类变量,使用因子格式并命名变量的不同级别是一个很好的实践。
- 对于本例,让我们根据距离创建另一个名为
dist_cat
的新变量,然后将其格式从数字改为因子(同时还指定级别的标签):
# create new variable dist_cat
dat$dist_cat <- ifelse(dat$dist < 15,
1, 2
)# change from numeric to factor and specify the labels
dat$dist_cat <- factor(dat$dist_cat,
levels = c(1, 2),
labels = c("small distance", "big distance") # follow the order of the levels
)head(dat)## speed dist speed_dist speed_cat speed_quali mean_score total_score
## 1 4 2 8 low speed [0,12) 4.666667 14
## 2 4 10 40 low speed [0,12) 18.000000 54
## 3 7 4 28 low speed [0,12) 13.000000 39
## 4 7 22 154 low speed [0,12) 61.000000 183
## 5 8 16 128 high speed [0,12) 50.666667 152
## 6 9 10 90 high speed [0,12) 36.333333 109
## dist_cat
## 1 small distance
## 2 small distance
## 3 small distance
## 4 big distance
## 5 big distance
## 6 small distance
- 要检查变量的格式:
class(dat$dist_cat)## [1] "factor"# or
str(dat$dist_cat)## Factor w/ 2 levels "small distance",..: 1 1 1 2 2 1 2 2 2 2 ...
如果您只需要格式化有限数量的变量,这就足够了。但是,如果您需要对大量的分类变量执行此操作,那么多次编写相同的代码很快就会变得非常耗时。正如您所想象的,使用within()
命令格式化许多变量而不必逐个为每个变量编写完整的代码是可能的:
dat <- within(dat, {
speed_cat <- factor(speed_cat, labels = c(
"high speed",
"low speed"
))
dist_cat <- factor(dist_cat, labels = c(
"small distance",
"big distance"
))
})head(dat)## speed dist speed_dist speed_cat speed_quali mean_score total_score
## 1 4 2 8 low speed [0,12) 4.666667 14
## 2 4 10 40 low speed [0,12) 18.000000 54
## 3 7 4 28 low speed [0,12) 13.000000 39
## 4 7 22 154 low speed [0,12) 61.000000 183
## 5 8 16 128 high speed [0,12) 50.666667 152
## 6 9 10 90 high speed [0,12) 36.333333 109
## dist_cat
## 1 small distance
## 2 small distance
## 3 small distance
## 4 big distance
## 5 big distance
## 6 small distancestr(dat)## 'data.frame': 50 obs. of 8 variables:
## $ speed : num 4 4 7 7 8 9 10 10 10 11 ...
## $ dist : num 2 10 4 22 16 10 18 26 34 17 ...
## $ speed_dist : num 8 40 28 154 128 90 180 260 340 187 ...
## $ speed_cat : Factor w/ 2 levels "high speed","low speed": 2 2 2 2 1 1 1 1 1 1 ...
## $ speed_quali: Factor w/ 4 levels "[0,12)","[12,15)",..: 1 1 1 1 1 1 1 1 1 1 ...
## $ mean_score : num 4.67 18 13 61 50.67 ...
## $ total_score: num 14 54 39 183 152 109 208 296 384 215 ...
## $ dist_cat : Factor w/ 2 levels "small distance",..: 1 1 1 2 2 1 2 2 2 2 ...
或者,如果您想在不改变标签的情况下将几个数值变量转换成分类变量,最好使用transform()
函数。我们用来自[{ggplot2}](https://statsandr.com/blog/graphics-in-r-with-ggplot2/)
包的mpg
数据帧来说明该功能:
library(ggplot2)
mpg <- transform(mpg,
cyl = factor(cyl),
drv = factor(drv),
fl = factor(fl),
class = factor(class)
)
记录分类变量
如果您对当前标签不满意,可以对分类变量的标签进行重新编码。在本例中,我们将标签更改如下:
- “小距离”变成“短距离”
- “大距离”变成了“大距离”
dat$dist_cat <- recode(dat$dist_cat,
"small distance" = "short distance",
"big distance" = "large distance"
)head(dat)## speed dist speed_dist speed_cat speed_quali mean_score total_score
## 1 4 2 8 low speed [0,12) 4.666667 14
## 2 4 10 40 low speed [0,12) 18.000000 54
## 3 7 4 28 low speed [0,12) 13.000000 39
## 4 7 22 154 low speed [0,12) 61.000000 183
## 5 8 16 128 high speed [0,12) 50.666667 152
## 6 9 10 90 high speed [0,12) 36.333333 109
## dist_cat
## 1 short distance
## 2 short distance
## 3 short distance
## 4 large distance
## 5 large distance
## 6 short distance
更改参考水平
对于某些分析,您可能想要更改级别的顺序。例如,如果您正在分析关于对照组和治疗组的数据,您可能希望将对照组设置为参考组。默认情况下,级别按字母顺序排序,如果从数值更改为因子,则按其数值排序。
- 要检查级别的当前顺序(第一个级别为参考级别):
levels(dat$dist_cat)## [1] "short distance" "large distance"
在这种情况下,“短距离”是第一个级别,它是参考级别。这是第一个级别,因为在创建变量时,它最初被设置为等于 1 的值。
- 要更改参考电平:
dat$dist_cat <- relevel(dat$dist_cat, ref = "large distance")levels(dat$dist_cat)## [1] "large distance" "short distance"
大距离现在是第一级,因此也是参考级。
重命名变量名
要重命名变量名,如下所示:
- 距离→距离
- 速度 _ 距离→速度 _ 距离
- 距离 _ 猫→距离 _ 猫
使用dplyr
包中的rename()
命令:
dat <- rename(dat,
distance = dist,
speed_distance = speed_dist,
distance_cat = dist_cat
)names(dat) # display variable names## [1] "speed" "distance" "speed_distance" "speed_cat"
## [5] "speed_quali" "mean_score" "total_score" "distance_cat"
手动创建数据框
尽管大多数分析是在导入的数据框上执行的,但也可以直接在 R:
# Create the data frame named dat with 2 variables
dat <- data.frame(
"variable1" = c(6, 12, NA, 3), # presence of 1 missing value (NA)
"variable2" = c(3, 7, 9, 1)
)# Print the data frame
dat## variable1 variable2
## 1 6 3
## 2 12 7
## 3 NA 9
## 4 3 1
合并两个数据帧
默认情况下,合并是在公共变量(同名的变量)上完成的。但是,如果它们没有相同的名称,仍然可以通过指定名称来合并这两个数据框:
dat1 <- data.frame(
person = c(1:4),
treatment = c("T1", "T2")
)dat1## person treatment
## 1 1 T1
## 2 2 T2
## 3 3 T1
## 4 4 T2dat2 <- data.frame(
patient = c(1:4),
age = c(56, 23, 32, 19),
gender = c("M", "F", "F", "M")
)dat2## patient age gender
## 1 1 56 M
## 2 2 23 F
## 3 3 32 F
## 4 4 19 M
我们想通过主题编号来合并两个数据帧,但是这个编号在第一个数据帧中被称为person
,在第二个数据帧中被称为patient
,所以我们需要指出它:
merge(
x = dat1, y = dat2,
by.x = "person", by.y = "patient",
all = TRUE
)## person treatment age gender
## 1 1 T1 56 M
## 2 2 T2 23 F
## 3 3 T1 32 F
## 4 4 T2 19 M
从另一个数据框添加新观测值
为了从另一个数据框中添加新的观测值,这两个数据框需要具有相同的列名(但它们的顺序可以不同):
dat1## person treatment
## 1 1 T1
## 2 2 T2
## 3 3 T1
## 4 4 T2dat3 <- data.frame(
person = 5:8,
treatment = c("T3")
)dat3## person treatment
## 1 5 T3
## 2 6 T3
## 3 7 T3
## 4 8 T3rbind(dat1, dat3) # r stands for row, so we bind data frames by row## person treatment
## 1 1 T1
## 2 2 T2
## 3 3 T1
## 4 4 T2
## 5 5 T3
## 6 6 T3
## 7 7 T3
## 8 8 T3
如您所见,数据帧dat1
的末尾添加了 5 至 8 人的数据(因为rbind()
函数中dat1
在dat3
之前)。
从另一个数据框添加新变量
也可以使用cbind()
功能向数据帧添加新变量。与rbind()
不同,列名不必相同,因为它们是相邻添加的:
dat2## patient age gender
## 1 1 56 M
## 2 2 23 F
## 3 3 32 F
## 4 4 19 Mdat3## person treatment
## 1 5 T3
## 2 6 T3
## 3 7 T3
## 4 8 T3cbind(dat2, dat3) # c stands for column, so we bind data frames by column## patient age gender person treatment
## 1 1 56 M 5 T3
## 2 2 23 F 6 T3
## 3 3 32 F 7 T3
## 4 4 19 M 8 T3
如果只想添加另一个数据框中的特定变量:
dat_cbind <- cbind(dat2, dat3$treatment)dat_cbind## patient age gender dat3$treatment
## 1 1 56 M T3
## 2 2 23 F T3
## 3 3 32 F T3
## 4 4 19 M T3names(dat_cbind)[4] <- "treatment"dat_cbind## patient age gender treatment
## 1 1 56 M T3
## 2 2 23 F T3
## 3 3 32 F T3
## 4 4 19 M T3
或者更简单地用data.frame()
功能:
data.frame(dat2,
treatment = dat3$treatment
)## patient age gender treatment
## 1 1 56 M T3
## 2 2 23 F T3
## 3 3 32 F T3
## 4 4 19 M T3
缺少值
缺失值(在 RStudio 中用 NA 表示,表示“不适用”)对于许多分析来说通常是有问题的,因为包括缺失值的许多计算结果都有缺失值。
例如,具有至少一个 NA 的系列或变量的平均值将给出 NA 结果。上一节创建的数据帧dat
用于本例:
dat## variable1 variable2
## 1 6 3
## 2 12 7
## 3 NA 9
## 4 3 1mean(dat$variable1)## [1] NA
na.omit()
函数避免 NA 结果,就像没有丢失值一样:
mean(na.omit(dat$variable1))## [1] 7
此外,大多数基本函数都包含一个处理缺失值的参数:
mean(dat$variable1, na.rm = TRUE)## [1] 7
is.na()
表示某个元素是否为缺失值:
is.na(dat)## variable1 variable2
## [1,] FALSE FALSE
## [2,] FALSE FALSE
## [3,] TRUE FALSE
## [4,] FALSE FALSE
请注意,字符串形式的“NA”不会被视为缺失值:
y <- c("NA", "2")is.na(y)## [1] FALSE FALSE
要检查矢量或数据帧中是否至少有一个值缺失:
anyNA(dat$variable2) # check for NA in variable2## [1] FALSEanyNA(dat) # check for NA in the whole data frame## [1] TRUE# or
any(is.na(dat)) # check for NA in the whole data frame## [1] TRUE
尽管如此,对于某些类型的分析来说,使用 NAs 的数据帧仍然存在问题。有几种方法可以去除或估算缺失值。
删除 NAs
一个简单的解决方案是删除至少包含一个缺失值的所有观察值(即行)。这是通过仅保留完整案例的观察结果来实现的:
dat_complete <- dat[complete.cases(dat), ]
dat_complete## variable1 variable2
## 1 6 3
## 2 12 7
## 4 3 1
删除有缺失值的观测值时要小心,尤其是缺失值不是“随机缺失”的情况。这并不是因为删除它们是可能的(也是容易的),而是因为您应该在所有情况下都这样做。然而,这超出了本文的范围。
估算 NAs
除了删除至少有一个 NA 的观测值之外,还可以对它们进行估算,也就是说,用变量的中值或众数等值来替换它们。这可以通过包imputeMissings
中的命令impute()
轻松完成:
library(imputeMissings)dat_imputed <- impute(dat) # default method is median/mode
dat_imputed## variable1 variable2
## 1 6 3
## 2 12 7
## 3 6 9
## 4 3 1
当使用中值/众数方法(默认)时,字符向量和因子用众数估算。数字和整数向量用中位数估算。再次,小心使用插补。其他软件包提供更先进的插补技术。然而,我们保持这篇文章简单明了,因为高级插补超出了 r。
规模
缩放(也称为标准化)当一个数据帧的变量具有不同的单位时,变量通常用在主成分分析(PCA) 1 之前。请记住,缩放变量意味着它将计算该变量的平均值和标准差。然后,通过减去该变量的平均值并除以该变量的标准偏差来“缩放”该变量的每个值(即每行)。形式上:
其中 xbar 和 s 分别是变量的平均值和标准差。
使用scale()
缩放 R 中的一个或多个变量:
dat_scaled <- scale(dat_imputed)head(dat_scaled)## variable1 variable2
## [1,] -0.1986799 -0.5477226
## [2,] 1.3907590 0.5477226
## [3,] -0.1986799 1.0954451
## [4,] -0.9933993 -1.0954451
日期和时间
日期
在 R 中,默认的日期格式遵循 ISO 8601 国际标准的规则,该标准将一天表示为“2001–02–13”(yyyy-mm-DD)。 2
日期可以由字符串或数字定义。比如 2016 年 10 月 1 日:
as.Date("01/10/16", format = "%d/%m/%y")## [1] "2016-10-01"as.Date(274, origin = "2016-01-01") # there are 274 days between the origin and October 1st, 2016## [1] "2016-10-01"
英国泰晤士报(1785 年创刊)
日期和时间向量的示例:
dates <- c("02/27/92", "02/27/99", "01/14/92")
times <- c("23:03:20", "22:29:56", "01:03:30")x <- paste(dates, times)
x## [1] "02/27/92 23:03:20" "02/27/99 22:29:56" "01/14/92 01:03:30"strptime(x,
format = "%m/%d/%y %H:%M:%S"
)## [1] "1992-02-27 23:03:20 CET" "1999-02-27 22:29:56 CET"
## [3] "1992-01-14 01:03:30 CET"
找到更多关于如何用help(strptime)
表达日期和时间格式的信息。
从枣中提取
我们可以提取:
- 平日
- 月份
- 四分之一
- 年
y <- strptime(x,
format = "%m/%d/%y %H:%M:%S"
)y## [1] "1992-02-27 23:03:20 CET" "1999-02-27 22:29:56 CET"
## [3] "1992-01-14 01:03:30 CET"weekdays(y, abbreviate = FALSE)## [1] "Thursday" "Saturday" "Tuesday"months(y, abbreviate = FALSE)## [1] "February" "February" "January"quarters(y, abbreviate = FALSE)## [1] "Q1" "Q1" "Q1"format(y, "%Y") # 4-digit year## [1] "1992" "1999" "1992"format(y, "%y") # 2-digit year## [1] "92" "99" "92"
导出和保存
如果复制粘贴还不够,您可以用save()
保存一个 R 格式的对象:
save(dat, file = "dat.Rdata")
或者使用write.table()
或write.csv()
:
write.table(dat, "filename", row = FALSE, sep = "\t", quote = FALSE)
如果您需要将每个结果发送到一个文件而不是控制台:
sink("filename")
(别忘了用sink()
阻止它。)
寻求帮助
您总能找到一些关于以下方面的帮助:
- 一个功能:
?function
或help(function)
- 一包:
help(package = packagename)
- 一个概念:
help.search("concept")
还是apropos("concept")
否则,谷歌就是你最好的朋友!
感谢阅读。我希望这篇文章能帮助你在 RStudio 中操作数据。现在您已经知道了如何将数据帧导入 R 以及如何操作它,下一步可能是学习如何在 R 中执行描述性统计。如果您正在使用 R 寻找更高级的统计分析,请参阅所有关于 R 的文章。
和往常一样,如果您有与本文主题相关的问题或建议,请将其添加为评论,以便其他读者可以从讨论中受益。
- 主成分分析(PCA)是一种用于探索性数据分析的有用技术,允许更好地可视化具有大量变量的数据框架中存在的变化。当有许多变量时,数据不容易用原始格式表示出来。为了应对这种情况,PCA 采用具有许多变量的数据帧,并通过将原始变量转换成较少数量的“主成分”来简化它。第一个维度包含数据框中的最大方差,依此类推,维度之间不相关。请注意,PCA 是对数量变量进行的。 ↩︎
- 请注意,每个软件的日期格式不尽相同!例如,Excel 使用不同的格式。 ↩︎
相关文章
原载于 2019 年 12 月 24 日https://statsandr.com。