TowardsDataScience-博客中文翻译-2022-一-
TowardsDataScience 博客中文翻译 2022(一)
原文:TowardsDataScience
协议:CC BY-NC-SA 4.0
1:长度(A)被认为是有害的——或者如何使 Julia 代码“通用安全”
原文:https://towardsdatascience.com/1-length-a-considered-harmful-or-how-to-make-julia-code-generic-safe-ac7b39cfc2f0
照片由埃里克·维特索在 Unsplash 上拍摄
Julia 允许在相当抽象和通用的层次上编写代码,因此提供了强大的表达能力。然而,这种优势也给程序员带来了特殊的挑战。这篇文章展示了如何克服它们。
Julia 的几个语言概念,如用户可扩展的类型系统、参数类型、可选的类型声明和多重分派,使得编写非常通用的代码成为可能,并且可以应用于许多情况——甚至代码的作者也经常无法预料的情况。这些可能性也是 Julia 高度可组合性的支柱。
这是一个明显的优势,也是很多人喜欢 Julia 胜过其他编程语言的原因之一。但是这是有代价的,因为它扩大了可能出错的范围。所以在编写这样的代码时必须特别小心。
如果您编写的 Julia 代码只是供自己使用,因此能够控制传递的参数以及代码如何与其他包组合,那么您就不需要太担心这些问题。但是如果你写的代码被其他人使用(特别是公开可用的包,比如 Julia 注册表中的包),那么你需要记住这些方面。
我将给出三个常见的例子来展示这些挑战是怎样的,以及如何克服它们。这些信息中的大部分都可以在 Julia 文档中找到,但是我怀疑该语言的许多新手是否读过它们,因为在许多其他编程语言中,这些情况并不存在。那么,如果你不知道有一个问题,你为什么要去寻找答案呢?此外,最近关于话语的讨论表明,即使是经验丰富的 Julia 程序员有时也会落入这些陷阱。
数组
让我们从 Julia 中最常见的数据结构之一开始:Array
s .(一维)数组乍一看与其他编程语言中的数组非常相似(可能除了索引是基于 1 的)。
你可以在Array
上使用一堆预定义的函数,例如length(A)
给你数组A
中包含的元素个数。这提供了迭代数组并以如下方式打印每个元素的可能性:
for i in 1:length(A)
println(A[i])
end
您可以找到另一种方法,使用函数eachindex(A)
返回A
的迭代器:
for i in eachindex(A)
println(A[i])
end
第二个版本看起来更优雅,但除此之外,两个版本似乎可以互换。…这就是问题开始的地方。
事实上,如果你使用(具体的)类型Array
的数组,这两种变体只有可以互换。Array
是AbstractArray
的一个亚型。如果你允许A
是AbstractArray
的任何其他子类型,你可能会遇到麻烦。AbstractArray
不保证第一个元素在索引 1 处,也不保证最后一个元素在索引length(A)
处。
因此
1:length(A)
必须被视为有害。
如果您使用OffsetArrays
(另一个AbstractArray
的子类型),您可以自由定义索引边界。以下语句创建一个包含 11 个(随机)元素的数组,索引从-5 到 5:
B = OffsetArray(rand(11), -5:5)*--> 11-element OffsetArray(::Vector{Float64}, -5:5)
with eltype Float64 with indices -5:5*
如果您应用1:length(B)
-变量进行索引,将会出现错误,因为在这种情况下将使用索引值> 5。除此之外,索引不会从第一个元素开始,而是从第七个元素开始。
另一方面,eachindex(B)
-variant 是安全的,因为它保证你得到一个迭代器,覆盖从第一个到最后一个的所有元素,不管数据结构使用哪种索引方式。
如果您不需要索引值(如示例中的情况),下面的变体也是安全的(因为它更简洁,所以是首选的):
for a in A
println(a)
end
用线串
另一种常见的数据结构是String
s,在 Julia 中被定义为一系列Char
s。乍一看,String
s 可以像字符数组一样使用(类似于 Java 或 C)。所以要访问字符串s = "Hello"
中的第二个字符,你可以写c = s[2]
。该操作后,变量c
包含字母“e”。
您可以使用s[3]
来访问s
中“e”后面的字符(本例中为“l”)。
只要只使用 ASCII 字符,这就可以工作。但是在 Julia 中,Char
可能是任何 Unicode 字符(UTF 8 编码)。这些字符可能需要多于一个字节的存储空间(与纯 ASCII 字符相反)。
对于 Unicode 字符,上面的例子不再适用:
u = “α = alpha” # string with a Unicode-characteru[1] --> 'α': Unicode U+03B1 (category Ll: Letter, lowercase)u[2] --> **ERROR:** StringIndexError: invalid index [2],
valid nearby indices [1]=>'α', [3]=>' '
u
(‘α’)中的第一个字母是一个(2 字节)Unicode 字符。因此u[2]
不是可打印字符(而是第一个字符的一部分)。
要安全地索引任意 Unicode 字符串,您需要以下函数:
firstindex(u)
—u
的最小指数lastindex(u)
—u
的最大指数nextind(u, i)
—索引i
之后的下一个有效索引prevind(u, i)
—索引i
之前的前一个有效索引
因此,要获得u
(‘α’)中的第一个字符,然后是‘α’后面的下一个字符,您应该使用:
i = firstindex(u) --> 1
u[i] --> 'α': Unicode U+03B1
(category Ll: Letter, lowercase)i = nextind(u,i) --> 3
u[i] --> ' ': ASCII/Unicode U+0020
(category Zs: Separator, space)
为了安全地迭代一个字符串的所有元素,下面的表达式完成了这项工作(只有当您想要在一个字符串内来回移动时,才需要上述函数):
for c in u
println(c)
end
类型声明
到目前为止,我们看到的两个例子处理的是您应该在适当的抽象级别上访问数据结构的情况。也就是说,对数据结构的访问不应该依赖于对其实现的知识或(更糟的)假设。
下一个例子提出了另一个主题:关于类型声明的使用。
在 Julia 中,类型声明是可选的,但它们有助于编译器生成最佳代码。编译器至少需要知道输入参数的具体类型,以便为算法生成高效的代码。基于这个起点,它可以推断出大多数情况下所有其他变量的类型。
另一方面,您希望您的代码尽可能通用,以使其适用于广泛的情况。这两个要求相互冲突。
让我们看一个例子来更清楚地说明这种情况。二维空间中的点的类型定义可能如下所示:
struct Point
x
y
end
这是这种定义的最一般的方式。但是通常我们希望在我们的Point
上定义依赖于一些算术函数的函数,如下例所示:
function distance(a::Point, b::Point)
sqrt((b.x - a.x)^2 + (b.y - a.y)^2)
end
为了保证这些算术函数可用于x
和y
,我们必须将这些字段声明为Number
类型。这是最通用(即最不具体)的声明:
struct Point
x :: Number
y :: Number
end
所以保持代码尽可能通用的需求通过Point
的定义得到了满足。但是对于编译器来说并不是真正有用的。
当创建Point
s 的实例时,我们可以使用Number
的任何子类型,如Int8
、Int64
、Int128
、Float16
、Float32
、Complex{Float32}
、Rational{Int64}
等。例如,如果我们想要用我们的Point
类型在屏幕上表示像素,那么x
和y
的Int32
值可能适合这个任务。为了对一些数学应用的点进行建模,我们可以使用Float64
来表示真实值。对于这两个用例,多边形(表示为点的向量)的定义是:
pixel_poly = Vector{Point}()real_poly = Vector{Point}()
两个表达式是相同的。这意味着编译器不知道在每种情况下需要什么样的内存表示,因此无法为该特定类型生成优化的代码。相反,它必须提供一个非常通用的结构,能够存储上述每个子类型。这样效率不高。
解决这一冲突的方法是使用(受约束的)参数类型,如下所示:
struct Point{T <: Number}
x :: T
y :: T
end
当创建一个Point
的实例时,使用参数类型T
仍然给了我们使用任何具体类型T
的自由。声明<: Number
将可能的类型限制为Number
的子类型(同上)。
但是,如果我们需要一个特定的实例,我们现在也可以指定它的类型,并将多边形的两个定义写成:
pixel_poly = Vector{Point{Int32}}()real_poly = Vector{Point{Float64}}()
使用(受约束的)参数类型代替抽象类型满足了我们的两个要求:类型的广泛适用性和能够通知编译器在特定用例中需要的具体类型。
结论
我们已经看到了编写泛型 Julia 代码的一些最常见的挑战,以及如何使其安全。
前两个例子表明,您必须理解数据类型提供的抽象,并使用与该抽象级别匹配的函数来访问它:
AbstractArray
表示(在一维情况下)可以使用索引访问的元素序列。但是它没有断言最小和最大索引。
只有具体子类型Array
保证第一个索引为 1,最后一个索引为length(A)
。String
表示一系列的Char
,但是它没有断言它们的大小相等。
只有当您将应用程序限制为 ASCII 字符时,您才可以假定大小相等(一个字节)。
在所有这些情况下,Julia 都提供了一组丰富的函数来以一种适当(并且安全)的方式处理数据结构。
最后一个示例演示了如何将类型声明与参数类型结合使用,以尽可能保持代码的通用性,同时为编译器提供足够的信息来生成最佳代码。
当然,这些并不是你必须小心这些问题的唯一情况。但我认为这些例子很有代表性,希望我能提高对这些挑战的认识。
定义 2021 年的 10 个人工智能模型
原文:https://towardsdatascience.com/10-ai-models-that-have-defined-2021-7d804b87b10
未来将建立在这些基础上
Kirichay D 在 Shutterstock 上拍照
人工智能不断加速。每年我们都会读到大量的新闻,谈论新的人工智能模型,这些模型将彻底改变 X 行业或将人工智能推向新的高度。但是,信噪比很低。只有一堆令人印象深刻的突破值得铭记。
2021 年没有什么不同,这就是为什么我按时间顺序列出了今年最相关和最有影响力的车型。尽管研究和开发的路线多种多样,但有几个明显的趋势:大型语言模型变得更大,未来的顶级模型很可能是多模态的,对效率的追求正在得到有趣的结果。我用一小段描述了每个模型对该领域的主要影响。尽情享受吧!
开关变压器:第一个+1T 参数模型
**影响:**稀疏性支持将模型扩展到巨大的规模,这对于密集架构是不可行的,同时保持计算负担不变。
2021 年 1 月,谷歌发表了论文“开关变压器:通过简单有效的稀疏性扩展到万亿参数模型他们提出了一种新的语言模型架构,以证明模型可以增长到超过 1T 参数(开关变压器具有 1.7T 参数),同时保持计算成本稳定。
为了保持较低的计算要求,switch transformer 使用了由深度学习先驱 Geoffrey Hinton 共同发明的专家混合范式的变体。模型的参数被分成 2048 个专家,使得输入仅由一个专家处理。在任何给定时间,只有一小部分参数是活动的,即稀疏模型。
GPT-3 和大多数其他语言模型是密集的——它们使用整个模型来处理每个输入。通过利用稀疏性,开关变压器降低了计算成本,同时提高了精度和功耗。
一张图片胜过千言万语
影响: DALL E 利用丰富的自然语言创造出各种各样的图像。这是最早流行的多模式人工智能之一。
OpenAI 于 2021 年 2 月建造了 DALL E 。该模型以西班牙著名画家萨瓦尔多·达利和可爱的皮克斯机器人瓦力命名,是 GPT 3(120 亿参数)的小型版本,并在文本-图像对上接受训练,以“通过语言操纵视觉概念”
DALL E 采用自然语言书写的句子,并使用预期的含义生成图像。它的力量依赖于它的零射击能力;它可以执行没有经过训练的生成任务,而不需要例子。DALL E 创造性地利用了语言和图像相结合的可能性——例如,将高层次的概念融合到一幅图像中。用“竖琴做的蜗牛”或“鳄梨形状的扶手椅”来提示它,会给出你所期待的确切的,尽管世界上不存在任何类似的东西。
DALL E 加入了人工智能画家的行列——谷歌的 DeepDream 、 Ai-Da 、显见等等。创造力曾经是我们的专利,但现在不再是了。DALL E 已经证明,人工智能更接近于赋予“一张图胜过千言万语”这句话新的含义。
谷歌输入/输出大会:妈妈和 LaMDA
影响:类似妈妈的模特会简化在互联网上搜索的过程。LaMDA 是创造类似人类的对话式人工智能的最新一步。
谷歌一年一度的输入输出事件发生在 2021 年 5 月。技术高管展示了最新的产品和研究,其中 MUM (多任务统一模型)和 LaMDA 被描绘成明星。两种语言模型,没有什么好羡慕流行的 GPT-3 的。MUM 是搜索引擎的未来,而 LaMDA 是一个能够进行有趣对话的聊天机器人。
基于 Transformer 架构和以前的系统,如 BERT 和 Meena,谷歌建立了 MUM 和 LaMDA 其技术规格仍未披露。但是我们知道一些关于他们的事情。MUM 的使命是进一步增强谷歌的搜索引擎——可能会让 SEO 过时,正如我在之前的一篇文章中所说的。MUM 比 BERT(谷歌目前支持搜索引擎的力量)强大 1000 倍,可以处理跨语言、跨任务、最重要的是跨模式的自然语言复杂查询——它理解文本和图像。
LaMDA 以与人交流为导向。作为一个明智、具体、有趣和实事求是的聊天机器人,LaMDA 可以管理开放式对话——正如首席执行官桑德尔·皮帅在演示中通过让 LaMDA 扮演冥王星和纸飞机的角色向展示的那样。人类可以从一个句子中创造出一千条独特的路径。我们只需要做出选择,整个世界就会从那里出现。LaMDA 更接近于能够做同样的事情。
中国的语言人工智能市场:悟道 2.0,M6
**影响力:**这些模型为中国在人工智能研究、开发和效率方面达到第一做出了巨大贡献。
中国一直在努力在技术开发和研究方面赶上美国,人工智能是一个特别热门的领域。去年有两款车型引起了分析师的关注:武道 2.0(1.75 吨)和M6(10 吨)。它们基于在性能、计算成本降低和污染减少方面利用稀疏性的承诺。
2021 年 6 月,Wu Dao 2.0 害羞地亮相,声称它是有史以来最大的神经网络,规模是 GPT-3 的 10 倍。两者的主要区别是吴导的多模态性;作为一个通用的语言模型,它是第一个像 DALL E 或 MUM 那样利用多模态的语言。然而,性能方面没有太多的信息,因为北京人工智能研究院(BAAI)没有给出任何结果。(我的猜测是,该模型并没有被训练成收敛,而是作为一个实验来分析专家混合范式的力量)。
由阿里巴巴 DAMO 学院建设的 M6 经历了一个阶段性的发展过程。它于 6 月首次以 1T 参数作为多模式和多任务模型推出。然后,在 2021 年底,研究人员发表了一篇文章,概述了一个惊人的结果:在 10 万亿个参数下,新版本的 M6 在训练期间消耗的计算成本只有 GPT-3 的 1%——在效率和减少碳足迹方面达到了一个新的里程碑。
微软和英伟达联手:MT-NLG
影响:这是最大的密集语言模型,也是 Nvidia 和微软合作的第一个潜在的其他发展。
10 月,Nvidia 在其博客中发布消息称,他们已经与微软联手打造了(至今)最大的密集语言模型。MT-NLG 在 530B 参数上大于 GPT-3、J1-Jumbo 和 Gopher(尽管明显小于稀疏模型)。在大多数基准测试中,MT-NLG 比 GPT-3 具有更好的性能,直到最近,它仍然是我们拥有数据的顶级语言模型。
我把它列入这个名单的另一个原因是 Nvidia 和微软的联盟。两家大型科技公司都是人工智能领域的佼佼者。英伟达是图形处理器的头号制造商和提供商,微软在云服务和人工智能软件方面有着非常强大的影响力。这种伙伴关系的未来努力将值得关注。
GitHub Copilot:你的互惠生程序员
影响: GitHub Copilot 是程序员迈向自动化最枯燥重复任务的第一步。它最终也会成为一种威胁。
GitHub 的母公司微软和 OpenAI 联手创造了 GitHub Copilot ,许多开发者已经在日常工作中使用它。copilot——扩展了 GPT-3 强大的语言技能,并作为 OpenAI 编码模型 Codex 的基础——擅长编程。它可以跨语言工作,可以完成代码行,编写完整的函数,或者将注释转换成代码,还有其他功能。
一些用户指出由于版权和许可的潜在法律问题。副驾驶从哪里学的?使用它所有的完成是否安全?如果最终触犯了法律,该怪谁?但是不管它的大图限制,它是编码未来的一个重要里程碑。它很可能成为开发人员工具箱中的必备工具。
DeepMind 进入语言 AI 的入口:地鼠,复古
影响: Gopher 是目前排名第一的语言模型。复古证明,新技术可以提高效率(降低成本和碳足迹)数量级超过以前的模式。
DeepMind 这些年一直保持沉默,而全球的公司都参与了人工智能语言的爆炸。自从谷歌发明了 Transformer 架构以来,语言人工智能已经成为研究的主要焦点,超过了视觉、游戏和其他领域。作为主要的人工智能公司之一,DeepMind 的缺席令人惊讶。
2021 年 12 月,情况发生了变化。DeepMind 发表了三篇关于语言 AI 的论文。首先,他们提出了 Gopher ,一个 280B 参数密集模型,在 124 个任务中的 100 个任务中抹杀了能力——包括 GPT-3、MT-NLG 和 J1-Jumbo。一夜之间,DeepMind 不仅成为了强化学习的领导者,也成为了语言人工智能的领导者。Gopher 现在是有史以来无可争议的最好的语言模型。
第三篇论文更令人印象深刻。在 7B 参数下, RETRO (检索增强的 Transformer)是一个小一点的语言模型。然而,尽管它比 GPT-3 小 25 倍,但在各项基准测试中,它的性能不相上下。与 GPT-3 相比,DeepMind 通过该模型实现了 10 倍的计算成本降低。RETRO 使用一种检索机制,允许它实时访问大型数据库,避免模型必须记住所有的训练集。
这具有重要的后果。首先,它证明了新技术可以显著提高语言模型的效率。随着成本变得更可承受,这也有利于较小的公司参与进来。最后,它有助于减少人工智能对环境的影响。
如果你喜欢这篇文章,可以考虑订阅我的免费周报https://mindsoftomorrow.ck.page/!每周都有关于人工智能和技术的新闻、研究和见解!
您也可以使用我的推荐链接 这里 直接支持我的工作,成为中级会员,获得无限权限!:)
2023 年你应该知道的 10 个惊人的机器学习可视化
原文:https://towardsdatascience.com/10-amazing-machine-learning-visualizations-you-should-know-in-2023-528282940582
用较少的代码创建机器学习图的黄砖
戴维·皮斯诺伊在 Unsplash 上的照片
数据可视化在机器学习中起着重要的作用。
机器学习中的数据可视化用例包括:
- 超参数调谐
- 模型性能评估
- 验证模型假设
- 寻找异常值
- 选择最重要的功能
- 识别特征之间的模式和相关性
机器学习中与上述关键事物直接相关的可视化称为 机器学习可视化 。
创建机器学习可视化有时是一个复杂的过程,因为即使用 Python 也需要编写大量代码。但是,由于 Python 的开源 Yellowbrick 库,即使复杂的机器学习可视化也可以用较少的代码创建。该库扩展了 Scikit-learn API,并为视觉诊断提供了 Scikit-learn 没有提供的高级功能。
今天,我将详细讨论以下类型的机器学习可视化,它们的用例以及 Yellowbrick 实现。
**Yellowbrick ML Visualizations
-----------------------------** 01\. [Priniciapal Component Plot](#4662)
02\. [Validation Curve](#7375)
03\. [Learning Curve](#3a38)
04\. [Elbow Plot](#fd50)
05\. [Silhouette Plot](#3848)
06\. [Class Imbalance Plot](#f055)
07\. [Residuals Plot](#a31d)
08\. [Prediction Error Plot](#8e09)
09\. [Cook’s Distance Plot](#e1a7)
10\. [Feature Importances Plot](#9389)
黄砖—快速入门
装置
Yellowbrick 的安装可以通过运行以下命令之一来完成。
- pip 软件包安装程序:
pip install yellowbrick
- 康达包装安装程序:
conda install -c districtdatalabs yellowbrick
使用黄砖
Yellowbrick 可视化工具具有类似 Scikit-learn 的语法。可视化工具是从数据中学习以产生可视化效果的对象。它通常与 Scikit-learn 估计器一起使用。为了训练可视化工具,我们调用它的 fit()方法。
保存情节
为了保存使用 Yellowbrick visualizer 创建的绘图,我们调用 show()方法如下。这将把图保存为磁盘上的 PNG 文件。
visualizer.show(outpath="name_of_the_plot.png")
1.主成分图
使用
主成分图在 2D 或 3D 散点图中可视化高维数据。因此,该图对于识别高维数据中的重要模式极其有用。
黄砖实施
用传统的方法创造这个情节是复杂和费时的。我们需要首先对数据集应用 PCA,然后使用 matplotlib 库来创建散点图。
相反,我们可以使用 Yellowbrick 的 PCA visualizer 类来实现相同的功能。它利用主成分分析方法,减少了数据集的维数,并用 2 或 3 行代码创建了散点图!我们需要做的就是在 PCA()类中指定一些关键字参数。
让我们举个例子来进一步理解这一点。在这里,我们使用乳腺癌数据集(见最后的引文),它有 30 个特征和两个类别的 569 个样本(恶性和良性)。由于数据的高维数(30 个特征),除非我们对数据集应用 PCA,否则不可能在 2D 或 3D 散点图中绘制原始数据。
以下代码解释了我们如何利用 Yellowbrick 的 PCA 可视化工具来创建 30 维数据集的 2D 散点图。
(作者代码)
主成分图——2D(图片由 autr 提供)
我们还可以通过在 PCA()类中设置projection=3
来创建一个 3D 散点图。
(作者代码)
主成分图— 3D (图片由作者提供)
PCA 可视化工具最重要的参数包括:
- 小数位数: bool,默认
True
。这表示数据是否应该缩放。我们应该在运行 PCA 之前缩放数据。点击了解更多关于的信息。 - 投影: int,默认为 2。当
projection=2
出现时,一个 2D 散点图被创建。当projection=3
时,创建一个 3D 散点图。 - **类:**列表,默认
None
。这表示 y 中每个类的类标签。类名将作为图例的标签。
2.验证曲线
使用
验证曲线描绘了单个超参数对训练和验证集的影响。通过查看曲线,我们可以确定模型对于给定超参数的指定值的过拟合、欠拟合和恰到好处的条件。当一次有多个超参数要调整时,不能使用验证曲线。相反,你可以使用网格搜索或随机搜索。
黄砖实施
使用传统方法创建验证曲线既复杂又耗时。相反,我们可以使用 Yellowbrick 的 ValidationCurve 可视化工具。
为了在 Yellowbirck 中绘制验证曲线,我们将使用相同的乳腺癌数据集构建一个随机森林分类器(参见最后的引文)。我们将绘制随机森林模型中 max_depth 超参数的影响。
以下代码解释了我们如何利用 Yellowbrick 的 ValidationCurve 可视化工具,使用 breast_cancer 数据集创建验证曲线。
(作者代码)
验证曲线(图片作者提供)
在最大深度值为 6 之后,模型开始过度拟合。当max_depth=6
时,该模型非常适合训练数据,并且在新的看不见的数据上也推广得很好。
验证曲线可视化工具最重要的参数包括:
- **估计器:**这可以是任何 Scikit-learn ML 模型,如决策树、随机森林、支持向量机等。
- **参数名称:**这是我们想要监控的超参数的名称。
- **参数范围:**这包括参数名称的可能值。
- cv: int,定义交叉验证的折叠数。
- **评分:**字符串,包含模型的评分方法。对于分类,精度优先。
3.学习曲线
使用
学习曲线绘制了训练和验证误差或准确度与时期数或训练实例数的关系。您可能认为学习曲线和验证曲线看起来是一样的,但是迭代次数绘制在学习曲线的 x 轴上,而超参数的值绘制在验证曲线的 x 轴上。
学习曲线的用途包括:
- 学习曲线用于检测模型的欠拟合、过拟合和恰到好处情况。
- 当找到神经网络或 ML 模型的最佳学习速率时,学习曲线用于识别低收敛振荡**振荡发散和适当收敛* 场景。*
- 学习曲线用于查看我们的模型从添加更多训练数据中获益多少。以这种方式使用时,x 轴显示训练实例的数量。
黄砖实施
使用传统方法创建学习曲线既复杂又耗时。相反,我们可以使用 Yellowbrick 的学习曲线可视化工具。
为了在 Yellowbirck 中绘制一条学习曲线,我们将使用相同的乳腺癌数据集构建一个支持向量分类器(参见最后的引文)。
以下代码解释了我们如何利用 Yellowbrick 的 LearningCurve 可视化工具,使用 breast_cancer 数据集创建验证曲线。
(作者代码)
学习曲线(图片作者提供)
该模型不会从添加更多的训练实例中受益。该模型已经用 569 个训练实例进行了训练。在 175 个训练实例之后,验证准确度没有提高。
学习曲线可视化工具最重要的参数包括:
- ***估计器:*这可以是任何 Scikit-learn ML 模型,例如决策树、随机森林、支持向量机等。
- cv: int,定义交叉验证的折叠数。
- ***评分:*字符串,包含模型的评分方法。对于分类,精度优先。
4.肘图
使用
肘图用于选择 K-Means 聚类中的最佳聚类数。该模型最适合折线图中肘形出现的点。肘是图表上的拐点。
黄砖实施
使用传统方法创建弯头图既复杂又耗时。相反,我们可以使用 Yellowbrick 的 KElbowVisualizer。
为了在 Yellowbirck 中绘制学习曲线,我们将使用 iris 数据集构建 K-Means 聚类模型(参见最后的引文)。
下面的代码解释了我们如何利用 Yellowbrick 的 KElbowVisualizer,使用 iris 数据集创建肘图。
(作者代码)
肘情节(图片由作者提供)
**弯头出现在 k=4 处(用虚线标注)。该图表明该模型的最佳聚类数是 4。换句话说,该模型很好地拟合了 4 个聚类。
KElbowVisualizer 最重要的参数包括:
- 估计量: K 均值模型实例
- k: int 或者 tuple。如果是整数,它将计算(2,k)范围内的分类分数。如果是元组,它将计算给定范围内的聚类的分数,例如,(3,11)。
5.轮廓图
使用
侧影图用于选择 K-Means 聚类中的最佳聚类数,也用于检测聚类不平衡。该图提供了比肘图更精确的结果。
黄砖实施
用传统方法创建轮廓图既复杂又耗时。相反,我们可以使用 Yellowbrick 的轮廓可视化工具。
为了在 Yellowbirck 中创建一个剪影图,我们将使用 iris 数据集构建一个 K-Means 聚类模型(参见最后的引文)。
以下代码块解释了我们如何利用 Yellowbrick 的 SilhouetteVisualizer,使用具有不同 k(聚类数)值的 iris 数据集创建轮廓图。
k=2
(作者代码)
具有 2 个聚类(k=2)的轮廓图(图片由作者提供)
通过更改 KMeans()类中的聚类数,我们可以在不同的时间执行上述代码,以创建 k=3、k=4 和 k=5 时的剪影图。
k=3
具有 3 个聚类的轮廓图(k=3) (图片由作者提供)
k=4
具有 4 个聚类(k=4) 的轮廓图,(图片由作者提供)
k=5
具有 4 个聚类的轮廓图(k=5) (图片由作者提供)
轮廓图包含每个簇的一个刀形。每个刀形都是由代表聚类中所有数据点的条形创建的。因此,刀形的宽度代表了集群中所有实例的数量。条形长度表示每个实例的轮廓系数。虚线表示剪影得分—来源: 动手 K-Means 聚类 (我写的)。
具有大致相等宽度的刀形的图告诉我们,聚类是平衡的,并且在每个聚类中具有大致相同的实例数量——这是 K-Means 聚类中最重要的假设之一。
当刀形条延伸到虚线时,聚类被很好地分开,这是 K-Means 聚类的另一个重要假设。
当 k=3 时,团簇很好地平衡并且很好地分离。因此,我们示例中的最佳集群数是 3。
轮廓可视化工具最重要的参数包括:
- 估计器: K 均值模型实例
- 颜色: string,用于每种刀形的颜色集合。“yellowbrick”或 Matplotlib 颜色映射字符串之一,如“Accent”、“Set1”等。
6.阶级不平衡图
使用
类别不平衡图检测分类数据集中目标列中类别的不平衡。
当一个类的实例明显多于另一个类时,就会发生类不平衡。例如,与垃圾邮件检测相关的数据集有 9900 个“非垃圾邮件”类别的实例,而只有 100 个“垃圾邮件”类别的实例。该模型将无法捕获少数类别(垃圾邮件类别)。这样做的结果是,当一个阶层失衡时,模型将无法准确预测少数阶层—来源: 在幕后偷偷发生的 20 大机器学习和深度学习错误 (我写的)。
黄砖实施
用传统方法创建类不平衡图既复杂又耗时。相反,我们可以使用 Yellowbrick 的 ClassBalance 可视化工具。
为了绘制 Yellowbirck 中的等级不平衡图,我们将使用乳腺癌数据集(分类数据集,参见最后的引文)。
以下代码解释了我们如何利用 Yellowbrick 的 ClassBalance 可视化工具,使用 breast_cancer 数据集创建一个类别不平衡图。
(作者代码)
阶层失衡剧情(图片由作者提供)
在恶性类中有 200 多个实例,在良性类中有 350 多个实例。因此,我们在这里看不到太多的类不平衡,尽管实例在两个类中的分布并不均匀。
ClassBalance 可视化工具最重要的参数包括:
- ***标签:*列表,目标列中唯一类的名称。
7.残差图
使用
线性回归中的残差图用于通过分析回归模型中的误差方差来确定残差(观察值-预测值)是否不相关(独立)。
残差图是通过绘制残差和预测值来创建的。如果预测值和残差之间存在任何类型的模式,则表明拟合的回归模型并不完美。如果这些点围绕 x 轴随机分布,回归模型与数据吻合得很好。
黄砖实施
使用传统方法创建残差图既复杂又耗时。相反,我们可以使用 Yellowbrick 的 ResidualsPlot 可视化工具。
为了在 Yellowbirck 中绘制残差图,我们将使用Advertising*(Advertising . CSV,参见最后的引文)数据集。*
以下代码解释了我们如何利用 Yellowbrick 的 ResidualsPlot 可视化工具,使用广告数据集创建残差图。
(作者代码)
残差图(图片由作者提供)
在残差图中,我们可以清楚地看到预测和残差之间的某种非线性模式。拟合的回归模型并不完美,但已经足够好了。
残差图可视化器最重要的参数包括:
- ***估计量:*这可以是任何 Scikit-learn 回归量。
- hist: bool,默认
True
。是否绘制残差直方图,该直方图用于检查另一个假设-残差近似正态分布,平均值为 0,标准偏差固定。
8.预测误差图
使用
线性回归中的预测误差图是一种用于评估回归模型的图形方法。
预测误差图是通过将预测值与实际目标值进行对比来创建的。
如果模型做出非常准确的预测,这些点应该在 45 度线上。否则,这些点会分散在该直线周围。
黄砖实施
用传统方法创建预测误差图既复杂又耗时。相反,我们可以使用 Yellowbrick 的 PredictionError 可视化工具。
为了在 Yellowbirck 中绘制预测误差图,我们将使用广告* ( 广告. csv ,参见引用结尾)数据集。*
以下代码解释了我们如何利用 Yellowbrick 的 PredictionError 可视化工具,使用 Advertising 数据集创建残差图。
(作者代码)
预测误差图(图片由作者提供)
点不完全在 45 度线上,但模型足够好。
PredictionError 可视化工具最重要的参数包括:
- ***估计量:*这可以是任何 Scikit-learn 回归量。
- 身份: bool,默认
True
。是否画 45 度线。
9.库克距离图
使用
库克距离衡量实例对线性回归的影响。具有较大影响的实例被视为异常值。含有大量异常值的数据集不适合未经预处理的线性回归。简单地说,库克距离图用于检测数据集中的异常值。
黄砖实施
用传统方法创建库克距离图既复杂又耗时。相反,我们可以使用 Yellowbrick 的 CooksDistance 可视化工具。
为了在 Yellowbirck 绘制库克距离图,我们将使用广告* ( 广告. csv ,参见引用在最后)数据集。*
以下代码解释了我们如何利用 Yellowbrick 的 CooksDistance 可视化工具,使用广告数据集创建一个 Cook's distance 图。
(作者代码)
库克的距离图(图片由作者提供)
有一些观察延长了阈值(水平红色)线。他们是局外人。所以,我们应该在建立回归模型之前准备好数据。
CooksDistance 可视化工具最重要的参数包括:
- draw_threshold: bool,默认
True
。是否画门槛线。
10.特征重要性图
使用
特征重要度图用于选择产生 ML 模型所需的最少重要特征。由于不是所有的特性都对模型有相同的贡献,我们可以从模型中删除不太重要的特性。这将降低模型的复杂性。简单的模型易于训练和解释。
要素重要度图显示了每个要素的相对重要度。
黄砖实施
使用传统方法创建特征重要性图既复杂又耗时。相反,我们可以使用 Yellowbrick 的 FeatureImportances 可视化工具。
为了在 Yellowbirck 中绘制特征重要性图,我们将使用包含 30 个特征的乳腺癌数据集(见最后的引文)。
以下代码解释了我们如何利用 Yellowbrick 的 FeatureImportances 可视化工具,使用 breast_cancer 数据集创建特征重要度图。
(作者代码)
特征重要性图(图片由作者提供)
并非数据集中的所有 30 个要素都对模型有很大贡献。我们可以从数据集中移除带有小横条的特征,并用所选特征重新装配模型。
FeatureImportances 可视化工具最重要的参数包括:
- ***估计器:*任何支持
feature_importances_
属性或coef_
属性的Scikit-learn 估计器。 - ***相对:*布尔,默认
True
。是否以百分比形式绘制相对重要性。如果False
,显示特征重要性的原始数值分数。 - ***绝对:*布尔,默认
False
。是否通过避免负号只考虑系数的大小。
ML 可视化的使用总结
- 主成分图: PCA() ,用途——在 2D 或 3D 散点图中可视化高维数据,可用于识别高维数据中的重要模式。
- 验证曲线: 验证曲线(),用途——绘制单个超参数对训练和验证集的影响。**
- 学习曲线: LearningCurve() ,用途——检测模型的欠拟合*、过拟合和恰到好处条件,识别低收敛*、振荡、振荡发散、适当收敛
- ****肘图:kelbow visualizer(),用法—选择 K-Means 聚类中的最优聚类数。
- ****Silhouette Plot:Silhouette visualizer(),用法——选择 K-Means 聚类中的最优聚类数,检测 K-Means 聚类中的聚类不平衡。
- 类不平衡图: ClassBalance() ,用法-检测分类数据集中目标列中类的不平衡。
- 残差图: 残差图(),用法-通过分析回归模型中误差的方差,确定残差(观察值-预测值)是否不相关(独立)。
- 预测误差图: PredictionError() ,用法-用于评估回归模型的图形方法。
- 库克距离图: CooksDistance() ,用法-根据实例的库克距离检测数据集中的异常值。
- 特征重要度图: 特征重要度(),用法-根据每个特征的相对重要度选择所需的最少重要特征,以生成一个 ML 模型。
今天的帖子到此结束。
如果您有任何问题或反馈,请告诉我。
阅读下一篇(推荐)
- 黄砖,使用单行代码可视化特性的重要性
**https://rukshanpramoditha.medium.com/yellowbrick-for-visualizing-features-importances-using-a-single-line-of-code-33c87572eada
- 解释验证曲线——绘制单个超参数的影响
- 绘制学习曲线以分析神经网络的训练性能
https://rukshanpramoditha.medium.com/plotting-the-learning-curve-to-analyze-the-training-performance-of-a-neural-network-4a35818d01f2
- 动手 K 均值聚类
https://medium.com/mlearning-ai/k-means-clustering-with-scikit-learn-e2af706450e4
支持我当作家
我希望你喜欢阅读这篇文章。如果你愿意支持我成为一名作家,请考虑 注册会员 以获得无限制的媒体访问权限。它只需要每月 5 美元,我会收到你的会员费的一部分。
https://medium.com/membership/@rukshanpramoditha
非常感谢你一直以来的支持!下一篇文章再见。祝大家学习愉快!
乳腺癌数据集信息
- 引用: Dua,d .和 Graff,C. (2019)。UCI 机器学习知识库[http://archive . ics . UCI . edu/ml]。加州欧文:加州大学信息与计算机科学学院。
- 来源:https://archive . ics . UCI . edu/ml/datasets/breast+cancer+Wisconsin+(诊断)
- 许可: 威廉·h·沃尔伯格(威斯康星大学
普通外科学系)w·尼克街(威斯康星大学
计算机科学系)奥尔维·l·曼加里安(威斯康星大学计算机科学系)持有该数据集的版权。尼克街在知识共享署名 4.0 国际许可(CC BY 4.0)下向公众捐赠了这个数据集。您可以在此了解有关不同数据集许可类型的更多信息。
虹膜数据集信息
- 引用: Dua,d .和 Graff,C. (2019)。UCI 机器学习知识库[http://archive . ics . UCI . edu/ml]。加州欧文:加州大学信息与计算机科学学院。
- 来源:https://archive.ics.uci.edu/ml/datasets/iris
- 许可: R.A. Fisher 拥有该数据集的版权。迈克·马歇尔在知识共享公共领域专用许可 ( CC0 )下向公众捐赠了这个数据集。您可以在此了解有关不同数据集许可类型的更多信息。
广告数据集信息
- 来源:https://www.kaggle.com/datasets/sazid28/advertising.csv
- **许可:**该数据集在知识共享公共领域专用许可 ( CC0 )下公开可用。您可以在此了解有关不同数据集许可类型的更多信息。
参考
- https://www.scikit-yb.org/en/latest/
- https://www.scikit-yb.org/en/latest/quickstart.html
- https://www.scikit-yb.org/en/latest/api/index.html
鲁克山普拉莫迪塔
2022–11–04**
要避免的 10 个可怕的 Python 错误
原文:https://towardsdatascience.com/10-atrocious-python-mistakes-to-avoid-12fb228d60a1
Python 程序员经常犯的一些常见错误,但可能不应该犯
(图片由 Pixabay 上的 Klinkow 提供)
介绍
在我们编程和/或数据科学职业生涯中的某个时刻,我们可能不得不学习一门新语言,并了解它的所有知识。在许多情况下,我们可以用多种方式来解决问题。然而,当谈到编程时,有时有“正确的”方法来处理一些事情,有时有“错误的”方法来处理一些事情。Python 也不例外,如果说有什么事情倾向于仅仅因为它的可访问性而将这些问题变成现实的话;任何说英语的人都可能会假设 Python 中最基本的东西,当有多种更好的方法可供选择时,很容易陷入一种技术来解决问题。
今天,我想看看一些新的 Python 程序员做的一些糟糕的事情,并谈谈为什么有更好的方法来处理和解决他们的 Python 代码中的问题。虽然其中一些不一定是功能性的,这意味着您的代码可能会以两种方式运行,但它们确实提供了更好地了解的好处。此外,他们中的许多人使代码更加简洁,或者有时加快了代码的速度。不管是哪一种情况,编程技能都在不断提高,这些是我的一些建议,它们将改善您的 Python 技能中包含的外观和技术!
№1:将 Python 视为一种完全解释的语言
虽然在一些数据科学场景中,Python 将被更多地解释——例如当我们使用 Jupyter 内核时,许多人可能会惊讶地发现 Python 只是被部分地解释了。语言不仅被解释,而且被编译。在您使用 Python 的经验中,您可能已经注意到。pyc 文件和 Python 文件一起运行。这些文件包含编译后的 Python,信不信由你。
然而,还有另一个重要的区别。通常,编译器将代码放入一个新文件中,该文件模拟汇编中处理器的调用。然而,在 Python 的情况下,编译后的版本是字节码——这意味着它们仍然需要 C 来管理内存并推送到注册表,但是它们不需要在每次运行 Python 代码时都进行解释。请记住,虽然这种区别更多的是一种想法,而不是一个实际问题,但在您按下 return 键后,改变您对 Python 工作方式的看法(至少在一定程度上)是一个好主意。
№2:总是在范围内循环
我认为在线教程的一个问题是在范围内循环,在线教程只是展示一个选择的例子。简而言之,我们对范围的循环太多了。当你来自另一种语言时,这很有意义,因为在其他语言中,我们通常只考虑循环遍历索引,而不是元素。然而,在 Python 中,事实并非如此,最终会比您想象的更多地阻碍您的代码。
相反,您可以直接循环元素,就像这样
x = [5, 10, 15]
for n in x:
pass
范围通常也用于一次获取多个列表的元素,但是如果是这种情况,使用 enumerate()或 zip()可能会更好。有很多方法可以完成这类事情,但是如果你马上索引你的值,迭代枚举的全部意义就是索引你的结构,那么让这些值成为循环不变量就更有意义了。
№3:导入*
我认为网上教程中的一个错误是引入 star 的想法。导入 star 有其使用案例,例如,我认为在笔记本中从 NumPy 导入 star 很有意义,因为如果您正在处理矩阵等,您可能需要 NumPy 中的所有内容。导入 star 的问题是,我们现在从这个模块全局定义名字,用新的定义在运行时环境中乱丢东西,其中大部分我们可能不会使用。
即使这样,您也可以在 Python 中给名称空间起别名,所以如果您想导入整个模块,那么只给模块起别名更有意义。通过别名,您可以将名称空间/模块的调用转换成一两个字母,因此拥有所有这些全局定义的方法、值等就没有什么意义了。那可能最终会打乱你的通话。而是直接导入或者别名如下。
import numpy as np
from numpy.linalg import dot
№4:字符串串联
在 Python 中,字符串连接非常简单,用加法运算符就可以完成。虽然这绝对是一种很好的方法,并且使用这个操作符连接字符串没有任何问题,但是在某些情况下使用 f 字符串可能更有意义。当然,有些时候使用加法运算符更有意义,因为有时您只是连接一个或两个值,例如,如果运算符版本用于类似这样的情况,我不会发疯:
"hi" + "hi"
然而,如果你有很多值,不管什么原因,使用 f 字符串更有意义。这些类型的字符串允许您插入带有某种程度插值的字符串。
f"Hello my name is {name} and I like {food}"
№5:手动关闭文件
新的 Python 程序员犯的一个大错误是以这样的方式处理文件:
file = open("whatever.txt", 'r')
file.write("spaghetti")
file.close()
这种方法的问题是,如果在创建文件对象和关闭文件之间出现任何异常,文件将保持打开状态。相反,使用 with 块是一个更好的主意。这实际上不仅仅是文件的情况,通常是流的情况,尤其是开放这种语法是一个好主意。这是因为每当我们这样做的时候,我们就创建了一个新的范围级别,在这个范围中定义了文件,在语句运行之后,这个范围就被删除了,因此,在那个时刻创建的所有对象都被立即删除了。相反,应该这样编写上面的示例:
with open("whatever.txt", 'r') as file:
file.write("spaghetti")
file.close()
№6:使用裸露例外
另一个新手常犯的错误是在 try/except 块中使用简单的异常。这是一个坏主意的原因是因为这些异常是开放式的。每当一个例外是开放式的,我们就为任何可能出现的例外留有余地。例如,我们可以在块下处理一个中断异常。然后我们的代码无缘无故地运行,因为它被中断了,而不是中断简单地停止我们正在做的事情,它做得更多。相反,您应该在其中插入一个真正的异常。
№7:可变默认值
我经常看到 Python 代码不应该做的事情是为位置参数提供可变的默认值。参数默认值是在定义给定函数时设置的,而不是在运行时设置的。
def hello(x : int, y = []):
这意味着对这个函数的每个调用现在都共享 y,所以如果我们要向 y 追加一些东西,那么我们 hello()函数的每个后续调用都将使用这个 y 作为缺省值,我们将使用一个现在充满值的 y。相反,应该将它设置为 None 作为占位符,然后用一个有条件的。
def hello(X : int, y = None):
if y is None:
y = []
№8:错过理解
理解是完成很多事情的捷径。此外,作用域和类似的东西可以在我们不使用理解的时候打开,这样只会耗尽内存和编译时间。我们可以对列表、字典甚至生成器使用理解。下面是一个简单的列表理解的例子,与迭代的对应部分相比,它节省了时间:
lst = [5 * 5 for _ in range(1, 10)]lst = []
for _ in range(1, 10):
lst.append(5 * 5)
№9:使用==检查类型
在 Python 中可以做的一件愚蠢的事情是用==一前一后地调用 type()方法,以便检查特定对象的类型。首先,在这种情况下使用 is 关键字可能是一个更好的主意,但这可能有问题的另一个原因是 Python 将子类表示为同一个类,所以如果我们问一个命名的元组是否是元组,我们会得到 true——尽管从技术上讲这不是元组。我同意;Python 可以使用某种单一调度系统,它要求参数在提供时是某种类型,而不是在函数的后面,然而,不管我们认为什么可能更好,这仍然是事实。也就是说,在某些情况下,您可能希望像这样检查您的类型,但在大多数情况下,这是绝对应该避免的。
if typeof(x) == tuple:
pass
根据 Liskov 替换原则,子类型应该能够替换其父类型。这种用==检查类型的想法直接违反了这个原则。我不相信所有这些花哨的标签和定义,但肯定有理由认为这是一个坏主意。相反,您可能应该使用 isinstance()方法,该方法能够直接检查给定的 pyobject 是否是构造函数的实例。
if isinstance(x, tuple):
№10:单身人士的平等
我长期以来犯的一个错误是检查平等性而不是同一性。按位相等运算符==,是我们熟悉的东西,而且它很有效,所以很多人最终都这么做是有道理的。但是,如果我们想检查某个东西是真、假还是被定义为无,我们应该使用 is。这是因为 is 和==在语义上是不同的,虽然它们可能都在这些场景中工作,但是一个对另一个的使用对于代码的逻辑是很重要的。
if x is None
结论
Python 是一种很棒的编程语言,但是结合吸收少量代码和简单地不知道任何更好的东西,它确实让你很容易暴露自己没有经验。此外,有些事情你可以继续以更糟糕的方式去做,导致错误,或者在某些情况下是错误的,但在其他情况下不是,即使你已经非常有经验了。
要明确的是,对于其中的一些人来说,犯这些错误并没有什么错。您的代码可能仍然会运行,但您的代码也会脱颖而出。像这样的编程可能会很成问题。感谢您阅读这篇文章,我希望它对您复习 Python 技巧有所帮助,并为您可能偶然学到的东西提供更多的背景知识!
Docker 容器入门的 10 个命令
原文:https://towardsdatascience.com/10-commands-to-get-started-with-docker-containers-deffdcbf90fe
安心构建、交付和部署您的应用
伊恩·泰勒在 Unsplash 上拍照
Docker 是一个很好的工具,可以很容易地开发你的应用程序,将它们装入容器并部署到任何地方。
在我作为一名数据科学家的工作中,每当我需要将一个具有多种底层服务(如后端、数据库、前端等)的应用程序打包成一个我可以运行、更新、停止、共享并明确部署到任何云的映像时,我都会频繁地使用 Docker:IT 界从未见过这样的灵活性。
在这篇文章中,我分享了一些我经常用来操作 Docker 容器的 Docker 命令。虽然这不是对 Docker 的全面介绍,但它至少应该给你一些做大事的基础知识。
👉如果你是一名数据科学家,打算转向生产领域,让自己的应用在本地笔记本之外获得第二次生命,那么学习 Docker 是一个不错的选择。
我希望你都准备好了。让我们开始吧🏊
这篇文章假设读者对 Docker 的基本概念有一点熟悉,比如 Docker 客户端和守护进程、图像、容器、主机、Docker 文件等。如果你不熟悉这些术语,我强烈建议你查看官方文件的概述部分:最多两分钟。
1 —构建 Docker 映像
“一个图像是一个只读模板,带有创建 Docker 容器的指令。通常,一个图像是基于另一个图像的,并有一些额外的定制。例如,您可以构建一个基于
ubuntu
映像的映像,但是安装 Apache web 服务器和您的应用程序,以及运行您的应用程序所需的配置细节。”
—资料来源:Docker docs 。
为了便于学习,我们将构建并使用一个自定义的 Docker 图像,而不是从注册表中提取一个图像(将注册表想象成一个存储 Docker 图像的中心位置,类似于 Github,但用于图像)
这个映像封装了一个 Python 3.7 环境,它拥有在端口 80 上运行 Flask API 所需的一切。
为了构建这个 Docker 映像,我们需要在 Docker 文件中定义一系列指令:本文不会涉及 Docker 文件命令的细节。要了解更多,我建议你查看这个链接。
我们将使用的 docker 文件如下:它基本上是一组连续的指令,包含用户在命令行上调用的所有命令来组合一个图像。
让我们一行一行地理解这个 does 文件的作用:
- 它首先提取一个封装了轻量级 python 3.7 环境的基础映像
- 它设置了 Flask 应用程序将在容器上运行的工作目录
- 它将 requirements.txt 文件从主机复制到容器中(即在工作目录中)
- 它运行
pip
来安装 Python 需求 - 它将当前目录的内容(尤其是
app.py
文件)复制到容器中 - 它表示容器在运行时正在监听网络端口 80
- 当图像运行时,它执行 Python 代码
我们将要运行的 Python 代码是一个简单的 hello-world Flask API,没有什么特别的。
要构建图像并用特定的名称标记它(我选择了flask_image
,运行以下命令:
docker build -t flask_image
一旦构建开始执行,它会检查 over 文件中的每个步骤。
这里肯定有很多内容,所以我将跳过细节,以免你不知所措。不过如果你有兴趣的话,我推荐你查看一下这个 章节 。
作者截图
2 —运行 Docker 容器
容器是图像的可运行实例。您可以使用 Docker API 或 CLI 创建、启动、停止、移动或删除容器。您可以将容器连接到一个或多个网络,为其附加存储,甚至根据其当前状态创建新的映像。”—资料来源:Docker docs 。
一旦构建了 Docker 映像,您可以首先检查它是否存在于您的文件系统中。
作者截图
然后,您可以运行它:这将创建一个容器。如果您再次运行映像,这将创建另一个容器,依此类推。事实上,正如官方文档所指出的,容器只不过是映像 的一个 运行实例。
让我们通过运行我们的映像来运行一个容器:
作者截图
正如所料,这个容器触发一个监听 TCP 端口 80 的 Flask 服务器。
太好了!但是似乎我们不能在不杀死容器的情况下退出控制台。如果我们能在后台运行容器,那就太好了。
3-在后台运行容器
大多数时候,你的容器需要作为服务在后台运行。这可能是一个类似我们正在使用的 API,也可能是一个数据库、代理服务器、React 应用程序等。
你可以这样做:你只需添加-d
(分离的)选项:
docker run -d flask_image
作者截图
要检查容器是否确实在后台运行,可以使用列出正在运行的容器的ps
Docker 命令。
作者截图
现在,容器正在运行并提供一个令人惊叹的 API(我们可以看到端口号被打印到控制台),我们是否可以从外部(即从主机)访问它,并开始向它发送查询?
4 —映射容器和主机之间的端口
为了让主机可以访问我们的 Flask API,我们需要将当前容器的端口(80)映射到主机上的一个可用端口。让我们挑选,说… 1234
语法如下:
docker run -p 1234:80 flask_image
如果我们点击 http://localhost :1234,Chrome 表明这个 API 确实可以从主机访问。
作者截图
如果我们多次点击刷新按钮,我们可以看到容器上的 HTTP 日志。
作者截图
您也可以通过添加-d
选项在后台运行该命令:
docker run -d -p 1234:80 flask_image
现在您已经有了一个可以从容器外部访问的运行 API。
5-停止容器运行
假设您在后台运行一个容器,现在您想停止它。
首先,使用ps
查找它的id
:
作者截图
并在以下命令中使用它:
docker stop 11bca8ee1f8c
作者截图
通过再次运行ps
,容器不再可见。
作者截图
但是,您仍然可以将其视为已停止的容器(以及其他先前已停止的容器):
docker ps -a
作者截图
6-启动停止的容器
给定它的 id,您可以用docker start
启动一个停止的容器
你只需要提供它的 id:
docker start 11bca8ee1f8c
7-移除停止的容器
一旦一个容器被停止,您需要删除它,您首先需要使用docker ps -a
获取它的 id,然后启动一个docker rm
命令。
docker rm 11bca8ee1f8c
8-移除所有停止的容器
现在,如果您需要移除所有停止的容器,并且不想手动执行,您可以使用prune
命令。
docker container prune
9-运行容器,并在它停止后将其移除
如果您想在容器停止后自动移除它,您可以在运行它时使用—rm
选项。
这是一个很好的选项,可以提供清理。
docker run --rm -d -p 1234:80 flask_image
10-重命名容器
如果出于某种原因,您需要重命名您的容器,您可以使用docker rename
命令来完成。
结论
我们只是触及了容器的表面,它们是做什么的,以及如何用简单(并且有用)的命令来使用它们。
然而,由于容器通常只有一个职责,所以它们通常与其他容器组合在一起形成一个完整的堆栈:这是通过 docker-compose 实现的,我们可能会在以后的文章中对此进行研究。
今天就这些了。直到下一次更多的编程技巧和教程。👋
新到中?你可以每月订阅 5 美元,并解锁各种主题的无限文章(技术、设计、创业……)你可以通过点击我的推荐链接来支持我
https://ahmedbesbes.medium.com/membership
照片由卡斯滕·怀恩吉尔特在 Unsplash 上拍摄
初学者和专家的 10 个数据分析工具
原文:https://towardsdatascience.com/10-data-analysis-tools-for-beginners-and-experts-2d083203b06e
为你的事业或职业选择合适工具的指南
米利安·耶西耶在 Unsplash 上拍摄的照片
有许多数据分析工具,每一个都是为特定的用例而设计的。有时,工具会重叠并服务于相同的用例,两者各有利弊。这使得寻找满足您需求的合适工具变得非常困难。
今天,我将向您展示在选择工具时应该注意什么,我将介绍 10 款最优秀、最受初学者和数据科学家欢迎的工具。
如何选择正确的分析工具
选择数据分析工具时,需要考虑几个因素:
- 您的企业拥有什么类型的数据?它们需要特定的分析程序吗?(例如数据建模)
- 我们要处理多大规模的数据?大数据?
- 这项工作的技术性如何?我们面对的是数据科学家还是数据分析师?也许是营销人员和销售人员?
- 你需要任何特定类型的可视化吗?(例如地理热图)
- 你的公司有多少人?预算是多少?
目录
- 最适合存储/编辑数据&创建图形:Excel
- 最适合非技术用户:聚合物搜索
- 最容易建立预测模型:Akkio
- 最适合查询大数据:SQL
- 最适合机器学习&自动化:Python
- 最适合高级统计分析:R
- 最适合科学&学术界:SPSS
- 最佳商业智能&报告:表格
- 商业智能的廉价替代品:Power BI
- 最适合定性数据分析:ATLAS.ti
最适合存储/编辑数据和创建图表:Excel
作者截图
**非常适合:**存储/编辑数据、基本分析、操作数据、图形/图表。
**专长等级:**初级到中级
Excel 和 Google 的工作表 99%相似,所以我把它们都放在这里。Google Sheets 是免费工具,而 Excel 不是。它们做的事情完全一样,所以如果你的工作场所没有 Excel,你可以随时使用谷歌工作表。
Excel 是我快速创建图形和图表的首选工具,因为它们制作方便,并提供多种图表类型:条形图、堆积条形图、簇状条形图、饼图、散点图、盒须图、雷达图——应有尽有!Excel 都有。
您可以快速定制颜色,并为每种图形类型选择多种布局。如果你想在网上发布一幅图像,而又不想让它因为缩小/压缩而变得模糊,调整大小功能也很方便。
Excel 的另一个常见用例是数据操作。使用其广泛的函数和公式,您可以对数据进行几乎任何类型的操作,例如,想看看每一列中的第 5 个字母是否是元音,并输出 TRUE 或 FALSE?使用 Excel 公式很容易做到这一点。
最后,Excel 对于基础分析还是不错的。如果您对数据有某些疑问,您可以通过创建一个数据透视表并添加切片器来过滤数据来轻松回答这些问题。
如果你发现自己每天使用 Excel 几个小时,建议学习 VBA,它是 Excel 的本地编程语言(Visual Basic)。VBA 允许你自动完成任务,这对那些花大量时间在 Excel 上的人来说是有益的。我想说,如果你每天花一个多小时在 Excel 上,这是值得学习的。
Excel 的最大缺点是它不适合更复杂的数据操作(如连接数据集)和分析大数据,因为它有 100 万行的限制。它也不是更高级的统计分析(如回归建模)的最佳工具。
示例使用案例:
**双变量分析:**您有一些结构化数据,并且您想要快速创建一组条形图和散点图,以便对您的数据进行单变量或双变量分析。Excel 在这方面又快又方便,提供了您需要的几乎所有图表类型。
**数据透视表:**您有一些餐馆的销售数据,并且您想要回答一些基本问题,例如“在一天的不同时间,哪种饭菜最受欢迎?”通过在 Excel 中创建数据透视表,您可以轻松快捷地得到答案。
**计算:**您想要对您的数据执行计算。Excel 为您提供了多种方法,例如,您有关于产品销售和评级的电子商务数据,并且想要使用 Wilson 的下限创建一个“加权分数”。即使像这样半复杂的公式也可以在 Excel 中复制。
**数据操作:**你想清理或者操作数据。Excel 有多种方法来编辑数据的某些部分(例如,删除每个单元格中的第 4 到第 6 个字符位置,将一列拆分为多列,使用 if 语句)。
总的来说,每个人都使用 Excel——包括数据科学家,因为它可以方便地执行简单的任务,如图形/图表和数据透视表。它也适合存储/编辑/操作数据。
最适合非技术用户:聚合物搜索
作者截图
**适合:**营销/销售/调查数据、数据演示、商业智能。
**专长等级:**初级
Polymer Search 是一款无代码人工智能工具,旨在分析销售和营销数据。这是最容易学习的数据分析工具之一,比 Excel 简单。
你把你的数据上传到它的网络工具上,它会在几秒钟内把你的数据转换成一个交互式的网络应用。在这里,您可以执行几个分析功能:
1.交互式数据透视表:如果你对数据有某些疑问,你可以使用数据透视表快速得到答案,只需点击几下鼠标,在“智能数据透视表”下选择你的变量。由于一切都是互动的,你不需要浪费时间设置切片器,你可以通过点击标签轻松地过滤输入/输出数据。
2.交互式可视化:为您呈现一些图表类型。主要是条形图、时间序列、散点图、气泡图和热图。这些可用于发现模式、趋势、相关性、数量和其他关于数据的见解。它们还可以用来创建交互式仪表板。由于一切都是交互的,您可以轻松地过滤掉某些数据点(例如,删除异常值或查看没有某些数据点的数据会是什么样子)。
3.Auto-Explainer:允许您生成关于数据的摘要,显示数据中的异常和表现最佳的组合。例如,PPC 营销人员可以选择他们想要最大化的指标(如“转化率”),该工具可以生成影响该指标的因素组合,如受众定位/人口统计、广告创意、竞价策略等。
还有一个人工智能功能,可以提出关于数据的见解。
我非常喜欢 Polymer 的一个特性是它能自动识别数组并自动拆分它们。例如,如果你做了一个调查,并要求人们“选择最多 5 个项目”,在 Excel 中分析这一点可能会很棘手(甚至在 R 中),但 Polymer 会将每个项目检测为独立的,因此分析它变得很简单。如果检测不正确,您可以在列设置中关闭此功能(每个列都有自己的设置)。
Polymer 的最大缺点是它不能处理大数据,并且在进行更高级的分析时灵活性有限。例如,你不能对聚合物进行多元分析。还有数量有限的图形/图表类型。
示例使用案例:
**营销/销售数据:**你正在运行脸书广告或任何类型的 PPC 活动,你想找到表现最好的组合。Polymer 的 Auto-Explainer 工具会自动为您完成这项工作。
如果你想找到合适的目标受众,你只需输入性别、年龄、地点和设备类型,Polymer 就会给出从最佳表现到最差表现的不同结果组合。该报告还显示了任何异常值/异常值,并给出了每个数字的上下文信息(如 X 的表现高于平均水平 56%)。
**商业智能:**您有一个电子表格,您希望将它快速转换成交互式仪表板,用于演示或商业智能目的。Polymer 会自动将您的文件转换为交互式数据库,并让您创建交互式图形/图表,您可以通过 URL 共享这些图形/图表,使主管或客户可以轻松访问。
总的来说,Polymer 是非技术人员创建交互式仪表板、数据透视表和分析营销、销售或调查数据的工具。尽管该工具是为初学者设计的,但我发现它可以做一些非常强大的事情,为我节省了大量的编码时间。
最容易建立预测模型:Akkio
作者截图
**理想适合:**预测分析、销售、营销
**专业水平:**初学者
Akkio 是一个人工智能工具,可以让普通人成为数据科学家。你把数据集上传到 Akkio 上,选择你想要预测的变量,Akkio 就会围绕这个变量建立一个神经网络。不需要编码经验。
Akkio 自动进行 80–20 的训练/测试分割,这意味着您上传的数据的 80%用作训练数据,20%用作验证集。这使得 Akkio 能够确定和显示模型的统计有效性。
我喜欢 Akkio 的一点是,它不只是预测结果。它有一个准确度等级,它认为模型有多准确,并指出假阳性。
同样,只需点击几下鼠标,你就可以将模型部署到 web 应用程序、Zapier 或 API 中。
Akkio 的主要缺点是定价从每月 50 美元开始,并且仅限于表数据。你将无法进行物体检测、图像和音频分类等工作。此外,已经了解 R 或 Python 的人可以创建更好的模型。
示例使用案例:
你经营着一家电子商务商店,想开始向你的商店推荐产品并发送电子邮件简讯。你不是数据科学家,雇一个也太贵了。相反,你可以使用 Akkio 建立模型,根据客户过去的购买行为预测他们可能会购买什么。
总的来说,Akkio 是一个供非技术背景的用户开始预测分析的工具。
最适合查询大数据的:SQL
来源:https://commons . wikimedia . org/wiki/File:SQL _ ANATOMY _ wiki . SVG # File links
**非常适合:**查询和操作大数据。
**专长等级:**中级
SQL 是一种编程语言,主要用于查询和数据操作。
简而言之,SQL 做了 Excel 做的大部分事情,但在处理大数据方面效率要高很多倍。在 Excel 中需要一个多小时的事情,用 SQL 可以在几秒钟内完成。
与 Excel 相比,SQL 允许您轻松地发送更大的文件,因为 Excel 文件可能非常大。SQL 允许你在更小的纯文本文件中存储数据。
当您必须将多个数据集连接在一起时,SQL 也会大放异彩。
SQL 的缺点是学习起来比 Excel 要复杂一些,对于真正基本的任务,它的效率比 Excel 低。
示例使用案例
**大数据操作:**您有非常大的文件(例如,数百万条 Twitter tweets 数据),并且需要清理和编辑这些数据。在 Excel 中这样做是不可能的,但是 SQL 允许您用不到 15 行代码做几乎任何类型的操作。
**将数据集连接在一起:**假设您有 3 个包含 10 列的电子表格文件,您想要将它们连接在一起。你不能把它们垂直复制粘贴到 Excel 中。您需要将它们横向组合成一个包含 30 列的新数据集。在 Excel 中这样做是非常困难和耗时的,所以你需要 SQL 来完成。
机器学习和自动化的最佳选择:Python
Artturi Jalli 在 Unsplash 上拍摄的照片
**非常适合:**机器学习、自动化、应用部署、大数据。
**专长等级:**高级
Python 是一种免费的开源编程语言,在数据分析师和数据科学家中非常流行。你想使用 Python 的三个主要原因是它的高级、快速和包含大量的库。
Python 是一种高级编程语言,内部用 C 语言编写,这意味着您不必处理内存/RAM 的使用,它存储在哪里,以及处理耗时的位和字节。作为一种高级编程语言,Python 是分析数据的理想编程语言。
我喜欢 Python 的一点是它是开源的,并且有很多社区支持。你可以找到各种各样的图书馆,例如,无需自己编码就能找到访问者的位置。目前有超过 200,000 个软件包,用于数据分析的流行软件包包括、Matplotlib 、Plotly 和 Seaborn。
它的主要用例是机器学习、自动化和数据分析。
- 大数据——Python 处理大数据的速度极快
- 即使对于较小的数据集,Python 在执行困难的计算时也非常灵活
- 对于大多数组织来说,Python 可以通过自动化流程节省大量时间,这使得它成为一项非常值得拥有的技能。
因为它是开源的,所以它可以访问数量惊人的库。有超过 200,000 个软件包,最受欢迎的包括 Matplotlib、Plotly 和 Seaborn。
Python 最大的缺点是它不利于移动应用程序,因为没有人为此使用 Python。它也是为更高级的用户设计的,因为你可能需要几个月的时间来学习这个工具。对于基本任务,在 Excel 或其他工具上完成会更有效率。
示例使用案例:
**自动化:**每天你的工作场所会给你 10 个数据集来分析。他们希望你查看数据中的某些变量,为其创建图形/图表,并将其发送到特定的电子邮件。
虽然在 Excel 中可以做到这一点,但每天分析 10 个数据集非常耗时,因为您需要手动分析每个数据集。
使用 Python,您可以通过编写 15 行代码来自动化这一过程,这些代码将分析他们每天发送给您的每个数据集,并将信息发送到这些特定的电子邮件。
**清理数据:**你从网飞搜集了一系列电视节目,包括预告片链接、分级、描述等。你意识到网站上有一些丢失的数据。例如,并不是所有的节目都有预告片。
使用 Python,你可以解决这个问题,首先检测丢失的链接,然后编写一个脚本来检查 IMDb 是否有预告片。如果有,从那里抓取链接。如果没有,就去 Youtube 上看看预告片,然后从那里下载。
探索性数据分析: EDA 可能是一个耗时的过程,但使用Pandas Profiling(Python 中的一个开源模块),您可以在几行代码中生成数据的交互式摘要。这允许您通过可视化数据和查看数据的分布来理解数据。
总的来说,Python 是该领域最常用的语言,由于它是一种高级语言,所以相对容易掌握,这使得它成为数据科学家非常需要的技能。
最适合高级统计分析:R
来源:https://commons . wikimedia . org/wiki/File:r studio _ IDE _ snapshot . png
**理想适用:**高级学术统计分析、机器学习、大数据
**专业知识水平:**高级
R 和 Python 在处理大数据的能力上都极其相似。使用这两种方法中的任何一种,您都可以完成大多数工作,但是当涉及到统计分析过程,尤其是探索性数据分析(EDA)时,R 具有优势。
如果一个工具是通用的,它可以做很多事情(例如,Python 不仅仅是一个数据分析工具,还允许您创建和部署生产级应用程序)。然而,如果一个工具是特定的,它可以做得更好。r 是专门为数据分析设计的,当涉及到非常高级的统计分析(学术水平的东西)时,它可以打败 Python。
此外,在 R 上做一般的分析比 Python 更容易。使用 Python,你需要找到正确的库,弄清楚它是如何工作的,然后编写代码。Matplotlib 缺乏用户直观性,可能会让许多人感到害怕,而 R 的 ggplot2 更容易使用。
但总的来说,他们大多能做同样的事情,大多数人仍然会从 Python 中获益更多。就用例而言,R 和 Python 是相似的,但是用 R 你不能像 Python 一样创建生产级应用,而用 Python,更难做高级的学术数学。
科学和学术界的最佳选择:SPSS
来源:https://upload . wikimedia . org/Wikipedia/commons/7/72/sort column。JPG
理想情况: t 检验、方差分析、方差分析、线性&逻辑回归、聚类分析、置信区间。
**专长等级:**中级
SPSS 主要是一个点击式工具,主要由教育和社会科学专业人士使用。它在政府、市场研究和零售业中也有应用。
我喜欢 SPSS 的一点是,它允许各种测试和多元回归类型,以适应所有类型的数据和场景。SPSS 需要中级的统计学知识来进行更精细的假设检验技术,如 t 检验、MANOVAs 和 ANOVAs。
SPSS 最大的缺点就是 99 美元/月起的价格。
示例使用案例
**采样数据:**你在心理学、社会学或医学领域工作,在那里你正在进行需要采样的科学实验。一个例子是当测试一种药物是否能提高测试分数时——你需要有一个对照组和一个实验组。t 检验允许您根据您设置的 p 值找出这两组在统计上是否不同。
**多变量分析:**多变量分析侧重于同时跨多个变量分析组间差异。举个例子:就像上面这个关于药物是否能提高考试成绩的例子,你也要考虑年龄、性别、种族等等。
总的来说,SPSS 是一个“中级”工具,介于 R、Python 等高级编程语言和 Excel、Polymer Search 等初级工具之间。它的理想受众是希望分析样本数据以发现统计意义的科学专业人士。
最佳商业情报和报告:Tableau
作者截图
**非常适合:**创建交互式仪表盘和图表,基本数据清理。
**专长等级:**初级到中级
Tableau 是创建视觉上吸引人的图形和交互式仪表盘的最佳工具,无需编码。
虽然 R 和 Python 等其他工具更适合分析数据和创建预测模型来推动业务决策,但 Tableau 提供了一种更好的方式来将数据传达给不精通技术的人,并允许他们通过交互式仪表盘监控这些信息。
Tableau 也可以用于分析数据,但它不能很好地处理需要彻底清理的杂乱数据。地址就是一个例子。由于地址有这么多正确格式(不同的信息顺序,缩写和非缩写),在 Tableau 中分析这种格式将是一场噩梦。R & Python 更适合这个。
Tableau 的另一个缺点是它主要针对大型企业。他们的定价从每月 70 美元开始。
示例使用案例:
**演示:**你是一名数据科学家或数据分析师,需要向高管展示一些发现。ggplot/matplotlib 中的可视化效果是静态的,缺乏交互性,也不美观。您需要创建漂亮的、可定制的、交互式的报告,以便团队中的任何人都可以轻松访问。BI 工具允许您创建这些类型的可视化,以及轻松连接多个表的能力,以便更深入地研究数据,并在数据允许的情况下将数据分解到任何级别。Tableau 让您能够以简单的拖放方式完成所有这些工作。
**实时交互式仪表盘:**您想要创建实时交互式仪表盘,但在 Matplotlib/Seaborn/Plotly 中对它们进行编程过于复杂和耗时,而在 r 中则不可能。使用 Tableau,您可以节省数小时的时间,并使它们看起来好 10 倍。
更便宜的解决方案:Power BI
来源:https://commons . wikimedia . org/wiki/File:dado sabertos-ms-PWR bi-demo 02 . png
**非常适合:**创建交互式仪表盘、图表和数据操作。
**专长等级:**初级到中级
Power BI 是 Tableau 的替代产品,提供了比数据可视化更全面的 BI 包。它不需要编程就可以开始,但提供了使用 DAX 语言的选项,对于没有编程知识的人来说,这很容易掌握。
在快速和简单的可视化方面,Tableau 有优势,但使用 Power BI,操纵和清理数据更容易,因为 DAX 是一种强大的编程语言。Power BI 还可以与其他微软产品很好地集成。
Power BI 计划起价为 9.99 美元/月,可以与其他微软产品很好地集成,并提供与 R & Python 的集成以构建模型。
总的来说,虽然这两个工具都适合商业智能,Tableau 在视觉方面提供更多,但 PowerBI 更便宜,更适合处理数据。
最适合定性数据分析:ATLAS.ti
作者截图
**理想适合:**文本挖掘、情感分析
**专业水平:**初级到中级
ATLAS.ti 是一款用于分析定性数据的工具,例如社交媒体上的评论、开放式调查问题和采访。该工具允许非技术用户执行复杂的任务,如情感分析。
其特点包括:
- 词云
- 单词表
- 文本搜索
- 情感分析
- 实体识别
- 通过形容词、名词、连词等过滤。
- 同义词
- 演示功能
Atlas.ti 还支持上传视频和图像进行多模态分析,并能很好地处理地理数据/地图。
缺点是他们的定价从每月 35 美元开始,用于非商业用途,他们的情感分析只支持 4 种语言:英语,德语,西班牙语和葡萄牙语。
示例使用案例:
**非结构化数据:**您录制了一系列面对面的采访,并希望从这些记录中发现真知灼见。你不熟悉 Python,所以你求助于 ATLAS.ti,它允许你在没有任何编码的情况下执行文本挖掘。
**社会科学实验:**你在社会科学领域工作,你进行一些实验,比如让你的参与者在看完一段视频后写下他们的感受并画一幅画,看看这段视频如何影响他们写/画的东西。这通常是一个很难分析的任务,但是 ATLAS.ti 使多模态分析变得简单多了。
结论
选择正确的工具取决于您的组织想要分析的数据类型、您的预算和专业水平。
大多数情况下,最好是在工作中使用多种工具的组合。
例如,数据科学家的堆栈通常包括 Excel/Google Sheets、R/Python 和 Tableau。一个营销人员的堆栈可能涉及 Excel,聚合物搜索和 Akkio。社会科学的人可能会用 Excel,ATLAS.ti,SPSS。
大多数工具都有某种形式的免费试用,所以如果你不确定的话,试一试也无妨。
10 个来自 Kaggle 的数据集,你应该练习一下,以提高你的数据科学技能
原文:https://towardsdatascience.com/10-datasets-from-kaggle-you-should-practice-on-to-improve-your-data-science-skills-6d671996177
通过这 10 个数据集磨练你的技能
来自 Unsplash 的照片由 Arjan van den berg 拍摄
Kaggle 是一个网站,在那里你可以找到解决数据科学问题的比赛。
它是免费加入的,给你机会在不同行业的真实数据集上实践你的技能。
这篇文章将介绍 10 个数据集,它们对你在面试前练习技能很有帮助,或者仅仅因为它们很有趣!
让我们开始吧!
1.泰坦尼克号数据集(初学者)
泰坦尼克号数据集可能是 Kaggle 上最受欢迎的数据集之一。这是一个很好的数据集,因为它有很多变量(13)和记录(超过 1500)。该数据集包含泰坦尼克号上的乘客信息。
该数据集的目标是根据乘客的特征预测他们是否幸存。
例如,基于数据集,你可以看到已婚女性比单身男性存活的概率更高。
数据集中的变量示例如下:
- 年龄
- 性
- 已婚还是单身
- 帆船班(一等、二等、三等)
- 从(伦敦、南安普敦)出发
- 乘客机票号码
有很多关于如何处理这个数据集的教程。如果你在寻找一个挑战,试着预测不同出发点的存活率。
数据集可以从这里下载: 泰坦尼克号数据集
2.虹膜数据集(初学者)
这个数据集是最流行的二元分类问题。这项比赛的目标是预测鸢尾花是否属于两个物种之一(鸢尾,杂色)。
一些例子是鸢尾比杂色鸢尾有更短的花瓣和更宽的萼片。
一个示例预测可能是,如果花瓣长度大于 3 厘米,而萼片小于 6 厘米,则该花更有可能属于鸢尾。
该数据集中的变量示例如下:
- 花瓣长度
- 萼片宽度
- 花瓣宽度
有许多教程来研究这个数据集。其中最受欢迎的一个叫做“在 Iris Flower 数据集上使用 Scikit Learn”。对于初学者来说,这是一个非常好的教程,因为它向您展示了如何使用 scikit learn,它具有预构建的功能,允许您轻松地训练模型。
数据集可以从这里下载: 虹膜数据集
3.训练数据集(初学者)
训练数据集是 Kaggle 上另一个流行的数据集。该数据集包含乘坐美国国家铁路客运公司列车在波斯顿和华盛顿特区之间旅行的乘客的信息
该数据集的目标是预测乘客是否会在某个站点下车。
例如,根据数据集,您可以看到在巴尔的摩下车的乘客比在费城下车的乘客有更高的下车概率。
数据集中的变量示例如下:
- 年龄
- 轨道类型(公路、货运)
- 如果是周末或假日
基于这些变量,有各种方法来预测某人是否会在某一站下车。
数据集可以从这里下载: 训练数据集
4.波士顿住房数据集(初学者)
波士顿住房数据集是 Kaggle 上另一个受欢迎的数据集。该数据集包含波士顿市的住房信息。它有超过 20 万条记录和 18 个变量。
该数据集的目标是预测房价是否昂贵。数据集有三个不同的类(昂贵、普通和廉价)。
您可以看到如下功能示例:
- 卧室数量
- 浴室数量
- 平均房间数
如果您对数据科学领域感兴趣,这个数据集是一个很好的尝试。这并不太难,但仍然非常有趣。
数据集可以从这里下载:波士顿房屋数据集
5.酒精和毒品的关系(中级)
酒精和药物关系数据集是练习数据可视化技能的绝佳数据集。它包含不同药物之间的药物相互作用的信息。
该数据集的目标是根据两种药物的化学结构预测它们是否会相互作用。
例如,数据集表明布洛芬和扑热息痛可能会相互作用,因为它们都是抗炎药(NSAIDs)。
该数据集中的变量示例包括:
- 药物 A 结构(化合物)
- 药物 B 结构(化合物)
- 药物 A 和 B 活性(是/否)
这是一个很好的数据集,可以用来练习您的数据可视化技能。尝试创建一个图表来显示不同药物之间的相互作用。
数据集可以从这里下载: 酒精&药物关系数据集
6.乳腺癌威斯康星(中级)
对于那些在数据科学方面更有经验的人来说,乳腺癌威斯康星州数据集是一个巨大的挑战。该数据集包含威斯康星州乳腺癌患者的相关信息。
该数据集的目标是根据患者的特征预测其是否患有癌症。
比如,你可以从数据集中看到,肿瘤大小小于 0.50 cm 的患者有 98%的生存机会,而肿瘤大小大于或等于 0.80 cm 的患者只有 15%的生存机会。
该数据集中的变量示例如下:
- 肿瘤大小
- 肿瘤分级
- 淋巴结受累
有一些关于如何处理这个数据集的教程。如果你在寻找挑战,试着预测不同肿瘤大小的存活率。
数据集可以从这里下载: 乳腺癌威斯康星数据
7.皮马印第安人糖尿病(中级)
这个数据集是关于预测糖尿病的。这个比赛有超过 150,000 个例子,你需要预测病人是否会发展成糖尿病(二元分类)。
变量非常简单,因为只有一个特性:
- 糖尿病
这个挑战的目标是看你能否预测一个病人是否会在五年内患上糖尿病。这是练习二进制分类问题技巧的好方法。
数据集可以从这里下载: 皮马印第安人数据集
8.亚马逊评论(中级)
亚马逊评论数据集是一个很好的文本分析数据集。它包含对 Amazon.com 产品的评论。
这个数据集很有趣,因为它混合了正面和负面的评论。数据集的目标是预测评论是正面的还是负面的。
变量的例子有:
- 查看文本(字符串)
有很多关于如何处理这个数据集的教程。如果你正在寻找一个挑战,尝试预测情绪分析,然后在此基础上建立自己的模型。
数据集可以从这里下载: 亚马逊点评数据集
9.MNIST 手写数字(高级)
MNIST 数据集是一组手写数字的玩具。它由大小为 28x28 像素的图像组成,具有 60,000 个训练示例和 10000 个测试案例。
这个数据集的目标是正确地对训练集和测试集中的所有数字进行分类。
对于这种类型的问题,你通常会使用卷积神经网络(CNN)。
有很多关于如何处理这类问题的教程,所以我建议你从基础开始,然后学习更高级的方法。
数据集可以从这里下载: MNIST 手写数字
10.CIFAR-100(高级)
CIFAR-100 数据集是练习机器学习技能的绝佳数据集。该数据集包含 100 张物体图像,分为六类:飞机、汽车、猫、鹿、狗和船。
每个图像为 32x32 像素,有三个颜色通道(红、绿、蓝)。
数据的目标是预测每张图片属于六个类别中的哪一个。
该数据集中的变量示例如下:
- 像素
- 红色通道
- 绿色通道
- 蓝色信道
有许多关于如何应对这一挑战的教程。如果你正在寻找一个挑战,试着预测那些以某种方式被扭曲或变形的图像的标签。
数据集可以从这里下载: CIFAR-100
今天就尝试使用 Kaggle
Kaggle 是解决数据科学实践问题的绝佳资源。本文列出的 10 个数据集非常适合磨练你的技能。如果你刚刚开始,试着先做一些简单的数据集。
随着你的进步,转向更难的。经过足够的练习,你将能够解决任何出现在你面前的问题!
与 5k+人一起加入我的邮件列表,免费获得“如何在 2023 年学习数据科学 cheat sheet”
业余分析师和专业分析师的 10 个区别
原文:https://towardsdatascience.com/10-differences-between-amateurs-and-professional-analysts-3a1be1a06a4d
成为“真正的”数据分析师的旅程
亚历山大·辛恩在 Unsplash 上的照片
分析就像写作职业:基础知识很容易入门,是一门艺术,所以进入门槛很低,任何人都可以自称为“作家”。标题中没有质量保证。
然而,有足够的文化来写一些推文并不能让你成为托尼·莫里森或加布里埃尔·加西亚·马尔克斯——最好的作家比初学者超前好几光年。他们的观察很有力量。他们的洞察力改变了世界。
分析也是如此。这个行业的差异是巨大的。另一方面,比如说,统计的准入门槛更高,所以最低水平的统计学家比最低水平的分析师更令人印象深刻……但也有更窄的技能范围。比起统计学家和 ML 工程师,专家分析师给我的印象要深刻得多。
业余分析师和专业分析师之间有很大的不同,在这篇文章中,我将为你总结其中的 10 点。对于每一个,我都有一个更深入的博客帖子,所以请随意跟随链接的线索,找到让你好奇的兔子洞。
专业数据人员与业余数据人员的区别#1 —软件技能
专业分析师努力学习最有效、最快速、最灵活的工作工具,这意味着他们可以快速超越点击式分析界面,学习编码。如果他们想宣称自己是一名专业人士,他们至少在这三种语言中的两种语言上掌握了惊人的技能: R、Python 和 SQL 。 了解更多 。
专业数据与业余数据的区别之二——轻松处理大量数据
“大数据”有多大?这取决于你可以利用的技术——10 年前可能有价值的东西今天已经没有价值了。当你需要额外的工程技能来访问和移动数据时,数据就是“大”的。如果您可以将整个数据集加载到笔记本电脑的内存中,那么它肯定不是“大”的。
照片由兰迪·塔兰皮在 Unsplash 上拍摄
与新手不同,专业分析师不会被数据集的规模吓倒。如果需要额外的工程技能来应对,那就这样吧。你会学到你必须学的东西。因此,专家分析师经常在这个过程中学会数据工程技能。 了解更多 。
专业数据与业余数据的区别#3 —不受数据科学偏见的影响
业余分析师和专家分析师之间的另一个巨大区别是,专家已经形成了对数据的全面不尊重。他们从不把数据以大写字母“D”发音。
“有了数据,你仍然只是另一个有观点的人。”
我最喜欢的统计学先驱之一,W. Edwards Deming ,有一句名言*“没有数据,你只是另一个有观点的人。这是真的,但不幸的是:“有了数据,你仍然只是另一个有观点的人。专家分析家们从骨子里明白这一点。*
我在 LinkedIn 上的一篇帖子的评论中隐藏着一颗宝石。
数据会让毫无戒心的业余爱好者产生虚假的安全感,但专家知道如何避免量化的轻信。要开始建立相同的免疫力,停止将数据视为特殊。 了解更多 。
专业数据与业余数据的区别# 4——了解职业
与业余分析师不同,专业分析师是通过选择 成为 分析师的,而不是因为运气不好。对他们来说,分析本身就是一门优秀的学科,而不是通往其他职业的敲门砖(比如机器学习或统计学)。
图片由作者制作,为我的“数据科学到底是什么?”博文。
专业分析师明白,让你成为分析师的不是你的职位,也不是你使用的工具和技术。让你成为专家分析师的是你在探索和灵感方面的专长——所以这是思考分析职业微妙之处的最佳出发点。 了解更多 。
专业数据与业余数据的区别之五——拒绝成为数据骗子
专业分析师拒绝成为数据骗子:有毒后见之明的兜售者。
数据骗子的第一个警告信号是未能理解分析和统计是非常不同的学科 。不管你的正式职位是什么,没有规定说你不能想学就学,只要你不把它们弄混。为了避免意外成为数据骗子,一次解决一个问题。 了解更多 。
专业数据与业余数据的差异# 6——抵抗确认偏差
确认偏差 意思是我们都可以看着同一个数字,对它有不同的感知。
由 Paul J 提供的确认偏差图解,经允许使用。
换句话说,确认偏差 是数据驱动决策的死对头,因为这意味着一个事实不再仅仅是一个事实,无论你投入多少数学和科学去得到它。它从分析数据中吸取了所有的价值。
如果你渴望成为一名专业分析师,你需要绝地级别的确认偏差解药。这意味着将有意的练习放在磨练防御确认偏差的两个最佳技能上:预注册和面对 脱敏 。 学习如何 。
专业数据与业余数据的差异#7 —对数据的现实预期
如果你是专业分析师,你知道数据不欠你什么。对你的麻烦来说连像样的质量都没有。
对分析师来说,处理别人留下的烂摊子是工作的一大部分。由 Oleksii Hlembotskyi 在 Unsplash 上拍摄的照片
对于分析师来说,坏数据是一个职业现实,很大程度上是因为他们的工作涉及花更多的时间处理二手数据,而不是一手数据。分析师痛苦地意识到,你经常需要从坏数据开始,以找出如何制造更好的数据。要理解这些区别的重要性,并查看帮助分析师处理杂乱数据的技能列表,请点击 了解更多信息。
专业数据与业余数据的区别# 8——知道如何增加价值
如果你是一个决策者的混合体,你的价值由你的决策和行动的质量来判断。你的分析技能是达到这一目的的手段——分析只是你武库中的众多武器之一。
分析师充当决策者的某种感觉器官。照片由 Gerax Sotelo 在 Unsplash 上拍摄
如果你是一个纯粹的分析师,你的价值取决于你为决策者服务的能力。决策者的工作是将信息转化为更好的行动,如果他们不能获得大量信息,这是没有希望的。这就是分析师的用武之地,他们既被动地支持决策者的信息需求(通过查找能够回答他们特定问题的数据),也主动地支持决策者的信息需求(通过探索数据来启发他们考虑新的方向,使他们更具创新性和抵御威胁的能力)。
分析师充当决策者的某种感觉器官。
专家分析师知道,从任何地方开始,除了你的决策者的需求和优先事项,一定会把你引入歧途。 了解更多 。
专业数据与业余数据的区别之九——对时间的不同思考
很少有角色像激光一样专注于时间的投资回报(ROI)。
一个经验丰富的分析师知道他们的工作不是一件有保证结果的确定的事情,而是在灵感、创新和早期威胁检测方面的时间投资。这就是为什么他们会找那些也明白这一点的老板——那些不会因为他们空手而归而惩罚他们的老板。
照片由 MK 汉密尔顿在 Unsplash 上拍摄
如果他们在为一个精明的组织工作,他们的团队相信他们会最大限度地利用分配给他们的时间,所以他们会不断地考虑他们行动的潜在时间 ROI。要了解这如何指导专家分析师的工作方式, 在这里了解更多 。
专业数据与业余数据的差异# 10——对卓越的细微看法
分析游戏就是优化每分钟的灵感。
与业余爱好者不同,专业分析师不认为速度是一个肮脏的词,而是一个微妙的概念,指导他们如何看待自己的工作,如何优先考虑,如何评估业绩,以及如何发展自己的技能。
巴纳巴斯·赫特伦迪在 Unsplash 上拍摄的照片
作为专业分析师,速度也是你技能发展的北极星。诚然,数据格局正在快速变化,因此您不能停滞不前。你今天使用的工具不会持续很久。继续磨爪子,但不要追流行语。
不要再问:“我是不是应该学习所有酷小孩都在谈论的这个工具/方法/技术?” 开始提问:“学这个会让我更快吗?”
学习任何能让你更快的东西(用所有重要的方式)。既然你的工作包括加速别人,那就从加速自己开始吧。 了解更多 。
熟能生巧!
如果你只是想稍微了解一下分析,那就去看看一些数据吧。不要等待特别许可。你不需要任何花哨的训练。跳过这些课程和书籍,如果你还不是专家也不要担心…开始吧!一旦看数据开始变得有趣,你就可以称自己为分析师了。
但是如果你渴望成为专家,我有个坏消息要告诉你。虽然我希望你能探索我的分析迷你课程,但我(或其他任何人)教你的东西都不会让你精通。阅读分析可以帮助你调整心态和态度,但是精通需要天赋和实践。很多很多很多的练习。
http://bit.ly/quaesita_sminianalytics
如果你渴望用一些核心概念和对分析职业的思考来补充你的实践课程,请参加我的迷你分析课程。
哦,如果你在这里玩得开心,看看如果你不止一次点击拍手按钮会发生什么。
你应该知道的 10 个基本的 Julia 数组方法
原文:https://towardsdatascience.com/10-essential-julia-array-methods-you-should-know-bedb07b5488a
用这十个你可以使用的好方法把你的阵列带到一个新的水平
(图片由 Pixabay 上的 Boskampi 提供)
介绍
Julia 编程语言是一种非常著名的面向科学计算的语言。虽然这种语言肯定是一种具有许多不同功能的通用语言,但它令人惊叹的数字能力无疑是人们关注的焦点。在很多方面,Julia 在处理数组和矩阵数据的能力上就像一个高级 FORTRAN。
在数据科学领域,伟大的数值方法和快速计算肯定会在做任何事情时派上用场。也就是说,学习 Julia 中数组的来龙去脉,以及分派给数组的方法可能是个好主意。今天我想回顾一下在 Julia 中使用传统的一维数值数组的一些最基本的方法。我认为这是在 Julia 身上学到的最有价值的东西之一,因为它经常被用于科学,在科学中,我们的阵列变成了我们的特征,我们的元素变成了我们的观察。关于科学等价性的另一个注意事项是,在 Julia 中,“Vector”这个名字只是一个数组的别名,所以如果我或者代码,比如说 Vector,记住它的基本意思是数组。最后一件事,如果您想亲自尝试一下这段代码,看看它在笔记本上是什么样子,这里有一个我在本文中使用的笔记本的链接:
https://github.com/emmettgb/Emmetts-DS-NoteBooks/blob/master/Julia/10%20Julia%20array%20methods.ipynb
№1:推!()
我想说的第一个方法是推!方法。如其名称结尾的解释点所示,push!是一种会改变我们血型的功能。用力!只是用来将元素移动到几乎任何可迭代的对象中…这实际上是另一件需要注意的事情——由于多重分派,这些方法并不总是只适用于数组。用力!可以用在许多其他类型的收藏上,甚至那些不是来自 Base 的库中的收藏。再者,你甚至可以自己写推送!,我在一篇完整的文章中谈到了推送!。如果你想更多地了解这种方法,以及它的用途,你可以在这里阅读我写的关于它的文章:
使用 push!非常简单,我们将从定义要推送的数组开始!收件人:
x = [5, 10, 15, 20, 25, 30, 35, 40, 45]
我们现在可以叫推了!方法,首先提供我们想要推送的 iterable,然后是我们想要推送的 item:
push!(x, 50)
10-element Vector{Int64}:
5
10
15
20
25
30
35
40
45
50
需要注意的一点是,我们的 x 数组是一个向量。每当我们构造这种类型时,括号中的类型 Int64 作为 T 从内部构造函数提供给外部构造函数。如果我刚才说的没有任何意义,不要担心——因为这里有一篇文章解释了我刚才到底说了什么!:
无论如何,因为这个类型,我们称之为 T(可能在代码中就是这么叫的),是 Int64,我们只能把整数压入它。例如,字符串会导致类型字符串不能转换为 Int64:
push!(x, "hi")
MethodError: Cannot `convert` an object of type String to an object of type Int64
有两种方法可以解决这样的问题…
- 编写一个新的 convert()方法,将字符串转换为整数。
- 把 T 的类型改成 any,那么这个数组的类型可以是任意的。
对于这样的东西,最好的选择当然是第二种。在大多数情况下,这可能是你要做的选择,我们可以用一个简单的造型来做到这一点。
xany = Vector{Any}(x)
注意,虽然我可能说了 cast,但我们实际上是在这里调用一个构造函数。这是有区别的,因为转换/转换是通过方法完成的,而构造当然是通过构造函数完成的。
push!(xany, "hi")
11-element Vector{Any}:
5
10
15
20
25
30
35
40
45
50
"hi"
№2:滤镜!()
另一个不合理的有用的方法是过滤器!()方法。这也是一种在 Julia 生态系统中随处可见的方法,那些在数据科学领域工作的人可能需要格外关注,因为这种方法经常被用作我们的条件屏蔽。该函数将根据函数的假返回值过滤值。这个函数当然可以是我们环境中的一个定义好的别名,但是它也可以是匿名的,甚至是一个闭包函数。由于在 Julia 中函数被视为与类型相同,并且该语言是词汇范围的,这使得像这样使用函数的调用非常容易应用于许多不同的场景。用法很简单,我将使用一个匿名函数,如果你想了解更多,我也有一篇文章:
filter!(z -> z < 40, x)
7-element Vector{Int64}:
5
10
15
20
25
30
35
我希望 Base 中包含的一件事是 BitArray 能够做到这一点。我创建的 OddFrames 包实际上解决了这个问题,但是使 BitArray 索引成为类型间的通用特性。这样,您可以使用条件语句快速索引任何内容,而无需使用函数。也就是说,Julia 的优点在于,即使该方法的默认系统不符合我们的需求,比如用一个位数组屏蔽,我们也可以自己编写这样的代码!为此,我们还将方便地使用这个列表中的下两个函数,findall()和 deleteat!():
import Base: filter!function filter!(mask::BitArray, x::AbstractVector)
pos = findall(x -> x == 0, mask)
[deleteat!(x, p) for p in pos]
end
请注意,由于我们将 mask 分派给 bitarray,我们还需要将下面的数组转换为 vector,否则我们将得到“bool is not callable”,这是因为我们仍在使用常规过滤器!()方法,并试图将其作为函数调用。我们也可以将这种类型作为 Vector来避免这种类型转换(不过,我们还是像以前一样构造了一个类型,只是在精神上可以认为这是一种类型转换,我只是想详细说明一下。)
mask = BitArray([typeof(z) == Int64 for z in xany])
11-element BitVector:
1
1
1
1
1
1
1
1
1
1
0filter!(mask, xany)
1-element Vector{Vector{Any}}: [5, 10, 15, 20, 25, 30, 35, 40, 45, 50]
美味的肉汁…朱莉娅是个很酷的人。
注意,返回并不重要,它只是 for 循环的产物——我们可以不返回任何东西来抑制这个输出,因为我们的数组已经在函数内部变异了。
print(xany)
Any[5, 10, 15, 20, 25, 30, 35, 40, 45, 50]
№3:删除 at!()
下一个方法非常简单。删除 at!()方法允许我们通过索引删除数组中的一个元素。在前面的例子中,我们使用了 deleteat!()删除数组中每个有错误的位置。在我们的 x 数组的例子中,我将用它来删除我们的第一个索引,它将是 5。
deleteat!(x, 1)
6-element Vector{Int64}:
10
15
20
25
30
35
№4:查找所有()
findall()方法是另一个我一直在使用的非常好的方法,这也是为什么在上面使用它的原因。这个函数是我们列表中的第一个非突变函数,也是第一个返回非原始向量的函数。方法收集特定值的所有实例,然后返回找到这些值的索引数组。例如,我们可以对 x 上的数字 10 使用 findall(),因为它只有一个 10,现在在位置 1,我们将获得包含该位置的 1 元素数组。返回的类型总是 array,所以如果你的值是一个集合(不是按类型,而是按定义),那么你可以总是在第一个元素索引新的数组,以获得奇异位置。
findall(y -> y == 10, x)[1]1
使用这个,我们最终可以做三倍的工作来得到第一个元素的索引。
x[findall(y -> y == 10, x)[1]]10
我很搞笑。
№5: vcat/hcat
接下来要知道的方法分别是 vcat()和 hcat()方法。您可能已经猜到了,这些是用于数组的垂直和水平连接的。这些方法也可以用来将一维数组转化为多维数组。如果数组水平连接,这将把类型变为矩阵。在垂直连接的情况下,这基本上就像我们将每个值推入数组。
x3 = vcat(x, x, x)
18-element Vector{Int64}:
10
15
20
25
30
35
10
15
20
25
30
35
10
15
20
25
30
35
hcat 将创建一个矩阵:
xh = hcat(x, x, x)
6×3 Matrix{Int64}:
10 10 10
15 15 15
20 20 20
25 25 25
30 30 30
35 35 35
№6: .*, .+, …
接下来的清单上几乎所有的。运营商,其中有很多。基本上所有这些都只是常规操作符的迭代版本。虽然它们并不存在于每一个操作符绑定中,但是它们确实存在,并且比打开一个完整的循环来给数组中的每一个元素加一个数要方便和漂亮得多。这不仅适用于按位运算符,也适用于一元运算符。
x .== x
6-element BitVector:
1
1
1
1
1
1x .^ 26-element Vector{Int64}:
100
225
400
625
900
1225.- x6-element Vector{Int64}:
-10
-15
-20
-25
-30
-35
№7:插入!()
我们要看的下一个函数是 insert!()函数。正如您所料,这将给定的值插入到数组中。方法推的区别!()和 insert()方法的区别在于,insert 允许您指定要推进到的索引。如果在某个时候需要添加数据,或者特别是希望在不改变任何其他索引的情况下改变元素,这是非常方便的。这个函数也很容易使用,并且只接受三个位置参数。
insert!(x, 1, 5)7-element Vector{Int64}:
5
10
15
20
25
30
35
根据我的经验,这种方法非常有用,但是在很多情况下,对于稍微改变的算法,我们可以切换到另一种类似的方法,splice!()
№8:拼接!()
拼接!方法很像 insert!方法,然而在插入时!将保留我们正在更改的索引周围的值,拼接!不会。拼接!函数也有更多的细节要处理,因为我们可以拼接!一次输入几个值。同样,我们可以一次选择多个索引——这种方法非常方便,使得可变数组成为可能并且易于使用。
splice!(x, 1:5, [50, 45, 40, 35, 30])7-element Vector{Int64}:
50
45
40
35
30
30
35
№9:累加()
累积值可能是一件有点烦人的事情。虽然由于我们周围的基本函数,我们经常不需要使用累加器,但它们对于某些算法仍然非常有用。也就是说,这个列表中的下一个函数是 accumulate()函数。这将返回一个与我们提供的数组维数完全相同的数组。然而,这些元素将被操作成它之前的每个元素的累积。也就是说,新累积数组中的最终值将是整个数组的总和。最棒的是,我们可以用 Julia 的大多数操作符做到这一点,所以我们可以做一个累加器,它可以进行乘法、减法、平方等运算。
accumulate(*, x)7-element Vector{Int64}:
50
2250
90000
3150000
94500000
2835000000
99225000000accumulate(+, x)[length(x)] == sum(x)true
№10:地图切片()
我想看的最后一个方法是 mapslices()。我们可能都习惯于 map()函数,但是 mapslices 的工作方式与该函数略有不同。这个函数只允许你把一个给定的函数映射到整个数组,但是只接收返回的某些值,例如,如果我们想以一种奇怪的方式对某个东西求和:
mapslices(sum, x, dims = [1])
结论
数组不仅是 Julia 编程语言的一个非常重要的方面,也是整个科学计算的一个非常重要的方面。Julia 有一个相当健壮的处理数组的接口,包括一维数组和其他数组,所以在使用这种语言时利用它是一个很好的主意。这些简单的方法可能看起来不会改变生活,但它们肯定是必不可少的、令人敬畏的和有用的。感谢您阅读我的文章,我希望这篇关于 Julia 中奇妙的 vector 实现的简短旅程是一篇很棒的阅读!
掌握 ggplot2 的 10 个示例:线形图
原文:https://towardsdatascience.com/10-examples-to-master-ggplot2-line-plots-3e43e9aec8f
R 的绘图包
约翰尼斯·安德森在 Unsplash 上拍摄的照片
你如何传递信息和信息本身一样重要。数据可视化是数据科学中传递信息、讲故事或分析的必要工具。
数据科学生态系统中最大的两个参与者是 Python 和 r。它们都有大量的包来加速和简化常见的任务。
在本文中,我们将通过 10 个示例来学习如何使用 ggplot2 创建和定制线图,gg plot 2 是 tidyverse 中的一个数据可视化包,它是数据科学的 R 包集合。
你可以成为 媒介会员 解锁我的全部写作权限,外加其余媒介。如果你已经是了,别忘了订阅https://sonery.medium.com/subscribe如果你想在我发表新文章时收到电子邮件。
我们将在示例中使用 3 个不同的数据集。你可以从我的 GitHub 页面上的数据集库中下载它们。
第一个是包含 2022 年苹果股票价格的 CSV 文件。我们先用数据表包的 fread 函数创建一个数据表。
*library(data.table)
library(ggplot2)apple <- fread("datasets/apple_stock_prices_2022.csv")head(apple)
**# output** Date High Low Open Close Volume Adj Close
1: 2022-01-03 182.88 177.71 177.83 182.01 104487900 181.2599
2: 2022-01-04 182.94 179.12 182.63 179.70 99310400 178.9595
3: 2022-01-05 180.17 174.64 179.61 174.92 94537600 174.1992
4: 2022-01-06 175.30 171.64 172.70 172.00 96904000 171.2912
5: 2022-01-07 174.14 171.03 172.89 172.17 86709100 171.4605
6: 2022-01-10 172.50 168.17 169.08 172.19 106765600 171.4804*
示例 1
我们将创建一个简单的线图,在 x 轴上显示数据,在 y 轴上显示收盘价。
*ggplot(apple, aes(x = Date, y = Close)) +
geom_line()*
ggplot 函数指定数据以及到 x 和 y 的映射。aes 代表美学映射,描述数据中的变量如何映射到 geom 的视觉属性(例如 geom_line)。
geom_line 是绘制线图的函数。以下是上述代码片段的输出:
(图片由作者提供)
例二
我们可以在外观上做很多定制。让我们改变线条的大小和颜色,这可以在 geom_line 函数中完成。
*ggplot(apple, aes(x = Date, y = Close)) +
geom_line(size = 1.2, color = "blue")*
(图片由作者提供)
我们也可以使用 linestyle 参数(linestyle = "dashed ")将其设为虚线。
示例 3
y 轴上的范围根据数据集中的值自动定义。但是,可以使用 ylim 函数对其进行更改。
默认值通常是好的,但我们有时需要调整它们,以保持多个图之间的标准或有一个从零开始的轴。让我们将范围设置为 100–200。
*ggplot(apple, aes(x = Date, y = Close)) +
geom_line(color = "darkgreen") +
ylim(100, 200)*
(图片由作者提供)
实例 4
我们可以添加点来指示数据点的位置。当我们没有很多数据点时(即观察的密度很低),这是很有帮助的。
在本例中,我们将使用测量数据集。
*measurements <- fread("datasets/measurements.csv")measurements
**# output**
day value
1: 1 80
2: 2 93
3: 3 94
4: 4 76
5: 5 63
6: 6 64
7: 8 85
8: 9 64
9: 10 95*
让我们创建一个线图,在 x 轴上显示日期,在 y 轴上显示数值。我们还将使用 geom_point 函数添加点。
*ggplot(measurements, aes(x = day, y = value)) +
geom_line() +
geom_point()*
(图片由作者提供)
这些点被放置在我们在数据集中进行观察的位置。例如,数据集没有第 7 天,所以不显示。
实例 5
在前面的例子中,观察值的 x 值不是很清楚。为了在 x 轴上显示每一天的值,我们可以将其转换为一个因子,并使用 ggplot 函数的 group 参数。
*measurements[, day := factor(day)]ggplot(measurements, aes(x = day, y = value, group = 1)) +
geom_line() +
geom_point()*
(图片由作者提供)
实例 6
我们可以在一个线图上有多条线。对于这个例子,我们将使用另一个数据集,它包含 2022 年 9 月苹果和谷歌的股票价格。
*stock <- fread("datasets/apple_google_stock_prices_092022.csv")head(stock)
**# output** Date High Low Open Close Volume Adj Close Stock
1: 2022-09-01 158.42 154.67 156.64 157.96 74229900 157.96 AAPL
2: 2022-09-02 160.36 154.97 159.75 155.81 76905200 155.81 AAPL
3: 2022-09-06 157.09 153.69 156.47 154.53 73714800 154.53 AAPL
4: 2022-09-07 156.67 153.61 154.82 155.96 87449600 155.96 AAPL
5: 2022-09-08 156.36 152.68 154.64 154.46 84923800 154.46 AAPL
6: 2022-09-09 157.82 154.75 155.47 157.37 68028800 157.37 AAPL*
股票栏表示股票的名称。
对于每一天,我们有两个不同的值,一个是苹果的,一个是谷歌的。因此,如果我们像前面一样绘制日期和收盘价,我们最终会得到如下图:
(图片由作者提供)
我们需要用不同的线条显示苹果和谷歌的股票价值。做这件事有几种不同的方法。例如,我们可以使用颜色参数并指定区分苹果和谷歌的列。
*ggplot(stock, aes(x = Date, y = Close, colour = Stock)) +
geom_line()*
(图片由作者提供)
例 7
让我们重新创建以前的情节,但对苹果和谷歌使用不同的线条样式。我们只需要使用线型参数,而不是颜色。
*ggplot(stock, aes(x = Date, y = Close, linetype = Stock)) +
geom_line(size = 1.2)*
(图片由作者提供)
实施例 8
在示例 4 和 5 中,我们添加了点来标记数据集中的观察值。这些点的大小和形状也可以定制。
让我们在示例 7 的图中添加点,并更改 y 轴的取值范围。
*ggplot(stock, aes(x = Date, y = Close, color = Stock)) +
geom_line() +
geom_point(size = 3, shape = 22, fill = "white") +
ylim(90, 200)*
(图片由作者提供)
示例 9
我们可能想要更改默认的轴标签或给绘图添加标题。让我们通过这样做使我们的情节更有知识性和吸引力。
labs 功能可用于添加标题和副标题。可以使用 xlab 和 ylab 函数更改轴标签。
*ggplot(stock, aes(x = Date, y = Close, color = Stock)) +
geom_line(size = 1) +
labs(title = "Apple vs Google Stock Prices",
subtitle = "September, 2022") +
xlab("") +
ylab("Closing Price")*
(图片由作者提供)
实例 10
我们可以为情节添加一个主题,这允许进行许多自定义,包括:
- 更改标题和副标题的字体大小和样式
- 更改轴标签的字体大小和样式
- 更改刻度线的字体大小、样式和方向
让我们使用这些来定制前一个例子中的情节。
*ggplot(stock, aes(x = Date, y = Close, color = Stock)) +
geom_line(size = 1) +
labs(title = "Apple vs Google Stock Prices",
subtitle = "September, 2022") +
xlab("") +
ylab("Closing Price") +
theme(
plot.title = element_text(size = 18, face = "bold.italic"),
plot.subtitle = element_text(size = 16, face = "bold.italic"),
axis.title.y = element_text(size = 14, face = "bold"),
axis.text.x = element_text(size = 12),
axis.text.y = element_text(size = 12)
)*
(图片由作者提供)
Ggplot2 是一个高效的库,提供了很大的灵活性。我认为它与 Matplotlib 相似,我们可以在图上定制几乎任何东西。
本文中的示例涵盖了创建和定制线图所需的大部分内容。在一些边缘情况下,您需要做一些进一步的定制,但是到了那个时候,您可以担心它们。
感谢您的阅读。如果您有任何反馈,请告诉我。
10 本关于数据工程的精彩书籍
原文:https://towardsdatascience.com/10-fantastic-classic-books-for-data-engineering-84de7fb7e061
让你成为成功数据工程师的 10 本必读书籍
艺术之星在 Unsplash 上拍摄的照片
数据工程十大奇书介绍
许多在线免费资源教你如何成为一名数据工程师,但是这些在线资源的深度是有限的。阅读领域专家的书籍是获得这种深入知识的更有前途的方法。
2023 年数据工程读什么书,你在找建议吗?我有一个答案给你。作为一名成功的数据工程师,我为你列出了十本经典书籍。
在2021 年数据/AI 薪资调查、 Python 和 SQL 是最基础的技术技能。要想成功,你至少要精通这两种语言。我推荐了两本中级水平的书来扩展你的 Python 和 SQL 知识。
但是,认识那两个大概也只是敲开了做数据工程师的门。许多公司希望你有使用 Apache Spark 等批处理系统、Apache Flink 或 Apache Beam 等流系统以及 Apache Airflow 和 Kubernetes 等工作流编排工具的经验。我对每一个议题都有四点建议。
数据工程师需要设计原则才能在职业生涯中更上一层楼。总的来说,关于分布式系统和维度建模(OLAP),我强烈推荐两本书给你,让你对这些主题有更多的了解。
最后,数据工程将获得更多的奖金,拥有一些数据分析技能以及数据沟通技能。我找到了另外两本书,它们会提高你的技能。
先说我推荐的十本数据工程经典书籍:
1.关于分布式系统的主要书籍:设计数据密集型应用
我的短评:如果我有一本书可以推荐的话,这是我的首选。这本书涉及广泛的主题,有许多参考资料。你可以用这本书作为目录,从引用的内容中积累深入的知识。
这本书将众多与数据相关的技术与三个主要部分结合在一起:可靠性、可伸缩性和可维护性。这本书涵盖了分布式系统如何广泛地工作。马丁在这本书里真的很博学,分享了他的经验,他引用了很多书和论文供进一步阅读。这些书籍和论文可以成为数据和软件工程师的另一份权威清单。从他的书中,这里有一些突出的主题:
- 你会学到一个类似于“如何设计 Twitter 的经典系统设计面试问题?”。
- 如果数据不适合单台机器,如何横向扩展数据?领导者和追随者如何确保高可用性?
- 明确的酸解释(原子性、一致性、隔离性、持久性)。
- 更好地理解最少一次、最多一次和恰好一次语义在流应用程序中至关重要。
唯一的缺点是,自从这本书于 2017 年 3 月出版以来,随着许多新技术的发展,一些图书馆已经褪色,少数内容不再新鲜。然而,数据系统设计的核心概念在 2022 年的今天仍然适用。任何数据系统都需要达到**可靠性、可伸缩性和可维护性的原则。**通常也是买来作为学习系统设计的参考书。如果你正在寻找一本更新鲜的书来学习系统设计或去面试,我也推荐两本来自 Alex Xu 的书:
- 系统设计面试—内部人员指南
- 系统设计访谈—内部人员指南:第 2 卷
2.SQL 基础书: T-SQL 查询(开发者参考)
我的短评 : Ben-Gan 从 ANSI/ISO 标准的角度解释了 SQL,并教你从过程化编程的心态去思考。读了他的书后,作为一名数据工程师,编写复杂的查询和调试任何与 SQL 查询相关的问题变得容易了。
Ben-Gan 之前写过一些关于写 T-SQL 的经典书籍。这总结了他在教导人们如何先思考,然后编写 SQL 查询方面的最新专业知识。不要跳过这本书,即使 T-SQL 不是你的主要 SQL 语言。这本书的核心思想不是教你 SQL 的奇特语法;相反,它很好地解释了如何从过程化编程的角度思考 SQL。理解了核心概念后,您会对编写 SQL 逻辑感到更加舒适。此外,您成为了调试 SQL 语句的专家,因为您知道它在内部是如何工作的。书中的材料为你奠定了坚实的基础,使你成为编写 SQL 的专家,而这是数据工程师必须具备的。
3.OLAP/数据仓库必读:数据仓库工具包(维度建模权威指南,第 3 版)
我的短评:一本定义维度建模/ OLAP 系统的经典书籍。作为一名数据工程师,维度建模和 OLAP 是需要大量工作才能理解的主题。理解它们可以让你的日常工作顺利进行,并让你有更大的机会在数据仓库主题的面试中表现出色。
这本书没有制作虚假的模式,而是在每一章中利用了不同的行业,并展示了不同的数据模型作为例子。它没有马上进入设计模式的技术部分。这本书首先提出了一些问题,比如为什么你需要一个数据仓库,以及如何与最终用户合作来交付一个最终会成功的模型。这本书教你使用“企业数据仓库总线矩阵”来弥合技术设计差距和用例。然后,它涵盖了维度建模的四个关键步骤,并为本书的其余部分奠定了基础。
作为一名数据工程师,您需要构建一个 ETL 管道,并以分析格式存储数据。维度建模还没有过时。许多行业仍然大量使用它来开发他们的 OLAP 系统。
4.Python 深度:流畅的 Python:清晰、简洁、有效的编程第二版
我的短评:深入了解 Python。这些书展示了如何作为开发人员编写有效的 Python,并探索了 Python 的独特特性以及它们与其他语言的不同之处。它揭示了 Python 在幕后是如何工作的,这使得这本书成为提高您的 Python 技能的绝佳选择。
这本书无疑不是 Python 101 的书。它要求您对 Python 有中级水平的理解。它的目标读者是那些能够编写 Python 但不知道自己是否编写了有效的 Python 代码或遵循 Python 模式的人。这些中级和高级知识是许多数据工程师错过的空白。
Python 使得给每个用户一条快乐的上船之路变得简单。但是,有效地编写 Python 来利用它的最佳特性只是在某些时候。Python 作为数据工程师和您的首选编程语言已经被广泛采用。这本书可以真正让你重新思考用 Python 写代码。
5.向创造者学习: Spark:权威指南:让大数据处理变得简单
我的短评:向 Matei Zaharia(Apache Spark 的创造者)学习 Spark 让这本书成为一种独特的阅读体验。
在那个年代,Apache Spark 及其生态系统对于任何数据工程师来说都不应该是陌生的。这本书带给你一个 Apache Spark 的创造者视角。它回顾了 Spark 的历史,并深入探讨了 Scala 和 Python 中的 RDD 和 DataFrame API。它更详细地介绍了 Spark 生态系统,比如批处理、流、ML 和 Graph,还重点介绍了部署和 Spark 作业调优。
虽然 Spark 3.0 已经发布,但核心概念变化不大。这本权威性的指南仍然是获得更深刻的 Apache Spark 知识的理想选择。
6.工作流管理工具:带有 Apache Airflow 的数据管道
我的短评:Apache Airflow 的分步指南,从创建简单的 DAG 到将 air flow 部署到生产环境。
Apache Airflow 正在成为工作流管理的首选开源包。这本书给人的第一感觉就像是 Apache Airflow 在线文档的增强版。但是很快,你就会意识到作者从部署气流的工业经验中增加了更多的内容。主要是在某些情况下气流设计不正确的地方,它会显示关于如何解决它们的合理提示。
气流有特定的用例,而不是像流数据这样的用例。也需要一些人去理解它的核心概念。我有一些关于气流的博客帖子,在社区中很受欢迎,也可以随意阅读:
- 气流状态 101 概述阿帕奇气流状态
- 了解气流执行器的温和介绍
- 气流计划间隔 101
7.关于串流基础,你需要知道的一切:串流系统:大规模数据处理的内容、地点、时间和方式
我的短评:阅读构建了最初的谷歌流媒体系统 Millwheel 的谷歌工程师,在本书中系统地阐述他的论文和流媒体的概念。这本书是流媒体的首选书籍。它为现代流行的流媒体系统如 Beam、Flink 和 Spark 流媒体奠定了基础。
作为一名数据工程师,除了传统的批量数据处理之外,随着人们越来越渴望更快地获得数据,流式系统变得越来越普遍。流式系统始终如一地全天候处理数据。早期做得最好的公司是谷歌。
谷歌已经建立了一个名为 Millwheel 的内部流媒体系统,但尚未开源。几位谷歌工程师发表了一篇论文,“ MillWheel:互联网规模的容错流处理”,详细解释了 MillWheel 作为一个流媒体平台。泰勒是这篇论文的第一作者。这篇论文启发了德国的一些研究生,他们后来构建了 Apache Flink 作为一个开源项目。
这本书涵盖了为什么我们需要一个流系统,并设置了流系统背后的基本思想。我强烈推荐他的书和 MilllWheel 报纸,因为他在流媒体领域很有权威。这本书的数字版本展示了一些很酷的动画来演示流式思想。我强烈建议你也去看看。
8.了解数据科学: R 对于数据科学:导入、整理、转换、可视化和建模数据
我的短评:数据工程师应该不仅仅致力于 ETL 数据管道。数据工程师的一组用户是数据科学家。了解基本的数据科学思想将使沟通更加轻松,并帮助数据工程师从数据中获得更多商业意识,以提供更好的解决方案。
Wickham 先生还是 R-gg plot 2 中最流行的数据可视化工具之一的作者。如果你想了解为什么 ggplot2 如此神奇,即使你不是用 R 开发也应该花时间学习,请查看我的文章— 为什么 ggplot2 对数据可视化如此好?
这本书不全是关于 ggplot2 的。它讲述了数据科学流程以及如何执行探索性分析。对于任何数据项目,如何有效地扯皮数据。虽然用 R 开始编程是一个学习曲线,但这本书让它不那么痛苦。
9.数据交流:用数据讲故事:商业人士数据可视化指南
我的简短评论:“技术并不能促成交易。一个好故事可以。”无论你投入多少时间和精力来分析数据和构建管道,适当的沟通都可能导致不良的结果。这本书告诉你该做什么和不该做什么,以帮助你吸引观众。
构建仪表板很简单,但是开发一个自我解释的仪表板需要更多的思考和努力。作者在 Google 辅导数据可视化方面有多年的经验。这也是另一本从领域专家那里学到的书。
这本书没有给你留下优秀的图形,而是指导你在会议或文档等不同渠道上与他人交流数据时的良好实践。它还教会了你如何恰当地进行面对面的讨论,并在 3 分钟内抓住听众的注意力来展示数据。我发现这对于任何推动对话以获得更好结果的数据工程师来说都特别实用。
10.获取云基础知识: Kubernetes 在行动
我的短评:随着越来越多的数据基础设施迁移到云端,数据工程师应该了解他们的数据是如何流动的。随着许多基础设施被容器化,学习 Kubernetes 对于数据工程师来说变得很有必要,尤其是那些在多家云提供商工作的数据工程师。
这本书通过介绍 Docker 和 Kubernetes 很好地充当了第一本 Kubernetes 书;构建本地集群,并向 Kubernetes 集群添加更多特性。在此过程中,您还会熟悉kubectl
命令。这是一本非常好用的入门书,可以用来调试 Kubernetes 生态系统中任何关于云的数据工程错误。
最后的想法
我选择的书籍涵盖了各种数据工程主题,包括基本编程语言、流行的批处理和流框架、数据通信和云。这里还有很多书我没有展示,也很棒。我想提出我认为一个数据工程师应该经历的最明确的清单。我希望更多关于数据工程的精彩书籍不断涌现,并且你能享受阅读这些书籍的美好时光!
作为数据工程师,你是如何获得所有这些技能的?答案是观察其他数据工程师做什么,阅读经典的数据工程书籍,实践数据工程概念和技能。获得知识和经验需要一些时间。一旦你承诺去做,它最终会回报你。
请评论你对这份名单的看法,以及你是如何喜欢阅读它的。干杯!
免责声明:这篇文章有亚马逊联盟链接,如果你从上面的链接购买这本书,我可能会得到一小笔佣金。它不会增加你的成本。感谢您的支持!
希望这个故事对你有帮助。本文是我的工程&数据科学故事系列的一部分,目前包括以下内容:
赵承志
数据工程和数据科学故事
View list47 stories
你也可以 订阅我的新文章 或者成为 推荐媒介会员 无限制访问媒介上的所有故事。
如果有问题/评论,请不要犹豫,写下这个故事的评论或者通过 Linkedin 或 Twitter 直接联系我。
2022 年你应该知道的 10 个领先的 Python 库
原文:https://towardsdatascience.com/10-leading-python-libraries-you-should-know-in-2022-a3287498c4b4
破折号,不平衡学习, FlashText,PyFlux,还有更多
由布雷特·乔丹在 Unsplash 上拍摄的照片
Python 编程充满了可能性。它简单明了,有许多优秀的库和函数,可以使任务更易于管理。每个 Python 开发者都必须使用流行的库,比如 OS、pandas、datetime、scikit-learn、seaborn、Tkinter 等等。
在本文中,我将讨论十个您可能感兴趣的 Python 库。让我们仔细看看一些不常见但很有价值的 Python 编程库。
1。Wget
数据科学家最重要的职责之一是数据提取,尤其是从网站提取数据。Wget 是一个用于下载非交互式在线文件的免费模块。即使用户没有登录,该模块也可以在后台运行,因为它是非交互式的。因此,它是从网站或页面下载所有照片的理想选择。
我们通常使用这个模块来实现自动化,我们想让它在后台继续运行。
安装:
pip install wget
2。钟摆
如果您需要在 python 项目中使用日期和计时,钟摆是一个很好的项目。这个 python 包简化了日期和时间操作。它能够完全取代 Python 的原生类。
安装:
pip install pendulum
如果我们想获得任何特定时区的当前时间,那么钟摆模块的一行代码可以完成如下任务。
import pendulum# Getting current UTC time
**utc_time =****pendulum.now('UTC')**
3。不平衡学习
事实上,当每个类别中的样本数量几乎相等时,分类算法的性能最佳,但在实际项目中,大多数数据集是不平衡的。
这些数据集影响机器学习算法的学习阶段和后续预测。为了解决这些问题,不平衡学习正在发展。IB 项目的组件 Scikit Learn 与之兼容。当您下次遇到不平衡的数据集时,请记住这一点。
安装:
pip install -U imbalanced-learn# orconda install -c conda-forge imbalanced-learn
4。FlashText
在大多数 NLP 任务中,替换句子中的单词或从短语中移除单词是文本数据清洗。这个过程通常使用正则表达式来执行,但是随着搜索关键字的数量接近数千,它变得非常困难。
Python 中的 flash 文本模块基于 flash 文本算法,在这种情况下提供了一个合适的替代方案。Flashtext 的运行时间是一致的,不管搜索查询的数量是多少,这是它最健壮的特性。
安装:
pip install flashtext
5。模糊模糊和多模糊
这个名字听起来很有趣,但是 fuzzywuzzy 是一个方便的字符匹配库。它可以快速实现字符串匹配和令牌匹配等操作。它还可以很容易地匹配来自几个数据库的条目。
有许多高级模糊匹配替代方法可用,如 polyfuzz,它使用变形器、手套、快速文本和嵌入来进行高效匹配。
安装:
pip install fuzzywuzzy
pip install polyfuzz
如果我们想用 transformers、FastText、Td-IDF 或 Embeddings 等高级算法在两个文本列表之间应用模糊匹配,那么下面几行代码可以帮助我们。
from polyfuzz.models import TFIDF from polyfuzz import PolyFuzz tfidf = TFIDF(n_gram_range=(3, 3)) model = PolyFuzz(tfidf) model.match(from_list, to_list)
直接从行业专家那里获得 Python 和数据科学的优质内容——使用我的推荐链接成为中级会员以解锁内容:https://pranjalai.medium.com/membership
6。PyFlux
机器学习中最普遍的困难之一是时间序列分析。Pyflux 是一个开源 Python 包,旨在处理时间序列挑战。该模块包含几个良好的当前时间序列模型,包括 Arima、GARCH 和 VaR 模型。最后,flux 为时间序列建模提供了一种有效的方法。值得一试。
安装:
pip install pyflux
7。Ipyvolume
数据科学是关于交流结果的,可视化是一个巨大的帮助。Ipyvolume 是一个 Python 模块,用于在 Jupyter 笔记本中查看 3D 视觉效果(如 3D 立体图)。
安装:
# Using pippip install ipyvolume# Using Conda/Anacondaconda install -c conda-forge ipyvolume
这是你如何使用它。
import ipyvolume as ipv
import numpy as np
x, y, z, u, v, w = np.random.random((6, 1000))*2-1
ipv.quickquiver(x, y, z, u, v, w, size=5)
由作者添加
8。破折号
Dash 是一个用于开发 web 应用程序的轻量级 Python 框架。它是用 Flash Plotly.js 和 React.js 构建的,Dash 是创建数据可视化应用程序的理想选择。这些应用程序可以通过网络浏览器查看。
安装:
pip install dash==0.29.0 # This will install the core dash backendpip install dash-html-components==0.13.2 # This command will install HTML componentspip install dash-core-components==0.36.0 # Supercharged componentspip install dash-table==3.1.3 # Interactive DataTable component
9。Bashplotlib
Bashlotlib 是一个 Python 库和命令行实用程序,用于在终端创建简单的图形。当用户不能访问 GUI 时,可视化数据变得非常有用。
安装:
pip install bashplotlib
下面是如何使用它来制作一个交互式直方图。
import numpy as npfrom bashplotlib.histogram import plot_histrand_nums = np.random.normal(size=700, loc=0, scale=1)plot_hist(rand_nums, bincount=100)
由作者添加
10。Colorama
Colorama 是一个 Python 包,可以在终端和命令行上生成彩色文本。它使用标准 ANSI 转义码对终端输出进行着色和样式化。它是跨平台的,在 Windows 和 Linux 上运行良好。
安装:
pip install colorama
下面是使用方法。
from colorama import init, Fore, Backinit()# Fore changes the text's foreground color
print(Fore.BLUE + "These are Blue Letters")#Back changes the text's background color
print(Back.WHITE + "This is White Background")
结论
许多现实世界的应用程序经常使用易于理解的 Python 编程语言。由于它是一种高级的、动态类型的、解释型的语言,所以它在错误调试领域迅速发展。此外,因为 Python 库是可用的,所以用户可以完成各种活动而无需构建他们的代码。
因此,学习 Python 及其库对于当今任何有抱负的人才来说都是至关重要的。作为开发人员,这些库可以让您的生活更加轻松。
在你走之前……
如果你喜欢这篇文章,并且想继续关注更多关于 Python &数据科学的精彩文章——请点击这里https://pranjalai.medium.com/membership考虑成为中级会员。
请考虑使用 我的推荐链接 报名。通过这种方式,会员费的一部分归我,这激励我写更多关于 Python 和数据科学的令人兴奋的东西。
10 个鲜为人知的 Python 可视化概念和技巧
原文:https://towardsdatascience.com/10-less-known-python-visualization-concepts-and-hacks-2b5f8ff4a5b7
添加到您的探索性数据分析库中
来源:像素(免费使用)
介绍
可视化是我们以各种视觉形式描述数据的操作,从图表、图形到信息图形。它是探索性数据分析(EDA)中最重要的部分之一,因为它使我们能够轻松掌握变量之间的关系和数据的任何独特特征,这对后期的特征工程和建模非常有用。在本文中,我将向您介绍 10 个 Python 可视化概念和技巧,这些概念和技巧不太为人所知,但是对于将它们添加到您的可视化武库中非常有用!
我们从导入相关库和数据集(CC0:Creative Commons;允许商业使用)我们将在下面的一些例子中使用。
**import** numpy **as** np
**import** pandas **as** pd
**import** seaborn **as** sns
**import** matplotlib.pyplot **as** pltdf = pd.read_csv(“../input/mall-customers/Mall_Customers.csv”)df
来源:来自作者
这是一个购物中心客户数据集,包含 5 个变量—客户 ID、类型、年龄、年收入(k$)和消费得分(1-100)。
为了方便起见,我们将流派列重命名为性别。
df.rename(columns={'Genre':'Sex'}, inplace=True)
使用样式
Python 中的 Matplotlib 允许我们指定用于可视化的特定样式。这些风格使我们的视觉化图像更容易理解,更容易阅读和解释,有时还会给它们添加美学的味道,使它们对观众更有说服力。以下是您可以使用的样式列表。
['seaborn-deep','seaborn-muted','bmh','seaborn-white','dark_background','seaborn-notebook','seaborn-darkgrid','grayscale','seaborn-paper','seaborn-talk','seaborn-bright','classic','seaborn-colorblind','seaborn-ticks','ggplot','seaborn','_classic_test','fivethirtyeight','seaborn-dark-palette','seaborn-dark','seaborn-whitegrid','seaborn-pastel','seaborn-poster']
在开始构建可视化之前,您只需运行以下代码:
plt.style.use("fivethirtyeight")
设置和更新参数
有时,为您制作的每个可视化指定参数很麻烦,您可能希望为您制作的所有可视化定义一组参数。在这种情况下,您可以利用 matplotlib 的 rcParams 方法。
**# Setting figure size using matplotlib.pyplot's rcParams method** plt.rcParams['figure.figsize'] = (16, 9)**# Setting linewidth of line graph
import** matplotlib **as** mpl
[mpl.rcParams](https://matplotlib.org/stable/api/matplotlib_configuration_api.html#matplotlib.RcParams)['lines.linewidth'] = 2##and other settings are available too
##[https://matplotlib.org/stable/tutorials/introductory/customizing.html](https://matplotlib.org/stable/tutorials/introductory/customizing.html)
也可以通过 seaborn 的 set 方法设置参数或设置。
**# Another way to set figure size using seaborn's set method** sns.set(rc={'figure.figsize':(10,8)})
我们可以使用 matplotlib 中的 pylab 方法来更新参数。
**import** matplotlib.pylab **as** pylab**# Specify various parameters you want to overwrite/update with**params = {'legend.fontsize': 'large','figure.figsize': (16,9),'axes.labelsize': 'x-large','axes.titlesize':'small','xtick.labelsize':'medium','ytick.labelsize':'x-large'} pylab.rcParams.update(params)
请注意,您可以使用 7 个不同的选项来指定大小,如下所示:
Size: {'xx-small', 'x-small', 'small', 'medium', 'large', 'x-large', 'xx-large'}
环形图
这是一个很好的可视化不同类别的比例图。当您为每个部分的实际比例值添加注释时会更有效,因为具有相似比例的部分可能很难相互区分。
size = df['Sex'].value_counts()
colors = ['pink', 'lightblue']
labels = "Male", "Female"
explode = [0.05, 0.03] *# It specifies the fraction of the radius with which to offset each wedge for each portion. In this case, we only have two categories and so we specify two values.*# first argument specifies the location of circle center and the second argument specifies the size of the radius. We set color to be white so that the center of the circle becomes empty and hence the name "donut" plot.
donut = plt.Circle((0,0), 0.6, color = 'white') # The autopct argument allows us to add annotations of proportion values to each portion of the donut plot
plt.pie(size, colors = colors, labels = labels, shadow = True, explode = explode, autopct = '%.2f%%')plt.title('Distribution of Gender', fontsize = 20)
p = plt.gcf()
p.gca().add_artist(donut)
plt.legend()
plt.show()
来源:来自作者
群体图
群体图是一种可视化类型,允许我们可视化每个类别的值的分布。它可能比其他类型的可视化(如箱线图)更有用,因为它的粒度显示(即显示每个数据点的值)如下所示。这样做的缺点是,如果有太多具有相似值范围的数据点,可视化可能会看起来过于集中,并在解释可视化时造成困难。我建议将它用于不太大的数据集。
来源:来自作者
您可以使用以下代码创建上面的虫群图:
sns.catplot(x='Sex', y='Age', data=df)
博兴图
Boxenplot 是由 seaborn 包提供的,看起来几乎像一个方框图。虽然箱线图的主要改进是分位数的更精细显示,这为用户的可视化增加了更多信息。关于这个可视化的更多信息可以从这个文档中找到。
sns.boxenplot(x='Sex', y='Annual Income (k$)', data=df, palette = 'copper')
来源:来自作者
散布矩阵图
散点图包含数值变量的单变量和多变量可视化。如果有 n 个数值变量,则显示 n x n 个网格,对角线位置的网格包含每个变量的单变量分布图(如直方图),而其他网格向我们显示散点图,解释不同变量组合之间的关系。请看下面的可视化!
来源:来自作者
**from** pandas.plotting **import** scatter_matrixpd.plotting.scatter_matrix(df.drop('CustomerID',axis=1), figsize=(10,10))
密度图
核分布估计图是一种类似于直方图的分布图,但不同之处在于它描述的是概率密度函数,而不是纯粹的计数或比例。根据熊猫文档,“这是一种估计随机变量概率密度函数(PDF)的非参数方法,使用高斯核进行估计,包括自动带宽确定。”
fig, ax = plt.subplots(1,1,figsize=(9,5))sns.kdeplot(df[df['Sex']=='Male']['Annual Income (k$)'], ax=ax)
sns.kdeplot(df[df['Sex']=='Female']['Annual Income (k$)'], ax=ax)plt.legend(['Sex == Male', 'Sex == Female'])
来源:来自作者
正如您在上面看到的,这种可视化对于并列不同类别的密度图以及查看分布如何不同非常有用。这可能会给我们关于变量本身的有用见解,以及关于如何设计该特征以提高模型性能的潜在想法。
安德鲁斯曲线
因为人类能够感知和理解的最大维数是三,任何超过这个维数的特征组合都变得很难放到画布上。为了解决这个问题,有几种可视化方法以我们可以理解的方式描述了三维的多维数据。安德鲁斯曲线就是其中之一。它通过以下方式转换多元观测值:
资料来源:安德鲁斯博士(1972)。高维数据图,生物特征28:125–136。
看看这个教程的另一个例子。虹膜数据中对应于不同物种的线用不同的颜色标记,我们看到一些线有很多重叠,而另一些没有。这给了我们一个概念,一个变量中的哪些类别具有与其他类别完全不同的基本分布或模式。
**from** pandas.plotting **import** andrews_curves**# Only used 30 sampled data points to create the visualization because using the entire data makes the display too cluttered**andrews_curves(df.drop(“CustomerID”, axis=1).sample(30), ‘Sex’,colormap=’rainbow’)
来源:来自作者
堆积面积图
堆积面积图有助于显示不同类别在一段时间内的比例或数值的细分。看看下面的可视化。
来源:来自作者
正如你在上面看到的,我们可以很容易地看到类别和 A、B、C 的细分是如何随时间变化的。例如,A、B 和 C 的细分在 2017 年开始相对均匀。然而,B 和 C 的部分呈指数下降,直到 2018 年,而 A 的部分保持相对不变。
树形地图
类似于饼图、条形图和圆环图,树形图向我们展示了不同类别比例的可视化显示。我个人认为它比前面提到的三个图更有效,尤其是当你有很多类别要比较的时候。例如,在圆环图中,许多具有相似比例的类别显示为一个圆中的角,这可能很难理解。另一方面,三棵树图在一个大矩形的石板中以不同大小的矩形显示比例,这使我们更容易立即知道类别在大小方面如何相互比较。
来源:来自作者
**import** matplotlib.pyplot asplt
**import** seaborn **as** sns
**import** folium
**import** squarify# Create a new variable that assigns random categories from 1 to 4 for the purpose of illustrating this example
df['rand_assignment'] = [randint(1,5) for e in range(len(df))]y = df['rand_assignment'].value_counts( )
# The alpha argument sets the transparency of the visualization. If you would like to form the graph plot less transparent, make alpha greater than 1\. This solidifies the graph plot, making it less transparent and dense. On the other hand, ff you would like to form the graph plot more transparent, make alpha smaller than 1.squarify.plot(sizes = y.values, label = y.index, alpha=.8, color = ['red','orange','lightblue','green','pink'])plt.axis('off')
plt.show()
结论
在本文中,我向您解释了 10 种可视化和技巧,它们不太为人所知和利用,但对添加到您的数据可视化工具包中很有用。最重要的是,我个人认为最重要的是理解每一个可视化做什么,它显示什么信息,什么时候它最有效,以及它如何被用来向观众传达你想要的信息,而不是骄傲于你知道如何创建多少可视化。
如果你觉得这篇文章有帮助,请考虑通过以下链接注册 medium 来支持我: )
joshnjuny.medium.com
你不仅可以看到我,还可以看到其他作者写的这么多有用和有趣的文章和帖子!
关于作者
数据科学家。加州大学欧文分校信息学专业一年级博士生。
密歇根大学刑事司法行政记录系统(CJARS)经济学实验室的前研究领域专家,致力于统计报告生成、自动化数据质量审查、构建数据管道和数据标准化&协调。Spotify 前数据科学实习生。Inc .(纽约市)。
他热爱运动,健身,烹饪亚洲美食,看 kdramas,制作/表演音乐,最重要的是崇拜我们的主耶稣基督。结账他的 网站 !
10 分钟轻松的 SQL 教程,适合铁杆熊猫爱好者
原文:https://towardsdatascience.com/10-minute-effortless-sql-tutorial-for-die-hard-pandas-lovers-a64c36733fd0
曾几何时,情况正好相反
菲奥娜·阿特摄于 Pexels
动机
当 Pandas package 在 2009 年获得公开曝光时,SQL 自 1974 年以来一直统治着数据世界。Pandas 具有一系列吸引人的功能,如内置可视化和灵活的数据处理,并成为一种终极数据探索工具。随着它越来越受欢迎,出现了许多教授 Pandas 并将其与 SQL 进行比较的课程和资源。
快进到 2021 年,人们现在首先开始接触熊猫包*,而不是通用数据语言——SQL。尽管 SQL 一如既往地受欢迎,但 Pandas 的灵活性和多功能性使其成为初学数据科学家的首选。*
那么,既然知道熊猫,为什么还需要 SQL 呢?
即使熊猫看起来是更好的选择,SQL 仍然在数据科学家的日常工作中扮演着重要角色。事实上,SQL 是数据科学第二大需求和第三大增长的编程语言(见这里)。所以,如果你想在这个领域找到一份工作,在你的简历中加入 SQL 是必须的。了解熊猫,学习 SQL 应该轻而易举,正如您将在本文中看到的。
*https://ibexorigin.medium.com/membership
获得由强大的 AI-Alpha 信号选择和总结的最佳和最新的 ML 和 AI 论文:
https://alphasignal.ai/?referrer=Bex
连接到数据库
设置一个 SQL 工作区并连接到一个示例数据库可能是一件非常痛苦的事情。首先,你需要安装你喜欢的 SQL 风格(PostgreSQL,MySQL 等。)并下载一个 SQL IDE。在这里做这些会使我们偏离文章的目的,所以我们将使用捷径。
具体来说,我们将在 Jupyter 笔记本中直接运行 SQL 查询,无需额外的步骤。我们需要做的就是使用 pip 安装ipython-sql
包:
pip install ipython-sql
安装完成后,启动一个新的 Jupyter 会话,并在笔记本中运行以下命令:
%load_ext sql
你已经准备好了!
为了说明基本的 SQL 语句是如何工作的,我们将使用 Chinook SQLite 数据库,您可以从这里下载。该数据库有 11 个表。
要检索存储在该数据库表中的数据,请运行以下命令:
%sql sqlite:///data/chinook.db
该语句以%sql
行内神奇命令开始,告诉笔记本解释器我们将运行 SQL 命令。接下来是下载的 Chinook 数据库所在的路径。对于 SQLite 数据库,有效路径应该总是以前缀sqlite:///
开头。上面,我们正在连接到存储在当前目录的“data”文件夹中的数据库。如果你想传递一个绝对路径,前缀应该以四个正斜杠开始- sqlite:////
如果您希望连接到不同风格的数据库,可以参考这篇优秀文章。
先看一下表格
在 Pandas 中,我们通常做的第一件事是使用.head()
函数来查看数据。让我们学习如何在 SQL 中实现这一点:
数据集也被许可用于商业用途。
上述查询中的第一个关键字是SELECT
。它相当于 Pandas 中的括号操作符,在这里我们选择特定的列。但是,SELECT 关键字后跟一个*(星号)。*是一个 SQL 操作符,它从一个在FROM
关键字后指定的表中选择所有内容(所有行和列)。LIMIT 用于最小化返回的输出。所以,上面的查询相当于df.head()
函数。
如果不想选择所有列,可以在 select 关键字后指定一个或多个列名:
相当于熊猫的操作是
tracks[['Name', 'Composer', 'UnitPrice']].head(10)
SQL 中另一个有用的关键字是DISTINCT
。在任何列名之前添加此关键字都会返回其唯一值:
SQL 中的注释用双破折号书写。
计算行数
就像 Pandas 在其数据帧上有.shape
属性一样,SQL 有一个COUNT
函数来显示表中的行数:
%%sqlSELECT COUNT(*) FROM tracks
也可以将列名传递给 COUNT:
%sql SELECT COUNT(FirstName) FROM customers
但是输出将与 COUNT(*)相同。
更有用的信息是计算特定列中唯一值的数量。我们可以通过在 COUNT 中添加 DISTINCT 关键字来实现这一点:
使用 WHERE 子句筛选结果
仅仅是看和数行是相当蹩脚的。让我们看看如何根据条件过滤行。
首先,让我们来看看价格超过一美元的歌曲:
条件语句写在 WHERE 子句中,该子句总是位于 FROM 关键字之后和 LIMIT 关键字之前。使用条件句和我们在熊猫身上做的很相似。
使用条件句时也可以使用 COUNT 函数。例如,让我们看看价格在 1 到 10 美元之间的歌曲数量:
上面我们用布尔运算符 AND 链接了两个条件。其他布尔运算符在 SQL 中是相同的。
现在,让我们看看所有将巴黎或柏林作为账单城市的发票:
SQL 中的等号运算符只需要一个“=”(等号)。不等式运算符用“!= '或'【T4]'运算符:
使用“介于”和“在”更容易过滤
类似的条件句使用得非常频繁,用简单的布尔写出它们变得很麻烦。例如,Pandas 有.isin()
函数,它检查一个值是否属于一个组或值的列表。如果我们想选择五个城市的所有发票,我们必须编写五个连锁条件。幸运的是,SQL 支持类似于.isin()
的 IN 操作符,所以我们不必:
IN 之后的值列表应该作为元组给出,而不是列表。您也可以用 NOT 关键字否定条件:
对数字列的另一种常见筛选操作是选择某个范围内的值。为此,可以使用 BETWEEN 关键字,相当于pd.Series.between()
:
检查空值
每个数据源都有缺失值,数据库也不例外。就像有几种方法可以探索 Pandas 中缺失的值一样,有一些特定的关键字可以检查 SQL 中是否存在空值。以下查询计算 BillingState 中缺少值的行数:
您可以在 IS 和 NULL 之间添加 NOT 关键字,以筛选出特定列中缺少的值:
使用 LIKE 更好地匹配字符串
在 WHERE 子句中,我们根据精确的文本值过滤列。但是通常,我们可能希望根据模式过滤文本列。在 Pandas 和 pure Python 中,我们会使用正则表达式进行模式匹配,这非常强大,但需要时间来掌握。
作为替代,SQL 提供了一个“%”通配符作为占位符来匹配任何字符 0 次或更多次。例如,“gr%”字符串匹配“great”、“groom”、“greed”,而“%ex%”匹配中间带有“ex”的任何文本,等等。让我们看看如何在 SQL 中使用它:
上面的查询查找所有以“b”开头的歌曲。包含通配符的字符串应该在 LIKE 关键字之后。
现在,让我们找出标题中包含“美丽”一词的所有歌曲:
您也可以在 LIKE 旁边使用其他布尔运算符:
SQL 中还有许多其他通配符,它们具有不同的功能。你可以在这里看到完整的列表和它们的用法。
SQL 中的聚合函数
还可以对列执行基本的算术运算。这些操作在 SQL 中称为聚合函数,最常见的是AVG, SUM, MIN, MAX
。它们的功能应该从它们的名字中清晰可见:
聚合函数对于使用它们的列只给出一个结果。这意味着您不能跨一列进行聚合并选择其他未聚合的列:
您可以使用 WHERE 子句轻松地将聚合函数与条件结合起来:
也可以在列和简单数字上使用算术运算符,如+、-、*、/等。在列上使用时,操作是按元素执行的:
关于算术运算,有一点需要注意:如果您只对整数执行运算,SQL 认为您期望整数作为答案:
%%sql SELECT 10 / 3
而不是返回 3.33…,结果是 3。要获得浮点数结果,您应该在查询中至少使用一个浮点数,或者使用所有浮点数以确保安全:
%%sql SELECT 10.0 / 3.0
利用这些知识,让我们以分钟为单位计算一首歌曲的平均持续时间:
如果您注意上面的列,它的名称被写成“用于生成该列的查询。”由于这种行为,使用长时间的计算(如查找列的标准偏差或方差)可能会有问题,因为列名将与查询本身一样大。
为了避免这种情况,SQL 允许别名,类似于 Python 中的别名导入语句。例如:
在一个SELECT
语句中的单个项目后使用as
关键字告诉 SQL 我们在混淆。以下是更多的例子:
对于具有长名称的列,也可以很容易地使用别名。
SQL 中的排序结果
就像 Pandas 有sort_values
方法一样,SQL 支持通过ORDER BY
子句对列进行排序。在子句后传递列名会按升序对结果进行排序:
我们按照作曲家的名字对曲目表进行升序排序。请注意,ORDER BY 语句应始终位于 WHERE 子句之后。也可以通过以下方式将两列或更多列传递给 ORDER:
您也可以通过在每个列名后传递DESC
关键字来颠倒排序:
上面的查询在按降序对 UnitPrice 和 Compose 排序以及按升序对 name 排序后返回三列(ASC
是默认关键字)。
SQL 中的分组
熊猫最强大的功能之一就是groupby
。你可以用它把桌子变成任何你想要的形状。它在 SQL - GROUP BY
子句中的近亲可以用来实现相同的功能。例如,下面的查询统计了每个流派中的歌曲数量:
SQL 中的 GROUP BY 和 Pandas 中的groupby
的区别在于,SQL 不允许选择 GROUP BY 子句中没有给出的列。例如,在上面的查询中添加一个额外的空闲列会产生一个错误:
但是,您可以在 SELECT 语句中选择任意多的列,只要您对它们使用某种类型的聚合函数:
上面的查询几乎包括了我们到目前为止学到的所有主题。我们根据专辑 ID 和流派 ID 进行分组,并为每个组计算一首歌曲的平均持续时间和价格。我们也在有效地利用别名。
我们可以通过按平均持续时间和流派计数排序来使查询更加强大:
注意我们如何在 ORDER BY 子句中使用聚合函数的别名。一旦为列或聚合函数的结果起了别名,就只能在查询的其余部分通过别名来引用它们。
将条件句与 HAVING 连用
默认情况下,SQL 不允许在 WHERE 子句中使用聚合函数进行条件筛选。例如,我们希望只选择歌曲数量大于 100 的流派。让我们试试 WHERE 子句:
根据聚合函数的结果筛选行的正确方法是使用 HAVING 子句:
HAVING 子句通常与 GROUP BY 连用。每当您想使用集合函数过滤行时,HAVING 子句是一个不错的选择!
摘要
到目前为止,您应该已经意识到 SQL 有多强大。尽管我们学到了很多,但我们仅仅触及了皮毛。对于更高级的话题,你可以阅读 W3Schools 上的优秀指南,并通过在 Hackerrank 或 LeetCode 上解决真实世界的 SQL 问题来练习你的查询技巧。感谢您的阅读!
https://ibexorigin.medium.com/membership https://ibexorigin.medium.com/subscribe
更多来自我的故事…
https://ibexorigin.medium.com/yes-these-unbelievable-masterpieces-are-created-with-matplotlib-b62e0ff2d1a8 https://ibexorigin.medium.com/how-to-use-matplotlib-annotations-like-you-know-what-you-are-doing-da61e397cce3 *
给铁杆 Python 爱好者的 10 分钟 Julia 指南
原文:https://towardsdatascience.com/10-minute-guide-to-julia-for-die-hard-python-lovers-a2fcf7dcb860
你不能再忽视她了,你不能
照片由 艾玛 上 像素
不要误解我。我不是一个讨厌 Python 的人。我喜欢它,在事实改变之前,我的眉毛可能会变成蓝色。但是朱莉娅似乎好得不像真的。
所有的编程语言在特定的任务上都很优秀,但在其他方面却很糟糕。Julia 的创造者很贪婪——他们想要最好的语言的所有超能力并创造一种超级语言。
他们做到了。正如创作者在《朱莉娅的贪婪》中所描述的那样,这种语言已经实现了他们 90%以上的宏伟梦想。
尽管 Julia 相对年轻,但它已经可以和 Python 一较高下了。考虑到 Python 花了很多年才成熟并被认真对待,Julia 正在以惊人的速度增长。在一个小得多的社区中,这种语言已经有了几乎任何可以用 Python 完成的任务的包和框架。
在本文中,您将了解核心语言,即使没有额外的模块,它也包含了令人敬畏的特性。
https://ibexorigin.medium.com/membership
获得由强大的 AI-Alpha 信号选择和总结的最佳和最新的 ML 和 AI 论文:
https://alphasignal.ai/?referrer=Bex
安装和设置
安装 Julia 并将其添加到 JupyterLab 只需要几分钟的时间。从这里下载安装程序,并勾选安装时将 Julia 添加到PATH
的选项。你甚至不需要重启你的机器。如果您在自己选择的 CLI 上键入julia
并得到以下输出,Julia 就正常了:
作者 GIF
对于 IDE,你可以为 PyCharm 安装 Julia 插件。对于 VSCode,扩展市场已经覆盖了你。
如果你想试试 JupyterLab 里面的 Julia,输入julia
进入 REPL 模式后这两行应该就够了:
using Pkg
Pkg.add("IJulia")
只需记住重新启动任何正在运行的 JupyterLab 会话,以使更改生效。然后,你可以从开始菜单打开一个带有 Julia 内核的笔记本:
作者 GIF
变量
Python 和 Julia 之间有很多语法上的相似之处。两者读起来几乎都像自然英语。
假设您已经熟悉 Python,我将主要提到 Julia 中在基本编程原则方面与 Python 语法完全不同的部分。先说变量。
Julia 是一种动态类型语言,这意味着 Julia 和 Python 中的变量没有太大的区别。在这两种情况下,变量都区分大小写,没有语义含义,并且允许在创建时使用大多数 Unicode 符号。
在风格指南中有一些小的不同:
茱莉亚文件截图
除此之外,Julia 中的一个变量可以替代它们的 Pythonic 对应物。
数字和数学
Julia 是一种科学语言,比 Python 更科学,它对数学计算有极好的、极快的支持。
所有的数学运算符都是一样的,除了乘方运算符,在 Julia 中用^
表示,以及底除数,用÷
表示(我不知道你如何在键盘上用一个简单的击键产生它)。还有一个额外的运算符,用反斜杠 ( \
)执行逆除法:
默认情况下,整数和浮点用 Int64 和 Float64 数据类型表示。Julia 非常重视正确的类型用法,因为它们对记忆有很大的影响:
不幸的是,Julia 还不支持全局变量的类型声明:
无穷大和空值表示为Inf
和NaN
:
但是,奇怪的是,在 Julia 中没有零除法误差:
现在,我们到了 Julia 开始觉得自己是一种真正的科学的、以数学为目的的语言的部分。Julia 允许你写出多项式的系数,而不用那些讨厌的乘法符号:
然而,也有例外——像这样的东西是行不通的:
尽管如此,允许数字紧接在变量之前,使得公式和表达式的编写更加简洁明了。
Julia 还在全局范围内提供了广泛的标准函数,无需导入额外的模块:
>>> factorial(10)3628800
下面是除法函数的列表:
茱莉亚文件截图
幂、对数和根函数的列表更加令人印象深刻:
茱莉亚文件截图
也没有遗漏触发功能:
朱莉娅文件的截图
条件式
在 Julia 中,缩进是没有语义意义的(但是请大家为了大家的利益使用它,就像你在写 Python 一样)。因此,诸如条件、循环和函数等代码块应该以关键字end
结束。
条件关键字(if,else if(Python 中的 elif),else)的逻辑是一样的。数字比较运算符也是如此:
朱莉娅文件的截图
复合语句的条件运算符略有不同:
&&
和||
操作人员称为短路**and**
和**or**
操作人员。我们只探索它们的标准功能;优秀的短路特性将在文章结尾进行探讨。
在 Julia 中还有严格的等式运算符— ===
。这将检查值和数据类型是否相等:
像任何现代语言一样,Julia 支持三元运算符:
不幸的是,与 Python 版本相比,这个版本非常不可读:
最后,Julia 中的值没有 Python 中的真值:
所以,语法if value
在 Julia 中不起作用。为了完善这种奇怪性,Julia 中有四种类型的空值:
我特别喜欢nothing
。现在,我可以明确地在函数中不返回任何东西。
复合表达式
复合表达式在 Julia 中比在 Python 中成熟得多。
在 Python 中有很多这样的情况,一些代码行就宽度而言非常短,但仍然占据了一整行。Julia 中的复合表达式解决了这个问题,让你的代码更加紧凑。这里有一个简单的例子:
将多个表达式放在括号内并用分号分隔,就构成了一个复合表达式。此外,您不必将它们写成单行语句:
在复合语句中创建的变量在语句结束后仍将留在它们的作用域内:
>>> println(x + y)31
您也可以使用begin
/ end
语法创建复合表达式,这样可以避免分号:
用线串
先简单说一下字符串:
尽管在数据类型方面很相似,但是在 Julia 和 Python 中字符串方法有很大的不同。例如,串联是用乘法符号非直觉地完成的:
或者是string
函数,它也将数字转换成字符串(如何转换...好玩):
分割字符串也有点不寻常。第一个字符不像 Python 中那样用0
索引,而是使用关键字begin
:
哦,没有负数的反向切片。相反,Julia 使用了end
关键字:
也可以用SubString
功能分割字符串:
使用$
符号进行字符串插值:
在 Julia 中没有针对字符串的in
关键字,所以您必须使用occursin
函数来检查子字符串:
>>> occursin("was", long_str)true
重复一个字符串是通过电源符号或重复功能完成的:
>>> str ^ 3"JuliaJuliaJulia"
你可以从 Julia docs 的 this 链接中找到标准字符串函数的列表,它包括了几乎所有你喜欢的 Python 字符串函数等等。
环
Julia 中的循环与 Python 相同,除了缺少冒号和在末尾添加了end
关键字:
您可以使用:
创建一个 iterable 对象,尽管 Julia 中也存在range
函数。
令人惊讶的是,您还可以使用=
符号来循环遍历一个 iterable:
break
、continue
逻辑按预期工作。zip
功能也是如此。
对于嵌套循环,Julia 提供了更紧凑的语法:
每次在for
块中的逗号后添加 iterable 时,都会创建一个内部循环,如下所示:
while
循环也几乎与 Python 的相同:
功能
函数用关键字function
定义,并以end
结束:
类型声明用双分号书写(对于返回类型也是如此):
Julia 还允许为上面这样的短函数定义单行函数:
您也可以将函数分配给其他变量:
这是 Julia 的另一个特质——即使是操作符也是函数,因此可以被重新赋值(不要忘记分号):
这些类型的技巧也有效:
使用->
运算符对lambda
进行如下定义:
要更全面地了解 Julia 中的函数,请查看文档。
数组
创建基本数组的语法与 Python 类似:
由于 Julia 是一种科学语言,基本数组被认为是向量。vector 中的元素不需要是相同的类型,就像 Python 中一样。
您可以使用collect
函数从迭代中创建向量:
或者使用熟悉的range
功能输入一系列数字:
Julia 还内置了对快速强大的 2D 和 3D 矩阵的支持。只要去掉元素之间的逗号,你就得到一个 2D 数组。记住用分号分隔各行:
列表理解与 Python 中的相同:
您也可以在生成器表达式上使用collect
函数来创建向量:
你可以阅读关于创建和操作向量和矩阵的所有方法的 Julia 文档,在这方面你可以学到很多东西。
字典
创建字典需要与 Python 不同的语法,但逻辑是相同的:
不变性约束仍然有效——键应该只是不可变的类型,比如数字、字符串和元组。从字典中添加和检索值与 Python 中的相同。但是删除有点不同:
令我高兴的是,字典中的理解在 Julia 中也有效:
要检查字典中是否存在关键字,使用haskey
功能:
haskey(dict1, "missing")false
获取所有的键和值都有各自的功能:
不幸的是,没有像 Python 中那样的items
方法来获取键/值对。
你可以阅读文档来了解更多关于 Julia 中的字典。
短路的魔力
在前面的部分中,我们简要地讨论了逻辑and
和or
如何具有短路行为。我们来细说一下。
短路评估可用于替换短条件表达式。用逻辑和T9 来考虑这个例子:
您可能会在以下条件下产生上述行为:
因此,如果条件为真,短路&&
可以用于我们想要评估表达式的情况。下面是一个总是执行的短路&&
表达式:
换句话说,如果短路表达式的左侧计算结果为true
,则执行右侧部分。
短路||
则相反。只有当左侧为false
时,||
的右侧才运行;
短路可以清除许多繁琐的条件语句。
结论
我想 Julia 在使用方面接近 Python 还需要一段时间。Julia 可能比 Python 好几个数量级,但可能仍然无法说服许多长期的 Python 爱好者做出改变。
你呢?你认为未来像数据科学、机器学习和人工智能这样的领域会由朱莉娅一个人统治吗?
留下你的想法,感谢你的阅读!
您可以使用下面的链接成为高级媒体会员,并访问我的所有故事和数以千计的其他故事:
https://ibexorigin.medium.com/membership
或者订阅我的邮件列表:
https://ibexorigin.medium.com/subscribe
你可以在LinkedIn或Twitter上联系我,友好地聊一聊所有的事情数据。或者你可以读我的另一个故事。这些怎么样:
</6-pandas-mistakes-that-silently-tell-you-are-a-rookie-b566a252e60d> </8-booming-data-science-libraries-you-must-watch-out-in-2022-cec2dbb42437> </7-cool-python-packages-kagglers-are-using-without-telling-you-e83298781cf4> </22-2-built-in-python-libraries-you-didnt-know-existed-p-guarantee-8-275685dbdb99>
关于堆栈溢出的 10 个最常见的熊猫问题
原文:https://towardsdatascience.com/10-most-frequently-asked-pandas-questions-on-stack-overflow-b9d7d94cd83e
来自现实生活的问题
在 Unsplash 上由Towfiqu barb huya拍摄的照片
Stack Overflow 是最大的在线社区,它不断地在软件、编码、数据科学和许多其他主题中提问和回答问题。
我认为使它成为无价资源的是问题来自现实生活。人们会发帖询问他们在工作中遇到的困难。答案通常来自经历过同样挑战并找到解决方案的人。
在这篇文章中,我们将讨论关于栈溢出的 10 个最常见的问题。如果你正在或计划学习熊猫,你可能会搜索这些问题中的一些。
在撰写本文时,我根据投票数和对堆栈溢出的看法选择了问题。
让我们从创建一个用于问题的样本数据框架开始。
import numpy as np
import pandas as pd
df = pd.DataFrame({
"first_name": ["John", "Jane", "Emily", "Matt", "Alex", "George", "Max"],
"last_name": ["Doe", "Doe", "Uth", "Dan", "Mir", "Jen", "Potter"],
"start_date": ["2022-10-04", np.nan, "2022-08-04", np.nan, np.nan, "2021-12-10", "2022-02-05"],
"group": ["A", "B", "A", "A", "C", "D", "D"],
"salary": [75000, 72000, 45000, 77000, np.nan, np.nan, 65000]
})
df
df(作者图片)
1.如何在 Pandas 中迭代数据帧中的行
尽管这个问题是最重要的,但是通常不建议对行进行迭代。矢量化运算比执行迭代更实用、更快速。
我认为这个问题的浏览量最高,因为它是在将近 10 年前提出的。当时很少有人对数据科学感兴趣。
如果一定要遍历行,可以使用 iterrows,它返回行及其索引。这里有一个简单的例子:
for index, row in df.iterrows():
print(row[0], row[1])
# output
John Doe
Jane Doe
Emily Uth
Matt Dan
Alex Mir
George Jen
Max Potter
2.如何根据列值从数据帧中选择行?
这个问题是关于根据一列或多列中的值过滤数据帧。根据数据类型,有几种不同的过滤方式。
最重要的是把条件写好。例如,我们可以选择工资高于 70000 的行,如下所示:
df[df["salary"] > 70000]
# output
first_name last_name start_date group salary
0 John Doe 2022-10-04 A 75000.0
1 Jane Doe NaN B 72000.0
3 Matt Dan NaN A 77000.0
我们也可以基于多个条件过滤数据帧。下面是我们如何选择工资高于 7000 且属于 a 组的行。
df[(df["salary"] > 70000) & (df["group"] == "A")]
# output
first_name last_name start_date group salary
0 John Doe 2022-10-04 A 75000.0
3 Matt Dan NaN A 77000.0
另一种常用的筛选方法是 isin 方法,它将值与一组给定的值进行比较。
以下代码行选择 A、B 或 c 组中的行。
df[df["group"].isin(["A", "B", "C"])]
# output
first_name last_name start_date group salary
0 John Doe 2022-10-04 A 75000.0
1 Jane Doe NaN B 72000.0
2 Emily Uth 2022-08-04 A 45000.0
3 Matt Dan NaN A 77000.0
4 Alex Mir NaN C NaN
3.在 Pandas 中重命名列名
rename 函数可用于更改 Pandas 中的列名。新旧列名在 Python 字典中被写成键值对。
让我们重命名数据框架中的名字和姓氏列。
df = df.rename(columns={"first_name": "fname", "last_name": "lname"})
df
df(作者图片)
4.从熊猫数据框架中删除一列
drop 函数可用于删除行和列。为了将它用于列,需要将轴参数的值设置为 1。
我们在 Python 列表中写入要删除的列名或索引。
# dropping the start_date and group columns
df_new = df.drop(["start_date", "group"], axis=1)
df_new.columns
# output
Index(['fname', 'lname', 'salary'], dtype='object')
drop 函数返回删除了列的数据帧,但不修改原始数据帧。为了保存更改,我们需要:
- 将它赋给一个新变量
- 使用 inplace 参数
在上面的例子中,我们选择了第一个选项,并将返回的数据帧赋给了 df_new。
以下代码行修改了原始数据帧(df)。
# dropping the start_date and group columns
df.drop(["start_date", "group"], axis=1, inplace=True)
5.我如何获得熊猫数据帧的行数?
DataFrame 是一个带有标记行和列的二维数据结构。
为了获得行数,我们可以使用 shape 函数返回一个显示行数和列数的元组。另一种选择是使用 Python 的 len 函数,它将只返回行数。
df.shape
# output
(7, 5)
len(df)
# output
7
6.在熊猫数据框架中选择多个列
这是根据列过滤数据帧的另一种方式。我们可以通过将列写入 Python 列表来选择它们的子集。
cols = ["first_name", "last_name", "salary"]
df[cols]
(图片由作者提供)
我们还可以使用 loc 和 iloc 方法,通过列名或索引来选择多个列。如果你想了解更多,我之前写过一篇关于 loc 和 iloc 方法的教程。
7.如何更改数据帧列的顺序
完成这项任务有不同的方法。一种选择是使用 loc 方法。
new_cols = ["salary", "group", "first_name", "last_name", "start_date"]
df.loc[:, new_cols]
(图片由作者提供)
逗号前的冒号表示我们需要所有的行。逗号后面的列表决定了列的新顺序。
我写了一篇关于这个任务的详细文章,展示了改变列顺序的 4 种方法。
8.在 Pandas 中更改列类型
我使用了与堆栈溢出完全相同的短语。这个问题意味着改变列数据类型。
更改数据类型最直接的方法是使用 astype 函数。
让我们首先检查数据框架中的列数据类型。
df.dtypes
# output
first_name object
last_name object
start_date object
group object
salary float64
dtype: object
开始日期列的数据类型是 object,但最好将其转换为 datetime 数据类型。
df["start_date"] = df["start_date"].astype("datetime64[ns]")
df.dtypes
# output
first_name object
last_name object
start_date datetime64[ns]
group object
salary float64
dtype: object
我们可以在一次操作中改变多列的数据类型。列名和新的数据类型被写成 Python 字典中的键值对。
df = df.astype({
"start_date": "datetime64[ns]",
"first_name": "string",
"last_name": "string"
})
df.dtypes
# output
first_name string
last_name string
start_date datetime64[ns]
group object
salary float64
dtype: object
9.如何删除熊猫数据帧中某一列的值为 NaN 的行
dropna 函数可用于删除缺少值的行和列。默认情况下,它会删除行。为了将其更改为列,轴参数的值被设置为 1。
df.dropna()
(图片由作者提供)
默认情况下,至少有 1 个任务值的行将被删除。我们可以使用 subset、how 和 thresh 参数来定制这种行为。这里有一篇关于如何处理熊猫数据帧中缺失值的更详细的文章。
</8-methods-for-handling-missing-values-with-python-pandas-842544cdf891>
10.从 Pandas DataFrame 列标题获取列表
我们简单地使用 columns 方法和 list 构造函数。
col_headers = list(df.columns)
col_headers
# output
['first_name', 'last_name', 'start_date', 'group', 'salary']
截至撰写本文时,堆栈溢出上有 267,037 个问题被标记为熊猫。我们已经知道了这个庞大的列表和资源的前 10 个问题的答案。
你可以成为媒介会员来解锁我的作品的全部访问权限,以及媒介的其余部分。如果你已经是了,别忘了订阅如果你想在我发表新文章时收到电子邮件的话。
感谢您的阅读。如果您有任何反馈,请告诉我。
关于堆栈溢出的 10 个最常见的 Python 字典问题
原文:https://towardsdatascience.com/10-most-frequently-asked-python-dictionary-questions-on-stack-overflow-2cb345f07496
来自现实生活的问题
在 Unsplash 上由Towfiqu barb huya拍摄的照片
Stack Overflow 是最大的在线社区,它不断地在软件、编码、数据科学和许多其他主题中提问和回答问题。
我认为使它成为无价资源的是问题来自现实生活。人们会发帖询问他们在工作中遇到的困难。答案通常来自经历过同样挑战并找到解决方案的人。
我写了一篇关于关于熊猫的 10 个最常见问题的文章。在本文中,我们将讨论关于栈溢出的 Python 字典的 10 个最常见的问题。
如果您正在学习 Python 进行软件开发或创建面向数据的产品,那么您很可能会遇到这些问题。
在撰写本文时,我已经根据栈溢出的投票数和浏览量选择了问题(跳过了重复的问题)。
1.如何在一个表达式中合并两个字典?
解决这个问题有多种方法。如果您使用的是 Python 3.9 或更高版本,您可以简单地使用“|”操作符。
a = {"James": 95, "Jane": 98}
b = {"Matt": 85, "Ashely": 90}
c = a | b
c
# output
{'James': 95, 'Jane': 98, 'Matt': 85, 'Ashely': 90}
Python 字典中的键必须是唯一的,因此如果两个字典中存在相同的键,合并的字典将只有其中一个键。
a = {"James": 95, "Jane": 98}
b = {"Matt": 85, "Ashely": 90, "James": 100}
c = a | b
c
# output
{'James': 100, 'Jane': 98, 'Matt': 85, 'Ashely': 90}
键 James 的值是 100,这是我们在字典 b 中的值,如果你把表达式写成“b | a”,字典 c 就会有来自字典 a 的 James。
a = {"James": 95, "Jane": 98}
b = {"Matt": 85, "Ashely": 90, "James": 100}
c = b | a
c
# output
{'Matt': 85, 'Ashely': 90, 'James': 95, 'Jane': 98}
原因是表达式“a | b”类似于用字典 b 更新字典 a 的操作。因此,在具有相同键的情况下,值将来自最后一个字典。
“a | b”运算符返回组合字典,但不改变 a 或 b。如果需要使用另一个字典中的键值对来更新一个字典,请使用 update 方法。
a = {"James": 95, "Jane": 98}
b = {"Matt": 85, "Ashely": 90, "James": 100}
a.update(b)
a
# output
{'James': 100, 'Jane': 98, 'Matt': 85, 'Ashely': 90}
在上面的代码片段中,字典 a 用字典 b 更新。
如果使用的是 Python 3.5 或以上版本,可以使用“{**a,**b}”表达式,其作用与“a | b”相同。
a = {"James": 95, "Jane": 98}
b = {"Matt": 85, "Ashely": 90, "James": 100}
c = {**a, **b}
c
# output
{'James': 100, 'Jane': 98, 'Matt': 85, 'Ashely': 90}
2.如何从 Python 字典中删除一个键?
第一个选项是 del 函数。
a = {"James": 95, "Jane": 98, "Matt": 85, "Ashely": 90}
del a["James"]
a
# output
{'Jane': 98, 'Matt': 85, 'Ashely': 90}
del 函数仅在字典中存在该键时才有效。否则,它会引发一个 KeyError。如果您不确定字典中是否存在该键,请使用 pop 方法,但一定要指定如果该键不存在该怎么办。否则,pop 方法也会引发一个 KeyError。
与只从字典中删除指定键的 del 函数不同,pop 方法删除键并返回它的值。如果键不存在,它返回我们指定的值。
a = {"James": 95, "Jane": 98, "Matt": 85, "Ashely": 90}
a.pop("James", None)
# output
95
a.pop("Max", None)
# output
上面代码片段中的第二个操作没有返回任何内容,因为 Max 不是字典 a 中的一个键,但是键 James 已经从字典中删除了。
a
# output
{'Jane': 98, 'Matt': 85, 'Ashely': 90}
3.使用 for 循环迭代字典
如果我们使用一个带有字典的 for 循环,我们就可以遍历所有的键。
a = {"James": 95, "Jane": 98, "Matt": 85, "Ashely": 90}
for key in a:
print(key, a[key])
# output
James 95
Jane 98
Matt 85
Ashely 90
在上面的 for 循环中,我们打印了键,并使用“a[key]”表达式访问它的值。
我们还可以使用 items 方法迭代键和值。
a = {"James": 95, "Jane": 98, "Matt": 85, "Ashely": 90}
for key, value in a.items():
print(key, value)
# output
James 95
Jane 98
Matt 85
Ashely 90
4.如何按值对字典进行排序?
我们可以使用 Python 内置的排序函数来完成这项任务。如果我们将其应用于字典项目(即键-值对),项目将按键排序。
a = {"James": 95, "Jane": 98, "Matt": 85, "Ashely": 90}
sorted(a.items())
# output
[('Ashely', 90), ('James', 95), ('Jane', 98), ('Matt', 85)]
返回的数据结构是元组列表。每个元组包含两个值。第一个是关键,第二个是它的值。为了按值排序,我们需要使用排序函数的 key 参数,并指定按元组中的第二项排序。
a = {"James": 95, "Jane": 98, "Matt": 85, "Ashely": 90}
sorted(a.items(), key=lambda x:x[1])
# output
[('Matt', 85), ('Ashely', 90), ('James', 95), ('Jane', 98)]
如果我们需要将返回数据结构作为字典,我们可以使用 dict 构造函数。
a = {"James": 95, "Jane": 98, "Matt": 85, "Ashely": 90}
sorted_a = dict(sorted(a.items(), key=lambda x:x[1]))
sorted_a
# output
{'Matt': 85, 'Ashely': 90, 'James': 95, 'Jane': 98}
5.如何向字典中添加新键?
我们可以添加一个新的密钥,如下所示:
a = {"James": 95, "Jane": 98, "Matt": 85, "Ashely": 90}
a["Max"] = 100
a
# output
{'James': 95, 'Jane': 98, 'Matt': 85, 'Ashely': 90, 'Max': 100}
如果字典中已经存在该键,则用新值更新其值。
a = {"James": 95, "Jane": 98, "Matt": 85, "Ashely": 90}
a["James"] = 100
a
# output
{'James': 100, 'Jane': 98, 'Matt': 85, 'Ashely': 90}
6.检查字典中是否已经存在某个键
我们可以使用 keys 方法来访问字典的键。然后,我们可以检查字典键中是否存在给定的键,如下所示:
a = {"James": 95, "Jane": 98, "Matt": 85, "Ashely": 90}
keys_to_check = ["James", "Max", "Ashley"]
for key in keys_to_check:
print(key, key in a.keys())
# output
James True
Max False
Ashley False
7.如何在 Python 中以列表形式返回字典键?
在前一个问题中,我们了解到 keys 方法返回字典键。我们可以应用 list 构造函数来创建由 keys 方法返回的字典键列表。
a = {"James": 95, "Jane": 98, "Matt": 85, "Ashely": 90}
list(a.keys())
# output
['James', 'Jane', 'Matt', 'Ashely']
8.如何从独立的键和值列表中创建字典?
这可以通过使用 zip 函数和 dict 构造函数来完成。
names = ["James", "Jane", "Matt", "Ashley"]
grades = [95, 98, 85, 90]
grades_dict = dict(zip(names, grades))
grades_dict
# output
{'James': 95, 'Jane': 98, 'Matt': 85, 'Ashley': 90}
列表中出现的键和值是匹配的。
9.创建一本有理解力的词典
我们可以使用字典理解,这是一种使用 iterables 创建字典的方法。它类似于列表理解,只是语法略有不同。
列表和字典理解的基本结构如下:
(图片由作者提供)
我们来做一个例子。
words = ['data', 'science', 'machine', 'learning']
words_len_dict = {i:len(i) for i in words}
words_len_dict
# output
{'data': 4, 'science': 7, 'machine': 7, 'learning': 8}
键的表达式是“I ”,它表示单词列表中的项目。值的表达式是“len(i)”,它计算每个单词中的字符数。
10.用 Python 创建新字典
我们可以使用 dict 构造函数或者空花括号来创建一个空字典。
# dict constructor
a = dict()
type(a)
# output
dict
# curly braces
b = {}
type(b)
# output
dict
在撰写本文时,有 181,580 个关于堆栈溢出的问题被标记为 Python 字典。我们已经知道了这个庞大的列表和资源的前 10 个问题的答案。
你可以成为媒介会员来解锁我的作品的全部访问权限,以及媒介的其余部分。如果你已经是了,别忘了订阅如果你想在我发表新文章时收到电子邮件的话。
感谢您的阅读。如果您有任何反馈,请告诉我。
Python 中多元数据分析的 10 个必知的 Seaborn 可视化图
原文:https://towardsdatascience.com/10-must-know-seaborn-functions-for-multivariate-data-analysis-in-python-7ba94847b117
了解如何使用 Seaborn 的轴级和图形级绘图来可视化数据
由米卡·鲍梅斯特在 Unsplash 拍摄的照片
许多初学者课程专注于 Matplotlib 的可视化,原因是底层功能和定制每个情节细节的能力。但是,我发现自己陷入了所有的文档、社区讨论和许多创建简单情节的方法中,感谢上帝我找到了 Seaborn。
Seaborn 是一个建立在 Matplotlib 之上的接口,它使用几行简短的代码从 Pandas datafames 创建统计图表并设置其样式。它在引擎盖下利用了 Matplotlib,最好对图、轴、轴对象有一个基本的了解。
</8-seaborn-plots-for-univariate-exploratory-data-analysis-eda-in-python-9d280b6fe67f>
我们将使用来自 Kaggle 的车辆数据集,该数据集受开放数据库许可。下面的代码导入所需的库,设置样式,并加载数据集。
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as snssns.set_style('darkgrid')
sns.set(font_scale=1.3)cars = pd.read_csv('edited_cars.csv')
在我们继续之前,请注意 seaborn 地块属于两个组之一。
- 轴级 图 —这些图模仿 Matplotlib 图,可以使用
ax
参数捆绑成子图。它们返回一个 axes 对象,并使用普通的 Matplotlib 函数来设置样式。 - 人物级 图 —这些提供了一个围绕轴的包装图,只能创建有意义的相关支线图,因为它们控制整个人物。它们返回 FacetGrid 、 PairGrid 或 JointGrid 对象,并且不支持
ax
参数。他们使用不同的风格和定制输入。
对于每个情节,我会提到它属于哪一组。
第一部分:探索数字列之间的关系
数字要素包含连续数据或数值。
前两个图将是矩阵图,其中您传递整个数据框架以在一个图中可视化所有成对分布。
1.配对图
成对图创建散点图网格,以比较成对数值变量的分布。它还为对角线框中的每个特征提供了一个直方图。
要使用的功能:
sns.pairplot()
—图形级绘图
kind
参数改变用kind= ‘scatter’ (default)
、‘kde’, ‘hist’
或‘reg’
创建的二元图的类型。
每个网格两列(双变量)
sns.pairplot(cars);
需要注意的事项:
- 散点图显示正线性关系(如果 x 增加,y 增加)或负线性关系(如果 x 增加,y 减少)。
- 对角线框中的直方图显示了各个特征的分布。
在下面的配对图中,圆圈图显示了明显的线性关系。对角线指出了每个特征的直方图,pair 图的顶部三角形是底部的镜像。
作者的 Pairplot
三列(多变量):两个数字和一个分类
我们可以添加第三个变量,使用参数hue=’cat_col’
按颜色分割散点图。
sns.pairplot(
data=cars,
aspect=.85,
**hue='transmission'**);
作者的多元配对图
需要注意的事项:
- 散点图中不同颜色的簇。
2。热图
热图是网格中数值的颜色编码图形表示。遵循配对图是一个理想的图,因为绘制的值代表显示线性关系度量的配对的相关系数。
简而言之,配对图显示数据的直观趋势,而热图使用颜色绘制实际的相关值。
要使用的功能:
sns.heatmap()
—轴级绘图
首先,我们运行df.corr()
来获得相关系数表。该表也被称为相关矩阵。
cars.corr()
作者相关矩阵
**sns.heatmap()**
—由于上表不太直观,我们将创建一个热图。
sns.set(font_scale=1.15)
plt.figure(figsize=(8,4))sns.heatmap(
cars.corr(),
cmap='RdBu_r',
annot=True,
vmin=-1, vmax=1);
cmap=’RdBu_r’
设置颜色方案,annot=True
绘制单元格内的值,vmin
和vmax
确保颜色代码从-1 到 1 开始。
作者热图
需要注意的事项:
- 高度相关的特征。这些是暗红色和暗蓝色的细胞。接近 1 的值表示高度正线性关系,而接近-1 的值表示高度负线性关系。
图片来自www.statisticshowto.com
在下面的情节中,我们将进一步探讨这些关系。
3。散点图
一个散点图显示了两个数字特征之间的关系,使用点来可视化这些变量如何一起移动。
要使用的功能:
sns.scatterplot()
—轴级绘图sns.relplot(kind=’line’)
—图形级
有回归线的函数;
sns.regplot()
-轴级sns.lmplot()
—图形级
两个数字列(双变量)
[**sns.scatterplot(x='num_col1', y='num_col2', data=df)**](https://seaborn.pydata.org/generated/seaborn.scatterplot.html)
— 让我们用车辆的mileage
(效率)来形象化的描述engine size
。
sns.set(font_scale=1.3)sns.scatterplot(
x='engine_cc',
y='mileage_kmpl',
data=cars)plt.xlabel(
'Engine size in CC')
plt.ylabel(
'Fuel efficiency')
作者散点图
**sns.regplot(x, y, data)**
一个 reg 图 绘制一个散点图,用一条回归线表示数据的趋势。
sns.regplot(
x='engine_cc',
y='mileage_kmpl',
data=cars)plt.xlabel(
'Engine size in CC')
plt.ylabel(
'Fuel efficiency');
作者的回归图
三列(多变量):两个数字和一个分类。
**sns.scatterplot(x, y, data, hue='cat_col')**
— 我们可以使用hue
通过分类变量进一步分割散点图。
sns.scatterplot(
x='mileage_kmpl',
y='engine_cc',
data=cars,
palette='bright',
**hue='fuel'**);
由作者绘制的带色调的散点图
**sns.relplot(x, y, data, kind='scatter', hue='cat_col')**
相关图 或关系图用于使用kind=’scatter’
(默认)创建散点图,或使用kind=’line’.
创建线图
在我们下面的图中,我们使用kind='scatter'
和hue=’cat_col’
按颜色分段。请注意下图与上图的结果相似。
sns.relplot(
x='mileage_kmpl',
y='engine_cc',
data=cars,
palette='bright',
**kind='scatter',
hue='fuel'**);
由作者重新绘制
**sns.relplot(x, y, data, kind='scatter', col='cat_col')**
— 我们也可以使用col=’cat_col’
按列和/或row=’cat_col’
按行创建片段的支线剧情。下图按transmission
类别将数据分成不同的图。
sns.relplot(
x='year',
y='selling_price',
data=cars,
**kind='scatter',
col='transmission'**);
由作者重新绘制
四列:两个数字和两个分类。
**sns.relplot(x,y,data, hue='cat_col1', col='cat_col2') —**
col_wrap
参数在此宽度后换行,以便子情节跨越多行。
sns.relplot(
x='year',
y='selling_price',
data=cars,
palette='bright',
height=3, aspect=1.3,
**kind='scatter',
hue='transmission',
col='fuel',
col_wrap=2**);
按作者划分的关系散点图
**sns.lmplot(x, y, data, col='cat_col1', hue='cat_col2')**
lmplot 是 regplot 的图形级版本,它用回归线将散点图绘制到面网格上。它的没有有一个kind
参数。
sns.lmplot(
x="seats",
y="engine_cc",
data=cars,
palette='bright',
**col="transmission",
hue="fuel"**);
由作者绘制
4。线图
一个线图包括由一条线连接的点,显示 x 和 y 变量之间的关系。x 轴通常包含时间间隔,而 y 轴包含一个数值变量,我们希望跟踪它随时间的变化。
要使用的功能:
sns.lineplot()
—轴级绘图sns.relplot(kind=’line’)
—图形级绘图
两列(双变量):数字和时间序列。
**sns.lineplot(x=’time’, y=’num_col’, data=df)**
sns.lineplot(
x="year",
y="selling_price",
data=cars)
作者绘制的线图
三列(多变量):时间序列、数字和分类列。
**sns.lineplot(x, y, data, hue='cat_col')**
—我们可以通过使用hue.
的分类变量来拆分行
sns.lineplot(
x="year",
y="selling_price",
data=cars,
palette='bright',
**hue='fuel'**);
由作者绘制的带色调的线图
上述结果可通过使用sns.relplot
和 kind=’line’
以及hue
参数获得。
**sns.relplot(x, y, data, kind='line', col='cat_col')**
—如前所述,一个相关图的kind=’line’
参数绘制一个线形图。我们将使用 col=’transmission’
为两个传输类创建列方向的子图。
sns.relplot(
x="year",
y="selling_price",
data=cars,
color='blue', height=4
**kind='line',
col='transmission'**);
作者绘制的关系线图
四列:时间序列、数字和两个分类列。
**sns.relplot(x, y, data, kind='line', col='cat_col1', hue='cat_col2')**
sns.relplot(
x="year",
y="selling_price",
data=cars,
palette='bright',
height=4,
**kind='line',
col='transmission',
hue="fuel"**);
作者使用色调绘制的关系线图
5。联合地块
一个联合图由三个图表组成。中心包含 x 和 y 变量之间的二元关系。顶部和右侧的图分别显示了 x 轴和 y 轴变量的单变量分布。
要使用的功能:
sns.jointplot()
—图形级绘图
两列(双变量):两个数字
**sns.**[**jointplot**](https://seaborn.pydata.org/generated/seaborn.jointplot.html)**(x='num_col1, y='num_col2, data=df)**
—默认情况下,中心图是散点图,(kind=’scatter’)
,而侧边图是直方图。
sns.jointplot(
x='max_power_bhp',
y='selling_price',
data=cars);
作者联合策划
下图中的关节图利用了不同的kind
参数(‘kde’
、‘hist’
、‘hex’
或‘reg’)
,如每个图中所标注的。
作者使用不同“种类”参数的联合图
三列(多变量):两个数值,一个分类
**sns.jointplot(x, y, data, hue=’cat_col’)**
sns.jointplot(
x='selling_price',
y='max_power_bhp',
data=cars,
palette='bright',
**hue='transmission'**);
作者使用色调参数的联合绘图
第二部分:探索分类关系和数字关系之间的关系
在下面的图表中,x 轴表示分类变量,y 轴表示数值变量。
6.条形图
条形图使用不同高度的条形来比较数字变量在分类变量组之间的分布。
默认情况下,条形高度是使用“平均值”来估计的。estimator
参数通过使用 python 的内置函数如estimator=max
或len
或 NumPy 函数如np.max
和np.median
来改变这个聚合函数。
要使用的功能:
sns.barplot()
—轴级绘图sns.catplot(kind=’bar’)
—图形级绘图
两列(双变量):数字和分类
**sns.barplot(x=’cat_col’, y=’num_col’, data=df)**
sns.barplot(
x='fuel',
y='selling_price',
data=cars,
color='blue',
*# estimator=sum,
# estimator=np.median*);
作者柱状图
三列(多变量):两个分类列和一个数字列。
**sns.barplot(x, y, data, hue=’cat_col2')**
sns.barplot(
x='fuel',
y='selling_price',
data=cars,
palette='bright'
**hue='transmission'**);
带作者色调的条形图
**sns.catplot(x, y, data, kind='bar', hue=’cat**_**col'**)
一个 catplot 或分类图,使用kind
参数指定绘制什么分类图,选项为‘strip’
(默认)、’swarm’, ‘box’, ‘violin’, ‘boxen’, ‘point’
和‘bar’
。
下图使用 catplot 创建了一个与上图相似的图。
sns.catplot(
x='fuel',
y='selling_price',
data=cars,
palette='bright',
**kind='bar',
hue='transmission'**);
作者的带色调参数的条形图
四列:三个分类和一个数字
**sns.catplot(x, y, data, kind='bar', hue=’cat**_**col2', col='cat_col3') —**
使用col_wrap
参数在该宽度后换行,这样子情节就可以跨越多行。
g = sns.catplot(
x='fuel',
y='selling_price',
data=cars,
palette='bright',
height=3, aspect=1.3,
**kind='bar',
hue='transmission',
col ='seller_type',
col_wrap=2**)g.set_titles(
'Seller: {col_name}');
作者分类柱状图
7.点图
与条形图中的条形不同,点图绘制点来代表每个类别组的平均值(或另一个估计值)。然后用一条线将这些点连接起来,这样就很容易比较 y 变量的中心趋势在各组中是如何变化的。
要使用的功能:
sns.pointplot()
—轴级绘图sns.catplot(kind=’point’)
—图形级绘图
两列(双变量):一个分类列和一个数字列
**sns.pointplot(x=’cat_col’, y=’num_col’, data=df)**
sns.pointplot(
x='seller_type',
y='mileage_kmpl',
data=cars);
作者的点图
三列(多变量):两个分类和一个数字
当您使用hue
添加第三个类别时,点状图比条状图更能提供信息,因为每一个“色调”类都有一条线,这使得比较该类在 x 变量组中的变化变得更加容易。
**sns.catplot(x, y, data, kind='point', col='cat_col2')**
—这里,catplot 与kind=’point’
和hue=’cat_col’
一起使用。使用sns.pointplot
和hue
参数可以获得相同的结果。
sns.catplot(
x='transmission',
y='selling_price',
data=cars,
palette='bright',
**kind='point',
hue='seller_type'**);
作者分类点图
**sns.catplot(x, y, data, kind='point', col='cat_col2', hue='cat_col')**
—这里,我们在hue
和col
参数中使用相同的分类特征。
sns.catplot(
x='fuel',
y='year',
data=cars,
ci=None,
height=5, #default
aspect=.8,
**kind='point',
hue='owner',
col='owner',
col_wrap=3**);
作者使用色调和颜色的点图
8。箱形图
一个箱线图通过显示关于四分位数的信息来可视化数值和分类变量之间的分布。
作者的箱线图插图
从图中,您可以看到每个类别的最小值、中值、最大值和异常值。
要使用的功能:
sns.boxplot()
—轴级绘图sns.catplot(kind=’box’)
—图形级绘图
两列(双变量):一个分类列和一个数字列
**sns.boxplot(x=’cat_col’, y=’num_col’, data=df)**
sns.boxplot(
x='owner',
y='engine_cc',
data=cars,
color='blue')plt.xticks(rotation=45,
ha='right');
作者的箱线图
三列(多变量):两个分类和一个数字
**sns.boxplot(x, y, data, hue='cat_col2')**
—这些结果也可以通过sns.catplot
使用kind=’box’
和hue
重新创建。
sns.boxplot(
x='fuel',
y='max_power_bhp',
data=cars,
palette='bright',
**hue='transmission'**);
作者使用色调的箱线图
**sns.catplot(x, y, data, kind='box', col='cat_col2'**
) —将catplot
函数与kind=’box’
配合使用,并提供col
参数来创建支线剧情。
sns.catplot(
x='fuel',
y='max_power_bhp',
data=cars,
palette='bright',
**kind = 'box',
col='transmission'**);
按作者分类的箱线图
四列:三个分类和一个数字
**sns.catplot(x, y, data, kind='box', hue='cat_col2', col=’cat_col3')**
g = sns.catplot(
x='owner',
y='year',
data=cars,
palette='bright',
height=3, aspect=1.5,
**kind='box',
hue='transmission',
col='fuel',
col_wrap=2**)g.set_titles(
'Fuel: {col_name}');g.set_xticklabels(
rotation=45, ha='right')
按作者分类的箱线图
9。小提琴剧情
除了箱线图显示的四分位数外,小提琴图绘制了一个内核密度估计曲线,显示了不同区域的观察概率。
图片来自来源
要使用的功能:
sns.violinplot()
—轴级绘图sns.catplot(kind=’violin’)
—图形级绘图
两列(双变量):数字和分类。
**sns.violinplot**
( **x=’cat_col’, y=’num_col’, data=df**
)
sns.violinplot(
x='transmission',
y='engine_cc',
data=cars,
color='blue');
作者的小提琴情节
三列(多变量)—两个分类列和一个数字列。
**sns.catplot(x, y, data, kind='violin', hue='cat_col2')**
—通过kind=’violin’
和hue=’cat_col’
使用 catplot 功能。使用带有hue
参数的sns.violinplot
可以复制以下相同的结果。
g = sns.catplot(
x='owner',
y='year',
data=cars,
palette='bright',
height=3,
aspect=2
**split=False,
# split=True
kind='violin',
hue='transmission'**)g.set_xticklabels(
rotation=45,
ha='right')
violin plot 支持split
参数,该参数为每个分类类绘制一半的 violin plot。请注意,这在hue
变量只有和两个类时有效。
四列:三个分类和一个数字
**sns.catplot(x, y, data, kind='violin', hue='cat_col2', col=’cat_col3')**
—这里,我们只过滤‘diesel’
和‘petrol’
燃料类型的数据。
my_df = cars[cars['fuel'].isin(['Diesel','Petrol'])]g = sns.catplot(
x="owner",
y="engine_cc",
data=my_df,
palette='bright',
**kind = 'violin',
hue="transmission",
col = 'fuel'**)g.set_xticklabels(
rotation=90);
作者的小提琴情节
10.带状图
一个带状图使用点来显示一个数字变量是如何在一个分类变量的类别中分布的。把它想象成一个散点图,其中一个轴是分类特征。
要使用的功能:
sns.stripplot()
—轴级绘图sns.catplot(kind=’strip’)
—图形级绘图
两个变量(双变量):一个分类变量和一个数字变量
**sns.stripplot(x=’cat_col’, y=’num_col’, data=df)**
plt.figure(
figsize=(12, 6))sns.stripplot(
x='year',
y='km_driven',
data=cars,
linewidth=.5,
color='blue')plt.xticks(rotation=90);
作者的脱衣舞表演
三列(多变量):两个分类和一个数字
**sns.catplot(x, y, data, kind='strip', hue='cat_col2')**
—通过kind=’strip’
使用 catplot 函数(默认),并提供hue
参数。参数dodge=True
(默认为dodge=False
)可用于按颜色分隔垂直点。
sns.catplot(
x='seats',
y='km_driven',
data=cars,
palette='bright',
height=3,
aspect=2.5,
**# dodge=True,
kind='strip',
hue='transmission'**);
四列:三个分类和一个数字
**sns.catplot(x, y, data, kind='strip', hue='cat_col2', col='cat_col3')**
g = sns.catplot(
x="seller_type",
y="year",
data=cars,
palette='bright',
height=3, aspect=1.6,
**kind='strip',
hue='owner',
col='fuel',
col_wrap=2**)g.set_xticklabels(
rotation=45,
ha='right');
按作者分类的带状图
结合条形剧情和小提琴剧情
带状图可以与小提琴图或盒状图一起使用,以显示数据中缺口或异常值的位置。
g = sns.catplot(
x='seats',
y='mileage_kmpl',
data=cars,
palette='bright',
aspect=2,
**inner=None,
kind='violin'**)sns.stripplot(
x='seats',
y='mileage_kmpl',
data=cars,
color='k',
linewidth=0.2,
edgecolor='white',
**ax=g.ax**);
作者的连环漫画和小提琴情节
附加备注
- 对于条形图和箱线图等分类图,可以通过向上切换 x 和 y 变量,将条形方向重新定向为水平条形。
- 一起使用的 FacetGrid 人物级对象的
row
和col
参数可以给支线剧情增加另一个维度。然而,col_wrap 不能与 row 参数在一起。 - FacetGrid 支持不同的参数,具体取决于基础绘图。例如,
sns.catplot(kind=’violin’)
支持split
参数,而其他种类的不支持。本文档中有关于种类特定选项的更多信息。 - 数字级函数也创建二元图。例如,
sns.catplot(x=’fuel’, y=’mileage_cc’, data=cars, kind=’bar’)
创建一个基本的条形图。
结论
在本文中,我们对数据集进行了二元和多元分析。
我们首先创建了矩阵图,在网格中可视化关系,以识别具有高相关性的数字变量。然后,我们使用不同的轴级和数字级函数来创建图表,探索数字列和分类列之间的关系。在 GitHub 上的这里找到代码。
我希望你喜欢这篇文章。每当我发表文章时,想收到更多这样的消息,请在这里订阅。如果你还不是一个媒体成员,并且愿意支持我作为一个作家,跟随这个链接,我将赚取一小笔佣金。感谢您的阅读!
10 个熊猫查询示例,让你轻松使用熊猫查询
原文:https://towardsdatascience.com/10-pandas-query-examples-that-will-make-you-use-pandas-query-easily-12a45b1e115
数据科学
开始使用熊猫查询功能轻松过滤您的数据
由 cookie_studio 创作的滴咖啡照片——【www.freepik.com
主数据集过滤使用熊猫查询功能!
有了 Pandas 库,Python 中的数据分析变得很容易。在执行数据分析任务时,您通常需要选择数据子集进行深入研究。而这可以用熊猫轻松实现。DataFrame.query() 函数。
因此,了解如何高效和有效地利用它非常重要。
我列举了 10 个例子,解释了几乎所有可以使用查询函数过滤数据点的用例。最后,你将能够在需要的时候毫不费力地使用熊猫的查询功能。
您可以通过下面的索引快速跳转到您最喜欢的用例。
**·** [**Filtering using Single Condition**](#7fc6)
∘ [Example 1](#66c5)
**·** [**Filtering on Multiple Conditions**](#5a5d)
∘ [Example 1](#bd3d)
∘ [Example 2](#67af)
∘ [Example 3](#685e)
**·** [**Filtering based on Text Columns**](#7968)
∘ [Example 1](#1c2d)
**·** [**Simple Math Operation in Pandas Query**](#5d7e)
∘ [Example 1](#4280)
∘ [Example 2](#4b75)
**·** [**Built-In Functions in Pandas Query**](#1821)
∘ [Example 1](#2c05)
∘ [Example 2](#3165)
**·** [**Filtering based on Date-Time Columns**](#e832)
∘ [Example 1](#224c)
∘ [Example 2](#d651)
**·** [**Inplace in Pandas Query Function**](#ebb0)
📍注意:我使用的是自己创建的 Dummy_Sales_Data ,你可以在我的 Github repo 上免费获得MIT License!!
让我们将数据集导入熊猫数据框架— **df**
import pandas as pd
df = pd.read_csv("Dummy_Sales_Data_v1.csv")
df.head()
虚拟销售数据|作者图片
这是一个简单的 9999 x 12 的数据集,我用 Python 中的Faker创建的📚
你可以在本文末尾下载一个完整的笔记本,里面有所有这些例子!
在进入示例之前,快速回顾一下 pandas 中的查询功能—
Q 查询函数用于根据指定的表达式提取记录,并返回新的数据帧。表达式是以字符串形式书写的条件或条件组合。
在后端,使用 pandas 中的**eval()**
函数计算该表达式,并返回数据或记录的子集,其中表达式被计算为 TRUE 。
因此,要过滤 pandas DataFrame,您只需在查询函数中指定条件,您将在后续示例中看到这一点。
为什么要在熊猫数据帧
**.loc**
、**.iloc**
和括号**[ ]**
上使用**query()**
符号
- pandas DataFrame 属性——
**.loc**
和**.iloc**
——专门用于根据行和列标签和索引提取数据集的子集。因此,它并没有真正为您提供根据条件过滤数据帧的灵活性。 - 括号符号
**[ ]**
为您提供了根据条件过滤数据帧的灵活性,但是用多对方括号来编写在语法上是很庞大的
另一方面,pandas **query()**
函数为您提供了基于一个或多个条件提取数据帧子集的灵活性,这些条件被写成一个非常简单的表达式。您真的不需要考虑或检查任何丢失的括号!💯
现在,您知道了为什么应该使用 query()函数来过滤数据集,让我们从示例开始吧。
从最简单的用例开始—基于单个条件(即仅一列上的条件)过滤数据帧。
使用单一条件过滤
当过滤单个条件时,在query()
函数中待评估的表达式将只包含一个条件。并且返回的输出将包含该表达式计算为TRUE
的所有行。
示例 1
假设您想提取数量为 95 的所有行。所以逻辑形式的条件可以写成—
**Quantity == 95**
📌记住,你需要把这个条件写成一个字符串,也就是用双引号**“ ”**
把它括起来。
因此,您可以根据以下条件过滤数据帧—
**df.query("Quantity == 95")**
在 pandas 查询中使用单个条件进行过滤()|图片由作者提供
看起来很简单。它返回数量为 95 的所有行。
嗯,这很简单,你甚至可以像这样使用括号符号——**df[df[“Quantity”]==95]**
。****
但是,如果您想在同一列中再包含一个条件,该怎么办呢??
这无疑在括号符号中增加了一对方括号,使得它庞大并且从长远来看难以管理。这就是**query()**
的有效性开始显现的时候。**
根据多个条件过滤
无论您根据一个还是多个条件进行过滤,query()的语法都是相同的——通过将条件括在**“ ”**
中,将条件写成字符串。
但是,您必须指定如何基于两个或更多条件进行过滤,因此您可以从以下两个条件中选择一个:
**AND**
:只有两个条件都满足时,才返回数据帧中的所有记录**OR**
:返回数据帧中满足一个或两个条件的所有记录。
让我们用下面两个例子来看看它是如何工作的。
示例 1
假设,您想要选择两个条件(数量为 95,单价为 182)都为真的所有行。
所以,你应该选择AND
逻辑。在 query()表达式中,使用关键字**and**
实现。💯
注意,包含单价的列被命名为单价(美元)**
所以,条件是—
****Quantity == 95
UnitPrice(USD) == 182****
这个表达会变成—
****"Quantity == 95 and UnitPrice(USD) == 182"****
要提取所需的数据集,您需要编写—
****df.query("Quantity == 95 and UnitPrice(USD) == 182")****
然而,您得到的不是输出,而是关于‘单价’的 KeyError ,如下所示。🚨🚨
作者的列名|图像不一致时出现关键错误
但是为什么会出现这个错误呢??
这是因为,query()函数对列名有一些限制。并且列名单价(美元)在查询()中使用无效。
query()表达式将列名 UnitPrice(USD )中的 UnitPric e 解释为要对变量 USD 进行操作的函数。
📌query()guidelines为这个问题提供了一个快速的替代方法,将反勾号中的无效列名称为— **
UnitPrice(USD)**
所以你应该写的正确表达是—
****df.query("Quantity == 95 and `UnitPrice(USD)` == 182")****
按作者在查询()和逻辑|图像中筛选多个条件
如您所见,当这两个条件都满足时,只有 3 条记录。
然而,同样有可能你忘记提到一个反勾号,程序将抛出另一个语法错误。因此,一个最简单的解决方案是将 中的列名 修改如下—**
**df.rename(columns={**'UnitPrice(USD)':'UnitPrice'**,
'Shipping_Cost(USD)':'Shipping_Cost',
'Delivery_Time(Days)':'Delivery_Time'},
inplace=True)**
因此,您现在可以使用新的列名获得相同的输出,如下所示—
**df.query("Quantity == 95 and **UnitPrice == 182**")**
或者,您也可以使用与号运算符 **&**
获得相同的输出,如下所示**
**df.query("Quantity == 95 **&** UnitPrice == 182")**
你可以看到这是多么简单——你可以用简单的英语把表达写在纸上。
现在,让我们看看如何实现**OR**
逻辑。
示例 2
假设您希望获得至少满足上述一个条件的所有行。
你所需要做的就是在以下两个条件之间使用关键字**or**
—
****df.query("Quantity == 95 or UnitPrice == 182")****
根据多个条件或逻辑筛选|按作者筛选图像
它返回两个条件之一为真的所有行(见上图中的第 2 到第 5 行)以及两个条件都为真的行(第 1 行
这里也可以使用按位运算符**|**
来代替**or**
关键字。✅
更进一步,您还可以在 query()中使用**NOT**
逻辑,当 query 中的指定条件被评估为FALSE
时,它将返回所有记录。
示例 3
假设您想要获取所有数量不等于 95 的行。
最简单的答案是在表达式中的条件前使用**not**
关键字或否定运算符**~**
,如下所示。
****df.query("not (Quantity == 95)")****
在查询|作者图片中使用 NOT 逻辑进行过滤
正如您在输出中看到的,它包含了 Quantity 不为 95 的所有行。
此外,条件不必总是等于运算符,而是可以在定义条件时从**==**
、**!=**
、 **>**
、**<**
、**≥**
、 ≤ 中选择任意一个。
因此,在以下条件下使用不等运算符**!=**
,可以得到与NOT
逻辑相同的输出
**df.query("**Quantity != 95**")**
这将进一步节省您编写(可能会忘记结束)额外的圆括号的努力!从而简化了query()
的表述。
条件并不总是需要在数字列上。您始终可以基于非数字文本列来筛选数据点。
基于文本列的过滤
根据文本列进行筛选时,您的条件应该是将列名与字符串进行比较。
记住,你的
query()
表达式已经是字符串了。那么如何在另一个字符串中写一个字符串呢??
📌只需用单引号将您想要在条件中使用的文本值括起来,如**‘ ’**
。让我们看一个如何做到这一点的例子。
示例 1
假设,您想要获取状态为'未发货'的所有记录。你可以把这个用query()
表达式写成—
**df.query("Status == **'Not Shipped'**")**
按作者过滤文本栏|图像
它返回所有记录,其中 Status 列包含值— ' 未发货'。
同样,您可以在同一列或不同列上使用多个条件,它可以是数字列和非数字列上条件的组合。💯
在现实世界中,大多数时候,用于过滤数据帧的条件包括某些计算。Pandas query()允许您在查询表达式中自由使用数学。
熊猫查询中的简单数学运算
数学运算可以是任何东西,比如加、减、乘、除,甚至是列中某个值的平方或立方。
由于数学运算是用于数值的,所以只能在查询表达式中的数值列上使用,如下例所示。
示例 1
例如,假设当 double of shipping cost 小于 50 时,您希望从数据集中获取所有行。
这就像用简单的英语书写表达式一样简单,如下所示
**df.query("**Shipping_Cost*2** < 50")**
query()函数内的数学运算|作者图片
嘣!它返回所有需要的行。
您还可以在一列或多列中包含甚至有点复杂的计算。💯
示例 2
假设您希望得到所有数量的平方和运输成本的平方之和小于 500 的行。**
**df.query("**Quantity**2 + Shipping_Cost**2** < 500")**
query()函数中的复杂数学运算|作者图片
您可能已经注意到,使用 query()函数进行复杂的计算是多么简单。
但是,您并不仅限于使用不同的数学运算,而是可以在查询表达式中使用内置函数。
熊猫查询中的内置函数
Python 内置的函数如sqrt()
、abs()
、factorial()
、exp()
等可以很容易地在查询表达式中使用。您可以像在正常用例中一样直接使用它。
示例 1
检索单价的平方根大于 15 的所有行。因此这里将使用内置函数— sqrt()
。
**df.query(**"sqrt(UnitPrice) > 15"**)**
在 Pandas query()中使用内置函数|图片作者
很简单!该查询将返回单价超过 225 的所有行。
此外,query()函数非常灵活,您还可以在同一个查询表达式中使用内置函数和数学函数。
示例 2
获得所有单价的平方根小于一半运费的记录是如此简单,你可以用——
**df.query("**sqrt(UnitPrice) < Shipping_Cost/2**")**
数学和内置函数在查询表达式|作者图片中的组合
这样,您可以使用不同复杂程度的多个条件来过滤数据集。这也是使用一个简单的查询。✅
到目前为止,您观察到的所有查询示例都是关于数字和文本列的。但是,query()的用法并不仅限于这些数据类型。
通常,您需要根据日期时间值过滤数据帧。query()函数非常灵活,您可以根据日期和时间值轻松过滤数据集,这一点您可以在下一节中了解。
基于日期-时间列进行筛选
使用 query()函数根据日期时间值过滤数据帧的唯一要求是,包含这些值的列的数据类型应该是**datetime64[ns]**
✅
在我们的示例数据集中,OrderDate 列包含日期时间值,但它被解析为字符串值。您可以很容易地将该列转换成所需的数据类型,使用—
**df["OrderDate"] = **pd.to_datetime**(df["OrderDate"], format="%Y-%m-%d")**
现在,您已经准备好使用query()
中的日期-时间列过滤数据帧。要提取关于日期的有用信息并在 query()函数中使用它们,**dt**
访问器非常方便。
📌 dt 是一个访问器对象,用于提取日期时间序列的类似日期时间的属性。
让我们探索一下可以根据日期时间值过滤数据集的不同方法。
示例 1
假设您想要获取订单日期在八月份的所有记录。你需要做的就是—
**df.query("**OrderDate.dt.month == 8**")**
使用 query()中的日期筛选数据集|按作者排序的图像
如您所见,所有记录都有八月份的订单日期。**OrderDate.dt.month**
展示了如何使用**dt**
访问器从整个日期值中只提取月份。
进一步过滤,假设您想要获得 2021 年 8 月的所有订单,其中订单日为 15 或更多。你可以通过——
**df.query("**OrderDate.dt.month == 8 and OrderDate.dt.year == 2021 and OrderDate.dt.day >=15**")**
根据日期-时间变量的多个条件进行筛选|按作者排序的图片
尽管这是一个典型的**dt**
访问器的例子,并且在同一列上组合多个条件,但是这个表达式似乎太长了,因此不是一个好的实践。
编写它只是为了演示如何使用**dt**
操作符提取数据的不同部分,以及如何组合多个条件。
然而,您可以通过编写非常简单表达式得到完全相同的输出,如下所示
**df.query("**OrderDate >= '2021-08-15' and OrderDate <= '2021-08-31'**")**
此外,您还可以在单个表达式中组合日期-时间列上的条件和任何其他列上的条件。💯
示例 2
例如,检索订单日期为前一个示例且状态为 Delivered 的所有记录非常简单,查询表达式为
**df.query("**OrderDate >= '2021-08-15' and OrderDate <= '2021-08-31' and Status == 'Delivered'**")**
根据不同列的多个条件进行筛选|按作者排序的图片
它返回表达式计算为 True 的所有记录。同样,这只是一个演示如何在单个查询中组合日期-时间和文本列条件的示例。
到目前为止,您只指定了要在 query()函数中计算的表达式。然而,该函数还采用了另一个可选参数— **inplace**
就地熊猫查询功能
在所有示例中,您都可以看到 df.query()生成了一个新的数据帧。这是因为 query() — **inplace**
—的第二个参数默认设置为 False。
因此,即使在多个条件下过滤数据帧后,如果您检查数据帧的大小,它将显示 9999 x 12 的原始大小
****df.shape**# output
**(9999, 12)****
因此,使用**inplace=False**
,查询没有修改原始数据集。当你想改变原始数据帧时,只需点击inplace=True
。
🚨但是要小心使用 inplace=True
,因为它会覆盖原始数据帧。因此,一旦执行了带有此选项的查询,就没有机会恢复原始数据帧。
以上就是使用 query()过滤数据点的全部内容!
我希望你发现这篇文章非常有用,令人耳目一新,并且你学会了一些非常酷的过滤熊猫数据帧的技巧。我确信,读完这篇文章后,你会更频繁、更流利地使用 pandas query()函数。
过去 4 年多以来,我一直在使用 Python 进行数据分析,并发现 query()函数最便于过滤数据集。这些技巧中的大部分,我每天都在工作中使用。
有兴趣在媒体上阅读更多的故事吗??
💡考虑 成为媒体会员 到访问媒体上无限的故事和每日有趣的媒体文摘。我会得到你的费用的一小部分,没有额外的费用给你。
💡请务必 注册我的电子邮件列表 以免错过另一篇关于数据科学指南、技巧和提示、SQL 和 Python 的文章。
💡这里有一个完整的 笔记本 里面有所有的例子。
感谢您的阅读!
十年前在 StackOverflow 上问的 10 个熊猫问题在今天仍然适用
原文:https://towardsdatascience.com/10-pandas-questions-asked-a-decade-ago-on-stackoverflow-that-are-still-relevant-today-309430aa1919
重温熊猫的基本操作
照片由埃文·丹尼斯在 Unsplash 拍摄
随着越来越多的结构化表格数据的出现,对于这个时代的数据科学家来说,熟悉使用 Pandas 进行表格数据分析和管理是绝对必要的。虽然自学是获得专业知识的一个很好的方法,但有时,通过寻找他人面临问题的答案来跟随同伴学习也有助于自我成长。
因此,为了在这个方向上迈出一步并提高您的熊猫专业知识,在这篇博客文章中,我汇集并解决了 StackOverflow 上与熊猫相关的十大投票最多的问题,作为一名数据科学家,您必须知道如何解决这些问题。成为投票最多的问题之一凸显了数据科学界的普遍兴趣及其发展方向。
你可以在这里找到这篇文章的代码。下面提到了这篇文章的亮点:
[**Q1: How to iterate over rows in a DataFrame in Pandas?**](#59ff)[**Q2: How do I select rows from a DataFrame based on column values?**](#2b64)[**Q3: Renaming column names in Pandas**](#0c5a)[**Q4: Delete a column from a Pandas DataFrame**](#71bb)[**Q5: How do I get the row count of a Pandas DataFrame?**](#0330)[**Q6: Selecting multiple columns in a Pandas dataframe**](#0bf7)[**Q7: How to change the order of DataFrame columns?**](#9683)[**Q8: Change column type in pandas**](#23f2)[**Q9: Get a list from Pandas DataFrame column headers**](#7be5)[**Q10: Create a Pandas Dataframe by appending one row at a time**](#e389)
我们开始吧🚀!
**注意:**下面提到的解决方案描述了我自己解决这些问题的方法,并没有从任何来源复制。而且 StackOverflow 上所有用户生成的内容都是授权商业使用的(CC BY 4.0),可以免费使用。
Q1:如何在 Pandas 中迭代数据帧中的行?
迭代(也称为循环)是单独访问数据帧中的每一行并执行一些操作。
考虑下面的数据框架:
在熊猫中,你可以用三种不同的方式迭代,使用range(len(df))
、iterrows()
和itertuples()
。
我在下面的博文中详细讨论了迭代数据帧的不同方法:
Q2:我如何根据列值从数据框中选择行?
此问题旨在了解如何根据条件过滤数据帧。要了解常用的过滤方法,请考虑下面的数据框架:
过滤数据帧的一些方法实现如下:
上面使用的[isin()](https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.isin.html)
方法接受一个过滤器值列表。另一方面, query() 方法计算一个字符串表达式来过滤数据帧中的行。
Q3:重命名 Pandas 中的列名
这里的目标是更改列标题的名称。考虑与上面相同的数据帧。
我们可以使用[rename()](https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.rename.html)
方法将col1
的名称改为col3
,如下所示:
这里,原始数据帧保持不变。如果不想创建新的数据帧,使用如下所示的inplace=True
:
使用rename()
方法时,您需要创建一个从old-column-name
到new-column-name
的映射作为字典。如果列名保持不变,则不需要在字典中指定它。
Q4:从熊猫数据帧中删除一列
要从 DataFrame 中删除一列或多列,可以使用 drop()方法,并将要删除的列作为列表传递。这在下面的Method 1
和Method 2
中显示。或者,如Method 3
所示,您可以选择想要在最终数据帧中保留的列子集。
drop()
方法的语法类似于rename()
的语法,唯一的区别是columns
参数接受要删除的列的列表。
问题 5:我如何获得熊猫数据帧的行数?
这个问题围绕着了解熊猫数据帧的形状。要回答这个问题,请考虑以下三行两列的数据帧:
要找到形状,使用 DataFrame 的shape
属性,如下所示:
属性返回一个python
元组。第一个元素对应于行数,第二个元素表示列数。
Q6:在熊猫数据框架中选择多列
这里要实现的目标是从数据帧中选择一个以上的列进行进一步处理。例如,如果原始数据帧包含三列,即col1
、col2
和col3
,如何仅选择col1
和col3
。
有两种方法可以做到这一点:
iloc
中的列表[0,2]
解释为位于第 0(col1
)和第 2(col3
)索引的列。你可以在这里阅读更多关于iloc
的内容。
Q7:如何改变 DataFrame 列的顺序?
改变数据帧中列的顺序指的是在不改变列的数量(或数据帧的形状)的情况下重新排列列。
考虑下面的数据框架。目标是将列排列为col1
- col2
- col3
。
有两种方法可以做到:
iloc
中的列表[2,0,1]
解释为位于第 2(col1
)、第 0(col2
)和第 1(col3
)索引的列。
Q8:更改熊猫中的列类型
通过这个问题,目的是知道如何改变一个列的数据类型。考虑下面的数据帧,其中col1
将整数值保存为字符串。
col1
的当前数据类型为object
(与string
相同)。目的是将col1
的数据类型从string
更改为integer
。您可以按如下方式更改数据类型:
如果不想创建列,可以将新值存储在同一列中,如下所示:
使用astype()
方法时,必须确保从源数据类型到目标数据类型的类型转换是可行的。例如,您不能将字母的string
列转换为integer
或float
数据类型。
Q9:从 Pandas DataFrame 列标题中获取列表
这里的目标是以列表的形式获取数据帧中所有列的名称。考虑下面的数据框架:
要获得列的列表,使用如下所示的columns
属性:
上面的代码将列作为索引对象返回。要以列表形式获取它,请将获得的结果转换为列表:
Q10:通过一次追加一行来创建一个熊猫数据帧
在这个问题中,目标是一次将一行追加到原来为空的数据帧中。假设您有以下空数据帧和一个列表列表data
,其中每个单独的子列表将作为一行添加到数据帧中。
为了一次追加一行,我们必须遍历data
列表并添加一个新行,如下所示:
如上文 Q5 中所讨论的,由shape
属性返回的元组的第一个元素表示数据帧中的行数。因此,添加到数据帧的每个新行都确保为下一行创建新索引。
总之,在这篇文章中,我解决了 StackOverflow 上熊猫类的十个投票最高的问题。如果你愿意进一步解决列表中的问题,我认为你应该这样做,你可以在这里找到它们。
或者,如果你想在熊猫中练习一些具有挑战性的问题,可以参考下面我之前的两篇博文来练习熊猫。
有兴趣在媒体上阅读更多这样的故事吗??
✉️ 注册我的电子邮件列表 不要错过另一篇关于数据科学指南、技巧和提示、机器学习、SQL、Python 等的文章。Medium 会将我的下一篇文章直接发送到你的收件箱。
感谢阅读!
给新数据科学毕业生的 10 条单句求职建议
原文:https://towardsdatascience.com/10-pieces-of-single-sentence-job-advice-for-new-data-science-graduates-ffbca3454df2
意见
将这些简单的建议放在手边,帮助你成为一名成功的数据科学家
在 Unsplash 上由михалавленко拍摄的照片
你做到了。
你毕业了/完成了训练营/获得了证书/自学了,现在,你终于成为了一名数据科学家。经过几个月或几年的疲惫,你可以正式称自己为数据科学家,并开始申请数据科学的工作。
你的辛勤工作和努力是值得的,现在你可以利用这些技能,开始在一家公司产生影响。
不过,现在是时候吸收更多一点的信息了。你的大脑被塞满了,但是这个拥有多年经验的数据科学家社区想与你分享一些东西:给新数据科学毕业生的一句话工作建议。在这里,你会发现 10 条小建议永远放在你的后口袋里,这将有助于你在数据科学家的职业生涯中取得成功。
1.硬技能让你获得面试,软技能让你获得工作
当 500 名新的数据科学家申请同一个入门级职位时,你认为是什么让一名成功的候选人与众不同?
是他们通过复杂分析思考的能力?也许吧。
是他们建立机器学习模型的速度比其他人都快吗?也许吧。
他们是否有能力将公司正在寻找的硬技能和软技能结合起来,使他们成为团队的合适人选?事实上,是的。这正是数据科学家与众不同的地方。
当与 500 名其他候选人竞争一个数据科学职位时,可以假设每个人都或多或少地拥有一家公司正在寻找的合适的硬技能,如编码、数学以及构建机器学习和人工智能模型的能力。
但是,大家没有的,是软技能。团队合作、沟通、阅读、写作、理解、解决问题、做出关键决策以及明智地管理时间的能力都是让你获得这份工作的软技能。这些技能使你从所有候选人中脱颖而出,并成为公司的宝贵财富。
2.你不会总是有正确的数据来解决问题
在大学里,你总会有一个合适的数据集来解决你被分配的问题。
在训练营中,干净整洁的数据集将帮助你发展技能。
通过你自己的个人项目,你会发现网上有数百个数据集,其中包含数以千计的完整条目,你可以用它们来开发一些非常复杂的项目。
然而,当你进入现实世界时,你会意识到,通常情况下,这些数据很糟糕。无论数据集是不完整的、太小的还是有太多离群值而无法做出具体决策的,现实世界的数据通常都是您要完成的分析的关键。
这没关系。糟糕的数据是生活中的事实,你只能期望用你被赋予的工作来开发尽可能精确的分析。
3.你将被要求建立一个模型来解决一个没有人真正理解的问题
在学校或训练营使用数据科学解决问题是一回事。在那里,你“为之工作”的人对数据科学以及给定特定数据集下你能解决和不能解决的问题类型有很好的理解。他们会给你明确的问题,让你着手解决,并且真正有意义。
在现实世界中,很可能某个 C 级高管希望您的数据科学团队构建一个模型或开发一种分析来解决一个没有人真正理解的问题。对那些坐在高管桌旁的人来说,似乎存在某种问题,但实际问题是什么,没人能说得很清楚。
随着时间的推移,数据科学工作的这一方面将成为你工作的另一部分。你的工作是帮助那些高管更清楚地了解他们对问题的看法,并向他们解释你认为如何解决问题。简单明了。不要重新发明轮子或竭尽全力试图从无到有。你的工作只是帮助他们理解使用数据。
4.保留一张你的成就的“自吹自擂表”,以帮助职业发展和进步
一份【自吹自擂表】可以是你简历上的补充内容,也可以是贴在显示器底部的便利贴。
本质上,这应该是你列出你在职业生涯中积累的成就的地方。
也许你开发了一个模型,发现了你公司报告策略中的错误,这帮助他们发现了他们的真实数字。或者你找到了更长时间吸引网站用户注意力并降低网站跳出率的方法。或者,你可能开发了一个人工智能模型,它可以学习皮肤癌的特定趋势,用于帮助医生将诊断的准确性提高 17%。
无论你取得了什么样的成就,或者对你的公司或组织产生了什么样的影响,记录你在职业生涯中的所作所为都是非常重要的。当你第一次开始时,这将有助于你在困难时期保持动力,当你已经有了几年的经验,这将有助于你在职业生涯的剩余时间里取得进步。
5.你用类比建立概念联系的能力将是你所拥有的最好的技能之一
数据科学家的独特之处在于,他们需要能够用公司中任何人都能理解的简单术语来解释残酷的技术概念。
实现这一点的最佳技巧是培养使用类比来建立概念之间的联系的能力。类比是一种很好的方式,可以从一开始就以一种容易消化和理解的方式清晰地表达一个复杂的想法。这些类比应该与你所在的公司或行业相关,并且应该提供足够的信息,让高管们有信心根据他们的理解做出决定。
类比应该避免使用数据科学术语,并且足够简短,便于记忆。
以我的经验来看,创造人们能够理解的类比,对于你能够成功地用数据解释公司内部发生的事情至关重要。我用运动类比、烹饪类比、动物类比等等来帮助人们理解我试图告诉他们的技术概念。这些类比不仅有助于想法留在利益相关者的脑海中,而且也是利益相关者用来传播你的信息的工具。
6.简单点,笨蛋
这个首字母缩略词会一直出现,不管你是多久前第一次学习数据科学时学到的。来自编码领域,这个缩写可能比任何其他建议更有助于你的职业发展。
当你能让事情变得简单时,为什么要让它变得复杂呢?当然,用两行代码清理数据的复杂模型给你的老板留下深刻印象是不错的。但是,如果你开发了一个在你离开公司后可以容易理解、更新、集成和使用的模型,难道不会给他们留下更深刻的印象吗?
你可能在开始职业生涯时认为,工作的复杂性是与公司保持联系的唯一途径。然而,你以简单的方式按时完成工作的能力,可以被任何人使用,并产生所追求的确切结果,这将使你保持相关性。此外,你不断学习和提高技能的能力也将使你成为团队中有价值的一员。
如果你喜欢复杂,只要确保你先和你的老板确认一下,看看这个项目是否适合你全力以赴。
否则,保持简单,保持干净,保持简单易懂。
7.你希望你老板的老板对你印象深刻,但仍然有点理解
公平地说,要打动一位没有广泛技术经验的 C 级高管并不难。重要的是要记住,当像他们的调制解调器这样简单的东西被重置时,这些人通常很容易感激。
然而,总有一天你会想要给人留下特别深刻的印象。这种给人留下深刻印象的需要也必须与老板的老板仍然能够理解你做了什么或解决了什么相平衡。
同样,如上所述,这可能涉及开发一个复杂的模型来解决一个仍然可以用简单术语描述的难题。你想给你老板的老板留下深刻印象,但仍然让他们能够理解你给公司带来的影响。
当有疑问时,给图表添加颜色,尝试直方图而不是条形图,使用像“机器学习”和“人工智能”这样的词来打动人,而不要泄露太多细节。记住,可以说 90%的数据科学都是简单的线性回归,你可能只需要稍微修饰一下。
8.低估和过度兑现仍将是你最有价值的资产
数据科学家经常被赋予不可能完成的任务——用不存在的数据完成一次数据分析,开发一个解决公司问题的机器学习模型,或者将新模型整合到一个自 2005 年以来从未被触及的代码库中。
许多人将数据科学家视为各行各业的高手(我们就是),他们可以利用数据解决任何公司问题(而我们不能)。这意味着,当我们接到一个业务问题并被告知要在周末之前解决它时,风险是很高的。不幸的是,不是所有的问题都可以通过在伤口上贴线性回归绷带来解决。
因此,最好是谨慎行事,对你所相信的在你所拥有的工具和条件下可以实现的事情持保守态度。当事情按计划进行时,表现不足会拯救你;当事情出乎意料地顺利时,表现过度会让你的老板和老板的老板喜欢你。
9.要勤于命名你的变量和注释你的代码
“只有你和上帝能读懂你的代码,而你离上帝只有一步之遥。”— TheDragonSpark,r/data sciencee
编写优秀的代码并不是用最少的代码行完成最多的工作。这是关于能够阅读和理解你在一个长周末外出后的星期五写的代码。这是关于能够把你的代码交给五年后的实习生,让他们能够理解并优化它。这是关于能够在一家公司留下易于使用的代码,而不会导致不满的数据科学家在奇怪的时间打电话给你寻求帮助。
除了给变量命名为x
、y
和z
之外,还要更进一步。相反,应该使用描述性的名称,确切地告诉你一个变量包含什么,以及当它与另一个变量组合时应该产生什么结果。
命名你的函数,准确描述它们的功能。
使用注释来澄清任何令人困惑的行、逻辑或你必须深入 StackOverflow 的地方。
使用 READ.me 文件可以清楚地了解您的思维过程、代码的目标,以及它应该如何以及为什么工作。
勤于准确命名变量和使用注释将会让你在数据科学家的职业生涯中走得更远。
10.随着“数据科学家”的工作头衔包含大量的技能,你经历冒名顶替综合症是正常的
大多数数据科学家都不擅长写好代码(与软件工程师相比)。
大多数数据科学家都不擅长数学(与数学家相比)。
大多数数据科学家都不擅长建模(与机器学习开发者相比)。
这就是数据科学家的独特之处,因为我们拥有这些专业的能力,即使他们来自完全不同的领域,也能出色地完成任务。
冒名顶替综合症在数据科学家中非常普遍,每个人都期望你成为软件工程师、数学家、机器学习开发者、商业分析师、平面设计师、项目经理等等。因此,重要的是要提醒自己,你擅长所有这些技能,但没有必要成为每一项技能的专家。如果公司想要一个统计学家,他们会雇佣一个统计学家。相反,他们雇佣你是因为你拥有多种多样的技能,这使你成为一个完整的人,能够完成上面列出的每一项任务,甚至更多。
订阅将我的故事直接发送到您的收件箱:故事订阅
请成为会员,使用我的推荐链接获得无限制的媒体访问权限(我将收取少量佣金,无需额外费用):媒体会员
通过捐款来支持我的写作,以资助更多像这样的故事的创作:捐款
帮助你在 2022 年开始数据科学学习的 10 篇文章
原文:https://towardsdatascience.com/10-posts-to-help-you-kick-off-your-data-science-learning-in-2022-7fadf8647c23
大家新年快乐!一月初是采取大胆措施、制定雄心勃勃的计划、一头扎进新的挑战和兴趣的好时机。为了帮助你做到这一切,我们今年的第一期可变版精选了 10 篇我们认为特别有活力和有用的文章。让我们开始吧!
- **您是否刚刚开始学习数据科学?**成为一名全职数据科学家是你 2022 年工作清单上的一个关键项目,但你不知道从哪里开始?为了帮助你迈出第一步,我们在最新的月刊中为初学者和学习者编辑了一些最受欢迎的资源。
- 提升你的沟通技巧 。根据 Rose Day 的说法,数据科学家经常弥合技术和非技术利益相关者之间的差距,这正是他们应该专注于有效的、上下文驱动的沟通的原因。
- 充分利用你的未标注数据 。如果你正准备进行一次将理论与实际应用相结合的深度探索,那么只需看看 Betty LD 最近关于不确定性、智能采样以及从可用数据中获取最大价值的文章。
照片由Match sàmàyà在 Unsplash 上拍摄
- 赶上最近图机器学习的趋势 。作为机器学习研究中最具活力的领域之一,人们很容易迷失在 graph ML 的所有最新发展中。迈克尔·高尔金来拯救我们了,他对这个领域的现状进行了全面、有力的概述。
- 更具“表现力”的 gnn 会是什么样子? 谈到图 ML,如果你想在这个不断发展的子领域中放大更具体的主题,不要错过 Michael Bronstein 的最新文章,其中涵盖了在一组子图中应用图神经网络(GNNs)的几种最新方法。
- 探索支撑 BERT 等大型语言模型提炼的理论。LLM 已经风靡了一段时间,但是培训它们需要大量的资源。在他的最新帖子中, Remi Ouazan Reboul 向我们介绍了蒸馏技术,这些技术为蒸馏 BERT 提供了动力,并减少了与 BERT 类模型相关的一些时间和成本。
- 在求职过程中脱颖而出 。在您未来几个月的路线图中,是否在寻找一个新的或更好的数据科学角色?艾玛丁(Emma Ding)最近分享了她在产品案例面试阶段应该做和不应该做的事情,你可能现在就想看(并保存下来以备将来参考)。
- 给你的工具箱 再添加一个可视化资源。如果你正在寻找一些更实际的东西来开始你的一年,你不能错过 Parul Pandey 的最新教程,它解释了如何可视化决策树并使用开源包 Pybaobabdt 解释你的模型。
- Up 你的算法驱动的预测游戏 。仍然在实践学习的领域, Christophe Brown 的最新文章介绍了支持向量机算法,并展示了如何在 NBA 比赛仍在进行时用它来预测比赛结果。
- 增长你对 ML 可解释性的理解 。2022 年,模型可解释性将继续成为数据科学家和 ML 实践者工作中的一个关键因素;阅读 Robert Kübler 博士的最新文章将帮助你使用 PyTorch 构建可通过设计解释的前馈神经网络。
感谢您在短暂的假期暂停后再次加入我们,我们希望您的一年有一个好的开始!
加入 TDS 会不会更好?如果你对数据科学和优秀的写作充满热情,请查看我们目前的职位空缺:我们希望招聘一名完全远程的加拿大高级编辑,如果你认为你非常适合这个角色,我们很乐意听取你的意见。
直到下一个变量,
TDS 编辑器
对 2030 年客户数据平台(CDP)的 10 个预测
原文:https://towardsdatascience.com/10-predictions-for-customer-data-platforms-cdps-in-2030-6f4e3c447caf
到 2030 年,新兴趋势将如何改变 CDP
在我的软件和数据职业生涯中,我经历了惨痛的教训,认识到设计和管理卓越的客户体验是非常困难的。没有两个客户体验是相同的,他们都有自己独特的背景故事。每当我们试图线性地简化和模拟体验时,我们总是做不到。客户很少遵循“一条路”;每一个顾客带着不同的背景、不同的奋斗和通过不同的媒介接触到你的产品或服务。
客户数据平台(CDP)的最新发展——从部门到方向舵栈——开始解决这些问题。但我认为,随着我们越来越接近提供出色、愉快的客户体验这一最终目标,还有很多事情要做。在这篇文章中,我将描绘一幅我希望并期待在 2030 年从 CDP 中看到的画面。我将解释什么是 CDP,并提供额外的数据环境背景,然后开始我的预测(期望?)2030 年。
照片由 Edge2Edge 媒体在 Unsplash 上拍摄
那么什么是 CDP 呢?
让我们先把定义放在一边。什么是客户数据平台?CDP Institute 的创始人 David Raab 在他 2013 年发表的名为的博客中描述道,我发现了一个新的系统类别:客户数据平台—
…从多个来源收集客户数据、合并与相同个人相关的信息、对生成的数据库执行预测分析,并使用结果指导多渠道营销处理的系统。 — 大卫·拉布 ,CDP 研究所创始人
CDP 研究所给出了一个更简洁的定义:
…打包的软件,可创建其他系统可访问的持久、统一的客户数据库。 — CDP 研究院
这里的“打包软件”指的是预构建的软件,这些软件可以在没有管理数据仓库所需的专业技术水平的情况下进行设置和维护。“持久、统一的客户数据库”是指 CDPs 的主要价值主张,即能够将来自多个来源的事件关联到单个用户配置文件。换句话说,CDP 将客户旅程中的所有接触点都绑定到一个用户配置文件。“可供其他系统访问”可确保 CDP 不会封闭在孤岛中,并且可以随时部署见解。CDP 的这些特性,至少在理论上,允许我们跟踪单个客户从第一次接触到购买的整个过程。
我们今天所处的位置…
在过去的几年里,我们看到了在了解客户和获取数据以改善客户体验方面取得的巨大进步。我们已经慢慢但肯定地摆脱了谷歌分析(Google Analytics)之类的聚合性质,并开始整理来自各种来源的大量数据,以建立有意义的客户档案。在 2010 年初,当我们有太多的分析软件涌现时——世界的 Mixpanels 和 Amplitudes——Segment的扇出架构是一股新鲜空气,它整合了当时分散的数据收集。Segment 创建了一个单一界面,通过该界面可以从各种数据源中捕获数据点。我们在 Segment 中插入了 Full Story、Mixpanel 和一系列其他工具,这样我们就可以开始创建一个更全面、多角度的客户视图。随着大量数据流经 Segment,漂亮的功能出现了,例如数据回放,让我们可以将历史数据回放到其他 SaaS 工具。存储在细分市场中的粒度数据还允许我们构建“人物角色”,并逐个事件地跟踪客户旅程。2020 年,Segment 被 Twilio 以 32 亿美元[ * ]收购,这对于一家 YC 初创公司来说是一个惊人的壮举,这家公司最初陷入困境,并在 2012 年几乎退出,后来凭借他们的成功的黑客新闻帖子取得了突破。
斯蒂芬·道森在 Unsplash 上拍摄的照片
在 Segment 稳步增长的同时,一个新的流行词“现代数据堆栈”(MDS)也开始流行。MDS 是一组云工具,它们共同形成了一个以云数据仓库为中心的数据平台。一个典型的 MDS 星座可能看起来是这样的: Fivetran 从各种数据源收集数据(数据整合);AWS Kinesis 提供实时数据的主干(数据流); AWS S3 存储原始数据(数据湖);DBT 对数据进行转换和建模(数据转换); AWS 红移充当中央数据仓库。一些平台如 Snowflake 将这些价值主张打包成一个服务。最近,我们看到反向提取-转换-加载(ETL)工具,如 Hightouch ,加入了 MDS 生态系统。这些工具从数据仓库中提取丰富的客户洞察,并将它们直接放入销售、营销和运营使用的工具中。数据仓库位于中间的 MDS 星座已经变得越来越普遍,因为托管自己的数据仓库已经变得非常便宜。这一趋势意味着,即使是初创公司——我职业生涯的大部分时间都在这里度过——现在也能负担得起存储大量粒度数据并从中获得洞察力。对于数据来说,这是一个彗星撞地球的时刻:当托管数据仓库变得可以忽略不计时,即使是最小的企业也能提供出色的客户体验。这太令人兴奋了!
正是在这种背景下,像 Rudderstack 这样的公司正在寻找新的、以数据仓库为中心的角度来收集和管理客户数据。像 Segment 一样,它从各种来源收集数据,并将数据点传送到流行的目标平台,在这些平台上可以操作数据。但是,Rudderstack 给了你更多的控制权,并且是以仓库为中心的:你可以自带雪花、Google BigQuery 或者 AWS Redshift 等数据仓库;身份解析可以在你自己的仓库附近完成。
像这样的新解决方案不断涌现,因为我们不断改进我们的解决方案,以解决检测和减轻客户问题以及发现新机会的老问题。
2030 年会有什么?
有了背景知识,让我们开始对 2030 年的预测。有些是相对明显的预测,我们在不久前已经看到了一些证据。但其他预测将是纯粹的“空中手指”推断,今天看起来可能很怪异,但在不太遥远的将来可能会成为现实!没有办法完全确定,但我愿意打赌,其中一些赌注不会太远。这里有一个总结:
- 仓库是你的 CDP
- 无服务器将削减成本,让以仓库为中心的 CDP 无处不在
- 无代码事件将进一步增加客户数据量
- CDP 将服务于营销和数据团队
- 身份解析将是确定性的,但对于某些用例是概率性的
- 指标层将成为标准,CDP 将从中受益
- SQL 将大行其道
- DataOps 工具将确保 10 倍的数据可信度
- 个性化,就像你设计的一样
- 客户洞察触手可及,边缘仓库
请允许我在下面深入解释一下。
1.仓库是你的 CDP
这可能是最明显的。我们已经看到以仓库为中心的基础设施,如 Rudderstack 。Hightouch 主张将仓库变成新的 CDP 。如果您的 CDP 是孤立的,处于“专有”墙的后面,那么对您的数据的控制和查询您自己的客户数据的能力都会受到限制。在数据仓库生态系统尚不成熟的时期,今天的一些 CDP 演变成了孤岛。一体化解决方案很有意义。
但是在未来,随着 MDS 生态系统的成熟,我们将会看到更多强大的工具建立在仓库之上。随着仓库每年变得越来越便宜,定制的机器学习模型变得越来越容易部署在你自己的数据上,几乎不用想,人们就会涌向你可以找到最佳见解的地方:以仓库为中心的 CDP。
2.无服务器将削减成本,使以仓库为中心的 CDP 无处不在
无服务器的兴起及其在仓储领域的到来——如雪花、谷歌 BigQuery 和 AWS Redshift 无服务器——使仓储变得更加容易,因为你可以根据你使用数据仓库的时间来支付费用。这将意味着更多的企业能够负担仓储,当然还有以仓库为中心的 CDP。
随着无服务器技术变得越来越快,我们应该(希望如此!)也可以看到无服务器仓储的性能改进。事实上,2021 年细分市场生态系统中增长最快的应用是 BigQuery 和 Snowflake [ Segment ],因此这一趋势对于那些密切关注该领域的人来说可能不会感到惊讶。
3.无代码事件将进一步增加客户数据量
团队 Xperian 在 Unsplash 上的照片
没有代码,没有代码。我非常相信无代码软件可以将以前需要工程师来实现的标准业务流程自动化。连接 Stripe、HubSpot 和 Slack 从未如此简单,无代码软件如 Zapier 和 Make (以前的 Integromat)将继续使 SaaS 软件更容易缝合在一起。当然,这种趋势的第二个影响是事件的数量将会大量增加。我们刚刚开始看到后端服务器突破最受欢迎的数据源(参见部门的 2021 年 CDP 报告),我预计无代码将导致后端粒度事件量爆炸式增长。随着无代码执行的每个新的 API 调用和 webhook,我们将有更多的数据点可以发送到我们的仓库来提取洞察力。
让我们考虑一个例子:你的客户玛丽通过你在博客上写的一篇文章发现了你的服务;她注册了你的时事通讯,这引发了一系列点滴式的电子邮件;再往下,她会购买你的电子商务产品;她收到一封确认电子邮件;产品被发送给她;她收到产品并第一次使用它;有一个问题,她通过支持台投诉。所有这些交互都将由无代码集成提供支持,并发出将由以仓库为中心的 CDP 处理的数据点。数据点甚至可以通过机器学习(例如 NLP)算法来向数据添加进一步的上下文。CDP 需要确保 Convertkit 电子邮件、Stripe 客户、邮戳电子邮件、Shopify 客户和 Zendesk 请求者都与单个用户配置文件(Mary 的)相关联。
CDP 将是确保支持代理在处理客户投诉时拥有完整的客户旅程和背景的关键。随着无代码事件越来越多,对身份解析和 CDP 的需求也会越来越大。
4.CDP 将服务于营销和数据团队
这是一个相当直接的预测,几乎不需要解释。CDP 最初是一种营销工具,用于整合不同来源的数据点,并使事件跟踪计划更易于开发人员管理。但是,要真正利用您的数据并提取可以插入 CRM 和帮助台的见解,您需要让您的数据团队参与进来。
以仓库为中心的 CDP 将使客户体验成为真正的多学科努力。最好的企业不会是那些只使用由孤岛式 CDP 提供的现成通用客户模型的企业,而是那些在其以仓库为中心的 CDP 中拥有定制客户旅程模型的企业。与 CDP 集成的逆向 ETL 工具(或更进一步,如 Hightouch )无疑将扩展到金融和其他运营用例[ Mikkel Dengsoe ]。
5.对于某些用例,身份解析将是确定性的,但也是概率性的
要使身份解析真正发挥作用并获得客户的完整资料,您需要控制您的身份图。身份图需要靠近你的仓库,我们已经在方向舵栈等地方看到了这种趋势。但是,由于客户在旅途中可能会有大量的接触点,用基于规则的算法将用户资料拼接在一起会有限制。随着隐私趋势和接触点的爆炸,这个问题只会变得更加困难。在某一点上,一个概率(机器学习?)模型将需要解决大规模的单个用户简档的客户交互。虽然这在原则上听起来很棒,但概率身份解析伴随着风险。错误地链接两个不应该链接的个人资料,往好里说会导致不相关的客户体验(显示错误的广告),往坏里说会导致失去客户忠诚度(看到别人的数据就拉响警报)。
照片由本·斯威特在 Unsplash 上拍摄
那么我们如何解决这个问题呢?我们将对风险较低但交易量较大的情况应用概率解析。一个目标错误的广告不如一个威胁品牌的安全漏洞重要(一个约翰·史密斯看到另一个约翰·史密斯的个人数据);虽然前一种情况在个体水平上可能是较低的 ROI,但在高容量和一些误差幅度是可接受的情况下,它将是概率解决方案的强有力候选。确定性解析将继续用于已知和流行系统的标识符。但是对于我们不熟悉或者不能确定解决的标识符,我们将能够找到概率解决的用例。身份解析是 CDP 的主要价值主张,所以最好的 CDP 会做得很好。更好的身份解析将极大地增强客户支持和其他运营用例,同时也将刺激个性化、推荐和广告活动优化。
6.指标层将成为标准,CDP 将从中受益
这有点跑题了,但是度量层现在正成为一个热门话题。这是一个被设想为介于仓库和 BI 工具之间的层,为度量标准的定义提供“唯一的真实来源”。例如,“用户数量”指标可能有不同的定义,这取决于您所查看的仪表板;指标层将为所有这些仪表板提供“用户数量”的单一定义。你可以在 Benn Stancil 的博客中阅读更多关于度量层的技术细节。
这对 CDP 有什么影响?如果你曾经从 Google Analytics 和 Mixpanel,或者 Stripe 和你的电子商务商店获得过不同的数据,你会知道获得一致的指标是很难的。有了 CDP 正确识别用户配置文件和指标层准确定义客户指标,我们将能够信任仪表盘中的客户洞察。这是 CDP 的优势,因为不明确的指标会降低对我们的分析和 CDP 的信任。
7.SQL 将会是类固醇
SQL 经受住了时间的考验,并将继续成为提取客户数据的查询语言。但是 SQL 是有限制的。如果你曾经尝试过建模客户旅程漏斗,你会知道用 SQL 建模漏斗完全是一团糟。但是我们会看到更多的工具,让我们更容易表达复杂的查询。也许是一种建立在 SQL 之上的语言,它包含了 SQL 所有流行的语言特性,但又有额外的、新的表达特性。各种 SQL 的 Typescript-for-Javascript 超集。像 Looker 这样的公司已经开始尝试 SQL [ Malloy by Looker ]的类似 SQL 的迭代。
Malloy by Looker 表达对流行的“Wordle”游戏的示例查询。来源: Github
这将如何影响 CDP?更简单的客户旅程建模意味着我们可以更容易地跟踪独特的客户旅程。复杂查询的更简单表达将使查询更便宜。我们将在移动设备上随时随地进行查询,我们很可能会看到简化复杂客户旅程查询的抽象。
8.数据运营工具将确保 10 倍的数据可信度
数据管道、误差遥测、监控仪器和工作流程都处于良好的状态对于我们从数据中获取洞察力至关重要。要做到这一点,我们需要非常好的数据运营工具,这样我们才能专注于收集客户见解。DevOps for software engineering 是一个非常相似的类比:正如我们从监控和警报工具以及软件中的基础设施即代码(IaC)中受益一样,DataOps 工具帮助数据人员专注于数据。
当然,CDP 会直接受益。不良数据会侵蚀对我们 CDP 的信任,因此尽早发现数据质量问题并快速解决它们至关重要。在以仓库为中心的世界中,找出在到达仪表板(数据沿袭)之前对数据点应用了什么转换并检测异常将是容易实现的。数据质量将通过正确性(有效性)、完整性、跨来源的一致性、可信度和当前性(实时)来维护。DataOps 工具本身将确保整个数据基础架构的可靠性、可恢复性和可观察性。
假设一批错误的数据导致仪表板中包含不正确的客户数据。恢复更改应该像在版本控制的代码库中恢复提交一样简单。数据点的变更历史应该很容易查找(我们已经在数据沿袭工具中看到了这一点)。也许通过在将数据应用到生产仓库之前将数据隔离在“死信队列”中,可以进一步缓解这种混乱。在进入生产基础架构之前,我们可能已经在由 DataOps 基础架构管理工具创建的暂存管道中测试了数据。所有这些问题都将影响 CDP,并归入 DataOps。
9.个性化,就像你设计的一样
我们仍然生活在一个努力使用户内容个性化的时代。当然,通过像 Qubit 这样的公司,我们已经看到了这一领域的巨大进步,这些公司在电子商务中提供个性化导航、购物车废弃恢复和个性化产品标签。 Klaviyo 现在是一个家喻户晓的名字,因为它实现了与客户个性化沟通的自动化。但是我们还没有看到超级个性化大规模出现。
马特·霍华德在 Unsplash 上拍照
例如,考虑一种家用保健产品。今天,您可能会通过填写一份长长的健康调查开始旅程,用产品进行测试,将其寄回进行评估,然后获得解释您健康状况的结果。每位顾客很可能会得到不同的诊断,更不用说经历不同的旅程了。今天,许多个性化,如果有的话,是基于基于规则的逻辑,当某个事件被触发时,呈现预先写好的内容。个性化的圣杯是实时提取洞察力,并将最相关的副本和界面呈现给客户。未来,随着 CDP 确定客户处于客户旅程的哪个阶段,我们将看到机器生成的部分副本和多元设计出现在客户的屏幕上。
10.借助边缘仓库,客户洞察触手可及
想象一下从地理上最近的 CDN 服务器提供数据的仓库。边缘仓储已经成为现实。您可以对仓库进行查询,并在几毫秒内获得结果,因为结果已经缓存在边缘。
由 CDP 支持的个性化只会从中受益。例如,从理论上讲,一个大型电子商务网站无需多次往返数据仓库就能获得实时客户洞察。
将这一切结合在一起
那么,从 CDP 的角度来看,2030 年的客户体验可能是什么样的呢?让我们考虑一个高度个性化的家庭肠道健康测试产品,它的客户旅程比常规电子商务产品稍微复杂一些。这是一个虚构的例子,但希望它能有助于将上述一些应用到生活中。
- 被动地看:每一次顾客之旅都包含着你生活中的奋斗或进步的渴望(要做的工作)。一个潜在客户——姑且称她为乔安娜——第一次意识到他们的问题是在他们遇到第一次挣扎的时候。这可能是乔安娜对某些食物的不良反应。她在网上搜索描述自己疾病的关键词组合。乔安娜登陆了你的博客和你最近与之建立了合作关系的一个有影响力的人的 vlog。她正在了解自己的问题。个性化引擎没有足够的客户资料数据,所以一个主要的行动号召(CTA)出现在用无代码博客构建器创建的博客帖子上,以注册订阅时事通讯。还有一个二级 CTA 访问产品页面,但我们猜测她还没有完全准备好做出任何决定。她注册了时事通讯,以了解更多关于肠道健康的知识。
- 乔安娜去看过她的医生,但没有明确的诊断。所以她有点沮丧,这是可以理解的。她重访了你的博客。在这一点上,她仍然是一个匿名用户,但我们可以做出推论,将她以前的博客和影响者 vlog 访问与她的个人资料相关联。由于无服务器,以仓库为中心的 CDP 可用于像我们这样的小型创业公司,这可能表明博客和 vlog 访问者在概率上是相同的。个性化引擎交换主要和次要 CTA,从而使产品页面 CTA 更加突出。她访问产品页面,查看该产品是否解决了她的部分或全部问题。乔安娜也喜欢你发的关于小麦食品和某些疾病之间联系的推文。
- **决定:**乔安娜决定用这个产品来帮助她找出疾病的根源。存储在边缘的见解显示,来自乔安娜国家的游客尤其担心国际航运。一个小横幅似乎向她保证了送货和退货的便利性。她购买产品。
- 消耗:发货;乔安娜最终收到了产品,进行了肠道健康测试,并在在线门户网站上注册了她的产品。所有这些交互都流向仓库。她将测试样本送回公司进行评估。几天过去了。这个为营销和数据团队建造的仓库包含了之前电子邮件通信的汇总数据,并表明现在发送一封令人放心的电子邮件将会缓解她的焦虑。我们相信这些数据,因为我们可以追踪我们数据点的血统,并对我们的数据操作充满信心。与此同时,她的产品注册在仪表板中被注册为“激活”——根据指标层的定义。她收到了一份报告中的测试结果,并了解了自己的诊断结果。乔安娜学到了一些新东西,并在一次即时调查中表达了她对该产品的满意程度。当她联系支持人员以澄清其报告的部分内容时,支持代理人员对她的旅程有了全面的了解,因为来自仓库的见解会立即提交给帮助台工具。其中一些见解——例如漏斗指标——可能是从富有表现力的**“类固醇上的 SQL”中提炼出来的。**
…一个集合了我上面讨论的所有元素的人为例子!当然,规划一个复杂的旅程从来都不容易,但我对 2030 年(或更早)抱有很高的期望,即使是最小的初创公司也将能够负担得起并利用现代数据堆栈的进步。2030 年可能看起来有些遥远,但直到 2012 年,像片段和雪花这样的东西才出现。谁说我们不会在 2030 年前实现更大的飞跃呢?
谢谢你
感谢你阅读这篇博文。如果你喜欢它,并有任何自己的想法要分享,请随时联系我(@ Twitter 上的逻辑或电子邮件)。
为你的分析项目注入活力的 10 个熊猫小窍门
原文:https://towardsdatascience.com/10-quick-pandas-tricks-to-energize-your-analytics-project-2333a144946b
数据科学
使用这些技巧让你的分析师生活变得轻松
SpaceX 在 Unsplash 上拍摄的
Pandas 是 Python 中流行的数据分析库。它无疑为您提供了处理数据所需的灵活性和工具。
然而,你必须知道节省时间和易于使用的高效率工作的技巧。这就是为什么我要分享熊猫的 10 个快速但非常有用的技巧,你可以在 10 分钟内掌握。
即使您已经非常熟悉 pandas 的方法和功能,您仍然会发现其中一些技巧是可行的。如果你是一个绝对的初学者,那么这篇文章是你开始学习的好地方。
这里有一个快速索引供你参考—
调整要显示的列数或行数
用 sample()
用 query()方法随机采样行子集一个数据帧
用 Round()方法舍入数据帧中的值
用 explode()方法解包列表值
用 plot()方法创建快速图
用 display()方法返回多个数据帧
为了举例,我将使用 Airbnb 开放数据,你可以免费使用,因为它在 ODbL 许可下公开可用!
不要忘了在阅读结束时获取包含所有示例的笔记本!
数据分析任务从将数据集导入 pandas DataFrame 开始,所需的数据集通常在中提供。csv 格式。
然而,当您在 pandas 数据帧中读取一个包含大量列的 csv 文件时,您只能看到后面跟有**. . . . .**
的几个列名和几个列名,如下所示。
import pandas as pd
df = pd.read_csv("Airbnb_Open_Data.csv")
df.head()
在笔记本|作者图片中显示有限数量的列
.head()
背后的主要目的是先睹为快。有了这些隐藏在. . . . .
后面的列名,你就看不到那些列中的数据了。因此,这里的第一个技巧是确定您想要显示的列数和行数。
调整要显示的列数或行数
默认情况下,pandas 在屏幕上只显示 60 行 20 列。这可能是几根柱子藏在. . . . .
后面的原因。
您可以使用下面的熊猫显示选项自己检查这个限制。
**pd.options.display.max_rows**#Output
60**pd.options.display.max_columns**#Output
20
您可以使用完全相同的选项来设置屏幕上显示的最大行数和列数。
例如,您可以将最大列数设置为 30,如下所示。
pd.options.display.max_columns = 30
df = pd.read_csv("Airbnb_Open_Data.csv")
df.head()
熊猫设置最大行数和列数|作者图片
在上图中,您可以看到数据集中的所有列。红框内的柱子先前隐藏在. . . . .
后面。并且在输出中不可见。
此外,您可以使用如下所示的功能.reset_option()
将选项重置回默认值。
pd.reset_option('display.max_rows')
pd.options.display.max_rows
#Output
60
当您在 pandas 中更改多个默认选项时,您可以使用.reset_options()
函数中的‘all’
参数在单个语句中将所有选项重置回初始值。
为了先睹为快,您可以在。这限制了您只能看到前/后几行。在 pandas 中,您总是可以从任何随机选择的记录中检查数据,甚至可以使用随机选择来检查数据的子集。
用 sample()随机对行进行采样
从第一行或最后几行看,数据可能组织得很好,很干净。因此,查看数据集中的任何随机记录以更好地理解它总是有好处的。
pandas.DataFrame.sample
提供从数据集中随机选择任何记录的灵活性,有 7 个可选和可调参数。
例如,假设您想从 Airbnb 数据集中选择 4 条随机记录。您可以简单地输入— df.sample(4)
—获得下面的输出。
作者从数据帧|图像中随机选择记录
或者,您也可以使用 fraction 来指定要随机选择整个数据集的多少部分。只需将分数(小于 1)赋给sample()
函数中的参数frac
,如下所示。
df.sample(frac = 0.00005)
熊猫随机样本使用分数|图片由作者提供
这里,您简单地获取了 DataFrame 中总行数的 0.005% 。
但是,每次执行这个单元格时,记录都是随机选择的。所以,为了每次都得到相同的输出,你可以将参数 random state 设置为任意整数。
假设你想每次都检索相同的三行,那么你可以使用下面的sample()
函数。
df.sample(3, random_state = 4)
熊猫随机抽样,每次输出相同|图片由作者提供
当您想要选择不同的记录时,您可以简单地将random_state
参数更改为另一个整数。
一旦检查了数据集中可用的数据,下一个任务就是选择所需的数据集子集。当然你可以用.loc
和。iloc
方法后跟一系列方括号,用于提取选定的行和列。
但是,还有一个方法.query()
可以帮助您去掉多个方括号来创建数据帧子集。
使用 query()方法对数据帧进行子集化
函数pandas.DataFrame.query(expression)
为您提供了有条件选择数据帧子集的灵活性。该函数中提供的表达式是一个或多个条件的组合。你可以用一种绝对随和的方式来写,不用任何方括号。
例如,假设您想要从数据集中提取所有记录,其中邻域是 Kensigton 。使用query()
方法很简单,如下所示。
df.query("neighbourhood == 'Kensington'")
使用 query()的熊猫数据帧子集|作者图片
您还可以在同一列上使用多个条件以及它们之间的任何逻辑,例如AND
、OR
、NOT
。
要了解更多关于这种方法的信息,我强烈推荐阅读—
</10-pandas-query-examples-that-will-make-you-use-pandas-query-easily-12a45b1e115>
选择子集后,您将进入分析中的数据清理阶段。数字列的一个常见问题是,小数点后的位数超过了要求。让我们看看如何处理这样的列。
pandas 数据帧中的舍入值,使用 Round()
有时,一列中的数字数据在小数点后包含多个数字,最好将其限制在 2-3 位。
在这种情况下,方法[pandas.DataFrame.round](https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.round.html)
会非常方便。您所需要做的就是在方法中提到所需的位数,如下所示。
df.round(2)
将数据帧四舍五入到可变的小数位数|作者图片
在 Airbnb 数据集中,只有列 lat 和 long 包含小数点后 5 位数的值。DataFrame 方法round()
只是将数据集中所有列的位数向上舍入。
但是,假设您只想对这个数据集中的单个列的位数进行舍入。方法pandas.Series.round
在这种情况下很有用,如下所示。
df['lat'].round(2)
#Output
0 40.65
1 40.75
2 40.81
...
102596 40.68
102597 40.75
102598 40.77
Name: lat, Length: 102599, dtype: float64
pandas.Series.round
的输出又是一个序列。要使它成为同一个数据帧的一部分,需要将更改后的列重新分配给原始列,如下所示。
df['lat'] = df['lat'].round(2)
df.head()
将系列或列中的每个值四舍五入到给定的小数位数|按作者排序的图像
它仅将列 lat 中的值更改为小数点后两位数,而列 long 中的值保持不变。
继续操作列数据,让我们看看另一个方法 explode(),它有一个更具体的用例——将类似列表的值的每一项转换为单独的行。
使用 explode()方法解包列表值
有时您会遇到数据集,其中列中的值是列表。从长远来看,很难处理这样的值,最好是为列表中的每个值创建一行。
为了更好地理解这个概念,让我们创建一个数据框架。
df = pd.DataFrame({"Country":["India","Germany"],
"State":[["Maharashtra", "Telangana", "Gujarat"],
["Bavaria", "Hessen"]]})
df
样本数据集|作者提供的图像
上述数据帧中的列状态包含列表作为值。要为每个列表中的每个值获取一行 State 列,可以使用方法pandas.DataFrame.explode
,如下所示。
df.explode("State")
Python |作者图片中的 df.explode()
您所需要做的就是在explode()
中提到包含列表的列名作为它的值。您可能会注意到,在上面的输出中,它只是复制了列表中每一项的索引值。
数据清洗后的常见任务是数据可视化。图表和图形可以很容易地识别潜在的趋势、模式和相关性。
当您使用 pandas 进行数据分析时,您不需要导入任何其他库来创建图表。熊猫有自己的方法和灵活的选项来快速创建各种图表。
使用 plot()方法创建快速绘图
通常,您的分析任务的目的不是数据可视化,而是您希望从数据中看到简单的图表/图形。Pandas 是一个非常灵活的包,它允许你使用自己的方法来可视化数据帧的内容。
假设,您想查看每种类型房间的平均评论数。你可以通过制作系列图或数据帧图的方法pandas.DataFrame.plot
来实现。
您可以创建一个更小更简单的 DataFrame — df_room —只需要两列,就像我在这里做的那样。
df_room = pd.DataFrame(df.groupby('room type')['number of reviews'].mean())
df_room.reset_index(drop=False, inplace=True)
display(df_room)
df_room.plot(x='room type', y='number of reviews', kind='bar')
熊猫。DataFrame.plot |作者图片
新创建的数据帧和图表都显示在输出中。
您可以随时使用**.plot()**
中的参数“*种类”*将图表类型从条形图更改为折线图。您可以在本笔记本中找到可用图表类型的完整列表。
但是熊猫是如何在没有图表样式输入的情况下创建条形图的呢?
pandas.DataFrame.plot
使用选项plotting.backend
指定的后端。绘图后端是 pandas 用来创建图表的绘图库,它使用 matplotlib 作为默认库。
您可以通过设置pd.options.plotting.backend
或使用选项pd.set_option(‘plotting_backend’, ‘name_of_backend’)
随时更改。
回到整体处理数据帧,让我们看看如何同时显示多个数据帧。
使用 display()返回多个数据帧
通常,您会创建多个数据帧,但是当您提到它们的名称或者在同一个单元格中对它们使用.head()
/ .tail()
方法时,只有最新的数据帧会显示在输出中。
例如,让我们创建两个数据帧,并尝试在输出中查看它们。
df1 = pd.DataFrame({"Country":["India","Germany"],
"State":[["Maharashtra", "Telangana", "Gujarat"],
["Bavaria", "Hessen"]]})
df2 = df1.explode("State")
# Get both DataFrames as output
df1
df2
单元格输出|作者图片
虽然,你在代码末尾提到了df1
和df2
;它在输出中只显示了df2
。
但是,您希望看到两个数据帧,一个在另一个下面。这就是函数display()
有用的地方。您只需要将 DataFrame 传递给 display()函数,如下所示。
df1 = pd.DataFrame({"Country":["India","Germany"],
"State":[["Maharashtra", "Telangana", "Gujarat"],
["Bavaria", "Hessen"]]})
df2 = df1.explode("State")
# Get both DataFrames as output
display(df1)
display(df2)
按作者显示输出|图像中的所有数据帧
简单!
现在,您可以在输出中看到两个(或所有)数据帧——一个堆叠在另一个之上。
前面的技巧也是函数显示()的一个很好的例子,您可以在输出中看到数据帧和条形图相互堆叠。
一旦探索了数据集并研究了其中的趋势和模式,下一步就是进行描述性分析。这可以通过数据转换来实现。
从一个基本的数据转换开始—使用不同的内置函数调查分类列中的不同值。
用 nunique()计算唯一值
当数据集中有分类列时,有时需要检查一列中有多少不同的值。
使用最简单的函数— **nunique()**
就可以得到。例如,假设您想查看数据集中有多少种不同的房间类型,您可以使用 nunique()快速查看。
df['room type'].nunique()
#Output
4
它只告诉你有多少唯一值可用,但要得到不同的值,即房间类型,你可以使用另一个函数— **unique()**
df['room type'].unique()
#Output
array(['Private room', 'Entire home/apt', 'Shared room', 'Hotel room'],
dtype=object)
它返回一个包含所有唯一值的数组。
检查完唯一值后,检查每个值在数据集中出现的次数也很有意义,即每种类型的房间在数据集中记录了多少次。
你可以用另一种方法得到它——T2——如下所示。
df.value_counts('room type')
#Output
room type
Entire home/apt 53701
Private room 46556
Shared room 2226
Hotel room 116
通过这种方式,您可以使用一行代码获得唯一值的数量以及它们出现的次数。
数据转换从不局限于分类列,事实上大多数可操作的见解都是从数字列中获得的。
因此,让我们研究两个与数字列相关的常用操作。第一件事是看看如何获得数据帧中一列的累积摘要。
返回带有 cumsum()的累计汇总
累积总和也称为运行总和,用于显示数据随时间增长的总和。所以在任何时间点,它会告诉你到那时为止所有值的总和。
pandas DataFrame 有自己的方法pandas.DataFrame.cumsum
,它返回 DataFrame 列的累积和。
让我们创建一个简单的日期和售出产品数量的数据框架。
daterange = pd.date_range('2022-11-24', periods=5, freq='2D')
df1 = pd.DataFrame({ 'Date': daterange,
'Products_sold' : [10, 15, 20, 25, 4]})
df1
虚拟数据集|作者提供的图像
这是一个虚拟数据集,其日期范围从 2022 年 11 月 24 日到 2022 年 12 月 2 日,以及每个日期销售的产品数量。
现在,假设您想查看截至 2022 年 11 月 30 日售出的产品总数。你不需要手动计算它,而是方法pandas.DataFrame.cumsum
会在一行代码中为你得到它。
df1["Products_sold"].cumsum()
#Output
0 10
1 25
2 45
3 70
4 74
它只是返回特定列的运行总数。但是,这很难理解,因为您在输出中看不到任何日期或原始值。
因此,您应该将累积总和分配给同一数据帧中的新列,如下所示。
df1["Total_products_sold"] = df1["Products_sold"].cumsum()
df1
熊猫数据框|作者图片中的累计总和或累计总数
答对了。
您只用一行代码就获得了您的专栏的运行总数!!
通常观察到的累积和用例是理解"到目前为止有多少"例如
- 到目前为止,这条河的水位上升了多少
- 特定时间之前销售了多少产品
- 每次交易后,账户里还有多少余额
因此,知道如何在数据集中获得累计值可能是您分析项目的真正救星。
此外,在处理数字数据时,您必须知道如何汇总数据并以汇总形式呈现出来。
使用 agg()通过多个函数进行聚合
您可以随时汇总原始数据,以提供统计见解,如最小值、最大值、总和以及计数。但是,当您使用 pandas 进行数据分析时,您真的不需要手动操作。
Pandas 提供了一个函数—— agg()
——可以在 pandas 数据帧上按对象分组使用。当 DataFrame 方法groupby()
用于将数据分组到类别中时,创建该对象。
使用agg()
函数,您可以将聚合函数应用于数据集中的所有数值列。
例如,您可以按房间类型对 Airbnb 数据集进行分组,以创建一个pandas.DataFrame.groupby
对象。
df_room = df.groupby('room type')
df_room
#Output
<pandas.core.groupby.generic.DataFrameGroupBy object at 0x0000029860741EB0>
现在,您可以对列点评数和最低住宿天数应用聚合函数sum
,如下所示。
df_room.agg({'number of reviews': sum,
'minimum nights': sum})
熊猫|作者图片中的数据聚合
您所需要做的就是向函数agg()
传递一个字典,其中键是列名,值是聚合函数名,比如sum
、max
、min
。
您还可以在同一列上应用多个函数,甚至在不同的列上应用不同的函数。
为了更好地理解数据聚合,我强烈推荐阅读—
</5-pandas-group-by-tricks-you-should-know-in-python-f53246c92c94>
我希望你很快读完这篇文章,并发现它对使用 pandas 提高数据分析技巧很有用。
我使用 Python 已经 4 年多了,我发现这些技巧非常省时。这些概念在实际项目中非常有用。
对阅读介质上的无限故事感兴趣??
💡考虑 成为媒体会员访问媒体上无限的故事和每日有趣的媒体文摘。我会得到你的费用的一小部分,没有额外的费用给你。
我也是一个中等会员&这真是太神奇了。我可以从这里张贴的每一篇文章中阅读和学习。
💡请务必 注册我的电子邮件列表 以免错过另一篇关于数据科学指南、技巧和提示、SQL 和 Python 的文章。
感谢您的阅读!
💡**【Jupyter】-笔记本配实例!**
三年来每天用 SQL 写作的 10 个快速 SQL 技巧
原文:https://towardsdatascience.com/10-quick-sql-tips-after-writing-daily-in-sql-for-3-years-37bdba0637d0
数据科学
这些技巧解决了您作为数据专业人员将会遇到的常见 SQL 问题
来自 Pexels 的 Andrea Piacquadio 的照片
我从事数据专业工作已经 3 年了,但看到其他人在考虑进入数据相关领域时,几乎没有 SQL 知识或经验,这仍然让我感到惊讶。我怎么强调这一点都不为过,不管你渴望得到什么样的数据角色,SQL 都是基础。
当然,我也见过一些例外的人,他们在 SQL 之外的其他领域拥有惊人的技能,却得到了这份工作,但他们在被聘用后仍然不得不学习 SQL。我认为,如果不学习 SQL,成为一名数据专家几乎是不可能的。
这些 SQL 技巧适用于所有人,不管你有多少经验。这些是我实际上经常使用的 SQL 技巧,不是什么新奇有趣但实际上不太适合你的工作流程的东西。为了方便起见,我按难易程度列出了这些。
我将使用这个 SQLite 沙盒数据库作为我的代码示例:https://www.sql-practice.com/。
1.检查表中的不同计数
第一个例子展示了如何检查列是否是表中的主键。当然,这通常会用在您创建的表中,因为大多数数据库都可以选择在信息模式元数据中列出主键。
如果两列中的数字相等,那么您在查询的第二部分中计算的列可能是主键。这不是一个保证,但它可以帮助你找到它。
当您有多个创建主键的列时,这只会稍微复杂一点。要解决这个问题,只需将构成主键的列连接在 DISTINCT 关键字之后。一个简单的例子是连接沙箱表中的名和姓来创建一个主键。
2.查找重复记录的示例
沙盒表是您将在工作中使用的数据库的简化版本。很多时候,您会希望查找数据库中出现重复值的原因。这就是下一个查询派上用场的地方。
您可以使用 HAVING 关键字对重复的值进行排序。在沙盒数据库中,您可以看到名字“John”是最常重复的。然后运行另一个查询,过滤到“John”以查看重复值的原因,您可以很快看到它们都有不同的姓氏和患者 ID。
3.用不同的
对于 COUNT(*)列,该查询的输出将是 4531,对于其余两列,输出将是 4530。指定列时,COUNT 关键字将排除计算空值。但是,当您使用星号时,空值将包含在计数中。当检查一个列是否是主键时,这可能会令人困惑,这就是我为什么要提到它的原因。
4.CTE >子查询
三年前,当我刚开始做数据分析师时,我编写的 SQL 查询包含的子查询比我愿意承认的要多。我很快意识到这不会产生可读的代码。在大多数情况下,您希望使用 CTE(公共表表达式)来代替子查询。为您想要包含的一行程序保留子查询。
5.一起使用 SUM 和 CASE
如果您想要合计满足特定条件的患者数量,WHERE 子句可以发挥作用。但是如果你想检查多个条件,你可以使用 SUM 和 CASE 当关键字在一起。这简化了代码,也易于阅读。
这种组合也可以用在 WHERE 子句中,如下例所示。
6.小心日期
此沙盒数据集的所有日期都被截断到一天。这意味着本例中 birth_date 列的时间部分都是 00:00:00。然而,在真实世界的数据集中,情况通常不是这样。
根据您的 SQL 开发 IDE,您的设置可能会隐藏显示时间组件。但是仅仅因为时间被隐藏,并不意味着它不是数据的一部分。
在上面的例子中,我人为地给病人#1 添加了一秒钟。如您所见,当使用 BETWEEN 关键字时,这 1 秒钟足以将患者从结果中排除。
我看到数据专业人员忽略的另一个常见例子是加入仍然有时间成分的日期。大多数时候,他们实际上打算在被截断的日期加入,但最终没有得到他们想要的结果;或者更糟,他们没有意识到他们没有得到正确的结果。
7.不要忘记窗口函数
窗口函数是保存所有数据行的好方法,然后在另一列中添加重要的聚合细节。在这种情况下,我们能够保留所有的数据,但是添加了一个“城市最大权重”列。
我见过一些分析师尝试解决方法,当一个窗口函数可以使代码更短,更易读,并且很可能节省他们的时间。
有许多不同的窗口函数,但是上面的例子是一个普通而简单的用例。
8.尽可能避免截然不同
下面的最后 3 个技巧没有具体的代码片段要展示,但是和上面的例子一样重要。在我的职业生涯中,我发现数据专业人员经常会在不理解数据的情况下添加一个 distinct 来防止重复。
这是一个错误。如果你不能解释为什么数据中会有重复,你可能会从你的分析中排除一些有用的信息。你应该总是能够解释为什么在一个表上放一个 distinct,为什么会有重复的。WHERE 子句通常是首选的,因为这样您就可以看到被排除的内容。
9.SQL 格式
这已经说了很多,但值得重复。确保格式化您的 SQL。最好创建更多具有良好格式的代码行,而不是试图将所有代码浓缩在几行代码中。它会让你的发展和别人的发展更快。
你可以在我上面的代码片段中看到,我在 WHERE 子句中使用了 TRUE 关键字。这是为了使 WHERE 子句中的所有参数都以 AND 开头。这样,争论就从同一点开始了。
另一个快速技巧是在 SELECT 子句中的列的开头添加逗号。这使得任何遗漏的逗号都很容易找到,因为它们都是对齐的。
10.调试提示
一些 SQL 查询可能是很难调试的问题。当我过去遇到这些问题时,对我帮助最大的是非常勤奋地记录我的步骤。
为了记录我的步骤,我将在查询前的注释中对一段代码进行编号。注释描述了我在查询部分尝试做的事情。然后我会在运行查询后在评论标题下写下我的答案。
在你调试的时候,很容易看到你已经尝试了什么,我保证你会用这种方法更快地解决它。
结论
希望你从这些建议中学到了有用的东西。在用 SQL 编码时,你发现了哪些有用的技巧?我也期待听到你的建议,请在评论中链接其他有用的文章,谢谢!
https://medium.com/@andreasmartinson/membership
如果你喜欢这篇文章,请在 LinkedIn 上联系我,或者看看我的另一个故事:
</5-window-function-examples-to-take-your-sql-skills-to-the-next-level-2b3306650bb6>
我在 Jupyter 笔记本上使用 VS 代码的 10 个原因
原文:https://towardsdatascience.com/10-reasons-why-i-stopped-using-jupyter-lab-498e958424ac
阅读了解 10 个增强 Jupyter 笔记本编程体验的优秀 VS 代码特性
照片由 Fotis Fotopoulos 在 Unsplash 上拍摄
我已经在学术研究和工业环境中从事 Python、深度学习和计算机视觉工作近 5 年了。我从 Jupyter 笔记本开始,但是因为几个原因很快就转到了 Jupyter 实验室。我喜欢使用它,直到我开始使用 VS 代码编程。比起为大多数任务创建笔记本,我更喜欢编写合适的 CLI 程序。然而,对于数据分析和快速可视化,没有什么能打败 Jupyter 细胞的互动性质!我甚至没有意识到,我已经习惯了 VS 代码中提供的特性,以至于当它不再为我工作(由于一个愚蠢的错误)并且我不得不短暂地切换到 Jupyter 实验室时,我意识到我再也回不去了!
在本文中,我将分享让 VS 代码工作变得非常高效的主要原因。
VS 代码 Jupyter 支持
1。完整的 IDE 功能:仅此一点就足以成为切换的理由。不像你们中的一些人,我不是一个用文本编辑器(vim,nano 等)编程的人。【无意冒犯。])并使用单独的终端进行程序编译、执行等。我非常喜欢使用 ide 进行开发。集成开发环境(IDE)是一个软件应用程序,它为计算机程序员提供软件开发的综合设施[1]。它们的存在是有原因的,在使用 Jupyter 笔记本电脑时,拥有它们所有的功能是一种解放的体验。从自动完成到能够使用你已经习惯的配色方案,这是我所感激的。IDE 的好处非常多,超出了本文的范围。
来源:作者
**2。令人敬畏的远程开发体验:**在云计算盛行的今天,远程开发不再是可选的,而是开发人员技能中不可或缺的一部分。对于初学者来说,启动一个远程实例、连接到它并进行开发可能是具有挑战性的。在云上开始使用 Jupyter 笔记本可能会很困难。设置需要对实例进行适当的 ssh 访问,然后使用正确的选项运行 Jupyter Lab(或笔记本)(例如,端口、启动目录、无浏览器标志等)。)最后用一个端口转发来完成。所有这些对有经验的人来说都是小菜一碟,但仍然是需要执行的步骤。用 VS 代码远程开发简直不可思议!事实上,它太棒了,我写了一篇关于它的文章。可以在这里了解:使用 Visual Studio 代码(VS 代码)在云(AWS/Azure/GCP)上进行深度学习/计算机视觉的远程开发和调试。简而言之,您在 VS 代码上的远程开发体验与本地开发一样接近。
**3。调试器:**对于任何开发人员来说,调试并找到问题的根本原因或解决 bug 的能力都是至关重要的。使用 print 语句进行调试是很好的,但是你只能做到这一步。使用调试器可以极大地提高生产率和性能。一个合适的调试器允许你在代码中的任何地方放置断点,这些断点可以是有条件的,然后让你在断点处停止程序执行。你将可以访问所有的局部和全局变量,堆栈跟踪等。程序的一部分。此外,您还将有能力步入、走出、跨过和恢复执行。有一个调试器控制台(并非总是如此,也不是每种语言都支持),在其中您可以像在解释器中一样操作局部变量。使用 VS 代码,你可以在你的 Jupyter 笔记本中放置断点,并调试单元格!多酷啊。这是我在用笔记本工作时渴望的一件事。
来源:作者
4。变量查看器: VS 代码支持 Jupyter: Variables 视图,该视图允许您检查内存中的所有变量。它很好地将熊猫数据帧格式化成表格!如果您想查看某些变量的内容,而不一定想调试,这非常方便。您可以单击顶部 Jupyter 工具栏中的变量按钮来打开变量选项卡。
来源:作者
**5。输出大小限制:**这个功能看起来可能不怎么样,但是当你的笔记本需要打印大量内容时,它可以帮上忙。这导致 Jupyter Lab(或笔记本)根据大输出而冻结和挂起。然而,在 VS 代码中,输出被截断到一个设定的最大大小限制。如果您想查看整个输出,只需单击输出单元格顶部的超链接,即可在单独的只读文本选项卡中打开整个输出。
来源:作者
**6。高级终端支持:**一个强大的终端是每个开发者的梦想,对吗?您可以访问 VS 代码终端支持。这包括拆分终端,打开多个选项卡,并使其整齐地出现在一个选项卡组中,该选项卡组可通过键盘快捷键访问。你还想要什么?我知道 Jupyter 实验室有终端支持,但我从来没有能够让它工作。
**7。自动端口转发:**如果您使用远程机器,您可能需要端口转发。(咳咳)即使你想使用 Jupyter 实验室或笔记本电脑,你也需要进行端口转发!对于 FiftyOne、Streamlit 等应用程序。你还需要端口转发。VS 代码的好消息是它会自动完成,手动端口转发就像输入端口号一样简单。它在远程连接的终端组中可用。按 ctrl+(或 cmd+
)打开该组,然后单击端口选项卡。
来源:作者
**8。强大的 git 支持:**除了 VS 代码中的原生 Git 支持和查看历史图表的扩展之外,还有对 Jupyter 笔记本令人难以置信的支持!这也可以在 Jupyter 实验室中通过额外的扩展获得(不确定 Jupyter 笔记本)。笔记本的更改在单元格级别上得到了很好的呈现,包括单元格内容、元数据和输出更改。然而,结合 VS 代码特性,git 体验变得非常愉快。
来源:作者
**9。格式细胞或笔记本:**这是另一个伟大的功能。您可以右键单击一个单元格并格式化该单元格或整个笔记本。只需右键单击并选择格式化单元格或格式化笔记本。您也可以使用键盘快捷键。这是清理你的笔记本和使用你选择的格式化程序格式化的一个非常快速的方法。
来源:作者
**10。自动单元运行时间:**在一些情况下,您可能需要知道单元执行时间。导入时间模块或 Jupyter magic 命令总是可行的。然而,VS 代码本身为您提供了每次运行的单元执行时间。这是一个非常方便的功能。
来源:作者
我们看到了 VS 代码的积极方面。然而,没有什么东西是没有缺陷的,VS 代码也很少有缺陷。
限制
我使用 VS 代码已经有一段时间了,有一些缺点或不足。
- VS 代码服务器连接有时会变得不稳定。如果您的 Jupyter 笔记本太大或者您打开了多个这样的笔记本,有时会发生这种情况。
- 有时候,用于启动 Jupyter 内核的基础环境被搞乱了,内核就是不启动。Jupyter 很容易解决这个问题:选择解释器来启动 Jupyter 服务器。
- 有时,如果你让你的机器进入睡眠状态,并且不重启 VS 代码,那么 python 内核将变得不可用。重启帮我解决了这个问题。
除了这几点,我对 VS 代码没有任何抱怨。
结论
最后,在这篇文章中,我分享了我喜欢使用 VS 代码进行 Juptyer 笔记本开发的 10 个原因。我希望这是有益的。如果你在 VS 代码上有任何你喜欢并经常使用的附加特性,请分享!Juptyer 实验室也一样!感谢您阅读文章。关注更多技术内容。你可以在 LinkedIn 上和我联系。
参考
[1]https://en . Wikipedia . org/wiki/Integrated _ development _ environment
在 Google Cloud 上学习数据科学的 10 个便利资源
原文:https://towardsdatascience.com/10-resources-to-learn-data-science-on-google-cloud-c19fb3033df5
劳伦·埃德瓦尔森在 Unsplash 上的照片
我对有抱负的数据科学家的首要建议是了解云计算。
所有企业都在将数据工作负载转移到云上。
如果你打算建立一个 ML 模型,并在一家公司投入生产,我几乎可以保证它会涉及到访问或处理云上的数据。
我注意到,现在大多数数据科学职位的招聘广告都将云技能作为工作描述的核心部分。我强烈建议你花时间提升技能。
哪家云提供商 — AWS,GCP(谷歌云平台),或者 Azure 都无所谓。
选择一个,使用该平台学习数据存储、处理、分析和 ML 工作流的基础知识。
就我而言,我和 GCP 一起着陆。
我喜欢使用 GCP 的一个主要原因是谷歌开发者倡导团队创建了大量易于理解的文档和高质量的学习资源。
在这篇文章中,我将分享我在谷歌云上开发时的 10 大信息和灵感来源。
我将这些资源分类为:博客、GitHub 库、文档页面、YouTube 频道和内容创建者。
几乎每天我都能找到新的有价值的信息源来帮助我理解一个主题或实现一个解决方案。我确信我一定错过了一些很棒的资源——如果你认为我错过了什么,请评论!
博客
1.开发者和从业者谷歌云博客
Google Cloud 在他们的主网站上有一个非常活跃的博客,涵盖了许多 Google Cloud 相关的主题,包括高级趋势以及更详细的技术内容。
开发者和实践者博客是主 Google Cloud 博客中的一个子主题,主要关注 GCP 工具的详细教程和演示。
这些高质量的博客文章是由谷歌杰出的开发者权益团队成员撰写的。
我发现这个博客对于学习最佳实践特别有用。
还有许多优秀的备忘单,它们可以很好地刷新你对不同 GCP 工具的记忆。“Google Cloud Products in 4 Words or Less”这篇博文对于了解 GCP 平台产品非常有用。
2.谷歌云媒体博客
除了谷歌云网站上的博客,谷歌还会定期更新他们在 Medium 上的“社区”博客。这包括来自谷歌云员工以及该领域其他从业者的大量策划博客帖子。
与开发人员和实践者的博客类似,该资源包含大量关于各种 GCP 用例及最佳实践的深入教程。
查看这个博客的新更新已经成为我早上例行公事的一部分。
GitHub 仓库
3.Google cloud platform github repo(⭐️顶级资源)
Google Cloud 维护着一个非常活跃的 GitHub 帐户,拥有数百个包含教程、研讨会材料和 GCP 工具的存储库。
这是一个很好的资源,可以找到 GCP 上已经实现的解决方案的代码片段,并观察 Google 工程师的编码最佳实践。
GCP 文档中引用了许多这样的库,但是,我建议浏览一下,看看是否有与您要使用的工具和语言相关的库。
我特别强调的内容包括:
- 专业服务 —谷歌云专业服务团队面临的常见解决方案的教程和代码
- GCP 上的 ML—谷歌云上各种机器学习框架的指南
- GCP 的 MLOps—针对各种 ML 工程主题的大量设计和代码模式的演示
- 带 Vertex AI 的 MLOps—使用 Vertex AI 平台的端到端 MLOps 流程
- ML 设计模式—O ' Reilly 的 ML 设计模式书的源代码和例子
- GCP 的数据科学 —奥莱利的谷歌云平台上的数据科学的源代码和示例
- 培训数据分析师 —谷歌云培训课程的实验室和演示
4.谷歌 API 源代码
Google 提供了许多客户端库,可以使用您选择的语言与其服务进行交互。
在整个 Google Cloud 文档中,您会发现每个工具的各种代码片段,展示了如何为您选择的客户端库使用 API。
这些代码片段实际上可以在 Github 上的 Google API 源代码中找到——通常在一个名为 samples 的文件夹中。我发现这非常方便,因为您可以在一个地方访问所有这些代码示例,而不必浏览文档中的各个页面,试图找到您依稀记得的有用片段。
例如,这里是使用 BigQuery 的 Python API 的所有代码片段。
此外,您可以访问这些样本的各种测试 Google 用来测试这些代码样本。当基于这些片段为你自己的函数编写单元测试时,这些可以成为有用的参考。
证明文件
5.产品文档页面—关键概念
正如您所料,Google Cloud 上的每个产品都有大量的文档,包括解释和分步示例教程。
特别是,每个产品文档页面都有一个名为“概念”的部分。
概念页解释了每个产品最重要的方面。他们通常会指出关键特性和最佳实践。这对于快速上手非常有帮助,特别是如果你以前在另一个云提供商上使用过类似的工具。
例如,这里有一个到谷歌云存储和云 SQL 的关键概念页面的链接。
6.谷歌云架构中心
在很大程度上,谷歌的文档是理解每个 GCP 工具的关键概念和有用例子的极好资源。
很长一段时间,由于文档页面如此全面,我甚至从未想过看看是否有更多的资源可以帮助我在 Google Cloud 上设计解决方案。
直到我偶然发现了谷歌云架构中心。
在大多数情况下,您正在处理的数据问题已经被其他人解决了(至少部分解决了)。没有必要重新发明轮子。
Google 云架构中心包含参考架构、图表、设计模式、指南以及在 Google 云上构建或迁移工作负载的最佳实践。
每当在 Google Cloud 上设计一个新的解决方案时,我总是在架构中心查看已经记录在案的类似解决方案。如果还没有参考架构,它仍然为解决我的具体问题提供了灵感。
例如,有一个现成的解决方案,用于处理流时间序列数据,包括使用发布/订阅和数据流进行异常检测。
许多参考架构还链接到文档各部分的教程章节。
作者捕获的云架构中心的屏幕截图
YouTube 频道
7.谷歌云技术
谷歌云技术是谷歌面向开发者的主要 YouTube 频道,拥有超过 80 万用户。该频道的特色是由 Google Developer Advocate 团队专业制作的视频,介绍 GCP 工具和最佳实践以及技术教程演练。
这个频道不同于其他谷歌云 YouTube 频道( 谷歌开发者 , 谷歌云 **),因为它专注于为从业者提供深入的技术资料。**其他渠道更多地从“高管层”的角度来看待趋势和概念,对 GCP 解决方案的日常实施用处不大。
如果我需要一个工具的演练,这通常是我熟悉主要概念和最佳实践的第一站。
我建议访问播放列表页面,浏览与您感兴趣的工具最相关的播放列表。我特别喜欢国玉峰的《人工智能历险记》
8.云中奇遇
《云中冒险》是一个小得多的频道(目前只有 2k 订户),由国玉峰运营,他也是谷歌云开发者的倡导者。尽管它很大,但它是内容的金矿。
该频道主要提供关于机器学习和 MLOps 的长篇实时教程。国玉峰实时浏览教程,这并不总是按照计划进行,但这是一种非常有价值的学习方式,因为你可以看到如何调试他遇到的常见问题。
我真的很喜欢他关于用人工智能平台管道生产机器学习的视频。
不幸的是,看起来他已经有一段时间没有上传任何新的内容了,然而,有很多旧的内容让你很忙。
内容创建者
最后,我想强调几个我最喜欢关注的人物,他们在谷歌云领域创造了伟大的内容。我肯定我已经错过了许多其他优秀的内容创作者,但这里有两个不断出现的真正有用的材料。
我已经链接到他们的中型博客,但是,我建议你也在 LinkedIn 上关注他们,以获得定期更新和见解。
9.拉克什马南
Lak 是谷歌云数据分析和人工智能解决方案总监。他主要围绕 BigQuery 和机器学习提供有见地的思考和清晰的教程。
他是许多书籍的作者,包括《O ' Reillybig query 权威指南 ( GitHub 链接)。
10.普里扬卡·韦尔加迪亚
Priyanka 是谷歌的开发人员关系工程师,在谷歌的云技术 YouTube 频道和 LinkedIn 上非常活跃。
Priyanka 在整个 Google Cloud 上创建主题内容,包括许多娱乐性和知识性的视频。
她最近制作了一个很棒的系列来解释谷歌云的 13 个参考架构。
结论
在这篇文章中,我分享了我作为数据科学家使用 Google Cloud 进行开发的 10 大技术资源。
谷歌为开发者提供的资源质量给我留下了深刻的印象,这使得谷歌云成为迄今为止我最喜欢与之合作的云提供商。
这些资源中有许多是我在过去几个月才接触到的,这让我觉得肯定还有更多我忽略了的。我很想知道你最喜欢的资源是什么——我肯定错过了一些!
This post was originally published on my blog: [https://engineeringfordatascience.com/posts/top_10_google_cloud_resources/](https://engineeringfordatascience.com/posts/top_10_google_cloud_resources/)
埋藏在文档中等待被发现的 10 颗 Sklearn 宝石
原文:https://towardsdatascience.com/10-sklearn-gems-buried-in-the-docs-waiting-to-be-found-ad95a8fabdfd
隐藏的宝藏
照片由乔尼·卢
动机
我讨厌 Sklearn。我上的“ML 入门”课对支持向量机的解释非常糟糕,以至于我以此为基础来评价整个库。在那之后的几个月里,我放弃了这门课程,永远离开了曼梯·里。
我一点也不知道 Sklearn 会成为我在庞大的数据科学堆栈中最喜欢的库。我也不知道我会为此写 22 篇文章。这是我第 23 次。最后一个的和之前的的都是飞天成功。成千上万的人读过它们。
我写这篇文章的目的是一样的——向你展示这个图书馆比你想象的要棒得多。这一次,您将了解我发现并立即添加到我的工具箱中的一些最新的、被低估的 Sklearn 特性。
这篇文章将比我上一篇类似的功能汇编实用得多,我的上一篇类似的功能汇编更侧重于边缘情况。尽情享受吧!
</19-hidden-sklearn-features-you-were-supposed-to-learn-the-hard-way-5293e6ff149>
1️.功能变压器
尽管 Sklearn 有许多预处理转换器可以放入管道中,但它们不足以用于任何可以想象的预处理场景。即使您有一个不在管道内的单独步骤,原子的单一调用管道的整体思想也会崩溃。
这就是为什么你应该把你所有的自定义函数包装在FunctionTransformer
里面,这样可以把它们转换成一个 Sklearn 兼容的转换器。唯一的要求是该函数接受一个特征数组(X)和一个可选的目标数组,并在预处理后返回它们。
💻演示
📚证明文件
功能变压器 — 链接
https://ibexorigin.medium.com/membership
获得由强大的 AI-Alpha 信号选择和总结的最佳和最新的 ML 和 AI 论文:
https://alphasignal.ai/?referrer=Bex
2️.用户定义的变压器
在最后一节的基础上,您不能在一个简单的函数中执行一些定制的数据清理步骤。
例如,清理过程中最常见的操作之一是缩放倾斜要素,使其呈正态分布。通常,人们使用像PowerTransformer
或np.log
这样的对数变压器,但是它们有一个缺点。如果某个要素包含零,对数将无法处理它们并引发错误。
作为一种变通方法,人们在特征向量上加 1,然后进行变换。如果他们需要原始向量,他们会调用该要素的指数函数并减去 1-问题就解决了。
当然,这个操作不是内置在 Sklearn 中的,并且您不能在一个简单的 Python 函数中执行它。这就是你用定制变形金刚优雅地解决这个难题的地方。下面是一个完全符合我描述的转换器:
💻演示
该类应该从BaseEstimator
和TransformerMixin
类继承,使其能够插入到管道中。编写的代码越少,数据泄露的可能性就越小。
如果您想了解关于这种方法的更多信息,我有一篇关于这种类型的定制转换器的单独文章,包括 FunctionTransformer:
📚证明文件
BaseEstimator — 链接。
变压器混频器 — 链接。
3️.转换目标回归器
有时,即使是目标数组也需要额外的预处理步骤,这是不能包含在管道中的。一个典型的场景是缩放数字目标,使它们呈正态分布。你在管道之外这样做,经常不止一次。
如果有一个管道也能处理目标数组,那不是很好吗?原来是有的!(仅用于回归)。
TransformedTargetRegressor 是一个类,它既接受功能上的回归器管道,也接受目标数组的单独预处理函数或转换器。
💻演示
regressor
参数接受以它们结尾的回归变量或管道。它还有transformer
参数,您可以为它传递一个要应用到目标上的 transformer 类。如果 transformer 是一个函数,比如np.log
,你可以把它传递给func
参数。
然后,调用fit
将转换特性和目标数组,并拟合回归量。在文档中了解更多信息。
📚证明文件
转换目标进度器 — 环节。
4️.HTML 估计器表示
如果你的管道由几个步骤或者子管道组成,它们的 IPython 显示会让你眼睛出血。如果你不小心在 Jupyter 中显示它们,看起来会是这样:
幸运的是,Sklearn 提供了估算器的 HTML 表示,使它们更加用户友好,让我们看得开心:
💻演示
通过将 display config 设置为diagram
,您可以在 IPython 中获得管道的交互式 HTML 表示。
📚证明文件
sklearn.set_config — 链接。
sk learn . utils . estimator _ html _ repr—链接
5️.正交判别分析
在 Kaggle 即时满足竞赛中,一个二次判别分析分类器甚至在没有超参数调整的情况下也取得了令人印象深刻的 0.965 ROC AUC 分数,超过了大多数基于树的模型,包括 XGBoost 和 LightGBM。
那么,如果这种算法可以胜过最先进的模型,为什么你以前从未听说过它呢?嗯,它的用例是有限的。用于训练 QDA 的要素应严格服从正态分布,从而便于 QDA 计算和拟合分布周围的椭球形状。
图片来自 Sklearn 用户指南
QDA 的另一个优势是它非常快,在百万行数据集上训练它只需要几秒钟:
💻演示
在这本笔记本中,Chris Deotte 展示了他如何通过组合 512 个 QDA 模型获得 0.965 的 ROC AUC 分数。
在上个月的 TPS 竞赛(9 月)中,我也设法获得了 0.8 左右的 ROC AUC,而表现最好的解决方案大约为 0.81。2%的差异是您可能要考虑的最精确的基于树的模型和运行速度极快的模型之间的权衡,前者速度慢得多,后者以较低的精确度为代价。
📚证明文件
方差分析 — 环节。
6️.投票分类器/回归器
在一个单独的项目中,你经常会得到几个性能相似的模型。这就是投票组合可以集体使用这些模型来进一步提高性能的地方。投票分类器将几个分类器的多数投票作为最终预测。如果类是概率或预测是连续的,则预测是平均的。
这种方法非常有效的原因是概率论中固有的。简而言之,当组合时,具有 0.6、0.7、0.8 准确度的三个分类器最终将优于具有 0.8 准确度的三个分类器。如果你不相信我,请阅读来自 MLWave 的这篇文章。
Sklearn 提供了两个方便的类来实现这个操作。您需要传递一个分类器或回归器列表,它会处理剩下的事情。
💻演示
我将voting
设置为 soft,表示我希望预测是概率。还有一个weights
参数,您可以使用它为更精确的模型分配不同的系数。查看文档了解更多细节。
📚证明文件
投票分类器 — 链接。
VotingRegressor — 链接。
7️.堆叠分类器/回归器
另一种比投票更强大的集合方法是堆叠。
假设你有五个模型。要堆叠它们的输出,您需要将它们逐一拟合到训练数据中,并生成预测。您将有五个预测集,这些预测集与定型集的目标数组组合成一个数据集。
然后,您选择一个最终的、完全不同的模型来训练这个“预测数据集”,并在保留集上进行预测。
堆叠背后的想法是,您选择的 1 级模型应该尽可能多样化。不同的模型从不同的角度学习训练集中的信息,覆盖了整个信息空间。换句话说,像树、线性模型、表面拟合、基于邻居的模型、贝叶斯模型和高斯模型这样的各种模型最大化了训练潜力,并且它们的组合输出减少了偏差并防止了过度拟合。
在 Kaggle 表格竞赛中,大多数获胜的解决方案都是几个模型叠加在一起。
💻演示
尽管听起来很复杂,但使用 Sklearn,你很快就会掌握它的窍门。实现就像投票分类器/回归器一样直观。欲了解更多信息,请阅读本文或文档。
📚证明文件
堆叠分类器 — 环节。
堆栈回归器 — 链接。
8️.LocalOutlierFactor
离群点是机器学习中的一个严重问题。它们会使模型的目标函数产生偏差,并可能导致过于乐观或悲观的结果。
对于小型玩具数据集来说,发现异常值不成问题。真正的挑战始于拥有超过 50–100 个要素的数据集。您需要一种既快速又准确地检测高维离群值的算法。即便如此,对于包含数百个要素和数百万行的数据集,原始算法可能需要数小时才能运行。
这就是你需要结合一个降维算法和一个健壮的离群点检测器的地方。最近喜欢上的一个组合是 UMAP 和localooutlierfactor。
UMAP 在降低数据集的维度并尽可能多地保留信息方面表现出色。至于 LocalOutlierFactor,它是一种基于邻居的算法,旨在快速处理大型数据集。
💻演示
如果这个演示不完全可以理解,我有一篇关于这个主题的单独文章来深入讨论它:
📚证明文件
local outlierfactor—链接。
9️.量化变压器
有时,你会遇到像下面这样的疯狂分布,简单的对数变换,或者定标器不能满足它:
具有罕见分布的合成生成数据-按作者
如果你有这样的双峰,三峰,或 n 峰分布,你最好的选择是QuantileTransformer
使它们尽可能正态分布。它使用稳健的统计指标,如四分位数和中位数来确定分布的中心和比例。
💻演示
📚证明文件
量化器 — 环节。
1️0️.PCA + tSNE/UMAP
更多的数据不一定意味着更好的模型。有些数据集太大了,即使不完全使用它们,你也能做得很好。但是如果你不愿意将一部分数据放在一边,我建议使用降维技术将数据投影到一个较低的空间。
不能保证模型性能的提高,但是从长远来看,您可以在更小的数据集上运行更多的实验,因为您将使用更少的 RAM,并且计算时间将会更短。
但问题是,如果数据集中有许多特征,质量降维可能需要太长时间。你不会第一次就做对,所以更多的实验会更加昂贵。这就是为什么 Sklearn 文档建议将降维算法和 PCA(主成分分析)结合起来。
主成分分析对任意维数都能快速工作,是第一阶段简化的理想选择。建议使用 PCA 将数据投影到合理的维数,如 30–50,然后使用其他算法进一步降低维数。
下面是 PCA 和 tSNE 的组合:
💻演示
300 个维度的综合生成数据—按作者
在一个包含 100 万行和大约 300 个要素的合成数据集上,将数据投影到前 30 个维度,然后投影到 2D,需要 4.5 个小时。不幸的是,结果并不乐观:
这就是为什么我建议使用 UMAP。它比 tSNE 快得多,并且更好地保留了数据的本地结构:
300 维合成数据的 UMAP 投影
UMAP 设法找到了目标类之间的明显区别,并且比 tSNE 快 20 倍。
📚证明文件
PCA — 链接。
tSNE — 链接。
UMAP — 链接。
摘要
有趣的事实是——我仍然不知道支持向量机及其工作原理。并且没有立即学习它们的计划。评判我吧,但我只关心树木。
感谢您的阅读!
https://ibexorigin.medium.com/membership
我的更多故事……
https://ibexorigin.medium.com/28-weekly-machine-learning-tricks-and-resources-that-are-pure-gems-1-8e5259a93c94 </18-non-cliché-datasets-for-beginner-data-scientists-to-build-a-strong-portfolio-c59743b2a829> https://ibexorigin.medium.com/in-depth-guide-to-building-custom-sklearn-transformers-for-any-data-preprocessing-scenario-33450f8b35ff
80%的数据操作需要 10 次 SQL 操作
原文:https://towardsdatascience.com/10-sql-operations-for-80-of-your-data-manipulation-7461c56e25f4
作者图片
关系数据库(表格数据)是最常用的数据库之一,它占被捕获数据总量的 70%。
SQL 是操作关系数据最常用的编程语言之一。数据分析师和数据科学家非常积极地使用 SQL 来完成数据拉取和数据操作任务。
在这篇博客中,我将带您了解 10 个最常用的 SQL 操作,每个有抱负的数据科学家/数据分析师都应该知道。让我们开始吧:
- Limit :查看行会让你对数据表不同列中的值有一个概念。获取并查看数据表的“所有”行是一个昂贵的操作,它需要时间和资源。因此,获取数据表前几行的功能变得非常有用。Limit 子句用于获取数据表的顶行。
- Distinct :使用 Distinct,我们可以找到一列中的不同值,应用 count 函数可以给出该列中不同值的计数。例如,我们可以使用下面的代码来查找不同(或唯一)产品 id 的数量。
**3。聚合:**聚合运算用于求出一列值的总和、计数、最小值、最大值等。例如,如果我们想找到售出产品的总数量(或单位),我们可以将 sum 函数应用于 quantity 列。类似地,我们还可以通过对 quantity 列应用 max 函数来查找产品的最大销售量。
总量(图片由作者提供)
最大数量(图片由作者提供)
4。Groupby: Groupby 用于查找列级的聚合/组。Groupby 与 sum、min、max、count 等聚合一起使用。例如,为了找到所有产品的总销售量,我们可以按产品 id 分组,并找到数量的总和。
所有产品的总销量(图片由作者提供)
5。Where: Where 子句用于根据一些列值过滤行。例如,假设我们想要查看对应于产品 id 10 的总销售量,我们可以在产品 id 列上使用 where 子句。
对应于 ProductID — 10 的总数量
6。Having: Having 子句用于对聚集的列/值应用过滤器。例如,假设我们想要查找总销售量大于 350 件的产品,我们可以使用 having 子句对聚合数量应用过滤器。
Where vs Having: Where 用于对数据帧的现有列应用过滤器,而 Having 用于对列的聚合值应用过滤器。
7 .。Order by: Order by 子句用于按升序(默认)或降序对列的值进行排序。例如,如果我们想找到零售商销售的最大数量的产品,那么我们可以使用 order by 函数。
按聚合列排序(按作者排序的图像)
Order by 也可以应用于非聚合列。例如,使用下面的代码,我们可以对数量列进行排序:
按 ProductID 列排序(按作者排序的图像)
8。Join: Join 用于将两个数据表中的信息合并到一个表中。图像,如果我们想获得产品的信息,我们可以将订单明细表与产品表连接起来以获得产品信息。为了连接两个数据表,我们需要在两个表中公共的主键(或列)上连接它们。在下面的示例中,我们使用 ProductID 列在两个表之间应用内部联接。
在这里了解更多关于加入的信息:加入简介!
连接表(作者图片)
**9。窗口:**窗口函数用于在数据的子集/窗口上应用函数。例如,为了找到每个类别中的前 3 个销售产品,我们可以按类别列对数据进行分区(按 CategoryID 进行分区),按总量排序(从高到低),将行号附加到每一行,并过滤前 3 行(如下面的代码所示)。
数据划分的目的是找到等级、滞后等。在数据子群中。下面是窗口函数的一些使用案例:找出每个类别中的前 3 名,比较当前行和前一行的值,等等。
过滤每个类别中的前 3 个产品(按作者分类的图片)
10。LIKE : Like 操作符与‘Where’子句一起使用,用于搜索列中的特定模式。例如,为了找到联系号码以代码 171 开头的供应商,我们可以使用以下代码:
使用 LIKE 运算符过滤联系人(图片由作者提供)
如果你觉得我的博客有用,那么你可以 关注我 每当我发布一个故事时,你都可以直接得到通知。如果你自己喜欢体验媒介,可以考虑通过 注册会员 来支持我和其他成千上万的作家。
谢谢大家!
这里还有一个与你相关的故事:
https://anmol3015.medium.com/write-your-sql-queries-the-right-way-9c04dfbb6499
任何学习 Python 的人都应该知道的 10 个终端命令
原文:https://towardsdatascience.com/10-terminal-commands-anyone-learning-python-should-know-22c847ece888
像专业人士一样使用终端命令来使用您的电脑
图片由 cottonbro 在像素上拍摄
我们大多数人通过图形用户界面(GUI)与计算机进行交互。当执行简单任务时,这个友好的选项对我们来说已经足够了,但是当要做更高级的事情时,命令行(CLI)是首选界面。
使用 CLI,我们可以做我们使用 GUI 做的事情,例如浏览目录和处理文件,但是它在速度和效率方面表现出色,甚至可以轻松处理重复的任务(如果您非常熟悉命令的话)
在本文中,我们将看到任何学习 Python 的人都应该知道的基本终端命令。为什么?它们形成了自动化的基础,这是我们大多数人喜欢在 Python 中做的事情(命令# 7“cat”就是一个很好的例子)
1.显示当前工作目录
pwd 代表打印工作目录,它会打印当前的工作目录。
$ **pwd**
/Users/frank
Windows 上的输出略有变化。
$ **pwd**
C:\Users\frank
2.激光唱片
cd 代表更改目录。我们可以使用这个命令来浏览文件夹。
现在,这是您应该在终端上看到的内容
user@computer-name:~ $
我的情况是frankandrade@MacMini ~
。~
表示我们在用户的个人文件夹中。
作者图片
假设我们想使用终端移动到test-folder
。
frankandrade@MacMini ~ % **cd** test-folder/
现在我们不再位于~
,而是位于test-folder
。
frankandrade@MacMini test-folder %
如果您想返回到父目录,请使用cd ..
3.限位开关(Limit Switch)
此命令列出当前目录中的计算机文件。
我的test-folder
有 2 个 txt 文件。
作者图片
如果我们使用ls
命令,我们将得到这两个文件作为输出
$ **ls** file1.txt file2.txt
太好了!我们列出了两个文件。现在让我们列出那些我们在 GUI 中看不到的隐藏文件。
$ **ls -a** . .. .DS_Store file1.txt file2.txt
如你所见,除了文本文件,我的文件夹中还有其他文件。
4.mkdir
这个命令允许我们创建一个新的文件夹。
让我们创建一个名为my-folder
的文件夹。
$ **mkdir** my-folder
现在我们使用ls
来验证文件夹是否被创建。
$ **ls** file1.txt file2.txt my-folder
5.触控
这个命令允许我们创建一个空文件。
让我们创建一个名为file3.txt
的文件
$ **touch** file3.txt
现在我们使用ls
来验证文件是否被创建。
$ **ls** file1.txt file2.txt file3.txt my-folder
如果您想使用终端编辑这个新文件,请使用nano
。
$ **nano** file3.txt
运行上面的命令后,nano
将会打开。
作者图片
这是一个简单的基于终端的文本编辑器。我们可以使用 Nano 来修改现有文件或编写简短的纯文本文件。
我只写下Hello World!
几个字,然后按^X
、Y
并点击enter
退出并保存文件。
如果您打开file3.txt
,您将看到所做的更改。
6.空间
这个命令帮助我们从计算机中删除文件和目录。
说我们要删除file3.txt
。
$ **rm** file3.txt
如果您想删除目录,请添加-r
$ **rm** **-r** my-folder/
现在我们使用ls
来验证文件和目录是否被删除。
$ **ls** file1.txt file2.txt
6.平均变化
我们可以使用 mv 命令来移动文件或目录,也可以重命名文件。
对于这个例子,我在~
目录中创建了一个file3.txt
文件。
让我们将这个文件移动到test-folder
目录。
$ **mv** file3.txt test-folder
如果第二个元素不是目录,而是另一个文件名,我们将重命名该文件。
让我们将 file3.txt 重命名为 my-file3.txt
$ **mv** file3.txt my-file3.txt
7.猫
cat
最基本的功能是查看文件内容。
让我们看看file1.txt
里面的内容(它只有“一”和“二”两个字)
$ **cat** file1.txtone
two
我们还可以使用cat
连接两个(或更多)文件的内容。如果你想深入了解这个问题,可以看看我下面的视频。
让我们将文件 1 和文件 2 的内容连接起来,放入新的文件 3 中。
$ **cat** file1.txt file2.txt > file3.txtone
two
three
four
但这还不是全部!我们可以使用cat
和>>
将一个文件的内容附加到另一个文件中。
$ **cat** file2.txt >> file1.txtone
two
three
four
8–9.头/尾
使用head
命令,我们可以很容易地看到文件的前 10 行。
对于这个例子,我有一个编号为 1 到 12 的 file1.txt。让我们看看前 10 排。
$ **head** file1.txtone
two
three
four
five
six
seven
eight
nine
ten
我们可以使用cat
命令得到类似的结果,但是当我们只想看到前“n”行时head
更有用。我们只需添加如下所示的-n
参数。
$ **head** **-n** 5 file1.txtone
two
three
four
five
如果我们想得到最后 10 或“n”行,我们可以使用tail
命令。
让我们获取 file1.txt 的最后 5 行。
$ **tail** **-n** 5 file1.txteight
nine
ten
eleven
twelve
10.丙酸纤维素
要复制一个文件或目录,我们使用cp
命令。
让我们复制我的 file1.txt 文件,并将其放入名为 new-folder 的文件夹中。
$ **cp** file1.txt new-folder
如果我们想要复制一个目录,我们必须添加-r
参数。
让我们将名为 new-folder 的文件夹复制到父目录(..)
$ **cp** -r new-folder ..
恭喜你!您刚刚学习了 10 个终端命令,它们将帮助您像专业人士一样使用电脑。
用 Python 学习数据科学? 通过加入我的 10k+人电子邮件列表,获得我的免费 Python for Data Science 备忘单。
如果你喜欢阅读这样的故事,并想支持我成为一名作家,可以考虑报名成为一名媒体成员。每月 5 美元,让您可以无限制地访问数以千计的 Python 指南和数据科学文章。如果你用我的链接注册,我会赚一小笔佣金,不需要你额外付费。
https://frank-andrade.medium.com/membership
关于数据科学你不知道的 10 件事
原文:https://towardsdatascience.com/10-things-you-are-not-told-about-data-science-3460636feeb1
管理数据科学职业的期望与现实
来源 pexels.com(https://www . pexels . com/photo/abstract-accuracy-accurate-aim-262438/)
当数据专业人员进入数据科学领域时,他们往往会措手不及。期望和现实之间有很大的差距,在这篇文章中,我将分享一些公开的秘密。我希望这将让数据科学专业人士更好地准备好进入职场后会遇到什么,并优先考虑在就业市场上提供优势的实用技能。
这些公开的秘密在我最新的奥赖利的书https://www.amazon.com/Essential-Math-Data-Science-Fundamental-dp-1098102932/dp/1098102932/中讨论。它包含了我希望在 12 年前就知道的一切,当时数据科学、人工智能和机器学习定义了未来十年的技术投资和数据专业人员的发展。虽然这本书主要侧重于构建微积分、统计和机器学习模型,但我也为读者提供了关于现实世界应用和职业管理的实用建议。
以下是我与读者分享的十件关于数据科学不太为人所知的事情,尤其是那些该领域的新手。
1。数据科学家不太可能在工作中使用深度学习
毫无疑问,深度学习帮助了数据科学作为一种职业的普及。讽刺的是,很少有数据科学家有资源做这样一个巨大的项目。数据输入工作将需要数十万(或数百万)美元,他们将花费漫长的工作日点击停车标志的图片(查看纽约时报文章 AI 正在向人类学习,许多人类 )。)之后,海量的硬件和参数实验会消耗巨大的研究成本。将这一点与深度学习的过度拟合倾向及其部署难度结合起来,你就会明白为什么大多数公司会满足于线性回归或逻辑回归。
尽管如此,你可以学习神经网络和深度学习来拥有这些知识,并为你的管理设定预期,我在我的书的第 7 章中写了如何从头构建神经网络。如果你获得了一两个博士学位,并在 Alphabet 或微软找到了一份工作,或许你会有机会。但对于我们其他人来说,我们没有 FAANG 公司的那种 R&D 预算。
2。SQL 可能是你能学到的最有价值的技术
简单的结构化查询语言(SQL)已经存在了近 50 年,但在查询数百个数据库平台时仍然保持着相关性。为什么?它只是工作。
当像 NoSQL 和 Apache Spark 这样的大数据平台在 2015 年出现时,有很多人猜测 SQL 将被取代。具有讽刺意味的是,出于最终用户的需求,SQL 接口被添加到这些技术中。SQL 一直是数据的通用语言,甚至在大数据繁荣时期保持了它的相关性。它的声明性和逻辑语法为检索和操作数据提供了简明易读的指导。
许多数据科学家进入角色时都希望使用机器学习和花哨的统计工具。事实上,他们将花费 99%的精力去寻找数据源,如果他们不懂 SQL,就很难有所作为。
令我惊讶的是,有这么多数据科学家不懂 SQL,而是依赖他人为他们检索数据。他们也不必要地浪费时间去做复杂的 Python/Pandas 任务,这些任务可以用 SQL 的几行代码来完成,而且数据量可能非常大,应该在数据库服务器上用 SQL 来完成。
想打入数据科学,先学 SQL,再学别的。如果你得不到你需要的数据,你的模型和分析毫无价值。这里还有一个无耻的自我推销:我还有一本奥赖利的书【SQL 入门】,而且只有 100 页长!**
3。当你只有一把锤子时,一切都开始看起来像钉子
数据科学充满了专业人士寻找用机器学习解决的问题,而不是从一个问题开始,寻找正确的解决方案。正因为如此,数据科学家错过了强大、有效的工具,只是因为这些算法已经成熟、被遗忘,而不是机器学习。这些可能是代价高昂的错误,不仅对于追求错误技能的招聘经理来说如此,对于冒着将错误的解决方案与问题配对的风险的数据科学专业人员来说也是如此。
暂且抛开机器学习!学习正则表达式、试探法、搜索算法、基于规则的系统、线性编程、优化和其他经过时间考验并解决机器学习无法解决的实际问题的旧学校计算机科学概念。我发现最有效的解决方案往往不是制造媒体头条。我还听说过许多令人痛苦的轶事,一家大型科技公司的数据科学团队试图使用自然语言处理来解决文本模式问题,一位经验丰富的新员工在一个小时内用正则表达式解决了它。数据科学家不匹配解决方案的数量太常见了。
4。数据科学家的角色很可能变成 IT 工作
许多数据科学家在受雇于统计和机器学习时变得失望,但却发现自己反而成了常驻的“IT 专家”。这种现象并不新鲜,实际上早于数据科学。
影子信息技术(shadow IT)描述了在 IT 部门之外创建系统的办公室工作人员。这包括数据库、仪表板、脚本和代码。这在组织中过去是不被认可的,因为它不受监管并且在 it 部门的控制范围之外运行。然而,数据科学运动的一个好处是,它使 shadow IT 更被接受为创新的必需品。
数据科学家不会失望,而是可以精通 SQL、编程、云平台、web 开发和其他有用的技术。毕竟,数据科学家与数据打交道,而这必然会导致 IT 工作。它还可以简化他们的工作,让其他人更容易获得,并为统计和机器学习模型开辟可能性。
5。计算机和机器学习无法检测数据中的偏差
计算机不知道哪些数据被捕获,哪些数据没有被捕获。对计算机来说,数据只是数字。作为数据科学专业人员,数据的定性分析与实证分析一样重要。
我不喜欢“数据驱动”这个说法。它假设数据是真相的来源,而不是真相的线索。它忽略了数据不能捕捉现实的事实,就像照相机不能捕捉相框外面的东西一样。这导致了偏见、不完整的数据、对基础事实的假设和虚假的相关性。
同样重要的是,如果不是更重要的话,不仅要问数据说明了什么,还要问数据从何而来。要“分析驱动”,而不是“数据驱动”
是什么产生了这些数据?是什么让它产生偏见?它是什么时候生产的?它没有捕捉到什么?最重要的是,我们如何运用自己的启发法和偏见来解释它?最后一部分是不可避免的,所以通过问这些问题来正确地塑造它。
6.计算机和机器学习无法区分相关性和因果关系
当 x 和 y 之间存在关联时,计算机无法确定是 x 导致了 y 、 y 导致了 x ,还是第三个未捕获的变量 z 导致了 x 和 y 。无法确定 x 和 y 是否完全互不因果,相关性是否只是巧合。
这不仅对简单的回归有许多重要的影响(例如,更高的水费是否会导致更高的用水量?)还包括机器学习和深度学习。计算机视觉模型可以将空旷的场地识别为“奶牛”,因为它在场地上而不是在训练过程中与奶牛相关联。
请记住,机器学习最终是一个没有常识的模式识别器,因果关系是一个开放的问题。好消息是天网不会很快到来!
7.数据挖掘是一种逆向进行的科学方法
科学方法假设然后收集数据,而数据挖掘收集数据然后假设。虽然后者看起来足够无辜,但也有可能遇到麻烦。很容易发现巧合的模式,因为你没有一个控制和测试组的发现可能是虚假的。这就是为什么在数据挖掘之后获取新的数据以观察您的发现是否仍然成立是一个好做法。
机器学习和深度学习是数据挖掘吗?是的,他们实际上通过在一个大的假设空间中搜索数据来自动化这个过程。因为这可能会导致过度拟合,所以我们会拿出一个“测试”和“验证”数据集来模拟“新数据”,看看拟合的回归是否成立。
具有训练/测试分割的线性回归(作者图片)
8.并非所有行业生来平等
让我们来比较两个行业:电影流媒体(如网飞)和航天防御(如洛克希德马丁)。他们有什么共同点吗?几乎没有!两家公司都是技术驱动型公司,但一家是面向消费者的流媒体电影,另一家是用军械制造飞机。
数据科学和机器学习都是关于逼近的,这意味着不可避免地会有误差。相关的是,这两个行业对风险的容忍度非常不同。一家电影流媒体公司可能会吹嘘他们有一个人工智能系统,可以学习向消费者推荐什么电影,但是当它给出一个糟糕的推荐时,灾难性有多大呢?嗯,最坏的情况是,您有一个有点恼火的消费者,他浪费两个小时看了一部他们不喜欢的电影。
但是航天防御公司呢?如果一架战斗机上有自动射击目标的人工智能,如果它是错的,会有多灾难性?我们现在谈论的是人的生命,而不是电影推荐!这两个行业之间的风险承受能力差距很大。当然,航天防御公司在实施任何实验系统时都会更加保守。
作为一名数据科学专业人士,你需要了解你所在的行业及其对风险的容忍度。具有讽刺意味的是,高风险行业的高管可能会观察低风险行业并体验 FOMO(害怕错过),这仅仅是因为这种差异没有得到足够的重视。不危及、伤害或引起争议的机器学习应用程序将更容易使用。从事高风险的应用程序将是一个更难驾驭的职业,可能需要博士证书,仍然不会使假阳性/假阴性消失。
9.将机器学习投入生产很难
将数据科学模型和机器学习投入生产真的很难。测试和验证数据集可能在实验室环境中表现良好,但在野外数据可能会有所不同,并且充满意外事件。还有数据腐烂的问题,随着趋势的变化,数据有一个截止日期。当“自动驾驶汽车”上的传感器被重新配置时,也会发生这种情况,使之前的所有数据和模型参数变得无用。这些问题只是触及表面,吴恩达已经承认这是人工智能在放射学方面的一个公开问题。
数据科学家和软件工程师之间存在巨大的鸿沟,这也是为什么许多数据科学家的工作从不离开他们的笔记本电脑。除了这些数据问题之外,数据科学家还需要软件工程技能。正如前面所强调的,重要的是不仅要问数据说明了什么,还要问数据来自哪里,以及数据将被捕获到的环境的受控或不受控程度如何。此外,在您预算数十万(如果不是数百万)美元来获取标记数据之前,请确保您了解该数据的保质期!
10.对你所学的东西进行优先排序是很重要的
在数据科学中,有一种公认的态度,那就是永远保持学习和好奇。这很好,但我认为更重要的技能是对你所学的东西进行优先排序。
外面有如此多的信息,对你所学的东西进行优先排序成为一种无价的技能。我认为最好的方法是找出你感兴趣的问题(而不是解决方案),然后找到解决问题的最佳方法。
很多年前,我意识到我对调度问题感兴趣,并希望一个“人工智能”来调度员工、教室、服务器作业和其他具有各种规则的受限资源。让我失望的兔子洞很有启发性:元启发式、线性规划、树搜索和随机优化。这些都与数据科学无关,但后来我意识到这些技术是机器学习的一个组成部分。这些见解非常有价值,我有了更多的解决方案,可以恰当地解决问题。我也认识到供应商正在销售各种算法作为“人工智能”,而不是机器学习,事实上,我以前做的很多工作都是“人工智能”🤷♂️
朋友们,优先考虑你学的东西,而不是为了学而学!
结论
如果你试图进入数据科学职业生涯,期望和现实之间可能会有很大的差距。这绝对不意味着没有机会。有大量的工作要做,这有助于多样化技能,这样你就能熟练地找到解决问题的正确方法。
如果你喜欢这篇文章,请再次查看我最新的奥赖利的书https://www.amazon.com/Essential-Math-Data-Science-Fundamental-dp-1098102932/dp/1098102932/【数据科学的基本数学】。它有很多类似的信息,可以帮助初学和实践数据科学的专业人士。我涵盖了微积分、假设检验、线性回归、逻辑回归和神经网络。然而,我强调数据背后有背景的重要性,而不是仅仅关注应用数学。
成为数据科学家或机器学习工程师的 10 个技巧
原文:https://towardsdatascience.com/10-tips-to-become-a-data-scientist-or-machine-learning-engineer-8c0700976f9e
迪伦·卡勒伊在 Unsplash 上的照片
数据科学和机器学习在最近十年里获得了很多关注。大量初创公司和高度成熟的公司正在向人工智能领域发展,以进一步加强其产品与数据相关的能力。此外,有相当多的职位需要特定的技能来解决问题。因此,出现了数据科学家或机器学习工程师的职位,他们参与搅动数据,寻找有用的模式,并利用 ML 模型生成实时预测。公司正在寻找合适的人才,但尽管该领域有大量的课程(硕士或博士),却找不到合适的人才。这解释了为什么对数据科学家和机器学习工程师的需求很高。
以下是我给任何打算进入数据领域并成为数据科学家或机器学习工程师的人的一些建议。根据我的经验,经历这些步骤会极大地影响你申请的成功率。
成为数据科学家或机器学习工程师的技巧
我们将看到各种各样的技巧,可以帮助机器学习新手获得数据相关的职位,如数据科学家或机器学习工程师。
与数据科学家对话— 你没听错。为了更好地了解数据科学领域的知识,与在该领域经验丰富的人交谈可能是最有用的。了解 ML 模型的各种优势和劣势以及讨论在数据科学工作流程中不要做什么,对于有抱负的数据科学家来说非常有用。它们可以更好地指导您如何利用数据并将其用于各种目的的整个过程,如探索性数据分析、深度学习、机器学习和许多其他人工智能子集。
建立一个强大的投资组合— 对于那些刚接触数据科学和机器学习的人来说,做大量的在线课程可以帮助建立一个强大的理论基础。然而,通过构建项目并上传到你的公共网站或 GitHub 上,将学到的理论应用到实践中也很重要。很多招聘人员希望看到你的工作证明,以及你如何处理他们与数据相关的情况。在这种情况下,从 GitHub 构建并突出显示项目列表会非常方便和有用,原因有很多。接到众多公司招聘人员电话的几率更高。对于那些期待建立一个强大的投资组合的人,请随意看看我的 GitHub 投资组合。下面是链接。
苏哈斯·马达利(苏哈斯·马达利)(github.com)
润色你的简历— 虽然这听起来很明显,但精心打理你的简历并突出你的主要成就对于有抱负的数据科学家来说会很方便。尽量确保你提到了你申请的职位所使用的工具,如果你缺乏数据科学家相关角色通常需要的经验,也可以增加更多的项目。有一些格式非常吸引人,吸引了招聘人员的眼球。你可以随意从谷歌和必应上搜索各种能突出你技能的简历格式。
拥有良好的沟通技巧 —机器学习和人工智能都是关于将结果传达给大量受众,包括数据工程师、经理、机器学习工程师和软件开发人员。因此,在面试中,面试官希望应聘者有良好的沟通技巧。参加一些在线课程可以在很大程度上帮助培养沟通技巧。此外,每天花大量的时间提高你的沟通技巧会对你的面试经历产生很大的影响。
获得很多理论上的理解 —机器学习和数据科学涉及到很多数学。通过解决一些优化问题或者通过改变一组参数来寻找改进模型的方法,可以帮助你在使用数学时了解机器学习中涉及的复杂性。在各种机器学习模型的工作背后有一个好的理论,可以确保人们在执行优化和超参数调整等操作以构建有趣的模型之前,了解它们在内部是如何工作的。浏览一系列在线课程有助于一个人很好地学习理论,因为他们教授大量的问题来很好地解决。因此,我会建议提高你对机器学习和数据科学概念的理论理解,以增加你成为数据科学家的机会。
学习关键的编程语言——既然你已经学习了机器学习和人工智能背后的理论,现在是时候在现实生活中实践这些概念了。毕竟,是实际应用导致企业转向你的工作及其评估。数据科学家或机器学习工程师最常用的一些语言是 Python 和 R 。还有其他工具,如 SAS ,但以上两个工具使用频率很高。我建议学习 Python,因为它非常容易学习(语法很简单),不仅用于机器学习,也用于更容易的 web 开发和软件工程。另一方面,R 主要用于统计分析,并由研究人员在设计最终架构之前探索数据和算法,最终架构将在研究论文中发表。
在社交媒体上宣传自己——有大量的社交媒体平台,如 LinkedIn ( 脸书也是如此),帮助你宣传你在机器学习和数据科学相关工作中需要具备的技能。不断更新你的个人资料,并与招聘人员保持联系,这样如果他们发现你非常适合的职位空缺,你会是他们第一个联系的人。在 LinkedIn 上添加大量的帖子也可以确保你瞄准大量的受众,并且有可能在招聘人员进行潜在的面试之前,来自一家知名公司的人就认可了这项工作。我建议通过发布你的作品和展示你的作品集来利用 LinkedIn。
从事你课程之外的项目 —这对目前正在攻读工程学或数据科学或人工智能领域硕士学位的学生来说尤其如此。许多学生在理解概念的细节之前,在最后一分钟完成作业。当你在做使用这些概念的辅助项目时,这些主题的内容很容易记住。因此,我强烈建议那些机器学习的新手也建立一些辅助项目,并把它们上传到各种网站或平台上,在那里工作是非常明显的。招聘人员一直在寻找这一领域的人才,如果他们发现你的简介很有趣,尤其是基于副业项目,他们更有可能安排电话与他们的团队成员进行甄选。
准备面试 —虽然这个建议听起来很直观,但有很多候选人不知道数据科学相关职位通常会问的问题。在那段时间里,考虑到所提问题的复杂性,对他们来说破解面试会变得有些困难。因此,一个人必须花大量的时间来准备面试,这将有助于在很大程度上加强形象。在面试中表现出色之后,候选人的安全就有了保证,因为他/她最有可能被录用。因此,必须花费大量时间来准备数据科学家或机器学习工程师的角色。
获得认证 —当你在网上寻找数据相关的课程时,你可能会遇到大量数据科学和机器学习领域的课程。有一些网站,如 Coursera 或 Udemy,实际上有助于建立对机器学习基础的强有力的理论理解。在完成这些课程并获得证书后,把它放在你的文件夹里也是一个好主意,可以向你的个人资料展示可信度。如果招聘人员和招聘经理看到你有资格胜任这份工作,他们会很乐意加入他们的团队。因此,将你的证书加入你的作品集是一件很棒的事情,因为这会增加你被选中的机会。
结论
读完这篇文章后,我希望你能很好地理解事实上有助于你成为数据科学家或机器学习工程师的东西。确保有足够的时间来建立你的档案可能是一件大事,特别是如果你想成为一名数据科学家或机器学习工程师。看完这篇文章,希望你成为一名伟大的数据科学家或者机器学习工程师。万事如意!
如果你想获得更多关于我的最新文章的更新,并且每月只需 5 美元就可以无限制地访问中型文章,请随时使用下面的链接来添加你对我工作的支持。谢了。
【https://suhas-maddali007.medium.com/membership
以下是您联系我或查看我作品的方式。
GitHub: 苏哈斯·马达利(Suhas Maddali)(github.com)
YouTube:https://www.youtube.com/channel/UCymdyoyJBC_i7QVfbrIs-4Q
LinkedIn: (1)苏哈斯·马达利,东北大学,数据科学| LinkedIn
中等: 苏哈斯·马达利——中等
数据科学家的 10 个 VSCode 生产力技巧
原文:https://towardsdatascience.com/10-vscode-productivity-hacks-for-data-scientists-1836f87e0525
借助这些 VSCode 扩展,您的工作效率提高 10 倍
安德里亚斯·克拉森在 Unsplash上拍摄的照片
介绍
Visual Studio Code (VSCode)是数据科学专业人士中最流行的集成开发环境之一。它支持大量的编程语言,自带终端集成、内置调试器、直观的键盘快捷键、Jupyter 笔记本支持和可定制的布局。如果您找不到满足您需求的内置功能,请访问 VSCode 扩展市场。它有超过 30,000 个扩展可供选择,其中一个可能就是您正在寻找的。在本文中,我们精心挑选了 10 个 VSCode 扩展,它们将有助于提高您作为数据科学家的工作效率。
1.AutoDocString
文档字符串也称为文档字符串,是描述 python 类、函数或方法的字符串文字。Docstrings 为试图使用您开发的类、函数或方法的开发人员提供了指南。
AutoDocString 帮助根据定义的变量名、返回值、类型提示和引发的错误生成预填充的文档字符串。
查看这篇关于如何在数据科学项目中使用 AutoDocString 的教程。
2.更好的评论
代码中交织的注释提供了人类可读的描述,这使得维护和调试更加容易。我们经常在注释中记下重要的笔记,只是为了在滚动无尽的代码页时忽略它们。
更好的注释通过将注释分类为重点、提醒、问题和待办事项,帮助在代码中创建更人性化的注释。更好的评论颜色编码不同类别的评论,使其更容易识别。
3.托多 MD
TODO MD 是 VSCode 中的一个高级任务列表扩展,帮助你管理 markdown 格式的待办事项。TODO MD 允许基于各种属性(如颜色代码、项目名称、上下文、标签、截止日期等)对任务进行注释。这简化了组织和搜索任务的过程。让我们在 VSCode 中创建新的 markdown 文件,标题为todo.md
。
- 使用圆括号中的大写字母排列任务列表的优先级,例如
(A)
、(B)
、(C)
- 使用
+
符号后跟项目名称,用项目名称注释任务 - 使用
@
符号后跟上下文名称,用上下文注释任务 - 使用
#
符号后跟标签名称来标记任务,例如#HighImportance,#LowImportance - 使用
{due: YYYY-MM-DD}
为任务分配截止日期 - 使用
{cm: YYYY-MM-DD}
标记已完成的任务和完成日期
待办事项 MD 面板有助于根据各种注释对您的任务进行分组,甚至在过期任务旁边还有一个提醒图标。
4.智能代码
代码完成,也称为代码提示或自动完成,是建议函数、方法、类或关键字名称的工具。在您的集成开发环境中拥有代码完成工具可以极大地提高您的工作效率,因为它减少了手动输入关键字或在文档中搜索类、方法和函数。
IntelliSense 是 VSCode 中常用的代码完成辅助工具。下图显示了 Pylance 的智能感知。请注意,推荐的代码是按字母顺序显示的,我们必须在这些推荐中循环,以找到我们打算使用的方法。
IntelliCode 是一个智能代码完成扩展,它推荐您最有可能使用的代码。IntelliCode 将最有可能使用的代码放在推荐列表的顶部,用星号标记。这有助于节省我们按字母顺序遍历所有可能代码的时间。
5.Python 缩进
在 Python 中,缩进是代码行开头的空格,有助于指示代码块并提高代码可读性。 Python Indent 是一个 VSCode 扩展,有助于纠正 VSCode 的默认缩进。下面是启用和未启用 python-indent 扩展的示例。
适当的缩进使得代码更易于阅读。
6.缩进-彩虹
缩进通常难以阅读,尤其是在带有嵌套缩进的代码中。缩进-彩虹通过对缩进进行颜色编码,有助于使这些缩进更易于阅读。
7.代码拼写检查器
您是否经常在文档字符串或注释中犯愚蠢的拼写错误,然后由同事通过请求更正?使用代码拼写检查器避免这些错误。代码拼写检查有助于执行拼写检查,并更正代码、注释和文档字符串的单词建议。让我们看一个例子。
8.降价预览增强
阅读或写原始格式的批单可能很乏味,令人困惑,尤其是对初学者来说。缩小预览增强版是一款缩小预览器,实时显示对.md
文件的编辑,让您可以快速编辑缩小的文件。
9.Python 的 AREPL
使用 python 的AREPL实时调试您的 Python 代码。
REPL 循环(Read-Eval-Print-Loop)是一种交互式环境,在这种环境中,用户对计算机的输入被读取、评估,并将结果返回给用户。AREPL 代表自动化 REPL [1],它是一个便笺簿,在其中调试、运行和编写代码可以同时完成。每当您停止键入时,都会计算代码并显示输出。但不仅仅是输出,您的局部变量也被保存起来以供检查。更新代码,值会无缝变化。
10.碳
Carbon-now-sh 扩展允许您通过 VSCode 使用 carbon.now.sh 创建美丽的源代码图像。
- 突出显示您希望共享的代码
- 使用快捷键
Alt+Cmd+A
或(【Windows 上的 )或打开命令面板(Cmd+Shift+P
或【Windows 上的 ),然后键入 Carbon。您将被重定向至 carbon.now.sh 并将您所选的代码填入文本框。 - 调整您的形象
- 导出图像
结论
在本文中,我们共享了 10 个 VSCode 扩展,这些扩展对于提高数据科学家的工作效率非常有用。这些扩展广泛覆盖文档、代码格式化和调试领域。我希望这有所帮助。请在下面的评论中自由分享您最喜欢的 VSCode 扩展!
加入 Medium 阅读更多类似文章。
https://medium.com/@edwin.tan/membership
参考
[1] 演讲:AREPL:俄亥俄州克利夫兰的 python | PyCon 2018 实时评测
如何轻松地服务和部署机器学习模型
原文:https://towardsdatascience.com/10-ways-bentoml-can-help-you-serve-and-scale-machine-learning-models-4060f1e59d0d
Moving from Jupyter notebooks to production is not that difficult
毕竟
弗兰·雅克耶在 Unsplash上的照片
如果您是一名数据科学家,您可能会花大量时间开发复杂的 Jupyter 笔记本来执行数据分析、构建复杂的培训管道或计算统计数据。
Jupyter 笔记本在这方面非常棒,它让我们可以立刻构建出想法的原型。
但是,一旦您完成了这项工作,并且对保存的 ML 模型感到满意,会发生什么呢?🤔
这是您开始考虑将它们部署到生产中的地方。你开始工作的时候有没有想清楚这一点?
大概不会。这不怪你,因为这不是数据科学家的核心专长。(尽管行业目前正朝着这个方向发展)
在本教程中,我将展示如何使用一个名为 BentoML 的 Python 库来打包您的机器学习模型并轻松部署它们。
我先给大家介绍一下制作 ML 的概念。然后,我将向您介绍该工具,并涵盖 BentoML 可以让您的生活变得更轻松的 10 种方式。
PS:这不是一篇 clickbait 的文章:所有这些理由都是有效的、有据可查的理由。对于每一个,我将分享代码,解释和我的印象。
事不宜迟,我们来看看🔍
一旦你的模型被训练后会发生什么?
一旦你训练了一个模型,你需要开始考虑与其他团队分享它。
如果您团队中的其他开发人员(例如后端或前端开发人员)想要使用它,他们需要与包装它的某种 API 进行交互。这个 API 必须清晰并有文档记录,有明确的错误记录和数据验证。
如果 DevOps 团队想要管理您的模型的部署,它需要处理它的依赖关系。它通常期望至少有一个运行并服务于您的模型的 Docker 映像。
如果产品团队想要对您的模型进行压力测试或者向客户展示,那么 API 必须能够适应许多并发请求。
接下来会发生什么?作者图片
这里总结一下。
将一个 ML 模型带入生活(即生产)会有很多限制:
- 多 ML 框架的使用和支持(咄!)
- 创建 API 并以最低的性能水平为其服务
- 再现性和依赖性管理
- API 文档
- 监控、日志记录、指标等。
势不可挡不是吗?
在接下来的 10 节中,我们将通过概念、有用的命令和 ML 相关的特性来探索 BentoML 是如何实现这一点的。
1— BentoML🍱:分发您的 ML 模型的标准化格式
BentoML 是模型服务和部署的端到端解决方案。它旨在帮助数据科学家利用通用 MLOps 最佳实践构建生产就绪型终端。
它是另一个 web 框架吗?
不完全是。BentoML 将 ML 项目中需要的所有东西打包成一个名为 的分发格式🍱
更准确地说,便当是一个文件档案,包含您的模型训练的所有源代码和您定义的用于服务的API**,保存的二进制模型,数据文件,docker 文件,依赖关系,以及附加的配置。**
所有的东西都组合成一个单元,并打包成一种标准化的格式。
你可以把便当想象成 Docker 图像,但是对于 ML。
BentoML —作者图片
一份盒饭也是自带的。这简化了任何云基础架构的模型服务和部署。
当你的便当被构建时(我们将在下一节看到这意味着什么),你可以把它变成一个 Docker 镜像,你可以部署在云上,或者使用[**bentoctl**](https://github.com/bentoml/bentoctl)
,它依赖于幕后的 Terraform,并把你的便当部署到任何云服务和基础设施(AWS Lambda 或 EC2,GCP 云运行,Azure 函数,等等)。
如何部署便当—作者图片
2-将模型保存到本地存储并进行版本控制💾
首先,你需要运行:**pip install bentoml**
一旦安装完毕, *bentoml*
命令就会被添加到您的 shell 中:这在接下来的章节中会很有用。
当您的模型完成训练时,您通常会开始使用 BentoML(这一部分不受影响)
事实上,您可以使用 BentoML 将模型保存在特定的文件夹中(称为模型存储),而不是保存在文件系统的某个地方。这有助于为模型的每个版本提供唯一的标签,并确保可再现性。
在下面的例子中,我们保存了一个在 iris 数据集上训练的 SVC 模型。
这将生成一个惟一的模型标记,允许您稍后获取相应的模型。
它还会创建一个以模型标记命名的文件夹。如果查看这个文件夹,我们会发现二进制文件和一个名为model.yaml
的 Yaml 文件,它描述了模型元数据。
作者图片
3—创建推理服务,将模型公开为 API⚙️
一旦模型被创建并保存在模型存储中,您就可以将它转换成您可以请求的 API 端点。要做到这一点,首先必须创建一个调用模型运行器的服务,然后用它来修饰一个函数。
在下面的例子中,当有效负载数据(NumpyNdarray 类型)通过 HTTP POST 请求发送到/classify
端点路径时,用api
方法修饰的 classify 函数运行代码。
然后,通过使用以下命令运行服务,您可以在本地为模型提供服务:
bentoml serve service:svc --reload
这将打开一个 HTTP 本地服务器,您可以使用 Python 请求它
或界面(直接访问 http://localhost:3000))
****
通过 Swagger UI 请求—作者提供的图片
4—制作并定制您的便当🏗
在这里你可以构建一个便当,看看里面有什么文件。这为您的所有项目提供了一个独立于底层工具的标准化结构。
要构建您的便当,您首先需要创建一个名为bentofile.yaml
的文件
这个文件配置如何构建便当:它包括元数据,列出有用的源代码,并定义包列表。
要构建便当,在包含bentofile.yaml
的文件夹中运行下面的命令。
bentoml build
作者图片
现在,如果我们查看便当并检查里面有什么,我们将看到以下文件夹结构,其中包含以下内容:
- API 的描述和模式
- 构建 Docker 映像所需的 Docker 文件
- Python 需求
- 经过训练的模型及其元数据
- 负责训练模型和定义 API 路线的源代码
- 指定便当构建选项的配置(
**bentoml.yaml**
)
作者图片
5—将便当装入 Docker 图像中🐳
一旦创建了便当,您可以使用dockerize
命令来构建一个健壮的 Docker 映像。这是 bentoml 提供的一个非常有用的特性。如果您使用的是 FastAPI,那么您必须手动完成这项工作。
BentoML 提供了这个简单的命令来为您构建图像。
bentoml containerize iris_classifier:latest
将便当容器化——作者的形象
一旦构建了映像,您就可以在您的系统上检查它:
作者图片
这个 Docker 映像是自包含的,用于在本地提供便当或将其部署到云中。
docker run -it --rm -p 3000:3000 iris_classifier:jclapisz2s6qyhqa serve --production
从容器到主人端上便当——图片由作者提供
6——使用跑步者独立于 web 请求扩展推理🚀
Runners 是特定于 ML 的计算单元,它允许推理过程独立于 web 服务器进行扩展。
这意味着推理和 web 请求处理运行在两个独立的进程上。
这也意味着您的推理管道可以有任意数量的运行器,并且可以垂直伸缩(通过分配更多的 CPU)。每个运行器也可以有特定的配置(RAM、CPU 与 GPU 等。)
例如,这种架构允许你拥有一个依赖于三个独立的运行者来处理不同事情的服务。
在下面的例子中,两个运行器(一个执行 OCR 任务,另一个执行文本分类)在输入图像上顺序运行。
你可以在这里了解更多关于跑步者的信息。
7 —支持自适应批处理
批处理是对一组 N 个输入运行预测而不是启动 N 个顺序预测的术语。
这具有优势:它提高了性能和吞吐量和利用加速硬件**(GPU 因加速矢量化运算而闻名)**
FastAPI、Flask 或 Django 等 Web 框架没有处理批处理的机制。
另一方面,BentoML 为此提供了一个很好的解决方案。
事情是这样的:
- 多个输入请求并行运行
- 代理(即负载平衡器)在工作器之间分发请求(工作器是 API 服务器的运行实例)
- 每个工作人员将请求分发给负责推理的模型运行人员
- 每个运行器通过在延迟和吞吐量之间找到一个折衷,动态地将请求分批分组
- 跑步者对每一批进行预测
- 然后,批量预测被拆分并作为单独的响应发布
这一点的美妙之处在于,对于发送多个并行请求的客户机来说,这是完全透明的。
图片由作者修改
要启用批处理,您需要将batchable
参数设置为 True。示例:
点击 了解更多配料 。
8 —平行推理
跑步者有一种优雅的气质。您可以根据需要组合它们,以创建可定制的推理图。在前面的例子中,我们看了两个跑步者依次跑步。(OCR →文本分类)。
在这个例子中,我们展示了通过利用异步请求,运行者也可以并发运行。
平行推理——作者图片
想想有多少次你不得不将 ML 模型合并到一个预测管道中。使用 BentoML,您可以同时运行这些模型,并在最后收集结果。
9—部署到任何云基础架构
如何部署便当—作者图片
便当的好处在于,当它被构建时,你可以用两种方式部署它:
- 通过将 Docker 映像推送到注册表并将其部署到云中
- 通过使用 BentoML 团队开发的实用程序库bento TL来加速部署过程
强烈推荐使用 bentoctl。它有助于将任何构建好的便当作为生产就绪的 API 端点部署在云上。它支持许多云提供商(AWS、GCS、Azure、Heroku)以及同一云中的多个服务(AWS Lambda、EC2 等)。)
我最近用 spaCy 模型为 AWS Lambda 部署了一个(无服务器)API 端点。它非常管用,我只需要一个现成的便当。
你可以通过文档来让它工作,但是简单来说你需要做的就是下面这些:
- 安装 bentoml
- 安装 terraform(检查此链接
- 设置 AWS CLI 并配置您的凭证(参见安装指南)
- 安装 bentoctl (
pip install bentoctl
) - 做了你的便当
- 安装允许在 AWS Lambda 上部署的 aws-lambda 操作符(bentoctl 也支持其他操作符):
bentoctl operator install aws-lambda
- 运行
bentoctl init
生成部署文件。这一步交互地要求您配置 Lambda 函数的部署(设置区域、内存、超时等) - 通过运行
bentoctl build
构建部署所需的映像这一步准备一个 Docker 映像并将其推送到部署注册中心。 - 通过运行以下命令部署到 Lambda🚀
bentoctl apply -f deployment_config.yaml
。配置部署后,这一步依赖于 Terraform 来应用更改
部署完成后,会提示您一个 API URL,您可以请求它与您的模型进行交互。
作者截图
要删除 Lambda 函数,只需运行bentoctl destroy -f deployment_config.yaml
即可。
10 —API 文档和交互 UI
当您部署 BentoML 服务或在本地为其提供服务时,您可以访问一个 Swagger UI,该 UI 允许您在没有任何实现逻辑的情况下可视化 API 资源并与之交互。
这是由带有可视化文档的 OpenAPI 规范生成的,便于后端实现和客户端使用。
大摇大摆的用户界面示例——作者的图片
资源:
- https://towards data science . com/comprehensive-guide-to-deploying-any-ml-model-as-APIs-with-python-and-AWS-lambda-b441d 257 f1 EC
- https://towards data science . com/bento ml-create-an-ml-powered-prediction-service-in-minutes-23d 135 D6 ca 76
- https://neptune.ai/blog/ml-model-serving-best-tools
- https://www . Reddit . com/r/mlops/comments/w4v l6 r/hello _ from _ bentoml
- https://docs . bentoml . org/en/latest/concepts/service . html # runners
- https://github.com/bentoml/BentoML/tree/main/examples
- https://model serving . com/blog/breaking-with-flask-amp-fastapi-why-ml-model-serving-requires-a-specialized-framework
新到中?你可以每月订阅 5 美元,并解锁各种主题的无限文章(技术、设计、创业……)你可以通过点击我的推荐链接来支持我
**https://ahmedbesbes.medium.com/membership **
一千个大脑和 EKG
原文:https://towardsdatascience.com/1000-brains-and-the-ekg-8ef7b1764ccd
形状检测如何推动分类
每个皮层列都包含用于输入分类的位置单元和网格单元。每个专栏都对识别一个项目并将其连接到参考框架进行投票——作者的说明。
2021 年 4 月,著名的技术专家、企业家和大脑理论家杰夫·霍金斯出版了他的新书《一千个大脑》。这本书描述了杰夫关于人类大脑皮层结构的千脑理论。在这篇博客中,我将回顾这个架构,并讨论它对企业级知识图 (EKGs)的长期架构的影响。
本文是关于心电图如何成为组织的中枢神经系统 (CNS)的一部分的系列文章的一部分。就像我们自己的中枢神经系统一样,心电图可以对环境中的信号做出快速反应,并在正确的时间向正确的人发出正确的通知。
这里最重要的观察是,我们的大脑已经进化到可以帮助我们在世界中穿行。心电图本身不会在世界上移动,但他们需要通过我们的组织跟踪客户、产品和想法的运动,当这种运动需要纠正时,他们需要通知正确的人。
杰夫·霍金斯的背景
杰夫·霍金斯的照片(取自 Numenta 网站)。照片经 Numenta 许可使用。
在过去的 15 年里,杰夫·霍金斯一直是人工智能领域最有影响力的思想家之一。杰夫 2007 年的书《T8 论智力》(T9)是第一批展示人类大脑整体架构的书籍之一,重点是新皮层的分层结构。杰夫强烈的感觉到,不了解人脑就无法了解 AI。他还帮助我们理解,人工智能最难的部分几乎总是知识表示的挑战。在过去的十年里,机器学习在训练神经网络方面取得了长足的进步,但它的优势在于看到数据中的模式,而不是理解我们周围的世界。看完杰夫的书,你会意识到,如果我们不知道如何在计算机内存中表示一个分类的结果,如何归纳,我们就不是在解决 AI 的真正问题。我们可以识别项目,但我们不理解项目在我们分类项目周围的其他项目的上下文中的相关性。
我最喜欢引用杰夫·霍金斯的话如下:
“人工智能的关键一直是表现。”
这个观点,自从我在 1980 年代在人工智能的研究生院工作以来,我一直分享,这就是为什么我一直关注 RDF、NoSQL 和现在的 EKG。
千脑架构的关键方面
虽然我不会在这篇博客中涵盖千脑理论的所有方面,但我想指出一些关键的理论元素,它们可能有助于我们关注我们的 EKG 架构。明确地说,心电图不像我们的大脑,就像飞机不像鸟,潜艇不像鱼一样。我们用大脑来理解智能,以及我们的心电图如何才能更智能。心电图是大脑激发的,但是现代 EKG 的建筑与人脑完全不同。
千脑理论试图理解人类大脑皮层的高级结构。该理论假定了以下关键点:
- 人类的新大脑皮层由大约 150,000 个皮层柱组成。每一列包含数以亿计的神经元,这些神经元读取输入信号,并对输入信号进行更高级别的分类。皮质柱也依次由迷你柱组成,每个迷你柱有数百个神经元。
- 每列包含两种类型的单元格:网格单元格和位置单元格。这些细胞从早期动物进化而来,帮助它们在世界中导航。
- 格网单元和位置单元协同工作,通过识别输入的形状和结构来对输入进行分类。皮层列是不断进化的神经网络,将输入数据转化为有用的表示结构。
- 分类的输出是到一个或多个参考帧的链接。你可以把参照系想象成描述我们世界中物体结构的抽象线框图形。理解什么是参照系,以及它们如何与其他事物联系在一起,是智能中的一个中心问题。
- 分类过程高度分布在许多皮质柱上。每一个皮质专栏都与其他专栏合作,对他们的信念和输入应该如何分类进行“投票”。学习本质上是不断调整这些投票系统的权重的过程。
千脑结构的一个关键方面是网格细胞和位置细胞是如何工作的。以下是对这些细胞的简要描述
网格单元
大鼠网格细胞神经元活动的空间自相关图。图片来自维基百科。
网格单元格 是帮助你找到自己在世界上相对位置的单元格。当细胞开始在它们的环境中移动时,它们就进化了。由于植物不经常走动,它们没有进化出这些大脑结构。移动的动物需要发展一种意识,即它们与资源的关系。他们需要走向食物,远离敌对的环境,包括他们的敌人。网格细胞相互连接,构成我们周围世界的“地图”或模型。他们通过另一个叫做位置细胞的细胞连接到他们世界中的特定物品。
位置细胞和网格细胞协同工作,帮助动物导航它们的环境——图片来自维基百科。
位置细胞 是当你处于环境中的特定位置时会触发的细胞。它们将你世界的地图与你世界中的事物联系起来。他们可能会发出信号,“嘿,这里有食物”或“这个地方有危险。”
这些原始细胞一起工作,告诉动物他们在固定的静态地图上的位置。如果他们的世界改变了,他们需要绘制一张新的地图。
我们的大脑如何进化到使用高效的动态地图
在旧地图旁边构建新地图非常简单。您需要将旧地图链接到新地图。每当我们从一个房间走进另一个房间时,我们的大脑就会在地图之间跳跃。但是,如果您的环境在旧地图和新地图中有相似的结构,该怎么办呢?例如,如果旧地图和新地图有相似的食物来源,比如一种你可以吃的植物,会怎么样?动物自然进化出了通过将新地图的一部分重新连接到旧地图来最小化构建新地图所需工作的方法。
在计算机科学中,我们通常称这种技巧为“可组合性”我们能否将大量重复但相似的业务规则在本体的上层重新链接在一起,从而减少重复?可组合性使得我们的本体学家更容易维护这些规则。
但是在大脑能够将相似的结构连接在一起之前,它必须掌握一些复杂的东西。它必须学会如何识别形状是相似的,并且可以连接在一起。不同的形状被合并成一个更抽象的形状。这些形状的概括就是一个参照系。我们使用参照系来学习如何概括。我们的大脑通过将相似的项目联系在一起来“学习”,以保持大脑的效率。很少有动物掌握了这一技巧,这是智力的标志。抽象的表现是智能的关键。
动物可能会从识别地图中的固定项目开始,并将它们与相同的抽象项目表示联系起来。但是如果物品四处移动呢?大脑现在需要识别物品,即使它们周围有不同的结构。项目识别器需要能够感知上下文。如果它们是视觉细胞,即使有不同的光线和方向,它们也能对物品进行分类。当图需要寻找不变结构时,我们称这些查询为同构查询。
当我想到同构查询时,我想到的是识别事物的抽象形状并可以将这些形状与已知的形状数据库进行比较的查询。这类似于参考框架的工作原理。它们是固定的结构库,我们可以在大脑中建立链接。
现在,让我们盘点一下我们用来构建心电图的各个部分,并寻找千脑理论中各个功能之间的相似之处。
顶点、嵌入和规则
当我们建造 EKG 时,我们没有储存在 EKG 中的皮质柱的概念。由于皮质柱是从早期的大脑结构复制而来,以帮助动物适应环境,这并不奇怪。然而,心电图发展很快,我们看到许多不同类型的子图具有专门的功能。
像神经元一样,我们也有顶点和边,用来穿越 EKG。顶点和它们的属性也是从它们卑微的起源进化而来的,穿孔卡片用它们的列填充平面文件。在这个过程中,我们的顶点之间的关系,称为边,也进化了它们的属性。
以及关于我们的关键业务实体(客户、接触点、产品、服务器等)的知识。),我们还可以在我们的图表中存储关于相似项目如何相关的知识。这些“相似性”向量被称为嵌入。虽然它们是新的,但是嵌入可以以类似于皮质柱的方式使用。嵌入是快速相似、分类和推荐的关键。分类提问— *这件物品与我们过去见过的其他物品有何相似之处?*我们可以获取任何新的项目,找到它的嵌入,并计算与图中标记项目的距离。关键是使用类似于FPGA的并行计算硬件来近乎实时地(低于 50 毫秒)进行这些计算。
一旦我们对新数据进行了分类,我们就可以添加属性,创建新链接,并执行在正确的时间通知正确的人的功能。
尽管千脑理论还有许多其他结论,但我想重点谈谈这一理论可能会如何影响我们构建心电图的方式,以及机器学习需要如何集成到心电图中,以达到我们企业数据库所需的智能水平。
我们想停下来思考一下我们在企业知识图上运行的查询类型。查询有许多子类型:
- 在我们的图中查找项目的查询(例如,广度优先搜索、深度优先搜索)。
- 寻找项目间路径的查询(寻路)。
- 寻找项目群集(中心性)的查询。
- 查找相似项目的查询(产品图中的相似产品、兴趣图中的相似项目、医疗保健图中的相似患者)。
- 寻找相似形状的查询(同构查询)并将它们与参考模式(参考帧)进行比较。
- 在基于图形的决策树等结构中执行确定性业务规则的查询。这就是本体论派上用场的地方。
请注意,这些算法可以一起工作。您可以编写深度优先搜索,查找与相似形状相关的项目。然后,您可以在这两个形状之间找到一条路径。您也可以用新链接将相似的形状链接在一起。
位置和网格单元如何成为分类器
杰夫和他的团队正在研究已经在动物大脑中存在了数亿年的网格和位置细胞是如何进化来解决图像识别、声音识别和危险预测等复杂问题的?杰夫的理论是,这些细胞可以重新用于识别在我们世界中运动的事物的结构。我们可以识别情感、思想、声音、词语、理论以及由其他先前不相关的想法组成的任何想法的结构。随着我们的进化,这些结构变得越来越抽象。
我们大脑中所有 150,000 个皮层列本质上都是分类器回路。它们都从它们的输入端读取并向它们的输出端发送信号,并指示投票过程应该考虑什么参考系。尽管我们过去认为这些是严格的层次结构,但现在我们知道信号在抽象层次结构中上下移动,以帮助我们将注意力集中在我们需要的领域,因为项目的分类变得清晰。
心电图是我们公司的中枢神经系统
在我之前的博客中,我讨论了心电图如何慢慢演变,以承担额外的任务,使商业用户能够对变化做出快速反应。添加、更新或删除的任何顶点或边都可以触发规则,这些规则也作为图中的决策树来实现。不再需要将数百万字节的数据移动到外部规则引擎中。在我们的 EKG 中,一切都可以以快速指针跳转的方式执行。
千脑理论帮助我理解了未来几年我们的心电图将如何演变。可视化动物如何进化位置和网格细胞也帮助我可视化 EKG 进化。
经济高效的知识图表的秘密是不断扫描图表中的新模式,以帮助我们做皮层列所做的事情:不断查看发生了什么变化,并利用图表中的共享规则来重新分类和丰富我们的信息。这些规则也需要不断地被扫描,以寻找增加规则可组合性的模式。规则需要不断发展,以变得更高效、更节能、更紧凑。关于心电图中现代规则如何工作的更多信息,请参见我关于知识图规则的规则的博客。
图形机器学习的作用
我们面临的挑战是,随着模式识别决策树中规则数量的增长,它们变得更加复杂,也更加难以管理。这就是机器学习变得越来越重要的地方。像流行的 PyTorch Geometric 这样的图形机器学习库只在出现了几年,并且通常由小团队驱动。如果不移动大量数据,它们还不容易集成到我们的生产十亿顶点图中。
我坚信,随着这些库的成熟,并以开放标准编码,如 GQL ,所有企业级分布式图形数据库供应商都将提供它们,作为其开箱即用解决方案的一部分。
角色测试和人在回路中
在我们跳出让机器学习自动改变我们的本体和决策树规则的困境之前,我们想强调的是,对于机器学习驱动的过程,可解释性、可解释性、透明度和人类管理的回归测试是我们知识图中质量控制的关键值。本体可能很快变得不稳定,尤其是当高级本体结构被改变时。幸运的是,机器学习还可以对本体变化的影响进行分类,甚至推荐新的回归测试。
结论
千脑理论引发了我想象心电图演变能力的巨大飞跃。还有很多未知。获得针对图遍历优化的低成本全定制 ASICs 仍不确定。虽然我仍然希望这种硬件能比当前最先进的分布式图形数据库再提高 1000 倍的性能,但软件和硬件仍有许多地方需要调整。最后,我想说 2022 年可能是心电图非常好的一年。
11 数据科学的美学数据可视化(第三部分)
原文:https://towardsdatascience.com/11-less-used-but-important-plots-for-data-science-dede3f9b7ebd
一些独特的数据可视化技术,用于深入了解数据
作者图片
动机
数据就是美。当我们想象它的时候,它的美就出现了。可视化是快速了解大量数据的一种更方便的方式。在深入分析的情况下,我们应该有数据的图形表示技术的想法。我们经常使用bar charts, histograms, pie charts, boxplots, heatmaps, scatter plots, line plots, etc.
这些典型的图对于数据可视化是必不可少的。除了这些被广泛使用的情节,还有许多高超的情节却很少被使用。当我们想到分析数据和艺术地表现数据时,这些图有助于完成工作。
*[Complete data visualization guideline is available here..]*
https://medium.datadriveninvestor.com/ultimate-guide-to-data-visualization-for-data-science-90b0b13e72ab
目录
[**Parallel Coordinate Plot**](#1531)
[**Hexagonal Binning**](#168a)
[**Contour Plot**](#b18d)
[**QQ-plot**](#cfea)
[**Violin plot**](#57d0)
[**Boxenplot**](#1f20)
[**Swarm plot**](#5150)
[**Point Plot**](#a7a2)
[**Word Cloud**](#e209)
[**Sunburst Chart**](#dee3)
平行坐标图
实际上,我们可以可视化多达 3 维的数据。但有时,我们需要可视化更多的三维数据来获得洞察力。我们经常使用主成分分析或 t-SNE 来降低维度并绘制它。在降维的情况下,大量的信息可能会丢失。在某些情况下,我们需要考虑所有的特性。平行坐标图有助于做到这一点。但是怎么会!让我们看看..
虹膜数据集的平行坐标图(图片由作者提供)
看上图。横线(平行轴)代表鸢尾花的特征 ( *Petal length, Sepal length, Sepal width, Petal width*
) 。类别有*Setosa, Versicolor and Virginica*
。上图将物种编码为 Setosa →1,Versicolor →2,Virginica →3。 每条平行轴包含最小值到最大值(如花瓣长度从 1 到 6.9,萼片长度从 4.3 到 7.9 等。)。例如,考虑花瓣长度轴。说明**Setosa**
品种的花瓣长度比其他两个品种小,**Virginica**
品种的花瓣长度最大。
所以,有了这个图,我们可以很容易地得到数据集的整体信息。数据集看起来像什么?让我们看看。
*[N.B. — I have used the* [***iris***](https://www.kaggle.com/datasets/uciml/iris) *dataset which is a public domain dataset under “*[*CC0: Public Domain*](https://creativecommons.org/publicdomain/zero/1.0/)*” license.*]
让我们用 ***Plotly Express***
库[1]将数据可视化。 **Plotly**
库提供了一个交互式绘图工具。
我们也可以使用其他类似[**pandas**](https://pandas.pydata.org/docs/reference/api/pandas.plotting.parallel_coordinates.html)**,** [**scikit-learn**](https://learn-scikit.oneoffcoder.com/plot-parallel-coordinates.html), [**and matplotlib**](https://www.geeksforgeeks.org/parallel-coordinates-in-matplotlib)
https://www.geeksforgeeks.org/parallel-coordinates-in-matplotlib的库来绘制平行坐标。
六角宁滨
六边形宁滨是用六边形直观表示**density of 2D numerical**
个数据点的过程。
我已经考虑了上一节的数据集来绘制上面的六边形宁滨。[**Pandas**](https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.plot.hexbin.html)
库允许我们绘制六边形宁滨[2]。我已经展示了寻找sepal_width
和sepal_length
列的密度的图。 **(df is a pandas DataFrame)**
如果我们仔细观察这个图,我们会发现总面积被分成无数个六边形。每个六边形覆盖一个特定的区域。我们注意到六边形有颜色变化。一些六边形没有颜色,一些是浅绿色的,一些是深的。根据图右侧显示的色标,颜色密度随密度而变化。刻度表示有颜色变化的数据点的数量。六边形没有填充颜色,这意味着该区域没有数据点。
其他像[**matplotlib**](https://matplotlib.org/stable/api/_as_gen/matplotlib.pyplot.hexbin.html) **,** [**seaborn**](https://seaborn.pydata.org/examples/hexbin_marginals.html)**,** [**bokeh**](https://www.geeksforgeeks.org/python-bokeh-plotting-hexagon-bins-on-a-graph/)(interactive plot)
这样的库也可以用来出图。
等值线图表
2D 等值线密度图是显示特定区域中数据点密度的另一种方式。这样做是为了找出两个数值变量的密度。例如,下图显示了每个阴影区域中有多少个数据点。
为了生成上面的图形,我使用了 plotly 库,因为它有助于绘制交互式图形。相同的**iris**
数据集已用于绘制图表,以显示两个变量sepal_width
和sepal_length
的密度。
其他的库,像 seaborn , **matplotlib,**等等。,也可以使用。
QQ 图
QQ 情节是另一个有趣的情节。QQ 代表分位数——分位数图*(分位数/百分位数是一个范围,在该范围内,指定百分比的数据下降。例如,第 10 个分位数/百分位数意味着在该范围之下找到 10%的数据,而在该范围之上找到 90%)。*直观检查数值变量是否正态分布的一种方式。让我解释一下它是如何工作的。
(a)样本分布(b)标准正态分布(图片由作者提供)
图是一个样本分布;另一方面、、**、、*、**是标准的正态分布。对于样本分布,数据范围从**10 to 100**
(10 到 100 之间的 100%数据)。但是对于标准的正态分布,100%的数据保持在范围**-3 to 3 (z-score)**
**之间。*在 QQ 图中,两个 x 轴值都被分成 100 等份(称为分位数)。如果我们将这两个值绘制在 x 轴和 y 轴上,我们将得到一个散点图。
QQ-Plot(图片由作者提供)
散点图位于对角直线上。这意味着样本分布是正态分布。然而,如果散点图位于左边或右边,而不是对角线,这意味着样本不是正态分布。
导入必要的库
生成正态分布数据。
绘制数据点的分布。
图表显示数据呈正态分布。所以我们用数据点做 QQ-plot,检查一下是否正态分布。
该图显示散点图点位于对角线上。所以,是正态分布的。
小提琴情节
小提琴的情节与盒子的情节有关联。我们从小提琴图中得到的另一个信息是密度分布。简单地说,它是一个结合了密度分布的箱线图。所以我们用箱型图来对比一下。
*在小提琴图中,小提琴中间的一个白点表示中点。实心框表示**四分位数范围(IQR)。*上下相邻值是异常值的围栏。超出范围,一切都是离群值。下图显示了这种比较。
盒子情节和小提琴情节的共同成分。所有学术级别的总薪酬[3]。
让我们看看**iris**
数据集的sepal width
的小提琴图。
我们还可以通过传递species
列名来绘制不同物种的小提琴图。
你也可以使用其他库,比如 plotly 、 matplotlib 等等。,来图谋小提琴的阴谋。
博兴图
Boxenplot 是由 seaborn 库 引入的一种新型盒图。对于方框图,方框创建在四分位数上。但是在Boxenplot
中,数据被分成更多的分位数。它提供了对数据的更多洞察。
**iris**
数据集的箱线图显示了**sepal_width**
的数据分布。
上图显示的方框比箱形图多。这是因为每个方框代表一个特定的分位数。
不同species
的sepal_width
的箱线图。
点图
请看下图。有一些被称为误差线的垂直线和一些连接这些垂直线的其他线。让我解释一下它的确切含义。
点图(图片由作者提供)
点状图 是用上图所示的点的位置来表示一个数值变量的中心趋势的一种方式,误差条表示变量的不确定性(置信区间【4】。绘制线图是为了比较不同分类值的数值变量的可变性[4]。
让我们来看一个实际的例子
为了绘制图表,我使用了 seaborn 库和**iris**
数据集(在平行坐标部分提到过)。**
该图显示了不同种类的鸢尾花的萼片宽度的变化。我们还可以绘制多个点图,如文章[4]所示。
群体图
虫群剧情是另一个受‘‘*beeswarm*’’
启发的有趣剧情。有了这个图,我们可以很容易地得到不同的分类值是如何沿着数轴分布的概念[5]。此外,它绘制的数据不会与数据点重叠。但是对于大型数据集来说,效果并不好。
Python 实现的蜂群剧情为 iris 数据集。
你会在这里 找到蜂群剧情 的不同实现。
词云
**单词云情节背后的想法很简单但是很有趣也很有用。假设我们有一大块文本文档。单词很多,有的很频繁,有的很少见。在词云图中,所有的词都被绘制在一个特定的区域中,频繁出现的词被突出显示(以较大的字体显示)。有了这个词云,我们可以轻松找到重要的客户反馈、趋势政治议程话题等。,一目了然[6]。
实现字云剧情—
*[N.B. — I have used* [*Top Games on Google Play Store*](https://www.kaggle.com/datasets/dhruvildave/top-play-store-games) *dataset for creating the cloud. The dataset is open for public use under “*[*Database: Open Database*](http://opendatacommons.org/licenses/odbl/1.0/)*” license.]*
我想在 google play 商店找到游戏的热门类别。这就是为什么我检查了每个类别的频率。
我们来画一下。
该图显示了所有类别,突出显示了具有最大频率的类别。我们也可以用这个图从文本中找到常用的单词。(文章[6]帮我实现剧情。)
旭日图
这是一个定制版的甜甜圈图或饼图,将一些额外的层次信息整合到图中[7]。
旭日图(图片由作者提供)
整个图表分为几个环(内侧到外侧)。它保存了层级信息,其中内环在层级的顶部,外环在较低的顺序[7]。
上述旭日图的数据(图片由作者提供)
如果我们仔细观察数据集,第一列包含一年的季度;每个季度下面都有几个月,每个月都有几周。这个场景用上面的 sunburst 聊天描述。没有层次值的旭日图与饼图或圆环图一样。
Python 的***Plotly***
库提供了一个简单、美观、交互式的工具来绘制旭日图。
旭日图的实现【8】—
数据集的样子…
*[N.B. — The tips dataset is* ***plotly’s*** *built in dataset under MIT open source license.]*
绘制数据集的旭日图。
sunburst 类的**path**
属性提到了层次结构,其中sex
位于层次结构的顶部,然后是day
和time
。
结论
数据可视化是数据科学不可或缺的一部分。在数据科学中,我们玩数据。手动分析少量数据是可以的,但当我们处理成千上万的数据时,这就变得非常麻烦,有时甚至是不可能的。如果我们找不到数据集的趋势和见解,我们可能无法处理这些数据。希望上面的图可以帮助你更好地形象化数据,并深入了解数据。
***Full notebook is available here***
Reference
[https://plotly.com/python/parallel-coordinates-plot/](https://plotly.com/python/parallel-coordinates-plot/)
[https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.plot.hexbin.html](https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.plot.hexbin.html)
Hintze, V. P. A Box Plot-Density Trace Synergism. *Am. Stat*, (52), 181 (Open Access Journal).
[seaborn.pointplot — seaborn 0.12.1 documentation (pydata.org)](https://seaborn.pydata.org/generated/seaborn.pointplot.html)
[seaborn.swarmplot — seaborn 0.12.1 documentation (pydata.org)](https://seaborn.pydata.org/generated/seaborn.swarmplot.html)
[Word Cloud in Python | How to Build Word Cloud in Python? (analyticsvidhya.com)](https://www.analyticsvidhya.com/blog/2021/05/how-to-build-word-cloud-in-python/)
[Create a sunburst chart in Office — Microsoft Support](https://support.microsoft.com/en-us/office/create-a-sunburst-chart-in-office-4a127977-62cd-4c11-b8c7-65b84a358e0c#:~:text=The%20sunburst%20chart%20is%20ideal,similar%20to%20a%20doughnut%20chart.)
[Sunburst charts in Python (plotly.com)](https://plotly.com/python/sunburst-charts/)
完成数据可视化指南
**https://medium.datadriveninvestor.com/ultimate-guide-to-data-visualization-for-data-science-90b0b13e72ab
你也可以朗读美学数据可视化的文章。
面向数据科学初学者的完整统计指南
**
了解更多数据科学的 11 种方法
原文:https://towardsdatascience.com/11-ways-to-learn-more-data-science-1c5ab293be2d
使用这些方法让你的专业知识更上一层楼!
来自安斯佩的亚伦·伯登https://unsplash.com/photos/xG8IQMqMITM
0。但是首先,请注意阅读你“已经知道”的东西
我热爱教育。我在很多年级都当过老师,我拥有一个辅导中心,为 4 到 18 岁的孩子服务。十多年来,我亲自辅导过数百名学生。我花了很多时间试图向学生、同事、朋友、直接下属教授概念。我这样说是因为有一件事我恳求你们听一听,因为这是我在各个层次的学生身上看到的最重要的问题:
我们的自我评估几乎总是高估我们对一个话题的掌握程度。
我们只是不知道我们不知道什么。人们不善于发现自己理解中的小缺口。对于任何主题,我们都有几行知识可以滔滔不绝地讲,但我们只是在看到它们之前不知道存在哪些边缘情况。我们并不知道每个话题是如何与每个相关话题交叉的,很多时候,这些答案并不容易弄清楚。这就是专业知识。这就是为什么经验是有价值的。
即使是基本的数据科学主题,也有太多我们还没有遇到的东西。
出于这个原因,我发现阅读我已经知道的话题是有价值的。总是有新的角度,新的方式来解释它,新的方式来揭示更多的光。统计很难。编码很难。我们收集了大量的知识,但是存在一些统计问题和编码情况,它们会完全难倒你。坦率地说,这是因为经过几年的研究,我们的理解仍然很肤浅。
此外,即使阅读没有给你新的知识,反复接触一个话题也会加深你的熟悉程度。当你对一个主题更熟悉时,当你花更多时间思考它(最好是从多个角度)并加强你大脑围绕该主题的神经连接时,你会对该主题有更快更清晰的思考。
因此,积极阅读所有关于数据科学的资料,即使你认为你已经知道了。阅读数据科学、商业分析和编码中常见的情况。
当然,如果你知道基本知识,有时你可以自己想出所有的推论,如果你对正确的问题思考足够长的时间。但是阅读其他人的生活经历、观点和解释是掌握的捷径。
也就是说,让我们深入了解一下我们可以从哪里获得这些知识。
一、买二手书
有一百万本书与数据科学家有关。从许多人认为必须阅读的经典著作,如 O'reilly 系列,到统计学和人工智能的开创性教科书,再到一位经验丰富的分析师决定写下职业生涯中有价值的见解的鲜为人知的探索,数据科学知识比所有这些书籍的总和还要多。
老实说,我只是在亚马逊上搜索我正在研究的主题,并购买一堆相关的二手书籍。当然,有些结果并不合适。但是对于每本 5 美元的书,考虑到即使是一本好的数据科学书籍也会对你的职业生涯产生巨大的影响,我认为我的时间花在阅读它们上比研究买哪本书更好。
所以不要害羞,去拿 15 本 DS/Stats 的书,每本 5 块钱。当然,你可能最终看不到其中的一半,因为此时它们并不相关/不值得一读。但是我保证你最终会从你所读的东西中获得无数有用的知识。
更不要说把你的头脑包裹在所有要知道的东西的范围内的背景和信心。仅仅阅读十几本书的目录就能使你对要知道的东西有一个全面的认识。
二。从媒体获得推荐
你已经在 Medium 上了,所以你可能已经知道这个平台上存在大量的数据科学文章。有优秀的人可以追随,有充满优秀文章的优秀渠道/出版物:除了面向数据科学的大量文章之外,还有专注于统计学、因果推理、深度学习、时间序列、商业分析和策略、产品管理的出版物或个人作家——无论你需要知道什么。
会议讨论、白皮书和学术出版物当然仍然是研究发展的正式渠道。但是如果你没有超越基准,它们就不是你的数据科学方法论细节的地方。
中级是入门级、中级、高级甚至行政级别人员可以讨论他们的数据科学方法和流程的地方。它甚至可能是当今大多数职业数据科学家交流思想和方法的主要渠道。他们使用的库和工具,他们如何考虑问题,他们的代码看起来像什么,以及常见的混淆点——都在那里。这些文章中的许多都一步一步地带您了解整个方法,其中穿插了代码和解释。这就像有一百万个同事,你可以每天从他们的每一步和每一个想法中学习。因为即使你理解像正规化这样的主题,仍然有很多关于实践中发生的事情的讨论。
当然,媒体时好时坏——任何人都可以发表文章。流行的标题可以是 clickbait。但它比白皮书更简洁,比听报告更简洁,最好的文章可能比新的《变形金刚》论文更与你的工作相关。
所以好好利用。关注那些撰写与你的工作(或期望的工作)相关的主题的作家和出版物。把它设置好,这样当相关文章写出来的时候,你就可以收到电子邮件更新了。在我的 android 手机上,我的 Medium widget 总是显示大约 10 篇相关文章,我每天都在上面阅读新的 10 篇文章。
三世。订阅电子邮件简讯
有大量的数据科学电子邮件简讯,它们写得很好,并提供该领域热门话题的每周或每月更新。订阅 Batch 或 Import 人工智能可以让我了解数据科学的应用、该领域正在出现的困境以及有趣的新发展。
为了找到这些,有许多媒体文章,人们友好地编辑了一个推荐列表。如果时事通讯是免费的,为什么不订阅呢?
还有 Substack——你可以付费订阅电子邮件列表。就像二手书一样,当你投资了解你的职业时,会有很高的投资回报率。如果这是提升你职业生涯的费用,不要对墨西哥卷饼的钱太害羞。光是财务红利就非常值得——更不用说我们从我们的领域的繁荣中获得的意义和目的了。
因此,订阅你能找到的所有好的数据科学电子邮件。虽然你可能会忽略其中的一些电子邮件,但你阅读的那些邮件将提供对数据科学的宝贵见解。他们也很有趣!尽情享受吧!
四世。阅读文档、指南,是的,甚至是代码。
实际阅读 所有 你正在使用或考虑使用的 Python 库或数据科学工具上的可用信息有很多价值。是的,整个文档指南。
无论是 Databricks 的用户指南还是整个 scikit-learn API,都有很多关于每个工具可以做什么,如何工作,甚至为什么会这样工作的内容要学习。
不要只使用工具的一个功能而不了解它还能做什么。您可能会对一个通用工具提供的实用程序感到惊讶。
该注释包括 Python 本身。不要生活在对 Python 所有奇妙功能的无知中。阅读它的文档/API。有很多方法会派上用场,比如内存化、序列化、I/O、并发、集合、itertools、functools 和 operators 以及 pathlib。别忘了还有熊猫、熊猫和松鼠。
您甚至可以学习工具之外有价值的一般数据科学。scikit-learn API 是对模型的一个很好的调查,并且有一些比较它们的图表。类似地,许多因果推理库都有包含因果推理数学笔记的指南、讨论模型利弊的图表和流程图,以及对可以利用因果推理的业务问题的深入讨论。
对于入门级的数据科学家来说,还有另一层深度似乎有点令人生畏:阅读一个伟大的 Python 库的整个代码库。我从阅读 spaCy 的代码中学到了很多。您将了解每个类、方法和属性,更深入地理解它们实际上是如何工作的,并学习如何编写好的代码!
当然,你读得越多,学得越多。阅读一个工具的整个 API 或者整个源代码是非常有教育意义的。但是当然,考虑一下什么时候值得,什么时候不值得。一个有很多明星和贡献的回购可能是如何编写代码的一堂好课,但一个未知的回购可能会教你反模式。或者,如果你正在做一个 spike,并且为你的项目考虑一堆不同的库,阅读每个库的整个 API 可能比必要的更深入一点(但是这是理解库之间的差异的一个非常好的方法!).像往常一样,做一个快速的成本效益评估来决定此时什么样的深度适合你。
但是,如果唯一的障碍是我们的懒惰,那么也许是时候阅读文件了:)
五、数据科学课程
我想我们都听说过在线数据科学课程。
首先,有 100 家初创公司宣称,只要你完成了他们的数据科学迷你学位,就有能力给你一份数据科学的工作。当然,这些课程确实倾向于侧重于基础知识,但说实话,其中有很多好的信息。如果你能从这些公司免费或便宜地学习一些迷你课程,那么不要错过免费的知识。
Coursera、Udacity 和 EdX 等 MOOC 平台也有自己的数据科学课程,通常由教授与大学合作教授。也许他们承诺给你一张证书,让你的简历脱颖而出。现在我不能保证证书有价值,但我确实认为课程中的知识肯定有价值。
Udemy 也有许多课程,可以是对你的职业生涯很重要的工具或主题的 20 小时简要介绍。课程只要 10 美元左右,所以这可能比你这周在墨西哥卷饼上涂上番石榴更有价值。再次,考虑你职业生涯的长期投资回报率。
许多顶级大学也在网上发布了他们的数据科学课程。你可以找到教学大纲,包括演讲幻灯片、书籍/论文推荐和作业,实际上你可以自己选修这门课。
不要只找名为“数据科学”的课程搜索人工智能、因果推理、贝叶斯概率、统计和决策都将产生教授数据科学的课程。我们也不要忽视编码课程。从基本的 python 到掌握事件总线和并发性,总有大量的课程会让你的知识更上一层楼。
额外说明:spaCy 有自己的用 spaCy 学习 NLP 的课程。希望更多的顶级图书馆将跟随这一趋势,至少提供一个织机演练。
六。观看 Youtube
如果说 Medium 是一座关于数据科学的文字山,那么 Youtube 就是图像和声音的海洋。
像媒体作家一样,有大量的 Youtube 创作者在制作数据科学内容。人们在讨论核心概念时,会分享他们的代码或制作精美的幻灯片。如果你深究一下,你会发现那些给出优秀解释的人,他们肯定会升级。有 Kaggle 员工解决问题的视频,每个 ML 模型如何工作的可爱演示,以及总结为 5 分钟的热门新论文。
本文前面的一些部分,如用户指南和在线课程,也存在于 Youtube 上。像雪花这样的公司会发布教学视频,你可以通过观看来掌握这个工具。至于课程,你可以观看整个大学课程中关于数据科学、线性代数、最优化、因果推理或编程的每一堂课。
还有大量与您的数据科学职业相关的会议演讲录音。有关于论文的演讲,有教授的演讲,有关于生存分析等方法的演讲——如果你搜索它们,它们都会出现。
此外,你可以搜索一家公司的数据科学讲座(也许可以查找关键团队成员)。成为您团队中的数据科学家,观看 FAANG 公司关于 ML 架构的讨论,或者关注数据科学如何用于解决公司的业务问题。
从谷歌最近流行的与 ML 交朋友,到永远迷人的 StatQuest,到每天都在发明因果推理的教授和公司的演讲,光是 Youtube 上的知识就肯定有职业价值。
七世。阅读所有谷歌搜索结果
谷歌是一个兔子洞,但它非常非常有价值。
每当我对一个话题感到好奇或者正在研究这个话题时,比如说“分类变量的正则化”,我就会用谷歌搜索这个短语。然后,我至少打开前 10 个链接,阅读这些页面,并做笔记。
结果可以是维基百科、stack exchange 或其他论坛、博客文章和媒体文章、研究论文和白皮书、教授的网站、一本书的摘录等等。
当我读这些的时候,我倾向于发现一些能加深我理解的见解。我也会想到更深层次的问题,然后我会用谷歌搜索。由于这种谷歌搜索分支到许多相关的问题,它有助于将所有这些搜索结果复制到一个文档中;把这些笔记和问题组织好。
或者,有时我会根据我们正在解决的业务问题进行搜索,而不是根据数据科学概念进行搜索。以前人们是如何解决这个问题的?哪些考虑是相关的----相关的问题和相关的解决办法。
我认为这一类别包含了许多不同的资源。但是,确实没有什么可以代替大力搜索你正在研究的东西。优秀的数据科学家不会重新发明轮子,他们会获取并应用所有已经完成的统计和数据科学项目的知识。
VIII。面试准备内容
有大量的面试准备内容,它可以为你的数据科学职业生涯提供大量有用的知识。我喜欢阅读标题为“50 个棘手的数据科学面试问题”的文章,因为我总是能学到一些我不知道的关于 catboost 这样的模型或降维或可解释性这样的目标的东西。“让你得到一份数据科学工作”的初创公司有自己的面试准备内容,也有类似的关键数据科学信息汇编。
Interview query 围绕真实数据科学工作的每个方面都有大量的问题。从关于因果关系的产品发布问题到实践 SQL 问题,有无限的内容可以加深您的理解。他们还撰写了大量内容,为解决数据科学问题和选择正确的模型提供框架、技巧和见解。
我还会提到 Brilliant.org,在那里我发现了一些可爱的教育作品。他们关于线性期望的文章教会了我很多。除了为面试做好准备之外,学习一些复杂的数学也很有趣,它加深了我们对概率和统计的理解。
也可以看练习面试的视频。人们张贴 FAANG 面试问题被回答的例子。看完这些总是让我有一个新的想法,无论是如何解决非正态数据分布,还是提出关于业务问题的正确问题的框架。
九世。竞赛
最后,哪里有竞争,哪里就有知识。
通读所有历史上的 Kaggle 竞赛提供了无数问题公式的例子——数据科学可以用于的数据集和目标。如果你的职责是提出或重新定位一个数据科学项目,没有什么可以替代通读明智的输入和输出的例子。
你也可以通读 Kaggle 笔记本,在那里人们已经编写了清理数据集和运行 ML 模型的代码。这些不仅可以提供您不知道的好代码或方法的示例,而且如果您需要清理类似的数据集或运行类似的 ML 模型,它还可以提供一个起点。
同样,Leetcode 问题也是一个很好的学习机会。可能不是数据科学,但是掌握 Python 让我们的工作变得更轻松。通读 Leetcode 问题的 Python 解决方案加深了我对一些 Python 方法、属性和技术的熟悉,这些可能我已经看到过,但我自己不会轻易使用。
参加 Kaggle 和 Leetcode 竞赛肯定会有帮助。在比赛之外用自己的时间去挑战也是一样。但是仅仅通读其他人的解决方案或提交的内容就能教会我们很多东西。有些人认为,没有人可以代替自己去做,也许是因为这迫使你去实践一个过程。但是,如果你直接找到解决方案,你可以通读更多的解决方案——至于过程,你可能应该从专家那里学习一个好的解决方案,而不是自己想出来。
X:数据科学推特
只做一个数据科学的 Twitter,跟着数据科学的海报走就行了。点击进入 Twitter 应用程序,就能看到最近论文的帖子,以及关于该领域发展方向的深刻问题,这真的很有帮助。关注教授、数据科学公司、数据科学内容创作者。有些账户非常棒,会以惊人的高频率在新论文上发表一句话的总结。
不要用分散注意力的内容来冲淡精彩的内容。把这个留给另一个账户吧。或许更普遍的是,将这些数据科学电子邮件订阅、youtube 推荐和媒体插件放在最前面和中心,减少其他内容。这是你的事业,不是吗?我保证,被学习消耗最终是非常有益的。
XI:解决更多的商业问题
这个列表可能应该有 5 或 7 种方式,然后我决定 10 种,但现在我们在 11 种,因为我们不能把这一种排除在外。
通过与数据科学家以及其他利益相关者(如产品经理)一起工作,我学到了很多东西,为公司创造最终产品。
很明显,你可以直接从其他数据科学家那里学习。他们可能会教你你不知道的数学、模型或因果概念。你可能会从它们的编码方式中学到新的库、方法和语法。但是,在朝着一个真正的商业目标努力的过程中,你会被迫学习许多其他的方法。
为主要产品计划提供信息的分析需要细致入微的讨论,甚至可能违反直觉。
当用数据做商业决策时,因果推断几乎总是会抬头。当分析师和项目经理注意到数据中的相关性时,公司应该只在这些相关性实际上与因果关系一致时才采取行动。如果不是,那么这可能是完全错误的商业行为。如果我们在比较其他关键协变量不平衡的组,我们需要对其进行校正以得出业务决策。我们可能需要创建准实验,这可能会推动我们推测业务中的所有这些因果力量,并使用适当的因果推断数据科学。
此外,计算对业务至关重要的不确定性,并在考虑这些因素的情况下做出决策可能非常棘手。虽然项目经理知道要查看 A/B 测试的统计显著性,但我们需要确保相关性驱动的想法也基于统计显著性,使用适当的错误分析来回答所提的问题。
任何新的预测或因果推断问题都可以让我们以新的方式思考数据表示和特征工程。测量的治疗和/或结果的所有预测因子或协变量可以用许多方式表示,但是哪种表示与结果相关。特别是在因果推理中,我们不仅仅是提高准确性,我们还必须问,哪种表示真正抓住了混杂因素,并且没有控制错误的方面(中介)?这些问题可以帮助我们发现数据科学中的联系,否则我们可能不会发现。
创建正确的产品功能可能涉及相同的问题。例如,如果你给用户看一个热图,他们会用它作为行动的建议,那么这个热图应该是真实治疗效果的图,颜色的差异应该仔细选择,以反映这些治疗效果的不确定性。产品需求迫使我们考虑我们可能没有想到的数据科学问题。
此外,在企业中从事数据科学意味着优化或利用有限的资源进行开发、培训、预测、记忆、存储等。您可能需要探索新的方法来对数据进行采样以满足这些约束,但是您仍然需要解决那些关于因果关系和错误的问题!这远远超出了盲目运行 scikit-learn 模型的范围!
每一个新的商业问题都会将你推向一系列新的问题,所以抓住机会解决其中的许多问题。
感谢阅读!我希望这个列表中的一些东西可以融入到你的学习过程中。
查看我的其他文章:
https://medium.com/@skylar.kerzner/publish-your-first-python-package-to-pypi-8d08d6399c2f https://medium.com/@skylar.kerzner/making-python-packages-part-3-designing-your-classes-82b3a5786e30
关于类型提示的 12 个初学者概念,以改进您的 Python 代码
原文:https://towardsdatascience.com/12-beginner-concepts-about-type-hints-to-improve-your-python-code-90f1ba0ac49
就像单元测试一样,类型提示花费了开发人员的时间,但从长远来看是值得的
阿里安·达尔维什在 Unsplash 上拍摄的照片
Python 是一种动态类型的编程语言。这意味着解释器只在代码运行时执行类型检查**,并且变量类型允许在其生命周期内改变。**
尽管 Python 一直保持动态类型,并且从未打算改变这一方向,但自从 PEP 484 以来,类型提示已经被引入,目的是将静态类型检查引入代码分析。
在本文中,我们将介绍类型提示,并回顾使用它们时应该熟悉的 12 个概念。
在这篇文章的最后,你应该对类型提示有一个总体的了解,它们是什么以及什么时候应该使用它们。您还将学习如何构建复杂类型和执行静态类型检查。
话虽如此,让我们深入研究一下一些代码💻
新到中?你可以每月订阅 5 美元,解锁我写的不限数量的关于编程、MLOps 和系统设计的文章,以帮助数据科学家(或 ML 工程师)编写更好的代码。
https://medium.com/membership/@ahmedbesbes
1-类型注释:支持添加类型的新语法
使用 Python 注释执行类型提示(从 PEP 3107 开始引入)。它们用于向变量、参数、函数参数以及它们的返回值、类属性和方法添加类型。
添加类型提示没有运行时效果:这些只是提示,本身并不强制。如果你担心他们,一定要记住翻译总是忽略他们。
👉
变量注释变量注释遵循以下语法:
***<variable_name>: <variable_type> = <variable_value>***
您可以使用以下基本内置类型之一来执行类型提示:int
、float
、str
、bool
、bytes
、list
、tuple
、dict
、set
、frozenset
、None
。
以下是一些入门示例:
为了构建更高级的类型,我们将使用类型化模块。继续阅读,了解更多。
👉函数注释
你也可以给函数添加类型提示来指定它们的参数和返回值的类型。
使用前面的语法来指定参数的类型。
使用箭头->
提示返回值。
在下面的例子中,type_x
、type_y
、type_z
、type_return
必须是有效的 python 表达式,比如内置类型或者使用类型模块的更复杂的类型。
→如果一个函数不返回任何东西,可以将返回类型(箭头后)设置为None
。
👉你甚至可以在你的类中标注属性和方法。
2-使用 mypy 执行静态类型检查
要检查 python 是否强制类型提示,请尝试运行以下脚本,该脚本声明一个类型为int
的变量x
,并在稍后更改其值以存储一个浮点数。
# script.pyx: int = 2# ...x = 3.5
作者截图
没有错误。(不出所料)
现在,如果你真的对你的代码很严格,并且仍然想检测这些类型的错误,你可以使用 mypy ,一个执行静态类型检查的工具。
要安装它,只需运行pip install mypy
。
然后,要分析您的代码,只需运行:mypy script.py
作者截图
在这个简单的例子中,mypy 检测到一个错误:**赋值中不兼容的类型,**这正是我们想要强调的。
通过静态分析您的代码,mypy 帮助您符合您定义的类型,提高您的代码质量,防止无声错误,并通过遵循最佳实践来标准化您的代码。
要了解更多信息,请查看 http://mypy-lang.org/的。
3—添加类型提示的好处
如果解释器不强制执行,为什么还要写类型提示呢?
我经常听到这句话。
的确,类型提示不会改变代码的运行方式:Python 本质上是动态类型化的,并且不会很快改变。
然而,从开发人员体验的角度来看,类型提示为您的代码库带来了多种好处。
我可以不假思索地想到以下优点:
- 使用类型提示,尤其是在函数中,通过提供信息签名来阐明关于参数类型和所产生结果类型的假设,从而记录您的代码
- 通知类型消除了认知开销,使代码更容易阅读和调试。记住了输入和输出的类型,您就可以很容易地推理出您的对象以及它们是如何耦合的
- 类型提示改善您的代码编辑体验:
结合 mypy,您的 IDE 依靠它们来静态分析您的代码,并帮助检测潜在的错误(例如,传递错误类型的参数,调用错误的方法,等等。)
另外,根据变量的类型提示,为每个变量提供自动完成功能。
mypy 根据类型提示检测支持的类型操作和不兼容的类型—作者截图
VSCode 使用类型提示信息来提供相关的自动完成功能——作者截图
在接下来的部分中,我们将讨论类型模块中的高级类型。
4-列表
假设你想给你的函数传递一个有点复杂的参数,由…一个浮点数列表组成。你会如何注释它?
您可以尝试通过将list
类型与float
类型组合来编写类似的内容。
不错的尝试。
遗憾的是,这不起作用,尽管写起来似乎很自然和直观。
为了支持这一点,您只需用从https://docs.python.org/3/library/typing.html模块导入的**L**ist
类型替换内置的标准list
类型。
列表类型的有趣之处在于,它可以包含任何类型,而不仅仅是内置类型。我们自己的类型基本上可以和 List 结合。
例如,如果你有一个字符串列表,你应该这样输入:
5—字典
我喜欢使用 python 字典,因为它们很灵活。它们允许您使用不同类型的键和值。例如,您可以拥有一个包含字符串键和 dict 值的字典(在本例中,这表示一个嵌套的 dict 结构)
然而,作为这种灵活性的代价,并不总是清楚底层模式是什么:字典键是什么类型?字典值有哪些类型?
要控制字典中键和值的类型,可以使用类型模块中的 Dict 类型。
假设我用字符串键和字符串值处理字典。
**{"name": "Ahmed", "job": "ML engineer"}**
要建立这样一个字典结构的模型,可以向 Dict 传递两个参数,其中第一个是键的类型,第二个是值的类型。
**from typing import Dict****my_dict_type = Dict[str, str]**
6 —联合
从 Python 3.10 开始,
*Union*
被*|*
取代,也就是说*Union[X, Y]*
现在相当于*X | Y*
。
Union[X,Y](或 X | Y)表示 X 或 Y。
****示例👇
假设您的函数需要从缓存目录中读取一个文件并加载一个 torch 模型。这个缓存目录位置可以是一个字符串值(比如/home/cache
)或者是来自 Pathlib 库中的一个路径对象。
在这种情况下,代码如下所示:
7-类型直接
如果您的 Python 字典有一个固定的模式,其中包含已知的字符串键和不同类型的值,该怎么办?
大概是这样的:
**d = {"name": "Ahmed", "interests": ["chess", "tennis"]}**
你会怎么打?
❌使用字典和联合并不理想,因为我们丢失了关于什么键需要具有什么类型的值的信息。
使用 TypedDict 的✅允许你声明一个字典类型,期望它的所有实例都有一组特定的键,其中每个键都与一个一致类型的值相关联。
这是一个如何工作的例子👇
图片由作者提供—制作于https://carbon.now.sh/
8 —可赎回
Callable 是当你想用一个函数作为参数时使用的。
你也可以指定参数的类型和可调用函数的返回值。
Callable[[input_type_1, ...], return_type]
下面是带有附加类型提示的相同示例:
9 —任何
Any
类型非常简单。事实上,写这个
def bar(input: Any):
...
相当于这样写:
def bar(input):
...
Any
类型只是在这里明确声明 bar 函数打算接收任何输入类型作为参数。(可能是因为这个函数后面执行的内容不依赖于它的参数类型)。
这个
*Any*
型到底有没有用?🤔
老实说,我不知道。
10-可选
如果您的任何函数使用可选的参数,比如说,因为它有一个默认值,那么您可以使用类型模块中的可选类型。
11 —序列
类型为序列的对象是任何可以被索引的东西:列表、元组、字符串、对象列表、元组列表的元组,等等。
⚠️:请注意,集合或字典不是序列类型。
12 元组
元组类型的工作方式与列表类型略有不同。
如果你不在乎你的 tuple 的每个元素的类型,你可以继续使用tuple
内置类型。
**t: tuple = (1, 2, 3, ["cat", "dog"], {"name": "John"})**
但是,如果您想指定类型中每个元素的类型,请使用 Tuple。
结论
类型提示在您的代码之上带来了一个额外的抽象层:它们有助于记录代码,阐明关于输入/输出的假设,并在静态代码分析(👋mypy)在上面执行。
现在剩下的问题是:我应该开始在我的项目中使用类型提示吗?
如果你在一个已经实现了类型提示(和单元测试)的大型代码库上合作,那么如果你想编写现代 python 代码并提高代码质量,那么添加
是很自然的事情,类型提示是一条可行之路。
然而,如果您使用的是旧版本的 Python,如果您是编程语言的新手,或者如果性能确实是个问题,那么您可能应该避免添加类型提示。事实上,关于这最后一点,类型提示会在启动时引入一点开销。
资源
- https://better programming . pub/twenty-type-hinting-techniques-and-tools-for-better-python-code-e 877 e 0 b 0 c 679
- https://www.youtube.com/watch?v=dgBCEB2jVU0
- https://www.youtube.com/watch?v=QORvB-_mbZ0
- https://mypy.readthedocs.io/en/stable/cheat_sheet_py3.html
- https://realpython.com/python-type-checking/
- https://www . python tutorial . net/python-basics/python-type-hints/
- https://realpython.com/lessons/pros-and-cons-type-hints/
- https://bernat . tech/posts/the-state-of-type-hints-in-python/
新到中?您可以每月订阅 5 美元,并解锁各种主题的无限文章(技术、设计、创业……)您可以通过点击我的推荐链接来支持我
**https://ahmedbesbes.medium.com/membership **
12 个基本的可视化以及如何实现它们——第 1 部分
原文:https://towardsdatascience.com/12-essential-visualizations-and-how-to-implement-them-part-1-41e40400a740
我们看看如何用 Python、Matplotlib 和 Streamlit 创建 12 个最有用的图形和图表
马体·米罗什尼琴科的照片
“当我回顾过去一年为研讨会和咨询项目创作的 150 多幅视觉作品时,我只使用了十几种不同类型的视觉作品”, Cole Nussbaumer Knaflic 用数据讲述故事
许多人都读过科尔·努斯鲍默·克纳弗里克(Cole Nussbaumer Knaflic)的书《用数据讲述 T4》,根据这本书的前言,克纳弗里克“在这个星球上一些最受数据驱动的组织工作过”,在谷歌教授数据可视化已经有几年了,现在她已经创建了自己的教学公司。
这本书致力于描述如何使用图表和图形进行有效的交流,并提供了大量关于用图形进行交流的许多方面的信息。
但是你在书中学到的第一件事是,作者只依赖 12 种不同类型的可视化。这本书描述了这些视觉效果和它们的用途,但没有深入到实现中,所以这就是我们在这里要做的。
本文的目的是开始描述 12 种视觉效果,并展示如何用 Python 实现它们。本文中使用的所有代码和数据都可以从我的 Github 页面下载。(可下载的代码还可能包含本文中没有包含的其他示例。)
本文将着眼于前 6 种视觉效果:简单的文本、表格、热图、散点图、线图和坡度图。
六种视觉效果——作者图片
我将在后续文章中处理剩余的图表。这些将是,垂直和水平条形图,垂直和水平堆积条形图,瀑布图和方形面积图。
1.简单文本
正如科尔·努斯鲍默·克纳弗里克(CNK,从现在开始)告诉我们的,有时候,图形并不是必要的,甚至不是交流数据的最佳选择。当只呈现几个值时,简单的文本就可以了,甚至可能比图表更好。我们举个例子。
英国伦敦的天气在夏天似乎越来越热。2022 年 7 月最高气温 27.2 摄氏度,对英国来说相当炎热。2012 年是 24.2 度。
我们将设计一个视觉传达这种仅由文本组成的增加,我们将看到许多不同的设计效果如何。
首先,让我们设置一些代表伦敦这两年最高气温的变量和一些标题。然后我们会用不同的格式展示它们。
# Set up variables
years = ['2012','2022']
temps = [24.2,27.2]
caption = f"The maximum temperature in July 2022 was {temps[1]}°C"
caption2 = f"That's {temps[1]-temps[0]}° up from 2012"
现在,看看下面的条形图——它显示了使用我们刚刚设置的日期从 2012 年到 2022 年的温度变化。但是,虽然很明显温度上升了几度,但你不能确切地看到多少或确切地说这些温度是多少。
作者图片
条形图并不适合呈现这类数据,因此,让我们看看一些纯文本的视觉效果如何让我们更好地了解正在发生的事情。
Streamlit 为我们提供了一种很有吸引力的方法来显示两个值以及它们之间的变化。这为我们提供了一种显示相同数据的吸引人且有效的方式,并且编码非常简单,如下所示:
col3.metric("Temperature", temps[1],temps[0])
如果我们将它与一些说明性的文字结合起来,并使用一个列布局,我们可以实现一个直观的形象,告诉我们到底发生了什么,而不需要任何形式的图表。
col3, col4 = st.columns([1,4])
col3.metric("Temperature", temps[1],temps[0])
col4.markdown(f"#### {caption}")
col4.markdown(caption2)
作者图片
这种视觉效果提供了与条形图相同的数据,但实际上比图表传达得更好。
使用 markdown,您可以获得类似的结果,如下所示:
col1, col2 = st.columns([1,4])
col1.markdown(f"# {temps[1]}")
col2.markdown(f"#### {caption}")
col2.markdown(caption2)
作者图片
这两种方法是 Streamlit 特有的。另一种更通用的 Python 方法是在 Matplotlib 图表中定位文本。下面的代码就是这样做的。
您可以看到,我们创建了一个 Mathplotlib 图表,但其中没有绘制任何图形——我们只是将文本放置在正确的位置,并关闭轴、刻度等。用语句ax2.axis('off')
。
fig2, ax2 = plt.subplots(figsize=(5,1))
ax2.text(0, 0.9, temps[1],
verticalalignment='top', horizontalalignment='left',
color='red', fontsize=18, fontweight = 'bold')
ax2.text(0.2, 0.9, caption,
verticalalignment='top', horizontalalignment='left',
color='Black', fontsize=10)
ax2.text(0.2, 0.55, caption2,
verticalalignment='top', horizontalalignment='left',
color='darkgrey', fontsize=6)
ax2.axis('off')
st.pyplot(fig2)
这给了我们下图。
作者图片
这比其他两种方法更大胆和引人注目,但是,当然,如果我们愿意,我们可以通过改变字体大小、颜色和文本的位置来制作一个更微妙的小图形。
2.桌子
CNK 告诉我们,表格是向不同的受众显示数据的合适的视觉工具,每个受众可能对特定的行感兴趣。她还建议,我们应该让数据成为关注的中心,所以不应该让表格边框太重,而应该使用浅色边框或空白来分隔数据项。
Streamlit 为我们提供了两种显示表格的方法,st.table()
和st.dataframe()
。
使用与上一个示例相同的数据,下面是将数据显示为表格的代码。
import streamlit as st
import pandas as pd
temps = pd.DataFrame()
temps['Year'] = ('2012', '2022')
temps['Temperature'] = (24.2,27.2)
st.subheader("st.table")
st.table(temps)
看起来像这样:
作者图片
如果你喜欢的表格太宽了,那么把它放在一个栏里,然后把这个栏调整到你想要的宽度就很简单了。
数据帧非常相似:
st.dataframe(temps)
作者图片
单击数据框的列标题将按该列对数据框进行排序。
同样,这些是特定于 Streamlit 的方法。用 Mathplotlib 显示一个表格是可能的,但是它实际上是被设计成一个图表的附加物。我在 Matplotlib 中尝试了各种形式的表格,但对结果都不太满意。因此,我不确定这是否为独立的 Python 程序提供了合适的解决方案。
但是,如果您没有使用 Streamlit,那么作为一名数据科学家,您可能会使用 Jupyter 笔记本,它们可以非常简洁地呈现数据帧,例如,您只需在 Jupyter 单元格中写下数据帧的名称:
import pandas as pd
temps = pd.DataFrame()
temps['Year'] = ('2012', '2022')
temps['Temperature'] = (24.2,27.2)
temps
它是这样呈现的:
作者图片
3.热图
热图是一种使用颜色而不是数字来突出表格中数值差异的图形。
我们将看看热图的一个非常合适的用途——我们想要显示热量的增加!嗯,温度,真的。
下图显示了过去 150 年左右的相对全球温度,摘自我的文章专题图:全球变暖热图。(我在这里使用的数据包含在可下载的代码中,可以免费使用——参见注释 2)。
热图是展示过去几十年全球变暖趋势的绝佳工具。随着时间的推移,你可以很容易地看到颜色变浅,这意味着气温上升。(当然,这些数据不是绝对温度,而是相对于 1961 年至 1990 年期间的温度。)
作者图片
创建热图最简单的方法之一是使用 Seaborn 库。从下面的代码中可以看到,Seaborn 只是将 Pandas 数据帧作为参数,并将相应的地图显示为 matplotlib 图表。
import streamlit as st
import pandas as pd
import matplotlib.pyplot as plt
url='data/bydecade.csv'
gwdec = pd.read_csv(url)
gwdec=gwdec.set_index('Year')
st.table(gwdec)
import seaborn as sns
fig, ax = plt.subplots()
sns.heatmap(gwdec)
st.pyplot(fig)
您可以使用 matplotlib 中的imshow()
函数来实现类似的图表(参见可下载代码中的示例)。
4.散点图
散点图用于显示两个变量之间的关系。下面的例子使用了一个数据文件,该文件记录了 2018 年伦敦每个月的天气数据(见注 4)。它绘制了以毫米为单位的降雨量与日照时数的关系。
当然,当下雨的时候,太阳通常是不发光的,所以当下雨的时候,你会看到更少的日照时间。散点图清楚地显示了这种关系。
作者图片
下面的代码使用 Matplotlib 散点图来创建图表。
import streamlit as st
import pandas as pd
import matplotlib.pyplot as plt
weather = pd.read_csv('data/london2018.csv')
fig, ax = plt.subplots()
weather.plot.scatter(x='Rain', y='Sun', ax=ax)
st.pyplot(fig)
5.线条
折线图用于连续数据,通常也用于时间序列数据。
使用与上面相同的天气数据,我们将看三个不同的线图。
首先,我们将绘制一年中的平均温度,然后我们将看看如何通过绘制平均、最高和最低温度将多幅图放在同一个图中。最后,在第三个图表中,我们将看到如何通过绘制平均温度并在周围加上阴影来显示该平均值周围的最大值和最小值范围,从而显示一系列值,您可以使用相同的技术来显示置信水平。
首先,我们读取数据。它包含各种温度、日照时间和降雨量的每月读数。
weather = pd.read_csv('data/london2018.csv')
weather['Tmean'] = (weather['Tmax'] + weather['Tmin'])/2
看起来是这样的:
作者图片
它最初没有 mean 列——我们在上面的第二行代码中创建了它。
现在,简单的线图。
fig, ax = plt.subplots()
ax = weather.plot.line(x='Month', y = 'Tmean', ax=ax)
st.pyplot(fig)
使用 Pandas 和 Matplotlib 绘制的非常简单的平均温度线图。
作者图片
在同一个图中创建多个图只是为这些图创建新的轴。
ax = weather.plot.line(x='Month', y = 'Tmax', color = 'lightgrey', ax=ax)
ax = weather.plot.line(x='Month', y = 'Tmin', color = 'lightgrey', ax=ax)
st.pyplot(fig)
上面的代码为最低和最高温度增加了两个轴——我将这两个轴与平均值图进行了不同的着色——然后重新绘制了该图。
作者图片
你可以看到,这给了我们一个范围,但我们可以使它在视觉上更具吸引力,更好地传达一个范围的想法,通过阴影的最大和最小线之间的区域。
我们使用 Matplotlib 函数fill_between()
如下所示:
plt.fill_between(weather['Month'],
weather['Tmax'],
weather['Tmin'], color='lightgrey', alpha=0.5)
ax.get_legend().set_visible(False)
ax.set_ylabel('Temperature Range °C')
填充颜色设置为lightgrey
,因此它混合了上下图。我还隐藏了图例,并给 y 轴加了一个标签,以显示我们试图表示的内容。
作者图片
正如你所看到的,这也是一个非常合适的信心水平表示。例如,您可以使用原始图的固定百分比来创建上图和下图。因此,举例来说,上面的图线可以取中间值加 5%的值,下面的图线取中间值减 5%的值。
6.斯洛佩格拉夫
斜率图只是一个符合特定样式的线图,但只比较两组值。
根据 CNK 的说法,“当你有两个时间段或比较点,并想快速显示相对增加和减少时,斜率图会很有用”。
不幸的是,slopegraph 在标准的可视化库中并不常见。你可以简单地用线图来代替,它应该传达同样的意思。我们将这样做,但也通过结合线图和散点图并添加适当定位的文本来创建一个更典型的斜率图。
继续我们的天气主题,我将创建两个图表来显示我们在上面的文字图中看到的温度变化,但这次我们将伦敦与苏格兰的威克进行比较:
作者图片
这个数据代表了两个城市在不同年份的最高温度。在下面的代码中,我们在同一个图中绘制了两个图。第一个是数据的简单线图,然后我们叠加一个只有四个点的散点图,以给出斜率图线末端的原型斑点。
import streamlit as st
import pandas as pd
import matplotlib.pyplot as plt
st.header("Slope graph")
st.subheader("Here is the data")
df = pd.DataFrame()
df['year']=[2012,2022]
df['London']=(24.2,27.2)
df['Wick']=(14.8,17.3)
st.table(df)
st.subheader("A Slopegraph as a line graph")
fig, ax = plt.subplots()
ax = df.plot(x='year', color = ('red', 'blue'), ax=ax)
ax = df.plot.scatter(x='year',y='London', color= 'red', ax=ax)
df.plot.scatter(x='year',y='Wick', color = 'blue', ax=ax)
plt.xlim(2010,2024)
plt.xticks(df['year'])
ax.set_ylabel('')
st.pyplot(fig)
我在这里做的是绘制线条,然后使用散点图在线的末端叠加斑点。我还设置了记号,只显示我们感兴趣的两年,并调整了 x 轴的限制,在图的两边留出一些间距。这些调整中的每一项都使线形图更像斜率图。
它看起来还不错,但不是斜率表的典型形式,当然也不是 CNK 书中描述的那种形式。
作者图片
为了制作一个更传统的 CNK 风格的斜坡图,我们需要用 Matplotlib 做一些操作。
这是 CNK 在书中的渲染类型:
作者图片
它不同于传统的折线图,因为 y 值和图例文本被写在线的末端,而传统的轴被移除。
运行这段代码将会显示上面的图表。
ax.text(df.year[0] -5, df.London[0], df.columns[1])
ax.text(df.year[0] -2.5,df.London[0], f'{df.London[0]}°C')
ax.text(df.year[1] +1, df.London[1],f'{df.London[1]}°C')
ax.text(df.year[0] -5, df.Wick[0], df.columns[2])
ax.text(df.year[0] -2.5, df.Wick[0],f'{df.Wick[0]}°C')
ax.text(df.year[1] +1, df.Wick[1],f'{df.Wick[1]}°C')
ax.spines['right'].set_visible(False)
ax.spines['left'].set_visible(False)
ax.spines['bottom'].set_visible(False)
ax.spines['top'].set_visible(False)
ax.xaxis.grid(visible=True, color = 'black')
ax.get_yaxis().set_visible(False)
ax.get_legend().set_visible(False)
st.pyplot(fig)
前六行将文本和值添加到行尾,接下来我们移除样条线(图表的框架),然后我们添加 x 轴网格,这为我们提供了垂直线。最后,我们隐藏了这个传说。
对于一个没什么不同的结果来说,这是不是太多的努力了?我会让你决定。
这是 CNK 书中的前 6 个视觉效果,以及它们是如何实现的——我希望你会觉得有用。
你可以阅读第二部分,解决接下来的 6 个视觉效果。这里:
</12-essential-visualizations-and-how-to-implement-them-part-2-e47c1d4b9784>
您可以从我的 Github 资源库下载所有代码和数据文件。在我的网页上找到它的链接,以及其他文章的信息。
如果你想了解我发表的其他文章,你可以在 Medium 上关注我,或者在 Substack 上订阅我的时事通讯。
https://medium.com/membership/@alan-jones
笔记
- 《用数据讲故事》,商业人士数据可视化指南 ,科尔·努斯鲍默·克纳弗利奇,威利,2015 年(附属链接*)
- 全球温度数据包含在可下载的代码中,并来自 HadCRUT 数据集,该数据集跟踪自 19 世纪后期以来的温度变化。你可以从英国气象局哈德利中心下载它的版本,根据开放政府许可 v3 免费下载页面(也见下面的注释 3)。
- 使用观测估计集合量化全球和区域温度变化的不确定性:HadCRUT4 数据集 ,Colin P. Morice,John J. Kennedy,Nick A. Rayner 和 Phil D. Jones
- 天气数据来源于英国气象局的文本数据,在这里找到。该数据根据开放政府许可 v3 发布,并可在相同条件下使用。
- 如果你通过代销商链接购物,我可能会得到佣金。不会影响你付出的代价。
12 个基本的可视化以及如何实现它们,第 2 部分
原文:https://towardsdatascience.com/12-essential-visualizations-and-how-to-implement-them-part-2-e47c1d4b9784
我们看看如何用 Python 和 Streamlit 创建 12 个最有用的图形和图表
照片由 Olya Kobruseva 拍摄
“当我回顾过去一年为研讨会和咨询项目创作的 150 多幅视觉作品时,我只使用了十几种不同类型的视觉作品”, Cole Nussbaumer Knaflic 用数据讲述故事
在《T4》第一部中,我们看了科尔·努斯鲍默·克纳弗里克(CNK)在她的书用数据讲故事中确定的 12 种视觉效果中的前 6 种(见注释 1)。在本文中,我们将处理第二个 6 的实现。这些是各种各样的条形图,瀑布图和方形面积图。
所有的实现都使用 Pandas plots 和/或 Mathplotlib,并且是为 Streamlit 编写的,尽管也有一个 Jupyter 笔记本的版本。本文中使用的所有代码(Streamlit 和 Jupyter)和数据都可以从我的 Github 页面下载。可下载的代码可能包括下面没有包括的附加示例。
第二组 6 个视觉效果的变化——作者图片
条形图
CNK 认为,条形图通常被避免使用,因为它们很常见。但这正是它们有用的地方!人们习惯于看到它们,所以它们很容易理解。这意味着你的观众花更少的脑力解释你的图形,更多的精力理解数据。
因此,我们不应该回避条形图,而应该把它作为一种简单的方法,以一种容易理解的方式表达数据的含义。
条形图还具有易于创建的优点,因为它们包含在大多数可视化库中。
CNK 将条形图分为 4 类,垂直、水平、垂直堆叠和水平堆叠,我们将依次来看。
零基线问题
但是首先要说一下基线。CNK 坚持认为,所有的条形图都应该有一个零基线,否则它们就有被误导的风险,或者更严重的是,被操纵的风险。
这方面的一个例子是,CNK 让我们注意到了福克斯新闻频道在巴拉克·欧巴马总统任期内发表的一份条形图。他们在考虑如果奥巴马的前任乔治·w·布什的税收改革被允许终止会发生什么。
现实情况是最高税率将从 35%提高到 39.6%——绝对增长 4.6%,相对增长约 13%。
图表看起来像这样:
具有非零基线的误导性图表设计—图片由作者提供
基线从 34%开始,因此增长看起来非常巨大。这是因为右边一栏的大小几乎是左边一栏的 5 倍。当然,这并没有恰当地反映实际的增加。
一个类似但基线为零的图表告诉我们真实的情况:
更好的零基线图表设计—作者图片
由此得出的结论是,条形图的基线通常应该为零,如果不是一直为零的话。
数据
在我们开始绘图之前,我们需要获得一些数据。我们将使用 2022 年冬季奥运会的奖牌榜作为我们将要查看的各种条形图的数据。这是我们需要的初步代码。这些数据是公开的,我是从维基百科的表格中复制的(见注释 2)。
import streamlit as st
import pandas as pd
import matplotlib.pyplot as pltmedals = pd.read_csv('data/2022WinterOlympics.csv')
该数据记录了前 5 名国家获得的金牌、银牌和铜牌的数量以及奖牌总数。这是它的样子。
2022 年冬奥会前 5 名国家奖牌榜—数据来源, 维基百科 ,图片作者
现在,图表。
7.垂直条
垂直条形图是普通的香草口味的条形图。在 Streamlit 中,实现一个简单的熊猫条形图的代码是这样的:
fig, ax = plt.subplots()
medals.plot.bar(x='Country', y='Total', ax=ax)
st.pyplot(fig)
该图绘制了每个国家获得的奖牌总数的单个条形图系列,x 轴表示国家,y 轴表示获得的奖牌总数。
垂直条形图—作者图片
请注意,我使用 Streamlit 和 Pandas 来实现这一点,Streamlit 坚持我们专门创建一个 Matplotlib 图形,它可以作为绘图函数的参数。这就是第一行代码的作用。因此,我们必须将 *ax=ax*
添加到熊猫图代码中,以便将该图添加到已经创建的图形中。如果您要使用 Jupyter 笔记本或独立的 Python,就不需要这段代码。查看 Github 上的 Jupyter 笔记本,查看替代代码。
条形图的一个常见用途是比较一系列条形图中的多个值。下面是显示奖牌表中所有列的条形的代码。注意,由于没有为y
指定值,Pandas 认为我们想要绘制所有的列。
fig, ax = plt.subplots()
medals.plot.bar(x='Country', ax=ax)
st.pyplot(fig)
多条竖条图—作者图片
要显示列的子集,您应该将y
设置为您感兴趣的列的列表。下面我们指定列,Gold
,Silver
和Bronze
(即不包括合计)。
fig, ax = plt.subplots()
medals.plot.bar(x='Country', y = ['Gold','Silver','Bronze'],ax=ax)
st.pyplot(fig)
结果是这样的:
带有多个特定条形图的垂直条形图—图片由作者提供
8.单杠
CNK 告诉我们,水平条形图是她的条形图版本,因为它更容易阅读。她告诉我们,我们的眼睛自然地以 Z 形运动扫描一页,在页面上来回移动,因此,我们会首先注意到图表上的标签,然后看到与它们相对应的条形。我要指出的是,虽然从西方文化的角度来看这很可能是真的,但它可能不是普遍的(我非常欢迎对此的评论)。
在 Pandas 中,垂直条形图和水平条形图在语法上的唯一区别是函数名中只有一个字母。例如,不调用函数medals.plot.**bar**(x='Country', ax=ax)
we,而是调用medals.plot.**barh**(x='Country', ax=ax).
这里有一个例子,但是上一节中的所有图表都可以通过调用函数的barh
版本而不是bar
来呈现为水平图表。
fig, ax = plt.subplots()
medals.plot.barh(x='Country', ax=ax)
st.pyplot(fig)
多条横条图—作者图片
9.堆叠垂直条
堆积条形图不像以前的类型那样常见,但当您想要比较由不同子成分组成的总计时,它会很有用,如下图所示。
在这里,我们将每个国家的不同奖牌类别组合成一个单一的堆叠条形图。除了添加了参数stacked = True
之外,代码与前面的示例非常相似。
fig, ax = plt.subplots()
medals.plot.bar(x='Country',
y = ['Gold','Silver','Bronze'],
stacked = True, ax=ax)
st.pyplot(fig)
垂直堆积条形图—作者图片
正如 CNK 指出的那样,尽管比较第一个子成分很容易,但较高的子成分就不那么容易比较了,因为它们不是从同一水平开始的。
10.堆叠水平条
除了我们调用barh
函数之外,水平堆叠条形图的编码与垂直堆叠条形图相同。
当然,关于垂直图表的评论也适用于此。
fig, ax = plt.subplots()
medals.plot.barh(x='Country',
y = ['Gold','Silver','Bronze'],
stacked = True, ax=ax)
st.pyplot(fig)
水平堆积条形图——作者图片
11.瀑布
瀑布图可以用来解构堆积的
条形图,这样我们就可以一次专注于一个部分。此外,瀑布图可以跟踪从起始值到最终结果的增加和减少。
瀑布图通常不作为可视化库的标准部分,尽管它们本质上是由两部分组成的堆叠条,当前值和增量或减量。正如 CNK 所评论的,这些可以通过使酒吧的下部透明来构建。
然而,我们将走一条更容易的路线。Python 库 w aterfallcharts 使用 Matplotlib 实现瀑布图,简单易用。
首先,当然,我们安装它。
pip install waterfallcharts
我们将构建的图表取自用数据讲故事,并跟踪一个虚拟公司中人员的增加和减少。下面是数据:
a = ['Beginning HC','Hires','Transfers In','Transfers Out','Exits']
b = [100,30,8,-12,-10]
List a
是一组标签,b
是一个值列表,从当前人数开始,然后列出初始值的增量或减量。
由此产生的图表看起来像这样:
瀑布图——作者图片
您可以看到初始值以及由于标签所描述的原因而导致的变化。还添加了最终值。
产生这种结果的代码非常简单。
my_plot = waterfall_chart.plot(a, b, net_label = "Ending HC")
st.pyplot(my_plot)
我们传入标签和数据点的列表,以及一个将应用于最终计算出的总数的标签。结果是在 Streamlit 中可以用st.pyplot()
绘制的图形。
您可能会注意到,在条形的视觉编码中有相当多的冗余。第一个柱和正变化标为绿色,负变化标为红色,最后一个柱标为蓝色。但积极和消极的变化已经通过增加或减少整体高度来区分。除此之外,还有数字标签向我们展示变化——这些也是彩色编码的。
此外,我们不需要初始值和最终值是不同的颜色,因为它们是位置编码的:初始值在左边,最终值在最右边。
在她的书里,CNK 把所有的条形都涂成一样的颜色,我认为这样会有更好的效果。因此,这里有一个替代的编码,将所有的条设置为相同的颜色。
my_plot = waterfall_chart.plot(a, b, net_label = "Ending HC",
blue_color='blue',
red_color='blue',
green_color='blue')
st.pyplot(my_plot)
这是结果。
另一幅瀑布图——作者图片
12.正方形区域
面积图通常存在问题,因为面积通常是不规则的形状,相互堆叠在一起,读者很难将其解释为一个值。
CNK 说她一般不使用它们,除了方形面积图更容易阅读,我们将在这一部分探讨。
数据
我们将使用与食用过多加工肉类的健康风险相关的数据。在我的文章 可视化健康风险 中,我讨论了如何有效地呈现这些风险,我从大卫·斯皮格尔哈尔特的优秀著作统计的艺术(注 4)中获得了灵感。
2015 年 11 月,国际癌症研究机构(世界卫生组织的一部分)报告称,食用 50 克加工肉类——例如培根或香肠——与肠癌风险增加 18%有关(注 3)。
这并不像一些媒体让你认为的那样可怕,因为这是相对风险的增加,而不是绝对风险的增加,而且绝对风险仍然相当小(非常粗略地说是从 6%增加到 7%)。但是仅仅用数字来解释这个想法是很困难的。可视化方法更好,一个好的候选可视化方法是方形面积图。我修改了我最初的方法,创建了一个正方形的面积图,就像 CNK 的书中所描绘的那样。
这是原始数据:每 100 个人中,大约有 6 个人患有肠癌,大约有 1 个人因为吃了太多的加工肉类而患病。
让我们看看用条形图表示的数据。
显示癌症实例(但不是很好)的条形图—作者图片
出于兴趣,下面是生成图表的代码。
fig, ax = plt.subplots(figsize=(8,5))plt.bar(['Cancer-free','Contracted cancer by chance','Contracted cancer and is a Bacon Eater'],[94,6,1])
plt.xticks(rotation = 45)ax.set_ylabel('Percentage')
ax.set_title('Occurance of Bowel Cancer in a Population')st.pyplot(fig)
很明显,最短的棒线和最长的棒线相比很小,但是很难判断到底有什么不同。
让我们试试传统的面积图。下面的是一个单一的堆积酒吧,作为一个矩形面积图。
一个条形图作为面积图显示癌症实例-作者图片
同样,这是这个图表的代码。
fig, ax = plt.subplots()
ax.bar('Instances of Cancer', 94,label='Cancer-Free')
ax.bar('Instances of Cancer', 6, label='Contracted cancer by chance')
ax.bar('Instances of Cancer', 1, label='Contracted cancer and is a Bacon Eater')
st.pyplot(fig)
这本书可能比前一本书可读性强一点,但实际上,它也面临着同样的问题。
当数值存在差异时,方形面积图会让我们对情况有更好的印象。
显示癌症实例的方形面积图更清楚地显示了数据——图片由作者提供
在上图中,很容易看出每个类别的相对大小。问题是,我们并不经常将方形面积图视为可视化软件包的标准组件。
在下面的代码中,我利用 Seaborn 热图来创建方形面积图。首先,我创建一个 10 x 10 的 Numpy 数组,用零填充—这代表总人口—我用值 0 代表一个没有癌症的个体。接下来,我用六个 1 填充数组的左下角。值 1 代表患有癌症的个体。最后,为了完成数组,我将左下角的单个数组元素的值设置为 2,表示一个人由于吃了太多加工过的肉而患了癌症。
*# construct a 2D array of 0s - total pop*
a = [0]*100
b = np.array(a).reshape((10,10))*# add a 2 by 3 rectangle of 1s representing cancer sufferers*
for i in range(8,10):
for j in range(7,10):
b[i,j] = 1*# add a single cell with value 2*
*# representing the number of cancer sufferers*
*# who eat too much bacon*
b[9,9] = 2*# Plot the grid as a heat map in Seaborn*
fig, ax = plt.subplots(figsize=(8,5))
sns.heatmap(b,
linewidths=0.5,
yticklabels=False,
xticklabels=False,
cmap=['lightblue','royalblue','midnightblue'],
ax=ax)*# Customize legend*
colorbar = ax.collections[0].colorbar
colorbar.set_ticks([0.5,1,1.5])
colorbar.set_ticklabels(['Cancer-free','Contracted cancer by chance','Contracted cancer and is a Bacon Eater'])ax.set_title('Occurance of Bowel Cancer in a Population')
st.pyplot(fig)
剩下的代码是为每个类别设置颜色,设置标签等等。
结论
因此,我们有 12 个必要的可视化,如科尔·努斯鲍默·克纳弗里克的书用数据讲故事中所描述的。大多数图表都很容易阅读和实现,有一两张稍微复杂一点,因为它们通常不包含在标准的可视化软件包或库中。我希望,在这些案例中,我已经帮助您了解了它们是如何实现的。
感谢阅读,我希望它是有用的。所有的代码都可以通过我的网页上的链接获得。你还会发现一个 Jupyter 笔记本,实现了每一个视觉效果。还有一个 Streamlit 应用程序演示了你在这里看到的每一个可视化效果。
要了解我所做工作的更多信息,请访问我的网页和/或订阅我在子堆栈上的不定期简讯。
笔记
- 《用数据讲故事》,商业人士数据可视化指南 ,科尔·努斯鲍默·克纳弗利奇,威利,2015 年(附属链接*)
- 维基百科上的奖牌榜页面列出了每个参赛国家获得的奖牌。
- IARC 专论评估红肉和加工肉的消费
- 统计的艺术:如何从数据中学习,大卫·斯皮格尔哈特,2021 ( 附属链接
- 如果你通过代销商链接购物,我可能会得到佣金。不会影响你付出的代价。
2022 年行业数据科学家应该听的 12 个播客,不是关于数据科学的
原文:https://towardsdatascience.com/12-podcasts-for-industry-data-scientists-2022-1c76b4c26bdf
通过倾听,变得更有商业头脑,更善于思考,更好地为人
照片由从派克斯拍摄制作
数据科学的艺术,特别是对于所谓的“行业数据科学家”(即那些在企业界工作的人),正在慢慢与其他领域融合。专家们谈到,这一角色将分裂为一条更侧重于业务的道路和另一条更侧重于工程的道路。
不管发生什么,花时间学习你直接关注领域之外的话题从来都不是一个坏主意。这是创新和创造力真正蓬勃发展的地方。
我花了很多时间思考这个问题,甚至在微软媒体出版物上开设了一个关于数据科学的博客系列,名为“如何通过成为一名更好的数据科学家…”。它旨在寻找我们的领域和其他领域之间的和谐,以激发改进和创造力。
在这种情况下,作为一名连续播客听众,我决定将我最喜欢的 12 个非数据科学播客放在一起,这有助于我成为一名更好的数据科学家——就此而言,也是一名人类。
TLDR;
- 知识工程
- 工作实验室
- 下班后
- a16z
- 像经济学家一样思考
- HBR
- https://hanselminutes.com/
- 零食日用
- 大师级
- 《华尔街日报》未来的一切
- 哲思本
- 快乐 10%
专业建议 1:用这些作为借口,在一天当中散步休息一下。思维敏捷的数据科学家更好。
专业建议 2:以 1.2 倍或 1.5 倍的速度听他们会改变你的生活。
知识工程
平均每集长度:<80 minutes
W 讲的是什么?
知识工程 是《法南大街背后的伟大头脑沙恩·帕里什》创作的播客。如果你不熟悉这个网站,它是一个专注于“工作和生活的永恒课程和见解”的媒体。这些出版物有长有短的文章,包含了关于心智模型、管理时间、优化成功、指导等等的大量信息。
为什么你应该听:
播客是智慧的一种声音形式,发布在网站上。谢恩更进了一步,他采访了一些知名人士,从博弈论、创业、做出更好的决策和过坚忍的生活中提取有用的经验。
学到的教训不是如何建立更好的模型,而是如何管理自己的时间、职业生涯、项目,以及更好地思考。所有这些都将导致更成功的数据科学。
工作实验室
平均每集长度:22 分钟
关于什么的?
微软进行了大型调查研究,旨在了解当前和未来的工作趋势。他们决定通过名为工作实验室的出版物来传播他们的所有发现。
由 Elise Hu 主持的 WorkLab 播客 每一集都巧妙地从他们最近的研究中选取了一个统计数据,并深入探讨了其背后的故事。它意味着什么,为什么它是重要的,以及要吸取的教训。他们将这些引人注目的叙述与行业专家结合起来,以更好地阐明观察到的工作趋势。
为什么你应该听:
微软将成为塑造信息/技术工作者“工作未来”的主要声音之一。播客是一个实时日志,记录了他们在这个重要话题上的立场是如何形成的。通过分享新的研究、行业专家和员工的集体意见,微软提供了一个论坛来学习如何修改您的工作,使其“为您服务”。
下班后
平均每集长度:<60 minutes
W 讲的是什么?
2021 年我最喜欢的发现之一——下班后的https://www.ted.com/podcasts/after-hours播客简直是音频黄金。每一集都包含三位主持人 Youngme Moon、Mihir Desai 和 Felix Oberholzer-Gee 对两个热门故事(例如 2021 供应链,Zillow 的大摸索)。
为什么你应该听:
首先,这是一个了解世界上发生的事情的奇妙方式。第二,每集都是哈佛商学院教授完美的苏格拉底式讨论,所以感觉像是免费的 Micromasters 节目。如果你正在寻找一个新的“商业”播客来添加到你的数据科学剧集库中,这应该是它。
a16z 播客
平均每集长度:不等,但 30 或 60 分钟
这是关于什么的?
a16z 播客 是由知名风险投资公司 Andreessen Horowitz 的人开发的。每集都是与某种形式的技术行业专家的深入对话——从 NFTs 到数据中心到 mRNA,以及新冠肺炎疫苗背后的机器是如何工作的。
为什么你应该听:
技术世界和它周边的其他世界正在迅速变化。作为一名数据科学家,a16z 播客不仅帮助我了解最新的发展动态,还通过侧重于商业而不是侧重于数据科学的视角来了解它们。由于这种观点,它也向听众展示了相邻领域发生的创新,这些创新最终可能会影响数据科学实践。
像经济学家一样思考
平均每集长度:<20 minutes
W 讲的是什么?
由喜马拉雅教育平台创建的 像经济学家一样思考 旨在简化经济学,并用核心原则武装听众。每集不到 30 分钟,专注于一个可消化的概念。他们得到了大量外行人的发言和例子的称赞。
为什么你应该听:
经济学在我们生活和工作的世界中扮演着重要的角色。就个人而言,由于其令人生畏的复杂性,这也是一个大多数人似乎回避的话题。这个播客帮助我开始理解 a)它没有我想象的那么可怕,b)不同经济趋势中的主要杠杆(例如:通货膨胀)。
作为一名数据科学家——尤其是在企业环境中工作的“行业数据科学家”,构建推理和建模业务指标——它只会有助于进一步了解推动公司支付你工资的因素。
HBR 理念传播
平均每集长度:<40 minutes
W 讲的是什么?
众所周知,《哈佛商业评论》是所有商业和管理信息的最佳来源。播客【HBR】idea cast是相同的,但以音频形式,每周传送一次。它的特点是有各种各样的专家,当然有商业专家,也有心理学专家,神经科学专家,人工智能专家等等。
为什么你应该听:
每集都包含如何更好地管理业务、人员和流程的信息。同样,他们深入研究企业工作领域的相关趋势。将其添加到你的迷你 MBA 学校课程中,以构建更好的数据科学产品,并了解你的商业同事的想法。
HanselMinutes 播客
平均每集长度:<40 minutes
W 讲的是什么?
不可否认的是, HanselMinutes 正处于与数据科学过于接近的风口浪尖,以至于不在非数据科学播客的名单上。它仍然包括在内,因为真正的开发者和其他人提供了大量的内容,构建了令人难以置信的产品。情节从超技术到更表面的水平变化;从安全到游戏开发到大脑研究。斯科特·汉瑟曼无疑过着他最好的生活,通过与有趣的人交往来满足自己的好奇心。
为什么你应该听:
每集似乎都揭示了与数据科学相关的技术信息。那样的话,你会觉得自己越来越精通开发。同样,也有来自正常的、有关系的人的迷人故事。
每日小吃
关于什么的?
每日小吃 播客是你自己的个人音频形式的咖啡,每天早上开始搭配,“这是尼克,这是杰克,这是‘迄今最好的一个’”。这是一个快速而有趣的新闻来源,每天有三个关于趋势、公司动向、收益报告等的故事。它不是为了提供投资建议,但归投资平台 RobinHood 所有。
为什么你应该听:
尼克和杰克就某些公司新闻对公司本身以及行业意味着什么提供了一个很好的视角。由此看来,播客是一个很好的方式来了解某些运动和决定对企业和投资意味着什么。强烈建议学习更多关于商业战略的想法和/或如果你只是对市场新闻感兴趣。
音阶大师
平均每集长度:<45 minutes
W 讲的是什么?
由 LinkedIn 的联合创始人雷德·霍夫曼主持的 规模大师 是一个播客,详细介绍了企业“如何从零成长为亿万企业”。每一集都带领听众踏上一段旅程——从想法的开始开始,讨论许多障碍,并留下要学习的课程。
为什么你应该听:
这个播客帮助任何人理解建立一个广泛使用的、成功的产品所需要的真正的时间和努力——然后达到规模。许多经验教训可以转移到生活的其他领域。因此,行业数据科学家可以收集想法和最佳实践来启动他们正在构建的东西,无论是内部还是外部组织使用。
《华尔街日报》是一切的未来
平均每集长度:<45 minutes
W 讲的是什么?
有趣的未来派对话夹杂着有意的报道——这就是《华尔街日报》未来的一切https://www.wsj.com/podcasts/wsj-the-future-of-everything。他们自己的话说得最好:“它提供了一个万花筒般的视角,展现了将塑造我们世界的新生趋势”。
为什么你应该听:
谁不喜欢一个讲得好的故事,尤其是当它是关于未来的时候?播客提供了关于聪明人如何解决问题的引人入胜的故事。作为拿工资做同样工作的专业人士,这是一种有趣的学习和获得想法的方式。同样,这也是了解更多技术和其他进步的好方法。
对此进行哲学思考
平均每集长度:< 30 minutes
W 讲的是什么?
哲学。创作者斯蒂芬·韦斯特深入探讨了具体的哲学家,他们的理论和对世界的影响。他经常将这些哲学与正常的日常生活相联系,使这些概念变得平易近人、有趣和令人惊叹。加分点每个 哲思本 集以同一个“大家好!我是斯蒂芬·韦斯特“介绍。
为什么你应该听:
哲学是关于我们周围世界的推理。然而,传统的设计方式可能会让轻度好奇的人感到畏惧。这个播客打破了入门的障碍。通过这种方式,您可以获得关于思考世界的方式的大量信息,这些信息可能会激发关于特定数据科学项目、工作道德或简单生活的想法。
快乐 10%
平均每集长度:<80 minutes
W 讲的是什么?
记者丹·哈里斯与冥想老师、科学家和其他有趣的人谈论正念、冥想和活出最好的自己。每集的目的很简单:想办法让自己更快乐和平静一点。
为什么你应该听:
这个世界充满压力。数据和技术可以压倒一切。投入时间学习更多更好的心理健康实践从来都不是一个坏主意。同样地, 百分之十快乐播客 经常谈到人际交流和移情。这两个主题都有助于数据科学家更有效地与其他人协作和/或对终端用户体验有新的认识。
有这么多很棒的播客值得一听。希望你喜欢这些建议。如果你认为还有其他人应该被提及和/或帮助你成为更好的数据科学家(或人类),请在评论中给他们留言!
关于时间序列你应该知道的 12 件事
原文:https://towardsdatascience.com/12-things-you-should-know-about-time-series-975a185f4eb2
亚当·米格尔斯基在 Unsplash 上的照片
对于那些不知道的人来说,时间序列只是一组随时间收集的数字观察值(图 1)。时间序列的例子出现在许多领域,从零售(例如库存计划)到金融(股票价格预测)。时间序列之所以有趣,是因为它们潜在的不确定性——数据会随着时间而变化,这使得人们很难理解它们未来的行为。
图 1:从 1949 年到 1960 年,每月国际航线乘客的数量。蓝色部分代表未来 12 个月的预测。
在这里,我将描述 12 个在建模时间序列时需要考虑的重要属性或成分。以这样或那样的方式,这些特征影响了预测系统开发的数据科学管道中的决策。
如果你着急的话,下面是每个主题的一条线:
- 趋势:数据均值的长期变化;
- 季节性:有规律的、可预测的变化;
- 残差:去季节性和去趋势的序列;
- 平稳性:时间序列性质随时间保持不变时;
- 自相关:与过去观测值的相关性;
- 异方差:方差的变化;
- 规律性 : 是否定期采集系列;
- 频率 : 观测序列的频率;
- 反身性 : 预测影响结果时;
- 异常值 : 罕见的但可能有趣的观测值;
- 状态和变化检测 : 当数据分布发生变化时;
- 维度 : 时间序列中变量的个数。
1.趋势
趋势是时间序列的基本组成部分之一。它的代表了****数据均值的长期变化,如图 1 中的所示。此图显示了一个时间序列示例,它代表了一段时间内某家航空公司每月的乘客人数。时间序列的平均水平随着时间的推移而增加,这代表了一个明显的上升趋势。
一些学习算法很难处理时间序列的趋势部分。因此,为了时间序列的最佳建模,通常建议将其移除。您可以使用差分运算来实现这一点。差异仅仅意味着取当前观察值和前一个观察值之间的差异。图 2 显示了通过差分去除趋势后的航空乘客时间序列;经过这一过程后,序列的平均水平变得稳定。
图 2:应用差异运算后的去趋势时间序列。
2.季节性和周期性模式
如果一个时间序列在固定周期(例如每月)内经历有规律的和可预测的变化,那么它就有季节性成分。航空旅客时间序列显示出一个月的季节性,这是显而易见的周期性振荡。****
与趋势类似,季节性因素也会破坏平稳性,通常建议将其去除。也可以通过差分来实现,但是我们不是从当前观测值中减去前一个值,而是从同一季节中减去前一个观测值。
季节性差异减轻了可预测的波动,这也稳定了序列的平均水平。去除季节性成分后,该时间序列称为季节性调整。
除了季节效应,时间序列还可以表现为其他不具有固定周期的可预测振荡**。这种类型的变化是一种循环模式。周期模式的典型例子是经济周期,在这个周期中,经济经历增长期和衰退期。**
3.残差
图 3:时间序列的残差部分。这些是在进行消除趋势的差分和消除季节性的季节性差分之后获得的。
从时间序列中去除上述三个成分(趋势、季节性、周期模式)后,剩下的部分称为不规则成分或残差。图 3 显示了一个例子。残差无法用任何趋势、季节或周期行为来解释,但仍然会对时间序列的动态产生影响。
在任何给定的时间点,一个时间序列可以以相加的方式分解成上述的组成部分,如下所示:
y =趋势+季节性+周期性+残差
根据数据的不同,这种分解也可以通过用乘积运算代替求和运算来实现乘法运算。
4.平稳性
趋势或季节性等因素打破了时间序列的平稳性。如果时间序列的属性不依赖于观察数据的时间,则时间序列是稳定的** 。**
更正式的说法是,如果均值或方差没有系统的变化,并且周期性变化已经被消除,那么时间序列被认为是平稳的,但不涉及具体细节。
许多时间序列技术都是在假设时间序列是平稳的情况下工作的。当它不是时,诸如差分之类的操作被用来使它静止。
5.自相关
时间序列的概念意味着对历史数据有某种程度的依赖——我们今天观察到的取决于过去发生的事情。时间序列的自相关根据每个观察值与其过去值的相关性来量化这种依赖性。该属性提供了关于系列的重要结构信息。如果一个时间序列在所有滞后上都表现出低的自相关性,则称之为白噪声。
6.异方差
这是一个复杂的词,但概念其实很简单。如果一个时间序列的方差不是常数并且随时间变化,则称该时间序列为异方差的,与同方差的相反。在飞机乘客的例子中,很明显,数据的可变性随着时间的推移而增加。这种方差变化通常与数据均值水平的变化同时发生,即均值越高,方差通常也越高。异方差在建立数据模型的过程中提出了一个问题,有一些方法可以解决这个问题。幂变换,例如取对数,或者更一般地,Box-Cox 变换,通常被用于稳定方差。图 4 显示了 Box-Cox 方法应用于时间序列的一个例子。****
图 4:应用 Box-Cox 变换后的时间序列
7.规律性和间歇性
时间序列通常以固定的时间间隔收集,例如,每天或每小时。这些被称为规则时间序列,并且大多数时间序列方法在规则性假设下工作。然而,在许多应用中,时间序列本质上是不规则的。例如,自然灾害(如地震)或特定零售产品的销售,它们以不规则的时间间隔发生。
通常,对时间序列的不规则性进行插值处理,使序列变得规则。例如,与产品销售相关的时间序列可以转换为某个时间段的销售计数(例如,每小时的产品销售)。这种插值过程可能会产生稀疏或间歇的时间序列,其中有几个值为常数 0 的观察值(例如,在给定的一个小时内没有产品销售)。这种间歇性是库存计划时间序列预测中的一个常见障碍,其中一些产品很少出售。
8.采样频率
时间序列的采样频率表示其采集的规律性,例如,每日或每月**。不同频率的时间序列带来不同的挑战。对于频率较高的时间序列,季节性成分可能更难捕捉。每日或次每日时间序列通常包含多个季节模式,这些模式不易捕捉。**
就季节性而言,处理低频时间序列更简单。但是,可能还有其他问题需要考虑。相对于高频数据集,低频数据集通常包含较小的样本量。经典的时间序列模型,如 ARIMA 或指数平滑,可以很好地处理这个问题,因为它们有少量的参数。参数多的学习算法可能容易过拟合。
9.自反性
****如果预测影响事件的展开,时间序列就是自反的。自反时间序列的经典例子是股票市场数据。预测股价上涨会吸引投资者,从而创造需求并推动股价上涨。这种预测会自我实现。另一方面,由于投资者的恐慌,市场崩溃的预测本身也可能导致市场崩溃。也有弄巧成拙的反身系统,在这种系统中,预测给定事件会降低其可能性。
反身性可能会导致意想不到的后果。从业者应该确定它如何出现在他们的时间序列中,并以某种方式将响应纳入他们的预测系统。
10.极端值
****离群值或异常值是明显偏离其他观测值的罕见事件。这些实例常见于所有类型的数据,而不仅仅是时间序列。然而,在时间序列中,由于观测值之间的时间依赖性,异常值构成了额外的挑战。
时间序列异常值可能只出现在一个实例中(点异常值),也可能跨越几个时间步(子序列异常值)。在搜索异常时,将上下文考虑在内通常是很重要的。例如,0 度的温度在冬天可能是常见的,但在夏天却是异常的。
处理异常值的最合适方法取决于它们的性质。异常值可能由于错误的数据收集或传感器故障而出现。这种异常值表示不符合生成观察值的分布的不需要的数据。然而,也有时间序列异常值,这些异常值本身就是感兴趣的事件。这方面的例子包括股票市场崩盘或欺诈检测,其目标是预测或减轻这些罕见事件的影响。
11.制度和变化检测
****当时间序列的分布发生变化时,会出现一个变化点,也称为概念漂移。变化可以重复出现;一个时间序列可以用不同的制度或概念来描述,而数据分布在这些制度之间是变化的。状态转换模型是解决这类问题的流行方法。
变化也可以是永久性的。这些被称为结构性断裂。这些变化对学习算法提出了挑战,学习算法必须能够检测到这些变化,并及时做出相应的调整。
重要的是不要混淆变化检测和异常值检测。第一个是关于检测管理时间序列的制度的变化。当体制改变时,观测值的分布也随之改变。另一方面,异常值代表明显偏离典型行为的观察结果(或后续观察结果),其中典型行为的特征在于当前的基础制度。
12.维度
到目前为止,列出的属性都假设基础时间序列由一个维度表示,其中维度表示变量的数量。因此,这些时间序列被称为单变量。然而,有时时间序列包含额外的维度,因此被称为多元时间序列。多变量时间序列中的额外变量可在对时间序列的特定目标变量建模时用作解释变量。
摘要
在这篇文章中,我列出了 12 个在构建预测模型时很重要的时间序列属性。从基本组件(如趋势或季节性)到自反性或变化检测,这些特征可能会显著影响预测模型的性能。
进一步阅读
[1] Hyndman,Rob J .,和 George Athanasopoulos。预测:原理与实践。OTexts,2018。
[2]彼得罗保罗斯、福蒂斯等人,“预测:理论与实践”《国际预测杂志》 (2022)。
[3]克里斯·查特菲尔德。时间序列预测。查普曼和霍尔/儿童权利委员会,2000 年。
[4]史密斯,乔治·克莱因。“预测反馈定律。”美国统计学家18.5(1964):11–14。
[5] Aminikhanghahi、Samaneh 和 Diane J. Cook。"时间序列变点检测方法综述."知识与信息系统 51.2(2017):339–367。
使用 PyTest 的 13 个技巧
原文:https://towardsdatascience.com/13-tips-for-using-pytest-5341e3366d2d
Unsplash 上 AltumCode 拍摄的照片
单元测试对于软件开发来说是一项非常重要的技能。有一些很棒的 Python 库可以帮助我们编写和运行单元测试,比如 Nose 和 Unittest 。但是我最喜欢的是 PyTest 。
我最近更详细地阅读了 PyTest 的文档,以便更深入地了解它的特性。
下面是一些我认为有用的模糊特性的列表,我将开始把它们集成到我自己的测试工作流程中。我希望这个列表中有一些你不知道的新东西…
💻这篇文章中的所有代码片段都可以在e4ds-snippets GitHub 资源库 中找到。
编写测试的一般提示👨🎓
1.如何编写好的单元测试
好了,这一条并不是专门针对 PyTest 库的,但是第一条建议是浏览一下 PyTest 的文档关于构建你的单元测试。这很值得一读。
一个好的测试应该验证某种预期的行为,并且能够独立于其他代码运行。也就是说,测试中应该包含设置和运行要测试的行为所需的所有代码。
这可以概括为四个阶段:
- 安排 —执行测试所需的设置。例如定义输入
- 动作 —运行您想要测试的功能
- 断言 —验证函数的输出是否符合预期
- 清理——(可选)清理测试中产生的任何工件。例如输出文件。
例如:
# example function
def sum_list(my_list):
return sum(my_list)
# example test case
def test_sum_list():
# arrange
test_list = [1, 2, 3]
# act
answer = sum_list(test_list)
# Assert
assert answer == 6
虽然这是一个微不足道的例子,但是让所有的测试都有一个通用的结构有助于提高可读性,编写更好的测试。
https://docs.pytest.org/en/7.1.x/explanation/anatomy.html
2.测试异常
通常,我们首先想到的测试是函数成功运行时的预期输出。
但是,当函数引发异常时,验证函数的行为也很重要。尤其是当您知道哪种类型的输入会引发某些异常时。
您可以使用pytest.raises
上下文管理器测试异常。
例如:
import pytest
def divide(a, b):
"""Divide to numbers"""
return a/b
def test_zero_division():
with pytest.raises(ZeroDivisionError):
divide(1,0)
def test_type_error():
with pytest.raises(TypeError):
divide("abc",10)
https://docs . pytest . org/en/7.1 . x/how-to/assert . html # assertions-about-expected-exceptions
3.测试记录/打印
PyTest 允许您测试代码中的打印和日志记录语句。
有两个内置的 PyTest fixtures, capsys 和 caplog ,可用于跟踪功能打印到终端的信息。
测试打印输出
def printing_func(name):
print(f"Hello {name}")
def test_printing_func(capsys):
printing_func(name="John")
# use the capsys fixture to record terminal output
output = capsys.readouterr()
assert output.out == "Hello John\n"
https://docs . py test . org/en/6.2 . x/reference . html # STD-fixture-cap sys
测试日志输出
import logging
def logging_func():
logging.info("Running important function")
# some more code...
logging.info("Function completed")
def test_logging_func(caplog):
# use the caplog fixture to record logging records
caplog.set_level(logging.INFO)
logging_func()
records = caplog.records
# first message
assert records[0].levelname == 'INFO'
assert records[0].message == "Running important function"
# second message
assert records[1].levelname == 'INFO'
assert records[1].message == "Function completed"
https://docs . pytest . org/en/6.2 . x/reference . html # STD-fixture-cap log
4.测试彩车
涉及浮点运算的算法会在 Python 中引起问题。
例如,这个简单的函数会导致一个奇怪的错误:
def subtract_floats(a,b):
return a - b
def test_substract_floats():
assert subtract_floats(1.2, 1.0) == 0.2
预期的输出应该是0.2
,但是 Python 返回了0.19999999999999996
。
这个函数的逻辑没有任何问题,它应该不会在这个测试用例中失败。
为了消除测试中的浮点舍入误差,您可以使用近似函数
import pytest
def test_substract_floats():
assert subtract_floats(1.2, 1.0) == pytest.approx(0.2)
测试现在通过了。
注意,您也可以将approx
函数应用于 numpy 数组。这在比较数组和数据帧时很有用。
例如:
import pytest
import numpy as np
np.array([0.1, 0.2]) + np.array([0.2, 0.4]) == pytest.approx(np.array([0.3, 0.6]))
https://docs . py test . org/en/7.1 . x/reference/reference . html # py test-approx
节省您时间的提示⏳
5.通过只运行某些测试来节省时间
运行测试应该有助于您的工作流程,而不是一个障碍。长时间运行的测试套件会降低您的速度,让您无法定期运行测试。
通常,您不需要在每次进行更改时都运行整个测试套件,尤其是当您只处理代码库的一小部分时。
因此,能够运行与您正在处理的代码相关的测试子集是很方便的。
PyTest 提供了一些选项来选择要运行的测试:
使用-k
标志
在运行 PyTest 时,您可以使用-k
标志来只运行匹配给定子串的测试。
例如,如果您有以下测试:
def test_preprocess_categorical_columns():
...
def test_preprocess_numerical_columns():
...
def test_preprocess_text():
...
def test_train_model():
...
您可以使用以下命令只运行包含子字符串' categorical '的第一个测试:
# run first test only
pytest -k categorical
您可以运行以下命令,只运行包含名称“预处理”的测试(前三个测试):
# run first three tests only
pytest -k preprocess
逻辑表达式也是允许的。例如,下面将运行包含“预处理”的测试,但排除包含“文本”的测试。这将运行前两个测试,但不会运行第三个:
# run first two tests only
pytest -k "preprocess and not text"
命令行标志文档中提供了对-k
标志的有效短语的完整解释:https://docs . pytest . org/en/7.2 . x/reference/reference . html #命令行标志
在单个测试文件中运行测试
如果您的测试被拆分到多个文件中,您可以通过在运行 PyTest 时显式传递文件名来从单个文件中运行测试:
# only run tests defined in 'tests/test_file1.py' file
pytest tests/test_file1.py
使用标记
您还可以使用 pytest“标记”来标记某些测试。这对于标记“慢”测试很有用,然后您可以用-m
标志将其排除。
比如说。
import time
import pytest
def my_slow_func():
# some long running code...
time.sleep(5)
return True
@pytest.mark.slow
def test_my_slow_func():
assert my_slow_func()
my_slow_func
将比其他测试花费更长的时间。
在使用了@pytest.mark.slow
装饰器之后,我们可以使用-m
标志来排除每次运行这个测试:
# exclude running tests marked as slow
pytest -m "not slow"
如果你在某些情况下需要跳过测试,标记也很方便。例如,如果您的 CI 构建使用多个版本的 Python 运行测试,并且您知道某个测试将会在某个版本的 Python 上失败。
import sys
@pytest.mark.skipif(sys.version_info < (3, 10), reason="requires python3.10 or higher")
def test_function():
...
https://docs.pytest.org/en/7.1.x/example/markers.htmlT12https://docs.pytest.org/en/7.1.x/how-to/skipping.html
6.仅重新运行失败的测试
当您运行整个测试套件时,您可能会发现少数测试失败了。
一旦您调试了问题并更新了代码,而不是再次运行整个测试套件,您可以使用--lf
标志只运行上次运行失败的测试。
在再次运行整个测试套件之前,您可以验证更新的代码是否通过了这些测试。
# only run tests which failed on last run
pytest --lf
或者,您仍然可以运行整个测试套件,但是使用--ff
标志从上次失败的测试开始。
# run all tests but run failed tests first
pytest --ff
https://docs . pytest . org/en/7.1 . x/how-to/cache . html # re running-only-failures-or-failures-first
节省您编写代码的技巧🚀
7.参数化测试
当您想要测试特定函数的多个不同输入时,人们通常会在测试函数中编写多个 assert 语句。例如:
def remove_special_characters(input_string):
return re.sub(r"[^A-Za-z0-9]+", "", input_string)
def test_remove_special_characters():
assert remove_special_characters("hi*?.") == "hi"
assert remove_special_characters("f*()oo") == "foo"
assert remove_special_characters("1234bar") == "bar"
assert remove_special_characters("") == ""
在 PyTest 中使用“参数化测试”有一个更好的方法:
import pytest
@pytest.mark.parametrize(
"input_string,expected",
[
("hi*?.", "hi"),
("f*()oo", "foo"),
("1234bar", "1234bar"),
("", ""),
],
)
def test_remove_special_characters(input_string, expected):
assert remove_special_characters(input_string) == expected
这有利于减少重复代码。此外,PyTest 为每个参数化的输入运行单独的测试。因此,如果其中一项测试失败,将更容易识别。然而,在使用多个 assert 语句的原始实现中,PyTest 将其作为单个测试运行。如果任何断言语句失败,整个测试将“失败”。
8.从文档字符串运行测试
另一个很酷的技巧是直接从 docstrings 定义和运行测试。
您可以如下定义文档字符串中的测试用例:
def add(a, b):
"""Add two numbers
>>> add(2,2)
4
"""
return a + b
然后,在运行pytest
命令时,通过添加--doctest-modules
标志,您可以将 docstring 测试包含到您的测试套件中。
pytest --doctest-modules
在 docstrings 中定义测试对使用您的代码的其他开发人员非常有帮助,因为它在函数定义中明确显示了函数的预期输入和输出。
我发现这对于使用“简单”数据结构作为输入和输出的函数非常有效。而不是编写向测试套件添加更多代码的全面测试。
https://docs . pytest . org/en/7.1 . x/how-to/doctest . html # how-to-run-doc tests
9.内置 pytest 夹具
PyTest 包括许多非常有用的内置装置。
我们在技巧 3 中简要介绍了其中的一些装置——capsys 和 cap log——但是完整的列表可以在这里找到:https://docs . pytest . org/en/stable/reference/fixtures . html # built-in-fixtures
您的测试可以通过简单地将它们作为参数添加到测试函数中来访问这些装置。
在我看来,两个最有用的内置夹具是request
夹具和tmp_path_factory
夹具。
你可以在这里查看我关于使用request
夹具在参数化测试中使用夹具的文章。
tmp_path_factory
fixture 可以用来创建运行测试的临时目录。例如,如果您正在测试一个需要将文件保存到某个目录的函数。
https://docs . pytest . org/en/stable/reference/fixtures . html #内置固定装置
https://docs . pytest . org/en/7.1 . x/how-to/tmp _ path . html # the-tmp-path-factory-fixture
帮助调试的提示
10.增加测试的冗长度
PyTest 的默认输出可能非常小。如果测试失败,增加终端输出中提供的信息量会很有帮助。
这可以通过使用详细标志-vv
来添加
# increase the amount of information provided by PyTest in the terminal output
pytest -vv
https://docs . py test . org/en/7.2 . x/reference/reference . html #命令行标志
11.显示测试持续时间
如果您的测试套件需要很长时间来运行,您可能想要了解哪些测试运行的时间最长。然后,你可以尝试优化这些测试,或者使用标记来排除它们,如上所示。
您可以使用--durations
标志找出哪些测试运行时间最长。
您还需要传递 verbosity 标志来显示完整的持续时间报告。
# show top 5 longest running tests
pytest --durations=5 -vv
https://docs . py test . org/en/7.2 . x/reference/reference . html #命令行标志
12.在代码中显示 print 语句的输出
有时,您会在源代码中使用 print 语句来帮助调试函数。
默认情况下,如果测试通过,Pytest 不会显示这些打印语句的输出。
您可以通过使用-rP
标志来覆盖这种行为。
def my_function_with_print_statements():
print("foo")
print("bar")
return True
def test_my_function_with_print_statements():
assert my_function_with_print_statements()
# run tests but show all printed output of passing tests
pytest -rP
https://docs . py test . org/en/7.2 . x/reference/reference . html #命令行标志
13.为参数化测试分配 id
运行参数化测试的一个潜在问题是,它们在终端输出中以相同的名称出现。即使他们在技术上测试不同的行为。
您可以将 id 添加到您的参数化测试中,为每个参数化测试赋予一个唯一的名称,以帮助识别它。它还增加了测试的可读性,因为你可以清楚地知道你要测试什么。
这里有两个向测试中添加 id 的选项:
选项 1:id
参数
重用技巧 7 中的参数化示例:
@pytest.mark.parametrize(
"input_string,expected",
[
("hi*?.", "hi"),
("f*()oo", "foo"),
("1234bar", "1234bar"),
("", ""),
],
ids=[
"remove_special_chars_from_end",
"remove_special_chars_from_middle",
"ignore_numbers",
"no_input",
],
)
def test_remove_special_characters(input_string, expected):
assert remove_special_characters(input_string) == expected
选项 2:使用pytest.param
或者使用pytest.param
包装:
@pytest.mark.parametrize(
"input_string,expected",
[
pytest.param("hi*?.", "hi", id="remove_special_chars_from_end"),
pytest.param("f*()oo", "foo", id="remove_special_chars_from_middle"),
pytest.param("1234bar", "1234bar", id="ignore_numbers"),
pytest.param("", "", id="no_input"),
],
)
def test_remove_special_characters(input_string, expected):
assert remove_special_characters(input_string) == expected
一般来说,我更喜欢使用选项 1,因为我认为它更整洁。但是,如果您正在运行包含许多行的大量参数化输入,那么使用选项 2 可能更具可读性。
https://docs . py test . org/en/stable/example/parameter ize . html # different-options-for-test-ids
结论
PyTest 是一个很棒的测试框架,有很多有用的特性。文档通常非常好,我强烈推荐浏览更多信息和其他优秀特性。
我希望您学到了一些新东西——我很想知道您还有哪些使用 PyTest 的技巧。
测试愉快!
本文最初发表于engineeringfordatascience.com
您应该知道的 13 个有用的 Shell 命令
原文:https://towardsdatascience.com/13-useful-shell-commands-you-should-know-4a28cfbe5732
提高生产力和增强您的终端技能
用 DALLE-2 生成的图像
对于很多程序员来说,终端就像第二个家,只不过一切都触手可及。想象一下,当你舒舒服服地躺在床上,冲咖啡,用手指轻轻一划就可以毫不费力地拉开窗帘,甚至可以遛狗。这就是开发人员喜欢命令行的原因:您可以快速完成所有工作,而无需点击数十个窗口。
然而,为了提高使用 shell 的效率,您必须习惯于使用纯文本界面执行任务,并且不可避免地要学习一些命令。一旦你知道了像改变目录和文件目录这样的基础知识,是时候学习那些常用的命令了,这些命令会给你的控制台工作效率带来积极的影响。
在本文中,我将向您展示我一直使用的 13 个命令,按用例分组。请注意,有些系统可能没有捆绑所有这些实用程序,但是您可以使用您选择的软件包管理器轻松地安装它们。
更好的输出可视化
如果您使用终端已经有一段时间了,那么您肯定会遇到这样的情况:命令输出太大,以至于无法显示在屏幕上,甚至无法显示在终端历史记录中。在读取大型日志文件或列出文件和目录时,通常会出现这种情况。
幸运的是,有三个命令可以解决这个问题:head
、tail
和less
。
head
仅打印输入的第一行(或字节)。默认打印行数为 10,但您可以通过-n
选项指定:
$ cat large_file.log | head -n 30
上面的命令只打印 cat-ted 文件的前 30 行。
tail
与head
相反:仅打印给定输入的最后一行(或字节):
$ cat large_file.log | tail
上面的命令打印给定输入的最后 10 行。
最后,less
允许您使用箭头键或滚轮、利用快捷方式等,轻松浏览文本,无论是文件还是命令输出。如果你必须浏览大量输出,less
是你最好的朋友。
不要忘记按q
从less
退出,否则你可能会永远被锁在一个仅次于vim
的无法逃脱的监狱里。在本文的后面,我们将会遇到一些常见的less
命令的实际应用。
计算代码行数
如果您正在进行一个大型项目,您可能会好奇它由多少行代码组成。您可以利用命令行的强大功能来为您完成繁重的工作,而不是打开每一个源代码文件,记下行数,然后手动添加它们。
首先,wc
命令可以和它的-l
选项一起使用来计算一个给定文件的行数。然而,代码库是由多个文件和嵌套目录组成的。这就是find
命令派上用场的地方。
$ find <dir_name> -name "*.py"
将查找指定目录及其子目录中扩展名为.py
的每个文件。除此之外,您可以将结果传输到sort
以产生更整洁的输出。最后的命令如下所示:
$ find . -name "*.cpp" | xargs wc -l | sort -nr
上面的命令打印当前目录及其子目录中每个.cpp
文件的行数,加上总行数,全部以整齐的降序排列。
但是,如果您想在普查中包含其他文件类型,例如头文件,该怎么办呢?find
允许您指定多个模式进行查找:
$ find . -name '*.cpp' -o -name '*.hh' | xargs wc -l | sort -nr
这是我在一个 C++项目中用来计算所有代码行的命令,包括源代码和头文件。下面是一个输出示例:
1917 total
768 ./src/processor.cpp
137 ./headers/processor.hh
100 ./headers/byte_code.hh
84 ./src/byte_code.cpp
75 ./src/memory.cpp
64 ./src/main.cpp
55 ./src/registers.cpp
42 ./headers/registers.hh
40 ./headers/memory.hh
最后,如果你的代码库太大,以至于把所有东西都打印到控制台上变得很糟糕,你总是可以把输出传递给less
。因此,最终的行计数器命令应该是:
$ find . -name '*.cpp' -o -name '*.hh' | xargs wc -l | sort -nr | less
如果您厌倦了一直输入它,您可以将它放在 bash 文件中。
获取磁盘使用情况和文件大小
如果您想知道您的虚拟或物理存储设备上还有多少空闲空间,您可以使用df
命令。实际上,您可能希望使用-h
选项以人类可读的格式打印尺寸。
$ df -h
和示例输出:
Filesystem Size Used Avail Use% Mounted on
dev 1,9G 0 1,9G 0% /dev
run 1,9G 18M 1,9G 1% /run
/dev/sda2 102G 23G 74G 24% /
tmpfs 1,9G 120M 1,8G 7% /dev/shm
/dev/loop1 114M 114M 0 100% /var/lib/snapd/snap/core/13308
tmpfs 1,9G 42M 1,9G 3% /tmp
/dev/sda1 300M 312K 300M 1% /boot/efi
如果你想打印一个目录的大小及其内容,你可以使用du
命令。
$ du . -hacS --apparent-size
该命令从当前目录开始,以人类可读的格式列出所有文件和目录的大小,并打印总大小。示例输出:
1,3K ./src/main.cpp
870 ./src/errors.cpp
22K ./src/processor.cpp
1,7K ./src/memory.cpp
1,2K ./src/registers.cpp
1,8K ./headers/byte_code.hh
4,4K ./headers/processor.hh
1,1K ./headers/memory.hh
16K ./headers
734 ./Makefile
66K total
进一步的改进是排除像.git
这样的目录,并使用less
输出结果:
$ du . --exclude "**/.git" -hacS --apparent-size | less
定位文件和程序
如果您必须在系统中搜索一个文件,您可以使用locate
命令来查找模式或确切的文件名。例如,您想找到您计算机上的所有.jpg
文件:
$ locate .jpg
和示例输出:
/boot/grub/themes/Vimix/archlinux03.jpg
/boot/grub/themes/Vimix/archlinux04.jpg
/boot/grub/themes/Vimix/archlinux06.jpg
/usr/share/app-info/icons/archlinux-arch-community/64x64/freewheeling_freewheeling.jpg
然而,如果您想定位可执行文件、源代码或手册页,您可以使用whereis
命令:
$ whereis gcc
上面的命令查找以“gcc”作为基本名称的文件:
gcc: /usr/bin/gcc /usr/lib/gcc /usr/share/man/man1/gcc.1.gz /usr/share/info/gcc.info.gz
当您必须定位某个程序的安装位置时,whereis
命令会很有用。或者,你可以使用which
,但是它的功能比较弱:
$ which gcc/usr/bin/gcc
比较文件
假设您必须检查两个文件是否相等,或者,如果它们不相同,您想知道区别在哪里。cmp
和diff
就是为此而生。
cmp
是更简单的选项。它逐字节比较两个文件,并输出第一个不匹配的字节和行号。如果文件相等,它不会输出任何内容:
$ cmp maths.c setup.pymaths.c setup.py differ: byte 1, line 1
如果您想要更详细的比较,diff
显示文件的不同之处:
$ diff file1.txt file2.txt13c13
< return NULL;
---
> return NULLoaoaoaoao;
对于并排比较,您可以使用-y
选项:
$ diff -y file1.c file2.c
样本输出。需要一个图像来保持输出格式。
获取设备状态
acpi
实用程序显示关于当前电池电量、热量状态、冷却等有用信息。我通常添加-V
选项来显示所有可用信息:
$ acpi -V
Battery 0: Full, 100%
Battery 0: design capacity 3691 mAh, last full capacity 2814 mAh = 76%
Adapter 0: on-line
Thermal 0: ok, 45.0 degrees C
Thermal 0: trip point 0 switches to mode critical at temperature 126.0 degrees C
Thermal 1: ok, 51.0 degrees C
Thermal 1: trip point 0 switches to mode critical at temperature 95.0 degrees C
Cooling 0: Fan 0 of 1
我经常发现自己在系统特别加载时使用acpi
来控制温度。
测量执行时间
你有没有想过一个命令或一个脚本需要多少时间来执行?无论您想知道一个编译过程持续了多长时间,还是想比较两个命令的性能,time
实用程序都允许您测量执行时间和其他有用的参数,例如磁盘 io、平均内存使用量、使用的 CPU 百分比等等。
$ time makereal 0m6,256s
user 0m5,835s
sys 0m0,383s
或者您可以使用-f
选项指定输出格式:
$ time -f "\nInputs: %I\nOutputs: %O\nTime elapsed: %E" locate gimp...Inputs: 9136
Outputs: 0
Time elapsed: 0:00.74
结论
一旦您知道一些基本的 shell 命令并开始构建工作流,命令行就可以成为您最好的通用工具,让您只需按几个键就可以高效地处理一切。您不必成为系统专家就能从使用终端中获益:您所需要的只是一些有用的命令和应用它们的大脑。
我希望你喜欢这篇文章。如果你有什么要补充的,请在评论中分享你的想法。感谢阅读!
如果你对学习成功的软件开发职业的基本技能感兴趣,看看下面这个故事:
https://betterprogramming.pub/the-language-every-programmer-should-master-8d0dfc461284
您下一个数据科学项目的 14 个数据集
原文:https://towardsdatascience.com/14-datasets-for-your-next-data-science-project-f5fca7f75e32
包含文本/图像分类、推荐系统、数据可视化等方面的教程
维塔利·弗拉索夫在的照片
数据科学项目中不能省略什么?数据!
这就是这篇文章的全部内容。我将与您分享 14 个数据集,您可以使用它们来进行数据分析、数据可视化、文本/图像分类、构建推荐系统等等。
列出的每个数据集都有教程链接。如果你需要一些指导或灵感,看看它们吧。教程是按难度排列的,所以初级教程在开头,高级教程在文章末尾。
数据分析
您可以使用 Pandas 和 Numpy 来处理本节中列出的数据集。
考试分数
该数据集包含学生在各种科目(数学、阅读、写作)上的分数,以及关于学生的其他数据,如他们的性别、种族和午餐类型。您可以执行一些分析并获得每个性别的平均分数,了解学生是否通过了考试,等等。
数据集:链接
教程:链接
口袋妖怪数据集
这个数据集有 721 个口袋妖怪的统计数据。你会发现他们的类型,HP,攻击,特殊攻击,特殊防御,和速度。你可以玩玩这些数据,做一些分析,比如说,找出攻击和防御最高的口袋妖怪。
如果你是熊猫的新手,我强烈建议你通过观看下面的教程来学习这个数据集的基础知识。
数据集:链接
教程:熊猫教程
网飞电影和电视节目
该数据集包含截至 2021 年年中网飞所有可用的电影和电视节目。在那里,您可以找到诸如标题、导演、分级、发行年份和持续时间等数据。缺少数据,在项目中使用某些列之前,需要对它们进行一些清理。
数据集:链接
教程:用 Python 清理和准备数据的简明指南
数据可视化
您可以使用这些数据集来创建可视化效果。为此,您可以使用 matplotlib、seaborn 甚至 pandas。
FIFA 22 球员数据集
该数据集包含视频游戏 FIFA 的足球运动员数据。出生日期、身高、体重和综合评分等数据可以在这里找到。
最酷的是,在网站上,不仅有 2022 年的球员数据,还有 2016 年至 2022 年的数据,所以你可以使用折线图和其他可视化方式比较每个球员的收视率演变。
数据集:链接
教程:Python 优美可视化的简单指南
人口数据集(1955-2020 年)
该数据集包含世界上大多数国家从 1955 年到 2020 年每 5 年的人口。数据集有 3 列:国家、年份和人口。这些数据有利于制作简单的可视化图形,如饼图、条形图、箱线图和直方图。
数据集:链接
教程:用熊猫制作漂亮的交互式可视化效果的最简单方法
辛普森一家/阿凡达最后的气宗
为什么不在学习可视化的过程中享受乐趣呢?Kaggle 上有免费的电视节目数据集,如《辛普森一家》和《阿凡达:最后的气宗》。在那里,你可以找到所有的剧集和剧本,这样你就可以可视化地显示谁的台词最多,谁跟谁说话,制作文字云,以及情节情感分析。
数据集:辛普森一家,阿凡达
教程:辛普森一家遇上数据可视化,数据可视化用 Python 与阿凡达最后的气宗
自动化
您可以使用 Python 自动完成创建 Excel 报表等重复任务。
超市销售
我们大多数人在生活中曾经不得不使用销售数据集创建 Excel 报表。为什么不自动化呢?该数据集包含一家超市公司 3 个月的历史销售额数据。您可以使用这些数据在 Excel 中使用 Python 后台创建数据透视表和条形图。
数据集:链接
教程:用 Python 实现 Excel 报表自动化的简单指南
回归分析
波士顿房价
这是一个用于进行线性回归的流行数据集。该数据集包含有关波士顿房屋的信息,如城镇人均犯罪率、每所住宅的平均房间数、每 10,000 美元的全价值财产税税率等。
数据集:您可以通过 sklearn 库获得这个数据集。
**from sklearn.datasets import load_boston**
boston_dataset = load_boston()
教程:使用 Python 进行线性回归的简单指南
文本分类
如果你对 NLP(自然语言处理)感兴趣,你会喜欢这些数据集的。要使用它们,你必须使用诸如 sklearn、NLTK、gensim、spaCy 等库
IMDB 数据集—情感分析
该数据集包含 50k 条电影评论及其情感(正面/负面)。这些数据对于建立一个分类文本是正面还是负面的模型非常有用。这就是所谓的二进制文本分类。
数据集:链接
教程:Scikit-Learn 简单指南——用 Python 构建机器学习模型
60k 堆栈溢出问题和质量评级
这个数据集包含了 2016 年到 2020 年的 60k 个栈溢出问题。有 3 种类型的问题:HQ(未经编辑的高质量帖子),LQ _ 编辑(分数为负的低质量帖子,有多个社区编辑),LQ _ 关闭(未经编辑就被社区关闭的低质量帖子)。
您可以使用该数据集来预测问题的标签。这比上一个项目更具挑战性,因为对于一个标签来说,不仅有 2 个选项,还有多个选项。在这种情况下,您必须使用多标签分类方法。
数据集:链接
教程:用线性模型预测 StackOverflow 上的标签(这个不完整,但有如何解决它的说明)
图像分类
与本文中列出的其他数据集不同,这些数据集主要包含可用于构建分类模型的影像。为此,您必须使用张量流、打开 CV 等。
石头剪刀布
如果你喜欢石头剪子布游戏,你就不会对这个数据集感到厌烦。该数据集包含 2892 张不同手在石头/布/剪刀姿势下的图像。
这通常用于影像分类(如下教程所示),但您也可以将此数据集用于其他目的。
数据集:链接
教程:石头剪子布图像分类使用 CNN
面罩检测
该数据集包含 1,376 幅图像。在 690 张图片中,人们戴着口罩,而在 686 张图片中,人们没有戴口罩。
您可以使用此数据集构建一个模型来检测一个人是否戴着口罩。项目结束时,你可以拿起一个面具,用你电脑上的摄像头自己测试一下。
数据集:链接
教程:使用 TensorFlow 和 OpenCV 的人脸遮罩检测
推荐系统
你有没有想过像网飞和 YouTube 这样的公司是如何推荐电影和视频的?您可以使用下面的数据集来构建自己的推荐系统,并了解其工作原理。
电影镜头 20M 数据集—电影推荐
该数据集包含 2000 万个评级和 465,000 个标签应用,由 138,000 个用户应用于 27,000 部电影。非常适合那些想从头开始构建电影推荐系统的人。
数据集:链接
教程:Python 中的推荐系统
加入我的电子邮件列表,与 1 万多人一起获取我在所有教程中使用的 Python for Data Science 备忘单(免费 PDF)
如果你喜欢阅读这样的故事,并想支持我成为一名作家,可以考虑报名成为一名媒体成员。每月 5 美元,让您可以无限制地访问数以千计的 Python 指南和数据科学文章。如果你使用我的链接注册,我会赚一小笔佣金,不需要你额外付费。
https://frank-andrade.medium.com/membership
14 场 Kaggle 竞赛开启您的数据科学之旅
原文:https://towardsdatascience.com/14-kaggle-competitions-to-start-your-data-science-journey-41943496b6f4
无限的免费资源等待着你
迪诺·瑞奇穆斯在 Unsplash 上拍摄的照片
Kaggle 是一个主办在线机器学习竞赛的网站,无论有没有奖品。它允许用户主要以 Jupyter 笔记本的形式分享他们的代码。它有大量的数据集,甚至有机器学习和数据科学的课程。
我基本上是一个自学成才的数据科学家,我在头六个月学到的一切都归功于 Kaggle。我当时做的是参加一个比赛,使用别人的代码,理解它,谷歌任何我不知道的东西,并从中获得乐趣。4 年后,我不那么活跃了,但我总是回来查看新的比赛、笔记本和很酷的数据集。总是有新的东西要学。
我对有抱负的数据科学家的建议是尽可能地利用 Kaggle,因为它能为你提供很多东西。它最重要的资产是来自其他用户的即用型笔记本电脑。通过阅读和复制它们,你可以了解其他人是如何面对和解决问题的。你不需要从零开始。可以抄一个本子,改进一下。
有些比赛对初学者友好,是开始数据科学之旅的最佳方式。我会把他们区分为:
- 分类
- 回归
- 计算机视觉
- 自然语言处理
让我们来看看这个列表:
分类问题:
1。 泰坦尼克号 🛳️
Kaggle 上的入门比赛。预测哪些乘客在泰坦尼克号海难中幸存。这是一个有 891 个训练样本和 10 个特征的分类问题。
使用这个数据集,你将熟悉 Kaggle 平台以及竞赛中的工作方式。如何参加比赛、创建笔记本、使用其他人的笔记本、提交内容以及查看自己在排行榜上的得分。
2。 森林覆盖类型预测 🌳
另一个分类问题,您需要预测 30 x 30 米森林单元中主要的树木覆盖种类。15,120 个训练样本和 54 个特征。
这是一个 7 类多类分类问题。从泰坦尼克号数据集向前迈进了一步。现在你已经熟悉了 Kaggle,你可以接受这个挑战,并与 1,600+的其他球队进行比赛。
3。 不要过度配合!ιι⚖️
给你一个只有 250 个训练行和 300 个特征的分类问题,而你试图预测 19,750 行。挑战在于开发一个不会过度拟合的成功模型。
我推荐这个比赛来磨砺你(不)过度拟合的技能。任何机器/深度学习项目中非常重要的概念。请务必查看其他用户提供的可用代码。你会学到很多减少过度拟合的技巧和诀窍。
4. CareerCon 2019 —帮助导航机器人🤖
使用 487,680 行和 10 个变量的训练数据集,帮助机器人识别他们站在的地板表面。
这是一场竞争,也是一个找工作的机会。表现最好的人获得了被选中公司的面试机会。这是一个发现你在其他候选人中所处位置的好方法。
5. 分类特征编码挑战 🐈
只包含分类特征的竞争。300,000 行和 23 个特征。这个游戏竞赛将让你有机会为不同的算法尝试不同的编码方案,以比较它们的表现。
参加机器学习竞赛是一个很好的策略,它必须教会你一些新的东西。在你的学习旅程中,不要只和你更熟悉的人竞争。走出你的舒适区,尝试新事物。在这里,您将学习如何处理分类特征。
回归问题:
6. 房价 🏠
事实上的回归机器学习竞赛。有 79 个解释变量描述了爱荷华州埃姆斯住宅的各个方面,这个比赛要求你预测每栋房子的最终价格。
这是一场非常有趣的比赛。有这么多的功能,我推荐它是为了挑战你的功能工程技能!
7. TMDB 票房预测 🍿
在这场比赛中,你将看到电影数据库中超过 7,000 部过去电影的元数据,以尝试预测它们的全球票房总收入。
谁不喜欢看电影?现在,您有机会使用包含 7,000 部电影的数据集,探索它们的许多可用功能。在享受乐趣的同时,学习预处理、特征工程、数据转换以及更多内容!
8. 自行车共享需求 🚴♀️
在本次竞赛中,您需要将历史使用模式与天气数据相结合,以便使用 10,886 个训练行来预测华盛顿特区首都自行车共享计划中的自行车租赁需求。
使用环境数据来预测日常使用情况太酷了。使用温度、湿度、风速等等来预测自行车需求?我加入。
9.预测未来销售📋
这项挑战是 Coursera 课程“如何赢得数据科学竞赛”的最终项目。在本次竞赛中,您将使用由每日销售数据组成的具有挑战性的时间序列数据集。
同样,我们的重点是走出舒适区,学习新的东西。时间序列是您将会遇到的最常见的数据类型之一。因此,学习如何处理这些类型的数据将对你有很高的价值。
计算机视觉问题:
10. 数字识别器 🔢
如果你是计算机视觉的新手,这是使用包括预先提取的特征的经典数据集的神经网络等技术的完美介绍。
这是计算机视觉事实上的“hello world”数据集。任务是从成千上万的手写图像数据集中正确识别数字。
11. 犬只品种识别 🐶
从 120 个可能的选择和每班有限数量的训练图像中预测正确的品种。
计算机视觉领域的进一步发展。预测手写数字真的很容易。预测 120 种狗的品种更具挑战性,但也是有益的。
自然语言处理问题:
12. 真实与否?NLP 与灾难推文 ⛈️
这个特殊的挑战对于希望开始自然语言处理的数据科学家来说是完美的。你面临的挑战是建立一个机器学习模型,预测哪些推文是关于真正的灾难,哪些不是。你可以访问一个由 10,000 条推文组成的数据集,这些推文都是经过人工分类的。
这个数据集也被学术界用于提取人们如何在推特上发布自然灾害的宝贵见解。文本数据的可能性和学习机会是无限的,所以我建议你从这个数据集和比赛开始这个独特的旅程。
13.拼图毒性评论分类挑战 🗯️
在这场比赛中,你的挑战是建立一个多头模型,能够检测不同类型的毒性,如威胁,淫秽,侮辱和基于身份的仇恨。你将使用维基百科谈话页面编辑的评论数据集。
本次竞赛中需要重点关注的一件重要事情是,您可以对原始数据应用各种预处理技术,以成功适应您的分类算法。
14.影评情感分析🎬
这个比赛提供了一个在烂番茄数据集上测试你的情感分析想法的机会。你被要求用五个值来标记短语:负面的、有点负面的、中性的、有点正面的和正面的。像句子否定、讽刺、简洁、语言歧义和许多其他障碍使这项任务非常具有挑战性。
这个比赛实际上种子了我 2016 年的大学论文,在那里我做了影评的情绪检测!
最后,我建议你在每次比赛中一次只专注于一件事。预处理、编码、转换、ml 算法、特征工程、选择、调整、分析等等。创建一个 GitHub 个人资料,并上传你的作品。
这有双重目的:a)未来你总能找到你以前的作品,b)全世界都能看到你的能力证明。
你可以从上面的比赛开始,随着你的学习和感觉更加自信,过渡到更具挑战性和新的比赛。
祝您踏上伟大的数据科学之旅!
不确定接下来要读什么?这里有一个选择:
**</5-data-science-podcasts-you-should-be-listening-right-now-178f0af8ebce>
保持联络
跟随我在 Medium 上了解更多类似的内容。
让我们在 LinkedIn 上连线。
检查我的 GitHub 。**
应对数据科学面试的 14 个概率问题
原文:https://towardsdatascience.com/14-probability-problems-for-acing-data-science-interviews-3735025a6425
用风格解密数据科学访谈中的概率问题
由@briansuman 拍摄的关于 unsplash.com 的照片
关于概率的问题在任何数据科学面试中都很常见。这些问题可能很有挑战性(也很棘手),但是如果你经过一些练习并且知道基本的公式和概念,这些问题是很容易解决的。在这篇博客中,我分享了一些关于概率中不同概念的练习题(有解答)。
关键词 : 概率,二项分布,贝叶斯定理
博客假设读者知道基本的概率公式和概念。请参考参考资料部分,获得一些关于这些概念的好的阅读材料。我建议读者首先试着在一张纸上自己解决问题,然后去寻找提示和解决方案。注意:同样的问题可能有许多不同的解决方法。提供的解决方案只是其中一种方式(可能是唯一的方式)。
基本概率
Q1。 正六边形的 3 个顶点(角)随机连接。形成等边三角形的概率有多大?
注意:在正六边形中,所有的边和角度都是相等的。等边三角形的三条边都相等。答案= 0.1。
回答 Q1。图片由作者提供。
Q2。 甲、乙、丙三人独立向一个目标开火。(I)恰好其中一个击中目标,(ii)至少其中一个击中目标的概率是多少? 给定:命中目标的概率。P(A) = 1/6,P(B) = 1/4,P(C) = 1/3。
(I)恰好其中一个击中目标的概率要求另外两个不击中目标。我们可以很容易地看到这一事件发生的三种情况。最后,我们通过对这些情况进行联合来计算概率。
(ii)至少其中一个命中目标的概率是通过创建几个案例并像我们在前面所做的那样取一个并集来解决的。一种更简单的方法是计算同一事件的负值,并将其从 1 中减去。(因为点火是独立的,所以 P(ABC)变成 P(A)P(B)P(C))。
回答 Q2。图片由作者提供。
Q3。 老师突击考试的概率是 0.55。如果一个学生缺席两天。他错过一次测试,最多一次测试的概率是多少?
(一)与上一个问题类似。(ii)错过最多 1 次测试意味着错过 0 次测试或 1 次测试。
PS:这类似于优步和 Lyft 的问题。
回答 Q3。图片由作者提供。
Q4。 一个盒子里装 2 支缺陷笔和 3 支工作笔。笔被逐个测试,直到发现两个有缺陷的笔。在(I)第二次测试,(ii)第三次测试结束时,测试程序结束的概率是多少?
为了使测试在两次检查结束时结束,前两支起动笔需要有缺陷。为了让测试在三次检查结束时结束,我们可以创建案例并获取联合。
回答 Q4。图片由作者提供。
Q5。 如果一个房间里有 30 个人,每个人生日不同的概率是多少? 假设一年中有 365 种可能的生日。
回答 Q5。图片由作者提供。
代数问题
Q6。 一个变形虫分别有 25%、25%、50%的几率产生 0、1、2 个后代。阿米巴原虫的每个后代也有相同的概率。阿米巴原虫的血统灭绝的概率有多大?
阿米巴原虫谱系死亡需要产生 0 个后代。如果它产生 1 个后代,那么子代必须产生 0 个后代。两个孩子的后代也是如此。
回答 Q6。图片由作者提供。
Q7。2×2 矩阵中的元素是为每个元素独立选择的整数。项为奇数的概率为 p,若行列式的值为偶数的概率为 0.5,求 p .
行列式为奇数/偶数的概率可以通过对奇数/偶数进行分类,然后对这些分类的概率求和来计算。
回答 Q7。图片由作者提供。
二项分布
Q8。醉汉要么向前一步,要么向后一步。他向前迈一步的概率是 0.4。求 11 步结束时他离起点 1 步的概率?
显然,对于离起点 1 步远的醉汉来说,他可以向前走 5 步(意味着向后走 6 步)从而在起点后 1 步结束,或者他可以向前走 6 步(意味着向后走 5 步)从而在起点前 1 步结束。最后的概率可以通过两个事件的联合来计算。
回答 Q8。图片由作者提供。
Q9。在一系列独立的投掷中,一枚硬币正面落地的可能性是反面的两倍。找出第五次投掷时出现第三次投掷的概率。
对于出现在第五次投掷中的第三个头,最初的两个头可以出现在第四次投掷中的任何一次,这成为二项式分布的一种情况。
回答 Q9。图片由作者提供。
全概率定律
Q10。一位富有的女士在她的钱包里有 4 个夹层。第一格有 1 卢比和 2 枚硬币。第二个有 2 卢比和 3 派斯硬币。第三个有 3 卢比和 4 派斯硬币。第四个有 4 卢比和 6 派斯硬币。
她随机选择一个隔间&抽取一枚硬币,抽取的硬币是卢比硬币的概率是多少?
回答 Q10。图片由作者提供。
贝叶斯定理
Q11。 艾滋病病毒检测准确率达 99%(双向)。只有 0.3%的人口是 HIV +。假设一个随机的人检测为阳性,那么这个人是 HIV 阳性的概率是多少?
回答 Q11。图片由作者提供。
Q12。 A 在 70%的情况下讲真话,B 在 50%的情况下讲真话。找出他们在描述某一事件时会说同样的话的概率?
回答 Q12。图片由作者提供。
杂项卡问题
Q13。从 52 张洗好的牌中一张一张地发牌。在第一张王牌 出现之前,恰好发出***【k】张牌的概率是多少?***
我们在间接寻找第一张 ace 出现在第(k+1)张牌中的概率。 () 是标准组合的记数法。
回答 Q13。图片由作者提供。
Q14。从一副 52 张洗好的牌中取出所有的正面牌。从剩下的 40 张牌中,随机抽取 4 张。4 张牌出自不同花色、不同面额的概率有多大?
花色总数= 4(黑桃、红心、梅花、方块);总面额= 13 (2,…,10,A,J,Q,K)。
回答 Q14。图片由作者提供。
参考
[1].(必读)概率概念的总结理论(包括定律和定理):https://www.cuemath.com/data/probability/
[2].基本概率概念:https://seening-theory . brown . edu/basic-Probability/index . html(偶然事件、期望等。)
[3].条件概率:http://www.stat.yale.edu/Courses/1997-98/101/condprob.htm
[4].全概率定律:https://youtu.be/7t9jyikrG7w
[5].贝叶斯定理(3 blue 1 brown):https://youtu.be/HZGCoVF3YvM
[6].二项式分布(汗阿卡德。):https://youtu.be/WWv0RUxDfbs
[7].排列组合:https://youtu.be/XJnIdRXUi7A
[8].一些概率统计的 YouTube 频道推荐:@ jbstatistics ,@ organicchemistrytutor
我希望这是一些关于概率的很好的练习,并且你喜欢解决这些问题。我很高兴知道任何不同的方法来解决上述问题。我很乐意回答任何疑问或讨论上述任何问题。反馈非常感谢。拍手声👏🏼也是一个很好的反馈😇。祝你下次数据科学面试好运。你可以通过 Linkedin 联系我。
谢谢你!
评估数据谱系时要问的 14 个问题
原文:https://towardsdatascience.com/14-questions-to-ask-when-evaluating-data-lineage-d7af718b150a
正在寻找数据沿袭工具?这些是您应该询问的关键“问题”和功能。
照片由 克劳福德 上 下
数据沿袭可能会很混乱。
就像织毯子一样。线从各个方向来来去去,多得数不清。所有这些都必须以一种复杂的模式完美地结合在一起。弄对了就是艺术,哪怕有一个元素不符合,就是混乱。
沿袭很难得到正确的结果,因为存在大量的变量——来自各种来源(不断变化的旧来源和最新的新来源)的数据,每个阶段的转换,命名和描述数据资产所涉及的复杂语言,编写数据逻辑和代码的不同风格,等等。
尽管这很困难,但我们不能放弃。沿袭在数据团队工具箱中是不可或缺的,它揭示了数据流并支持重要的用例,如影响分析、根本原因分析、治理和法规遵从性。
在您搜索合适的数据沿袭工具以全面评估其深度(支持的唯一源的数量)广度(每个源支持的字段或对象的数量),以及效用(跨不同数据角色提供洞察力和行动的能力)时,这里有 14 个问题要问。
作者谢恩·吉布森(@ shag bility)
1.它会自动解析 SQL 查询吗?
许多数据平台都提供了沿袭 API,因此任何沿袭系统都可以轻松地从这些来源获取和使用沿袭。但是,并不是每个平台都这样做。自动 SQL 解析对于填补这些空白并确保您的谱系完整,涵盖所有数据源、流程和资产至关重要。
如果您只在仓库层解析 SQL,那么来自没有本地查询历史的数据源的 SQL 查询(例如像 PostgreSQL 和 MySQL 这样的关系数据库)将会漏网。
寻找从没有“查询历史”特性的源系统中读取 SQL 查询转储的能力。
2.支持哪些类型的 SQL 语句?
为了避免血统上的差距,从各种类型的 SQL 语句中解析和注册血统是很重要的:
CREATE TABLE
CREATE TABLE AS SELECT
CREATE VIEW
MERGE
INSERT INTO
UPDATE
大多数 SQL 解析器支持 SQL CREATE
,在某些情况下,还支持MERGE
语句。但是,很多不支持INSERT INTO
和UPDATE
语句。这些说明了数据仓库中的大多数转换,因此它们对于完整的沿袭覆盖非常重要。
寻找还可以解析 **MERGE**
、 **INSERT INTO**
和 **UPDATE**
语句的血统。
3.沿袭 API 支持程序化的沿袭创建和检索吗?
数据生态系统在不断发展,新的数据源也在不断涌现。以编程方式处理来自不受支持的来源的沿袭(通过一个开放的 API)是扩展沿袭的关键,而不必担心您可以和不可以采用哪些新平台。
寻找两个关键特征:
- 能够通过 API 以编程方式检索和创建沿袭。
- 能够跨任何对象类型发布和检索表和列级沿袭。
4.沿袭是本地的功能,还是由外部合作伙伴提供的?
在沿袭中,处理边缘案例是一种规范,新的边缘案例通常需要定制特性或沿袭供应商的支持。
Lineage 通常被打包为更大的目录或异常检测产品的一部分。有时,这种血统是天生可用的,并得到产品团队的支持。然而,有时它是通过外部合作伙伴来实现的,这会导致帮助和修复速度变慢。
寻找三个关键特征
- 沿袭能力是本地支持的还是外部提供的。
- 产品团队是否直接控制谱系开发。
- 明确支持 SLA 和工程依赖矩阵(如果存在外部依赖)。
5.它如何适应现代数据堆栈的变化?
数据转换工具和过程总是在不断发展。即使客户从旧的堆栈转换到最新的数据工具,沿袭也应该始终保持可靠。
如果源系统发生变化,将沿袭从数据源(例如,从转换过程中)拉得更远会导致问题。从尽可能靠近源头的地方提取血统通常更安全,也更经得起未来的考验。
寻找从源系统的查询历史中提取的血统(例如,从 雪花 ) 而不是与下游转换工具或过程集成。
6.它是否具有云原生的灵活性来扩展 SQL 解析需求?
在沿袭中,很容易出现大规模 SQL 解析需求。(我们亲眼见过每天有超过 100 万次查询的客户。)解析这些查询需要大量的计算资源,所以你的血统能跟上很重要。
云原生产品使用网飞等公司发明的最新设计模式和微服务,实现无限的可扩展性。当心那些不是为云构建的或者有遗留技术债务的平台——它们很难维护,随着你的血统扩展,会导致性能问题。
寻找支持大规模 SQL 解析的现代云原生架构。
7.它提供向下到列级别的沿袭吗?
表级沿袭被认为是“表桩”,但列级沿袭也应该如此。这对一系列使用情形至关重要:
- 追踪转换后的 PII 数据的敏感数据分类
- 模式变更等因素的影响分析
- 根本原因分析——例如,通过跟踪 BI 字段到数据仓库中的上游列来调查为什么仪表板看起来不正常
如果不能深入到粒度列或字段谱系中,数据工程师和分析师可能会在调查过程中错过关键深度。
寻找两个关键特征:
- UI 中的原生列级体验,包括在列级查看图形链接。
- 支持
**MERGE**
、**INSERT INTO**
、**UPDATE**
、 SQL 语句,这些语句是列级转换的关键。
8.它是否自动将上游 SQL 源与下游 BI 资产连接起来?
通常,沿袭的目标是识别为什么最后一英里的某些东西看起来不对劲。作为公司数据的管理者,数据工程团队负责确保提供给最终用户资产的数据是可信和可靠的。当这个失败时,血统是一个重要的诊断工具。
并不是所有血统都会天生连接到你选择的 BI 工具(例如 Looker 、 Tableau 、 Power BI 等)。有些依赖耗时的手动脚本和资产推送,即使对于主要的 BI 工具也是如此。
寻找能够自动连接到您选择的 BI 工具的本机连接器或自动化脚本。
9.它是否支持 BI 仪表板的字段级沿袭?
任何进行根本原因分析的人都需要深入到一个不正确的字段(即维度、度量、计算字段等。)中,并向后工作以集中在上游字段或损坏的列上。这仅适用于 BI 工具的字段级沿袭。
字段级沿袭对于影响分析也很重要。如果数据工程师试图进行模式更改,他们需要了解将受到影响的特定下游列和字段,而不仅仅是哪些仪表板将以某种未指明的方式受到影响。
一些平台支持一些字段的沿袭,但是没有深入到对这些类型的分析至关重要的 BI 字段。
寻找两个关键特征:
- 涵盖 SQL 源的列级沿袭和 BI 字段级沿袭。
- 您的 BI 工具的对象是否在沿袭中被支持和公开。(例如在 Looker 中,lineage 是否会覆盖所有你关心的字段/对象,比如仪表盘、外观、浏览、磁贴、字段、视图?)
10.它能否使用 Salesforce 中的数据创建上游沿袭(在对象和字段级别)?
我们经常听说 Salesforce 是“狂野西部”,没有人知道 ETL 管道中的数据发生了什么。然而,开放 Salesforce(和其他关键的 SaaS 源系统)可以改变游戏规则,帮助数据和业务团队进行协作。影响分析是这里的一个主要用例,因为 Salesforce 字段一直在变化,并对下游造成严重破坏。
如果可能,确保调查 Salesforce 血统的深度。一些沿袭始于存储层(即数据仓库、湖等)。能否在存储层上游为 Salesforce 等 SaaS 工具生成沿袭?
如果有,深入到什么程度?一些系统不能深入到 Salesforce 对象和字段级别,这对于使下游沿袭有用和理解下游数据资产的上下文至关重要。
从 Salesforce 到数据仓库层寻找对象和字段级沿袭。
11.它能与现代数据集成工具集成吗?
在数据仓库的上游建立血统是困难的。大规模地这样做,尤其是当您从多个源系统中提取数据时,会更加困难。
如果您遵循 ELT 方法,那么您的血统能够与现代数据集成工具(如 Fivetran )连接是非常重要的。这使您可以构建上游沿袭,创建真正的端到端沿袭,并显示数据在进入存储层之前发生了什么。
看看它是否能本地连接到 Fivetran 或其他现代数据集成工具。
12.它能与数据块集成并为 Spark 作业生成血统吗?
火花血统难以生成。但是,如果您使用 Databricks,这是了解您的转换并创建可用血统的关键,以帮助数据科学家、工程师和分析师处理 Databricks 中的 ML 和分析工作负载。
寻找两个关键特征:
- 它是否从数据块 Unity 目录 API (包括 Spark、Scala 和 SQL)中获取血统
- 是否支持数据块下游 BI 工具中的字段级沿袭。
13.它是否结合了其他类型的元数据来为谱系图中的资产提供额外的上下文?
孤立地看,血统只讲述了故事的一部分,因此,只提供了价值的一部分。当与关键元数据和上下文结合时,沿袭变得可操作:
- 操作元数据:资产是如何以及何时被编排的?
- 质量和异常元数据:资产处于什么状态?他们可靠吗?
- 业务/语义元数据:资产如何链接到关键业务术语或 KPI?
- 所有者和专家元数据:在故障诊断过程中,您应该与谁联系或合作?
- 社交元数据:该资产的人文背景是什么——例如关于该资产的相关闲散讨论或吉拉门票?这是机器本身会错过的。
有时候谱系图看起来是另一种孤立的视图。如果没有这些资产的其他元数据,就很难将沿袭放在上下文中。
寻找三个关键特征:
- 开放性:一个“设计开放”的可扩展平台,您可以通过 API(包括定制的连接器)从任何来源获取数据和元数据。
- 灵活性:支持来自这些来源的广泛的技术、操作、异常/质量和业务/语义元数据。
- 个性化:个性化的数据体验,每个角色都能看到适合自己的元数据,而不是淹没在所有的元数据中。
14.它不仅可以用来调查问题,还可以有计划地推动行动吗?
除了支持数据人员的工作,lineage 还可以支持自动化系统操作和工作流。
例如,如果上游表有数据质量问题,那么自动向下游 BI 仪表板添加公告就很重要。这可以防止业务用户创建“垃圾输入,垃圾输出”的分析,并节省数据分析师和工程师手动发送警报或警告的时间。
一些平台没有底层架构和可伸缩性来执行基于血统的自动化操作。
寻找开放 API、构建或定制自动化工作流的能力,以及读取元数据更改事件并触发整个谱系图中链接资产的更改的能力。
发现这个有用吗? 阅读我们的完整数据谱系电子书,获取五个额外问题和更多信息。
本博客由 Mark Pavletich(销售工程总监)和 Swaminathan Kumar(战略&情报)在Atlan共同撰写。
让你的机器学习项目成功的 14 个要求(上)
原文:https://towardsdatascience.com/14-requirements-to-make-your-machine-learning-project-a-success-part-i-80c288be503d
为成功做好准备,避免灾难
安德鲁·尼尔在 Unsplash 拍摄的照片
关于算法和新颖解决方案的文章很多,但关于如何开发一个能为你的组织/公司增加价值的机器学习项目却谈得不够。大多数情况下,项目失败不是因为“错误”算法的实现,而是因为缺乏组织支持、清晰的路线图和简单透明的工作方法。尽管这在预算紧张的初创企业中变得更加重要,但在需要联系更多参与者的大型组织中,问题的复杂性会增加。
从这个意义上说,无论你是从零开始创建一家公司,提供基于机器学习的产品/服务,还是在一家初创公司或大公司工作,对这类项目几乎没有经验,本文(分为两部分)的目的是为你提供一个清晰的画面,说明应该如何处理它们以避免浪费资源,这反过来也有助于你识别组织不良的团队和低质量的机器学习外部服务供应商,这些供应商将毁灭你的项目。
那么,机器学习有什么推荐的方法呢?出于某种原因,我们喜欢列出前 10 个步骤/规则,但在这种情况下,你只能选择 14 个。以下列表是基于我作为数据科学家和战略顾问的个人经历,以及我从真正有洞察力的领导者那里学到的宝贵东西。你可以把它看作是一个需求列表,当不满足时,很可能导致你的项目迟早失败。为了简单起见,该列表被分为两组需求,一组与管理决策相关,另一组涉及与开发过程紧密相关的技术原因:
管理要求
- 定义问题、解决问题所需的资源和可能的限制
- 寻找对手头问题有实地了解的关键人物
- 定义项目范围
- 定义成功指标(技术和业务导向)
- 设定灵活的截止日期
- 给出如何进行开发的全局描述(前面提供了适合大多数情况的通用示例)
- 寻找能够促进你的项目的内部拥护者
开发要求
- 了解数据、其来源和生成过程
- 谦卑下来,研究新的解决方案/算法
- 不要实现你无法解释的模型
- 建立基准模型,尽可能多的快速失败
- 尽可能频繁地与整个团队讨论你的决策,同时关注你的听众并优先考虑透明度
- 经历开发、测试和生产阶段
- 记录整个过程(不仅仅是代码)
在第一部分中,我们将讨论管理要求。
深度管理要求
如果你的角色不涉及管理,那也没关系,为了一个项目的成功,每个人都需要为它的秩序做出贡献,即使这不是你所期望的。特别是,当从事需要许多复杂任务的技术开发工作时,这一点变得更加重要,这些任务无法由一个人在合理的时间内熟练完成。在这方面,您最不希望出现的情况是,一些没有太多技术知识的人做出承诺,包括完成不可能的任务,或者更糟的是,在项目结束时,意识到您犯了非常严重的错误,使整个开发无效。考虑到这一点,让我们来看看在进行涉及机器学习的开发时,您应该努力满足的一些最基本的需求。
1。定义问题、解决问题所需的资源和可能的限制
信不信由你,许多项目的启动是因为有人说:让我们做一些机器学习,这听起来很酷,将有助于我们的数字化转型之路。有些人甚至会更进一步说:我不在乎我们做什么,但我们需要创新,人工智能将使我们不同于我们的竞争对手。除了这些虚构的例子,这里的要点是,机器学习永远不应该只是为了说你正在使用它或者因为它看起来很创新而实现。听起来很公平,对吧?
无论如何,第一步应该总是从定义你试图解决的问题开始,定义完成它所需的资源和可能的限制(我敢说你可能甚至不需要使用机器学习)。开始前需要回答的一些问题是:
- 我们要解决什么?相关吗?这对我们有什么好处?
- 这个问题以前在其他公司/行业解决过吗?
- 一个潜在的发展需要多长时间?
- 我们有足够的数据来做这件事吗?我们如何提取它?
- 我们有开始开发所需的基础设施吗?
- 我们有完成这个项目所需的团队吗?如果没有,我们如何建立它?
- 我们的目标是什么?
- 可以使用哪些变量?
- 是否有任何法律限制(例如,GDPR 或 CCPA)?这将如何改变我们对前面问题的回答?
值得注意的是,这一要求应与第二项要求同时满足,因为回答前面的大多数问题需要组织中具有多种观点和相关声音的关键人物。
2。找到对手头问题有实地了解的关键人物
即使你是你所从事的特定领域的专家,你也应该总是试图确定并让一群专业人士参与进来,他们将从不同的角度帮助你理解整个问题,它的复杂性和相关的细节。没有人比生活在其中的人更了解问题/业务。记住这一点,你将避免采取明显错误的方法,同时建立共识。
此外,请记住,即使你以前已经解决了这个问题,或者你已经找到了第三方开发的解决方案,一旦你考虑到属于每个公司/组织/数据库的变量的语义,它可能就不是同一个问题了。从这个意义上来说,两家公司可以拥有完全相同的数据库,因为它们共享相同的财务/人力资源平台,但每个变量的意义和相关性可能会因这些平台的使用方式而完全不同。
3。定义项目范围
你的创造力持续多久,机器学习项目就会持续多久。例如,如果您曾经在 ETL 过程中工作过,您应该知道您可能会花费大量时间来尝试新的缺失值插补方法(如果适用),检测异常值/不一致,测试新的特征/变量,甚至寻找新的数据/外部来源。
问题是你在哪里停下来?当然,你不可能永远继续下去,因为你被期望在某个时间点显示结果…你花的时间越长,你就必须等待更长时间才能看到你的投资回报。答案是定义一个项目范围,其目标是在短时间内构建一个最小可行产品(MVP ),然后在项目的未来迭代中基于它进行构建。注意:你应该清楚简洁地说明 MVP 中包含的内容,这样在项目结束时就不会有疑问了。
但是什么是可以接受的结果,你应该花多长时间去努力实现它?为了回答这个问题,我们有需求 4 和 5(可以说是最具挑战性的)。
4。定义绩效指标(面向技术和业务)
让我们解决性能指标的两个最重要的方面:意义和可接受的值。
**含义:**如果你最相关的内部利益相关者不能用简单的术语解释你如何衡量你的模型的性能,那么你就做错了,因为这表明完全缺乏范围界定、透明度和对业务需求的考虑。从这个意义上说,你应该花时间讨论和解释你将如何衡量绩效。例如,我们知道对于分类问题,准确性可能是一个很差的度量,甚至当类别严重不平衡时会产生误导。在本例中,精确度、召回率或 f1 分数可能是一些更好的备选方案,可以根据业务目标进行选择。另一个例子是用于库存管理的产品的时间序列需求预测,其中不良指定模型旨在最小化单一价值损失函数(RMSE、梅伊、MAPE、斯马普等)。)而不是使用可以为企业提供时变库存水平策略的分位数损失函数。如果需要,不要害怕构建自定义损失函数。
**可接受的值:**您可能会根据自己过去的经验提出可接受的值,但正如我们所知,这不是一个明智的决定,因为可用数据的质量(一致性和可变性)和数量会告诉我们什么是合理的/可实现的。不要成为那样的人。首先尝试你将要使用的模型的简单版本,并检查结果,这应该足以让你提出一个可接受的值。
5。设定灵活的截止日期
回答完成一个项目需要多长时间从来都不容易(除非这个项目真的很简单)。同样,即使你以前解决了这个问题,你也可能会发现自己遇到了几个常见的问题,例如:
- 质量差的数据
- 缺少数据模型(或存在混乱的数据模型)
- 较差的变量和流程文档
- 缓慢的 IT 部门需要花费大量时间来为您提供工作所需的资源(例如云服务)
- 你确定的关键角色很少或没有支持,等等
为了应对前三个问题,你能做的最好的事情是要求几天时间(不到一周)来快速检查与数据相关的问题。一旦您设法了解了数据的当前状态,您就可以提出一些灵活的截止日期,在 MVP 阶段,这些截止日期的变化不应该超过 2 周。如果您因为是外部顾问/服务提供商而无法进行第一次评估,那么您仍然可以提供一个答案…老实说,如果您有一个由 2/3 数据科学家组成的有能力的团队,对于大多数常见的建模问题,MVP 的开发不应该超过 3 个月(假设不需要数据工程任务,并且不期望您构建平台)。您可能想知道,什么是常见的建模问题?以下是一些面向业务的示例:
- 需求时间序列预测
- 客户/竞争对手细分
- 推荐系统
- 文本分类
- 情感和主题分析(实现起来最简单也最快)
- 生存分析模型(客户/员工流失/流失)
- 需求的价格弹性(做对了,不是简单的回归和理论分布)
- 供应链优化(可能是唯一需要更多时间来解决的问题,但前提是这是你第一次做这个工作)
对于与后两个问题类似的问题,即涉及他人主动性的延迟,要清楚预期的响应时间以及其不符合性将如何影响开发时间。
6.给出一幅如何进行开发的全局图
在大多数情况下,您的项目应该遵循与下图中描述的相同的全局结构:
作者图片
您应该始终致力于首先通过遵循一些标准步骤来构建原型,这些标准步骤应该由前面需求的完成来支持:
- 定义问题和范围
- 识别和提取相关数据
- 实施过滤器(如果适用),分析缺失数据和异常值
- 从事特征工程过程
- 定义建模方法,即我们将在什么样的理论框架下工作
- 建立一个基准模型并改进它
- 检查模型的性能
- 根据要求 4,重复整个过程,直到原型足够好
通过展示此工作流程,您可以增加工作的透明度,并向参与此流程的非数据专业人士暗示问题的复杂性。这反过来将帮助您以更清晰的方式解释可能出现的延迟(特别是在数据处理步骤中)。
一旦原型阶段被清除,涉及将最终模型转移到生产的经常被忽略的步骤应该被处理。下图简要描述了这一过程。
作者图片
简而言之,您需要定义解决方案的架构(现在主要是云组件),将您的代码组织成在专用环境中运行的可执行脚本,构建管道并协调其执行,构建监控流程以跟踪模型性能的变化(小心数据漂移),正式化文档,如果可能的话,探索新的扩展并确定改进机会。
7 .。寻找能够推广你的项目的内部支持者
最后一个要求只适用于大型组织。你很快就会明白为什么。
第二个最差的模型是没有使用的模型。在通过共识进行开发和使用最新的算法时,你可能已经做得很好了,但是,如果用户没有看到你工作的价值,你还有最后一项任务要做,即让他们心甘情愿地使用它。这就是变革管理策略发挥作用的地方,因为大多数情况下,新工具的使用需要组织内的一些文化适应(规模越大越糟糕)。好消息是,如果你遵循了前两个要求,也就是说,问题的定义得到了关键参与者的讨论和支持,那么工作就完成了一半,因为高层管理人员会有额外的强制措施。在任何情况下,找到内部拥护者总是有用的,他们将促进您的项目,并在他们的团队、其他团队甚至组织的各个领域中强制使用它们(也许您开发了一个仅用于特定领域的解决方案,但稍加修改就可能对其他人有所帮助)。
结束语
总而言之,我们已经讨论了一些最关键的要求,这些要求是你在着手一个新的机器学习项目时应该考虑的。其中许多对某些人来说可能听起来显而易见,但正如我们所知,一旦你读了它,所有与管理相关的东西听起来都显而易见。至少,这篇文章应该是: a) 一个快速提醒同行们要避免的错误; b) 对外部/内部数据团队提出要求的标准。
作为最后一条建议,始终以透明度、共识和质量为目标/要求(如果可能,不要仓促行事)。我希望你在这篇短文中找到价值,并继续关注第二部分。
别忘了喜欢和订阅更多与解决真实商业问题相关的内容🙂。
让你的机器学习项目成功的 14 个要求(第二部分)
原文:https://towardsdatascience.com/14-requirements-to-make-your-machine-learning-project-a-success-part-ii-5a89600a7a16
为成功做好准备,避免灾难
安德鲁·尼尔在 Unsplash 拍摄的照片
S 有时我们会忘记,开发和实现机器学习模型来解决实际问题,至少可以说是“困难的”。因此,一个涉及 It 的项目的成功不是偶然发生的也就不足为奇了。有些人甚至会说没有办法保证,但我可以向你保证,我们总是可以采取一些措施来增加我们成功的几率。
在这方面,在本文的第一部分中,我们提出了在处理机器学习项目时需要解决的最相关的管理和开发需求,以避免不良结果。为此,提供了两组要求,并对第一组要求进行了详细解释。现在是时候复习第二套了。作为一个快速提醒,这里有一些需求,如果不能满足,可能会大大降低您的项目成功的可能性:
管理要求
- 定义问题、解决问题所需的资源和可能的限制
- 寻找对手头问题有实地了解的关键人物
- 定义项目范围
- 定义成功指标(技术和业务导向)
- 设定灵活的截止日期
- 给出一幅如何进行开发的全局图
- 寻找能够促进你的项目的内部拥护者
开发要求
- 了解数据、其来源和生成过程
- 谦卑下来,研究新的解决方案/算法
- 不要实现你无法解释的模型
- 建立基准模型,尽可能多的快速失败
- 尽可能频繁地与整个团队讨论你的决策,同时关注你的听众并优先考虑透明度
- 经历开发、测试和生产阶段
- 记录整个过程(不仅仅是代码)
让我们回顾一下开发需求。
深度开发需求
我们已经讨论了与管理决策和行动相关的需求,这些需求将增加您交付成功项目的机会,但是不要忘记,没有一些技术指令,您仍然如履薄冰。
现在我们有一个新问题要回答:从技术角度来看,有没有什么防弹的方法来处理机器学习的开发?不尽然,但至少我们可以指出一些你应该尝试印入工作方法的基本价值观:顺序(经过验证的小步骤、时间和文档生成)责任(任务所有权和未能满足要求的高级责任)和透明(诚实、清晰和频繁的沟通)。我们如何确保我们正在做这件事?满足以下一组要求将是一个很好的起点。
1。了解数据、其来源和生成过程
在完全理解所使用的数据之前,永远不要构建模型。以下是一些问题,应该可以帮助您做好开始开发的准备:
- 数据来自交易系统吗?刮刀?表格/调查?ERP 系统?
- 我们生成/更新信息的频率是多少?
- 这些信息是否被用于其他目的?如果是这样,是为了什么?
- 我们是否遵循任何数据治理结构?
- 我们可以按原样使用数据吗?或者出于隐私要求,我们需要对数据进行加密吗?
- 这些数据源是稳定的,还是在未来的可持续性方面存在某种程度的不确定性?
一旦你完成了这些问题,你将准备评估是否需要总结所有的数据源(内部和外部),记录现有的变量,生成一个数据模型(实体关系图),并创建一个数据契约,以确保你的数据库在未来不会被更改或删除。如果您开始的场景中有数据,但没有关于其使用的文档或协议,您将不得不系好安全带,向参与项目的每个人宣布没有正式的数据模型,并致力于本段开始时提出的所有要点。还有,别忘了更改你的截止日期…
当然,您可以忽略一切,继续开始构建模型。虽然很常见,但这并不可取,因为您可能会因为对数据的不正确解释而犯下更多不必要的错误,甚至更糟的是,发现您的模型由于您的数据库由于某种合理或不合理的原因而消失了(关键是,您没有做任何事情来防止这种情况发生)。
2。谦卑下来,研究新的解决方案/算法
无论你在机器学习领域拥有 1 年、5 年、10 年还是+15 年的工作经验,你都应该通过研究当前的解决方案和最新的学术出版物来启动一个项目。可能会有更高效、更精确、成本更低的解决方案。此外,随着技术进步的速度,你在学士、硕士甚至前一年学到的新方法,可能在你读这篇文章的时候已经完全过时了。不要误解我的意思,它们仍然可以工作,但是我们都不应该接受向内部/外部客户提供不合格的解决方案。
作为一个建议,我建议你总是做一个相关文献和当前代码实现的简要总结,作为开发阶段的第一个任务(这对需求 3 和 7 会很有用)。不要忘记,最终目标应该始终是以更低的成本增加更多的价值(更复杂可能不是答案)。
最后,作为一个友好的警告,请记住,即使是高级数据科学家也无法满足这一要求,因此快速提醒当然很重要。
3。不要实现你无法解释的模型
这似乎是显而易见的,但随着 AutoML 的激增和新模型的快速出现,人们在不了解他们在做什么的情况下运行模型的场景已经设置好了。
例如,丢失值的处理是最关键的步骤之一,因为它可能会在模型结果中引起潜在的偏差。在某些情况下,由于某种特殊的原因,填充值是完全错误的,这种原因解释了为什么我们首先会丢失值(不是随机丢失)。尽管如此,还是有一些模型声称他们可以解决这些问题。注意:一个模型通过使用一些自动插补方法来处理缺失值的事实并不意味着它是正确的…它只是意味着代码将运行,您将得到一个结果。
另一方面,我们可能会不知不觉地使用变量的组合,这可能会在一些模型中产生潜在的目标泄漏问题,这些模型没有准备好处理给定的架构。关键是,并不是所有的模型都可以在相同的输入下正确工作,代码运行的事实并不意味着你在做正确的事情。
最后,即使支持一个模型的论文说它做了一些事情,你也应该总是检查你正在使用的实现是否做了它应该做的事情(在开源时代,你可能会惊讶地发现有时它并没有做)。
4。建立基准模型,尽可能多地快速失败
矛盾的是,成功的关键是迅速失败。在展示初步结果之前,不要花太多时间构建最佳模型。您总是可以进行另一次迭代来改进基准模型。
正如第一部分中所暗示的,时间和金钱资源不是无限的,所以你最好尽可能多地快速失败。这将允许您的组织/客户:
- 确定稍后要改进的基准模型
- 加快项目进度
- 削减开支
- 更精确地了解利用现有数据可以实现的目标
- 停止一个没有前途的项目的进一步发展
- 在做出最终决定之前,尝试更多的选择
- 在更短的时间内获得更好的开发
5。尽可能频繁地与整个团队讨论你的决定,同时关注你的听众并优先考虑透明度
沟通技巧会让你走得更远。你可能犯的最严重的错误之一是不去询问关于你的设计决策的第二种意见(对技术和非技术专业人士)。你可能认为你什么都懂,也许你确实是这样,但要一直保持敏锐几乎是不可能的。所以,问许多问题,即使是愚蠢的问题也可能最终一点也不愚蠢。
利用与你试图解决的问题一起生活的人的知识,他们将帮助你找到可能使你的项目陷入深渊的例外和关键细节。除了避免简单的错误之外,您还将让您的解决方案的潜在用户参与进来。这将使知识传授会议顺利进行,并有助于采用正在开发的新工具。另外,通过优先考虑透明度,你会增加对你工作的信任。
在这里,关注你的听众是很重要的,这样你的信息就可以被理解。另外,一个好的建议是经常这样做(至少一周一次),这样你就不会让错误或误解越积越多。
另外,记住这也适用于你的代码。让你的团队成员评审你的代码将帮助你提高你的技能,同时发现潜在的错误和改进的机会。
6。经历开发、测试和生产阶段
开发阶段的存在是有原因的:秩序和风险缓解。如第一部分所述,第二差的型号是不使用的型号。如果你在模型开发上花费了资源,你会期望它被业务使用(这是工作中最令人满意的方面之一),为了实现这一点,你首先需要确定它已经准备好了,也就是说,模型已经与生成输入数据并使结果可供最终用户使用的管道一起进行了充分的测试。
尽管这是显而易见的,但事实是许多项目仍然在不可访问的笔记本中,不准备供非技术用户使用,在某些情况下甚至不是技术用户。将代码正式化为准备包含在管道中的脚本可能会很麻烦和无聊,但是您应该认为这是必须的。作为一个快速提示,我建议通过以下方式以有组织的方式进行开发:
- 让您的导入和函数在特定的“utils.py”脚本中得到注释和解释,并导入到您的实验笔记本中
- 利用使用笔记本的一个主要好处:降价和单元订购。使用 markdown 添加章节(简介和目标、数据提取、数据处理、缺失值插补、特征工程等。)用数字和详尽的解释说明你在做什么。最后,如果你像我一样,你可能经常会发现,你可以以一种更有效或更少冗余的方式对一些转换/步骤进行排序,这就是有意识的细胞排序派上用场的地方(但是,不要忘记检查你是否已经做出了必要的更改,以便代码在重新排列后能够按预期工作)。
- 生成需求文件(我更喜欢使用 yaml,因为它很清晰),包含在固定条件下在笔记本中运行代码所需的包和版本
- 与最终用户讨论所需结果的结构
如果您遵循了这些步骤,那么将开发转移到生产的过程应该会容易得多。
最后,如果项目的某个迭代不包括模型在生产中的部署,你应该清楚这一点,因为管理期望对于避免误解至关重要。
7。记录整个过程(不仅仅是代码)
经常被忽视的是,文档是开发最有价值的结果。为什么?文献和历史书的目的是一样的,帮助我们避免过去的错误,理解我们的决定,并给我们的后人留下教训。
如果你不想花太多时间写一个正式的项目文档,一个很好的选择是使用吉拉或其他项目管理工具。然而,我仍然相信,除了使用这样的工具之外,一个模仿具有以下元素的论文的正式文档,尽管不是强制性的,总是很好的:
- 参与开发的人员名单
- 解释目标的摘要
- 关于项目、范围、成员和步骤的介绍
- 当前相关方法和实现的概述
- 对要使用的变量和数据模型的分析
- ETL 的细节(为什么我们做了一些决定而不是其他的?这是谁的主意?)
- 模型(为什么我们使用模型 A 而不是模型 B?它是如何工作的?)
- 结果呢
- 结论和可能的扩展
请注意,如果您遵循了第一部分中所示的路线图,您已经具备了坐下来撰写此报告所需的一切。我知道这可能令人厌倦,但是如果开发人员没有留下任何文档就离开了公司,无论何时出现任何问题或疑问,您都无法在短时间内提供解决方案。嗯,即使他们没有离开公司,我们仍然有一个问题,因为我们往往会忘记一个月前的细节或决定(这里是乐观的),所以文档是必不可少的,你知道这个想法。
结束语
在这篇文章的第一部分和第二部分中,我们讨论了 14 个需要考虑的最关键的需求,以避免机器学习项目中的灾难。鉴于我们职业的多任务性质,管理和发展要求都是为了提供一个更丰富和更全球化的视角(一个经常被忽视的视角)。
希望这将有助于揭示这类项目的复杂性,并增加对机器学习项目管理和开发标准的讨论。
别忘了喜欢和订阅更多与解决真实商业问题相关的内容🙂。
优化 BigQuery SQL 性能的 14 个最佳实践
原文:https://towardsdatascience.com/14-ways-to-optimize-bigquery-sql-for-ferrari-speed-at-honda-cost-632ec705979
让你的查询跑得像法拉利一样快,但像本田一样便宜。
数据管道类似于管道——我们需要在它破裂之前修复漏洞。图片来自 Pixabay 的精灵月舞。
P 优化不当的 SQL 查询就像管道内壁上的裂缝——几乎不能保持水分。当水压较低时,会有轻微的漏水,但一切仍然正常。当我们加大负荷时,噩梦就开始了。曾经可以忽略不计的裂缝现在突然大开,我们开始消耗资源,直到基础设施的完整性崩溃。
随着大数据的激增,数据管道必须处理大量负载,成本越来越容易失控。查询不再仅仅是编写一个运行的语法。它还需要经济高效且快速。
在服务器崩溃了太多次之后,我想是时候开始问… 如何?
- 第一:限制是一个陷阱。
- #2:选择尽可能少的列。
- #3:用 EXISTS()代替 COUNT()。
- #4:使用近似聚合函数。
- #5:用 Windows 函数替换自加入。
- #6:按 INT64 列排序或联接。
- 优化你的反连接。
- 尽早并经常整理你的数据。
- #9:顺序很重要(?)
- 利用分区和/或集群。
- #11:将订单按推至查询末尾(?)
- #12:延迟资源密集型操作。
- #13:使用搜索()。
- #14:利用缓存。
注 1:这里所有的查询都是基于 BigQuery 公共数据 编写的,每个人都可以访问。换句话说,您可以将查询复制并粘贴到 BigQuery 中,自己尝试查询。
注 2:虽然我们在本文中使用的是 BigQuery,但是这里描述的大部分优化技术都是通用的 SQL 最佳实践,可以应用到其他平台,比如 Amazon Redshift、MySQL、Snowflakes 等。
#1:限制是一个陷阱。
最佳实践 :
LIMIT
提高了性能,但没有降低成本。对于数据探索,可以考虑使用 BigQuery 的(免费)表预览选项。
不得不说——
大多数 SQL 从业者曾经被LIMIT 1000
歪曲的安全错觉所欺骗。完全有理由假设,如果我们只显示 1000 行输出,数据库的负载会更少,因此成本会更低。
不幸的是,这不是真的。
在 SQL 数据库扫描全部数据后,LIMIT
子句的行限制应用于*。更糟糕的是——大多数分布式数据库(包括 BigQuery)基于数据扫描收费,但而不是输出,这就是为什么LIMIT
不能帮助节省一毛钱。*
LIMIT 子句通过减少洗牌时间来提高性能。图片由作者提供。
然而,这并不都是悲观的。由于LIMIT
对输出行设置了上限,我们需要在 BigQuery 的网络上移动更少的数据。这种字节重排的减少显著提高了查询性能。
为了进行演示,我使用了 BigQuery 公共数据存储库中的crypto_ethereum
表,其中有 1500 万行数据。
# Not OptimizedSELECT
miner
FROM
`bigquery-public-data.crypto_ethereum.blocks`-----------------------
Elapsed Time : 11s
Slot Time : 162s
Bytes Processed: 617 MB
Bytes Shuffled : 1.7 GB
Bytes Spilled : 0 B
-----------------------
让我们用LIMIT
再次尝试查询。
# Optimized (for speed only)SELECT
miner
FROM
`bigquery-public-data.crypto_ethereum.blocks`
LIMIT
1000-----------------------
Elapsed Time : 2s
Slot Time : 0.01s
Bytes Processed: 617 MB
Bytes Shuffled : 92 KB
Bytes Spilled : 0 B
-----------------------
使用LIMIT
提高了速度,但不增加成本。
- 成本:处理的字节保持不变,仍为 617 MB。
- 速度:字节混洗从 1.7 GB 下降到仅仅 92 KB,这解释了槽时间的巨大改进(从 162 秒到 0.01 秒)。
虽然使用LIMIT
总比没有好,但是如果纯粹是为了研究表格,还有更好的选择。我强烈推荐使用 BigQuery 的表预览选项。这个特性允许我们一页一页地浏览表格,一次最多 200 行,而且完全免费。
BigQuery 的表预览选项对于探索表结构非常有用。截图摘自 BigQuery 。
为了成本优化,限制使用LIMIT
。
#2:选择尽可能少的列。
**最佳实践:**避免使用
SELECT *
。只选择您需要的相关列,以避免不必要的、代价高昂的全表扫描。来源。
BigQuery 不是传统的基于行的数据库,而是一个列数据库。这种区别是有意义的,因为它读取数据的方式不同。
如果一个表有 100 列,但是我们的查询只需要 2 个特定列的数据,那么基于行的数据库将遍历每一行——每行的所有 100 列——只提取感兴趣的 2 列。相比之下,列数据库将只处理 2 个相关的列,这有助于更快的读取操作和更有效的资源利用。
基于行的数据库和基于列的数据库读取数据是不同的。图片由作者提供。
下面是一个典型的查询,写起来很快,但是运行起来很慢。
# Not OptimizedSELECT
*
FROM
`bigquery-public-data.crypto_ethereum.blocks`-----------------------
Elapsed Time : 23s
Slot Time : 31 min
Bytes Processed: 15 GB
Bytes Shuffled : 42 GB
Bytes Spilled : 0 B
-----------------------
由于列数据库可以跳过列,我们可以利用这一点,只查询我们需要的列。
# OptimizedSELECT
timestamp,
number,
transactions_root,
state_root,
receipts_root,
miner,
difficulty,
total_difficulty,
size,
extra_data,
gas_limit,
gas_used,
transaction_count,
base_fee_per_gas
FROM
`bigquery-public-data.crypto_ethereum.blocks`-----------------------
Elapsed Time : 35s
Slot Time : 12 min
Bytes Processed: 5 GB
Bytes Shuffled : 11 GB
Bytes Spilled : 0 B
-----------------------
在本例中,查询成本降低了 3 倍,因为我们需要处理的字节从 15 GB 减少到了 5 GB。除此之外,我们还观察到,随着时隙时间从 31 分钟减少到 12 分钟,性能有所提高。
这种方法的唯一缺点是我们需要输入列名,这可能很麻烦,尤其是当我们的任务需要大部分列时,除了少数几个。在这种情况下,并不是所有的都丢失了,我们可以利用EXCEPT
语句来排除不必要的列。
# OptimizedSELECT
*
EXCEPT (
`hash`,
parent_hash,
nonce,
sha3_uncles,
logs_bloom)
FROM
`bigquery-public-data.crypto_ethereum.blocks`-----------------------
Elapsed Time : 35s
Slot Time : 12 min
Bytes Processed: 5 GB
Bytes Shuffled : 11 GB
Bytes Spilled : 0 B
-----------------------
除非绝对必要,否则避免SELECT *
。
#3:使用 EXISTS()而不是 COUNT()。
最佳实践:如果我们不需要精确的计数,使用
EXISTS()
,因为一旦找到第一个匹配行,它就退出处理循环。来源。
当探索一个全新的数据集时,有时我们发现自己需要检查特定值的存在。我们有两个选择,要么用COUNT()
计算值的频率,要么检查值EXISTS()
是否。如果我们不需要知道值出现的频率,总是使用EXISTS()
来代替。
这是因为一旦找到第一个匹配行,EXISTS()
就会退出处理循环,如果找到目标值,则返回True
,如果目标值不在表中,则返回False
。
相反,COUNT()
将继续搜索整个表,以便返回目标值的准确出现次数,浪费不必要的计算资源。
一旦找到匹配项,EXISTS()子句就退出处理。图片由作者提供。
假设我们想知道值6857606
是否存在于number
列中,我们使用了COUNT()
函数…
# Not OptimizedSELECT
COUNT(number) AS count
FROM
`bigquery-public-data.crypto_ethereum.blocks`
WHERE
timestamp BETWEEN '2018-12-01' AND '2019-12-31'
AND number = 6857606-----------------------
Elapsed Time : 6s
Slot Time : 16s
Bytes Processed: 37 MB
Bytes Shuffled : 297 B
Bytes Spilled : 0 B
-----------------------
因为只有一行与值匹配,所以COUNT()
返回 1。现在,让我们用EXISTS()
来代替。
# OptimizedSELECT EXISTS (
SELECT
number
FROM
`bigquery-public-data.crypto_ethereum.blocks`
WHERE
timestamp BETWEEN "2018-12-01" AND "2019-12-31"
AND number = 6857606
)-----------------------
Elapsed Time : 0.7s
Slot Time : 0.07s
Bytes Processed: 37 MB
Bytes Shuffled : 11 B
Bytes Spilled : 0 B
-----------------------
查询返回True
,因为该值存在于表中。使用EXISTS()
函数,我们不会得到关于其频率的信息,但是作为回报,查询性能得到了极大的提高——从 16 秒减少到 0.07 秒。
难道不庆幸EXISTS()
功能的存在吗?
#4:使用近似聚合函数。
最佳实践:当你有一个大的数据集,并且你不需要精确的计数时,使用近似聚合函数。来源。
一个COUNT()
扫描整个表以确定出现的次数。因为这是逐行进行的,所以操作将以 O(n)的时空复杂度运行。对具有数亿行的大数据执行这样的操作将很快变得不可行,因为它需要大量的计算资源。
为了加剧性能问题,COUNT(DISTINCT)
将需要大量的计算机内存来记录每个用户的唯一 id。当列表超过内存容量时,多余的容量会溢出到磁盘中,导致性能急剧下降。
在数据量很大的情况下,通过使用近似聚合函数来牺牲准确性以换取性能可能对我们最有利。例如:-
[APPROX_COUNT_DISTINCT()](https://cloud.google.com/bigquery/docs/reference/standard-sql/approximate_aggregate_functions#approx_count_distinct)
[APPROX_QUANTILES()](https://cloud.google.com/bigquery/docs/reference/standard-sql/approximate_aggregate_functions#approx_quantiles)
[APPROX_TOP_COUNT()](https://cloud.google.com/bigquery/docs/reference/standard-sql/approximate_aggregate_functions#approx_top_count)
[APPROX_TOP_SUM()](https://cloud.google.com/bigquery/docs/reference/standard-sql/approximate_aggregate_functions#approx_top_sum)
[HYPERLOGLOG++](https://cloud.google.com/bigquery/docs/reference/standard-sql/hll_functions#hyperloglog_functions)
与通常的强力方法不同,近似聚合函数使用统计信息来产生近似结果,而不是精确结果。预计误差率 1~2%。因为我们没有运行全表扫描,所以近似聚合函数在内存使用和时间方面是高度可伸缩的。
近似聚合函数使用统计信息快速提供近似结果。放大镜图标来自 Flaticon 的 Freepik,经作者允许编辑。
假设我们对 220 万个块中唯一以太坊矿工的数量感兴趣,我们可以运行以下查询…
# Not OptimizedSELECT
COUNT(DISTINCT miner)
FROM
`bigquery-public-data.crypto_ethereum.blocks`
WHERE
timestamp BETWEEN '2019-01-01' AND '2020-01-01'-----------------------
Elapsed Time : 3s
Slot Time : 14s
Bytes Processed: 110 MB
Bytes Shuffled : 939 KB
Bytes Spilled : 0 B
-----------------------
COUNT(DISTINCT)
函数返回了 573 名矿工,但用了 14 名矿工。我们可以将其与APPROX_COUNT_DISTINCT()
进行比较。
# OptimizedSELECT
APPROX_COUNT_DISTINCT(miner)
FROM
`bigquery-public-data.crypto_ethereum.blocks`
WHERE
timestamp BETWEEN '2019-01-01' AND '2020-01-01'-----------------------
Elapsed Time : 2s
Slot Time : 7s
Bytes Processed: 110 MB
Bytes Shuffled : 58 KB
Bytes Spilled : 0 B
-----------------------
令我高兴的是,APPROX_COUNT_DISTINCT()
返回了 573 名矿工的正确数字(运气?)在一半的时隙时间内。即使只有 220 万行数据,性能上的差异也很明显,但我想随着表变大,这种差异会对我们有利。
每当不需要超精确计算时,请考虑使用近似聚合函数来获得更高水平的响应。
#5:用 Windows 函数替换自连接。
最佳实践:自连接总是低效的,应该只在绝对必要的时候使用。在大多数情况下,我们可以用窗口函数来代替它。来源。
自联接是指表与自身相联接。当我们需要一个表引用它自己的数据时,这是一个常见的连接操作,通常是在父子关系中。
自联接通常比 windows 函数需要更多的读取,因此速度较慢。图片由作者提供。
一个常见的用例——带有 manager_id 列的 Employee 表包含所有雇员和助理经理(也是公司的雇员)的行记录,他们也可能有自己的经理。要获得所有员工及其直接主管的列表,我们可以使用 employee_id = manager_id 执行自联接。
这通常是一种 SQL 反模式,因为它可能会使输出行数平方,或者强制进行大量不必要的读取,随着表变大,这会成倍地降低我们的查询性能。
例如,如果我们想知道每个矿工今天和昨天开采的以太坊块数之间的差异,我们可以编写一个自连接,尽管这是低效的
# Not OptimizedWITH
cte_table AS (
SELECT
DATE(timestamp) AS date,
miner,
COUNT(DISTINCT number) AS block_count
FROM
`bigquery-public-data.crypto_ethereum.blocks`
WHERE
DATE(timestamp) BETWEEN "2022-03-01"
AND "2022-03-31"
GROUP BY
1,2
)SELECT
a.miner,
a.date AS today,
a.block_count AS today_count,
b.date AS tmr,
b.block_count AS tmr_count,
b.block_count - a.block_count AS diff
FROM
cte_table a
LEFT JOIN
cte_table b
ON
DATE_ADD(a.date, INTERVAL 1 DAY) = b.date
AND a.miner = b.miner
ORDER BY
a.miner,
a.date-----------------------
Elapsed Time : 12s
Slot Time : 36s
Bytes Processed: 12 MB
Bytes Shuffled : 24 MB
Bytes Spilled : 0 B
-----------------------
与执行自连接相比,窗口功能与导航功能LEAD()
相结合将是更好的方法。
# OptimizedWITH
cte_table AS (
SELECT
DATE(timestamp) AS date,
miner,
COUNT(DISTINCT number) AS block_count
FROM
`bigquery-public-data.crypto_ethereum.blocks`
WHERE
DATE(timestamp) BETWEEN "2022-03-01" AND "2022-03-31"
GROUP BY
1,2
)SELECT
miner,
date AS today,
block_count AS today_count,
LEAD(date, 1) OVER (PARTITION BY miner ORDER BY date) AS tmr,
LEAD(block_count, 1) OVER (PARTITION BY miner ORDER BY date) AS tmr_count,
LEAD(block_count, 1) OVER (PARTITION BY miner ORDER BY date) - block_count AS diff
FROM
cte_table a-----------------------
Elapsed Time : 3s
Slot Time : 14s
Bytes Processed: 12 MB
Bytes Shuffled : 12 MB
Bytes Spilled : 0 B
-----------------------
这两个查询给出了相同的结果,但是使用后一种方法在查询速度上有了显著的提高(从 36 秒的时间段减少到 14 秒的时间段)。
除了LEAD()
函数之外,还有很多其他的导航、编号和聚合分析函数可以用来代替自连接操作。就我个人而言,这些是我在日常工作中经常使用的功能
- 导航功能:
LEAD()
,LAG()
- 编号功能:
RANK()
,ROW_NUMBER()
- 聚合分析函数:
SUM()
、AVG()
、MAX()
、MIN()
、COUNT()
下一次你看到自加入时,提醒自己它们只是机会之窗,让你灵活掌握窗口功能。
#6:在 INT64 列上的 ORDER BY 或 JOIN。
最佳实践:当您的用例支持时,总是优先比较
INT64
,因为评估INT64
数据类型比评估字符串更便宜。来源。
连接操作通过比较它们的连接键将一个表映射到另一个表。如果连接键属于某些难以比较的数据类型,那么查询就会变得缓慢而昂贵。
我们的计算机比较整数比字符串快。图片由作者提供。
问题是,哪些数据类型很难比较,为什么?
一个原因是存储大小的不同。在我们的数据库中,每种数据类型都被分配了特定的存储空间块。确切的存储空间列在 BigQuery 的定价页面上。
文档告诉我们,对于 BigQuery,INT64
将总是占用 8 个字节的空间,不管它的长度如何,但是STRING
可以根据它的长度占用不同的空间。这里我们有点过于简化了,但是我们姑且说STRING
一般占用 2 + 4 * number_of_characters 字节的存储,或者换句话说,比INT64
多很多。
在计算机内存中,整数比字符串占用更少的存储空间。图片由作者提供。
不需要数据科学家就能明白,扫描的字节越少,查询运行得越快。所以在存储大小部门,整数比字符串快。
除此之外,INT64
比STRING
还有一个巨大的优势,那就是排序。排序规则告诉我们的数据库如何对字符串进行排序和比较。例如,当我们运行 ORDER BY 子句时,排序规则决定了大写和小写是否应该被视为相同。它还关注重音、日语假名字符类型、区分宽度和区分变体选择器。
所有这些排序规则都增加了STRING
比较的复杂性,这实际上降低了菠萝在查询中的速度。另一方面,我们并不关心所有这些,因为我们唯一能做的比较就是它们是比其他数字小还是大。
那么,加入STRING
到底有多糟糕?
我看到了 Borna Almasi 的一篇精彩的文章,他比较了列类型对连接速度的影响。他的实验发现,整数比字节快 1.2 倍,比字符串快约 1.4 倍。
然而,一些比较的字符长度更短/更长,这可能导致读取的字节更少/更多,因此速度不同。出于好奇,我决定使用一种类似的方法,但是比较每个正好 10 个字符的字符串和整数。
WITH
keys AS (
SELECT
*
FROM
UNNEST(GENERATE_ARRAY(1000000000,1001000000)) AS key
),
keys_hashed AS (
SELECT
key AS key_int,
CAST(key AS STRING) AS key_str,
CAST(CAST(key AS STRING) AS BYTES) AS key_byte
FROM
keys
)SELECT
*
FROM
keys_hashed a
LEFT JOIN
keys_hashed b
ON a.key_int = b.key_int
-- Change to key_str/key_byte for other experiments
在实验中,我对每种数据类型运行了 10 次查询,并基于 T 统计量计算了误差幅度。以下是调查结果。
耗时只是连接阶段的持续时间,而不是整个查询的持续时间。相对持续时间越长,意味着性能越慢。图片由作者提供。
虽然我们的样本数据数量非常有限,但看起来对INT64
应用连接操作比BYTE
产生的性能更好,其次是STRING
,提高了 39%以上。
下次你用 DDL 创建一个表时,我建议优先考虑INT64
。这是一个简单的策略,但是如果我们考虑未来对这个表的所有查询所获得的性能收益,它会带来巨大的好处。
#7:优化你的反连接。
**最佳实践:**而不是
NOT IN
,使用NOT EXISTS
操作符来编写反连接,因为它会触发一个更加资源友好的查询执行计划。来源。
大多数 SQL 从业者都熟悉JOIN
操作符,但是很少有人知道反连接。这并不是说它复杂或高级,而是我们很少关心命名约定。事实上,您自己可能也在不知不觉中编写了几个反联接运算符。
从字面上看,“反连接”是一个带有 exclusion 子句(WHERE NOT IN
、WHERE NOT EXISTS
等)的JOIN
操作符,如果它在第二个表中有匹配项,就删除这些行。
例如,如果我们想知道“汽车”表中的哪些汽车没有发生事故,我们可以从“汽车”表中查询汽车列表,然后过滤掉那些出现在“事故”表中的汽车。
反连接返回存在于一个表中而不存在于另一个表中的结果。图片由作者提供。
为了更好地理解这一点,这里还有一个例子可以在 BigQuery 上尝试。假设我们已经跟踪所有以太坊矿工的名字超过 2 年,并且我们将数据存储在两个单独的表中(2019 年和 2020 年)。我们在这里的目标是找出哪些 2019 年的矿工在 2020 年停止采矿。
WITH
miner2019 AS (
SELECT DISTINCT
miner
FROM
`bigquery-public-data.crypto_ethereum.blocks`
WHERE
DATE(timestamp) BETWEEN '2019-01-01' AND '2019-12-31'
),
miner2020 AS (
SELECT DISTINCT
miner
FROM
`bigquery-public-data.crypto_ethereum.blocks`
WHERE
DATE(timestamp) BETWEEN '2020-01-01' AND '2020-12-31'
)
如果我们拿出 2019 年矿工的名单,然后如果他们的名字出现在 2020 年的名单中,就把他们的名字去掉,那么我们应该会得到一份停止采矿的矿工名单。这是可以应用反连接的许多场景之一。不管是好是坏,我们有很多方法可以编写反联接子句。
LEFT JOIN
方法NOT EXISTS
方法NOT IN
法EXCEPT DISTINCT
方法
语法如下:-
# LEFT JOIN METHOD
SELECT
a.miner
FROM
miner2019 a
LEFT JOIN
miner2020 b ON a.miner = b.miner
WHERE
b.miner IS NULL # NOT EXISTS METHOD
SELECT
a.miner
FROM
miner2019 a
WHERE NOT EXISTS
(SELECT b.miner FROM miner2020 b WHERE a.miner = b.miner) # NOT IN METHOD
SELECT
a.miner
FROM
miner2019 a
WHERE
a.miner NOT IN
(SELECT miner FROM miner2020) # EXCEPT DISTINCT METHOD
SELECT
a.miner
FROM
miner2019 a
EXCEPT DISTINCT
SELECT
b.miner
FROM
miner2020 b
所有这些方法都将返回相同的结果(大约 491 个矿工),因为底层逻辑是相同的。这两种方法之间的唯一区别是它们触发不同的查询计划——一些比另一些更有效。以科学的名义,我在禁用缓存的情况下对每个方法运行了 5 次,并记录了查询性能。这是我的发现
反连接的不同写作风格比较。图片由作者提供。
大多数方法都有相似的性能,除了NOT IN
方法,它有几乎两倍的槽时间和字节混洗。
好吧,真糟糕。根据我的经验,NOT IN
是反连接最常用的语法,因为它可读性强,但不幸的是,它的性能也最差。
出于好奇,SQLShack 在这里花了很大力气来讨论其性能不佳的根本原因。TLDR 版本是,NOT IN
方法触发一些运行嵌套循环和计数操作的繁重操作,这显然是非常昂贵的。
这个故事的寓意?编写反连接时避开NOT IN
。就我个人而言,我推荐默认使用NOT EXIST
方法,因为它具有很高的性能,阅读起来同样直观。
#8:尽早并经常整理你的数据。
最佳实践:尽早并经常在查询中应用过滤功能,以减少数据混乱和在对最终查询结果没有贡献的无关数据上浪费计算资源。
我听起来就像一张破唱片,但伟大的建议值得重复——只要有机会,就用SELECT DISTINCT
、INNER JOIN
、WHERE
、GROUP BY
或任何其他过滤功能整理你的数据。我们做得越早,查询的每个后续阶段的负载就越小,因此每一步的性能增益都是复合的。
尽早整理无关数据可以节省下游的计算资源。图片由作者提供。
例如,如果我们想知道每个 GitHub 存储库的受欢迎程度,我们可以查看(I)浏览量和(ii)提交量。为了提取数据,我们可以JOIN
表repos
和commits
然后用GROUP BY
合计计数。
# Not OptimizedWITH
cte_repo AS (
SELECT
repo_name,
watch_count
FROM
`bigquery-public-data.github_repos.sample_repos`
),
cte_commit AS (
SELECT
repo_name,
`commit`
FROM
`bigquery-public-data.github_repos.sample_commits`
)SELECT
r.repo_name,
r.watch_count,
COUNT(c.commit) AS commit_count
FROM
cte_repo r
LEFT JOIN
cte_commit c ON r.repo_name = c.repo_name
GROUP BY
1,2-----------------------
Elapsed Time : 3s
Slot Time : 8s
Bytes Processed: 50 MB
Bytes Shuffled : 91 MB
Bytes Spilled : 0 B
-----------------------
在这个场景中,GROUP BY
子句是在最外层的查询中执行的,所以每一行提交都是先JOIN
到存储库。由于多个提交可以属于同一个存储库,这导致了一个指数级的大表,我们需要使用GROUP BY
。
为了比较,我们可以在commits
表中提前实现GROUP BY
。
# OptimizedWITH
cte_repo AS (
SELECT
repo_name,
watch_count
FROM
`bigquery-public-data.github_repos.sample_repos`
),
cte_commit AS (
SELECT
repo_name,
COUNT(`commit`) AS commit_count
FROM
`bigquery-public-data.github_repos.sample_commits`
GROUP BY
1
)SELECT
r.repo_name,
r.watch_count,
c.commit_count
FROM
cte_repo r
LEFT JOIN
cte_commit c ON r.repo_name = c.repo_name-----------------------
Elapsed Time : 2s
Slot Time : 5s
Bytes Processed: 50 MB
Bytes Shuffled : 26 MB
Bytes Spilled : 0 B
-----------------------
当我们提前 T13 时,我们看到时隙和字节混洗有了巨大的改进。这是因为所有提交都从 672,000 条记录压缩为 6 条记录,因此需要移动的数据更少。
下面是用于比较的查询计划。对于上下文,在repos
和commits
表中分别有 400,000 和 672,000 条记录。
使用 GROUP BY early 可以大大减少读取的记录和写入的记录。截图摘自 BigQuery ,由作者编辑。
尽可能随时随地整理数据。
#9:顺序很重要(?)
推测的最佳实践: BigQuery 假设用户已经在
WHERE
子句中提供了表达式的最佳顺序,并且不会尝试对表达式进行重新排序。您的WHERE
子句中的表达式应该首先排序为最具选择性的表达式。来源。
这个建议激起了我的兴趣,因为如果它是真的,它将是最简单的实现,具有巨大的优化改进潜力。Google 声称,不仅在我们的查询中(在不同的表上)尽早使用WHERE
很重要,而且在同一个表中WHERE
的顺序也很重要。
在比较子句之前先应用过滤子句是否更好?图片由作者提供。
我决定亲自测试一下。
# "Supposedly" Not OptimizedSELECT
miner
FROM
`bigquery-public-data.crypto_ethereum.blocks`
WHERE
miner LIKE '%a%'
AND miner LIKE '%b%'
AND miner = '0xc3348b43d3881151224b490e4aa39e03d2b1cdea'-----------------------
Elapsed Time : 7s
Slot Time : 85s
Bytes Processed: 615 MB
Bytes Shuffled : 986 KB
Bytes Spilled : 0 B
-----------------------
在我们使用的三个WHERE
子句中,LIKE
操作符是运行成本很高的字符串比较操作,而=
操作符选择了一个非常具体的挖掘器,这大大减少了相关行的数量。
在理想状态下,=
操作符将在其他两个操作符之前执行,因此昂贵的LIKE
操作将只在剩余行的子集上执行。
如果WHERE
do 的顺序很重要,那么上述查询的性能无疑会比以=
操作符为第一操作符的类似查询差。
# "Supposedly" OptimizedSELECT
miner
FROM
`bigquery-public-data.crypto_ethereum.blocks`
WHERE
miner = '0xc3348b43d3881151224b490e4aa39e03d2b1cdea'
AND miner LIKE '%a%'
AND miner LIKE '%b%'-----------------------
Elapsed Time : 8s
Slot Time : 92s
Bytes Processed: 615 MB
Bytes Shuffled : 986 KB
Bytes Spilled : 0 B
-----------------------
但是看起来,两个查询的槽时间和字节数是相当的,这表明 BigQuery 的 SQL 优化器足够聪明,可以运行最具选择性的WHERE
子句,而不管我们如何编写查询。这也得到了大多数 StackOverflow 答案的支持,比如这里的、这里的和这里的。
从我收集的信息来看,我们的WHERE
子句的顺序在大多数时候并不重要,除非在极端的极端情况下,如来自 StackOverflow 的“注册用户”(是的,那是他的用户名)所指出的。
- 如果查询中有大量的表(10 个或更多)。
- 如果你的
WHERE
子句中有几个EXISTS
、IN
、NOT EXISTS
或NOT IN
语句 - 如果使用嵌套 CTE(公共表表达式)或大量 cte。
- 如果您的
FROM
子句中有大量子查询。
虽然这可能不会影响我们的查询性能,但我认为为了以防万一,按重要性顺序排列我们的WHERE
子句不会有什么坏处。
#10:利用分区和/或集群。
**最佳实践:**在大于 1 GB 的表上使用分区和集群来对数据进行分段和排序。对分区键或簇键应用筛选器可以显著减少数据扫描。来源。
查询一个巨大的数据集是一件痛苦的事情,因为它占用大量的资源,而且速度非常慢。为了提高可用性,将大型数据集分成多个较小数据集的数据库并不少见(例如:sales_jan2022、sales_feb2022、sales _ mar 2022……)。虽然这种方法避免了缺点,但它是以必须处理管理所有拆分表的逻辑噩梦为代价实现的。
这就把我们带到了 BigQuery 的分区表。在功能上,分区允许我们查询较大表的子集,而不必将它分成单独的较小的表。我们得到了性能,但没有缺点。
CREATE TABLE database.zoo_partitioned
PARTITION BY zoo_name AS
(SELECT *
FROM database.zoo)
分区将一个大表分解成更小的块。图片由作者提供。
当我们对一个分区表运行查询时,BigQuery 将过滤掉存储中不相关的分区,这样我们将只扫描指定的分区,而不是全表扫描。
在与分区相同的并行中,我们还可以使用集群将数据细化为更小的块。
CREATE TABLE database.zoo_clustered
CLUSTER BY animal_name AS
(SELECT *
FROM database.zoo)
“animal_name”列上的聚类表。群集键指向块,但不指向特定的行。图片由作者提供。
聚集表根据我们选择的列将数据分类成块,然后通过聚集索引跟踪数据。在查询过程中,聚集索引指向包含数据的块,因此允许 BigQuery 跳过不相关的块。扫描时跳过不相关块的过程称为块修剪。
这个概念类似于一个图书图书馆——当书架根据流派组织起来时,我们可以很容易地找到我们想要的书。
虽然一个重要的区别是它不指向确切的行,而只指向块。有趣的是,BigQuery 不一定要为聚集列中的每个不同值创建一个块。换句话说,当我们搜索特定值时,BigQuery 不会为 1000 个唯一值创建 1000 个块,并节省 99%的字节扫描。根据经验,Google 推荐至少 1 GB 的集群表,因为该算法可以将高基数数据分组到更好的块中,这最终会使集群表更有效。
最终,分区和集群都有助于减少 BigQuery 需要扫描的字节数。由于需要扫描的字节更少,查询运行起来更便宜、更快。
CREATE TABLE database.zoo_partitioned_and_clustered
PARTITION BY zoo_name
CLUSTER BY animal_name AS
(SELECT *
FROM database.zoo)
分区和集群可以一起使用,以获得更好的性能。图片由作者提供。
请注意,分区和集群不一定是互斥的。对于大型表,将两者结合使用是非常有意义的,因为它们的效果可以复合。考虑bigquery-public-data.wikipedia.pageviews_2022
,一个分区和聚集的表。
我们可以参考“Table Details”选项卡来验证表是分区的还是集群的。截图摘自 BigQuery ,由作者编辑。
通过参考 big query UI 的详细信息页面,我们可以看到该表由datehour
列划分,并由wiki
和title
列聚集。它看起来和感觉上就像一个普通的表,但是当我们过滤它的时候,真正的奇迹发生了。
# OptimizedSELECT
title
FROM
`bigquery-public-data.wikipedia.pageviews_2022`
WHERE
DATE(datehour) = '2022-01-01'
AND title = 'Kinzie_Street_railroad_bridge'-----------------------
Elapsed Time : 1s
Slot Time : 27s
Bytes Processed: 1.3 GB
Bytes Shuffled : 408 B
Bytes Spilled : 0 B
-----------------------
当我应用一个WHERE
语句来过滤它的分区datehour
时,处理的字节从 483 GB 减少到只有 4 GB。如果我在title
集群上添加另一个过滤器,它会进一步下降到 1.3 GB。我们只需支付 0.0065 美元,而不是 2.4 美元。如果这还不划算,我不知道什么才划算。
#11:将 ORDER BY 推到查询的末尾(?)
**推测的最佳实践:**仅在最外层查询或窗口子句(分析函数)中使用
ORDER BY
。来源。
ORDER BY
一直是一个资源密集型操作,因为它需要比较所有行,并按顺序组织它们。
之所以建议延迟使用ORDER BY
直到最外层的查询,是因为表在查询开始时往往会更大,因为它们还没有经过从WHERE
或GROUP BY
子句的任何修剪。表越大,需要做的比较就越多,因此性能就越慢。
此外,如果我们使用ORDER BY
纯粹是为了提高数据的可读性,那么就没有必要在早期对它们进行排序,因为数据的排序可能会在下游被扭曲。
不必要地使用 ORDER BY 会增加计算负载。图片由作者提供。
例如,下面的查询有针对cte_blocks
和cte_contracts
的ORDER BY
子句,但是它们没有实际用途,因为我们在这里没有计算任何顺序关系(前一行对下一行)。不仅如此,最外层查询中的ORDER BY
无论如何都会覆盖之前的排序。
# "Supposedly" Not OptimizedWITH
cte_blocks AS (
SELECT
*
FROM
`bigquery-public-data.crypto_ethereum.blocks`
WHERE
DATE(timestamp) BETWEEN '2021-03-01' AND '2021-03-31'
ORDER BY
1,2,3,4,5,6
),
cte_contracts AS (
SELECT
*
FROM
`bigquery-public-data.crypto_ethereum.contracts`
WHERE
DATE(block_timestamp) BETWEEN '2021-03-01' AND '2021-03-31'
ORDER BY
1,2,4,5,6,7
)SELECT
*
FROM
cte_blocks b
LEFT JOIN
cte_contracts c ON c.block_number = b.number
ORDER BY
size,
block_hash-----------------------
Elapsed Time : 14s
Slot Time : 140s
Bytes Processed: 865 MB
Bytes Shuffled : 5.8 GB
Bytes Spilled : 0 B
-----------------------
为了比较,我们从两个cte_tables
中删除了无意义的ORDER BY
子句,并再次运行查询。
# "Supposedly" OptimizedWITH
cte_blocks AS (
SELECT
*
FROM
`bigquery-public-data.crypto_ethereum.blocks`
WHERE
DATE(timestamp) BETWEEN '2021-03-01'
AND '2021-03-31'
),
cte_contracts AS (
SELECT
*
FROM
`bigquery-public-data.crypto_ethereum.contracts`
WHERE
DATE(block_timestamp) BETWEEN '2021-03-01' AND '2021-03-31'
)SELECT
*
FROM
cte_blocks b
LEFT JOIN
cte_contracts c ON c.block_number = b.number
ORDER BY
size,
block_hash-----------------------
Elapsed Time : 14s
Slot Time : 145s
Bytes Processed: 865 MB
Bytes Shuffled : 5.8 GB
Bytes Spilled : 0 B
-----------------------
根据我们到目前为止建立的逻辑,前一个查询应该运行得慢得多,因为它需要对多个列执行额外的ORDER BY
子句,但是令我惊讶的是,这两个查询在性能上的差异可以忽略不计——140 秒对 145 秒。
这有点违反直觉,但是进一步深入执行细节会发现,无论我们如何编写查询,两个查询都只运行最外层查询中的ORDER BY
。
查询计划告诉我们为查询执行的确切步骤。在这两种情况下,我只能找到两个 ORDER BY 操作符,并且它们都在最外层的查询中。截图摘自 BigQuery ,由作者编辑。
事实证明,万能的 BigQuery 的 SQL 优化器再一次足够聪明,能够找出冗余子句,并自动将它们从计算中排除。
尽管在这里包含多余的ORDER BY
子句是无害的,但是我们应该总是删除不必要的ORDER BY
子句,并尽可能地在查询中延迟它们。因为尽管 BigQuery SQL Optimizer 令人印象深刻,但其他一些遗留数据库可能不具备同样的能力。
#12:延迟资源密集型操作。
**最佳实践:**将复杂操作,如正则表达式和数学函数推到查询的末尾。来源。
扩展与延迟ORDER BY
语句相同的理念,我们希望将复杂的函数尽可能地推到查询中,以避免计算我们最终将丢弃的数据。
将资源密集型操作延迟到查询末尾可以提高性能。图片由作者提供。
这适用于任何函数,比如LOWER()
、TRIM()
、CAST()
,但是我们将重点放在正则表达式和数学函数上,比如REGEXP_SUBSTR()
和SUM()
,因为它们往往会消耗更多的资源。
为了展示影响,我将在查询的早期运行REGEXP_REPLACE()
,而不是在后期。
# Not OptimizedWITH
cte_repo AS (
SELECT
REGEXP_REPLACE(repo_name, r"(.*)", "\\1") AS repo_name
FROM
`bigquery-public-data.github_repos.sample_repos`
),
cte_commit AS (
SELECT
REGEXP_REPLACE(repo_name, r"(.*)", "\\1") AS repo_name
FROM
`bigquery-public-data.github_repos.sample_commits`
)SELECT
r.repo_name,
c.repo_name
FROM
cte_repo r
INNER JOIN
cte_commit c ON r.repo_name = c.repo_name-----------------------
Elapsed Time : 2s
Slot Time : 8s
Bytes Processed: 20 MB
Bytes Shuffled : 68 MB
Bytes Spilled : 0 B
-----------------------
随后,我们再次运行相同的查询,只是在将两个初始表连接在一起之后,我们只调用最终表中的REGEXP_REPLACE()
。
# OptimizedWITH
cte_repo AS (
SELECT
repo_name
FROM
`bigquery-public-data.github_repos.sample_repos`
),
cte_commit AS (
SELECT
repo_name
FROM
`bigquery-public-data.github_repos.sample_commits`
)SELECT
REGEXP_REPLACE(r.repo_name, r"(.*)", "\\1") AS repo_name,
REGEXP_REPLACE(c.repo_name, r"(.*)", "\\1") AS repo_name
FROM
cte_repo r
INNER JOIN
cte_commit c ON r.repo_name = c.repo_name-----------------------
Elapsed Time : 2s
Slot Time : 3s
Bytes Processed: 20 MB
Bytes Shuffled : 56 MB
Bytes Spilled : 0 B
-----------------------
就这样,槽时间从 8s 提高到 3s,而字节混洗从 68 MB 下降到 56 MB。
#13:使用搜索()。
谷歌最近发布了一个预览版的[SEARCH()](https://cloud.google.com/blog/products/data-analytics/pinpoint-unique-elements-with-bigquery-search-features)
功能,该功能将文本数据标记化,使得找到隐藏在非结构化文本和半结构化JSON
数据中的数据变得异常容易。
SEARCH()函数允许我们搜索相关的关键字,而不必了解底层的数据模式。图片由作者提供。
传统上,在处理嵌套结构时,我们需要提前理解表模式,然后在运行组合的WHERE
和REGEXP
子句来搜索特定的术语之前,用UNNEST()
适当地展平任何嵌套数据。这些都是计算密集型运算符。
# Not OptimizedSELECT
`hash`,
size,
outputs
FROM
`bigquery-public-data.crypto_bitcoin.transactions`
CROSS JOIN
UNNEST(outputs)
CROSS JOIN
UNNEST(addresses) AS outputs_address
WHERE
block_timestamp_month BETWEEN "2009-01-01" AND "2010-12-31"
AND REGEXP_CONTAINS(outputs_address, '1LzBzVqEeuQyjD2mRWHes3dgWrT9titxvq')-----------------------
Elapsed Time : 6s
Slot Time : 24s
Bytes Processed: 282 MB
Bytes Shuffled : 903 B
Bytes Spilled : 0 B
-----------------------
我们可以用一个SEARCH()
函数来简化语法,而不是让它们过于复杂。
# OptimizedSELECT
`hash`,
size,
outputs
FROM
`bigquery-public-data.crypto_bitcoin.transactions`
WHERE
block_timestamp_month BETWEEN "2009-01-01" AND "2010-12-31"
AND SEARCH(outputs, ‘`1LzBzVqEeuQyjD2mRWHes3dgWrT9titxvq`’)-----------------------
Elapsed Time : 6s
Slot Time : 24s
Bytes Processed: 87 MB
Bytes Shuffled : 903 B
Bytes Spilled : 0 B
-----------------------
我们甚至可以为该列创建一个搜索索引,以支持点查找文本搜索。
# To create the search index over existing BQ table
CREATE SEARCH INDEX my_logs_index ON my_table (my_columns);
搜索索引指向所需记录的位置。图片由作者提供。
如您所见,SEARCH()
是一种极其强大、简单且经济的点查找文本搜索方式。如果您的用例需要在非结构化数据中搜索非常具体的术语(例如:日志分析),请使用SEARCH()
进行优先排序。
#14:利用缓存。
BigQuery 为我们的查询提供了一个免费的、完全托管的缓存特性。当我们执行查询时,BigQuery 会自动将查询结果缓存到一个临时表中,该表可以保存长达 24 小时。我们可以通过编辑器 UI 上的查询设置来切换该特性。
默认情况下,缓存功能处于启用状态,但可以关闭。截图摘自 BigQuery ,由作者编辑。
当触发重复查询时,BigQuery 返回缓存的结果,而不是重新运行查询,为我们节省了额外的费用和计算时间。
缓存结果作为临时表存储长达 24 小时,以便在需要时重用。图片由作者提供。
我们可以通过在运行查询后检查“作业信息”来验证缓存的结果是否被使用。处理的字节应该显示“0 B(结果缓存)”。
使用缓存的结果是免费的。截图摘自 BigQuery ,由作者编辑。
在我们一有机会就疯狂地发出查询之前,重要的是要知道不是所有的查询都会被缓存。BigQuery 在这里概述了异常。值得注意的一些更重要的问题是
- 当查询使用非确定性函数时,例如
CURRENT_TIMESTAMP()
,它不会被缓存,因为它会根据查询的执行时间返回不同的值。 - 当查询引用的表接收到流插入时,因为对表的任何更改都会使缓存的结果无效。
- 如果使用通配符查询多个表。
结束语
虽然这不是所有优化技巧和诀窍的详尽列表,但我希望这是一个良好的开端。如果我错过了任何重要的技术,请评论,因为我打算继续添加到这个列表中,这样我们都可以有一个简单的参考点。
祝你好运,一帆风顺。
18 个非陈词滥调数据集,供初学数据科学家构建强大的投资组合
原文:https://towardsdatascience.com/18-non-clich%C3%A9-datasets-for-beginner-data-scientists-to-build-a-strong-portfolio-c59743b2a829
从微生物学到体育的独特数据集
Photo bydoukan ahin上 像素。 除特别注明外,所有图片均为作者所有。
当你不断看到人们一遍又一遍地使用相同的数据集时,你可能已经产生了一种轻微的厌恶感。
你就是忍不住——每个人都想要简单的东西。初学者使用像 Titanic、Iris 和 Ames Housing Dataset 这样的数据集,因为它们简单明了;大多数课程创建者和博客作者都使用它们,因为只需一次谷歌搜索就能找到它们(甚至可以加入书签)。
在我写的 115 篇以上的文章中,我真的不记得使用过这些陈词滥调(如果我的记忆让我失望了,并且使用了一次或多次,我道歉!).这主要归功于我花了很多时间寻找一个好的数据集,并以新颖的方式向我宝贵的观众提供内容。
今天,我决定分享一份我在帖子中使用的精选数据集的列表,作为我学习的一部分。尽情享受吧!
https://ibexorigin.medium.com/membership
获得由强大的 AI-Alpha 信号选择和总结的最佳和最新的 ML 和 AI 论文:
https://alphasignal.ai/?referrer=Bex
回归数据集
1️.钻石价格和克拉回归
这个列表中我最喜欢的是钻石数据集。它在长度上非常适合实践(+50k 个样本),并且有多个目标可以作为回归或多类分类任务进行预测:
🎯目标:“克拉”或“价格”
🔗链接: Kaggle
📦尺寸:(53940,10)
⚙Missing 值:否
📚入门笔记本
2️.鲍鱼壳的年龄
这是动物学领域的一个独特的数据集。这项任务是通过一些物理测量来预测鲍鱼壳(一种软体动物)的年龄。传统上,它们的年龄是通过切开它们的球果,给它们染色,并在显微镜下计数壳内的环数来确定的。
对动物学家来说,这可能很有趣,但对数据科学家来说,就没那么有趣了:
🎯目标:“戒指”
🔗链接:https://www.kaggle.com/rodolfomendes/abalone-dataset
📦尺寸:(4177,9)
⚙Missing 值:否
📚入门笔记本
3️.金县房屋销售
这是为那些仍然对房地产和房价回归感兴趣的人准备的数据集:
🎯目标:“价格”
🔗链接: Kaggle
📦尺寸:(21613,17)
⚙Missing 值:是
📚入门笔记本
4️.癌症死亡率
该数据集要求您使用几个人口统计变量找出人均癌症死亡率(100,000):
🎯目标:'目标 _ 死亡率'
🔗链接: 数据世界
📦尺寸:(3047,33)
⚙Missing 值:是
5️.预期寿命
一个人会活多久?这是科学界最难回答的问题之一。为了了解人类的寿命和寿命,已经开展了几项研究,世卫组织(世界卫生组织)提供的数据集就是其中之一:
🎯目标:“预期寿命。”
****🔗链接:https://www.kaggle.com/kumarajarshi/life-expectancy-who/
📦尺寸:(2938,21)
⚙Missing 值:是
📚入门笔记本
6️.汽车价格
标题说明了一切——使用里程、燃料类型、变速器和几个特定领域的功能等变量来预测汽车价格。这也是一个很好的数据集,可以锻炼你的特征工程肌肉:
🎯目标:'销售价格'
🔗链接:https://www.kaggle.com/nehalbirla/vehicle-dataset-from-cardekho?ref=hackernoon.com&select=Car+details+v3.csv
📦尺寸:(8128,12)
⚙Missing 值:是
📚入门笔记本
二元分类
7️.NBA 新秀统计
列表中的第一个二元分类数据集要求您预测一名新秀篮球运动员是否会在联盟中持续 5 年以上:
🎯目标:'目标 _ 5 年'
🔗链接:data . world
📦尺寸:(8128,12)
⚙Missing 值:是
📚入门笔记本
8️.中风预测
另一个医疗数据集要求您根据患者的病史预测患者是否会中风,该数据集具有有趣的特征:
🎯目标:“中风”
🔗链接: Kaggle
📦尺寸:(5110,11)
⚙Missing 值:是
📚入门笔记本
9️.水的可饮用性
安全饮用水是最基本的人权,也是健康的主要影响因素。使用该数据集,您应该使用几种化学特性将水体分为可饮用(可饮用)和不可饮用:**
🎯目标:“可饮用性”
🔗链接: Kaggle
📦尺寸:(3276,10)
⚙Missing 值:是
📚入门笔记本
10.智能电网稳定性
这是由 Vadim Arzamasov 创建的“电网稳定性模拟数据集”的扩充版本。它被捐赠给 UCI,并在 Kaggle 上提供。您将预测 4 节点智能电网系统的稳定性(无论它们意味着什么):
🎯目标:' stabf'
🔗链接:https://www.kaggle.com/pcbreviglieri/smart-grid-stability
📦尺寸:(60000,13)
⚙Missing 值:否
📚入门笔记本
1️1.IBM 人力资源分析和员工流失
这个由 IBM datasets 创建的虚构数据集要求您找出哪些因素会导致员工流失(他们是否会离职):
🎯目标:“减员”
🔗链接: Kaggle
📦尺寸:(1470,35)
⚙Missing 值:否
📚入门笔记本
1️2.我能吃这个蘑菇吗?
另一个独一无二的数据集是将蘑菇分为食用和有毒两类。这也提出了一个独特的挑战——所有特征都是绝对的:
🎯目标:“类”
🔗链接:https://www.kaggle.com/uciml/mushroom-classification
📦尺寸:(8124,23)
⚙Missing 值:是
📚入门笔记本
1️3️.钞票认证
尽管这个数据集的特征很少,但我还是想把它包括进来,因为这个任务真的很有趣——使用钞票的物理属性,你应该把它们分为伪造的和原始的:
🎯目标:“类”
🔗链接:https://www.kaggle.com/ritesaluja/bank-note-authentication-uci-data
📦尺寸:(1372,5)
⚙Missing 值:否
📚入门笔记本
1️4️.成人收入数据集
使用年龄、教育程度、背景、性别、婚姻状况等因素预测一个人最终收入是否会超过 50k。:
🎯目标:“收入”
🔗链接:https://www.kaggle.com/wenruliu/adult-income-dataset
📦尺寸:(48842,15)
⚙Missing 值:是
📚入门笔记本
多类分类数据集
1️5️.酵母分类
这个数据集将让你领略微生物世界。你的任务是将一种叫做酵母的真菌分类:
🎯目标:' class _ protein _ localization '
🔗链接: OpenML
📦尺寸:(1484,9)
⚙Missing 值:否
**** ****
1️6️.ka ggle TPS 2021 年 5 月
Kaggle 每月都会举办名为“表格游乐场系列”的竞赛,有初级到中级难度的任务。最重要的一点是,每个月都会使用 CTGAN 框架创建一个新的相当大的合成数据集。这是五月版的。
🎯目标:“目标”
🔗链接:https://www.kaggle.com/nehalbirla/vehicle-dataset-from-cardekho?ref=hackernoon.com&select=Car+details+v3.csv
📦尺寸:(100000,52)
⚙Missing 值:否
📚入门笔记本
**** ****
1️7️.卡格尔 TPS 2021 年 6 月
具有更多要素和样本的相似数据集:
🎯目标:“目标”
🔗链接:https://www.kaggle.com/c/tabular-playground-series-jun-2021/data?select=train.csv
📦尺寸:(200000,77)
⚙Missing 值:否
📚入门笔记本
1️8️.又是钻石
再次提及钻石数据集是因为它有三个分类特征,这些特征本身可以是多类目标:
🎯目标:“切割”、“颜色”、“清晰度”
🔗链接:https://www.kaggle.com/shivam2503/diamondshttps://www.kaggle.com/shivam2503/diamonds
📦尺寸:(53940,10)
⚙Missing 值:否
📚入门笔记本
找到一个好的、新颖的数据集很难,尤其是如果你是初学者的话。我希望我简化了这个过程,并能列出一个你可以收藏的清单。感谢阅读。
****https://ibexorigin.medium.com/membership https://ibexorigin.medium.com/subscribe
我的更多故事……
https://ibexorigin.medium.com/python-became-the-language-of-the-year-3-times-in-4-years-it-wont-be-this-year-e5c724758ef https://ibexorigin.medium.com/in-depth-guide-to-building-custom-sklearn-transformers-for-any-data-preprocessing-scenario-33450f8b35ff </10-minute-effortless-sql-tutorial-for-die-hard-pandas-lovers-a64c36733fd0> ****
用 Python 最大化聚类散点图
原文:https://towardsdatascience.com/19-examples-of-merging-plots-to-maximize-your-clustering-scatter-plot-87e8f1bb5fd2
混合搭配图,从散点图中获取更多信息
照片由马扬·布兰 在 Unsplash 上拍摄
我是超级英雄电影的超级粉丝。通常,许多超级英雄拥有非凡的能力、身体或力量。然而,有些超级英雄只是普通的家伙,比如托尼·斯塔克(又名钢铁侠)。
让他成为超级英雄的是钢铁侠的盔甲。通过装备,他可以做更多的事情,如飞行或使用单梁。
和钢铁侠一样,在数据可视化中,给一个图表添加更多的组件,可以给用户提供更多的信息。从理论上讲,每种图表都有其用图形或数字表示数据的目的。组合图表的特征可能会增强结果。
第一张图片是一个基本的散点图。第二幅图显示了将散点图与其他图合并以提取更多信息的结果。作者图片。
散点图是一个简单的图表,它使用笛卡尔坐标来显示通常两个连续变量的值。该图表通常用于显示某些聚类分析的结果,因为它可以展示数据点的位置并帮助区分每个聚类。
为了改进聚类散点图,本文将指导如何添加不同类型的图来提供更多信息。
检索数据
从导入库开始。
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns%matplotlib inline
例如,我将使用可以直接从 Seaborn 库下载的企鹅的数据集。该数据集包含三种企鹅的数据,阿德利企鹅、下巴颏企鹅和巴布亚企鹅。
获取企鹅数据集
df_pg = sns.load_dataset('penguins', cache=True, data_home=None)
df_pg.head()
使用 describe()浏览数据集
df_pg.describe()
作为一个简单的例子,我将创建一个散点图使用脚蹼和法案的长度值。如果您想使用不同的变量对或其他数据集,请随意修改下面的代码。
在上面的探索步骤中,可以注意到每个变量都有不同的范围。在绘图之前,让我们用标准缩放器缩放数值。
下面的三种颜色将用于可视化每个集群。
color_dict = {'Adelie':'#F65E5D',
'Chinstrap':'#3AB4F2',
'Gentoo':'#FFBC46'}
使聚集
本文将使用 k 均值聚类。这种无监督算法应用矢量量化将具有最近平均值(质心)的 n 个数据点划分为 k 个簇。
还有其他聚类方法,如 MeanShift、DBSCAN 等。如果你想尝试不同的算法,更多方法可以在这里找到。
使用 sklearn 应用 K 均值聚类
根据聚类结果绘制散点图。
散点图显示对数据集应用 K 均值聚类的结果。图片由作者提供。
选择要合并的图的类型
在这一节中,我将解释散点图和其他可以合并的图,以及如何创建它们。总的来说,我们将处理五个地块:
- 散点图
- KDE 图
- 赫克宾图
- 线形图
- 回归图
散点图
为了使散点图与其他图完美匹配,我们将使用 seaborn jointplot ,其中可以设置“kind”参数以获得不同的数据可视化。通过这样做,我们可以控制输出格式。此外,还有一个选项显示边缘轴上两个变量之间的关系。
让我们从创建散点图的三个版本开始,以便稍后轻松分层。前两个图没有边缘轴,一个有背景,另一个有透明背景。最后一个图是带有透明背景的边缘轴。
请考虑将结果导出到您的计算机上,以便以后导入。
用作背景或覆盖图的散点图。作者图片。
KDE 剧情
理论上,核密度估计(KDE)是一种使用核函数来估计未知概率密度函数的方法。KDE 图通过显示一维或多维的连续概率密度曲线来可视化数据。
KDE 的优点是绘制的图不那么杂乱,更容易理解,尤其是在绘制多个分布图时。但是,如果基础分布是有界的或不平滑的,它会引入失真。
像散点图一样,我们将创建三个不同的 KDE 图,供以后用作背景或覆盖图。对于具有透明背景的版本,我们将使 KDE 图填充和不填充颜色。
用作背景或覆盖图的核密度估计(KDE)图。作者图片。
赫克宾图
一个 hexbin 图是一个有用的数据可视化,它应用几个六边形来划分区域,并使用颜色渐变来表示每个六边形的数据点数量。
首先,我们需要单独创建每个聚类的 hexbin 图,并用透明背景保存每个图。最后一步是合并它们。
Image.open('hex_tr.png')
Image.open('j_hex_tr.png')
第一张图片:透明背景的 hexbin 图。第二个图像:具有透明背景和边缘轴的 hexbin 图。作者图片。
线形图
K-means 算法是一种基于质心的聚类,其中每个聚类都有自己的质心。显示质心的位置可以更深入地了解散点图。
我发现了这篇实用且有帮助的文章使用 Python 的 Matplotlib 可视化集群,它演示并推荐了将数据点与每个集群质心连接起来的方法。此外,文章还建议显示平均线,这有助于解释结果。
让我们从每个数据点到它的质心画一些线,并创建参考线来显示每个轴上的平均值。在开始绘制线条之前,我们需要获得质心值。
x_avg = df_std['flipper'].mean()
y_avg = df_std['bill_length'].mean()centroids = [list(i) for i in list(kmeans.cluster_centers_)]
centroids#output:
#[[-0.8085020383937745, -0.9582361857580423],
# [-0.37008778973321976, 0.938075318440887],
# [1.1477907585857148, 0.6665893202302959]]
画出线条
第一个图像:将数据点连接到质心和平均线的线图。第二个图像:具有边缘轴的第一个图像。作者图片。
回归图
本文的目的是最大化散点图信息。得到每个聚类的结果后,我们可以更进一步,绘制每组的线性回归线。
使用 seaborn regplot 可以很容易地将线性回归拟合到每个聚类中。
第一个图像是具有透明背景的回归图。第二个图像是具有边缘轴的第一个图像。作者图片。
合并图
有趣的部分来了!!为了方便合并步骤,我们将使用 Pillow 中的 Image 定义一个函数,Pillow 是一个处理图像的有用库。
现在一切都准备好了,让我们把所有的情节结合起来。
合并两个图
#1 散点图+ KDE 图
background = 'kde.png'
layer_list = ['scatter_tr.png']merge_plot(background, layer_list)
散点图+ KDE 图
#2 散点图+赫克斯宾图
background = 'scatter.png'
layer_list = ['hex_tr.png', 'scatter_tr.png']merge_plot(background, layer_list)
散点图+六边形图
#3 散点图+回归图
background = 'scatter.png'
layer_list = ['reg_tr.png']merge_plot(background, layer_list)
散点图+回归图
合并两个图(基于联合散点图)
#4 联合散点图+ KDE 图
background = ‘j_scatter.png’
layer_list = [‘kde_tr_fill.png’, ‘scatter_tr.png’]merge_plot(background, layer_list)
联合散点图+ KDE 图
#5 联合散点图+ hexbin 图
background = ‘j_scatter.png’
layer_list = [‘j_hex_tr.png’, ‘j_scatter_tr.png’]merge_plot(background, layer_list)
联合散点图+ hexbin 图
#6 联合散点图+回归图
background = ‘j_scatter.png’
layer_list = [‘reg_tr.png’]merge_plot(background, layer_list)
联合散点图+回归图
合并 3 幅图
#7 联合散点图+ KDE 图+赫克斯宾图
background = 'j_scatter.png'
layer_list = ['kde_tr.png','j_hex_tr.png', 'j_scatter_tr.png']merge_plot(background, layer_list)
联合散点图+ KDE 图+赫克斯宾图
#8 联合散点图+ KDE 图+回归图
background = 'j_scatter.png'
layer_list = ['kde_tr_fill.png', 'reg_tr.png']merge_plot(background, layer_list)
联合散点图+ KDE 图+回归图
#9 联合散点图+ hexbin 图+回归图
background = 'j_scatter.png'
layer_list = ['j_hex_tr.png', 'reg_tr.png', 'j_scatter_tr.png']merge_plot(background, layer_list)
联合散点图+六边形图+回归图
#10 联合散点图+赫克斯宾图+线图
background = 'j_scatter.png'
layer_list = ['j_hex_tr.png', 'line_tr.png', 'j_scatter_tr.png']merge_plot(background, layer_list)
联合散点图+六边形图+线形图
合并 4 幅图
#11 联合散点图+ KDE 图+赫克斯宾图+线图
background = 'j_scatter.png'
layer_list = ['kde_tr.png', 'j_hex_tr.png',
'line_tr.png', 'j_scatter_tr.png']
merge_plot(background, layer_list)
联合散点图+ KDE 图+赫克斯宾图+线图
#12 联合散点图+ KDE 图+赫克斯宾图+回归图
background = 'j_scatter.png'
layer_list = ['kde_tr.png', 'j_hex_tr.png',
'reg_tr.png', 'j_scatter_tr.png']
merge_plot(background, layer_list)
联合散点图+ KDE 图+赫克斯宾图+回归图
#13 联合散点图+赫克斯宾图+回归图+线图
background = 'j_scatter.png'
layer_list = ['j_hex_tr.png', 'reg_tr.png',
'line_tr.png', 'j_scatter_tr.png']
merge_plot(background, layer_list)
联合散点图+六边形图+回归图+线形图
合并 5 幅图
最后,是最后的最后组合的时候了!!
#14 联合散点图+ KDE 图+赫克斯宾图+线形图+回归图
background = 'j_scatter.png'
layer_list = ['kde_tr_fill.png', 'j_hex_tr.png', 'line_tr.png',
'reg_tr.png', 'j_scatter_tr.png']
merge_plot(background, layer_list)
瞧啊。!
联合散点图+ KDE 图+赫克斯宾图+线图+回归图
#15 联合散点图+ KDE 图+赫克斯宾图+线图(无填充颜色)+回归图
如果前面的图太密集,让我们试试没有填充颜色的 KDE 图。
background = 'j_scatter.png'
layer_list = ['kde_tr.png', 'j_hex_tr.png', 'line_tr.png',
'reg_tr.png', 'j_scatter_tr.png']
merge_plot(background, layer_list)
联合散点图+ KDE 图+赫克斯宾图+线图(无填充颜色)+回归图
在最后两个结果中可以看到,可以修改一些细节来改变输出。有多种方法可以合并这五个图并创建不同的结果。
讨论
本文旨在指导从散点图中提取更多信息的可能方法。通过将 KDE 图、赫克斯宾图、线形图和回归图这四个图合并成散点图,可以注意到更多的信息可以添加到结果中。
为了进一步改善结果,除了这里提到的图表之外,可能还有其他类型的图表可以合并到散点图中。此外,本文中解释的方法也可以应用于其他数据可视化。
最后,你可能希望我总结出哪一个是最好的或者应该避免的。我能告诉你的是,这很难决定,因为每个人会发现每种组合的用处不同。有些人可能喜欢简单的散点图,而其他人可能会发现多层图很有用。这取决于很多因素,所以我会让你决定。
如果有什么建议,欢迎随时留下评论。
感谢阅读
以下是您可能会感兴趣的关于数据可视化的其他文章:
- 8 用 Python 处理多个时序数据的可视化(链接)
- 9 用 Python 可视化显示比例或百分比,而不是饼状图(链接)
- 用 Python 实现的 9 个可视化比条形图更引人注目(链接
- 用 Python 处理超长时间序列数据的 6 个可视化技巧(链接)
参考
- 维基媒体基金会。(2022 年 7 月 27 日)。 K 均值聚类。维基百科。检索于 2022 年 9 月 19 日,来自https://en.wikipedia.org/wiki/K-means_clustering
- t .卡瓦略(2022 年 8 月 19 日)。用 Python 的 matplotlib 可视化集群。中等。检索于 2022 年 9 月 19 日,来自https://towardsdatascience . com/visualizing-clusters-with-python-matplolib-35ae 03d 87489
- Seaborn.jointplot 。seaborn . joint plot-seaborn 0 . 12 . 0 文档。检索于 2022 年 9 月 20 日,来自https://seaborn.pydata.org/generated/seaborn.jointplot.html
19 个隐藏的 Sklearn 特性你应该通过艰苦的方式来学习
原文:https://towardsdatascience.com/19-hidden-sklearn-features-you-were-supposed-to-learn-the-hard-way-5293e6ff149
但我会给你一条捷径
了解您从未见过的 19 种 Sklearn 功能,这些功能可以直接、优雅地替代您手动执行的常见操作。
乌祖诺夫·罗斯季斯拉夫在佩克斯拍摄的照片
介绍
通过看 Sklearn 的 API 参考,我已经意识到最常用的模型和函数只是库所能做的很薄的一部分。尽管有些特性非常狭隘,只用于极少数极端情况,但我发现许多估算器、转换器和效用函数是对人们手工操作的更好的修正。
因此,我决定列出最重要的几个,并简要地解释它们,这样您就可以在一篇文章中极大地扩展您的 Sklearn 工具集。尽情享受吧!
https://ibexorigin.medium.com/membership
获得由强大的 AI-Alpha 信号选择和总结的最佳和最新的 ML 和 AI 论文:
https://alphasignal.ai/?referrer=Bex
1️⃣.协方差。椭圆包络线
分布中有异常值是很常见的。许多算法处理异常值,而EllipticalEnvelope
就是一个直接内置到 Sklearn 中的例子。该算法的优势在于它在检测正态分布(高斯)特征中的异常值方面表现出色:
为了测试估计量,我们创建了一个均值为 5、标准差为 2 的正态分布。在它被训练之后,我们将一些随机数传递给它的predict
方法。对于test
中的异常值,该方法返回-1,即 20,10,13。
2️⃣.特征 _ 选择。RFECV
选择最有助于预测的特征是克服过度拟合和降低模型复杂性的必要步骤。Sklearn 提供的最健壮的算法之一是递归特征消除(RFE)。它通过使用交叉验证自动找到最重要的特性,并丢弃其余的特性。
这个估计器的一个优点是它是一个包装器——它可以在任何返回特征重要性或系数分数的 Sklearn 算法周围使用。以下是一个关于合成数据集的示例:
假数据集有 15 个特征,其中 10 个是信息性的,其余的是冗余的。我们用Ridge
回归作为估计量来拟合 5 倍 RFECV。训练结束后,可以用transform
的方法丢弃多余的特征。调用.shape
向我们展示了评估者设法丢弃了所有 5 个不必要的特性。
我已经写了一整篇关于这种算法的文章,涵盖了它如何与现实世界的数据集一起工作的基本细节:
3️⃣.合奏。树外
即使随机森林都很强大,过度适应的风险也很高。因此,Sklearn 提供了一种称为 ExtraTrees(分类器和回归器)的 RF 替代方法。
“额外”这个词并不意味着更多的树,而是更多的随机性。该算法使用另一种非常类似决策树的树。唯一的区别是,不是在构建每个树时计算分割阈值,而是为每个特征随机绘制这些阈值,并选择最佳阈值作为分割规则。这允许以偏置略微增加为代价来稍微降低方差:
如您所见,ExtraTreesRegressor 在合成数据集上的表现优于随机森林。
从官方用户指南中阅读更多关于极度随机化树木的信息。
4️⃣.估算。迭代输入器和计算器
如果您正在寻找比SimpleImputer
更强大、更先进的插补技术,Sklearn 将再次满足您的需求。impute
子包包括两个基于模型的插补算法- KNNImputer
和IterativeImputer
。
顾名思义,KNNImputer
使用 k-最近邻算法来查找缺失值的最佳替换:
更健壮的算法是IterativeImputer
。它通过将每个具有缺失值的要素建模为其他要素的函数来查找缺失值。这一过程以逐步循环的方式完成。在每一步,具有缺失值的单个特征被选择作为目标(y
),其余的被选择作为特征阵列(X
)。然后,使用回归器预测y
中的缺失值,并对每个特征继续该过程,直到max_iter
时间(迭代输入器的一个参数)。
因此,对于单个缺失值,会生成多个预测。这样做的好处是将每个缺失值视为一个随机变量,并关联随之而来的固有不确定性:
BayesianRidge 和 ExtraTree 被发现使用 IterativeImputer 执行得更好。
您可以在我的另一篇文章中了解更多关于这两种插补技术的信息:
5️⃣.线性 _ 模型。休伯回归量
离群值的存在会严重扰乱任何模型的预测。许多离群点检测算法丢弃离群点并将它们标记为缺失。虽然这有助于模型的学习功能,但它完全消除了异常值对分布的影响。
一个备选算法是HuberRegressor
。它不是完全去除异常值,而是在拟合期间减少异常值的权重。它有epsilon
超参数,控制应归类为异常值的样本数量。参数越小,对异常值的鲁棒性越强。它的 API 与任何其他线性回归相同。下面,您可以看到与贝叶斯岭回归器在一个有大量异常值的数据集上的比较:
图片由 Sklearn 用户指南提供。 许可证— BSD-3
可以看出,具有ε1.35、1.5、1.75 的 HuberRegressor 设法捕获了不受异常值影响的最佳拟合线
您可以从用户指南中了解更多关于该算法的信息。
6️⃣. tree.plot_tree
Sklearn 允许您使用plot_tree
函数绘制单个决策树的结构。对于刚开始学习基于树和集合模型的初学者来说,这个特性可能很方便:
图片由 Sklearn 用户指南提供。 许可证— BSD-3
还有其他绘制树的方法,比如 Graphviz 格式。从用户指南中了解它们。
7️⃣.线性 _ 模型。感知器
这个列表中最酷的名字是第七名——感知器。尽管它有一个花哨的名字,但它是一个简单的线性二元分类器。该算法的定义特征是它适合于大规模学习,并且默认情况下:
- 它不需要学习速度。
- 不实现正规化。
- 它只在出错时更新模型。
它相当于带有loss='perceptron', eta0=1, learning_rate="constant", penalty=None
的 SGDClassifier,但速度稍快:
8️⃣.特征 _ 选择。从模型中选择
Sklearn 中另一个基于模型的特征选择估计器是SelectFromModel
。它不像 RFECV 那样健壮,但是对于大规模数据集来说是一个很好的选择,因为它具有较低的计算成本。它也是一个包装估计器,适用于任何具有.feature_importances_
或.coef_
属性的模型:
如你所见,该算法成功地删除了所有 40 个冗余特征。
9️⃣.指标。混淆矩阵显示
混淆矩阵是分类问题的圣杯。大部分指标都来源于它,比如精度、召回率、F1、ROC AUC 等。Sklearn 允许您计算和绘制默认混淆矩阵:
作者图片
老实说,我不会说我喜欢默认的混淆矩阵。它的格式是固定的—行是真正的标签,列是预测。同样,第一行和第一列是负类,第二行和第二列是正类。有些人可能更喜欢不同格式的矩阵,可能是转置或翻转的。
例如,我喜欢将 positive 类作为第一行和第一列,以符合维基百科中给出的格式。这有助于我更好地隔离 4 个矩阵术语——TP、FP、TN、FN。幸运的是,您可以使用另一个函数ConfusionMatrixDisplay
绘制自定义矩阵:
作者图片
在把混淆矩阵cm
传给ConfusionMatrixDisplay
之前,你可以把它做成任何你想要的格式。
您可以从这篇文章中了解关于分类和混淆矩阵的所有内容:
🔟。广义线性模型
如果有其他方法可以处理其他类型的分布,那么转换目标( y )使其呈正态分布是没有意义的。
例如,Sklearn 为泊松、特威迪或伽马分布的目标变量提供了 3 种广义线性模型。PoissonRegressor
、TweedieRegressor
和GammaRegressor
可以为具有各自分布的目标生成稳健的结果,而不是期望正态分布。
除此之外,他们的 API 与其他任何 Sklearn 模型都是一样的。为了找出目标的分布是否与上述三者相匹配,您可以在具有完美分布的相同轴上绘制它们的 PDF(概率密度函数)。
例如,为了查看目标是否遵循泊松分布,使用 Seaborn 的kdeplot
绘制其 PDF,并通过在相同轴上使用np.random.poisson
从 Numpy 采样来绘制完美的泊松分布。
1️⃣1️⃣.合奏。隔离森林
由于基于树的模型和集成模型通常产生更鲁棒的结果,因此它们在异常值检测中也被证明是有效的。在 Sklearn 中,使用一个由非常随机的树组成的森林(tree.ExtraTreeRegressor
)来检测异常值。每棵树都试图通过选择单个特征并随机选择所选特征的最大值和最小值之间的分割值来隔离每个样本。
这种类型的随机划分在每棵树的根节点和终止节点之间产生明显更短的路径。
因此,当随机树的森林共同产生特定样本的较短路径长度时,它们极有可能是异常——sk learn 用户指南。
该算法正确地捕获了异常值(90)并将其标记为-1。
在用户指南中阅读更多关于该算法的信息。
1️⃣2️⃣.预处理。电力变压器
许多线性模型需要对数字要素进行一些变换,以使其呈正态分布。StandardScaler
和MinMaxScaler
对于大多数发行版来说都非常好用。但是,当数据中存在高偏斜度时,分布的核心指标,如平均值、中值、最小值和最大值,会受到影响。因此,简单的规范化和标准化对偏态分布不起作用。
相反,Sklearn 实现了PowerTransformer
,它使用对数变换将任何倾斜的特征尽可能地变成正态分布。考虑钻石数据集中的这两个要素:
作者图片
两者都严重倾斜。让我们用对数变换来解决这个问题:
作者图片
偏斜没了!您可以在此阅读有关不同类型的要素变换的更多信息:
1️⃣3️⃣.预处理。鲁棒定标器
Sklearn 中的另一个数字变换器是RobustScaler
。你可能从它的名字就能猜到它的作用——它能以一种对异常值鲁棒的方式变换特征。如果要素中存在异常值,则很难使其呈正态分布,因为它们会严重扭曲平均值和标准差。
RobustScaler
没有使用均值/标准差,而是使用中位数和 IQR(四分位间距)来衡量数据,因为这两个指标不会因为异常值而有偏差。您也可以在用户指南中了解相关信息。
1️⃣4️⃣.compose . make _ column _ transformer
在 Sklearn 中,有一个用make_pipeline
函数创建管道实例的简写。该函数只接受转换器和估算器并完成它的工作,而不是命名每一步并使代码变得不必要的长:
对于更复杂的场景,使用ColumnTransformer
,这也有同样的问题——每个预处理步骤都要命名,使得你的代码又长又不可读。幸运的是,Sklearn 提供了与make_pipeline
类似的功能:
正如您所看到的,使用make_column_transformer
要短得多,而且它负责单独命名每个转换器步骤。
1️⃣5️⃣.compose . make _ column _ 选择器
如果您注意的话,我们使用了 pandas 数据帧的select_dtypes
函数和columns
属性来隔离数字和分类列。虽然这肯定有效,但是使用 Sklearn 有一个更加灵活和优雅的解决方案。
make_column_selector
函数创建一个可以直接传递给ColumnTransformer
实例的列选择器。它的工作方式和select_dtypes
一样,而且更好。它有dtype_include
和dtype_exclude
参数来根据数据类型选择列。如果您需要一个定制的列过滤器,您可以将一个正则表达式传递给pattern
,同时将其他参数设置为None
。它是这样工作的:
不用传递列名列表,只传递一个带有相关参数的make_column_selector
实例,就大功告成了!
1️⃣6️⃣.预处理。普通编码器
初学者的一个常见错误是使用LabelEncoder
对有序分类特征进行编码。如果你已经注意到了,LabelEncoder
允许一次只转换一列,而不是像OneHotEncoder
一样同时转换。你可能会觉得 Sklearn 搞错了!
实际上,LabelEncoder
应仅用于对响应变量(y
)进行编码,如其文档中所规定。要对特性数组(X
)进行编码,您应该使用OrdinalEncoder
,它会像预期的那样工作。它将有序分类列转换为具有(0,n_categories - 1)类的要素。它在一行代码中对所有指定的列都这样做,这使得在管道中包含它成为可能。
1️⃣7️⃣. metrics.get_scorer
Sklearn 内置了 50 多个指标,在sklearn.metrics.SCORERS.keys
中可以看到它们的文字名称。在一个项目中,您可能需要使用几个指标,如果您单独使用它们的话,就需要导入它们。
直接从sklearn.metrics
导入大量指标可能会污染您的名称空间,并变得不必要的长。作为一个解决方案,您可以使用metrics.get_scorer
函数访问任何带有文本名称的指标,而无需导入它:
1️⃣8️⃣.型号 _ 选择。HalvingGrid 和 HalvingRandomSearchCV
在 Sklearn 的 0.24 版本中,我们介绍了两个实验性的超参数优化器:HalvingGridSearchCV
和HalvingRandomSearchCV
类。
不同于他们详尽的表亲 GridSearch 和 RandomizedSearch,新的类使用了一种叫做连续减半的技术。不是在所有数据上训练所有候选集,而是只给参数一个数据子集。通过在更小的数据子集上训练,表现最差的候选人被过滤掉。在每次迭代之后,训练样本以某个因子增加,并且可能的候选者的数量减少,从而导致更快的评估时间。
快了多少?在我做过的实验中,HalvingGridSearch 比常规 GridSearch 快 11 倍,HalvingRandomSearch 甚至比 HalvingGridSearch 快 10 倍。你可以从这里阅读我对连续减半的详细概述和我的实验:
</11-times-faster-hyperparameter-tuning-with-halvinggridsearch-232ed0160155>
1️⃣9️⃣. sklearn.utils
最后但同样重要的是,Sklearn 在sklearn.utils
子包下有一大堆实用程序和助手函数。Sklearn 本身使用这个模块中的函数来构建我们都使用的所有转换器和估计器。
有用的有class_weight.compute_class_weight
、estimator_html_repr
、shuffle
、check_X_y
等。您可以在自己的工作流中使用它们,使您的代码更像 Sklearn,或者在创建适合 Sklearn API 的定制转换器和估算器时,它们可能会派上用场。
摘要
尽管像 CatBoost、XGBoost、LightGBM 这样的库正在慢慢地从 Sklearn 那里抢走领先的 ML 库的头把交椅,但它仍然是现代 ML 工程师技能堆栈中非常宝贵的一部分。
一致的 API、出色的代码设计和创建健壮的 ML 工作流的能力仍然使 Sklearn 在功能和灵活性方面无与伦比。尽管我们可以用这些基础知识完成很多工作,但这篇文章表明,Sklearn 提供的东西比看上去的要多得多!
感谢阅读!
https://ibexorigin.medium.com/membership </6-grievous-sklearn-mistakes-that-give-no-error-messages-dc8748fbc37d>
可视化 PCA 的两种美丽方式
原文:https://towardsdatascience.com/2-beautiful-ways-to-visualize-pca-43d737e48ff7
加上模型调整和评估,以选择最佳数量的组件。
K8 在 Unsplash 上拍照
什么是 PCA?
主成分分析或 PCA 是一种降维技术,用于具有许多特征或维度的数据集。它使用线性代数来确定数据集最重要的特征。在识别出这些特征后,您可以仅使用最重要的特征或那些解释最大差异的特征,来训练机器学习模型,并在不牺牲准确性的情况下提高模型的计算性能。
PCA 找到具有最大方差的轴,并将这些点投影到该轴上。PCA 使用称为特征向量和特征值的线性代数概念。栈交换上有个帖子很漂亮的解释了一下。
这是一个用特征向量绘制的二维数据的快速视图。您可以看到其中一个向量是如何与方差最大的维度对齐的,而另一个向量是正交的。然后将数据投影到该轴上,减少数据量,但保持总体方差。
作者图片
最近我写了一篇关于 PCA 如何用于图像压缩的文章。这次我想通过可视化来谈谈 PCA 的一些基础知识。当我在学习 PCA 以及它作为机器学习工具箱中的一个工具有多么强大时,我遇到了两种不同的方法来可视化 PCA ,最终让它为我所用。我想我会与你分享这两种方法,并进一步展示模型如何在使用和不使用降维的情况下执行和。这两种方法是:**
- 解释方差累积图:这个简单但是强大。它会立即告诉您数据中有多少方差是由每个分量解释的,以及不同分量的组合如何构成总方差。
- 原始数据叠加的主成分:这个是我绝对喜欢的。你可以看到每一个主成分是如何带来稍微多一点的信息的,反过来,也就很难区分不同的成分。该图是解释方差累积图的完美伴侣。
你听够了吗?我们走吧!
入门指南
我们将使用的数据集是来自加州大学欧文分校机器学习知识库的葡萄酒数据集。数据集包含关于葡萄酒质量的数据。该数据集获得了知识共享署名 4.0 国际(CC BY 4.0)许可。
当然,我们将从导入所需的包和加载数据开始。
import numpy as np
import pandas as pd
import warnings
warnings.filterwarnings('ignore')
# Machine Learning
from sklearn import metrics
from sklearn.metrics import ConfusionMatrixDisplay
from sklearn.pipeline import Pipeline
from sklearn.pipeline import FeatureUnion
from sklearn.preprocessing import StandardScaler
from sklearn.decomposition import PCA
from sklearn.decomposition import IncrementalPCA
from sklearn.model_selection import GridSearchCV
from sklearn.model_selection import cross_val_score
from sklearn.model_selection import train_test_split
from sklearn.neighbors import KNeighborsClassifier
from sklearn.ensemble import RandomForestClassifier
from sklearn.linear_model import LogisticRegression
# Plotting
import seaborn as sns
import matplotlib.pyplot as plt
%matplotlib inline
df = pd.read_csv("wine.csv")
这个特殊的数据集有 13 个特征和一个名为类的目标变量,我们可以用它来进行分类。每个值都是连续的,因此我们可以直接将 PCA 应用于所有变量。通常我们会在更高维的数据集上使用 PCA,但是这个数据集将显示概念。
df.info()
[OUT]
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 178 entries, 0 to 177
Data columns (total 14 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 Class 178 non-null int64
1 Alcohol 178 non-null float64
2 Malic acid 178 non-null float64
3 Ash 178 non-null float64
4 Ash Alcalinity 178 non-null float64
5 Magnesium 178 non-null int64
6 Total phenols 178 non-null float64
7 Flavanoids 178 non-null float64
8 Nonflavanoid phenols 178 non-null float64
9 Proanthocyanins 178 non-null float64
10 Color intensity 178 non-null float64
11 Hue 178 non-null float64
12 OD280/OD315 178 non-null float64
13 Proline 178 non-null int64
dtypes: float64(11), int64(3)
memory usage: 19.6 KB
快速检查不平衡数据向我们展示了这个数据集,不像大多数数据集,是相当平衡的。在这次演示中,我们将保持原样。
df['Class'].value_counts()
2 71
1 59
3 48
Name: Class, dtype: int64
让我们创建我们的X
和y
变量,其中X
是除了类之外的每个特性,y
是类。
y = df['Class'].copy()
X = df.drop(columns=['Class']).copy().values
查找解释的差异
第一步是找到每个主成分的解释方差。我们通过首先用StandardScalar
缩放我们的数据,然后用 PCA 模型拟合缩放后的数据来计算解释方差。标准缩放器是一个简单的转换,它将数据标准化为具有0
和0
单位方差的平均值,或1
的标准偏差。
您还会注意到,主成分的总数等于数据集中特征的总数。然而,需要注意的一件重要事情是,主要组件不是数据集的列;相反,主成分分析正在构建新的特征来最好地解释数据。**
*def get_variance(X, n):
scaler = StandardScaler()
pca = PCA(n_components=n)
pca.fit(scaler.fit_transform(X))
return pca.explained_variance_ratio_.cumsum()[-1:]*
*for i in range(1,14):
print('Components:\t', i, '=\t', get_variance(X, i),
'\tCumulative Variance')*
*Components: 1 = [0.36198848] Cumulative Variance
Components: 2 = [0.55406338] Cumulative Variance
Components: 3 = [0.66529969] Cumulative Variance
Components: 4 = [0.73598999] Cumulative Variance
Components: 5 = [0.80162293] Cumulative Variance
Components: 6 = [0.85098116] Cumulative Variance
Components: 7 = [0.89336795] Cumulative Variance
Components: 8 = [0.92017544] Cumulative Variance
Components: 9 = [0.94239698] Cumulative Variance
Components: 10 = [0.96169717] Cumulative Variance
Components: 11 = [0.97906553] Cumulative Variance
Components: 12 = [0.99204785] Cumulative Variance
Components: 13 = [1.] Cumulative Variance*
此外,每个主要分量加在一起,所有分量的总和将等于1
。当您浏览累积差异列表时,您会看到第个组件是最重要的*,最后一个组件是最不重要的;换句话说,第一个成分对方差的贡献最大。随着我们包含越来越多的组件,每个组件的贡献量开始减少。让我们通过绘制累积方差来形象化这一点。*
绘制解释方差的阈值
虽然这些值的打印输出是一个良好的开端,但我们可以通过绘制这些值来改进。此外,我们将绘制一条线,代表解释的方差的95%
。虽然没有规则规定模型中需要包含多少解释方差,但95%
是一个很好的起点。稍后,我们将执行网格搜索,以找到在模型中使用的最佳组件数量。
*scaler = StandardScaler()
data_rescaled = scaler.fit_transform(X)
pca = PCA().fit(data_rescaled)
plt.rcParams["figure.figsize"] = (8,5)
fig, ax = plt.subplots()
xi = np.arange(1, 14, step=1)
y = np.cumsum(pca.explained_variance_ratio_)
plt.ylim(0.0,1.1)
plt.plot(xi, y, marker='o', linestyle='-', color='black')
plt.xlabel('Number of Components')
plt.xticks(np.arange(1, 14, step=1))
plt.ylabel('Cumulative variance (%)')
plt.title('The number of components needed to explain variance')
plt.axhline(y=0.95, color='grey', linestyle='--')
plt.text(1.1, 1, '95% cut-off threshold', color = 'black', fontsize=16)
ax.grid(axis='x')
plt.tight_layout()
plt.savefig('pcavisualize_1.png', dpi=300)
plt.show()*
作者图片
在绘制了累积解释方差后,我们可以看到曲线在6
或7
成分附近变得平缓。在我们为95%
绘制的线处,总的解释偏差大约在9
分量处。这就是解释差异可视化!让我们继续绘制实际的组件。
绘制每个组件与原始数据的对比图
下一步是可视化每个组件产生的数据,而不是解释的差异。我们将使用 PCA 模型的inverse_transform
方法,这将获取每个组件并将它们转换回原始数据规模。我们将绘制来自1-13
的整个元件范围,并用原始数据覆盖它们。
*# Function to perform PCA with n-Components
def transform_pca(X, n):
pca = PCA(n_components=n)
pca.fit(X)
X_new = pca.inverse_transform(pca.transform(X))
return X_new*
*# Plot the components
rows = 4
cols = 4
comps = 1
scaler = StandardScaler()
X_scaled = scaler.fit_transform(X)
fig, axes = plt.subplots(rows,
cols,
figsize=(12,12),
sharex=True,
sharey=True)
for row in range(rows):
for col in range(cols):
try:
X_new = transform_pca(X_scaled, comps)
ax = sns.scatterplot(x=X_scaled[:, 0],
y=X_scaled[:, 1],
ax=axes[row, col],
color='grey',
alpha=.3)
ax = sns.scatterplot(x=X_new[:, 0],
y=X_new[:, 1],
ax=axes[row, col],
color='black')
ax.set_title(f'PCA Components: {comps}');
comps += 1
except:
pass
plt.tight_layout()
plt.savefig('pcavisualize_2.png', dpi=300)*
在我们的图中,灰色数据是原始数据,黑点是主成分。仅显示一个组件*,它以一组点的形式投影在一条线上,这条线沿着原始数据中方差最大的轴。随着越来越多的组件被添加,我们可以看到数据开始与原始数据相似,即使显示的信息更少。当我们进入上限值时,数据开始与原始数据相匹配,最终,在所有 13 个分量上,它与原始数据相同。***
这是我最喜欢的视觉化 PCA 的方式!现在让我们用一个机器学习分类模型把它付诸行动。
比较主成分分析和非主成分分析分类模型
让我们对数据集运行三个分类器,应用和不应用 PCA,看看它们的性能如何。为了有趣起见,我们将只使用前两个组件(n_components=2
)来比较它们。我们将比较KNeighborsClassifier
、RandomForestClassifier
和LogisticRegression
作为我们的分类器,看看它们的表现如何。
和往常一样,我们将使用一个管道将我们的数据预处理和 PCA 合并到一个单独的步骤中。我们将使用之前使用的相同的StandardScaler
来缩放数据,然后用一定数量的组件来拟合数据。由于我们将在工作流程中多次使用该功能,因此我们将其设置为灵活的。
*def create_pipe(clf, do_pca=False, n=2):
scaler = StandardScaler()
pca = PCA(n_components=n)
if do_pca == True:
combined_features = FeatureUnion([("scaler", scaler),
("pca", pca)])
else:
combined_features = FeatureUnion([("scaler", scaler)])
pipeline = Pipeline([("features", combined_features),
("clf", clf)])
return pipeline*
接下来是循环不同的分类器并执行交叉验证。如上所述,我们将尝试三种不同的分类器,并在应用和不应用 PCA 的情况下分别测试它们。
*models = {'KNeighbors' : KNeighborsClassifier(),
'RandomForest' : RandomForestClassifier(random_state=42),
'LogisticReg' : LogisticRegression(random_state=42),
}
def run_models(with_pca):
for name, model, in models.items():
clf = model
pipeline = create_pipe(clf, do_pca = with_pca, n=2)
scores = cross_val_score(pipeline, X,
y,
scoring='accuracy',
cv=3, n_jobs=1,
error_score='raise')
print(name, ': Mean Accuracy: %.3f and Standard Deviation: \
(%.3f)' % (np.mean(scores), np.std(scores)))
print(68 * '-')
print('Without PCA')
print(68 * '-')
run_models(False)
print(68 * '-')
print('With PCA')
print(68 * '-')
run_models(True)
print(68 * '-')*
*--------------------------------------------------------------------
Without PCA
--------------------------------------------------------------------
KNeighbors : Mean Accuracy: 0.944 and Standard Deviation: (0.021)
RandomForest : Mean Accuracy: 0.961 and Standard Deviation: (0.021)
LogisticReg : Mean Accuracy: 0.972 and Standard Deviation: (0.021)
--------------------------------------------------------------------
With PCA
--------------------------------------------------------------------
KNeighbors : Mean Accuracy: 0.663 and Standard Deviation: (0.059)
RandomForest : Mean Accuracy: 0.955 and Standard Deviation: (0.021)
LogisticReg : Mean Accuracy: 0.972 and Standard Deviation: (0.028)
--------------------------------------------------------------------*
***魔法!*我们看到,在没有 PCA 的情况下,所有三个模型都表现得相当好。然而,只有前两个组件,RandomForest
的性能几乎相同,而LogisticRegression
的性能与原始组件完全相同!并不是所有的用例都是这样的,但是希望这能让我们一窥 PCA 的威力。如果你回头看看上面的图,每一个部分都重叠了,你可以看到需要的数据少了多少。
找到组件的最佳数量
对于这一部分,我们将使用train_test_split
函数将数据集分割成70/30%
个分区,然后使用GridSearch
特性找到最佳参数。我们想要验证的最关键参数是各种 PCA 组件号的性能。
正如我们从上面的散点图中看到的,当我们接近更高的数字(如9
)时,转换后的数据集看起来很像原始数据集,其中95%
是由转换后的数据集解释的变化。我们还看到只有2
组件表现良好,因此我们可以从1-13
开始测试整个范围并找到最佳设置。
*# Make training and test sets
X_train, X_test, y_train, y_test = train_test_split(X,
y,
test_size=0.3,
random_state=53)*
调整模型
接下来,我们将执行所谓的超参数调整。在利用默认参数基于交叉验证选择模型之后,我们执行网格搜索来微调模型并选择最佳参数。我们将循环三件事
查看LogisticRegression
的文档,了解更多参数信息。
*def get_params(parameters, X, y, pipeline):
grid = GridSearchCV(pipeline,
parameters,
scoring='accuracy',
n_jobs=1,
cv=3,
error_score='raise')
grid.fit(X, y)
return grid*
*clf = LogisticRegression(random_state=41)
pipeline = create_pipe(clf, do_pca=True)
param_grid = dict(features__pca__n_components = list(range(2,14)),
clf__C = [0.1, 1.0, 10, 100],
clf__solver = ['liblinear', 'saga'],
clf__penalty = ['l2', 'l1'])
grid = get_params(param_grid, X_train, y_train, pipeline)
print("Best cross-validation accuracy: {:.3f}".format(grid.best_score_))
print("Test set score: {:.3f}".format(grid.score(X_test, y_test)))
print("Best parameters: {}".format(grid.best_params_))*
*Best cross-validation accuracy: 0.976
Test set score: 0.944
Best parameters: {'clf__C': 10, 'clf__penalty': 'l1',
'clf__solver': 'liblinear', 'features__pca__n_components': 2}*
就这么简单——在执行网格搜索后,我们可以看到一些执行得最好的设置。我们可以看到最好的参数是C=10
、penalty='l1'
、solver='liblinear'
和n_components=2
。我们还可以看到,测试集得分接近最佳交叉验证得分。我们还可以看到,从0.972
到0.976
,交叉验证的准确性有所提高。
顺便提一下,这是典型的超参数调优。你不会得到巨大的改进*;它是小的、渐进的改进,最大的收获是通过特征工程和模型选择。*
模型验证
执行最终拟合,并用新参数进行测试。一个用于我们优化的组件数量(2
),另一个用于一组没有进行 PCA 的数据。我们将打印出一份分类报告并生成一个混淆矩阵来比较结果。
*def fit_and_print(pipeline):
pipeline.fit(X_train, y_train)
y_pred = pipeline.predict(X_test)
print(metrics.classification_report(y_test, y_pred, digits=3))
ConfusionMatrixDisplay.from_predictions(y_test,
y_pred,
cmap=plt.cm.Greys)
plt.tight_layout()
plt.ylabel('True Label')
plt.xlabel('Predicted Label')
plt.show;*
*clf = LogisticRegression(C=10,
penalty='l1',
solver='liblinear',
random_state=41)
pipeline = create_pipe(clf, do_pca=True, n=2)
fit_and_print(pipeline)*
*precision recall f1-score support
1 0.933 1.000 0.966 14
2 1.000 0.864 0.927 22
3 0.900 1.000 0.947 18
accuracy 0.944 54
macro avg 0.944 0.955 0.947 54
weighted avg 0.949 0.944 0.944 54*
作者图片
*clf = LogisticRegression(C=10,
penalty='l1',
solver='liblinear',
random_state=41)
pipeline = create_pipe(clf, do_pca=False)
fit_and_print(pipeline)*
*precision recall f1-score support
1 1.000 1.000 1.000 14
2 1.000 0.955 0.977 22
3 0.947 1.000 0.973 18
accuracy 0.981 54
macro avg 0.982 0.985 0.983 54
weighted avg 0.982 0.981 0.982 54*
作者图片
最后,虽然 PCA 的性能低于完整数据集,但我们可以看到,仅使用前两个组件,我们就能够非常接近。如果我们有一个更大、更高维的数据集,我们可以显著提高性能,而不会显著降低精度。
结论
PCA 是一种不可思议的工具,可以自动将数据转换为更简单的表示,而不会丢失太多信息。您可以将 PCA 应用于数据集中的连续变量,然后通过网格搜索进行优化,为您的模型和用例找到最佳数量的组件。虽然这只是一个简单的概述,但我希望这对您有用!
这篇文章的所有代码都可以在 GitHub 上找到。
如果你喜欢阅读这样的故事,并想支持我成为一名作家,考虑注册成为一名媒体会员。一个月 5 美元,让你可以无限制地访问成千上万篇文章。如果您使用 【我的链接】 注册,我会为您赚取一小笔佣金,无需额外费用。
参考
Dua,d .,& Graff,C. (2017)。UCI 机器学习知识库。加州大学欧文分校信息与计算机科学学院。http://archive.ics.uci.edu/ml
使用 Python Assert 语句时要避免的 2 个警告
原文:https://towardsdatascience.com/2-caveats-to-avoid-when-using-python-assert-statement-8060e123c26a
消除这些可能发生的无声错误
照片由Olav Ahrens rtne在 Unsplash 上拍摄
Python 中的assert
语句允许您运行内部单元测试,并提供测试条件的调试帮助。
**syntax: assert condition [, Error Message]**
如果条件为真,则什么都不会发生。否则,会引发一个带有可选错误消息的**AssertionError**
异常。
assert 语句有用的示例
假设您想根据费率计算折扣价。
为了使其正常工作,贴现率必须介于 0 和 1 之间。
为了检查可能导致折扣率高于 1 的潜在错误,我们可以添加以下断言。
如果我们对 100 美元应用 40% (0.4)的贴现率,这将产生预期的结果。
作者图片
现在,如果我们应用 120%的贴现率(!),这会导致以下异常:
作者图片
为了使异常更加明确,我们可以在assert
语句中添加一条错误消息:
再次运行前面的示例会将错误消息添加到控制台。
作者图片
如果您查看 stacktrace,您会看到解释器指出了断言条件失败的确切行。这对于调试非常有用:对于你和与你合作的其他队友。
此外,当您将错误消息添加到 assert 语句中时,这可以作为代码的文档。
陷阱 1:使用断言进行数据验证
虽然assert
语句可以帮助您调试代码并在内部进行测试,但是应该谨慎使用,不要依赖它们来验证数据或应用安全检查。
原因很简单:出于性能原因,可以在生产中禁用assert
语句。因此,如果代码的关键部分使用了它们,将会忽略对条件的检查。
让我们看看下面这个使用assert
语句检查管理员权限的例子:
如果使用-O
和—OO
命令行开关启动执行该函数的 python 程序,断言将被全局禁用。
这种特殊情况引入了安全漏洞。
→避免这个问题的正确方法是永远不要使用断言进行数据验证。相反,我们可以使用 if 条件,并在必要时引发异常。
陷阱 2:使用括号使断言永远不会失败
如果你使用了assert
语句,但对语法不太确定,你可能会像这样加上括号。
不幸的是,这导致了一个无声的错误。事实上,在写的时候:
**assert (condition, error_message)**
**assert**
语句不检查条件,如果为假则打印错误信息。它实际做的是将 **(condition, error_message)**
整个元组作为一个条件进行求值。
因为在 Python 编程语言中元组的计算结果为 True,所以该语句:
**assert (condition, error_message)**
**永远不会引发错误 si **(条件,错误消息)始终为真。
注意 ipython 解释器如何引发关于括号的语法警告异常。
作者图片
参考
- https://careerkarma.com/blog/python-assert/
- https://www . programiz . com/python-programming/assert-statement
结论
assert
用于调用函数的程序员出错的情况,与用户相反。在这种情况下使用assert
可以确保程序员在测试过程中正确使用你的函数。
请记住,assert
并不是为了防止运行时出现错误,因此不应该用于执行数据验证。
此外,不要在条件和错误消息之间使用括号,因为 Python 总是将元组求值为 True,断言永远不会失败。
新到中?你可以每月订阅 5 美元,并解锁各种主题的无限文章(技术、设计、创业……)你可以通过点击我的推荐链接来支持我
**https://ahmedbesbes.medium.com/membership
照片由卡斯滕·怀恩吉尔特在 Unsplash 上拍摄**
Python 熊猫的 2 个不同的替换函数
原文:https://towardsdatascience.com/2-different-replace-functions-of-python-pandas-c079408de031
以及何时使用哪个
文森特·范·扎林格在 Unsplash 上拍摄的照片
Pandas 是一个用于 Python 的高效数据分析和操作分析库。考虑到 Python 在数据科学中的主导地位以及大量的数据清理、操作和分析工作,Pandas 是数据科学领域中使用最广泛的工具之一。
我一直用熊猫来做我的工作和创作内容。从我第一次写熊猫代码到现在已经快 3 年了,我还在不断学习新的东西。
当然,拥有一个活跃的开源社区并不断改进是发现熊猫新技能的一个重要因素。
在这篇文章中,我们将讨论 Pandas 的一个具体部分:替换函数。我把它写成复数,因为熊猫有两个不同的替换函数。
- 熊猫。数据框架.替换
- 熊猫。Series.str.replace
我们将通过几个例子来了解这些函数是如何工作的,以及它们的用途。
让我们从创建一个示例数据帧开始。
import pandas as pd
df = pd.DataFrame(
{
"name": ["Jane", "James", "Jhn", "Matt", "Emily", "Ashley"],
"profession": ["doc", "doctor", "eng", "engineer", "eng", "accountant"],
"category": ["group-1", "group-1", "group-2", "group-3", "group-1", "group-2"],
"address": ["Houston-TX", "Dallas, TX", "Houston, TX", "Dallas, Texas", "Palo Alto, CA", "Austin, TX"]
}
)
df
df(作者图片)
数据框架.替换
此函数可用于替换一列或多列中的值。当然,我们需要指定要替换的值和新值。
例如,我们可以将专业栏中的“doc”替换为“doctor”。
df["profession"].replace(to_replace="doc", value="doctor")
# output
0 doctor
1 doctor
2 eng
3 engineer
4 eng
5 accountant
Name: profession, dtype: object
我们也可以直接将函数应用于数据帧。在这种情况下,使用 Python 字典指定列名。
df.replace(to_replace={"profession": {"doc": "doctor"}})
输出(图片由作者提供)
在前两个示例中,字符串“doc”被替换为“doctor”。“专业”列中的“工程”字符串应替换为“工程师”。
由于熊猫的灵活性,我们可以在一次操作中完成两种替换。每个替换在字典中被写成一个键值对。
df.replace(to_replace={"profession": {"doc": "doctor", "eng": "engineer"}})
输出(图片由作者提供)
“doc”和“eng”都被替换了。替换一列中的多个值还有另一种方法,即使用 Python 列表来指示要替换的值和新值。
df["profession"].replace(
to_replace=["doc", "eng"],
value=["doctor", "engineer"]
)
# output
0 doctor
1 doctor
2 engineer
3 engineer
4 engineer
5 accountant
Name: profession, dtype: object
在前两个示例中,我们替换了同一列中的多个值。我们还可以使用嵌套字典替换不同列中的多个值。
以下代码片段替换了 name 和 profession 列中的多个值。
df.replace(
{
"profession": {"doc": "doctor", "eng": "engineer"},
"name": {"Jhn": "John"}
}
)
输出(图片由作者提供)
Series.str.replace
通过 str 访问器提供的 replace 函数可用于替换字符串的一部分或子序列。
Pandas 中的访问器提供了特定于特定数据类型的功能。str 访问器用于字符串操作。
“str.replace”函数可用于替换字符串中的字符。
df["address"]
# output
0 Houston-TX
1 Dallas, TX
2 Houston, TX
3 Dallas, Texas
4 Palo Alto, CA
5 Austin, TX
Name: address, dtype: object
df["address"].str.replace("-", ", ")
# output
0 Houston, TX
1 Dallas, TX
2 Houston, TX
3 Dallas, Texas
4 Palo Alto, CA
5 Austin, TX
Name: address, dtype: object
上面第 3 行中的单词“Texas”是一个字符串的子序列,因此我们可以使用“str.replace”将其替换为“TX”。
df["address"].str.replace("Texas", "TX")
# output
0 Houston-TX
1 Dallas, TX
2 Houston, TX
3 Dallas, TX
4 Palo Alto, CA
5 Austin, TX
Name: address, dtype: object
为了做多重替换,我们可以进行如下链式操作:
df["address"].str.replace("-", ", ").str.replace("Texas", "TX")
# output
0 Houston, TX
1 Dallas, TX
2 Houston, TX
3 Dallas, TX
4 Palo Alto, CA
5 Austin, TX
Name: address, dtype: object
与“DataFrame.replace”不同,“str.replace”不能应用于 DataFrame,因为 DataFrame 对象没有 str 属性。
“str.replace”可用于替换整个字符串,但要确保要替换的字符串不是另一个值中的子字符串。我们来做一个例子来演示这个案例。这是我们的数据框架:
df(作者图片)
让我们使用“str.replace”将职业列中的“doc”替换为“doctor”。
df["profession"].str.replace("doc", "doctor")
# output
0 doctor
1 doctortor
2 eng
3 engineer
4 eng
5 accountant
Name: profession, dtype: object
第 0 行中的替换是好的,但是我们在第 1 行中有一个问题。字符串“doctor”中的“doc”子序列也被替换为“doctor ”,因此我们得到了一个字符串“docdoctor ”,这肯定不是我们想要的。
两者都有效的情况
df(作者图片)
假设我们想用整数替换 category 列中的值。我们可以使用“DataFrame.replace”和“str.replace”来完成这项任务。
df["category"].str.replace("group-", "")
# output
0 1
1 1
2 2
3 3
4 1
5 2
Name: category, dtype: object
df["category"].replace(
{"group-1": 1, "group-2": 2, "group-3": 3}
)
# output
0 1
1 1
2 2
3 3
4 1
5 2
Name: category, dtype: int64
除了数据类型之外,输出是相同的。当使用“str.replace”时,数据类型保持为字符串(或对象)。因此,我们需要一个额外的数据类型转换步骤来用整数表示类别。
结论
我们学习了熊猫的两种不同的替代功能以及它们之间的区别。有些情况下,其中一个是更好的选择,所以最好两个都知道。
值得注意的是,这两个函数都支持正则表达式(即 regex),这使它们更加灵活和强大。如果您传递一个模式并希望它作为正则表达式来处理,只需将 regex 参数的值设置为 True。
你可以成为 媒介会员 解锁我的全部写作权限,外加其余媒介。如果你已经是了,别忘了订阅https://sonery.medium.com/subscribe如果你想在我发表新文章时收到电子邮件。
感谢您的阅读。如果您有任何反馈,请告诉我。
2 个必须知道的 PostgreSQL 函数
原文:https://towardsdatascience.com/2-must-know-postgresql-functions-50bbcc30032b
举例说明
(布莱恩·布里登在 Unsplash 上拍摄的
考虑到存储在关系数据库中的大量结构化数据,数据科学家和分析师几乎每天都要与关系数据库进行交互。我们使用 SQL 来进行这些交互,这使得它成为数据科学中最受欢迎的技能之一。
有许多不同的关系数据库管理系统(RDBMS)使用 SQL 与关系数据库中的数据进行交互和管理。流行的 RDBMSs 之一是 PostgreSQL,它是开源的,在可靠性、特性健壮性和性能方面享有很高的声誉。
在本文中,我们将学习 2 个 PostgreSQL 函数,它们简化了复杂的操作,在许多情况下派上了用场。我称它们为救生功能。
1.生成 _ 系列
该函数可用于创建带有数字和日期的有序表格。日期的一个典型用例是,您有一个事件的开始和结束日期,并且需要将其扩展为一个日历。
让我们看一个例子。我们有一个包含酒店预订的预订表。它包括预订 id、入住和退房日期。我们希望扩展它,以便更容易计算占用率。
SELECT
id,
generate_series(
checkIn,
checkOut,
INTERVAL '1 day'
) AS booked
FROM booking
上述查询将包括实际上不被视为已预订的退房日期。因此,为了准确标记预订的天数,我们需要在生成序列之前从退房日期中减去一天。
这是如何做到的:
SELECT
id,
generate_series(
checkIn,
(checkOut - INTERVAL '1 day'),
INTERVAL '1 day'
) AS booked
FROM booking
这段代码的作用如下所示:
(图片由作者提供)
我们可以将左边的桌子连接成日历桌,就这样!我们有一个标有预定日期的日历。
2.收件人 _ 字符
to_char 函数可用于将时间戳、时间间隔或数值转换为格式化字符串。我发现它在从时间戳或日期中提取信息时最有用。
其语法如下:
TO_CHAR(expression, format)
我们可以用它来提取月份名称和月份缩写,分别使用' month '和' MON '格式。假设我们有一个预订表,其中有一个名为“已预订”的日期列。我们可以使用 to_char 函数提取这些片段,如下所示:
select
booked,
to_char(booked, 'MONTH') AS month,
to_char(booked, 'MON') AS mon,
from booking
(图片由作者提供)
我们还可以获得字符串形式的年月信息:
select
booked,
to_char(booked, 'YYYY-MM') AS yearmonth
from booking
如果日期是 2022–10–08,则年月值将是 2022–10。
还有一些与日期相关的有用格式。例如,我们可以提取日期名称和数字。
select
booked,
to_char(booked, 'DY') AS day_name,
to_char(booked, 'DD') AS day,
from booking
(图片由作者提供)
对于不同的任务,还有其他可能有用的格式。您可以查看官方文档,了解 to_char 函数支持的其他格式。
我们已经介绍了 PostgreSQL 的两个重要功能。它们主要用于数据预处理,或者使原始数据更好地适合您随后要做的任务。这些函数实际上表明 SQL 不仅仅是一种查询语言,还是一种高效的数据分析和操作工具。
你可以成为 媒介会员 解锁我的全部写作权限,外加其余媒介。如果你已经是了,别忘了订阅https://sonery.medium.com/subscribe如果你想在我发表新文章时收到电子邮件。
感谢您的阅读。如果您有任何反馈,请告诉我。
2 个必须知道的时间序列模型及其特性
原文:https://towardsdatascience.com/2-must-know-time-series-models-and-their-properties-e92953bd8c5a
随机游走和白噪声
马克西姆·霍普曼在 Unsplash 上的照片
时间序列分析或预测是数据科学中极具挑战性的任务。这方面有几种模型。在本文中,我们将讨论随机游走和白噪声。
与其他模型相比,随机游走和白噪声可以被认为是简单的。然而,它们是基本的,并且被用于许多领域,例如金融、数学、计算机科学等等。
而且,对随机游走和白噪声有一个全面的了解,将有助于理解更复杂的模型。
如果你想在我发表新文章时收到电子邮件,别忘了订阅。
随机游动
随机游走模型假设时间序列从初始值开始,并在每个时间间隔采取随机步骤。因此,时间 t 的值等于时间 t-1 的值加上一个随机值。
随机行走模型
在每个时间间隔,来自正态分布(即随机噪声)的值被加到先前的值上。因此,无论你在哪里,你的下一个位置就是你的当前位置加上一个随机噪声。
时间间隔的长度取决于时间序列。例如,股票价格的随机游走模型可以有每日股票价值。在这种情况下,今天的股票价值等于昨天的价值加上随机噪声。
下面的线图包含一个随机游走。
(图片由作者提供)
在平稳时间序列中,均值和方差等统计属性不会随时间而改变。
在上面的图中,我们清楚地观察到均值和方差随时间的系统性变化。因此,随机漫步不是一个平稳的时间序列。
因为 t 时刻的值等于 t-1 时刻的值加上一个随机噪声,所以随机游走中的值取决于它们以前的值。因此,连续值之间存在相关性。
我们可以使用 ACF 图来显示这种相关性,ACF 图显示了不同时间滞后的自相关系数。
随机漫步的 ACF 图(图片由作者提供)
自相关系数总是从 1 开始。我们观察到两个连续值之间有很强的相关性。
随着时间差或滞后时间的增加,自相关系数也会降低。这是有意义的,因为每一个时间步长都会给初始值引入一个额外的随机噪声。
白噪声
花点时间检查一下上面随机漫步的情节。数值先下降,然后在 150 多天内保持上升。然后,我们观察到突然下降。因此,数据中有一个明显的趋势。
如果我们以某种方式从随机游走模型中移除这种趋势,我们最终会得到白噪声。我们可以通过取连续值之间的差来实现。
下面的线图显示了我们上面的随机漫步模型中连续步骤之间的差异。这些值的计算方式如下:
- X1-X0,
- X2-X1,
- X3-X2,
- 诸如此类。
(图片由作者提供)
这是一个纯粹的随机过程,也称为白噪声。这是一个平稳的过程,因为我们看不到均值或方差随时间的任何系统性变化。
让我们也创建白噪声的 ACF 图,并将其与随机游走的 ACF 进行比较。
白噪声的 ACF 图(图片由作者提供)
值之间的自相关系数非常小,不显著,因为蓝色虚线表示显著性水平。
我已经创建了随机游走和白噪声时间序列以及 R 的图。如果你想自己练习,这里是生成这些图的 R 代码。
# Create a time-series with 300 values
x <- NULL
x[1] <- 0 # starts with 0for (i in 2:300) {
# add a random value from a standard normal distribution
x[i] <- x[i-1] + rnorm(1)
}# converting to time-series
random_walk <- ts(x)# line plot
plot(random_walk, main="A random walk", xlab="Day", ylab="")# acf plot
acf(random_walk)# create white noise by taking the differences
white_noise <- diff(random_walk)# line plot
plot(diff(random_walk), main="White noise", xlab="Day", ylab="")# acf plot
acf(white_noise)
时间序列分析有它自己的技术和动态。如果你打算在一个需要相当水平的时间序列分析的领域工作,比如金融和零售,我建议学好基础知识。
别忘了 订阅 如果你想在我发表新文章时收到电子邮件。
你可以成为 媒介会员 解锁我的全部写作权限,外加其余媒介。如果您使用以下链接,我将收取您的一部分会员费,无需您支付额外费用。
https://sonery.medium.com/membership
感谢您的阅读。如果您有任何反馈,请告诉我。
演示企业级 ML 平台时需要做好的两个问题
原文:https://towardsdatascience.com/2-questions-to-prep-well-for-while-demoing-enterprise-ml-platforms-f9f9a45b257d
何时(以及不)用技术话题淹没你的潜在客户
Pawel Czerwinski 在 Unsplash 上的照片
(注:所有观点均为本人)
介绍
自动化数据科学和机器学习在众多行业和使用案例中呈上升趋势,随之而来的是越来越多的公司希望获得现成的数据科学能力,而无需雇佣数据科学家和建立内部能力的漫长过程。
因此,随着市场竞争越来越激烈,潜在客户在购买自动化机器学习操作时,现在比以往任何时候都有更多的选择。
在销售周期中,向您的潜在目标客户演示解决方案是一个关键步骤,以便建立对产品的信任,并在收购业务部门的眼中验证应用程序。
许多公司采用偏重技术的方法来完成这一步,也许让他们自己的数据科学家和开发人员带领业务领导者了解最具技术性的功能,而没有意识到你的客户有兴趣获得答案的一些最重要的问题并不总是与核心的机器学习概念相关,特别是如果你的受众是非技术人员。
在这篇文章中,我将详细阐述两个问题,这两个问题决定了演示的成败,以及在一个经过深思熟虑的回答中,哪些方面是关键的。
我们怎么知道这个模型是好的?
第一个问题旨在验证模型,不仅要了解机器学习结果是如何计算的,更重要的是,数据科学平台对这些结果的有效性水平是什么。
根据您是向技术数据科学部门演示,还是向希望通过与 AutoML 平台集成来快速获得现成数据科学功能的非技术业务部门演示,回答此问题时要考虑的要素如下:
**受众是技术(数据分析/科学)部门:**演示中需要强调的有用元素包括:
- 对模型验证评分和评估选项的深入分析,主要是深入了解用户如何与不同的参数进行交互
- 与建模提供商(AWS、GCP 等)的第三方集成..),涵盖或一般验证平台的建模和算法基础是否稳固,以及模型结果是否合法
- 涵盖由潜在客户的数据科学部门提供的应用内自定义脚本功能,以将开箱即用的验证结果与通用数据科学编程语言中可用的特定工作流相结合;引入额外的模型验证检查
**受众是非技术人员(业务利益相关者&职能经理):**演示中需要强调的要素包括:
- 提供类似用例及其应用结果的客户验证和推荐
- 展示简单的模型验证仪表板,提供易于阅读的 KPI,使用户和利益相关者了解一般模型性能;在这点上,更高级别的抽象是优选的(例如,代替提供精度/回忆/F1/对数损失分数度量,整体模型准确性或评级,以使得更低级别的/更技术性的度量不会引入混淆
这不是我们的典型使用案例。这有什么关系?
许多演示侧重于突出 AutoML 平台的技术特性,而不是真正针对潜在客户的行业或典型用例。
这通常是一个问题,因为利益相关者对相关示例感兴趣,通过这些示例,他们可以真正评估产品的数据科学产品。随着演示过程中的注意力持续时间越来越短,尤其是在虚拟通话过程中,展示相关的工作流程是必须的。
尽管这需要更多的准备工作,需要销售和技术利益相关者之间更多的协调来整理演示材料,但这是非常值得的。这需要对客户的产品和使用情形有透彻的了解,通过向具有类似需求的类似客户销售产品,这一点可以得到有力的支持。
还可以通过按机会大小划分潜在客户群来节省额外的准备时间,确保只为那些具有高于平均估计美元价值的客户演示做最充分的准备。
在实践中,为 AutoML 平台制作相关演示意味着关注以下元素:
- **数据:**获取代表客户行业或应用的数据(例如,带着贷款预测数据与银行客户会面是相关的,而向制药客户演示相同的数据则不相关)
- **用例:**展示一个 AutoML 工作流,它不仅从数据的角度,而且从“业务案例”的基本原理来看都是重要的和一致的(例如,向一个银行客户的业务部门演示一个贷款预测用例,该业务部门不处理贷款相关的流程,而向一个处理该业务部门的业务部门演示相同的数据是不相关的)
以这种方式确定演示目标要有效得多,即使在大多数情况下 B2B 销售团队不会在演示准备上做额外的努力,这是迄今为止你可以采取的最有效的行动,以充分准备好浏览你的演示,不要期望这个问题会出现。
如果很难获得相关的使用案例和/或数据,您可以通过使用类比,并在您正在展示的数据和演示与您的潜在客户的数据科学使用案例之间绘制有意义的平行关系,来努力获得相关的使用案例和/或数据。
摘要
如果你在汽车领域,你知道一个好的演示对吸引你的目标客户和建立你的产品的可信度是至关重要的。
为了总结如何最大限度地向客户展示您的解决方案,请记住在演示准备中考虑以下几个方面:
- 开发一个针对客户受众的模型验证部分
- 通过专注于让数据和用例与潜在客户的需求“对话”,增加演示的相关性。
感谢阅读!
访问我的免费数据科学资源清单 这里 。
https://edo-romani1.medium.com/membership
在 SQL 中使用 GROUP BY 时要遵循的 2 条规则
原文:https://towardsdatascience.com/2-rules-groupby-sql-6ff20b22fd2c
了解 GROUP BY 子句中要包含哪些列,以及如何在 WHERE 子句中包含聚合
由 Markus Spiske 在 Unsplash 上拍摄的照片
SQL 中的GROUP BY
子句允许用户应用函数,并通过将具有相同值的记录分组在一起来对数据执行聚合,如结果查询中所指定的。
SQL 新手在使用GROUP BY
子句和聚合函数时,通常很难找到正确的查询语法。
在接下来的几节中,我们将介绍两个基本原则,这两个原则最终可以帮助您解决 SQL 中聚合和 GROUP BY 子句的任何困惑。
首先,让我们创建一个示例表,我们将在这个简短的教程中引用它,以便用实际的例子来演示一些概念。
> SELECT * FROM orders;+----+-------------+---------+-----------+----------+
| id | customer_id | amount | order_date| store_id |
+----+-------------+---------+-----------+----------+
| 1 | 20 | 10.99 | 2022-02-02| 1 |
| 2 | 138 | 21.85 | 2022-09-10| 1 |
| 3 | 31 | 9.99 | 2021-12-28| 2 |
| 4 | 20 | 12.99 | 2022-04-29| 2 |
| 5 | 89 | 5.00 | 2022-03-03| 3 |
| 6 | 31 | 4.99 | 2022-11-09| 1 |
| 7 | 20 | 15.00 | 2022-09-10| 3 |
| 8 | 15 | 120.00 | 2022-06-07| 2 |
| 9 | 15 | 32.00 | 2022-04-01| 2 |
+----+-------------+---------+-----------+----------+
SQL 中的 GROUP BY 子句
现在,GROUP BY
子句通常应用于分类列。尽管可以对具有连续值的列上的记录进行分组,但这样做通常没有太大意义。
当调用GROUP BY
子句时,查询将根据GROUP BY
子句中指定的列的值将记录分组,然后将聚合函数应用于各个组,以计算所需的结果,并最终返回结果,在这些结果中,我们将看到GROUP BY
子句中指定的每组列的一个值。
一些最常见的聚合函数包括SUM
、AVG
、COUNT
、MAX
和MIN
。
现在使用我们的示例表,假设我们希望看到每个客户的最大订单量,最后根据最大订单量对结果进行降序排序。下面的查询可以解决这个问题:
SELECT
customer_id,
MAX(amount) as max_order_amount
FROM
orders
GROUP BY
customer_id
ORDER BY
max_order_amount DESC
;
结果会是
+-------------+------------------+
| customer_id | max_order_amount |
+-------------+------------------+
| 15 | 120 |
| 138 | 21.85 |
| 20 | 15 |
| 31 | 9.99 |
| 89 | 5 |
+------------+-------------------+
GROUP BY 子句中要包含哪些列
现在,当我们需要在我们的SELECT
子句中包含更多列时,事情可能会变得有点复杂。继续我们之前编写的查询,现在让我们假设我们想要查看每个商店的每个客户的最小和最大订单。
让我们尝试运行以下查询:
SELECT
customer_id,
store_id,
MIN(amount) as min_order_amount,
MAX(amount) as max_order_amount
FROM
orders
GROUP BY
customer_id
ORDER BY
max_order_amount DESC
;
显然,我们有一个语法错误,应该类似于下面报告的错误:
ERROR: column "orders.store_id" must appear in the GROUP BY clause or be used in an aggregate function LINE 3: store_id, ^ SQL state: 42803 Character: 29
这是因为我们违反了涉及GROUP BY
子句的 SQL 查询的一个基本原则。在SELECT
语句中指定的列,要么必须应用聚合函数,要么必须包含在GROUP BY
子句中。
回到我们的例子,这个错误是因为我们没有将staff_id
和customer_id
一起包含在GROUP BY
子句中。另一方面,amount
不应该包含在GROUP BY
子句中,因为它应用了聚合函数(MIN
和MAX
)。
SELECT
语句中的列必须应用聚合函数,或者包含在GROUP BY
子句中
因此,为了修复我们的查询,我们需要做的就是在GROUP BY
子句中包含store_id
(假设我们想要观察的是每个客户和商店的最大和最小订单金额)。
SELECT
customer_id,
store_id,
MIN(amount) as min_order_amount,
MAX(amount) as max_order_amount
FROM
orders
GROUP BY
customer_id,
store_id
ORDER BY
max_order_amount DESC
;
WHERE 语句中的聚合以及如何使用 HAVING
回到我们的第一个例子,让我们假设我们想计算每位消费超过 5.00 英镑的顾客的最大订单金额。
SELECT
customer_id,
MAX(amount) as max_order_amount
FROM
orders
WHERE
MAX(amount) > 5
GROUP BY
customer_id
ORDER BY
max_order_amount DESC
;
如果我们尝试运行上面的查询,将会出现以下错误:
ERROR: aggregate functions are not allowed in WHERE
上述查询的问题是,我们试图在一个WHERE
子句中包含一个聚合函数(即MAX
)。SQL 的语法明确规定WHERE
语句不能引用SELECT
子句中指定的聚合。
但是解决方法是什么呢?
WHERE 语句不能引用 SELECT 子句中指定的聚合
我们可以使用HAVING
子句,而不是在WHERE
子句中指定聚合列的条件,该子句允许我们使用GROUP BY
子句,然后对聚合结果进行筛选。
因此,我们应该将WHERE
替换为HAVING
子句,如下所示:
SELECT
customer_id,
MAX(amount) as max_order_amount
FROM
orders
GROUP BY
customer_id
HAVING
MAX(amount) > 5
ORDER BY
max_order_amount DESC
;
生成的记录集应该如下所示:
+-------------+------------------+
| customer_id | max_order_amount |
+-------------+------------------+
| 15 | 120 |
| 138 | 21.85 |
| 20 | 15 |
| 31 | 9.99 |
+------------+-------------------+
最后的想法
作为一名 SQL 初学者,使用 GROUP BY 子句有时会非常令人沮丧。在今天的简短教程中,我们讨论了在 SQL 查询中使用聚合时需要牢记的两个最基本的原则。
概括地说,重要的是要确保在SELECT
子句中指定的所有列都将应用聚合函数(例如SUM
、AVG
等)。)或在GROUP BY
条款中指定。
此外,您需要记住聚合(在SELECT
子句中指定)不能在WHERE
子句中引用。如果您希望这样做,您需要在HAVING
条款中指定您的条件。
成为会员 阅读介质上的每一个故事。你的会员费直接支持我和你看的其他作家。你也可以在媒体上看到所有的故事。
https://gmyrianthous.medium.com/membership
相关文章您可能也喜欢
两种方法来建立自己的自定义 Scikit 学习变形金刚
原文:https://towardsdatascience.com/2-ways-to-build-your-own-custom-scikit-learn-transformers-a8aeefbf8bf8
如何(以及为什么应该)创建定制的变压器
照片由欧根·斯特伦在 Unsplash 上拍摄
Scikit 学习转换器(不要与深度学习转换器混淆)是 Scikit 学习包中的类,有助于给定数据集中的转换。
这些转换器可以执行各种操作,如归一化和主成分分析。但是,某些情况下可能需要使用所提供的工具无法执行的操作。
对于这种情况,用户可以选择创建满足其特定需求的自定义函数。然而,对于机器学习应用程序来说,有一个更好的选择:创建定制的转换器。
在这里,我们探索在 Scikit 中使用定制转换器而不是定制函数的好处——了解并回顾用户创建它们的两种不同方式。
为什么要定制变压器(相对于函数)?
Scikit 学习变压器设计高效。他们实现了fit
方法和transform
方法,前者从训练集获得所需的模型参数,后者使用这些模型参数来转换训练集和测试集。
此外,Scikit Learn 包提供了 Pipeline 和 ColumnTransformer 之类的类。这些工具与变压器携手并进,使用户能够构建一个整洁有序的特征工程程序。
自定义函数的主要问题是它们不能集成到前面提到的许多 Scikit 学习工具中。结果,用户将被迫以一种既低效又容易出错的方式把这些功能硬塞到他们的特征工程过程中。
一个更好的选择是使用定制转换器执行定制操作。这将确保它们可以通过管道等工具与其他变压器一起使用。
你真的需要定制变压器吗?
下一个要考虑的问题是,您是否首先需要一个定制的转换器。Scikit 学习包可能没有您需要的转换器,但这并不意味着您必须额外工作来创建自己的转换器。
有许多专门研究与 Scikit Learn 兼容的特征工程的开源 Python 包,如 feature_engine 和 category_encoders 包。这些软件包提供了自己的一套变压器,可以满足您的需求。
因此,在你开始考虑编写任何额外的代码之前,要彻底地探索所有可用的工具。从长远来看,稍微挖掘一下可以省去你很多麻烦。
在 Scikit-Learn 中创建自定义转换器
创建一个 transformer 的想法可能看起来令人望而生畏,但是由于 Scikit Learn 包的巨大特性,它几乎不需要任何努力。
对于那些希望构建自己的定制转换器的人来说,有两个主要的选择。
选项 1 -使用 FunctionTransformer
Scikit 学习模块提供了 FunctionTransformer 类,顾名思义,该类将函数转换成转换器。此外,转换是通过一个简单的一行程序实现的!
FunctionTransformer 可用于将预先存在的 numpy 或 pandas 函数转换为转换器。
它还可以用于将自定义函数转换为转换器。如果感兴趣的函数需要参数,可以在kw_args
参数中输入。
例如,如果我们想要创建一个将所有值乘以给定数字的转换器,我们可以创建一个执行该任务的函数,然后将其转换为转换器。
一旦该函数被转换成一个转换器,它就拥有了fit
和transform
方法,这使得它很容易与其他转换器一起使用。
也就是说,FunctionTransformer 有一个明显的限制。
不幸的是,它不存储用于拟合训练数据的参数,这对于某些需要保留模型参数的操作来说可能是一个问题,例如规范化和一次热编码。
因为可能很难将这个缺陷概念化,所以使用一个例子将是有益的。我们可以使用通过转换pandas.get_dummies
函数创建的转换器对数据集执行一次性编码。
假设我们有以下数据。
代码输出(由作者创建)
我们可以将get_dummies
函数转换成一个转换器,然后使用它的fit_transform
方法对数据进行编码。
代码输出(由作者创建)
输出显示列“水果 _ 苹果”和“水果 _ 香蕉”。为了使转换器可行,它需要在处理不可见数据时生成相同的列。
然而,我们的变压器是这样吗?它将如何处理以下包含不可见数据的数据集?
代码输出(由作者创建)
代码输出(由作者创建)
转换器现在生成“Fruit_Blueberry”和“Fruit_Strawberry”列,它们与定型集的输出不匹配。这是因为新列来自测试数据,而不是定型数据。
另外,我在另一篇文章中讨论了这个难题的解决方案:
总而言之,FunctionTransformer 类是一种将函数转换为转换器的简单方法,但对于必须保留来自训练数据的参数的情况,它并不理想。
选项 2—从头开始创建 Scikit 学习转换器
第二种选择是从头开始创建一个转换器。同样,这种前景并不像看起来那么具有挑战性。
说明这种方法的最好方式是用一个例子。
假设我们正在构建一个转换器,通过将少数类别转换成一个特定的类别来解决高基数(即,太多的唯一值)问题。
变压器将利用以下模块:
首先,我们可以创建名为ReplaceMinority
的类。为此,我们需要继承两个导入的基类BaseEstimator
和TransformMixin
。
然后,我们需要用__init__
构造函数初始化属性。这个转换器将有threshold
参数和replace_with
参数,前者规定了非少数民族类别的最小比例,后者规定了少数民族应该被替换的类别。
接下来,我们可以创建fit
方法。对于这个应用程序,我们需要输入数据,并记录给定数据框中每一列的所有非少数类别。
之后,我们可以创建transform
方法。在这里,我们用每列的replace_with
参数中的参数替换所有少数类别,并返回结果数据集。
就是这样!
当我们把所有的东西放在一起,这就是这个类的样子。
那并不需要太多的工作,不是吗?
让我们来测试一下变压器。假设我们有一个水果数据集,其中有几个少数群体。
代码输出(由作者创建)
我们可以通过使用这个转换器将少数民族替换为“其他水果”来减少独特类别的数量。
让我们创建一个ReplaceMinority
对象,然后使用fit_transform
方法将少数民族替换为“其他水果”。
代码输出(由作者创建)
在这里,变形金刚已经将“苹果”和“香蕉”识别为非少数民族。所有其他水果都换成了“其他水果”。这导致唯一值的数量减少。
转换器现在将根据训练数据中的参数处理任何看不见的数据。我们可以通过转换测试集数据来证明这一点:
代码输出(由作者创建)
仅在测试集中,没有一个类别是少数,但是转换器已经将“苹果”和“香蕉”识别为唯一的非少数类别,因此任何其他类别都将被替换为“其他水果”。
代码输出(由作者创建)
此外,我们可以将新的转换器嵌入到 Scikit 学习管道中。在这里,我们可以用一个OneHotEncoder
对象来链接它。
总的来说,从零开始构建一个转换器使用户能够为更具体的用例执行过程。它还使用户能够基于来自训练集的参数来转换测试集。然而,这种方法更费时,而且容易出错。
结论
照片由 Prateek Katyal 在 Unsplash 上拍摄
总的来说,Scikit Learn transformers 功能强大,因为它们的效率以及与 Pipeline 和 ColumnTransformer 等工具的兼容性。为了保持这种效率,最好坚持使用与 Scikit Learn 功能工程兼容的变压器。
如果 Scikit Learn 中没有一个变形金刚可以完成这项工作,请探索其他兼容的软件包。如果所需的转换器不可用,您可以选择将自定义函数转换为转换器,或者从头开始创建自己的 Scikit Learn 转换器。
我祝你在数据科学的努力中好运!
掌握熊猫数据帧过滤的 20 个例子
原文:https://towardsdatascience.com/20-examples-to-master-filtering-pandas-dataframes-df6fabfe126f
实用指南
法国人 Daphné Be 在 Unsplash 上的照片
我们倾向于收集尽可能多的数据,因为数据是非常有价值的资产。我们拥有的数据越多,我们能够创造的解决方案和产品就越强大。
近年来,收集和存储的数据量急剧增加。这背后的两个主要原因是:
- 收集和存储数据变得更加便宜和容易。
- 我们有强大的工具来处理大量的数据。
然而,我们并不总是使用手头的所有数据。数据的收集可能有多种目的,其中一部分对于特定目的来说可能是多余的。
我们有时会从大型数据集中抽取一小部分样本来进行探索性数据分析。这使得熟悉数据的特征和结构变得更加容易。
对于这种情况,拥有一个高效的工具来过滤数据是非常重要的。Pandas 是最好的数据分析和操作工具之一,它为我们提供了加速和简化过滤表格数据的功能。
在这个例子中,我们将讨论 20 个例子,包括在过滤熊猫数据帧时使用的函数和技术。
让我们从导入 Pandas 和创建一个示例数据框架开始。
import pandas as pddf = pd.DataFrame({ "name": ["John","Jane","Emily","Lisa","Matt"],
"note": [92,94,87,82,90],
"profession":["Electrical engineer","Mechanical engineer",
"Data scientist","Accountant","Athlete"],
"date_of_birth":["1998-11-01","2002-08-14","1996-01-12",
"2002-10-24","2004-04-05"],
"group":["A","B","B","A","C"]})
df(作者图片)
我们现在可以开始举例了。
示例 1:选择列的子集
df[["name","note"]]**# output**
name note
0 John 92
1 Jane 94
2 Emily 87
3 Lisa 82
4 Matt 90
示例 2:用 loc 选择行和列的子集
loc 方法用于使用行和列标签进行筛选。以下代码行返回前 3 行以及 name 和 note 列。
df.loc[:3, ["name","note"]]**# output** name note
0 John 92
1 Jane 94
2 Emily 87
示例 3:使用 iloc 选择行和列的子集
iloc 方法类似于 loc 方法,但它使用行和列索引,而不是标签。以下代码行返回前 3 行和第 3 列(索引从 0 开始)。
df.iloc[:3, 2]**# output**0 Electrical engineer
1 Mechanical engineer
2 Data scientist
Name: profession, dtype: object
您可能已经注意到,我们使用相同的表达式(":3 ")来选择具有 loc 和 iloc 方法的行。原因是 Pandas 默认为行分配整数标签。除非指定特定的标签,否则一行的索引和标签是相同的。
示例 4:对列值使用比较运算符
df[df.note > 90]**# output** name note profession date_of_birth group
0 John 92 Electrical engineer 1998-11-01 A
1 Jane 94 Mechanical engineer 2002-08-14 B
示例 5:对字符串使用比较运算符
df[df.name=="John"]**# output** name note profession date_of_birth group
0 John 92 Electrical engineer 1998-11-01 A
示例 6:带有字符串访问器的字符串条件
字符串访问器有几个函数可以处理字符串。例如,我们可以基于包含特定单词或字符序列的列进行过滤。
df[df.profession.str.contains("engineer")]**# output** name note profession date_of_birth group
0 John 92 Electrical engineer 1998-11-01 A
1 Jane 94 Mechanical engineer 2002-08-14 B
示例 7:另一个带有字符串访问器的字符串条件
df[df.name.str.startswith("L")]**# output** name note profession date_of_birth group
3 Lisa 82 Accountant 2002-10-24 A
示例 8:多类型字符串方法
我们可以通过链接来组合多个 str 方法。例如,如果我们不确定是否所有的名字都以大写字母开头,我们可以先将它们转换成小写字母,然后进行过滤。
df[df.name.str.lower().str.startswith("l")]**# output** name note profession date_of_birth group
3 Lisa 82 Accountant 2002-10-24 A
示例 9:波浪号(~)运算符
波浪号运算符表示“非”逻辑。它让我们得到不符合给定条件的行。
df[~df.profession.str.contains("engineer")]**# output** name note profession date_of_birth group
2 Emily 87 Data scientist 1996-01-12 B
3 Lisa 82 Accountant 2002-10-24 A
4 Matt 90 Athlete 2004-04-05 C
示例 10:dt 访问器
dt 访问器为我们提供了许多处理日期和时间的方法。但是,我们不能将 dt 访问器应用于具有 string 数据类型的列,因此我们首先需要更改数据类型。
df.date_of_birth = df.date_of_birth.astype("datetime64[ns]")df[df.date_of_birth.dt.month==11]**# output** name note profession date_of_birth group
0 John 92 Electrical engineer 1998-11-01 A
我们已经从一个日期中提取了月份信息,并将其用于过滤。
例 11:dt 访问器(2)
df[df.date_of_birth.dt.year > 2000]**# output** name note profession date_of_birth group
1 Jane 94 Mechanical engineer 2002-08-14 B
3 Lisa 82 Accountant 2002-10-24 A
4 Matt 90 Athlete 2004-04-05 C
例 12:多个条件(与)
我们可以用逻辑运算符组合多个条件。以下代码行用“与”逻辑组合了两个条件。
df[(df.date_of_birth.dt.year > 2000) &
(df.profession.str.contains("engineer"))]**# output** name note profession date_of_birth group
1 Jane 94 Mechanical engineer 2002-08-14 B
例 13:多个条件(or)
下面一行代码返回数据科学家或注释超过 90 的人。
df[(df.note > 90) | (df.profession=="Data scientist")]**# output** name note profession date_of_birth group
0 John 92 Electrical engineer 1998-11-01 A
1 Jane 94 Mechanical engineer 2002-08-14 B
2 Emily 87 Data scientist 1996-01-12 B
例 isin 方法
isin 方法是另一种使用多个条件进行过滤的技术。它将该值与值列表进行比较。
df[df.group.isin(["A","C"])]**# output** name note profession date_of_birth group
0 John 92 Electrical engineer 1998-11-01 A
3 Lisa 82 Accountant 2002-10-24 A
4 Matt 90 Athlete 2004-04-05 C
当我们有几个值用于过滤时,isin 方法非常有用。
例 15:查询功能
查询函数接受字符串作为过滤器。
df.query("note > 90")**# output** name note profession date_of_birth group
0 John 92 Electrical engineer 1998-11-01 A
1 Jane 94 Mechanical engineer 2002-08-14 B
例 16:查询功能(2)
df.query("group=='A' and note > 89")**# output** name note profession date_of_birth group
0 John 92 Electrical engineer 1998-11-01 A
例 17:最小的函数
它允许根据给定的列选择 n 个最小值。
df.nsmallest(2, "note")**# output** name note profession date_of_birth group
3 Lisa 82 Accountant 2002-10-24 A
2 Emily 87 Data scientist 1996-01-12 B
例 nlargest 函数
df.nlargest(2, "note")**# output** name note profession date_of_birth group
1 Jane 94 Mechanical engineer 2002-08-14 B
0 John 92 Electrical engineer 1998-11-01 A
例 isna 函数
isna 函数可用于选择指定列中缺少值(即 null)的行。让我们首先在数据帧中添加一个空值。
import numpy as npdf.loc[0, "profession"] = np.nan
以下代码行返回职业值为空的行。
df[df.profession.isna()]**# output** name note profession date_of_birth group
0 John 92 NaN 1998-11-01 A
例 notna 函数
这与 isna 的功能正好相反。我们可以用它来过滤掉缺少值的行。
df[df.profession.notna()]**# output** name note profession date_of_birth group
1 Jane 94 Mechanical engineer 2002-08-14 B
2 Emily 87 Data scientist 1996-01-12 B
3 Lisa 82 Accountant 2002-10-24 A
4 Matt 90 Athlete 2004-04-05 C
我们已经做了 20 个例子,展示了几种过滤熊猫数据帧的工具和技术。
你可以成为 介质成员 解锁我的全部写作权限,外加其余介质。如果你已经是了,别忘了订阅https://sonery.medium.com/subscribe如果你想在我发表新文章时收到电子邮件。
*https://sonery.medium.com/membership
感谢您的阅读。如果您有任何反馈,请告诉我。*
即使是熟练的 Python 程序员也会犯的 20 个新手错误
原文:https://towardsdatascience.com/20-newbie-mistakes-that-even-skilled-python-programmers-make-6879048731a4
用 Python 编码时应该避免的一些常见错误
安德烈·德·森蒂斯峰在 Unsplash 上拍摄的照片
编程(不仅仅是用 Python,而是任何编程语言)的最大好处是,通常有多种方法来实现同一个解决方案。
使用不同的方法达到相同的输出(图片由作者提供)
当然,有些方法比其他方法更好,这可能是由于各种原因,如:
- 更少的内存使用
- 运行时高效
- 较少的代码行
- 容易理解
- 简单的逻辑等。
在这篇文章中,我将向您介绍 20 种特定的情况,在这些情况下,Python 程序员不知不觉地陷入编写大型、不优雅和复杂的 Python 代码的陷阱——这最终阻碍了他们释放 Python 的真正潜力。
除此之外,我还将为所提出的问题提供另一种解决方案,以帮助您纠正这些错误。
你可以在这里找到这篇文章的代码。
我们开始吧🚀!
#1 使用多个打印语句
天真的方法
如果您想要打印多个变量,那么简单的方法建议每个变量应该有自己的print()
语句。
优雅的方法
根据我的经验,使用多个 print 语句通常是编码人员(尤其是新手)在用 Python 编码时最常犯的错误。
然而,他们不知道的是,有了print()
,你可以在一条打印语句中打印多个变量,如下所示:
上面的sep
参数指定了使用相同的print
语句打印的各种变量之间的分隔符(上面的a
、b
和c
)。
请注意,
end
参数用于指定打印语句的结束字符。
在上面的代码中,end='\n---\n’
参数打印新的行字符,接着是---
,然后是一个新的行字符。
#2 使用 FOR 循环打印相同的变量
天真的方法
顾名思义,目标是多次打印同一个变量。
当然,您应该创建一个 FOR 循环,并迭代您希望打印变量的次数,对吗?我是说,这有什么错?
优雅的方法
虽然写一个 FOR 循环没有坏处,而且一切运行良好,但是没有必要写一个 FOR 循环多次打印同一个变量。
# 3–4 创建一个单独的变量来跟踪循环中的索引
天真的方法— 1
为了实现这一点,通常需要定义一个新变量(idx
)来跟踪索引值,并在每次迭代中递增,如下所示:
天真的方法— 2
如果不是上面的方法,人们会创建一个range
迭代器来跟踪索引,如下面的代码所示:
优雅的方法
感谢开发了enumerate()
方法的开发者。
本质上,使用这种方法,您可以跟踪索引(idx
)和值(i
),如下所示:
#5 使用 FOR 循环将列表转换为字符串
字符串列表(作者图片)
天真的方法
使用 FOR 循环,如下所示,我们可以一次收集一个列表元素。
优雅的方法
将列表转换为字符串的巧妙方法是使用 join()方法,如下所示:
这不仅可以让你避免编写一些不必要的长代码,而且和 for-loop 方法一样直观。
#6 使用 FOR 循环从列表中删除重复项
从列表中删除重复项(按作者排序的图像)
天真的方法
FOR-loop 再次出手相救!
最简单的方法是迭代输入列表,并将唯一的元素存储在一个新列表中。
优雅的方法
但是,使用一行 Python 代码就可以从列表中删除重复项,如下所示:
以上返回一个集合,您可以获得如下列表:
#7 使用 for 循环搜索列表中的元素
天真的方法
假设您想知道一个元素是否存在于一个列表(或集合)中,并返回一个布尔响应(如果存在,则返回True
,否则返回False
)。
下面演示了这种简单的方法:
啊!代码太多了吧?
优雅的方法
让我们使用in
关键字将其简化为一行实现:
#8 使用索引变量迭代两个相同大小的可迭代对象
天真的方法
类似于我们在第 3-4 节中所做的,也就是说,专门为索引定义一个变量,这里最简单的方法就是在这里采用相同的方法,如下所示:
优雅的方法
明智的方法是使用zip()
函数,将两个可重复项中的相应值配对。
#9 使用 FOR 循环反转列表
反转列表(作者图片)
天真的方法
您可能已经猜到了,我们可以对列表进行反向迭代,并将元素追加到一个新列表中,如下所示:
优雅的方法
如果您理解 Python 中的切片,这个优雅的解决方案只是一个简单的单行程序:
不要循环!
#10 使用 FOR 循环检查回文
天真的方法
扩展上述情况的想法(#9 —反转列表),我们可以检查反转列表是否与输入列表相同。
优雅的方法
如上所述,优雅的方法是使用切片并将其与输入列表进行比较:
#11 使用 FOR 循环统计 iterable 中元素的出现次数
天真的方法
寻找元素频率的简单方法是使用 FOR 循环遍历列表,并计算出现的次数。
优雅的方法
在这种情况下,节省我们编写 FOR 循环的优雅方法是使用count()
方法:
您也可以在字符串输入上使用count()
方法:
#12 使用 FOR 循环获取字符串的子字符串
天真的方法
这里的目标是返回长度为n_chars
的子串,从位置start_index
开始。
新手解决这个问题的方法是使用 FOR 循环,如下所示:
优雅的方法
然而,一行程序的方法是使用切片,这样您就不用编写 FOR 循环了。
#13 定义长整型常量
假设你想声明一个值为 10 的整型变量。
天真的方法
理想情况下,一个人可以连续地写零,并在打字时计数。
但是说别人想参考这个代码。让他们把所有的零都数出来岂不是很麻烦?
优雅的方法
为了提高可读性,可以用_
(下划线)分隔一组零,如下所示:
但这仍然是一个麻烦,不是吗?为什么有人要数零呢?
如果数字可以用a^b
的形式表示,你应该使用pow()
的方法。
#14 使用 IF 条件交换字符串的大小写
给定一个字符串,目标是使大写字母小写,反之亦然。
天真的方法
一种简单的方法是检查每个元素的大小写,然后为每种情况设置特定的条件。
输出没有问题,但是为什么要这样做呢?
优雅的方法
请改用swapcase()
方法。
#15 获得两个集合的并集
两个集合的联合(图片由作者提供)
天真的方法
迭代两个集合,并将元素添加到一个新集合中。
代码行太多了,不是吗?
让我们把它简化成一行。
优雅的方法
Python 中的集合数据结构为两个集合的并集提供了一个union()
方法。
此外,您可以将其扩展到任意数量的输入集:
是不是很酷?想象一下,为了合并这四个集合,您需要编写多少 FOR 循环。
#16 获取两个集合的交集
天真的方法
与上面讨论的联合案例类似,我们可以发现两个集合之间的公共元素如下:
优雅的方法
但是,您可以使用intersection()
方法来达到同样的目的:
#17 在 IF 语句中编写多个条件
为了详细说明这一点,假设您想要实现以下逻辑。输入是一个整数a
。
将输入映射到输出的函数(图片由作者提供)
天真的方法
在这里,我们将使用多个或独立的条件来实现上述逻辑。
优雅的方法
避免多重条件的一个聪明方法是使用in
关键字,如下所示:
#18 更改列表中所有元素的数据类型
给定一个表示整数的字符串列表,目标是通过改变数据类型将它们转换成整数列表。
天真的方法
使用 FOR 循环遍历列表,并对单个元素进行类型转换。
优雅的方法
一个聪明的方法是使用map()
,如下所示:
作为第一个参数,map()
方法接受一个函数(int
),第二个参数是一个可迭代函数(input_list
)。
#19 交换变量
给定两个变量,目标是将第一个变量的值传递给第二个变量,将第二个变量的值传递给第一个变量。
天真的方法
大多数 C/C++程序员在这里采用的方法是定义一个新的变量(temp
),他们通常也会在 Python 中扩展这个变量。
优雅的方法
幸运的是,Python 允许在一个语句中进行多次赋值,消除了对任何临时变量的需求。
#20 使用嵌套循环生成两个列表的所有组合
给定两个列表(长度为n
的a
和长度为m
的b
,生成所有的nxm
组合。
天真的方法
编写两个嵌套的 FOR 循环,并将所有组合追加到一个列表中。
优雅的方法
优雅的方法是使用 itertools 库中的product()
方法,如下所示:
结论
总之,在这篇文章中,我展示了 20 种不同的场景,我相信大多数 Python 程序员都经历过这些场景,并且可能采取了错误的方法来编写解决方案。
如果您注意到,在大多数情况下,优雅的方法主要集中在消除前一种方法中使用的 FOR 循环的显式编码。
作为这篇文章的关键,你应该永远记住,在大多数情况下,你想出的第一个解决方案不会是一个理想的方法。因此,快速的谷歌搜索总是有益的:)。
这就是为什么采用不完美主义者的心态对于成为一名优秀的程序员至关重要(不仅仅是 Python,而是任何语言)。
附:我将很快发布这篇文章的第二部分!
一如既往,感谢阅读!
🧑💻成为数据科学专家!获取包含 450 多个熊猫、NumPy 和 SQL 问题的免费数据科学掌握工具包。
✉️ 注册我的电子邮件列表 不要错过另一篇关于数据科学指南、技巧和提示、机器学习、SQL、Python 等的文章。Medium 会将我的下一篇文章直接发送到你的收件箱。
数据科学家 80%的时间使用熊猫 20%的功能
原文:https://towardsdatascience.com/20-of-pandas-functions-that-data-scientists-use-80-of-the-time-a4ff1b694707
将帕累托法则运用于熊猫图书馆
在 Unsplash 上由 Austin Distel 拍摄的照片
掌握像熊猫这样的整个 Python 库对任何人来说都是具有挑战性的。然而,如果我们退一步思考,我们真的需要了解特定库的每一个细节吗,尤其是当我们生活在一个受帕累托法则支配的世界中时?对于那些不知道的人来说,帕累托法则(也称为 80-20 法则)说,你 20%的投入总会产生 80%的产出。
因此,这篇文章是我将帕累托法则应用于 Pandas 库的尝试,并向你介绍你可能用 80%的时间处理数据帧的 20%的 Pandas 函数。下面提到的方法是我发现自己在日常工作中反复使用的方法,我觉得对于任何开始接触熊猫的人来说,熟悉这些方法是必要和充分的。
1/n:读取 CSV 文件:
如果您想在 Pandas 中读取一个 CSV 文件,使用 pd.read_csv() 方法,如下所示:
读取 CSV 文件的代码片段(作者使用 snappify.io 创建的图片)
在这里阅读文档。
2/n:将数据帧保存到 CSV 文件:
如果您想将数据帧保存到 CSV 文件,使用如下所示的 to_csv() 方法:
将数据帧保存到 CSV 文件的代码片段(作者使用 snappify.io 创建的图片)
在这里阅读文档。
3/n:从列表列表中创建数据帧:
如果你想从一系列列表中创建一个数据帧,使用 pd。DataFrame() 方法如下所示:
用于从列表的列表中创建 DataFrame 的代码片段(作者使用 snappify.io 创建的图片)
在这里阅读文档。
4/n:从字典创建数据帧:
如果你想从字典创建一个数据帧,使用 pd。DataFrame() 方法如下所示:
从字典创建 DataFrame 的代码片段(作者使用 snappify.io 创建的图片)
在此阅读文档。
5/n:合并数据帧:
DataFrames 中的 Merge 操作与 SQL 中的 JOIN 操作相同。我们用它来连接一列或多列上的两个数据帧。如果您想要合并两个数据帧,使用如下所示的 pd.merge() 方法:
用于合并数据帧的代码片段(作者使用 snappify.io 创建的图片)
在这里阅读文档。
6/n:对数据帧进行排序:
如果您想要根据特定列中的值对数据帧进行排序,请使用如下所示的 sort_values() 方法:
用于对数据帧进行排序的代码片段(作者使用 snappify.io 创建的图片)
在这里阅读文档。
7/n:连接数据帧:
如果您想要连接数据帧,请使用 pd.concat() 方法,如下所示:
用于连接数据帧的代码片段(作者使用 snappify.io 创建的图片)
在这里阅读文档。
- axis = 1 将列堆叠在一起。
- 轴= 0 将行堆叠在一起,前提是列标题匹配。
8/n:重命名列名:
如果要重命名数据帧中的一列或多列,使用如下所示的 rename() 方法:
用于重命名 DataFrame 中的列的代码段(作者使用 snappify.io 创建的图片)
在这里阅读文档。
9/n:添加新列:
如果要向数据帧添加新列,可以使用通常的赋值操作,如下所示:
向 DataFrame 添加新列的代码段(作者使用 snappify.io 创建的图片)
10/n:根据条件过滤数据帧:
如果要根据条件从数据帧中筛选行,可以如下所示进行:
用于过滤数据帧的代码片段(作者使用 snappify.io 创建的图片)
11/n:删除列:
如果要从数据帧中删除一列或多列,使用如下所示的 drop() 方法:
从 DataFrame 中删除列的代码段(作者使用 snappify.io 创建的图片)
在此阅读文档。
12/n:分组依据:
如果要在分组后执行聚合操作,请使用如下所示的 groupby() 方法:
用于对数据帧进行分组的代码片段(作者使用 snappify.io 创建的图片)
在这里阅读文档。
13/n:列中的唯一值:
如果您想计算或打印数据帧的一列中的唯一值,使用如下所示的 unique()或 unique() 方法:
用于在 DataFrame 列中查找唯一值的代码段(作者使用 snappify.io 创建的图片)
在这里阅读文档。
14/n:填充 NaN 值:
如果您想用其他值替换列中的 NaN 值,请使用如下所示的 fillna() 方法:
用于在 DataFrame 中填充 NaN 值的代码片段(作者使用 snappify.io 创建的图片)
在这里阅读文档。
15/n:对列应用函数:
如果您想将一个函数应用到一个列,使用如下所示的 apply() 方法:
对数据帧应用函数的代码片段(作者使用 snappify.io 创建的图片)
在这里阅读文档。
16/n:删除重复项:
如果要删除重复值,请使用 drop_duplicates() 方法,如下所示:
用于从数据帧中删除重复数据的代码片段(作者使用 snappify.io 创建的图片)
在这里阅读文档。
17/n:数值计数:
如果您想要查找列中每个值的频率,请使用如下所示的 value_counts() 方法:
计算列中值的频率的代码片段(作者使用 snappify.io 创建的图片)
18/n:数据帧的大小:
如果要查找数据帧的大小,请使用。形状属性如下图所示:
最后,在这篇文章中,我介绍了 Pandas 中一些最常用的函数/方法,以帮助您开始使用这个库。虽然这篇文章将有助于你熟悉语法,但我强烈建议你创建一个虚拟的数据框架,并在 jupyter 笔记本上进行实验。
此外,没有比参考熊猫官方文件更好的地方了这里获得熊猫各种方法的基本和实用知识。panda 的官方文档提供了一个函数所接受的每个参数的详细解释,以及一个实际的例子,在我看来,这是获得 panda 专业知识的一个很好的方法。
感谢阅读。我希望这篇文章是有帮助的。
20 个开源单说话人语音数据集
原文:https://towardsdatascience.com/20-open-source-single-speaker-speech-datasets-2768561f44aa
全面的开源多语言语音数据
杰森·罗斯韦尔在 Unsplash 上的照片
语音合成(text-to-speech,TTS)是人工智能领域的一项新的关键技术。它提供了从文本输入动态生成类似人类声音的能力。TTS 可用于多种目的,并与自动化服务紧密相关。
然而,训练文本到语音模型需要大量的音频数据及其相应的转写/音素。因此,对于大多数开发人员来说,这并不容易实现,因为收集和标记数据集需要付出巨大的努力。
我整合了 20 个公开的开源单说话人多语言语音数据集。免费为你的项目使用它们。
注:并非所有都可以用于商业目的。我已经在每个数据集下面列出了他们的许可证、采样率和文件大小,供您参考。
英语
LJSpeech
LJSpeech 是最常用的文本到语音转换数据集之一。大约有 13,100 个基于 7 本非小说类书籍的音频剪辑。每个片段由 1 到 10 秒组成,产生超过 23 小时的音频数据。
╔═══════════════╦═══════════╦═══════════╦═══════════════════════╗
║ **Sample rate** ║ **Format** ║ **File size** ║ **License** ║
╠═══════════════╬═══════════╬═══════════╣═══════════════════════╣
║ 22050 ║ wav ║ 2.6 GB ║ [Public domain ](https://librivox.org/pages/public-domain) ║
╚═══════════════╩═══════════╩═══════════╩═══════════════════════╝
世界英语圣经
世界英语圣经是由音频宝库提供的音频圣经录音的修订版。在最初的版本中,每个音频文件作为文本到语音转换训练的输入数据都太长了。因此,一名研究人员主动将录音拆分,并重新排列转录。
╔═══════════════╦═══════════╦═══════════╦═══════════════════════╗
║ **Sample rate** ║ **Format** ║ **File size** ║ **License** ║
╠═══════════════╬═══════════╬═══════════╣═══════════════════════╣
║ 12000 ║ wav ║ 6.66 GB ║ [CC BY-NC-SA 4.0](https://creativecommons.org/licenses/by-nc-sa/4.0/) ║
╚═══════════════╩═══════════╩═══════════╩═══════════════════════╝
韩国的
朝鲜语单一使用者(KSS)
KSS 是首批公开的韩语数据集之一。录音是由一名专业女声演员朗读精选的书籍录制的。大约有 12,853 个音频剪辑,产生超过 12 小时的音频数据。
╔═══════════════╦═══════════╦═══════════╦═══════════════════════╗
║ **Sample rate** ║ **Format** ║ **File size** ║ **License** ║
╠═══════════════╬═══════════╬═══════════╣═══════════════════════╣
║ 44100 ║ wav ║ 4.32 GB ║ [CC BY-NC-SA 4.0](https://creativecommons.org/licenses/by-nc-sa/4.0/) ║
╚═══════════════╩═══════════╩═══════════╩═══════════════════════╝
Jejueo 单说话人语音数据集
Jejueo,也叫济州语,是济州岛上使用的韩语。Jejueo 单说话人语音数据集是济州研究中心发起的项目的一部分。它包含大约 10k 音频文件。每个音频片段的长度约为 2 至 18 秒。
╔═══════════════╦═══════════╦═══════════╦═══════════════════════╗
║ **Sample rate** ║ **Format** ║ **File size** ║ **License** ║
╠═══════════════╬═══════════╬═══════════╣═══════════════════════╣
║ 44100 ║ wav ║ 4.38 GB ║ [CC BY-NC-SA 4.0](https://creativecommons.org/licenses/by-nc-sa/4.0/) ║
╚═══════════════╩═══════════╩═══════════╩═══════════════════════╝
日本人
CSS10 日语
CSS10 is a collection of single speaker speech datasets for 10 languages created by Kyubyong. All audio recordings is based on the audio books from LibriVox. CSS10 Japanese is a subset of CSS10 and contains about 14 hours of audio files for 明暗 (Meian).
╔═══════════════╦═══════════╦═══════════╦═══════════════════════╗
║ **Sample rate** ║ **Format** ║ **File size** ║ **License** ║
╠═══════════════╬═══════════╬═══════════╣═══════════════════════╣
║ 22050 ║ wav ║ 4.74 GB ║ [CC0: Public Domain](https://creativecommons.org/publicdomain/zero/1.0/) ║
╚═══════════════╩═══════════╩═══════════╩═══════════════════════╝
Kokoro 语音数据集
Kokoro 语音数据集包含了取自青空文子的 14 本小说的大约 43253 段录音。
它有不同的尺寸,即:
- 微小的
- 小的
- 大的
- xlarge
Tiny:
Total clips: 285
Min duration: 3.019 secs
Max duration: 9.462 secs
Mean duration: 4.871 secs
Total duration: 00:23:08Small:
Total clips: 8812
Min duration: 3.007 secs
Max duration: 14.431 secs
Mean duration: 4.951 secs
Total duration: 12:07:12Large:
Total clips: 22910
Min duration: 3.007 secs
Max duration: 14.988 secs
Mean duration: 4.984 secs
Total duration: 31:42:54X Large:
Total clips: 43253
Min duration: 3.007 secs
Max duration: 14.988 secs
Mean duration: 4.993 secs
Total duration: 59:59:40
转录元数据是在 LJSpeech 之后建模的,这使得它与大多数语音合成项目兼容。
╔═══════════════╦═══════════╦═══════════╦═══════════════════════╗
║ **Sample rate** ║ **Format** ║ **File size** ║ **License** ║
╠═══════════════╬═══════════╬═══════════╣═══════════════════════╣
║ 22050 ║ wav ║ Varies ║ [Public Domain](https://librivox.org/pages/public-domain) ║
╚═══════════════╩═══════════╩═══════════╩═══════════════════════╝
JSUT
JSUT 单个说话者语料库是 JSUT 集合的一部分,用于连接语音、歌曲和音频事件的日语语音语料库。它有大约 10 小时的音频数据
╔═══════════════╦═══════════╦═══════════╦═══════════════════════╗
║ **Sample rate** ║ **Format** ║ **File size** ║ **License** ║
╠═══════════════╬═══════════╬═══════════╣═══════════════════════╣
║ 48000 ║ wav ║ 2.7 GB ║ [CC-BY-SA 4.0](https://creativecommons.org/licenses/by-sa/4.0/) ║
╚═══════════════╩═══════════╩═══════════╩═══════════════════════╝
西班牙语
CSS10 西班牙语
CSS10 西班牙语是 CSS10 集合中最大的数据集之一。它包含超过 23 小时的录音。内容基于以下有声读物:
- 百伦
- 3 月 19 日至 5 月 2 日
- 拉巴塔拉-德洛斯阿拉皮斯
╔═══════════════╦═══════════╦═══════════╦═══════════════════════╗
║ **Sample rate** ║ **Format** ║ **File size** ║ **License** ║
╠═══════════════╬═══════════╬═══════════╣═══════════════════════╣
║ 22050 ║ wav ║ 7.57 GB ║ [CC0: Public Domain](https://creativecommons.org/publicdomain/zero/1.0/) ║
╚═══════════════╩═══════════╩═══════════╩═══════════════════════╝
荷兰人
CSS10 荷兰语
CSS10 荷兰语是 CSS10 集合的另一个子集。它包含大约 14 小时的录音,基于 20.000 Mijlen onder Zee 有声读物。每个片段大约 5 到 10 秒。
╔═══════════════╦═══════════╦═══════════╦═══════════════════════╗
║ **Sample rate** ║ **Format** ║ **File size** ║ **License** ║
╠═══════════════╬═══════════╬═══════════╣═══════════════════════╣
║ 22050 ║ wav ║ 4.48 GB ║ [CC0: Public Domain](https://creativecommons.org/publicdomain/zero/1.0/) ║
╚═══════════════╩═══════════╩═══════════╩═══════════════════════╝
法语
CSS10 法语
CSS10 法语自带 19 小时音频数据。每个音频剪辑的长度大约为 2 到 12 秒,这使得它成为大多数文本到语音转换训练的输入数据的良好选择。内容基于以下有声读物:
- 《悲惨世界》——第 5 卷。
- 亚森·罗宾控制她洛克·肖尔斯
╔═══════════════╦═══════════╦═══════════╦═══════════════════════╗
║ **Sample rate** ║ **Format** ║ **File size** ║ **License** ║
╠═══════════════╬═══════════╬═══════════╣═══════════════════════╣
║ 22050 ║ wav ║ 6.08 GB ║ [CC0: Public Domain](https://creativecommons.org/publicdomain/zero/1.0/) ║
╚═══════════════╩═══════════╩═══════════╩═══════════════════════╝
SynPaFlex
SynPaFlex 语料库拥有大约 87 小时的法语表达音频数据。不像其他数据集。这个数据集是基于一个人阅读不同文学类型的有声读物。它旨在从不同的角度探索表现力。例如:
- 话语风格
- 韵律学
- 发音
╔═══════════════╦═══════════╦═══════════╦═══════════════════════╗
║ **Sample rate** ║ **Format** ║ **File size** ║ **License** ║
╠═══════════════╬═══════════╬═══════════╣═══════════════════════╣
║ 44100 ║ wav ║ 22 GB ║ [CC BY-NC-SA 2.0](https://creativecommons.org/licenses/by-nc-sa/2.0/) ║
╚═══════════════╩═══════════╩═══════════╩═══════════════════════╝
匈牙利的
CSS10 匈牙利语
与 CSS10 中的另一个子集相比, CSS10 匈牙利语数据集的大小和音频长度大约是前者的一半。总共有大约 10 小时的基于 Egri csillagok 有声读物的简短录音。
╔═══════════════╦═══════════╦═══════════╦═══════════════════════╗
║ **Sample rate** ║ **Format** ║ **File size** ║ **License** ║
╠═══════════════╬═══════════╬═══════════╣═══════════════════════╣
║ 22050 ║ wav ║ 3.18 GB ║ [CC0: Public Domain](https://creativecommons.org/publicdomain/zero/1.0/) ║
╚═══════════════╩═══════════╩═══════════╩═══════════════════════╝
中国人
CSS10 中文
CSS10 中文是 CSS10 集合中的低资源数据集之一。它只有来自两本有声读物的大约 6 个小时的数据集:
- 朝花夕拾 (Chao Hua Si She)
- 呐喊 (Call to Arms)
它带有中文转录文本以及相应的拼音形式与语调。
╔═══════════════╦═══════════╦═══════════╦═══════════════════════╗
║ **Sample rate** ║ **Format** ║ **File size** ║ **License** ║
╠═══════════════╬═══════════╬═══════════╣═══════════════════════╣
║ 22050 ║ wav ║ 2.05 GB ║ [CC0: Public Domain](https://creativecommons.org/publicdomain/zero/1.0/) ║
╚═══════════════╩═══════════╩═══════════╩═══════════════════════╝
面包师
Baker 数据集是汉语文语转换研究中常用的数据集之一。它包含大约 12 小时的音频数据,超过 10,000 个句子。
╔═══════════════╦═══════════╦═══════════╦═══════════════════════╗
║ **Sample rate** ║ **Format** ║ **File size** ║ **License** ║
╠═══════════════╬═══════════╬═══════════╣═══════════════════════╣
║ 22050 ║ wav ║ 2.05 GB ║ Non-commercial ║
╚═══════════════╩═══════════╩═══════════╩═══════════════════════╝
德国人
CSS10 德语
CSS10 德语子集根据以下有声读物录制了约 16 小时的音频数据:
- 梅斯特·弗洛
- 见
╔═══════════════╦═══════════╦═══════════╦═══════════════════════╗
║ **Sample rate** ║ **Format** ║ **File size** ║ **License** ║
╠═══════════════╬═══════════╬═══════════╣═══════════════════════╣
║ 22050 ║ wav ║ 5.13 GB ║ [CC0: Public Domain](https://creativecommons.org/publicdomain/zero/1.0/) ║
╚═══════════════╩═══════════╩═══════════╩═══════════════════════╝
托尔斯滕之声
Thorsten-Voice 项目是一个针对德语的中立的单个说话者的语音数据(T2)。它模仿 LJSpeech 的元数据和文件结构。作者贡献了超过 23 小时的音频数据,使其成为最大的德语公开数据集之一。
╔═══════════════╦═══════════╦═══════════╦═══════════════════════╗
║ **Sample rate** ║ **Format** ║ **File size** ║ **License** ║
╠═══════════════╬═══════════╬═══════════╣═══════════════════════╣
║ 22050 ║ wav ║ 2.7 GB ║ [CC Attribution 4.0](https://creativecommons.org/licenses/by/4.0/legalcode) ║
╚═══════════════╩═══════════╩═══════════╩═══════════════════════╝
此外,该项目还提供了另一组语音数据,带有以下情绪:
- 🙂中立(19 分钟)
- 🤢厌恶(23 分钟)
- 😠愤怒(20 分钟)
- 😀开心(18 分钟)
- 😲惊讶(18 分钟)
- 😔困倦(30 分钟)
- 😵喝醉(25 分钟)
- 🤫窃窃私语(22 分钟)
╔═══════════════╦═══════════╦═══════════╦═══════════════════════╗
║ **Sample rate** ║ **Format** ║ **File size** ║ **License** ║
╠═══════════════╬═══════════╬═══════════╣═══════════════════════╣
║ 22050 ║ wav ║ 399.3 MB ║ [CC Attribution 4.0](https://creativecommons.org/licenses/by/4.0/legalcode) ║
╚═══════════════╩═══════════╩═══════════╩═══════════════════════╝
俄语
CSS10 俄语
CSS10 Russian 是 CSS10 集合中的高资源数据集之一。总之,这相当于长达 21 小时的录音。每个音频片段平均长度约为 5 至 10 秒。内容基于以下有声读物:
- 冰雪三月——ледянойпоход
- 早期短篇小说
- 儿童和成人短篇小说
╔═══════════════╦═══════════╦═══════════╦═══════════════════════╗
║ **Sample rate** ║ **Format** ║ **File size** ║ **License** ║
╠═══════════════╬═══════════╬═══════════╣═══════════════════════╣
║ 22050 ║ wav ║ 6.79 GB ║ [CC0: Public Domain](https://creativecommons.org/publicdomain/zero/1.0/) ║
╚═══════════════╩═══════════╩═══════════╩═══════════════════════╝
希腊的
CSS10 希腊语
CSS10 希腊语包含 CSS10 集合中最少的音频录音。总长度仅相当于 4 小时的数据,这可能不足以训练适当的文本到语音模型。录音基于παραμύθιχωρίςόνομα(没有名字的故事)有声读物。
然而,这些数据提供了一个良好的开端,因为你几乎找不到公开可用的希腊语单个说话者的语音数据集。
╔═══════════════╦═══════════╦═══════════╦═══════════════════════╗
║ **Sample rate** ║ **Format** ║ **File size** ║ **License** ║
╠═══════════════╬═══════════╬═══════════╣═══════════════════════╣
║ 22050 ║ wav ║ 1.31 GB ║ [CC0: Public Domain](https://creativecommons.org/publicdomain/zero/1.0/) ║
╚═══════════════╩═══════════╩═══════════╩═══════════════════════╝
芬兰人的
CSS10 芬兰语
在芬兰数据集中有大约 10 个小时的音频数据。每个音频片段的长度约为 5 到 10 秒。内容基于以下有声读物:
- gulli verin matkat kaukaisilla mailla
- ensimmiset 中篇小说
- 卡莱利-奥尔佳
- 萨尔梅兰·海因塔尔库特
╔═══════════════╦═══════════╦═══════════╦═══════════════════════╗
║ **Sample rate** ║ **Format** ║ **File size** ║ **License** ║
╠═══════════════╬═══════════╬═══════════╣═══════════════════════╣
║ 22050 ║ wav ║ 3.35 GB ║ [CC0: Public Domain](https://creativecommons.org/publicdomain/zero/1.0/) ║
╚═══════════════╩═══════════╩═══════════╩═══════════════════════╝
阿拉伯语
阿拉伯语语音语料库
阿拉伯语语音语料库为阿拉伯语(大马士革口音)提供高质量的自然语音数据集。使用专业工作室记录数据集。
╔═══════════════╦═══════════╦═══════════╦═══════════════════════╗
║ **Sample rate** ║ **Format** ║ **File size** ║ **License** ║
╠═══════════════╬═══════════╬═══════════╣═══════════════════════╣
║ 22050 ║ wav ║ 1.11 GB ║ [CC BY 4.0](https://creativecommons.org/licenses/by/4.0/) ║
╚═══════════════╩═══════════╩═══════════╩═══════════════════════╝
结论
随着人工智能的快速发展,语音合成将成为建设智能国家的一个重要因素。希望上面的数据集将有助于你的人工智能项目和研究。
请让我知道你是否在其他单个说话者的语音数据集上有新的发现。我很乐意将它们包含在这篇文章中,以帮助那些有需要的人。
感谢你阅读这篇文章。祝你有美好的一天!
参考
- CSS10 — Github
- OpenSLR —资源
20 个 Python Gem 库埋藏在装置中等待被发现
原文:https://towardsdatascience.com/20-python-gems-buried-in-the-installation-waiting-to-be-found-96034cad4d15
前所未有地了解 Python 的标准库
照片由 Dids 拍摄
介绍
大多数人认为 Python 的大规模统治地位是因为它像 NumPy、Pandas、Sklearn、XGBoost 等强大的包。这些是由专业开发人员编写的第三方包,通常借助于其他更快的编程语言,如 C、Java 或 C++。
因此,憎恨 Python 的人可能会抛出的一个无力的论点是,一旦你剥夺了这些第三方包带来的所有荣耀,Python 就不会那么受欢迎了。我要说的是,标准 Python 已经足够强大,可以与任何语言媲美。
我提请您注意 Python 安装中内置的 20 个轻量级包,它们离被释放只有一步之遥。
https://ibexorigin.medium.com/membership
获得由强大的 AI-Alpha 信号选择和总结的最佳和最新的 ML 和 AI 论文:
https://alphasignal.ai/?referrer=Bex
1️.上下文库
处理外部资源,如数据库连接、打开的文件或任何需要手动打开/关闭的操作,可能会变得非常棘手。上下文管理器很好地解决了这个问题。
上下文管理器是 Python 的一个定义特性,其他语言中没有,非常受欢迎。您可能见过与open
函数一起使用的with
关键字,并且您可能不知道您可以创建作为上下文管理器的函数。
下面,您可以看到一个充当计时器的上下文管理器:
将一个用特殊语法编写的函数包装在来自contextlib
的contextmanager
装饰器下,将它转换成一个可以和with
关键字一起使用的管理器。您可以在我的独立文章中阅读更多关于定制上下文管理器的内容。
📚文档:https://docs.python.org/3/library/contextlib.html
💻演示:链接
2️.functools
想要更强大、更短小、多功能的功能?那么,functools
已经为你准备好了。这个内置的库包含许多方法和装饰器,您可以包装现有的方法和装饰器来添加额外的特性。
其中之一是partial
,它可以用来克隆函数,同时用自定义值保留它们的一些参数。下面,我们从 Pandas 复制了read_csv
,这样我们就不必重复传递相同的参数来读取某些特定的 CSV 文件:
我最喜欢的另一个是缓存装饰器。一旦包装完毕,cache
会记住每个映射到输入的输出,这样当相同的参数传递给函数时,结果立即可用。streamlit
图书馆充分利用了这样一个功能。
📚文件:https://docs.python.org/3/library/functools.html
3️.itertools
如果您发现自己正在编写嵌套循环或复杂的函数来迭代多个 iterable,那么检查一下itertools
库中是否已经有一个函数。也许,你不必重新发明轮子——Python 想到了你的每一个需求。
下面是库中一些方便的迭代函数:
📚文件:https://docs.python.org/3/library/itertools.html
4️.一团
对于喜欢 Unix 风格的模式匹配的用户来说,glob
库应该有宾至如归的感觉:
glob
包含所有相关的功能,可以同时处理多个文件而不会有麻烦(或者使用鼠标)。
📚文件:https://docs.python.org/3/library/glob.html
5️.pathlib
说得好听点,Python os
模块糟透了...幸运的是,核心 Python 开发者听到了数百万人的呐喊,并在 Python 3.4 中引入了pathlib
库。它为系统路径带来了方便的面向对象方法。
它还拼命解决与*(放在形容词里)* Windows 路径系统相关的所有问题:
📚文件:https://docs.python.org/3/library/pathlib.html
6️.sqlite3
令数据科学家和工程师高兴的是,Python 通过sqlite3
包内置了对数据库和 SQL 的支持。只需使用一个连接对象连接到任何数据库(或创建一个)并启动 SQL 查询。该软件包运行良好。
📚文档:https://docs.python.org/3/library/sqlite3.html
7️.哈希里布
Python 已经在网络安全领域产生了很深很深的根基,不仅仅是在人工智能和人工智能领域。这方面的一个例子是hashlib
库,它包含了最常见的(也是最安全的)加密散列函数,比如 SHA256、SHA512 等等。
📚文档:https://docs.python.org/3/library/hashlib.html
8️.秘密
我喜欢推理小说。你读过 巴斯克维尔的猎犬 吗?太棒了,去读吧。
虽然实现自己的消息编码函数可能会非常有趣,但它们可能达不到与secrets
库中久经考验的函数相同的标准。
在那里,您将找到生成最复杂的密码、安全令牌和相关机密的随机数和字符所需的一切:
📚文件:https://docs.python.org/3/library/secrets.html
9️.argparse
你擅长命令行吗?那么,你是为数不多的。还有,你会爱上argparse
图书馆。您可以让静态 Python 脚本通过 CLI 关键字参数接受用户输入。
该库功能丰富,足以为您的脚本甚至包创建复杂的 CLI 应用程序。
我强烈推荐阅读 RealPython 文章,以获得对该库的全面概述。
📚文件:https://docs.python.org/3/library/argparse.html
💻演示教程:真实 Python
10.随意
这个世界上没有巧合——乌龟。
也许这就是为什么科学家使用伪随机性,即纯粹的随机性是不存在的。
不管怎样,Python 中的random
模块应该足够模拟基本的机会事件了:
📚文档:https://docs.python.org/3/library/random.html
1️1.泡菜
正如数据集的大小变得越来越大,我们也需要更快、更高效地存储它们。Python 安装自带的平面 CSV 文件的替代方案之一是pickle
文件格式。事实上,它在 IO 上比 CSV 快 80 倍,占用的内存也更小。
下面是一个 pickles 数据集并将其加载回来的示例:
📚文档:https://docs.python.org/3/library/pickle.html
💻Dario Radecic 的比较文章:链接
1️2.舒蒂尔
shutil
库代表 *shell 实用程序,*是一个用于高级文件操作的模块。使用shutil
,您可以复制、移动、删除、存档或执行任何您通常在文件浏览器或终端上执行的文件操作:
📚文件:https://docs.python.org/3/library/shutil.html
13.统计数字
有了statistics
模块,谁还需要 NumPy 或 SciPy?(其实大家都有——我只是想写一个戏剧性的句子)。
这个模块可以方便地在纯 Python 数组上执行标准的统计计算。如果你需要的只是做一个简单的计算,就没有必要安装第三方的包。
📚文件:https://docs.python.org/3/library/statistics.html
14.千兆周
Python 真是使出浑身解数。它伴随着一切——从包管理器到垃圾收集器。
是的,你没听错。一旦启用,gc
模块就充当 Python 程序中的垃圾收集器。在低级语言中,这个烦人的任务留给了开发人员,他们必须手动分配和释放程序所需的内存块。
collect
函数返回在名称空间中找到并清除的不可达对象的数量。简单地说,该函数释放未使用对象的内存槽。你可以在下面阅读更多关于 Python 内存管理的内容。
📚文档:https://docs.python.org/3/library/gc.html
💻Python 中的内存管理— 链接
15.pprint
来自某些操作的一些输出看起来太可怕了。帮你的眼睛一个忙,使用pprint
包获得智能缩进和漂亮的输出:
对于更复杂的输出和自定义打印选项,您可以使用pprint
创建打印机对象并多次使用它们。细节在文件里。
📚文档:https://docs.python.org/3/library/pprint.html
16.pydoc
代码更多的是被阅读而不是被编写——Guido Van Rossum。
你猜怎么着?我喜欢文档,喜欢为自己的代码编写文档(不要惊讶;我有点强迫症)。
讨厌它或者喜欢它——记录你的代码是一件必要的坏事。对于较大的项目来说,这变得非常重要。在这种情况下,您可以使用pydoc
CLI 库在浏览器上自动生成文档,或者使用您的类和函数的文档字符串将其保存到 HTML。
作者 GIF
在将您的文档部署到 Read the Docs 等其他服务之前,它可以作为一个初步的概述工具。
📚文件:https://docs.python.org/3/library/pydoc.html
💻编写代码指南——真正的 Python
17.日历
这个九月到底发生了什么?
作者截图
显然,英国 1752 年 9 月有 19 天。3,4,… 13 去哪了?嗯,这是关于从儒略历转换到格里高利历的巨大混乱,英国在 18 世纪 50 年代之前对此非常顽固。这里可以看。
这种情况只发生在英国。世界上的其他人是有感觉的,并且正在遵循正确的时间进程,这可以从使用calendar
模块中看出:
Python 很重视时间。
📚文件:https://docs.python.org/3/library/calendar.html
18.网络浏览器
想象一下从 Jupyter 笔记本或 Python 脚本直接跳到 StackOverflow。你为什么要这么做?
嗯,因为你可以…用webbrowser
模块。
作者 GIF
📚文档:https://docs.python.org/3/library/webbrowser.html
19.记录
你正在寻找一个经验丰富的开发人员的标志之一是他们的代码中缺少 print 语句。普通的print
函数不仅仅适用于你在编码和调试时必须处理的无数用例。你需要使用更复杂的工具,比如logging
。
此模块允许您记录具有不同优先级和自定义格式时间戳的消息。下面是我每天使用的一个:
📚文档:https://docs.python.org/3/library/logging.html
💻Python 登录优秀教程:真正的 Python
20.并行未来
我把一些有趣的东西留到了最后。这个库是关于并发执行操作的,就像多线程一样。
下面,我向一个 URL 发送 100 个 GET 请求并得到响应。这个过程缓慢而乏味,因为解释器要等到每个请求返回,这就是你使用循环的结果。
一个更聪明的方法是使用并发,并使用机器上的所有内核。concurrent.futures
包使你能够做到这一点。下面是基本语法:
运行时间减少了 12 倍,因为并发允许使用所有内核同时发送多个请求。你可以在下面的教程中读到更多关于并发性的内容。
📚文档:https://docs.python.org/3/library/concurrent.futures.html
💻演示教程:文章作者 Dario Radecic
结论
没必要把事情过分复杂化。如果您不需要它们,就没有必要让您的虚拟环境充满沉重的软件包。有几个内置的包可能就足够了。记住,“简单胜于复杂”Python 的禅宗。
https://ibexorigin.medium.com/membership
在 LinkedIn(领英)或 Twitter(T2)上与我进行友好的交谈。或者你可以读我的另一个故事。这些怎么样:
挑战你知识的 20 个 Python 面试问题
原文:https://towardsdatascience.com/20-python-interview-questions-to-challenge-your-knowledge-cddc842297c5
对数据结构、编程概念和最佳实践的一瞥
照片由克里斯里德在 Unsplash 拍摄
在不断学习我最喜欢的编程语言的来龙去脉的同时,我总是在多个概念页面上跟踪有趣的东西。
在本文中,我将我的一些笔记变成了 20 个面试问题,涵盖了数据结构、核心编程概念和 Python 最佳实践。 有趣的是,这些问题很多都是在数据科学面试中被问到的。
希望您能浏览其中的一些,并提高您的 Python 技能。
事不宜迟,让我们直接开始吧。🏊
https://medium.com/membership/@ahmedbesbes
1—列表和元组有什么区别?你应该在什么时候使用它们?
列表是可变的数据结构,而元组是不可变的。
Python 中的可变对象具有改变其值的能力。
列表是动态的:您可以向其中添加项目,或者覆盖和删除现有的项目。
元组是固定大小的:它们没有append
或extend
方法。您也不能从中删除项目。
元组和列表都支持索引,并允许使用in
操作符来检查其中的现有元素。
→有些情况我觉得元组可能有用。
- 如果您声明了一个您知道永远不会改变的项集合,或者您将只循环而不改变其值,请使用元组。
- 如果考虑性能,元组比列表更快,因为它们是只读结构。如果不需要写操作,可以考虑使用元组。
- 如果您想防止意外写入不需要更改的数据,元组可以使您的代码更安全。
下面的代码示例展示了元组与列表的不同之处。
2 —多重处理和多线程有什么区别?你应该在什么时候使用它们?
多重处理和多线程是旨在提高代码速度的编程范例。
当您使用多重处理时,您可以在多个进程上并行化您的计算。进程是独立的,相互之间不通信:它们不共享同一个内存区域,之间有严格的隔离。就应用程序而言,多处理适合 CPU 密集型工作负载。但是,它确实拥有与进程数量成比例的大量内存。
另一方面,在多线程应用程序中,线程存在于单个进程中。因此,它们共享相同的内存区域:它们可以修改相同的变量,也可以相互干扰。虽然进程是严格并行执行的,但在 Python 中,在给定的时间点上只执行一个线程,这是由于全局解释器锁( GIL )。多线程适合于 IO 绑定的应用程序,比如 web 抓取或从数据库中获取数据。
→如果你想了解更多关于多线程和多重处理的知识,我推荐你去看看这篇精彩的博客帖子,它全面地描绘了这两个概念。
3 —模块、包和库之间有什么区别?
模块只是一个 Python 文件,可以导入到脚本或其他模块中。它包含函数、类和全局变量。
包是在一个文件夹中组合在一起以提供一致功能的模块的集合。包可以像模块一样导入。它们通常有一个__init__.py
文件,告诉 Python 解释器像这样处理它们。
库是包的集合。
python 中的多线程有什么问题?
全局解释器锁(或 GIL)防止 python 解释器同时执行多个线程。简而言之,在 Python 中,GIL 强制在任何时间点只执行一个线程。
在依赖多线程代码的 CPU 受限的应用程序中,这是一个很大的性能瓶颈。
5 —什么是装修工?你能描述一个值得使用装饰者的情况吗?
装饰器是一个函数,它接收一个函数作为输入,返回一个函数作为输出。装饰器的目标是扩展输入函数的行为,而不改变其核心机制。
使用装饰器也可以防止你重复自己。它迫使你写一次通用代码,然后将它应用到每个需要它的函数中。
装饰者大放异彩的一个典型用例是日志。
例如,假设您希望将传递给程序中调用的每个函数的所有参数值记录到终端。你可以检查每一个函数定义并把它写下来,或者你可以只写一个完成这个日志记录任务的装饰器,并把它应用到所有需要它的函数上。
对一个函数应用装饰器只是在该函数的定义上添加一行代码。
**# without decorator** **def my_awesome_function():
# do awesome stuff** **# with a decorator** **@my_awesome_decorator
def my_awesome_function():
# do even more awesome stuff**
下面的代码示例创建了一个名为log
的装饰器,它记录传递给函数的参数值。
装饰器还可以用于其他目的,比如计时功能、验证输入数据、实施访问控制和认证、缓存等。
、缓存等。
6 —如何正确地将数据写入文件?否则会出什么问题?
使用上下文管理器是关键。
当您在没有上下文管理器的情况下使用open
语句,并且在关闭文件之前发生了一些异常(关闭文件是您在以这种方式打开文件时必须记住的事情)时,可能会发生内存问题,并且文件可能会在此过程中损坏。
当您使用with
打开一个文件并且出现异常时,Python 保证该文件是关闭的。
7 —函数参数是通过引用传递还是通过值传递?
在 Python 中,所有的函数参数都是通过引用传递的:这意味着如果您将一个参数传递给一个函数,该函数将获得对同一对象的引用。
如果对象是可变的,并且函数改变了它,那么参数将在函数的外部范围内发生变化。让我们看一个例子:
8-如何覆盖对象的打印方式?
使用__str__
和__repr__
邓德方法。
这里有一个例子,演示了如何在将 Person 类的实例打印到控制台时很好地进行格式化。
9 —编写一个计算整数 n 的阶乘的函数
递归是关键
10—is 和==运算符之间有什么区别?
==
是测试等式的运算符,而is
是测试等式的运算符。
两个对象可以具有相等的值,而不一定是相同的(即具有相同的存储器地址)。
记住a is b
是id(a) == id(b)
的语法糖。
11 —什么时候不应该使用 assert 语句?
assert
语句对于内部测试和健全性检查非常有用。
但是,它不应该用于执行数据验证或错误处理,因为出于性能原因,它通常在生产代码中被禁用。
想象一下,如果您使用 assert 检查管理员权限:这可能会在生产中引入一个大的安全漏洞。
您可以抛出一个自定义错误,而不是使用assert
语句。
12-什么是 Python 生成器?
Python 生成器是一个生成项目序列的函数。
生成器看起来像典型的函数,但它们的行为是不同的。首先,他们没有使用return
语句,而是使用了yield
语句。
然后,调用生成器函数并不运行该函数:它只创建一个生成器对象。只有当next
函数被应用到生成器对象或者生成器被迭代时,生成器的代码才会执行(在这种情况下,next
函数被隐式调用)
在生成器对象上调用next
函数的次数等于在生成器函数中调用yield
语句的次数。
您可以使用 for 循环或生成器表达式来定义生成器。
13 —类方法和静态方法的区别是什么?什么时候应该使用哪个?
静态方法是知道调用它的类或实例的任何信息的方法。这是一个逻辑上属于类的方法,但是没有隐式参数。
静态方法既可以在类上调用,也可以在它的任何实例上调用。
类方法是一种传递给被调用的类的方法,就像self
传递给类中的其他实例方法一样。类方法的强制参数不是类实例:它实际上是类本身。
类方法的一个典型用例是提供另一种构造实例的方法:这样做的类方法被称为类的工厂。
这里有一个 Employee 类,它使用一个类方法来创建一个实例,该方法与该类的主构造函数略有不同。
14-举例说明如何使用 zip 和 enumerate
zip
函数将多个可迭代对象作为输入,并将它们聚集在一个元组中。例如,如果您想同时遍历两个列表,这可能会很有用。
enumerate
函数允许循环遍历一个 iterable 并同时访问运行索引和 item。
15 —在给定的函数中,如何使用*args 和**kwargs?
*args 和**kwargs 通过接受可变数量的参数使 Python 函数更加灵活。
- *args 在列表中传递可变数量的非关键字参数
- **kwargs 在字典中传递可变数量的关键字参数
这里有一个函数的例子,它接受可变数量的关键字参数,这些参数被收集在一个名为data
的字典中(注意,它不需要被命名为kwargs
作者提供的图片—使用**kwargs 的函数
16-给出一个使用 map 的函数式编程的例子
continue 和 break 语句之间有什么区别
break
语句终止包含它的循环。程序立即移动到循环外部范围内的代码部分。
作者图片
另一方面,continue
语句跳过当前迭代的剩余代码,并转移到下一次迭代。
作者图片
18 —如何防止函数被调用不必要的时间?
使用缓存。
如果与给定输入相关联的输出在一段时间内没有变化,那么使用缓存对函数来说是有意义的。
一个典型的场景是查询一个 web 服务器:如果您第一次查询一个 URL,并且您知道响应不会改变,那么您可以缓存结果。
19 —给出一些 PEP8 准则
- 每个缩进层次使用 4 个空格。
- 进口应按以下顺序分组:
- 标准库导入。
- 相关第三方进口。
- 特定于本地应用程序/库的导入。
- 函数名和变量名应该小写并用下划线隔开
- 类名使用 CapWords 约定。
20 —如何在一台内存为 2GB 的电脑上读取一个 8GB 的 Python 文件?
这个解决方案适用于任何大(甚至更大)的文件。
当您打开文件时,您需要做的就是将 file 对象用作迭代器:在遍历这个 file 对象时,您将一次获取一行,前面的行将从内存中清除(即它们被垃圾收集)。
这样,文件永远不会完全加载到内存中,您的处理将在移动中完成。
参考📖
- https://www . analytixlabs . co . in/blog/python-interview-questions-for-data-science/
- http://wiki.python.org/moin/GlobalInterpreterLock
- https://stack overflow . com/questions/986006/how-do-I-pass-a-variable-by-reference
- https://medium . com/content square-engineering-blog/multi threading-vs-multi processing-in-python-ECE 023 ad 55 a
- https://peps.python.org/pep-0008/
- https://stack abuse . com/python-class method-and-static method-explained/
感谢阅读🙏
这是我在面试中经常看到的一些问题的概述。我希望你已经从他们身上学到了一些东西。
我错过了什么重要的事情吗?请在评论中告诉我。
今天就这些了。以后的帖子再见!👋
新到中?你可以每月订阅 5 美元,并解锁各种主题的无限文章(技术、设计、创业……)你可以通过点击我的推荐链接来支持我
https://ahmedbesbes.medium.com/membership
PySpark RDD 的 20 个非常常用的功能
原文:https://towardsdatascience.com/20-very-commonly-used-functions-of-pyspark-rdd-90b8271c25b2
由 Unsplash 上的闪光灯 Dantz 拍摄
每个功能都用清晰的例子演示
Apache Spark 在大数据分析领域非常受欢迎。它使用分布式处理系统。PySpark 是 Python 中 Apache Spark 的接口。当你有一个万亿字节大小的巨大数据集时,常规的 python 代码会非常慢。但是 PySpark 算法要快得多。因为它将数据集分成更小的部分,将数据集分布到不同的处理器中,在每个处理器中分别执行操作,然后将它们重新组合在一起,得到总输出。
这是 PySpark 如何更快工作的高级概述。本文将重点介绍 PySpark 中一些非常常用的函数。
如果是初学者,可以用 google-colab 笔记本练习一下。您只需使用以下简单的命令行进行安装:
pip install pyspark
只需几分钟即可完成安装,笔记本电脑将准备好 PySpark 代码。
首先,需要创建一个 SparkContext,这是 Spark 功能的主要入口点。它代表与火花簇的连接。我在这里创建了一个 SparkContext:
from pyspark import SparkContext
sc = SparkContext.getOrCreate()
我将从最基本的函数开始,向更便于分析的函数发展。
sc.parallelize()
在这里,我使用并行化方法,用这个 SparkContext 创建了一个非常简单的 RDD 对象。并行化方法创建一个并行化的集合,允许数据的分布。
rdd_small = sc.parallelize([3, 1, 12, 6, 8, 10, 14, 19])
您不能像在笔记本中打印常规列表或数组一样打印 RDD 对象。
。收集()
如果您简单地键入 rdd_small 并在笔记本中运行,输出将如下所示:
rdd_small
输出:
ParallelCollectionRDD[1] at readRDDFromFile at PythonRDD.scala:274
所以,它是一个 parallelCollectionRDD。因为这些数据在分布式系统中。你必须把它们收集到一起,才能作为一个列表使用。
rdd_small.collect()
输出:
[3, 1, 12, 6, 8, 10, 14, 19]
当数据集太大时,收集整个 RDD 对象可能并不总是有意义。您可能希望只获取数据的第一个元素或前几个元素来检查数据结构、类型或数据质量。
在这里,我做了一个更大的 RDD 物体:
rdd_set = sc.parallelize([[2, 12, 5, 19, 21], [10, 19, 5, 21, 8], [34, 21, 14, 8, 10], [110, 89, 90, 134, 24], [23, 119, 234, 34, 56]])
。首先()
仅获取 RDD 对象的第一个元素:
rdd_set.first()
输出:
[2, 12, 5, 19, 21]
。采取()
这里我取前三个元素:
rdd_set.take(3)
输出:
[[2, 12, 5, 19, 21], [10, 19, 5, 21, 8], [34, 21, 14, 8, 10]]
我们得到前三个元素作为输出。
。文本文件()
此时,我想引入一个文本文件来演示几个不同的功能。
我从美国的维基百科页面复制了一些文本,用一个简单的记事本制作了一个文本文件。该文件保存为 usa.txt。您可以通过以下链接下载该文本文件:
https://github.com/rashida048/Big-Data-Anlytics-Pyspark/blob/main/usa.txt
以下是如何使用文本文件创建 RDD:
lines = sc.textFile("usa.txt")
让我们使用。再次使用()函数查看文件的前 4 个元素:
lines.take(2)
输出:
["The United States of America (U.S.A. or USA), commonly known as the United States (U.S. or US) or America, is a country primarily located in North America. It consists of 50 states, a federal district, five major unincorporated territories, 326 Indian reservations, and nine minor outlying islands.[h] At nearly 3.8 million square miles (9.8 million square kilometers), it is the world's third- or fourth-largest country by geographic area.[c] The United States shares land borders with Canada to the north and Mexico to the south as well as maritime borders with the Bahamas, Cuba, Russia, and other countries.[i] With a population of more than 331 million people,[j] it is the third most populous country in the world. The national capital is Washington, D.C., and the most populous city and financial center is New York City.", '']
。平面地图()
将文本内容分开进行分析是一种常见的做法。下面是使用 flatMap 函数按空间分割文本数据并生成一个大的字符串列表:
words = lines.flatMap(lambda x: x.split(' '))words.take(10)
输出:
['The', 'United', 'States', 'of', 'America', '(U.S.A.', 'or', 'USA),', 'commonly', 'known']
前 10 个元素现在看起来像这样。
。地图()
如果要对 RDD 的每个元素应用某种变换或使用某个条件,该映射会很有用。在这种情况下,每个元素意味着每个单词。在这里,我将使每个单词小写,并将通过在每个单词上加 1 来将每个单词转换为一个元组。
wordsAsTuples = words.map(lambda x: (x.lower(), 1))wordsAsTuples.take(4)
输出:
[('the', 1), ('united', 1), ('states', 1), ('of', 1)]
下面是对发生的事情的一点解释。lambda 表达式中的“x”表示 RDD 的每个元素。你对 x 做的任何事情都适用于 RDD 中的每一个元素。
在这里,我们将“x”转换为(x,1)。所以,每个单词都是(word,1)。仔细查看输出。
。reduceByKey
如果有一个键-值对,并且您希望将同一个键的所有值相加,那么这个函数非常有用。例如,在上面的 wordsAsTuples 中,我们有键-值对,其中键是单词,值是 1。通常,元组的第一个元素被认为是键,第二个元素是值。
如果我们在 wordsAsTuples 上使用 reduceByKey,它会将我们为同一个键添加的 1 相加(这意味着相同的单词)。如果我们有 4 个“the”,它将加上 4 个 1,并将使它(' the ',4)
counts = wordsAsTuples.reduceByKey(lambda x, y: x+y)
counts.take(3)
输出:
[('united', 14), ('of', 20), ('america', 1)]
因此,在我们的文本数据中,“united”出现了 14 次,“of”出现了 20 次,“america”只出现了一次。
。顶部()
返回指定的顶部元素。在这个例子之后,我将进一步解释:
counts.top(20, lambda x: x[1])
输出:
[('the', 55),
('and', 24),
('of', 20),
('united', 14),
('is', 13),
('in', 13),
('a', 13),
('states', 12),
('it', 9),
('to', 7),
('as', 6),
("world's", 6),
('by', 6),
('world', 5),
('with', 5),
('american', 5),
('war', 5),
('or', 4),
('north', 4),
('its', 4)]
这里发生了什么?在这个命令中,我们说我们想要前 20 个元素。然后 x[1]被指定为 lambda 表达式中的一个条件。在类似(' the ',55)的元组中,' the '是 x[0],55 是 x[1]。在 lambda 中,指定 x[1]意味着我们想要基于每个元素的 x[1]的前 20 个元素。因此,它根据文本文件中的出现次数返回前 20 个单词。
如果使用 x[0]作为 lambda 的条件,它将根据字母顺序返回前 20 名,因为 x[0]是一个字符串。请随意尝试。
。过滤器()
在上面的前 20 个单词中,大部分单词都不是很显著。像“to”、“The”、“with”、“in”这样的词不能提供对文本的任何洞察。在处理文本数据时,通常会忽略那些无关紧要的单词。尽管这并不总是一个好主意。
如果我们能排除一些无关紧要的词,我们可能会看到一些更有意义的词出现在前 20 名中。
以下是我在选择前 20 个单词之前想从文本中排除的单词列表:
stop = ['', 'the', 'and', 'of', 'is', 'in', 'a', 'it', 'to', 'as', 'by', 'with', 'or', 'its', 'from', 'at']
现在,我们将过滤掉那些单词:
words_short = counts.filter(lambda x: x[0] not in stop)
这个新 RDD 单词 _short 没有我们在‘stop’中列出的那些单词。
以下是现在最热门的 20 个单词:
words_short.top(20, lambda x: x[1])
输出:
[('united', 14),
('states', 12),
("world's", 6),
('world', 5),
('american', 5),
('war', 5),
('north', 4),
('country', 3),
('population', 3),
('new', 3),
('established', 3),
('war,', 3),
('million', 3),
('military', 3),
('international', 3),
('largest', 3),
('america,', 2),
('states,', 2),
('square', 2),
('other', 2)]
我们在“禁止”列表中没有这些词。
。sortByKey()
我们可以用这个对整个 RDD 进行排序。sortByKey()函数。顾名思义,它通过键对 RDD 进行排序。在“计数”RDD 中,关键字是字符串。所以,它会按字母顺序排序。
counts.sortByKey().take(10)
输出:
[('', 3),
('(1775–1783),', 1),
('(9.8', 1),
('(u.s.', 1),
('(u.s.a.', 1),
('12,000', 1),
('16th', 1),
('1848,', 1),
('18th', 1),
('1969', 1)]
如你所见,空字符串先出现,然后是数字字符串。因为数字键在字母顺序中排在字母之前。
默认情况下,排序以升序给出结果。但是如果在 sortByKey 函数中传递 False,它会按降序排序。这里我们按降序排序,取前 10 个元素:
counts.sortByKey(False).take(10)
输出:
[('york', 1),
('years', 1),
('world.', 1),
('world,', 1),
("world's", 6),
('world', 5),
('with', 5),
('which', 1),
('when', 1),
('west.', 1)]
中排序之前应用函数或条件也是可能的。sortByKey 函数。这里有一个 RDD:
r1 = [('a', 1), ('B', 2), ('c', 3), ('D', 4), ('e', 5)]
在 RDD r1 中,一些键是小写的,一些键是大写的。如果我们按键排序,默认情况下大写字母会先出现,然后是小写字母。
r1.sortByKey().collect()
输出:
[('B', 2), ('D', 4), ('a', 1), ('c', 3), ('e', 5)]
但是,如果我们希望避免使用大小写部分,并且希望函数在排序时不区分大小写,我们可以在。sortByKey 函数。这里有一个例子:
r1.sortByKey(True, keyfunc=lambda k: k.upper()).collect()
输出:
[('a', 1), ('B', 2), ('c', 3), ('D', 4), ('e', 5)]
在上面的 lambda 表达式中,我们要求函数将所有键都视为大写,然后进行排序。它只将所有键视为大写字母,但不返回大写字母的键。
。groupByKey()
这个函数 groupByKey()根据键对所有值进行分组,并对它们进行聚合。**提醒一下,默认情况下,元组中的第一个元素是键,第二个元素是值。**在进一步讨论之前,我们先看一个例子:
numbers_only = wordsAsTuples.groupByKey().map(lambda x: sum(x[1]))
numbers_only.take(10)
输出:
[14, 20, 1, 1, 1, 6, 2, 13, 3, 1]
在这种情况下,关键词就是单词。假设“the”是一个键,当我们使用 groupByKey()时,它将这个键“the”的所有值分组,并按照指定的方式聚合它们。这里我使用 sum()作为聚合函数。所以,它总结了所有的值。我们得到了每个单词的出现次数。但是这一次我们只得到出现次数的列表。
。减少()
它用于减少 RDD 元素。减少数量 _ 只有我们从上一个例子中得到的:
total_words = numbers_only.reduce(lambda x, y: x+y)
total_words
输出:
575
我们得了 575 分。这意味着文本文件中总共有 575 个单词。
。地图值()
它可以用来对键值对的值进行某种转换。它返回键和转换后的值。下面是一个例子,其中键是字符串,值是整数。我将这些值除以 2:
rdd_1 = sc.parallelize([("a", 3), ("n", 10), ("s", 5), ("l", 12)])rdd_1.mapValues(lambda x: x/2).collect()
输出:
[('a', 1.5), ('n', 5.0), ('s', 2.5), ('l', 6.0)]
这里,lambda 表达式中的“x”表示值。所以,无论你对 x 做什么,都适用于 RDD 中的所有值。
再举一个例子会有助于更好地理解它。在本例中,使用了不同的 RDD,其中键是字符串,值是整数列表。我们将在列表中使用聚合函数。
rdd_map = sc.parallelize([("a", [1, 2, 3, 4]), ("b", [10, 2, 8, 1])])rdd_map.mapValues(lambda x: sum(x)).collect()
输出:
[('a', 10), ('b', 21)]
看看这里的输出。每个值都是值列表中整数的总和。
。countByValue()
以字典格式返回 RDD 中每个元素的出现次数。
sc.parallelize([1, 2, 1, 3, 2, 4, 1, 4, 4]).countByValue()
输出:
defaultdict(int, {1: 3, 2: 2, 3: 1, 4: 3})
输出显示了一个字典,其中键是 RDD 的不同元素,值是这些不同值的出现次数。
。getNumPartitions()
RDD 对象存储为元素簇。换句话说,一个 RDD 对象被分成许多分区。我们不做这些划分。这就是 RDDs 的本质。这是默认发生的。
集群可以为所有分区同时运行一个任务。顾名思义,这个功能。getNumPartitions()告诉你有多少分区。
data = sc.parallelize([("p",5),("q",0),("r", 10),("q",3)])data.getNumPartitions()
输出:
2
“数据”对象中有两个分区。
您可以使用. glom()函数来查看它们是如何划分的:
data.glom().collect()
输出:
[[('a', 1), ('b', 2)], [('a', 2), ('b', 3)]]
它显示了两个元素列表。因为有两个分区。
联盟
您可以使用 union 合并两个 rdd。例如,这里我制作了两个 rdd“rd1”和“rd2”。然后,我使用 union 将它们连接在一起,创建“rd3”。
rd1 = sc.parallelize([2, 4, 7, 9])rd2 = sc.parallelize([1, 4, 5, 8, 9])rd3 = rd1.union(rd2)rd3.collect()
输出:
[2, 4, 7, 9, 1, 4, 5, 8, 9]
新形成的 RDD“rd3”包括“rd1”和“rd2”的所有元素。
。独特()
它返回 RDD 的独特元素。
rd4 = sc.parallelize([1, 4, 2, 1, 5, 4])rd4.distinct().collect()
输出:
[4, 2, 1, 5]
我们只有“rd4”的独特元素。
。zip()
当我们在两个 rdd 上使用 zip 时,它们使用两个 rdd 的元素创建元组。一个例子将清楚地证明这一点:
rd11 = sc.parallelize(["a", "b", "c", "d", "e"])rdda = sc.parallelize([1, 2, 3, 4, 5])rda_11 = rdda.zip(rd11)
rda_11.collect()
输出:
[(1, 'a'), (2, 'b'), (3, 'c'), (4, 'd'), (5, 'e')]
在 zip 操作中,我们首先提到了“rdda”。因此,在输出中,“rdda”元素排在第一位。
连接
本文最后要做的是连接。这个名字已经告诉你它连接了两个 rdd。让我们再做一个类似‘RDA _ 11’的 RDD,然后我们就加入。
rddb = sc.parallelize([1, 3, 4, 6])rd22 = sc.parallelize(["apple", "ball", "cal", "dog"])
rdb_22 = rddb.zip(rd22)rdb_22.collect()
输出:
[(1, 'apple'), (3, 'ball'), (4, 'cal'), (6, 'dog')]
我们现在有‘RDB _ 22’。让我们将上一个示例中的“rdda_11”和“rdb_22”连接在一起:
rda_11.join(rdb_22).collect()
输出:
[(4, ('d', 'cal')), (1, ('a', 'apple')), (3, ('c', 'ball'))]
默认情况下,join 操作连接键上的两个 rdd。再次提醒,每个元组的第一个元素被认为是键。
在基本的连接操作中,只有两个 rdd 中的公共键元素连接在一起。
还有其他种类的连接。以下是左外部联接的一个示例:
rda_11.leftOuterJoin(rdb_22).collect()
输出:
[(4, ('d', 'cal')),
(1, ('a', 'apple')),
(5, ('e', None)),
(2, ('b', None)),
(3, ('c', 'ball'))]
因为这是左外部连接,所以左边提到的 RDD,在这种情况下,“rda_11”将带来它的所有元素。但是元素的顺序可能和‘RDA _ 11’不一样。右侧的 RDD 只会带来与左侧的 RDD 相同的元素。
还有一个右外部联接的作用正好相反:
rda_11.rightOuterJoin(rdb_22).collect()
输出:
[(4, ('d', 'cal')),
(1, ('a', 'apple')),
(6, (None, 'dog')),
(3, ('c', 'ball'))]
最后,有一个完整的外部连接,它从两个 rdd 返回每个元素。
rda_11.fullOuterJoin(rdb_22).collect()
输出:
[(4, ('d', 'cal')),
(1, ('a', 'apple')),
(5, ('e', None)),
(2, ('b', None)),
(6, (None, 'dog')),
(3, ('c', 'ball'))]
如您所见,这包含了来自两个 rdd 的所有密钥。
结论
我想列出最常用和最简单的 RDD 操作,它们可以处理很多任务。还有很多 RDD 行动。稍后我可能会拿出更多的。希望这是有帮助的。
请随时在 Twitter 、脸书页面上关注我,并查看我的 YouTube 频道。
更多阅读
https://pub.towardsai.net/data-analysis-91a38207c92b
2003–2023:大数据简史
原文:https://towardsdatascience.com/2003-2023-a-brief-history-of-big-data-25712351a6bc
总结 Hadoop 20 年的历史以及相关的一切
每当我进入一个 RPG 电子游戏的图书馆,我都会忍不住看看每个书架,以便更好地了解游戏的宇宙。有人记得《上古卷轴》里的“帝国简史”吗?
大数据,尤其是 Hadoop 生态系统,诞生于 15 年多一点的时间前,并以很少有人能预料到的方式发展。
自其诞生和开源以来,Hadoop 已经成为存储和操作 Pb 级数据的首选武器。围绕它形成了一个包含数百个项目的广泛而充满活力的生态系统,许多大公司仍在使用它,即使其他几个基于云的专有解决方案正在与之竞争。通过这篇文章,我旨在快速追溯 Hadoop 生态系统这 15 年的发展历程,解释它在过去十年中是如何成长和成熟的,以及大数据生态系统在过去几年中是如何不断发展的。
所以,系好安全带,开始 20 年的时间旅行,我们的故事从 2003 年开始,在旧金山南部的一个小镇...
免责声明:我最初的计划是用提到的公司和软件的徽标来说明这篇文章,但是在 TDS 上广泛使用徽标是被禁止的,我决定用随机的图像和无用的琐事来保持娱乐性。努力回忆当时我们在哪里,做了什么是很有趣的。
2003 年至 2006 年:开始
始于 2003 年 : iTunes,Android,Steam,Skype,Tesla。2004 年开始 : Thefacebook,Gmail,Ubuntu,魔兽世界。始于 2005 年 : Youtube,Reddit。始于 2006 年 : Twitter,蓝光。Waze,遗忘。(图片由罗伯特·安德森在 Unsplash 上拍摄)
这一切都始于千禧年之初,当时山景城一家名为 Google 的已经不算小的初创公司正试图索引整个已经不算小的互联网。他们必须面对两大挑战,但这两大挑战都没有得到解决:
如何在数千个磁盘上存储数百 TB 的数据,
跨越一千多台机器,而不会出现停机、数据丢失、
甚至数据不可用的情况?如何以一种高效且有弹性的方式并行计算,让
在所有这些机器上处理所有这些数据?
为了更好地理解为什么这是一个困难的问题,考虑当您有一个有一千台机器的集群时,总有平均至少有一台机器停机。
从 2003 年到 2006 年,谷歌发布了三篇研究论文,解释了他们的内部数据架构,这将永远改变大数据行业。第一篇论文发表于 2003 年,题目是“谷歌文件系统”。第二篇论文发表于 2004 年,标题为“ MapReduce:大型集群上的简化数据处理”,据谷歌学术称,从那以后,该论文被引用了 21 000 多次。第三个版本于 2006 年发布,标题为“ Bigtable:一个用于结构化数据的分布式存储系统”。即使这些论文对 Hadoop 的诞生至关重要,谷歌也没有参与其诞生,因为他们保留了自己的源代码。然而,这个故事背后的故事非常有趣,如果你没有听说过杰夫·迪恩和桑杰·格玛瓦特,那么你绝对应该读一读《纽约客》的这篇文章。
与此同时,Hadoop 之父,雅虎!员工名叫道格·卡丁,他已经是 Apache Lucene (位于 Apache Solr 和 ElasticSearch 核心的搜索引擎库)的创建者,正在从事一个名为 Apache Nutch 的高度分布式网络爬虫项目。像谷歌一样,这个项目需要分布式存储和计算能力来实现大规模。在阅读了谷歌关于谷歌文件系统和 MapReduce 的论文后,Doug Cutting 意识到他目前的方法是错误的,并从谷歌的架构中获得灵感,于 2005 年为 Nutch 创建了一个新的子项目,,他以他儿子的玩具(一只黄色的大象)命名:Hadoop。这个项目从两个关键组件开始:Hadoop 分布式文件系统()和一个 MapReduce 框架的实现。不像谷歌,雅虎!决定将该项目作为 Apache 软件基金会的一部分进行开源,从而邀请所有其他主要的技术公司使用并为该项目做出贡献,并帮助他们缩小与邻居的技术差距(雅虎位于山景城旁边的桑尼维尔)。正如我们将看到的,接下来的几年超出了预期。当然,谷歌也做得很好。
2007–2008:Hadoop 的早期采用者和贡献者
始于 2007 年 : iPhone、Fitbit、传送门、质量效应、生化奇兵、巫师。始于 2008 年:苹果应用商店、安卓市场、Dropbox、Airbnb、Spotify、谷歌 Chrome。(照片由莱昂纳多·拉莫斯在 Unsplash 上拍摄)
很快,面临类似容量分析问题的其他公司开始使用 Hadoop。在过去,这意味着巨大的承诺,因为他们必须自己安装和管理集群,并且编写 MapReduce 作业不是在公园散步(相信我)。雅虎!为了降低编写 MapReduce 作业的复杂性,微软推出了一款名为 的 Apache Pig 的 ETL 工具,它能够将自己的语言 Pig Latin 翻译成 MapReduce 步骤。但是很快其他人也开始为这个新的生态系统做贡献。
2007 年,一家名为脸书的年轻但发展迅速的公司,由 23 岁的马克·扎克伯格领导,在 Apache 许可下开源了两个新项目:Apache Hive,以及一年后的Apache Cassandra。Apache Hive 是一个框架,能够将 SQL 查询转换为 Hadoop 上的 Map-Reduce 作业,而 Cassandra 是一个宽列存储,旨在以分布式方式大规模访问和更新内容。Cassandra 并不需要 Hadoop 来运行,但随着 MapReduce 连接器的创建,它迅速成为了 Hadoop 生态系统的一部分。
与此同时,一家名为 Powerset 的不太知名的公司正在开发一个搜索引擎,他们从谷歌的 Bigtable paper 中获得灵感,开发了Apache h base,这是另一个依靠 HDFS 进行存储的宽列商店。Powerset 很快被微软收购,来自举一个新项目叫做Bing**。****
最后但同样重要的是,另一家公司在 Hadoop 的快速采用中发挥了决定性作用: Amazon 。通过启动第一个按需云 亚马逊网络服务 ,并通过 弹性 MapReduce 服务快速添加对 MapReduce 的支持,亚马逊允许初创公司轻松地在 s3(亚马逊的分布式文件系统)上存储他们的数据,并在其上部署和运行 MapReduce 作业,而没有管理 Hadoop 集群的麻烦。
2008–2012:Hadoop 供应商的崛起
2009 年开始:比特币、Whatsapp、Kickstarter、优步、USB 3.0。2010 年开始 : iPad,Kindle,Instagram。2011 年开始 : Stripe,Twitch,Docker,《我的世界》,Skyrim,Chromebook。(照片由斯潘塞·戴维斯在 Unsplash 上拍摄)
使用 Hadoop 的主要难点是设置、监控和维护 Hadoop 集群需要大量的工作。很快,第一家 Hadoop 厂商 Cloudera 于 2008 年成立,Hadoop 之父 Doug Cutting 很快加入其中。Cloudera 提出了 Hadoop 的预打包发行版,名为 CDH ,以及集群监控接口cloud era Manager*,最终使得安装和维护 Hadoop 集群以及 Hive 和 HBase 等配套软件变得非常容易。不久之后,出于同样的目的,Hortonworks 和 MapR 也成立了。2010 年 Datastax 成立时,卡珊德拉也有了自己的供应商。*
很快,每个人都同意,尽管 Hive 是处理大量 ETL 批处理的很好的 SQL 工具,但它不适合交互式分析和 BI。任何习惯于标准 SQL 数据库的人都希望它们能够在不到几毫秒的时间内扫描一个有 1000 行的表,而 Hive 需要几分钟(这是当你让大象做鼠标的工作时得到的结果)。这是一场新的 SQL 战争开始的时候,这场战争至今仍在肆虐(尽管我们将看到其他人从那时起也进入了舞台)。谷歌又一次间接地对大数据世界产生了巨大影响,它在 2010 年发布了第四篇研究论文,名为“ Dremel:网络规模数据集的交互式分析”。本文描述了两个主要的创新:一个分布式交互式查询架构,它将启发我们下面将要提到的大多数 interactive SQL 一个面向列的存储格式,它将启发几种新的数据存储格式,如由 Cloudera 和 Twitter 联合开发的Apache Parquet,以及由 Hortonworks 和脸书联合开发的Apache ORC。
受 Dremel 的启发,Cloudera 试图解决 Hive 的高延迟问题,并将其与竞争对手区分开来,于 2012 年决定启动一个新的开源 SQL 引擎,用于交互式查询,名为 阿帕奇黑斑羚 。 类似地,MapR 启动了自己的开源交互式 SQL 引擎,名为Apache Drill,而 Hortonworks 决定他们宁愿致力于使 Hive 更快,而不是从头开始创建一个新的引擎,并启动了Apache Tez,这是一种类似于 MapReduce 的版本 2* ,并对 Hive 进行了调整,以在 Tez 而不是 MapReduce 上执行两个原因可能推动了这一决定:第一,由于比 Cloudera 小,他们缺乏人力来采用与他们相同的方法,第二,他们的大多数客户已经在使用 Hive,他们宁愿让它工作得更快,也不愿切换到另一个 SQL 引擎。正如我们将看到的,很快许多其他分布式 SQL 引擎出现了,并且“每个人都比 Hive 快”成为了新的座右铭。*
2010–2014:Hadoop 2.0 和火花革命
始于 2012 年 : UHDTV、Pinterest、脸书活跃用户达到 10 亿,加南风格视频在 Youtube 上的浏览量达到 10 亿。2013 年开始:爱德华·斯诺登泄露 NSA 文件,React,Chromecast,谷歌眼镜,丨t丨e丨l丨e丨g丨r丨a丨m丨s丨,Slack。(照片由 Lisa Yount 在 Unsplash 上拍摄)
当 Hadoop 正在整合和添加一个新的关键组件时,https://hadoop.apache.org/docs/stable/hadoop-yarn/hadoop-yarn-site/YARN.html(另一个资源管理器)作为其官方资源管理器,这个角色以前由 MapReduce 笨拙地完成,当开源项目Apache Spark开始以前所未有的速度获得牵引力时,一场小革命开始了。很快就清楚了,Spark 将成为 MapReduce 的一个很好的替代品,因为它有更好的功能,更简单的语法,并且在许多情况下比 MapReduce 快得多,特别是由于它能够在 RAM 中缓存数据。与 MapReduce 相比,唯一的缺点是它最初的不稳定性,这个问题随着项目的成熟而逐渐消失。它还与 Hive 有很好的互操作性,因为 SparkSQL 是基于 Hive 的语法(实际上,他们一开始借用了 Hive 的 lexer/parser),这使得从 Hive 迁移到 SparkSQL 相当容易。它在机器学习领域也获得了巨大的牵引力,因为以前在 MapReduce 上编写机器学习算法的尝试,如Apache Mahout(现已退休)很快被 Spark 实现超越。为了支持 Spark 的快速增长并从中获利,其创始人于 2013 年创立了 Databricks。从那以后,它的目标是通过提供多种语言(Java、Scala、Python、R、SQL,甚至是 Java)的简单而丰富的 API,让每个人都能大规模地操作数据。NET)和许多数据源和格式(csv、json、parquet、jdbc、avro 等)的本地连接器。).值得注意的一件有趣的事情是,Databricks 采取了与其前辈不同的市场战略:不是提议对 Spark 进行内部部署(Cloudera 和 Hortonworks 很快将其添加到自己的平台上),Databricks 选择了纯云平台,从 AWS(当时最受欢迎的云)开始,然后是 Azure 和 GCP。九年后,我们可以有把握地说这是一个明智之举。**
与此同时,其他新兴科技公司开源了处理实时事件的新项目,如 阿帕奇卡夫卡 ,由 LinkedIn 制作的分布式消息队列,以及 阿帕奇风暴 ,由 Twitter 制作的分布式实时计算引擎。两者都是 2011 年开源的。此外,在此期间,亚马逊网络服务变得和以往一样受欢迎和成功:网飞在 2010 年令人难以置信的增长,主要是由亚马逊的云实现的,这本身就说明了这一点。云竞争对手终于开始出现,2010 年 微软 Azure 开始全面上市,2011 年 谷歌云平台 (GCP)。
2014-2016 年到达 Apex⁴
2014 年开始 : Terraform,Gitlab,炉石。2015 年开始:Alphabet,Discord,Visual Studio Code。(照片由威尔弗里德·桑特在 Unsplash 上拍摄)
从那时起,属于 Hadoop 生态系统的项目数量持续呈指数级增长。它们中的大多数在 2014 年之前就开始开发,其中一些在那之前就已经开源了。项目的数量开始变得令人困惑,因为我们到达了这样一个点,对于每一个需求,都存在多个软件解决方案。更高级别的项目也开始涌现,如,Apache Apex(现已退役)或Apache Beam(大多由 Google 推动),旨在提供一个统一的接口,在各种分布式后端(如 Apache Spark、Apache Flink 或 Google 的数据流)之上处理批处理和流处理。
我们还可以提到,由于 Airbnb 和 T2 的 Spotify,我们终于开始看到优秀的开源调度程序出现在市场上。调度器的使用通常与使用它的企业的业务逻辑联系在一起,它也是一个非常自然和简单的软件,至少在开始时是这样。然后你意识到,保持它的简单和便于他人使用是一项非常艰巨的任务。这就是为什么几乎每一家大型科技公司都编写并(有时)开源了自己的软件:Yahoo!sApache oo zie,Linkedin 的 阿兹卡班 ,Pinterest 的Pinball(现已退役),还有很多。然而,从来没有一个广泛的共识,其中之一是一个非常好的选择,大多数公司坚持自己的。好在 2015 年前后, Airbnb 开源Apache air flow,而 Spotify 开源Luigi⁵,这两个调度器迅速达到了跨其他公司的高采用率。特别是,气流现在可以在谷歌云平台和亚马逊网络服务上以 SaaS 模式使用。
在 SQL 方面,出现了其他几个分布式数据仓库,旨在提供比 Apache Hive 更快的交互式查询功能。我们已经谈到了 Spark-SQL 和 Impala,但我们还应该提到 Presto ,2013 年由脸书开源,2016 年已被亚马逊更名为 雅典娜 用于他们的 SaaS 发售,并在他们离开脸书后被其原开发者分叉为Trino。在专有方面,也发布了几个分布式 SQL 分析仓库,如谷歌的big query,2011 年首次发布,亚马逊的 红移,2012 年创立的 雪花 。
要获得作为 Hadoop 生态系统的一部分被引用的所有项目的列表,请查看此页面的,其中引用了超过 150 个项目。
2016–2020 集装箱化和深度学习的兴起,以及 Hadoop 的衰落
2016 年开始:奥库斯裂谷,Airpods,Tiktok。2017 年开始:微软团队,堡垒之夜。2018 年开始 : GDPR,剑桥分析公司丑闻,在我们中间。2019 年开始:迪士尼+、三星 Galaxy Fold、谷歌 Stadia(图片由 Jan Canty 在 Unsplash 上拍摄)
接下来的几年,一切都保持着加速和互联。跟上大数据市场中的新技术和公司变得越来越困难,因此长话短说,我将谈谈我认为对大数据生态系统影响最大的四个趋势。
第一个趋势是数据基础设施向云的大规模迁移,HDFS 被云存储取代,如亚马逊 S3 、谷歌存储或 Azure Blob 存储。**
第二个趋势是集装箱化。你可能已经听说过 Docker 和 Kubernetes。 Docker 是 2011 年推出的一个容器化框架,从 2013 年开始迅速流行起来。2014 年 6 月,Google 开源了其内部容器编排系统Kubernetes(又名【K8s】),该系统立即被许多公司采用,以构建其新的分布式/可扩展架构的基础。Docker 和 Kubernetes 允许公司为包括基于事件的实时转换在内的许多用例部署新型的分布式架构,更加稳定和可伸缩。Hadoop 花了一些时间赶上 docker,因为在 2018 年 3.0 版本中支持在 Hadoop 中启动 Docker 容器。
如前所述,第三个趋势是用于分析的完全托管的大规模并行 SQL 数据仓库的兴起。“现代数据栈”和 2016 年首次开源的 dbt 的崛起很好地说明了这一点。
最后,影响 Hadoop 的第四个趋势是深度学习的出现。在 2010 年的后半年,每个人都听说过深度学习和人工智能: AlphaGo 在围棋比赛中击败了世界冠军柯洁,这是一个里程碑,就像 20 年前 IBM 的深蓝与卡斯帕罗夫在国际象棋中的表现一样。这一技术飞跃已经实现了奇迹,并带来了更多希望,就像自动驾驶汽车一样,它经常与大数据联系在一起,因为它需要处理大量信息才能训练自己。然而,Hadoop 和机器学习是两个非常不同的世界,他们很难一起工作。事实上,深度学习推动了对大数据新方法的需求,并证明了 Hadoop 并不是万能的工具。
长话短说:从事深度学习的数据科学家需要两件 Hadoop 当时无法提供的东西。他们需要 GPU,这是 Hadoop 集群节点通常没有的,他们需要安装最新版本的深度学习库,如 Tensorflow 或 Keras ,这在整个集群上很难做到,特别是当多个用户要求同一库的不同版本时。Docker 很好地解决了这个问题,但是 Docker 对 Hadoop 的集成花了很长时间才变得可用,数据科学家现在就需要它。因此,与使用集群相比,他们通常更喜欢使用 8 个 GPU 来生成一个虚拟机。
这就是为什么当 Cloudera 在 2017 年首次公开募股时,他们已经将开发和营销重点放在了他们的最新软件 数据科学工作台 上,该软件不是基于 Hadoop 或 YARN,而是基于 Docker 和 Kubernetes 的容器化,并允许数据科学家将他们的模型作为容器化的应用程序部署到他们自己的环境中,而没有安全或稳定性问题的风险。
这不足以阻止他们的衰落。2018 年 10 月,Hortonworks 和 Cloudera 合并,仅保留 Cloudera 品牌。2019 年,MapR 被惠普企业(HPE)收购。2021 年 10 月,一家名为 CD&R 的私人投资公司以低于最初价格的股价收购了 Cloudera。
然而,Hadoop 的衰落并不意味着它的死亡,因为许多大公司仍在使用它,尤其是在内部部署中,并且围绕它构建的所有技术都在继续使用它,或者至少是它的一部分。创新也仍在进行。例如,新的存储格式是开源的,如最初在 2016 年优步开发的 阿帕奇胡迪*;2017 年网飞开始的 三角洲湖有趣的是,这些新文件格式背后的主要目标之一是规避我提到的第一种趋势的后果:Hive 和 Spark 最初是为 HDFS 构建的,HDFS 保证的一些性能属性在迁移到 S3 这样的云存储中丢失了,这导致了效率低下。但是我不会在这里深入讨论细节,因为这个特定的主题需要另一篇完整的文章。*****
2020–2023 现代
2020 年开始:新冠肺炎疫情。2021 年开始 : Log4Shell 漏洞,Meta,Dall-e .2022 年开始:乌克兰战争,中途,稳定扩散。(照片由乔纳森·罗杰在 Unsplash 上拍摄)
**如今,Hadoop 在云中的部署大多被 Apache Spark 或 Apache Beam⁶应用程序(大多在 GCP 上)所取代,从而有利于 Databricks 、亚马逊的 Elastic Map Reduce (EMR) 、谷歌、 Dataproc/Dataflow 或 *Azure Synapse。*我也看到许多年轻公司直接瞄准“现代数据堆栈”方法,围绕 SQL 分析仓库构建,如 BigQuery、Databricks-SQL、Athena 或 Snowflake,由无代码(或低代码)数据摄取工具提供,并使用 dbt 进行组织,这些工具似乎根本不需要 Spark 等分布式计算工具。当然,仍然倾向于本地部署的公司仍然在使用 Hadoop 和其他开源项目,如 Spark 和 Presto,但移动到云的数据比例每年都在增加,我认为目前没有理由改变这一点。
随着数据行业的不断成熟,我们也看到了更多的元数据管理和目录工具被构建和采用。在那个范围内,我们可以提到 2015 年由 Hortonworks 开始的Apache Atlas、2020 年由Amundsen、2019 年由 Lyft 开源、2020 年由data hub、Linkedin 开源。许多民营科技创业公司也出现在这个领域。
我们也看到了围绕新的调度器技术建立的创业公司,如 提督达格斯特 和Flyte,它们的开源库分别于 2017 年、2018 年和 2019 年开始,它们正在挑战 Airflow 目前的霸权。
**最后,湖畔小屋的概念已经开始浮现。湖库是一个结合了数据湖和数据 warehouse⁷.优势的平台这允许数据科学家和 BI 用户在同一个数据平台内工作,从而使治理、安全性和知识共享变得更加容易。由于 Spark 在 SQL 和 DataFrames 之间的多功能性,Databricks 是第一个创造该术语并将其定位于该产品的公司。紧随其后的是雪花与https://docs.snowflake.com/en/developer-guide/snowpark/index.htmlAzure Synapse以及最近的谷歌与 BigLake 。开源方面,dre mio提供了 2017 年以来的 lakehouse 架构。
谁能说出未来会是什么样子?
2023 年开始:谁知道呢?(安妮·斯普拉特在 Unsplash 上拍摄)
自从这一切开始以来,大数据世界中的开源项目和创业公司的数量逐年增加(只要看一看 2021 年的前景就知道它已经变得多么巨大)。我记得在 2012 年左右,有人预测新的 SQL 战争将会结束,真正的胜利者将最终出现。这还没有发生。所有这些在未来将如何发展很难预测。尘埃落定还需要几年时间。但如果让我做一些王尔德的猜测,我会做出以下预测。
- 正如其他人已经注意到的,现有的主要数据平台(Databricks、Snowflake、BigQuery、Azure Synapse)将继续改进并添加新功能,以缩小彼此之间的差距。我希望看到每个组件之间越来越多的连接,以及像 SQL 和 Python 这样的数据语言之间的连接。
- 未来几年,我们可能会看到新项目和公司的数量放缓,尽管这更多是因为新的互联网泡沫破裂后缺乏资金(如果这种情况真的发生的话),而不是缺乏意愿或想法。
- 从一开始,主要缺乏的资源就是熟练劳动力。这意味着,对大多数 companies⁸来说,投入更多资金解决性能问题,或者迁移到更具成本效益的解决方案,比花更多时间优化它们更简单。尤其是现在主要分布式仓库的存储成本变得如此低廉。但也许在某个时候,供应商之间的价格竞争将变得更加难以维持,价格将会上涨。即使价格不上涨,企业存储的数据量也在逐年增加,以及与之相关的低效率成本。也许在某个时候我们会看到一个新的趋势,人们开始寻找新的、更便宜的开源替代品,一个新的类似 Hadoop 的循环将再次开始。
- 从长远来看,我认为真正的赢家将是云提供商,谷歌,亚马逊和微软。他们所要做的就是等待和观察风向,等待时机,然后获得(或简单地复制)最有效的技术。集成到他们的云中的每个工具都让用户的工作变得更加简单和无缝,尤其是在安全性、治理、访问控制和成本管理方面。只要他们不犯重大的组织错误,我看现在没人能赶上他们。
结论
我希望你喜欢这次和我一起的回忆之旅,它能帮助你更好地理解(或者简单地回忆)这一切是从哪里以及如何开始的。我试图让这篇文章便于所有人理解,包括非技术人员,所以请不要犹豫,与您的同事分享,他们有兴趣了解大数据来自哪里。
最后,我想强调的是,如果没有开源和知识共享的神奇力量,人类在人工智能和大数据方面的知识和技术永远不会发展得如此之快。我们应该感谢最初通过学术研究论文分享知识的谷歌,我们应该感谢所有开源项目的公司。在过去的 20 年里,开源和免费(或至少廉价)获取技术一直是互联网经济创新的最大驱动力。20 世纪 80 年代,一旦人们买得起家用电脑,软件创新就真正开始了。3D 打印也是如此,它已经存在了几十年,在 21 世纪初随着自我复制机器的出现而腾飞,或者是推动 DYI 运动的树莓派的出现。
开源和轻松获取知识应该永远被鼓励和争取,甚至比现在更多。这是一场永无止境的战斗。一场这样的战斗,也许是最重要的一场,这些天正在与 AI 进行较量。大公司确实为开源做出了贡献(例如谷歌和 TensorFlow),但他们也学会了如何使用开源软件如 venus flytraps 来吸引用户进入他们的专有生态系统,同时保留专利背后最关键的(也是最难复制的)功能。
我们继续尽最大努力支持开源和知识共享(如维基百科)对人类和世界经济至关重要。政府、公民、公司以及最重要的投资者必须明白这一点:增长可能由创新驱动,但创新是由与大众分享知识和技术驱动的。
“做你必须做的。无论发生什么”(写在巴黎人文小教堂墙上的句子)
脚注
:如果算上来自谷歌的前传,甚至是 20 年,因此得名。
:也许在 2022 年,我们在硬件可靠性方面取得了足够的进步,使这一点不那么真实,但 20 年前肯定是这样。
:2016 年, Twitter 开源 Apache Heron (好像还在 Apache 孵化阶段)取代 Apache Storm。
⁴:一语双关。
⁵:2022 年, Spotify 决定停止使用 Luigi,转而使用 Flyte
⁶::我怀疑 Apache Beam 主要用在有数据流的 GCP 上。
⁷: 正如 Databricks 所说的,lakehouse 将数据湖的灵活性、成本效益和规模与数据仓库的数据管理和 ACID 事务结合在一起。
⁸:当然,我这里说的不是像优步的网飞那么大的公司。
更好地压缩 GIS 要素
原文:https://towardsdatascience.com/2022-051-better-compression-of-gis-features-9f38a540bda5
深潜
替换 JSON、XML 和 Shapefile 格式,以改善访问者的体验
压缩大型数据集可能是获得和失去潜在用户的区别。(图片由约瑟夫·洪顿提供。)
使用在线地理信息系统(GIS)制图工具讲述数据密集型故事需要仔细规划。如果我们提供的数据太少,我们的故事就不会产生应有的影响。如果我们提供太多的数据,我们就有失去不耐烦的用户的风险,这些用户不愿意为下载大型 GIS 文件多等几秒钟。
因此,我们工作的一个重要部分是确保我们将 GIS 数据打包成尽可能紧凑的形式。
我一直在使用全球数据集,用地球的交互式正投影(T2)来讲述故事。以下是一些有用的策略,用于优化使用基于 web 的可视化工具访问大型 GIS 文件所需的时间。
基线案例
作为案例研究,使用了世界的个国家的自然地球形状文件(ne_10m_admin_0_countries)
。以下是它包含的内容:
- 258 个表示国家及其外围区域轮廓的要素。
- 每个特征的 161 个属性:名称、人口、地图颜色等。
- 474,443 个经度/纬度坐标对。
- shapefile 坐标的基线文件大小为 8.39 MB,加上其 dBase 属性的 794 KB。
在 10 米分辨率的交互式世界正投影上显示世界上的国家。(图片由约瑟夫·洪顿提供。)
作为一个案例研究,这是一个很好的优化候选。它太大了,不适合在 HTTP 连接上使用,尤其是与其他类似大小的数据集结合使用时。
GIS 文件格式的比较
ESRI shapefile 格式已经存在很长时间了,并且被每一个主要的 GIS 平台所支持。这对于希望分享作品的创作者来说非常有利。他们可以分发 shapefiles,并保证以最少的努力获得尽可能多的受众。
shapefile 格式最初是在 20 世纪 90 年代开发的,当时 GIS 还只是一项地方性事务。当时没有人想到可以远程执行 GIS,所以没有考虑优化文件传输时间。
随着 Web 2.0 运动的发展,在新千年开始时,XML 编码标准成为了惯例。地理标记语言 (GML)是一种 XML 文件格式,当时被认为是一种无所不包的交换格式。GML 计划成为开发新一代网络地图应用的催化剂。
几年后,谷歌开始使用另一种 XML 文件格式——Keyhole Markup Language(KML)——用于其新生的 Keyhole Earth 浏览器(现在称为谷歌地球)。大型 KML 文件很冗长,所以实际上它们通常被压缩成 KMZ 文件。
如今,JSON 文件通常用于网站数据,而不是 XML 文件。这主要是因为如此多的语言方便地支持解析和序列化。geoJSON 格式顺应了这一趋势。尽管 geoJSON 文件很方便,但它几乎和 XML 文件一样冗长。
geoJSON 的替代方案是由 Mike Bostock 和 Calvin Metcalf 开发的 topoJSON 文件格式。它利用了共享公共边界的要素之间存在的拓扑冗余。这对于多边形数据(如世界各国)尤其有利。
另一个选择是 GeoPackage 格式,它不会占用太多空间。它由跨平台 SQL 数据库中的一组标准化表定义组成。这意味着不需要特殊的导出和导入代码。文件经过优化,可供提供商和用户直接使用。
以下是每种格式的文件大小比较:
XML 和 JSON 文件的大小是原始 ESRI shapefile 的两倍。只有拉链 KML 更小。(使用 QGIS 生成的比较文件。)
属性最小化
当从 QGIS 保存为 geoJSON 文件时,默认坐标设置为 15 位十进制数字,我们的案例研究文件膨胀到 24.1 MB,是其初始大小的三倍!更好的坐标设置是 6 个十进制数字,这仍然可以在全球范围内提供 1 米的精度,但文件大小只会增加到 14.8 MB。
作为第一个优化——不管我们使用 XML、JSON 还是其他编码——我们可以删除所有无助于讲述我们故事的属性。对于这个案例研究,只保留了 3 个属性:NAME, MAPCOLOR7, POP_EST
。当其他 158 个属性被删除时,geoJSON 文件大约减少 1MB,变成 13.9 MB。
对于 countries 数据集,大部分文件都是由经度/纬度坐标消耗的,因此节省的空间并不大。但相比之下,另一个常用的数据集,世界城市地区(ne_10m_urban_areas)
包含 11,878 个要素。因此,对于该数据集,最小化每个要素的属性数量会导致更显著的减少。
Web 服务器压缩
将坐标精度降低到 6 位小数,并删除未使用的属性,这仅仅是个开始。考虑网络压缩技术的可用性也很重要。
Web 服务器压缩几乎总是能够大幅减少通过网络传输的字节数。所有 web 服务器和浏览器都理解三种content-encoding
可能性:deflate、gzip 和 brotli。
作为比较,以下是使用accept-encoding
请求头获取优化的 13.9 MB geoJSON 文件时,通过网络传输的实际字节数:
deflate
4.59 兆字节gzip
4.59 兆字节brotli
2.90 MB
相对较新的 brotli 方案在最小化传输的字节方面是明显的赢家。不利的一面是,brotli 方案需要在服务器上花费额外的时间来执行其相当复杂的压缩,因此必须预先缓存并准备好提供,这样才能真正节省时间。
HTTP 内容编码很容易获胜。请让您的 DevOps 工作人员进行设置。(显示的 Web 压缩统计数据来自 RWSERVE HTTP/2 服务器。)
如果您无法完成配置 web 服务器的任务,请让您的 DevOps 工作人员将这些设置添加到您的配置文件中:
content-types {
geojson application/geojson
topojson application/topojson
}
content-encoding {
application/geojson br,gzip,deflate
application/topojson br,gzip,deflate
}
cache-control {
`*.geojson` *instructions='public, max-age=86400'
`*.topojson` *instructions='public, max-age=86400'
}
另外,请记住在服务器和用户浏览器上都启用缓存。在服务器上缓存意味着将预压缩的数据集保存在一个可以立即访问的地方,而不必在每次请求时都重新压缩它。浏览器上的缓存意味着设置cache-control
响应头,这样用户就不必检索他们上次访问你的网站时保存的数据。
三种新的 GIS 编码
JSON 的便利已经变成了一根拐杖,我们经常会蹒跚而行,而不是昂首阔步。我们可以做得更好。
由于对当前的技术水平不满意,我对这个问题进行了深入的研究,并确定了几个改进的机会。
- JSON 文件语法很多,逗号、引号、花括号和方括号遍布其中。
- 每个特征的属性名称都是重复的*。*
- 两个相邻要素之间的边界共享一个公共坐标序列,一个沿顺时针方向,另一个沿逆时针方向。
- 生成的格网上的经度和纬度由多个要素共享,这是一个明显的冗余,应该加以利用。
- 文本文件存储数字效率低下,精度有限。
- 文本文件需要分隔符(空格或逗号)来分隔数据。
接下来的三种文件编码是我对这些问题和机会的解决方案:
- 地理要素编码(GFE)
- 索引坐标编码
- 拓扑弧编码(TAE)
它们在 GDAL 的ogr2ogr
转换工具中还不可用;尽管如此,因为它们是用 JavaScript 编写的,所以使用 gcsio 包的序列化器和解析器在浏览器和 Node.js 主机上都是可用的。
地理要素编码(GFE)
地理要素编码文件格式删除了所有额外的双引号、花括号、硬括号和逗号,它们在 JSON 文件中占据了大量空间。在内部,该文件仍然是纯文本,因此任何文件编辑器都可以用来显示其内容或进行微小的编辑。
当打开查看时,GFE 文件看起来有点像一个老派的制表符分隔的文件,但有了新的面貌。这里有一个展示文件自描述性质的例子。文件的其余部分包含经度、纬度和我们选择保留的三个属性值。
!gfe 1.0
!dataset ne_10m_admin_0_countries
!geometry Polygon
!properties 5
lngRings,latRings,NAME,MAPCOLOR7,POP_EST
lngRings,latRings,string,string,string
!features 258
. . .
除了自描述的特性,GFE 格式还能够在同一个文件中序列化和解析多个数据集。这对于顶点、边和面的规则模式共享公共坐标的情况尤其重要。
索引坐标编码(ICE)
ICE 格式更进一步,利用了具有重合折点的数据集。这是通过构建由多个要素共享的经度和纬度值的索引列表来实现的。
ICE 文件看起来类似于 GFE 文件,但是增加了一个保存唯一经度和纬度值的部分。在这种方案中,单个要素将其坐标存储为短整数索引,而不是长浮点值。
拓扑弧编码(TAE)
一些面(如案例研究文件)具有很长的经度/纬度对序列,这些序列通常定义两个相邻要素之间的公共边界。如果这些序列可以被识别,那么它们可以被两个特征重复使用。
TAE 分析器能够识别两个要素共有的公共弧。有了这些信息,特征被重新加工成一系列圆弧参考,而不是一系列坐标对。圆弧参照是简单的整数值。
TAE 文件使用与前两种格式相同的通用自识别方案,并增加了一个拓扑弧部分。
二进制序列化
GFE、ICE 和 TAE 文件都存在文本文件固有的低效问题。第一,数字占用空间太大。其次,相邻的属性仍然需要用某种类型的空格来分隔,这样解析器才能正常工作。
它们互补的二进制文件格式是:
- 地理要素编码二进制(GFEBIN)
- 索引坐标编码二进制
- 拓扑弧编码二进制(TAEBIN)
对于二进制文件,浮点数没有这个问题。数字可以紧凑地存储在 1 字节、2 字节或 4 字节序列中。对 GIS 文件特别重要的是,经度和纬度都可以存储为一个 4 字节的压缩数字。压缩浮点值具有足够的精度,可以以 11 厘米的精度定位地球上任何地方的对象。相比之下,具有同等精度的十进制经度值“-179.876543”在文本文件中将占据 11 个字节。
二进制文件不需要空白分隔符——制表符、换行符和逗号在二进制文件中不起作用。
选择最佳优化
考虑最佳优化时,应考虑几个正交因素:要素数量、每个要素的属性数量、每个要素的平均折点数、所需的坐标精度以及拓扑共享程度。
以下是一些有帮助的指导方针:
- 线和点数据集通常使用简单的 GFE 编码效果最佳。
- 当要素位于共享同一经度或纬度的规则格网上时,ICE 编码将非常有用。
- 具有共享边界的多边形数据集可以利用拓扑,因此 TAE 是一个不错的选择。
- 二进制编码的压缩效果总是比文本编码好,所以大多数情况下选择 GFEBIN、ICEBIN 或者 TAEBIN。
- 当人的可读性很重要时,退回到基于文本的 GFE、ICE 和 TAE;例如,当调试数据集时,或者当预计要手动编辑要素时。
对于案例研究,结果文件大小为:
ICE
15.3 MB 原始/ 3.2 MB brotliTAE
13.6 MB 原始/ 2.9 MB brotliGFE
11.4 MB raw / 2.8 MB brotliICEBIN
7.6 MB 原始/ 2.8 MB brotliTAEBIN
6.0 MB raw / 2.6 MB brotliGFEBIN
4.5 MB 原始/ 2.2 MB brotli
这三种新格式的二进制编码的大小是文本的一半,brotli 压缩又将文件大小减少了一半。
不管文件格式如何,brotli 网络压缩无疑是赢家。但是要小心,因为服务器端的压缩需要时间。请确保预先缓存压缩文件,以便可以毫不延迟地提供该文件。
至于文件格式本身,“哪种格式把最多的数据挤进最小的空间”这个问题没有简单的答案。最好的工作流程是自动将源数据集转换为每种受支持的格式,然后比较它们的结果大小。当这不可能时,GFEBIN 是最好的通用默认设置。
我对 2022 年数据产品领导者的 10 大预测
原文:https://towardsdatascience.com/2022-predictions-for-data-products-f4e6512d6819
意见
我对 2022 年数据产品领导者的 10 大预测
照片由 莎伦 上 下
以下是对数据产品领导者和组织在 2022 年尝试在其软件、工具、应用和服务中利用 ML 和分析的十个预测。
从一个咨询产品设计师的角度。
是的,你的头对了。如果你的物理学、统计学、数学或工程学博士学位已经让你畏缩了,你可以从 12 号门离开这篇文章——我不会生气的!
我为什么要谈这个?
有足够多好奇、有抱负和经验丰富的数据产品领导者知道他们需要更多地关注使用 ML/AI 和传统分析的技术的人员、结果和体验方面。他们已经建立了足够多技术上正确但实际上错误的数据产品,知道数据科学、分析、统计和机器学习工程不足以让人们关心、采用决策支持技术和信任人工智能。
我今年的预测完全基于定性研究、讨论、对你、我的客户和我交谈过的人的接触——没有背后的大数据集!如果你想这样,只需走 3 个街区,右转经过卖报纸的邪恶丑陋的孩子的 Dunkin,跳上红线,在市区十字路口换车,穿过老 Filene 的地下室出口,你会找到 API 终点。如果你想要 API 或者洗手间的钥匙,你得回去问那个丑小孩。
现在,这个:
- 在研究和设计阶段没有让用户和利益攸关方在上游大量参与的数据产品将继续产生不产生成果的低使用率/无使用率产出。如果你不能接触到产品或服务的实际终端用户,你很可能会失败——即使技术努力似乎在进步。
- 人工智能/数据产品经理的角色将继续增长,但速度缓慢。(注:这是 IIA 今年的第四大预测)。我认为,由于各种原因,这些角色中的大多数人不会来自数字 PMs,但好的公司会努力吸引这种类型的人才。
- 在传统企业公司中,与基于项目的数据产品构建方法相比,在“产品”领域将会有缓慢但一定的增长。(部分是因为第二个原因)。
- 传统企业组织中的传统分析和数据科学团队。将开始看到缺乏设计或定义的 UX 在哪里损害他们的工作,可能会有一些招聘(甚至可能比#2 更少)。
- 数据科学和分析领域的咨询公司认为,引入设计资源可能会为客户提供更好的数据产品和服务,并在经历了“嘿,这对我们内部很有帮助”阶段后,将此视为竞争优势。
- 在 UX 和设计领域,将会出现更多的子专业团体和讨论(除了像米歇尔·卡尼的 MLUX、本·施奈德曼的 HCAI 新书发布会+团体、纳迪亚·皮特的 AI x 设计等之外)。)然而,总体数字仍然很低,这里的讨论要么会严重偏向道德领域,要么会受到最大的数字原生/方类型公司的观点和工作的影响。
- 老牌软件公司的设计领导,以及在较小程度上的产品领导将继续把他们的头埋在沙子里(抱歉!)关于他们的角色以及围绕数据和 ML/AI 的机会。在更成熟的 FANG 公司等之外,人工智能将主要继续意味着“聊天机器人”和推荐算法——看起来并不真正需要设计思维或输入的“功能”。传统企业组织中的数字/设计团队。还没有任何关于数据的正式或集中的观点,也不知道它如何改善 UX 客户、员工、合作伙伴、供应商等。
- 雇用具有(或愿意发展)良好人际交往、创造性和非技术技能的首席数据科学家的组织将看到巨大的优势,特别是当 ML 计划较少依赖手工编码、手工构建的解决方案时,并将在项目的采用/可用性/信任阶段面临最大的挑战。(又名“可操作化”,但我们不使用“围绕这些部分”这个词!)
- “拥有问题的团队”将比“被指派”到业务项目的“IT/数据团队”取得更大的成功——特别是在大型传统企业中,他们在需要用户“改变”他们的行为的定制应用程序中使用 ML/AI。越多的组织将数据科学/数字/分析视为合作伙伴和业务团队的一部分,创造的价值就越多。
- 到 2022 年,我将幸运地答对其中的 3/10,但没有人会知道,因为他们没有听我与道格·哈伯德的播客第 80 集如何衡量任何东西(尤其是数据产品的价值!).
- 有趣的事实: ML 不会被重新命名为“机器猜测”,尽管我很喜欢这个框架。
预测到此为止,但是如果你想了解更多关于这一切的来源,订阅我的洞察邮件列表。我定期撰写和发布关于数据产品领导者如何能够、应该并且正在使用设计驱动的创新来创建不可或缺的 ML 和分析解决方案的播客。
准备好了吗?
2022 年到了;我们走吧。
关于作者
Brian T. O'Neill 是一名咨询产品设计师,他帮助数据产品领导者使用设计驱动的创新来创建创新的 ML 和分析解决方案。他是 Designing for Analytics 的创始人和负责人,主持 体验数据 播客,并为麻省理工学院沙盒创新计划提供建议。不做咨询的时候,布莱恩也是一名职业音乐家,他作为打击乐手、鼓手和作曲家在世界各地巡回演出,比如卡内基音乐厅、肯尼迪中心和蒙特利尔爵士音乐节。
想在收件箱中获得更多关于创新数据产品设计的见解吗?
现在就订阅 | 🎧播客|designingforanalytics.com|领英 | 推特
2022 年俄罗斯数据科学和机器学习趋势
原文:https://towardsdatascience.com/2022-trends-in-data-science-and-machine-learning-in-russia-1cd9998696d7
超自动化,自动化,数据市场和更多…
刘玉英在 Unsplash 上的照片
2021 年,俄罗斯的数字和技术部门继续积极发展壮大。这增加了对数据科学和机器学习领域及其在俄罗斯的发展的影响。ML 和 ds 在线的顶级趋势有许多版本,这就是为什么我专门写关于俄罗斯的情况,这不仅与那些生活在那里的人有关,也与任何考虑与俄罗斯市场合作的专业人士或公司有关!
数据交换和数据市场
2021 年,俄罗斯的专家和管理人员终于清楚地认识到相互之间以及与开发人员共享数据的必要性。数据仍然分散并“锁定”在单个公司或财团内,然而,俄罗斯大型科技公司和政府官员优先考虑开发创新解决方案和技术,创建“智能城市”、“智能”交通系统、“智能”医疗和人们生活的其他“智能”领域,因此,显然有必要建立和自动化所有格式的数据交换:B2B、B2G、G2B、C2B 等。
由于这种发展,俄罗斯出现了一个新的市场——数据市场。它还很年轻,没有明确的规则,但它是 ML 和 ds 开发者走向光明未来的第一步。现在也变得很明显,这个市场将围绕着俄罗斯最大的科技公司,如 Sber、Yandex、VK(前 Mail.ru),也许还有最大的电信公司(Megafon、VimpelCom、MTS、Tele2)。由于“开放数据”政策,我们还可以考虑让政府机构参与这个新兴市场。
为了让这篇文章以实用的方式对你有用,我决定添加一些在俄罗斯可以获得的最好的公开数据源,这些数据源对外国人来说可能不是那么明显(如果你想继续阅读有关趋势的内容,可以直接跳到下一段):
- https://data.gov.ru/—官方开放数据门户。几乎所有你能想到的政府可以自由公开分享的东西;
- 【https://www.fedstat.ru/——官方统计数据的便捷探索;
- 【https://www.data-in.ru/data-catalog/——非政府机构,虽然直接与许多政府机构合作,但提供通常专门为 ML 和 DS 专家创建的数据集;
- https://www.cbr.ru/statistics/官方统计数据。不幸的是,它对 DS 和 ML 任务不是很有用,因为你只能以 PDF 格式下载它,然而,它仍然是一个很好的官方信息和数据的来源,如果你使用它的话会很有用;
- https://data.mos.ru/——莫斯科官方门户网站,提供数据集。他们人数不多,但是组织得很好,并且有一个英文版的网站;
- https://opendata.domclick.ru/—由 Sber 提供俄罗斯房地产市场数据的非政府门户网站;
- https://www.datacatalogs.ru/—非政府项目,包括广泛的数据来源列表(包括上面列出的一些)。主要包括有关俄罗斯的数据来源,但一些数据来源是国际性的。
我将在这里结束列表,因为这不是本文的主要目的,并且最后一个资源提供了关于这个主题的相当多余的信息!如果你想让我创建一个单独的俄罗斯数据源列表,请在下面的评论区联系我:)
作为“复杂”数据使用方式的超自动化
越来越多的公司开始接受数据的“复杂”使用。这意味着组织从简单的流程自动化转向复杂的汽车系统,包括物联网的使用。例如,工厂不仅监控来自生产线上安装的传感器的数据,还根据生产中收集的数据处理部署自动化生产控制。此外,我们将看到各行各业广泛采用数字化平台实现全面生产自动化。
一些俄罗斯大型工业公司已经在市场上寻找现成的复杂生产自动化解决方案,但现实是还没有现成的解决方案,他们必须从市场上找到的产品中构建定制的解决方案。
人工智能工程
在生活和商业的几乎每个领域,人工智能解决方案的采用都在增加。这涉及到创建人工智能解决方案的所有步骤:数据收集,预处理,数据标记,ML 算法的开发,测试,优化,部署。人工智能工程使简单 ML 模型的开发不仅适用于数据科学和机器学习专业人员,也适用于没有编程技能的行业专业人员。这包括数据准备和所谓的 AutoML 领域,它自动为 ML 专家做脏活:寻找最佳模型,调整超参数等。
尽管 AutoML 的目标是让每个人都容易使用,但现在它仍然主要是供数据科学家使用的。因此,AutoML 解决方案,即机器学习模型开发的自动化,在各种各样的领域中越来越受欢迎,大规模和小规模的公司和实验室都在投入精力进行该领域的研究。在俄罗斯,你还可以发现 Yandex 和 Sber 等科技巨头已经在该领域提供了他们的第一个解决方案。
生成人工智能
生成性人工智能是指在物理世界中创造新的信息片段甚至物体的人工智能(如果配备足够的仪器)。科技界的一个重大事件是 GPT-3 自然语言处理模型的出现,它被证明是如此强大,可以在化身的帮助下创作戏剧、歌曲、保持对话,以至于毫无准备的人不太可能理解他/她正在与一个人工智能说话。与此同时,GPT-4 模型预计将在未来几年发布,其规模和人工智能的“力量”将是前所未有的。
在俄罗斯,一方面,Sber 在 2020 年提出了 RuGPT-3 模型,它基本上是在大量俄语文本上重新训练的 GPT-2 模型。另一方面,Yandex 创建了自己的生成式 NLP 转换器家族,名为 YaLM(又一种语言模型),其中最大的一个拥有 130 亿个参数,现在为 Yandex 搜索引擎和他们的智能助手“亚里沙”提供支持。这里你可以玩它,但要注意——它只在俄语中有效:)
人工通用智能
另一个重要趋势是 AGI 的诞生——人工智能允许你解决生活和学习中不同领域的问题,重新训练人类可以学习的任何知识。这样的人工智能将为过渡到一个时代奠定基础,在这个时代,AGI 将学习如何至少做人类可以做的一切,并将以人类无法达到的速度进一步学习。然而,现在我们只能说,专家们已经“摸索”出了创造这样一个人工智能所需的向量。上述神经网络 GPT-4 就是对这一点的证实。这是一个全球趋势,我不会说俄罗斯目前在这一领域处于前沿。尽管这个话题在商业和政府界都有很高的兴趣。
AI-native
最后,一个重要的趋势,尤其是在俄罗斯,已经成为向“人工智能-本地”格式的数字解决方案开发的大规模过渡。也就是说,开发者从一开始就暗示,几乎每一个开发的数字产品中都存在某种形式的人工智能或独立的机器学习算法。在我看来,俄罗斯的情况尤其如此,因为它得到了国家计划“数字经济”和其他联邦项目的积极支持。
与此同时,不用说,现在几乎每个人都明白,如果他们的产品不是人工智能产品,他们就处于互联网繁荣时期的离线业务的相同情况下——竞争对手可以通过提供相同的产品但带有人工智能来随时抓住你。
总而言之,我想说的是,人工智能现在终于不像 2019 年那样被认为是一个“泡沫”,尽管仍有许多创业公司和小公司不会与在 R&D 部门投入大量美元的大型科技巨头进行激烈竞争。然而,创造一个真正的创新不总是很难吗?大公司不总是那些经常(但不总是)采用并加速“创业公司”创新的公司吗,或者有时只是个别天才?在机器学习和数据科学的世界中,有足够的空间容纳所有的创新者、加速器、投资者和采纳者!
只要继续做好你的工作,为人工智能的发展做出贡献,希望 2022 年会给我们带来更多令人兴奋的趋势,让我们离梦想的未来更近一步!
2022 世界杯模拟器使用数据科学,用 Python
原文:https://towardsdatascience.com/2022-world-cup-simulator-using-data-science-with-python-6bf56a543436
以下是我如何建立一个世界杯模拟器,并预测下一届世界杯冠军
照片由瑞德·路易斯在 Unsplash 拍摄
免责声明 1 :请勿将此用于博彩目的。这只是一个数据科学家做的数学实验。我不是一个给小费的人,我也不想对你的赌注提出任何建议。
免责声明 2: 本文与这些天卡塔尔发生的所有事件没有任何关系,也不是 2022 年卡塔尔世界杯的赞助商或反赞助商
所以,2020 年我们夺得欧洲杯后,意大利出局世界杯。作为一名意大利人,这让我非常失望。我们的国家是一个每天吃饭、睡觉、聊天、踢足球的国家。我记得意大利上一次赢得世界杯时,我还是个孩子。当我和家人在罗马我叔叔家的小电视上看这场比赛时,我还不到 10 岁。
我现在 25 岁了,住在美国,但那段记忆却永远印在了我的灵魂里。尽管本届卡塔尔世界杯给我们带来了诸多争议,但我仍然相信世界杯本身就是一个神奇的时刻。
问题是,今天我也是一名研究人员,我每天都在使用数据科学。我生命中的最后 4 年在大学里做数据科学和机器学习,我完全爱上了它。
所以我决定做的是建立一个数据科学算法(我不会恰当地称之为机器学习,但你将是裁判)来预测下一届世界杯版本的获胜者和整个锦标赛。
所以让我用几句话告诉你,你会在这篇文章中看到什么:
- 我们将为匹配结果建立某种概率函数
- 我们将基于我们提取的概率运行一个模拟
- 我们将多次运行模拟并提取一些统计数据
那就开始吧!
1.第一步
让我们先导入一些库:
我使用的数据集是一个关于比赛和一个国家队赢得或通过小组赛次数的数据集,我们将会看到。
现在我来做一些探索。让我们从显而易见的开始,看看每支球队之前赢得过多少次世界杯:
我们已经知道了,对吧?巴西 5 胜,意大利 4 胜,阿根廷 2 胜(迭戈)。
我们可以探索的另一件很酷的事情是,在 matches 数据集中,我们还有锦标赛的阶段。探究这一点很有意思,因为一个国家通过小组赛的次数明显地表明了该队的水平。
让我们来看看:
所以我们有很多小组赛,但只有几个淘汰赛。这完全有道理,因为,当然,你有多个小组,但只有一个淘汰阶段。
2.模拟概率分布
现在无聊的部分做完了,让我们进入我们将要如何模拟这届世界杯的细节。
我们有我们的球队和他们的比赛。假设你有团队 1(t1)和团队 2(T2)。一队赢这场比赛的可能性有多大?
作者图片
T2 和图也是一样。
现在,关于**抽签:**当然,两队在小组赛阶段可以抽签,但在淘汰赛阶段不能抽签。稍后我会告诉你如何处理。😉
类似于我之前所说的,我们可以找到一般情况下 t1 获胜的概率如下:
作者图片
当然,无论输赢都是一样的。
为此,我们需要下面的匹配列,我们称之为“结果”:
现在我们必须选出参加卡塔尔世界杯的队伍。这不是一个很大的工作量,我们可以从网站上复制和粘贴它。我是为你做的。
现在,我们必须将现有的数据与团队列表进行匹配。我们必须确保数据集中有所有将去卡塔尔的球队。
具有讽刺意味的是,卡塔尔是我们数据集中唯一没有的球队。我们以后再处理这个。我们暂且补充一个卡塔尔 _ 概率字典,这是一种杜撰的卡塔尔在世界杯上实际能赢多少场比赛的现实概率。
现在,如果我们想做概率转换,让我们使用以下函数:
让我们绘制一些随机结果:
现在,这一切都很酷,但我们需要做的是比赛的概率,而不仅仅是单个团队的概率。我们以下列方式应用上述规则:
现在,这个概率只有在两个匹配有匹配历史的情况下才有效。例如,这在法国和意大利行得通:
但是在这种情况下我们该怎么办呢?
现在。这是一个真正的问题。我没有答案,因为很难自动预测两支从未交手过的球队的结果。我们能做的是为每一次建立一个分数,并比较两个分数,以将它们转换为团队 1 获胜、团队 2 获胜或两个团队平局的概率。
我认为一个球队的好成绩就是球队通过小组赛的(归一化)次数。这当然是一个很好的点,表明了一个团队的质量。我们称之为 1 分。另一个需要考虑的重要事情是一支球队实际赢得世界杯的次数。我们称之为 2 分。由于 score_1 介于 0 和 1 之间,而 score_2 可以是 2、3 或 4,因此让我们将其乘以 0.5。所以给定一个团队 T,我们将有:
作者图片
所以如果我们有两个队,T_x1 和 T_x2,我们把 T_x1 赢的概率定义为 P(T_x1,T_x2),我们可以说:
作者图片
并且:
作者图片
但是这个概率的定义不允许我们画。所以我们宁愿说两个从未打过比赛的球队之间的平局概率是固定的,比如说 0.10。那么我们会说:
作者图片
作者图片
他们抽到的概率是:
作者图片
让我们以下面的方式实现这个想法:
1。获取团队分数的函数
2。将两个队的得分转换成概率的函数
*我们可以看到,卡塔尔的得分是 0.09。我从所有分数 1 分布的第一个 0 . 25 四分位数得到的。对于一支从未参加过世界杯的球队来说,这是一个合理的(低)数值。
3。用于提取比赛中两个队之间的结果概率的函数*
例如:
*我还确信,通过增加一些(小的)输赢概率,一个团队不可能有 100%的胜算
3.乐趣!
现在是时候让我们的模型运行了。我们必须为卡塔尔世界杯组建准确的小组。我们将让这个小组运行,一个小组将根据我们建立的概率赢、平或输。
我们还将建立算法淘汰阶段(A 组第一队对 B 组第二队,B 组第一队对 A 组第二队)。
我们将多次运行这个算法,然后选出获胜者。
让我一步一步来。让我们来定义这些组:
并将它们组合在一起:
例如,这是 B 组的概率:
基于这些概率,我们可以按以下方式运行模拟:这是针对给定组的:
这适用于所有组:
让我们为各组进行模拟:
让我们展示一些结果:
这些都是:
我不知道你怎么想,但是我认为这些结果是非常真实的。
让我们继续前进!
从分组来看,这是淘汰阶段:
这是整个锦标赛模拟:
这是整个锦标赛模拟的一个例子:
我们可以运行 10,000 次:
(需要一段时间)
以下是获胜者的统计:
其中一些令人惊讶(塞内加尔,哥斯达黎加,厄瓜多尔…,巴西和阿根廷不包括在内),一些相当可靠(西班牙,德国,英国)
我们可以稍微改变一下函数来决定冠军和亚军。
这实际上非常令人兴奋,我们可以得出很多结论。例如,荷兰在决赛中发挥很大作用,英格兰也是如此。尽管如此,西班牙在决赛中的胜场比这两支球队都多。我们可以继续分析。比如,伊朗进入了决赛(至少一次),但从未获胜。
4.考虑
在这篇文章中,我们模拟了下一届世界杯冠军。我们实际上模拟了整个比赛,我们抽取了冠军和第二队。
为此,我们采取了以下措施:
- 提取团队的统计数据
- 为几乎没有比赛记录的队伍建立一个分数系统
- 建立分组选择和淘汰阶段的算法
- 多次运行模拟。
- 提取结果。
有很大的改进空间。例如,我们可以考虑球队的实际质量,考虑他们的球员、教练和他们的状态。同时,让我们享受一些精彩的足球。🥰
5.结论
如果你喜欢这篇文章,你想了解更多关于机器学习的知识,或者你只是想问我一些问题,你可以:
A.在 Linkedin 上关注我,我在那里发布我所有的故事
B .订阅我的 简讯 。这会让你了解新的故事,并给你机会发短信给我,让我收到你所有的更正或疑问。
C .成为 推荐会员 ,这样你就不会有任何“本月最大数量的故事”了,你可以阅读我(以及成千上万其他机器学习和数据科学顶级作家)写的任何关于现有最新技术的文章。
你必须知道的 25 个 A/B 测试概念:面试复习
原文:https://towardsdatascience.com/25-a-b-testing-concepts-interview-cheat-sheet-c998a501f911
王牌面试一体化小抄
丹·克里斯蒂安·pădureț在 Unsplash 上拍摄的照片
面试中越来越多地问到 A/B 测试的问题,但准备这些问题的可靠资源仍然很少。假设你不久前完成了一门关于 A/B 测试的课程,并且对你对 A/B 测试统计的理解很有信心。现在已经有一段时间了,你有一个即将到来的采访,看在上帝的份上,你似乎不记得统计能力意味着什么或者 SUTVA 代表什么。或者你在目前的职位上一直在尝试,并且已经自动化了大部分流程。不需要手动步骤,你已经变得生疏了,需要一个快速的备忘单来回忆背后的重要概念和直觉,这样你才能在即将到来的面试中胜出。
使用这篇文章作为面试前你需要知道的 A/B 测试中最重要的概念的快速资源。你会发现最重要的概念的总结以及建立你的直觉的例子。
目录(点击下方跳到具体主题)
- 最基本的东西📚
总体、样本、样本均值、样本变异性 - 实验设计🎭
无效假设、关键指标、总体评估标准(OEC)、护栏指标、随机化单元、干扰 - A/B 检验统计&样本量计算 🧮
置信水平、误差幅度、置信区间、一类误差、二类误差、p 值、统计显著性、统计功效、最小可检测效应、实际显著性、样本量&持续时间 - 对实验有效性的威胁🚧
新奇效应、首因效应、季节性、星期效应
在我们开始之前,让我们建立一个 A/B 测试的例子,我们将利用它来复习概念。假设您正在一个网页上运行 A/B 测试,目标是提高点击率(CTRs)——您的原始网页,即控件使用文本“Save $25”提供了$25 的节省;通过此 A/B 测试,您将测试此网页的一个变体,它使用文本“节省 15%”以不同的方式呈现相同的报价(价值仍为 25 美元)。
作者图片
现在谈谈概念…
最基本的
- 人口——你要得出结论的是整个群体。在统计学中,总体是对某个问题或实验感兴趣的一组相似的项目或事件。在我们上面的例子中,真正的人群是将来会访问网页的每一个人。
- 样本 —样本是总体中代表较大总体特征的一小部分。通过统计分析,您可以使用从样本中收集的数据来对总体进行估计或测试假设。在 A/B 测试中,一个样本是随机选择的一组访问者,我们向他们展示我们的每一个页面变体——控制暴露于一个样本,处理暴露于另一个样本。
- 样本平均值 —对于给定的指标,这是基于为样本收集的数据的平均值。对于我们旨在优化点击率(点击率)的 A/B 测试示例,这只是每个样本中用户的平均点击率。
- 样本可变性 —从总体中随机选择的两个样本可能互不相同。无论我们从样本中得出什么样的结论,由于样本的可变性,我们的估计很可能会有误差。随着样本量的增加,抽样可变性将会降低。在 A/B 测试中,抽样可变性会影响我们所需的样本量,以便有机会得出具有统计意义的结果。
作者图片
试验设计
5。零假设——推断统计学基于这样一个前提,即你不能证明某事是真的,但是你可以通过发现一个例外来证明某事是假的。你决定你试图为什么提供证据——也就是另一个假设,然后你建立相反的假设作为零假设,并找到证据来反驳它。在我们的 A/B 测试示例中,零假设是原始页面上的总体 CTR 和页面变异没有不同。
作者图片
6。关键指标 —您试图通过实验优化的一组指标。一些常用的指标包括点击率(CTR)、注册率、参与率、平均每单收入、保留率等。可以想象,关键指标将与业务、okr 和目标的优先级相关。许多组织检查多个关键指标,并有一个当他们看到特定组合时愿意接受的权衡的心理模型。*例如,如果剩下的用户增加他们的参与度和收入,他们可能很清楚他们愿意失去多少用户(客户流失增加)。*这就把我们带到了 OEC 的解释下面。
7 .。总体评估标准(OEC) —当有多个指标需要通过实验进行优化时,通过设计一个称为总体评估标准(OEC)的单一指标来制定折衷方案是很有帮助的,总体评估标准本质上是这些目标的加权组合。一种方法是将每个指标标准化到一个预定义的范围,比如 0-1,并给每个指标分配一个权重。你的 OEC 就是一些标准化指标的加权值。在上面的例子中,需要评估客户流失和收入之间的权衡,LTV 可以用作 OEC。
8。护栏指标 —这些指标对公司很重要,不应受到实验的负面影响。例如,我们的目标可能是让尽可能多的用户注册,但我们不希望每个用户的参与度大幅下降。或者,我们可能希望提高应用参与度,但同时确保应用卸载不会增加。
9。随机化单元 —这是一个单元,例如应用随机化过程将其映射到控制或处理的用户或页面。适当的随机化对于确保分配到不同变异的人群在统计上相似是很重要的。应选择随机化单位,以满足稳定的单位治疗值假设(SUTVA)。SUTVA 指出,实验单元不会相互干扰,即测试和控制单元的行为是相互独立的。用户级随机化是最常见的,因为它可以避免用户体验不一致,并允许长期测量,如用户保留率。
10。干扰 —有时也称为溢出或泄漏,当对照组的行为受到给予测试组的治疗的影响时发生。这导致违反 SUTVA 假设,从而导致潜在的错误结论。推理可能有两种方式——
- 直接-如果两个单元是社交网络上的朋友,或者如果他们同时访问了相同的物理空间,则这两个单元可以直接连接。如果其中一个用于治疗,另一个用于控制,这将导致变异之间的干扰
- 间接—间接连接是由于某些共享资源而存在的连接。例如,如果 Airbnb 市场改善了治疗用户的转化流,导致更多预订,自然会导致控制用户的库存减少。类似地,在 Lyft/优步/Doordash 等市场中,控制和治疗用户可能共享同一群司机/司机,这也将面临干扰
样本量计算
11.置信水平 —置信水平是指当您多次抽取随机样本时,置信区间将包含真实总体参数的百分比或概率或确定性。在在线 A/B 测试的技术世界中,95%的置信水平是最常被选择的,但是你可以根据情况选择不同的水平。95%的置信水平意味着样本均值周围的置信区间有望在 95%的时间内包含真实均值。
12.误差幅度——正如我们之前提到的,由于抽样的可变性,你基于样本得出的关于人口的结论可能是不准确的。误差幅度告诉你你的结果与真实的总体值相差多少个百分点。例如,95%的置信区间和 4%的误差意味着在 95%的时间里,您的统计数据将在真实总体值的 4 个百分点以内。将误差幅度加到平均值上并从中减去,以确定置信区间(下面讨论)。
13.置信区间 —在统计推断中,我们旨在使用观察到的样本数据来估计总体参数。置信区间给出了可能包含未知总体参数的估计值范围,该估计范围是根据给定的一组样本数据计算的。置信区间的宽度取决于三个因素——感兴趣人群的变化、样本的大小和我们寻求的置信水平。
作者图片
14.第一类错误 —当我们错误地拒绝零假设时,就会出现第一类错误。*在我们的 A/B 测试示例中,如果我们得出的结论是治疗的总体均值不同于对照组的总体均值,而实际上它们是相同的,则会出现 I 型错误。*通过获得具有统计意义的结果来避免 I 型错误。
15.第二类错误 —当零假设为假,但我们错误地未能拒绝它时,就会发生第二类错误。*在我们的 A/B 测试示例中,如果我们得出结论,变异 B 的总体均值与变异 A 的均值没有不同,而实际上两者是不同的,那么就会出现第二类错误。*通过运行具有高统计功效的测试来避免这些错误。
作者图片
- P 值 — p 值是指如果测试的零假设为真,获得至少与我们看到的结果一样极端的结果的概率。p 值基本上告诉你你的证据是否让你的零假设看起来很可笑。
17.统计显著性 —当 p 值小于显著性水平时,达到统计显著性。显著性水平(𝛂)是您希望用于犯 1 型错误的概率的阈值,即得出控制和处理的总体均值不同而实际上它们相同的结论。换句话说,统计显著性是统计检验的 p 值小到足以拒绝零假设的另一种说法。科学标准是使用 p 值 0.05,即𝛂 = 5%。
18.统计功效 —统计功效,我们知道它是测试正确拒绝零假设的概率,即检测到最小效应的时间百分比,如果存在的话。
19.最小可检测效应(MDE) —您感兴趣检测的转化率的最小变化。在优化 CTR 的示例中,假设控件的 CTR 为 20%。您希望检测到的最小变化是相对于对照的 5%绝对升力,即治疗的 CTR 是否为 25%或更高。在这种情况下,5%是 MDE。
20.实际显著— 假设检验有可能产生具有统计显著性的结果,尽管其影响范围很小。这通常有两个原因——1)低抽样方差和 2)大样本量。在这两种情况下,我们可能能够检测出测试和控制之间具有统计学意义的甚至很小的差异。然而,这些在现实世界中可能并不重要。让我们以 A/B 测试为例,该测试向用户展示了一个新模块,并且能够检测到 CTR 存在 0.05%的差异,但是,对于如此小的升力,构建该模块的成本是否合理。在这种情况下,可行的实际有效升力是多少?
21.样本量 —在给定基线转换、最小可检测差异(MDE)、显著性水平&的情况下,达到统计显著性所需的单位数。“持续时间”指的是你需要多长时间来运行测试,以达到每个变量足够的样本量。
对实验有效性的威胁
作者图片
22.新奇效应——“有时会有‘新奇效应’在起作用。你对网站所做的任何改变都会引起你现有用户群的更多关注。把你网站上那个大的行动号召按钮从绿色改成橙色会让回头客更有可能看到它,哪怕只是因为他们之前已经把它关掉了。这种类型的影响不太可能长期持续——但它可能会人为地影响您的测试结果。
23.首因效应(Primacy effect)——当产品发生变化时,人们会做出不同的反应。一些用户可能习惯了产品的工作方式,不愿意改变。这就是所谓的首因效应。首因效应只不过是倾向于记住我们遇到的第一条信息,而不是后来呈现的信息。这可以被认为是一种与新奇效应相反的现象。
24.季节性 —企业可能在每月 1 日和 15 日有不同的用户行为。对于一些电子商务网站来说,它们的流量和销售额全年都不稳定,例如,它们往往在黑色星期五和网络星期一达到峰值。这些因素导致的可变性可能会影响您的测试结果。
25.星期几效应 —与季节性相似,指标可能基于星期几具有周期性。比如说,周四的转化率比周末高得多。在这种情况下,为整周的增量运行测试是很重要的,因此您包括了一周中的每一天。
结论
A/B 测试是最重要和应用最广泛的数据科学概念之一,在增长优化中有许多应用——无论是产品实验(优化入职流程、增加 CTR、服务器端优化等。)或用于营销收购(创意测试、增量测试、地理分割测试)等等。有这么多潜在的应用,很可能会在面试中对你的 A/B 测试知识进行评估——特别是对于产品数据科学/分析或营销数据科学/分析职位。
如果您想继续学习 A/B 测试概念和应用,请查看关于 A/B 测试的完整课程和面试指南。
感谢阅读!
矛盾的是,应对数据科学面试与其说是科学,不如说是艺术!更多来自我关于数据科学访谈或数据科学职业成长的内容, 订阅并关注 !
关注 领英!
人们在不告诉你的情况下使用的 25 种先进的熊猫功能
原文:https://towardsdatascience.com/25-advanced-pandas-functions-people-are-using-without-telling-you-b65fa442f0f4
ExcelWriter,因式分解,分解,挤压,T,遮罩,idxmax,剪辑,…
来自 Pexels 的 Caleb Oquendo 的照片
“我希望我能在熊猫身上做这个手术……”
很有可能,你可以!
Pandas 是如此的庞大和深入,它使您能够执行几乎任何您能想到的表格操作。然而,这种巨大有时会成为劣势。
许多优雅、高级的特性解决了罕见的边缘情况和独特的场景,但这些特性在文档中消失了,被更频繁使用的特性所掩盖。
这篇文章旨在重新发现这些特征,并向你展示熊猫比你所知道的更令人敬畏。
https://ibexorigin.medium.com/membership
获得由强大的 AI-Alpha 信号选择和总结的最佳和最新的 ML 和 AI 论文:
https://alphasignal.ai/?referrer=Bex
1.ExcelWriter
ExcelWriter
是创建 excel 文件的通用类(带工作表!)并将数据帧写入其中。假设我们有 2:
它有额外的属性来指定要使用的日期时间格式,您是否想要创建一个新的 excel 文件或修改一个现有的文件,当一个工作表存在时会发生什么,等等。查看文档中的详细信息。
2.pipe
照片由 莉亚·凯利 上 佩克斯
pipe
是 Pandas 中以简洁紧凑的方式进行数据清理的最佳功能之一。它允许您将多个自定义函数链接到一个操作中。
例如,假设你有接受自己参数的函数drop_duplicates
、remove_outliers
、encode_categoricals
。以下是如何在一次操作中应用这三种方法:
我喜欢这个函数如何类似于 Sklearn 管道。你可以用它做更多的事情,所以查看一下文档或者这篇有用的文章。
3.factorize
这个功能是 Sklearn 的LabelEncoder
的熊猫替代品:
与LabelEncoder
不同,factorize
返回两个值的元组:编码列和唯一类别列表:
4.explode
—🤯🤯🤯
照片由 约书亚·苏科夫 上Unsplash
一个名字很有趣的函数叫explode
。先看个例子再解释:
dirty
列有两行,其中的值被记录为实际列表。您可能经常在调查中看到这种类型的数据,因为有些问题接受多个答案。
explode
获取一个具有类似数组的值的单元格,将它分解成多行。将ignore_index
设置为 True 以保持数字索引的顺序。
5.squeeze
图片由cotton bro上 Pexels
另一个有着时髦名字的函数是squeeze
,用于非常罕见但令人讨厌的边缘情况。
其中一种情况是从用于数据帧子集的条件返回单个值。考虑这个例子:
即使只有一个单元格,它也会作为 DataFrame 返回。这可能很烦人,因为现在您必须再次使用.loc
和列名和索引来访问价格。
但是,如果你知道squeeze
,你就不必。函数使您能够从单个单元格数据帧或系列中删除坐标轴。例如:
>>> subset.squeeze()326
现在,只返回标量。也可以指定要移除的轴:
注意squeeze
仅适用于单值的数据帧或序列。
6.在...之间
照片由 贾斯汀做梦 上 像素
一个相当漂亮的函数,用于对一个范围内的数字特征进行布尔索引:
7.T
照片由Pixabay上的 像素 组成
所有数据帧都有一个简单的T
属性,代表转置。您可能不经常使用它,但是我发现它在显示describe
方法的数据帧时非常有用:
>>> boston.describe().T.head(10)
作者图片
波士顿住房数据集有 30 个数值列。如果您按原样调用【the DataFrame 将会水平拉伸,从而很难比较统计数据。进行转置将会切换轴,从而以列的形式给出汇总统计数据。
8.熊猫造型
你知道熊猫允许你设计数据框架吗?
它们有一个style
属性,打开了只受你的 HTML 和 CSS 知识限制的定制和样式的大门。我不会讨论你可以用style
做什么的全部细节,而只会向你展示我最喜欢的功能:
作者图片
上面,我们突出显示了保存一列最大值的单元格。另一个很酷的样式器是background_gradient
,它可以根据列的值给列一个渐变的背景颜色:
当您在一个有许多列的表上使用describe
并想要比较汇总统计数据时,这个特性特别方便。点击查看 styler 的文档。
9.熊猫选项
与 Matplotlib 一样,pandas 也有全局设置,您可以调整这些设置来更改默认行为:
这些设置分为 5 个模块。我们来看看display
下有哪些设置:
display
下有很多选项,但我主要使用max_columns
和precision
:
你可以查看文档来深入了解这个奇妙的特性。
10.convert_dtypes
我们都知道 pandas 有一个令人讨厌的倾向,就是将一些列标记为object
数据类型。您可以使用试图推断最佳数据类型的convert_dtypes
方法,而不是手动指定它们的类型:
不幸的是,由于不同日期时间格式的限制,它不能解析日期。
11.select_dtypes
我一直在用的一个函数是select_dtypes
。我认为从它的名字可以明显看出这个函数是做什么的。它有include
和exclude
参数,您可以使用它们来选择包含或排除某些数据类型的列。
例如,仅选择带有np.number
的数字列:
作者图片
或者exclude
他们:
作者图片
12.mask
照片由Pixabay上的 像素组成。
mask
允许您快速替换自定义条件为真的单元格值。
例如,假设我们有从 50-60 岁人群中收集的调查数据。
作者图片
我们将把 50-60 范围之外的年龄(有两个,49 和 66)视为数据输入错误,并用 NaNs 替换它们。
作者图片
所以,mask
用other
替换不满足cond
的值。
13.沿着列轴的min
和max
尽管min
和max
函数是众所周知的,但它们对于某些边缘情况还有另一个有用的属性。考虑这个数据集:
作者图片
上面的假数据帧是 4 个不同梯度增强库在 5 个数据集上的点性能。我们希望找到在每个数据集上表现最好的库。以下是你如何用max
优雅地做到这一点:
只需将轴更改为 1,就可以得到行方向的最大值/最小值。
14.nlargest
和nsmallest
有时,您不仅仅需要列的最小值/最大值。你想看一个变量的前 N 个或者~(top N)个值。这就是nlargest
和nsmallest
派上用场的地方。
让我们来看看最贵和最便宜的五大钻石:
作者图片
作者图片
15.idxmax
和idxmin
当您在列上调用max
或min
时,pandas 返回最大/最小值。然而,有时您想要最小/最大值的位置,这对于这些功能是不可能的。
相反,你应该使用idxmax
/ idxmin
:
您还可以指定columns
轴,在这种情况下,函数会返回列的索引号。
16.value_counts
同dropna=False
寻找缺失值百分比的常见操作是将isnull
和sum
链接起来,然后除以数组的长度。
但是,你可以用相关的参数对value_counts
做同样的事情:
埃姆斯住宅数据集的壁炉质量包含 47%的零。
17.clip
照片由 安 H 上 Pexels
异常值检测和去除在数据分析中很常见。
clip
函数使得找出超出范围的异常值并用硬限制替换它们变得非常容易。
让我们回到年龄的例子:
这一次,我们将把超出范围的年龄替换为 50 岁和 60 岁的硬性限制:
>>> ages.clip(50, 60)
快速高效!
18.at_time
和between_time
当处理高粒度的时间序列时,这两种方法会很有用。
at_time
允许您在特定日期或时间对值进行子集化。考虑这个时间序列:
作者图片
让我们选择下午 3 点的所有行:
>>> data.at_time("15:00")
作者图片
很酷吧。现在,让我们使用between_time
来选择自定义间隔内的行:
作者图片
注意,这两个函数都需要一个 DateTimeIndex,并且它们只处理时间(如在点)。如果你想在日期时间间隔内子集化,使用between
。
19.bdate_range
bdate_range
是一个创建具有工作日频率的时间序列指数的简写函数:
工作日频率在金融界很常见。因此,当使用reindex
功能重新索引现有时间序列时,该功能可能会派上用场。
20.autocorr
时间序列分析的一个关键部分是检查变量的自相关性。
自相关是简单的相关系数,但它是用时间序列的滞后版本计算的。
更详细地说,时间序列在lag=k
的自相关计算如下:
- 时间序列移动到
k
周期:
作者图片
2.计算原始tip
和每个lag_*
之间的相关性。
你可以使用熊猫的autocorr
功能,而不是手动完成所有这些操作:
你可以从这篇文章中了解更多关于自相关在时间序列分析中的重要性。
21.hasnans
Pandas 提供了一种快速的方法来检查一个给定的序列是否包含任何带有hasnans
属性的空值:
根据其文档,它可以实现各种性能提升。注意,该属性仅在pd.Series
上有效。
22.at
和iat
这两个访问器比loc
和iloc
快得多,但有一个缺点。它们一次只允许选择或替换一个值:
23.argsort
当您想要提取将对数组进行排序的索引时,应该使用此函数:
作者图片
24.cat
访问器
众所周知,Pandas 允许使用像dt
或str
这样的访问器对日期和字符串使用内置的 Python 函数。
Pandas 还有一个特殊的category
数据类型用于分类变量,如下所示:
当一个列为category
时,您可以使用cat
访问器来使用几个特殊的函数。例如,让我们看看钻石切割的独特类别:
还有类似remove_categories
或rename_categories
等功能。:
你可以在这里看到cat
访问器下的完整函数列表。
25.GroupBy.nth
该功能仅适用于GroupBy
对象。具体来说,分组后,nth
从每个组中返回第 n 行:
>>> diamonds.groupby("cut").nth(5)
摘要
尽管像 Dask 和 datatable 这样的库正在以其处理海量数据集的闪亮新功能慢慢赢得 Pandas,Pandas 仍然是 Python 数据科学生态系统中使用最广泛的数据操作工具。
该库是其他软件包模仿和改进的榜样,因为它很好地集成到了现代 SciPy 堆栈中。
感谢您的阅读!
https://ibexorigin.medium.com/membership https://ibexorigin.medium.com/subscribe
更多来自我的故事…
https://ibexorigin.medium.com/28-weekly-machine-learning-tricks-and-resources-that-are-pure-gems-1-8e5259a93c94 </18-non-cliché-datasets-for-beginner-data-scientists-to-build-a-strong-portfolio-c59743b2a829>
埋藏在文件中等待被发现的 25 件宝贝
原文:https://towardsdatascience.com/25-numpy-treasures-buried-in-the-docs-waiting-to-be-found-60d8e17931cd
在 NumPy 致富
照片由陈信宏·K·苏雷什在 Unsplash 上拍摄
动机
每个数据科学家都钦佩某个人。对一些人来说,可能是那些创造了杀手级数据可视化的人;对其他人来说,就是任何回答他们 StackOverflow 问题的人。对我来说,是那些像忍者一样使用 NumPy 的人。
我不知道。我一直认为,在罕见的极端情况下,能够使用深埋在文档中的被遗忘很久的函数,说明了一个程序员的技能。为一个特定的任务重新发明轮子是具有挑战性的,但这并不总是你想要的。
这个月,是时候扭转乾坤,成为一名忍者了。一路上我都在说“为什么我不把别人也做了呢?”。因此,我在这里列出了一些最酷但罕见的 NumPy 函数,当使用它们时,肯定会让任何阅读您的代码的人大吃一惊。
https://ibexorigin.medium.com/membership
获得由强大的 AI-Alpha 信号选择和总结的最佳和最新的 ML 和 AI 论文:
https://alphasignal.ai/?referrer=Bex
1️⃣.np.full_like
我打赌你用过像ones_like
或zeros_like
这样的标准 NumPy 函数。嗯,full_like
和这两个完全一样,除了你可以创建一个和另一个形状一样的矩阵,填充一些自定义值。
💻演示
这里,我们正在创建一个pi
的矩阵,形状为array
。
📚文档:链接
2️⃣.日志空间
我相信你经常使用linspace
。它可以在一个间隔内创建自定义数量的线性间隔数据点。它的表亲logspace
更进一步。它可以在对数标度上生成均匀分布的自定义点数。您可以选择任何数字作为基数,只要它不是零:
💻演示
📚文档:链接
3️⃣.网络网格
这是你只能在文档中看到的功能之一。我以为它暂时不会公开使用,因为我很难理解它。像往常一样,斯达克弗洛来拯救我们了。根据这个线程,您可以使用meshgrid
从给定的 X 和 Y 数组创建每个可能的坐标对。这里有一个简单的例子:
将有 16 个唯一的坐标对,结果数组中每个索引到索引元素对一个。
当然,meshgrid
通常用于更复杂的任务,如果使用循环的话,将会花费很长时间。绘制 3D 正弦函数的等值线图就是一个例子:
💻演示
📚文档:链接
4️⃣.triu/tril
类似于ones_like
或zeros_like
,这两个函数返回高于或低于某个矩阵对角线的零。例如,我们可以使用triu
函数在主对角线上方创建一个具有真值的布尔掩码,并在绘制关联热图时使用该掩码。
💻演示
如你所见,用triu
创建的蒙版可用于相关矩阵,以去掉不必要的上三角和对角线。这使得热图更加紧凑,可读性更好,没有杂乱无章。
📚文档:链接 — np.triu
5️⃣.拉威尔/拉平
NumPy 是关于高维矩阵和 n 数组的。有时候,你只是想把这些阵列粉碎成 1D。这是您可以使用ravel
或flatten
的地方:
💻演示
他们看起来一样吗?不完全是。flatten
总是返回一个 1D 副本,而ravel
试图生成原始数组的 1D 视图。所以,要小心,因为修改从ravel
返回的数组可能会改变原始数组。要了解更多关于它们区别的信息,请查看这个 StackOverflow 线程。
📚文档:链接
6️⃣.np.vstack / np.hstack
在 Kaggle 上,这两个函数是经常使用的。通常,人们对来自不同模型的测试集有多种预测,他们希望以某种方式集成这些预测。为了便于使用,必须将它们组合成一个矩阵。
💻演示
记住,在将每个阵列与这些阵列堆叠在一起之前,要对它们进行整形,因为默认情况下它们需要 2D 阵列。这就是我们使用reshape
函数的原因。这里,reshape(-1, 1)
表示将数组转换成一个尽可能多行的单列。
类似地,reshape(1, -1)
将数组转换为尽可能多列的单行向量。
📚文档:链接
7️⃣.np.r_ / np.c_
如果您像我一样懒惰,不想在所有的数组上调用reshape
,有一个更好的解决方案。np.r_
和np.c_
运算符(不是函数!)允许将数组分别堆叠为行和列。
下面,我们用 100 个概率模拟一个预测数组。为了将它们堆叠起来,我们用括号符号调用np.r_
(就像pandas.DataFrame.loc
)。
💻演示
类似地,np.c_
将数组堆叠在一起,创建一个矩阵。然而,它们的功能并不局限于简单的水平和垂直堆栈。他们比那更强大。要了解更多信息,我建议您阅读文档。
📚文档:链接 — np.r_
📚文档:链接 — np.c_
8️⃣.np .信息
NumPy 是如此的广阔而深邃。你很可能没有时间和耐心去学习它的 API 的每一个函数和类。面对未知函数怎么办?好吧,不要跑去找文档,因为你有更好的选择。
info
函数可以打印 NumPy API 中任意名称的 docstring。这里是用在info
上的info
:
💻演示
📚文档:链接
9️⃣.np .哪里
顾名思义,这个函数返回一个数组的所有索引where
某些条件为真:
💻演示
当在稀疏数组中搜索非零元素时,它特别有用,甚至可以在 Pandas 数据帧上使用,以便根据条件进行更快的索引检索。
📚文档:链接
1️⃣0️⃣.所有/任何
当与assert
语句一起使用时,这两个函数在数据清理过程中会很方便。
np.all
仅当数组中的所有元素都符合特定条件时才返回 True:
💻演示
因为我们创建了两个填充了随机数的数组,所以不可能每个元素都相等。但是,如果这些数字是整数,则更有可能至少有两个数字彼此相等:
因此,如果数组中至少有一个元素满足特定条件,any
将返回 True。
📚文档:链接 — np.all
📚文档:链接——np.any
1️⃣1️⃣.np.allclose
如果您想检查两个长度相等的数组是否是彼此的副本,一个简单的==
操作符是不够的。有时候,你可能想比较浮点数组,但是它们的长小数位数很难比较。在这种情况下,您可以使用allclose
,如果一个数组的所有元素在一定的容差范围内相互靠近,它将返回 True。
💻演示
请注意,只有当差值(<
)小于rtol
,而不是<=
时,该函数才返回 True!
📚文档:链接
1️⃣2️⃣.np.argsort
虽然np.sort
返回一个数组的排序副本,但这并不总是您想要的。有时,您需要对数组进行排序的索引,以便针对不同的目的多次使用相同的索引。这就是argsort
派上用场的地方:
💻演示
它来自于以arg
开头的一系列函数,这些函数总是从某个函数的结果返回一个或多个索引。例如,argmax
查找数组中的最大值并返回其索引。
📚文档:链接
1️⃣3️⃣.np.isneginf / np.isposinf
这两个布尔函数检查数组中的元素是负无穷大还是正无穷大。不幸的是,计算机或 NumPy 不理解无穷大的概念(好吧,谁理解呢?).它们只能将无穷大表示为某个非常大或非常小的数字,它们可以放入一个比特位中(我希望我说得没错)。
这就是为什么当你打印出np.inf
的类型时,它会返回float
:
这意味着无穷大的值可以很容易地溜进一个数组,破坏你在浮点数上使用的操作。你需要一个特殊的功能来找到这些鬼鬼祟祟的小…
💻演示
📚文档:链接
1️⃣4️⃣.np.polyfit
如果你想执行一个传统的线性回归,你不一定需要 Sklearn。NumPy 为您提供:
💻演示
polyfit
可以获取两个向量,对它们应用线性回归,并返回一个斜率和一个截距。你只需要用deg
指定次数,因为这个函数可以用来逼近任意次多项式的根。
用 Sklearn 再次检查发现用polyfit
找到的斜率和截距与 Sklearn 的LinearRegression
模型相同:
📚文档:链接
1️⃣5️⃣.概率分布
NumPy 的random
模块有很多伪随机数发生器可供选择。除了我最喜欢的[sample](https://numpy.org/doc/stable/reference/random/generated/numpy.random.sample.html)
和[choice](https://numpy.org/doc/stable/reference/random/generated/numpy.random.choice.html)
之外,还有模拟伪完美概率分布的函数。
例如,binomial
、gamma
、normal
和tweedie
函数从各自的分布中提取自定义数量的数据点。
当您需要估算数据中要素的分布时,您可能会发现它们非常有用。例如,下面,我们检查钻石价格是否遵循正态分布。
💻演示
这可以通过在完美的正态分布上绘制钻石价格的 KDE 来实现,以使差异可见。
📚文档:链接
1️⃣6️⃣.np.rint
如果您想将数组中的每个元素四舍五入到最接近的整数,那么rint
是一个很棒的小函数。当您想要在二进制分类中将类概率转换为类标签时,可以开始使用它。你不必调用你的模型的predict
方法,浪费你的时间:
💻演示
📚文档:链接
1️⃣7️⃣.nan mean/nan *
您知道吗,如果至少有一个元素是NaN
,纯 NumPy 数组上的算术运算就会失败。
💻演示
要在不修改原始数组的情况下解决这个问题,您可以使用一系列的nan
函数:
以上是忽略缺失值的算术平均值函数的示例。许多其他人也以同样的方式工作:
但是如果你只处理 Pandas 数据帧或系列,你最好忘记这些,因为它们默认忽略 nan。
>>> pd.Series(a).mean()22.0
📚文档:链接——np.nanmean
1️⃣8️⃣.np .剪辑
当您想要对数组的值施加严格的限制时,clip
非常有用。下面,我们将剪切任何超出 10 和 70 这两个硬限制的值:
💻演示
📚文档:链接
1️⃣9️⃣.计数非零
使用稀疏数组是很常见的。通常,它们是对具有高基数的分类要素或仅仅许多二进制列进行一次性编码的结果。
您可以使用count_nonzero
检查任何数组中非零元素的数量:
💻演示
在 100k 个随机整数中,有~1000 个是零。
📚文档:链接
2️⃣0️⃣.np.array _ 斯普利特
列表中的最后一个函数是array_split
。我想你可以从名字中猜出它的作用——它可以用来将 N 个数组或数据帧分成 N 个桶。此外,当您想要将数组分割成大小不等的块时(如vsplit
),它不会引发错误:
💻演示
📚文档:链接
摘要
好吧,我在介绍中撒了点谎。我并不真正钦佩那些很好地使用 NumPy 的人。其实我很佩服任何比我更会用某个库或者工具的人。所以,我写的每一篇文章都是我试图推动自己,看看使用更有经验的人如此精心利用的东西是什么感觉。
https://ibexorigin.medium.com/membership https://ibexorigin.medium.com/subscribe
在你离开之前——我的读者喜欢这些。你为什么不去看看?
https://ibexorigin.medium.com/28-subtle-weekly-machine-learning-tricks-and-gem-resources-5-177f95be31c4 </20-python-gems-buried-in-the-installation-waiting-to-be-found-96034cad4d15>
2D 旋翼直升机机械和 PID 控制一体化
原文:https://towardsdatascience.com/2d-rotorcopter-mechanics-and-pid-control-with-unity-a3d9a3951a8a
模拟二维飞行,并在 Unity 引擎的帮助下学习 PID 控制回路
这篇文章介绍了如何使用 Unity 游戏引擎和 PID 控制器来实现一个二维四轴飞行器的飞行控制。这是最近实现的,这里记录了细节,希望对其他人有所帮助。
阿莱西奥·索格蒂在 Unsplash 上拍摄的照片
预期成果
遵循本教程中的演练应该希望提供以下内容:
- 模拟二维四轴飞行器飞行的统一环境,准备进行实验。
- 对 PID 控制器如何在 Unity(和其他地方)中作为控制系统使用有一个基本的了解。
- 旋翼机二维动力学基础。
所有覆盖的代码以及工作项目都可以在这个 GitHub 的资源库中找到。如果您不关心如何以及为什么获取代码的演练,可以直接跳到模拟部分。
开始之前
为这个模拟做了一些决定。
为什么统一? Unity 配备了一个复杂的物理引擎,使快速开发和实验变得快速简单。
**为什么只有二维?**旋翼机控制的问题很复杂,去除一个维度可以显著简化。一旦掌握了二维的控制,三维就能被解决。
为什么把 PID 控制器 ?有经验的 Unity 开发者可能想知道为什么使用 PID 控制而不是传统的路径技术。我们的目标是使用一个可以转化为现实世界的控制器。PID 控制器是自动调节系统的首选控制回路。
2D 四轴飞行器的基本知识
通过以 2 维而不是 3 维开始模拟,复杂性显著降低。
重要: 本文中,纵轴称为 y ,横轴称为*****【x****。这样做是为了保持与x-y2D 轴的一致性。在标准符号中,水平轴将被称为* y ,垂直轴将被称为 z (或x ⇒和y ⇒)。**
现役部队
无人机在任何给定时间都有三个合力作用于其上:
- ****每个推进器垂直于机架向上的可变向上力
- 恒定的重力直接向下,与框架的方向无关。
作者图片
只要四轴飞行器被定义为有质量的刚体,Unity 就照顾到了引力。转子的力(或推力)是控制系统必须管理的。
控制
模拟四轴飞行器的加速可以通过改变旋翼的推力来控制。
当四轴飞行器与地面水平时,加速度仅沿 y 轴施加。在这个方向上增加旋翼的推力会使四轴飞行器加速上升,而减少推力会使其加速下降。
作者图片
作者图片
当四轴飞行器相对于地面倾斜一个角度(我们将这个角度称为φ或 𝜙 )时,来自螺旋桨的力开始施加水平和垂直加速度。保持这个方向的推力增加了水平速度(y 轴)。
作者图片
或者…
作者图片
最后,为了改变四轴飞行器(或滚转**)的角度方向,转子之间的推力需要变化,以产生扭矩(或 力矩 ) 。该力矩与力和转子之间的距离之差成比例。**
作者图片
作者图片
注: 三维四轴飞行器还需要控制即电机旋转产生的扭矩(或力矩)。幸好只有 2D 没有第三次元让无人机向* 左右偏航 。***
上述动力学允许一个相当简单的控制系统,其中只需要确定四轴飞行器线性加速度的总推力和转子之间的旋转力差。这通常用 u1 和 u2 来表示,其中 u1 表示总推力,而 u2 表示总力矩。
作者图片
这些是 PID 控制器需要确定的值。
该控制系统
PID 控制器是一种控制回路方法,持续向系统提供输入(如推力、电压、电阻等)。)并基于系统随时间的表现来调整该输入。
总体思路是为 PID 控制器提供 3 个系数——位置、积分和微分。算法使用这些系数来确定当系统接近或远离其目标时如何缩放输出控制值。我们不会深入研究 PID 控制器工作原理背后的细节,但是强烈建议获得更多关于这个主题的知识。我发现这里的系列是一个很好的介绍。
系统采用 2 个 PID 控制器来解决 2D 四轴飞行器的控制问题;
高度控制器——为无人机提供将四轴飞行器驱动到所需高度所需的推力值。
姿态控制器——为无人机提供力矩值,帮助稳定飞机。
这是控制循环的样子。注意,只有所需的高度(y 轴)被提供作为整个系统的输入。控制器的工作是驾驶四轴飞行器到那个高度,同时确保平衡的方向。
作者图片
位置驱动——代表总控制回路输入——高度。
误差估计器 —负责向 PID 控制器提供期望状态(高度和中性方位**)和实际值之间的偏差的组件。**
PID 高度控制器 —该 PID 控制器使用来自误差估计器的位置误差来导出一个 u1 值或总体期望的垂直推力**。**
PID 姿态控制器 —该 PID 控制器使用来自误差估计器的方位误差来导出 u2 值或所需的扭矩**。**
马达混合算法(MMA) —该算法使用 u1、u2 并将它们与无人机的当前方位相结合,以确定每个旋翼所需的总推力。
工厂/无人机 —与环境交互并向系统提供实际状态值反馈的物理(或虚拟)无人机。
代码
所有这些都完成后,让我们开始构建实际的模拟。使用 Unity 是由于其内置的物理引擎。GitHub 库可以在这里找到,包含了一个模拟的工作实例。
一个人可能没有任何 Unity 的经验,但是强烈建议你至少熟悉一下,即使你没有任何游戏开发的愿望。Brackeys 有一些奇妙的资源,比如这个一个可以让你开始。
文件夹结构
该项目被组织成以下文件结构。
**├───**Prefabs**
│ ├───Quadcopter - prefab of the complete quadcopter
│ └───Thruster - prefab for a thruster object
├───**Scenes**
│ └───Main - the only scene in the project
├───**Scripts**
│ ├───PIDController - PID script obejcts
│ ├───Quadcopter - script for the quadcopter object
│ ├───FlightController - script to bring everything together
│ └───Thruster - script containing control for rotor objects**
现场
所有场景和摄影机默认值都将保留,场景仅使用以下对象进行更新:
作者图片
四轴飞行器——四轴飞行器,包含一个飞行控制器、一个刚体框架和两个推进器。
平台——为四轴飞行器提供稳定起飞面的静态刚体。
事件系统 —默认事件系统对象,由于未使用而被禁用。
主摄像机 —默认摄像机对象。
代码
这里可以找到https://github.com/adidinchuk/2d-unity-quadcopter-sim****。脚本对象是用几行值得注意的代码进行高级描述的。
推进器. cs
该脚本与每个旋翼相关联,并为四轴飞行器提供推力。在每个物理引擎滴答时,转子脚本使用推力系数和模拟叶片速度计算它应该产生的力。
可以通过调用 setRevolutionTarget() 函数并传递所需的 RPM 值来更新转子推力。然后,推进器使用 updateRevolutionRate() 功能不断更新 RPM 值,直到达到目标值。
四轴飞行器. cs
该脚本代表四轴飞行器对象,它被映射到附加的转子对象,并包含马达混合器算法代码。****
作者图片
通过乘以Cos(φ)来调整 u1 值,以说明重力,其中φ是无人机当前的角度方位角。 u2 值(力矩输入)正施加于左侧转子,负施加于右侧,以产生所需的力矩。
****注意,这些值作为力的单位直接传递给转子。这是可以做到的,因为 PID 控制系统的一般灵活性。控制回路根据系统的反应调整输入的大小。
PIDController.cs
这是主 PID 控制脚本,核心逻辑打包到 GetPIDOutput() 函数中。每次需要估计新值时,都会调用此方法。 p 、 i 和 d 是增益幅度, kP 、 kI 和 kD 是可以通过 FlightController.cs 脚本调整的系数,以改变 PID 控制器的性能。
这里的是学习 PID 控制逻辑的绝佳资源。
使用模型的先前积分值更新积分项,并且旨在为模型提供一种“记忆”。这有助于系统适应未知的变量,但也会给我们带来麻烦。例如,如果无人驾驶飞机离目标目的地仍有一段距离,但已经达到其最大速度,则积分项将继续增长超过最大值。这将导致次优减速,因为系统将不得不撤销卷起的过剩。更详细的解释可以在这里找到,它讨论了如果 PID 输出超过系统能力阈值,通过箝位(或停止累加)积分项来防止这种过饱和的概念。
FlightController.cs
这是将所有内容整合在一起的脚本。期望的位置和推力,以及滚转 PID 系数都可以通过这个对象来设置。
作者图片
在每次物理引擎更新时,该脚本计算当前的错误状态,将错误传递给 PID 控制器,并将产生的 u1 和 u2 值传递给无人机马达混合器算法。
模拟
repo 中的代码应该按原样运行,但是如何操作模拟的参数将在下面介绍。
推进器
无人机有左和右推进器,它们可以单独操纵,但是为了获得最佳效果,它们的参数应该是相同的。每个推进器也有一个具有规定质量(0.3)的刚体,这个刚体通过一个 2D 固定接头连接到主无人机机身上。****
作者图片
要配置的主推进器. cs 参数将是推力系数、最大 RPM、和旋转速率。****
四轴飞行器
四轴飞行器还有一个质量确定的刚体(1)以及一个简单的碰撞器,以防止它穿过地表平台。****
作者图片
旋翼和旋翼数在 Quadcopter.cs 脚本中设置,目标位置和 PID 控制系数在 FlightControl.cs 脚本中设置。
运行代码
当场景运行时,四轴飞行器离开地面,向指定的高度移动,并停留在那里。
*红色的 线 是显示推力的调试线。
可以修改 P 推力值,以改变无人机达到所需高度的速度。
比例项= 25,积分项= 2.5,导数项= 4 —图片由作者提供
D 推力值决定了我们的轨迹有多平滑,可以用来以收敛速度较慢为代价最小化超调。
比例项= 25,积分项= 2.5,导数项= 11 —图片由作者提供
I 推力值允许系统克服环境中不可预见的干扰,实现更平稳的恢复。无人机使用积分项值 2.5,这允许它考虑模型中完全忽略的重力。这是积分项设置为 0 时的情况——无人机未能达到目标高度 10。
比例项= 25,积分项= 0,导数项= 11 —图片由作者提供
除了俯仰之外,滚转 PID 系数提供相同的作用。这是当无人机的方向和位置受到干扰时的样子。
作者图片
结论
如果你走到这一步,你应该有一个工作的 2D 四轴飞行器 Unity 模拟,或者至少知道如何创建一个。在未来的文章中,我希望增加这种模拟的复杂性,包括自动运动规划和适应 3 维。
如果我有任何错误或遗漏了什么,请让我知道。也可以随意发表任何问题作为评论。
编码快乐!
原载于 2022 年 2 月 1 日 https://theappliedarchitect.comhttps://theappliedarchitect.com/learning-2d-rotorcopter-mechanics-and-control-with-unity/。****
在亚马逊 SageMaker 上运行 R 的 3 + 1 方式
原文:https://towardsdatascience.com/3-1-ways-of-running-r-on-amazon-sagemaker-13034a8f3686
借助云的力量点燃您的 R 工作负载;如何使用 SageMaker 笔记本、Studio、Jobs 和 RStudio
图片来源于 unsplash.com
R 编程语言是科学领域中最常用的语言之一,是机器学习中最常用的语言之一(可能仅次于 python ),也可以说是数学家和统计学家中最流行的语言。它易于上手,免费使用,支持许多科学和可视化库。
虽然 R 可以帮助您分析数据,但您拥有的数据越多,您需要的计算能力就越强,您的分析就越有效,就越需要可重复性和再现性。分析师和数据科学家需要找到满足这些要求的方法。进入云端。
在这篇文章中,我们简要描述了在云上运行 R 工作负载的主要方式,利用 Amazon SageMaker,这是 AWS 的端到端机器学习云产品。众所周知,AWS 为开发人员和科学家如何使用他们的产品提供了选择和灵活性,所以对于 SageMaker 来说这也是事实,不要感到惊讶。让我们看看怎么做。
SageMaker 经典笔记本
通过提供笔记本实例,SageMaker 在云上提供了完全托管的 Jupyter 笔记本体验。作为一项服务,与它的年轻兄弟 SageMaker Studio 相比,它的功能范围可能更小,但笔记本实例仍然是在 AWS 云上开始使用 jupyter 笔记本的最简单方式。
除了非常容易上手之外,您还获得了对 R 内核的开箱即用支持。
要尝试这一点,您可以打开一个笔记本实例,方法是转到 SageMaker 控制台>笔记本实例,然后创建笔记本实例(如果您还没有),保持默认设置。然后点击打开 Jupyter 或打开 JupyterLab
进入后,单击新建并选择 r。
在 Jupyter 启动 R 动力笔记本—左|在 Jupyterlab 启动 R 动力笔记本—右
就是这样!开始写你的 R 代码吧!
SageMaker 工作室笔记本
亚马逊 SageMaker Studio 是一个完整的云端机器学习 IDE。它是一个托管的 JupyterLab 环境,具有许多专门为允许您与 SageMaker 服务的其余部分进行交互而开发的附加特性。在 Studio 中,您可以快速启动 Jupyter 笔记本,只需几次点击,您就可以选择底层计算、关闭或共享笔记本。它附带了许多预制的内核,但它们都是 python 特有的。
幸运的是,就像几乎所有其他 SageMaker 服务一样,我们可以通过自带容器来定制它。
你猜对了——我们可以带来自己的支持 R 的容器,并定制 Studio 来满足我们的 R 需求。
要做到这一点,你可以按照下面的 GitHub 库上的说明,或者按照下面你自己的账户上的简单步骤:
在 Jupyter 笔记本上(是的,它可以是使用 python 的 Sagemaker Studio 笔记本)或者你的本地终端上设置了 AWS 凭证,
- 从上面的链接下载 DockerFile 文件,并运行以下几个命令:
2.等待上述命令运行完毕,这可能需要几分钟时间。
3.在 SageMaker 控制台中,点击“图像,然后点击“创建图像”。键入您在步骤 1 中创建的图像的 URI(如果步骤 1 成功运行,将在最底部打印图像 uri)。一旦你点击下一个,输入一个容易记忆的图像名称,比如studio-custom-r-image然后点击创建。
4.将映像附加到域。点击 SageMaker 域>向下滚动一点>附加图像。根据下面的截图,选择图像源作为您刚刚创建的图像。
单击下一步和下一步,然后在提交之前,为内核名称和内核显示名称键入一个容易记住的名称。然后点击提交。
5.打开 SageMaker Studio,使用新创建的内核创建一个笔记本。R-coding 快乐!
*注意:如果您不能立即看到可用的自定义图像,您可能需要重新启动您的工作室(数据不会丢失)
SageMaker 工作 APIs 处理、培训和部署
使用 SageMaker APIs,您可以加速处理和训练作业在临时集群上运行,为您提供可能需要的所有计算资源,而您只需为作业运行的秒数付费。为实时消费、批量推理、异步或无服务器推理部署您的模型也变得很容易。
对于您需要的计算运行时,您可以从支持的列表中选择,或者以 docker 容器的形式自带。
带上你自己的 R 容器,可以让你的 R 代码无缝地运行在 SageMaker 上。您可以按照这个 GitHub 示例来看看端到端会是什么样子。阅读我的中型博客如何为 SageMaker 作业创建可重用的 R 容器以详细了解如何在 AWS 帐户中创建这些容器,并重用它们来满足所有 R 需求。
SageMaker 上的 RStudio
陈京达在 Unsplash 上的照片
正如所承诺的,在 SageMaker 上有一个运行 R 的奖励方式,这是通过在 SageMaker 上使用 RStudio 实现的。SageMaker 上的 RStudio 是 SageMaker 服务家族中相对较新的产品,本质上是将您熟悉的 RStudio Workbench IDE 带到了云上。
如果您已经拥有 RStudio Workbench 的许可,您可以使用相同的许可在 SageMaker 上启用 RStudio。
关于如何开始的更多细节,你可以阅读亚马逊 SageMaker 上的博客【RStudio 入门。
这个工具允许你结合两个世界的优点。作为一名 R 开发人员,所有您喜欢的工具,以及您梦想中的云的所有处理云。
如果你对这个工具感兴趣,我强烈推荐你观看 Rstudio.com 网站上的一个很棒的视频。
结论
在这篇博客中,我们探索了几种在 Amazon SageMaker 的云上运行 R 代码的可能方式。
你更喜欢哪一个?
如果您想讨论您的使用案例以及如何在云上部署您自己的 R 工作负载,请联系我!
用 Python 表示数字数据的 3 种美观方式
原文:https://towardsdatascience.com/3-aesthetically-pleasing-ways-to-represent-numerical-data-in-python-ebc3572bd7db
数据可视化的艺术
Firmbee.com 在 Unsplash 上的照片
以易读的格式呈现数据对于正确的解释至关重要;我们经常利用数据可视化技术来排列数据,以便可以从视觉角度清楚地获得数据中包含的信息。这是因为我们理解视觉信息更自然——当视觉信息呈现给我们时,我们能更好地识别趋势、模式、异常值等。
了解可视化数据的最佳方式是一项挑战。有几种方法来表示一条信息,但在某些情况下,有些方法比其他方法更能提供信息。有一个清晰的问题,你试图用可视化来回答,这是朝着正确的方向迈出的一步。从那时起,你必须做的就是选择强调你想要研究的信息的图表。
本文的重点是数字数据。我们将介绍三种常见的图表,您可以用它们来表示数字数据。我们还将介绍它们的用法,如何解释它们,以及用 Python 实现它们。
**Table of Contents** --> [The data](#31b7)
--> [Scatter plot](#9c66)
--> [Histogram](#3835)
--> [Box Plot](#8461)
数据
为了演示我们将在本文中涉及的一些图表,我们使用 scikit-learn 的[make_regression](https://scikit-learn.org/stable/modules/generated/sklearn.datasets.make_regression.html)
函数生成了一个数据集。
我们的数据集将由 100 个样本和四个特征组成,其中四个是信息性的。我们还将高斯噪声的标准偏差应用于输出 10,并将random_state
设置为 25——但这些只是随机决定。
import numpy as np
import matplotlib.pyplot as plt
from sklearn.datasets import make_regression# Generate a regression problem
X, y = make_regression(
n_samples=100,
n_features=4,
n_informative=4,
noise = 10,
random_state=25
)# view first 5 observations
print(X[:5])"""
array([[-0.30756146, 0.88820421, -0.50315008, 0.89552899], [ 0.49830983, -1.35889534, -0.53652108, -1.14732055], [-0.58739664, 1.02036419, 0.56016947, 0.04803703], [-0.92340049, -0.56273293, 0.00384206, -0.41429594],
[ 0.46763613, -0.01500773, 0.02000411, -0.5443902 ]])
"""
散点图
散点图是可视化两个数值变量之间关系的重要工具。我们可以用它来更好地理解一个变量如何影响另一个变量。图中的每个点用来代表一个单独的观察值。
# generate line of best fit
m, b = np.polyfit(X[:, 2], y, 1)
best_fit = m*X + b# plotting
plt.subplots(figsize=(8, 5))
plt.scatter(X[:, 2], y, color="blue")
plt.plot(X, best_fit, color="red")
plt.title("The impact of feature at index 2 on target label")
plt.xlabel("Feature at index 2")
plt.ylabel("Target label")
plt.show()
作者图片
我们主要关注两个变量之间的关系。这意味着你用散点图回答的主要问题是是否有关系。
从你与同事、朋友和家人的关系中你可能知道,并不是所有的关系都是一样的。如果两个变量之间存在关系,您可以开始剖析这种关系的动态,以便更深入地了解数据。
关于您的变量,您可能想知道的一些事情有:
→关系的强度
→关系是正还是负
→关系是线性还是非线性
→是否存在任何异常值
上面的图像显示我们的数据集有一个积极的,相当强的,线性关系。在我们的数据中似乎也没有任何异常值,但是我们可以用箱线图进行复查。
柱状图
你可能还记得高中数学课上的直方图;直方图可能是表示统计数据最常用的图表。它们是了解数据集中数字要素总体分布的好方法。
它的工作原理是通过宁滨把数据分成不同的区间。然后将每个观察值放入一个适当的区间,通过每个条形的高度可以看到这个区间。直方图可用于了解我们正在处理的数据的密度,以及如何描述变量的分布。
plt.subplots(figsize=(8, 5))
plt.hist(X[:, 0], bins=10) #10 bins is the default
plt.xlabel("Feature at index 0")
plt.title("Distribution of feature at index 0")
plt.ylabel("Number of occurences")
plt.show()
作者图片
一些需要注意的事情包括偏斜度和模态:
- 偏度是一个实值随机变量关于其均值的概率分布的不对称性的度量来源 : 维基百科。特征的偏斜度可由以下四种偏斜度定义:正/右偏斜度、负/左偏斜度、对称/无偏斜度或未定义。
- 模态描述了数据集中的峰值数量。数据集可能是:单峰,这意味着它在数据分布中只有一个主峰,双峰,这意味着分布有两个主峰,均匀表示没有主峰,或者多峰表示分布有两个以上的主峰。
我们看到的数据看起来好像是对称的单峰的。
另一件要注意的事情是,我们为直方图选择的条块宽度是完全随机的。调整用于表示数据的条柱数量可以改变直方图所讲述的故事:太宽会丢失信息,太窄会越来越难以确定总体分布。理想的箱宽度对问题是主观的。
箱线图
箱线图是另一个很好的图表,可以更好地理解数据的分布。他们在突出异常值、四分位数范围和群体的中位数方面做得很好。此外,使用的空间要少得多,因此可以更容易地在同一个图表上比较不同组之间的分布。
plt.subplots(figsize=(8, 5))
plt.boxplot(X, vert=False)
plt.ylabel("Features")
plt.show()
作者图片
我们可以使用箱线图来确定每个特征的偏斜度、异常值以及组的最小值和最大值。
在数据的可视化中,我们可以确定我们所有的特征都是对称的。我们还可以看到,我们的第一个和第四个特征中存在异常值,这需要在现实场景中进一步研究。
数据可视化对于高效和有效地共享见解至关重要。非常有必要让我们的视觉化图像容易被设计的受众理解。实现这一点的一个关键因素是使用你的图表来回答听众感兴趣的问题。虽然我们没有在本文中分享一个全面的图表列表,但是您现在已经有了一个良好的基础,可以开始分享高质量的视觉洞察。
感谢阅读。
如果你喜欢阅读这样的故事,并希望支持我的写作,可以考虑成为一名灵媒。每月支付 5 美元,你就可以无限制地阅读媒体上的故事。如果你使用我的注册链接,我会收到一小笔佣金。
已经是会员了?订阅在我发布时得到通知。
https://kurtispykes.medium.com/subscribe
建立数据和分析团队时要遵循的 3 条动画电影台词
原文:https://towardsdatascience.com/3-animated-movie-quotes-to-follow-when-establishing-a-data-analytics-team-e7fd84357d84
未来数据和分析领导者的功夫熊猫名言
伊恩·施耐德在 Unsplash 上拍摄的照片
在我们开始之前,我想分享一段我个人感兴趣的话:
“我没有特别的天赋。我只是强烈好奇。”
——阿尔伯特·爱因斯坦
这一切是如何开始的
在我十年的经历中,我身兼数职——我是研究员、商业智能顾问、数据工程师,还是数据科学家和数据分析师的混合体。我不能称自己为任何领域的专家,但有一点是明确的——我的激情是数据,我的座右铭很简单:“你给我数据,我给你见解”。
然后,在我职业生涯的某个时刻,我得到了一个提议,由一小群从事“数据任务”的人组建数据和分析团队。
我的优势在于,我有一个已经在公司工作的两位同事的起点,并且用现代数据工具栈定义了数据架构。
我的缺点是我以前从未担任过领导职务。更不用说,我被所有的组织任务和赶上团队建立的相关流程淹没了。
长话短说,我的领导之旅就是这样开始的。
在做了一年多的数据和分析主管后,我将通过引用《功夫熊猫》动画电影中对人生有价值的话来分享建立团队最有益的个人技巧和诀窍。:)
《功夫熊猫》的引言与建立团队的技巧和诀窍相一致
“没有秘方。”
——平先生
事实上,建立数据和分析团队没有秘密可言。从我的经验中得到的最重要的提示是:在这个过程中获得支持,为团队选择“伟大的资产”。
让我们开始详细阐述这两个部分:
首先,记住你在这条路上并不孤单。
联系你的主管(C 级)和同事(TL 级)。虽然你对申请过程很熟悉,但你现在坐在桌子的另一边。最有价值的部分是来自你的上司/同事的支持,他们已经经历了同样的过程很多次了。他们可以分享自己在选择过程中需要注意的技巧和诀窍。
但是,请记住,您可以调整招聘流程,选择您认为会成为数据和分析团队重要资产的人。
其次,为你的团队选择“伟大的资产”。
这一步很棘手,因为最终的决定是你的,有时你需要依靠你的直觉。所以我的建议是:当你在组建一个团队时,不要雇佣那些只对一个领域有偏好的人,例如,纯粹的数据工程或数据科学。
相反,首先搜索数据从业者,即在不同领域处理任务没有问题的人。现在,让我们把事情弄清楚:这在每个组织中都是不可行的。换句话说,这取决于您正在使用的工具堆栈和您需要处理的用例的复杂性。
最后,雇佣渴望解决混合数据问题并喜欢了解不同领域的人是产生业务影响的最大资产。
“我可以控制果实何时落下。我可以控制在哪里播种。”
――师傅师傅
面对所有新的领导任务,不要忘记创建、共享和维护与组织愿景一致的清晰的数据和分析愿景。
将愿景与业务影响联系起来将会提高您的主管/同事的意识。因此,他们将更好地理解分析性见解如何简化他们的决策过程并产生更高的商业价值。
另一方面,与团队成员分享愿景将有助于他们理解组织发展战略,并展示他们的工作和贡献是多么重要。
记住,你是在两边播种。
在这个过程中,你可以遵循一些简单的提示来确保目标得以实现:
- 创建一个清晰的路线图,包含所有要处理的用例。
- 使用敏捷方法将用例分割成故事/任务,并在团队成员之间共享任务的所有权。
- 经常检查已交付的工作,并召开回顾会议,以确保您的团队在“大图”的轨道上。
“教功夫是一门需要多年才能掌握的艺术。”
――师傅师傅
随着时间的推移,您组织内对数据和分析团队的期望将会提高。
在这个过程中,你将需要获得新的工具,学习新的库甚至编码语言,并开发解决复杂分析用例的方法。因此,持续教育和知识共享对于数据和分析团队至关重要。
你可以用来掌握团队新需求的技巧和窍门:
- 促进团队成员和其他技术团队之间的内部知识共享和思想交流。
- 通过利用电子学习平台和咨询,提供外部知识共享机会。
- 在开始任何新的用例/任务之前,强调研究和业务理解的重要性。
寻找“气”
锡德·巴拉钱德朗在 Unsplash 上拍摄的照片
最后,我可以分享数据和分析团队最相关的组织成就的一年总结:
1 从数据从业人员,到现在团队成员涵盖的具体角色: **数据工程师、数据分析师、数据科学家。**相应地,任务被改编为每个角色。
2 通过这种方式,团队成员被告知未来的任务,并且对优先的用例有一个清晰的概念。
3 **角色之间的内部知识共享流程每周在回顾会议上进行。**然而,团队成员之间的支持,无论其角色如何,也是每天都存在的。
4 团队成员利用data camp和LinkedIn Learning平台,利用外部知识增长机会。此外,在处理更具挑战性的任务时,团队会得到咨询公司的支持。
5 最后但同样重要的是:数据和分析团队已经成为连接 IT 和业务团队的团队,并培养了更强大的数据文化。
参考文献:
[1]奥斯本,马克和约翰·斯蒂文森。2008.功夫熊猫。美国:梦工厂动画。
信用到期时的信用:
- 没有我周围领导的支持,建立数据和分析团队是不可能的。谢谢你们,弗洛里安,克里斯蒂安,斯蒂芬和克里斯托夫,感谢你们在这次旅程中的帮助。
- “气”在于创造团队的人。在撰写本文时,数据和分析团队由以下成员组成:nataa、Lukas、Rafael、Milan 和 Stefan 。
寻找缺失值的 3 种方法
原文:https://towardsdatascience.com/3-approaches-to-find-missing-values-ff656eba6902
学习处理不同类型缺失值的好方法
Ehimetalor Akhere Unuabona 在 Unsplash 拍摄的照片
引言
我将以一个“启示”开始这篇文章:现实世界中的数据集并不总是像 NaN 一样缺少值。
是的。他们可以是任何东西。在你浪费大量时间试图弄清楚该做什么之前,请继续阅读这篇短文,以获得处理这些类型数据的 3 种好方法。
首先我要给大家介绍一个缺失数据或者空值。
当列中的值未知或缺少时,使用数据集中的空值**。(改编自 docs.microsoft.com)**
上面的定义意味着无论何时你看到或南?、—,等等,不代表来自该变量或列的数据的一个观察值的所有内容,即缺失值或空值。
你将如何找到他们
很多时候,是的,null 值会以 Python 中著名的 NaN 或者 RStudio 中简单的 NA 的形式出现。在这些情况下,该值不会改变变量的数据类型。
其他时候,由于多种原因,数据可能会出现在由数据集创建者确定的特定文本符号下。例如,可以使用“无值”作为缺失值的代理。也可以是#或-,!或者别的什么。在这些情况下,变量的类型将被更改为字符串。
因此,如果您正在处理另一种数据类型,比如数字,就更容易注意到该列中有一个错误的值。如果你正在处理文本,它会稍微复杂一点,但是我们会看到该怎么做。
让我们看看如何处理每一种情况。
常见缺失值 NaN
首先,我将创建一个玩具数据集并导入一些库。
# imports
import pandas as pd
import numpy as np# Create a dataframe
df = pd.DataFrame({'ID': range(1,31),
'value':[n if n % 5 != 0 else np.nan for n in range(1,31)],
'numbers': [n if n % 4 != 0 else '?' for n in range(1,31)],
'text': ['txt' if n % 3 != 0 else 'No Value!' for n in range(1,31)],
})df.head()
数据帧已创建。图片由作者提供。
检查数据类型,注意列的值,其中有 NaN,它保持其类型为 float。但是看列的数字,它已经被强制转换成字符串。
df.dtypes
如果缺少的值是字符串,数据类型可能会改变。图片由作者提供。
您可以使用方法isna() or isnull()
来查找缺失值,但是它们都不会找到列编号或*文本、*的缺失值,因为这些是 Pandas 识别(或强制)为文本的列中的文本缺失值。
# Finding the total of null values
df.isna().sum()# Or you can also use
df.isnull().sum()
看到没有将指向“?”或者“没有价值!”作为缺失值。图片由作者提供。
对于已知的缺失数据,只需对数据集进行切片就可以找到它们。
# Pandas has good methods for that
df[ df.value.isna() ]
“值”列中缺少的 6 个值。图片由作者提供。
从这里,你可以使用许多可用的技术来处理缺失数据:删除,插补,插值等。我在下面的文章中浏览了几个选项。
带有文本缺失数据的数值数据
现在对于其他列,最好的方法之一是,首先检查数据类型,就像我们在df.dtypes
之前所做的那样。
如果我们知道在某一列中我们应该有哪种类型——就像我们知道列数字应该有整数——但是我们得到了与预期不同的东西,那么我们知道我们可能有一个丢失的数据点或者我们应该在该列中仔细检查的东西。
所以,既然我知道我的列数字必须是整数,我将继续寻找非数字数据,比如不同于数字(0–9)的数据。
# Find the non-numeric with isdigit to assess if the data is number.
# You can also use .isnumeric()
df[ df.numbers.astype(str).str.isnumeric() == False ]
我们已经找到了丢失的数字:'?'—图片由作者提供。
当然,也有数字以文本形式出现的情况,只是因为 Python 无法识别正确的类型或它带有额外的空格(例如,“3”),但在这种情况下,它要么不会作为缺失值出现,要么不会出现在您的列表中,但您知道它是正确的,您可以继续进行清理/格式化/转换以反映正确的数据类型。
带有额外空格的数字 3 被识别为“非数字”。图片由作者提供。
缺少值的文本数据
在不知道 NAs 在哪里的情况下,如何处理文本数据?
很多时候, NaN 值可以作为文本条目“NA”、“?, "—", "!"、【NULL】等,但它们可以是许多其他的东西。因此,我们的想法是使用正则表达式来尝试找到它们。一旦你找到了模式,识别其他的就变得容易了。
假设我们不知道列文本的 NA 值是“无值!”。我们将使用正则表达式检查许多模式。
在下面的代码中,我将应用一个 lambda 函数,在列文本的每一行中查找以下文本值:“NA”或“*”或“?”或者“!”或“#”或“-”并检查它找到的列表的长度。如果列表不为零,这意味着我找到了一些东西,所以在那一行中至少有一个模式。您可以在正则表达式中包含任何其他值。
# Import Regular Expressions lib
import re# Using regex to find the NA values
df[ df.text.apply(lambda x: len(re.findall('NA|[*|?|!|#|-]', x)) !=0 )]
找到结果。所有的空值。图片由作者提供。
在你走之前
在开始探索性分析之前,了解您的数据始终是必须的。如果可以的话,查看数据集文档,如数据字典或研究总结。这些文档将为您带来丢失的数据案例以及它们是如何被识别的。
对于您公司的业务数据,请尝试与该数据库的所有者交谈,以帮助您赢得时间并更快地找到 NAs。
如果你缺乏这两种选择,那么就选择上面显示的三种方法。
丢失数据处理起来并不复杂,但是如果没有正确清理,它肯定会损害您的工作。
更多内容,别忘了关注我。
https://gustavorsantos.medium.com/
如果你喜欢的话,可以订阅 Medium。你可以在这里使用我的推荐代码。
熊猫文献。
用当前日期字符串重命名文件的 3 种自动方法
原文:https://towardsdatascience.com/3-automated-ways-to-rename-a-file-with-a-current-date-string-3c787a5eb78e
分别使用 VBA 宏、批处理文件命令和 Python
照片由 Maddi Bazzocco 在 Unsplash 上拍摄
背景
可以在数据准备工作流的早期阶段使用数据科学技术来自动化手动任务。具体来说,在我职业生涯的许多实例中,我不得不使用带有时间戳的固定命名约定来重命名文件。这是为了使下游的工作流程能够区分数据或识别随时间变化的趋势。虽然只手动执行几个文件的重命名是可以接受的,但如果有数百个文件,就不可以了,这在商业环境中是常见的情况。
通过一个用例,本文介绍了三(3)种基于当前或预定义日期使用字符串重命名文件的自动化方法,分别使用 Excel VBA 宏和批处理文件命令和 Python 。
用例
在我职业生涯的早期,我有机会在一家人寿保险公司担任再保险分析师,该公司将再保险业务转让给多家再保险人。由于再保险人最终是直接保险公司运营的外部第三方,我的部分职责包括每月为再保险人准备各种报告。对于这个用例,我准备的一个报告是系统在一个月的最后一个工作日生成的所有有效策略的摘录。
这个摘录和系统生成的许多其他再保险报告一样,有一个固定的(陈旧的)名称 inforce_extract.csv 。当时准备这些报告的流程要求我通过添加再保险人标签和日期字符串(例如inforce _ extract _ reinsurer 1 _ 201206 . CSV)来手动重命名这些报告。对于多个再保险人的数百份报告,我遵循这一手动流程两个月,然后决定这是不可行的,因为它非常耗时且容易出现手动错误。
下面我将首先介绍我当时分别使用 Excel VBA 宏和批处理文件命令实现的两种方法,以取代上面概述的手动重命名过程(这两种方法最终使我获得了重大的过程改进),然后用 Python 中的一种实现来总结这一点,以帮助那些可能不熟悉前两种方法下的编程语言的人。
Excel VBA 宏
对于那些熟悉 Excel 的人来说, Excel VBA 宏以通过在其内置的 VBA 编辑器中创建定制函数来自动化手动 Excel 相关任务而闻名。在这种情况下,由于大多数报告是在。csv 格式,我想我可以写一个定制的功能,自动执行以下步骤:
- 打开底层。csv 报告
- 在函数中创建一个软编码变量,用于捕获引用日期的字符串(例如,当前报告日期的年和月,或“yyyymm”)
- 保存。csv 报告为另一个文件,采用选择的格式,文件名中包含步骤 2 中的字符串
以 inforce_extract.csv 报告为例,这可以通过运行以下 VBA 宏来实现:
第一步
' Open the system generated report
' path needs to be defined as path to directory of the system
' generated reportWorkbooks.Open Filename:=path & "\inforce_extract.csv"
Set inforce_extract = Application.Workbooks("inforce_extract.csv")
第二步
' DateAdd function allows one to soft-code a date referencing a
' pre-defined date' The code below would return 202112 at time of writing, which is 3 ' months in arrears to March 2022 date_string = Format(DateAdd("m", -3, Now), "yyyymm")
第三步
' Save the extract as "ïnforce_extract_reinsurerX_202112.csv"
' SAVEpath needs to be defined as the path to the directory where
' we want to save the renamed report
' There is also an option to save the file in another format, xlCSV ' is chosen for this instanceinforce_extract.SaveAs _
Filename:=SAVEpath & "inforce_extract_reinsurerX" & date_string & ".csv", _
FileFormat:=xlCSV, CreateBackup:=False,
inforce_extract.Saved = True
虽然作为每月重命名过程的一部分,我花了一些时间为所有需要重命名的文件编写代码,但这是值得的,因为我只需点击一下鼠标,就可以重命名数百份引用最新报告日期的报告。
值得注意的是,在步骤 2 中引入的 DateAdd 函数也可以用于以类似的方式在步骤 1 中打开一个已经带有日期字符串的文件。
批处理文件命令
没过多久,我就对 VBA 宏自动化的过程感到不满意,因为我突然想到,我应该能够更有效地重命名报告,而不需要打开它们。这类似于在 Windows 目录中的文件上按 F2 键并键入新名称。
由于这是 Excel 之外的操作,VBA 宏不再是合适的工具。当时我的一位同事给我指了指批处理文件命令。简单来说,这是一种用于在 Windows 操作系统中创建可执行脚本文件的编程语言。
脚本文件可以在文本文件中编译和编辑(例如,在 Windows 的记事本中),并以. bat 扩展名保存。然后,只需双击。蝙蝠文件。
我需要遵循的步骤有效地减少到只有前面章节中的步骤 2 和步骤 3 。概括地说,这只是基于最近的报告日期捕获日期字符串,并使用捕获再保险人名称(在报告日期中不变)和日期字符串的命名约定来重命名系统生成的报告,而不需要打开底层文件。
要在脚本文件中基于当前日期(即今天)捕获日期字符串(注意“@REM”是在脚本文件中显示注释的方式):
@REM Get the current date, by capturing the first 10 substrings @REM This captures a date of dd/mm/yyyy
set stamp=%date:~-10% @REM Get the year (e.g. 2022), by extracting the 7th to 10th @REM substrings
set year=%stamp:~6,4% @REM Get the month (e.g. 03), by extracting the 4th to 5th @REM substrings
set month=%stamp:~3,2%
如果我需要捕获基于非当前日期的日期字符串,需要一些额外的步骤。下面的脚本演示了如何根据比当前日期晚 3 个月的日期提取日期字符串“yyyymm”:
@REM subtract 3 months
set /a month=1%month%-103 @REM "Rollback" year and month if the above is negative @REM e.g. 101 for January - 103 would be negative, then add 12 to @REM month and subtract 1 from year
if %month% LSS 1 (
set /a month=%month%+12
set /a year=%year%-1
) @REM Prepend with zero for single-digit month numbers (i.e. if month @REM number is 9 or less, add a leading 0)
if %month% GTR 9 (set month_final=%month%)
else (set month_final=0%month%)
最后,要使用再保险人和日期字符串重命名报告:
@REM Define current directory, path needs to be defined as path to @REM directory of the system generated report
cd "path"@REM Rename the inforce_extract.csv report in the path
rename inforce_extract.csv inforce_extract_reinsurerX_%year%%month_final%.csv
计算机编程语言
与上面的两种方法相比,我认为使用以下步骤在 Python 中可以更容易地实现相同的重命名任务:
第一步:导入库
from datetime import datetime
import os
第二步:定义要重命名的文件
## Path to be defined as directory where the file is saved
inforce_extract = 'path/inforce_extract.csv'
第三步:创建日期字符串并为文件定义新名称
## The below returns yyyymm, or 220203 at time of writing
date_string = datetime.today().strftime('%Y%m')## Define new name
new_name = 'path/inforce_extract_reinsurerX_'+ date_string +'.csv'
第四步:重命名
os.rename(inforce_extract, new_name)
总结想法
我观察到,与我一起工作的大多数人鄙视手工过程,而一些人选择接受,另一些人采取额外的步骤来自动化它们。
我很感激在我职业生涯早期所处的环境中,我被迫使用编程来改进过程。在接下来的几年里,这种有益的经历继续激励我学习各种应用程序的编程,自动化无疑是其中之一,除此之外,数据科学和机器学习也是我日常工作的应用程序。
如果你喜欢你正在阅读的东西,一定要访问我的个人资料,在这里查看我写的其他文章。
ML 团队避免构建公平模型的 3 个(坏)原因
原文:https://towardsdatascience.com/3-bad-reasons-ml-teams-avoid-building-fair-models-d8f85a1edc23
浅谈机器学习模型中的社会公平
ML 有公关问题。
尽管我们对更智能、更细致、更强大的移动营销的能力突飞猛进,产生了巨大的积极社会价值,但消费者对移动营销的担忧并没有消退。
事实上,它似乎在增长。
这种趋势对于任何公司、团队或专业人士(像我一样)来说都是令人担忧的,他们的主要功能是为消费者应用构建 ML。
我认为这种趋势正在增长的原因是因为 ML 团队在构建模型的时候主动避免了“公平”。我将讲述我见过的团队避免这种情况的 3 个主要原因,以及当我们进一步进入 2020 年代时,为什么这些原因不足以忽视公平。
现状
解决 ML 应用中的“公平”是例外而不是规则。几乎所有的 ML 应用程序都是在没有充分考虑“公平”概念的情况下推出的。我认为这有三个原因:
(1)定义不清:公平对于机器学习意味着什么?
在机器学习之外,判断一件事是否“公平”是一项困难的工作。添加数学、统计和 B]你的团队通常只理解的缺乏盒子模型—
什么是地面真理?我们测试哪些群体/身份?模型性能的差异有多大值得偏见?我们能确定这不会与其他真正提升性能的特性混淆吗?
—使得这项任务几乎不可能完成。一个团队如何测试社会偏见?
硅谷的幕后人员发现讨论公平是徒劳的。cherydeck在 Unsplash 上拍照
左右目前 ML 队伍争…
由于定义和量化最大似然公平是一项棘手的任务,ata 的科学家们通常会放弃试图在他们的模型中明确解决社会偏见的想法。
对于数据科学中难以定义/量化的指标,这是一种常见的反应,通常也是一种好的反应。另一种选择是尝试将一个模糊的术语翻译成一个可量化的度量标准,这对于 ML 项目来说常常以灾难告终。
虽然公平肯定是一个模糊的概念,但有一些清晰的、几乎普遍接受的定义:
**ML 公平性:**如果结果独立于给定变量,特别是那些被认为敏感的变量,例如不应与结果相关的个体特征(即性别、种族、性取向、残疾等),则给定的 ML 模型是公平的。).[ 链接
定义大联盟公平并不像大联盟团队想象的那么难
在模型开发阶段,上述定义可以很容易地转化为几个 ML 测试用例。
例如,一个团队可以通过简单的皮尔逊测试来检查模型的预测与性别的相关程度:
import numpy as np
from scipy.stats import pearsonrp = pearsonr(gender_values, labels)# If there is modest correlation between label and gender,# we should attempt to mitigate thisif np.abs(p) >= 0.5:
print("Potential Gender Bias")
或者使用模型的特征重要性分数+与年龄相关的特征,以确保模型不会隐含地发现有偏差的信号:
# Using SKLearn Tree model + panda dataset
import pandas as pd
import numpy as np
from sklearn.ensemble import GradientBoostingRegressortree_model = GradientBoostingRegressor()
tree_model.fit(X_train, y_train)top_ten_imp_thresh = sorted(tree_model.feature_importances_)[-10]for i in range(len(X.columns)): col = X.columns[i] imp_score = tree_model.feature_importances_[i]
fair_score = pearsonr(X[col].values, bias_labels) # Check each column for importance + bias
print(col) if np.abs(fair_score) >= 0.5:
print("Potential Bias")
if imp_score >= top_ten_imp_thresh:
print("Important Feature")
print()
这些当然是不可思议的简单例子,但即使是简单的方法也能给人启发。
您永远无法真正知道您是否已经从您的模型中消除了所有偏见,但是简单地尝试解决它将确保社区发布的模型对我们的最终用户更加公平。
(2)默许:垃圾进,垃圾出
解决公平性的另一个反对意见是将对公平性缓解的控制从建模团队移交给底层数据。短语:
垃圾进,垃圾出
是 DS 社区的主要内容。而在工业界,这是绝对正确的。我们把大部分时间花在清理数据上,而不是创造任何东西。数据科学家可以构建模型来发现数据中的复杂模式…但是如果数据不够干净,无法发现这些模式,我们就无能为力了!
有时候,数据科学感觉就像在垃圾堆里找到金子。埃文·德米科利在 Unsplash 上拍摄的照片
将这与 ML 公平性联系起来,如果数据本身包含模型拾取的有偏见的模式,我们就什么也做不了。或者我们甚至没有数据来检验我们的模型是否有偏差。
简而言之,有两个与数据相关的异议:
- 我们没有足够或正确的数据来验证我们的模型是否公平
- 算法偏差是由于我们的数据和社会固有的偏差
虽然两个不同的论点,都含蓄地得出结论 ML 公平是“不可能的”给定的情况。
To (#1) ,如果你有足够的数据来验证你的模型是准确的,你就有足够的数据来验证你的模型是公平的。如果您的应用程序是面向客户的,您绝对有足够的客户信息来围绕算法偏差构建测试。
即使没有明确的人口统计/身份信息,散列的电子邮件或邮政编码也可以为您的团队提供足够的果汁来解决 ML 公平性问题。你甚至可以使用像 IBM 的 fairness 360 这样的开源工具来完成这个任务。
http://aif360.mybluemix.net/
To (#2) , 仅仅因为你的数据/社会中存在偏见,并不意味着你注定要延续这种偏见。
对算法偏见的测试肯定会揭示内在的数据/社会偏见,但一旦你意识到这些问题,你就可以解决它们,就像你会解决任何其他非公平相关的偏见一样,如不平衡的班级。
(3)金钱万能:为了商业价值而忽视公平
在我看来,这是算法社会偏见在模型开发中被忽略的最常见原因,即使大多数数据科学家不会明确地说出来:
ML 团队需要不惜一切代价交付商业价值。如今,这种成本包括忽略社会偏见缓解,以加快模型部署。
ML 产品开发仍处于初级阶段。85%的人工智能项目失败。
即使有正确的数据、人员和策略,ML 项目也只能在 20%的时间里实现 ROI。
从公司的角度来看(今天的*),一个 ML 团队的唯一目标是尽快交付商业价值。为了完成这项任务,我们的工作岌岌可危。*
正如气候变化已经进入主流辩论,ML Fairness 也是如此,由 Clem Onojeghuo 在 Unsplash 拍摄
就像几代人都忽略了环境后果,因为金钱激励压倒了任何反对意见,有偏见的模型在规模决策时的广泛社会反响被忽略,以确保 ML 团队的项目属于推动 ROI 价值的 15%的计划。
而且要快。
*“*快速移动和打破东西”后脸书工程开发的咒语很难转化为 ML 任务,但特别是使解决像算法社会偏见这样的外部性成为一个额外的不必要的步骤。
正如一位 DS 的知己告诉我的:
我们已经有了构建和发布模型的紧迫期限。【他老板】不问公平,我就不考了。很糟糕,但事实就是如此。
但就像工业公司进入公共话语的环境后果一样,科技公司的社会后果也会如此。它将开始影响底线。
结论
公众对公平 ML 模型的期望已经改变。围绕 ML 公平发展的现状将需要向紧张的消费者保证,他们可以信任公司如何管理他们的个人数据,并且他们的模型的预测是同样准确和公平的。
“人工智能冬天”一词通常用来描述对人工智能研究的兴趣急剧下降的时期。我假设
除非 ML 团队承认并解决消费者对人工智能日益增长的不满,否则我们可能会进入一个奇怪的“消费者人工智能冬天”:
大多数消费者非常不信任和不喜欢使用 ML 的产品,因此消费者对 ML 的应用不再流行。
避免这种命运将涉及添加护栏和功能,以确保我们的模型满足消费级技术所需的期望。
正如所讨论的,ML 社区能够并且应该解决这些模型的缺点。如果做不到这一点,将会(1)直接导致野生环境中更糟糕的结果,以及(2)从根本上削弱公众对人工智能产品的信任和渴望。
细分客户的 3 种最佳方法
原文:https://towardsdatascience.com/3-best-approaches-to-segment-your-customers-21fb3732b98a
学习层次聚类、k-均值聚类和 RFM 分割的用法
Avinash Kumar 在 Unsplash 上拍摄的照片
客户细分
今天,客户是一切的中心。但是,你不可能让所有人都满意。现实就是这样。你越早了解这一点,它将更好地为你和你的企业服务。这就是为什么业务分析师要做的第一件事是根据客户的需求、愿望和共同特征将客户(现有的和潜在的)分成不同的组。了解客户的偏好可以让你设计量身定制的策略来赢得他们,并提供最好的产品和服务。这对于软件即服务(SaaS)企业来说更为重要,因为客户保持率(RR)是关键 KPI 之一。
有几种方法来细分客户。分层聚类、最近频率和货币(RFM)分割和 K-均值聚类是流行的方法。
最近,我写了一个由 3 部分组成的系列文章,详细描述了如何进行客户细分。查看它们:
客户细分介绍
使用 k 均值聚类进行客户细分
用 PCA 改进 k-means 客户细分模型
分层分段
根据维基百科,层次聚类是一种聚类分析方法,旨在建立聚类的层次结构。
https://en.wikipedia.org/wiki/Hierarchical_clustering
在层次聚类中,成对样本基于相似性被分组在一起,然后它们被合并以形成下一层次。最后形成一个树状图(一个树形结构)。要形成的簇的数量由专家分析师基于该树状图来确定。
下面的代码基于标准化的客户数据集生成一个树图。完整的代码可以在 Deepnote 笔记本中找到。
k-均值算法
K-means 聚类是一种无监督聚类算法。它试图根据最接近的平均值对观察值进行分组。下面是实现 K-means 算法所需的步骤。
- 选择聚类的数量(k)
- 为每个簇分配初始质心(在 scikit-learn 的 KMeans 类对象的 init 参数中传递
kmeans++
)。 - 根据距离测量值,将每个观测值分配给质心最近的聚类。
- 计算修改后的质心。
- 只要质心保持变化,重复步骤
3
和4
https://en.wikipedia.org/wiki/K-means_clustering
一旦我们知道了最佳的集群数量,我们就可以通过n_clusters
参数对我们的客户进行细分。
一旦用数据训练了模型,我们就可以从 kmeans 对象的label_
参数中获得分配的分类标签。
RFM 分割
R 频率、 F 频率和货币细分(RFM)是一个管理型的客户细分过程,适应性强,易于理解。关键实体是:
- 新近度:客户互动的新近度。
- 频率:客户购买的频率。
- 货币:顾客消费的总金额。
RFM 细分的关键要素是将静态管理权重分配给客户的 3 个因素,并计算每个客户的最终等级,从而确定客户群。
客户细分是第一步。下一步是制定强有力的战略。在实施你的策略时,保持专注并定期检查以确保你在正确的轨道上。
万事如意。
感谢阅读!如果你喜欢这篇文章一定要 鼓掌(最多 50!) 和让我们 连接上*LinkedIn和 在 Medium 上关注我,随时更新我的新文章。*
请通过此 推荐链接 加入 Medium,免费支持我。
*https://analyticsoul.medium.com/membership *
直方图的 3 个最佳(通常更好)替代方案
原文:https://towardsdatascience.com/3-best-often-better-alternatives-to-histograms-61ddaec05305
避免直方图最危险的陷阱
斯科特·韦伯的照片
宁滨偏差,直方图的最大缺陷
直方图可能是您开始数据科学家之旅时使用的第一个图表。它们是直观且容易理解分布形状的图表。
然而,当你在旅途中前进时,你会发现直方图并不那么美好。直方图将值分组到称为仓的间隔中,直方图中每个仓的高度表示该仓中的点数。考虑这个例子:
作者图片
从这个直方图中,我们可以立即看到大多数分数在 60 到 80 之间。让我们看看如果我们将容器数量从 10 个更改为 20 个会发生什么:
作者图片
然而,前一种趋势是显而易见的。让我们继续改变,这次从 20 岁到 40 岁:
作者图片
现在,我们可以看到分布并不像看起来那么平滑。您可以注意到 40、62、68 和 80 附近有 40 个频段的小峰值。所以,箱子的数量实际上可能掩盖了对我们分布的本质认识。
然而,过多地改变箱的数量可能只会引入随机噪声,并使其看起来像一个重要的发现。这就给我们带来了**宁滨偏差,**这也是直方图的最大缺陷。
宁滨偏差是直方图的一个缺陷,当您改变要绘制的条柱数量时,您将获得相同数据的不同表示。
在后面的章节中,我们将看到三种直方图选择,它们避免了宁滨偏差,并给出了比较分布的更好结果。
https://ibexorigin.medium.com/membership
获得由强大的 AI-Alpha 信号选择和总结的最佳和最新的 ML 和 AI 论文:
https://alphasignal.ai/?referrer=Bex
离散和连续数据复习
在我们讨论替代方案之前,我想为那些不熟悉的人提供一些关于数据类型的信息。
有两种类型的数值数据:
- 离散数据——通过计数记录的任何数据,如年龄、考试分数,有时还有时间的个别组成部分,如年份、工作日或月份数字等。
- 连续数据 —测量记录的任何数据,如身高、体重、距离等。时间本身也被认为是连续的数据。连续数据的一个定义方面是,您可以用不同的度量单位来表示相同的数据。例如,可以用英里、公里、米、厘米和毫米来度量距离,列表 延续 。无论多小,你都可以找到一个更小的连续数据的度量单位。
关于货币和价格,统计学家们争论货币是连续的还是离散的,所以我就不多说了。但是,需要注意的是,银行业和税务系统将货币视为连续数据。
概率质量函数— PMF 图
直方图的第一种替代方法是绘制概率质量函数的结果。
概率质量函数是一个采用离散值的分布(任何序列)并返回每个唯一值的频率的函数。考虑这个小分布:
x = [4, 6, 5, 6, 4, 3, 2]
为了计算这个分布的 PMF,我们将使用来自empiricaldist
库的Pmf
函数(由 Allen B. Downey 编写,他是著名书籍的作者,如 ThinkStats 、 *ThinkPython、*和 ThinkBayes :
作者图片
为了创建分布,我们将使用Pmf
函数的from_seq
方法,该方法将一个序列作为参数。
结果是一个Pmf
对象(pandas
系列),其中包含传递的分布的唯一值。它们以有序索引的形式给出,其频率(计数)在probs
下。
现在,如果我们将normalize
设置为True
,probs
将包含每个值的小数频率,总计为 1:
作者图片
要获得任何值的频率,我们可以使用括号运算符:
这是一个简单的例子,给你一个概率密度函数的概念。接下来,我将从这个源加载一个从 Kaggle 下载的样本学生分数数据集:
marks = pd.read_csv('data/student_performance.csv')
>>> marks.head()
作者图片
首先,我们将为数学成绩创建一个 PMF 分布:
就像之前一样,math_pmf
隔离出数学成绩的唯一值,并将其归一化。Pmf
对象有一个默认的plot
方法,绘制一个线图(要绘制一个条形图,可以使用.bar
函数):
作者图片
线上的每个数据点对应于分布中的唯一分数及其百分比频率。
为了更容易理解,我将对中位数和第 25 个百分位数进行注释:
作者图片
大约 25%的学生得分为 66,大约 17%的学生得分为 57。
从图中,我们可以看到大多数学生的得分在 55-70 之间。该图的优点是我们可以看到数据中的一些峰值,例如峰值在 40°处,另一个峰值在大约 55°处。如果我们使用直方图,这可能会变得模糊不清,看起来也不会很好:
作者图片
最后,还有另一种方式来解释 PMF 的结果。之前,我们看到大约 25%的学生得到了 66 分的中值。这也意味着如果我们从分布中随机选择一个学生的分数,我们有 25%的机会得到 66 分。这种看待事物的方式会对我们以后有所帮助。
请记住,PMF 函数最适用于离散值。我们将在后面的章节中看到它对于连续数据的等效。
累积分布函数图
快速提问——有人意识到 PMF 阴谋的最大缺点了吗?如果没有,这里是:它不能与有太多唯一值的分布一起工作。例如,我将创建 2000 个随机整数来模拟一个离散分布,并用 PMF 来绘制它:
作者图片
如果我们使用 PMF 图,噪音太大,我们无法获得任何有意义的见解。使用直方图太危险了,因为很难选择最好地描述分布的宁滨。
对于这种分布,有一个鲜为人知但非常有用的函数:累积分布函数。与 PMF 不同,它们可以采用任何值(离散、连续、混合)并显示分布趋势。
为了更好地理解,让我们从一个微不足道的例子开始:
# Simple dist
dist = [1, 2, 3, 4, 5, 6, 7]
我创建了一个由 7 个连续整数组成的伪序列。为了创建 CDF,我们将使用empiricaldist
库的Cdf
功能:
作者图片
Cdf
也有类似的from_seq
方法。它还接受唯一值,并按照索引对它们进行排序。不同的是概率。
假设你从一个分布中选择一个随机值 x 。在这种情况下,累积分布函数将告诉您获得小于或等于该值的概率:
谷歌搜索结果
对于我们从 1 到 7 的小分布值,假设我选择了 5。有五个值小于或等于 5,因此CDF(5)
大约等于 72%。类似地,CDF(1)
等于 14%,分布中的最大值将总是有 100%的概率,因为所有值都小于或等于最大值。
另一种说法是,首先,计算每个唯一值的分数频率并排序。然后,来自分布的随机值的 CDF 将等于小于或等于 x 的所有唯一值的单独频率之和。
接下来,我将从seaborn
加载内置的diamonds
数据集,我们将看到钻石价格的CDF
图:
链接到数据集回购:https://www.kaggle.com/datasets/shivam2503/diamonds
作者图片
绘制累积频率可以让我们消除随机性,不受噪音干扰。就像之前一样,让我们注释一下中间价格和第 25 个百分位数:
作者图片
本质上,CDF 只是百分位数的另一种框架。从结果中查找任何值,比如 17,CDF 会告诉它的百分位数,或者在分布中小于或等于 17 的值的百分比。
当我们在同一个图上绘制不同的分布时,可以看到 CDFs 的一个明显的优点。
让我们画出 3 种不同类型的钻石切割的价格。我将创建理想、高级、和非常好切割钻石的 CDF:
作者图片
如果你正确解读这个情节,你会发现一个重要的发现。出乎意料的是,比特级或非常好钻石更理想的价格非常低的钻石还有很多。
让我们重点关注价格在 0 到 2500 之间的钻石。在这个区间里哪条线最高?是理想钻石的蓝线。事实上,60%或更少的理想钻石价格在 0-2500 英镑之间。相比之下,非常好的钻石的其他线的高度几乎是 50%,高级钻石的大约 45%。
因此,当用 CDF 图比较分布时,一些区间之间的线的高度(陡度)说明了该区间中的点数。线越高,值越多。
如果区间包含陡度角更接近水平线的线,则表明该区间中的点更少,但它们的值更大。例如,在我们的图中,所有三条线在 12500 美元之后几乎都变成了水平线,这告诉我们很少有钻石的价格超过了这个数额。
通常最好使用 CDF 来比较不同组的分布。与其他图相比,它们给出了更好的分布视图。
核密度估计(KDE)图,解释
另一个观察分布形状的好图是 KDE 图(核密度估计)。KDE 图使用概率密度函数,这是概率质量函数的替代方法,但适用于任何类型的分布。
如果在离散分布中有太多独特的数据点,PMF 只是将随机噪声引入我们的图中,而不是给出任何见解。然而,它们比直方图好得多,因为它们不会陷入宁滨偏差带来的陷阱,例如模糊或过度表示数据。
当我们处理连续数据的分布时,几乎每个数据点都是唯一的,因为每个值都可以有小数点。有了这种类型的数据,我们就不能问这样的问题了,比如“精确 2 英寸降雨量的确切概率是多少?”。问这个问题就意味着问精确 2 英寸降雨的概率,而不是多一个水分子或少一个水分子,不是 2.01,也不是 1.9999。答案当然是 0,因为 2 可以有无限多的小数。
然而,我们可以很快回答这样一个问题:下雨 大约 2 英寸的概率是多少?概率密度函数帮助我们回答这类问题。
在统计学中,pdf 的结果是用一种叫做核密度估计(KDE)的方法来估计的。在不涉及统计细节的情况下,我们将在本节学习如何绘制 KDE 图。
首先,您可以使用的kdeplot
功能创建 KDE 图。我们将再次使用diamonds
数据集:
作者图片
如果你不熟悉统计学,请忽略 KDE 图的 y 轴。解释它远远超出了本文的范围。
与 CDF 不同,在 CDF 中你会得到一条平滑的线,KDE 图最适合于快速确定分布的中心趋势、双峰和偏斜。
kdeplot
有一个有用的参数hue
,它让我们指定第二个变量来对结果进行分组:
作者图片
KDE
图非常适合于比较不同的分布并同时辨别分布的个体质量。例如,上面的图显示了哪个分布有更多的值,它们在哪里聚集,它们的偏斜度和模态。
参见 Seaborn 文档的页面,了解更多关于 KDE 地块和 pdf 的信息。
结论
在本文中,您了解了三种最常见的直方图替代方法。它们可以根据数据类型显示关于分布的不同见解,但主要是帮助您避免宁滨偏差。
然而,这并不意味着你必须完全抛弃直方图。通过计算数据点数量的平方根,可以粗略估计出适合您的分布的容器数量。
感谢您的阅读!
https://ibexorigin.medium.com/membership https://ibexorigin.medium.com/subscribe
您可能也会感兴趣…
https://ibexorigin.medium.com/6-sklearn-mistakes-that-silently-tell-you-are-rookie-f1fe44779a4d
https://towards data science . com/19-hidden-sk learn-features-you-should-to-learn-the-d-way-5293 e6ff 149
ML 模型在生产中面临的 3 大挑战
原文:https://towardsdatascience.com/3-challenges-for-ml-models-in-production-6cf8870f2fd1
这些都是不容忽视的。
照片由 Unsplash 上的德韦恩·希尔斯拍摄
很大一部分机器学习(ML)模型从未投入生产。在 Jupyter 笔记本中创建一个模型是一回事,但将它部署到生产中并作为一项持续服务来维护它则是另一回事。这是一个涉及许多相关步骤的过程,这些步骤可以归为机器学习操作这一术语, MLOps 。
MLOps 如此重要,我认为它是数据科学中的下一件大事,或者说它已经是一件大事了😊。为了通过机器学习产生长期的商业价值,我们需要从数据采集到模型监控都坚持 MLOps 原则。
在生产中维护 ML 模型有一些挑战,需要解决和正确处理这些挑战,以使整个系统可靠和健壮。在本文中,我们将讨论其中的 3 个挑战。
1.没有人为干预
ML 模型极有可能做出比我们更好的预测。他们比我们工作得更快,可扩展性更强。另一方面,ML 模型的一个缺点是它们没有常识。因此,ML 模型有可能产生不切实际的结果。
ML 模型的核心是训练数据。它们反映了它所训练的数据中存在的结构和关系。在揭示数据中的依赖关系方面,ML 模型比我们好得多。然而,当他们遇到新事物时,他们可能会产生荒谬的结果。
由于生产中的 ML 系统很可能没有人工干预,因此总是存在结果不合理的风险。
这些风险的影响因应用而异。在推荐引擎的情况下,这并不重要。然而,如果我们有一个自动反馈供应变化的预测引擎,那么事情可能会变得非常糟糕。
这些风险不应被视为赤字。我们只需要记住它们。我们可以通过频繁地重新训练我们的模型,基于某些限制检查结果,并在生产中监控模型来克服这一挑战。
2.数据更改
世界在不断变化。唯一不变的是变化本身。
生活中唯一不变的是变化——赫拉克利特。
一切都随世界而变,数据也是如此。不可避免地会有以前看不到的数据点,我们希望我们的模型能为它们产生结果。
考虑一个垃圾邮件检测模型。诈骗者改变他们的策略,创造新的垃圾邮件。没有经过这些新例子训练的模型很可能无法捕捉到它们。这个概念被称为数据漂移,如果处理不当,可能会导致严重的问题。
另一个对模型准确性有影响的变化叫做概念漂移。当因变量和目标变量之间的关系发生变化时,就会发生这种情况。在欺诈检测模型中可以观察到概念漂移的典型例子。如果一个过去没有被归类为欺诈的交易,现在也可以是欺诈。
数据和概念漂移都可以通过实施稳健可靠的监控系统和反馈回路来处理。然后我们可以决定何时重新训练我们的模型。
3.利益相关者之间的沟通
建立一个 ML 系统需要不同的技能。一般来说,数据科学家、数据工程师、软件工程师、DevOps 工程师和主题专家参与机器学习生命周期。
主题专家与数据科学家合作,定义要用机器学习解决的业务问题。他们设置了 KPI 来衡量模型的性能。
数据工程师的主要职责是数据采集和 ETL 操作。软件工程师和 DevOps 工程师处理与 IT 相关的任务。
角色和任务可能因公司而异。不变的是,不同的利益相关者之间需要稳健有效的沟通,才能使事情顺利进行。否则,我们最终会有不必要的时间间隔,甚至会使项目失败。
为了产生商业价值,需要将 ML 模型部署到生产中。这绝对不是一件容易的事。创建这样一个系统超出了数据科学家的技能范围。然而,了解与在生产中维护 ML 模型相关的风险并采取预防措施可以使事情变得更容易。
你可以成为 媒介会员 解锁我的全部写作权限,外加其余媒介。如果你已经是了,别忘了订阅https://sonery.medium.com/subscribe如果你想在我发表新文章时收到电子邮件。
*https://sonery.medium.com/membership
感谢您的阅读。如果您有任何反馈,请告诉我。*
面向数据和分析团队的 3 个知识库模板集群
原文:https://towardsdatascience.com/3-clusters-of-knowledge-base-templates-for-data-and-analytics-teams-1d87cc26c93a
以系统的方式创建外部、共享和内部文档
由 Hubi 拍摄的照片。在 Unsplash 上的 img
数据和分析团队的任务是开发推动决策的洞察力。这些见解通常基于从整个组织的多个来源收集的数据集,包括客户数据库、销售历史、营销活动、财务报告等。
庞大的信息量会使寻找所需答案变得非常困难,尤其是当数据和分析团队随着时间的推移而增长时。
因此,许多组织最终会得到一个支离破碎或重复的信息架构,使得他们的数据团队很难在部门间和跨部门级别上交换知识。
每个数据角色的重要部分是记录开发过程和结果。或者,换句话说,根据不同的领域创建技术和非技术文档;数据工程、数据科学和数据分析。
说实话,编写文档并不是什么新鲜事。然而,如果事先没有明确的指导方针,这可能会非常耗时。
考虑到这一点,数据专业人员应该创建模板,以确保系统和透明的文档交付。
因为让我们面对它,预定义的模板已经完成了一半的工作。
随后,这篇博文旨在从外部、共享和内部文档的角度展示如何创建和模板化数据和分析知识库。
知识库组织
知识库应该是数据和分析以及其他团队的中央协作中心。这是团队的信息、方法和技术/业务知识存储的地方,并相应地与不同的业务用户组共享。
考虑到不同的用户群,我们的数据和分析(D&A)团队将知识库文档模板分为三组: D &外部文档,D &共享文档,D &内部文档。
让我们从阐述每个文档组及其模板开始。
D&A 外部文件
作为数据和分析团队,拥有透明的流程和标准至关重要。无论你是在进行新的开发还是支持现有的开发,记录团队是如何运作的都是很重要的,这样组织中的每个人都理解分析开发过程。
这是外部文档的主要目标——分享关于团队组织、跨部门数据洞察、发展洞察和团队发展更新的一般信息。
考虑到这一目标,我们的 D&A 外部文档由以下结构组成:
数据和分析外部文档结构[图片由作者提供]
如上图所示,外部文档有四个主要部分:
- #1:关于 D &团队— 该部分涵盖了数据和分析团队的一般信息,以及商业智能和数据科学领域的开发框架和路线图。此外,该部分向所有业务用户解释了分析开发流程,并包含我们的季度和年度开发跟踪。
- #2:终端用户数据洞察— 该部分详细解释了所使用的分析和业务缩写、不同类型的仪表板列表(趋势或演变仪表板)以及不同的业务领域。此外,这里还为有权访问自助服务数据模型的用户提供了每个数据模型的解释。
- #3:开发洞察 —该部分涵盖数据工程、数据科学/分析和定制开发笔记。本节还介绍了数据和分析架构,以及解释的数据源和测试模板。
- #4:数据&分析每月更新 —该部分涵盖根据不同数据和业务领域开发的票据的每月更新。
在详细描述了外部文档结构之后,我们现在可以切换到详细描述共享文档结构。
D&A 共享文档
跨团队合作与数据和分析团队相关,因为每天/每周/每月都需要交换业务和开发更新。
为此,我们的数据和分析团队创建了共享文档来记录会议笔记、开发想法和团队相关的业务知识,以便规划未来的分析用例。
我们的 D&A 共享文档由以下结构组成:
数据和分析共享文档结构[图片由作者提供]
如上图所示,共享文档包含以组织中其他团队/圈子命名的部分,并包含不同的子部分,用于加速分析和业务开发。
根据行业和组织类型的不同,您的数据和分析团队将在此列出完全不同的部分和子部分。然而,主要目标是让共享文档**中的部分仅对特定的用户组(团队)**可见。
说到这里,我们现在可以转到解释知识库的最后一部分——内部文档。
D&A 内部文件
内部数据和分析团队文档更加详细和具体,因为它应该包含团队专用的相关信息。
它应该是数据和分析团队成员的参考中心,以持续监控团队的组织和技术发展计划。此外,它还可以包含新团队成员的组织和技术指南,以及团队可以共享有用资源的地方。
我们的 D&A 内部文件由以下结构组成:
数据和分析内部文档结构[图片由作者提供]
如上图所示,内部文档有四个主要部分:
- #1:公司和 D &愿景| D &团队间指导方针 — 该部分包含与组织愿景一致的数据和分析愿景。它还包含预订假期和下班时间的相关指导原则,以及核心工作时间的信息。
- #2:入职&技术指南 —该部分有一个关于组织入职的子部分,其中包含时间管理系统、了解公司结构的资源以及访问所有相关数据源和其他部门联系人的链接。这里还提供了一个技术入门子部分,它包含了相关的教程和文献以跟上当前的发展。最后,这里还列出了每个不同数据区域的完成标准的定义。
- #3:回顾会议记录 —可能是数据和分析团队中使用最多的部分,因为它包含每周组织和团队间更新、sprint(重新)计划的任务以及过去几周已完成任务的总结。
- #4: Docendo discimus 或“通过教学,我们学习” —这个部分背后的想法是分享有用的日常资源和与工作无关的想法或会议计划。
我们将总结使用此零件构建知识库的“最佳实践”。
总结一下:让它变得可见并成为惯例
让我们通过分享为什么应该在任何(数据)团队中实现三个不同的知识库集群(外部、内部和共享文档)的好处来结束这篇博客:
- 所提供的知识库结构使得数据和分析 工作流 对业务中的每个人来说都是透明且易于参考的。
- 所提供的知识库结构包含数据和分析更新、会议记录、开发文档等。,可供业务用户随时使用。这将避免数据和分析团队成员重复共享更新。
- 所提供的知识库结构通过确保团队中的任何人始终关注当前(和过去)sprints 中的计划任务,消除了团队间的发展瓶颈。
- 提供的知识库结构简化了团队领导的团队间信息共享,因为每个团队成员都可以轻松访问组织和技术指南。
- 提供的知识库结构简化了新团队成员 和具有数据洞察力的新业务用户的入职。
- 最后,提供的知识库结构**节省了创建新文档的时间,**为每个部分创建了模板。
最后,这篇文章旨在帮助数据团队构建他们的知识库文档,因为即使这样的小事也可以在信息透明度和知识共享方面产生巨大的组织差异。
3 种常见的错误来源以及如何避免它们
原文:https://towardsdatascience.com/3-common-bug-sources-and-how-to-avoid-them-182f9974d2ab
有些编码模式更容易隐藏 bug。编写高质量的代码并了解我们的大脑是如何工作的,有助于大幅减少它们的数量。
德米特里·布汉佐夫在 Unsplash 上拍摄的照片
错误是生活中不可避免的一部分,对代码来说更是如此。软件项目的复杂性通常增长很快,导致微妙的逻辑错误(也称为 bug ),破坏了软件部分的正确功能。
尽管不可避免,我们仍然可以采取一些措施来减少它们的数量,或者至少在它们发生时使它们更容易被发现。毕竟,我们花在捕获 bug 上的时间越多,我们能花在真正向客户交付价值上的时间就越少。
好消息是,有一些常见的虫子藏身的模式,我们可以避开它们,给我们的虫子更少的藏身空间。
这些模式各不相同,但是它们有一个共同的重要因素:当代码的复杂性超出我们的认知能力时,它们就会出现。现代心理学同意存在一种工作记忆,我们用它来推理我们正在执行的认知任务,就它所能包含的项目而言,它也是相当小的。幸运的是,有像分块这样的工具帮助我们处理复杂的信息。
Python 核心开发人员 Raymond Hettinger 在下面的视频中非常有效地解释了这些概念如何与我们的日常工作相关联:
但是现在回到我们的故事,是时候看看模式了。
请注意,这个故事中的代码示例是故意非常简单的。我不做数据验证,我使用浮点数来表示货币,以及其他在生产就绪代码库中是错误的东西。这里我只对展示讨论的相关部分感兴趣。
代码示例是用 Python 编写的,但是这里的建议并不局限于这种语言。
模式 1:重复条件句
当同一个条件语句(if-else,switch 语句)在代码中重复多次时,bug 可能以多种方式隐藏在那里。
首先,我们没有一个单一的地方可以看到同一分支的所有出现,然后检查它们的一致性。
第二,出于同样的原因,当修改一个或多个分支中的代码时,我们可能会忘记更新所有的事件。
第三,如果没有一个清晰的接口,我们可能会添加一些分支,但只是添加到条件代码的某些部分,而不是所有适当的位置。
示例:假设我们正在为一家公司编写一个人力资源应用程序,该公司的员工级别(为简单起见)从 1 到 3。
很容易看出,这里的问题是同一个 switch 语句(if…elif…else)在不同函数的代码中重复了几次。我们没有工具在代码处于这种状态时,对发生分支的所有代码部分进行强制检查。幸运的是,一些重构可以帮助我们解决这个问题:
https://betterprogramming.pub/my-top-takeaways-from-refactoring-part-2-55efe6c547b8
解决方案:多态性
第一个解决方案是使 Employee 数据类成为一个多态类。为此,我们首先使 Employee 成为一个抽象类(如果使用 Python 或 C++等语言,一个与 Java、C#或 Go 的接口)。然后,我们为每个等级创建一个具体的类。上面写的每个函数都成为抽象类中的抽象方法,然后在具体类中强制实现。
对要实现的方法的自动控制意味着我们不能忘记为一个类添加功能,同样也不能忘记为一个分支添加功能。此外,如果完全相同的多分支代码在代码的不同部分重复,现在该功能在其自己的方法中只出现一次。
根据上面的描述,实现是不完整的,因为我们仍然需要实例化具体的类。工厂方法模式拯救了我们。它将对象的创建集中在一个点上,这是我们需要编写等级切换的唯一点。一旦创建了对象,就决定了它的行为,不再需要检查它的类型。
这种模式的一个特殊例子是,相同的条件在同一个函数中出现两次或更多次。例如,让我们假设我们正在编写深度学习代码,我们有一个在两个不同任务之间共享参数的模型:一个接收文本输入,一个接收音频输入。共享参数前有一部分,共享参数后有一部分,这取决于输入的维数:
在这种特定的情况下,通过为每种输入类型使用不同的函数来编写重复的文字x = self.trunk_encode(x)
可能比上面的代码更好。事实上,我们增加了毫无意义的复杂性,导致读者的高认知开销。此外,具有多个分支的代码在修改过程中更容易出错(在我的皮肤上试过)。
具有多个函数的一个变体,可以是只写一次条件而不是多次,并且一起写属于一个分支的所有代码。DRY(不要重复自己)原则不适用于这里重复的代码(在这里是 x = self.trunk_encode(x)
),因为它增加了复杂性。此外,DRY 是关于集中知识,而不是编写更少的代码,这里的知识已经在 trunk_encode 方法内部了。
https://annageller.com/blog/dont-repeat-yourself-is-beneficial-not-only-in-software-engineering
模式 2:可变状态
面向对象编程中经常提到的一个问题是,数据和对数据的操作(方法)被打包在一个类中。这些方法作用于状态,并以“受控”的方式改变它,也就是说,外部代码不能直接访问表示状态的内部属性,而必须使用类的公共接口。
这一切都是好的和合理的,除了它仍然会导致微妙的错误。的确,所有由可变状态构成的代码都很容易导致 bug。让我们考虑这个例子
这里的 bug 很明显,discounted_items 与 bill.items 是完全相同的列表,当打印最后两行时,值将是相同的,完整的价格将会丢失。
在这种情况下,我们考虑的是一小段代码,很容易发现,但是在复杂的代码库中,我们可能会将 bill 对象传递给一个方法,该方法调用 apply_discount(并且不将它写在 docstring 中)。在这种情况下,我们将在没有注意到的情况下修改价格。
这种类型的错误确实很烦人,而且很难发现,但是幸运的是有一个明确的解决方案:不变性。
解决方案:不变性
当把我们的对象传递给我们不信任的代码时,模拟不变性的一个简单方法是使用防御副本。尽管名字像打仗一样,但它只是意味着在将对象作为参数传递给函数之前复制一个对象。副本应该是递归的(或者 python 中的 deepcopy ),因为副本的内部容器应该与原始容器没有任何共同之处,否则防御性副本将不起作用。回到我们的例子,浅层拷贝只会拷贝对 self.items 的引用,所以对拷贝的修改在原始拷贝中也是可见的。
这就是在我们的例子中如何实现防御性复制
另一个更简单的方法是不要用包含折扣价格的新列表替换 self.items,而是创建一个新列表并返回它。这不会影响我们的内部状态。
错误的另一个来源可能是 add_item 方法,如果我们对账单中的项目数量有预期,但这些项目并不匹配,因为有人在某个地方调用了 add_item。
在这种情况下,我们可以使用另一种技术来防止我们的对象发生变异。它被称为写时复制,包括每次我们写可变对象时创建并返回一个新对象。
回到我们的例子:
在这种情况下,我们从不就地修改我们的 bill 对象。我们总是创建一个新的对象并重新分配变量。这当然会带来性能开销,但是除非数据非常大,否则您可能不会真正感觉到这一点。另一方面,它减少了错误的发生,因为对代码进行推理变得更容易,因为您不必担心可能的数据更改。
当您的不可变对象作为参数传递给不属于您的代码时,您仍然可以确保它们的状态在外部代码终止期间和之后是相同的。
模式 3:复杂的控制流
编写复杂代码的另一种方式是使用嵌套的 if-else 条件和循环来创建复杂的控制流,所有这些都放在多个缩进层中。
例如,假设我们有一个电子商务,营销部门决定发布一个促销活动。他们希望对选定的产品应用折扣:库存超过 10000 件的电子产品将有 20%的折扣,对于所有其他类别,促销针对库存超过 500 件的所有产品。价格低于 1000 美元的商品享受 50%的折扣,价格高于 500 美元的商品享受 30%的折扣。
直接翻译成 python 应该是这样的:
尽管逻辑并不特别复杂,但要理解上面的代码可能很难,因为我们需要跟踪所有可能的路径。由于我们需要记住所有的条件,所以在到达终点之前,我们的工作记忆将被完全占用。如果增加更多分支,情况只会变得更糟。
当我们对代码进行推理的可能性被它的复杂性所阻碍时,我们努力识别我们逻辑中的错误,并最终识别代码错误。
解决方案:拆分代码
我们的问题是我们需要记住大量的信息来理解代码。发生这种情况是因为有一个函数将关于产品类别的代码和概念放在一起,直到一个项目的结构。这是由多个循环丰富的,这些循环本身就很复杂。
然后,在实现细粒度的实现之前,我们可以使用分块来提高代码的抽象级别,使其更具可读性。
通常容易遵循的一条规则是将循环和条件放在它们自己的函数中:
这段代码看起来比前一段长了 10 行代码(最初的 15 行),但需要注意的是,其中 6 行是由 PEP8 强加的空白 likes,3 行是额外的函数签名,逻辑代码根本没有增加。
我们在这段代码中所做的是,首先提取一个类别中所有项目的循环,注意到它在两个分支中都是相同的:我们总是循环该类别中的所有项目,然后根据条件决定是否将一个项目添加到我们的列表中(使用折扣率)。然后,我们提取条件和关联贴现率,并将它们放入每个分行的一个函数中。
我们实现的是隔离每个功能的逻辑。第一个函数是非常高级的,它告诉我们要扫描所有产品,以检查电子产品和其他产品是否有两种不同的促销方式。然后,我们看到这种扫描只是简单地遍历所有产品,并对每个产品应用一个函数,将我们的促销列表作为一个附加值传递。最后,在最后两个函数中,我们隔离了将两个类别的商品添加到促销中的逻辑。
有了这样一个清晰划分不同抽象层次的结构,对代码进行推理就变得更加容易,因为每时每刻都有更少的信息需要记住,因此发现错误也变得更加容易。
结论
我们经常听到“这只是一个实现细节”的说法,但是编程都是关于实现细节的。用另一个符号改变一个符号,用一个相似的符号改变一个变量名,代码行为就偏离了初衷。
因此,逻辑错误(也称为 bug)不可能从任何足够复杂的代码库中消除。我们可以成为世界上最好的程序员,但是代码库将包含太多的信息,我们在给定的时间里只能记住这些信息。信息过载阻碍了我们对代码做出全意识的决定,这通常是错误产生的原因。
在本文中,我们回顾了复杂代码的三种模式,它们可以长期隐藏错误:重复的条件、可变的状态和深度嵌套的控制流。
在第一种模式中,当同一个分支在一个函数中多次出现时(或者更糟,在一个模块中的所有函数中,或者在一个类中的所有方法中),我们必须记住该怎么做,此外,当我们修改代码时,我们需要记住更新分支出现的所有地方。
在第二种模式中,我们读取假定状态为某些值的代码,但是某些东西在我们没有注意到的情况下改变了状态。
在第三种模式中,我们有多个控制流语句在多个标识级别中相互嵌套,当我们阅读代码时,我们会感到脑袋塞满了东西,因为有太多的信息需要记住。
在所有情况下,解决方案都是降低复杂性,要么抽象出循环或条件分支,使用多态性对与类型相关的方法进行分组,要么防止我们的对象发生意外变异。
这些保持代码简单的技术将帮助您减少在日常工作中产生的错误,并使您的代码对您的同事更具可读性。
我知道,这是一个漫长的过程。谢谢你一直读到最后!
参考
设计模式最全面的介绍可以在 Gamma Erich,Helm Richard,Johnson Ralph,Vlissides John 的设计模式:可重用面向对象软件的元素中找到。
代码重构的技巧可以在马丁·福勒的书中找到,这本书介绍了概念重构:改进现有代码的设计,他实际上写了关于这个主题的博士论文。
Eric Normand 所著的《追求简单性:用函数式思维驯服复杂软件》一书提倡通过使用函数式编程中的不可变性和其他技术来实现基于代码简单性的方法。
更多来自我