下一次编码面试前要掌握的 7 个基本 SQL 概念
编程 | 面试 | 办公时间
通过解决取自真实编码面试的 SQL 习题来练习,最终得到你应得的工作。
照片由阿兹哈鲁尔·伊斯拉姆在 Unsplash 上拍摄
我的读者请注意
你们中的许多人联系我,要求我提供宝贵的资源来 练习更高级的 SQL 概念,以编写面试代码,包括真实的面试问题。 下面我分享 4 个我个人推荐的平台/课程:
- SQL 高级编码问题(StrataScratch)→目前为止我找到的准备 SQL 编码面试的最好平台!比 LeetCode 更好更便宜。
- 学习 SQL 进行大数据分析(纳米程度) → 优质课程进行更长期的承诺。
- SQL 汇总统计&窗口函数(DataCamp)
- SQL(Data camp)中操作数据的函数
>>>还不是中等成员?考虑与我的 推荐链接 签约,以获得 Medium 提供的一切服务,费用低至【5 美元一个月 !
停止低估 SQL 面试
当面试顶级科技公司的数据科学、数据工程或软件工程职位时,很可能技术环节会包括一个或多个现场代码会话,以测试你对 SQL 和你选择的编程语言的了解。
尽管练习用 Python 或 JAVA 来解决算法通常是很费力的,而且可能会占用你大量的时间(,因为几乎有无限多的问题存在!)、FAANG 面试中你要尽量不要低估 SQL 问题的难度。
在这篇文章中,我介绍并分享了 FAANG 中经常出现的一些基本算法的解决方案
towardsdatascience.com](/10-algorithms-to-solve-before-your-python-coding-interview-feb74fb9bc27)
科技公司的数据库中存储了大量数据,他们希望应聘者能够使用复杂的 SQL 查询以高效的方式提取和处理数据,然后再进行更高级的分析。由于对这些角色来说,良好的 SQL 知识几乎是理所当然的,所以面试官通常希望你能出色地解决这些挑战“”并且不太会提示你或忽略明显的错误。
举一个突出的例子,几年前,一名招聘人员联系我,希望在伦敦一家新兴的电子商务公司谋得一个职位,就在编码屏幕前,他打电话问我对解决定时 SQL 问题有多大信心。我告诉他,作为一名 BI 开发人员,我每天都使用 SQL 来编写复杂的查询,因此我对通过测试充满信心。我至今记得他的回答:
“SQL 编码面试可能会变得棘手。你不知道有多少有经验的候选人声称准备好了,然后在这个阶段失败了。”
就像预言一样,这正是发生在我身上的事情:我通过了 Python 编码筛选,却没有通过 SQL 测试。起初,我感到非常羞愧,我一直对自己说:“我是一名 BI 开发人员,却没有通过 SQL 面试……你能相信吗?”。
然而,不久之后,我意识到,在解决边缘案例的技术面试中,很多 SQL 问题并不罕见,这些问题在日常工作中并不常见,因此需要特别的准备。
为了帮助您在下一轮现场编码或带回家的定时 SQL 测试中评估自己的准备情况,在下一节课中,我将讨论一些面试练习问题 ( 和解决方案),涵盖以下 7 个基本概念:
- SQL 概念#1 : 使用子查询的高级过滤
- ***SQL 概念# 2:***HAVING 子句的正确使用
- SQL 概念#3 : 聚合 With CASE WHEN 子句
- SQL 概念#4 : 排名函数的正确使用
- SQL 概念#5 : 正确使用 UNION vs UNION ALL
- SQL 概念#6 : 处理空值
- SQL 概念#7 : 计算累计总和
[## 排名上的 6 个 SQL 窗口函数编码问题——采访倒计时 P1
SQL 面试即将来临,您正在寻找一些具有挑战性的练习来测试您的准备情况?你是…
towardsdatascience.com](/6-sql-window-functions-coding-problems-on-ranking-interview-countdown-p1-9be0ccf66453)
SQL 概念# 1:高级过滤
编写一个 SQL 查询来报告购买了产品“A”、“B”但没有购买产品“C”的客户的 *customer_id*
和 *customer_name*
,因为我们想推荐他们购买该产品。返回结果表按 *customer_id*
排序。
CUSTOMERS table:
+-------------+---------------+
| customer_id | customer_name |
+-------------+---------------+
| 1 | Daniel |
| 2 | Diana |
| 3 | Elizabeth |
| 4 | Jhon |
+-------------+---------------+ORDERS TABLE table:
+----------+-------------+--------------+
| order_id | customer_id | product_name |
+----------+-------------+--------------+
| 10 | 1 | A |
| 20 | 1 | B |
| 30 | 1 | D |
| 40 | 1 | C |
| 50 | 2 | A |
| 60 | 3 | A |
| 70 | 3 | B |
| 80 | 3 | D |
| 90 | 4 | C |
+----------+-------------+--------------+Expected OUTPUT Structure:
|Customer_id | Customer_Name
解决方案:
注意这个查询有多紧凑:它通过利用WHERE()
子句中的子查询只选择购买了产品 A 和 B 而没有购买 c 的客户,避免了使用多个 cte(节省了现场编码会话中的大量输入工作。在过滤时,请记住,如果子查询返回多个值,您可以使用IN()
或NOT IN()
运算符来检查成员资格。
SQL 概念# 2:HAVING 子句的正确使用
编写一个 SQL 查询,报告拥有最多员工的所有项目。
PROJECT table:
+-------------+-------------+
| project_id | employee_id |
+-------------+-------------+
| 1 | 1 |
| 1 | 2 |
| 1 | 3 |
| 2 | 1 |
| 2 | 4 |
+-------------+-------------+EMPLOYEE table:
+-------------+--------+------------------+
| employee_id | name | experience_years |
+-------------+--------+------------------+
| 1 | Khaled | 3 |
| 2 | Ali | 2 |
| 3 | John | 1 |
| 4 | Doe | 2 |
+-------------+--------+------------------+Expected OUTPUT Structure:
|project_id|
解决方案:
问题基本上是要求返回涉及最多名员工的项目。为了实现这一目标:
- 首先创建一个子查询,以便在按
project_id
分组时只检索最大数量的雇员(LIMIT 1
), - 然后结合使用
HAVING()
子句和COUNT(DISTINCT)
函数来过滤主查询,以便只选择在子查询中找到的雇员数量最多的项目。
如您所见,当涉及某种聚合时,HAVING()
应该用于过滤数据集(准备好解释 HAVING()
和WHERE()
之间的区别,因为这是一个非常受欢迎的问题,特别是对于入口角色)。
SQL 概念# 3:聚合时的情况
编写一个 SQL 查询来重新格式化表格,这样每个月都有一个 *department_id*
列和一个 *revenue*
列。结果表应该有 13 列(1 列表示部门 id + 12 列表示月份)。
DEPARTMENT table:
+------+---------+-------+
| id | revenue | month |
+------+---------+-------+
| 1 | 8000 | Jan |
| 2 | 9000 | Jan |
| 3 | 10000 | Feb |
| 1 | 7000 | Feb |
| 1 | 6000 | Mar |
+------+---------+-------+Expected OUTPUT Structure:
|id | Jan_Revenue | Feb_Revenue | Mar_Revenue | ... |
解决方案:
在某些情况下,面试官希望测试你处理数据的能力,例如,会要求你通过水平扩展来取消旋转表格。对于这个问题,我们的目标是去掉month
维度,创建与月数一样多的事实列。这可以很容易地通过使用一个CASE WHEN()
子句来识别特定的月份并生成新的聚合列来实现。
SQL 概念# 4:排名函数的使用
编写一个 SQL 查询,为每个客户返回第二早的 *order_id*
,每个日期他们至少下了两个订单。
Extract from ORDERS table
+------------+--------------+----------------------+------------ +
| order_id | customer_id | order_datetime | item_id |
+------------+--------------+----------------------+-------------+
| C-001 | 62456 | 2018-12-15 09:15:22 | A000 |
| C-005 | 21376 | 2019-01-14 09:28:35 | A001 |
| C-005 | 88956 | 2019-01-14 09:28:35 | A005 |
| C-006 | 42491 | 2019-01-14 03:53:08 | A008 |
+------------+--------------+----------------------+-------------+Expected Output Structure:
Customer_id | Order_date | Second_order_id
解决方案:
涉及使用排名函数(和一般窗口函数)的问题在 SQL 技术回合中极为常见。例如,在这种情况下,RANK() OVER()
函数用于通过customer_id
和order_date
对分区中的每个订单进行排序。注意分区是如何使用order_date
的,而等级是通过order_datetime
以升序排列的。这样,第一个订单将得到order_rank = 1
,第二个最早的订单将得到order_rank = 2
。然后使用WHERE order_rank = 2
子句只保留第二早的订单。上面的过滤器会自动排除客户下少于两个订单的日期,因此无需添加任何其他内容。
[## Python 中复制的 8 个流行的 SQL 窗口函数
关于如何利用业务分析中的 Pandas 高效复制最常用的 SQL 窗口的教程…
towardsdatascience.com](/8-popular-sql-window-functions-replicated-in-python-e17e6b34d5d7)
SQL 概念 5:UNION 与 UNION ALL 的使用
写一条 SQL,求出 2019–08–16 所有产品的价格,假设修改前所有产品价格都是 10。
# PRODUCTS table:
+------------+-----------+-------------+
| product_id | new_price | change_date |
+------------+-----------+-------------+
| 1 | 20 | 2019-08-14 |
| 2 | 50 | 2019-08-14 |
| 1 | 30 | 2019-08-15 |
| 1 | 35 | 2019-08-16 |
| 2 | 65 | 2019-08-17 |
| 3 | 20 | 2019-08-18 |
+------------+-----------+-------------+Expected Output Structure:
product_id | price
解决方案:
这个问题有点挑战性:它要求您识别每个product_id
在2019–08–16的最近价格变化。如果某个产品的价格仅在该日期后发生变化,您应该假设2019–08–16的价格为 10。为此,您可以应用上述问题中介绍的两个概念:
- 首先,您可以使用
DENSE RANK()
函数来查找每种产品在2019–08–16 的最新价格变化。DENSE_RANK()
函数在分区中分配连续的等级,因此没有出现平局然后重复的风险。该数据集不包括在阈值日期后发生价格变化的产品。 - 然后,您可以创建第二个数据集,包括 2019 年 8 月 16 日之后发生最早价格变化的所有产品,并将它们的价格设置为 10。为了实现这一点,请注意带有
MIN()
函数的HAVING()
子句的使用。 - 最后一步是用
UNION ALL
连接两个数据集,这样所有的product_id
都会出现在解决方案中。
如果被问到,请记住UNION ALL
比UNION
更有效、更快,原因是第一个操作符不会检查重复值。
SQL 概念# 6:处理空值
编写一个 SQL 查询,查找在过去 7 天内每个类别订购了多少台。考虑总共七个日历日期,包括今天。还要考虑所有品类,甚至是零订单的品类。
Extract from ORDERS table:
+------------+----------------------+------------------------------+
| order_id | order_datetime | item_id | order_quantity |
+------------+----------------------+------------------------------+
| C-001 | 2018-12-15 09:15:22 | A000 | 5 |
| C-005 | 2019-01-14 09:28:35 | A001 | 1 |
| C-005 | 2019-01-14 09:28:35 | A005 | 1 |
| C-006 | 2019-01-14 03:53:08 | A008 | 3 |
+------------+--------------+---------------------+----------------+Extract from ITEMS table:
+-------------+---------------+
| item_id | item_category |
+-------------+---------------+
| A000 | Outdoors |
| A001 | Outdoors |
| A002 | Outdoors |
| A003 | Kitchen |
| A004 | Kitchen |
+-------------+---------------+Expected Output Structure:
Category | Units
解决方案:
这个问题需要找到每个类别的和每个类别的的总单位数,这意味着在这种情况下items
表应该被用作前导表,并与orders
保持连接,以保留所有的item_category
值,甚至是那些与从未订购的项目相关联的值。一般来说,当你在真实的面试问题中读到单词 “each” 和 “every” 时,你可能需要对连接和一些空值采取一些行动,这些需要在过滤器中处理(OR o.item_id IS NULL
)
SQL 概念# 7:计算累积和
编写一个 SQL 语句来获得一个雇员三个月的工资总额,但不包括最近一个月。结果应该按“Id”升序显示,然后按“Month”降序显示。
EMPLOYEE table:| Id | Month | Salary |
|----|-------|--------|
| 1 | 1 | 20 |
| 2 | 1 | 20 |
| 1 | 2 | 30 |
| 2 | 2 | 30 |
| 3 | 2 | 40 |
| 1 | 3 | 40 |
| 3 | 3 | 60 |
| 1 | 4 | 60 |
| 3 | 4 | 70 |
+---------------------+Expected Output Structure:
id | month | salary
在 SQL 技术访谈中,被要求计算累计总和是一个非常经典的问题,因此对于这个问题,我提供了两个潜在的解决方案。
解决方案 1:
在这种情况下,ROW_NUMBER()
函数用于识别和排除支付给每个雇员的最后一笔工资。一旦排除了最后一笔工资,就会对前三行进行累计求和(SUM() OVER()
)。
解决方案 2:
在这个备选解决方案中,不是使用窗口函数来对月工资进行排序,而是通过编写一个查找并排除每个雇员最近一个月(MAX(month)
)工资支付(WHERE e1.id = e2.id
)的子查询来过滤掉最后一笔工资。然后,与解决方案 1 完全一样地计算累积和。
结论
在这篇文章中,我提出了 7 个基本的 SQL 概念,您应该在下一次 FAANGs 技术面试之前掌握它们。我希望你在下一个 SQL 编码屏幕或定时测试中使用上面的问题进行练习。
涉及日期转换的解决方案使用 PostgreSQL 作为语法(以节省一点打字……),但可以很容易地转换成 MySQL。我的解决方案也只是每个问题的潜在解决方案之一,所以请在评论中分享你的解决方案。请注意,本文中出现的所有 SQL 问题都摘自leet code,其中混合了官方问题和订户在讨论区中直接报告的问题。
给我的读者一个提示:这篇文章包含了附属链接,如果你购买的话,我可以免费给你一点佣金。
Python 中的 7 个地理空间数据处理技巧
第 2 部分:如何使用 Geopandas 在 Python 中轻松有效地集成空间要素
Lucas Ludwig 在 Unsplash 上拍摄的照片
我喜欢使用 Geopandas,在过去的两个月里,我分享了一些使用 Geopandas 处理地理空间数据的最佳技巧和诀窍。本文是该系列的第二部分,在这里我将分享另外七个技巧和诀窍,让您在用 Python 处理地理空间数据时更加轻松。
Geopandas 技巧的第一部分涵盖了五个专业技巧,您可以通过下面的链接阅读这篇文章。
第 1 部分:如何使用 Geopandas 在 Python 中轻松有效地集成空间要素。
towardsdatascience.com](/5-geospatial-tips-and-tricks-in-python-eef86aec5110)
以下是我们在本文中包含的技巧列表。
提示 1-CSV 转地理数据框架
很多数据集都是 CSV 格式的,而且很多数据集都有坐标(纬度和经度)。将这些数据集转换为地理数据框架可以在 Geopandas 中实现大量地理空间处理功能。
要将 CSV 转换为地理数据框架,我们首先读取包含 Pandas 的 CSV 文件,如以下代码片段所示。然后,我们可以使用 Geopandas 中的 points_from_xy 函数将数据框转换为地理数据框。
使用 Geopandas 将数据框转换为地理数据框— 作者提供的图片
将数据框转换为地理坐标框架后,我们现在可以执行几何操作,包括绘制地理空间数据、计算距离等等。
技巧 2 —几何过滤器
有了 pandas,我们可以使用行或列来过滤数据。使用地理数据框架,除了熊猫过滤之外,您还可以通过其几何来过滤数据。以下示例显示了读取著名的出租车数据。该数据集是一个相对较大的文件,因此我们可以避免使用几何过滤器读取整个数据集,因为我们只读取曼哈顿边界内的点。
通过几何图形过滤数据—作者的图像
mask 参数采用一个几何图形,因此我们在这里提供一个行政区名称,Geopandas 将在读取数据集时排除所有其他行政区。
技巧 3 —溶解
通常,我们有不同的多边形来处理地理边界,包括其他邮政编码、社区、地区等…如何合并这些子单元而不丢失原始数据集中的统计数据?
对于非地理数据,我们只需要使用groupby
函数。但是,对于空间数据,我们还需要聚合几何要素。在这种情况下,我们可以使用溶解。以下示例显示了将国家边界分解为洲
消失的边界——作者的图片
下面的可视化显示了使用上述代码将国家边界(左上)分解为洲边界(右下)。
溶解示例(国家边界到大陆)——作者图片
请注意,要使用聚合溶解,您需要有一个列。此外,您可以进行不同的统计计算。在本例中,我们展示了如何计算总和。
技巧 4——创建气泡图
当您拥有点数据集并希望按大小显示数量时,气泡图是 choropleth 图的绝佳替代方案。在 Geopandas 中创建气泡图并不难,但我相信如何创建一个气泡图并不明显。
要创建气泡图,只需将标记大小参数设置为任何数量列,如下面的代码片段所示。
使用 Geopandas 创建气泡图— 作者图片
此外,你需要照顾重叠的点圆;因此,我在这里将 alpha 设置为一个较低的值以保持透明。您可以看到输出可视化。
气泡图— 作者图片
技巧 5——找到最近的距离
距离和查找附近的内容是空间分析的重要组成部分。在这篇技巧中,我将向您展示如何有效地计算距离并找出最近的点。
让我们说:我们有城市。nearest_city 函数采用一个点(纬度和经度)和城市地理数据框,并返回距离所提供坐标最近的城市。
最近邻计算— 作者图片
你也可以拥有你的数据。它不一定是城市本身。但是对于任何点数据集,您现在都可以使用此函数计算最近的邻域。
提示# 6-至 Geojson/Geopackage
谁不喜欢 shapefiles!除了 shapefiles,我们还可以将地理处理后的数据导出为其他格式以在本地存储。在本例中,我展示了如何在本地将地理数据框存储为 GeoJSON 和 Geopackages。
将地理空间数据存储为 Geojson/Geopackage。— 作者图片
对于 GeoJSON,您需要将驱动程序指定为 GeoJSON。保存为地理包格式,我们需要设置图层名称和驱动程序为 GPKG。
技巧 7——阅读 PostGIS
成为超级用户并设置您的 PostGIS 数据库。通过 Geopandas,您可以使用 SQL 读取数据。该代码片段展示了一个使用 Geopandas 和 Sqlalchemy 从 PostgreSQL 数据库读取数据的示例。
连接到 PostgreSQL/PostGIS 数据库— 作者的图片
SQL 语法可以包装成字符串,Geopandas 将执行它。这种方法是通过空间数据库访问数据的好方法。您可以从本文开始安装和使用 PostgreSQL:
[## 使用 PostgreSQL/PostGIS 的空间数据科学
PostgreSQL 和 Python 空间数据入门实用指南。
towardsdatascience.com](/spatial-data-science-with-postgresql-postgis-2f941c8c367a)
结论
我希望您喜欢这一轮 Python 中的地理空间数据处理技巧。在本文中,我们看到了有效使用 Geopandas 进行地理空间数据分析的七个技巧。
其中一些技巧是直接的几何操作,对于处理地理空间数据至关重要:将数据框架转换为地理数据框架、几何过滤和融合。作为一名地理空间数据科学家,繁重的几何功能是救命的。
其他技巧涉及地理空间数据可视化、空间数据库连接、查找最近邻和地理空间矢量数据格式输出。
如果你喜欢我在推特上发布的这些提示和技巧,你可以在 @spatialML 找到它们
R 语言中探索性分析的 7 大功能
这些功能将把您的探索性分析提升到下一个层次
在 Unsplash 上由 Carlos Muza 拍摄的照片
数据挖掘框架的 EDA(探索性数据分析)阶段是从数据集中提取信息的主要活动之一。无论你的最终目标是什么:神经网络、统计分析或机器学习,一切都应该从对你正在处理的数据的良好理解和概述开始。
EDA 的一个主要特征是,它是一个有点开放的过程,依赖于工具箱和数据科学家的创造力。不幸的是,这既是福也是祸,因为做得不好的 EDA 可能会隐藏数据中的相关关系,甚至损害研究的有效性。
EDA 中通常执行的一些活动(这绝不是一个详尽的列表):
- 数值变量分析:平均值,最小值和最大值,数据分布。
- 类别变量分析:类别列表,每个类别中记录的频率。
- 异常值的诊断以及它们如何影响每个变量的数据分布。
- 预测变量之间的相关性分析。
- 预测变量与结果变量之间的关系。
谈到 EDA,没有什么神奇的公式,但在分析数据时,一定要记住一些软件包和函数,以保持分析中敏捷性和灵活性的完美平衡。
数据集
研究或实践数据科学的人都非常熟悉本文中使用的数据集。在这里可以找到和,它包含了 2008 年在葡萄牙推出的葡萄酒信息。它包含 1599 个观察值,葡萄牙红葡萄酒的 11 个心理化学属性和 1 个目标变量,数字离散质量指数从 0 到 10。
1599 obs 数据集的展望。x 12 变量(图片由作者提供)
软件包和功能
R 编程语言是数据爱好者中最广泛使用的编程语言之一。经过广泛的研究,我编制了一个列表,其中列出了对数据执行 ed a 时应该知道的一些最佳函数,重点是那些允许进行更直观分析的函数,以及表格和图形。
数据集概述
visdat 包有两个有趣的函数,可以快速、实用地查看数据集。 vis_dat 函数以一种非常容易理解的方式显示变量、观察值的数量以及每个变量的类型。
visdat::vis_dat(wine,sort_type = FALSE)
vis_dat 用于可视化变量的类型(图片由作者提供)
来自同一个包的 vis_miss 函数允许您查看每个变量缺失值的数量,从而给出数据集完整性的概述。
vis_miss 用于查看丢失的值(图片由作者提供)
注意:所讨论的数据集没有任何带有缺失值的变量,因此一些缺失值是为了更好地可视化而“人工”生成的。
可视化数字变量
名为 funModeling 的软件包提供了强大的功能来绘制关于数据集的有用信息,从关于变量的基本信息到更具体的信息,如每个变量提供的信息增益,以及预测变量和结果变量之间的关系。
要记住的函数之一是 plot_num 函数,它绘制每个数值变量的直方图。在其他包中有几个类似的函数,甚至有直接通过 ggplot2 完成相同任务的方法,但是 plot_num 函数大大简化了任务。
plot_num 用于绘制数值变量的分布(图片由作者提供)
这样,你就可以在一个图中得到所有的东西——当然,这取决于变量的数量——一个数字多样性的概述。
可视化分类变量
与数值变量一样,对数据集的分类变量有一个总体的了解是很重要的。包 inspectdf 的 inspect_cat 函数允许您一次绘制所有分类变量的摘要,显示每个变量中最常见的类别。
inspect_cat 用于查看分类变量中最常见的类别(图片由作者提供)
注意:本文中使用的数据集没有任何分类变量,因此该图像是说明性的,它取自此处的。
异常值识别和处理
dlookr 包是一个具有非常有趣的分析、数据处理和报告功能的包,它为 R 语言的 EDA 带来了一些最佳解决方案。这个软件包的一个亮点是关于数值变量中异常值的信息。
首先, diagnose_outlier 函数生成一个数据框,其中包含每个变量的信息:离群值计数、离群值 x 总观察值比率,以及包含和不包含离群值的平均值。
dlookr::diagnose_outlier(wine)
用于查看异常值信息的 diagnose_outlier(图片由作者提供)
同一个包还提供了 plot_outlier 函数,该函数显示了包含和不包含上述异常值的值分布中所有变量的图形。
dlookr::plot_outlier(wine)
plot_oulier 查看有无异常值时变量的外观(图片由作者提供)
从氯化物变量中可以看出,当应用统计模型时,几个高值肯定会影响结果,尤其是当一些模型假设数据呈正态分布时。
注:重要的是要记住,异常值不应该总是被删除,因为在这种情况下,它们可能表明葡萄酒的一个特定子类别,特别是由于这个变量中异常值的高度集中(值的 7%)。
相关可视化
有许多软件包都具有生成数据集中变量之间的相关图的功能,但很少像图表那样提供几个因素的完整可视化。 PerformanceAnalytics 包的关联功能。
chart.Correlation(wine[,2:7], histogram = TRUE, pch = 15)
图表。查看变量之间交互的相关性(图片由作者提供)
它呈现:
- 数据集中数值变量之间的数值相关性(皮尔逊系数),较大的源表示较大的相关性
- 每对变量之间的微型散点图
- 每个变量的直方图和密度图
注意:该函数只接受只有数字变量的数据框作为输入,因此如果数据集包含分类预测变量,则应事先执行此处理。这种处理的一个建议是使用 keep 方法(在 dplyr 包中提供):
wine %>%
keep(is.numeric)
这样,数据集中只保留数值变量。
自动报告
有些软件包还具有自动生成数据集 EDA 报告的功能。当前可用的报告选项在所呈现的分析的范围和维度方面有所不同,但都显示数据集变量的某种摘要、关于缺失值的信息、每个变量的直方图和条形图等。
我测试过的最好的函数可能是 DataExplorer 包的 create_report 函数。对于更标准的分析(已经相当全面了),它允许您只使用一行代码生成报告:
DataExplorer::create_report(wine)
DataExplorer 包中的 create_report 函数示例,用于创建完整的 EDA 报告(图片由作者提供)
幸运的是,这个函数远远不止于此,因为它可以定制报告的各个方面,从更改布局和主题到调整特定的参数或准确选择哪些图形应该包含在报告中。
注意:请务必记住,对于数据分析和可视化来说,没有一个解决方案可以涵盖所有基础,而且自动报告生成功能也不应该如此对待。
TLDR
- 您是否需要数据集的高级概述?visdat::vis_dat(概述)和 visdat::vis_miss(缺少值)。
- 你需要关于数字变量的信息吗?funModeling::plot_num。
- 那么分类变量呢?inspectdf::inspect_cat。
- 变量之间的相关性?performance analytics::chart . correlation。
- 一个自动化和可配置的报告怎么样?包 DataExplorer::create_report。
你呢?在探索性分析中,有没有一个不可错过的功能来自动化或帮助可视化您的数据?请在评论区告诉我!😁
来源和致谢
我们首先要感谢负责创建和维护这些令人难以置信的包的开发人员——这些包都可以在 R 的官方资源库中找到,也可以在我的研究中参考以下来源:
inspectdf 是什么,有什么用?我经常发现自己在整个过程中查看和检查数据帧…
alastairrushworth.github.io](https://alastairrushworth.github.io/Exploring-categorical-data-with-inspectdf/) [## 第 2 部分:使用 inspectdf 的 R 中的简单 EDA 少量缺失数据
我喜欢这个包,因为它有很多功能,而且非常简单易用。简而言之,它…
www.littlemissdata.com](https://www.littlemissdata.com/blog/inspectdf) [## 自动化探索性数据分析的 R 包前景
具有大量异构变量的大型但有噪声的数据集的可用性不断增加,导致…
www.groundai.com](https://www.groundai.com/project/the-landscape-of-r-packages-for-automated-exploratory-data-analysis/1)
高效程序员的 7 个习惯
卡尔·海尔达尔在 Unsplash 上拍摄的照片
大约 40%到 45%的我们程序员每天做的事情是我们自动完成的:刷牙,早上喝杯咖啡,坐在办公桌前打开邮件,以及许多其他事情。
这些习惯在我们的日常生活中为我们节省了大量的时间和精力,并且对我们日常任务的整体质量和成就非常重要。
脸书首席执行官马克·扎克伯格有每天穿同一件衣服上班的习惯,因为他注意到这有助于节省能量。“我真的很幸运,每天起床后,我都可以帮助十多亿人。如果我把精力花在生活中愚蠢或琐碎的事情上,我会觉得自己没有尽到自己的职责。”
微软创始人比尔·盖茨每天晚上都洗碗,因为这个习惯可以减轻压力,提高创造力,帮助大脑思考和创造性地解决问题。
斯蒂芬·科维写了一本名为《高效人士的 7 个习惯》的书,销量超过 2500 万册。这本书是关于发展一套核心的价值观和思想,帮助你用一种综合的和以原则为中心的方法解决个人和职业问题。是一本帮助了很多人改善生活的经典书籍,相信软件开发者也能从中受益。由于软件开发人员能够将想法转化为现实并解决现实生活中的问题,因此他们受到了广泛的欢迎。
下面的习惯可以进一步增强这种能力,并使之更加有效。
1)要主动
尼克·莫里森在 Unsplash 上的照片
每个人的生活中都会发生很多事情。有些事情你无法控制,也无能为力。
你可能生活在一个因为签证问题而不允许你出国利用一个非常有吸引力的工作机会的国家。你工作的公司可能会破产。你的经理很容易生气,所以你总是害怕表达你对团队重要问题的想法。你可能不被允许使用测试驱动开发,因为你的团队领导认为这花费了太多的时间,尽管你尽力让他们相信这是一个非常有效的长期策略。
如果你想成为一名高效的程序员,你就不应该关注那些超出你控制范围的事情。你应该采取积极的态度,而不是责怪社会,讨厌你的工作。在你能控制的事情上投入你的精力和努力。
你应该准时上班,这样你就不会因为错过了和其他团队成员的每日 scrum 会议而感到内疚。你应该学习新的概念和技术,而不是在没有任何任务分配的情况下,花无数的时间在无意识的浏览上。你需要看新书,看教程,参加开发者大会。你应该在空闲时间写博客和参与开源项目来帮助他人。
你需要追求不断的学习和进步。用亨利·大卫·梭罗的话来说,“我所知道的最令人鼓舞的事实莫过于人类通过有意识的努力提升自己生活的不容置疑的能力。”
你不应该让不受你控制的事情占据你的大部分注意力。你需要关注那些在你影响范围内的事情。你需要积极主动地养成新的好习惯。
2)从心中的目标开始
本杰明·戴维斯在 Unsplash 上拍摄的照片
有效的程序员通常对他们未来的自我有非常令人信服的目标。
盖茨和他的商业伙伴保罗·艾伦设定了让每个家庭都拥有一台电脑的目标。扎克伯格说他想利用脸书让世界更加开放。
想象一下,如果你在自己的葬礼上,你的家人、朋友和队友用充满感情的话语称赞你。你希望他们怎么评价你?你希望如何被人记住?你想留下什么贡献或遗产?
这些问题可以提醒你你的核心价值观,可以帮助你明白什么对你来说是真正有价值和重要的。
积极对待你的生活。规划你的人生。
想象你未来的自己和你想要在生活中拥有的东西。你不能击中你看不见的目标。对你来说,设定明确的目标是非常必要的,你要去哪里,你在生活中真正想要的是什么。令人信服的目标激发大规模的行动。
尝试逆向工程,设定你认为会让你朝着那个目标前进的目标和里程碑。
设定真正激励你朝着目标努力的年度目标——与你的价值观一致的目标。让它们可以衡量,并把它们分解成季度、月和周目标。每周回顾一下你目前所处的位置,以及你需要达到的目标。确定哪些是有效的,哪些需要改进。对自己诚实,无情地切断阻碍你的活动、常规或关系。坚持计划、执行和评审。
3)将最重要的事情放在第一位
我们生活在一个令人分心的时代,很难抵制我们定期收到的无数电子邮件或脸书和垃圾信息。它们可能代表了我们工作的一个重要部分,因为我们需要在开始实现之前理解需求。
然而,有时我们的注意力和精力会被不必要的干扰耗尽,这不仅会占用我们很多时间,还会增加我们的罪恶感和压力。我们可能会开始想为什么我们不能完成我们应该做的事情。
你可能有很多工作要做,随着时间的推移,新的工作可能会突然出现。当您正在开发一个需要实现的重要特性时,突然之间,生产中出现了一个严重的 bug。
因此,你在选择做什么和做什么权衡之间处于一场持续的战斗中。柯维说得很清楚,“我们大多数人花太多时间在紧急的事情上,而没有足够的时间在重要的事情上。”他进一步解释道,“关键不在于优先考虑你日程表上的事情,而在于安排好你的优先事项。”
显然,不是每个任务都有相同的重要性和紧迫性。柯维提到了我们应该遵循的最有效的顺序:
1)重要和紧急
2)重要且不紧急
3)不重要和不紧急
4)不重要且不紧急
艾玛·马修斯数字内容制作在 Unsplash 拍摄的照片
如果你想成为一名高效的程序员,你需要通过把重要的事情放在日程的首位来充分利用你的时间。你需要成为一名领导者,并根据上面的排序模式管理你的日程。
正如柯维所说,“最主要的是保持主要的东西是主要的东西。”
有很多书和文章提到了“时间管理”事实上,你无法管理时间。你只能管理你的优先事项。
分清主次似乎很困难,因为你可能害怕错过其他事情。然而,一旦你习惯了坚持不懈地做这件事,并看到它带来的好处和情感回报,它就会变得更容易和令人愉快。
4)认为双赢
无论你是否是项目中唯一的开发人员,你都不能让你的自负导致你只考虑自己。对于开发者来说,自我是最大的敌人。
有些开发人员倾向于认为 有赢有输 ,即别人必须输才能有人赢。如果你的同事在你的经理面前看起来很糟糕,你认为你会得到晋升或加薪。结果,你会把你的行为导向尽可能的炫耀,没有价值的邀功,或者贬低你的同事,所有这些都是为了表现你更优秀。
这不仅会给你一种表面的满足感(因为你一直在试图贬低你的同事),还可能会损害你的团队整体生产力,因为你和你的同事根本不愿意一起工作。
如果你想成为一个有效的开发者,你需要把自己和大多数人的做法区分开来。在任何情况下,你都应该努力为整个团队找到最好的选择。
你应该考虑最终会带来更好的长期解决方案的互利解决方案,而不是在这种情况下只有一个人能如愿以偿。
培养问自己这样问题的习惯:“他们有什么好处,我也能从中受益?我们如何才能在不破坏我们关系的情况下,各取所需?”
你可能有时会和同事发生误解和脾气暴躁,但这并不意味着你所拥有的和谐和关系会被破坏。你与人相处的能力是你生活中的一个重要方面。
尽可能避免争论,关注长期利益。当你开始时心里有了目标,即使你达到了最大的目标,你也不想孤独。
5)先寻求理解,再寻求被理解
安娜·范德·斯特尔在 Unsplash 上的照片
沟通是我们需要具备的最重要的技能之一。我们大部分时间都在交流。
我们上班前和家人沟通。我们旅行时在街上和邻居交流。我们与队友、客户和顾客交流的时间比我们写代码的时间多。
我们阅读技术书籍,学习如何使用 Docker 和开发图形应用编程接口(API),但几乎没有人向我们提到倾听和理解他人的重要性。如果我们想要健康的团队协作,那么我们需要理解我们的团队成员。
我们通常更多地看着我们的智能手机,而不是面对那些已经处理了很长时间的问题的同事。
如果我们想成为高效的程序员,互相激励,我们需要使用共情倾听,并真正理解我们的同事。这迫使其他人回应你的倾听,并愿意受你的影响。
提醒你自己,你没有能力独自完成伟大的项目,也没有能力打造自己的产品来影响数百万人。不要忽视你的队友。成为持续帮助他们的人,无论是工作任务还是软技能。当你试图向别人解释一个概念,或者帮助他们解决一个问题时,实际上你自己学得更好。教学有助于你的学习。
因此,这不仅会让你和他人感觉良好和重要,因为你的话和倾听对他人很重要,而且还会创造一种互相关心和帮助的氛围。同理心可能是软件开发人员的超能力。
6) 协同
安娜·萨莫伊洛娃在 Unsplash 上的照片
毫无疑问,大型项目是由许多团队成员开发的。
盖茨和艾伦一起创立了微软,艾伦甚至想出了微软这个名字。埃隆·马斯克(Elon Musk)与他的兄弟金巴尔(Kimbal)创建了他的第一家 IT 公司 Zip2,然后他以 3.07 亿美元的现金和 3400 万美元的证券将该公司出售给 AltaVista。Instagram 最初是由凯文·斯特罗姆和迈克·克里格创立的。
亚马逊大约有34.1 万名员工。微软拥有超过 12 万名员工。谷歌在对建立完美团队进行了大量的研究后发现,一些最有效率的团队拥有一个培养协作和拥抱心理安全的环境。
哈佛商学院教授 Amy Edmondson 将心理安全描述为“一种自信,认为团队不会因为某人说出来而使其尴尬、拒绝或惩罚他。”每个人都有贡献、合作和参与他们想要的任何事情的自由。
每当你发现自己成为与同事争论的一部分时,试着理解他们的核心兴趣。解决它们,使它们变得互惠互利和富有成效。
这样,通过利用每个成员的优势,你的团队会更有成效。团队合作大于各个部分的总和。
如果你想成为一名高效的程序员,试着帮助你的团队变得更加协同。这可以通过尊重每个队友的自由来实现,并帮助他们在表达不同观点时感到非常舒适,而不必担心尴尬。允许每个人在他们觉得有趣和值得贡献和关注的事情上做出贡献和合作。
7)磨快锯子
想象一下,你看到一个同事因为无法完成一项任务,在过去的两天里没有睡觉,陷入困境,压力很大。他们没有最后期限,但他们只是非常渴望完成工作,所以他们没有优先考虑睡眠。你建议他们休息一下,因为你同情他们。“我太忙于编程了,”他们可能会回答。
这可能有点夸张,但事实并非如此。更多的时候,我们被日复一日的生活事务所困扰,以至于我们很少退一步思考我们的生活。我们被困在“忙碌”中太多,以至于我们甚至没有试图找到任何时间来磨利锯子。
根据柯维的说法,磨利锯子意味着更新我们自己,在我们本性的所有四个方面。这些维度是生理、心理、社会/情感和精神。
我们需要健身和健康饮食来改善我们的身体状况。
我们必须掌握数据结构、算法和设计模式等基础知识;编写具有挑战性的任务;看别人的代码,新书,博客帖子;并为开源项目做贡献,以在精神上提高我们自己。Dain Miller 甚至建议读更多的书而不是写更多的代码。
我们需要乐于助人,对同事感同身受,培养协作精神,在社交和情感方面提升自己。
我们需要成长和贡献来更新我们的灵性。这些代表了我们需要满足的一些最稀有的需求。我们需要在个人和职业上成长。杰夫·考夫曼(在谷歌工作)和他的妻子将年收入的 50%捐赠给有效的慈善机构。我们不需要在谷歌工作来给予,给予不仅仅意味着经济上的。为开源项目做贡献或者通过写文章来教导他人也是给予的例子。
我们必须努力在所有这些方面保持平衡,否则可能会造成不平衡。我们可能会假装任何失衡都没有那么痛苦,但从长远来看,它可能是痛苦的。
柯维建议每天集中一个小时磨利锯子。我们必须提醒自己,磨利锯子是一场马拉松,而不是短跑。正如亚伯拉罕·林肯所说:“给我六个小时去砍树,我会用前四个小时去磨斧子。”
建立有效的习惯
许多真正擅长自己技术的开发人员分享了一些我们都可以借鉴的共同习惯。我相信成功会留下线索,当我们有一些可以效仿的、被证明有效的东西时,我们都会变得更好。
习惯是很强大的。
如果你想成为一名有效的程序员,首先你必须决定这样做。正如柯维所说,“我不是环境的产物。我是我的决定的产物。”卓越不是偶然的,而是精心计划、努力工作和全心投入的结果。正如亚里士多德所说,“我们就是我们反复做的事情。因此,优秀不是一种行为,而是一种习惯。”
开始实践这些习惯中的任何一个,自己看看效果如何。
跟我上 推特
Python 中字典理解的 7 个便利用例
PYTHONIC 式的编码方法
展平、反转、合并、过滤等等
Python 中的理解是用于从其他序列构建序列的语法结构。本质上,理解是一种更简洁、更易读的编写循环的奇特形式。
所有的理解都可以使用for
循环重写,但反之则不成立。总的来说,Python 中有四种理解技术。
- 列出理解
- 词典释义
- 集合理解
- 生成器理解
这篇文章的目的是向你展示字典理解的力量,以及如何以不同的方式利用它。在我们探索一些有趣的案例之前,让我们先了解一下语法,因为它可能会让许多开发人员在开始时感到困惑。
词典理解的句法
考虑下面的代码,该代码从一系列数字中创建一个字典,其值是键的平方:
square_dict = {num: num*num for num in range(1, 6)}
print(square_dict)
#Output
{1: 1, 2: 4, 3: 9, 4: 16, 5: 25}
现在让我们使用上面的代码作为参考来分析字典表达式的语法:
上面的语法代表了编写字典理解的最小形式。词典理解的输出以绿色突出显示。所有的键值对都被分配给构造的字典。
iterable 不一定是字典。它可以是任何可以循环的 python 对象——列表、元组、字符串等。
与列表理解不同,字典理解也可以同时迭代一组键和值。通过调用字典上的items()
方法,您可以将它转换成一个键值元组列表进行循环。
还可以在字典理解中的for
循环后设置一个条件语句,如下所示:
fruits = ['Apple', 'Orange', 'Papaya', 'Banana', '']fruits_dict = {f:len(f) for f in fruits if len(f) > 0}print(fruits_dict)
#Output
{'Apple': 5, 'Orange': 6, 'Papaya': 6, 'Banana': 6}
既然我们已经很好地了解了字典理解的语法,让我们来看看它的应用。
1.字频率
通常情况下,您需要构建一个字典来保存字符串中每个单词的计数。使用 for 循环实现这一点的经典方法是:
s = 'I felt happy because I saw the others were happy and because I knew I should feel happy'dict = {}
for token in s.split(" "):
dict[token] = dict.get(token, 0) + 1
但是我们可以使用字典理解使它明显更短,如下所示:
frequency_dict = {token: s.split().count(token) for token in set(s.split())}#Output
{'felt': 1, 'and': 1, 'should': 1, 'others': 1, 'saw': 1, 'were': 1, 'knew': 1, 'happy': 3, 'feel': 1, 'the': 1, 'because': 2, 'I': 4}
2.修改字典的键和值
对于大型字典,可能会出现这样的情况,您需要在所有的字典后面追加一个字符。例如,它可以是一个简单的$
符号。
在另一种情况下,您可能需要从键或值字符串中删除一个字符。以下是如何使用字典理解功能通过修改键和值来创建新字典的示例:
d = {'My_Article1': '1', 'My_Article2' : '2'}my_dict = { k[3:] : '$' + v for k, v in d.items()}#Output
{'Article1': '$1', 'Article2': '$2'}
3.按一组关键字过滤词典
您可能只对字典中具有特定键集的部分感兴趣。下面是一个基于键列表过滤和创建新字典的示例:
d = {1: 'a', 2: 'b', 3: 'c', 4: 'd'}
keys = [1, 2]my_dict = {key: d[key] for key in keys}
#Output
{1: 'a', 2: 'b'}
但是当列表keys
包含一个字典中没有的无关值时,上面的代码会抛出一个错误。因此,我们不迭代keys
,而是使用sets
来寻找d
和keys
中的公共键,如下所示:
my_dict = {key: d[key] for key in set(keys).intersection(d.keys())}
下面是第三种情况,我们通过包含指定字符串的关键字来过滤字典:
d = {'num_1': 'a', '2': 'b', 'num_3': 'c', '4': 'd'}filter_string = 'num'
filtered_dict = {k:v for (k,v) in d.items() if filter_string in k}
#Output
{'num_1': 'a', 'num_3': 'c'}
4.反转字典的映射
如果您的字典有唯一的键和值,并且想要反转从k:v
到v:k
的映射,您可以通过以下方式使用for
循环来实现:
d = {'1': 'a', '2': 'b', '3': 'c', '4': 'd'}my_dict = {}
for k,v in d.items():
my_dict[v] = k
通过使用字典理解,我们可以在一行中做同样的事情:
my_dict = {v: k for k, v in d.items()}
#Output
{'a': '1', 'b': '2', 'c': '3', 'd': '4'}
5.元组和稀疏向量到字典
接下来,我们有一个元组列表,其中每个元素包含国家代码和名称。我们将使用理解技术创建一个字典,以国家名称作为关键字,以国家代码作为值:
tuples = [("US", '+1'), ("Australia", '+61'), ("India", '+91')]
my_dict = {k[0]: k[1] for k in tuples}
稀疏向量一般包含很多零值。我们可以考虑在字典中只保存非零值,这样可以节省一些空间。通过使用下面的字典理解技术,我们可以将稀疏向量转换成键值对,其中key
是稀疏向量的索引:
values = [0,0,21,0,0,0,100]
my_dict = { values.index(v) : v for v in values if v}
#Output
{2: 21, 6: 100}
还有另一种方式来编写上面的字典理解,可读性稍微好一点:
my_dict = {n: v for n,v in enumerate(values) if v}
if v
表示仅当稀疏向量的元素不是 False、0、None 等时,才将键和值添加到字典中。
6.整理字典
对字典进行分类有不同的方法。我们可以用键或值,按升序或降序来做。让我们来看看。
下面是一个按关键字升序和降序排序的示例:
d = {"a": 3, "b": 4, "d": 1, "c": 2}
dk_ascending = {k: d[k] for k in sorted(d)}
#Output
{'a': 3, 'b': 4, 'c': 2, 'd': 1}dk_descending = {k: d[k] for k in sorted(d, reverse=True)}
#Output
{'d': 1, 'c': 2, 'b': 4, 'a': 3}
以下示例显示了如何按升序和降序对值进行排序:
d = {"a": 3, "b": 4, "d": 1, "c": 2}
dv_ascending = {k: d[k] for k in sorted(d, key=d.get)}
#Output
{'d': 1, 'c': 2, 'a': 3, 'b': 4}dv_descending = {k: d[k] for k in sorted(d, key=d.get, reverse=True)}
#Output
{'b': 4, 'a': 3, 'c': 2, 'd': 1}
7.将字典列表展平为单个字典
假设 Python 列表中有未知数量的字典,如下所示:
l = [{'a':1}, {'b':2}, {'c':3, 'd' : 4}]
现在,我们想把这个列表展平成一个字典,这样所有的子字典合并成一个字典。我们可以使用下面的双重嵌套字典理解技术:
my_dict = {k: v
for d in l
for k, v in d.items()
}#Output
{'a': 1, 'b': 2, 'c': 3, 'd': 4}
结论
我们看到了在 Python 中应用字典理解的许多不同的用例。这个想法是有效地使用它,不要过度使用。很容易误用它来进行相当简单的操作。
这一篇就到此为止——感谢阅读。
每个数据科学家都应该知道的获取缺失值的 7 个习惯用法
数据科学提示
你应该把命令自动化
卢多维克·沙雷特在 Unsplash 上的照片
M 缺失数据肯定会在数据集分析过程中产生问题。即使是确定丢失值的事实,更不用说它们的数量和分布,也可能消耗大量的时间。这就是为什么您可能应该保留一些有用的命令,以提高自动化和分析速度,并保持代码整洁和准确。
我们将使用 Kaggle 的免费葡萄酒评论数据集来展示这些命令的影响。
1.DataFrame.describe()(但不完全是)
在这里你可以想到可能和 describe() 方法一样司空见惯的东西。尽管该方法处理了关于整个数据集的大量信息(但没有一个字是关于丢失的数据的)。实际上,我们不会使用这个命令的所有潜力,而是可以应用一个简单的技巧来提取我们需要的数据。只需查看输出的 count 列:
wine_data.**describe**(include='all').loc['count']
我们检索所有列的非缺失值的数量:
Unnamed: 0 150930
country 150925
description 150930
designation 105195
points 150930
price 137235
province 150925
region_1 125870
region_2 60953
variety 150930
winery 150930
Name: count, dtype: object
它不是我们需要的确切信息,因为它期望我们知道数据集的大小来计算数据缺口的数量。但是,我们可以很容易地将输出转换成现值的百分比,这相当有用:
wine_data.**describe**(include='all').loc['count'] / wine_data.shape[0] * 100
describe() 方法的过滤能力(包含/排除参数)为我们提供了必要的灵活性。
2.Series.value_counts()(但不完全是)
通常这是一个非常有用的命令,有很多输出。但是,我们将再次应用一个小技巧。这是我们可以用来检索单个列中缺失值的数量的习语。不再多言:
wine_data['country'].**value_counts**(dropna=**False**).loc[np.nan]Out[1]: 5
3.DataFrame.count()
对于那些不需要 describe()方法及其过滤能力的人来说,pandas 已经内置了 count()方法:
wine_data.**count**()Out[1]:
Unnamed: 0 150930
country 150925
description 150930
designation 105195
points 150930
price 137235
province 150925
region_1 125870
region_2 60953
variety 150930
winery 150930
dtype: int64
对于单列:
wine_data.**count**()['country']Out[1]: 150925
很简单,有点无聊。
4.isnull()。总和()习语
非常常见和非常有用的习语检索缺失数据的数量。看起来正是我们从一开始就想要的命令:
wine_data.**isnull**().sum()Out[1]:
Unnamed: 0 0
country 5
description 0
designation 45735
points 0
price 13695
province 5
region_1 25060
region_2 89977
variety 0
winery 0
dtype: int64
页(page 的缩写)对于紧凑代码爱好者来说, isna() 别名是存在的:
wine_data.**isna**().sum()
5.isnull()。sum()。sum()(深入)
有时我们不需要数据缺口的数量,而是需要它们存在的事实(例如,对于自动化管道)。我们会发现下一个习语很有用:
wine_data.**isnull**().sum().sum()Out[1]: 174477
但是它返回一个数字,我们可能想把它转换成布尔值。所以,还有一个习语返回布尔值:
wine_data.**isnull**().values.**any**()Out[15]: True
简短回答的简短代码。
6.NaNs 热图
但是,如果需要更多关于数据集中缺失值分布的信息,该怎么办呢?我们应该有意识地画出差距的热图!
**import** **seaborn** **as** **sns**
**import** **matplotlib.pyplot** **as** **plt**plt.figure(figsize=(16,10))
sns.heatmap(wine_data.isnull(), cbar=**False**, cmap="YlGnBu")
seaborn 的热图。黑线显示数据差距。
看一下分布就可以为分析提供很多信息。
7.缺失值的索引
之前的所有脚本都没有回答我们数据缺口在哪里。当然,我们可以使用数据帧过滤器来隔离丢失的数据或简单地丢弃它。但是在少量缺失数据的情况下(还记得“国家”栏的 5 个缺口吗?)我们可能希望现在它完全没有重新索引的问题。因此,多一个内置的熊猫方法将帮助我们:
wine_data['country'].isnull().**to_numpy**().**nonzero**()Out[18]:
(array([ 1133, 1440, 68226, 113016, 135696], dtype=int64),)
这样,一个索引数组就准备好了。
这种简短紧凑的命令可以在数据集调查过程中节省一些时间。对我来说,我总是在不同的组合中使用它们,用更少的代码获得更多有价值的信息。你可以在我的 GitHub 上找到整个工作笔记本:
此时您不能执行该操作。您已使用另一个标签页或窗口登录。您已在另一个选项卡中注销,或者…
github.com](https://github.com/Midvel/medium_jupyter_notes/blob/master/missing_data_idioms/missing-data-tips.ipynb)
在您的数据科学项目中,您使用了哪些单行惯用语?
机器学习工程师和研究人员之间的 7 个关键区别(包括工资)
包含有关期望薪资、工作量、可交付成果以及更多重要差异的信息。
左:Arif Riyanto 在 Unsplash 上的照片右:Jaredd Craig 在 T2 Unsplash 上的照片
介绍
人工智能目前是一个有趣的行业,机器学习从业者现在是’酷孩子’。
但即使在’酷孩子’'中,机器学习实践者的群体之间也有明显的区别,更具体地说,是研究解决方案的人和设计解决方案的人之间的区别。
也就是说,这种区别并不像它应该的那样明显。
这篇文章旨在揭示机器学习研究者和 ML 工程师之间的一些关键区别。
强调这两种角色之间的差异可以让你获得做出更好的学术和职业选择所需的信息。
在我们进一步讨论之前,需要注意的是,我将术语机器学习工程师和研究员作为以下角色的总称:
- 计算机视觉工程师/研究员
- 自然语言处理工程师/研究员
- 数据科学家
主要差异
1.工作角色描述
机器学习工程师的角色包括在已实施的软件/硬件解决方案中实施机器学习算法和模型。
机器学习研究人员的角色关注机器学习中特定或利基学科领域的进步。
2.学术背景
ML 研究人员通常被教育到博士水平。他们往往是具有强大的学术和研究背景的个人。
他们还拥有计算机科学相关课题的高级学位。
大多数 ML 工程师拥有硕士学位,只有少数 ML 工程师拥有博士学位。
为了了解 ML 工程师和研究人员的学术背景,我利用了 LinkedIn 。
我查看了一些职位名称中包含“机器学习研究员”、“机器学习科学家”或“机器学习工程师”的个人简介。
3.交付品/最终产品
Rami Al-zayat 在 Unsplash 上拍摄的照片
ML 工程师的可交付成果通常是具有机器学习模型的工程解决方案,能够以自动化、高效或创造性的方式执行一组任务。
对于一个 ML 工程师来说,最终产品或可交付成果可以是一个软件,其中的功能由机器学习方法驱动。
然而,ML 研究人员的可交付成果往往是一篇写得很好的研究论文,其中包括为实现特定机器学习相关任务中性能/准确性的特定进步或改进而进行的实验和调查研究的细节。
一个 ML 研究者的最终产品将是对新发现、改进或分析的探索记录,并提交给国际会议和科学杂志。
4.薪水
薪水可能是许多读者最感兴趣的关键差异。
机器学习从业者的需求量很大,ML 相关角色提供的薪资就反映了这一点。
例如,纽约时报的这篇文章提到顶级人工智能研究人员的工资超过 100 万美元。
很明显,在高要求的行业中,收入最高的 0.01%的人拥有高额的薪水。
但是让我给出一些适用于大多数人的数据。
在英国,从 2020 年 4 月 3 日算起的 6 个月内,机器学习研究员 的平均 工资为57500 英镑。****
同时,同期机器学习工程师 的平均 工资为68750。****
所以在英国,两个 ML 角色之间有明显的 10000 的差距。
根据 LinkedIn 的数据,在美国的 ML 研究人员 的平均** 底薪为14.3 万美元(110 ML 研究人员)。**
对于美国的 ML 工程师 ,这个数字降为12.5 万美元,但是包含了 900 多 ML 工程师的更多数据。
就我个人而言,根据我对人工智能行业中与我一起学习和工作的人的观察,金钱动机不是主要的。
接触和获取知识的机会似乎对我的团队更有吸引力,包括我自己。
简单来说,年轻的机器学习工程师可能更关心吹嘘的权利和影响力,而不是金钱激励。
谁不想成为一个FAANG公司的机器学习工程师或研究员,而不考虑报酬?
请注意,统计数据并不能反映该行业的真实薪资预期,它们应该被用作指导方针,而不是绝对的事实。
5.工作/项目范围
照片由 D A V I D S O N L U N A 在 Unsplash 上拍摄
ML 工程师需要看到更大的画面。ML 研究者需要更集中的视角。
软件工程是一门学科,要求理解与产品、过程或管道相关的组件。这是至关重要的,因为工程师的任务是负责集成几个组件。
以下是一个典型的 ML 工程师在项目中需要解决的几个问题:
- 理解 ML 模型使用的数据格式
- 理解从数据源接收的数据格式
- 实现与数据湖和数据库的连接,以便存储和访问数据。
- 了解最终产品的使用环境,因为这可以决定分配的资源水平,以确保高效运行和最佳运行能力。
另一方面,一个 ML 研究员的工作范围往往是非常明确的。ML 研究员的角色是一个非常集中的学科。
ML 研究人员不需要非常担心 ML 模型或算法在各种环境中的表现。ML 研究员的工作往往非常关注问题和具体。他们的任务通常是找到解决问题的新方法,或者提高以前设计的解决方案的性能和准确性。
6.工作角色要求
对 ML 研究人员的工作角色描述和要求是精确的,并且集中在机器学习的特定领域。
ML 研究员的典型工作角色要求包括以下内容:
- 机器学习平台和库的知识,如 TensorFlow、PyTorch、Keras 等。
- 能够进行文献综述,并以良好的书面研究格式提交报告和实验结果,以提交给会议或科学期刊
- 机器学习中特定领域的成熟知识,如概率模型、高斯过程、强化学习等
- 对包括理论知识在内的机器学习的基本主题有很强的理解
- 扩展利基问题的最新技术
ML 工程师的典型工作角色要求如下:
- 云计算服务知识,如谷歌云平台(GCP) 和亚马逊网络服务(AWS)
- 精通 Java、Python、JavaScript 等语言的编程技能
- 将机器学习模型部署到生产环境中的经验
- 在手机等边缘设备上部署机器学习模型的经验
- 能够实施、评估和测试常见问题的最新解决方案,如对象检测、语义分割和图像分类
- 能够从发表的研究论文中提取关键细节和信息,并向项目利益相关者传达发现。
- 实施数据挖掘脚本的经验。
7.重叠
ML 研究员可以做工程,ML 工程师做研究。
成为机器学习实践者也意味着精通现代的软件库和硬件。如果机器学习本身是一个多学科的领域,职称通常不能描绘角色的全貌。
为了说明我的观点,ML 研究人员可以在实际研究和工程之间进行 70/30 的划分。而不是硬币的另一面,ML 工程师通常在工程和研究之间有 70/30 的分离。
我可以证明,对于一个 ML 工程师来说,研究和工程是分开的,因为在我目前作为计算机视觉工程师的角色中,我花了很多时间将 ML 模型设计成解决方案,如网站或移动应用程序。与此同时,我会花很少的精力搜索代码为的论文或研究中心发表的关于我正在解决的特定问题的研究论文。
结论
我不得不承认,有几个区别在本文中没有提到,但快速的谷歌搜索会提供一些其他的区别。
无论你选择走哪条职业道路,都要承认这两个角色都需要大量的时间和努力来获得,但是好处是值得的。
为了更多地了解作为一名 ML 工程师是什么样子,我链接了两篇文章,讲述了我作为一名计算机视觉工程师在一家初创公司的第一天和第一个月是如何度过的。
洞察一个实践机器学习工程师的第一个月。Jupyter 笔记本之外的世界
towardsdatascience.com](/my-first-month-as-a-computer-vision-engineer-5813574d394a) [## 我作为计算机视觉工程师的第一天
剧透:我引起轰动
towardsdatascience.com](/my-first-day-as-a-computer-vision-engineer-8b59750c79a0)
希望这篇文章对你有用。
要联系我或找到更多类似本文的内容,请执行以下操作:
- 订阅我的 YouTube 频道 视频内容即将上线 这里
- 跟着我上 中
- 通过 LinkedIn 联系我**
7 个机器学习算法的 7 个要点
引擎盖下到底发生了什么?
在 Unsplash 上由 Waldemar Brandt 拍照
感谢各种库和框架,我们可以只用一行代码实现机器学习算法。有些则更进一步,让你立刻实现和比较多种算法。
易用性也有一些缺点。我们可能会忽略这些算法背后的关键概念或思想,而这些概念或思想对于全面理解它们是必不可少的。
在这篇文章中,我将提到 7 个机器学习算法的 7 个关键点。我想指出的是,这不会是对算法的完整解释,所以如果你对它们有一个基本的了解就更好了。
我们开始吧。
1-支持向量机(SVM)
点:C 参数
SVM 创建了一个决策边界来区分两个或更多的类。
软利润 SVM 试图通过以下目标来解决优化问题:
- 增加决策边界到类别(或支持向量)的距离
- 最大化训练集中正确分类的点数
这两个目标之间显然有所取舍。决策边界可能必须非常接近某个特定类,才能正确标注所有数据点。然而,在这种情况下,新观测值的准确性可能会较低,因为决策边界对噪声和独立变量的微小变化过于敏感。
另一方面,决策边界可能被放置在尽可能远的每个类,代价是一些错误分类的异常。这种权衡由 c 参数控制。
C 参数为每个错误分类的数据点增加一个惩罚。如果 c 很小,则对误分类点的惩罚也很低,因此以更大数量的误分类为代价选择了具有大余量的决策边界。
如果 c 很大,SVM 试图最小化由于高惩罚导致的错误分类的例子的数量,这导致了具有较小裕度的决策边界。对于所有错误分类的例子,惩罚是不一样的。它与到决策边界的距离成正比。
2-决策树
要点:信息增益
当选择要分割的特征时,决策树算法试图实现
- 更多的预测
- 杂质少
- 低熵
熵是不确定性或随机性的度量。一个变量的随机性越大,熵就越大。均匀分布的变量具有最高的熵。例如,掷一个公平的骰子有 6 个概率相等的可能结果,所以它有均匀的分布和高熵。
熵 vs 随机性
选择导致更纯节点的分裂。所有这些都表明“信息增益”,这基本上是分裂前后熵的差异。
3-随机森林
要点:引导和特征随机性
随机森林是许多决策树的集合。随机森林的成功高度依赖于使用不相关的决策树。如果我们使用相同或非常相似的树,总体结果与单个决策树的结果不会有太大不同。随机森林通过自举和特征随机性实现不相关的决策树。
Bootstrapping 是通过替换从训练数据中随机选择样本。它们被称为 bootstrap 样本。
通过为随机森林中的每个决策树随机选择特征来实现特征随机性。随机森林中每棵树使用的特征数量可通过 max_features 参数控制。
特征随机性
4-梯度提升决策树
要点:学习率和 n _ 估计量
GBDT 是决策树与 boosting 方法相结合的集合,这意味着决策树是顺序连接的。
学习率和 n_estimators 是梯度推进决策树的两个关键超参数。
学习率就是模型学习的速度。较慢学习速率的优点是模型变得更加健壮和通用。然而,学习是要慢慢付出代价的。训练模型需要更多的时间,这就引出了另一个重要的超参数。
n_estimator 参数是模型中使用的树的数量。如果学习率低,我们需要更多的树来训练模型。然而,我们需要非常小心地选择树的数量。使用太多的树会产生过度适应的高风险。
5-朴素贝叶斯分类器
点:天真有什么好处?
朴素贝叶斯是一种用于分类的监督机器学习算法,因此任务是在给定特征值的情况下找到观察值的类别。朴素贝叶斯分类器计算给定一组特征值(即 p(yi | x1,x2,…,xn))的类的概率。
朴素贝叶斯假设特征是相互独立的,特征之间没有相关性。然而,现实生活中并非如此。这种特征不相关的天真假设是这种算法被称为“天真”的原因。
所有特征都是独立的假设使得与复杂的算法相比非常快。在某些情况下,速度优先于更高的精度。
它可以很好地处理文本分类、垃圾邮件检测等高维数据。
6-K-最近邻
要点:何时使用和不使用
k-最近邻(kNN)是一种受监督的机器学习算法,可用于解决分类和回归任务。kNN 的主要原理是一个数据点的值是由其周围的数据点决定的。
随着数据点数量的增加,kNN 算法变得非常慢,因为模型需要存储所有数据点,以便计算它们之间的距离。正是这个原因也使得算法的内存效率不高。
另一个缺点是 kNN 对异常值很敏感,因为异常值对最近的点有影响(即使它太远)。
积极的一面是:
- 简单易懂
- 不做任何假设,因此可以在非线性任务中实现。
- 适用于多个类别的分类
- 处理分类和回归任务
7-K-均值聚类
要点:何时使用和不使用
k-均值聚类旨在将数据划分为 k 个聚类,使得同一聚类中的数据点相似,而不同聚类中的数据点相距较远。
K-means 算法无法猜测数据中存在多少个聚类。集群的数量必须预先确定,这可能是一项具有挑战性的任务。
随着样本数量的增加,算法会变慢,因为在每一步,它都要访问所有数据点并计算距离。
K-means 只能画线性边界。如果数据中存在非线性结构来分隔组,k-means 将不是一个好的选择。
积极的一面是:
- 容易理解
- 相对较快
- 可扩展用于大型数据集
- 能够以一种聪明的方式选择初始质心的位置,从而加速收敛
- 保证收敛
我们已经介绍了每个算法的一些关键概念。给出的要点和注释绝对不是算法的全部解释。然而,在实现这些算法时,了解它们对于做出改变是非常重要的。
感谢您的阅读。如果您有任何反馈,请告诉我。
在接受数据分析师提议之前,要考虑的 7 个鲜为人知的因素
办公时间
剧透一下——这不是薪水或头衔
恭喜你!您已经完成了数据分析师面试,并获得了一份工作机会。你再兴奋不过了。
你会接受吗,因为主要原因是比你现在的工作更高的薪水和更高的头衔?如果你的回答是“是”,请继续阅读。
我之前谈过作为一名成功的数据分析师我学到了什么。今天我想更进一步,谈谈你应该考虑的鲜为人知的因素,让你的成功之路更加平坦。
1.对公司业务的兴趣
公司业务是否符合你的个人兴趣?记住,你每周要花 40 多个小时查看未来几年的数据。如果你喜欢玩电子游戏,而这是一家在线游戏公司,你会更喜欢你的工作,而不是为一家卖家具的公司工作吗?
对公司业务感兴趣将增加你的参与度,并帮助你获得第一手的观点,从而找到可行的见解。
2.数据文化
数据在公司的决策中是如何使用的?数据团队是否建立良好?数据基础设施是什么样的?
这些问题的答案将决定你作为数据分析师的生活。
缺乏数据基础设施意味着您可能最终不得不手动提取和加载原始数据来进行分析,因为这些数据不存在于数据库中。你会花大部分时间去获取数据,而不是分析数据。
如果你是第一批数据雇员之一,你想从其他人那里学习,这家公司可能不太适合你。如果你是一名高级分析师,想要展示你的技能,那么成为首批数据雇员对你来说是一个好机会。如果没有数据科学团队,那么就有可能将建模融入到您的工作中,并在工作中学习。
根据你的职业目标决定这家公司的数据文化是否适合你*。***
3.学习潜力
在这家新公司,你还能学到多少额外的技能?
每个公司都有一套不同的工具和系统。学习如何使用这些工具和系统将有助于扩展你的简历。
如果数据团队中有许多分析师,并且数据文化非常强大,那么你有很大的潜力向团队中的其他人学习,并从事你以前从未做过的新型分析。
4.公司增长潜力
这家公司有可能发展壮大数据团队的规模吗?
这可能是一个赔钱的创业公司,但如果业务在增长,你的角色可以随着业务的增长而增长。如果公司停滞不前,业务发展缓慢,那么未来扩大数据团队和提升你的资金就会减少。
5.经理和利益相关者
你的经理会指导你并帮助你更上一层楼吗?
如果你是一名初级分析师,而你的经理似乎太忙或缺乏指导你的技能,那么你只能靠自己,你将更难达到下一个级别。
你的利益相关者使用数据做决策吗?
你可以成为世界上最好的分析师,但如果你的利益相关者不接受你的建议,而依赖直觉,你就无法展示价值。让利益相关者依靠你的分析来改进业务,对建立你的信誉大有帮助。
6.行业
你是支持一个部门还是多个部门?
如果你是一名初级分析师,支持多个部门会让你最大程度地接触到业务的不同部分,并帮助你在各种分析中获得更多经验。如果你是一名高级分析师,这可能并不理想,因为你可能很少有机会展示你在某个领域的专长。
你将支持的部门是成本中心还是收入中心?
营销是一个成本中心。如果你支持市场营销,而事实证明市场营销不能带来比他们花费更多的销售,那么在市场营销中扩大你的角色的机会将非常低。
相反,销售是一个收入中心。如果你支持销售并帮助提高转化率,那么你更有可能被注意到,随着销售的增长,他们可以雇佣更多的分析师并让你领导他们。
7.工作生活平衡
我不知道你怎么想,但是在一天中的某个时间点之后,我会遭受收益递减的痛苦。我需要休息和充电,因为这比连续 12 个小时盯着一个问题更容易帮助我思考问题。
如果你知道你的工作压力大,工作时间长,那么你会很快筋疲力尽,开始寻找新的工作。健康的工作生活平衡会让你保持快乐和投入。
我们如此关注薪水和头衔,是因为这些是人们用来评估工作机会的最常见的因素。现在你知道了在通往成功的道路上要考虑的另外 7 个因素。现在决定权在你手中。明智地选择。
你可能也会喜欢…
我希望从一开始就知道的成功秘诀
towardsdatascience.com](/my-experience-as-a-data-scientist-vs-a-data-analyst-91a41d1b4ab1) [## 如何将机器学习成果转化为商业影响
向高管解释模型结果
towardsdatascience.com](/how-to-translate-machine-learning-results-into-business-impact-d0b323112e87) [## 我如何使用机器学习模型来生成可操作的见解
将数据科学与数据分析相结合
medium.com](https://medium.com/swlh/how-i-used-a-machine-learning-model-to-generate-actionable-insights-3aa1dfe2ddfd)***
现在修复 7 个现代 Python 错误!
Python 中常见的 7 个不该犯的错误。
介绍
Python 是一种相对容易掌握的语言,但是由于很多事情都是假设的,所以很容易出错。此外,这些错误可能会在很长一段时间内被忽视。提前给我的另外四头菜鸟巨蟒失误。
他们可能会工作,但他们可以工作得更好。
towardsdatascience.com](/avoid-these-rookie-python-mistakes-9cc17cccd051)
今天我将分享更多在 Python 3.8 中容易犯的错误。
№1: +=
在很多情况下,我肯定会犯的一个错误是使用了+=操作数。假设加法必须用两个独立的操作数来完成似乎太容易了,一个用于加法,另一个用于断言。幸运的是,Python(以及许多其他编程语言)支持可以同时执行数学和断言运算的操作数。
而不是:
x = x + 5
做:
x += 5
№2:位置变元表示
在大多数现代脚本语言中,有两种主要类型的参数可以用作函数的参数:
位置和
关键词。
在 Python 3.8 发布之前,没有办法表示位置参数,使得位置参数缺省基本上不可能。然而,由于 Python 3.8 中的更新,我们可以使用\将所有以前的参数表示为位置参数。您应该使用它们,因为位置参数是高性能 Python 代码的基础。如果在 Python 中有什么东西是你的代码需要补偿的,特别是在机器学习的时候,那可能就是性能。
关键字参数在函数定义时计算一次。这对递归算法的性能尤其有害。如果你喜欢写成本函数,使用位置参数是绝对必要的。这并不是说根本不应该使用它们,但是尽可能使用位置参数绝对是一个更好的主意。
而不是:
def numbers(custom, five=5,ten=10,fifteen=15):
total = five + ten + fifteen + custom
return(total)
做:
def numbers(custom,\,five=5,ten=10,fifteen=15):
total = five + ten + fifteen + custom
return(total)
同样重要的是要记住,这个特性是相当新的,所以为了提高性能而使用仅位置参数的概念将仅限于 Python 3.8+版本
№3:初始化时返回
虽然这种方法并不常见,而且可能是一个相当大的新手动作,但我见过有人尝试在初始化函数中执行 returns。在 Python 面向对象的世界中,每次实例化一个类时都会调用 init 函数。init 函数对于设置变量、移动数据和构造类型非常有价值。然而,随着强大的能力而来的是巨大的责任,Python 的 init 函数应该用于类初始化,而不是监视、循环、定向,只是类初始化。并且拜托(我有经历过有人这么做!)
初始化时不要返回!
(没有任何意义!)
№4:循环依赖
当用完成相似目标的不同部分编写一个大的 Python 包时,通常你的包会互相依赖。这可能会产生很大的问题,并导致所谓的“循环依赖”发生这种情况时,当模块中的不同位置试图相互访问时,就会遇到问题。
№5:空格还是缩进?
众所周知,Python 使用缩进而不是分隔符来将代码包含在其他代码中。对许多人来说,这使得代码更容易阅读和编写,尽管我个人主观上很鄙视它。然而,在其他语言中,我通常倾向于用缩进(tab 键)来缩进代码。)然而,根据 PEP8,你应该使用四个空格来缩进。老实说,这是我和很多人一起做项目时唯一遵循的原则。对我来说,只要保持一致,我不认为空格或缩进有什么关系——但正式来说,你应该使用空格。也就是说,在为一项工作或需要许多其他用户观察的大型团队项目编写代码时,遵循 PEP8 的标准可能是一个好主意。
№6:块迭代
当执行迭代 for 循环时,当您编写完整长度的 for 循环时,在代码中表达您的想法会容易得多。然而,一般来说,如果您需要执行的操作只需要一行,那么最好是循环一行。这不仅会使您的代码更加漂亮和简洁,而且还会带来相关的性能提升。
而不是:
for i in x:
i += 5
做:
[i + 5 for i in x]
№7:内部字符串
对于要考虑的最后一个错误,我想谈谈互联网字符串。在某些情况下,Python 会尝试重用不可变的对象,字符串实习就是这种情况的一个例子。所有长度为 1 的字符串都被保留。除 ASCII 字符、数字和下划线之外的任何字符串都不会被保留。
这里我试图创建两个不同的对象,a 和 b,但是这不是 Python 所做的。Python 实际上把 b 变成了指向 a 的指针,而不是产生一个新的字符串。但是如果我们添加一个 ASCII 字符:
所以在使用不可变字符串的时候要记住这一点,因为它确实给我带来了很多麻烦。
7 个月的关系,WhatsApp 消息分析
他们说,交往是关键。没有交流,任何关系都是生不如死。在这个时代,就通信而言,技术占据了中心舞台。在这篇文章中,我们将分析我和我未婚夫之间的 WhatsApp 消息,最终你可以在 WhatsApp 数据上应用这些知识。我们将在这个分析中使用 Python,并具体处理:Pandas 表、数据可视化、数据清理等等。
在我们开始之前,我想提一下,我们已经有一年半的关系了,可用的聊天时间是从 2019 年 12 月 18 日到 2020 年 8 月 10 日(236 天或 7 个月 23 天)。在这期间,我离开了我的祖国,离开了她的家乡。我们是土生土长的肯尼亚人,但我目前在南非。
现在让我们继续分析数据。我希望我们一步一步来,这样你就清楚了。
步骤 1:获取 WhatsApp 数据
WhatsApp 允许用户将整个聊天记录下载到一个文本文件中。要做到这一点,请打开您有兴趣获取数据的对话。在右上角点击 3 个点>更多>导出聊天>无媒体。之后,将下载一个文本文件,它将包含从开始到结束的转换中的所有消息。为了清楚起见,我把我的保存为whatsapp.txt
。
图 1:获取转换数据的过程。(来源:作者)
第二步:查看数据
打开文件whatsapp.txt
时,你会看到这样一个文件
图 whatsapp.txt 文件的前 5 行(来源:作者)
- **第 1 行:**这是 WhatsApp 的一条消息,确保消息是端到端加密的。这是一个特例,我们将在分析中跳过它。
- 第 2 行到第 5 行:通常,每一行代表发件人的一条消息。它将包含日期、时间、发送者以及消息。
注:有两个寄件人(我和我未婚夫)。我把我未婚夫的名字保存为我的妻子,我爱你❤ ,我的 WhatsApp 用户名是 koech christian 。
步骤 3:处理数据并将其保存到 CSV 中
对于每一行,我们需要提取消息发送的日期和时间、发送者和消息本身。
- **第 2 行:**这是一个空列表,用来保存我们的数据。
- 第 3 行和第 4 行:这里,我们以读取模式®读取我们的文件,并且一次遍历每一行。
- 为了理解第 6–8 行,让我们以其中一行为例:
**line** = 12/18/19, 08:15 - koech christian: Have woken up my dear.In 6, we will **strip** the **line** of trailing white spaces and **split** the **line** by the hyphen (-)Result:
12/18/19, 08:15 **#send_time**
koech christian: Have woken up my dear. **#message_section**Note: **send_time** still has both the date and the time while **message_section** has the sender and the message.Code line 7: We will split the content of **message_section** by the first occurrence of a full colon (:) hence **maxsplit = 1**. If we don't do this split function may split at the middle of the message in case a sender uses a full colon.You now know what 8 does.
- 第 9 行到第 15 行:我们将感兴趣的值传递到一个字典中,然后将其追加到数据中。
- 第 19 行和第 20 行:将数据写入名为
messages.csv
的 CSV 文件。 - 由行 1 引发的异常将由
try...except...
处理
步骤 4:查看 CSV 文件
让我们加载我们在步骤 3 中保存的 CSV 文件(messages.csv
),看看几行是什么样子的。
输出:
接下来的事情是分析数据,但在此之前,我只是想做出我的猜测,可能是我的预期。第一,我知道这很傻,但我给我的句子加标点符号,她不 LoL!。她睡得很早,甚至没有说晚安,所以我打赌我会在任何一天结束谈话。她也比我醒得早,我想她会开始大部分的“早上好”信息。
当我们回到肯尼亚时,她很少在 WhatsApp 上和我聊天。这意味着我去南非之前(2020 年 2 月 2 日之前)的信息数量肯定会比我在这里时我们互相发送的信息少。
第五步:数据分析
在数据分析中,我们将使用 Pandas 库进行描述性统计,并使用 Matplotlib 中的 Pyplot 模块来可视化我们的分析结果。
让我们开始吧!
活动天数
在我们有数据的 236 天中,有多少天我们实际上交换了 WhatsApp 信息?
输出:
Active days: 222
First Day: 2019-12-18
Last Day: 2020-08-10
Difference of Dates: 236
让我们再来看看代码实际上在做什么
- 第 1 行:将日期字符串转换成 Python 日期时间对象。
- 第 3 行和第 4 行:通过简单地计算日期列中唯一值的数量来确定活动天数。
- 第 6 行到第 10 行:获取聊天历史的第一天和最后一天。对话中包含的消息是从 2019 年 12 月 18 日到 2020 年 8 月 8 日。
- 第 12–15 行:获取 6–10 中确定的第一个和最后一个日期之间的差值。
从这里可以看到我们在 WhatsApp 上聊过 236 天的 222 天 (94%的时间)。事实上,造成差异的 14 天是选择存在的。我们使用了另一种交流方式(当我回到肯尼亚的时候)。我在南非的时候,我们有 100%活跃的日子。我们马上就会发现。
谁的消息最多?
我想我是留言最多的人,但差别不会很大。让我看看。
输出:
Total Messages: 34491
My Wife, I LOVE YOU ❤ 18030
koech christian 16461
哎呀!总共 34491 条信息,其中大部分是她写的。她得听听这个。
第一条和最后一条消息(一天的开始和结束)
正如我所说的,我很确定这一点:她通常会开始这一天,而我通常会结束这一天。那位女士总是在说晚安之前就睡觉,而且总是在早上道歉。
早晚信息(第 1-7 行)
- 第 2 行:在这一行中,我们按照日期和时间对数据帧进行排序,这样我们就可以将第一天的消息放在当天聊天的顶部。我们还删除了重复的消息,这样我们就可以在每天的数据帧中保留最早的消息。最后,我们统计每个发送者的早期消息。
- 第 3 行:输出(早间消息)
My Wife, I LOVE YOU ❤ 157
koech christian 63
- 第 11 行:输出(当天的最后一条消息)
koech christian 156
My Wife, I LOVE YOU ❤ 64
惊人的发现!的确,大多数日子里她写第一条信息,而大多数晚上我写最后一条信息。更令人惊讶的是它们的对称程度。这就好像我们在平等地进行“晨跑”和“夜跑”。
自从我们开始这段关系到现在,我一直不明白为什么她总是不说晚安就睡觉。开始的时候我很不舒服,但是我最终接受了那个层次的她。
一段时间内每天的邮件数量
嗯,对于这一个,我知道期待什么,但我不知道理想的关系应该是怎样的。当关系变得稳固时,发信息的速度是否会下降,或者下降意味着一段失败的关系?我不知道,但对我来说,我认为有一些因素在起作用。首先,我一直致力于减少我的手机瘾。这可能是下降趋势的一个原因。
我也希望当我在家(肯尼亚)的时候会有很少的消息,而在这里(南非)会有更多的消息,因为 WhatsApp 现在是主要的沟通渠道。
让我看看。
看来我的预测是对的。自从我旅行以来,每天的信息数量有所增加,但持续下降。为了真正理解这一点,让我们在上面的图上画一条趋势线,也画一条我出国旅行那天的垂直线。
趋势平滑
有很多方法可以形成平滑的趋势线。这些方法包括重采样和滚动窗口。
重采样
将时间序列数据重新采样到更低或更高的频率通常是有用的。重新采样到较低的频率(下采样)通常涉及一个聚合操作——例如,从每日计数中计算每月邮件总数。
重新采样到更高的频率(上采样)不太常见,通常涉及插值或其他数据填充方法,例如,将每日数据插值到每小时间隔中,以输入到模型中。
Pandas resample()
方法,该方法将数据索引分成时间仓,并按时间仓对数据进行分组。resample()
方法返回一个重采样器对象,类似于熊猫group-by()
函数。聚合方法如mean()
、median()
、sum()
等。,然后可以应用于每个时间仓的数据组。
滚动车窗
滚动窗口操作是时间序列数据的另一个重要转换。类似于下采样,滚动窗口将数据分成时间窗口和,并且每个窗口中的数据用诸如mean()
、median()
、sum()
等函数聚集。但是,与时间窗不重叠且输出频率低于输入频率的下采样不同,滚动窗口重叠并以与数据相同的频率“滚动”,因此转换后的时间序列与原始时间序列具有相同的频率。
对于我们的数据,我们将使用滚动窗口来拟合趋势线
从上图中,我们可以看到趋势线(窗口大小为 50 天)实际上与我们的预测相匹配。在我旅行之前(洋红色垂直线的左边),我们使用 WhatsApp 的频率比旅行之后(右手边)要少。同样清楚的是,每天的消息数量正在随着时间的推移而下降。
一天中最大和最小的消息数量
最大:一天 461 条消息。日期:2020 年 2 月 13 日
最小:每天 1 条消息。日期:2019 年 12 月 22 日,2020 年 1 月 1 日及其他
实际单词和句子的分析
如果我们了解我们每个人使用的常用单词/表情符号,那将会非常有趣。在本节中,我们正是这样做的。
每位发送者的总字数
在本节中,我们将统计每个发件人的所有消息的所有单词(注意,我们跳过了一些填充词,如下面的行 10 和 16 所示的a
、and
、&、the
输出:
Number of words(Myself): 105612
Number of words(mylove): 113716
又来了!她赢了!。
让我们看一下上面的代码片段,这样你就能理解它是做什么的了。
- 第 6 行和第 12 行的 If…else…语句用于调节发送器上的过滤器。
- 第 8 行和第 14 行在理论上做同样的事情。让我们看一个例子。
message = "Okay. Bye for now 💕💕💕💕"word_list = message.strip().lower().translate(str.maketrans('', '', string.punctuation)).split(" ")print(word_list)**Result:** ['okay', 'bye', 'for', 'now', '💕💕💕💕']
在这部分代码中,我们剥离尾部空格的消息,将单词改为小写,将标点符号的消息剥离(注意句号被剥离),最后通过空格分割消息,这样我们就有了一个单词列表。
最常见的单词有哪些?随着时间的推移,有哪些独特的词语被使用?
collections
库中的模块让我们的事情变得简单。在第 4 行和第 5 行,我们计算字数。结果是单词计数元组对的列表,例如,
**text** = "dog is a pet, hen is a bird"
**result** = Counter(text.split()).most_common()
**print(result)**
**[('is', 2), ('a', 2), ('dog', 1), ('pet,', 1), ('hen', 1), ('bird', 1)]**
从这里开始,可以通过简单地获得结果列表的长度来确定唯一单词的数量(第 7–9 行)。
第 7–9 行的输出:
Unique words used:
Unique words She used: 8783
Unique words I used: 7281
她又赢了。我不知道这是不是衡量智力的好方法,但我相信她是更聪明的一个。难怪!
接下来,我们想得到最常用的单词
注意,我们已经在两个变量most_common_me
和most_common_her
中有了最常见的单词。在下面的代码片段中,我们将只选择前 10 个。
一旦我们有了最常用单词的列表和计数,我们现在就可以把它们放在一个熊猫的数据框架上,还可以制作一些柱状图来直观显示这些单词,如下所示
结果:
她最常用的词
我常用的词
说实话,数据不会说谎。从她的统计数据来看,我对I, you, my
和love
名列榜首并不感到惊讶。她经常使用它们,当她写下像“我爱你,我的爱人”这样的信息时,我总是不会感到惊讶,哈哈!。另一方面,我最了解的就是如何笑。难怪😂位居前十。但是相信我,我不会用很多表情符号,我可能只知道两个表情符号:😂和🙈。
事实上,让我们继续分析表情符号的用法。
表情符号爱情
表情符号主要用于表达情感,只是一种增加交流乐趣的方式。让我们深入分析一下
- Line 1–4:我们正在使用
emoji
包,借助extract_emojis
函数从句子中提取表情符号,例如,
extract_emojis("K😂ip 😆rono🤣 El😂ij😁 😆ah")result: '😂😆🤣😂😁😆'
- 第 6–24 行:遍历所有消息,并将所有表情提取到发送者列表中。
输出:
Most Common emojis used (Me)
('😂', 1652)
('🙈', 270)
('😍', 85)
('😘', 52)
('😋', 45)
Most Common emojis used (Her)
('😂', 1577)
('♀', 132)
('🤦', 120)
('😘', 81)
('❤️', 67)
情节:
最常用的表情符号
我们是最开心的一家人。我们俩都用😂不过当然我用的最多还是比她多。
时间和活动分析
了解聊天在一段时间内的分布也很有趣。
我们的确主要在周四和周五聊天,但实际上没什么区别。
上图显示了平均一天的聊天分布。在 0000 到 0500 之间的大多数日子里,我们都在睡觉,因此没有太多的活动。聊天量逐渐增加,在 2000 小时到 2100 小时之间达到峰值,然后随着我们继续睡觉,聊天量迅速下降。
我做的最后一项分析是确定我们写过的最长的信息,
再一次,她用她自己最长的包含 166 个单词的信息来引导我,而我只有 62 个单词。
结论
在这篇文章中,我希望你玩得开心,也学到了东西。我们使用 pandas 对数据进行了清理、描述和可视化,通过这样做,你可以做出调整,使你们的关系更好,或者更好地理解字符串操作。
您可以使用自己的 WhatsApp 数据按照相同的步骤复制相同的内容。
一如既往,感谢阅读:-)
数据科学简历中的 7 个必备要素
寻找新角色?一定要检查这些临界点才能脱颖而出,通过简历筛选。
图片由授权(经许可使用)
管理 Riskified 的数据科学部门需要大量招聘——我们在不到一年半的时间里增加了一倍多。作为几个职位的招聘经理,我也看了很多简历。招聘人员用 7.4 秒筛选一份简历,在招聘了几年之后,我的平均时间相当快,但没有那么快。在这篇博客中,我将向你展示我的个人启发法(“作弊”),它可以帮助我筛选简历。虽然我不能保证其他人使用相同的启发式方法,并且不同的角色在每个要点的重要性方面会有所不同,但注意这些要点可以帮助你征服 CV 屏幕阶段。此外,其中一些试探法可能看起来不公平,或者可能会忽略合格的候选人。我同意,没有在简历上投资的有才华的机器学习从业者可能会被这个屏幕拒绝,但考虑到时间,这是最好的权衡。记住,一个非常抢手的职位可能会吸引上百份简历。如果你想要一个高效的流程,简历筛选必须快速。
以下是用于快速筛选你的数据科学简历的 7 种试探法:
1.作为数据科学家的先前经验
我将快速浏览您的简历,看看您以前的职位,看看哪些被标记为“数据科学家”。还有一些其他相邻的术语(取决于我招聘的角色),如“机器学习工程师”、“研究科学家”或“算法工程师”。我没有将“数据分析师”包括在内,因为日常工作通常不同于数据科学家的工作,而且数据分析师的头衔是一个非常宽泛的术语。
如果你在目前的工作岗位上从事数据科学工作,并且你有一些其他创造性的工作描述,那么将你的头衔改为数据科学家可能对你最有利。对于事实上是数据科学家的数据分析师来说,这是千真万确的。请记住,即使简历包含了你所从事项目的描述(其中包括机器学习),除了数据科学家之外的头衔也会增加不必要的模糊性。
此外,如果你参加过数据科学训练营或该领域的全日制硕士课程,这可能会被视为你数据科学经历的开始(除非你之前从事过类似的工作,这将保证在稍后阶段提出问题)。
2.面向业务的成就
理想情况下,我想看看你做了什么(技术方面)和业务成果是什么。缺乏精通技术、能够用商业术语交流的数据科学家。如果你能分享你的工作所影响的业务 KPI,在我看来这是一个很好的建议。例如,表明您的模型在 AUC 方面的改进是没问题的,但解决由于您的模型改进而导致的转化率增加意味着您“明白了”——业务影响才是最终真正重要的。比较以下描述相同工作但侧重点不同(技术与业务)的选项:
a.银行贷款违约率模型——将模型的精确召回 AUC 从 0.94 提高到 0.96。
b.银行贷款违约率模型—将业务部门的年收入提高了 3%(每年 50 万美元),同时保持不变的违约率。
3.教育
你的正规教育是什么,在什么领域。是知名机构吗?对于更多的应届毕业生,我也会看看他们的平均绩点,以及他们是否获得过任何优秀奖或荣誉,比如上了校长或院长的名单。由于数据科学是一个完全开放的领域,没有任何标准化的测试或所需的知识,人们可以通过各种方法进入该领域。在我的上一篇博客中,我写了进入这个领域的 3 条主要途径,基于你的教育和时机,我会找出你可能选择了哪一条。因此,时机有助于理解您的故事,即您是如何以及何时过渡到数据科学的。如果你没有接受过任何数据科学方面的正规教育,那很好,但你需要证明你在该领域的工作记录和/或类似领域的高等学位。
4.布局/视觉吸引力
我见过一些漂亮的简历(我保存了一些作为个人灵感),但我也收到过文本文件(。txt ),缺少任何格式。写简历可能是一件痛苦的事,如果你选择了数据科学作为你的努力方向,那么你很可能不喜欢在业余时间创造美学设计。在不走极端的情况下,您确实希望寻找一个好的模板,使您能够在有限的空间内完成所有工作。明智地使用空间——将页面分开,突出不属于按时间顺序排列的工作/教育经历的特定部分是很有用的。这可以包括你熟悉的技术栈,一个自我项目列表,到你的 github 或博客的链接等等。一些简单的图标也有助于强调章节标题。
许多候选人在他们熟悉的每种语言/工具旁边使用 1-5 颗星或条形图。就我个人而言,我不太喜欢这种方法,原因有几个:
- 这非常主观——你的“5 星”和别人的“2 星”是一样的吗?
- 他们把语言和工具混在一起,在最糟糕的情况下,还把软技能混在一起——说你在领导力方面的“4.5 星”没有帮助。作为一个对成长心态深信不疑的人,声称最大限度地发挥一项技能(尤其是一项更难量化、更难掌握的软技能)感觉非常放肆。
我还看到这种方法被进一步滥用,采取主观的方法,并把它们变成一个饼图(30% python,10%团队成员,等等)。虽然这可能被认为是一种脱颖而出的创造性方式,但它表明了对不同图表概念背后的基本理解的缺乏。
这里有两个我觉得视觉上很吸引人的简历例子,为了匿名细节被模糊了。
信用伊娃米舍(经许可使用)
视觉上吸引人的数据科学家简历,细节模糊。请注意两个例子中使用的垂直分割来区分经验、技能、成就和出版物。在这两种情况下,简短的总结段落有助于描述他们的背景和愿望。经所有者许可使用。
5.机器学习种类
我寻找两种类型的变化:
- 算法类型—结构化/经典 ML vs 深度学习。一些候选人只从事深度学习,包括可能更适合基于树的模型的结构化数据。虽然成为 DL 专家本身没有问题,但是限制您的工具集会限制您的解决方案。正如马斯洛所说:“如果你拥有的唯一工具是一把锤子,你往往会把每个问题都视为钉子。”在 Riskified ,我们处理结构化的、领域驱动的、特征工程化的数据,这些数据最好用各种形式的提升树来处理。拥有一个整个简历都指向 DL 的人是一个问题。
- ML 领域——这通常与两个需要大量专业知识的领域相关——计算机视觉和 NLP。这些领域的专家很受欢迎,在许多情况下,他们的整个职业生涯都将专注于这些领域。如果你正在寻找从事该领域工作的人,这一点至关重要,但通常来说,这不适合从事更一般的数据科学工作的人。因此,如果你的大部分经验是在 NLP 领域,而你申请的是该领域之外的职位,试着强调你在结构化数据领域工作过的职位/项目,以展示多样性。
6.技术堆栈
这通常可以分为语言、特定的包(scikit learn、pandas、dplyr 等)、云和它们的服务(AWS、Azure、GCP)或其他工具。一些候选人将这与他们熟悉的算法或架构混为一谈(RNN,XGBoost,K-NN)。就个人而言,我更喜欢围绕技术和工具;当提到一个特定的算法时,我不禁想知道候选人的理论上的 ML 知识是否仅限于这些特定的算法。在这里,我在寻找技术组合的相关性——它们是否来自过去几年(这是一个积极的迹象,表明候选人正在实践和学习新技能),组合的广度(它们是否非常局限于特定的工具,或者它们是否熟悉相当多的东西)以及与我们的组合的契合度(我们需要教它们多少)。
7.项目
你有什么工作可以在 GitHub 上分享的吗?任何 Kaggle 竞赛或附带项目都非常有帮助,可以查看简明代码、预处理类型、功能工程、EDA、算法选择以及现实项目中需要解决的无数其他问题。给你的 GitHub 和 Kaggle 账户添加一个链接,让面试官深入了解你的代码。如果你没有太多的经验,很有可能你会被问到这些项目中的一个或多个。在我参加的一些面试中,候选人不太记得这个项目,我们无法就他们做出的选择及其背后的原因展开对话。一定要重温你做过的工作,或者把它从简历中去掉。同样,确保你展示了你最好的作品,并且你投入了足够的时间和精力。最好有 2-3 个高质量的项目,而不是 8-10 个中等(或较低)质量的项目。
摘要
如果你正在寻找一个新的数据科学职位,请花些时间浏览一下本文中的要点。如果你不能检查所有这些标记,这没关系,但是你能检查的越多越好。希望这些建议能帮助你脱颖而出,顺利通过简历筛选。
祝你好运,找工作愉快!
在筛选数据科学简历时,你有不同的方法吗?
请在下方评论区分享!
让我的代码更好更聪明的 7 个小技巧
我希望我早点知道的技巧
Numpy 是 Python 中最重要和最流行的数值计算库之一。它被广泛应用于数据科学和机器学习,许多库都是基于它建立的。我希望在这篇文章中分享 7 个数字游戏技巧,我希望我作为一个初学者能早点知道。
1.numpy.linspace()
np.linespace(start, stop, num)
返回一个数组,数组中的数字从strat
到stop
均匀分布
例如:
画数学函数很方便:
numpy.arange()
np.arange(start, stop, step)
提供了类似的功能,它创建了一个从开始到停止的一步数组。
例如:
2.numpy.random
我们经常需要生成随机数来进行统计计算。Numpy 提供了一些函数来生成随机数。
np.random.randint()
randint(low, high, size)
生成一个范围(低—高)内的随机整数数组(size=size)。
np.random.rand()
rand()
生成在给定形状下均匀分布在 0 到 1 之间的随机数。
随机的
randn()
生成正态分布的随机数。
np .随机数.选择()
random.choice()
允许我们从给定的数组中随机选择样本。传递一个概率也是可以的。
3.numpy.argmax()
np.argmax()
返回沿轴最大值的索引。
在对象分类和检测中,找到具有最高概率的对象是有用的。
还有类似argmin()
、argwhere()
、argpartition()
的功能
4.numpy.setdiff1d()
np.setdiff1d()
返回一个数组中不在另一个数组中的值。
例如,我们有两个数组:
如果我们想找到a
中没有出现在b
中的值(答案应该是[1,2,3]),我们可以使用setdiff1d()
:
我们也可以反过来做,在 b 中寻找 a 中没有的值:
numpy.intersect1d()
一个类似的函数是intersect1d()
,它返回 2 个数组的交集,在本例中是[4,5,6]。
5.numpy 在哪
np.where(condition,x,y)
根据条件返回从 x 或 y 中选择的元素。
例如,我们有一个包含考试分数的数组:
我们想用‘pass’或‘not _ pass’代替分数。条件可以设置为scores>60
:
如果 x 和 y 没有传递给np.where
,将返回满足条件的元素的索引位置。
6.重塑()
有时我们需要重塑数组,我们可以使用resphape()
的方法。
例如,我们有一个一维数组:
我们可以将其改造成 2×5 阵列:
我们可以使用-1
,numpy 为您计算尺寸。
展平()
如果你想把一个多维数组重塑成 1D 数组,你可以使用flatten()
堆栈()
您也可以使用np.stack()
将多个数组堆叠在一个数组中。
例如:
您可以在其他轴中执行此操作,
您也可以使用hstack()
来水平堆叠数组:
7.numpy.clip()
如果您有一个包含一些数字和一个范围的数组,您可以使用clip()
将数字限制在该范围内。对于超出范围的数字,它返回边缘值。
例如:
它将数组裁剪在 3 到 5 之间。
就是这样。这些 Numpy 技巧使我的代码变得更加简单和高效。我希望这些也能帮助你
我也写过关于 Python 和熊猫的文章。有兴趣可以看看。
[## 让我的代码更好更聪明的 7 个 Python 技巧。
我希望我能早点知道的技巧。
towardsdatascience.com](/7-python-tricks-to-make-my-code-better-and-smarter-60dfde0b6c49) [## 让我的数据分析过程更高效的 10 个熊猫窍门:第 1 部分
我希望我早点知道的技巧
towardsdatascience.com](/10-pandas-tricks-to-make-my-data-analyzing-process-more-efficient-part-1-78a0cc1636f3) [## 让我的数据分析过程更高效的 10 个熊猫窍门:第二部分
我希望我早点知道的技巧
towardsdatascience.com](/10-pandas-tricks-to-make-my-data-analyzing-process-more-efficient-part-2-b72ea43a0bb5)
感谢阅读,编码快乐。
7 处理不平衡数据的过采样技术
各种过采样技术的深度分析
M 对不平衡数据建模是我们在训练模型时面临的主要挑战。为了处理分类问题,目标类别标签的类别平衡在建模中起着重要的作用。对于不平衡类问题,即数据集中存在少数类,模型会尝试只学习多数类,从而导致有偏差的预测。
不平衡的阶级问题的一些著名例子是:
- 信用卡欺诈检测
- 疾病诊断
- 垃圾邮件检测等等
在训练模型之前,需要处理数据集的不平衡。有各种技术来处理类平衡,其中一些是过采样,欠采样,或两者的结合。本文将深入解释 7 种过采样技术:
- 随机过采样
- 重击
- 临界击打
- 克平均击打
- SVM 击杀
- 阿达辛
- Smote-NC
对于不同过采样模型的评估,我们使用来自 Kaggle 的流失建模数据集。
不使用任何过采样或欠采样技术的逻辑回归模型的性能。
1.随机过采样:
随机过采样是平衡数据集不平衡性质的最简单的过采样技术。它通过复制少数类样本来平衡数据。这不会导致任何信息丢失,但是当复制相同的信息时,数据集容易过拟合。
(图片由作者提供),**左:**随机过采样后的散点图,**右:**随机过采样后模型的性能
2.击打:
在随机过采样的情况下,当少数类样本被复制时,容易出现过拟合,这里 SMOTE 出现了。SMOTE 代表合成少数过采样技术。它创建新的合成样本来平衡数据集。
SMOTE 通过利用k-最近邻算法来创建合成数据。使用 Smote 创建步骤示例:
- 识别特征向量及其最近邻
- 计算两个样本点之间的距离
- 用 0 到 1 之间的随机数乘以距离。
- 在计算出的距离处识别线段上的新点。
- 对识别的特征向量重复该过程。
(图片由作者提供),**左:**SMOTE 后散点图,**右:**SMOTE 后模型表现
3.临界击打:
由于多数类点区域内存在一些少数类点或异常值,因此会创建少数类点的桥。这是 Smote 中的一个问题,使用边界 Smote 可以解决这个问题。
在边界线 Smote 技术中,只有边界线附近的少数样本被过采样。它将少数类点分类成噪声点、边界点。噪声点是少数类点,其大多数点都是其邻居中的多数点,而边界点在其邻居中既有多数类点也有少数类点。边界线 Smote 算法试图仅使用这些边界点来创建合成点,并忽略噪声点。
(图片由作者提供),**左:**边界平滑后散点图,**右:**边界平滑后模型性能
4.KMeans 击打:
K-Means SMOTE 是一种用于类不平衡数据的过采样方法。它通过在输入空间的安全和关键区域生成少数类样本来帮助分类。该方法避免了噪声的产生,并且有效地克服了类之间和类内的不平衡。
K-Means SMOTE 分五步工作:
- 使用 k-means 聚类算法对整个数据进行聚类。
- 选择具有大量少数类样本的聚类
- 将更多合成样本分配给少数类样本分布稀疏的聚类。
这里,使用 SMOTE 对每个滤波后的聚类进行过采样。
(图片由作者提供),**左:**k means 击打后散点图,**右:**k means 击打后模型性能
5.SVM 击打:
边界重击的另一个变体是边界重击 SVM,或者我们可以称之为 SVM 重击。这种技术结合了 SVM 算法来识别错误分类点。
在 SVM-SMOTE 中,在原始训练集上训练支持向量机分类器后,边界区域由支持向量近似。然后,沿着将每个少数类支持向量与其多个最近邻居连接起来的线,随机创建合成数据。
(图片由作者提供),**左:**SVM 击杀后散点图,**右:**SVM 击杀后模型表现
6.自适应合成采样— ADASYN:
边界线 Smote 更重要,或者仅使用作为边界点的极端观测值创建合成点,而忽略其余的少数类点。ADASYN 算法解决了这个问题,因为它根据数据密度创建合成数据。
合成数据的生成与少数群体的密度成反比。与较高密度的区域相比,在低密度的少数民族类区域中创建了相对较大数量的合成数据。
换句话说,在少数类的不太密集的区域,合成数据被创建得更多。
(图片由作者提供),**左:**ADASYN 后散点图,**右:**ADASYN 后模型表现
7.Smote-NC:
Smote 过采样技术仅适用于具有所有连续特征的数据集。对于具有分类特征的数据集,我们有一个 Smote 的变体,它是 Smote-NC(名义的和连续的)。
Smote 也可以通过一键编码用于具有分类特征的数据,但它可能会导致维数增加。标签编码也可以用于将分类转换为数字,但是 smote 之后可能会产生不必要的信息。这就是为什么当我们有混合数据的情况下,我们需要使用 SMOTE-NC。Smote-NC 可以通过表示分类特征来使用,Smote 会对分类数据进行重新采样,而不是创建合成数据。
(图片由作者提供),**左:**SMOTE-NC 前车型性能,**右:**SMOTE-NC 后车型性能
实施:
(作者的代码实现)
结论:
对不平衡数据集建模是我们在训练模型时面临的主要挑战,使用上面讨论的各种过采样技术可以提高模型的性能。在本文中,我们还讨论了 SMOTE-NC,它是 SMOTE 的一个变体,可以处理分类特征。
通过使用各种欠采样技术,例如随机欠采样、TomekLinks 等,以及过采样和欠采样技术的组合,例如 SMOTEENN、SMOTETomek 等,也可以提高不平衡数据集的模型性能。
参考资料:
[1] Imblearn 文档:https://unbalanced-learn . readthedocs . io/en/stable/API . html # module-imb learn . over _ sampling
[2]https://pypi.org/project/kmeans-smote/
感谢您的阅读
我最常用的 7 个熊猫功能
数据分析过程中最常用的函数。
Pandas 是一个著名的数据分析和操作库。它提供了许多加快数据分析和探索过程的功能和方法。
在丰富的函数和方法选择中,有些是更常用的。它们提供了一种快速获得手头数据的基本理解的方法。
在这篇文章中,我将介绍我在数据分析项目中最常用的 7 个 pandas 函数。
我将使用 Kaggle 上的糖尿病数据集。让我们首先将数据集读入熊猫数据帧。
import pandas as pd
import numpy as npdiabetes = pd.read_csv("/content/diabetes.csv")
1。头尾
一旦我们将一个数据集读入 pandas 数据帧,我们就想看一看它以获得一个概览。最简单的方法是显示一些行。Head 和 tail 允许我们分别从数据帧的顶部和底部显示行。
diabetes.head()
diabetes.tail()
默认显示 5 行,但是我们可以通过传递我们想要显示的行数来调整它。例如,diabetes.head(10)将显示前 10 行。
2。努尼克
处理具有离散值的分类数据或要素时,了解唯一值的数量非常重要。这是数据探索的重要一步。
一种方法是使用 value_counts 函数,该函数返回一个 pandas 系列,其中包含一列中的唯一值以及每个值出现的次数。这个序列的长度是唯一值的个数。
len(diabetes.Pregnancies.value_counts())
17
我发现 nunique 更容易使用:
diabetes.Pregnancies.nunique()
17
我们还可以将其应用于整个数据帧,并查看每列中唯一值的数量,我认为这使 nunique 更具功能性:
diabetes.nunique()
3。描述
Describe 函数通过提供基本统计数据(如平均值、中值和标准偏差)来快速概述数字列。
diabetes.describe()
25%、50%和 75%是百分位数。50%也称为中值,是所有值排序时位于中间的值。25%是第一个四分位数因此 25%的值低于该点。你可以把它想象成一个列的下半部分的中值。同样,75%是第三个四分位数。
基本的统计数据给了我们宝贵的见解。例如,通过比较平均值和中间值(50%),我们可以了解异常值。如果平均值远高于中值,则在上端有异常值。基本统计数据也给我们提供了数据分布的概况。
您也可以使用百分点参数选择不同的百分点进行显示。默认值为[.25、. 50、. 75]。例如,除默认值外,百分点=[.1,. 25,. 5,. 75,… 9]将显示 10%和 90%的百分点。
4。Isna
处理缺失值是构建稳健数据分析流程的关键步骤。缺少的值应该是最优先考虑的,因为它们对任何分析的准确性都有重大影响。
Isna 函数返回用布尔值填充的数据帧,true 表示缺少值。
diabetes.describe()
除非您想要逐个单元地分析数据帧,否则 isna 应该与聚合结合使用。isna()。any()指示列中是否有任何缺少的值,而 isna()。sum()返回列中缺失值的数量。
diabetes.isna().any()
diabetes.isna().sum()
我们拥有的数据集没有任何缺失值,但这种情况在现实生活中不太可能发生。
5。分组依据
Pandas groupby 函数是探索数据的绝佳工具。它更容易揭示变量之间的潜在关系。下图概述了 groupby 函数的功能。
熊猫分组(图片由作者提供)
假设我们有两个特征。一个是颜色,它是分类特征,另一个是数值特征,即值。我们希望按照颜色对值进行分组,并计算不同颜色值的平均值**(或任何其他集合)。然后最后根据平均值对颜色进行排序。**
当然,您可以创建更复杂的分组操作,但概念是相同的。
让我们用数据集创建一个简单的分组操作。下面的代码将向我们展示糖尿病阳性和阴性人群的平均葡萄糖值。
diabetes[['Outcome','Glucose']].groupby('Outcome').mean()
正如所料,糖尿病阳性患者的血糖值较高(1)。
我们在数据集中没有很多分类变量,所以我们可以在这个数据集上用 groupby 函数做的事情是有限的。然而,如果你想阅读更多关于 groupby 函数的内容,并看到更复杂的例子,我有一个帖子专门讨论熊猫 groupby 函数。
如何高效利用熊猫的分组功能
towardsdatascience.com](/pandas-groupby-explained-453692519d0)
6。数据类型和数据类型
我们需要将值存储在适当的数据类型中。否则,我们可能会遇到错误。对于大型数据集,正确的数据类型选择会极大地影响内存使用。例如,对于分类数据来说,“分类”数据类型比“对象”数据类型更合适,尤其是当类别的数量远小于行数时。
Dtypes 显示每一列的数据类型。
diabetes.dtypes
“血压”列的数据类型不合适。应该是 int 或者 float。对象数据类型可以是存储字符串或分类数据。
我们可以很容易地用 astype 函数改变数据类型。
diabetes.BloodPressure = diabetes.BloodPressure.astype('int64')diabetes.dtypes
7。形状和尺寸
Shape 可以用在 numpy 数组、pandas 系列和 dataframes 上。它显示维度的数量以及每个维度的大小。
因为数据帧是二维的,所以 shape 返回的是行数和列数。它衡量我们拥有多少数据,是数据分析过程的关键输入。
此外,在设计和实现机器学习模型时,行和列的比率非常重要。如果我们没有足够的关于特征(列)的观察值(行),我们可能需要应用一些预处理技术,如降维或特征提取。
diabetes.shape
(768, 9)
让我们把它用在一个实际上是熊猫系列的专栏上。
diabetes.Glucose.shape
(768,)
顾名思义,Size 返回数据帧的大小,即行数乘以列数。
diabetes.size
6912
感谢您的阅读。如果您有任何反馈,请告诉我。