AUC 及其在 CatBoost 中的实现
本教程是关于受试者工作特征(ROC)曲线下的区域(AUC)及其在 CatBoost 中的实现,用于二元分类、多类分类和排序问题。
关于 AUC
ROC 曲线显示了模型区分等级的能力。
将类别随机分配给对象的模型是“坏的”分类器,并且具有对角 ROC 曲线。分类器越好,ROC 曲线越高。绘制 ROC 曲线,y 轴为 TPR、真阳性率,x 轴为 FPR、假阳性率。该曲线也可以根据模型的敏感性和特异性进行解释,y 轴为敏感性,x 轴为(1-特异性)。
构建和可视化 ROC 曲线可用于测量具有不同概率边界的分类算法性能和选择实现指定假阳性或假阴性率所需的概率边界。
AUC 是 ROC 曲线下的面积。对所有对象进行正确排序的模型的最佳 AUC = 1(所有具有类别 1 的对象被分配比类别 0 的对象更高的概率)。作为随机猜测的“坏”分类器的 AUC 等于 0.5。
AUC 用于二元分类、多类分类和排序问题。 AUC 测量正确排序对象的比例和模型区分类别的能力。
AUC 具有一个重要的统计特性:分类器的 AUC 相当于分类器将随机选择的阳性实例排列得高于随机选择的阴性实例的概率。
CatBoost 实现
对于二分类、多分类、排序问题,在 CatBoost 中有 AUC 的实现。您可以在过度拟合检测和自动最佳模型选择的训练期间计算 AUC,使用 model.eval_metric 评估新数据上的模型,并将 AUC 用作预测评估和与 utils.eval_metric 比较的指标。请参阅如何在真实数据集上使用 Catboost 中的 AUC 一节中使用 CatBoost 进行模型拟合和 AUC 计算的示例。
有用的链接
- 在维基百科上阅读更多关于 ROC 的内容。
- 要从头开始了解 ROC 曲线的构建,请参见文章。
- 要了解多类分类的 AUCμ,请参见文章。
二元分类
二元分类的计算规则
二元分类的 AUC 根据以下公式计算:
其中 aᵢ,aⱼ —算法给出的物体属于类别 1 的预测(概率)。
对所有对象对 i,j 计算总和,使得: tᵢ=0,tⱼ=1 其中 t 是真正的类标签。
如果对象 i,j 排序正确,则 I 是等于 1 的指示函数:
用户可以为每个对象分配权重,以指定每个对象在度量计算中的重要性。
二元分类 AUC 计算的一个简单例子
让我们看一个简单的 ROC 曲线构建和 AUC 计算的例子:
我们有 10 个对象的样本,4 个来自类 1,6 个来自类 0(“类”列)。所有对象同等重要(权重= 1)。假设我们预测了对象来自类别 1 的概率(“预测”列)。
分母等于对象对的数量 i,j 使得真实类 tᵢ=0,tⱼ=1 。因为有 4 个来自类 1 的对象和 6 个来自类 0 的对象,所以分母等于 24。
对于来自类 1 的每个对象,计算来自类 0 的对象的数量,这些对象在排序的数据集中位于下面(概率较小)。
我们添加+1 个正确排序的对象(例如,id 为 0 和 4 的对象),如果概率相等,则添加+0.5 个对象(例如,id 为 1 和 7 的对象)。
例如,ID = 1 的对象将+4.5 加到 AUC 分子上,与 ID:8,3,6,9 的对象正确排序,并且与对象 7 具有相同的预测:
denominator = sum(toy_example['class'] == 1) * sum(toy_example['class'] == 0)numerator = (6 + 5 + 4.5 + 2)manually_calculated_auc = numerator / denominatormanually_calculated_auc = 0.7292
让我们用 Catboost 计算同样的指标,并确保一切都是正确的:
catboost_auc = eval_metric(toy_example['class'], toy_example['prediction'], 'AUC')[0]
受试者工作特征曲线
要构建 ROC 曲线,请将类别 1 (n1)的对象数量放在正方形中,第 1 条边沿 y 轴,类别 0 (n0)的对象数量沿 x 轴。
按照由模型预测以降序排列的目标标签列表,将沿着 y 轴增加 1/n1,遇到类别 1 的对象,并且沿着 x 轴增加 1/n0,遇到类别 0 的对象。
通过“类”列从上到下,如果类是 1,我们就在图上向上,如果类是 0,我们就在图上向右。当遇到预测相同的对象时,将 y 轴上的数字 1 和 x 轴上的数字 0 相加,然后沿着矩形的对角线前进。
AUC:加权计算
CatBoost 允许我们为数据集中的每个对象分配一个权重,以便根据上面的公式计算 AUC。如果没有分配权重,所有权重都等于 1,因此 AUC 与正确排序对的数量成比例。如果分配给此属性的权重被更改。
权重对于不平衡的数据集非常有用。如果在训练数据集中存在具有少量样本的一类或一组对象,则增加相应对象的权重可能是合理的。
例如,如果我们将权重 10 分配给一个对象,这可以理解为将 9 个相同的对象添加到数据集。
让我们以权重= 10 的一个重要对象的错误和正确分类为例来计算 AUC。
roc_auc = catboost.utils.eval_metric(toy_example[‘class’], toy_example[‘prediction’], ‘AUC’, weight=toy_example[‘weight’])[0]
AUC = 0.9167。一个重要的对象被正确排序,AUC 增加
roc_auc = catboost.utils.eval_metric(toy_example['class'], toy_example['prediction'], 'AUC', weight=toy_example['weight'])[0]
AUC = 0.4417。一个重要对象订购错误,AUC 下降
多类分类的 AUC
Catboost 中的多类分类实现了两个 AUC 指标。
首先是 OneVsAll 。根据二元分类计算原则,对每个类别分别计算 AUC 值。
第二个是 AUC μ,其被设计为满足以下特性:
- 物业 1。如果模型在每个例子中给出正确标签的概率最高,那么 AUC = 1
- 房产 2。对实施例的随机猜测产生 AUC = 0.5
- 房产 3。AUC 对类别偏差不敏感
AUCμ可以解释为类别之间成对 AUC 的平均值。详情可在文章中找到。
OneVsAll AUC
Catboost 中的 OneVsAll AUC 返回 n-class 分类的 n 个 AUC 值。根据二进制分类计算规则,为从 0 到 K–1 编号的每个类 K 单独计算该值。类别 k 的对象被认为是正的,而所有其他的被认为是负的。
它的工作方式与二进制分类几乎相同,所以我在这里跳过计算细节(它们在 iPython 笔记本中)。
OneVsAll AUC 衡量分类器区分一类对象与另一类对象的能力。
OneVsAll 的一个优势是能够分别监控不同类的性能。
AUCμ
AUCμ可用作评估度量以防止过度拟合,而 OneVsAll AUC 仅可用于包含 k 值的信息(k 是类的数量)。
让我们来看看 AUCμ公式:
K 是班数, i < j ≤ K 是班数。
S(i,j) 是类 i 和 j 之间的可分性度量,定义为:
在哪里
- I 是应用于 O 结果的指示函数,如果 O返回正值则返回 1,如果O返回负值则返回 0,如果O返回 0 则返回 0.5。
- O 是一个方向函数,指示两个实例的顺序是正确、错误还是相同。如果预测排序正确,则返回正值;如果排序错误,则返回负值;如果排序相同,则返回 0。
- a,b 分别是来自类 i,j 的对象,
- p(a),p(b) 是对象属于类别的预测概率的向量,
- y(a),y(b) 是对象的真标签 a,b (一热向量),
- vᵢ ⱼ 是一个两类决策超平面法向量。
O 计算如下:
向量 v_i,j 来自误分类代价矩阵 A ,该矩阵是在学习任务之后手动定义的。
vᵢ ⱼ=A ᵢ.—ⱼ.
一个 ᵢ ⱼ 是当实例的真实类是 j 时,将实例分类为类 i 的成本。然后,A 在*(k1)*—单纯形上定义一个划分,并归纳出 K 类之间的决策边界。
默认的误分类成本矩阵值在任何地方都是 1,除了对角线上的值是 0。它被称为 argmax 划分矩阵,因为它以最大概率分配一个类。
这是一个具有 argmax 划分矩阵 a 的 3 类分类问题的划分。对于使用定义的划分矩阵,边界(由箭头标记)被移动。
请关注文章了解更多详情。
CatBoost 允许我们设置误分类成本矩阵 A 和对象的权重来计算 AUCμ。
让我们计算一个非常小的例子的 AUCμ,这个例子有 3 个类和 4 个对象:
让我们计算每个有序类对的 S(i,j ):
让我们用 Catboost AUCμ计算相同的指标,并确保一切都是正确的:
我们可以看到 AUCμ相当高,但实际上,算法性能很差,精度为 0.25。因此,在培训期间评估其他重要指标是合理的。
AUCμ是评估算法在多分类问题中分类能力的一个很好的概括度量。在文章的第 4.3 节中可以看到更多关于多类 AUC 计算的不同方法及其特性。
AUCμ可以解释为类别之间成对 AUC 的平均值。与 OneVsAll AUC 不同,AUCμ是单个值,因此它可以在用于过拟合检测和树修剪的训练期间用作评估度量。
排名的 AUC
对于 CatBoost 中的排名,有两种不同的 AUC。
经典 AUC
用于具有对数损失和交叉熵损失函数的模型。它具有与二元分类的 AUC 相同的公式:
aᵢ , aⱼ —预测对象的等级 i,j 。
对所有对象对 i,j 计算总和,使得: tᵢ=0,tⱼ=1 其中 t 是相关的。
上面的公式适用于目标值等于 1 和 0 的简单任务。如果我们有更多的目标值呢?
如果目标类型不是二进制,那么具有目标值 t 和权重 w 的每个对象 i 被替换为两个对象用于度量计算:
- 重量 wt 目标值为 1 的σ₁
- 重量为w(1t)的σ₂ ,目标值为 0。
目标值必须在范围*[0;1]* 。
让我们为一个小例子计算排名的经典 AUC。假设我们有 2 个文档,2 个请求,相应的相关性在范围[1,5]内,预测相关性在范围[0,1]内:
数据预处理后(详见笔记本),我们得到:
让我们计算 AUC:
排名 AUC
AUC 排名用于损失函数排名。
*aᵢ,*是预测对象的等级 i,j 。
对所有对象对 i,j 计算总和,使得: tᵢ < tⱼ 其中 t 是相关的。
排名 AUC 直接衡量正确排名对的数量。问题是指标的计算不考虑组。在我们的例子中,我们有组(请求),并且我们可能想要测量组内的质量,但是目前,AUC 是在数据集上计算的,并且如果例如一个请求的前一个文档的排名低于另一个文档的前一个文档,而真实排名相反(但是仍然是每个文档的前一个),则 AUC 惩罚我们。
AUC 用于排序的另一个问题是,它没有将顶部对象与其他对象区分开来。如果我们有许多不相关的文档,这些文档被模型排序为不相关,但排名在前 10 位,AUC 可能仍然很高,因为不相关对象的“尾巴”比相关对象的排名低。
概观
AUC 是一种广泛使用的度量标准,用于衡量模型区分类别和正确排序来自不同类别/具有不同相关性的对象的能力。AUC 是不可微的,因此不能用作损失函数,但作为一种度量,它提供了很多信息,非常有用。
我们研究了以下 AUC 类型:
- 二元分类的 AUC。这是一个经典的度量标准,用来衡量模型的质量。ROC 曲线允许选择概率阈值以满足所需的假阳性或假阴性率。
- 多类分类的 AUC:OneVsAll 和 AUCμ。OneVsAll AUC 有助于控制每个类的算法性能,但不能用作防止过度拟合的度量。相反,AUCμ是一个很好的概括指标,但是不能检测一个类的问题。
- 排名的 AUC:经典 AUC 和排名 AUC。AUC 适合于排序任务,因为它被设计成测量算法如何区分类别,并且它简单地转移到区分相关和不相关的对象。但是 AUC 没有考虑到在排序问题中,前 n 个位置非常重要,并且平等地对待每个正确排序的文档对。
要更深入地了解数据处理、计算细节以及在 CatBoost 中使用 AUC 的示例,请参见 iPython 笔记本,代码见 CatBoost 教程。
AUC-ROC:简化
直觉的理解
来源:https://pxhere.com
介绍
机器学习的一个重要方面是模型评估。你需要一些机制来评估你的模型。这就是这些性能指标发挥作用的地方,它们让我们感觉到你的模型有多好。如果你熟悉机器学习的一些基础知识,那么你必须了解这些指标,如准确度、精确度、召回率、auc-roc 等。
假设您正在处理一个二元分类问题,并提出了一个准确率为 95%的模型,现在我问您这实际上意味着什么,您可以很快说出您的模型做出的 100 个预测中,有 95 个是正确的。让我们更进一步,现在基本的指标是回忆,我问同样的问题,你可能会花一点时间,但最终你会得出一个解释,比如在 100 个相关数据点(一般为正类)中,你的模型能够识别其中的 80 个。到目前为止,我们假设您使用 AUC-ROC 作为指标评估您的模型,得到 0.75 的值,我再次问您同样的问题,0.75 或 75%意味着什么,现在您可能需要思考一下,有些人可能会说模型有 75%的机会正确识别数据点,但现在您应该已经意识到不是这样。让我们试着对分类问题中最流行的一个性能指标有一个直观的理解。
历史
如果你参加过任何在线机器学习竞赛/黑客马拉松,那么你一定遇到过曲线下面积-接收器操作员特征,也称为 AUC-ROC,其中许多人将它作为他们分类问题的评估标准。让我们承认,当你第一次听说它的时候,你一定有过这样的想法,这个又长又花哨的名字是怎么回事?ROC 曲线的起源可以追溯到第二次世界大战,它最初用于分析雷达信号。美国陆军试图测量他们的雷达接收机在信号噪声中正确识别日本飞机的能力。现在我们有了一个小小的起源故事,让我们进入正题
几何解释
这是你在谷歌上搜索 AUC-ROC 时会遇到的最常见的定义。基本上,ROC 曲线是显示分类模型在所有可能阈值下的性能的图表(阈值是一个特定值,超过该值,您就说某个点属于特定类别)。曲线绘制在两个参数之间
- 真阳性率
- 假阳性率(FPR)
在理解 TPR 和 FPR 之前,让我们先快速看一下混淆矩阵。
来源:知识共享
- 真阳性:实际阳性和预测阳性
- 真阴性:实际阴性,预测为阴性
- 假阳性(I 型错误):实际阴性但预测为阳性
- 假阴性(II 型错误):实际阳性但预测为阴性
简单来说,你可以把假阳性称为假报警,把假阴性称为漏警*。* 现在让我们看看 TPR 和 FPR 是什么情况。
作者图片
作者图片
基本上,TPR/回忆/灵敏度是正确识别的阳性样本的比率**,FPR 是错误分类的阴性样本的比率**,如前所述,ROC 只不过是 TPR 和 FPR 之间跨越所有可能阈值的图,AUC 是该 ROC 曲线下的整个面积。****
来源:知识共享
概率解释
我们看了几何解释,但我想这仍然不足以开发 0.75 AUC 实际含义背后的直觉,现在让我们用概率的观点看一下 AUC-ROC。
让我先谈谈 AUC 的工作,稍后我们将在此基础上建立我们的理解
AUC 衡量模型区分类别的能力
0.75 的 AUC 实际上意味着假设我们取属于不同类别的两个数据点,那么有 75%的机会模型能够分离它们或者正确地对它们进行排序,即正点比负类具有更高的预测概率。(假设较高的预测概率意味着该点理想情况下属于正类)
下面举个小例子,让事情更清楚。
**╔═══════╦═══════╦═════════════╗
║ Index ║ Class ║ Probability ║
╠═══════╬═══════╬═════════════╣
║ P1 ║ 1 ║ 0.95 ║
║ P2 ║ 1 ║ 0.90 ║
║ P3 ║ 0 ║ 0.85 ║
║ P4 ║ 0 ║ 0.81 ║
║ P5 ║ 1 ║ 0.78 ║
║ P6 ║ 0 ║ 0.70 ║
╚═══════╩═══════╩═════════════╝**
这里我们有 6 个点,其中 P1、P2、P5 属于第 1 类,P3、P4、P6 属于第 0 类,并且在概率列中有相应的预测概率,正如我们说过的,如果我们取两个属于不同类的点,那么模型秩正确排序它们的概率是多少
我们将采取所有可能的配对,这样一个点属于类 1,另一个点属于类 0,我们将有总共 9 个这样的配对,下面是所有这 9 个可能的配对
**╔═══════╦═════════╦═══════════╗
║ Index ║ Pair ║ IsCorrect ║
╠═══════╬═════════╬═══════════╣
║ 1 ║ (P1,P3) ║ Yes ║
║ 2 ║ (P1,P4) ║ Yes ║
║ 3 ║ (P1,P6) ║ Yes ║
║ 4 ║ (P2,P3) ║ Yes ║
║ 5 ║ (P2,P4) ║ Yes ║
║ 6 ║ (P2,P6) ║ Yes ║
║ 7 ║ (P3,P5) ║ No ║
║ 8 ║ (P4,P5) ║ No ║
║ 9 ║ (P5,P6) ║ Yes ║
╚═══════╩═════════╩═══════════╝**
此处,列 isCorrect 表示所提及的点对是否是基于预测概率的正确排序,即 1 类点比 0 类点具有更高的概率,在这 9 个可能的点对中的 7 个中,1 类点的排序高于 0 类点,或者我们可以说,如果选择一对属于不同类的点,模型将有 77%的机会能够正确区分它们。沃拉。现在,我认为您可能对这个 AUC 数字有一点直觉,只是为了澄清任何进一步的疑问,让我们使用 scikit learn 的 AUC-ROC 实现来验证它
AUC 验证的样本代码(图片由作者提供)
何时使用
尽管如此,AUC-ROC 在某些地方可能并不理想。
- AUC-ROC 在数据集严重失衡的情况下效果不佳,为了给出一些直觉,让我们回顾一下这里的几何解释。基本上 ROC 是 TPR 和 FPR 之间的情节(假设少数阶级是积极阶级),现在让我们再次仔细看看 FPR 公式
作者图片
FPR 的分母有一个真阴性作为一个因素,因为阴性类占多数。FPR 的分母由真阴性主导,这使得 FPR 对少数类预测的任何变化不太敏感(由于分母较高,假阳性数字的任何变化在 FPR 没有得到适当反映)。为了克服这个问题,使用精确召回曲线代替接收方操作者特征曲线,然后计算 AUC,尝试自己回答这个问题精确召回曲线如何处理这个问题(提示:比较 PR 曲线和 ROC 输入,召回和 TPR 是相同的,技术上只有 FPR 被精确代替,只需比较两者的分母,并尝试评估 PR 曲线中不平衡问题是如何解决的)**
- AUC-ROC 试图衡量分类的等级排序是否正确,它没有考虑实际预测的概率,让我用一小段代码来说明这一点
**import pandas as pdy_pred_1 = [0.99,0.98,0.97,0.96,0.91,0.90,0.89,0.88]
y_pred_2 = [0.99,0.95,0.90,0.85,0.20,0.15,0.10,0.05]
y_act = [1,1,1,1,0,0,0,0]
test_df = pd.DataFrame (zip(y_act,y_pred_1,y_pred_2),columns=['Class','Model_1','Model_2'])
test_df**
两个样本模型(图片由作者提供)
如上所述,我们有两个模型 Model_1 和 Model_2,这两个模型都很好地隔离了这两个类别,但是如果我让你从它们中选择一个,你会选择哪一个,请稍等片刻,让我先画出这些模型的概率。
**import matplotlib.pyplot as pltcols = ['Model_1','Model_2']
fig,axs = plt.subplots(1,2,figsize=(15,5))
for index,col in enumerate(cols):
sns.kdeplot(d2[d2['Status']==1][col],label="Class 1",shade=True,ax=axs[index])
sns.kdeplot(d2[d2['Status']==0][col],label="Class 0",shade=True,ax = axs[index])
axs[index].set_xlabel(col)
plt.show()**
预测概率分布(图片由作者提供)
如果之前有任何轻微的疑问,我想现在你的选择将是非常清楚的,Model_2 是一个明显的赢家。但两者的 AUC-ROC 值是相同的,这是它的缺点,它只是测量模型是否能够正确地对类进行排序,它不查看模型区分两个类的程度,因此,如果您需要使用实际预测的概率,那么 AUC-ROC 可能不是正确的选择,对于那些好奇的人来说,log loss 是解决此问题的一种度量
因此,理想情况下,当数据集没有严重的不平衡,并且您的用例不要求您处理实际预测的概率时,应该使用 AUC-ROC。
多类别的 AUC
对于多类设置,我们可以简单地使用一个对所有的方法,每个类都有一条 ROC 曲线。假设您有四个类别 A、B、C、D,那么所有四个类别都有 ROC 曲线和相应的 AUC 值,即,一旦 A 是一个类别,B、C 和 D 组合起来就是其他类别,类似地 B 是一个类别,A、C 和 D 组合起来就是其他类别,等等。
结束注释
AUC-ROC 是您在处理分类问题时会经常遇到的东西,无论是在线黑客马拉松还是您的组织中分配给您的项目。我希望我能够对 AUC-ROC 到底是什么以及何时使用它给出一些基本的理解。如果您想讨论什么或有任何建议,可以通过以下方式联系我:
****领英:【https://www.linkedin.com/in/ravindra-sharma-832a04156 ****
参考
[1]: 《利用受试者工作特征(ROC)曲线分析分类模型:历史兴趣的最后注解》 (PDF)。犹他大学数学系。犹他大学数学系。检索于 2017 年 5 月 25 日
使用 PyTorch 的生态系统工具进行音频分类
PYTORCH 生态系统
torchaudio 和 Allegro 列车介绍
torchaudio 和 Allegro 列车的音频分类
音频信号无处不在。因此,对各种场景的音频分类越来越感兴趣,从听力受损者的火警检测,通过用于维护目的的引擎声音分析,到婴儿监控。虽然音频信号本质上是时间性的,但在许多情况下,可以利用图像分类领域的最新进展,并使用流行的高性能卷积神经网络进行音频分类。在这篇博文中,我们将通过使用将音频信号转换到频域的流行方法来演示这样一个例子。
这篇博文是关于如何利用 PyTorch 的生态系统工具轻松启动 ML/DL 项目的系列文章的第三篇。之前的博文主要关注图像分类和超参数优化。在这篇博文中,我们将展示如何使用 Torchaudio 和 Allegro Trains 实现简单高效的音频分类。
基于卷积神经网络的音频分类
近年来,卷积神经网络(CNN)已被证明在图像分类任务中非常有效,这导致了各种架构的设计,如 Inception、ResNet、ResNext、Mobilenet 等。这些 CNN 在图像分类任务上实现了最先进的结果,并提供了各种现成的经过预先训练的骨干。因此,如果我们能够将音频分类任务转移到图像领域,我们将能够利用这些丰富的主干来满足我们的需求。
如前所述,我们希望将音频信号转换成图像,而不是直接使用声音文件作为振幅与时间信号。以下预处理是使用这个脚本在 YesNo 数据集上完成的,该数据集包含在 torchaudio 内置数据集中。
作为预处理的第一阶段,我们将:
- 使用 torchaudio 读取音频文件
- 以固定的采样率对音频信号进行重新采样 —这将确保我们将使用的所有信号都具有相同的采样率。理论上,采样信号可以代表的最大频率略低于采样率的一半(称为奈奎斯特频率)。由于 20 kHz 是人类通常能听到的最高频率,44100 Hz 的采样率被认为是最受欢迎的选择。然而,在许多情况下,为了减少每个音频文件的数据量,移除较高的频率被认为是合理的。因此,对于低比特率的 MP3 文件,20050 Hz 的采样率已经相当普遍。在我们的例子中,我们将使用这个采样率。
- 创建单声道音频信号 —为简单起见,我们将确保我们使用的所有信号都有相同数量的声道。
这种预处理的代码如下:
生成的 matplotlib 图如下所示:
来自 YESNO 数据集的音频信号时间序列
现在是时候将这个时序信号转换到图像域了。我们将通过将其转换为频谱图来实现,频谱图是信号频谱随时间变化的直观表示。为此,我们将使用对数标度的 mel 谱图。mel 频谱图是一种频谱图,其中频率被转换为 mel 标度,Mel 标度考虑了这样一个事实,即人类在较低频率下比在较高频率下更善于检测差异。mel 音阶会转换频率,使音高距离相等的人听起来距离相等。
因此,让我们使用 torchaudio 转换,并将以下代码行添加到我们的代码片段中:
现在,音频文件被表示为二维频谱图图像:
Mel 光谱图(上图)及其对数标度版本(下图)
这正是我们想要实现的。音频分类问题现在转化为图像分类问题。
使用 Allegro-Trains、torchaudio 和 torchvision 进行音频分类
Pytorch 的生态系统包括各种开源工具,可以启动我们的音频分类项目,并帮助我们管理和支持它。在这篇博客中,我们将使用其中的三种工具:
- Allegro Trains 是一款开源的机器学习和深度学习实验管理器和 MLOps 解决方案。它提高了人工智能团队的效率和生产力,以及本地和云 GPU 的利用率。Allegro Trains 帮助研究人员和开发人员零集成地管理复杂的机器学习项目。
- Torchaudio 是一个由 I/O 函数、流行数据集和常见音频转换组成的包。
- Torchvision 是一个由流行的数据集、模型架构和计算机视觉的通用图像转换组成的包。
为了简单起见,我们不会在这个博客中解释如何安装一个 Trains-server 。因此,实验将被记录在 Allegro Trains 演示服务器上。有关如何部署自托管 Trains 服务器的更多信息,请参见 Allegro Trains 文档。
出于本博客的目的,我们将使用 UrbanSound8K 数据集,该数据集包含来自 10 个类别的 8732 个带标签的声音摘录(< =4s),包括狗叫、警笛和街头音乐。我们将使用预训练的 ResNet 模型来分类这些音频文件。
我们将从初始化 Allegro Trains 来跟踪我们所做的一切开始:
接下来,我们将确保代码中没有隐藏“神奇数字”,并且所有脚本参数都反映在实验管理器 web 应用程序中。当编写 python 脚本时,可以使用流行的 argparse 包,Allegro Trains 会自动拾取它。在我们编写 Jupyter 笔记本示例时,我们将定义一个配置字典,并将其连接到 Allegro Trains 任务对象:
现在是时候定义我们的 PyTorch 数据集对象了。这个对象应该包括数据加载和数据预处理。数据集元数据的加载在类的构造函数中完成,并基于 UrbanSound8K 数据集结构进行配置。因此,它将如下所示:
接下来我们要做的是定义 Dataset 类的 __ getitem__ 方法。如前所述,我们希望这部分执行几个预处理步骤:
- 加载音频文件
- 将其重新采样到预配置的采样速率,注意这里这样做是为了简单起见。对音频文件进行重新采样是一项耗时的功能,会显著降低训练速度,并导致 GPU 利用率下降。建议在训练周期之前对所有文件执行该预处理功能。
- 将其转换成单声道音频信号
- 将其转换成 Mel 频谱图信号
除此之外,我们希望所有转换后的信号具有相同的形状。因此,我们将把所有 Mel 光谱图裁剪到一个预先配置的长度,并把比这个长度短的光谱图补零。结果应该是这样的:
现在最精彩的部分来了。由于我们已经将问题从音频域转换到图像域,所以我们不需要担心定义模型。我们可以使用 Torchvision 自带的内置模型之一。我们决定选择有效且健壮的 ResNet 模型。由于数据集很小,我们希望降低过度拟合的风险,因此我们将使用小而有效的 ResNet18 模型。除了我们刚刚采取的这个伟大的捷径,Torchvision 使我们能够加载在 Imagenet 上预先训练的模型,因此训练将更短,更有效。
我们需要做的就是使模型的输入层和输出层适应我们的数据。这很容易做到,如下所示:
就是这样!我们可以开始训练我们的模型了。在这篇博客中,我们不会讨论培训和评估循环的结构。它们非常简单明了——你可以在完整笔记本中查找它们。我们只需注意,在训练和评估过程中,我们确保将音频信号、标量(损耗、精度)和频谱图报告给 PyTorch 的内置 TensorBoard 类,以便进行调试。Allegro Trains 会自动拾取发送到 TensorBoard 的所有报告,并将它们记录在 web 应用程序中您的实验下。
我们剩下要做的就是使用火车代理在本地或远程机器上执行我们的 Jupyter 笔记本,并在 Allegro Trains 的 web 应用上观看我们的培训进度。
Allegro Trains webapp 中标量报告的快照
因为我们确保每隔几个迭代就报告调试数据,所以我们可以检查 Allegro Trains webapp 中的调试样本部分,并确保输入模型的数据是有意义的。我们可以听原始音频信号或检查频谱图:
Mel 光谱图调试报告的快照
音频调试样本的快照
摘要
自动音频分类是一个不断发展的研究领域,包括语音、音乐和环境声音等领域。这一新兴领域可以极大地受益于丰富的经验和为计算机视觉任务开发的各种工具。因此,利用 PyTorch 生态系统开源工具可以推动您的音频分类机器学习项目。您不仅可以享受一套免费的开源生产力工具,还可以通过将信号从时域转换到频域,使用一套强大且经过验证的预训练计算机视觉模型。
在本教程中,我们演示了如何使用 Tochaudio、Torchvision 和 Allegro Trains 来完成简单有效的音频分类任务。通过零集成工作和零成本,您可以获得一个通用的培训和评估脚本。要了解更多信息,请参考快板列车文件、火炬广播文件和火炬广播文件。
在本系列的下一篇博文中,我们将展示如何使用 PyTorch 生态系统轻松创建机器学习管道。这对于我们有重复任务序列的情况非常有效。比如预处理和训练,就像我们在这篇博文开头提到的。
原载于 2020 年 10 月 18 日https://allegro . ai。
音频开始检测:使用 Librosa 为棒球应用程序准备数据
使用声音来识别视频中的击球时间
介绍
我希望为棒球应用程序建立一个深度学习项目,其中一个挑战是数据收集。我需要很多击球手击球的短片。但是我在网上找不到这种数据集,因此,我决定自己收集和制作数据集。
我发现的大多数棒球击球视频在一个长视频剪辑中包含多次击球,例如:
我需要找到击球的瞬间,把它们剪下来,分成短片。一种简单的方法是手工操作,但是这非常费时费力。
我需要一个工具来自动完成这项工作。
受郑健国作品《用深度学习视频分析构建机器人裁判》的启发,我决定尝试一下 【发病检测】 。
经过一些研究和阅读教程,如这个,我使用 librosa 的发作检测功能。
加载视频
第一步是从 YouTube 下载并加载视频。我用 pafy 做的。
filename='batting_pratice'
url='https://www.youtube.com/watch?v=dbZy8Q6J7pw'
video = pafy.new(url)
clip = video.getbest(preftype="mp4")
clip.download()
os.rename(clip.filename,filename+'.mp4')
该视频现已下载并保存为“batting _ pratice.mp4”
加载音频
然后我可以用 librosa 加载音频。
x, sr = librosa.load(filename+'.mp4')
如果你感兴趣就去玩吧。
ipd.Audio(data=x, rate=sr)
并绘制波形图
plt.figure(figsize=(14, 5))
librosa.display.waveplot(x, sr=sr)
plt.show()
音频波形图(图片由作者提供)
你可以看到有一些尖刺,是击球的声音。工作是确定它们的时间。
应用过滤器
一个额外的步骤是使用高通滤波器过滤一些低频噪声。可以使用 scipy 来完成。
from scipy.signal import butter,filtfilt**def** butter_highpass(data,cutoff, fs, order=5):
"""
Design a highpass filter.
Args:
- cutoff (float) : the cutoff frequency of the filter.
- fs (float) : the sampling rate.
- order (int) : order of the filter, by default defined to 5.
"""
# calculate the Nyquist frequency
nyq = 0.5 * fs
# design filter
high = cutoff / nyq
b, a = butter(order, high, btype='high', analog=False)
# returns the filter coefficients: numerator and denominator
y = filtfilt(b, a, data)
return yx_f=butter_highpass(x,1000, sr, order=5)
发病检测
然后我们可以开始发作检测,我们使用 librosa.onset 。详细介绍可以在他们的 doc 中找到。
o_env = librosa.onset.onset_strength(x_f, sr=sr)
times = librosa.frames_to_time(np.arange(len(o_env)), sr=sr)
onset_frames = librosa.util.peak_pick(o_env, 3, 3, 3, 5, 0.3, 100)
在这之后,我们应该看到存储在 onset_frames 中的峰值。
然后我们可以绘制它并检查。
D = np.abs(librosa.stft(x_f))plt.figure(figsize=(15,10))ax1 = plt.subplot(2, 1, 1)
librosa.display.specshow(librosa.amplitude_to_db(D, ref=np.max),
x_axis='time', y_axis='log')
plt.title('Power spectrogram')plt.subplot(2, 1, 2, sharex=ax1)
plt.plot(times, o_env, label='Onset strength')
plt.vlines(times[onset_frames], 0, o_env.max(), color='r', alpha=0.9,
linestyle='--', label='Onsets')plt.axis('tight')
plt.legend(frameon=True, framealpha=0.75)
plt.show()
发病检测(图片由作者提供)
看起来我们确定了所有的发病点。
现在,我们可以将 onset_frames 转换为时间:
onset_times = librosa.frames_to_time(onset_frames)
这会返回一个时间数组。
然后,我们可以将数据放入数据帧中,并在特定时间创建 youtube URLs。
检查其中一个示例。成功了!
切断视频
然后,我们可以使用计时将视频剪切成短片。我想要 3 秒的剪辑,所以我从(开始时间-1.5)到(开始时间+1.5)开始。这可以使用 ffmpeg 来完成。
for hit_time in onset_times:ffmpeg_extract_subclip(filename+'.mp4',round(hit_time)-1.5,
round(hit_time)+1.5,
targetname=filename+'/'+filename+'_'+str(int(hit_time))+".mp4")
现在,我有了一个工具,可以根据声音来检测击球,并自动进行切割。下一步将使用该工具收集更多数据,用于进一步培训。
感谢阅读。欢迎提出建议和意见。
在这里支持我:【https://medium.com/@c.kuan/membership】T2
具有深度学习的音频源分离
基本上是一种听觉超能力
作者:阿卡什·库马尔、桑尼·卡雷尔、普拉吉瓦尔·波卡雷尔、卡尼什克·辛格、凯莉·特雷维尼奥和米盖尔·加尔萨
想象一下,走进一个拥挤嘈杂的自助餐厅,能够将你听到的所有噪音“解混”到各自的扬声器中。这就是音频源分离的问题:将输入的混合音频信号分解成它最初来自的源。
音频源分离,也称为鸡尾酒会问题,是音频领域最大的问题之一,因为它在许多情况下都有实际用途:识别歌曲的人声,帮助聋人在嘈杂的区域听到扬声器,在逆风骑自行车时隔离电话中的声音,你会明白这一点。
我们提出了一种利用深度学习的优势来解决这个问题的方法。
我们的数据
在处理这个问题时,我们使用了 UrbanNoise8K 和 LibriSpeech 数据集。UrbanNoise 数据集为我们提供了各种背景噪音,而 LibriSpeech 数据集为我们提供了各种人在没有任何背景噪音的情况下阅读一本书。我们自己为音调分离生成音调。
我们的方法
在对该主题进行初步研究后,我们决定使用频谱图来处理音频,而不是原始波形。虽然 Lyrebird 的 MelGAN 和 OpenAI 的全新 Jukebox 在生成原始音频波形方面取得了成功,但我们项目的时间框架和神经网络的深度不允许我们与原始音频进行交互,因为它非常复杂。使用频谱图(原始 STFT 输出),我们不会丢失有关音频波形的信息,并且可以以最小的损失重建它。
为了新奇,我们决定尝试不同的独特损失函数和训练架构,概述如下。
模型
我们尝试了许多不同的模型进行实验,从普通卷积神经网络到密集层,但我们决定采用两种模型 A 和 b。这两种模型都具有下述 U-Net 风格的架构。
U-Net 架构最初在图像分割中获得成功,但后来也被用于光谱图分析。下图总结了架构。它包括缩减像素采样层,将图像的高度和宽度减少到一个点。然后使用某种策略对图像进行上采样。残差(跳过)连接被添加到在相应的上采样层和下采样层之间具有相同形状的层之间。
适用于音频的 U-Net 模型。从这张纸上检索。
我们在 PyTorch 中实现了模型 A,它基于上面参考资料中引用的 Choi 等人的论文中的图表。这个想法非常类似于 U-Net 的下采样和带有跳跃连接的上采样。神经变换层仅改变图像中通道的数量,而下采样/上采样层将图像的高度和宽度改变 2 倍(简单卷积)。神经变换层和下采样层的数量从 7 到 17 不等。
每个神经变换层是一个由 4 个批处理范数、ReLU 和卷积运算组成的密集块,如下图所示。密集块意味着每个较小的块接收所有先前块的输出作为输入,本质上是将通道添加到“全局状态”变量上。下图说明了这个想法。
神经变换层图。从这张纸上检索。
模型 B 是模型 A 的缩小版,没有批次标准层。这在下面引用的 Belz 的博客文章中取得了成功。
模型 A 和模型 B 的输入是混合信号的频谱图。对于模型 A,输出值是预测语音的声谱图,目标值是目标孤立语音的声谱图。模型 B 的一个变化是,输出值不是预测语音,而是预测噪声的声谱图,目标是目标噪声的声谱图。通过从输入混合信号中减去预测的噪声信号来预测模型 B 中的语音。
我们使用两种不同类型的光谱图。一种类型是简单的 STFT 输出,其产生复数值频谱图,并被表示为代表实部和虚部的双通道图像。另一种类型仅涉及将 STFT 的幅度作为单通道图像馈送,并在最后接收幅度谱图。用于重建的短语只是初始 STFT 相位(相位不变),如上图所示。
损失函数
损失函数是优化最重要的部分之一,因为它决定了最小化哪个表面。我们测试了以下损失函数,并使用它们与加权的线性组合。
为了理解损失函数,让我们定义一些变量。v 是语音谱图信号。n 是噪声频谱图信号。m 是输入到神经网络的混合音频信号。
M = V + N
V* 是生成器看到 m 后给出的预估语音。
M →发电机→ V*
目标是得到尽可能接近真实声音的估计声音。
目标: V* = V
V 上的 MSELoss,V*
输出和目标之间的常规元素级 ms 损耗是我们损耗函数中的主要项之一。这是一种广泛使用的稳健损失,但它没有考虑特征的局部性。
V,V*上的噪声加权 MSE loss
输出和目标之间的常规元素 MSELoss,但基于该点的真实噪声强度进行了额外的元素加权。我们希望这将有助于消除噪音,而不是重建声音(这相对容易做到)。
休伯在 N,N*上的损失
Huber 损耗本质上是 MSE 损耗和 MAE 损耗的分段函数,在低误差值时,它表现得像 MSE,但是在某个阈值之后,它变成 MAE。这惩罚了小于 MSE 的异常值,但是在低损失值下具有相似的 MSE 属性。我们认为这可以帮助微调输出和目标之间的误差。
V,V*上的可微结构相似性(SSIM)损失
与 MSELoss 不同,SSIM 损失最初用于通过考虑位置来比较两幅图像的结构相似性。这个想法是,MSELoss 对于两幅非常相似的图像中的轻微偏移是不鲁棒的。这个术语可以捕捉两个光谱图的整体结构,并查看它们是否大致相同。
源投影损失
我们自己想出了这个损失,与噪声加权 MSELoss 的想法相同:专门去除噪声。与其在谱图空间中工作,我们尝试对谱图的像素值运行 MSELoss,不如在更简单的空间中工作?基本思想是,您可以将所有频谱图视为大向量,并通过投影回真实语音和真实噪声向量加上一些正交噪声伪像来分解估计的语音向量。
分解:V = aV+bN*+R
目标现在变为简单地将 a,b,R 分别减少为 1,0, 0 。
目标:V =V→V = 1V+0N**+0
为此,我们可以将 a,b, R 上的 MSELoss 设为 1,0, 0,。
该损失函数直接测量与真实语音和真实噪声部分的关系。
然而,当在实践中应用时,出现了一个问题。大部分损失来自最小化 R 噪声误差的幅度,而不是减少投射到噪声上的量。如果这一项的权重较低,那么就会出现 R 增长过快的问题,并在结果中引入不必要的噪声伪像,使这种损失弊大于利。
【计算机】优化程序
除非另有说明,学习率为 0.001 的 Adam 优化器在任何地方都被使用。在源投影实验中,使用了 SGD,因为它在输出中创建了更少的 R 矢量伪像(从 V + N 到 V 采取了更直接的直线路径)。
色调分离
为了从头开始,我们决定简单地分离一个被恒定音调覆盖的声音。我们对模型的输入是一个人说话,背景中播放一种音调,模型试图将声音从音调中分离出来,只返回声音。运行模型 A,我们得到了非常好的结果,如下所示。
输入:
[## mix0.wav
编辑描述
drive.google.com](https://drive.google.com/open?id=1s0U2uXMw-xT1MU9ZzlFON2gFAQnmDwwM)
输出:
[## vp0_naive.wav
编辑描述
drive.google.com](https://drive.google.com/open?id=1-vVWxPjqA-P_Ov-a15H63sE7dh1rCc9a)
培训损失图表:
空调噪声分离
作为一个更高级的挑战,我们决定分离被空调噪音覆盖的声音。我们对模型的输入是一个人说话,背景中有交流噪声,模型试图分离交流噪声,只返回说话的人。运行模型 A,我们得到的结果如下所示。
培训损失图表:
输入音频:
[## 输入. wav
编辑描述
drive.google.com](https://drive.google.com/open?id=1_7q0LLQ52WFUCDTiWze0f2olRCu-2rLC)
输出音频:
[## 输出. wav
编辑描述
drive.google.com](https://drive.google.com/open?id=13XY25Y3GK__ZX7TeRy7Wq0l2Pso7obNW)
用 GAN 方法分离空调噪声
为了改进之前的结果,我们决定采用 GAN 方法。众所周知,甘很难训练,而且很不稳定。考虑到这一点,我们决定预先训练生成器和鉴别器,本质上是在训练过程中给它们一个“开端”。我们希望这将增加 GAN 的训练稳定性和收敛性。
由于我们已经有了一个训练过的生成器,我们预先训练了一个鉴别器网络来区分真实语音和来自生成器的估计语音。这是鉴频器的先验训练损失图:
在预训练之后,我们在一个经典的对抗设置中设置发生器和鉴别器并进一步训练。发生者损失是先前损失项与欺骗鉴别者的新的对抗性损失的组合。
以下是发电机的训练损耗:
这是鉴别器的训练损失:
以下是我们在所有培训后取得的成果:
输入音频:
[## 输入. wav
编辑描述
drive.google.com](https://drive.google.com/open?id=1Yy06WGs84DNcVbeKdpnOEOn6auXpkvFX)
输出音频:
[## 输出. wav
编辑描述
drive.google.com](https://drive.google.com/open?id=1rmFPAqOTv3IeQe5_1yhClcIWgPyFv_0g)
虽然这听起来不太好,但我们断定这是因为我们的发电机不够深。我们为此总共使用了 7 个神经变换层,当用 GPU 训练时,可以很容易地增加到 17 或更高。
狗叫声分离
在我们的一个实验中,我们只在嘈杂的演讲中训练模型 B,对于噪音,我们从噪音数据集中提取不同的狗叫声音。该模型使用 10 个时期的 5000 个嘈杂的语音进行训练。为了便于训练模型,每个有噪声的语音音频保持 1 秒的长度。
在训练该模型之后,我们使用该模型来预测干净的语音。下面我们展示了输入噪声语音、目标干净语音和预测语音的频谱图和音频剪辑。
输入:
[## 输入. wav
编辑描述
drive.google.com](https://drive.google.com/open?id=1-b27xEeqiWwDXFlwCM-igicFma_Gfy9U)
输出:
[## 输出. wav
编辑描述
drive.google.com](https://drive.google.com/open?id=1hxZGgl5BA9WDZz8VaEi56EqjqsnO7Olh)
总体而言,该模型在训练数据和验证数据上都表现良好。预测的 80 毫秒的干净语音音频剪辑听起来非常像真实的声音。
网站(全球资讯网的主机站)
这是我们网站的链接:https://audio-separation.herokuapp.com/
简而言之,我们的网站接受任意长度的嘈杂音频输入,通过我们的模型输入片段,然后将它们组合在一起,返回声音的干净版本。用户可以选择将声源添加到他们的输入中,以测试模型是否有效。我们使用 React.js 开发前端,使用 Python Flask 开发后端。我们面临的主要挑战是后端处理前端发送的任意长度的音频文件。此外,我们不得不面对 Heroku cloud 实例内存不足的问题,因为 Tensorflow 和 PyTorch 占用了大量空间。为了解决这个问题,我们转向了 AWS,它提供了更大的存储选项。一旦我们解决了安装正确的包和拥有足够内存的后勤问题,我们就能够使用 Material-UI 和 React.js 开发前端。
来自我们网站的截图
结论
我们在这个项目中完成了大量的工作。我们的模型 A 在色调分离方面表现得非常好,但在去除复杂的空调噪音时有其缺点,因为它太浅了。我们的 B 型车比 A 型车小,在狗叫声中表现良好。模型 B 中的变化是我们预测了噪音而不是更复杂的声音,并从我们的输入声音中去除了预测的噪音。另一方面,在模型 A 中,我们使用了更直接的方法,我们试图直接预测无声的声音。在这两个模型中,我们自己版本的 U-net 架构都发挥了关键作用。
我们的主要方法是创建一个鉴别器网络和生成器,独立地对它们进行预训练,然后过渡到对抗式训练,如 GAN。对于该方法,我们使用投影损失通过将估计的噪声投影到真实语音和真实噪声以及剩余项来直接去除噪声。然后使用 MSE,我们能够尝试训练我们的模型忽略真实噪声和剩余项分量。虽然这种方法无法产生我们希望的空调噪音结果,但我们相信,如果我们能够用更强的计算能力和更深的网络来训练它,它将会成功。
未来的工作
这个项目还有相当多的工作要做。从尝试鸡尾酒会问题的完整解决方案到通用噪声分离器,我们希望看到更多的成果。在这个项目中,我们将采取的下一步措施包括首先尝试创建能够学习分离各种噪音的模型。虽然我们已经能够创建模型来处理狗叫等个体噪音,但更复杂的噪音,如警笛声,却超出了我们的能力范围。在此之后,我们期望继续将这些单独的模型结合起来,以创建一个单一的更通用的模型,可以从语音中消除任何类型的噪声。在这里,我们甚至可以更进一步,尝试识别我们正在消除的噪声。最后,我们的最终目标是解决多个扬声器,特别是 GAN。这将是一个更具挑战性的问题,因为我们必须从噪音中识别出语音,并试图将每个声音从其他声音中分离出来。
更多信息
Github 链接:https://github.com/akarshkumar0101/DSProject
来源:
- 【https://arxiv.org/pdf/1912.02591.pdf 号
- 【https://arxiv.org/pdf/1710.10779.pdf
- https://arxiv.org/abs/1710.11428
- https://pdfs . semantic scholar . org/b665/fee 51 fff 861 c 55319137916 a 10935193 BCB 0 . pdf
- https://pdfs . semantic scholar . org/1f 85/596488 b 67 EFC ba 51026 E1 ce 32 DCC d 1796176 . pdf
- https://towards data science . com/advanced-topics-in-deep-convolutionary-neural-networks-71ef 1190522d
- https://towards data science . com/speech-enhancement-with-deep-learning-36a 1991d 3d 8d
使用的 Python 库:
- 利布罗萨
- PyTorch
- 火炬报
- 皮托尔赫-SSIM
- 米尔评估
- NumPy
- Matplotlib
- tqdm
- 火炬摘要
使用机器学习算法的审计:金融数据科学用例
ML 算法在现实审计中的应用
弗兰克·维西亚在 Unsplash 上拍摄的照片
数据科学的世界充满了奇迹(除了独角兽!).它无处不在,在健康科学、太空探索、图像识别、机器人、欺诈检测等领域都有应用。如果你曾经在网飞或 Prime 上看过一些东西,那么你很有可能已经接触到了令人惊叹的电影推荐算法!
我们如何在一个典型的内部审计职能中运用 ML 技术来减少假阴性和提高效率。副作用:降低成本。
金融业也不例外,我们已经看到了组织向应用先进的数据科学技术进行见解生成、预测、预算和欺诈风险的巨大转变。
当我在日常审计中研究 ML 的用例时,作为一名财务专业人员,我们都面临的一个非常现实的问题是**“与标准有何不同”**?
假设您有 1,600 笔交易(或购买发票),其中每笔交易代表“购买数量”(体积)和为该数量支付的“金额”。为了识别任何异常值(即不遵循正常模式的交易),在典型的审计环境中,我们会尝试从总体中抽取随机样本,然后希望我们的“随机”抽样能够检测到任何此类异常。这有时既费时又事与愿违,因为我们有遗漏实际异常值的风险,这些异常值不会被我们的样本发现,因此会报告假阴性。这对审计职能的成本和效率都有不利影响。
因此,我尝试采用一种 ML 算法(KNN,下面会进一步解释)来解决上述问题,并自动进行异常检测。该算法使用发票的数量和金额特征,并计算 1,600 个这种发票集中的异常值。
现在好的算法或代码和我们讲的故事一样好。因此,在我讲述准则的本质之前,下面是一份一页的执行摘要或电梯演讲,可以与我们的业务利益相关方分享:
如果你想知道模型是如何建立的,请继续阅读下面的内容。
数据科学拯救
Python 中一个专门用于离群点检测建模的包叫做 PyOD 。这个包(我用 pip install pyod 安装的)提供了多种算法来检测异常值,并且非常容易实现。然而,在本文中,我将把自己限制在一个基于邻近度的模型的用例上,这个模型被称为 KNN 或 K-最近邻。 KNN 是一种数学模型,它测量到最近的第 K 个邻居的距离,并根据该距离识别数据中的异常值。这是一种分类算法,将异常值分类为“1”和“0”的二进制结果,或者说“是”或“否”。
以下是分步实施的方法:
第一步:数据集
对于任何数据科学项目,生成有意义的随机数据集与算法或代码本身一样重要。所以我强烈推荐阅读关于‘随机数据’和‘种子’的好资源。生成的数据集是一组 1600 张购买发票,代表两个特征,即当月购买的“数量”和为该发票支付的“金额”。下面是它看起来的样子(想象的但看起来仍然足够真实!)
为 KNN 建模生成的随机数据
第二步:想象
让我们使用 Plotly 散点图快速可视化数据。关于 的快速纲要,请参考我的文章 。
步骤 3:训练和测试模型
现在有趣的部分来了,我们实际上建立了我们的模型并训练了算法。这些是我通常会遵循的步骤:
- **预处理和缩放数据:**这有效地将数据标准化并缩放到 0 和 1 之间的值,这有助于处理现实生活中变化很大的大量数据集。然后,我们重塑数据集的特征(体积和数量),以便进一步处理。
from **sklearn.preprocessing** import **MinMaxScaler**
scaler = MinMaxScaler(feature_range=(0, 1))
df[[‘Volume’,’Amount’]] = scaler.fit_transform(df[[‘Volume’,’Amount’]])**# reshape the individual features to numpy arrays**
x = df['Volume'].values.reshape(-1,1)
y = df['Amount'].values.reshape(-1,1)X = np.concatenate((x,y),axis=1)
**2。分割训练和测试数据:**我使用了 80:20 的训练/测试分割。然后首先使用训练数据训练该模型,并使用测试数据测试该模型。由模型生成的异常分数的可视化为我们提供了正常和异常数据是如何分割的指示。
from sklearn.model_selection import train_test_split
**#split dataset into train and test data**
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
print (‘Train set:’, X_train.shape, y_train.shape)
print (‘Test set:’, X_test.shape, y_test.shape)**# train KNN detector**
from pyod.models.knn import KNN
clf_name = 'KNN'
clf = KNN(contamination=0.03, n_neighbors = 5) #assuming a 3% outliers based on some historical data
clf.fit(X_train)
**#raw anomaly score**
y_train_scores = clf.decision_scores_
**#Train predictions**y_train_pred = clf.predict(X_train) *#creates outlier labels (0 or 1)*
**#print size for sanity check**
print('Train score size: ',y_train_scores.shape)
print('Train prediction size: ',y_train_pred.shape)**# Now we have the trained KNN model, let's apply to the test data to get the predictions**
y_test_pred = clf.predict(X_test) # outlier labels (0 or 1)
**# Generate the anomaly score using clf.decision_function:**
y_test_scores = clf.decision_function(X_test)
**#print size for sanity check**
print('Test score size: ',y_test_scores.shape)
print('Test prediction size: ',y_test_pred.shape)**Output:**Train set: (1280, 2) (1280, 1)
Test set: (320, 2) (320, 1)Train score size: (1280,)
Train prediction size: (1280,)Test score size: (320,)
Test prediction size: (320,)
**3。可视化训练和测试分数:**让我们使用‘y _ train _ scores’和‘y _ test _ scores’将异常分数可视化为一个简单的直方图。注意异常的数量。
**#visualise training scores**
fig = px.histogram(y_train_scores)
fig.show()**#visualise test scores**
fig = px.histogram(y_test_scores)
fig.show() **# lets see the number of anomalies**
print('Anomalies in test data: ',np.count_nonzero(y_test_pred))
print('Anomalies in training data: ',np.count_nonzero(y_train_pred))**output:**
Anomalies in test data: 10
Anomalies in training data: 33
**4。将模型应用到给定的数据集:**现在,我已经使用了上面为这个示例生成的相同数据集来演示我们如何获得最终结果。
**#Apply model to the given data set**
y_pred=clf.predict(X)
y_pred_scores = clf.decision_function(X)
5。将所有这些放在一起:在这一步中,我们将预测标签 s ('0 ‘和’ 1 ')附加到数据集,可视化和对异常值 ('1 ')的过滤,以获得需要进一步调查的发票列表:
df1[‘Outliers’] = y_pred.tolist() #append list to copy of dataframe**#visualise data using plotly fro df1 dataframe**
fig = go.Figure(go.Scatter(x=df1['Volume'], y=df1['Amount'],mode='markers',marker=dict(size=df1['Amount']**0.26+3,color=df1['Outliers'],colorscale='rdylgn_r')))fig.update_layout(xaxis_showgrid=True, yaxis_showgrid=True, plot_bgcolor='whitesmoke',
title={
'text': 'Volume vs transaction size with anomalies',
'y':.88,
'x':0.5,
'xanchor': 'center',
'yanchor': 'top'},width=800,
height=600)
fig.update_xaxes(title= '------>Volume' ,showline=True, linecolor='black')
fig.update_yaxes(title= '------>Amount', showline=True,linecolor='black')#overlay the bars
fig.show()
**# Filter data on Outliers = 1**
Review_sample=df1.loc[df1[‘Outliers’] == 1].reset_index()
Review_sample.drop(‘index’, inplace=True, axis=1)
print(‘Number of invoices to deep-dive:’, len(Review_sample), ‘which is’, round(len(Review_sample)/len(df1)*100,1),’% of total transactions’)
Review_sample.head()
显示 43 个“异常”交易中前五张发票的输出
上面展示了金融和审计环境中机器学习用例的一个非常简单的例子。在现实世界的问题中,我们肯定需要考虑许多因素和多种模型的使用,但是为了文章的长度,我只把它限制在 KNN。
在以后的文章中,我将深入研究数据科学在金融和会计领域的应用和用例。在自学之旅中,请随时评论或联系,分享关于这方面的想法或想法。
有关 PyOD 的更多资源,请参考此处 的 文档链接。链接里有一些非常好的文章,给了我很多启发和帮助。
数据开发中的审计与测试
“你如何测试数据?”
“你如何测试数据?”
每当有人想讨论数据堆栈的现代化时,这个问题总是排在列表的首位。最常见的情况是,软件工程师负责解开 SQL 脚本和存储过程的网络,当他们发现“dev”和“prod”只是数据开发人员的 SQL 编辑器中不同的连接设置时,他们感到很苦恼。数据开发的发展非常缓慢,可以说缺乏自动化测试/测试驱动的开发是这种懒惰的一个重要原因。TDD 和 CI/CD 已经成为快速可靠的软件开发领域的爆炸性催化剂,一旦被采用,它们将对数据开发产生同样的影响。问题是 如何 进行数据转换/模型测试并不十分直观。数据给软件设计增加了一层活动部件,可以感觉几乎不可能测试;但是和任何类型的开发一样,如果事情感觉太复杂,你可能需要考虑的更小。那么如何测试数据呢?容易;你不知道。你 测试 软件,你 审核 数据。
非结构化开发和 TDD 在技术上都是编程的方式,就像它们在技术上都是电话一样。图片来自美国国会图书馆印刷品和照片部吉尔伯特·h·格罗夫纳收藏。
数据不是软件,但数据软件是软件
《剑桥词典》将软件定义为控制计算机工作的指令。在 ELT 入库流程的情况下,软件是 SQL(或 python,或 R 等。)来决定如何更改或处理数据。数据是这个软件处理的东西。这种区别看起来很明显,但明确地说出来仍然很重要,因为它是如此多混乱的根源。当我们编写软件测试时,关键是我们只测试软件。
事情在哪里变糟?
想象你拥有一家冰淇淋工厂(我们都可以做梦)。你的价值链大概是这样的:
假设你决定测试你的产品,所以你去商店买了一加仑的石头路。令你惊恐的是,你发现冰淇淋酸得要命!从这个测试中,我们知道有几个不同的地方可能会出错:
- 这个牛奶场可能一开始就生产了劣质牛奶
- 罐车可能污染了牛奶(不良 EL 工艺)
- 工厂可能会让牛奶变质(转化软件错误)
如果一个测试告诉你出了问题,但是不能帮助你确定它发生在价值链的什么地方,那么这个测试就是没有价值的。单一责任原则告诉我们任何一点软件都应该只做一件事,并且把那件事做好。我们的测试也不例外!
如果不只是去商店测试,而是设立测试点,会怎么样?
- 在对牛奶做任何处理之前,在牛奶场检查牛奶
- 从罐车上接受牛奶之前,先检查一下
- 就在装运前,检查工厂生产线末端的冰淇淋
- 检查店面的冰淇淋
现在如果你在奶牛场发现一批酸奶,就没必要再往前走了。如果你在工厂生产线的末端收到一盒变质的冰淇淋,你知道它在加工过程中变酸了。
审计 你的数据是在对牛奶做任何事情之前检查它。审计所做的唯一一件事( SRP )就是确保我们的源数据按照我们的预期到达。
测试 您的转换/模型逻辑是在冰淇淋被处理后检查它。测试所做的唯一一件事( SRP )就是确保给定一个预期的数据输入,你的代码会像预期的那样运行。
事情变得混乱
审核和测试之间的界限最初可能很难看出,原因如下:
- 代码看起来一样,一定是重复工作。开发人员对我们代码库中相同的文本段落有一种精心策划的恐惧。干编程告诉我们,任何两个看起来几乎相同的东西都应该被参数化/注入/粉碎成某种形式的单一的、可调用的执行。当我们的测试和审计提出类似的问题时,很容易尝试多任务处理。不要这样做!审计和测试可能会问同样的问题,但它们是在非常不同的环境中进行的。例如,在
user_id
中发现一个NULL
值的审计告诉您有一个源数据问题或变更。转换测试中相同的NULL
值告诉您您的 SQL 是不正确的。审计NULL
只能意味着源数据有问题,因为您的转换还没有触及它。一个测试NULL
只能意味着你的 SQL 代码有 bug,因为源数据通过了审计。** - 测试是工具,不是数据。测试的唯一目的是促进发展。给定一个不可变的输入,我们应该期待一个不可变的输出(否则我们会有更大的问题)。因此,测试是确定我们在输入和输出之间精心制作的逻辑何时“完成”的一种方式为了让测试有用,它们需要足够快,能够在我们开发的过程中一遍又一遍地运行,并且足够全面,以至于我们“目测”来验证我们工作的任何东西都有一个等价的自动化测试。有效测试的一个核心要求是,我们可以相信所提供的源数据与我们得到的承诺完全一致。
- 审计是实质性的(和大量的元数据)。为了让我们的测试信任源数据,我们的审计不能信任源数据。审计对源数据有期望(即
user_id
永远不会是NULL
),并检查以确保这些期望得到满足(SELECT * FROM products WHERE user_id IS NULL
)。当源数据没有通过这项检查时,审计人员并没有生气,他们只是感到失望——他们通过停止 ELT 过程来表达这种失望。
实践中的理论
理解审计-测试模型最简单的方法是浏览一个例子。
这里我们有来自一个电子商务网站的源数据,如下所示:
我们相信:
-所有记录必须*有一个user_id
值
- ip_region 只能是
east
、west
、north
或south
*
因此,我们编写了在每次从源系统批量加载后运行的审计:
*## audit_users_user_id_is_not_null
SELECT * FROM "DATA_LAKE"."USERS" WHERE user_id IS NULL;## audit_users_region_in_set
SELECT * FROM "DATA_LAKE"."USERS" WHERE ip_region NOT IN ('west','east','south')*
如何运行审计可以有多种方式(从实现的角度来看)。重要的是:
-审计在任何转换之前首先运行。
-当所有审核通过时,ELT 正常进行。
-当审核失败时,会详细记录失败情况,ELT 会暂停并发出警报。
注意:Kimball围绕审计级别和记录模式做了大量的工作,这些不在本文的范围之内。**
从事聚合转换的开发人员也可以编写一个测试,在user_id
中寻找NULL
值:
**## test_user_id_never_null
SELECT * FROM "DATA_WAREHOUSE"."DIM_USER" WHERE user_id IS NULL;**
但是关键的区别在于:开发人员的测试只是为了告诉他们代码是否正确。审计层承诺所有记录都有user_id
值,所以开发过程中的任何NULL
值都意味着代码有 bug。开发人员可以根据承诺的输入安全地编写测试来检查预期的输出,当所有测试都通过时,代码就可以发布了。
如果没有user_id
的记录进来,ELT 停止。所有记录都有一个user_id
的信念不再被认为是正确的。通过审计记录调查缺失行的user_id
,发现所有有问题的行都正好来自 2020–03–02t 11:10:53,是由一个应用程序错误引起的,该错误已被修补。还要注意的是,在那个时间戳没有创建有效的行。新的承诺是所有行都将有一个user_id
,除了在 2020–03–02t 11:10:53 创建的记录。审计代码被调整以反映我们现在认为是真实的,应用程序代码被调整以处理数据的新现实。
审计记录可以(并且经常)被注释,以便为所有这些复杂性创建上下文。其结果是丰富的数据演变历史记录和高性能的开发工作流程,优化您最有价值的资产—数据开发人员带宽。
使用 Amazon Rekognition 定制标签增强肺炎胸部 x 光诊断
亚马逊 Rekognition 自定义标签胸部 x 光预测模型测试结果
在尼日利亚读高中的时候,我想成为一名医生——我们都知道结果如何。公平地说,我进入了医学院预科,但在第二年意识到我不是被设计来切割人体的。在那之后,我换了学校学习计算机科学,我们都知道结果如何。然而,我并没有失去对改善医学科学的执着。2013 年,我的学士论文重点是使用基于案例的推理来诊断伤寒。如果我从头再来,我将利用自然语言理解方面的进步来利用临床记录,实时预测伤寒病例。保持警惕。
在过去的几周里,我一直在为亚马逊识别定制标签 ⁵、来自 AWS 的令人惊叹的人工智能服务寻找新的用例——这是继切片面包之后最伟大的事情。在仔细研究了 Kaggle 之后,我偶然发现了胸部 x 光图像(肺炎)数据集,这是我的灵光一现。如果医疗从业者可以在没有 Google⁴的计算能力和技术专长的情况下利用人工智能诊断肺炎,会怎么样?
假设:如果医疗从业者可以在没有谷歌的计算能力和技术专长的情况下利用人工智能诊断肺炎,会怎么样?
这项工作
准备数据集
为了使用 Amazon Rekognition 自定义 Labels⁵训练模型,我需要将数据集保存在本地并通过 Amazon Rekognition 自定义标签控制台手动上传,或者已经存储在 Amazon S3 存储桶中。考虑到数据集的大小和要完成的任务,我决定利用云的力量——AWS。我启动了我的亚马逊 SageMaker 笔记本,安装了 Kaggle python 库。
下一步是将图像上传到 S3 的一个地点。然而,我意识到一个小故障。尽管 Kaggle 数据集页面的信息显示了 3 类——正常、细菌性肺炎和病毒性肺炎,但文件夹仅分为 2 类——正常和肺炎。通过对图像的简单浏览,我意识到它们可以根据文件名进一步分成 3 类,这要感谢数据集管理员。
随着 3 类到位,数据被上传到我的 S3 桶,并准备进行训练。这是我做过的任何计算机视觉任务中最简单的数据争论,少了 11 行代码。
完成上述步骤后,我必须使数据集对 Amazon Rekognition 自定义标签可用。我简单地从在亚马逊自定义 Labels⁵中创建一个新的数据集开始,在 web 控制台上点击几下,指向我在 S3 中的数据集位置。Amazon Rekognition 自定义标签为您提供了直接从控制台标注数据集的机会。如果你有一些图片,我会推荐这个。在我的场景中,我有超过 3k 张图片,并通过文件夹结构将它们分成不同的类别,我必须选中“,根据图片存储的文件夹自动为图片添加标签。”选项,这样 Amazon Rekognition 可以自动推断标签。
我得到了什么:
随着数据集导入 Amazon Rekognition,是时候训练我的医疗诊断助手了。
训练模型
要在 Amazon Rekognition 自定义标签中训练模型,首先要创建一个项目。
一旦创建了项目,Amazon Rekognition 自定义标签就可以训练我的模型了。不到 5 次点击,我就开始了我的模特训练。为此,我:
- 选择了项目,
- 选择我的训练数据集,
- 指示 Amazon Rekognition 应该拆分训练数据集,
- 点击了“火车”橙色按钮,然后
- 等待(用机器学习模型训练时最需要的属性)。
结果呢
正如我提到的,我开始证明我的假设是错误的,医疗从业者不可能在没有谷歌的情况下使用人工智能对胸部 X-rays⁸进行分类。结果证明我错了:确实有可能,感谢亚马逊 Rekognition 定制 Labels⁵.让我们从评估我花了多少钱开始。
费用
- 数据集在网上很容易找到,这让我几乎不用花钱就能下载。
- 我的亚马逊 SageMaker 笔记本花费了我大约 2 美元,我也用它来完成其他任务
- 亚马逊 S3 成本低于 0.90 美元
- 亚马逊 Rekognition 定制标签的模型培训持续 1.308 小时,每小时 1 美元;大约 2 美元。
总培训费用约为 5 美元(4.90 美元)。这不需要谷歌的财力。
为了用训练好的模型进行预测,亚马逊 Rekognition 定制标签的费用是 4 美元/小时。因此,如果我将我的生产用例设计为在一个 28 天的月中每天 4 小时进行批量预测,我将花费大约 450.00 美元/月(包括可扩展性和基础设施管理)。从而帮助全球成千上万的医疗从业者提高肺炎诊断水平,挽救数百万人的生命。看到更好的主意了吗?
模型度量
我不会去详细定义每个指标,我已经在以前的 post⁷和亚马逊 Rekognition 自定义 Labels⁵文件中广泛地这样做了。技术上,模型性能精度为 0.946 ~=94.6%。
总之,在胸部 x 射线数据集上的 Amazon Rekognition 自定义标签上训练的肺炎诊断模型能够正确预测患者是否患有细菌性肺炎、病毒性肺炎或零肺炎病例。
此外
想想这对全世界卫生保健的重要性和规模,即使是在最偏远的地方。想想可以重用这种方法的医疗用例。想想我们可以通过用人工智能增强医疗从业者的 X 射线诊断来拯救生命。
迫不及待地想知道您将使用亚马逊 Rekognition 自定义 Labels⁵.构建什么你可以通过电子邮件联系我,在推特关注我,或者在 LinkedIn 联系我。
参考
[1]克曼尼,丹尼尔;张、康;Goldbaum,Michael(2018),“用于分类的标记光学相干断层扫描(OCT)和胸部 X 射线图像”,Mendeley Data,v2http://dx.doi.org/10.17632/rscbjbr9sj.2
[2]更大的善的意义,维基百科,https://en.wiktionary.org/wiki/greater_good
[3]基于案例的推理,维基百科,https://en.wikipedia.org/wiki/Case-based_reasoning
[4]利用已裁定的图像标签开发胸部 x 光的深度学习模型,https://ai . Google blog . com/2019/12/Developing-Deep-Learning-Models-for . html
[5]亚马逊 Rekognition 定制标签,https://aws.amazon.com/rekognition/custom-labels-features/
[6]胸部 x 光影像(肺炎),https://www . ka ggle . com/paultimothymooney/胸部 x 光-肺炎
[7]带亚马逊 Rekognition 定制标签的 AI Powered Video Assistant 裁判,https://medium . com/@ elesin . olalekan/AI-Powered-Video-Assistant-referend-with-Amazon-Rekognition-Custom-Labels-5e 4902 b 47 ce 5
[8] Google details AI 以人类级别的准确度对胸部 X 射线进行分类,https://venturebeat . com/2019/12/03/Google-details-AI-that-classified-胸部 X 射线以人类级别的准确度进行分类/
设计师需要增强智能,而不是黑盒人工智能
我们正处于深度学习的复兴时期,但通用人工智能仍然很遥远。设计师需要工具来利用人工智能最擅长的东西:放大人类创造力的极限
急需颠覆的行业
建筑行业面临着生存危机。这是数字化程度最低的行业之一和全球领先的二氧化碳排放源。随着全球气温上升和大规模人口向城市中心迁移,我们迫切需要一种能够实现更可持续的工作方式的数字化变革。
作为建筑师,我们可以从其他领域学习,这些领域在开发协同人机系统方面取得了快速进展,这些系统利用了人类和人工智能生成的推理的积极方面。
在过去的一年里,开发了许多人工智能工具,为设计的环境影响和性能提供了新的见解。尽管潜力巨大,但广泛采用仍存在几个障碍:
- 需要大量专业知识来利用他们的能力
- 人工智能和其他计算方法需要严格定义的设计目标
- 对于客户——为项目融资的客户——来说,这些工具的输出仍然不透明,不可理解。
在Digital Blue Foam(DBF),我们开发新的解决方案,加速世界向更好、更可持续的城市转型。我们是设计师和技术专家,具有强烈的责任感,推动建筑、工程和施工(AEC)行业迫切需要的革命向碳负项目发展。
在新的设计时代来临之际,几个基本问题依然存在:
- 我们如何开发工具,给予设计师更大的权力来促进可持续设计?
- 下一代用户交互是什么样子的?
- 我们如何在一个设计工具中连接人类和机器智能的长处?
人工智能毫无意义
2019 年是新机器学习(ML)应用多产的一年。ML,机器从结构化数据或深度学习的非结构化数据中推断输出的能力,已经获得了大量的炒作和歇斯底里。这导致了一个普遍的误解,即如果我们使用最新的算法和计算能力收集和处理足够的数据,智能就会出现。事实根本不是这样。
使用相关性而不是因果关系的策略,ML 识别模式的速度非常快,尤其是当输入数据结构良好时。这就是它在玩像 *Flappy Bird 这样的视频游戏时如此有效的原因。*在大多数电子游戏中,规则和目标是一致的;不像真实世界,模式总是保持不变。但是当情况发生变化时会发生什么呢?
因果智能是人类智慧的基础。虽然人类识别模式的能力相对较差,但我们擅长将过去的知识重新应用到新的情况中。所以当 *Flappy Bird 2 发布的时候,*我们知道它将会有和第一代几乎一样的规则和目标,我们很快适应了。另一方面,我们的人工智能什么都不懂;它只是遵循一种模式。当模式改变时,人工智能变得无用。
增强智能的接口
Digital Blue Foam 开发了一种工具,可以引导 AEC 行业绕过一个主要瓶颈。建筑师花费大量时间学习和使用低效的绘图工具,这实际上分散了他们的基本角色,即创造和试验设计选项,以满足场地和项目的过多需求,无论是社会、环境还是经济需求。我们的工具使用增强智能将建筑师从这种麻烦中解放出来,并通过增强久经考验的草图绘制方法来帮助他们生成设计。
我们 DBF 是增强智能的主要支持者,而不是黑盒人工智能。在这种范式中,人工智能成为增强人类智能的工具,而不是取代它。虽然复杂的人工智能系统能够在分析“大数据”中的模式后做出决策,但它们的好坏取决于人类给它们的数据。
增强智能是人类和机器智能的杂交
增强智能已经嵌入到许多知名产品中。这在文字处理应用程序中尤为明显:MS Word 的拼写检查器、海明威编辑器和 Grammarly(一个在线语法检查器)是增强智能的几个日常例子。Powerpoint 中的“设计想法”功能是另一个例子,它使用增强智能来帮助非设计师改善他们的布局。
在我们的软件中,用户使用笔接口,用计算机设计**。随之而来的是其他人所描述的具有人机协作的【人在回路】增强智能(郑,2017)。**
I 人性化设计方法
手动设计方法源于直觉、经验和逻辑。它能够为复杂的问题提出解决方案,比如在形状奇特的地块的不同部分建造不同类型的建筑。
二计算方法:
计算策略能够快速生成符合预定义逻辑的解决方案。这种方法的本质非常适合迭代任务,例如生成基于规则的解决方案以及执行计算和分析。
III 增强智能(1+1 > 2):
增强智能(AI)方法结合了前两种策略的优点。它理解设计者的意图,在这种情况下是通过线条或节点,并应用规则集来生成高度细微差别的解决方案
用不太专业的术语来说,这意味着当设计者绘制草图时,计算机将该图解释为一个输入,以限制新设计的产生。反过来,设计师观察计算机生成的东西。然后,他们可以在顶部绘制草图来编辑结果,提供新的输入。通过重复这个过程,新的解决方案出现了,无论是机器还是人类都无法想象。
通过在我们的技术中应用增强智能的原理,我们希望将人类一生的经验中获得的常识与机器智能最擅长的事情联系起来:在大型数据集中识别有用的模式。
结论
史蒂夫·乔布斯是增强智能的大力倡导者,这种方法是苹果产品成功的主要原因。在《滚石》杂志 1994 年的一篇文章中,富有远见的乔布斯评论道:“技术什么都不是。重要的是你对人们有信心,相信他们本质上是善良和聪明的,如果你给他们工具,他们会用这些工具做很棒的事情。
增强智能并不是一个新概念,但值得更多的关注,因为我们正在研究如何应用人工智能提供给我们的所有惊人能力。为了解决 AEC 行业的生存危机,我们必须扩展我们对增强智能的定义,并利用人工智能的真正潜力:结合设计师直觉的敏感性和机器智能的蛮力。
注意事项
- 郑等(2017)“混合增强智能:协作与认知”。信息技术前沿&电子工程
- 合著者 Tejas Chavan
- 作者提供的图片和视频
- 特别感谢格雷厄姆·福斯特的剪辑!
- 试试这里的数字蓝色泡沫
试试数字蓝色泡沫这里
使用基准标记的增强现实
ArUco 基准标记
根据维基百科,基准标记“是放置在成像系统的视野中的物体,其出现在产生的图像中,用作参考点或测量点。它可以是放置在成像对象中或上的东西,或者是光学仪器的十字线中的一个标记或一组标记。”[1]基准标记已经在许多不同的场合作为测量手段使用。例如,如果你拍一张某人站在尺子旁边的照片,看看他们有多高,尺子将作为一个基准标记。
2014 年发表了一篇研究论文,提出了一种专门为相机姿态估计设计的基准标记系统[2]。相机姿态估计是寻找真实环境中的点和它们的 2D 图像投影之间的对应关系的过程。使用基准标记使这一过程变得容易得多。他们提出的标记被称为阿鲁科标记。该论文的两位作者拉斐尔·穆尼奥斯和塞尔吉奥·加里多制作了一个模块来与他们合作,这个模块又作为 aruco 模块并入 OpenCV[3]。
用 OpenCV 和 Python 检测 ArUco 标记
在之前的一篇文章中,我提到了 Pyto [4],所以我想我应该写一个脚本,从我的 iPhone 上的一个实时摄像头中找到一个 ArUco 标记,然后在它周围画一个方框。我使用了以下 ArUco 标记图像:
阿鲁科标记(id=1)
我把这张图片打印在一张纸上,放在我的桌子上:
你会发现我把透明度降低到 50%来保存我的黑色墨盒!它仍然工作正常。
下面是我的脚本,它检测标记,然后在它周围画一个框,并附上 ID:
下面是在我的桌子上用 ArUco 标记运行的脚本:
增强现实
一旦我能够检测到标记,我想在它上面放置一个图像会很好,这样可以在你移动相机时保持正确的视角。为了实现这一点,我们需要知道标记的单应性。然后,我们可以将图像转换成相同的单应性,并将其正确地放置在标记的顶部。
你不需要理解单应、齐次坐标或矩阵的实际细节就能实现这一点。但是如果你感兴趣的话,可以看看最后的维基文章参考文献[5][6]。
为了获得单应性,我们调用 OpenCV 方法find 单应性。一旦我们有了单应性,我们就可以调用方法 warpPerspective ,它将对图像进行仿射变换,以将其置于正确的角度,并将其正确地放置在标记的顶部。
这是我的脚本:
这是它在 Pyto 运行时的样子:
参考和链接
[1]维基百科对“基准标记”的定义:https://en.wikipedia.org/wiki/Fiducial_marker
[2]塞尔吉奥·加里多-朱拉多,拉斐尔·穆尼奥斯-萨利纳斯,弗朗西斯科·j·马德里-奎瓦斯和曼努埃尔·j·马林-希门尼斯,遮挡情况下高度可靠的基准标记的自动生成和检测
[3]https://docs . opencv . org/4 . 1 . 0/D5/DAE/tutorial _ aruco _ detection . html
[4]皮托:【https://github.com/ColdGrub1384/Pyto】T4
[5] 单应维基百科定义
[6] 同质坐标维基百科定义
八月版:数据世界中的新闻业
月刊
一点一点地解开现代生活的复杂性。
认识到数据是一把双刃剑可能是一颗难以下咽的药丸。从揭示我们社区的行为到创造完全假设的现实,我们致力于数据科学的社区有幸将数据视为一种资源,其潜力仅受我们想象力的限制。
然而,这种乐观的观点忽略了一个事实,即数据也是一个日益极化和复杂的世界的同义词。对于门外汉来说,现代数据过剩成为注意力分散和困惑的无尽来源。在错误的人手中,数据可以被用作面纱,让我们看不到这个世界。因此,了解数据传达我们对世界的看法的各种方式以及随之而来的责任,正成为现代讲故事者工具箱的重要组成部分。
在这期月刊中,我们将重点介绍我们关于数据新闻的一些最新讨论,以及过去一年中发表的一些关于“走向数据科学”的最佳文章,这些文章结合了严谨和创新的数据驱动的故事讲述方式。
从简单的数据分析应用到最新的机器学习模型,从政治到文化,这些故事向我们展示了数据——在正确使用的情况下——总是可以为我们带来更细致入微、更深刻的世界观,一次一点。
《走向数据科学》的编辑刘燕森。
面向数据记者的 Python:从网络上获取数据
由阿兰·琼斯—11 分钟读完
使用 Python 和 Pandas 在网络上发现、读取和分析 CSV、Excel 电子表格中的数据
失传的理解数据科学的艺术
作者哈姆丹·阿兹哈尔 — 6 分钟阅读
用于理解的数据科学和用于预测的数据科学之间存在巨大差异。
解读市场——机器学习与金融新闻
詹姆斯·贝克 — 22 分钟阅读
大量的金融新闻文章被发表。但只有一小部分能真正推动市场。知道哪些可能会有帮助。机器学习能指明方向吗?
如何在调查报告中使用开源卫星数据
本·马克斯科技记者 — 13 分钟阅读
今天,我们将尝试解决您可能与同事分享的一些保留意见,并教授一些访问、理解和处理开源卫星数据的基础知识。
来自金融科技初创公司数据新闻实习生的 3 堂课
由詹姆斯·勒 — 7 分钟读完
找出我在一家金融科技初创公司实习时学到的经验,这家公司正在利用机器学习来彻底改变信贷承销行业。
僧康的年轻选民并没有过剩
哈尼夫·萨马德 — 8 分钟阅读
获胜的工人党团队拥有特殊人口优势的证据很少——这对他们来说是个好兆头。
利用数据科学研究美国的经济不平等
由安德鲁·洪 — 12 分钟读完
我们如何利用公共数据来分析和理解美国黑人社区面临的挑战?
新视频
- ML 和其他半真半假的 DevOps 生命周期的过程和工具| Kenny Daniel
- 自己解释!利用语言模型进行常识推理
- 人工智能在临床决策支持中的应用:障碍&机遇| Niki Athanasiadou
- 使用 DVC 构建可维护机器学习流水线的终极指南 | 德博拉·梅斯基塔
新播客
- Solmaz Shahalizadeh — 高增长公司中的数据科学
- Will Grathwohl — 基于能量的模型和生成算法的未来
- Ian Scott — 德勤的数据科学
- 多智能体强化学习和人工智能的未来
我们也感谢最近加入我们的所有伟大的新作家梅根·马洛伊、迈克尔·高尔金、尼乌莎·RF、乔斯琳·卢特斯、斯泰西·斯维特利克纳娅、亚历克斯·德里杰、史蒂文·麦克唐纳、许明初、纪尧姆·休特、 黄、罗曼·斯图德、普拉诺蒂·帕瓦尔、罗布·齐泽克、乔纳森·费尔南德斯、莱恩·布朗、米米·布朗等等。 我们邀请你看看他们的简介,看看他们的工作。
澳大利亚野火增加了环境空气污染
我使用来自新南威尔士的监测数据来显示该州的环境空气污染是如何增加的。下载数据,自己看!
现在,你一定已经听说了澳大利亚东南部两个州新南威尔士和维多利亚发生的灾难性野火。到目前为止,森林大火已经烧毁了 800 多万公顷的土地,使 10 多万人流离失所,并导致至少 29 人和 10 亿只动物死亡。
令人心碎的照片在互联网上随处可见,其中大多数都有一个共同的特征:一片红色的天空。这种启示性的黄色过滤器是有机物燃烧产生的浓烟的产物。
野火是颗粒物(PM)的强大来源,PM 是由悬浮在空气中的有机(和无机)物质的混合物组成的颗粒。PM 10 和 PM 2.5 是两种常见的报告污染物;它们的数字表示颗粒的最大直径(微米)。这些微小颗粒只有人类头发的一小部分,非常危险。
事实上,空气污染(以 PM 的形式)可能是野火最大的无形后果,因为与空气污染相关的短期和长期成本不像火焰那样明显。
数据显示,在遭受火灾的地区,环境空气污染已经恶化;这些地区的个人定期暴露在被认为是’危险’或’T10 非常不健康’T13 的浓度中;一些监测站记录的浓度水平甚至超过了任何健康标准的极限。
虽然火灾结束后,严重的环境空气污染会很快恢复到正常水平,但它的一些无形成本可能会持续几十年。
滚动至底部,查看如何下载数据并自行进行分析的说明。
野火增加了环境空气污染
新南威尔士州(NSW)规划、发展和环境部报告他们每个监测站的多种污染物的日平均空气质量指数(AQI)。
资料来源:新南威尔士州规划、发展和环境部
AQI 将空气污染的剂量(即给定时间段内污染物的浓度)转换为基于国家空气质量标准的指数值。新南威尔士州政府使用的空气质量指数见下表。
澳大利亚和(通常使用的)美国环境保护局(EPA)标准的比较可以在这里找到。
我通过对分布在该州的 40 多个监测站的数据进行平均,得出了新南威尔士州 PM 2.5 的每日 AQI 估计值。结果(如下图所示)显示,自 9 月份以来,环境空气污染增加了一倍多——主要是由于 11 月份火灾加剧。事实上,环境空气污染的这种程度的峰值在以前的野火季节中并不存在(附录T6【A】,并且可以直接归因于丛林大火(附录 B )。
新南威尔士州 40+监测站 PM 2.5 日平均 AQI 读数,采用澳大利亚标准。资料来源:新南威尔士州规划、发展和环境部;作者的计算。
该地区的平均空气污染已经从平均非常好/良好上升到平均差/非常差**。美国的等效 AQI 是中度——即空气质量可以接受,但可能对一些人构成风险,特别是那些对空气污染异常敏感的人。**
这种增加也可以从野火通常排放的其他污染物(如 PM 10、CO 和臭氧)中观察到。我在附录 c中绘制了多种污染物的行为
然而,分析州一级的数据,掩盖了成千上万接近森林大火的人对非常危险的空气污染浓度的严重暴露;相反,独立地分析台站提供了对事件的更有启发性的见解。在下图中,我绘制了八个站点的数据,这些站点的每日 PM 2.5 浓度有显著差异。
8 个监测站(3 个应急站)PM 2.5 的日平均 AQI 读数,采用澳大利亚标准。资料来源:新南威尔士州规划、发展和环境部;作者的计算。
靠近火灾的两个城镇 Katoomba 和 Goulburn 的空气污染浓度经常远远超过可接受的水平(AQI 在 0-66 之间)。
到目前为止,北瓦加瓦加经历了环境空气污染最严重的一天。世界上污染最严重的城市是印度的古鲁格拉姆,其日均(PM 2.5) EPA AQI 为 145。1 月 5 日,北瓦加瓦加经历了日均 500+的 EPA AQI!
新南威尔士州监测站 PM 2.5 的十大日平均 AQI 读数。访问日期:2020 年 1 月 14 日。资料来源:新南威尔士州规划、发展和环境部;作者的计算。
临近的表格详细列出了空气污染最严重的 10 天(根据澳大利亚和美国环保局的空气质量指数)。Goulburn 不成比例地出现在十个最差的地方,接下来是 Katoomba 和 Orange。
12 月 31 日,古尔本的平均空气质量指数为 1335(环保局的空气质量指数为 385),当时古尔本邮报上传了这张照片并报告停电。要比较你所在城市的环境污染与如此高的浓度,请查看 NYT 互动看看世界上污染最严重的空气与你所在城市的相比如何。
如果 2240 的空气质量指数看起来很高——与监测器报告的最高空气质量指数相比,这是微不足道的。记录的前十个浓度对应的 AQI 值在 4500 到 7200 之间(其中八个大于 5000)。
下面的直方图详细描述了一月份前两周的小时数(y 轴),监测器记录的空气质量指数(x 轴)被 EPA 标准标记为非常 不健康(即 EPA 空气质量指数为 200+)。它报告澳大利亚的等效空气质量指数。虽然空气质量指数超过 4000 不会持续超过几个小时(如下所示),但它们会对人产生可怕的(如果不是致命的)后果。
直方图:1 月 1 日至 1 月 14 日,40 多个监测站记录了总计 331 个小时的空气质量指数超过 200。资料来源:新南威尔士州规划、发展和环境部;作者的计算。
跟踪 NSW.govaqicn.org或IQAir的实时空气污染读数;关注my fire watch现场直播更新。****
点击 阅读更多关于森林大火的信息。阅读更多关于 大火造成的空气污染的对话 。
如何提供帮助
NYT 发表了一篇关于 如何帮助澳洲火灾受害者 的文章。考虑为新南威尔士州农村消防服务局或维多利亚中央消防局做贡献。 救助儿童会 致力于管理儿童友好空间,让儿童能够在一个安全、受支持的环境中处理他们的经历。最后,考虑支持野生动物救援工作,例如来自世界野生动物基金会的。
附录 A
附录 A 显示了 2017 年 6 月至 2020 年 1 月新州 PM 2.5 的日平均 AQI 读数。下图显示,这一野火季节的环境空气污染明显高于以往季节。
新南威尔士州 40+监测站 PM 2.5 日平均 AQI 读数,采用澳大利亚标准。资料来源:新南威尔士州规划、发展和环境部;作者的计算。
下图显示了相同的点,但使用的是 PM 10。
新南威尔士州 30+监测站 PM 10 日平均 AQI 读数,采用澳大利亚标准。资料来源:新南威尔士州规划、发展和环境部;作者的计算。
附录 B
附录 B 提供了进一步的证据,证明环境空气污染的增加与野火有关。2019 年的森林火灾季节开始于 9 月(比往常早),由于更高的温度和热空气库,11 月期间加剧。到月底,消防队员已经扑灭了 120 多处森林大火。
我在 11 月初选择了一个任意的日期,然后进行了一个基本的回归不连续时间。结果可以在下图中找到。
新南威尔士州 40+监测站 PM 2.5 日平均 AQI 读数,采用澳大利亚标准。资料来源:新南威尔士州规划、发展和环境部;作者的计算。
虽然我没有考虑自回归或风等天气模式,但在数据中可以观察到约 40 个单位的具有统计显著性处理估计的明显不连续性。处理的右侧受到多种因素的影响,包括长期的自回归(因为更稠密的空气污染需要更长的时间来稀释)、风的模式、相互作用的影响以及野火的扩展和收缩。
下图描绘了处理前后样本的平均值(11 月火灾前后)。虽然它不能准确估计处理效果,但它表明野火是环境空气污染增加的根源。t 检验确定两个样本的平均值之间的统计显著差异。
附录 C
附录 C 介绍了对其他污染物的见解。野火排放一次污染物(PM、CO、NOx)和二次污染物。臭氧等二次污染物是 NOx 和 PM 与其他污染物(如碳氢化合物)相互作用的产物。下图显示一氧化碳和臭氧的浓度增加了(左),而一氧化氮和二氧化硫的浓度没有变化(右)。
新南威尔士州记录的 CO、NO、SO2 和臭氧的日平均 AQI 读数。资料来源:新南威尔士州规划、发展和环境部;作者的计算。
虽然预计二氧化硫浓度不会发生变化,但野火是氮氧化物的主要排放源。me bust(2013)【1】将澳洲野火氮氧化物排放的可变性归因于在火灾季节植物在地下重新分配氮的事实。我们的数据确实显示了 NO 的季节性变化,在火灾季节浓度较低。
[1] A.K. Mebust,从太空观察到的野火氮氧化物排放的可变性 (2013),加州大学伯克利分校。
自己分析数据
您可以下载数据并自己进行分析!前往新南威尔士州规划、发展和环境部并遵循以下步骤:
****第一步:选择数据类别和参数(污染物)。
选择“每日”或“每小时”现场平均值以及您感兴趣的污染物。这将提供浓度的平均值(g/m3 或 ppm)。****
有了浓度方面的数据,您就可以轻松地将空气质量转换为任何 AQI(无论是 EPA、澳大利亚还是您所在国家的环境机构使用的 AQI)。
要将浓度转换为澳大利亚 AQI,请遵循此处的说明。污染物目标浓度是给定污染物的 NEPM 空气标准。这个标准是由国家政府制定的。
****第二步:选择地区或站点。
由于数据下载时间不长,我建议您选择所有站点(站)。这可以通过选择粗体显示的区域来轻松完成。
不要忘记紧急站点!它们位于底部。
****第三步:下载数据。
点击 ’ 下载成文件 ’ 下载一个 xls (excel)文件。
选择所需的开始和结束日期。每小时数据的每次下载限制为 3652415 条记录。
下载数据后,您可以创建整个新南威尔士州地区的日平均值,如下所示:
***Daily_Average$mean = rowMeans(Daily_Average[2:nrow(Daily_Average], na.rm = T)***
****您可以使用新南威尔士州使用的 AQI (仅用于 PM 2.5)生成一个变量,如下所示:
***Daily_Average$AQI_mean = (100*Daily_Average$mean)/25***
您可以使用 ggplot 绘制数据:
***main = ggplot(data=Daily_Average, aes(x=Date, y=AQI_mean)) + geom_line() + geom_smooth(span=0.6, col="steelblue4")***
制作一个最小的背景,如下所示:
***main +
theme_minimal() + theme(panel.grid.minor = element_blank(), panel.grid.major = element_blank())***
插入澳大利亚 AQI 行作为参考,如下所示:
***main +
geom_hline(yintercept = (0), col="steelblue2", alpha=0.6, linetype = "dashed", size=.65) + # Very good
geom_hline(yintercept = (33), col="green4", alpha=0.6, linetype = "dashed", size=.65) + # Good
geom_hline(yintercept = (67), col="gold", alpha=0.6, linetype = "dashed", size=.65) + # Fair
geom_hline(yintercept = (100), col="orange", alpha=0.6, linetype = "dashed", size=.65) + # Poor
geom_hline(yintercept = (150), col="brown4", alpha=0.6, linetype = "dashed", size=.65) + # Very Poor
geom_hline(yintercept = (200), col="orangered2", alpha=0.6, linetype = "dashed", size=.65) # Hazardous***
按如下方式添加标签:
***main +
labs(title = "Ambient Air Pollution in New South Wales",
subtitle = "Daily average AQI readings of PM 2.5 (Australian standards)",
caption = "Source: NSW Department of Planning, Industry and Environment; author's calculations.
Note: The mean is based on 40+ stations. The colored dashed lines are hazard labels based on NSW recommendations.") +
xlab("Date") +
ylab("AQI") +
theme(text = element_text(size=12.5)) + # Adjust font size
theme(plot.subtitle = element_text(hjust = 0.5)) + # Adjust text
theme(plot.title = element_text(hjust = 0.5)) # Adjust text***
可以通过 rdd 包进行时间上的回归中断:
***library(rdd)
library(dplyr)Daily_Average = Daily_Average %>% mutate(n = row_number())plot(RDestimate(data = Daily_Average, cutpoint = 876, AQI_mean~n))title(main="Bushfires Cause a Sharp Discontinuity in Ambient PM 2.5", ylab="AQI", xlab="Days since the start of time series")***
Python 的自动文档
编写代码很无聊,为什么要浪费时间呢?
不管我们喜不喜欢,好的文档绝对是项目成功的关键**。那么,为什么好的文档如此难找呢?**
在现实中,它常常被忽视,被当作代码本身的劣质产品。制作好的、用户友好的文档实在是太耗时了。
这种忽视是错误的。我们构建的工具的采用在很大程度上取决于易用性。如果文档难以浏览、理解,或者仅仅是使用起来没有吸引力,用户不会喜欢它。
因此,考虑到这一点,我相信我们都应该为简单而全面的文档而努力。
我们将介绍如何为任何 Python 项目快速构建自动文档工具。有了它,只需几秒钟就可以为包含大量代码的复杂项目生成文档。
正则表达式是我们的朋友,我们将在整篇文章中大量使用它们。我写这篇文章的目的是真正关注代码的这一方面,我希望你能从中学到很多东西(我当然有)。
如果你使用NumPy/SciPy docstring 标准 ,你甚至可以使用我使用的确切代码,这些代码在 GitHub 这里有 !
在开始之前,现成的文档工具是现成的。用起来都没毛病,其实斯芬克斯,唯一一个我综合使用过的其实很不错。
然而,到目前为止,我还没有其他工具能特别快速地生成我喜欢的文档样式。
尽管如此,他们是好的,我建议你考虑你所有的选择。如果您对 Sphinx(或另一个)工具满意,请使用它。如果你想以你自己的风格构建一些东西(并学习正则表达式),使用这个指南。
Jorn Eriksen 在 Unsplash 上拍摄的照片
结构
autodocs 文档结构可以表示为一棵树,如下所示:
由此我们可以看出,我们必须能够从代码中提取几个关键结构,它们是:
- 文档字符串 : *(包含描述、参数、参数数据类型等)*这些是我们用来描述每个脚本、类和函数的块引用部分。
- 类:类定义本身、它们的描述(包含在 docstring 中)和方法。
- 函数:函数本身及其文档字符串,包含函数描述和参数。
- 参数:包含在函数 docstring 中。每个参数包含一个描述、数据类型和一个“可选”标志。
我们将采用这些组件中的每一个及其各自的子组件,并使用这些信息来开发另一个简化的、可理解的文档的树状结构。
文档字符串
Numpy/Scipy 标准文档字符串(包含在三重引号中的部分)。
如您所见,我们可以通过每个文档周围的三重引号来识别文档字符串。在 regex 中,我们写(?s)\"{3}.*?\"{3}
。
这里发生了一些事情。
\
用作转义字符。我们将它放在 Python"
或 regex{[()]}
中有其他含义的字符前面,以“逃离”它们的原生含义。表明我们实际上只是想寻找那个字符。- 我们有两组
\"{3}
,这正好匹配我们的两组三重引号。 .*
匹配除换行符之外的任何字符,?
使其成为一个“懒惰”量词——停止正则表达式匹配"""
的第一个实例到"""
的最后一个实例,取而代之,我们匹配第一个和第二个、第三个和第四个实例,等等。(?s)
是一个全局模式修饰符,s
告诉正则表达式我们希望.*
也匹配换行符。
班级
一个类的示例格式,后跟一个类外函数。
一个类的开头可以很容易地通过单词class
后跟一个空格、几个字母和一个冒号来识别。
为了防止我们匹配类开头之后的所有内容,我们将类的结尾标识为换行符直接跟在文本字符之后的第一个位置。
在 regex 中,我们写(?sm)class [\w\d_]+:.*(^\w)
。
[\w\d_]
匹配文本、数字和下划线字符,添加+
意味着它将匹配无限数量的这些字符。(?sm)
还是我们的全局模式修饰符,m
标志告诉正则表达式我们希望^
和$
分别表示一行的开始和结束。(^.)
是一行的开始^
,后面紧跟着一个字符.
。
功能
我们需要提取的例子。
功能有点不同。不像类,我们捕获类中包含的所有内容(这样我们也可以提取类方法),我们只需要函数名和 docstring。
幸运的是,这使得我们的第一个函数匹配正则表达式更加容易,我们写(?s)def [\w\d_]+\(.*?\):\s+\"{3}.*?\"{3}
。
描述
每个函数还包含我们必须提取的名称、描述和参数列表。我们分几部分来做,参数提取稍微复杂一点,我们将在下一部分讨论。
函数 名称我们用def [\w\d_]+\(
提取,用它我们去掉def
和(
,只留下函数名称。
name = re.search(r"def [\w\d_+\(", func).group()
name = name.replace("def ", "").replace("(", "").strip()
描述 desc
和参数表params
是用(?s)\"{3}.*?\"{3}
拉出 docstring 并在Parameters\n
上拆分提取的。然后,我们删除三重引号和过多的空白。
docstring = re.search(r"(?s)\"{3}.*\"{3}").group()
desc, params = docstring.split("Parameters\n")
desc = re.sub(r"\s+", " ", desc.replace('"""', "")).strip()
因素
我们的参数列表包含在params
中,看起来像这样:
为了匹配每个参数,我们编写(?s)\w+ : .*?(?=\w+ :)
。
在很大程度上,我们已经涵盖了这方面的所有内容,除了一个部分— (?=\w+ :)
。
在这种情况下,我们知道\w+ :
将匹配后跟空格和冒号的多个字母。然而,它被包裹在(?=)
中。这被称为正向前瞻断言。
通过添加这个,我们告诉 regex 对 assert (?=)
声明,我们匹配的内容后面紧跟着\w :
。
截图来自regex101.com
如果我们把它放到一个在线正则表达式测试器中,我们可以看到它几乎完美地工作,但是不幸的是,它遗漏了最后一个参数(因为它后面没有跟随\w :
)。
我们通过一次提取一个参数来解决这个问题。在这个循环中,如果我们发现没有找到参数,我们用修改后的参数 finding regex (?s)\w+ : .*
再次尝试,提取最后一个参数。
参数细节呢?
我们最后的、最深的提取层要求我们提取参数名、数据类型、“可选”标志和描述。
为此,我们简单地用换行符\n
分割我们的参数文本new_param
。现在,在索引0
处,我们有了包含参数名、数据类型和可能的可选标志的第一行。让我们修改上面的代码来包含这个提取。
这里唯一增加的逻辑就是:
对new_param
的第一行进行拆分,给我们name
和dtype
。接着检查dtype
中的单词'optional'
,给出optional
。
然后我们简单地将这些参数细节添加到新的params
字典中。给了我们这样的东西:
我们的准则
至此,我们已经完成了从代码中提取我们需要的所有内容的代码。我们已经创建了前面提到的树形结构:
脚本或类行中包含的任何内容都将有一个专门的文档页面。脚本页面将包含名称、描述以及指向其下任何类的链接。
从单个脚本 docs.py 生成的页面,其中包含一个名为 DocsBuilder 的类。
在构建文档时,我们将遍历项目中包含的每个脚本和类。迭代地为每一个构建文档。
有了这个,我们可以继续为我们的文档构建 HTML 代码。
构建文档
这些文档分为四个主要部分:
- 脚本/类信息。这出现在每一页的顶部。这是来自第一个脚本或类级 docstring 的信息。
- 面包屑导航栏。允许我们上下浏览文档级别。
- 类节。在这里,我们将有一个脚本类列表,单击一个类按钮将显示类描述和文档链接。
- 功能部分。这包含一个函数列表,详细说明了它们各自的参数。
在动态构建这些部分之前,我们确实需要将<head>
信息添加到我们的初始 HTML 页面,现在我们将保持它非常简单。
我们将为页面中的 CSS 和 JS 使用 Bootstrap 。在<head>
中,我们使用<link>
元素附加引导 CSS 样式表。JS 脚本是稍后添加的。
在 Python 中,我们可以将这段代码添加到三重引号块中,或者从文件中读取它。变量html
最初将只包含这个<head>
元素。
顶级信息
这是我们的脚本/类信息,出现在我们页面的顶部。
当我们独立地遍历每个脚本和类时,我们可以同样对待它们。两者之间的唯一区别是脚本页面将包含类部分,而类则不包含(除非您在类中有一个类)。
对于docs.py
,fullpath
将只包含一个条目['docs']
。但是对于较低的级别,例如DocsBuilder
,这将包含通向类['docs', 'DocsBuilder']
的层列表。因此,我们的主标题是列表fullpath[-1]
中的最后一个索引。
顶层描述包含在desc
中。
面包屑导航
接下来是我们的导航部分,我们用最高级别的页面readme
初始化它。
接下来,我们遍历fullpath
中的条目,创建一个到当前页面的完整“面包屑路径”。
因为生成的文件名都是骆驼大小写,并且包括任何前面的类/脚本。我们将相同的格式应用于变量path
。这使得**DocsBuilder** -> **docs.docsbuilder**
。
班级
类别都存储在一个名为classes
的字典中。该字典包含类名和描述键值对。
首先,我们检查当前级别是否包含类,如果没有,我们不添加类部分。
如果我们有类,我们添加类和类按钮部分的开头。然后我们遍历classes
,为每个项目添加一个按钮,只包含类name
。
接下来,我们添加类按钮的结尾和类描述(和链接)的开头。我们遍历每个项目,添加按钮内容。这允许我们在点击按钮时显示课程描述和链接。
最后,我们结束这节课。
功能
函数存储在名为funcs
的字典中,格式如上。
由于每个函数内部都有额外的参数层,所以这里还会发生更多的事情。
所有函数都包含在一个无序列表<ul>
中,其中每个列表项<li>
由一个函数组成。
包含在标签中的函数示例。
我们首先添加函数name
,然后添加包含在<kbd>
元素中的函数示例,通过用","
连接所有参数来构建。
下面是参数表。这里我们用标签<table>
和<tbody>
初始化表格的开头。一个循环逐行构建表,由参数名和描述组成。
在这之后是几个标签结束部分。由于 functions 部分是页面的最终动态构建部分,我们可以添加 Bootstrap JS 脚本和结束标记。
生成文档
一旦我们将所有这些代码提取和页面构建脚本放在一起,我们就可以只用几行代码来构建文档。
当然,在这里,你在整篇文章中看到的所有东西都被构建到了DocsBuilder
类中。
我们使用的所有提取正则表达式都包含在extract
方法中。在build
方法中的 HTML 构建代码。
我在包含许多脚本和类的更大的项目中运行过相同的脚本。尽管如此,所有文档都是在瞬间构建的。
你可以在 autodocs GitHub repo 中找到所有的代码。它绝不是一个完成的项目,所以请随时提出改进建议或指出不必要的代码!
如果你有任何其他问题或建议,请随时通过 Twitter 或在下面的评论中联系我们。
感谢阅读!
如果您喜欢这篇文章,您可能会对我最近写的另一篇关于处理来自 web 的文本数据的文章感兴趣。重点关注机器学习的数据准备:
使用 Python 抓取和处理 web 上的文本数据
towardsdatascience.com](/web-scraping-and-pre-processing-for-nlp-2e78810b40f1)
自动生成的知识图
利用网络抓取机器人、计算语言学、自然语言处理算法和图论的集合。
知识图是一种数据科学工具,处理相互关联的实体(人、组织、地点、事件等)。).实体是通过边连接的节点。知识图由这些实体对组成,可以遍历这些实体对来发现非结构化数据中有意义的联系。
图形数据库有一些固有的问题,其中之一是构建它们需要手工操作。在本文中,我将讨论我使用 web 抓取机器人、计算语言学、自然语言处理(NLP)算法和图论(提供 python 代码)进行自动生成的研究和实现。
网页抓取
构建知识图表的第一步是收集你的资源。对于某些目的来说,一个文档可能就足够了,但是如果你想更深入地在网上搜索更多的信息,有多种方法可以使用网络抓取来实现。维基百科是一个不错的起点,因为该网站的功能是作为一个用户生成的内容数据库,引用了大多数可靠的二手来源,这些二手来源审查来自一手来源的数据。
边注 :随时检查你的来源。信不信由你,网上的信息并不都是真的!对于基于启发式的解决方案,交叉引用其他网站或选择 SEO 指标作为信任信号的代理。
我将尽可能避免屏幕抓取,对维基百科 API 使用直接的 python 包装器。
下面的函数在维基百科中搜索给定的主题,并从目标页面及其内部链接中提取信息。
让我们测试一下这个函数的题目:“2007-08 年金融危机”
wiki_data = wiki_scrape('Financial crisis of 2007–08')
输出:
维基百科页面抓取:798
如果您想提取单页,请使用下面的函数:
计算语言学和自然语言处理算法
使用词性和依存解析可以从文本中自动构建知识图和。使用 NLP 库 SpaCy 从语法模式中提取实体对是快速的,并且可扩展到大量文本。
下面的函数将实体对定义为由根动词连接的具有主语-宾语依赖关系的实体/名词块。其他的经验法则可以用来产生不同类型的连接。这种联系可以称为主谓宾三元组**。**
调用主主题页面上的函数:
pairs = get_entity_pairs(wiki_data.loc[0,'text'])
输出:
提取的实体对:71
共指消解通过规范化文本、移除冗余以及将实体分配给代词,显著改进了实体对提取(参见下面我关于共指消解的文章)。
使用 NeuralCoref 将基于神经网络的共指消解集成到您的 NLP 管道中
towardsdatascience.com](/coreference-resolution-in-python-aca946541dec)
如果您的用例是特定领域的(医疗、法律、科学),那么训练一个定制实体识别器模型也是值得的。
图论
接下来,让我们使用 NetworkX 库来绘制网络。我将创建一个有向多图网络,其节点大小与度中心性成比例。
draw_kg(pairs)
如果绘制的图形变得难以理解,我们可以增加图形尺寸或过滤/查询。
filter_graph(pairs, **'**Congress**'**)
大规模知识图表
为了有效地为我们的主题使用整个语料库 ~800 维基百科页面,使用在 wiki_scrape 函数中创建的列为每个节点添加属性,然后您可以跟踪每个节点位于哪个页面和类别。
我推荐使用多处理或者并行处理来减少执行时间。
大规模的知识图表是人工智能研究的前沿。唉,现实世界的知识并没有整齐地组织成一个模式,而是无组织的、杂乱的和有机的。
SQLAlchemy 中的自动反映表和列
或者几行代码让我想在街上翻跟斗
大卫·克洛德的《向上冲刺》
呻吟,不是另一篇 SQLAlchemy 文章!
相信我,这个不一样…
在对 SQAlchemy docs 进行了大量的自我反省和挖掘之后,我有了一个重要的发现:您不需要使用基于类的属性来利用基于会话的查询的强大功能。
本文中的代码是根据 Apache 2.0 软件许可证授权的。下面是将要讨论的 Python 代码的一部分:
https://gist . github . com/steadynotion/129 c 7 b 58 ff 0 a 146d 45083527888 c 5749
SQLAlchemy 中自动反映表的扰流板代码
简单吧?
嗯,算是吧:请允许我解释一下。
我已经创作了几个使用 Pandas 和 SQLite 的 Python 脚本。对于那些还没有享受过与熊猫一起工作的乐趣的人来说,这是一个惊人的包,在数据科学和许多其他领域有大量的应用。我惊叹于为各种 Pandas 函数指定各种关键字参数以获得惊人结果的简单性。我的脚本使用 SQLite 数据库来存储传入的、“中游”和结果数据集。虽然 SQLite 非常适合原型开发,但我现在需要更多。
比如认证。
我可以移植我现有的代码来指向一个不同的数据库,但是我真正想要的是与方言无关的东西。进入 SQLAlchemy 及其强大的对象关系映射器(ORM)。它允许开发人员作为 Python 友好的类与他们的数据库进行交互。非常酷!
SQLAlchemy 的巨大优势之一是基于会话的查询,它采用 Python 面向对象的语法,而不是 SQL 语句。对于那些使用过两种或两种以上数据库技术的人来说,我有点不好意思解释为什么这是有益的。对于那些没有享受过这种乐趣的人来说,这就像是在一次环球电话会议上,与每个外向、健谈的人交谈时雇佣一名翻译。
SQLAlchemy 的 ORM 是你的翻译器。标题中有“物体”意味着它热衷于…物体。有几个扩展 SQLAlchemy 的包,如 Elixir 和SQLSoup;他们也使用面向对象的方法。如果您的代码使用( drum roll please…) 对象,这是没有问题的。
一个小问题是,我的代码中的一些咳咳 大部分使用 JavaScript 对象符号(JSON)在运行时配置参数。我有一个装满 JSON 趣闻的曲棍球球袜:这些是另一篇文章的主题。可以说,我的许多 Python 脚本使用从 JSON 获得的基于string
的参数进行配置。
在查看了 SQLAlchemy 文档并通过 Eclipse 调试器进行了一些检查之后,我拼凑了一个小而庞大的代码片段,它使我能够通过名称引用给定数据库中的每一个表和列,而不必将它们指定为对象和属性。
当我第一次看到一个没有错误的控制台时,我想在街上翻跟斗。
有些人可能会问‘那又怎样,我为什么要在乎?’也许一个更充分的例子是合适的。在深入下面的代码之前,如果您想知道如何使用 SQLAlchemy 配置数据库,我建议您查看以下有用的文章: SQLAlchemy — Python 教程作者 Vinay Kudari 和如何使用 Python SQLite3 使用 SQLAlchemy 作者 Mahmud Ahsan 。
一旦配置好 Python 环境和测试数据库,就可以将下面的代码片段加载到您选择的 IDE 中:
https://gist . github . com/steadynotion/8d 81 b5 bcdd 74 Fe 75 C3 a3 b 694516d 6528
一个更充分的例子
SQLAlchemy 中自动反映表的更完整的例子
配置了 SQLAlchemy engine
之后,您可以将它与测试数据库中的表和列的名称一起提供给get_data
函数。假设我们的测试数据库包含一个名为“ThisIsATable”的表和一个名为“ThisIsAColumn”的列。在“ThisIsAColumn”中,我们有几个基于文本的行,其中至少有一行包含“请尝试找到我”。
如果一切顺利,您应该有一个 Pandas DataFrame
包含来自测试数据库的表的子集。多亏了几行代码,我们现在可以自由地编写与数据库无关的查询了。通过这些查询,我们可以获得供熊猫咀嚼的数据,这要归功于简单的基于string
的参数。
从“易于维护”的角度来看,代码利用了公共函数和属性。调用私有属性通常是不明智的,因为这些属性在未来的版本中可能会改变;我倾向于尽可能回避私人属性。值得一提的是,上面代码中的Session
是在函数get_data
中调用的。这不是推荐的做法。有关创建和使用会话的更多信息,请参见这篇由 A Gordon 撰写的文章。SQLAlchemy 文档还包含关于创建和使用会话的信息,特别是标题为“我何时构造一个[Session](https://docs.sqlalchemy.org/en/13/orm/session_api.html#sqlalchemy.orm.session.Session)
、何时提交它以及何时关闭它”的部分。
有了上面的代码,您和您的概念验证 Python 脚本现在能够通过方便的字符串指定最少的信息来自动加载和反映数据库元数据。
弦乐!如此美妙的事情。
跟我一起说:琴弦是很奇妙的东西!
在我看来,这代表了通过 SQLAlchemy 的数据库无关性,以及强大的 Pandas 库和基于string
的关键字参数进行高级查询的开端!我认为另一个蛇的形象是合适的:它总结了 SQLAlchemy,熊猫和基于文本的互动之间的关系。它们共同组成了三驾马车,为自然语言处理和许多其他用例的无限扩展做好了准备。
蛇的图像由 Laura Barry 在 Upslash 上提供
祝你玩得开心,在外面注意安全!
E
使用 Python 自动更新您的 Github 概要文件
实践教程
通过自动化您的个人资料自述来展示您的技能
背景
最近,我在 Github 上看到越来越多的开发者拥有个人资料级别README.md
,我想创建同样的东西。我认为这是另一个展示我的机会。我还觉得这是一个将技术观众引向对我来说重要的东西的好地方,这些东西就是我过去几周一直在写的文章。此外,如果你作为一名读者,目前正在寻求提高你在同事、客户或潜在雇主中的权威,这可能是另一个给人留下深刻印象的机会。作为一名科技领域的招聘经理,我也会对那些通过 Github 个人资料展示自己技能的人留下深刻印象。
我想展示的东西之一就是我正在写的这样的文章。我每周都会写一些文章,这要求我每次发表文章时都要记得去更新这些文章。作为一个开发者,这将是不可接受的,因为我希望你们中的一些人会有这样的反应😉。
这让我开始寻找在我之前已经为这种自动化做了些什么的伟人。在搜索过程中,我找到了一些 Go 教程,以及一个非常好的 JavaScript 教程,我在页脚中做了链接。
以此为灵感,我想我会自己构建它,因为我还没有找到一个人以我喜欢的方式用 Python 做这件事。接受了这个挑战后,我现在需要搜索所需的组件来保持我的 Github 概要自述文件是最新的。
对于那些不愿意等着看结果的人。你可以自己看看下图中的结果。
作者图片
入门指南
正如你在上面看到的,我的 README 页面中我想要自动化的部分将会是 Medium 上最近文章的提要。为了轻松做到这一点,我需要一个 python 库来解析 RSS 提要。除此之外,我想在页脚添加我所在时区的当前时间戳,以表明上次更新的时间,因为这在 Github profile 登录页面中没有显示。所有这些都将在我选择的语言 Python 3.8 中发生,所以如果你继续学习,请确保使用 Python 3,因为有一些文件 I/O 是 Python 3 特有的。
图书馆
这里是我决定使用的库,基于前面提到的实现这个目标所需要的库。
feed parser—一个为 Atom 和 RSS 提要提供解析器的库。我本可以构建自己的解析器并使用 urlib 或 requests,但是我可以添加这种依赖。
pytz —允许我们为我们想要的时区提供一个人类可读的名称,这样我们就有了一个时区感知时间戳。这可能是通过标准库的 tzinfo 来实现的,但是这个库是我愿意用于这个目的的拐杖。
概念
虽然你应该可以克隆我的回购协议,并从中工作,或者只是从这篇文章中复制和粘贴。了解以下概念会很有用。如果这篇文章中的其他内容值得在这里发表,请在评论中告诉我,我可以为任何未来对 Github 自述文件的自动化部分感兴趣的读者添加它。
Github 操作 — Github 的 CI/CD 解决方案允许我们创建和更新我们的 Github 自述文件的工作流程。
真正简单的聚合(RSS) —一种标准化的提要格式,在这种情况下,允许用户或应用程序自动检查新内容。
开始建造
如果你还没有这样做,我的第一步也是一样的。我需要利用 Github Profile 特性创建一个自己命名的 Github 库。所以有了下面的回购,我准备开始建立我的README.md
文件。
我目前在道琼斯公司工作,利用尖端技术提供创新产品,我的…
github.com](https://github.com/dylanroy/dylanroy)
我们的自述文件
为了确定我想更新我的README.md
的哪些部分,我在 markdown 文件中搜索了短语“## Stories by Dylan Roy on Medium”,并添加了新的内容,在本文后面,当我浏览用于更新自述文件的代码时,您将会看到这些内容。
在未来的迭代中,我可能只需要更新一个主模板,而不是这个粗糙的方法,虽然这可以等到我决定向我的个人资料添加更多动态更新信息的时候。
Python 代码
因此,我们想要创建的自动化代码非常简单。首先,我们将使用 feedparser 读取一个 RSS 提要。
下一步是找到提要中列出的所有项目,并检查它们是否有与文章相关联的标签。这是我能够识别哪些是我发布的真实故事,哪些是评论的唯一方法。介质应该真正改变这一点,因为这是一个相当黑客。
过滤掉评论后,我们将故事列表加入到一个减价列表中,并将其附加到当前 readme 的末尾,使用 Python string 的 find 函数来识别标题所在的位置,从而删除旧的故事列表。
一旦看到这个样子,我就发现在 Github 中查看配置文件时缺少了一些东西。如果由于某种原因同步失败,我不知道信息是否过时,只需查看自述文件。
为了让我的个人资料的读者明白这一点,也为了让我在调试问题时明白这一点。我需要在最终产品中添加一个带有最新更新日期的页脚,如下所示。
作者图片
我做的第一件事是创建一个页脚模板,如下所示。在这个模板中,我只是使用了 python 字符串插值的模板语法。
<hr>
<div align="center">
README.md last auto generated {timestamp}
<br>
<a href="https://medium.com/@dylanroy" target="_blank">Learn to automate you own README here!</a>
</div>
更新和添加页脚的代码非常简单。第一步是以适合我的格式更新我想要的时间值。这就是pytz
库发挥作用的地方。我想用我的时区来反映它,所以我只是用那个时区配置了检索到的时间戳。
之后,就像使用标准 Python 格式函数替换那个时间一样简单。
**注意:**不是用标准的
open
函数打开文件,然后读取内容。我使用Path
对象一次性读取文件的内容。否则,我需要在之后关闭文件流,或者为文件操作设置一个范围。
之后,我们只需要将 Github 动作运行所需的功能组合在一起。步骤很简单。
- 阅读旧的 readme 与我们的手路径对象。
- 将更新后的自述文件输出到变量中
- 将此内容写入文件,并追加更新后的页脚。
下面是完整的代码,这样可以更容易地为您自己的目的进行复制导入等等。
通过操作实现自动化
现在我只需要为需要调度的 Github 动作构建工作流。
在之前的一篇文章中,我实际上描述了如何构建一个操作工作流来保持数据集最新,因此如果您已经阅读过,那么您将只是在这一点上逐步完成动作,因为这些工作流非常相似。因为我已经写完了,所以我不会对每一步做太深入的描述。
不到 10 行 Python 代码,保存了著名 CEO 的历史
towardsdatascience.com](/simple-versioned-datasets-with-github-actions-bd7adb37f04b)
首先,我们想安排我们的行动运行。在本例中,我只选择了上午 5:05。这些操作使用 cron 语法进行调度,因此这一步非常简单。
Github 动作工作流中需要定义的下一件事是我们想要在其上执行动作的操作系统。虽然将来我可能会使用更亮的图像,但我选择了最新的 ubuntu 来运行。
最初的步骤是我基本上复制并粘贴到我创建的每个动作中的步骤。它们按此顺序用于以下目的。获取 Github 存储库的工作副本,设置 Python 3.8,并安装将要执行的 Python 脚本的需求。
在工作流中的这一点上,运行我们的代码以更新数据集所需的一切都已经提供给了环境,因此在这一步中,我们现在将这样做。
现在,我们有了 readme 的更新版本,剩下的就是提交这些更改了。下面的命令就是这样做的,并推动这些更改。此时,我们已经执行了指示我们自动更新自述文件所需的所有操作。
和前面的步骤一样,这里是完整的 Github 操作流程。确保将这个文件放在.github/workflows
目录中,这样就一切就绪了。
将来我将对我的自述文件做一个额外的改进。将有条件地部署我的自述文件更新。现在我每天都有一个提交,但是只有当新的帖子出现时才更新是有意义的。我在下面的另一篇文章中采用了这种方法,我在下面链接了一个版本化数据集的条件部署。
关键要点
实际上,自动化操作非常容易。在这种情况下,你的 Github Profile 自述文件不仅可以传达你是一名开发人员,还可以作为作品集的一部分。
如果你在找工作或想给人留下深刻印象,这份文件可以帮助你开始成为一个更有吸引力的候选人。你能做什么的限制实际上只是你的想象,因为围绕公共 Github Repos 没有任何明确的限制。一旦你开始使用它,就值得在 Github 中搜索一些其他的配置文件自动化的例子,因为有一些非常有创意的例子。我印象最深的是 Tim Burgan 的,他的个人资料中有一场公共象棋比赛。
游戏正在进行中。任何人都可以下一步棋。这才是重点。👋轮到你了!移动一个白色…
github.com](https://github.com/timburgan)
感谢阅读。我在下面链接了我的其他教程,如果你感兴趣的话,请看看,并给我一个关注,以保持对未来文章的了解。
阅读迪伦的其他教程
停止花费时间手动调整未对准的箭头
towardsdatascience.com](/create-beautiful-architecture-diagrams-with-python-7792a1485f97) [## 具有 Github 操作的简单版本化数据集
不到 10 行 Python 代码,保存了著名 CEO 的历史
towardsdatascience.com](/simple-versioned-datasets-with-github-actions-bd7adb37f04b)
资源
- 本文来源于知识库
- 动作 Python 设置 Github
- 对我有用的 Github 动作介绍
- 另一篇关于 Python Readme Profile Automation 的文章 (给这家伙发了一些链接 karma,因为他是我见过的唯一一个用 Python 做这件事的人。)
- Thomas Guibert 关于 JavaScript 自述文件自动化的文章
- Koen Verburg 关于 Go 自述文件自动化的文章
- Victoria Drake 关于 Go 自述文件自动化的文章
将数据转换为模型的魔力
不用一行代码就能构建复杂的人工智能模型!
IBM Watson AutoAI
AutoAI 是一个图形工具,是 Watson Studio 的一部分,它允许在没有编码的情况下生成预测模型。AutoAI 由 IBM 生产,用于自动化企业 AI 模型开发,并减少建模生命周期的时间。奥拓获得爱康智能自动化奖。
AutoAI 具有强大的功能,包括:
- 快速选择和创建模型
- 人工智能生命周期管理,即理解你的数据,清理数据,预处理,培训,特征工程,微调,并为部署提供 API
- 易用性(只需几次点击即可培训和部署不同的模型)
自动开票流程—来自自动开票文档的图像
Watson Studio 中的视觉识别
Watson Studio 识别服务使用尖端的深度学习算法对图像进行分析和分类,并检测物体和其他内容。它允许用户建立一个协作环境,机器学习工程师可以远程合作。它将项目与 Github 连接起来,使推和拉变更变得更加容易。它支持不同的图像格式,如 JPEG 和 PNG。它还支持笔记本。
使用 Watson Studio 构建的视觉识别模型— 来自 Watson Studio 文档的图像
自然语言分类器
Watson Studio 自然语言分类器允许用户基于用户定义的类来构建文本分类器。它支持 CSV(。csv)数据文件,其中包含每个类的样本。它支持不同的语言,包括英语、阿拉伯语、法语、德语、意大利语、日语、韩语、葡萄牙语(巴西)和西班牙语。Watson Studio 提供多类别分类和多阶段分类(单个 API 请求中最多 30 个单独的输入)。它还支持笔记本中的 API。
这是一个使用 Watson Studio 构建的示例模型,包含三个类(嗨,问题,问题。
Watson Studio 中的自然语言分类器模型生成器— 图片来自 Watson Studio 文档
自动示例
在下文中,我列出了我创建的几个博客,以指导您使用 AutoAI 训练和部署不同模型的步骤:
图像分类
我们将使用包含来自世界各地的 120 种狗的图片的斯坦福狗数据集。我们的分类器的目标是根据狗的品种对狗的图像进行分类。
[## 如何使用 Watson AutoAI 构建图像分类器
建立一个没有编码的图像分类模型
towardsdatascience.com](/how-to-build-an-image-classifier-using-watson-autoai-ab1ffda25bab)
使用预先训练的图像分类器
在这篇博客中,我们学习了如何通过将预先训练好的模型公开为推理任务的 API 来重用它们。
[## 如何使用 Watson AutoAI 推断预训练的图像分类器
推理 AutoAI 预训练模型
towardsdatascience.com](/how-to-inference-a-pre-trained-image-classifier-using-watson-autoai-a63894a06458)
目标检测
在这篇博客中,我们学习如何建立一个模型来检测大脑扫描中的癌症和液体。
[## 如何使用 Watson AutoAI 建立对象检测模型
无需编码,构建脑瘤目标检测模型
towardsdatascience.co](/how-to-build-an-object-detection-model-using-watson-autoai-64677e045fd0)
文本分类
我们建立了一个模型,用于将不同的 StackOverflow 帖子分类到不同的标签中。
如何在不编码的情况下使用 Watson Studio AutoAI 训练文本分类器
towardsdatascience.com](/build-a-text-classification-model-using-watson-autoai-3650c461642)
如果你是图像分类/深度学习的新手,请查看我的帖子,了解深度学习的基础知识,并在下面的博客中端到端地了解整个训练过程:
理解神经网络的循序渐进教程
towardsdatascience.com](/under-the-hood-of-deep-learning-e8bb39aec5d2)
了解关于嵌入和文本模型的更多信息
探索 Word2vec 和 GloVe 的实现
towardsdatascience.com](/the-magic-behind-embedding-models-c3af62f71fb)
如果你是文本数据的初学者,想从头开始,看看下面的帖子
将文本转换成数字的魔力
towardsdatascience.com](/the-magic-behind-embedding-models-part-1-974d539f21fd)
结论
机器学习工程师经常花费相当多的时间来搜索合适的模型(参考模型)。使用 AutoAI 可以极大地改进和简化这一步骤。它有助于轻松建立深度学习模型,只需提供您的数据,无需一行代码。
如果您有任何问题,请告诉我!
承认
非常感谢Jorge Castaón的宝贵意见,使这个博客的质量得以提高!
资源
AutoAI:您的伙伴(值得信赖的合作伙伴),加快您的 AI 和 ML 模型的上市时间。
自动化 ML 生命周期的不同步骤
Auto AI 或 AUTO ML(甚至自动化数据科学)是学术界和行业中一个活跃的研究领域。云供应商推广某种形式的 AutoML 服务。同样,科技独角兽也为其平台用户提供各种 AutoML 服务。此外,还有许多不同的开源项目,提供了有趣的新方法。但是什么是 Auto AI,AutoML 是什么意思?
AutoAI 以一种复杂的方式利用特征训练来自动完成整个机器学习管道中的大多数复杂和耗时的任务,更具体地说,是特征工程和 ML 模型选择和构建部分。它不需要您成为数据科学专家。当然,如果你有这方面的专业知识会有所帮助,因为到那时,你将能够在下一个最佳水平上利用自动人工智能能力,这就是所谓的反馈回路中的人类。
预计自动化人工智能将有助于将 ML 功能提升到一个新的水平,帮助商业用户改善 ML 工作流程。虽然,自动人工智能的长期目标是自动化大部分(如果不是全部的话)将 ML 应用于商业用例的端到端过程。我们有必要了解它的能力、局限性以及自动化人工智能的未来目标。
这篇博客的重点是澄清概念,它包括什么,我们还缺少什么,或者换句话说,需要哪些潜在的改进来完成自动化数据科学之旅。本博客讨论了与 AutoML 相关的项目和研究工作的前景和历史,不仅着眼于超参数优化,还考虑了对端到端工作流和数据科学实践的影响。
🎓你会学到什么?
在这篇博客中,你将了解到以下几个方面:
- 自动人工智能、自动人工智能,以及我们所说的自动人工智能/数据科学是什么意思
- 目前使用的各种自动化技术
- AutoML 的近期功能和局限性,以及长期目标
- 如何利用这项技术来改善机器学习工作流的端到端生命周期
什么是汽车 AI?
AutoAI 代表人工智能的自动化。更具体地说,它意味着 ML / DL 管道的哪些部分(或步骤)可以而且应该自动化。它以机器学习步骤的选择和调整的自动化为中心,包括但不限于数据准备、特征工程和提取、模型选择、超参数调整和优化、结果解释和可视化。
ML 工作流程的哪些部分可以自动化?
虽然不是数据科学工作流中的一切,但我相信很多事情是可以自动化的。你可以看看下面一个典型的机器学习工作流程,我在 2020 年 4 月关于功能商店的文章中介绍过。我把它转贴下来供你参考。Feature Store 是让你的 AI 和数据科学工作流自动化的一个很好的方式(至少在很多部分)。关于功能商店的更多细节,你可以阅读 T2 的博客。
预先实现的模型类型和结构可以从输入数据集中呈现或学习以供选择。AutoAI 简化了 AI 项目的开发、价值证明计划,并帮助(企业)用户加快 ML 解决方案的开发,而无需丰富的编程知识。然而,就目前而言,它可以作为数据科学家的补充工具。这有助于他们快速找到他们可以尝试的算法,或者看看他们是否错过了一些算法,这可能是一个有价值的选择,以获得更好的结果。
通常,商业领袖认为,如果他们手中有自动人工智能工具,他们为什么要雇用数据科学家。我强烈建议不要陷入这种想法,因为它会给你错误的印象。
原因是,
- 数据科学就像任何其他业务职能一样,必须尽职尽责地执行,并需要创造性思维和人类技能来充分利用它。
- 汽车人工智能仍然没有出现,我们正在研究的仍然是狭义的人工智能,我们还没有接近实现(通用人工智能)AGI,一旦我们有了它,我们就可以考虑没有数据科学家的生活,至少在大部分情况下。
- 数据科学就像保姆,你必须定期照看你的管道、模型、数据和其他资产
- 理解业务和数据(CRISP-DM 模型的前两步)不能由算法来完成,你需要一个数据科学家来做这项工作,为 ML 管道准备好数据。
- 同样,在管道的其他步骤中,您仍然需要数据科学家和人工智能专家来确保模型正常工作,如果有什么需要调整的话。
- 最后但并非最不重要的一点是,一旦您获得了结果和业务见解,您仍然需要数据工作者来解释它们并将其传达给业务部门。
我在这里很早就提出了这些观点,这样您就不会因为没有数据科学家就可以使用 AutoAI 而感到困惑。如果您在迈向基于人工智能的转型之旅中同时拥有这两者,那将是最好的选择。
与此同时,我想强调并提醒你,有一个极好的价值,汽车人工智能可以提供给你,并缩短上市时间的毫升模型,这就是为什么我想出了这个博客。
企业寻求自动化 ML 管道和 ML 工作流中的不同步骤,以解决他们加快采用人工智能的趋势和需求的增长。在深入研究什么是自动化之前,我们先来看看标准的 ML 管道是什么样子的。如上图所示,它包括数据检索、数据准备、建模、超参数调整、模型部署和监控。
在初始数据摄取之后,我们需要删除重复项,修复缺失值,并解决数据中是否存在任何潜在错误。下一步是应用特征工程来提取和工程化特征,然后从清理后的数据集中获得训练数据。它包括数据编码、特征(重新)缩放、相关性分析等。
然后,我们将这些准备用于训练的特征馈送到所选模型,随后进行超参数调整。这种模型选择和参数调整需要数据科学家多次经历这个过程,并比较模型的性能。
由此产生的模型及其结果需要检验和解释。在这一步中,数据科学家必须验证特征的重要性,检测潜在的偏差,并解释预测,以便业务用户能够理解见解并理解它们对他们的相关性。
数据科学家对每个用例和每个用例中的每个用例都要经历这个过程。这些重复需要花费时间、精力、金钱和延迟才能投入生产。出于这个原因,我们建议 AutoAI 可以作为救星出现,并且可以自动化 ML 生命周期的许多步骤。
不同的供应商提供了 ML 管道自动化的解决方案。由 IBM 提供的解决方案被称为 AutoAI。AutoAI 专注于自动准备数据、选择和应用机器学习算法,以及构建最适合您的数据和业务场景的模型管道。
数据清理和特征工程
在 ML 管道中,数据摄取之后的第一步是关于数据清理和特征工程:特征+(选择、提取、构造)。“自动分析”可以帮助您检测数据中可能存在的重复项、缺失值以及其他不一致或错误。在解决了这些问题(数据清理)之后,我们将数据中的属性转换为特征,以便 ML 模型可以使用它们。特征的质量和数量极大地影响了模型及其结果。
**特征选择:**系统使用搜索策略选择特征子集,并对其进行评估。它一直这样做,直到找到适合该模型的这样一个特征集。
**特征构建:**从原始数据或结合现有特征创建新特征。
**特征提取:**侧重于使用 PCA、独立成分分析、isomap 等标准方法进行降维。
通常,这一步需要数据科学家花费大量时间,因为这是一个繁琐的过程。Auto AI 解决了这个问题,提高了效率并保证了质量特性。
提出正确的功能是机器学习流程中最耗时的步骤之一。
模型选择、超参数调整和模型测试
有两种选择模型的方法。传统上,数据科学家专注于手动模型选择:从传统的 ML 模型(决策树、SVM、逻辑回归等)中选择模型。)基于可用的数据和模型的适用性。AutoAI 使用的第二种方法是神经架构搜索(NAS) :它试图在 b 背景中使用强化学习来设计网络架构。
由于数据科学家是稀缺资源,这一部分通常对数据科学家来说非常具有挑战性,因为他们的时间和其他实际考虑有限,不允许他们同时尝试多个模型。AutoAI 在许多方面帮助他们。一旦模型得到训练,就可以在 AutoAI 的测试和进一步调整中重用它们。
为了有效地选择最佳模型,AutoAI 对小的数据子集运行估值器,逐渐增加。它有助于系统迭代地消除估值器并选择最佳估值器,同时节省时间和存储等稀缺资源。
一个至关重要的方面是超参数训练。它包含管理培训过程的数据。超参数调整运行整个训练作业,评估结果,并进行调整,以找到最佳的参数组合,从而找到解决方案。
Auto AI 提供了一个智能的超参数调整,可以调整每个算法的基本超参数。用于 HPO 的方法包括进化算法、强化学习、贝叶斯优化等。它搜索每个参数的不同范围的值,一旦算法完成执行,您可以选择相应的模型并可视化结果。
解释和可视化
您希望能够可视化数据集和模型,即能够看到关于数据的统计信息,如数据类型、分布、异常值等。如果没有自动化的人工智能,数据科学家可能需要几个小时甚至几天的工作。
可视化有助于用户更直观地了解和理解数据。它还可以帮助你解释模型,把它们变成白盒。例如,如果您可以直观地绘制决策树的结构,这将非常有帮助。它使用户能够评估模型并修改树结构,如剪枝和增强。同样,它有助于了解关于特征、特征的重要性以及特征如何影响模型预测的信息。
模型部署和监控
当模型准备好进行部署时,可以使用模型功能的一键部署,这让数据科学家感到非常轻松和舒适。此外,如果您可以选择并保存您希望与模型一起使用的服务,并创建模型的版本控制,这将会很有帮助。我的意思是,谁不想有“饭桶”在那里!
模型管线的自动评分使模型准备好在生产中运行它们。除此之外,它还为用户提供了运行多项实验的灵活性,例如 A/B 测试、健康检查、维护和应用安全补丁。
汽车人工智能的未来
在未来,汽车人工智能将获得更多的采用和动力。它要求进一步改进和增加 AutoAI 系统的功能。例如,添加数据收集功能将非常有帮助,因为这通常是需要解决的挑战性问题之一,尤其是高质量的数据。这个问题有两个解决方案;1)数据合成和 2)数据搜索。
**数据合成:**数据扩充将对图像数据有用;文本数据的翻译也有帮助,数据模拟可以服务于更特殊的任务。
**数据搜索:**由于互联网包含无限的数据,数据搜索可能会成为一个很好的解决方案。此外,特定于领域的功能将有助于针对特定场景自动化数据科学。
2020,Chan Naseeb。保留所有权利。