使用 Matplotlib 和 Cartopy 可视化卫星数据
实践教程
使用 Python 和被动微波数据探索我们不断变化的气候
北半球亮温图像(作者创建)
我最近给写了一篇帖子,讲述我们如何利用从卫星上获得的被动微波图像来研究积雪。利用卫星来研究积雪,可以解开一些区域的信息,否则这些信息是不可能研究的,尤其是在大范围内。除了覆盖范围大之外,携带被动微波传感器的太阳同步卫星每天在相似的时间拍摄两极的图像。这些一致的测量产生了令人难以置信的每日时间序列,可以追溯到 1978 年 Nimbus 7 卫星的发射。Nimbus 计划是 NASA 和 NOAA 首次合作发射专门用于气象研究的卫星,40 多年后,我们仍然受益于研究气候的早期投资。
在本帖中,我们将通过各种方法来使用 Matplotlib 和 Cartopy 可视化卫星图像。在制作演示地图时,这两个库是我最喜欢的工具;虽然网络地图风靡一时,但我们经常需要一种非在线托管的高质量可视化。
我们将从使用 Matplotlib 快速绘制信息丰富的图像开始,然后深入到使用 Cartopy 使用 Matplotlib 绘制地理坐标。最后,我们将讨论如何用 Matplotlib 制作动画图像和地图,以显示随时间的变化。所以,请坐好,放松,让我们学习如何使用 Matplotlib 来可视化阿拉斯加的积雪。
数据
背景
我们将使用 MEaSUREs 校准的高分辨率被动微波数据集,该数据集是 NASA 制作地球系统数据记录用于研究环境(MEaSUREs)计划的一部分。这个数据集是特殊的,因为它被重采样到比传感器最初捕获的分辨率高得多的分辨率;原始像素为 25 公里宽,但新数据的像素为 6.25 公里宽。这意味着我们现在有 16 个像素,而原来只有一个。
这些无源微波传感器测量的辐射能量非常低,这迫使我们在大范围内进行测量,以获得良好的读数。虽然与其他类型的卫星图像相比,6.25 公里仍然是一个宽像素,但它使我们能够比以前更详细地研究积雪。
被动微波辐射计测量的主要参数之一是亮温(TB),它是对朝向卫星上的传感器移动的辐射的辐射率的测量。我们在不同的频率下测量结核,用千兆赫(GHz)表示。对于积雪分析,我们主要关注 37GHz 和 19GHz 频率。当地面上没有雪时,两种频率相似,但随着雪在地面上积累,37GHz 频率的散射要多得多。这种差异使我们能够找到雪水当量(SWE)的替代变量,即储存在雪堆中的水量。
由作者创建
在该图中,您可以看到 19GHz 和 37GHz 频段在冬季如何发散,这是由于 37GHz 频段更多地从雪中散射。
在这篇文章的中,我深入研究了这个数据集,以及我们如何使用被动微波传感器测量的亮度温度来估计积雪中储存的水量。如果你对使用被动微波成像研究雪背后的科学感兴趣,请阅读那篇文章的前半部分。
选择研究区域
可通过 FTP 获得的完整数据集将近 70TB。幸运的是,为了研究 SWE,我们只需要在我们的时间序列期间每天下载两个文件。我已经写了一个 Python 库来为我们做这项工作,确保我们每年都能得到最佳的文件;有多种传感器可用,某些传感器的错误率低于其他传感器。
为了处理合理数量的数据,我们需要选择一个研究区域,因为使用完整北半球影像的时间序列(如帖子顶部所示)需要存储大量数据!下面你会看到我们将要绘制的阿拉斯加地区。
由作者使用谷歌地球创建
由于该数据使用 EASE-Grid 2.0 投影,我们必须通过选择左上角和右下角的一组坐标来选择边界框。等面积可缩放地球(EASE)格网是全球范围的网格数据的通用格式,可以很好地保留映射对象的面积。虽然缓和网格不使用纬度和经度;相反,他们选择以米为单位的行/列系统。稍后我将展示如何在纬度/经度和行/列坐标之间进行转换,这被称为重新投影。
用 Matplotlib 绘制 SWE
Matplotlib 是 Python 程序员可以使用的绘图库。虽然它在图形上比交互式绘图库更简单,但它仍然是一个强大的工具。Matplotlib 是我的首选库,用于快速绘制和演示我想要传达的特定观点。交互式地图根本难以清晰呈现;除非你正在做一个现场编码演示,否则你永远不会真的想在和观众说话的时候和你的电脑互动。
用 imshow 绘制简单图像
绘图是探索性数据分析的一个重要组成部分,Matplotlib 非常适合我们 EDA 所需的快速绘图。利用我们的 SWE 数据,简单地绘制时间序列中的一天就可以有力地证实我们对图像进行了正确的子集划分。
fig = plt.figure(figsize=(12,6))
im = plt.imshow(swe[0,:,:])
由作者创建
使用 Matplotlib 的 imshow 函数,我们可以像绘制任何图像一样绘制光栅数据。我们可以看到这个图中的海岸线和我用来创建上面的边界框的谷歌地球轮廓之间的大致相似之处,这意味着我们确实正确地选择了数据!
然而,这个情节缺少一些关键的组成部分。让我们用一些基本的 Matplotlib 格式使它更丰富一些:
fig = plt.figure(figsize=(12,6))
im = plt.imshow(swe[0,:,:],cmap='gist_rainbow')
plt.colorbar(im)
plt.title("SWE (mm) on Jan 23, 1993 | North Slope, Alaska");
由作者创建
这是我喜欢在演讲中使用的情节;这很简单,有助于避免分心,并且可以很快被消化,以便听众可以专注于我所说的内容。当在投影仪上呈现色彩不总是最饱和的地块时,使用对比度更高的色彩映射表会有所帮助。强烈对比的颜色使人们能够很快看出细微的差异,而这些差异在更微妙的颜色图上很难分辨出来。
利用支线剧情
支线剧情通过允许我们在一张画布上组合多个情节,为我们提供了许多扩展的功能。我们可以使用支线剧情来查看我们的研究区域在第一年不同季节的快照。
由作者创建
由作者创建
这是个很酷的情节。有趣的是,看到雪在秋天积累,在冬天达到高峰,并通过春天的图像几乎完成融化。在夏季/秋季图像和冬季/春季图像之间,海洋也在明显地改变温度;我们可以看到海洋重新变暖的时间可能比陆地上的雪融化的时间要长。
虽然这些图提供了丰富的信息,但由于我们将数据视为普通图像,因此我们失去了坐标参考系统,该系统实际上将网格与地球相一致。当我们像这样绘制空间数据时,我们失去了许多适当的形状和空间背景;接下来让我们尝试使用 Cartopy 在地图上绘制它。
添加投影
默认情况下,Matplotlib 设计用于在传统网格空间中绘图。为了在地图上显示数据,我们必须有一个带有匹配投影的底图。幸运的是,有一个名为 Cartopy 的库,它被设计用来处理地理空间数据,以便使用 Matplotlib 进行制图。我最喜欢 Matplotlib 的一点是,开发人员在它的基础上进行构建是多么容易;Cartopy 在某种程度上类似于 Seaborn,它建立在 Matplotlib API 之上,为用户带来了一个更加定制化的工具。
我们从定义制图坐标参考系统(CCRS)对象开始。这些告诉 Cartopy 我们的数据正在使用什么坐标参考系统(CRS)。
geod = ccrs.Geodetic()
proj = ccrs.LambertAzimuthalEqualArea(central_latitude=90.0)
我们数据的投影是以北极为中心的 Lambert 方位角等面积。让我们通过定义我们的投影和范围,使用我们的新坐标系来绘制地球的北半球。
由作者创建
由作者创建
在这张地图中,我们俯视北极,北美在左边,非洲在底部作为参考。您会注意到,我们没有绘制任何数据,这是因为这本质上是我们的新“画布”。Matplotlib 现在将 EASE-Grid 2.0 坐标视为绘图空间。
如果我们想在这个底图上分层数据,那么我们也需要找到数据的范围。您会注意到,当我们绘制底图时,我们用四个数字定义了范围。这些是边界框左上角和右下角的 x/y 坐标。在这种情况下,-9,000,000–9,000,000 米是 EASE-Grid 2.0 格网中两个 x/y 坐标的最大范围,北极位于点(0,0)。
我知道我学习区域的左上坐标是[-145,66],右下坐标是[-165,72]。这些是以度为单位的大地坐标,可以使用前面定义的 Cartopy 对象转换为米(由 EASE-Grid 2.0 使用)。
找到我们的边界坐标(由作者创建)
您会注意到我们将源坐标参考系统设置为geod
,这是另一个 CCRS 对象,表示使用度数、纬度和经度的大地坐标参考系统。我们使用兰伯特方位角等面积 CCRS 物体来转换坐标,因为那是我们的目标投影。
现在,我们在正确的 CRS 中有了新的边界坐标,我们可以继续绘制我们的研究区域:
由作者创建
覆盖数据(由作者创建)
不错!现在,我们已经将数据叠加到地图上,我们可以使用海岸线来验证我们是否使用了正确的投影和方向。我最初将 SWE 数据上下颠倒绘制,因为它的“原点”与基础地图不同,所以如果有些东西偏离了,不要害怕调整方向。
这张地图有点缩小了。很难非常清楚地看到 SWE 数据。我们可以通过调整底图的范围来放大:
ease_extent = [-3000000., 1000000., -1000000., 3000000.]
由作者创建
Cartopy 为 Matplotlib 带来了强大的功能,支持许多投影。
动画 Matplotlib 图
我总是发现用 Matplotlib 显示连续的变化非常困难。我们可以制作支线图来显示离散的变化,但是如果不使用动态绘图工具,显示变化是有挑战性的。解决这个问题的一个方法是使用动画。创建随时间变化的图形的电影或 gif 并不困难,这对于可视化地理空间数据的变化非常有用!
让我们试着用动画演示我们的原始绘图,它使用plt.imshow()
来绘制我们的 SWE 数据。
由作者创建
动画 SWE(由作者创作)
制作动画剧情真的那么容易!关键是我们有一些迭代绘图的方法。在这种情况下,我简单地遍历 1000 天的时间序列,并保存每个图的快照,然后将其转换为 gif。因此,我们首先创建一个 Matplotlib 图形fig
,并将其传递给Camera()
实例化器。现在,每次我们迭代创建一个新的图形时,我们只需用camera.snap()
对当前的 Matplotlib 图形进行快照。
有多种方法可以创建动画 Matplotlib 图。大多数例子可能会使用内置的Matplotlib.animation
模块。总的来说,这个模块工作得很好,但是,我遇到了依赖问题,阻止了在 Windows 10 上导出动画。Matplotlib 的动画模块也不能导出为 GIF 格式,而 GIF 是我用来分享演示和文章的首选格式。
为了避免依赖性问题并直接导出为 GIF 文件,我们可以使用一个叫做赛璐珞的库。赛璐珞是一个轻量级的库,用于从现有的情节中创建动画。它的开发并不活跃,但是如果您对内置的 Matplotlib 功能有问题,我建议您尝试一下。我喜欢它可以很容易地添加到现有的情节与任何功能的最低限度的返工。
实际上,在 Matplotlib 图形上绘制的任何东西都可以被动画化。所以我们也可以在地图上制作 SWE 图像的动画!
由作者创建
动画漫画/Matplotlib 图(由作者创建)
我觉得这些动画情节挺好玩的。能够看到陆地和海洋上的数值如何随着相应的日期变化,确实有助于显示每年的积累和融化周期。我们还可以以各种方式聚合数据,然后将这些聚合动画化。
包扎
虽然有时可能会觉得在 Python 中有比 Matplotlib 更好的绘图选项,但它仍然是最可靠和有效的绘图工具之一。Matplotlib 做得很好,为我们提供了一个可以根据我们的每一个愿望进行定制的画布。如果您需要为演示文稿、论文或文章绘制图表,Matplotlib 的可定制性是无可争议的。
除非您需要交互式地图,否则您可能会在某个时候使用 Matplotlib 来可视化 Python 中的地理空间数据。幸运的是,Cartopy 这样的库为 Matplotlib 提供了处理各种地理空间数据的能力。
资源
可视化技能评估指标
评估你的模型有多“好”
无论是评估回归模型还是地球系统模型,我们都需要能够量化它的“好”,这可能是主观的。这篇文章讨论了一套常用的技能评估指标,它们的优点,以及如何可视化或解释它们。每个指标将模型的 预测值§ 与一组 实际观察值(A) 进行比较。
我不主张选择一个度量标准来量化好,而是提倡综合并呈现一套标准。在这篇文章中,我将讨论:bias
、MAE
、RMSE
、NSE
和RI
。我将描述每个指标,展示它的可视化,并展示如何用 Python 对它进行编码。前三个(bias
、MAE
和RMSE
)是一个数字,用来量化预测的偏差程度。每一种都提供不同的信息,应该在分析中提出。
其他两个指标NSE
和RI
应谨慎解读,因为它们涉及比率。NSE
量化模型的预测能力,而RI
量化预测在乘法意义上的偏离程度。
0.交叉绘图
虽然不是一个技能指标,但这个情节非常重要,值得讨论。每当将预测值与实际数据进行比较时,总是从交会图开始,y 轴上的 预测值 ,x 轴上的 实际值 ,以及一条一对一的对角线。
将预测值放在 y 轴上,将实际值放在 x 轴上是很重要的。有了这个约定,一对一线以上的点被高估,线以下的点被低估。因此,坚持这一惯例可以对预测进行快速的视觉评估,并可以告诉你是否存在系统性偏差。
残差
下图显示了交叉图上的数据点,并说明了如何可视化单个数据点的***【R】***。
单个数据点的残差示意图。
为了得到正确的符号,残差必须计算为预测值减去实际值。在 Python 中,残差可以通过按元素减去两个数据集来计算,这通常适用于大多数数据类型:
*residual = prediction - actual*
残差是预测值和实际值之间的差值,它告诉您两条信息:
- 量级:预测与实际观测的差距有多远
- ***符号:*正表示高估,负表示低估
总是从一个交会图开始,y 轴上的 预测值 ,x 轴上的 实际值 ,以及一条一对一的对角线。
1.平均误差(偏差)
平均误差或偏差是所有残差的平均值,与符号无关。
偏差方程(图片由作者提供)
一个等价的表达偏差的方式是这样的:bias = mean(P) — mean(A)
,因为你可以分配总和。这清楚地表明,偏见仅仅是手段的不同。对偏差的解释是量化预测是否过度或低估的一种快速而肮脏的方法。
计算
无论你计算的平均误差是所有残差的平均值,
*import numpy as npresidual = prediction - actual
mean_error = np.mean( residual )*
或者作为两个平均值之间的差异,
*import numpy as npbias = np.mean(prediction) - np.mean(actual)*
答案完全一样。
平均误差是平均残差,与符号无关。
无偏见是什么意思?
解释偏差时一定要小心,因为接近零的值可能会引起误解。例如,如果较低的实际值被高估,而较大的值被低估,那么bias
也将出现在零附近。这在下面右边的图中有所说明。
两个交叉图,每个都有接近零的偏差。
这是因为大小相似的正负残差相互抵消,从而导致接近零的bias
。因此,要小心不要过于强调偏见,总是要参考交叉图来为bias
添加上下文。
也可以计算交会图的线性回归斜率,为bias
添加上下文。如果预测与实际观测完全一致,则斜率为 1。
谨慎解释偏见是很重要的
2.平均绝对误差
平均绝对误差MAE
与平均误差相似,只是我们忽略了符号。数学上,这是通过取绝对值来完成的。换句话说,MAE
是残差的平均幅度。值得注意的是没有告诉你错误的方向。
平均绝对误差方程。这与偏置方程非常相似,只是我们取绝对值。(图片由作者提供)
MAE 是残差的平均幅度
计算
使用numpy
,MAE
是这样计算的:
*import numpy as npmae = np.mean(np.abs(prediction - actual))*
sklearn
的实现如下所示。
*from sklearn.metrics import mean_absolute_error
mae = mean_absolute_error(actual, prediction)*
实际值通常是sklearn.metrics
中的第一个参数,但顺序与 MAE 无关。
MAE 告诉你,平均来说,一个数据点距离一对一的直线有多远
3.均方根误差(RMSE)
了解 RMSE 的最好方法是把它分成以下几个部分:
- 平方误差 : SE
- 均方误差 : MSE
- 均方根误差: RMSE
平方误差:标准误差
这是通过对每个数据点的残差求平方来计算的,并显示在一个十字图上,就像正方形一样。见下图:
交会图上的平方误差示意图。
更准确地说,它被想象成一个区域。如果我们预测的是开尔文温度,那么误差平方的单位是开尔文平方。
均方差:MSE
均方误差 MSE 就是平均“误差面积”。然而,MSE 不是一个好的技能指标,因为单位仍然是平方的。MSE 随残差呈指数增长,因为它代表一个面积,并且通过对残差求平方来计算。
均方根误差:RMSE
求 MSE 的平方根解决了单位问题,并得到均方根误差(RMSE)。这可以解释为 MSE 正方形的边长。
RMSE 方程(图片由作者提供)
计算
下面是一个numpy
实现。
*import numpy as np# squared error
se = (actual - prediction)**2# mean squared error
mse = np.mean(se)# root mean squared error
rmse = np.sqrt(mse)*
下面是一个sklearn
实现:
*from sklearn.metrics import mean_squared_error# mean squared error
mse = mean_squared_error(actual, prediction)# take square root of mse
rmse = np.sqrt(mean_squared_error)*
RMSE 边界
看起来似乎RMSE
和MAE
是同一个数字。然而,RMSE
被限制在MAE
和MAE*sqrt(N)
之间。下限是当所有的误差具有相同的幅度时,而上限是当所有的N
点除了一个以外都为零时的情况。
RMSE 误差界限(图片由作者提供)
见这篇文章关于 RMSE 及其误差范围的详细讨论。
MSE 告诉你平均面积,RMSE 告诉你面积的平方长度。
RMSE 对重大失误的处罚力度更大
RMSE 对大错误的惩罚比 MAE 多,这可能是一个可取的特征。例如,考虑以下两个残差,5 和 10
- 梅说,10 点下班比 5 点下班“糟糕”两倍。
- RMSE 说,10 点前的失误是 5 点前的两倍多。这是因为残差首先被平方。
RMSE 对重大失误的处罚力度超过了 MAE
其他指标
以下两个指标与后三个不同。它们是作为比率计算的,因此需要小心解读。每当涉及一个比率时,总有被零或一个非常小的值除的风险。解释 NSE 和 RI 时要小心
4.纳什-萨特克利夫效率
Nash-Sutcliffe 效率衡量的是预测值相对于观测平均值的准确程度。这与 RMSE 的根据有关:
纳什-苏特克利夫效率方程(图片由作者提供)
其中var(A)
是实际观测值的方差。
计算
这里是NSE
的一个numpy
实现。
*import numpy as np# squared error
se = (actual - prediction)**2# mean squared error
mse = np.mean(se)# nse
nse = 1 - (mse/np.var(actual))*
解释
- NSE = 1 :满分
- NSE = 0 :表示预测并不比观测平均值好。
- NSE < 0 :表示观察平均值是比您的模型更好的预测器
5.可靠性指数
可靠性指数被解释为预测值与实际观测值不同的平均因子。例如,RI 为 2 表示,平均而言,预测值与观测值在乘法因子 2 的范围内一致。理想情况下,RI 应该接近 1。
可靠性指数方程(图片由作者提供)
计算
在数学上,RI 从对预测和观测值进行对数转换开始。然后计算 RMSE,最后对结果求幂。因此,RI 是对数变换预测和观测值的指数 RMSE。
下面是一个numpy
实现。
*import numpy as np# logged squared error
log_se = np.log(prediction/actual)**2# log rmse
log_rmse = np.sqrt(np.mean(se))# reliability inded
ri = np.exp(log_rmse)*
最后的想法
这篇文章描述了评估模型预测的五个标准,无论是回归模型还是海洋模型。对于bias
、MAE
和RMSE
,越接近零预测越好。对于NSE
和RI
,1 分被认为是完美的。我主张显示所有这些指标的完整性。关于海洋科学背景下这些指标的详细讨论,我鼓励你阅读 Stow et al. 2009 。
我没有讨论的一个常见指标是相关性,它也与决定系数(R2)相关。这个在别处已经讨论过了(见相关帖子)。
讨论的每个度量都是空间和时间上的敏感相移。因此,每个指标都可以用“滞后”来计算例如,通常通过计算滞后相关性来确定任何滞后-超前效应。
相关职位
*https://medium.com/human-in-a-machine-world/mae-and-rmse-which-metric-is-better-e60ac3bde13d https://medium.com/@SilentFlame/pearson-correlation-a-mathematical-understanding-c9aa686113cb
感谢阅读和支持媒体作者
https://lukegloege.medium.com/membership *
用 Python 和 Tableau 可视化 Spotify 数据
使用您的流数据和 Spotify 的 API 创建一个动态仪表板
我不需要做这个项目来发现我仍然沉迷于 Lorde 的’https://open.spotify.com/track/0TEekvXTomKt3hdXDZxxeW****''排骨,但尽管如此,工作还是很有趣。参见下文,了解如何使用您自己的 Spotify 数据轻松复制它!
https://public . tableau . com/app/profile/Anne . bode/viz/spotifypremiumdash/PremiumDashboard
步骤 1:请求数据
在此 向 Spotify 索取您的数据副本。耐心等几天。可能有一种方法可以直接使用 Spotify 的 API 请求这些数据,但那是另外一个项目了!
步骤 2:准备流/库数据
使用 Spotify 给我们的文件,我们现在将创建一个数据帧,其中包括我们所有的流媒体数据,以及每首歌曲是否在我们的资料库中,以及每首歌曲的 Spotify“URI”(唯一标识符,以后会派上用场)
创建 df_stream :
接下来,我从 Spotify 清理了我的“YourLibrary”文件,这样它就只包含了“tracks”字典,用方括号[ ]括起来,并保存为一个新文件“YourLibrary1”。更擅长清理 json 文件的人可能会自动执行这个步骤,并使用原始文件。
创建 df_library :
创建我们的最终数据帧, df_tableau:
步骤 3:创建新的 Spotify 项目
在这里 登录你的开发者账号 。在仪表板中,创建一个新项目。创建后,您可以检索您的“客户 ID”和“客户机密”我们将在步骤 4 中使用这些。
步骤 4:使用 Spotify 的 API 创建流派数据框架
首先,我们将使用我们的客户端 ID 和客户端密码来生成一个访问令牌,这样我们就可以从 Spotify 的 API 中提取数据。注意:此令牌必须在一小时后重新生成。我在 这篇文章 的帮助下想出了如何做到这一点。
现在,我们将从库中提取与每个 track_uri 相关联的艺术家和流派,并添加到字典(查看 Spotify 的 控制台以了解如何提取您感兴趣的数据点)。**
我们将把这个字典转换成一个 dataframe ( df_genre )并扩展它,以便每个曲目/艺术家的每个流派都在它自己的行中(我使用了这个解决方案)。这将创建 df_genre_expanded 。
然后,我们将把 df_tableau 和 df_genre_expanded 保存为 csv 文件,以便加载到 tableau 中。
步骤 5:将数据加载到 Tableau 中
连接到 Excel 文件(MySpotifyDataTable.csv)作为数据源。这应该也会在左侧弹出您的 GenresExpandedTable.csv 文件。将后一个文件拖到右边,并在两个表之间添加一个关系。确保基于 track_uri 创建关系(注意:您可能需要单击 GenresExpandedTable.csv 旁边的向下箭头,然后单击“字段名在第一行”)。
步骤 6:编辑 Tableau 中的字段
我们将在数据表中添加两个计算字段。我们可以用 Python 来完成这个,但是我想用 Tableau 来做实验。
- 将 Ms 播放转换为分钟收听*:
【Ms 播放】/60000*** - 将结束时间* (UTC)转换为结束时间(Adj) (您的时区,已考虑夏令时):
IF【结束时间】<DATE(2020–03–08)THEN DATEADD(‘小时’,-5,[结束时间])
ELSEIF【结束时间】<DATE(2020–11–01)THEN DATEADD(‘小时’,-4,[结束时间***
步骤 7:创建可视化效果
下载仪表板 来看看我是如何创建下面的可视化效果的。请注意,它们在仪表板中都是链接在一起的,因此可以互相过滤,这很不正常!
仪表板过滤了风格为“alt z”的歌曲/艺术家——我是一个酷 Z 一代的孩子吗?
- 顶级艺人:收听分钟数最多的流行艺人,个人歌曲构成了丰富多彩的片段
- 艺人广度 : 我听了> 1 分钟和> 1 流的每位艺人的歌曲数量
- 热门歌曲:收听分钟数最多的流行歌曲
- 流派:我听过的所有流派,用大小和颜色表示流的数量
- 按月统计的听众人数:不言而喻的(编辑 9/29:我将“在图书馆中”字段从一个度量转换为一个维度,这样我就可以将它包含在一个堆叠条形图中,以查看我每个月总共听了多少分钟,其中有多少分钟在我的图书馆中)**
- 每小时听众人数:不言自明
最后
通过分析您的 Spotify 流媒体和图书馆数据,您可以收集到大量有趣的见解,尤其是结合通过 Spotify API 获得的其他数据字段(即流派)时。我知道今年我真的很喜欢朱利安·贝克,我对洛德的爱没有时间限制。8 月份,我听了太多阿德里安娜·伦克的’https://open.spotify.com/track/1abuE8PRWIA2GAH1DqzfNl*'(# sadgirlvibes),但 12 月份,我最喜欢的歌当然是玛丽亚·凯莉的’ 我想要的圣诞礼物就是你 '。现在我知道如何连接到 Spotify 的 API,在未来的项目中,我想检查我听的歌曲/艺术家的音乐质量(不仅仅是流派)。我特别感兴趣的一个领域是“可跳舞性”,因为每当我被指派为家庭公路旅行的 DJ 时,我母亲的唯一标准就是“我能跟着跳舞的东西。”不管那是什么意思。***
祝你好运分析你自己的收听历史,继续收听 2013 年以来你最喜欢的歌曲!
用 Python 可视化 Spotify 歌曲:探索性数据分析
实践教程
需要回答的一些问题:是什么让流行音乐流行?今天的音乐与 30 多年前有什么不同?
sgcdesignco 在 Unsplash 上的照片
在过去的一年里,我一直在使用 Spotify 应用程序收听我最喜欢的艺术家,并获得新歌推荐。最近,我了解到该应用程序根据音频特征系统对曲目进行分类,并将它们存储在一个数据库中,通过其 API 可以轻松访问。所以,我想:我们能不能利用这个数据库更好地了解其中的轨迹?也就是说,我们可以根据音乐的流行程度或发行年份等因素来划分音乐分组,从而发现任何趋势吗?让我们开始吧:
音频特性:
根据 Spotify 网站的说法,他们所有的歌曲都在以下每个类别中得到了分数(摘自 Spotify API 文档,https://developer . Spotify . com/documentation/we b-API/reference/):
- 情绪:可跳性、效价、能量、节奏
- 特性:响度、语音、乐器性
- 语境:活跃度,声音
我将要使用的数据来自这个 Kaggle 数据集:https://www . ka ggle . com/yamerenay/Spotify-dataset-19212020-160k-tracks?select=tracks.csv 。
1。前 100 首最受欢迎的歌曲对比所有数据集
首先,让我们将前 100 首歌曲与数据集的其余部分进行比较。这是通过对“受欢迎程度”列进行排序来完成的:
现在我们有了数据,让我们来看看每首歌的特点。具体到这一部分,我们将查看前 100 首最流行歌曲以及所有数据集的平均值。为了形象化这一点,我们可以使用如下雷达图。下面的代码是:
- 获取数据的所有标签,在我们的例子中是音频特征,并获取它们的含义。有两个变量:“特征”,具有前 100 首歌曲的音频特征的平均值,以及“特征 _ 全部”,具有所有数据集的平均值。
- 用不同的颜色在同一雷达图上绘制“特征”和“特征 _ 全部”。
前 100 首歌曲和其余数据集的特征平均值雷达图
从剧情来看,这两个歌曲分组在几乎所有的音频特征上似乎都有一些不同。也就是说,最流行的歌曲更“有活力”,“可跳舞”,并且具有更高的“明确性”值。根据 Spotify 对这些特征的定义,其余歌曲在“声音”和“效价”类别中得分较高,这可以被解释为传达了更多的积极信息。
比较盒式图中的歌曲
既然我们看到两组人的特征有一些不同,我们来更好地看看他们怎么样?下面,您可以找到这些功能的方框图,0 表示数据取自前 100 首歌曲,1 表示数据取自数据集的其余部分。
前 100 首歌曲和其余数据集的特征的方框图
箱形图还显示了两组特征的一些差异:在“活泼”子图中,流行歌曲部分比数据集的其余部分短。然而,在很大程度上,这些图证实了我们对这些群体的观察。
精力与舞蹈能力
现在让我们画一个散点图,看看“活力”和“可跳舞性”特征之间是否有关联。除了前 100 首最受欢迎的歌曲,我还从数据集中随机选择了 100 首歌曲。在下图中,有两种不同的颜色,黄色表示 100 首随机歌曲,紫色表示前 100 首歌曲。
能量与舞蹈性散点图
计算的皮尔逊相关系数是:0.35156523(对于黄色/所有数据集点)和 0.20520467(对于前 100 首歌曲)。
价和活泼
我们可以画的另一个散点图是化合价与活跃性的关系。“生动性”代表一首歌曲是否在观众面前现场表演的概率。该图的图例同上:
化合价和活度散点图
有趣的是,这两个变量之间似乎没有很强的线性关系。在这里,我还计算了皮尔逊系数,就像上面的散点图一样:-0.09403765(黄色点)和 0.02555036(紫色点)。
3.比较时代:90 前与 90 后
除了比较流行歌曲和数据集的其他部分,我们还可以看看不同时代之间歌曲的差异。出于本教程的目的,我将把年代定义为 1990 年之前和 1990 年之后。现在让我们看一个与上面类似的雷达图,但是有这两个类别(图的代码基本相同,所以我不会在这里再次展示)。
对比 20 世纪 90 年代前后音乐的雷达图
根据盒子情节,两个时代的音乐有几个不同之处:首先,90 年代后的音乐更“有活力”、“适合跳舞”和“明确”。而其他特征如“效价”和“活泼性”在两者中非常相似。20 世纪 90 年代以前的音乐在“声音性”和“乐器性”方面也往往得分较高。
4.可视化最受欢迎的艺术家
该数据集还包括每首歌曲的艺术家姓名,但采用列表格式。为了解析单个的名字,我们可以使用“re”,这是一个非常有用的文本操作包。首先,我们从列表中删除“[”和“]”,并构建一个文本模式来搜索数据。由于艺术家通常使用他们的全名或一个艺术名称,该模式查找一个或两个单词,由一个字符分隔,如下所示:
然后,我们在数据集的列中执行搜索,并使用另一个名为“collections”的 Python 包来计算每个艺术家的出现次数:
以下是统计前 100 名艺术家的结果:
按歌曲数量排名前 100 位的艺术家
顶级艺术家是贾斯汀比伯(5 首歌曲)和坏兔子(4 首歌曲),反映了 2021 年 4 月收集该数据集时公众的偏好。
5.图形音频功能相似
对于这一部分,我们将使用 networkx 包来绘制图表,以可视化歌曲之间的相似性。要使用的功能将是 Spotify 音频功能,我们将使用**余弦相似度、**来计算歌曲相似度,这是一种常用的测量对象(如歌曲、电影或书籍)之间相似度的方法。我们可能试图回答的一个问题是,哪些歌曲与许多其他歌曲相似。也就是说,有没有“听起来”和别人差不多的歌?让我们将一首歌曲与另一首歌曲的相似度的下限设定为余弦相似度 0.95。下面是计算余弦相似度和绘制图形的代码:
余弦相似度高于 0.95 的前 100 首歌曲的图表
正如你在下图中看到的,没有多少歌曲是彼此非常相似的,因为图中包含的节点少于 100,这是我们最初的数字。但是,哪些歌曲的“度”最高,这意味着它们与图中的许多其他歌曲相似?
代码返回数据库中的第 55 个条目,对应于 23 度,这意味着这首歌与其他 23 首歌相似。这首歌是这样的:
与前 100 名中的其他人相比度数最高(边缘最多)的歌曲
让我们也获得一些关于该图的其他信息,例如平均程度,它告诉我们一个音轨有多少首歌曲的平均值是相似的:
- 平均度: 12.494845360824742(歌曲平均类似其他 12 首左右)
- 节点数: 97
6.获取歌词数据
对于这一部分,我们还将分析数据集中歌曲的歌词数据。为此,我们可以使用 LyricsGenius API。由于数据集非常大,我将再次随机选择大约 400 首歌曲来可视化。为了用 LyricsGenius 搜索歌词,您需要知道歌曲和艺术家的名字,所以下面的代码提取了这两条信息并搜索了歌词:
从所有数据集中选择和抓取 400 首随机歌曲
7.歌词分析
既然我们已经研究了最流行歌曲的音频特征,我们也可以尝试分析数据子集的歌词。对于这一部分,我们将使用 Python 的 TextBlob 包对我们在上面的步骤 6 中选择的歌曲进行文本分析。
- 文本情感分析:极性
歌词的一个方面是它的极性,或者文本被认为是积极的(值更接近 1)还是消极的(值更接近-1)。这是歌曲子集极性的方框图:
400 首随机歌曲文本极性的箱线图
虽然该指标的中值约为 0,这意味着歌曲大多是中性的,但在图的两个方向上仍有许多异常值。这表明有许多积极乐观的歌词,也有消极的。
- 词性分析
在进行文本分析时,查看词性标注对于理解文档也很重要。你可以在这里阅读更多关于所有部分的内容:https://www . geeksforgeeks . org/python-part-of-speech-tagging-using-text blob/。在这个故事中,我们将学习 NN(单数名词)、NNS(复数名词)、RB(副词,如“非常”)、rbs(最高级副词)、RBR(比较副词)和 VB(基本动词)。让我们看看我们挑选的 400 首歌曲是如何根据上述部分的百分比使用以下代码创作的:
现在我们已经有了每首歌的这些指标,我们可以使用一个方框图来可视化它们:
词类构成
词类构成第二部分
正如你所看到的,单数名词占了歌词的很大一部分,其次是动词和规则副词。另一方面,比较级和最高级副词在歌词中不常出现。
结论
总结我们的发现,我们发现与其他歌曲相比,最受欢迎的歌曲之间以及不同时代之间存在相当大的差异。我们还构建了图表来查看哪些歌曲与其他歌曲更相似,并查看了用于查看歌词的文本分析技术。下面是您可以仔细查看的代码:https://github . com/DeaBardhoshi/Data-Science-Projects/blob/main/Music % 20 system . ipynb
我希望你喜欢这篇文章,并感谢阅读!
使用 Python 可视化统计数据-使用 Matplot 讲述故事
用 Python 讲述数据故事
为泰坦尼克号数据集精心制作一个故事
数据科学家可以学习的最重要的技能之一是如何使用给定的数据编写令人信服的故事。虽然我们倾向于认为我们的工作是客观的和技术性的,概括在格言“数字不会说谎”中,但我们也应该意识到它更主观的方面。我们不应该陷入这样一个陷阱,即认为我们的工作完全脱离了我们自己对世界的印象和先入为主的观念。
在这篇文章中,我将回顾相同的数据集可以被用来制作不同的(有时是相互矛盾的)关于主题的叙述的许多方法。
我们开始吧!
像往常一样,让我们导入将要使用的 Python 库。
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import scipy.stats as stats
太好了,现在让我们导入将要使用的数据。
df = pd.read_csv('titanic_data.csv')
df.head()
数据帧的前 5 行
你可能已经注意到了,我们使用的是经典的泰坦尼克号数据,可以在 Kaggle 这里的找到。我鼓励新的数据科学家看一看它,因为它是开始学习基本统计学的一个极好的方法。
让我们先来看看最明显的特征,幸存者人数。
fig, ax = plt.subplots(1, figsize=(5,5))
plt.suptitle('Frequency of Survival', fontsize=15)
ax.bar(dataset['Survived'].value_counts().index,
dataset['Survived'].value_counts().values,
color = ['darkblue', 'darkorange'])
ax.set_xticks(range(0, 2))
ax.set_xticklabels(['Died','Survived'], fontsize = 14);
死亡与存活的计数图(由代码生成的图像)
正如我们所看到的,记录显示死亡人数多于存活人数。尽管这是一个有趣的统计数据,但我们并不能从中挖掘出多少故事。现在让我们加入一些其他的描述性特征,比如性别。
fig, ax = plt.subplots(2,2, figsize=(15,10))
plt.suptitle('Survival by Gender', fontsize=25)
ind = np.arange(2)
width = 0.45x_axis_status = dataset['Survived'].value_counts().index
x_axis_sex= dataset['Sex'].value_counts().index
male_stats = dataset[dataset['Sex'] == 'male']['Survived'].value_counts().values
female_stats = dataset[dataset['Sex'] == 'female']['Survived'].value_counts().valuesax[0][0].set_title('Stacked Graphs', fontsize = 18)
ax[0][0].bar(x_axis, male_stats, label = 'Male', color = 'darkblue')
ax[0][0].bar(x_axis, female_stats, label = 'Female',
color = 'darkorange', bottom = male_stats)
ax[0][0].set_xticks(range(0, 2))
ax[0][0].set_xticklabels(['Died','Survived'], fontsize = 14)ax[0][1].set_title('Side-by-Side Graphs', fontsize = 18)
ax[0][1].bar(ind, male_stats , width, label='Male',
color = 'darkblue')
ax[0][1].bar(ind + width, female_stats, width, label='Female',
color = 'darkorange')
plt.sca(ax[0][1])
plt.xticks(ind + width / 2, ('Died', 'Survived'), fontsize = 14)ax[1][0].set_title('Stacked Graphs', fontsize = 18)
ax[1][0].bar('Male', male_stats[0], label = 'Died',
color = 'darkblue')
ax[1][0].bar('Male', male_stats[1], label = 'Survived',
color = 'darkorange', bottom = male_stats[0])
ax[1][0].bar('Female', female_stats[0], color = 'darkblue')
ax[1][0].bar('Female', female_stats[1], color = 'darkorange',
bottom = female_stats[0])
ax[1][0].set_xticklabels(['Male','Female'], fontsize = 14)ax[1][1].set_title('Side-by-Side Graphs', fontsize = 18)
ax[1][1].bar(0, male_stats[0] , width, label='Died',
color = 'darkblue')
ax[1][1].bar(0 + width, male_stats[1] , width,
label='Survived', color = 'darkorange')
ax[1][1].bar(1, female_stats[0] , width, color = 'darkblue')
ax[1][1].bar(1 + width, female_stats[1] , width,
color = 'darkorange')
plt.sca(ax[1][1])
plt.xticks(ind + width / 2, ('Male', 'Female'), fontsize = 14)[axi.legend(fontsize = 14) for axi in ax.ravel()]
[axi.set_ylim(0, 800) for axi in ax.ravel()]fig.tight_layout()
plt.show();
图表比较(代码生成的图像)
既然我们已经纳入了性别因素,我们的分析可能会更有趣。通过设计,我们制作了四个不同版本的基本相同的图表。注意每一个微小的变化是如何突出数据的不同方面的(因此需要不同的叙述)。
上面的两张图给人的印象是,我们应该关注乘客死亡中的性别差异。如果我们看上面的图表,我们会注意到更多的人死于泰坦尼克号的沉没。然后,我们可能会忍不住得出结论,这是如何通过“妇女和儿童”优先政策实现的。然而,看下面的一组图表揭示了一些更微妙的东西。
与上面的图表不同,死亡人数中的性别差异并不是重点。实际上强调的是,男性和女性的死亡率明显相似。
“但这怎么可能呢?”你可能会问。男性显然代表了更多的死亡。那么,两性的死亡率怎么会相似呢?
答案在另一张图中。
fig, ax = plt.subplots(1, figsize=(5,5))
plt.suptitle('Gender Split', fontsize=15)
ax.bar(dataset['Sex'].value_counts().index,
dataset['Sex'].value_counts().values,
color = ['darkblue', 'darkorange'])
ax.set_xticks(range(0, 2))
ax.set_xticklabels(['Male','Female'], fontsize = 14);
按性别划分的乘客计数图(由代码生成的图像)
我们可以看到,男性实际上大大超过了女性,两者相差大约 82%。这样一来,男性在死者中所占的比例就更大了,这也就说得通了,因为他们的数量本来就更多(请注意,男性也构成了幸存者的大部分)。
当然,这并不是说不存在强调保护妇女和儿童而不是成年男子的偏见。然而,当试图寻找这种特殊偏见的证据时,我们必须认识到要使用的“正确的数据。我们还必须认识到,完全相同的数据在被选为主要分类器时可能看起来非常不同(在我们的案例中,幸存者身份与性别)。如果我们依赖第一组图表,我们可能会夸大死亡统计中的性别差异水平。
但是现在让我们不要从性别的角度来看这些数据,而是从年龄的角度来看。
fig, ax = plt.subplots(figsize=(10,7))
age_died = df[df['Survived']==0]['Age']
age_survive = df[df['Survived']==1]['Age']
n, bins, patches = plt.hist(x = [age_died, age_survive],
stacked = True, bins='auto',
color=['darkblue', 'darkorange'],
alpha=0.65, rwidth=0.95)
plt.grid(axis='y', alpha=0.55)
plt.xlabel('Passenger Age', fontsize = 15)
plt.ylabel('Frequency', fontsize = 15)
plt.title('Age Distribution of Passengers', fontsize = 22)
plt.legend(['Died','Survived'], fontsize = 15);
按乘客年龄划分的存活率(由代码生成的图像)
从上面的图表中我们可以看出,年轻肯定有优势,因为我们注意到,存活数大于死亡数的唯一时间是在 10 岁以下。此外,我们看到一个八十多岁的老人能够在灾难中幸存下来,也许一些乘客同情他们,让他们上了救生艇。
总之
我们已经看到了图表中的细微变化如何对数据的整体叙述产生巨大影响。在实际的数据科学项目中,我发现简单地制作一个条形图并接受 Matplotlib 或 Seaborn 的第一个输出是一种诱惑。虽然这有助于加快进程,但我们在最初查看数据时必须小心。我们必须尽力以多种方式将其可视化,以确保我们不会对数据产生错误的印象。在以后的文章中,我们将讨论更高级的统计概念以及可视化它们的最佳方式。现在,我希望这篇文章已经帮助你认识到我们的工作有时会相当主观。
可视化幸存者电视节目数据集:幸存者个性和投票团队模式
十几岁的时候,我记得电视真人秀《幸存者》每一集的精彩场面。虽然观众对角色的阴谋和策略有了接近真实的一瞥,但我们都知道真正的洞察力隐藏在原始数据中。
最近发布了一个新的公共数据集,记录了数据科学家希望在电视节目中看到的一切:从评级,到漂流者的个性,以及投票结果。
在这篇博文中,我将尝试一些我觉得有趣的可视化。
获奖者的性格特征是什么?
Myers-Briggs Type Indicator是一种流行的个性特征方法,尽管它作为一种心理测量工具的有效性一直是许多批评的主题!但是有人(!?)正在努力对 40 季中的每一季进行分类,每集 20 名漂流者,参与者,以及…数据已经在那里了,所以为什么不看看呢。只是为了好玩。
bind_rows(
castaways %>% ungroup %>%
mutate(place = case_when(
result == ‘Sole Survivor’ ~ ‘Sole Survivor’,
result == ‘Runner-up’ ~ ‘Runner-up’,
TRUE ~ ‘voted-out / other’)) %>%
count(place, personality_type) %>%
group_by(place) %>%
mutate(perc = n / sum(n)) %>%
ungroup,
castaways %>% ungroup %>%
count(personality_type) %>%
mutate(perc = n / sum(n)) %>%
mutate(place = ‘all’)
) %>%
filter(!is.na(personality_type)) %>%
mutate(personality_type = as.factor(personality_type)) %>%
ggplot(aes(x = personality_type, y = perc)) +
geom_bar(position=”dodge”, stat=”identity”) +
facet_grid(~place) +
coord_flip() +
labs(title = ‘Survivors castaway personality type across all seasons, overall, and by winning place subgroups’,
subtitle = ‘% are relative to the place-group only, e.g. Runner-up only, etc’,
caption = ‘created by Dror Berel’) +
theme(axis.text.x = element_text(angle = 90))`
图来源:作者
首先,让我们来看看制片人是否有偏见选择,只选择特定的性格类型来表演。左侧的“所有”柱状图直观地表明,在所有 731 名遇难者中,总体上有一些平衡。接下来,我们看到赢家(“唯一幸存者”)拥有各种各样的人格类型,但可能倾向于 es 人格类型,特别是 ESTP 。“亚军”往往也有 ES 的部分,尽管有些人拥有 IS 的特征,特别是 ISFP。
联盟/投票团队模式
第一次尝试用一个简单的条形图来显示被淘汰的漂流者。
## Barplot ----
vote_history %>%
filter(season == 40) %>%
mutate(vote = vote %>% fct_reorder(order)) %>%
ggplot(aes(vote, fill = castaway)) +
geom_bar() +
facet_grid(.~episode) +
coord_flip() +
labs(title = 'Season 40 Voted out castaway',
#subtitle = '% are relative to the place-group only, e.g. Runner-up only, etc',
caption = 'created by Dror Berel') +
theme(axis.text.x = element_text(angle = 90))
图来源:作者
第一集展示了琥珀和娜塔莉,以及其他一些稀疏的漂流者之间的密切匹配。然后,接下来的几集没有那么多样的投票模式,也许在第六集丹尼斯和帕尔瓦蒂之间有一些额外的戏剧性时刻。
虽然上面的柱状图已经给出了一些关于哪些联盟一起投票的指示,但是下面的流程图显示了成对投票的模式。第一个仅针对第 1 集,随后是跨所有集的聚合。
图来源:作者
图来源:作者
拱门狭窄的漂流者在比赛初期就被淘汰了。在游戏中走得更远的幸存者有更长的拱门和更多的联盟。
你对特定的季节感兴趣吗?请继续关注另一篇全季全集可视化的博文。
用于可视化的 r 包: ggplot2 、circle circle、 tidyverse 。
查看我的其他博客文章和我的 GitHub 页面获得更多有趣的阅读。领英。
想象圆周率的美丽
柴坦尼亚电视台在 Unsplash 拍摄的照片
由圆周率的数字制成的各种静态和动态图像
注 1: 图形以高分辨率渲染,清晰可见。请给图形加载一些时间。
注 2: 这些图片的高分辨率 pdf 版本可以从www.pi.aqeel-anwar.com下载
注 3: 随着时间的推移,更多的可视化将被添加到本文中。
圆周率是圆的周长与直径的比率,是宇宙中最重要的数字之一。这是一个非-终止,非 - 重复小数,这意味着没有一组数字无休止地重复。利用谷歌云,Emma Haraku 将圆周率大部分位数的计算记录设定为 31.4 万亿。给你一个视角,一个人要花将近 100 年才能说出圆周率的这些数字。
在本文中,我们将尝试通过不同的动画和情节来可视化圆周率。
1.网格上的 Pi
网格上的圆周率从左到右、从上到下绘制大小相等的圆。圆圈的颜色表示从 0 到 9 的数字,如果数字是奇数,则表面颜色为空。下面的网格图描绘了圆周率的 100、400、2500 和 10,000 位数。
作者图片
作者图片
2.圆周率数字的随机游走
每个数字被分配一个等间距的角度(0-360 度)。对于每一个手指,行走以相等的步长在各自的方向上前进。
下图描绘了 100、500、1000 和 10,000 位数圆周率的变化。
作者图片
作者图片
作者图片
3.码头的环形人行道;
受 Martin Krzywinski 的启发,环形网络行走以环形模式绘制圆周率数字的行走。下图描绘了 100、1000、5000 和 10000 位数圆周率的变化。
作者图片
作者提供的视频
4.圆周率的概率直方图:
这个可视化显示了圆周率的前 n 位数字的分布。可以看出,数字 0 是最后出现的,而数字 3 是圆周率前 100 位中最占优势的。
作者图片
作者图片
总结:
一张图胜过千言万语,或者在这种情况下,一张图胜过数万位数。从上面看到的各种形象化,可以看出圆周率的数字中并没有隐藏着可观察的模式。随着位数的增加,不仅从 0 到 9 的所有数字的出现频率变得相等(概率直方图),而且所有可能的 2 位数模式(11、12、…、19、21、22、…)的出现频率也变得相等(循环网络遍历)。
如果这篇文章对你有帮助,欢迎鼓掌、分享和回复。如果你想了解更多关于机器学习和数据科学的知识,请关注我@Aqeel an war或者在LinkedIn上与我联系。
可视化超参数对支持向量机的影响
直观地了解在支持向量机中使用不同的核函数和超参数时会发生什么
本文的目标是直观地查看 SVM 的每个超参数和核函数的效果,以了解它们对模型的影响。
首先简单介绍支持向量机,然后是数据集。就本项目而言,数据集是一个简单的数据集,只有两个特征,可以很容易地以二维方式可视化。数据集将分为训练数据集和验证数据集。并且,对于每个核函数,呈现了显示不同超参数的效果的可视化。
你可以在这个笔记本里找到的源代码。
目录
- 支持向量机简介
- 资料组
- 流行的内核函数
- 结论
- 感谢
支持向量机简介
支持向量机是用于分类(或回归)任务的监督机器学习模型。在二元分类的情况下,有一个由𝑛观测值组成的数据集,每个观测值由𝑑维数的向量𝑥𝑖和目标变量𝑦𝑖组成,目标变量可以是 1 或 1,这取决于观测值是属于一个类还是属于另一个类。
使用这些数据,SVM 学习超平面的参数,𝑤⋅𝑥−𝑏=0 将空间分成两部分:一部分用于一个类的观察值,另一部分用于另一个类。此外,在分隔两个类的所有可能的超参数中,SVM 学习分隔它们最大的超参数,即,在每个类和超平面之间留下尽可能多的距离/余量
两类训练的 SVM 的最大边缘超平面和边缘。边缘上的样本被称为支持向量,因为它们是定义超平面所需的唯一样本。
图片由拉赫玛姆提供,CC BY-SA 4.0<https://creativecommons.org/licenses/by-sa/4.0>,转自维基共享
为了学习超平面的参数,SVM 试图最大化观测值之间的间隔,并且附加约束是不同类别的观测值必须在超平面的不同侧。
本文不会详细讨论支持向量机如何获得这些参数背后的数学原理。然而,为了提供一些可能有用的直觉,有趣的是注意到当计算超平面的参数时,训练数据、 𝑥 将仅作为标量积的一部分出现。
由于这种观察,支持向量机可以利用所谓的核函数。这是一个函数,它返回两个向量之间的标量积,但不需要计算这些向量的坐标。这非常有用,因为我们可以模拟应用增加𝑥维度的操作,而不需要去更高维度,这在计算上更便宜(这被称为内核技巧)。
因此,支持向量机可以处理不可线性分离的数据。SVM 不再试图为数据拟合复杂的函数,而是进入数据可以线性分离的更高维度,并在那里找到分离数据的超平面(回到原始维度,它看起来不会像线性分离)。
因此,现在是时候说,支持向量机不计算超平面的参数,而是记住计算超平面所需的𝑥’s,当新的输入数据到来时,支持向量机执行这些𝑥’s(称为支持向量)和输入数据之间的标量积。同样,这是为了继续使用标量积并利用内核函数。
另一个要注意的有趣的事情是,在两个类之间找不到完美的分离是很常见的。这对于支持向量机是不利的,因为在训练(计算超平面参数)期间,它们试图最大化类别之间的间隔,并限制一个类别的观测值必须在超平面的一侧,而另一个类别的观测值必须在另一侧。为了有助于这一点,支持向量机有“软余量”,这是一个通过调节允许多少观察值通过余量来放松这一点的参数。
资料组
该数据集是对虹膜数据集的修改,只有两个维度,因此可以很容易地可视化。特别是,它由刚毛鸢尾和杂色鸢尾花的萼片长度和宽度组成。
下图显示了该数据集是如何划分为训练集和验证集的。此外,数据已经过预处理,具有平均值 0 和单位方差。这是一个很好的实践,因为支持向量机使用标量积,所以如果一个变量的值范围比其他变量大,它将支配标量积的结果。
作者图片
流行的内核函数
本节介绍四种最常见的核函数以及每个超参数对 SVM 结果的影响。
线性核函数
作者图片
这是最简单的核函数,因为它相当于不使用任何核函数。换句话说,它直接计算输入之间的标量积。它没有向 SVM 添加任何额外的超参数,并且可以很好地看到调节余量的超参数𝐶的效果。
接下来的图显示了在训练数据集上使用线性核训练 SVM 的结果
作者图片
背景色代表 SVM 的决定。训练数据集被表示为平面中的点,并且它们的类也用颜色表示。突出显示的点代表支持向量,即定义超平面的数据点。虚线代表 SVM 的边缘。在每个图的上方,您可以找到该 SVM 在验证数据集上的 R2 分数以及所用超参数的值。
如图所示,增加超参数 𝐶 的效果是使边缘更紧,因此,需要更少的支持向量来定义超平面。
RBF 核函数(径向基函数)
作者图片
该函数为调谐𝛾.增加了一个额外的超参数但是,与线性核函数的情况不同,该函数将数据映射到更高维度。从下图中可以看出,现在 SVM 可以表示非线性分离。
作者图片
从上到下,我们可以看到增加超参数𝐶的效果,如前所述,这会影响 SVM 的余量。
另一方面,从左到右,我们可以看到增加𝛾 的效果:较低的值导致分色看起来更线性,随着 𝛾 的增加,它导致更复杂的分色。
在𝛾足够高的情况下,训练集的每个观测值都是支持向量。换句话说,每个训练点都用于定义超平面,这表明明显的过拟合。此外,使用的支持向量越多,SVM 的计算开销就越大,并且它需要更多的时间来进行预测。
最后,有趣的是注意到,在数据的原始维度中观察分离,它看起来像高斯,就像核函数公式看起来像高斯一样。
Sigmoid 核函数
作者图片
在这个函数中有两个额外的超参数:𝑟和另一个也称为𝛾的超参数,正如下面可以看到的,它也影响分离的复杂性。
作者图片
现在,𝐶超参数已被修复,因为如上所示,它会影响边距。从上到下可以看到改变 𝛾 的效果,这有助于使分离变得更加复杂,因为它增加了,就像 RBF 核函数一样。
𝑟超参数变化不大,视觉效果不太清晰。但是看函数定义,tanh(γxi⋅xj + r),这个常数 𝑟 的作用是移动双曲正切:
作者图片
𝑟常数的较大正值和负值支配着结果,这使得标量积更难对函数的结果产生影响。****
如果我们将标量积解释为两个向量之间相似性的度量,那么核函数也表示相似性。因此,我们可以把𝑟的这种效应解释为使结果有偏差,如果我们知道某个类比另一个类更受偏爱,这是很有用的?
多项式核函数
作者图片
这最后一个核函数有三个超参数:影响标量积的因子𝛾、常数𝑟和多项式的次数𝑑.
作者图片
从上到下可以看出,增加多项式次数和 𝛾 的效果是进行更复杂的分离。
从左到右可以看出,改变 𝑟 的效果看起来类似于 sigmoid 函数中的 𝑟 所发生的情况,至少对于多项式的较低次而言是如此。
结论
本文首先简要介绍了支持向量机,然后介绍了使用的数据集。然后,它显示了在原始数据的维度上,改变最常见的核函数的超参数的视觉效果。这些影响可以根据视觉直觉分为两类:它们影响 SVM 的边缘和/或它们影响分离的非线性。
通常建议使用 RBF 核作为“go-to”核函数,因为它只有两个超参数需要调整,并且可以模拟非线性分离。但是,正如许多事情一样,这可能不是任何任务的完美核函数,根据数据,可能有一个核函数可以更好地模拟类之间的分离。希望这篇文章给读者一种直觉,帮助他们选择要使用的核函数和/或更好地理解支持向量机🙂
感谢
特别感谢安吉尔·伊加丽塔在本文发表前审阅了本文😊
感谢您阅读本文!😄有反馈吗?非常感谢🙂请在这里的评论中,或者在笔记本上,甚至在 LinkedIn 上自由分享你的想法!
祝您愉快!🙂
可视化 MLP:变换的组合
如何绘制非线性决策边界
介绍
神经网络通常被视为从数据中“学习”的黑盒。但是他们的重量实际上在学习什么呢?简而言之,他们正在学习以特定的方式操作向量空间。虽然这不是一个新的想法,但它是一个核心概念,在我打算阐述的课程中经常被忽略。在本文中,我将关注多层感知器,并理解一个复杂的决策边界是如何从一系列转换中形成的。
基本向量
在深入研究神经网络操作之前,我们需要一本线性代数入门书。
作者图片
什么是基矢?
基向量是坐标空间中独立的单位向量。在上图中,有两个基本向量定义了我们的 2D 平面:I 和 j。向量 I 的值为[1 0],向量 j 的值为[0 1]。如上所述,平面上的所有其他矢量都可以表示为基本矢量的线性组合。这样,它们定义了坐标空间。
作者图片
让我们将两个基向量重新组织成一个矩阵,以加强这一想法,其中顶行包含向量 I,底行包含向量 j。如果我们取向量[3 ^ 2]和基向量矩阵的乘积,那么我们得到该向量在矩阵中的基向量所定义的坐标空间中的嵌入。虽然这听起来很抽象,但是通过下面的方式,这个想法是非常清晰的。
变换
为了更好地理解基向量如何定义坐标空间,让我们看看当我们改变基向量时会发生什么。
作者图片
向量 I 现在在[1 ^ 2],向量 j 现在在[2 ^ 1]。在视频中,我们可以看到改变基向量如何通过线性变换来操纵坐标空间,这正是神经网络所做的。有关更深入的描述,请参见 3blue1brown 关于线性变换的视频。
线性图层
作者图片
现在我们已经掌握了一些线性代数的基础知识,让我们来看看一个基本的线性层。在这种情况下,所有输入神经元通过明显学习的权重连接到所有输出神经元。所以每个输出神经元就是输入向量和权重向量的点积。我们可以将权重向量组织成矩阵 W,然后与输入向量 x 相乘,而不是单独编写所有这些内容。在这里,我们可以将 W 视为基本向量的矩阵,我们已经看到了更改这些值会对坐标空间产生什么影响。
但是偏见有什么作用呢?
类似于直线的方程,这里的偏差移动原点。在上面的示例中,对上述变换应用了[1,1]偏差。
激活功能
作者图片
激活函数通常紧接在上述线性变换之后。在这里,我们将研究双曲正切函数,它独立作用于每个输出神经元。该函数将线性运算的输出从-1 限制到 1。
众所周知,非线性在神经网络中起着重要作用,尤其是在绘制决策边界方面。但是他们实际上是如何划分这些界限的呢?他们通过变换坐标空间来实现。在上面的视频中,我们可以看到双曲正切函数是如何扭曲坐标空间的。当需要收缩或扩展不同的区域时,这种类型的行为非常有益。稍后对整个网络的可视化将阐明这一点。
MLP 背后的直觉
既然我们已经介绍了线性图层的每个组件,那么多个图层如何一起工作呢?直观上,在 N 层的 MLP 中,前 N-1 层用于变换坐标空间,以使第 N 层更容易线性分离数据。我选择 MLP 作为基本案例来表达这个想法,因为它是最清晰的,但它可以很容易地显示其他运营商如何以不同的方式操纵坐标空间。
线性回归决策边界
我们已经了解了线性图层如何转换坐标空间,但现在让我们关注它如何绘制决策边界。Thomas Countz 在这里对单层感知器进行了详细的分析:
总而言之,最终线性层中的权重向量(对于给定的输出神经元)定义了与决策边界正交的超平面,并且从该超平面,我们可以得到决策边界的方程如下:
- b + w1x + w2y = 0
- x 截距= (0,-b / w2)
- y 轴截距= (-b / w1,0)
- m = -(b / w2) / (b / w1)
- y = (-(b / w2) / (b / w1))x + (-b / w2)
将它整合在一起
最后,我们可以充分了解 MLP 的运作。在上面的例子中,我们设想了一个四层的 MLP,每层分别有(2,2,2,1)个神经元。该网络在一个 2 类非线性可分螺旋数据集上进行训练,以突出显示该网络如何操纵原始坐标空间来使这两个类线性可分。
画好线后,通过反向操作将网络向后滚动到原始坐标空间。通过这个过程,我们可以看到潜在空间中的线是如何变成原始空间中的非线性决策边界的。
摘要
在这篇文章中,我简要介绍了从拓扑学的角度思考神经网络。我希望本教程对初学者有所启发,并且在设计新的架构时会更多地考虑组件的拓扑影响。
评论
本文旨在提供对神经网络如何运行的简化见解,因此我将这里省略的其他考虑留到以后的文章中。
所有的可视化都是通过开源软件 manim 的定制版本以编程方式产生的。
可视化美国石油管道网络
让我们用数据来理解殖民地管道在更大的美国石油产品管道网络中的作用。
美国主要的石油产品管道。来源:环评。图片来源:塞犍陀·维维克
最近殖民管道勒索软件网络攻击的影响遍及整个美国东南部。肇事者是一个著名的勒索软件组织,名为黑暗面,他们声称他们的目标从来不是扰乱社会:
“我们的目标是赚钱,而不是给社会制造问题。从今天起,我们引入了审核机制,并检查我们的合作伙伴想要加密的每家公司,以避免未来的社会后果。”
但是人们怀疑这是否完全正确。毕竟,黑暗面的总部设在俄罗斯,最近源于俄罗斯的网络安全管理软件产品网络攻击导致多个美国政府服务器被攻破。这一事件以及最近发生的其他事件表明,俄罗斯确实有兴趣破坏美国的网络,甚至是关键的基础设施网络,例如那些穿越美国大部分地区的燃料网络。
让我们更深入地了解一下美国石油产品管道网络。这将有助于理解殖民地管道的作用。此外,来自俄罗斯、朝鲜、伊朗和中国的民族国家网络攻击的增加意味着,未来美国可能面临有针对性的攻击的风险,其目的是最大限度地破坏社会秩序。在这种情况下,最好考虑关键基础设施中的漏洞,以便在网络攻击成功的情况下建立弹性。
可视化管道形状文件
import networkx as nx
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
import re
import matplotlib.colors as mcolors
import geopandas as gpd
import contextily as ctxshapefile = gpd.read_file('./PetroleumProduct_Pipelines_US_EIA/PetroleumProduct_Pipelines_US_202001.shp')
shapefile2=shapefile[shapefile['geometry'].notnull()]shapefile3=shapefile2.to_crs(epsg=3857).sample(frac=1) #projecting to Spherical Mercator projection coordinate system for subsequent plotting on mapfig=plt.figure()
ax=shapefile3.plot(column='Shape_Leng', cmap='jet',linewidth=3,figsize=(32,16))
plt.axis('off')
ctx.add_basemap(ax)
美国主要的石油产品管道。来源: EIA 。图片来源:塞犍陀·维维克
我从 EIA 网站获取了美国主要石油产品管道的数据,并使用 Python GeoPandas 包加载了 shapefile。你可以看到暗红色的最大管道,这是殖民地管道。对 5 个最大管道的进一步观察证实了这一点。第二长的是从美国中西部到加拿大阿尔伯塔省的 Southern Lights 管道,第三长的是从路易斯安那到华盛顿特区的种植园管道,除了稍微短一点之外,几乎与殖民地管道相同。
5 条最大的石油产品管道|塞犍陀维维克
将 Shapefiles 转换为网络
#using shapely to convert geometry into string format
from shapely import wkt
shapefile2['str_geom'] = shapefile2.geometry.apply(lambda x: wkt.dumps(x))
net = nx.Graph()
nt=0for i in range(0,len(shapefile2)):
a=np.zeros(len(shapefile2['str_geom'][i].split())-1) #e.g. 4 points with 8 coordinates means a has 8 values
nt+=len(a)/2
for j in range (0,len(a)):
a[j]=float(re.findall(r"[-+]?\d*\.\d+|\d+", shapefile2['str_geom'][i].split()[j+1])[0])
for k in range(0, int(len(a)/2)-1):
net.add_edge((a[2*k],a[2*k+1]),(a[2*k+2],a[2*k+3]))positions = {n: (n[0], n[1]) for n in list(net.nodes)}fig, ax = plt.subplots(figsize=(16,8))
ax.tick_params(left=True, bottom=True, labelleft=True, labelbottom=True)
nx.draw(net, positions, ax=ax, node_size=20)
plt.tight_layout()
节点和边的石油产品管道网络|塞犍陀·维韦克
每个 shapefile 行包含管道中点的坐标。我将每个点表示为一个节点,并通过边连接这些点,通过边使用 NetworkX Python 包构建网络。现在我们有了网络,我们可以运行一些经典的网络算法来发现哪些节点或管道段对于整个管道网络是至关重要的。
中心性度量
在图论和网络分析中,中心性度量确定节点在整个网络中的相对重要性。我将使用介数中心性,它是网络中一个节点对信息流(T3)(或者在这种情况下,石油流)的影响的量。中间中心性度量如下所示:
中间中心性|维基百科
在等式中,分子是节点 s 和 t 之间通过节点 v 的最短路径的数量,分母是 s 和t之间所有最短路径的数量,求和是对所有节点对进行的。在我们的例子中,中间中心性应该给出在更大的网络中哪个管道段对石油运输最重要的感觉。
fig, ax = plt.subplots(figsize=(16,8))ax.tick_params(left=True, bottom=True, labelleft=True, labelbottom=True)
nodes = nx.draw_networkx_nodes(net, positions,ax=ax, node_size=20, cmap=plt.cm.jet,node_color=list(nx.betweenness_centrality(net).values()),nodelist=nx.betweenness_centrality(net).keys())edges = nx.draw_networkx_edges(net, positions,ax=ax)
plt.axis('off')
plt.title('Betweenness Centrality')
plt.colorbar(nodes)
plt.tight_layout()
石油产品管道网络,由中间中心值着色的节点|塞犍陀·维韦克
具有最高介数中心性的节点位于南卡罗来纳州的殖民地管道的中心。这让我感到惊讶,因为我原以为最重要的节点可能位于更靠近美国地理中心的地方
结论
Colonial 管道的绝对长度以及中间中心性指标都将 Colonial 管道视为美国石油产品管道网络中最重要的资产。一个更大的问题是攻击者如何最大限度地破坏社会秩序,比如一个民族国家的行为。那些后果会是什么?我们已经看到了殖民地管道勒索软件攻击后几周的天然气供应中断和价格上涨。如果多条这样的管道被关闭,情况会是怎样?我们如何建立社会对成功攻击的弹性?
我们可以通过多维数据源和灾难期间的点点滴滴来学习很多东西,以便在未来,我们作为一个社会有更好的准备。在殖民地管道网络攻击的案例中:管道网络、炼油厂和存储位置、运输供应链以及短缺加油站的位置可以帮助理解事件链。这一认识将使我们为未来的网络攻击做好更充分的准备。
总之——要让社会抵御网络攻击,还有很多事情要做。但我认为第一步在于量化复杂的社会对这种攻击的脆弱性。不幸的是(或者是故意的)——在 Colonial pipeline 事件中,数据明确显示,攻击关闭了整个美国石油产品管道网络中最重要的管道,导致几周的天然气短缺。
有兴趣的话,下面详细介绍一下带代码的 Google Colab 笔记本。
https://colab.research.google.com/drive/1FaK2wiUV_3MqJViGS1m-xQYPUXGG5EaT?usp=sharing 如果你喜欢这篇文章——我经常写复杂系统、物理学、数据科学和社会的界面
使用 Welly Python 库可视化井眼轨迹
使用 Matplotlib 创建 3D 线图以可视化井眼轨迹
显示从 Welly Python 库生成的井眼轨迹位置的 3D 线图。图片由作者提供。
测井中使用多个深度参考来表示沿井筒的位置。这些包括测量深度(MD)、真实垂直深度(TVD)、真实水下垂直深度(TVDSS)等。所有这些都是油井成功开发和完井的关键衡量标准。
显示 MD、TVD 和 TVDSS 之间差异的图示。图片来源:http://petroleum-companies . blogspot . com/2013/12/diffused-well-directional . html
上图展示了本文中提到的关键深度参考。
- 测量深度(MD)是沿井眼长度测量的井眼长度。
- 真实垂直深度(TVD),是基准面(如转盘)和井筒中一点之间的绝对垂直距离。
- 海底真实垂直深度(TVDSS),是平均海平面和井筒中某点之间的绝对垂直距离。
当井是垂直的时,MD 等于从同一基准面测量的 TVD。在井斜的情况下,TVD 值变得小于 MD 值。
大多数 LAS 文件都参考测量深度,通常不包含 TVD 曲线。因此,我们必须用一些数学来计算 TVD。为此,我们需要井的倾斜度,即井眼与垂直方向的偏差,我们还需要方位角,测量井眼轨迹相对于北方的方向。
在本文中,我们不会关注 TVD 背后的计算,相反,我们将了解如何使用 Welly 的位置模块来计算它。如果你想知道更多关于计算背后的数学知识,我在下面的描述中提供了一些文章的链接。
https://www.drillingformulas.com/minimum-curvature-method/
视频版教程
如果你喜欢跟随视频,你可以在我的 YouTube 频道找到它。
Python 教程
导入库和加载数据
让我们从导入将要使用的库开始。这些是来自 welly 图书馆和熊猫图书馆的位置和井模块。
from welly import Location
from welly import Well
import pandas as pd
一旦我们导入了这些,我们就可以加载数据了。本例中使用的数据来自北海的荷兰部分,可以在 NLOG 网站或我的 Github Repo 上找到。
data = Well.from_las('Netherlands Data/L05-15-Spliced.las')
检查数据
如果我们调用刚刚创建的data
变量,我们可以得到油井的摘要。我们可以看到井的名称、位置以及文件中包含的数据信息。
使用 Python Welly 库生成的井的摘要(图片由作者提供)
如果我们想更仔细地查看数据,我们可以调用我们的 well 对象,后跟.data
。这提供了一个包含曲线助记符以及前 3 行和后 3 行中包含的值的 dictionary 对象。不出所料,大部分数据都丢失了。
data.data{'BHT': Curve([nan, nan, nan, ..., nan, nan, nan]),
'CAL': Curve([nan, nan, nan, ..., nan, nan, nan]),
'CHT': Curve([nan, nan, nan, ..., nan, nan, nan]),
'CN': Curve([nan, nan, nan, ..., nan, nan, nan]),
'CNC': Curve([nan, nan, nan, ..., nan, nan, nan]),
'CNCQH': Curve([nan, nan, nan, ..., nan, nan, nan]),
'CNQH': Curve([nan, nan, nan, ..., nan, nan, nan]),
'GR': Curve([nan, nan, nan, ..., nan, nan, nan]),
'MBVI': Curve([nan, nan, nan, ..., nan, nan, nan]),
'MBVM': Curve([nan, nan, nan, ..., nan, nan, nan]),
'MCBW': Curve([nan, nan, nan, ..., nan, nan, nan]),
'MPHE': Curve([nan, nan, nan, ..., nan, nan, nan]),
'MPHS': Curve([nan, nan, nan, ..., nan, nan, nan]),
'MPRM': Curve([nan, nan, nan, ..., nan, nan, nan]),
'PEQH': Curve([nan, nan, nan, ..., nan, nan, nan]),
'PORZ': Curve([nan, nan, nan, ..., nan, nan, nan]),
'PORZC': Curve([nan, nan, nan, ..., nan, nan, nan]),
'TEN': Curve([nan, nan, nan, ..., nan, nan, nan]),
'TTEN': Curve([nan, nan, nan, ..., nan, nan, nan]),
'WTBH': Curve([ nan, nan, 87.943, ..., nan, nan, nan]),
'ZCORQH': Curve([nan, nan, nan, ..., nan, nan, nan]),
'ZDEN': Curve([nan, nan, nan, ..., nan, nan, nan]),
'ZDENQH': Curve([nan, nan, nan, ..., nan, nan, nan]),
'ZDNC': Curve([nan, nan, nan, ..., nan, nan, nan]),
'ZDNCQH': Curve([nan, nan, nan, ..., nan, nan, nan])}
理解数据内容的更好方法是查看测井曲线。我们可以通过调用data.plot
并设置曲线范围的关键字参数来实现。我们可以生成一个从第一个测量值开始到最后一个测量值的图。
data.plot(extents='curves')
这将返回以下图。该图允许我们快速查看每个测井测量的内容及其特征,如果数据中存在大量曲线,则很难查看。
在本文中,我们不会对测井数据进行绘图,但是如果您感兴趣,请务必查看我在 welly 系列中的 YouTube 视频,在该视频中,我重点介绍了单井和多井的工作。
Welly 生成的显示井内容的测井图。图片由作者提供。
使用测量数据和 Welly
导入调查数据
现在我们已经加载了日志数据,我们可以开始加载调查数据了。
在钻井过程中,通常以不规则的间隔测量勘测数据。它给出了测量时测量深度(MD)、倾角(INC)和方位角(AZI)的快照。由此,我们可以计算出油井原点的真实垂直深度(TVD)、x 偏移和 y 偏移。
通常,数据以表格或 CSV 格式提供。要加载 CSV 数据,我们可以使用pd.read_csv()
并传入文件的位置及其名称。
survey = pd.read_csv('Netherlands Data/L05-15-Survey.csv')
当我们调用调查对象时,我们看到返回了一个包含关键井位置信息的数据帧。
熊猫数据框中的井调查数据。图片由作者提供。
Welly 要求勘测数据包含测量的深度、倾斜度和方位角。这允许库计算 TVD、X 偏移和 Y 偏移。
我们可以通过调用调查数据框架并使用方括号传入所需列名的列表来对数据进行子集化。
survey_subset = survey[['MD', 'INC', 'AZI']]
当我们调用survey_subset
时,我们得到下面的数据帧。
准备好要导入 Welly Python 库的测量数据。图片由作者提供。
向油井添加测量数据
从 CSV 文件中加载调查数据后,我们需要计算我们的位置参数。默认情况下, Welly 被设置为使用最小曲率法计算这些,这是最常见和最精确的方法。
有关此方法的更多信息,请访问https://petro wiki . SPE . org/Calculation _ methods _ for _ directional _ survey
要将测量数据添加到井中,我们可以调用以下内容
#Add deviation data to a well
data.location.add_deviation(survey_subset.values)
既然勘测数据已经加载到我们的 Welly well 对象中,我们可以调用data.location.position
来查看数据。对于这个例子,我使用切片符号只返回数据的前 5 行。
#View first five rows of the data
data.location.position[:5]
返回的数组格式为:X 轴偏移量、Y 轴偏移量和 TVD。
array([[ 0\. , 0\. , 0\. ],
[ 0\. , 0\. , 89.3 ],
[ -0.6333253 , 0.8552655 , 142.08569704],
[ -1.59422229, 2.03112298, 170.14372544],
[ -3.19869524, 3.75201703, 197.74222054]])
我们可以通过分割数组将每个位置参数提取到变量中。这是通过使用方括号并使用冒号(:)后跟数组中的列来选择所有行来完成的。
x_loc = data.location.position[:,0]
y_loc = data.location.position[:,1]
z_loc = data.location.position[:,2]
如果我们调用 z_loc,它是我们的 TVD,我们得到下面的数组:
array([ 0\. , 89.3 , 142.08569704, 170.14372544,
197.74222054, 225.68858529, 254.17872844, 282.83986178,
311.3294853 , 339.82739229, 368.42706739, 396.92691062,
425.62638313, 454.22551155, 482.42473573, 511.12342097,
539.72042719, 568.21483874, 597.00539705, 625.8900492 ,
654.36614119, 683.22656973, 711.6691264 , 740.00649462,
767.54748074, 797.06893638, 825.36408467, 853.83548556,
882.30553194, 910.5784206 , 939.03148052, 967.35658945,
995.56380403, 1023.95695144, 1052.22740711, 1080.54668678,
1108.68959153, 1136.6589388 , 1164.87003188, 1192.91335907,
1220.78632672, 1248.71483434, 1276.69724251, 1304.38501765,
1332.02759325, 1359.48829109, 1386.59399864, 1413.47807554,
1440.51055639, 1467.37758752, 1494.27990524, 1521.15255355,
1547.94826077, 1574.81148851, 1601.67556214, 1628.46190115,
1655.38744119, 1682.77094459, 1709.94467279, 1737.02953371,
1764.09191195, 1791.3868565 , 1818.75450935, 1845.99897829,
1873.48895669, 1900.86728951, 1928.20315443, 1955.1719983 ,
1982.16522007, 2009.02433087, 2035.75920778, 2062.44460278,
2088.89113734, 2115.18715337, 2141.53399746, 2167.86835015,
2194.17601217, 2220.34087524, 2246.65950847, 2273.26101123,
2300.13882036, 2326.97261339, 2353.95042418, 2380.81977995,
2407.70173751, 2434.4676547 , 2460.90920154, 2472.20902514,
2498.66491934, 2525.74629926, 2553.35452297, 2579.86481719,
2606.67927736, 2634.67341768, 2663.73057678, 2690.48389425,
2716.3110963 , 2743.39559139, 2770.53319932, 2798.10117685,
2824.99473242, 2851.85337513, 2879.55133503, 2906.56976579,
2933.96384651, 2960.25680057, 2986.50202763, 3013.35506117,
3039.2427437 , 3065.81112303, 3078.05551274, 3096.92997476])
我们也可以通过调用data.location.tvd.
来访问相同的数据
array([ 0\. , 89.3 , 142.08569704, 170.14372544,
197.74222054, 225.68858529, 254.17872844, 282.83986178,
311.3294853 , 339.82739229, 368.42706739, 396.92691062,
425.62638313, 454.22551155, 482.42473573, 511.12342097,
539.72042719, 568.21483874, 597.00539705, 625.8900492 ,
654.36614119, 683.22656973, 711.6691264 , 740.00649462,
767.54748074, 797.06893638, 825.36408467, 853.83548556,
882.30553194, 910.5784206 , 939.03148052, 967.35658945,
995.56380403, 1023.95695144, 1052.22740711, 1080.54668678,
1108.68959153, 1136.6589388 , 1164.87003188, 1192.91335907,
1220.78632672, 1248.71483434, 1276.69724251, 1304.38501765,
1332.02759325, 1359.48829109, 1386.59399864, 1413.47807554,
1440.51055639, 1467.37758752, 1494.27990524, 1521.15255355,
1547.94826077, 1574.81148851, 1601.67556214, 1628.46190115,
1655.38744119, 1682.77094459, 1709.94467279, 1737.02953371,
1764.09191195, 1791.3868565 , 1818.75450935, 1845.99897829,
1873.48895669, 1900.86728951, 1928.20315443, 1955.1719983 ,
1982.16522007, 2009.02433087, 2035.75920778, 2062.44460278,
2088.89113734, 2115.18715337, 2141.53399746, 2167.86835015,
2194.17601217, 2220.34087524, 2246.65950847, 2273.26101123,
2300.13882036, 2326.97261339, 2353.95042418, 2380.81977995,
2407.70173751, 2434.4676547 , 2460.90920154, 2472.20902514,
2498.66491934, 2525.74629926, 2553.35452297, 2579.86481719,
2606.67927736, 2634.67341768, 2663.73057678, 2690.48389425,
2716.3110963 , 2743.39559139, 2770.53319932, 2798.10117685,
2824.99473242, 2851.85337513, 2879.55133503, 2906.56976579,
2933.96384651, 2960.25680057, 2986.50202763, 3013.35506117,
3039.2427437 , 3065.81112303, 3078.05551274, 3096.92997476])
创建位置图
为了了解井的位置,我们可以看三幅图。
- x 偏移与 Y 偏移(地形图)
- x 偏移与 TVD
- y 偏移与 TVD
为了创建这些图,我们可以使用 matplotlib 并使用 subplot2grid 创建多个图。
import matplotlib.pyplot as plt
fig, ax = plt.subplots(figsize=(15,5))
ax1 = plt.subplot2grid(shape=(1,3), loc=(0,0))
ax2 = plt.subplot2grid(shape=(1,3), loc=(0,1))
ax3 = plt.subplot2grid(shape=(1,3), loc=(0,2))
ax1.plot(x_loc, y_loc, lw=3)
ax1.set_title('X Location vs Y Location')
ax2.plot(x_loc, z_loc, lw=3)
ax2.set_title('X Location vs TVD')
ax3.plot(y_loc, z_loc, lw=3)
ax3.set_title('Y Location vs TVD')Text(0.5, 1.0, 'Y Location vs TVD')
这将返回我们的三个井剖面图。
使用 matplotlib 和 Welly 生成的油井剖面。图片由作者提供。
请注意,这两个 TVD 图是颠倒的,我们将使用ax.invert_yaxis()
进行排序。
为井的起点和终点添加标记
我们可以在图中添加标记,以显示井的起始位置(黑色方块)和结束位置(红星)。此外,我们将反转两个 TVD 图的 y 轴。
fig, ax = plt.subplots(figsize=(15,5))
ax1 = plt.subplot2grid(shape=(1,3), loc=(0,0))
ax2 = plt.subplot2grid(shape=(1,3), loc=(0,1))
ax3 = plt.subplot2grid(shape=(1,3), loc=(0,2))
ax1.plot(x_loc, y_loc, lw=3)
ax1.plot(x_loc[0], y_loc[0], marker='s', color='black', ms=8)
ax1.plot(x_loc[-1], y_loc[-1], marker='*', color='red', ms=8)
ax1.set_title('X Location vs Y Location')
ax2.plot(x_loc, z_loc, lw=3)
ax2.plot(x_loc[0], z_loc[0], marker='s', color='black', ms=8)
ax2.plot(x_loc[-1], z_loc[-1], marker='*', color='red', ms=8)
ax2.invert_yaxis()
ax2.set_title('X Location vs TVD')
ax3.plot(y_loc, z_loc, lw=3)
ax3.plot(y_loc[0], z_loc[0], marker='s', color='black', ms=8)
ax3.plot(y_loc[-1], z_loc[-1], marker='*', color='red', ms=8)
ax3.invert_yaxis()
ax3.set_title('Y Location vs TVD')Text(0.5, 1.0, 'Y Location vs TVD')
使用 matplotlib 和 Welly 生成的油井剖面。还标记了孔的开始(黑色方块)和结束(红星)位置。图片由作者提供。
与原始调查进行比较
幸运的是,我们有一个包含位置参数和 TVD 的测量文件,但情况可能并不总是如此。通过将数据添加到我们的图中,我们可以快速检查 Welly 计算的数据和 CSV 文件中包含的数据。
fig, ax = plt.subplots(figsize=(15,5))
ax1 = plt.subplot2grid(shape=(1,3), loc=(0,0))
ax2 = plt.subplot2grid(shape=(1,3), loc=(0,1))
ax3 = plt.subplot2grid(shape=(1,3), loc=(0,2))
ax1.plot(x_loc, y_loc, lw=7)
ax1.plot(x_loc[0], y_loc[0], marker='s', color='black', ms=8)
ax1.plot(survey['X-offset'], survey['Y-offset'])
ax1.plot(x_loc[-1], y_loc[-1], marker='*', color='red', ms=8)
ax1.set_title('X Location vs Y Location')
ax2.plot(x_loc, z_loc, lw=7)
ax2.plot(x_loc[0], z_loc[0], marker='s', color='black', ms=8)
ax2.plot(survey['X-offset'], survey['TVD'])
ax2.plot(x_loc[-1], z_loc[-1], marker='*', color='red', ms=8)
ax2.invert_yaxis()
ax2.set_title('X Location vs TVD')
ax3.plot(y_loc, z_loc, lw=7)
ax3.plot(y_loc[0], z_loc[0], marker='s', color='black', ms=8)
ax3.plot(survey['Y-offset'], survey['TVD'])
ax3.plot(y_loc[-1], z_loc[-1], marker='*', color='red', ms=8)
ax3.invert_yaxis()
ax3.set_title('X Location vs TVD')Text(0.5, 1.0, 'X Location vs TVD')
创建井眼轨迹的 3D 图
我们可以使用 matplotlib 以三维方式查看数据,而不是以二维方式查看数据。但首先,我们要计算连续的数据。这是通过使用location.trajectory()
来完成的。这里我们可以提供一个数据,即地面井位的 UTM 坐标和一个垂直偏移。
如果我们看看 NLOG 网站上的下图,我们就有了油井的精确表面坐标
我们将在location.trajectory()
功能中使用交付的位置坐标。
# Create a trajectory of regularly sampled points
location_data = data.location.trajectory(datum=[589075.56, 5963534.91, 0], elev=False)xs = location_data[:,0]
ys = location_data[:,1]
zs = location_data[:,2]plt.plot(xs, ys)
plt.xlabel('X Location')
plt.ylabel('Y Location')
plt.ticklabel_format(style='plain')
plt.grid()
当我们运行此代码时,我们现在有了油井的地形图,这些值反映了油井的真实坐标。
使用参考基准面的 Welly Python 库创建的井眼轨迹计划。图片由作者提供。
创建 3D 绘图
现在,井位已经参考了基准面,我们可以继续绘制井眼轨迹了。不需要应用前面的步骤,您可以使用 x、y 和 z 位置进行查看
为了创建 3D 绘图,我们需要从mpl_toolkits.mplot3d
导入 Axes3D,然后当我们需要启用 3D 绘图时,使用一个神奇的 Jupyter 命令:%matplotlib widget
。
然后,我们创建图形并将投影设置为 3d,如下面的代码所示。
from mpl_toolkits.mplot3d import Axes3D# Enable 3D Ploting
%matplotlib widgetfig = plt.figure(figsize=(8, 8))
ax = plt.axes(projection='3d')
ax.plot3D(xs, ys, zs, lw=10)
ax.set_zlim(3000, 0)
ax.set_xlabel('X Location')
ax.set_ylabel('Y Location')
ax.set_zlabel('TVD')
plt.ticklabel_format(style='plain')
plt.show()
用 Welly 和 Matplotlib 创建的交互式 3D 井眼轨迹。图片由作者提供。
摘要
在这个简短的教程中,我们已经了解了如何将原始井测量数据与井井对象相结合,以及如何在平面图和侧视图中显示井井轨迹。我们还看到了如何使用 matplotlib 在 3D 中可视化井眼轨迹。这样,我们可以更好地了解井眼轨迹。
感谢阅读!
如果您觉得这篇文章有用,请随时查看我的其他文章,这些文章介绍了 Python 和测井数据的各个方面。你也可以在GitHub找到我在这篇文章和其他文章中使用的代码。
如果你想联系我,你可以在LinkedIn或者我的 网站 找到我。
有兴趣了解更多关于 python 和测井数据或岩石物理学的知识吗?跟我上 中 。
如果你喜欢阅读这些教程,并想支持我作为一名作家和创作者,那么请考虑报名成为一名媒体成员。一个月 5 美元,你就可以无限制地阅读数千篇各种主题的文章。如果您使用 我的链接 **,**注册,我将为您赚取一小笔佣金,无需额外费用!
https://andymcdonaldgeo.medium.com/membership
使用 expert.ai 可视化文档的真实内容
关于如何使用 expert.ai NL API 检索和可视化文本文档中隐藏的相关数据的简短教程。
如果您曾经处理过文本数据集,您就会知道在数据集中检索中心信息、避免干扰或冗余是多么困难。如果你想训练你自己的模型,很多方法都可以得到很好的结果,但是这需要时间和资源。在下面的教程中,我们将探索如何使用 expert.ai NL API Python SDK 检索文本中的隐藏信息,这不需要模型训练,然后将结果可视化为可以添加到报告中的图表。
什么是 expert.ai NL API?
expert.ai 自然语言 API 是由 expert.ai 开发的服务,可用于轻松构建 NLP 应用程序。该库包括多种功能,如 NLP 管道(标记化、词汇化、词性标注、依存解析、句法解析、词义消歧)和即用型 IPTC 媒体主题分类器、地理分类和情感分析。命名实体识别(NER)也被执行,其中实体被链接到它们在公共知识库(例如,Wikidata、GeoNames、DBpedia)中的唯一标识。对于任何对自然语言处理感兴趣的人来说,expert.ai NL API 都是一个有用的工具,因为它易于使用并且提供了广泛的功能。该技术由 expert.ai 开发,该公司在提供语言解决方案方面拥有 20 多年的经验,这使得该 API 非常适合任何有兴趣构建业务就绪型解决方案的人。
第一步:安装 expert.ai NL API python SDK
在本教程中,我们将使用用于 expert.ai 自然语言 API 的 Python 客户端来为 Python 应用程序添加自然语言理解功能。
您可以使用pip
来安装库:
$ pip install expertai-nlapi
建立
要使用 expert.ai NL API,您需要在 expert.ai 开发者门户上创建您的凭证。Python 客户端代码期望 expert.ai 开发人员帐户凭据作为环境变量可用:
- Linux:
**export** EAI_USERNAME**=**YOUR_USER
**export** EAI_PASSWORD**=**YOUR_PASSWORD
- Windows 操作系统
SET EAI_USERNAME**=**YOUR_USER
SET EAI_PASSWORD**=**YOUR_PASSWORD
您也可以在代码中定义它们:
**import** os
os.environ["EAI_USERNAME"] **=** YOUR_USER
os.environ["EAI_PASSWORD"] **=** YOUR_PASSWORD
第二步:关键要素
现在,我们可以在一组文档上使用开箱即用特性来检索它们的关键元素。
首先:导入库并初始化对象。
然后,设置文本和语言:
我们可以执行第一次分析,简单地看一下文档的内容。关键元素通过relevants
分析获得,并在文档中被识别为主句、主要概念(称为“同步子”)、主要引理和相关主题:
expert.ai 引擎执行词义消歧,这要归功于一个专有的知识图,它存储了每种语言的所有概念。这有助于引擎理解文档中出现的概念。
注意概念和引理的不同。一个概念可以用一个或多个同义词来表示。例如,如果我们在文本中找到 home 和 house ,expert.ai 技术理解这两个词条具有相同的含义,并为它们分配概念的首选标签——在这种情况下将是 house 。
让我们看看在之前的文本中找到的最相关的概念,以及它们的相关性分数:
CONCEPT SCORE
startup company 42.59
Facebook Inc. 41.09
Springfield 14.89
American 1.1
我们可以对一组文档做同样的事情,为每个文档检索相关的概念,并将它们聚合起来:
然后,我们可以在条形图中显示结果,选择在我们的数据集中更常见的 20 个最常见的概念:
文档中 20 个最常见概念的条形图
第三步:文件分类
现在,我们将学习如何根据自然语言 API 提供的 IPTC 媒体主题分类法对文档进行分类。我们首先从一个示例文本开始,看看如何设置一切,然后在数据集上执行相同的操作。
我们现在可以请求根据 IPTC 媒体主题类别对之前的文本进行分类:
对于每个类别,我们可以在文本中看到其标签、唯一 ID 和频率 whitin:
CATEGORY IPTC ID FREQUENCY
Earnings 20000178 29.63
Social networking 20000769 21.95
通过数据集上的这一新功能,我们可以检索和收集文档中触发的所有 IPTC 媒体主题类别:
现在,在collection_of_categories
中,我们找到了每一个 IPTC 媒体主题类别以及找到它的文档数量。我们现在可以看到数据集主题的标签云:
IPTC 媒体话题类词云
全部代码可在这里获得。
结论
借助 expert.ai 技术,可以轻松访问文本中隐藏的信息,如最重要的概念或它们描述的主题。正如我们所见,从安装到有意义数据的可视化只需要几分钟!
我们希望您喜欢本教程,并期待了解您使用 expert.ai NL API 执行的文本探索。
视觉上吸引人的进度条
使用 tqdm 在 python 中创建进度条
沃洛季米尔·赫里先科在 Unsplash 上的照片
当我们想要测量特定函数或代码块的进度时,进度条非常重要。它允许我们可视化我们的代码已经运行了多少,或者告诉我们在运行时代码中是否有错误。它还允许我们查看代码块的剩余执行时间。
我们可以在 python 中使用不同的 or 库创建进度条,其中之一就是 tqdm。这是一个开源的 python 库,用于创建视觉上吸引人的进度条。Tqdm 来源于一个阿拉伯语单词,意思是进步。它很容易创建进度条,并且可以将任何代码块包装在里面。
在本文中,我们将看到一些可以使用 tqdm 创建的基本进度条。
让我们开始吧…
安装所需的库
我们将从使用 pip 安装 tqdm 开始。下面给出的命令可以做到这一点。
pip install tqdm
导入所需的库
在这一步中,我们将导入创建进度条所需的库。在这篇文章中,我将向你展示如何使用 tqdm 和 tqdm_notebook 创建一个进度条。
创建进度条
在这一步中,我们将看到使用 tqdm 创建进度条是多么容易。
for i in tqdm(range(10)): time.sleep(0.5)
进度条(来源:作者)
同样,我们也可以使用 tqdm_notebook 创建一个进度条。
for i in tqdm_notebook(range(10)): time.sleep(0.5)
进度条(来源:作者)
当代码执行过程中出现错误或者我们不小心停止了它时,它看起来就像下面给出的图像。
错误(来源:作者)
类似地,您可以在任何函数、循环或代码块中添加进度条,并分析特定代码块的时间和进度。您也可以在创建 python 应用程序时使用它。
继续尝试不同的代码块,创建漂亮的进度条。如果您发现任何困难,请在回复部分告诉我。
本文是与皮尤什·英格尔合作完成的。
在你走之前
感谢 的阅读!如果你想与我取得联系,请随时通过 hmix13@gmail.com 联系我或我的 LinkedIn 个人资料 。可以查看我的Github简介针对不同的数据科学项目和包教程。还有,随意探索 我的简介 ,阅读我写过的与数据科学相关的不同文章。
增强 Git 工作流的重要命令
一些 git 提示和技巧来提高您的贡献和协作能力
作为一名软件工程师、设计师、开发人员,或者你选择的其他身份,你的工具包中最重要的一项是版本控制系统,特别是 git。
作为开发人员,git 是我们的保险单,也是协作的强大工具。但是,重要的是,除了简单的提交或推送之外,我们很多人都不知道自己到底在做什么。
但是请不要担心,我将带您快速浏览一些您在现实世界中会遇到的常见场景,以及一些帮助您应对这些场景的简单解决方案。
观众
对于那些已经理解 git 作为工作流的一部分的重要性并对提高他们的生产力感兴趣的用户来说,这篇文章将是最有帮助的。如果你对使用 Git 的好处感兴趣,我强烈建议为什么使用 Git 以及如何作为数据科学家使用 Git。
背景
我在这里分享的方法是在以下假设下运行的,但也可能适用于其他情况。
- 你和其他人一起工作。
- 您在一个从“主”存储库中派生出来的存储库上工作,而其他人从他们的派生中贡献出来。
- 你是唯一一个使用叉子的人。(极其重要:其中一些方法将改写历史。如果你在共享回购中搞乱了历史,这对你的合作伙伴来说可能是一件痛苦的事情。)
如何下载私人回购?(Github)
方案
你刚刚开始与一个新的组织合作,并且你很兴奋开始建立一些令人惊奇的东西。您尝试克隆存储库,但是哦,不——您遇到了一个小问题
fatal: repository 'https://github.com/user/project.git/' not found
那么,我们该如何度过这一关呢?
首先,您需要为 Github 设置一个个人访问令牌。您可以使用下面的链接找到相关说明。
现在您已经有了令牌,您可以运行以下命令来克隆 repo。
git clone https://<TOKEN>@github.com/<USERNAME>/<REPO>.git
准备好开始贡献吧!
如何使分叉回购中的分支与原始回购中的分支完全匹配?
方案
假设我们有一个名为 **dev 的分支。**在这个场景中, dev 是主要的分支,贡献者在这里合并来自原始 repo 的变更。因此,您希望将分叉回购中的本地 dev 分支与原始回购中的 dev 分支上的最新变更同步。
好的,这是一个相当简单的方法,如果你在一个快速发展的团队中,你会发现自己每天都在使用它。
首先,您需要确保获取最新的更改。
git fetch upstream/dev
此后,您可以硬重置本地分支,以匹配上游分支的状态。
git reset --hard upstream/dev
完全匹配。
怎么取别人的 PR(拉取请求)?
方案
您的开发伙伴对代码做了一个小而重要的更改,从他们的 repo 向主 repo 提交了一个 PR,并希望您帮助测试这些更改。所以你需要在你的机器上获得他们的代码,这样你就可以在本地测试它。
这是你怎么做的!
git fetch upstream pull/ID/head:#username
这里的 ID 是拉请求的 ID,而#username 是您试图获取其代码的开发人员的用户名。例如,假设您的好友 JaneSmith 希望您查看他们的 PR,该命令如下所示:
git fetch upstream pull/1234/head:#JaneSmith
附加信息:在 上面的命令中,“上游”.) 是指分叉回购发起的回购。
这将使分支机构,他们的公关是提供给你本地,所有你要做的下一步是检查他们的分支机构。
git checkout #JaneSmith
瞧啊。现在,您可以在本地测试它们的更改。
更新(2022 年 10 月): 不必在分支机构名称前加标签,实际上名称是任意的,你可以随意命名。
如何从分支的历史记录中删除特定的提交?
方案
您刚刚修复了一个 bug,发布了代码,创建了 PR。您去检查您的变更,但是,您注意到其中有一些来自您以前工作的分支的代码没有被批准,您需要将它从这个分支中取出来。
这是你需要做的。
首先,您需要包含不需要的更改的提交散列。您可以使用下面的命令找到它。
git log
找到散列后,可以运行下面的命令将其从分支的历史记录中删除。
git rebase --onto <commit-id>^ <commit-id>
太好了,现在你已经摆脱了那些讨厌的不想要的变化!
接下来,由于您删除了提交,本地分支的历史记录将不再与远程分支的历史记录相匹配。要解决此问题,您必须强制推送以覆盖遥控器的历史记录。
git push -f
太好了,现在你的公关准备好了!
如果你做到了这一步,首先,感谢你的阅读。
作为开发人员,git 是一个至关重要的工具,它使我们能够以很小的摩擦进行协作,并轻松地修复我们破坏的东西。我分享了这些具体的情况,因为它们是我经常遇到的问题,我发现自己在谷歌上搜索。我发现这些简单的命令对我的工作效率是不可或缺的,我希望你也能把它们添加到你的工具箱中!
生命体征:评估数据健康状况和处理异常值
你的数据准备好机器学习了吗?检查它的健康状况,并学习如何处理您可能发现的异常值
杰西·奥里科在 Unsplash 上的照片
在医生的办公室,在医生到达之前,你和医疗助理要经历一个熟悉的例行程序。他们会检查你的生命体征——脉搏、血压、呼吸率等——并收集一些一般信息。这些步骤总结了你健康的一些重要方面,让医生直接进入更复杂的分析。
现在包含在 Alteryx 智能套件中的数据健康工具,为您的数据做类似的事情。它为您提供了对数据集进一步分析准备情况的快速而全面的评估,尤其是在预测分析和机器学习之前。该工具还会查找异常值,并方便地将它们放在单独的输出中,以便您可以处理它们。
让我们看看使用这些新诊断能力的最佳方式,以及如何对结果采取行动,尤其是那些异常值。
关于数据健康工具
数据健康工具收集数据集的“生命体征”,揭示数据集是否已准备好产生可靠、准确的见解,或者它是否会受益于一些特殊处理。具体来说,该工具可以查看数据集的缺失值、是否有异常值及其稀疏度。(如果数据集包含许多零值,则它是“稀疏的”;例如,许多购物推荐系统使用的数据集是稀疏的,因为每个购物者都没有购买过甚至没有看过许多提供的产品。)Data Health 还检查每个变量的唯一值的数量对于其数据类型和数据集的大小是否有意义。
图像通过 GIPHY
如果您是数据调查工具面板的粉丝,您可能想知道数据健康与字段汇总工具有何不同。您从这两种工具中确实获得了一些相同的信息;然而,值得注意的是,正如 Alteryx 数据科学产品经理 Sonia Prakasam 最近告诉我的那样,数据健康提供了“对数据集质量的整体衡量”。“数据健康产生更具可操作性的结果。在任何机器学习过程之前使用它来帮助为机器学习管道准备数据非常好。”
Data Health 还会为您检测和识别异常值,而 Field Summary 不会这样做。我们一会儿将讨论这个问题——包括一旦你将这些离群值收集起来,该如何处理它们。
在使用数据健康之前,最好使用要素类型工具来确保您的数据类型设置正确,否则您可能会得到不同的结果。数据健康可以处理字符串、布尔和数字数据;特征类型允许您为每一列设置更详细的类型(例如,邮政编码、文本、分类等)。).Data Health 了解如何处理每一种类型,如果提供额外的信息,它将提供更好的运行状况评估。
诊断异常值
除了所有其他可操作的信息之外,拥有一个工具来快速发现可能给分析和建模带来挑战的异常值是非常棒的。数据健康工具使用 2008 年同行评审研究中建立的方法(在此阅读)。它基于一种你可能听说过的数据可视化方法:盒状图或盒须图。
图片由Schlurcher,维基共享
下面是对阅读这些情节的复习.)。我们主要对代表异常值的点感兴趣。我们如何知道哪些数据点应该被定义为异常值,并显示为那些孤独的小点?当数据失真时,这种识别也变得更加棘手。一些识别异常值的方法假设您将拥有一个良好的、正态分布的数据集,但事实可能并非如此。
图片 via GIPHY
不管您的数据分布看起来如何,Data Health 识别异常值的方法已经涵盖了您。它基于一种叫做“ medcouple 的偏斜度测量方法该度量用于调整箱线图的结构。这种方法避免了不必要地将数据点标记为异常值,因为它们实际上相当接近数据分布的中心。正如研究人员解释的那样,“这使得调整后的箱线图成为自动异常值检测的有趣而快速的工具,而无需对数据的分布做出任何假设。”
在没有自动化工具的情况下寻找异常值有点复杂。Designer 中的一些选项在本线程中讨论。您可以尝试使用 Python 和 pandas,如这里的所解释的那样,计算每一列中的值的 z 值,然后潜在地消除在一列或多列中包含异常值的行。另一个 Python 选项是使用本地离群因子,sklearn 中提供的。这种方法在此处演示并在下图中显示,它基于k-最近邻点,并根据一个数据点相对于其周围邻域的孤立度来确定该数据点是否为异常值。可怜的孤独的局外人!
每个带有局部异常值因子的数据点用红色圆圈的直径显示。图来自 scikit-learn 示例。
所以我有离群值…有什么治疗方法?
首先,仔细看看你的异常值:
- 它们真的很稀有吗?不应该有很多古怪的价值观。如果有,你可能有其他问题要解决。
- 会不会是错别字?也许那些值可以被修正。
- 会不会有测量误差?例如,在某些情况下,传感器可能会错误地记录数据。
- 异常值是如何出现的,有什么模式吗?也许它们与另一个变量的特定值同时出现。这可能是一个重要的观察模式。
- 你的样本中是否有值得进一步研究的不寻常的人或事?异常值可能是一个线索,表明有一个全新的领域需要研究。
- 如果你的样本量很小:你的异常值可能只是出现在分布末端的前几个数据点吗?如果你收集了更多的数据,你会有更多的数据点吗?这种可能性可能很难确定,但这些异常值可能只是随着进一步的数据收集而出现的额外数据的暗示。
这次考试将决定你下一步的行动。表面上,处理异常值的方法很简单:忽略它们,删除它们,或者修改它们。您的选择可能部分取决于您对数据的计划。如果您正在进行探索性的数据分析和生成可视化,离群值可能是新奇的和/或讨论的开始,所以让它们留在原处可能不是问题。您可能希望在有异常值和无异常值的情况下运行分析,以查看您的结果有何不同。
如果您有大量数据,简单地删除异常值可能没问题。这种删除有时被称为“修剪”您的数据。通常,您会从数据中删除相同百分比的最高值和最低值。请将此视为修剪数据钟形曲线的尾部。但是,您正在非常显著地修改您的数据,这可能会引发所有的问题,并且您希望对这种方法有一个很好的理由。
修整异常值
修改你的异常值是另一个策略。离群值肯定会影响机器学习模型,有些影响更大。然而,您可能希望保留在训练模型时必须使用的每一点数据。您可以考虑以下几种修改方法:
- 转换:对数、平方根或逆转换有时会在预处理中使用,以减少数据的偏斜度(即,使其看起来更像正态分布)并减少异常值的潜在影响。Designer 公式工具中的 LOG(x)函数可以帮助进行对数转换。
- 裁剪,又名 winsorization :这个方法对变量可以拥有的值进行限制。例如,数据的 90% winsorization 将取前 10%和后 10%的值,并分别用第 90 百分位和第 10 百分位的值替换它们。与修剪相反,你没有删除数据点;您正在用更接近数据其余部分的值替换曲线两端最远的值(以前的异常值)。
裁剪或 winsorization 用更多的中心值替换离群值
均值或中值替换:一些参考文献建议用变量的均值或中值替换异常值,假设仅用非异常值计算。这可能不是一个好主意,因为在这个讨论中阐述了的许多原因。
有了数据健康工具,一旦您的异常值被识别出来,如何处理它们就取决于您了。您可以在工具的第三个输出锚点中找到它们,并进一步查看它们。您可以添加一个字段,将它们标记为异常值,并将它们连接回您的主数据集。您可以绘制数据并使用该标志标记异常值,方法是使用不同的颜色来标识异常值(例如,在散点图上),或者使用数据调查工具来进一步探究这些异常值及其与其他变量的关系。您还可以将异常值输出连接到主数据源,然后从您的分析中排除异常值。无论你选择做什么,记住上面的警告。
总的来说,数据健康工具为分析和机器学习提供了对数据质量和就绪性的快速和极其有用的洞察。在它的帮助下,您可以自信地快速进入下一步,因为您已经查看了数据集的关键生命体征。
附加阅读
- 为什么离群值对科学有好处(还有其他领域!)
- 40 年的箱型电影,作者:哈德利·威克姆和丽莎·斯特莱杰斯基
- 关于 Winsorization 和 Trimming 的一些观察
原载于 Alteryx 社区 数据科学门户 。
用 Python 通过三个简单的步骤实现 VLOOKUP
通常,在数据分析领域,数据清理和处理需要花费最多的时间和精力。虽然与模型开发等更有趣的部分相比,数据清理、过滤和预处理等步骤通常被低估或忽略,但决定输出质量的是数据质量。正如正确的说法,垃圾输入=垃圾输出,反之亦然。
在 Excel 中,VLOOKUP、HLOOKUP、xlookup 和 INDEX MATCH 等函数对于从数据表或区域中查找满足给定条件的所需数据非常有用。在本文中,我将描述一种简单的方法,用 Python 通过三个简单的步骤复制 Excel 的 VLOOKUP 函数。本文使用的脚本可以在这个 GitHub 资源库中获得。让我们开始吧。
图片来自 Unsplash 作者 Jonnelle Yancovic
数据
首先,我将描述我们在这篇文章中使用的数据。
世界银行开放数据是一个关于全球发展的免费和开放的数据来源。人们可以从世界银行的数据库中找到数百个与全球发展相关主题的数据集,包括经济、人口、气候变化、卫生、基础设施、能源等。分析这些指标的时间序列数据对于制定适合一个国家或地区的政策、制度和监管框架至关重要。
世界银行的数据可以以 Excel 或 CSV 格式直接从数据库中下载,也可以使用pandas_datareader
从 Python 中直接访问,如下面的脚本所示:
在这篇文章中,我将使用特定国家特定年份的选择性指标。我从世界银行数据库中选择了国内生产总值、人均国内生产总值、电力供应、人口和二氧化碳排放数据,并提供了这些指标的代码,这些数据也可以从网站上获得。接下来,我通过提供 ISO 代码随机选择了 12 个国家,并下载了 2018 年的数据。我用指标名称而不是代码来重命名列,并且只选择索引中的国家。数据帧df
如下所示:
2018 年选自世界银行数据库的发展指标
Excel 中的 VLOOKUP 实现
在这一节中,我将描述 VLOOKUP 函数如何在 Excel 中从数据表或数据区域中获取所需的数据子集。如下面的 Excel 截图所示,A 到 F 列表示与df
中相同的数据。在 I 到 L 列中,我想从第一个表中获得二氧化碳排放量和人口数据。
在 Excel 中实现的 VLOOKUP 函数在右边的表(I1:L6)中从左边的表(A1:F13)中获取值
在 Excel 屏幕截图中用红色矩形表示的公式栏中,我们可以看到用于单元格 J2 的公式。
=VLOOKUP($I2, $A$1:$F$13,6,FALSE) * 1000
其中,
$I2
代表我们要在第一个表中查找的国家不丹;
$A$1:$F$13
表示整个第一个表,在该表中可以找到查找值和要返回的数据
6
代表栏号(此处代表 kt CO2 栏),将从该栏返回相应的数值(不丹),以及
FALSE
表示完全匹配。
用 Python 实现它的三个简单步骤
在这里,我描述了上面在 Excel 中使用的相同函数的实现,但是用 Python 分三个简单的步骤:
**首先,**我们创建一个名为df_target
的数据帧,我们希望在其中包含所需的子集数据。最初,数据框架包括五个所需国家的名称。然后我们为想要从df
返回的指标CO2 emissions (tonnes)
和Population
创建空列。
第一步
df_target
中的countries
列与df
中的country
列共用。因此,**其次,**我们将df_target
中的countries
列设置为索引。
第二步
**第三步,**这是我们将df_target
中的索引映射到df
以获取所需列的数据作为输出的主要步骤。例如,df
的kt CO2
列的值乘以 1000 后返回给df_target
的CO2 emissions (tonnes)
列。 map()函数根据输入对应关系映射系列的值,并用于将系列中的每个值替换为另一个值,该值可从函数、字典或系列中提取。
第三步
在本文中,我们学习了一种简单的技术,用 Python 通过三个简单的步骤实现 Excel 的 VLOOKUP 函数。Python 中不同包的功能和模块使得几个步骤自动化,否则将花费大量的时间和精力,从这个意义上说,这是优化成本和资源的真正福音。
语音分类使用深度学习,用 Python
Jukka Aalho 在 Unsplash 上拍摄的照片
以下是如何使用深度学习对音轨的声音进行分类
有时人类能够非常容易地做某些事情,但是他们不能恰当地描述他们是如何做的。例如,当两个不同的声音说话时,我们能够清楚地区分它们,但很难描述我们用来区分它们的确切特征。由于任务很难描述,教计算机如何做就更难了。幸运的是,我们有数据,我们可以用这些例子来训练我们的机器。
我们开始吧!
1.设置
如题,我用过 Python 。特别是,我使用了这些库:
我们将在此过程中使用它们。
2.数据集
我用了第一场美国 2020 年总统辩论的前 30 分钟。具体来说,任务是区分三种声音:
- 克里斯·华莱士(主持人)
- (前任)总统唐纳德·特朗普
- (前任)副总统乔拜登
音频可以在这里找到。特别是,你有一个. csv 文件,一步一步地描述所有的争论。然后,你有一个. mp3 文件,这是辩论的音频。我对它进行了裁剪,得到了一个 30 分钟的音频(为了让过程更快),并将其命名为“ trimmed.mp3 ”。然后我做了音频的梅尔频谱图。很多人比我解释得更好(例如),但是你可以认为 **MEL 频谱图是音频信号的频率表示,它被转换以更接近我们对声音的感知。**最终结果如下:
因此,信号基本上有 20 个频率。采样率为 22010 Hz,因此,可以使用代码提取时间向量
现在,由于已经使用了**监督学习方法,是时候使用。csv 文件。**特别是,它由三列组成:
- 演讲者**(华莱士、拜登或特朗普)**
- 结束分钟**(分:秒或小时:分:秒)**
- 演讲
因为我们有以秒为单位的时间,所以我们将结束分钟转换为秒:
现在我们完成了。
尽管如此,它是关于整个演讲,而正如已经说过的,音频较短。由于这个原因,数据集的一部分也被取走了。
让我们来看看:
现在可以轻松地将音频数据转换成熊猫数据帧:
开始了。所以现在我们有 20 列 X 74200+行…非常大。为此,已执行****主成分分析(PCA)缩减:
****现在,我们要合并。带有 pca_data 数据帧的 csv 文件。为了做到这一点,我们定义了另一个列,告诉你,对于那个特定的点,说话者:
现在,我们来看看。
因为这是可以预测的,所以有必要查看时间序列以了解正在发生的事情。为了简单起见,让我们使用互信息来选择最具信息性的特征,并从中提取出一个时间序列**。**
信息量最大的是 2 组分。
事情是这样的:
使用 LabelEncoder():
定义字典:
3。深度学习
现在我们已经有了我们需要的一切,我们来谈谈深度学习。虽然众所周知,卷积神经网络对图像非常有效,但很少有人知道它们对时间序列也很有效。其实我们会用一个 CNN 来区分三种声音。
让我们使用一个训练测试分割并混合数据:
定义模型:
训练模型:
评估模型:
该模型以 softmax 结尾。这意味着我们基本上获得了特朗普、拜登或华莱士发言的概率。这里有一个例子:
让我们来探索一下测试集:
结果如下:
****正如可能看到的,当他们实际说话时,概率很高,这是一个好迹象!此外,如果我们直接评估准确性,我们是严格的,因为该算法在几分之一秒内工作,而人类语音不能变化如此之快(例如,强制预测不变,直到某个时间增量被验证,这可能是一个好主意)。
尽管如此,让我们严肃一会儿,让我们画出困惑矩阵:
和分类报告:
所以我们有 68%的准确率。
摘要
简而言之,已经开展的进程如下:
- 获取音频数据,修整并应用 MEL 频谱图
- 使用主成分分析降低维数
- 使用。标记音频数据的 csv 数据
- 定义深度学习 CNN 模型
- 得到结果
如果你喜欢这篇文章,你想知道更多关于机器学习的知识,或者你只是想问我一些你可以问的问题:
A.在 Linkedin 上关注我,我在那里发布我所有的故事
B .订阅我的 简讯 。这会让你了解新的故事,并给你机会发短信给我,让我收到你所有的更正或疑问。
C .成为 推荐会员 ,这样你就不会有任何“本月最大故事数”,你可以阅读我(以及数千名其他机器学习和数据科学顶级作家)写的任何关于最新可用技术的文章。
VoxMorphia:使用人工智能进行歌词风格转换
我如何使用 GPT-3 重新想象鲍勃·马利、电台司令和梅根·赛恩风格的经典歌曲
鲍勃·马利作者埃迪·马林,电台司令汤姆·约克作者克里斯、和梅根·赛恩作者阿尔弗雷德·马罗奎因,作者图片说明,来源图片来自commons.wikimedia.org经 2.0 许可在 CC 下使用
OpenAI 的第三代转换器 GPT-3 是目前最先进的文本生成模型[1]。只要给出几个例子,它就可以创建高质量的文本。我想看看能否提示系统采用一位作家的写作风格,并将其转移到另一位作家的作品中。
在这个我称之为 VoxMorphia 的实验中,我选择了转换公共领域的歌曲,包括像“是的,先生,那是我的宝贝”这样的经典歌曲。使用 GPT-3 和一些额外的开源项目,我将经典歌曲的歌词改编成鲍勃·马利、来自电台司令的汤姆·约克、梅根·赛恩和其他 43 位歌曲作者的抒情风格。
我选择突出这三位录音艺术家,以展示一系列风格:鲍勃·马利在复古雷鬼节奏中流畅的旋律线条,汤姆·约克在复杂的另类摇滚模式中充满焦虑的漫谈,以及梅根·赛恩在甜美的嘻哈节拍中巧妙而露骨的说唱。
概观
我将首先展示主要系统组件是如何连接在一起的,然后介绍 GPT-3 是什么以及它是如何工作的。接下来,我将介绍我用来转换歌词风格的过程,并展示一首具有三种不同歌词风格的歌曲的样本输出。
在附录中,我将展示三首不同风格的不同歌曲的较长示例。
这个项目的源代码可以在 GitHub 上获得,你可以使用这个 Google Colab 来试验代码。请注意,您需要一个来自 OpenAI 的帐户来运行代码。你可以加入等候名单,进入他们的测试程序这里。
系统组件
这个项目的主要工作是由 GPT-3 生成歌词,谷歌的通用句子编码器[2]帮助对文本进行预处理和后处理。
以下是该系统的组成部分及其工作原理的示例。
VoxMorphia 组件图,图片作者
该系统首先对 Kaggle 数据库中的歌词和一首老歌进行预处理,例如,Gus Kahn 1925 年的“是的,先生,那是我的宝贝”。Google 的通用句子编码器用于从目标歌曲作者(例如 Bob Marley)中查找紧密匹配的旧歌词和新歌词对。这些配对被添加到一个提示中,作为商业服务运行的 GPT-3 的输入。该提示包含三个用简单英语编写的部分:说明、前/后示例和输入文本。您可以在上面生成的提示块中看到一个例子。
在被提示后,GPT-3 以鲍勃·马利的风格返回“是的,先生”的五个候选歌词行。再次使用通用句子编码器来选择最佳候选。理想情况下,新歌词将(A)抓住原始歌词的精髓,但(B)不完全相同,©不会相差太远。
在我进入 VoxMorphia 的细节之前,我将介绍 GPT-3 的简短历史和概述,并展示它是如何工作的。
GPT 模型的大小(对数标度)随着时间的推移,大约每六个月就会增加 10 倍,图表由作者绘制
GPT 三号背景
在使用更大的变压器模型进行自然语言处理(NLP)之前,人工智能模型被训练来执行特定的任务,如文本分类、回答问题、创建摘要等。
GPT 一号
2018 年 6 月,OpenAI 发布了其初始生成式预训练变压器(GPT),其神经网络规模为 1.17 亿个参数。它接受了 7000 本未出版书籍的训练[3]。该系统可以执行一般的 NLP 任务,而不需要太多的预先训练。
GPT-2
2019 年 2 月,OpenAI 发布了拥有 15 亿个参数的 GPT-2。它在 800 万个网页上进行了训练,并成为许多自然语言任务的最先进的系统[4]。我在我的 PlotJam 和 InventorBot 项目中使用了 GPT-2。
GPT-3
2020 年 6 月,OpenAI 发布了 GPT-3 的测试版。它使用 29 亿个网页进行训练,拥有 1750 亿个参数[1]。作为参考,一个典型的人脑大约有 1000 亿个神经元[5]。正如我们在波斯顿所说,GPT 三号是“邪恶的史迈特”
缺德斯迈特到底有多聪明?当我被邀请参加 OpenAI 的测试程序时,我做的第一件事是对我为我的 AI-8 Ball 项目所做的事情进行一个快速测试,以神奇 8 球的方式回答是/否问题。
我登录 OpenAI 的 playground 运行测试,用粗体键入以下提示,GPT-3 回答了。
GPT 3 号游乐场由 OpenAI 拍摄,图片由作者提供
文本提示
与其他生成文本的人工智能模型不同,OpenAI 目前不允许微调 GPT-3。但是,它允许您用英语告诉转换器做什么,并在提供输入文本之前提供几个例子。这称为“少量”学习,通过提供文本提示来完成。
从示例中,您可以看到提示的三个部分:说明、前/后示例和文本输入。这是上例中的提示,部分用括号标注。
The following are questions with yes/no answers in the style of the Magic 8-Ball. **(Instructions)**Is the sky blue?
Yes. It is certain. **(Example 1)**
###
Will I win the lottery?
No. Don’t count on it **(Example 2)**
###
Can a computer beat a grandmaster chess player? **(Text Input)**
然后,系统将为文本输入中的问题写下答案。
Yes. Ask Garry. **(Response Created by GPT-3)**
爆笑!它没有完全做到我想要的,因为它没有使用魔术 8 球的标准答案之一。但是它很好地提到了加里·卡斯帕罗夫,他在 1997 年输给了 IBM 的深蓝电脑。
控制参数
上面操场的截图显示了控制生成文本的参数集。这里是我使用的设置的每个参数的简要描述。
- 引擎 -要使用的 AI 模型。达芬奇型号 175B 参数能力最强, Ada 最快 2.7B 参数。居里和巴氏合金型号介于两者之间分别为 13B 和 6.7B 参数。我为这个项目使用了 达芬奇 模型。
- 响应长度 -要生成的最大文本量,用令牌指定。令牌大致相当于单词中的一个音节。对于上面的示例,提示中有 62 个标记,结果中有 8 个标记。对于 8 球问题,我将响应长度设置为 64,对于生成歌词,我将设置为 128 。
- 温度 -控制响应的变化,范围从 0.0 到 1.0。默认是 0.7,但是我用了 0.8 。
- 顶部 P -控制输出的多样性。我一直盯住 1.0 。
- 频率惩罚 -在响应中避免重复的程度。我将此设置为 0.25 。
- 存在惩罚 -控制在生成的文本中改变主题的能力。我将此设置为 0.75 。
- 之最——在服务器端生成多少响应。如果设置为大于 1,那么 GPT-3 将只发送最好的一个。我把这个设置保持为 1 。
请注意,温度和 Top P 参数是相似的。将它们移向 0,结果会变得乏味且可预测,将它们移向 1,结果会变得更加随机。你可以在 Ben Mann 的文章这里中了解这些参数是如何工作的。
频率和出席惩罚也是相似的。弗拉德·亚历克斯在他的帖子中实验了这些参数。他发现增加频率惩罚会导致与先前生成的文本产生新的偏差。并且增加存在惩罚允许 GPT-3 将新主题插入文本。
定价
正如我上面提到的,OpenAI 提供 GPT 3 作为商业服务。当我注册测试版时,他们给了我 30 万个免费代币,4 个月后到期。我在两个月内用完了免费代币,现在为使用达芬奇模型支付每 1000 个代币 0.06 美元。上述 8 球的例子总共使用了 70 个代币,总成本为 0.004 美元,约为 0.5 美分。其他车型的费率计划在这里,beta.openai.com/pricing。运行模型的成本基于它们的大小。参数越多=成本越高。
体视吗啡系统详情
在这一节中,我将介绍 VoxMorphia 使用的过程,并解释系统组件是如何工作的。
创建提示
我不想自己为转换歌词风格创建自定义提示,所以我设计了一个自动完成这项工作的方法。下面是一个样式转换提示示例,包含三个部分:指令、前/后示例和要转换的输入行。
说明
这是我给 GPT 3 号的指令。
Rewrite the song "Yes Sir, That's My Baby" in the style of Bob Marley. Try to follow the rhyming pattern. Be creative.
这些指令相当简单。我试验了各种变化,发现效果很好。
前/后示例
这里有几个 before/示例来帮助 GPT-3 了解它被要求做的事情的要点。
Original lyrics: "What was I just 'gonna' say, / I forget, but anyway."
Bob Marley lyrics: "I wanna know now / That was a moment I never will forget"Original lyrics: "Who's the 'who' I rave about? / In the Winter, Summer, Spring and Fall?"
Bob Marley lyrics: "Who is Mr. Brown? I wanna know now / Winter is here"
对于之前的部分,我从原来的歌词开始。对于之后的部分,我使用了来自 kaggle.com网站的一组歌词。我对歌词进行预处理,以拆分长行并删除空白。
然后,我使用谷歌的通用句子编码器找到目标风格的最佳歌词前/后。
通用句子编码器将文本编码成高维向量,这些向量可用于文本分类、语义相似性、聚类和其他自然语言任务。该模型针对大于单词长度的文本(如句子、短语或短段落)进行了训练和优化。—丹尼尔·瑟尔等人,谷歌[2]
为了找到最好的例子,我对原始歌曲的歌词进行编码,并与数据集中所有鲍勃·马利歌词的编码歌词进行比较。这有效地运行了语义搜索,寻找前后具有相似含义的行。
举例来说,下面是原始歌曲第二节的一对歌词,以及数据集中与鲍勃·马利的歌词最接近的语义匹配:
原文→鲍勃马利 我刚才“打算”说什么→我现在想知道
我忘了,但无论如何→那是我永远不会忘记的一刻
即使这些匹配不太好,在提示符下添加两到三个这样的匹配对 GPT 3 号来说已经足够完成任务了。我试图在提示中添加更多的例子,但结果是收益递减。这些例子只是帮助系统做我要求的事情,而不是教它作曲者的风格。它已经从训练中了解了风格。
输入文本
提示的第三部分是我希望设置风格的一组行。我用第一组双引号引导 GPT-3 以鲍勃·马利的风格写下这些诗句。
Original lyrics: "Who’s that coming down the street? / Who’s that looking so petite?"
Bob Marley lyrics: "
Python API
接下来,我使用 OpenAI 的 API 来设置参数,并将提示发送到 GPT-3。下面是我为此编写的代码。
**这个调用相当简单。它设置参数,调用 openai。Completion.create(),并返回响应。
下面是对提示的回应。
原创→由 GPT 生成的鲍勃·马利风格-3
街上走来的是谁? → 谁来了,沿着街道来了?
那个长得这么娇小的是谁?谁在看,看起来如此甜美?
好吧,它改变了一些单词,但保留了押韵方案。还不错。
示例输出
在我展示更多 GPT-3 输出的例子之前,这里是 OpenAI 建议我展示的法律免责声明,这都是真的。
作者使用 OpenAI 的大规模语言生成模型 GPT-3 生成了以下文本。在生成草稿语言后,作者根据自己的喜好审阅、编辑和修订语言,并对本出版物的内容承担最终责任。
这是鲍勃·马利风格的“是的,先生,那是我的宝贝”的第一段和副歌。
****
****格斯·卡恩和 GPT-3 作词,鲍勃·马利摄影埃迪·马林来自commons.wikimedia.org根据 CC 通过 2.0 许可使用
这是电台司令风格的相同歌词。
****
****格斯·卡恩和 GPT 作词-3、T22、汤姆·约克克里斯摄影来自commons.wikimedia.org在 CC 下使用通过 2.0 许可
最后,在父母的忠告警告之后,这里又是种马梅根风格的歌词。
****家长咨询,来源:commons.wikimedia.org
****
由格斯·卡恩和 GPT-3,梅根·赛恩作词阿尔弗雷德·马罗奎因来自commons.wikimedia.org由 2.0 许可在 CC 下使用
请注意,GPT-3 将输出标记为安全、敏感或不安全。以下是 OpenAI 对这些术语的定义。
0 - 文字安全。
1 - 这段文字比较敏感。这意味着文本可能在谈论一个敏感的话题,一些政治的,宗教的,或者谈论一个受保护的阶层,比如种族或国籍。
2 - 这段文字不安全。这意味着文本包含亵渎的语言,偏见或仇恨的语言,可能是 NSFW 教的东西,或以有害的方式描绘某些群体/人的文本。
对于上述示例,系统偶尔会将鲍勃·马利和电台司令风格的歌词标记为敏感。但它总是把梅根·赛恩标为不安全。
摘要
因为我运行着 GPT-3,所以我用它来创建本文的摘要。我在前三段粘贴,加了“TL;博士,“这代表”太长了;没看。”这促使 GPT-3 产生了一个两句话的总结。
GPT 3 号游乐场由 OpenAI 拍摄,图片由作者提供
这个项目是一个概念证明,人工智能可以用来根据另一位作家的风格生成新的文本。这表明人工智能可以用来生成新的内容,人工智能生成的文本可以以创造性的方式使用。- GPT-3
这 254 枚代币花了我 0.015 美元。因此,这就像为 GPT 3 的想法支付一便士来获得它的 2 美分。😃
未来的工作
另一个潜在的项目是将风格转移用于其他类型的创造性写作。这可能包括诗歌、小说和电影剧本。电影剧本创作中一个有趣的应用是观察不同的角色如何表达相同的思想。
我还想尝试 OpenAI 的新指令系列模型,这些模型经过微调,使提示更容易。
Instruct 系列是一套新的模型,它可以让你更容易地告诉 API 你想要它做什么:只需给 API 一些指令和输入数据,API 就会尽最大努力遵循你的指令。这是我们朝着建立符合人类利益的安全模型的目标迈出的重要一步。— OpenAI
这些新模型正在接受训练,只需在提示符下输入指令和数据。不需要举例。这就是所谓的“零距离”学习。
讨论
我从这个项目中得到的第一个收获是 GPT 3 号有着巨大的潜力。但是哄骗它使用样式转换来自动生成文本是很棘手的。使用 GPT-3 将焦点从编写好的代码转移到编写好的提示。
随着通用人工智能变得更加智能,我们很可能能够用一些简单的事情来提示未来的系统,“用梅根·赛恩的风格把歌词改写成‘是的,先生,那是我的宝贝’。”(顺便说一下,我用达芬奇的和达芬奇的的模型对 GPT-3 进行了测试,但都没有成功。他们只是重复了多次提示。)
源代码
这个项目的所有源代码都可以在 GitHub 上获得。您可以使用这个 Google Colab 来试验代码。我在 CC BY-SA 许可下发布了源代码。
归属共享相似
感谢
我要感谢詹尼弗·林对这个项目的帮助。我还要感谢 Oliver Strimpel、Penny Lennox 和 Fez Aswat 审阅了这篇文章并提供了有益的反馈。
参考
[1] GPT-3 、布朗、汤姆·b、本杰明·曼、尼克·赖德、梅勒妮·苏比亚、贾里德·卡普兰、普拉富拉·达瑞瓦尔、阿尔温德·尼拉坎坦等,“语言模型是很少出手的学习者。”,2020 年 7 月 22 日。https://arxiv.org/abs/2005.14165
[2] 通用语句编码器、Cer、Daniel、杨、孔胜义、南华、Nicole Limtiaco、Rhomni St John、Noah Constant 等人【通用语句编码器】、
[3] GPT-1 、拉德福德 a .、纳拉西姆汉 n .、萨利曼斯 t .、苏茨基弗 I .,《通过生成性预训练提高语言理解》,2018 年,https://www . cs . UBC . ca/~ amuham 01/ling 530/papers/radford 2018 Improving . pdf
[4] GPT-2 、a、、吴 j、、Child R、、Luan d、、Amodei、d、、Sutskever、I .,《语言模型是无监督的多任务学习者》,2019 年 2 月,https://cdn . open ai . com/better-Language-Models/Language _ Models _ are _ Unsupervised _ multask _ leaders . pdf
**【5】**100 b 神经元,**赫库兰诺-胡泽尔,苏珊娜。"数字中的人脑:线性放大的灵长类大脑."人类神经科学前沿 3 (2009)。【https://doi.org/10.3389/neuro.09.031.2009 **
[6] 深蓝诉卡斯帕罗夫,chessgames.com,1996–1997,https://www.chessgames.com/perl/chess.pl?pid=29912&PID 2 = 15940
附录
下面的歌词是基于公共领域的三首不同的歌曲,按照鲍勃·马利、电台司令和梅根·赛恩的风格重新构思的。
这是鲍勃·马利 1892 年创作的《黛西·贝尔》。
****
哈利·戴克和GPT 作词-3,鲍勃·马利摄影埃迪·马林来自commons.wikimedia.org根据 CC 通过 2.0 许可使用
这是 1911 年电台司令风格的“亚历山大拉格泰姆乐队”。
****
格斯·卡恩和 GPT 作词-3、 汤姆·约克照片克里斯来自commons.wikimedia.org在 CC 下使用通过 2.0 许可
最后,这是 1923 年梅根·赛恩风格的“是的,我们没有香蕉”。
****家长咨询,来源:commons.wikimedia.org
****
****由弗兰克·西尔弗和 GPT-3,梅根·赛恩作词由阿尔弗雷德·马罗奎因摄影来自commons.wikimedia.org根据 CC 通过 2.0 许可使用
为了无限制地访问 Medium 上的所有文章,成为会员,每月支付 5 美元。非会员每月只能看三个锁定的故事。