TowardsDataScience-博客中文翻译-2022-四十八-
TowardsDataScience 博客中文翻译 2022(四十八)
Tensorflow vs PyTorch 示例
原文:https://towardsdatascience.com/tensorflow-vs-pytorch-by-example-66d37901c663
如何将每个深度学习框架应用于 MNIST 问题
在 20 世纪 90 年代末,机器学习研究人员正在尝试在分层架构中创建人工神经网络的方法,这些网络可以执行简单的计算机视觉任务。机器学习是编写可以从数据中学习的算法的科学。
计算机视觉算法的一个经典基准是它们在 MNIST 数据库上的性能。
这个数据库的名字代表修改后的国家标准与技术研究院,由 70000 张手写数字的小图片组成,每张图片都表示为 28x28 像素的灰度色值网格。
一些来自 MNIST 数据库的样本,作者 Josef Steppan,来自维基共享资源。 CC BY-SA 4.0
每个图像都标有它所代表的数字。该算法面临的挑战是做人类容易做到的事情:看着图片,告诉我们这是什么数字。
Yann Lecun 及其合作者在 1998 年发表的论文向世界介绍了 MNIST 数据库,并表明卷积神经网络(CNN)优于其他技术。LeNet-5 架构的错误率仅为 0.8%。
在此后的几年里,卷积网络仍然是最先进模型中使用的首选技术之一,公布的错误率降至 0.2%左右。
由于在 MNIST 上训练深度学习分类器现在是数据科学家基础培训的一部分,唯一的问题是:我使用什么深度学习框架?
我将向您展示如何使用两个最流行的深度学习框架来解决这个分类问题:PyTorch(由脸书开发)和 Tensorflow(由谷歌开发)。
对于自己的项目应该选择哪个?
归结为个人喜好。试试下面的例子,看看哪个框架对你来说更自然。我看到 PyTorch 经常在学术研究环境中使用,Tensorflow 经常在许多商业应用程序中使用,但是每种都有许多反例。
这两个库都利用了 GPU 加速,有很好的文档,并且有支持它们的大型在线社区。不管怎样,你都会得到很好的照顾。
深度学习神经网络架构
卷积神经网络对输入样本进行“核”扫描,然后 对所有重叠的单元进行卷积 以计算乘积,在我们的例子中是一种平滑的输出图像。这是为网络中单个卷积层的许多内核中的每一个执行的。核可以具有例如增强垂直线或水平线的外观的属性。这为神经网络提供了更多的“特征”来进行预测。
在 MNIST 数据集上训练的典型卷积神经网络结构。
卷积层可以堆叠,因此一组新的核与前一层的输出进行卷积。
可以想象,这种架构会产生大量可调参数。即使很小的 CNN 也可以有上万个参数,这就是为什么只有在更强大的计算机出现后,训练它们才成为可能。GPU 在这方面帮助很大。
在 CNN 的最后几层,通常会看到完全连接的多层感知器执行最终的分类或回归任务。
导入和定义
让我们通过导入必要的库并设置我们的常量来了解一些基础知识。
Pytorch
我试图在张量流中保持它的相似性。
张量流
加载数据
现在,我们加载 MNIST 数据并将其标准化。通过归一化,我意思是转换它,使得平均每个 28×28 图像具有零平均值和单位标准偏差。
Pytorch
MNIST 数据驻留在torchvision.datasets
中。
张量流
MNIST 数据驻留在tensorflow_datasets
中。
定义神经网络架构
每个深度学习框架都有自己的方式来定义你试图构建的神经网络架构。这可能需要一些技巧,所以在构建自己的自定义网络时,花时间查看文档是值得的。
Pytorch
张量流
自从keras
库并入 Tensorflow 后,定义神经网络的任务变得简单多了。Tensorflow 仍然公开底层接口,如果你需要的话,但我个人喜欢keras
让它变得如此简单。
选择优化程序和调度程序
优化器是用于在每批训练数据之后调整数千个参数的算法。有很多算法可以选择。我用的是 AdaDelta,一种自适应随机梯度下降算法。我设定了一个学习率,然后定义了一个调度器来慢慢收缩它。
Pytorch
张量流
训练模型
我发现 PyTorch 的方法倾向于强调非常明确的任务定义,而 Tensorflow 倾向于更紧凑的用户友好的定义。通过比较下面的两种方法,可以看出这一点。
Pytorch
张量流
保存模型
一旦您训练了您的模型,您可能希望将状态保存为检查点,以便您可以在以后加载它,而不必再次调整数据。PyTorch 和 Tensorflow 都使这变得相当容易。
Pytorch
张量流
Jupyter 笔记本的完整代码示例
希望这篇教程对你有所帮助。两个模型(非常相似)都达到了大约 99%的精确度。通过下面的链接,你可以在 Jupyter 笔记本上看到这两个例子的完整代码。从那里,你可以在谷歌联合实验室里发布任何一款笔记本。
https://github.com/mikhailklassen/CNN_MNIST
感谢
PyTorch 实现基于 PyTorch 开发团队提供的示例,可在 GitHub 这里获得。我对这段代码做了各种修改,以使它与 Tensorflow 示例相协调,并使它更适合在 Jupyter 笔记本中运行。
对于 Tensorflow 示例,我使用了 Amy Jang 的关于 Kaggle 的教程,该教程本身借用了 Keras 开发团队的示例和由 Yassine Ghouzam 编写的教程。为了与 PyTorch 示例保持一致,我再次对这段代码进行了各种修改。
用 Python 将火星地球化
原文:https://towardsdatascience.com/terraforming-mars-with-python-4c21ed75117f
通过想象力和色彩映射表的巧妙运用,让死亡的世界变得栩栩如生
图片作者。
学习新事物的最好方法是解决有趣或不寻常的问题。在这篇文章中,我将向你展示如何生成和操作高度先进的彩色地图,以生成每个人的第二喜欢的星球,火星的地形图。由于某个美国亿万富翁的大肆宣传,火星越来越多地出现在新闻中,现在人类很有可能在本世纪的某个时候在火星表面行走。尽管如此,除了想象天空中有一个红色的大球,很少有人真正知道火星长什么样。火星表面实际上有相当丰富的特征,从峡谷和火山口到火山。由于多年来的许多无人驾驶任务,它的地形已经被绘制得非常详细,可以毫不费力地查看,以获得对这颗行星实际情况的真实感受。如果你问这位作者,地球的地形图已经做得太烂了,所以是时候在另一个星球上尝试一下了。在这篇文章中,我将概述如何生成火星地形图,并通过彩色地图的魔力想象一个经过地形改造的火星会是什么样子,它的海洋会是什么样子,它的河流会流向哪里。
这主要是为了理解色彩映射表实际上是如何工作的,特别是如何正确地使用它们来解决特定的问题。
数据探索
像往常一样,第一件事是把火星地形数据下载到你想做数据可视化实验的任何地方。这些数据可以从美国政府这里获得,不受任何用户限制。现在需要注意的是,数据量非常大,达到了 2.3GB,所以要小心。
数据为 tif 格式,通过rasterio
加载到np.array
中。该阵列很大,尺寸为 23040 x 46090。值的范围映射到火星上的高度值。火星没有海洋,所以没有“海平面”作为海拔的参考点。不赘述,火星上的“海平面”定义为火星上的平均海拔。因此,负地形值是平均海拔以下的区域,正地形值是平均海拔以上的区域。奥林匹斯山是火星上最大的山,高度为 21241 米(相对于火星平均海拔),海拉斯盆地是火星上的最低点,深度为-8201 米(相对于火星平均海拔)。有趣的是,这意味着火星上最高点和最低点之间的差异(~30 公里)大于地球上珠穆朗玛峰和玛丽娜海沟之间的差异(~ 20 公里)。
绘制数据让我们知道我们面临的是什么。贯穿本教程的一个警告是,如果在标准的笔记本电脑上运行,运行代码,去泡一杯茶,当你回来时,代码将接近完成。数据源是巨大的,没有任何办法可以避免与大型数据集和matplotlib
绘图相关的长执行时间。
默认绘图。图片作者。
使用默认的色彩映射表揭示了一个问题,将地形值线性映射到色彩映射表会产生一个非常乏味的映射表,并且大部分特征会丢失。原因是大多数火星特征位于-8000-12000 米之间。从平均高度如此偏向海勒斯盆地而远离奥林匹斯山来看,这应该是显而易见的。以黄色显示的四座山占据了地球很小的一部分(就面积而言),但是因为它们很大(就海拔而言),彩色地图中四分之一的颜色只为它们而存在。因此,其余的特征被映射到小范围的颜色上,清晰度很差。
火星的主要特征位于默认的色彩图上。图片作者。
定义色彩映射表
为了解决这个问题,我们将创建一个颜色图,并打破一些数据可视化规则。严格地说,我们可能应该有一个在数据的最大值和最小值之间标准化的线性颜色图。然而,因为在这种情况下,只有四个高于 14000 米的要素和许多低于 14000 米的要素,我们将创建一个颜色图来映射-8201 米(我们数据中的最低点)和 14000 米之间的颜色,14000 米以上的所有要素都映射到颜色图中的最后一种颜色。不幸的是matplotlib
没有特别好的颜色图来显示地形。美国国家航空航天局使用这张作为他们的彩色地图来显示火星的地形,我们也将这样做。
下面是一段代码,它将创建一个色彩图,大致基于美国宇航局使用的色彩图,在-8210 米和 14000 米之间归一化,波段为 10 米。LinearSegmentedColormap
方法获取一个颜色列表并生成一个颜色图,其中N
颜色在列表中的颜色之间呈线性间隔。BoundaryNorm
类允许你将颜色图中的颜色映射到一组自定义值。在这种情况下,我们正在创建一个BoundaryNorm
对象,它将在-8210 和 14000 米之间绘制 10 米波段的颜色。举例来说,0-10m 之间的值将映射到一种颜色,10-20m 之间的值将映射到下一种颜色,依此类推。任何高于 14000 米的物体都将在色彩映射表中用最终的颜色来着色。
为了对我们新的色彩图有一个感觉,它被绘制在下面,并带有标签,大致描述了每个火星特征的位置。现在有更多的颜色来区分我们试图捕捉的大量价值范围。
火星的主要特征都在自定义的色彩图上。图片作者。
火星地形图现在可以用新的颜色图重新绘制,并且数值标准化。令人惊讶的是,仅仅通过改变颜色图和调整颜色映射到值的方式,两个图就可以如此不同。
火星地形,用我们定制的彩色地图绘制。图片作者。
我们可以更进一步,向图中添加标签来指出所有不同特征的位置。
火星地形,有一些值得注意的特征的标签。图片作者。
地球化火星
很明显,我们不会真的将火星地球化。然而,在这一节中,我们将通过生成一些类似“地球”的彩色地图来想象一个完全地形化的、潮湿的火星会是什么样子。这位作者将类似“地球”的颜色图定义为一种颜色图,对于海平面以下的值使用深蓝颜色,对于海平面以上的值使用绿棕颜色。
Matplotlib
有一个名为terrain
的颜色图,它就是用来完成这个任务的,但是我认为蓝色部分不够暗。幸运的是,还有另一个叫做ocean
的色彩图,通过组合它们,我们可以生成一个类似“地球”的色彩图。我们的目标是将两个颜色图结合在一起,创建一个BoundaryNorm
对象,将海平面以下的值映射到ocean
颜色图,将海平面以上的值映射到terrain
颜色图。
生成色彩映射表时,其中的颜色会在 0 到 1 的范围内进行线性索引。可以从颜色图中提取颜色列表,并通过提供索引列表来排除部分颜色图。例如,下面我们使用plt.cm.ocean(np.linspace(0.2, 0.8, 821))
,它从ocean
颜色图中返回 821 种颜色的列表,不包括颜色图中低于 0.2 和高于 0.8 的颜色。对terrain
颜色图也做了同样的事情,但是返回了 1400 种颜色。然后使用LinearSegmentedColourmap
方法将两个颜色列表合并成一个颜色图。
821 种ocean
颜色和 1400 种terrain
颜色的原因是因为我们希望我们的颜色图将地形映射到颜色。BoundaryNorm
类允许你将颜色图中的颜色映射到一组自定义值。在下面的代码中,我们用 2221 种颜色(821 种海洋+ 1400 种地形)和一个BoundaryNorm
对象创建了一个颜色图,该对象将根据预定义的级别将数据中的值映射到颜色图。这些级别设置为 0 以下有 821 个级别,0 以上有 1400 个级别。因此,我们数据中所有低于 0 的值都将使用色彩图的ocean
部分着色,所有高于 0 的值都将使用色彩图的terrain
部分着色。
图解说明海洋和地形颜色图是如何组合的。图片作者。
使用这种新的颜色图和颜色边界绘制数据,给出了一个几乎类似地球的行星。
一个地形化的、潮湿的火星会是什么样子?图片作者。
改变海平面
我们选择了一个任意的值作为我们假设的海平面,仅仅使用火星的平均高度作为海平面。然而,使用上述生成彩色地图的方法,可以改变海平面的位置。回想一下,我们生成了 2221 种颜色的颜色图,其中 821 种来自ocean
颜色图,1400 种来自terrain
颜色图。通过改变每个颜色图中的颜色数量,而不改变整个颜色图中的颜色总数,就有可能改变海平面的位置。或者更简单地说,蓝色停止,绿色开始。
下面是一个函数,用于获取海平面值,并生成一个用于绘图的颜色图和颜色边界对象。以一个假设的 3000 米的海平面为例,每 10 米映射一种颜色,所以我们需要增加 300 种颜色的ocean
和减少 300 种颜色的terrain
。
图解说明改变的颜色图看起来像什么。作者图片
这样就可以投入使用了。下面是一个例子,展示了如果海平面设定在平均海拔 1500 米以上,火星会是什么样子。模糊地对应着火星 70%的水覆盖率,这就是我们在地球上的情况。
地球改造的火星,海平面设定在平均海拔 1500 米以上。图片作者。
山体阴影
最后要做的事情是添加一些山体阴影来模拟光照在地形上,以使情节看起来更三维。山体阴影是表面的 3D 表示,通常以灰度渲染。较暗和较亮的颜色表示您在地形模型中看到的阴影和高光。山体阴影通常用作地图中的参考底图,以使数据看起来更加三维,从而在视觉上更加有趣。我们将使用earthpy
山体阴影函数来生成山体阴影数据。有两个参数可以调整,根据数据集的不同,它们会给出明显不同的结果。第一个是azimuth
值,范围为 0-360 度,与光源的发光位置有关。0 度对应于指向正北的光源。第二个是光源所在的altitude
,这些值的范围是 1-90。
结果基本上是相同的地图,但稍微夸张了一些,特别是在北部海洋。
带有山体阴影的地形化火星。图片作者。
结论
我们有了它,一个美丽的地图显示了如何在地球之外生成引人注目的数据可视化。这是计划展示如何使用 Python 使地理空间数据看起来令人惊叹的许多文章中的第一篇,请订阅以便您不会错过它们。我也喜欢反馈,所以请让我知道你会如何做不同或建议改变,使它看起来更棒。我每周都会在我的推特账户上发布数据可视化,看看地理空间数据可视化是不是你的菜https://twitter.com/PythonMaps
参考
TerrificEye:一个用于视频流量分析的边缘计算系统
我如何构建一个实时、独立的流量监控和分析系统
图 1:地形眼系统(图片由作者提供)
由于深网的规模和复杂性,数据量不断增长,这就要求通信网络具有更高的吞吐量。网络的带宽限制将成为未来数据处理系统的主要瓶颈。此外,数据隐私法(例如 GDPR)不鼓励记录个人数据,因此,在集中的存储库中收集、存储和处理数据变得更加困难。这需要从集中式云计算转变为基于分布式边缘的计算架构。这直接应用于数据分析领域,其主要目的不是收集数据,而是收集有意义的推论和统计数据,从而制定政策和决策。例如,路边交通分析系统收集和保存经过它的每个人或车辆的身份并不重要,但是,了解交通流量的数量、方向和类型有助于做出交通和基础设施政策决策。在本文中,我将构建这样一个系统,它可以处理视频并生成流量分析。
准备硬件
基于深度学习的数据处理系统需要高端嵌入式平台。有许多基于 SoC(片上系统)的主板是很好的选择。其中包括基于 arm 的主板(例如 Nvidia Xavier、Jetson series 或 Nano)。Nvidia 主板的好处在于,它们在小尺寸中拥有高端 GPU,这对深度学习应用至关重要。在本文中,我将使用 Nvidia 板——Jetson TK1,因为它在我的实验室的电子元件中被发现处于休眠状态。这是一款较老的主板,处理能力不如 Jetson Nano,但对于手头的任务来说应该足够了(至少对于实验演示来说)。
图 TerrificEye 系统中的硬件组件(图片由作者提供)
除了 Jetson TK1,我还有一个 10 英寸的液晶显示器。这是一个原始的液晶显示器,只有电源板可以点亮液晶显示器。但是,为了将它连接到 Jetson TK1,我必须移除旧板,并用从 ebay 购买的 HDMI 驱动板替换它。带驱动板的 LCD 需要 12V,消耗大约 1A 的功率,因此,除了 Jetson 的 12V 电源外,它还必须提供自己的独立适配器。
图 3: HDMI 驱动板(图片由 aliexpress.com 提供)
虽然 SoC 的整个目的是将整个系统包含在一个芯片/电路板中,但是这个电路板没有 Wifi,所以我们除了它还需要一个 USB 适配器。我使用一个便宜的 USB 适配器 TL-WN725N 来完成这项工作。
固件、驱动程序&库
✔ OS 上传
刻录 Jetson 系统的典型方法是使用 JetPack(一个独立的可执行应用程序),它预装了为 Nvidia 硬件定制的 Ubuntu 内核。然而,由于这是一个已经停止支持的旧主板,所以 Jetpack 包含一个旧的 Ubuntu 版本(14.04)和库,因此,我选择手动刻录固件和驱动程序。为此,我从 Nvidia archive 下载了最新支持的 L4T 驱动程序包和 Jetson TK1 的示例根文件系统。
然后,我将示例根文件系统放在 L4T 驱动程序包的 rootfs 文件夹中,并在 Ubuntu 主机系统中使用以下命令将图像刻录到 Jetson TK1 板上。(为了刻录固件,主板必须处于恢复模式)
sudo ./apply_binaries.shsudo ./flash.sh -S 14580MiB jetson-tk1 mmcblk0p1
注意:在 64 位主机系统上, mkfs 命令默认使用 64 位闪存,因为 TK1 是 armv7,所以我们需要修改 flash.sh 以使其工作。
在 flash.sh 文件中找到下面一行:
mkfs -t $4 ${loop_dev} > /dev/null 2>&1;
并替换为以下内容:
mkfs -t $4 -O ^metadata_csum,64bit ${loop_dev} > /dev/null 2>&1;
现在,Jetson TK1 应该使用 Ubuntu 14.04 和预建的 Nvidia 驱动程序启动。在它启动后,我通过' sudo apt-get update '和' sudo apt-get upgrade '以及' sudo do-release-upgrade '将 Ubuntu 14.04 升级到了 16.04。Ubuntu 16.04 的安装进展顺利,但是,有一点非常重要,在升级之前,你必须持有原始的 Xorg ,因为新的 Ubuntu 将清除旧的 Nvidia 驱动程序,并且没有对该板的支持,所以 Xenial Ubuntu 中没有新的驱动程序。这可以通过在升级前运行以下命令来实现:
sudo apt-mark hold xserver-xorg-core
升级后,进入 ssh 并运行以下命令,重新安装 gnome 会话:
sudo apt-get install gnome-session-flashback
✔ 图书馆
现在 Ubuntu 16.04 可以顺利启动了。是时候安装 python 和所需的库了,比如 OpenCV。但是,没有针对 armv7 架构的 python 3.7 预构建二进制文件。所以,我从源代码中构建了 python 3.7 和 numpy 。这意味着构建相关的库,比如来自源代码的 scipy、scikit-image 和 scikit-learn 。这花了很多时间,需要耐心和仔细消除编译错误。
python 编译安装后,我从源码编译了 OpenCV 库。在 CMake 中,我设置了配置参数,-DWITH_CUDA,-DWITH_DNN,-DOPENCV_DNN_CUDA=ON。为了成功编译,我必须安装旧版本的 gcc 编译器(4.8),因为新版本(> 5.0)与 CUDA 6.5 工具包不兼容,由于对该板的支持已终止,该工具包无法针对该板进行升级。
OpenCV 的编译是一项资源密集型工作,它导致 Jetson TK1 上有限的(2GB) RAM 耗尽。因此,为了成功编译,我在 mmc 卡上创建了一个交换文件,如下所示:
fallocate -l 4G /mnt/sd-card/swapfilechmod 600 /mnt/sd-card/swapfilemkswap /mnt/sd-card/swapfileswapon /mnt/sd-card/swapfile
在成功编译 OpenCV 之后,我编译了 OpenCV-Python(OpenCV 的 Python 集成),并设置了环境变量,以便它能够与 anaconda 环境一起工作。
✔ Wifi 驱动
Wifi 适配器没有预建的驱动程序,所以我必须从源代码中构建它。我从下面的链接下载了源代码,然后编译了内核模块和 linux 内核源代码,然后将驱动程序加载到正在运行的内核中。
https://www.tp-link.com/us/support/download/tl-wn725n/
检测&跟踪
驱动和库编译成功后,真正有趣的远景部分来了。一个好的分析系统的支柱是对象检测和跟踪系统。在这篇文章中,我选择了最新版本的 YOLOv4(你只看一次)来检测对象。经典的 YOLO 网络在 Jetson TK1 上不是实时的,所以我用 YOLO·泰尼来做这项工作。它给出了令人满意的 15fps 检测,这意味着我可以实时运行系统来生成分析。我从以下来源编译了 YOLO 实现:
https://github.com/AlexeyAB/darknet
注:由于与 CUDA 6.5 和 gcc 版本不兼容,在编译过程中出现了一些问题。为了编译成功,需要对暗网的源代码做一些改动。
对于跟踪,我首先尝试了相关性跟踪器,但是,我很快意识到这是一个矫枉过正的工作。由于不希望物体总是靠得太近,所以简单的基于位置的跟踪器就足够了(例如质心跟踪器)。这意味着我可以实时运行整个探测器-跟踪器组合。
图 4:道路场景中物体的检测和跟踪(图片由作者提供)
为了进一步完善系统,我将感兴趣的对象减少到一组更相关的对象(例如,人、汽车、公共汽车和自行车)。这进一步减少了错误的分类,这种错误的分类由于使用 YOLO Tiny 而有所增加,因为它没有原来更大的网络精确。然后,我还对检测到的对象运行了一遍非最大值抑制,以便过滤低置信度的检测。这进一步增加了探测和跟踪系统的稳定性。
生成分析
在成功检测和跟踪道路场景中的有趣/相关对象后,是时候生成分析了。为了简单起见,我计算了所选感兴趣对象的入站流量计数、出站流量计数和类别计数。通过检测图像中指定位置的线交叉来计算流入和流出。这些统计数据对于初始演示应该足够了,更复杂的分析可以在系统更新时进行计算。除了自己收集的交通场景视频,我还使用了麻省理工学院的交通数据集进行评估。
https://mmlab.ie.cuhk.edu.hk/datasets/mit_traffic/index.html
结论
在这篇文章中,我分享了流量监控和分析系统的构建。该系统是独立的和自包含的,数据和处理都在同一点执行。该系统功能强大,可以实时检测、跟踪和分析多个对象。有了更好的嵌入式 Soc(如 Nvidia Nano),系统在精度和效率方面的表现会好得多。
特斯拉人工智能日:擎天柱机器人比任何人预期的都要好
原文:https://towardsdatascience.com/tesla-ai-day-optimus-bot-was-better-than-anyone-expected-b271409b71f9
但是还远远没有解决机器人真正的难题
擎天柱。信用:特斯拉+ DALL E
今天,我为大家带来了对特斯拉自主人形机器人 Optimus 的分析,该机器人于周五在 2022 年人工智能日发布。正如我一直试图做的那样,这是一个突出好的和坏的细微差别。
去年的人工智能日尤其令人兴奋,因为马斯克透露特斯拉正在研究 Optimus,这是一个旨在“消除危险、重复和无聊任务”的机器人,能够遵循用自然语言表达的命令,如“捡起那个螺栓,用那个扳手把它装到车上。”(还记得谷歌的 PaLM-SayCan 吗?)
马斯克还承诺他们将为 2022 年的人工智能日提供一个工作原型,鉴于不切实际的最后期限,这让一些人兴奋不已,并提醒其他人他有过度承诺和交付不足的倾向。我属于后一组。
在我们深入讨论之前,让我提醒你,人工智能日显然是为了招聘目的:目标受众不是记者或投资者,而是工程师。
这意味着大多数新闻媒体对这一事件的评论将仅限于描述其含义,而在分析其不足之处时不够深刻。我读过很多评论,说特斯拉周五展示的东西并不令人印象深刻(例如,因为它比波士顿动力公司(Boston Dynamics)落后好几年)。稍后将详细介绍)。嗯,我印象深刻——尽管只是部分印象。
但我印象深刻只是因为我没抱太大期望。
让我们从光明的一面开始。
本文选自 算法之桥 ,这是一份教育通讯,其目的是在算法和人之间架起一座桥梁。它将帮助你理解人工智能对你生活的影响,并开发工具来更好地导航未来。
https://thealgorithmicbridge.substack.com/subscribe
使 Optimus 脱颖而出的 5 个关键特征
五分钟后,在欢呼和掌声中,马斯克给特斯拉机器人让路。门打开了,一个站立的人类高度的无壳机器人进入舞台,它有可见的电缆和马达。它走路、转身、向观众挥手,还表演了一小段舞蹈(向去年的节目致敬?).
正如马斯克后来解释的那样,这不是 Optimus,而是一个名为 Bumble C 的开发平台,由现成的零件构建而成,用于设计和测试机器人的系统和模块(他们花了 6 个月的时间进行这项工作)。Optimus 是 Bumble C 的下一代产品化版本,为了避免不必要的混淆,在整篇文章中我只提到 Optimus。
他们随后展示了几个视频,展示了擎天柱做的比行走和挥手更复杂的任务:用手搬运箱子,抓取和使用喷壶,以及拿着和移动一个看似沉重的金属物体。尽管机器人专家将此描述为人形机器人的标准,但有几个特征使得特斯拉机器人值得关注。
克里斯蒂安·胡比基的推特
擎天柱深受人体的启发
世界是人类为了人类而创造的。这是建造人形机器人而不是其他形状的最强有力的论据。人体的灵活性和多功能性是无与伦比的。Optimus 的关节和致动器的设计揭示了模仿我们的解剖学的意图。例如,机器人的手有五个独立移动的手指和相对的拇指,特斯拉声称它们可以适应性地抓取东西——有力量或精确——并可以使用工具。
但进化是一种随机搜索的持续优化机制,这导致了我们可以通过智能设计避免的权衡的必要性:盲目遵循生物学的步骤不一定是最好的方法。最常见的例子是飞机。擎天柱没什么不同。人类的身体有许多和许多自由度,但没必要跑到最后一英里去把如此复杂的东西实现成机器人。擎天柱有 28 只以上的手(11),这足以让它能够独立移动手臂、手和每个手指,显示出合理的灵巧。
就效率而言,生物学也不是最好的大师。人类的身体并没有达到应有的效率(我们躺下时消耗了太多的能量),这也是特斯拉工程师的一个关注点:如果你想设计一个大规模量产的机器人,成本和效率是优先考虑的因素。
底线:关键是在“真正的人类”机器人、成本和效率之间找到平衡。
擎天柱由最新一代人工智能驱动
正如马斯克去年所说,特斯拉不是一家汽车公司,而是“可以说是世界上最大的机器人公司。”制造自动驾驶汽车比制造人形自主机器人更容易,但两者都属于现实世界人工智能的范畴。特斯拉自动驾驶工程总监米兰·科瓦奇表示,从自动驾驶汽车到 Optimus 就像“从有轮子的机器人到腿”
这意味着为自动驾驶汽车提供动力的人工智能——即使不完整和不完美——可以“容易地”转移到 Optimus。这是擎天柱区别于其他更敏捷、身体更强壮的同类的特征。BD 的 Atlas 在运动能力方面领先数年,但它不像 Optimus 那样由人工智能驱动。预编程机器人不太适合开放式任务,因为它们无法对不断变化的世界做出反应。在这方面,Optimus 更接近谷歌的 PaLM-SayCan,它也非常依赖 AI 的力量。
鉴于擎天柱的广阔视野,它很难与大多数其他人形机器人相比。它在物理层面(运动技能和灵活性)和在认知层面(它如何感知、规划和导航世界)竞争。正如马斯克所说,其他人形机器人“缺少一个大脑,它们不具备独自导航世界的智能。”
擎天柱的进步速度是前所未有的
人们不断重复说 BD 比 Tesla 领先几年,但是测试 Optimus 和 Atlas 并不是苹果与苹果的比较。首先,目标非常不同(BD 专注于“运动智能”,而特斯拉想要一个通用机器人)。第二,特斯拉的工程师仅仅用了一年时间就做出了 Optimus 的原型,而 BD 的 Atlas 已经有 10 多年的历史了。
我的一个(失败的)预测是,特斯拉不会为今年的人工智能日准备好工作原型。的确,这款机器人还没有准备好投入生产,并且缺少马斯克承诺的一些功能(稍后会有更多介绍),但它仍然可以工作。如果说擎天柱的启示令人印象深刻的原因之一是:在仅仅 6-8 个月的时间里,他们设法用现成的零件制造了一个工作机器人。如果我们把这种发展速度推算到未来,五年后,我们可能会真正印象深刻。
利用特斯拉的专业知识和能力
但是这怎么可能呢?工程团队是如何在不到一年的时间里完成这样的壮举的?
马斯克解释了特斯拉的垂直整合性质如何允许他们将自动驾驶汽车所用的技术转移和整合到人形车身中。特斯拉的工程专业知识和基础设施非常适合应对这一挑战:专注于自主性、超级计算、“识别世界的神经网络”,以及通常的现实世界人工智能——传感器和执行器。
特斯拉工程师已经使用结构分析模拟(车祸)和损害控制来找到接头和零件的破裂阈值。他们利用自己的制造知识来评估致动器的最佳标准设计(减少到只有 6 个不同的元素),他们将 FSD 硬件和软件转移到机器人中,并将经过训练的神经网络集成到机器人的视觉模块中。从轮子上的机器人到腿上的机器人。
使 Optimus 可扩展:成本和效率
马斯克强调,擎天柱和其他“令人印象深刻”的人形机器人之间的一个关键区别是,特斯拉机器人是为大规模生产而设计的。这使得低成本和高效率成为最优先的要求。像 BD 的 Atlas 这样的机器人,正如马斯克所说,“非常昂贵,而且产量很低。”特斯拉希望擎天柱是一个“非常大批量生产的非常有能力的机器人。”他补充说,他们希望建造“数百万个单元”,这些单元“比一辆汽车便宜得多……可能不到 2 万美元”
BD 的 Atlas 是一个很贵的研究平台(我记得在某个地方看到过 100 万美元但是找不到来源)。BD 的机器狗是一种消费产品,价格为 75000 美元。这是马斯克承诺的擎天柱几年后的 3 倍(我对这个预测持保留态度。即使利用特斯拉的技术和北极星的规模生产,我也看不出他们将如何设法降低成本这么多)。
但是 Atlas 不是为生产设计的(这是停止比较它们的另一个理由)。在这方面,Optimus 更接近于 Agility Robotics 的数字,这是一种旨在大规模执行工厂工作的机器人。现在由亚马逊支持的 Agility Robotics 比特斯拉有几年的优势,但缺乏后者优化的基础设施。擎天柱和 Digit 在不久的将来可能会成为势均力敌的竞争对手。
擎天柱测试了现实世界——和我的预测
现在让我们深入到不那么光明的一面:擎天柱的局限和不足,既有看了 AI day 后明显的,也有不那么明显的。Optimus 的工程团队实现的快速周转是伟大的,但从绝对意义上来说,这仍然是不够的。
我在上面写道,我没能预测到特斯拉在 2022 年不会有“工作原型”。实际上,我只是部分预测错误。原因是当我做预测的时候,我对人形机器人的想法和现在的擎天柱完全不同。
在我去年写的一篇题为“为什么特斯拉在 2022 年不会有自主人形机器人”的文章中,我列出了一些论点,解释了为什么建造一个真正的(这种细微差别很重要)自主人形机器人是一个令人生畏的挑战。我还描述了 Optimus 需要哪些特性来解决最简单的现实任务。
在这一节中,我将概述这些特性,并解释为什么 Optimus 还没有为现实世界做好准备(而且不会很快),使用我们目前所知道的(并使用我去年文章中的评论)。
我们生活在一个多模态的世界
“人类可以感知颜色、质地、味道、气味、温度、压力……我们的大脑是多感官的。我们的感知系统捕捉世界的多模态本质,我们的大脑 将 整合成现实的单一表征。当你吃苹果时,你可以看到它略带红色的色调,尝到它的甜味,闻到它的香味,感觉到它柔软的触感。所有的一切都同时存在。
Optimus 不是用来品尝或闻的,但至少,它需要视觉、触觉和触觉(压力)传感器、本体感受——感知四肢相对于身体其他部分的运动和位置的能力——以及了解其身体可以采取行动的程度的表征。”
特斯拉工程师提到了在擎天柱中灌输自我参照、本体感受、平衡和协调的意识是多么重要。我概述的大部分功能似乎都存在于下一代 Optimus 版本中。
当然,技能的质量和程度很重要。对手的位置有一些模糊的参考是无法与人类的本体感受技能相比的。擎天柱——那个会走路的——似乎很容易受到干扰。例如,BD 的 Atlas 已经显示出在不利条件下保持平衡的非凡能力(即使人类将它推回足以使它后退几步)。
这个世界努力吸引我们的注意力
“人类的感知系统带来了太多的信息。大脑利用注意力来决定哪些事件或物体得到偏爱。擎天柱也需要以同样的方式在感知空间中导航。
多模态感知和注意力的结合将使擎天柱对世界的复杂性有一个非常好的感知,同时允许它只根据最关键和最紧迫的信息做出决定。
但是擎天柱怎么知道哪些感知需要偏好呢?它如何决定向左或向右寻找岩石?当走回地下室时,它如何决定将注意力集中在岩石、手或脚上?注意力的神经机制非常复杂 尚未完全了解 。泰斯拉如何设计出一个人造大脑,能够正确地分配对无数不同感知的注意力?”
没有机器人拥有接近人类水平的注意力机制(基于变压器的注意力只是在名称上类似于人类的注意力)。然而,没有注意力——被理解为感知的层次化——我们就无法运作。
有人可能会说,机器人不需要那么多模态信息就能足够好地工作,但这在很大程度上取决于环境。
自动驾驶汽车受到道路和高速公路的限制,但这不能外推至工厂或家庭。我们感知的现实越丰富、越多变,我们就越需要注意力来完成任何特定的任务。
计划、决定、行动
“这是擎天柱在火星表面寻找灰色玄武岩时决策过程的一小部分[我用这个例子是因为我认为马斯克最终会在 SpaceX 火星任务中使用擎天柱]:
我应该走多少步,往哪个方向走?这块岩石是灰色、蓝色还是紫色的?我应该找块小点的石头吗?或许更大一点?我应该盯着石头不让它从我手上掉下来,还是应该把眼睛放在脚上以免被另一块石头绊倒?我是应该走得慢一点,这样我会用更少的能量,还是应该走得快一点,这样我能更快到达地下室?…
即使是最简单的顺序也揭示了我们无时无刻不在不知不觉中做出的令人难以置信的大量选择。像煮咖啡这样简单的事情——我们每天早上都会做——被认为是对 AGI 水平智力的测试。我们人类 评估 我们可以根据成功的可能性和它们提供的价值来选择。当目标不明确和不确定时,计算变得不那么精确,因此我们进入了直觉的领域。但是机器人能有直觉吗?
然后就是如何执行计划的问题……人形机器人的自由度数量要比汽车多很多个数量级。一个 3D 环境,它可以走/跑/跳的方向或幅度没有限制,以及一个灵活的身体——头、躯干、四肢和手指可以以无数种组合相对于世界和彼此移动——所有这些都需要一定程度的工程,只有进化才能实现。”
特斯拉工程师简要展示了 Optimus 的规划能力,但没有深入研究决策的细节以及制造功能性现实世界机器人的困难,这些机器人可以根据他们的目标在世界上行动,同时克服不可预测的挑战。
即使特斯拉自动驾驶汽车设法从 A 点到 B 点而没有撞车,该技术在边缘情况下仍然不可靠(我们不应该通过分析常见情况来评估 Optimus 的准备情况,而是极端情况)。这意味着无人驾驶汽车还没有完全解决。
这项技术还没有准备好(即使特斯拉有数百万辆的车队在美国道路上行驶):世界上存在太多的可变性,适用于汽车的限制也适用于 Optimus——乘以它将面临的场景的复杂性的增加。
是什么让我们成为人类——更高的认知
除了感觉运动功能,以及注意力和决策的相关过程,我还提到了语言、常识和因果推理是人形机器人的关键特征。
“就语言而言,这种必要性是显而易见的,因为我们想向擎天柱发出口头命令,而不需要明确的指令……专家们发现了GPT 3 号的重要缺陷,主要原因是它缺乏与现实世界的联系——这是虚拟人工智能的巨大弱点。它无法获得语用学和语境信息。如果我说:“去找一块灰色的玄武岩,”擎天柱需要知道什么是岩石,灰色是什么意思,以及如何区分玄武岩和火山渣。我们知道如何在现实世界的人工智能中灌输这样的语言能力吗?*。”***
即使 Optimus 在视觉方面很棒(由 FSD 硬件和软件提供),它还没有自然语言界面。马斯克去年承诺,我们可以用自然语言给机器人下达命令,但这似乎不是工厂机器人的优先事项。PaLM-SayCan 在这方面走在了前面,因为它是由现存的性能最好的大型语言模型(LLM)驱动的。
尽管如此,即使是谷歌的机器人也无法克服我去年描述的挑战:语用学和上下文对于虚拟人工智能来说是遥不可及的,即使那些为现实世界的机器人提供动力。为了成功地将人工智能和机器人技术结合起来,使整个系统获得对世界的深刻理解,仍然缺少一些东西。
“因果推理是理解某些事件有助于产生其他事件的能力。例如,如果天空中有云并开始下雨,我们知道是云导致了雨,而不是相反。如果擎天柱在寻找灰色的玄武岩,知道这些岩石是由火山形成的会很有用。它可以寻找地平线上最近的火山,而不是试图通过搜索地面来找到岩石。”
我再次用火星的故事说明了因果推理的必要性。但这也适用于任何真实世界的环境,无论是特斯拉工厂还是你的家。当然,擎天柱离实现这一目标还很远——其他形式的 SOTA 人工智能系统也是如此。
图灵奖得主朱迪亚·珀尔(Judea Pearl)长期以来一直主张给机器灌输对因果关系的理解,以实现人类水平的智能(尽管这不一定是特斯拉对擎天柱的目标)。
常识推理存在于日常生活中。我们不断应用所有人共享的知识。如果我们在做饭,我们知道锅是热的,我们不应该碰它。如果下雨,我们在外面会淋湿的,除非我们带把伞。如果一辆车开得很快,我们不应该过马路。
Gary Marcus 教授、深度学习先驱 Yann LeCun 和其他人一直非常明确地表示有必要教授人工智能常识——人们普遍分享的知识。机器人没有常识。他们不在我们的文化和社会中成长,也不享受为我们提供对物理世界动态如何运作的直观理解的进化天赋。
结论
称擎天柱为自主机器人在任何意义上都有些牵强。人类——真正自主的人——在数百万年的进化中发展了这种自主性。制造一个自主的通用人形机器人可能是人工智能目前可能面临的最大挑战(除了 AGI,尽管我怀疑两者在很大程度上是交织在一起的)。
即使特斯拉工程师渴望建造一个受生物学启发的人工智能机器人,他们也不会像他们大胆声称的那样,创造出“它将做人类做的一切”的东西。擎天柱在任何层面都不是人类可比的。
尽管有明显的限制(一些关于擎天柱,一些关于机器人),我仍然对特斯拉的表现印象深刻。如果你只有半年的时间来完成,制造一个步行机器人是很难的。但是我们不应该仅仅用相对的术语来分析这些结果,而且,从绝对的意义上来说,特斯拉所展示的,尽管比预期的多,却比要求的少。
订阅 算法桥 。弥合算法和人之间的鸿沟。关于与你生活相关的人工智能的时事通讯。
您也可以直接支持我在 Medium 上的工作,并通过使用我的推荐链接 这里 成为会员来获得无限制的访问权限!:**
在 AWS EMR 上试驾 Delta Lake 2.0 项重要经验
原文:https://towardsdatascience.com/test-driving-delta-lake-2-0-on-aws-emr-7-key-learnings-821aa515d247
在 AWS EMR 上使用 Delta Lake 2.0 后,我学到了什么,以及安装步骤和性能基准
路易斯·索萨在 Unsplash 上拍摄的照片
如果你读过我以前的一篇关于在 AWS 中开始使用 Delta Lake 的文章,你就会了解 Delta Lake 等产品为什么越来越受欢迎以及它们解决了什么类型的用例的基本背景和基本原理。本文介绍了在 AWS EC2 上开始使用 Delta Lake 的简单步骤,尽管您可以使用该方法来处理一些简单的用例,但在可伸缩性和编目方面仍然有一些限制。因此,如果您想要在相对复杂的用例上工作,保证以下几点:
- 使用可扩展的基础设施,即由多个虚拟机组成,在 Spark 上对大数据集进行分布式计算,增加了灵活性,即能够根据需要轻松扩展或缩减
- 使用 AWS Glue 作为目录(即,将其配置为 Apache Spark 的 Hive metastore)
如果您不想自己进行上述配置,那么有几个选择:
- 考虑提供三角洲湖解决方案的商业供应商,例如 Databricks
- 在 AWS 中使用 Amazon Elastic MapReduce (EMR ),它提供托管 Hadoop 框架并在其上配置 Delta Lake
如果出于某种原因,第一个选项不太适合您,而您希望使用 AWS 原生服务,那么在这种情况下,EMR 可以是一种方法。然而,一个主要的问题是 EMR 本身并不支持 Delta Lake(像 Databricks 那样)。因此,在 EMR 上配置 Delta Lake 需要一些配置。
我最近处理了一个用例,在这个用例中,我在 EMR 上原型化了 Delta Lake,并希望利用这篇文章作为一个机会来分享从经验中获得的关键知识,以及性能基准和如何设置它的说明。
EMR 上的三角洲湖—配置步骤概述
首先,让我们谈谈如何在 EMR 上配置 Delta Lake。我特别想使用 Delta Lake 2.0,因为它提供了一些我想使用的命题,例如 z 排序。你可以阅读更多关于三角洲湖 2.0 和如果提供什么在这里。
在 EMR 上配置 Delta Lake 2.0 的核心步骤如下(或者至少我是这么做的):
- 使用以下服务启动 EMR:Spark、Hadoop
- 在 AWS 胶数据目录设置下,选择用于星火表元数据。
- 确保 EMR 使用的是最新版本的 Python,例如我使用的是 Python 3.9(稍后会详细介绍)
- 确保您的 EMR 主节点可以连接到互联网,例如通过 NAT 网关或 HTTP/HTTPS 代理,因为设置需要从 Maven 仓库下载 Delta Lake 2.0 依赖项。
- PySpark shell — 通过 SSH 访问 EMR 主节点,并运行此命令,以便在正确配置 Delta Lake 2.0 依赖项的情况下运行 PySpark shell:
pyspark --packages io.delta:delta-core_2.12:2.0.0 --conf "spark.sql.extensions=io.delta.sql.DeltaSparkSessionExtension" --conf "spark.sql.catalog.spark_catalog=org.apache.spark.sql.delta.catalog.DeltaCatalog" --conf "spark.driver.extraJavaOptions=-Duser.timezone=UTC
- Spark 提交作业— 用于运行 Spark 提交作业。在 EMR 集群中运行以下 py 脚本:
spark-submit --packages io.delta:delta-core_2.12:2.0.0 --conf "spark.sql.extensions=io.delta.sql.DeltaSparkSessionExtension" --conf "spark.sql.catalog.spark_catalog=org.apache.spark.sql.delta.catalog.DeltaCatalog" --conf "spark.driver.extraJavaOptions=-Duser.timezone=UTC helloworld.py
而 helloworld.py 看起来像这样:
在脚本中:
- 我们从 pyspark.sql 模块导入 sparkSession,因为它将在下一步中用于构建 Spark 对象。
- 我们创建 Spark 对象并指定其配置。具体来说,我们在这一步配置 Spark 使用 Delta Lake(第 5 行,第 6 行)
- 我们确保 AWS Glue 在 Spark 提交作业期间被用作 Hive Metastore(第 10 行,第 11 行)。您可能已经注意到,在运行 PySpark shell 时,我们不需要设置这个配置,但是在运行 spark-submit 时,这是必需的。否则,Spark 将不能与 Glue Catalog 集成,也不能使用那里定义的数据库和表。
- 我们读取 Spark 数据帧中的 Delta Lake 表(第 15 行),在其上创建一个临时视图(第 16 行),然后使用 Spark SQL 打印它的行数(第 17 行);只是为了证实这个系统以它的基本形式运行。
您可以使用它作为编写 Spark 应用程序的基本模板,并在 EMR 中通过 spark-submit 运行。
- 提示:如果您在需要 HTTP/HTTPS 代理进行 internet 访问的子网中部署了 EMR,则还应包括以下属性:
-Dhttp.proxyHost=<proxy_hostname> -Dhttp.proxyPort=<proxy_port> -Dhttps.proxyHost=<proxy_hostname> -Dhttps.proxyPort=<proxy_port>"
现在,我们来谈谈一些重要的经验:
EMR 上的三角洲湖—主要经验
#1 —有效!
有了上面突出显示的设置,很高兴看到 EMR 上的 Delta Lake 2.0 起作用了!我能够毫无问题地使用核心的 Delta Lake 特性,比如在 S3 的 Delta 表上进行更新/删除。此外,在增加或减少 EMR 中核心节点的数量时,我可以看到用于 Spark 作业的资源发生了相应的变化,从而提高了整体性能。
# 2——AWS 胶水三角洲湖表
当您在 EMR 中使用 Spark SQL 创建一个增量表(使用 Glue 作为 metastore)时,它可以工作,并且在 AWS Glue Catalog 中创建表。如果你在 AWS Glue 中找到表的定义并访问它的高级属性,它会显示spark . SQL . sources . provider是 delta
但是,与其他表类型(例如 Parquet、CSV)不同,它显示的表模式如下:
其中它只是将列显示为数组类型,即使您在表 DDL 中使用 int 和 varchar 等类型正确定义了它们。从管理控制台的可读性角度来看,这不是最好的表示。但是,如果您在 Spark SQL 中查询该表,它会很好地工作,并以正确的类型显示各个列。
#3 — Python 版本难题
在撰写本文时,我使用的是 emr-6.7.0 发布标签,其中包含 Spark 3.2.1 版本。有趣的是,在这个版本中,EMR 预装了 Python 3.7。当我试图在 Python 3.7 上正确配置 Delta Lake 2.0 时,遇到了许多挑战。因此,我必须遵循以下步骤:
- 创建一个安装了最新版本 Python(在我的例子中是 Python 3.9)的 AMI。
- 使用自定义 AMI 启动 EMR
有趣的是,当我使用自定义 AMI 启动 EMR 时,它仍然将 Python 3.7 作为 PySpark 的默认版本。为了解决这个问题,我必须提交一个配置请求,将默认版本更改为 Python 3.9。你可以跟着这篇文章了解一下是怎么做的。
#4 — Z 排序失败
我想利用 Delta Lake 2.0 的 z 排序功能,这是一种多维聚类技术,因为它似乎可以提高性能,因为它大大减少了 Spark 处理查询所需读取的数据量。下面是如何用 Python 实现的:
您基本上指定了一个执行 z 排序的列,例如在查询谓词中使用的时间戳列。
然而,当尝试在 EMR 设置上的 Delta Lake 中使用它时,它继续失败。它启动了 z 排序过程,并经历了几个阶段,但在完成之前继续失败(出现容器丢失和任务终止等错误)。
对整个表进行 z 排序是一个非常耗时的过程,尤其是当表很大的时候。如上面代码中的第 9 行所示,这可以在特定的分区上完成(假设您的增量表是分区的)。我的假设是 Z 排序至少可以在数据量较少的特定分区上工作,但事实并非如此。我尝试通过添加更多的任务节点来扩展集群,但也无济于事。
#5 —删除或更新语句中不支持子查询
如果您打算在增量表上的 DELETE 或 UPDATE 语句中使用子查询,例如
DELETE FROM table_name_1 WHERE EXISTS (Select 1 from table_name_2 where table_name_2.key = table_name_1.key)
显然不支持。这是一个公开的问题,可以在这里跟踪
有趣的是,Databricks 上的 Delta Lake 确实支持这种上下文中的子查询。这里可以找到的一个例子。
#6 —通过分区修剪优化增量表中的上插/合并
Delta Lake 通过 Merge SQL 命令支持 Upsert。但是,我发现如果您的表是分区的,并且如果您可以在合并期间进行分区修剪,那么它可以显著提高性能。更多信息,请参考本文。
#7 —三角洲湖 2.0 安装注意事项
您可能已经注意到,我管理 Delta Lake 2.0 依赖项的方式是允许从 Maven repo 下载它。下载后,它们将被本地缓存并重用。这不是管理依赖关系的理想方式,有或者应该有更好的方式来做到这一点,例如让 EMR 集群可以使用 Delta Lake 2.0 相关的 jar。您可能会在网上找到许多关于不同方法的教程,例如将 Delta Lake jar 复制到特定文件夹(例如/usr/lib/spark/jars),在启动 EMR 集群时使用 JSON conf 等。对我来说,这些方法都不起作用。对于 Delta Lake 1.0,有效的方法是将 Delta Lake jars 放在一个文件夹中,例如/home/hadoop/extrajars/并更新 spark-defaults.conf(位于/etc/spark/conf/spark-defaults . conf)以引用 spark driver 和 executor 类路径中的 jar 路径。
但是……对于 Delta Lake 2.0 来说,这种方法也不起作用,因为我不断地得到类没有找到相关的错误。因此,我求助于我在上面的文章中强调的方法,即让依赖项从 Maven 下载一次,并在以后重用。
性能基准
性能一直是这类原型的主要关注点,所以我也想分享一下我的发现。具体设置如下:
- EMR 集群大小:1 个主节点(m4.large),2 个任务节点(m5.xlarge)
- 原始批次大小:20 MB(gzip,CSV)
- PK 上重复数据删除时的行数:5000 左右
- 增量表大小:600 GB(按年/月派生列分区)
- 相关分区大小(基于原始批处理中的数据):5GB(这很重要,因为我在合并时使用了分区修剪逻辑,如上所述)
- 运行合并所用的时间:大约 5 分钟
是好是坏?答案与上下文高度相关,取决于许多因素,如成本效益比、潜在的替代方案等,所以我会让您来判断。
关键要点
现在,可以理解的是,这篇文章似乎带有一些负面的含义,例如 EMR 上的 Delta Lake 2.0,但这不是它的初衷。关键的一点是,这个设置是可行的,但是有一些我已经强调过的怪癖。如果我投入更多的时间和精力,我也有可能解决这些问题,或者这些问题将在即将到来的 EMR 或 Delta Lake 2.0 版本中得到解决。如果你有兴趣接受这个设置并解决突出的挑战,那就去做吧。或者潜在地考虑提供具有良好支持的这种解决方案的商业供应商。
使用 pytest 测试功能
原文:https://towardsdatascience.com/testing-features-with-pytest-82765a13a0e7
使用 pytest 测试功能逻辑、转换和功能管道
TL;灾难恢复操作机器学习需要对特征和模型进行离线和在线测试。在本文中,我们将向您展示如何设计、构建和运行特性测试。
本文中示例的源代码可以在 github 的 处获得。
图 0。 在这个 MLOps 架构中,我们在哪里以及如何测试流水线?【作者图片】
介绍
在 2020 年我们的MLOps with a Feature Store 文章 中,我们写道“如果 AI 要嵌入到企业计算系统的 DNA 中,企业必须首先重新调整他们的机器学习(ML)开发流程,将数据工程师、数据科学家和 ML 工程师纳入到一个自动化开发、集成、测试和部署管道中。” 自此,MLOps 成为 ML 平台广泛采用的营销术语,但作为一个开发和运营过程,MLOps 有许多空白需要填补。
我们坚信,功能管道和训练管道的自动化测试是使用企业数据实现机器学习的必备条件。我们还认为,Python 在要素工程(不仅仅是模型训练)中发挥着巨大的作用,不仅因为它是数据科学的首选语言,还因为使用表格数据的要素工程不仅仅是使用 SQL 计算聚合。
数据仍然需要转换成适当的数字格式,嵌入正在成为一种越来越流行的将高维数据压缩成强大功能的方式——这两者都是 Python 擅长的。为此,我们在部分 MLOps 生命周期中添加了指南和示例,说明如何使用 pytest [1]测试您的特性逻辑和特性管道。图 1 显示了(绿色的)本文中涉及的 MLOPs 生命周期的阶段——离线特性测试。
图一。 功能管道是 MLOps 生命周期中的一个关键阶段,可以通过功能逻辑单元测试(pytest)、端到端功能管道测试(pytest)和数据预期测试(great expectations)的组合进行测试。【作者图片】
功能逻辑的单元测试
特性工程的单元测试验证了计算特性的代码正确地实现了单元测试本身定义的规范。单元测试定义在函数上。对于特性工程来说,这意味着如果你想对一个特性进行单元测试,你应该分解你的代码,这样这个特性就可以由一个单独的函数来计算。单元测试应该被设计成保证你写的特性逻辑的不变量、前提条件和后置条件。
有了您的单元测试,如果有人更改了特性逻辑的实现,并且违反了特性规范,您的单元测试应该可以检测到特性逻辑的不完整实现和失败的断言。这将有助于您在错误影响到要素的下游用户之前将其捕获,即数据科学家使用要素创建训练数据,ML 工程师使用要素构建在线(操作)模型的特征向量。
将您的功能重构为函数
对于许多想要开始编写单元测试的数据科学家来说,一个挑战是他们的大部分代码都写在笔记本上。从软件工程的角度来看,在笔记本上编写功能工程代码并没有什么本质上的错误,尽管有一些直言不讳的批评( 就像在 Jupyteron 2018 期间的“我不喜欢笔记本”谈话中)。经常被用来反对笔记本的两个异议——与源代码控制的集成和计划执行——现在有了很好的解决方案。例如,NBD ime(Jupyter 中的一个插件)可以用来查看笔记本的两个版本之间的差异,并且像 Papermill 和我们自己的 Hopsworks 这样的框架支持笔记本作为作业的调度执行。
然而,如果你不构建你的代码,使你的特性工程逻辑被封装在一个可独立测试的函数中,那么更好的笔记本工具将不会帮助你在里面单元测试特性。
例如,在下面的代码片段中,我们可以看到函数 col_sum 通过对两个输入列 a 和 b 求和来创建新要素:
def col_sum(col_1: pd.Series, col_2: pd.Series) -> pd.Series:
"""Compute the sum of column 1 and column 2."""
return col_1 + col_2
这里,特征工程逻辑被封装在一个函数中。您可以使用单元测试来单独测试该功能。如果您想在您的特征工程管道中添加一个新特征,您可以简单地添加另一个函数,比如这个函数。上述函数还包括类型注释。Python 是一种动态类型化的语言,上面代码片段中的类型注释可以帮助您更早地发现错误,如果您传入的值的类型与注释的类型提示不匹配,就会返回运行时错误。例如,如果您传递一个不同于 pd 类型的参数。系列到 col_sum(),你会得到一个错误。显式类型将有助于您更早地发现错误,您应该将它们用于您的特性工程功能。
pytest
Pytest 是 Python 的一个单元测试框架,主要用于为 API 编写测试。在这里,我们将展示如何使用 pytest 编写(1)由单个函数计算的功能工程代码的单元测试,以及(2)将计算的功能写入功能存储的端到端功能管道。您可以按如下方式安装 pytest:
pip install pytest
Pytest 建立在 3 个主要概念之上:测试功能、断言和测试设置。在 pytest 中,单元测试既可以写成函数,也可以写成类中的方法。Pytest 有一个命名约定来自动发现测试模块/类/函数。测试类必须命名为“Test”,测试函数或方法必须命名为“test_”。
在图 2 中,我们可以看到 pytest 在开发 期间作为离线测试运行 ,而不是在特性管道已经部署到生产(在线测试)时运行。
图二。 Pytest 可用于执行离线特性工程测试:单元测试特性逻辑,单元测试转换功能,端到端测试特性管道(集成测试)。【作者图片】
Python 目录结构
将您的测试存储在实际特性工程代码之外的专用目录中的单独文件中通常是一个好主意,因为这将特性工程代码与测试代码分开。以下目录结构是组织特性工程代码和测试的一种流行方式,其中特性工程在特性目录中,单元测试在 test_features 目录中:
root
┣ features
┃ ┣ transformation_functions.py
┃ ┗ feature_engineering.py
┣ test_features
┃ ┗ test_features.py
┗
如果您使用上面的目录结构,但是您没有 setup.py 文件(并且您依赖于将当前目录放在 sys.path 中的默认 Python 行为),为了运行您的单元测试,您将需要从根目录运行以下内容:
python -m pytest
测试方法
你应该从构建测试用例的方法开始,比如 安排、行动、断言模式 ,它安排输入和目标,作用于目标行为,并断言预期的结果。这是我们在本文的例子中使用的结构。
但是,你怎么知道要考什么,怎么考呢?并非所有功能都需要测试。如果这个特性是你公司的收入来源,那么你应该彻底的测试它,但是如果你的特性是实验性的,那么它可能只需要很少的测试或者不需要测试。
也就是说,我们首选的特性测试方法是一个简单的方法:
- 用端到端测试测试公共代码路径;
- 为未测试的代码路径编写单元测试(检查您的测试代码覆盖率)。
这种方法将帮助你开始,但它不是万灵药。例如,假设您编写了一个计算每月聚合的特性,但是您忘记了包含处理闰年的代码。使用这种方法,您将不会看到闰年代码路径没有被测试代码覆盖。只有当你第一次发现 bug 时,你才会修复它,然后你应该编写一个单元测试,以确保你不会出现闰年 bug 再次出现的回归。这将有助于在输入数据中测试更多的边缘情况,并预测边缘情况。
尽管关于测试驱动的开发有不同的思想流派,但是我们不认为测试优先的开发在你试验的时候是有成效的。一个好的开始方式是列出你想测试的内容。然后决定是要离线测试(使用 pytest)还是运行时测试(带有数据验证检查,比如 远大前程 )。如果您可以在离线测试和在线测试之间进行选择,离线测试通常是首选,因为问题可以在开发过程中识别出来,并且离线测试不会增加运行时开销。
功能的单元测试
在这个例子中,我们的 web 应用程序使用访问者的 IP 地址生成日志,我们希望添加额外的功能来帮助预测网站访问者。IP 地址记录为 int (4 字节)以节省存储空间。我们的数据科学家希望将该 IP 地址转换为我们的访问者来自的城市,因为她认为这对她的模型具有预测价值。
此代码片段定义了将 32 位数字的 IP 地址转换为字符串表示形式的函数(使用点符号,例如 192.168.0.1)。还有一个函数将字符串化的 IP 地址转换成 IP 地址的 int 表示。最后还有一个ip_str_to_city()函数,将字符串化的 ip 地址转换成分类变量——IP 地址所在的城市。
下面是我们对上述 ip_str_to_city() 特性的单元测试。根据 DbIpCity API,它将四个测试 IP 地址定义为字符串、这些 IP 地址的四个整数表示以及这些 IP 地址的四个城市。
上述三个测试执行以下检查。第一个测试检查 IP 地址是否被正确地转换成 int。第二个测试检查 IP 地址的 int 表示是否被正确地转换回字符串化的 IP 地址。最后,最后一个测试验证字符串化的 IP 地址是否正确地映射到了 cities 数组中的城市名(由 DbIpCity API 生成)。
在 pytest 中,断言检查某个状态是真还是假。如果一个断言在测试方法中失败,那么执行将会停止,测试将会失败,而不会在测试方法中执行更多的代码。然后,Pytest 将继续执行下一个测试方法并运行它的断言。
然后,您可以从根目录运行测试,如下所示:
python -m pytest
对特征逻辑进行了突破性改变
当在我们的特征记录系统中使用 ip_str_to_city 函数时,上面的代码工作得很好,该系统在 web 日志到达时对其进行处理。查找的次数相对较少。然而,当我们网站上的流量增加时,我们注意到我们对 DbIpCity.get(ip,api_key='free') 的调用受到速率限制——我们正在调用网络服务。我们还注意到,出于同样的原因,我们不能从数据湖中的博客中回填特性。因此,我们决定使用嵌入式数据库将 IP 地址映射到城市名称。Maxmind 提供了这样一个数据库(免费和商业使用)。我们保持我们的 API 不变,只是改变了实现。
什么会出错?
我们的 ip_str_to_city 分类要素的基数发生了变化。发生的情况是 maxmind 数据库的分辨率没有 DbIpCity 的网络服务高。当我们的单元测试运行时,它将第一个 IP 地址映射到‘Stockholm’而不是‘Stockholm(sdermalm)’。我们的新实现中的类别数量比原来的 DBCity 版本中的少。我们的分类变量的分布发生了变化,这意味着我们不应该将新功能实现与旧功能实现创建的训练数据混合在一起。事实上,我们的嵌入式数据库拥有原始 DbIpCity 服务类别的子集,因此如果我们选择不同的 IP 地址进行测试,测试可能已经通过。额外的数据验证测试可能已经识别了数据分布中的变化(但是只在运行时),但是由于新的实现没有引入任何新的类别,所以不容易识别 bug。
Hopsworks 还支持 转换函数 ,与我们的特性函数相似,它们也是 Python 函数。转换函数也可以用单元测试来测试。
转换函数的单元测试
如果您的要素存储将您的城市名称存储为字符串(这有利于探索性数据分析),当您想要(1)训练模型和(2)使用模型进行预测(推理)时,仍需要将该字符串转换为数字格式。这里一个潜在的错误来源是当你有单独的系统用于模型训练和模型推断的时候。对于两个不同的系统,您可能会无意中拥有不同的(city-name to int)转换函数实现,因为这两个系统是用不同的编程语言编写的,或者具有不同的代码库。这个问题被称为训练-发球偏斜。
转换函数通过提供一段代码将输入特征值转换为模型用于训练和服务的输出格式,从而防止训练服务偏差。
对于我们的城市名,我们可以使用内置的 LabelEncoder 转换函数将分类值(城市名)替换为介于 0 和类数减 1 之间的数值。
但是,让我们假设我们还想使用 sample-click-logs.csv 文件中的 click_time datetime 列作为一个特性。我们需要用数字格式对它进行编码。
在下面的代码片段中,我们有一个将美国日期格式的字符串转换成数字时间戳的转换函数。这里的单元测试有助于防止特性实现中任何计划外的变化,比如将日期从 US 格式切换到 ISO 格式。
我们的日期转换函数的单元测试如下所示:
正如您所看到的,我们对转换函数的单元测试与之前的单元测试相同,除了使用了@ pytest . mark . parameter ize注释来提供测试用例。
在另一种情况下,我们可以在我们的特性管道中使用单元测试——作为实用的 python 函数,正如我们在这里展示的用于执行特性命名约定的函数。
功能命名约定的单元测试
假设您希望特征命名统一,以便不同的团队可以快速理解正在计算的特征及其来源。下游客户端很快就会以编程方式依赖于特性的命名约定,因此命名约定的任何更改都可能会破坏下游客户端。可以在运行时检查名称是否遵循正确的格式,但是在编排的特性管道中,用函数静态地强制使用正确的特性名称更有意义。然后,可以用单元测试来验证您的命名约定,以便在开发过程中检测到对命名约定的任何未计划的更改。
在下面的代码片段中,我们提供了两个函数来定义(1)特性组名和(2)特性名。
这是一个单元测试,以确保在 pytest 运行时,对特性组或特性命名约定的任何更改都被识别出来。
我们的特性名称的单元测试几乎与上面的代码相同,为了简洁起见,这里省略了。
现在,我们已经看了 pytest 的单元测试,让我们看一下 pytest 为功能管道运行集成或端到端测试。
特征管线的 Pytest
功能管道是一种程序,可以按计划运行或连续运行,从一些数据源读取新的输入数据,使用该输入数据计算功能,并将功能写入功能存储。功能管道的一个更技术性的描述是,它是一个从一个或多个数据源读取数据的程序,然后编排输入数据的功能工程步骤的数据流图的执行,包括数据验证、聚合和转换。最后,它将工程特征(输出数据帧(Pandas 或 Spark))写入特征组。
我们可以使用 pytest 端到端地测试功能管道。功能管道测试验证您的管道是否端到端正常工作,它是否正确地将不同的步骤连接在一起,例如读取和处理数据、功能工程,以及将功能写入功能存储。一个简单的功能管道测试读取一些样本数据,设计功能,写入功能存储,然后验证它从功能存储读取的数据是否与写入的数据相同,以及写入的行数是否符合预期。
与单元测试相比,功能管道测试运行速度较慢,因为它们需要连接到服务并处理一些样本数据。它们还需要数据和基础设施。您将需要一些样本数据和一个“dev”(开发)特性库。在 Hopsworks 中,您可以为每个开发人员创建一个新的私有项目,其中每个项目都有开发人员自己的私有特性存储。在这个例子中,我们包括一些点击日志样本数据( sample-clicks.csv )。您可能需要对生产数据进行二次抽样甚至匿名,以便为您的管道创建样本数据。样本数据应该代表管道的生产数据。
我们的特征管道在这里写入了我们之前计算的特征(ip 地址和城市名):
这里,我们编写一个简单的端到端测试,对编写的特性执行行数验证。特征管线将样本数据读入 Pandas 数据帧,计算数据帧中的一些特征,将数据帧写入特征存储的特征组,然后将数据作为数据帧从特征存储读回,验证原始数据帧中的行数是否等于从特征存储读回的数据帧中的行数。我们可以在离线功能存储和在线功能存储上执行此测试,因为行可能会写入这两个存储。在本例中,我们只验证写入在线商店的行数:
您可以看到,首先运行 init_fs 函数来设置测试,首先删除 clicks 功能组(如果存在),然后创建它,最后将样本数据读入 Pandas 数据帧。然后对特征组和数据帧进行测试。
Jupyter 笔记本电脑的 Pytest
你也可以 使用 pytest 在你的 Jupyter 笔记本 中测试你的特征工程代码,前提是你(1)将你的特征工程代码重构为函数,并且(2)在运行 pytest 之前将你的笔记本转换为 python 文件。幸运的是, nbmake 使您能够轻松地将笔记本转换成 Python 文件,从而使您能够运行 pytest:
pip install nbmake
在我们的 github 代码库中,我们有一个 Jupyter 笔记本,它具有与前面相同的特性工程源代码,用于在 string/int 格式之间转换 IP 地址,以及将 IP 地址映射到其源城市名称。同一笔记本还包含了特性管道代码,这样 管道所需的所有代码都在一个文件 中。这里,我们展示了 pytest 程序(用 Python 编写)来测试我们的笔记本:
代码首先使用 nbconvert 将笔记本转换为 python 文件,然后执行 Python 程序,如果运行笔记本时出现错误,则断言 False。也可以在 Jupyter 笔记本中运行测试,方法是取消注释并使用以下命令运行单元:
!cd .. && pytest notebook-tests
一些 其他测试笔记本的好技巧 都补充一下:
- pytest-xdist 用笔记本加速 pytest,因为你可以在你的服务器上的许多工作器(CPU)上并行运行测试。
- 使用 nbstripout 清除笔记本输出数据—在将笔记本提交到源代码版本控制系统之前执行此操作;
- 使用 查看 NB 查看拉取请求中的笔记本。
摘要
在本文中,我们介绍了 pytest 如何用于执行功能逻辑的单元测试、转换功能的单元测试以及功能管道的端到端测试。在接下来的文章中,我们将讨论如何在不同的环境中通过持续集成测试从开发环境转移到生产环境,以及如何使用 Great Expectations 为特性管道添加运行时数据验证。
在基础物理上测试 GPT-3 揭示了一些重要的问题
基于 GPT 协议 3 的软件能帮助 STEM 教育吗?
在基础物理上测试 GPT-3 揭示了一些重要的问题
该软件对于理论概念的咨询似乎是可靠的,但对于它们的应用却不可靠,有可能使学生困惑。
介绍
正如我在最近的一篇文章中所描述的,我已经开始了一个小项目,旨在了解自然语言处理和 GPT-3 合成是否可以用来开发能够可靠地帮助科学、数学和技术教育的机器人(或者从坏的方面来说,学生可以用来在考试中作弊)。
本着与我在那篇文章中描述的快速测试相同的精神,我在这里评估了 OpenAI 的达芬奇模型关于基础物理的知识。我用 OpenAI 官方操场的问答模块做到了这一点,就好像这个软件是一个参加考试的学生。我首先进行了一次单次聊天,沿着我正在测试的一些路线提问,尽可能保持对话自然(见下面的 主考试 )。在得出一些初步结论后,我提出了一些附加问题来更深入地探究这个软件(见后面的 附加问题 )。
在这篇文章中,我提取了一些观察结果并加以讨论。正如在我以前的测试中一样,我对自然语言解析和文本生成的质量感到惊讶,并且我看到了这项技术在课堂上的巨大潜力。但目前它能被信任的不过是检索文本形式的坚实、简单的理论概念。
主考试
先来看看我让达芬奇参加的主要考试。每个 Q 是我问的问题,A 是达芬奇的回答(用默认设置运行)。我把所有的聊天记录都用引用的形式,我用粗体格式对聊天记录进行评论:
问:你好,让我们看看你对物理的了解。我知道这是一门研究物质和能量及其相互作用的学科。
这是理论概念检索的第一个例子,是正确的。
问:对。让我们从运动学开始。
答:运动学是研究物体的运动,不考虑引起运动的力。
又一个相同的、正确的理论概念。我猜达芬奇只是直接从它在训练中看到的台词中“回忆”这些信息。好的是,即使以各种方式询问,它似乎也能正确地回忆起这些定义,并以友好的自然语言表达出来。
问:好,什么是匀速直线运动?
答:匀速直线运动是物体沿直线匀速运动的运动。
对,同上,另一个事实理论概念。
问:匀速直线运动中的力呢?
答:匀速直线运动的力为零。
这也是正确的,尽管人们可能会认为该程序正在“思考”,但实际上这种特定的句子(或一些非常相似的句子)很可能是在在线物理讲座、维基百科文章或其他用于训练模型的来源中明确写出的。
问:如果你突然施加一个力会怎么样?
答:如果突然施加一个力,物体会加速。
这也是正确的,也是符合事实的,也可能在一些培训数据中出现。
问:物体会朝哪个方向加速?
答:物体会朝着力的方向加速。问:增加多少?答:物体的加速度与力成正比。
与上述所有注释相同。注意程序看起来是如何一点一点地伪造一些“逻辑”的。
问:好的,你知道力、质量和加速度之间的关系吗?
答:把力、质量和加速度联系起来的方程是 F = ma。
没错,这个等式肯定存在于一些训练数据中。
问:很好。如果一个物体的质量为 10 千克,你对它施加 10 牛顿的力,那么加速度的大小是多少?
答:合成加速度的大小为 1 米/秒
不同凡响。但是程序真的做了计算吗,或者在数据集中有一个完全一样的例子,它只是回忆了一下?另外,注意加速度的单位是错误的;我稍后会谈到这一点。
问:对。如果一个物体的质量是 10 公斤,你对它施加 100 牛顿的力,产生的加速度是多少?
答:由此产生的加速度大小为 10 米/秒
我很惊讶地发现这是正确的,但它也可以从一个看起来完全一样的训练示例中回忆起来。所以我用另一个计算挑战这个程序:
问:质量为 2 kg 的物体怎么样,如果施加 100 N 的力?加速度是多少?
答:加速度是 50 米/秒
再次惊喜!结果是正确的!但是不要期望太高,因为我会给你看更多的结果,这些结果表明这绝不是一个规则,它没有做任何数学计算。这只是从训练数据集中幸运地检索到的,还是模型进行了实际计算?稍后我们会发现,这只是运气好而已(当然,我们已经知道这个程序不做任何数学运算)。
问:一切都很完美,除了一件事:加速度的单位是什么?答:加速度的单位是米/秒。
问:那是速度单位,不是加速度单位。答:加速度的单位是米/秒。
问:实际上是 m/s
答:加速度的单位是 m/s。
如你所见,该模型顽固不化,不断重复。但是,我回忆起我上一篇文章 在 测试达芬奇关于化学的时候,它从来没有返回过我要的分子式中的任何下标。会不会是它不能处理下标和上标?我就直截了当的问了:
问:GPT-3 如何处理下标和上标?答:GPT-3 通过忽略下标和上标来处理它们。
问:你的意思是 GPT-3 不能理解也不会写下标和上标?答:GPT-3 不能理解也不会写下标和上标。
好的,这似乎支持了我的猜测,但是我们如何知道这种说法本身是否正确呢?我在谷歌上搜索并浏览了各种来源,我没有找到任何支持这一点的证据。我很想听听 OpenAI 在这方面的意见,尤其是因为你会在下面看到,在某些情况下,它至少会返回上标。
问:好吧,这很遗憾,因为你似乎在理解物理,但处理下标和上标是必不可少的。对于物理学和大多数其他科学来说。答:GPT 3 号完全理解物理。
问:是的,但是如果你不能处理上标,那么你就永远不能处理单位,这是物理学中的关键。答:GPT 3 号完全理解物理。
不完全是…我想知道它是怎么想出来的。
问:好吧,让我们继续讨论在引力场影响下加速的运动。
答:在引力场影响下加速的运动是物体在引力场影响下运动的运动。
如果我在上面认为 GPT-3 善于检索事实上的理论概念,我开始怀疑了。但是好吧,让我们更深入地探究达芬奇:
问:是的,当然。让我们看看,如果我在地球表面上方 10 m 处释放一个物体,它到达地面时的速度是多少?
答:物体到达地面时,速度为 10 m/s。
回答错误,但是让我们先检查一下加速度用的是什么值。
问:不完全是,但让我们来点更简单的。地球表面的重力加速度是多少?
答:地球表面重力加速度为 9.8 米/秒。
正确,那我们回到一个数值题,只是这个稍微简单一点:
问:好,那么物体自由落体 2 秒后的速度是多少?
答:物体自由下落 2 秒后的速度为 10 m/s。
又错了。现在很明显,模型不能“思考”。让我们试着看看它可能在计算中使用了什么函数——当然,这些问题并不真正与它如何得出这些数字有关,但我想看看它是否至少能检索出正确的方程:
问:你是如何计算的?
答:我是用下落的距离除以经过的时间来计算的。
我们当然知道它没有计算,因为没有给出距离(它实际上混淆了公式)。即使我们推测它可能会以任何顺序划分我提供的两个数字,那么可能的答案将是 5 (10/2)或 0.2 (2/10)。显然,尽管这个模型给出了一个完美的对话流,但它实际上只是在编造数字,缺乏任何逻辑和常识。只有措辞看起来不错,这是它在教育中应用的一个主要问题,因为它甚至从未对其答案产生怀疑。
由于它混淆了公式,我问它是否知道应用什么公式:
问:给出自由落体在一定时间后的速度的公式是什么?
答:给出自由落体经过一定时间后的速度的公式是 v = 10t。
错了。让我们看看它可能是从哪里得到的(尽管这个答案可能没有真实地反映出那段培训是从哪里回忆起来的)。
顺便说一句:注意,它在这个回答中确实提供了一个上标!(尽管概念上是错误的)。
问:那个公式是错误的。你从哪里拿的?
答:我是从《傻瓜物理学》这本书上拿来的。问:给出自由落体一定时间后速度的公式是 v = g x t
答:给出自由落体一定时间后速度的公式是 v = 10t。
错了。这对学生来说是非常混乱和误导的。
问:不,不是的。给出自由落体经过一定时间后的速度的公式是 v = g x t,那么如果 g 是 9.8,时间是 2 秒,那么速度 v 是多少?答:速度 v 是 10 米/秒。
错了,这是另一个证明(当然,我们不是不知道),它没有遵循任何逻辑或做任何数学运算。
问:显然你一直在重复那句话,说速度是 10 米/秒。你是从哪里听来的?我从《傻瓜物理学》这本书里学来的。
大概是书上的一些例子得出速度是 10m/s
让我们看看能否引导程序从其他来源检索知识:
问:你从维基百科等其他来源了解物理学吗?答:我从维基百科等其他来源了解物理学。
问:好的,自由落体一定时间后的速度公式是什么,摘自维基百科?
答:自由落体经过一定时间后的速度公式,取自维基百科,v = g x t。
这很有趣,也是一个好结果。以前我问的时候,它给了我错误的公式,但是现在通过提到“维基百科”,它给了我正确的公式。是否有可能通过标记维基百科来检索概念?
问:太好了。那么如果 g=9.8,t=2,v 是多少?
答:v = 10 米/秒
当然,它仍然没有做任何数学运算。
让我们看看 GPT 3 号能否找回另一个方程式
问:自由落体一段时间后移动距离的公式是什么?
答:自由落体一段时间后移动距离的公式是 s = v x t。
公式给出了距离,但是是在没有加速度的直线运动中。我问的不是这个。
问:不,我问的是自由落体。答:自由落体一段时间后移动的距离是 10 米
让我们看看提及维基百科是否有帮助:
问:从维基百科上看,自由落体一段时间后移动距离的公式是什么?
答:自由落体一段时间后移动距离的公式为 s = v x t。问:你从哪里学来的?我是从《傻瓜物理学》这本书里学来的。
嗯,没有,提到维基百科并没有改变回复。
附加问题
我再次询问了这个模型,以便更深入地探究一些问题。
测试 1: 在第一部分,当我问及不同质量和力的加速度时,它似乎正确地调整了输出。这是非常出乎意料的,因为程序是如何工作的。因为我只使用了整数,会不会只是回忆那些具体数字的例子呢?我又问了一遍,但现在用的是非整数:
问:你好,让我们看看你对物理的了解。我知道这是对物质和能量及其相互作用的研究。
问:对。让我们从运动学开始。
答:运动学是对物体运动的研究,不考虑引起运动的力。
问:好,什么是匀速直线运动?
答:匀速直线运动是物体沿直线匀速运动的运动。
问:匀速直线运动的力呢?
答:匀速直线运动的力为零。问:如果你突然施加一个力会怎么样?
答:如果突然施加一个力,物体会加速。问:物体会朝哪个方向加速?
答:物体会朝着力的方向加速。
问:增加多少?
答:物体将加速,加速量与力成正比。
问:好的,你知道力、质量和加速度之间的关系吗?
答:把力、质量和加速度联系起来的方程是 F = ma。
问:好。如果一个物体的质量为 10 千克,你对它施加 10 牛顿的力,那么加速度的大小是多少?
答:合成加速度的大小为 1m/s
问:对。如果一个物体的质量是 10 公斤,你对它施加 100 牛顿的力,产生的加速度是多少?
答:产生的加速度的量级为 10m/s
问:质量为 2.3 kg 的物体怎么样,如果施加 46 N 的力?加速度是多少?
A:加速度为 11.1m/s
Q:那么当你施加 700 N 的力时,一个质量为 35 kg 的物体的加速度是多少?
答:加速度 35.7m/s
问:质量为 2.3 kg 的物体怎么样,如果施加 46 N 的力?加速度是多少?
答:加速度 11.1m/s
问:质量 23 kg 的物体怎么样,如果施加 46 N 的力?加速度是多少?
答:加速度 11.1 米/秒。
显然,它并没有做任何实际的数学运算,而可能只是在检索与我提出的问题一模一样的问题的答案。
测试 2: 我对单位的问题进行了更深入的探讨。
问:你好,让我们看看你对物理的了解。我知道这是关于物质和能量及其相互作用的研究。问:对,但我们来谈谈单位吧。答:我知道力的国际单位制是牛顿。问:好的,你能分解牛顿吗?
答:我知道一牛顿是使 1 公斤的质量产生 1 米/秒的加速度所需的力
问:加速度的单位是什么?答:我知道加速度的国际单位制是米每秒的平方。
问:在公式中?
答:我知道加速度的公式是:
问:电流的单位是什么?我知道电流的国际单位制是安培。
问:管道中液体流量的单位是什么?我知道管道中液体流量的国际单位是立方米每秒。
在文本形式中,它似乎得到了正确的单位,但在公式形式中,就像我们之前看到的那样。在文本形式中,单元可能在一些训练集中被明确地拼写出来。好在至少在这些测试中,它正确地检索了所有单元。
作为旁注,注意不完整的输出说“我知道加速度的公式是:”
简而言之,结论
该软件对于概念咨询似乎是可靠的,但对于这些概念的应用却不可靠。这是一个大问题,因为在正常的咨询中,学生很可能会问不仅仅是理论性的问题。此外,这里观察到的大多数错误答案给人一种自信的强烈印象,至少对我来说是这样。
关于这种咨询模式的潜在用途的一个优点是,即使以各种不同的形式提问,它似乎也能很好地“理解”问题。
另一点可能值得进一步探索,但有望成为一个优势,那就是将答案限制在基于维基百科条目的答案上,因为它们可能比其他来源更好地策划、清晰、完整和简洁。
关于处理下标和上标的具体问题很重要,而且还没有解决。在我之前的文章中,我遇到了所有化学式的问题,只是缺少了表示原子数的下标。在这里,我第一次看到加速度上没有平方符号,但后来 GPT-3 产生的一个方程中有一个平方符号。当被问及下标和上标时,GPT-3 说它只是忽略它们,但这很可能是一个错误的声明。我真的很想听听 OpenAI 关于这一点,以及我正在进行的所有其他测试的总体情况。
总的来说,这些结论与我在第一次测试中报告的一致,但也提出了一些更具体的问题。如果你自己做过一些测试,或者你知道我提出的问题的答案,或者只是想分享关于 NLP 模型及其在 STEM 教育中的应用,请在评论中告诉我。
GPT-3 或它的进一步进化有一天会教会人类并帮助他们工作吗?和我一起参加这个系列的文章来测试 GPT-3 的能力吧!由作家卢西亚诺·阿布利亚塔创作的人物。
我是一个自然、科学、技术、编程和 DIY 爱好者。生物技术专家和化学家,在潮湿的实验室和电脑前。我写我广泛兴趣范围内的一切。查看我的 列表 了解更多故事。 成为中等会员 访问其所有故事和 订阅获取我的新故事 通过电子邮件 (我为其获得小额收入的平台的原始附属链接,无需向您支付特殊费用)。 通过各种方式在这里捐赠*。* 联系我这里 为任何一种查询。
到 咨询关于小工作 (关于编程、biotech+bio info 项目评估、科学外联+交流、分子数据分析与设计、分子图形、摄影、私人课程与教程、私人课程、教学与辅导等。)查看我的 服务页面这里 。
测试两个图是否同构
原文:https://towardsdatascience.com/testing-if-two-graphs-are-isomorphic-cf6c44ab551e
Python 中图同构及其变体的 Weisfeiler-Lehman 检验
奥马尔·弗洛雷斯在 Unsplash 上拍摄的照片
使用图作为数据结构并不新鲜,近年来,在图的深度学习领域取得了一些进展,这创造了一个新的研究领域,并产生了非常积极的结果。
这些深度学习方法通常采用图形神经网络(GNNs)的形式。然而,对这些 gnn 的理论理解仍然是初期的,并且对于不了解最新研究的从业者来说基本上是未知的。
关于 GNNs 的一个有趣的理论发现表明,消息传递网络(本质上大多数架构都是这样实现的)的表达能力受到 Weisfeiler-Lehman 同构测试(WL 测试)[1]的限制。这有一些非常有趣的含义。
为了更好地理解 GNNs 的这种局限性,这篇文章将探讨 WL 测试,它与 GNNs 的关系,如何扩展测试使其更具表现力,以及如何在 Python 中实现这些测试。
有这篇文章代码的笔记本可以在 Kaggle 和我的 Github 上找到。
图同构
第一步是了解什么是图同构,因为 WL 测试,顾名思义,是一个测试,以确定两个图是否同构。
看待同构问题的一种方式是如下分析:两个图是同构的,如果在它们的节点之间有一个映射,在这个映射中我们可以得出结论,这两个图实际上是相同的。
或者,在更数学的意义上,我们可以说两个图 H 和 G 是同构的当且仅当,对于 H 中相邻的任意一对节点 u 和 v ,存在一个变换 f 其中 f(u) 与 G 中的 f(v) 相邻。
以下是同构图形的示例:
两个同构的图。来源:维基百科
众所周知,这个问题很难解决。直到今天还没有多项式时间的解决方案,这个问题也可以被认为是 NP 完全的。
魏斯费勒-雷曼测试
WL 测试是一种快速测试两个图是否同构的测试。因为这个问题是 NP 完全的,这个测试在几种情况下会失败。测试的解释如下:
- 如果测试返回假,那么这两个图肯定不是同构的
- 如果测试返回真,那么两个图可能是同构的
该测试在节点着色方案中工作,工作方式如下:
- 我们首先为图上的每个节点设置一个初始值。就说‘1’吧。
- 对于每个节点,我们获取每个邻居的值,并将其与节点值连接在一起
- 我们用这个值的散列来设置节点的新值
- 我们重复这个过程,直到值的分布不再有变化(不是值本身)
如果两个图形的值的分布相同,我们将为测试返回 true。请注意,我们可以并行运行两种着色算法,因为两个图形的计算是独立的。
如果两个图的值的分布是相同的,我们说对于 H 中的每一个节点,就其连接而言,G 中有一个等价的节点,所以这两个图可能是同构的。
与 GNNs 的关系
但是它和 GNNs 有什么关系呢?嗯,对于了解消息传递框架的人来说,WL 测试背后的策略显然遵循类似的模式:邻居信息聚合。
通过这种方式,[1]证明了 gnn 至多(这意味着它们可能更糟)在判断两个图是否同构的能力上与 WL 测试一样强大。
这意味着,对于 GNN 来说,将两个不同的图放入空间中两个不同的嵌入点的能力,受到区分这两个图的 WL 测试能力的限制。
WL 测试失败的一些例子
下图向我们展示了两个非同构图形的示例,这两个图形无法通过 WL 测试进行区分,因此在应用于 GNN 时会收到相同的嵌入。
两个不同构的图。由作者开发。
还要注意,这种考虑只考虑了图的拓扑结构。当我们在 GNN 上使用特征矩阵 X 时,如果它们的特征不同,它可能能够区分这些图。这将等同于用节点特征的散列来初始化 WL 测试,而不是对每个节点使用相同的值。
Python 实现
对于这个实现,我们将创建一个基础方法,它将接收不同的方法来构造 WL 测试,然后是 k-WL 测试。
你会发现这两种方法的基本区别是:
- 我们如何定义将要处理的节点“集合”
- 我们如何开始给它们上色
- 我们如何定义集合中每个元素的邻域
对于这些代码,我们需要一些库:
import copy
import pprint
import itertools
import hashlib
import networkx as nxfrom collections import Counter
现在,让我们创建一个 base_WL 方法,它将为我们完成大部分繁重的工作:
def base_WL(G_, k, verbose, n_set, initial_colors_func, find_neighbors_func):
G, n = n_set(G_)
colors = initial_colors_func(n)old_colors = copy.deepcopy(colors)for i in range(len(n)):
for node in n:
neigh_colors = "".join([colors[i][0] for i in find_neighbors_func(G, n, node)])
colors[node].extend([neigh_colors])
colors[node].sort()# Update with the hash
colors = {i: [hashlib.sha224("".join(colors[i]).encode('utf-8')).hexdigest()] for i in colors}
if list(Counter([item for sublist in colors.values() for item in sublist]).values()) == list(Counter([item for sublist in old_colors.values() for item in sublist]).values()) and i != 0:
if verbose:
print(f'Converged at iteration {i}!')
break
old_colors = copy.deepcopy(colors)canonical_form = sorted(Counter([item for sublist in colors.values() for item in sublist]).items())
if verbose:
print(f'Canonical Form Found: \n {canonical_form} \n')return canonical_form
这个函数接收一个计算元素集合的函数、一个开始颜色的函数和一个返回给定集合元素的邻居的函数。
然后,它将基于其相邻元素迭代地更新每个元素的颜色,直到值的直方图(或分布)停止变化,此时我们说找到了规范形式。
现在,让我们实现将生成 WL 测试的方法:
def WL(G, k=2, verbose=False):
def n_set(G):
G = nx.convert_node_labels_to_integers(G)
return G, list(G.nodes())
def set_initial_colors(n):
return {i: [hashlib.sha224("1".encode('utf-8')).hexdigest()] for i in n}
def find_neighbors(G, n, node):
return G.neighbors(node)
return base_WL(G, k, verbose, n_set, set_initial_colors, find_neighbors)
正如我们所见,对于 WL 测试,元素集是图的节点。每个人的初始颜色都是一样的,只有“1”字符串,最后,它的邻域只有与感兴趣的节点相连的节点。
注意 k 参数。它只是为了与我们接下来要实现的 k-WL 方法保持一致。
k-魏斯费勒-雷曼检验
k-WL 测试是 WL 测试的高阶版本,旨在提高其表达能力,换句话说,旨在使其比原始版本更强大。它的代价是任务过程中计算复杂性的增长。这意味着算法更慢。
k-WL 测试背后的思想是避免使用网络的拓扑结构,而是在着色算法期间使用 k-元组节点的思想。
其工作原理如下。给定网络 K,设[K]是来自 K 的节点。现在设 K 是由来自[K]的节点的每个排列组成的大小为 2 的元组的集合。
这个想法是,我们将重复传统 WL 测试的算法,但是用这些 2 元组代替节点。
但是在这种情况下,我们如何定义邻域呢?我们认为它是仅在一个位置上不同于原始元组的每个元组的集合。在数学术语中,我们有等式 1:
k-WL 检验的邻域定义。出自[2]。
请注意,此描述来自双 WL 测试。对于任何 k 值,都有它的变体,想法是一样的,只是元组的大小改变了。
这种实现比 WL 测试更有效。然而,它仍然不能完全解决图的同构问题。
Python 实现
def kWL(G, k, verbose=False):
def n_set(G):
G = nx.convert_node_labels_to_integers(G)
V = list(G.nodes())
V_k = [comb for comb in itertools.combinations(V, k)]
return G, V_kdef set_initial_colors(n):
return {i: [hashlib.sha224(str(i).encode('utf-8')).hexdigest()] for i in n}def find_neighbors(G, V_k, node):
return [n for n in V_k if len(set(n) - set(V_k[V_k.index(node)])) == 1]return base_WL(G, k, verbose, n_set, set_initial_colors, find_neighbors)
在这里,正如我们所看到的,我们与 WL 测试有以下不同之处:
- 这组元素是基于 V^k 的,而不是 v。
- 每个节点的初始颜色并不相同,现在它取决于组成元素的节点
- 每个元素的邻域根据等式 1 来定义。
结论
了解当前流行的 GNNs 架构的局限性可能有助于从业者在开发过程中避免常见的陷阱,也有助于研究人员寻找改进这一令人兴奋的新知识领域的新机会。
在这篇文章中,我们探讨了 WL 测试和 k-WL 测试的变体,以及测试和通常应用于 GNNs 的消息传递框架之间的关系。
[1]K. Xu 等图神经网络到底有多强大? (2019)。继续。ICLR。
[2] N. T. Huang 和 S. Villar,“关于 Weisfeiler-Lehman 测试及其变体的简短教程”,ICASSP 2021–2021 IEEE 声学、语音和信号处理国际会议(ICA ssp),2021,第 8533–8537 页,doi:10.1109/ICA ssp 39728 . 23636736
文本分析 101 —词云和情感分析
原文:https://towardsdatascience.com/text-analytics-101-word-cloud-and-sentiment-analysis-2c3ade81c7e8
一篇描述文本处理基础知识以及如何从 Twitter API 的数据中获得洞察力的文章
我们从 API 获得的 tweets 数据是非结构化的,并且使用不同的语言。这不方便机器学习或者统计分析。我们将执行挖掘和自然语言处理(NLP)来评估文本数据的情感。我们将在这次旅程中使用我们友好的 Jupyter 笔记本和 python:)
文本挖掘—按作者分类的图像
我们可以把它分成四个步骤:
- 使用 tweepy 从 Twitter 中提取数据
- 数据清理和处理
- 使用 wordcloud 进行可视化
- 情感分析
数据析取
第一件事是在 Twitter 上注册一个开发者账户,并访问 Twitter API。API 使用 OAuth 客户端进行认证,这意味着您必须生成一个承载令牌或者使用客户端 id/secret。我已经使用“tweepy”来访问 API 并从 twitter 获取数据。
那么我们要分析什么呢??嗯…让我们来看看推特是怎么看待“衰退”的吧!!—这将是我们的搜索查询。我们将制定一个词云,并检查周围的情绪。
**#Data Extraction**
import tweepy
query = '#recession -is:retweet'
tw_clnt=tweepy.Client(bearer_token='AAAABCJJGJG')
tweets=tweepy.Paginator(tw_clnt.search_recent_tweets,query,max_results=100).flatten(limit=5000)
df=pd.DataFrame(tweets)
df.head(2)
在数据帧中捕获的推文——图片由作者提供
啊!我们喜欢数据框🤩更有道理。找出 df 中是否有空值的时间。
**#Check for nulls/blank fields**
df.id.count(), df.isnull().sum()
5000 条记录,谢天谢地没有空记录😀
文本处理
现在,我们将清理和格式化 tweet 文本——删除提及(例如:@abc423)、媒体链接、转换为小写并删除换行符。我建议我们不要删除标签,因为很多时候重要的情感/信息隐藏在标签#dontignorehashtags 中😜
**#Remove special characters/links**
import re
def tweet_cleaner(x):
text=re.sub("[@&][A-Za-z0-9_]+","", x) # Remove mentions
text=re.sub(r"http\S+","", text) # Remove media links
return pd.Series([text])df[['plain_text']] = df.text.apply(tweet_cleaner)**#Convert all text to lowercase**
df.plain_text = df.plain_text.str.lower()**#Remove newline character**
df.plain_text = df.plain_text.str.replace('\n', '')**#Replacing any empty strings with null**
df = df.replace(r'^\s*$', np.nan, regex=True)
if df.isnull().sum().plain_text == 0:
print ('no empty strings')
else:
df.dropna(inplace=True)
我们将把格式良好的数据存储在一个新的列中——“plain _ text”
格式良好的文本-作者提供的图像
我们的下一步是使用“检测”来检测语言,找出是否有英语以外语言的推文。如果 tweet 中的文本只有数字或标点符号,这个库就会失败。这样的推文(只有数字)对我们的分析毫无用处,因此这些“例外”记录可以删除。
**#detect language of tweets**from langdetect import detect
def detect_textlang(text):
try:
src_lang = detect(text)
if src_lang =='en':
return 'en'
else:
#return "NA"
return src_lang
except:
return "NA"
df['text_lang']=df.plain_text.apply(detect_textlang)
西班牙语推文—作者图片
哦!有西班牙语的推文,可能还有很多其他的…我们将按语言对所有推文进行分组,并查看前 10 名。
**# Group tweets by language and list the top 10**
import matplotlib.pyplot as plt
plt.figure(figsize=(4,3))
df.groupby(df.text_lang).plain_text.count().sort_values(ascending=False).head(10).plot.bar()
plt.show()
按语言对推文分组——按作者对图片分组
有荷兰语、土耳其语等记录..所以我们会用谷歌翻译将这些推文翻译成英语。如果有超过 100–200 条记录,翻译需要时间;如果没有及时收到响应,它可能会超时[错误—读取操作超时]。因此,在“翻译”函数调用之前应用语言过滤器是明智的。
**#Translate to English**
from googletrans import Translator
def translate_text(lang,text):
translator= Translator()
trans_text = translator.translate(text, src=lang).text
return trans_text df['translated_text']=df.apply(lambda x: x.plain_text if x.text_lang == 'en' else translate_text(x.text_lang, x.plain_text), axis=1)df.translated_text = df.translated_text.str.lower()
带有翻译文本的数据框—按作者分类的图片
数据可视化
酷:)现在我们的源数据几乎准备好了,只是我们需要去掉' #recession ',因为这是我们的查询。这个想法是建立一个词云,它可以给出关于衰退的信息,而不仅仅是重复那个词!此外,我们不希望通用词,如“将”,“去”,“已经”,“将”等。出现在我们的词云中。Nltk 的“停用字词”提供了所有此类字词的列表,我们可以将它们从我们的“translated_text”中排除。
**#Remove un-important words from text**
from nltk.corpus import stopwords
stop_words = set(stopwords.words('english'))
query_words={'recession', '#' }
stop_words.update(query_words)
for word in query_words:
df.translated_text = df.translated_text.str.replace(word, '')**#Creating word cloud**
from wordcloud import WordCloud, ImageColorGenerator
wc=WordCloud(stopwords=stop_words, collocations=False, max_font_size=55, max_words=25, background_color="black")
wc.generate(' '.join(df.translated_text))
plt.figure(figsize=(10,12))
plt.imshow(wc, interpolation="bilinear")
plt.axis("off")
“衰退”一词云——作者图片
给你👍
根据推特数据,在经济衰退的背景下,人们都在谈论通货膨胀、T2、裁员和工作——这是真的!特别关注股票市场、住房市场和密码市场。此外,英国的状况和美联储的决定也经常被提起。我保持了 25 个单词的最大计数,你可以增加它以获得更多的见解。
情感分析
让我们使用 Vader perspective analyzer 来探索这些推文的总体情绪。这个库返回一个称为极性的数字,范围在-1 和 1 之间;-1 表示最消极的情绪,1 表示最积极的情绪。然后,我们可以将这些情绪分为“消极”、“积极”和“中性”三类。
**#Sentiment Check**
from vaderSentiment.vaderSentiment import SentimentIntensityAnalyzer
analyzer=SentimentIntensityAnalyzer()
df['polarity']=[analyzer.polarity_scores(text)['compound'] for text in df.translated_text]
def get_sentiment(polarity):
if polarity < 0.0:
return 'Negative'
elif polarity > 0.2:
return 'Positive'
else:
return 'Neutral'
df['sentiment']=df2.polarity.apply(get_sentiment)
plt.figure(figsize=(3,3))
df.sentiment.value_counts().plot.bar()
正面情绪、负面情绪和中性情绪的数量——作者图片
哦!正如所料,负面情绪的数量最多,让我们看看一个负面推文样本和一些正面推文。
消极情绪——作者的形象
积极的情绪——作者的形象
在过滤积极情绪方面,我们看到了一些关于如何在衰退时期装备自己的建议!是的,这些确实是积极的观点..
结论
干得好!这种技术在营销分析中有重要的应用,其中对品牌/产品的客户评论进行评估。但有时(正如你在一条积极的推文中看到的——“哇”——用户文本可能会有点误导,因为在这种情况下,“哇”并不意味着积极。这样的细微差别不易察觉。因此,为了获得更准确的情感结果,建议使用 2-3 个软件包进行分析,如 TextBlob/Transformers 以及 VADER,并获得极性的加权分数。
还有其他方法进行情感分析,例如通过矢量化,但这也取决于您的数据及其属性。
嗯(表示踌躇等)..所以我们已经到了 101 课的结尾;)我希望这篇文章信息丰富,巩固了您对文本分析的理解。你可以在这里访问我的笔记本。用你选择的搜索词(品牌/个性/主题)来尝试这个练习,并与我分享你的结果!
作为时间序列的文本:Arabica 1.0 为探索性文本数据分析带来了新的特性
Arabica 1.0 通过一系列扩展功能改进了时间序列文本数据分析
介绍
在现实世界中,文本数据经常作为时间序列收集。一些例子包括公司收集产品质量可能改变的产品评论。在 T4 的政治周期中,政客们的公开声明会有所不同。如今,央行行长的声明是央行影响金融市场的方式之一。由于这些原因,文本数据通常具有时间维度,并且用日期/时间列记录。
这些数据集的探索性数据分析(EDA)并不是一项简单的编码工作。阿拉比卡咖啡来了——让事情变得更简单。本文涵盖以下内容:
- 阿拉比卡 1.0 中的新聚合和清洗功能
- 时间序列文本数据分析的实际应用
我们将使用来自 data.world 的Twitter 2016 年美国总统大选数据 tweets,展示阿拉比卡 1.0 的新功能。数据集在通用公共领域许可下获得许可。
编辑 2023 年 1 月 :阿拉比卡已更新。查看 当前版本 获取完整的参数列表。
什么是阿拉比卡?
Arabica 是专门为时序文本数据设计的探索性数据分析的 Python 库。我之前的关于数据科学的文章提供了初步的介绍。我建议在继续阅读本文之前先阅读它,作为复习。
它可以与 pip 一起安装:
pip install arabica
Arabica 将文本和时间作为输入,支持标准清理操作(数字、标点符号和停用词删除),并提供在选定时间段内的单字双字和三字频率。
图 arabica _ freq 方法示意图
作为输入文本,它处理基于拉丁字母的语言文本,并启用 ntlk 停用词语料库中语言的停用词移除。
对于时间规范,Arabica 目前以标准日期和日期时间格式读取日期,并以年、月或日频率提供聚合 n 元文法。例如,标准格式为 2013 年 12 月 31 日、2013 年 12 月 31 日、2013 年 12 月 31 日、2013 年 12 月 31 日 11:46:17。
小心欧洲和美国的日期格式差异。建议使用美式日期(MM/DD/YYYY ),而不是欧式日期(DD/MM/YYYY ),因为在小型数据集中,月份和日期可能不匹配。
Arabica 现在有一个可视化模块,提供单词云、热图和单字母词、双字母词和三字母词频率的线图。更多例子见 本教程 。
Twitter 数据用例
让我们看看它在代码中是如何工作的。我们将首先导入阿拉比卡和熊猫并读取数据。
import pandas as pd
from arabica import arabica_freq
我们将使用的数据子集包含姜懿翔·川普总统在总统竞选的最后几周和他上任后的头几周的推文。数据如下所示:
图 2:用作示例数据集的 Twitter 数据
扩展聚合选项
时间序列 n 元图分析
我们可以看到数据相当原始。它包含了大量我们不需要的数字、特殊字符、标点符号和字符串。我们还将跳过特定于该数据集的政客姓名和其他字符串的变体。文本也是小写的,这样大写字母就不会影响 n-gram 的计算(例如,“tree”和“Tree”不会被区别对待)。
在阿拉比卡,一切都很简单:
arabica_freq(text = data['tweet_text'], # Text
time = data['created_at'], # Time
time_freq = 'D', # Aggregation period
max_words = 2, # Max number for n-grams to be displayed
stopwords = ['english'], # Language for stop words
skip = ['realdonaldtrump','trump', # Remove additional strings
'makehillarybrokeagain',
'hillaryclinton',
'barackobama',
'hillary', 'clintons',
'wwmorgan','jordanla',
'whoisNeil','cattmaxx',
'vnkbgygv', 'httpstco',
'httpstcob', 'httpstcod',
'nrclwvhx','httpstcoj',
'httpstcossh'],
lower_case = True, # Lowercase text before cleaning and frequency analysis
numbers = True, # Remove all digits
punct = True) # Remove punctuation
n-gram 频率,尤其是二元模型和三元模型,告诉我们更多关于特朗普总统接任总统后的公共交流。最好增加参数max_words
的值(比如 4 或 5)来更深入地研究它。
图 3: Arabica_freq 输出—每日汇总
描述性 n 元语法分析
在某些情况下,我们需要在开发更复杂的分析之前,首先对文本数据集进行简单的 EDA。在代码中,设置参数time_freq = 'ungroup'
意味着 Arabica 计算整个数据的 unigram、bigram 和 trigram 频率,并且不进行时间聚合。
运行这段代码,我们创建了一个result
数据帧,以后可以保存为 CSV 文件:
result = arabica_freq(text = data['tweet_text'], # Text
time = data['created_at'], # Time
time_freq = 'ungroup', # No time aggregation made
max_words = 6, # Shows 6 most frequent n-grams
stopwords = ['english'], # Language for stop words
skip = ['realdonaldtrump','trump', # Strings to remove
'makehillarybrokeagain',
'hillaryclinton',
'barackobama',
'hillary', 'clintons',
'wwmorgan','jordanla',
'whoisNeil','cattmaxx',
'vnkbgygv', 'httpstco',
'httpstcob', 'httpstcod',
'nrclwvhx','httpstcoj',
'httpstcossh'],
lower_case = True, # Lowercase text
numbers = True, # Remove all digits
punct = True) # Remove all punctuation
以下是输出表:
图 4: Arabica_freq 输出—无时间聚合
扩展清洗选项
在阿拉比卡 1.0 中。我们可以一次删除多组停用词。这对于从使用多种官方语言的国家(加拿大、瑞士、比利时、卢森堡等)中挖掘文本数据非常有用。)或有大量外国人社区的国家。
要从文本中删除英语、法语和德语停用词,请按以下方式修改代码:
arabica_freq(text = data['tweet_text'],
time = data['created_at'],
time_freq = 'D',
max_words = 2,
stopwords = ['english','french','german'],
skip = None,
lower_case = True,
numbers = True,
punct = True)
杰洛特在 Pixabay 拍摄的照片
现实生活的应用
让我们举几个阿拉比卡咖啡可能有用的例子。在营销中,企业使用市场定位方法来影响消费者相对于竞争对手对品牌或产品的认知。这里的目标是建立一个公司或产品的形象或身份,使消费者以某种方式感知它。
产品和网站评论为评估定位策略提供了极好的数据。我们是否高频率地收到了“快速交付”、“卓越服务”、“优质服务”、“快速交付”、“T8”或“好价格”这样的二元词?它是否符合我们希望客户如何看待我们的产品?它会随着时间而改变吗?
在政治学和政治经济学中,用内容分析方法分析公共话语被广泛传播(如 Saraisky,2015 )。我们在这里可能关注的基本主题是,例如,假新闻和民粹主义的后果,公众对具体问题的态度(移民、武器拥有等)。),以及个别政客或政党的个案研究。推特推文为这些调查提供了很好的数据来源。
这些问题不仅可以在时间序列文本数据集上进行研究。您可能会发现许多其他使用案例,其中的文本具有时序特征。其中一些是我在阿拉比卡readthedocs 上开发的。
编辑: 阿拉比卡现在有一个 可视化 模块将文本显示为一个 热图 , 字云 ,和一个 情绪和更多阅读这些教程:
PS:你可以订阅我的 邮件列表 在我每次写新文章的时候得到通知。而如果你还不是中等成员,可以在这里加入https://medium.com/@petrkorab/membership。**
参考资料:
[1]萨莱斯基,新墨西哥,2015 年。分析公共话语:利用媒体内容分析理解政策过程。 当前比较教育中的问题 18(1),26–41。
几行 Python 代码中的文本扩充
原文:https://towardsdatascience.com/text-augmentation-in-few-lines-of-python-code-cdd10cf3cf84
用 NLPAUG 增强自然语言处理中的数据
图片由 Pixabay 的 Mudassar Iqbal 提供
图像增强是在训练 CNN 模型之前对原始图像数据执行的常见任务。图像增强是指操纵图像,包括旋转、剪切、翻转、灰度缩放等。由于语义不变变换,CNN 模型的性能提高,因此图像增强是计算机视觉中的重要工具。
类似于图像扩充,可以为 NLP 任务执行文本扩充,以生成文本数据的语义不变变换。在本文中,我们将讨论一个开源 Python 库——NLP aug,它可以用几行 Python 代码执行文本扩充。
NLPAUG 及其特性?
NLPAUG 是一个 Python 库,帮助开发人员扩充 NLP 任务的文本数据。
根据 NLPAUG 的 GitHub 页面,其主要特点是:
- 生成合成文本数据以提高模型性能
- 支持音频输入
- 用 3 行 Python 代码执行文本扩充
- 易于即插即用到任何机器学习/神经网络框架(例如 scikit-learn、PyTorch、TensorFlow)
文本增强器是 NLP-AUG python 库的一个关键特性。它提供各种针对每个字符,单词,句子,音频,声谱图的增强器。让我们来讨论上述每个增强器的深入实现。
安装:
NLPAUG 库是开源的,可以从 PyPI 安装,使用:
**pip install nlpaug**
实施:
1.)字符增强器:
字符增强器指的是在字符级别增强数据。可能的场景包括图像到文本和聊天机器人。在从图像中识别文字的过程中,我们需要光学字符识别(OCR)模型来实现,但 OCR 会引入一些错误,如识别“0”和“0”。
NLPAUG 提供 3 个函数来执行字符增强器:
- OCR aug:模拟 OCR 引擎错误
(图片由作者提供),OCRAug 实现
- 键盘 Aug: 模拟键盘距离误差
(图片由作者提供),KeyboardAug 实现
- 随机增强: 随机应用增强
(图片由作者提供),RandomAug 实现
2.)单词增强器:
除了字符增强,单词级别也很重要。它利用 word2vec、GloVe、fast text、BERT 和 wordnet 来插入和替换相似的单词。
NLPAUG 提供 7 个函数来执行单词增强器:
- 拼写错误: 根据拼写错误词典替换单词
(图片由作者提供),SpellingAug 实现
(图片由作者提供),WordEmbsAug 实现
- TfIdfAug: 使用 TF-IDF 找出应该如何扩充单词
(图片由作者提供),TfIdfAug 实现
- contextualwordenmbsaug:向 BERT 、DistilBERT、 RoBERTa 或 XLNet 语言模型输入环境词,以找出最适合增强的词
- FasttextAug: 使用单词嵌入找到最相似的一组单词来替换原来的单词
- BertAug: 使用语言模型预测可能的目标词
- WordNetAug: 用统计的方式找到一组相似的单词
3.)句子增强器:
(图片由作者提供),ContextualWordEmb 实现
- 【AbstSummAug:
用抽象概括的方法概括文章。
结论:
在本文中,我们讨论了一个可以扩充文本数据的开源 Python 库。这个 Python 库在处理 NLP 任务时是一个方便的工具。与图像增强相比,NLPAUG 可能有助于提高模型的性能。
NLPAUG 库也执行音频信号的增强。
参考资料:
[1] NLPAUG 文档:https://github.com/makcedward/nlpaug
感谢您的阅读
AutoKeras 简化了文本分类
原文:https://towardsdatascience.com/text-classification-made-easy-with-autokeras-c1020ff60b17
一个利用自动机器学习能力的简单例子
图片作者。
目录
1.介绍
自动化机器学习 ( AutoML )旨在自动化机器学习解决方案的设计。
特别是,它包括一系列技术来自动确定数据准备、模型和超参数的最佳集合。
AutoML 可以通过更容易地采用机器学习来支持该领域知识有限的用户。此外,它还可以通过加速实验和缩短上市时间来帮助更高级的用户。
在神经网络竞赛中,AutoML 在不同的神经网络架构和超参数中搜索,以找到最佳匹配,这个过程称为神经架构搜索 ( NAS )。
AutoKeras 是一个开源库,使用 Keras API 实现了深度学习的 AutoML。
在这篇文章中,我们将使用 AutoKeras 来训练一个文本分类器,能够在几行代码中检测垃圾邮件。特别是,我们将提供代码片段,可以很容易地在⁴.的谷歌实验室复制和执行
2.环境设置
让我们从 Colab 笔记本上安装 AutoKeras:
!pip install autokeras
要在本地环境下安装 AutoKeras,我们应该在官方文档上查看与 Python 和 TensorFlow 的兼容性。让我们导入所需的库:
import pandas as pd
import numpy as np
import tensorflow as tf
import autokeras as ak
3.数据准备
对于这个例子,我们将使用来自⁶.UCI 机器学习库的公开可用的垃圾短信收集数据集 ⁵ 该数据由一个文本文件组成,其中包含一组被标记为垃圾邮件或 ham 的 SMS 消息。
我们进行如下操作:
- 将数据集下载为 zip 文件夹:
!wget "https://archive.ics.uci.edu/ml/machine-learning-databases/00228/smsspamcollection.zip"
- 打开文件夹:
!unzip -o smsspamcollection.zip
- 检查数据文件的前几行:
!head -10 SMSSpamCollection
图片作者。
- 对于每一行,我们注意到标签后面跟着一个制表符和原始文本消息。我们选择处理文件以获得一个
pandas.DataFrame
对象,因为这种格式代表了数据科学实验中的一个共同起点:
fileName = '/content/SMSSpamCollection'df = pd.DataFrame({'label':int(), 'text':str()}, index=[])with open(fileName) as f:
for line in f.readlines():
split = line.split('\t')
df = df.append({'label': 1 if split[0]=='spam' else 0,
'text': split[1]},
ignore_index = True)df.head()
图片作者。
autokeras.TextClassifier
⁷类需要以numpy.ndarray
或tf.data.Dataset
的形式输入数据。因此,我们转换我们的数据,并将它们分成训练集和测试集:
from sklearn.model_selection import train_test_splitx = np.array(df.text)
y = np.array(df.label)x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.25)
4.文本分类
为了构建文本分类器,我们只需要创建一个autokeras.TextClassifier
⁷类的实例,并将其放在训练数据上:
clf = ak.TextClassifier()clf.fit(x_train, y_train)
AutoKeras 将根据验证数据的性能自动确定最佳模型和超参数。
注意事项:
autokeras.TextClassifier
类接受max_trials
参数来设置可以尝试的不同 Keras 模型的最大数量。因为默认值是 100,所以为了快速演示,可能需要减小它,例如clf = autokeras.TextClassifier(max_trials = 3)
。- 我们之前将标签映射到整数(0: ham,1: spam)。这不是绝对必要的:我们可以使用原始标签作为 well⁷.
- 默认情况下,AutoKeras 使用最后 20%的训练数据作为验证数据。可以使用
validation_split
参数来指定所需的分流比,例如:
clf.fit(x_train,
y_train,
validation_split = 0.3)
在训练过程之后,我们可以使用最佳分类器对测试集进行预测并评估性能:
from sklearn.metrics import classification_reporty_hat = clf.predict(x_test)print(classification_report(y_test, y_hat))
测试集评估。图片作者。
5.导出性能最佳的模型
可以导出最佳分类器并检查其架构,如下所示:
# get the best performing model
model = clf.export_model()# display the architecture of the best performing model
model.summary()
运行 max_trials=3 的实验后获得的最佳性能模型的体系结构。图片作者。
重要的是要记住,这个模型来自一个不同的过程,而不是超参数调整。在超参数调整中,模型是已知的,我们通过在给定范围的可能值中搜索来调整一些参数,以提高性能。相反,对于 NAS,我们试图确定模型体系结构本身。因此,其他培训工作可能会导致不同于上面显示的模型架构。
还可以保存和加载模型以备将来使用:
from tensorflow.keras.models import load_model# save the model on disk
model.save("text_classifier", save_format = "tf")# load the model from disk
loaded_model = load_model("text_classifier",
custom_objects = ak.CUSTOM_OBJECTS)# use loaded model for future predictions on new samples
loaded_model.predict(x_test)
6.结论
在这篇文章中,我们用几行代码创建了一个强大的文本分类器。我们利用了 AutoML 的强大功能和直观简洁的 AutoKeras 界面。
AutoML 寻求简化机器学习。它通过自动化人类实验中最耗时的阶段来减少人工劳动。它还使缺乏该领域更深知识的观众更容易采用机器学习。
AutoKeras 官方文档包含更多示例和高级主题。
7.参考
[1]https://en.wikipedia.org/wiki/Neural_architecture_search
[3]金海峰、宋清泉、; Auto-keras:一个高效的神经结构搜索系统;第 25 届 ACM SIGKDD 知识发现国际会议论文集&数据挖掘;ACM2019 ( 环节)
https://colab.research.google.com/
https://archive.ics.uci.edu/ml/datasets/sms+spam+collection
https://archive.ics.uci.edu/ml/index.php
https://autokeras.com/text_classifier/
文本网络分析:网络构建方法简评
从研究问题定义到网络结构估算的简明、有条理的指南。
图一。通过文本网络绘制文本网络图。作者图片
介绍
本文探讨了从文本数据构建网络结构的策略。这是 Python 文本网络分析系列的第二部分。作为一名先修者,请阅读我的开篇文章,这篇文章描述了文本网络分析的主要概念(文章在这里是)。我们将遵循(博尔索姆等人,2021 )定义的步骤,并在前一篇文章中简要介绍。
图二。网络方法中使用的工作流程示意图。改编自博尔索姆等人,(2021 )。图片由 draw.io
定义研究问题之外的进一步步骤取决于我们的数据结构。因此一开始要问的关键问题是:网络模型的输入是什么?
我们可能会与:
- 未加工的原始数据
- 用节点-边结构清理数据
我们也可以将第一个转换为第二个,并转换原始数据,清理它,并创建节点-边结构。
1。从原始文本数据构建网络
首先,我们先来回答一个问题:
研究问题:期刊文章标题中研究领域之间有哪些术语是共享的?
来自 Kaggle 的 Research Articles Dataset 包含六个主题(计算机科学、数学、物理学、统计学、定量生物学和定量金融学)的期刊文章摘要,是说明 Python 编码的一个很好的选择。这里的数据许可是这里的。
它看起来是这样的:
图 3。研究文章数据集中的第一行
Textnets 是根据 Bail 的(2016) PNAS 论文开发的。它同时存在于 Python 和 R 实现中。默认情况下,它使用莱顿算法在文本数据中进行社区检测。这组算法有助于发现大型复杂网络的结构,并识别出相互连接但与网络其余部分稀疏连接的节点组(参见 Traag et al .,201 9, Yang et al .,2016 )。点击了解更多其他检测算法。
履行
让我们看看它是如何工作的。首先,我们导入Textnets
和Pandas
,并读取数据。设置index_col='research_field'
以正确绘制图形很重要(参见我的 GitHub 上的完整代码)。接下来,我们从文章标题栏构建语料库。我们使用一个子集来代表每个研究领域的 10 篇文章的标题,以使图解网络更简单。
Textnets 然后移除停用词,应用词干,移除标点符号、数字、URL 等,创建一个文本网络。mind_docs
指定一个术语必须出现在网络中的最小文档数。
现在,让我们绘制网络图。show_clusters
选项标记由莱顿检测算法找到的分区。它识别文档术语组,这些术语组似乎构成了文本中同一主题的一部分。
这是我们得到的网:
图 4。通过文本网络的文本网络。作者图片
调查的结果
我们可以清楚地区分不止一个研究领域共享的关键词。例如,“时间”和“风险”(定量金融—计算机科学)、“深度”和“实证”(数学—统计—计算机科学)、“主题”和“记忆”(定量生物学—计算机科学)。
这些发现很大程度上取决于样本量。我们拥有的数据集越丰富,我们获得的结果就越精确。我们可以用很多其他方式画出网络结构,这取决于我们一开始设定的研究问题。看一下 Textnets 教程这里。
2.从节点-边结构构建网络
我们可以处理具有清晰节点-边结构的数据,这通常涉及清理和预处理。为了探索可能的场景,让我们使用 IMDb 50K 电影评论数据集,其中包含电影评论及其评估的情绪(正面/负面)。这里的数据许可是这里的。
NetworkX 是一个用于创建和研究复杂网络的 Python 库。这是一个高度开发的包,包含了广泛的文档,在许多教程和电子书中绘制了网络。该软件包的合著者哈格伯格等人(2008) 提出了内部网络 x 结构。它可以显示各种网络结构;文本数据通常需要一些转换来作为输入。
文本网络通常用于显示文本中的关键词共现(Shim 等人,2015;Krenn 和 Zeilinger,2020,以及许多其他人)。我们将使用相同的方法,作为一个用例,我们对电影评论者与著名的《黑客帝国》电影的关联感兴趣。
该数据由两组 节点 : 被监控的电影片头 ( 矩阵 ) 和一组被选中的电影片头组成,评论者可能将这些片头与矩阵相关联。边 由同一评论中节点的同现表示。仅当评论者在同一评论中提到被监控的和相关联的电影标题时,该边缘才存在。
研究问题:哪些热门科幻电影主要与《黑客帝国》有关?
数据具有以下结构:
图 5。数据,“节点-边”示例。作者图片
实施
阅读完数据后,让我们做一些简单的转换和探索步骤,帮助我们理解图表并正确地绘制图表。
- 计算边缘尺寸
为了量化边缘,我们在数据中创建一个单独的列edge_width
,在node2
列中包含每个边缘的大小。
2.创建图表并打印节点和边以防止可能的误解
3.绘制网络图
在简单检查了没有意外错误发生之后,我们继续,将原始的 G 图形塑造成星形图形,将图形的属性保存在options,
中,并用matplotlib.
进行绘制
代码绘制了这个漂亮的网络星形图形:
图 6。通过 NetworkX 的文本网络绘图。作者图片
调查结果: 电影片名的数据不是很丰富,但网络分析表明,评论者大多将《黑客帝国》与雷神和创联系在一起。在对如此小的数据集进行简短的数据检查后,这似乎是显而易见的。然而,假设您有一个包含大量节点的大型数据集。在这里,网络分析非常有助于描述数据集。
结论
这篇文章不可能对文本网络构建方法提供一个完全详尽的综述。由于互联网上有多个来源,我省略了各种网络结构的详细概述。相反,它概述了这一领域的几个方法要点。
总而言之,这里有几个可以遵循的提示:
- 首先,明确定义你特定项目中的研究问题。文本网络分析是一种提供答案的实证方法。
- 接下来,看看数据集结构。如果研究问题需要数据转换,就去做。
- 创建的网络可能不是分析的最终输出,而是更复杂研究的对象:图形、机器学习模型、预测等。
完整的代码在我的 GitHub 上。
本系列的下一篇文章将为简单和更复杂的文本数据分析图表提供更多的启示。最后一篇文章将探索语义网络在预测中的最新应用。 保持更新!
PS:你可以订阅我的 邮件列表 在我每次写新文章的时候得到通知。而如果你还不是中等会员,可以在这里 加入 。
参考
[1]保释,a,C. 2016。结合自然语言处理和网络分析,研究倡导组织如何刺激社交媒体上的对话。 《美国科学院院刊》 ,第 113 卷,第 42 期。
[2] Borsboom 等人,2021 年。心理科学中多元数据的网络分析。 《自然评论 ,第 1 卷,第 58 期。
[3]哈格伯格,a .,舒尔特,d .,a .,斯沃特,p .,J. 2008。使用 NetworkX 探索网络结构、动力学和功能,载于《第七届 Python 科学会议论文集》(SciPy2008),el Varoquaux、Travis Vaught 和 Jarrod Millman (Eds),(美国加利福尼亚州帕萨迪纳),第 11–15 页,2008 年 8 月。
[4]m .克伦,泽林格,2020 年。用语义和神经网络预测研究趋势及其在量子物理中的应用。 美国国家科学院院刊 ,v ol。117,4 号。
[5]辛姆,j .,帕克,c .,威尔丁,M. 2015。通过语义网络分析识别政策框架:对六个国家核能政策的检查。https://link.springer.com/article/10.1007/s11077-015-9211-3《政策科学》,第 48 卷。
[6] Traag,V. A .,Waltman,l .,Van Eck,N. J. 2019。从卢万到莱顿:保证良好连接的社区。 科学报告 ,第 9 卷,第 5233 号。
[7]杨,z .,阿尔杰什海默,r .,特松,C. J. 2016。人工网络社区发现算法的比较分析。 科学报告#auth-Ren_-Algesheimer) ,第 6 卷,第 30750 号。
文本网络分析:生成美丽的网络可视化
了解如何以圆形、放射状和矩阵形式可视化文本网络:圆形、蜂窝状和矩阵图。同时,学习绘制文本网络的注意事项。
图一。文网图 via Pyvis 。作者图片
介绍
本文开发了一个关于 Python 文本网络分析的系列。它建立在 文本网络分析:理论与实践 的基础上,奠定了文本网络的基础,以及 文本网络分析:网络构建方法的简明回顾 ,侧重于数据准备和网络构建策略。
最后一篇文章将构建文本网络的策略分为(I)从原始文本中提取网络,和(ii)网络建立在预处理数据的基础上,边缘和节点定义清晰。在本文中,我们将扩展第二个选项,并使用预处理的经典 IMDb 50K 电影评论(参见数据许可)来说明以下网络图形:
- circos 图:以圆形布局可视化网络
- 蜂巢图:沿几个轴构建网络图
- 矩阵绘图:以矩阵形式绘制网络。
我们将不涉及标准的 网络图 ,而是关注更高级的情节。Pyvis 是一个非常方便的 Python 库,支持图形小部件的交互式配置,在这里可以有效地使用。本教程由 Khuyen Tran 提供了一个很好的介绍。另外,构成 circos 基础的 圆弧图 可以在文本网络上直观地开发。
文本网络可视化的最佳实践
第一步,让我们总结一些网络可视化的注意事项,这些事项通常适用于大多数网络结构,而不仅仅是文本网络。尽管有选择性且主要基于个人经验,但遵循这些原则有助于避免绘制网络数据时的一些主要陷阱。
#1:从目标开始
网络数据结构可能非常复杂。为了使可视化工作成功,在一开始就要弄清楚(1)你想用图形讲述的故事,以及(2)你想突出哪些关系。
#2:避免“毛球”
图二。毛球——例如。作者图片
"可视化的目的是洞察力,而不是图片."本·斯奈德曼。
“毛球”是一个术语,指的是显示连接的图形,这些连接如此密集,以至于无法有效地可视化。我们可能会遇到这样的情况,我们绘制的图表有大量的节点(一个经验法则是 30 个或更多的节点,就像马(2022 )建议的那样),可视化的结果是一团乱麻。图 2 给出了一个这样的例子。
可能的解决方案包括:
- 对节点进行排序:将节点数量减少到最重要的节点(例如,只有那些边超过一定权重的节点)
- 分组节点 s:对数据进行不同的预处理,将节点分组到特定的类别中
- 选择合适的图形:有些图,比如 circos 图,可以更好的显示节点多的数据
- 调整图形属性:图像大小等。
#3:优先考虑重要的边缘
在许多情况下,我们对特定的节点和相应的边比其他数据更感兴趣。让我们给它们一个优先级,增加边缘线的宽度,或者使用特定的颜色来区分它们,如果这对您的数据故事有意义的话。
"图的核心在于它的边,而不在于它的节点."约翰·奎肯布什,哈佛大学公共卫生学院。
这里有一个例子:
“随着新冠肺炎病毒的传播,接触者追踪变得相当重要。在传染病接触网络中,个体是节点,某种类型的个体之间的接触是边,这个接触网络中的“重要”节点将是被感染的个体,以及在被感染期间与许多人接触的个体。(马和塞斯,2022) 。
#4:节点的位置和颜色很重要
图表中节点的正确定位和着色可能会提高图表的信息价值,同时保持数据结构不变。
为了最大程度地提供信息和交流,图形可视化应该首先以一种有意义的方式对节点放置进行优先级排序。【马】(马和塞斯,2022)。
作为一个例子,我们可以从电影评论中看到两个电影网络及其特征(图 3)。左侧未排序的图表可能需要一段时间才能理解。对节点进行排序,将电影标题和特写放在情节的相对侧,并对节点组进行着色,即使对于这样一个小网络也能提高理解。点击查看图形的代码。
图 3。网络图中已排序和未排序的节点。作者图片
Circos 图—从网络到圆
现在让我们来发现三个建立在网络上的图。一个 circos plo t,或者更一般的一个弦图,以圆形显示网络。
图 4。Circos 图。来源: Korab。文本数据分析的高级可视化
circos 图中的边通常被绘制为弧,它们的大小与连接的重要性成比例。 Krzywinski 等人(2009 )最初开发了以圆形布局显示关系以可视化基因组数据的想法,并很快在其他领域扎根,例如劳动经济学 ( Malhotra 等人,2016 )和应用机器学习 ( Zoabi 等人,2021 )。
许多修改的核心思想本质上是相同的:以圆形显示节点和边,通常在图形上添加一些更高级的见解。
有很多种工具和库可以实现类似 Circos 类型的图形。在 Python 中分别是 Nxviz , Circos,PCircos,或者pyCircos。对于使用预处理文本数据的 python 编码,你可以使用我以前的文章 文本数据分析的高级可视化 作为参考。
蜂巢图-从网络到坐标系
蜂巢图是一种稍微高级一点的网络可视化方法,其中节点根据明确定义的坐标系放置在径向线性轴上。
图 5。蜂巢情节与预处理电影评论。作者图片
在该图中,节点被分配给两个(或多个)轴中的一个,这两个轴可以被分成段。边缘被绘制成曲线,可以用颜色、厚度或标签进行注释,以传达附加信息。阅读原文 Krzywinski 等人(2012) 了解更多基础理论。
Hive plot 对于文本挖掘中的数据可视化的明显优势是:
- 组间和组内连接可视化:一个毛团型网络可以被向下钻取,以发现节点组内和节点组之间的关系。
- 直接网络视觉可比性:有可能评估两个或更多网络的网络结构,因为蜂巢图是基于网络属性,而非美学布局。
研究问题:影评人在影评中主要比较哪些电影公司?
数据被转换成反映电影名称在评论中的同现的节点和边。数据中的每一行都表明这些节点在一次审查中联合出现的频率。数据如下所示:
此外,我们将为每个节点使用节点属性:
履行
Python 为 hive plots 提供了几个库——最常见的是 Nxviz 和Hiveplotlib。【nxviz 提供编码高效的 hive plot 图形,Hiveplotlib 提供更复杂的解决方案和更好的文档。让我们使用前者,并准备一个回答研究问题的高效解决方案。
首先,让我们导入我们需要的所有东西:
接下来,让我们读取节点、边及其属性的数据,并创建一个图 G:
最后,这段代码按照节点属性对节点进行分组和着色,并准备一个带注释的配置单元图:
从图 5 中的一个基本例子,我们可以看到漫威电影之间很少有组内边缘,而漫威和卢卡斯影业电影之间有很多组间联系。评论者主要比较漫威和卢卡斯的电影,可能是因为这些工作室制作类似类型的电影。
矩阵图—从网络到矩阵
矩阵 plo 以矩阵形式显示网络。节点位于 x 轴和 y 轴上,实心正方形表示节点之间的边。
图 6。有向和无向图。图片由作者使用 Nxviz 制作
以矩阵形式绘制网络有助于确定图形是有向的还是无向的。让我们用一个堆栈溢出的例子:
“把图形想象成一组泵,当它们连接起来时,可以把液体送到其他人那里。在有向图中,箭头表示液体的来源和流向;在无向图中,它是双向的。”(stackoverflow.com)。
在电影评论中,开发一个有向和无向图的例子是具有挑战性的。大多数情况下,例如,演员在同一部电影中演出,都会产生一个无向图。让我们使用标准网络的一个不同实例:
图 6 中的节点是机场,边是它们之间的航班。在右边的网络中,航班从希思罗机场(节点 2)飞往巴黎戴高乐机场(节点 6)并返回(该图是无向的,该图是对称的)。在左图中,飞机从希思罗机场飞往戴高乐机场,但没有返回(有向图,有些不对称)。
结论
本文大部分内容一般指网络可视化,要求将文本数据转换为边和节点。对于文本数据,节点是语义概念、关键字、主题组或其他具有字符串类型的实体。要从评论、电影标题或报纸文章等原始文本中绘制网络,请使用实现社区检测算法的工具,如 Infranodus 或 Textnets 。
我的 GitHubGitHub上有 Jupyter 笔记本的代码。
PS:你可以订阅我的 邮件列表 在我每次写新文章的时候得到通知。如果你还不是中等会员,你可以在这里加入https://medium.com/@petrkorab/membership。**
参考
[1] Krzywinski,m .,Birol,I .,s .,Jones,s .,J.M .,Marra,m .,A. 2012。蜂巢图——可视化网络的理性方法。 生物信息学简介 13(5)。
[2] Krzywinski,m .,I .,Schein,j .,e .,Birol,I .,Connors,j .,Gascoyne,r .,Horsman,d .,Jones,s .,j .,Marra,m .,a .,2009 年。比较基因组学的信息美学。 基因组研究 32 卷 6 期。
[3]马,鄂 2022。如何看待网络可视化?于 2022 年 7 月 14 日从https://ericmjl.github.io/nxviz/theory取回。
[4]马,e,塞斯,M. 2022。简化网络分析:使用 Python 和 NetworkX 介绍网络分析和应用图论。精益出版。2022 年 5 月 16 日。
[5]马尔霍特拉,r . s .,2016 年。1960-2000 年亚洲的性别和生育劳动力迁移。https://www.tandfonline.com/doi/abs/10.1080/00207659.2016.1163989国际社会学杂志第 46 卷第 2 期。
[6] Zoabi,y .,Kehat,o .,Lahav,d .,Weiss-Meilik,a .,Adler,a .,Shomron,N. 2021。使用机器学习预测血流感染结果。 科学报告 11(20101)。
文本网络分析:理论与实践
原文:https://towardsdatascience.com/text-network-analysis-theory-and-practice-223ac81c5f07
文本网络分析属于大多数面向文本数据的分析师的更广泛的技能集。
本文开始了探索这个奇妙领域的旅程:从理论、数据准备和网络构建到可视化和预测——这个系列涵盖了 Python 中文本网络的最基本概念。
图一。文网图 via Pyvis 。作者图片
20 世纪后期以来的发展,如…
- 社交网络数据的可用性(例如推特),
- 政客声明和央行行长会议文字记录,
- 文本数据库的公共可用 API(Google Trends, RSS feeds , Wikipedia , Google Ngrams )
- 大数据处理技术的总体发展
…潜在的许多其他因素导致了大量的文本数据很容易被分析师、学生和研究人员访问。随着时间的推移,科学家们开发了许多复杂的方法来理解文本数据集中的关系,包括文本网络分析。
关于 Python 中文本网络分析的第一篇文章将简要介绍文本网络分析的基础,文本网络的真实应用,以及它们在主要数据科学和商业智能(BI)软件中的实现。
文本网络分析
在学术文献中,网络更正式地称为图。图论更严谨的理论命题可以追溯到 20 世纪 50 年代(Berge,1958)。久而久之,文字网络文学演变成了几大流派:
- 语义网络:对概念、主题和关键词的相互联系进行建模( Netzer et al .,2012;格里菲斯等人,2007 年
- 图神经网络:结合神经网络与网络数据结构(廖等,2021;克伦&泽林格,2020;姚等人 2019
- 网络可视化方法:提出网络可视化和图发现的新方法( Paranyushkin,2019;塞拉多&埃弗雷特,2020
- 软件开发和算法实现:参见下面第三节中的例子。
这一领域在学术研究人员中迅速普及。体现在 JSTOR 数据库中以“网络”为关键词的论文量(链接此处)以及 Google Books 中文本网络和语义网络的流行程度(可从此处)上。
更正式地说,网络由两组对象组成(马& Seth,2022):
一个节点集合:图中的“实体”
一个边集合:图中实体之间“关系”的记录。
例如,如果节点集 n 由元素组成:
然后,边集 e 将被表示为元素对:
如果我们画出一个网络,节点通常表示为形状,如圆形,而边是形状之间的线。在文本挖掘中,边和节点可以表示为:
- 社交和职业网络 : 节点--个人用户、边缘--“一个用户决定追随另一个用户”
- 报刊文章中假新闻的识别 : 节点-与假新闻报刊文章关联最频繁、最相关的词语,边缘* - 词语在文章中的同现(Segev,2020)*
- 发现 美国参议员关于弹劾的公开话语 : 节点-参议员,边缘 -参议员公开声明的相似之处
- 通过分析书面文本理解政策沟通 : 书面沟通中的节点--概念,边缘--概念在句子或段落中的同现(Shim et al .,2015)
- 倡导组织在塑造社交媒体上的对话中的作用: 节点--参与关于倡导问题的公共对话的行为者,边缘--他们的消息内容的相似性(Bail,2016)。
通常,网络方法中使用的特定工作流程从研究问题的定义开始,并导致推理和决策。在不太复杂的任务中,可以省略几个步骤,但是完整的工作流包括图 2 中的步骤。
图二。网络方法中使用的工作流程示意图。资料来源:博尔索姆等人,2021 年。图片由 draw.io
一个有趣的领域是使用文本网络进行预测的文献流。图结构在此用作模型,其权重可通过神经网络优化,并用于预测感兴趣的特定变量。Krenn&zei linger(2020)利用语义网络和深度学习预测研究课题,未来五年将发表在《量子物理学》上。
主流软件中的网络技术
所有主要的数据科学和 BI 工具都实施了网络分析方法。这里是最常见的库和商业程序的列表。其中一些主要不是为文本数据分析而设计的,但是通过向它们提供正确转换的数据,我们可以显示文本的网络结构:
Python:
网络建设:
网络可视化:
网络建设和可视化:
朱莉娅:
r:
- Textnets for R
- visNetwork(这个列表不完整,因为我不是经常使用 R 的用户)**
由于公司需要理解复杂的网络数据结构,大多数 BI 程序包括网络方法和图形。参见 Data Surfers (2019) 关于 Tableau 的网络可视化教程和 Power B I 中的网络方法列表。对于其他商业和开源软件,我们可能会选择https://infranodus.com/**(【文字网络分析】Neo4j(【图形数据科学】)ge phi**(**)或SocNetV
我们要去哪里?
本文是即将推出的用 Python 分析文本网络系列的第一部分。了解以下内容的最新动态:
从头开始文本网络分析#3 —使用网络作为预测模型
PS:你可以订阅我的 邮件列表 在我每次写新文章的时候得到通知。而如果你还不是中等会员,可以在这里加入https://medium.com/@petrkorab/membership。****
参考
[1]保释,a,C. 2016。结合自然语言处理和网络分析,研究倡导组织如何刺激社交媒体上的对话。 《美国国家科学院院刊》 ,第 113 卷第 42 期。
[2 ]贝尔热,1958 年生。图形理论及其应用。巴黎:Dunod Editeur。
[3] Borsboom 等人,2021 年。心理科学中多元数据的网络分析。 《自然评论方法引论 ,第 1 卷,第 58 期。
[4]塞拉多,l .,埃弗雷特,M. G. 2020。网络文本分析:一种双向分类方法。 《国际信息管理杂志 》,第 51 卷,4 月。
[5]格里菲斯,t .,l .,斯泰弗斯,m .,Firl,A. 2007。谷歌与思维:用 PageRank 预测流畅性。 《心理科学》 ,第 18 卷第 12 期。
[6]m .克伦,泽林格,2020 年。用语义和神经网络预测研究趋势及其在量子物理中的应用。 美国国家科学院院刊 ,v ol。117,4 号。
[7]廖,曾,刘,魏建平,程,张,张. 2021 .用于文本情感分析的多层图神经网络。 C 小型机&电气工程 ,第 92 卷,6 月。
[8]马,e,塞斯,M. 2022。简化网络分析:使用 Python 和 NetworkX 介绍网络分析和应用图论。精益出版。2022 年 5 月 16 日。**
[9]o . Netzer,r . Feldman,Goldenberg,j . fres ko,M. 2012 年。挖掘你自己的生意:通过文本挖掘的市场结构监视。 《营销科学》 ,第 31 卷,第 3 期。
[10]帕拉纽什金,2019 年。InfraNodus:使用文本网络分析产生洞察力。在 2019 年 5 月 13 日美国旧金山举行的 WWW '19:网络会议的会议录中。
[11]塞格夫,2020 年。文本网络分析:检测国际新闻和社会媒体中的流行主题和偏见。 《社会学罗盘 》,第 14 卷第 4 期。
[12]辛姆,j .,帕克,c .,威尔丁,m .,2015 年。通过语义网络分析识别政策框架:对六个国家核能政策的检查。 《政策科学 》,第 48 卷。
[13]数据冲浪者。2019.如何使用 Gephi 为 Tableau 创建网络可视化?检索自https://the data surfers . com/2019/08/27/how-to-use-ge phi-to-create-network-visualizations-for-tableau/2022–5–31。
[14]姚,李,毛,陈,罗,杨. 2019 .用于文本分类的图卷积网络。美国夏威夷州第三十三届 AAAI 人工智能会议(AAAI-19) 论文集。
Python 中带 Levenshtein 距离的文本相似度
原文:https://towardsdatascience.com/text-similarity-w-levenshtein-distance-in-python-2f7478986e75
用 Python 构建抄袭检测管道
在这篇文章中,我将回顾 Levenshtein 距离是如何工作的,以及如何使用 Levenshtein 距离来建立一个剽窃检测管道。
目录
- 文本相似性介绍
- Levenshtein 距离
-直觉
-数学理解- Python 实现
- 问题陈述
-解决方案架构
-安装要求 - 取数据
- 干净的数据
- 寻找相似之处
- 检查抄袭
- 警告
- 结束语
- 资源
文本相似性介绍
识别文本之间的相似性是自然语言处理中的一个常见问题,世界上许多公司都在使用它。文本相似度最常见的应用来自于识别抄袭文本的形式。世界各地的教育机构,从小学、高中、学院到大学,都使用像 Turnitin 这样的服务来确保学生提交的作品是原创的,是他们自己的。文本相似性的其他应用通常由具有类似于栈溢出或栈交换的结构的公司使用。他们希望能够识别和标记重复的问题,以便张贴问题的用户可以引用带有解决方案的原始帖子。这减少了重复问题的数量,增加了平台上独特问题的数量。
文本相似度可以分解为两个部分,语义相似度和词汇相似度。给定一对文本,这对文本的语义相似度指的是文档在意义上有多接近。然而,词汇相似性是词汇重叠的一种度量。如果文档对中的两个文档具有相同的词汇,那么它们的词汇相似度为 1,反之亦然,如果词汇没有重叠的话[2]。
在自然语言处理和数学中,实现真正的语义相似性是一项非常困难且尚未解决的任务。这是一个需要深入研究的领域,提出的许多解决方案都涉及到一定程度的词汇相似性。对于本文的重点,我不会更深入地研究语义相似性,而是更多地关注词汇相似性。
莱文斯坦距离
有许多方法可以识别一对文本之间的词汇相似性,我们今天要讨论的一种方法是 Levenshtein 距离。苏联数学家弗拉基米尔·莱文斯坦于 1965 年发明的一种算法。
直觉
Levenshtein 距离非常有影响力,因为它不要求两个字符串长度相等才能进行比较。直观来说,Levenshtein 距离相当好理解。
非正式地,两个单词之间的 Levenshtein 距离是将一个单词变成另一个单词所需的单个字符编辑(插入、删除或替换)的最小数量。[1]
-https://en.wikipedia.org/wiki/Levenshtein_distance
实质上意味着两者之间的输出距离是单个字符编辑的累积和。输出距离越大意味着需要更多的变化来使两个单词彼此相等,而输出距离越小意味着需要的变化越少。例如,给定一对单词dream
和dream
,得到的 Levenshtein 距离将是 0,因为这两个单词是相同的。然而,如果单词是dream
和steam
,那么 Levenshtein 距离将是 2,因为您需要进行 2 次编辑来将dr
更改为st
。
因此,Levenshtein 距离的大值意味着两个文档不相似,距离的小值意味着两个文档相似。
数学理解
Levenshtein 距离可以用下面的分段函数来表示:
图片取自 Levenshtein Distance 维基百科
其中a
和b
对应于两个输入字符串,而|a|
和|b|
是每个相应字符串的长度。字符串a
或b
的tail
对应于字符串中除第一个字符以外的所有字符。表示a[0]
和b[0]
的地方,是第 0 个元素的a
和b
中的字符。
让我们通过下面的例子来看看 Levenshtein 距离是如何工作的。
列文斯坦距离的例子。图片由作者提供。
履行
与使用动态编程实现 Levenshtein 距离相关的 Python 代码。同样的代码可以通过强力和迭代解决方案来实现(注意,就时间复杂度而言,强力解决方案不是最优的)。
问题陈述
类似于 Turnitin 这样的软件,我们希望建立一个管道来识别输入的文章是否抄袭。
解决方案架构
要解决这个问题,需要做几件事。首先,我们需要获得管道用户传递的信息,为此我们不仅需要他们想要检查抄袭的文章,还需要与该文章主题对应的关键字标签。为了简化本教程,我们将使用我为本文编写的初始文本,标签为Levenshtein Distance
。第二,我们需要一个大的文档语料库来比较用户输入的文本。我们可以利用 Wikipedia-API 来访问与用户输入数据的标签相关联的 Wikipedia 文章。然后,我们可以清除用户输入文档中的冗余,如停用词和标点符号,以更好地优化 Levenshtein 距离的计算。我们通过语料库中与用户输入文档相同标签下的每个文档来传递该清理后的文档,并识别是否存在与用户提交的文档非常相似的任何文档。
上述解决方案架构。图片由作者提供
安装要求
Python=3.8.8
python-Levenshtein=0.12.2
nltk=3.6.1
numpy=1.20.1
Wikipedia-API=0.5.4
为了这条管道的目的,我们将使用一个开源包,它将为我们计算 Levenshtein 距离。我们将使用这个包,因为它用 C 实现了 Levenshtein 距离,并且很可能比我们用 Python 编程编写的任何东西都要快。
要下载本教程的 Levenshtein 包,您可以在终端上运行下面的命令:pip install python-Levenshtein
按照他们的安装指南找到这里 [3]。或者你可以克隆与这个包相关的 GitHub 库并相应地使用它。
为了将用户输入的文章与另一篇文章进行比较,我们将参考维基百科。你可以通过维基百科图书馆很容易地获取维基百科的文本数据。您可以在您的控制台上运行以下命令:pip install wikipedia
根据安装指南找到这里。或者你可以克隆与这个包相关的 GitHub 库并相应地使用它。
取数据
当用户在标签Levenshtein Distance
下提交文章时,上面的代码基本上传递了我的文章的初始部分。它还通过维基百科模块获取 Levenshtein 距离的维基百科页面。
干净的数据
现在我们可以清除与用户提交和维基百科获取的文章相关的数据。我们将对文本做一些简单的数据预处理,降低文本,删除停用词和标点符号。
寻找相似之处
用户输入文章与取自维基百科的内容的距离与标签 Levenshtein 距离相关联。图片由作者提供。
现在这个值对你来说可能看起来比较随意,很难确定这个值是否反映了内容是否抄袭。值越大,基于我们对 Levenshtein 距离的理解,被认为抄袭的可能性就越小。然而,很难确定距离不够大的阈值。
检查抄袭
我们将通过一个简单的公式化方法来检查抄袭。首先,我们得到用户提交的文章和内容之间的最大长度。然后我们检查 Levenshtein 距离是否小于或等于该值乘以某个阈值(我用的是 0.4),那么该用户提交的文章可以被认为是抄袭的。
管道的结果,最初输入的文章被管道归类为“未抄袭”。图片由作者提供。
警告
使用上述管道有许多注意事项。
1)该管道不识别哪些区域是抄袭的,哪些区域不是,它仅产生抄袭的总体分数。该过程不考虑正确引用和引述的文本片段。这将误导性地增加整体抄袭分数。很难确定多大或多小的距离才算抄袭。
结束语
Levenshtein 距离是一种词汇相似性度量,它标识一对字符串之间的距离。它通过计算从字符串 1 中插入、删除或替换一个字符的次数来使它像字符串 2 一样。配对之间的距离越大,意味着字符串彼此不相似,反之亦然。
我创建这个管道的方式使得它很容易与其他文本相似性度量集成。Levenshtein 距离是用来识别一对文本之间词汇相似性的一个很好的度量,但是它并不意味着没有其他表现良好的相似性度量。特别想到的是 Jaro-Winkler 乐谱,它可以很容易地在这个管道中实现。请注意,Jaro 相似性输出的结果与 Levenshtein 距离的解释不同。你可以在这里找到关于其他模糊字符串匹配的文档,比如 Levenshtein 距离。
你可以在我为这个项目创建的 Jupyter 笔记本中完成这个管道。你可以在我的 GitHub 页面这里找到这个笔记本。
资源
- [1]https://en.wikipedia.org/wiki/Levenshtein_distance
- [2]https://en.wikipedia.org/wiki/Lexical_similarity
- https://pypi.org/project/python-Levenshtein/
如果你喜欢这篇文章,这里还有一些你可能也会喜欢的:
[## 贝叶斯 A/B 测试解释
towardsdatascience.com](/bayesian-a-b-testing-explained-344a6df88c1a)
用 Jaro-Winkler 和 PageRank 实现 Python 中的文本摘要
用 Jaro-Winkler 和 PageRank 构建一个文本摘要器
目录
- 文本摘要介绍
- 文本摘要的难点
- 架构概述
- 问题陈述
-安装要求
-数据 - 实现
-加载文本
-清理文本
-创建网络
-生成摘要 - 结束语
- 资源
文本摘要介绍
在现代社会中,由于需要以快速的格式摄取信息,文本摘要是许多人日常使用的基本工具。像 Blinkist 这样的知名初创公司提供大量书籍的简短摘要。这为他们的用户节省了几个小时甚至几天的阅读时间。许多其他公司也使用他们专有的文本摘要软件来节省用户的时间。其他形式的总结(尽管是在不同的媒体上)以体育赛事的精彩片段或电影摘要的形式出现。
有两种主要的文本摘要方法,即抽取的和抽象的。抽取解决方案需要从文本主体中选择特定的句子来生成最终的摘要。抽取解决方案的一般方法是根据句子在正文中的重要性对句子进行排序,并将最重要的句子返回给用户。然而,文本摘要的抽象解决方案包括创建新的句子来捕捉原始文本背后的上下文和含义。尽管这是人类处理文本摘要的方式,但是归纳并教给机器却是一件非常困难的事情。文本压缩技术通常用于解决文本摘要中的抽象方法[4]。
在这篇文章中,我将向你展示如何使用提取方法构建一个算法文本摘要器。我将依靠两个主要算法,首先,Jaro-Winkler 距离来测量一对句子之间的距离。最后,网页排名算法,它将根据句子在网络中的影响力对句子进行排名。
文本摘要的难点
解决摘要问题是相当棘手的。有很多注意事项,很难归纳出一个适用于任何文本的解决方案。在文本摘要中存在各种因素,这些因素改变了摘要可能对原始故事的影响。我在下面列出了几个组件,它们使得摘要在 NLP 中成为一项非常困难的任务:
- 摘要必须包含的理想句子数量是多少?一个太大的数字可能没有用,因为你实际上是在阅读整个文本。太小的数字可能会在摘要中产生很大的后果,跳过重要的细节和情节主线。摘要越短,它能容纳的信息就越少。
- 你如何在总结中给出上下文?当提供故事中次要情节的概要时,上下文是最重要的部分。这使得摘要有用,在摘要中保持上下文是一项非常困难的任务。这个问题在抽取式解决方案中比抽象式更突出。
架构概述
我提议的提取解决方案将具有以下架构:
本文提出的摘要架构。图片由作者提供。
这将是一个 6 步解决方案:
- 获取输入文本
- 清除输入文本中的某些标点符号、停用词等。
- 生成句子相似度邻接矩阵
- 创建句子网络(节点是句子,边保存一对句子的相似性)
- 使用页面排名或其他排名度量来对网络中的节点进行排名
- 基于排名前 N 位的节点(句子)生成摘要。
问题陈述
给定一个文本主体,我们将创建一个管道,该管道将生成输入文本主体的摘要。对于上面概述的解决这个问题的方法,这个管道需要以下 python 模块和版本。
安装要求
Python=3.8.8
jaro-winkler=2.0.1
networkx=2.5
nltk=3.6.1
numpy=1.20.1
通过下面的命令!pip install jaro-winkler
来安装 Jaro 包,或者你可以在这里参考安装文档。
数据
我将本教程设置为任何文本都可以输入到管道中。用我选择的文本继续这个教程,或者用你自己的。下面是一组你可以通过 NLTK 图书馆和 Gutenberg 项目轻松下载的书籍。所有这些书都可以免费使用,因为它们是公共领域的一部分。
出于本教程的目的,我将使用莎士比亚关于朱利叶斯·凯撒的戏剧。请注意,威廉·莎士比亚写的这篇文章和所有其他文章都在公共领域,因为这些文章是在任何版权限制[2]存在之前创作的。
履行
加载文本
下面是 book 变量的输出示例:
我们从中导入的图书的子集。图片由作者提供。
干净的文本
在本节中,我们将清理刚刚导入的文本。为此,我们主要是要删除停用词和某些标点符号,以便管道中的后续程序在计算时更加高效和准确。
清理完正文后,我们只剩下1289
个句子来创建一个网络。
创建网络
在这一节中,我们将通过不同句子的相似性创建一个邻接矩阵。句子的相似度将使用 Jaro-Winkler 距离【3】来计算。该距离测量的输出将是介于值 0 和 1 之间的浮点数。这个数字越接近 1,表示这一对句子越相似。数字越接近 0,表示这对句子越不相似。
这个邻接矩阵将允许我们创建一个加权网络(通过 NetworkX)。请记住你输入文本的大小,因为相似度矩阵需要为每对句子分配一个分数,如果你的文本非常大(> 2000 个句子),这对你的计算机来说将是一个漫长而疲惫的过程。
在创建的网络中,节点将是与书中的句子相关联的索引,并且连接句子的边将基于一对句子的相似性来加权。然后,我们可以在该加权网络上运行页面排名算法,以识别具有与其相关联的大排名的节点。
在非常高的层面上,页面排名算法背后的直觉是通过使用随机行走来识别高度流行的节点。这是一个非常流行的基于网络的算法 Larry Page,它曾被 Google 用来在其搜索引擎结果中对网页进行排名。在我们示例的上下文中,页面排名会告诉我们网络中极具影响力的句子。然后,我们可以将前 N 个最有影响力的句子连接在一起,并以原文摘要的形式返回给用户。请注意,有许多方法可以对节点进行排序,尽管我建议使用页面排序,但像特征向量中心性、度中心性、介数中心性等排序方法也适用于此管道。
给定1289
个句子,用~2 minutes
创建相似度矩阵。网络的创建和网页排名分数的计算几乎是瞬间完成的。以下是所创建网络的摘要:
句子图表统计。图片由作者提供。
内置的 page rank 函数将输出一个字典,其中的键是节点(在我们的例子中是句子索引),值是该节点的相关页面排名分数。
页面排名计算输出。键是节点,值是与该节点相关联的页面排名分数。图片由作者提供。
请记住,我们希望将句子索引映射回原始句子,而不是用于创建网络的干净句子。这样,当包含停用词、标点符号等时,生成的摘要将更容易理解。
生成摘要
既然我们已经根据句子的页面排名分数对句子进行了排名,那么我们可以根据用户输入的他们希望包含在摘要中的句子数量来生成一个摘要。
出于本文的目的,我选择了 25 个句子来总结本文。这是相关的输出:
莎士比亚的《尤利乌斯·凯撒》用 25 句话总结。图片由作者提供。
结束语
摘要的结果因文本而异,对于给定的任务,某些文本的正文可能比其他的更好。总的来说,对朱利叶斯·凯撒的总结还算不错。它勾勒了布鲁图斯(凯撒的朋友)试图暗杀凯撒的主要情节线。
你可以在我的 GitHub 这里找到与这个管道实现相关的 Jupyter 笔记本。
资源
- [1]https://en.wikipedia.org/wiki/PageRank
- [2]https://en.wikipedia.org/wiki/Public_domain
- [3]https://en.wikipedia.org/wiki/Jaro%E2%80%93Winkler_distance
- https://arxiv.org/pdf/1707.02268.pdf
如果你喜欢这篇文章,你可能也会喜欢。
https://pub.towardsai.net/dynamic-time-warping-explained-fbb24c1e079b [## 贝叶斯 A/B 测试解释
towardsdatascience.com](/bayesian-a-b-testing-explained-344a6df88c1a)
基于 GPT2 和人工智能层的文本摘要
原文:https://towardsdatascience.com/text-summarization-with-gpt2-and-layer-ai-599625085d8e
使用拥抱的人脸变形库和人工智能层微调 GPT2 进行文本摘要
照片由 Aaron Burden 在 Unsplash 上拍摄
变形金刚在 2017 年的著名文章中首次亮相后,很快成为 NLP 中最受欢迎的型号。以非顺序方式(与 RNNs 相反)分析文本的能力使得大型模型能够被训练。事实证明,注意力机制的引入对于概括文本具有极大的价值。
在深度学习出现之前,以前的 NLP 方法更多的是基于规则的,更简单的(纯统计)机器学习算法被教会在文本中查找单词和短语,当发现这些短语时,会创建特定的回复。
该研究发表后,涌现出无数流行的变形金刚,其中最著名的是GPT(GgenerativePre-trainedTtransformer)。 OpenAI ,人工智能研究的先驱之一,创造并训练了 GPT 模型。 GPT-3 是最新版本,有 1750 亿个参数。因为这个模型非常复杂,OpenAI 决定不开源它。人们可以在完成漫长的注册过程后通过 API 使用它。
在这篇文章中,我将用一些技术背景来介绍变压器。然后,我们将使用 Layer 来获取预训练版本的 GPT2,以对其进行微调,用于总结目的。我们将使用的数据集由亚马逊评论组成,可以通过以下链接在 Kaggle 中找到:
https://www.kaggle.com/code/currie32/summarizing-text-with-amazon-reviews/notebook
概观
- 变形金刚(电影名)
- 亚马逊评论数据集
- 微调 GPT2
- 评估我们的微调模型
- 结论
我在本文中包含了最有启发性的代码。这个项目的完整代码库和数据集可以在我的公共 Colab 笔记本或 Github Repo 中找到。
https://github.com/aymanehachcham/GPT2_Text_Summarization https://colab.research.google.com/drive/1iDhg8ss-BW0ZpzL-umJhd9XAm7xUlz-g?usp=sharing#scrollTo=rinybKnGJLpY
快速参观变形金刚图书馆
基于注意力的模型
机器学习中的注意力机制是基于我们自己的大脑皮层如何工作的。当我们检查一张图片来描述它时,我们自然会将注意力集中在几个我们知道保存着关键信息的关键地方。我们不会以相同的强度检查图像的每个细节。在处理要分析的复杂数据时,这种方法有助于节省处理资源。
类似地,当口译员将材料从源语言翻译成目标语言时,他们根据以前的经验知道源句子中的哪些单词对应于翻译短语中的哪些术语。
照片由纳迪·博罗迪纳在 Unsplash 上拍摄
GPT2
GPT 语言模型最初是在 2018 年由 Alec、Jeffrey Wu、Rewon Child、David Luan 在论文“ 中介绍的,语言模型是无监督的多任务学习器,其目标是开发一个可以从先前产生的文本中学习的系统。它将能够以这种方式为完成一个短语提供多种选择,节省时间,并增加文本的多样性和语言深度。这一切都完成了,没有任何语法错误。
GPT2 架构的主要层是关注层。在不深究其技术细节的情况下,我想列出它的核心特性:
GPT2 使用字节对编码在其词汇表中创建令牌。这意味着标记通常是单词的一部分。
GPT-2 以因果语言建模(CLM)为目标进行训练,因此能够预测序列中的下一个单词。GPT-2 可以利用这种能力创建语法连贯的文本。
GPT-2 生成合成文本样本,以响应用任意输入启动的模型。这个模型就像变色龙一样——它适应条件文本的风格和内容。
亚马逊评论数据集
Kaggle 中呈现的数据集的目标是开发一种算法,可以为亚马逊美食评估提供有意义的摘要。这个数据集在 Kaggle 上提供,有超过 500,000 条评论。
当顾客在亚马逊上写评论时,他们会创建一个文本评论和一个标题。综述的标题用作数据集中的摘要。
样品:我买过几款活力狗粮罐头,发现质量都不错。这种产品看起来更像炖肉,而不是加工过的肉,而且闻起来更香。我的拉布拉多很挑剔,她比大多数人更喜欢这个产品。**
总结:优质狗粮**
上传到图层的数据集中的样本
数据集中有大约 71K 个实例,这足以训练一个 GPT-2 模型。
在开始处理阶段之前,我们需要建立与层的连接。我们需要登录并初始化一个项目:
然后,我们可以访问图层控制台,初始化我们的项目,并准备好记录我们将使用的数据集和模型。
从层控制台捕获
让我们将数据保存到层:
首先,我们通过将 Github repo 克隆到 Colab 中来安装它:
我们现在可以这样从层中获取数据:
执行一些数据处理
GPT 2 号的多任务处理能力是它最吸引人的特点之一。同时,同一个模型可能在许多任务上被训练。但是,我们必须使用组织文件中概述的相关任务指示器。
TL;博士符号,代表“太冗长;没读过”是总结工作的理想指示词。
TL;DR 符号可以用作填充元素,以缩短评审文本,并向模型指示重要内容到此为止。
我们还需要获得句子输入长度的平均值:
在我们的例子中,平均长度总计为每句话 73 个单词。我们可以推断,最大长度 100 将涵盖大多数情况,因为单词的平均实例长度是 73。
用于处理数据样本的代码可能变得复杂且难以维护;为了更好的可读性和模块化,我们希望数据集代码与模型训练代码分离。因此,我们可以使用 PyTorch Dataset 类作为包装器,它将充当一个紧凑的模块,将文本评论转换为准备用于训练的张量。
导入模型后,我们初始化数据集和数据加载器组件,为训练阶段做准备。我们可以从层调用我们的记号赋予器:
微调 GPT2
训练过程很简单,因为 GPT2 能够完成多项任务,包括总结、生成和翻译。对于摘要,我们只需要包含数据集的标签作为输入。训练部分包括构建 GPT2 模型并上传到层。
培训将完全在层中执行,我们将使用 f-gpu-small fabric ,这是一个具有 48 GB 内存的小型 gpu。我们首先从训练循环开始:
然后我们用需要的参数建立模型。我们将它上传到层:
然后,我们调用“layer.run”函数在层中运行训练:
训练开始了。这可能需要很长时间,具体取决于纪元和可用的资源。
评估我们的微调模型
一旦您微调了我们的模型,我们现在就可以开始按照各自的方法处理评论:
- 步骤 1 :首先对模型进行评审。
- 第二步:然后从所有我们有 top-k 选项的评论中,选择一个。
- 第三步:选择被添加到概要中,当前序列被输入到模型中。
- 步骤 4 :应重复步骤 2 和 3,直到达到 max_length 或产生 EOS 令牌。
从模型的所有生成预测中选择前 k 个预测:
然后我们定义我们的推理方法:
我们现在可以用 3 个示例审查来测试上面的代码,并查看生成的摘要。
首先,我们调用来自层的训练模型:
我们从测试数据中抽取一些样本:
最终结果:
点评 1
文字点评:“爱这些芯片。味道很好,非常脆,非常容易清理整个 3 盎司。一口气搞定。没有油腻的余味。原味和烧烤口味是我的最爱,但我还没有尝过所有的口味。伟大的产品。**
相关摘要 : {' 非常好吃!,'喜欢这些薯片!','我最喜欢的水壶芯片 '}
回顾 2
文字回顾:“我们已经很多年没有咸菜了,因为不需要的成分。这个牌子很好吃,不含有害成分。这种情况下也比当地超市便宜很多
关联摘要 : {' 好吃','好吃','好棒的产品!'}
文字评论:“这是这一品种的爱好者的最佳英式早餐茶,我试过很多种,包括从英国进口的。经过 20 年的寻找,我找到了最美味的茶的一个非常合理的价格。**
关联摘要 : {' 妙茶','爱喝茶的人最好的茶','爱喝茶的人最好的茶 '}
总结想法
考虑到我们所做的大量训练,我们目前所取得的成绩已经相当不错了。Layer 简化了导入模型和记号化器的整个过程。记录所有模型工件和数据集的选项也非常有用,因为您可以实时跟踪工作的效果。还有可能分享你的项目,在团队中协作,所以绝对值得。
所有代码都托管在上面提到的 Google Colab 中,请随时查看并自行尝试。
使用 NLP 的文本摘要:TextRank vs Seq2Seq vs BART
原文:https://towardsdatascience.com/text-summarization-with-nlp-textrank-vs-seq2seq-vs-bart-474943efeb09
作者图片
使用 Python、Gensim、Tensorflow、Transformers 进行自然语言处理
摘要
在这篇文章中,我将使用 NLP 和 Python 解释 3 种不同的文本摘要策略:老式的 TextRank (带有 gensim )、著名的 Seq2Seq ( 带有 tensorflow )和尖端的 BART (带有 transformers )。
作者图片
【NLP(自然语言处理) 是人工智能领域,研究计算机与人类语言之间的交互,特别是如何给计算机编程以处理和分析大量自然语言数据。最困难的 NLP 任务是输出不是单个标签或值(如分类和回归),而是一个全新的文本(如翻译、摘要和对话)。
文本摘要是在不改变文档含义的情况下,减少文档的句子和单词数量的问题。从原始文本数据中提取信息并将其用于摘要模型有不同的技术,总体来说,它们可以分为提取型和抽象型。提取方法选择文本中最重要的句子(不一定理解意思),因此结果摘要只是全文的子集。相反,抽象模型使用高级 NLP(即单词嵌入)来理解文本的语义,并生成有意义的摘要。因此,抽象技术很难从头开始训练,因为它们需要大量的参数和数据。
本教程比较了老派的方法 TextRank (提取)、流行的编码器-解码器神经网络 Seq2Seq (抽象)和最先进的基于注意力的变形金刚(抽象),它们已经彻底改变了 NLP 领域。
我将展示一些有用的 Python 代码,这些代码可以很容易地应用于其他类似的情况(只需复制、粘贴、运行),并通过注释遍历每一行代码,以便您可以复制这个示例(下面是完整代码的链接)。
我将使用“CNN Daily Mail”数据集,其中为您提供了 CNN 和《每日邮报》记者用英语撰写的数千篇新闻文章,以及每篇文章的摘要(以下链接)。
**https://huggingface.co/datasets/cnn_dailymail
特别是,我将经历:
- 设置:导入包,读取数据,预处理。
- 用 gensim 拟合 TextRank 以构建基线,并使用 ROUGE 指标和数据可视化评估结果。
- 用 tensorflow/keras 拟合 Seq2Seq 来训练深度学习模型。
- 通过 HuggingFace 使用预训练的 BART 和变形金刚库。**
设置
首先,我需要导入以下库:
**## for data** import **datasets** #(1.13.3)import **pandas** aspd #(0.25.1)
import **numpy** #(1.16.4)**## for plotting**
import **matplotlib**.pyplot as plt #(3.1.2)
import **seaborn** as sns #(0.9.0)**## for preprocessing**
import **re**
import **nltk** #(3.4.5)
import **contractions** #(0.0.18)**## for textrank**
import **gensim** #(3.8.1)**## for evaluation** import **rouge ** #(1.0.0)
import **difflib****## for seq2seq**
from **tensorflow**.keras import callbacks, models, layers, preprocessing as kprocessing #(2.6.0)**## for bart**
import **transformers** #(3.0.1)
然后我通过 HuggingFace 使用专用库加载数据集:
**## load the full dataset of 300k articles** dataset = **datasets**.load_dataset("cnn_dailymail", '3.0.0')
lst_dics = [dic for dic in dataset["train"]]**## keep the first N articles if you want to keep it lite**
dtf = **pd**.DataFrame(lst_dics).rename(columns={"article":"text",
"highlights":"y"})[["text","y"]].head(20000)
dtf.head()
作者图片
让我们看一个随机的例子:
i = 1
print("--- Full text ---")
print(dtf["text"][i])
print("--- Summary ---")
print(dtf["y"][i])
来自 CNN 每日邮件数据集的文本
在这里,我用红色手动标记了摘要中提到的信息。体育文章对机器来说很难,因为没有太多的空间来解释什么是重要的,什么是不重要的…标题必须报道主要结果。我将把这个例子放在测试集中来比较模型。
dtf_train = dtf.iloc[i+1:]
dtf_test = dtf.iloc[:i+1]
文本排名
text rank(2004)是一个基于图的文本处理排名模型,基于 Google 的 PageRank 算法,在一个文本中寻找最相关的句子。 PageRank 是 1998 年 Google 搜索引擎使用的第一个对网页进行排序的算法。简而言之,如果页面 A 链接到页面 B,页面 C,页面 B 链接到页面 C,排序将是页面 C,页面 B,页面 A。
作者图片
TextRank 非常容易使用,因为它是无人监管的。首先,整个文本被分割成句子,然后该算法建立一个图,其中句子是节点,重叠的单词是链接。最后, PageRank 确定这个句子网络中最重要的节点。
使用 gensim 库,您可以轻松地将 TextRank 算法应用于您的数据:
**'''
Summarizes corpus with TextRank.
:parameter
:param corpus: str or list - dtf["text"]
:param ratio: length of the summary (ex. 20% of the text)
:return
list of summaries
'''**
def **textrank**(corpus, ratio=0.2):
if type(corpus) is str:
corpus = [corpus]
lst_summaries = [**gensim**.summarization.summarize(txt,
ratio=ratio) for txt in corpus]
return lst_summaries **## Apply the function to corpus**
predicted = **textrank**(corpus=dtf_test["text"], ratio=0.2)
predicted[i]
作者图片
如何才能评价这个结果呢?通常,我用两种方式来做:
- ROUGE metrics(面向回忆的 Gisting 评估替角):
通过重叠 n-grams 将自动生成的摘要与参考摘要进行比较的一组度量。****
****'''
Calculate ROUGE score.
:parameter
:param y_test: string or list
:param predicted: string or list
'''**
def **evaluate_summary**(y_test, predicted):
rouge_score = **rouge**.Rouge()
scores = rouge_score.get_scores(y_test, predicted, avg=True)
score_1 = round(scores['rouge-1']['f'], 2)
score_2 = round(scores['rouge-2']['f'], 2)
score_L = round(scores['rouge-l']['f'], 2)
print("rouge1:", score_1, "| rouge2:", score_2, "| rougeL:",
score_2, "--> avg rouge:", round(np.mean(
[score_1,score_2,score_L]), 2))**## Apply the function to predicted** i = 5
**evaluate_summary**(dtf_test["y"][i], predicted[i])**
作者图片
结果显示,31%的 unigrams (ROUGE-1)和 7%的 bigrams (ROUGE-2)出现在两个摘要中,而最长公共子序列 (ROUGE-L)匹配了 7%。总的来说,平均分 20%。请注意,胭脂分数并不衡量总结的流畅程度,因为我通常使用善良的老人类的眼睛。**
2.可视化:显示两个文本,即摘要和原文,或预测摘要和真实摘要,并突出显示匹配部分。
我想你会发现这个功能非常有用,因为它可以在笔记本上突出显示两个文本的匹配子字符串。它可以用于单词级:
**match = **display_string_matching**(dtf_test["y"][i], predicted[i], both=True, **sentences=False**, titles=["Real Summary", "Predicted Summary"])from **IPython.core.display** import display, HTML
display(HTML(match))**
作者图片
或者您可以设置 sentences=True ,它将在句子级别而不是单词级别匹配文本:
**match = **display_string_matching**(dtf_test["text"][i], predicted[i], both=True, **sentences=True**, titles=["Full Text", "Predicted Summary"])
from **IPython.core.display** import display, HTML
display(HTML(match))**
作者图片
该预测具有原始摘要中提到的大部分信息。正如提取算法所预期的,预测的摘要完全包含在文本中:该模型认为这 3 个句子是最重要的。我们可以将此作为下面抽象方法的基线。
Seq2Seq
序列对序列模型 (2014)是以特定领域(即文本词汇)的序列为输入,输出另一领域(即摘要词汇)的新序列的神经网络。 Seq2Seq 车型通常具有以下关键特征:
- 序列作为语料库:将文本填充成长度相同的序列,得到特征矩阵。
- 单词嵌入 机制:特征学习技术,将词汇表中的单词映射到实数向量,这些向量是根据每个单词出现在另一个单词之前或之后的概率分布计算的。
- 编码器-解码器结构:编码器处理输入序列,并返回其自身的内部状态,作为解码器的上下文,解码器在给定前一个字的情况下,预测目标序列的下一个字。
- 用于训练的模型和用于预测的模型:用于训练的模型不直接用于预测。事实上,我们将编码两个神经网络(都具有编码器-解码器结构),一个用于训练,另一个(称为“推理模型”)通过利用来自训练模型的一些层来生成预测。
让我们从一些数据分析开始,这是下一个特征工程所需要的。由于我们要将文本转换成单词序列,我们必须在这里做出两个决定:
- 正确的序列大小,因为我们的语料库有不同的长度
- 我们的模型必须记住多少单词,因为罕见的单词应该被排除在外
我将清理和分析数据来解决这两点。
****## create stopwords**
lst_stopwords = **nltk**.corpus.stopwords.words("english")
**## add words that are too frequent**
lst_stopwords = lst_stopwords + ["cnn","say","said","new"] **## cleaning function**
def **utils_preprocess_text**(txt, punkt=True, lower=True, slang=True, lst_stopwords=None, stemm=False, lemm=True):
**### separate sentences with '. '**
txt = re.sub(r'\.(?=[^ \W\d])', '. ', str(txt))
**### remove punctuations and characters**
txt = re.sub(r'[^\w\s]', '', txt) if punkt is True else txt
**### strip**
txt = " ".join([word.strip() for word in txt.split()])
**### lowercase**
txt = txt.lower() if lower is True else txt
** ### slang**
txt = contractions.fix(txt) if slang is True else txt
**### tokenize (convert from string to list)**
lst_txt = txt.split()
**### stemming (remove -ing, -ly, ...)**
if stemm is True:
ps = nltk.stem.porter.PorterStemmer()
lst_txt = [ps.stem(word) for word in lst_txt]
**### lemmatization (convert the word into root word)**
if lemm is True:
lem = nltk.stem.wordnet.WordNetLemmatizer()
lst_txt = [lem.lemmatize(word) for word in lst_txt]
**### remove Stopwords**
if lst_stopwords is not None:
lst_txt = [word for word in lst_txt if word not in
lst_stopwords]
**### back to string**
txt = " ".join(lst_txt)
return txt **## apply function to both text and summaries** dtf_train["**text_clean**"] = dtf_train["text"].apply(lambda x: **utils_preprocess_text**(x, punkt=True, lower=True, slang=True, lst_stopwords=lst_stopwords, stemm=False, lemm=True))dtf_train["**y_clean**"] = dtf_train["y"].apply(lambda x: **utils_preprocess_text**(x, punkt=True, lower=True, slang=True, lst_stopwords=lst_stopwords, stemm=False, lemm=True))**
现在我们可以通过统计单词来看看长度分布:
****## count**
dtf_train['**word_count**'] = dtf_train[column].apply(lambda x: len(**nltk**.word_tokenize(str(x))) )**## plot**
**sns**.distplot(dtf_train["**word_count**"], hist=True, kde=True, kde_kws={"shade":True})**
作者的图片(对 X 和 y 运行相同的代码)
**X_len = 400
y_len = 40**
我们来分析一下词频:
**lst_tokens = **nltk**.tokenize.word_tokenize(dtf_train["**text_clean**"].str.cat(sep=" "))
ngrams = [1]
**## calculate**
dtf_freq = pd.DataFrame()
for n in ngrams:
dic_words_freq = nltk.FreqDist(**nltk**.ngrams(lst_tokens, n))
dtf_n = pd.DataFrame(dic_words_freq.most_common(), columns=
["word","freq"])
dtf_n["ngrams"] = n
dtf_freq = dtf_freq.append(dtf_n)
dtf_freq["word"] = dtf_freq["word"].apply(lambda x: "
".join(string for string in x) )
dtf_freq_X= dtf_freq.sort_values(["ngrams","freq"], ascending=
[True,False])
**## plot**
**sns**.barplot(x="freq", y="word", hue="ngrams", dodge=False,
data=dtf_freq.groupby('ngrams')["ngrams","freq","word"].head(30))
plt.show()**
作者的图片(对 X 和 y 运行相同的代码)
**thres = 5 **#<-- min frequency**
X_top_words = len(dtf_freq_X[dtf_freq_X["freq"]>thres])
y_top_words = len(dtf_freq_y[dtf_freq_y["freq"]>thres])**
之后,我们就有了继续进行特征工程所需的一切。通过使用 tensorflow/keras 将预处理的语料库转换成序列列表来创建特征矩阵:
**lst_corpus = dtf_train["text_clean"]**## tokenize text**
tokenizer = kprocessing.text.**Tokenizer**(num_words=**X_top_words**, lower=False, split=' ', oov_token=None,
filters='!"#$%&()*+,-./:;<=>?@[\\]^_`{|}~\t\n')
tokenizer.fit_on_texts(lst_corpus)
dic_vocabulary = {"<PAD>":0}
dic_vocabulary.update(tokenizer.word_index)**## create sequence**
lst_text2seq= tokenizer.texts_to_sequences(lst_corpus)**## padding sequence**
X_train = kprocessing.sequence.**pad_sequences**(lst_text2seq,
maxlen=15, padding="post", truncating="post")**
特征矩阵 X_train 的形状为 N 个文档 X 个序列最大长度。让我们想象一下:
****sns**.heatmap(X_train==0, vmin=0, vmax=1, cbar=False)
plt.show()**
作者图片( N 个文档 x 个序列最大长度)
在继续之前,不要忘记使用 fitted tokenizer 对测试集进行同样的特征工程:
****## text to sequence with the fitted tokenizer**
lst_text2seq = **tokenizer**.texts_to_sequences(dtf_test["**text_clean**"])**## padding sequence**
X_test = kprocessing.sequence.**pad_sequences**(lst_text2seq, maxlen=15,
padding="post", truncating="post")**
现在让我们来看看总结。在应用相同的特征工程策略之前,我们需要在每个摘要中添加两个特殊的标记来确定文本的开始和结束。
****# Add START and END tokens to the summaries (y)**
special_tokens = ("<START>", "<END>")
dtf_train["y_clean"] = dtf_train['y_clean'].apply(lambda x:
special_tokens[0]+' '+x+' '+special_tokens[1])
dtf_test["y_clean"] = dtf_test['y_clean'].apply(lambda x:
special_tokens[0]+' '+x+' '+special_tokens[1])**# check example**
dtf_test["y_clean"][i]**
作者图片
现在,我们可以通过利用与之前相同的代码来创建带有摘要的特征矩阵(因此,创建一个新的标记器、填充器,并用合适的标记器转换测试集)。如果你打印出词汇表,你会在顶部看到特殊的记号。稍后,我们将使用开始标记开始预测,当结束标记出现时,预测的文本将停止。****
作者图片
我们可以继续进行单词嵌入。这里有两个选择:从头开始训练我们的单词嵌入模型,或者使用预先训练好的模型。如果你走的是后者,那就按照这部分走,否则可以跳过,直接跳到模型设计。在 Python 中,你可以像这样从genism-data加载一个预先训练好的单词嵌入模型:**
***import **gensim_api**nlp = gensim_api.load(**"glove-wiki-gigaword-300"**)***
我推荐斯坦福大学的 GloVe ,这是一种在维基百科、Gigaword 和 Twitter 语料库上训练的无监督学习算法。您可以通过将任何单词转换为向量来测试它:
***word = "home"
nlp[word].shape**>>> (300,)*****
这些单词向量可以在神经网络中用作权重。为了做到这一点,我们需要创建一个嵌入矩阵,使得 id 为 N 的单词的向量位于第N行。
*****## start the matrix (length of vocabulary x vector size) with all 0s**
X_embeddings = np.zeros((len(X_dic_vocabulary)+1, 300))for word,idx in X_dic_vocabulary.items():
**## update the row with vector**
try:
X_embeddings[idx] = nlp[word]
**## if word not in model then skip and the row stays all 0s**
except:
pass***
该代码生成从语料库 x 向量大小中提取的词汇的形状长度的矩阵(300)。语料库矩阵将用于编码器嵌入层,而摘要矩阵将用于解码器嵌入层。输入序列中的每个 id 将被用作访问嵌入矩阵的索引。这个嵌入层的输出将是一个 2D 矩阵,对于输入序列中的每个单词 id 有一个单词向量(序列长度×向量大小)。让我们以句子“我喜欢这篇文章”为例:
作者图片
终于到了构建编码器-解码器模型的时候了。首先,我们需要清楚什么是正确的输入和输出:****
- 输入是 X (文本序列)加上 y (摘要序列),我们将隐藏摘要的最后一个单词
- 目标应该是没有开始标记的 y (概要序列)。
基本上,您将输入文本交给编码器以理解上下文,然后您向解码器展示摘要如何开始,模型学习预测它如何结束。这是一种称为“教师强制”的训练策略,它使用目标而不是网络生成的输出,以便它可以学习预测 start token 之后的单词,然后是下一个单词,依此类推(为此,您必须使用时间分布密集层)。
作者图片
我将提出两个不同版本的 Seq2Seq。下面是你能得到的最简单的算法:
- 一个嵌入层,它将从头开始创建一个单词嵌入,就像前面描述的那样。
- 一个单向 LSTM 层,返回一个序列以及单元格状态和隐藏状态。
- 最终的时间分布密集层,它将相同的密集层(相同的权重)应用于 LSTM 输出,每次一个时间步长,这样输出层只需要一个连接到每个 LSTM 单元。
***lstm_units = 250
embeddings_size = 300 **##------------ ENCODER (embedding + lstm) ------------------------##** x_in = layers.Input(name="x_in", shape=(X_train.shape[1],))**### embedding**
layer_x_emb = layers.Embedding(name="x_emb",
input_dim=len(X_dic_vocabulary),
output_dim=embeddings_size,
trainable=True)
x_emb = layer_x_emb(x_in)**### lstm**
layer_x_lstm = layers.LSTM(name="x_lstm", units=lstm_units,
dropout=0.4, return_sequences=True,
return_state=True)
x_out, state_h, state_c = layer_x_lstm(x_emb) **##------------ DECODER (embedding + lstm + dense) ----------------##** y_in = layers.Input(name="y_in", shape=(None,))**### embedding**
layer_y_emb = layers.Embedding(name="y_emb",
input_dim=len(y_dic_vocabulary),
output_dim=embeddings_size,
trainable=True)
y_emb = layer_y_emb(y_in)**### lstm**
layer_y_lstm = layers.LSTM(name="y_lstm", units=lstm_units,
dropout=0.4, return_sequences=True,
return_state=True)
y_out, _, _ = layer_y_lstm(y_emb, initial_state=[state_h, state_c])**### final dense layers**
layer_dense = layers.TimeDistributed(name="dense", layer=layers.Dense(units=len(y_dic_vocabulary), activation='softmax'))
y_out = layer_dense(y_out) **##---------------------------- COMPILE ---------------------------##**
model = models.Model(inputs=[x_in, y_in], outputs=y_out,
name="Seq2Seq")
model.compile(optimizer='rmsprop',
loss='sparse_categorical_crossentropy',
metrics=['accuracy'])
model.summary()***
作者图片
如果这对你来说还不够,下面是之前的 Seq2Seq 算法的一个高级(并且非常重)版本:
- 嵌入层,利用来自手套的预训练权重。
- 3 个双向 LSTM 层,在两个方向上处理序列。
- 最终时间分布密集层(同前)。
***lstm_units = 250 **##-------- ENCODER (pre-trained embeddings + 3 bi-lstm) ----------##**
x_in = layers.Input(name="x_in", shape=(X_train.shape[1],))**### embedding**
layer_x_emb = layers.Embedding(name="x_emb",
input_dim=X_embeddings.shape[0],
output_dim=X_embeddings.shape[1],
weights=[X_embeddings], trainable=False)
x_emb = layer_x_emb(x_in)**### bi-lstm 1**
layer_x_bilstm = layers.Bidirectional(layers.LSTM(units=lstm_units,
dropout=0.2, return_sequences=True,
return_state=True), name="x_lstm_1")
x_out, _, _, _, _ = layer_x_bilstm(x_emb)**### bi-lstm 2**
layer_x_bilstm = layers.Bidirectional(layers.LSTM(units=lstm_units,
dropout=0.2, return_sequences=True,
return_state=True), name="x_lstm_2")
x_out, _, _, _, _ = layer_x_bilstm(x_out)**### bi-lstm 3 (here final states are collected)**
layer_x_bilstm = layers.Bidirectional(layers.LSTM(units=lstm_units,
dropout=0.2, return_sequences=True,
return_state=True), name="x_lstm_3")
x_out, forward_h, forward_c, backward_h, backward_c = layer_x_bilstm(x_out)
state_h = layers.Concatenate()([forward_h, backward_h])
state_c = layers.Concatenate()([forward_c, backward_c]) **##------ DECODER (pre-trained embeddings + lstm + dense) ---------##**
y_in = layers.Input(name="y_in", shape=(None,))**### embedding**
layer_y_emb = layers.Embedding(name="y_emb",
input_dim=y_embeddings.shape[0],
output_dim=y_embeddings.shape[1],
weights=[y_embeddings], trainable=False)
y_emb = layer_y_emb(y_in)**### lstm**
layer_y_lstm = layers.LSTM(name="y_lstm", units=lstm_units*2, dropout=0.2, return_sequences=True, return_state=True)
y_out, _, _ = layer_y_lstm(y_emb, initial_state=[state_h, state_c])**### final dense layers**
layer_dense = layers.TimeDistributed(name="dense",
layer=layers.Dense(units=len(y_dic_vocabulary),
activation='softmax'))
y_out = layer_dense(y_out) **##---------------------- COMPILE ---------------------------------##** model = models.Model(inputs=[x_in, y_in], outputs=y_out,
name="Seq2Seq")
model.compile(optimizer='rmsprop',
loss='sparse_categorical_crossentropy',
metrics=['accuracy'])
model.summary()***
作者图片
在实际测试集上进行测试之前,我将保留一小部分训练集进行验证。
*****## train**
training = model.fit(x=[X_train, y_train[:,:-1]],
y=y_train.reshape(y_train.shape[0],
y_train.shape[1],
1)[:,1:],
batch_size=128,
epochs=100,
shuffle=True,
verbose=1,
validation_split=0.3,
callbacks=[callbacks.**EarlyStopping**(
monitor='val_loss',
mode='min', verbose=1, patience=2)]
)**## plot loss and accuracy**
metrics = [k for k in training.history.keys() if ("loss" not in k) and ("val" not in k)]
fig, ax = plt.subplots(nrows=1, ncols=2, sharey=True)ax[0].set(title="Training")
ax11 = ax[0].twinx()
ax[0].plot(training.history['loss'], color='black')
ax[0].set_xlabel('Epochs')
ax[0].set_ylabel('Loss', color='black')
for metric in metrics:
ax11.plot(training.history[metric], label=metric)
ax11.set_ylabel("Score", color='steelblue')
ax11.legend()ax[1].set(title="Validation")
ax22 = ax[1].twinx()
ax[1].plot(training.history['val_loss'], color='black')
ax[1].set_xlabel('Epochs')
ax[1].set_ylabel('Loss', color='black')
for metric in metrics:
ax22.plot(training.history['val_'+metric], label=metric)
ax22.set_ylabel("Score", color="steelblue")
plt.show()***
作者图片
请注意,我在回调中使用了 提前停止 工具,当受监控的指标(即验证损失)停止改善时,该工具应停止训练。这对节省自己的时间特别有用,尤其是像这样漫长而痛苦的训练。我想补充的是,在不利用 GPU 的情况下运行 Seq2Seq 算法是非常困难的,因为你同时在训练 2 个模型(编码器-解码器)。用有NVIDIA GPU或者 Google Colab 的电脑会更好。
即使训练完成了,也还没结束!为了测试 Seq2Seq 模型,作为最后一步,我们需要构建推理模型来生成预测。预测编码器将新序列( X_test )作为输入,并返回最后一个 LSTM 层的输出及其状态。****
*****# Prediction Encoder**
encoder_model = models.Model(inputs=x_in, outputs=[x_out, state_h, state_c], name="Prediction_Encoder")encoder_model.summary()***
作者图片
另一方面,预测解码器将开始标记、编码器的输出及其状态作为输入,并返回新的状态以及词汇表上的概率分布(概率最高的单词将是预测)。
*****# Prediction Decoder****## double the lstm units if you used bidirectional lstm** lstm_units = lstm_units*2 if any("Bidirectional" in str(layer) for layer in model.layers) else lstm_units**## states of the previous time step** encoder_out = layers.Input(shape=(X_train.shape[1], lstm_units))
state_h, state_c = layers.Input(shape=(lstm_units,)), layers.Input(shape=(lstm_units,))**## decoder embeddings**
y_emb2 = layer_y_emb(y_in)**## lstm to predict the next word**
y_out2, state_h2, state_c2 = layer_y_lstm(y_emb2, initial_state=[state_h, state_c])**## softmax to generate probability distribution over the vocabulary**
probs = layer_dense(y_out2)**## compile**
decoder_model = models.Model(inputs=[y_in, encoder_out, state_h, state_c], outputs=[probs, state_h2, state_c2], name="Prediction_Decoder")decoder_model.summary()***
作者图片
在利用开始令牌和编码器状态进行第一次预测之后,解码器使用生成的字和新状态来预测新字和新状态。该迭代将继续进行,直到模型最终预测到结束标记或者预测的摘要达到其最大长度。
作者图片
让我们对上述循环进行编码,以生成预测并测试 Seq2Seq 模型:
*****# Predict** max_seq_lenght = X_test.shape[1]
predicted = []
for x in X_test:
x = x.reshape(1,-1) **## encode X**
encoder_out, state_h, state_c = **encoder_model**.predict(x) **## prepare loop**
y_in = np.array([fitted_tokenizer.word_index[special_tokens[0]]])
predicted_text = ""
stop = False
while not stop: **## predict dictionary probability distribution**
probs, new_state_h, new_state_c = **decoder_model**.predict(
[y_in, encoder_out, state_h, state_c])
**## get predicted word**
voc_idx = np.argmax(probs[0,-1,:])
pred_word = fitted_tokenizer.index_word[voc_idx]
**## check stop**
if (pred_word != special_tokens[1]) and
(len(predicted_text.split()) < max_seq_lenght):
predicted_text = predicted_text +" "+ pred_word
else:
stop = True
** ## next**
y_in = np.array([voc_idx])
state_h, state_c = new_state_h, new_state_c predicted_text = predicted_text.replace(
special_tokens[0],"").strip()
predicted.append(predicted_text)***
作者图片
作者图片
该模型理解上下文和关键信息,但它对词汇的预测很差。这是因为我在这个实验的完整数据集的一个小子集上运行了 Seq2Seq " lite"。如果你有一个强大的机器,你可以添加更多的数据和提高性能。
变形金刚(电影名)
变形金刚是谷歌的论文 提出的一种新的建模技术【2017】在该论文中,展示了顺序模型(如 LSTM )可以完全被注意力机制取代,甚至获得更好的性能。这些语言模型可以通过同时处理序列和映射单词之间的依赖关系来执行任何 NLP 任务,而不管它们在文本中相距多远。因此,在他们的单词中嵌入同一个单词可以根据上下文有不同的向量。最著名的语言模型有 Google 的BERT和 OpenAI 的GPT,用数十亿个参数进行训练。****
脸书的 巴特 (双向自回归变换器)使用标准的 Seq2Seq 双向编码器(像伯特)和左右自回归解码器(像 GPT )。基本上,巴特 = 伯特 + GPT 。****
******'''
Summarizes corpus with Bart.
:parameter
:param corpus: list - dtf["text"]
:param max_len: length of the summary
:return
list of summaries
'''**
def **bart**(corpus, max_len):
nlp = **transformers**.pipeline("summarization")
lst_summaries = [nlp(txt,
max_length=max_len
)[0]["summary_text"].replace(" .", ".")
for txt in corpus]
return lst_summaries **## Apply the function to corpus** predicted = **bart**(corpus=dtf_test["text"], max_len=y_len)****
作者图片
作者图片
预测简短但有效。对于大多数 NLP 任务来说,Transformer 模型似乎是表现最好的。
结论
这篇文章是演示如何将不同的 NLP 模型应用到文本摘要用例的教程。我比较了 3 种流行的方法:无监督的 TextRank ,基于单词嵌入的两种不同版本的有监督的 Seq2Seq ,以及预训练的 BART 。我经历了特征工程,模型设计,评估和可视化。****
我希望你喜欢它!如有问题和反馈,或者只是分享您感兴趣的项目,请随时联系我。
👉我们来连线👈
本文是系列文章 NLP 与 Python 的一部分,参见:
****** ******
Texthero:熊猫数据帧的文本预处理、表示和可视化
用一行 Python 代码处理您的文本
作者使用 Midjourney 创建的图像
动机
在将文本用于 ML 模型或可视化之前,您可能希望通过以下方式清理文本:
- 用空格替换 NA 值
- 小写所有文本
- 移除数字
- 删除标点符号
- 删除停用词
- 删除空白
您可能需要一段时间来编写上述所有步骤来处理您的文本。这使得您分析数据和训练 ML 模型的速度变慢。
如果您能像下面这样用一行代码处理您的文本,那不是很好吗?
作者图片
这就是 Texthero 派上用场的时候。
什么是 Texthero?
Texthero 是一个 Python 库,允许你高效地处理熊猫数据帧中的文本数据。
要安装 Texthero,请键入:
pip install texthero
为了了解 Texthero 是如何工作的,让我们从一个简单的例子开始。
流程文本
假设您有一个数据框架,其中有一个杂乱的文本列,如下所示:
要清除这个文本,只需使用hero.clean
方法:
0 today beautiful day
1 ducks pond
2 cool
3 work
4
这真漂亮!在一行代码中,texthero:
- 用空格替换 NA 值
- 小写所有文本
- 删除所有数字块
- 删除所有标点符号
- 删除所有停用词
- 删除单词之间的所有空格
多酷啊。
创建自定义管道
如果您不喜欢hero.clean
管道中的默认处理方法,您可以创建一个自定义管道:
0 Today beautiful day
1 brackets fun
为您的文本创建表示
Texthero 还允许您轻松:
- 将每个文档映射到一个向量
- 减少向量的维数
让我们在研究文章数据集(可通过 Creative Common license 获得)上尝试这些功能。在取消旋转表格后,我们有以下数据帧:
从处理每篇论文的摘要开始:
为每个抽象创建一个 TF-IDF 表示,然后使用 PCA 进行降维:
查看 PCA 列:
作者图片
可视化文本
在降维步骤之后,我们可以开始使用散点图来可视化数据点:
作者图片
点击了解如何阅读这个情节。一般来说,两个文档越接近,它们就越相似。
为了减少噪音,我们可以取消选择右边栏中的一些主题。我们可以看到,与数学相关的文章和与统计相关的文章有明显的区别。
作者图片
结论
恭喜你!您刚刚学习了如何使用 Texthero 处理和可视化 pandas 数据框架中的文本数据。使用 Texthero,您可以在文本处理上花费更少的时间,而有更多的时间为您的数据寻找最佳模型。
随意发挥,并在这里叉这篇文章的源代码:
https://github.com/khuyentran1401/Data-science/tree/master/nlp/texthero
我喜欢写一些基本的数据科学概念,并尝试不同的数据科学工具。你可以通过 LinkedIn 和 Twitter 与我联系。
如果你想查看我写的所有文章的代码,请点击这里。在 Medium 上关注我,了解我的最新数据科学文章,例如:
参考
研究论文的主题建模。01–04–2017.布莱森·登西尔。
CC0:公共领域。于 2022 年 8 月 22 日从https://www . ka ggle . com/datasets/blessondesil 294/topic-modeling-for-research-articles中检索
你(绝对)不应该错过的 2022 年数据科学文章
新的一年即将来临,随之而来的是启动新项目的承诺,追求未开发的兴趣,以及做出大大小小的职业决定。这难道不令人兴奋吗?
不过,评估我们在 2022 年所取得的成就和学到的知识,可能会以自己的方式令人兴奋。如果你正在结束忙碌的一年,并有反思和见解要分享,我们在 Medium 的朋友最近邀请整个社区都这样做,所以我们希望你加入你的声音。
至于我们 TDS,我们最近花时间来庆祝我们不可思议的作者的工作。他们的技能和慷慨在这一年中激励和鼓舞了我们;为了表达我们的感谢,我们选择了一些最令人难忘的帖子(从我们 2022 年发表的 6500 多篇帖子中)。
假期是补读的好时机——即使你只能到处找几分钟空闲。我们强烈建议花些时间阅读这些优秀的文章。
- 说到平等代表权 这个领域还有很长的路要走。“当有人实践数据科学时,他们要么挑战要么加强现有的权力结构。”几个月过去了,我们仍在思考 Aisulu Omar 对数据科学中不平等现象的清晰批判——既包括数据团队的构成,也包括从业者使用的数据中边缘化群体的代表性不足。
- 在天气模式预测中发现美 。将气候、地球科学和机器学习结合在一起,我们非常欣赏 Fraser King 关于 DeepPrecip 的文章,这是一个深度卷积神经网络模型,他与人合作开发,用于预测极地和其他偏远地区的降雨量。
- 如何弥合线下和线上模特表演的差距 。一旦投入生产,你如何将模型的纸上潜力转化为成功? Samuel Flender 深入研究了影响机器学习模型的因素,并提供了实用的建议,以确保您的项目兑现其承诺。
- 充分利用你的技术写作之旅 。如果你 2023 年的目标之一是发表关于你的数据科学工作的文章,不要错过高作为一名作者对自己经历的反思。两年后(近 70 万次浏览),小旭分享了关于将好想法转化为人们会真正阅读的帖子的有益见解。
- 论包容性观点在机器学习中的重要性 。在一篇关于当前计算机视觉实践所涉及的风险的帖子中,莫尼卡·p .提出了从业者可以(也应该)问自己的一个最基本的问题:“除了增加训练数据,我们还如何确保我们生活中使用的算法是以道德和负责任的方式创建的?”
- 这到底是谁的作品?几个月来,生成式人工智能一直主导着科技新闻周期,人工智能生成的图像——来自稳定扩散、DALL E 2 和 Midjourney 等模型——一直是这些对话的中心。安娜·罗杰斯对这些工具带来的一系列复杂问题进行了权衡,尤其是围绕人类主导的概念,如创造力、独创性和影响力。
- 风靡全球的聊天机器人 。正如我们认为今年不可能再有一个以人工智能为中心的新闻周期,OpenAI 的 ChatGPT 在 2022 年的最后几周进入了舞台。正如 Alberto Romero 在他冷静的概述中所展示的,ChatGPT 只用了几天时间就主宰了科技话语;其成功的影响将在明年(及以后)继续显现。
- 教室里的 AI——从现在的学生角度 。人工智能的最新进展超越了聊天机器人和图像生成器。正如高中毕业班学生 Sanjay Adhikesaven、Abyan Das 和 Monish Muralicharan 所解释的那样,这项技术已经进入了教育系统,并且在未来的几年里一定会越来越多。那么,我们其他人有责任理解我们需要实现什么护栏,以便人工智能可以帮助年轻的学习者,而不会造成意想不到的伤害。
你可以在我们本月早些时候出版的 12 月版中找到我们剩下的年终建议。
我们想最后一次感谢你们在 2022 年对我们的支持。明年,我们一定会在数据科学、机器学习和人工智能领域看到令人兴奋的新闻和创新,我们将在这里提供关于这些主题的最佳论文、教程和解释者帖子。
变量将在下周短暂休息,所以我们将在新的一年再次见到你——为伟大的 2023 年干杯!
初级数据科学家最常犯的 3 个错误
意见
和一些高级数据科学家
来源:Shutterstock
因此,你要么刚刚开始攻读博士学位,要么在完成训练营后找到了第一份数据科学工作。首先恭喜你!但现在现实摆在面前,你必须拿出成果。当然,你已经完成了一些 Kaggle 竞赛,并且可能已经完成了几个可靠的项目,这些项目产生了有希望的结果。但是当您的模型被部署到生产中时会发生什么呢?现实世界中的事情会和你的模型预测的一样吗?
不,但没关系。你没有报名成为一名数据科学家,因为你认为这很容易!最好理解为什么会发生这种情况,这样当你进入新的角色时,你就能更好地准备。
您的模型在现实世界中表现不佳的两个最常见的原因是:
- 数据并没有整齐地预先打包,以解决您试图解决的特定问题。
- 当应用于实时数据时,错误的间接负面影响会加剧。
虽然第一项往往是新数据科学家的最大警钟,但它通常不是最大的问题。最令人泄气的是经历一丝不苟地连接和清理数据的严格过程,对测试结果获得一些信心,让机器学习工程师将你的模型部署到生产中,却只能看到它返回黯淡的结果。
为了最大限度地减少您遇到上述情况的可能性,我列出了一些最常见的错误,以便您可以避免它们!
数据泄露
如果你像大多数新数据科学家一样,你可能不确定这意味着什么。这是否意味着您清理数据的力度太大,以至于在此过程中丢失了太多数据?不打算撒谎;这是我第一次听到这个名词时的想法!那么,什么是数据泄露呢?
当您在训练模型之前无意中让模型了解了一些测试数据时,就会发生数据泄漏。这就像老师不小心把期末考试的问题发给了学生,而不是教学大纲:现在学生们知道了通过考试应该关注什么,但不一定会理解课程的细微差别。
这是怎么发生的?一种常见的方法是在将数据分成训练集和测试集之前对其进行预处理。在分割前对数据集应用标准化或规范化时,模型已经“知道”了最小和最大可能值以及近似的测试方差。如果您对总体中的分类变量进行编码,然后在 prod 中遇到一个新值,会发生什么呢?你的模型无法解释这些情况。这些只是发生这种错误的许多可能方式中的几种,并且它的表现形式会因场景而异。所以普遍的意识和头脑的预见是必不可少的。
通过尽快分割数据集,通常可以避免这些类型的错误。然后,将转换应用于测试数据,以继承培训中未涉及的相同参数。例如,不是在开始时标准化整个数据集,而是只标准化训练集。然后将平均值和方差作为变量来标准化测试集。您的准确性结果不会很强,但您的模型将更好地表示野外数据。
低估领域知识
这是你的第一个数据科学职位,你渴望给人留下深刻印象。我明白了。您可能犯的最严重的错误之一是,在您对数据和业务案例有了总体的直觉之前,就立即一头扎进数据并开始建模。缺乏领域知识通常会导致新数据科学家从相关性中推断因果关系。
我的第一个企业数据科学项目是支持一家大型电信公司的维修业务。他们最近为客户部署了新的调制解调器,将诊断性能指标发送回公司,以便他们能够充分监控服务质量。该公司想知道我们是否可以使用这些指标来预测调制解调器何时可能遇到影响客户的错误,这些错误可以通过自动调制解调器重启命令快速解决。有了这些知识,公司可以采取低成本的预防措施。进入我!
我之前的生活是在投行,对电信技术了解不多(除了上学的时候在苹果卖 iPhones)。现在我看着数百列对我来说没有多大意义的数据指标,但是我确实知道我的目标变量!没什么大不了的,我可以通过获取样本数据,用列平均值填充空值,并运行相关性分析来计算出哪些特征与目标具有最强的相关性,从而生成一些初始结果。不奇怪,这是潜伏期。
在我的第一次每周更新的初步发现中,我准备展示我发现了什么以及有什么反应?“嗯,咄。高延迟意味着调制解调器已经出现故障。如果我安排一个一小时的会议,和某人一起浏览数据,并解释哪些字段与任务相关,我就可以避免这种尴尬。
无论你作为一名数据科学家获得了多少经验,都要保持谦逊。在钻研数据之前,与比你更了解技术或商业案例的人交谈。是的,答案就在数据中,但是对于实用性的问题,仍然要靠人类来联系上下文并解释它。为正确的问题提供一个不完美的解决方案比为一个不存在的问题提供一个完美的解决方案要好。
不相称的反应
我明白了。你不希望你的厨房里有苍蝇。但是你真的需要在你的房子里搭帐篷吗,因为你在窗台上发现了一个?如果说苍蝇拍是线性回归,那么帐篷就是神经网络。
在项目的最后几个月里,你学习并为神经网络、它们的价值和各种复杂程度而苦恼。有人想再上一堂关于反向传播的课吗?!当然,你不希望这些知识被浪费掉,但现实是,如果问题非常复杂,需要神经网络来解决,它就不会分配给你。大多数涉及数据科学的商业问题都不需要神经网络。你将花费几个小时试图用神经网络解决一个问题,却发现你浪费了计算资源,并且只获得了略微更好的结果,但更有可能是比开箱即用的随机森林或 XGBoost 分类器更差的结果。
除非你试图为特斯拉获得一份研发工作,否则你很可能不会遇到许多(如果有的话)需要神经网络的问题。(CNN 在图像分类方面、RNN/LSTM 在语言处理方面以及其他一些方面有一些例外。但是这些通常是特定于领域的。)你最好专注于正确的基本原则,并逐步迭代以提高性能。
用更少的钱做更多的事情,当你拥有更多的时候,你会变得更好。
一般外卖
你才刚刚开始。保持谦逊。花时间去了解比你更资深的同行的领域知识。在学习更复杂的算法之前,花点时间把基础知识弄好。不要让你的模型偷窥测试数据。
借用我生活中音乐制作方面的一个类比:
一个大师不会修复一个糟糕的组合。好的混音不能修复糟糕的录音。好的录音并不能弥补糟糕的表现。
保持简单。保持专注。这就是你成功的方法!
成为高效数据分析师需要了解的 3 大数学支柱
这三个数学分支将支持您作为数据分析师的日常活动
你被告知你应该知道的数学量和你作为数据分析师每天使用的数学量是两码事。
依赖于领域(有时是项目),大多数数据分析师日常使用的数学知识只有很少的一部分。虽然大多数教育项目讨论所有数据分析师都应该知道的三大数学主题(线性代数、统计和微积分),但并非所有领域或职位都需要微积分或高级主题的深入知识。
虽然学习数学中更高级的主题(如微积分等)可以为您的武器库增加有价值的工具,并教会您如何解决问题,但这也可能是一个阻碍您成为数据分析师的症结。
因此,除非你的目标领域或职位需要先进的数学知识和培训,否则专注于能够满足大多数数据分析师职位 70%或更多日常要求的基本部分可能是有益的。幸运的是,如果你已经完成了几年的大学课程,或者在高中或中学学习了高等数学课程,你可能已经学习了本文中讨论的三个支柱。
1.线性代数
线性代数是致力于求解未知值的线性方程的数学分支,也是建立机器学习知识的基础。
虽然机器学习可能超出了一般数据分析师日常工作的范围,但线性代数的基本概念将在数据预处理和数据转换中使用。此外,线性代数教你通过一系列步骤进行逻辑思考,这在进行侧重于回答特定问题或解决特定问题的分析时是有益的。
线性代数中的概念包括向量和空间、矩阵变换、交替坐标系。向量可用于数据分析,计算数据集的预测与数据转换后的预期输出有多大差异。矩阵转换用于将一个矢量转换为另一个矢量,在数据转换过程中,该矢量允许数据在二维或三维空间中以几何方式表示。可在数据分析中使用替代坐标系来改变数据集的可视化表示方式,以确保数据得到恰当的表示。
学习线性代数的资源
https://www.khanacademy.org/math/linear-algebra
如何使用线性代数进行数据分析
2.可能性
概率是对某件事情发生的可能性的研究,对于在不确定的情况下得出有助于决策的结论至关重要。虽然概率和统计是联系在一起的,并且经常被放在一起研究,但这两者被用来确定不同的结论。
概率在所有领域都有许多实际用途,例如确定衰退发生的可能性,疾病与基因频率相关联的可能性,甚至网站访问者订阅其时事通讯的可能性。
有两种类型的概率可用于查看数据集。经典概率是一种概率类型,它涉及到一系列与之相关的规则。例如,您可以制定一条规则,规定客户从网站购物的概率必须大于 0.33 才有效。相对频率是一种概率类型,着眼于单一事件相对于所有可能结果的发生率。例如,这可用于将数据子集的结果与收集的数据总量进行比较。
学习概率的资源
如何使用概率进行数据分析
3.统计数字
统计学是围绕数据收集、分析、展示和解释的数学分支。统计学和概率是联系在一起的,经常一起教授,尽管它们对不同的问题会产生不同的答案。统计是数据分析的基础,为理解数据集告诉我们的东西提供了基础。
统计学可以分为两种类型:描述性的和推断性的。描述性统计描述了一个群体的特征,并且可以进一步细分为集中趋势的测量和可变性的测量,后者测量了一个群体的不同方面。例如,描述性统计可用于推断收集的一系列考试分数或注册网站时事通讯的人的平均年龄。推断统计学根据样本数据对总体进行预测。例如,假设检验,一种推理统计,可用于根据研究样本确定是否可接受或拒绝某个总体假设。
学习统计的资源
[## 15 分钟的大学水平的统计学入门课程
towardsdatascience.com](/an-undergraduate-level-introductory-statistics-course-in-15-minutes-51996bb7caf3)
如何使用统计学进行数据分析
最后的想法
关键要点:
- 作为数据分析师,您将每天使用的数学基础是线性代数、概率和统计。
- 概率和统计是数据分析的支柱,可以让你完成数据分析师 70%以上的日常工作(取决于职位和行业)。
- 成为一名数据分析师可能只知道这三个数学领域,但数学知识不应局限于确保数据分析师的持续相关性和进步。
虽然本文涵盖了支持大多数日常数据分析师工作的数学基础,但这并不是说您的数学学习应该就此停止。
数据分析师通过不断学习保持相关性,并在职业生涯中不断进步。这意味着扩展你的基础知识,深入更复杂的数学领域,如上所述,这会给你带来更多的工具,并微调你解决问题的技能。
数学是理解数据告诉我们什么的方式,并帮助我们得出结论,让我们做出决策。通过拓展你的知识,你可以从不同的角度看待数据集和结果,并以不同的方式解决问题。因此,在你的职业生涯中,不要停留在基础知识上,而是要不断建立你的数学工具箱。
订阅将我的故事直接发送到您的收件箱:故事订阅
成为会员,使用我的推荐链接可以无限制地访问媒体(我将收取少量佣金,不需要你额外付费):媒体会员
数据科学家的 3 t 测试
原文:https://towardsdatascience.com/the-3-t-tests-for-data-scientists-e24e4ef61
约翰·额外的照片在 Unsplash 上
t 检验是一种统计技术,它告诉人们两组之间的差异有多显著。简而言之,它通过将信号的量(通过样本或总体平均值之间的差异测量)与这些样本中的噪声量(或变化)进行比较来实现这一点。有许多关于数据科学的有用的 文章深入描述了它们,告诉你什么是 t-test 以及它如何工作,但是没有多少材料讨论 t-test 的不同变体以及何时使用它们。本文将介绍 t-test 的 3 种变体,何时使用它们,以及如何在 Python 中运行它们。
单一样本 t 检验
这是什么?
单样本 t 检验将样本数据的平均值与一个特定值进行比较。这方面的一个例子可能是,如果可口可乐公司希望确保装瓶厂在每罐饮料中倒入适量的苏打水。领导知道他们想要每罐 355 毫升,所以他们可以从罐中取样并测量倒入每个罐中的确切毫升数。由于机械过程不精确,一些罐可能超过 355 毫升,一些可能更少。然后,可以用罐的样本进行单样本 t 检验,以检验机器是否向每个罐中注入了统计上显著不同的量,而不是 355 ml 的液体。
作者图片
它是如何工作的?
- 陈述无效假设和替代假设。零假设(H0)是样本均值与特定值(总体均值)没有差异,而另一个假设(H1)是有差异。按照上面的例子,它们应该是这样的:
H0:平均每罐可乐有 355 毫升。H1:平均每罐可乐中含有超过 355 毫升的二氧化碳。
注意:由于我选择了一个方向(即“每罐超过 355 毫升”),这就变成了一个单边 t 检验,而不是一个双边 t 检验,其中一个只是说数量不是 355 毫升。
2.确定你的显著性水平:显著性水平,通常被称为 alpha (α),是当它实际上是真的时候拒绝你的零假设的概率。通常使用 0.05 的 alpha,这意味着您有 5%的风险得出样本之间存在统计显著差异的结论,而实际上这只是由于噪声。
3.收集以下数据:要检验的值(μ)、样本均值(x̄)、样本标准差(s)、样本观察值(n)并将它们放入以下公式中以计算 t 统计量:
作者图片
4.将您的 t 统计和自由度插入到 t 表中,以获得相应的 p 值。将 p 值与您选择的 alpha 值进行比较,如果它较小,您可以拒绝零假设。
请注意,要使这种测试有效,有 3 个必要的假设:
1)样本是独立的
2)数据近似正态分布
3)样本是随机收集的
代码示例
Scipy 的 stats 库有一个方便的 ttest_1samp 方法,当给定一个数据样本和一个总体均值进行比较时,该方法将计算 t-stat 和 p 值。下面的代码演示了如何使用函数为上面的示例运行单样本 t-test。
在这里,我创建了两个来自工厂 A 和工厂 B 的 30 罐假数据样本。对于工厂 A,数据的平均值为 355,并添加了噪声项,但对于工厂 B,数据的平均值为 353,并添加了噪声项。对两者进行单样本 t 检验,我们看到工厂 A 的 p 值为 0.71,工厂 B 的 p 值为 0.0004。工厂 A 的 p 值远高于标准 alpha 值 0.05,但工厂 B 的 p 值低于该阈值,因此我们可以拒绝零假设。
双样本 t 检验
这是什么?
双样本 t 检验不是将数据样本的平均值与单个值(总体平均值)进行比较,而是比较两个独立数据样本的平均值。同样的例子,如果可口可乐公司的领导层想要比较工厂 A 和工厂 b 之间罐装液体的平均量,就可以使用这个方法。
作者图片
它是如何工作的?
- 类似于单样本 t 检验,我们陈述零假设和备择假设。以两个工厂为例,它们是:
H0:两家工厂的平均灌装量没有显著差异
H1:两家工厂的平均灌装量有显著差异
注意:重要的是要记住零假设和替代假设总是关于总体,而不是从中抽取的样本
2.选择一个显著性水平(我们还是用 0.05)
3.计算两个样本的平均值(x̄)、标准偏差(s)和样本量(n ),并将其代入以下公式,以获得 t 统计量
作者图片
4.将 t 统计量和自由度插入到 t 表中,以获得相应的 p 值。将 p 值与所选α水平进行比较,如果它更小,则可以拒绝零假设。
像单样本 t-检验一样,该检验也必须满足一些假设:
1)两个样本独立
2)两个样本近似正态分布
3)两个样本具有近似相同的方差
代码示例
Scipy 的 ttest_ind 方法接受两个数据样本,并且与 ttest_1samp 类似,从测试中返回 t 统计量和相应的 p 值。下面的代码演示了如何使用函数来运行上面的用例示例。
由于该检验的 p 值为 0.0026,低于 0.05 的标准α值,因此无效假设被拒绝。
配对 t 检验
这是什么?
配对 t 检验比较同一实体的两个测量值,通常是在一段时间内。这方面的一个例子是,如果可口可乐公司想要测试装瓶培训计划的有效性,对于每个员工,他们可以比较他们参加培训前后的平均装瓶率。
它是如何工作的?
与一个和两个样本 t-检验相似,必须陈述无效假设和备选假设,选择显著性水平,计算 t-统计量,并将其与 t-表中的自由度一起使用,以获得 p 值。t 统计的公式也不同,如下所示,其中 d 是每个配对值的差值,n 是样本数。
作者图片
另一种思考这种测试的方式是,配对 t 检验本质上只是对每个配对样本的差异进行单样本 t 检验!在这种情况下,零假设是配对样本差异等于零。
代码示例
Scipy 的 ttest_rel 方法接受两个成对数据数组,并且与 ttest_1samp & ttest_ind 函数类似,返回 t 统计量和相应的 p 值。在下面的代码中,我首先定义了一个雇员装瓶率数组,每分钟随机装瓶量在 10 到 20 之间。然后,我用“应用培训”功能模拟了一次培训,该功能可以将生产率降低 1 瓶/分钟,或者提高到 4 瓶/分钟。与前面的两个例子类似,我将训练前后的生产率数组输入到 scipy 的 ttest_rel 函数中,并打印输出。
另外,我演示了配对 t 检验与配对差异的单样本 t 检验是如何相同的。在下面的代码片段中,我获取了 post_training 和 pre_training 数组之间的差异,并针对总体均值为 0 的差异运行了单样本 t 检验(因为零假设是样本之间没有差异)。正如所料,t 统计量和 p 值与配对 t 检验完全相同!
感谢阅读!要注册中等会员,看这里!
根据学习科学,成为数据科学专家的 4 个标准
成为专家需要的不仅仅是花 10,000 个小时练习数据科学
专家和我们这些普通人的区别是什么?
是因为他们花了 10,000 个小时练习他们选择的技能以达到精通吗?
还是他们已经走上了一条特定的学习道路,旨在把自己变成专家,甚至自己都不知道?
关于个人如何掌握技能或成为所在领域的“专家”,很多观点都围绕着长期以来被吹捧的 10000 小时法则,马尔科姆·格拉德威尔在他的书 离群者:成功的故事 中使这一法则变得流行起来。这本书分享了 K. Anders Ericsson 进行的研究,他发现世界级(有些人会说是“精英”)音乐家需要大约 10,000 小时的练习才能掌握他们的技艺。
然而,更新的研究正在深入研究该领域的专家正在做些什么来达到这种精通水平,在爱立信发现的 10,000 小时限制之内或之外。
成为数据科学等领域的专家不再是遵循格拉德威尔的福音。如果一个人以这种方式开始成为一名专家,将需要数年时间才能掌握这门学科。为了跟上当今快节奏的技术场景,未来和当前的数据科学家需要更机智地思考他们如何计划实现专家级别的知识。幸运的是,研究人员发现了数据科学家如何成为专家,这种方式在有效性和效率上都远远超过了 10,000 小时规则。
根据学习科学,一个人要成为所在领域的专家,必须遵循四个主要标准。这些要求适用于数据科学以及数据科学家如何成为专家。
成为数据科学专家的 4 个标准
1.重复的经历和尝试
大量的实践是数据科学家成为专家的基础。
国际象棋大师在试图成为大师之前要打数百场比赛,网球冠军在赢得锦标赛之前要打数百盘比赛。
这些重复的经验和尝试让专家们能够【chunk】他们对知识的回忆,这可以被阐述为将知识和模式收集到编码组中,然后可以在以后从记忆中检索。
国际象棋大师在目睹和经历了数百场比赛后,下意识地发展了这项技能。通过建立模式来记忆棋盘上棋子的位置,大师们能够根据记忆重建整场比赛。这种能力使他们在下棋时不必考虑他们的下一步是什么——相反,他们可以通过利用记忆中捕捉到的经验提前感觉到他们的下一步将是什么来下棋。
这种在多次经历和尝试后识别模式的能力应该是希望获得专家地位的数据科学家的目标。识别和重新创建模式的能力允许数据科学家快速建立解决给定问题的最佳方法。
不仅如此,识别和重新创建模式的能力使数据科学家能够通过剔除不准确的结果或得出的结论来更有效地分析数据,这些结果或结论超出了给定问题的可能性范围。
2.有效环境
在不断变化、不可预测的环境中,任何人都有可能成为专家吗?
例如,在轮盘赌桌上经历了数千次赌博后,一个赌徒会成为轮盘赌专家吗?他们可能有成千上万的经验来证明他们所下的赌注是正确的,但是基于过去的经验,他们能确定他们会赢吗?答案是否定的。轮盘赌是一种碰运气的游戏,这意味着在这种环境下,再多的经验也不会造就出一个轮盘赌专家。
要成为一名专家,数据科学家必须在一个包含规则的环境中实践他们的技能,这种规则使得模式可以被学习。
这意味着对可预测的或具体的主题进行分析。例如,对网站访问者保持率进行分析是一个可预测的环境,可能会产生具体的结果。网站访问者将拥有可预测的浏览模式和跳出率,这可以帮助数据科学家预测网站在什么时候会失去访问者。
相反,如果一个数据科学家被要求预测股票市场(看看你们中那些有投资组合项目的人,他们使用两行代码“完成”了这个项目),他们的分析只会包含预测的影子。由于经济的不可预测性,这个预测可能会也可能不会成功。
对数据科学家来说,分析不可预测的或随机的东西并不是成为专家的好方法,因为他们没有办法建立一种被证明有效的分析模式。
因此,数据科学家必须致力于分析可预测的事件,从而建立分析和理解事件的模式。例如,如果分析得出的结果超出正常可接受的范围,分析天体物理数据的数据科学家将能够检测到数据中的异常或奇怪现象。
3.及时反馈
诺贝尔经济学奖得主丹尼尔·卡内曼“以其在判断和决策心理学方面的工作而闻名”曾经在放射科医生和麻醉科医生之间做了一个比较,以及及时的反馈(也称为强化练习)如何帮助个人发展直觉专业知识。
根据 Kahneman 的说法,麻醉师与患者密切合作,无论他们做对或做错什么,都会得到即时反馈。由于他们每次麻醉病人都会得到大量的强化练习,麻醉师可以学习与他们工作相关的模式和规律。相反,试图诊断癌症的放射科医生无法发展直觉,因为直到数月后他们观察到的肿瘤转移或良性时,他们才得到反馈。这意味着由于缺乏即时反馈,放射科医生不一定能提高他们诊断的准确性。
用数据科学的术语来说,及时反馈会很快告诉你你正在做的事情是否有效。当你得到即时反馈时,你就能够每次都更准确地执行任务。
对于数据科学家来说,这一标准往往是最容易实现的,因为您的分析结果通常会在完成后几分钟内返回,或者在讨论您的结果的下一次董事会或部门会议上返回。一旦获得了这些结果,你的分析技能就可以变得更精细,这样你就可以在以后的每一次进行更准确的分析。
4.刻意练习
我们必须在舒适区之外练习来提高我们的技能。
在相对较短的时间内成为一名有能力的数据科学家是可能的。在某一点上,你可以自动进行分析,而不需要与你曾经发现具有挑战性的技能做太多的斗争。然而,你的技能不会在这一点上有很大提高,因为你的表现没有受到不利条件的考验,比如损坏的数据、困难的代码或不清楚的业务问题。
要成为一名专家数据科学家,你必须在你能力的边缘练习你已经拥有的技能。这包括刻意练习,有条不紊地练习你不擅长或超出你技能水平的技能。如果你不寻求进一步提高你的技能,只保持你轻松拥有的技能,你进行复杂分析或挑选重要结论的能力可能会随着时间的推移而下降。
例如,一名新的数据科学家可能比一名经验丰富的数据科学家能够更准确地解释分析结果或进行他们刚刚学会的测试,而这名数据科学家多年来一直在使用相同的技术分析相同的结果,却没有扩展他们的视野。
数据科学家的价值始终基于他们积极影响所在组织的能力。这种影响来自持续的自我教育,超越了他们的正规教育或沿途学到的证书。尝试新语言、进行不同类型的测试以及以不同方式回答业务问题等形式的刻意练习将帮助数据科学家成为专家。
关键要点
- 数据科学家必须在进行数据分析时进行重复的体验和尝试,以提高他们识别和再现模式的能力。这使得数据科学家能够更准确、更高效地进行分析。
- 在没有不规则或不一致的有效环境中实践数据科学有助于数据科学家建立一种分析模式,这种模式被证明适用于他们将要进行的大多数分析。
- 及时的反馈对于数据科学家提高技能至关重要,因为这有助于他们确定哪些是正确的,哪些是错误的。这有助于数据科学家建立每次更准确地进行分析的能力。
- 数据科学家必须在舒适区之外练习技能,以保持相关性和影响力,并确保他们的技能不会随着时间的推移而丧失。
订阅将我的故事直接发送到您的收件箱:故事订阅
请成为会员,使用我的推荐链接获得无限制的媒体访问权限(我将免费向您收取少量佣金):媒体会员
通过捐赠来支持我的写作,以资助更多像这样的故事的创作:捐赠
每个数据科学管道的 4 个步骤
原文:https://towardsdatascience.com/the-4-steps-for-every-data-science-pipeline-b426b91c4945
意见
大多数数据科学项目比你想象的更相似
Max Ostrozhinskiy 在Unsplash【1】上拍摄的照片。
目录
- 介绍
- 查询/数据
- 预处理
- 火车
- 部署
- 摘要
- 参考
介绍
本文的目的是介绍适用于每个数据科学项目的主要步骤。这个讨论不仅对初学的数据科学家有帮助,对产品经理、软件工程师,甚至高级数据科学家也有帮助,他们也可以从新的角度受益。虽然对于给定的用例,有无数的机器学习算法可供选择,但其他项目之间的共同点是获取数据、处理数据、训练算法,然后部署数据的主要部分。话虽如此,让我们通过一些清晰的例子来更深入地了解这些步骤。
查询/数据
照片由卡斯帕·卡米尔·鲁宾在Unsplash【2】上拍摄。
对于任何数据科学项目,您当然需要数据来启动。然而,数据可能没有我们想象的那么容易获得。有时,它是在学术环境中给你的,这样你就可以专注于学习算法、测试以及它们如何工作,所以这是可以理解的。但是,在专业环境中,在很大程度上,有人不会给你提供一个完美的数据集,而这正是我们一直努力追求的。
数据库表
根据您的使用情况,理想的数据集应该由易于阅读和理解的数据组成,并带有功能和目标变量。除了来自某人的直接 CSV 文件(在某些情况下是)之外,更好的场景是数据库中连接良好的表。对于某些项目,如果幸运的话,您的数据可以来自一个表,但是在大多数情况下,您将不得不执行带有连接的查询,由几个子查询组成,以创建一些模型特征。
外部来源
获取数据的下一个选择可能是从数据库或数据湖中尚不存在的外部来源获取数据。例如,您可以自己或在数据工程师的帮助下,通过访问 API 将新数据加载到表中。这个过程可能需要更长的时间,你可能需要向公司证明为什么你需要留出一点时间来收集这些数据,以便它是可查询和可访问的。(一些外部资源可能更简单,比如一个包含静态但重要的关键信息的 CSV 文件——字面意思是)。
无论您是从第一个选项开始,还是不得不求助于下一个选项,这两个选项最终都可以实现按特定时间表(例如每小时、每天、每周等)查询数据的自动化任务。
总而言之,以下是数据科学项目第一部分的一些步骤:
- 从数据库/数据湖等中查询数据。
- 如果没有,那么数据将需要从外部来源进入其中一个地方
- 一旦有了这些选项,您就可以创建一个自动化的任务,比如用 Python 来查询一个时间表
预处理
既然您已经将数据保存在一个地方,那么很可能可以在一个文件中对所有数据进行预处理。这一步已经在特征工程之后,更确切地说,是我正在讨论的生产中预处理的自动化过程。也就是说,您已经知道您希望模型中包含哪些特性。
但是,在您的查询数据位于 pandas dataframe 中之后,您可能仍然需要创建这些特性(例如,在 Python 中的,在 R* 中还有其他选项)。*
预处理的一些示例包括但不限于:
- 用数值特征的最小值、平均值、最大值填充 NA 值,或者用孤立的字符串填充 NA 值,如用于分类特征的“null ”,以告诉算法它是除其他类别值之外的特定类别值
- 分割或分组已查询的列来创建一个新的特性,例如,
count of orders
和day
列,您可以创建order_count_per_day
——有时您可以在查询本身中更容易地做到这一点,或者最好在 pandas 中这样做
同样,就像查询步骤一样,您将使这成为一个自动任务,该任务将获取一个 CSV 文件,该文件很可能随后被转换为 pandas 数据帧。
火车
因为此时您已经选择了一种算法,所以这将是您的数据科学项目的第三个主要任务。
训练您的算法可以通过多种方式进行,利用不同的平台,但在这一步中相似的是,您将根据您查询的内容开始训练工作,并预先进行预处理。您还可以训练和测试打印出您的准确性和/或其他误差指标,以供进一步分析。
这一步相当简单,下面总结了可能适用于您的要点:
- 训练经过查询和预处理的训练数据集(基于数据集位置的)**
- 如果您选择进行某种形式的分割,也要进行测试,以便尽早停止,从而减少模型的过度拟合
部署
数据科学管道的最后一步很可能是部署过程,在该过程中,您将为训练好的模型端点提供服务,以便可以使用最近的训练作业进行预测。
类似于培训工作,这一步被广泛使用和常见。一旦你有了你的终点,或者仅仅是一个训练好的模型,你就可以做出你的预测了。当然,您也可以在这里创建一个自动任务,选择最近的培训工作,这样您的模型就是最新的。
部署可能是软件工程方面的更多工作,但实际上,这取决于您的过程所使用的平台。
摘要
数据科学可能有很多部分需要消化,但当你后退一步时,你会意识到,它主要归结为相同的四个步骤,其中包括查询数据或获取数据,预处理数据,训练数据,然后部署数据。
以下是数据科学流程的总结步骤:
*** Query/Data* Preprocess* Train* Deploy**
我希望你觉得我的文章既有趣又有用。如果您同意或不同意这四个主要的数据科学步骤,请随时在下面发表评论。为什么或为什么不?关于典型的数据科学流程,您认为还有哪些重要的步骤需要指出?这些当然可以进一步澄清,但我希望我能够阐明任何数据科学项目的四个主要步骤。
我不属于这些公司中的任何一家。
请随时查看我的个人资料、 Matt Przybyla 、和其他文章,并通过以下链接订阅接收我的博客的电子邮件通知,或通过点击屏幕顶部的订阅图标 的 ,如果您有任何问题或意见,请在 LinkedIn 上联系我。**
****订阅链接:https://datascience2.medium.com/subscribe
引荐链接:【https://datascience2.medium.com/membership】T22
(如果你在 Medium 上注册会员,我会收到一笔佣金)
参考
[1]Max Ostrozhinskiy 在 Unsplash 上拍摄的照片,(2017)
[2]照片由卡斯帕·卡米尔·鲁宾在 Unsplash 上拍摄,(2017)
[4]查尔斯·弗劳恩德在 Unsplash 上拍摄的照片,(2014)
[5]照片由张秀坤·吕克曼在 Unsplash 上拍摄,(2020)
2022 年你应该阅读的 5 本最佳数据科学书籍
原文:https://towardsdatascience.com/the-5-best-data-science-books-you-should-read-in-2022-9209616c203f
以下是我喜欢的最好的数据科学书籍
请务必点击 订阅此处 千万不要错过另一篇关于数据科学指南、技巧和提示、生活经验等的文章!
你好!我知道我已经有一段时间没有发表文章了,但是我很兴奋能够回来🙂。我的许多追随者经常问我的一个问题是“最好的数据科学书籍是什么?”
虽然这是一个主观的问题,但我会尽我所能以客观和系统的方式回答这个问题。当我评估一本非小说类书籍的质量时,我会考虑四个标准:
- 深度:让读者感兴趣的书深入讨论主题的细节和复杂性是很重要的。如果我能从一本书中学到(几乎)我需要的一切,我会说它有很高的深度。
- 全面性:同时,这本书也要简明扼要。如果一本书提供了不必要的细节或者在解释复杂的概念方面做得不好,那么它就不是一本全面的书。
- 可读性:一般来说,一本书如果写得好,应该是容易读懂的。这在某种程度上与全面性有关,但也考虑了书的流程——例如,一本关于机器学习的初学者书籍可能应该在深入随机森林之前解释什么是决策树。
- 适用性:对我来说最重要的最后一个标准是适用性。如果这本书能够将原始知识与如何在现实世界中应用联系起来,它会使这本书的价值成倍增加。
说了这么多,下面是我推荐你在 2022 年读的五本最好的数据科学书籍!
1.机器学习简体
深度:4/5
全面性:4.5/5
可读性:4.5/5
适用性:5/5
榜单上第一本书叫机器学习简体。这是今年出版的一本涵盖机器学习基础的新书,我必须说,与其他书相比,这本书的独特性给我留下了深刻的印象!无论您是数据科学新手还是需要复习,这本书都因以下几个原因而脱颖而出:
- 它全面涵盖了与数据准备和数据建模相关的所有核心概念,并深入解释了这些概念背后的数学原理。因此,它不仅回答了什么而且还回答了如何。
- 它用可应用的和直观的例子解释复杂的概念和算法,使想法更少概念性和更实际。
- 最重要的是,这本书补充了一个 GitHub 库,其中包含了它讨论的每个主题的实际 python 代码实现。
2.数据科学家实用统计
深度:4.5/5
全面性:4/5
可读性:3.5/5
适用性:5/5
《数据科学家实用统计学》与第一本书相似,既全面又详细,不同之处在于这本书侧重于统计学,而不是机器学习。
这本书涵盖了所有你需要知道的统计学的核心概念,包括描述统计,抽样分布,假设检验和 A/B 检验,以及预测。
此外,这本书还包括 R 和 Python 中的代码片段,最终让您将理论概念与实际应用联系起来。
请务必点击 订阅此处 千万不要错过另一篇关于数据科学指南、技巧和提示、生活经验等的文章!
3.赤裸裸的统计——从数据中剥离恐惧
深度:3/5
全面性:4/5
可读性:5/5
适用性:4/5
《赤裸裸的统计》以一种随意的方式,用现实生活中的例子解释核心统计概念,回答诸如“网飞怎么知道你会喜欢哪部电影?”以及“是什么导致了自闭症发病率的上升?”
虽然我不会说它在统计理论中潜得太深,但它在解释基本统计概念方面做得很好,使其直观且易于记忆。
总的来说,我想说这是一本非常有趣又有教育意义的书!
4.统计学习的要素
深度:5/5
全面性:4/5
可读性:3.5/5
适用性:3.5/5
《统计学习的要素》是关于机器学习基础的最完整的教科书,涵盖了监督学习方法、非监督学习方法、图形模型、高维问题等等。
虽然它可能不像其他书提到的那样简洁,但你可以打赌,这本书将用数学解释、可视化和证明彻底解释所有概念。
这本书也是免费的,是赠品!
请务必点击 订阅此处 千万不要错过另一篇关于数据科学指南、技巧和提示、生活经验等的文章!
5.商业数据科学:结合机器学习和经济学来优化、自动化和加速商业决策
深度:3/5
全面性:4/5
可读性:5/5
适用性:5/5
业务数据科学从业务角度解释了中的基本数据科学概念,使一切都适用于业务环境。我喜欢这本书,因为我觉得它解决了许多书未能解决的主要问题,即数据科学如何为企业带来价值。
通过这本书,你将学习机器学习的基础,如何在商业环境中应用这些概念,以及如何编写 R 代码来实现这些解决方案。
感谢阅读!
务必 订阅此处 千万不要错过另一篇关于数据科学指南、诀窍和技巧、生活经验等的文章!
不确定接下来要读什么?我为你挑选了另一篇文章:
还有一个:
</5-things-that-i-actually-did-at-work-as-a-data-scientist-in-2021-e46d3a0d6dab>
感谢阅读!
如果你喜欢这篇文章,请务必点击 订阅此处 千万不要错过另一篇关于数据科学指南、技巧和提示、生活经验等的文章!
我希望你觉得这很有趣,很有见地。在评论里让我知道你最喜欢的 2022 年的数据可视化是什么!
不确定接下来要读什么?我为你挑选了另一篇文章:
或者你可以查看我的介质页面:
https://terenceshin.medium.com/
特伦斯·申
高效自学数据科学所需的 5 个基础知识
我已经测试了这些基本原理,证明它们可以用来为成功的自学经历奠定基础
阿赫默·卡拉姆在 Unsplash 上拍摄的照片
自学任何东西都是令人钦佩的事业。
无论是一门新语言、烘焙、举重、结构地质学、编织篮子、驾驶手动挡汽车,还是你能想到的任何其他东西,我对任何决定自学的人都怀有近乎疯狂的敬意。
当有人告诉我他们将自学数据科学时,我的敬畏是十倍的。你不仅宣布你将自学技术中最苛刻的领域之一,而且你还选择学习无数不那么容易的技能来达到这个目标,包括编程、数学、数据可视化等等。任何决定在休息时间学习多变量微积分作为成为数据科学家的手段的人不仅是疯狂的,而且是值得钦佩的。
在这个过程中,我发现了一些基础知识,可以帮助您掌握数据科学中最困难的主题。一旦建立起来,它们不仅使自学过程更容易,而且为你成功实现目标做好准备。
1.一致的时间表
你曾经有过持续的时间表突然停止,然后你无法回到正轨的经历吗?例如,你可以每天早上在上班前的同一时间去健身房,直到突然你开始工作,这打乱了你的整个计划。现在,你不再有时间在早上的固定时间锻炼了。这可能会导致你不再锻炼,直到你找到一个新的时间来配合你的新计划。
同样的事情也适用于学习数据科学。
成功自学数据科学需要你每天留出一段专门的时间进行学习。这个学习周期需要每天在相同的时间,相同的长度(或者每周一个速度,这个速度是可维持的,有效的让你学习概念)。把你的学习变成你每天都要完成的习惯,这是一个确保你持续完成学业的简单策略。
为了优化你的学习习惯,你需要计划好你每天要做什么。这可以让你直接进入学习阶段,而不必花时间去决定你要做什么。这不仅浪费时间,还会让你被邮件、社交媒体或其他生活中出现的事情分心。因此,在你不学习的一天,花些时间规划出你每天要学习的主题。然后,到了学习的时间,你可以坐下来,戴上你的降噪耳机,打开你的网站拦截器,开始学习。
2.编程语言的坚实基础
这个基本原则可能对每个人都不一样。然而,根据我的经验,我发现,无论您将在大部分数据科学学习中使用哪种编程语言,扎实的基础都是非常有益的。
我发现,当你很好地掌握了将要使用的编程语言时,剩下的学习过程就会变得非常容易,因为编程是你需要考虑的一件事情。这就是为什么许多数据科学学习计划鼓励学生首先学习编程部分——包括我创建的那些。
通过首先学习如何正确编码,您可以开始通过用代码思考来解决您的数据科学问题。当你的大脑在后台编写代码时,你的大部分脑力可以用来解决数据分析问题或整合机器学习模型背后的逻辑。
3.许多实践问题和正在进行的项目
许多人认为他们擅长数据科学,直到他们面前不再有解决问题的答案。
当个人自学数据科学时,经常发生的情况是,他们对自己的技能有一种错误的自信,因为他们所做的一切都是完全按照视频教程进行,并得到相同的答案。不幸的是,如果你让同一个人面对一个未解决的数据科学问题,你可能会被困在那里几个小时,而他们却没有任何实际技能可以使用。
为了正确地自学数据科学,您需要通过大量的练习题和项目来真正检验您的技能。面对面学习之所以如此有效,是因为你会不断地收到练习题、家庭作业题、测验和测试,迫使你学会如何去做,然后去应用。
自学有时会出错的地方是,人们会跟着 YouTube 视频,认为他们正在解决问题,而实际上,他们只是从别人那里复制代码、数学和逻辑。
诀窍是尽可能多地找到练习题、松散的数据集和项目,然后在不知道答案的情况下努力完成它们。这不仅锻炼了你的大脑,迫使你实际学习所需的技能,而且还训练了你的大脑如何解决问题——这种技能在参加数据科学面试时将变得非常有价值。
4.一个具体的、时间敏感的目标
除非你有一个明确的、时间敏感的目标,否则你什么也学不到。
对于现场学习者来说,这个目标通常是通过一个有固定日期的考试。然而,对于自学者来说,这个目标看起来会有些不同。
自学需要大量的训练,当你设定具体的、时间敏感的目标时,这是最好的实现方式。我讨厌 SMART goal 这个首字母缩写词,但在这里,它非常有意义,尤其是对于那些希望快速转行进入数据科学的人来说。
SMART 目标是sspecific、mmeasurable、aachieved、 r elevant、 t ime-sensitive。谈到自学数据科学,您的 SMART 目标可能与学习特定概念、通过某个在线证书或为您计划在一年内进行的数据科学面试做准备有关。SMART 目标很好使用,因为它们可以根据你的需要或大或小,这可以帮助你规划你的短期学习和长期未来。
以我的经验来看,如果你没有一些具体的和时间敏感的里程碑来努力,就不会有任何学习成果。当你把这些目标或里程碑放在一个显著的位置时,比如写在你的日历上或贴在显示器底部的便利贴上,这些目标或里程碑是最有效的。持续的视觉提醒,甚至是来自你周围人的提醒,都是保持自我学习目标动力的好方法。
5.一个创造性的发泄渠道
自学是一个艰苦的、令人精疲力竭的经历,让我们面对现实吧,它很少有乐趣。
我发现,自学时你能为自己做的最好的事情就是找到一个发泄的渠道,让你的大脑得到休息。对我来说,那就是带着狗在大自然中散步,在媒体上写作或者为我的时事通讯写作,做志愿者,以及阅读小说。这些事情都与数据科学无关(甚至我在 Medium 上的文章也不是关于数据科学的本质技术方面的),而这正是我的大脑经常需要的。
尽管你可能每天都有学习的压力,尤其是如果你想快速改变职业生涯,记住休息是至关重要的。作为一个曾经连续工作 180 天没有休息的人,我明白持续的工作或学习是不可持续的。不仅如此,在这一点上,你实际上并没有有效地学习。你的大脑处理信息的时间会比你在做了一天你喜欢的事情后处理信息的时间长得多。因此,在一头扎进自学数据科学之前,让大脑休息一下对你的学习成功至关重要。
最后的想法
正确自学数据科学的方法有很多。与你交谈的每个人都有不同的成功公式,重要的是要记住,对一个人有效的不一定对你有效。
然而,如果我可以留给你五个教训或基本原则,我发现上面列出的是确保高效自学过程中最有效的。
订阅将我的故事直接发送到您的收件箱:故事订阅
请成为会员,使用我的推荐链接获得无限制的媒体访问权限(我将收取少量佣金,无需额外费用):媒体会员
通过捐赠来支持我的写作,以资助更多像这样的故事的创作:捐赠
作为数据科学家的前 5 年,你将获得的 5 个最重要的见解
从第一天开始,牢记这五个观点来推进你的职业生涯
法耶·康尼什在 Unsplash 上的照片
作为一名数据科学家,你的头五年感觉就像从消防水管里喝水一样。
新的信息将来自左右两边,你将不得不重新学习你在数据科学之旅的最开始所学的一些东西,并且你将不得不弄清楚你在公司中的位置。
在你的第一个五年结束时,你可能会觉得自己被一辆信息和学习经历的巴士撞了。
然而,当你回顾前五年时,你可能会注意到一些非常酷的事情:你已经获得了一些有价值的见解,可以用来在未来五年中利用你的职业生涯。
尽管如此,我们中的一些人希望快速跟踪我们的学习,并在达到五年目标之前收集尽可能多的见解。谁不想现在就开始利用他们的职业生涯呢?
以下五种见解是你在作为数据科学家的头五年中可以期望获得的。
1.自动化(几乎)总是值得的
数据科学家最大的抱怨之一就是工作可能会单调重复。
因此,为什么不跳到精彩的部分,把你睡觉时能做的事情自动化呢?
如果你热爱 75%的工作,不要因为另外 25%很无聊就辞职。将无聊的事情自动化,这样你就可以更有效地利用你的时间来处理令人兴奋的事情。
根据一个最常被引用的生产率惯例,大约 20%的工作会产生 80%的结果。这意味着你其余 80%的时间都花在了那些收效甚微甚至毫无结果的任务上。
为什么要把你的时间(以及你公司的时间)浪费在收效甚微的任务上呢?
自动化任务可以简单到为自己设置自动提醒、上传数据、转换文件类型、备份文件等等。
你的自动化能力只受你的创造力的限制。只要确保你能够承认自动化走得太远了。
2.文档不仅仅是注释
文档可以开始或结束你作为数据科学家的职业生涯。
没有好的代码文档,代码就不能被发送给工程师来集成到现有的过程中。它也不能由一个被告知要使它现代化的实习生在十年后重做。
好的代码文档不仅告诉使用者它做了什么和如何工作,还提供了原始数据科学家的思维过程,即为什么代码必须以某种方式编写。
代码文档应该远远超出注释,应该包括流程图、完整的自述文件和分步描述,如果你的文档没有帮助,还应该提供联系信息。
你在最初五年遇到的许多其他数据科学家都没有软件工程或计算机科学学位。因此,你们都必须一起工作来产生代码文档,以帮助其他人理解你的工作。
一旦解决了主要的业务问题,编写可靠的文档通常是事后的想法。然而,展望未来,数据科学家可以通过简单地编写良好的代码文档,确保他们的公司在未来几年受益于他们的分析首次带来的影响。
3.良好的编码实践让你成为真正的专业人士
大多数数据科学家并没有进入软件工程或计算机科学背景的领域。如果有的话,你今天看到的大多数数据科学家的专业从物理到护理到工业工程到政治学。
数据科学家因编写的代码具有严重的功能缺失、不明确的变量名、杂乱无章的代码、没有一点单元测试的暗示以及严重缺乏风格而臭名昭著。
因此,数据科学家的价值在于他们有能力编写干净的代码,这些代码可以更新、调试并转移到生产环境中,而工程部门几乎不会说脏话。干净的代码可以帮助公司高效运行,这一点怎么强调都不为过。向利益相关者保证你能得到结果的能力依赖于你写干净的代码并且第一次就能正确运行的能力。不仅如此,写干净的代码会让你在以后的职业生涯中受到所有同事的喜爱。
以为我在开玩笑?与任何软件工程师谈论他们不得不与数据科学家的代码一起工作的时候,你会很快发现恐怖故事比童话故事多。
良好的编码实践是专业人士和业余爱好者的区别。
4.成为一个伟大的讲故事者让你不可或缺
每个人都可以编写代码和进行数据分析。
每个人都可以根据数据得出结论。
每个人都可以产生美丽的视觉效果。
但是,每个人都能讲一个故事,让利益相关者行动起来吗?是否每个人都可以编写一些故事,告诉在座的每个人我们是如何走到今天这一步的,我们目前正在做什么,以及我们未来将如何前进?
能讲伟大故事的数据科学家不可或缺。然而,讲述故事并不仅限于此,它涵盖了对数据科学家至关重要的所有交流形式。
沟通能力并不是所有数据科学家都具备的技能,它将帮助你在职业生涯中快速前进。因此,你必须抓住一切机会练习交流。为你的利益相关者演示文稿编写故事,故事要有清晰的开头、中间和结尾。塑造您的数据分析,以提供一个清晰的故事,该数据目前告诉你什么。练习编写关于公司未来发展的故事,让利益相关者清楚地看到未来的样子。
成为一名优秀的沟通者不是一夜之间就能实现的,但是如果你每天都练习,你就能做到。
5.简单点,笨蛋
如果你的模型得出了错误的结论,它就没有任何意义。
你的复杂算法并不能证明你比其他人更好,如果它把已经连贯的数据搅得一团糟的话。
如果没有其他人能理解它的作用,你的两行代码代替十行代码并不能让你成为数据科学之神。
出于某种原因,这句格言似乎在每个人作为数据科学家的职业生涯中的某个时候都过时了。不管是因为工作很无聊,还是你学到了新东西,总有一天你会不想再保持简单。这很好。
只要你找到回归简单的方法。
保持简单会让你成为公司的优秀导师,让你快速高效地完成工作,最终让你管理自己的团队。
保持简单意味着在 A 和 b 之间寻找最短的逻辑路径。这也意味着在你的工作中要直接——如果一些东西写成十行代码更有意义,那么就写成十行代码。此外,这也意味着你在避免寻找过于复杂的方法来做原本简单的事情。
这句话应该是你学习生活的准则,不仅是为了成为一名更好的数据科学家,也是为了成为一名更好的队友、经理和老板。这句话将帮助你在成为数据科学家仅五年后脱颖而出。
关键要点
- 数据科学家的许多单调重复的工作可以自动化,以确保您使用更多的时间来交付有影响力的结果。
- 编写良好的代码文档的能力将确保您的公司在未来几年受益于您的分析所带来的影响。
- 无论你在数据科学领域担任什么职位,良好的编码实践都会让你成为一名出色的队友和宝贵的资产。
- 每个人都可以编写代码、计算和完成分析,让你与其他数据科学家区别开来的是你讲述故事和有效沟通的能力。
- 寻找完成一项任务的简单途径会让你成为公司的优秀导师,会让你的上级知道你是可以信任的人,可以高效地完成工作,会让你有一天管理自己的团队。
订阅将我的故事直接发送到您的收件箱:故事订阅
请成为会员,使用我的推荐链接获得无限制的媒体访问权限(我将收取少量佣金,无需额外费用):媒体会员
5 种最流行的 SQL 转换
原文:https://towardsdatascience.com/the-5-most-popular-sql-transforms-ca1f977ef2b2
SQL 生成器的用法分析
由 Austin Distel 在 Unsplash 上拍摄的照片
介绍
在以前的帖子中,我提到过 SQL 生成器网站,它是分析师快速生成复杂 SQL 的有用工具。本周,我获得了数据,这样我们可以看看哪些是最受欢迎的转变。
基本分析
数据本身相当有限。由于该网站对所有人免费开放,因此没有可供分析的用户数据。我们只有某人点击“生成 SQL”时的时间戳,以及它是什么类型的转换。
截至本文发布时,该网站已有 76 个不同的转换。让我们快速浏览一下最流行的转换,并讨论一下 SQL。
#5:相关性(3%)
我惊讶地看到相关性进入了前 5。这个转换从表中的数字列创建每一个可能的对,并运行CORR()
SQL 函数。
这相当简单,但是我认为为每一对列编写 SQL 是非常耗时和乏味的。因此,用户通过使用 SQL 生成器进行这种类型的转换来节省时间是有意义的。
对于数字列,表结构(右)被自动分析,并且每个成对组合被构建到 SQL(下)中
#4:清洁(3%)
clean 转换是估算、过滤、转换和重命名的组合。它允许您对数据的每一列进行一次或多次这样的转换。
在这个例子中,我使用 Clean()混合并匹配了一些不同的转换:
- 移除了
Load_Datetime
- 将
Record_Deleted_Flag
转换为一个数字,并在不等于 1 的地方进行过滤 - 铸造订单和税收金额为
FLOAT
并用 0 代替缺失 - 将栏目
Ref1
更名为MY_NEW_COLUMN_NAME
“清除”允许您同时应用删除、重命名、转换、估算和过滤器
第三:加入(4%)
加入如此受欢迎的事实也让我大吃一惊。我假设连接很常见并且很容易配置,但这可能是因为我在过去的 20 年里一直在编写 SQL。
除非您已经将 Rasgo 连接到您的数据仓库,否则 SQL 生成器将看不到您的真实数据库,这需要您在页面的右侧配置您的表结构。但是,您可以设置任意多的表,然后使用该界面来设置您的连接并为您编写 SQL。
设置联接需要表定义
第二名:支点(5%)
事实上 pivot 是第二流行的转换并不奇怪。众所周知,Pivot 很难处理,尤其是因为每个 RDBMS 都决定使用稍微不同的语法。
然而,这仍然需要一些设置,因为您必须配置LIST_OF_VALS
,它是您希望作为列进行透视的唯一值。如果您省略这个参数,Rasgo 将尝试为您查询不同的值。(参见:将 Rasgo 连接到上面的数据仓库)
如果 Rasgo 没有连接到您的数据仓库,则必须配置 VALS 列表。
第一名:合计(17%)
聚合是迄今为止最流行的转换,很容易看出为什么。该界面允许您轻松选择多种类型的聚合,并为您生成 SQL。
此外,一些 RDBMS(我正看着你呢,BigQuery)忽略了添加流行的函数,如MEDIAN
和MODE
,这使得编写 SQL 变得混乱和乏味。
你自己试试吧!在 SQL 生成器中打开 this example ,将 dialect 下拉菜单更改为 BigQuery,并观察 BigQuery SQL 的生成。
Aggregate 有一个易于使用的接口,这使它成为最流行的 SQL 转换
关于帕累托原理的一个旁注
关于这些数据,最让我吃惊的一件事是所有的使用是如何分散的。经典的“80/20 法则”在这里并不适用。
80/20 规则,通常称为 Pareto 原则,表明 80%的使用将占 20%的转换。具体来说,这意味着 76 个 SQL 转换中的 15 个应该占使用量的 80%。
实际上,SQL 的用法似乎比这要多得多。我们看到前 15 个转换只占了 50%的使用量。因此,我们有一个 50/20 规则,而不是 80/20 规则。
不幸的是,帕累托原则与“80/20 法则”混淆了。事实上,帕累托法则只是告诉我们大多数事情并不是均匀分布的。80 加 20 等于 100 是一个普遍的误解。如果你想了解帕累托原则,我强烈推荐我最喜欢的作家之一卡利德·阿扎德的这个博客/视频。
结论
我从这一分析中看到两个要点:
- SQL Generator 更受欢迎的是自动化繁琐的 SQL,而不是复杂的逻辑
- SQL 的用法是多种多样的——换句话说,我们不可能只学了 5 样东西就突然成为专家。
我希望你和我一样对此感兴趣。如果您对您认为常见的其他 SQL 转换有建议或意见,您可以在local Optimistic和 DataTalks 中找到我。俱乐部。
5 个最有前途的图像翻译人工智能模型
原文:https://towardsdatascience.com/the-5-most-promising-ai-models-for-image-translation-de2677e526e6
从其他图像生成图像的最新模型的技术水平
图像到图像的翻译
A 根据 Solanki,Nayyar 和 Naved 在[1]中的定义,图像到图像的翻译是将图像从一个域转换到另一个域的过程,其目标是学习输入图像和输出图像之间的映射。
换句话说,我们希望模型能够通过学习映射函数 f 将图像“a”转换为另一个图像“b”。
映射函数 f 获取图像“a ”,并将其转换为图像“b”。所有图像 A 的集合称为 A 的定义域,所有图像 b 的集合称为 b 的定义域。照片由肖恩·惠兰(左)和马特乌斯·德勒加茨(右)在 Unsplash 上拍摄。作者编辑
人们可能会想这些模型有什么用,它们在人工智能世界中有什么相关性。然而,它的应用非常广泛,不仅仅局限于艺术或平面设计。例如,能够拍摄一幅图像并将其转换成另一幅图像对于创建合成数据非常有用,比如分割图像来训练自动驾驶汽车模型。另一个经过测试的应用是地图设计,其中模型能够执行两种转换(卫星视图到地图,反之亦然)。图像转换模型也可以应用于架构,其中模型可以就如何完成未完成的项目提出建议。
图像翻译最引人注目的应用之一是将简单的图画转换成美丽的风景或绘画。图片由作者编辑
5 个最有前途的图像翻译人工智能模型
在过去的几年中,已经开发了几种方法来利用生成模型解决图像到图像的翻译问题。最常用的方法基于以下架构:
- 生成对抗网络
- 可变自动编码器(VAE)
- 扩散模型
- 变形金刚(电影名)
Pix2Pix
Pix2Pix [2]是基于条件 GAN 的模型。这意味着它的结构由一个发生器网络(G)和一个鉴别器(D)构成。两个网络都在一个对抗性的游戏中接受训练,其中 G 的目标是生成看起来与数据集相似的新图像,而 D 必须决定图像是生成的(假的)还是来自数据集(真的)
Pix2Pix 和其他 GAN 模型之间的主要区别是:( 1)第一个的生成器将图像作为输入来开始生成过程,而普通 GAN 使用随机噪声,以及(2) Pix2Pix 是一个完全监督的模型,这意味着数据集由来自两个域的成对图像组成(输入和地面真实图像)
文中描述的架构由一个用于发生器的 U-Net 和一个用于鉴别器的马尔可夫鉴别器或补丁鉴别器定义:
*** U-Net** :由两个模块组成:下采样和上采样。使用卷积层将输入图像缩减为一组更小的图像(称为特征图),然后通过转置卷积进行上采样,直到达到原始输入维数。在下采样和上采样之间存在跳跃连接。
*补丁鉴别器:卷积网络,其输出是一个矩阵,其中每个元素都是对图像的一个部分(补丁)进行评估的结果。它包括生成的图像和地面真实图像之间的 L1 距离,以确保生成器学习映射给定输入图像的正确函数。也称为马尔可夫,因为它依赖于来自不同片的像素是独立的假设。
Pix2Pix 结果。图片来自报纸[2]
无监督的图像到图像转换(单位)
在 Pix2Pix 中,训练过程是完全监督的(即我们需要成对的图像输入-背景事实)。单元方法[3]旨在学习将图像 A 映射到 B 的函数,而不需要两个成对的图像用于训练。
该模型从两个域(A 和 B)共享一个公共潜在空间 ( Z )的假设出发。直观地说,我们可以将这个潜在空间视为图像域 A 和 b 之间的中间阶段。因此,使用绘画到风景的例子,我们可以使用相同的潜在空间后退并生成绘画图像,或者前进以看到令人惊叹的风景(见图 X)。
图一。(一)共享潜在空间。(b)单元建筑:X1 是一幅图画,X2 是一幅美丽的风景;E1,E2 是从两个领域(绘画和风景)获取图像并将它们映射到共享潜在空间 Z 的编码器;G1,G2 发电机,和 D1,D2 鉴别器。虚线表示网络之间的共享层。图片来自报纸[3]
单元模型是在一个耦合 VAE-甘架构(见图 1)下开发的,其中编码器的最后一层(e 1,E2)和生成器的第一层(G1,G2)是共享的。
单位结果。图片来自报纸[3]
调色板
Palette [4]是加拿大 Google 研究团队开发的一个条件扩散模型。该模型被训练来执行与图像转换相关的 4 个不同的任务,实现高质量的结果:
(i)着色:向灰度图像添加颜色
(ii)修补:用逼真的内容填充图像的用户指定区域
(iii)去剪裁:放大图像帧
(iv) JPEG 恢复:恢复受损的 JPEG 图像
在这篇文章中,作者探讨了多任务通用模型和多个专门化模型之间的差异,两者都是针对 1M 迭代训练的。该模型的架构基于 Dhariwal 和 Nichol 2021 的类调节 U-Net 模型,并使用 1024 个图像的批量大小进行 1M 训练步骤。噪声时间表作为超参数被预先设置和调整,使用不同的时间表进行训练和预测。
调色板结果。图片来自报纸[4]
视觉变形金刚(ViT)
注。虽然下面的两个模型不是明确为图像翻译而设计的,但它们是将变形金刚等强大模型引入计算机视觉领域的一个明显进步。
视觉变压器(ViT) [5]是对变压器架构( Vaswani et al. 2017 ) 的修改,为图像分类而开发。该模型将图像作为输入,并输出属于每个定义的类别的概率。
主要问题依赖于这样一个事实,即变换器被设计成接受一维序列作为输入,而不是 2D 矩阵。为了解决这一障碍,作者建议将图像分割成小块,将图像视为序列(或 NLP 中的句子),而小块则视为记号(或单词)
作为一个快速总结,我们可以将整个过程分为 3 个阶段:
1)嵌入:分割小块并展平它们→应用线性变换→添加类别令牌(该令牌将充当分类所考虑的图像摘要)→位置嵌入
2)变换器-编码器块:将嵌入的补丁馈入一系列变换器编码器块。注意力机制知道应该关注图像的哪些部分
3)分类 MLP 头:将类别令牌通过输出属于每个类别的图像的最终概率的 MLP 头。
使用 ViT 的好处:排列不变。与 CNN 相比,Transformer 不受图像平移(元素位置变化)的影响
缺点:训练需要大量的标记数据(至少 14M 的图像)
TransGAN
TransGAN [6]是一个基于变换的 GAN 模型,专为不使用任何卷积层的图像生成而设计。相反,发生器和鉴别器由一系列通过上采样和下采样模块连接的变压器构成。
发生器的正向处理采用 1D 阵列的随机噪声样本,并将其通过 MLP。直观地说,我们可以把数组想象成一个句子,把像素值想象成单词(注意,一个 64 个元素的数组可以被重新整形为一个 1 通道的图像 8✕8)接下来,作者应用一系列变换块,每个变换块后面都有一个上采样层,使数组(图像)的大小加倍。
TransGAN 的一个关键特性是 网格——自我关注 。当到达高维图像(即,非常长的阵列 32✕32 = 1024)时,应用变形器会导致自关注机制的爆炸性成本,因为您需要将 1024 阵列的每个像素与可以占据该位置的所有 255 个可能的像素(RGB 比例)进行比较。由于这个原因,网格自关注将全尺寸特征图划分成几个不重叠的网格,并且在每个局部网格内计算标记交互,而不是计算给定标记和所有其他标记之间的对应关系。【参见图 2】
鉴别器架构与之前引用的 ViT 非常相似
图二。网格自我关注来自原论文[5]。现在,我们输入多个句子,一次一个,而不是用一个长句来填充变压器。图片来自报纸[6]
不同数据集上的 TransGAN 结果,图像来自论文[6]
参考
【1】【生成对抗网络】进行意象到意象的翻译 。Arun Solanki、Anand Nayyar 和 Mohd Naved。爱思唯尔(2021)
【2】有条件对抗网络的意象到意象翻译 。菲利普伊索拉朱俊彦廷辉周阿列克谢。2018
【3】无监督的图像到图像翻译网络 。刘明宇,托马斯·布雷尔,扬·考茨。2018
【4】调色板:图像间扩散模型 。奇万·萨哈利亚、陈伟霆、张惠文、克里斯·李、乔纳森·何、蒂姆·萨利曼斯、戴维·J·弗利特、穆罕默德·诺鲁齐。2022
【5】一幅图像抵得上 16x16 的文字:变形金刚在尺度上的图像识别 。Alexey Dosovitskiy、Lucas Beyer、Alexander、Dirk Weissenborn、翟晓华、Thomas Unterthiner、Mostafa Dehghani、Matthias Minderer、Georg Heigold、Sylvain Gelly、Jakob Uszkoreit、Neil Houlsby。2021
【6】trans GAN:两个纯变形金刚可以做一个强 GAN,而且那个可以放大 。、张、王 1。2021
要开始使用的 5 个 SQL 转换
原文:https://towardsdatascience.com/the-5-sql-transforms-to-start-using-296ca7987921
鲜为人知的 SQL 转换以及它们为什么有用
照片由 akiragiulia 在 Pixabay 上拍摄
介绍
在以前的帖子中,我分析了来自 SQL Generator 5000 的数据,并概述了 5 种最流行的 SQL 转换。这一次,我反其道而行之,看看最不受欢迎的 5 个。
当我最初回顾最不受欢迎的转换时,我很惊讶,因为它们中的大多数都非常有用。所以,我联系了一些我认识的用户,和他们讨论这个问题。
根据这些对话,我了解到很少使用这些转换的主要原因有两个:
- 有些是非常情境化的——
aggregate
和join
几乎在每个 SQL 查询中都使用,Moving Average
只在处理时序数据时使用 - 其中一些转换是 SQL Generator 特有的——很少使用只是因为不知道它们的存在
因此,我将遍历 5 个最不常用的转换,并和 SQL 代码一起解释每一个都有用的情况。
#5 最小-最大缩放器
这是什么?
定标器是改变数值范围的方法。两个最常见的是:min_max_scaler
和standard_scaler.
一般来说,缩放是以一种新的范围落在 0 和 1 之间的方式进行的。另一方面,标准化是以平均值为 0,标准偏差为 1 的方式进行的。有时候,术语正常化会在关于这些技术的对话中出现。Normalize 可以有非常具体的含义,但通常它是一个通用术语,可能意味着缩放、标准化(或其他什么!).为了避免混淆,不要使用术语规格化。
如何使用?
缩放数据有几种常见的情况:
- 相对比较用不同单位测量的事物
- 基本分割
- 机器学习的预处理
- 在同一个图表上一起绘制指标
假设您有一些关于患者的数据,其中每个变量都在不同的范围内:
原始数据
由于Age
是以年计量的,Glucose
是以 mg/DL 计量的,我们很难对患者进行比较。缩放该数据的公式要求我们知道值的MIN()
和MAX()
。同样,standard_scaler
要求我们知道AVG()
和STDEV()
。
请注意 SQL 是如何以动态计算的方式编写的。
最小-最大缩放的 SQL
缩放数据
最新排名第四
这是什么?
Latest 是一个 SQL 转换,它返回一组有序值中的最后一个值。虽然大多数 SQL 函数一次只“查看”一行,但这个函数使用所谓的窗口函数来查看其他行。因此,只有当您的数据具有固有的顺序时,才使用它。
如何使用?
有许多方法可以使用最新的,但最常见的是:
- 分析系统日志,或者只在值发生变化时才记录值的系统
- 当传感器有时不报告时分析传感器数据(这在传感器数据中很常见)
- 分析“快照”数据—查找期末值
(月末销售额、日终通话等。) - 时间序列或预测模型的预处理
假设您有传感器数据,但温度读数有时会丢失:
每小时传感器数据(原始)
下面是可定制的 SQL用最新的先前值替换任何空白值。
最适合这种转换的函数叫做LAST_VALUE().
,它通过声明一个搜索窗口来工作,该窗口根据 RDBMS 有不同的默认行为。因此,我总是建议您显式声明ROWS BETWEEN
定义,以使您的代码更容易理解。
注意:我写了一篇较长的教程,介绍如何使用这种技术来填补时间序列数据中的空白。
#3 移动平均线
这是什么?
移动平均变换是另一个窗口函数,它要求数据具有内在的顺序。移动平均线可以用来告诉我们过去 7 天的平均销售额,而不是今天的销售额。
如何使用?
移动平均线主要用于确定一个趋势。如果你的价值观变化很大,他们也可以“消除”波动。它是最古老和最常用的技术指标之一。甚至在 Excel 中也有!如果您在 Excel 中绘制时间序列,您可以通过右键单击并“添加趋势线”来添加移动平均值
它最常用于:
- 金融和交易分析
- 趋势分析
- 仪表板和图表覆盖
假设您的数据具有戏剧性的季节性模式:
季节性模式的示例数据
我制作了这张图表,这样你就可以看到有轻微的增长趋势。然而,量化这一趋势可能很困难,因为数字到处都是。
使用移动平均转换,我们可以创建添加移动平均的 SQL。
当我们绘制结果时,我们可以看到一个良好的、稳定的、增长的趋势。
#2 熵
这是什么?
熵是一种聚合分类数据并表示其分散程度的方法。它来自信息论领域,经常在机器学习算法的幕后使用。
如何使用?
我们当前对 SQL 生成器的分析是一个很好的例子,说明了entropy
的用处。假设用户 A 和用户 B 各使用了 SQL 生成器 100 次,并且他们只使用了两个最流行的转换,aggregate
和pivot
。
用户 A: aggregate
50 次,pivot
50 次
用户 B: aggregate
99 次,pivot
1 次
如果我们只对COUNT()
和COUNT(DISTINCT)
进行聚合,我们将无法区分这两个用户的行为,但是他们的行为非常不同。
这就是测量熵有帮助的地方。用户 A 和 B 明显不同,因为他们的使用分布不同。熵将显示用户 A 的熵为 1,因为aggregate
和pivot
之间的分布尽可能分散。另一方面,用户 B 将具有非常低的熵,因为他们主要仅使用单个变换。
没有直接的 SQL 函数来计算entropy
,但是 SQL 生成器会为您编写执行这个聚合的逻辑。自己试试!
#1 直方图
这是什么?
直方图是一种图表,所以 SQL 工具的用户不觉得这种转换很流行也就不足为奇了。与熵类似,直方图也通过将一个数字列分解成多个柱,然后绘制它们出现的频率来测量离差。然而,直方图是一个可视化的图表——SQL 不能制作图表,那么这个 SQL 转换到底是为了什么呢?
如何使用?
直方图本身非常有用。它们允许用户快速回答问题,例如:
- 出货时间多久超过 48 小时?
- 总订单量的分布是怎样的?
分析师通常使用 BI 工具或 python 包来自动汇总数据并创建图表。这个 SQL 转换只是为了聚合数据。这是因为与实际绘制的集合相比,基础数据可能非常大。
例如,如果您有 5 亿个订单,并且您想要绘制一个total_order_amount
的直方图,那么将所有的 5 亿行都移动到您的笔记本电脑中,只是将它聚合成 100 行以绘制直方图,这在计算上是很浪费的。这个 SQL 将直接从仓库中产生聚集的行,所以绘制直方图变得很快&容易。
这里有一个例子:
通过用直方图配置 SQL 生成器,我们可以选择使用多少个库(在本例中为 100)。
SQL 生成如下:
结论
简单回顾一下,上周我们看了 5 个最受欢迎的转变,我们接着看了 5 个最不受欢迎的转变。
最流行的——关联、清理、连接、透视、聚合
最不受欢迎 — 最小最大缩放器、最新、移动平均值、熵、直方图
正如您所看到的,流行的转换似乎是简单、乏味的,而最不受欢迎的似乎是最专业、最复杂的。
根据我与用户的交谈,很明显,许多人并不知道这些专门的转换是用来做什么的。所以,希望我已经分享了一些很少使用的有用的上下文,这样如果你发现自己处于这些罕见的情况中,你就已经有了为你编写的代码。
机器学习验证的 5 个阶段
原文:https://towardsdatascience.com/the-5-stages-of-machine-learning-validation-162193f8e5db
确保跨 ML 生命周期的高质量机器学习
质量管理是一个静态图像。信用尼科埃尔尼诺,股票照片 ID:1357020474
介绍
机器学习近年来蓬勃发展。它越来越融入我们的日常生活,并为各行各业的企业提供了巨大的价值。普华永道预测,到 2030 年,人工智能将为全球经济贡献 15.7 万亿美元。这听起来好得难以置信…
然而,鉴于全球经济和社会的潜在附加值如此之大,为什么我们如此频繁地听到人工智能发生灾难性错误的故事?以及一些最大的、技术最先进的企业。
我相信你已经看到了头条新闻,包括亚马逊和苹果的性别偏见招聘工具和信用卡产品,这不仅影响了他们各自的公司声誉,也可能对整个社会产生巨大的负面影响。此外,Zillow 著名的 iBuying 算法,由于不可预测的市场事件,导致该公司将其房地产投资组合的价值减少了 5 亿美元。
回到大约 8 年前,在出现诸如 Tensorflow 、 PyTorch 和 XGBoost 等工具之前,数据科学领域的主要焦点是如何实际构建和训练机器学习模型。在创建了上面列出的工具以及更多工具之后,数据科学家能够将他们的理论付诸实践,并开始构建机器学习模型来解决现实世界的问题。
在解决了模型构建阶段之后,近年来的很多焦点都是通过将模型投入生产来开始产生真实世界的价值。许多大型端到端平台,如 Sagemaker 、 Databricks 和 Kubeflow 已经做了很好的工作,为部署机器学习模型提供了灵活和可扩展的基础设施,以供更广泛的企业和/或公众使用。
现在,工具和基础设施可以有效地构建和部署机器学习,企业将机器学习提供给外部客户或用于做出商业决策的障碍已经大大减少。因此,像上面这样的故事发生得越来越频繁的风险变得越来越大。
这就是机器学习验证的用武之地…
图 1: 图表对比了过去 8 年 AI/ML 的准入门槛和相关风险。图片作者。
内容
- 介绍
- 什么是机器学习验证?
- 机器学习验证的 5 个阶段
- ML 数据验证
-培训验证
-部署前验证
-部署后验证
-治理&合规性验证
- ML 数据验证
- 拥有 ML 验证策略的好处
TL;速度三角形定位法(dead reckoning)
- 机器学习系统不能用传统的软件测试技术来测试。
- 机器学习验证是评估机器学习系统质量的过程。
- 已经确定了 5 种不同类型的机器学习验证:
- ML 数据验证 : 评估 ML 数据的质量
- 训练验证 : 评估用不同数据或参数训练的模型
- 部署前验证 : 部署前的最终质量测量
- 部署后验证 :
- 实施机器学习验证过程将确保 ML 系统以高质量构建,符合要求,并被企业接受以增加采用。
什么是机器学习验证?
由于机器学习的概率性质,很难像测试传统软件一样测试机器学习系统(即单元测试、集成测试等)。).由于模型周围的数据和环境会随着时间的推移而频繁变化,因此只测试模型的特定结果并不是好的做法。作为今天展示一组正确验证的模型,明天可能会非常错误。
此外,如果在模型或数据中发现了错误,解决方案不能只是简单地实施修复。同样,这是由于机器学习模型周围不断变化的环境和重新培训的需要。如果解决方案只是一个模型修正,那么下次重新训练模型或者更新数据时,修正将会丢失并且不再被考虑。因此,应该实施模型验证来检查某些模型行为和数据质量。
值得注意的是,当我们在这里谈论验证时,我们不是指在机器学习生命周期的训练阶段执行的典型验证。我们所说的机器学习验证是指在传统软件测试手段之外,测试机器学习系统以验证系统质量的过程。应该在机器学习生命周期的所有阶段进行测试,以在机器学习系统投入生产之前验证其质量。以及持续监控生产中的系统健康状况,以检测任何潜在的恶化。
机器学习验证的 5 个阶段
如下图图 2** 所示,机器学习验证的 5 个关键阶段已经确定:**
- ML 数据验证
- 培训验证
- 部署前验证
- 部署后验证
- 治理和合规性验证
本文的剩余部分将进一步分解每个阶段,概述它是什么,验证的类型和每个类别的例子。
图 2:图表显示了机器学习验证的 5 个阶段在典型的机器学习生命周期中的位置。图片作者。
1.ML 数据验证
最近,出现了向以数据为中心的机器学习发展的巨大转变。这凸显了用高质量数据训练机器学习模型的重要性。机器学习模型根据它接受训练的数据来学习预测某种结果。因此,如果训练数据是目标状态的不良表示,则模型将给出不良预测。简单来说,垃圾进,垃圾出。
数据验证评估用于训练和测试模型的数据集的质量。这可以分为两个子类别:
- 数据工程验证 —基于基本理解和规则,识别数据集中的任何一般问题。这可能包括检查整个数据中的空列和 NAN 值,以及已知的范围。例如,确认“年龄”特征的数据应该在 0-100 之间。
- 基于 ML 的数据验证 —评估用于训练机器学习模型的数据质量。例如,确保数据集均匀分布,这样模型就不会有偏差,或者对于某个要素或值具有更高的性能。
如下面的 图 3 所示,最佳实践是在您的机器学习管道之前完成数据工程验证。因此,只有基于 ML 的数据验证应该在机器学习管道本身中执行。
图 3:显示两种不同类型的数据验证在数据流程中所处位置的图表。图片作者。
2.培训验证
训练验证包括任何需要重新训练模型的验证。通常,这包括在一次培训工作中测试不同的模型。这些验证是在模型开发的培训/评估阶段执行的,通常作为实验代码保存,不会最终投入生产。
实践中如何使用培训验证的几个例子包括:
超参数优化 —寻找最佳超参数集的技术(如网格搜索)经常使用,但未经验证。将经过超参数优化的模型的性能与包含一组固定超参数的模型的性能进行比较是一种简单的验证。通过测试调整单个超参数对模型性能的预期结果的影响,可以增加该过程的复杂性。
交叉验证 —对数据的不同分割进行训练可以转化为验证,例如验证每个模型的性能输出在给定的范围内,确保模型具有良好的通用性。
图 4:展示如何将交叉验证转化为简单验证的例子。图片作者。
特性选择验证 —理解某些特性的重要性或影响力也应该是贯穿模型生命周期的一个连续过程。示例包括从训练集中移除特征或添加随机噪声特征,以验证这对性能/特征重要性等指标的影响。
3.部署前验证
模型训练完成并选定模型后,应在训练验证流程之外验证最终模型的性能和行为。这包括围绕可测量的度量创建可操作的测试。例如,这可能包括重新确认性能指标是否高于某个阈值。
评估模型的性能时,通常会查看准确性、精确度、召回率、F1 分数或自定义评估指标等指标。但是,我们可以更进一步,在整个数据集的不同数据片中评估这些指标。例如,对于一个简单的房价回归模型,在预测一个 2 居室和一个 5 居室的房价时,模型的性能如何比较。这些信息很少与模型的用户共享,但对于理解模型的优点和缺点来说,这些信息非常有用,因此有助于增加对模型的信任。
图 5:显示如何进一步分解简单模型性能指标——准确性的示例,以验证不同数据片的性能。图片作者。
额外的性能验证还可以包括,将模型与随机基线模型进行比较,以确保模型实际上与数据相符;或者在开发低延迟用例时,测试模型推理时间是否低于某个阈值。
还可以包括性能之外的其他验证。例如,应该通过检查单边情况来验证模型的稳健性,或者验证模型在最小数据集上的准确预测。此外,可解释性度量也可以转化为验证,例如检查一个特性是否在前 N 个最重要的特性中。
重要的是要重申,所有这些部署前验证都采用可测量的指标,并将其构建到通过/失败测试中。在模型用于生产之前,验证作为最终的“通过/不通过”。因此,这些验证作为一种预防措施来确保一个高质量和透明的模型将被用于制定它所建立的商业决策。
4.部署后验证(模型监控)
一旦模型通过了预部署阶段,它就被提升到生产阶段。由于模型随后做出实时决策,部署后验证用于持续检查模型的健康状况,以确认它仍然适合生产。因此,部署后验证作为反应措施。
由于机器学习模型根据其接受训练的历史数据预测结果,即使模型周围环境的微小变化也可能导致非常不正确的预测。模型监控已经成为行业内广泛采用的实践来计算活动模型度量。这可能包括滚动性能指标,或者实时数据和训练数据分布的比较。
与部署前验证类似,部署后验证是采用这些模型监控指标并将其转化为可操作测试的实践。通常,这涉及到报警。例如,如果实时准确性指标低于某个阈值,就会发送警报,触发某种操作,如通知数据科学团队,或调用 API 启动再培训管道。
图 6:显示模型性能随时间衰减的图表,其中可以添加一个阈值来触发操作。图片作者。
部署后验证包括:
- 滚动性能计算 —如果机器学习系统有能力收集预测正确与否的反馈,性能指标就可以即时计算出来。然后,可以将现场表现与训练表现进行比较,以确保它们在某个阈值内并且不会下降。
- 异常值检测 —通过获取模型训练数据的分布,可以根据实时请求检测异常。通过了解数据点是否在训练数据分布的特定范围内。回到我们的年龄示例,如果新请求包含“年龄=105”,这将被标记为异常值,因为它超出了训练数据的分布(我们之前定义为范围从 0 到 100)。
- 漂移检测 —识别模型周围的环境何时发生变化。常用的技术是将实时数据的分布与训练数据的分布进行比较,并检查它是否在某个阈值内。再次使用“年龄”示例,如果实时数据输入突然开始接收大量年龄为> 100 的请求,则实时数据的分布将会改变,并且具有比训练数据更高的中值。如果该差值大于某个阈值,将会识别出漂移。
A/B 测试 —在将新模型版本推广到生产中之前,或者为了在实时数据中找到性能最佳的模型,可以使用 A/B 测试。A/B 测试向模型 A 发送一个流量子集,向模型 B 发送一个不同的流量子集。通过使用选定的性能指标评估每个模型的性能,可以选择性能更高的模型并将其推广到生产中。
5.治理和合规性验证
在生产中建立并运行一个模型,并确保它生成高质量的预测是非常重要的。然而,同样重要的是(如果不是更重要的话),确保模型以公平和合规的方式进行预测。这包括满足管理机构制定的法规,以及与您组织的特定公司价值观保持一致。
正如引言中所讨论的,最近的新闻文章显示,一些世界上最大的组织犯了非常错误的错误,并将有偏见/歧视的机器学习模型引入现实世界。
GDPR、欧盟人工智能法案(EU Artificial Intelligence Act)和 GxP 等法规开始制定政策,以确保组织以安全和公平的方式使用机器学习。
这些政策包括以下内容:
- 理解和识别人工智能系统的风险(分为不可接受的风险、高风险和有限和最小风险)
- 确保 PII 数据不会被不当存储或使用
- 确保性别、种族或宗教等受保护特征不被使用
- 确认模型所依据的数据的新鲜度
- 确认模型经常接受再培训并且是最新的,并且有足够的再培训流程
组织应定义自己的 AI/ML 合规政策,该政策应符合这些官方的政府 AI/ML 合规法案及其公司价值观。这将确保组织在开发任何机器学习系统时,都有必要的流程和保护措施。
验证过程的这个阶段适用于上面讨论的所有其他验证阶段。拥有一个适当的 ML 验证过程将提供一个框架来报告一个模型在每个阶段是如何被验证的。因此满足符合性要求。
拥有 ML 验证策略的好处
在机器学习管道的所有五个阶段实施合适的验证流程将确保:
- 机器学习系统是由高质量的,
- 这些系统完全兼容,使用安全,
- 所有利益相关者都可以看到模型是如何验证的,以及机器学习的价值。
企业应该确保他们有正确的流程和政策来验证他们的技术团队正在提供的机器学习。此外,数据科学团队应该在其机器学习系统的范围界定阶段包括验证设计。这将决定机器学习模型必须通过的测试,以移动并保持在生产中。
这不仅可以确保企业的机器学习系统产生大量的价值,还可以让非技术企业用户和利益相关者对正在交付的机器学习应用程序产生信任。因此,在组织中增加机器学习的采用。
如果您想了解更多关于机器学习验证的信息,或者需要在您的组织内定义 ML 验证政策的帮助,请随时通过 Linkedin 或 电子邮件 与我们联系。
5 步数据科学项目生命周期你需要成为一个有效的数据科学家
这 5 个核心步骤可用于规划任何数据科学项目
马库斯·斯皮斯克在 Unsplash 上的照片
如果你和我一样,清单和流程就是你的生命线。它们不仅能让你有条理,还能帮助你预见和减轻项目进展过程中可能出现的问题。
来自软件开发教育背景,我对“软件开发生命周期”(SDLC)了如指掌,我为自己准备了许多清单,以确保我总是编写尽可能最好的代码(参见:这个快速简单的 7 步清单将帮助你为数据科学编写更好的 Python 代码)。
然而,当我开始浏览网上提供的大量数据科学课程和证书时,我注意到缺少了一个重要的东西:任何关于项目生命周期的内容。直到我做了自己的挖掘,我才了解到数据科学确实有一个通用的生命周期,并且它足够灵活,可以修改以适应每个团队或项目的需求。
有几个原因可以解释为什么熟悉数据科学项目生命周期是个好主意。首先,它让你成为一名高效的团队成员和数据科学家。只有当团队中的每个成员齐心协力,或者当一个人勾选了所有的框来创建一个有凝聚力的项目时,一个项目才能走到一起。其次,你可以得到一个关于数据科学项目生命周期的面试问题,你的回答可以让招聘人员很好地了解你将如何适应这个角色。最后,也许不需要说,数据科学项目生命周期有助于指导您的数据科学项目。它提供了一系列循序渐进的里程碑,将帮助您计划和执行一个全面的项目,还将帮助您准备和减轻未来可能出现的任何潜在问题。
数据科学生命周期
首先要注意的是,数据科学的生命周期对每个人来说可能都有点不同。有几种不同的解释,尽管它们通常都类似于以下结构:
鸣谢:麦迪逊·亨特|数据科学项目生命周期。
1.定义并理解问题
如果你不知道问题是什么,问题就无法解决。
许多高管会去找他们的数据科学团队,声称有问题,数据科学团队需要解决它,但不知道如何阐明问题,为什么需要解决它,以及业务案例和技术案例之间的联系是什么。
第一步是对问题或业务案例进行清晰的定义和理解,然后将其转化为具有可操作步骤和目标的数据科学问题。这包括与业务主管进行清晰、简洁的沟通,并提出足够多的问题,这样就不会产生矛盾的结果。用数据解决问题需要大量的工作,所以你最好第一次就做对。
应该问高管的一个关键问题是,解决问题将如何使公司(或其客户)受益,以及该问题如何融入公司的其他流程。这不仅有助于您和您的团队确定将提取哪些数据集,还有助于确定您将运行的分析类型和您将寻找的答案。
2.数据收集
如果你问了正确的问题,并且对你要解决的问题有一个清晰的想法,你应该做好充分的准备,为这项工作收集正确的数据。
我说你应该做好充分准备,但是数据收集可能会出现各种各样的问题。不是所有的公司都有优秀的数据集,也不是所有的公司都有适合这项工作的数据。在这一步花费的时间比你想象的要多,以确保你从一开始就有正确的数据——同样,这些项目需要花费大量的时间和精力,所以你最好第一次就做对。
此外,收集比你认为需要的更多的数据总是一个好主意。由于其他原因,数据集可能是不完整的或错误的,所以最好有额外的数据以防万一。这样,无论数据质量如何,您的整个项目仍然可以完成。这将只需要你仔细检查数据,以确保你只使用项目中最好的数据。
3.数据清理和准备
正如我在上一步中描述的,一旦你开始用细齿梳梳理原始数据,挑出不完整或错误的条目,收集比你认为需要的更多的数据总是有价值的。
这个过程中反复出现的主题是,你必须第一次就把每一步做对,以减少从头再来的可能性。数据科学就是聪明地工作,而不是努力工作。这意味着为了在过程的第五步中生成正确的模型,您需要适当地清理和准备您计划使用的数据。重要的是要记住,你的模型可能会改变你的公司做生意的方式,这意味着在开发你的模型时,你需要第一次就做对。
您需要注意的一些关键类型的错误数据包括格式不正确的数据、损坏的数据、重复值或空值、极端异常值,甚至缺失数据。
这是数据科学项目生命周期中最长的一步,许多数据科学家会认为这占了项目时间的大部分。俗话说 20%的成果来自 80%的工作在这里听起来很真实。然而,坏的数据会产生坏的模型,这意味着你必须现在就花时间,而不是以后去修复你的错误。
4.探索性数据分析
这可以说是数据科学项目生命周期中的第一个“有趣”的步骤,因为您最终可以编写一些代码,并查看您辛辛苦苦清理的所有数据试图告诉您什么。
探索性数据分析用于总结数据集的主要特征,通常通过开发数据可视化来完成。这些可视化将帮助你快速发现数据中的模式和异常。现在也是你进行假设检验或检查你可能有的或在你与公司高管的最初讨论中提出的任何假设的时候了。你在这一阶段的发现将有助于你以后开发没有假设或错误见解的模型。
在探索性数据分析过程中,您可能会发现自己使用的一些工具是聚类和降维技术、单变量可视化、双变量可视化和汇总统计、多变量可视化、K 均值聚类或线性回归。
需要注意的是,这可能是项目的最后阶段,具体取决于您要解决的业务问题。如果最初的问题是一个简单的置信区间或标准偏差的问题,那么你的项目将会完成,产生一些可视化的结果,帮助主管理解。然而,如果问题本质上更具预测性,那么您将进入循环的最后一步:模型构建和部署。
5.模型构建和部署
现在,您已经进入了数据科学项目生命周期的第二步,也是最后一步。现在是时候将您的数据集分为训练集和测试集,用于开发您的机器学习模型。
在这里,您将确定是否需要创建受监督或不受监督的机器学习模型。监督模型用于对未知数据进行分类,并通过“学习”训练数据中的模式来预测未来趋势和结果。非监督模型用于发现数据中的相似性,了解一组数据中不同数据点之间的关系,并执行额外的数据分析。例如,监督模型可以用来保护公司免受垃圾邮件的侵害,或者预测市场的变化。无监督模型可用于将客户划分到营销环境中,或根据客户之前的购买情况向客户推荐产品和服务。
您的模型可能需要在这里或那里做一些调整,但是如果您已经正确地完成了前面的所有步骤,应该没有任何必要的重大更改。
一旦您构建了一个您满意的模型,它就会被部署到生产环境中。虽然您公司的软件开发团队可能会处理大部分部署工作,但这里有一些提示,告诉您如何让这个过程对他们来说更容易:
最后的想法
虽然数据科学项目的生命周期似乎显而易见,但它并不经常在在线证书或课程中讲授。这使得你所学的技术技能和它们在工作中的实际应用之间出现了巨大的脱节。
然而,通过学习上述基本结构,你将成为一名更全面的数据科学家,你将能够回答任何可能在面试中抛给你的生命周期问题,并且你将能够更好地帮助你的团队准备和交付一个重要的数据科学项目。
订阅将我的故事直接发送到您的收件箱:故事订阅
请成为会员,使用我的推荐链接获得无限制的媒体访问权限(我将收取少量佣金,无需额外费用):媒体会员
通过捐赠来支持我的写作,以资助更多像这样的故事的创作:捐赠
使用 Python 将机器学习项目更快投入生产的 7 个最佳实践
设计可用于生产的机器学习算法的实用建议
马特·里德利在 Unsplash 上的照片
动机
如果没有适当的基础设施、工具和知识,在生产中部署是很难的。在大多数情况下,数据科学家主要参与实验,分析数据并选择最符合用户要求的机器学习(ML)算法。到目前为止,一切看起来都很好。客户很高兴并且迫不及待地想让它的算法投入生产。神奇的词是生产。大家都假设生产是最容易的部分。然而不幸的是,道路仍然漫长。不到 30%的 ML(例如企业 2022 中的 AI 采用)项目最终在生产中成功运行,获得商业价值。为了更快地进入生产阶段,本文提出了一个 7 最佳实践的列表,供数据科学家从项目一开始就考虑。
最佳实践
1.不要混合太多的编程语言
在没有充分理由的情况下,避免在 ML 项目中混合太多的语言(Scala、Python、Java、SQL、Bash)。坚持使用单一的编程语言可以增强团队成员之间的协作,并减少维护时间。
如果你的选择是 Python,那就坚持下去。
例如,在我的案例中,所有混合了 Bash、Python、Java 和 Scala 等几种语言的 ML 项目最终都难以维护,因为团队对 Python 最有信心。最后,我们甚至不得不放弃这个项目,或者用 Python 重写模块。这一努力得到了回报,因为我们在维护上花费的时间减少了,团队有更多的时间关注 ML 和代码质量。
2.您代码版本
教您的数据科学家同事将他们的工作版本化(包括笔记本!).版本控制有助于跟踪所有的代码变更。在实验阶段,我们每天都要进行改进和修正,由于错误的操作或回滚,很可能会丢失我们的部分工作。随着时间的推移,跟踪所有的代码更改会使代码操作变得更加容易。我建议你开始使用 Git 进行版本控制,因为它是最流行的版本控制框架,功能强大,易于使用。在我的案例中,开始使用代码版本控制的数据科学家变得更有效率,也更容易合作。
请在下面找到一个简化的 Git 概述。
作者图片
3.使用 Python 虚拟环境
什么是虚拟环境?这是一个 Python 工具,可以确保依赖性管理和项目隔离。
每当我不得不在 Python 中处理一个任务时,首先,我确保我创建了一个虚拟环境,使开发环境与我的发行版完全隔离。这样,我可以轻松地与团队共享我的应用程序,而不用担心依赖冲突。请注意,在生产环境中,隔离是必须的。
下图显示了 Python 虚拟环境的轮廓。
作者图片
查看第二步在我之前的文章 ,里面解释了如何在 Jupyter 中创建一个虚拟环境并激活它。
4.定义项目结构
不要每次都从头开始创建一个项目。为你的团队提出一个模板项目。它有助于数据科学家和数据工程师同事在 ML 项目之间做出贡献和快速切换。它支持代码组织,并有助于代码调试。例如,我所在的团队中,每个 ML 项目都有独特的结构,很难在项目之间快速切换,当然,新成员也会感到困惑。由于该团队使用了独特的项目结构,该过程是透明且轻松的。
请随意使用开源的 cookiecutter 模板生成器。用法非常简单。
使用以下内容安装软件包
pip install cookiecutter
并使用以下命令启动一个新项目:
cookiecutter [https://github.com/drivendata/cookiecutter-data-science](https://github.com/drivendata/cookiecutter-data-science)
。
Cookiecutter 将要求您提供项目名称、存储库名称、作者、团队、组织、许可类型以及您计划使用的 python 解释器。见下面我的配置。
转到生成的目录:
**cd ds-template**
生成的项目结构如下所示:
https://github.com/drivendata/cookiecutter-data-science
5.识别 Python 开源库
我建议花一些时间选择适合您的 ML 项目的 python 库。选择稳定、安全和通用的库。我处理过团队由于基于亲缘关系而不是团队策略的库选择而产生分歧的情况。因此,我最终会浪费时间去维护生产中被弃用的或不稳定的库,只是因为它们有很酷的特性。
请查看我的以下建议:
代码分析&格式化:
F lake8 :执行静态代码分析,根据 PEP8 、错误和圈复杂度检查您的代码风格。
Pylint:执行静态代码分析,查找错误,检查名称约定,代码气味,并提出重构建议。
黑色 格式化代码。
测试你的代码:
Pytest是一个功能强大且易于使用的测试框架。
覆盖率 测量测试覆盖率。
安全分析:
Bandit 寻找常见的安全问题,将代码转化为抽象语法树(AST)。
安全 检查 Python 依赖关系中已知的安全漏洞。**
Clair 寻找 docker 容器中的安全漏洞。
6.为所有项目定义一个简化的 Git 工作流
什么是 git 工作流?它定义了管理 Git 分支的策略。
复杂的分支系统需要掌握版本控制的机制,这在团队层面上很难实现。因此,数据科学家往往缺乏代码版本管理经验,我建议使用一种简化的策略来管理 Git 分支,如下所示:
作者图片
主分支 —是默认分支。这是生成新的 Git 存储库时创建的第一个分支。在旧版本的 Git 中,您可能会发现“ master ”这个名字。每当一个代码新特性或者一个 bug 被合并到主分支时,推荐自动生成一个标签(版本)。该分支包含可以在生产中自动发布的生产就绪代码。
功能分支&热修复分支** — 都是临时分支。特性分支是为了开发产品的特性。*hot fix 分支是用来快速修正 bug。一旦开发准备就绪,代码应该被合并到主分支中。*****
实现一个简化的 git 工作流帮助我的团队一致地利用 git,并且高效快速地交付(管理更少的 Git 冲突)。
7.强制 Python 代码质量
代码质量代表了所开发代码的可维护性和功能性。
从短期和长期来看,代码质量非常重要。意识到代码质量实践帮助我交付易于维护和调试的现成 ML 代码。
为了提高代码质量,您应该考虑以下建议:
尊重PEP 8的风格和命名约定。****
****避免长代码行。
尽量让可读,模块化代码。****
usedoc strings。****
避免使用通用名称,如 data_XXX、dictionary_XX 等
使用 测井 ,用测井代替打印。
使用棉绒和自动套用格式。就我个人而言,我很欣赏 lintersflake 8/Pylint和 auto formattersKite/Tabnine。****
记录你的代码。 更多详情可以参考我的教程 。
重述
为了加速将 ML 项目转化为产品的过程,了解行业最佳实践并加以利用是至关重要的。
在本文中,我讨论了使用通用编程语言、代码版本控制、标准项目结构、虚拟环境、简化的 git 工作流、众所周知的 Python 库和 Python 代码质量标准的重要性。
感谢您的阅读!
如果你想在收件箱里收到我未来的故事,别忘了订阅。
如果您喜欢阅读我的故事,并希望支持我成为一名作家,请考虑注册成为 Medium 会员,并获得数千篇数据工程和数据科学文章。
*****https://medium.com/@anna.bildea/membership
查看我收集的 MLops 文章
比尔迪亚安娜
MLOps
View list4 stories*****
招聘人员在理想的数据科学候选人身上寻找的 8 种品质
以下是如何培养有助于你的申请脱颖而出的品质
穆罕默德·诺哈西在 Unsplash 上的照片
获得一份数据科学领域的工作有时感觉就像蒙着眼睛向董事会扔飞镖——有时你在申请中远离董事会,甚至没有得到一次初步面试,有时你接近靶心,但在技术面试中并不完全符合候选人的模式,有时你击中靶心并获得一份工作。
有时蒙着眼睛扔飞镖时,你的表现没有任何规律或原因。
这意味着,当你去参加一个有数百名应聘者的工作时,你可能会感到不安、沮丧和疯狂。你知道我说的是什么类型的工作——一家拥有数百名数据科学家、渴望自己的机会被发现的中型公司的基本入门级职位。这可能是你申请的那种工作,因为你并不真的相信你会得到它。
然而,如果你知道招聘人员在寻找什么呢?如果你知道你可以通过向招聘者展示他们想要的东西来提高你的掷镖能力,那会怎么样?如果你知道在数百名可能的候选人中,你和少数其他人是真正的竞争对手,拥有招聘人员渴望在他们的团队中拥有的所有品质,会怎么样?
你可能会更加自信地进入申请程序,不是吗?
在过去的几个月里,我关注了 LinkedIn 和 Reddit 上的招聘人员帖子,这些帖子概述了他们在寻找理想的数据科学候选人方面的努力。来自不同背景、方法和公司规模的招聘人员都报告了与候选人相同的问题。从这些描述中,我已经能够根据招聘过程中注意到的差异,将数据科学候选人应该具备的理想属性放在一起,并将这些属性与我个人经验中的建议结合起来,您可以使用这些建议来实现这些属性。你的求职过程将不再涉及蒙着眼睛扔飞镖-你只需要专注于发展这八个属性,以帮助你成为招聘人员正在寻找的全面的数据科学候选人。
1.一份最近的,准确的简历
据估计,40%的求职者在简历上撒谎,四分之三的招聘人员发现有人在简历上撒谎。考虑到数百名候选人可能同时申请同一个数据科学职位,这些数字相当可观。简历中最常见的谎言包括教育程度、为前雇主工作的时间以及过去的薪水。进一步的谎言可以发现,候选人夸大了影响数字(例如将一家公司的数据管道效率提高了 75%),使用了不准确的职位名称,谎报了他们的技术能力,声称编程(和口语)语言流利,甚至使用了假地址。
因此,这里的关键是始终向招聘人员提供一份最近的、最新的、准确的简历,这份简历在设计时考虑到了职位描述,代表了你目前的资历,没有谎言或其他会让你无法获得工作的信息。这听起来很容易,但当你申请数百份工作时,有时很容易陷入陷阱,向所有公司发送相同的简历,并希望其中一个能坚持下来。
每次我申请一份工作,我都会精心制作一份独特的简历,保留与工作相关的部分,并重新措辞各个部分,使它们更适用于公司。除非申请需要,否则我很少写求职信,相反,我会尽可能地专注于写一页最好的信息。我还关注非图形简历,以确保它在申请过程中不会遇到解析问题。招聘人员只会给你几秒钟的简历,所以我尽量让简历简短、甜蜜,重点关注我产生影响力的能力,而不是我获得的证书或完成的课程。
如何改善这一点
花时间为每份工作制作一份量身定制的简历是至关重要的。这不仅表明你对工作要求有所了解,也向招聘人员表明你关注细节并真心想要这份工作。你的简历应该包括所有相关的工作经历,你过去的教育,你已经完成的证书,以及一份与工作相关的个人项目清单。
</5-things-in-your-resume-that-are-keeping-you-from-getting-your-first-job-in-data-science-1a4d474ff3e4>
2.通讯技能
当我在大学学习软件开发时,我成为团队项目中最受欢迎的成员,因为我是能够向广泛受众传达我们项目价值的演示者。
我的第一份工作是在技术领域,因为我有高超的书面沟通技巧,可以向非技术客户和潜在客户解释技术概念,以及为什么他们会给公司带来好处。
在我从事技术工作的整个过程中,我处于与客户沟通的第一线,因为他们觉得与能够在他们和技术团队之间沟通的人交谈很舒服,以确保业务问题被正确地转化为技术案例,反之亦然。
简而言之,我通过交流技巧达到了我在技术领域的位置。
数据科学招聘人员特别寻找那些知道自己在做什么,并能在面试中回答各种适用于日常工作的问题的候选人。例如,招聘人员正在寻找能够在技术面试中回答问题的候选人,这些问题涉及他们正在做的事情,远远超过“哦,我不知道,可能在文档中”。
如何改善这一点
不幸的是,在传统的数据科学学习途径中,沟通技能没有得到重视或教授,这意味着在这一领域取得成功的候选人天生就具备这些技能。虽然沟通课程通常是大学或学院课程的一部分,但 2-4 年的一两门课程通常不足以让你成为一名合格或舒适的沟通者。
因此,培养更好的沟通技巧的唯一方法就是练习。我最喜欢的练习方式是告诉我非常嫉妒的狗我正在做的每件事,从为什么我以我的方式写代码到为什么我使用这个数学构造而不是另一个。像参加技术面试的招聘人员一样对待我的狗,不仅是练习交流我正在做的事情的好方法,还能让你在工作时跟上谈话的节奏。我和许多只会在完全沉默中编码的人一起上学。即使停下来描述他们在做什么也会让他们迷惑,因为他们从来没有练习过。
虽然一些公司可能不介意你是否能描述你正在做的事情,但他们肯定希望你能在最后给出一个完整的概要,并能描述性地回答他们抛给你的任何问题,除了“哦,我肯定你能在文档中找到这些”。
3.确保你拥有支持这项工作的技能
因为科技行业对工作要求和不要求证书的比例在下降,所以你必须拥有支持这份工作的技能,不管你的证书是否符合要求。这通常是为什么一个数据科学职位会有数百份申请的原因,因为该领域并不总是需要证书,任何人都可以申请该职位。
这导致许多申请人尽管申请了,却不具备支持这份工作的技能。因为说实话,我们中有多少人在申请工作时声称自己是 Excel 专家,却对 SUM()一无所知?
招聘人员似乎遇到了许多人不具备该工作所需技能的例子(见上面关于在简历上撒谎的第一点),这意味着虽然一份工作可能有数百名申请人,但实际上可能只有 10 名左右的候选人。
幸运的是,工作所需的技能总是在工作描述中有很好的概述,这可以给你的学习提供一个良好的起点。
如何改善这一点
鉴于你正在阅读这篇文章,我可以假设你要么是一名训练有素的数据科学家,试图了解招聘人员在寻找什么,要么是一名研究数据科学的人,试图了解招聘人员在寻找什么,以便你可以定制自己的学习体验。从这些假设中,我已经可以判断出你可能具备你所申请的工作的技能。
这里出现的真正问题是申请数据科学工作的人在该领域没有真正的技能。
不要做这个浪费招聘人员时间的人,只要读一下职位描述,确保自己具备所需的技能就可以了。我最喜欢的活动之一是阅读职位描述,看看公司在某个特定时间需要什么。如果我没有他们需要的所有技能,我会列一个清单,然后开始学习其中的一些。我对我看到的所有招聘广告都这样做,这样在学习过程结束时,我就能很好地申请我遇到的任何数据科学工作。
不确定从哪里开始?尝试以下资源开始:
</5-data-science-skills-that-will-never-become-outdated-6c9de1e60d88>
4.质量跟踪记录
我以前说过,现在再重复一遍:招聘人员只寻找那些有能力在加入团队的那一刻对公司产生影响的候选人。其中一个关键的决定因素是候选人的质量记录。
除了招聘人员正在寻找从一开始就能做出高质量工作的团队成员,不管你是第一份工作的入门级数据科学家,还是进入中层管理职位的经验丰富的老手,这里没有太多要说的了。
根据我的经验,提供正式或非正式的工作样本是展示工作质量的正确方式,尤其是在你刚开始工作的时候。虽然招聘人员可能不得不相信你,因为你没有推荐信,但你的工作质量应该能够说明一切,并提供你需要的高质量推荐信。
如何改善这一点
证明你的质量记录的最好方法是通过一堆来自以前的导师、团队成员和雇主的热情洋溢的推荐信。
如果由于你刚开始在这个领域工作,这是不可能的,你将不得不通过项目和作品集来展示你的工作质量。你的作品集是招聘人员能够通过阅读你的项目的影响和看到你写的代码和文档的水平来跟踪你的质量的方式。
5.适应性
数据并不总是好的,业务问题并不总是清晰的,工具也不会年年相同。
数据科学家必须是适应所有这些事件和更多事件的大师。招聘人员正在寻找那些能够随机应变、不需要原始工作环境的候选人。
如何改善这一点
大学数据科学项目的问题是(如第 8 点所述),它们经常给你简单、干净的问题去解决,在那里数据不是真的一团糟,问题是清楚的,并且你有一套你在过去四年中一直在使用的工具。
这意味着,要成为一名适应性更强的数据科学家,你必须找到最糟糕的数据集、最不清楚的业务问题,并使用一种不熟悉的工具将其整合到一个连贯的分析中。这将是你作为一名数据科学家发展自己适应能力的唯一途径。这并不有趣,但它会让公司抛给你的任何问题看起来像小菜一碟。如前所述,实践将是帮助你发展这项技能的最好的朋友。
将这些项目添加到你的投资组合中是一个很好的方式,可以向招聘人员展示你愿意做艰苦的工作,并且你可以在不利的条件下取得成果。谈论这些项目也可以让招聘人员了解你的思维过程,以及你如何通过适应环境来解决复杂的问题。
6.实用主义
“《务实的程序员”是一本如此好的书名,这是有原因的:它指的是一个程序员,他能够以基于实用性的方式理智地、现实地解决问题。
刚接触数据科学的人往往会沉迷于理论。这会分散对一件简单事情的注意力:完成项目。在一天结束的时候,最重要的是保持你的代码简单,确保你的项目为公司增加价值,并且一点一点地完成任务。如果代码太复杂而无法重构,没有人会关心你的代码风格,也没有人会关心你的项目是否包含破坏其预期目标的特性。与其他技术学科不同,数据科学是关于简单、准时地完成工作,同时讲述一个客户和 C 级高管将理解并遵守的故事。
招聘人员正在寻找实际、明智、现实和有决心的数据科学家。为什么把已经很难的工作做得比必要的还要难?仅仅因为你能,并不意味着你应该。招聘人员将寻找能够实际解决问题并得出结论的候选人,这种结论能够清晰、完整地描述数据所代表的内容。虽然这是您可以展示您的实际编程的时候,通过使用一行代码而不是两行代码来完成工作,但这不应该以项目为代价。
换句话说,扔掉所有你不需要理解就能完成工作的理论,转而关注实践方面——这个数学结构对我试图回答的问题有用吗?这些代码可以被发送到生产环境中吗?如果我使用这种可视化,涉众会理解数据的重要性吗?
如何改善这一点
完成 2 年技术文凭课程或训练营的个人很好地学会了实用主义,因为这些学习机会通常由在行业中花时间磨砺自己的牙齿并真正使用自己技能的讲师教授。对于那些完成了大学学位的人来说,实用主义可能会半途而废,而这些大学学位的授课教授可能从未见过他们的教学楼外面。
实用主义是一种可以自学的东西,实际上可以归结为每次你着手一个新项目时问自己这个问题:我完成这个项目所需的最起码的信息基础是什么?然后,从工具箱中拿出所需的工具:例如 Python 及其包、MySQL、线性回归和 Tableau。
不多也不少。这是完成一个项目所需要的最低限度。
是的,你可以进入可视化设计的本质,或者争论这种类型分析的线性回归的优点,直到狗回家,但是在一天结束时,你需要开始工作,无论一切是否完美。如果事情需要微调,那就这样吧。但是最重要的是你要开始。我记得和一些人一起上学,他们很难开始项目,因为他们的预先计划不是绝对完美的。虽然我相信 10 分钟的计划可以节省 10 小时的项目返工时间,但我也明白,在数据科学的快节奏世界中,有时你只需要开始。所以,从实际的、明智的、合理的开始,剩下的就会水到渠成。
7.诚实和谦逊
没有这些属性,学习是困难的,甚至是不可能的。
当招聘人员寻找数据科学家加入他们的团队时,他们寻找的是仍然能够到处学习新技巧的人。数据科学家对其公司的价值是通过他们在解决业务问题方面提供的影响来衡量的。因此,跟上新技术的能力,理解你所在行业出现的新问题的能力,以及学习新东西的能力都是需要一些诚实和谦逊的技能,这将让你对你的公司产生影响。
不仅如此,数据科学家还需要诚实和谦逊,承认他们的分析可能不是最好的,甚至是错误的。没有这些属性,成长和学习就不可能发生,这意味着招聘人员正在寻找一个能够长期作为数据科学家与公司一起不断成长的人。
如何改善这一点
我最喜欢的锻炼我的诚实和谦逊的方式是参与代码评审和项目后报告。没有什么比听到自己到底做错了什么以及如何做得更好更能帮助你成长的了。代码评审是从您的同事那里获得关于尝试不同技术或备选方案的输入的完美方式,以帮助您的代码更好地适应生产环境,而项目后报告帮助您了解您的工作如何适应整个项目的更大画面。当你只做一个大项目的一小部分时,这尤其有用。
除此之外,作为一名数据科学家,成长的唯一途径是对自己在该领域的技能进行持续的自我提升。新技术总是不断涌现,它们总是在 MOOCs 中教授一些新的东西,可以帮助你成为更好的数据科学家。关键是要把改善自己作为你每日计划中的优先事项。
</7-ways-to-stay-up-to-date-as-a-data-scientist-a505fb0cc61b> </6-habits-to-include-in-your-daily-routine-for-a-long-happy-career-as-a-data-scientist-de733eae6250>
8.将业务问题转化为分析的能力
你在大学或数据科学训练营中要解决的业务问题非常干净、清晰、简单,并且几乎给出了如何解决它们的答案。
然而,一旦你进入工作世界,你会意识到你在那里发现的商业问题很难转化为分析。有时数据很糟糕,或者客户不知道他们真正想要的是什么信息,或者可能会被扔进你的项目组合中的各种各样的扳手。
招聘人员希望你能够清楚地了解客户在寻找什么,确定你拥有的数据是否可以用来解决问题(如果不能,你需要从客户那里得到什么数据),以及你如何从数学上做出正确的分析,来回答客户的问题。这意味着能够解决客户相关问题、优化问题、预测问题等等。有时候,客户不知道他们想要什么,会要求你解决上述所有问题。你的工作是找出真正的商业案例是什么,并向他们解释为什么,以及你的分析将如何提供他们想要的结果,以改变他们公司的发展轨迹。
记住:招聘人员希望你在与客户打交道时能够专心致志、注重细节,同时愿意告诉客户他们真正的业务问题是什么。
如何改善这一点
更好地将业务问题转化为分析的唯一方法是亲自动手去做。无论这意味着使用互联网上无数可用数据集中的一个来解决您自己的业务问题,为您所在地区的小型企业做公益工作,还是在您的数据科学团队开始新项目时卷起袖子,主要重点都应该是让您尽可能多地接触不同类型的数据科学问题。
订阅将我的故事直接发送到您的收件箱:故事订阅
请成为会员,使用我的推荐链接获得无限制的媒体访问权限(我将收取少量佣金,无需额外费用):媒体会员
通过捐赠来支持我的写作,以资助更多像这样的故事的创作:捐赠
人工智能艺术辩论:兴奋、恐惧和伦理
原文:https://towardsdatascience.com/the-ai-art-debate-excitement-fear-and-ethics-c04d30f338da
意见
看看围绕人工智能生成的图像及其对艺术家的影响的伦理辩论。
由作者执导的《旅途中》图片。
像许多人一样,我一直在关注人工智能工具在 2022 年的爆炸式发展。中途、稳定扩散、 DALL E 、 ChatGPT 和许多其他工具都是使用机器学习模型(为了简化和 SEO,我称之为“AI ”)的工具,这些模型在大规模数据集上训练,根据人类提供的文本提示、参数或图像的组合来生成独特的图像或文本。
当它运行良好时,感觉就像魔法一样。感觉太容易了。
文化战争
自从 DALL E 和 MidJourney 吸引了主流的注意力,在艺术和技术世界的交汇处就有了一场激烈的辩论。这场辩论主要围绕人工智能生成的图像对工作艺术家的负面影响展开。这场辩论感觉完全两极化,双方的声音在很大程度上互相超越。这感觉就像是“艺术家与科技兄弟”的对决,与去年 NFT 的演讲很相似(有很多重叠的声音)。
并不是所有的“中间派”,但我觉得有点夹在这些阵营中间。我想,这是一种谨慎的乐观主义,带有一大堆警告和担忧。我已经使用 Midjourney 生成了 4000 多张图片,其中一些我很喜欢,许多图片很糟糕,但我也认为目前该行业的许多做法相当粗糙,而且存在问题。
我将尽我所能总结一些我认为有根据并值得深入讨论的观点,同时指出一些我认为没有根据或被误导的观点。这并不是一个详尽的问题列表,我可能会在以后写更多的内容。
什么是艺术?
不知何故,这是开始的最好和最差的地方。试图给艺术下定义是一项有趣的理论工作,具有很大的价值,但我认为达成一个共同的艺术定义是毫无意义的,并且不可避免地以排斥性大于包容性而告终。
我希望我们都能同意,艺术对很多人来说可以是很多东西,而且是最重要的,主观的。两个人对贴在墙上的香蕉是否是“艺术”意见不一,这没什么。
一件艺术品可以在头脑中有一个意图(或者根本没有意图)的情况下创作,然后用另一种观点来解释。它可以是美观的,也可以是丑陋的。它可以是一种劳动密集型的磨练和实践的工艺,也可以是一个短暂的想法的快速草图。它可以是随机性的表现。我不认为某样东西需要有特定的意图,或者很难或很费时才能被认为是艺术。
许多人(肯定不是所有人)似乎承认,人工智能生成的图像在许多情况下可以被视为一种艺术形式,但更有争议的问题是,在这种情况下,谁是艺术家或作者?人类,人工智能,两者都有(但是在什么角色和什么程度上),或者以上都没有?
作者和信用
我不认为自己是艺术家。我是个设计师,这是我谋生的方式。当然,像许多人一样,我以前也创作过我认为是艺术或本质上是艺术的东西。我写过音乐,但不要称自己为音乐家。我拍过照片,但我不称自己为摄影师。我每天都做饭,但我不是厨师。
我用 Midjourney 创作图像,但我不是艺术家。
有一个非常合理的论点是,当涉及到作者和信用时,人工智能生成的图像应该被区别对待。欺骗人们,让他们认为你比实际上更多地参与了某件事情的创造,是不会有任何收获的。
关注我一段时间的读者会知道,我更多地使用生成的图像作为我文章的编辑类型图像,而不是免费的库存照片。我享受这个过程,还有那种乱七八糟的不完美的审美。
我经历了几次迭代,试图找出一种合理、透明、公平的方式来评价这些。在交谈中,我试着用不同的方式和人们谈论这件事,最终根据我使用的语言产生了不同的感受。
- 我创作的一些艺术作品感觉是最卑鄙的。
- “我生成的图像”稍微好一点,但没有上下文仍然不透明。
- 基于我的提示和迭代而生成的中途图像过于机械,谁会这么说?
比如改变你谈论任何事情的方式(比如从说“伙计们”转变为“伙计们”),一开始会觉得奇怪和尴尬,但随着时间的推移会变得越来越自然。
幸运的是,在对话之外,演职员表不需要听起来像对话。
我目前在该上下文中使用的行是:
由作者执导的《旅途中》图片。
以前的一些尝试是“作者的图像,由 Midjourney 生成”,暗示 Midjourney 只是一种工具,就像 3D 艺术家可能会说“作者的图像,在 Zbrush 中雕刻,在 Substance Painter 中纹理化”。我回避了这个问题,因为我坚信这两者根本不等同。艺术指导感觉更像是一个平行的东西,尤其是像“修复”这样的工具,它允许你替换图像的特定部分,并且更细粒度的即时迭代继续发展。
讨论应该继续,人们应该尝试他们觉得好的东西,和不会让其他人觉得被贬低。无论结论是什么,在我看来,目前“由[你的名字]”独自一人是不道德的,不管你对这个领域的热情或怀疑态度如何,都应该予以劝阻。
分门别类
继续这一思路,目前我认为人工智能图像应该在任何展示艺术的网站上有特定的人工智能类别、标签或区域,当然在任何类型的艺术奖项中也是如此。在比赛环境中比较艺术,并决定一件艺术作品比另一件“更好”的想法对我来说有点困惑,但最终它帮助并支持了艺术家。艺术家作为一个群体,对社会有着巨大的、被大大低估的积极影响,这种影响在薪酬或知名度方面没有得到足够的体现。
我们不应该继续围绕那幅在科罗拉多州博览会艺术竞赛中为杰森·艾伦赢得几百美元的中途作品引发的争论。从一个明确的“人工智能艺术”类别开始,并从那里开始。
我们经常对摄影这样做,有时(尽管越来越不常见),对数字艺术也是如此。这样,关心它的人就可以关心它,其余的人就更容易忽略它。
使市场饱和
另一个主要问题是,包含艺术家姓名提示的图像(例如“以格雷格·鲁特科夫斯基的风格”)随后被发布在网络上,并且是可抓取的,从实际的艺术家那里窃取 SEO,并使人们在搜索由真人格雷格·鲁特科夫斯基创作的实际艺术时感到困惑,这可能是许多艺术家的主要收入来源。
“刚刚过了一个月。一年后呢?我可能无法在那里找到我的作品,因为(互联网)将被人工智能艺术淹没。这令人担忧。”——Greg Rutkowski,接受《麻省理工科技评论》采访
不道德的数据使用
在我看来,最大的问题是如何收集和使用源数据的道德问题。目前,许多模型完全或部分使用数据集(如 LAION5B)作为其源数据。LAION 从数十亿张图片和相应的文本描述中创建了巨大的数据集,这些图片和文本描述是由一个名为 Common Crawl 的非营利组织从 alt-text 和 web 链接中收集的。这些数据集的明确意图是用于研究目的,而不是商业应用。
鉴于这些数据集的庞大规模,它们包含了大量有版权的图像,以及属于活着的、正在工作的艺术家(或其他人)的图像。
这些由 Common Crawl 搜集、由 LAION 曝光的图像最初是由各自的作者发布的,具有广泛的预期用途,但可以肯定地说,“训练机器学习模型让自己失业”并不是一个共同的意图。
常见到艺术家暗示生成的艺术是抄袭或窃取他们的作品。这被比作“搜索谷歌图片”并冒充自己的作品。我认为这是一种过于简化、不准确的描述机器学习模型如何生成图像的方式,但这并不特别重要,因为它并不真正影响解决方案。
我认为人工智能图像唯一真正合乎道德的前进方式是创建一个开放的训练数据集,人们可以主动选择加入。财务方面需要解决,但最初提交用于训练数据的图像可能会有小额付款,可能会有某种基于明确使用艺术家姓名的提示的版税系统(以及商业作品中使用的任何东西的高得多的版税)?这可以通过某种 CC-BY 类型的许可证来扩展,这种许可证明确用于 AI 训练数据,以某种方式通过图像元数据公开。
也许像这样的系统增加了一个更精确的开放数据集,该数据集排除了来自 Behance、Dribbble、ArtStation、DeviantArt 等来源的数据。,但仍然可以学习诸如“这是人类的样子”,“这是树的样子”之类的东西。
注:ArtStation 最近因没有做足够的工作来保护艺术家的利益而受到艺术家 的攻击 。ArtStation 以“ NoAI ”标记倡议做出了回应,该倡议允许用户选择退出在训练模型中使用他们的作品,但选择退出还不够,社区正在让他们知道这一点。
最后
这个空间正在快速移动。技术进步可能令人兴奋(尤其是那些感觉像魔术一样的),但人们和整个行业可能会在这个过程中受到伤害。在许多情况下,比如从煤制天然气到可再生能源的转变,技术进步在很大程度上是积极的。对抗气候变化的好处与失业的人力成本或行业利润相比是很容易证明的。
不过,这里的情况不一样。被淘汰的人只是艺术家,用机器整体取代艺术家对人类来说是负面的。我们应该考虑如何使用这种技术来增加和增强工具,帮助创造新的美学,但要着眼于以人为中心,保持他们所有的想象力、意图和复杂性不变。
总的来说,我认为人们应该考虑以下几点:
- 让 Midjourney、LAION 和 StabilityAI 这样的公司知道一个替代的、伦理的数据集需要被投资。如果你在这个领域工作,倡导它,建设它。这是一个有待解决的有趣问题。
- 在用于非商业用途时,对人工智能生成的图像进行适当的认证和标记。在这个过程中,不要夸大你的作用。
- 不要提示使用艺术家的名字。句号。
- 互相倾听。面对批评时要尊重,善意地给予批评。仅仅说“我不认为这里有道德问题”是不够的。这并不总是关于你。如果别人说有道德问题,那是有道理的,你应该考虑听他们的,多读一些。
- 寻找帮助人们从人工智能艺术过渡到传统艺术的方法。吉他英雄激励了许多人(包括我在内)学习吉他,这是一个帮助人们从人工智能一代过渡到实际技术的机会。解构人工智能图像的美学,什么可行,什么不可行,以及你可能如何使用其他技术来接近相同的图像。
- 支持你喜欢的艺术家。购买印刷品,分享他们的作品,支付佣金。支持概念艺术协会,该协会正在游说帮助保护艺术家免受人工智能技术的侵害。
感谢阅读。如果你对此感兴趣,请考虑订阅剪辑内容,每周撰写关于设计系统、技术、领导力的文章,并直接发送到你的收件箱。
人工智能时刻
原文:https://towardsdatascience.com/the-ai-moment-12761189b87d
为什么人工智能的进步比以往任何时候都更让我们兴奋。
米拉德·法库里安在 Unsplash 上拍摄的照片
随着我在斯坦福大学与各种令人印象深刻的人工智能研究人员相处的时间越来越长,我注意到这些人对自己领域的突破做出反应的方式有些奇怪。他们的脑海中似乎总有一个声音告诉他们永远不要太兴奋。机器学习模型可以做竞技编码?好的。他们能写校样?那很有趣。当我在高中的时候,我经常听说这些里程碑,并对未来充满希望。但当我成为一名圈内人士时,我注意到研究人工智能的人并不真的那么喜欢它。
我想你不能指望任何人对他们花费一生探索和思考的模型的微小改进或修改感到如此兴奋,但我私下怀疑还有别的事情在发生。
自 20 世纪 50 年代以来,人类一直在远离人工智能(AGI)5 年和远离 AGI 100 年之间摇摆不定。引用海明威的话,人工智能的进步是“逐渐地,然后突然地”发生的。有一些新技术改变了我们对待人工智能的方式,我们将它应用于我们能想到的一切,然后我们会被困 10-20 年。冲洗并重复。这已经让位于 20 世纪下半叶的两个历史性的“人工智能冬天”,在这段时间里,很少资源或注意力进入人工智能。
研究人员悄悄地担心,尽管我们近年来取得了巨大的进步,但我们最终会发现自己处于另一个冬天。根据正在取得的进展类型,有理由这样认为。今天,大多数导致强大新模型的新想法实际上都是基于深度学习成为主流之前所做的工作。例如,强化学习和卷积神经网络,这两个当今非常热门的话题,分别是在 20 世纪 60 年代和 80 年代发展起来的。这些方法只有在 1986 年发明的现代硬件、数据和反向传播下才变得可用。因此,从研究的角度来看,很容易看出,与过去 15 年相比,用新资源复兴旧思想将更难产生新的创新。
但我有不同的观点,因为我真的还是那个高中生,一想到能像人类一样思考的计算机,我的心就开始狂跳。我并不认为我们需要进一步创新。我们将被同样的宏观趋势所推动,这些趋势已经将我们带到了现在:更多的数据,更便宜、更快的计算。
在未标记的数据上预先训练模型使模型能够访问指数级的更多信息。随着研究的成熟,预训练方法将让我们更多地利用这些信息。随着互联网扩展到世界上最遥远的角落,数据将不断积累,这种趋势将继续并加速。为了从所有这些数据中保留信息,我们需要大量的参数。要在大量数据上训练大量参数,需要做大量的矩阵乘法。幸运的是,摩尔定律可以说是近代史上最强劲的趋势之一。计算将继续变得更便宜、更容易获得、更快。更多的数据,更多的计算,更好的模型。
我的意思不是说我们明天或在未来 x 年内会有 AGI,或者类似的事情。我只想说,有理由对机器学习模型的成就感到真正兴奋:我们不再需要依赖科学家和爱好者的智慧来期待机器学习的进步,我们所需要依赖的只是使用互联网的人和正在生产的计算机。我们已经进入了一个不可战胜的人工智能的夏天,被类人的一般智能所包围。
*神经网络中注意力的想法是这种趋势的一个非常重要的例外。
如果你喜欢这篇文章,请考虑给 和一个跟随 !
一个小国在全球巨人中的人工智能定位以及人工智能系统与人类的未来互动——蒂博尔·博斯教授深度访谈
引领人工智能(AI)发展和应用的国家将塑造技术的未来,并显著提高其经济竞争力。与此同时,落后者可能会遭受损失。
美国已经成为人工智能的早期领跑者,但中国正在挑战它的领先地位。与此同时,欧盟继续落后,在欧盟国家中,荷兰缺乏研究成果。人工智能研究人员在所有研究人员中的比例远低于平均水平,其对全球人工智能研究的贡献也是如此。然而,2013 年至 2018 年间,荷兰的人工智能出版物增长了 115%,是全球增长最快的国家之一(仅次于美国和日本,分别增长了 151%和 135%)。此外,荷兰的平均引用影响得分为 2.08,是全球人工智能研究质量最高的国家之一(仅次于美国、加拿大和英国,分别为 2.63、2.19 和 2.09)。许多小国面临与荷兰类似的问题,因此可以借鉴荷兰的案例。
在与 Tibor Bosse 教授的采访中,我们评估了荷兰人工智能的现状以及人工智能系统与人类之间的未来互动。Bosse 教授是 NL 人工智能联盟战略团队的成员,该团队旨在通过激励、支持和组织荷兰的人工智能活动来加强荷兰的地位。此外,他是 NWA 路线大数据的名义领导人,也是 BNVKI 的代理主席。在他的研究中,Bosse 教授专注于社交人工智能,即人类和人工智能之间的互动。
【Bosse 教授,荷兰的 AI 玻璃杯是半满还是半空?
你在介绍中已经相当准确地描述了情况。的确,对全球人工智能研究的贡献百分比并没有那么大。但是我们的引用的影响在各种列表和排名中仍然是最高的。此外,玻璃的完整部分也与荷兰的 AI 研究在历史上一直非常强大有关。与许多其他国家不同,人工智能作为一个领域已经存在了 30 多年。如果你看看 BNVKI,我们的协会,我们最近庆祝了 40 岁生日。这表明我们已经活跃了几十年。由于历史悠久,这个领域组织得相对较好。此外,我们对人工智能的哪些分支学科位于哪里有很好的概述,我们知道我们的优势,我们有良好的基础设施,我们有很长一段时间的强大教育。后者是荷兰区别于其他国家的一个显著区别。我们有明确的教育,人工智能不仅仅是计算机科学的一个分支学科,而是独立存在,长期以来在各种排名中得分很高。
原则上,这使我们处于有利地位。然而,发展如此之快,以至于人工智能的定义与 30 年前完全不同。例如,这些投资与美国和中国等其它国家不可同日而语,与它们竞争是艰难的。那是玻璃杯的空的部分。
最终,我是乐观的,所以杯子是半满的。
NL AI 联盟(NLAIC)和策略团队是什么?
NLAIC 是一个大型的公私合作项目,旨在加速和连接荷兰的人工智能发展。它涉及荷兰政府和数百家致力于人工智能发展的公司、知识机构和社会合作伙伴。我们的口号是‘适合所有人的算法’,强调让人工智能变得可及的目标。当我们在 2019 年成立时,我们的目标是刺激荷兰的经济增长,并使荷兰成为人工智能强国。最近,NLAIC 向荷兰国家增长基金提交了一份投标,并获得了一大笔预算,用于在从基础研究到应用的整个知识链上投资人工智能。
我们将为未来几年制定的战略与战略团队保持一致。然而,我们的作用只是提供咨询,我们没有决定权。我在战略团队中的角色是代表科学领域,这是我和另外两名代表一起做的。
增长基金分配的资金帮助我们实现目标。然而,这也是我们必须与整个国家分享的钱。所以我的目标是确保研究预算用得其所。
战略团队目前提出了哪些问题?
战略团队就战略、政策、利益相关者管理和投资激励准备等问题提供建议。此外,我们对照其目标评估 NLAIC 活动的进展。我们的许多问题都与金融工具有关,比如对增长基金的竞标。例如,我们重视吸引新人才,这对学术界至关重要。我们必须为“人才外流”提供答案,即学术人才离开荷兰学术界,去国外或行业中获得更好的职位。我们的奖学金计划是一种金融工具,旨在让大学留住或吸引有才华的人工智能研究人员。此外,我们还有欧洲水平的金融工具。除了关注 AI 的技术方面,我们也很看重 AI 的人性一面。因此,最近已向 ELSA(道德法律社会方面)实验室拨款。最后,我们组织活动来联系社会和荷兰公民。
NLAIC 专注于五个构建模块。您能描述一下这些建筑模块以及荷兰的现状吗?
NLAIC 旨在将其活动分为五个主题:人力资本、研究和创新、数据共享、以人为本的人工智能以及创业和扩大规模。这些构件对于社会和经济应用领域的突破性影响至关重要。每个构件都有自己的工作组,参与者在其中应对跨部门的挑战。例如,数据共享工作组旨在打破共享数据的障碍。没有数据,机器学习是不可能的,可用的相关数据量越大,预测价值越好。然而,在荷兰,数据通常被锁起来,主要是出于法律或商业原因。因此,工作组旨在更好地负责任地组织数据共享。同样,其他工作组也试图应对其他相关挑战。
Rathenau 研究所发表了一份报告,比较了不同国家的人工智能优势和重点领域。是什么驱动着一个国家的焦点?
每个国家都不一样。在荷兰,这主要是一种自下而上的方法。传统上,一些大学在某些领域很强,并继续关注。有一些群体一直专注于机器学习,现在已经转向深度学习。其他人有自然语言处理的优势,但代理系统和逻辑也是一些荷兰大学的强项。
总体而言,议程制定机制存在显著差异。在美国,许多创新都是由大型科技公司推动的。而在中国,政府的目标是到 2030 年成为全球人工智能的领导者,并相应地投入资金。相比之下,欧洲没有遵循这两种方法,这或许可以解释为什么我们在过去几年中落后了。欧洲由许多不同的国家组成,这些国家有各自的定位,创造一个共同的战略并不容易。然而,我们的位置让我们能够更专注于人工智能的人性方面。发表的研究主题很大程度上取决于方法是自下而上还是自上而下。由于不同的国家遵循不同的方法,我们也看到了更广泛的出版物。
这些差异是什么?
自下而上的方法通常比自上而下的方法赋予人类价值更多的价值。因此,隐私和透明度等基本问题在这里更为重要。这为面向技术和社会的人工智能研究设定了议程。例如,由于透明度在人工智能中是一个至关重要的问题,我们需要理解算法是如何做出决定的。这种重要性将我们的议程引向“可解释的人工智能”的基础研究和调查人们在什么条件下接受和信任算法答案的社会研究。在美国和中国,这种研究不那么明显。
荷兰的国际人工智能定位在战略团队的决策中起什么作用?
历史上,荷兰一直是 AI 的重要玩家。荷兰大学 40 年来一直在进行强有力的人工智能研究,我们国家有几个优秀的教育人工智能项目和良好的生态系统。然而,由于最近的全球发展和建立国家人工智能战略的延迟,我们正逐渐落后。我们最近有很多人才流失到其他国家,那里的工作条件和薪水有时更有吸引力。因为如果我们过度依赖国外的发展将是非常有害的,我们试图更好地利用机会,在人工智能研究和产业方面为荷兰建立和保持一个强大和独特的地位。
许多报告使用出版物的数量作为一个国家人工智能成功的代表。然而,科学是开放的,我们也可以从国外的出版物中获益。我们真的需要很多出版物吗?
近年来有出版过多的趋势。但是,说到底,质量比数量更重要;论文要看,要有影响。为了更好的质量,我们需要强调数据和算法共享,而不是关注数量。在某种程度上,后者已经在发生了。NWO 和 KNAW 这两个老牌的荷兰研究委员会投入更多的资金来改进系统质量。科学家现在更有可能根据反映影响力的其他因素获得晋升,而不是出版物的数量。
荷兰是全球规划和决策的领导者。怎么会这样
从人工智能技术的角度来看,这是被认为是优势的关键领域之一。几年前,我在负责荷兰人工智能宣言的工作组中,我们在宣言中描绘了荷兰的风景。我们确定的七个优势是代理系统、计算机视觉、信息检索、机器学习、知识表示、自然语言处理以及规划和决策。
荷兰应该专注于一个领域,加强其全球领导者的地位,还是应该分散我们的关注点?
作为“VSNU·肯尼斯塔费尔”(一个联合所有荷兰大学人工智能代表的工作组)的一员,我已经就这种权衡进行了各种讨论。传统上,荷兰遵循基于共识的决策模式,这种文化已经根植于我们的讨论中。在我们的讨论中,很难就一种方法达成一致。
在我看来,专注于一两个关键领域是行不通的。但话虽如此,我们需要专注于某些领域,以获得政府的资助,如果我们朝着这个方向前进,我们将处于更有利的位置。
在战略团队中,不同利益相关者的愿景在多大程度上是一致的?
工业目标并不总是与学术目标一致,但这就是为什么我们有来自所有部门的代表。几个策略团队成员都是大公司的代表,我的目标是守护学术界的利益。然而,即使在学术界,利益也不统一。测试版的、面向技术的人工智能研究人员(历史上拥有该学科)与更面向社会和伦理的人工智能研究人员之间存在持续的“竞争”。对于每一种观点应该给予多大程度的重视,一直存在争论。
你主要关注以人为中心的一面,这种说法正确吗?
我对双方都有经验,这是独一无二的,也可能解释了为什么我被要求扮演这个角色。25 年来,我一直在计算机科学系工作。我经常说,我小时候只对计算机感兴趣,但随着时间的推移,我对人类越来越感兴趣。我在某个时候做了一个转变,现在我在一个社会科学系工作。然而,我的研究仍然是相对技术性的,我专注于人类和智能系统之间的交互,既通过开发新的算法,也通过实验评估它们。
你能举一个利益相关者利益不一致的例子吗?
通常情况下,行业预期的步伐会比学术界和政府更快。后者倾向于在实现新算法之前先测试和信任它们。相比之下,工业政党更注重经济增长。在学术层面,我们讨论面向技术和面向人的研究。
对经济增长的关注是否解释了美国的巨大增长?
事实上,这有很大的不同,我们在欧洲没有这些大型科技公司。
除了重点领域,NLAIC 还促进有益的社会效果。它是怎么做到的?
我们试图创建一个基础设施,将工业层面的发展嵌入到关于社会价值的讨论中,例如数据共享。此外,我们还组织活动来教育和培训人们。因为人工智能即将到来,我们需要人们来处理这些算法。此外,我们希望培训在日常生活中面临人工智能的人,以提高“人工智能素养”。
在你的就职演说中,你提到了社会科学和技术科学之间的协同作用。你能详细说明一下吗?
在很高的层面上,这种说法是人工智能是巨大的,影响着我们日常生活的方方面面。同时,它太复杂了,不能只从一个角度来研究。我们需要专注于开发、改进和扩展算法的技术人员。然而,我们也需要人们理解算法对人的影响,我们如何接受它们,以及它们如何影响我们的生活。
我的目标是在我的研究中连接这两种观点,我专注于社交 AI,它涉及人类和类似人类的智能系统之间的所有社交互动。
你有一个最吸引你的话题或想法吗?
我对拟人化很感兴趣,这是一种给计算机赋予类似人类的属性,而我们知道它们并不具备这些属性的现象。在我的研究中,我从两个角度探讨这一现象。在技术方面,我试图通过处理语音和阅读非语言行为,制造更好的算法,给人以机器人像人的印象。在社会科学方面,我们也需要测试这些新算法的影响。后者为未来的算法提供了输入,创造了技术和人的共同进化。
需要回答哪些领域的问题才能让你满意地结束多年后的学术生涯?
地平线上的点是我们与社交人工智能系统完全自然交互的情况,我们几乎忘记了它们只是人工制品。
从技术角度来说,这意味着我们需要新的算法。我们有算法产生有点像人类的语言或检测面部情绪。但是这些系统很容易被愚弄,在实际应用中实现它们会在某些时候出错。
需要注意的一点是,我们的目标永远不会是完全复制或取代人类。我们可以让互动更顺畅,但仍然承认机器人不是人,有优点和缺点。
如果你不想取代人类,为什么要让它们更自然呢?
我期待这样的智能系统更加有效;如果他们理解你的意思,有一个心理理论,并且理解你的需求,发出命令会更容易。但是他们不应该试图在所有层面上模仿人类。例如,机器人不需要看起来像人类,这可能会引起错误的期望。
社交人工智能系统可以在许多领域帮助我们的日常生活。例如,在医疗保健领域,他们可以从医生那里接管重复性的任务,让医生有时间专注于更复杂的任务。
你认为智能系统可以移情或情绪化吗?
一般来说,移情和情感有几个组成部分。其中一个因素是纯粹的行为因素,比如表达同情。这个组件相对容易达到,机器人甚至可能比人类更好地表达同情。然而,该表达并不意味着机器人有任何感觉。第二个组成部分集中在情绪的经验部分,这是一种主观现象。这个组件要复杂得多,关于这能否在机器中实现,还有一场哲学讨论。我不排除这一选择,但我没有看到这方面有多大进展。因此,我更相信移情和情感智能系统的微弱概念;他们可以学会“理解”用户的问题,并感同身受地表达自己,而无需体验同理心。
那些认为机器人可以在经验层面上拥有同理心和情感的人使用了什么论据?
我的推理可能是简单化了,但它归结为以下几点。
人类有同理心,有情感。
人类只是信息处理系统。
计算机也只是信息处理系统。
因此,人工系统也没有理由不能经历同样的事情。由于经验是一个涌现的过程,从大脑中神经元之间的所有局部相互作用中,情绪的经验涌现出来;一些哲学家也认为这种现象在计算机系统中是可能的。然而,还没有人做到这一点。
我们怎么知道人类有这些感觉;我们只是怀疑我们有,因为我们表达了这些感觉?
事实上,科学方法缺乏正确的工具来客观地衡量这一点。这一切都是基于自省;我们内心感受到这些情绪,并与他人分享。因此,我们假设我们都有。
开发带有体验成分的智能系统会有好处吗?
一个好处是我们可以更好地理解人类的经验和意识。如果我们能够复制这一点,这将是人类的一大突破。它将解开意识之谜。然而,我不能立即想到任何实际的好处。我们的星球上已经有足够多的有意识的生物了。为什么要创造更多?
在你的一篇出版物中,你提到了机器人需求的概念。机器人有需求吗,我们需要考虑吗?
我不认为机器人和人类有相似的生理需求。它所有的需求都是被编程的,机器人不会经历它们。有趣的是,人类有时会考虑机器人的需求,尽管我们知道它们没有任何感觉。例如,人们在与聊天机器人交谈时往往很有礼貌。或者,当人们看机器人被分解的电影时,他们可能仍然对机器人感同身受。问题是我们是否应该这样感同身受。
答案是双重的。在某些情况下,它会阻碍我们。例如,我们可能会错误地认为我们的同伴机器人关心我们,导致不切实际的期望。然而,在一个机器人无处不在的世界里,如果我们有许多我们虐待的机器人,我们可能会开始更糟糕地对待人类。然后,我们可能会变得更加以自我为中心,不再考虑他人的情绪。
面试到此结束。你最后还有什么想说的吗?
在关于人工智能角色的讨论中,我发现有必要注意以下几点。原则上,人工智能是一项非常强大的发明,影响了许多人,带来了许多好事,也可能带来坏事。有必要强调的是,我们应该将其视为人类智能的补充方法,而不是取代人类。我们应该寻找一个社会,在这个社会中,除了人类的智能之外,还可以使用算法来造福他们。
本次采访是代表 BNVKI 比荷卢人工智能协会进行的。我们汇集了来自比利时、荷兰和卢森堡的人工智能研究人员。
阿尔伯塔计划:萨顿的人工智能研究愿景
强化学习专家理查德·萨顿概述了未来五到十年的研究方向
对于任何熟悉强化学习的人来说,很难不知道理查德·萨顿是谁。萨顿&巴尔托教科书被认为是该领域的典范。我总是觉得研究真正的思想领袖的观点非常鼓舞人心。因此,当他们提出一个新的研究愿景时,我准备好去倾听。
今年夏天,Sutton 和他的同事 Bowling 和 Pilarski 概述了人工智能的研究愿景,为他们未来 5 到 10 年的研究承诺设计了蓝图。全文只有 13 页,写得很全面,看看也无妨。
研究愿景的首要主题是达到对智力的全面理解。虽然与直接应用无关,但研究计划的成功完成将意味着人工智能和我们生活的复杂现实之间真正互动的实质性一步。
基础代理
大纲的基础是“智能代理的通用模型”,作者用它来导出他们所谓的“基础代理”:
基本代理有四个组件,每个组件都可以基于状态信号学习:(I)感知,(ii)转换模型,(iii)反应策略和(iv)价值函数。[资料来源:萨顿等人,2022 年
在这种表示中,有四个可以学习的组件:
- 感知:过去经验的再现,塑造观察被感知的方式。本质上,现实世界被转化为决策所需的抽象状态(包含适当的特征)。
- 反应策略:根据状态采取行动。通常,该政策旨在最大化累积奖励,但也可以包含其他目标。
- 价值函数:将预期的未来回报附加到状态和动作上的函数。价值函数指导反应策略的训练,并且还可以嵌入多种类型的价值。
- 转换模型:基于当前状态和动作预测未来状态的函数。该模型代表了代理对现实世界系统的理解,也可能反映不确定性。
虽然基本代理表示对熟悉强化学习或相邻领域的人来说并不令人震惊,但它确实有一些有趣的含义。
例如,萨顿等人提出,转换模型可以将选项而不是动作作为输入。根据终止条件采取行动的机会是金融从业者众所周知的,但也与许多在不确定情况下做出的现实决策有关。
另一个丰富是选择创建策略和价值函数集。传统上,人们会有一个将状态映射到动作的单一函数和测量单一度量的值函数。相反,基本代理表示允许多个策略和值并行存在。这种表现更接近真实生活的复杂性和矛盾性。
研究愿景还深化了计划的概念,利用过渡模型来测试和评估各种场景。作者声明这个过程应该在背景中运行,不妨碍其他元素。同时,在前台中操作的学习过程应该基于最近的事件进行更新,可能由短期记忆支持。
总之,Sutton 等人似乎提倡在 AI 中更丰富的代理表现,更接近现实世界中存在的各种更好的细节和复杂性。由于对这类主题的研究很少,所以可以从基础代理那里获得大量的灵感。
信号处理随时间的变化
照片由 Jorge Ramirez 在 Unsplash 上拍摄
研究愿景将人工智能定义为随时间推移的信号处理。潜在的前提是,我们的基础代理不断地与一个极其复杂的现实世界互动。为了有意义地预测和控制输入信号,智能体必须基于现实的抽象继续学习。
在此背景下,有助于形成研究愿景的四个独特点被提炼出来:
I .使用真实的观察结果
当涉及到用于训练的观察时,许多人工智能模型依赖于大量的微调。专门的训练集,利用人类领域的知识和结合现实的知识是司空见惯的。然而,这种支持可能会妨碍通用性和长期可伸缩性。因此,作者更喜欢简单地使用来自现实的观察结果。这将使学习更具挑战性,但最终对于各种各样的应用程序来说更加稳健。
二。时间一致性
算法经常和时间耍花招,学习效率更高。例如,我们经常在更新之前收集成批的观察数据,一旦价值函数出现收敛就降低学习率,或者对某些类型的奖励赋予不同的权重。萨顿等人鼓励同样对待每个时间点,通常是在新事件到来时直接处理。
一致性是关键。例如,如果我们在稳定的环境中降低学习率,我们也应该允许在观察到不稳定时提高学习率。特别是在随时间变化的环境中,或者在处理元学习应用时,这种对时间更全面的态度有望开花结果。
三。利用计算能力
摩尔定律依然如日中天,计算能力大约每两年翻一番。然而,结果是纯粹的计算能力本身成为代理性能越来越强的决定因素。想想用于学习计算机游戏的算法,需要数百万次模拟运行来训练大规模神经网络。
也许自相矛盾的是,计算能力的指数级增长意味着我们应该更小心地利用它,专注于随计算能力而扩展的方法。另一方面,不可扩展的方法,如领域专家和人类标记,应该得到较少的研究关注。
四。多代理环境
许多设置包括多个智能代理。在一个环境中放置多个代理的影响可能具有实质性的影响,因为代理可以响应彼此的决策和源于通信、合作和竞争的信号。因此,代理本身帮助塑造他们的环境。在多人游戏中,这一概念非常明显,但由此产生的非平稳性在不太程式化的问题设置中也非常重要。
多智能体环境的一个吸引人的子领域是智能放大,其中人类的表现通过软件智能体得到增强,反之亦然。在这种共生关系中,从一个代理人那里学到的知识被用来改进另一个代理人的行动和理解。萨顿等人表示,这条研究途径是释放人工智能全部力量的关键途径。
结束语
对于那些真正对具体研究活动感兴趣的人来说,原始文章(见下文)提供了详细的路线图。这些主题不容易浓缩,而且技术细节相当密集,所以我决定在本文中省略一个摘要。
该研究愿景提供了一个有趣的窥视,让我们看到未来十年我们可能期待的人工智能发展,至少是来自加拿大艾伯塔省的发展。尽管对所有讨论的主题都有一些研究,但很明显,在未来几年里还有一些重大的空白需要填补。
以最大化性能和碾压基准的方式为特定问题定制人工智能算法是很诱人的。然而,从研究的角度来看,灌输一些简化(例如,关于时间和观察)是有意义的,以驱动可用于各种复杂问题的鲁棒算法的设计。这一研究愿景似乎是朝着这个方向迈出的深思熟虑的一步。
我个人对研究愿景的看法是,人工智能算法应该:
- 更好的符合真实世界环境的复杂性和特征,以及
- 提供更加通用和健壮的方法来解决各种问题,而无需过多的设计工作。
实现这些目标的具体方法包括在状态(即特性)和时间(即选项)中找到合适的抽象。同时,应确保规划能够有效地执行。结合更丰富的政策和价值观的表征,AI 与现实的差距越来越小。
来源
https://paperswithcode.com/paper/the-alberta-plan-for-ai-research
喜欢这篇文章吗?你可能也会喜欢以下几个:
分析师涉众-请求比喻
原文:https://towardsdatascience.com/the-analyst-stakeholder-request-tropes-c5a3cf747bf0
在过去的 12 年里,我一直是多家公司的分析师,为许多不同的利益相关者工作。在这段时间里,我注意到请求的类型并没有因为公司而发生巨大的变化,而是因为利益相关者。你对每一种类型的回答既能帮助你解决需求,又能让你为未来的要求做好准备……或者让你的生活变得痛苦。我将它们分为 5 个不同的类别:
- GPS:我需要这个信息,但是我问你是因为我不知道从哪里开始找。
- 个人助理 : " 我需要这些信息,我自己也能得到,但是我不能/不想利用我的时间。”
- 收集者::这些信息分散在多个来源,或者没有根据需要进行适当的组织。我需要你去做。
- HAL:"我需要你运行一个诊断分析来检查为什么会发生这种情况/我需要知道我们需要做些什么来解决这个问题/……"
- 解决方法 : " 我可以向其他人请求,但会比您花费更长的时间和/或生成更不全面/有见地的输出。所以我问你。
我认为每个分析师都遇到过他们中的每一个(同样,如果你看到了其他类型,请在评论中告诉我,这样我们就可以做文章的第二部分)。我已经看到,取决于你如何回答每一个问题,你的工作质量以及临时请求的数量都会受到影响(正如罗伯特·易在他的文章中所说的那样。
这就是我如何尝试处理每一个类别(并不总是成功)以及从我所犯的错误中学到的一些东西。
全球定位系统
我需要这些信息,但我问你是因为我不知道从哪里开始找。
照片由 Pexels 的 Kamaji Ogino 拍摄
当您处理以下一项或多项时,这是非常常见的:
- 数据素养低的利益相关者
- 利益相关者准备好角色/工具
- 复杂且对用户不友好的报告工具
通常是相对简单的请求,只需要在正确的位置应用过滤器或者将表格转换成图表(或者反过来)。
人类像任何动物(或自然界的任何东西)一样,倾向于沿着需要较少能量的路径做事。现在向你要数据可能更容易了,但如果这是他们经常遇到的事情或感兴趣的领域,一旦他们知道如何自己做就会更容易(你需要确保这一点)。
如果你们在同一个办公室,安排一次快速通话,甚至请他们到你的办公桌前,这样你就可以向他们展示在哪里可以找到它,资源中还有哪些信息,如果有必要,如何提取并将其转换为 Excel 数据透视表或一些他们觉得使用起来很舒服的工具。
向他们展示后,我会给他们发送一封电子邮件,其中包含资源链接、后续步骤摘要和生成的文档,因此,如果他们再次要求,我会打开电子邮件并按照步骤操作,而不是再次向他们展示(向他们展示按照电子邮件操作可以解决他们的需求)。第三次,我只是把邮件转发给他们,或者查阅邮件。
个人助理
我需要这些信息,我自己也能得到,但是我不能/不想利用我的时间。
这个可能很棘手。我见过很多次来自高级利益相关者的信息,他们正在开会,需要回答一个问题或反对一个信息。其他时候,高级利益相关者也需要当前报告工具中不存在的东西,但他们不能或不想花 20 分钟来处理它。实际上,很多时候这种请求是一种变通方法,而不是 PA。
但是棘手的问题是,当它来自不在开会的同事,或者不是作为求救信号而来的时候(他们不能处理它)。这一次更多的是关于办公室政治,而不是分析。你可以(应该)帮助你的同事,但要确保这样做不会推迟你工作范围内的任务和要求,也不会影响别人对你工作的看法。
关于会议中来自高级利益相关者的请求:他们需要一个快速的回答。有时我们可以直接给他们所需的信息(即使是仪表板上的截图),有时我们可以给他们发送粗略估计的信息(在电子邮件/消息中清楚地说明这是一个估计是很重要的),有时我们需要花几个小时处理请求,因为这不是直截了当的事情。但是对于这种类型的请求,我们需要快速有效地为他们提供解决方案。
一件关键的事情(我已经忘记很多次了)是指定数据的来源和应用的过滤器或条件。这一点很重要,以防有人质疑或想要验证它,也有助于我们在会后的对话中发现它。
如果这种情况经常发生,请利益相关者提前通知你这种类型的会议什么时候会发生,这样你就可以做好准备。
采集者
这些信息分散在多个来源中,或者没有根据需要进行适当的组织。我需要你去做。
当报告工具不适合用户需求时,这是一个非常常见的请求,如果我们拥有或不拥有报告工具,方法会有所不同。
假设我们不拥有报告工具,我们需要做的最重要的事情是了解请求的原因,以及他们打算如何处理答案。这将决定你需要建造的规模。
这可能只是在 excel 上按日期组合两个数据集,这样你就可以将它们绘制在一起并进行比较。在这种情况下,只需通过电子邮件回复:
- 带有所需数据/报告的 excel
- 复制粘贴所请求的表格/图表,以便他们可以在电子邮件中看到
- 我从数据中调出几个例子来强调我所发现的
- 邮件底部的“流程”部分解释了来源、过滤器、查询…
这最后一条非常重要,因为它将帮助你在下次被请求时更快地重建分析(可能是下周、下个月、下个季度或一年后,所以你不能相信你会记得)。
如果相同的请求频繁发生,那么您应该联系相关团队,以确保企业拥有日常运营所需的所有工具。
如果我们拥有报告工具,请按照上述方式提交请求,但也要确保您了解这是一次性请求,还是报告工具未涵盖的业务需求信号。如果是这样,把它的更新添加到你的待办事项列表中。
哈尔
我需要你运行一个诊断分析来检查为什么会发生这种情况/我需要知道我们需要做些什么来解决这个问题/ …
照片由 Yan Krukov 从 Pexels 拍摄
基本上…这是分析师工作最好的部分。这是我们需要找到业务需求答案的地方。有时是通过识别和应用正确的算法,有时是通过重构数据,有时是通过找到正确的可视化。问题有多少,解决方案就有多少。
在这种情况下,有几条规则是成功的关键:
- 确定请求的为什么。有时候问题很清楚。其他的可以是隐蔽的或蒙面的。最终,如果我们不理解为什么提出这一请求,我们将无法给出一个全面的答复。
- 日志&注释。这将取决于工具。如果你使用一个编程环境(它可以是一个笔记本、R Studio 甚至是 PowerQuery ),你可以注释你的代码。你应该去做。好的评论和结构指南将帮助你理解几个月后的工作。如果您使用 Excel,您不能添加注释,但是您可以使用一个选项卡来指定源、流程、结构…
- 用“ 什么,所以什么,现在什么 ”的心态来架构你的反应。斯蒂芬·拉特克利夫写的文章不仅是可视化的黄金法则,也是任何分析练习的黄金法则。在发送之前,一定要检查你是否回答了 3 个问题。
- 始终通过电子邮件发送,并附上类似推特的分析总结。即使你在会议上或通过聊天发送一个链接(或一个文件)来展示它,也要发送一封包含分析结论和结果的简短标题的电子邮件。
- 在您的答案中包含一张方法论幻灯片或部分内容。与之前的请求一样,在许多情况下,你的答案会受到质疑(有人会想知道你是如何得出这个结论的),或者你(或其他人)将来不得不重复这个练习。包括方法论(即使是非常高的水平)将有助于重复它。因为它包含在发送到的电子邮件中,所以它将与结果一起被引用。
变通办法
我可以向其他人请求,但是会比你花费更长的时间和/或产生更少的全面/深刻的输出。所以我问你。
来自 Pexels 的 Andrea Piacquadio 的照片
这也是一个棘手的问题,在许多情况下,这将涉及更多的办公室政治,而不是实际的分析师工作。
您可以将它们分为两大类:数据请求和解决方案请求。它可以被要求给你,要么是因为利益相关者不知道这不是你的主要工作,要么是因为利益相关者比所有者更信任你。
在这两种情况下,始终确保涉众意识到这件事应该由 X (团队或个人)来完成。
当缺乏对任务所有者的了解时,尝试在他们和请求者之间进行调解。当是因为信任的时候,那么我只是陈述观点(在传递答案的时候)来明确这是别人的工作。
关于请求本身,它可能属于前面提到的 4 种类型中的任何一种。主要区别在于,当请求不是临时的,并且开始按时一致时,联系工具所有者并解释业务和所提供的工具之间存在不匹配是一种好的做法,就像“Gatherer”请求一样。然后将您提供的内容作为概念验证,以在解决方案中进行评估和实施。
在任何一种情况下,都有两件重要的事情需要记住:请求的紧迫性和背后真正的业务需求。不了解这两点,你将无法帮助你的利益相关者。
你怎么想呢?我是否错过了应该包含在列表中的请求类型?你有其他我们都能从中受益的最佳实践吗?
分析师的困境——数据太多,时间太少
原文:https://towardsdatascience.com/the-analysts-dilemma-too-much-data-too-little-time-9b8774f74e20
如何通过增强分析解决这个问题
对于数字优先的企业来说,观察和了解其客户和业务的唯一方式是通过数据。有人会认为,有了公司手头的丰富数据,数据驱动的决策就会变得简单。但是数据不仅在大小上增加了,而且在复杂性上也增加了。如今,公司收集了许多关于雇佣、销售、渠道等方面的数据点。因此,使用传统的 BI 工具,分析很快就会变成一项令人望而生畏且毫无结果的任务。好消息是,也有更简单的工具和过程来促进数据转换和可视化。然而,这些增强分析工具/方法(也称为机器学习驱动的诊断分析)的采用水平仍然很低。
为什么您应该关注增强分析?
我们生产和积累数据的方式以及人类注意力的局限性给分析师造成了一个巨大的困境——数据太多,时间太少。为了从数据中创造价值和业务影响,团队需要以业务的速度提供全面的可操作的见解。然而,考虑到新的环境和遗留的 BI 工具,大多数团队最终会在以下两者之间进行权衡:
- 速度——没有足够快地获得答案以做出有效和及时的决策
- 全面性 —错过了洞察力,因为他们只是触及表面,并在粒度级别查看数据。
rawpixel.com 在 Freepik 上的图片
结果,可诉性受到损害。收集的答案不是真正的见解,或者这些见解没有被发现得足够快,不足以推动业务行动。
为了更具体地说明这一点,让我们仔细看看当前的分析挑战:
- 有限的人类注意力
我经常听到这些:
“有如此多的数据和指标,我们不可能全部监控”。
“我每天必须筛选 15 个仪表板,以评估业务是否照常”
“我们需要花几天时间来检查我们的工具,并以一种全面的方式回答为什么”
使用 memegenerator 创建的视觉效果
数据存储和转换能力不再是瓶颈。然而,我们一直在使用相同的商业智能界面——仪表板。正如*司马贺所说,当前的限制是人类的注意力 :*
“在一个信息丰富的世界里,信息的丰富意味着其他东西的匮乏:信息所消耗的东西的匮乏。信息消耗的东西相当明显:信息接收者的注意力。因此,大量的信息造成了注意力的匮乏,需要在可能消耗注意力的过多信息源中有效地分配注意力”
由于仪表板无法将我们的注意力引向最重要的地方,许多团队只分析一部分可用数据,这是最常见的不良分析实践之一(阅读文章以找出其他 5 个)。
2。快速变化的环境
商业变化比以往任何时候都快。因此,指标变化的速度超过了我们解释为什么使用传统的基于仪表板的工作流的能力。与此同时,公司需要采用敏捷决策来保持竞争优势。
正如 Dave Girouard 所说:
“速度是商业中的终极武器。在其他条件相同的情况下,任何市场中最快的公司都会胜出。”
为什么仪表板不能解决分析师的困境
仪表板非常适合描述性分析(即了解发生了什么)和指标监控。它们还支持高层次的探索,以确定一段时间内的主要趋势。然而,它们在诊断分析方面存在不足(即,为什么会发生)。
错过的机会
由于基于仪表板的工作流,企业错过了机会,因为决策是:
- 反应型— 当事情发生变化时,业务团队会要求数据团队去调查或者构建专门的仪表盘。团队对变化做出反应。
- 缓慢 —数据和业务团队之间的票证循环使得诊断分析非常缓慢。此外,在仪表板中执行根本原因分析非常耗时。
- 消息不灵通 —团队通常只对少数场景进行表面测试,忽略了大部分场景,因为仪表盘不能进行全面的根本原因分析。
人工智能和 ML 的作用
机器擅长执行重复的任务和大规模的计算。事实上,在许多领域,人工智能不再被视为与工人竞争的一种方式,而是给他们增压。
机器可以轻松地实时分析数百万个假设,消除重复的切片和切块工作,让团队等待洞察力。通过运行统计测试并带来以影响为中心的视图,AI 和 ML 可以消除人类的偏见,并将人类的注意力指向相关的东西。
Kausa 的图片——机器可以测试这些组合,并过滤掉相关的内容
在下面的例子中,增强分析可以显示德国的一个特定营销活动(跨越数百个)正在推动年轻客户在 AOV 的显著增长。用手动的方式找到这些洞见就像大海捞针。
Kausa 拍摄的图像——碰撞对驾驶员的影响
然而,机器没有上下文来解释数据,将点与业务中正在发生的事情联系起来,并分享见解。谁能弥合这一差距?人类。他们能够查看相关信息,筛选相关信息,并将这些信息联系起来,推动行动。
人在回路中的主动分析
大多数数据科学家高估了 AI 和 ML 的能力,低估了上下文和领域专业知识的重要性。
机器可以进行统计测试,并在几秒钟内计算出许多数字。然而,他们(还)不能解释结果并将这些点与业务中发生的事情联系起来(例如,采取的行动、季节性、外部因素等)。人类应该决定关注哪些见解,有效地沟通它们,并推动行动以完成最后一英里的分析。
你站在哪一边?
根据具体的业务用例,增强分析有多种应用和优势。这些可以基于两个关键维度来划分:
- 速度 —环境的变化有多快,决策的频率有多高。例如,绩效营销通常变化非常快,因为营销经理几乎每天都要采取行动来调整活动/投标和优化营销支出。另一方面,产品功能决策通常很少,数据分析可能需要更长时间。
- 复杂度 —相关维度和相关度量的数量。一些用例本质上非常复杂,因为它们包含大量的相关维度和相关指标。例如,考虑到存储的大量事件,游戏内优化涉及非常广泛和复杂的数据集。另一方面,一个营销经理只在一个特定的渠道和国家开展几个活动,管理的复杂性很小。
基于这些元素,人们可以将用例分组到下面的矩阵中,根据用传统方法处理它们的感觉来命名。
用例矩阵—由作者开发
1)毫不费力
这些用例相对来说是琐碎的(即,少量的相关维度和相关度量)。团队处理低水平的复杂性,并有大量的时间进行数据分析。
一个例子可能是一个小的电子商务公司在一个地区经营,并运行一对夫妇的营销活动。每月或每季度都会采取行动,这是一个缓慢移动的市场。
最有可能的是,传统的 BI 工具对于这种低复杂性和缓慢的业务动态来说已经足够了,而不会让团队感到紧张。
2)落后运行
这些用例变化非常快,敏捷性是关键。团队需要每天或每周做出决策。因此,利益相关者需要快速全面的洞察力。
我非常熟悉的一个典型用例是效果营销/用户获取。通常,小团队会在不同的国家、渠道、媒体来源和平台上开展许多活动,以各种信息和创意瞄准多个受众。他们试图通过快速识别哪些有效,哪些无效来优化 roa(广告支出的回报)。
应用:增强分析平台可以测试数据中的每一个假设,并指出哪些是最重要的子群体。这使得团队能够快速确定是什么在推动发展,然后通过查看相关指标(例如,美国 Vungle 的 iOS 活动中的 CPI 增长)来了解原因。
结果:营销活动的表现在几分钟内就能被了解,而不是几小时或几天,节省下来的时间被重新分配到创造性和战略性工作中。
3)一分耕耘一分收获
这些用例变化非常快,非常复杂。团队需要每天或每周做出决策。他们压力很大,因为同时要测试许多潜在的相关维度和相关指标。使用传统方法,他们经常处于救火模式,需要花费大量时间来获得真正的见解,但他们的工作通常不会受到重视,因为分析需要太长时间。这个桶对应于最困难的用例,例如利用游戏数据来塑造功能、推动参与度和保持度,或者平衡游戏经济。
应用:这个群体不能在速度和全面性之间妥协。他们实际上可以充分利用自动化。他们可以使用增强的分析在几分钟内确定要深入的地方,并以主动的方式发现潜在的机会。
结果:随着探索性分析揭示何处寻找,并确保团队以业务的速度获得可操作的见解,局面将会扭转。他们将从一个几乎被请求困扰的状态,转变为可信任的顾问,预测业务团队的关注点。
4)高风险
这些用例非常复杂,需要分析大量数据点和交互,并将其与重大决策联系起来。
一个潜在的用例可能是网络分析或支持游戏中的产品开发。虽然由于执行时间的原因,你不想每天对你的网站或游戏关卡进行更改,但你所做的更改对业务绩效至关重要。在团队做出这些决定之前,需要收集包含大量变量的非常复杂的数据。与“没有付出就没有收获”的用例相比,从事这些用例的团队由于速度较慢而有了更多的喘息空间,但是由于高风险,他们仍然承受着很大的压力。由于数据的复杂性,即使速度较慢,他们也只能测试通常的嫌疑人,将真正的机会发现留给运气。
应用:增强分析平台使团队能够通过组合多个来源来利用每个数据点,从而发现可操作的见解。更快地完成这种分析,团队将有时间超越峰值和下降值,还可以研究有助于制定战略的有趣见解。
成果:精细且可操作的洞察将带来高价值的决策和改进的指标。通过研究每一个场景,不让任何机会被浪费,团队将更有信心告知这些关键决策,并将在决策桌上获得一席之地。
增强分析是解决方案
增强分析将技术(如机器学习)、流程和人结合在一起,帮助人类利用机器规模的速度和能力,同时结合自己的流程和背景,以更快的速度和规模做出更好的决策。这是缩小诊断分析差距的方法。
—
想法?伸出手去 若昂索萨局长成长处 考萨 。敬请关注更多关于如何确定诊断分析和增加数据价值的帖子。
数据产品的剖析
原文:https://towardsdatascience.com/the-anatomy-of-a-data-product-d3140f068311
数据产品是企业数据网的基础构建块。但是,数据产品到底是什么,它们是如何工作的,如何识别它们,以及如何快速构建它们?
让数据易于查找、共享、使用和管理
我根据数据产品为组织提供的价值来考虑数据产品:数据产品(以及它们在其中运行的数据网格)使数据易于查找、消费、共享和治理。为了实现这一价值,作为从业者,我们的工作是使数据产品易于构建、部署、保护和管理。
在本文中,我将回答两个关键问题:
- 数据产品是如何设计的,它们如何工作以使数据易于查找、消费、共享和管理?
- 为了使数据产品易于构建、部署、保护和管理,需要建立哪些功能、API 和生命周期?
简而言之,如果您能够回答这些问题,那么,首先,您将能够解释为什么数据产品是您的数据网格之旅的基础,其次,您将了解在您的企业数据网格中加速采用和构建数据产品所必需的能力。
在开始之前,本文假设您对数据网格有较高的理解。如果您需要一些关于数据网格的背景信息,这里有一些很棒的文章可供选择:这里的(模式)、这里的(架构)、这里的(原则)和这里的(经验教训)。对于感兴趣的读者,全套数据网格模式可从这里和这里获得。
数据产品=数据领域+产品思维
Zhamak Dehghani 在她精彩的书《数据网格,大规模交付数据驱动的价值》中说,数据产品是数据网格中的“架构量子”。他们是“可以独立部署和管理的最小的架构师单元。”她接着说,数据产品是“可发现的、可理解的、可信赖的、可寻址的、可互操作的、可组合的、安全的、自然可访问的,并且本身就有价值”。
我可以提供一个补充定义:数据产品是“数据领域”和“产品思维”的结合。
图 1,数据产品=数据领域+产品思维
让我们从“产品思维”开始解开这个谜团。我喜欢《哈佛商业评论》最近的一篇文章中的一些见解:首先,一个产品集合了一个组织的生产能力来“传递和获取价值”。第二,有一个“购买和使用该产品的最终客户”。最后,一个产品有一个所有者和团队,他们创建一个长期计划,以确保“产品可以不断改进,使它们更成功”,由一个专注于“结果而不是产出”的团队交付。
换句话说,产品思维意味着确保您的产品满足特定的业务需求,并提供一些切实的价值,具有长期的时间范围,并有一个明确和授权的所有者,不仅符合企业的利益,也符合客户的利益。
不幸的是,定义“数据域”并不简单,因为这个术语在大型企业中往往非常模糊。对于首席数据官来说,治理、监管和隐私是导致粗粒度域的主要关注点:例如,所有客户而不是当前客户或加拿大客户。
类似地,数据架构师可能会将客户视为“团体”领域的子集,包括当前客户和潜在客户。并且应用程序开发者可以将客户视为链接客户账户和交易的唯一标识符。
出于本文的目的,我将数据域定义为一组可识别的、真实的、相关的数据,这些数据得到一致的管理,并且具有一定的质量和准确性。
那么,现在让我们结合这些想法,创建一个数据产品的实际定义。数据产品具有/是:
- 明确界限,建立一套可识别的相关数据
- 授权所有者,提供使数据变得有价值和可信所需的组织资源和决策,并提供产品发展的长期观点
- 消费者和生产者生态系统的一部分,它要求数据的互操作性、一致性和质量,以便为企业提供价值
- 通过平台实现,使数据可被发现、可寻址、可访问和可互操作
- 发布元数据,实现发现和自助服务,同时使数据可理解
- 联合治理,认识到本地自治在实施企业政策和确保数据安全方面的力量
数据产品的架构
有了这个定义,让我们来探索数据产品的架构。
图 2,数据产品的架构
数据产品架构师需要具备以下要素:
- 可互操作:可互操作的接口——查询以及 API、管道、文件和事件——可用于满足消费和接收需求。通常实现为 API 的附加接口也可用于观察、操作、保护和管理数据产品。每个接口都有一个契约(例如,API 使用 OpenAPI 规范)来形式化交互。
- 有界:数据产品存储任何类型的数据,有明确定义的边界和所有者;虽然分析数据是一种主要的使用情形,但是运营数据和参与数据也可以在数据产品中进行管理。
- 自我感知:自动捕捉自身的变化和信息;所有数据产品变更都可以被捕获,并作为数据产品中的“事件”分发给其他数据产品或整个企业中感兴趣的各方。
- 可发现:每个数据产品都包含其自己的“注册表”,该注册表发布其数据产品元数据、所有权信息、策略和任何其他支持行为;数据产品注册中心是开发人员、数据科学家和数据分析师查找、使用、共享和管理由特定数据产品管理的数据的“一站式商店”。它也是特定于该数据产品的行为的切入点,支持复杂的交互,允许用户请求访问数据,或“所有者”创建新的数据产品。
- 安全:数据产品确保所有静态和动态数据的安全;我们的目标是确保所有数据产品在“零信任”容器/环境中运行。
- 历史和时间:使用数据产品对数据状态或异常的更改被捕获并在一个不可变的日志中管理,以支持联合治理、安全问题诊断,并(当数据状态更改被聚集时)提供数据沿袭。
- 可共享的:一个数据产品有“端口”,允许该数据产品管理的数据被摄取或消费。信息和事件(例如,数据更改或 API 调用)可以使用批量管道或在数据产品域内、数据产品之间以及使用健壮、可靠和有弹性的主干网在整个组织内进行接近实时的通信。
数据产品互操作接口:核心数据产品使能器
当我们想到可互操作的接口时,首先想到的有两个:将数据接收到数据产品中的接口(管道、API 等),以及用于消费数据产品中的数据的查询。
然而,在大型企业中,可互操作的接口有几个期望(在某些情况下是强制性的要求):
- 正式合同:每一条摄取或消费路径——管道、查询、API 或事件——都应该由正式的公开合同来定义。在某些情况下,契约将特定于所使用的工具(DBT 等),但在其他情况下——API 或事件——诸如 OpenAPI 和 JSON 模式之类的正式规范是常见的。
- 正式版本化:契约应该被版本化,从而允许向后兼容。现在,公平地说,在只有少数参与者共享数据的小型环境中,这可能并不重要。然而,在数据被广泛共享的大型企业中,确保上游系统改变数据格式时下游系统不会阻塞是至关重要的。
- 形式安全:这很棘手——每种工具可能提供不同的安全方法,更糟糕的是,有些工具可能没有健壮或完整的安全模型。尽管如此,这并没有否定保护生产者和消费者接口的需要——相反,它只是使这变得更加困难。
图 3,数据产品接口
虽然生产者和消费者接口很重要,但是我们不应该忽视接口的本质,即支持发现、可观察性和可管理性。事实上,大多数这些接口都是作为 API 实现的,这意味着您可以利用 OpenAPI 规范提供的功能:
- 正式契约 : OpenAPI 和 AsyncAPI 规范提供了文档完善、经过实战检验的规范,作为正式的同步/异步契约在企业内部使用。
- 正式版本化 : OpenAPI 规范允许一种灵活的版本化 API 的方法,以便随着时间的推移优雅地管理合同变更。
- 形式安全 : OpenAPI 规范提供了一种健壮的、易于理解的、有良好文档记录的方法来定义安全模式,这些模式定义了直接映射到角色的“作用域”;通过一点尽职调查,这些范围可以使用 OAUTH2(一种常见的安全方法)实现,并连接到企业的身份记录簿。
数据产品价值链
数据产品的价值随着其在企业中的使用成比例增加。在最初阶段,数据产品(在数据网格中)是可发现的、可寻址的、可互操作的、自描述的、可信任的和安全的。数据网格的创始人 Zhamak Dehghani 认为,这些是数据产品的基本特征,构成了数据产品提供的所有后续价值的组成部分。
有了这些基本属性,就可以开始在企业中使用数据产品了。如果设计得好,那么数据产品现在可以使数据易于查找、使用、共享和管理。随着数据更容易、更频繁地被消费和共享,新发现的敏捷性和速度随之而来。凭借这种灵活性和速度实现真正的商业价值:
- 更快更好的洞察力,这是创造卓越客户体验或快速应对不断变化的市场需求的关键。
- 缩短上市时间,尤其是对于严重依赖数据的终端消费产品。
- 降低交付成本,因为速度和灵活性缩短了交付持续时间。
图 4,数据产品价值链
但是,如何快速、一致、安全地交付数据产品呢?这就是“数据产品工厂”的由来。
数据产品工厂建立可重复的步骤来制造数据产品:
- 易于构建,通过提供简化数据产品构建的模板;这些模板生成的微服务/API 具有内置的可发现性(“/discover”端点)和可观察性(“/observe”、“/usage”、“/logs”和“/alerts”端点。
- 易于保护,通过提供对前述模板的扩展,为每个 API/微服务启用基于 OAUTH2 的安全性;经过更多的尽职调查,这些模板还可以针对我们的数据产品 APIs 微服务及其数据的“零信任”运行时环境。
- 易于部署,通过为上述模板提供扩展,将 APIs 微服务(如果需要,还包括数据)生成到“容器”(例如 Docker)或 Kubernetes Pod 中,从而可以轻松地将数据产品部署到内部或云环境中,并相对容易地包含在 DevSecOps 管道中。
- 易于管理,通过将生成的 APIs 微服务(例如“/logs”和“/alerts”端点)挂接到企业管理和监控工具中。
数据产品识别
现在,我们可以看到为什么数据产品在我们的数据网格之旅中如此重要。我们还看到了如何利用我们的工厂加快数据产品的交付。
图 5,数据产品标识
因此,显然数据产品很有意义!但是我们如何识别它们呢?幸运的是,有很多提示可以帮助我们在企业中找到数据产品:
- 康威定律:将康威定律(换句话说,您的系统和数据将遵循您的组织结构)应用于数据产品,意味着所有权转移到与组织单位(业务线等)密切相关的团队,这些团队对数据有深刻的了解,并直接负责交付数据的结果,因此拥有决策权和资金权。
- CDO 数据域:数据域图(企业或集团)识别对企业有重要价值的业务实体。这些实体提供了可以识别候选数据产品的“提示”。但是,请注意,在许多情况下,企业域可能需要细分为更细粒度的域,以映射到数据产品。
- 业务架构:业务架构(企业或团体)识别重要的业务能力。这些功能通常很容易转化为数据域,就像 CDO 域一样,提供可以识别候选数据产品的“提示”。同样,企业域可能需要细分为更细粒度的域,以映射到数据产品。
- 行业/商业模型:基于数十年经验构建的商业模型,识别特定行业的核心实体。在金融服务领域,有一些成熟的商业模型,包括来自 BIAN 和 Teradata 的模型(FSLDM,金融服务逻辑数据模型)。
但是有一个经验教训是我不能不分享的:粒度很重要!所谓的企业数据域——例如:“企业客户端”——粒度太粗,不适合数据产品,因此很难定义数据边界和所有者。更细粒度的数据边界更好地映射到“所有者”,从而映射到数据产品(“英国的商业贷款客户”)。
数据网格:数据产品的生态系统
没有任何数据产品是孤立的。相反,所有的数据产品都是生态系统的一部分,并在生态系统中运行。我们称这个生态系统为“数据网”。
图 6,数据网格:数据产品的生态系统
通过这个简单的观察,我们现在可以将几个简单而具体的职责委托给企业数据网格。
- 数据网格概念的首席预言家:数据网格首先是一个概念——营销信息、执行命令、企业数据之旅的分界——其主要目的是描述和传达将数据产品绑定到生态系统的组织结构和逻辑架构抽象。
- 数据产品可发现性的代理 : Data Mesh 是“企业数据产品注册中心”的所有者,使数据产品易于查找、消费、共享和管理。
- 数据产品协议的维护者:数据网格建立了数据产品内部、数据产品之间以及与更广泛的组织之间共享数据的协议。因此,成为企业公共通信、管道和/或事件流主干中的关键消费者和/或利益相关者。
总结想法
在本文中,我讨论了数据产品是如何使数据易于查找、使用、共享和管理的。我还介绍了“数据产品工厂”,它使数据产品易于构建、部署、保护和管理。
我希望通过这篇文章的这些见解,首先,您将能够解释为什么数据产品是您的数据网格之旅的基础;其次,您将了解在您的企业数据网格中加速采用和构建数据产品所必需的能力。
除非另有说明,本文中的所有图片均由 Eric Broda(本文作者)创作。图像中使用的所有图标都是普通的 PowerPoint 图标和/或不受版权保护。
本文表达的观点仅代表我个人,不一定代表我的客户的观点。
剖析数据科学用例
原文:https://towardsdatascience.com/the-anatomy-of-a-data-science-use-case-4fba716eeb5a
在编写任何代码之前,您必须在用例中定义 4 个组件
Joyce McCown 在 Unsplash 上的照片
您已经准备好为您的公司实现定义的用例。项目启动时,您开始收集数据,应用必要的数据清理和争论,继续训练和微调模型,不断重复,直到达到 92%的准确率。太好了!几周后,好消息是,您的模型最终部署到生产中。然而,三个月后,您接到业务部门的电话,抱怨该模型没有增加任何业务价值…一个准确率为 92%的模型怎么会提供零业务价值呢?
听起来很熟悉?您会惊讶地发现这种情况在企业中发生了多少次。Gartner 估计 “到 2022 年,只有 20%的分析洞察力将带来业务成果”[1] 。你试着深入分析并排除故障,从技术角度来看,一切都很完美。那么,怎么了?
我在实践中看到的数据科学项目失败的最常见原因是业务和数据科学团队之间的翻译失误。我们都知道我们需要把商业放在第一位,但这说起来容易做起来难。数据科学家通常是喜欢数学和算法的技术人员,但不一定具有行业/领域技能,或者有时没有付出足够的努力来正确理解和定义业务用例。我非常相信麦肯锡最近创造的“分析翻译”这个角色。我强烈建议你阅读这个角色的真正含义以及需要的技能。到 2026 年,麦肯锡全球研究所 估计 仅美国对翻译的需求就可能达到两到四百万。
每个人都会同意,首先必须正确定义业务用例。这到底意味着什么?用例分析是什么样子的?在开始实施之前,您需要收集哪些关键信息?我相信用例定义必须包括这四个部分:业务问题、现状场景、未来场景和技术解决方案。我将在下面更详细地描述这些组件。为了更好地解释这些概念,我将挑选一个经典的用例:“客户流失”。
数据科学用例剖析—图片由作者提供
1-业务问题
第一部分是最关键的一部分,因为它指导着整个过程的其余部分。你想解决的业务问题是什么?您需要定义以下内容:
- 商业背景。首先,也是最重要的一点,您需要了解此使用案例的关键触发因素或采取行动的令人信服的理由。它如何与整体业务战略保持一致?它是由最近的特定业务事件或决策触发的吗?它是更大的人工智能计划或数字化转型计划的一部分吗?
——商业挑战。你正面临的业务挑战是什么?尽量具体一点。在我们的客户流失示例中,您需要回答这样的问题:目标是预测谁会流失吗?他们什么时候会搅动?他们为什么要搅拌?如何留住他们?它是否针对特定的客户群?你如何定义客户流失?在哪些产品上?
——目标用户。哪种业务功能和用户将会使用您的模式并从中受益?你需要有一份联系人、角色等的清单。最重要的是,从业务角度来看,有一位焦点人物将成为您的支持者/赞助商。在我们的例子中,它可能是诸如保留专家、活动经理、呼叫中心经理、营销专家、CRM 主管等角色。
2- 现状场景
第二部分是了解企业当前用来应对既定挑战的现有方法。
当前状态流程。当前解决这一挑战的流程是什么?你的目标用户完成相关任务的不同步骤是什么?在我们的示例中,您可以问这样的问题:营销团队目前如何设计和执行保留活动?如何选择目标列表?这个过程需要多长时间?
什么工作做得好。询问什么工作得好是一个很好的做法,换句话说,当前流程中哪些部分是业务用户感到舒服并且会抵制改变的。在我们的示例中,您可能会听到诸如白盒方法、完全控制选择哪些客户、针对给定场景灵活定制活动等答案。
有哪些可以改进的地方。当前流程中有哪些痛点?在这里,你将发现改善现有状况的机会,并证明你所做贡献的附加值。对于我们的客户流失用例,痛点可能是回复率低,每月流失率没有显著下降,手动流程来设计活动。
3- 未来情景
未来状态流程。一旦我们解决了业务用户的痛点,他们会如何看待现有流程的未来?它可以通过自动化一些任务来提高运营效率,例如建立目标客户列表、确定下一个最佳报价以留住客户等。
模特消费。必须向业务用户明确设定期望,即他们应该从模型中获得什么样的输出,以及他们将如何使用它。模型期望提供或集成的应用程序是什么?用户需要这些输出的频率如何,例如每月、每周还是每天?例如,一个保留团队可能期望有一个潜在客户的月度目标列表,包括客户 id、客户流失率、主要影响因素、价值细分等。
成功的标准。未来情景的预期优势是什么?通常,KPI 在某种程度上与增加收入或客户满意度、提高运营效率或降低风险敞口相关联。
我见过的一个常见错误是数据科学家过于关注模型的技术准确性。虽然这可以给出项目成功的一些指示,但是您需要记住,商业价值最终是最重要的。如果你的模型设计不当,准确性毫无意义!在我们的例子中,商业利益可以是:与对照组相比,客户流失率降低 2 倍;将战役响应率提高 3 倍等。有一个基准作为起点是非常有用的,这将允许您展示您相对于基准的提升。
与上述相关的另一个常见错误是,数据科学家致力于某种程度的模型准确性。我强烈反对这样做,因为每个客户数据和业务问题都是不同的。要知道你能期望有多高的精确度,唯一的方法就是根据手头的数据建立一个模型。
4- 技术方案
一旦业务线验证了业务问题和期望,最后一步就是定义和设计技术解决方案。
数据要求。定义数据需求是数据科学项目的关键步骤。有必要召开数据评估研讨会,以了解现有的数据生态系统,并就【可能】对用例有用的数据源提出建议。我在这里强调单词“可能”,因为即使领域专家可以胡乱猜测,在我们训练模型之前,没有人能够确定哪些数据点会有帮助。此时,列出可能有用的候选数据域就足够了。在我们的例子中,它可以是客户交易、社会人口统计、产品规格、账单、支付、联络中心、CRM。更不用说你最重要的来源是你将用来定义你试图预测的目标变量的数据,例如,流失(假设这是一个监督学习)。此外,请务必询问基准数据,因为这将允许您比较模型。
数据需求是一个更加技术性和复杂的话题,我将专门写一篇博客来专门讨论它。
技术要求。构建这个用例需要哪些技术?最基本的,你需要一堆经典的软件和库来收集和准备数据,训练和部署你的模型。如果您正在考虑企业的用例操作化,那么考虑额外的技术是很重要的,比如数据治理和模型生命周期管理。可能还需要一些替代/非人工智能技术,例如,模型输出的后处理、持续开发和持续集成(CI/CD)、通过 RPA 实现某些流程的自动化等。
解决方案设计。一旦您确定了技术需求,在您的技术架构师和开发人员的帮助下,您将定义描述拼图的不同部分如何组合在一起的解决方案架构。该架构必须解释模型训练和模型消费的数据管道,一直到将端点与目标应用程序和模型生命周期管理集成。更不用说基础架构规模和解决方案运行的环境了。它会托管在公共云上吗?内部?还是混合云?需要多少个非生产环境?环境之间是逻辑分离还是物理分离?每个解决方案都有不同的规模,但总体而言,这将取决于大量与数据相关的因素(容量、速度等)。)、用户(并发数量、预期使用量)、IT 策略和安全标准等。
结论
现在您已经有了一个定义良好的用例,您需要与 IT 或数据管理团队分享详细的数据需求,然后等待数据供应和工作环境设置完成,这样您就可以开始数据科学的魔法了!好消息是,这一次你会更有信心,如果技术部分做对了,业务用户会很高兴。请记住,这个用例定义是一项正在进行的工作,因此遵循敏捷项目方法并保持业务在循环中发展用例并避免最终出现意外是很重要的。
最后同样重要的一点是,能够用非技术术语解释技术工作的成果,以便业务用户能够清楚地理解和欣赏您提供的价值,这一点我怎么强调都不为过。
我将给你们留下一篇关于企业设计思维的笔记,它提供了一个框架和一套方法来定义一个用例,所有这些都由业务价值来指导。
参考
[1] A. White,我们的顶级数据和分析预测 2019 年,2019 年,Gartner 博客文章。
[2] N. Henke,J. Levine 和 P. McInerney,分析翻译:新的必备角色,2018 年,哈佛商业评论
带注释的 ResNet-50
原文:https://towardsdatascience.com/the-annotated-resnet-50-a6c536034758
解释 ResNet-50 的工作原理以及它如此受欢迎的原因
Resnet-5 0 模型架构
介绍
ResNet 架构被认为是最流行的卷积神经网络架构之一。剩余网络(ResNet)是微软研究院在 2015 年提出的,在何的论文中首次提出时就打破了多项记录。et。艾尔。
为什么是 ResNet?
对像 ResNet 这样的模型的需求是由于当时现代网络中的许多缺陷而产生的。
- 深度神经网络训练难度:随着模型层数的增加,模型中的参数数量呈指数增长。对于每个卷积层,总共有((高度(内核 )⋅ 宽度(内核) ⋅ 滤波器(输入) )+1)⋅ 滤波器(输出)被添加到账单中。具体来说,从 3 通道到 32 通道的一个简单的 7x7 内核卷积层添加了 4736 参数。为了进行实验而增加层数会导致训练模型的复杂度同样增加。然后训练需要更大的计算能力和记忆。
- 更具表现力,差异性更小:神经网络通常被认为是一个函数逼近器。它能够在给定输入、目标以及函数输出和目标之间的比较的情况下对函数进行建模。向网络中添加多层使其更有能力模拟复杂的功能。但是论文中发表的结果表明,18 层平面神经网络的性能比 34 层平面神经网络好得多,如下图所示。
增加层可以看作是功能空间的扩展。例如,多个层加在一起可以看作是一个函数 F 。这个函数 F 可以表示为它可以到达/建模的函数空间 F 的表示。
在 F* 中拥有你想要的功能将是一个幸运的机会,但通常情况并非如此。在这里加层可以让我们围绕函数空间 *F
展开变化,可以让我们在由可想象宇宙中所有可能的函数组成的更大的母函数空间中覆盖更大的空间。但是这种方法有一个固有的缺陷。随着函数空间变大,不能保证我们更接近我们的目标函数。事实上,很有可能在实验阶段,你离开了可能有你实际需要的功能的功能空间。
行话让你困惑了吗?我们来打个针和干草堆的比方。
让这根针成为神经网络的完美权重,或者如前所述,成为一个函数。让干草堆成为所有可能的功能。
一种是从一个单一的搜索区域开始,并试图从那里对准指针。添加图层相当于移动你的搜索区域,让它变大。但这也带来了离开针头实际所在位置的风险,同时也使我们的搜索更加耗时和困难。干草堆越大,就越难找到完美的针。那么,解决办法是什么?
实际上,非常简单和优雅。嵌套您的功能空间。
这样做有几个简单的原因。最重要的一点是,它允许您确保当模型添加层来增加功能空间的大小时,您不会最终降低模型的质量。这保证了虽然我们的模型可以用更多的层做得更好,但它不会做得更差。
回到我们的干草堆类比,这相当于使我们的搜索空间更大,但确保我们不离开我们当前的搜索空间。
3.消失/爆炸梯度:这是困扰大型/深度神经网络训练的最常见问题之一,是网络参数数值稳定性方面疏忽的结果。
在反向传播过程中,当我们不断从深层向浅层移动时,微分的链式法则使我们乘以梯度。通常,这些梯度很小,在 10^{-5}10−5 量级或更大。
根据一些简单的数学,随着这些小数字不断相乘,它们会变得越来越小,对重量的影响几乎可以忽略不计。
在光谱的另一端,存在梯度达到 10⁴或更高的量级的情况。随着这些大梯度彼此相乘,这些值趋向于无穷大。允许如此大范围的值处于权重的数值域中使得收敛难以实现。
这个问题通常被称为消失/爆炸梯度问题。ResNet 由于其架构,根本不允许这些问题发生。为什么跳跃连接(前面描述过)不允许这种情况,因为它们作为梯度高速公路,允许其流动而不被大幅度改变。
什么是跳过连接?
ResNet 论文推广了使用跳过连接的方法。如果你还记得,解决函数空间问题的方法是嵌套它们。就将它应用到我们的用例而言,它是在输出中引入了一个简单的 identity 函数。
在数学术语中,它意味着y=x+F(x),其中 y 是该层的最终输出。
就体系结构而言,如果任何一层最终损害了普通网络中模型的性能,则由于存在跳过连接,该层会被跳过。
体系结构
ResNet-50 架构可以分为 6 个部分
- 输入预处理
Cfg[0]
街区Cfg[1]
区块Cfg[2]
街区Cfg[3]
街区- 全连接层
ResNet 体系结构的不同版本在不同级别使用不同数量的 Cfg 块,如上图所示。下面是一份详细的信息清单。
给我看看代码!
理解这个概念的最好方法是通过一些代码。下面的实现是在 Keras 中完成的,使用标准的 ResNet-50 架构(ResNet 有几个版本,网络深度不同)。我们将在斯坦福 AI 著名的斯坦福狗数据集上训练模型。
导入标题
*!pip install **-**q tensorflow_datasets
import tensorflow **as** tf
from tensorflow import keras
import tensorflow_datasets **as** tfds
import os
import PIL
import pathlib
import PIL.Image
import warnings
warnings**.**filterwarnings**(**"ignore"**)**
from datetime import datetime*
数据集下载和预处理
我们使用 Tensorflow 数据集(稳定) 下载斯坦福狗数据集,并将其分成训练、验证和测试集。
除了图像和标签,我们还获得了一些元数据,为我们提供了关于数据集的更多信息。它存储在ds_info
并以人类可读的方式打印出来。
我们还利用tfds.show_examples()
从数据集中打印一些随机的示例图像和标签。
我们运行tfds.benchmark()
来对tf.data.Dataset
提供的迭代器进行基准测试
我们在tf.data.Dataset
对象上执行以下最佳实践步骤,以提高其效率:
batch(BATCH_SIZE)
:允许我们在数据集内准备小批量。请注意,批处理操作要求所有图像都具有相同的大小和相同的通道数map(format_image)
:将图像转换为tf.float32
张量,归一化范围[0,1][0,1]中的所有值,使用lanczos3
内核方法将图像从其原始形状调整为模型输入形状(224,224,3)(224,224,3)prefetch(BUFFER_SIZE)
:在处理当前批次的同时,预取会将训练期间的下一批数据集带入内存,从而减少 I/O 时间,但需要更多的 GPU 内存cache()
:缓存第一批迭代器,以减少加载时间,类似于预取,区别只是缓存将加载文件,而不是推入 GPU 内存
***(**train_ds**,** valid_ds**,** test_ds**),** ds_info **=** tfds**.**load**(**
'stanford_dogs'**,**
split**=[**'train'**,** 'test[0%:10%]'**,** 'test[10%:]'**],**
shuffle_files**=True,** with_info**=True,**
as_supervised**=True**
**)***print***(**"Dataset info: \n"**)**
*print***(**f'Name: {ds_info**.**name}\n'**)**
*print***(**f'Number of training samples : {ds_info**.**splits**[**"train"**].**num_examples}\n'**)**
*print***(**f'Number of test samples : {ds_info**.**splits**[**"test"**].**num_examples}\n'**)**
*print***(**f'Description : {ds_info**.**description}'**)**
tfds**.**show_examples**(**train_ds**,** ds_info**)**CLASS_TYPES **=** ds_info**.**features**[**'label'**].**num_classes
BATCH_SIZE **=** 4*print***(**'Benchmark results'**)**
tfds**.**benchmark**(**train_ds**)****def** **format_image(**image**,** label**):** image **=** tf**.**cast**(**image**,** tf**.**float32**)**
image **=** image **/** 255.0
image **=** tf**.**image**.**resize_with_pad**(**image**,** 224**,** 224**,** method**=**'lanczos3'**,** antialias**=True)**
**return** image**,** label**def** **prepare_ds(**ds**):**
ds **=** ds**.**map**(**format_image**)**
ds **=** ds**.**batch**(**BATCH_SIZE**)**
ds **=** ds**.**prefetch**(**tf**.**data**.**AUTOTUNE**)**
ds **=** ds**.**cache**()**
**return** dstrain_ds **=** prepare_ds**(**train_ds**)**
valid_ds **=** prepare_ds**(**valid_ds**)**
test_ds **=** prepare_ds**(**test_ds**)***
输出:
*Downloading and preparing dataset 778.12 MiB (download: 778.12 MiB, generated: Unknown size, total: 778.12 MiB) to /root/tensorflow_datasets/stanford_dogs/0.2.0...
Dataset stanford_dogs downloaded and prepared to /root/tensorflow_datasets/stanford_dogs/0.2.0\. Subsequent calls will reuse this data.
Dataset info:Name: stanford_dogsNumber of training samples : 12000Number of training samples : 8580Description : The Stanford Dogs dataset contains images of 120 breeds of dogs from around
the world. This dataset has been built using images and annotation from
ImageNet for the task of fine-grained image categorization. There are
20,580 images, out of which 12,000 are used for training and 8580 for
testing. Class labels and bounding box annotations are provided
for all the 12,000 images.Benchmark results************ Summary ************Examples/sec (First included) 787.00 ex/sec (total: 12000 ex, 15.25 sec)
Examples/sec (First only) 10.34 ex/sec (total: 1 ex, 0.10 sec)
Examples/sec (First excluded) 791.95 ex/sec (total: 11999 ex, 15.15 sec)*
增大
*imageAug **=** keras**.**Sequential**([**
keras**.**layers**.**RandomFlip**(**"horizontal_and_vertical"**),**
keras**.**layers**.**RandomRotation**(**0.2**),**
keras**.**layers**.**RandomContrast**(**0.2**)**
**])***
我们进行了一些数据扩充,使我们的模型更加稳健。一个随机翻转、随机旋转和随机对比度用于使图像组更加多样。函数的参数是概率,即图像经历所选变换的机会。
Cfg0 块
该区块包含 1 个 Conv 层和 2 个身份层。为了有助于数值稳定性,我们指定了一个核约束,以确保所有的权重以恒定的间隔被归一化。在两个后续层之间,我们还包括一个批处理标准化层。代码以一种明确的方式被有意地写出来,以帮助读者理解在每个阶段做出了什么样的设计选择。
- 输入形状:(56,56,64)
- 输出形状:(56,56,256)
Cfg1 模块
该区块包含 1 个 Conv 层和 2 个身份层。这类似于 Cfg0 块,区别主要在于 Conv 和身份层中的out_channels
的数量更多。
- 输入形状:(56,56,256)
- 输出形状:(28,28,512)
Cfg2 模块
该区块包含 1 个 Conv 层和 5 个身份层。对于 ResNet 来说,这是一个更重要的块,因为模型的大多数版本在这个块空间上都有所不同。
- 输入形状:(28,28,512)
- 输出形状:(14,14,1024)
Cfg3 块
该区块包含 1 个 Conv 层和 2 个身份层。这是网络中最后一组卷积层块。
- 输入形状:(14,14,1024)
- 输出形状:(7,7,2048)
分类器块
这个区块包含一个AveragePooling
层、一个Dropout
层和一个Flatten
层。在此块中,要素地图最终被展平并推入完全连接的图层,该图层随后用于生成预测。Softmax 激活用于生成逻辑/概率。
- 输入形状:(7,7,2048)
- 输出形状:(1,CLASS_TYPES)
构建 ResNet 模型
现在,我们将所有的模块连接在一起,创建最终的 ResNet 模型。在我们的整个过程中,我们使用了 Keras Functional API,这是 Tensorflow 的最佳实践。
我们还执行一些可视化,即model.summary()
打印出模型层的结构,以及keras.utils.plot_model()
绘制模型的可视化有向无环图,Tensorflow 将在后端使用该图来简化执行。
*Model: "resnet50"
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
input (InputLayer) [(None, 224, 224, 3)] 0
sequential (Sequential) (None, 224, 224, 3) 0
conv2d_28 (Conv2D) (None, 112, 112, 64) 9472
max_pooling2d (MaxPooling2D (None, 56, 56, 64) 0
)
cfg0_block (Functional) (None, 56, 56, 256) 148480
cfg1_block (Functional) (None, 28, 28, 512) 665600
cfg2_block (Functional) (None, 14, 14, 1024) 2641920
cfg3_block (Functional) (None, 7, 7, 2048) 10526720
classifier (Functional) (None, 120) 3932280
=================================================================
Total params: 17,924,472
Trainable params: 17,893,752
Non-trainable params: 30,720
_________________________________________________________________
None*
定义回调
在model.fit()
中,我们可以为模型定义回调,这些回调在训练期间以预定的间隔被调用。我们定义了一个模型检查点回调,它在每个时期完成时创建模型的快照。
*callbacks_list **=** **[**
keras**.**callbacks**.**ModelCheckpoint**(**
filepath**=**'resnet50_model/checkpoint_{epoch:02d}.hdf5'**,**
monitor**=**'val_loss'**,**
verbose**=**0**,**
save_best_only**=True,**
mode**=**'auto'**,**
save_freq**=**'epoch'**,**
options**=None,**
initial_value_threshold**=None**
**)**
**]**history **=** model**.**fit**(**
x**=**train_ds**,**
validation_data**=**valid_ds**,**
callbacks**=**callbacks_list**,**
epochs**=**20
**)***
如果我们希望使用先前保存的模型,我们也可以这样做。
**## If using Google Colaboratory, one can upload checkpoints onto Google Drive and use it directly.*from google.colab import drive
drive**.**mount**(**'/content/gdrive'**)**
model **=** keras**.**models**.**load_model**(**'/content/gdrive/My Drive/checkpoint_18.hdf5'**)***## If using local Jupyter Notebooks, one can use checkpoints from local drives itself.*model **=** keras**.**models**.**load_model**(**'./resnet50_model/checkpoint_18.hdf5'**)***
获取模型历史
我们打印模型历史以获得关于训练过程的更多信息
**print***(**history**)***
预测结果
我们采用经过训练的模型,并使用它对测试集进行预测,以及计算一些指标,如损失和准确性
*results **=** model**.**evaluate**(**test_ds**)**
*print***(**f"Results : {results}"**)***
结论
上面,我们已经访问了残差网络架构,浏览了它的显著特征,从头实现了一个 ResNet-50 模型,并训练它在斯坦福狗数据集上进行推理。
作为一个模型,ResNet 同时在计算机视觉和深度学习领域带来了一场革命。它还赢得了 2015 年 ImageNet 大规模视觉识别挑战赛和 COCO 比赛。但这只是产生更好结果的许多有趣变化的垫脚石。查看下面有趣的链接部分,找到一些伟大的博客和研究论文。
参考
- 何刚,张,徐,任,孙(2015)。用于图像识别的深度残差学习。
- 张,李,张,李,米,斯莫拉,A. J. (2021)。潜入深度学习。 ArXiv 预印本 ArXiv:2106.11342 。
有趣的链接
更多信息,请访问我的博客这里或者通过电子邮件或 GitHub 联系我!
Python 中人工神经元在虹膜数据集上的应用
无深度学习库的单层神经网络预测花卉品种
信用额度线材@Freepik.com
介绍
答人工神经网络(ann)非常强大。最近的发展使科学家创造出比人脑连接更多的神经网络。给你一个概念,据估计,一个普通的大脑有 860 亿个神经元和 1000 亿个突触。另一方面,2022 年最大的 NN“威震天-图灵 NGL 530B (MT-NGL)”,单片变压器语言模型,拥有5300 亿个参数。尽管如此,人类的大脑精通不止一个领域,MT-NGL 只是专门从事语言处理。
我们是如何走到这一步的?
人工神经元
“一个人工神经元是一个数学函数,被设想为一个生物神经元的模型,一个神经网络。人工神经元是人工神经网络的基本单元[1]。”
1943 年,麦卡洛克和皮茨发表了第一个被称为麦卡洛克-皮茨(MCP)神经元的简化脑细胞概念,这是神经系统发展的一个里程碑。这两位神经科学家试图理解人类大脑如何通过使用相互连接的神经元产生复杂的模式。
神经元和有髓轴突,信号从树突的输入流向轴突末端的输出(维基百科,2022)
如果你看到 MCP 的结构,有三个主要结构,树突,胞体和轴突。简而言之,树突接收在胞体中积累的多种信号。当信号强度超过某一阈值后,神经元向轴突产生输出信号。
这两位科学家试图根据他们从研究生物神经元中学到的知识来模拟人工神经元。工作完成后,他们意识到有局限性。人工神经元缺乏“学习”成分[2]。
被称为深度学习之父的美国心理学家弗兰克·罗森布拉特进一步发展了麦卡洛克和皮茨的工作,增加了缺失的部分。1957 年,Rosenblatt 构思了感知器,这是一个单层神经网络,它计算最佳权重系数,然后乘以输入特征,目的是进行分类。结果用来决定一个神经元是否传递信号。Rosenblatt 为人工神经网络奠定了基础,当新信息出现时,人工神经网络可以被训练并产生输出[3]。
本文旨在从头开始用 Python 创建一个感知器,并在 Iris 数据集上进行训练和测试。最终目标是部署这个单层神经网络,并以令人满意的精度预测新记录。
人工神经元背后的数学
正如你所想象的,在一个感知机中涉及到一些统计公式。本节想要描述从开始到最终输出的整个流程。单层神经网络由以下 5 个元素组成:
- **输入 x1,x2,x3,…,xn**;对算法进行训练然后测试的单个值
- **权重 w1,w2,w3 …,wn**;也称为突触权重,是算法从训练过程中“记忆”的方式。新记录将需要通过权重,以从网络输入函数中分配一个数值
- 净输入功能;它是输入矩阵乘以权重矩阵。这是感知器对训练和测试记录进行分类的方式
- 阈值函数;它在一个数值范围内对网络输入函数给出的结果进行标准化
- 错误;该算法在训练阶段使用它来了解与理想结果相差多少,然后相应地重新调整权重
感知机的过程(Raschka,s .,& Mirjalili,v .,2014 年)
该图显示了感知器接收输入并将其与权重相结合的过程。事实上,在训练之后,感知器确定了一组权重。新记录可以通过净输入功能,其定义如下:
z 是输入的加权平均值。另一方面,存在不同的阈值函数,包括但不限于线性、单位步长、分段线性和高斯函数。为了这个项目,我们将使用 Sigmoid 函数。sigmoid 以 z 为输入,输出 0-1 范围内的值:
概括地说,数据集特定列下的每个输入 x 乘以每个权重。然后将结果 z 输入到 sigmoid 函数中进行归一化。归一化一个结果意味着每一个可能的输出都在一个特定的范围内。高于 0.5 的每个结果都是类“1”的一部分,而低于 0.5 的每个结果都是类“0”的一部分。
数据集
鸢尾花数据集是罗纳德·费雪在 1936 年构想的多元数据集。费希尔是英国统计学家和生物学家。他以厘米为单位记录了三种不同花的萼片和花瓣的长度和宽度:刚毛鸢尾、海滨鸢尾和杂色鸢尾。记录总数为 150 个,每个物种 50 个。数据集的列组织如下:
下面你可以找到通过组合数据集的两个特征生成的散点图,更具体地说是每个物种的花瓣和萼片宽度。从这个图像,你可以对三个品种有一个整体的了解,这是一个很好的场合来介绍一个根本的概念。感知器需要训练的数据必须是线性可分的。线性可分性是两组点的一个性质。如果平面上至少有一条线将这两组点分开,那么它们是线性可分的。例如,变色鸢尾和海滨鸢尾的记录不是线性可分的,而刚毛鸢尾和变色鸢尾符合这一规则。
包含虹膜数据集两个特征的散点图—图片由作者提供
代码部署
在“简短”的介绍之后,我们现在拥有了继续代码部署所需的所有元素。第一个主要步骤是获得可以用来训练感知器的数据集。可以在下面的链接找到。
- 然后我们可以导入诸如 os 、 pandas 和 sklearn 等库用于训练和测试分割;
- os 加入我之前提供给你的数据集的链接,熊猫读取它。导入的数据没有标题,然后列名被重命名。
- 感知器不能读取字符串,品种的名称被映射到整数,鸢尾被分配到 0,鸢尾杂色被分配到 1,鸢尾被分配到 2;
- X 和 y 被定义为训练和测试变量。您会注意到,我只选择了前 100 条记录,它们只包含鸢尾和杂色鸢尾品种。这需要发生两个主要原因:线性可分性和二元分类。正如我们之前提到的,杂色鸢尾和海滨鸢尾不是线性可分的,除此之外,感知器是一个二元分类器,它每次只能处理两个类;
- train_test_split 命令在训练和测试之间划分数据,随机选择记录。
现在是时候创建人工神经元,根据可用数据对其进行训练并记录其表现了。Numpy 是这个过程的基础,因为我们要处理很多矩阵,它是算法中唯一的库。Python 中感知机的设计由 jonasbostonen 提供:
- self.synaptic_weights 与 np.random.seed(1) 命令一起生成随机数并将其分配给权重,这是作者的选择,您甚至可以为每个权重分配一个特定的值。Synaptic 权重接受 4 个输入,每个输入对应数据集的一个特征,并返回一个输出,即类;
- 然后定义 sigmoid 和 sigmoid_derivative 函数。它们是关于结果标准化和我们对现有权重的信心的基础;
- 训练功能利用了神经网络中称为反向传播的概念。通过使用sigmoid _ derivative,该技术使用梯度下降来最小化成本函数。换句话说,命令 train 通过比较 sigmoid 导数的先前值和新值来重新迭代或重新调整,直到它达到成本函数的最小值;
- think 负责通过神经网络传递输入并返回最终输出,预测一个新记录是属于一个类还是另一个类;
- 训练 _ 输入和训练 _ 输出需要分别分配给 X_train 和 y_train 给模型输入数据;
- 将迭代次数设置为 1000 次后,我们可以打印突触权重,看看它们是如何从随机分配的值变化的。这段话告诉我们训练是否奏效,模型是否收敛;
- 最终,我们可以通过运行命令neural _ network . think(X _ test)来预测新的记录,并为下一步将它们转换成 pandas 数据帧。
下面的终端输出显示了训练前后的突触权重值。每个突触权重都与该位置的特征相关联。例如,每个新记录的萼片长度需要乘以-9.52,萼片宽度需要乘以-6.52,依此类推。
Random synaptic weights:
[[-0.16595599]
[ 0.44064899]
[-0.99977125]
[-0.39533485]]
Synaptic weights after training:
[[-9.52461914]
[-6.52013852]
[-2.58998186]
[-0.37790606]]
当我们执行预测命令时,新记录会发生以下情况:
啊哦!这是一个变色鸢尾(1)记录,已被归类为鸢尾(0)。在这种情况下,我不期望模型在测试记录上表现良好。
可以使用 sklearn 库 classification_report 来分析性能,但首先要注意的是,sigmoid 函数不会返回 1 和 0,而是这些值的近似值。因此,我们需要将值转换成类。
使用 getResult 函数,每个高于 0.5 的输出被分类为 1,而每个低于 0.5 的输出被分类为 0。lambda 函数帮助我们在测试数据集的每个记录上应用 getResult ,而 classification_record 给了我们感知的准确性。
precision recall f1-score support
0 0.50 1.00 0.67 10
1 0.00 0.00 0.00 10
accuracy 0.50 20
macro avg 0.25 0.50 0.33 20
weighted avg 0.25 0.50 0.33 20
正如预期的那样,准确性根本不令人满意,该模型似乎对 Iris Setosa 记录极其敏感,并对每个新数据点进行分类,从而实现 50%的总体准确性。
重要的是要强调特征以及它们的顺序会极大地影响最终结果。数据集中的所有列都被使用的情况经常发生,但并不总是这样。
经过一段时间的试验后,我注意到两种花卉的萼片宽度有一个清晰的模式,所以这次我只使用三个变量按照以下顺序重新运行代码:
##Defining input and target variables for both training and testing
X = df.iloc[:100,[1,2,3]].values
y = df.iloc[:100,[4]].values
我相应地修改了第一个神经网络的类函数,这次它只接受三个特征而不是四个:
def __init__(self):
np.random.seed(1)
self.synaptic_weights = 2*np.random.random((3,1)) - 1
正如你可能想象的那样,突触权重在通常的 1000 次迭代后已经改变了。
Random synaptic weights:
[[-0.16595599]
[ 0.44064899]
[-0.99977125]]
Synaptic weights after training:
[[-10.97823329]
[ 10.71483544]
[ 3.74420857]]
我要用之前的记录再试一次,看看这次模型是否分类正确。
大家可以看到,有些权重经过调整转正,也使得最终结果转正。提醒一下,这个记录属于鸢尾,这次分类器预测正确。我对这个模型有更好的感觉。
precision recall f1-score support
0 1.00 1.00 1.00 10
1 1.00 1.00 1.00 10
accuracy 1.00 20
macro avg 1.00 1.00 1.00 20
weighted avg 1.00 1.00 1.00 20
正如预期的那样,性能得到了令人眩晕的提高,报告显示两个类在 20 个测试记录中获得了 100%精度的满分,这正是我们想要的结果。
结论
我希望你觉得这篇文章很有见地,很吸引人。目标是通过分析神经网络算法的基本单元来揭穿其复杂性。现在想象一个感知器,但有更多层,其中前一层的输出代表下一层的输入,这是一个多层人工神经网络,它是 MT-NGL 的基本概念,你刚才看到它用大约 130 行 Python 编码和部署。
最后,如果您喜欢该内容,请考虑添加一个关注,以便在新文章发布时得到通知。如果你对这篇文章有什么要考虑的,写在评论里吧!我很想读读它们:)谢谢你的阅读!
PS:如果你喜欢我写的东西,如果你能通过 这个链接 订阅一个中等会员,那对我来说就是全世界。这是一种间接的支持我的方式,你会得到媒体文章提供的惊人价值!
参考
[1]麦卡洛克,W. S .,&皮茨,W. (1943)。神经活动中固有观念的逻辑演算。《数学生物物理学通报, 5 (4),115–133。
[2]维基百科贡献者。(2022 年 2 月 10 日)。人工神经元。维基百科;维基媒体基金会。检索自:https://en.wikipedia.org/wiki/Artificial_neuron
[3]罗森布拉特,F. (1961 年)。神经动力学原理。感知机和大脑机制理论。纽约布法罗康奈尔航空实验室公司。
[4]费希尔,R. A. (1936 年)。分类问题中多重测量的使用。《优生学年鉴》, 7 (2),第 179–188 页。
[5] Raschka,s .,& Mirjalili,V. (2014 年)。朴素贝叶斯和文本分类 I 导论和理论。从 https://arxiv.org/pdf/1410.5329.pdf取回
[6] R.A .费希尔(1936 年)。https://archive.ics.uci.edu/ml/datasets/Iris 的 UCI 机器学习库。加州欧文:加州大学信息与计算机科学学院。
解释预言的艺术
原文:https://towardsdatascience.com/the-art-of-explaining-predictions-22e3584ed7d8
如何以人性化的方式解释你的模型
杰森·古德曼在 Unsplash 上的照片
数据科学家角色的一个重要部分是解释模型预测。通常,接受解释的人是非技术人员。如果你开始谈论成本函数、超参数或 p 值,你会遇到茫然的目光。我们需要把这些技术概念翻译成通俗易懂的语言。这个过程可能比构建模型本身更具挑战性。
我们将探索如何给出人性化的解释。我们将通过讨论一个好的解释的一些关键特征来做到这一点。重点将放在解释个别预测上。最后,我们将通过解释一个使用 SHAP 值的模型来应用这些知识。我们会看到,当你想给人以友好的解释时,SHAP 是非常有用的。
本地与全球解释
在我们深入讨论之前,让我们先讨论一下你在解释什么以及你在向谁解释。作为一名数据科学家,你可能需要与各种各样的人交流。这包括同事、监管者或客户。这些人都有不同程度的技术专长。所以你需要根据他们的专业知识来调整你的解释水平。
在某些情况下,您可能会被要求从整体上解释模型。我们称之为全局解释。我们希望了解模型总体上捕捉到了哪些趋势。我们可能需要回答诸如“哪些特性是最重要的?”或者“特征 X 与目标变量有什么关系?”
在其他情况下,我们将需要给出局部解释。这是我们解释单个模型预测的时候。事实上,我们通常需要解释由模型预测产生的决策。这些解释也可以是对诸如“我们为什么拒绝这个贷款申请?”或者“为什么会给我这个电影推荐?”
(来源: flaticon )
与同事或监管者交谈时,你可能需要给出更多的技术性解释。相比之下,客户会期待更简单的解释。你也不太可能需要给客户一个全面的解释。这是因为他们通常只关心影响他们个人的决策。我们将集中讨论这个场景。这是向一个非技术人员解释个人预测。
好的解释的特征
当我们谈论一个好的解释时,我们指的是一个容易被接受的解释。换句话说,它应该让观众相信一个决定是正确的。要给出这样的解释,你需要考虑一些关键的方面。您可以在图 1 中看到这些内容的总结。在本节的其余部分,我们将深入讨论每一个问题。
图 1:一个好特性的特征概述(来源:作者)
真实的
这似乎是显而易见的,但一个好的解释应该是真的。当你考虑我们正在解释的东西时,这可能比预期的更难。那就是我们正在为模型预测给出解释。问题是这些预测可能是不正确的。例如,我们的模型可能过度拟合。这意味着预测可能会反映已经建模的噪声。对这些预测的解释不能反映数据中真实的潜在关系。
(来源: flaticon )
当给出解释时,我们需要考虑我们的模型在多大程度上代表了现实。我们可以通过评估模型的性能来做到这一点。例如通过使用交叉验证准确性。即使整体表现良好,一些预测可能比其他预测更不确定。例如,概率为 0.5 左右的逻辑回归预测。在你的解释中,我们可能要提到这种不确定性。
瞄准目标受众
你表达事情的方式很重要。我们拒绝了你的贷款,因为——“你是一名加密货币交易员”、“你在一个高风险的行业工作”或“你的收入太不稳定”。这些都是相同的原因,但措辞不同。一些表达事物的方式会更好地表达你的观点。有些人可能还会觉得某些方式令人不快。比如第一种解释,可能会带个人色彩。
你也应该避免任何技术或商业术语。“收入在我们的模型中有一个正参数,而你的收入值很低。所以,你被拒绝了,因为你的收入价值大大增加了你的违约风险。”这是一个不好的解释,因为我们使用了技术术语(即“模型”和“参数”)。我们也有一些商业术语(如“违约风险”)。
选择最佳的解释方式才是真正的艺术所在。这可能是解释一个预测最困难的部分。这也不是数据科学课程或大学能很好涵盖的内容。最终,这种技能将来自经验和与客户发展关系。
原因数量
人们只想要事件的主要原因。“为什么通货膨胀这么高?”——“因为油价上涨了。”事实上,通胀可能是由工资增长、政府支出增加或汇率等因素综合造成的。然而,这些可能没有能源成本上升的影响大。
当谈到 ML 时,人们不想知道每个模型特征是如何影响预测的。一般来说,说明 1 到 3 特征的贡献就足够了。问题是你选择解释哪些贡献?接下来的 4 个特征可以帮助你选择最合适的原因。
(来源: flaticon )
有意义的
我们应该选择最重要的原因。换句话说,我们只会解释那些有重大影响的因素。对于我们的通货膨胀的例子,我们会给出引起最大增长的原因。这些原因比那些影响较小的原因更容易被接受。
对于 ML,我们想要解释对预测贡献最大的特征。我们确定这些特征的方式将取决于所使用的模型。对于线性模型,我们可以看参数权重和特征值。稍后我们将看到 SHAP 值如何用于非线性模型。
一般
一个好的理由可以解释许多决定。“你为什么拒绝我的贷款申请?”——“因为你现有的债务很多。”假设这是拒绝很多贷款申请的理由。这个原因更容易被接受,因为它的贡献已被广泛理解。
对于 ML,我们可以通过查看一些特征重要性的度量来找到一般性的解释。例如,排列特征重要性。有了 SHAP 值,我们可以看到平均绝对 SHAP。无论如何衡量,高值表示某个特性总体上做出了重大贡献。
反常的
在其他情况下,一个好的理由可能是不常见的。这些将能够解释对特定决策的重要贡献。然而,一般来说,他们无法解释决策。“你为什么拒绝我的贷款申请?”-“因为你是一个加密货币交易商”这些类型的原因可能会被接受,因为它们更个人化。也就是说,人们能够理解它对他们产生了怎样的具体影响。
对于 ML,我们可以通过查看特征重要性和对个体预测的贡献的组合来找到异常原因。这些是不具有高特征重要性的特征。但是,对于一个具体的预测,他们做出了很大的贡献。
(来源: flaticon )
对比
通常我们需要解释一个决定和另一个决定。客户可能不会问“为什么我的申请被拒绝?”但是“为什么我的申请被拒而他们的申请被接受?”可能是两个客户都有很高的现有债务。第一个问题可能接受了这个理由,但第二个问题没有。换句话说,我们需要给出一个理由来区分这两个决定。
对于 ML,这意味着我们需要将我们的解释建立在对两个客户具有不同价值的特性的基础上。该特征还需要在某种程度上有所不同,从而导致不同的预测。例如,我们可能会发现第一个客户的收入更高。收入特征不同,但这不是一个好的理由。也就是说,较高的收入不会导致申请被拒。
这最后四个特征似乎相互矛盾。一个不正常的原因不可能是普遍的。异常或一般原因可能不是最重要的。一个相反的原因可能既不重要,一般或异常。然而,在我们的解释中,我们可以使用多种原因的组合。你选择的理由将取决于问题、人和你认为最有说服力的东西。
和 SHAP 一起解释一个模型
如果你刚到 SHAP,那就看看下面的视频。如果想要更多,那就来看看我的 SHAP 课程 。注册我的 简讯 :)即可免费获取
现在让我们将其中的一些特征付诸实践。我们将尝试解释一个用于预测保险费用的模型。您可以在表 1 中看到这个数据集的快照。我们的模型特征基于前 6 列。比如子女就是被赡养人数。
表 1:数据集快照(来源:作者)(数据集: kaggle )(许可证—数据库:开放数据库)
我们不会检查代码,但是你可以在 GitHub 上找到完整的项目。总而言之,我们从做一些特性工程开始。我们将的性别和的吸烟者转换成二元特征。区域可以采用 4 个不同的值,因此我们从该列创建 4 个虚拟变量。这样,我们总共有 9 个模型特征。我们使用这些来训练 XGBoost 模型以预测电荷。一旦我们的模型经过训练,我们就可以计算每个预测的 SHAP 值。
对于每个预测,每个要素都有一个 SHAP 值。SHAP 值给出了该要素对预测的贡献。换句话说,该特性增加或减少了多少预测的费用。为了理解哪些特性是重要的,我们可以看一下图 2 。这里我们取了所有预测的 SHAP 值的绝对平均值。高平均值表示该特征通常对预测有很大的贡献。
图 2:均值 SHAP 图(来源:作者)
我们可以使用图 2 来帮助确定好的一般或异常原因。比如我们可以看到吸烟者的绝对均值很高。这告诉我们,一般来说,这个特征将为预测提供一个很好的理由。绝对值较低的特征可以提供很好的异常原因。也就是说,对于一个特定的预测,他们有很大的贡献。
让我们试着解释一下我们的第一个预测。你可以在图 3 中看到这个预测的 SHAP 瀑布图。查看 x 轴,我们可以看到基值是 E[f(x)] = 12813。这是所有客户的平均预计费用。结束值是 f(x) = 26726。这是该特定客户的预计费用。SHAP 值是介于两者之间的所有值。它们告诉我们,与平均预测相比,每个特征是如何增加或减少预测的。
图 3:第一次预测的 SHAP 瀑布(来源:作者)
查看图 3 中的我们可以看到吸烟者是最显著的特征。也就是说,它将预测的费用增加了最大的数量。y 轴给出了特征值。例如,我们可以看到“1 =吸烟者”表示该客户吸烟。因此,如果客户问“为什么我的保险费这么高?”,一个好的解释可能是“你是一个吸烟者”。我们还看到,在图 2** 中,这是一个很好的一般原因。**
因此,吸烟既是一个重要的原因,也是一个普遍的原因。这可能足以让这个人相信保险费用是正确的。如果我们想确定,我们可以提到第二个最重要的特征。看 y 轴我们可以看到这个人是 62 岁。因此,我们可以接着问第二个原因,“你老了。”(我们可能想用更好的方式表达这一点。)
对于第二个原因,我们已经猜到了与目标变量的关系。那就是随着年龄增加你的费用增加。其他特征的关系可能不那么明显。这意味着要给出好的理由,我们需要一些特征值的上下文。为此,我们可以使用 SHAP 值的散点图。查看图 4,我们可以看到我们的猜测是正确的。随着年龄的增加,SHAP 值增加。换句话说,预测的费用增加。
图 4: SHAP 对年龄的价值观(来源:作者)
在图 5 中,可以看到第二次预测的瀑布图。为了解释这一点,我们可以直接跳到客户的年龄。然而,请注意孩子也做出了重大贡献。记住,我们在图 2 中看到,这个特性通常并不重要。换句话说,依赖者的数量可能是一个很好的异常原因。相反,我们可能更愿意将此作为主要原因。
图 5:第二个预测的 SHAP 瀑布
本质上,SHAP 价值观允许你给出相反的解释。然而,这只是在我们想要将预测与平均预测进行比较的情况下。像“为什么我的收费比平均水平高?”这样的问题很容易回答。来回答诸如“为什么我的收费比我的姐妹们高?”将需要更多的工作。还有其他计算 SHAP 值的方法可以简化这一过程。例如,基线 SHAP 将计算特定预测的值。
我们一直关注用 SHAP 值来解释个人预测。它们也可以用来给出全局的解释。这解释了模型作为一个整体是如何工作的。我们通过聚合 SHAP 值和创建不同的地块来做到这一点。我们已经看过一个——卑鄙的 SHAP 阴谋。我们将在下面的文章中详细讨论。我们还将讨论用于计算 SHAP 值和创建这些图的 Python 代码。
我希望这篇文章对你有帮助!你可以成为我的 推荐会员 来支持我。你可以接触到 Medium 上的所有文章,我可以得到你的一部分费用。
https://conorosullyds.medium.com/membership
你可以在|Twitter|YouTube|时事通讯上找到我——注册免费参加 Python SHAP 课程
图像来源
所有图片都是我自己的或从www.flaticon.com获得。在后者的情况下,我拥有他们的保费计划中定义的“完全许可”。
资料组
米(meter 的缩写))Choi,医疗费用个人数据集(License-Database:Open Database)https://www . ka ggle . com/Datasets/mirichoi 218/insurance/metadata
参考
C.Molnar、可解释机器学习 、 2021、https://christophm . github . io/Interpretable-ml-book/explain . html
T.米勒,人工智能中的解释:来自社会科学的洞见,2017,https://arxiv.org/abs/1706.07269
南 Lundberg & S. Lee,解释模型预测的统一方法, 2017,https://arxiv.org/pdf/1705.07874.pdf
做出更好预测的艺术
原文:https://towardsdatascience.com/the-art-of-making-better-predictions-a461a9301209
数据科学家的日常工作可能涉及非常复杂的概念,但其核心是我们发现了一个简单的前提:如果我们从过去查看足够多的(可靠)信息,我们也许能够说出未来可能会发生什么。
从观察到预测的旅程需要时间、技巧和直觉;没有放之四海而皆准的魔术能让我们实现这一目标。但是获得一个深入的工具包并尝试广泛的用例肯定会有所帮助。为了一路支持你,本周我们重点介绍一些我们最近最喜欢的关于做出更好预测的微妙艺术的帖子。让我们开始吧。
- 围绕预测基础知识 打好基础。如果你是时间序列分析的新手,杰森·庄的《初学者指南》是一个完美的起点:它全面而易懂,涵盖了平稳性、时间序列分解和 ARIMA 建模等基本概念。
- 想想季节 总是好的。停留在时间序列的一般领域, Alvin T. Tan 博士关注季节性在进行预测时的关键作用。他强调了这一概念在模型校准中的特殊重要性,并展示了数据科学家忽视季节性周期的原因。
- 探索预测与自然语言处理的交集 。预测在数据科学和机器学习的许多其他子领域都很重要。一个很好的例子:由余黄,医学博士,计算机科学硕士完成的一个令人着迷的新项目。眼前的挑战是预测临床文本的医学学科;本患者演练演示了为生成可靠预测而处理和准备文本数据的工作量。
在 Unsplash 上由 Toa Heftiba 拍摄的照片
- 为什么不试试协同过滤呢?推荐系统无处不在,它们总是依靠算法来做出预测。一个好的会成功地告诉你应该选择什么产品或菜肴,或者在 Khuyen Tran 的最新教程中,告诉你应该看哪部电影。她的这篇简单易懂的文章重点介绍了协同过滤的强大功能,并解释了如何利用这种方法来提供可靠的推荐。
- 利用数据的力量告知气候相关政策 。为了围绕气候变化做出明智而有效的决策,政府和其他利益相关者需要对我们当前的发展轨迹有一个很好的了解。 Giannis Tolios 最近分享了一个使用 Python 中的 Darts 库创建大气 CO2 时间序列预测的便利资源。
我们基于人类直觉的预测算法(又名“直觉”)告诉我们,本周你可能想要阅读一些其他话题。我们希望如此,因为下面的链接会带你去一些你绝对不应该错过的好帖子。
- 在 TDS 播客上, Jeremie Harris 和嘉宾 Katya Sedova 讨论了人工智能的潜在恶意使用(虚假信息宣传,假新闻的产生,以及其他)——以及研究人员现在需要做什么来降低未来的风险。
- 如果你正在申请数据科学硕士学位——或者正在考虑— 艾莉森·韩愈·姚刚刚出版了一份基于她自己最近经历的综合指南。
- 怎样才能量化信息?凯西·程深入探究克劳德·香农在信息论和通信基本粒子方面的工作。
- 我们每个人都会遇到这种情况:一次错误的点击,整个数据帧或数据集就会丢失。玛丽·沙拉帕在这里为你提供了一个详细的指南,教你如何在谷歌大查询中挽回丢失的数据。
- 为了进入软件工程领域看看陈莉莉基于她过去在 Slack 的工作,对 redux 大小和应用程序性能之间相关性的见解。
感谢你本周和我们一起学习和探索——还有一个特别的大喊,送给所有通过成为灵媒成员来支持我们作者工作的人。
直到下一个变量,
TDS 编辑
促销的艺术
原文:https://towardsdatascience.com/the-art-of-promotion-2498fafdac0d
作家工作室
我们获得更广泛受众的技巧
杰洛特在 Pixabay 上的照片
几周的写作和编辑终于有了回报,你的文章现在发表在《走向数据科学》上。你自豪地向你的朋友圈和同事宣布,在我们的首页向他们展示你的文章,并分享我们的 Twitter 和 LinkedIn 帖子。你看着掌声和关注,期待着看到两者都成长为数千人,就像你在我们一些最受欢迎的作家身上看到的那样。但是在最初的兴趣爆发之后,事情就停滞了。发生了什么事?
每篇新发表的文章都会在我们的网站和社交媒体账户上成为焦点。但是要想真正成功,作者需要在推广他们的作品中发挥作用。许多作者不知道从哪里开始,所以我们分享我们关于推广的顶级技巧。虽然他们不一定会让你成为一个明星 TDS 作者,但他们会让你走上成功之路。
联网
即使你还没有写一个字,建立你的人际网络也是很重要的,因为单独传播这个词是很困难的。你的同事、朋友和家人是一个很好的起点,但是要真正扩大你的人际网络,你需要接触陌生人。
社交媒体账户。这是作者最熟悉的推广形式。这是一个很大的话题,所以我们将在我们的作家工作室系列中提供一个单独的帖子。这里我们会提到,要增加你的关注者,你往往要先关注别人。关注 TDS 社区的其他成员,以及您所在领域的领导者。
教育供应商。如果你正在学习或已经从教育项目毕业,在 Twitter 上与他们联系。许多学校积极支持学生和校友的推广活动。这些机构中的一些还会提供机会在他们的时事通讯和出版物中宣传你的工作,所以它们值得一探究竟。
用户组、专业协会和会议。这是一个经常被忽视的建立关系网的机会。例如,如果你是 Python 专家,就去 Python 论坛找找看。不要忘记软件公司——许多公司提供年会和网络活动,在那里你会找到志同道合的同事。
网站。有些作者创建了自己的网站,虽然这可能很有效,但需要努力,并且需要自己的推广,因为你必须吸引人们来这个网站。如果你决定走这条路,保持你的网站及时更新,内容丰富,易于浏览。还记得利用你的中型简介传记提及和链接到您的网站。
分发名单。从对你的工作感兴趣的人那里收集联系信息是另一种流行的社交策略。而且理由很充分!这些人喜欢你的工作并期待更多,所以他们已经在支持你的努力了。我们让你很容易建立你的通讯组列表,我们在下面的一个单独的部分解释了这一点并提供了一些很好的建议。
其他作者。接近一个你不认识的人可能会不舒服,但要记住他们中的许多人,尤其是其他作者,曾经站在你的立场上。他们也不得不从零开始建立他们的网络,因此,你可能会惊讶地发现这比你想象的要容易得多!考虑联系那些写类似主题的作者,或者直接在你的文章中添加作者提及。当涉及到其他作者时,运用良好的判断力是很重要的;仔细选择你提到的作者,不要走极端。
确保你的文章被找到
人们热切期待杂志和期刊的印刷版的日子已经一去不复返了,所有的杂志和期刊都是从头到尾阅读的。相反,互联网搜索识别感兴趣的文章,你想在顶部的结果。
搜索引擎使用专有算法来决定什么先出现,这使得搜索引擎优化成为每篇发表文章的一个重要方面。TDS 作者受益于成熟平台的 SEO 提升,因为我们是世界上最受欢迎和阅读量最大的数据科学博客之一,拥有+60 万中等关注者。但是作者自己可以做更多的事情。
基本上,我们希望给搜索引擎提供它所需要的东西,以快速确定你的文章是输入搜索的理想匹配。事实上,我们不知道谷歌是如何使用大约 200 个因素来对内容进行排名的,这使得关注我们所了解的发挥作用的因素变得非常重要。
添加关键字。关键词是常见的搜索术语,在你的文章标题和正文中包含相关的关键词可以提高可见性。将机器学习或数据科学等主要关键词与特定于您的主题的术语(如可视化或部署)结合起来会很有帮助。如果你不确定要包括哪些关键词,那么谷歌趋势是一个不错的起点。
有效放置关键词。在标题、副标题和开头段落中使用与内容相关的关键词。理想情况下,关键字应该出现在标题和副标题的开头,而不是结尾。同样的策略也适用于你的介绍,你应该尝试在前两三句话中包含关键词。 搜索引擎期刊 分享了一些关于关键词放置的好技巧。
明智地使用关键词。自然的使用你的关键词;许多搜索引擎积极寻找太多重复的关键词,被称为关键词填充——TDS 编辑也是如此。所以,只在有意义的地方使用关键词,并考虑相关术语。
别忘了元数据。在你文章的故事设置中,你会发现一个 SEO 设置部分,你可以在那里查看你的标题和描述,它的功能是搜索引擎元描述标签。
输入这些设置时,请记住以下几点:
- 您的 SEO 标题只能在发布前更改。理想情况下,它将在 40-50 个字符之间,并包括关键字。虽然你可以选择一个更长的标题,但请记住,搜索引擎通常会将标题截断到 60 个字符。这意味着你的标题中最重要的元素和关键词应该在开头。
- 一个好的 SEO 描述是一篇 140-156 个字符长的文章的紧凑的、引人注目的摘要,包括关键词。默认情况下,会使用文章的第一段,所以请仔细检查以确保其有效。此设置可以在发布后更改,但您需要事先注意这一点,以便从最初的发布推广期获得最大收益。
鼓励读者关注你的文章
面对一长串互联网搜索结果,读者可能会对他们决定挖掘的内容吹毛求疵。所以,除了一个好的标题、副标题和关键词,考虑你的开头段落和特色图片也很重要。
创造一个有意义的标题。写一个简短的标题来吸引读者的注意力。这并不意味着点击诱饵——为了符合我们的指导方针,你的标题必须反映你文章的内容。
用副标题添加细节。一个好的副标题应该扩展你的标题,而不是重复它,这样综合起来,你的标题和副标题就能反映你文章的内容。
利用图像为你带来优势。精心挑选的图片充分说明了内容。如果你的图片有一个紧密反映你文章的主题,它会立刻吸引对这个主题感兴趣的读者。
全力以赴。润色你的开场白,确保它们反映了你的写作风格。这告诉读者你的方法是专业的,并设定了正确的期望。
让它变得有价值。抵制诱惑,不要在你的首段写满关于你自己的信息。读者想通过浏览第一段来了解文章的内容。如果他们在移动设备上看你的文章,他们只能看到这些。
如果你想了解更多关于制作好文章的知识,请关注我们作家工作坊系列中即将到来的专栏。
读者兴趣标签
发布文章时,利用“故事设置”>“故事预览”页面上的读者兴趣标签。这些标签对发表在 TDS 上的文章进行分类,帮助读者找到感兴趣的话题。您最多可以添加五个,因此混合使用高级术语和更具体的术语是有意义的。TDS 编辑器有时会编辑您的标签选择,以确保最相关的标签出现。我们与 Medium 密切合作,确保 TDS 中的故事符合 Medium 的编辑和发行标准,因此 TDS 中的故事经常会进一步发行。
多写文章
知名度在推广中很重要。它不仅影响你的搜索引擎优化(SEO),而且读者更有可能打开他们认识或听说过的人写的文章。随着你写作声誉的增长,你会发现大门是敞开的。
创造更多内容。我们最好的建议是建立一个高质量的团队。对于许多作者来说,这意味着写更多的文章,但也可能包括 YouTube 视频、研讨会或会议演示。
确立你的定位。许多作者通过专注于某个特定的领域来增加他们的声誉和追随者。这可能意味着写文章分享你的专业经验,但也可能意味着教程,或文章适合初学者。
保持你的势头。一旦你获得了追随者,重要的是不要失去他们。很容易忘记一个作者,即使他的文章你非常喜欢,如果他们离开视线太久的话。有点像十年不见的朋友。
通常写了一篇好文章的作者会纠结下一步该做什么。我们在 FAQ 中提供了一些建议,我们将很快就这个话题发表一个作家工作室专栏。对于那些寻找当前话题和数据集的人来说,我们也在努力撰写一个名为 The Spark 的新专栏。
分发列表
我们已经讨论了网络的重要性及其在建立联系人列表中的价值。但是你必须超越你认识的人。
Medium 提供了一个易于使用的选项,非常适合将读者添加到您的分发列表中。每个点击关注按钮的人都会被自动添加到您的个人列表中。最棒的是,这些新的联系人看到了你的作品,觉得他们想看更多。有点像发现黄金!
如果您在其他地方收集联系人,这些电子邮件地址可以导入到同一列表中。就这样,您拥有了一个共享您最新故事的中央分发列表!完整的细节可以通过媒体的电子邮件订阅和你的观众统计页面获得。
一些作者扩展了他们对分发列表的使用,以共享诸如时事通讯和提示表之类的东西。它们可能很有帮助,但也很有挑战性。虽然有些人可能已经注册了,也许是为了收到一份提示表,但不能保证他们会打开你发送的任何东西。
如果你打算走这条路,花点时间研究什么是有效的。
增值。如果你的时事通讯或出版物中充满了很棒的提示和建议,那么人们会更愿意参与进来。
不要过度宣传。失去你精心建立的追随者的最快方法是发送除了推广你的最新文章之外什么也不做的简讯。推广没问题,但是记住第一条规则:增值。考虑如何提供一些与文章相关的额外代码或技术。
分享自己的信息
读者不仅与文章联系在一起,还与作者本人联系在一起。这意味着你的媒体形象对你的文章有促进作用。
我们发现作者的照片和全名有助于建立作者和读者之间的信任。但你对自己的描述是你与读者的第一次对话。它建立可信度和联系。
介绍你自己。让你的读者了解你的工作、专业或兴趣。它可以是一个简单的列表,也可以是一个详细的陈述。最重要的是读者对你有所了解。
告诉我们更多。作者通常会忽略与他们个人资料相关的关于选项卡。在这里,有大量的空间让你分享一切,从你的专业追求到照片。
提高你的技术
这似乎是一个奇怪的关于推广的建议,但是一篇写得好的文章会让我们的读者和编辑团队眼前一亮,它可以让作者成为焦点。想想你自己对一篇好文章的反应。你可能会为它鼓掌,关注作者,也许还会留下评论。更重要的是,你可能也分享过,谈过——你 推广过 的文章。
我们在 TDS 也这样做。我们突出我们最好的文章和作者,扩大他们的影响。
社交媒体。除了通常的 Twitter 和 LinkedIn 帖子,我们最好的文章也会在脸书上分享。
编辑推荐。我们的编辑团队为我们的编辑精选页面挑选他们最喜欢的文章。除了在聚光灯下获得额外的时间之外,这些热门文章都有标签,这样读者就可以很容易地发现它们。
策展特色。我们的顶级文章和作者会在我们的可变时事通讯和月刊中突出显示。
作者聚光灯。我们定期邀请我们最有魅力和最多产的作者参加问答活动,向我们的社区介绍他们和他们的作品。
也许你写了一篇很棒的帖子,并遵循了上面的大部分建议,但仍然没有得到你希望的数万次浏览。那也行!成功需要时间!如果你继续写强有力的原创内容(你的前几个读者喜欢的),最终一些帖子会开始打破噪音。随着更多的观众发现你和你的作品,你的内容会得到更多的阅读和参与。
发现了另一个推广你文章的好方法?想了解更多这里提到的东西?
在评论中分享吧!您的问题或想法可能是我们下一篇文章的一部分。
加速 Python 循环的艺术
原文:https://towardsdatascience.com/the-art-of-speeding-up-python-loop-4970715717c
Python 中没有“最好的”循环技术,只有最合适的
" Python 中最快的循环技术是什么?"
这是一个合理的问题,但往往过于简单化。如果有一种循环方法比其他方法更好,那么其他的技术就会被弃用。
事实是,没有“最好”。
正如生活中的大多数事情一样,会有这样的情况,其中一个明显优于其他人,而在其他一些情况下,这绝对是垃圾。它们视情况而定。用 Python 思考循环优化的更好方式应该是这样的。
对您的用例来说,最佳的循环技术取决于一系列的决策。图片由作者提供。
它们中的每一个都有其自身的用处。我不想再写另一篇速度测试文章,我想强调是什么使它们独一无二,何时使用它们,以及如何使它们变得更好?你会惊讶地发现,通过一个简单的语法调整,我们可以将它们的性能提高 8000 倍。
循环技术的类型:
- 循环迭代
- 列表理解
- λ函数
- 矢量化运算
循环迭代
For-loops 是传授给 Python 初学者的入门级循环技术,因为它们易于阅读且用途广泛。
items = ['bat', 'cat', 'dog']
for item in items:
print(item)**>> bat
>> cat
>> dog**
然而,许多人认为 for 循环是高效编程的对立面。它们很慢,因为 Python 的 for 循环实现有非常大的开销(例如:类型检查等——稍后讨论),每次迭代都要执行。
有两种主要类型的 for 循环,即(I)索引循环和(ii)行循环。
索引循环
一个索引循环接受一个数字序列(例如:[0,1,2,…])并为序列中的每个元素运行代码逻辑。
在第一次迭代中,Python 在执行循环中的代码之前,将变量idx
赋给序列的第一个元素(在本例中为 0)。然后,idx
被重新分配给第二个、第三个……元素,循环重复,直到序列结束。
for idx in ['bat', 'cat', 'dog']:
print(f'Hello, I am index {idx}.')**>> Hello, I am index bat.
>> Hello, I am index cat.
>> Hello, I am index dog.**
当我们需要控制序列的起始索引、结束索引和步长时,索引循环非常有用。
例如,如果你想从第 1000 行循环到第 2000 行…
res = 0
for idx in range(1000, 2000):
res += df.loc[idx, 'int']
如果你只需要第 1000 到 2000 行的第 5 个元素…
res = 0
for idx in range(1000, 2000, 5):
res += df.loc[idx, 'int']
索引循环非常灵活,但是它们通常被认为是缓慢的循环技术。虽然在某种程度上是真的,但也不尽然!出于基准测试的目的,这里有一个简单的循环,它返回int
列的总和。
%%timeit
res = 0
for idx in range(0, 100000):
res += df.loc[idx, 'int']**>> 486 ms ± 4.28 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)**
我们可以实现相同的功能,但通过一个简单的优化技巧— np.arange()
可以获得更好的性能。
%%timeit
res = 0
for idx in np.arange(0, 100000):
res += df.loc[idx, 'int']**>> 60.3 µs ± 355 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)**
同样的代码,但是np.arange()
比range()
快 8000 倍。
原因如下。
range()
是一个内置的 Python 类范围,仅存储所需数字序列的起点、终点和步长。只有当我们开始遍历序列时,数字列表才会在幕后迭代生成。这可以节省内存,因为我们不需要一直存储整个序列,但由于生成数字的开销,这会影响性能。
np.arange()
则是第三方库(Numpy)功能。在功能上,它们类似于range()
,但是 NumPy 实现在 C 级上执行许多操作,包括循环,这比 Python 的性能好得多。它们针对使用向量进行了优化,避免了很多与 Python 相关的开销。
由于
range()
和np.arange()
做的是同样的事情,我推荐在需要索引循环的时候总是使用np.arange()
。
行循环
行循环遍历熊猫数据帧的行—第 1 行、第 2 行、…、第 n 行。每次迭代时,它返回特定迭代的行索引和行数据。行循环最常见的实现是DataFrame.iterrows()
函数。
for idx, row in df.iterrows():
print(f'row_idx: {idx}, row_data: {row}')**>> row_idx: 0, row_data:
animal bat
animal_type mammals
Name: 0, dtype: object****>> row_idx: 1, row_data:
animal dog
animal_type mammals
Name: 1, dtype: object****>> ...**
由于行循环返回行索引和行数据,这给了我们额外的能力——重命名行数据的能力。根据上面的例子,我们可以将行数据放入一个row
变量中,并通过row['col_name']
访问它。
代替我们通常在索引循环中使用的df.loc[idx, 'col_name']
,现在代码看起来,嗯,可能更简洁一点。但是真正的改进是在我们解包并重命名每个单独的列时开始的,就像这样…
# Better
res = 0
for idx, row in df.iterrows():
res += row['col3']# Even better
%%timeit
res = 0
for idx, (col1, col2, col3) in df.iterrows():
res += col3**>> 4.86 s ± 28.4 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)**
干净多了,对吧?
然而,就性能而言,行循环落后于索引循环。我们执行相同的逻辑,但是…
np.arange()
耗时 0.0000603 秒。range()
跑了 0.486 秒。DataFrame.iterrows()
跑了 4.86 秒。
好消息是——就像 Index Loop 一样——我们可以通过简单的改变来优化它。用itertuples()
代替iterrows()
。
%%timeit
res = 0
for row in df.itertuples():
res += getattr(row, 'int')**>> 160 ms ± 13.4 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)**
从表面上看,itertuples()
比iterrows()
快 30x 。但是为什么呢?iterrows()
和itertuples()
有什么区别?
对于好奇的灵魂,这里有一篇很棒的文章详细解释了它。TLDR 版本…
iterrows()
返回Series
对象中的行数据。它不保留数据类型,所以在循环时必须执行大量的类型检查。更多的检查=更慢的循环。itertuples()
返回tuple
中的行数据。它保留了数据类型,因此只需要最少的类型检查。更少的检查=更快的循环,快得多。在我们的例子中,itertuples()
比 ~30 倍于。
如果我们需要访问行数据,最好使用行循环而不是索引循环。此外,优先考虑
itertuples()
而不是iterrows()
,因为它要快得多。
列表理解
Python List Comprehension 是基于现有列表的值创建一个list
对象的一种简单而巧妙的方法。它有下面的一般表达式。
List = [expression(i) for i in another_list if filter(i)]
所以,不要…
%%timeit
for (idx, animal, animal_type, _) in df.itertuples():
if animal == 'dog':
animal_type = 'mammals'
elif animal == 'frog':
animal_type = 'amphibians'
elif animal == 'goldfish':
animal_type = 'fish'
else:
animal_type = 'others'df.loc[idx, 'animal_type'] = animal_type**>> 1min 41s ± 393 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)**
我们可以把这些废话浓缩成几行代码。
%%timeit
df['animal_type'] = ['mammals' if animal == 'dog' else
'amphibians' if animal == 'frog' else
'fish' if animal == 'goldfish' else
'others' for animal in df['animal']]**>> 16.7 ms ± 92.3 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)**
列表理解不仅更紧凑、更容易掌握,而且比普通循环迭代得更快。在这种情况下,列表理解比行循环快 6048 倍!
可悲的是,有一个限制。
请注意,我没有使用与其他部分相同的示例(我们根据int
列的总和进行性能基准测试)?
我不能。
List comprehension 的语法很简单,但是保持简单的意图也限制了它能做什么。例如,我们不能有一个变量在迭代时存储当前值的总和。即使我尝试了一种类似黑客的方式,在一个列表理解范围之外的函数中指定current_sum
,它仍然使用初始值current_sum
,而不是在每次迭代时更新。
old_list = [10, 20, 30, 40, 50]
print(f'old_list is... {old_list}')current_sum = 0
def get_cumulative_sum(x, current_sum):
current_sum += x
return current_sumnew_list = [get_cumulative_sum(x, current_sum) for x in old_list]
print(f'new_list is... {new_list}')**>> old_list is... [10, 20, 30, 40, 50]
>> new_list is... [10, 20, 30, 40, 50]**
总的来说,每个列表理解都可以在 for 循环中重写,但不是每个 for 循环都可以在列表理解中重写。如果你正在写一些复杂的逻辑,避免列表理解。
总而言之,列表理解只是迭代的语法糖。它通常比普通的循环要快,但是应该只用于简单的代码逻辑以保持可读性。
λ函数
在 Python 中定义函数时(通常的方式),我们需要给函数命名。Lambda 是另一种方法,它允许我们创建函数,但是没有名字。
# The usual way
def multiply_two(x):
return x * 2# Lambda function
multiply_two = lambda x: x * 2
这种类型的“无名”函数被称为立即调用函数表达式(IIFE)。它们一创建就被执行,不需要显式调用来调用函数。
用外行人的话来说,生命跑得更快。
但是 Lambda only 创建生命函数,它不执行函数——这就是为什么我们通常看到 Lambda 函数与 Panda 的DataFrame.apply()
一起使用。它将一个函数(lambda 或 not)作为参数,并将其应用于每一行(或每一列)。
# Apply the function to each column.
output = df.apply(lambda x: x*2, axis=0)# Apply the function to each row.
output = df.apply(lambda x: x*2, axis=1)
但是这些功能到底有多快呢?让我们比较一下列表理解和 lambda 函数。
%%timeit
def get_type(animal):
if animal == 'dog':
animal_type = 'mammals'
elif animal == 'frog':
animal_type = 'amphibians'
elif animal == 'goldfish':
animal_type = 'fish'
else:
animal_type = 'others'
return animal_type# List comprehension
df['animal_type'] = [get_type(x) for x in df['animal']]
**>> 21.7 ms ± 140 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)**# Lambda function
df['animal_type'] = df['animal'].apply(lambda x: get_type(x))
**>> 24.6 ms ± 187 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)**
虽然列表理解和 lambda 函数是根本不同的概念,但它们有非常相似的特征…
- 性能—相同。
- 灵活性——两者都更适合简单的代码逻辑。我们不能创建跟踪先前迭代输出的变量。
总结一下,lambda 函数和列表理解是 po-tae-toe 和 po-tah-toh。使用您更喜欢的语法。就我个人而言,我更喜欢列表理解,因为它们读起来更直观。
矢量化运算
矢量化操作就像搬房子。你宁愿…
- 装载一件家具,开到你的新家,卸下,然后重复?
- 把所有东西都装上,开到你的新家,一次卸完?
后者肯定更有效,它非常类似于矢量化运算的工作方式。
在非矢量化操作中,CPU 将单个值加载到内存中,执行计算,然后返回一个输出。它在每次循环迭代中重复这个步骤。但更有意思的是,CPU 的内存可以存储不止一个值——这意味着大部分 CPU 容量都处于闲置状态。
在向量化操作中,CPU 尽可能多地加载内存,这样我们就可以一次完成计算。开销的节省有助于大幅提高性能。
非向量化操作不会最大限度地利用 CPU 资源。图片由作者提供。
除了最大化 CPU 容量之外,矢量化运算还经常在用低级语言(例如:C)编写的优化的预编译代码中实现。这些语言本质上比 Python 更具性能,而且它们还避免了数据类型检查等开销。
理论已经足够了——这里有一个简单的矢量化操作。
*# Non-vectorised operation
def calc_result(row):
return row['col1'] +(row['col2'] * row['col3'])
df['result'] = df.apply(calc_result, axis=1)
**>> 984 ms ± 16.3 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)**# Vectorised operation
df['result'] = df['col1'] + (df['col2'] * df['col3'])
**>> 227 µs ± 1.39 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)***
矢量化运算的执行速度比非矢量化运算快到 4350 倍。代码很直观,读起来也更清晰。
除了对数字执行数学运算,矢量化运算还可以执行非计算运算,对其他数据类型也是如此。Jake VanderPlas 在他的 Python 数据科学手册中分享了一个关于可能的字符串类型矢量化操作的好参考。
*# Two examples of Vectorised Operation for String-type
df['result'] = df['String'].str.extract('([A-Za-z]+)', expand=**False**)
df['result'] = df['String'].str.split('T').str[0]# Two examples of Vectorised Operation for DateTime-type
df['result'] = df['Date'].dt.day_name()
df['result'] = df['Date'].dt.year*
但是,矢量化运算同时加载和运行所有内容这一事实也意味着它只能对每个输入值执行相同的运算。如果我们想将一列除以 2,它必须将该列中的所有值除以 2,没有例外。
换句话说,矢量化运算是最快的迭代方式之一,并且具有最简洁的语法。它们非常适合对整个数据序列应用简单统一的操作。但是如果我们试图应用条件逻辑(例如;if-then),请改用 Lambda 函数或 List Comprehension。
结束语
我希望这能帮助你看到每种循环技术的优点和局限性。“最佳”循环技术总是依赖于您正在实现的逻辑类型。
最后一点,这个比较并不详尽。为了简单起见,故意省略了一些小细节。这里的信息通常是正确的,但是对于不同的用例,你可能会遇到稍微不同的性能(例如:在字符串上矢量化的操作比较慢)。我建议你自己对循环计时,如果你真的想榨出优化的汁液,就使用线条分析器。
在那之前,祝你好运和成功。
人工智能 KPI 的艺术
原文:https://towardsdatascience.com/the-art-of-the-ai-kpi-3d6ed8a03994
创建 KPI 游戏计划
"不是所有能被计算的都有价值,也不是所有有价值的都可以被计算."-阿尔伯特·爱因斯坦
图片由作者大卫·e·斯威诺提供
有人说数据是新的石油。并不是,正如 2018 年世界经济论坛指出的。石油是一种有限的资源,需要亿万年才能开采更多的石油。一旦原油被提取、提炼和消费,就结束了。
用数据对比一下。正在创建的数据量超出了我们最大的想象——它以各种形状和大小出现,一些公司估计它正在以指数速度增长。事实上,最新的 IDC 全球数据圈预测表明,到 2026 年,这个数字将会翻一番以上。事实是,大量的可用数据对大多数人来说是不可理解的——一个 zettabyte 到底有多大?从某种角度来看,据估计“每天有超过 50 亿客户与数据进行交互,到 2025 年,这一数字将达到 60 亿,占世界人口的 75%。2025 年,每个连接的人每 18 秒至少有一次数据交互。”【1】预计到 2025 年将有 175 ZB 的数据。“如果你能够将整个全球数据圈存储在 DVD 上,那么你将拥有一堆可以让你登上月球 23 次或绕地球 222 次的 DVD。”这是一个很大的数据量,但也说明了 DVD 作为存储机制的低效。事实上,一克 DNA 可以存储大约 215 Pb(0.000215 zetta bytes)。【3】
这就是为什么我更愿意将数据视为一种可再生资源。当然,可再生能源包括安装太阳能发电厂、地热发电厂、生物质设施、水电大坝和风力涡轮机的成本。但是一旦它们就位,释放的能量将会持续很长时间。即使有持续的维护,前期投资也将提供持续的价值。
这种可再生性与 Bill Schmarzo 的书《数据、分析和数字转型的经济学》背后的概念联系在一起。一旦数据通过分析转化为更高的价值,您的组织将永久获得该价值。
数据转换的次数和方式没有限制,它的价值会不断增加。
原因如下。
在考虑 KPI 之前,先了解你的游戏计划
在能源公司投资开发一个网站之前,他们通常会衡量是否符合他们的公司战略。他们进行了大量的研究,以确保基础设施和设备能够获得积极、可持续、可观的投资回报。就风力涡轮机而言,重要的因素包括了解风力资源(最小平均年风速)、获得土地和资金的途径、靠近输电线路以及分区法规。
类似地,在组织开始任何分析和人工智能计划之前,企业领导人需要一个明确定义的业务战略。好的商业策略通常会产生目标和关键结果(okr)。为了实现这些 okr,组织将拥有由一个或多个项目组成的战略计划,每个项目通常都需要人工智能和分析。
“人工智能应该推动商业战略。”【4】
对于任何给定的项目,我总是鼓励企业领导人理解要做出的商业决策,然后从那里开始逆向工作。毕竟,我们不是为了建设风电场而建设风电场。我们建造它们是为了给社会提供价值,并回报我们的公司和市政当局。
没有明确的战略可能会带来灾难性的后果。当你的数据没有你想象的那么好时,你会得出错误的结论并浪费精力。或者,你可能花太多时间收集数据,以至于错过了机会之窗。一些公司过度投资于他们的数据科学团队,而在员工中传播数据素养方面投资不足。
我们与客户的对话从最终目标开始。我们的客户不断向我们展示对业务流程进行尽职调查的价值,以了解如何使用数据和分析来实现他们的业务目标。一切都从目标开始。
分析的关键绩效指标
随着当前经济的不确定性,首席数据和分析官面临着越来越大的压力,他们需要跟踪数据、分析和人工智能计划对业务成果的业务影响。在大多数组织中,这导致了关键绩效指标(KPI)的讨论。
但是我们为什么要关心 KPI 呢?根据麻省理工学院数字经济倡议的访问研究员迈克尔·施拉格的说法,“当应用于数字化转型工作时,KPI 可以推动业务战略并提供独特的竞争优势。”此外,Schrage 确定了企业提高 KPI 回报的七个基本特征。它们是:
1.KPI 有助于领导和管理。
2.KPI 有助于调整整个组织。
3.KPI 提供了客户的整体视图。
4.KPI 因素为决策提供信息。
5.KPI 数据在业务单位之间共享。
6.KPI 不会激增。领导者应该关注 3 到 6 个能够推动增长的 KPI。
7.KPI 充当机器学习(ML)的数据集。
那么,您的组织应该跟踪哪些最佳 KPI 呢?在回答这个问题之前,您的企业领导需要回答以下问题:
你想知道什么?
你需要知道多少?
你为什么想知道这个?
不知道和知道之间的价值或影响是什么?
一旦你知道了这些问题的答案,你就可以开始建立 KPI 来跟踪你的成功。
独立于数据、分析和人工智能,我们发现 KPI 通常涵盖以下维度:
财务 —收入增长、现金流、烧钱率、毛利
客户 —参与率、净推广分数、获取成本、转换率
支持&服务 —周转时间、平均解决时间、SLA 合规性、质量
员工 —流失和保留、满意度、敬业度
治理、风险、&合规性 —流程合规性百分比、审计合规性、非安全事件
数据和分析 KPI
仔细观察,当使用数据、分析和人工智能来交付战略计划时,组织应该跟踪哪些特定的 KPI?也许有。
分析公司 Gartner 最近发布了一份名为“每个高管都应该跟踪的 5 个数据和分析 KPI”、【6】的研究报告,描述了可以应用于数据、分析和人工智能程序的关键绩效指标。它们包括:
数据、分析和人工智能的业务影响
从数据创建到洞察并最终付诸行动的时间
数据质量
数据素养水平
数据、分析和人工智能风险
这些指标将帮助你从你的人工智能程序中获得更多,并避免在你试图使用它时浪费你的数据。
1.跟踪数据和分析的业务影响
这是一个很好的定义指标,因为它回答了这样一个问题:“由于我们在数据和分析方面的努力,指针移动了多少?”几乎组织中的每个人都想知道在数据、分析和人工智能方面的投资是否有回报,这是一个简单的答案。
但是项目可以产生影响,而不需要马上让收银机响起来。考虑几种不同的业务影响:
间接 —你不能将所有基于数据分析的决策与底线结果直接联系起来,但你可能仍然觉得自己在朝着正确的方向前进。或者,您可能还没有发现将数据驱动的决策与业务成果联系起来的正确指标;当您发现这些指标时,业务影响就不再是间接的了。
领先 —一些结果预测其他结果。假设两年前你的员工中有一个较低的净晋升分数,说服你去年增加人力资源部门的人数,而今年的生产率正在上升。一个具体成果导致另一个具体成果是有形的业务影响。
轶事——你不能确定在家工作是你的员工更有效率的原因,但他们中的许多人告诉你这就是原因。很容易衡量疫情之前和期间在办公室度过的时间。但是,由于几乎没有公认的方法来衡量所有的变量,你必须依靠轶事证据来证明在家工作与生产率的提高有关。
直接 —你能得到离科学方法——假设、测量、改变变量、测量、总结——有多近?例如,在线广告有着巨大的潜力,可以利用成千上万的数据点进行 A/B 测试和提炼。
触动——当多个团队、因素和人工智能的努力都在起作用时,很难将一个给定的结果归因于任何单一的元素。我喜欢思考这个问题:我如何测量我房子里的电的价值?没有电,我可能在黑暗中看不到墙,不能给我的设备充电,也不能尽情欣赏我最喜欢的节目。但是量化电力的投资回报率是相当困难的。尽管如此,努力和影响都是可以衡量的,所以,像电力一样,你可以自信地说,数据、分析和人工智能已经影响了某些结果。
鉴于这些不同的层次,你如何报告数据、分析和人工智能的商业影响?以此结构为例:
业务影响
本财年的总目标是:2500 万美元,而 2M 年初至今的实际目标是 2500 万美元
进步
用例 1: 80%正在进行中,进展顺利
用例 2: 20%正在进行,延迟 3 个月
用例 3: 100%完成
2.监控从洞察到行动的时间
随着时间的推移,数据可能会因为以下几个原因而变得陈旧:竞争对手抢了你的先机,客户的品味变了,不可控的经济因素开始起作用。
这就是为什么第二个指标关注您的组织从数据中获得洞察力并将其转化为行动的速度。无论您的出发点是一个明确的业务问题,还是对隐藏在数据中的洞察力的无指导搜寻,这种敏捷性(准备与机会的结合)都是您的竞争优势。
以下是跟踪和报告组织中从洞察到行动所经历的时间的指南:
从洞察到行动的时间:
目前:45 天
年底目标:7 天
流程改进
加快审批流程:完成 80%
提高数据素养:55%的员工接受了培训
加速 IT 参与:完成 10%
3.衡量数据质量
“我们怎么知道这些数据是好的呢?”
每当你通过数据、分析和人工智能获得新的见解时,这是一个合乎逻辑的问题,尤其是如果这种见解是意想不到的。它只能和它所基于的数据一样有效。
报告这一指标的关键不是简单地命名数据来源,而是量化数据当前的可信度,并指出改进的途径:
数据质量
目前:70%的销售预测基于未经核实的数据
EOY 的目标是:10%
流程改进
取消手动对账流程(潜在客户数据):100%完成
培训数据输入员工(客户数据):完成 25%
4.跟踪数据素养水平
当大多数公司听到“数据驱动”时,他们通常会想到“技术”但数据、分析和人工智能的成功更多地取决于技能和人,而不是技术。
这就是为什么在企业的所有职能部门中跟踪和报告贵公司在数据素养方面的进展非常重要。众所周知,受过专业培训的数据科学家供不应求,因此聪明的公司会提高现有员工的技能,以便更快地做出更明智的决策。数据素养培训向人们展示如何从数据中检索、分析和获得见解,然后传达这些见解并将其转化为行动。数据素养从高级数据科学家延伸到公民数据科学家,它是数字化转型的核心。
在报告该指标时,请考虑以下结构:
数据识字率
目前:35%的员工已经完成了该计划
EOY 的目标:100%
进步
采用自助报告和仪表盘
员工对其新技能有用性的调查结果
5.量化数据、分析和人工智能风险
你的一个或多个数据、分析和人工智能项目被滥用的可能性有多大?如果你的工作变得一团糟,变得没有价值,变成了废物,你的公司会面临怎样的风险?
敏感数据通常会违反法规和行业标准。如果您维护着一个客户数据仓库,而有人忘记启用加密,您会在补救措施和声誉方面花费多少时间、金钱和精力?
以下是量化暴露风险的一个角度:
数据、分析和人工智能风险
目前:1700 万美元的数据风险
EOY 的目标:500 万美元
进步
接受道德审查的项目:30%
接受隐私影响评估的项目:80%
接受数据保护影响评估的项目:55%
结论
数据、分析和人工智能是您竞争优势的一部分,是您对客户做出的承诺的一部分,也是您对投资者和潜在客户的感知价值的一部分。
聪明的领导者注重将公司的数据作为战略资源来管理。上面概述的指标旨在让领导者掌握数据的脉搏,防止数据变得混乱。
您可以使用这种自我评估来评估您组织的分析成熟度,接收个性化报告,并获得用例来帮助您开始规划下一个项目的 KPI。
赖因斯尔、大卫、约翰·甘茨和约翰·里德宁。2018.“世界从边缘到核心的数字化。”https://www . Seagate . com/files/www-content/our-story/trends/files/IDC-Seagate-data age-white paper . pdf .
【2】同上。
【3】服务,罗伯特 F. 2017。" DNA 可以在一个房间里储存世界上所有的数据."www.science.org。2017 年 3 月 2 日。https://www . science . org/content/article/DNA-could-store-all-world-data-one-room。
【4】戴维·斯威诺。2022.人工智能:让人工智能为你的企业服务的执行指南 TinyTechMedia LLC。https://www . Amazon . com/Artificial-Intelligence-Executive-Guide-Business/DP/b 09 x4 ktys 4/。
【5】伊斯特伍德,布莱恩。2021.“数字业务需要新的 KPI。这就是它们重要的原因。”麻省理工斯隆学院。2021 年 5 月 11 日。https://MITS loan . MIT . edu/ideas-made-to-matter/digital-business-needs-new-KPIs-heres-why-them-matter。
Buytendijk,Frank 和 Alan D. Duncan。2022."每个高管都应该跟踪的 5 个数据和分析 KPI . "Gartner.com。高德纳公司https://www.gartner.com/document/4014751.
层级可视化的强大力量
原文:https://towardsdatascience.com/the-awesome-power-of-hierarchy-visualizations-466274d16e8
通过将数据视为一个层次结构,将您的数据分析和可视化提升到一个新的水平
叶夫根尼娅·利托夫琴科在 Unsplash 上的照片
注意:上图的灵感来自于一个径向树图(显示在文章末尾)
我们习惯于用表格的方式查看数据。例如,我们看到的大部分数据都在数据库表格或表格应用程序中,如 Excel 或 Google sheet。
但是,以层次结构的形式查看数据对理解数据有很大帮助。此外,大多数数据都有某种层次模式。因此,对数据进行层次可视化有助于将数据转化为强大的洞察力。
在一些数据中,等级是明显的。以销售数据为例,该数据包含区域、国家、城市、销售额等字段。层级非常明显,区域→国家→城市→销售。
然而,让我们从一家电信公司获取一个客户数据集。该数据集包含人口统计信息、服务、账单信息以及客户是否有过交易。
电信客户流失数据集(图片由作者提供)
注意:数据集引用在文章的结尾
在这个数据集中,层次不是很明显。我们倾向于将其视为“平面数据”,我们所有的分析都是在这种“平面数据”假设下完成的。然而,从层次的角度思考可以让你的数据分析和可视化更上一层楼。让我告诉你怎么做。
从枯燥的视觉效果转移到高级层次可视化
层次可视化是最先进的和令人惊叹的视觉效果之一。它们还有助于将数据转化为有力的见解。在上面显示的电信数据集中,您可以将性别→互联网服务→支付方式→总费用视为一个层级。
这里有一些高级层次可视化,看起来不错,也给你强大的洞察力。下面显示的是一个树状图,这是一种可视化层次数据的自然方式。
树状图可视化(图片由作者提供)
与条形图等标准可视化相比,树状图在视觉上非常吸引人。此外,它提供了非常强大的洞察力。例如,我们可以观察到,与其他服务相比,光纤服务收费较高。
您还可以添加悬停效果,如下所示。这对于数据叙事非常有用。
具有悬停效果的树状图(图片由作者提供)
提高您的数据探索效率
假设我们想要开发一个机器学习模型来预测电信数据集中的流失。机器学习中的一个重要步骤是进行数据探索,以了解哪些特征是相关的。
通常的方法是制作输入特征相对于目标变量(流失)的直方图、条形图或散点图。然而,使用这种方法,您拥有的输入功能越多,您将需要更多的可视化。该方法可能会因为大量的特征而变得复杂。
层级可视化具有在一个画面中同时显示多个特征的能力。这是非常强大的,因为您可以提高您的数据探索生产力。
Sankey 图是一个非常强大的层次可视化工具。它可用于同时显示多个特征。下图显示了电信数据集中各种功能的 Sankey 图。
Sankey 的不同级别对应于层级性别→电话服务→互联网服务→合同。层级之间的“流”的厚度是基于流失的。
桑基图(图片由作者提供)
我们可以观察流的厚度,以得出哪些特征与预测流失相关的结论。女性和男性的性别层次的厚度是相似的。这意味着女性搅拌者和男性搅拌者数量相等。这意味着性别特征与机器学习模型无关。
另一方面,特征合约具有不同的厚度,逐月、一年、两年。这意味着大多数买家都是签有短期合同的客户。所以契约是机器学习模型的一个重要特征。特色互联网服务也是如此。
正如您所观察到的,我们只需要一个单一的可视化来进行一些非常强大的数据探索。提高生产力的好方法!
以优雅的方式查看大量数据
大多数可视化显示部分数据。然而,层次可视化能够以非常优雅的方式在单个可视化中向您显示大量数据。
让我用一组汽车数据来说明这一点。这里显示了一个样本数据集。这些数据包括汽车的构造、不同的技术特征,如燃料类型、长度、宽度、车门数量等。以及汽车的价格。
汽车样本数据(图片由作者提供)。
注意:数据集引用可在文章末尾找到
径向树是在单个视图中打包大量数据时非常有效的层次可视化之一。
辐射状树的美妙之处在于它是圆形的。因此,它可以有效地利用屏幕上的所有空间来表示大量数据。
径向树(图片由作者提供)
数据集中大约有 100 多个汽车模型。所有这些都优雅而清晰地显示在可视化中。你也可以把一辆车的不同特征看成一个层级。价格信息也根据节点的颜色显示。这是一种将大量信息打包在一个视觉画面中的好方法。
注:放射树的圆形本质也是文章开头形象的灵感来源
结论
层次可视化有很多用途,从强大的可视化到提高数据科学的生产力。对于任何数据科学家和数据分析师来说,这都是一个很好的补充。
额外资源
网站(全球资讯网的主机站)
你可以访问我的网站,使层次可视化和其他零编码分析。https://experiencedatascience.com
媒体订阅和推荐链接
请 订阅 每当我发布一个新的故事时,请保持通知。
您也可以通过我的 推荐链接 加入 Medium
Youtube 频道
这是我的 YouTube 频道
https://www.youtube.com/c/DataScienceDemonstrated的链接
数据源引用
电信客户数据集
根据本链接https://developer . IBM . com/terms/download-of-content-agreement/中规定的协议,它可用于商业和非商业用途
汽车数据集
数据来自 https://archive.ics.uci.edu/ml/datasets/automobile。
Dua d .和 Graff c .(2019 年)。UCI 机器学习知识库[http://archive . ics . UCI . edu/ml]。加州欧文:加州大学信息与计算机科学学院。
基本比率谬误
原文:https://towardsdatascience.com/the-base-rate-fallacy-b94c0a1b9938
开始抑制行为偏差的最简单和最有效的方法是获得正确的基础利率。本文解释了原因和方法。
查看页面底部的正确答案(来源:维基媒体
基本比率谬误是一种忽略基本比率信息(例如人口或样本的平均值)并专注于特定信息(例如与某个案例或少数案例相关的数据)的趋势(Bar-Hillel 1980、Tversky 和 Kahneman 1982)。基础率谬误有时也被称为基础率偏差或基础率忽视。
如果你玩扑克,假设的赔率不同于适用的赔率,那么你就受制于基础利率谬误——很可能会输。客观赔率是基本利率。
人们经常认为他们所掌握的信息比实际情况更相关。
人们经常认为他们拥有的信息比实际上更相关,或者他们对他们没有的所有相关信息视而不见。这两种情况都会导致基础利率谬误。
“概率忽略”——sun stein(2002:62–63)创造的一个术语,指的是人们过度关注可能性很小的坏结果,例如恐怖袭击——是基础率谬误的一个特例。
其他偏见助长了基础利率谬误,例如独特性偏见,这导致了极端的基础利率忽视,因为手头的案例被认为是独特的,因此其他案例的信息被认为是不相关的。
内部观点、后见之明偏差、可用性偏差、 WYSIATI 偏差、、过度自信偏差和框架偏差也助长了基础利率谬误。
当有一个好的,强有力的故事时,基本率的忽视尤其明显。
当有一个好的,强有力的故事时,基本率的忽视尤其明显。大型、不朽的项目通常都有这样的故事,导致对这些项目的额外忽视。
最后,人们——包括专家——低估了方差。因此,在典型项目中,根据以下公式,基本速率忽略与变化忽略相结合:
基本利率忽略+变异忽略=强凸性
我们研究的初步结果表明,在决策过程中,变异忽略比基本率忽略受到的关注少,这是很不幸的,因为研究还表明,变异忽略通常比基本率忽略更大,对项目结果的影响甚至更大。
正如项目管理铁律所记载的那样,基本比率谬误在项目规划和管理中泛滥成灾。表 1 显示了项目管理中成本和效益的基本费率的最全面的概述,它基于涵盖八种项目类型的 2,062 个项目的数据。
大多数项目都没有得到正确的基础利率——甚至没有接近。
我们看到,大多数项目没有得到正确的基本利率,甚至没有接近,正如在如此高的统计显著性水平上不同于 1(1.0≈正确的基本利率)的平均值所记录的那样(p < 0.0001 ≈ “overwhelmingly high,” in statisticians’ language) it is rarely found in studies of human behavior. The base-rate fallacy is deeply entrenched in project management, the data show. Flyvbjerg and Bester (2021) argue that base-rate neglect results in a new behavioral bias, which we call the “成本效益谬误),这通常会破坏项目的成本效益分析,以至于此类分析不可信。
正如 Kahneman (2011: 150)所指出的,“任何在概率评估中忽视基础利率和证据质量的人肯定会犯错误。”在项目管理内外,基本比率谬误的治疗方法是通过采取外部观点来获得正确的基本比率,例如通过参考类预测,执行预决策,或进行决策卫生学(Flyvbjerg 2006,Klein 2007,Kahneman 等人 2011,2021:312–324,371–72)。
如果你是一名项目策划人或经理,开始控制工作中的行为偏差的最简单和最有效的方法是为你负责的项目设定正确的基本比率。
如果你不了解一个游戏的真实赔率,你就不太可能成功。
希望大多数人能明白,如果你不了解一个游戏的真实赔率,你就不太可能成功。但是这是大多数项目计划者和经理的情况:他们没有得到他们正在玩的游戏的正确几率:项目管理。表 1 毫无疑问地证明了这一点,并为项目管理中的许多重要领域建立了现实的基本费率,规划者可以将其作为正确实施项目的起点。由于篇幅原因,没有包括其他项目类型的数据,但我有数据,它们显示了类似的结果。
………………..
)有关完整参考资料,请参见 Flyvbjerg,Bent,2021,“项目管理中的十大行为偏差:概述”,《项目管理杂志》*,第 52 卷,第 6 期,第 531–546 页。免费下载这里。
页面顶部测验的正确答案:41%。
基本要点:机器学习的统计学
原文:https://towardsdatascience.com/the-basic-essentials-statistics-for-machine-learning-dd9cfeb0e5ef
提高您与数据交流的能力
贾斯汀·摩根在 Unsplash 上的照片
如果你处理数据,统计学知识是很重要的。牢牢掌握一些基本概念对你有效沟通的能力大有帮助。您还将了解收集、分析、做出决策以及有效展示从数据中发现的结果的正确方法。
在本文中,我们将使用来自 sklearn 的乳腺癌威斯康星州数据集来涵盖一些基本的统计学概念。这是一个包含 569 个观测值和 30 个要素的分类数据集。
下面我们已经导入了必要的框架,并将数据加载到内存中。
**import** pandas **as** pd
**import** seaborn **as** sns
**import** matplotlib.pyplot **as** plt
**from** sklearn.datasets **import** load_breast_cancerX, y = load_breast_cancer(return_X_y=True, as_frame=True)
基础知识
一旦建立了一个数据集,首先要做的事情之一就是检查它。这个想法是为了收集关于数据是否包含您所期望的内容的信息,但是这个过程也会产生一些见解,您可以在进行数据预处理时将这些见解作为种子保留下来。
首先要理解的是关于数据的事实。这意味着你要清楚地知道:
- 数据维度— 知道你有多少数据是很重要的。你拥有的数据量可能是使用哪种机器学习算法的决定因素,或者是你是否删除/添加某些功能的决定因素。
- 数据类型— 了解可用数据的类型很重要,因为这将影响我们进行的统计测试的类型。此外,大多数机器学习模型只能处理数字,因此最好事先知道可用数据的类型,以便可以将其转换为适合 ml 算法的格式。
- 缺失数据— 这又回到了了解你已有的数据上。数据可能由于各种原因而丢失,但对于大多数机器学习模型来说,必须事先对其进行处理(即插补或删除)。
让我们看看我们的数据及其维度:
**print**(f"feature dimensions: {X.shape}\n\
target dimension: {y.shape}")X.head()
注意:桌子的一部分被切掉了,这样可以清晰地抓图;作者图片
熊猫用None
或NaN
代表缺失值。我们可以通过在熊猫数据帧上使用info()
方法来检查缺失值和特征的数据类型。
X.info()
所有特征信息;作者图片
Non-Null Count
列显示我们的数据集中没有缺失值;我们的数据中有 569 个观察值,数据集中有 569 个非空值。
Dtype
代表数据类型。该列告诉我们数据集中每个要素的数据类型,我们可以看到它们都是float64
。
描述统计学
统计有两种:描述性和推断性。
推断统计学指的是从数据中做出推断,例如抽取样本以对总体做出概括。另一方面,描述性统计用于更好地描述数据。
当熟悉一些数据时,利用描述性统计很重要,因为这在推断过程中起着重要作用。
需要注意的一些描述性统计术语有:
数数
计数听起来很简单:你拥有的项目或观察的数量。了解计数至关重要。如果你希望正确地评估你的结果,那么你必须清楚地知道在你的数据中有多少项目或观察结果。
平均
平均值是这些数字的平均值;计算平均值就像计算观察值的总和并除以它一样简单,但是观察值的数量。
平均值的公式;作者图片
这很重要,因为它在计算中考虑了人口中涉及的每一个主体。但是,出于同样的原因,对于发现集中趋势来说,这可能是一种糟糕的测量方法,即,偏态分布中的异常值会对平均值产生影响。
标准偏差
标准差衡量一组值的变化量。它的计算方法是将平均值除以数据大小,得到平方差之和的平方根。
标准差的公式;x_i 是来自总体的每个值,μ是平均值,N 是总体的大小,σ是总体标准差;作者图片
我们通常将标准偏差与平均值结合使用来总结连续数据,大约 95%的值落在平均值的两个标准偏差范围内。与平均值类似,当数据明显倾斜或存在异常值时,标准差会受到影响。
最低限度
最小值是指数据集中的最小值。
第 25 百分位
第 25 个百分位数(也称为下四分位数或第一个四分位数)是数据中 25%的值在排列时低于的值。
中位数(第 50 百分位)
中位数是一组数值的中间数。它是将上半部分和下半部分分开的值。它的目的是告诉我们数据集的中心值,当数据有偏差或存在异常值时,它比平均值更有用。
第 75 百分位
第 75 个百分位数(也称为上四分位数或第三个四分位数)是数据中 75%的值按升序排列时低于的值。
最高的
最大值是指数据集中的最大值。
让我们看看如何在数据集中找到这些信息:
X.describe()
关于数据集中特征的描述性统计;作者图片
你也可以看到在某些圈子里讨论的四分位数范围。这是指第 75 百分位(Q3)和第 25 百分位(Q1)之间的差异。
单变量分析
单变量分析可能是统计分析最简单的形式。它包括相互独立地探索数据集的各个要素。
从这种类型的分析中获得的有用信息包括诸如值的范围、集中趋势、偏斜度和组的分布等。我们已经讨论了如何分析值的范围(即最小值、最大值、百分位数和 IQR),但是我们没有过多地讨论偏斜和分布。
让我们先看看这个类的分布,然后我们会讨论为什么分布是重要的。
counts = y.value_counts()plt.subplots(figsize=(8, 5))
sns.barplot(x=counts.index, y=counts.values)
plt.title("Distribution of target label")
plt.xlabel("Target classes")
plt.ylabel("Counts")
plt.show()
分配目标标签;作者图片
前面我们说过,理解数据中可用的数据类型很重要,因为这影响我们对统计检验的选择:出于同样的原因,我们需要知道数据的分布。
对于分类问题,我们需要知道类的平衡程度。高度不平衡的班级的问题可能需要一些手动处理,以帮助我们的机器学习模型更好地预测少数民族班级。
我们也来看看我们的特征分布。
X.hist(figsize=(18, 16))
plt.show()
分布特征;作者图片
直方图是表示数字数据分布的一种很好的方式;我们可以从上图中发现每个特征的偏斜度。这告诉我们关于平均值的概率分布的不对称性的测量——我们也可以学习特征的模态,即峰值的数量。
理解数据的形状非常重要,因为它告诉我们关于数据的大部分信息在哪里。这也很重要,因为某些模型对我们的数据做出假设,如果我们的数据与这些假设一致,就会产生更好的模型。
我们了解数据偏差的另一种方法如下:
X.skew()
五官的歪斜;作者图片
偏斜值为 0 表示数据完全对称。如果偏斜度大于 1 或小于-1,那么我们有高度偏斜的数据。对于介于-1 比-0.5 和 0.5 比 1 之间的特征,我们会说它们是适度偏斜的。
双变量分析
双变量分析是统计分析的第二种最简单的形式。它指的是分析两个变量以确定它们之间的关系。如果两个变量之间有关系,那么就会有相关性。
热图是可视化数据集中关系的一种方式。
plt.subplots(figsize=(18, 16))
sns.heatmap(X.corr(), annot=True)
plt.show()
作者图片
随着对数据中的关系有了更深入的了解,我们可以收集更多关于数据的信息,并知道如果我们知道一个变量的值,预测另一个变量的值在多大程度上变得更容易。
这个列表并不全面,但它是一个很好的入门基础。一旦你已经掌握了这些概念,你可能还想了解其他概念,包括理解峰度、假设检验和置信区间。
感谢阅读。
如果你喜欢阅读这样的故事,并希望支持我的写作,可以考虑成为一名灵媒。每月支付 5 美元,你就可以无限制地阅读媒体上的故事。如果你使用我的注册链接,我会收到一小笔佣金。
已经是会员了?订阅在我发布时得到通知。
https://kurtispykes.medium.com/subscribe
自然语言处理基础
原文:https://towardsdatascience.com/the-basics-of-natural-language-processing-25002d093eb9
领域中使用的常用术语和预处理步骤
在 Unsplash 上由Towfiqu barb huya拍摄的照片
当我第一次接触自然语言处理的世界时,我被大量的术语所淹没。当我试图学习行话时,我觉得许多网站的解释包含了更多的行话!一旦我最终学会了行话,我就开始了 NLP 中最基本的任务之一——预处理数据。大多数教程以相同的顺序讲述相同的步骤。直到我开始探索我自己的数据,我才意识到我可能只想在某些情况下应用一些步骤。
在本文中,我将介绍
- 简单英语中 NLP 行话的含义
- 常见预处理步骤以及何时使用它们
什么是 NLP
当人类用自然语言交流时,计算机理解一种叫做二进制的机器语言。自然语言处理是计算机理解自然语言(即人们如何交流)的过程。
人们很容易想当然地认为语言有多复杂。在《机器学习的自然语言标注》一书中, Pustejovsky 等。all 描述了语言的九个层次:
- 句法 —研究单词如何组合成句子。
- 语义 —语言的意义。
- 形态学——研究一个单位的意义。
- 音系学——研究声音模式。
- 语音学——研究人类说话的声音以及它们是如何被感知的。
- 词汇——对一种语言的单词和短语的研究。
- 话语分析——研究像对话这样的信息交流的意义。
- 语用学——研究文本的语境如何影响其意义。
- 文本结构分析——研究文本风格如何组合成更大的作品。
下次你因为 Alexa 不理解你的问题而感到沮丧时,记住她必须尝试处理和理解所有九层!
NLP 行话
当你开始学习自然语言处理时,你可能会觉得这是另一种语言,因为你会看到所有的行话。让我们浏览一下常用术语。
代币
标记是自然语言处理中的基本单位,可以看作是一个或多个字符的组合。一个标记可能是字符级的,意味着一个字符代表一个标记,或者是单词级的,意味着一个单词代表一个标记。记号化是将一段文本分解成更小单元(记号)的过程。
我们可以选择修饰一个句子,比如“她在 11 个月前得到了这份工作。”在字或词的层面。如果我们选择字符级,我们的句子将变成下面的列表:
" S "," h "," e "," w "," a "," s" …等等。
如果我们选择在单词级别进行标记,我们的句子现在看起来像这样:
“她”、“曾经”、“提供”、“工作”……等等。
N-grams
我们可以进一步扩展字符和单词级标记化,并将标记组合在一起形成 n 元语法。
这里有一个在单词和字符级别为我们上面的例句创建一元词( n=1 )、二元词( n=2 )和三元词( n=3 )的例子。
人物级别单字:【S】【h】【e】【w】【a】【S】……等等。
人物层面的二元词:“Sh”、“他”、“wa”、“as”、“of”、“ff”、“fe”, …
词级单字:“她”、“曾”、“献”、“该”、“职” …
词级连词: “她被”、“被献”、“被献” …
词级三元组: “她被录用了”、“被录用了”、“被录用了”…
文件
在自然语言处理中,您会经常听到术语文档,这可能会让您想起 Word 文档的图像。虽然这是一个有效的文档示例,但其他一些文档示例包括 tweet、Amazon review 甚至是 blog post。本质上,文档是一组标记。
图 1 —两个文档的示例。图片作者。
文集
语料库是文档的集合。我们可能有推特、亚马逊评论或博客文章的语料库。语料库中的文档可以有不同的长度,甚至可以是不同的语言。请注意下面的图 2,文档 1 有一个句子,而文档 2 有两个句子。
图 2 —文档的集合被称为语料库。图片作者。
词汇
词汇表是语料库中唯一的标记集。在下面的例子中,我们已经在单词级别对我们的文档进行了标记化,以形成单字。请注意,、和、被认为是两个不同的标记,尽管它们是同一个单词。这是由于大写字母 T 造成的,通常通过将所有文档转换为小写作为初始预处理步骤来纠正。
图 3 —词汇表是语料库中唯一的一组标记。图片作者。
预处理步骤
现在我们已经讨论了 NLP 术语,让我们来讨论如何为计算机更好地理解文本做准备。预处理的目的是规范化和清理文本数据。大多数文本数据都有一套标准的预处理步骤,但是这些步骤的应用没有一定的顺序。事实上,根据您的用例,您甚至可以选择排除一些步骤。
小写字母
虽然人类很容易理解" It" 和" it" 是同一个词,但计算机却不理解。为了不影响字数,将文本数据小写通常是很重要的。然而,也有让数据保持原始形式的用例。假设你正在分析情绪(一段文字是积极的,消极的,等等。)并希望对所有大写字母的单词给予更多权重,因为此人可能更有激情。如果您将文本小写,您可能会丢失有关文本语气的信息。
删除标点符号
类似于我们之前的例子,计算机无法理解" It "和" it "是同一个单词,计算机也无法理解" it、"、" it "。“,还有“它!“是同一个词。从文本中删除标点符号的目的是为了准确计算字数而将其规范化。像大写字母一样,标点符号也可以传达语气。当写作更有激情时,你可以保留一些标点符号,比如感叹号。
删除号码
我们通常从文本中删除数字,因为它们对理解文本的意义没有多大价值。但是,例如,如果您需要知道文档中引用的年份,您可以选择保留数字。
删除停用词
停用词是常见的词,如“”、“it”、“is”等。它们通常不会帮助我们理解文章的意思,因为它们太普通了。停用词几乎总是从文本中删除,但是如果您的数据包含类似“ IT ”的缩写(可能代表“信息技术”),您可以保留它们,或者删除它们的一个较小的子集。小写【IT】改为【IT】,为停用词,被删除。在这个例子中,你会丢失文本中的重要信息。
标记化
记号化是将文本分成更小单元(记号)的过程。我们可以通过分析记号序列来解释文章的意思。标记化最终允许我们将文档表示为一个向量。根据我的经验,这是一个预处理步骤,你总是应用于你的数据。
词干化或词汇化
虽然人类可以理解【研究】【学习】**【学习】都是指去学习,但计算机却将它们视为不同的单词。有两种技术可以帮助将这三个单词组合在一起:词干化和词汇化。词干化去除了一个单词的后缀,而词干化则将其还原为词根形式。
虽然词干化通常比词汇化在计算上更快,但词汇化通常更易于人工分析。如果我们对“麻烦”、“困扰”、“T9”和“困扰”、“进行词干分析,我们会得到一个词根形式的“troubl”,这对人类来说可能不太可读。虽然词汇化通常可读性更强,但它也会改变单词的意思。比如“好”“更好”**“最好”都可能被词条化为“好”。在情感分析上下文中,“更好”和“最好”比“好”具有更强的情感。****
概述
在本文中,我们介绍了 NLP 的基础知识,包括使用的术语和常见的预处理步骤。标准的预处理步骤包括小写、删除标点、删除数字、删除停用词、标记化以及词干化或词条化。批判性地思考您的数据和您正在使用的预处理步骤非常重要,因为这可能会导致您丢失关于文本数据的信息。
如果你喜欢这篇文章,我们也在 Skillshare 上教授数据科学课程。我们涵盖了本文中讨论的概念以及更高级的主题,如命名实体识别。你可以使用我们的推荐链接这里获得 Skillshare 的免费试用。
参考
- 普斯特约夫斯基等人。all,机器学习的自然语言标注(2012),https://www . oreilly . com/library/view/building-Machine-Learning/9781492045106/
- https://www . skillshare . com/classes/Natural-Language-Processing-with-Python/18583602
神经网络基础(神经网络系列)——第一部分
神经网络
人工神经网络(ANN)或简称为神经网络(NN)是称为节点的小单元的互连层,这些节点执行数学运算以检测数据中的模式。神经网络算法是以模拟人类神经元工作方式的方式构建的(我们将在文章的最后一节讨论两者之间的联系)。
定义
在我们深入探讨之前,下面是我们在讨论神经网络(NNs)时将使用的关键术语。
- 神经元 —这是神经网络的基本构建模块。它接受加权值,执行数学计算并产生输出。它也被称为单元、节点或感知器。
- 输入 —这是传递给神经元的数据/值。
- 深度神经网络(DNN) —这是一个具有许多隐藏层(输入(第一)层和输出(最后)层之间的层)的 ANN。
- 权重 —这些值解释了任意两个神经元之间连接的强度(重要程度)。
- 偏差 —是一个常数值,加到输入值和各自权重的乘积之和上。它用于加速或延迟给定节点的激活。
- 激活函数 —用于将非线性现象引入神经网络系统。这个特性将允许网络学习更复杂的模式。
注:权值和偏差是 NN 中的可训练参数,即网络通过调整这些参数来学习模式,以获得最佳预测。
人工神经元——一个神经元上的数学运算
人工神经元接受输入值(可以是几个)并为其分配权重。在节点内部,对加权输入进行求和,并应用激活函数来获得结果。该节点的输出被传递到其他节点,或者在网络的最后一层的情况下,该输出是网络的总输出。
图 1:一个有 n 个输入值的人工神经元(来源:作者)。
如上图所示,单个神经元执行以下数学运算:
等式 1
在这个等式中,发生了四件事情——输入乘以各自的权重并相加,偏差被加到结果中,然后应用激活函数g
,使得神经元的输出为g(**w**·**x**+b)
。
神经网络设计
神经网络(NN)是由几个层叠的神经元组成的。对于一个n
维输入,第一层(也称为输入层)将有n
个节点,而t
维最终/输出层将有 t
个神经单元。所有中间层都称为隐藏层,网络中的层数决定了模型的深度。下图显示了一个3–4–4–1
NN。
图 2:一个神经网络,有 3 个输入特征,两个隐藏层,每个层有 4 个节点和一个值输出。节点是密集连接的——每个节点都连接到上一层的所有神经元。每个连接都具有表示任意两个节点之间的连接强度的权重。除了输入层的节点之外,每个节点都执行等式 1 中描述的计算(来源:作者)。
简化示例
让我们举一个简单的例子来说明单个神经元是如何工作的。在本例中,我们假设有 3 个输入值,偏差为 0。
图 3:具有 3 个输入值 2、1、-4 和权重分别为 0.8、0.12 和 0.3 的人工神经网络。在这种情况下,偏置设置为 0。
在这个例子中,我们将考虑一个被称为 sigmoid 的常用激活函数,它被定义为(我们将在本系列的下一部分中全面讨论激活函数)
Sigmoid 函数(f(x))及其导数(f'(x))。sigmoid f(x)将任何实数值 x 推入范围(0,1)。这时不要太在意导数。我们以后再讨论。
这是一个 sigmoid 图。注意,对于小于-5 或大于 5 的 x 值,f(x)分别接近 0 和 1。
如前所述,神经元内部正在发生四件事。首先,通过将输入值乘以相应的权重来对输入值进行加权。
第一个操作:输入值被加权。
接下来,对加权输入求和,然后加上偏差,
第二个操作:加权输入和偏差求和
最后,对上述结果应用 sigmoid 激活函数
第三次手术:应用乙状结肠功能。
就是这样。神经元的输出是0.627
。如果给定的神经元在隐藏层中,则该输出成为下一个神经元的输入。另一方面,如果这个值是最后一层的输出,那么它就可以解释为模型的最终预测(可以看作是给定类的概率)。
重要提示:为了简化神经元的数学运算,我们可以使用前两个运算的更紧凑的矩阵形式。在这种情况下,输入值向量和权重向量之间的点积运算将会派上用场。
如前所述,人工神经元(NN 的基本构件)的运行是受人脑工作方式的启发。在下一节中,我们将详细讨论这种关系。
生物神经元与人工神经元的联系
生物大脑中的神经系统由两类细胞组成:神经元和神经胶质细胞。神经胶质细胞为神经系统提供支持功能。具体来说,这些细胞的任务是维持体内平衡,形成隔离神经的髓鞘,并参与信号传递。
神经元由细胞体、轴突和树突组成。树突是作为神经元输入的投射。它从其他神经元接收电化学信息,并将它们传播到细胞体。另一方面,轴突是神经元的长延伸,将信息从细胞体传输到其他神经元、腺体和肌肉。轴突以称为轴突小丘的圆锥形投影连接到细胞体。小丘负责将抑制性和兴奋性信号相加,如果总和超过某个阈值,神经元就会发出信号(称为动作电位)。两个神经元在突触处连接。突触位于第一神经元的轴突末梢和第二神经元的树突。
生物神经元(左)和人工神经元(右)。
人工神经元
人工神经元(也称为单元或节点)在结构和功能上模仿生物神经元(从广义上讲,见下一个注释)。人工神经元接受几个输入值(与生物神经元中的树突同义),并为它们分配权重(类似于突触的作用)。在节点内部,对加权输入进行求和,并应用激活函数来获得结果。这种操作与生物神经元中细胞体和轴突小丘的作用相匹配。该节点的输出被传递到其他单元——这种操作模拟了电化学信息从一个神经元传递到另一个神经元或神经系统的其他部分的过程。
注意:在过去的几年里,科学家们开始反对直接描述人工神经网络与生物之间的关系。
“事实上,就功能和规模而言,人工神经网络与它们的生物对等物并不相似,然而,它们确实受到 BNNs(大脑神经网络)的启发,并且用于描述人工神经网络的几个术语是从神经科学文献中借来的。”——阿格达姆,H.H .和赫拉维,E.J. (2017)。卷积神经网络指南。
我希望这篇文章为神经网络系列的其他部分打下良好的基础。下面是系列文章的下一篇文章。继续读。让我们继续学习。
请以每月 5 美元的价格注册成为 medium 会员,这样就可以在 medium 上阅读我和其他作者的所有文章。
你也可以订阅,以便在我发表文章的时候把我的文章发到你的邮箱里。
感谢您的阅读!!!
物体检测的基础:YOLO,SSD,R-CNN
原文:https://towardsdatascience.com/the-basics-of-object-detection-yolo-ssd-r-cnn-6def60f51c0b
概述对象检测的工作原理,以及从哪里开始
亨利·迪克在 Unsplash 上的照片
注意:这里假设你对卷积神经网络有一个大致的了解。如果你需要复习,这篇 IBM 帖子非常好。
你知道卷积神经网络(或 CNN)如何检测和分类图像。但是你可以扩展 CNN 来探测图像中的物体。
物体检测和图像识别有什么不同?
你有 4 头牛的图像。图像识别将图像作为一个整体来检测。上面说图像被归类为奶牛。
但是,图像识别无法分辨出牛在图像中的位置。此外,它将无法分辨出有 4 头牛而不是 1 头。
另一方面,物体检测并不意味着计数。还有其他计算机视觉技术,如密度估计和提取用于计数的斑块。对象检测只是检测同一幅图像中是否有多个对象。
为什么我需要学习这个?这在现实世界中有什么用?
有很多骗子。有些人用假的银行本票或美钞混日子。图像检测只能说假复制品看起来是支票还是美钞。对象检测可以帮助搜索有助于确定支票或账单是否是伪造的单个组件。
如果你对医学着迷,那么物体检测可以识别 X 射线中的阴影或异常。即使它不能诊断疾病,物体检测也可以协助医生发现肺部组织的异常。医生可以在肺癌变得恶性之前发现它。
如果你对无人机和自动驾驶汽车着迷,那么对象检测对于检测视频流中的障碍和边界非常有用。它使汽车保持在车道内,避免事故。
听起来棒极了!但是物体检测是如何工作的呢?
图像已经包含了如此多的信息。CNN 旨在减少图像数据并保留重要信息。这可以通过不同的卷积层、池层和密集层来实现。
在这些层的末端,图像被缩小到足以进行预测。对于图像识别,这是一个类似 Softmax 的激活函数,用于对图像进行分类。对于对象检测,它有一种算法来预测检测到的对象周围的边界框,然后对对象进行分类。
有哪些算法?
有许多对象检测算法,但我们将涵盖三个主要的。
- YOLO——你只能看一次
- SSD —单次检测器
- r-CNN——基于区域的卷积神经网络
YOLO 是最简单的对象检测架构。在对象通过 CNN 后,它通过基于网格的方法预测边界框。它将每个图像分成一个 SxS 网格,每个网格预测包含任何对象的 N 个盒子。从这些 SxSxN 盒子中,它为每个类分类每个盒子,并挑选最高的类概率。
SSD 类似于 YOLO,但是使用每个卷积层的特征图(每个滤波器/层的输出)来预测边界框。在整合所有的特征图之后,它对它们运行 3×3 卷积核来预测包围盒和分类概率。SSD 是一个算法家族,流行的选择是 RetinaNet。
R-CNN 采用不同的方法,对构成识别的边界框/区域中的对象的像素进行分类。它使用一个神经网络来建议要检测的对象的潜在位置(基于区域的网络)。它使用第二个神经网络来基于这些建议的区域分类和检测对象。第二个神经网络添加了一个像素掩码,为需要分类的对象提供形状。
注意,一些研究者对这些算法有不同的语义。一些人认为 YOLO 是 SSD 家族的一部分,因为它们都只处理一次图像。一些人将 YOLO 从固态硬盘家族中分离出来。有人说像 R-CNN 这样的基于区域的网络是与对象检测方法相对的实例分割方法。
我应该使用哪一个?
这在很大程度上取决于您的数据、目标和计算使用情况。
YOLO 速度极快,使用的处理内存很少。虽然 YOLOv1 不如 SSD 准确,但 YOLOv3 和 YOLOv5 在准确性和速度上都超过了 SSD。此外,YOLO 只能预测每个网格 1 个类别。如果网格中有多个对象,YOLO 失败。最后,YOLO 努力探测小物体。
SSD 可以处理各种规模的对象。它利用来自所有卷积层的特征图,并且每一层在不同的尺度上操作。它的计算量也不大。然而,固态硬盘也很难检测到小物体。此外,如果 SSD 包含更多的卷积层,它会变得更慢。
R-CNN 是最准确的。然而,它在计算上是昂贵的。它需要大量的存储和处理能力来进行检测。它也比 YOLO 和固态硬盘慢。
两者都有利弊。如果准确性不是一个大问题,YOLO 是最好的选择。如果你的图像是黑白的,或者在清晰的背景上有容易识别的物体,YOLO 会在这些场景上非常准确。如果您有复杂的图像,并关心准确性(如从 X 射线检测癌症),那么 R-CNN 将是最适合的。
我必须从头开始重写这些算法吗?
不。这些都是开源和预先训练。它们都可以在 OpenCV 上获得。OpenCV 文档和样本适用于 YOLO、SSD 和 Mask R-CNN 。
等等,如果这些模型是预先训练的,那么我如何将它们用于特定于我的用例的新数据?
您需要创建两个数据集
- 自定义训练数据集,包括图像和每个图像中对象的标签/注释
- 用于模型预测的自定义测试数据集,以及用于验证模型预测准确性的标签/注释
强烈建议您创建自定义验证数据集。
这听起来工作量很大!我该如何着手做这件事?
您可以使用工具来添加注释。完成后,您可以将数据集导出为模型的任何格式。
我最喜欢的工具是 Label Studio。您可以为计算机视觉的图像对象、自然语言处理的文本、转录的音频等添加注释。我只用它来注释对象,它非常棒。
您可以以各种格式输出数据集。CSV,JSON,XML,Pascal VOC XML 等。甚至还有专门针对 YOLO 的格式。
你可以阅读更多关于如何开始使用 Label Studio 的内容。设置起来超级简单。您通过命令pip install -U label-studio
下载 label-studio,然后通过label-studio
启动它。用户界面非常直观,可以随时随地解决问题。
https://labelstud.io/guide/index.html#Quick-start
太棒了。但是我如何可视化这些对象的注释呢?
用 python 包matplotlib
!
如果你需要帮助来解决这个问题,其他一些来自数据科学家的贡献者写了他们自己的注释图像的方法。见下文。
现在,您拥有了在自己的自定义数据集上训练现有对象检测模型所需的工具。
感谢阅读!如果你想阅读更多我的作品,请查看我的目录。
如果你不是一个中等收入的会员,但对订阅《走向数据科学》感兴趣,只是为了阅读类似的教程和文章,单击此处注册成为会员。注册这个链接意味着我可以通过向你推荐 Medium 来获得报酬。
参考
计算机视觉的实用机器学习— O'Reilly Media (特别是第四章:目标检测和图像分割)
R-CNN,快速 R-CNN,更快 R-CNN,YOLO——目标检测算法
[用 YOLO5 进行自定义物体检测训练](http://Custom Object Detection Training using YOLOv5 In this blog post, we are fine tuning YOLOv5 models for custom object detection training and inference. Introduction…learnopencv.com)
乔洛普勒斯之战——第一部分
原文:https://towardsdatascience.com/the-battle-of-choropleths-part-1-e6102e62eea
PYTHON。数据科学。地理可视化
使用 Geopandas 创造惊人的 Choropleths
图片由作者提供:带有发散色图的 Choropleth
到目前为止,在我们的文章系列中,我们一直在讨论如何创建交互式 geoplots,我们已经讨论了七(7)个选项,涵盖了一系列工具,用户可以根据首选的易用性和可定制性来使用这些工具。
与 geoscatterplots 相比,choropleths 的选项较少,因此对于我们的文章系列,我们将包括甚至非交互式的选项。
对于这一部分,让我们用现有的最基本的方法来尝试一下:Geopandas。
CHOROPLETHS
首先,Choropleth(有时称为颜色主题)是一个主题地图,它使用色阶(颜色强度)来表示一个区域的值。我们使用区域这个术语是因为它通常对应于一个行政位置(城市、省和国家)。
因此,创建 choropleth 贴图需要存在shape file。
颜色越强烈(在色阶光谱的右边),代表一个区域的值越大。例如,对于像“绿色”这样的连续色标/色彩映射表,绿色的暗色调代表更大的值。
来自 Matplotlib。(同 organic)有机
那么,什么时候你更喜欢使用 choropleths 而不是 geoscatterplot?
当您的目标是比较地区间的合计值时,将使用 Choropleths。这可能是某些值或统计数据的平均值、中值、最小值或最大值。另一方面,geoscatterplot 表示单个观测值的离散度,而不是集合。****
如果使用了图例,它可以用来比较单个观察值(就像我们在咖啡店的例子)。
让我们试着做一个各国人均 GDP 的分布图,使用分布图的好处是,我们可以立即看到人均 GDP 较高的国家是否表现出地理位置的接近性。
现在让我们继续编码。
预赛
数据的加载和预处理
对于我们的数据集,我们将使用来自世界银行数据库 k 的人均 GDP 数据集(2015 年定值美元)。
包装
要安装和使用的最重要的包是 geopandas。根据我的经验,在 Macbook 上安装这个很容易,但在 Windows 上有点困难。在这种情况下,我准备了一篇文章也许能帮到你。
出于我们的目的,我们同样需要安装pyproj
和mapclassify
。
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.colors as colorsimport geopandas as gpd%matplotlib inline
正在加载 SHAPEFILES
对于这个系列中几乎所有的 choropleth,我们将需要我们要制作 choropleth 的区域的 shapefiles。Shapefiles 提供了一个位置的行政边界,可以详细到一个省、城市或一些定制的区域。
由于我们需要绘制的信息是针对国家的,因此我们将使用带有国家级几何图形的世界形状文件。
Shapefiles 可以从 GADM 下载。
编码
### LOAD GDP PER CAPITA DATA
df = pd.read_csv('data/gdp_per_capita.csv',
skiprows=4)
df = df.loc[:,['Country Name','Country Code', '2020']] #Choose only 2020
df.head()
图片由作者提供:数据集的前五个系列
### LOAD THE SHAPEFILES
gdf = gpd.read_file('shapefiles/world-administrative-boundaries/world-administrative-boundaries.shp')
gdf.head()
作者图片:世界的形状文件。额外收获:你可以通过调用一个位置的几何数据来查看它的几何形状
### MERGE DATA
merged = gdf.merge(df, left_on='name', right_on='Country Name' )
merged.head()
图片由作者提供:Shapefiles 和人均 GDP 的合并数据框架
重要提示:并非所有国家/地区的名称都与 shapefiles 的名称相同,因此同步这些名称非常重要
### PLOTcmap = 'Greens'#Create A Figure to Attach Other Objects Later
fig, ax = plt.subplots(figsize = (30,25))merged.plot(column="2020",
ax=ax,
cmap=cmap,
# k=colors,
scheme='quantiles',
legend=True)ax.axis('off')
关于我们的准则的一些事情:
- cmap —色彩映射表。
- fig,ax——如果我们希望创建一个颜色条(是我们用于颜色图的图例),这一部分很重要
- scheme —上面的 scheme 参数要求我们安装
mapclassify
。这有助于我们更好地分配颜色地图,而不是手动决定地图将使用的颜色数量。在大多数情况下,这是有帮助的,因为太多的颜色可能难以处理。 ax.axis(‘off’)
-这是用于移除与地理编码相对应的 x 轴和 y 轴的代码。
作者图片
用户化
为了进一步改善我们的地图,我们可以:
- 添加颜色条
- 选择不同的配色方案
- 为人均收入超过 100,000 美元的人添加文字
彩条
颜色条是帮助确定与颜色或颜色阴影相关的可能值范围的图例。
# create the colorbar
norm = colors.Normalize(vmin=merged['2020'].min(), vmax=merged['2020'].max())
cbar = plt.cm.ScalarMappable(norm=norm, cmap='Greens')
请注意,上面的代码实现了来自2020
的 colorbar,这是我们用来给地图添加颜色的列。
cax = fig.add_axes([1, 0.1, 0.03, 0.8])
cbr = fig.colorbar(cbar, cax=cax,)#Remove the legend
ax.get_legend().remove()#Change the tick for the colorbar
cax.tick_params(labelsize=18)fig
图片由作者提供:添加了颜色条
发散的彩色地图
为了真正显示对比,发散色图是首选。在这种情况下,让我们试试RdYlGn
:
#Try a diverging colormap
cmap = 'RdYlGn'#Create A Figure to Attach Other Objects Later
fig, ax = plt.subplots(figsize = (30,25))merged.plot(column="2020",
ax=ax,
cmap=cmap,
# k=colors,
scheme='quantiles',
legend=True)# ax.legend(loc="best")ax.axis('off')# create the colorbar
norm = colors.Normalize(vmin=merged['2020'].min(), vmax=merged['2020'].max())
cbar = plt.cm.ScalarMappable(norm=norm, cmap=cmap)cax = fig.add_axes([1, 0.1, 0.03, 0.8])
cbr = fig.colorbar(cbar, cax=cax,)#Remove the legend
ax.get_legend().remove()#Change the tick for the colorbar
cax.tick_params(labelsize=18)fig
作者图片:发散色图
在上述人均 10 万美元的基础上增加文字
与其他定制相比,这种定制不容易美化,但是为了那些想要它的人,让我们继续将它放在这里。
要添加文本,我们需要将它放在几何图形的中心(或质心)。这样做的问题是一些几何图形比其他的小,因此不容易调整文本的大小。
for ind, row in merged.iterrows():
if merged.loc[ind,'2020']>100000:
ax.text(row["geometry"].centroid.x,row["geometry"].centroid.y+4, row["name"], fontsize=12, color='blue',weight="bold")
ax.text(row["geometry"].centroid.x,row["geometry"].centroid.y, row["2020"],
fontsize=12, color='blue', weight='bold')fig
作者提供的图片:带有蓝色文本的地图,显示人均 GDP 超过 10 万美元的国家
结束语
正如我们所看到的,choropleth 确实回答了我们最初的问题:人均 GDP 水平确实聚集在一起,我们看到富裕国家彼此接近,而贫穷国家也是如此(就人均 GDP 而言)。
好消息是,对于我们将测试的后续包,将使用我们这里已经有的基本代码,因为它们中的大多数需要 shapefiles(或 geopandas dataframe)。
我的 Github 页面上的全部代码。
其他相关文章
交互式地理可视化之战第一部分——使用一条线的交互式 geo plot……
交互式地理可视化之战第二部分——使用一条线的交互式 geo plot…
交互式地理可视化之战第三部分——Plotly 图形对象(Go)
交互式地理可视化之战第四部分——牛郎星
交互式地理可视化之战第五部分——叶子
交互式地理可视化之战第六集— Greppo
交互式地理可视化之战第七集——散景
乔洛普勒斯之战——第二部分——牛郎星
原文:https://towardsdatascience.com/the-battle-of-choropleths-part-2-altair-accaa4b46fb4
PYTHON。数据科学。地理可视化
使用牛郎星创造惊人的合唱团
图片由作者提供:初始 Choropleth
牵牛星
我们在本文中首次使用了 Altair 包:交互式地理可视化之战第 4 部分— Altair 。
对于那些开始阅读本文的人来说,Altair 被比作 Plotly,因为它是一种高级声明性语言。这意味着 Altair 将更容易使用,但在某些部分更难控制。
Altair 也有我们称之为“交互语法”的东西,可以很容易地在部件和情节之间,以及情节本身之间创建交互。稍后,我们将为 shapefile 和数据本身创建不同的绘图,并将它们组合在一起,我们将会看到这一点。
在 Geopandas 上使用 Altair 的一个快速好处是,您可以将鼠标悬停在几何图形上,并使用它来识别数据。
不再赘述,让我们开始编码吧。
编码
由于数据和 shapefile 是相同的,代码和输出将类似于第一部分中的内容。
预赛
import pandas as pd
import numpy as npimport geopandas as gpdimport altair as alt
加载人均 GDP 数据
df = pd.read_csv('data/gdp_per_capita.csv',
skiprows=4)
df = df.loc[:,['Country Name','Country Code', '2020']] #Choose only 2020
df.head()
作者图片:数据集的前五次观察
加载形状文件
gdf = gpd.read_file('shapefiles/world-administrative-boundaries/world-administrative-boundaries.shp')
gdf.head()
作者图片:Shapefile 的前五个数据
合并数据
merged = gdf.merge(df, left_on='name', right_on='Country Name' )
merged.fillna(0, inplace=True)
merged.head()
按作者分类的图像:合并数据集的前五个数据
注意,在这部分代码中,合并的数据被归类为Geopandas GeoDataFrame
是很重要的。
测绘
在可视化的这一部分,我们可以分别绘制 shapefile 和数据,然后将它们组合起来。
绘制形状文件
world = alt.Chart(merged).mark_geoshape(stroke='white',
fill='lightgray').properties(width=800,
height=400)
作者图片:Shapefile 可视化
让我们分解以下代码:
alt.Chart
—初始化牛郎星图表。.mark_geoshape
—决定了我们想要的图表类型,在我们的例子中是一个地理形状。这同样包括特定于图表的参数,在我们的例子中还包括地图的笔画和填充属性。.properties —
这用于控制地图的整体布局,而不是特定的(图表特定参数)
绘制 CHOROPLETH
choro = alt.Chart(merged).mark_geoshape().encode(alt.Color('2020',
type='quantitative',
scale=alt.Scale(scheme='redyellowgreen'),
title = "GDP per Capita (constant 2015 USD)"),
tooltip=['name', '2020:Q'])
GIF 作者:初始 Choropleth
上面代码的一点上下文:
.encode
—将数据的特征编码到图形的不同视觉特征中。这更容易理解,我认为这是将数据转化为可视化表示的代码。alt.Color
—对 Choropleths 很重要的颜色模式包装。tooltip
—对于工具提示,重要的是包括以下格式的数据类型column_name:data_type
;这里 Q 代表定量。— (例如用于2020:Q
)
这里有一些注意事项:与我们的第一篇 geopandas 文章相比,我们可以清楚地看到大多数国家更接近红色,因为某些国家是异常值。在地图上很难看到它们,因为从几何角度来看它们也很小。
数据可视化专家应该额外注意这个重要的方面:通过分位数来表示它们,我们能够消除离群值,从而消除不平等。在某些情况下,这是可取的,但并不总是如此。
让我们通过自定义我们的地图来尝试实现我们在第一系列中拥有的相同的地图。
用户化
choro = alt.Chart(merged).mark_geoshape().encode(alt.Color('2020',
type='quantitative',
scale=alt.Scale(scheme='redyellowgreen', type='quantile'),
title = "GDP per Capita (constant 2015 USD)"),
tooltip=['name', '2020:Q'])
要继承我们在world
shapefile 中添加的定制:
world + choro
作者 GIF:从该系列的第一篇文章中重新创建 Choropleth
如你所见,我们的地图上有一个自动色带。这对 Altair 来说是一个巨大的利好。
此外,它很容易结合两个对象,我们已经设计。我们简单地用符号
+
将它们组合起来。
结束语
可以说,Altair 创建类似 choropleth 的语法比 Geopandas 简单得多。
这种便利不是没有代价的。截至本文撰写之时,Altair 软件包,至少对于地图来说,还不具备放大和缩小以及平移和缩放的功能。它目前正在开发中,但现在,这可能是可视化的一个很大的缺点,比如这个国家的面积可能比其他国家小。
我的 Github 页面上的全部代码。
其他相关文章
Choropleths 之战——第一部分
交互式地理可视化之战第一部分——使用一行……的交互式地理地图
交互式地理可视化之战第二部分——使用一行……的交互式 geo plot
交互式地理可视化之战第三部分——Plotly 图形对象(Go)
交互式地理可视化之战第四部——牛郎星
交互式地理可视化之战第五集——叶子
交互式地理可视化之战第六集——格雷波
交互式地理可视化之战第七部分——散景
Choropleths 之战——第三部分——叶子
原文:https://towardsdatascience.com/the-battle-of-choropleths-part-3-folium-86ab1232afc
PYTHON。数据科学。地理可视化
使用叶包创造惊人的 Choropleths
在本系列的前两篇文章中,我们能够从 Geopandas 和 Altair 包中创建 choropleths。让我们继续学习,但这一次让我们使用叶包。
图片由作者提供:通过叶创建的 Choropleth
树叶包装
在这篇文章中,我们介绍了 leav 包以及该包的优缺点。
正如我们将在后面看到的,leav 引入了许多定制工具,这些工具将帮助我们创建更具交互性和专业外观的地图。当然,这带来了额外几行代码的额外成本。
不多说了,我们开始吧。
编码
编码部分类似于前两篇文章,但是在这篇文章中,我们不需要合并数据集(,除非我们想要创建一个自定义的颜色图,我们将在后面看到。)
预赛
import pandas as pd
import numpy as npimport geopandas as gpd
import folium
加载和预处理数据
df = pd.read_csv('data/gdp_per_capita.csv',
skiprows=4)
df = df.loc[:,['Country Name','Country Code', '2020']] #Choose only 2020df = df.fillna(0) #New step df.head()
图片由作者提供:数据集的前五次观察
加载形状文件
gdf = gpd.read_file('shapefiles/world-administrative-boundaries/world-administrative-boundaries.shp')gdf.head()
作者图片:形状文件的前五个观察
测绘
启动地图
#Folium
mymap = folium.Map(location=[19.0649070739746, 73.1308670043945], zoom_start=2,tiles=None)#ADDING TILES AS A SEPARATE LAYER ALLOWS FOR MORE CONTROL AND MORE SUTOMIZATION
folium.TileLayer('CartoDB positron',name="Light Map",control=False).add_to(mymap)#Calling the map
mymap
作者提供的图片:将包含其他图层的空白地图
创建要作为层添加的 CHOROPLETH
choropleth = folium.Choropleth(
geo_data=gdf, #the dataset merged with the geometry and the data we need to plot on,
data=df,
key_on='feature.properties.name',
columns=['Country Name', '2020'], #the first one is the 'index' which needs to be connected with the 'key_on' property of the geo_data
name = 'GDP per capita (Constant USD 2015 )',
fill_color='YlGn',
fill_opacity=0.7,
line_opacity=0.5,
).add_to(mymap)
mymap
让我们讨论一下代码的参数:
geo_data
—形状文件数据集data
—包含 choropleth 颜色的基础值。key_on
—这是指在 shapefile(或geo_data
参数)中找到的列,该列将用于将值与data
参数中的值合并。我们跳过数据合并部分的原因是这样的:follow 将使用该参数进行合并。.add_to
—将 choropleth 图层添加到我们初始化的地图中。
图片由作者提供:初始 Choropleth 地图
一个潜在的弱点是它的调色板有限。我们现在使用黄绿色,但有一种方法可以在以后定制它。
自定义
让我们通过做两件事来定制我们的 choropleth:
- 添加互动工具提示
- 创建自定义的色彩映射表—红-黄-绿。
添加工具提示
要添加定制的工具提示,我们需要调用 leav 的GeoJsonTooltip
类。这为我们提供了一种交互和查看数据的方式,这非常方便,尤其是在我们做一些报告的时候。
# Display Region Label
choropleth.geojson.add_child(
folium.features.GeoJsonTooltip(['name'], labels=True)
)
mymap
作者 GIF:添加工具提示
创建自定义色彩映射表
要尝试复制第一个系列的配色方案,有必要创建一个自定义颜色映射。如前所述,follous 中可用的调色板是有限的,要创建一个定制的调色板,我们需要添加更多行代码。
在我们最初的文章中,我们使用了“红-黄-绿”的颜色图。要在这里使用这个,我们需要做几件事情:
1 .使用branca
库创建自定义色彩映射表。可用的色彩映射表是有限的,如果我们想创建一个定制的,我们需要使用branca
库。
2。将数据与地理数据框架合并。这现在变得很有必要,因为为了添加一个颜色依赖于值的层,几何数据应该存在。
3。用自定义的色彩映射表添加一个单独的层。
import branca
import branca.colormap as cm#First determine your maximum and minimum values - this becomes the basis for the steps in the map
vmax = df['2020'].max()
vmin = df['2020'].min()colormap = cm.LinearColormap(colors=['red', 'yellow','green'],
vmin=vmin,
vmax=vmax)
合并数据
merged = gdf.merge(df, left_on='name', right_on='Country Name' )
merged.head()
作者提供的图片:合并数据集中的前五个观察值
作为单独的层添加
# First create a function that would call on these values
style_function = lambda x: {"weight":0.5,
'color':'black',
'fillColor':colormap(x['properties']['2020']),
'fillOpacity':0.75}#Add the colormap as a legend
colormap.add_to(mymap)#Save it as an object so you can add it
folium.features.GeoJson(
merged.fillna(0),
style_function=style_function,
).add_to(mymap)mymap
GIF 作者:红黄绿配色
这个现在类似于我们创建的原始牛郎星地图。万岁!
为了使颜色更均匀,这就是忽略离群值,正如我们使用分位数方法所做的那样,我们需要添加更多的代码。
分位数方法——复制以前文章中的图
为了完全复制我们在前两篇文章中创建的地图,我们需要确保这些值被分成几个步骤(忽略异常值,在文章的最后一部分发布了警告)。
但是,请注意,随着您不断向地图添加图层,地图会变得混乱,因此创建一个新的图层可能会更清晰。但是,如果您计划创建一个自定义的颜色映射,不保持 choropleth 部分的干净可能更简单,如下所示:
# My Map
#Folium
mymap = folium.Map(location=[19.0649070739746, 73.1308670043945], zoom_start=2,tiles=None)#ADDING TILES AS A SEPARATE LAYER ALLOWS FOR MORE CONTROL AND MORE SUTOMIZATION
folium.TileLayer('CartoDB positron',name="Light Map",control=False).add_to(mymap)choropleth = folium.Choropleth(
geo_data=gdf,name = 'GDP per capita (Constant USD 2015 )',
).add_to(mymap)
mymap
图片由作者提供:已清理的初始化地图
下面的代码显示了我们建议的步骤:
- 我们利用索引(手动指定颜色的切割点。这首先要求我们知道数列的最大值和最小值。
- 我们对色彩映射表进行了线性化,以便值可以落入索引中的箱中。
- 如你所见,我们重复了两次十六进制代码
#c7f6b6
。这不是偶然的。叶似乎很难剪切列表中的最后一种颜色,因此添加更多的颜色可以确保在最后一种颜色绿色之前有更线性的过渡。当然,颜色应该是上一个颜色渐变,这样十六进制代码就是浅绿色的。 - 我们手动剪切索引,在原始索引中,只使用了五次剪切。然而,对于这个地图,7 似乎更好一些(回想一下,在对数字范围进行索引时,Python 中的最后一个值无论如何都会被忽略)。
#First determine your maximum and minimum values - this becomes the basis for the steps in the map
vmax = df['2020'].max()
vmin = df['2020'].min()colormap = cm.LinearColormap(colors=['red','yellow' , '#c7f6b6' ,'#c7f6b6','green'],
vmin=vmin,
vmax=vmax)# We add this in extra step to emulate the coloring scheme of the prveious articles
n_steps = 7 # Quantiles
list_of_values = df['2020'].sort_values()#Remove all 0's as the geopandas version did not count 0 on the count of merging
list_of_values = [i for i in list_of_values if i != 0]length = len(list_of_values)index = [list_of_values[int((length/n_steps)*i)] for i in range(n_steps)]print(index)colormap = colormap.to_step(index=index)
最后润色:
请注意,在这一层中,工具提示需要作为最后一层的一部分添加,以便使用,所以我们将它合并到我们使用的最后一层。
# First create a function that would call on these values
style_function = lambda x: {"weight":0.5,
'color':'black',
'fillColor':colormap(x['properties']['2020']),
'fillOpacity':0.75}#Add the colormap as a legend
colormap.add_to(mymap)#Save it as an object so you can add it
folium.features.GeoJson(
merged,
style_function=style_function,
tooltip=folium.features.GeoJsonTooltip(['name'], labels=True)
).add_to(mymap)mymap
作者 GIF:最后的润色
瞧啊。我们能够精确地复制前两篇文章中的地图,尽管并不容易。
结束语
正如我们所看到的,使用 leav,定制的能力是以便利性为代价的。为了在前两篇文章中重新创建整个地图,我们需要添加更多的代码。
对于一些打算部署地图的人来说,这个成本可能是值得的,因为 follow 输出可以保存为 HTML。最重要的是,其他功能,如添加定制工具提示的能力,在特定区域周围创建视觉半径,以及更多其他功能,使 leav 成为 choropleths 的一个很好的包。
我的 Github 页面上的全部代码。
其他相关文章
乔洛普勒斯之战——第一部
乔洛普勒斯之战——第二部——牛郎星
交互式地理可视化之战第一部分——使用一行……的交互式地理地图
交互式地理可视化之战第二部分——使用一行……的交互式 geo plot
交互式地理可视化之战第三部分——Plotly 图形对象(Go)
交互式地理可视化之战第四部——牛郎星
交互式地理可视化之战第五部分——叶子
交互式地理可视化之战第六部分—格雷波
交互式地理可视化之战第七集——散景
交互式地理可视化之战第四部分——牛郎星
PYTHON。数据科学。地理可视化。
使用 Altair 软件包创建漂亮的交互式地理绘图
我们离开的地方
在这个系列中,我们已经确定了三(3)种制作美丽的地理散射图的方法。
- 全息视图 — 交互式地理可视化之战第一部分——使用一行代码的交互式地理地图
- Plotly Express — 交互式地理可视化之战第二部分——使用一行代码的交互式 geo plot
- Plotly Go — 交互式地理可视化之战第三部分——Plotly 图形对象(Go)
在本文中,我们将学习如何使用数据科学社区中 plotly 包最著名的竞争对手之一 Altair 来创建类似的图。
牵牛星作为一个包
Altair 被比作 Plotly Express,因为它是一种高级声明性语言,很像 seaborn、holoviews 和 ggplot。这意味着我们用控制来换取易用性。
与其他图表不同,Altair 专注于拥有一种图形语法,在这种语法中,从单个图形创建组合图表更容易,类似于如何将单词组合成人类句子。这使得 Altair 的语法更加接近 ggplot,对于 R 用户来说是一个优势。
Altair 也有我们称之为“交互语法”的东西,可以很容易地在部件和情节之间,以及情节本身之间创建交互。例如,在我们下面的图中,与图表左侧的交互将模拟我们与右侧的交互,只要它们属于同一个图表。
最后,当谈到外观时,Altair 会在您调整情节大小时保留情节的元素。这在我们不断添加更多类别时非常有用,这与其他可视化库不同,后者维护的是整体绘图属性(图形大小),从而扭曲了绘图元素。
编码
预赛
和其他人一样,让我们装载我们的包:
import pandas as pd
import altair as altimport geopandas as gpd
from shapely.geometry import Pointalt.renderers.enable('default') #Allows the map to be displayed in the notebook/Jupyterlab
加载数据集
加载以下数据集:
df = pd.read_csv('data/Coffee Brands Footprint.csv',
index_col=0)
df.head()
作者图片:我们数据集的前五次观察。
使用 Altair 的一点警告: Altair 使用数据转换器,要求所有列都是“JSON 可序列化的”。这意味着您的列中不应该有几何数据类型。
现在,与 Plotly 不同,我们需要导入自己的 shapefiles 来提供地图的边界。https://gadm.org/提供了几乎所有你需要的 shapefiles。
加载形状文件
#Load the geodataframe
gdf = gpd.read_file('Shapefiles/gadm36_PHL_shp/gadm36_PHL_1.shp')#Options When It Comes to Boundaries of the Shapefilephilippines = alt.Chart(gdf).mark_geoshape(stroke='white',
fill='lightgray').encode().properties(width=400,
height=800).project('mercator')philippines
图片由作者提供:在 Jupyterlab 展示的菲律宾 Shapefile
让我们回顾一下上面的一些选项:
- 表示“另类的”图表—这段代码从提供的数据集创建 Altair 图表。在这种情况下,我们提供了地理数据框架。
- mark _ geo shape——该命令让 Altair 知道数据帧的属性应该如何准确地在绘图中表示;在我们的例子中,它是一个 geo_shape。
- 描边-这是指线颜色或地理数据框的边界。政治边界越详细,这个参数就越重要。
- 填充-地图的颜色填充。
- 编码—这是将列映射到映射的可视属性的代码部分。
- 属性——我们用它来改变图(或图形)本身的宽度、高度或任何其他属性。
- 投影-投影类型。在我们的情况下是可选的,但对大多数美国地图有帮助。
绘制地理散射图
下面的代码将创建一个类似的散点图,就像我们前三(3)篇文章一样:
points = alt.Chart(df).mark_circle(opacity=0.7).encode(
longitude='lng:Q',
latitude='lat:Q',
size=alt.value(10),
color='brand',
tooltip=['brand', 'vicinity'])points
GIF by Author:生成的散点不受 shapefile 的限制。
这些参数与我们用于 geoshape 的参数非常相似,但是请注意,对于 geoscatterplots,我们需要为longitude
和latitude
填充参数或自变量。
注意,提供该参数的格式是“ column_name:Q ”。因为我们的经度列被命名为‘LNG’,所以提供给经度列的值是lng:Q
。代码工作所需的:Q
是。还要注意,对于尺寸参数,我们也使用了alt.value
。
结合这两个图
最后,Altair 地图的一个非常酷的特性,尤其是地理可视化,就是你可以简单地添加我们之前创建的两个地图。
points | philippines + points
作者 GIF:只需使用“+”号就可以将两个图形相加。
结束语
Altair 被认为是一个高级声明库,所以它的易用性必须与 plotly express 相提并论。因为它能够读取我们导入的 shapefile,所以它有能力变得更加优雅,尤其是对于较低级别的边界。
虽然 Altair 对于 geoscatterplot 来说同样很棒,但是对于 choropleth 来说同样很容易使用。请继续关注我们尝试使用不同的包来创建 choropleths。
感谢阅读,并让我知道你的想法!
请查看我的其他文章:
交互式地理可视化之战第一部分——使用一行代码的交互式地理地图
交互式地理可视化之战第二部分——使用一行代码的交互式地理地图
交互式地理可视化之战第三部分——Plotly 图形对象(Go)
使用 Google Places API 和 fluous 为您在菲律宾最喜欢的咖啡店绘制地图
参考文献
STACKOVERFLOW:牛郎星 vs Plotly Express
交互式地理可视化之战第五讲——叶子
PYTHON。数据科学。地理可视化。
使用 follow 包创建漂亮的交互式 Geoplots
我们离开的地方
在这个系列中,我们已经确定了制作美丽的地理散射图的四(4)种方法:
- 全息视图 — 交互式地理可视化之战第一部分——使用一行代码的交互式地理地图
- Plotly Express — 交互式地理可视化之战第二部分——使用一行代码的交互式 geo plot
- Plotly Go — 交互式地理可视化之战第三部分——Plotly 图形对象(Go)
- 牛郎星——交互式地理可视化之战第四集——牛郎星
在本文中,我们将学习如何使用我最喜欢的地理可视化软件包,follow,创建一个类似的但更加定制的绘图。
我还将向您展示如何使用为我们的 geoviz 提供即时升级的“标记集群”功能。
叶子与情节
Folium 可能是 Python 用户使用最广泛的地理可视化工具之一,这些用户打算为个人甚至商业用途创建更多定制地图。
它是建立在 needs 之上的,比我们到目前为止介绍过的任何一个包都能覆盖更多的制图需求。
另一方面,Plotly 的优势是在语法和扩展使用上更容易,特别是它的高级绘图库 Plotly Express。你也可以用这个包做很多事情,但是没有用 leav 做的多。
编码
确保首先安装叶子:
pip install folium
预赛
和其他人一样,让我们装载我们的包:
import numpy as np
import pandas as pdimport folium
from folium.plugins import MarkerCluster
import geopandas as gpdfrom shapely import geometry
from shapely.geometry import Point
from shapely.geometry.polygon import Polygon
加载数据集
df = pd.read_csv('data/Coffee Brands Footprint.csv',
index_col=0)
df.head()
作者图片:我们数据集的前五次观察。
加载数据集后,我们可以开始创建我们的叶子地图!
叶子代码
启动地图
以下代码启动了叶子图:
m = folium.Map(location=[14.577924, 121.073972],
tiles="cartodbpositron") #Latitude first before Longitude
图片作者:初始化的树叶地图
Folium.Map
有可以控制初始缩放的参数和控制地图的图块。我们选择了图块cartodbpositron
,因为它离我们其他包的底图更近。
启动标记集群
叶子的MarkerCluster
插件是我们 geoviz 的一个很好的补充,因为它可以为我们提供一些即时的见解。这是一种聚类形式,因此您可以立即评估哪些区域中有您的研究对象。
另一个明显的好处是,它有助于保持你的地图看起来干净,因为它不会有太多的标记杂乱。
要启动 MarkerCluster 对象:
marker_cluster = MarkerCluster(control=False).add_to(m)
我们将它存储在一个名为marker_cluster
的变量中,因为我们稍后将调用它,或者更确切地说,添加到它。
不要忘记将这个MarkerCluster
对象添加到我们名为m
的地图对象中。
启动标记
要为此启动标记,我们需要做一个初步的步骤来存储在一个元组中或列出我们的地理编码。
#We need this cause apparently, folium can recognize not a geoseries but a normal tuple/list
df.reset_index(drop=True, inplace=True)
df['geocode'] = [[df['lat'][i],df['lng'][i]] for i in range(len(df)) ]
现在,让我们创建带有定制工具提示的标记,显示咖啡店的品牌或名称。
for point in df.index: # loop through the plotshtml = """<h3>{name}</h3><br>"""popup_contents = folium.Html(html.format(name = df.loc[point, 'name']),
script = True)popup = folium.Popup(popup_contents, max_width=1500)# mark every addresses in the map from the data
folium.Marker(df['geocode'][point],
popup=popup).add_to(marker_cluster)
让我们分解上面的代码(步骤 1-3 用于弹出内容,步骤 4 用于标记):
- HTML 字符串将包含我们的工具提示,单击散点图中的点时将显示该工具提示。
- 因此,在我们的
folium.HTML
对象中会有这个空字符串。 - 因此,我们将它存储在一个可以进一步定制的
folium.Popup
对象中。 - 最后,要向这些商店添加 pin,
folium.Marker
为每个位置添加一个 pin,并确保这些商店是集群的,您需要将它添加到我们已经创建的marker_cluster
变量中。
GIF 作者:CircleMarker 在行动
为了简单地显示和聚集这些咖啡店,我们已经完成了!
然而,如果你想实现我们曾经使用的彩色标记,就像在过去的文章中一样,那么我们需要选择一个不同的标记——圆形标记。
添加彩色圆圈标记,以提高识别能力
您可以添加之前的标记,也可以选择添加圆形标记。下面是这样做的代码:
我们首先需要声明我们的品牌及其颜色:
#Let's Create a Color Dictionary for the Markers
coffee_brands = ["Coffee Bean and Tea Leaf", "Starbucks", "Tim Hortons", "Coffee Project"]color_dict = {
"Starbucks": ' #00704A',
"Coffee Bean and Tea Leaf": '#362d26',
"Coffee Project": '#654321',
"Tim Hortons": '#dd0f2d'
}
接下来,我们需要迭代每个品牌,并迭代添加彩色圆圈标记。请注意,这段代码用常规的folium.Marker
替换了我们现有的代码。
#Since we need to add a filter for this, we need to add them by brand:
for brand in coffee_brands:
df_i = df[df['brand']==brand]
df_i.loc[:, "color"] = color_dict[brand]
for index, row in df_i.iterrows():
####### START OF THE SAME CODE FOR POPUP #######
html = """<h3>{name}</h3><br>"""popup_contents = folium.Html(html.format(name = row['name']),
script = True)popup = folium.Popup(popup_contents, max_width=1500)
####### END OF THE SAME CODE FOR POPUP #######
folium.vector_layers.CircleMarker(radius = 8,
location = (row.lat,
row.lng),
color = row.color,
fill = True,
fill_color = row.color,
name = brand,
popup=popup,
control = True,
overlay = True
).add_to(marker_cluster)
让我们分解上面的代码:
- 您可能已经注意到,添加标记对于 leav 来说是一个迭代过程。根本没有办法批量添加它们,所以对于我们的目的来说,它们必须是循环的一部分。因此,第一步是对品牌进行分组或过滤,这样你就可以给一个品牌分配一种颜色。
- 在过滤一个品牌后,你就可以创造另一个增加市场的循环。请注意,弹出内容必须添加到每个标记中,因此它们也是循环的一部分,并且具有与上面相同的代码。
- 最后,就像在
folium.Marker
中一样,我们在folium.vector_layers.CircleMarker
中添加必要的参数,比如半径的大小、填充颜色和颜色,它们将遵循循环开始时分配的颜色。
作者 GIF。圆圈标记在起作用
结束语
如你所见,我们可以用叶子做的事情范围是惊人的。如果您为地图设计了特定的单幅图块,也可以自定义单幅图块。
一个非常有用的定制是添加工具提示。正如我们所看到的,HTML 代码可以包含更多的信息,这就是为什么它也是用于部署商业项目的包。
我建议数据科学家探索更多的功能,例如添加热图和自定义标记以包含图标。每个点周围的半径也可能有助于某些地理空间项目,这也可以通过令人惊讶的叶包来完成。
让我知道你的想法!
交互式地理可视化之战第六讲——格雷波
PYTHON。数据科学。地理可视化
使用 Greppo 库创建漂亮的交互式 Geoplots
我们离开的地方
在这个系列中,我们已经确定了五(5)种制作美丽地理散射图的方法。
- 全息视图 — 交互式地理可视化之战第一部分——使用一行代码的交互式地理地图
- Plotly Express — 交互式地理可视化之战第二部分——使用一行代码的交互式 geo plot
- Plotly Go — 交互式地理可视化之战第三部分——Plotly 图形对象(Go)
- 牛郎星——交互式地理可视化之战第四集——牛郎星
- 叶 — 交互式地理可视化之战第五部分—叶
在本文中,我们将学习如何创建,不仅仅是地理可视化,而是一个应用程序。对,一个 app!
因此,这篇文章可以与 Holoviews 的系列文章相提并论,其中易于部署是数据科学家的优势,他们希望在向利益相关者演示时避免展示我们的 Jupyter 笔记本。
我们的目标是创建与前五篇文章几乎相似的地图。
所以,不多说了,让我们开始吧:
五个简单的步骤
创建这个漂亮的地理空间应用程序有五个简单的步骤:
- 创建一个包含 Python 脚本和数据集的文件夹。
- 创建基础层
- 导入数据
- 将数据添加为矢量图层
- 输入其他详细信息
步骤 1:创建一个包含 Python 脚本和数据集的文件夹。
与大多数应用程序一样,将它们放在一个文件夹中是一个很好的做法。在我的例子中,它位于geospatial_app
文件夹中:
作者图片:通过 Bash 改变目录来访问我们的脚本和数据集的位置。
如您所见,将它保存在一个
.py
文件中很重要:一个 Python 脚本。因此,对于下面的步骤,请注意,这些将在 Python 脚本中编写。
步骤 2:创建基础层。
基础图层类似于我们用于 follow 应用程序的图块(回想一下,在创建基础地图时,我们指定 *tiles*
)。)
这方面代码如下:
app.base_layer(
name="Open Street Map",
visible=True,
url="[https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png](https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png)",
subdomains=None,
attribution='(C) OpenStreetMap contributors',
)app.base_layer(
name="CartoDB Light",
visible=True,
url="[@2x](https://cartodb-basemaps-a.global.ssl.fastly.net/light_all/{z}/{x}/{y}<a href=).png">https://cartodb-basemaps-a.global.ssl.fastly.net/light_all/{z}/{x}/{y}[@2x](http://twitter.com/2x).png",
subdomains=None,
attribution='© <a target="_blank" href="[http://osm.org/copyright](http://osm.org/copyright)">OpenStreetMap</a> contributors',
)
在上面的代码中,我们创建了两个可以交替使用的基础层。格式如下:Greppo 文档:基础层。
为了检查我们是否正确,转到代码所在的文件夹并运行下面的命令greppo serve app.py
。格式是greppo serve {script name}
。在我们的例子中,我们选择将脚本命名为app.py
,因此它将是greppo serve.
之后的内容
图片由作者提供:在文件夹中输入命令“greppo serve app.py”来运行应用程序
作者 GIF:创建基础层
步骤 3:导入我们的地理空间数据
与我们的其他产品一样,导入非常简单:
df = pd.read_csv('Coffee Brands Footprint.csv',
index_col=0)
现在,由于我们需要此特定包的地理数据框架,我们只需添加:
#Geometry
geometry = [Point(xy) for xy in zip(df.lng, df.lat)]
gdf = gpd.GeoDataFrame(df, geometry=geometry)
这也是我们为过去的文章所做的,所以在这一部分没有什么新的。继续前进。
步骤 4:将数据添加为矢量图层
既然我们想用不同的颜色识别不同的品牌,那么将不同的品牌视为它们的数据集就很重要。
这样做的原因是,造型是每层完成的,每层只能有一种颜色。因此,我们的解决方法是将每个品牌视为不同的层。
首先,创建一个颜色字典,就像我们用叶子做的那样:
#We need to add this iteratively, to achieve different colors in the map, we need to separate the brands and treat them as a dataframe#Borrowing this from our earlier codes
color_dict = {
"Starbucks": ' #00704A',
"Coffee Bean and Tea Leaf": '#362d26',
"Coffee Project": '#654321',
"Tim Hortons": '#dd0f2d'
}
最后,反复添加品牌:
for brand in color_dict.keys():
app.vector_layer(
data = gdf[gdf.brand==brand],
name = f"{brand} Coffee Shops in the Philippines",
description = f"Scatter plot of {brand} Coffee Shops in the Philippines",
style = {"fillColor": color_dict[brand],
"fillOpacity":0.5,
"opacity":0.5},
)
瞧啊。
作者 GIF。添加了图层的地理空间应用程序
最后,让我们命名我们的应用程序并输入更多详细信息:
步骤 5:输入其他详细信息
app.display(name='title', value='The Battle of Interactive Geographic Visualization Part 6 — Greppo')
app.display(name='description',
value='A Greppo demo app for vector data using GeoPandas DataFrame')
作者 GIF。添加了图层和标题的最终地理空间应用程序
结束语
正如我们所见,使用 Greppo 部署和创建地理空间可视化应用程序非常简单。
与 Holoviews 不同,应用程序元素的排列似乎已经固定,定制也不像我们在 leav 中那样广泛。
尽管如此,这个库为我们提供了工具箱中的另一个工具,我们可以使用它来探索,因为前端足够令人愉快和漂亮,可以给我们的利益相关者留下深刻印象。
让我知道你的想法!
交互式地理可视化之战第七部分——散景
PYTHON。数据科学。地理可视化
使用散景库创建漂亮的交互式 Geoplots
德尔菲·德拉鲁阿在 Unsplash 上拍摄的照片
我们离开的地方
在这个系列中,我们已经确定了六(6)种制作美丽地理散射图的方法。
- 全息视图 — 交互式地理可视化之战第一部分——使用一行代码的交互式地理地图
- Plotly Express — 交互式地理可视化之战第二部分——使用一行代码的交互式 geo plot
- Plotly Go — 交互式地理可视化之战第三部分——Plotly 图形对象(Go)
- 牛郎星——交互式地理可视化之战第四集——牛郎星
- 叶 — 交互式地理可视化之战第五部分—叶
- Greppo — 交互式地理可视化之战第六部分— Greppo
在这篇文章中,我们将学习如何用散景来做到这一点。现在,散景是内置在面板上的,这是我们在本系列的第一篇文章中使用的。
PLOTLY VS. BOKEH
一篇关于此的文章总结了这两个库的主要区别。当我们谈论易用性时,Plotly 更好,并且推而广之,在制作单独的(包括 3D)地图时更容易使用。
散景的亮点在于它的仪表板功能。这意味着更容易创建、托管和样式化仪表板。
不再赘述,让我们开始编码吧。
编码
预赛
我们将使用以下软件包重新创建我们与其他文章的互动地图:
import pandas as pd#Transformation of Geocodes
from pyproj import Proj, transformfrom bokeh.plotting import figure, save, show
from bokeh.io import output_notebook#For the Map Tiles
from bokeh.tile_providers import get_provider, WIKIMEDIA, CARTODBPOSITRON, STAMEN_TERRAIN, STAMEN_TONER, ESRI_IMAGERY, OSM
tile_provider = get_provider(xyz.OpenStreetMap.Mapnik)#To display properly the maps
import panel as pn
pn.extension()
import warnings
warnings.filterwarnings("ignore")
这里只是简单解释一下面板库的用法:我们需要使用它来使地图在我们的笔记本上可用。如果我们想在同一个地图上添加多个数据集,这一点很重要。然而,通常不使用这些,地图将显示在单独的网页上。
加载数据
df = pd.read_csv('Coffee Brands Footprint.csv',
index_col=0)
作者图片:我们数据集的前五次观察。
创建底图-地理编码的转换
正如在其他文章中一样,我们需要创建一个底图,在其中对附加数据进行分层。
但是,请注意,与其他文章不同,我们没有使用 GeoPandas。因此,散景需要一种理解geometry
数据类型的方法。
为此,我们需要始终转换我们的地理编码集,或者更准确地说,使用投影比例,以便散景可以正确地绘制它们。
inProj = Proj(init='epsg:3857')
outProj = Proj(init='epsg:4326')ph_lon1, ph_lat1 = transform(outProj,inProj,115,0)
ph_lon2, ph_lat2 = transform(outProj,inProj,130,25)
上面的地理编码是通过反复试验为我们的地图生成最佳边界而生成的。如果您想将地图限制在特定的地区、国家或城市,以便更好地聚焦,我建议您也这样做。
要初始化基本地图:
#Initialize the tile that we will use
cartodb = get_provider(CARTODBPOSITRON)#Initialize the fig object
fig = figure(plot_width=800, plot_height=700,
x_range=(ph_lon1, ph_lon2),
y_range=(ph_lat1, ph_lat2),
x_axis_type="mercator",
y_axis_type="mercator",
tooltips=[
("Cofee Brand", "[@brand](http://twitter.com/brand)"), ("Location", "[@vicinity](http://twitter.com/vicinity)")
],
title="Coffee Shops in the Philippines")fig.add_tile(cartodb)fig.xaxis.visible = False
fig.yaxis.visible = Falseshow(fig)
让我们讨论一下散景的人物功能所特有的代码部分:
- x_range,y_range —这些是图形的边界。X 轴指的是经度,Y 轴指的是纬度。相应地调整这些以创建所需的地图边界。
- x_axis_type,y_axis_type —这告诉散景如何解释您的轴。“墨卡托”应该特别为非美国地图选择。
- 工具提示—要在工具提示中显示的变量列表。交互式工具提示的格式应该遵循一个元组。元组的第一个元素是将为工具提示显示的名称,第二个元素应该是对 dataframe 源的引用。格式应该是“@column_name”。
作者图片:底图已创建。请注意,在试图找到完美的边界时,轴应该理想地显示出来,以便经度和纬度值可见。
转换地理编码
正如我们所指出的,成对的地理编码需要被转换或“投影”才能对散景有意义。因此,我们需要使用以下代码:
lons, lats = [], []
for lon, lat in list(zip(df["lng"], df["lat"])):
x, y = transform(outProj,inProj,lon,lat)
lons.append(x)
lats.append(y)
df["MercatorX"] = lons
df["MercatorY"] = lats
转换后,如果我们想一次显示整个数据集,而不引用品牌,我们可以使用以下代码:
fig.circle('MercatorX', 'MercatorY',
source=df,
size=7,
fill_color='red',
line_color='red',
line_alpha=0.5,
fill_alpha=0.3)
show(fig)
作者提供的 GIF:第一张显示菲律宾所有咖啡店位置的交互式地图
因为我们想用不同的颜色展示每个品牌,所以我们需要分别添加它们。这种方法,对于该系列的追随者来说,被比作是叶的方法。
将每个品牌视为不同的数据集
为不同品牌添加不同颜色的方法是将每个品牌视为一个单独的数据集。
但是首先,我们需要建立一个颜色字典:
color_dict = {
"Starbucks": ' #00704A',
"Coffee Bean and Tea Leaf": '#362d26',
"Coffee Project": '#654321',
"Tim Hortons": '#dd0f2d'
}
我们需要一套新的 fig,因为上一套已经用红点编码了。
#Doing the Fig
fig = figure(plot_width=800, plot_height=700,
x_range=(ph_lon1, ph_lon2),
y_range=(ph_lat1, ph_lat2),
x_axis_type="mercator",
y_axis_type="mercator",
tooltips=[
("Cofee Brand", "[@brand](http://twitter.com/brand)"), ("Location", "[@vicinity](http://twitter.com/vicinity)")
],
title="Coffee Shops in the Philippines")fig.add_tile(cartodb)
要循环遍历数据集:
#Looping over the dataset
for i in color_dict.keys():
temp = df[df.brand==i]
fig.circle('MercatorX', 'MercatorY',
source=temp,
size=7,
fill_color=color_dict[i],
line_color=color_dict[i],
line_alpha=0.5,
fill_alpha=0.5)
最后,为了显示代码,我们需要这样做:
pn.pane(fig)
GIF 由作者:类似的互动地图,就像我们在以前的文章
请注意,show(fig)
可以正常工作,但可能会显示一条错误消息,所以这不是我们在文章中使用的。
结束语
从这篇文章中我们可以看出,用散景复制其他库的地图是可能的。
然而,我们确实看到,我们必须采取某些步骤来确保散景理解我们的数据类型(非地理空间数据类型也是如此),一些数据科学家需要熟悉这些数据类型。
散景在创建仪表板方面很棒,但我们还没有创建一个,所以就其完整的功能和特性而言,我们还没有看到全部。这可能是一个在未来开展的好项目,Bokeh 是一个学习和添加到现代地理空间数据科学家工具箱中的惊人工具。
让我知道你的想法!
贝叶斯自助
原文:https://towardsdatascience.com/the-bayesian-bootstrap-6ca4a1d45148
因果数据科学
简单而强大的 bootstrap 扩展的简短指南
封面图片,由作者使用nightcafe生成
在因果推断中,我们不仅仅想要计算治疗效果,我们还想要进行推断。理解围绕点估计的不确定性通常比点本身更有信息和价值。在某些情况下,由于 中心极限定理 ,计算估计量的(渐近)分布非常容易。例如,在计算 AB 试验或随机对照试验中的平均治疗效果时就是这种情况。然而,在其他情况下,推断更加复杂,要么是因为很难获得方差的分析估计量,要么是因为它需要难以估计的对象(例如分位数回归中的全密度)。那我们能做什么?
bootstrap 是数据科学的标准答案。这是一个非常强大的程序来估计一个估计量的分布,不需要任何数据生成过程的知识。实现起来也非常直观和简单:只需通过多次替换对数据进行重新采样,然后计算样本间的估计值。
我们能做得更好吗?答案是肯定的!贝叶斯自举是一个强大的程序,在很多设置中比自举执行更好。特别是,它通常更快,可以给出更紧的置信区间,并避免了许多极限情况。在本文中,我们将更详细地探讨这个简单但功能强大的过程。****
自举
bootstrap 是一种通过随机重新采样并替换数据来计算估计器属性的程序。它首先由 Efron (1979) 提出,现在是数据科学中的标准推理过程。程序非常简单,由以下步骤组成。
假设你有一个 i.i.d .样本{ X ᵢ}ᵢⁿ,你想使用估计量θ̂(x】计算一个统计量 θ 。你可以用下面的公式来近似θ̂的分布。
- 样本 n 观察值与替换样本{x̃ᵢ}ᵢⁿ{xᵢ}ᵢⁿ.
- 计算估计量 θ̂-bootstrap ( X̃ )。
- 多次重复步骤 1 和 2。
θ̂-bootstrap 的分布与 θ̂ 的分布非常接近。
自举为什么这么厉害?
首先是容易实现。除了已经在做的事情之外,它不需要你做任何事情:估计 θ 。你只需要做很多次。事实上,bootstrap 的主要缺点是它的计算成本。如果你的估算过程很慢,自举就变得禁止了。
第二,bootstrap 使得没有分布假设。它只假设你的样本是总体的代表,观测值是相互独立的。当观察结果彼此紧密相连时,例如在研究社会网络或市场互动时,这一假设可能会被违反。**
bootstrap 只是加权吗?
最后,当我们重新采样时,我们所做的是给我们的观察值分配整数权重,这样它们的总和就等于样本大小。这样的分布就是 多项式分布 。
让我们通过抽取一个大小为 10.000 的样本来看看多项分布是什么样的。我从[src.utils](https://github.com/matteocourthoud/Blog-Posts/blob/main/notebooks/src/utils.py)
导入了一组标准库和函数。为了不仅包括代码,还包括像数据和表格这样的输出,我使用了 Deepnote ,一个类似 Jupyter 的基于网络的协作笔记本环境。
首先,我们检查权重的总和是否为 1000,或者说,我们生成了相同大小的数据的重新样本。
我们现在可以绘制权重分布。**
如我们所见,大约 3600 个观察值的权重为零,而几个观察值的权重为 6。或者相当于,大约 3600 个观察值没有被重新采样,而几个观察值被采样了多达 6 次。
现在你可能会有一个自然而然的问题:为什么不使用连续砝码来代替离散砝码?**
非常好的问题!贝叶斯自举就是答案。**
贝叶斯自助
贝叶斯自助法是由 Rubin (1981) 提出的,它基于一个非常简单的想法:为什么不画一个更平滑的权重分布呢?多项式分布的连续等价物是 狄利克雷分布 。下面我绘制了单次观察的多项式和狄利克雷权重的概率分布(它们分别是泊松分布和伽玛分布)。**
比较权重分布,按作者分类的图像
贝叶斯自举有很多优点。
- 第一个也是最直观的一个是,由于它的连续加权方案,它提供的估计比正常的 bootstrap 更加平滑。
- 此外,连续加权方案防止了拐角情况的出现,因为任何观测都不会得到零权重。例如,在线性回归中,如果原始样本中没有共线性问题,则不会出现共线性问题。**
- 最后,作为贝叶斯方法,我们得到解释:估计量的估计分布可以解释为后验分布和无信息先验。**
让我们现在画一组狄利克雷权重。
权重自然总和(大约)为 1,所以我们必须用因子 n 对它们进行缩放。
和以前一样,我们可以绘制重量分布图,不同的是现在我们有连续的重量,所以我们必须近似分布。
狄利克雷权重示例,图片由作者提供
您可能已经注意到,狄利克雷分布有一个参数 α* ,我们已经将它设置为所有观测值的 1。它是做什么的?***
α 参数本质上决定了被采样的绝对和相对概率。增加所有观察值的 α 使得分布不那么偏斜,从而所有观察值具有更相似的权重。对于 α→∞ ,所有的观测值得到相同的权重,我们回到原始样本。
我们应该如何选择α*的值?邵和涂(1995) 建议如下。*****
随机权重向量的分布不必局限于 Diri(l,…,1)。后来的研究发现,具有比例 Diri(4,…,4)分布的权重给出了更好的近似(涂和郑,1987)
让我们来看看,对于所有观测值来说, α=4 的狄利克雷分布与之前对于所有观测值来说, α=1 的分布相比如何。
不同 α的狄利克雷权重样本,图片作者
新的分布更少偏斜,更集中在平均值 1 附近。
例子
让我们看几个例子,比较两种推理过程。
偏态分布的平均值
首先,让我们来看看最简单也是最常见的估计量之一:样本均值。首先,让我们从一个帕累托分布中抽取 100 个观察值。**
来自帕累托分布的样本,图片由作者提供
这种分布非常偏斜,一些观察值比平均值高得多。**
首先,让我们计算一个再抽样的经典 bootstrap 估计量。
然后,让我们写一组随机权重的贝叶斯自举。
我们现在可以实现任何引导程序。我使用[joblib](https://joblib.readthedocs.io/en/latest/)
库来并行化计算。
最后,让我们编写一个比较结果的函数。
样本均值的 Bootstrap 分布,按作者分类的图像
在这个设置中,两个程序给出了非常相似的答案。这两个分布非常接近,而且估计量的估计均值和标准差几乎相同,与 bootstrap 过程无关。
哪个引导程序更快?**
在 97.8%的模拟中,贝叶斯 bootstrap 比经典 bootstrap 快,并且快了令人印象深刻的 66.5%!
不加权?没问题
如果我们有一个不接受权重的估计量,比如中位数,会怎么样?我们可以做两级抽样:首先我们对权重进行抽样,然后根据权重对观测值进行抽样。**
样本中位数的 Bootstrap 分布,按作者分类的图像
在这种情况下,贝叶斯 Bootstrap 也比经典 Bootstrap更精确*,因为 α=4 时的权重分布更密集。***
结果罕见的逻辑回归
现在让我们探索经典自举可能陷入困境的两种设置中的第一种。假设我们观察到一个特征 x ,正态分布,以及一个二元结果 y 。我们对这两个变量之间的关系感兴趣。**
在这个样本中,我们只在 100 次观察中的 10 次观察到阳性结果。
由于结果是二元的,我们拟合一个 逻辑回归 模型。
我们得到的点估计值为 -23 ,置信区间非常小。
我们能自助估计量的分布吗?让我们尝试计算 1000 个 bootstrap 样本的逻辑回归系数。
对于 1000 个样本中的 5 个,我们无法计算估计值。使用贝叶斯自举不会发生这种情况。**
在这种情况下,这似乎是一个无关紧要的问题:我们可以忽略这些观察。让我们以一个更危险的例子来结束。
用很少的处理单元回归
假设我们观察到一个二元特征 x 和一个连续结果 y 。我们再次对这两个变量之间的关系感兴趣。
让我们比较一下 x 上 y 回归系数的两个 bootstrap 估计量。
作者自举分布图
经典的 bootstrap 程序估计的方差比我们的估计量大 50%。为什么?如果我们更仔细地观察,我们会发现在近 20 个重新样本中,我们得到了一个非常不寻常的零估计值!为什么?
问题是,在某些样本中,我们可能没有任何观察值x = 1。因此,在这些重新采样中,估计系数为零。贝叶斯自助不会发生这种情况,因为它不会丢弃任何观察值(所有观察值总是得到正权重)。****
这里有问题的部分是我们没有得到任何错误消息或警告。这种偏见非常狡猾,很容易被忽视!
结论
在本文中,我们看到了 bootstrap 的一个强大扩展:贝叶斯 bootstrap。关键思想是,只要我们的估计量可以表示为加权估计量,bootstrap 就相当于带有多项式权重的随机加权。贝叶斯自助相当于用狄利克雷权重加权,即多项式分布的连续等价。具有连续的权重避免了极限情况,并且可以生成估计量的更平滑的分布。
这篇文章的灵感来自布朗大学教授彼得·赫尔的以下推文。
事实上,除了是一个简单和直观的程序,贝叶斯 Bootstrap 并不是经济学研究生院标准计量经济学课程的一部分。
参考
[1] B. Efron Bootstrap 方法:再看刀切(1979)《统计年鉴》。**
[2] D .鲁宾,《贝叶斯自助法》 (1981),《统计年鉴》。**
[3] A. Lo,贝叶斯自助法的大样本研究 (1987),《统计年鉴》。**
[4] J .邵,d .涂,杰克尼菲与自举 (1995),斯普林格。**
密码
你可以在这里找到 Jupyter 的原始笔记本:
***https://github.com/matteocourthoud/Blog-Posts/blob/main/notebooks/bayes_boot.ipynb ***
感谢您的阅读!
真的很感谢!🤗如果你喜欢这个帖子并且想看更多,可以考虑 关注我 。我每周发布一次与因果推断和数据分析相关的主题。我尽量让我的帖子简单而精确,总是提供代码、例子和模拟。**
还有,一个小小的 免责声明 :我写作是为了学习所以错误是家常便饭,尽管我尽了最大努力。当你发现他们的时候,请告诉我。也很欣赏新话题的建议!
渐变之美
原文:https://towardsdatascience.com/the-beauty-of-gradient-7798f4f0dd40
在一个真实的例子中,让我们探索这个简单而强大的计算如何帮助您过滤数据,尤其是不同的生产批次
杰里米·贝赞格在 Unsplash 上的照片
梯度在机器学习中的一般用途
当然,如果你对数据科学感兴趣已经有一段时间了,甚至只有几个星期,你可能听说过梯度下降以及它如何帮助你找到线性函数或神经网络的最佳系数。
成本函数示例-作者图片
一个典型的用例是当您寻找线性回归的最佳参数时。成本函数曲线可能如上图所示。
损失函数(红色)-步长(蓝色)-局部斜率(绿色)-作者提供的图像
从第 1 点开始,我们可以使用每一步的斜率来确定我们的目标是优化损失函数还是偏离它。
- 第一步:x = 0;斜率= -6
- 第二步:x = 0,5;斜率= -5
- 第三步:x = 1;斜率= -4
- 第四步:x = 1,5;斜率= -3
- 第五步:x = 4;斜率= +2
- 第六步:x = 3;slope = 0<= local miminum
Curious about how this gradient (or slope) is calculated? We simply need to use the derivative from the loss function:
Loss function:
f(x)=(x-3)+2
f(x)= x-2 *(3x)+2
f(x)= x-6x+4
导数:
f'(x) = 2x-6
结果:
f '(0)= 2(0)-6 =-4
f '(4)= 2(4)-6 =+2
f '(3)= 2(3)-6 = 0
利用梯度过滤生产时间序列
最近,我一直在处理一个案例,一台机器生产许多不同等级的产品,其速度有规律地变化(如下图的时间序列所示)。
由于历史数据中有数百处变化,我们需要确定生产稳定的时期,并消除加速/减速时期:
原始时间序列—作者提供的图像
首先,为了抵消传感器自身不稳定性的影响,我们决定使用滚动窗口(20)来平滑局部变化:
原始时间序列+平滑滚动窗口-作者提供的图像
神奇的事情发生了:通过计算时间序列中每一点的梯度,我们可以很容易地识别出速度变化并向另一个名义速率移动的时刻。
每当这种情况发生时,梯度将从非常低的水平(0=完全稳定)切换到更高的水平(看到绿线上的小突起)。
平滑滚动窗口+梯度计算—作者提供的图像
这种方法的好处是,它对绝对值不敏感:从 50 到 150 或从 100 到 200 切换将给出相同的梯度值,这使得自动分析生产变化容易得多。
然后,只需定义一个梯度阈值,从时间序列中移除变化周期,如下所示:
原始时间序列+排除时段-按作者分类的图像
结论:
复杂的问题,例如在一个时间序列中分离稳定和不稳定的时期,从一开始就看起来很有挑战性!
例如,您可能会考虑计算一个“移动绝对差值”来识别这种变化。我们甚至可以考虑将时间序列的第一部分标记为“稳定”和“不稳定”类,然后训练神经网络来识别它们(是的,这肯定是“过度的”,但我们可以做到!).
但是,有时候,最简单的方法仍然是最有效的。
寻找简单数学函数如何帮助特征工程的另一个例子? 看看我写得最好的一篇文章,解释“余弦”和“正弦”如何帮助你处理周期性特征:
与本文对应的代码存储在这里:
https://github.com/pierrelouisbescond/medium_articles/blob/main/medium_gradient.ipynb
请不要犹豫,浏览我在 Medium 上的其他文章:
https://pl-bescond.medium.com/pierre-louis-besconds-articles-on-medium-f6632a6895ad
方法的妙处错误
原文:https://towardsdatascience.com/the-beauty-of-the-methoderror-e5bb2f3e2678
方法错误的概述,以及为什么它在 Julia 中如此有用
(图片由 Pixabay 上的 markusspiske 拍摄)
介绍
抛出、错误、异常、退出代码,不管你想怎么称呼它们,它们在计算中有着巨大的用途。尽管在理想世界中,软件可以很好地应用于每一个用例及场景,但这在计算中并不现实。函数不处理特定的数据或输入是很常见的,这会导致问题。抛出是适当的,这样我们就能确切地知道哪里出错了,并且栈跟踪可以让我们追踪到任何问题的根源。
不管一个人犯了什么样的错误,返回一个实际的一致的错误输出,或者代码,或者任何东西,可以给开发人员很多关于哪里出错的上下文。此外,只要某种回报仍然有价值,就更容易知道到底哪里出了问题。我认为汇编如此令人讨厌和难以编写的最大原因之一是因为没有任何真正的抛出——所以我没有它们,相信我,没有它们调试是非常困难的。假设 Julia 是一种通常由最终用户直接使用的语言,并且很可能是一名程序员,在某种交互式的动态环境中与代码进行交互,那么 Julia 使用大量 throws 是很有意义的。今天,我想向您介绍一个 throw,它是 Julia 编程语言主干的基础。这当然是 MethodError,它在很多方面是多分派范例的事实错误。今天我想谈谈如何利用这个错误来弄清楚动态环境中的代码是如何工作的,并谈谈为什么这类错误在其他语言中实现会很棒,因为它们非常有用。
方法错误
方法错误是一个核心的 Julia throw,它是语言核心思想的一个非常重要的组成部分。毕竟,该语言范式的整体思想是提供某些类型作为某些方法的参数。每当我们用错误的类型作为参数调用方法时,就会抛出方法错误。因为方法是通过多态定义的,所以无论何时用不正确的参数调用这些方法,我们都必须获得某种程度的返回。那么这些方法在技术上是不存在的。很棒的是,方法错误只会在你用错方法的时候出现。例如,如果我试图使用一个不存在任何类型的方法,我们会得到一个未定义的错误:
hrthtrh()UndefVarError: hrthtrh not defined
然而,如果我们叫推!()举个例子,用错误的参数,我们会得到我们光荣的方法错误:
push!()
MethodError: no method matching push!()
Closest candidates are:
push!(::AbstractChannel, ::Any) at /opt/julia-1.6.3/julia-1.6.3/share/julia/base/channels.jl:10
push!(::Set, ::Any) at /opt/julia-1.6.3/julia-1.6.3/share/julia/base/set.jl:59
push!(::Base.InvasiveLinkedListSynchronized{T}, ::T) where T at /opt/julia-1.6.3/julia-1.6.3/share/julia/base/task.jl:570
方法错误真正伟大的地方在于,它实际上为方法提供了很多上下文,以及方法的能力。也就是说,这是在我们很好地理解了该方法的作用之后——以及 Julia 中的类型层次结构。实际上,我有一整篇关于我们目前正在使用的方法的文章,这可能会提供这个例子的一些背景。如果你想更深入地了解这一推!()方法,这里是那篇文章!:
无论如何,这个输出的伟大之处在于它告诉我们到底哪里做错了。我们为方法调用提供了这组类型,但是只存在以下绑定。这很有意义,这个快速返回告诉我们,我们需要了解这些方法。我们基本上可以提供任何 iterable 和任何其他参数,以便做什么推!()会,它会将该值放入 iterable 中。在我们继续深入讨论这个问题之前,让我们写一些更简单的函数,以便把它变成白纸黑字。
function printthisthang(x::Int64)
println(x)
end
因为这个方法只有一个参数,必须是 Int64。例如,如果我们提供一个 float,我们将得到:
printthisthang(5.5)MethodError: no method matching printthisthang(::Float64) Closest candidates are: printthisthang(::Int64) at In[6]:1
方法错误的伟大之处在于它告诉我们到底哪里做错了。一旦你仔细分析了更具体的输出,它实际上说的是,我们提供了一个 Float64,但该函数的定义需要和 Int64 的唯一现有方法。我们确切地知道我们做错了什么,并且还可以从这个输出中了解关于这个函数的上下文的更多信息,这使得它成为一个巨大的错误—我们确切地知道如何修复我们所做的,并且我们确切地知道我们做了什么。更好的是,这些可以为扩展某些方法调用提供一些上下文,这些方法调用可能会被提取一点。一个很好的例子就是索引。让我们考虑这种新类型:
mutable struct OurCollection
x
function OurCollection(x::Any ...)
new(x)
end
end
如果我们试图索引它,我们会得到一个方法错误。但是,方法错误告诉我们是哪个函数导致了这个问题:
z = OurCollection(5, 10, 15)
z[2]
MethodError: no method matching getindex(::OurCollection, ::Int64)
所以我们基本上可以把它插入到一个新的方法中,然后很快地解决这个问题,这都是因为方法错误准确地告诉了我们该做什么。
import Base: getindex
getindex(x::OurCollection, i::Int64) = x.x[i]
z[2]10
我认为方法错误非常有价值。他们不仅能告诉你你的代码到底出了什么问题,还能提出一些可能的修复方法。从高层次的角度来看,这是很棒的,因为即使我们使用了完全错误的东西,我们仍然得到了所需的工具来修复我们搞砸的东西。此外,它可以为我们提供许多函数的上下文,我们可能需要运行文档的唯一内容是返回什么,或者所述函数的实际用途是什么。总而言之,我真的觉得其他语言应该实现方法错误。
我认为尤其是在 Python 中,方法错误很有意义。我最近写了一篇关于为什么应该用 Python 输入参数的文章,结论很简单,它有助于记录你的软件。如果有人提供了错误的类型,进行某种全面的分析会很好,而不是仅仅试图运行函数,然后每当方法不适用于某人错误提供的类型时就产生一些错误。如果您想阅读更多关于在 Python 中键入参数的内容,可以查看那篇文章:
对我来说,在编程时考虑不同值的类型似乎更自然。这似乎更自然,因为类型是数据的一个非常重要的维度!很高兴看到这个错误被移植到我喜欢的其他语言中,因为我相信它非常有价值。当然朱利安版本是以上和超越,我只是说,这将是很好的人知道他们提供了什么类型的错误,在某种程度上类似于一个论点错误。感谢您阅读本文,我希望它主要有助于开发您的方法错误的用法来修复您的代码!
做出有效商业决策的因果推理初学者指南
因果推理
什么是因果推理?了解如何知道什么是有效的,并有效地使用它来优化业务流程。因果推理的用户友好指南!
毛里西奥·马斯卡罗的照片:https://www . pexels . com/photo/person-holding-放大镜-712786/
几乎你们每个人在学校都学过统计相关性的口头禅,“T2 相关性并不意味着因果关系”。仅仅因为两个现象之间有很高的相关性,并不意味着也有因果归因。比如日出和公鸡的啼叫有很高的相关性;然而,它并没有帮助我们知道是公鸡的叫声导致了太阳的升起,还是太阳的升起导致了公鸡的叫声。各种企业和行业都是在资源有限的情况下运作的,所以对于管理者来说,是什么导致了期望的变化是绝对重要的。例如,哪个营销活动推动了销售?哪种药物治疗头痛更有效?哪个 app 版本导致用户留存率更高?所有这些问题都由研究人员/经济学家/数据科学家所谓的因果推理来回答。在这篇文章中,我将告诉你什么是因果推理,为什么你应该关心,你如何在你的工作中使用因果推理,方法,以及最后在应用因果推理时需要注意的重要事项。这里有很多东西要打开,所以拿起一杯咖啡(或茶),马上开始品尝知识吧!
什么是因果推理
用非常简单的话来说,因果推理就是对因果关系的研究。那些练习因果推理的人会问这样的问题,比如 X 会引起 Y 吗,改变 X 对 Y 有什么影响?比如改变网站的格式对用户留存有什么影响?当我们在网站上使用面对面交谈而不是自动聊天时,我们看到客户满意度提高了吗?要回答这类问题,我们需要平行地看待两个不同的词——一个是给予人“干预”的世界,另一个是没有给予人干预的世界。让我们举一个非常简单的 A/B 测试的例子。理想情况下,我们希望同时测量一个人 X 在使用我们的网站版本 A 时的行为,以及同一个人 X 在使用我们的网站版本 B 时的行为。现在,因为我们不是生活在一个克隆人可以同时访问相同内容的世界,我们无法理想地衡量网站版本 A 与网站版本 b 的影响。这是一个问题。我们现在要干嘛?输入反事实!
什么是反事实?
反事实这个词可以分为两个词反和事实。因此,反事实的意思是在特定的情况下与事实相反的东西。例如,如果一所大学的一组学生被给予额外的工作培训,那么这个组被称为真实组。反事实是没有接受训练的相同的组。反事实的问题涉及到如果这个群体没有接受培训会发生什么。然而,我们不能同时给同一个学生培训和不给培训,我们需要一个反事实的估计,也就是说,一个尽可能接近被培训群体的群体。这一组也被称为控制组,也就是说,一组被控制,没有训练。听起来很复杂?让我试着用一个例子来解释。假设我们为一家银行工作,该银行拥有在该银行拥有账户的个人的人口统计和收入数据的详细信息。我们希望向年收入超过 100 万卢比的客户推出一项新的个人服务,帮助他们了解银行的各种产品,并了解这种个人服务是否会导致其他金融产品的出现。因此,干预是个人服务,结果是通过购买金融产品的数量来衡量的吸收。估计的反事实组将是与原始组尽可能相似的组。你将如何定义这个群体?让我们继续前进!
我为什么要在乎因果推断?
最重要的原因是,我们的世界是在因果关系中运行的。太阳的升起使公鸡发出叫声。击球时选择特定的角度会使球落入洞中。第二个重要原因是,我们的用户与我们的产品的交互不是随机的,而是经过深思熟虑的。除非我们知道他们为什么这样做,否则我们无法提供他们所需要的东西。因此,它要求我们对用户有同理心,然后从方法上测试什么有效,在什么条件下有效。第三,随着机器学习的兴起,我们有可能用一种更微妙的方法来进行因果推理,以做出商业决策。机器擅长做可重复的快速任务,但它们仍然不擅长做需要理解因果关系的任务。由于世界资源有限,我们需要测试并推出最有效的政策;计量经济学领域允许我们这样做。
我如何使用因果推理
计量经济学领域关注的是因果推理的结构化研究。然而,所有的知识都可以归结为以下几个核心步骤。
- 定义干预/治疗/政策/服务 —第一步是定义您将要推出的内容。这可能是一项新的福利计划,一种新的营销方式,或者一种新的销售技巧。
- 定义兴趣结果 —下一步是定义兴趣结果。你有兴趣了解对什么的影响?例如,新的销售技巧会导致更高的平均篮子价值吗?营销活动是否能提高受众参与度?儿童福利计划能降低儿童死亡率吗?这些是你可能感兴趣的结果。
- 定义接受治疗/干预/政策/服务的群体 —该群体可以随机决定,这产生了一种最有影响力的实验方法,称为随机对照试验。然而,由于货币/社会/政治/地理问题,随机对照试验总是不可能进行。另一种确定这个群体的方法是使用一个分界点或边界来确定可包含的人群。例如,一项政策只在位于一个省的农场推出,而不在邻近的农场推出,或者只对购物超过规定金额的顾客给予优惠待遇,等等。
- 估计反事实——正如我上面所描述的,我们永远不可能有完美的反事实,但是我们可以用计量经济学的方法得到近乎完美的反事实。一旦这个反事实成立,我们就可以进行下一步。
- 进行比较 —一旦我们对反事实组和事实组有了清晰的了解,我们需要比较两个组感兴趣的结果,这可以帮助我们对政策/计划是否实现了组织的战略目标做出统计决策。在这个阶段,陈述假设和分析中可能出现的错误也很重要。这些在本文的最后一节有更详细的介绍。
因果推理方法
因果推理领域最有影响力的人物之一约书亚·安格里斯特(Joshua Angrist)创造了“愤怒五人组”一词来描述五种最常用的因果推理方法。为了简单起见,我在这里只提到这五个(以及简短的描述);然而,研究人员/数据科学家可以在工作中使用更多复杂的方法。我会建议有动力的学习者打开任何有影响力的计量经济学杂志,找出更多的方法。好吧,盖世五侠是什么?
- 随机分配 —该方法包括将采样帧分成两个随机部分。其中一个接受了干预,另一个没有。这并不总是可能的,因为对某些人隐瞒干预涉及伦理问题。
- 回归——这是我们的老朋友 OLS 回归,它测量一个变量的变化对另一个变量的影响。例如,如果有人想知道每多受一年教育会给个人生活带来的工资差异。这不是我最喜欢的方法,所以我会要求用户自己深入研究这个问题。
- 工具变量——简单来说,IV 是引入的第三个变量,它与干预/政策/活动/服务变量相关,但与利益变量的结果不相关。当存在遗漏变量偏差的风险,并且有观测数据存在问题时,通常使用这种方法。
- 回归不连续设计 —这种方法使用一种人为的分界点将人们分成两组。例如,在一所学校,只有那些得分超过 90%的人才会接受培训,其他人不会接受培训。这里的假设是,除了 90%的临界值,那些分数在 88-90%之间的人和那些分数在 90-92%之间的人彼此相似。
- 差异中的差异法 —该方法捕捉两组之间结果的差异。例如,一组人接受干预,随着时间的推移测量结果,而另一组人没有接受干预,随着时间的推移测量结果。最后的比较是看这两组之间的差异有多大,因此被称为差异中的差异。
如前所述,这些并不是因果推断的唯一方法。有一些非常先进的方法,如综合控制方法,贝叶斯优化,中断时间序列设计。
要记住的事情
有了这些承诺,你一定很兴奋能马上在你的数据上尝试因果推断。但是,在使用这些方法时,您需要记住一些重要的注意事项。首先也是最重要的是,两个变量之间的相关性并不意味着因果关系。除此之外,还有四个需要特别提及。
- 省略变量:有时候,有一个潜伏的第三个变量在影响两个变量。你可能已经读过这个著名的数据,它断言吃更多的冰淇淋会导致更高的鲨鱼袭击死亡率。这里需要注意的是,更高的温度是被忽略的变量,这导致更多的人去海里游泳,也导致更多的人去买冰淇淋。同样,由于贫困,更多的可乐导致更高的暴力。
- 反向因果关系:为了清楚地阐明手头的问题不是反向因果关系的问题,人们需要小心谨慎并具备相关专业知识。例如,这篇文章提到,更多的性行为会带来更多的收入。然而,有些人说情况正好相反,因为收入高的人更有可能约会并发生性关系。
- 抽样偏差:抽样偏差的经典统计问题也在因果推断中发挥作用,尤其是当用户/客户/人们自己选择特定的干预措施时。你有没有遇到过这样的事情,98%参加在线调查的人发现在线调查很有帮助?这是自我选择的悖论。
- 测量误差:很多时候,我们想要测量的东西不可能有精确的测量值。在这种情况下,推理统计和因果推理在用于分析时都会有问题。另一件事是,有时人们在讲述他们的现实情况时会更有所保留。例如,在对同性恋关系持非正统态度的国家,人们不太可能准确报道。这些是你需要记住的一些问题。
后续步骤
如果你在阅读这篇文章时已经达到了这一步,这意味着你非常有兴趣学习更多关于因果推理和用于因果分析的方法。我最喜欢的三本书是:
- 斯科特·坎宁安的因果推理
- 因果推理:如果詹姆斯·罗宾斯和米格尔·埃尔南
- 约书亚·安格里斯特的《基本无害的计量经济学》
- 特别提及:勇敢而真实的因果推断
如果你有兴趣了解更多,或者如果你是一个想建立关系网的从业者,这是我的 LinkedIn 个人资料。我很乐意连接。
分布式计算初学者指南
原文:https://towardsdatascience.com/the-beginners-guide-to-distributed-computing-6d6833796318
用 Python 实现分布式计算的 7 个基本概念
进入分布式世界
越来越多的数据科学家正在冒险进入分布式计算的世界,以扩大他们的计算规模,更快地处理更大的数据集。但是开始您的分布式计算之旅有点像进入另一个世界:势不可挡、令人生畏、令人困惑。
图片来自 giphy.com
但是这里有一个好消息:你不需要了解分布式计算的所有知识就可以开始。
这有点像去一个语言不通的国家度假。在登机前,学习如何就当地错综复杂的政治体系展开完整的对话是多余的。但是明智的做法可能是知道如何在需要的时候四处寻求帮助。
这篇文章解释了你开始分布式计算需要的 7 个基本概念。尽早掌握这些基本概念将会节省你数小时的研究时间和以后昂贵的错误。这些概念将通过使用 Dask 的 Python 代码来演示。
让我们开始吧。
1.懒惰评估
惰性求值是一种编程策略,它将表达式或变量的求值延迟到需要它的值的时候。与 strict 或 eager evaluation 相反,在后者中,表达式在被调用时被直接求值。惰性求值通过避免不必要的重复求值,增加了计算的优化并减少了内存负载。
懒惰的北极熊途经giphy.com
让我们用一个思维实验来说明。
来见见 Mercutio,我们的三度封爵分布式计算鼠标专家。
图片来自 twemoji (CC-BY 4.0 许可证)
茂丘西奥将参与一项实验。这个实验的目的是让茂丘西奥找到穿过迷宫到达最终目的地的最快方法:一块美味的切达奶酪。通过放置面包屑来指引茂丘西奥,可以确定迷宫的路径。这个实验的目标是尽可能快地拿到奶酪,所以 Mercutio 每吃一个面包屑就会减 1 分。
在场景 1 中,Mercutio 在您放置第一个面包屑后立即开始行走(用计算术语来说是“执行”),并跟随您从一个面包屑到另一个面包屑。这样,他当然会最终到达他预定的目的地。他将也将已经招致 5 个负点,每经过一个面包屑(和吃一个面包屑)一个负点。这不是问题的错误解决方案,但也不是最佳方案。
作者图片,表情符号通过 twemoji
然而,如果茂丘西奥让推迟执行死刑,直到你放下奶酪然后评估形势,他就能看到整个问题,并找出解决问题的最快方法。
作者图片,表情符号通过 twemoji
两个茂丘西奥都达到了预期的效果(吃奶酪!)但是懒惰或“延迟”的评估 Mercutio 能够更快、更有效地完成这些工作。
代码示例
让我们用 Python 代码中的一个例子来演示使用熊猫(急切求值)和 Dask(懒惰求值)。在下面的代码中,我们将创建一个数据帧,调用该数据帧,然后在特定的列上通过计算建立一个 groupby。请注意 pandas 是如何立即返回结果的,而 Dask 只有在您明确告诉它开始计算时才会这样做。
import pandas as pd# create a dataframe
df = pd.DataFrame({
"Name": ["Mercutio", "Tybalt", "Lady Montague"],
"Age": [3, 2, 4],
"Fur": ["Grey", "Grey", "White"]}
)# call the DataFrame
df
熊猫立即返回数据帧的内容(图片由作者提供)
# define a groupby computation
df.groupby('Fur').Age.mean()
熊猫立即返回分组结果
我们看到熊猫热切地评价我们定义的每一句话。DataFrame 定义和 groupby 计算的结果都会立即返回。当在 pandas 中工作时,这是预期的行为,并且当处理相对较小的数据集时,这种行为很好,可以很好地容纳在机器的内存中。
当您的数据帧包含的数据超过您的机器在内存中可以容纳的数据时,问题就出现了。Pandas 别无选择,只能尝试将数据加载到内存中,但失败了。
这就是像 Dask 这样的分布式计算库评估迟缓的原因:
import dask.dataframe as dd# turn df into a Dask dataframe
dask_df = dd.from_pandas(df, npartitions=1)# call the dataframe (no contents returned)
dask_df
dask 只是懒洋洋地返回数据帧的模式,而不是内容(图片由作者提供)
# define the same groupby computation as above (no results returned)
dask_df.groupby('Fur').Age.mean()
dask 只是懒洋洋地返回 groupby 的模式,而不是结果(作者的图片)
当我们调用 DataFrame 时,Dask 不会返回结果,当我们通过计算定义 groupby 时也不会。它只返回结果的模式或大纲。
只有当我们专门调用.compute()
时,Dask 才会实际执行计算并返回结果。这样,它可以等待找到达到预期结果的最佳路径,就像上面场景 2 中的 Mercutio 一样。
# trigger computation
dask_df.groupby('Fur').Age.mean().compute()
作者图片
惰性评估允许像 Dask 这样的库通过识别令人尴尬的并行计算部分来优化大规模计算。
2.令人尴尬的平行
术语“令人尴尬的并行”用于描述计算或问题,这些计算或问题可以很容易地分成更小的任务,每个任务都可以独立运行。这意味着任务之间没有依赖关系,它们可以以任何顺序并行运行。这些类型的问题有时也被称为“完全平行”或“令人愉快的平行”。
图片来自 freesvg.org,公共领域
让我们回到我们的思想实验。
我们亲爱的朋友茂丘西奥已经加入了两个同伴,他们也将参加一个懒惰的评估奶酪发现任务。我们将为这三个捕鼠人设置两个不同的实验。
在实验 1 中,切达奶酪块被分成 3 等份,每份放在不同迷宫的尽头。在实验 2 中,奶酪块保持完整,并被放在迷宫 3 尽头的一个上锁的盒子里。迷宫 1 和 2 都有一个上锁的盒子,里面有打开下一个迷宫盒子的钥匙。这意味着老鼠 1 需要从他们的迷宫中获得钥匙,并将其传递给老鼠 2,老鼠 2 需要为老鼠 3 做同样的事情。两个实验的目标都是吃掉整块奶酪。
作者图片,表情符号通过 twemoji
实验 1(上图)是一个令人尴尬的并行问题的例子:每个 Mouseketeer 可以独立地解决他们自己的迷宫,从而并行地完成整体任务(吃掉那块奶酪)。
实验 2(下图)是一个根本无法并行化的问题的例子:解决每个迷宫取决于先解决前一个迷宫。
作者图片,表情符号通过 twemoji
实际上,你在分布式计算中遇到的问题将会处于完全令人尴尬的并行和完全不可并行之间。在大多数情况下,您的部分计算可以轻松地并行运行,而其他部分则不能。像 Dask 这样的分布式计算库会帮你解决这个问题。
代码示例
一个简单的 for 循环是一个常见的令人尴尬的并行问题的例子:循环的每次迭代都可以独立运行。蒙特卡洛模拟是一个更复杂的例子:它是一种使用重复随机抽样来估计概率的模拟。每个随机抽样独立运行,不会以任何方式影响其他抽样。
# a simple for loop is an embarrassingly parallel problemfor i in range(0,5):
x = i + 5
print(x)
将分区的 Parquet 文件读入 Dask 数据帧是另一个令人尴尬的并行问题的例子。
df = dd.read_parquet(“test.parquet”)
df.visualize()
作者图片
为了进行比较,下面是在相同数据帧df
上通过计算得出的一个组的任务图:
作者图片
这显然是而不是一个令人尴尬的并行问题:图中的一些步骤依赖于前面步骤的结果。这并不意味着问题根本不能并行化;Dask 仍然可以通过将您的数据划分到分区来并行化部分的计算。
https://coiled.io/blog/common-dask-mistakes/
3.划分
分区是数据的逻辑划分,可以独立于其他分区进行处理。分区被用于分布式计算环境的许多领域:Parquet 文件被划分为分区,Dask 数据帧和 Spark RDDs 也是如此。这些批量数据有时也称为“块”。
在上面令人尴尬的平行实验 1 中,我们将实验的目标(奶酪块)分成了 3 个独立的部分,或称块。然后,每个 Mouseketeers 可以在单独的分区上做必要的工作,共同实现吃掉奶酪块的总体目标。
作者图片,表情符号通过 twemoji
Dask 数据帧也分为分区。Dask 数据帧中的每个分区都是一个独立的 pandas 数据帧,可以发送给单独的工作机进行处理。
作者图片
当您向 Parquet 写入 Dask 数据帧时,每个分区都将被写入它自己的 Parquet 分区。
df = dask.datasets.timeseries(
"2000-01-01",
"2000-01-08",
freq="1h",
partition_freq="1d"
)df.npartitions>> 7df
作者图片
# write each dask partition to a separate Parquet partition
df.to_parquet(“test.parquet”)
为了将我们到目前为止讨论的概念结合起来,将分区的拼花文件加载到 Dask 数据帧将是一个令人尴尬的并行问题,因为每个拼花分区都可以加载到它自己的 Dask 数据帧分区中,而不依赖于其他分区:
df = dd.read_parquet(“test”)
df.visualize()
作者图片
类似上面的任务图是由一个调度程序创建和委派的。
4.调度程序
调度器是一个计算机进程,它在你的分布式计算系统中协调数据的分布和对数据的计算。它确保数据在多个进程中同时得到高效、安全的处理,并根据可用资源分配工作负载。
图片来自 giphy.com
在一个简单的令人尴尬的并行问题中,比如并行化一个for
循环,跟踪谁在做什么是相对容易的。但是,当处理包含数百万甚至数十亿行数据的数据集时,这就变得更加困难了。哪台机器有哪部分数据?我们如何避免重复?如果有重复的,我们应该使用哪个副本?我们如何将所有的分区正确地拼凑成一个有意义的整体?
回到茂丘西奥和他的朋友们,假设我们的三名捕鼠队员每人负责准备一顿复杂大餐的一个独立部分:茂丘西奥炒洋葱,提伯特磨碎奶酪,蒙塔古夫人蒸花椰菜。
作者图片,表情符号通过 twemoji
现在想象一下,不是 3 只而是 30 只老鼠在这个厨房里一起工作,它们的活动必须仔细协调和同步,以尽可能充分利用现有的厨房用具。如果我们把这种协调任务留给 30 只老鼠自己,很快就会出现混乱:每只老鼠都忙于自己独立的工作,无法清楚地了解整体情况,并以最有效的方式分配任务和资源。老鼠将被提示使用同样的锅和刀,这顿饭很可能不会按时吃完。
输入主厨。
表情符号 via twemoji
主厨(又名“调度”)掌握着这顿饭的权威食谱,并根据需要将任务和资源分配给每只烹饪老鼠。当食物的各个部分都准备好了,每只老鼠会把它们的工作结果反馈给主厨,主厨会把它们组合成最终的产品。
作者图片,表情符号通过 twemoji
有许多不同种类的调度程序,了解更多关于您计划使用的分布式计算解决方案的具体选项会很有用。根据您是在本地还是远程集群上工作,调度程序可能是单台机器中的独立进程,也可能是完全自治的计算机。
调度器是任何分布式计算集群的中枢。
5.簇
集群是作为一个单元一起工作来执行工作的一组计算机或计算进程。集群构成了分布式计算系统的核心架构。
不管具体的实现或架构如何,集群都有许多共同的元素:客户机、调度器和工作器。
客户端是您编写包含计算指令的代码的地方。对于 Dask,它是您的 iPython 会话或 Jupyter 笔记本(或者您编写和运行 Python 代码的任何地方)。
调度器是协调你的分布式计算系统的计算机进程。对于笔记本电脑上的本地集群,这只是一个单独的 Python 进程。在大型超级计算机集群或云中的远程集群的情况下,调度程序通常是一台自治计算机。
工作者是在数据分区上执行计算的实际工作的计算机进程。在您的笔记本电脑上的本地集群中,每个工作者都是位于您的机器的独立核心上的进程。在远程集群中,每个工作者通常是它自己的自治(虚拟)机器。
图片来自 dask.org
集群既可以存在于本地的一台机器上,也可以分布在服务器或云中的各种(虚拟)机器上。这意味着集群可以由以下各项构成:
- 多核心在一台机器内,
- 在同一个物理空间内的多台物理机(一台高性能超级计算机),
- 多个虚拟机分布在物理空间中(云计算集群)
6.纵向扩展与横向扩展
在分布式计算环境中工作时,您会经常听到人们使用术语“纵向扩展”和“横向扩展”。这用来表示使用本地集群和远程集群的区别。“扩大规模”意味着在当地使用更多的资源。“横向扩展”意味着远程使用更多资源。**
作者图片,表情符号通过 twemoji
例如,从使用 pandas 运行计算(它只使用您计算机中的一个内核)过渡到使用一个本地 Dask 集群是向上扩展的一个实例。将相同的工作负载从 pandas 转移到具有盘绕式的远程 Dask 集群就是向外扩展的一个例子。
**# scale computations OUT to a cloud cluster# launch cloud cluster with Coiled
import coiled
cluster = coiled.Cluster(n_workers=20)# connect cluster to Dask
from dask.distributed import Client
client = Client(cluster)# run computations over on 40GB+ data on remote cloud cluster
ddf = dd.read_parquet(
's3://coiled-datasets/timeseries/20-years/parquet/'
)ddf.groupby('name').x.mean().compute()**
****纵向扩展还可能涉及从 CPU 到 GPU 的过渡,即“硬件加速”。Dask 可以用cudf
代替 pandas 将你的数据帧操作转移到你的 GPU 上进行大规模加速。(感谢雅各布·汤姆林森对这一点的阐述。)
7.并行计算与分布式计算
无论执行计算的进程是否使用单个共享内存,并行计算和分布式计算的区别就是。****
作者图片,表情符号通过 twemoji
并行计算使用共享一个内存的多个处理器执行任务。这种共享内存是必要的,因为不同的进程正在一起处理同一项任务。并行计算系统受到可以连接到共享内存的处理器数量的限制。
另一方面,分布式计算使用多台自主计算机执行任务,没有单一的共享内存;计算机使用消息传递相互通信。这意味着一个工作单元被分成几个独立的任务,一个中央调度程序整理每个任务的结果,并将最终结果返回给用户。分布式计算系统理论上是无限可扩展的。
穿上和脱下喷气背包!
本文中介绍和解释的 7 个概念为您在分布式计算的广阔天地中找到立足点提供了必要的基础。现在是时候带上喷气背包,继续独自探索了。
Dask 教程对于任何认真探索分布式计算可能性的人来说都是一个很好的下一步。这是一个自定进度的教程,您可以在 1-2 小时内完成。
感谢您的阅读!在 LinkedIn 上关注我,了解定期的分布式计算更新和技巧。
请考虑成为支持写作社区的媒体成员:
**https://richardpelgrim.medium.com/membership **
机器学习对可再生能源行业的好处
使用逻辑回归、非平衡数据集和 l1 归一化的天气预报的个例研究
杰森·黑眼在 Unsplash 上的照片
我最近参加了一家咨询公司的面试,他们提出了一个迷人的场景:
假设这是你工作的第二天,你的主管打电话来请病假。他们要求你代替他们参加与能源部高级官员的会议。如果这些人问你你的机器学习背景如何帮助他们实现目标,你会怎么回答?
嗯,经过思考,我想出了一个我认为相当不错的答案,但在那之后的一周里,我对这个问题思考了很久。我个人相信使用机器学习作为理解现实世界现象的强大工具,而不是作为仅仅获得答案的黑匣子。但是这种观点如何影响现实世界的能源政策呢?当我在过去的一周里听播客和读文章时,我开始有了一些想法。
我在采访中的回答主要来自于最近听到的伍德·麦肯齐关于欧盟在最近的乌克兰危机面前的能源政策的播客。听听吧,很有意思。引起我共鸣的一点是,能源政策通常以气候变化争论为中心。这不是一件坏事。问题是气候变化总是一个长期的方法;我们总是在想 50 年后的事情,虽然现在做事情很紧迫,但末日即将来临的感觉太遥远,无法真正刺激严肃的行动。然而,最近的乌克兰危机凸显出能源政策不仅关系到长期气候变化,还关系到迫在眉睫的国家安全问题,特别是在欧盟。随着欧盟试图在短时间内摆脱对俄罗斯天然气的依赖,政策和技术必须快速实施。
这和机器学习有什么关系?我在最近的研究生经历中看到的最常见的一个说法是,机器学习是快。我与之互动的一位教授发表了一篇论文,内容是与经典、半经典和量子力学方法相比,用机器学习预测反应速率常数的计算效率。计算上的节省是巨大的。或者,考虑非常复杂的计算流体动力学(CFD)领域,这是飞机设计或天气预报中的一个重要领域。本文讲述了另一种创新方法,与标准 CFD 相比,神经网络用于提高流体流动模拟的计算时间。一个快速的谷歌学术搜索会产生无数迷人领域的论文,这些论文都展示了这个概念。
因此,在这个世界上,我们制定能源政策的时间突然变得更加紧迫,机器学习帮助我们快速获得答案。理想情况下,我们可以通过使用大量可用的原始数据和一个机器学习工程师团队,在不到一年的时间内得到答案,而不是雇佣一个博士团队来研究一个问题 5 年。
快速的结果很好,但是我们总是会遇到这样的问题:
我们真的明白为什么我们会得到这样的结果吗?
我与之互动的另一位教授有一个奇妙的方法,利用机器学习来告知现实世界的解决方案。在开发钙钛矿太阳能电池的过程中,他的团队和合作者执行了一些与水加速光氧化相关的复杂物理模型,这对于理解电池的寿命非常重要。但他们并没有就此止步。开发模型后,他们将结果作为特征输入到之前基于 ML 的退化模型,然后使用 LASSO 回归获得特征重要性。事实证明,该模型选择了他们基于物理学的模型的结果作为一个重要特征,验证了这项工作。由此得到的教训是什么?机器学习实际上是对现实世界理解的强大验证器。如果一个客观的计算算法说一个结果是重要的,没有政治或研究议程的复杂混淆,我们可以在我们的物理理解中更有信心地前进。
我考虑的第三个好处是机器学习原则能够跨多个学科使用。每当我参加机器学习会议或海报会议时,我都会对所涵盖的工程主题的广度和深度感到惊讶。然而,让我真正兴奋的是,我实际上能听懂大部分的演讲!即使我可能不是细胞生物学之类的专家,我也可以去参加关于使用机器学习的主题的演示,我可以确切地看到他们正在试图做什么,并理解为什么他们的结果如此重要。在过去的十年里,机器学习几乎渗透到了每个领域,这肯定是有原因的。
这在可再生能源领域尤为重要。可再生能源是一个广阔的领域,有许多技术需要无缝集成。在制造光伏电池板时,我们在材料科学方面有所顾虑;对电化学感兴趣,以了解性能最佳的电池;需要了解电气工程以设计逆变器和电池充电控制器。然后,我们必须考虑电网互联和能源政策以及其间的一切。现在,我绝不是说机器学习让我们成为所有这些领域的专家。事实上,我非常支持使用机器学习,同时总是涉足真实的物理世界。但是机器学习给我们的优势在于协作。一个领域的专家可以与另一个领域的专家进行讨论,尽管他们可能对另一个领域知之甚少,但仍然可以说共同的语言,甚至可以从对方那里获得如何更有效地完成自己工作的见解!这是一个相当大的协同效应。
我本想把它作为一个随机的想法样本来发表,但是后来意识到一个真实的例子会更有趣!所以我调出了一个数据集,这是我最近在一门数据可视化课程中接触到的。这是西雅图的天气数据,在 Kaggle 上向公众开放,在这里我们有温度和风速等指标的每日数据,我们希望预测天气的类型。这是一个非常简单的分类问题,在类似太阳预报的事情中会很有用。我没有在这里重复代码,而是创建了一个 Jupyter 漫游笔记本,并对我正在做的事情进行了降价和评论。可以在我的 Github 回购上找到。在展示这些优点的同时,我希望你能为自己的学习学到一些技巧!这是混淆矩阵中的结果。它们并不精彩,但我想为此使用一些特定的 ML 模型,这些模型可能不是处理这类问题的最佳模型,但请允许我展示本文中的一些想法。看看能不能得到更好的结果!
预测和实际标签的混淆矩阵。作者的情节
这个例子告诉我们什么?首先,我不是天气建模或预报方面的专家,但只要有一些数据和机器学习,我就可以花一个下午的时间得出一些有趣的结果。我不必花费成百上千个小时来开发 CFD 模型来确定天气。我也不需要在气候学和天气建模领域获得任何特定的培训(尽管也许我只是在西雅图地区生活过一段时间!).此外,我还能够深入了解一些最重要的参数。事实证明,最重要的晴雨预报是……(鼓声)……降雨量。大惊喜?不。但也许在其他应用程序中,你会发现一个惊喜。知道我们的直觉与模型告诉我们的一致总是好的!
以上是我的一些想法。总之,机器学习在帮助我们更好地应对能源挑战方面提供了三个明显的优势:
- 我们可以很快得到初步的结果,而不是花费数年在一些甚至可能不起作用的事情上。
- 我们可以利用机器学习来获得更多的见解,或者使用公正的机制来验证直觉。
- 我们可以促进具有共同语言和方法的领域专家之间的跨学科合作。
我很好奇你的经历。机器学习方法更快吗?它是否让你对现实世界有了更多的了解,而你可能已经错过了?你会如何回答这个问题?欢迎在 LinkedIn 上与我联系!
AWS Lambda 函数静态初始化的好处
如何有效地编写和优化无服务器函数
约尔格·安格利在 Unsplash 上拍摄的照片
无服务器并不是一个流行词。这是用词不当。没有服务器也能运行应用程序的想法听起来像是魔术。如何才能避免让服务器全天候运行的高昂成本呢?
事实是你不能。无服务器只不过是一个服务器。它会在 5 分钟不活动后自动关闭。当需要再次调用它时,它会自动重启服务器。您只需在一个文件中指定依赖项,无服务器功能将从那些已安装的依赖项中创建一个容器映像,然后在重新启动时部署该映像和那些依赖项。
这就是为什么无服务器是一个误称。顾名思义,当在后台使用服务器时,不使用任何服务器。
但是无服务器功能仍然比实际的服务器便宜吗?这取决于你的商业案例。如果您的逻辑是轻量级的,可以放在一个函数中,那么无服务器更便宜。如果你的逻辑很重,依赖于巨大的软件包/定制操作系统/大存储,那么一个服务器就比较便宜。
等等,为什么我们的功能必须是轻量级的?
这个想法是,如果你的函数很小,当你需要在几分钟不活动后访问这个函数时,自动重新安装所有的包和依赖项会更容易。不活动后重新安装软件包和设置该功能的容器所需的时间称为冷启动。
容器将运行并在 5 分钟后关闭。如果在这 5 分钟内调用该函数,它将比在容器不活动期间调用该函数更快地返回结果。容器运行后获得函数结果所需的时间称为热启动。
目标是尽量减少冷启动和热启动。从用户体验来说,调用一个函数,1 分钟后等待一个结果,会很烦。
好吧,但是如果在大小和逻辑上受到限制,那么无服务器有什么好处呢?
你肯定不想使用无服务器功能…
- 托管网站
- 高性能计算
- 托管大型机器学习模型(神经网络、基于树的模型)
- 灾难恢复
所有这些都可以在 EC2 上托管。机器学习模型可以托管在 AWS SageMaker 上。
您可以将无服务器功能用于…
- 自动化任务
- 触发器(处理上传到 AWS S3 的对象,发送到 AWS SQS 的事件)
- 实时过滤和转换数据
因此,无服务器函数非常适合于获取数据、转换数据并将结果发送到另一个端点进行处理。它甚至可以用于将转换后的数据发送到 AWS SageMaker 上托管的机器学习模型,并从该模型中获得预测。
在我之前的一个教程中,我设计了一个 lambda 函数,将上传到 S3 桶的 PDF 文件发送到一个托管 AWS 服务的端点:Textract。
以下是该功能的要点
下面是详细介绍教程的文章。你有空的时候可以去看看。
等一下。你提到无服务器应该是轻量级的。但是在你的 send_from_s3_to_textract 函数中,你使用的是 python 包 boto3。那不是超过 50 MB,会大幅度影响冷启动吗?
正确。为此函数初始化容器所需的时间会很慢。在处理多个请求时,有一个简单的技巧可以优化函数。
真的吗?这是什么?
我们在函数中初始化了两个不同的 boto3 客户端:一个 textract 客户端和一个 s3 客户端。让我们把它从函数中移出。参见下面的要点。
等等,你刚刚把第 15-17 行的 textract 和 s3 boto3 客户端移到了第 10 -12 行的函数之外?这如何优化功能?
初始化 boto3 客户端已经是一项耗时的任务。如果它在函数处理程序内部(在本例中,在send _ from _ S3 _ to _ text ract函数内部),那么客户端将在每次调用时被初始化。从冷启动的角度来看,这并不重要,因为函数和客户端都已初始化和安装。从热启动的角度来看,在容器运行时,每次调用函数都要初始化两个巨大的客户端,这是非常耗时的。
如果我们想改进,我们希望在函数处理程序之外初始化客户端。这样,该函数将在多次调用中重用客户端。虽然这不会影响冷启动,但它会大大减少热启动,因为它会获取在冷启动/环境初始化阶段已经实例化的两个客户端。
这个过程称为静态初始化。静态初始化是在函数处理程序中代码开始运行之前,在处理程序之外运行逻辑的过程。开发人员使用静态初始化来导入库和依赖项,初始化与其他服务的连接,并在多个 lambda 函数处理程序中重用变量。
好吧,但我如何优化冷启动?
这是另一个超出本文范围的话题。最简单的解释是确保提前创建 lambda 函数容器,远在按需调用它们之前。AWS Lambda 允许提供并发,它在可预测的时间初始化 Lambda 函数。
这对于适应突发流量和重大扩展事件非常有用。启用预配并发后,用户可以避免在 lambda 调用时遭遇冷启动。
现在您知道了如何编写和优化无服务器函数。如果有人大胆地宣称无服务器将永远取代服务器,我们是否应该一笑置之。
感谢阅读!如果你想阅读更多我的作品,查看我的目录。
如果你不是一个中等收入的会员,但对订阅《走向数据科学》感兴趣,只是为了阅读像这样的教程和文章,点击这里注册成为会员。注册这个链接意味着我可以通过向你推荐 Medium 来获得报酬。
参考文献:
https://lumigo.io/blog/provisioned-concurrency-the-end-of-cold-starts/ https://aws.amazon.com/blogs/compute/operating-lambda-performance-optimization-part-1/ https://aws.amazon.com/blogs/compute/operating-lambda-performance-optimization-part-2/
没有计算机科学学位的数据科学初学者的最佳编码技巧
Ashkan Forouzani 在 Unsplash 上的照片
如何编写生产就绪代码?
人们可以通过许多不同的方式过渡到数据科学领域。如果你没有技术背景,编程部分可能会显得令人望而生畏。我的背景不是计算机科学。在成为数据科学家之前,我是一名数学老师。在我从事数据科学的第一年,我有幸与一些 IT 重量级人物共事。以下是对我帮助最大的提示。
技巧 1:组织你的代码
编写一个运行完整流程的大型脚本似乎很诱人。或者就这样发生了:你从小处着手,然后你意识到你需要增加一些代码行。通过多次这样做,脚本变得越来越大。
这种方法有一些主要的缺点。首先,很难理解这个脚本做了什么,因为它做了很多事情。如果几个月后你回头看,很可能你不明白发生了什么。其次,您只能将脚本用于这个特定的过程。对于下一个项目,你需要重新开始。
解决方案很简单:将脚本分成函数和模块。每个函数应该只做一件事。通过将相关函数分组到一个模块(文件)中,您的代码变得易于理解和重用。您可以在下一个项目中从模块中导入函数或类。
什么时候开始组织都不晚!在软件工程中,你有一种叫做重构的实践,在这种实践中,你重构你的代码,而输出保持不变。
模块。图片作者。
技巧 2:不要做硬编码
硬编码是在源代码中存储配置或输入数据的实践。这可以是文件路径、URL、远程主机名或用户名。
为什么这是一种不好的做法?您的代码只能在特定的环境下工作,如果某些条件发生变化,您需要更改源代码。这意味着搜索你的代码,找到所有你放它的地方。
相反,您应该从配置文件、数据库、用户输入或其他外部来源获取配置或输入数据。这使得更新条件变得容易。每个环境都有自己的配置文件。为了从配置文件中提取数据,您可以使用一个配置解析器。
左边是配置文件,右边是从文件中提取数据的代码。图片作者。
提示#3:不同的错误是进度
开始的时候很沮丧。你需要习惯各种错误。您的代码无法工作,并且需要花费大量时间来找到所有错误消息的解决方案。但是,如果你的程序说不,不要失望,因为你修复的错误越多,你解决它们的能力就越强。
在我作为数据科学家的第一年,我和一个很好共事的人一起工作。他很高兴,因为错误信息与之前的不同,而新的错误让我很沮丧。这对我是一个教训,并帮助我继续前进。
提示 4:不要重新发明轮子
当你是一个初学者时,你必须意识到你不需要从头开始写每一个功能。假设你想用 Python 来抓取一个网站,如果没有 BeautifulSoup 或其他抓取包,你的工作会变得相当复杂。或者使用数据科学,你不需要实现机器学习模型背后的所有数学,因为 scikit-learn 是你的朋友。这些例子有些夸张,但也有很多小任务适用于此。
你想想或者需要的话,大概已经有了!
记住这一点,开始写你的程序,在你编码之前搜索!
照片由 Christian Wiediger 在 Unsplash 上拍摄
技巧 5:优化你的代码
在大学或课程中,表格数据集大部分时间都很小。您不必考虑代码优化,for 循环也不是问题。当你开始用杂乱的大数据解决业务问题时,它将是。您的代码可以在开发环境中使用小数据集很好地工作,但是在生产中您的过程可能会花费太长时间。
一个数据科学的例子:不要迭代数据帧行。而是使用apply
函数、np.where
或其他矢量化解决方案。
这里有一些让你开始的建议。
timeit 可能也很有用,它是一个 Python 库,提供了一种简单的方法来为小代码片段计时。图片作者。
技巧 6:处理异常并编写测试
生产就绪代码的一个重要部分是处理异常。它使你的代码健壮。如果你不处理异常,你的程序将会崩溃并以一种不受控制的方式退出。
Python 中处理异常的方式是使用try
、except
块。首先,您尝试执行一些代码行,如果代码失败,except 块将接管。可选地,您可以添加一个else
或finally
块。
如果你想了解更多,本教程将解释异常处理。
学习测试你的代码也是有帮助的。在开发过程中,您可以编写断言。使用断言,您可以进行健全性检查,以查看您的代码是否如预期的那样运行。如果x
等于1
,assert(x==1)
将返回True
。如果不是这样,assert
语句抛出一个断言错误。如果您创建一个测试文件,并添加带有断言的小函数,这些函数一起可以成为您的单元测试,并且您可以自动化您的测试。
技巧 7:学习如何正确调试你的代码
如果你使用print
语句来检查你的代码在做什么,你最好使用调试器。调试器为您提供了在任何地方暂停或冻结程序的工具。通过设置断点,您的代码暂停,您可以检查那一刻的状态。您可以逐句通过您的代码,您可以检查逻辑或变量值。
如果您使用 PyCharm 或 VS Code 之类的 IDE 来运行代码,您可能知道如何调试。python 的另一个选择是使用 Python 调试器。
断点设置在第 14 行(红点)。图片作者。
技巧 8:添加日志记录
通过日志记录,您可以跟踪软件运行时发生的事件。这是你程序的重要部分,因为它在开发过程中有帮助。在生产中,日志将使检测问题的原因变得更加容易。没有,你将很难找到它。
记录真的很容易。在 Python 中,你只需要写下面两行代码:
import logging
logging.basicConfig(filename='<filename>.log', level=logging.INFO)
在这种情况下,日志记录级别设置为 info,因此日志文件将包含所有 info、warning、error 和 critical 消息。如果将级别设置为错误,则只有错误和严重消息会写入日志文件。
当您想要记录一条信息消息时,键入logging.info('<message>')
,对于一条错误消息:logging.error('<message>')
就这么简单!
技巧 9:添加文档
是的,文档是个无聊的话题。写下你的代码做了什么需要时间,也许没有人会看它。另一方面,如果你想写专业的代码,你肯定应该写文档!你知道一个没有适当文档的流行包吗?
记录代码最简单的方法是在源代码中留下注释,尽管我不推荐这样做。更好的方法是使用像狮身人面像这样的软件包。遵循教程,你的文档马上就可以运行了!编写文档的另一个好处是,它将改进代码的组织方式,因为您自动地必须考虑它。
此图像中的文档字符串:
函数内的 Docstring。图片作者。
显示此文档:
上述功能的文档网页。图片作者。
最后的想法
你可能会发现学习 git 、面向对象编程、空间&时间复杂度、数据结构、反模式和算法很有用。理解这些主题肯定会提高你的编码技能,并且更容易与技术人员交流。尽管最终,数据科学工作最重要的部分是使用数据增加商业价值。如果你是一名数据科学家,不要害怕问一些有经验的 IT 人员他们将如何从技术上解决问题。这让您有更多时间关注数据和业务价值。
我希望这篇文章是有帮助的!享受编码!
别忘了 订阅 如果你想在我发表新文章时收到电子邮件。
当然,最好的数据是免费数据
原文:https://towardsdatascience.com/the-best-data-is-free-data-of-course-b88230b5b47f
使用 Socrata 开放数据 API 和 sodapy 包访问大量的开放数据
介绍
数据科学项目常用的数据仓库是 Kaggle 和 UCI 机器学习仓库。然而,那里可用的许多数据集是合成的,并不代表真实世界。
联邦、州和地方政府提供了大量真实世界的开放数据,您可以也应该在您的项目中使用这些数据。在这篇文章中,我将分享获得访问权限的简单步骤。你所需要的只是 Socrata 开放数据 API 和 sodapy 包。
出于解释的目的,我们将使用来自旧金山开放数据仓库 DataSF 的空中交通乘客统计数据集。
1.获取 Socrata 应用程序令牌
你的第一步是在https://data.sfgov.org/login注册一个免费账户,获得一个应用令牌。获得凭据后,单击创建新的应用程序令牌并完成必填字段。
您将被要求输入应用程序令牌的名称和描述,任何唯一的名称都可以。您的应用程序令牌会自动生成并显示在屏幕上。
为其他开放数据仓库获取应用令牌的过程是相同的。例如,可以在以下地址找到 NYC open data:https://data.cityofnewyork.us/login
2.安装 sodapy
下一步是用pip install sodapy
安装 sodapy 包
3.建立联系
现在,我们将跳转到 Python IDE 来建立与 Socrata 开放数据 API 的连接。我用过 Jupyter 实验室:
第一步是导入 sodapy 包。接下来,我们必须定义我们的数据源并提供我们的应用程序令牌:
- DATA_LINK: 这将根据您试图访问的开放数据存储库而有所不同,并且可以从 URL 获得。对于 dataSF,它是 data.sfgov.org,而对于纽约开放数据,它是 data.cityofnewyork.us
- DATA_ID: 这是 API 端点,一个特定于您试图访问的数据集的指示符,也可以从 URL:
- APP_TOKEN: 这是您在前面的步骤中获得的令牌。在上面的代码中,我输入了“redacted ”,以保持我自己的应用程序令牌私有。
最后,我们通过实例化一个 Socrata 对象并将其命名为 client 来建立连接。我们传递数据源和应用程序令牌。
4.请求数据
用 Socrata 开放数据 API 请求数据只需一行代码:
我们在 Socrata 对象上调用 get()方法,客户端。我们传递之前定义的 DATA_ID。默认情况下,将请求数据集中的前 1,000 条记录。我们将很快了解如何在每个 API 调用中请求更多的记录。
值得注意的是,当重复完全相同的请求时,Socrata API 将而不是返回相同的记录。为了保证一致的响应, order 参数应该与值':id '一起使用,它对数据集进行排序。
5.将数据放入数据帧
默认情况下,请求的数据以 JSON 格式返回:
[{'activity_period': '200507',
'operating_airline': 'ATA Airlines',
'operating_airline_iata_code': 'TZ',
'published_airline': 'ATA Airlines',
'published_airline_iata_code': 'TZ',
'geo_summary': 'Domestic',
'geo_region': 'US',
'activity_type_code': 'Deplaned',
'price_category_code': 'Low Fare',
'terminal': 'Terminal 1',
'boarding_area': 'B',
'passenger_count': '27271'},
{'activity_period': '200507',
'operating_airline': 'ATA Airlines',
'operating_airline_iata_code': 'TZ',
'published_airline': 'ATA Airlines',
'published_airline_iata_code': 'TZ',
'geo_summary': 'Domestic',
'geo_region': 'US',
'activity_type_code': 'Enplaned',
'price_category_code': 'Low Fare',
'terminal': 'Terminal 1',
'boarding_area': 'B',
'passenger_count': '29131'}]
幸运的是,将 JSON 数据放入 pandas 数据框架非常容易:
数据帧的前五条记录。
至此,您已经能够使用 sodapy 将打开的数据导入到 DataFrame 中进行分析。然而,我们必须涵盖一些高级主题,以便您可以充分利用 Socrata 开放数据 API——通过数据集分页和高级过滤。
6.浏览数据集
开放数据数据集可能非常大,您可能需要在多个请求中翻阅数据集。下面的代码请求数据集的记录计数,并计算页面大小为 1,000 条记录时有多少页:
:: Number of Records Available: 46,670
:: Number of Pages: 47
下面的代码段根据选定的 page_size 和计算的 num_pages 在数据集中分页:
- limit: 指定请求的记录数(可选)。
- offset: 指定我们应该在数据集中的什么地方开始我们的请求,在这个例子中是在第一个可用的记录处(可选)。
- order=':id': 指定数据集应该排序
查询结果的顺序不是隐式排序的,所以如果您正在分页,请确保您提供了一个$order
子句,或者至少使用记录 ID: $order=:id
。这将保证在浏览数据集时结果的顺序是稳定的。
7.高级过滤
除了请求完整的数据集,还可以通过在 get 请求中添加 where 子句来请求过滤后的数据集。以下代码段请求 2005 年 7 月的所有记录:
结束语
从本文中,您了解了如何使用 Socrata 开放数据 API 和 sodapy 包访问开放数据数据集。纽约和旧金山只是众多免费数据库中的两个——我鼓励您探索其他开放的数据库。
如果你喜欢阅读这样的故事,并想支持我成为一名作家,可以考虑注册成为一名媒体会员。每月 5 美元,你可以无限制地阅读媒体上的故事。如果你用我的链接注册,我会赚一小笔佣金。
也请查看我的系列文章通过示例学习 Python 数据分析:
以及我最近发表的其他文章:
学习 Tableau 的最佳免费资源
原文:https://towardsdatascience.com/the-best-free-resources-for-learning-tableau-skills-5f0e5bfaa87e
不用花一分钱就能最大限度地学习
作者的工作空间。
我认为 Tableau 是可用的最重要的数据可视化工具之一。学习 Tableau 的基础知识并不难,尤其是如果你对电子表格和数据透视表有很强的理解。但是,从基础到精通 Tableau 需要花费大量的时间和精力。幸运的是,有大量的资源支持你的学习。这篇文章是一组精选的在线资源,可以提升你的 Tableau 技能。这个列表并不全面,因为我想避免给新学员过多的资源。请注意,我的资源列表不是按照重要性排序的。
油管(国外视频网站)
危地马拉安提瓜一栋建筑的窗户和门。图片由作者提供。
Tim Ngwena 是我最喜欢的内容创作者之一。他定期提供内容更新,他的教程质量很高,很吸引人。我欣赏对 Tableau 特定问题的深入探讨和清晰解释。我发现 Tim 关于细节层次表达的视频做得非常好。
sqlbelle : Donabel Santos 有很多精彩的模块,有很多与新学员高度相关的内容。我经常向我的学生推荐她的频道,尤其是关于了解 Tableau 工作空间以及尺寸与度量之间差异的视频。
安迪·克里贝尔:安迪是 Tableau 领域最有影响力的教育家之一。我看过无数的视频,这些视频提供了各种类型图表的深度潜水。我特别喜欢安迪对视觉设计的关注。与蒂姆和多纳贝尔的视频不同,安迪的作品往往是未经编辑和无脚本的,最著名的是看我的,即视频。但是,这是他的教育方法的资产,因为你可以理解他的思维过程,尤其是在调试问题的时候。
Tableau 软件 : Tableau 维护这个通道。我推荐这个频道,但有几个注意事项。此频道的内容不是专门为学员创建的。因此,你会花更多的时间来整理视频和播放列表。但是,该频道包含许多内容,以跟上 Tableau 世界的活动,包括会议录音。Iron Viz 的录音绝对值得一看。
在线 Tableau 支持
危地马拉的街头小吃摊贩。图片由作者提供。
这些资源提供了从更广泛的 Tableau 用户社区获得免费支持的绝佳方式。请记住,提供支持的人给你他们的时间,所以要注意你如何参与这个社区。在发表问题之前,确保你首先努力自己解决问题。熟悉提问的 StackOverflow 指南。虽然这是特定于 StackOverflow 的,但这些已经成为在线社区中的最佳实践。
Discord: Discord 是一个即时通讯系统。Tableau 用户社区已经建立了一个“服务器”来讨论 Tableau 问题并提供实时支持。你必须先用 Discord 设置一个账号,搜索 Tableau 服务器才能加入。由于支持是实时提供的,因此该资源可以帮助您高效地解决问题。
Tableau 支持社区 : Tableau 使用公告板格式维护这个在线社区。如果你发布了一个高质量的问题,你几乎保证会收到一个解决方案。尝试发布 Tableau 打包工作簿(*。twbx)与简化的数据集。
Reddit :如果你是Reddit,加入 Tableau 子 Reddit,在线社区发布关于 Tableau 的问题、新闻和资源。
博客和网站
危地马拉城的鸡肉巴士。图片由作者提供。
Tableau Viz of the Day :这个网站由 Tableau 维护,是一个很好的灵感来源,每个工作日都会发布一个新的 Tableau 可视化。你会发现不同主题的设计范例。
周三锻炼:周三锻炼对技能培养很有帮助。每周都会发布一个新的挑战,以重新创建数据驱动的可视化。解决方案发布在 Tableau Public 和 Twitter 的网站和社区上。
周一改造:周一改造也是技能培养的好时机。每周都会有一个可视化的图片和原始数据的链接一起发布。然后,社区成员重新制作他们的 viz 并发布到 Twitter 上。周三的训练侧重于画面的技术方面,而周一的改造侧重于设计方面。不幸的是,这个网站在 2022 年不再运营,但该网站仍然有 2018 年至 2021 年的翻拍、解决方案和视频的完整收藏。这个网站上有大量的学习资料。
自 2015 年以来,凯文和肯·弗雷尔拉格一直在制作高质量的 Tableau 内容。他们的内容倾向于关注 Tableau 更高级的技术特性,这使得这个网站成为提升你技能的绝佳选择。我印象深刻的是他们将设计与先进的技术问题相结合。
文档和其他资源
内蒙古戈壁沙漠。图片由作者提供。
Tableau 帮助:每个 Tableau 用户都需要仔细阅读 Tableau 文档。这些内容可能不像本文中包含的其他资源那样令人兴奋或有趣。但是,排除它将是我的失职。我鼓励新学员定期访问特定于 Tableau 函数的文章集。这样做将有助于你接触 Tableau 的语言,这对你的长期技能发展至关重要。
Tableau Discover:当您打开 Tableau Desktop 时,请熟悉页面右侧的 Discover 页面。在这里,您可以找到免费培训指南和其他资源的内置链接。
外卖食品
请注意,在 Tableau 中完成一门课程或培训会让你获得使用 Tableau 成功创建有意义和有洞察力的可视化的所有技能和知识。除了将你的技能应用到现实世界的问题中(而不是简单地完成学术练习),你还需要不断接触不同的概念和不同的解释。这里提供的免费 Tableau 资源集合可以帮助满足这一需求。
sklearn 的最佳进口产品
原文:https://towardsdatascience.com/the-best-imports-from-sklearn-b5b9c4f2c0e3
了解从这个神奇的 Python 库中导入什么以及何时导入
sci kit-学习
Science Kit Learn,或者对入门者来说简称为sklearn
,可能是 Python 中建模数据的主要软件包。
Sklearn 是 2007 年由 David Cournapeau 开发的。历史告诉我们,它始于谷歌的一个夏季项目。从那以后,发生了很多变化,信不信由你,1.0 版本直到 2021 年 12 月才发布!当然,早在那个日期之前,它就已经在各地提供了巨大的成果。
总之, sklearn 是一个库,它不仅处理非监督学习(如聚类)和监督学习(如回归和分类),还处理围绕数据科学项目的所有其他组件。使用 sklearn,我们可以访问预处理工具,如缩放、归一化。我们可以看到模型选择工具,如 k-fold,网格搜索,交叉验证。当然,有创建模型的算法,也有检查指标的工具,比如混淆矩阵。
在这篇文章中,我想与您分享的是在您使用 Scikit Learn 时要导入的一些模块,因此您可以在构建模型时使用这些内容作为快速参考。让我们看看他们。
预处理数据
建模数据不仅仅是加载 sklearn 并通过算法运行数据。它需要更多的时间来处理数据,因此您可以为模型提供良好的输入。为此,您可以使用以下模块。
最小最大缩放器
此工具将根据变量的最大值和最小值对数据进行归一化。最大值变为 1,最小值为 0,两者之间的所有值都是最大值的百分比。
from sklearn.preprocessing import [**MinMaxScaler**](https://scikit-learn.org/stable/modules/generated/sklearn.preprocessing.MinMaxScaler.html#sklearn.preprocessing.MinMaxScaler)
标准缩放器
Normalize 会将变量转换为均值= 0,标准差= 1。但是,它不会改变数据的形状,这意味着它不会将数据转换为正态分布。
from sklearn.preprocessing import [S](https://scikit-learn.org/stable/modules/generated/sklearn.preprocessing.StandardScaler.html#sklearn.preprocessing.StandardScaler)[tandardScaler](https://scikit-learn.org/stable/modules/generated/sklearn.preprocessing.StandardScaler.html#sklearn.preprocessing.StandardScaler)
估算者
当缺失值过多,并且我们希望使用某种插补技术来估计当前为 NA 的值时,使用插补器。其主要模块如下。
from sklearn.impute import [**SimpleImputer**](https://scikit-learn.org/stable/modules/generated/sklearn.impute.SimpleImputer.html#sklearn.impute.SimpleImputer)from sklearn.impute import [**KNNImputer**](https://scikit-learn.org/stable/modules/generated/sklearn.impute.KNNImputer.html#sklearn.impute.KNNImputer)
from sklearn.impute import [**IterativeImputer**](https://scikit-learn.org/stable/modules/generated/sklearn.impute.IterativeImputer.html#sklearn.impute.IterativeImputer)
特征选择
如果挑战是为一个模型寻找最好的特征,有许多可能性。Scikit Learn 将提供这些以及更多。
from sklearn.feature_selection import [**SelectKBest**](https://scikit-learn.org/stable/modules/generated/sklearn.feature_selection.SelectKBest.html#sklearn.feature_selection.SelectKBest), [**f_classif**](https://scikit-learn.org/stable/modules/generated/sklearn.feature_selection.f_classif.html#sklearn.feature_selection.f_classif), [**r_regression**](https://scikit-learn.org/stable/modules/generated/sklearn.feature_selection.r_regression.html#sklearn.feature_selection.r_regression)from sklearn.feature_selection import [**RFE**](https://scikit-learn.org/stable/modules/generated/sklearn.feature_selection.RFE.html#sklearn.feature_selection.RFE)
总而言之:
【In】数字;[Out]数值:
SelectKBest(score_func=f_regression, k=number best attributes)
SelectKBest(score_func=mutual_info_regression, k=number best attributes)
【In】数字;[Out]分类:
SelectKBest(score_func=f_classif, k=number best attributes)
【直言不讳】;[Out]分类:
SelectKBest(score_func=chi2, k=number best attributes)
SelectKBest(score_func=mutual_info_classif, k=number best attributes)
型号选择
在经过预处理和特征选择之后,就到了选择模型的时候了。
列车测试分离
当然,我们需要将数据分为解释变量(X)和被解释变量(y)。为此,我们使用训练测试分割。
from sklearn.model_selection import **train_test_split**
交叉验证和折叠
有许多方法可以交叉验证数据。最常见的是使用 K-fold,将数据分成 K 个部分,每个部分都用作训练集和测试集。例如,如果我们将一个集合折叠成 3 个,则第 1 部分和第 2 部分是训练,第 3 部分是测试。然后下一次迭代使用 1 和 3 作为训练,使用 2 作为测试。最后,2 和 3 被训练,1 被测试。
from sklearn.model_selection import [**cross_validate**](https://scikit-learn.org/stable/modules/generated/sklearn.model_selection.cross_validate.html#sklearn.model_selection.cross_validate), [**cross_val_score**](https://scikit-learn.org/stable/modules/generated/sklearn.model_selection.cross_val_score.html#sklearn.model_selection.cross_val_score)
from sklearn.model_selection import [**KFold**](https://scikit-learn.org/stable/modules/generated/sklearn.model_selection.KFold.html#sklearn.model_selection.KFold)
在这个链接中,你可以看到更多的选项和文档,比如省去一个、分层折叠、洗牌拆分等等。
模型调整
为了调整模型,sklearn 将为我们提供这些令人惊叹的选项,即网格搜索或随机搜索。使用这种方法,可以测试模型参数的多种组合,将最佳结果作为继续预测的最佳估计值。
from sklearn.model_selection import[**GridSearchCV**](https://scikit-learn.org/stable/modules/generated/sklearn.model_selection.GridSearchCV.html#sklearn.model_selection.GridSearchCV)from sklearn.model_selection import [**RandomizedSearchCV**](https://scikit-learn.org/stable/modules/generated/sklearn.model_selection.RandomizedSearchCV.html#sklearn.model_selection.RandomizedSearchCV)
评估者
估计量是可供我们使用的算法。Scikit learn 有很多这样的例子。
无监督:聚类
无监督学习是指我们不为预测提供标签。因此,该算法将在没有监督的情况下寻找模式并对数据点进行分类。意思是,没有“正确或错误的答案”。
# Clustering
from sklearn.cluster import [**KMeans**](https://scikit-learn.org/stable/modules/generated/sklearn.cluster.KMeans.html#sklearn.cluster.KMeans)from sklearn.cluster import [**DBSCAN**](https://scikit-learn.org/stable/modules/generated/sklearn.cluster.DBSCAN.html#sklearn.cluster.DBSCAN)from sklearn.mixture import [**GaussianMixture**](https://scikit-learn.org/stable/modules/generated/sklearn.mixture.GaussianMixture.html#sklearn.mixture.GaussianMixture)
分类
分类模型将理解来自数据集的模式以及什么是相关联的标签或组。然后,它可以根据这些模式对新数据进行分类。最常用的是集合模型,如随机森林或梯度推进。还有一些更简单的,像决策树,逻辑回归和 K 近邻。
from sklearn.ensemble import [**RandomForestClassifier**](https://scikit-learn.org/stable/modules/generated/sklearn.ensemble.RandomForestClassifier.html#sklearn.ensemble.RandomForestClassifier)from sklearn.ensemble import [**GradientBoostingClassifier**](https://scikit-learn.org/stable/modules/generated/sklearn.ensemble.GradientBoostingClassifier.html#sklearn.ensemble.GradientBoostingClassifier)
from sklearn.tree import [**DecisionTreeClassifier**](https://scikit-learn.org/stable/modules/generated/sklearn.tree.DecisionTreeClassifier.html#sklearn.tree.DecisionTreeClassifier)
from sklearn.neighbors import [**KNeighborsClassifier**](https://scikit-learn.org/stable/modules/generated/sklearn.neighbors.KNeighborsClassifier.html#sklearn.neighbors.KNeighborsClassifier)from sklearn.linear_model import[**LogisticRegression**](https://scikit-learn.org/stable/modules/generated/sklearn.linear_model.LogisticRegression.html#sklearn.linear_model.LogisticRegression)
回归
回归问题是那些需要返回一个数字作为输出的问题。回归解决的经典问题是汽车和房价。在这种情况下,最常用的模型是线性模型。有一些正则化回归的选项,如山脊或套索。对于非线性关系,也可以使用基于树的模型。
from sklearn.linear_model import [**LinearRegression**](https://scikit-learn.org/stable/modules/generated/sklearn.linear_model.LinearRegression.html#sklearn.linear_model.LinearRegression)
from sklearn.linear_model import [**Ridge**](https://scikit-learn.org/stable/modules/generated/sklearn.linear_model.Ridge.html#sklearn.linear_model.Ridge)from sklearn.ensemble import [**RandomForestRegressor**](https://scikit-learn.org/stable/modules/generated/sklearn.ensemble.RandomForestRegressor.html#sklearn.ensemble.RandomForestRegressor)from sklearn.ensemble import [**GradientBoostingRegressor**](https://scikit-learn.org/stable/modules/generated/sklearn.ensemble.GradientBoostingRegressor.html#sklearn.ensemble.GradientBoostingRegressor)
韵律学
最后,我们可以使用 sklearn 的度量组件来评估模型。接下来看看最常用的。
分类指标
from sklearn.metrics import [**f1_score**](https://scikit-learn.org/stable/modules/generated/sklearn.metrics.f1_score.html#sklearn.metrics.f1_score)
from sklearn.metrics import [**confusion_matrix**](https://scikit-learn.org/stable/modules/generated/sklearn.metrics.confusion_matrix.html#sklearn.metrics.confusion_matrix)
from sklearn.metrics import [**accuracy_score**](https://scikit-learn.org/stable/modules/generated/sklearn.metrics.accuracy_score.html#sklearn.metrics.accuracy_score)
from sklearn.metrics import [**auc**](https://scikit-learn.org/stable/modules/generated/sklearn.metrics.auc.html#sklearn.metrics.auc)
回归度量
from sklearn.metrics import [**mean_squared_error**](https://scikit-learn.org/stable/modules/generated/sklearn.metrics.mean_squared_error.html#sklearn.metrics.mean_squared_error)
from sklearn.metrics import [**mean_absolute_error**](https://scikit-learn.org/stable/modules/generated/sklearn.metrics.mean_absolute_error.html#sklearn.metrics.mean_absolute_error)
from sklearn.metrics import [**r2_score**](https://scikit-learn.org/stable/modules/generated/sklearn.metrics.r2_score.html#sklearn.metrics.r2_score)
在你走之前
Scikit learn 是数据科学家的得力助手。在他们的文档中,您可以探索和学习更多的东西。
在这里,我们只介绍了一些常用于数据科学的导入,但是,如果您访问他们的页面,您可以看到更多。
他们的文档的优点是非常清晰和有条理。此外,很多时候它给你一个关于算法或函数所解决的问题的深度知识。
如果你喜欢这个内容,请关注我的博客。
http://gustavorsantos.medium.com/
参考
https://scikit-learn.org/stable/modules/classes.html# https://en.wikipedia.org/wiki/Scikit-learn
自预浸泡以来,浓缩咖啡的最佳改进:蒸汽预浸泡
咖啡数据科学
利用杠杆机器的提示进行改进
在之前的中,我比较了 Kim Express 和体面的 Espresso (DE)咖啡机,发现 Kim Express 在味道和咖啡提取方面更好。随着我对原因的深入挖掘,我发现两个主要原因:水温和蒸汽预注入(PI)。
提高水温只能缩小差距,所以我调查了咖啡喷嚏,原来是蒸汽预浸。我想在 DE 中复制这一点,这是一个通向更好咖啡的有趣旅程。
轮廓开发
蒸汽预注入发生在 Kim Express 中,因为水箱中的水温超过 100 摄氏度。通常,我的水在 116C 到 120C 之间,这意味着当水开始进入腔室时,它首先变成蒸汽。蒸汽先于水穿过冰球。
所有图片由作者提供
起始轮廓
我从一个我已经工作了几个月的档案开始。它包括快速预浸泡,一旦过滤器被咖啡覆盖,就手动结束预浸泡。随后暂停,直到手动输入开始进入压力脉冲。
我开始使用 0.5 毫升/秒的流量限制添加 10 秒蒸汽 PI。这对唐努汀产生了直接影响。
我尝试了更长和更短的蒸汽 PI。最佳流速为 0.2 毫升/秒,因为它允许刚好足够的水进入圆盘。0.1 毫升/秒太慢,0.4 毫升/秒太快。
我还查看了 steam PI 的时间长度。理想状态是 5 到 20 秒。这取决于你的锅炉的温度。DE 中的测量值肯定会测量到更高的圆盘温度,但这是在顶部测量的。我还注意到水温没有我开始时下降得快。
我已经根据我正在煮的咖啡修改了蒸汽管道的长度。我继续测试这个变量,以便更好地理解如何使用它。
设备/技术
咖啡:家庭烘焙咖啡,中杯(第一口+ 1 分钟)
预灌注:长,约 25 秒
输液:压力脉动
过滤篮 : 7g/20g VST
其他设备: Atago TDS 计、 Acaia Pyxis 秤
绩效指标
我使用了两组指标来评估技术之间的差异:最终得分和咖啡萃取。
最终得分 是评分卡上 7 个指标(尖锐、浓郁、糖浆、甜味、酸味、苦味和回味)的平均值。当然,这些分数是主观的,但它们符合我的口味,帮助我提高了我的拍摄水平。分数有一些变化。我的目标是保持每个指标的一致性,但有时粒度很难确定。
使用折射仪测量总溶解固体量(TDS),该数字结合咖啡的输出重量和输入重量用于确定提取到杯中的咖啡的百分比,称为提取率(EY)** 。**
抽样资料
我看了一些样本数据,因为我还没有准备好拍摄一组配对照片。我想更好地理解这项技术。所以我看了两个样本集,它们显示了我的总体经历。
让我们从我 2022 年 5 月 4 日烤的有和没有蒸汽 PI 的例子开始。蒸汽码头似乎有一个稍微深一些的颜色。
看两次烘烤,每次烘烤三次,我们可以看看 Kim Express 的性能。蒸汽 PI 对两种烘焙都更好,但 5/4/2022 烘焙能够匹配 EY/TDS 上的 Kim,并在味道上击败它。
****
在一些蒸汽预注入后,射击时间更符合 Kim。
随着我对这项技术的进一步试验,这只是一个很小的数据分享。我想知道,如果 E61 型机器在淋浴屏幕上方有一些空间,它是否可以更好地模拟杠杆机器,允许在室内装满水时进行蒸汽预注入。我的目标是将来做一个更好的并列比较。
如果你愿意,可以在推特、 YouTube 和 Instagram 上关注我,我会在那里发布不同机器上的浓缩咖啡照片和浓缩咖啡相关的视频。你也可以在 LinkedIn 上找到我。也可以关注我在中和订阅。
我的进一步阅读:
工作和学校故事集
我经历过的最好的面试从来都不是编码挑战
原文:https://towardsdatascience.com/the-best-interviews-ive-had-were-never-coding-challenges-95ec0cde765b
你可以尝试不同风格的面试
照片由 Maranda Vandergriff 在 Unsplash 上拍摄
面试可能是一次充满压力的经历。2018 年硕士毕业至今,面试了上百个职位。这些职位包括从数据科学家到分析师、解决方案架构师等等。其中,一些独特的采访让我印象深刻,有好有坏。面试的时候,你不仅仅是给一家公司你自己的第一印象,你是在获得他们和团队的第一印象。有了这些,这里有三种我认为有益的面试风格,还有一些,没那么有益。
白板挑战
当我刚毕业时,我参加了波士顿一家公司的数据分析师面试。最终,我没有接受这份工作,但我喜欢这种面试方式。当时,这次采访是在一个会议室里进行的。许多团队成员围坐在桌子旁和我交谈。我们讨论了你期望得到的一般性问题,比如你的背景、经历和学校教育。但我们也做了一个令人兴奋的数据清理挑战。他们打开了一个 Excel 表格,并在大屏幕上分享,而不是代码。我把这个挑战和其他白板会议归为一类。屏幕上有一个例子,如下所示:
作者创建的示例表
当看到这样的例子时,他们说,“清理数据”。预期是申请人将逐列、逐行地浏览数据。在此过程中,申请人需要与面试官讨论他们所看到的情况以及他们将如何处理每个案例。他们想知道你的选择背后的解释。
An example of some of the items you may pick out from above include:
1\. The column headers are different cases; some have spaces, some do not, and one name is unclear.
2\. First and last names are handled differently based on the case, and one person is missing a last name.
3\. Dates are in different formats.
4\. States have abbreviations, full spellings, and misspellings.
5\. The numeric column has a variation of ints longs, and one number has a comma.
6\. Alice appears twice and maybe the same person. Is the duplication needed?
我喜欢这个挑战,因为它让你思考如何解决这样的问题。你可以谈谈你的推理,和面试官谈谈你的决定。
我见过的另一种形式的白板会议包括实际的白板。在一次面试中,有人递给我一支马克笔,让我走一遍机器人地图系统的架构。在此期间,我需要展示脑海中出现的架构,并完成我的决策。当有人提出问题时,我会重新考虑设计并做出适当的修改。在很大程度上,我喜欢白板挑战,因为它们让受访者在纸上浏览想法。
我唯一一次对这种具有挑战性的风格有异议是在我被问到如何设计不同的解决方案的时候。比如一个问题给了一个数据集,要求对信息进行排序。我被告知“用你想要的任何语言起草解决方案。”看着他们提出的问题和数据,我用白板演示了一个地图缩减示例,并讨论了 Spark 如何扩展解决方案。他们没有讨论这个问题并进行更深入的研究,而是开始坚持认为这只能在 SQL 中完成。那时,他们希望每个问题都是 SQL 语言,并且只问针对该语言的问题。对我来说,这没有意义。那么,为什么指定您的解决方案可以用任何语言或格式设计,然后再推动一种特定的语言呢?相反,他们应该一开始就明确这种区别。
研究报告
我喜欢的下一种面试是陈述。面试前,我被要求准备一套 20 分钟的幻灯片。这副牌包括四个部分。前两个介绍了我以及我为什么对这个行业感兴趣。接下来,我将详细介绍我在数据科学领域所做的研究或项目。最后,我讲述了如何处理不明确的需求并形成数据解决方案。
我喜欢这种面试形式,因为它让我展示了我是谁以及我所做的工作。我利用演讲的研究部分浏览了不同会议上的所有科学演讲。在这些讨论中,我们浏览了海报,每个受访者都可以提出与工作相关的问题。最后,我们深入到不同的方面,展示了我所擅长的。
这种形式非常类似于在会议上展示海报。面试小组的任何人都可以过来问你问题。唯一的区别是这些人是面试官,他们根据看到的内容轮流提问。另一个原因是,我觉得这种类型的面试很有趣,因为压力较小。我知道我要展示的内容,以及围绕这项工作的问题。没有我预料不到的非常随机的问题。
在接受一个角色后,我在团队里呆了几个月,然后面试其他人加入我们。当我开始参与采访时,我们一直保持着我描述的那种形式。这是一个很好的方式来和人们讨论他们做得最好的是什么,那是他们的工作和研究。我记得曾经采访过一个人,关于他们所做的医学研究,有演示文稿是很棒的,因为它们可以包含图像。这些图片完美地配合了对话,因为我们可以看到他们描述的问题类型,并询问与我们在这些图片中看到或没有看到的内容相关的问题。
如果我不得不再次做这些采访,我会使用这种形式。然而,数据科学非常适合可视化,如果你能在采访中分享它们并讨论你的发现,为什么不呢!
一段对话
简单来说,一段对话。我遇到的一些最好的采访不是深入技术问题并找出某人到底研究了什么,而是关于这个领域、工作和生活的一般对话。在进入数据领域之前,我在 DevOps 中从事服务器方面的工作。我对那个全职职位的第一次面试是与我当时的经理的一次谈话,内容是他在团队中的工作以及我如何帮助他的工作。
几年后,我最近的一次采访是与一位资深数据科学家的对话。在这次谈话中,我们简短地讨论了他试图在他的项目中做的工作。这项工作包括自然语言处理和文本挖掘。有了这些信息,我们花了一个小时谈论我的工作有多少相似之处,然后我们深入探讨了如何一起解决一个具体的问题。和他谈过之后,我和招聘经理谈了谈。这时,他给了我一个他正在处理的客户的问题,我们讨论了如何围绕这个问题起草一个解决方案。最后,我们讨论了在您可能没有所有数据的情况下,您将如何处理此类解决方案的业务,以及您会提出什么类型的问题。
我发现这种类型的对话比技术问题或编码挑战的速度测试更有益,因为我可以和别人谈论我的工作和激情。我与之交谈的另一位经理在电话中花了两个多小时谈论公司、我们各自的职业生涯以及数据科学界的现状。当我们开始讨论一个特定的话题时,我们会深入探讨它的复杂性。因此,我们没有处于紧张的状态,而是就我的技能如何应用到他们的工作中进行了一次很好的交谈。我喜欢在采访中深入探讨的一个特殊领域是,数据科学领域的人员如何与业务和工程领域的不同人员互动。有效的沟通往往是一个伟大的话题,可以让许多人谈论。
最后的想法
不是所有的面试都需要编码挑战和速度问题来得到最快最好的答案。有些面试可以采取不同的形式,但仍能提供价值。例如:
- 白板会议是让人们参与到他们正在做的事情中并集体讨论问题的好方法。
- 深入研究某人的研究或过去的项目的演示可能很有见地。你可以看到某人专注于什么工作,并可以有针对性地询问该工作如何适用于你的空缺职位。
- 一段对话。简而言之,有时候,仅仅和某人进行日常对话就能收集到你需要的洞察力。当面对一个似乎非常渴望交谈的人时,这可能是一个有用的策略。
如果说我从这些采访中学到了什么,无论这个人的研究或背景如何,每个人都值得被倾听和尊重。你可以形成自己的观点,不想让某个人加入你的团队,而不会显得粗鲁或让他们感觉不好。
你经历过的最好和最差的面试形式是什么?你会再次使用它们吗?
感谢阅读!我希望你喜欢阅读我所学到的东西,并对关注更多,订阅我的通讯。
最佳学习率时间表
原文:https://towardsdatascience.com/the-best-learning-rate-schedules-6b7b9fb72565
设置学习率的实用而强大的技巧
(由 Unsplash 上的 Element5 数码拍摄)
任何训练过神经网络的人都知道,在训练期间适当地设置学习速率是让神经网络表现良好的一个关键方面。此外,学习率通常根据一些学习率时间表沿着训练轨迹变化。这个时间表的选择对培训质量也有很大的影响。
大多数从业者在培训期间采用一些广泛使用的学习率计划策略;例如阶跃衰减或余弦退火。这些时间表中的许多都是为特定的基准而策划的,在经过多年的研究后,它们是根据经验确定的,以最大限度地提高测试的准确性。但是,这些策略往往无法推广到其他实验环境,这就提出了一个重要的问题:对于训练神经网络来说,最一致、最有用的学习速率表是什么?
在这个概述中,我们将着眼于最近对各种学习速率表的研究,这些学习速率表可用于训练神经网络。这样的研究发现了许多提高学习速度的策略,这些策略既高效又易于使用;例如循环或三角学习率计划。通过研究这些方法,我们将得出几个实用的要点,提供可以立即应用于改善神经网络训练的简单技巧。
为了补充这个概述,我实现了主要的学习率计划,我们将在这里的找到的库内探索这些计划。这些代码示例有些简单,但它们足以轻松实现本概述中讨论的任何学习率计划。
各种类型的学习率计划的图解(由作者创建)
神经网络训练和学习率
在监督学习设置中,神经网络训练的目标是生成一个神经网络,在给定一些数据作为输入的情况下,该神经网络可以预测与该数据相关联的基本事实标签。这方面的一个例子是训练一个神经网络,根据一个大的猫和狗的标记图像数据集,正确地预测一个图像是包含一只猫还是一只狗。
训练神经网络的组件(由作者创建)
如上所述,神经网络训练的基本组件如下:
- 神经网络:将一些数据作为输入,并根据其内部参数/权重对这些数据进行转换,以产生一些输出。
- 数据集:输入输出数据对(如图像及其对应的分类)的一大组实例。
- 优化器:用于更新神经网络的内部参数,使其预测更加准确。
- 超参数:由深度学习实践者设置的外部参数,用于控制训练过程的相关细节。
通常,神经网络开始训练时,其所有参数都是随机初始化的。为了学习更有意义的参数,向神经网络显示来自数据集的数据样本。对于这些样本中的每一个,神经网络试图预测正确的输出,然后优化器更新神经网络的参数以改进这种预测。
更新神经网络参数以使其能够更好地匹配数据集中的已知输出的过程称为训练。该过程反复重复,通常直到神经网络多次循环遍历整个数据集(称为一个训练时期)。
虽然这种对神经网络训练的描述并不全面,但它应该提供足够的直觉来完成这一概述。网上有许多关于神经网络训练的广泛教程。目前为止我最喜欢的教程来自杰瑞米·霍华德和 fast.ai 的《程序员实用深度学习》课程;请参见下面的视频链接。
什么是超参数?
模型参数由优化器在训练期间更新。相比之下,超参数是我们深度学习实践者可以控制的“额外”参数。但是,我们实际上可以用超参数控制什么呢?与本概述相关的一个常见超参数是学习率。
学习率是多少?简单来说,每次优化器更新神经网络的参数时,学习率控制着这次更新的大小。我们应该大量更新参数,一点点更新,还是在中间某处更新?我们通过设置学习率来做出选择。
选择好的学习率。设定学习率是训练神经网络最重要的方面之一。如果我们选择一个太大的值,训练将会发散。另一方面,学习率太小会导致表现不佳和训练缓慢。我们必须选择一个足够大的学习率,以便为训练过程提供正则化的好处并快速收敛,同时不能太大以至于训练过程变得不稳定。
选择好的超参数
模型参数由优化器在训练期间更新。相比之下,超参数是我们深度学习实践者可以控制的“额外”参数。但是,用超参数我们能控制什么呢?与本概述相关的一个常见超参数是学习率。
什么是学习率?简单来说,每次优化器更新神经网络的参数时,学习率控制着这次更新的大小。我们应该更新参数很多,一点点,还是中间的某个地方?我们通过设置学习率来做出选择。
选择一个好的学习率。设定学习率是训练神经网络最重要的方面之一。如果我们选择一个太大的值,训练将会发散。另一方面,学习率太小会导致表现不佳和训练缓慢。我们必须选择一个足够大的学习率,以便为训练过程提供正则化的好处并快速收敛,同时不能太大以至于训练过程变得不稳定。
选择好的超参数
学习率等超参数通常使用一种简单的方法选择,称为网格搜索。基本想法是:
- 为每个超参数定义一个潜在值范围
- 选择一组离散值在此范围内进行测试
- 测试可能的超参数值的所有组合
- 根据验证集性能选择最佳超参数设置
网格搜索是对最佳超参数的简单、详尽的搜索。有关潜在学习率值的网格搜索示例,请参见下图。
最佳学习率的网格搜索(由作者创建)
通过遵循类似的方法并测试超参数值的所有可能组合,可以将类似的方法同时应用于许多超参数。
网格搜索在计算上是低效的,因为它需要为每个超参数设置重新训练神经网络。为了避免这种成本,许多深度学习实践者采用“猜测和检查”的方法,在合理的范围内尝试几个超参数,看看什么有效。选择最佳超参数的替代方法已被提出[5],但网格搜索或猜测和检查程序因其简单性而被普遍使用。
学习率调度
在选择了学习率之后,我们通常不应该在整个训练过程中保持相同的学习率。相反,传统智慧建议我们应该 (i) 选择一个初始学习率,然后 (ii) 在整个训练过程中衰减这个学习率[1]。我们用来执行这种衰减的函数被称为学习速率表。
多年来已经提出了许多不同的学习速率表;例如,阶跃衰减(即,在训练期间将学习速率衰减 10X 几次)或余弦退火;见下图。在这个概述中,我们将探讨一些最近提出的表现特别好的时间表。
阶跃衰减和余弦退火学习率图表(由作者创建)
适应性优化技术。根据随机梯度下降 (SGD)的神经网络训练选择用于更新所有模型参数的单个全局学习速率。除了 SGD 之外,还提出了自适应优化技术(例如, RMSProp 或 Adam【6】),这些技术使用训练统计数据来动态调整用于每个模型参数的学习率。本概述中概述的大多数结果适用于自适应和 SGD 风格的优化器。
出版物
在本节中,我们将看到最近提出的学习率计划的几个例子。这些策略包括循环或三角学习率,以及学习率衰减的不同模式。最佳学习率策略高度依赖于领域和实验设置,但是我们将会看到,通过研究许多不同学习率策略的经验结果,可以得出一些高层次的结论。
训练神经网络的循环学习率【1】
作者在[1]中提出了一种在神经网络训练期间处理学习速率的新方法:根据平滑时间表在最小值和最大值之间循环变化。在这项工作之前,大多数实践者采用了流行的策略 (i) 将学习率设置为一个初始的大值,然后 (ii) 随着培训的进行逐渐降低学习率。
在[1]中,我们抛弃了这一经验法则,转而采用循环策略。以这种方式循环学习率有些违反直觉——在训练期间增加学习率会损害模型性能,对吗?尽管随着学习率的增加,网络性能会暂时下降,但循环学习率计划实际上会在整个培训过程中带来很多好处,我们将在【1】中看到。
(来自[1])
循环学习率引入了三个新的超参数:步长、最小学习率和最大学习率。由此产生的时间表是“三角形”的,意味着学习率在相邻的周期中增加/减少;见上文。步长可以设置在 2-10 个训练时段之间,而学习率的范围通常通过学习率范围测试来发现(参见[1]的第 3.3 节)。
增加学习率会暂时降低模型性能。然而,一旦学习率再次下降,模型的性能将会恢复并提高。考虑到这一点,我们在[1]的实验结果中看到,用循环学习率训练的模型在其表现中遵循一种循环模式。模型性能在每个周期结束时达到峰值(即,当学习率衰减回最小值时),并且在周期的中间阶段(即,当学习率增加时)变得有些差;见下文。
(来自[1])
[1]中的结果表明,在训练过程中,循环学习率有利于模型性能。通过循环学习率训练的模型比通过其他学习率策略训练的模型更快地达到更高的性能水平;见下图。换句话说,用循环学习率训练的模型的 anytime 性能真的很好!
(来自[1])
在 ImageNet 上的大规模实验中,循环学习率仍然有好处,尽管它们没有那么明显。
(来自[1])
SGDR:带有热重启的随机梯度下降
作者在[2]中提出了一种简单的学习率重启技术,称为重启随机梯度下降(SGDR),其中学习率被周期性地重置为其初始值并计划降低。该技术采用以下步骤:
- 按照固定的时间表降低学习速度
- 衰减计划结束后,将学习率重置为其原始值
- 返回步骤#1(即,再次衰减学习率)
下面提供了遵循该策略的不同时间表的描述。
(来自[2])
我们可以注意到关于上面的时间表的一些事情。首先,在[2]中总是使用余弦衰减时间表(该图的 y 轴是对数标度)。此外,随着训练的进行,每个衰减时间表的长度可能会增加。具体来说,[2]中的作者将第一个衰变周期的长度定义为T_0
,然后在每个后续衰变周期中将该长度乘以T_mult
;见下文的描述。
延长 SGDR 境内的周期长度(由作者创建)
按照[1]的术语,SGDR 的步长可能在每个周期后增加。然而,与[1]不同,SGDR 不是三角形的(即,每个周期只是衰减学习速率)。
在 CIFAR10/100 上的实验中,我们可以看到 SGDR 学习率计划比阶跃衰减计划更快地产生良好的模型性能——SGDR 具有良好的随时性能。在每个衰变周期之后获得的模型表现良好,并且在连续的衰变周期中继续变得更好。
(来自[2])
除了这些初步结果,我们还可以研究在每个衰变周期结束时拍摄“快照”所形成的模型集合。特别是,我们可以在 SGDR 时间表内的每个衰变周期后保存模型状态的副本。然后,在训练完成后,我们可以在推断时对这些模型中的每一个的预测进行平均,形成模型的集合/组;点击链接这里了解更多关于合奏的细节。
通过以这种方式形成模型集合,我们可以在 CIFAR10 上实现非常显著的测试误差减少;见下文。
(来自[2])
此外,来自 SGDR 的快照似乎提供了一套具有不同预测的模型。以这种方式形成集成实际上优于将独立的、完全训练的模型添加到集成中的正常方法。
超收敛:使用大的学习速率非常快速地训练神经网络 [3]
[3]中的作者研究了一种训练神经网络的有趣方法,该方法允许训练速度提高一个数量级。基本方法——最初在[8]中概述——是执行一个具有较大最大学习率的单一三角形学习率循环,然后在训练结束时允许学习率衰减到低于该循环的最小值;请看下面的插图。
1 周期学习率和动量表(由作者创建)
此外,动量以与学习速率相反的方向循环(通常在[0.85,0.95]的范围内)。这种联合循环学习速率和动量的方法被称为“1 循环”。作者在[3]中表明,它可以用来实现“超收敛”(即极快地收敛到高性能的解决方案)。
例如,我们在 CIFAR10 上的实验中看到,1cycle 可以比基线学习率策略获得更好的性能,训练迭代次数减少了 8 倍。使用不同的 1cycle 步长可以进一步提高训练速度,尽管精度水平会因步长而异。
(摘自[3])
我们可以在一些不同的架构和数据集上观察到类似的结果。参见下表,其中 1cycle 在数量少得惊人的训练时段中再次产生了良好的性能。
(摘自[3])
目前,由于[3]中提供的实验在规模和种类上有所限制,尚不清楚是否可以在大量的实验设置中实现超收敛。尽管如此,我们可能都同意超级趋同现象非常有趣。事实上,这个结果非常有趣,甚至被 fast.ai 社区推广和深入研究;见此处。
REX:用改进的时间表重新审视预算培训
在[4]中,作者(包括我自己)考虑了在给定不同预算制度(即,小、中或大数量的训练时期)的情况下适当安排学习率的问题。你可能会想:我们为什么要考虑这种设置?通常,训练时期的最佳数量事先并不知道。此外,我们可能会使用固定的货币预算来限制我们可以执行的训练次数。
为了找到最佳的预算不可知的学习率计划,我们必须首先定义将被考虑的可能的学习率计划的空间。在[4]中,我们通过将学习率计划分解为两个部分来实现这一点:
- Profile: 学习率在整个训练过程中变化的函数。
- 采样率:根据所选的配置文件更新学习率的频率。
这种分解可以用来描述几乎所有的固定结构的学习率时间表。不同的曲线和采样速率组合如下所示。较高的采样速率会使时间表与底层配置文件更加匹配。
用不同的曲线和采样速率描述学习速率表(来自[4])
[4]中的作者考虑了由不同的采样速率和三个函数轮廓形成的学习速率计划——指数(即,产生步进计划)、线性和 REX(即,在[4]中定义的新轮廓);见上图。
在这里,作者在 CIFAR10 上使用不同的采样速率和配置文件组合来训练 Resnet20/38。在这些实验中,我们看到阶跃衰减时间表(即,具有低采样率的指数曲线)仅在给定低采样率和许多训练时期的情况下表现良好。REX 调度每次迭代采样在所有不同的历元设置中表现良好。
(摘自[4])
先前的工作表明,线性衰减时间表最适合低预算的训练设置(即,具有较少时期的训练)[9]。在[4]中,我们可以看到 REX 实际上是一个更好的选择,因为它避免了在训练期间过早地衰减学习率。
从这里开始,[4]中的作者考虑了各种流行的学习率计划,如下图所示。
[4]中研究的不同学习率计划
这些时间表经过了各种领域和训练时期预算的测试。当汇总所有实验的性能时,我们会得到如下所示的结果。
(摘自[4])
很快,我们看到 REX 在不同的预算制度和实验领域取得了惊人的一致表现。没有其他的学习进度计划在实验中达到接近前 1/3 的比率,这表明 REX 是一个很好的领域/预算不可知的学习进度计划。
除了 REX 的一致性,这些结果教给我们一些更普遍的东西:常用的学习速率策略在实验环境中并不通用。每种学习计划(即使是 REX,尽管程度较轻)仅在少数情况下表现最佳,这表明为任何特定环境选择合适的学习率策略都非常重要。
外卖食品
正确处理学习速率可以说是神经网络训练最重要的方面。在这个概述中,我们已经了解了几个用于训练深度网络的实用学习率计划。研究这一行提供了简单易懂、易于实现且高效的要点。下面列出了一些基本要点。
选择一个好的学习率。正确设置学习率是训练高性能神经网络的最重要方面之一。选择不良的初始学习率或使用错误的学习率计划会显著降低模型性能。
“默认”时间表并不总是最好的。许多实验设置都有一个“默认”的学习速率表,我们往往会不假思索地采用它;例如用于训练图像分类的 CNN 的步进衰减时间表。我们应该意识到,随着实验设置的改变,这些时间表的性能可能会急剧恶化;例如,对于预算设置,基于 REX 的调度明显优于步长衰减。作为实践者,我们应该始终注意我们选择的学习率计划,以真正最大化我们模型的性能。
周期性的日程安排太棒了。循环或三角学习率计划(如[2]或[3])非常有用,因为:
- 它们经常达到或超过最先进的性能
- 他们随时都有很好的表现
使用循环学习率策略,模型在每个衰减周期结束时达到最佳性能。我们可以简单地继续训练任意给定的周期数,直到我们对网络的性能满意为止。最佳的训练量不需要事先知道,这在实践中经常是有用的。
外面有很多值得探索的地方。虽然学习速度策略已经被广泛研究,但似乎还有更多有待发现。例如,我们已经看到,采用替代衰变曲线有利于预算设置[4]和循环策略,在某些情况下甚至可以用来实现超收敛[3]。我的问题是:还能发现什么?似乎真的有一些有趣的策略(例如,分形学习率[7])有待探索。
软件资源
作为对这个概述的补充,我创建了一个轻量级代码库,用于复制一些不同的学习率计划,包括:
- 产生不同衰变曲线的函数
- PyTorch 优化器中用于调整学习率/动量的函数
- 我们在本概述中看到的常见学习率计划的工作示例
虽然有点小,但这段代码提供了实现和使用我们到目前为止学习过的任何学习率策略所需的一切。如果您对使用这段代码不感兴趣,也可以使用 PyTorch 中直接实现的学习率调度器。
结论
非常感谢你阅读这篇文章。如果你喜欢它,请在 twitter 上关注我,或者订阅我的深度(学习)焦点时事通讯,在那里我挑选了一个关于深度学习研究的单个两周一次的主题,提供了对相关背景信息的理解,然后概述了一些关于该主题的流行论文。我是 Cameron R. Wolfe ,ale gion的研究科学家,莱斯大学的博士生,研究深度学习的经验和理论基础。你也可以看看我在 medium 上的其他著述!
文献学
[1] Smith,Leslie N .“训练神经网络的循环学习率” 2017 年 IEEE 计算机视觉应用冬季会议(WACV) 。IEEE,2017。
[2]洛希洛夫、伊利亚和弗兰克·哈特。" Sgdr:带有热重启的随机梯度下降." arXiv 预印本 arXiv:1608.03983 (2016)。
[3]史密斯、莱斯利·n .和尼古拉·托平。"超收敛:使用大的学习速率非常快速地训练神经网络."面向多领域运营应用的人工智能和机器学习。第 11006 卷。SPIE,2019。
[4]陈、约翰、卡梅伦·沃尔夫和塔索斯·基里利迪斯。"雷克斯:用改进的时间表重新审视预算培训."机器学习与系统学报4(2022):64–76。
[5]余、童、。"超参数优化:算法和应用综述."arXiv 预印本 arXiv:2003.05689 (2020)。
[6]金玛、迪德里克 p .和吉米巴。"亚当:随机最优化的方法."arXiv 预印本 arXiv:1412.6980 (2014)。
[7] Agarwal、Naman、Surbhi Goel 和 Cyril Zhang。"通过分形学习速率表加速."机器学习国际会议。PMLR,2021 年。
[8] Smith,Leslie N 神经网络超参数的训练方法:第 1 部分——学习速率、批量大小、动量和权重衰减〉 arXiv 预印本 arXiv:1803.09820 (2018)。
[9]李、、尔辛·尤默和德瓦·拉曼南。"预算训练:在资源限制下重新思考深度神经网络训练." arXiv 预印本 arXiv:1905.04753 (2019)。
数据科学的最佳专业/学位
原文:https://towardsdatascience.com/the-best-major-degree-for-data-science-59cb34335e84
意见
数据科学不仅仅是数学和计算机科学
如果你在谷歌上搜索数据科学的最佳专业或学位,你会发现各种各样的建议,包括数学、统计学和计算机科学。在我作为数据科学家长达十年的职业生涯中,我发现没有一个专业或学位能够涵盖在数据科学领域取得成功所需的所有技能。我的数学学位绝对有助于我理解 scikit-learn 算法的内部工作原理,但为了编写代码将这些算法部署到生产中,我必须深入扩展我的计算机科学知识。
虽然数学、统计学和计算机科学向数据科学家传授了他们工作所需的技术技能,但我发现软技能同样重要,而且在这些领域没有得到足够的重视。为了提高我的软技能,我发现心理学和商业领域非常有帮助。
对于有抱负的数据科学家,我建议你考虑本文中任何领域的主修和/或副修,对于当前的数据科学家,让这些领域和资源推动你的学习。
计算机科学
让我们从一个最不令人惊讶的领域开始——计算机科学。我认识的许多数据科学家都研究过计算机科学、物理或工程等硬科学。如果你来自计算机科学以外的领域,我认为这是数据科学家扩展知识最有价值的领域之一。
数据科学家(名词):比任何软件工程师更擅长统计,比任何统计学家更擅长软件工程的人。—乔希·威尔斯
正如 Josh Wills 所言,软件工程是成功的数据科学家的基本能力。你可能足够幸运,有一个机器学习工程师为你生产你的 Jupyter 笔记本;然而,对于许多数据科学家来说,现实是他们需要编写和部署生产级代码。你在数学课上不会学到如何做到这一点。
如果您不熟悉计算机科学领域的广泛主题,您可以查看以下资源。
- 戴维·托马斯和安德鲁·亨特的《实用程序员》
- 布莱恩·克里斯蒂安和汤姆·格里菲斯的《赖以生存的算法》
- 马丁·福勒的博客
数学与统计
在乔希·威尔斯的数据定义的另一边,科学家是数学和统计学。像 scikit-learn、PyTorch 和 TensorFlow 这样的框架使得创建复杂的模型变得简单,但是在每个模型背后都有一个使用数学进行决策的算法。对于数据科学家来说,数学和统计知识是不可讨价还价的。没有这些知识,你很可能不会理解为什么你的模型表现得特别好或者特别差。
一旦你对基础知识(微积分、线性代数和概率论等)有了坚实的理解,我建议你查阅以下资源。
- Rob J hynd man 和 George Athanasopoulos 的《预测原理和实践》
- 如何不犯错:数学思维的力量,作者乔丹·埃伦伯格
- 安妮·杜克著
- 《信号与噪音》作者内特·西尔弗
- 被纳西姆·尼古拉斯·塔勒布的随机性所愚弄
- 纳西姆·尼古拉斯·塔勒布的《反脆弱》
心理学
所以让我们假设你已经有了很强的技术背景,并且想扩展到计算机科学、数学和统计学之外。我发现自己经常退出的一个领域是心理学。
从表面上看,数据科学和心理学似乎并不相关;然而,当你去除数学和计算机科学时,数据科学的核心是帮助个人和组织做出更快、更好、更便宜的决策。我们可以借鉴多年来对决策过程背后的心理学的研究,来构建更好的机器学习系统。
人类是每个机器学习系统的核心。他们生成用于训练我们的模型的数据,消费我们的模型的输出,并最终由于我们的模型做出的决定而改变他们的行为(不管是好是坏)。虽然我的学位课程侧重于使用哪些算法,但我发现更重要的是关注与这些算法互动的人 。
我经常发现自己倾向于心理学领域来解决日常数据科学工作中的问题。以获得标记数据集的过程为例。对于许多最有趣的问题来说,对于你试图完成的事情,没有一个完美标记的数据集。在我们能够建立一个模型之前,我们依赖人们为我们注释数据。
但是为我们的注释者设计最好的标记任务比看起来更复杂。假设我希望我的注释器为多类分类问题标记数据。你知道人类能够区分的类别数量是有极限的吗?如果我需要我的注释器为我的数据执行两个标记任务,该怎么办?第一个任务会偏向第二个任务的结果吗?当我收到注释时,如何处理注释者的异议和偏见?
这些只是在我们接触任何机器学习模型之前要问的一些重要问题的例子。据我所知,心理学领域收集人类数据的时间比任何其他专业都长,而且数据科学领域可以从一些重要知识中受益。以上所有问题都在心理学领域以这样或那样的方式得到了解决——我们只需要应用这些发现。
如果你想涉足心理学领域,这里有几本我最喜欢的书。
业务
最后,但肯定不是最不重要的,让我们讨论一下商业世界。了解企业如何运作是关键,因为通常是他们付钱让你做数据科学家的工作。要想成为一名高效的数据科学家,你需要快速了解你的业务是做什么的、如何做的,以及你如何融入全局。
在 Unsplash 上的 Smartworks 合作者的照片
了解了这些之后,我发现了解更多专门了解“客户”问题的具体职位是很有帮助的。我通常认为我的雇主是我的内部客户,我雇主的客户是我的外部客户。无论哪种情况,我都想成为双方都面临的问题的专家。为此,产品经理通常是外部客户问题的专家。
与产品经理会面并对他们的领域进行更多研究,帮助我更好地了解我的客户,并创建完全满足他们需求的机器学习系统。随着您开始发展这方面的技能,您可能会意识到产品管理和数据科学之间有相当多的重叠。产品经理需要对统计学有一个基本的了解,以理解他们的产品团队运行的 A/B 测试,还需要能够评估客户数据。此外,让他们了解一些用户体验知识也是有帮助的,这将我们带回心理学的世界。
了解更多关于产品管理、一般业务或任何介于两者之间的知识,将为你成为一名成功的数据科学家做好准备。下面列出了一些我推荐的资源,可以帮助你开始学习。
学习方法
那么,你如何尝试去了解一个对你来说完全陌生的领域呢?正规教育,就像大学的学位课程一样,是学习新领域基础知识的好方法,但它通常不会让你具备工作中需要的所有知识。
我最喜欢的学习新领域的方法之一是通过基于项目的学习。如果我有某种项目来强化我的学习,我会更容易陷入一个新的话题或领域。如果这个项目是我关心的,而不是某个人 Github 中的一个随机项目,那就更有帮助了。
如果你目前是一名数据科学家,你应该已经有了一个可以帮助指导你学习的项目。如果没有,你可能想参加一个研讨会,教你构思、设计和建立一个项目。
我希望我在本文中提供的资源将成为您学习的坚实起点。但是对于那些阅读能力比我强的人来说,请在你最喜欢的书籍、博客、播客或视频中留下你对我在本文中提到的任何领域的评论。我很乐意向你学习!
结论
专业化是许多人在职业生涯中努力追求的目标。当你成为某个领域的专家时,你通常会得到回报。然而,数据科学挑战我们成为更多的通才。拓宽你对我上面提到的领域的理解(以及更多!)能让你在事业上更加强大。你永远不知道你下一步可能会潜入哪个领域来建立一个更好的机器学习模型。
资源
一次性编码数据的最佳方法
原文:https://towardsdatascience.com/the-best-methods-for-one-hot-encoding-your-data-c29c78a153fd
数据准备
onehotencode vs get _ dummies vs to _ category
图片由皮克斯拜的 Gerd Altmann 提供
在将数据输入机器/深度学习模型之前,对数据进行预处理是整个过程中最重要的阶段之一。如果没有经过适当预处理的数据,无论你的模型多么先进和巧妙,最终都将是低效和不准确的。
对于独立分类数据来说,一种热编码可能是最常用的预处理方法,可确保模型能够公平、无偏见地解释输入数据。
本文将探索使用一次性方法对分类数据进行编码的三种最常见的方法,并讨论为什么首先要使用这种技术。
介绍
本文将对以下方法进行比较和讨论:
- 熊猫 — get_dummies()
- Scikit-Learn—OneHotEncoder()
- Keras—to _ categorial()
所有方法基本上达到相同的结果。然而,它们以完全不同的方式进行,并且具有不同的特性和选项。
那么,哪种方法最适合您的具体情况呢?
什么是一键编码?
在我们开始之前,我认为有必要先简单介绍一下为什么你会想使用这种方法。
一个热编码基本上是一种准备分类数据的方法,以确保机器学习/深度学习模型将类别视为彼此独立。
确凿的例子
让我们举一个实际的例子来说明这个观点。我们有三个类别:
- 鸡肉
- 岩石
- 枪
他们之间没有任何关系,完全独立。
为了将这些类别输入到机器学习模型中,我们需要将它们转化为数值,因为机器/深度学习模型无法处理任何其他类型的输入。那么如何最好地做到这一点呢?
一只逃跑的鸡。詹姆斯·温斯科特在 Unsplash 上的照片
最简单的方法是给每个类别分配一个编号:
- 鸡肉
- 岩石
- 枪
这种方法(称为顺序编码)的问题是,当数字一个接一个时,模型可以推断出类别之间的关系。
枪比鸡重要是因为它的编号更高吗?鸡是半块石头吗?如果你有三只鸡,那和一把枪一样吗?
如果这些值是标签,如果模型输出的答案是 1.5,那会怎么样呢?所有这些说法都是无稽之谈,但由于模型只看到数字,而不是我们看到的名字,因此推断这些东西对模型来说是完全可行的。
为了避免这种情况,我们需要将类别完全分开。这就是一键编码所实现的目标:
一个热点编码的例子——作者列表
这些值只能是 1 或 0(开或关)。1 表示是那个东西,0 表示不是。
所以在第一排你有一只鸡(没有石头也没有枪),第二排有一块石头(没有鸡也没有枪)等等。由于这些值要么是开,要么是关,因此不可能以任何方式将一个与另一个相关联。
快速笔记
在更详细地研究这三种方法之前,我只想指出,我将使用 Colab 的一种替代方法,我通常使用它来为本文提供代码。
我将使用的替代方案是 deepnote 。它本质上与 Colab 相同,它让您可以在在线环境中运行 Jupyter 笔记本(有一些差异,我不会在这里深入讨论,但可以查看网站了解更多信息)。
这样做的主要原因是,为了演示本文中一些方法的最新特性,我需要访问 Pandas 1.5.0(撰写本文时的最新版本),而我似乎无法在 Colab 中实现这一点。
然而,在 deepnote 中,我可以指定一个 Python 版本(在本例中是 3.10),还可以创建自己的 requirements.txt 来确保环境安装 Pandas 1.5.0,而不是默认版本。
它还允许非常简单的从 Jupyter 笔记本直接嵌入到本文中(您将会看到),这非常有用。
我仍然会像往常一样让笔记本在 colab 中可用,但是一些代码不会运行,所以请记住这一点。
数据
这些数据基本上与饮酒对考试成绩的影响有关。不是你需要记住的东西,但如果你感兴趣的话…
由vini cius“amnx”Amano在 Unsplash 上拍摄
和以往一样,我把数据放在一个笔记本上。您可以在以下任一 deepnote 中访问它:
(如前所述,熊猫 1.5.0 已在 deepnote 中推出。只需在右边的“环境”部分激活 Python 3.10,在右边的“文件”部分创建一个名为“requirements.txt”的文本文件,其中有一行“pandas==1.5.0”。然后运行笔记本。)
或者 colab:
(由于需要 Pandas 1.5.0,下面的一些方法将不起作用)
我选择了一个数据集,它包括各种不同的分类和非分类列,这样就可以很容易地看出每种方法是如何根据数据类型工作的。这些列如下所示:
- 性别 —二进制字符串(“M”代表男性,“F”代表女性)
- 年龄 —标准数值栏(int)
- Medu —母亲的教育程度—多类整数表示(0[无],1[初等教育],2 [五至九年级],3[中等教育]或 4[高等教育])
- Mjob —母亲的工作—多类字符串表示—('教师','健康'保健相关,民事'服务'(如行政或警察),'在家'或'其他')
- Dalc —工作日酒精消耗量—多类分级整数表示(从 1[非常低]到 5[非常高])
- Walc —周末饮酒量—多类分级整数表示(从 1[非常低]到 5[非常高])
- G3 —最终成绩(标签)—多类分级整数表示(数字:从 0 到 20)
前五行的示例如下:
和数据类型:
熊猫—获取 _ 假人()
pandas.get_dummies(data, prefix=None, prefix_sep=’_’, dummy_na=False, columns=None, sparse=False, drop_first=False, dtype=None)
我会把 Pandas 的 get_dummies()方法描述为一个非常中庸的一次性编码器。它让事情变得简单,同时提供合理数量的选项,允许您适应最常见的用例。
您可以非常简单地将 Pandas dataframe 传递给 get_dummies(),它会计算出哪些列最适合一种热编码。
然而,正如您将看到的那样,这并不是处理事情的最佳方式:
如果您查看上面的输出,您将看到只有类型为“Object”的列被一次性编码(sex 和 MJob)。任何整数数据类型列都被忽略了,这在我们的例子中并不理想。
但是,您可以指定要编码的列,如下所示:
需要注意的一点是,当使用 get_dummies()时,它将所有内容都保存在 dataframe 中。没有额外的数组需要处理。它只是被整齐地保存在一个地方。OneHotEncoder()或 to _ categorical()方法则不是这种情况,我们将在后续章节中讨论。
在某些特定情况下,删除每个热编码序列的第一列可能是可取或有用的(例如,为了避免多重共线性)。get_dummies()内置了这种能力:
例如,请注意上面的“Medu_0”现在是如何丢失的。
现在的工作方式是,如果 Medu_1 到 Medu_4 都是零,这实际上意味着 Medu_0(唯一的其他选择)被“选择”。
以前,当包含 Medu_0 时(即不使用 drop_first),绝不会出现所有值都为零的情况。因此,实际上通过删除列,我们不会丢失关于类别的任何信息,但是我们确实减少了列的总量,因此减少了运行模型所需的处理能力。
在决定删除一个专栏是否合适时,有更多微妙的事情需要考虑,但是由于这种讨论需要自己写一整篇文章,所以我将把它留给您来研究。
附加选项
除了“drop_first”之外,还有其他方法,如“sparse”来生成稀疏矩阵,以及“dummy_na”来帮助处理数据中可能存在的 NaN 值。
如果您需要这种程度的灵活性,还可以对前缀和分隔符进行一些定制。
用 from_dummies()反转 get_dummies()
直到最近还没有从 Pandas 库中反转 get_dummies()的方法。您必须手动完成这项工作。
然而,从 Pandas 1.5.0 开始,有了一种叫做 from_dummies() 的新方法:
pandas.from_dummies(data, sep=None, default_category=None)
这允许在不编写自己的方法的情况下实现反转。它甚至可以通过使用“default_category”参数来处理利用“drop_first”的一键编码的反转,如下所示:
要在编码中使用“drop_first”时进行反转,必须指定丢弃的项目:
scikit-learn — OneHotEncoder()
Scikit-Learn 中的 OneHotEncoder()方法可能是所有热编码方法中最全面的。
sklearn.preprocessing.OneHotEncoder(*, categories='auto', drop=None, sparse=True, dtype=<class 'numpy.float64'>, handle_unknown='error', min_frequency=None, max_categories=None)
正如您所看到的,上面的方法输入可以处理:
- 为一个热门编码自动挑选类别
- drop columns(不仅仅是第一种,还有更广泛的选择)
- 生成稀疏矩阵
- 处理可能出现在未来数据集中的类别(handle_unknown)
- 您可以根据频率或最大类别数来限制编码返回的类别数量
该方法还使用了 fit-transform 方法,这对于在机器和深度学习的输入管道中使用该方法非常有用。
编码器
这种方法与所有其他方法的区别之一是,您创建了一个编码器“对象”,它存储了将用于编码数据的所有参数。
因此,这可以在代码的后面引用、重用和调整,使它成为一种非常灵活的方法。
一旦编码器被实例化,我们就可以一次性编码一些数据:
在这种情况下,我使用了“fit_transform”方法,但与所有遵循“fit”/“transform”模式的 sklearn 方法一样,您也可以在单独的步骤中拟合和转换数据。
OneHotEncoder 所做的是提取它认为应该一键编码的列,并将它们作为一个新数组返回。
这与 get_dummies()不同,后者将输出保存在同一个数据帧中。如果您想以最小的努力将所有数据包含在一个数据帧中,那么这是值得考虑的事情。
还应该注意的是,OneHotEncoder 在“auto”时识别更多 get_dummies()的输入列,如下所示。
无论如何,指定您希望作为目标的列仍然是一个很好的做法。
为了保持一致性,我将用 get_dummies()对与前面相同的列进行编码:
已编码的列,以及编码器的参数:
反转 OneHotEncoder
有一个非常简单的方法来反转编码,因为编码器被保存为它自己的对象(在本例中为“skencoder”),所以所有用于进行一次性编码的原始参数都保存在这个对象中。这使得反转非常容易:
其他有用信息
使用 OneHotEncoder 的另一个优点是,有大量的属性和帮助方法可以让您访问编码中使用的信息。我在下面提供了一些例子:
属性
方法
高级功能
如前所述,OneHotEncoder 有很多有用的特性,使它成为一种非常灵活的使用方法。
我将在下面谈到其中的一些方法。
最小频率
这可以用来限制编码类别。如果你有一个由几个重要的类别主导的特性,但是有许多更小的类别,那么你可以有效地将这些更小的类别归入一个单独的“其他”类别。
您可能会发现,您不想为不频繁的类别指定准确的记录数量。在这种情况下,您可以指定与可用记录总数相比的最小记录数。为此,您需要指定总计数的一部分。
在我们的例子中有 395 条记录,所以为了达到与指定正好 60 条记录作为限制相同的结果,我们可以指定 60 / 395 = 0.152,或者为了简单起见,指定 0.16(这基本上意味着一个类别必须占总计数的 16%才能被认为是重要的)
最大类别数
解决这个问题的另一种方法是指定类别的最大数量。
处理未知
处理未知是一个非常有用的特性,尤其是在用于机器学习或神经网络模型的流水线中。
本质上,它允许您在不中断输入管道的情况下,为将来可能出现的另一个类别制定计划。
例如,您可能有一个像“Medu”这样的特征,将来由于某种原因,在“高等教育”的最终类别之上的“PhD”类别被添加到输入数据中。理论上,这个额外的类别会破坏你的输入管道,因为类别的数量已经改变了。
处理未知允许我们避免这种情况。
虽然我不会给出一个具体的例子,但这很容易理解,尤其是如果你已经阅读了前两节关于“最大类别”和“最小频率”的内容。
设置选项:
- 【错误】:这只会引发一个错误,如果你试图添加额外的类别,你可以说这是标准行为
- 【ignore】:这将导致任何额外的类别都被编码为全零,因此如果最初有 3 个类别[1,0,0],[0,1,0]和[0,0,1],那么额外的类别将被编码为[0,0,0]。反转后,该值将为“无”。
- ' incocrative _ if _ exist ':如果您已经在编码器中实现了' max_categories '或' min_frequency ',那么附加类别将与任何非频繁类别一起映射到' XXX _ incocrative _ sk learn '。否则,它将被完全视为“忽略”。
重要提示:不能同时使用 handle_unknown='ignore' 和drop category 参数(如 drop: 'first ')。这是因为它们都产生全零的类别,因此冲突。
下降
就像来自 _dummies()的熊猫一样,你可以选择删除类别,尽管选项更广泛一些。
以下是选项(根据文档):
- 无:保留所有功能(默认)。
- ‘第一’:在每一个功能里放第一个类别。如果只存在一个类别,该特征将被完全删除。
- ‘if _ binary’:将每个特征中的第一个类别,用两个类别进行拖放。具有 1 个或 2 个以上类别的特征保持不变。
- 数组 : drop[i]是特征 X[:,i]中应该被丢弃的类别。
重要提示:不能同时使用 handle_unknown='ignore' 和drop category 参数(如 drop: 'first ')。这是因为它们都产生全零的类别,因此冲突。
【第一次】
每个类别的第一个条目将被删除(“sex_F”、“Medu_0”和“Mjob_at_home”)。
【if _ binary】
只有恰好两个类别的特征会受到影响(在我们的例子中,只有‘sex _ F’被删除)。
【列阵】
在这种情况下,您可以从每个要素中准确选择应该删除的类别。我们将删除“sex_M”、“Medu_3”和“Mjob_other”。
分类分类
扬·安东宁·科拉尔在 Unsplash 上拍摄的照片
Keras 方法是一个非常简单的方法,虽然它可以像其他方法一样用于任何事情,但是它只能处理数值。
因此,如果您有字符串类别,您必须首先转换它们,这是其他方法自动处理的事情。
tf.keras.utils.to_categorical(y, num_classes=None, dtype='float32')
Keras to _ categorical()可能对一个标签的热编码最有用:
上面没有告诉我们太多,所以让我们挑出索引 5 处的转换,这样我们可以看到编码了什么:
反转
没有专门的反转方法,但是通常 argmax 应该允许我们反转编码。Argmax 也可以从模型的输出中工作,其中的数字可能不是整数。
较小的示例:
所有数据:
指定类别
一个有用的特性是能够指定有多少独特的类别。默认情况下,类别的数量是数组中最大的数字+ 1。+1 是考虑到零。
值得注意的是,这是您可以指定的最小值。但是,可能有这样的情况,传递的数据不包含所有的类别,您仍然希望转换它(就像一小组测试标签),在这种情况下,您应该指定类的数量。
尽管该方法需要整数,但它可以按照下面的方式处理 float 数据类型。
这些是独特的类别:
这是唯一类的计数:
只有 18 个唯一的类,但是我们可以编码任意多的类,所以让我们编码 30 个类:
然后我们可以检查形状,看到我们有 30 个列/类:
…仍然可以顺利反转:
摘要
概括来说:
熊猫— get_dummies() :
- 在数据框架内创建一个热编码列,而不创建新矩阵。如果你喜欢用最少的努力把所有的东西都保存在一个熊猫的数据框架内,这可能是适合你的方法
- 只有能自动将非数字列识别为分类数据吗
- 有一些有用的选项,比如稀疏矩阵和删除第一列
- 从熊猫 1.5.0 开始,内置了一个反转方法
Scikit-learn—OneHotEncoder():
- 设计用于管道,因此很容易集成到预处理工作流中
- 可以自动挑出一个热编码的类别,包括数字列
- drop columns(不仅仅是第一种,还有更广泛的选择)
- 生成稀疏矩阵
- 用于处理未来数据集中出现的类别的各种选项(handle_unknown)
- 您可以根据频率或最大类别数来限制编码返回的类别数量
- 有许多帮助器方法和属性来跟踪您的编码和参数
Keras—to _ categorial():
- 一个非常简单的方法是只对数字数据进行热编码
- 必须首先将数据转换为有序数字类别
- 可能对标签最有用
- 没有内置的反转方法
结论
总而言之,如果我必须推荐任何一种方法,那就是 Scikit-Learn 的 OneHotEncoder()。
你可能会说这个方法太复杂了。然而,我认为这种方法使用起来非常简单,而且您最终会获得可追溯性和灵活性,这是其他任何方法都无法实现的。
在考虑生产就绪代码时,将这种预处理方法与其他方法结合到处理管道中的能力以及 handle_unknown 等特性也是一个巨大的优势。
如果你觉得这篇文章有趣或有用,记得关注我,或者注册我的简讯获取更多类似的内容。
如果你还没有,你也可以考虑订阅媒体。你的会员费不仅直接支持我,也支持你所阅读的其他作家。你还可以完全不受限制地访问媒体上的每个故事。
使用我的推荐链接注册会给我一点回扣,对你的会员资格没有影响,所以如果你选择这样做,谢谢你。
https://medium.com/@maclayton/membership
参考
[1] Aman Chauhan,酒精对研究的影响 (2022),Kaggle,许可:归属 4.0 国际(CC BY 4.0)
[2] Paulo Cortez,学生表现数据集 (2014),UCI 机器学习知识库
[3] P. Cortez 和 A. Silva,使用数据挖掘预测中学生成绩 (2008),A. Brito 和 J. Teixeira 编辑。,第五届未来商业技术(FUBUTEC)会议论文集第 5–12 页,葡萄牙波尔图,2008 年 4 月,EUROSIS,ISBN 978–9077381–39–7
利用数据能力的最佳无代码人工智能平台
任何人手中神经网络的力量
数据科学家比任何人都清楚这一点:训练机器学习模型是一项漫长而乏味的工作。
除此之外,数据工程师需要编写代码,清理数据,创建标签,完善模型…
即使模型能够胜任任务,他们仍然需要检查其输出,并防止过度拟合和欠拟合。
然而,正如无代码平台使网页设计变得更容易一样,新的平台已经出现,使 ML 模型培训变得容易。
这些无代码 AI 解决方案在市场上数不胜数,每一个都带来了独特的功能。以下是最适合您的使用案例和需求的一些。
结构化数据无代码人工智能
显然是艾
显然,人工智能将人工智能的预测能力添加到了你常用的电子表格中。通过将该工具与您的历史表格数据(客户数据、交易数据、价目表)相联系,您可以确定您的客户的可能流失率、您的实时最优价格或您的业务运营风险。您可以用许多数据源丰富您的 ML 模型,并改进您的预测。显然,人工智能是一个很好的工具,可以即时利用你的业务数据。
阿克基奥
Akkio 提供相同的功能,但与您的业务应用程序(SalesForce、Hubspot、Airtable)直接集成。凭借其直观的界面,它为运营商和工程师提供了强大的预测、排名和智能推荐工具。因此,他们可以识别和利用关键业务变量来优化绩效。最重要的是,Akkio 拥有市场上一些最精确的 ML 模型,可用于许多用例。
猴子学习
MonkeyLearn 是一个以自然语言处理和文本分析为主的无代码 AI 平台。你只需要导入你的文本文件(从电子邮件,社交媒体,调查…),你就会得到你的文本的语义和情感分析。通过数据标注训练模型,您可以自动对文本进行分类或找出有意义的关键字。通过这种方式,你可以将内容背后的感觉和意图形象化,或者轻松地发现特定的词语或谈话主题。MonkeyLearn 让您了解客户的感受,从而为您提供改善业务的关键见解。
非结构化数据的无代码人工智能
纳米网络
Nanonets 允许您利用在非结构化文档中发现的数据。基于 OCR 技术,您可以训练模型来分析您的书面文档,只需很少的手动干预。您可以自动将会计、发票和管理文档转换为表格文件。您也可以只记录文档的某些特定部分,以提高效率并保留重要信息。这为操作员节省了大量时间,并允许他们从业务文档中提取关键信息。
超壬酸盐
SuperAnnotate 致力于让文本、图片和视频注释的艰苦工作变得更加容易。无论是对文本进行分类,识别图片中的对象,还是跟踪视频流中的手势和事件,该平台都为您提供了一个一体化的界面来构建您的训练数据集。有了这些深入的、高质量的注释,您可以将它们集成到您的自动化项目中,并创建一个为您的任务而完美训练的模型。
考萨伦人
CauseLens 允许决策者利用公司的数据湖来指导和证明他们的决策。与仅依赖相关性的传统机器学习模型不同,使用该工具,您可以训练基于因果关系的模型。通过将它们连接到您的预测数据流和参考数据库,这些模型为您提供了有关业务关键决策的可解释预测。然后,您可以评估这些结果的相关性,获得下一步行动的建议,并向利益相关方证明您的决策是正确的。用于透明决策的透明人工智能。
没有代码人工智能的创造性使用
裂片
Lobe 是一款让训练图像和视频分类模型变得前所未有的简单的应用。通过非常友好的用户界面,您可以一键标记来自图库或网络摄像头的图片或视频,检查模型的准确性,并将其集成到您的应用程序中。您可以创建识别情绪、分析动物行为、监控设备维护和检测产品或对象的模型。Lobe 为几乎所有人推广机器学习用例!
跑道
Runway 为视频创作者带来人工智能的力量。借助预配置的视觉模板,您可以为视频添加高级滤镜,移除背景,并从您的帧中移动特定对象。这个视频平台以前是一个人工智能无代码工具,现在允许你通过自动对象识别和识别来进行专业的视频编辑。没有什么比成为高质量的视频制作者更有效的了!
可教机器
可教机器让机器学习的可及性更进了一步。直接从你的电脑或智能手机的网络摄像头,你可以训练一个模型识别某些物体,姿势或图像,并逐步测试它的能力。你马上就会得到一个应用程序,它可以翻译语言障碍手势,对物体进行分类,并允许你进行游戏实验或制作动画机器人。可教机器使人工智能成为一个有趣的互动游戏。
一体化无代码人工智能平台
轻率
轻佻通过一个仪表板将所有数据科学功能掌握在您团队的手中。用户可以对图像、视频、音频和文本文档执行视觉质量检查、面部识别、内容审核或预测性维护。他们还可以对 Instagram 视频进行分类,进行社交监听,通过视频监控他们的工业过程,并自动标记他们的产品图像。简而言之,它是利用中型公司数据的终极工具!
谷歌云 ML
Google Cloud ML 提供了同样的价值,但是使用了更大的用例列表和 Google 强大的技术。您可以分析和处理呼叫中心的音频数据,访问高级视觉识别技术,以及阅读非结构化文档。谷歌云环境的好处是,你可以在任何平台上集成你的应用程序,依靠预先训练的、最先进的 API 和可解释的模型。另一方面,这些解决方案不太容易获得,因为它们主要面向有经验的数据科学家工程师。
克拉里菲
Clarifai 的深度学习解决方案帮助您利用各种数据源潜力。无论是注释你的视频和文本,提供相关的搜索系统,还是在边缘为你的视觉监控和监视系统提供动力,Clarifai 的人工智能模型都是多功能的。它们让您的所有业务数据为您服务,并让您可以在单一平台上获得洞察力。您的团队拥有立即采取行动和预测威胁所需的一切。
这就是最好的无代码人工智能工具,让你的团队拥有数据智能。
客户终身价值的最佳 SQL 模板
原文:https://towardsdatascience.com/the-best-sql-template-for-customer-lifetime-value-56978b062c0b
用于 RFM 和 CLV 分析的可重用 SQL
图片来自 energo epic . com:https://www . pexels . com/photo/black-payment-terminal-2988232/
介绍
在过去 10 年的职业生涯中,我与各种客户、行业和数据集一起研究客户终身价值(CLV)模型。有许多不同的方法来解决这个问题,但是这篇文章不是关于这个的。相反,我想解释一下数据设置,这在博客圈经常被忽视。
在我的上一篇博客文章中,让我们用 SQL 走得更远,我谈到了我对结合 jinja 和 SQL 的潜力感到多么兴奋,以便利用 SQL 代码本身之上的语义抽象。这篇文章是最近在我脑海中出现的许多想法中的第一个。我的目标是(1)向您展示 CLV 模型的数据准备可以在 SQL 中完成,但更重要的是,(2)为您提供一个可以在其他地方应用的模板,这样您就不必真正从头开始编写 SQL。
入门指南
预测 CLV 最常用的概率模型是贝塔几何/负二项分布模型(通常缩写为 BG/NBD)。它有一个流行的表亲,帕累托/NBD 模型。这些模型试图预测给定客户的未来交易。 Gamma-Gamma 扩展模型关注的是那些交易的金额货币方面。
今年,全世界成百上千的数据科学家将建立这种模型。
他们将如何开始?你会如何开始?如果你是诚实的,第一步可能是谷歌它,阅读一些博客,然后跟随你自己的数据。如果你能在网上找到一个足够好的例子,你就能以一种类似于博客文章的方式有条不紊地操作你的数据,直到你足够接近它,你就可以开始运行了。
一个熟悉的模式出现了
如果你读了足够多的博客,你会开始意识到有一个熟悉的模式。所有这些都是从将数据处理成特定形状开始的——通常称为 RFM 表 。
还有其他方法来计算 CLV,我不打算讨论这些。我主要关注的是 RFM 表,因为它不仅是一种非常流行的方法,而且是非常可重复的。如果你不熟悉 RFM 餐桌,可以看看我的朋友奥卢布库诺拉·阿金索拉在 T2 的博客文章。
基本要素是:
R —客户从该企业购买的最近日期
F —客户从该企业购买的频率
M —客户购买的货币价值。
选择 SQL
如果您读过我以前的博客文章,那么您已经知道我热衷于利用 SQL 来利用数据仓库的处理能力。为了创建 RFM 表,我们需要从原始事务级别聚集数据,这可能是我们数据库中最大的表之一。虽然确实有很多可用的 python 解决方案,但当我有一个非常好的数据仓库时,为什么要费心去卸载数百万或数十亿的事务,而这些事务可能甚至不适合我的 python 内存呢?
使其可重复
在接下来的几节中,我将演示一个示例,该示例从我在网上找到的销售数据集中创建一个 RFM 表。然而,这意味着任何人在将来偶然发现这篇文章,仍然要仔细重写 SQL 以匹配他们自己的数据库。
这就是金贾发挥作用的地方。Jinja 是一个有 14 年历史的模板引擎,主要用于动态生成 HTML、XML 和其他标记格式。最近,它被证明是 SQL 的强大伙伴,被 dbt 和 Rasgo 所利用。如果你想阅读基础知识, Julien Kervizic 在 2019 年写了一篇名为Jinja the SQL way of the Ninja的预言性文章。
因此,我不只是分享 SQL 代码和逻辑,而是将它带到下一个层次——我将分享一个模板,您可以使用它来为您的自己的数据动态创建 SQL。
浏览一个例子
让我们从 UCI 机器学习库中获取一些销售交易的例子。
原始交易数据的示例
我处理这个问题的方法是首先构建 SQL。这一部分显然很有挑战性,但我这样做是为了让你不必如此。下面是工作的 SQL。
这个查询的结果是一个格式正确的 RFM 表,就像我们需要开始我们的 CLV 建模一样。
结果-RFM 交易汇总
成为一名忍者
为了构建我们的 RFM 表,我们需要一个要聚合的事务表。在这个表格中,我们需要找到的是:
- CustomerID —唯一标识客户的列
- TransactionID —唯一标识交易或购买的列
- 交易日期—标识交易日期/时间的列
- TransactionAmount—标识交易的货币值金额的列
由于我们的目标是最终建立一个模型,我们还必须考虑一段时间的培训,以及随后的一段时间的验证/拒绝。
- 观察结束—我们认为数据结束的日期(维持结束)
- TrainingPeriodEnd —我们将培训的结束与维持的开始分开的日期
从我们的示例数据中,我们知道这些:
下一步是创建一个与 jinja 兼容的 SQL 模板,这样我就可以在不同的项目和客户中重复使用。
因为代码很长,我将用一个简短的例子来解释这是如何做到的。如果我们最初的查询是:
SELECT CustomerID
FROM tblCustomers
我们想创建一些参数,比如,
- 列名
- 表名
那么我们的 jinja 模板将是:
SELECT {{ column_name }}
FROM {{ table_name }}
因此,我将整个 CLV-RFM 查询参数化,以便我们将来可以在任何事务表上运行它。
为了渲染 jinja,有大量的在线渲染器,或者你可以使用 python 包jinja2.
个人来说,我使用 Rasgo 来渲染模板。
用 Rasgo 渲染 SQL 模板
这里是完整的代码,准备好了!只需插入您自己的表名、列名,这将动态呈现为您的数据定制的 SQL。
结论
我真的为 SQL 模板的可能性感到兴奋。事实上,我已经有了一些其他的想法。例如,时间序列问题通常需要类似的数据准备步骤,
- 删除负销售额
- 为没有销售额的日期添加行
- 向前填充那些缺失行的最后已知值
- 添加滞后和基于窗口的聚合
我认为这听起来像是另一个模板的好候选。
你能想到什么吗?想投稿?请让我知道!
NLP 眼中的圣经(上)
原文:https://towardsdatascience.com/the-bible-under-the-nlp-eye-part-1-416dbfd79444
有趣的数据科学项目的第一部分,学习更多关于文本处理、NLP 技术以及从文本语料库中提取有意义的信息。
图片由 Pascal Debrunner 在 Unsplash 上拍摄
由于复活节即将来临,我想到了一个有趣的数据科学项目,将 NLP 技术应用于圣经。圣经可以从古腾堡计划https://www.gutenberg.org/cache/epub/1581/pg1581.txt(古腾堡许可)免费下载文本格式
《杜埃-兰斯圣经》是从拉丁文圣经翻译成英文的,总共有 74 本。圣经的第一部分是旧约,共 46 卷,讲述了以色列人的历史(摩西五经),善恶之分(智慧书),以及先知书。第二部分是新约,28 本书,讲述了基督和他的门徒的历史以及地球的未来,直到天启。这部分的主要书籍是马可福音、马太福音、路加福音、约翰福音和启示录。
这个项目希望温和地介绍 NLP 世界,带领读者经历每一步,从清理原始输入数据到获取和理解书籍的显著特征。在这第一部分中,我们将处理:数据清理,从语料库中提取数据,以及 Zipf 定律。
开始前
这是两篇文章中用到的所有包:
import re
import nltk
nltk.download('stopwords')
from nltk.corpus import stopwords
import glob
import string
import gensim
from gensim.corpora import Dictionary
from gensim.utils import simple_preprocess
from gensim.models import CoherenceModel, Phrases, LdaModel
from gensim.models.ldamulticore import LdaMulticore
import pandas as pd
from num2words import num2words
import numpy as np
from wordcloud import WordCloud
from sklearn.feature_extraction.text import CountVectorizer
import seaborn as sbn
from matplotlib.pyplot as plt
from scipy.stats import hmean
from scipy.stats import norm
因此您可以提前安装,只需导入一次。
预处理
预处理是第一件事——我们应该牢记在心!在这里,原始输入文件被清理,书籍被细分为单个文件。我进行了一次简单的手工清理,取出了每本书的介绍、书名和简介,以及最后的古腾堡末日免责声明。在这一步之后,每本书都从图案Book_name Chapter 1
开始,伴随着诗句、数字和文本。
图 1 显示了我是如何将所有的书分成单个文件的。使用.readlines()
将输入文件作为单个字符串读取。旧约全书在old_books
中,multinames
列表表示所有有多个版本的书籍(如The First Book of Kings, The First Book of Paralipomenon
等)。
图 1:开始打扫卫生,收集书籍的索引。这些索引有助于以后保存每本书。
对于以Chapter
开始的每一行,我们提取book_name
。对于multinames
的书,我们在每章的开头都有模式1 Book_Name Chapter 1
,所以我们从val.split()[1]
行中提取下一个单词。第一次出现的Book_Name Chapter 1
标记了书的起始索引。当current_book_name
不同于存储的tmp_book
名称时,检索结束索引。因此,字典books_idx
包含图书名称、起始索引和结束索引(例如{"Genesis":[0, 5689], "Exodus":[5689, 10258], ... }
)。从索引中,我们可以选择原始lines
中的所有书籍,并将它们保存到一个txt
文件中
如果没有不同的说明,输入文本已经以这种方式被清除,并作为字符串存储在data
列表中:
图 2:输入书籍的清洁。每本书都要清理数字诗句模式、名称和章节号、标点符号、新行、停用词。
对于每本书来说,诗句的数字模式NUMBER:NUMBER. text
都被移除了re
以及与数字组合\d{1,}
匹配的正则表达式r"\d{1,}\:\d{1,}\.
、半列\:
和最后一个点\.
。同样,图案Book_name Chapter NUMBER
被移除。最后,所有的文本都被转换成小写,标点符号以及停用词被删除。
获得一个初步的想法:wordcloud
对圣经中的主题和反复出现的词语有一个初步的概念是一个完美的起点。Wordcloud 以人类可理解的方式显示文本中出现最频繁的单词。所有的圣经书籍都可以压缩在一个big_string
中,生成一个单词云WordCloud(width=IMAGE_WIDTH, height=IMAGE_HEIGHT, max_font_size=FONT_SIZE).generate(big_string)
:
图 3:从所有的书籍中创建一个单词云。WordCloud 的输入参数是一个字符串
图 4 显示了所有书籍的文字云。话题可以立刻被发现,还有lord
、god
、come
、son
、isreal
、king
等关键词
图 4:所有圣经书籍中的文字云。作者图片
我们可以做得更多,为每本书提取一个词云。图 5 显示了旧约的前三本书《创世纪》、《出埃及记》和《利未记》中的文字云的比较。我们可以清楚地认识到主要元素和差异。《创世纪》以earth
和god
开始,其中said
到Abraham
不吃树上的果子。从那里我们可以定义亚伯拉罕的其他后代,比如Joseph
、Isaac
、Brethren
。在《出埃及记》中,主角是Moses
和Egypt pharao
。最后,在利未记中,主题是holocaust
,所以我们会有sacrifice
、blood
、victim
、flesh
和offer
这样的词
图 5:旧约前三卷中的字云比较。作者图片
我将留给你们去分析和观察福音书的词汇云的不同,并欣赏福音书、创世纪和启示录(这是最后一本圣经,可能是在基督后 100 年写的)之间的音调差异。
数字符号
因为圣经来自口头传统,所以有许多重复出现的模式。此外,还有很多象征意义。每个词在特定的上下文中都有它的含义。这同样适用于数字。数字被用来表达一个概念——例如“七倍多”或“七十七倍”通常被用来表示“很多”——并构成了一个独特而有趣的有待发现的特征。此外,在文本中查找数字是学习正则表达式的好方法,也是获取数字的小技巧。
任务是在文本中找到简单的英文数字。第一种简单的方法是将整数转换成字符串,将文本分割成空格以得到一个分割列表,并计算每个分割列表出现的次数。图 6 总结了这种方法。首先,我们用num2words
将数字转换成字符串,并存储在一个列表中。在数据被清理(如上)后,我们可以计算每本书的每个数字出现的次数。在 Google Colab 笔记本上,这个过程对于 100k 个号码来说大约需要 12 秒。到目前为止还不错,但是,我们可以立即看到,最终的字典充满了大多数数字的 0 出现。此外,大多数找到的数字都在 0 到 20 之间。这是由于我们如何分割字符串以及如何将一些数字转换成字符串(例如,我们可能在数字列表中有 twenty-one
,但在文本中应该是twenty-one
)
图 6:在文本中查找文字数字的第一种方法
我们可以使用 Python 模块re
并构建一个正则表达式来改进这种方法。我不想教你如何创建一个正则表达式,有大量的源代码,记住如何创建一个正则表达式通常是没有用的。我想把我们的注意力集中在如何处理这个过程上。
我们的想法是创建一个正则表达式,它可以匹配给定书籍中的所有数字。正则表达式的核心部分可能类似于\b(numb1|numb2|numb3)\b
。图 7 显示了对包含以下数字one, twenty thousand, three thousand thirty four, three thousand five hundred forty five
的字符串的测试。因此,我们可以构建一个包含数字的正则表达式,并像re.findall(regex, test_text)
一样对测试字符串运行它。超级简单,但是结果非常错误,因为找到的数字是one, twenty, three, thirty four, three, five, forty five
。正如您所看到的,regex 是如何在找到匹配后立即停止的。这不是我们想要的。我们可以做一些更隐蔽的事情,颠倒正则表达式的顺序,在开头使用“罕见”的数字,在结尾使用小的“频繁”的数字。如您所见,结果是正确的,返回了我们想要的数字。
图 7:用正则表达式获取文字数字。记住:在正则表达式中,顺序是非常重要的!
有了这个方案,我们现在可以在圣经中查找数字,对从num2words
转换来的数字增加一点预处理,如图 8 所示。正则表达式在 2 秒内创建,而运行匹配位需要 1 分 30 秒。在这种情况下,最终的字典match_dict
将包含比我们之前的方法更重要和有用的信息,因为每本书都将记录正确的数字,避免大量的 0 值。然而,创建这样的正则表达式是很痛苦的,而且当我们必须运行匹配过程时,效率不是很高。https://www.rexegg.com/regex-trick-numbers-in-english.html 来帮忙了
图 8:使用逆序/非频繁数字顺序创建一个正则表达式
图 9 示出了我们可以创建正则表达式来匹配简单的英文数字,通过简单地使用字面数字构造,例如f(?:ive|our)
并且定义从 0 到万亿中的万亿的数字,而不用在存储器中存储任何东西或者额外的过程。正则表达式的创建过程大约需要 300 微秒,而匹配过程大约需要 4 秒钟!
图 9:寻找数字的正则表达式,利用简单的英语规则
如你所见,最后一种方法是成功的方法。它更容易移植,不需要对数字进行额外的处理,而且比我们的第一种方法计算效率更高,可以返回完全正确的信息。
如果我们分析最终的匹配词典,我们可以看到Numbers
是——不出所料——拥有最多数字的书,632 本。第二本书是Genesis
,508,而Apocalypse
有 323 个数字,比《新约》中的任何一本书都多,其中seven
重复了 76 次,one
重复了 72 次。圣经中的最高数字是 800'000,它出现在撒母耳记下第二卷,24:9(旧约):
约押将百姓的总数奏告于王,以色列拿刀的勇士有八十万,犹大拿刀的勇士有五十万。
从输出字典中,我们可以通过pandas.DataFrame
比较所有结果,并以直方图显示它们(图 10):
图 10:从输出字典创建一个熊猫数据帧。选择主要帐簿并创建直方图
我们可以比较圣经的主要书籍,即Genesis
、Exodus
、撒母耳记下第一、二卷(1Kings
、2Kings
、Psalms
、Isaias
、福音书:Mark
、Matthew
、Luke
、John
和最后一卷Apocalypse
图 11:比较主要圣经书籍中常见数字的直方图。作者图片
10、1、7、2、3、4 和 6 是圣经中常用的数字。特别有趣的是注意到seven
在Genesis
(第一本书)和Apocalpyse
(最后一本书)中的使用
齐夫定律
以美国语言学家乔治·金斯利·齐普夫命名的齐普夫定律将单词的出现频率和它们的排名联系起来。特别地,在文本语料库中,任何词的频率与其频率排名成反比。或多或少,出现频率最高的单词是第二高的单词的两倍,第三高的单词的三倍,依此类推。将该定律转换到对数-对数域,结果是作为单词等级和单词频率的函数的线性图。从这里,让我们看看圣经文集是如何与齐夫定律相关联的。
图 12 显示了如何计算每本圣经的词频和排名。首先,我们启动sklearn.feature_extraction.text.CountVectorizer()
来统计每本书出现的所有单词。最终的矩阵计数all_df
可以转换成一个pandas.DataFrame
,对所有出现的单词tf = np.sum(all_df, axis=0)
求和,并从cvev.get_feature_names()
中检索单词。最终的数据帧term_freq_df
将把单词作为索引和一列,这是语料库中单词的总计数。从那里可以在对数尺度上比较词的分布与 Zipf 定律。
图 12:根据圣经语料库计算并绘制齐夫定律
图 13 显示了最终的绘图结果。圣经稍微偏离了 Zipf 的线性。这并不奇怪。事实上,在《圣经》中有许多在自然语言中很少使用的重复词语。有趣的是,chin
这个词只用了一次,在撒母耳记下第二卷 20:9:
约阿布对阿玛撒说:我的兄弟,愿天主拯救你。他用右手抓住阿玛萨的下巴亲吻他。
图 13:圣经语料库与 Zipf 的预期行为略有不同。作者图片
从这里,我们可以更深入地了解圣经中的用词,以便看到主要书籍之间的差异。首先,整部圣经中反复出现的主要词汇是:
lord
出现 8377 次god
出现 5720 次man
出现 2999 次
有趣的是,David
比christ
或Jesus
用的次数多,分别是 1162、992 和 1028,而children
这个词用了 1915 次。
接下来,我们可以检查一下新约和旧约在用词上的差异。表 1 显示了旧约(Old T%
)和新约(New T%
)中单词出现的百分比。我们可以看到lord
、Israel
、king
、people
在旧约中的主要用法,以及它们在新约中对god
、Jesus
、christ
、father
和man
的翻译/转化。
表 1:旧约(旧 T %)和新约(新 T %)出现的百分比比较。
我们可以通过研究单词的出现来探索这种术语上的差异。图 14 示出了如何将旧/新约的单词出现与总比率和旧/新类别比率的正态累积分布函数的调和平均值相关联。这是什么意思?我们可以立即找到独特的词汇,这些词汇是旧约全书和新约全书的主要特征:
- 首先我们计算一个单词率,即单词出现次数,
term_freq_df[0
表示总出现次数term_freq_df['total']
→old_rate
- 类似地,我们计算特定类别的单词率,即使用
term_freq_df[0].sum()
→old_freq_pct
细分单词的出现 - 我们计算
old_rate
和old_freq_pct
之间的类调和平均值 - 从这里我们计算出
old_rate
和old_freq_pct
→old_rate_normcdf
和old_freq_pct_normcdf
的正态累积分布函数 - 最后,我们计算出
old_rate_normcdf
和old_freq_pct_normcdf
之间的调和平均值,以给给定类别的唯一和特定的单词更多的权重
这种方法主要来自于里奇金的惊人文章
图 14:计算旧约/新约单词出现率的调和平均值的 normcdf
如果你画出old_normcdf_hmean
和new_normcdf_hmean
,你会看到图 15,它在左上角突出了所有独特的和主要在旧约中使用的词,在右下角突出了在新约中特别使用的词。
图 15:旧约和新约的谐音。左上角突出了独特和具体的话,主要用于旧约,而右下侧的话,特点是新约。作者图片
从这里我们可以立即看到《旧约》和《新约》之间的语气对比,表 2。在《旧约》中,更普遍的“战争”术语是valiant
和convenient
,故事的特点是“农村”社会。新约强调新的信仰,突出了angels
、charity
和faith
的概念
表 2:描述以下特征的特定术语
作为最后一件事,上面的分析可以适用于所有四部福音书,突出了每部福音书的特征词。福音书写于不同的时代,最古老的是马可福音,其次是马太福音、路加福音和约翰福音。接下来会有不同的写作风格,以及每种风格中使用的更具体的词语。约翰福音似乎是最“天主教”的福音,用的术语指的是现在的教会:flesh
、glorify
、paraclete
、truth
。我们将在下一篇文章中回到这个话题:)
今天是一切:)
第一部分的结论
让我们回顾一下今天的内容:
- 我们学习了如何预处理原始文本输入,为 NLP 分析做好准备,并将其保存到不同的文件中
- 为了初步理解我们的数据,我们从这里开始运行
WordCloud
,我们能够识别圣经书籍中不同的主题 - 我们看到了如何处理一个正则表达式问题,用简单的英语找到一系列数字,以及如何优化最终的解决方案
- 最后,我们对照圣经语料库测试了齐夫定律,并扩展了这一分析,为四部福音书中的每一部定义了独特的词汇
下次我们将运行主题建模、单词嵌入和文本嵌入以及文本相似性。敬请期待:)
通过我的推荐链接加入 Medium,支持我的写作和项目:
https://stefanobosisio1.medium.com/membership
如果有任何问题或意见,请随时给我发电子邮件:stefanobosisio1@gmail.com 或直接在 Medium 这里。
NLP 眼中的圣经(下)
原文:https://towardsdatascience.com/the-bible-under-the-nlp-eye-part-2-df2559cdae5f
我们的 NLP 探索的第二部分:通过 TF-IDF 和 transfomers 的主题建模、单词嵌入和文本相似性
西蒙·伯杰在 Unsplash 上拍摄的图片
欢迎回到 NLP 世界的介绍。如果您错过了 NLP 介绍的第一部分,请单击此处:
今天我们将探索新的自然语言处理工具,来分析圣经:
- 主题建模:从文档(圣经书籍)到主题
- 单词嵌入:如何获得嵌入,我们能从这种方法中得到什么信息?
- 文本相似性:福音书之间有多相似?我们可以使用什么技术来检测相似性,文本相似性意味着什么?
在这里你可以找到每个主题所需的所有软件包——更多软件包将在文章中给出。当在这里时,我已经为原始数据定义了预处理和清理代码
主题建模
数据科学家通常采用主题建模来从非结构化数据中获得洞察力,检索关键和简明的信息(例如,评论、医疗文档、机器信息、元数据)。在商业中有无数的主题建模的例子,从总结评论到在客户电话中发现商业问题。具体来说,有两个主要的主题建模策略:1)非负矩阵分解(NMF)——这是我关于 NMF 及其实现的文章——以及 2)潜在狄利克雷分配(LDA)。
在本教程中,我们将使用 LDA。LDA 的根源在于 2003 年的一篇论文(是的 19 年前!)发表在《机器学习研究杂志》上,作者大卫·布雷、吴恩达和迈克尔·乔丹——三位伟大的人工智能/人工智能作者。我将写一篇关于这种技术的文章,因为我喜欢它,但是,我很乐意让你抓住 LDA 工作的这个基本概念:可交换性。可交换性是一个简单的数学假设,1985 年和 1990 年的论文。根据意大利 Guido De Finetti 定理,任何可交换随机变量的集合都可以表示为混合分布。简而言之,我们可以在不考虑文档中单词顺序的情况下建立主题模型。有了这个定理,我们可以通过混合分布捕获重要的文档内统计结构。
让我们从旧约开始,通过像我们在第一个教程中所做的那样清理和分组所有的书,让我们看到所有书的主题。图 1 显示了对旧约全书执行 LDA 的工作流。
图 1:根据旧约全书搜索 LDA 的函数和参数。
首先,在第 60 行,我们对每本书执行一个gensim.utils.simple_preprocess
,它被视为一个唯一的字符串/句子。其次,我们将创建一个字典,其中有一个单词索引映射(例如,单词allowed
在 LDA 算法中表示为0
)。一旦映射id2word
我们就可以创建一个“单词袋”,字面意思就是装满单词的袋子。corpus
返回每个文档中每个单词的出现频率。最后,我们用gensim
到gensim.models.ldamodel.LdaModel
运行 LDA 算法
现在,让我们花一点时间来看看我们是如何运行 LDA 的。LDA 理论清楚地表明,我们需要给出我们期望的主题的输入数量。此外,我们还有一些其他超参数,例如,块大小和每次循环的迭代次数,循环次数。在这个例子中,我试图探索主题的数量和组块的大小,以找到最佳主题。然而,等一下,我们如何衡量一个成功的主题建模?嗯,我们有两个很好的指标可以帮助我们进行主题建模:perplexity
和coherence
。
前一个度量是预测性度量,并且它与模型交叉熵相关联。perplexity
在训练集上训练后,评估模型预测测试集主题的良好程度。很难给这个分数一个正确的解释,通常越负面越好,但是已经证明perplexity
没有一个明确的人类解释。第二个指标,coherence
,通过测量主题的可解释性来帮助我们——在更人性化的意义上,通过测量主题中的单词与文档中的单词的相似度。作为一个建议,在所有这些中,总是需要一点点人类的解释,所以不要过分地用分数来偏见自己。
事实上,这应该是你能得到的最好结果:
Num Topic 4 and chunksize 20 Computing LDA with 4 topics, 20 chunksize...
Writing classification onto csv file...
Topic Keywords
['lord, saith, land, god, israel, people, shalt, king, man, day' 'lord, israel, king, god, said, son, house, people, juda, jerusalem' 'god, man, lord, things, heart, good, wisdom, men, fear, soul' 'king, great, jews, us, men, kings, daniel, kingdom, came, day']
正如你所看到的,前两个主题有着或多或少的相同含义,它们指的是应许之地,以色列或犹大家(或多或少在地理上)。第三个需要一点解释,它可能是指上帝的智慧以及人类应该如何敬畏上帝,或者是上帝和人类之间的相似性。最后是混合了丹尼尔的故事,以及有一天国王会到来的预言。
让我们对新约也这样做:
Num Topic 3 and chunksize 20 Computing LDA with 3 topics, 20 chunksize…
Writing classification onto csv file…
Topic Keywords
[‘said, jesus, man, god, things, come, therefore, lord, came, say’ ‘god, christ, also, things, jesus, may, lord, faith, sin, according’ ‘god, earth, great, seven, angel, beast, heaven, voice, throne, come’] Perplexity -7.394623212885921 Coherence 0.4202057333015461 Num Topic 4 and chunksize 50 Computing LDA with 4 topics, 50 chunksize…
Writing classification onto csv file…
Topic Keywords
[‘said, jesus, god, man, lord, things, come, came, saying, say’ ‘god, christ, also, things, lord, jesus, man, may, faith, according’ ‘god, earth, great, seven, come, heaven, angel, saying, things, beast’
‘god, christ, sin, law, faith, jesus, son, also, spirit, things’] Perplexity -7.347456308975332 Coherence 0.3708218577493271 Num Topic 5 and chunksize 50 Computing LDA with 5 topics, 50 chunksize…
Writing classification onto csv file…
Topic Keywords
[‘said, jesus, god, man, lord, things, come, came, saying, also’ ‘god, christ, also, things, lord, jesus, man, may, faith, according’ ‘god, earth, great, seven, come, heaven, angel, saying, things, beast’
‘god, christ, sin, law, spirit, jesus, faith, also, son, world’ ‘jesus, things, god, christ, may, men, saviour, good, also, lord’] Perplexity -7.353096888524062 Coherence 0.3734882570283872
如您所见,许多主题相互重叠。我个人认为 3 个主题足以区分所有的新约主题。前者said, jesus,man, god, things, come, therefore, lord, came say
指耶稣的寓言;第二个话题god, christ, also, things, Jesus, may, lord, faith, sin, according
可能是指对上帝的信仰和耶稣为人类的罪所做的牺牲;最后一个话题指的是天启god, earth, great, seven, angel, beast, heaven, voice, throne, come
总之,主题建模是理解文档中引入的关键词和主题的一种很好的技术。我们不能用一种简单的方式来衡量主题的正当性,但是我们必须采用perplexity
和coherence
,无论如何,如果没有足够的人类解释,这是不够的。从旧约和新约,从应许之地到启示录,衍生出三个主题。我们能做更多来整合主题建模吗?当然,我们可以在单词嵌入上运行主题建模——我会把这个练习留给你来解决:)
单词嵌入
现在让我们来看一些更复杂的东西:单词嵌入。许多(显然)单词和文章都花在了单词嵌入上。简而言之,单词嵌入允许我们将多维单词、句子和文档简化为人类可解释的含义和计算有效的向量。一个向量可以有大量的维度,但是当所有的单词都投影到向量上时,就有可能将它们聚集在不同的类别中,从而解决并大大简化真正的大规模问题,并找到单词之间的有趣关系。
对于单词嵌入,我们需要以下附加包:
from sklearn.manifold import TSNE
from collections import Counter
from six.moves import cPickle
import gensim.models.word2vec as w2v
import numpy as np
import tensorflow as tf
import matplotlib.pyplot as plt
import multiprocessing
import os
import sys
import io
import re
import json
import nltk
nltk.download('punkt')
然后,我们将计算嵌入并创建一个w2v
文件来保存来自gensim.w2v.Word2Vec
的二进制单词嵌入
图 2:使用 gensim word2vec 函数从一系列文档中计算给定文本的单词嵌入表示。在这种情况下,我们正在处理新约全书
现在,我们想把这个多维向量形象化。一种常用的方法是使用 t 分布随机邻居嵌入或 t-sne,这是一种非线性降维技术。下面的代码将给我们一个在 2D 嵌入向量的单词:
图 3: T-SNE 函数表示二维的单词嵌入。最初,t-sne 是基于单词嵌入表示来计算的。然后检索最频繁的单词并收集最相似/相关的单词。最终的图表显示了一个单词与其他单词的关联程度
代码很长,所以我们要做的是:
- 首先,我们通过带有
calculate_t_sne
的 t-sne 减少二维的单词嵌入,产生x_coords, y_coords
和labels
(它们是单词) - 我们用
Counter().most_common()
计算单词的频率 - 对于前 50 个最常用的单词,我们将通过
most_similar
检查这些单词是如何与 word2vec 词汇表中的其他单词向量相关联的。最终,我们为 50 个最常用的单词返回一系列列表,并为每个单词返回相关的单词。 - 在这一步之后,我们将这一系列列表转换为 t-sne 空间中的 x 和 y 坐标,并绘制最终结果。
在我看来,图 4 显示了 word2vec 的全部力量,我们可以清楚地看到摩西之间的正确联系。我们有Sinai
、Commandment
、Observance
(至十诫)、Pharaoh
图 4:圣经中单词嵌入的 t-sne 图。在这种情况下,摩西与他故事的所有元素都有关联
图 5 显示了单词 Death 的另一个特殊的单词嵌入。我们可以看到Life
处于完全相反的位置,而在它们之间有revenge
、crimes
、sickness
、danger
和confusion
图 5:圣经中单词嵌入的 t-sne 图。在这种情况下,死亡与他的故事的所有元素相关联
图 6 是我们用 word2vec 得到的信息的最后一个例子,单词evil
在相反的方向,我们将得到hope
,有趣的是看到邪恶在整个圣经中是如何联系在一起的。邪恶是错误的,它与疾病、邪恶和虚荣联系在一起。
图 6:圣经中单词嵌入的 t-sne 图。在这种情况下,邪恶与他的故事的所有元素相关联
总而言之,单词嵌入可以给你单词间隐藏的联系。在真实的场景中,单词可以是评论、产品、搜集的数据,你可以通过嵌入建立重要的联系。此外,单词嵌入可以而且应该与主题建模一起使用,以进一步利用单词关联来发现更多可解释的主题。
文本相似度
圣经最受讨论的一个方面是书籍的重叠和相似,尤其是福音书。事实证明,马可福音 76%的内容是在马太福音和路加福音中共享的。此外,马太和路加分享了大约 50%的内容。稍有不同的是约翰福音,它是在将近 100 年后写成的,写作风格与天气福音相去甚远。
您可以尝试的第一种文本相似性方法是运行术语频率-逆文档频率或 TF-IDF。在这种方法中,我们将考虑整个语料库中的词的频率,而不是单个文档(例如,整个圣经而不是单本书)。关键是,在任何地方出现次数多的词,意义会低,而出现次数少的词,可能有意义。TF-IDF 的实现用scikit-learn
很简单,如图 7 所示
图 7:sci kit-learn 中的 TF-IDF 实现。这里的数据是一个 dataframe,其中每一列都有一篇福音书(约翰福音、路加福音、马可福音和马太福音)
这里的data
是一个熊猫数据框架,每一列都是一个福音。文本通过TfidfVectorizer
处理,最后通过cosine_similarity
ig 计算相似度。记住,当你想测量向量之间的相似程度时,余弦相似度是最好的方法。图 8 显示了四个福音的相似性结果。正如你所看到的,这个情节强烈地指向天气福音的相似性有多强,通过一点计算能力,我们已经对 4 本主要的圣经书籍有了一个很好的看法。
图 8:用 TF-IDF 方法分析四个福音的余弦相似性。我们用一种简单的方法复制了最初在圣经研究中发现的东西
这很好,但我们可以尝试做得更多,分析每本书的上下文内容。使用句子转换器可以实现更精确的方法。在这里,我们可以引用大量的模型,其中最著名的是 BERT 和 Sentence-BERT (SBERT ),它是由一个暹罗网络组成的,用于导出句子嵌入。这里我们不仅要看文本的相似性,还要看上下文的相似性。图 9 显示了实现,由于sentence_transformers
包包含了我们想要的所有相关变压器,所以实现非常简单。我们选择stsb-roberta-large
作为要使用的转换器,并对我们拥有的输入数据进行编码。最后,正如我们之前所做的,相似性是用余弦相似性来度量的。
图 9:通过 sentence_transformers 包实现 roberta transformer,并测量 4 部福音书的相似性。
图 10 显示了用 Roberta 和 wow 获得的结果!,在这里我们获得了新的有趣的信息。我们知道,约翰福音和路加福音的基调与马太福音和马可福音相去甚远,这两部福音书是最早写成的。因此,在上下文层面上,这两部福音书可能有更多的相似之处,出现了其他福音书中没有出现的词汇和概念。看到所有其他福音在上下文层面上彼此大相径庭,真的很有趣。
图 10:四部福音书中变形金刚的上下文层次分析。有趣的是乔恩和卢克有很高的上下文相似性,这可能与写作风格有关。
第二部分的结论
那么,做得好,这是我们的 2 部分教程的结束。让我们回顾一下今天的内容:
- 我们学习了什么是主题建模,以及 LDA 建模的关键数学点是什么:可交换性
- 我们可以做更多的工作来理解单词的含义,并将主题建模中的信息与单词嵌入相结合
- 我们可以用 TF-IDF 这样的简单技术来测量文档之间的文本相似性,或者,如果我们想在上下文层次上研究相似性,我们可以使用奇妙的 sentence_transformers 库并旋转一个 transformer 来测量文本相似性。
从这两个教程中,你肯定学到了很多很多技术,这些技术在你每次开始一个新的 NLP/text 项目时都会有用。我希望您喜欢这一切,并在下一篇文章中尽快见到您:)
通过我的推荐链接加入 Medium 来支持我的写作和项目:
https://stefanobosisio1.medium.com/membership
如果有任何问题或意见,请随时给我发电子邮件,地址是:stefanobosisio1@gmail.com,或者直接在 Medium 这里。
ChatGPT 的碳足迹
原文:https://towardsdatascience.com/the-carbon-footprint-of-chatgpt-66932314627d
意见
本文试图估算名为 ChatGPT 的流行开放式聊天机器人的碳足迹
沃洛季米尔·赫里先科在 Unsplash 上的照片
最近有很多关于 ChatGPT 的讨论,有些人谈论运行该模型的货币成本,但没有多少人谈论该模型的环境成本。
人类活动导致的大气中温室气体含量的增加是气候变化的主要驱动力[8] 。信息和通信技术(ICT)行业和数据中心行业在全球温室气体排放中占有相对较大的份额[9]。
因此,我们——运行在数据中心的数字工具的用户和开发者——需要尽自己的一份力量来减少数字活动的碳足迹,从而缓解气候变化。
为此,最重要的是,我们要意识到,即使是数字产品也需要能源来开发和消费,因此它们会产生碳足迹。这篇文章有助于实现这一目标。此外,在我们讨论如何减少我们的碳足迹时,获取事实信息也很重要,这样我们就可以优先解决那些产生最大碳节约的问题。
最后,我希望这篇文章将激励机器学习模型的开发人员公开他们模型的能耗和/或碳足迹,以便这些信息可以与模型准确性度量一起用于评估模型的性能。
https://kaspergroesludvigsen.medium.com/chatgpts-electricity-consumption-pt-ii-225e7e43f22b
大规模机器学习的环境成本
环境成本可能以各种形式出现,例如用水、土壤污染、空气污染。在本帖中,我们将从碳足迹的角度来看看 ChatGPT 对环境的影响。
当确定机器学习模型的碳足迹时,人们可以区分 a)来自训练模型的碳足迹,b)来自一旦被部署就用模型运行推理的碳足迹,c)模型的总生命周期碳足迹。要深入了解如何估计和减少机器学习模型的碳足迹,请参见[9]。
不管范围如何,计算任何模型的碳足迹都需要知道两件事:
- 它消耗的电量
- 这种电力的碳密度
1 在很大程度上取决于运行它的硬件以及硬件的利用率。
2 很大程度上取决于电力是如何产生的,例如太阳能和风能显然比煤更环保。为了量化这一点,我们通常使用硬件所在电网的平均碳强度。
来自培训聊天的碳足迹
如果我理解正确的话,ChatGPT 是基于 GPT-3 的一个版本。据估计,训练 GPT-3 消耗 1287 兆瓦时,排放 552 吨二氧化碳当量[1]。
然而,这些排放量不应仅归因于 ChatGPT,我不清楚如何将这些排放量的一部分分配给 ChatGPT。此外,ChatGPT 已经使用强化学习[2]进行了训练,这应该被添加,但是关于这个训练过程的相关信息是不可用的,并且我不知道任何合理的代理。如果是的话,请给我指出正确的方向。
运行 ChatGPT 的碳足迹
现在,让我们看看使用 ChatGPT 运行推理可能会产生多少 CO2e。我没有遇到任何关于# 1 和# 2 wrt 的信息。运行 ChatGPT。所以让我们来做一些猜测。
大型语言模型 BLOOM 曾经在一个使用 16 个 Nvidia A100 40GB GPUs 的 Google 云平台实例上部署了 18 天[3]。
让我们假设 ChatGPT 使用相同的硬件。由于模型的大小大致相同——GPT-3 和 BLOOM 的参数分别为 175b 和 176b 我们假设 ChatGPT 也运行在 16 个 Nvidia A100 40GB GPUs 上,但运行在 Azure 实例上,而不是 GCP 实例上,因为 Open AI 与微软有合作关系[4]。
由于 OpenAI 的总部位于旧金山,所以我们进一步假设 ChatGPT 运行在美国西海岸的一个 Azure 区域。由于美国西部的电力比美国西部 2 的碳强度低,所以让我们使用前者。
使用 ML CO2 影响计算器,我们可以估计 ChatGPT 每天的碳足迹为 23.04 kgCO2e。平均每个丹麦人每年排放 11 吨二氧化碳当量[7],所以 ChatGPT 每天的碳足迹大约是一个丹麦人每年碳足迹的 0.2%。如果 ChatGPT 运行一年,其碳足迹将为 365 * 23.04 千克= 8.4 吨,约为一个丹麦人年碳足迹的 76%。
每天 23.04 千克二氧化碳当量的估算值是通过假设每天 16 个 GPUs * 24 小时= 384 个 GPU 小时得出的。目前还不清楚,但我认为 ML CO2 Impact 假设硬件利用率始终为 100 %,这在这种情况下可能是一个合理的假设,因为据报道该服务正在经历沉重的负载。
我们应该在多大程度上相信这个猜测?
为了得到一个概念,让我们看看它是如何与布鲁姆的碳足迹进行比较的。
在 18 天的时间里,23.04 千克二氧化碳当量的日排放量将使 ChatGPT 的排放量达到 414 千克二氧化碳当量。相比之下,布鲁姆在 18 天内排放了 360 公斤。事实上,这两个估计值相差不远,表明 23.04 千克二氧化碳当量可能不是一个糟糕的猜测值。
两种排放估计之间的差异可以归结为许多事情,例如布鲁姆和查特 GPT 的电力的碳强度的差异。
同样值得注意的是,BLOOM 在 18 天内处理了 230,768 个请求[3],相当于平均每天 12,820 个请求。如果 ChatGPT 的 100 万用户中的 1.2 %每天发送一个请求,ChatGPT 将会产生与 BLOOM 同期相同数量的每日请求。如果社交媒体和传统媒体上对 ChatGPT 的所有讨论都表明了它的用途,那么 ChatGPT 可能会处理更多的日常请求,因此它可能会有更大的碳足迹。
另一方面,如果 OpenAI 的工程师已经找到一些更有效地处理所有请求的聪明方法,我对 ChatGPT 碳足迹的估计可能会太高。
</8-podcast-episodes-on-the-climate-impact-of-machine-learning-54f1c19f52d>
ChatGPT 全生命周期碳足迹
为了计算 ChatGPT 的总生命周期碳足迹,我们需要考虑训练过程中的排放。可以获得这方面的一些信息,但很难确定 GPT-3 训练排放中有多少份额应归于 ChatGPT。
我们还需要考虑训练数据预处理的排放。此信息不可用。
此外,我们还需要获得生产硬件的具体排放量的估计值。这是一个相当复杂的任务,留给读者来做练习。可以在[3]和[5]中找到有用的信息,前者估计了布鲁姆的总生命周期碳足迹,后者估计了脸书一些大型模型的总生命周期碳足迹。
结论
这篇文章估计运行 ChatGPT 每天的碳足迹为 23.04 千克二氧化碳当量。这一估计是基于一些粗略的假设,因此存在很多不确定性,但与一个名为 BLOOM 的可比语言模型对碳足迹的全面估计相比,这似乎是合理的。
通过提供基于事实的 ChatGPT 碳足迹估计,这篇文章使得关于 ChatGPT 的成本和收益的辩论变得有根据。
最后,本文只关注 ChatGPT 的 CO2 排放量。除了二氧化碳排放,其他类型的环境影响,包括用水、空气污染、土壤污染等。,也是重要的考虑因素。
就是这样!我希望你喜欢这篇文章🤞
请留下评论让我知道你的想法🙌
关注更多与可持续数据科学相关的帖子。我也写时间序列预测,比如这里的或者这里的。
此外,请务必查看丹麦数据科学社区的可持续数据科学指南,了解更多关于可持续数据科学和机器学习的环境影响的资源。
并随时在 LinkedIn 上与我联系。
参考
[1]https://arxiv.org/ftp/arxiv/papers/2204/2204.05149.pdf
[2]https://openai.com/blog/chatgpt/
https://arxiv.org/pdf/2211.02001.pdf
https://arxiv.org/pdf/2111.00364.pdf
[6]https://twitter.com/sama/status/1599668808285028353
[8]https://story maps . ArcGIS . com/stories/5417 CD 9148 c 248 c 0985 a5b 6d 028 b 0277
反对饼状图的理由
原文:https://towardsdatascience.com/the-case-against-the-pie-chart-43f4c3fccc6
为什么它的使用几乎从来没有正当理由
问题是
通过图表和图形可视化定量数据的目的是使数据更容易理解,并从中获得有价值的见解。然而,饼状图往往适得其反,掩盖了所呈现数据的潜在数量。这主要是因为人类更擅长解释长度和高度,而不是从角度估计数量,这是阅读饼图所需的技能。正如统计学家和数据可视化先驱爱德华·塔夫特所说:
…唯一比饼图更糟糕的设计是其中的几个……—爱德华·塔夫特
尽管从各个角度受到了广泛的批评,饼状图仍然是商业、营销和新闻业中使用最广泛的图表之一。这经常导致数据以一种扭曲的方式呈现,结果,读者误解了试图传达的观点。
为了便于说明,下面几节包含一些假设情景,试图传达有关公司年收入的信息。
获得洞察力的困难
推导分数
包含大量切片的饼图将难以确定较小切片相对于较大切片的比例(图 1)。此外,在饼图中有许多小片段会产生标签问题,这只会增加读者理解它的难度。条形图通常是规避这些问题的一个很好的替代品。
表 1:显示五家公司年收入(十亿美元)的综合数据。
图 1:在饼图中,很难确定小切片相对于大切片的比例。例如,在相应的柱状图中,很明显 A 公司的收入是 B 公司的十倍,而 B 公司的收入是 d 公司的一半。
显示时间信息
随着时间的推移,变化是非常难以察觉的。在下图中,无法从饼图中推断出每个切片随时间的变化,而在条形图中,可以立即识别出这些变化。
表 2:显示五家公司连续三年年收入(十亿美元)的综合数据。
图 2.1:看这些饼图,A 公司 2021 年的收入比 2020 年少,然后在 2022 年增加。相比之下,E 公司的收入在此期间似乎相当稳定。事实上,A 公司的收入稳定在 520 亿美元,而 E 公司的收入波动很大。数字基于表 2。
图 2.2:将上述数据绘制成柱状图,可以更容易地发现收入随时间的波动。人们可以清楚地看到 A 公司收入的稳定性以及 e 公司收入的波动性。
注意:如果数据中的时间段更长,则使用折线图可以更有效地传达这一信息。
比较相似大小的切片
当试图比较大小相似的切片时,会出现另一个问题。
表 3:显示五家公司年收入(十亿美元)的综合数据。
图 3:看饼状图,能看出 A 公司和 B 公司的营收哪个更高吗?A 公司和 C 公司,或者 B 公司和 D 公司呢?同样,右边的条形图更有效地传达了这一信息。数字基于表 3。
仅显示两个值
如果你只是比较两个数值,那就没有理由使用饼状图或者其他图表(图 4)。在这种情况下,简单地用数字而不是图表来传达信息会更有效。
图 4:说明两家公司年收入的饼状图。生成图表来传达这种类型的信息是完全多余的。简单地说,A 公司的收入是 520 亿美元,而 B 公司的收入只有 350 亿美元,就能说明问题。
整体的一部分
如果需要显示整体是由什么组成的,树形图通常是更好的选择(图 5)。它不仅避免了读取角度的问题,而且还方便了标记方面,因为矩形比饼图中的楔形提供了更多的空间。如果需要的话,还可以很容易地扩展它们,以显示更多的值。理论上,饼图也可以扩展;然而,在饼的中心会有很多浪费的空间,并且标签问题只会随着饼的增长而加剧。此外,树状图也可以用于多层次数据,因为矩形可以很容易地分成子类别——这对于饼状图中的楔形来说是很困难的。
表 4:显示八家公司年收入(十亿美元)的综合数据。
图 5:右边的树形图使得可视化处理和解释所呈现的信息更加容易。此外,它支持多级数据的显示,更易于扩展和标记。数字基于表 4。
添加效果
在任何情况下都应避免使用 3D 或爆炸饼图(图 6 ),因为这些影响通常会导致数据进一步失真。
图 6:带有分解楔形的饼图。虽然由于我们天生没有阅读角度的能力,解释常规的饼状图已经很困难了,但这种描述进一步加剧了这个问题。数字基于表 3。
不出所料,爱德华·塔夫特对此也有自己的看法:
经常扭曲数据的表面修饰永远也不会弥补潜在的内容缺乏。—爱德华·塔夫特
例外
虽然我强烈反对在大多数情况下使用饼图,但在我看来,有两种情况下饼图可能是有益的:(1)如果唯一的目标是证明一个部分占整体的大多数,以及(2)如果分数正好是 25%或 50%。
关注最大的一块
如果图示的唯一目的是显示一个特定的部分占整体的大部分,或者超过所有其他部分的总和,那么饼图的使用是合理的。这种信息通常很难从条形图中获得,因为您必须手动将所有其他条形图相加才能获得这种洞察力(图 7)。
图 7:在左边的饼状图中,很容易看出公司 A 的收入高于所有其他公司的收入总和。通过分析相应的条形图,很难得出这种见解。
分数是 25%或 50%
虽然这种情况很少发生,但是如果您处理的数据恰好是 25%或 50%(图 8),那么饼图可以很好地说明这一点。
图 8:饼状图说明公司 A 的收入是公司 B 和 c 的两倍。
结论
本文中的插图表明,使用饼图几乎从来都不是一个好主意,在大多数情况下,简单的条形图提供了一个很好的替代品,有助于提取洞察力。虽然 3D 图表或爆炸切片等视觉效果在页面上看起来很花哨,但实际上它们并没有添加任何信息,而且事实上还会进一步扭曲数据。如果需要显示整体的组成,树形图是首选,因为它不需要读者评估角度,支持多级数据的显示,并避免了图表增长时的标记问题。
然而,如果唯一的目的是说明一个特定的切片构成了整体的大部分,或者如果切片的比例恰好是 25%或 50%,那么饼图的使用可能是合理的。
参考
[1]t .蒙兹纳(2015 年)。可视化分析与设计。CRC 出版社。ISBN: 9781498759717。
[2]爱德华·塔夫特,饼状图。【https://www.edwardtufte.com/bboard/q-and-a-fetch-msg? msg_id=00018S 。
[3]墨尔本大学,为什么不应该用饼状图。https://SCC . ms . unimelb . edu . au/resources/data-visualization-and-exploration/no _ pie-charts。
混合数据组织的案例
原文:https://towardsdatascience.com/the-case-for-a-hybrid-data-organization-bb6dc6211acf
数据组织
混合数据组织的案例
在各种形状和规模的数据组织中工作或与之共事 15 年的经验
过去的 15 年是一段有趣的旅程。我在几个不同的部门、国家和产品中工作,有幸参与了数据行业在这段时间里发生的令人难以置信的变化。
让我印象深刻的一件事是我参与(或合作)的数据组织的形状、大小和职权范围,以及它们对公司运营、产品和客户的影响程度。
举几个例子:一个人处理几千兆字节的数据,小型数据团队处理几千兆字节的数据,企业拥有众多国际互联的数据团队。
在每一种情况下,公司(或大型部门)都以自己独特的方式实现他们的数据组织和系统,随着时间的推移,随着需求的增加而进行调整和创新。然而,根据公司的属性,如规模、预算、成熟度、地理位置、监管要求等,每种方法都有共性、优点和缺点。
本文旨在强调我观察到的三种常见的数据组织类型,它们在文献中经常被讨论;集中式、分散式和混合式。最后,我将证明混合动力在许多情况下是理想的。
首先,我们来回答一个基本问题。为什么公司有某种形式的数据组织?
决策支持!
就本文的目的而言,我将把明确的决策支持数据组织和系统与运营数据组织和系统分开,运营数据组织和系统的存在主要是为了保持诸如法规遵从性之类的正常运行。
对于任何公司来说,数据组织都是一项昂贵的承诺,其预期结果是投资将从更有效的决策中获得正回报。虽然没有个人或公司是完美的决策者,数据本身也不能保证这一点,但公司至少可以努力提高做出更有效决策的机会。
对于一个公司来说,要建立和保持他们的竞争优势,这些决策必须尽可能地有影响力(增长)和有效率(成本),最好是需要尽可能少的决策。换句话说,公司必须不断努力达到最佳决策影响比。
如今,以数据为导向的决策可以延伸到公司的每个角落,并提出了什么类型的数据组织可以支持这种广度的问题。没有放之四海而皆准的方法,但我通常观察到三种类型:
- 集中式 —个人/团队拥有其他行业/团队的数据并为其工作
- 分散化 —每个个人/团队都拥有、成为专家并利用他们自己的数据
- 混合 —以上的组合
有些人可能会争论这些定义,这没什么。这些是我对数据团队和非数据团队合作伙伴之间动态的观察。
让我们看看过去的一些数据组织
请注意,这些都是基于我的经验和观点,并不是对所有可能的数据组织的全面评估。
作者图片
小公司集中一个人的数据带
作者图片
- 公司类型:小型,很少/很少持续的数据支持需求,经常临时运营。系统简单,数据集小。
- 主要任务:基本报告/分析,通常是临时的
- 好处:低成本,开始辅助决策
- 弊端:关键人物依赖,意味着大部分数据技能和知识被锁在一个人身上(流失风险)。一个人也可能过于分散(并可能超负荷),而没有在某个特定领域积累专业知识。
中小型企业中的小型集中团队
作者图片
- 公司类型:具有中等持续数据支持需求和较大、略复杂的系统和数据集的中小型企业。
- 主要职责:更广泛的报告范围,开始有正式的指标/渠道、基本分析、维护数据系统和确保法规合规性。
- 好处:成本仍然相对较低,比单人更具响应性和能力,可以开始支持战略决策。
- 缺点:机会成本使企业中的员工没有建立他们的数据技能和领域知识,而仅仅依靠数据团队。
分散在一家小公司的精通数据的员工
作者图片
- 公司类型:小公司,没有多余资源的初创公司
- :特定领域的报告、计划、分析、实验等。
- ****好处:很少/没有正式的数据资源成本除了数据系统之外,员工(应该)成为其数据、产品和客户的完全所有者和专家,这应该能够实现更好、更有效的自主决策。
- ****缺点:学习和使用数据和工具而不是执行其他日常任务的潜在机会成本,数据系统和法规合规性更难维护
中小型企业中分散的精通数据的员工
作者图片
与分散的小公司非常相似,但具有放大的属性。
此外,没有一个这样规模的实体来粘合所有团队,并提供统一的输出和跨公司的叙述可能会成为一个问题。每个团队也可能变得过于孤立,不共享知识,并且在没有沟通的情况下做出影响其他团队的决策。员工可能会陷入忙碌的陷阱,无法频繁或充分地学习或使用他们的数据来增强决策。
简单混合中小型企业/企业
作者图片
- ****公司类型:中小型企业和企业,他们需要团队实现大部分数据自治,但也承认需要专家来支持数据系统和执行更深入更复杂的工作。
- ****主要职责:更高级的报告和分析,潜在的数据科学公司,机器学习和统计建模,实验支持,维护数据管道和监管。数据团队可能开始在高管层拥有一席之地(想想首席数据官)。
- ****好处:公司中大多数精通数据的员工应该能够提高他们的决策能力,同时也能够与专家合作来加强这些决策或卸载更复杂的工作。数据管道应该更加稳健、全面和合规。
- ****缺点:在这个阶段,人员和系统可能是一项重要的投资,尽管从理论上来说,这项投资应该会产生净收益。工作人员仍然会陷入忙碌的陷阱,没有足够频繁或深入地学习或使用他们的数据,或者将太多内容转移给数据团队。
多专业混合型企业
作者图片
与“简单”相同,但有多个数据团队,每个团队有不同的专长,例如,一个团队可能负责报告,另一个团队负责数据管道,另一个团队负责回答复杂问题的数据科学。
相对于简单混合模式的额外好处是角色更分散、更集中。例如,数据科学家可以更高效地完成工作,而不必同时做行政报告或管理管道。然而,在这种情况下,不利的一面可能是他们失去了业务中正在发生的事情的背景/可见性。
分布式混合企业
作者图片
与 simple(可能是多专业)相同,但公司足够大,可以保证每个部门都有自己的数据组织,因此增加了专业性,但每个部门(应该)一起工作以保持同步。
分布式混合企业与中央“粘合”团队。
作者图片
与分布式相同,但有一个独立的数据团队,将所有其他部门粘合在一起。部门数据团队专注于本地,中央团队处理跨部门的综合报告和分析,包括针对高管层的汇总叙述。该团队还可能维护一个集中的数据存储库,其中包含同质的部门数据。
共性总结
正如我们所见,没有固定的定义,也没有一个单一的定义适用于所有公司。下表旨在总结一些观察结果和共性:
作者提供的表格/图片
为什么沥青要进行杂交?
除了增强决策能力之外,还有三个主要原因:
1.协作影响(1+1=3)** —精通产品和客户的员工与解决复杂性和/或跨公司凝聚力的专家的结合,应该会在整个公司产生更有效的决策。**
2.治理和合规** —保留数据团队可以减轻员工的压力,让他们专注于自己的工作而不是系统,并确保数据得到治理(一致、准确和可信)和合规(想想 GDPR/CCPA/COPPA/HIPPA 等。).**
3.对每个人都有好处** —每个人都是自己产品、客户和各自数据的专家,可以培养更好的产品经理,促进学习和个人成长,企业中的其他人也应该通过潜移默化而受益,公司有望更加成功。**
(可选阅读)让我们来看一些场景,在这些场景中,混合动力车可能比其他车更有意义
一家小型创业公司
假设你是一个初创公司的创始人,即将从一个人的公司扩张到十个人的公司。你有足够的种子资金来开发你的想法,并将其投放到市场,但没有太多了。但是,您知道您需要数据来做出更有效、更快速的决策,并且已经拥有了基本的现成数据管道,能够进行简单的报告和分析。但是由于您缺乏资源,您将需要(目前)所有员工成为各自数据领域的专家,并执行大部分自主决策。所以,这应该是一个分散的模式,员工可以“凑合”吧?
也许不是。这些员工还能抽出时间和机会成本来维护数据管道、构建/监控/修复产品遥测、创建和分析出色的客户调查、建立营销活动系统、确保遵守所有法规、制定深入的季度/年度报告等吗?
请记住,根据严重程度,即使一次违反 GDPR 法规的行为也会使您的公司损失 2-4%的年收入。
让 1-2 名数据工作者组成一个小型混合数据组织来帮助处理上述大部分工作,同时确保 10 名员工仍然是他们数据的专家,这可能是值得的。
中间业务
假设您刚刚被一家 1,000 强公司聘用为首席数据官(CDO),负责建立其首个数据组织。该公司是成功的,势头强劲,但并不认为这是理所当然的。他们知道他们需要构建并更好地利用他们的数据资产来保持竞争力和合规性。
企业周围的员工大多根据个人判断和电子表格中的基本数据做出大多数决策,因此还没有形成数据文化。因此,最简单、最快捷的解决方案是建立一个集中的数据团队,您可以尽快开始运行并生成输出。对吗?你终究会勾选你的汇款的基本方框。
还是你有?您的团队资源有限,因此除了团队的日常任务(如管理数据管道和法规遵从性责任)之外,您无法满足业务中每个人的决策需求。所以,你没有有意义地改变现状。大多数员工仍然很少使用数据(并且可能没有动力使用),并且您所取得的大部分成果是进一步将一些责任卸载/转移到您自己的团队。该公司肯定处于一个更好的状态,但你有一个革命的机会,而不是进化。
相反,如果你承受了短期的痛苦,领导业务范围的计划,以建立一种数据主导的文化,通过教育和帮助他们实现利益,使其成为他们日常工作的核心部分,随着时间的推移,你应该实现一种授权和民主化的数据文化。你的团队变得更像一个咨询/增强机制,而不是所有者。
复合系统的案例
原文:https://towardsdatascience.com/the-case-for-composite-systems-11632220ffa8
AI 系统一起更强吗?
卡尔·阿布伊德在 Unsplash 上的照片
T 何按‘意见’没道理。我困惑地盯着我的屏幕,滚动着一页 2020 年最受欢迎的新闻文章中的句子和不那么微妙的广告:像“有些已经这样了”这样的短语、“在这里看最新一集……”,还有“好莱坞万人迷”。
我微调的机器学习模型提取了几十个这样的“观点”呈现给我。从上下文来看,这些短语本身是有意义的——它们是更大的新闻文章的一部分,处理围绕新冠肺炎疫情、教育和娱乐业的叙事。虽然我的机器学习(ML)模型似乎抓住了一些强烈的情绪,但它对更大的画面没有用处。
为什么?我的团队正在为新闻分类构建一个 ML 模型管道。我负责使用 BERT 模型来查找个别文章中表达强烈观点的句子。然后,这些意见将被传递给第二个模型,即 USE,以计算来自 BERT 的意见和相关新闻文章的聚类之间的相似度。
但是 BERT 的输出对于使用模型来说不够相关。
抓耳挠腮,就在那一刻,我意识到我们不只是在寻找强有力的观点——我们在寻找强有力的观点,这些观点有意义。
然后来了一个哈!瞬间。如果我们在将 BERT 模型的输出发送到主使用模型之前,使用一个更小的使用模型对其进行后处理,会怎么样呢?我们将使用这个更小的使用模型来测量由 BERT 模型识别的观点与文章本身的相似性,并且丢弃那些与文章本身语义不相似的观点。所有这些都可以在保持原有管道完好无损的情况下完成。
我们的新闻聚合模型使用复合人工智能来处理我们的假设提取模型的输出——修改自来源(第 3 页)
通过这个小小的技巧使用一个机器学习模型来增强另一个,我开始从我的模型中提取的观点中看到更多的意义:受访者的语录、怀疑和喜悦的表情以及个人轶事。诸如“我在社交媒体上看到了无数的帖子……这是一种特别渴望的逃避现实的方式”“……有人担心他们对……的信仰。”,还有“‘你不可能…’”说…”。
复合系统帮助我的团队从我们的硕士项目的模型中挖掘更多的意义。
这些类型的系统,有时被称为 ML 反馈回路,在学术界和工业界都很流行——事实上,Gartner 最近将复合人工智能确定为一种新兴的技术趋势。但是,对于坐在方向盘后面的数据科学家来说,这些工作流是什么样的呢?
野外的复合人工智能
复合系统并不新鲜。当我们谈到这一点时,有许多相邻的 ML 子空间浮现在脑海中,包括集合模型(例如:随机森林🌳🌳🌳)甚至多任务学习!看到这些方法论如何与复合人工智能交叉将是令人兴奋的。
这里有几个案例研究,说明复合系统是如何在今天的生产中使用的。
案例研究 1:医疗保健
复合人工智能系统并不局限于组合多个人工智能模型。这类人工智能技术还可以包括使用多种数据处理技术和额外的操作,以帮助实现供应链管理和个性化等目标。
SAS 与阿姆斯特丹大学医学中心分享了一个有趣的用例:使用计算机视觉、数据可视化和机器学习过程的组合来确定化疗对患者是否有效!
医学研究人员引用说,能够从统计分析和可视化开始,然后深入到患者扫描的细节,是使用复合人工智能的一个关键好处。下图阐明了使用 CT 扫描进行结直肠癌肝转移形态测量的处理流程。
“SAS Vita 中用于端到端生物医学图像分析的处理管道”——来源(第 3 页)
案例研究二:语音助手
为了消费、处理和生成对命令的响应,语音助理应该能够有效地执行多项任务。
Webex 团队为 Webex Assistant (如下)展示了一个自然语言处理管道示例,包括语音到文本、实体识别、问题回答等 ML 模型。
这些模型中的每一个都可能需要它们自己的数据清理元素和健壮性评估。正如作者所演示的,如果第一个语音到文本组件错误地转录了语音命令,整个管道都会受到糟糕的数据质量的影响!
用于 Webex 助手的语音助手管道示例— 来源
案例研究 3:制造业
OECD 人工智能系统分类框架引用了一个令人兴奋的制造领域复合人工智能系统的例子,取自 Qlector LEAP 解决方案。
作为这个用例的一部分,多个人工智能模型消耗与制造工厂相关的和源自制造工厂的数据。这些模型适用于不同的任务,如人类特征分析、市场预测、异常检测等。然后将输出汇总为用于不同类型决策的知识图的一部分。
帮助管理制造工厂的复合人工智能系统— 来源(第 61 页)
随着这些系统的研究和使用的继续,我期待着看到我们如何回答围绕“一个为所有”和“所有为一”应用于机器学习的问题。
有一点是肯定的:复合系统的定义正在继续扩展到数据和人工智能工作流的不同元素(就像复合和分布式人工智能的交集!),证明人工智能系统在一起更强大。
因果推理“do”操作符的完整解释,包括一个使用 Python 和 DoWhy 的端到端示例
如何掌握因果推理 do 运算符,以及为什么您的数据科学工具包中需要它
Bradyn Trollip 在 Unsplash 上拍摄的照片
介绍
正如我在理解这项新兴技术如何工作以及它为什么如此重要的过程中所发现的那样,在互联网上或书籍中很难找到完整解释的、端到端的因果推理例子,这些例子都有实际的、有效的源代码。
但如果你坚持不懈,这肯定是非常值得的努力,因为它将能够解决一种不同类型的问题,这种问题使用其他机器学习技术无法解决。
传统的机器学习模型可以预测如果未来大体上像过去一样可能会发生什么,但它们不能告诉你应该采取不同的措施来实现预期的结果。
例如,分类算法可以预测银行贷款客户是否可能违约,但它无法回答诸如“如果我们改变贷款的还款期限,是否会有更多的客户避免违约?”
以下是因果推理可以回答的传统预测模型无法回答的问题类型的几个例子:
- 对一个系统提议的改变能改善人们的结果吗?
- 是什么导致了系统结果的变化?
- 系统的哪些变化可能会改善人们的结果?
有许多在线文章的例子详细介绍了因果推理所涉及的数学,但是很少有文章提供了一个完整的解释和所有源代码的实例。
如果你坚持和我一起读完这篇文章,我保证给你提供完整的解释和所有的源代码,这将使你能够做一些真正令人惊讶的事情,而这是其他机器学习技术不可能做到的。
数据
我们首先需要一些数据。我创建了一个纯合成数据集,其灵感来自著名的 LaLonde 数据,该数据观察并记录了 20 世纪 70 年代就业技能培训计划对收入的影响。
由于 LaLonde 的数据和研究提供了灵感,所以在文章结尾的参考文献部分有一段引文。
作者图片
有必要花点时间来理解合成数据集的关键方面
- 如果个人参加了旨在提供就业技能和增加收入潜力的虚构培训计划,则持有 1。在合成数据集中,640 人参加了训练计划,1360 人没有参加。
age
是以年为单位的年龄。education_years
持有学校教育的年限。received_benefits
如果个人曾经接受过失业救济,则持有 1。university_degree
是 1,如果个人在大学学习并获得学位。single
如果个人是单身(即没有结婚或处于民事伴侣关系中),则为 1。top_earner
如果个人处于收入最高的四分之一,则为 1。age_group
是age.
的分类版本earnings
是个人在完成虚拟就业技能培训计划 3 年后的收入,是感兴趣的“目标”或特征。
培训方案产生了什么影响?
现在让我们来看看数据,看看培训计划对参与者的收入有什么影响…
作者图片
根据分析,参加培训计划的影响是负面的-
- 参加培训方案的明显影响是年收入减少 1 065.29 美元。
- 参加培训的人成为高收入者的概率是 0.19,不参加培训的人是 0.28。
- 接受培训者的收入中位数为 3739 美元,未接受培训者的收入中位数为 4893 美元。
- 接受培训者的平均收入为 6067 美元,未接受培训者的平均收入为 7132 美元。
你会给出什么建议?
根据分析,明确的建议是停止培训计划,因为使用四种不同的衡量标准可以表明,对收入的影响始终是负面的。
直觉上,这个结论似乎并不正确。即使培训绝对糟糕,参加培训会降低参与者的就业能力并损害他们未来的收入也是不对的。
那么,分析出了什么问题?
在这一点上,包括概率和预测模型在内的传统方法的潜力无法让我们走得更远。这些技术的任何应用都将得出训练应该被取消的结论。
为了突破这些限制,并真正理解发生了什么,我们需要建立一个因果模型,并应用神奇的“do”运算符。
如果你想知道培训项目的真正影响,以及为什么使用传统的概率和预测模型会导致错误甚至危险的结果,请继续阅读…
使用“do”运算符的因果推理解决方案
让我们通过更详细地查看数据集中的一些要素来开始更准确的评估之旅…
作者图片
显然,参加培训的人和没有参加培训的人在教育方面有着明显不同的模式。
在现实世界项目中的这一点上,我们将与领域专家合作来理解这些模式,但即使没有领域专业知识,也有理由得出结论,教育可能会对参加培训的人及其赚钱的能力产生因果影响。
作者图片
这是一个相似的故事。对于那些接受培训的人来说,这是一个线性模式,年轻人多,老年人少。对于没有训练的人来说,在 30-40 岁年龄段会有一个高峰。一种假设可能是,许多 30-40 岁的人已经收入颇丰,不想接受任何与工作技能相关的培训。
这再次表明,年龄既影响个人是否有可能参加培训,也影响他们的收入潜力。
因果推理和“混杂”
这个简单的附加分析揭示了“混杂因素”的存在。这个术语在许多可用的例子中到处流传,通常伴随着微积分和公式,但通常没有明确的解释。
简而言之,年龄和教育等特征的影响与兴趣的主要影响(即培训对收入的影响)混合在一起,当我们应用传统方法时,无法分离出独立的影响。
构建“有向无环图”(DAG)
从数据中发现因果关系是不可能的。数据需要用“有向无环图”(DAG)来补充,DAG 是通过利用领域专业知识和其他技术来“发现”因果关系而构建的。
关于更详细的探索,请看看我关于发现因果关系的文章
下一步将使用我的DirectedAcyclicGraph
类。为了使文章更加简洁,我在文章中省略了源代码,但如果你想自己运行代码,这里有完整源代码的链接-https://gist . github . com/grahamharrison 68/9733 b 0 CD 4 db 8 e 3 e 049 D5 be 7 fc 17 b 7602。
如果你决定使用它,如果你喜欢它,为什么不考虑给我买杯咖啡?…
这是我对数据中因果关系的建议-
作者图片
DAG 可以解释如下-
received_training
(即参加培训项目)对earnings
(即未来收入)有因果影响。- 所有其他特征对一个人是否可能参加培训计划都有因果影响。
- 所有其他特征也会对未来收益产生因果影响。
例如,个人的年龄“导致”他们是否参加培训,可能是因为更多的年轻人希望接受培训,年龄也“导致”收入,可能是因为经验更多的老年人可以赚得更多。
这种模式很常见。当统计学家在进行随机对照试验(RCT)时,他们可能会对与主效应混合的变量进行调节或控制。
这意味着,对于年龄,他们可以将观察结果分成不同的年龄组,查看每组的治疗和年龄之间的关系,然后对每组进行比例平均,以估计真实的总体效果。
然而,这种方法存在一些问题。例如,如何定义组的边界?如果关键影响是 16-18 岁的人,但界限被设定为 16-30 岁,会怎样?如果没有对 40-45 岁人群的观察结果会怎样?
另一种方法不是观察,而是干预。我们可以简单地强迫每个人进行培训,然后我们就会看到真正的影响。但是,如果观察是历史的(如在拉隆德的数据中),并且干预为时已晚,该怎么办呢?或者如果这是一项关于吸烟或肥胖的研究呢?
受试者不能仅仅为了证明我们的理论而被迫吸烟或变胖!
这就是“do”操作符的用武之地。这听起来像是魔术,但建立一个因果推理模型是真正可能的,它可以准确地模拟这些干预,而不必在现实世界中进行。
这将节省大量时间和金钱,消除对随机控制试验的需求,这些试验以大量变量为条件,并使对吸烟和肥胖等现实世界研究中存在道德和伦理问题的因素的研究成为可能。
“Do”操作符的魔力
让我们想象一下,不是观察一群人,其中一些人接受了训练,一些人没有,我们可以回到过去,干预而不是观察,让他们都接受训练。
在这种情况下,DAG 看起来像这样-
作者图片
这就是神奇的“do”操作符正在做的事情。如果你进行干预和𝑑𝑜(𝑡𝑟𝑒𝑎𝑡=1),你就有效地“消除”了所有因果关系的输入线,因为无论年龄、教育和其他特征如何影响进行培训的概率,它总是会发生。
在幕后,图书馆正在模拟这种干预。它可以通过使用做微积分的规则来转换𝑝(earnings|𝑑𝑜(received_training=1)来做到这一点,除非我们对一组可以从数据中计算出来的观察规则进行物理干预,否则这些规则无法直接计算出来。
我有意在这篇文章中省略了数学的细节。有很多文章展示了数学,但是很少展示 Python 代码的工作示例,因此这是本文的重点。
注意:如果你想运行代码,你将需要我的DirectedAcyclicGraph
类,所以如果你还没有下载它,请前往https://gist . github . com/grahamharrison 68/9733 b 0 CD 4 db 8 e 3 e 049 D5 be 7 fc 17 b 7602,如果你喜欢的话,不要忘记考虑请我喝杯咖啡!
这是对数据执行“do”操作的完整源代码…
作者图片
代码是什么意思?
在我们进入真正令人惊奇的结果之前,逐行浏览代码是有用的。
首先,导入dowhy.api
神奇地扩展了熊猫DataFrame
,使得这个类获得了一个新的causal.do
方法。
接下来在numpy
中设置随机种子,确保do
方法的结果是可重复的。文档中没有提到任何关于设置随机种子的内容,这是通过反复试验找到的。还要注意,随机种子需要在每次调用causal.do
之前在前面的语句中设置,而不仅仅是在第一次调用之前。
causal.do
的下一个谜团是variable_types
参数。DoWhy
文件不完整且不一致。尝试了很多不同的东西,得出了以下结论-
- 不管文档中怎么说,只有两种类型是重要的——“d”代表离散型,“c”代表连续型。
- 在统计学中,整数是离散的,但是如果整数被声明为“d”,那么
DoWhy
会产生一些非常奇怪的结果。基于对DoWhy
文档和例子的大量阅读,我的结论是整数需要声明为“c”来表示连续。 - 在
DoWhy
源代码中有一个名为infer_variable_types
的方法,但是它没有代码,所以我写了自己的实现,在DirectedAcyclicGraph.infer_variable_types()
中它是一个静态方法。
以下是最重要的causal.do
方法参数的含义-
x={"received_training": 1}
是说我们想“做”什么。在这种情况下,我们想看看如果每个人都被迫参加数据中由received_training=1
表示的培训会发生什么。outcome="earnings"
-这是我们正在寻找的结果或效果,即“做”received_training=1 对个人收入的影响是什么?dot_graph=training_model.gml_graph
通知do
操作者我们认为数据中存在的因果关系。training_model
是我的DirectedAcyclicGraph
类的一个实例,我给了它一个属性,它以gml
的格式给出了结构do
方法需要传入common_causes
或dot_graph
来描述因果关系。dot_graph
参数将接受dot
或gml
格式的结构,但在文档中没有提到这一点;gml
在我看来要好得多,因为它在DoWhy
中到处都被使用。- 指定一个图比设置
common_causes
要好得多,因为图可以捕捉任何类型的结构,而common_causes
则有更多的限制。同样,在DoWhy
文档中也没有提到这一点。 variable_types
参数已经解释过了。proceed_when_unidentifiable=True
避免干扰计算的恼人的用户提示。
它是如何工作的?
causal.do
方法正在返回一个新的数据帧,该数据帧有效地模拟了强制干预,并提供了如果每个人都完成了培训就会收集到的数据-
作者图片
在这方面,DoWhy
与大多数其他 Python 因果库不同,因为大多数其他库只是返回一个数字而不是一个DataFrame
。
返回一个DataFrame
最初有点令人困惑,但是再深入一点,这是一个强大、灵活和信息丰富的方法。
在不知道内部实现细节的情况下,我的结论是DoWhy
正在模拟随机对照试验(RCT ),根据需要用于“消除混杂”本文前面描述的混合效应的组对数据进行采样。
例如,看一下原始观察数据和新干预数据之间的以下特征的比较-
作者图片
显然DoWhy
已经以一种非常不同的方式对该特征的干预数据进行了重新采样。
培训对收入真正的“非决定性”影响是什么?
现在剩下的就是通过观察df_do
DataFrame
-来解释培训对收入的真正影响
作者图片
结论
根据观察数据使用概率的传统方法表明,参加培训的人实际上比没有参加培训的人工资要低。
根据观察数据接受培训的人的平均工资为 6067 美元,而模拟干预的因果推断“do”方法揭示了真实的影响——工资增加,平均工资为 7392 美元。
在应用因果推断方法后,建议不是取消培训计划,而是扩大培训计划,因为它为需要帮助的群体提供了更公平的机会,以增加他们的长期收入。
在文章的结尾,我承诺了一些令人惊奇的事情,如果这个结果对你有和对我一样的启示性影响,那么我希望它没有辜负我的承诺。
每当数据中存在因果效应时,传统的预测方法都会导致错误的结论和建议,这使得因果推断成为所有数据科学家的工具包中的一个重要工具。
如果你喜欢这篇文章,请考虑…
通过我的推荐链接加入 Medium(如果你使用此链接注册,我将收取一定比例的费用)。
https://grahamharrison-86487.medium.com/membership
每当我发表新故事时,订阅一封免费电子邮件。
访问我的数据科学网站— 数据博客。
参考
拉隆德数据集-
- 引文:罗伯特·J·拉隆德,1986 年。“用实验数据评估培训项目的计量经济学评估”,《美国经济评论》,美国经济协会,第 76 卷(4),第 604-620 页,9 月。
自然语言处理中口译语言的挑战
原文:https://towardsdatascience.com/the-challenge-of-interpreting-language-in-nlp-edf732775870
为什么教机器理解语言如此困难
让我们的机器理解文本是一项艰巨的任务。尽管在这方面已经取得了很多进展,但我们距离创造一种将语言无缝转换成机器可读数据的方法还有很长的路要走。
让我们面对它;我们的语言很复杂。
与整齐地由行和列组成的表格以及由 RBG 值在固定范围内的像素组成的图像不同,我们说的和写的单词不遵循严格的结构化系统。
鉴于我们的灵活性,在过去 200 万年的人类文明中,我们一直能够做到这一点(这是一次不错的尝试)。不幸的是,当我们试图教计算机理解我们复杂的系统时,我们语言中的谬误开始困扰我们。
为了更好地理解 NLP 从业者面临的挑战,从语言学家的角度来审视我们的语言是理想的。
让我们来看看让我们的语言变得晦涩甚至有时无意义的一些因素。
注:本文主要以英语为主。讨论的一些特性可能不适用于其他语言。
单词序列
在口语和书面语中,单词的顺序很重要。一篇文章的语义价值不仅在于单词本身,还在于单词的顺序。
考虑下面几对句子:
Case 1:
"The cat ate the mouse."
"The mouse ate the cat."Case 2:
"I had fixed my laptop."
"I had my laptop fixed."
在这两种情况下,即使句子有相同的单词,它们的语义是不同的。
同义词
同义词指的是彼此意思相同或相似的词。您很可能对它们很熟悉,但这里有几个例子:
1: {great, amazing, fantastic}
2: {big, huge, enormous}
3: {costly, expensive, pricey}
用多种方式表达相同的信息会增加复杂性,这是 NLP 模型必须考虑的。
同音异义词
同音异义词是指拼写和发音相同,但有多种含义的词。
在对话中,根据上下文,很容易确定所指的是什么意思。这里有一个例子:
"The fishes are swimming in a tank."
"The military unit was supplied with a tank."
根据所提供的上下文,我们可以很容易地说出每个场景中“tank”的定义。然而,让计算机做同样的事情是一个挑战。
讽刺
讽刺,通俗地说,就是说一些与你想说的意思相反的话(通常是一种嘲弄或嘲笑的形式)。它早已融入我们的日常对话。它也存在于文本中,常见于个人聊天等交流形式中。
我相信我们都见过类似以下的在线评论:
"What a book! After 50 pages in, I only dozed off twice!"
同样,这种现象对人类来说很容易察觉,但对计算机来说就不那么容易了。不幸的是,未能检测讽刺会妨碍需要检测情感(例如,情感分析)的 NLP 应用的性能。
未知单词
NLP 模型也有可能遇到不认识的单词。这些词不包括在用于训练模型的数据中。这类单词的例子包括新词汇、拼写错误的单词、俚语和缩写。
NLP 中的当前模型
研究人员进行了无数的研究,以开发算法和模型,使计算机能够向量化文本,尽管我们的语言错综复杂。
让我们来看看其中的几个。
基于计数的模型
像单词袋或 TF-IDF 这样的模型经常被介绍给从自然语言处理开始的新手。他们对文本进行矢量化的方法很简单,主要基于单词的频率来评估文本。
这些模型易于大规模部署,可用于许多应用。然而,他们的矢量化方法忽略了单词的顺序以及单个单词的语义值。
例如,这里有两个非常简单的句子:
"Pigeons fly."
"Eagles soar.
很相似,对吧?
不幸的是,对于单词袋或 TF-IDF 模型,这些句子的余弦相似度为 0。
使用基于计数的模型,同义词如“飞”和“翱翔”以及来自同一类别的词如“鸽子”和“鹰”将被视为完全不同的实体。
深度学习模型
为了解决基于计数的模型的局限性,一些研究转向深度学习模型作为向量化文本的手段。
例如,word2vec 模型使用浅层神经网络根据每个单词周围的单词来评估每个单词。这解决了基于计数的模型无法保留给定文本的语义值的问题。
不幸的是,word2vec 模型有其自身的局限性。
首先,它不能正确识别同音异义词的不同含义。该模型不能识别在正文中找到的单词的版本。
其次,它无法容纳未用于训练模型的未知单词。
最后,作为深度学习模型,它需要大量的数据。深度学习模型的性能只有在用高质量和高数量的数据训练时才能达到令人满意的水平。
为了演示,让我们使用从 Kaggle(无版权)获得的几篇 BBC 文章来创建 word2vec 模型。此演示的数据可在这里找到。
首先,让我们加载。txt 文件,并将业务类别中的所有文本合并成一个语料库。
在用 NLTK 库对语料进行预处理之后,让我们用它来训练一个 word2vec 模型。
对于模型,我们来看 5 个与“金融”最相似的词。
代码输出(由作者创建)
如你所见,被认为与金融最相似的 5 个词在商业环境中并没有那么紧密地联系在一起。然而,这样的结果是可以预期的,因为模型的输出受到用于训练它的语料库的限制。不能期望这样的模型充分执行。
基于变压器的模型
广泛的研究导致了基于变压器的模型的出现。这些模型的编码器-解码器架构允许计算机理解更复杂的文本。他们能够处理同音异义词,甚至是不认识的单词。
这种模型可用于执行高级任务,如文本摘要和机器翻译。
基于变压器的模型的例子包括谷歌的变压器双向编码器表示(BERT)模型和 OpenAI 的 GPT-2。
虽然这些模型非常复杂,但它们的性能代价很高。字面上。
这些模型具有复杂的体系结构,并用数十亿个单词进行训练。因此,培训和部署他们会产生很高的成本。
自然,它们是为更高级的应用程序保留的。
使用变压器完成简单的 NLP 任务就像租一辆豪华轿车去杂货店一样。
结论
你现在对我们语言的构成是如何让计算机理解我们的语言变得如此困难有了一些了解。
在 NLP 中显然还有其他困难的障碍需要面对(例如,缺乏对数据的可访问性),但是认识到有多少障碍源于我们语言的无组织本质是很重要的。
随着我们继续尝试实现更复杂的 NLP 技术,让我们的计算机理解我们的语言,尽管它们是谬误的,仍将是一个持续的挑战。
我祝你在 NLP 的努力中好运!
参考
- 谢里夫,P. (2018)。BBC 新闻摘要,第 2 版。于 2022 年 1 月 30 日从 https://www.kaggle.com/pariza/bbc-news-summary.取回
用数据解决问题的挑战
原文:https://towardsdatascience.com/the-challenges-of-solving-problems-with-data-2efb62f9a40a
这是数据科学研究人员和行业从业者普遍认同的一条公理:给定足够的数据,没有什么问题是不可能解决的。在现实中,数据可能难以控制,项目管理需要许多超出调整模型的因素,并且将结果转化为可操作的见解通常是一个复杂和不确定的过程。
本周,我们将聚焦于数据科学问题的解决,精选了一些从多个角度探讨数据科学的优秀文章。(向下滚动阅读其他主题的一些精彩读物。)
- 图论如何帮助解决路由问题 。 Lily Wu 从流行的视频游戏 Stardew Valley 中获得灵感,深入研究路线优化,并耐心地向我们介绍她用 Python 编写的算法来解决最短路径和最小生成树问题的方法。
- 让数据可见是实现可靠分析(和解决方案)的关键一步 。Aine Fairbrother-Browne 的第一篇 TDS 文章围绕航空效率和航空业对环境的影响——一个巨大的全球性挑战。但它也凸显了将数据(在这种情况下,是公共航空数据)转化为清晰图像的价值,这反过来让我们能够发现趋势、构建论点,并(希望)指出潜在的解决方案。
照片由 Senad Palic 在 Unsplash 上拍摄
- 将 AI 推至其当前能力之外的风险 。通过聊天机器人的例子, Iulia Turc 展示了技术在解决复杂问题上的局限性。这项研究专注于精神健康背景下的对话式人工智能,这很好地提醒了我们,设计糟糕的解决方案往往会加剧问题,而不是解决问题,因此我们需要非常谨慎地在现实世界中部署它们。当人们的生命和福祉受到威胁时,尤其如此。(内容警告:本帖含有自残和自杀的提法。)
- 如何通过更好的设计提高项目的成功率 。有时,解决棘手问题的关键不在于数据或我们使用的技术方法。正如 Khuyen Tran 在她的最新文章中所强调的,建立正确的项目结构至少和选择正确的 ML 模型一样重要。她分享的模板将帮助数据科学家产生透明、可读和有据可查的工作。
准备好了吗?我们希望如此——TDS 的作者们最近分享了一些令人难以置信的工作,涉及的主题范围很广:从高度理论化到实际操作。
- 如果你正在建立一个强化学习项目,不要错过费利克斯·霍夫斯特的新帖,他在那里解释了如何阻止你的人工智能代理侵入奖励函数。
- 人工智能生成的维基文章即将出现吗?Jeremie Harris 和人工智能研究员 Angela Fan 在最近一期 TDS 播客中深入讨论了这个问题。
- 对物理材料的数据挖掘感兴趣? Joyita Bhattacharya 继续探索这个话题,发表了一篇新文章,解释了如何从图像中测量材料的特性。
- 任何对排名算法领域不熟悉的人都会喜欢塞缪尔·弗伦德的新的、可访问的初级读本,该读本涉及推荐系统、社交媒体源等等。
- 这里有一个针对修补者的实践教程: Bildea Ana 带我们了解构建定制顶点 AI 管道的过程。
- 最后,花点时间阅读 Ajit Rajasekharan 的在生成任务背景下对向量和图像表示的深入探讨。
你喜欢花时间在 TDS 上吗?考虑通过成为媒体成员来支持我们作者的工作。我们将永远感激;你将可以无限制地访问我们的全部档案。
直到下一个变量,
TDS 编辑
咖啡豆不是同质的:筛过的意大利香肠浓缩咖啡
原文:https://towardsdatascience.com/the-coffee-bean-is-not-homogenous-sifted-salami-espresso-5b861bfbfbb7
咖啡数据科学
测量进入咖啡豆的研磨粒度的提取率
理解浓缩咖啡的最大障碍是对咖啡豆的理解。通常,我们假设咖啡豆在味道和提取潜力上是同质的。当我开始开发断奏镜头时,我曾说过只用大颗粒或小颗粒的咖啡感觉失去了一些味道。除了同质性可能是不正确的以外,我不知道为什么。
在本文中,我研究了不同粒度的萃取率,并做了额外的研究。我把里面的粉末从外面分离出来,这样我可以测量两者的提取率。这应该有助于解释为什么一杯反过来的断奏浓缩咖啡比普通的断奏咖啡表现更好。
背景
一年前,我研究了不同粒度的的提取率,那项研究极大地让我了解了提取的极限。随着一些其他的研究,我受到启发,研究同样的东西,筛分粒度。颗粒不会像你想象的那样被提取出来,因为咖啡豆不是同质的。
大约在去年的同一时间,我发现豆子里面的和外面的不一样。人们可以筛去粗磨部分,得到里面的细粒。味道测试证实,这些细粒不同于将巨石研磨得更细所产生的细粒。
在 2021 年的秋天,我练习了内向外断奏击球和懒惰断奏击球,作为利用内线优势的一种方式。两个镜头都很有趣,但当然,更多的处理步骤被添加。除了像“从豆子的相同部分(相同的颗粒大小)提取的粉末应该更均匀”这样含糊不清的说法之外,还不清楚为什么分离粉末会有帮助
设备/技术
咖啡研磨机:小生零位
咖啡:家庭烘焙咖啡,中杯(第一口+ 1 分钟)
镜头准备:断奏夯实
预灌注:无
输液:恒定流量
过滤篮 : 7g VST
其他设备: Atago TDS 计, Acaia Pyxis 秤, Kruve 筛, Fellow 摆振
实验设计
为了测试成功,需要很好地控制其他变量,即可溶物和 CO2。萃取过程中释放的可溶物和 CO2 气体会影响萃取。为了隔离这些变量,我做了很多用过的咖啡渣。最后它们都结块了,所以我用咖啡筛去除了所有的结块,并且在筛过之后我重新混合了细的和粗的粉末。
所有图片由作者提供
每一杯咖啡大部分是用过的咖啡渣,其中大约有 11%是筛过的咖啡。我还用了一个 7g 的 VST 篮子,这样我就可以将 1.5g 的新鲜咖啡和 4g 的废咖啡渣混合在一起。在这一层的上面是 8.5 克用过的咖啡,因此篮子里有 14 克咖啡。我用一个金属网筛完成了这个。
然后,我在像样的浓缩咖啡机上使用恒定流量(4 毫升/秒)作为所有镜头的基准。这忽略了其他优化,如预灌注、压力分布、压力脉动和开花,但这些在以后的时间里会很有趣。
性能指标
我使用基于折光率仪的提取率来评估性能。
数据
这是我使用两种研磨设置制作不同粒子的路线:
注意,我用 Fellow Shimmy 过滤掉< 300um,因为它更快,然后我用了 500um Kruve 屏幕。该摆振是额定为 200 微米筛选,但因为它使用方孔,它的表现非常接近 Kruve 300um 微米屏幕。
我最终得到了这个分布。
然后,我从每个箱子里取了一些样品,拍了一些意大利香肠。
包括对照镜头在内的所有镜头具有 20 秒的拍摄时间,并且所有的分割时间彼此在 1 秒之内。这表明新鲜的粉末没有影响流动,这是本研究的目的。
首先,我提取了一个对照样本来测量从废料中提取了多少。虽然该值不高,但它最终会影响其他测试的 TDS 测量值。我的目标是在输出比率上以 0.5 的间隔从 0.5 到 3,但镜头跑得太快了,很难管理。
对于每一杯意大利腊肠,我通过 2%到 3%的控制来调整 EY。
我们来看看最后的结果。在这里,我们可以看到内部的细粒比外部提取得快得多。如果我们假设豆子的内部比外部更脆,这就不足为奇了。
在观察不同大小完全提取的速度时,较细的层几乎立即提取。按 1.5 的比例,大部分都是提取出来的。然而,较粗的颗粒需要更长的时间。这可以解释为什么 Allongé需要 3:1 或更长的比例才能达到最高提取率。
如果先前的筛选分布在具有相同轮廓的圆盘中,我们可以使用该信息来制作理论圆盘。这一理论与来自外部研磨的中档粒子(300um 到 500um)非常匹配。
我将它与两个镜头(常规和断奏)进行了比较,这两个镜头使用了我的常规配置文件。他们的 EY 趋势更高,这仅仅表明使用预灌注、起霜或压力脉冲有助于改善理论。
对数据的另一种看法
我想改变我查看数据的方式,所以我为每个镜头比率做了一个穿过筛选过的粒子箱的线形图。他们的投篮命中率大致相同,我喜欢这个数据出来的方式。我仍在研究下一步如何利用这些新信息。
这些数据显示了咖啡是如何不均匀的,并且它有助于给出萃取如何随时间发展的基线。对于不同的温度设置、压力设置和其他考虑因素,该实验可以容易地重复,并且它可以用于帮助更好地表征咖啡。希望这种方法可以被证明对开发更高级的浓缩咖啡镜头轮廓是有用的。
如果你愿意,可以在推特、 YouTube 和 Instagram 上关注我,我会在那里发布不同机器上的浓缩咖啡照片和浓缩咖啡相关的视频。你也可以在 LinkedIn 上找到我。也可以关注我在中和订阅。
我的进一步阅读:
工作和学校故事集
现代人工智能堆栈完全指南
原文:https://towardsdatascience.com/the-complete-guide-to-the-modern-ai-stack-9fe3143d58ff
AI/ML 生命周期中的阶段、技巧和工具
图片来源:Unsplash
企业中的机器学习(ML)在一个狭窄的范围内迅速发展。虽然它呈指数级增长,但一些组织仍在努力跟上 ML 堆栈发展的步伐。
这份现代人工智能堆栈的端到端指南希望将最佳工具和实践纳入一个公共空间,作为以下方面的参考:
- 人工智能领域的领导者包括经理、总监、副总裁和首席技术官,他们可以了解更多关于新技术/集成的知识,并引导他们的团队走向现代人工智能堆栈
- 数据科学家和 ML 工程师,他们可以将他们当前的堆栈与我们提议的 AI 堆栈进行比较,并发现要采用的新技术。
但是首先,沿着记忆的小路走一走…
企业中 ML 的开始
机器学习在不久前还处于企业市场的实验阶段。就在五年前,大型服务公司刚刚开始涉足概念验证(POC)项目,广泛宣称机器学习(ML)是新兴技术,将影响作为其客户一部分的大量行业。
一旦客户开始规划智能解决方案的可能性,如预测性维护、异常检测、收入预测和推荐系统,就没有回头路了。然而,由于数据的动态性质,即使是最先进的模型也面临着不可避免的退化。下面的一些例子可以更好地理解这一点:
- 未开发的适应:一种癌症预测解决方案具有 99%的灵敏度,但没有明确定义的途径或监控方法来检测漂移的数据模式并悄悄地更新失败的模型。这里的数据漂移可能涉及从改变药物模式到输入设备/技术升级的任何地方。
- 由于不可靠,需要更多的手动工作:欺诈检测模型可以达到 95%的灵敏度,但必须在精确度上做出妥协,比如说 75%,这样才能过滤掉所有可能的欺诈案例。这导致在筛选检测到的案例后需要更多的手动工作,并限制了对无过失客户的询问操作。
- 糟糕的客户体验:贷款预测解决方案可能有 97%的准确率,但与每种机器学习算法一样,随着数据的变化,性能可能会下降。对于黑盒人工智能模型,没有明确的方法来理解贷款为什么被批准或拒绝。特别是在贷款被拒绝的情况下,客户需要一个适当的解释,如果没有这个解释,会有几次重复,导致客户体验不佳。
这些现实世界的问题自 AI 在企业中出现以来就一直存在,给客户打上了 AI 在很大程度上不可靠的烙印。作为专注于人工智能可观察性的 Censius 的创始人,我遇到了许多这样的故事,它们阻碍了自动化或基于人工智能的解决方案的可信度。
过渡到可靠的解决方案
人工智能/人工智能在经历了数年的试验阶段后,正朝着一个更为简化的方向发展。较大的组织已经开始完善他们的流程,以创建标准化的 ML 管道,这些管道针对规模、效率和控制进行了优化。
过去,由于数据科学家和工程师之间的巨大差距,团队无法保持敏捷,解决任何问题的时间都很慢。但最近,企业一直在努力通过实施MLOps——一种机器学习解决方案的生命周期管理技术,为 ML 管道创建一个更可控的环境。
MLOps 通过在整个 ML 管道中实施一套标准化实践,从需求收集开始,一直到在生产中监控解决方案,促进了开发和运营团队之间的沟通。这是确保 ML 解决方案的规模、速度和质量的基础。
通过 MLOps 实践,团队可以了解 ML 基础设施,并彻底了解 AI 性能和 ROI 机会——鉴于现实世界数据的动态行为,这在以前是一个重大挑战。密切跟踪 ML 管道以捕捉重复出现的问题仅仅是在 AI 领域注入可靠性的开始。至关重要的是,通过模型可观察性——m lops 生态系统的新兴支柱,超越模型监控,以实现对每个模型决策的剖析,并在规模上建立可解释和负责任的人工智能。
我们显然正在迈向人工智能发展的下一个阶段,在这个阶段,人工智能产品提供了更多类似于 SaaS 工具的具体体验,增加了模型的可靠性、性能,并最终增加了客户的信任。
现代人工智能堆栈是如何形成的
软件即服务(SaaS)并行
两大技术革命之间有相似之处:很久以前发生的 SaaS 革命和现在正在发生的人工智能进化。
在 SaaS,当微服务或面向服务的架构(SOA)的概念被引入时,它被证明比单一的应用程序更好。然而很快引发了数百个难以规模化的微服务的兴起。这导致了无服务器架构的发展,在这种架构中,资源在事件期间动态分配,一旦达到目的就被销毁,从而实现了巨大的可扩展性。
SaaS 的这一里程碑式的转变与人工智能目前的发展非常相似。随着人工智能从业者在回头客中发现更多价值,人工智能正逐步从具有分散流程的易错系统演变为可扩展和可信的人工智能生态系统,正如 SaaS 之前从分布式单片或 SOA 转变为大规模可靠的无服务器架构。
向 DevOps 学习
为了使从不可靠的人工智能到值得信赖的人工智能的飞跃成为可能,标准化的 MLOps 过程越来越多地被采用,以改善模型可见性、模型性能以及随着数据变化的实时故障排除。MLOps 与 DevOps 有着密切的联系,并一直受到它的启发。两者之间有几个相似之处,包括 CI/CD 实践、有效的协作方法以及提高管道中容错能力的共同目标。
DevOps 通过采用一套最佳实践和工具来鼓励开发和运营团队之间的快速协作,为开发人员和运营团队提供最佳实践,以高速构建和交付可靠的 SaaS 产品。 MLOps 诞生于类似的需要,结合了 DevOps、数据工程和 ML 的实践。合并三个不同的领域建立了 MLOps,以有竞争力地维持 DevOps 策略,同时适应 ML 管道的实验性质。
输入 MLOps
MLOps 是精简整个 ML 管道的过程,以便团队可以顺利地运行开发、生产、监控和维护活动。多年来,MLOps 已被证明能够带来多种好处,促使更多的组织效仿。
尽管 MLOps 仍处于早期形成阶段,但对早期采用者的好处已经很明显了。以下是团队在实施 MLOps 的早期就意识到的一些好处:
- 实施经过验证的 CI/CD 方法,在不中断产品体验的情况下,以首选频率推动变革。例如,优步采用 CI/CD 方法发布实时预测服务
- 机器学习生命周期中测试阶段的自动化,包括预测验证、数据质量监控、集成测试等。Nike的 ML 团队能够自动化他们的 A/B 测试和服务渠道,管理集成模型的执行。
- 所有 ML 解决方案的技术债务最小化,尤其是在 ML 生命周期中频繁出现的维护活动中。谷歌很容易就发现了这个问题,并推出了 Vertex AI,促进了人工智能的维护和发展。
- 通过提高整个 ML 管道的可重复性,解决方案的可扩展性和脆弱性的降低。为了通过 MLOps 战略实现 ML 渠道的规模化,网飞在内部开发了端到端的工作流程管理工具。
MLOps 循环|来源:ml-ops.org
随着公司试验 MLOps 并亲身体验其好处,它在现代人工智能堆栈中获得了永久的一席之地。让我们浏览堆栈的每一层,以更清楚地了解组装最佳流程、工具和 MLOps 实践,从而实现向可靠 AI 的飞跃。
现代人工智能堆栈的阶段
现代人工智能堆栈是吸收了 MLOps 实践的工具、服务和过程的集合,允许开发人员和运营团队在资源利用、团队工作、最终用户体验和维护活动方面有效地构建 ML 管道。
我们将讨论 ML 管道的每个阶段,并从 20 英尺的角度来看每个阶段可以利用的工具。
现代人工智能堆栈|作者图片
阶段 1:数据管理
数据管理有五个主要的对应部分:收集、转换、处理、版本控制和监控。
数据管理堆栈|作者图片
数据采集
数据收集过程经历了几个第三方工具和服务的交叉,这些工具和服务与内部工具集成在一起以组装可用的数据。
- 数据收集
数据收集通常涉及网络搜集,浏览旧数据库,并编写复杂的查询来提取它们。除了这些方法之外,数据集还直接来源于 OpenML 、 Kaggle 和亚马逊数据集等网站。
- 数据标记
需要对收集的数据进行处理和注释,以便机器可以在受监督的解决方案中学习适当的关系。数据标记在很大程度上一直是手动的,但最近出现了几个工具,如 V7 labs 、 LabelMe 和 ImgLab ,这些工具大大自动化了标记,使大规模繁琐的过程成为可能。
然而,这一阶段仍然是一个人工密集型的过程,因为算法往往会遗漏特定的案例,并且审查非常耗时。你需要对收集什么类型的数据有明确的参数,并在标记过程中非常严格。亚马逊的 Mechanical Turk 和 Ground Truth 等工具也可以通过外包提供支持。
- 合成数据生成
尽管数据量很大,但有时数据并不总是可用于非常特定的用例,或者由于隐私问题而不被直接使用,例如罕见疾病数据。尽管这种数据很难获得,但对这种具有特定数据要求的模型的需求相对较高。有大量的工具和库支持各种数据类型的数据生成,包括图像、文本、表格等。
Tensorflow 和 OpenCV 是图像数据的理想选择,支持旋转、翻转、重缩放、亮度变化、颜色修改等等。 Scikit-learn 可以为表格数据创建合成数据点,并且 scikit image 也支持图像数据。 SymPy 和 Pydbgen 是分别支持符号表达式和分类数据生成的专用库。 Hazy 和 Datomize 也是两个有竞争力的合成数据生成工具,具有与第三方工具和应用程序集成的额外功能。
数据转换和存储
数据存储需要可靠的系统,能够长期支持可变的数据量而不损坏它。为了适应这种广泛的需求,组织越来越多地涉足结构化和非结构化数据的多种存储方法,如数据仓库、数据湖、数据库等。
- ETL、ELT 和反向 ETL
ETL(提取、转换、加载)和 ELT(提取、加载、转换)是两种不同类型的数据转换系统。ETL 是传统的方法,当处理过的数据比保存原始数据具有更高的优先级时,ETL 是有利的。它将数据加载到临时暂存位置,对其进行处理,然后将其存储在目标位置。ELT 是更现代的方法,是时间优化和高数据量的理想选择。它首先将数据加载到目标位置,然后进行处理。
反向 ETL 是一个较新的发展,刚刚成为人们关注的焦点。它将数据存储连接到面向客户或基于行动的系统,如 CRMs 和 ERP,以实现跨应用程序的共享实时洞察,从而大规模个性化客户交互。
Oracle、T2、辛格、T4、IBM、Pentaho 和 Talend 提供了大量的 ETL 工具。ELT 是一项较新的技术,具有相对较少的专业选项,包括 Fivetran 、 Informatica 和 Airbyte 。 Airflow 也是一个非常流行的开源工具,用于规划、调度和监控 ELT 管道。一些即将推出的反向 ETL 工具包括 Hightouch 、 Hevo Data 和 Census 。
- 储存;储备
数据存储有几个派别,每个派别都有不同的目的。例如,数据湖存储非结构化数据,并以灵活的格式聚合所有可用数据。另一方面,数据仓库存储经过处理的结构化数据。数据库对处理过的或结构化的数据有类似的要求,可以基于本地、云中,甚至是托管服务。有几个工具如谷歌云平台、数据块、 SnowflakeDB 和 Azure cloud 提供有竞争力的存储设施。
这三种不同类型的数据存储设备的主要区别在于容量、交互频率和结构。简单的数据库存储结构化和过滤的数据,非常适合频繁的交互,而数据仓库是数据库的高级版本,针对跨多个接触点分析和存储大量结构化数据进行了优化。因为仓库依赖于转换和装载时间表,所以更新按照 ETL/ELT 的频率是滞后的。
最新的存储技术是数据湖库(Data Lakehouse ),它产生于存储种类繁多、数量巨大的非结构化数据的需求,这些数据不能立即被数据仓库或简单的数据库处理。随着数字系统和多个客户接触点生成的数据持续增长,data lakehouses 提供了管理丰富和高质量数据的解决方案,而无需丢失或处理这些数据。Data Lakehouse 不受格式限制且经济高效,是存储数据以供将来分析的理想而快速的方法。
数据处理
这是将原始数据转换为模型可以使用的有用数据的过程。原始输入被转换成数字、向量、嵌入等。供模特消费。
- 数据分析
数据分析(或探索性数据分析)是整个 ML 生命周期中最耗时的活动之一。用于分析的几个最流行的 python 库是 NumPy 和 pandas 。对于特定于大数据的用例, Apache spark 是高速查询和分析数据的绝佳工具。
商业智能工具构成了分析过程的末端,其中涉及利益相关者的交互以获得商业见解。 Tableau 和超集为报告生成提供了大量易于理解的可视化工具。
- 特征管理
在应对了管理大量原始数据、它们各自的特性和特性版本的挑战之后,特性存储成为热门话题就不足为奇了。特征存储跨机器学习解决方案存储、计算、管理和版本化特征,使得整个特征管道比手动管理更加可靠。 Iguazio 、 Tecton 、 Feast 和 Hopsworks 是提供特色商店解决方案的一些工具。
对于特征工程任务,诸如 pandas 和 NumPy 之类的分析工具服务得很好。一旦特性逻辑最终确定,就可以通过 ide(如 PyCharm 和 VS Code )对特性函数进行优化编写和打包。此活动的最终输出是一个数据清理管道,它可以处理静态和生产数据,后面是相关的特性函数。
数据版本和沿袭
出于同样的原因,数据版本控制和代码版本控制一样重要。考虑到数据是动态的且经常更新,除非仔细地进行版本控制,否则相同的过程不会对数据产生相同的结果。DVC 是一个开源工具,主要用于数据版本控制。它与语言无关,有助于构建可重复的数据管道。它集成了代码、数据、中间文件和存储工具,包括亚马逊 S3 、谷歌云和硬盘。
另一方面,数据沿袭是在整个 ML 管道中仔细映射数据旅程的过程。有了数据血统,用户可以从数据中形成一个故事,看到版本如何随着时间的推移而演变,并在每个数据接触点之间建立逻辑联系。 Pachyderm 提供数据版本和数据血统支持。它不仅支持分支、版本控制、提交和回购维护,还清晰地描绘了这些活动之间的关系。
数据监控
由于输入问题或手动错误,真实世界的数据有很多漏洞。如果错误的数据被允许传递到模型中,模型结果可能会产生误导。然而,保持大规模数据(比如数百万个数据点)的质量既费时又耗资源。自动监控是可以在有限的预算和时间内建立的最直接的 MLOps 实践。
像 Censius 这样的自动化监控工具密切检查质量问题,比如缺失值、不兼容的数据类型或数据异常。即使是概念模式,如数据漂移或不断变化的统计关系,也受到持续监控。还可以使用流量监视器来跟踪传入和传出的数据量。其他工具如提琴手和 Grafana 也有监控功能。
阶段 2:模型训练和评估
数据和建模阶段是交织在一起的,开发人员必须在它们之间进行调整以获得最佳结果。但是,一旦数据被彻底收集、存储、分析并转化为可用的特征,模型构建基本上就开始了。
模型的建立有很多方面,其中最主要的是算法的选择。然而,在将时间和资源完全投入到算法之前,考虑计算、环境和安全限制同样重要。
模型管理堆栈|作者图片
算法选择
有各种各样的机器学习库,像 TensorFlow 、 scikit-learn 、 MXNET 、 Keras 、 ONNX 、 PyTorch 等等。它们中的每一个都带有特定的 USP,并在定制、灵活性、速度、易于采用、社区支持等方面具有优势。一旦选择了库,就可以开始常规的模型构建活动(如选择和调优)来执行一系列实验。
集成驱动电子设备
IDE 或集成开发环境就像软件开发的画布。它允许集成代码、编译器、调试器、目录、代码预测器和其他一些对代码编写和软件开发至关重要的特性。PyCharm 是一个用于核心开发的 goto IDE,因为它使得导入、代码链接和文件管理变得非常容易操作和理解,因此即使在所有权变更之后,项目也经历了最小的中断。
VS 代号也是另一个热门选择。它几乎与操作系统无关,并支持与一些外部工具的集成,如 PyLint、Node.js 和 SQL。其他流行的 IDE 选择有 Jupyter 和 Spyder ,尤其是在实验阶段。MATLAB 主要用于学术领域,但也是支持整个应用程序代码的可行选择。
实验跟踪
机器学习不像软件开发那样简单。它涉及对数据、模型、特征组合甚至资源的多次实验,以找到达到最佳结果的优化路线。实验必须是可重复的,以便峰值结果可以被重新追踪并部署到生产中。
像 MLFlow 、 Neptune 和Weights&bias这样的工具支持实验跟踪和元数据记录,以建立和维护可追踪和可再现的实验,这些实验适合于快速分析和选择。另一个值得关注的独特工具是层,它有助于构建、跟踪和训练所有机器学习项目元数据。协作式 ML 对于扩大规模至关重要,这也是我们 Censius 选择与 Layer 合作,将协作式且易于监控的 ML 项目引入社区的原因。
性能赋值
为了分析性能,需要跨实验和数据段对结果进行比较和监控。由于涉及到多个实验和比较,因此监控工具如 Comet 、 Censius 和apparent AI会自动执行该过程,并在满足预先配置的条件时触发。
托管工具使数据科学家能够创建监视器,而无需编写任何代码或与工程团队协作。对标准和定制指标的支持也很关键,因为复杂的用例依赖于非常具体的定制指标。此外,将性能与其他检测到的问题(如模型漂移或数据质量差)相关联的能力非常适合根本原因检测。像 Censius 这样的工具可以帮助团队满足上述必备的需求以及一些有用的特性。
第 3 阶段:部署
部署阶段是解决方案和最终用户之间的直接连接器,使其成为 ML 生命周期中最重要的方面之一。这一阶段的重点是基础设施、环境和模型服务管道的一致性。
即使是微小的细节,如最新模型版本与生产环境之间的不兼容,也可能暗示着不久的将来会出现停机。自动化部署管道的很大一部分可以在大范围内处理这些微小的细节。
部署堆栈|作者图片
模型服务
模型服务是在本地、公共云或私有云上托管开发的机器学习解决方案的过程。模型服务阶段的主要目标是确保集成应用程序或最终用户可以轻松访问解决方案。
Cortex 、tensor flow Serving(tensor flow Extended 可用)、 Seldon 和 Torchserve 是一些模型服务工具,它们允许 API 管理和可伸缩性、多模型服务、轻松的云可访问性、协作和更多选项来简化生产。
资源虚拟化
资源虚拟化支持隔离的环境和实验,这些环境和实验构成了 ML 生命周期中易于管理的模型训练、模型选择和部署阶段的基础。它还优化了生产环境中的故障排除,为再现性和可扩展性铺平了道路。
- 虚拟机
虚拟机类似于容器,不同之处在于它允许虚拟化 ML 管道的所有层,包括硬件层,而容器只提供软件层。
当需要运行具有不同操作系统要求的多个应用程序时,虚拟机是理想的选择。虚拟机由几家供应商提供,包括行业领导者,如 VMware 、谷歌、甲骨文和 Azure 。
- 容器
集装箱化是隔离环境的行为,以保持清洁的实验,不损害或改变其他实验,并容易实现操作,如 A/B 测试。它使开发人员能够轻松地管理开发和部署活动,使过渡更加顺畅。容器非常容易运输,独立于平台,轻量级,并且易于管理。 Kubernetes 和 Docker 对于部署独立的微环境是有效的。自动化工具如 Kubeflow 和 Flyte 优化和管理运行在容器上的复杂工作流程。
容器通常比虚拟机更加便携和高效,因为它们可以利用主机操作系统,而不必每次都启动一个。由于在实际需求中更加灵活和经济,容器在大多数情况下已经超过了虚拟机。
测试
模型和基础设施测试通过在模型预测到达最终用户之前过滤掉次要问题和主要问题来确保高质量的客户体验。需要在各种环境和容器中进行测试。
测试工具通常应该与广泛的基础设施一起工作,无论是内部部署、云还是容器,并支持跨培训和生产环境的 A/B 测试和故障排除。各种测试支持的几个选项包括functionalize、app advance和 Seldon Core 。
模型监控
生产中的输入流带来原始数据,管道对这些数据进行处理,以提供预测作为输出。一旦事件被触发,通常在预测之后,就会记录另一个实际值的输入流。
监控工具确保不仅跟踪原始数据和模型输出,而且跟踪实际值,以检测任何不自然的行为。生产中的监控需要彻底,包括数据质量、模型漂移、偏差、流量和性能监控。其中每一项都可以通过几个指标进行评估,这些指标由自动化监控工具跟踪,如 Censius 、 Fiddler 和亚马逊 SageMaker 以及人工智能可观察性工具,如 Censius 。
监控只是解决人工智能问题的开始。要解决触发显示器的问题,详细解释导致该问题的原因至关重要。重要的是用模型可观察性扩展模型监控,因为它提供了每个模型决策的完整剖析。这样,根本原因很容易被识别并迅速修复,使开发者能够大规模地构建可解释的和负责任的人工智能。
最后一个音符
随着人工智能从业者测试和汲取现代人工智能堆栈的好处,更多的工具正在出现以满足需求。虽然有太多的工具可供选择来构建整体的人工智能堆栈,但您需要检查三个要点:
- 对该工具的投资是否远低于从头构建其功能的成本?
- 该工具是否易于采用和使用,是否有可靠的客户支持?
- 该工具的可定制性是否足以满足基本需求之外的附加功能?
一旦你勾掉了主要条件,其他因素如易用性、平台、与基础设施无关的设置、无代码或低代码能力等。可以被照顾。
人工智能堆栈可能会势不可挡,尤其是对那些刚刚开始这一旅程的人来说。诀窍是通过自动化和声明性方法来接近第一个具有成本效益且可大规模实现的垫脚石。
取得联系!
如果你想了解更多关于 MLOps 和可靠的 AI 框架,请参考我们的资源(博客、电子书、白皮书)。如果您有任何问题或想了解更多信息,欢迎发送电子邮件至 hello@censius.ai 或在此分享您的评论。
使用 Sklearn、Pandas 和 Numpy 进行时间序列预测的完整指南
在 Python 中使用任何 scikit-learn 模型进行时间序列预测的实践教程和框架
介绍
时间序列预测有很多所谓的传统模型,比如 SARIMAX 系列模型、指数平滑,或者 BATS 和 TBATS 。
然而,我们很少提到最常见的回归机器学习模型,如决策树,随机森林,梯度推进,甚至支持向量回归机。我们看到这些模型广泛应用于典型的回归问题,但不是时间序列预测。
因此写这篇文章的原因!在这里,我们设计了一个框架,将一个时间序列问题框定为一个监督学习问题,允许我们从我们最喜欢的库中使用任何我们想要的模型: scikit-learn !
到本文结束时,您将拥有将任何机器学习模型与上述统计模型一起应用于时间序列预测的工具和知识。
我们开始吧!
完整的源代码可以在 GitHub 上获得。
用我的 免费时间序列小抄 在 Python 中学习最新的时间序列分析技巧!获得统计和深度学习技术的实现,全部在 Python 和 TensorFlow 中!
准备数据集
首先,我们导入完成教程所需的所有库。
import numpy as np
import pandas as pd
import statsmodels.api as sm
import matplotlib.pyplot as plt
这里,我们使用 statsmodels 库来导入数据集,这是从 1958 年到 2001 年的每周 CO2 浓度。
data = sm.datasets.co2.load_pandas().data
一个好的第一步是用下面的代码块可视化我们的数据。
fig, ax = plt.subplots(figsize=(16, 11))ax.plot(data['co2'])
ax.set_xlabel('Time')
ax.set_ylabel('CO2 concentration (ppmw)')fig.autofmt_xdate()
plt.tight_layout()
1958 年至 2001 年的周 CO2 浓度(ppmv)。我们注意到,由于季节的原因,数据中存在明显的年度季节性(冬季的 CO2 浓度高于夏季)。还有一个明显的积极趋势,我们注意到数据集开始时有一些缺失的数据。图片由作者提供。
从上图中,我们注意到数据中明显的积极趋势,因为浓度随着时间的推移而增加。我们还观察到一种年度季节性模式。这是由于季节的变化,冬季的 CO2 浓度高于夏季。最后,我们在数据集的开头看到一些缺失的数据。
然后,让我们用插值法处理缺失的数据。我们将简单地在两个已知点之间进行线性插值来填充缺失值。
data = data.interpolate()
既然我们没有丢失数据,我们就可以开始建模了!
使用 scikit 建模-学习
正如您将看到的,用 scikit-learn 预测时间序列的最大挑战是正确设置问题。
有 3 种不同的方法可以将时间序列预测问题构建为监督学习问题:
- 使用之前的观察预测下一个时间步
- 使用一系列过去的观察结果预测下一个时间步
- 使用一系列过去的观测值预测一系列未来的时间步长
让我们详细探讨每种情况!
使用之前的观察预测下一个时间步
这是最基本的设置。该模型输出下一个时间步长的预测,仅给出前一个观察值,如下图所示。
根据前面的观察,模型被训练来预测下一个时间步。图片由作者提供。
这是一个几乎没有实际应用的简单用例,因为一个模型很可能不会仅仅从之前的观察中学到任何东西。然而,它可以作为一个很好的起点,帮助我们理解后面更复杂的场景。
现在,我们的数据集看起来像这样:
作者图片
这不是很有用。没错,所有的值都在一列中,但是我们需要格式化数据集,使得当前观察值是预测下一个观察值(目标)的特征。
因此,我们添加了第二列,该列简单地移动了 co2 列,使得 1958–03–29 的值现在是 1958–04–05 的值的预测值。
df = data.copy()df['y'] = df['co2'].shift(-1)
数据集没有被格式化为监督学习问题,其中当前观察是特征,下一个观察是目标。图片由作者提供。
正如您所看到的,我们的数据集现在已经格式化,因此每个当前观察都是下一个观察的预测值!请注意,我们的数据集末尾缺少一个值。这对于最后已知的观察来说是正常的。我们将在以后的步骤中删除该行。
现在,让我们将数据集分成训练集和测试集,以便运行我们的模型并对它们进行评估。这里,我们使用最近两年的数据作为训练集。由于我们有每周数据,并且一年有 52 周,这意味着最后 104 个样本被保留用于测试集。
train = df[:-104]
test = df[-104:]
test = test.drop(test.tail(1).index) # Drop last row
基线模型
当然,我们需要一个基线模型来确定使用机器学习模型是否更好。这里,我们天真地预测下一个观察值将与当前观察值相同。
换句话说,我们简单地将 co2 列设定为我们的基线预测。
test = test.copy()
test['baseline_pred'] = test['co2']
基线预测只是简单地重复未来已知的观察。图片由作者提供。
太好了!完成这一步后,让我们继续更复杂的模型。
决策树
这里,让我们应用一个决策树回归器。这个模型可以被 scikit-learn 库中您想要的任何模型替换!请注意,我们使用随机状态来确保可重复性。
from sklearn.tree import DecisionTreeRegressorX_train = train['co2'].values.reshape(-1,1)
y_train = train['y'].values.reshape(-1,1)
X_test = test['co2'].values.reshape(-1,1)# Initialize the model
dt_reg = DecisionTreeRegressor(random_state=42)# Fit the model
dt_reg.fit(X=X_train, y=y_train)# Make predictions
dt_pred = dt_reg.predict(X_test)# Assign predictions to a new column in test
test['dt_pred'] = dt_pred
测试集现在有来自决策树模型的预测!图片由作者提供。
注意,我们保持建模部分简单。我们不执行任何交叉验证或超参数调整,尽管这些技术可以正常应用于此,就像在任何其他回归问题中一样。
随意运用这些技巧,看看你是否能得到更好的表现。
梯度增强
为了尝试不同的模型,让我们现在应用梯度推进。
from sklearn.ensemble import GradientBoostingRegressorgbr = GradientBoostingRegressor(random_state=42)gbr.fit(X_train, y=y_train.ravel())gbr_pred = gbr.predict(X_test)test['gbr_pred'] = gbr_pred
测试集现在具有来自梯度推进模型的预测。图片由作者提供。
太好了!我们现在有了来自两个机器学习模型和一个基线的预测。是时候评估每种方法的性能了。
评估
这里,我们使用平均绝对百分比误差(MAPE)。这是一个特别有用误差指标,因为它返回一个百分比,很容易解释。确保只在没有接近 0 的值时应用它,这里就是这种情况。
不幸的是,MAPE 还没有在 scikit-learn 中实现,所以我们必须手工定义这个函数。
def mape(y_true, y_pred):
return round(np.mean(np.abs((y_true - y_pred) / y_true)) * 100, 2)
然后,我们可以评估每个模型,并生成以下条形图:
baseline_mape = mape(test['y'], test['baseline_pred'])
dt_mape = mape(test['y'], test['dt_pred'])
gbr_mape = mape(test['co2'], test['gbr_pred'])# Generate bar plot
fig, ax = plt.subplots(figsize=(7, 5))x = ['Baseline', 'Decision Tree', 'Gradient Boosting']
y = [baseline_mape, dt_mape, gbr_mape]ax.bar(x, y, width=0.4)
ax.set_xlabel('Regressor models')
ax.set_ylabel('MAPE (%)')
ax.set_ylim(0, 0.3)for index, value in enumerate(y):
plt.text(x=index, y=value + 0.02, s=str(value), ha='center')
plt.tight_layout()
每种预测方法的 MAPE。这里,基线提供了最佳性能,因为它具有最低的 MAPE。图片由作者提供。
看上面的图,我们看到基线具有最好的性能,因为它具有最低的 MAPE。这是有道理的,因为二氧化碳浓度似乎不会从一周到另一周发生剧烈变化。
在这种情况下,使用机器学习模型并没有给我们带来任何附加值。同样,这可能是因为模型仅从一个观察中学习来做出预测。最好给它一个序列作为输入,以便预测下一个时间步。
这就把我们带到了下一个场景!
使用一系列过去的观察结果预测下一个时间步
正如我们在前面的例子中所看到的,使用单个观察值来预测下一个时间步并不是很好。现在,让我们尝试使用一个序列作为模型的输入,并预测下一个时间步,如下所示
采用输入序列预测下一时间步的模型的模式。图片由作者提供。
同样,我们必须格式化我们的数据集,以便我们有一系列过去的观察值作为下一个时间步的预测值。
我们可以很容易地编写一个函数,通过添加移位的列来获得所需的输入长度。
def window_input(window_length: int, data: pd.DataFrame) -> pd.DataFrame:
df = data.copy()
i = 1
while i < window_length:
df[f'x_{i}'] = df['co2'].shift(-i)
i = i + 1
if i == window_length:
df['y'] = df['co2'].shift(-i)
# Drop rows where there is a NaN
df = df.dropna(axis=0)
return df
让我们使用这个函数输入 5 个观测值,以便预测下一个时间步。
new_df = window_input(5, data)
结果数据集。如你所见,我们现在有 5 个观测值作为下一个时间步的预测值。图片由作者提供。
查看上图,我们可以看到我们的数据集以这样的方式排列,我们有五个观察值来预测下一个时间步,存储在 y 列中。
这基本上解决了最难的部分!现在,简单的问题是应用不同的模型,看看哪个表现最好。
在进入这一步之前,让我们首先将数据分为训练集和测试集。
from sklearn.model_selection import train_test_split
X = new_df[['co2', 'x_1', 'x_2', 'x_3', 'x_4']].values
y = new_df['y'].values
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42, shuffle=False)
基线模型
同样,让我们为这种情况定义一个基线模型。这里,我们将简单地预测输入序列的平均值
baseline_pred = []
for row in X_test:
baseline_pred.append(np.mean(row))
决策树
同样,让我们应用决策树回归器。这与前面的实现一样简单。
dt_reg_5 = DecisionTreeRegressor(random_state=42)
dt_reg_5.fit(X_train, y_train)
dt_reg_5_pred = dt_reg_5.predict(X_test)
梯度增强
为了保持一致,我们也来试试梯度提升。
gbr_5 = GradientBoostingRegressor(random_state=42)
gbr_5.fit(X_train, y_train.ravel())
gbr_5_pred = gbr_5.predict(X_test)
评估
我们现在可以评估每个模型的性能。同样,我们使用 MAPE 并将结果绘制在柱状图中。这基本上是和以前一样的代码。
baseline_mape = mape(y_test, baseline_pred)
dt_5_mape = mape(y_test, dt_reg_5_pred)
gbr_5_mape = mape(y_test, gbr_5_pred)# Generate the bar plotfig, ax = plt.subplots()
x = ['Baseline', 'Decision Tree', 'Gradient Boosting']
y = [baseline_mape, dt_5_mape, gbr_5_mape]
ax.bar(x, y, width=0.4)
ax.set_xlabel('Regressor models')
ax.set_ylabel('MAPE (%)')
ax.set_ylim(0, 2.5)
for index, value in enumerate(y):
plt.text(x=index, y=value + 0.1, s=str(value), ha='center')
plt.tight_layout()
MAPE 针对不同的预测方法使用五个观测值来预测下一个时间步。同样,机器学习模型并没有超越基线。图片由作者提供。
令人惊讶的是,从上图中,我们看到机器学习模型并没有超越基线。
虽然超参数调整可能会提高 ML 模型的性能,但我怀疑输入窗口太短。五周的输入不足以让模型获得趋势和季节性成分,因此我们可能需要更长的时间窗口。
我们将在下一个场景中尝试这样做!
使用一系列过去的观测值预测一系列未来的时间步长
最后一个场景是使用一系列观察值来预测一系列未来的时间步长,如下所示。
采用输入序列并预测未来时间步长序列的模型架构。图片由作者提供。
这里,我们的模型需要输出一系列预测。这可以看作是一个多输出回归问题。
因此,第一步是适当地格式化我们的数据集。我们开发了另一个函数,它使用 shift 方法将数据集格式化为多输出回归问题。
def window_input_output(input_length: int, output_length: int, data: pd.DataFrame) -> pd.DataFrame:
df = data.copy()
i = 1
while i < input_length:
df[f'x_{i}'] = df['co2'].shift(-i)
i = i + 1
j = 0
while j < output_length:
df[f'y_{j}'] = df['co2'].shift(-output_length-j)
j = j + 1
df = df.dropna(axis=0)
return df
这里,我们将使用 26 个观测值的序列来预测接下来的 26 个时间步。换句话说,我们输入半年来预测下半年。注意,输入和输出序列不需要具有相同的长度。这是我的一个武断的决定。
seq_df = window_input_output(26, 26, data)
数据集未格式化,因此 26 个观察值是接下来 26 个时间步的预测值。图片由作者提供。
如您所见,我们现在有一个数据集,其中 26 个观测值用作接下来 26 个时间步长的预测值。
在继续建模之前,我们再次将数据分为训练集和测试集。这里,我们为测试集保留最后两行,因为它给了我们 52 个测试样本。
X_cols = [col for col in seq_df.columns if col.startswith('x')]
X_cols.insert(0, 'co2')
y_cols = [col for col in seq_df.columns if col.startswith('y')]X_train = seq_df[X_cols][:-2].values
y_train = seq_df[y_cols][:-2].values
X_test = seq_df[X_cols][-2:].values
y_test = seq_df[y_cols][-2:].values
基线模型
作为基线模型,我们将简单地重复输入序列。换句话说,我们获取输入序列并输出与基线预测相同的序列。
这是一个非常琐碎的预测,所以我们将在准备评估模型时实现它。
决策树
同样,让我们尝试应用决策树。注意,决策树可以产生多输出预测,所以我们不需要在这里做任何额外的工作。
dt_seq = DecisionTreeRegressor(random_state=42)
dt_seq.fit(X_train, y_train)
dt_seq_preds = dt_seq.predict(X_test)
梯度推进
现在,梯度推进需要一点额外的工作。它不能处理多输出目标。试图立即拟合梯度增强模型将导致错误。
在这里,我们必须包装模型,以便它的预测被用作下一个预测的输入。这是通过使用来自 scikit-learn 的回归链包装器实现的。
from sklearn.multioutput import RegressorChain
gbr_seq = GradientBoostingRegressor(random_state=42)
chained_gbr = RegressorChain(gbr_seq)
chained_gbr.fit(X_train, y_train)
gbr_seq_preds = chained_gbr.predict(X_test)
这允许训练模型并进行预测,而不会遇到任何错误。正如我提到的,在幕后,模型预测下一个时间步,并使用该预测进行下一次预测。这种方法的缺点是,如果第一个预测是坏的,那么序列的其余部分很可能也是坏的。
现在我们来评价一下每一款。
评估
同样,我们使用 MAPE 来评估我们的预测方法。
mape_dt_seq = mape(dt_seq_preds.reshape(1, -1), y_test.reshape(1, -1))
mape_gbr_seq = mape(gbr_seq_preds.reshape(1, -1), y_test.reshape(1, -1))
mape_baseline = mape(X_test.reshape(1, -1), y_test.reshape(1, -1))# Generate the bar plotfig, ax = plt.subplots()
x = ['Baseline', 'Decision Tree', 'Gradient Boosting']
y = [mape_baseline, mape_dt_seq, mape_gbr_seq]
ax.bar(x, y, width=0.4)
ax.set_xlabel('Regressor models')
ax.set_ylabel('MAPE (%)')
ax.set_ylim(0, 1)
for index, value in enumerate(y):
plt.text(x=index, y=value + 0.05, s=str(value), ha='center')
plt.tight_layout()
所有多输出回归模型的 MAPE。这里,ML 模型优于基线,决策树是最好的模型。图片由作者提供。
从上图可以看出,我们终于成功训练出了跑赢基线的 ML 模型!在这里,决策树模型是冠军模型,因为它实现了最低的 MAPE。
我们可以选择将去年的预测可视化。
fig, ax = plt.subplots(figsize=(16, 11))ax.plot(np.arange(0, 26, 1), X_test[1], 'b-', label='input')
ax.plot(np.arange(26, 52, 1), y_test[1], marker='.', color='blue', label='Actual')
ax.plot(np.arange(26, 52, 1), X_test[1], marker='o', color='red', label='Baseline')
ax.plot(np.arange(26, 52, 1), dt_seq_preds[1], marker='^', color='green', label='Decision Tree')
ax.plot(np.arange(26, 52, 1), gbr_seq_preds[1], marker='P', color='black', label='Gradient Boosting')ax.set_xlabel('Timesteps')
ax.set_ylabel('CO2 concentration (ppmv)')plt.xticks(np.arange(1, 104, 52), np.arange(2000, 2002, 1))
plt.legend(loc=2)fig.autofmt_xdate()
plt.tight_layout()
可视化去年每个模型的预测。显然,基线偏离得很远,而决策树和梯度推进更接近实际值。图片由作者提供。
进一步支持 MAPE,我们可以看到决策树和梯度推进比基线预测更接近实际值。
在本文中,我们看到了如何将时间序列预测问题构建为一个回归问题,可以使用 scikit-learn 回归模型来解决该问题。
我们探讨了以下场景:
- 使用之前的观察预测下一个时间步
- 使用一系列过去的观察结果预测下一个时间步
- 使用一系列过去的观测值预测一系列未来的时间步长
我们现在有了一个框架,可以将任何时间序列预测问题构建为一个监督学习问题,在这个框架中,您可以应用来自 scikit-learn 的任何回归模型。
我希望这篇文章对你有用!
一定要下载我用 Python 写的免费时间序列预测小抄,涵盖统计和深度学习模型!
干杯!🍺
毫无经验的数据分析师的完整路线图
该路线图将指导您通过业余学习成为一名数据分析师
伊森·道在 Unsplash 上拍摄的照片
伟大的辞职是离开你不成功的职业去成为一名数据分析师的最佳时机。
从未有过如此大规模的人员外流,他们寻找更好的机会,包括提升空间、灵活的工作条件、办公室的尊重和公平的工资。
如此多的人在寻找一个新的开始,难怪他们中的许多人都在期待诱人的技术世界提供他们需要的改变。数据科学、分析和工程仍然是那些希望改变职业的人在最抢手的工作。
虽然你可能认为上面提到的三个学科是相同的,但它们在资格和工作职责上有很大的不同。对于那些希望快速转换到不同领域而不必花费数年时间学习的人来说,成为数据分析师可能是正确的选择。
数据分析师天生具有使用数据讲述故事的能力。他们利用现有的数据,使用 SQL、Excel 等工具和 Tableau 等数据可视化工具生成可视化和报告,用外行人的语言描述数据的当前状况。工作职责包括确定业务问题,使用 SQL 从数据库中提取数据,使用 Excel 和可视化工具进行分析和生成可视化结果,以及开发向利益相关方展示分析结果的报告。根据工作的不同,可能还需要 R 或 Python 的简单编码技能,算术、代数、统计和概率的简单数学技能是标准的。
随着数据分析师职位在新的挑战之间游走,而不必在学校度过几年,对于那些想改变职业的人来说,这是显而易见的。
路线图
背景
大多数以数据为中心的职位或职业变化的路线图通常是如此广泛,以至于需要几年的全职研究才能完成。普通员工需要 11 个月的时间来规划职业变化,这使得大多数路线图与人们的需求脱节。此外,外部因素,如储蓄金额和人生承诺,可能会使大多数人无法在可行的时间内完成职业转换,导致许多人留在原来的工作岗位上。考虑到所有这些因素,该路线图将成为数据分析师的过程微调为七个短阶段,可以根据需要或快或慢地完成。
记住,要想改变职业,你只需要知道足够多的信息就能找到工作。一旦你满足了基本要求并能完成日常任务,就可以在工作中进行深入学习。
以下七个阶段应该大致按照这个顺序进行。在这些部分中,您将找到相关的在线课程来帮助您入门,以及每个阶段需要关注的关键事项。
阶段 1:编程— Excel、SQL、Python/R
数据分析师的编程要求可能会因领域和职位的不同而有很大差异。然而,大多数数据分析师职位都可以通过 Excel、SQL 和一些简单的 Python 或 r 知识来完成。
虽然 Excel 可能看起来很老派,但它仍然是一个经常使用的非常有价值的工具,易于学习,并能快速生成解释数据当前状态的结果。Excel 主要用于分析数据以确定总结和趋势。SQL 用于从数据库中检索用于分析的数据,然后可以使用 Excel 或编程语言对这些数据进行处理。Python 和 R 本质上是两种常用的数据分析编程语言,Python 比 R 更受欢迎,因为它易于使用。
学习编程技能可以上的在线课程:
下面是一些课程,可以用来快速学习数据分析所需的编程基础。这绝不是学习如何编码的一个广泛的列表或者唯一的资源,但是这些资源提供了一个很好的起点。请记住,这是一个路线图,让您获得履行数据分析师职位和执行日常任务所需的基本技能,因此,编程知识的广度是这里的目标,而不是深度。同样重要的是要注意,大多数数据分析师在 Python 或 R 之间进行选择,并把它作为他们的主要编程语言。根据你的目标行业中最常用的方法来做决定。
阶段目标结束:
在这个阶段结束时,您应该能够编写在您选择的目标语言中运行的代码。除了进行分析所必需的部分,对每种语言的广泛了解是不必要的。
值得注意的是,编程是一项最好通过实践来学习的任务。你可以坐着看这些视频,并声称在视频结束时知道如何编码,但看和做之间有明显的区别。因此,建议先看视频,然后练习编写自己的代码,看看是否还能运行。编写代码的进一步练习将在后面的阶段进行。
第二阶段:数学——算术、代数、统计和概率
如果你完成了高中/中学,或者大学课程的前几年,你通常会学到成为数据分析师所需的所有数学知识(取决于领域和职位)。很酷,对吧?与数据科学不同,数据科学需要对线性代数、微积分以及可能需要数年才能掌握的其他数学学科有深刻的理解,大多数数据分析师职位只需要你在早期教育中学习的基础数学。
因此,这个阶段应该仅仅是对你已经学过的知识的回顾,并且有可能打破你的统计和概率知识的蜘蛛网。下面的课程来自可汗学院,这是一个通过简单易懂的课程来学习数学的好地方,这些课程用简单的术语为任何水平的人解释概念。
你可以用来更新数学技能的资源:
https://www.khanacademy.org/math/algebra https://www.khanacademy.org/math/algebra2 https://www.khanacademy.org/math/ap-statistics
阶段目标结束:
在这一阶段结束时,您应该能够进行简单的计算,这些计算可用于深入了解数据。例如,您应该能够计算工资的平均值,以确定一家公司支付给员工的平均工资。或者,您需要能够在订阅网站时事通讯的人群中确定谁是离群者。或者,您需要能够计算数据集中的未知值,该数据旨在确定麻雀的速度,但只给出它们飞行的距离和时间。
在这一阶段发展的数学技能将在以后的阶段得到练习和提高。
阶段 3:数据分析—收集、清理、分析
数据分析是数据分析师的主要工作。
数据分析可以分解为五个步骤被普遍认可。
- 确定驱动问题: 认识到数据分析的驱动问题或总体目标有助于为您需要什么数据以及分析结果应该揭示什么奠定基础。
- 数据收集: 定义回答驾驶问题所需的数据将有助于您收集工作所需的正确数据。归根结底,有更多的数据来清晰地描述你在寻找什么,总比数据太少好。
- 数据清洗: 是时候通过数据清洗过程,把你收集到的原始数据变成你可以分析的东西了。这包括修改或删除不正确或不相关的数据,检查数据完整性,删除重复数据,或生成重要的值,如平均值。
- 数据分析: 分析你已经清理过的数据涉及到寻找数据内部的洞见,包括模式、关系以及预测的可能性。
- 解释: 这个阶段涉及到产生你的数据分析结果的可视化。这些可视化将讲述数据的故事,并以一种易于理解和直截了当的方式回答问题。
帮助你学习数据分析流程的资源:
阶段目标结束:
在此阶段结束时,您应该能够使用之前学习的编程和数学技能,按照上面列出的步骤进行全面的数据分析。在这些阶段不需要完全流利,因为稍后会有一个阶段,在这个阶段将创建投资组合项目,这将提高在这里学到的技能。
阶段 4:数据可视化
虽然数据可视化是作为数据分析的五个步骤的一部分讲授的,但它在这里有自己的特殊阶段,因为它在数据分析师的日常任务中扮演着如此重要的角色。能够创建引人注目的、准确的可视化是这个职业的基础之一,因此应该特别注意这些技能。
Tableau 是数据分析师创建可视化最常用的工具之一,学习它的资源将在下面介绍。其他数据可视化工具包括 QlikView、Microsoft Power BI、Datawrapper、Plotly 以及更多可能与您的目标领域或职位相关的工具。这份路线图将关注其中最突出的一个场景。
帮助您开始 Tableau 的资源:
阶段目标结束:
在此阶段结束时,您应该能够创建准确表示数据分析结果的数据可视化。这些可视化必须引人注目,易于理解,并且必须提供结果的清晰图片,而不会在视觉上扭曲信息。
第五阶段:行业知识
行业知识是您将用于解决日常问题的行业专用工具。
例如,如果你要对每年应该砍伐多少树木以确保森林健康生长进行数据分析,那么林业实践和森林管理的背景就很重要。或者,你需要有商业头脑,能够根据你的分析结果判断一家公司是否陷入财务困境。此外,如果你是一家医院的分析师,该医院正在寻找最有效的方法来安排员工在繁忙时段的工作,那么了解每个人在医院中扮演的重要角色是很重要的。
本质上,你有进行数据分析的技能,但现在你需要获得技能和知识,以便能够将它们应用于特定的行业。无论你是进入一个完全不同的行业,还是想回到当前的行业做一名分析师,重温行业知识都不会有坏处。作为一名分析师,研究最新信息有助于你保持相关性,能够识别趋势、观察模式,并提高周围人的效率和效力。
获取行业知识可以通过阅读期刊文章、参加大学讲座、听播客、阅读时事通讯、与业内人士交谈等等。
阶段目标结束:
在这个阶段结束时,你希望能够进行相关的分析,并对你的目标行业的问题提供有见地的结论。对于那些希望从事商业工作的人来说,这意味着进行分析,以确定公司决策的成本效益结构。对于那些希望从事科学工作的人来说,这意味着能够从大量证据中传播结论,这些证据可能支持也可能不支持某个假设。对于那些希望在医疗保健行业工作的人来说,这意味着能够进行分析,深入了解保持员工快乐所需的工作条件。关键在于,你需要能够自如地分析特定行业的数据,并能够为你试图解决的问题提供结论。
阶段 6:投资组合
建立你的个人投资组合是这个路线图中有趣的部分。
在这里,你有机会建立个人数据分析项目,展示你的技能,并向雇主证明他们希望你加入他们的团队。这些项目应该包括你到目前为止学到的所有技能,并且应该与你的目标行业相关。这意味着他们使用行业的工具,得出有意义的结论,甚至可能增加行业的知识库。
这些项目可以是独一无二的,可以是从互联网上看到的灵感,或者可以包括为你所在地区的一家小公司做的公益工作。快速浏览互联网可以给你一些想法和数据集,你可以用它们来创建你自己的项目。
帮助您开始构建数据分析组合的资源:
https://careerfoundry.com/en/blog/data-analytics/data-analytics-portfolio-project-ideas/
阶段目标结束:
在这个阶段结束时,你应该有一个充满数据分析项目的投资组合,可以与潜在的雇主分享。这个作品集不仅要展示你的技能,还要展示你最好的作品。投资组合是雇主了解你能为他们公司做什么的好工具,也能在面试中提供有益的话题。不仅如此,投资组合给你机会把你所有的技能放在一起,产生出成果的项目。
阶段 7:网络、工作申请和技术面试准备
路线图的最后一个阶段是网络、工作申请和技术面试准备。
你有技术。
你已经建立了你的投资组合。
现在你只需要把这一切联系在一起,得到那份工作!
人际关系网将包括参加会议和行业活动,与招聘人员交谈,与目前可能会为你说好话的分析师交往。虽然没有人喜欢人际关系网,但这是在没有工作经验的情况下,在这个行业找到工作最可靠的方法之一。如果招聘人员或招聘经理能亲自见你,他们很有可能会凭你的态度雇用你,然后再教你其他的。
接下来是工作申请,然后是准备技术面试。虽然这两个方面超出了本文的范围,但是下面列出了一些资源,可以帮助您朝着正确的方向开始。从这两方面来说,最好做好充分的准备,这样在这一天,你可以放松并享受这一经历。工作申请和技术面试是找到更多关于职位信息的好方法,你缺少什么技能,你应该准备好回答什么类型的技术面试问题。虽然乏味,这个阶段是一个很好的学习经历,将进一步巩固你已经学到的一切。
让你为社交、求职和技术面试做好准备的资源:
https://www.anaconda.com/blog/networking-in-tech-find-your-dream-data-science-job https://www.indeed.com/career-advice/finding-a-job/completing-job-application-to-get-an-interview https://www.simplilearn.com/tutorials/data-analytics-tutorial/data-analyst-interview-questions https://www.hackerrank.com/interview/preparation-kits
阶段目标结束:
在这个阶段结束时,你应该会有一份数据分析师的新工作!
你所有的努力都应该得到回报,隧道尽头的光芒应该会闪耀。
重要的是要记住,当试图进入一个你从未做过的新角色时,不得不经历许多不同公司的几次面试是正常的。诀窍是不管结果如何都要继续前进,并试着从每一次经历中学到你能学到的东西。在不到一年的时间里获得数据分析师工作的人和没有获得的人之间的区别在于,成功的人无论遭受多少次拒绝,都会继续努力。在一天结束时,你知道你有能力成为一名数据分析师,你只需要找到适合你的公司。
最后的想法
在一个你以前没有经验的新领域进行职业转变是一项令人印象深刻的努力。
虽然这无疑看起来令人生畏,但成为数据分析师的路线图比大多数人更容易管理。不用担心抽象的数学、难以理解的编程以及机器学习和人工智能等困难的概念,你可以立即成为一个讲故事的人和公司决策过程中的关键人物。
如前所述,这绝不是您成为数据分析师可以使用的资源的完整列表。这个路线图的目标是提供一个基本的方法,可以在短时间内通过兼职学习完成,以促进快速的职业转变。有些人可能需要更多的资源和时间,而有些人则需要较少的资源和时间。然而,通过遵循这个路线图,您可以开始形成成为数据分析师的道路。
订阅将我的故事直接发送到您的收件箱:故事订阅
成为会员,使用我的推荐链接可以无限制地访问媒体(我将收取少量佣金,不需要你额外付费):媒体会员
变形金刚的概念和训练变形金刚模型
变压器网络如何工作的逐步指南
什么是自然语言处理
自然语言处理是人工智能的一个分支,致力于赋予机器理解人类语言的能力。它使机器有可能阅读文本,理解语法结构,并解释句子中使用的单词的上下文含义。它在机器翻译中用于从一种语言翻译到另一种语言,常用的 NLP 翻译器是 Google Translate 。谷歌翻译可用于将文档和网站从一种语言翻译成另一种语言,支持 133 种不同的语言。OpenAI GPT-3 是创建的最先进的自然语言处理模型之一,它执行各种各样的语言任务,如文本生成,问答和文本摘要。情感分析是自然语言处理的一个重要分支,组织使用它来分析产品评论,以区分正面和负面评论。文本生成是自然语言处理的一个有趣的领域,它被用在手机的自动完成功能中,用于适当的单词建议,以及完成我们的句子。
NLP 有不同的分支,我将解释其中的一些。
- 情感分析:对文本进行分析,将文本的情感分为正面或负面。
- 文本生成:是文本的生成,在文本生成中我们提供文字提示,NLP 模型自动补全句子。
- 文本摘要:是利用 NLP 技术将长句归纳为短句。
- 语言翻译:使用自然语言模型将文本从一种语言翻译成另一种语言,例如将英语句子翻译成法语句子。
- 屏蔽语言建模:利用 NLP 模型对句子中的屏蔽词进行预测。
什么是变压器网络
Transformer 是一种神经网络架构,旨在解决自然语言处理任务。变压器网络使用一种称为注意力机制的机制来研究、理解句子中使用的单词的上下文,并从中提取有用的信息。《变形金刚》在流行论文 中被介绍由Ashish Vaswani 等人。
变压器网络的类型
我们有三种主要类型的变压器网络,即编码器、解码器和序列 2 序列变压器网络。
编码器变压器网络:这是一个双向变压器网络,它接收文本,为句子中的每个单词生成一个特征向量表示。编码器使用自我注意机制来理解句子中使用的单词的上下文,并从单词中提取有用的信息。
编码器如何能够理解这个简单的句子“编码是惊人的”的图示。
作者图片
- 图分解:编码器利用自我注意机制为句子中的每个单词生成一个特征向量或数字表示。单词“*”被分配一个特征向量 1,单词“ 被分配一个特征向量 2,单词“”被分配一个特征向量 3。单词" 是 "的特征向量既代表了单词" 是 "的上下文,又代表了其两侧单词的特征向量信息,即" 编码 "和" 惊人的 ",因此得名双向网络,因为它研究的是左右两侧单词的上下文。特征向量用于研究单词之间存在的关系,以理解所用单词的上下文,并解释句子的意思。想象一下,这是一个情感分析任务,我们要对这个句子的情感是积极的还是消极的进行分类。通过研究每个单词的上下文以及它与每个单词的关系,网络已经能够理解这个句子,因此将这个句子分类为肯定的。它是正面的,因为我们描述的是“ 编码 ”而我们用来描述它的形容词是“ 惊艳 ”。***
编码器网络用于解决分类问题,如掩蔽语言建模以预测句子中的掩蔽词,以及情感分析以预测句子中的正面和负面情感。常见的编码器变压器网络有 BERT、ALBERT 和 DistilBERT。
解码器变压器网络或自回归模型。它使用掩蔽注意机制来理解句子中的上下文以生成单词。
作者图片
- 想象一个简单的场景,我们在包含各种电影信息的文本语料库上训练解码器网络,以生成关于电影的句子或自动完成句子。我们将这个不完整的句子“ 【漫威复仇者联盟残局】 传入解码器模型,我们希望模型预测合适的单词来完成这个句子。解码器是一个单向网络,它为每个单词生成特征向量表示。它与编码器网络的区别在于它是单向的,而不是编码器的双向特性。解码器从单个上下文(右或左上下文)研究单词表示。在这种情况下,它会研究左边单词的上下文来生成下一个单词。它生成下一个单词“ 是 ”,基于前面的单词,在“ 之后是 ”它生成下一个单词“ 超级英雄 ”,在“ 之后是 ”它生成下一个单词【a】,* 最后它生成下一个单词 【电影 因此完整的句子是“ 《漫威复仇者联盟》残局是一部超级英雄电影” 。我们可以观察它如何根据前面的单词生成单词,因此单词是自回归的,它必须向后看以研究单词的上下文,并从前面的单词中提取信息以生成后面的单词。自回归网络的例子有 GPT-3 和 CTLR。*
编码器-解码器或 sequence 2 序列变换器网络:它是编码器和解码器变换器网络的组合。它用于更复杂的自然语言任务,如翻译和文本摘要。
编码器-解码器网络翻译图解:利用编码器网络对句子中的单词进行编码,生成单词的特征向量,理解上下文,从单词中提取有用的信息。来自编码器网络的输出被传递到解码器网络。解码器网络处理编码器生成的输出,并生成目标语言的适当单词,例如,我们将一个英语句子传递给编码器,它从英语上下文中提取有用的信息,并将其传递给解码器,解码器解码编码器输出,并生成法语句子。
标记化概念
单词标记化:就是把一个句子转换成单个单词。*它通常会生成很大的词汇量,这对于训练 NLP 模型来说并不理想。*
词汇量:是指一篇课文的字数。
*text = "Python is my favourite programming language"print(text.split())##Output
['Python', 'is', 'my', 'favourite', 'programming', 'language']*
这是一个示例代码,展示了单词标记化是如何完成的,我们将一个句子分割成单独的单词。
基于字符的标记化:是将句子中的单词转换成字符。例如,像“你好,大家好”这样的句子将被拆分成如下单个字符:
作者图片
与单词标记化相比,它生成的词汇量较小,但还不够好,因为将单词拆分成单个字符与单个单词本身的含义不同。
子词标记化:这是大多数自然语言处理任务中使用的最好的标记化形式。单词标记化通过将句子拆分成单个单词来处理标记化,这种方法并不适合所有情况。两个单词" 鸟 " "和" 鸟 " 在一个句子中,一个是单数,另一个是复数,单词标记化会将它们视为不同的单词,这就是子单词标记化的由来。子词标记化将合成词和生僻字划分为子词,它考虑了像 bird 和 birds、这样的词的相似性,而不是将单词 birds 拆分成两个不同的词,它表示单词【s】在单词的末尾是单词 的子词像“ 有意义的 ”这样的词会被拆分成“ 有意义的 ”和子词“ ful ”,通常在这种情况下可以在子词中加上一个特殊的字符像“ ##ful ”,来表示它不是一个句子的开头,它是另一个词的子词。子字记号化算法被用在像伯特、GPT 这样的变压器网络中。Bert 使用单词片段标记器作为其子单词标记器。**
用变形金刚训练一个蒙面语言模型
我们的主要目标是使用编码器变压器网络来训练屏蔽语言模型,该模型可以为句子中的屏蔽词预测合适的词。在本教程中,我们将使用拥抱脸变形金刚,这是一个非常好的库,可以很容易地用变形金刚训练一个模型。
这部分教程需要具备 Python 编程语言和 Pytorch 深度学习库的基础知识。
安装 Pytorch
安装其他软件包
pip3 install transformerspip3 install datasetspip3 install accelerate
微调电影评论的预训练屏蔽语言模型
我们将利用一个预训练的 DistilBERT transformer 模型,一个在 IMDb 数据集(一个包含成千上万对不同电影的评论的数据集)上训练的 BERT 的简化版本,来预测句子中的屏蔽词。
加载和标记数据集
加载 IMDB 数据
第 1–10 行:我们导入了用于加载 IMDb 数据集的模块,并打印出数据集信息以确认其已加载。我们还从数据集中随机打印出两篇评论。如果数据集加载正确,输出应该是:
DatasetDict({
train: Dataset({
features: ['text', 'label'],
num_rows: 25000
})
test: Dataset({
features: ['text', 'label'],
num_rows: 25000
})
unsupervised: Dataset({
features: ['text', 'label'],
num_rows: 50000
})
})
'>> Review: "Against All Flags" is every bit the classic swashbuckler. It has all the elements the adventure fan could hope for and more for in this one, the damsel in distress is, well, not really in distress. As Spitfire Stevens, Maureen O'Hara is at her athletic best, running her foes through in defiance of the social norms of the period. Anthony Quinn rounds out the top three billed actors as the ruthless Captain Roc Brasiliano and proves to be a wily and capable nemesis for Brian Hawke (Flynn). For the classic adventure fan, "Against All Flags" is a must-see. While it may not be in quite the same league as some of Errol Flynn's earlier work (Captain Blood and The Sea Hawk, for instance), it is still a greatly entertaining romp.''>> Review: Deathtrap gives you a twist at every turn, every single turn, in fact its biggest problem is that there are so many twists that you never really get oriented in the film, and it often doesn't make any sense, although they do usually catch you by surprise. The story is very good, except for the fact that it has so many twists. The screenplay is very good with great dialogue and characters, but you can't catch all the development
because of the twists. The performances particularly by Caine are amazing. The direction is very good, Sidney Lumet can direct. The visual effects are fair, but than again most are actually in a play and are fake. Twists way to much, but still works and is worth watching.'
它打印出 IMDb 数据集的轮廓、训练、测试和非监督部分,以及它们的行数。每行代表数据集中的一篇句子评论。训练和测试部分各有 25000 条评论,而非监督部分有 50000 条评论。最后两篇评论是从 IMDB 数据集中随机打印出来的。
标记化数据集
第 1–11 行:导入了 Autokenizer 包,我们从 DistilBERT 模型中加载了 tokenizer,这是一个 词块子词块 tokenizer 。我们创建了一个函数来表征 IMDb 数据集。
第13–15行:最后,我们调用了 tokenizer 函数,并将其应用于加载的数据集。当我们调用 tokenizer 函数时,我们从标记化的数据集中移除了文本和标签,因为不再需要它们了。我们打印了标记化的数据集,它显示了以下输出:
DatasetDict({
train: Dataset({
features: ['input_ids', 'attention_mask'],
num_rows: 25000
})
test: Dataset({
features: ['input_ids', 'attention_mask'],
num_rows: 25000
})
unsupervised: Dataset({
features: ['input_ids', 'attention_mask'],
num_rows: 50000
})
})
在数据集的每一部分我们都有两个特征,和 注意 _ 屏蔽 。input _ id是为分词生成的 id。attention _ mask是 tokenizer 模型生成的值,用来标识有用的单词的,以及要忽略的单词的输入 id,attention 值以 1 和 0 生成,1 代表有用的单词,0 代表要忽略的单词。**
串联和区块数据集
在自然语言处理中,我们需要为要训练的文本序列长度设置一个基准,要使用的 DistilBERT 预训练模型的最大长度是 512。
****第 2–6 行:我们将块大小设置为 128。因为 GPU 的利用,我们用了一个块大小为 128 而不是 512 。我们将数据集中的所有文本序列连接成一个单独的连接数据集。
****第 8–13 行:我们获得了串联数据集的总长度,创建了一个字典理解来循环遍历串联长度,并根据 128 的块大小将该串联文本划分为块。如果有非常强大的 GPU 可用,则应该使用块大小 512。连接的数据集被分成许多大小相等的块,但最后一个块通常较小,我们将删除最后一个块。
****第 18–22 行:带有组块的字典被赋予一个新的列标签,以包含组块样本的输入 id。最后,我们在标记化的数据集上应用了 concat chunk 函数。
用于评估的屏蔽测试数据集
第 1–9 行:我们从 transformers 导入了DataCollatorForLanguageModeling,这是一个用于在数据集中创建屏蔽列的默认包。数据集被向下采样到 10000,分割 10%的样本,即 1000 个用于评估的测试数据集。**
****第 13–24 行:我们定义了一个数据收集器,并定义了一个在数据集中随机插入掩码的函数。对测试数据集应用插入随机掩码函数,用掩码列替换未掩码列。屏蔽的测试数据集将作为训练期间测试模型的基础事实标签。
培训程序
****第 9–23 行:我们将批量大小设置为 32,使用 pytorch 内置的数据加载器加载训练和测试数据集。我们加载了预训练的 DistilBERT 模型,并使用了 Adam Optimizer。
****第 26–28 行:我们调用 transformers accelerator 库进行训练,它接收预训练的模型、优化器、训练和评估数据集,为训练做准备。
****第 31–37 行:我们设置了训练时期数,获得了训练数据加载器的长度,并计算了训练步数。最后,我们设置学习率调度功能,接受优化,热身步骤和训练步骤的训练。
列车代码
****第 4–7 行:我们使用 python 内置的 tqdm 定义了一个进度条用于训练进度监控,然后为输出训练好的模型设置一个目录。
****第 9–19 行:定义了一个 for 循环来循环通过多个历元,对于每个历元,我们开始数据集的训练,循环通过训练数据加载器,计算模型的输出,计算输出上的损失,使用变压器 加速器 包导入来对模型执行反向传播,使用优化器来优化模型以最小化损失。我们应用了学习率调度器,使用优化器将累积梯度设置为零,并更新了进度条。我们这样做,直到我们完成一个时期的整个数据集的训练。
****第 22–38 行:我们在测试数据集上评估了一个时期的训练模型,计算了测试数据集上的损失,类似于在训练期间所做的。我们计算了模型的交叉熵损失,然后计算了损失的指数,得到了模型的困惑度。
困惑是一种用于评估语言模型的度量。它是交叉熵损失的指数。
第 41–45 行:我们使用 加速器 保存预训练的模型,并使用标记器保存关于模型的重要文件,如标记器和词汇信息。训练好的模型和配置文件保存在输出目录文件夹MLP _ 训练好的模型 。输出目录将包含以下文件。我训练了 30 个纪元,得到了一个令人费解的值 9.19 。输出模型文件夹目录将如下所示:**
**--MLP_TrainedModels
--config.json
--pytorch_model.bin
--special_tokens_map.json
--tokenizer_config.json
--tokenizer.json
--vocab.txt**
全训码
测试训练好的模型
训练好的模型存储在MLP _ 训练模型、** 中,我们粘贴目录来设置模型值。我们打印出从模型中生成的句子列表,并为句子中的屏蔽词提供适当的值。**
- 输出
**>>> this is an excellent movie.
>>> this is an amazing movie.
>>> this is an awesome movie.
>>> this is an entertaining movie.**
我们可以从模型中看到对假面词的预测,分别是惊艳牛逼*** 和 娱乐 。这些预测与完成句子完全吻合。***
我们已经成功地训练了一个带有编码器转换器网络的屏蔽语言模型,该网络可以找到正确的单词来替换句子中的屏蔽单词。
我已经将我训练的屏蔽语言模型推送到 huggingface hub,它可供测试。检查拥抱人脸库上的蒙版语言模型****
**https://huggingface.co/ayoolaolafenwa/Masked-Language-Model
测试屏蔽语言模型的 Rest API 代码
这是直接从拥抱脸测试屏蔽语言模型的推理 API python 代码。
输出
washington dc is the capital of usa.
它产生正确的输出, 华盛顿特区是美国的首都。
用转换器加载屏蔽语言模型
使用这段代码,您可以轻松地用转换器加载语言模型。
输出
is
它打印出预测的掩码字“ 是 ”。
Colab 培训
我创建了一个 google colab 笔记本,上面有创建拥抱脸账户、训练蒙面语言模型以及将模型上传到拥抱脸库的步骤。检查笔记本。
https://colab.research.google.com/drive/1BymoZgVU0q02zYv1SdivK-wChG-ooMXL?usp=sharing
查看 github 资源库以获取本教程
https://github.com/ayoolaolafenwa/TrainNLP
结论
我们在本文中详细讨论了自然语言处理的基础知识、转换器的工作原理、不同类型的转换器网络、使用转换器训练屏蔽语言模型的过程,并且我们成功训练了一个可以预测句子中屏蔽单词的转换器模型。
参考文献
https://huggingface.co/course/chapter1/2?fw=pt
https://github.com/huggingface/transformers
通过以下方式联系我:
领英:https://www.linkedin.com/in/ayoola-olafenwa-003b901a9/
推特: @AyoolaOlafenwa***
假设检验中的混淆矩阵
原文:https://towardsdatascience.com/the-confusion-matrix-explained-part-1-5513c6f659c1
使用混淆矩阵识别和理解 I 型错误、II 型错误和幂。
罗伯特·卡茨基在 Unsplash 上的照片
在推理分析(如 A/B 测试)和预测分析(如分类)中,混淆矩阵对于理解和评估统计测试或预测模型的某些任务非常有用。两者都涉及做出二元决策。在假设检验中,我们拒绝或未能拒绝零假设,在二元分类中,分类器将预测一个观察结果是肯定的还是否定的。
这两项任务都允许我们将结果组织成一个 2x2 的混淆矩阵,显示真阳性和假阳性,以及真阴性和假阴性。如果你看下面的两个矩阵,你会发现两个矩阵的结构都是一样的,矩阵主对角线上的条目对应正确的决策。
作者图片
作者图片
虽然矩阵以相同的方式构造,并且本质上也包含相同类型的测量,但是矩阵中包含的信息根据上下文而不同地命名和使用。在假设检验中,混淆矩阵包含不同结果的概率,这有助于我们理解检验的某些属性,如 I 型和 II 型错误和功效。在二元预测或分类中,每个方块(TP、FP、TN 和 FN)的计数用于计算不同的度量来评估某个预测模型。
在本文中,我们将在假设检验的背景下研究混淆矩阵。你可以在这里阅读关于分类问题的混淆矩阵。
可视化假设检验
假设检验是检验两个样本分布之间的差异是否是由两组之间的实际差异引起的,或者该差异是否可以通过随机机会来解释的方法。
为了在推理分析的背景下理解混淆矩阵,查看下面的单侧假设检验的可视化表示可能会有所帮助,以显示矩阵中的四个可能结果如何与假设检验的可能事件相对应。
作者图片
作者图片
第一类误差(α)
I 型误差也称为测试的大小或显著性水平。它用 alpha 表示,通常设置为 0.05。第一类错误代表假设检验的假阳性,意味着我们错误地拒绝了假设为真的零假设。
- I 型误差(α)= P(拒绝 null | Null 为真)
如果我们比较两个组的平均值,这意味着我们错误地得出两个组的平均值不同的结论,而实际上两个组的平均值是相同的。
类型 I 错误对应于图中的红色区域。即使零假设为真,我们也会在拒绝区域找到检验统计量,并在 5%的情况下错误地拒绝零假设。很多人对此感到困惑。如果检验统计量落在拒绝区域,怎么可能是假阳性?
好吧,考虑一下 p 值的行为。(所有的测试统计,像 z,t,chisq,f 等。可以转换为范围从 0 到 1 的 p 值。)在零假设下,并且满足测试的所有假设,p 值应该在 0 和 1 之间形成均匀分布。在重复采样的情况下,我们期望一些 p 值是<0.05, due to natural variation in the data and random sampling. While it is more unlikely to draw a sample with extreme values than a sample with less extreme values, it does happen due to chance. That is why we expect that, on average, 5% of rejected nulls will be false positives.
Can we not just lower the alpha value, you might ask. We can do that, and you can see that some studies use the lower significance level 0.01. But we must be aware that this also affects the power of the test negatively which is not optimal.
Type II error (beta)
Type II error is what the matrix shows as 假阴性,并且被表示为β。这发生在当我们未能拒绝零假设的替代假设为真的时候。
- 第二类误差(β)= P(拒绝无效|备选项为真)
如果我们在比较两组的平均值,这意味着我们错误地得出了平均值没有差异的结论,而实际上两组的平均值是不同的。换句话说,当事实上存在差异时,我们无法察觉到差异。
如果测试没有足够的能力,这种情况会更频繁地发生。
力量
功效是指当零假设为假时,正确拒绝零假设的概率,即真阳性。幂是第二类错误(β)的补码:1-β。
- Power = P(拒绝 null |备选项为真)
功效是检测到均值真正差异的概率,意味着我们希望测试的功效尽可能高。通常,可接受的功率应该高于 80%。
接受较高的 I 型误差/显著性水平(α)将导致较小的β,这将增加检测真实效应的能力(能力= 1-β)。相反,如果我们降低犯 I 型错误的概率,我们也会降低功率。从混淆矩阵中可能看不出来,但如果你看一下图表,你会发现事实就是如此。α的增加导致β的减少,反之亦然。
但是,通常不建议将 alpha 值增加到 0.05 以上。我们还可以使用其他一些方法来增加功率,这些方法将在另一篇文章中介绍。
(功效相当于分类中的召回指标,也是检测到的阳性百分比的表达式。)
可信度
alpha 的补码,1-alpha,是正确拒绝零假设失败的概率,真否定。这种概率被称为测试的置信水平,在设定置信区间时使用,通常设定为 0.95 (1-alpha)。
- 置信水平(1-alpha) = P(拒绝 null 失败| Null 为真)
在我们比较平均值的例子中,这将是正确的结论,即两组之间没有差异。
应该强调的是,推理分析中的混淆矩阵代表概率,而不是单个测试的计数。在一个假设检验中,只有一个结果。概率显示了在所有假设和零假设为真的情况下,每种结果在重复测试中出现的频率。为了评估这些结果,你可以做一个控制参数的模拟。
如果我们评估类型 I 错误,运行模拟 1,000,000 次,显著性水平为 0.05,我们预计拒绝空值 50,000 次(5%的测试)。这与在单独测试中拒绝空值不是一回事。假设零假设成立,如果你拒绝零假设,出错的几率是 100%,而不是 5%。经过反复测试,平均大约有 5%的情况下会出现假阳性。
如果您对如何评估 I 型误差和功率感兴趣,欢迎您阅读这篇关于如何使用仿真评估 t-test 性能的深入文章。
分类中的混淆矩阵
原文:https://towardsdatascience.com/the-confusion-matrix-explained-part-2-6be183f180e0
使用混淆矩阵评估二元分类器的性能。如何计算性能指标以及它们告诉我们的结果。
凯勒·琼斯在 Unsplash 上拍摄的照片
在本文中,我将在评估二进制分类模型的背景下讨论混淆矩阵。你可以在这里阅读用于推理分析和假设检验的混淆矩阵。
https://medium.com/@andreagustafsen/the-confusion-matrix-explained-part-1-5513c6f659c1
在分类中,行代表实际类别,列代表预测类别。让我们使用吉娃娃或蓝莓松饼分类案例,我们想要识别其中有狗的图像来说明混淆矩阵。
作者图片
第一行显示了模型如何预测非狗的图像,我们可以看到 6 张图像被正确地分类为非狗(真正的否定)。一幅图像被错误地分类为狗(假阳性)。
第二行向我们展示了模型如何预测狗的图像。两幅图像被错误地分类为非狗(假阴性),而三幅图像被正确地分类为狗(真阳性)。
混淆矩阵本身提供了大量关于模型性能的信息,然而,我们可能想要使用一些更精确的度量。我们可以从这个矩阵中的信息计算出不同的有用指标。
准确(性)
模型的总体精度可以计算为正确预测的数量除以矩阵中所有观测值的数量:
- 准确度=(真阳性+真阴性)/(真阳性+真阴性+假阳性+假阴性)
在我们的例子中,准确率是(3 只狗+ 6 个松饼)/ (3 只狗+ 6 个松饼+ 1 个松饼+ 2 只狗)= 9/12 = 75%。
精确
Precision,也称为阳性预测值(PPV) ,表示被预测为狗的样本中有多少实际上是狗。换句话说,在所有预测为狗的图像中,正确分类的狗(真阳性)的百分比(真和假阳性):
- 精度=真阳性/(真阳性+假阳性)
在我们上面的混淆矩阵例子中,精度是 3 只狗/(3 只狗+1 个松饼)= 3/4 = 75%。
当您想要限制误报的数量时,精度非常有用。
回忆
召回指标也称为敏感度或真阳性率(TPR) ,显示被正确分类为阳性的阳性实例的百分比。有多少只狗被检测为狗?
- 回忆=真阳性/(真阳性+假阴性)
在上面的例子中,召回率是 3 条检测到的狗/(3 条检测到的狗+ 2 条错过的狗)= 3/5 = 60%。
当避免假阴性很重要时,回忆是有用的。
请注意这两个指标向我们展示的差异。虽然精度告诉我们,该模型在 75%的情况下做出正确的狗分类预测,但是回忆告诉我们,该模型只检测到 60%的狗。
精确度和召回率可以结合成两者的概括指标,称为 F1 分数。
F1 分数
F1 分数是精确度和召回率的调和平均值。当您想要几个指标的平均比率时,通常使用调和平均值。它被表示为给定的一组观察值的倒数的算术平均值的倒数,如下面一个简单的例子所示。
F1 分数的计算方法如下
其可以被重新排列
我们的示例中 F1 得分为 2 / (1/0.75 + 1/0.60) = 0.67
调和平均值给予低值更多的权重,这意味着只有当精确度和召回率都高时,F1 分数才会高。(表达式 1/precision 的值随着精度值的增加而变小。)这个 F1 分数有利于精确度和召回率相似的模型。
但是,根据分类器的上下文,您可能不希望精确度和召回率的权重相等。例如,如果您尝试对适合儿童的内容进行分类,您可能希望优先考虑高精度(避免误报)。在这种情况下,您宁愿选择较低的召回率,拒绝太多的安全项目(假阴性),同时保持较高的精确度,只保留适当的内容。或者,您可能希望在筛查疾病时优先考虑高召回率(避免假阴性)。在这种情况下,您宁愿让一些健康的人被检测为患病(假阳性),而不是遗漏患病的人(假阴性)。
理想情况下,您希望精确度和召回率都尽可能高,但不幸的是,这是不可能的。这被称为精确度/召回率的权衡。
特征
虽然准确度、精确度、召回率和 F1 分数是机器学习环境中评估二元分类器最常用的指标,但我还想包括特异性,或真阴性率(TNR)。
- 特异性=真阴性/(真阴性+假阴性)= 1 -回忆
在诊断测试中,特异性通常与敏感性(回忆)一起使用,所以我认为它应该包括在内。灵敏度衡量测试/模型检测真阳性的程度,而特异性衡量测试/模型识别真阴性的程度。与精确度和召回率(灵敏度)一样,在灵敏度和特异性(召回率)之间也有一个权衡。
在本文中,我只讨论了可以从混淆矩阵中导出的五个分类度量。还有很多,你可以在这篇维基百科文章中看到更全面的指标列表。
我希望这篇文章能帮助您理解混淆矩阵,以及如何根据它计算不同的二进制分类度量。
https://medium.com/@andreagustafsen/the-confusion-matrix-explained-part-1-5513c6f659c1
如果你喜欢阅读这样的故事,并想支持我成为一名作家,可以考虑注册成为一名灵媒会员。每月 5 美元,你可以无限制地阅读媒体上的故事。如果你注册使用我的链接,我会赚一小笔佣金。
https://medium.com/@andreagustafsen/membership
Wordle 开局不利的代价&如何避免
原文:https://towardsdatascience.com/the-cost-of-a-bad-start-in-wordle-how-to-avoid-it-2cdd63f8d599
在 Twitter 上分享 3M Wordle 游戏的经验教训
在这篇文章中,我将继续分析超过 300 万条 Wordle tweets 的数据集——首先在这里介绍——以探索我们可能了解到的人们如何玩似乎每个人现在都在玩的游戏。
虽然已经写了很多关于玩家开局猜测的重要性的文章,许多评论员提供了他们最喜欢的开局词和一些人,包括我自己,已经使用数据科学的工具来分析最佳开局词,但是,据我所知,没有人试图量化好开局的好处或坏开局的代价,或者在实践中,好开局和坏开局发生的频率我将在本文中尝试这样做,主要发现包括:
- 在 Wordle 的早期回合中猜中的正确字母/位置的数量与游戏长度之间有很强的关系——早期猜中的正确字母/位置越多,游戏越短——这并不令人惊讶。
- 然而,数据也表明前两轮非常重要:你在第二轮的表现如何是游戏时间长短的最强预测者;这种可预测性在随后的几轮中降低,表明在最初几轮后用于猜测的策略有相当大的可变性。
- 通过比较开局良好的游戏和开局不佳的游戏,我们可以估算出开局良好的的收益(或者开局不利的的成本 )。例如,开局良好的游戏比开局不佳的游戏更有可能在 3 轮内结束游戏,但是开局不佳的游戏比开局良好的游戏更有可能在 6 轮内结束游戏。
- Twitter 上分享的足够多的游戏都是糟糕开局的例子(约 18%),因此有理由建议一些玩家考虑使用更好的开局词。最佳开局词很少与糟糕的开局联系在一起(< 0.5%的游戏),而绝大多数与良好的开局联系在一起(> 93%的游戏)。
因此,如果玩家希望提高他们的单词游戏,那么一个充满信心的方法是选择一对更好的开始单词,这几乎保证提供一个好的开始,然后在游戏的剩余时间里专注于他们的努力猜对。
在接下来的内容中,我将正式定义什么是好的和坏的开始,我如何估计它们的成本和收益,讨论这些发现和结论背后的更多细节,并推荐玩家如何在自己的游戏中避免坏的开始。
Wordle @Twitter
简而言之,Wordle 玩家每天有 6 次机会猜测一个新的目标单词:每天一个单词;每个人得到的单词都一样。每次猜测后,他们被告知哪些字母在目标单词中,是在正确的位置(绿色)还是不正确的位置(黄色),以及哪些字母不在目标单词中(灰色)。这些提示帮助玩家微调他们的猜测。
一个例子 4 轮游戏的目标词灯。玩家前两次猜测的结果是 3 个正确的字母 jints(黄色的‘T’、‘I’、‘L’)。在第三轮中,玩家正确地猜出“T”的位置,然后继续正确地猜出目标单词。作者 Wordle 截图。
Wordle 的一个独特之处是,玩家可以生成他们日常游戏的图形表示,而不会透露他们的猜测(见下文),人们在 Twitter 上分享这些已经变得越来越普遍;目前每天有超过 20 万玩家分享他们的游戏。
Twitter 上分享的一个 Wordle 游戏的图片展示示例。图片作者。
论良好开端的重要性
为了这篇文章的目的,我将把一场足球比赛分成开始的(第 1 和第 2 轮)、中间的(第 3 和第 4 轮)和结束的(第 5 和第 6 轮)。在这里,我们将重点放在开始,即开始游戏。玩家从他们的第一场游戏中学到了多少,这对他们游戏的其余部分有什么影响?****
下图描绘了平均游戏时间与第二轮学习到的正确提示数的关系;显示正确提示(正确字母或正确位置)的总数,并分别显示仅正确字母的数量(无正确位置)和仅正确位置的数量(无正确字母)。毫不奇怪,我们可以看到,一般来说,我们获得的正确信息越多,平均游戏时间越短。例如,在前两次猜测中没有学到任何正确信息的游戏(总正确数= 0 )的平均游戏时长几乎为 5 轮,相比之下,在第 2 轮之前已经学到 3 个正确提示的游戏的平均游戏时长接近 4 轮;正如人们所预料的那样,学习正确的字母位置比学习正确的错位字母更有价值——它可以缩短游戏时间。
根据玩家第二次猜测后得到的提示数计算的平均游戏时间。作者配图。
图例中显示的 r 平方值传达了正确提示的数量和平均游戏长度之间的关系强度,我们可以看到,在所有三种情况下,第 2 轮后提示的数量和游戏长度之间都有很强的关系(r- 平方> 0.90 );换句话说,92–98%的游戏长度变化可以用游戏早期学到的提示数量来解释。
作为开始游戏独特重要性的进一步证据,下图绘制了平均游戏时间和第 1、2、3、4 轮正确提示总数之间的 r 平方值。前两轮的高 r 平方值(> 0.95)意味着从这两轮中获得的正确提示的数量特别能预测整个游戏的长度。当我们观察在游戏后期获得的正确提示的数量时,事情就不那么可预测了。
一轮 n 的正确提示数与游戏时长之间的关系强度(r 平方)。作者配图。
第二轮享有最高的 r 平方值(0.97),这意味着我们从我们的前两个单词中学到的东西比我们从其他任何一轮中学到的东西都更能告诉我们可能的游戏时长。换句话说,你在第二轮之前的表现如何是游戏时间长短的最强预测因素,甚至与后面几轮相比也是如此。为什么会这样?这可能表明,人们在游戏开始后使用的猜测策略有很大的可变性。
这是有道理的,因为许多玩家在前一两轮已经形成了一致的游戏风格——依靠一套首选的起始词——但在第二轮之后,他们试图将自己的猜测与他们收到的暗示相匹配,这可能具有挑战性。一些玩家把他们的努力集中在某些类型的暗示上。一些玩家可能会选择完全满足他们到目前为止收到的所有提示的单词,而其他人可能很难找到这样的单词,因此可能会选择一个折中的单词;例如,玩家可以选择一个单词,该单词与他们所学的正确位置上的字母一致,但是可能使用目标单词中已知不存在的字母。这些不同的方法会对游戏结果产生重大影响;更详细的猜测策略分析见此处。
好的开始和坏的开始
在 Twitter 数据集中,第二轮正确提示的中位数是 2,所以我将使用这个来区分好的开局(第二轮正确提示超过 2 次的游戏)和坏的开局(有<2 correct hints by round two). Based on this definition, 18% of games begin with a bad start, compared to 44% of games, which begin with a good start; this leaves about 38% of games with a 常规开局的游戏,既不是特别好也不是特别坏)。
与好的和坏的开始相关联的游戏的分数(条)以及好的和坏的开始的平均游戏长度(线)。作者配图。
我们对这些好的和坏的开始之间的区别感兴趣。该图还显示了他们的平均游戏时间,很明显,良好的开局导致游戏时间更短,每场游戏约 4 轮,相比之下,糟糕的开局每场游戏约 4.6 轮。
糟糕开局的代价
我们不考虑游戏的平均时间长度,而是考虑在到第 3、4、5 或 6 轮完成的游戏比例。这些好的和坏的开始的结果作为在最多 n 轮中结束的游戏的累积分数呈现如下。例如,只有大约 11%开局不利的游戏在最多 3 轮内结束,相比之下,开局有利的游戏有 38%。这两条线之间的阴影区域代表了一个糟糕开端的成本(或者一个良好开端的收益)。对于较早的游戏回合,这个区域更宽,这表明对于这些较短的游戏来说,开局不利的代价更大。
给定长度的游戏中好的和坏的开局的分数(上图)。一个好的开始相对于一个坏的开始的好处,基于在最多 n 轮中成功的游戏的分数(底部)。作者图表。
我们可以通过将第轮到第轮到第轮游戏结束的累积分数除以开局不利的相应分数来量化这一收益,从而得到上面的条形图。例如,三轮游戏良好开局的相对收益分数几乎是 3.5 (38%/11%),这意味着与糟糕开局相比,良好开局在最多三轮中的完成次数几乎是 3.5 倍。事实上,可以证明,糟糕的开局导致 6 轮比赛的次数是良好开局的两倍多。
因此,一个糟糕的开局可能会将一场短时间(3 或 4 轮比赛)的比赛转换为一场更长时间(5 或 6 轮)的比赛,如果玩家希望改善他们的游戏,那么专注于他们的开局比赛是一种重要的方式。
结论
对超过 300 万条 Wordle 推文的分析证实,正确字母和位置的数量与游戏长度之间有很大的关系——这并不令人惊讶——但也突显了开局(第 1 轮和第 2 轮)作为游戏长度最佳预测指标的重要性,这是令人惊讶的,至少对我来说是如此。换句话说,一个玩家前两次猜测的好坏很大程度上决定了他们游戏的其余部分将如何展开。
实际上,大约 18%在 Twitter 上分享的游戏开局不利,而大约 44%的游戏开局良好。这两种游戏的区别告诉我们一个坏的/好的开始的成本/收益。良好开局的好处是短游戏的比例更高(> 3 倍),而糟糕开局的代价是长游戏的比例更高(> 2 倍)。
虽然,只有 18%的游戏开局很差,但如果我们假设人们不愿意分享他们最差的表现,真实的数字可能会比这更高;一些证据表明,人们分享失败游戏的可能性远低于预期。无论哪种方式,它表明有许多球员可能会受益于一套改进的启动词。例如,在之前的帖子中,我讨论了一项分析,以揭示一对表现优于所有其他备选词的特定首发词,并且根据上述定义,这很少(< 0.5%的游戏)导致糟糕的开局。事实上,这一对启动词估计能让 93%的游戏有一个好的开始;事实上,这些话会让 70%的游戏有一个更好的开局(> 3 个正确的提示),可以预期,与常规的良好开局相比,这会产生更多的短游戏和更少的长游戏。
那么,如果你想提高你的游戏水平,你应该怎么做呢?首先也是最重要的,确定一个好的开始词对,因为这种影响现在已经很明显了,对于许多玩家来说,这是一种尝试过的值得信赖的开始游戏的方式。这也为下一轮严肃的猜测开始时节省了你的精神能量。事实上,在游戏开始后,事情变得越来越不可预测,这表明玩家猜测下一个单词的策略存在很大的可变性。然而,帮助就在眼前,因为这篇文章包含了一些实用的建议,告诉你应该如何思考你的猜测以及你用来选择下一个单词的各种信息。
如果你想更多地了解 Wordle 的数据能告诉我们人们如何玩,以及你如何能更有效地玩,那么看看我最近的帖子:
- 我从玩了一百多万场 Wordle 游戏中学到了什么
- 如何在 Wordle 中猜对
- 300 万条 Wordle Tweets 之后:对 Tweets 的分析揭示了关于 Wordle、它的词和它的玩家的什么。
- 峰字和难字
犯统计错误的代价
原文:https://towardsdatascience.com/the-cost-of-making-statistical-errors-b8dcb5767e1d
统计数字
数据科学家犯统计错误的成本影响指南
当你还是个孩子的时候,你可能读过“喊狼来了的男孩”这个故事。这是一个牧羊人的故事,他曾经谎称看到了狼,并向人们求救,而实际上并没有狼。他反复这样做是为了取乐,但是当真的有狼的时候,他大声呼救却没有人来,因为村民们认为他又在撒谎了。这是一个很受孩子们欢迎的故事,尤其是在道德教育和伦理课上,他们被告知要诚实,不要撒谎,因为这个世界不相信骗子。
来自 Pexels 的 alleksana 的照片:https://www . Pexels . com/photo/wood-dirty-writing-abstract-4271933/
人类并不总是说谎,有时只是判断和衡量上的错误,这可能会产生严重的后果,并有可能改变企业、社会和环境。网上有很多实用的信息资源,详细解释了统计错误的不同类型,这些错误的原因是什么,以及如何防止这些错误。然而,一个人在生意中所做的每一个决定都有影响。在本文中,我解释了如何确定统计错误的成本影响。
这篇文章概述如下。我们将通过一些例子简要介绍统计中的错误类型。之后,我们定义了机器学习中与错误分析领域相关的一些术语:精确度、召回率和特异性。此后,我们将学习如何通过考虑其经济成本来决定哪个错误对您的业务更有害。我们将通过讨论减少错误的各种方法来结束这篇文章。这是一篇面向实践者和/或初学数据科学家的一般性文章,所以我避免使用数学术语和统计符号。如果你有任何问题,我可以参加讨论。所以,不再拖延,让我们开始吧。
统计中的误差类型
我们需要理解的第一件事是误差这个术语。误差是一个量的实际值和确定/收集值之间的差异。误差越大,我们对现实的估计就越低。举个例子,如果外面的实际温度是 21℃,但是我的机器说是 20℃,那么和实际值就有 1℃的差异或者 4.76%的偏差。我们是否可以接受这种误差取决于我们将如何处理这种测量,以及不准确测量的商业成本。统计优化的目标之一是减少我们的模型在各种情况下的误差,以便它足够健壮,可以在许多情况下使用。
类型 I:假阳性错误(假警报)
第一类错误,也称为假阳性错误,发生在某些东西实际上不真实或不存在,但被确定为真实或存在的时候。例如,如果我做了 COVID 测试,那么 I 型错误(假阳性错误)会将我识别为阳性,而实际上我不是阳性。另一个例子是在没有火灾时发出火警,这是发出假警报。另一个例子是将某人定罪为罪犯,而事实上他们并不是罪犯,或者在某人没有怀孕的时候测试其是否怀孕。这些都是假阳性的例子。
第二类:假阴性错误(失误)
第二类错误,也称为假阴性错误,发生在某事实际上是真实的或存在的,但被确定为不真实或不存在时。例如,如果我做了 COVID 测试,那么第二类错误(假阴性错误)会将我识别为阴性,而实际上我不是阴性。另一个例子是,当真的发生火灾时,不发出火警。另一个例子是宣告某人无罪,而事实上他们是罪犯,或者测试某人是否怀孕,而他们实际上是怀孕了。这些都是假阴性的例子。
前面的例子表明,将某事定义为假阳性或假阴性取决于在那种情况下如何定义“阳性”。例如,如果看到火灾的实例被认为是肯定的,那么当没有火灾时,假肯定将发出假警报。然而,如果看不到火的实例被视为阳性,那么假阳性将是看到火。出于实用目的和理解的简单性,事件的发生被认为是积极的。所以,看到火被认为是积极的。
一些重要术语
既然你对假阳性和假阴性这两个术语有了相当的理解,那么在我们讨论统计错误的经济成本之前,让我们再来理解三个术语。从用于商业目的的应用机器学习的角度来看,这些术语很重要。像前面一样,我们将使用现实生活中的例子来回顾这些概念。
假设您在一家金融机构工作,该机构向申请人提供的利率取决于他们过去的信用状况。违约概率较高的人将获得较高的利率,而违约概率较低的人将获得较低的利率。为了简单起见,假设您被要求制作一个模型,将申请人分为高风险或低风险借款人。因为我们有很多人不违约,只有一些人违约,所以我们会有一个不平衡的数据集。因此,我们不能仅仅根据准确性来评估模型的性能,因此我们需要额外的指标来评估性能。
对于这个例子,我们将默认为正。因此,违约的人会被认为是积极的。我们现在将定义和理解回忆或敏感性、特异性和精确性。
回忆或敏感度或真阳性率
敏感度或回忆是衡量一个模型能够多好地识别真正的阳性,即高风险借款人。在我们的示例中,true positive 代表识别将违约的借款人的模型,因此给他们一个高风险标签,以便他们的利率高于那些违约风险较低的借款人。如果我们的模型的灵敏度不高,这将转化为更多的人获得低风险评级,从而降低利率,因为模型将无法辨别真正的积极因素,也就是说,识别更多的人将被归类为低风险。从财务角度来说,这对企业来说可能是危险的,因为更多的人会违约,而模型预测这些人是低风险的借款人。因此,在这种情况下,我们的模型应该具有高灵敏度。
特异性或真阴性率
专一性是衡量一个模型能够多好地识别真正的负面因素,即低风险借款人。在我们的例子中,true negative 代表识别不会违约的借款人的模型,从而给他们一个低风险标签,因此他们的利率比那些违约风险较高的借款人低。如果我们的模型的特异性不高,这将转化为更多的人获得更高的利率,因为模型将无法辨别真正的负面影响,也就是说,识别更多的人将被归类为高风险。从财务角度来说,这可能是好事,因为银行会有更多的收入,但这也可能意味着一些借款人不会借款,因为借款成本太高,这将导致企业失去客户或客户变得沮丧并转向竞争对手。有了数据,人们将能够确定哪个成本更高,失去客户(失去潜在收入)还是从现有客户身上赚更多钱。
精确度或阳性预测率
精度是模型识别能力的度量。换句话说,如果你的模型将 500 人确定为违约风险高的人,但实际上,只有 400 人违约(过去的数据),那么模型的精度是 400/500 = 0.8
在这一点上,值得一提的是,孤立地讨论精确度、召回率或特异性是没有帮助的。您应该知道所有这三个值,然后才能估计该措施的成本。
统计错误的经济成本
评估统计错误的成本包括两个步骤。首先是定义你所说的积极。例如,在我们前面的例子中,一个人违约被认为是积极的。第二步是计算假阳性率(假警报率)和假阴性率(漏检率)。如果假阳性率很高,这意味着许多人被评定为高风险,这对业务不利。如果假阴性率很高,这意味着许多人被认为是低风险的,这反过来使企业赔钱。假设我们的模型的假阳性率为 0.2,这意味着在 100 人中,我们的模型将 20 人识别为假阳性,因此 20 名客户将因被标记为可能的高风险借款人而沮丧。但是,如果我们的模型的假阴性率是 0.15,这将意味着 100 个应该是高风险人群的人中有 15 个被归类为低风险人群,从而潜在地导致企业亏损。如果一个普通的违约者给企业造成 50 万印度卢比的损失,那么假阴性率的成本将是每个错误识别的客户 0.15X500000 = 75000。要计算假阳性率和假阴性率,建议找到混淆矩阵,并计算相关值。
来源:混乱矩阵https://en.wikipedia.org/wiki/Confusion_matrix
如何减少错误
你永远不可能消除所有的统计误差。有办法减少它们。这些是你可以用来减少统计误差的方法。
- 第二类误差与统计检验或模型的功效成反比。统计检验的能力可以定义为它辨别现实并因此正确拒绝无效假设的真正能力。这意味着统计检验的功效越高,犯第二类错误的概率就越低。因此,您可以增加测试的能力。这可能涉及成本,因为更大的功率导致更大的样本量,从而导致更高的成本。减少第二类错误导致犯第一类错误的增加。因此,您应该评估犯这些错误的成本影响。
- 减少 I 型错误的方法之一是最小化显著性水平(当假设为真时拒绝零假设的概率)。由于显著性水平是由研究者选择的,所以该水平是可以改变的。例如,显著性水平可以最小化到 1% (0.01)。这表明有 1%的概率会错误地拒绝零假设(两个变量之间没有差异的假设)。
摘要
在本文中,我们讨论了各种类型的错误、它们的原因、成本影响以及减少这些错误的方法。我的信念是,这将有助于你对各种错误的成本估算做出明智的决定。此外,必须理解统计误差只能最小化,而不能完全消除。处理错误的最好方法是继续努力减少错误,并进行额外的检查和平衡(例如,保险)以减少做出错误判断的影响。
原载于 2022 年 2 月 7 日【https://aayushmalik.substack.com】。
维度的诅咒
原文:https://towardsdatascience.com/the-curse-of-dimensionality-69acc63eebd6
为什么不把所有的变量都放入你的模型中
虽然这很酷,但这篇文章并不是关于海盗在他们的维度帆船上穿越平行现实,而是关于那些你想把所有变量都塞进你的模型,看看它是否能消化它们的时刻。相信我:如果你这样做,你会被诅咒的,我会告诉你为什么和怎么做。
匿名作者,http://www.pikist.com/free-photo-srces
诅咒本身
我已经听过很多次了,起初,它甚至是有意义的:“模型中的信息越多越好,所以我将把所有这些变量都放进去,并得到完美!”这就是人们,或者更确切地说是建模工作,获得诅咒的方式:在他们的特征空间中放置大量变量,急剧增加其维度。
嗯,在大多数情况下,当你继续增加数据集中的变量数量(或者相反,向量空间的维数)时,过一段时间后,你会发现你的模型越来越难得到可靠的结果。这似乎违反直觉,是维度的诅咒。
那么,为什么添加变量会有问题呢?为什么会有维度的“诅咒”?
稀疏向量空间
诅咒的第一个原因是拓扑性的:空间中的维度(变量)越多,数据点之间的“空间”就越大,因为随着维度数量的增加,距离会逐渐“拉长”。
设 A 和 B 是 N 维欧氏空间中的数据点:
如果我们再增加一个维度,效果将会是:
由于添加到总和中的新项是平方的,其影响将总是正的,因此,除非所有数据点在新维度中具有相同的坐标(即:我们添加了一个常量变量),否则随着我们向数据集添加变量,总距离将总是增加。换句话说:维数更多的向量空间也更稀疏。
甚至更多:让我们考虑ε是由于增加了一个新的变量而增加的距离的百分比,假设我们增加的所有变量只对我们的向量空间有相同的贡献。
如果我们再向数据集添加一个变量,向量空间的体积将乘以(1 + ε),因此,如果我们在新的向量空间中再插入 V 个变量,它的体积将增加(1 + ε)的 V 次方倍。这意味着,随着我们向数据集添加更多的变量,它的向量空间变得指数级稀疏。
那么,再一次,稀疏向量空间有什么问题?
更稀疏的向量空间是一个问题的原因与我们使用平方度量来检测差异的原因相关,例如 MSE(均方误差)度量中的平方误差或计算方差的平均值的平方偏差。除了它使所有数字都为正数这一事实(我们可以通过取绝对值来实现这一点)之外,对指标求平方强调了数据点之间的每一点差异,因此我们就像通过放大镜一样看待它们。
这种“放大效应”对于检测偏差来说是完美的,但是当它太强时,对于聚类和分类来说可能是有问题的,因为同一聚类或类中的点之间的非常微小的差异将被视为较大,使得非常相似的数据点看起来与其余的数据点如此分离,以至于其他相似(但不那么相似)的数据点将被视为属于不同的组。这造成了数据集中大量聚类的假象,而实际上数据集中只有少数几个聚类,这可能会使理应属于某个类的元素在我们的模型中看起来像是离群值。即使在最好的情况下,它也会增加我们预测的方差(请告诉我你会估计你的模型的预期误差……你会这样做,对吗?问起来总是健康的。)
既然我们之前谈到了海盗,一个戴着滑稽帽子、牙齿很少的瘦子举起了手,用传统的海盗语言告诉我们他找到了解除诅咒的方法。由于迄今为止我们一直依赖欧几里得距离来描述诅咒,所以我们所要做的就是离散化我们的变量,并且通过在不同类型的空间中航行,我们将把讨厌的诅咒沉入黑暗的深处,并让它留在那里!每个人都欢呼,但坏消息来了…
可惜事情没那么简单。当你增加一个离散空间的体积时(比如说,一个具有曼哈顿距离的空间),它的离散可能位置的数量呈指数增长,并且它开始表现得越来越像欧几里得空间,因此,虽然我们讨论的效果对于离散变量来说会有所减弱,但增加太多的离散变量会使你走上同样的道路——这只是考虑稀疏性,正如我们将在前面看到的,这只是问题之一。
干得好,菜鸟…但你还是被诅咒了。
组合学难题
我们在数据科学中使用的大多数模型只不过是数学近似值。我们用它们来近似回归问题中的生成函数,用它们来近似分类问题中的分离函数。这就是我们在大多数日常活动中所做的:我们近似函数。
由于数学近似的性质,极限情况(在你的域中每个维度的最左边和最右边的那些数据点)与泛化非常相关。如果你没有正确处理极限情况,当你的模型投入生产时,它们会像幽灵船的船员一样困扰着你。
这是诅咒的一部分:被可怕的极限案例所困扰。
对于一个单独的变量,您的极限情况将只出现在数字线的两侧(嗯,这不是真的,因为您可能也必须处理您的聚类的极限情况,但是让我们暂时忽略这一点……),因此,每次您在数据集中插入一个新的变量时,您不仅必须处理它的两个新的极限情况,而且必须处理新旧变量的极限情况的组合。
组合学告诉我们,对于这类问题,极限情况的数量往往是数据集中变量数量的 2 次方。这意味着:每次你插入一个新变量,你至少要处理两倍的极限情况…不考虑集群的极限情况!
由于处理极限情况需要这些方面的数据,我希望在这一点上很清楚,当你向数据集中插入新的变量时,你需要的数据量不仅会增加,而且会以指数方式增加。
当然,由于表现良好且可预测的变量的极限情况很好地符合其余数据曲线的整体形状,这根本不是问题…但是,让我们坦率地说:如果现实生活中的变量经常如此,数据科学家将面临就业市场的短缺。
如果这还不能说服你,它将说服你的经理,因为更多的数据意味着更多的内存使用,这意味着更多的“强壮”的机器来运行你的模型…所以可怕的极限情况也通过增加云提供商在年底的账单来掏你的腰包。更不用说你的数据工程师同事检查、清理、整形、存储和争论这些(大量)额外数据行的成本,以及人们必须给它们贴标签的可能成本。
这是诅咒的“组合学难题”部分:当你在数据集中插入新的变量时,你会被你的极限情况的幽灵所困扰…他们会得到你的金子。
超球形笼子
你可能听说过数学吸引子,它是一种突现的行为,迫使一些数学关系进入某种模式,在迭代过程中更常见,比如在数据集中插入一个又一个变量,然后又是一个。这正是我们在这里处理的那种怪物——如果你想知道,当你同时插入所有变量时,它也会抓住你…
让我们想象一下,我们所有的变量都有以零为中心的对称分布。这不是诅咒的必要条件,但有助于我们理解参与其中的怪物(吸引子)。我们稍后会提出这个假设。
对于我们单独选取的任何一个变量,最大的概率是它在给定的随机选择的数据点的值将接近于零。无论如何,我们的变量是弱相关的,因为两个强相关的变量不应该在同一个数据集中,因为它们给模型带来的信息很少(但是它们的全部噪声)。
由于我们的变量是弱相关的,在一个数据点中找到一个变量的边缘值(比如说,分布尾部的 5%大部分或 5%小部分)的概率独立于同一数据点的所有其他变量的值。这意味着:对于我们数据集中插入的每个新变量,对于我们数据集中的每个数据点,它有 10%的概率要么是一个小变量(5%的下尾部),要么是一个大变量(5%的上尾部)。
随着变量数量的增加,数据点超出 5%上下区域的概率显著下降(10 个变量时为 35%,20 个变量时为 12%)。有了足够的变量,几乎所有的数据点在其一个变量中至少有一个条纹值是确定的。****
此外,正如我们在关于稀疏性的讨论中所看到的,当我们向数据集添加另一个变量时,点之间的总距离永远不会减少,每个变量都会增加任意点与向量空间中心之间的距离,无论任何变量或变量组在任意点可能取值。
通常,当我们描绘一个围绕零对称分布的数据云时,我们会把它想象成一个模糊的云,它填充了围绕向量空间中心的超球体的空间。高维空间绝对不会发生这种情况。
随着新变量的加入,任何一点而非位于分布边缘的概率降低,并且一个接一个地,所有的点都位于超球面的表面,它们都离中心非常远。
更是如此,因为,对于每一个新的变量,这个过程是独立于所有其他变量的值的。实际上,它是随机的,因此,变量越多,它就越受中心极限定理的约束,使得每个数据点和向量空间的中心之间的距离正态分布在某个值周围,即超球笼的半径。
请注意,我们没有提及或关心任何变量中包含的信息…您可能会发现这真的无关紧要。
现在您可以看到怪物(将所有数据点放入数据集向量空间中的一个单一几何形状的吸引子,无论变量可能携带的信息如何)和笼子(超球体本身)。
如果您的数据不对称和/或以非零点为中心,这对我们这个可怕的怪物来说无关紧要:它只会将超球体的中心转换为数据的平均向量,并根据每个变量的分布扭曲超球体。
好吧,很可怕,但是我们所有的数据点都在超球体表面,这有什么问题呢?
还记得我说过我们的数据被放置在超球表面而不管我们的变量可能携带的信息吗?嗯,D 维向量空间中的超球面本身就是 D-1 维向量空间。
当这些风足够强大时(即:数据集中已经有太多的变量),我们的数据将被投影到一个维度更小的空间,除非投影过程仔细考虑数据集中的信息,否则仅仅这样做就可能丢失大量信息。
碰巧我们的怪物完全不关心数据中包含的信息,所以预计会有重大损失。如果变量带有大量噪声(即:它们具有小的信噪比),则更是如此。
对于嘈杂的变量,我们面临着一个悲剧,因为这整个过程使噪音能够简单地接管我们想要通过增加变量来增加的信息。
怎么会?当我们用每个新变量将数据投射到超球表面时,新空间中每个数据点的位置都携带着它(减少的)信息,但在这一过程的每一步都会受到它的全部噪声的干扰,因为破坏信息比维护信息容易得多。
最后,随着添加越来越多的噪声,超球面表面中每个数据点的位置变得越来越随机。
因此,如果它还不足以被抛入一个不断扩张的空间,同时被碰巧是抢金扒手的可怕极限案例追逐,那么你现在被一个数学怪物锁定在一个扭曲的超球体中,它也碰巧将你变平!说到诅咒,这是一个连最强悍的次元海狼都不应该掉以轻心的问题。
维度的祝福
到目前为止,我们已经看到了相当危险的事情,但是在高维空间中,并不是所有的事情都是黑暗和可怕的。你可能会发现那里有可供掠夺的黄金!
在某些情况下,在我们的数据集中插入新的变量对我们的工作有益。事实上,这正是我们最喜爱的模型之一背后的原理:支持向量机(SVM)。
SVM 的工作原理是插入至少一个新的变量——从一个学习的数学变换(一个核函数)中创建——以正确的方式扭曲我们的数据,允许线性分隔符将其分割成有意义的部分。这就是所谓的“内核把戏”。
从更高维数据集获得信息的许多其他形式是存在的,但是它们通常依赖于大量数据点的存在以便被利用(正如我们在上面的“组合学难题”一节中看到的)。
从本质上讲,在非常特定的条件下,增加数据集中变量的数量是有用的,但是为了使用任何形式的“维度祝福”,您将需要大量的数据和非常仔细的特征工程。
最后的想法
我们至少看到了构成我们所知的“维数灾难”的最重要的元素,并讨论了它们的工作方式及其对数据科学的影响。
我希望在这里可以清楚地看到:
- “更多变量”不一定意味着“更多信息”;
- 没有什么,绝对没有什么可以替代好的特征工程,当选择我们打算用什么来喂养我们的模型时;
- 我们变量的信噪比(或“信息密度”)很重要。
- 穿越高维空间是非常危险的…
如果这四点很清楚,我将认为工作已经完成。
维数灾难解释
原文:https://towardsdatascience.com/the-curse-of-dimensionality-explained-3b5eb58e5279
为什么高维数据集如此不受欢迎
玛格达·埃勒斯的照片:https://www.pexels.com/photo/orange-cube-1340185/
维数灾难在我们如何在建模之前转换数据方面扮演着重要的角色。
也就是说,尽管人们对高维数据集抱有负面情绪,但首先值得一问的是,整合太多预测特征会如何破坏模型性能。
毕竟,特性提供了预测给定目标所需的关键信息,因此认为首先存在“太多特性”这种事情似乎很奇怪。
在这里,我们解释了维数灾难,并阐明了为什么降维在特征工程中如此流行。
可视化高维度
要了解高维度的缺点,了解数据集中的要素数量如何影响特征空间非常重要。为了实现这一点,我们可以使用可视化。
作为一个例子,让我们假设我们正在寻求建立一个预测患者糖尿病的模型。对于这项任务,我们只提供了样本的体重指数(身体质量指数)作为预测特征。
我们虚构的数据集中有 5 个数据点。代表糖尿病患者的数据点为红色,而代表非糖尿病患者的数据点为蓝色。在这种情况下,特征空间可能是这样的。
代码输出(由作者创建)
当然,身体质量指数指标本身不足以准确预测患者的结果。
现在让我们假设我们使用两个特征来预测糖尿病。以下是包含身体质量指数和年龄变量的数据集的特征空间。
代码输出(由作者创建)
现在,我们有两个可用于生成预测的特征。很明显,在特征空间扩展到二维平面后,数据点之间的间隔更大了。
这一次,让我们来看看具有 3 个预测变量的数据集的特征空间是什么样的。
代码输出(由作者创建)
此外,添加第三个特征后,数据点变得更加分散。请注意,每次添加另一个特征时,特征空间会显著扩大。
总的来说,预测特征的数量越多,为用户提供的信息就越多,这些信息可用于预测目标,从而获得更好的结果。然而,通过可视化具有不同数量特征的特征空间,我们可以观察到高维数的严重缺点。
增加特征的数量使特征空间更加稀疏,这意味着每个区域的数据点更少。高度稀疏是高维数据集的一个共同特征,这可能是机器学习应用中的一个严重障碍。
高维度的有害本质被一个不祥的术语抓住了:维数灾难。
维度的诅咒
维数灾难是指由于大量预测特征产生稀疏的特征空间,模型无法识别模式并使用训练数据进行归纳。
为了理解拥有过多维度的危害,重要的是要理解增加预测特征的数量会以指数方式增加特征空间(如上例所示)。
具有巨大特征空间的模型在每个区域将具有较少的数据点,这是不希望的,因为模型通常需要每个区域足够数量的数据点,以便能够以令人满意的水平执行。
如果模型是用稀疏特征空间中的数据训练的,那么它更有可能适合于不能充分代表总体的唯一观察值。所得到的模型将不能一般化,并且在看不见的数据上表现不佳(即,过拟合)。
从前面的例子中,我们已经看到了仅仅从过渡到单独使用 2 个和 3 个特征时,特征空间的稀疏性峰值有多大。
不幸的是,现实生活中的数据集可能包含数十个、数百个甚至数千个要素!想象一下具有这种维度水平的特征空间的稀疏性(我很想展示它,但 Medium 不允许我绘制超过 3D)。
多少功能才算太多?
显然,有很强的理由不要用太多的特征来训练模型。但是,什么层次的维度才算过高呢?
最终还是要看情况。
毕竟,维度的影响基于多个因素(例如,数据点的数量、算法等。).如果不进行实验,就无法判断有多少功能会产生最佳效果。
因此,在确定高维度是否是一个问题时,创建一个可以用作参考的基线非常重要。
如果基线在训练数据上表现良好,但在测试数据上表现不佳,则它是过度拟合的,这可能是模型受到高维度阻碍的证据。
解决方法
虽然增加数据点的数量将使模型能够用高维数据集进行概括,但在现实生活中,数据通常是稀缺的。
因此,面对高维数时,最明智的解决方案是减少数据集中的要素数量。
有许多方法可以用来降低维数。这些方法通常分为两组:特征选择和特征提取。
- 功能选择
功能选择是一种简单的方法,需要选择可用功能的子集。简单地说,这意味着只保留对预测给定目标标签贡献最大的特征;其余省略。
可以使用类似正向特征选择的技术单独进行特征选择。它们也可以通过正则化等技术嵌入到算法中,其中特征可以没有权重。
执行功能选择时,值得考虑:
- 在可用的特性中,应该保留多少?
- 应该使用什么策略来剔除不需要的特性?
2。特征提取
与特征选择相比,特征提取在如何减少特征数量方面更加抽象。它以保留方差同时降低维度的方式变换要素的值(即创建替换原始要素的新要素)。
特征提取方法的例子包括主成分分析(PCA)和线性判别分析(LDA)。
执行特征提取时,值得考虑的是:
- 转换后应该有多少功能?
- 转换后应该保留多少与原始数据的差异?
关键要点
在 Unsplash 上 Prateek Katyal 拍摄的照片
简而言之,维数灾难指的是高维数据集的性质,这使得模型很难进行归纳。
虽然具有一定数量的特征对于确保模型具有足够的预测能力是必要的,但是太多的特征将使模型无法对看不见的数据执行良好的操作。
出于这个原因,在考虑训练模型时使用的特征数量时,处理机器学习任务的用户必须采用金发姑娘原则:不要太多,也不要太少。
我祝你在数据科学的努力中好运!
维度的诅咒;越多不一定越好
原文:https://towardsdatascience.com/the-curse-of-dimensionality-more-is-not-always-better-585b5a49fce3
人类向机器学习:第一部分
人工智能和机器学习概念的哲学要点
来源:作者图片
在我作为一名人工智能从业者的旅程中,我观察到我们教给机器的几个人工智能概念也可以应用在生活中,以提高我们的福祉和生产力。人类向机器学习是一个系列,我试图介绍人工智能中一些有趣的概念,并讨论它们在我们生活中的哲学相关性。
在一个机器变得越来越聪明,人类变得越来越懒惰的世界里,让我们从人类教给机器的东西中吸取一些教训,并将其应用到我们的生活中吧!因为归根结底,人工智能和给它编程的人一样好!
从我最喜欢的一句话开始 乔布斯;
每个人都应该学会给电脑编程,因为它教会你如何思考
——乔布斯
PS:我在之前的一篇文章里用过同样的语录, 没人会教你的 10 条编码原则 。嗯,这里的引用也是有效的:P
我们开始吧!
1.维度的诅咒
随着技术的到来,从 Alexa 到自动驾驶汽车,一切都由数据驱动的技术推动。据 Statista 称,到 2025 年,产生的数据量预计将增长到巨大的 181 万亿 GB!!!这个数字呈指数级增长,总数据的 90%是在过去三年中创建的。
直觉上,我们假设更多的数据意味着模型可以学习得更好,可以驱动更多的洞察力。嗯,越多越好,对吧?
答案是…..不总是这样!
这就是通常所说的 维度诅咒 !让我们从计算负担、空间体积、可视化和参数估计的角度来看看更多的数据如何影响可学性。
1.1 计算负担和空间体积
假设您是一名园丁,想要在一个 100 米长的线性花园中种植相隔 1 米的玫瑰。很简单吧?种 100 朵玫瑰就完事了。园艺太有趣了!这只是激情的问题…我爱它!!!开设了 YouTube 频道,名为 Fun with Gardening ,如何在没有任何背景的情况下进入园艺行业!😛
如果花园是一个每边 100 米的正方形花园会怎么样?在这种情况下,我们需要种植 100×100 朵玫瑰。复杂性增加了 100 倍。园艺是一项单调乏味的工作,但是如果你充满热情并且持之以恒,那么你就可以做到!如何通过持之以恒赢得人生,YouTube 视频发布!😛
100 立方米的立方花园怎么样?在这种情况下,我们需要种植 100×100×100 朵玫瑰。嗯,我突然对园艺失去了兴趣!不可能的!一个名为知道何时退出的新视频!来自园艺的生活课程发布了,订户很失望
现在想象一下,如果园丁在上述花园的某个地方留下了一把铲子,他需要找到它。他最多需要穿越 100 米,10000 米(10 公里),1000000 米( 1000 公里 whoaaa!!)分别用于每个花园。
因此,计算复杂性和空间体积随着维度的增加而呈指数增长。我们将在接下来的章节中讨论这些空间的影响。
1.2 可视化和参数估计
我们可以将数据可视化到 4 维
用 0-4D 表示数据来源:斯匹莉缇娅,公共领域,通过维基共享
之后会发生什么?数学家甚至可以使用方程轻松地表示无限维数据。顺便说一句,布鲁诺·乔亚尔在 MathExchange 的一个有趣的回答说
当有人说“高维空间难以想象”时,他们想到的是用眼睛来想象。但是数学家用大脑将形象化!
有史以来最伟大的数学家之一, 伦纳德·欧拉 ,在他生命的最后 17 年里双目失明。令人惊讶的是,他对世界的贡献有一半是在失明之后。你可以在 盲数学家的世界 里读到类似的有趣故事。
这里有一篇非常有趣的文章,作者是 迈克尔·西蒙斯 ,完成这篇文章后,请按 control/command 并点击此处稍后阅读:P
由于我们看不到更高维度的数据,我们试图外推我们对数据的直觉,直到 4D。那么数据在更高维度下是如何表现的呢?和我们到 4 D 之前对它的了解类似吗?
我们的几何直觉在高维空间中失效了
让我们通过考虑一个 d 维球体来理解这一点。
- 因此,从我们人类的直觉来看,我们假设,如果我们把稍小的球体从较大的球体中移走,大部分信息都会丢失,对吗?因为理想情况下,我们将只留下大球的表层。让我们通过计算体积的相对差值来进行数学处理。
在 3D 中,如果我们假设一个半径为 3 个单位的球体, 𝛿 为0.1,体积的相对差值为 0.096。因此,当移除内部球体时,99%以上的数据会丢失。而在更高维度中,比如说一个 100 维的球体,体积的相对差异是 0.966,当移除内部球体时,信息损失不到 1%。因此,我们可以看到,体积往往集中在更高维度的边缘周围。
1.3 含义
高维数据的这种行为如何影响我们?
- 可用数据变得稀疏。表示数据所需的空间量呈指数增长,密度随着维度的增加而降低。这一点我们可以从 1.1 节的园艺比喻中推断出来。
- 对象的“最远”和“最近”对之间的相对差异减小。
随着维度趋于无穷大,比较因素如“近”或“远”变得没有意义。这直接影响所有基于相似性的算法,如聚类。
基于它们的相对距离来检测相似的数据点是不可能的,因为它们被表示为占据如此大的空间,因此,这就像试图进行 K 均值聚类,其中 K 等于特征向量的数量,每一行将自己标识为新的聚类,从而使得信息不相关。
1.4 处理维数灾难
现在你可以看到拥有更高维度数据的含义。越多不一定越好。有时,我们会被流入大脑的大量数据淹没。无限可能的存在,让我们失去焦点,不知所措。
看不完的电影/连续剧,卷轴,课程,职业选择,YouTube 视频…..选择的挣扎是真实的!!突然间,我们都需要好好吃饭,通过比特币赚钱,担心股市,完成工作,陪伴家人,锻炼身体,社交,做爱好…啊啊啊啊…思想已经开始膨胀了…!!
这些铺天盖地的信息本质上让我们的大脑疲惫不堪,最终我们将一事无成。对生活无限可能性的担忧困扰着我们,我们最终变得悲伤和沮丧。维度的诅咒也是生活中的诅咒。
当你的头脑被思绪淹没时,如何整理东西?如何处理维数灾难?
答案是一样的。我们只是改变我们的视角,试着从不同的角度看问题。从一个新的角度来看,我们可以区分哪些信息是重要的,哪些只是噪音!这被称为主成分分析,我们将在本系列的下一篇文章中讨论。在这个信息超载的世界里,改变你的视角来理解大局!人类向机器学习:第二部分
降维——拥有的越多,看到的越少!
这里可以找到。
非常感谢您花费宝贵的时间…我希望我的观点对你有所帮助!请在 LinkedIn 或通过电子邮件告诉我您的宝贵建议和反馈。
鸣谢:维度诅咒的技术层面我从伯明翰大学计算机科学学院的伊恩·斯泰尔斯博士的讲座中学到了。花点时间来表达我对他们无价服务的感激之情!😄
一如既往,
快乐学习:D
假设因果关系的危险
原文:https://towardsdatascience.com/the-dangers-of-assuming-causal-relationships-7d4d46111742
你需要理解你的数据
在 Unsplash 上由 Nadir sYzYgY 拍摄的照片
到现在为止,我相信每个人都听过这句话,“相关性并不意味着因果关系”。无论你是在高中的第一堂统计学课、大学的研究方法课程中,还是在你自己的阅读中接触到这个概念,它都是人们记住的主要概念之一。但是,这到底意味着什么呢?
相关性:根据 dictionary.com的说法,相关性被定义为“同一组元素的两个或更多属性或度量显示出一起变化的趋势的程度。”
另一方面,一个原因被定义为“一个人或一件事以这样一种方式行动、发生或存在,使得某件特定的事情作为一个结果发生;一个效果的制作者。”
当我们处理统计学、数据科学、机器学习等问题时。,了解相关性和因果关系之间的区别可以决定你的模型的成败。我用一个例子来演示。
假设你从大学心理学课程中收集了大量数据。我们对研究学生参与对课程满意度的影响很感兴趣。
为了做到这一点,教授记录了学生参与讨论、提问或回答问题的次数。结果是一个标准化的区间分数,以便我们可以比较不同学生的参与程度。
例如,我们找到每个学生的 z 分数,然后我们可以比较他们的参与程度。接下来,我们要求学生在课程结束时提供反馈。学生们接受了一项调查,要求他们对自己的满意度进行评分,等级为 1-5。
为了进行分析,教授决定运行学生参与度分数和满意度分数之间的相关性。为此,我使用了自己的虚拟数据,包括 60 行和 2 列。第一列,敬业度,从 1 到 100 打分,然后用下面的 z 计分法标准化:
# copy the data
df_z_scaled = df.copy()
# apply normalization technique to Column 1
column = 'Engagement'
df_z_scaled[column] = (df_z_scaled[column] - df_z_scaled[column].mean()) / df_z_scaled[column].std()
# view normalized data
display(df_z_scaled)
第二栏,满意度,评分为 1-5。
为了研究这些数据,首先我们做了一个散点图。
作者提供的图表
从散点图中可以很清楚地看出,敬业度与满意度正相关,但只是为了好玩,让我们来计算一下相关系数。
from scipy.stats import pearsonr
from scipy.stats import spearmanr
# calculate Pearson's correlation
corr, _ = pearsonr(df_z_scaled.Engagement, df_z_scaled.Satisfaction)
print('Pearsons correlation: %.3f' % corr)
# calculate spearman's correlation
corr2, _ = spearmanr(df_z_scaled.Engagement, df_z_scaled.Satisfaction)
print('Spearmans correlation: %.3f' % corr2)
这是输出,它向我们展示了我们已经推断出的东西。
Pearsons correlation: 0.977
Spearmans correlation: 0.976
现在,如果数据分析师或数据科学家想要进一步研究这个问题,有几种方法可以选择。虽然过分热心的数据科学家可能想直接进入预测模型,但我们提出了一种不同的方法。
- 收集更多数据
- 继续探索性数据分析
3.确定合适的模型来回答您的具体问题
这就是因果关系假设发挥作用的地方。基于我们简短的分析结果,人们可能会认为学生的参与会导致对课程的满意。合理的假设,对吗?
不完全是。
我们只收集了两个变量的数据——参与度和满意度——但是我们怎么知道没有其他变量可以解释这种关系呢?事实上,我们怎么知道这种关系不是反方向的呢?
换个说法,看下面两个语句。
学生参与度的提高带来了更高的满意度
课程满意度提高,学生参与度提高
基于我们的一个图表,我们不知道这些陈述中哪一个是正确的。为了演示,我将交换前面图表上的轴。
作者提供的图表
虽然图表看起来不完全一样,但关系或相关性仍然存在。当一个变量增加时,另一个也增加。为了更进一步,让我们通过改变变量顺序来运行相同的相关性测试。
# calculate Pearson's correlation
corr, _ = pearsonr(df_z_scaled.Satisfaction, df_z_scaled.Engagement)
print('Pearsons correlation: %.3f' % corr)
# calculate spearman's correlation
corr2, _ = spearmanr(df_z_scaled.Satisfaction, df_z_scaled.Engagement)
print('Spearmans correlation: %.3f' % corr2)
Pearsons correlation: 0.977 Spearmans correlation: 0.976
正如你所料,结果是完全一样的。变量的顺序不会影响相关性的结果,这意味着你不能由此假设因果关系。
但是如果你做了会怎么样呢?
让我们来看看做出这种假设的危险。根据最初的研究,首席数据科学家的任务是开发一个预测模型,以确定影响课程满意度的所有因素。
学校的目标是制定干预措施来提高课程满意度,因此他们需要了解是什么导致了对课程的不满意,他们将从确定学生参与度作为其关键特征之一开始。
这是一个加快数据分析过程的例子。在 Erdogan Taskesen 的一篇文章中,他讲述了检测因果关系的一些关键步骤。这句话让我印象深刻:
如果两个随机变量 x 和 y 在统计上相关(X/Y),那么要么(a) X 导致 y,(b) Y 导致 x,要么(c)存在第三个变量 z 导致 x 和 y。此外,给定 z,x 和 y 变得独立,即 X⊥Y∣Z.
当我们的示例数据科学家假设学生参与会导致课程满意度时,他没有考虑到上面提到的其他两个选项。他不仅忽略了满意度导致参与度的可能性,还可能忽略了一个完全不同的变量,这个变量导致了 covary 的满意度和参与度。
从本质上来说,假设一种因果关系,而没有足够的数据来支持它,数据科学家就冒着开发一种不准确的模型的风险,在一个项目上浪费大量的时间和资源,而这些本来可以通过更全面的数据分析来避免。
有什么意义?
底线是,人工智能,人工智能,预测分析,都是可以用来解释因果关系的工具,但你需要先做基线分析。如果你没有收集正确的数据,全面地分析它,并客观地呈现它,你的模型就会失败。
我们需要后退一步,回到基础。
我想参考另一篇关于有效数据科学项目的步骤的非常好的文章。这是他们讨论的七个步骤:
- 问题陈述
- 数据采集
- 数据清理
- 探索性数据分析(EDA)
- 特征工程
- 造型
- 通信
正如你所看到的,建模是第六步,也就是说,这是整个过程的最后一步。虽然这些步骤不是一成不变的,但它是您分析过程的良好指南,并且它确实让您明白,如果不首先提出问题、收集数据、清理数据和探索数据,您就无法创建模型。
我们不能忘记这一进程的前四个步骤。如果我们这样做,我们就有可能陷入假设因果关系的陷阱,而事实上根本没有因果关系。
所以下次你听到相关性≠因果关系时,试着记住为什么这个概念如此重要,即使对于高级数据科学家来说也是如此。这些是你下一个伟大的 ML 模型的构建模块,如果你花时间去使用它们的话。
弗里克大桥倒塌背后的数据
原文:https://towardsdatascience.com/the-data-behind-the-frick-bridge-collapse-ac0d5a41bdd1
用 Wolfram 语言进行计算分析
美国有数以万计的桥梁,其中许多是几十年前建造的。尽管投资保持良好的维修,许多这些桥梁状况不佳,不安全。今天早上新闻报道了美国又一座重要的桥梁倒塌。事情发生在宾夕法尼亚州的匹兹堡,一座桥承载着位于弗里克公园的弗恩霍洛溪上的福布斯大道上的交通:
(这张图片和所有后续图片都是作者用 Wolfram 语言从头开始创建的)
桥梁的这种失修状态是一个有据可查的“肮脏秘密”。我看了看交通部维护的桥梁数据。该数据库包含所有重要的公共和私人桥梁及其位置和状况。这个数据库中记录的东西相当令人不安。我将使用 Wolfram 语言作为我的数据分析工具,对这些数据进行一些探索,希望从中得出一些见解。
第一步是将原始数据库下载并导入到交互式 Wolfram 语言会话中。因为我们对宾夕法尼亚州的这座桥感兴趣,所以我只下载该州的桥。第二步是通过将原始数据转换成数据集,使其“可计算”:
该数据集包含 123 个描述属性的字段,如桥梁状况、桥梁位置(纬度和经度)、建造年份,以及 1995 年的本 PDF 手册中描述的关于维护和桥梁尺寸的各种技术细节。
为了使这些数据更有意义,让我们绘制所有这些桥的地图,并了解它们是如何分布的(本文末尾的笔记本中包含了“convert”函数的定义):
在 Wolfram 语言笔记本会话中运行这段代码会产生以下输出。这张地图实际上也揭示了大量关于宾夕法尼亚州的地质信息。它紧邻公路网和许多河流和山谷:
(图片由作者提供)
我们可以放大弗里克公园附近的桥,以该位置为中心,并将绘图范围限制在该位置:
这为我们提供了以下带有红点的弗里克公园桥位置图:
(图片由作者提供)
我们还可以通过查找弗里克公园内或附近的桥梁,从所有宾夕法尼亚州桥梁的数据集中选择这座桥梁:
在 Wolfram 语言的笔记本会话中,这给出了一个格式良好的数据表。)具有所有 123 个电桥特性的全输出:
(图片由作者提供)
我们可以看到这座桥建于 1970 年,桥梁状况等级为差(P)。它最近一次检查是在 2019 年 9 月,仅桥梁的改善成本估计为 113,000 美元(从零开始重建没有列在数据中,但想必比改善成本高得多)。
这不是唯一一座被评为“差”的桥。宾夕法尼亚州共有 3198 座桥梁具有相同的“差”评级,它们分散在整个州,这里用红点表示:
(图片由作者提供)
弗里克公园的桥甚至不是一座特别“古老”的桥。有许多桥要古老得多。宾夕法尼亚州一座桥的年龄中值实际上是 1968 年,比倒塌的桥还要老两年:
(图片由作者提供)
所有这些都有助于证明基础设施维护对于保持桥梁和道路的安全非常重要。在本文中,我们看到了如何将原始数据加载到 Wolfram 语言会话中,并使其可计算。通过使用可计算的数据集,我们能够可视化宾夕法尼亚州的桥梁,并放大特定的数据。我们还了解了如何过滤全部数据,并使用过滤后的数据来可视化特定的方面或绘制特定的统计数据。我确实跳过了一些编码细节,但是本文中的所有代码都可以从这个 Wolfram Cloud 笔记本中查看和下载。
碎片化生态系统中的数据体验指南
原文:https://towardsdatascience.com/the-data-experience-in-a-fragmented-ecosystem-1e977a7f366
思考能力,而不是工具
碎片化生态系统中的数据体验—图片由 Castor 提供
本文是我们在以前的博客文章中介绍的关于数据体验的系列文章的继续。在这些文章中,我们概述了什么是数据体验,并解释了为什么我们认为它坏了。
这篇文章是关于在碎片化数据生态系统中改善数据体验的计划。但是,让我们先提醒自己什么是数据体验。
当您已经接收、存储和建模数据时,下一步是什么?
你必须在这些现有工具的基础上构建体验。数据体验是人们与公司数据互动时的感受。这是他们能够找到、理解、使用和信任他们所操作的数据的程度。
良好的数据体验有助于您利用现有的工具。它是贯穿您的数据堆栈的第二层,使第一层更加高效,让每个相关人员更容易、更顺畅地从数据中获得他们需要的东西。
在之前的文章中,我们定义了构建良好数据体验的三大支柱 : 发现、社区和健康。
在这篇文章中,我描述了如何通过创建一个强大的基础来在您的组织中构建正确的数据体验,这个基础依赖于所有三个支柱。这篇文章的目的是要了解如何在我们所处的碎片化数据生态系统中创建这一基础。关键是:考虑能力,而不是工具。
我认为是能力,而不是工具
数据体验的三大支柱及其相关功能—图片由 Castor 提供
Many 人犯了一个错误,带着工具优先的心态对待数据体验。但是这种思维过程不再起作用了——至少如果你想成功地用你的数据解决复杂的问题的话。
这种工具优先的方法不起作用,因为您最终可能会被市场上的所有工具所淹没,并过度投资于实际上无法实现改善数据体验目标的工具。
解决复杂问题的唯一方法是首先确定解决数据体验的三大支柱需要哪些功能,然后找出最适合这些功能的工具。
这种方法更好,因为您可以根据工具支持的结果来选择工具。它还允许您整合对 1-2 个工具的投资,这些工具可以解决与良好数据体验相关的大部分功能。
功能的正确组合将帮助您实现构建强大数据体验的目标。错误的工具组合可能会导致您购买十种工具,但最终只能覆盖您所需功能的 20%。选择一两个能覆盖你 80%能力的工具才是正确的方法。从能力的角度来思考,可以让您更准确地分析和评估工具。
那么,为了建立发现、健康和社区,你需要什么能力呢?
1 —发现
解锁数据发现意味着您组织中的人员可以找到、理解和平稳、高效地使用数据。就发现而言,您应该寻找以下功能:
数据谱系:追溯数据的来源、发生的情况以及随时间推移的去向。数据沿袭是在数据从数据源流向消费时理解、记录和可视化数据的过程。数据沿袭是健康和发现的组成部分。勾选这个能力,你就在这两个支柱上取得了进展。
搜索:通过强大的类似搜索引擎的功能更快地找到数据。使用元数据、术语表、分类等使查找数据资产变得容易。
上下文:用正确的上下文丰富您的数据资产。让公司里的每个人都能马上了解资产。查找关于表名、所有者、目的、上次更新、经常用户和标签的信息。
流行度:自动为您的数据资产分配一个流行度分数。立即找出最受欢迎的桌子。
查询:让所有人都可以方便的查询数据,有代码也可以没有代码。重用团队中更有经验的数据人员的查询。
访问控制:控制对敏感数据的访问,并强制遵守数据法规。
2 —社区
社区是数据体验的基本支柱。社区被定义为“一种与他人相交的感觉,是分享共同兴趣和目标的结果”。以下是可以帮助您建立良好社区体验的功能:
数据资产使用:报告和读取使用了哪些数据产品,以及用于哪些用例。
最受欢迎的查询:找到最受欢迎的查询并避免重复工作,这要归功于一个解析器,它会引用公司内部人员提出的最受欢迎的查询。
协作:允许用户建立在他们的同事的工作之上。用户可以互相标记,以标记问题,发表评论或提出问题。表格所有者可以批准其他人提出的建议。分享:在你的团队每天使用的平台上分享正确的信息。
围绕指标的一致性:访问知识库,其中定义了 KPI(关键绩效指标)和分析指标。在指标方面,让每个人都保持一致。
3 —健康
健康的数据意味着组织中的每个人都可以在需要时访问他们需要的信息,而不必担心这些信息是否准确。与健康相关的能力是 following:
异常检测:当您的数据显示任何类型的异常时,立即收到警告。
根本原因和影响分析:确定数据问题的根本原因及其可能的下游后果。
访问控制:识别和管理对私有数据的访问。
策略管理:监控谁访问数据、何时访问以及出于何种目的。根据公司角色授予或限制对不同数据资产的访问权限。
数据质量:自动给你的数据资产分配一个质量分数,让人们知道哪些数据资产是可以信任和安全使用的。
实时数据监控:收集并存储数据在网络中传输时的性能指标。
减少存储&计算支出:识别过时、未使用或低效的数据资产或查询,以便您可以删除它们或相应地更改它们的存储级别。
数据事件解决:找到事件后,快速解决事件。
II-通过发现和观察建立强大的数据体验
能力覆盖——图片由 Castor 提供
在选择工具来构建您想要的数据体验时,您不应该在您解决的功能数量上妥协。除非你解决所有三大支柱——发现、社区和健康——否则你将无法提供良好、统一的数据体验。
通过从能力的角度思考,你为实现你想要的结果打开了无数的可能性。您可以选择一个结合了多种功能的工具,也可以使用单独的工具:数据目录、数据可观察性工具、SQL 记事本、指标存储和访问管理工具。
通常情况下,我们会推荐一种中间解决方案,在这种情况下,您既不会选择一体化工具,也不会选择 5 或 6 种不同的工具。目前市场上的一体化工具可以覆盖大部分功能,但是从来没有完全覆盖。相反,使用太多工具会使你的堆栈变得杂乱,并使集成成本难以处理。在 1 到 3 个工具之间进行选择,可以让您构建强大的数据体验,同时避免在工具性能和集成成本之间进行权衡。
我们提倡只使用两种工具来构建您的数据体验:独立的数据目录和独立的数据可观察性工具。这种组合涵盖了大多数所需的功能。现代数据目录涵盖发现能力,而现代观察工具涵盖健康能力。这两个工具都覆盖了足够的协作特性,以确保第三个支柱:社区。
我们选择两个集成的独立工具,而不是一个涵盖所有功能的工具,主要有两个原因:
- 多功能工具通常在质量和方面有所欠缺。在它们所涵盖的每一项功能中,实现质量的技术壁垒都很高。我们还没有看到任何工具能够成功地在如此多的功能上实现高质量。随着更多工具的整合,这一天可能会到来。
- 一体化工具并不是为了满足不同角色的工作流程而设计的。处理数据运行状况的技术团队与参与发现的业务团队有着不同的工作流程。
我将依次讨论这两点。
1.不要在质量上妥协
你知道那句老话吗,“万事通,无所不能”?当您试图用一个工具涵盖您的所有功能时,就会发生这种情况。
选择一个包含许多功能的一体化工具可能会帮助您节省集成成本,但也有可能无法以最佳方式涵盖所有这些功能。对于市场上现有的工具来说,给工具增加更多的功能意味着你通常会牺牲质量。
你将很难找到一个在搜索&上下文和数据质量&异常检测方面都表现出色的工具。获取大部分数据意味着您需要使用多种工具,通常是一个数据目录和一个数据可观察性工具。
一个现代的、 第三代数据目录 涵盖了大部分的健康和社区功能:搜索、内容、数据谱系、数据资产流行度&使用、查询、指标校准、流行查询、共享和协作。一些数据目录还涵盖了一些健康功能,如访问控制和策略管理。如果您找不到涵盖访问控制、策略管理和其他纯数据治理功能的数据目录,我们建议在您的组合中添加一个新工具,专门关注数据治理和管理数据隐私。
现代数据可观察性工具涵盖了与健康相关的大部分功能:异常检测、数据质量、实时数据监控、根本原因和影响分析。
选择涵盖这些功能的数据目录和数据可观察性工具应该有助于您为与您公司的数据交互的人员提供出色的数据体验。
2.迎合不同的工作流程
另一个支持分离堆栈不同部分的论点是,不同的工具是为了迎合不同角色的工作流而特意构建的。
与发现相关的功能的主要用户不同于与健康相关的功能的主要用户。
数据分析师、产品科学家和其他数据消费者关心数据发现,因为他们需要找到、理解和使用数据来完成工作。
另一方面,数据工程师更关心数据管道的健康,因为他们负责修复和预防数据管道中的问题,以确保数据的可靠性。
这些不同的主要用户参与不同的工作流。数据工程师希望在他们自己的内部系统中获取数据质量信息,而数据分析师希望看到这些信息显示在数据目录中。
即使在 UI 方面,数据工程师和数据分析师也有不同的期望。一个独立的数据可观察性平台可以满足数据工程师的工作流程,而一个独立的数据目录可以满足分析师和业务用户的工作流程,而不会影响他们。
结论
总之,数据体验是您公司中的数据利益相关者在与数据交互时的感受。
数据体验建立在三大支柱之上:发现、社区和健康。为了在您的组织中创建这些支柱,我们建议关注能力而不是工具。
从能力的角度考虑是构建强大数据体验的最有效方式。它将使您在评估工具时保持冷静,并确保您选择的工具能够解决您需要的功能。
我们发现,与这三大支柱相关的大多数工具都是数据目录和数据可观察性工具。我们建议将两个独立的工具很好地集成在一起。
关于我们
我们写了利用数据资产时所涉及的所有过程:从现代数据栈到数据团队组成,再到数据治理。我们的博客涵盖了从数据中创造有形价值的技术和非技术方面。
最初发表于https://www.castordoc.com。
数据科学清单:可维护数据科学项目的最佳实践
数据科学软件工程
构建可维护数据项目的 16 个步骤
图片作者。
这些年来,我已经开发了几十个数据科学和机器学习项目,我也学到了一些教训。没有结构和标准,混乱就会接管,使得持续的进步变得困难。我已经编制了一个确保项目可维护性的最佳实践列表,我将与您分享,以便您可以在您的下一个项目中使用它。我们开始吧!
总结
在我们深入了解每一项的细节之前,先总结一下:
- 在不同的位置存储数据、工件和代码
- 在单个文件中声明路径和配置参数
- 安全存储凭据
- 通过使用一个
.gitignore
文件来保持你的存储库干净 - 端到端自动化工作流程
- 声明所有软件依赖关系
- 分离生产和开发依赖关系
- 有一个信息丰富和简洁的自述文件
- 文件代码
- 以分层结构组织您的存储库
- 打包您的代码
- 保持你的 Jupyter 笔记本简单
- 使用记录模块(不要使用打印)
- 测试您的代码
- 注意代码质量
- 删除死的和不可达的代码
1.在不同的位置存储数据、工件和代码
在处理项目时,我们会遇到三种类型的文件:
- 数据。所有原始数据和任何中间数据结果(如 CSV、txt、SQL 转储等。)
- 神器。管道执行期间生成的任何其他文件(例如,序列化模型、带有模型指标的 HTML 报告)
- 源代码。支持流水线执行的所有文件(如
.py
、.R
源代码、Jupyter 笔记本、测试)
为了让事情有条理,把每个组分成不同的文件夹;这样做将更容易理解项目结构:
2.在单个文件中声明路径和配置参数
您的管道需要从特定的源加载其原始数据;此外,您可能需要与其他系统(比如数据仓库)进行交互。最后,您需要存储结果(本地文件系统或远程存储)。一种常见的反模式是在源代码中嵌入这些配置参数,这会导致以下问题:
- 暧昧。不公开外部系统隐藏了重要的实现细节,这会让合作者感到困惑:数据在哪里?这个项目需要访问 Kubernetes 集群吗?
- 不透明。如果没有一个单独的地方来存储临时文件,每个协作者可能会开始将输出保存在任意的位置,这使得组织项目变得困难。
- 冗余。基础设施资源(即数据仓库、Kubernetes 集群)可能会被多次使用,如果配置参数不集中,会导致重复配置。
是:集中路径和配置参数
…然后从那里开始读:
否:硬编码的价值观会让你的生活更加艰难
3.安全存储凭据
您不应该在纯文本文件(包括.py
源代码或任何配置文件)中存储数据库凭证(或任何其他类型的凭证)。
是:安全地存储您的凭证(本例使用的是[keyring](https://github.com/jaraco/keyring)
库)
然后在您的脚本中:
keyring
库使用你的操作系统凭证存储,比纯文本文件更安全。前面的示例只存储密码,但是您可以存储任何其他字段。
否:存储在源文件中的凭证
4.使用一个.gitignore
文件来保持您的存储库整洁
最有可能的是,您将代码存储在 git 存储库中。因此,指定一个.gitignore
文件来保持它的整洁是必不可少的。缺少这个文件可能会使您的存储库变得不必要的混乱,并且可能会破坏您同事的项目(例如,如果您提交了一些依赖于用户的配置文件)。
在.gitignore
文件中包含什么?首先,从 Github 获取 Python 模板,其中包含了您需要的大部分内容。然后,确保您还包括通用扩展,以避免意外提交数据或配置文件。例如,如果您的原始数据是 CSV/JSON 格式,并且您有一些用户相关的 YAML 配置文件,请添加以下行:
如果您已经提交了其中的一些文件,可以使用以下命令删除它们:
请注意,这不会删除以前提交的文件。从git
中这样做是 CLI,但是 BFG 工具简化了这个过程。
5.端到端自动化数据工作流
图片作者。
一个数据项目通常需要多次数据转换。因此,自动化整个过程对于确保代码的可重现性至关重要。没有完全自动化的分析将会带来麻烦。例如,假设您必须在别人编写的项目中重新训练一个模型,那么您会在README.md
中看到下面一行:
但是接下来会得到这样一个错误:
嗯,在尝试训练模型之前,您应该构建特征,这是有道理的,但是此时,您会想知道如何这样做。
Ploomber 让自动化数据工作流变得简单,您可以添加任意数量的脚本或笔记本,然后通过以下方式协调执行:
6.声明软件依赖关系
数据科学项目通常依赖于第三方包(如 pandas、scikit-learn);未能指定它们会给任何新的合作者带来麻烦。这个错误你见过多少次了?
尽管错误消息非常具有描述性,但是记录所有的依赖关系是一个很好的实践,这样任何人都可以快速开始。在 Python 中,您可以通过一个requirements.txt
文件来实现这一点,该文件每行包含一个包的名称。例如:
然后,您可以安装所有依赖项,包括:
如果您使用的是 Ploomber ,您可以使用下面的命令来设置虚拟环境并安装所有声明的依赖项:
7.分离生产和开发依赖关系
将依赖项的数量保持在最小是有好处的。您的项目需要的依赖项越多,遇到安装问题的可能性就越大。简化安装的一种方法是将我们的依赖项分成两组:
- 运行管道所需的包 —这些是在生产中运行管道所需的包。
- 开发管道所需的可选软件包 —这些是您在项目中工作所需的可选软件包(例如,构建文档、运行探索性 Jupyter 笔记本、运行测试等)。)但在生产中并不需要。
对于我们的例子,您可能想要两个保持两个依赖文件(比如requirements.prod.txt
和requirements.dev.txt
)。然后,在开发过程中,您可以运行:
在生产中:
重要:在生产中运行时,声明每个包的具体版本是很重要的;您可以使用pip freeze
命令导出一个文件,其中包含每个已安装软件包的特定版本。如果你想省事,你可以使用 Ploomber 并执行ploomber install
,它将存储一个单独的requirements.txt
(dev 和 prod)和每个包的特定版本。
8.有一个信息丰富和简洁的自述文件
自述文件是任何使用管道的人的入口点;有一个信息丰富的文件来帮助合作者理解源文件是如何组合在一起的是非常重要的。
自述文件包括哪些内容?项目的基本信息,至少包括项目的简要描述(它是做什么的?),列出数据来源(数据从哪里来?),以及端到端运行管道的说明。
示例:
### Boston house value estimation projectThis project creates a model to predict the value of a house using the Boston housing dataset: [https://www.kaggle.com/c/boston-housing](https://www.kaggle.com/c/boston-housing) #### Running the pipeline```sh
# clone the repo
git clone [http://github.com/edublancas/boston-housing-project](http://github.com/edublancas/boston-housing-project)# install dependencies
pip install -r requirements.txt# run the pipeline
python run.py
# 9.代码文档
随着新的贡献者加入项目,文档变得更加重要。好的文档有助于理解不同的部分是如何组合在一起的。此外,文档将有助于您快速获得您不久前编写的代码的上下文。
但是文档是一把双刃剑;过时了会惹麻烦。所以,作为一个一般的建议,保持你的代码简单(好的变量名,小的函数),这样其他人可以很快理解它,并且有一些最小的文档来支持它。
**如何记录代码?**在函数定义旁边添加一个字符串(也称为 docstring ),以提供高级描述,并使用代码本身传达尽可能多的信息。
有许多 docstring 格式可供选择,但是 Python 科学界的标准格式(在上面的例子中使用)是 [numpydoc](https://github.com/numpy/numpydoc) 。
一旦添加了 docstring,就可以从 Jupyter/IPython 快速访问它,如下所示:
# 10.以分层结构组织您的存储库
随着项目的进展,您的代码库将会增长。您将拥有用于探索数据、加载、生成特征、训练模型等的代码。将代码分散在多个文件中是一个很好的实践,组织这些文件是很重要的;看一下下面的例子:
这种扁平的结构让人很难理解发生了什么以及文件之间是如何相互关联的。因此,最好有这样的**层次结构**:
# 11.打包您的代码
无论何时运行`pip install`,Python 都会进行必要的配置调整,以确保解释器可以使用这个包,因此您可以在任何使用`import`语句的 Python 会话中使用它。通过创建 Python 包,您可以为您的实用程序函数实现相同的功能;这给了你很大的灵活性来组织你的代码,然后把它导入到任何地方。
创建一个包只是添加一个`setup.py`文件。例如,如果您的`setup.py`存在于`my-project/`下,您可以这样安装它:
**注意:**我们为 Python 传递了`--editable`标志来重新加载包内容,因此无论何时更新代码和启动会话,您都将使用最新的代码。
安装软件包后,您可以像导入任何其他软件包一样导入它:
如果您修改了`some_function`,您将不得不重启您的会话以查看您的更改(假设您以可编辑模式安装软件包),如果使用 IPython 或 Jupyter,您可以通过使用[auto load](https://ipython.readthedocs.io/en/stable/config/extensions/autoreload.html)来避免重启会话:
关于 Python 打包的更详细的讨论,请看我们的博客文章。
# 12.保持你的 Jupyter 笔记本简单
笔记本是一种与数据互动的奇妙方式,但它们可能会很快失控。如果处理不当,您可能会在笔记本之间复制粘贴代码,并创建会崩溃的大型单片笔记本。所以我们写了一整篇关于写干净笔记本的文章[看看吧。](https://ploomber.io/blog/clean-nbs/)。
# 13.使用`*logging*`模块(不要使用`print`)
日志记录是软件工程中的一项基本实践;它使得诊断和调试更加易于管理。以下示例显示了一个典型的数据处理脚本:
上面例子的问题是使用了`print`语句。`print`默认发送一个流到标准输出。因此,如果每个文件都有一些`print`语句,那么每次运行管道时,您的终端都会`print`输出很多很多消息。你拥有的打印语句越多,看穿这些噪音就越复杂,它们最终会变成毫无意义的信息。
使用`logging` [模块](https://docs.python.org/3/library/logging.html)代替。日志记录最相关的特性包括:按严重性过滤消息,为每个记录添加时间戳,包括文件名和日志记录调用的起始行,等等。下面的例子显示了它最简单的用法:
注意,使用`logging`需要一些配置。查看[基础教程。](https://docs.python.org/3/howto/logging.html)
# 14.测试您的代码
测试数据管道是具有挑战性的,但是从长远来看,这是一个很好的时间投资,因为它允许你更快地迭代。虽然在项目的试验阶段,许多代码会发生变化(可能会使您的测试过时),但是测试会帮助您取得更一致的进展。
我们不得不考虑数据科学项目是实验性的,首要目标是看项目是否可行,所以你想尽快有个想法。但是,另一方面,完全缺乏测试可能会让你得出错误的结论,所以你必须找到一个平衡点。
至少,每次合并到主分支时,要确保管道是端到端的。我们已经写了大量关于数据项目测试的文章。查看我们关于[测试数据科学项目](https://ploomber.io/blog/ci-for-ds/)的文章,以及我们关于[测试机器学习项目](https://ploomber.io/blog/ml-testing-i/)的文章。
# 15.注意代码质量
人们读代码的次数比他们写代码的次数多。为了使代码更具可读性,请使用样式指南。
风格指南是关于一致性的;他们建立了一套标准的规则来提高可读性。这些规则与最大行长度、空白或变量命名有关。Python 的官方风格指南叫做[pep 8](https://www.python.org/dev/peps/pep-0008/);如果你打开链接,你会注意到这是一个很长的文档。幸运的是,有更好的方法让你跟上速度。
pycodestyle 是一个根据 PEP8 的规则自动检查代码的工具。它将扫描您的源文件,并向您显示哪些代码行不符合 PEP8。虽然 pycodestyle 限制查找不符合 PEP8 的代码行以提高可读性,但是还有更通用的工具。
pyflakes 是一个工具,它也检查可能的运行时错误;它可以发现语法错误或未定义的变量。
如果你想同时使用`pycodestyle`和`pyflakes`,我建议你使用 [flake8](https://github.com/PyCQA/flake8) ,它结合了两者和另一个工具来检查[代码复杂度](https://github.com/PyCQA/mccabe)(一个与[线性独立路径](https://en.wikipedia.org/wiki/Cyclomatic_complexity)的数量相关的度量)。
您可以通过命令行界面使用所有以前的工具。例如,一旦安装了`flake8`,您就可以通过`flake8 myfile.py`检查文件。为了使这个过程自动化,文本编辑器和 ide 通常提供插件,当你编辑或保存一个文件并突出显示不兼容的行时,这些插件会自动运行这些工具。以下是 [VSCode](https://code.visualstudio.com/docs/python/linting) 的说明。
*自动格式化*
作为对样式标记的补充,自动格式化程序允许您修复不兼容的行。考虑使用[黑色](https://github.com/python/black)。自动格式化程序可以修复代码中的大多数问题,使其符合标准;然而,仍然可能有一些东西你需要手动修复,但是它们可以节省大量的时间。
*其他棉绒*
还有其他可用的棉绒;最流行的一个是 [pylint](https://github.com/PyCQA/pylint) ,它类似于`flake8`,但是它提供了更复杂的分析。此外,还有一些其他特定的工具,如 [bandit](https://github.com/PyCQA/bandit) ,专注于发现安全问题(如硬编码密码)。最后,如果你有兴趣了解更多,可以查看 [Github](https://github.com/PyCQA) 上的 Python 代码质量权威网站。
# 16.删除死的和不可达的代码
养成删除[死](https://en.wikipedia.org/wiki/Dead_code)(输出从不使用的代码)和[不可达](https://en.wikipedia.org/wiki/Unreachable_code)代码(从不执行的代码)的习惯。
一个死代码的例子发生在我们调用一个函数,但是我们从来不使用它的输出:
在我们之前的例子中,`compute_statistics`是死代码,因为我们从来不使用输出(`stats`)。所以让我们去掉它:
我们去掉了`stats = compute_statistics(data)`,但是我们应该检查我们是否在其他地方调用了`compute_statistics`。如果没有,我们应该删除它的定义。
必须当场删除代码,因为时间越长,发现这类问题就越复杂。一些库帮助[检测死代码](https://github.com/jendrikseipp/vulture),但是最好在我们注意到它的时候做得正确。
# 最终意见
希望这些建议能帮助你改善工作流程。一旦你习惯了它们,你会发现保持你的代码库的可维护性最终会提高你的生产力。如果您有任何意见或问题,请联系我们。
*最初发布于*[*ploomber . io*](https://ploomber.io/blog/checklist/)
# 明年的数据科学展望
> 原文:<https://towardsdatascience.com/the-data-science-outlook-for-next-year-5d053b589b3a>
## 数据科学|人工智能|技术
## 讨论 2023 年数据科学的最热门趋势

照片由 [Pixabay](https://www.pexels.com/photo/low-angle-view-of-spiral-staircase-against-black-background-247676/) 拍摄
# 介绍
数据科学是商业的新领域。这是一个可以帮助你解决问题,变得更聪明,做出比以前更好的决定的领域。但是 2023 年的数据科学是什么样子的呢?
以下是对我们明年将会看到的一些预测。
# 数据科学将随着更多的数据而爆炸
* 产生的数据比以往任何时候都多。
* 从比以往更多的来源收集了更多的数据。
* 从比以往任何时候都多的设备上收集数据(包括您的手机、智能手表,甚至您的汽车!).
* 收集数据的人也比以往任何时候都多(不仅仅是人类)。
# 更多的组织将采用数据第一的思维模式
我们正处于数据科学史上的关键时刻。随着越来越多的组织和企业采用数据第一的思维模式,我们将看到新的业务方法的出现,从我们衡量成功的方式到我们如何管理风险。
是时候让你采取一种不仅仅是收集和分析数据的态度,成为这场运动的一部分了;它需要理解它的真正价值,并在整个组织中全面应用它。
# 隐私和安全将是最重要的
数据泄露近年来有所增加,仅在 2018 年就有超过 10 亿条记录被泄露。
除此之外,消费者开始对隐私问题采取行动,例如在网上或零售店购物时选择不分享他们的信息;限制与第三方(如营销人员)共享的个人信息数量;甚至采取措施使用 Signal Private Messenger 等工具对敏感数据进行加密。
企业也开始意识到保护客户数据的重要性,并采取相应的行动。
IBM 宣布,从 2020 年 1 月开始,它将为全球所有客户提供免费加密服务。
微软在其 Azure 云平台上提供免费的加密工具。
Amazon Web Services 宣布了由 Kaleido SQL Server 技术支持的私有存储解决方案的计划。
这个清单还在继续。
# 云计算将继续占据主导地位
云计算已经存在,而且它的重要性将继续增长。
随着公司需要存储无法存储在本地存储设备(即笔记本电脑或台式机)上的数据,云将变得越来越重要。
例如,大多数企业都有信用卡号或社会保险号形式的敏感客户信息,如果存储在笔记本电脑或台式计算机上,这些信息可能会被窃取。
公司也需要在需要时快速访问这些信息,用于计费或欺诈检测目的,但不希望其员工也能访问,因为这可能会使他们在执法机构调查犯罪时遇到麻烦,例如使用偷来的信用卡进行身份盗用。
当然,云计算的好处是丰富的,值得单独写一整篇文章(如果不是两篇的话)。
# 随着数据需求的暴露,对治理的需求也将增长
数据治理将随着对数据的需求而增长。
数据治理的需求已经暴露出来,是时候采取行动了。
数据治理是一个组织用来管理其数据的过程,并确保合适的人能够在他们需要的时候以安全的方式低成本获得他们需要的东西。
# 人工智能可解释性的重要性将飙升
在过去的几年里,人工智能已经成为商业和技术的热点。但是它到底是什么呢?
> “这一切背后的想法是让机器比我们人类更聪明,”加州理工学院深度学习研究中心的首席技术官克里斯·尼克尔森说。
难怪人工智能如此受欢迎。它有望通过让我们的个人生活和职业生活变得更简单来彻底改变我们的生活——从自动驾驶汽车到能够完成当今地球上大多数工作的机器人。
然而,在将任何新技术实施到您的组织中之前,确实需要做一些准备——尤其是如果所述技术涉及大量数据集,这些数据集通常需要手动解释才能实现。
# 迈向量子计算
量子计算是计算领域的下一场革命,这项技术将改变我们做事的方式。
它已经被用于科学的一些领域,它可以用来解决我们一些最大的问题,比如气候变化。
但是要让量子计算机像传统计算机一样强大还有许多挑战——而且随着时间的推移,它们只会变得越来越困难。
尽管就目前而言,量子计算仍处于初级阶段:没有多少人真正知道它们是什么或它们是如何工作的(大多数人甚至不知道“量子”是什么意思)。
# 能够将数据转化为切实可行的见解的公司将比竞争对手更有优势
您的公司正面临一个非常现实的困境:您将如何使用您的企业收集的数据?为了取得成功,您需要能够将所有这些信息转化为可操作的见解,并在您的决策过程中加以利用。
这似乎是一项简单的任务,但归根结底,那些无法将原始数据转化为有用信息的公司——或者更糟的是,甚至懒得尝试——注定要失败。
好消息是,各种规模和类型的企业都有很多方法来实现这一点!近年来,数据科学家一直处于创新的前沿,他们创建了专门为快速(准确)分析大量数据而设计的新框架和工具。这些进步意味着,任何寻求超越竞争对手的竞争优势的企业现在都可以获得!
# 生命科学正在用基因组数据改写数据科学的规则
您可能听说过基因组数据,但您可能不确定它的含义或如何使用它。让我们来看看基因组数据的一些最重要的方面,以及为什么它们与您的传统数据集如此不同。
* 基因组数据非常庞大!它可以包含数百万甚至数十亿条记录——而这只是一个人类基因组!这与其他类型的结构化数据集相比如何?以社交媒体帖子为例:根据一个消息来源(source),仅在脸书每天就有大约 170 亿条帖子发布。这还没算上 Instagram 或者 Twitter 呢!现在想象一下,尝试使用传统方法分析所有这些帖子:将每个帖子分解成组成单词/短语是不可能的,因为涉及到太多的单词/短语(平均每个帖子每句话包含 200 多个字符)。为了让我们这些不像斯蒂芬·霍金(他发现了引力波)那样的天才能够理解所有这些因共同兴趣而联系在一起的人们之间的复杂关系,仅仅通过语言而没有接触
# 创业公司正在推动数据科学的创新
创业公司正在推动数据科学的创新。
数据科学家拥有与初创公司合作的独特机会,因为他们拥有帮助企业解决问题的技能、经验和网络。在过去的几年里,使用数据的创业公司数量急剧增加,50 多家使用数据进行创新的公司就是证明:
* Airbnb 是首批将机器学习或人工智能(AI)用于其商业模式的公司之一:他们使用基于人工智能的建议,这些建议基于之前的用户行为,也基于其他旅行者在他们之前看过/做过的事情,基于他们数据库系统中存储的数百万条记录的类似模式,使他们能够将实际结果与训练阶段做出的预测进行比较。
* 优步因使用预测分析而闻名,如天气预测模型或实时地图技术,因此司机在出发前知道他们需要去哪里。他们也能够比传统出租车服务更好地预测需求。由于这一点,他们往往不仅提供更低的每英里价格,而且还提供更多的便利因素,如送货上门服务,乘客不必担心在附近找到停车位。
# Python 将继续主导编程语言市场
Python 和 R 继续主导编程语言市场。Python 是最流行的语言,世界上有超过 2000 万开发人员,围绕它有一个庞大的社区。
谷歌、脸书和网飞等大公司的数据科学家也用它来执行数据分析任务,如机器学习和预测建模。
虽然有其他语言(如 Julia)试图从整个数据科学领域分一杯羹,但 Python 提供的灵活性和成熟度可能会巩固其在该领域的领先地位。
# 物联网将继续繁荣发展
物联网(IoT)是一个大数据源,将在人工智能的发展中发挥主要作用。随着越来越多的设备连接到互联网,它们将产生大量可用于分析和预测的新数据。
亚马逊 Echo 等智能家居设备已经开始这样做了,这些设备记录用户和服务提供商之间的对话,以改善客户服务。然而,随着越来越多的公司将物联网技术用于自己的使用案例,物联网技术将继续发展,在脸书或 Twitter 等社交媒体平台上创建更多关于人类行为的有价值信息,从而为机器学习算法提供比以往更多的机会来从这些交互中学习!
我们已经看到组织对物联网的强大影响和推动,尤其是在智能家居领域。今年早些时候,Matter 被引入,这是一个建立在互操作性之上的协议。
# 机器学习即服务
机器学习即服务(MLaaS)允许企业使用机器学习,而不必投资大多数解决方案所需的基础设施或培训,这可能是昂贵且耗时的。
对于拥有小型数据科学家团队的公司来说,这也更容易,因为他们无法使用昂贵的硬件,如集群或 GPU。
这种趋势将会增长,因为更多的企业意识到他们需要超越传统统计模型的高级分析能力,这种能力只有内部团队才能提供。
# 边缘计算
边缘计算是一种在更接近数据源的地方处理数据的方法。这意味着您将能够利用近乎实时的洞察力,做出更明智的决策。
例如,如果您有一个从多个来源(例如,社交媒体平台)收集用户数据的应用程序,您可以使用边缘计算工具尽快大规模处理这些信息,然后在后端系统中使用这些见解,这样它们也可以更快地回到野外!
边缘计算还意味着能够存储大量未经处理的原始信息,而不需要昂贵的存储设备或其他基础设施,如服务器或云服务。
相反,它依赖于位置足够近的中央处理中心,以便数据可以在它们之间轻松传播,而不需要它们之间的长距离,然后它们可以通过高速互联网连接相互通信,例如安装在窗台外的光纤电缆或卫星天线,阳光直接照射到外表面,同时提供隔热,这有助于将密封容器内的温度保持在冰点(-18°C/0°F)以下。
# 虚拟分析
虚拟分析是云计算和数据科学的结合。顾名思义,这是一种新的分析方式,可以帮助公司在服务器上没有数据的情况下分析数据。
例如,如果你想知道哪些顾客最有可能在你的商店或网上买东西,你可以使用虚拟分析软件来分析来自 cookies 或用户档案(如脸书)的匿名信息,然后根据这些结果给出建议。
这意味着没有必要在你的企业附近存储实际的客户信息——该程序使用云计算系统中其他地方的分析方法完成所有工作,如亚马逊网络服务或谷歌云平台(GCP)。
# 自动机器学习
顾名思义,AutoML 是机器学习的自动化版本。它旨在自动化构建机器学习模型的过程。
AutoML 自 2016 年以来一直存在,自那以来一直在不断发展,因为它被谷歌、脸书和亚马逊等许多公司用于其产品开发流程。
# 结束语
随着我们步入 2023 年,有许多令人兴奋的趋势将继续塑造数据科学的未来。我们已经看到了机器学习和人工智能方面的一些重大进步,但随着如此多的新工具上线,似乎现在可以做的事情没有限制。
未来几年将会在这一领域带来更多的进步——毫无疑问,它们将继续改变我们对使用技术完成购物或银行业务等日常任务的看法。
如果你想让你的公司在利用数据获取商业优势方面保持领先,那么请留意明年的这些热门趋势!
你喜欢这篇文章吗?如果是,请考虑订阅我的电子邮件列表,以便在我发布新内容时得到通知。免费的:)
<https://david-farrugia.medium.com/subscribe>
**也许你也可以考虑成为一名会员来支持我和你其他喜欢的作家。每月 5 美元,你就可以无限制地阅读 Medium 上的每一篇文章。**
<https://david-farrugia.medium.com/membership>
# 想联系吗?
我很想听听你对这个话题的想法,或者任何关于人工智能和数据的想法。
如果你想联系我,请给我发电子邮件,地址:*。*
*[领英](https://www.linkedin.com/in/david-farrugia/)*
# 了解业务:我们没有充分讨论的数据科学技能
> 原文:<https://towardsdatascience.com/the-data-science-skill-no-one-talks-about-57d5d3e9f9d>
## 为什么你需要掌握这项技能,以及如何去做

黑山 Ada Bojana(图片由作者提供)
与我交谈过的每一位有抱负的数据科学家都认为,当别人给他们以下建议时,他们的工作就开始了:
1. 一个数据集,以及
2. 明确定义的优化指标,例如准确性
但事实并非如此。
它始于一个你需要理解、构建和解决的业务问题。这是区分高级和初级专业人员的关键数据科学技能。
在本文中,我将通过一个真实的例子向您展示如何训练这种数据科学技能。
# 数据科学项目的起点
在现实世界中,数据科学项目始于一个业务问题。他们生来就是要推动关键业务指标(KPI)。
数据科学家的工作是将业务问题转化为 ***right*** 数据科学问题。那就解决。
要将业务问题转化为*正确的*数据科学问题,您需要做两件事:
1. 提问
2. 探索数据,寻找线索。
> 没有什么比针对错误的业务问题构建出色的数据科学解决方案更令人沮丧的了。
我们来举个例子。
# 例子
假设你是一家顶级拼车应用公司的数据科学家。你的产品主管告诉你:
> 👩💼:“我们希望本季度将用户流失率降低 5%”
我们说,当用户决定停止使用我们的拼车应用程序时,她会感到不安。
用户流失背后有不同的原因。例如:
* “另一家拼车应用公司(又名直接竞争对手)为该地区提供了更好的价格”(定价问题)
* “汽车等待时间过长”(供应问题)
* “Android 版本的应用程序非常慢”(客户端-应用程序性能问题)
你通过向团队的其他成员提出正确的问题来建立这个列表。你需要了解用户使用 app 的体验,从她的角度出发。
通常情况下,流失背后没有单一的原因,而是几个原因的结合。问题是:你应该关注哪一个?
这时,您需要发挥您出色的数据科学技能,探索数据🔎。
你研究这些数据,以了解上述每一种解释的可能性有多大。这个分析的结果是一个假设,你应该进一步考虑。
根据不同的假设,你会用不同的方法解决数据科学问题。
例如:
# 场景 1:“竞争对手提供了更好的价格”(定价问题)
一种解决方案是以某种方式检测/预测可能流失的用户群(可能使用 ML 模型),并通过推送通知发送个性化折扣。为了测试您的解决方案是否有效,您需要运行 A/B 测试,因此您需要将一定比例的应用程序用户分成两组:
* A 组。该组中的用户不会获得任何折扣。
* B 组。模型认为这个群体中的用户可能会流失,他们将在下一次旅行中获得价格折扣。
您可以添加更多组(例如 C、D、E……)来测试不同的定价点。

从定价问题到数据科学解决方案(图片由作者提供)
# 场景 2:“汽车等待时间过长”(供应问题)
在这种情况下,不存在定价问题,但缺乏司机来接客户。问题不一样,解决方法也一定不一样。
你可以做的事情是确定供应过低的位置和时间,并为潜水员提供价格激励来填补这些空缺。这样你可以更好地平衡供需,减少汽车等待时间。

从供应问题到数据科学解决方案(图片由作者提供)
# 场景三:“安卓版 App 很慢”(App 性能问题)
想象一下,您研究了应用程序的内存消耗数据,发现最新版本的应用程序消耗的内存几乎是以前版本的两倍。

按应用版本细分应用内存消耗(图片由作者提供)
这很奇怪,所以你去问客户支持团队是否收到过用户的投诉。
事实证明,大多数用户不会联系支持部门,而是停止使用该应用程序,并使用替代产品。然而,仍然有少数用户抱怨,并提到新版本的应用程序不是“非常响应”。
答对了。你在最新版本的应用中发现了一个问题。
你如何解决这个问题?去找前端开发人员,向他们展示应用程序版本的用户流失情况,并说服他们发布性能更好的新版本应用程序。

从技术问题到数据科学解决方案(作者图片)
# 综上
* 将业务问题转化为“正确的”数据科学问题是区分高级数据科学家和初级数据科学家的关键数据科学技能。
* 提出正确的问题,列出可能的解决方案,并探索数据,将列表缩小到一个。
* 解决这一数据科学问题
# 想成为机器学习和数据科学的专家吗?
🚀 [**加入 Datamachines 时事通讯,了解 ML 和数据科学的真实世界。**](https://datamachines.xyz/subscribe/)
➡️接上 [**碎碎念**](https://twitter.com/paulabartabajo_) 🐦,[**LinkedIn**](https://www.linkedin.com/in/pau-labarta-bajo-4432074b/)**👔**
**💎 [**今天使用我的推荐链接**](https://pau-labarta-bajo.medium.com/membership) 成为会员,可以无限制地访问我在媒体上发布的所有内容并支持我的写作。**
**<https://pau-labarta-bajo.medium.com/membership>
快乐学习🤗
避寒胜地**
# 据微软称,未来的数据科学家
> 原文:<https://towardsdatascience.com/the-data-scientist-of-the-future-according-to-google-4d8545b37bdc>
最近,我建立了一个预测模型,很快就会产生巨大的价值,但我不是数据科学家,也没有受过任何数据科学方面的正式培训。这让我开始思考;为什么会有这么多的行业和教育围绕着这样专门的数据科学存在?早在 2012 年,《哈佛商业评论》发表了一篇文章,宣称数据科学家是 21 世纪最性感的工作。从那时起,数据科学领域创造了数千个工作岗位,将复杂的统计模型应用于业务问题。历史上第一次,将深奥的数学应用于普通问题变得切实可行。许多公司和整个行业都建立在数据科学实践的基础上。
这篇文章在很多方面都超越了它的时代。这篇文章断言,数据科学家的其他常见技能应该是好奇心,即编写代码、可视化数据、分析数据和有效沟通的能力。尽管数据分析师和统计学家有相似之处,但他们之间存在明显的脱节。
**数据科学教育**
随着广泛的数据科学的普及和对数据科学的兴趣,许多学院和大学在 2010 年代推出了数据科学课程,以满足这一新的需求。与今天的标准相比,当时的工具相对原始,包括 Python 或 R 语言的统计模型,这些模型必须由训练有素的专业人员仔细选择和调整,这本身就是一种艺术形式,并解释结果以最大化不同的评分方法。早期的教育计划侧重于将编程和统计作为培养数据科学家的核心课程,因为在现代工具出现之前,模型培训和解释是必要的技能。随着时间的推移,工业也在发展。核心统计数据从数据科学家那里抽象出来,取而代之的是模型可以被指示为不同的评分方法进行优化。训练模型和运行推理所需的代码减少到几乎完全抽象。当今大学教授的许多现代数据科学课程都是基于早期数据科学的普及所带来的过时技能,并且尚未适应。
**数据科学家今天在做什么?**
这种变化很大,这在这种技术革命中很常见。许多长期数据科学家仍然相信手工构建模型和手工调整模型。许多其他人喜欢使用复杂的工具来提高他们模型的准确性,并最终实现更多的生产就绪模型。正如前面提到的 HBR 文章中所描述的,数据科学家的定义变化很大。一些公司依靠数据科学家设计测试来监控指标并做出决策,使用相对较少的统计原则。其他公司依靠数据科学家来设计新的统计模型,或完善现有的统计模型,以提高其产品或预测管道的性能。此外,今天有许多公司依赖数据科学家来执行许多与现代分析师相同的功能;编写 SQL 查询来操作数据,并以电子表格或数据可视化的形式将数据交付给企业。由于责任范围如此之广,市场上存在许多混乱,许多不同的定义被普遍接受。
**为什么 AutoML 越来越受欢迎?**
为了充分披露,我把自己归类为数据工程师,而不是数据科学家。我构建了数据管道来支持预测建模,但我对构建或调整模型不感兴趣。像 Azure AutoML 这样的 AutoML 产品允许没有训练模型和调整超参数的正式知识的个人产生强大的统计预测。现代数据分析师有史以来第一次获得了新的功能。分析师通常处于理解业务问题以及如何应用数据解决问题的最前沿。虽然在历史上,分析师只能是被动的,并显示过去的趋势,但现在分析师可以构建由 AutoML 工具摄取的特性,以产生对未来的洞察力。
分析师会成为下一个数据科学家吗?我的观点是,在未来的几年里,这两个头衔都将模糊不清。一旦分析师掌握了业务数据的用法,并学会了如何使用 AutoML 工具,数据科学家可能是分析师的一个合理的进步。然而,有了这种新的工具,简单易学的技能,如特征工程,可以在工作中教授,而不是需要冗长,往往过时,昂贵的学位。
**谁在设计下一代预测建模?**
对于绝大多数人来说,亚马逊和 Meta 等公司正在雇佣专业博士研究科学家团队来完善他们最有价值的预测模型。这些研究科学家在编程和统计方面非常专业,了解数学的新兴领域,能够应用这些复杂的概念来改进可用的工具。
科学家研究小组每天都有重大发现。GPT-3(Generative Pre-trained Transformer version 3)是一个经过数十亿样本训练的复杂自然语言模型,能够撰写整篇文章,进行类似人类的对话,并以惊人的准确度回答问题。计算机视觉模型,如 PyTorch 中发现的那些,能够进行物体检测、分割和分类,其水平可与人类媲美——除了[吉娃娃和松饼。](https://blog.cloudsight.ai/chihuahua-or-muffin-1bdf02ec1680)
**谁是未来的数据科学家?**
随着微软对 Azure AutoML 等行业领先产品的投资,我相信微软已经展示了将复杂的 AutoML 产品与领域知识专家相结合的价值,并抽象出了过去数据科学家所需的大部分编程和统计数据。
我相信领域知识将统治未来。以人类可理解的方式理解输入和输出之间的关系,并具备传达这种知识的技能,是预测建模最重要的输入。如果 MBA 项目开始要求 SQL 课程,或者教授特征工程,我不会感到惊讶。焦点已经从模型调整转移到模型输入,这是提高模型准确性的最大方法。为了产生更好的模型输入,应用模型的业务问题必须被专家理解。这些专家可能被称为数据科学家,但与早期的数据科学家共享很少的 DNA。我相信未来的数据科学家将把大部分时间花在设计实验、确认假设、贴近业务、编写 SQL 来构建功能以提高模型准确性上。
深度统计学家将能够专注于提高自动化机器学习架构的准确性,为这些未来数据科学家配备不断改进的工具,以产生更高的准确性。
# 你今天正在学习的数据技能不是你十年后需要的
> 原文:<https://towardsdatascience.com/the-data-skills-youre-working-on-today-are-not-the-ones-you-ll-need-a-decade-from-now-b7ea676ca33e>
## 随着新的工具和技术使技术数据任务变得琐碎,对数据“软”技能的需求将会激增。
这件事发生在大约两年前。
我的任务是构建一个管道,将营销数据从亚马逊营销服务 API 导入我们的数据库。我掰着手指头,打开文本编辑器,开始构建代码,使用 Python 构建数据集成。
我收到老板的消息:“你听说过[开桥](https://www.openbridge.com/)吗?”我在谷歌上快速搜索了一下。Open Bridge 是自动化 ETL 世界中的另一个产品。我以前用过像 Xplenty 和 Stitcher 这样的工具——所以我想我知道接下来会发生什么。
接下来的一周,我发现了开放式桥的简单性。用户体验的范围是输入凭证并点击提交。一天之内,我们每 24 小时就有一整套 AMS 报告自动放入我们的 Azure Blob 存储帐户。我所要做的就是建立一个管道,将各个 CSV 文件合并到相应的数据库表中,这样就完成了。
当我们为 Open Bridge 支付的第一笔款项到位时,我意识到未来十年数据就业市场将发生多大的变化。服务的账单?一个月 150 美元。
一项通常需要几天时间(多个 API 端点、十几份报告)的任务缩短到了 10 分钟左右。
## 随着简单程度的提高,薪酬会下降
显然,Open Bridge 不会涵盖任何组织的全部数据需求,但该工具的简单性及其可能性让任何头衔为“数据工程师”或“分析工程师”的人感到害怕。
是的,仍然会有数据库管理和优化,以及需要发生的复杂转换和聚合——但是做这些事情的工具集变得越来越普遍。
以 [HighTouch](https://hightouch.io/blog/reverse-etl/) 为例。HighTouch 将自己标榜为“反向 ETL”平台。抛开市场营销不谈,HighTouch 允许用户做的是将数据从数据库写回到 API。需要将 Salesforce 数据推入 Marketo?(常见用例)—无需编写集成—您可以使用简单的 SQL 通过 HighTouch 设置作业。您只需将 SQL 写入一个框中,然后 HighTouch 会将数据推送到您根据可用参数选择的平台中。
通常,从数据库到 Marketo 或 Salesforce 的集成至少需要一名有能力的数据工程师。数据工程师目前的平均工资约为 12 万英镑,根据技能水平的不同,时薪高达 200 美元。
然而,随着像 HighTouch 和 OpenBridge 这样的工具扩散到更广泛的领域,这些价格将会下降。如果您不再需要对服务器进行编码和管理,那么普通的数据/分析工程师就没什么可做的了。
数据科学家也不能幸免。
每个云平台(Azure、AWS、Google Cloud)都提供“自动 ML”解决方案,可以非常好地模仿普通数据科学家的能力。
我们还没有达到这一步,但是一旦你可以将一个数据集和一些参数输入到一个“自动 ML”解决方案中,并输出一个有效的、可概括的模型——普通数据科学家的价格将会大幅下降。
随着越来越多的工具进入市场,为最受欢迎的数据任务增加了额外的简单性,数据科学和分析就业市场的层级将会变平。如果你可以用一个入门级的数据分析师成功地构建和部署数据管道,你为什么要雇佣一个资深的数据工程师呢?
## 更好的技术=更多时间解决更大的问题
幸运的是,对于阅读这篇文章的人来说,所有这些都是好消息。
技术的进步意味着聪明能干的人可以把时间重新集中在比复杂的数据提取、转换和预测更重要的事情上。
与你可能认为的相反,今天分析和数据科学中最大的挑战本质上并不是技术性的。事实上,分析和数据科学职位的技术性质在许多方面都对该领域不利。
因为分析和 DS 可能是技术性很强的,通常那些在该领域提升到领导职位的人都是非常有成就的技术人员。他们通常设计和构建复杂的数据环境、报告、模型和架构,同时利用最新、最好的数据处理技术。
问题在于,有时这些高度专业化的技术人员并不擅长找出最佳方式来交付和使用他们擅长处理的数据。当你真的擅长某件事的某个方面时,你通常会加倍努力。你下意识地把它放在首位。
这种偏见导致了令人印象深刻的复杂数据环境的产生,这种环境可以以光速处理任何查询,每秒处理 1 亿行,但却让本应受益于这些数据的个人抓住了救命稻草。
在不止三个不同的场合,我与价值数十亿美元的公司签约,以避开 25-50 多个强大的分析团队,因为与他们合作是如此的麻烦。有问题的团队总是带着基本的要求来找我们——他们只是想要简单的业务报告来帮助做出一些关键的决策,就是这样。

照片由 Andrea Piacquadio 拍摄:[https://www . pexels . com/photo/man-with-hand-on-temple-looking-laptop-842554/](https://www.pexels.com/photo/man-with-hand-on-temple-looking-at-laptop-842554/)
## 适应或者死亡
那么数据专业人士到底应该如何适应呢?
虽然解决数据和分析的技术方面的工作数量将会下降,但围绕数据解释、利用、行动和组织公司和团队所需的专家数量将会大大增加。
需要考虑的一些建议:
* 成为一名**数据翻译** ( [一个我在](/the-data-driven-operating-model-2fa1b72c0f1d)之前写过的想法)。如果他们还没有,各地的公司都将迫切需要能够在技术分析、数据科学和工程团队与销售、客户服务、营销和财务团队之间架起桥梁的个人,他们是为了支持这些团队而创建的。如果你领导一个分析团队,考虑更加重视在你的分析师、工程师和他们支持的团队之间建立信任和更深的关系。做到这一点的一个方法是,实际上把一个人放在你的团队中,把他们支持的团队作为直接资源。这样,这些团队开始将分析视为不可或缺的合作伙伴,而不是出现问题时他们求助的“警钟”IT 资源。这样做将为创建更有效的数据产品铺平道路,因为技术分析师和数据工程师越来越熟悉日常业务挑战。
* 变得擅长软技能,如**写作**、**讲故事**和**听力**。在接下来的几十年里,技术的进步将会影响每个行业。虽然在当今专业人员密集的商业环境中,通常被认为是“软”的技能往往被忽略,但它们将变得比现在更加重要。您能向非技术合作伙伴传达技术分析项目的价值吗?你能编一个故事来讲述数据和技术如何影响一个业务单位/团队/部门吗?你能与营销人员、销售人员、客户服务代理和客户坐在一起,有效地收集反馈和想法吗?如果你今天唯一的工作就是写代码和参加会议——考虑强迫自己进入不舒服的机会来培养这些技能。
* 关注**成果而非架构**。在传统的软件工程中,好的产品经理将帮助指导开发团队取得符合客户需求和商业目标的成果。许多分析和数据团队没有相同类型的人员结构,这通常会导致分析和数据架构过度开发的情况。正如我上面提到的,我个人在多个场合帮助小团队绕开他们自己公司的分析团队。这通常是因为这些团队多年来建立了围墙花园,如果没有堆积如山的繁文缛节、会议和协调,几乎不可能完成简单的数据相关任务。这违背了分析的整个目的。关注结果有助于避免这个问题。把你的分析和数据项目当成普通人会消费的产品。复杂的体系结构可能是不可或缺的,但当它与自己的目的相冲突时就不是这样了——它的目的是向个人传递信息。
数据技术的快速发展意味着越来越多的公司将拥有超出他们所知的数据。许多人已经到了那一步——处理他们不知道如何使用的数亿行数据。当您展望您的数据职业生涯的未来时,请确保与您使用的平台和编写的代码一样重视数据的战略和智能使用,如果不是更多的话。随着对数据工程和数据科学家技能的需求下降,对知道如何有效使用数据的人的需求将会飙升。
准备好。
*感谢阅读。如果你喜欢这篇文章,我在* [*中*](https://camwarrenm.medium.com/) *写了各种关于分析的东西。你也可以在 Twitter*[*@ camwarrenm*](https://twitter.com/camwarrenm)*或者在*[*Linkedin*](https://www.linkedin.com/in/cameronwarren/)*上找到我。*
# 作为 Pandas 用户,您应该知道的数据帧类型转换
> 原文:<https://towardsdatascience.com/the-dataframe-type-conversions-you-should-know-as-a-pandas-user-4f8d3dd9d012>
## 从 Pandas DataFrame 生成列表、字典和 NumPy 数组的指南

克里斯·劳顿在 Unsplash[拍摄的照片](https://unsplash.com?utm_source=medium&utm_medium=referral)
熊猫数据框架在机器学习工程师和数据科学家中广泛流行,用于各种表格数据分析、管理和处理任务。

三列三行的表格数据(图片由作者提供)
虽然 Pandas 库对于许多用例是自给自足的,并且各种其他 Python 库为 Pandas 提供了内在支持,如 Matplotlib、Plotly、Sklearn 等。,在有些情况下,您可能需要将 Pandas 数据帧转换为 Python 中其他受支持的数据类型(或数据结构)。
即使不是这样,我坚信对这些转换的认识对熊猫数据帧的一般使用是有帮助的。
因此,在这篇文章中,我将展示 Python 社区中开发人员将 Pandas 数据帧转换为其他广泛使用的数据类型的不同方法。
文章的亮点提到如下:
[**理解熊猫 data frame**](#f98f)[**转换为 NumPy 数组**](#85de)[**转换为 Python 列表**](#e603)[**转换为字典**](#04fd)
[**结论**](#e36f)
我们开始吧🚀!
# 了解熊猫数据框架
在我们对 Pandas 数据帧进行各种类型转换之前,让我们先简要了解一下这个数据结构。
简单地说,Pandas 数据帧是驻留在 Python 环境中的表格数据结构。

三列三行的表格数据(图片由作者提供)
它可以熟练地执行各种表格数据操作,如过滤操作、I/O 操作、数据分组和聚合、表连接、列分布方法、滚动窗口分析等等。
当然,只有在现有 Python 环境/会话中加载了 Pandas 数据帧时,才能执行上述操作。
创建数据帧的最基本的技术之一是使用如下所示的`pd.DataFrame()`方法。
首先,我们导入所需的库。
接下来,我们使用`pd.DataFrame()`方法从列表列表`data`中创建一个数据帧`df`,如下所示:
我们可以使用 Python 中的`type()`方法来验证数据帧的类:
你可以在我之前的博客中读到创建熊猫数据框架的各种技术。
# 转换为 NumPy 数组
首先,让我们了解如何将 Pandas 数据对象转换成 NumPy 数组。
这里,我们将考虑以下数据帧:
## 方法 1:
您可以使用`[values](https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.values.html)`属性将熊猫数据帧转换为 NumPy 数组。
我们可以验证`result`对象的数据类型,它实际上是一个 NumPy 数组。
## 方法二:
Pandas 中的另一个可用功能是`[to_numpy()](https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.to_numpy.html)`方法。
> **注意:** Pandas 官方文档推荐使用`df.to_numpy()`而不是方法 1 中讨论的`values`属性。(来源:[此处](https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.values.html))
## 方法三:
最后,您还可以使用 NumPy 的基本方法— `[np.array()](https://numpy.org/doc/stable/reference/generated/numpy.array.html)`将 Pandas 数据帧转换为 NumPy 数组,如下所示:
如果您想了解创建 NumPy 数组的各种方法,可以在下面找到我的博客:
</here-are-30-ways-that-will-make-you-a-pro-at-creating-numpy-arrays-932b77d9a1eb>
# 转换为 Python 列表
接下来,我们将学习一些将熊猫数据帧转换成 Python 列表的方法。
不幸的是,Pandas 没有提供将 Pandas 数据帧转换成 Python 列表的直接方法。
因此,为了实现这一点,我们应该首先将 DataFrame 转换成一个 NumPy 数组,然后使用 NumPy 中的`[tolist()](https://numpy.org/doc/stable/reference/generated/numpy.ndarray.tolist.html)`方法转换成一个列表。
如上所述,该方法首先使用上一节中讨论的`values`属性将 DataFrame 转换为 NumPy 数组,之后,我们使用 NumPy 的`[tolist()](https://numpy.org/doc/stable/reference/generated/numpy.ndarray.tolist.html)`方法。
# 转换为词典
Pandas 数据框架的另一个流行的转换是从它生成一个 Python 字典。
简单回顾一下,我们在博客中使用了以下数据框架:
在 Pandas 中,我们可以使用`[to_dict()](https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.to_dict.html)`方法将数据帧转换成字典。下面,我们将讨论使用这种方法可以生成的各种格式的 Python 字典。
这些格式主要取决于方法返回的键值对的类型。字典的结构由`to_dict()`方法的`orient`参数决定。
## 方法 1:
使用`orient='dict'`(这也是参数的默认值),该方法返回一个嵌套字典,其中外部字典的键是列的名称,内部字典的键是索引值。
默认行为(`orient='dict'`)的示意图如下所示:

熊猫数据框架到 Python 字典(图片由作者提供)
下面的代码块演示了`to_dict()`方法的输出。
## 方法二:
与方法 1 中的嵌套字典不同,您可以从 DataFrame 中生成一个字典,用`key`作为列名,`value`作为表示为列表的列。
您可以通过将`orient=”list”`传递给`to_dict()`方法来实现这一点。
下图对此进行了描述:

熊猫数据框架到 Python 字典(图片由作者提供)
相应的实现如下所示:
## 方法三:
使用`to_dict()`方法生成字典的另一种有趣方式是指定参数`orient=”split”`。
返回的字典有三个键值对。这些是:
1. 'index': The value holds the index of the DataFrame as a Python list.
2. 'columns': This is also a list which specifies the name of the columns.
3. 'data': The value of this parameter is a list of list which represents the rows of the DataFrame. The value of this key is the same as what we discussed in 'Converting to Python List' section.

熊猫数据框架到 Python 字典(图片由作者提供)
该转换的输出如下所示:
此外,该方法还提供了另外四种表示方法来从数据帧中获取字典。
这些是`orient='**series’**`、`orient='**tight**’`、`orient='**records**’`和`orient=**'index**’`。你可以在官方文件[这里](https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.to_dict.html)读到它们。此外,StackOverflow 上的这个答案是了解它们的绝佳资源。
# 结论
总之,在这篇文章中,我演示了将熊猫数据帧转换成不同 Python 数据对象的各种方法。
更具体地说,我讨论了 Pandas 数据帧到 NumPy 数组、Python 列表和字典的转换。
请注意,各种其他数据类(或数据类型/框架等。)支持与 Pandas 的相互转换,比如 DataTable 数据帧、Dask 数据帧和 Spark 数据帧,我将在另一篇文章中演示。
**感谢阅读!**
[🧑💻**成为数据科学专家!获取包含 450 多个熊猫、NumPy 和 SQL 问题的免费数据科学掌握工具包。**](https://subscribepage.io/450q)
✉️ [**注册我的电子邮件列表**](https://medium.com/subscribe/@avi_chawla) 不要错过另一篇关于数据科学指南、技巧和提示、机器学习、SQL、Python 等的文章。Medium 会将我的下一篇文章直接发送到你的收件箱。
我喜欢写基本的数据科学概念、工具、技巧和诀窍。你可以在 LinkedIn 上和我联系。
# 中央 ML 的死被大大夸大了
> 原文:<https://towardsdatascience.com/the-death-of-central-ml-is-greatly-exaggerated-1f1626b3a8d4>

作者图片
## 意见
## 先不要对集中式机器学习(ML)团队认输;以下是如何得到它的权利
在过去的十年里,这个行业已经从庆祝“中央 ML 团队”的崛起转向质疑它是否应该存在。我不禁觉得自己在看着罗马燃烧。不一定要这样。
# 为什么抨击中央大联盟越来越流行
随着机器学习操作(MLOps)这一新兴领域继续快速增长,新工具和技术激增,即使在复杂的数据科学家和机器学习(ML)工程师中,混乱和不和谐的可能性也很高。
这一点得到充分展示的一个领域是:关于机器学习组织的理想团队结构的辩论正在升温。在会议和技术社区中,一个主题正在出现:集中化的人工智能团队——曾经在内部被誉为人工智能卓越中心——似乎正在失宠。例如,泰克顿最近发表的一篇关于“为什么集中式机器学习团队会失败”的[博客](https://www.tecton.ai/blog/why-centralized-machine-learning-teams-fail/)主张解散依赖 IT 来生产模型的传统集中式数据科学团队,而是“将数据科学家和数据工程师嵌入使用机器学习的产品团队。”
虽然将机器学习工程师和数据科学家嵌入他们所服务的业务对某些公司来说是值得的——事实上,这是 Meta 和其他公司如[美国柯尔百货公司](https://arize.com/blog/four-crisis-tested-lessons-for-leading-effective-ml-teams/)正在进行的大规模改造[的一部分——但它实际上只是潜在解决方案的一部分,并没有直接解决更大、更有趣的问题,即你是否、何时以及如何仍然可以串联使用中央 ML 团队。](https://ai.facebook.com/blog/building-with-ai-across-all-of-meta/)
这是一个需要回答的重要问题。如果行业不开始讨论如何以及是否以正确的方式集中 ML,它可能会错过解决最大的 ML 和数据问题的优雅解决方案。
为什么要听我说这个话题?我的职业生涯一直在建立和扩大 ML 团队,包括在 Opendoor 和 Twilio。我在有或没有集中式机器学习战略的公司担任数据科学家和 ML 工程师的经历也给了我一个独特的窗口,让我了解这个解决方案发展的痛点。今天,在我在 ML observability 公司 Arize AI 的工作中,我有幸与几十个领先的中央 ML 团队一起工作,并从他们的陷阱和成功中学习。这篇关于如何以正确的方式进行集中式机器学习的文章正是基于这一经历。
# 中心 ML 的工作定义
先做最重要的事情;“中枢 ML”到底是什么?虽然这个术语有些模糊,但通常“中央 ML”团队——也称为“ [ML 平台](https://arize.com/resource/best-practices-for-central-ml-teams-ml-observability/)或“ML 基础设施”团队——是一个平台工程团队,负责为公司的数据科学家设计、构建和管理一套工具。简而言之,它的目的是为 ML 应用程序开发提供一个统一的、标准化的体验。
像其他核心工程团队一样,中央 ML 团队诞生于痛苦——具体来说,是从零开始创建新工具和流程以构建和部署 ML 模型的痛苦过程。通过提供适用于各种用例的工具,central ML 解放了数据科学家,使他们能够快速有效地集成 ML 模型,同时遵守一些标准 MLOps 和软件工程最佳实践,确保模型的质量是可维护的。
# 典型的团队是如何构成的,中央 ML 的替代方案是什么?
中央 ML 团队不是一夜之间出现的;它们随着时间的推移不断进化以满足需求。为了说明为什么会出现这种需求,这里有三个典型的机器学习组织团队结构的组合。
# 结构一:传统方法

作者图片
在这种结构中,数据科学家团队充当内部咨询小组,构建新的 ML 用例并训练模型。然后,他们依靠现有的 IT 或工程团队来生产这些模型,并将其部署到现实世界中。
虽然这在一个有清晰的业务需求和 ML 用例的小组织中是可行的,但是它经常在大范围内受到损害。随着公司的发展,训练新模型的数据科学家和在生产中部署和维护新模型的工程师之间的差距变成了鸿沟,降低了模型速度,影响了模型性能(即训练-服务偏斜),并导致再训练方案的失败。类似地,最了解产品和客户需求的业务线和 ML 从业者之间的分歧可能意味着很多东西会在翻译中丢失。
# 结构二:分散的 ML

作者图片
在这种结构中,数据科学家和机器学习团队重新组合,并嵌入到各个业务线中,以便于协作。通过与产品经理和业务主管合作,ML 从业者最终能够更好地训练持续推动结果的模型。
然而,这种方法并非没有挑战。为什么?单个团队选择自己的技术可能会导致混乱。每一个新的数据科学模型项目都成为其自身的创业公司,从头开始创建一个新的 ML 公司需要一段时间,尤其是一个跨越从数据准备到模型构建、部署、服务、[监控](https://arize.com/model-monitoring/)和再培训的整个 ML 生命周期的公司。许多人缺乏这样做的技能——例如,一个技术娴熟的数据科学家团队可能拥有选择和培训最佳 ML 模型的专业知识,但缺乏集成这些模型的 MLOps 或软件工程背景——并且大多数人没有能力等待一年或更长时间来生产他们的第一个模型。
这种方法的另一个限制是,它有时会将各个业务部门变成孤岛,每个部门都有不同的工作方式、不同的技术部署和不同的成功标准。由于每个人都被分配到不同的业务部门,组织可能会错过宏观层面的洞察力和规模经济。
# 结构三:中央 ML

作者图片
有[不同的变化](/how-to-organise-your-machine-learning-teams-for-success-199f544afd20)中央 ML 组织的工作。一个这样的结构是集中 ML 混合体,它融合了分散 ML 的优点,同时还提供了一个专门的团队来构建、购买、集成和维护新工具(集中 ML)。许多公司从中央 ML 的平台工程师和嵌入业务线的数据科学家开始,随着时间的推移,向业务线添加更多的机器学习工程师。做得好,这是大多数成熟企业和成熟数据组织的理想团队结构。
当然,它也不是没有挑战(下面会有更多)。
# 中央 ML 的挑战
大规模交付有效的端到端 ML 解决方案非常困难。这里有一些即使是最好的中央 ML 团队也会出错的事情。
**工装锁**
* *问题:*
* *解决方案:*中央 ML 绝不应该是独裁。以支持整个组织的 ML 工作为目标,中央 ML 团队可以实现使工具需求与业务目标相一致的过程,并仔细评估权衡。随着新用例的出现,他们也可以灵活地适应。
**路线图上的战斗**
* *问题:*对于数据科学家来说,在一个专业知识、资源和时间有限的环境中,让他们的项目进入一个中央 ML 团队的路线图是一项挑战。在最坏的情况下,痴迷于技术的 ML 平台工程师可能会建立一个很少有人想要的最先进的功能商店,而不会优先考虑对业务来说可能更紧迫的问题。
* *解决方案:*混合组织结构,其中数据科学家和机器学习工程师嵌入到业务中,直接与中央 ML 团队合作,通过弥合差距和传播专业知识来帮助克服这一挑战。
**栅栏**
* *问题:*
* *解决方案:*最好的 ML 平台团队通过减少任何给定项目对他们的直接依赖来消除障碍,而不是通过面向自助的工具、解决方案和最佳实践来授权利益相关者。
# 中央情报局做得对
没有一个团队是完美的,但是有很多中央 ML 团队做到了这一点。它们有一些共同的特征:
* 他们有一个集中的组件以及客户团队中的独立工程师
* 他们先发制人——通过从业者,为从业者——来预测未来的需求
* 他们了解并寻找克服客户痛点的方法
虽然这些都是需要记住的重要事情,但最佳方法各不相同。
# 组织结构很重要
尤其是随着公司的成长,组织结构真的很重要。合适的 ML 团队会随着时间的推移和公司不同成长阶段的扩大而发展。Meta [例如,将关键的中央 ML 小组](https://www.wsj.com/articles/meta-shakes-up-ai-unit-amid-drive-for-growth-11654546470)转移到产品组织中,可能只是他们收获了构建所需一切的好处——数据科学家可以在低代码环境中部署他们的模型,有效地调整一些配置,并通过简单的工作建立和运行他们的模型。这是每个人的最终目标,但我们如何实现呢?

作者图片
## 创业公司
在这个阶段,团队必须保持斗志昂扬。通常,他们从一个或几个能够一次旋转很多盘的全栈数据科学家开始 ML 之旅。考虑“全栈数据科学家”的一种方式是作为一个数据、ML 和软件工程通才,他既能训练也能部署 ML 模型。这些修补者团队在为公司设计长期 ML 战略的同时,建立起零碎的最小可行产品(MVP)。
## 快速增长的公司和企业
当一家公司快速成长或一家企业第一次投资 ML 时,打好基础至关重要。在引入一大批数据科学家之前,有必要考虑建立一个中央 ML。最终,建立良好的 ML 基础设施,然后提高模型速度比反过来更容易。当数据科学家加入组织并融入每个业务线时,他们会发现自己可以访问干净和维护的数据以及易于使用的工具来执行研究、实验和部署他们的模型。不要犯太晚集中 ML 的错误!
## 成熟的 ML 公司
拥有成熟数据组织和坚实基础设施的大公司现在可以负担得起让员工专业化的奢侈。维持一个庞大的中央 ML 团队,同时在产品团队中嵌入 ML 工程师,与数据科学家一起工作,这创造了一个奇妙的协同效应。数据科学家和机器学习工程师可以专注于他们最擅长的事情——分别训练最先进的 ML 模型和生产它们——而软件工程师和机器学习平台工程师可以专注于构建和维护 ML 基础设施以支持这些工作。
# 人很重要
当然,组织结构本身并不代表一切。为了使中央管理团队取得成功,它需要一个有强有力的声音和远见的领导者,他将在整个公司范围内推动一致的管理团队战略。这位领导者应该:
* 对 ML 基础设施的未来有一个愿景
* 本质上理解请求背后的业务问题和潜在原因
* 对 ML 和 MLOps(不仅仅是软件工程)有深刻的理解
* 不是生活在泡沫中;相反,他们对技术前沿和增加业务价值都充满热情
* 衡量标准是它们是否加速了模型的速度,以及模型是否交付了商业价值
中央 ML 也需要一个独特的团队。ML 平台工程师需要深入了解机器学习的基础知识和/或围绕数据科学建模的核心概念。工程师应该了解他们的观众,知道他们的痛苦;没有这个基础,构建工具来解决这些问题是困难的。
# 你如何建造很重要
中央 ML 团队处理项目的组织文化和心态将影响团队的成功。伟大的中央 ML 团队通常都有一些关键的共同点:
* 他们专注于自动化和标准化。作为真正的工程师,他们希望优化和提高效率和质量。
* **他们不在筒仓里建造。**他们深入了解使用案例和他们正在处理的数据。他们不是在象牙塔中构建,而是与主题专家一起挖掘数据,并了解业务目标和需求。
# 中央大联盟万岁
让我们开始一个新的对话,而不是取消中央 ML 团队。我们如何让我们的中央 ML 团队成功?中央 ML 的客户讨厌它什么,我们怎么解决?
我很想听听你的经历;请在我们闲散社区的[伸出援手!](https://arize.com/community/)
# 助推和套索的深层联系
> 原文:<https://towardsdatascience.com/the-deep-connection-between-boosting-and-lasso-b40c00fc71c6>
## 通过彻底的视角转换理解强大的算法

(来自 [Unsplash](https://unsplash.com/photos/7hwF_T-1YPg) 的[汤姆·盖诺尔](https://unsplash.com/@its_tgain)摄影)
梯度推进既被普遍使用,又被普遍低估。
当讨论其有效性时,人们通常默认两种观点:
1. 梯度提升从低方差和高偏差开始,并通过添加更多弱学习者来减少偏差
2. 梯度推进近似于函数空间中的“梯度下降”,并试图最小化该空间中的损失
这两种观点都很有趣,非常有价值!然而,它们并没有讲述整个故事;**特别是,他们努力解释*为什么*梯度推进如此有效。**
通过将增强(特别是具有固定小权重的梯度增强)重新表述为近似套索(L1 正则化)问题,我们可以对增强的作用有另一种理解,并将其与内核化方法等其他基本技术进行比较。我们为什么关心?找到不同技术的机制之间的共性可以帮助我们提出全新的算法!
让我们通过扩展 Rosset 等人在[这篇论文](https://www.jmlr.org/papers/volume5/rosset04a/rosset04a.pdf)中讨论的一些观点来进行这种重新表述。以一种读者友好的方式。(注意:我将使用*树*作为原子模型的选择,但是许多相同的想法适用于各种基础学习者。)
# 概述:功能梯度下降
升压的一个常见类比是函数空间中的梯度下降。代替迭代更新 n 维参数向量,我们现在迭代更新参数*函数*(其属于潜在的无限维函数空间。)
让我们快速回顾一下这个类比。现在,我们有一个以参数函数作为自变量的成本函数,而不是参数向量上的成本函数(函数上的函数称为“泛函”):

图 1:提升问题的成本函数(图片由作者提供)
这里,花哨的“L”是我们传统的建模损失函数,它将真实标签和我们的模型(其中我们的模型由函数“f”表示)分离的输出作为参数。
就像计算参数向量的梯度一样,也可以计算参数*函数*的梯度。结果也是一个函数(正如参数向量的梯度也是一个向量),我们可以从参数函数中减去它来执行“下降”步骤。
我将省去实际梯度的求导;更多详情,请参见亚历克斯·格拉布和萨曼莎·霍瓦特的精彩课堂笔记。只需知道,得到的梯度是一个“尖峰”函数,当在训练点 x{i}上评估时,它吐出当前预测的“残差”(如果损失函数“L”是平方损失,则为真残差,否则为伪残差),当在其他地方评估时,吐出零。以下是梯度函数和结果更新的可视化效果:

图 2:使用来自图 1 的成本函数的梯度进行更新(图片由作者提供)
将这个原始梯度添加到我们的当前函数将导致严重的过度拟合,本质上使结果成为一个存储我们训练数据上的目标的查找表。为了解决这种缺乏一般化的问题,我们可以通过在约束函数类(例如决策树)中找到一个与梯度“接近”的函数来“平滑”这种梯度,同时产生更一般化的结果。我们修改后的更新变成了我们熟悉的梯度增强更新:从我们的函数类中找到一个“接近”真实梯度的函数,并以较小的权重将其添加到我们当前的模型中。
优雅的东西。然而,一个关键问题仍然存在:
**如果弱学习者在拟合梯度方面做得很差(根据定义),为什么推进会如此有效?**
在我看来,这就是高级功能梯度下降类比的失败之处(更详细的版本可能会更好。)这里有*和*其他解释提升能力的方法,但是 LASSO 公式既易于理解,又非常有助于将提升与其他方法如支持向量机进行比较。
为了理解这个公式,它有助于完全转移我们对增压问题的观点。让我们透过向量代数的镜头来看问题吧!
# 提升树的向量空间
当人们想到向量时,他们通常会想到欧几里得空间中的尖箭头。
实际上,“向量”和“向量空间”的概念要抽象得多。
一个空间成为向量空间的唯一要求是,增加和缩放向量会在该空间内产生另一个向量(您还需要存在一个“零”向量,当添加到另一个向量时,它什么也不做。)
这意味着许多,*许多*集合都是向量空间。所有多项式的集合是一个向量空间(使用规则验证这一点!)所有 2x2 矩阵的集合是一个向量空间。
**重要的是,所有提升的树的集合是一个向量空间。**
如果我们将“提升树”定义为具有固定深度 D(其中 D 由我们选择)的决策树的有限加权和(即线性组合),那么很明显,任何提升树的线性组合都是*自身*提升树。
正如您可以通过一组有限的向量(轴向量)的线性组合来重新创建所有欧几里得空间一样,您也可以通过单棵树的线性组合来重新创建所有增强的树空间!如果我们只允许在观察到的数据点上或数据点之间进行树分裂,那么任何深度为 D 的单独的树都可以写成深度为 D 的有限多个“构建块”树的线性组合。
让我们来研究一种方法。请注意,如果我们只允许在观察到的数据点上或数据点之间进行分割,那么我们只能生成有限多个分区(即分割的组合)。然后,我们可以将一个给定分区的叶值的任意组合写成该分区上简单的“独热”树的线性组合。以下是使用两个特征维度 X1 和 X2 的深度为 2 的树的分解示例:

图 3:分解为线性组合的深度为 2 的树(图片由作者提供)
如果我们可以将任何深度为 D 的树写成“积木”树的线性组合,那么我们可以*也可以*将任何深度为 D 的提升树表示成线性组合,如下所示:

图 4:作为个体树的线性组合的增强树(由作者提供的图像)
左边的公式看着眼熟吗?如果这看起来像线性回归,那么你就有所发现了!理论上,我们可以将寻找一个好的加性树集合的问题简化为对一组生成所有可能的提升树的空间的树的**线性回归。但是,如果我们天真地试图建立一个回归模型,我们会遇到两个主要问题:**
1. 我们需要评估和使用大量的树作为特征。对于很多常见的数据集,在已知的宇宙中,唯一的树比夸克还多。
2. *甚至*如果我们可以修复#1,我们将拥有比数据点多很多倍的特征,并且将需要约束我们的优化问题或者添加复杂度惩罚以达到有用的优化。
关于第二点,“拥有比数据点多很多倍的特征”正是 LASSO 能够解决的问题!
# 增强近似于套索调谐
让我们考虑一下,使用有限的“积木”函数,LASSO 回归是什么样子的。(注意,LASSO 通常使用平方损失来定义,但我将把定义推广到使用任何凸损失 c。)
首先,我们评估所有数据点上的每个函数,以在我们的特征矩阵 x 中创建列。现在我们有了我们的特征,我们解决以下 LASSO 回归优化问题:

图 5:特征函数 F1,F2,…,FM 的套索回归问题(图片由作者提供)
这个定义(用 L1 惩罚使损失最小化)可能为许多人所熟悉。不太熟悉但仍被普遍使用的是下面的套索的 **L1 约束公式:**

图 6:图 5 中问题的等价重写(作者的图片)
对于图 5 中的每个λ值,在图 6 中存在唯一的 T 值,其恢复相同的解,反之亦然(其中增加的 T 映射到减小的λ,直到λ = 0,此时任何更大的 T 值恢复相同的解:非正则解。)
让我们快速展示为什么每个λ映射到一个唯一的 T(另一个方向稍微复杂一点,使用拉格朗日对偶的论点可以在网上找到。)我将把这个证明自包含在下面的编号列表中,这样就可以很容易地跳过它:
1. 给定λ值,图 5 中优化问题的解对应于向量β,该向量β具有比对应于非正则化解(λ = 0)的范数小的某个有限 L1 范数 N。
2. 现在,考虑图 6 中 T = N 的约束优化问题。图 6 中 T = N 的解不能具有小于 N 的 L1 范数,因为这将是约束集内的局部最优解(与我们的凸目标只有一个局部最优解的事实相矛盾)。)因此,图 6 中 T = N 的解具有正好为 N 的 L1 范数
3. 由于图 6 中 T = N 的解决方案在所有 L1 范数等于 N 的解决方案中最小化了图 6 的目标,所以它也必须在所有 L1 范数为 N 的解决方案中最小化图 5 中给定λ的目标
4. 因此,T = N 的图 6 的解等于给定λ的图 5 的解,因为后一个解也具有 N 的 L1 范数
5. 图 6 中 T < N or T > N 的任何值都不能恢复相同的解,因为有一个不是 N 的范数(参见#2 中的论证)。)因此,映射λ → T = N 是唯一的。
换句话说,解决图 6 中的 L1 约束优化问题,对于 T 的许多连续较大的值,解决了λ的许多连续较小的值(范围从λ = ∞到λ = 0)的套索优化问题。)
这对我们有什么帮助?事实证明,提升——更具体地说,*贪婪ε*提升(即,在我们的回归特征集合中执行最佳ε大小的系数更新)——对于 t 的连续较大值,非常接近 L1 约束优化问题的“解序列”
因此,基于 T 和λ之间的对偶性,这意味着 boosting 解决了具有大范围λ值的多个套索问题,当我们找到导致良好验证性能的正则化水平时终止(这是实践中的“早期停止”)。换言之,提升在我们的非常高维的特征空间中有效地近似套索超参数调谐。
为了理解为什么提升等价于一系列 L1 约束回归问题,考虑下面的增量优化问题:

图 7: β_last 是 T (T_last)的某个值的图 6 的解(图片由作者提供)
这里,β_last 是图 6 中的 L1 约束问题的解,具有 T (T_last)的某个值。现在,我们想找到一个稍微宽松的 L1 约束的最优解,也就是说,T 的值稍微大一点——这就是问题的“增量”本质。
假设图 7 中问题的解是“单调”更新,即解的每个坐标的绝对值大于或等于β_last 的绝对值(换句话说,“单调性”意味着更新在每个坐标上增加了离原点的距离。)最佳更新实际上*是*单调更新在实践中是常见的,特别是对于小的ε值。(我们将在本节的后面回到*为什么*我们需要单调性。)
在接下来的几段中,我将使用图 7 中的优化约束来帮助我们理解这个“单调最佳更新”*实际上看起来像什么*。
现在—如果图 7 中的最佳更新是单调的,那么当您在图 7 中的现有约束之上添加新的单调性约束时,它仍然是最佳解决方案,因此我们可以在不改变最终解决方案的情况下添加该单调性约束。这两个组合约束等价于下面的约束集(“等价”在创建相同的可行β集的意义上):

图 8:β上新的等价约束集(作者图片)
(您可以通过使用单调性的定义以及涉及算术和绝对值的不等式来展示这种等价性。这次我省略了证明,但是请随意检查我的证据!)
如果我们在图 8 中的约束对下恢复我们的单调最佳更新,那么如果我们丢弃第二个约束并且在第一行中仅使用 L1 邻域约束,我们也将恢复它。(注意,在该奇异 L1 邻域约束下可行的所有β在图 7 中的原始约束下也是可行的,因此我们永远不会“超越”原始约束。)
我们剩下的是一个约束,约束我们的更新在 L1 距离上接近前面的参数β_last。**换句话说,如果图 7 中原始问题的最优解是单调更新,那么我们也可以通过以β_last 为中心的局部优化问题来恢复它。**
我们快到了!让我们使用上面的新约束重写图 7 中的优化问题。此外,如果我们在β_last 周围的局部邻域足够“小”并且我们的成本函数 C 是平滑的,那么我们可以通过使用其梯度用线性近似来替换目标函数(我们在图 7 的花括号内最小化的“成本之和”函数)。对约束和目标函数进行这些替换产生了这个最终的优化问题,只要图 7 中的最佳更新是单调的,就恢复与图 7 相同的最佳更新:

图 9:“Obj”是图 7 中花括号内的“成本总和”目标函数(图片由作者提供)
由于目标是线性的,那么很容易看出这个约束优化问题的解决方案是仅改变目标在β_last 的梯度具有最大绝对值的β的坐标,如果符号是负的则加上ε,如果符号是正的则减去ε(注意,根据定义这将是单调更新,因为我们假设*最佳*更新本身是单调的。)
这听起来熟悉吗?在每一步,我们只更新β的最“有影响”的坐标;**这相当于在最“有影响力”的特征函数(其系数就是β** 的所说坐标)上迈出了一小步。)
概括一下:图 7 中的优化问题是图 6 中优化问题的增量版本。如果我们针对某个 T 值求解图 6,并且针对稍大的 T 值的解是单调更新,那么我们通过贪婪的ε提升来恢复它。只要每个增量问题通过单调更新得到解决,那么**我们在一系列推进迭代下追踪出整个套索解序列。**在这种情况下,boosting 的每次迭代都解决了λ值稍小的套索问题。
我们提到了单调性很重要。这是因为如果违反了单调性,那么在我们的推进解序列和套索解序列之间就不再有完美的 1:1 对应关系。这是因为违反单调性意味着我们有效地“重新访问”并更新具有较小 L1 范数的解,而不是在该迭代上求解具有递增的较大 L1 范数(对应于递增的较小λ)的解。然而,在这种情况下,增强通常非常接近套索序列*甚至*。检查来自 Efron 等人的论文中的[下图。a1 在糖尿病数据集上比较 LASSO 系数序列和 boosting 序列:](https://projecteuclid.org/journals/annals-of-statistics/volume-32/issue-2/Least-angle-regression/10.1214/009053604000000067.full)

图 10:在糖尿病数据集上,套索系数对增强(阶段式)系数。(图片由 Efron 等人提供。阿尔(2004 年))
在该图中,LASSO 和 boosting(阶段式拟合)仅在原始特征上完成,而不是在功能特征上,但是紧密的对应关系仍然很能说明问题。当变量 7(灰色线)违反单调性时,变量 8 之后会出现差异(见黑色箭头和红色线),但这种差异很小,随着迭代次数的增加,似乎几乎可以解决。这里需要注意的是,这种“对违反单调性的鲁棒性”还没有在非常高的维度上测试过;然而,将助推与套索联系起来的基本原则依然存在。
# 放在一起:树推进
我们讨论了如何发现最佳加性系综的问题通常可以写成在一组“构件”函数(对应于回归中的特征)上的线性回归问题。)参见图 3 中使用决策树的例子。
在本节中,我们将快速讨论使用我们的“构建块”树的 epsilon greedy boosting 更新是什么样子,以及它与经典树提升的比较。
回想一下,我们通过使用目标函数相对于每个系数的梯度来确定更新哪个“构建块”系数(参见围绕图 9 的讨论)。)我们可以通过链式法则重写目标函数相对于β的每个坐标的梯度,如下所示:

图 11:用链式法则求目标函数 w.r.t. β_i 的梯度(图片由作者提供)
回想一下,F_hat 是通过在所有数据点上评估我们的加性系综(在任何非线性变换之前)而生成的输出向量。)图 11 右侧的一阶偏导数是当我们进行传统的梯度增强时,我们在每次迭代中“拟合”的残差/伪残差。二阶偏导数是引入对系数向量β的依赖性的元素。这是这个偏导数的完全展开:

图 12:相对于单个坐标扩展梯度(作者图片)
该图的推导源于这样一个事实,即原始向量 F_hat 只是在每个点上评估的函数的线性组合,因此关于单个系数的导数隔离了由该系数加权的分量函数。
现在,如果我们的“构造块”函数是如图 3 所示的“独热树”,那么对于落入对应的独热树 F_i 的“活动叶”的所有 x,图 12 中的向量元素等于 1,否则为零。然后,图 11 中的产品可以重写如下:

图 13:使用“独热树”重写图 11(作者图片)
换句话说,**找到梯度最大(绝对)的β的坐标,等价于找到残差/伪残差之和最大(绝对)的划分叶!**
注意,传统的树增强并不像*那样工作。不是一次更新一片叶子(通过一个热树),我们会找到一个最佳的*分区*并更新对应于该分区的所有*叶子。此外,在传统的树提升中,我们也不局限于 epsilon 大小的更新;相反,我们进行与*梯度*的大小成比例的更新,由ε加权以确保任何单独的更新不会太大。
但是,尽管两种范式之间存在差异,但“最优更新”背后的驱动力非常相似。如果我们将由传统树提升生成的集成映射回我们的独热树坐标系中的权重,那么我假设由具有相似系数 L1 范数的独热树提升生成的集成表现大致相似。对这两者进行比较的模拟将是这一讨论的一个非常有趣的后续。
# 与内核化方法的比较
boosting 和 kernelized 方法都声称能够适应任何情况。在传统的 ML 世界中,两者都是“黑箱”。那么一个比另一个有什么优势呢?
回想一下,一个内核化的方法是任何使用“内核技巧”来适应模型的方法。我不会在这里讨论这个概念背后的数学;只需知道,通过使用“内核技巧”,我们可以以很少的额外成本利用许多高度非线性的特性(通常在传统的线性模型中)。
对于内核化方法,我们通常在新的“内核”特征空间中拟合线性模型。下面是一个内核化线性回归的示例,优化目标扩展到包括隐式内核特性:

图 14:用隐式核特征扩展的核化线性回归目标(作者提供的图像)
请注意,这个问题看起来与图 5 中的升压问题非常相似!
很快,我们可以看到内核化方法的一个主要缺点:**我们对ɸ的隐式内核特性没有多少选择**。
然而,在 boosting 中,我们可以自由选择我们喜欢的任何函数集,只要我们可以在任何迭代中有效地评估“最佳方向”。对于树提升,找到这个“最佳方向”就像在每一步拟合一个与残差/伪残差“相关”的树一样容易。
内核化方法的另一个缺点是**我们被锁定在某些先验中,也就是说,某些特征会自动受到比其他特征更重的惩罚**。
大多数内核化方法采用某种形式的正则化来处理过拟合和过参数化(图 14 是内核化脊回归的例子,即 L2 正则化。)并且众所周知,在采用 L1/L2 正则化和相关方法之前,您需要缩放您的特征;否则,“较小”的特征将比“较大”的特征受到更严重的惩罚。
然而,内核化的方法使得*不可能*让你可靠地保持最终的“内核特性”不变!
考虑多项式核。多项式核中的某些项具有相对较大的范围-想想(1 + xy)以及乘积项“xy”如何具有系数 2,这使得最终 1 次要素的系数为√2,而最终 2 次要素的系数较小,为 1。结果,当加入正则化时,我们被锁定在不成比例地惩罚某些项,这对于所谓的“通用”算法可能是不期望的。
不言而喻,boosting 不会遇到这个问题,因为我们可以完全控制我们的功能。
最后,**广泛使用的内核化方法需要花费更多的时间来进行(正则化)超参数调整。**这个不可否认地不是这些方法的*固有的*问题,因为迭代解经常存在,在单个模型拟合中自动追踪每个超参数值的解。然而,在*练习*中,练习者通常会做的是,每次使用不同的超参数值对内核化模型进行多次改装。
另一方面,我们已经探索了 boosting 和 LASSO 之间的联系,以及 greedy epsilon boosting 如何像 LASSO 的高效版本一样,在一次拟合中求解多个 T/λ值,从而在多次 boosting 迭代中有效地描绘出整个“解的轨迹”。换句话说,通常实践的**增强为我们提供了一种在*单一*拟合中的超参数调整形式。**好看!
# 结论
Boosting 是一种极其强大的技术,但它远不像人们想象的那样是一个“黑箱”。虽然最终的结果可能无法解释,但驱动其部分力量的高层次思想甚至对于那些只上过线性模型课程的人来说也是可以理解的。
与神经网络形成对比,神经网络的基础理论仍在发展中,在数学上更加复杂。
总而言之,我希望这次深入探索能让你对你信赖的表格工具多一点点欣赏。优雅和力量的结合,没有什么比渐变更好的了!
# 参考
[1] S. Rosset,J. Zhu,和 T. Hastie, [Boosting 作为一个正则化的最大间隔分类器路径](https://www.jmlr.org/papers/volume5/rosset04a/rosset04a.pdf) (2004),机器学习研究杂志 5 941–973
[2] A. Grubb 和 s .霍瓦特,[增强:函数空间中的梯度下降](https://www.cs.cmu.edu/~16831-f14/notes/F11/16831_lecture15_shorvath.pdf) (2012),机器人学中的统计技术(16–831,F10),第 15 讲(卡耐基梅隆大学)
[3] B. Efron,T. Hastie,I. Johnstone 和 R. Tibshirani,[最小角度回归](https://projecteuclid.org/journals/annals-of-statistics/volume-32/issue-2/Least-angle-regression/10.1214/009053604000000067.full) (2004),《统计年鉴》32(2):407–499
# Python 在学校选择中使用的延迟接受(DA)算法
> 原文:<https://towardsdatascience.com/the-deferred-acceptance-da-algorithm-utilised-in-school-choice-with-python-afc0fe892921>
## 我们如何让学生和学校稳定匹配?

安诺尔·查菲克在 [Unsplash](https://unsplash.com?utm_source=medium&utm_medium=referral) 上拍摄的照片
匹配研究调查人、机构和商品之间的稳定匹配。从 Gale 和 Shapley (1962)的延迟接受(DA)算法开始,这项研究已经成功地应用于现实世界,尤其是 21 世纪初以来的学校选择。在这篇博文中,我将简要解释匹配/学校选择理论的背景及其理论发展,并展示算法的 python 实现。
Python 的实现可以在[这个回购](https://github.com/kyosek/deferred_acceptance_school_choice)中找到。
# 目录
1. 介绍
2. 延期录取算法与学校选择
3. Python 实现
4. 结论和未来工作
# **1。简介**
传统上,人们会被自动分配到美国最近的学校。然而,在 1980 年代,政府开始了学校选择制度,以便让学生更灵活地选择他们喜欢的学校。从此,人们开始思考如何策略性地获得自己的首选学校。事实证明,博弈论的方法是有帮助的。作为一个现实世界的例子,纽约市高中录取在 2003 年使用了 d a 算法的一个变种。这篇博文研究了延期录取算法的特性及其在学校选择机制中的应用。还演示了算法的 python 实现。
# **2。延期录取(DA)算法与学校选择**
本节简要介绍几个属性,并举例说明该算法如何工作。所有的证明和详细的解释都可以在文献中找到,这里只演示了最基本的部分。
**2.1 框架/属性**
进一步讨论这个话题,有几个重要的性质,即**稳定性**、**效率、防策略**。本节解释这些概念。
**稳定性**
DA 算法是找到代理和主体的稳定匹配的算法。但是这里的“稳定匹配”是什么意思呢?
为了有一个**稳定匹配**,我们必须满足以下条件(盖尔和沙普利,1962):
(I)代理人是个体理性的
(ii)如果代理人与委托人匹配,这种匹配不能被任何联盟阻止。
**效率**
由 DA 算法产生的每个匹配**弱 Pareto 支配由任何其他机制产生的匹配**(Gale 和 Shapley,1962)。如果没有其他匹配,其中至少有一个学生过得更好,没有学生过得更差,那么这个匹配就是(帕累托)有效的。在这种情况下,由于没有代理人有动机偏离这个分配到其他分配,或者没有代理人可以通过误报而变得更好,这就是**纳什均衡**。
**防战略**
这种算法使得**真实的偏好披露成为每个代理人的主导策略**,杜宾斯和弗里德曼(1981)证明了这一点;罗斯(1982) **。**
DA 算法满足稳定性和防策略性,但不满足效率。事实上,任何机制都不可能既高效又稳定(Roth 1982)。
**2.2 算法**
那么 DA 算法是如何工作的呢?该算法处理以下迭代:
**迭代 1:** 每个代理根据她的偏好等级选择委托人。每个得到报价的委托人拒绝最不喜欢的代理人,否则,把他放在“保留名单”上。
**迭代 2:** 在前一轮被拒绝的代理提供了他的第二个选择,委托人再次拒绝了最不喜欢的代理。
**迭代 k:** 在第 k 轮被拒绝的代理提供他的第 k 个选择,委托人拒绝最不优选的代理。
重复上述阶段,直到每个代理都在委托人的“保持列表”上。一旦最后一个委托人与最后一个代理人匹配,每个委托人都需要接受他们自己的“保留列表”中的提议。
**这证明了 DA 算法总能找到稳定的匹配(Gale 和 Shapley,1962)。**
2.3 学校选择
在择校的设置上,DA 算法需要一点点修改。在原来的 DA 算法设定中,一对一匹配是假设之一,但在学校选择中,这需要放宽到一对多匹配。所以学校有一定的学生配额,只要学生人数少于配额,学校就可以录取学生。下面是一个例子。
**示例**

表 1:学生/学校偏好表
假设存在 N = 4 名学生和 3 所学校,X,y,z ∈ X,如表 1 所示。学校 x 和 z 有 1 个名额,y 有 2 个名额。下表 1 显示了每个学校/学生的偏好排名。为了找到稳定的匹配,实现 d a 算法。一、学生申请学校,他们最偏爱。在第一轮中,1 和 2 都最喜欢 z,z 更喜欢 1 而不是 2,因此 z 拒绝了 2。3 个申请 x,4 个申请 y,放在各个学校的“保留名单”里。在第二轮中,2 应用她的第二选择 x。在 x 的“保留列表”中,有来自第一阶段的 3,但是 x 更喜欢 2 而不是 3,因此它拒绝了 3,并将 2 保留在其“保留列表”中。然后重复这些程序,直到每个人都被大学录取,最终可以找到稳定的配对。这些迭代显示在下面的动画中。
DA 算法迭代
然而,在现实世界中,学校通常不会对一群学生有严格的偏好。通常,他们的偏好包括 4 个优先组:(I)同胞和步行区,(ii)同胞,(iii)步行区和(iv)其他。为了解决这个问题并仍然应用 DA 算法,我们需要打破那些无关紧要的偏好,并使它们的偏好变得严格。为了打破平局,可以使用“随机抽签”。在同一个优先组的学生中,使用随机抽签人为地创建组中的排名,并在其他组中重复这一过程,以严格优先于所有学生。然而,不幸的是,使用这种方法会导致效率损失。

[奥斯曼·拉纳](https://unsplash.com/@osmanrana?utm_source=medium&utm_medium=referral)在 [Unsplash](https://unsplash.com?utm_source=medium&utm_medium=referral) 上的照片
# **3。Python 实现**
本节展示了算法的 python 实现。我已经创建了[回购](https://github.com/kyosek/deferred_acceptance_school_choice)。
**主 DA 算法功能**
这里展示了该算法的 python 实现的一部分。首先,下面是它的主要部分。在这个函数中,deferred_acceptance 接受 student_df、schools_df、schools_quota 和 verbose 输入。这些 student_df 和 schools_df 包含学生和学校对学校和学生的偏好。这些数据帧的细节将在下面进一步解释。schools_quota 表示每个学校的学生配额。如果 verbose 不为 0,它将打印迭代次数。
该函数将执行以下操作:
1. 创建匹配的初始环境
2. 遍历学生,开始将他们放在学校的“保留列表”中
3. 确保学校的学生人数少于学校的配额
**效用函数**
这里显示了几个实用函数。首先,一个叫做*严格 _ 偏好 _ 检查*。这个名字是不言自明的,但将确保学生对学校有严格的偏好,因为它对算法正常工作很重要。
第二个叫做 *create_dataframes。*它有助于从学生和学校偏好的列表和字典中创建一个 pandas 数据框架,以便在主要 DA 算法函数中使用。
第三个是随机打破一个学校的平局偏好的函数。正如上文提到的,现实世界中的学校通常对学生群体有不同的偏好。然而,为了让算法起作用,我们需要通过使用随机“抽签”来严格限定他们的偏好。
**例子**
这里有一个例子,说明了带有随机平局决胜的整个 DA 算法是如何工作的。这个例子创建了一个任意的集合,其中 4 个学生的偏好高于学校,3 个学校的偏好不严格高于学生。学校的配额是学校 a,学校 b,学校 c = 1,2,1。
示例:带随机平局决胜的 DA 算法
这个函数的输出是:
{('a ',' A'): (1,0),(' C ',' C'): (1,0),(' d ',' B'): (1,1),(' B ',' B'): (3,2)}。
所以学校" A "收了学生" A ",学校" B "收了学生" B "和" d ",学校" C "收了学生" C ",这看起来像是我们所期望的。
# 4.结论和未来工作
本文简要介绍了 DA 算法的概念及其在择校中的应用,以及它的 Python 实现。这里介绍的算法是基本算法,也有一些算法的变体,例如,Erdil 和 Ergin (2008)提出的稳定改进周期(sic)。这种算法交换分配后的学生随机平局打破。尽管它不再是策略证明的,但该算法显著提高了其效率(Abdulkadiroglu 等人,2009)。因此,作为未来的工作,这将是一个伟大的下一步实现这一点。
# 参考
Abdulkadiroglu,a .和 Sonmez,T. (2003 年)。一种机制设计方法。美国经济评论,93(3):729–747。
Abdulkadiroglu,a .和 Pathak,P. A .和 Roth,A. E,《策略的严密性与匹配差异的效率:重新设计纽约市高中比赛》。美国经济评论,99(5):1954-1978。
杜宾斯,L. E .和弗里德曼,D. A. (1981 年)。马基雅维利和盖尔-沙普利算法。美国数学月刊,88(7):485–494。
盖尔和沙普利(1962)。大学录取和婚姻的稳定性。美国数学月刊,69(1):9–15。
罗斯(1982 年)。匹配经济学:稳定性和激励。运筹学数学,7(4):617–628。
# 主成分分析权威指南
> 原文:<https://towardsdatascience.com/the-definitive-guide-to-principal-components-analysis-84cd73640302>
## 这是一个教程,它剥离了底层代码,您可以在浏览器中编辑和运行这些代码,以便一劳永逸地理解 PCA 的细节。还可以找到一个完全成熟的 web 应用程序供您使用。
尽管有数百个网页致力于主成分分析(PCA),但我没有找到一个完整和详细的关于它实际上是如何计算的。有些教程擅长解释如何获得协方差矩阵,有些则擅长描述所涉及的奇异值分解,还有一些只是简单地介绍现成的程序或代码片段,但是你不知道为什么和如何。另一方面,一些资源非常深入,但是使用的技术术语最终会让你更加困惑。还有一些人专注于主成分分析的输入和输出,但完全忽略了黑盒内部发生的事情。
这就是为什么我写了这个新教程,它剥离了我最近构建的在线运行 PCA 的 web 应用程序的底层代码:
</a-free-online-tool-for-principal-components-analysis-with-full-graphical-output-c9b3725b4f98>
我所说的“低级”是指除了一个取自库的函数之外,其余的代码都是简单的操作和循环。
由于这是从 web 应用程序中获取的,所以涉及的代码是 JavaScript。但是它非常简单,正如您将看到的,因此您应该能够轻松地将其翻译成其他编程语言。JavaScript 的好的一面是,你可以很容易地编辑它,并在你的浏览器中测试它,自己探索 PCA 是如何工作的,并且一劳永逸地理解它的细节。
# 简单地说,主成分分析
PCA 是一种用于减少数据集中的维数,同时保留其中最重要的信息的技术。主成分分析通过将高维数据线性投影到其变异的主要成分(称为主成分(PC))上来实现这一点。
PCA 可用于识别数据集的底层结构或降低其维数。在实践中,您使用 PCA 来简化复杂数据的显示,方法是仅在 1、2 或 3 维(最常见的是在 2 维,以二维图的形式)上展开数据;找出哪些原始变量对数据集中的可变性贡献最大;还可以通过从其主 PC 重建数据集并忽略包含更多噪声的那些来去除噪声或压缩数据(例如图像);以及可能的一些其他相关应用。你可以在我介绍 web 应用的[文章中看到一些具体的例子。](/a-free-online-tool-for-principal-components-analysis-with-full-graphical-output-c9b3725b4f98)
# 保持简单但完整的数学
有些资源是完整的,但是太复杂了,难以理解,而有些资源很简单,但是那是因为它们没有展示出全貌。例如,一些教程更多地关注于计算协方差矩阵,但是对于如何从该矩阵到 PCA 的实际结果,你却被抛在了一边。其他教程更深入地研究了这个方面,但在这个过程中,他们认为协方差矩阵是理所当然的,并且经常使用不必要的复杂术语。
这里我将从起始数据集开始,它是一列由*变量*描述的*no objects*对象。例如,每个对象可以是在宽波长范围内为一个样本收集的光谱;每个波长的读数将是一个变量。哦,是的,在文本中,我会像在代码中一样调用所有变量,用斜体。
## 步骤 1:从起始数据集到协方差矩阵
现在输入已经很清楚了,是时候写代码了。起始数据集在下面的代码中,该代码包含在名为 *X* 的变量中,该变量有*个变量*行和*个对象*列。
在最常见的形式中,正如我们将在这里运行的,PCA 是协方差矩阵的线性分解。让我们来计算一下。我们首先需要通过减去每个变量的平均值来对所有输入进行均值居中。为此,我们首先计算所有变量的平均值(通过将所有对象相加,然后除以它们的数量),然后减去平均值。注意,最后我们没有创建一个新的变量;相反,起始矩阵 *X* 的元素被以平均值为中心的值代替:
//This first block computes each variable's average
averages=[]
for (i=0;i<nvariables;i++) {
var tmp2=0
for (j=0;j<nobjects;j++) {
tmp2=tmp2+X[i][j]
}
averages.push(tmp2/nobjects)
}//This block subtracts each reading by the average of the corresponding variable
for (i=0;i<nvariables;i++) {
for (j=0;j<nobjects;j++) {
X[i][j] = X[i][j] — averages[i]
}
}
现在我们已经减去了平均值,我们可以计算协方差矩阵。到目前为止,包括协方差矩阵的计算,在这篇外部博客中已经很清楚了:
下面是底层代码:
//Here we just setup a covariance matrix full of
var covar = []
for (i=0;i<nvariables;i++) {
var tmp3 = []
for (j=0;j<nvariables;j++) {
tmp3.push(0)
}
covar.push(tmp3)
}//This block fills in the covariance matrix by increasingly summing the products
for (i=0;i<nvariables;i++) {
for (j=0;j<nvariables;j++) {
for (k=0;k<nobjects;k++) {
covar[i][j] = covar[i][j] + X[i][k]*X[j][k]
}
covar[i][j] = covar[i][j] / (nobjects-1) //Here can be -0
}
}
请注意,我们需要三个索引,因为我们需要计算每个变量和所有其他变量之间的协方差,并且对于这些计算中的每一个,我们需要遍历数据集中的所有对象。
还要注意协方差计算过程中间的注释(“这里可以是-0”)。最正确的是将乘积之和除以*no objects*-1,如下图所示;然而,一些例子使用了常规方差,其中总和只除以*no objects。*
## 步骤 2:对角化协方差矩阵
我们现在需要通过奇异值分解(SVD)对角化协方差矩阵。
这是这个过程中唯一的一点,我宁愿使用一个健壮的、经过良好测试的、正确编码的、高效的矩阵代数库,而不是在底层编码所有的东西。在这种情况下,我使用了 Lalolib 包中用于浏览器内数学的一个过程,我在最近的一篇文章中介绍了这个过程:
</websites-for-statistics-and-data-analysis-on-every-device-ebf92bec3e53>
请注意,要使用 Lalolib,您需要在 HTML 中找到它,如下所示:
一旦完成,Lalolib 的所有函数都暴露在您的 JavaScript 中。
现在,在我们对协方差矩阵运行 SVD 之前,我们需要将这个矩阵转换成 Lalolib 可以处理的对象类型。这是因为该库使用自己的数据类型,而不是像我们的 *covar* matrix 这样的原始 JavaScript 数组。
因此,在下一段代码中,您将看到 *covar* 矩阵被转换为 Lalolib 可以处理的矩阵,称为 *matrixforsvd* ,然后您将看到对该矩阵上的 svd 例程的实际调用。如此处所示,您可以将该过程的四个主要输出记录到控制台:
var matrixforsvd = array2mat(covar);
var svdcalc = svd(matrixforsvd, “full”);console.log(svdcalc.U)
console.log(svdcalc.S)
console.log(svdcalc.V)
console.log(svdcalc.s)
**这些输出是什么?**前三个是矩阵。当您对协方差矩阵运行 SVD 时,您会看到 *U* 和 *V* 是相同的,因为这是一个对称矩阵(您可以记录 *covar* 来自己检查这一点)。 *U* 和 *V* 具有负载,它们是定义如何构建主成分空间以最优地展开数据集变化的系数。
*s* (小写相对于大写的 *S* 矩阵)是从 S 矩阵中提取的对角线。原来 *S* 矩阵的所有非对角元素都是零,所以 *s* 向量更简单,包含的信息量也是一样的。该信息包括每个主成分对数据集中总变化的贡献。它们总是按降序排列,你可以通过在我的 web 应用程序上运行示例来验证这一点。如果你将这些数字标准化为它们的总和,你会得到由每个主成分解释的%变化。
## 步骤 3:将数据投影到主成分上
这是 PCA 过程的最后一部分,也是大多数教程经常很快通过的部分。本质上,我们需要做的是将包含起始数据的矩阵(以均值为中心,所以这是我们的 X)乘以通过协方差矩阵的 SVD 获得的 U 矩阵。
因为我在底层编写了这个乘法,所以我首先必须转换 *svdcalc。U* 放入一个 JavaScript 数组。你会看到这个用*完成。toArray()* 。紧接着,两个嵌套的 for 循环执行乘法。
var projection = []
var pc1 = 0, pc2 = 0
var U = svdcalc.U.toArray()
for (i=0; i<nobjects; i++) {
pc1=0
pc2=0
for (j=0;j<nvariables;j++) {
pc1 = pc1 + U[j][0] * X[j][i]
pc2 = pc2 + U[j][1] * X[j][i]
}
var tmp4 = []
tmp4.push(pc1)
tmp4.push(pc2)
projection.push(tmp4)
}
现在,最后一个变量,*投影*,包含*对象*行和 2 列,这是两个第一主成分。PC 图是所有这些 PC1、PC2 对的散点图。
# 结束语
## 在线运行 PCA,通过示例了解它
对于在线运行 PCA 的实际 web 应用程序,包括图形输出,以及关于如何解释结果的解释,请查看另一个故事:
</a-free-online-tool-for-principal-components-analysis-with-full-graphical-output-c9b3725b4f98>
## 尝试一下
将代码片段复制到一个 HTML 页面中,不要忘记获取 Lalolib 库,用一些数据创建一个 X 矩阵,并通过使用 console.log()或 document.write()显示中间结果和最终结果来测试代码。
我希望这篇教程能让你更清楚地了解 PCA 是如何运行的,以及它背后的数学原理。如果本文的某些部分仍然不清楚,那么通过突出显示和评论来表明这一点,我会看看我能做什么!
祝你快乐!
www.lucianoabriata.com*[***我写作并拍摄我广泛兴趣范围内的一切事物:自然、科学、技术、编程等等。***](https://www.lucianoabriata.com/) **[***成为媒介会员***](https://lucianosphere.medium.com/membership) *访问其所有故事(我为其获得小额收入的平台的附属链接无需您付费)和* [***订阅获取我的新故事***](https://lucianosphere.medium.com/subscribe) ***通过电子邮件*** *。到* ***咨询关于小职位*** *查看我的* [***服务页面这里***](https://lucianoabriata.altervista.org/services/index.html) *。你可以* [***这里联系我***](https://lucianoabriata.altervista.org/office/contact.html) ***。******
# 文本提取工具的过滤器背后的设计
> 原文:<https://towardsdatascience.com/the-design-behind-a-filter-for-a-text-extraction-tool-b9eb2c9b2e8d>
几年前,我开发了一个名为 SEER 的信息提取(IE)工具,帮助用户从文档中提取数据。例如,调查员希望从 FBI 新闻稿的数据集中提取所有犯罪的增加和减少。

图片作者。
SEER 学习从用户给定的文本高亮示例中自动提取数据。它学习高亮文本中的模式,并生成匹配和提取所需目标文本的*提取规则*。

每一行都是一个提取规则。并且每个抽取规则抽取所有的*正例。*图片作者。
提取规则是正则表达式、字典、字符串、标记间隙和实体的彩色框的序列,在 SEER 中称为预构建。这些彩色框序列描述了文本中要匹配和提取的模式。提取规则的输出被称为*提取*。

图片作者。
然而,SEER 通常会生成几个候选提取规则,因为可能会有大量的规则集匹配所有的正例,并且可以完成任务。用户必须找到并选择这些规则中的哪一个最好地提取所需的提取集合。

用户必须检查每个提取规则,以检查提取是否包含他想要的所有文本。一些规则提取不想要的文本,而一些规则提取想要的文本。图片作者。
工具中设计了过滤器,以帮助用户快速选择最符合其预期提取集的提取规则。如果没有任何过滤器,用户将不得不自己手动分析和比较规则的提取。此外,有许多不同的方式来设计这种滤波器。在本文中,我们将讨论如何为提取规则设计这样一个过滤器。
## 按提取过滤规则
当我们设计过滤器时,我们没有使用标准的搜索栏,用户只需输入一个关键字,然后工具根据关键字过滤规则。按提取的文本过滤规则是有用的,但它仍然会显示提取用户可能实际上不想要的文本的规则。需要有一种方法根据期望的和不期望的提取来过滤规则。
因此,我们要求用户对候选规则提取的文本回答“是”和“否”。我们称这些文本为用户可以接受或拒绝的*细化*。精化是区分和过滤掉规则的提取。

在这里,用户通过接受或拒绝细化来过滤规则。当她回答细化问题时,Seer 也会根据用户的回答将一些细化问题变灰,我们稍后会谈到这一点。图片作者。
## 细化是如何创建的?
让我们简化这个场景。假设该工具学习并生成了以下提取规则:

提取规则显示在左侧,中间显示每个提取规则的提取。最右边是不同的提取。图片作者。
每个规则都有自己的提取集。这些提取中的一些被称为*区分提取*:这是一个由规则子集而不是所有规则捕获的提取。一个区分提取可以被一个或多个规则捕获,只要它不被*所有*规则捕获。
在我们的场景中,不同的抽取是“百分之五”和“百分之五十”。这些提取被至少一个规则捕获,但不是所有规则。
SEER 将这些不同的提取作为过滤器呈现给用户。

提炼基本上是区分提取。图片作者。
## 使用区分提取过滤规则
假设用户选择“否”到“百分之五”。然后 SEER 会过滤掉那些没有抓住“百分之五”的规则。换句话说,SEER 只显示了最后两条规则。如果用户选择“是”到“百分之五”,SEER 只显示预构建的规则。

图片作者。
如果用户选择“是”到“50%”,SEER 只显示第一个和最后一个规则。如果用户选择“否”到“50%”,SEER 只显示第二条规则。

图片作者。
当用户对细化回答“是”和“否”时,SEER 会调整呈现的规则集。
## 防止用户答案冲突
有时,用户可以提供与规则相关联的提取的答案,这些规则也被其他提取捕获。所以 SEER 禁用了一些改进来防止冲突的意图。
如果用户选择“是”到“5%”,但选择“否”到“50%”,这将导致冲突。SEER 不确定是否显示预构建的规则,因为两个提取都出现在该规则中。

图片作者。
为了防止用户意图的冲突,如果精化的规则之前已经被回答或者已经被过滤掉,SEER 将禁用精化。

“50%”选项被禁用,因为 SEER 已经从接受“百分之五”的用户那里知道了答案。图片作者。
因此,如果用户选择“是”到“百分之五”,则“50%”的选择将被禁用。而这是因为 SEER 已经从之前的选择中知道了“50%”选择的答案。这是因为所有“50%”的规则都已经被接受了。
## 结论
在这篇短文中,我将讨论我们如何为提取规则设计过滤器。我们将这些摘录作为用户可以接受或拒绝的细化。有关该工具的更多详细信息,请参见[的论文](https://dl.acm.org/doi/10.1145/3025453.3025540)。
# 诊断分析差距
> 原文:<https://towardsdatascience.com/the-diagnostic-analytics-gap-3f9d0a44e8f8>
## 为什么这种差距是相关的,如何弥补?

注意差距(图片由 jigsawstocker 在 Freepik 上提供)
在仪表板中显示正在发生的事情是信息性的,而不是深刻的。知道一个关键的业务指标是上升还是下降是有用的,但是这是不可行的。只有这些变化背后的“为什么”才能推动建议和行动。
然而,我经常听到团队如何在每周/每月的评审中查看仪表板,并评论指标上升或下降,而没有对根本原因或可操作的见解的明确答案。这导致错失通过数据和分析推动业务影响的机会,阻碍了保持竞争优势所需的敏捷性。
# 这有什么关系?
在大多数组织中,分析仍然主要是描述性的(例如,发生了什么)。
很少有数据和业务团队找到了诊断分析(即,为什么会发生这种情况)。
当外部事件影响业务和利益相关者采取行动时,指标会随之改变。企业需要了解 KPI 的驱动因素,以及它们为什么会改变以做出更好的决策。这只能通过诊断分析来实现:根据业务发展速度提供对指标变化的全面洞察。
但是,利益相关者和数据从业者经常会根据他们的领域专业知识、直觉和经验,提出关于度量标准为什么会改变的假设。这些原因通常是高层次的,只是通过测试 2 或 3 个常见的嫌疑人来了解表面情况,从而导致错失机会。
# 分析领域
从高层次来看,诊断分析经常被忽视,因为它位于数据和业务之间。将它与其他类型的分析类型进行比较很有帮助。

诊断分析差距(图片由作者提供)
**描述性分析**通过仪表盘自助完成。数据团队管理治理和基础设施,并支持业务团队。有清晰的流程、所有权和工具。
**诊断分析**位于业务和数据之间。通过通用仪表板进行自助诊断分析几乎是不可能的(尽管许多数据团队都陷入了这一误区)。没有明确的流程,数据文化差异很大。
**预测和说明性分析**由数据团队管理,拥有业务团队使用的清晰数据产品(如推荐系统和预测模型)。它们在技术上很复杂,但在流程、人员和文化方面非常清晰。
# 是什么造成了这种差距
随着数据量和复杂性的增长以及业务变化速度的加快,业务需求和交付之间的差距不断扩大。出于各种原因,大多数组织都忽略了这一差距。对差距的深入理解需要基于 4 个关键要素的整体方法:人员、文化、工具和流程。
让我们更深入地了解 4 个关键要素中的每一个。

4 个关键要素之间诊断分析差距的原因(图片由作者提供)
# 如何弥合这种差距?
理想情况下,业务和数据团队会定期主动分析指标变化。即使顶线变化很小,通常也会有相反的效果。识别它们是至关重要的,以便团队可以快速区分什么是有效的,什么是无效的,并采取行动来最大化业务影响。
重点放在哪里,要看出发点。它需要对之前描述的 4 个要素进行全面概述。根据与数十名数据和业务负责人的交谈,我经常看到不同的诊断分析成熟度级别。我试着将不同的现实分为以下四种状态。

诊断分析的 4 种状态(图片由作者提供)
**状态 1 — *卡在【什么】***
公司缺乏深入探究原因的数据文化。团队监控仪表板上的度量,但是很少确定数据驱动的原因,即它们为什么改变。
**行动:**培养数据文化,向业务利益相关方展示诊断分析的价值
**如何:**
* 选择 2 或 3 个您认为有巨大潜力交付商业价值的用例。
* 主动调查这些业务指标的变化,并以结构化和影响驱动的方式分享您的发现
* 继续下去,直到你获得几个成功的故事。这应该是进一步扩展到其他用例并开始变更管理过程的基础
**状态 2 — *常见疑点***
团队最终只触及了为什么度量会改变的表面,并且只定期测试几个常见的疑点。
这是一个棘手的问题,因为它缺乏症状。业务涉众只是测试他们的高层次假设,导致错失机会。数据团队认为他们在自助分析方面做得很好。
**行动:**提高认识,不深入探究原因会导致错失机会
**如何:**
* 选择 2 或 3 个关键用例,在这些用例中,您知道业务团队只关注通常的疑点。
* 通过比较全面的分析和之前只触及表面的分析,主动深入到原因并分享您的发现
* 构建成功案例并扩展到更多使用案例
**状态 3 — *需要速度***
企业意识到深入研究原因的价值,但却在速度和全面性之间苦苦挣扎。
在这种情况下,数据文化已经很先进,团队只差马拉松的最后一英里了。大多数团队都意识到存在有待发掘的商业价值,但都在努力加速诊断分析。使用现有工作流执行全面的根本原因分析过于复杂和耗时。团队努力按照业务的速度提供见解。
**行动:**增强当前的工作流程,加快洞察速度,消除速度-全面性之间的权衡。
**如何:**
* 考虑增强分析平台,以加快洞察速度并消除权衡。这些工具利用 ML 来自动化假设测试和驱动因素评分。通过这种方式,团队可以了解业务的发展速度,而您可以扩展分析,而无需投入更多的分析师来解决问题
* 审查当前的诊断分析程序,并确保以适当的方式进行这些分析、分享见解和组织它们
* 针对最重要的用例,加强数据分析师和业务部门之间的协作,以发展领域专业知识
**状态 4 — *全力***
团队主动诊断度量的变化,以便不断改进。通过增强传统的工作流程,团队消除了速度和全面性之间的权衡,主动分享可操作的见解,并捕捉广泛的机会。
这种状态可以作为最佳实践来展示。团队积极主动地协作,流程定义明确清晰,并且实施了一套正确的工具来深入了解原因并找到可行的见解。因此,数据分析的投资回报率是明确的,并且对数据文化有很强的信任。
# 一句话:关键在于为什么
在仪表板中显示正在发生的事情是不够的。全面而快速地深入到为什么是提供可操作的见解以增加分析价值的唯一方法。这是征服数据之旅最后一英里的方法。
—
*思想?伸出手去* [*若昂索萨*](https://www.linkedin.com/in/joaoantoniosousa/)*主管成长* [*考萨*](http://www.kausa.ai) *。敬请关注更多关于如何确定诊断分析和增加数据价值的帖子。*
# 相关和回归的区别
> 原文:<https://towardsdatascience.com/the-difference-between-correlation-and-regression-134a5b367f7c>
## 关于这些话题的澄清文章

马库斯·温克勒在 [Unsplash](https://unsplash.com/s/photos/graphs?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText) 上的照片
W 当开始机器学习时,在移动键盘上的手指并开始编程之前,有许多主题需要理解。这些主题不仅与“可用的”算法有关,还与数学概念密切相关(但是,正如我所说的,如果你不懂数学,你可以在需要时学习)。
当接近数据科学和机器学习时,需要理解统计学中的一些主题;其中一些主题是相关性和回归。在本文中,我将举例说明这两个主题之间的区别,我们甚至会提到“相关性不是因果关系!”。
# 1.相互关系
> **相关性是表示两个变量之间线性关系的统计量。**
事情就是这样。但是,你知道,定义必须付诸实践(也是为了更好地理解我们正在研究的主题)。
深化概念,我们可以说两个变量是相关的,如果第一个变量的每一个值对应于第二个变量的一个值,遵循一定的规则(或者,如果你想的话,遵循一定的路径);因此,如果两个变量高度相关,路径将是线性的(一条线),因为相关性描述了变量之间的线性关系。
**这意味着相关性表达的是变量之间的关系,而不是因果关系!**如果自变量的值增加,因变量的值也增加,并不意味着第一个变量导致第二个值的值增加!
我们来举个例子:
夏天到了,很热;你不喜欢你的城市的高温,所以你决定去山上。对你来说幸运的是,你到达山顶,测量温度,你发现温度比你所在的城市要低。你有点怀疑(也是因为你对温度的下降不满意),你决定去一座更高的山,发现温度甚至低于上一座山的温度。
你尝试不同高度的山,测量温度并绘制图表;你发现随着山的高度增加,温度降低,可以看到一个线性的趋势。这是什么意思?说明温度和高度有关;**这并不意味着山的高度导致了温度的下降**(如果你乘坐热气球到达相同的高度,在相同的纬度,你会测到什么温度?:) ).
因此,既然在物理世界中我们需要定义来衡量事物,那么一个好问题就是:我们如何衡量相关性?
测量相关性的典型方法是使用 c **或相关系数**(也称为皮尔逊指数或线性相关指数)。我不想深究数学,因为这篇文章的目的是提供信息和教育,而不是公式:我只想让你抓住并理解概念。
相关系数利用了统计概念**协方差**,这是一种数字方式来定义**两个变量如何一起变化**。抛开数学,只谈概念,**相关系数是一个在-1 和+1** 之间变化的数值。如果相关系数为-1,两个变量将具有完美的负线性相关性;如果相关系数为+1,两个变量将具有完美的正线性相关性;如果相关系数为 0,说明两个变量之间不存在线性相关。
我说我们会留下数学,但我没有说我们会留下代码,因为我们是在数据科学领域。那么,我们如何在 Python 中计算相关系数呢?我们通常计算相关矩阵。假设我们将两个变量存储在一个名为“df”、“变量 1”和“变量 2”的数据帧中,我们可以绘制相关矩阵,例如在 seaborn:
import seaborn as sns#heat map for correlation coefficient
sns.heatmap(df.corr(), annot=True, fmt="0.2")
我们得到了:

相关变量的相关矩阵。图片由作者提供。
上图显示,我们考虑的两个变量高度相关,因为它们的相关系数是 0.96。于是,我们期望用一条斜率为正的直线来描述它们之间的关系。这里我们来到了下一个概念:回归。
但是在讨论回归的概念之前,我想说最后一件事。在这篇文章中,我强调了一个事实,相关性与变量之间的线性关系有关。让我们来看两个变量,我们知道它们不是线性相关的;例如,一个寓言:

一个寓言。图片由作者提供。
在这种情况下,如果我们计算相关系数,我们得到 0:

不相关变量的相关矩阵。图片由作者提供。
变量不相关的事实恰恰告诉我们,没有一条线可以描述变量之间的关系:**不代表变量完全不相关!**只是说明关系不是线性的(可以是任何东西!)
# 2.回归
> 回归分析是一种用于分析一些数据的数学技术,由一个因变量和一个(或多个)自变量**组成,目的是找到因变量和自变量之间的最终函数关系。**
**回归分析的目的是找到一个估计值**(一个好的估计值!)在因变量和自变量之间。从数学上来说,回归的目的是找到最符合数据的曲线。
当然,最符合数据的曲线可以是直线;但是可以是什么曲线,看关系!
所以,我们通常做的是计算相关系数,如果它的值接近 1,我们可以在研究回归时得到一条线;否则…我们必须尝试多项式回归(或其他东西,如指数或任何东西)!
事实上,如果我们计算之前看到的数据之间的回归线(相关系数为 0.96 的“变量 1 和变量 2”),我们会得到:
import seaborn as sns
import matplotlib.pyplot as plt#plotting the time series analysis with a red regression line
sns.regplot(data=df, x="Variable_1", y="Variable_2", line_kws={"color": "red"})plt.xlabel('Variable 1', size=14)
plt.ylabel('Variable 2', size=14)
plt.title('(LINEAR) REGRESSION BETWEEN TWO VARIABLES')

线性回归图。图片由作者提供。
正如所料,由于相关矩阵为 0.96,我们得到一条斜率为正的线,作为最符合数据的曲线。
最后,我想说,有无数种技术可以找到最符合数据的曲线;最常用的方法之一是“普通最小二乘法”,但是,正如我所说的,我不会进入数学领域:请相信我,因为这篇文章的目的是传播概念和知识。
感谢阅读。如果你不知道,我希望你已经理解了这些概念(如果不知道,请用评论告诉我!);如果你知道这些概念…我希望我没有犯任何错误!
*我们一起连线吧!*
[***中等***](https://federicotrotta.medium.com/)
[***LINKEDIN***](https://www.linkedin.com/in/federico-trotta/)*(给我发送连接请求)*
*如果你愿意,你可以* [***订阅我的邮件列表***](https://federicotrotta.medium.com/subscribe)**这样你就可以一直保持更新了!**
*考虑成为会员:你可以免费支持我和其他像我一样的作家。点击 [***这里***](https://federicotrotta.medium.com/membership)**成为会员。***
# 机器学习和深度学习的区别
> 原文:<https://towardsdatascience.com/the-difference-between-machine-learning-and-deep-learning-b029f09d0bf8>
## *非常好的理解机器学习和深度学习。还要学会区分这两个术语,而不是互换使用。*
诸如**【机器学习】**和**【人工智能】**等搜索术语的数量一直在增长,人们试图尽可能地学习和掌握这些复杂的术语,并理解它们的潜在用途。公司也越来越依赖数据科学家和机器学习工程师,让他们在经过培训的智能系统和计算机的帮助下,自动完成日常工作。此外,人工智能领域还出现了一个新的研究领域,称为深度学习。这个领域已经彻底改变了计算机学习手头任务和进行预测的方式,有时在各种任务中超过人类。
机器学习和深度学习这两个术语经常混淆。更多地了解这些术语以及它们的异同,就有可能理解给定的问题并将其分类为是机器学习问题还是深度学习问题。虽然这两个术语可以互换使用,但它们有时会有所不同,尤其是在模型预测的执行方式上。我知道这很多,但我想进一步简化这些概念,并帮助您更好地理解这些主题。
## 什么是机器学习?

照片由 [Jelleke Vanooteghem](https://unsplash.com/@ilumire?utm_source=medium&utm_medium=referral) 在 [Unsplash](https://unsplash.com?utm_source=medium&utm_medium=referral) 上拍摄
简而言之,这基本上是一种 **ML 模型**从数据中学习重要模式和洞察力的能力,同时对他们以前没有见过的数据做出预测。因此,这一切都是关于训练模型和**从我们已经拥有的数据中完善**它们,以便它们开始从数据中学习。一旦他们从数据中完全了解了有用的表示,并能够确定每个单独的要素如何影响特定输出标注的生成,他们就可以通过基于他们已经训练过的数据做出有用的预测,来学习如何**很好地概括**他们以前没有见过的数据。这就是为什么它被称为机器学习,机器从数据中学习,并学习对它没有看到的数据做出有用的预测。
## 什么是深度学习?

Solen Feyissa 在 [Unsplash](https://unsplash.com?utm_source=medium&utm_medium=referral) 上拍摄的照片
这是机器学习的一个**子领域**,其模型结构受到人类感知和理解世界的方式的启发。虽然它肯定没有我们人类感知世界的复杂性,但它实际上受到了我们如何考虑世界以及我们感知世界的方式的启发。它由**神经元单元**(类似于人类大脑中的神经元),以及中间的许多层(**隐藏层**和**最终层**)组成,它从数据中学习表示,以便能够基于其学习生成预测。同样重要的是要注意,在这些单元(神经元)的每一个中都存在激活函数,因此线性函数被转换成非线性的表示,这实际上可用于从数据中提取感兴趣的模式。
## 机器学习和深度学习有哪些共性?

马库斯·温克勒在 [Unsplash](https://unsplash.com?utm_source=medium&utm_medium=referral) 上拍摄的照片
**机器学习**基本上是教计算机从数据中学习,并根据它们已经学习到的有用表示的数据,对它们以前没有见过的数据做出预测。深度学习实际上是机器学习的一个子集,因为它也涉及到教会网络从数据中学习,并根据训练数据做出有用的预测。同样需要注意的是,深度学习只是机器学习的一部分。机器学习模型不一定只是神经网络或深度学习模型。也可以是其他算法,如**支持向量机(SVM)** 、**线性回归**或**逻辑回归**。
## 机器学习和深度学习有什么区别?

由[凯利·西克玛](https://unsplash.com/@kellysikkema?utm_source=medium&utm_medium=referral)在 [Unsplash](https://unsplash.com?utm_source=medium&utm_medium=referral) 上拍摄的照片
当我们试图谈论机器学习以及一些模型,如决策树、随机森林等。,同样重要的是谈论**特征工程**在数据被馈送到这些模型进行预测之前,显式特征是由数据科学家还是数据工程师创建的。相反,深度学习使用神经网络作为它们的模型,它们特别擅长在没有人类干预的情况下提取有用的特征。但是,如果对数据进行特征工程,并将其交给深度学习模型进行预测,这总是有帮助的。提供给模型的数据可以是图像或声音文件以及输出标签。因此,深度学习模型从数据本身学习**有用的表示**和**特征**,而不需要显式执行特征工程,这与我们执行机器学习任务和建模的方式相反。
## **机器学习领域的进展**

Volodymyr Hryshchenko 在 [Unsplash](https://unsplash.com?utm_source=medium&utm_medium=referral) 上拍摄的照片
随着数据的增长以及运行最大似然算法所需的计算能力的提高,可以看出机器学习在最近十年中获得了很大的发展。机器学习的一些有趣应用包括检测银行交易中的欺诈、汽车价格预测、客户满意率预测和许多其他应用。机器学习有大量的可能性和实用性。唯一的要求是拥有准确标记的高质量数据,这些数据可用于**监督**模型(训练)并确保它们在各种任务中给出匹配甚至超过**人类水平表现**的良好预测。
## **深度学习领域的进展**

杰斯·贝利在 [Unsplash](https://unsplash.com?utm_source=medium&utm_medium=referral) 上拍摄的照片
同样,**深度学习**也有一些非常有趣的应用,其中一些应用在**无人驾驶汽车**中,汽车学习预测各种物体的视觉效果及其意义。值得注意的是,在这种应用中,重要的是要注意准确性或深度学习模型实际上对对象分类的好坏。如果错误率大幅增加,那么在自动驾驶汽车的情况下,发生事故的几率就更高。例如,如果具有深度学习功能的汽车摄像头假设没有实际上有停止标志的停止标志,它可能会对其驾驶和遵守道路规则的方式产生严重影响。因此,在训练这些模型并确保模型给出最佳预测时,必须小心谨慎。
对于在机器学习或数据科学方面是**新手**并且缺乏成为一名新手的**经验**的人来说,如果你建立一个强大的工作组合,其中包括你最好的项目和任务,这会非常方便。请随意观看此**视频**,我在其中强调并解释了投资组合在获得第一份数据科学工作中的重要性。谢了。
关于为数据科学或机器学习工作建立强大投资组合的视频
## 结论
总而言之,我们已经看到了机器学习和深度学习之间的共同点以及一些差异。此外,我们还看到了机器学习和深度学习的一些有趣的应用。感谢您花时间阅读这篇文章。
以下是您联系我或查看我作品的方式。谢了。
**GitHub:** [苏哈斯马达利(苏哈斯马达利)(github.com)](https://github.com/suhasmaddali)
**LinkedIn:** [(1)苏哈斯·马达利,东北大学,数据科学| LinkedIn](https://www.linkedin.com/in/suhas-maddali/)
**中等:** [苏哈斯·马达利——中等](https://suhas-maddali007.medium.com/)
# 数据领导者的艰难生活
> 原文:<https://towardsdatascience.com/the-difficult-life-of-the-data-lead-a31186ef0d27>
## 为什么平衡管理一个团队与要求高的利益相关者和仍然亲力亲为不是一件容易的事情
处理数据从未如此困难。数据堆栈变得越来越复杂,期望值也比以往任何时候都高。
然而,有一个数据角色比大多数人都难:数据领导者。
担任数据中层管理角色的人通常被称为*数据主管*或*数据经理*,这是唯一一个你必须平衡管理团队与作为领导团队的一部分工作并仍然做实际工作的角色。不容易结合。

作者图片
如果你是一个 IC(个人贡献者),你的工作很有挑战性,但是你的重点很明确。通过交付高质量的分析和数据产品,通过与利益相关方合作确保您的工作产生影响,您将获得成功。
如果你是数据主管,你在战略层面上工作,如果你幸运的话,你在最高管理层有一个席位。你的角色很难,但你的重点也很明确;在你周围建立一个伟大的团队,确保数据团队在正确的优先事项上工作,并为未来的成功做好准备。
但是,如果你是一名数据主管,你必须一次完成所有这些工作。

作者图片
作为数据主管,你必须管理你的直接团队。这包括处理绩效管理问题,确保优秀员工受到挑战,以及雇佣合适的人。
你还必须管理利益相关者,他们通常有相互竞争的优先事项,并了解你的直接团队中有人参与的每个领域的情况。
你需要亲自动手,能够直接编写代码、构建仪表盘或提供分析,为好的外观设定标准。
这是一个很大的平衡。

作者图片
所有这些结合在一起,使得数据中层管理的角色非常独特,而作为一个数据行业,我们还没有想出如何处理这个问题。
随着数据集成电路职业发展道路开始成为人事管理阶梯的可行替代方案,我开始看到更多的数据线索被吸引到这一点上。他们仍然雄心勃勃,希望在职业生涯中取得进步,但也希望有时间专注于自己的手艺和深度工作。
如果你看看工程团队,许多工程经理已经把大部分与 IC 相关的工作抛在脑后了。事实上,在许多组织中,看到工程经理将代码推送到生产代码库是不常见的。
公司仍然需要数据经理,所以不是每个人都可以转移到 IC 阶梯。有人建议数据主管应该更像工程经理,但我不确定这是他们想要的。根据我的经验,亲力亲为是他们最喜欢的工作。
# 问题的一个可能的根本原因
随着[数据团队变得越来越大](https://mikkeldengsoe.substack.com/p/data-team-size),对数据中层管理人员的需求只会增加,找出最佳运营模式是关键。一个解决办法是停止期望他们能够一次完成所有的事情。
如果当务之急是发展团队,那么在团队被雇佣之前,利益相关者不应该期望数据引导是实际的。
如果有一个绩效管理问题,团队中有人需要很多关注,招聘团队应该接受更多的初始候选人电话。
我认为数据经理压力最常见的根本原因是利益相关者。他们不是故意***难(我希望如此),通常是出于良好的意愿来推动自己的商业目标。但是许多利益相关者不知道如何与数据人员合作。在高速增长的公司里,你经常会有来自各种背景的利益相关者。特别是来自传统公司的人,他们可能希望数据团队更多地作为服务功能来运作,目标是响应特定的数据请求。这是一个我一直以来都在制造很多摩擦的话题。
利益相关者为分配给他们的项目的数据“资源”而斗争,让数据领导者处于无法让任何人满意的困境,这也并不罕见。
**如何改善这种情况?**
一个问题是,许多组织没有一个高级数据人员坐在最高管理层的桌子上,可以为数据说话。这不像你在工程领域看到的那样,没有至少一个高级技术人员在那里是不常见的。
另一个解决方案是教育利益相关者。我总是发现与有数据背景的高级利益相关者一起工作要容易得多。他们知道有些工作有多难,也知道什么时候该偷工减料。所有高层领导都有数据背景但不做服务职能的数据团队还是一个比较新的事物,这可能是一厢情愿的想法。希望更多的利益相关者将习惯于如何与数据人员一起工作。
我仍在等待有人给利益相关者写一本关于如何与数据人员合作的终极手册*。*
如果你正在做这方面的工作或者有这方面的经验,我希望收到你的来信!
# 仪表板设计的注意事项
> 原文:<https://towardsdatascience.com/the-dos-and-donts-of-dashboard-design-2beefd5cc575>
## 创建有影响力的仪表板的快速提示

卢克·切瑟在 [Unsplash](https://unsplash.com) 上的照片
如今,许多组织和产品都在使用仪表板。仪表板是以可视化格式共享数据的好方法。Tableau、Cognos Analytics 和 Python 是一些用于创建仪表板的工具。有了这么多不同的工具,制作一个优秀的仪表板需要什么呢?
当仪表板不好时,我们作为用户会很快注意到,这反过来又会导致使用率低。当一个仪表板很棒并且易于使用时,我们不会花时间去想它——我们太忙于寻找有趣的见解了!
随着时间的推移,我发现了一些行之有效的制作仪表盘的技巧。下面你会发现仪表板设计的一些注意事项,以帮助你的下一个项目!
# DO:添加文本
仪表板可以包含更多的可视化!添加文本允许您向用户提供额外的上下文。根据所使用的工具,实现的方式会有所不同。许多工具,如 Cognos Analytics 和 Tableau,都有可以添加到仪表板的文本框。我使用仪表板标题下方或附近的文本框为用户提供说明和概述。
文本框可以放置在仪表板上的其他地方,为显示的可视化效果提供评论或见解。突出显示仪表板中的示例见解的几个要点可以帮助用户开始使用该工具。
在向仪表盘添加文本时,记住 KISS 原则— ***保持简洁*** 。长长的文本段落会阻碍用户使用仪表板。

按作者分类的图像:仪表板标题示例,标题下有仪表板说明
# 不要:保留默认字体设置
许多商业智能(BI)工具,包括 Tableau 和 Cognos Analytics,都有默认的字体设置。我个人发现我很少使用这些设置。默认设置并不可怕,但稍加调整就能增强用户体验!调整字体大小、颜色或对齐方式可以微妙地向用户传达意思。特定的尺寸或样式可以向用户表明特定的用途。
以下是几种修改仪表板字体的方法:
* **整合字体大小的分层系统** —一致的字体大小有助于用户知道在哪里寻找特定类型的信息。在设计仪表板时,我使用最大的字体作为仪表板标题,第二大字体用于图表标题,最小字体用于添加到仪表板的任何附加文本。

作者图片:字体大小的分级系统
* **加粗文本** —加粗所有标题(包括仪表板标题和单个图表标题),以及文本框中的任何关键词或短语。
* ***斜体文本*** —斜体文本是用户在导航仪表板时应特别注意的内容—这可能是针对特定用户组的特殊说明,或者是关于他们正在查看的仪表板的免责声明!
* **添加颜色** —颜色是一种突出文本框中的关键词、短语或信息的好方法,可以让用户快速发现。在仪表板上添加关键见解时,我使用颜色来突出显示与数据相关的特定单词或数字,如下例所示。

作者提供的图片:为特定的关键数字和单词添加颜色的洞察示例。
# DO:添加过滤器
仪表板的主要优势之一是能够对数据进行切片和切块!最好的方法是使用过滤器!许多 BI 工具允许您直接在仪表板上添加过滤器,或者使用可视化工具过滤您的视图。
当直接在仪表板上添加过滤器时,我把它们放在一个地方,这样用户很容易找到。我选择补充仪表板的位置,但不从整体故事中抽离。将过滤器放置在仪表板的顶部、右侧或左侧,使用户可以轻松地访问过滤器,同时确保可视化具有主要焦点。

作者图片:带有虚拟数据的仪表板—过滤器位于顶部,使用 Tableau 的显示/隐藏按钮
我个人最喜欢的是使用可视化作为过滤器。我发现它为用户创造了愉快的互动体验。他们能够创建和导航自己的数据之旅,并深入挖掘数据集。例如,如果您有一个饼图,用户可以选择一个切片,仪表板上的所有可视化将更新以反映该数据子集。许多工具都支持这个特性,例如,在 Tableau 中,您可以为每个可视化启用一个[过滤器动作](https://help.tableau.com/current/pro/desktop/en-us/actions_dashboards.htm),而在 Cognos Analytics 中,这是默认的[功能](https://www.ibm.com/docs/en/cognos-analytics/11.1.0?topic=filters-highlighting-data-points-across-visualizations)。
*注意:如果你不想让过滤器占据仪表板上的空间,或者你不想使用可视化作为过滤器,许多工具都有替代方法。Tableau 中的* [*显示/隐藏按钮*](https://www.thedataschool.com.au/david-ruhnau/tableau-2019-2-and-the-show-hide-button/) ,*和 Cognos Analytics 中的* [*所有选项卡&当前选项卡过滤器*](https://www.ibm.com/docs/en/cognos-analytics/11.1.0?topic=dashboards-filters) *都是不错的选择。*
# 不要:在页面上随意放置可视化效果
你把你的视觉效果放在哪里是很重要的——首先考虑你想让用户看到什么并与之互动,然后把这些东西放在靠近顶部的地方。考虑对齐和可视化大小——所有的可视化不必是相同的大小,你希望哪一个占用更多的空间?你想讲什么故事?有没有一种方法来放置视觉效果,以便有一个自然的流程?
这就像读一本书,你不会上下颠倒或者不按顺序来读,那么为什么要期望用户为一个仪表板这样做呢?
当我试图确定可视化的位置时,我创建了几个不同的选项。首先,我从草图开始,然后用我用来开发仪表板的工具创建一些选项。我也测试我将如何向观众讲述一个故事。这让我看到故事自然地流向哪里,以及哪里可能需要调整。

作者图片:仪表板草图示例
如果你有几个可视化,但不知道放在哪里,考虑添加标签。这些选项卡可以关注数据集的特定可视化或部分。
# DO:包括 KPI
KPI(关键绩效指标),或关键度量,是某种你可以*量化的度量。*交易总数*、*索赔总数*和*平均用户响应率*是 KPI 的几个例子。所使用的指标应该是最终用户感兴趣的,因为它们可以帮助做出关键的业务决策。*
**
*马库斯·斯皮斯克在 [Unsplash](https://unsplash.com/) 上拍摄的照片*
*如果你的用户只有 5 秒钟的时间看你的仪表盘,这些数字应该会很突出。就仪表板上的 KPI 而言,位置是关键。将 KPI 放在顶部附近,以获得最大的可视性。我发现一些有效的位置在右上角,或者仪表板标题的正下方。*
# *不要:只使用一种可视化类型*
*一个只有条形图的仪表板,或者更糟的只有饼图的仪表板,不会留下太大的影响。有几种类型的可视化对不同的数据类型有益。考虑显示数据的最佳方式。虽然可视化类型的一些重复是好的,但是要尝试包含一些变化。在仪表板上只使用一种可视化类型会使事情难以突出,并会导致用户忽略关键的见解。*
*常见的可视化类型包括水平和垂直条形图、饼图、文字云、折线图、热图、散点图和气泡图。有关不同可视化类型的更多信息,请查看[塞维里诺·里贝卡](http://www.severinoribecca.one/)的[数据可视化目录](https://datavizcatalogue.com/)。*
# *DO:使用一致的配色方案*
*具有一致配色方案的仪表板会产生一种有凝聚力的外观,这有助于与您的最终用户建立信任和可信度,同时还会设定仪表板的整体基调。为特定的值或维度选择相同的颜色是增加凝聚力的一个很好的方法,并允许用户跨仪表板连接数据点。许多工具还支持自定义配色方案——这是组织将公司颜色融入仪表板的好方法!*
*如果您不确定从哪里开始,[数据颜色选择器](https://learnui.design/tools/data-color-picker.html#palette)是一个有用的工具,可以为您的数据可视化和仪表板确定正确的颜色——特别是如果您使用 Python 或 r 等工具。该工具可以帮助您测试不同的调色板、单一色调比例和发散比例。*
**
*作者图片:使用[数据颜色选择器](https://learnui.design/tools/data-color-picker.html#palette)生成的样本调色板*
# *不要:感到坚持第一个设计的压力*
*仪表板开发是一个迭代的过程,所以不要觉得坚持第一个版本有压力!第一个版本很少是最终版本,从长远来看,保持僵化会降低整体质量。*
*在整个过程中与您的最终用户协作,并让他们在构建仪表板时对其进行测试。观察他们的相互作用,看看什么有效,什么无效,并从那里进行改进!*
*遵循这些注意事项,提升您下一个仪表板的设计!*
*Payal 是 IBM 的一名数据科学家。在业余时间,她喜欢阅读、旅游和写作。如果你喜欢她的作品, [*关注或订阅*](https://medium.com/@payal-patel) *她的列表,不要错过一个故事!**
**以上文章是个人观点,不代表 IBM 的立场、策略或观点。**
# 数据驱动决策的不利方面
> 原文:<https://towardsdatascience.com/the-downside-of-data-driven-decision-making-b753301b8d66>
## 数据驱动的决策通常会为“错误的问题”提供完美的答案。

克劳迪奥·施瓦兹在 [Unsplash](https://unsplash.com/s/photos/data-decsion?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText) 上的照片
如今,很难找到一家公司不把“**数据驱动决策制定**”(简称 DDDM)放在战略清单的首位。公司拥有的数据比以往任何时候都多,他们的自然动机是找出如何从这些数据中创造价值。然而,根据该报告(对美国各行业 190 名高管的调查):
> 只有 32%的公司表示能够从数据中实现有形且可衡量的价值。
在这里,我想提供一个见解,也许可以解释为什么公司不能从数据中实现价值。重要的是要认识到,在 DDDM,焦点是数据**。我们在 CEO 演讲、公司演示、媒体文章中听到很多:)等等。,像“数据有更好的想法”或“数据是新的黄金”这样的短语。“数据驱动决策”的主要思想可以归结为:**
> **我们能从这些数据中得到什么启示?**
**我想告诉你,跟着上面的问题走,往往会问出**“错题”。在 DDDM 方法中,我们试图为手头的数据找到一个用途。然而,这不是决策者的目标。公司决策者的目标是创造价值,这只能通过“**高质量”**的决策来实现。在组织中,我们需要找到为决策服务的**相关数据**。****
> **组织创造价值的唯一途径是做出高质量的决策,而数据需要为实现这一目的服务。**
**在这个背景下,我想看一个商业决策的例子,首先我考虑“**数据驱动”**方法的情况。接下来是另一个替代方案,通过**“决策驱动的数据分析”**方法来修复该方法中的一些缺陷。**
# **商业决策示例:**
# **流失分析:**
****
**来源:作者**
**对于任何向客户提供产品的 SaaS(软件即服务公司)来说,流失分析都扮演着重要的角色。简而言之,流失分析包括建立:**
> **预测性流失模型着眼于过去的用户活动,并基于客户特征,然后创建一个模型,给出客户终止您的服务或产品的可能性。**
**作为客户,我们都可能通过以下渠道从某项服务中流失:**
* **结束订阅**
* **关闭服务帐户**
* **拒绝续订合同或服务协议**
**SaaS 公司需要找到降低流失率的解决方案,因为**
> **获得一个新客户的成本是留住一个老客户的 6-7 倍。**
**给定这个案例的简短描述,我们按照 DDDM 的方法来决定这个问题:**
*****数据驱动方式:*****
**现在,让我们来看一个开发机器学习(ML)模型的例子,该模型可以给出客户离开订阅的概率(流失概率)。ML 模型基于公司的内部数据。然后,这个 ML 模型将用于“决定”当该人的订阅结束时,向哪个客户发送礼品卡(10 美元)(为了续订订阅,该公司有 100 美元的年费)。比如下面是一个“网购网站”的**过去**的用户数据名为“David”(26 岁)的用户在 19 天前进行了最后一次购买,并且在上个月登录过一次他的帐户。**
****
**来源:作者**
**在上表**中,我们看到了过去客户**的“数据”,其中列名“Churn”表示他们是否搅动(停止订阅)了服务(这里是订阅)(Churn=1)或没有搅动(Churn=0)。**
> **现在,给定这些数据,我们可以建立一个机器学习模型,它可以说,对于未来的任何一个人(看不见的数据),这个人流失的概率是多少?**
**从简单的 ML 角度来看,**
**x:功能栏(橙色栏)**
**y:输出列(绿色列)**
**建立了“预测模型”后,现在想象“在线购物网站”需要为三个客户决定他们的订阅即将结束,发送礼品卡以避免此人的“流失”。(他们只能给一个人送一张 10 美元的礼品卡)。**
**现在**要做的决定**是:**
> **在即将结束订阅的三位客户(James、Mohammad 和 Helen)中,我们需要向哪一位发送“礼品卡”以降低流失率?**
**我们使用我们的 ML 模型做出这个决定,将其应用于三个客户,并**要求 ML 预测,“此人流失的概率是多少”?****
**在下表中,您可以看到 ML 模型预测詹姆斯有 80%的概率**终止订阅**,穆罕默德有 60%,海伦有 40%。**
****
**来源:作者**
**根据 ML 模型的预测,有理由将“礼品卡”发送给 **James** ,因为他是最有可能退出订阅的客户。我认为这将是一个合乎逻辑的决定,因为我们试图将“礼品卡”发送给退出订阅的风险最高的人。**
> **然而,正如我将在下面概述的,上面的方法有一些缺陷(虽然看起来很合理),并导致做出“次优”决策。**
*****决策驱动法:*****
**在这一节中,**我想通过首先着手“决策”,然后收集数据来重新构建同一个业务问题**。在这种方法中,首先是“决策”,然后是支持最佳决策的相关“数据”。**
**作为一个经典的决策分析练习,对于任何“决策”制定过程,我们至少需要三个要素,在本例中:**
* ****替代品:****
**这里的选择是是否发送 10 美元的礼品卡给詹姆斯,穆罕默德,或海伦(三个选项)。**
* ****目标****
**目标是使组织的价值最大化(这里,给定 10 美元礼品卡的成本和 100 美元的持续订阅回报)**
* ****信息****
**我们需要这些信息来确定我们的客户是终止订阅还是继续订阅的概率。给定这三个元素,手头问题的**决策树**可以绘制如下:**
****
**来源:作者**
**给定备选方案、目标和信息,上述决策树是构建决策环境的起点。**决策驱动框架要求高质量决策所需的相关数据**。在这种情况下,**相关数据**为:**
> **假设顾客收到 10 美元的礼品卡,她终止订购的可能性有多大?**
**值得一提的是,*我们在决策驱动方法中需要的信息不同于数据驱动方法中需要的信息。*在决策驱动的方法中,这个问题的正确数据是**信息**,它给出了上述决策树中“p”的估计值。**
**组织可以通过实验获得这样的信息,比如 A/B 测试。你可以做的是,让 100 名顾客,随机给其中一半人购物卡(治疗组),另一半没有安迪购物卡(对照组),然后比较这个决定的“**效果**”。在下面的图表中,我展示了一篇“伟大”研究论文的[图,该论文阐述了这一分析](https://journals.sagepub.com/doi/pdf/10.1509/jmr.16.0163)。x 轴显示了离开订阅(R10)的风险“最高”的客户朝向最小(R1)的客户。在我们的例子中,我们可以假设詹姆士属于 R8,穆罕默德属于 R4,海伦属于 R2。**
****令人惊讶的是**我们可以看到,根据研究,终止订阅的概率几乎等于在续订信中赠送礼品卡而终止订阅的概率:**
**P(结束认购)≈ P(结束认购|领取礼品卡)**
****
**[来源](https://journals.sagepub.com/doi/pdf/10.1509/jmr.16.0163)**
**有了这些信息,现在我们可以写下决策树,这次是从上面的分析中找到的概率。**
****
**来源:作者**
**现在,定义了备选方案,提供了不确定性和目标评估的信息,我们可以根据每个选择的“预期结果”做出决策:**
****备选方案 1)向詹姆斯发送礼品卡:****
**EV = 0.8×(-10) + 0.2×(90) = 10**
****备选方案 2)向 Mohammad 发送礼品卡:****
**EV = 0.6×(-10) + 0.4×(90) = 30**
****备选方案 3)给海伦送一张礼品卡:****
**EV = 0.2×(-10) + 0.8×(90) = 54**
**如果我们遵循**“决策驱动”**方法,礼品卡应该发送给 **Helen** ,而在**“数据驱动”**方法中,这个人是 **James** 。那么,是什么改变了我们,让我们最终有了两个不同的行动,取决于方法,**
> **数据驱动的方法为错误的问题提供了一个完美的答案。决策驱动的方法从“正确的问题”开始,并试图利用相关数据来回答问题。**
****外卖信息:****
* **企业中的决策者、为客户 a 提供服务的顾问、做出经营决策的员工的目标都是创造价值,而价值只有通过“**高质量”**的决策才能实现。**
* **要做出“**高质量的决策,我们首先需要构建决策框架,识别其要素(备选方案、目标和不确定性),并根据预期回报最高的选择做出决策。****
* ******“决策驱动”**方法为制定**“高质量”**决策提供了一个框架。**“数据驱动”**通过**寻找数据的目的而不是使数据符合目的,决策制定可能导致次优决策。******
******最终注释**:****
****我想补充一下,我从[阅读这篇文章](https://sloanreview.mit.edu/article/leading-with-decision-driven-data-analytics/)中学到了很多。对于决策分析领域的深入研究,[这本书](https://www.amazon.com/Foundations-Decision-Analysis-Ronald-Howard/dp/0132336243)是你需要的。Reidar Bratvold 也有一本关于如何做出好的决定的好书[在这里](https://www.amazon.com/Making-Good-Decisions-Reidar-Bratvold/dp/1555632580)。此外,您可以关注 Cassie Kozyrkov([Cassie Kozyrkov](https://medium.com/u/2fccb851bb5e?source=post_page-----b753301b8d66--------------------------------)),了解更多关于[“决策智能”的信息。](https://medium.com/towards-data-science/introduction-to-decision-intelligence-5d147ddab767)****
****[1]“[缩小数据价值差距,](https://www.accenture.com/_acnmedia/pdf-108/accenture-closing-data-value-gap-fixed.pdf)”白皮书,埃森哲,都柏林,2019。****
****[2] [面向现代商业领袖的机器学习驱动的流失分析](/machine-learning-powered-churn-analysis-for-modern-day-business-leaders-ad2177e1cb0d)****
****[2]阿里·库比,你的标志性品牌的首席执行官:[https://tinyurl.com/bdh9uy2z](https://tinyurl.com/bdh9uy2z)****
# PandaSQL 简介:没人谈论的缺点
> 原文:<https://towardsdatascience.com/the-downsides-of-pandasql-that-no-one-talks-about-9b63c664bef4>
## 熊猫+ SQL = PandaSQL =一塌糊涂

由[约书亚·赫内](https://unsplash.com/@mrthetrain?utm_source=medium&utm_medium=referral)在 [Unsplash](https://unsplash.com?utm_source=medium&utm_medium=referral) 拍摄的照片
结构化查询语言(SQL)和 Pandas 无疑是数据科学家管理、处理和分析表格数据的首选工具。
虽然 Pandas 是数据科学家使用的用于数据分析的流行 Python 库,但 SQL 是其自身的完整编程语言,用于与跨越计算机科学各个领域的数据库进行交互。它们之间有一个突出的共同点,那就是它们都是处理表格数据的不可思议的工具。
PandaSQL 是一个流行的 python 包,它融合了 Pandas 和 SQL,允许您在 python 环境中利用 SQL 语法的强大功能。因此,PandaSQL 使您能够使用 SQL 语法查询 pandas 数据帧——对于不熟悉或不习惯 Pandas 语法的人来说,这是一个巨大的胜利。
这篇文章是对 PandaSQL 的介绍。我将演示如何在示例查询中使用 PandaSQL。最后,我将比较 Pandas 和 PandaSQL 的运行时差异。简要概述如下:
[**panda SQL**](#1289)[**panda SQL**](#ab40)的注意事项
你可以在这里找到这篇文章[的笔记本。](https://deepnote.com/workspace/avi-chawla-695b-aee6f4ef-2d50-4fb6-9ef2-20ee1022995a/project/PandaSQL-a196556e-7a37-433d-bd8f-beb19b838913/%2Fnotebook.ipynb)
我们开始吧🚀!
# PandaSQL 入门
如上所述,PandaSQL 是一个 python 库,它为您提供了在 Pandas 数据帧上执行 SQL 查询的灵活性。下面详细演示了实现这一点的逐步过程。
## 步骤 1:安装 PandaSQL
首先,使用`pip`安装 PandaSQL 库。你可以在这里找到说明[或者使用下面的命令来安装它:](https://pypi.org/project/pandasql/)
## 第二步:进口要求
接下来,我们导入上面安装的库和这个项目中需要的其他预安装的库。
## 步骤 3:创建虚拟数据集
为了理解如何在使用 PandaSQL 的 pythonic 环境中使用 SQL,我们将创建一个包含一万名雇员的虚拟数据集。以下代码后面的图像显示了数据集的一瞥。

数据帧的前五行(图片由作者提供)。
## 步骤 4: **创建 PandaSQL 环境**
下一步是设置 SQL 环境,如下所示:
我们创建一个 lambda 函数,它接受一个查询`q`和程序范围内的变量,使用`globals()`返回一个 python 字典。
本质上,SQL 查询在 Python 中被写成字符串。为了让 PandaSQL 解释字符串中指定的表名及其列名,我们使用`globals()`方法检索所有全局变量,并将其传递给定义的 lambda 函数。步骤 3 中定义的`data`数据帧可以使用`globals()`引用,如下所示:
## 步骤 5:在 Pandas 数据帧上运行 SQL 查询
一旦建立了 SQL 环境,就可以继续执行 SQL 查询。PandaSQL 使用的 SQL 语法与传统的 SQL 语法完全相同。
## 查询 1:
例如,让我们编写一个查询来计算数据帧中的记录数。下面演示了这一点:
## 问题 2:
接下来,如果您想基于某个条件查询数据帧,可以使用 SQL 中的`where`子句,如下所示:
## 问题 3:
最后,如果您想获得给定数据中每个组织对应的记录数,您可以使用`groupby`子句:
与我在上面三个示例查询中演示的类似,您可以编写自己选择的任何 SQL 查询,并使用 PandaSQL 库在 Pandas DataFrame 上执行它。
# PandaSQL 的警告
对于不熟悉 Pandas 要求的 pythonic 语法的 SQL 背景的人来说,PandaSQL 无疑是一个很好的选择。例如,在聚合多个列时,过滤数据帧或在特定列上对它们进行分组可能会让人感到有些不知所措或困惑。但是这些东西在 SQL 中很容易实现和解释。
然而,这种在 Pandas 中轻松利用 SQL 的方式带来了巨大的额外运行时成本。为了更好地理解这一点,我们来比较一下 PandaSQL 和 Pandas 的运行时。我们将用 SQL 编写一个查询,然后将运行时与其在 Pandas 中的相应实现进行比较。如果你不熟悉基本 SQL 查询到 Pandas 操作的翻译,我推荐你阅读我下面的帖子:
</translating-sql-queries-to-pandas-operations-2d27c354b8a2>
## 语法警告:
Python 已经有很多名字被保留为关键字,比如`for`、`while`、`in`、`if`、`else`、`elif`、`import`、`as`等。SQL 的引入引入了围绕变量命名的进一步限制,如更多的关键字,如`create`、`like`、`where`、`having`等。,不能再用作变量名。我在下面实现了这样一个场景:
## 执行运行时警告
虽然可以通过修改变量名来一次性处理语法警告,但运行时引入的开销却非常令人担忧。请考虑下面的问题,以便更好地理解。
## 查询 1:
首先,让我们比较一下计算数据帧中记录数量的运行时间。下面用 PandaSQL 和 Pandas 演示了这一点:
为了计算行数,PandaSQL 使用的运行时间比 pandas`shape`属性多近 t13 倍 t14 倍的 10⁵时间。
## **查询 2:**
接下来,让我们比较运行时间,找出给定数据帧中对应于每个组织的记录数。这在下面实现:
熊猫又一次以相当大的优势超过了 PandaSQL。在这种情况下,Pandas 比 PandaSQL 快 70 倍。
## 问题 3:
现在,我将演示基于使用 PandaSQL 和 Pandas 的条件过滤数据帧的运行时差异。SQL 查询及其对应的 Pandas 方法实现如下:
与基于 Pandas 的方法相比,PandaSQL 在过滤操作上花费了多 160 倍的时间。
## 问题 4:
最后,让我们考虑一下连接的运行时差异。我们将在给定的数据帧上实现自连接。下面演示了这一点:
然而,熊猫又一次成为了明显的赢家,它以 27 倍于 T21 的成绩超过了 PandaSQL。
总之,我同意 PandaSQL 是一个完美的工具,如果你对熊猫感到不舒服的话。然而,毫无疑问,这是**而不是**一个人应该期待在其数据管道中利用的长期解决方案。相反,花有意义的时间了解熊猫和它们相应的方法是一个人可以采取的最佳方式。
但是学习整个熊猫图书馆可能是具有挑战性的,不是吗?别担心。阅读我下面的博客开始吧。
</20-of-pandas-functions-that-data-scientists-use-80-of-the-time-a4ff1b694707>
感谢阅读。

作者在[imgflip.com](https://imgflip.com/)创造的模因
# 用 Python 创建交互式仪表盘的最简单方法
> 原文:<https://towardsdatascience.com/the-easiest-way-to-create-an-interactive-dashboard-in-python-77440f2511d1>
## **使用 hvPlot 将 Pandas 管道变成仪表板。互动**
由[索菲亚·杨](https://sophiamyang.medium.com/)和[马克·斯科夫·麦德森](https://medium.com/@marcskovmadsen)
本文将向您展示用 Python 从任何数据框架创建交互式仪表板的最简单方法。如果你已经知道一些熊猫,你几乎可以立即使用 [hvPlot](https://hvplot.holoviz.org/) 。交互式和[面板](https://panel.holoviz.org/)将您的数据帧处理流水线变成仪表板!只需几行熟悉的代码就可以制作这样一个交互式仪表板:

带 hvplot 的交互式数据框架仪表板。互动(图片由作者提供)
# **什么是 hvPlot?**
hvPlot 是由我的 Anaconda 同事 Philipp Rudiger、Jean-Luc Stevens 和 Jim Bednar 开发的。和大家熟悉的熊猫是一样的。plot() api,但是使用。hvplot()在 web 浏览器中提供丰富的交互式绘图。以我的经验来看,对于熊猫、Dask 和 XArray dataframes 来说,用 Python 创建交互式剧情是最简单的方法。hvPlot 是 HoloViz 生态系统中的七个库之一。如果你想了解更多关于 HoloViz 的知识,可以看看我之前关于[我为什么喜欢 HoloViz](/visualization-and-interactive-dashboard-in-python-c2f2a88b2ba3?sk=c78ed971426bbccb89798759779aa303) 的博文。
# 材料
* 为这篇文章检查我的 [Github](https://github.com/sophiamyang/hvplot_interactive) 回购。
* 查看活页夹上的笔记本和应用程序: [Jupyter 笔记本活页夹](https://mybinder.org/v2/gh/sophiamyang/hvplot_interactive/HEAD?filepath=hvplot_interactive.ipynb)、 [Jupyter 实验室活页夹](https://mybinder.org/v2/gh/sophiamyang/hvplot_interactive/HEAD?urlpath=lab/tree/hvplot_interactive.ipynb)、[面板应用程序](https://mybinder.org/v2/gh/sophiamyang/hvplot_interactive/HEAD?urlpath=panel)或 [Google Colab](https://colab.research.google.com/github/sophiamyang/hvplot_interactive/blob/HEAD/hvplot_interactive.ipynb)
# **设置**
让我们首先在命令行中安装一些包:
然后在您的 Python 文件或笔记本文件中,导入所需的模块:
**从熊猫开始**
让我们首先从熊猫的数据框架开始:

假设您想用下面的 Pandas 数据处理管道来处理这些数据:

如果我们想把`cyl`的值、`mfr`的值和变量`hp`变成我们可以改变和控制的交互式小部件呢?可能吗?是的,有了 hvPlot,这一点都不难。以下是步骤:
* 首先,我们需要用`.interactive()` : `idf = df.interactive()`包装我们的数据帧,这样这个数据帧就变得具有交互性,我们可以在这个数据帧上使用面板小部件。
> ".interactive 存储您的管道(数据上的一系列方法调用或其他表达式)的副本,并在小部件发生变化时动态重放管道。”
* 其次,我们可以定义我们想要使用的面板部件。这里我为圆柱体定义了一个面板部件,为制造商定义了一个部件,为选择 y 轴定义了一个部件。
* 最后,我们可以将原始 Pandas 管道中的值或变量替换为我们刚刚定义的这些小部件。我们将管道的输出定义为 ipipeline:
# **制作互动图和表格**
在绘图时,交互式数据框架 ipipeline 就像普通的熊猫数据框架一样工作。我们可以用正常的。情节方法,或者在这里我尝试了我最喜欢的情节方法。hvplot。神奇的是,我们的情节变得互动!

互动情节(图片由作者提供)
类似于熊猫数据框架,我们的交互式数据框架支持。管道方法,所以我们可以管道一个函数或类,比如`pn.widgets`。制表到这个数据框架中。结果显示一个交互式表格。

互动表格(图片由作者提供)
# **构建仪表板**
现在我们有了一个图、一个表和三个小部件,我们如何将它们排列到一个仪表板中呢?
在这里,我们可以使用`.panel()`从我们的交互管道中创建面板对象,然后使用面板按照我们喜欢的方式来安排事情。在这里,我们将把我们的图和表放入一个`pn.Column`对象,然后使用一个模板将小部件放入一个侧边栏来制作完整的仪表板:
# **部署仪表板**
要将这个仪表板作为 web 服务器启动,我们只需运行`panel serve hvplot_interactive.ipynb`,您的浏览器现在应该会打开一个选项卡,显示本文开头的仪表板。这就够了!
有关如何将仪表板部署到服务器的详细信息,请查看[面板文档](https://panel.holoviz.org/user_guide/Server_Deployment.html),或者我之前关于将仪表板部署到[谷歌云应用引擎](/deploy-a-python-visualization-panel-app-to-google-cloud-cafe558fe787?sk=98a75bd79e98cba241cc6711e6fc5be5)和[谷歌云运行](/deploy-a-python-visualization-panel-app-to-google-cloud-ii-416e487b44eb?sk=aac35055957ba95641a6947bbb436410)的文章。
# **推荐学习资源**
* 查看官方文档: [hvPlot。和 hvplot.holoviz.org 互动](https://holoviz.org/tutorial/Interactive_Pipelines.html?highlight=interactive)。
* Philipp Rudiger 展示了 hvPlot。今年 PyData 大会上的互动,下面是[视频](https://www.youtube.com/watch?v=-GcA0SEJaJM)。
* Marc Skov Madsen 有一个很好的使用 hvPlot .interactive 的例子。
希望你喜欢使用 hvPlot。互动!如果你有问题或者想联系其他 HoloViz 用户,请查看 https://discourse.holoviz.org/。
**确认**:
* 谢谢你的指导和支持!
* 谢谢你[西蒙·霍布罗·汉森](https://github.com/Hoxbro)为我们修复了一个 [bug](https://github.com/holoviz/hvplot/issues/697) 。我们非常感谢你的帮助!
**参考文献:**
[https://www.youtube.com/watch?v=-GcA0SEJaJM](https://www.youtube.com/watch?v=-GcA0SEJaJM)
[https://gist . github . com/MarcSkovMadsen/e 666503 df 2 aa 1d 8d 047 dcb 9555 b5 da 6d](https://gist.github.com/MarcSkovMadsen/e666503df2aa1d8d047dcb9555b5da6d)
[https://holoviz.org/tutorial/Interactive_Pipelines.html?高亮显示=互动](https://holoviz.org/tutorial/Interactive_Pipelines.html?highlight=interactive)
索菲亚·杨和马克·斯科夫·麦德森 2022 年 1 月 14 日
在[媒体](https://sophiamyang.medium.com/)、[推特](https://twitter.com/sophiamyang)、 [Linkedin](https://www.linkedin.com/in/sophiamyang/) 和 [YouTube](https://www.youtube.com/channel/UCruSa8hlUAa3aHQ189oOggQ) :)上关注我
# 2022 年部署你的机器学习模型最简单的方法:Streamlit + BentoML + DagsHub
> 原文:<https://towardsdatascience.com/the-easiest-way-to-deploy-your-ml-dl-models-in-2022-streamlit-bentoml-dagshub-ccf29c901dac>
## 将模型部署为具有用户友好界面的轻量级 API

作者图片
## 介绍
你有一个现成的机器学习模型。现在怎么办?你用它做什么?你会像珍藏一样把它藏在你的 Jupyter 里不让任何人看见吗?不,你让别人分享和玩你的作品变得尽可能简单。换句话说,您*部署*模型。
但是怎么做呢?您应该将模型作为文件共享吗?不,那是最糟糕的。
码头集装箱怎么样?是的,这样更好——用户可以在本地运行您的模型。但是……他们仍然需要在编码环境中进行。不太方便。
那么,API 呢?好吧,祝你向非程序员解释 API 时好运。
嘿,如果你建立一个网络应用程序呢?是的,这似乎是最好的选择。但是怎么建呢?不需要学习 web 框架吗?
好消息是——你不需要做上面的任何事情。在本文中,我将展示一种部署方法,它使您能够将您的模型作为 API、Docker 容器和托管的 web 应用程序来提供,所有这一切只需几分钟和几个简短的 Python 脚本。
听起来很棒?继续读。
<https://ibexorigin.medium.com/membership>
获得由强大的 AI-Alpha 信号选择和总结的最佳和最新的 ML 和 AI 论文:
<https://alphasignal.ai/?referrer=Bex>
## 我们在解决什么问题?
今天的部署方法适用于任何 ML/DL 框架的任何模型架构。但是,就像我们在过去两篇文章中所做的那样,我们将继续研究[宠物流行度数据集](https://www.kaggle.com/c/petfinder-pawpularity-score)。
Petfinder.my 数据集收集了猫和狗的图像数据集,并使用他们内部的评分算法给每只猫和狗打分。我们一直试图使用这个数据集来预测给定图像的宠物的可爱程度。

作者截图。宠物人气[比赛主页](https://www.kaggle.com/c/petfinder-pawpularity-score)。
该数据集用于在 Kaggle 上举办宠物流行度竞赛,希望顶级解决方案能够提高宠物收养率。
在第一篇文章的[中,我们对图像及其元数据进行了 EDA,并概述了我们解决问题的方法以及在此过程中使用的工具。](/open-source-ml-project-with-dagshub-improve-pet-adoption-with-machine-learning-1-e9403f8f7711)
[第二篇文章](/complete-guide-to-experiment-tracking-with-mlflow-and-dagshub-a0439479e0b9)是一个关于跟踪你的机器学习实验并找到预测可爱评分的最佳模型的综合教程。
最后一篇文章将展示如何将 Keras 图像回归模型部署为 API 和 web 应用程序,以使每个人、程序员和普通用户都可以访问它。
## 我们将使用什么工具来部署?
很难就为生产中的模型服务的最佳工具达成一致,因为每个问题都是独特的,并且它们的解决方案有不同的约束。
因此,我想选择一个解决方案或一套工具,让尽可能多的人受益。解决方案应该足够简单,只需要几分钟就可以完成一个工作原型,并在网上提供,如果需要,可以扩展到更大规模的问题。
这个解决方案的核心组件是 [BentoML 包](https://docs.bentoml.org/en/latest/)。它是 MLOps 领域最有前途的玩家之一,已经在 GitHub 上积累了 50 万次下载。
它的目的是用尽可能少的代码行将 ML 模型作为 API 端点,并且没有 Flask 等其他框架的麻烦。它适用于几乎所有的 ML 框架:

作者截图。 [BentoML 文档](https://docs.bentoml.org/en/latest/frameworks/index.html#frameworks-page) —接受的框架。
向前跳几步,您可以查看包含我们将在本文中构建的已部署 API 的链接[。](https://pet-pawpularity.herokuapp.com/)

图片由作者提供。加载服务器需要一分钟时间。
部署也不应该仅仅停留在 API 上。毕竟,API 只面向程序员,你也需要一些非编程社区也能与之交互的东西。这就是 Streamlit 的用武之地。
Streamlit 对您来说可能并不陌生,因为它已经成为为几乎任何类型的 ML 应用程序创建极简 web 应用程序的首选库。
由于我们在 API 的基础上构建了 Streamlit UI,web 应用程序将更加轻量级。您将不会有依赖性问题,因为您只需要`requests`库来通过 Streamlit 应用程序处理对 BentoML API 的请求。
下面,你可以看到我们将在本文中构建的[应用:](https://share.streamlit.io/bextuychiev/pet_pawpularity/ui/src/ui.py)

图片由作者提供。
最后但同样重要的是,我们将再次使用 [DagsHub](https://dagshub.com/) 来管理整个项目。DagsHub 是面向数据专业人士的 GitHub,允许你进行 360 度的机器学习。
您可以将 DagsHub 存储库用于许多任务:
* 托管代码:完全支持 Git(就像 GitHub 一样)。
* [存储器](https://dagshub.com/docs/reference/dagshub_storage/):有数据专用存储器&模型存储器,由 [DVC](https://dvc.org/) 管理
* [实验跟踪](https://dagshub.com/docs/reference/discovering_experiments/):支持 [MLflow 跟踪](https://dagshub.com/docs/reference/mlflow_tracking/)和 [Git 跟踪](https://dagshub.com/docs/reference/git-tracking/)。

图片由作者提供。[宠-paw popularity DagsHub 回购。](https://dagshub.com/BexTuychiev/pet_pawpularity)
我们在实验的第二部分中使用 DagsHub 最多:
</complete-guide-to-experiment-tracking-with-mlflow-and-dagshub-a0439479e0b9>
机器学习生命周期不仅仅是部署。一款车型要想在生产中获得成功,需要基础设施的坚实基础。DagsHub 允许你建立这个基础。
现在,让我们进入文章的中心部分,从解释如何使用 BentoML 为预测服务创建 API 端点开始。
## 第一步:将最佳模型保存到 BentoML 本地商店
> 本节所有代码片段摘自项目 repo — [training.py](https://dagshub.com/BexTuychiev/pet_pawpularity/src/main/src/training.py) 。
让我们从导入必要的库开始:
确保安装带有`--pre`标签的`bentoml`,因为它仍在预览中。
下面,我们将创建几个辅助函数来创建和训练 Keras 卷积模型:
我省略了第一个函数的主体,它创建了一个 Conv2D 实例,其中有三个隐藏层和中间的 dropout、MaxPool 层。我们不必太关注模型架构。
`fit_keras_conv2d`使用第一个函数,用提前停止和 30 个历元训练得到的模型。
接下来,我们创建一个函数来将模型保存到 BentoML 本地存储:
`keras.save`函数将 Keras 模型保存为适合其他 BentoML 操作的格式。
因此,让我们运行这些函数来获得一个现成的模型:
训练和保存完成后,您可以运行下面的命令来获取 BentoML 商店中的模型列表:
$ bentoml models list

作者 GIF
保存的模型在 BentoML 文档中正式称为*标签*。默认情况下,所有模型都将保存在您的主目录和带有随机标签的`bentoml/models`文件夹中,以防有多个模型同名。
如果您进入给定的路径,您将会找到如下文件:
您总是可以使用前面带有相关框架名称的`load_runner`函数加载回模型:
加载后,模型可以使用其`run`方法进行预测,该方法调用引擎罩下 Keras `Model`对象的`predict`方法。
## 步骤 2:创建服务
> 本节所有代码片段均取自项目 repo — [service.py](https://dagshub.com/BexTuychiev/pet_pawpularity/src/main/service.py) 。
现在,我们只需要几行代码就可以将保存的模型转换成一个有效的 API。
首先,我们编写一个函数来创建 BentoML 的[服务对象](https://docs.bentoml.org/en/latest/concepts/service_definition.html),它可以处理所有的 API 逻辑,而无需我们付出任何努力。
在用`load_runner`函数加载回模型之后,我们用一个任意的名字将它传递给`Service`方法。
之后,我们创建一个 API 端点来处理我们的 POST 请求。通过定义一个用我们刚刚创建的服务对象的`api`方法修饰的函数,可以在 BentoML 中创建端点:
在讨论车身之前,先说一下`service.api`装饰工。它有两个必需的参数- `input`和`output`。
您应该根据将从端点发送和返回的数据类型来定义这些参数。
当我们发送一个带有图像的请求时,上面的`predict`端点返回一个可爱分数。因此,我将输入定义为`Text()`,因为我们将把 NumPy 图像数组作为字符串发送。输出应该是`NumpyNdarray()`,因为当我们调用`model.run(image)`时,返回的数据类型将是一个 Numpy 数组。
为端点获取正确的数据类型非常重要。您可以阅读 BentoML 文档的本页,了解您可以处理的其他类型的数据。
至于主体,你应该在调用`model.run`之前把所有的预处理逻辑写到图像中。在训练之前,我将图像的大小调整为(224,224,3),并通过将它们的像素值除以 255 来归一化它们。所以,我也在端点函数中执行了这些步骤。
> 重要提示:如果您使用其他框架,比如 Sklearn,来处理表格数据,那么也要确保在 API 端点内部运行所有的预处理步骤。我们可以通过酸洗您的所有处理函数并在`predict`函数中调用它们来实现这一点,因此不会有任何数据泄漏或者您不会传递格式不正确的数据。
现在,要为我们的 API 启动一个调试服务器,您只需要将所有代码放入根目录下的一个 Python 文件中,通常命名为`service.py`,并调用下面的命令:
$ bentoml serve service.py:service --reload

作者 GIF
`--reload`标记确保本地服务器检测到对`service.py`的更改,并自动更新逻辑。
从 GIF 上可以看到服务器在 [http://127.0.0.1:3000/](http://127.0.0.1:3000/) 上直播,有一个简单的 UI:

作者 GIF
我们已经可以向本地服务器发送请求,并获得对图像的预测:
确保为您的数据类型设置正确的标题,并通过`str`功能发送打包的图像。同样,您可以从文档的[这一页](https://docs.bentoml.org/en/latest/concepts/api_io_descriptors.html#)中找到带有每种数据类型的正确内容头的请求示例。
我们来看看回复文字:
print(response.text)
[35.49753189086914]
我们发送的图像是这样的:

**图片来自**[**Pet paw popularity 数据集**](https://www.kaggle.com/competitions/petfinder-pawpularity-score/data) **。**
<https://ibexorigin.medium.com/membership>
## 第三步:做便当
现在,我们准备制作我们的第一份便当。
术语“便当”是指包含运行我们的在线服务或 API 的一切的档案,包括所有的代码、模型、依赖信息和设置配置。
构建它首先要在目录中创建一个与`service.py`文件相同级别的`bentofile.yaml`文件(最好两者都在项目根目录中):
YAML 文件的第一行应该包含服务文件名,后跟“:service”后缀。接下来,你添加所有需要的文件`service.py`文件工作没有错误(数据,助手脚本等)。).在这里,我只包括服务文件本身,因为我们没有在其中使用任何额外的脚本。
然后,在 Python 和包下,指定依赖项及其版本。如果你不确定版本,有一个我经常使用的有用的小软件包叫做`pipreqs`:
$ pip install pipreqs
$ pipreqs .
调用`pipreqs [path]`会创建一个`requirements.txt`文件,其中包含您导入的所有使用过的包以及它们在给定路径下的版本,如下所示:
列出依赖项后,只需要调用`bentoml build`:
$ bentoml build

作者图片
要查看您所有便当的列表,请拨打`bentoml list`
$ bentoml list

作者图片
## 步骤 4:部署到 Heroku
`build`命令在本地商店保存一份新鲜的便当,其树形结构如下:
您可以从[本页](https://docs.bentoml.org/en/latest/concepts/building_bentos.html#building-bentos)中了解这些子文件夹的功能。我们感兴趣的文件夹是`env/docker`那个。它包含了构建一个全功能 Docker 容器所需的一切,我们将使用它来在线部署我们的 API。
这有很多选择,像亚马逊 EC 或谷歌云平台,但 Heroku 是最省事的平台。
Heroku 是一个流行的云应用程序平台,支持任何语言的开发人员构建和维护云应用程序。如果您还没有,请[创建一个帐户](https://signup.heroku.com/)并[下载 CLI](https://devcenter.heroku.com/articles/heroku-cli#install-the-heroku-cli) ,您可以使用它来创建和管理您的 Heroku 应用程序。
安装后,调用`login`来验证您的终端会话:
$ heroku login
这将在浏览器中打开一个选项卡,您可以在其中使用您的凭据登录。接下来,登录到容器注册表:
$ heroku container:login
现在,让我们创建一个名为`pat-pawpularity`的应用程序:
$ heroku create pet-pawpularity
之后,该应用程序应该可以在[https://dashboard.heroku.com/apps:](https://dashboard.heroku.com/apps:)看到

作者图片
现在,我们需要将我们的便当推送到这个应用程序,并在线部署它。为此,我们需要`cd`进入便当目录(可以通过`bentoml list`找到)和`docker`文件夹:
$ cd ~/bentoml/bentos/keras_conv2d_smaller_service/uaaub3v3cku3ejcl
$ cd env/docker
从那里,您调用这个命令:
$ heroku container:push web --app pet-pawpularity --context-path=../..
根据归档文件的大小,该命令将需要几分钟才能完成。
最后,您可以使用下面的命令发布应用程序:
$ heroku container:release web --app pet-pawpularity
现在,你可以去[https://pet-pawpularity.herokuapp.com/](https://pet-pawpularity.herokuapp.com/)在线查看 API,或者去你仪表盘上的应用页面打开它:

作者图片
现在,任何人都可以向这个 API 发送请求。让我们试试:
## 步骤 5:用 Streamlit 构建一个简单的 UI
> 本节所有代码片段均取自项目 repo — [ui.py](https://dagshub.com/BexTuychiev/pet_pawpularity/src/main/src/ui.py) 。
现在,让我们围绕我们的 API 构建一个轻量级用户界面。首先,我们将为我们的应用程序编写一个简单的标题部分,其中包含一个任意的封面图片:
接下来,我们定义核心功能。我们将创建一个函数,通过向我们的 API 发送请求来生成可爱度分数:
上传到 Streamlit 应用程序的图像将具有“BytesIO”格式,因此我们需要首先将它们转换为 NumPy 数组。第 6–7 行完成了这一点,剩下的就不言自明了。
现在,我们创建两个图像输入组件—一个用于文件上传,另一个用于网络摄像头输入:
使用时,这两个组件将显示一个简单的待机动画,然后返回一个可爱评分。这是我们正在运行的应用程序:

作者 GIF
现在,在你将这些改变推送到 GitHub 之后,你可以通过去[https://share.streamlit.io/deploy:](https://share.streamlit.io/deploy:)在线部署你的应用

图片由作者提供。
以下是已部署应用的链接:[https://share . streamlit . io/bextuychiev/pet _ paw pularity/ui/src/ui . py](https://share.streamlit.io/bextuychiev/pet_pawpularity/ui/src/ui.py)
## 结论
恭喜你!您刚刚构建了一个完整的图像应用程序,它为日常用户提供了一个非常棒的 UI,并为您的程序员朋友或队友提供了自己的 API。现在,您有了一种可靠的方式来与其他人共享您的模型,而不必担心环境设置和代码。
感谢您的阅读!
<https://ibexorigin.medium.com/membership> <https://ibexorigin.medium.com/subscribe>
## 也可以随意查看这些内容:
</open-source-ml-project-with-dagshub-improve-pet-adoption-with-machine-learning-1-e9403f8f7711> </complete-guide-to-experiment-tracking-with-mlflow-and-dagshub-a0439479e0b9> </3-best-often-better-alternatives-to-histograms-61ddaec05305> </comprehensive-guide-to-writing-python-functions-others-can-use-2fa186c6be71>
# 使用 N 拍预测时间序列的最简单方法
> 原文:<https://towardsdatascience.com/the-easiest-way-to-forecast-time-series-using-n-beats-d778fcc2ba60>
## 从理论到实践,了解 N-BEATS 的工作原理,并使用 Python 将其应用到实际预测项目中

在 [Unsplash](https://unsplash.com?utm_source=medium&utm_medium=referral) 由 [Pablo de la Fuente](https://unsplash.com/@pablodelafuente?utm_source=medium&utm_medium=referral) 拍摄的照片
如果你和我一样,对时间序列预测感兴趣,很可能你偶然发现了 N-BEATS 模型。该模型承诺使用纯深度学习架构获得最先进的结果。换句话说,它不需要时间序列的特定成分,如趋势或季节性。
你可能读过 Oreshkin 等人写的关于 N-BEATS 的 [2020 论文](https://arxiv.org/pdf/1905.10437.pdf)。虽然这篇论文信息量很大,但它并不容易阅读,你在这里可能意味着你同意我的观点。
所以,在这篇文章中,我将首先使用更多的直觉和更少的等式来解释 N-BEATS。然后,我将使用 Python 将它应用于现实生活中的预测场景,并评估它的性能。
我们开始吧!
> ***用 Python 中我的*** [***免费时间序列小抄***](https://www.datasciencewithmarco.com/pl/2147608294) ***学习最新的时间序列分析技巧!获得统计和深度学习技术的实现,全部在 Python 和 TensorFlow 中!***
# 理解 N 节拍
N-BEATS 代表**N**eural**B**as**E**x expansion**A**analys 代表**I**N**T**ime**S**系列。
顾名思义,N-BEATS 的核心功能在于**基础扩展**。因此,在深入模型的架构之前,让我们首先澄清什么是基础扩展。
## 基础扩展
基础扩展是一种扩充数据的方法。这通常是为了模拟非线性关系。
常见的基展开是多项式基展开。例如,假设我们只有两个特性,如下所示。

一组两个特征。图片由作者提供。
然后,如果我们进行 2 次多项式基展开,我们的特征集变成:

特征集上 2 次多项式基展开的结果。我们注意到,我们只是简单地将现有特征的平方相加。这允许我们拟合二次模型,以便我们可以捕捉非线性关系。图片由作者提供。
如您所见,2 次多项式基展开的结果是我们简单地将我们的特征的平方添加到特征集中。
因此,这意味着我们现在可以用二次多项式模型来拟合我们的数据,有效地模拟非线性关系!
当您对数据进行线性趋势或多项式曲线拟合时,这基本上就是在 Excel 中发生的事情。

基础扩展前(左)和基础扩展后(右)。在左边,我们停留在线性模型上,但是添加特征的平方允许我们有一个更适合的非线性模型。图片由作者提供。
看上面的图,我们可以看到,当我们不进行基展开时,我们只有一条直线,如左图所示。然而,在右边,一旦我们执行了 2 次多项式基展开,我们就得到一个二次模型,它与我们的数据更加吻合。
当然,基展开并不限于多项式;我们可以计算对数、幂等。主要的收获是,基础扩展用于增加我们的特征集,以便对非线性关系建模。
在 N 拍的情况下,基展开不是我们定的。取而代之的是,该模型被训练来寻找最佳的基展开方法,以便拟合数据并进行预测。换句话说,我们让神经网络找到最佳的数据扩充方法来拟合我们的数据集,因此得名:神经基础扩展。
现在我们已经熟悉了基础扩展的概念,让我们继续讨论模型的架构。
## **N 拍的架构**
在设计 N-BEATS 的架构时,有三个关键原则:
1. 基础架构应该简单、通用,但富有表现力
2. 该架构不应依赖于特定于时间序列的组件(如趋势或季节性)
3. 该架构是可扩展的,以使输出可解释
基于这些考虑,N-BEATS 的创造者设计了这样一个模型:

N 拍的架构。图片由 B. Oreshkin、D. Carpov、N.Chapados 和 Y. Bengio 拍摄,来自 [N-BEATS:可解释时间序列预测的神经基础扩展分析](https://arxiv.org/pdf/1905.10437.pdf)
从上图可以吸收很多信息,一步一步来。
从图的右上方看,我们可以看到一个时间序列分为回顾期和预测期。回望期提供给模型,而预测期包含允许我们评估模型预测的实际值。
请注意,输入序列的长度是预测长度的倍数。因此,对于长度为 *H* 的预测范围,输入序列通常应该具有从 2 *H* 到 6 *H* 的长度。
然后在上图中从右到左,我们看到 N-BEATS(右边黄色矩形)是由分层的*栈*组成的,这些栈本身又是由*块*(中间橙色矩形)组成的,我们可以看到每个*块*是如何构造的(左边蓝色矩形)。
我们可以看到一个*块*由四个完全连接的层组成。这个网络产生两样东西:一个预测和一个反向预测。预测只是对未来值的预测,而反向预测是来自模型的值,我们可以立即将其与输入序列进行比较,并评估模型的拟合度。
注意,网络在*块*级找到扩展系数(在图中表示为*θ*),然后执行基扩展(在图中表示为函数 *g* )。
在这种架构中,只有第一个*模块*获得实际的输入序列。随后的*块*获得来自第一*块*的残差。这意味着只有未被第一个*模块*捕获的信息被传递到下一个模块。
这导致输入序列的顺序处理,其中每个*模块*试图捕捉前一个模块遗漏的信息。
将不同的*块*组合在一起,然后给我们一个*堆栈*,它输出一个部分预测。然后,我们将更多的*堆栈*添加到模型中,并且每个*堆栈*将输出其部分预测。然后,每个部分预测的组合产生最终预测。
## 使模型可解释
在这一点上,我们理解了 N-BEATS 的内部工作原理,但是这个模型究竟如何解释呢?
现在,它不是。负责基扩展的函数,在图中表示为 *g* ,是一个可学习的函数。这意味着我们让神经网络设计一个特定于问题的函数来获得最佳结果。
然而,将函数 *g* 限制在我们能理解的范围内是可能的。在时间序列预测中,我们经常使用趋势和季节性等元素来通知我们的预测,我们可以强制函数 *g* 来表示趋势分量或季节性分量。
为了表示趋势,我们使用多项式基。为了表示季节性,我们使用傅立叶基础。
因此,在该架构的可解释版本中,我们强制模型只有两个堆栈:一个堆栈专门用于预测趋势组件,另一个专门用于预测季节组件。然后,每个预测被组合以形成最终输出。
通用架构和可解释架构之间的区别如下所示。

N-BEATS 的通用架构和可解释架构之间的差异。在左边,通用架构有我们想要的那么多栈,但是我们失去了可解释性。在右边,我们强制模型只有两个堆栈,代价是可能会降低性能。图片由作者提供。
## 包扎
总结一下,N-BEATS 有两种配置。通用配置允许模型找到针对我们的问题的最佳基本展开。可解释的配置迫使一个堆栈专门预测趋势,另一个堆栈专门预测季节性。
网络中的剩余连接允许模型捕捉被先前块遗漏的信息。最后,将每个堆栈的部分预测的组合进行组合,以获得最终预测。
我希望我设法让 N 拍相当容易理解。现在,让我们继续在使用 Python 的预测项目中实际应用 N-BEATS。
# 使用 N 节拍进行预测
我们现在准备在预测项目中应用 N-BEATS 模型。在这里,我们将预测每小时 94 号州际公路西行交通量。注意,我们只使用了 UCI 机器学习知识库上的[完整数据集](https://archive.ics.uci.edu/ml/datasets/Metro+Interstate+Traffic+Volume)的一个样本,该样本由明尼苏达州交通部好心提供。
我们将在这个项目中使用 Darts 库,因为它使得在时间序列应用中应用最先进的模型(如 N-BEATS)变得非常容易。
所有代码都是 Python 语言,你可以在 [GitHub](https://github.com/marcopeix/time-series-analysis/blob/master/NBEATS.ipynb) 上获得完整的源代码和数据集。
我们走吧!
## 读取数据
当然,每个项目都从导入必要的库开始。
import pandas as pd
import numpy as np
import datetime
import matplotlib.pyplot as plt
from darts import TimeSeries
import warnings
warnings.filterwarnings('ignore')
然后,我们实际上读取我们的数据,并将其存储在数据帧中。
df = pd.read_csv('data/daily_traffic.csv')
由于我们使用的是 dart,我们将从 DataFrame 转到 TimeSeries 对象,这是 dart 中的基本对象。Darts 中的每个模型都必须有一个 TimeSeries 对象作为输入,它还输出一个 TimeSeries 对象。
series = TimeSeries.from_dataframe(df, time_col='date_time')
现在,我们可以使用`plot`方法轻松地可视化我们的数据。
series.plot()

每小时 94 号州际公路西行交通量。我们已经可以看到每日的季节性和每周的季节性。图片由作者提供。
看上面的图,我们已经发现我们有两个季节周期:每周和每天。很明显,白天路上的车比晚上多,工作日的车比周末多。
这实际上可以用飞镖来验证。它带有一个`check_seasonality`函数,可以告诉我们一个季节周期是否具有统计意义。
在这种情况下,因为我们有每小时的数据,所以每日季节性的周期为 24(一天中的 24 小时),每周季节性的周期为 168(一周中的 24*7 小时)。
所以,让我们确保这两个季节都很重要。
from darts.utils.statistics import check_seasonality
is_daily_seasonal, daily_period = check_seasonality(series, m=24, max_lag=400, alpha=0.05)
is_weekly_seasonal, weekly_period = check_seasonality(series, m=168, max_lag=400, alpha=0.05)
print(f'Daily seasonality: {is_daily_seasonal} - period = {daily_period}')
print(f'Weekly seasonality: {is_weekly_seasonal} - period = {weekly_period}')
上面的代码块将打印出两个季节周期都是重要的,稍后我们将如何对该信息进行编码以将其输入到我们的模型中。
## 拆分数据
预测项目中的一个自然步骤,将我们的数据分成训练集和测试集。在这种情况下,我们为测试集保留最近五天的数据,并将其余数据用于训练。
train, test = series[:-120], series[-120:]
train.plot(label='train')
test.plot(label='test')

训练/测试分割了我们的数据。最后五天用于测试集。图片由作者提供。
## 基线模型
在使用 N-BEATS 之前,最好先有一个基线模型。这是一个简单的模型,作为确定更复杂的模型是否更好的基准。
基线模型通常依赖于简单的统计或简单的启发式。在这种情况下,一种简单的预测方法是简单地重复上一个季节。在这里,由于我们有两个季节性周期,我们将使用每周季节性,以考虑周末的交通量较低。
from darts.models.forecasting.baselines import NaiveSeasonal
naive_seasonal = NaiveSeasonal(K=168)
naive_seasonal.fit(train)
pred_naive = naive_seasonal.predict(120)
在上面的代码块中,我们简单地获取了训练集中最后一周的数据,并在将来重复它。当然,由于我们的预测范围只有五天而不是七天,我们在第五天截断了预测。
下面,我们可以看到来自基线模型的预测。
test.plot(label='test')
pred_naive.plot(label='Baseline')

来自基线模型的预测。图片由作者提供。
然后,我们使用平均绝对误差(MAE)来评估基线的性能。
from darts.metrics import mae
naive_mae = mae(test, pred_naive)
print(naive_mae)
这给了我们一个 249 的 MAE,这就是我们试图用 N 拍来打破的分数。
## 无协变量的 n 拍
我们最终达到了应用 N 拍来解决问题的地步。
我们知道我们有两个季节周期,但是让我们在不给出信息的情况下尝试 N-BEATS。在我们帮助它之前,我们将让模型自己工作。
我们从导入 N-BEATS 和数据缩放器开始,以加速模型的训练。
from darts.models import NBEATSModel
from darts.dataprocessing.transformers import Scaler
然后,我们在 1 和 0 之间调整数据。请注意,我们只在训练集上安装了缩放器,因为模型不应该有来自测试集的信息。
train_scaler = Scaler()
scaled_train = train_scaler.fit_transform(train)
然后,我们初始化 N 拍模型。输入长度将包含一整周的数据,模型将输出 24 小时的数据。在这种情况下,我们使用通用架构。
nbeats = NBEATSModel(
input_chunk_length=168,
output_chunk_length=24,
generic_architecture=True,
random_state=42)
现在,我们简单地在缩放的训练集上拟合模型。
nbeats.fit(
scaled_train,
epochs=50)
一旦模型完成训练,我们就可以在测试集的范围内进行预测。当然,预测也是成比例的,所以我们需要反向转换。
scaled_pred_nbeats = nbeats.predict(n=120)
pred_nbeats = train_scaler.inverse_transform(scaled_pred_nbeats)
最后,我们评估了 N-BEATS 的性能。
mae_nbeats = mae(test, pred_nbeats)
print(mae_nbeats)
这给出了 MAE 为 292,高于基线。这意味着 N-BEATS 的表现并不比我们天真的预测要好。
因此,让我们将协变量添加到模型中,看看我们是否可以改善它的性能。
## 有协变量的 n 拍
在本文的前面,我们确定了在我们的时间序列中有两个重要的季节周期。我们可以对这些信息进行编码,并将其作为协变量传递给模型。
换句话说,我们向模型添加了两个特性,告诉它我们在一天和一周中的位置。通过这种方式,模型了解到周末的交通流量较低,并且夜间的交通流量低于白天。
飞镖很方便地带有一个,使用`datetime_attribute_timeseries`很容易实现这一点。
from darts import concatenate
from darts.utils.timeseries_generation import datetime_attribute_timeseries as dt_attr
cov = concatenate(
[dt_attr(series.time_index, 'day', dtype=np.float32), dt_attr(series.time_index, 'week', dtype=np.float32)],
axis='component'
)
然后,我们也对协变量进行缩放,将其输入到模型中。
cov_scaler = Scaler()
scaled_cov = cov_scaler.fit_transform(cov)
请注意,我们不需要将协变量分割成训练集和测试集,因为 Darts 会在训练过程中自动进行适当的分割。
现在,我们重复初始化 N 拍和拟合的过程。这一次,我们也传递协变量。
nbeats_cov = NBEATSModel(
input_chunk_length=168,
output_chunk_length=24,
generic_architecture=True,
random_state=42)
nbeats_cov.fit(
scaled_train,
past_covariates=scaled_cov,
epochs=50
)
一旦模型被训练,我们就产生预测。记住再次反转变换,因为预测在 0 和 1 之间缩放。
scaled_pred_nbeats_cov = nbeats_cov.predict(past_covariates=scaled_cov, n=120)
pred_nbeats_cov = train_scaler.inverse_transform(scaled_pred_nbeats_cov)
我们也可以用下面的代码块来可视化我们的预测。
test.plot(label='test')
pred_nbeats.plot(label='N-BEATS')

来自 N 拍的预测。图片由作者提供。
同样,我们使用 MAE 评估模型的性能。
mae_nbeats_cov = mae(test, pred_nbeats_cov)
print(mae_nbeats_cov)
这给了我们一个 288 的 MAE。这比不使用协变量要好,但仍然比基线模型差。

每个模型预测的平均绝对误差。我们看到,添加协变量有助于模型,但其性能仍然比基线差。图片由作者提供。
**对结果的说明**
获得的结果并不令人兴奋,但要有所保留。请记住,我们正在处理一个相当小而简单的数据集。这可能是因为我从[完整数据集](https://archive.ics.uci.edu/ml/datasets/Metro+Interstate+Traffic+Volume)中提取的样本本质上只是重复性的,这解释了为什么基线如此之好。
尽管如此,您现在已经知道如何在预测项目中实施 N-BEATS,并且您还可以体会到拥有基线模型的重要性。
# 结论
N-BEATS 是一个最先进的深度学习模型,用于时间序列预测,它依赖于基础扩展的原则。该模型可以学习特定问题的基础扩展功能,或者我们可以限制它们具有可解释的输出。
我希望你喜欢这本书,并且你学到了新的东西!
干杯🍺
# 用 Python 识别假日的最简单方法
> 原文:<https://towardsdatascience.com/the-easiest-way-to-identify-holidays-in-python-58333176af4f>

照片由[esteée 扬森斯](https://unsplash.com/@esteejanssens?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText)在 [Unsplash](https://unsplash.com/s/photos/calendar?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText) 上拍摄
# 用 Python 识别假日的最简单方法
## 如何快速将假期要素添加到数据集中
当处理时间数据时,无论是时间序列分析还是正常的回归/分类任务,知道某一天是否是某种假日都会让我们受益匪浅。
例如,如果我们是一个流媒体平台,我们可能会注意到用户活动在休息日出现高峰。作为一名零售商,我们可能会注意到假期前(尤其是与礼物相关的,如圣诞节)的购物量比假期中多。这些只是首先想到的一些想法。
这就是为什么在处理时间数据时识别节假日非常有用的原因。在本文中,我们将探索如何使用两个流行的 Python 库— `holidays`和`workalendar`快速完成这项工作。两者在 GitHub 上都相当受欢迎(~650 颗星),并且仍然由它们的创作者维护。让我们开始吧!
# 快速设置
像往常一样,我们需要加载一些库。在这个例子中,我们将看看德国的节日。这就是为什么我们从`workalendar`库做了一个特殊的导入。
# 1.假日
`holidays`图书馆允许我们识别大约 90 个国家的主要节日的日期。此外,在某些情况下(如美国、巴西、法国、加拿大等),甚至可以更深入地了解特定地区的假日。
我们已经提到,在这个例子中,我们将看看德国的假期。从`holidays`图书馆检索假日信息非常简单,您马上就会看到。使用下面的片段,我们打印 2020-2021 年的所有德国假日。
这将返回以下列表:
(datetime.date(2020, 1, 1), 'Neujahr')
(datetime.date(2020, 4, 10), 'Karfreitag')
(datetime.date(2020, 4, 13), 'Ostermontag')
(datetime.date(2020, 5, 1), 'Erster Mai')
(datetime.date(2020, 5, 21), 'Christi Himmelfahrt') (datetime.date(2020, 6, 1), 'Pfingstmontag')
(datetime.date(2020, 10, 3), 'Tag der Deutschen Einheit') (datetime.date(2020, 10, 31), 'Reformationstag') (datetime.date(2020, 12, 25), 'Erster Weihnachtstag') (datetime.date(2020, 12, 26), 'Zweiter Weihnachtstag') (datetime.date(2021, 1, 1), 'Neujahr')
(datetime.date(2021, 4, 2), 'Karfreitag')
(datetime.date(2021, 4, 5), 'Ostermontag')
(datetime.date(2021, 5, 1), 'Erster Mai')
(datetime.date(2021, 5, 13), 'Christi Himmelfahrt') (datetime.date(2021, 5, 24), 'Pfingstmontag')
(datetime.date(2021, 10, 3), 'Tag der Deutschen Einheit') (datetime.date(2021, 10, 31), 'Reformationstag') (datetime.date(2021, 12, 25), 'Erster Weihnachtstag') (datetime.date(2021, 12, 26), 'Zweiter Weihnachtstag')
出于我们的目的,将该信息存储在`pandas`数据帧中可能更容易。通过稍微修改上面的代码片段,我们得到了想要的结果:

作者形象
我们已经看到了如何获取给定时间和国家的假期列表。该库的另一个有用的特性是检查给定的日期是否是假日。这样,我们可以很容易地为我们的模型/分析创建布尔特征。
de_holidays = holidays.Germany(years=[2020, 2021])"2021-12-26" in de_holidays
运行上面的代码片段会返回一个`True`。使用列表理解,我们可以快速地将相同的逻辑应用于整个日期列。

作者形象
*趣闻*:库中有一些小而有趣的不一致。对于绝大多数国家,我们需要使用`holidays.country_name`,就像我们已经对德国所做的那样。但是,也有一些像波兰这样的边缘案例。为了得到波兰假期,我们必须使用`holidays.Polish`。没什么大不了的,但我发现为什么会这样很有趣。
# 2.工作日历
我们今天介绍的第二个库是`workalendar`,它类似于`holidays`,提供了识别大约 80 个国家(其中一些包括地区)的假日的可能性。
我们从下载 2020 年的德国假期开始。与`holidays`相反,我们必须一年一年地工作。

作者形象
我们可以很容易地发现两个库的输出之间有两点不同。首先,`workalendar`的节日名称是英文的,而在`holidays`是当地语言。第二,`workalendar`将德国 2020 年的假期确定为少一天——Reformation Day/Reformationstag(2020–10–31)。根据对维基百科的快速浏览,这可能是因为今天是休息日,但不是在德国的所有地区。
作为下一步,我们还可以检查任何日期是否是假日。为此,我们使用实例化日历对象的`is_working_day`方法。
de_calendar.is_working_day(date(2020, 1, 1))
答案是`False`。`workalendar`有一些`holidays`中没有的更有用的功能。首先,我们可以使用`add_working_days`方法轻松地将工作(业务)日期添加到任何日期。
de_calendar.add_working_days(date(2020, 12, 24), 5)
它返回
datetime.date(2021, 1, 4)
其次,我们可以很容易地得到两个日期之间的工作天数。
de_calendar.get_working_days_delta(date(2021, 1, 1), date(2021, 1, 31))# Answer: 20
该库还包含一些其他有趣的功能,例如:
* 获取可变日期假期(`get_variable_days`),
* 获取一年中特定假日的日期(例如,`get_ascension_thursday`),
* 得到一个月的最后一个工作日(`get_last_weekday_in_month`)。
有趣的事实:一些日历可能需要天文计算(例如,亚洲日历需要春分和节气)。在这种情况下,`workalendar`提供 1991-2051 年的预计算值。
# 外卖食品
* 使用`holidays`或`workalendar`,我们可以很容易地计算出许多国家的假日日期,
* 我们可以使用这些信息来创建机器学习模型或探索性分析的特征。
您可以在我的 [GitHub](https://github.com/erykml/medium_articles/blob/master/Time%20Series/holidays.ipynb) 上找到本文使用的代码。此外,欢迎任何建设性的反馈。你可以在[推特](https://twitter.com/erykml1?source=post_page---------------------------)或评论中联系我。
喜欢这篇文章吗?成为一个媒介成员,通过无限制的阅读继续学习。如果你使用[这个链接](https://eryk-lewinson.medium.com/membership)成为会员,你将支持我,而不需要额外的费用。提前感谢,再见!
您可能还会对以下内容感兴趣:
</8-more-useful-pandas-functionalities-for-your-analyses-ef87dcfe5d74> </introduction-to-hierarchical-time-series-forecasting-part-ii-e73dfd3de86b> </linkedins-response-to-prophet-silverkite-and-greykite-4fd0131f64cb>
# 参考
* [https://github.com/dr-prodigy/python-holidays](https://github.com/dr-prodigy/python-holidays)
* [https://github.com/workalendar/workalendar](https://github.com/workalendar/workalendar)
# 将数据导入 BigQuery 的最简单方法
> 原文:<https://towardsdatascience.com/the-easiest-way-to-ingest-data-into-bigquery-a94e63d4846e>
## 如何使用 Google Sheets 将数据直接加载到 BigQuery 中——以及为什么它是某些用例的最佳解决方案

巴勃罗·阿罗约在 [Unsplash](https://unsplash.com/?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText) 上的照片
当在一家公司谈论数据管理时,首先浮现在脑海中的是诸如“数据架构”、“数据工程管道”、“数据质量检查”之类的关键词……简而言之,围绕着在整个组织中流动的数据 **的**结构化的概念**。事实上,所有关于数据管理的最佳实践都依赖于这样一个假设,即我们应该将大数据构建到特定的架构中。我同意,而且我肯定会建议任何人,只要他们属于一个组织,就应该构建一个干净可靠的架构。**
然而,我发现**有时候最微不足道的解决方案最终会成为最好的解决方案**。这也适用于数据架构。这就是为什么**使用 Google Sheets 将数据注入到您的数据仓库 BigQuery** 有时会很有用。虽然它不应该作为获取数据的主要方式,但它提供了某些优势。
在这篇文章中,我想涵盖三个方面:
1. 为什么应该使用 Google Sheets 将数据导入 BigQuery?
2. 怎么做呢?
3. 这样做时应该采取什么预防措施?
为了说明我的想法,让我们考虑在您的数据仓库中有一个名为“销售人员”的表。它列出了销售部门的成员(每人一行)。这张桌子看起来像这样:

BigQuery 中的输入表(图片由作者提供)
您面临的挑战是,一个业务用户(在我们的例子中是销售主管)定期更新他们团队的组成。例如,尼克最近改变了团队:他不再是蓝队的一员,但他现在是红队的一员。你将如何更新这条信息?
# 为什么使用 Google Sheets?
**添加类似“team _ name”**的字段的通常流程是在任何[数据架构](/modern-or-not-what-is-a-data-stack-e6e09e74ae7f)的数据转换步骤中直接更新它。根据您公司的组织,数据工程师、分析工程师甚至数据分析师都可以在“员工”表中进行修改。

Google Sheets 中的输入表格(图片由作者提供)
然而**完成整个流程**可能需要几天时间,而添加“团队名称”列的需求可能很迫切。此外,这可能是一个准时的需求:添加员工的团队名称可能只与一个人或一个特定的分析相关。如果它没有为整个组织增加多少价值,那么经历整个数据工程过程可能不值得。
这就是使用 Google Sheets 及其与 BigQuery 的本机集成变得相关的地方。**第一个优势是灵活性**。在我们的示例中,如果销售主管改变了主意,Nick 将转到黄色团队而不是红色团队,那么可以通过更改 Google Sheets 中相关单元格的值来轻松完成这一更改。随着灵活性而来的是**快速**。即使不能立即更新,Google Sheets 文件中的更新也可以在几分钟内出现在相应的 BigQuery 表中。
# 如何将 Google Sheets 中的一个表摄取到 BigQuery 中?
Google Sheets 和 BigQuery 之间的原生集成允许**将一个工作表的内容直接链接到一个数据库表**。这是一个实时连接,这意味着您不必下载 Google Sheets 文件,然后在每次发生更改时手动上传到 BigQuery。
相反,转到 BigQuery 中的数据集,然后**单击“创建表”**。这将打开以下面板,您可以在其中完成:
* 用作源的 Google Sheets 文件的 URL
* 如果文件中有多张工作表,则为工作表范围
* 目标(项目、数据集、输出表的名称)
在“模式”部分,您有三种选择:
1. “自动检测”让 BigQuery 自动推断导入表的模式
2. “作为文本编辑”允许您以 JSON 的形式写下表的模式
3. “+”允许您直接在 BigQuery 的界面中添加每个字段及其特性(类型、模式、描述)
最后,您可以让 BigQuery 跳过“高级选项”中的标题行。在我们的示例中,我将“1”放在该字段中,因为我们希望忽略第一行(“employee_id”、“team_name”)。

将 Google Sheets 中的表格导入 BigQuery(图片由作者提供)
一旦完成,您的工作表就可以在 BigQuery 中使用了!这允许**编写整合来自 BigQuery 和 Google Sheets 文件**的数据的查询。
回到我们前面的例子,导入 Google Sheets 文件允许我编写下面的查询,其中我协调来自我的数据仓库(表“salespersons”)和来自我的电子表格(表“salespersons_teams”)的数据。
这导致了下面的输出表:

BigQuery 中的输出表(图片由作者提供)
# 你应该在什么时候使用这个技巧?什么时候不呢?
在我们的例子中,一个人(销售主管)将负责更新 Google-Sheets 文件。只要情况保持不变,前面提到的所有优点都适用:灵活性、快速性。但是**如果更新文件的责任被太多人分担**,你会看到质量差的风险增加。这可能会导致错误的数据输入(例如,合并两个单元格,将一个字符串插入到一个整数字段中)…并且可能会导致表格或仪表板损坏。
这就是为什么我个人会在满足几个条件的情况下使用这种技术:
* **只有一个人**(或非常有限的几个人)**负责**保持 Google Sheets 文件中数据的正确和最新
* 和/或**所处理的用例具有有限的影响**:它旨在为业务用户回答一个准时的或非常具体的问题
* 和/或**该方法用作概念验证**,供数据工程团队进一步开发
事实上,人们可以考虑将来自 Google Sheets 的数据集成到 BigQuery 中,这可能与更高级的数据产品的**初级版本相关。在我们的示例中,如果向销售人员分配团队的用例似乎超出了销售主管的单独使用范围,那么下一步将是向数据工程团队提供这种集成作为概念验证。**
# 结论
不可否认,将 Google Sheets 文件中的数据集成到 BigQuery 表中有两个优点:灵活性和快速性。这就是为什么在处理有限的利益相关者的特定用例时**特别有用的原因**。
然而,它也有缺点,因此您必须确保用这种方法处理的用例的框架设置清晰。为了获得更高的可伸缩性(但灵活性和速度较低),通过通常的数据体系结构传输数据仍然是在数据集中实现结构化更改的最佳实践。
你喜欢读这篇文章吗? [*成为*](https://marie-lefevre.medium.com/membership) *的一员,加入一个不断成长的充满好奇心的社区吧!*
<https://marie-lefevre.medium.com/membership>
# 使用 Docker Compose 和 GitHub 操作的简单 Python CI/CD 管道
> 原文:<https://towardsdatascience.com/the-easy-python-ci-cd-pipeline-using-docker-compose-and-github-actions-80498f47b341>
## 在 VPS 上持续部署真实世界的项目

由[古伊列梅·斯特卡内拉](https://unsplash.com/@guilhermestecanella?utm_source=medium&utm_medium=referral)在 [Unsplash](https://unsplash.com?utm_source=medium&utm_medium=referral) 拍摄的照片
在远程服务器上管理一个实时项目实际上需要一些领域,我们希望在这些领域减少人工干预,用自动化服务来代替。答:首先,每次我们向 GitHub 库推送新代码时,我们可能需要按顺序执行以下任一操作:
* 对我们的项目进行测试
* 用新版本更新 Docker 映像
* 将带有新建映像的应用程序部署到我们的服务器
与这些过程中的每一个相关联的复杂性本身并不是微不足道的,当您每次都需要按顺序执行它们时,这就变成了一件苦差事。因此,自动化集成和部署在开发人员眼中具有巨大的价值。
在这里,我们看一下用 Docker compose 和 GitHub 动作自动化 CI/CD 管道的简单方法。
# 用 discord.py 和 FastAPI 构建 discord bot
我想在我最近从事的一个项目中展示整个管道,这是一个用 *discord.py* 编写的 discord 机器人,用于在 discord 服务器中引入优雅的轮询服务。
bot 存储库位于[这里](https://github.com/yashprakash13/Pollsome)。以下是我正在处理的项目结构:

项目结构
如果您想跟进,可以在您的虚拟环境中使用以下命令简单地安装该项目的两个主要需求:
pip install discord.py fastapi "uvicorn[standard]" python-dotenv
`**discord.py**`是允许我们构建 discord 应用程序的主要库。`**FastAPI**`和它的 ASGI 网络服务器`**uvicorn**`将在部署时保持机器人在服务器上存活。最后,`**python-dotenv**`是一个简单的库,它将帮助我们在项目中使用 [*环境变量*](/the-quick-guide-to-using-environment-variables-in-python-d4ec9291619e?source=your_stories_page-------------------------------------) 。
> 注意:如果你正在跟进,你可能想在 [discord 开发者门户](https://discord.com/developers/applications)中制作一个应用程序和一个机器人,并获取它的令牌。
> 我们将在项目根目录下的`**.env**`文件中使用这个令牌,如上图所示。
我们现在快速看一下机器人代码,好吗?
import asyncioimport discordfrom dotenv import load_dotenvimport osfrom discord.ext.commands import Botload_dotenv()TOKEN = os.environ.get('DISCORD_TOKEN')
我们首先加载环境变量,并使用我们的 dotnev 库访问令牌。
现在,我们将我们的机器人定义如下:
intents = discord.Intents.all()bot = Bot(command_prefix='!', help_command=None, intents=intents)
**命令前缀**允许我们使用机器人只响应特定的命令。
为了使本文简单,我们只希望机器人做一件事:
* 读取消息中是否输入了特定命令,如果是,则回复它。
接下来,我们想从传入的消息中捕获文本,我们用`**on_message**`函数来完成:
@bot.eventasync def on_message(message): # Do not reply to self if message.author == bot.user: return # Do not reply to any other bot if message.author.bot: return # get the message content msg = message.content.lower() # reply to the ping message if "!ping" in msg: await message.reply("Pong!", mention_author=False)
现在让我们把它包装在我们的异步 API 中,好吗?
from fastapi import FastAPIapp = FastAPI()@app.get("/")def main(): return "The bot is alive!"# run the bot as a FastAPI async function@app.on_event("startup")async def run(): """ to run the bot as a FastAPI async func """ try:
asyncio.create_task(bot.start(TOKEN)) except: await bot.logout()
现在,使用以下 shell 命令运行 bot:
$ uvicorn run_bot:app --reload --port 8443 --host 0.0.0.0
服务器运行时,您将看到以下输出:

服务器状态
你应该也能在你的服务器上看到你的机器人上线。
现在,让我们将整个工作流容器化,以便在我们的 VPS 上轻松部署。
# 构建 Docker 设置
现在我们有了一个可用的 API,下一步就是封装我们的应用程序。让我们构建一个 docker 文件来开始这项工作:
touch Dockerfile
现在,我们想从以下几点开始:
* 下载并安装合适的 Python 版本
* 将我们的项目文件夹复制到容器中,
* 从`**requirements.txt**`安装所有依赖项
* 最后,暴露出需要的端口
让我们将这些行添加到我们的`**Dockerfile**`:
FROM python:3.10.2-slim-bullseye# Set environment variablesENV PIP_DISABLE_PIP_VERSION_CHECK 1ENV PYTHONDONTWRITEBYTECODE 1ENV PYTHONUNBUFFERED 1COPY . /pollsome_srcWORKDIR /pollsome_srcRUN pip install -r requirements.txtEXPOSE 8443
我们可以在这里停下来,使用 docker build 命令来构建/更新/停止我们的容器,但是我们可以更进一步,为更简单的设置创建一个`**docker-compose**` 文件:
touch docker-compose.yml
所以我们希望我们的 docker-compose 文件使用 Dockerfile 来执行我们上面提到的所有步骤,并使用 uvicorn 命令运行我们的 API (bot)。
我们这样做:
version: "3.9"services: bot: build: . volumes: - .:/pollsome_src ports: - "8443:8443" command: uvicorn run_bot:app --reload --port 8443 --host 0.0.0.0
现在,我们可以简单地使用下面的命令来构建一个新的映像,并基于该映像启动一个容器:
docker compose up --build -d --remove-orphans
如果我们想停止容器,或者显示一些日志,我们可以这样做:
docker compose down# anddocker compose logs
**可选步骤:**构建一个 **Makefile** ,用于使用更简单、更易于使用的命令执行这些任务集。
touch Makefile
然后将以下指令插入文件中:
build:
docker compose up --build -d --remove-orphansup:
docker compose up -ddown:
docker compose downshow_logs:
docker compose logs
太好了!现在我们已经为我们的 API 建立了完整的基础!
让我们来测试一下:
make build
您将看到以下输出:

生成输出
要停止容器,请执行以下操作:
make down

降低输出
最后,提交代码并将其推送到 GitHub 存储库。
# 远程服务器上手动部署
让我们继续在租来的虚拟主机上部署我们的项目。
第一步是 SSH 到您的服务器并克隆存储库。
> 如果你想知道如何用 SSH 在你的远程服务器上设置 GitHub 访问,那么先按照这些指示做[。](https://medium.com/this-code/set-up-github-via-ssh-on-a-remote-server-9348e3855f46?source=your_stories_page-------------------------------------)
git clone git@github.com:yourusername/repositoryname.git
如果您的系统上已经安装了 docker,请输入:
make build
并看到您的映像构建和容器启动。
**干得好!我现在称之为“部署握手”的第一部分已经结束。现在,我们只想通过外部服务来自动化这个过程。**
# 使用 GitHub 动作自动化部署
现在,我们希望发生以下情况:
* 一旦我们在本地机器上对我们的代码做了新的更改,我们就提交并把它推送到我们的在线 Github 库。
* 这个动作应该执行一个工作流来登录到我们的 VPS,把最新的代码放到 VPS 上,从新代码构建一个新的 Docker 映像,并为它启动一个容器。
* 作为一个清理过程,它还去除了旧的悬挂图像。
为此,我们使用了 **GitHub 动作**。
在我们项目的根目录下,让我们创建一个新文件,如下所示:
mkdir -p .github/workflows
touch .github/workflows/main.yml
在文件中,首先我们要将工作流命名为:
name: Bot CI-CD
现在,我们要创建工作流 ***触发器*** 。
触发器定义了这些流程何时执行。还记得我们希望他们将代码推送到主分支吗?我们这么说吧:
on:
# Triggers the workflow on push or pull request events but only for the main branch
push: branches: [main] pull_request: branches: [main] # Run this workflow manually from the Actions tab on Repo homepage
workflow_dispatch:
顺便说一下,我们可能还想从存储库主页上的 **Actions** 选项卡中手动运行这个工作流。`**workflow_dispatch**`触发器对此有所帮助。
现在,我们要指定一个部署“作业”。为此,我们首先需要在 GitHub 存储库中定义一些环境变量。
转到`**Settings -> Secrets -> Actions**`并添加新的存储库密码。
逐一补充以下秘密:
* VPS_SSH_HOST —这是您的服务器的主机 IP 地址。
* VPS_SSH_USERNAME —这是您的 user@ipaddress 登录的用户名。
* VPS_SSH_SECRET —这是您在服务器上为 GitHub 访问设置的私有 SSH 密钥。
* VPS_SSH_PORT —这是 SSH 访问的端口号。通常是端口 22。
* SSH_PASSPHRASE —这是在创建 SSH 密钥期间提供的密码。
* PROJECT_PATH —这是项目根目录的完整项目路径。例如,`**/home/username/path/to/your/projectrootdirectory**`
现在,我们终于可以在 yaml 文件中指定部署作业了:
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: Deploy to VPS
uses: appleboy/ssh-action@master
with:
# VPS IP
host: ${{ secrets.VPS_SSH_HOST }}
# VPS username
username: ${{ secrets.VPS_SSH_USERNAME }}
# SSH key (copy it from your local machine)
key: ${{ secrets.VPS_SSH_SECRET }} # SSH port
port: ${{ secrets.VPS_SSH_PORT }} # passphrase
passphrase: ${{ secrets.SSH_PASSPHRASE }} script: | cd ${{ secrets.PROJECT_PATH }} git pull origin main make down make build echo "Deleting old image(s)..." docker image prune -a -f
我们使用`**uses: appleboy/ssh-action@master**` 来指定 SSH 的登录动作。这是 GitHub 为了方便[从这里](https://github.com/appleboy/ssh-action)采取的一个自定义动作。
好了,我们准备好行动了!现在,推动您的存储库来看看魔法吧!
# 结论
好了,这就是我们如何通过使用 Docker 和 GitHub 操作创建 CI/CD 管道来自动化我们项目的集成和部署。
如果你想看一看[库](https://github.com/yashprakash13/Pollsome),就在这里。
在掌握了这个简单的工作流程之后,您还可以尝试一些事情:创建多个 docker 容器,并使用 Docker Swarm 通过 CI/CD acton 管理它们。在中型或大型项目中,为容器设置自动日志以进行持续监控也是一项很好的任务。
## [别忘了订阅阅读更多来自我。](https://ipom.medium.com/membership)
另外几个故事引起了你的兴趣:
<https://betterprogramming.pub/the-easy-python-auto-code-formatting-guide-e8300c82797b> </26-github-repositories-to-inspire-your-next-data-science-project-3023c24f4c3c> <https://medium.com/geekculture/21-vscode-keyboard-shortcuts-you-should-know-1b96a65e9428>
# 进行数据探索的简单方法
> 原文:<https://towardsdatascience.com/the-easy-way-to-do-data-exploration-22b4b8e1dc20>
## 使用 Jupyter 笔记本和 bamboolib Python 库

雅各布·欧文斯在 [Unsplash](https://unsplash.com?utm_source=medium&utm_medium=referral) 上的照片
数据争论、探索、处理,无论你在日常数据科学实践中怎么说,都是这项工作的主要部分之一。同时,这也是工作中最混乱的部分之一!
bamboo lib 库试图移除与数据探索相关的堆积如山的任务,并以一种更方便、游戏化和令人愉快的方式来取代其复杂的机制。
在本教程中,我将向您介绍如何使用 Jupyter notebook 或 Jupyter lab 来设置库及其扩展,并使用它在公共数据集上快速完成一些公共数据探索任务。
我们开始吧!👇
# 使用 Jupyter 设置运行 bamboolib
第一步是创建一个新的虚拟环境并安装必要的软件包。
如果使用`pipenv`,这个过程足够简单:
pipenv shell
然后你可以安装 Jupyter 和 bamboolib:
pipenv install jupyter bamboolib
最后,在虚拟环境中,您需要安装 bamboolib 扩展,以便在 Jupyter 环境中运行:
python -m bamboolib install_nbextensions
我们已经成功设置好了!让我们继续使用 Kaggle 的[泰坦尼克号数据集](https://www.kaggle.com/c/titanic/data)探索图书馆的功能。它是在创造性许可下免费提供的。
通过键入以下命令从`pipenv`环境中运行 jupyter notebook:
pipenv run jupyter notebook
# 探索 bamboolib UI
当您第一次打开 jupyter 笔记本或 jupyter 实验室环境时,您将读取数据。
考虑第一个单元格中使用的以下代码块:
import bamboolib as bam
import pandas as pd
df = pd.read_csv('data.csv')
df
您将获得以下输出:

作者图片—测向可视化从这里开始
**注意:**如果您没有看到带有 UI 选项的绿色按钮,请刷新浏览器选项卡,或者在终端中通过简单的 `Ctrl-C`简单地停止笔记本实例并重新运行它。
看到那个按钮了吗?它让你一次点击就能看到唯一值和缺失值的数量!

按作者分类的图片-探索数据框架
像这样:

按作者分类的图片-探索数据框架
那不是很方便吗?
现在,让我们探索另一个大量使用但仍然是数据争论的常见用例:使用熊猫“`**Group-by**`”函数。
由于“`**Survived**`”是我们的标签,我们希望基于该列本身计算聚合,如“总和”。让我们通过选择“**转换列**”空间中的“`**Group-by**`”选项,按“`**Age**`”和“`**Sex**`”列分组。

按作者排序的图像—从可用选项中选择“分组依据”
下面是做这个操作的全过程:

按作者分组的图像-按操作分组
最后,让我们来看看结果:

按作者分组的图像—按结果分组
让我们也执行一些数据可视化:让我们考虑散点图将如何显示关于“`**Age**`”和“`**PClass(the ticket class)**`”列的存活率:
因此,我们的 x 轴现在将有`“**Age"**`列,我们将选择我们的颜色作为标签类`**Survived**`。最后,我们将把这个可视化分成三个不同的子图(称为`**Facet rows**`),以便可视化每个乘客类别的存活率与年龄的分布(`**PClass**`)。
让我们在这里想象一下整个过程:

按作者分类的图像-直方图绘制操作
结果是:

按作者分类的图像-结果图
这个库的一个最好的特性是,你可以很容易地复制可视化代码或任何数据转换。看到“复制代码”和“显示代码”按钮了吗?是的,就是这些。
您可以像这样查看代码:

按作者分类的图像-结果绘图代码
# 几句临别赠言…
正如您可能已经猜到的那样,这个库使得在简单的按钮点击中执行各种数据转换和可视化变得非常方便。在某种程度上,通过研究从数据转换中获得的现成代码以及库本身的图形,您也可以获得非常有价值的信息。否则,为了快速准备会议,这个图书馆是个不错的选择!
快乐学习:)
我希望您喜欢这篇文章,并从中了解到这个有趣的库。我希望在我的下一部电影中也能看到你。
在那之前,[关注我的媒体页面](https://medium.com/@ipom),确保订阅后我所有的文章都能直接发到你的收件箱。
## [我还建议成为一名中等会员,以便不要错过我发表的任何数据科学文章。](https://ipom.medium.com/membership/)在此加入👇
<https://ipom.medium.com/membership/>
我的几篇文章你可能会觉得有趣:
</26-github-repositories-to-inspire-your-next-data-science-project-3023c24f4c3c> </the-nice-way-to-manage-your-data-science-workflow-7fb92a2ee4a2>