数据建模:概述
本文概述了软件应用程序中的数据建模。它描述了常用的术语,并使用一个零售销售案例研究来解释一步一步的过程。
如果你观察世界上的任何软件应用程序,你会发现在最基本的层面上,它将处理数据的组织、操作和表示,以满足业务需求。
一个数据模型是表达和交流业务需求的概念表示。它直观地表示了数据的性质、管理数据的业务规则以及数据在数据库中的组织方式。
数据建模的过程可以比作建造房子的过程。假设某公司 ABC 需要建一个招待所(数据库)。它调用一个建筑架构师(数据建模师)并解释它的建筑需求(业务需求)。建筑设计师(数据建模师)开发计划(数据模型)并将其交给 ABC 公司。最后,ABC 公司召集土木工程师(数据库管理员和数据库开发人员)来建造客房(数据库)
数据建模中的关键术语:
实体和属性: 实体是业务环境中的“事物”,我们希望存储关于它们的数据,如产品、客户、订单等。属性提供了一种组织和构造数据的方法。例如,我们需要存储我们销售的产品的某些信息,如售价或可用数量。这些数据是产品实体的属性。实体通常表示数据库的表格,而属性是这些表格的列。
关系: 实体之间的关系描述一个实体如何链接到另一个实体。在数据模型中,实体可以是以下任何一种关系:一对一、多对一或多对多。这就是所谓的给定实体相对于另一个实体的基数。
交集实体(参照表): 当实体间存在多对多关系时,可以用交集实体解析为多对一和一对多关系。一个简单的例子是:有两个实体,电视节目和人。每个电视节目可以由一个或多个人观看,而一个人可以观看一个或多个电视节目:
这可以通过引入新的相交实体“查看记录”来解决,如下所示:
ER 图: 表示实体及实体间关系的图称为 ER 图。ER 图可以采用概念数据模型、逻辑数据模型或物理数据模型的形式。
概念数据模型: 概念数据模型包括所有主要实体和关系,不包含太多关于属性的详细信息,通常用于初始规划阶段。一个例子:
逻辑数据模型: 它是概念数据模型的扩展。它包括代表业务信息和定义业务规则的所有实体、属性、键组和关系。一个例子:
物理数据模型: 它包括数据库物理实现所需的所有表、列、关系、数据库属性。数据库性能、索引策略、物理存储和反规范化是物理模型的重要参数。一个例子:
数据建模开发周期:
关系与维度建模:
根据业务需求,您的数据模型可以是关系型的,也可以是维度型的。关系模型是一种旨在消除数据冗余的设计技术。数据被分成许多离散的实体,每个实体都成为关系数据库中的一个表。这些表格通常被标准化为第三范式。在 OLTP 应用程序中,遵循这种方法。
在仓库需求的情况下,数据被反规范化以提高性能。在维度模型中,数据被分为维度和事实,其设计目标是用户可理解性、查询性能和对变化的弹性。
案例研究:
ABC 公司在八个州拥有 200 家杂货店。每个商店都有不同的部门,如日用品、化妆品、冷冻食品、乳制品等。每家商店的货架上大约有 20000 种产品。单个产品被称为库存单位(SKU)。约 6000 个 SKU 来自外部制造商,产品包装上印有条形码。这些条形码被称为通用产品代码(UPCs)。销售点(POS)系统在两个地方收集数据:测量顾客外卖的前门和供应商送货的后门。
在杂货店,管理关心的是订购、储存和销售产品的物流,同时最大化利润。一些促销方案,如临时降价、报纸广告、展示等,也在不断增加。
设计一个数据模型来分析这个连锁杂货店的运作。
解决方案:
第一步:收集业务需求:
管理层希望更好地了解 POS 系统捕获的客户购买情况。该模型应该允许分析什么产品在什么日子在什么促销条件下在什么商店销售。此外,这是一个仓储环境,因此需要一个维度模型。
步骤 2:实体的识别:
在维度模型的情况下,我们需要识别我们的事实和维度实体。在开发模型之前,需要明确所需数据的粒度。在这种特殊情况下,我们需要颗粒是 POS 交易上的单个行项目。根据要求,我们需要在特定的一天,在特定的促销方案下,查看特定商店中特定产品的数据。这给了我们所需尺寸的概念:
日期维度
产品尺寸
店面尺寸
促销维度
要计算的数量(如销售数量、利润等)将在销售事实表中获取。
第三步:概念数据模型:
将根据收集的关于实体的信息建立一个初步的数据模型。在我们的例子中,它将如下所示:
步骤 4:属性的最终确定和逻辑数据模型的设计
现在,需要最终确定已识别的事实表和维度表的属性。在我们的例子中,以下属性已经完成:
日期维度:
产品:
店铺:
晋级:
销售事实:
交易编号
销售数量:(例如蔬菜汤面罐头的数量)
销售金额:销售数量*单价
成本金额:供应商收取的产品成本金额
毛利金额:销售金额-成本金额
逻辑数据模型将看起来像:
步骤 5:在数据库中创建物理表:
在数据建模工具的帮助下,或者通过编写定制脚本,现在可以在数据库中创建物理表。
数据建模是软件应用程序设计中最重要的任务之一。它为如何组织、存储、检索和呈现数据奠定了基础。
新生婴儿的数据建模和预测
请阅读我在产假期间与我的新生儿一起探索数据建模的经历
机器学习面临的挑战之一是处理数据。人们常说,数据建模是 90%的数据收集/清理和 10%的模型构建。因此,收集能够提供丰富见解的正确数据是一个巨大的难题。
在我生孩子的前几周,我和一个朋友聊了聊我在休产假期间可以做的一些科技项目。毕竟,我要生孩子了,我可以收集她周围的大量数据!!我们认为的一些想法是:
在一段时间内拍摄婴儿指纹的快照,并分析它们是否以及如何变化
收集不同婴儿哭声的音频剪辑,并使用机器学习模型对不同哭声的含义进行分类。
嗯,这两个想法对我来说都失败了。我简直不能正确地提取我孩子的指纹。每次她哭的时候,录音剪辑就更难了。
另一个想法是用一个预测模型来找到她大便和小便的模式。我开始收集出生后几周内的尿布数据。然而,我意识到大便和小便的模式每周都在变化,这取决于婴儿摄入的母乳和配方奶的量。随着年龄的增长,情况也在发生变化。当我问医生不准确的原因时,她大声说道:“很明显,她的便便周期会改变。会有一些天她完全不便便,没什么好惊讶的”。我意识到很难对这么小的婴儿的便便频率进行预测分析。我的想法泡汤了!
我意识到仅仅是我孩子的数据不足以做出任何预测。在网上搜索时,我发现了一个新生儿体重的数据集。数据集包含婴儿的特征,如出生日期、性别、出生时间等,以及关于怀孕的数据点,如产前、生母的医疗状况,如妊娠糖尿病、贫血等,以及父母的病史,包括数据点,如种族、出生子女数、饮酒和吸烟习惯。总的来说,数据集[1]有 131422 个数据点,我觉得对于一个预测模型来说足够了。目标是根据怀孕周预测婴儿的出生体重。这是一个重要的目标,因为分娩时的大尺寸婴儿可能会增加新生儿及其母亲受伤的风险[2]。因此,医生对出生体重的预测越准确,分娩就越容易。
虽然超声波是医生预测婴儿体重的常用方法,但他们往往会有 10-15%的差异。我决定使用机器学习来预测出生体重。
第一步:准备工作空间
我从 kaggle 链接导入了所需的库并加载了数据集“baby-weights-dataset2.csv”。
第二步:数据探索
这一步有助于我们理解目标可变出生体重——其平均值、标准偏差、最小值和最大值、中值等。我们还绘制了出生体重变量的直方图,以了解其性质。我们还计算目标变量的偏斜度和峰度
接下来,我们从训练数据集中识别分类值,并打印定性和定量列。此时,我们处理缺失的值,并将它们设置为“缺失”。我们还采用定性变量 HISPMOM 和 HISPDAD 并对其进行编码。
最后,我们使用 Spearman 的等级相关性来寻找变量之间的相关性,并在 Correlated_Feature 列表中选取最相关的特征,并将其用于进一步的建模。一些最相关的特征是妊娠完成周数、母亲体重增加量、母亲年龄、父母种族和产前检查次数。
第三步:测试和训练集
接下来,我们使用下面的代码将 80%的数据分割成训练集,而将 20%的数据分割成测试集。test_size 变量是我们实际指定测试集比例的地方。
这里,“训练”集是用于创建机器学习模型的数据文件,而“测试”集是我们使用模型来预测目标变量的数据文件。ATrain 和 ATest 分割相关特征,而 BTrain 和 BTest 分割出生体重变量。
然后,我们将归一化技术应用于我们的训练和测试特征数据集。
第四步:模型创建
把数据拆分成训练集和测试集之后,最后,就是训练我们算法的时候了。为此,我们需要设置种子并使用θ来计算预测值并改进模型。这一步也可以使用 scikit 学习线性回归库
模型公式:
第五步:预测出生体重
最后,让我们使用我们在步骤 4 中拟合的回归模型,使用该模型来预测每个测试数据集的出生体重目标变量。我使用误差函数检验了模型的表现:
我用平均 RMSE 和标准差来评估线性模型。RMSE 是更受欢迎的指标,通常与标准差一起用作解释模型的主要指标。
平均 RMSE 在 1.07 左右,我觉得对这个数据集来说已经不错了。此外,标准偏差约为 2.64,可通过进一步调整特性来改善。虽然仍然有一些足够好的误差,这些出生体重预测可能有助于医生在分娩过程中更准确地估计婴儿的大小。
当我休完产假回到办公室时,我期待着分享这一模式的见解。
这个模型的代码和数据文件被添加到这个 Github 库中。如果你觉得这有用,请与你的朋友和同事分享。欢迎在评论区分享你的想法和反馈。
参考资料:
- https://www.kaggle.com/c/csci-ml-s19-pa1/overview
- https://www . webmd . com/g00/baby/news/2002 09 26/you-can-predict-your-新生儿-体重?i10c . ua = 1&i10c . encreferrer = ahr 0 CHM 6 ly 93d 3c uz 29 vz 2 xllmnvbs 8% 3d&i10c . dv = 1
音乐流应用程序的数据建模
Udacity 数据工程师纳米学位
创建一个 Postgres 数据库,其中的表用于优化歌曲播放分析的查询
潘卡杰·帕特尔在 Unsplash 上的照片
介绍
我已经加入了 Udacity 数据工程师 Nanodegree。该计划由许多现实世界的项目组成。在这个项目中,我在一家名为“Sparkify”的虚构数据流公司担任数据工程师。这是一家初创公司,希望分析他们在新的音乐流媒体应用程序上收集的歌曲和用户活动数据。分析团队对了解用户在听什么歌特别感兴趣。目前,他们没有一种简单的方法来查询他们的数据,这些数据位于应用程序上用户活动的 JSON 日志目录中,以及应用程序中歌曲的 JSON 元数据目录中。
他们想要一个数据工程师来创建一个 Postgres 数据库,其表旨在优化歌曲播放分析的查询,并让我参与这个项目。我的角色是为这个分析创建一个数据库模式和 ETL 管道。我已经通过运行 Sparkify 的分析团队给我的查询测试了我的数据库和 ETL 管道,并将我的结果与他们的预期结果进行了比较。
项目描述
在这个项目中,我应用了我在 Postgres 数据建模方面学到的知识,并使用 Python 构建了一个 ETL 管道。我为特定分析焦点的星型模式定义了事实表和维度表,并使用 Python 和 SQL 编写了一个 ETL 管道,将数据从两个本地目录中的文件传输到 Postgres 的这些表中。
歌曲数据集
第一个数据集是来自百万首歌曲数据集的真实数据子集。每个文件都是 JSON 格式的,包含关于一首歌和这首歌的艺术家的元数据。这些文件按每首歌曲曲目 ID 的前三个字母进行分区。例如,以下是该数据集中两个文件的文件路径。
song_data/A/B/C/TRABCEI128F424C983.json
song_data/A/A/B/TRAABJL12903CDCF1A.json
下面是一个歌曲文件 TRAABJL12903CDCF1A.json 的示例。
{"num_songs": 1, "artist_id": "ARJIE2Y1187B994AB7", "artist_latitude": null, "artist_longitude": null, "artist_location": "", "artist_name": "Line Renaud", "song_id": "SOUPIRU12A6D4FA1E1", "title": "Der Kleine Dompfaff", "duration": 152.92036, "year": 0}
日志数据集
第二个数据集由这个事件模拟器基于上面数据集中的歌曲生成的 JSON 格式的日志文件组成。这些根据指定的配置模拟音乐流媒体应用程序的活动日志。
您将使用的数据集中的日志文件按年份和月份进行分区。例如,以下是该数据集中两个文件的文件路径。
log_data/2018/11/2018-11-12-events.json
log_data/2018/11/2018-11-13-events.json
下面是日志文件 2018–11–12-events . JSON 中数据的示例。
如果您想查看 log_data 文件中的 JSON 数据,您需要创建一个 pandas 数据帧来读取数据。记得先导入 JSON 和 pandas 库。
df = pd.read_json(filepath, lines=True)
例如,df = pd.read_json('data/log_data/2018/11/2018-11-01-events.json', lines=True)
将读取数据文件 2018-11-01-events.json。
如果你需要复习 JSON 文件格式,这里有一个有用的视频。
歌曲分析的图式
使用歌曲和日志数据集,我创建了一个针对歌曲播放分析查询优化的星型模式。这包括以下表格。
事实表
歌曲播放 —日志数据中与歌曲播放相关的记录,即带有页面NextSong
的记录歌曲播放标识、开始时间、用户标识、级别、歌曲标识、艺术家标识、会话标识、位置、用户代理
维度表
用户 —应用中的用户
用户标识、名字、姓氏、性别、级别
歌曲 —音乐数据库中的歌曲
歌曲 id、标题、艺术家 id、年份、时长
艺术家 —音乐数据库中的艺术家
艺术家 _id、姓名、地点、纬度、经度
时间—歌曲播放中记录的时间戳分解成具体的单位
sstart _ time、hour、day、week、month、year、weekday
火花数据库的 ER 图
在处理关系数据库系统时,像列中的Primary key
和NOT NULL
这样的条件很重要。同样,作为一名数据工程师,必须根据业务需求指定主键列,并且不能为空。例如,用户标识和开始时间应该被认为不为空。
项目模板
除了数据文件之外,项目工作环境还包括六个文件:
[test.ipynb](https://github.com/joshuayeung/Data-Modeling-for-a-Music-Streaming-App/blob/master/test.ipynb)
显示每个表格的前几行以检查数据库。[create_tables.py](https://github.com/joshuayeung/Data-Modeling-for-a-Music-Streaming-App/blob/master/create_tables.py)
放下并创建表格。每次运行 ETL 脚本之前,我都会运行这个文件来重置我的表。[etl.ipynb](https://github.com/joshuayeung/Data-Modeling-for-a-Music-Streaming-App/blob/master/etl.ipynb)
读取并处理来自song_data
和log_data
的单个文件,并将数据加载到表格中。这个笔记本包含了对每个表的 ETL 过程的详细解释。[etl.py](https://github.com/joshuayeung/Data-Modeling-for-a-Music-Streaming-App/blob/master/etl.py)
从song_data
和log_data
读取并处理文件,加载到表格中。[sql_queries.py](https://github.com/joshuayeung/Data-Modeling-for-a-Music-Streaming-App/blob/master/sql_queries.py)
包含所有的 SQL 查询,并被导入到上面的最后三个文件中。
创建表格
为了创建我需要的所有表,我完成了以下四个步骤:
- 在
[sql_queries.py](https://github.com/joshuayeung/Data-Modeling-for-a-Music-Streaming-App/blob/master/sql_queries.py)
中编写CREATE
语句,根据上面定义的模式创建每个表。 - 在
[sql_queries.py](https://github.com/joshuayeung/Data-Modeling-for-a-Music-Streaming-App/blob/master/sql_queries.py)
中编写DROP
语句来删除每个表(如果存在的话)。 - 运行
[create_tables.py](https://github.com/joshuayeung/Data-Modeling-for-a-Music-Streaming-App/blob/master/create_tables.py)
创建数据库和表格。 - 运行
[test.ipynb](https://github.com/joshuayeung/Data-Modeling-for-a-Music-Streaming-App/blob/master/test.ipynb)
确认用正确的列创建表格。运行本笔记本后,确保点击“重启内核”关闭与数据库的连接。
创建歌曲播放表的 CREATE 语句
在 create_tables.py 中,有一个函数create_tables
来执行create_table_queries
列表中列出的所有查询。
您可以看到这些表是用 test.ipynb 中定义的列创建的。
确认创建了具有正确列的表。
构建 ETL 管道
是时候为每个表开发 ETL 过程了。在 etl.py 中,有一个函数叫做process_data
。您可以传递处理数据所需的文件路径和处理函数。它获取所有与扩展名匹配的文件。json)从目录。然后它使用传入的函数遍历文件和进程。
流程song_data
首先,让我们处理song_data
并创建songs
和artists
维度表。我构建了process_song_file
函数来执行以下任务:
- 首先,在
data/song_data
中获取所有 song JSON 文件的列表 - 阅读歌曲文件
- 提取歌曲表的数据并将数据插入歌曲表
- 提取艺术家表的数据并将数据插入艺术家表
提取歌曲表的数据
要提取歌曲表的数据,需要完成以下任务:
- 选择歌曲 ID、标题、艺术家 ID、年份和持续时间的列
- 使用
df.values
从数据框中选择数值 - 索引以选择数据帧中的第一条(唯一的)记录
- 将数组转换为列表,并将其设置为
song_data
将记录插入歌曲表
在sql_queries.py
中编写song_table_insert
查询,并将这首歌曲的记录插入到songs
表中。
sql _ queries.py 中的 song_table_insert 查询
将歌曲记录插入歌曲表的代码
提取艺术家表的数据并将记录插入艺术家表
艺术家表的数据提取类似于歌曲表的数据提取,但是这次我选择了艺术家 ID、姓名、位置、纬度和经度列。
流程log_data
其次,我对第二个数据集log_data
执行了 ETL,创建了time
和users
维度表,以及songplays
事实表。
提取时间表的数据并将记录插入时间表
我已经通过NextSong
动作过滤了记录
df = df[df['page']=='NextSong']
并将ts
时间戳列转换为日期时间。
t = pd.to_datetime(df['ts'], unit='ms')
注意:当前时间戳以毫秒为单位
我使用 pandas 的dt
属性轻松访问类似日期时间的属性,例如来自ts
列的小时、日、星期、月、年和工作日,并将time_data
设置为按顺序包含这些值的列表。我还为这些列指定了标签,并设置为column_labels
。我创建了一个数据帧,time_df,
,包含这个文件的时间数据,方法是将column_labels
和time_data
组合成一个字典,并将其转换成一个数据帧。最后,我将日志文件中时间戳的记录插入到time
表中。
提取用户表的数据并将记录插入用户表
用户表的数据提取很容易,只需选择用户 ID、名字、姓氏、性别和级别的列并设置为user_df
,然后将该日志文件中的用户记录插入到users
表中。
一些笔记
需要为每个表修改 INSERT 语句,以便在适当的时候处理现有记录。作为一名数据工程师,我需要仔细考虑当新数据被插入表中时,表将如何处理现有记录。
例如,对用户表使用on conflict update
,因为级别可以从免费变为付费。
提取数据和歌曲播放表
这个有点复杂,因为songs
表、artists
表和原始日志文件中的信息都是songplays
表所需要的。因为日志文件没有为歌曲或艺术家指定 ID,所以我需要通过查询songs
和artists
表来获得歌曲 ID 和艺术家 ID,以便根据歌曲标题、艺术家姓名和歌曲的持续时间找到匹配项。
使用歌曲标题、艺术家姓名和歌曲持续时间来查询歌曲 ID 和艺术家 ID 的 SELECT 语句。
由于这是一个更大的数据集的子集,解决方案数据集将只有一行,其值包含事实表中songid
和artistid
的 ID。这是sql_queries.py
中的查询将返回的唯一两个非空值。对于这两个变量,其余的行将没有值。
结论
就是这样。我创建了一个 Postgres 数据库,其中的表是为优化歌曲播放分析的查询而设计的。分析团队现在可以轻松地查询他们的数据,并分析了解用户正在听什么歌曲。
更多细节可以访问我的 GitHub 库。
使用 Pandas 和 Scikit 实现数据标准化-学习
清洁数据集的完整指南—第 1 部分
杰里米·帕金斯在 Unsplash 上的照片
一个机器学习算法的成功高度依赖于输入模型的数据质量。真实世界的数据通常是脏的,包含异常值、缺失值、错误的数据类型、不相关的要素或非标准化的数据。这些中的任何一个的存在都将阻止机器学习模型正确地学习。出于这个原因,将原始数据转换成有用的格式是机器学习过程中的一个重要阶段。在预处理数据时,您会多次遇到的一种技术是归一化。
数据规范化是机器学习中的常见做法,它包括将数字列转换为通用比例。在机器学习中,一些特征值会多次与其他特征值不同。具有较高值的特征将主导学习过程。然而,这并不意味着这些变量对预测模型的结果更重要。数据标准化将多尺度数据转换为相同尺度。归一化后,所有变量对模型有相似的影响,提高了学习算法的稳定性和性能。
统计学中有多种归一化技术。在本文中,我们将讨论最重要的几个问题:
- 最大绝对缩放比例
- 最小-最大特征缩放
- z 值法
- 稳健缩放
此外,我们将用熊猫和 Scikit-Learn 解释如何实现它们。
那么,让我们开始吧💙
以下数据框包含用于预测二手车价格的多元回归模型的输入(独立变量):(1)里程表读数(km)和(2)燃油经济性(km/l)。在本文中,我们使用一个小数据集进行学习。然而,在现实世界中,所使用的数据集将会大得多。
你可以观察到,里程表读数从 120000 到 400000,而燃油经济性从 10 到 17。多元线性回归模型将比燃油经济性属性更重视里程表读数变量,因为它的值更高。然而,这并不意味着里程表读数属性作为一个预测因素更重要。为了解决这个问题,我们必须用归一化两个变量的值。❤️
最大绝对比例
最大绝对缩放通过将每个观察值除以其最大绝对值,在-1 和 1 之间重新缩放每个特征**。**
我们可以使用在熊猫中应用最大绝对缩放**。max()** 和**。abs()** 方法,如下所示。
或者,我们可以使用 Scikit-learn 库来计算最大绝对缩放比例。首先,我们用 maxabscaler 类创建一个 abs_scaler。然后,我们使用拟合方法学习缩放数据所需的参数(每个特征的最大绝对值)。最后,我们使用这些参数来转换数据。
正如你所观察到的,我们使用 Pandas 和 Scikit-learn 获得了相同的结果。下图显示了执行最大绝对缩放后的转换数据。
最小-最大要素缩放
最小-最大方法(通常称为归一化)通过减去特征的最小值然后除以范围,将特征重新缩放到 [0,1] 的固定范围。
我们可以使用在熊猫中应用最小-最大缩放**。min()** 和**。max()** 方法。
或者,我们可以使用 Scikit-learn 库中可用的 MinMaxScaler 类。首先,我们创建一个缩放器对象。然后,我们拟合缩放器参数,这意味着我们计算每个特征的最小和最大值。最后,我们使用这些参数对数据进行转换。
此外,我们可以获得由 fit 函数计算的最小值和最大值,以便用 data_min_ 和 data_max_ 属性对数据进行归一化。
下图显示了应用最小-最大要素缩放后的数据。正如您所观察到的,这种标准化技术将所有特征值重新调整到[0,1]的范围内。
正如你所观察到的,我们使用熊猫和 Scikit-learn 获得了相同的结果。但是,如果您想要执行许多数据转换步骤,建议使用最小最大缩放器作为管道构造器的输入,而不是使用熊猫执行规范化。
此外,切记最大绝对缩放和最小-最大缩放对异常值非常敏感,因为单个异常值会影响最小和最大值,并对结果产生重大影响。
z 得分法
z-score 方法(通常称为标准化)将数据转换为一个均值为 0 、标准差为 1 的分布。通过减去相应特征的平均值然后除以标准偏差来计算每个标准化值。
与最小-最大缩放不同, z 分数不会将特征重新缩放至固定范围。如果输入呈正态分布,则 z 值通常在 -3.00 到 3.00 (超过数据的 99%)之间。但是,标准化值也可以更高或更低,如下图所示。
重要的是要记住 z 分数不一定是正态分布的。它们只是缩放数据,并遵循与原始输入相同的分布。该变换后的分布具有平均值为 0 的和标准差为 1 的**,并且只有在输入要素遵循正态分布的情况下才会成为标准正态分布(见上图)。**
我们可以使用来计算熊猫**中的 z 分数。均值()**和 std() 方法。
或者,我们可以使用 Scikit-learn 库中可用的 StandardScaler 类来执行 z-score。首先,我们创建一个标准缩放器对象。然后,我们使用计算转换的参数(在这种情况下,表示和标准偏差**)。方法契合()。接下来,我们称之为。transform()** 方法将标准化应用于数据帧。。transform() 方法使用从生成的参数。fit() 方法来执行 z-score。
为了简化代码,我们使用了**。fit_transform()方法**将两种方法(fit 和 transform)结合在一起。
正如你所观察到的,这些结果与使用熊猫获得的结果不同。 StandardScaler 函数计算总体标准差,其中平方和除以 N (总体中值的数量)。
反之,。std()方法计算样本标准差,其中公式的分母是 N-1 而不是 N 。
为了使用 Pandas 获得相同的结果,我们将参数 ddof 设置为等于 0(默认值为 ddof=1),它表示计算中使用的除数( N-ddof )。
我们可以获得由 fit 函数计算的参数,用于标准化具有 mean_ 和 scale_ 属性的数据。如你所见,当在中设置参数 ddof 等于 0 时,我们在 Scikit-learn 和 Pandas 中获得相同的结果。std() 方法。
下图显示了应用 z 得分方法后的数据,该方法是使用总体标准差(除以 N)计算的。
稳健的缩放
在稳健缩放中,我们通过减去中值然后除以四分位间距来缩放数据集的每个特征。四分位数范围(IQR) 定义为第三个和第一个四分位数之间的差值,代表数据的中间 50%。数学上,鲁棒定标器可以表示为:
其中 Q1(x) 是属性 x 的第一个四分位数, Q2(x) 是中位数, Q3(x) 是第三个四分位数。
这种方法在处理包含许多异常值的数据集时非常方便,因为它使用的统计数据对异常值 ( 中值和四分位距)非常稳健,而以前的定标器使用的统计数据受异常值的影响很大,如最大值、最小值、平均值和
让我们看看异常值如何影响使用最小-最大缩放和鲁棒缩放缩放数据后的结果。
以下数据集包含 10 个数据点,其中一个是异常值(变量 1 = 30)。****
最小-最大缩放将变量 1 移向 0,因为与变量 2 相比存在异常值,变量 2 的点在 0 到 1 的范围内均匀分布。****
********
缩放前,第一个数据点的值为(1,1),变量 1 和变量 2 的值相等。转换后,变量 2 的值远大于变量 1 (0.034,0.142)。这是因为变量 1 有一个异常值。
相反,如果我们应用鲁棒缩放,两个变量在变换后具有相同的值(-1.00,-1.00),因为两个特征具有相同的中值和四分位间距,是被移动的值异常值。
********
现在,是时候对汽车数据集应用健壮的缩放了💜
正如我们之前所做的,我们可以使用 Pandas 来执行健壮的缩放。
中值被定义为分布的中点,意味着分布值的 50%小于中值。在熊猫中,我们可以用来计算。中位数()或。分位数(0.5) 方法。第一个四分位数是数据集下半部分的中值(25%的值位于第一个四分位数以下),可以用计算。分位数(0.25) 法。第三个四分位数代表数据集上半部分的中值(75%的值位于第三个四分位数之下),可以用计算。【分位数(0.75)】法。****
作为对 Pandas 的替代,我们也可以使用 Scikit-learn 库来执行健壮缩放。
如上所示,我们获得了与之前相同的结果🙌
下图显示了使用鲁棒缩放转换数据后的结果。
摘要
数据规范化包括将数字列转换为通用比例。在 Python 中,我们可以用非常简单的方式实现数据规范化。Pandas 库包含多种用于计算最常见的描述性统计函数的内置方法,这使得数据标准化技术非常容易实现。作为另一种选择,我们可以使用 Scikit-Learn 库将数据转换成通用的标度。在这个库中,已经实现了最常用的缩放方法。
除了数据标准化,我们还必须应用多种数据预处理技术来保证学习算法的性能。我们将在以后的文章中讨论其中的一些。🙌
感谢阅读:)
阿曼达💜
数据可观察性:如何防止数据管道损坏
数据停机时间、可观察性和可靠见解之间的关系
虽然用于分析、聚合和建模数据的技术和方法在很大程度上跟上了现代数据组织的需求,但我们处理破损数据管道的能力却落后了。那么,我们如何在这个太常见的问题变得令人头疼之前识别、补救甚至预防它呢? 答案就在数据行业的下一个前沿: 数据可观测性 。
在你成长的过程中,你有没有读过一本 选择自己的冒险 小说?你,主角,负责做出决定你史诗般旅程结果的选择,无论是杀死喷火龙还是踏上南极洲深处的旅程。如果您从事数据行业,这些“冒险”可能会有所不同:
数据分析师的追求
现在是凌晨 3 点。你已经花了 4 个小时对一个数据消防演习进行故障排除,你已经筋疲力尽了。您需要找出为什么您团队的 Tableau 仪表板没有从雪花中提取最新的数据,以便财务部门的 Jane 可以生成该报告…昨天。
数据工程逃脱
您正在迁移到一个新的数据仓库,并且没有办法知道重要数据存储在哪里。红移?天蓝色?Google Drive 里的电子表格?这就像一个电话游戏,试图弄清楚去哪里看,数据应该是什么样的,以及谁拥有它。
数据科学家的恶作剧
在你知道你公司的“好数据”在哪里之前,你需要入职 9 个月。你发现单个数据集有如此多的“FINAL _ FINAL _ v3 _ I _ PROMISE _ ITS _ FINAL”版本,以至于你再也不知道什么是 up,什么是 down,更不知道哪些数据表在生产中,哪些应该弃用。
听起来熟悉吗?
在深入探讨如何修复这个问题之前,我们先来说说数据管道破裂的常见原因: 数据宕机 。
数据停机时间的增加
在互联网的早期,如果你的网站宕机,没什么大不了的——你可以在几个小时内让它恢复运行,对客户几乎没有影响(因为,坦率地说,没有那么多,我们对软件的期望也低得多)。
快进到 Instagram、T2、抖音和 T4 的时代——现在,如果你的应用崩溃,这意味着对你的业务的直接影响。为了满足我们对五个九的正常运行时间的需求,我们构建了工具、框架,甚至是完全致力于解决这个问题的职业。
2020 年,数据是新的软件。
仅仅拥有一个伟大的产品已经不够了。每个认真保持竞争优势的公司都在利用数据做出更明智的决策,优化他们的解决方案,甚至改善用户体验。在许多方面,监控数据何时“中断”和管道何时被破坏的需求甚至比实现“五个九”更重要。正如一家拥有 5000 名员工的电子商务公司的一名数据主管最近告诉我的那样: “我公司的网站上有糟糕的数据比根本没有网站更糟糕。”
为了向应用程序宕机的概念致敬,我们将这个问题称为数据宕机 ,它指的是数据丢失、不准确或其他错误的时间段。数据停机会影响数据工程师、数据科学家和数据分析师,以及您公司中的其他人,导致时间浪费(数据团队工作时间的 30%之北)!),沉没成本,士气低落,也许最糟糕的是,对自己的见解缺乏信任。
数据停机往往被忽视,直到为时已晚,对您的数据管道造成严重破坏。图片由 蒂尔萨范迪克 上Unsplash。
以下是一些常见的数据宕机来源,也许它们会引起共鸣:
- 越来越多的数据正在从多个来源收集。随着公司越来越依赖数据来推动决策制定,越来越多的数据被吸收,通常达到千兆字节或兆兆字节!通常,这些数据资产没有得到适当的监控和维护,从而导致日后出现问题。
- 贵公司的快速发展,包括合并、收购和重组。随着时间的推移,不再与业务相关的数据不会被正确归档或删除。数据分析师和数据科学家不知道什么数据是好的,什么数据可以像渡渡鸟一样。
- 基础设施升级 迁移 。随着团队从本地迁移到云仓库,甚至在云仓库提供商之间迁移,复制数据表以避免在迁移过程中丢失任何数据是很常见的。当您忘记用新的、迁移的数据资产交叉引用旧的数据资产时,就会出现问题。
随着对数据收集、存储和应用程序的审查越来越严格,it 数据停机时间得到了应有的重视。
解决方案:数据可观察性
数据可观察性 ,一个来自 DevOps 和软件工程中最佳实践的概念,指的是一个组织完全了解其系统中数据健康状况的能力。通过将软件应用程序可观察性和可靠性的相同原则应用于数据,可以识别、解决甚至预防这些问题,让数据团队对其数据充满信心,从而提供有价值的见解。
数据可观察性可分为五大支柱:
图片由巴尔·摩西提供。
- 我的表最后一次更新是什么时候?我的数据应该多久更新一次?
- 分布:我的数据在可接受的范围内吗?
- 卷:我的资料完整吗?2000 排突然变成 50 排了?
- 模式:谁有权访问我们的营销表并对其进行了更改?
- 血统:我的数据哪里破了?哪些表或报表受到了影响?
数据可观察性提供了对数据管道的端到端可见性,让您知道哪些数据在生产中,哪些数据资产可以废弃,从而识别和防止停机。
一种数据可观察性方法,结合了自定义规则生成,以监控数据的特定维度何时被破坏。图片由巴尔·摩西提供。
实现数据可观察性的强大而全面的方法包括:
- 元数据聚合&编目。如果你不知道你有什么数据,你当然不会知道它是否有用。数据目录通常被整合到最佳的数据可观察性平台中,为您的数据生态系统提供了一个集中的、透明的视角,在一个视图中展示丰富的谱系、模式、历史更改、新鲜度、数量、用户、查询等。
- **自动监控&数据停机报警。**出色的数据可观察性方法将确保您是第一个知道并解决数据问题的人,让您能够在数据停机发生时立即解决其影响,而不是几个月后。最重要的是,这种解决方案需要最少的配置,而且几乎不需要设置阈值。
- 沿袭 追踪上下游的依存关系。强大的端到端沿袭使数据团队能够跟踪从 A(接收)到 Z(分析)的数据流,并在流程中纳入转换、建模和其他步骤。
- **既自定义&ML-生成规则。**我们建议选择一种两全其美的方法:使用机器学习来监控您的静态数据并确定应该设置什么规则,以及根据您的数据规格设置独特规则的能力。与编码到建模工作流或 SQL 包装器中的特殊查询不同,这种监控不会停留在“表 R 中的字段 T 的值今天低于 S”上
- **数据分析师、数据工程师和数据科学家之间的协作。**数据团队应该能够轻松快速地协作解决问题,制定新规则,并更好地了解数据的健康状况。
强大的端到端流程使数据团队能够跟踪其数据流,从接收、转换和测试,一直到生产、合并转换、建模和流程中的其他步骤。图片由巴尔·摩西提供。
有了这些指导原则,数据团队可以更有效地管理数据,甚至从一开始就防止数据停机。
那么,您的数据冒险将带您走向何方?
有兴趣了解有关贵组织数据可观测性的更多信息吗?把手伸向 巴尔摩西 和剩下的 蒙特卡洛团队 。
数据可观测性:数据工程的下一个前沿
介绍构建数据管道的更好方法
图片由 Unsplash 上的 Bekir Donmez 提供。
为了跟上数据创新的时钟速度,数据工程师不仅需要投资于最新的建模和分析工具,还需要投资于能够提高数据准确性和防止管道破裂的技术。解决办法? 数据可观测性 ,数据工程的下一个前沿和新兴支柱 数据可靠性范畴 。
随着公司越来越受数据驱动,这些丰富见解背后的技术变得越来越微妙和复杂。虽然我们收集、存储、聚合和可视化这些数据的能力已经在很大程度上跟上了现代数据团队的需求(想想:面向领域的数据网格、云仓库、数据可视化工具和数据建模解决方案),但是数据质量和完整性背后的机制已经落后了。
无论您的分析仪表板有多先进,或者您在云上的投资有多大,如果它吸收、转换和推送到下游的数据不可靠,那么您最好的计划都是徒劳的。换句话说,“垃圾入”就是“垃圾出”。
在我们讨论数据可靠性之前,让我们先讨论一下不可靠的“垃圾”数据是如何产生的。
好数据如何变坏
在过去 12 个月与数百个数据工程团队交谈后,我注意到好数据变坏有三个主要原因:1)单个数据生态系统中的数据源越来越多,2)数据管道越来越复杂,3)更大、更专业的数据团队。
越来越多的数据源
如今,公司使用数十到数百个内部和外部数据源来生成分析和 ML 模型。这些来源中的任何一个都可能在没有通知的情况下以意想不到的方式发生变化,从而危及公司用于决策的数据。
例如,工程团队可能会对公司的网站进行更改,从而修改对营销分析至关重要的数据集的输出。因此,关键营销指标可能是错误的,导致公司在广告活动、销售目标和其他重要的创收项目上做出糟糕的决策。
日益复杂的数据管道
数据管道越来越复杂,具有多个处理阶段和各种数据资产之间的重要依赖关系。由于缺乏对这些依赖关系的了解,对一个数据集的任何更改都可能会产生意想不到的后果,影响相关数据资产的正确性。
像改变一个系统中的单位这样简单的事情可能会严重影响另一个系统的正确性,就像火星气候轨道飞行器的情况一样。作为美国宇航局的一个太空探测器,火星气候轨道器由于数据输入错误而坠毁,该错误产生了非国际单位与国际单位的输出,使其过于接近火星。像航天器一样,分析管道在过程的任何阶段都极易受到最无害的变化的影响。
更大、更专业的数据团队
随着公司越来越依赖数据来推动智能决策,他们正在雇用越来越多的数据分析师、科学家和工程师来构建和维护数据管道、分析和 ML 模型,为他们的服务和产品以及业务运营提供支持。
沟通不畅或协调不充分是不可避免的,并且会导致这些复杂的系统随着变化而崩溃。例如,一个团队添加到数据表中的新字段可能会导致另一个团队的管道失败,从而导致数据丢失或部分丢失。在下游,这种不良数据可能导致数百万美元的收入损失、客户信任度下降,甚至是合规风险。
坏数据的好消息是什么?数据工程正在经历它自己的复兴,我们应该非常感谢我们在 DevOps 的同行,感谢他们为我们指引下一个前沿领域的一些关键概念和原则。
下一个前沿:数据可观察性
界定“垃圾数据”影响的一个简单方法是从软件应用程序可靠性的角度来看。在过去十年左右的时间里,软件工程师利用 New Relic 和 DataDog 等目标解决方案来确保应用程序的高正常运行时间(换句话说,工作的、高性能的软件),同时将停机时间(中断和落后的软件)降至最低。
在 data 中,我们把这种现象叫做数据宕机。数据宕机指的是数据不完整、错误、丢失或不准确的时间段,随着数据系统变得越来越复杂,它只会成倍增加,从而支持无止境的源和消费者生态系统。
通过将软件应用程序可观察性和可靠性的相同原则应用于数据,可以识别、解决甚至预防这些问题,让数据团队对其数据充满信心,从而提供有价值的见解。
图片由巴尔·摩西提供。
下面,我们将介绍数据可观测性的五大支柱。每个支柱都包含一系列问题,这些问题总体上提供了数据运行状况的整体视图。也许你会觉得它们很眼熟?
- 新鲜度:数据是最近的吗?最后一次生成是什么时候?包含/省略了哪些上游数据?
- 分布:数据是否在可接受的范围内?格式是否正确?完成了吗?
- 卷:数据都到了吗?
- 模式:什么是模式,它是如何改变的?谁做了这些改变,原因是什么?
- 沿袭:对于给定的数据资产,受其影响的上游来源和下游资产是什么?谁是生成这些数据的人,谁依赖这些数据来做决策?
一个强大而全面的数据可观察性方法需要通过一个集中的界面对这五大支柱进行一致而可靠的监控,该界面是关于数据健康状况的真实信息的集中来源。
端到端数据可靠性平台允许团队探索和了解他们的数据谱系,自动映射上游和下游依赖关系,以及这些资产的健康状况。图片由巴尔·摩西提供。
一个有效、主动的数据可观察性解决方案将快速、无缝地连接到您现有的堆栈,提供端到端的沿袭,允许您跟踪下游的依赖关系。此外,它将自动监控您的静态数据,而无需从您的数据存储中提取数据。这种方法可确保您满足最高级别的安全性和合规性要求,并扩展到要求最苛刻的数据量。
这种解决方案还需要最少的配置,并且实际上不需要设置阈值。它使用 ML 模型来自动学习您的环境和数据。它使用异常检测技术让你知道什么时候有东西坏了。此外,它不仅考虑了单个指标,还考虑了数据的整体视图以及任何特定问题的潜在影响,从而最大限度地减少了误报。
这种方法提供了丰富的上下文,能够快速进行分类和故障排除,并与受数据可靠性问题影响的利益相关方进行有效沟通。与特别查询或简单的 SQL 包装器不同,这种监控不会停留在“今天表 Y 中的字段 X 的值低于 Z”上
数据目录将关于数据资产的所有元数据都放在单一窗口中,因此您可以在单一视图中看到沿袭、模式、历史更改、新鲜度、容量、用户、查询等。图片由巴尔·摩西提供。
也许最重要的是,这种解决方案通过公开这五大支柱中有关数据资产的丰富信息,从一开始就防止了数据宕机事件的发生,以便能够负责任地、主动地进行更改和修改。
数据可观察性的下一步是什么?
就我个人而言,我对这个数据工程的新领域感到无比兴奋。随着数据领导者越来越多地投资于利用数据可观察性的数据可靠性解决方案,我预计该领域将继续与数据工程中的其他一些主要趋势相交,包括:数据网格、机器学习、云数据架构,以及数据产品的平台化。
有兴趣了解更多关于数据可观察性的信息吗?伸出手去 巴尔摩西 和剩下的 蒙特卡洛团队 。
有兴趣加入数据可靠性运动吗?把手伸向 蒙特卡洛团队 !
民主化人工智能是不相关的,数据是孤立的,如何建立一个人工智能公司
意见
数据超越一切
当我第一次听到“数据是新的石油”这句话时,我认为这是聪明的营销。
但是做了几年机器学习,我收回。
这是轻描淡写。
正确的数据可以启动公司,创造就业机会,解决实际问题。
要是有那么简单就好了。
你不能仅仅建立一个人工智能公司
最聪明的人工智能科学家无法在没有数据的情况下训练一个模型。
这对创业公司来说是一个先有鸡还是先有蛋的问题。
你需要数据来建立一个“AI 公司”。但是你需要一个正常运作的公司来收集特定领域的数据。
这解释了为什么:
- 公司假装做 AI
- 很少有产品以人工智能为核心
- (拥有数据的)大公司拥有巨大的优势
解决方案包括与大公司建立数据合作关系,以及利用公共数据集。
但是我提出一个替代方案。
建立业务(软件或其他),收集数据,然后使用 ML 来扩大业务。
从第一天起就把数据收集作为优先事项。与缺乏人才相比,缺乏数据是人工智能的更大障碍。
你不需要大数据,你需要小众数据
自动驾驶汽车和人工智能驱动的药物发现需要大量数据。
但是如果把一个问题的范围最小化,往往就不需要多少数据了。
特定烹饪中的食谱生成、优化温室番茄的水位以及酿造完美的浓缩咖啡可能不需要一百万个数据点。
如果你能结合狭义模型、领域知识和硬编码逻辑,自动化一项令人厌倦/耗时的工作,你就已经构建了一些有价值的东西。
艾将军多虑了。解决特定领域的特定问题。
人工智能的民主化被夸大了
根据定义,民主化意味着增加那些没有知识和资源的人的机会。
实际上,它是提供人工智能驱动的 API 的公司的营销。
轻松添加人工智能支持的聊天、图像识别或情感分析的能力对于适度增强现有产品非常重要。
但不是用于构建产品的核心。
- 它没有提供针对使用相同 API 的其他公司的护城河
- 你放弃了来之不易的数据,而大公司会用这些数据来训练它的模型
- 该 API 可能有一天会被弃用
你需要拥有你的模型来建立一个可持续发展的企业。
储存你自己的数据
我希望每个人都有足够的开放数据。没有。
对于一个 AI 创业公司来说,数据是你的护城河。
大公司有大量孤立的数据。
- 谷歌有浏览历史
- 脸书有你的图像、朋友和兴趣
- 亚马逊有购买历史
这些综合数据可能会催生一百家新公司。但不会。
你需要自己的私人数据仓库。你可以在成功后开源你所构建的东西。
用领域知识增强您的数据
如果数据是护城河。数据+领域知识是一片海洋。
大多数真正的机会是解决你不知道的问题,除非你在某个领域工作过。
给定 20 年的精确天气数据,我可以提出一些潜在的创业想法。但是一个农民,一个总承包商,或者一个物流公司,可以想出我无法想象的用例。世界上真正的问题更适合领域专家,而不是一群工程师。
标记需要领域专业知识的数据几乎不可能外包。我试过了。外包狗和猫的图像标签很容易。但是对法律案件进行分类需要专家。
您可能需要标记您自己的数据。糟透了。但如果只有你能做到,这是一件好事。
不要过度依赖公共数据集
如果你发现一个公共数据集的好机会,抓住它。但有趣的是,这种情况少之又少。
这种方法不太可靠,因为任何人都可以使用它,而且除非更新数据集,否则您可能无法生成额外的数据点。
作为世界上数据的一部分,公共数据集只占很小一部分。
重复我之前的例子,找到狗和猫的图像很容易。很难找到没有足够种子的汉堡面包的图像。
根据我的经验,这种影响在 NLP 中比在图像中更加明显。
收集你自己的数据。
这是一个机会
AI 有一个数据问题。我们知道未来会有更多的人工智能。所以解决这个问题是一个机会。
政府可以用数据刺激创新
政府拥有大量数据。并不是所有的都是敏感的。
开放数据和数据伙伴关系可以吸引公司解决具体问题,如果提供正确的数据,还可以产生经济价值。
我想到了这个鱼类黑客马拉松。
向矿工出售铲子
在历史上的淘金热期间,卖铲子比采矿更有利可图。用数据支撑 AI 公司是一个产品。我们需要更多:
- 数据市场
- 租赁领域专业知识的能力
- 数据监管
解决数据问题是用人工智能解决问题的一个组成部分。
结论
免责声明:我把 AI 和 ML 混为一谈。
人工智能有潜力解决很多问题。人工智能需要数据来做到这一点。
成为机器学习专家是不够的。获取和创造性地使用数据是一个首要的商业问题。
这并不容易,这是一件好事。当您拥有它时,它会提供一种超越竞争对手和其他人的技术专长的优势。
数据人员,来看看云吧
尼古拉斯·斯旺森在 Unsplash 上的照片
数据工程
向数据工程师、分析师和科学家简要介绍云平台,以及如何了解云中的数据
要说 云是未来 就要回溯 20 年。云已经来了。较新的公司确保他们不会建立自己的数据中心,而是使用 AWS、Azure 和 Google Cloud 等云提供商。也有一些小众玩家,如 Databricks、DigitalOcean 等。大多数老公司最终都会以某种方式转移到云平台。一些将使用混合(云+本地)模式运营。我想说的是,数据人员的工作将取决于他们对云的适应程度。
现在,有成百上千的课程会教你这些云技术。我自己已经参加了很多这样的课程,并且使用云平台已经大约七年了,我可以证明在开始他们的云之旅之前应该做些什么。
1.了解供应商
首先,了解主要的云提供商,他们提供的主要服务以及他们的优势领域和市场。根据我的理解,有三个明确的竞争者——AWS、Azure 和 Google,就像开始提到的那样。所有这些云提供商都有认证计划。虽然获得认证并不能保证你成为该平台的专家,但这意味着你必须了解该平台的基础知识,这对于入门来说已经足够了。
正如我所说,这三个认证和相关文档足以让您开始使用云。这并不意味着你必须走这条路来了解云。认证被高估了。直到最近我才全部做完。纳西姆·尼古拉斯·塔勒布有一句名言—
F 还是真人,如果某个东西在理论上行得通,但在实践中行不通,那就是行不通。对于学术来说,如果一个东西在实践中行得通,但在理论上行不通,那它就是不存在的。
实践总是胜过理论。所以,选择自己的路。但这可能是一个好的开始。
2.深入研究服务
所有主要的云提供商都提供一个帐户,在这个帐户中,你可以免费使用每月有限时间内的一些有限服务。你不需要支付任何费用。不过,你可能需要一张信用卡来开设账户。最好的起点是获得一个帐户。如果你不想这样做,你也可以使用几个云学习网站,这些网站提供对这些云提供商的实验室访问。其中一个例子是 Qwiklabs (来自谷歌)。
如果您已经开始了一个基本的认证学习路径,您可能知道所有与云中数据相关的服务。第一步是尝试最简单、最基本的服务,如关系数据库,然后逐步过渡到数据仓库、管道、编排器和 MPP 系统。几周前,我试图列出数据工程师应该知道的所有主要技术和概念。所有这些,不超过 10 个字。它包含了几乎所有值得初学者了解的云数据服务。
数据工程师必须知道的 10 个单词以内的概念
towardsdatascience.com](/complete-data-engineers-vocabulary-87967e374fad)
如果你完全是这方面的新手,我强烈推荐你在开始体验云计算之前,阅读这本由Robert Changairbneng—的第一部分、第二部分、第三部分撰写的关于数据工程的介绍。如果你已经学完了初级课程,所有这些云提供商都设计了针对特定数据的认证课程来提升你的技能。Azure 有 Azure 认证数据工程师项目,Google Cloud 有 Google Cloud 数据工程师项目,AWS 有 AWS 认证数据分析专业。
3.通过在线课程了解云
像 Udemy、Pluralsight、DataCamp、Coursera、Educative、edX、YouTube、ACloudGuru 等热门网站上有大量关于云计算的课程。学习的内容不缺。没有一个云平台还不能破解训练公式,所以市场上有过多的自由职业者或第三方训练者。但是,也有像谷歌授权培训师、 AWS 大使、 AWS 英雄这样的项目,面向真正活跃在社区中,推广各自服务的人。
在这一点上,我要说的是,个人自由职业培训师制作的学习内容质量要比官方培训视频好得多。说到这里,我不会完全拒绝官方视频。下面是 Google Cloud 在 Pluralsight 上发布的一篇关于 Google Cloud 上数据工程的精彩介绍。
这条道路为参与者提供了在谷歌上设计和建立数据处理系统的实践介绍…
www.pluralsight.com](https://www.pluralsight.com/paths/data-engineering-on-google-cloud-platform)
我最近破解了上面列出的所有这三个考试,我采取了不同的方法来破解它们。对于 AWS,我使用了 ACloudGuru 的优质内容和 Andrew Brown 在 freeCodeCamp 上的免费课程。对于谷歌云来说,它是 Udemy 上的一些随机课程,但主要是文档。对于 Azure 来说,它几乎都是文档。Azure 在文档方面做得非常出色。
4.学哪个云?
从一个开始,但要了解所有的人。技术世界正朝着多云的方向发展。大多数公司将使用不止一个云提供商来处理他们的工作负载。这非常有意义,因为不同的云提供商专注于不同类别的工作负载。例如,谷歌是处理大数据的专家。没有其他公司见过这么多数据。AWS 是第一个进入云市场的,比微软和谷歌想都要早很多年。所以,他们的优势在于拥有真正成熟的产品。Azure 有微软的优势。大多数商用电脑仍然运行 Windows。
HashiCorp 的联合创始人 Armon Dadgar 和 Mitchell Hashimoto 谈论多云。
所以,我会说,你应该从其中的任何一个开始,但要继续了解所有这些,以及越来越多的新兴云平台,如阿里云、甲骨文云等。如果你想学习像 Spark 这样非常具体的东西,那就去使用 Databricks 云产品学习吧。我最近破解了 Databricks Spark 开发者考试,发现他们的云平台真的很棒。
结论
当你在学习所有这些关于云的东西时,不要错过在云上的花费是非常重要的。可以说,对于大多数公司来说,这比拥有专用数据中心更划算,因为它可以大幅降低资本支出。几乎所有的云提供商的服务中都包含一个成本计算器,您可以使用它来研究成本。
要成为一名完全独立的工程师,你必须知道、理解并熟练使用云技术。关于这些不同的云平台,需要注意的另一件事是,大多数技术术语和技术实现在所有这些平台中都几乎是相同的。从概念上来说,如果你仔细想想,并没有什么显著的区别。学习一朵云意味着你已经学会了所有的云。所以,都认识。
由埃伯哈德·格罗斯加斯泰格在 Unsplash 上拍摄的照片
GCP 的数据管道:云功能基础
来源:谷歌云
大多数数据科学家更喜欢拥有他们模型的端到端数据管道,但是拥有管道需要大量的工程工作。
在本文中,我将讨论云功能,这是一个无服务器、简单且经济的选项。
第一步:日程安排
GCP 提供了一个简单的调度工具,叫做“云调度器”。从左上角的导航菜单中找到云调度程序。
给你的工作一个名字和描述。接下来,您需要提供计划的频率。如果您曾经使用过包括 Cron 作业在内的任何调度程序,您在这里都会很好。
选择时区和发布/订阅作为目标。
云调度程序用户界面
一旦你点击主题和有效载荷的发布/订阅选项。主题名称稍后将用作 Python 函数的名称,因此请记住使用 Python 中可接受的函数名称主题。现在给 payload 一些任意的字符串。
如果您喜欢使用命令行,可以运行以下命令:
gcloud alpha scheduler jobs create pubsub scheduler-name --schedule="0 8 * * *" --topic="my_pipeline_topic" --message-body=" "
现在,您应该能够在 Cloud Scheduler 中看到您的计划作业。
第二步:发布/订阅
我推荐你阅读谷歌关于 Pub/Sub 的文档。但是简单一句话,Pub/Sub 允许你在不同的应用之间发送消息。您可以将发布/订阅用于批处理和流数据管道。
现在使用该主题创建一个发布/订阅主题
gcloud pubsub topics create my_pipeline_name
您可以选择使用 UI 创建发布/订阅主题:
从用户界面创建发布/订阅主题
第三步:云功能
你可以选择从用户界面创建你的云功能,但我不建议这样做。首先,如果你的代码中有一个 bug,你将会丢失你的工作。第二,您很容易忘记您的更改和版本。
作为第一步,让我们在本地创建我们的函数,并将它们手动部署到 GCP。
你需要什么?
你需要一个“main.py”函数。这是所有函数和类的包装器。在 main.py 中应该有一个函数使用我们的云函数名。
your imports here
def my_pipeline_name(event,contex):
your_code_here
将其余的功能放在同一个文件夹中,这样更容易!
下面是根据谷歌对事件和背景的定义:
event (dict): The dictionary with data specific to this type of
event. The `data` field contains the PubsubMessage message.
context (google.cloud.functions.Context): The Cloud Functions event
`timestamp` field contains the publish time.
所以别管他们了!
创建一个. gcloudignore 文件。这个文件类似于一个. gitignore,但是用于云部署。您可以包含不想部署的文件(比如您保存在文件夹中用于本地测试的密钥)
用所需的包创建一个 requirements.txt 文件。
在运行过程中,您可能需要保存一些文件,但是您的云函数的根是只读的!您需要使用/temp/
目录来存放临时文件和可修改文件。
是时候部署了!
gcloud functions deploy my_pipeline_name --runtime python37
--trigger-topic my_pipeline_topic --timeout 540
这里有一个很大的限制!根据文档,云功能的最大超时为 9 分钟。
查看兹登科的文章和 GitHub 了解更多详情。
步骤 4:在 UI 上测试
转到 GCP UI 上的云功能,然后单击功能名称,它会将您重定向到一个名为“功能详细信息”的新页面,其中有最新的部署版本
云功能详细信息
在 general 选项卡中,您可以找到调用、执行时间、内存使用和活动实例。所有这些都是计费的重要因素(我知道云功能很便宜,但跟踪成本是一种很好的做法)。可以参考你 Romin 的关于云函数定价的文章。
你可以点击顶部中间的“编辑”,更改内存、功能或…
单击 Source,您将找到已部署的文件,您可以单击 edit 在线修改它们(不推荐)。
转到测试选项卡,点击TEST THE FUNCTION
,代码将运行,如果有任何问题,将返回一个错误。但这是对云功能的测试,Pub/Sub 和 Scheduler 呢?
您可以从导航菜单进入“云调度程序”,您会在您的作业名称前找到一个Run Now
按钮。你可以用它来测试和检查Result
栏下的信息。
第五步:密钥
我不喜欢在代码中部署我的秘密密钥,这里我将回顾一下我处理秘密的两个最佳选择。
第一个是将环境变量添加到云函数中。您可以使用 UI 或命令行。这个选项不是我最喜欢的,因为首先秘密就在 UI 中,其次我必须再次为其他功能部署它。
第二个选择是使用 GCP 的秘密经理。我将从 Dustin 关于管理云函数秘密的帖子中借用一些材料。
现在可以用云壳了。图标在搜索栏的右上方。
启用“机密管理器 API”:
gcloud services enable secretmanager.googleapis.com
创造一个秘密:
echo -n "your secret text here" | \
gcloud beta secrets create my-secret \
--data-file=- \
--replication-policy automatic
如果你的秘密文件中有双引号,那就用单引号括起来。
编写一个函数来检索您的秘密:
import os
from google.cloud import secretmanager
import json
def get_secret*(*secret_name*)*:
client = secretmanager.SecretManagerServiceClient*()* project_id = 'my_gcp_project'
resource_name = f"projects/*{*project_id*}*/secrets/*{*secret_name*}*/versions/latest"
response = client.access_secret_version*(*resource_name*)* secret_string = response.payload.data.decode*(*'UTF-8'*)* secret_string = json.loads*(*secret_string*)* return secret_string
您可以在剩下的代码中调用这个函数来检索您的密钥。确保将“google-cloud-secret-manager”添加到您的需求文件中。
你准备好了!去 UI 测试!
第六步:连接回购
即使您可以从本地部署,Google 也提供了一个选项,用于从 GitHub 或 BitBucket 之类的源代码控件进行部署。让我们一步一步来。
- 在 Google Cloud 控制台中,打开云源代码库。
- 开放云源代码库
- 点击添加存储库。
- 将打开添加存储库页面。
- 选择连接外部库并点击继续。
- 将打开连接外部存储库页面。
- 在项目下拉列表中,选择镜像存储库所属的 Google Cloud 项目。
- 在 Git 提供者下拉列表中,选择 Bitbucket 。
- 选中复选框以授权云源存储库存储您的凭据。
- 点击连接到铲斗。
- 使用您的机器用户凭据登录 Bitbucket。
- 点击授权 GoogleCloudPlatform 。
- 此选项授予 Google Cloud 对您的存储库的读取权限。
- 授权完成后,您将返回到连接外部存储库页面。将打开存储库列表。
- 从存储库列表中,选择要镜像的存储库。
- 点击连接选中的库。
在左上方的“云资源存储库”下方,您可以找到您的存储库的名称以及活动分支。点击下拉菜单,更改查看其余分支。
从云回购部署
您可以使用以下命令从云源存储库部署到云功能:
gcloud functions deploy my_pipeline_name \
--source [https://source.developers.google.com/projects/[gcp_project_name]/repos/[cloud_source_repository_root]/moveable-aliases/[branch]/paths/[folder](https://source.developers.google.com/projects/[gcp_project_name]/repos/[cloud_source_repository_root]/moveable-aliases/[branch]/paths/google_ads/[folder)_under_that_branch]/ \
--runtime python37 \
--trigger-topic my_pipeline_topic --timeout 540
现在检查你的功能,版本应该增加。前往TESTING
选项卡,享受通过测试的乐趣吧!
现在您已经将您的存储库镜像到“云源存储库”了,如果您检查您的云函数的源代码,您会看到它现在指向您的 repo!
这一步似乎是多余的,因为您可以从本地部署,但是让我们进入下一步。
第七步:CI/CD
到目前为止,我们已经学习了如何从本地和从云 repo 进行部署,下面让我们学习如何设置 CI/CD!
您需要在您的目录中添加一个“cloudbuild.yaml ”,并放入以下内容:
steps:
- name: gcr.io/cloud-builders/gcloud
args:
- functions
- deploy
- my_pipeline_name
- --source=https://source.developers.google.com/projects/[[gcp_project_name](https://source.developers.google.com/projects/[gcp_project_name]/repos/[cloud_source_repository_root]/moveable-aliases/[branch]/paths/google_ads/[folder)]/repos/[[cloud_source_repository_root]](https://source.developers.google.com/projects/[gcp_project_name]/repos/[cloud_source_repository_root]/moveable-aliases/[branch]/paths/google_ads/[folder)/moveable-aliases/[[branch]](https://source.developers.google.com/projects/[gcp_project_name]/repos/[cloud_source_repository_root]/moveable-aliases/[branch]/paths/google_ads/[folder)/paths/google_ads/[[folder](https://source.developers.google.com/projects/[gcp_project_name]/repos/[cloud_source_repository_root]/moveable-aliases/[branch]/paths/google_ads/[folder)_under_that_branch]/
- --trigger-topic=my_pipeline_topic
- --runtime=python37
- --timeout=540
现在从 GCP 的导航菜单转到云构建,转到触发器,并点击“创建新的”。现在应该是直截了当了!给你的触发器一个名称和描述。我想在每次推送到分支时触发构建,所以将选择该选项。在 source 部分,我将找到步骤 6 中的镜像 repo,并输入分支的名称。
由于构建配置保存在 cloudbuild 中,我将选择第一个选项,并将路径复制并粘贴到 YAML 文件。
一切就绪,单击“创建”并享受您的 CI/CD 管道!
数据预处理:分步指南
我们知道,对数据进行充分的分析和特征工程会产生良好的可视化效果,但是人们在开始时经常会遇到问题。
来源:BYroute 79根据 CC BY-NC-SA 2.0 获得许可
在这篇文章中,让我们来看看数据预处理的不同步骤。
1.用什么编码平台?
虽然 Jupyter Notebook 是一个很好的起点,但 Google Colab 始终是协作工作的最佳选择。在这篇文章中,我将使用 Google Colab 展示数据预处理步骤。
2。如何为进一步的分析准备原始数据?
在针对任何问题优化数据时,遵循正确的步骤以达到正确的目的是很重要的。
## Import required libraries
import numpy as np
import pandas as pd## Upload dataset
from google.colab import files
uploaded = files.upload()
2.1 选择要上传的文件
## Read a .csv file to pandas dataframe
df = pd.read_csv(uploaded['data.csv'])## Read a .json file to pandas dataframe
df = pd.read_json(uploaded['data.json'])## Read an excel file to pandas dataframe
df = pd.read_excel(uploaded['data.xlsx'])
答。csv 文件可以基于;
或任何其他分隔符(包括空格)进行分隔。
2.1.1 示例:以空格或制表符作为分隔符的 CSV 文件
*##* Read a .csv file to a dataframe with delimiter as space or tab:
df = pd.read_csv('data.csv', sep='\s+', engine='python')Output :
Name Age City
0 Jack 34 Sydney
1 Jill 31 Melbourne
2.1.2 示例:具有多个分隔符的 CSV 文件
*##* Read a .csv file to a dataframe with multiple delimiters :
df = pd.read_csv('data.csv', sep='[:,|_]', engine='python')Input :
Name,Age|City
Jack,34_Sydney
Jill:31,Melbourne
Adam,16:New YorkOutput :
Name Age City
0 Jack 34 Sydney
1 Jill 31 Melbourne
2 Adam 16 New York
3。描述数据有哪些不同的方式?
3.1 数据的维度
df.shape
# df is the dataframe object name whose dimension we want to obtain
3.2 从数据集中删除重复项
df.drop_duplicates(inplace=True)
inplace=True
确保 dataframe 对象被修改,但不创建其副本。如果你需要返回数据帧的副本,使用inplace=False
代替。
3.3 每个数字列的描述
df.describe()
describe()
通过最小值和最大值以及平均值、中值、标准偏差&等几个值,帮助获得数据集的基本信息。
3.4 获取数据集的第一行或最后几行
df.head(5) # returns first '5' rows of the dataframe
df.tail(5) # returns last '5' rows of the dataframe
3.4 列名
如果数据集包含大量的要素(列),它有助于获取整个要素列表。使用df.columns
以描述性格式返回数据帧中所有列的名称。
df.columnsOutput:
Index(['MSSubClass', 'LotFrontage', 'LotArea', 'OverallQual', 'OverallCond', 'YearBuilt', 'YearRemodAdd', 'MasVnrArea', 'BsmtFinSF2', 'SalePrice'], dtype='object')
3.5 检查列的数据类型和每列中的条目数:
df.info()
3.6 删除数字列中的特殊字符
现在,在几个实例中,包含数字数据的列可以具有“对象”数据类型。由于缺少数据点,一些特殊字符如**?**
或space
可能出现在连续变量中。在这种情况下,我们将检查唯一条目,以删除它们并更改数据类型:
for col in ['names of each column containing object datatype with numeric data points']:
uni_val_col = df[col].unique()
print ('The unique values in ' , col , 'are ', uni_val_col)## Convert string datatype to float wherever required and change special characters to NaN
for col in ['names of each column containing object datatype with numeric data points']:
df[col] = pd.to_numeric(df[col], errors='coerce')
这将某些列的特殊字符转换为NaN
(非数字)值,并转换为numeric
类型。
3.7 创建独立的连续和分类数据框架
## Create a dataframe with continuous columns
df_cont = df.select_dtypes(include = ['int64','float64'])## Create a dataframe with categorical columns
df_cat = df.select_dtypes(include =['object'])
3.8 从分类列中删除特殊字符
我们应该在分类列中检查类似的特殊字符(如 3.6 节所述),并用适当的值替换它们。
df.replace(to_replace=["?", ";"], value=np.nan)
4。缺失值处理
没有输入缺失值的最佳方法。它总是取决于问题的类型。在这里,我们只关注执行分析时要遵循的程序。
4.1 查找缺失值百分比
在这里,我们可以看到如何获得我们在 3.7 节中创建的连续数据帧中缺失值的百分比
# Percentage of missing values in each dataframe along with visualizationtotal = df_cont.isnull().sum().sort_values(ascending=False)
percent = df_cont.isnull().sum()/df_cont.isnull().count()).sort_values(ascending=False)
missing_data = pd.concat([total, percent], axis=1, keys=['Total', 'Percent'])
f, ax = plt.subplots(figsize=(15, 6))
plt.xticks(rotation='90')
sns.barplot(x=missing_data.index, y=missing_data['Percent'])
plt.xlabel('df_cont', fontsize=15)
plt.ylabel('Percent of missing values', fontsize=15)
plt.title('Percent missing data by feature', fontsize=15)
missing_data
输出:
我们可以将同样的方法应用于分类数据框架**df_cat**
4.2 缺失值的插补
数字数据框架
任何列的缺失值都可以通过均值、中值或众数进行估算。如果列中的数据点没有太大的偏差,对于连续数据点,中值比平均值更适合用于替换空值。
df_cont.'columnname'.fillna(features.Unemployment.median(), inplace=True)
与其他方法相比,我更喜欢用 KNN 插补来处理缺失值,因为它能提供更好的结果。
from sklearn.impute import KNNImputer
imputer = KNNImputer(n_neighbors=10)
df_data = imputer.fit_transform(df_cont)## Creating a new dataframe of the imputed data
df_num = pd.DataFrame(df_data, columns = df_cont.columns )
4.2.2 分类数据框架
在分类数据点的情况下,我们可以用模式来代替它
## Replacing NaN with mode for a column
df_cat.replace({'NaN':'four'} , inplace =True)
5。数据分发
5.1 数字数据帧的图形表示
## Plot distplot for continuous data columns
for col in df_num.columns:
plt.figure()
sns.distplot(df_num[col])
5.2 分类数据框架的图示
## Plotting bar plots for categorical data columns
for col in df_cat.columns:
plt.figure()
sns.countplot(x=col, data=df_cat)
plt.xticks(rotation=90)
6。异常值的处理
6.1 异常值百分比和其他描述性统计措施
异常值是可能影响也可能不影响模型的任何特征的极值。要获得每个数值或分类属性中异常值的百分比,我们可以使用-
# Use the appropriate dataframe in place of "dataframe_name" in the code below, i.e. in this case **df_num** and **df_cat**df_outliers = pd.DataFrame(index=dataframe_name.columns, columns=['outliers', 'outliers%']) for col in dataframe_name.columns:if any(x in str(dataframe_name[col].dtype) for x in ['int', 'float']):df_outliers.loc[col, 'count'] = len(dataframe_name)
df_outliers.loc[col, 'q1'] = dataframe_name[col].quantile(0.25)
df_outliers.loc[col, 'q3'] = dataframe_name[col].quantile(0.75)
df_outliers.loc[col, 'iqr'] = df_outliers.loc[col, 'q3'] - df_outliers.loc[col, 'q1']
df_outliers.loc[col, 'lower'] = df_outliers.loc[col, 'q1'] - (3 * df_outliers.loc[col, 'iqr'])
df_outliers.loc[col, 'upper'] = df_outliers.loc[col, 'q3'] + (3 * df_outliers.loc[col, 'iqr'])
df_outliers.loc[col, 'min'] = df[col].min()
df_outliers.loc[col, 'max'] = df[col].max()
df_outliers.loc[col, 'outliers'] = ((dataframe_name[col] < df_outliers.loc[col, 'lower']) | (df[col] > df_outliers.loc[col,'upper'])).sum()
df_outliers.loc[col, 'outliers%'] = np.round(df_outliers.loc[col,
'outliers'] / len(dataframe_name) *100)df_outliers
我们也可以对每个特征使用箱线图来获得相同的图形表示。
6.2 异常值的处理
有不同的方法来处理异常值,z-score 是最简单的一种。
from scipy import statsz_scores = stats.zscore(dataframe_name)
abs_z_scores = np.abs(z_scores)
entries = (abs_z_scores < 3).all(axis=1)
dataframe_name = dataframe_name[entries]
这就完成了我们最初的数据预处理!我们现在可以从可视化和特征工程开始,使我们的数据集模型就绪。
使用火花数据帧进行数据准备
使用 PySpark 继续调查金融服务消费者投诉数据库
当你向消费者金融保护局投诉时,你希望得到的平静——照片由 Unsplash 上的 Stephen Walker 拍摄
正如我们在上周的博客中看到的,三大信用报告机构是美国联邦金融服务消费者投诉数据库中被投诉最多的公司之一。想想你的信用评分被用来做的每一件事都很有趣:获得贷款、租公寓、购买手机套餐。算了吧。与其说有趣,不如说可怕。因此,今天我们将深入挖掘投诉数据库,回答我一直在思考的几个问题:
- 收到的投诉数量与星期几有什么关系?
- 这些年来投诉数量有什么变化?
- 投诉数量每月有何变化?
- 哪个州的居民抱怨最多?
- 不同州的人提交投诉的比率不同吗?
- 哪些产品被投诉最多?
一旦你有了 Spark 数据框架中的数据(如果没有,查看上周的文章),你就准备好做一些探索和清理了。 PySpark 数据框架、 PySpark 列和 PySpark 函数文档肯定会成为你的朋友,因为你在自己的环境中工作(分别是 Ross、Monica 和 Chandler……对不起 Joey,我仍然不确定你在数据科学世界中的位置)。对于我在美国联邦金融服务消费者投诉数据库上的项目,我将计数、填充和删除 nan,将 date 列转换为 datetime 并提取日期特征,并对照可接受值列表检查值。
使用 Jupyter 笔记本时,更易于使用的输出格式
在开始之前,我建议您像这样设置 Spark 配置:
spark.conf.set('spark.sql.repl.eagerEval.enabled', True)
这个设置使得输出更像熊猫,而不像命令行 SQL。此后,您不再需要指定 show()来查看输出。或者,您也可以使用.toPandas()
或.toPandas().T
(用于移调)来查看熊猫风格的输出。请记住,仅在足够小以适合内存的数据帧上执行此操作。太大的pandas
数据帧很容易使你的内核崩溃。
计算 nan 和 Nulls
请注意,在 PySpark 中,NaN 与 Null 不同。这两者也不同于空字符串"",因此您可能希望在任何数据集特定填充值之上检查其中的每一个。
像这样检查 nan:
from pyspark.sql.functions import isnan, when, count, coldf.select([count(when(isnan(c), c)).alias(c) for c in df.columns])
您可以在这里看到,这种格式肯定比标准输出更容易阅读,标准输出不适合长列标题,但它仍然需要向右滚动才能看到剩余的列。
这个数据集没有 NaNs,所以我转到 Null。
您可以使用以下代码计算空值:
from pyspark.sql.functions import when, count, coldf.select([count(when(col(c).isNull(), c)).alias(c) for c in
df.columns]).toPandas().T
检查重复
为了检查重复项,我比较了 df.count()和 df.distinct()。计数()。在这种情况下,我没有。
处理空值
接下来,我决定删除 company_response_to_consumer 中值为 null 的那一行。这里我们看到它和熊猫很像。
df_clean = df.dropna(subset='company_response_to_consumer')
对于 consumer _ contracted 列,我决定用 No 替换 null 值,同时为这一更改添加一个 flag 列:
# add flag column
df_clean = df_clean.withColumn('null_c_disputed',
df_clean['consumer_disputed?'].isNull())# fill na in consumer_disputed? with 'No'
df_clean = df_clean.fillna('No', subset=’consumer_disputed?’)
同样,这与 pandas 非常相似,除了用于添加列的新语法“withColumn”)。在下一节中,您将看到添加新列的另一种方法。
将字符串转换为日期(时间)并生成日期相关特征
from pyspark.sql.functions import (to_date, datediff, date_format,
month)# add datetime columns
df_clean = df_clean.select('*', to_date(df_clean['date_received'],
'MM/dd/yyyy').alias('date_received_dt'))
df_clean = df_clean.select('*',
to_date(df_clean['date_sent_to_company'],
'MM/dd/yyyy').alias('date_sent_to_company_dt'))# drop string date columns
df_clean = df_clean.drop(‘date_received’) \
.drop(‘date_sent_to_company’)
现在,我准备添加我的新功能:
# add time difference between receipt and sent to company
df_clean = df_clean.withColumn('transit_time',
datediff(df_clean['date_sent_to_company_dt'],
df_clean['date_received_dt']))# add submitted day of week (1=Monday, 7=Sunday)
df_clean = df_clean.withColumn('dow_submitted',
date_format('date_received_dt', 'u') \
.alias('dow_submitted'))# add submitted month, year
df_clean = df_clean.withColumn('y_submitted',
date_format('date_received_dt', 'y') \
.alias('y_submitted')) \
.withColumn('m_submitted',
month('date_received_dt') \
.alias('m_submitted'))
这让我能够研究我们数据集的时间方面
有趣的是,尽管有网上表格,但人们大多在投诉。我想知道这是如何按提交类型划分的。
这里似乎确实有周期性模式的可能性,但仅从这张图表上很难说。未来调查的另一个领域。
与可接受值列表相比,来自<75k 2012 to 275k in 2019.
的投诉明显呈上升趋势
我使用州缩写列表清理了我的 state 列,用一个值“unknown”替换了所有非标准响应。
# add clean state column, drop original column, rename new column
df_clean = df_clean.withColumn(‘state_c’, when(col(‘state’)
.isin(states),
col(‘state’)) \
.otherwise(‘unknown’)) \
.drop(‘state’) \
.withColumnRenamed(‘state_c’, ‘state’)
我最终得到了 26k 个“未知”状态的行——这是限制输入的主要原因,但至少现在已经包含了,而不是一大堆随机的错误输入的状态值。
有了这个,我按州分组,并把我现在的 50 行 2 列的数据框架转换成熊猫。然后,我将这个数据框架与我基于州的数据连接起来(谢谢 SimpleMaps CC4.0),并使用 geopandas(以及来自census.gov的 shapefiles)绘制图表。
state_counts = df_clean.groupby(“state”).count().toPandas()
在 GeoPandas 中,我发现阿拉斯加最西部的岛屿与我的可视化效果不太好,于是选择今天只绘制美国的连续部分——改天再详细介绍如何分离和操作形状优美的多多边形。
这仍然不是一个非常有吸引力的投影选择(强迫一个地球仪在一个平面屏幕上),但我们正在了解大多数投诉来自哪里的要点——人口最多的州。我想公平竞争,并考虑人口数量:
choropleth 会自动缩放颜色,因此我们必须有一个投诉提交量不成比例的小州。稍加挖掘就会发现,DC 的华盛顿州以每 100 名居民 1.1 起的投诉率领先。
按投诉计数的产品
最后,我执行了另一个groupby().count()
来查看哪些产品是最值得关注的。
我们发现信用报告在前四个最有问题的产品中出现了两次。这与我们在我之前的博客中发现的相吻合,三大信用报告机构 Equifax、Experian 和 Transunion 是投诉最多的三家金融公司。
一如既往,你可以在 GitHub repo 上查看详情。编码快乐!
数据准备——alter yx,Knime 还是 Python?
你选择的工具是什么?
米卡·鲍梅斯特在 Unsplash 上的照片
我们都听说过,在建立机器学习模型时,数据清理是 70%的任务。收集正确的数据、清理数据和合并数据集是数据建模工作的一半以上。数据准备不仅在数据建模中很重要,对于所有类型的分析工作和您构建的任何仪表板(如使用 Power BI 或 Tableau)也同样重要。
“数据准备”有许多方法,包括专门用于数据建模的商业软件。让我们看看本文中的 3 种方法——Alteryx、Python 和 Knime——并对它们进行比较。
正如我之前关于 Alteryx 的文章一样,我将使用 SEMMA 方法。在这篇文章中,我将只谈论样本,探索和修改阶段。
作者图片
我发现 SEMMA 方法非常有用,因为它为数据准备和建模提供了一种直观的方法。但是,您可以使用任何适合您的需求和偏好的数据准备方法。
采样 :流程从数据采样开始,即选择合适的数据集进行建模。数据集应该足够大,以包含足够的信息来有效地建模,但也应该足够小,以有效地使用。
探索 :在这个阶段,我们通过探索变量之间预期的和未预期的关系来理解数据,并借助数据可视化来发现任何异常。
修改 :修改阶段包含选择、创建和转换变量的方法,为数据建模做准备。
这些方法和逻辑可以复制到任何数据集。在下面的例子中,我已经使用波士顿房产数据集进行了演示。关键在于探索阶段,在此阶段,您估算缺失值并执行异常值分析。
你可以在这里找到所有申请的副本!
巨蟒:
样品:
在 Python 中进行数据加载和准备时,我使用了以下逻辑。
读入数据(使用 read_csv)->将数据添加到 pandas dataframe (pd.read_csv)->选择相关属性 ptype–>识别缺少值的列(使用 count()函数)->删除所有与分析无关的列,如名称等。(使用 dropna())
示例的 Python 代码
探索:
在上一个阶段,我们确定了 6 列缺失值,在这个阶段,我们将估算这些缺失值。一些估算策略包括:
均值:对于区间变量,一种策略是用均值或中值进行估算。在这种情况下,我们将使用 mean()函数估算 land_sf。
模式:对于分类变量,我们将使用模式来估算。
计算:对于一些变量,你可能需要做一些计算。例如,在我们的例子中,R _ BTH _ 样式 2、R _ BTH _ 样式 3、R _ 基奇 _ 样式 2 和 R _ 基奇 _ 样式 3 不能直接估算。如果房子的浴室少于两个,R _ BTH _ 样式 2 将具有空值。在这种情况下,我们将使用“NA”替换它
探索阶段:用平均值估算 LAND_SF,用模式估算 STRUCTURE_CLASS
探索阶段:用 YR _ BUILT 估算 YR_REMOD
估算浴室和厨房风格
修改:
现在,在这个阶段,我们有相对干净的数据。下一步是添加分析所需的任何额外变量(如年龄、YR_SINCE_REMOD),确保预测变量呈正态分布(对数变换 AV_TOTAL ),并且必须使用一个热编码对所有分类变量进行编码
修改阶段的 Python 代码
KNIME:
Konstanz Information Miner 是一个免费的开源数据分析、报告和整合平台。KNIME 通过其模块化的数据流水线概念,集成了用于机器学习和数据挖掘的各种组件。
这是快速准备数据的最佳工具之一,不需要任何编程背景。您可以快速合并不同的数据集,过滤行/列,连接列等。
链接到 Knime 例子这里!
样品:
在“示例”中,我们将使用行过滤器选择相关的 PTYE,使用列过滤器过滤掉列,然后使用统计数据块和行过滤器的组合来查找缺失值。我们将多次使用该列来检查缺失值。
样品台
列过滤器和行过滤器
缺少值和统计块的列
探索:
这里的步骤与 Python 中的相同。在这一阶段,我们将估算所有缺失的变量。我们将使用:数学公式、缺失值(估算模式和中值)和规则引擎块。这些模块如下所示。如您所见,您可以从块中的各种可用选项中进行选择,或者键入一个数学公式,类似于我们使用 excel 的方式
探索区块
I:数学块 ii)缺少值 iii)规则编辑器
修改:
这是数据准备的最后阶段。在这一阶段,我们将使用数学公式计算一些新变量,如年龄和 YR_SINCE_REMOD,并对预测变量进行对数变换,最后对数据进行分区(如下所示)。
修改阶段
隔墙砌块
Alteryx:
Alteryx 是一款出色的数据准备工具。它不是一个开源工具,但是 Alteryx 提供了一个试用许可。你可以看看我之前在 Alteryx 上发表的文章中关于 Alteryx 建模的介绍。
样本:
在’ Sample '阶段,我们将数据加载到 Alteryx 中,按 property type = 101 (单户住宅)进行过滤,并删除分析不需要的列(如姓名、地址和与单户住宅无关的行)。
样品台
Alteryx 允许你创建“容器”,在这里你可以将一个函数的所有模块组合在一起,如上图所示。我创建了一个名为“查找缺少值的列”的容器来完成这个任务。我已经多次重复使用这个容器来检查是否所有缺失的值都被输入了
缺少值的列(容器的输出)
探索:
这一阶段包括通过探索变量之间预期和未预期的关系来理解数据,并在数据可视化的帮助下发现任何异常。
在此阶段,我们将估算所有缺失的数据,为建模做准备。在最后一步中,我们确定了 7 个缺少值的列。在这一步,我们将估算这些列。
1)用平均值估算 LAND_SF。2)YR _ REMOD = YR _ build,STRUCTURE_CLASS 用 Mode 估算。3)估算浴室风格和厨房风格
修改:
在这一步中,我们将使用公式块转换变量/创建新属性。我们将计算年龄、YR_SINCE_REMOD 并对预测变量进行对数变换,如下所示。
添加分析所需的新变量。
结论:
Python 拥有丰富的库和支持(书籍和在线支持社区),对于任何有编程背景的人来说都是一个很好的工具。
对于没有编程背景并且正在寻找免费工具的人来说,Knime 是一个很好的选择。当我还在学习如何使用 Python 编程时,Knime 是我大学时代的首选工具。伟大和快速的工具,合并数据集,过滤出行和列,并添加新的列。
Alteryx:许多公司都在与 Alteryx 合作他们的分析和数据科学项目。Alteryx 允许您轻松地将数据源与许多现成的自动化构建模块结合起来,这使得例行的数据准备变得非常容易。
数据准备的工具选择完全是个人喜好。我建议选择一个您最熟悉的工具来加速数据准备过程,以便您有更多的时间进行数据建模。
参考文献:
- 数据分析的艺术和科学”,作者 Edward R. Jones 博士,德克萨斯 A&M 分析项目
- 使用 SAS Enterprise Miner、Barry de Ville 和 Padraic Neville 进行分析的决策树
- 德克萨斯 A&M 分析计划
- 所有截图来自 Python,Knime 和 Alteryx 作者
组织病理学癌症检测的数据准备指南
关于如何为 Kaggle 组织病理学癌症检测的模型训练准备数据的指南。
Kaggle 是数据科学和机器学习挑战的绝佳主持人。其中之一是组织病理学癌症检测挑战赛。在这个挑战中,我们提供了一个图像数据集,我们应该在这个数据集上创建一个算法(它说的是算法,而不是明确的机器学习模型,所以如果你是一个天才,有一个替代的方法来检测图像中的转移性癌症;去吧!)来检测转移癌。
这篇文章是关于如何准备 Kaggle 数据集的指南,该指南涵盖了以下四个方面:
- 如何从 Kaggle 将数据集下载到您的笔记本中
- 如何扩充数据集的图像。
- 如何平衡目标分布,并为训练/测试/验证拆分数据。
- 如何在 Keras 中为模型训练构建数据?
在笔记本中下载数据集
使用下面的命令下载 kaggle 包。我在谷歌的 Colab 上运行它们,但是你应该可以用你的命令行/Jupyter 笔记本来运行它们。
为了使用 Kaggle 的 API 用你的账号下载数据,你需要做以下两件事。
- 转到您的帐户设置,滚动到 API 部分,单击过期 API 令牌删除以前的令牌(如果您有任何令牌),然后单击创建新的 API 令牌。这将下载一个 ‘kaggle.json’ 文件。
- 将此文件上传到您的项目目录。
然后运行下面的代码,该代码使用 json 文件授予访问权限,并下载数据集。
解压缩 zip 文件。这需要几分钟的时间,因为它包含大约 6–7 GB 的数据。
此时,你应该有两个文件夹,和两个 csv 文件。
- 包含训练集图像的“train”文件夹
- 包含测试集图像的“测试”文件夹
- 一个“train _ labels”CSV 文件,包含每个图像的 id 及其相应的标签(0 表示无癌症,1 表示有癌症)。
- 一个“sample _ submission”CSV 文件,它是一个示例,说明如果您想参加 Kaggle 竞赛,您应该如何提交您的结果。
数据扩充
什么是数据增强,我们为什么要这样做?从本质上来说,数据扩充是一种通过对数据进行细微更改来增加图像数据集大小的方法。我们的目标是将我们的模型推广到更多通过图像增强引入的例子。更重要的是,图像增强还允许我们的模型概括不同类型图像的不同版本。
看下图。假设左边被画得可怕的猫来自训练数据集,但是右边的猫在测试数据集中。从字面上看,它们是相同的图像,只是右边的图像被翻转了。人类能够很容易地注意到这一点,但是模型可能无法成功完成这项任务,并且无法在测试数据集中识别它。理想情况下,您希望您的模型不关心图像的变化,并正确地对图像进行分类,这就是为什么您引入图像的增强版本,以便模型可以更好地概括。
增强图片的示例
这是一个函数的代码,它通过对图像应用各种变换来放大图像,例如改变图像的对比度、增加图像的亮度、应用随机旋转/移动。这里的代码引用自。
然后,我们使用此功能来扩充“train”文件夹中提取的图像。下面的代码生成 X 数量的新图像(基于一个名为 ‘images_to_generate’ 的变量,您可以更改该变量),方法是从我们的 train 集中随机选择图像,应用上面的增强功能,然后将图像保存在 train 文件夹中,并使用“增强的”+其以前的 ID 作为新名称。最后,我们还将标签和名称附加到 train_labels csv 文件,并保存一个新的 csv 文件,该文件也包含增强图像的 ID 和标签。
平衡目标分布
在机器学习中,我们希望确保我们的模型能够很好地处理我们扔给它的所有类型的数据!如果我们盲目地使用所有可用的训练数据,可能出现的一个问题是不平衡的类别/目标分布的情况。这意味着你的数据集包含一个或多个类比其他类更多的观察值。如果我们在这个完整的数据集上训练我们的模型,我们的模型将在预测具有更多数据点的类方面变得非常好,而在分类其他类方面表现不佳。让我们看看在我们的癌症检测模型的情况下会发生什么!
如果我们观察我们的训练数据集,我们会意识到它是不平衡的。运行下面的代码显示,我们有大约 130000 张没有癌症的图像,以及大约 90000 张有癌症的图像。如前所述,使用不平衡数据集进行训练可能会导致我们的模型在识别一个类时变得非常出色,而在其他类上却失败得很惨。在这种情况下,少数类是检测到癌细胞的一类,我们真的不想在对癌症图像进行分类时失败;因为这样做会导致人们带着未确诊的癌症继续生活,而他们应该接受治疗!
输出:
为了解决这个问题,我们可以从无癌症(0)类中删除图像,如下所示。为了更快的训练,我丢弃了多余的图像,但是我们可以简单地保持 95000:93099 的比例。下面的代码删除图像并保持类的分布相等。
还有一步,我们需要将我们的数据分成训练、测试和验证集。训练集用于训练我们的模型,验证集用于调整模型的超参数,测试集用于检查模型的性能。下面的代码片段按照 60:20:20 的比例对训练:测试:验证进行了划分。
在上面的例子中,我们有一个丰富的数据集,我们可以从中删除数据点来平衡类分布;然而,如果我们没有丢弃数据的奢侈呢?如果我们需要尽可能多的数据呢?
有几种方法可以做到这一点:
- 您可以对 minority 类进行过采样。在我们的例子中,这将简单地从我们的训练集中随机抽取带有检测到的癌细胞的图像样本,并将这些样本附加到我们的训练集中。您可能对此有点怀疑,但这种技术至少确保了您的模型不会严重依赖多数类进行训练,并且还学会了对少数类进行分类。
- 对于非基于图像的数据集,您可以创建假数据。这可以通过使用像核密度估计这样的技术来完成,在这种技术中,您可以了解数据集中要素的分布,并从这些分布中抽取样本来生成新数据。
这只是两种方法,你可以在这里找到更多的。
Keras 生成器的目录结构
机器学习模型使用存储在计算机/服务器内存中的数据。有时,数据集小到足以容纳在内存中;但在大多数实际情况下,并非如此。为了克服这一点,我们可以使用生成器(它们也执行图像增强,但我手动执行了上面的操作)来拍摄我们的图像,并将它们成批地传递给机器学习模型,而不是一次全部传递。为此,我们需要将图像存储在特定的目录结构中。本例中的目录应采用以下格式。
假设您在项目基本目录中,它应该是:
—培训数据文件夹
— — — class_0 文件夹
— — — class_1 文件夹
—测试数据文件夹
— — — class_0 文件夹
— — — class_1 文件夹
—验证数据文件夹
— — — class_0 文件夹
— — — class_1 文件夹
“培训数据”文件夹有两个子文件夹,其中包含每个类别的图像。测试和验证数据文件夹的结构相似。下面的代码创建了这些目录。
一旦我们创建了目录,我们就可以将相应的映像转移到这些目录中。下面的代码可以做到这一点。在 colab 上这样做大约需要 30 分钟,因为我们必须传输 160000 张图像。
结尾注释
太好了!此时,您应该已经设置好数据集,可以输入到您的模型中。完整的 A-Z 库可以在这里找到!
希望您发现这篇文章和笔记有助于理解挑战的预处理数据,以及一般的预处理。
参考
- https://www.kaggle.com/c/histopathologic-cancer-detection
- https://www . ka ggle . com/qit vision/a-complete-ml-pipeline-fast-ai
- https://towards data science . com/keras-data-generators-and-how-to-use-them-b 69129 ed 779 c
- https://github . com/DarthQadir/Cancer-Data-Preprocessing-Medium-Article/blob/master/Cancer _ Detection _ Preprocessing . ipynb
- https://scikit-learn.org/stable/modules/density.html
- https://towards data science . com/methods-for-handling-unbalanced-data-5b 761 be 45 a 18
数据预处理和解释结果:机器学习的核心:第 1 部分- EDA
卢克·切瑟在 Unsplash 上的照片
为什么以及如何分析数据和结果?
机器学习是当今世界越来越感兴趣的主题。越来越多的人,一些有经验的,一些新的,正在探索这个领域,因为它有趣的机会,应用和证明的能力。我是新来的一员。我进入这个领域是因为它能够完成非常有趣的应用。作为一名新手,我开始关注不同的机器学习模型及其工作方式。很久以后,我意识到,机器学习不仅仅是关于模型。模型是大脑,但是大脑从哪里学习呢?简单的答案是,根据数据。我们给模型的数据表现得越好,它学习得就越好。因此,数据处理和分析是机器学习的一个非常重要的部分。
现在,我们只讨论了输入,那么输出呢?我们还需要解释输出。已经观察到,如果数据集具有不平衡的数据,则在垃圾邮件检测之类的分类问题的情况下,模型可能无法正确地学习每个类别。在这种情况下,如果强表示集合在测试集合中数量很大,并且模型预测主要表示类别的每个样本,则由于集合的不平衡,准确性可能很好。但是这个模型和无技能分类器一样好。所以,我们不能部署这样的模型。我们需要在部署前分析结果。
这些事实是这篇博客背后的动机。
如何分析数据?
我们都听说过探索性数据分析(EDA)和主成分分析(PCA)这两个术语。这些方法被广泛用于可视化、分析、处理和解释数据变化和关系。在这篇文章中,我们将通过这些概念。为此,我们将使用 Kaggle 乳腺癌数据集。
数据集结构
这个数据集有 32 列。它有 30 个特性列、1 个索引列和 1 个“诊断”列,这是我们的目标列。
Y=pd.DataFrame(df['diagnosis'].values,columns=['diagnosis'])
X=df.drop(['diagnosis','id'],axis=1)
因此,我们得到了包含 30 列的特性集和包含 1 列的目标集。目标列有两个目标类,“M”和“B”。那么,我们开始吧。
探索性数据分析和数据预处理
相关图
我们的特征集的每一列被我们的模型用作值的向量。现在,我们如何将两个特征值或向量联系起来。为此,我们使用两个特征向量的点积,这给出了特征向量之间的协方差。协方差的值可以从正无穷大变化到负无穷大。这种协方差让我们了解两个考虑的特征之间的关联程度。符号表示变化的方向。换句话说,说明一个特征是随着另一个特征增加还是减少。它由下式给出:
Cov(x,y)= Sum((x-均值(x))(y-均值(y))) / n
其中 x 和 y 是两个特征。
现在,我们不直接使用协方差,我们使用相关性,即两个向量之间的余弦角。相关值从-1 到+1 不等。它只是给出了变化的方向。它是在协方差除以两个特征的标准差的乘积时获得的。相关性由下式给出:
相关性=corr(x,y)= Cov(x,y) / std(x)。标准(y)
关联是无量纲的,与尺度无关。了解特征之间的相关性很重要,因为我们不希望使用两个相关性非常高的不同特征,因为它们通常表示同一条信息。我们也不想使用与目标值相关性很小的特征,因为它们对预测没有太大影响,但会增加模型的复杂性。
这是相关图的样子:
import seaborn as sb
import matplotlib.pyplot as plt
C_mat = df.corr()
fig = plt.figure(figsize = (15,15))sb.heatmap(C_mat, vmax = .8, square = True)
plt.show()
这里我们可以看到代表两个特征之间相关性的标度和阴影。
对偏斜度的依赖
有几种分布描述了要素值在平面上的分布情况。在本节中,我们关注两种类型的分布:正态分布和偏态分布。在正态分布中,数据总体上是均匀分布的。在偏态分布中,数据可能在几个区域累积,而不是均匀分布在所有区域。偏斜分布通常是要素的一个问题,会影响模型的性能。我们可以使用直方图来研究这个问题。
df.hist(figsize = (35,35))
plt.show()
这些图很容易反映特征的分布。我们可以看到许多特征具有正态分布,而其他特征也具有偏态分布。所以,让我们做点什么吧。
如果我们仔细分析,我们可以发现“分形维数 se”和“面积 se”具有偏态分布。
import seaborn as sns
sns.distplot(df['fractal_dimension_se']);
sns.distplot(df['area_se']);
很明显,使用对数函数可以将偏态分布转换为正态分布。
import numpy as np
df['new_fractal_dimension_se']=np.log(df['fractal_dimension_se'].values)
df['new_area_se']=np.log(df['area_se'].values)
我们可以用数据集中新创建的正态分布要素替换实际的倾斜分布要素。
价值观的宁滨
通常在数据集中,我们会发现年龄、年份、人数等特征。这些特征本质上通常是数字的。但是它们与目标值的相关性很低,这可能是由于值的多样性。通过在几个范围内对这些特征进行宁滨,可以将这些特征转换成分类特征。例如,如果年龄在 0 到 100 的范围内,我们可以生成 5 个箱:
0-20 岁:小孩
20-40 岁:年轻
40-60 岁:中年
60-80 岁:老年人
80-100 岁:非常老
这种类型的数据预处理被称为宁滨,对于稀疏或长范围的数据非常流行。
数据分布
数字特征
有时查看连续数字特征相对于彼此的分布是非常重要的。这通常有助于我们估计某个特征对预测的有用程度。有几个情节可以做到这一点。我们会发现一些。
- 成对绘图
import seaborn as sns
sns.set()
cols = ['radius_mean', 'texture_mean', 'perimeter_mean',
'area_mean', 'smoothness_mean', 'compactness_mean', 'concavity_mean',
'concave points_mean', 'symmetry_mean', 'fractal_dimension_mean',
'radius_se', 'texture_se', 'perimeter_se', 'smoothness_se']
sns.pairplot(df[cols], size = 2.5)
plt.show();
由于篇幅限制,我们在这里只展示了几个特性。
配对图:仅用于数值。对角线元素显示特征的分布,另一个图形使用散点图显示两个特征的分布。
我们也可以使用散点图单独完成这项工作。
data = pd.concat([df['radius_mean'], df['new_conacvity_se']], axis=1)
data.plot.scatter(x='new_conacvity_se', y='radius_mean',);
该图显示了 2D 平面上半径平均值和新相关系数之间的分布。
2.基于目标特征的配对绘图。
import seaborn as sns
sns.pairplot(df_1, hue="diagnosis")
这些图显示了基于两个特征的点的分布,以及如何根据目标列区分它们,对角线显示了基于一个特征的两类目标列(M 和 B)的重叠程度。
3.聚类分析
这种类型的分析是基于聚类算法来完成的,主要是 K 均值聚类。这里,采用特征,并且应用 K 均值聚类来检查点分布的边界,如果基于这两个特征来预测目标,则该边界可以是分类边界。让我们看几个例子:
from sklearn.cluster import KMeans
import sklearn.metrics as sm
X_v=X.values
model = KMeans(n_clusters=2)
model.fit(X_v)
因此,这里我们的特征集被提供给 k=2 的 k 均值聚类算法。这将创建两个集群,它们将成为两个目标类。现在让我们按功能检查除法。
import numpy as np
import matplotlib.pyplot as plt
colormap = np.array(['red','blue'])
plt.scatter(X['radius_mean'], X['compactness_mean'],c=colormap[model.labels_], s=40)
plt.title('K Mean Classification')
plt.show()
import numpy as np
import matplotlib.pyplot as plt
colormap = np.array(['red','blue'])
plt.scatter(X['radius_mean'], X['concave points_mean'],c=colormap[model.labels_], s=40)
plt.title('K Mean Classification')
plt.show()
如果我们检查这些聚类,我们将能够在这两个聚类之间画出一条分类线。
分类特征
分类数据是指具有类、箱或分部的数据。它们不是连续的数字。关于分类特征,最重要的是要知道它们的分布。换句话说,假设“M”和“F”是性别特征中的两个类别,那么“M”实例的数量远大于“F”实例的数量是很常见的。在这种情况下,有一个问题,因为模型不学习代表不足的类。我们可以使用以下类型的分类特征图来了解这一点。
import matplotlib.pyplot as plt
feature = "diagnosis"
ax = df[feature].value_counts().plot(kind='bar',
figsize=(10,10),
color='blue')
ax.set_xlabel(feature, fontsize=20)
ax.set_ylabel("Count",fontsize=20)
这里的两个条形表示我们的目标列中“B”和“M”类的计数。
研究连续数值数据的分类特征的变化是非常重要的。我们通常使用箱线图和柱状图来分析这种关系。
1。箱线图
data = pd.concat([df['texture_mean'], df['diagnosis']], axis=1)
f, ax = plt.subplots(figsize=(10, 10))
fig = sns.boxplot(x='diagnosis', y="texture_mean", data=data)
这显示了连续 teture_mean 特性根据我们的目标列中的两个类别的分布。这些图形通常反映了特定类别的分类数据中数据的连续值的分布。实心框位于第一和第三个四分位数之间。柱是分布中多次出现的最高点和最低点,孤立点是异常值。它们必须被移除,因为它们降低了模型的准确性。两个方框显示了连续数据相对于两个类别的变化。
2。条形图
import seaborn as sns
sns.set(style="whitegrid")ax = sns.barplot(x="diagnosis", y="area_mean", data=df)
这些图类似于箱线图。它们还反映了不同类别的分类特征中连续数据行为的差异。它侧重于均值和标准差。条形的高度是类别中连续特征分布的平均值,条形代表标准差。
结论
我们在这里已经看到了几种数据分析和预处理的方法。在接下来的部分,我们将看看 PCA、特征选择和结果分析。我希望这有所帮助。
Github 链接在这里是。
数据预处理和解释结果:机器学习的核心:第 2 部分-主成分分析,特征选择和结果分析
卢克·切瑟在 Unsplash 上的照片
如何选择特征进行预测?
在第 1 部分,我们已经看了我们的数据集和探索性数据分析的概念。在这一部分,我们将看看主成分分析或 PCA 和特征选择程序。我们开始吧。
到目前为止,我们已经单独可视化了几个特征以及它们之间的相关性。但是对我们来说,将整个数据可视化是非常重要的。为此,我们需要将这 30 维数据投影到 2D 特征地图中。因此,需要降维。这就是 PCA 的用武之地。
在我们进入主成分分析之前,让我们探讨一下方差。
差异
方差是对集合分散或展开程度的度量,这是“平均值”(均值或中值)所不具备的。例如,如果我告诉你一个数据集的方差为零,你就知道它的每个成员都是相同的。如果方差很高,特别是与平均值的比率,这就告诉你数据在其成员之间有很大的不相似性。
如果方差非常低,我们基本上可以从该特性或特性集获得所有相似类型的数据。机器学习通常针对不同类别中数据点的不同行为。因此,如果它非常低,点预计会聚集在相同的点周围,这导致它们很难区分。因此方差通常被认为是最大似然数据集的信息。
方差由下式给出:
方差= Sum [i=1 到 n]((x { I }-均值(x)))
在 PCA 中,我们试图创建 n 个复合特征,它们能够最好地表示包含在我们的数据集的 30 个特征中的信息。这 n 个特征称为主成分。n 的值取决于用户。这 n 个特征都不是原始特征。这些特征被开发为不同特征的组合。
在我们开始理解和应用 PCA 之前,我们必须注意一件事。PCA 总是在缩放的数据上进行。那么,让我们来看看缩放。
缩放比例
我们使用的数据有几个特点。现在,这些特征根据特征具有不同的范围,例如一些特征具有 0 到 1 之间的十进制值,而其他特征具有 100-1000 之间的值。
如果我们使用像逻辑回归这样的分类器,就会产生很多问题。
y = w1x 1+w2x 2+……………………+wnxn+b
逻辑回归画一条线,用这个公式表示。现在,如果 x1 从 0 到 1,x2 从 100 到 1000,显然 x2 会有很大的压力和重量。为了避免这种情况,进行了缩放,使得所有的值都在固定的范围内。它只是将值更改为一个比例,但保持分布不变。
有两种主要的缩放类型
- **标准比例:**由下式给出
标度=(x-均值(x))/标准差(x))
它给出-1 到+1 之间的值。
2 **。最小-最大缩放:**由下式给出
Scale=(x- min(x))/(max(x)-min(x))
它给出 0 到 1 之间的值。
主成分分析
让我们回到 PCA。我们将在这里使用标准的定标器。让我们先来看看应用程序,然后我们再来看解释。
from sklearn.preprocessing import StandardScaler
scaler = StandardScaler()
scale=scaler.fit(X)
X_scaled=scaler.transform(X)
X_scaled_df=pd.DataFrame(X_scaled,columns=X.columns)
from sklearn.decomposition import PCA
pca = PCA(n_components=2)
PC = pca.fit_transform(X_scaled_df)
p_Df = pd.DataFrame(data = PC
, columns = ['principal component 1', 'principal component 2'])
p_Df.head()
降维后,这两个分量形成为我们的 n 分量是 2。现在,我们将把这作为我们的特征集,并相应地加入我们的目标集,我们将尝试可视化。由于它有两个数据特征,现在可以很容易地在 2D 平面上表示出来。
Y_l=Y.iloc[:]['diagnosis'].tolist()
joined=p_Df
joined['Diagnosis']=Y_l
joined.head()
import matplotlib.pyplot as plt
fig = plt.figure(figsize = (10,10))
ax = fig.add_subplot(1,1,1)
ax.set_xlabel('PC 1', fontsize = 12)
ax.set_ylabel('PC 2', fontsize = 12)
ax.set_title('PCA', fontsize = 15)
diags=['M','B']
colors=['r','b']
for diag, color in zip(diags,colors):
i = joined['Diagnosis'] == diag
ax.scatter(joined.loc[i, 'principal component 1']
, joined.loc[i, 'principal component 2']
, c = color
, s = 50)
ax.legend(diags)
ax.grid()
这是得到的主成分分析分布。如果我们以最好的方式表示 2D 的 30D 特征集,这就是我们的完整数据集表示。但是,这总是不可行的。让我们看看为什么。
PCA 是基于无监督算法的。问题是,这些成分是如何获得的?答案来了。
我们有一个 30 维的数据集。这意味着我们可以在一个 30 维的平面上绘制我们的点,每个维度代表一个特征。比方说,然后我们根据我们的目标分类给这些点着色。“M”是红色的。“B”是蓝色的。现在,在这一时刻,我们试图绘制一个 2D 平面,它最适合于根据目标类来划分点。我们使用 2D,因为 n_components 是 2。现在我们开始在 2D 平面上对这些 30D 点进行投影。因此,我们将 30 长度的元组减少到 2 长度的元组。现在,如果我们思考,我们会非常清楚,由于维数减少,我们也会丢失一些信息。因此,方差减小。x 轴和 y 轴值是主分量。因此,我们的目标是如何减少方差损失。为了做到这一点,我们通常从许多选择中挑选出可投影的 2D 平面。
详细地说,首先,选择一个最能区分这些点的 2D 平面。投影这些点并计算方差损失,然后选择与前一个平面正交的另一个平面并再次计算其方差。如此继续下去,直到获得许多选择,然后使用损失最小的平面。
毕竟,主成分分析并不总是很有信心代表所有的信息。这可以用方差比来测试。
pca.explained_variance_ratio_array([0.44272026, 0.18971182])
这没有给出非常清楚的表示,因为这两个分量仅表示这里所表示的总信息的 44+18=62%。这不是一个准确的表示,因为它仅表示总信息量的 62%。也就是说,它不能用两个主成分来表示。这是一个估计值,但据说如果比率之和小于 85%,则表示不太正确,因为缺少很多信息。
尽管如此,还是可以从这个操作中提取很多信息。比如,如果我们看这个图表,我们可以看到,如果我们画一条直线,那么它可以很容易地分类。因此,对于这个问题,逻辑回归将比 KNN 型分类器发挥更好的作用。
这几乎是关于 PCA 的所有内容,让我们进入下一个主题特性选择。
特征选择
我们有时会面临有很多特点的问题。它们甚至是像 99 100 个特征这样的大数字。现在,这些特征中的一些在模型预测中不是很有用。但是它们增加了特征集的维数,从而使其难以分析,增加了训练的时间,也降低了准确性。所以这些特征必须被去除。因此,在本节中,我们将讨论完成这项任务的几种方法。
随机森林特征重要性
在这种方法中,我们将数据拟合到一个随机森林模型,并获得特征重要性。从而获得最佳特征。正如我们所知,随机森林是基于决策树算法的,因此它们可以非常容易地模拟非线性,并提供非常清晰的特征重要性的图像。让我们看看应用程序。
from sklearn.ensemble import RandomForestClassifier
rfc = RandomForestClassifier()
X_n=X.values
Y_n=Y.values
rfc.fit(X_n,Y_n)
importance = rfc.feature_importances_
从而拟合决策树模型,获得特征重要度。
import matplotlib.pyplot as plt; plt.rcdefaults()
import numpy as np
import matplotlib.pyplot as pltobjects = X.columns
y_pos = np.arange(len(objects))
performance = importancefig, ax = plt.subplots(figsize=(20, 20))
plt.barh(y_pos, performance, align='center', alpha=0.5)
fontsize=14,
plt.yticks(y_pos, objects,fontsize=20)
plt.xticks(fontsize=20)
plt.xlabel('Contributions')
plt.title('Feature Contributions',fontsize=20)plt.show()
这是从随机森林算法中获得的特征重要性。
逻辑回归特征重要性
这是另一种在将数据拟合到逻辑回归模型后使用特征重要性的方法。如果数据本质上是线性的,这种方法非常有效。众所周知,逻辑回归的分类线由一个线性方程给出,如:
Y=w1x1+w2x2+w3x3…………+wnxn
这里的权重是相应的特征重要性。
from sklearn.linear_model import LogisticRegression
model = LogisticRegression(solver='liblinear', random_state=0)
model.fit(X_n, Y_n)
Weights=np.hstack((model.intercept_[:,None], model.coef_))
k=X.columns
k.append('bias')
因此,模型是合适的,并且在权重列表中获得了重要度。
这是由逻辑回归生成的特征重要性分布。
Lasso 回归要素重要性
这是一种非常常用的方法,用于获取特征重要性。这是通过将数据拟合到 lasso 回归模型并获得特征重要性来实现的。Lasso 回归适用于 L1 正则化的策略。
L1 正则化用于稀疏数据,其中有许多特征,但并非所有特征都是预测所必需的。在这种情况下,L1 正则化将不是非常重要的特征的特征重要性归零。Lasso 使用相同的策略。
需要注意的一点是 Lasso 不能用于分类“M”和“B”类,它们必须转换成整数。
让我们检查一下应用程序
from sklearn.linear_model import Lasso
import numpy as np
lasso = Lasso(alpha=0.0001)
i=0
y_d=[]
while i<len(Y_n):
if Y_n[i][0]=='M':
y_d.append([1])
else:
y_d.append([0])
i+=1
y_d=np.array(y_d)
lasso.fit(X_n, y_d)l=(lasso.coef_)
因此,我们将数据拟合到 lasso 模型,并加载特征重要性。
import matplotlib.pyplot as plt; plt.rcdefaults()
import numpy as np
import matplotlib.pyplot as pltobjects = X.columns
y_pos = np.arange(len(objects))
performance = lfig, ax = plt.subplots(figsize=(20, 20))
plt.barh(y_pos, performance, align='center', alpha=0.5)
fontsize=14,
plt.yticks(y_pos, objects,fontsize=20)
plt.xticks(fontsize=20)
plt.xlabel('Contributions')
plt.title('Feature Contributions',fontsize=20)plt.show()
这是 lasso 获得的特征重要性列表,我们可以看到一些特征的权重被降低到零,所以在模型的训练中,它们不会起任何作用,因为它们的权重为 0。
递归特征消除
递归特征消除是迄今为止设计的选择最佳特征的最佳方式。它基于一种递归算法。它首先考虑所有特征,建立模型预测,然后找到最不重要的特征。现在,它删除这些特征,重建模型,并再次检查删除特征的效果。这个过程包括一个 k 倍交叉验证步骤,以消除集合中任何种类的不平衡问题。我们设置流程使用的估计器或模型。
实施:
from sklearn.ensemble import RandomForestClassifier
from sklearn.model_selection import StratifiedKFold
from sklearn.feature_selection import RFECV
rfc = RandomForestClassifier(random_state=101)
rfecv = RFECV(estimator=rfc, step=1, cv=StratifiedKFold(10), scoring='accuracy')
rfecv.fit(X_n,Y_n)
因此,我们使用随机森林分类器作为估计器。我们在每一步都使用 10 倍交叉验证。
features=rfecv.n_features_
features
-> 24
这用于获得消除后最终获得的特征的数量。我们可以看到,在剔除之后,获得了 30 个特征中的 24 个。
n_p=np.where(rfecv.support_ == False)[0]
这获得了在该过程中已经消除的特征。让我们想象一下结果。
feat=X.columns
to_drop=[]
for i in n_p:
to_drop.append(feat[i])
x_imp=X.drop(to_drop,axis=1)
import matplotlib.pyplot as plt; plt.rcdefaults()
import numpy as np
import matplotlib.pyplot as pltobjects = x_imp.columns
y_pos = np.arange(len(objects))
performance = nfig, ax = plt.subplots(figsize=(20, 20))
plt.barh(y_pos, performance, align='center', alpha=0.5)
fontsize=14,
plt.yticks(y_pos, objects,fontsize=20)
plt.xticks(fontsize=20)
plt.xlabel('Contributions')
plt.title('Feature Contributions',fontsize=20)plt.show()
这些是 RFE 之后最后留下的特征和它们的重要性。
我们已经介绍了几乎所有用于获得重要特性的重要过程。
那么,让我们进入下一部分,结果分析。
结果分析
机器学习的另一个非常重要的部分是结果分析或解释。现在,通常情况下,我们理解结果意味着高准确性,但在机器学习的情况下并非如此。在机器学习中,准确性取决于许多其他因素。问题是为什么?让我们来看一个例子。假设有一个包含 100 封电子邮件的数据集,其中有 10 封是垃圾邮件。因此,我们形成 80%的训练集和 20%的测试集。现在,假设训练集有 9 封垃圾邮件,测试集有 1 封垃圾邮件。我们训练了我们的模型,但是由于垃圾邮件的实例较少,它没有正确地学习它。因此,该模型将所有内容分类为非垃圾邮件。现在,如果我们使用我们的测试数据集来评估我们的模型,那么它将给出 90%的准确性,因为 9 个实际上不是垃圾邮件。但是我们的模式实际上失败了。所以,我们不能只把准确性作为一个评价指标。
已经开发了几种方法来测量结果,最常用的是 ROC-AUC 曲线和精确回忆。
ROC- AUC 曲线
ROC 或接收器操作特性曲线用于可视化二元分类器的性能。它显示了真阳性率和假阳性率之间的权衡。
真阳性率=真阳性/(真阳性+假阴性)
假阳性率=假阳性/(真阴性+假阳性)
现在,它是如何工作的?分类模型实际上产生一个预测百分比,该百分比表示给定样本属于给定类别的可能性有多大。预测百分比可以是 0 到 100 之间的任何值。现在,它有一个阈值。在阈值以下,样本被分类为 0 类,在阈值以上,它被认为是 1 类。所以,假阳性,真阳性都取决于这个阈值。如果我们降低阈值,分类为 1 类的样本数量增加,因此假阳性增加,否则假阴性增加。ROC 曲线实际上滚动这个阈值,并相应地指出所有的真阳性和假阳性率。
AUC 代表“ROC 曲线下的面积”也就是说,AUC 测量整个 ROC 曲线下的整个二维面积。AUC 提供了对所有可能的分类阈值的综合绩效衡量。因此,AUC 越大,模型正确标记类别的机会就越大。所以,更多的是准确性。
我发现有一个很棒的帖子,它解释了我在这里使用的图片。
一个优秀的模型具有接近 1 的 AUC,这意味着它具有良好的可分性度量。差模型的 AUC 接近 0,这意味着它具有最差的可分性度量。事实上,这意味着它是往复的结果。它预测 0 是 1,1 是 0。当 AUC 为 0.5 时,意味着模型没有任何类别分离能力。
根据型号的容量,可能有 4 种情况。
案例 1:
这是模型正确预测每个点的理想情况。在实际数据中,正类和负类是不相交的集合,也就是说,一个点可以是真正的,也可以是真负的,但不能同时是真正的和真负的。在这里,我们可以看到模型正确地覆盖和分类了所有的点。因此,曲线下的面积是完整的 2D 盒面积,即 1,精度是 100%
案例二:
这些图表显示了模型的实际行为。在这里,我们可以看到有一个重叠部分,其中模型预测了一些错误的样本,即样本正类作为负类,反之亦然。重叠部分越小,模型的精确度越高。这里我们可以看到 AUC 是 0.7,而不是 1。
案例 3:没有技能分类器
这是一个模型基本没学到东西的案例。所以,它一直在平等的基础上预测两个类。所以,一半时间它分类正确,一半时间它是错误的。
案例 4:
在这种情况下,该模型将所有正类分类为负类,将负类分类为正类。所以,它做了一个完全错误的分类。因此,AUC 值为 0,准确率为 0%
这就是 ROC-AUC 曲线。让我们转向精确回忆。
精确召回
这些度量在用于评估二元分类模型的应用机器学习中也是有用的。
精度由下式给出:
精度=真阳性/(真阳性+假阳性)
召回由以下人员发出:
召回= TP / (TP + FN)
这两个指标在不平衡数据集的情况下非常有用。
如果数据集有太多的正类实例而几乎没有负类实例,那么模型将倾向于预测正类,因此假阳性更多,因此精度低。如果数据集有太多的负类实例而几乎没有正类实例,那么模型将倾向于预测负类,因此会有更多的假阴性,因此召回率低。
因此,在这两种情况下,这些指标可以给我们一个非常清晰的概念。让我们看看精确回忆曲线。
这就是精确回忆曲线的样子。精确回忆不考虑真正的否定。所以只关注正面类。现在,这些图表有一个无技能分类器基线作为参考。在 0.5 处是一条直线。曲线是在其基础上测量的,就像如果模型分类最好,则它是一个凸形的并且远离基线,否则它更接近。
我们已经研究了不同类型的性能矩阵。所以让我们在乳腺癌数据集上实现它。
我在这里使用了逻辑回归。
数据集的逻辑回归结果。
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(x, y, test_size=0.33, random_state=42)
from sklearn.preprocessing import StandardScaler
scaler = StandardScaler()
scale=scaler.fit(X_train)
X_train_scaled=scale.transform(X_train)
from sklearn.linear_model import LogisticRegression
model = LogisticRegression(solver='liblinear', random_state=0)
model.fit(X_train_scaled, y_train)
因此,这里的数据适合我们的模型,模型准备好进行预测。
x_test_scaled=scale.transform(X_test)
y_pred=model.predict(x_test_scaled)
from sklearn.metrics import accuracy_score
accuracy_score(y_test, y_pred)
我们的模型给出了 97%的准确率。这是一个非常高的精度,这意味着我们的主成分分析足够好。
ROC-AUC 曲线
让我们获得 ROC- AUC 曲线:
from sklearn.metrics import roc_curve
from sklearn.metrics import roc_auc_score
import numpy as np
i=0
y_pred_i=[]
y_test_i=[]
while i<len(y_pred):
if y_pred[i]=='M':
y_pred_i.append([1])
else:
y_pred_i.append([0])
i+=1
y_pred_n=np.array(y_pred_i)
i=0
while i<len(y_pred):
if y_test[i]=='M':
y_test_i.append([1])
else:
y_test_i.append([0])
i+=1
y_test_n=np.array(y_test_i)roc_auc_score(y_test_n, y_pred_n)
ROC 曲线下的 ROC AUC 分数或面积为 0.98
让我们检查图表。
from sklearn import metrics
import matplotlib.pyplot as plt
fpr, tpr, _ = metrics.roc_curve(y_test_n, y_pred_n)
auc = metrics.roc_auc_score(y_test_n, y_pred_n)
plt.plot(fpr,tpr,label="breast_cancer, auc="+str(auc))
plt.legend(loc=4)
plt.show()
这是我们得到的 ROC 曲线。
现在,我们来看看精确回忆曲线。
from sklearn.metrics import precision_recall_curve
lr_precision, lr_recall, _ = precision_recall_curve(y_test_n, y_pred_n)
plt.plot(lr_recall, lr_precision, marker='.', label='Logistic')
plt.xlabel('Recall')
plt.ylabel('Precision')
plt.legend()
plt.show()
这是获得的精度-召回曲线。正如我们所看到的,它离基线很远。因此,我们的数据集非常好,精度令人满意。
结论
在本文中,我们已经看到了 PCA、特征选择方法和性能度量。这里是 Github 链接。希望这些文章有所帮助。