TowardsDataScience-博客中文翻译-2019-五-
TowardsDataScience 博客中文翻译 2019(五)
离群点检测的短暂旅程
查找异常值的几种方法的快速概述

Source: Pexels by Pedro Figueras
目录:
- 目标
- 单变量异常值检测
- 线性回归模型的异常值检测
目标
根据我们工作的内容和当前使用的模型,有很多方法可以捕捉异常数据。当我们需要精确的统计数据和模型时,注意异常数据是至关重要的,因为这些数据,如异常值,会极大地影响均值、标准差和方差。在本文中,我们将体验三种类型的技术:
- 对于带有 Z-socre 和 IQR 的单变量
- 对于带有简单杠杆统计、库克距离和 DFFITS 的线性回归模型,以及
- 对于具有稳健协方差、局部异常因子和隔离森林的双变量和高维
我们的主要目标是获得更深一层的理解,而不仅仅是通过阅读文章获得想法,并从实验中获得洞察力。我们还寻求实现它们的能力,这样我们就可以在需要时优化我们的算法,这样我们就可以在使用开源软件时处理意想不到的问题。
单变量
在处理单变量时,我们的方法很简单。因为我们有高中的数学知识,我们已经知道如何处理异常值。
IQR
第一种方法是 IOR(四分位间距)。设 X 为一元变量,一组值,s.t. X ={0,1,2,3,4,5, 6 ,7,8,9,10,11,20}。用 X ,我们简单算一下 Q1、Q2、Q3。在这种情况下,Q1=3,Q2(中位数)=6,Q3=9,IQR 是 Q3-Q1=6。异常值定义为
Q1-1.5IQR* 或 Q3+1.5IQR* ,
因此,在这种情况下,如果 a 值小于-6 或大于 18,则为异常值。在数据集 X 中,20 是离群值。
Z 分数
使用 Z 分数来检测这种异常值也很简单。与 IQR 的不同之处在于首先将原始数据转换成 Z 值。z 分数定义为
z=(x-μ)/ σ,
其中 x 是原始数据, μ 只是xσ是 x 的标准差。异常值也被定义为
Z 值小于 1.0 或大于 3.0 的 x
在代码以下的数据样本中,30 是一个异常值。
这是异常检测和单变量检测。Z 分数的概念值得注意,因为它用于计算 Mahalanobis 距离。此外,在比较稳健协方差作为异常检测的性能时,马氏距离是一个基本概念。
线性回归模型
接下来我们将看看线性回归模型的异常检测技术,具体来说,杠杆统计、库克距离和 DFFITS 。他们的目的是相同的,然而他们的方法是不同的。
杠杆统计
杠杆统计是对数据与他人的距离/影响力的诊断。这里我们要观察杠杆 点,它是对回归模型没有影响,但对数据集的均值、方差有影响的数据点,以及影响点,它是对两者都有影响的数据点。我们将测量每个点的观测影响,并检测对从观测中提取的信息量有很大影响的异常数据。

Influence point (blue point) v.s. Leverage point (red point)
设 X 为设计矩阵, x 为 X , x ⊆ X 的变量。在杠杆统计中,我们计算杠杆分数,并将其与临界值进行比较。超过临界值的分数是杠杆或影响点。截止值定义为
2(全球平均观测影响(OI)/n),OI =痕迹(H),*
其中 n 为观察数, H 为 X 的投影矩阵。投影矩阵 H = X(XᵀX)⁻ Xᵀ ,各次观测的杠杆分数是的对角线入口。**
为了实现这一点,我们首先制作简单的样本数据,并用红色添加一个影响点。如果一个杠杆分数超过截止值,那么我们也把它涂成红色。
**
****
Fig. left: Plot data points with influence point (red). Fig. right: Applying leverage statistics and detecting leverage and influence points(red)**
从右图中我们可以看到,高度偏离的数据点被检测为杠杆点和影响点。
d fits
当我们拟合了一些估计量的值时,如 OLS,我们可以用 DFFITS 来寻找异常点。当我们在杠杆统计中计算分数时,我们在 DFT ifts 中做同样的事情。DFFITS 用两个不同估计量的拟合值之差来度量分数。其得分公式定义为
DFFITSᵢ = (ŷᵢ-ŷᵢᵢ) / s*√hᵢᵢ,
其中,是由估计器基于包括第 I 个观测值的数据集预测的第 I 个拟合值,而【ŷᵢᵢ】是由基于估计器的不包括第 I 个观测值的数据集预测的拟合值。 s 是由基于估计量的数据集预测的独立值和拟合值的误差的标准偏差,不包括第 I 次观察。
上面的公式等于,
dffitsᵢ=tᵢ √[hᵢᵢ/(1-hᵢᵢ)】*
其中 tᵢ 是一个 R-student 。
在下面的代码中,我们用第 I 个观察值来计算 DFFITS。因此 tᵢ 被称为内化残。
库克的距离
就 DFFITS 而言,当我们已经知道拟合值时,Cook 距离也是一种有用的方法。该方法通过计算由估计器基于包括第 I 个观察值数据集预测的第 I 个拟合值和由估计器基于排除所有第 I 个数据的第 I 个观察值的数据集预测的拟合值之间的平方误差来测量得分。因此,该公式定义为

其中 p 为变量个数, s 为回归模型的均方误差,拟合值定义与 DFFITS 中相同。对于小样本量,临界值推荐为 2(p+1)/n ,对于大样本量, 3(p+1)/n 。**
上述公式等于
dᵢ=(tᵢ/ps) √[hᵢᵢ/(1-hᵢᵢ)】
这方面的术语同上。
在 Statsmodels 中提供了库克距离和 DFFITS。为了进行 n 次实验,看看库克距离和 DFT ifts 之间的结果有多大差异,现在我们来看下面的代码。我们使用来自 Kaggle( 来源)的跌倒检测数据集。为了方便起见,我们取时间(监测时间)和 HR(心率),检查 cooks_d 和 dffits 值。在这两个图中,蓝线是 OLS 的回归线。Cook 的距离检测 HR 值方面的远杠杆数据和高变量数据点,而 DFFITS 倾向于检测回归线以上的数据点,而不检测位于远右上方的数据点。
模糊时间序列的简短教程—第三部分
区间和概率预测和非平稳方法

嗨伙计们!距离我发表这篇教程的第一篇和第二篇已经很久了。与此同时,我有机会与许多在几个不同领域应用 FTS 方法的人交谈,他们帮助我通过修复一些错误和扩展其功能和可用性来改进 pyFTS 库。
从本教程开始,我们就一直在处理不确定性。我们找到了使用模糊集来建模和描述时间序列的时间行为的方法,但我们没有考虑我们预测的不确定性。预测的不确定性就像一场雾:如果你看得更近,你会看到模糊不清,这可能不会对你产生太大影响,但如果你想看得更远…
所以,现在是时候深入探讨更多的预测类型和新方法了,这一次我将重点关注非平稳时间序列、概念漂移等。
本教程的所有例子都可以在谷歌实验室、http://bit.ly/short_tutorial_colab3 网站上找到。请随时联系,提供反馈并提出问题。现在,我们走吧!
点位预测背后有什么?
大多数预测方法产生点预测,即单一标量预测。给定一个数值时间序列 Y 及其单个值 y(t) ∈ Y ,一个点的预测通常是一个条件期望 ŷ(t+1) = 𝔼[Y |y(t),…】。这个数字代表了在时间 t+1 时 Y 的最佳猜测值,根据我们对 Y 的了解,以及它过去的值 t,t-1, …不管我们的估计量有多好,它仍然是一个猜测值,而不是一个精确的确定值。换句话说,这个数字的背后隐藏着不确定性。
点预测的问题就在于此:它没有告知周围的不确定性。一个很好的起点是条件方差Var[y(t+1)| y(t)】,但通常不被告知,甚至不知道。
有一些方法可以解决点预测的这种局限性,它们是区间预测和概率预测。
区间预测
一个预测区间𝕀是一个元组𝕀=【u,l】,其中 u 是不确定性上界, l 是不确定性下界,断言估计很可能会落在这个区间内,ŷ(t+1)∈【u,l】。
置信区间是与置信水平α ∈ [0,1]相关联的值σ,其中 ŷ(t+1) ∈ [ ŷ(t+1)-σ,ŷ(t+1)+σ] 具有概率α。置信区间通常是参数化的,即它们假设预测值ŷ(t+1 周围的不确定性由高斯 pdf 描述。
有几种方法可以衡量区间预测的准确性,最简单的方法是覆盖率(表示落入区间内的真实值的百分比)校准、锐度等。已知 Winkler 分数在一个度量中体现了区间的几个方面
s(α,x,𝕀)=(u l)+2α(l−x)𝟙(x<l)+2α(x−u)𝟙(x>u)
其中𝕀 = [u,l], x 为真值,α为置信水平,𝟙(condition) = {条件为真为 1,否则为 0 }。
概率预测
一个概率预测是一个概率分布p:u→【0,1】,其中 U 是 Y 的论域,约束为 ∑P(x) = 1,∀x ∈ U 。这意味着我们将为 U 的每一个可能值 x 估计一个概率π,即 ŷ(t+1) = x ,或者换句话说:P( ŷ(t+1) = x) = π,0 ≤ π ≤1 这是表示预测不确定性的最完整的方式,并为我们提供了 ŷ(t+1) 以其概率程度可以假设的可能值的图景。
有了概率分布 p,我们还可以计算α置信区间(使用累积分布 F 的 α 和1-α分位数,并使用期望值 𝔼[P] = ∑xP(x),∀x ∈ U. 生成点预测
概率预测的主要准确性测量是连续等级概率得分(CRPS) 。简而言之,CRPS 测量真实值 x 前后的预测概率曲线的面积。该测量值表明概率分布与真实值的接近程度。CRPS 是 MAE 在概率预报情况下的推广,CRPS 值越低越好。
CRPS(F,x) = ∫ (F(y) -𝟙(y > x)) dy,y = -∞..+∞
其中 F(x) = P(X ≤ x) 为累积分布函数,X 为真值。
我应该使用哪些 FTS 方法?
F 首先,在 pyFTS 库上,每个模型都有布尔标志,指示它能够做出哪种类型的预测。所有模型都支持点预测,但并非所有模型都支持区间预测和概率预测。如果您试图在没有这种技能的模型上使用其中一种预测,将会引发一个异常。
if model.has_interval_forecasting:
forecasts = model.predict(data, type=’interval’)
要在 pyFTS 中生成区间预测,您可以使用与标量预测相同的方法——方法预测 FTS 类中的——并通知参数 type='interval' 。“预测”方法上的“区间预测”类型生成一个元组列表,每个元组有两个值,对应于一个预测区间𝕀 = [u,l]。一些模型(如 EnsembleFTS 和 PWFTS)允许指定区间的方法。
- ifts。IntervalFTS (IFTS):生成预测区间的最基本方法,它是高阶函数的扩展。生成的预测区间不具有某种概率意义,它们只是度量预测过程中所涉及的模糊集的上下界,即模糊不确定性。这里描述的是方法。
- 合奏。AllMethodEnsembleFTS:EnsembleFTS 是由几个基础模型组成的元模型。AllMethodEnsembleFTS 为 pyFTS 中实现的每个单变量 FTS 方法创建一个实例,并将它们设置为基础模型。预测是根据基本模型的预测计算出来的。在这里可以找到该方法的简要说明。基本上有两种方法来计算集合中的预测区间:极值和分位数(默认)。在极值方法中,选择基础模型预测之间的最大值和最小值。在分位数方法中,必须告知阿尔法参数,然后对基础模型的预测进行排序,并提取分位数区间。
from pyFTS.models.ensemble import ensemblepart = Grid.GridPartitioner(data=train, npart=11)model = ensemble.AllMethodEnsembleFTS(partitioner=part)forecasts = model.predict(test, type='interval', mode='extremum')forecasts2 = model.predict(test, type='interval', mode='quantile', alpha=.1)
- pwft。probabilistweightedfts(PWFTS):顾名思义,这是最复杂的方法,仍在审核中(即将发布)。基本上有两种方法可以在 PWFTS 上产生预测区间:启发式(默认)和分位数。在启发式方法中,区间界限被计算为模糊集界限的期望值及其经验概率,而分位数方法生成一个完整的概率分布,然后提取分位数(使用α参数)。
forecasts1 = model.predict(test, type='interval', method='heuristic')forecasts2 = model.predict(test, type='interval', method='quantile', alpha=.05)
- 多变量方法:这种多变量方法使用与 IFTS 相同的方法来产生预测区间。
- 这种加权多元方法使用与 IFTS 相同的方法来产生预测区间。
在模块 pyFTS.common.Util 中,我们可以找到函数 plot_interval ,它允许我们很容易地绘制间隔:

Intervals generated by the monovariate methods (source)

Intervals generated by the multivariate methods (source)
生成的间隔试图展示模型考虑的可能变化范围。您可以看到,有些模型生成的区间比其他模型更宽,有时(尤其是在区间更窄的加权模型上)原始值会超出区间。最好的区间有平衡的宽度,既不会太宽而显示出高度的不确定性,也不会太窄而不能覆盖真实值。
要在 pyFTS 中生成概率预测,您还可以使用 FTS 类中的方法预测,并通知参数type =‘分布’。predict 方法将返回一个概率分布对象列表。此外,像间隔一样,概率预测也有自己的布尔标志来指示哪些模型能够执行它:
if model.has_probabilistic_forecasting:
distributions = model.predict(test, type='distribution')
在中,与区间预测相比,概率预测有自己的类来表示概率分布——类pyfts . probability . probability distribution。有几种方法来表示这种概率分布,根据定义,这是一种离散的概率分布。我们现在对该类的一些方法特别感兴趣: 【密度】 (返回输入值的概率)、 【累积】 (返回输入值的累积概率)、 分位数 (返回输入值的分位数)和(绘制输入 matplotlib 轴上的概率分布)。
现在让我们看看 pyFTS 上的一些概率预测方法:
- pwfts。T21:这种方法完全是为概率预测而设计的,也是概率预测的最佳方法。其规则包含与模糊集相关联的经验概率,并且还呈现特定的去模糊化规则,该规则将概率分布上的输入(清晰)值转换为未来值;
- 合奏。EnsembleFTS :之前提到的 ensemble 使用核密度估计器(KDE) 在基础模型的点预测上创建概率预测。KDE 还需要指定核函数和宽度参数。
让我们看看概率预测是什么样子的:

The probabilistic forecasting of 4 days using the Util.plot_density function (source)

The probabilistic forecasting of 24 hours using ProbabilityDistribution.plot function (source)
在上面的图片中,概率预测从两个不同的角度展示。第一张图片是通过模块中的 plot_density 方法生成的。Util* ,其中每个概率分布绘制为蓝色阴影,其强度对应于概率。这种方法允许绘制原始时间序列和预测概率分布。第二张图使用概率分布的方法 plot 显示了与话语领域相关的每个概率分布。*
当然不是一切!我们必须考虑未来许多步骤的区间和概率预测,我们希望这能告诉我们不确定性如何随着预测范围的增加而演变。是啊!这很吸引人,但我还有很多东西要展示,所以我会把它作为你的一个练习,好吗?
让我们现在走在一条最难走的路上…
不稳定的土地
你可能还记得那句广为人知的老话:
“唯一确定的是,没有什么是确定的”。
是的。预测可能是不公平的,因为事情总是在变化,我们必须应对。平稳性通俗地说就是随机过程的统计性质(如它们的期望值和方差)不随时间变化,其最终均值是稳定的。这对预测模型来说太棒了:测试数据集的行为将和训练数据集完全一样!
另一方面,非平稳性意味着统计特性的变化。但并不是所有的非固定性都是平等的。其中一些趋势和季节性是可以预测的。处理季节性并不棘手,你可以使用高阶、季节性或多元方法(你可能还记得我们上一个教程)。要处理趋势也不太复杂,您可以使用差异转换来消除数据的趋势。

The original time series — NASDAQ — and the differentiated time series (source)
假设我们将上述时间序列一分为二,称这些子集为训练和测试数据。您可以看到测试子集(在实例号 2000 之后)具有以前在训练子集中没有出现的值。这是大多数 FTS 方法的一个缺点:当输入数据超出已知的话语范围时会发生什么?这个模型以前从未见过那个区域,也不知道如何前进,于是它悲惨地失败了。你也可以在上面的图像中看到,微分时间序列表现得更好,事实上,它是平稳的。
如何在 pyFTS 上使用差分变换?只需从 pyFTS.common 导入转换模块并实例化它。不要忘记将转换通知给分区方法,并将其添加到模型中(使用 append_transformation 方法)。
*from pyFTS.data import NASDAQ
from pyFTS.models import chen
from pyFTS.partitioners import Grid
from pyFTS.common import Transformationsdiff = Transformations.Differential(1)train = data[:2000]
test = data[2000:]part = Grid.GridPartitioner(data=train, npart=15, transformation=diff)model = chen.ConventionalFTS(partitioner=part)
model.append_transformation(diff)
model.fit(train)forecasts = model.predict(test)*
看看经典的陈模型在 NASDAQ 数据集上进行差分变换和不进行差分变换时的行为:

The degradation effect of the FTS when the test data falls out of the known Universe of Discourse (source)
虽然时间序列仍在已知的话语空间中波动,但两种模型都表现良好。但是,当时间序列跳出训练数据的论域时,没有微分变换的模型开始恶化,因为它不知道如何处理未知数据。
然后,这些转变不仅帮助我们了解趋势模式,还帮助我们了解话语世界的未知范围。
但是有些非平稳性是不可预测的,有时候处理起来很痛苦。
概念漂移的噩梦
C 有时,这些漂移循环发生(周期不规则),在其他情况下,漂移是暂时的。当概念漂移发生时,有一些问题需要回答:它是暂时的吗?变化是结束了(确立了)还是会一直变化?
我们还必须区分概念漂移和离群值。异常值不是变化,它们属于已知信号但属于罕见事件。
概念漂移是噩梦——不仅 fts 方法,其他计算智能和统计技术也害怕它们——但我们需要学习如何与它们共存。尽管这个问题很复杂,但还是有一些简单的(不幸的是有些昂贵的)技术来解决它们。
时变方法
A 我们之前看到的 ll FTS 方法都是时间不变的方法,这意味着它们假设时间序列的未来波动会按照之前已经发生的模式表现。换句话说:由模型的模糊时态规则描述的时间序列的行为在未来不会改变。
这对于许多时间序列(例如我们之前研究过的环境季节性时间序列)来说很好,但对于其他时间序列(例如股票交易资产价格)来说却非常失败。
在这种情况下,我们需要应用时变模型,
- 增量。时变模型 :时变模型是解决概念漂移和非平稳性的最简单(但有效)的方法。这个类实现了一个元模型,这意味着你可以选择任何 FTS 方法作为它的基础方法,然后在每个 batch_size 输入时,元模型用最后的 window_length 输入重新训练它的内部模型。这些是模型的主要参数:窗口长度和批量大小。作为元模型,您还可以指定使用哪个 FTS 方法( fts_method 参数)以及您希望在其中使用哪个分区器( partitioner_method 和 partitioner_params 参数)。
*from pyFTS.models.incremental import TimeVariantmodel = TimeVariant.Retrainer(
partitioner_method=Grid.GridPartitioner,
partitioner_params={'npart': 35},
fts_method=hofts.WeightedHighOrderFTS,
fts_params={},
order=2 ,
batch_size=50,
window_length=200)*
- 增量。IncrementalEnsembleFTS:工作方式类似于 TimeVariant,但采用的是一种整体式方法。在 TimeVariant 中,只有一个内部模型在 n 次输入后重新创建(这意味着 batch_size 是它拥有的唯一内存)。在 IncrementalEnsemble 上,我们还有 window_length 和 batch_size 参数,还有 num_models ,它表示要保存多少个内部模型。一旦新的模型被创建(利用输入的数据),旧的模型就会被从集合中删除。
*from pyFTS.models.incremental import IncrementalEnsemblemodel = IncrementalEnsemble.IncrementalEnsembleFTS(
partitioner_method=Grid.GridPartitioner,
partitioner_params={'npart': 35},
fts_method=hofts.WeightedHighOrderFTS,
fts_params={},
order=2 ,
batch_size=50,
window_length=200,
num_models=3)*
- 非平稳模糊集非平稳模糊集是可以随时间修改的模糊集,允许它们通过平移和/或缩放其参数来适应数据的变化。NSFTS 方法非常类似于时间不变的 FTS 方法,除了它们的模糊集不是静态的:对于 NSFTS 模型执行的每个预测,误差被计算和存储,并且模糊集被改变以修正该误差。对于这种方法,误差是测试数据与训练数据有多少不同的度量。这个方法正在被出版的路上。
***from pyFTS.models.nonstationary import partitioners as nspart
from pyFTS.models.nonstationary import nsftspart = nspart.simplenonstationary_gridpartitioner_builder(
data=train,
npart=35, transformation=None)model3 = nsfts.NonStationaryFTS(partitioner=part)***
pyFTS.data 模块包含大量非平稳、概念漂移的时间序列,如纳斯达克、TAIEX、S & P 500、比特币、以太坊等。您还可以使用类data . artificial . signal emulator来创建合成和复杂的模式。SignalEmulater 被设计为作为一个方法链 / fluent 接口工作,因此您可以通过链接方法来模拟复杂的信号,这些方法产生添加到上一个方法或替换它的特定信号。方法stationary _ signal创建具有恒定均值和方差的简单平稳信号,方法incremental _ Gaussian创建均值和/或方差每次递增的信号,方法periodic _ Gaussian在恒定周期内波动均值和/或方差,方法 blip 在随机位置添加异常值。每次调用其中一个方法时,其效果都会添加到之前的信号中,除非您通知 start 参数——指示该方法何时(哪一次迭代)开始工作——或将布尔参数 additive 设置为 False,从而停止之前的信号并开始这个新信号。要渲染整个信号,你只需要调用函数 运行 。
***from pyFTS.data import artificialsignal = artificial.SignalEmulator()\
.stationary_gaussian(mu=2.5,sigma=.1,length=100,it=10)\
.incremental_gaussian(mu=0.02,sigma=0.01,length=500,start=500)\
.run()***
现在让我们将所有这些放在一起,创建 3 个非平稳时间序列,带有概念漂移,并使用上述方法来预测它们:

Performance of the time variant methods for artificial time series with concept drifts (source)
当处理非平稳性和概念漂移时,ime Variant 方法必须平衡某种开发和探索。利用模型已经知道的东西——它的记忆、从数据中最后学习的模式——或者探索新的数据和学习新的模式。每种方法都有自己的机制:再训练器由 window_length 和 batch_size 控制,增量集成由 window _ length 和 num_models 控制,NSFTS 使用自己的误差大小来调整模糊集。毕竟,适应概念漂移所花费的时间是时变方法最重要的方面之一。我们在以前的教程中看到的原则同样适用于本教程:每个 FTS 方法都有自己的特性和参数,最佳方法将取决于上下文。
伙计们。今天到此为止,好吗?
在这些教程中,我们已经涵盖了时间序列预测领域的一个很好的部分,甚至是表面上的,以及它们的问题和使用 FTS 方法的解决方案。我们还没完成呢!我们将永远有问题要解决,新的改进方法和优化。
在接下来的教程中,我将介绍一些新的方法,比如超参数优化和如何用分布式计算处理大时间序列。伙计们,再见!
获得高质量氮化镓结果的捷径

Above: Generated Samples. Below: After Super-Resolution
在过去的几周里,我一直在摆弄 StyleGAN,结果真的很奇怪,很酷。在过去的几年里,甘取得了如此大的进步,真是令人吃惊。
去年花 43.2 万美元买下那幅可怕的斑点肖像的人可能已经操之过急了,因为 GANs 现在可以生成一些令人惊叹的真实而美丽的照片。
[## 此人不存在
此人不存在
这个人不是 Existthispersondoesnotexist.com](https://thispersondoesnotexist.com/)
StyleGAN 真正令人惊讶的是,它第一次给了我们一些接近迁移学习的东西。我们实际上可以使用预先训练好的模型,这些模型是组织花费数十万美元训练出来的,并且通过我们自己的数据集得到了不错的结果。
一个教程解释了如何训练和生成高质量的动画脸与 StyleGAN 神经网络,并…
www.gwern.net](https://www.gwern.net/Faces)
我说不错,因为不幸的是,它仍然需要相当多的时间和美元的培训,以产生任何接近 NVidia 团队已经得到的现实结果。
随着更多的突破,我确信训练/计算需求会下降,但现在像我这样的平民仍然停留在生成低分辨率的艺术或风景图像上。这本身就是一个巨大的进步,因为我现在至少可以生成低质量的照片,而不是几年前用 DCGAN 得到的斑点。

Generated Landscapes: Not too shabby (in low resolution)
我在寻找提高 GAN 结果质量的方法,并有了一个想法。
这个想法
多亏了杰瑞米·霍华德教授的惊人的 fastai 课程,我在一年前偶然发现了一个很酷的技术:【https://arxiv.org/abs/1603.08155
主要思想是使用感知损失将图像特征转换到另一个图像上,而不使用 GANs。用这个,我可以给黑白照片上色。
深度学习可以很有趣。你给它一些猫和狗的照片,它可以分辨出哪些照片是猫和…
hackernoon.com](https://hackernoon.com/colorizing-pakistan-5697f7754b2a)
快进到今天,当我从 StyleGAN 生成这些模糊的照片时,我想知道我是否真的可以使用这种技术来提高最终结果的质量。所以——训练一个模型,将低质量的照片转换成高质量的照片,并在我的 GAN 生成的结果上使用。
这个实验是这样设置的。
- 使用预训练的 StyleGAN 模型在某组图像上训练您自己的模型。你可以从 NVidia StyleGAN 代码和他们的一个预训练模型开始:【https://github.com/NVlabs/stylegan
补充说明:Gwern(上面的链接)对如何设置 StyleGAN 代码并将其用于迁移学习有很好的指导。
- 完成训练后,从最终模型中生成并保存一些随机样本。
- 基于相同的数据集创建超分辨率模型。为了做到这一点,我们需要一个原始数据的源数据集,和一个包含转换图像的目标数据集。对于这个练习来说,可以简单地将原始图像重新保存为较小的尺寸和较低的质量。然后,您可以创建一个模型,尝试将这些图像恢复到原始形式,即提高图像质量。你可以在这里找到这样做的脚本:https://github . com/fastai/course-v3/blob/master/nbs/dl1/lesson 7-super RES . ipynb
- 最后,一旦你训练了一个可以从低质量图像中充分恢复原始图像的模型,你就可以看到你的 GAN 样本是如何通过这种技术得到的。
这是我从 LandscapeGAN 得到的一些结果。

Right: GAN generated. Left: After Super-resolution

Can see way more details on the right image

如果我用更多的数据训练我的 StyleGAN 和超分辨率模型更长时间,我相信我可以获得更好的质量最终结果。
我认为这是一个从你 GAN 结果中获得额外质量的巧妙技巧。GANs 倾向于收敛到一定的图像质量,让它们达到更高的分辨率会导致你必须投入的计算量的回报递减。例如,我只花了几个小时就可以得到这些风景图片,但是从这里到高质量的照片级的图片就要花更长的时间。
通过使用超分辨率,我们可以让我们的 GAN 模型产生我们想要的图像/视频质量的 80–90%的图像,并对它们应用超分辨率,最终获得高质量的结果。如果我们一直训练我们的 GANs 变得越来越好,这将花费我们更长的时间(和更多的成本)。
创建一个超分辨率模型不需要太多时间,所以绝对值得一试。您甚至可以将其设置为一个无缝的多步骤过程,生成 GAN 样品,然后通过一个经过训练的超分辨率模型进行处理。
现代世界的金融
“别哭了,这是时代的标志……”一点不错,哈里·斯泰尔斯,一点不错。
金融——认识你的小兄弟,金融科技 金融科技,通常被称为 Fintech,是科技创新发展最快的领域之一。预计它将呈指数级增长,并在未来几年内显著重塑金融格局。根据 Fintech Global 的数据,2018 年全球金融科技行业筹集了惊人的 417 亿美元投资。根据普华永道 2017 年全球金融科技报告,“82%的现任者预计在未来 3-5 年内增加金融科技合作。”因此,即使你不倾向于转行,了解你在不久的将来可能要合作和接触的玩家也是很重要的。
“你必须……重新想象如何管理和转移资金,因为未来 5 年金融服务业的变化将超过过去 30 年。”—PayPal 首席执行官丹·舒尔曼
目前,合格的金融科技工作者的需求远远大于供应,在这个市场上,潜在候选人很有可能继续在雇主面前占据上风。区块链、数据科学和机器学习等领域对知识工作者的需求很高。这些现代工作要求金融专业人士采用新技能,并熟练掌握技术语言。谁掌握了这一组合,谁就会加入少数幸运者的行列,他们的职业生涯将充满希望、挑战和利润。
随着金融科技的进步,对合格工人的需求预计将保持高位,而供应将保持低位。因此,工资将反映这一差异。
随着现有工作开始消失,新的工作到来,了解金融就业市场的走向非常重要。随着金融科技的进步,预计需求将保持高位,供应将保持低位。因此,工资将反映这一差异。出于上述原因,我们在下面介绍了一些薪酬最高的金融科技角色。
1。区块链专家和开发者 区块链技术在金融领域前景广阔。例如,基于区块链网络的智能合同允许在没有第三方参与的情况下进行可信的交易。这有可能取代和淘汰许多中介角色,如经纪人和银行机构。
在普华永道进行的 2017 年全球金融科技报告中,提出“77%的金融机构预计到 2020 年将采用区块链作为生产系统或流程的一部分”。区块链开发人员是与区块链技术公司合作的软件开发人员。他们负责区块链应用程序从研究到执行的整个生命周期。这一领域的人才稀缺,导致工资比正常工作至少高出 10-20%。平均每个区块链开发者有 14 个工作机会,我想他们的胜算更大。
2。应用专家(开发人员和架构师) 应用专家的主要角色是应用和软件设计,因为应用专家从头到尾指导产品生命周期。这包括设计流程以及创建、测试和介绍应用程序。应用专家还会修改现有软件,并对可能出现的任何软件相关问题进行故障排除。
3。数据科学家
如今,财务部门在很大程度上依赖数据科学来简化决策并为各种问题提供更好的解决方案。数据科学家帮助连接成千上万的信息源之间的点,并反过来为客户提供更好、通常更有效的解决方案。
今天,有了大量的现有数据,数据科学家告诉我们这一切意味着什么。因此,对数据科学家、数据分析师和分析专家的需求很大,并相应地要求高报酬。
根据 Glassdoor 的数据,数据科学家被列为 2019 年美国排名第一的工作。Glassdoor 的排名考虑了职位平均工资、空缺职位数量以及该职位员工的平均工作满意度。
4。网络安全专家
随着越来越多的金融数据以数字化方式存储和传输,网络攻击和黑客攻击也越来越多。不幸的是,网络技能安全缺口很大,而且还在扩大。因此,组织愿意花费大量的金钱来引进能够保护他们的在线资产和数据的人。据《福布斯》(Forbes)报道,“网络安全专业人员的平均工资为 11.6 万美元,是全职工资和薪水工人全国平均收入的近三倍。”
改旧迎新
许多长期存在的金融角色将继续存在,但会有所改变。例如,合规和风险管理这两个重要的金融领域将变得越来越重要,因此也越来越有利可图。鉴于技术的影响,这些高薪职位所需的技能将包括现代元素。我们解释如下:
6。风险控制经理
风险经理分析和控制企业的财务风险。评估和确定风险程度是金融界的基石。在现代世界中,数据科学是一项关键资产,可帮助金融机构构建更快、更好的风险决策流程和评估。
像 FICO 这样的信用评级机构和信用评分公司已经依靠数据科学和机器学习来获得借款人的即时数据。例如,他们使用逻辑回归来预测客户的风险,并区分好的借款人和坏的借款人。更新技术世界的长期角色是必要的,以确保它们继续存在。
7。合规专家 技术的作用越大,就越需要合规专家。随着技术对规则和法规提出新的挑战,监管的必要性和重要性与日俱增——新的法规越来越多,更严格的法规是必要的。
新平台已经在挑战做事的方式。
除了金融科技的角色,许多金融科技平台和技术已经在改变金融工作的方式。以下是您可能很快就会看到的集成、改变或取代财务工作场所流程的几个平台:
区块链平台
共生体是领先的智能合约平台。有了 Symbiont,机构可以依靠统一的分类帐来获取商业信息和市场数据。区块链平台可以用来创建数字形式的金融工具,包括贷款和证券。通过构建数据共享网络来降低风险、保护数据并节约成本。
支付平台
Payoneer 的跨境支付平台帮助企业在全球范围内支付和收款,就像在自己的城市一样轻松。使用 Payoneer,您可以轻松管理多个供应商,向供应商付款,并轻松获得来自世界各地的营运资金,从而超越您所在国家的边界。Payoneer 等平台为银行和传统贷款机构带来了新的竞争。
自动化平台
DataRails 通过自动化基于 Excel 的数据的繁琐合并流程,彻底改变了 FP &完成工作的方式。凭借其专利技术,DataRails 将所有基于 Excel 的数据整合并存储在基于云的集中式数据库中。节省时间、金钱和精力,而无需改变您的工作方式。DataRails 改进了财务部门,尤其是财务专业人员的工作方式和获取见解的方式。
借贷平台 Kabbage 是一个新颖的借贷平台,与 Payoneer 等支付平台一起,与传统金融服务相抗衡。Kabbage 提供了一种更简单的企业融资方式,允许个人在 10 分钟内获得高达 25 万美元的信贷。通过消除获取信贷的令人疲惫的过程,Kabbage 为小型和新兴企业提供了发展和繁荣的机会。
准备好,准备好,开始!不管喜欢与否,比赛已经开始了。
传统金融需要适应,否则就会被创新超越。
最后,我想引用“不同思考”小组的合伙人 David M. Brear 的话。尽管他专门谈到了银行业,但他的话引起了整个金融业的共鸣。
“技术创新将是未来许多年银行业的心脏和血液,如果大银行不能充分利用这一点,金融科技和大型科技公司的新参与者肯定会。”
-David M . Brear,合伙人,不同思维小组
最小 k 路切割问题的简单快速确定性算法
用一个例子逐步解释 m .托鲁普的“通过确定性贪婪树包装的最小 k 路切割”中的算法。
最小 k 向切割
设 G= ( V,E,c: E →R+ ) 是一个有容量限制的图,其中 |V|=n 个节点, |E|=m 个边。一个 k 路切割是将节点划分成 k 组。切割边是连接不同组中的节点的边。最小 k 路切割问题的目标是找到最小化切割边总容量的 k 路切割。

In the left, a capacitated graph. In the right, a minimum 3-way cut. The weight of the cut is the sum of the capacities of the edges that are not in the right subgraphs, which is 52.
最小路割问题在网络出现的不同领域都有应用,例如,在社交网络中划分兴趣组。它还用于查找电信网络甚至流量网络中最弱的连接。
解决问题
如果 k 是输入的一部分,那么为有容量限制的图寻找最小 k 路割的问题是 NP 难的,参见[1]。在 k 固定的情况下,问题是多项式可解的。
M. Thorup 在[2]中提出的算法解决了soft-o(n^(2k),参见 soft-O wikipedia 。
算法:通过确定性贪婪树包装的最小 K 路切割,由 m .托鲁普提出
该算法建立在 m .托鲁普在[2]中提出的以下定理的基础上:
对于 0 < a < 9/10,设 T 是一个至少有 3 个m(k/a)ln(nmk/a)树的贪婪树包装。然后,平均起来, T 的树交叉每条最小k-路割不到 2( k- 1+2 a )次。特别地,对于 a =1/4,每个最小 k 道切口被 T 中的某棵树最多穿越 2 k -2 次。
考虑到 a =1/4 的特殊情况,寻找最小 k 路径切口的过程如下:
- 构建贪婪树包装。
- 对于至少一棵树的包装,收集每个 k 道切口不超过 2k2 次。
- 从集合中选择最小的 k 向切削,也就是最小的 k 向切削。
逐步解释
在这个解释中,目标是找到以下容量限制图的最小 3 路截

Capacitated graph.
第一步:生成贪婪树包装
贪婪树打包是图的生成树的集合,其通过将关于利用率的最小生成树添加到集合中来构建。
一条边的利用率是该边在包装的当前树中的次数与其容量的商。因此,每次将一棵树添加到包装中,这些边的利用率都会随着其容量的倒数而增加。
贪婪树打包获得的第一个生成树如下:

First nine spanning trees (left-right by row) of the greedy tree packing. Edge labels are the capacities.
步骤 2:建造每一个 k 道切口,该切口被树穿过少于 2k2 次
如果对于每棵树,我们得到所有没有被该树交叉超过 2 次的 k 个方向切口,则最小的 k 个方向切口必须在最终集合中。那么,如何列出给定树木的采伐量呢?现在对包装的第一棵树进行解释,并且必须对它们中的每一个进行解释。有两个步骤:
- 考虑从树上切割 2 条 k 条 -2 条边所产生的所有可能的图形。这些切割中的每一个都有 2 个 k -1 块。

Sample of cuts generated by cutting 2k-2 edges from the first tree of the packing. Pieces of the first cut would be 1:[0, 1, 6, 7], 2:[2, 5], 3:[3], 4:[4], 5:[8]
- 对于每个切割,以各种可能的方式将 2 个 k -1 件分成 k 组。在这样的分组中,被分成 k 块的节点诱导出一个 k 路割(在不同组的节点之间没有边的原始图),该图满足被考虑的生成树交叉不超过 2 k -2 次的条件。

All 3-way cuts extracted from the first cut (previous figure’s first) of the first tree.
这样做的关键是,对于给定的树,删除 2 条 k -2 条边相当于确保我们只允许这些边穿过 k 路切割,因为剩余的边将节点保留在一个片段中,这些节点必须属于将片段分成 k 组的每个可能分组中的同一组。
这 25 个作为最小 k 路切割的候选是从贪婪树包装的第一棵树的第一次切割中提取的。必须对包装中每棵树的 2 个 k -2 个边缘的所有可能切割进行收集。
第三步:选择最小k-路切
最小 k 路切削是生成的 k 路切削集合的最小值。
时间复杂度
算法的时间复杂度是找到定理所有可能的 k 路割的时间。有关更多详细信息,请查看算法参考。因此,
- 贪心树包装:3 棵m(k/a)ln(nmk/a)=soft-O(MK)树,每棵在 O(n) 。对于每棵树:
- 树的 2 k -2 条边的所有可能切割: Binom ( n- 1,2k-2)=soft-o((en/(2k-2))^)2k-2)可能性。对于每次切割:
- 将 2 个 k -1 块分割成 k 套:最多k^(2k-1)/k!= 软-o((ek)^(k-1))不同的方式。
每个分区可以在固定的时间内生成分区,因此,时间复杂度变为soft-o(n^(2k)。
结论
在这篇文章中,解释了一个寻找有容量限制的图的最小 k 路割的算法。接下来是一个例子,看看它是如何工作的,最后起草了一个简单的复杂性分析。
图形操作和数字是用 Python 的 NetworkX 包创建的,见[3]。
参考
- O.戈德施密特和 D. S .霍赫鲍姆。固定 k 的 k 割问题的多项式算法。数学。操作。第 61 号决议,1994 年。
- 米(meter 的缩写))托鲁普。经由确定性贪婪树包装的最小 k 路切割。第四十届 ACM 计算理论年会会议录, 2008。
- NetworkX,https://NetworkX . github . io。
附录
算法的 Python 代码
在本附录中,有在 python 中运行算法的代码。该代码不是为最佳体验而优化的,它旨在阐明所描述的算法的定义和结构。
预测性维护的简单且可解释的基线
不久前,我在数据科学工作中遇到了一个预测性维护问题。高度不平衡的类(因为破损的数量通常小于 1%),大量不可解释的传感器——好吧,但下一步是什么?由于我缺乏这方面的经验,我开始搜索和阅读所有我能找到的关于“项目管理的数据科学”的资料。
令我失望的是,我发现的大多数文章都没有给我提供有价值的见解——它们要么是一些复杂的 Arxiv 论文,在不可用的数据上测试新的理论方法,要么是一些高水平的博客帖子,缺乏可重用的想法。
经过几个月用机器学习解决预测性维护(进一步设置为 PM)问题的实践经验,我厌倦了辛劳,决定分享我迄今为止开发的基线方法。对于像我几个月前一样,不知道该做什么,希望附近有某种灯塔的人来说,这可能是富有成效的。
在帖子中,我将解释问题的业务方面,并列出客户端对算法的典型要求,这可能会极大地限制可用的数据科学工具集。接下来,我将详细解释我的方法,并强调其利弊。最后,我将分享一些实用的技巧和代码片段,对实现它有所帮助。
业务问题
如果你只对技术感兴趣,你可以跳过这一部分。
安装在业务流程中的每个 ML 算法都应该以某种方式增加利润。在项目管理中,我们通常有一台大型机器,消耗昂贵的资源,通过复杂的多阶段过程产生某种最终输出。随着时间的推移,这些机器会意外损坏,导致闲置时间增加和宝贵资源的损失,因为发生故障的机器通常会浪费这些资源。
这就是 ML 算法可以进入场景的地方——它可以使用安装在机器上的传感器的数据,提前预测故障(我在全文中交替使用停止、损坏、停止)。然而,即使我们能够提前预测这些停止,在不知道原因的情况下,我们预测的财务价值将是适度的。
首先,如果我们向工程师报告的唯一信息是在接下来的 20 分钟内破损的可能性很高,他们就不能做太多。也许,他们可以停止机器,做一些深度维护,但这是昂贵的。此外,对于大型机器,他们不一定会在如此短的时间内发现故障原因,因此,我们预测的价值是无效的。第二,我们的算法会有一定的误报。由于假阳性的存在,客户端很少会批准停止机器来检查不明显的故障。
因此,我们的算法,除了预测停止的概率,应该在某种程度上暗示可能的原因。它将为技术人员在预防性维护过程中查找故障提供一定的指导。在这种情况下,我们的 ML 算法真正解决了客户的痛苦。
数据准备
现在让我们仔细看看一个典型的预测性维护数据。下面是完成数据准备后,结果变量的样子。 Y = 1 如果即将停止,而 Y = 0 如果在接下来的 K 分钟内没有停止。
你可以看到,类是不平衡的,机器学习模型应该给稀有类更高的权重,以便用更强的注意力来区分导致停止的异常。

Outcome variable
但是要获得这个时间序列,你必须做一些繁重的工作。通常,它们会为您提供两个数据集-一个包含有关停靠点的信息(它们的性质、原因和时间戳),另一个包含来自传感器的所有数据。
我们需要合并这两个文件来创建数据集。我建议当机器坏了时,停止观察(下面是数据处理的代码样本),因为这些信息可能有噪音。例如,可以丢弃到下一站的时间少于 5 分钟的所有观测。
接下来,让我们将到达下一站的时间超过 20 分钟的所有观察值标记为零,而将到达下一站的时间小于 20 分钟的所有观察值标记为一(您可以根据您的数据改变这个临界值)。这个操作稍微改善了你的职业平衡。
通常在机器的不同部分有不同类型的停止。我建议筛选数据,选择最常见的一个,然后将解决方案推广到其他止损点。不同类型的停车有不同的原因,因此,关于每次停车的信息将包含在不同的传感器组中。因此,一个通用模型不太可能表现良好。
一些可能有助于您完成上述操作的代码:
https://gist.github.com/ikleni/fa9421f23852459e166f14a5f4edb584
第二,要处理好解释变量( Xs )。在我们将它们与一个结果变量合并后,我们应该尝试降低维度,以便得出有意义的结论。在没有任何行业细节的先验知识的情况下,我们无法根据我们的直觉选择哪些对应于重要的预测因素。就看一些 Xs 的剧情:



Examples of sensors
然而,我们有很多技术可以降低维度:
- 超低方差跌落传感器
- 根据传感器在机器中的位置/角色对传感器进行分组和聚合(通过 PCA 或其他类似技术)(此信息可从其标签中获得)
- 变量的总体变化(有多少传感器刚刚改变了它们的状态)
根据与结果变量的原始相关性选择变量不是一个好主意
在我的任务中,变量变化的汇总很有帮助,因为它既包含了机器不稳定的信息,又减少了变量的数量。
这里有一个这样的聚合变量:

Aggregated variable and Y
我们可以进一步限制我们的传感器空间。
让我们反复挑选每个传感器,并尝试根据其分位数预测止损点。如果传感器的当前时间序列分位数在某种程度上指示停止,则传感器包含关于机器异常行为的信息。我建议选择大约 5-15 个(这个范围适用于我的特殊问题)传感器,它们的分位数模型具有最强的预测能力。
这一步预测能力的丧失取决于止损的数据和性质,因为有时某一顺序的复杂相互作用可能对预测至关重要。然而,我们的主要目标是简单的基线可解释性和对客户的可解释性。
另一个有用的事情是在停止之前和稳定工作期间检查所选传感器的行为。如果你注意到你的时间序列图在停止之前有异常,你就有很好的机会解决这个问题。

Sensors just prior to the stop (look for simultaneous jumps in certain variables)
生成此类图的代码:
https://gist.github.com/ikleni/95d93442f1042d1c7e3bf392d4322a30
建模
思绪
给定行为良好的( X,Y )(我假设你已经做了其他标准的数据预处理,比如处理缺失值)数据我们就可以开始建模阶段了。
在测试一些模型之前,我们可以假设信号包含在哪里。机器是为了正常运转而设计的。此外,它们还规定了一个稳定的工作状态,指示每个传感器的值的区间。如果由于某种原因(工程师没有顺利改变某个参数),机器偏离了规定的运行状态,它可能会发生故障。随着时间的推移,机器变得越来越不稳定,操作制度应考虑到这种转变。这种情况很少发生——这可能是我们完成这项任务的面包和黄油。
我希望通过每个传感器与一些新值范围的偏差,可以很好地预测止损。此外,我预计几个传感器之间的相互作用将预测停机。例如,如果一个传感器偏离其正常间隔,而另一个传感器的值为 w ,则不会发生停机。但是,如果同一个传感器出现偏差,而另一个传感器的值为 z ,则停止是不可避免的。
我不期望(这个假设对我的任务有好处)大量传感器之间的交互对这个任务有帮助。特别是,如果我们量化当前超出其标准值范围的传感器总数。这种整体机器稳定性应该是该模型的关键特征之一。
接近
考虑到这一点,我选择用基于 2-3 个传感器和集合特征的小模型的多数投票集合来预测停靠点。这种方法允许识别哪些传感器发出停止信号。这些信息可以在以后提供给工程师,工程师可以根据他们的知识找出原因并解决问题。
首先,我使用具有特定调整参数的基本 LGBM 模型,从我们的受限集合中选择一组传感器对(三元组)。根据 k 倍时间序列交叉验证的 AUC 分数,通过对成对的迭代搜索进行选择。除了传感器数据,这些小型模型还包括聚合功能和一些基于传感器的直观功能,例如:
- 平均
- 趋势
- z 分数
- 标准
变量生成代码:
在确定了小模型的集合之后,它们的预测通过基本集合被组合。发现 0.5 分位数,如果它高于预定义的边界,我预测 Y = 1,止损应该很快出现。报警!
上述方法略有简化,还可以做更多的工作来提高其精度,例如:
- 其他组装技术(RNN 和其他…)
- 其他初级学习者
- 搜索剩余的传感器,并将它们添加到一些小模型中
- 为每个生产体系建立一个单一模型(夏季/冬季在传感器值的分布上有很大不同,这可以通过 Kolmogorov-Smirnov 测试进行检查)
结果
在我看来,图像比文字或指标更能说明问题,如果你看到算法很少预测停止,但当机器确实发生了一些事情时——我们很好:

Good performance of the baseline

Bad performance
在我的数据中,所描述的框架能够以大约 40%的精度和大约 40%的召回率预测停止,这对于预测性维护中的基线来说是一个好结果。此外,它为工程师提供了特定传感器的参考,因为他们知道哪些传感器发出停车的可能性较高。因此,他们可以进行有针对性的预防性维护。
最后,我将简要总结一下这种方法的利弊:
优点
- 简单性和可解释性(由于每个型号的传感器数量如此之少,您可以强调机器的哪个部分驱动了停止的威胁)
- 对 GPU 使用和内存的低限制
缺点
- 在准确性方面次优(具有所有特征的训练有素的神经网络可能优于该基线)
- 计算时间限制(所有这些迭代搜索都需要时间)
- 人的时间限制(这种方法需要人的指导)
稍后我会添加链接到省略的代码。此外,我要感谢 Kaggle Bosch 竞赛,我用它创作了所有这些图像…
Python 中模板化 SQL 查询的一种简单方法
加速和自动化您的分析

在许多情况下,人们都希望在 SQL 查询中插入参数,并且有许多方法可以在 python 中实现模板化的 SQL 查询。在不比较不同方法的情况下,这篇文章解释了一种使用 JinjaSql 参数化 SQL 的简单而有效的方法。除了 Jinja2 的许多强大功能,如条件语句和循环,JinjaSql 还提供了一种简单明了的方法,不仅可以参数化代入where和in子句的值,还可以参数化 Sql 语句本身,包括参数化表和列名,以及通过组合整个代码块来组合查询。
基本参数替代
假设我们有一个保存金融交易记录的表transactions。该表中的列可以是transaction_id、user_id、transaction_date和amount。要计算给定用户在给定日期的交易数量和总金额,直接对数据库的查询可能如下所示
**select**
user_id
, count(*) as num_transactions
, sum(amount) as total_amount
**from**
transactions
**where**
user_id = 1234
and transaction_date = '2019-03-02'
**group by**
user_id
这里,我们假设数据库会自动将日期的字符串表示形式的YYYY-MM-DD格式转换成适当的日期类型。
如果我们想要为任意用户和日期运行上面的查询,我们需要参数化user_id和transaction_date值。在 JinjaSql 中,相应的模板将简单地变成
**select**
user_id
, count(*) as num_transactions
, sum(amount) as total_amount
**from**
transactions
**where**
user_id = {{ uid }}
and transaction_date = {{ tdate }}
**group by**
user_id
这里,值被占位符替换,python 变量名用双花括号{{ }}括起来。注意,选择变量名uid和tdate只是为了证明它们是变量名,与列名本身没有任何关系。存储在 python 变量中的同一模板的一个可读性更好的版本是
**user_transaction_template** = '''
**select**
user_id
, count(*) as num_transactions
, sum(amount) as total_amount
**from**
transactions
**where**
user_id = {{ user_id }}
and transaction_date = {{ transaction_date }}
**group by**
user_id
'''
接下来,我们需要为查询设置参数。
params = {
'user_id': 1234,
'transaction_date': '2019-03-02',
}
现在,从这个模板生成 SQL 查询非常简单。
**from** jinjasql **import** JinjaSql
j = JinjaSql(param_style='pyformat')
query, bind_params = j.prepare_query(user_transaction_template, params)
如果我们打印query和bind_params,我们会发现前者是一个参数化的字符串,而后者是一个参数化的OrderedDict:
>>> print(query)
**select**
user_id
, count(*) as num_transactions
, sum(amount) as total_amount
**from**
transactions
**where**
user_id = %(user_id)s
and transaction_date = %(transaction_date)s
**group by**
user_id>>> print(bind_params)
**OrderedDict**([('user_id', 1234), ('transaction_date', '2018-03-01')])
运行参数化查询
许多数据库连接都可以选择将bind_params作为参数传递给在连接上执行 SQL 查询的方法。对于数据科学家来说,在 Pandas 数据框中获得查询结果可能是很自然的事情。一旦我们有了连接conn,就像运行read_sql一样简单:
**import** pandas **as** pd
frm = pd.read_sql(query, conn, params=bind_params)
其他示例参见 JinjaSql 文档。
从模板到最终的 SQL 查询
通常希望在运行查询之前用所有参数完全展开查询。例如,记录完整的查询对于调试批处理过程非常重要,因为可以将查询从日志中直接复制粘贴到 interactive SQL 界面中。使用 python 内置的字符串替换将bind_params替换到query中是很诱人的。然而,我们很快发现字符串参数需要加引号才能产生正确的 SQL。例如,在上面的模板中,日期值必须用单引号括起来。
>>> print(query % bind_params)
**select**
user_id
, count(*) as num_transactions
, sum(amount) as total_amount
**from**
transactions
**where**
user_id = 1234
and transaction_date = 2018-03-01
**group by**
user_id
为了处理这个问题,我们需要一个助手函数来正确地引用字符串参数。我们通过调用来检测参数是否是字符串
**from** six **import** string_types
isinstance(value, string_types)
这对 python 3 和 2.7 都适用。字符串参数被转换为str类型,名称中的单引号被另一个单引号转义,最后,整个值被括在单引号中。
**from** six **import** string_types**def** quote_sql_string(value):
'''
If `value` is a string type, escapes single quotes in the string
and returns the string enclosed in single quotes.
'''
**if** isinstance(value, string_types):
new_value = str(value)
new_value = new_value.replace("'", "''")
return "'{}'".format(new_value)
**return** value
最后,为了将模板转换成正确的 SQL,我们循环遍历bind_params,引用字符串,然后执行字符串替换。
**from** copy **import** deepcopy**def** get_sql_from_template(query, bind_params):
**if** **not** bind_params:
**return** query
params = deepcopy(bind_params)
**for** key, val **in** params.items():
params[key] = quote_sql_string(val)
**return** query % params
现在我们可以很容易地得到最终的查询,我们可以记录或交互运行:
>>> print(get_sql_from_template(query, bind_params))**select**
user_id
, count(*) as num_transactions
, sum(amount) as total_amount
**from**
transactions
**where**
user_id = 1234
and transaction_date = '2018-03-01'
**group by**
user_id
将所有这些放在一起,另一个 helper 函数包装 JinjaSql 调用,简单地获取模板和一个dict参数,并返回完整的 Sql。
**from** jinjasql **import** JinjaSql
**def** apply_sql_template(template, parameters):
'''
Apply a JinjaSql template (string) substituting parameters (dict) and return
the final SQL.
'''
j = JinjaSql(param_style='pyformat')
query, bind_params = j.prepare_query(template, parameters)
return get_sql_from_template(query, bind_params)
计算列的统计信息
无论是在第一次浏览数据时还是在生产中进行数据验证时,对存储在特定数据库列中的值计算统计数据都很方便。因为我们只想演示模板的一些特性,为了简单起见,让我们只使用integer列,比如上面表transactions中的user_id列。对于整数列,我们感兴趣的是唯一值的数量、最小值和最大值以及空值的数量。有些列可能有一个默认值,比如说,-1,它的缺点超出了本文的范围,但是,我们确实想通过报告默认值的数量来捕获它。
考虑下面的模板和函数。该函数将表名、列名和默认值作为参数,并返回用于计算统计数据的 SQL。
**COLUMN_STATS_TEMPLATE** = '''
**select**
{{ column_name | sqlsafe }} as column_name
, count(*) as num_rows
, count(distinct {{ column_name | sqlsafe }}) as num_unique
, sum(case when {{ column_name | sqlsafe }} is null then 1 else 0 end) as num_nulls
{% if default_value %}
, sum(case when {{ column_name | sqlsafe }} = {{ default_value }} then 1 else 0 end) as num_default
{% else %}
, 0 as num_default
{% endif %}
, min({{ column_name | sqlsafe }}) as min_value
, max({{ column_name | sqlsafe }}) as max_value
**from**
{{ table_name | sqlsafe }}
'''
**def** get_column_stats_sql(table_name, column_name, default_value):
'''
Returns the SQL for computing column statistics.
Passing None for the default_value results in zero output for the number
of default values.
'''
params = {
'table_name': table_name,
'column_name': column_name,
'default_value': default_value,
}
**return** apply_sql_template(COLUMN_STATS_TEMPLATE, params)
这个函数很简单而且非常强大,因为它适用于任何表中的任何列。注意模板中的{% if default_value %}语法。如果传递给函数的默认值是None,SQL 将在num_default字段中返回零。
如果default_value设置为 None,上面的函数和模板也可以处理字符串、日期和其他数据类型。然而,为了更智能地处理不同的数据类型,有必要扩展该函数,以将数据类型作为参数,并构建特定于不同数据类型的逻辑。例如,可能想知道字符串长度的最小值和最大值,而不是值本身的最小值和最大值。
让我们看看transactions.user_id列的输出。
>>> print(get_column_stats_sql('transactions', 'user_id', None))**select**
user_id as column_name
, count(*) as num_rows
, count(distinct user_id) as num_unique
, sum(case when user_id is null then 1 else 0 end) as num_nulls
, 0 as num_default
, min(user_id) as min_value
, max(user_id) as max_value
**from**
transactions
请注意,空行出现在{% %}子句的位置,可以被删除。
摘要
有了上面的帮助函数,用 python 创建和运行模板化的 SQL 查询就非常容易了。因为参数替换的细节是隐藏的,所以可以专注于构建模板和参数集,然后调用单个函数来获得最终的 SQL。
一个重要的警告是代码注入的风险。对于批处理来说,这应该不是问题,但是在 web 应用程序中使用sqlsafe构造可能会有危险。sqlsafe关键字表明用户(您)确信不可能进行代码注入,并负责将参数中传递的任何字符串直接放入查询中。
另一方面,在查询中放入任意字符串的能力允许将整个代码块传递到模板中。例如,可以不通过上面的table_name='transactions',而是通过'(select * from transactions where transaction_date = 2018-03-01) t',查询仍然可以工作。
要探索 SQL 模板更强大的特性,也可以参考关于使用 JinjaSql 的 Python 中的高级 SQL 模板教程。
本帖中的代码获得了麻省理工学院许可的许可。这篇文章最初出现在生活数据博客上。
Sergei Izrailev 的照片和图片
一个简单而有效的面试准备技巧
尝试这种实用的方法来准备数据科学面试
正好逢年过节,各位求职者,我送给你的礼物是一个非常实用的面试准备方法。如果你也这么做,保证你有 100 万的工作机会!不过说真的,这样做了之后,在面试的时候谈自己和自己的工作就会轻松很多。回忆关于你技能的信息越容易,面试就越容易。
方法?在你的简历中标注#$%。
制作一份简历的副本,并保存为一个单独的文件。然后,花一到三个小时对这份文件进行评论,每项技能、项目或角色都与你面试的角色相关(简称“TRYIF”)。面试官可能会把你的简历作为他们会问你的问题的指南,无论是文化问题还是技术问题,所以你可以在评论中同时关注这两个问题。
如果你有一份过去几周一直在申请工作的“通用”简历,这尤其有帮助。这是一个通过 TRYIF 的镜头唤起你对每个主题的记忆并思考它的练习。最近你对这些事情想得越多,谈论它们就越容易。

Google docs is a good way to organize your resume thoughts
你的评论应该至少涵盖其中的一个方面,你涵盖的越多,你的准备就越充分。每一个后面都有一个我今天早些时候准备的简历注释的例子:
a) 定义或用你自己的话或从其他来源对项目的解释,还是那句话对你最有利。Seaborn:“Python 数据可视化库,它提供了一个高级接口,用于绘制有吸引力且信息丰富的统计图形。”(来自其网站)或 Seaborn:让 matplotlib 更漂亮。
b)项目的目标优点和缺点。 Pandas:因为有表格,所以很容易使用,但不能处理大量数据(超过 10gb 时会非常慢)
c) 该物品在您过去项目中的重要用途烧瓶:部署 汇聚 以及使用它的 Doppel app
d) 您对项目用药过量 项目的意见:很难找到这个项目的数据集,了解了很多关于人口普查及其 API 和阈值的信息。
其中一些可能看起来“多余”,但有一些很好的理由来注释你的简历。通常面试官感兴趣的是听你如何向那些不知道你在说什么的人解释事情。也有可能面试官不熟悉你简历上的某件事,然后你可以很快回忆起你刚刚为他们创造的简单解释。最后,这些很容易写,因为除了你没有人会看到它们。你不必担心语法或让它们变得完美——这完全是你的大脑的事!
面试并不容易,但是把这种方法和一般的面试建议结合起来,做很多项目,你就在获得工作机会的路上了,我的朋友。你自己试试吧,并告诉我你的想法。
新年快乐!希望新工作也愉快!

Photo by Suhyeon Choi on Unsplash
一个简单但强大的人工智能机器人,用于六边形网格上的创/光骑士
基于寻路的简单启发式算法如何找到通往排行榜顶层的路径。
新的学年,意味着新一批聪明的学生开始了他们工程生涯的第一步。和去年一样,我和我的三个课程助理同事(埃利亚斯、彼得和奥赞)为一个人工智能机器人竞赛创建了一个平台,将在根特大学的教授 Dhoedt 讲授的信息学课程(他们在该课程中学习 Python 编程)期间举办。今年,我们决定主办 Tron(有时称为连续蛇或 Lightriders)的游戏,如下所示。

A more advanced implementation of the game Tron, called Armagetron
既然谜语. io 和 CodinGame (如果你对 AI 机器人感兴趣的话绝对应该去看看!)也为 Tron 举办一场人工智能比赛,我们决定稍微修改游戏,让它在六边形网格上玩,而不是正方形。这可以避免学生只是复制粘贴那些平台的可用解决方案。游戏截图可以在下面找到。

A visualization of a match between two bots, which I lost. The darker colored tiles are starting positions.
和去年一样,我决定自己参加比赛,但没有那么多空闲时间。因此,我的解决方案不是很强。尽管如此,我最终在排行榜上名列前茅(第五名),拥有最少的代码基础和简单的启发式搜索,基于路径查找。

The top 10 of the final leaderboard. Again this year, we were amazed by the quantity and quality of many submitted agents by students. Notice how jvdhooft, my partner in crime of last year, regretted his decision of not collaborating this year 😉.
为了讨论我的解决方案,我不需要像去年那样多的时间/行数,因此我决定添加一些额外的内容。我把这篇博文分成几个部分:
目录
- 游戏和竞赛规则
- 我的强启发式的详细概述(附代码)
- 一些顶级竞争对手写的文章
- 竞赛平台制作概述(另文)
1.游戏和竞赛规则
1.1 游戏规则
游戏规则相当简单明了。两个玩家都从一个随机的位置(镜像在地图的中心)开始,并且有一个随机的方向(总共有 6 个方向)。每个玩家必须决定是否要旋转他们的蛇(120°或 60°顺时针/逆时针或 0°),然后向前移动(如下图所示)。每条蛇都会留下难以穿越的痕迹。第一条撞到墙壁或自己或对手的踪迹的蛇输掉游戏。

The five possible moves a player can make in each turn.
1.2 竞赛规则和代理界面
提交的代理必须遵循预定义的界面:
def **generate_move**(board, positions, orientations):
"""Generate a move.
Args:
board (np.array): playing field
positions (list): list of positions `(x, y)`
orientations (list): list of orientations (int in [0,5]) Returns:
move (int): integer in [-2,2]
"""
return 0
此外,每个代理必须遵守以下限制:
- 它不包含
import语句,除了:numpy, functools, itertools, collections, operator, heapq, math, random, time - 文件大小不得大于 1 兆字节
generate_move的执行时间不得超过 1 秒
向我们的平台提交您的第一个代理后,您将每 30 分钟与另一名玩家配对一次。每场比赛结束后,双方玩家的排名( TrueSkill 或 ELO )会根据比赛结果进行调整,这些排名用于排行榜。关于排名系统的更多信息,请参考我的下一篇文章。
1.3 定期比赛和附加赛
比赛持续了 1 个月左右。我们注意到运气对你的最终排名有很大的影响(由于匹配算法)。为了克服这一点,并尽可能客观地结束排名,我们在一段时间后从排行榜上剔除了排名靠前的竞争者(仅限一年级学生)。这些竞争者被挑选出来参加“附加赛”,每个代理人与所有其他代理人比赛四次。每赢一场,代理人被分配三分,而平局(有很多场)导致双方代理人被奖励一分。
2.我的基于寻路的强启发式算法
2.1 主回路
在实现更复杂的技术之前,比如强化学习、遗传算法和阿尔法-贝塔剪枝,首先实现一个基于启发式的代理总是一个好的实践。这些可以用来测试你对手的实力,但更重要的是你代理的后期版本的实力。不幸的是,由于时间不够,我今年没有实现更复杂的技术,只上传了我的基线代理,基于一个启发式的(结果非常强大)。我现在将彻底讨论我的实现。
我的代理人背后的主要推理相当简单:“总是选择导致你可以首先到达的牌的数量与你的对手可以首先到达的牌的数量之间的最大差异的移动。”很明显,会有很多情况下,每一个可能的走法的结果都是相同的分数(尤其是在游戏开始的时候)。我们通过最小化某一步后剩余合法走法的数量和最小化到中间的距离(如果还能到达的话)来打破平局。主游戏循环如下所示:
The main loop of our agent. In each turn, we iterate over all possible legal moves
2.2 获得所有合法移动
现在让我们把所有事情都分解开来,从(可能)代码中最简单的部分开始:获得所有合法的移动(get_legal_moves)。在这个函数中,我们迭代区间[-2,2]中的每个整数,这是五个可能的移动。我们将每个整数映射到一个偏移量元组(get_steps),该偏移量元组对应于我们的移动,并根据这些偏移量更新我们假设的位置和方向(_update_pos_orient)。然后,我们计算我们是否仍然居住在六边形网格中(_valid_position)以及我们是否没有撞上一个已经被占用的单元(_no_crash):
代码相当简单,可能不需要太多的阐述。为了检查我们是否仍然在六边形网格中,我们必须通过检查我们的x和y坐标是否没有超出我们游戏区域的边界来确保我们没有得到IndexError。此外,由于棋盘表示是一个带有一些不可到达的单元格的正方形,我们需要确保我们的代理不会移动到这些单元格中的任何一个上。通过检查主页上描绘的较小(7x7)游戏场,我们注意到合法单元的x和y之和以 3 和 9 为界。

The x and y coordinates of the allowed tiles on a 7x7 field are bounded by 3 and 9.
这适用于所有比赛场地,因此我们可以说:

k 是运动场的大小。此外,为了检查我们是否没有在已经被占用的单元上移动,我们可以只沿着我们的游戏板的最终轴进行求和(记住这个游戏板的最终轴包含每个玩家的位图),并检查我们想要移动到的坐标的值是否等于 0。此外,_get_steps中偏移的顺序是特定的顺序,这样我们可以使用我们新计算的方向(等于(orientation + action) % 6)直接索引它们。使用这个新的方向,我们可以得到相应的偏移量,并将它们添加到我们当前的坐标中,以计算我们的新坐标。
2.3 计算游戏状态的效用或分数
现在我们有了一个不会导致我们立即失败的所有移动的列表,我们可以根据启发式算法计算每个移动的分数。我们使用的试探法是基于到游戏区域中每个可能牌的距离。我们希望在比对手少走几步的情况下,尽可能多的拿到牌,同时尽可能少的先拿到牌。下面展示了一个不错的 GIF,取自谷歌 Tron 人工智能挑战赛中获胜解决方案的报道。

Maximizing the cells we (red) can reach first, while minimizing the cells our opponent (blue) can reach first results in a strong, but not optimal, heuristic.
为了计算从某个坐标到另一个单元的最小距离,我们可以使用 A*寻路算法或 Dijkstra 。但是因为我们需要计算到网格中所有单元的距离,所以我们使用一个稍加修改的版本。我们跟踪仍然需要访问的单元列表(以及到每个单元的距离),称为frontier。对于我们的边界中的每个单元,我们在所有可能的方向上扩展,并且如果它们还没有被探索或者如果我们发现了具有较小移动量的路径,则将这些新单元添加到我们的边界中(距离等于我们的旧距离+ 1)。一旦我们计算了两个玩家到所有单元的距离,我们就可以很容易地计算出两个玩家可以首先到达的牌的数量:
就是这样!就这么简单。简而言之,我们检索所有可能合法行动的列表,然后迭代这些合法行动并计算每个行动的得分。分数是基于我们在移动后可以从新的位置首先到达的牌的数量,以及我们的对手可以首先到达的牌的数量。还有一些额外的细节,例如,如果我们离对手太近,无法避免正面碰撞,则从分数中减去一个惩罚项,以及平局情况下的处理(平局的打破基于填满棋盘的剩余合法移动的数量以及到中间的距离,因为这在游戏开始时很重要)。
2.4 可能的改进和其他方向
如前所述,今年只花了有限的时间写我的经纪人。因此,许多可能的改进是开放的。最重要的列举如下:
- 启发式函数的适应可以导致显著的收益。根据谷歌 Tron 人工智能挑战赛的报道,这导致作者赢得了比赛。在他的博客文章中,提供了一个很好的游戏状态示例,其中用于我的代理的启发式函数将分配一个负的分数,而我们(再次是红色的)实际上是赢的一方:

According to our heuristic, red has much less tiles he can reach first than blue. But no matter what move blue makes now, red can easily win the game since it is impossible for blue to fill up all his tiles.
- 我们可以为每一步可能的棋计算分数,而不是为每一步可能的棋计算分数,从而预测不止一步棋。为了解决这个问题,我们通常使用诸如阿尔法-贝塔剪枝这样的技术,但是由于两个玩家同时移动,所以需要做一些额外的考虑。一个简单的方法是首先为你的对手检索所有合法的移动,然后迭代你所有的合法移动(改变游戏状态),然后递归地调用你的对手,传递这些移动。这确保了两个玩家都可以计算他们的合法移动,在递归过程中使用相同的游戏状态。
- 使用蒙特卡罗模拟,而不是使用启发式函数,计算每个可能的移动(或移动序列)的分数。在这里,我们将模拟从某个游戏状态开始的大量游戏,其中每个代理人将进行随机但合法的移动。我们从这些模拟中赢得的游戏分数可以很好地表明某个游戏状态的实力。当然,需要注意的是,出招的最大时间只有一秒。我没有测试一个人在一秒钟内可以做多少次模拟。
- 进化神经网络为你玩游戏,是一个非常通用的策略,不需要游戏本身的知识。为此编写一个框架(或者配置一个已经存在的框架)将需要相当多的工作,但是一旦编写好了(或者掌握了现有框架的窍门),它就可以很容易地适用于其他游戏。我发现很多单人贪吃蛇游戏的例子(比如这里的这里的和这里的)但是连续贪吃蛇或者 tron 的例子非常少(比如这里的这里的)。
- 阅读其他顶级竞争对手的评论,并结合所有人最重要的见解来创建一个超级机器人。
3.顶级竞争对手的报道
以下是一些最终排名高于我的代理的学生的答案:
3.1。Michiel Platteau(决赛排行榜第一,附加赛第二)
这个机器人是它所有前身的产物。每次我做了很多元函数,而不是重新编写新代码。很多更小的功能总是可以回收到下一代。这些功能包括确定移动是否合法,计算可用单元的数量以及到这些单元的距离。但是将所有这些功能结合起来会变得相当复杂。
代码首先计算对手是否和他在同一个领域,如果他不在,他用最大数量的可用单元进行最左边的移动(floodfill)。如果他们在同一个领域,这都是为了在未来拥有最好的防洪堤。它从去中心(6,6)开始。如果蛇从边界开始,他尽可能走得宽些,试图欺骗对手,否则他会走最中间的路线,试图把场地分成两半。比赛场地的中央是一个非常重要的位置。我为这个动作做了一个特殊的函数。他观察哪些位置可以给他优势而不给对手优势。如果他没有找到一个这样的位置,他就向中间移动,导致许多可能的选择。
一旦机器人完成了对中心的争夺,我已经定义了一个函数来模拟如果我的蛇在每个可能的方向上直线前进的情况。它分析我的机器人是否可以从那里利用优势(更大的洪水),以及到那个地点的距离是否更短。它分析了“成功”、“可能平局”或“成功但距离更远”的情况。对于我能做的移动,他也像对对手那样运行那个功能,并且不做可能导致对对手有利的移动。这可能需要一段时间,所以它在 0.7 秒后停止这样做,它只是假设对手不会有优势。如果没有成功的移动是可能的,他试着尽可能靠近中心和敌人。
3.2. Kristiaan Bogaerts (决赛排行榜第 2 名,附加赛第 3 名)
在每一回合开始时,代理根据它收到的数据生成几个变量,其中一些是长度和宽度等于棋盘长度和宽度的 2D 数组,其他的是单元素整数或布尔。这些变量作为输入用于最终决定邻近代理的哪个六边形是最适合下一个去的,并且因此代理应该如何旋转以到达那个六边形,这是输出。
代理生成的前述变量包括:
*一个 2D 阵列,其中对应于一个六边形的每个元素表示未被两个代理之一或其轨迹占据的相邻六边形的数量
- 2D 数组,其中对应于一个六边形的每个元素指的是从该六边形到棋盘边缘的最短可能距离(以六边形表示)
*一个布尔值,表示两个代理是否仍能相互联系
计算完这些变量后,代理根据单元素变量的值为 2D 数组分配权重。2D 阵列被乘以它们各自的权重,随后被加在一起以构建最终的 2D 阵列。在这个最终数组中对应于棋盘上的六边形的每个元素都被分配了一个值,如果代理通过移动到该六边形估计赢得游戏的机会相对较高,则该值相对较高,如果代理估计的机会相对较低,则该值相对较低。最后,代理将检查其位置周围的每个六边形,寻找在最终数组中具有最高对应值的六边形,并将输出到达该六边形所需的旋转。
3.3.马克西姆·德·克勒克( LinkedIn , GitHub )(最终排行榜第三,附加赛第一)
最终代理有两个主要版本,v8 和 v10,其中 v10 的策略几乎与 v8 完全相同,只是它的速度更快,因为它用图形表示棋盘(我将在后面解释)。
两个代理都有一大组实用函数,允许更快地编写代码,因为这些函数可以在版本之间复制,因为它们的实现保持不变(例如,位置 x 可以播放吗?代理从 x 位置可以到达多少个单元格?位置 x 和 y 之间的距离是多少?集合 s 中离位置 x 最近的位置是什么?).
代码的其余部分由算法组成,以确定最佳行动。这些算法中的大多数过滤可玩的棋步,并将它们传递给另一个算法来打破平局。第一种算法确定我们是否必须在两个或更多区域之间做出决定,并且只传递导致更大区域的移动。然后代理检查我们是否能到达对手,如果不可能,我们可以用填充算法填充剩余的区域。
在所有其他情况下,去棋盘的中心几乎总是最佳的。如果代理将要走到棋盘的中心,它首先检查对手是否也能到达中心。如果可以,那么代理人可以通过稍微向左或向右移动来切断对手,但前提是开始位置在棋盘的边缘,并且切断的区域比对手的区域大。
如果上述特殊情况都没有发生,代理就退回到它的通用洪泛算法,该算法使移动产生它能首先到达的最多的单元。如果对手能和代理同时到达一个单元格,则算作半个单元格。
如果泛洪在几个移动中得到相同的分数,它会将这些移动传递给多光线投射算法,这是一种相当古老的算法(v6 ),它从两个玩家的位置投射光线,并确定哪个移动会产生最大的区域。
v8 和 v10 最大的区别在于填充算法。v8 只从玩家的位置投射单条光线来确定最大可能的区域,而 v10 从网格中组成一个图形。这是通过将网格中的每个位置映射到一个从 0 到 126 的数字来实现的。因为光线投射仍然有用,所以我必须为图中的节点定义一个方向,所以我定义了一个 127×5 的网格,其中 get _ next _ nodes()[node][direction % 6]将为我提供代理在该方向上可以到达的节点。然后,一个相当复杂的转换函数会将网格转换成邻接表。代理现在可以确定图形中的关节点,而不是光线投射。代理现在可以通过在接下来的两个移动中产生最少关节点的移动来填充该区域。这导致任何区域的完美填充。
重要: Maxim 在他的 GitHub 上发布了代码。请务必查看比赛的获胜方案。你甚至可以模拟我和他经纪人之间的游戏!
结束语
这篇博文中讨论的所有代理代码都可以在 GitHub 上获得。我尽了最大努力清理和优化代码,但它肯定还不够完美。因此,我们非常欢迎您提交拉动请求或开放问题!
此外,和往常一样,如果这篇博文中有什么不清楚或者需要进一步澄清的地方,请随时发表评论,或者联系我!如果你对明年的游戏有任何酷的建议,请随时留下评论!
哇,你已经到达这篇博文的结尾了!向你致敬。第三届 AI 大赛明年见;),
张卫
一个简单的 CNN:多图像分类器
利用张量流和迁移学习,用卷积神经网络轻松制作一个有标签的图像分类器

计算机视觉和神经网络是机器学习技术的新热点。随着神经网络的进步和将图像读取为像素密度数字的能力,许多公司都依赖这种技术来获取更多数据。例如,speed camera 使用计算机视觉来拍摄超速行驶的汽车的牌照,并将牌照号码与已知的数据库进行匹配,以发送罚单。虽然这与目标字符识别比图像分类更相关,但两者都使用计算机视觉和神经网络作为工作基础。
图像分类的一个更现实的例子是脸书标记算法。当你上传一个有人物的相册,并在脸书给他们加标签时,标签算法会分解人物照片的像素位置,并将其存储在数据库中。因为每张图片都有自己独特的像素位置,所以算法可以根据数据库中以前的图片相对容易地识别出谁是谁。当然,该算法可能会不时出错,但你纠正得越多,它就越能识别你的朋友,并在你上传时自动为你标记他们。然而,脸书标签算法是建立在人工智能的基础上的。这意味着标记算法能够基于我们的输入进行学习,并在未来进行更好的分类。
我们不会关注人工智能方面,而是关注制作图像分类算法的最简单方法。我们的模式和脸书的模式之间的唯一区别是,我们不能从它的错误中吸取教训,除非我们修正它。但是,对于一个简单的神经网络项目来说,这就足够了。
由于使用人的照片是不道德的,我们将使用动物来创建我们的模型。我的朋友文森特和我已经就此做了一个项目,所以我会以此为例继续下去。GitHub 链接在最后。
第一步是收集数据。在我看来,这将是该项目的最困难和最烦人的方面。请记住,数据必须有标签。谢天谢地,Kaggle 已经标记了我们可以轻松下载的图片。我们使用的数据集可以在这里找到: animal-10 dataset 。如果数据集未被标注,这可能会非常耗时,因为您必须为每类影像手动创建新的标注。另一种方法是创建新的标签,只将 100 张图片移动到它们适当的标签中,并创建一个类似我们将使用的分类器,并让该机器对图像进行分类。这将导致分类错误,因此您可能希望在每次运行后手动检查,这是耗时的地方。
现在,我们已经将数据集安全地存储在我们的计算机或云中,让我们确保我们有一个训练数据集、一个验证数据集和一个测试数据集。训练数据集将包含全部标记数据的 85–90%。这些数据将被用来训练我们的机器了解我们拥有的不同类型的图像。验证数据集将包含总标记数据的 5-10%。这将测试我们的机器对已知标签数据的表现。测试数据集将包含未标记格式的其余数据。这些测试数据将被用来测试我们的机器对从未见过的数据进行分类的能力。测试数据也可以只包含你从谷歌下载的图片,只要它对你分类的主题有意义。
我们先导入所有需要的库:
import pandas as pd
import numpy as np
import itertools
import keras
from sklearn import metrics
from sklearn.metrics import confusion_matrix
from keras.preprocessing.image import ImageDataGenerator, img_to_array, load_img
from keras.models import Sequential
from keras import optimizers
from keras.preprocessing import image
from keras.layers import Dropout, Flatten, Dense
from keras import applications
from keras.utils.np_utils import to_categorical
import matplotlib.pyplot as plt
import matplotlib.image as mpimg
%matplotlib inline
import math
import datetime
import time
定义尺寸和定位图像:
#Default dimensions we found online
img_width, img_height = 224, 224
#Create a bottleneck file
top_model_weights_path = ‘bottleneck_fc_model.h5’# loading up our datasets
train_data_dir = ‘data/train’
validation_data_dir = ‘data/validation’
test_data_dir = ‘data/test’
# number of epochs to train top model
epochs = 7 #this has been changed after multiple model run
# batch size used by flow_from_directory and predict_generator
batch_size = 50
在这一步中,我们定义图像的尺寸。根据你的图像大小,你可以改变它,但我们发现 224,224 效果最好。然后我们创建了一个瓶颈文件系统。这将用于转换所有的图像像素到他们的数字(numpy 数组)对应,并存储在我们的存储系统中。一旦我们运行这个,它将需要半个小时到几个小时,这取决于分类的数量和每个分类有多少图像。然后我们简单地告诉我们的程序每个图像在我们的存储器中的位置,这样机器就知道哪里是什么了。最后,我们为我们的机器定义时期和批量大小。对于神经网络来说,这是关键的一步。我们发现,这组配对对于我们的机器学习模型来说是最佳的,但同样,这取决于需要调整的图像数量。
导入迁移学习模型 VGG16:
#Loading vgc16 model
**vgg16 = applications.VGG16(include_top=False, weights=’imagenet’)****datagen = ImageDataGenerator(rescale=1\. / 255)**
#needed to create the bottleneck .npy files
这引入了卷积神经网络的迁移学习方面。迁移学习很方便,因为它带有预制的神经网络和其他必要的组件,否则我们将不得不创建这些组件。迁移学习模式有很多。我特别喜欢 VGG16,因为它只使用了 11 个卷积层,非常容易使用。但是,如果您正在处理较大的图像文件,最好使用更多的层,所以我推荐 resnet50,它包含 50 个卷积层。
对于我们的图像分类器,我们只处理了 6 个分类,因此对这些图像使用迁移学习并没有花费太长时间,但是请记住,图像和分类越多,下一步将花费越长的时间。但是值得庆幸的是,由于您只需要将图像像素转换为数字一次,因此您只需对每个训练、验证和测试执行一次下一步操作——除非您删除或损坏了瓶颈文件。
使用 VGG16 创建权重和特征:
#__this can take an hour and half to run so only run it once.
#once the npy files have been created, no need to run again. Convert this cell to a code cell to run.__start = datetime.datetime.now()
generator = datagen.flow_from_directory(
train_data_dir,
target_size=(img_width, img_height),
batch_size=batch_size,
class_mode=None,
shuffle=False)
nb_train_samples = len(generator.filenames)
num_classes = len(generator.class_indices)
predict_size_train = int(math.ceil(nb_train_samples / batch_size))
bottleneck_features_train = vgg16.predict_generator(generator, predict_size_train)
np.save(‘bottleneck_features_train.npy’, bottleneck_features_train)
end= datetime.datetime.now()
elapsed= end-start
print (‘Time: ‘, elapsed)
因为我们正在制作一个简单的图像分类器,所以没有必要改变默认设置。对于我们在上面创建的培训、验证和测试目录,只需按照上面的步骤操作即可。但是,您可以添加不同的功能,如图像旋转、变换、反射和扭曲。
一旦文件被转换并保存到瓶颈文件,我们加载它们并为我们的卷积神经网络做准备。这也是确保所有数据都已经加载到瓶颈文件中的好方法。记住对验证和测试集也重复这个步骤。
为训练数据创建瓶颈文件。(验证和测试步骤相同):
#training data
generator_top = datagen.flow_from_directory(
train_data_dir,
target_size=(img_width, img_height),
batch_size=batch_size,
class_mode=’categorical’,
shuffle=False)
nb_train_samples = len(generator_top.filenames)
num_classes = len(generator_top.class_indices)
# load the bottleneck features saved earlier
train_data = np.load(‘bottleneck_features_train.npy’)
# get the class labels for the training data, in the original order
train_labels = generator_top.classes
# convert the training labels to categorical vectors
train_labels = to_categorical(train_labels, num_classes=num_classes)
创建我们的卷积神经网络代码:
#This is the best model we found. For additional models, check out I_notebook.ipynbstart = datetime.datetime.now()
**model = Sequential()**
model.add(Flatten(input_shape=train_data.shape[1:]))
model.add(Dense(100, activation=keras.layers.LeakyReLU(alpha=0.3)))
model.add(Dropout(0.5))
model.add(Dense(50, activation=keras.layers.LeakyReLU(alpha=0.3)))
model.add(Dropout(0.3))
model.add(Dense(num_classes, **activation=’softmax**’))model.compile(**loss=’categorical_crossentropy’**,
optimizer=optimizers.RMSprop(lr=1e-4),
metrics=[‘acc’])history = **model.fit**(train_data, train_labels,
epochs=7,
batch_size=batch_size,
validation_data=(validation_data, validation_labels))model.save_weights(top_model_weights_path)(eval_loss, eval_accuracy) = model.evaluate(
validation_data, validation_labels, batch_size=batch_size, verbose=1)print(“[INFO] accuracy: {:.2f}%”.format(eval_accuracy * 100))
print(“[INFO] Loss: {}”.format(eval_loss))
end= datetime.datetime.now()
elapsed= end-start
print (‘Time: ‘, elapsed)
现在我们创建我们的模型。第一步是用 Sequential()初始化模型。之后,我们平坦的数据,并添加我们额外的 3(或更多)隐藏层。这一步是完全可定制的你想要的。我们用不同的退出,隐藏层和激活制作了几个不同的模型。但是由于这是一个带标签的范畴分类,最终的激活必须总是 softmax。对于 loss 来说,最好是分类交叉相关的,但是 model.compile 中的其他内容都可以更改。然后,在我们创建并编译了我们的模型之后,我们用我们前面提到的规范使我们的训练和验证数据适合它。最后,我们创建一个评估步骤,来检查我们的模型训练集相对于验证集的准确性。

这是我们的模型,现在训练数据,然后验证它。一个时期是模型在我们整个数据集上训练的次数。批量可以解释为少量服用,训练后再服用一些。在进入下一个时段之前,每个时段必须完成所有批次。用太少的历元训练会导致数据拟合不足,而用太多的历元训练会导致数据拟合过度。你也希望损失尽可能低。下面的图片将显示我们的数据集的准确性和损失
代码为可视化的精度和损失:
#Graphing our training and validation
acc = history.history[‘acc’]
val_acc = history.history[‘val_acc’]
loss = history.history[‘loss’]
val_loss = history.history[‘val_loss’]
epochs = range(len(acc))
plt.plot(epochs, acc, ‘r’, label=’Training acc’)
plt.plot(epochs, val_acc, ‘b’, label=’Validation acc’)
plt.title(‘Training and validation accuracy’)
plt.ylabel(‘accuracy’)
plt.xlabel(‘epoch’)
plt.legend()
plt.figure()
plt.plot(epochs, loss, ‘r’, label=’Training loss’)
plt.plot(epochs, val_loss, ‘b’, label=’Validation loss’)
plt.title(‘Training and validation loss’)
plt.ylabel(‘loss’)
plt.xlabel(‘epoch’)
plt.legend()
plt.show()

Even though according to this graph, it showed that epoch 3 was the best as that was the point of intersection between accuracy and loss, when we ran the model on 3 epoch, it underperformed. So this graph is not an absolute indicator of how many epoch to run on your model.
下图显示了我们刚刚制造的机器对未知数据的预测能力。注意,它说它在 test_data 上进行测试。准确性是第二个数字。然而,这不是检查我们的机器性能的唯一方法

有两种很好的方法可以检验你的机器的预测和分类能力。其中一个是分类度量,另一个是混淆矩阵。

为了使用分类度量,我们必须将测试数据转换成不同的 numpy 格式,numpy 数组,以便阅读。这就是第一行代码所做的一切。第二个单元块接收转换后的代码,并通过内置的分类指标运行它,从而给出一个简洁的结果。请注意,除非您在这里手动标记您的类别,否则您将得到 0–5 作为类别,而不是动物。这里重要的因素是精确度和 f1 分数。分数越高,你的模型越好。这里有一个在 medium 上的很棒的博客,解释了这些都是什么。
现在来做一个混淆矩阵。网上有很多关于如何制作大混乱矩阵的教程。我们的是我们在网上找到的一些的变体
#Since our data is in dummy format we put the numpy array into a dataframe and call idxmax axis=1 to return the column
# label of the maximum value thus creating a categorical variable
#Basically, flipping a dummy variable back to it’s categorical variable**categorical_test_labels = pd.DataFrame(test_labels).idxmax(axis=1)
categorical_preds = pd.DataFrame(preds).idxmax(axis=1)**confusion_matrix= confusion_matrix(categorical_test_labels, categorical_preds) #To get better visual of the confusion matrix:def plot_confusion_matrix(cm, classes,
normalize=False,
title=’Confusion matrix’,
cmap=plt.cm.Blues):
#Add Normalization Option
‘’’prints pretty confusion metric with normalization option ‘’’
**if normalize:
cm = cm.astype(‘float’) / cm.sum(axis=1)[:, np.newaxis]
print(“Normalized confusion matrix”)
else:
print(‘Confusion matrix, without normalization’)**
# print(cm)
plt.imshow(cm, interpolation=’nearest’, cmap=cmap)
plt.title(title)
plt.colorbar()
tick_marks = np.arange(len(classes))
plt.xticks(tick_marks, classes, rotation=45)
plt.yticks(tick_marks, classes)
fmt = ‘.2f’ if normalize else ‘d’
thresh = cm.max() / 2.
for i, j in itertools.product(range(cm.shape[0]), range(cm.shape[1])):
plt.text(j, i, format(cm[i, j], fmt), horizontalalignment=”center”, color=”white” if cm[i, j] > thresh else “black”)
plt.tight_layout()
plt.ylabel(‘True label’)
plt.xlabel(‘Predicted label’)
我们之前创建的 numpy 数组放在 dataframe 中。混淆矩阵最适合数据帧。具有多个迭代代码的第三单元块纯粹用于彩色视觉效果。唯一重要的代码功能是“if normalize”行,因为它标准化了数据。

正如我们在标准化数据中看到的,我们的机器非常擅长对动物进行分类。鸡被误归类为蝴蝶,很可能是因为蝴蝶身上有许多不同类型的图案。此外,蝴蝶也可能因为同样的原因被误归类为蜘蛛。大象和马都是相当大的动物,所以它们的像素分布可能相似。
最后一个阶段是对图像进行测试。下面的单元块将实现这一点:
def read_image(file_path):
print(“[INFO] loading and preprocessing image…”)
image = load_img(file_path, target_size=(224, 224))
image = img_to_array(image)
image = np.expand_dims(image, axis=0)
image /= 255\.
return imagedef test_single_image(path):
animals = [‘butterflies’, ‘chickens’, ‘elephants’, ‘horses’, ‘spiders’, ‘squirells’]
images = read_image(path)
time.sleep(.5)
bt_prediction = vgg16.predict(images)
preds = model.predict_proba(bt_prediction)
for idx, animal, x in zip(range(0,6), animals , preds[0]):
print(“ID: {}, Label: {} {}%”.format(idx, animal, round(x*100,2) ))
print(‘Final Decision:’)
time.sleep(.5)
for x in range(3):
print(‘.’*(x+1))
time.sleep(.2)
class_predicted = model.predict_classes(bt_prediction)
class_dictionary = generator_top.class_indices
inv_map = {v: k for k, v in class_dictionary.items()}
print(“ID: {}, Label: {}”.format(class_predicted[0], inv_map[class_predicted[0]]))
return load_img(path)path = ‘data/test/yourpicturename’test_single_image(path)
第一个 def 函数是让我们的机器知道它必须加载图像,改变大小并将其转换为数组。第二定义函数使用迁移学习的预测模型和迭代函数来帮助正确预测图像。路径是我们定义图像位置的地方,最后 test_single_image 单元块将打印出最终结果,这取决于第二个单元块的预测。对于这一部分,我不会张贴一张图片,以便您可以找到自己的结果。然而,GitHub 链接就在下面,所以请随意下载我们的代码,看看它与您的代码相比如何。
基于 CNN 的不同类型动物图像分类。-动物图像分类
github.com](https://github.com/imamun93/animal-image-classifications) [## 动物-10
取自谷歌图片的 10 个不同类别的动物图片
www.kaggle.com](https://www.kaggle.com/alessiocorrado99/animals10) [## 准确度、精密度、召回率还是 F1?
当我与希望将数据科学应用到其流程中的组织交谈时,他们经常会问…
towardsdatascience.com](/accuracy-precision-recall-or-f1-331fb37c5cb9)
单词袋模型的简单解释
快速、简单地介绍单词袋模型以及如何用 Python 实现它。

Photo by Patrick Tomasso on Unsplash
单词袋 (BOW)模型是一种通过计算每个单词出现的次数将任意文本转换成固定长度向量的表示方法。这个过程通常被称为矢量化。
我们用一个例子来理解这个。假设我们想要向量化以下内容:
- 猫坐下了
- 猫坐在帽子里
- 戴帽子的猫
我们将每一个都称为文本文档。
第一步:确定词汇
我们首先定义我们的词汇表,它是在我们的文档集中找到的所有单词的集合。在上述三个文档中唯一找到的单词是:the、cat、sat、in、the、hat和with。
第二步:计数
为了对我们的文档进行矢量化,我们所要做的就是计算每个单词出现的次数:

现在每个文档都有长度为 6 的向量了!
- 猫坐着 :
[1, 1, 1, 0, 0, 0] - 猫坐在帽子里
- 戴帽子的猫 :
[2, 1, 0, 0, 1, 1]
请注意,当我们使用 BOW 时,我们丢失了上下文信息,例如,单词在文档中出现的位置。这就像一个字面上的单词包:它只告诉你哪些单词出现在文档中,而不是它们出现在的什么地方。
在 Python 中实现 BOW
既然您已经知道了 BOW 是什么,我猜您可能需要实现它。下面是我的首选方法,它使用了 Keras 的 Tokenizer 类:
运行该代码会给我们带来:
Vocabulary: ['the', 'cat', 'sat', 'hat', 'in', 'with']
[[0\. 1\. 1\. 1\. 0\. 0\. 0.]
[0\. 2\. 1\. 1\. 1\. 1\. 0.]
[0\. 2\. 1\. 0\. 1\. 0\. 1.]]
注意,这里的向量长度是 7,而不是 6,因为在开头有额外的0元素。这是一个无关紧要的细节——Keras 储量指数0并且从来不把它分配给任何单词。
BOW 有什么用?
尽管是一个相对基本的模型,BOW 经常被用于自然语言处理任务,如文本分类。它的优势在于它的简单性:它的计算成本很低,有时当定位或上下文信息不相关时,越简单越好。
我已经写了一篇使用 BOW 进行亵渎检测的博文——如果你对 BOW 的实际应用感到好奇,就来看看吧!
最初发表于T5【https://victorzhou.com】。
适用于 Github 初学者和其他人的简单 Git 工作流程

成为 Git 大师
当我在我参加的数据分析编码营开始我的第一个小组项目时,我们必须挑选一个“Git 大师”为五个使用 git 和 Github 的没有经验的人协调工作流的想法有点令人畏惧。决定的时候到了,因为我在新兵训练营开始前有一点点使用它的经验,我被任命为团队的“g it 大师”这是我创建的备忘单,用于帮助我的队友将他们的代码分支并合并到 Github 存储库中。如果你已经熟悉 Git ,可以在页面底部找到命令行指令的原始文本备忘单。
如果你正在考虑进入数据科学领域,请查看我在该领域工作 90 天后的感想:
我不是一个“数字迷”这是我在数据科学领域头 90 天的反思
towardsdatascience.com](/why-did-i-ever-get-into-data-science-aa69d3c74d19)
对 Git 和 Github 完全陌生?
GitHub 是一个 Git 存储库托管服务的用户界面。 Git 是一个可通过命令行访问的分布式版本控制系统。Git 是根据第二版 GNU 通用公共许可证的条款发布的免费开源软件。
Git 非常棒,因为它有助于跟踪代码的变化,并允许在各种规模的项目上进行协作。使用 Github,我可以与全世界分享我所有的编码项目。Github 有许多独特的特性,可以增强 git 体验,简化协作编码。任何人都可以打开我的用户页面,派生并克隆一个回购协议,然后玩代码。我不是 Git 或 Github 专家,但这是一个简短的指南,可以帮助你在 Github 上开始使用 Git:
创建一个 Github 帐户,如果你愿意的话,下载并安装 Git。这个例子是使用 Windows 10 机器完成的:
在 Github 上创建新的回购:
点击仓库选项卡上的绿色新建按钮。

将显示编辑器。
- 输入存储库名称。
- 选中复选框以使用自述文件初始化此存储库。
- 单击创建存储库。您的新回购显示。
- 单击绿色的克隆或下载按钮。
- 将地址复制到剪贴板。

- 复制完存储库地址后,切换到您的桌面。
- 右键单击并选择 Git Bash Here,在桌面上打开一个终端。终端将显示。
- 类型 git 克隆
。 - 一个文件夹将出现在您的桌面上,它是克隆的存储库的副本。


通过克隆回购,您创建了它的本地副本。因为我们在桌面上使用了 Git Bash,所以副本出现在桌面上。现在我们有了本地 repo,我们可以在本地 repo 上添加文件和更新代码,然后使用备忘单中的命令将它推送到 Github!
将文件添加到您的存储库中
将文件添加到 repo 并推送到 Github 很容易。
- 打开将存储库克隆到桌面时创建的文件夹。
- 创建新的文本文件。
- 切换到终端。确保您在正确的目录中!
- 使用以下命令将文件推送到 Github,这样就可以将它们添加到存储库的主分支中:
Add the files to the branch:
$ git add .
Commit the files:
$ git commit -m "comment"
Add branch and files to the Remote Repo:
$ git push -u origin main

注意新文件出现在 Github 上!

更多教程!
这个演练很简短,但是对于任何需要学习更多关于在平台上管理和共享代码的人来说,有很多好的 Git 和 Github 指南和教程。
如果您正在寻找编码项目,请查看我的一些教程:
[## 简单的情感分析为 NLP 初学者和其他人使用 VADER 和 TextBlob
无需训练模型,只需几行代码就能从 Panda 数据帧的文本中提取情感指标!
medium.com](https://medium.com/swlh/simple-sentiment-analysis-for-nlp-beginners-and-everyone-else-using-vader-and-textblob-728da3dbe33d) [## Python 中的仪表盘,适用于初学者和使用 Dash 的其他人
使用 Python 中的 Dash 初学者教程构建一个基本的和高级的仪表板
medium.com](https://medium.com/swlh/dashboards-in-python-for-beginners-and-everyone-else-using-dash-f0a045a86644)
工作流程备忘单
Common console commands:
cd - change directory
mkdir - make directory
ls - view the files/folders in directory
NOTE: Exit VIM if needed ctrl + c then type :qa! and push enter
NOTE: If file is not in local repo, manually move the file into
the correct folder (outside of console)
--------------------------------------------
Managing your Local Repo
--------------------------------------------
NOTE: If you need to hard reset your local repo to match
the remote master use the following commands:
$ git fetch origin
$ git reset --hard origin/master
Undo the act of committing, leaving everything else intact:
$ git reset --soft HEAD^:
Undo the act of committing and everything you'd staged,
but leave the work tree (your files intact):
$ git reset HEAD^
Completely undo it, throwing away all uncommitted changes,
resetting everything to the previous commit:
$ git reset --hard HEAD^
--------------------------------------------
BEGIN WORKFLOW
--------------------------------------------
Clone the Repo to local machine:
$ git clone https://github.com/user_name/repo_name.git
Make sure the local master is up-to-date:
$ git pull origin main
Create new branch:
$ git banch branch_name
Move to branch:
$ git checkout branch_name
Navigate file structure as needed:
$ ls
$ cd folder_name
Add the files to the branch:
$ git add .
Verify file:
$ git status
Commit the files:
$ git commit -m "comment"
Add branch and files to the Remote Repo:
$ git push -u origin branch_name
Go to the github website to manage pull request and merge.
Switch back to local master so you can delete the local branch:
$ git checkout main
Delete local branch:
$ git branch -d branch_name
OR
$ git branch -D branch_name
If you don't want to go to the website, you can merge your branch
to the master locally and push the new master to the remote repo:
Switch back to master branch:
$ git checkout main
Merge the branch with the local master:
$ git merge branch_name -m "comment"
Push the local master to the remote master:
$ git push origin main
Delete local branch:
$ git branch -d branch_name
OR
$ git branch -D branch_name
我的 Github
如果你是 Github 的新手,需要一些 repos 来玩,请点击这里查看我的 Github:
对游戏、金融、数据分析、技术写作和牛肉干感兴趣。阻止或报告 9 月 10 月 11 月 12 月 1 月…
github.com](https://github.com/bendgame/)
谢谢大家!
- 如果你喜欢这个, 跟我上 Medium 了解更多
- 通过订阅 获得完全访问权限并帮助支持我的内容
- 我们连线上LinkedIn
- 用 Python 分析数据?查看我的 网站
在 Google Cloud 上部署垃圾邮件检测器的简单指南
谷歌云平台,Flask,分类合一

Photo by Samuel Zeller on Unsplash
你好👋!嗯,有很多关于建立各种用途的机器学习模型的指南,我最近看到了一个关于建立垃圾邮件检测器然后使用 Flask 部署它的指南。通过这一点,我决定通过部署到谷歌云平台上更进一步!当然,你也可以使用 Heroku,AWS 等,但这是另一天的另一个主题,我现在只关注 GCP。
项目的简要背景
这是一种机器学习模型,通过对现有的标有“垃圾”或“火腿”的短信集合进行训练,对垃圾短信进行分类。垃圾邮件检测器采用 scikit-learn 的多项式朴素贝叶斯分类器,该分类器基于朴素贝叶斯算法,用于多项式分布数据:
朴素贝叶斯方法是一组基于应用贝叶斯定理的监督学习算法,其“朴素”假设是在给定类变量的值的情况下,每对要素之间的条件独立性。
与更复杂的方法相比,朴素贝叶斯学习器和分类器可以非常快。类别条件特征分布的分离意味着每个分布可以被独立地估计为一维分布。这反过来又有助于缓解维数灾难带来的问题。

Flask Logo
同时,Flask 作为 web 框架,通过前端接收用户的输入(HTTP 请求)并实现其预测功能。诞生于 2010 年的 Flask 以大多数标准来看都是一个小框架,小到可以被称为“微框架”。Flask 提高了其源代码的可读性和易理解性。Flask 是一个用 Python 编写的轻量级 Web 框架,它已经成为初创企业最广泛使用的 Python web 框架之一,也是大多数企业快速简单解决方案的完美工具。
Flask 的目标是保持框架的核心小但高度可扩展,从而非常容易和灵活地编写应用程序或扩展,同时使开发人员能够为他们的应用程序选择自己的配置

在 Google 云平台上部署
我们将在标准环境中使用谷歌应用引擎。它允许我们“在完全托管的无服务器平台上构建高度可扩展的应用程序”。在继续之前,我将提出一些必要条件或假设:
- 我假设您已经安装了 Flask 和虚拟环境中涉及的库(如果没有,将在后面显示)。
- 您有一个可以访问谷歌云平台控制台的谷歌账户,并在上面创建了一个新项目。
确保为您的项目启用计费。为了将应用程序部署到 App Engine,需要将计费帐户链接到您的项目
3.已安装 Google Cloud SDK ,按照其说明进行安装。
4.您已经成功地在本地测试了您的应用程序。

Project Folder Structure
大致来说,您的主文件夹将具有这种结构,请注意“nlp”是我的虚拟环境,我们将在下面创建 app.yaml、appengine_config.py 和 requirements.txt:
app.yaml
示例 app.yaml 指定了应用程序应该运行的运行时,对于这个项目,它将在 Python 3.7 上运行。对于 Python 2.7,可以参考下面的代码:
Python 2.7 app.yaml
app_engine_config.py
requirements.txt
如果您没有将必要的库安装到虚拟环境中,您可以使用下面的代码。应该首先激活环境,并使用终端、命令提示符等来访问它,以便根据需求安装新的依赖项。
pip install -t lib -r requirements.txt
-t lib: 此标志将库复制到 lib 文件夹中,该文件夹在部署期间上传到 App Engine。
-r requirements.txt: pip 安装 requirements.txt 中的所有内容。
部署
在我们开始之前,最好(可选)更新已安装的云 SDK:
gcloud components update
然后,在根文件夹,我们将使用您的 cmd/终端部署它,代码如下:
gcloud app deploy --project [ID of Project]
或者你也可以在没有项目 ID 的情况下完成!

根据您的项目,选择最合适的区域并等待几分钟,它将为您提供一个链接,任何人都可以访问该链接来查看/使用您的 web 应用程序!

或者只使用下面的代码:
gcloud app browse --project=
#the link usually is "projectid".appspot.com
结论
瞧啊。GCP 使部署 web 应用程序的过程变得更快、更容易。我希望我可以尝试在不久的将来或其他项目的其他选择。如果有任何问题,请随时联系我!我的网站可以在这里找到:spamdetector.appspot.com
参考
- 存储库:https://github.com/georgeblu1/Spam-Detector-Web-App
- 用 Python 开发 NLP 模型&用 Flask 逐步部署:https://towardsdatascience . com/develop-a-NLP-Model-in-Python-Deploy-It-with-Flask-Step-Step-744 F3 BDD 7776
- 烧瓶框架食谱
- 砂箱网开发
- Python 机器学习
面向数据科学家的链表简单介绍

Image by WILLGARD from Pixabay
算法面试
或者说,什么是链表,为什么我需要了解它们?
算法和数据结构是数据科学不可或缺的一部分。虽然我们大多数数据科学家在学习时没有上过适当的算法课程,但它们仍然很重要。
许多公司在招聘数据科学家的面试过程中会询问数据结构和算法。
现在,许多人在这里问的问题是,问一个数据科学家这样的问题有什么用。 我喜欢这样描述,一个数据结构问题可以被认为是一个编码能力测试。
我们都在人生的不同阶段进行过能力倾向测试,虽然它们不是判断一个人的完美代理,但几乎没有什么是真的。那么,为什么没有一个标准的算法测试来判断人的编码能力。
但我们不要自欺欺人,他们需要像你的数据科学面试一样的热情,因此,你可能需要花一些时间来研究算法和数据结构问题。
这篇文章是关于快速跟踪这项研究,并以一种容易理解的方式为数据科学家解释链表概念。
什么是链表?
链表只是一个非常简单的数据结构,表示一系列节点。

每个节点只是一个包含值和指向下一个节点的指针的对象。例如,在这里的例子中,我们有一个包含数据 12 并指向下一个节点 99 的节点。然后 99 指向节点 37 等等,直到我们遇到一个空节点。

也有双向链表,其中每个节点包含下一个和前一个节点的地址。
但是我们为什么需要链表呢?

我们都使用过 Python 中的列表。 但是你想过列表数据结构的插入时间吗?
假设我们需要在列表的开头插入一个元素。在 python 列表的开头插入或删除元素需要一个 O(n) 复制操作。
如果我们面临这样的问题,有很多这样的插入,我们需要一个数据结构,实际上在常数 O(1)时间内做插入,怎么办?
有很多你可以想到的链表的实际应用。人们可以使用双向链表来实现一个系统,其中只需要前一个和下一个节点的位置。 例如 chrome 浏览器中的上一页和下一页功能。或者照片编辑器中的上一张和下一张照片。
使用链表的另一个好处是,我们不需要对链表有连续的空间要求,即节点可以驻留在内存中的任何地方,而对于像数组这样的数据结构,节点需要分配一个内存序列。
我们如何在 Python 中创建一个链表?
我们首先定义一个可以用来创建单个节点的类。
class Node:
def __init__(self,val):
self.val = val
self.next = None
然后,我们使用这个类对象创建多个节点,并将它们连接在一起形成一个链表。
head = Node(12)
a = Node(99)
b = Node(37)head.next = a
a.next = b
我们有链表,从head开始。在大多数情况下,我们只保留变量head来定义我们的链表,因为它包含了我们访问整个链表所需的所有信息。
链接列表的常见操作或面试问题
1.插入新节点
在开始,我们说我们可以在一个常数 O(1)时间内在链表的开始插入一个元素。让我们看看我们能做些什么。
def insert(head,val):
new_head = Node(val)
new_head.next = head
return new_head
因此,给定节点的头,我们只需创建一个new_head对象,并将其指针设置为指向链表的前一个头。我们只需创建一个新节点,并更新一个指针。
2。打印/遍历链表
打印链表的元素非常简单。我们只是以迭代的方式遍历链表,直到遇到 None 节点(或者末尾)。
def print(head):
while head:
print(head.val)
head = head.next
3.反转单向链表
这更像是链表上一个非常常见的面试问题。如果给你一个链表,你能在 O(n)时间内反转这个链表吗?
**For Example:
Input:** 1->2->3->4->5->NULL
**Output:** 5->4->3->2->1->NULL
那么我们该如何应对呢?
我们从遍历链表开始,在将指针移动到下一个节点时反转指针方向,直到有下一个节点。
def reverseList(head):
newhead = None
while head:
tmp = head.next
head.next = newhead
newhead = head
head = tmp
return newhead
结论
在这篇帖子里,我谈到了链表及其实现。
链表是数据科学面试中一些最常见问题的基础,很好地理解这些问题可能会帮助你找到理想的工作。
虽然您可以在不学习它们的情况下在数据科学中走得更远,但您可以为了一点乐趣而学习它们,也许是为了提高您的编程技能。
这里有一个小的笔记本给你,我把所有这些小概念都放在里面了。
我把这个问题留给你自己解决— 实现一个函数来检查一个链表是否是回文。
如果你想学习算法和数据结构,也可以看看我在系列的其他帖子。
继续学习
如果你想了解更多关于算法和数据结构的知识,我强烈推荐 UCSanDiego在 Coursera 上的 算法专门化。
谢谢你的阅读。将来我也会写更多初学者友好的帖子。在 媒体 关注我,或者订阅我的 博客 了解他们。一如既往,我欢迎反馈和建设性的批评,可以通过 Twitter @mlwhiz 联系。
此外,一个小小的免责声明——这篇文章中可能会有一些相关资源的附属链接,因为分享知识从来都不是一个坏主意。
K-最近邻算法简介

Photo by h heyerlein on Unsplash
什么是 KNN?
k 最近邻是一种简单的算法,它存储所有可用的案例,并基于相似性度量对新数据或案例进行分类。它主要用于根据相邻数据点的分类方式对其进行分类。
让我们以下面的葡萄酒为例。两种化学成分叫做芦丁和杨梅素。考虑用红葡萄酒和白葡萄酒这两个数据点来测量芦丁和杨梅素的含量。他们已经测试了葡萄酒中芸香素和杨梅黄酮的含量,并确定了它们在图表中的位置。

KNN 中的“k”是一个参数,指的是在多数投票过程中包括的最近邻的数量。
假设,如果我们在数据集中添加一杯新的葡萄酒。我们想知道这种新酒是红的还是白的?

所以,我们需要找出这种情况下的邻居是谁。假设 k = 5,并且新的数据点被来自其五个邻居的多数投票分类,并且新点将被分类为红色,因为五个邻居中有四个是红色的。

KNN 算法中 k 的值应该如何选择?

KNN 算法中的 K’是基于特征相似性的。选择正确的 K 值是一个被称为参数调整的过程,并且对于更好的准确性是重要的。求 k 的值并不容易。

关于“K”取值的几点想法
- 没有一个结构化的方法可以找到“K”的最佳值。我们需要通过反复试验来找出不同的值,并假设训练数据是未知的。
- 选择较小的 K 值可能会产生噪声,并对结果产生较大影响。
3)K 值越大,决策边界越平滑,意味着方差越低,但偏差越大。此外,计算成本很高。
4)选择 K 的另一种方法是通过交叉验证。从训练数据集中选择交叉验证数据集的一种方法。从训练数据集中取出一小部分,称之为验证数据集,然后使用它来评估 K 的不同可能值。这样,我们将使用 K 等于 1,K 等于 2,K 等于 3 来预测验证集中每个实例的标签..然后我们看看什么样的 K 值能让我们在验证集上获得最佳性能,然后我们可以取这个值,并将其用作我们算法的最终设置,这样我们就能最小化验证误差。
5)一般来说,实践中,选择 k 的值是 k = sqrt(N) 其中 N 代表你的训练数据集中的个样本数。
6)尽量保持 k 值为奇数,以避免两类数据之间的混淆
KNN 算法是如何工作的?
在分类设置中,K-最近邻算法本质上归结为在与给定的“看不见的”观察最相似的 K 个实例之间形成多数投票。相似性根据两个数据点之间的距离度量来定义。一种流行的方法是欧几里德距离法

其他方法有曼哈顿、闵可夫斯基和海明距离方法。对于分类变量,必须使用汉明距离。
我们举个小例子。年龄 vs 贷款。

我们需要预测安德鲁的违约状态(是或否)。

计算所有数据点的欧几里德距离。

K=5 时,五个最近邻居中有两个 Default=N,三个 Default=Y。基于 5 分中的 3 分的主要相似性,我们可以说 Andrew 的默认状态是“Y”。
K-NN 也是一个懒惰的学习者,因为它不从训练数据中学习判别函数,而是“记忆”训练数据集。
KNN 的优点
- 易于实施
- 灵活选择功能/距离
- 自然处理多类案件
- 在实践中可以做得很好,有足够的代表性数据
KNN 的缺点
- 需要确定参数 K 的值(最近邻的数量)
- 计算成本相当高,因为我们需要计算每个查询实例到所有训练样本的距离。
- 数据存储
- 必须知道我们有一个有意义的距离函数。
参考:
https://stack overflow . com/questions/11568897/value-of-k-in-k-nearest-neighbor-algorithm
张量流的简单介绍

Don’t lie, this was you at some point
根据我的经验,学习任何对计算机科学有用的东西都落在了理论和实践的奇怪交叉点上。我们很容易忽略一些我们编码的东西的深度。机器学习将这一点发挥到了极致,如今每个人都想成为机器学习工程师。(包括我自己)
《统计学习要素》是一本很棒的书。如果你能熬过这一关,你会知道很多,但如果你不能将其中任何一点付诸实践,那就没什么意义了。TensorFlow 是一个用于构建、训练和部署机器学习模型的框架。Keras 是一个构建在 TensorFlow 之上的包装器,使它更容易访问,更容易使用,也更干净。
下面的代码块相当于 TensorFlow 中的“Hello World”。尽管这是使用 TensorFlow 的第一步,但这里还有很多东西要解开。所以让我们开始吧。
Full Code for this article
Python 令人惊奇的一点是,少量代码中可以包含如此多的内容。跟随教程并让代码做事情是非常容易的。对某些人来说,这就够了。其他人可能想知道每一行或每一个函数的作用。我属于后一类。
数据
import tensorflow as tf
mnist = tf.keras.datasets.mnist
(x_train, y_train),(x_test, y_test) = mnist.load_data()
MNIST 数据集由手写数字组成;60000 幅训练图像和 10000 幅测试图像。一个训练集是一个集合,在其中我们被给予我们正在观察的特征的结果。特征是可以测量的物体的特征。一个更熟悉的特性术语可能是变量或属性。

Digits in the MNIST Dataset
通过使用训练集中对象的特征,我们的模型将学习,然后对新的相似对象进行预测。
测试集是我们将(你猜对了)用来测试通过使用训练集创建的模型。
在上面的几行中,我们告诉 TensorFlow 我们想要 MNIST 数据集中的文件,然后我们将数据加载到训练和测试变量中。
print(x_train.shape)(60000, 28, 28)
我们已经知道我们的训练集有 60,000 张图片。28,28 指的是每个图像的尺寸,28 像素乘 28 像素。因此,让我们进一步探索这些数据。
import matplotlib.pyplot as plt
%matplotlib inlineplt.figure()
plt.imshow(x_train[5])
plt.colorbar()
plt.grid(False)
plt.show()

Result of plt.imshow(x_train[5])
对于图像的任何给定像素,分配给该像素的值可以在 0 到 255 之间。这就引出了下一行代码:
x_train, x_test **=** x_train **/** 255.0, x_test **/** 255.0
它标准化了我们训练和测试集中的所有值。
好了,酷的时候到了:
模型
model = tf.keras.models.Sequential([
tf.keras.layers.Flatten(input_shape=(28, 28)),
tf.keras.layers.Dense(512, activation=tf.nn.relu),
tf.keras.layers.Dropout(0.2),
tf.keras.layers.Dense(10, activation=tf.nn.softmax)
])model.compile(optimizer=’adam’,
loss=’sparse_categorical_crossentropy’,
metrics=[‘accuracy’])
我们的第一行指定了我们正在使用的模型:
tf.keras.models.Sequential
顺序模型可以被认为是一堆煎饼。每一层都是煎饼。因为我们正在努力成为高级厨师,制作机器学习模型,所以我们的煎饼有馅料。馅料即使不比它们的成分更好,也尽量做得一样好。我们的原料是我们的训练装备。
第一层之后的层可以自动识别出模型的输入形状是连续的,这就是为什么只做一次的原因。
tf.keras.layers.Flatten(input_shape**=**(28, 28)),
我们现在把输入的图像“展平”成一个 2D 数组。输入形状是输入到图层中的图像的尺寸。可以把这看作是为模型重新格式化图像。
tf.keras.layers.Dense(512, activation**=**tf.nn.relu)
这就产生了一个紧密连接的神经层。层中的每个输入节点都连接到一个输出节点。它接收来自前一层的输入,这就是为什么它是密集。512 表示输出空间的维数,乍一看,这对大多数人来说意义不大。这意味着什么的答案是比这篇文章更深入的神经网络。
一个激活函数接受网络中一个节点的输入,并生成将被传递到下一层的输出。如果没有非线性激活函数,这将只是一个线性回归模型。这里使用的激活函数类型是 RELU 或整流线性单元,这是最常用的激活函数之一。
tf.keras.layers.Dropout(0.2),
丢弃层是一种正则化技术,其中随机选择的神经元在训练中被忽略。这里我们有一个 20%的比率集,它将在下一个训练周期中丢弃每五个输入中的一个。
tf.keras.layers.Dense(10, activation**=**tf.nn.softmax)
与上面的 RELU 层类似,这一层使用了一个 Softmax 激活函数。Softmax 激活函数的输出类似于分类概率分布,因此它表示类为真的概率。
model.compile(optimizer**=**'adam',
loss**=**'sparse_categorical_crossentropy',
metrics**=**['accuracy'])
现在我们编译这个模型。
首先,亚当到底是谁?不是一个人。显然它是从“自适应矩估计”中推导出来的。应该是一个叫亚当的人想出来的,应该能写出更好的段落。
无论如何,优化器确实做了它听起来做的事情。Adam 优化算法用于根据训练数据更新网络权重。
损失函数用于衡量预测值和实际值之间的差异。目标是最小化损失函数。
结果
model.fit(x_train, y_train, epochs**=**5)
model.evaluate(x_test, y_test)
最后,我们拟合和评估我们的模型。需要注意的是,一个纪元与一次迭代不是一回事。历元是训练数据的完整传递。让一个模型运行太少的时期,在性能方面会有很多不足之处。让一个模型运行太多的时期会有开始“记住”它可能想要的输出的风险,因此会损害它的准确性。
这个模型的训练无论如何都不是很好,但这只是来自 TensorFlow 教程。
model.fit(x_train, y_train, epochs=5)
model.evaluate(x_test, y_test)Epoch 1/5
60000/60000 [==============================]60000/60000 [==============================] - 8s 126us/step - loss: 9.9728 - acc: 0.3813
Epoch 2/5
60000/60000 [==============================]60000/60000 [==============================] - 8s 127us/step - loss: 10.1151 - acc: 0.3724
Epoch 3/5
60000/60000 [==============================]60000/60000 [==============================] - 8s 127us/step - loss: 10.0101 - acc: 0.3789
Epoch 4/5
60000/60000 [==============================]60000/60000 [==============================] - 8s 126us/step - loss: 10.0149 - acc: 0.3786
Epoch 5/5
60000/60000 [==============================]60000/60000 [==============================] - 8s 127us/step - loss: 10.0893 - acc: 0.3740
10000/10000 [==============================]10000/10000 [==============================] - 0s 32us/step[10.388112817382812, 0.3555]
现在你知道了!首次尝试 TensorFlow。虽然它只有几行代码,但还有很多要解开,但这将变成一本书。如果你读了所有这些,我希望你学到了一些东西!
一个简单的,外行人介绍人工智能
人工智能(AI)是什么,为什么要关心?
你一定听说过艾。那么什么是“人工智能(AI)”。为了理解,我们首先需要理解什么是计算机。

“计算机”这个词的意思是会“计算”的人或东西。多年前,在计算机出现之前,进行计算的人被称为计算机。现在,计算机可以根据我们的指令进行计算、数据处理或控制与计算机相连的设备。人类可以做所有这些事情,但计算机可以做得更快。计算机每秒可以处理超过 20-30 亿次交易,而我们却几乎不能。如果我们改变时间尺度,这种差异是明显的。如果计算机需要一秒钟来做一个复杂的计算,保持相同的速度比,人类需要 63 年才能完成同样的计算。此外,从长远来看,与人类相比,计算机要便宜得多。
如果你想在 10,000 个文档中找到包含“AI”这个词的文档,或者创建同一文档的 20 个副本,计算机可以非常快地完成。因此,计算机非常擅长计算、存储和整理数据,并在大量数据中找到相关信息。有了这些技能,计算机变得无处不在,并且已经改变了世界。
然而,有许多问题是计算机无法处理的。我们已经说过,如果我们能告诉计算机做什么,它就能做到。但是,有些问题,很难说该怎么办。

举个例子,我们来考虑一下开车。还记得你是怎么学会开车的吗?有人写下在所有情况下该怎么做了吗?如果你认为你能做到,试着写如何开车。你会发现这几乎是不可能的。这种情况太多了。相反,我们通过尝试和获得反馈来学习。
很多需要决策、复杂思考或智力的问题都有相同的表现。人工智能是一种可以解决这类问题的技术。你不必告诉 AI 做什么。相反,你必须给出很多例子来说明什么是对的,什么是错的,技术能够从中学习,就像人类一样。
当人工智能学会如何解决一个问题时,它可以更快地解决它,一次又一次。例如,它可以识别声音,找到图片中的内容,诊断疾病,检测欺诈行为。这些事情不能自动化,因为人们不能告诉计算机如何去做。人工智能比人类更快、更便宜地完成这些任务。
例如,假设你计划去日本旅行,但你会发现大部分细节都是用日语写的。你可以去谷歌翻译器(https://translate.google.com/)翻译信息。几年前,要做同样的事,要么你得找个懂日语的人,要么雇个翻译。然而,现在谷歌有能力免费给你。这就是 AI 的力量之一。
在过去的几年里,对于一些问题,人工智能已经接近超越人类的表现。著名的例子发生在 1997 年,当时国际象棋计算机“深蓝”打败了国际象棋世界冠军。其他例子还有 Alpha Go 击败世界围棋冠军,IBM Watson 击败自然语言问答比赛 jeopardy 的冠军。
这些例子来自游戏。现实世界中的例子包括自动驾驶汽车、谷歌照片搜索、语言翻译和疾病诊断。AI 正在接管大量用例。它不再只是数百万公司手中的工具。例如,大约一年前,一名青少年编写的人工智能程序帮助推翻了 375000 多张停车罚单。IBM 正试图将他们的沃森人工智能引擎应用到健康领域,如果成功,它可能会让每个人以很少的成本获得高质量的医疗建议。
此外,我们每天通过使用谷歌搜索或脸书等应用程序与人工智能互动。比如,麦肯锡估计,在未来 10—15 年内,约 14%的现有工作将实现自动化。
人工智能或我们生活的影响将比上述例子所暗示的更加广泛。让我们以自动驾驶汽车为例。让我们检查一些不明显的影响。如果大多数汽车都是自动驾驶的,这将减少大多数事故,因为如果发生一起事故,所有的汽车都会从事故中吸取教训。作为一个单独的车队,汽车将能够开得更快,从而大大减少交通流量。大部分停车位都可以被释放出来,因为你可以下车,并要求汽车停放。汽车看起来会很不一样。你可以在车里吃东西、睡觉或看电视。交通警察、保险和许多相关服务可能不需要。
然而,并非所有的影响都是有利的。一些工作将被取代。人们将不得不学习新技能。政府必须帮助人们转换工作。然而,人工智能并不意味着它们将永远取代人类。更常见的是,人工智能将帮助人类做出更好的决定,更有效地做事,并接管他们工作中重复的部分。
很可能你至少看过一部有杀手级 AI 的电影。事实上,这是可能的,尽管我们可能需要 50-100 年才能实现这种人工智能。例如,一个人可以从 2-3 个例子中学习,而人工智能需要数十亿个。

最后,在对人工智能做出判断之前,我们需要了解当前的低效率。例如,世界上许多人无法接触到顶级专业人士,如医生、教师、设计师和律师。因此,每天都有许多人死亡。人工智能有可能使专业知识无处不在,并每天拯救许多生命。这意味着不作为也要付出代价。否定 AI,让人们死亡或处于劣势,公平吗?我们必须衡量积极影响和消极影响。
这意味着我们所知道的世界正在快速变化。我们的孩子将生活在一个不同的世界,做非常不同的工作。他们面临的挑战将会非常不同。然而,我充满希望,人类已经适应了许多环境和技术的变化,我们也将适应这种变化。
解决普特南竞赛数学问题的简单蒙特卡罗模拟
Python 中蒙特卡罗方法综述

Photo by Jonathan Petersson on Unsplash
介绍
高赌注赌博和高速赛车有两个共同点——高度的不确定性和蒙特卡洛城。这两者之间的联系导致了术语“蒙特卡罗模拟”的使用,该术语用于使用统计抽样来预测包含不确定性的过程的各种结果的概率的计算方法。迷茫?放心吧!我们将看看使用 Python 设计和执行一个简单的蒙特卡罗模拟。
当我的一个朋友挑战我解决久负盛名的普特南竞赛中的一个问题时,我通常无聊的火车通勤变得令人兴奋——这是一个甚至困扰最聪明的数学本科生的测试。
问题如下(转述):
如果你在一个球体上随机选择 4 个点并把它们连接起来,那么得到的四面体包含球体中心的概率是多少?

现在,通过应用一些几何和概率的概念来确定精确的解是完全可能的。我希望你们中的数学天才在你读完这句话之前就已经准备好答案了。对于那些不能理解的人(像我一样),YouTube 上 3Blue1Brown 的一个视频提供了一个关于分析解决方案的非常优雅的解释。
然而,问题中的“随机”一词在我的脑海中引发了另一种思路,最终导致了我将要提出的解决方案。我考虑了通过随机抽样获得答案的可能性。这个想法很简单——抽取大量四面体的随机样本,并计算考虑所有这些样本的概率。
该算法
模拟的大致算法如下:
- 将已知半径的球面定义为样本空间。
- 将合成概率定义为 num/den,其中 num=0,den=1。
- 从样本空间中绘制球体内部四面体的一个样本。
- 确定中心是否位于四面体内部。
- 分别基于当前试验的成功或失败,通过在 num 上加 1 或 0,并在任何情况下在 den 上加 1,计算得到的概率。
- 重复步骤 3 至 5,选择指定数量的随机样本。
- 显示结果概率。
代码
我们将一步一步地浏览代码,并详细检查每一步。
步骤 1:导入所需的模块
首先,我们在 Python 中导入所需的模块——即 Scipy 和 Matplotlib 。 Scipy 有一个允许生成随机数的子模块。
import scipy as sci
import matplotlib.pyplot as plt
步骤 2:定义样本空间
下一步是创建一个由一定数量的点组成的样本空间。对于这个例子,让样本空间在半径为 1 单位的球体表面上有 10,000 个点。
我们如何确保样本空间上的点位于球面上?三个简单的步骤:
- 使用
sci.random.rand(1,3)选择任意随机 3D 矢量。这将产生一个以 0.5 为中心的三维矢量,每个坐标的值在 0 到 1 之间。 - 从每个坐标中减去 0.5,使其以 0 为中心。
- 计算向量的范数(或大小)并将向量除以其范数,确保其成为单位向量。任何单位矢量都必然位于半径为 1 的球面上。
为了安全起见,可以添加一个 if 条件,以确保范数等于 0 或大于 1 的向量不会经历这种变换。
This animation was created using matplotlib; the code for this is not given in the article. It is merely used for the purpose of representation of under-the-hood computations.
points=10000 #Number of points
x=sci.zeros((points,3)) #To store x-coordinates of sample points
y=sci.zeros((points,3)) #To store y-coordinates of sample pointsfor i in range(points):
vector=sci.random.rand(1,3)-0.5
if(sci.linalg.norm(vector)!=0 and sci.linalg.norm(vector)<=1.0):
x[i,:]=vector
y[i,:]=x[i,:]/sci.linalg.norm(x[i,:])
为了绝对确保样本空间中的所有点都位于球体表面,我们可以添加另一个检查点。****
我们计算样本空间中向量的实际范数和期望范数(等于球体的半径;这里 1)并将其与一个公差(任意定义的;这里是 1×10⁻ ⁰).与所需规范不匹配的规范存储在danger_array中。如果danger_array的大小是 0(也就是说,不存在不需要的规范),那么我们显示“全部清除”消息并继续前进。
y_norms=sci.zeros(points) #Array to store norms of sample vectorsfor i in range(points):
y_norms[i]=sci.linalg.norm(y[i,:])
tol=1e-10 #Tolerance
norm_diff=abs(y_norms-1) #Diff. between actual and desired norm
danger_array=y_norms[norm_diff>tol]if(len(danger_array)==0):
print("All Clear")
else:
print("Danger")
步骤 3:创建函数来确定中心是否位于四面体内部
一旦所有检查都通过了,我们就进入问题的核心——确定球体的中心是否位于随机四面体中。这可以通过使用两个函数来简化。
第一个检查球体的中心和四面体的第四个顶点是否位于由四面体的其余三个顶点形成的平面的同一侧。
第二个为四面体的所有四个面调用第一个函数,并推断中心是否位于四面体内部。
为了公式化CheckSide函数,我们依赖于以下线性代数原理:
- 两个向量的叉积给出一个垂直于两个向量形成的平面的向量。****
- 两个矢量的点积给出了一个矢量在另一个方向上的分量的大小。如果分量的方向与第二个向量相反,那么点积就是负的。****
我们使用第一个原理来寻找由任意三个顶点形成的平面的法线。
接下来,我们找到法线和一个向量的点积,该向量将第四个顶点与三个顶点中的任何一个连接起来——这个点积的符号被存储。
最后,我们找到法线和连接球体中心和三个顶点中的任何一个的向量的点积——将该点积的符号与前一个进行比较,如果它们与匹配,则可以得出结论,第四个顶点和中心位于由剩余三个顶点形成的平面的同侧。

This schematic will make it easier for you to visualize the application of the two principles
def CheckSide(vertices,point):
t1,t2,t3,t4=vertices
p=point
side_1=t2-t1
side_2=t3-t1
normal=sci.cross(side_1,side_2) ref_vector=t4-t1
ref_sign=sci.dot(normal,ref_vector) point_vector=p-t1
point_sign=sci.dot(normal,point_vector) if(sci.sign(ref_sign)==sci.sign(point_sign)):
return 1
else:
return 0
如果我们将CheckSide函数应用于一个四面体的所有四个面,我们将能够准确地推断出中心是否位于其中。因此,我们定义了一个新函数CheckTetrahedron ,它调用了CheckSide 函数四次。
在每一次函数调用之间,我们将的顶点数组滚动一个,这样CheckSide 函数在下一次调用时会在一个新的面上工作。
最后,将所有四个CheckSide 调用返回的值相加,如果它们等于 4 ,则断定中心位于四面体内部;如果没有,它就在外面。
def CheckTetrahedron(vertices,point):
vert=sci.copy(vertices)
check_1=CheckSide(vert,point) vert=sci.roll(vert,1,axis=0)
check_2=CheckSide(vert,point) vert=sci.roll(vert,1,axis=0)
check_3=CheckSide(vert,point) vert=sci.roll(vert,1,axis=0)
check_4=CheckSide(vert,point) sum_check=check_1+check_2+check_3+check_4 if(sum_check==4.):
return 1
else:
return 0
步骤 4:初始化
现在我们已经定义了所有必需的函数,是时候开始实际运行了。在开始运行之前,我们需要初始化一些参数,以便运行和绘图。
数组check_point将存储的和的来表示每次迭代的成功或失败。我们将创建一个数组来存储每次迭代的值,而不是只存储结果概率的一个值,这样我们就可以绘制一条曲线来显示概率随迭代次数的变化。
centre=[0,0,0]
number_of_samples=10000
sample_span=sci.arange(0,number_of_samples,1)
check_point=sci.zeros(number_of_samples)
prob=sci.zeros(number_of_samples)
跑步
是时候运行模拟了!在每次迭代中,我们做以下三件事:
- 从样本空间中随机挑选 4 个不同的点。
- 将
CheckTetrahedron函数应用于这 4 个点和中心,以确定中心是否位于这 4 个点形成的四面体中。 - 根据试验的成功或失败,在
check_point中分别存储 1 或 0,并更新prob数组中的合成概率值。
This animation was created using matplotlib; the code for this is not given in the article. It is merely used for the purpose of representation of under-the-hood computations.
for i in range(number_of_samples):
indices=sci.random.randint(0,points,4)
vertex_list=y[indices]
check_point[i]=CheckTetrahedron(vertex_list,centroid)
prob[i]=len(check_point[check_point==1.])/(i+1)
第六步:绘图
最后,在给定迭代次数下运行模拟后,绘制结果并找出结果概率的时间到了。我们给情节添加了一些花里胡哨的东西,让它看起来更有吸引力,同时也确保它清晰地传达了所有需要的信息。
#Plot blank figure
plt.figure(figsize=(15,10))#Plot resultant probability from simulation
plt.plot(sample_span,prob,color="navy",linestyle="-",label="Resultant probability from simulation")#Plot resultant probability from analytical solution
plt.plot(sample_span,[0.125]*len(sample_span),color="red",linestyle="-",label="Actual resultant probability from analytical solution (0.125)")#Plot value of final resultant probability in text
plt.text(sample_span[int(number_of_samples/2)],0.05,f"The final probability is {prob[-1]:.4f}",fontsize=16)#Display axis labels
plt.xlabel("Number of iterations",fontsize=14)
plt.ylabel("Probability",fontsize=14)#Display legend
plt.legend(loc="upper right",fontsize=14)#Display title of the plot
plt.title("Variation of resultant probability with increase in the number of iterations",fontsize=14)
最终的剧情如下。从图的性质来看,很明显随着迭代次数的上升,概率收敛到真值(即解析解)。****

Plot generated by matplotlib detailing the variation of probability with the number of iterations
总结想法
由于方法中相关的随机性,你的模拟可能无法在与我的模拟相同的迭代次数内收敛到真实值。在这种情况下,您可以不断增加迭代次数,直到您的解收敛到真实值。
解析解是 1/8 或 0.1250 ,蒙特卡罗模拟收敛到一个值 0.1248,,这个值足够接近。我们通过模拟从随机性中创造了一种明显的秩序——重复随机采样可以导致单一收敛解的事实令人震惊。这种方法可能看起来不优雅——几乎就像对计算能力的野蛮使用——但它非常有效,确实给出了准确的答案。
代码已经被记录在一个 Jupyter 笔记本中,可以在线查看。
我希望我已经清楚地解释了方法和代码。欢迎您在评论中做出回应,提出问题或提供您可能有的任何建议。
你也可以在 Twitter 上关注我。
一个简单的 Python 脚本来记录 SQLite 数据库
自动生成降价文件以记录 SQLite 数据库
当我使用关系数据库时,这个问题一直困扰着我:文档。实体关系图是标准的,但是当列名不是自解释的或者模式变得太大而无法处理时,它就没有用了。 SchemaSpy 是一个开源工具,可以自动生成 ER 图,但它为用户提供了接近零的灵活性来增强文档。

SchemaSpy demo
对于小型数据集,SchemaSpy 可能是多余的。为了使数据集可用于协作,很好地记录每一列就足够了。我选择 markdown 作为这项工作的工具。事不宜迟,让我们看看解决方案是什么样子的。

After executing the script on the left, we obtain a documentation template on the right.
该脚本检索所有表和相应的列名。我们需要做的就是打开 markdown 文件,并填写每个字段的描述。
你可以在这里下载奇努克数据库并在你的电脑上运行演示。现在终于轮到我的食谱了。尽情享受,随心所欲地调节它:-)
sqlite_doc_template.py
你知道任何其他好的方法来记录数据库(SQL,NoSQL,图形数据库等)。)?请在下面评论或给我留言!
探索性数据分析的一个简单技巧
如果您很难理解您的数据,您可以尝试使用这些超级基础的数据分析工具,例如 python、SQL 和 excel 数据透视表。最终的结果是类似仪表板的表格,使您能够通过切片和切块来挖掘可操作的洞察力。

那么首先要做什么呢?当然,获取数据。
本文中使用的数据源是来自 UCI 机器学习库的一个银行机构的直接营销活动(大约#41K 记录)。 然后,用 pandas 把 CSV 文件读入 DataFrame。
~https://archive.ics.uci.edu/ml/datasets/Bank+Marketing
import pandas as pd
bank_cust_df = pd.read_csv('../dat/bank-additional-full.csv', sep = ',')
bank_cust_df.head(10)

First 10 rows of bank_cust_df
根据数据集描述,我们知道银行客户数据与基于电话的电话营销活动有关,并且与定期存款的预订 的结果有关。(出于演示目的,我将仅使用人口统计相关数据,并跳过下面展示中的数据清理步骤。)
+---------------+--------------------------------------------+
| Features Name | Features Description |
+---------------+--------------------------------------------+
| age | numeric |
| job | type of job (blue-collar, entrepreneur...) |
| marital | marital status (married, singe...) |
| education | education (high school,university...) |
| default | has credit in default? (Y/N) |
| housing | has housing loan? (Y/N) |
| loan | has personal loan? (Y/N) |
**| y | has subscribed a term deposit? (Y/N) |**
+---------------+--------------------------------------------+
接下来,我们需要隔离必要的列,并了解数据的样子。
使用 SQL 将数据汇总成汇总格式
# pandasql needed to run SQL with the pandas DataFrame
# [https://pypi.org/project/pandasql/](https://pypi.org/project/pandasql/)from pandasql import sqldf
pysqldf = lambda q: sqldf(q, globals())
聚合字段的基本思想是创建您想要浏览的字段的汇总表。例如,下面的代码将婚姻状况和教育与婚姻状况计数相加。
sql = """
select
--==================
-- Category Features
--==================
job
,education
,count(*) as cnt
--=============================
-- Summarized Category Features
--=============================
,sum(case when marital = "divorced" then 1 else 0 end) as m_divorced
,sum(case when marital = "married" then 1 else 0 end) as m_married
,sum(case when marital = "single" then 1 else 0 end) as m_single
,sum(case when marital = "unknown" then 1 else 0 end) as m_unknown
from bank_cust_df
--===============================================
-- in this case, there are 2 columns to summarize
--===============================================
group by 1,2
;
"""
agg_df = pysqldf(sql)
agg_df.head(20)
然后,您将得到一个汇总表 agg_df ,如下所示,包含工作和教育的所有可能组合。通过每种组合,您还可以拥有不同婚姻状况的客户数量。

Example on aggregated table
下面的全代码生成整个汇总表:
sql = """
select
y as subscribed
,case when age <= 18 then "Below 18"
when age <= 25 then "19 - 25"
when age <= 35 then "26 - 35"
when age <= 45 then "36 - 45"
when age <= 55 then "46 - 55"
when age > 55 then "55 +" end as age_group
,job
,education
,marital
,housing
,loan,count(*) as cnt,sum(case when y = "yes" then 1 else 0 end) as subscribed_y
,sum(case when y = "no" then 1 else 0 end) as subscribed_n,sum(case when age <= 18 then 1 else 0 end) as age_18
,sum(case when age <= 25 then 1 else 0 end) as age_25
,sum(case when age <= 35 then 1 else 0 end) as age_35
,sum(case when age <= 45 then 1 else 0 end) as age_45
,sum(case when age <= 55 then 1 else 0 end) as age_55
,sum(case when age > 55 then 1 else 0 end) as age_ge_55,sum(case when job = "admin." then 1 else 0 end) as job_ad
,sum(case when job = "blue-collar" then 1 else 0 end) as job_blue
,sum(case when job = "entrepreneur" then 1 else 0 end) as job_entre
,sum(case when job = "housemaid" then 1 else 0 end) as job_house
,sum(case when job = "management" then 1 else 0 end) as job_mgt
,sum(case when job = "retired" then 1 else 0 end) as job_reti
,sum(case when job = "self-employed" then 1 else 0 end) as job_self
,sum(case when job = "services" then 1 else 0 end) as job_serv
,sum(case when job = "student" then 1 else 0 end) as job_std
,sum(case when job = "technician" then 1 else 0 end) as job_tech
,sum(case when job = "unemployed" then 1 else 0 end) as job_unem
,sum(case when job = "unknown" then 1 else 0 end) as job_un,sum(case when marital = "divorced" then 1 else 0 end) as m_divorced
,sum(case when marital = "married" then 1 else 0 end) as m_married
,sum(case when marital = "single" then 1 else 0 end) as m_single
,sum(case when marital = "unknown" then 1 else 0 end) as m_un,sum(case when education = "basic.4y" then 1 else 0 end) as edu_4y
,sum(case when education = "basic.6y" then 1 else 0 end) as edu_6y
,sum(case when education = "basic.9y" then 1 else 0 end) as edu_9y
,sum(case when education = "high.school" then 1 else 0 end) as edu_high
,sum(case when education = "illiterate" then 1 else 0 end) as edu_illi
,sum(case when education = "professional.course" then 1 else 0 end) as edu_pro
,sum(case when education = "university.degree" then 1 else 0 end) as edu_ud
,sum(case when education = "unknown" then 1 else 0 end) as edu_un,sum(case when housing = "yes" then 1 else 0 end) as housing_y
,sum(case when housing = "no" then 1 else 0 end) as housing_n
,sum(case when housing = "unknown" then 1 else 0 end) as housing_un,sum(case when loan = "yes" then 1 else 0 end) as loan_y
,sum(case when loan = "no" then 1 else 0 end) as loan_n
,sum(case when loan = "unknown" then 1 else 0 end) as loan_un
from bank_cust_df
group by 1,2,3,4,5,6,7
;
"""agg_df = pysqldf(sql)
agg_df.head(20)
结果聚集表具有#3,980 条记录,共 45 列(45 列中的 7 列是特征列;其他为汇总栏)。创建这样的聚合表的一个优点是防止敏感的客户数据泄露,因为所有数据都已经汇总。
通过创建简单的 excel 数据透视仪表板实现数据可视化
接下来,将聚合表导出到 CSV。不直接导出到 excel 文件的原因是为了防止记录超出 Excel 限制(根据版本不同,是#65,536 还是# 1,048,576)。
# Export the csv file to out folder
agg_df.to_csv('..\out\summ.csv',index=False)

Exported summ.csv open in excel
再创建一个名为 summary.xlsx 的 excel 文件,使用 excel 内置函数(Data > From Text/CSV)添加与 summ.csv 的数据连接。数据导入后,使用导入的数据作为数据源创建数据透视表。

import summ.csv

Load the data with comma as the delimiter

Using summ table as a data source
根据特性类型放置字段,
-特性列>过滤区
-汇总列>值区
-订阅的>列
-σ值>行

Pivot Table fields setting
最后,将该字段重命名为有意义的标题,并对其应用条件格式,这样就完成了一个带有特色过滤器的清晰的仪表板,并且可以更容易地显示客户数据的分布。

Dashboard-like table
浏览数据的最简单方法
现在,您可以创建一个简单的仪表板表,以便更好地了解您的数据,而无需任何花哨的分析工具。
最后,如果您拥有的数据少于 100 万行,我建议您在您的任务中充分利用上面的探索方法。接下来你要做的只是简单地切片和切块,并搜索任何特殊的模式和见解。
部署任何机器学习模型的简单方法
如何使用 Azure 函数来公开一个 REST API 端点,以服务可以在另一个服务器中计算的 ML 模型

Is there an easy way to deploy a powerful image segmentation model to a mobile app? The answer is yes.
当数据科学家开发机器学习模型时,无论是使用 Scikit-Learn、深度学习框架(TensorFlow、Keras、PyTorch)还是自定义代码(convex programming、OpenCL、CUDA),最终目标都是使其在生产中可用。
然而,很多时候我们只是想要一个简单的方法来调用 REST API 并使用当前的分类器获得预测。例如,我们可能只想展示模型如何与用户界面集成,而不用担心设置环境、扩展到生产、平衡负载或任何其他问题。
这篇文章将展示我发现的最简单的方法:
- 建立机器学习模型;
- 公开一个端点(REST API),以便网站/应用程序可以向http://myendpoint.com/predict发布消息并获得结果;
- 所有源代码和安装说明可在 https://github.com/douglas125/AzureMLDeploy获得
我们不用担心导出模型、创建 Docker 图像、直接在浏览器中运行、安装软件包或任何类似的事情——有大量的资源可以处理这些问题(参见参考资料)。在本文中,机器学习服务器(MLServer)可以是本地计算机或云中的虚拟机。它将检索需要处理的数据,并将结果发送回来。
此外,无服务器架构是最便宜和最容易实现的架构之一:本质上,每个存储和执行时间都是收费的——如果我们不需要永远存储输入和输出,成本应该会非常低。
它是如何工作的?
Azure Function 应用程序充当中间人,接收并存储来自客户端的请求和来自 MLServer 的回答。当客户端返回来检索结果时,函数应用程序会将结果交付给客户端。
这看起来非常简单——确实如此。正是我们在这篇文章中寻找的。
示例 1:简单的 Ajax 页面
按照存储库中的安装说明,可以构建一个简单的 Ajax 页面来总结客户端和 MLServer 端的工作流。注意,虽然 HTML 页面非常简单,但它仍然演示了如何从客户端(发送作业和检索结果)和 MLServer(获取作业和发送结果)向端点发送数据。

Simple Ajax page to test Azure Function App. Sequence: 1 — client posts task, receives task_id; 2 — MLServer fetches task and processes it; 3 — MLServer sends results to Function App; 4 — Client retrieves results.
示例 2:将 DeepLabV3+作为服务运行
C#是为 Windows 构建用户界面的好工具。这个例子展示了如何使用 python(作为 MLServer)进行推理。同样,所有代码在这个库中都是可用的。
下面的图像序列演示了客户端和 MLServer 端发生的情况。请注意,MLServer 可以是运行 Jupyter 笔记本中 Keras 模型的任何计算机或虚拟机。

Client C# application loads image, resizes it to 512x512 (DeepLabv3+ input size) and sends it to Azure Function App Server.

A local computer or a virtual machine could be used to make predictions. In this case, we used Google Colab as the MLServer

Client C# application receives predictions (a .png file with the masks) and displays results to the user in a friendly interface.
保持简单
像 Azure Functions 或 AWS Lambda 这样的无服务器架构是实现云计算的绝佳方式:它们处理扩展服务的问题,它们通常易于使用,并且在许多情况下,它们也是最便宜的选择,因为它们不需要专用服务器,用户按使用付费(消费计划)。选择 Azure 函数完全是因为我对 C#的熟悉。
我们将构建一个简单的无服务器架构,接收用户请求,允许远程机器读取并预测存储在云中的数据,并让用户接收最终结果。请注意,功能应用程序可以配置为要求身份验证,保存发出请求的用户(稍后向他们收费)和许多其他功能-这只是一个入门代码,应该用作简单的基础。
工作流程如下:
- 用户通过向端点/预测发布消息来发出预测请求,该消息带有其有效载荷——文本、图像、音频或任何需要分析的数据;
- 服务器接收用户请求,保存有效载荷并生成唯一的 task_id,返回给用户;
- MLServer(机器学习服务器)查询服务器检索下一个作业;
- 服务器向 MLServer 发送下一个作业的 task_id 和有效载荷;
- MLServer 处理有效负载并将 task_id 的结果发送到服务器;
- 服务器接收并存储 task_id 结果;
- 用户使用 task_id 查询服务器并检索结果。

Client — Server — MLServer architecture
设置服务
我们已经讨论了客户端和 MLServer 是做什么的。现在是时候深入 Azure Function 应用服务器了。
服务器需要处理来自客户机和 MLServer 的请求。我们需要四个端点:
- 预测—接收有效负载并创建 task _ id
- getresult—接收 task_id 并返回该任务的结果(如果可用);
- getnexttask —向 MLServer 发送 task_id 和有效负载;
- puttaskresult —接收 task_id 并存储结果。
我们将使用 Azure Blob 存储来保存有效负载和结果。我们需要两个文件夹:收件箱(存储未完成任务的地方)和发件箱(存储结果)。如果我们想要使用多个服务器并行处理数据,我们可能会想要跟踪正在处理的任务(以便相同的任务不会被执行两次)。然而,这超出了本文的范围,并且会给我们的目标增加额外的、不必要的复杂性。
在函数 puttaskresult 中,我们将从 inbox 文件夹中删除有效载荷,并将结果保存在 outbox 文件夹中。如果我们愿意,我们可以在删除它之前将有效负载复制到一个“已处理”的文件夹中,但是这里我们将保持简单。
对于所有的实现细节,感兴趣的读者应该参考这个库。它有功能应用程序的所有源代码以及安装说明。
结论
本文演示了一种非常简单的方法,使用 Azure 函数存储和服务请求和预测结果,将机器学习模型部署到客户端应用程序。虽然这种方法不如 Tensorflow Serving 强大或不如 tensorflow.js 通用,但它具有重要的优势;
- 部署起来非常简单;
- 它允许程序员服务于任何机器学习模型——不仅仅是神经网络,以及任何预处理和后处理步骤;
- 不需要转换或 dockerize 任何东西;
- 不需要分配专用的 VM——推理可以在本地运行;
- 由于推理可以在本地运行,功能应用程序按请求/存储收费,因此这是一个演示概念的廉价选项。
当然也有缺点:
- 对于需要接近实时运行的模型(例如,有执行时间限制的模型),这不是最好的选择;
- 不会像 tf.js 一样在客户端运行;
- MLServers 的负载平衡必须手动完成。
请注意,在原型/开发的早期阶段,这些缺点通常不是开发人员所担心的——他们可以简单地让一台 PC 开着(或者甚至是 Google Colab ),让用户界面团队可以使用 REST API。
这是我发现的将当前状态的机器学习算法快速部署到客户端应用程序的最简单方法。
参考
Tensorflow.js 【https://js.tensorflow.org/
使用 Azure 机器学习服务部署模型。https://docs . Microsoft . com/en-us/azure/machine-learning/service/how-to-deploy-and-where
在生产中部署机器/深度学习模型的指南。https://medium . com/@ maheshkkumar/a-guide-to-deploying-machine-deep-learning-model-s-in-production-e 497 FD 4b 734 a
如何使用 Tensorflow Serving 轻松将机器学习模型投入生产。https://medium . com/coin monks/how-to-easy-put-machine-learning-models-to-production-using-tensor flow-serving-91998 fa 4 B4 e 1
通过使用 AWS Lambda 服务机器学习模型,我们学到了什么。https://medium . freecodecamp . org/what-we-learn-by-serving-machine-learning-models-using-AWS-lambda-c70b 303404 a 1
ML.NET——一个开源、跨平台的机器学习框架。https://dot net . Microsoft . com/apps/machine learning-ai/ml-dot net
使用 Python 训练和部署机器学习模型的初学者指南。https://medium . freecodecamp . org/a-初学者指南-训练-部署-机器学习-模型-使用-python-48a313502e5a
部署机器学习模型作为 REST API 。https://towards data science . com/deploying-a-machine-learning-model-as-a-rest-API-4a 03 b 865 c 166
部署机器学习模型很难,但不一定非得是。https://www . anaconda . com/blog/developer-blog/deploying-machine-learning-models-is-hard-but-it-dont-have-to-be/
我们如何使用 FLASK 和 DOCKER 部署 SCIKIT-LEARN 模型。https://blog . solutotlv . com/deployed-sci kit-learn-model-flask-docker/?UTM _ medium = How-do-I-deploy-Machine-Learning-Models-as-an-API&UTM _ source = quora
档案:波利贾·科纳·Poznań.jpg。https://commons . wikimedia . org/wiki/File:Policja _ konna _ Pozna % C5 % 84 . jpg
作者 LukaszKatlewa——自己的作品,CC BY-SA 4.0 ,https://commons.wikimedia.org/w/index.php?curid=49248622
Keras 实现 Deeplabv3+ 。https://github.com/bonlime/keras-deeplab-v3-plus
检测异常的简单方法

Photo by Markus Spiske on Unsplash
当一个类中的观察值比另一个类中的观察值多得多时,很难训练一个普通的 CNN 分类器。CNN 分类器可以认为所有的观察值都来自主类,以实现高精度。
解决这个问题的一种方法是使用过采样或下采样来平衡数据。此外,调整类权重以强制分类器处理稀有类中的数据也是一个好主意。
然而,当数据极度不平衡时,使用上述方法有时可能导致模型过度拟合。因此,我们将研究另一种方法,称为异常检测,来处理这种情况。
我们将假设主类中的观察值为正常数据,并仅使用这些数据来训练我们的模型。然后,我们能够预测一个新的观察是否正常。您可能会问,当模型没有根据这些数据进行训练时,如何检测异常数据。下面是一个简单的例子来说明异常检测是如何工作的。
—实施—
我们可以使用 Keras 和 Scikit Learn 在几行代码内实现异常检测。
首先,导入库来构建模型。这四个库正是我们所需要的。
其次,我们可以使用预先训练的模型作为特征表示,将图像转换到更好的特征空间。
我们使用 Keras 得到一个在 ImageNet 上预训练的 VGG16 模型,并得到所选层的输出。然后,我们将输出通过一个全局平均池层来降低维度。
为了实现一类分类器,我们使用来自 Scikit Learn 的聚类模型,高斯混合模型(GMM)。所以,建造一个只有一个组件的 GMM。

figure 2. clustering examples from Scikit Learn documentation.
如图 2 所示。越靠近高斯分布中心的数据越可能是正态的。通过选择分布的范围,我们能够确定观察值是否正常。
是时候导入数据集来看看模型是如何工作的了。我们使用来自 Keras 的 MNIST 数据集。我们假设“1”为正常数据,“7”为异常数据。因此,我们只使用“1”作为训练数据,同时使用“1”和“7”作为测试数据。
reshape_x: according to Keras’s VGG pre-trained model, the minimum size of images is 30 * 30, so we have to resize our images and transform them into 3-channel images.
只有两行来训练我们的模型。首先,使用 VGG 模型从训练数据中提取特征。然后,使用结果作为 GMM 的输入数据。
—结果—
使用 GMM 的 score_samples 函数,我们可以很容易地计算数据的可能性。假设阈值是训练数据的平均可能性加上 3 倍的标准偏差,我们可以预测我们的测试数据。
我们使用 VGG 模型从测试数据中提取特征。然后,我们使用经过训练的 GMM 来计算结果的可能性。最后,如果观测值的可能性小于阈值,我们就可以检测到异常。

the output of svdd_part6.py
让我们来看看我们的结果吧!我们画散点图,x 轴是数据的指数,y 轴是分数。我们将“1”标为蓝点,将“7”标为粉红点,并将阈值标为黑线。我们可以看到,大部分的点都可以用阈值来分隔。我们就是这样检测异常数据的。

visualization of output, the score is negative since the output of score_samples is log likelihood.
我们还可以检查失败案例。下图显示,当“1”更复杂且“7”过细时,模型更容易出错。

These are predictions of ‘1’. the first row is incorrect predictions. The second row is correct predictions.

These are predictions of ‘7’. the first row is incorrect predictions. The second row is correct predictions.
为了获得更好的准确性,我们可以用自动编码器代替预先训练的模型,以获得更好的特征表示。虽然在 ImageNet 上预先训练的模型可以从图像中提取很好的特征,但 MNIST 的图像与 ImageNet 中的图像非常不同。如果我们使用与 ImageNet 大不相同的数据集,可能会得到更差的结果。此外,有很多方法可以实现异常检测,请随意尝试另一种方法。
—参考—
[1] ICML 2018 论文深一类分类
[3] Scikit 学习文档
使用 Keras 简化影像分类的单一功能
我们一步一步地展示了如何构建一个单一的、通用的效用函数,从目录中自动提取图像,并训练一个卷积神经网络模型。
介绍
已经有很多关于深度学习框架的文章,如 Keras 和 PyTorch ,以及如何强大而简单地使用来构建和玩精彩的深度学习模型。
已经有很多关于模型架构和优化器的教程/文章——卷积的概念、最大池、优化器,如 ADAM 或 RMSprop 。
如果您想要的只是一个函数,从磁盘上的指定目录中自动提取图像,并返回给您一个完全训练好的神经网络模型,准备用于预测,会怎么样?

因此,在本文中,我们将重点讨论如何使用 Keras (TensorFlow) API 中的一些实用方法,通过适当的数据预处理来简化此类模型的训练(专门用于分类任务)。
基本上,我们想,
- 获取一些数据
- 将它们放在按类别排列的目录/文件夹中
- 用最少代码/fuss 训练神经网络模型
最后,我们的目标是编写一个单独的实用函数,它可以获取存储训练图像的文件夹的名称,并返回一个完全训练好的 CNN 模型。
数据集
在这个演示中,我们使用了一个由 4000 多幅花的图像组成的数据集。数据集可以从 Kaggle 网站下载。
数据收集基于 Flickr、谷歌图片、Yandex 图片等数据。这些图片被分为五类,
- 黛西,
- 郁金香,
- 罗斯,
- 向日葵,
- 蒲公英。
每个班级大约有 800 张照片。照片分辨率不高,320 x 240 像素左右。照片不是缩小到单一尺寸,它们有不同的比例。
然而,它们被整齐地组织在五个目录中,并以相应的类标签命名。我们可以利用这种组织并应用 Keras 方法来简化卷积网络的训练。
代码回购
完整的 Jupyter 笔记本在我的 Github repo 这里是 。随意分叉延伸,喜欢就给它一颗星。
我们将在本文中使用一些代码来展示重要的部分。
该不该用 GPU?
建议在 GPU 上运行该脚本(使用TensorFlow-GPU),因为我们将构建一个具有五个卷积层的 CNN,因此,如果您不使用某种 GPU,使用数千幅图像的训练过程可能会计算量大且速度慢。
对于 Flowers 数据集,在我配有英伟达 GTX 1060 Ti GPU (6 GB 视频内存)、Core i-7 8770 CPU 和 16 GB DDR4 内存的普通笔记本电脑上,单个纪元需要大约 1 分钟。
或者,你可以利用 Google Colab ,但是加载和预处理数据集可能有点麻烦。
数据预处理
内务处理和显示图像
请注意,笔记本代码的数据预处理部分的第一部分对于神经网络的训练并不重要。这组代码只是为了举例说明,并显示一些训练图像作为示例。
在我的笔记本电脑上,数据存储在比我的笔记本文件夹高一级的文件夹中。这是这个组织,

使用一些基本的 Python 代码,我们可以遍历子目录,对图像进行计数,并展示它们的示例。
一些雏菊的照片,

还有一些美丽的玫瑰,

请注意,图片的大小和长宽比各不相同。
构建ImageDataGenerator对象
这是真正的奇迹发生的地方。
ImageDataGenerator类的官方描述称“通过实时数据增强生成批量张量图像数据。数据将(分批)循环。
基本上,它可以用于通过大量内置预处理(如缩放、移位、旋转、噪声、白化等)来增强图像数据。现在,我们只是使用rescale属性在 0 和 1 之间缩放图像张量值。
这里有一篇关于这方面的有用文章。
结合 Keras 的 ImageDataGenerator 实现我们的自定义生成器的博客,以执行各种…
medium.com](https://medium.com/@arindambaidya168/https-medium-com-arindambaidya168-using-keras-imagedatagenerator-b94a87cdefad)
但是这个类在当前演示中的真正用途是超级有用的方法flow_from_directory,它可以从指定的目录中一个接一个地提取图像文件。
注意,这个目录必须是顶层目录,在这里各个类的所有子目录都可以单独存储。flow_from_directory方法自动扫描所有子目录,并获取图像及其相应的标签。
我们可以指定类名(就像我们在这里用classes参数做的那样),但这是可选的。然而,我们稍后会看到,这对于从大量数据中进行选择性训练是如何有用的。
另一个有用的参数是target_size,它让我们将源图像的大小调整到统一的 200 x 200,不管图像的原始大小是多少。这是一些很酷的图像处理,带有一个简单的函数参数。
我们还指定了批量大小。如果不指定batch_size,默认情况下,它将被设置为 32。
我们选择class_mode作为categorical,因为我们在这里做多类分类。
运行这段代码时,Keras 函数扫描顶层目录,找到所有图像文件,并自动用适当的类(基于它们所在的子目录)标记它们。

是不是很酷?
但是等等,还有更多。这是一个 Python 生成器对象 ,这意味着它将用于在训练过程中一个接一个地 生成数据。这大大减少了处理非常大的数据集的问题,因为数据集的内容不能一次放入内存。看看这篇文章可以更好地理解它,
生成器表达式是 Python 中一个有趣的特性,它允许我们创建延迟生成的可迭代对象…
towardsdatascience.com](/pythons-list-generators-what-when-how-and-why-2a560abd3879)
建立 conv 网络模型
正如所承诺的,我们不会花时间或精力去分析 CNN 模型背后的代码。简而言之,它由 5 个卷积层/最大池层和 128 个神经元组成,最后是 5 个神经元输出层,具有用于多类分类的 softmax 激活。
我们使用 RMSprop,初始学习率为 0.001。
这里又是代码。请随意试验网络架构和优化器。

使用' fit_generator' 方法进行训练
我们之前讨论过train_generator对象用flow_from_directory方法和它的参数做了什么很酷的事情。
现在,我们在上面定义的 CNN 模型的fit_generator方法中使用这个对象。
注意fit_generator的steps_per_epoch参数。由于train_generator是一个通用的 Python 生成器,它从不停止,因此fit_generator不知道一个特定的时期在哪里结束,下一个时期在哪里开始。我们必须让它知道一个时期内的步骤。在大多数情况下,这是总训练样本的长度除以批量大小。
在上一节中,我们发现总样本量为total_sample。因此,在这种特殊情况下,steps_per_epoch被设置为int(total_sample/batch_size),即34。因此,您将在下面的训练日志中看到每个时期 34 步。
部分培训日志…

我们可以用通常的绘图代码来检查准确性/损失。


好的。到目前为止,我们完成了什么?
我们已经能够利用 Keras ImageDataGenerator和fit_generator方法从单个目录中自动提取图像,给它们加标签,调整它们的大小和比例,并一个接一个地(成批地)流动它们来训练神经网络。
我们能把所有这些都封装在一个函数中吗?
将所有这些封装在一个函数中?
制作有用的软件/计算系统的中心目标之一是 抽象 ,即隐藏内部计算和数据操作的血淋淋的细节,并向用户呈现简单直观的工作界面/API。
作为实现这一目标的一种实践,我们可以尝试将上述过程封装在一个函数中。想法是这样的,

目标是用有用的参数实现灵活的 API
当你在设计一个高级 API 时,为什么不去做比这个特定的 flowers 数据集演示所需要的更一般化的东西呢?考虑到这一点,我们可以考虑为这个函数提供额外的参数,使它适用于其他图像分类情况(我们很快就会看到一个例子)。
具体来说,我们在函数中提供了以下参数,
train_directory:训练图像存储在单独文件夹中的目录。这些文件夹应该按照类来命名。target_size:训练图像的目标尺寸。一个元组例如(200,200)classes:一个 Python 列表,包含我们希望进行训练的类。这迫使生成器从train_directory中选择特定的文件,而不是查看所有的数据。batch_size:培训批量num_epochs:训练的次数num_classes:要考虑的输出类的数量verbose:训练的详细程度,传递给fit_generator方法
当然,我们可以提供与整个模型架构或优化器设置相对应的附加参数。本文并不关注这些问题,因此,我们保持它的简洁。
同样,完整的代码在 Github repo 中。下面,我们只展示了 docstring 部分,以强调使它成为一个灵活的 API,

测试我们的效用函数
现在,我们通过简单地提供一个文件夹/目录名来测试我们的train_CNN函数,并获得一个可用于预测的训练好的模型!
让我们还假设我们现在只想为“雏菊”、“玫瑰”和“郁金香”训练,而忽略其他两朵花的数据。我们简单地将一个列表传递给classes参数。在这种情况下,不要忘记将num_classes参数设置为 3。您会注意到,当训练样本的数量少于上述情况时,每个时期的步数会自动减少到 20。
另外,请注意,在上面的函数中,verbose默认设置为 0,因此,如果您想要按时段监控训练进度,您需要明确指定verbose=1!
基本上,我们现在能够用 2 行代码得到一个完全训练好的 CNN 模型!
该函数对另一个数据集有用吗?
这是对这种功能效用的严峻考验。
我们能不能不做太多修改就把它应用到另一个数据集?
加州理工学院-101
Caltech-101 是一个丰富且易于管理的影像分类数据集。我说的可管理的是指,没有 ImageNet 数据库那么大,它需要大规模的硬件基础设施来训练,因此超出了在笔记本电脑上快速测试酷想法的范围,但足够多样,可以练习和学习卷积神经网络的技巧和交易。

加州理工学院-101 是属于 101 个类别的不同类型的对象的图像数据集。每个类别大约有 40 到 800 张图片。大多数类别大约有 50 张图片。每个图像的大小大约为 300 x 200 像素。
这个数据集是 2003 年加州理工学院的费·李非教授和她的同事(马尔科·安德烈托和马克·奥雷利奥·兰扎托)建立的,当时她还是那里的一名研究生。因此,我们可以推测,加州理工学院-101 是她研究 ImageNet 的直接先驱。
用两行代码训练 Caltech-101
我们下载了数据集,并将内容解压缩到与之前相同的数据文件夹中。该目录如下所示,

因此,我们得到了我们想要的东西——一个顶级目录,其中包含包含训练图像的子目录。
然后,和之前一样的两行,
我们所做的就是将该目录的地址传递给函数,并选择我们想要为训练模型的图像类别。假设我们要训练模型在 【杯子】 和 【螃蟹】 之间进行分类。我们可以像以前一样将他们的名字作为列表传递给classes参数。
此外,请注意,我们可能必须显著减少该数据集的batch_size,因为与 Flowers 数据集相比,训练图像的总数将会低得多,并且如果batch_size高于总样本,那么我们将使steps_per_epoch等于 0,这将在训练期间产生错误。
瞧啊。该函数找到相关图像(总共 130 个)并训练模型,每批 4 个,即每个时期 33 步。

测试我们的模型
因此,我们看到了将训练图像的目录地址传递给函数并使用我们选择的类训练 CNN 模型是多么容易。
模型好吗?用网上下载的随机图片测试一下就知道了。
请记住,加州理工学院-101 数据集是由费李非和他的同事早在 2003 年创建的。因此,互联网上任何较新的图像都不太可能出现在数据集中。
我们随机下载了以下“螃蟹”和“杯子”的图片。



在一些基本的图像处理(调整大小和尺寸扩展以匹配模型)之后,我们得到了下面的结果,
model_caltech101.predict(img_crab)>> array([[1., 0.]], dtype=float32)
该模型正确预测了螃蟹测试图像的类别。
model_caltech101.predict(img_cup)>> array([[0., 1.]], dtype=float32)

该模型正确地预测了杯子测试图像的类别。
但是这个呢?
model_caltech101.predict(img_crab_cup)>> array([[0., 1.]], dtype=float32)
因此,该模型将测试图像预测为一个杯子。几乎是公平的,不是吗?
验证集和其他扩展
到目前为止,在fit_generator中我们只有一个train_generator对象用于训练。但是验证集呢?它遵循与train_generator完全相同的概念。您可以从您的训练图像中随机分割一个验证集,并将它们放在一个单独的目录中(与训练目录相同的子目录结构),并且您应该能够将它传递给fit_generator函数。
甚至还有一个用于ImageDataGenerator类的flow_from_dataframe方法,在这里您可以传递包含在熊猫数据帧中的图像文件的名称,然后训练可以继续进行。
请随意试验这些扩展。
摘要
在本文中,我们回顾了 Keras 的几个实用方法,它们可以帮助我们构建一个紧凑的实用函数,以便为图像分类任务有效地训练 CNN 模型。如果我们可以在一个公共目录下的子目录中组织训练图像,那么这个函数可能允许我们只使用几行代码来训练模型。
这很有意义,因为使用这些内置的类/方法和我们的实用函数,我们可以将代码/数据流完全保留在 Keras 中,并以紧凑的方式训练 CNN 模型,而不是使用其他库(如 PIL 或 Scikit-image)单独抓取和预处理图像。
如果你有任何问题或想法要分享,请联系作者tirthajyoti【AT】Gmail . com。另外,你可以查看作者的 GitHub 资源库中其他有趣的 Python、R 和机器学习资源中的代码片段。如果你像我一样对机器学习/数据科学充满热情,请随时在 LinkedIn 上添加我或在 Twitter 上关注我。
[## Tirthajyoti Sarkar - Sr .首席工程师-半导体、人工智能、机器学习- ON…
通过写作使数据科学/ML 概念易于理解:https://medium.com/@tirthajyoti 开源和有趣…
www.linkedin.com](https://www.linkedin.com/in/tirthajyoti-sarkar-2127aa7/)
我的数据科学转型之旅中的一个亮点
从童年开始,我就被视为铺设了一条有远见的道路,这条道路可以被兄弟姐妹追随,并得到长辈的赞赏。我的故事不是很英雄或者激励人心。只有我和“我的简单故事”。

在初中和高中时期,我是一个聪明勤奋的孩子。后来,我甚至准备了所有的入学考试,任何科学/数学专业的学生都会准备的。是的,我说的是 IIT-JEE!我对自己的目标很高(现在也是),但当时事情并没有很好地解决。我进入了一所颇有名气的政府工程学院。像其他学生一样,我不确定自己未来想做什么,所以工程是我的“首选”领域,也是一个安全的选择。它让我探索不同的领域。
但还是那句话,你必须有始有终。我对自己有不同的计划,但我必须为自己找到一个位置。这让我选择了 Python 语言 ,也让我从整体上更接近数据科学的概念。我脑子里有许多问题。我会比同龄人挣得少吗?我会有一个薪水不断上涨的快速职业生涯吗?还有什么不可以!但是,数据科学成了我的救星。就像一个真正的救世主,它帮助我走出混乱。

我选择 数据科学 的 原因不是出于直觉,而是因为数据的大规模指数增长。数据是推动行业发展的燃料。
“宁为玉碎,不为瓦全。”
我参加了 2-3 个月的线下培训,培训内容是 **Python 和数据科学。我在技术和非技术方面都学习过,但是我更喜欢非技术方面。它包括商业意识、沟通技巧和解决问题的策略。
渐渐地,Python 成为我在技术部分生存的力量【即数据预处理和数据分析】。我觉得数据科学比我所接触到的要多。我继续与我的同事和前辈讨论如何在这个庞大的领域进一步提高。然后,我决定通过线上培训开始学习 大数据 和 Hadoop 。我甚至有机会参加现场视频会议,并报道了各种项目来实践这一点。**********

抓住它需要时间。数学或基本上统计部分根本不是问题,但编程确实给我带来了一些缺点。为此,我开始使用各种在线代码练习网站,这些网站确实增加了我之前所学的内容。这些在不同平台和项目上的严谨实践完善了我的简历!我开始申请一些实习机会,为我一直在学习的数字增值。
最初,反响不太好,更确切地说,应该说没有任何反应。我学会了如何保持动力,激励我实现目标。我用一些“技术文献”来充实我的知识,例如——Python 速成班——作者 Eric Matthes,Peter Bruce 的《数据科学家实用统计学》,R-作者 Garrett Gorlemund 的《动手编程》,R . for Data Science and Learning SQL——作者 Alan Beaulieu。
虽然我不能全部完成,但它们确实为我之前所学的知识增加了一些实用性,并向我介绍了新技术,如和 SQL 。****
由于 在线课程 ,我对 Hadoop 和大数据很满意,也掌握得很好,所以我没有参考任何书籍。
但是,如果在学习过程中,你认为你需要关于这些技术的任何指导,你可以随时查阅《Hadoop—权威指南》和《实践中的大数据 Barnard Marr》**
后来,我用一些新项目更新了我的简历,这些项目涵盖了我所学到的最新技术。很快,我开始接到实习的电话。我参加了其中的一个“暑期培训/暑期实习”。这 75 天揭示了数据科学的本质以及当时获得的信息背后的现实意义。然后,我加入了大学的就业机会。
我所期望掌握的知识和我之前学习的课程直接刺激了我作为初级数据科学家的起步。这里的印象是,它通常不提供给新生。但是,我的项目工作和培训在我的职业生涯中起到了至关重要的作用。我遵循了我在训练期间学到的所有步骤,并在这里练习了几次。所有这些都让我在整个项目分配过程中更有效率。
我对使用哪种方法、应用哪种工具有了自己的想法和主意。学会区分什么是重要的,什么是不重要的。所有这些知识帮助我成为一名更有效的数据科学家。我认识到,在少数项目中取得成功或实现一个目标并不意味着你有权给自己贴上“有效”的标签。高效是一个持续的过程,它让你更谦虚地学习,并提高你的生产力。所有这些让我接触到了新项目,并帮助我每天都学到一些新东西。
我很早就意识到这一点,没有免费的午餐,如果你想在生活中得到什么,你必须全心全意地付出。要获得真实世界的经验,你需要:
a)找到你感兴趣的数据集,b)询问并尝试回答相关问题,c)记录结果,d)冲洗并重复以积累经验。
要称自己为真正的数据科学家,并有一个操纵它的“长期计划”,你必须铺平道路并创造你自己的身份【那种快乐的感觉是无法形容的:】。
简而言之,我们开始工作吧。
如何建立一个只有两栏的社交网络
好吧,如果你很挑剔的话,也许 3 张,如果你想让它真正有用的话,也许多几张桌子…
…但我的观点仍然成立。社交网络的本质可以很容易地存储在一个有两列的表中。
这篇文章的灵感来自于描述社交网络的复杂方式,尤其是在图表中,它让我思考如何简化它的想法,以便任何人都可以理解它。
让我们从概述什么是社交网络开始
简单来说,它是一个描述社会关系和互动的网络。他们在互联网出现之前就存在了。自从人类存在以来,事实上自从任何社会生物存在以来,城市、城镇、村庄和人们都有他们自己的小社会网络。
然而,一旦互联网允许社交网络被记录、存储和扩展,这个术语就爆炸了。
如今,你的社交网络可以不仅仅包括你认识的人,还包括你经常交往的人。它可以包括你从未谋面的人,或者仅仅通过网上交流认识的人。
想想就有点疯狂。
但是这些都不是新的。我们都很清楚这一点,但这些在线社交网络实际上在做什么呢?

Photo by Dương Hữu on Unsplash
它们存储了一个人(或者实体,如果你真的很迂腐的话)和另一个人之间的联系。
就是这样。只是两个人之间简单的联系。很多很多很多次。
这种规模就是为什么我认为我们把它们描绘成复杂的东西,但是如果你回到核心原则:存储两个人之间的联系,现在看起来并不太糟糕,对吗?
但是你说是两栏的表格,请解释一下…
…嗯,如果一个社交网络只是两个人之间的一个巨大的链接。那么你需要一种方法来存储两个人之间的链接。一种方法是创建一个表,存储代表每个人的两个用户标识符。
CREATE TABLE friend
(
user_id VARCHAR(64),
friend_user_id VARCHAR(64)
);
搞定了。
嗯,不完全是,但是你明白了。这个表现在可以很容易地存储两个用户之间的关系(我们称之为朋友)。
如果您想知道存储关系的顺序。如果是我设计的,我会把发起好友请求的人放在第一列,把他们请求的人放在第二列。
图遍历找朋友的朋友怎么样?
现在我们在谈话。现在我们来看看那些超级复杂的社交网络图片,它们让你大吃一惊。

A super complex social network: Image Source
让我们从简单的开始。
对于一个用户来说,找到他们的朋友,然后找到他们所有的朋友,这些朋友还不是最初用户的朋友。
所有的社交网络都是这样开始向你展示“推荐的朋友”或“你可能认识的人”。逻辑是,如果你认识一个人,你可能也认识同样的人。
SELECT user.user_id, friends.friend_user_id
FROM friend user
LEFT JOIN friend friends ON user.friend_user_id = friends.user_id
LEFT JOIN friend same_friends ON same_friends.user_id = friends.friend_user_id
WHERE a.user_id = 1 AND c.user_id IS NULL;
同样不太难。虽然我不想假装,当你想认识朋友的朋友的朋友等等的时候,它不会变得有点笨拙。
有趣的是,脸书遇到了同样的问题,并决定走图形数据库这条路。图形数据库旨在帮助解决这类问题,因为它们在构建时(显然)考虑了图形遍历。这使得询问更复杂的网络问题变得更加琐碎。
那么一个社交网络真的只是一个有两列的表格吗?
是也不是…
正如您所看到的,用一个表和两列来存储用户之间的关系是可能的。你甚至可以查询这些数据,并使用它们来查找推荐的朋友,以帮助用户建立他们的网络。
但实际上,你会希望它周围有很多额外的数据,以使它在现实世界中更有用。
首先,您将需要表来存储关于用户及其配置文件的数据。
你可能还想知道好友请求的概念,这样你就可以区分请求和真正的友谊。
您可能希望存储关于好友请求被发出和接受的事件的元数据。
然后扩展到构成社交网络的所有其他东西,包括帖子和赞——同样,赞只是用户和另一个实体之间的关系,更可能是用户和帖子之间的关系。
希望这种对社交网络世界的简化看法引发了一些思考,即简单的想法如何能很快变成一些最大和最强大的工具。
罪恶之歌:通过《权力的游戏》刻画总统候选人
作者:韦林多·曼格罗邦和米娅·伊瑟曼

Image by author
这个夏天,很多人对《权力的游戏》表达了强烈的意见——龙,浪漫,当然还有谁应该统治七大王国。事实上,你可能已经听过很多现实世界中的政治理由来解释这个故事中的事件——这个故事的背景是一个有龙和魔法存在的世界。粉丝们喜欢分析节目的政治,他们从第一季就开始分析了。
现实政治呢?希望每个对《权力的游戏》有强烈意见的人都同样关注即将于 2020 年举行的非虚构的美国总统选举。以防你对临冬城之战比对民主党辩论日程更感兴趣,我们用科学的方法整理了一份《权力的游戏》人物提名名单!
伯尼·桑德斯?更像伯尼·珊莎!詹德利——来自南方的好男孩,有一个令人困惑的同名者——那就是贝托!谁会在夜王再次召集他的僵尸大军之前最终击败他呢?艾莉亚·史塔克,又名伊丽莎白·沃伦!以下是目前民调超过 2%的总统候选人的完整名单以及他们对应的《权力的游戏》角色:拜登&乔恩、桑德斯&桑莎、沃伦&艾莉亚、Buttigieg &达沃斯、哈里斯&托尔蒙德、奥鲁克&詹德利、布克&吉利、克洛布查尔&乔拉。
如果到目前为止这感觉有点刺激,你没有错。本文的其余部分详细记录了创建我们的列表的过程。请继续阅读这些配对背后的科学,并随时查看我们的 Github 库。
获取和准备数据
我们使用 Reddit 注释和自然语言处理来创建映射。通过 Reddit API,以及来自这篇文章的一点帮助,我们将来自政治和权力的游戏子编辑的超过 30 万条评论保存到亚马逊网络服务关系数据库服务。
一旦我们有了一个很长的评论列表,我们需要将这些评论归属于特定的人。(出于我们的目的,“人物”既指虚构的人物,也指非虚构的被提名者。)为了做到这一点,我们创建了一个函数来检查评论数据帧中的每一行,将每条评论与一个人及其假名的字典进行比较,并记录该名字是否出现在评论中以给予该人信任。这被证明是非常耗时的,所以我们找到了一个更好的方法:矩阵!
使用 sklearn 的计数矢量器,我们将 324629 条评论和 114 个假名变成了一个矩阵。我们还为 114 个假名(例如卡丽熙和丹妮是同一个人)和 67 个人创建了一个 114 乘 67 的矩阵。然后,我们对这两个矩阵进行点积,得到每个人在评论行中的评论数:

An example of the dot product’s resulting matrix (Image by the author)
以情感和音量为特征的聚类
因为我们最感兴趣的是对每个角色进行分析,所以我们创建了一个矩阵,将人物作为第一列,将他们的特征作为其他列。我们使用维德来分析每个评论的情绪,并使用正面分数作为第一个特征,然后负面分数作为另一个特征。我们还使用 Reddit 的“投票率”(投票数除以投票数)、评论数和评论长度作为特征。sub_num_comments 列最终也用于根据所有的评论来查找特性的平均值。

Image by the author
如果我们使用无监督的 kmeans 聚类来查看不同的组是什么,我们会发现什么?最佳 k (3)并不比被提名者和其他被提名者组合在一起多多少,对角色也是一样。有趣的是,我们确实注意到,对人物的情感通常比被提名者更积极地被解读。

Image by the author
添加语义特征
在寻找更有吸引力的集群时,我们想要不同于用户情绪和数量的特性。如果我们看看角色的名字是如何相互关联的呢?为此,我们使用了 Gensim ,这是一个允许您“分析纯文本文档的语义结构”和“检索语义相似的文档”的工具我们就是这么做的!
我们使用所有的评论作为训练 word2vec 模型的语料库,该模型将单词转化为向量。然后,我们使用 Gensim 的最相似特征(利用余弦相似度)将这些人与“总统”、“宝座”和“领袖”进行比较。当我们使用这些特性重新聚类( k =6)时,我们得到了稍微有趣一些的结果,但是它仍然没有给我们两个不同领域中的自然重叠。

Image by the author
使用相似性得分进行匹配
很明显,我们需要变得更笨手笨脚,以实现我们的点击诱饵目标,将《权力的游戏》中的人物与总统候选人匹配起来。所以,我们把情感和数量抛到了九霄云外,只使用最相似的相似度分数。为了简化我们的分析,我们决定只关注前 8 名被提名者,即当时民调支持率超过 2%的人:拜登、桑德斯、沃伦、Buttigieg、哈里斯、奥罗克、布克和克洛布查尔。

Hodor — not a politician! (Image by the author)
为了创建我们的最终排名,我们按照投票顺序查看了被提名者,并将他们与最匹配的角色配对。拜登&乔恩,桑德斯&桑莎,沃伦&艾莉亚,布蒂吉格&达沃斯,哈里斯&托尔蒙德,奥鲁克&詹德利,布克&吉利,克洛布查尔&乔拉。
你有它!你怎么想呢?你会做些不同的事情吗?请在评论中给我们留言。
此外,不要忘记投票,否则你不会比《权力的游戏》更好。
使用网络摄像头扫描条形码的独立应用程序
在购物商店开发经济高效的自动化计费流程的一步
什么是条形码阅读器
当你逛任何一家购物中心或商店时,你一定见过条形码检测机(见图 1,图片来源 flickr ),它能读取你购买的商品的条形码并计算出价格。最后,你会得到一张购物收据,上面有你所购买的物品以及每件物品的价格。在购物中心使用条形码扫描仪在很大程度上减少了文书工作和数字化购物。然而,它仍然需要人的努力。

Figure 1: A typical bar code scanner
另一个问题是,它的成本很高。变化和耐久性也是这种条形码扫描仪的一个问题。因此,有必要开发这样一种系统,它能使扫描产品的过程自动化,并且成本低,维护要求低。
在这篇文章中,使用 python 开发了一个条形码扫描仪,它可以使用网络摄像头读取产品的条形码,解码条形码中加密的项目的成本,并计算产品的价格,最后在购物结束时,您将获得您购买的项目数量、购买日期、购买项目的名称和相应的成本。发现开发的系统具有成本效益,耐用,易于使用,完全自动化的计费过程,即不需要人工扫描条形码。
条形码生成
现在,python 中有许多标准库可以用来创建条形码。我用过 pyBarcode 。它可以提供 EAN-8,EAN-13,EAN-14,UPC-A,JAN,ISBN-10,ISBN-13,ISSN,Code 39,Code 128,PZN 类型的标准条形码。要安装 pyBarcode ,请使用 pip 作为
*pip install pyBarcode*
一旦安装了 pyBarcode ,运行以下四行代码来创建条形码图像。这将在中保存条形码图像文件。svg 格式。不过也可以另存为。以下代码中的与略有变化,摘自此处的。
>>>import barcode
>>>EAN = barcode.get_barcode_class('ean13')
>>>ean = EAN(u'5901234123457')
>>>fullname = ean.save('ean13_barcode')
上述代码将以欧洲商品编号(ean)标准保存条形码。您可以根据选择更改标准。使用 python 脚本生成的条形码如图 2 所示。

Figure 2: Generated barcode using python script
或者,您可以从互联网上免费下载任何软件来生成条形码。我用的工具是从这个网站下载的。您只需要在(可选)条形码的上方和下方设置数据和文本。您还可以设置条形码图像的宽度和高度,并将其提取为。 png 或储存在 excel 中。在我的应用程序中,我使用了 CODE 128 标准,并将图像提取为。 png 。使用软件工具生成的条形码如图 3 所示。

Figure 3: Barcode generate using software.
类似地,我为四个产品(两本书、一个计算器和一个计算机鼠标)生成了条形码,将这些条形码打印出来并粘贴到产品上。经过这些步骤,我的四个产品看起来像,如图 4 所示。

Figure 4: Barcode stick on products under consideration
因此,通过这种方式,您还可以为您的购物商店创建自己的产品条形码。
条形码扫描
在这里,我开发了一个 python 应用程序来读取我创建的条形码,并使用网络摄像头解码数据。该脚本初始化实时视频流,并从视频中提取每一帧。它通过模糊帧来寻找边缘。双边滤波器或高斯滤波器可用于此目的。然后采用自适应阈值获得处理后的图像。在形态学操作之后,围绕条形码绘制轮廓。所有这些步骤都由 pyzbar 的解码对象负责。因此,在执行程序之前,确保您已经安装了 pyzbar ,可以使用 pip as 安装
*pip install pyzbar*
对于剩余的过程,请从 GitHub 库下载完整的代码,并按照 readme 中提到的步骤进行操作。
工作原理:
条形码中加密的数据(产品成本)是产品名称及其成本的组合。例如,物品计算器条形码的数据被设置为 C4,其中“C”被视为物品 ID ( C 计算器),而“4”被视为以美元为单位的物品成本。对于每个扫描的项目,应用程序记录购买日期,购买的项目 ID 和项目成本。一旦我们按下按钮“e”退出条形码读取过程,应用程序会添加每一个购买项目的成本,并显示最终的购物成本。完整过程的演示视频显示在这里。
Demo of the execution of barcode reader script using webcam
优点
- 这种应用可以被认为是成本有效的,因为与条形码阅读器的成本相比,网络摄像头的成本非常非常低。
- 它非常容易操作,也不需要人力,因为网络摄像头可以固定在某个位置,客户只需要将要购买的商品面向网络摄像头的条形码。
- 与条形码阅读器相比,网络摄像头更耐用,即使出现问题,也很容易修复。
- 这个应用程序可以用在购物中心和小商店,以自动化计费过程。它也可以用来开发类似的应用程序,如在图书馆,一本书可以分配给学生使用条形码扫描系统。
挑战
- 如果条形码尺寸较小,或者网络摄像头和条形码之间的距离过大,则系统无法扫描条形码。
这个应用程序也可以用来读取二维码与矿工改变代码。您可以下载代码并创建自己的条形码,根据您的要求设置产品成本。最后,您将拥有一个适用于您的商店/购物店的自动计费流程的完整应用程序。感谢 Jayeeta Chakraborty,他帮助我开发了这个项目。希望这个应用程序可以帮助研究人员和开发人员开发定制的条形码扫描仪。
A 星(A*)搜索算法

Image from Pixabay and created by Author
分步编码的 A-Star 搜索算法
通过最短的路线到达目的地是我们每天都在做的事情。A-star(也称为 A*)是寻找节点或图之间最短路径的最成功的搜索算法之一。这是一种有根据的搜索算法,因为它使用关于路径成本的信息,并且还使用启发式来找到解决方案。
在本文中,我将重点介绍如何使用简单的 python 代码构建 A-star (A*)搜索算法。我发现许多文章和博客都非常关注理论,但没有太多关于这个项目的信息。我在这里尝试用易于理解的细节一步一步地展示代码。
首先,让我们先来点理论热身。
A*实现 最优性 和 完备性 ,搜索算法的两个有价值的性质。
当搜索算法具有最优性时,意味着保证找到最佳可能解。当一个搜索算法具有完备性的性质时,意味着如果一个给定问题的解存在,该算法保证找到它。
为了理解 A*的工作原理,我们首先需要理解几个术语:
- 节点(也叫状态 ) —所有潜在的位置或停止点都有唯一的标识
- 转换 —在状态或节点之间移动的动作。
- 开始节点— 从哪里开始搜索
- 目标节点— 停止搜索的目标。
- 搜索空间 —节点的集合,就像棋盘游戏的所有棋盘位置
- 成本 —从一个节点到另一个节点的路径的数值(比如距离、时间或财务费用)。
- g(n) —这代表从起始节点到任意节点 n 的路径的 精确成本
- h(n) —这代表从节点 n 到目标节点的启发式 估计成本 。
- f(n) —邻居节点 n 中的最低成本
每次 A*进入一个节点,它计算到达所有相邻节点的成本 f(n)(n 是相邻节点),然后进入 f(n)值最低的节点。
我们使用以下公式计算这些值:
f(n) = g(n) + h(n)
这里我们将解决一个迷宫问题。我们必须在迷宫中找到从起点到终点的最短路径。

- Left: Maze problem 2) Right: Position of every node (2D NumPy array positions) of the Maze (Image by Author)
对于这个问题,如果有一个有效的步骤可用,从迷宫位置有四个移动(左,右,上,下)。在红色方块位置,不允许移动(像在开始位置,只有向下的运动是可用的,因为向上和向左的移动被墙阻挡,而对于右边是红色方块位置,因此不允许移动)。
我采用了来自这里和这个博客的代码,这是一个极好的信息来源。如果你需要更清晰的理论和解释,请阅读帕特里克·莱斯特在 A*上的文章。
首先,我们将创建下面的类和帮助函数:
(1) 类“节点”可用于为每个节点创建一个对象,其信息为父节点、迷宫中的当前位置和成本值(g,h & f)。
(2)我们需要定义一个路径函数,它将返回从 A*开始到结束节点的路径
我们将建立一个搜索函数,它将驱动代码逻辑:
(3.1)初始化所有变量。
(3.2)将起始节点添加到“尚未访问列表”定义停止条件以避免无限循环。用相对位置来定义运动。
重复以下步骤,直到满足停止标准:
(3.3)在“尚未访问列表”中寻找 f 成本最低的方块这个方块成为当前的方块。我们还检查是否达到了最大迭代次数
(3.4)检查当前方块是否与目标方块相同(意味着我们已经找到路径)
(3.5)使用当前正方形并检查与该当前正方形相邻的四个正方形,以更新子节点。如果它是不可移动的,或者如果它在“已访问列表”中,忽略它。否则,以父节点作为当前节点创建新节点,并更新节点的位置。
(3.7)检查创建的所有子节点以查看
如果它不在“尚未访问列表”中,请将其添加到“尚未访问列表”使当前方块成为该方块的父方块。记录正方形的 f、g 和 h 成本。
如果它已经在“尚未访问的列表”中,使用 g 成本作为度量,检查一下到那个方块的路径是否更好。较低的 g 成本意味着这是一条更好的路径。如果是,将方块的父方块更改为当前方块,并重新计算方块的 g 和 f 分数。
(4) 主程序:我们将定义迷宫、起点和终点位置。然后,我们将使用搜索功能,如果路径存在,我们可以从路径功能打印路径。
现在,我将一步一步地检查代码中的上述步骤(参考括号中的数字)。
首先,我们将为一个节点创建一个类,该类将包含与该节点相关联的所有属性,如节点的父节点、节点的位置以及该节点的所有三个成本(g、h & f)。我们初始化该节点,并构建一个方法来检查该节点与另一个节点是否相等。

Image by Author
现在我们将构建 path 函数,它将用于返回从起始节点到目标节点(结束节点)的路径。

Image by Author
现在我们将定义搜索函数,它有多个步骤。第一步是初始化我们将在函数中使用的节点和列表。

Image by Author
将起始节点添加到“尚未访问列表”定义停止条件以避免无限循环。根据相对位置定义移动,这将用于查找子节点和其他相对位置。

Image by Author
现在我们通过比较所有 f 成本并选择成本最低的节点进行进一步扩展来使用当前节点。我们还检查是否达到了最大迭代次数,设置一个消息并停止执行(避免无限循环)

Image by Author
从“尚未访问列表”中删除所选节点,并将该节点添加到已访问列表中。现在我们检查是否找到了目标方块。如果我们已经定位了目标方块,那么调用 path 函数并返回。

Image by Author
对于选定的节点,找出所有子节点(使用移动来查找子节点)。获取所选节点的当前位置(这将成为子节点的父节点)
a)检查是否存在有效位置(边界墙将使少数节点无效)
b)如果任何节点位置无效(红色方块),则忽略该位置
c)添加到所选父节点的有效子节点列表中
在图中,我们显示黑色圆圈节点是当前节点,绿色圆圈节点是正确的子节点。

Image by Author
对于所有子节点:
a)如果子节点在已访问列表中,则忽略它,并尝试下一个子节点。
b)计算子节点 g、h 和 f 的值。对于 h 启发式算法,此处使用欧几里德距离计算当前节点到达目标节点的成本。
c)如果孩子在“尚未访问列表”中,则忽略它,将孩子移至“尚未访问列表”

Image by Author
现在,最后,我们将运行迷宫的主程序,并获得路径。参考同样使用箭头显示的路径。

Image by Author
结论
A-star (A)是人工智能中一个强大的算法,有着广泛的用途。然而,它只能发挥它的启发功能(考虑到问题的性质,它可以是高度可变的)。A是寻路最流行的选择,因为它相当灵活。
它已经在许多软件系统中找到应用,从机器学习和搜索优化到游戏开发,其中角色通过复杂的地形和障碍到达玩家。
你可以在这个 GitHub 仓库中找到完整的代码。
感谢阅读。你可以在 LinkedIn 上和我联系。
每月只需 5 美元,就可以无限制地获取最鼓舞人心的内容……点击下面的链接,成为一名媒体会员,支持我的写作。谢谢大家!
星巴克案例研究:优化顾客与促销的匹配

Photo Credit: Adrianna Calvo
简介
销售活动是用来促进短期销售的营销工具。成功取决于针对正确的客户进行正确的促销。设计不佳的销售活动会让公司付出代价;例如,收入可能会以奖励的形式流失。这意味着,每次公司发起销售活动时,必须仔细考虑奖励的形式——做出该决定所需的关键信息是:1)不同类型促销的预测销售增长,以及 2)了解特定客户对不同促销广告的反应。像星巴克这样的大型零售商在美国有近 14000 家店铺,为数百万顾客提供服务,一场糟糕的促销活动的代价可能是巨大的。
在这篇文章中,我将使用从星巴克的一个实验(见下文)中收集的数据来分析顾客对不同促销的反应。在星巴克,大多数销售活动都是通过互联网进行的,这些促销活动可以分为三类:
- 折扣
- 买一送一(BOGO)
- 信息(例如,新产品或季节性产品)
如果星巴克的老顾客在促销期间花的比她多,促销活动就成功了。如果一个星巴克常客在此期间不改变他的消费行为,销售活动就有让公司付出代价的危险。据估计,星巴克拥有 2300 万“星巴克移动应用”会员,以及关于这些客户的人口统计数据、收到的促销和购买记录的大量数据。通过结合几种数据分析技术,我将回答以下问题(概述了每个目标的简要方法):
1。细分客户群。对于不同类别的销售活动,我们能否将客户分为有响应的和无响应的客户?
我将设计功能,并手动将客户分为两组:一组不响应促销,另一组响应促销。反应迅速的顾客是在促销期间在星巴克消费增加的顾客。
2。预测新客户行为。给定之前没有星巴克购买记录的顾客的基本资料(年龄、收入、性别、会员日期),我们能否预测他或她对某种促销活动的反应?
根据现有的客户人口统计数据(性别、年龄、收入和会员资格),我将使用机器学习来建立一个预测模型,以帮助预测新的星巴克会员是否会成为特定促销类别的响应客户。
3。识别成功促销的特征。与成功的销售活动相关的一些特征是什么?
使用探索性数据分析(EDA),我将确定成功促销中的常见特征。
术语
促销子类型可以归入三个类别之一:1)折扣,2) BOGO,或 3)信息。例如,促销子类型“花 10 美元减 2 美元”和“花 20 美元减 5 美元”都属于折扣类别。
在折扣类别中,客户在消费一定金额后会获得小额奖励(例如,消费 10 美元可获得 2 美元的折扣)。在 BOGO 类别中,顾客支付一件商品的全价,并免费获得第二件商品。在“信息”类别中,不提供金钱或奖励,但会通知客户关于新产品或季节性产品的信息。
单个报价是发送给客户的广告,宣布促销子类型。
销售活动是在给定时间向客户群发送多个单一报价的行为。
星巴克的实验
在星巴克进行的这个实验中,收集了六个销售活动的数据。在第 1、8、15、18、21 和 24 天宣布了销售活动。在每次销售活动中,大约有 12700 个单次报价(大约。每个子类型 1270 个单个报价)被发送给随机选择的客户。总共有十个促销子类型可用:四个属于折扣类别,四个属于 BOGO 类别,两个属于信息类别。
数据集
三个数据集可用: 作品集 , 成绩单 ,以及 简介 。
Portfolio 包含星巴克提供的所有促销类别和子类型的参考列表。
抄本 记录客户的交易历史,发送给客户的单笔报价的数量和子类型,并提供分析单个客户行为所需的数据。通过一个月的过程收集抄本数据。
简档 包含关于客户的人口统计信息(例如,性别、年龄、收入和会员资格期限),并且当与从抄本数据导出的信息相结合时,可以用于构建客户行为的预测模型。
数据清理
对 组合 、 抄本 、 概要 数据集的部分特征进行了数据清理。
在 组合 中,“渠道”和“报价 _ 类型”被转换为虚拟特征。
在 抄本 中,“事件”被转换为虚拟特征。在“值”中,条目格式根据描述的事件类型而有所不同。我把这些条目分成不同的特征。如果该值反映了单个要约事件(例如,已接收、已查看或已完成的要约),则将对应于该单个要约的子类型的 id 输入到名为“ID”的新特征列中。如果该值反映了一个事务事件,则事务金额被输入到一个名为“transaction_amount”的新特性列中
在 轮廓 中,加工了几个特征。在“年龄”功能中,2175 名客户被列为 118 岁(可能是未透露年龄的客户的默认条目)。我将年龄列中的所有 118 个值转换为 NaN 值。在“成为会员”功能中,客户成为星巴克会员的日期以八位数格式记录(例如,20180726 表示 2018 年 7 月 26 日)。我将其转换为自八位数参考日期以来客户成为会员的总天数,并将该特性重命名为“tension _ length”。“性别”被转换为虚拟特征。
数据分析
1。细分客户群。
在这里,我将执行数据处理和特征工程,针对每种促销类别(折扣、BOGO、信息),将响应客户与非响应客户进行细分。回应型顾客是指在促销期间收到一个报价,并以比平时在星巴克消费更多的钱来回应的顾客。
基于交易和单个报价(例如,收到的报价、查看的报价或完成的报价)数据,我确定了客户在促销和非促销期间的每小时支出(SPH)(见下文),并使用设定的比率(促销-SPH/非促销-SPH)来确定响应客户。用于计算比率的几个指标定义如下:1)异常值,2)感知时间(客户感知促销的时间长度),以及 3)每个促销类别的 SPH。
度量标准。
- 极端值
在星巴克,主要产品是饮料和糕点,大多数交易金额低于 50 美元(见图 1-A)。然而,一小部分交易金额大得惊人(例如,一次付款超过 1000 美元,图 1-B)。这些大额交易可能是餐饮订单,不太可能受到促销的影响,因此不在此处分析。

Figure 1. Histograms of transaction amounts for normal transactions (A) and outlier transactions (B). Note that x an y axes are scaled differently between (A) and (B)
要被视为异常交易,交易金额必须高于由截断四分位数间距(IQR)方法确定的阈值。如果 IQR 得出的阈值低于 50 美元,那么我使用 50 美元作为阈值。
截断的 IQR 是通过首先将客户交易从高到低排序,然后删除前 20%的记录而得到的。这有助于避免人为的高 IQR。阈值是通过第一个四分位数(Q1)值以上的 IQR 值的两倍来计算的(阈值= 2 * IQR + Q1)。
2)意识时间
重要的是要确定顾客知道一次促销活动的时间长度,因为这是顾客的购买行为可能受到促销活动影响的时期。
对于折扣和 BOGO 类别,知晓时间是指客户查看报价的时间,即 1)客户完成报价(即购买)或 2)报价到期(即没有购买)。对于“信息”类别,知晓时间是指客户查看报价的时间到报价到期的时间。
3)每小时支出(SPH)
促销-SPH 按类别(折扣、BOGO 或信息)计算,并定义为:
知晓时间内所有正常交易的总和/属于某一类别的所有单个报价的知晓时间总和
例如,为了计算客户的 SPH 折扣,将在知晓时间内发生的所有正常交易的总和除以属于折扣类别的单个报价的知晓时间总和。
非促销 SPH 的定义是:
非知晓时间内所有正常交易的总和/非知晓时间的总和
所有 SPH 计算都排除了异常值。
识别响应的客户。
对于给定的促销类别,客户是否可以被归类为响应客户取决于(促销-SPH/非促销-SPH)比率。如果(促销-SPH/非促销-SPH)比率高于 1.04(针对折扣)、1.12(针对 BOGO)和 1.00(针对信息),则认为客户对特定促销类别做出了响应。
这里有一个例子。

Table 1. Hypothetical transcript data of a customer.
假设一个客户收到了折扣类别中的单个报价(事件 A,表 1),查看了单个报价(事件 C),进行了三次交易(事件 B、D、E 和 F),并完成了报价(事件 G)。交易 B 发生在知晓时段之外,将被排除在 SPH 促销计算之外。交易 F 被确定为异常值,将从促销 SPH 计算中排除。交易 D 和 E 发生在 aware 时段,将予以考虑。
在本例中:
折扣-SPH =(事件 D 交易金额+事件 E 交易金额)/(事件 G 时间戳-事件 C 时间戳)
= ($3.00 + $6.00) / (100–50)
=每小时 0.18 美元
如果该客户的非促销 SPH 为每小时 0.10 美元,则(折扣-SPH/非促销-SPH)比率将为:0.18 美元/ $0.10 = 1.80 美元
由于响应客户的“通过”(折扣-SPH/非促销-SPH)比率为 1.04,我将该客户确定为响应客户。
探索性数据分析(EDA)。
快速浏览一下响应型客户和 简档 【性别】、【年龄】和【收入】中的可用特征之间的可能关系,可以发现客户是否是响应型客户(参见图 2 中使用“年龄”特征的示例)。“任期长度”似乎显示了积极响应之间的微小差异(图 3 )。

Figure 2. Histograms showing similar “age” distribution for responsive vs. non-responsive customers. Histograms for “gender” and “income” also show no notable differences between responsive vs. non-responsive customers.

Figure 3. Histogram of “tenure_length” for responsive vs. non-responsive customers.
评论。
这里没有使用复杂的预测算法,但是基本的数据处理和分析可以有效地将客户群分为响应客户和非响应客户。
2。预测新客户行为。
在这里,我将使用机器学习来建立一个模型,用于预测新客户对特定促销类别(折扣、BOGO、信息)的反应。新客户是一个新的“星巴克移动应用程序”成员,具有基本的个人资料数据,但没有与星巴克的先前交易记录。基于这些客户的档案数据,我建立了三个分类器模型(每个促销类别一个)来预测一个新成员是否会成为某个促销类别的响应客户。
初始算法扫描。
对包括逻辑回归、线性判别分析、K-最近邻、支持向量机(SVM)、AdaBoost (Ada)、随机森林(RF)和 XGBoost (XGB)在内的七种算法的初始扫描显示,RF 具有最佳性能。F1 分数用于评估性能,因为它反映了第一类和第二类错误。
如果出现第一类错误,意味着一个响应客户被预测为一个非响应客户,那么响应客户的数量将被低估。如果销售活动是基于具有这种误差的预测模型设计的,那么星巴克促销的奖励可能被设置在不能最大化潜在销售促进的水平。
如果出现第二类错误,意味着一个非响应客户被预测为响应客户,那么响应客户的数量将被高估。如果销售活动是基于有这种误差的预测模型设计的,更多的顾客将享受促销的回报,而不会促进销售,星巴克可能会损失收入。
优化模型超参数。
来自 Ada、SVM、RF 和 XGB 的最佳性能模型得到了优化。折扣和 BOGO 的优化模型显示没有改善,而信息模型显示略有改善。
性能。
收集了折扣(0.65)、BOGO (0.67)和信息(0.53)测试集的 F1 分数。
重要特征。
“任期长度”被认为是区分所有促销类别的响应客户和非响应客户的最重要特征。但是由于“任期长度”对于任何新客户来说总是零天,所以这个特性不是一个有用的区分指标。“年龄”、“性别”和“收入”不是区分特征。
评论。
给定新客户的基本概况信息,无法使用机器学习模型预测客户与促销的匹配。可能会收集其他特征,如客户的职业、教育水平或位置,以帮助开发更有效的预测模型(尽管额外的数据收集可能会降低客户的用户体验)。
3。识别成功促销的特征。
这里我使用数据处理来确定推广子类型的成功率。成功的单次优惠必须满足以下标准:1)交易发生在单次优惠被查看之后,以及 2)客户花费的金额高于促销优惠所要求的金额。
促销子类型的成功率计算方法如下:
成功单笔报价数 /总单笔报价数
探索性数据分析(EDA)。
计算了所有十个推广子类型的成功率,范围从 17.5%到 61.0%,没有显示出对推广类别的显著依赖性(参见表 2 )。此外,还计算了要约子类型特征和成功率之间的点双列相关(图 4)。

Figure 4. Selected point biserial correlations of offer sub-type features and the success rate.

Table 2. Ten sub-types and their id’s, selected features (“purchase requirement,” “channel”), and projected success rate.
选择何种渠道(即社交媒体、移动应用、网页和电子邮件)提供单一优惠是成功促销的决定性因素(参见图 4 )。对于每一个子类型,一套固定的渠道被用来发出单一的报价,那些通过社交媒体和星巴克移动应用程序分发的成功率最高。
成功率也与较低的购买要求相关;也就是说,在奖励生效之前,客户支付的金额越少或购买的商品越少,促销就越成功(见图 3 )。例如,在给予“20%奖励”的基础上,要求客户“花 5 美元减 1 美元”的子类型优惠将比“花 20 美元减 4 美元”的促销更有效。
评论。
一次成功的促销可以归入任何类别,但高成功率的决定因素是发送单一优惠的渠道选择和奖励障碍。
建议星巴克采取的行动
下面列出了一些在促销期间提升短期销售额的建议措施。
1.为了最大限度地提高客户响应:
- 从现有会员处收集特定时间段的数据,确定单个客户的客户-促销类别匹配,并相应地发送单个报价。
2.预测新客户行为:
- 当新顾客注册成为星巴克会员以测试可能有助于顾客-促销匹配的可能特征时,在简档部分中可能要求附加数据(例如,职业、教育水平、位置)。
3.要最大限度地提高单次报价的成功率:
- 通过社交网络和移动应用程序发送单个报价。
- 提供折扣和 BOGO 促销,购买要求低。
下一步是什么?
可以做的一个有趣的实验是,发出邀请客户“选择你自己的促销”的单个报价。例如,单个报价可能包含使用折扣子类型、BOGO 子类型的选项,或者获得新的或季节性产品的第一视图。因为客户有“选择”的权利,所以像这样的促销将吸引客户,并揭示每个客户喜欢什么的洞察力,从而有助于改善客户与促销的匹配。可能是一个有趣的想法来测试?
谢谢你看我的帖子。请参见我的 GitHub 库了解这里介绍的工作细节。
回答技术面试中任何问题的循序渐进的方法
在分析和数据科学领域工作的 4 个建议——一个可以利用的框架
任何求职者都知道,整个过程中最紧张的部分几乎肯定是令人恐惧的求职面试!如果你想从事分析方面的职业,那么面试过程会有一系列独特的考验和磨难。但是就像生活中的任何事情一样,你能做的最好的事情就是做好准备。
这篇文章将帮助你做好准备——我们将解释从分析面试中可以期待什么,以及你如何最好地准备。

Image from Unsplash
对于分析领域的大多数职业来说,公司希望你能够很好地编码,或者至少足够好地了解语法,使它不会成为你日常工作的障碍。因此,虽然这些技能通常会受到考验,但这并不是面试官关注的唯一技能。除了技术部分(即编码部分),您可能还需要解决一个“用例”,这是一个他们经历过的问题,一个假设的问题,或者一个他们正在积极尝试解决的问题。
他们不仅测试你解决问题的方法,也测试你解决问题的方法。
成功的步骤
1。关注方法而不是代码
更多的重点通常放在你的方法和途径上,而不是代码本身是否 100%正确
这里需要注意的是,他们不只是在寻找你的解决方案。他们希望看到你解决问题的方法,以及你与主题相关的扎实的技术基础。即使是错误的解决方案,如果您向他们介绍一下您是如何做到这一点的,他们也会留下深刻印象。
你需要向他们展示你理解方法论和你需要做出的潜在的假设来达成解决方案。因此,您需要向他们介绍您所做的假设,以及您做出这些假设的原因。例如,你对用户数量有什么假设?
你还必须思考和解释支撑你的方法论的数学。思考在这种情况下,什么会影响您正在处理的指标,并告知您了解导致这些变化的原因。
如果你还看不到,沟通是贯穿所有这些建议的关键变量。在解释你的方法时,你需要表现出对形势的充分把握。解释你对问题的假设,以及你对解决方案的假设。

Image from Unsplash
2.在代码上注重细节,但只有在被问到的时候
证明你的技术基础足以胜任手头的工作
在工作面试问题中,你经常会看到一段代码,希望你能分析它或者改正错误,从而解决问题。这就是显示你注重细节的极端重要的地方。然而,在这部分之前,你最有可能关注的是解决问题的方法和途径,所以先参考上面的提示 1。
你应该引导面试官完成这个问题的每一部分。看着语法,向面试官解释每个代码块要实现什么。从这里开始,您将能够对这段代码要实现的目标有一个“大致的了解”,并理解可以添加(或删除)什么来实现一个适当的解决方案。
一旦你恰当地解释了整个代码,以及你解决问题的方法,带面试官看一下你认为的解决方案是什么。

Image from StrataScratch, with permission from founder
如您所见,解决方案很重要,但如何实现同样重要。如果面试官能看到你的思维过程,看到你基本上是在正确的轨道上,对所涉及的方法论有着坚实的理解,他们会更愿意原谅你的错误。
3.想想边缘案例
向他们证明您可以将业务问题与技术解决方案联系起来
在编码中,理解边缘案例总是很重要的,工作面试也不例外。
想一想你认为准则可能会被打破的情况,并与你的面试官交流。
如果您能够将这些边缘案例与他们在业务中实际遇到的特定场景联系起来,将会非常有帮助。这是一个很好的机会,不仅可以展示你的编码知识,还可以展示你对他们业务的理解。
然后,一旦你确定了这些潜在的边缘情况,建议一些方法来解释它们,这样问题就不会发生了。一旦你清楚地识别出潜在的问题,解决方案总是更容易达成。这是你向面试官展示你总是在思考潜在的问题领域,并且能够解决它们的机会。
4.不要接受明显的事实!
它们是用来绊倒你的
在面试中出现的任何问题,永远记住不要接受显而易见的答案!如果它是显而易见的,它可能不会在工作面试中作为一个问题给你。
这就是为什么考虑上面的建议如此重要。考虑呈现的每个细节,寻找代码中的漏洞,并考虑真实的业务边缘案例。通过沟通所有这些,你将有可能确定问题所在,并从那里你可以建立一个解决方案。
记住,这是一个需要解决的复杂问题,否则,他们不会给你看。如果你一开始很纠结,慢慢来,陪面试官看一遍,反正他们想看你的思维过程。
帮助您成功的结论和资源
我们无法确切地告诉你在求职面试中会遇到什么问题。但是通过考虑以上所有的建议,你可以制定一个可靠的策略来解决你可能遇到的任何问题。
如果你想对你的编码进行一些额外的练习,看看过去的一篇关于学习 SQL 和 Python 的最好平台的文章。
如果你面试的是一个涉及编码的分析职位,那么编码几乎应该成为你的第二天性。面试官更感兴趣的是你如何分解问题,如何识别需要改进的地方,以及如何找到解决方案。他们还希望看到你了解他们的业务,这意味着考虑具体的优势案例和可能与他们经营的竞争环境相关的相关因素。

Image from StrataScratch, with permission from founder
所以你有它,慢慢来,彻底,但最重要的是沟通你的整个思维过程。
祝你好运!
最初发表于T5【https://www.stratascratch.com】。
使用 Seaborn / Matplotlib 创建高级 Python 数据可视化的分步指南
尽管 Python 中有大量优秀的可视化工具,Matplotlib + Seaborn 仍然因其创建和定制各种绘图的能力而脱颖而出。

Photo by Jack Anstey on Unsplash
在本文中,我将首先浏览几个部分,为一些不熟悉 Matplotlib 的读者准备背景知识:
- 了解两个不同的 Matplotlib 接口(已经造成了很多混乱!) .
- 理解图中的元素,这样你就可以很容易地查找 API 来解决你的问题。
- 看一下几种常见的情节类型,这样读者会对何时/如何使用它们有更好的了解。
- 学习如何增加你的情节的“维度”。
- 了解如何使用 GridSpec 对图形进行分区。
然后我将通过一个例子来讨论创建高级可视化的过程:
- 树立一个目标。
- 准备变量。
- 准备可视化。
让我们开始旅程吧。
两个不同的 Matplotlib 接口
在 Matplotlib 中有两种编码方式。第一个是基于状态的:
import matplotlib.pyplot as plt
plt.figure()
plt.plot([0, 1], [0, 1],'r--')
plt.xlim([0.0, 1.0])
plt.ylim([0.0, 1.0])
plt.title('Test figure')
plt.show()
这有利于创造简单的情节(你称之为一堆 plt。XXX 来绘制图形中的每个组件),但您没有对图形的太多控制。另一个是面向对象的:
import matplotlib.pyplot as plt
fig, ax = plt.subplots(figsize=(3,3))
ax.bar(x=['A','B','C'], height=[3.1,7,4.2], color='r')
ax.set_xlabel(xlabel='X title', size=20)
ax.set_ylabel(ylabel='Y title' , color='b', size=20)
plt.show()
这将需要更多的时间来编码,但你可以完全控制你的数字。这个想法是,你创建一个“图形”对象,你可以把它想象成你要构建的整个可视化的边界框,和一个或多个“轴”对象,它们是可视化的支线剧情,(不要问我为什么这些支线剧情叫“轴”。名字太烂了……)支线剧情可以通过这些“轴”对象的方法来操作。
(关于这两个接口的详细解释,读者可以参考
https://matplotlib . org/tutorials/introductive/life cycle . html
或
https://pbpython.com/effective-matplotlib.html)
让我们在本教程中坚持使用面向对象的方法。
面向对象界面中图形中的元素
下面这幅取自 https://pbpython.com/effective-matplotlib.html 的图很好地解释了一个图形的组成部分:

让我们看一个简单的例子,如何用面向对象的界面创建折线图。

fig, ax = plt.subplots(figsize=(3,3))
ax.plot(['Alice','Bob','Catherine'], [4,6,3], color='r')
ax.set_xlabel('TITLE 1')
for tick in ax.get_xticklabels():
tick.set_rotation(45)
plt.show()
在上面的代码中,我们创建了一个 axes 对象,在其上创建了一个线图,添加了一个标题,并将所有的 x-tick 标签逆时针旋转了 45 度。
查看官方 API,看看如何操作轴对象:https://matplotlib.org/api/axes_api.html
几种常见的绘图类型
在对 Matplotlib 的工作原理有了大致的了解之后,是时候看看一些常见的情节了。他们是
散点图(x:数值#1,y:数值#2),

线形图(x:分类序数#1,y:数值# 1)[感谢 Michael Arons 在前图中指出一个问题],

条形图(x:分类#1,y:数字#1)。数字#1 通常是分类#1 的计数。

直方图(x:数值#1,y:数值#2)。数字#1 组合成组(转换成分类变量),数字#2 通常是这个分类变量的计数。

内核密度图(x:数值#1,y:数值#2)。数字#2 是数字#1 的频率。

二维内核密度图(x:数值#1,y:数值#2,颜色:数值#3)。数值#3 是数值#1 和数值#2 的联合频率。

箱线图(x:分类#1,y:数值#1,标记:数值#2)。箱线图显示了分类#1 中每个值的统计数据,因此我们可以了解其他变量的分布情况。y 值:另一个变量的值;标记:显示这些值是如何分布的(极差、Q1、中位数、Q3)。

小提琴图(x:分类#1,y:数值#1,宽度/标记:数值#2)。小提琴图有点类似于箱线图,但它更好地显示了分布。

热图(x:分类#1,y:分类#2,颜色:数字#1)。数值#1 可以是分类#1 和分类#2 的共同计数,也可以是该对中每个值的其他数值属性(分类#1、分类#2)。

为了了解如何绘制这些图形,读者可以通过谷歌搜索以下列表来查看 seaborn APIs:
SNS . bar plot/SNS . distplot/SNS . line plot/SNS . kdeplot/SNS . violinplot
SNS . scatter plot/SNS . box plot/SNS . heat map
我将给出两个示例代码,展示如何在面向对象的界面中生成 2D kde 图/热图。
# 2D kde plots
import numpy as np
import matplotlib.pyplot as plt
import seaborn as snsnp.random.seed(1)
numerical_1 = np.random.randn(100)
np.random.seed(2)
numerical_2 = np.random.randn(100)fig, ax = plt.subplots(figsize=(3,3))
sns.kdeplot(data=numerical_1,
data2= numerical_2,
ax=ax,
shade=True,
color="blue",
bw=1)
plt.show()
关键是参数 ax=ax。跑步的时候。kdeplot()方法,seaborn 会将更改应用到 ax,一个“axes”对象。
# heat mapimport numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as snsdf = pd.DataFrame(dict(categorical_1=['apple', 'banana', 'grapes',
'apple', 'banana', 'grapes',
'apple', 'banana', 'grapes'],
categorical_2=['A','A','A','B','B','B','C','C','C'],
value=[10,2,5,7,3,15,1,6,8]))
pivot_table = df.pivot("categorical_1", "categorical_2", "value")# try printing out pivot_table to see what it looks like!fig, ax = plt.subplots(figsize=(5,5))sns.heatmap(data=pivot_table,
cmap=sns.color_palette("Blues"),
ax=ax)
plt.show()
增加你的图的维度
对于这些基本图,只能显示有限的信息量(2-3 个变量)。如果我们想显示这些图的更多信息呢?以下是几种方法。
- 覆盖图
如果几个折线图共享相同的 x 和 y 变量,您可以多次调用 Seaborn plots,并将它们全部绘制在同一个图上。在下面的例子中,我们在覆盖图中添加了一个分类变量[value = alpha,beta]。

fig, ax = plt.subplots(figsize=(4,4))
sns.lineplot(x=['A','B','C','D'],
y=[4,2,5,3],
color='r',
ax=ax)
sns.lineplot(x=['A','B','C','D'],
y=[1,6,2,4],
color='b',
ax=ax)
ax.legend(['alpha', 'beta'], facecolor='w')
plt.show()
或者,我们可以将 x 轴相同但 y 轴不同的条形图和折线图结合起来:

sns.set(style="white", rc={"lines.linewidth": 3})fig, ax1 = plt.subplots(figsize=(4,4))
ax2 = ax1.twinx()sns.barplot(x=['A','B','C','D'],
y=[100,200,135,98],
color='#004488',
ax=ax1)sns.lineplot(x=['A','B','C','D'],
y=[4,2,5,3],
color='r',
marker="o",
ax=ax2)
plt.show()
sns.set()
这里提几点意见。因为两个图具有不同的 y 轴,我们需要创建另一个具有相同 x 轴的“轴”对象(使用。twinx())然后绘制在不同的“轴”上。sns.set(…)是为当前剧情设置特定的审美,我们最后运行 sns.set()将一切设置回默认设置。
将不同的柱状图组合成一个分组柱状图也为该图增加了一个分类维度(多了一个分类变量)。

import matplotlib.pyplot as pltcategorical_1 = ['A', 'B', 'C', 'D']
colors = ['green', 'red', 'blue', 'orange']
numerical = [[6, 9, 2, 7],
[6, 7, 3, 8],
[9, 11, 13, 15],
[3, 5, 9, 6]]number_groups = len(categorical_1)
bin_width = 1.0/(number_groups+1)fig, ax = plt.subplots(figsize=(6,6))for i in range(number_groups):
ax.bar(x=np.arange(len(categorical_1)) + i*bin_width,
height=numerical[i],
width=bin_width,
color=colors[i],
align='center')ax.set_xticks(np.arange(len(categorical_1)) + number_groups/(2*(number_groups+1)))# number_groups/(2*(number_groups+1)): offset of xticklabelax.set_xticklabels(categorical_1)
ax.legend(categorical_1, facecolor='w')plt.show()
在上面的代码示例中,您可以自定义变量名、颜色和图形大小。number_groups 和 bin_width 是根据输入数据计算的。然后,我编写了一个 for 循环来绘制条形,一次一种颜色,并在最后设置刻度和图例。
2.面-将数据集映射到多个轴,它们之间有一两个分类变量的差异。读者可以在https://seaborn.pydata.org/generated/seaborn.FacetGrid.html中找到一堆例子
3.散点图中节点的颜色/形状/大小:下面的代码示例来自 Seaborn 散点图 API,展示了它是如何工作的。(https://seaborn . pydata . org/generated/seaborn . scatter plot . html)
import seaborn as snstips = sns.load_dataset("tips")
ax = sns.scatterplot(x="total_bill", y="tip",
hue="size", size="size",
sizes=(20, 200), hue_norm=(0, 7),
legend="full", data=tips)
plt.show()
使用 GridSpec 划分图形
面向对象界面的一个优点是,我们可以很容易地将我们的图形划分成几个子图形,并用“轴”API 操纵每个子图形。

fig = plt.figure(figsize=(7,7))
gs = gridspec.GridSpec(nrows=3,
ncols=3,
figure=fig,
width_ratios= [1, 1, 1],
height_ratios=[1, 1, 1],
wspace=0.3,
hspace=0.3)ax1 = fig.add_subplot(gs[0, 0])
ax1.text(0.5, 0.5, 'ax1: gs[0, 0]', fontsize=12, fontweight="bold", va="center", ha="center") # adding text to ax1ax2 = fig.add_subplot(gs[0, 1:3])
ax2.text(0.5, 0.5, 'ax2: gs[0, 1:3]', fontsize=12, fontweight="bold", va="center", ha="center")ax3 = fig.add_subplot(gs[1:3, 0:2])
ax3.text(0.5, 0.5, 'ax3: gs[1:3, 0:2]', fontsize=12, fontweight="bold", va="center", ha="center")ax4 = fig.add_subplot(gs[1:3, 2])
ax4.text(0.5, 0.5, 'ax4: gs[1:3, 2]', fontsize=12, fontweight="bold", va="center", ha="center")plt.show()
在示例中,我们首先用 gridspec 将图形划分成 3*3 = 9 个小方框。GridSpec(),然后定义几个 axes 对象。每个轴对象可以包含一个或多个框。在上面的代码中,gs[0,1:3] = gs[0,1] + gs[0,2]被分配给 axes 对象 ax2。wspace 和 hspace 是控制地块间距的参数。
创建高级可视化
有了前几节的一些教程,是时候制作一些很酷的东西了。让我们从 https://www.kaggle.com/mehdidag/black-friday的
下载分析 Vidhya 黑色星期五销售数据,并做一些简单的数据预处理:
df = pd.read_csv('BlackFriday.csv', usecols = ['User_ID', 'Gender', 'Age', 'Purchase'])df_gp_1 = df[['User_ID', 'Purchase']].groupby('User_ID').agg(np.mean).reset_index()df_gp_2 = df[['User_ID', 'Gender', 'Age']].groupby('User_ID').agg(max).reset_index()df_gp = pd.merge(df_gp_1, df_gp_2, on = ['User_ID'])
然后,您将获得一个表,其中包含用户 ID、性别、年龄以及每个客户购买的商品的平均价格。
第一步。目标 我们很好奇年龄和性别会如何影响黑色星期五期间的平均购买价格,我们也希望看到价格分布。我们还想知道每个年龄组的百分比。
第二步。变量
我们希望在图中包括年龄组(分类)、性别(分类)、平均商品价格(数值)以及平均商品价格的分布(数值)。我们需要包括另一个图,每个年龄组的百分比(年龄组+计数/频率)。
为了显示平均物品价格+它的分布,我们可以用核心密度图,箱线图,或小提琴图。其中,kde 显示的分布最好。然后,我们在同一个图形中绘制两个或更多的 kde 图,然后绘制小平面图,这样年龄组和性别信息都可以包括在内。对于另一个图,条形图可以很好地完成这项工作。
第三步。可视化
一旦我们有了关于变量的计划,我们就可以考虑如何将它可视化。我们需要先做图形分区,隐藏一些边界、xticks、yticks,然后在右边加一个条形图。
下面的情节就是我们要创造的。从图中,我们可以清楚地看到,根据数据,男性比女性倾向于购买更昂贵的物品,老年人倾向于购买更昂贵的物品(对于前 4 个年龄组,趋势更明显)。我们还发现,18-45 岁的人是黑色星期五销售的主要买家。

以下代码生成绘图(注释中包含解释):
freq = ((df_gp.Age.value_counts(normalize = True).reset_index().sort_values(by = 'index').Age)*100).tolist()number_gp = 7**# freq = the percentage for each age group, and there’re 7 age groups.**def ax_settings(ax, var_name, x_min, x_max):
ax.set_xlim(x_min,x_max)
ax.set_yticks([])
ax.spines['left'].set_visible(False)
ax.spines['right'].set_visible(False)
ax.spines['top'].set_visible(False)
ax.spines['bottom'].set_edgecolor('#444444')
ax.spines['bottom'].set_linewidth(2)
ax.text(0.02, 0.05, var_name, fontsize=17, fontweight="bold", transform = ax.transAxes)
return None**# Manipulate each axes object in the left. Try to tune some parameters and you'll know how each command works.**fig = plt.figure(figsize=(12,7))
gs = gridspec.GridSpec(nrows=number_gp,
ncols=2,
figure=fig,
width_ratios= [3, 1],
height_ratios= [1]*number_gp,
wspace=0.2, hspace=0.05
)ax = [None]*(number_gp + 1)
features = ['0-17', '18-25', '26-35', '36-45', '46-50', '51-55', '55+']**# Create a figure, partition the figure into 7*2 boxes, set up an ax array to store axes objects, and create a list of age group names.** for i in range(number_gp):
ax[i] = fig.add_subplot(gs[i, 0])
ax_settings(ax[i], 'Age: ' + str(features[i]), -1000, 20000)
sns.kdeplot(data=df_gp[(df_gp.Gender == 'M') & (df_gp.Age == features[i])].Purchase,
ax=ax[i], shade=True, color="blue", bw=300, legend=False)
sns.kdeplot(data=df_gp[(df_gp.Gender == 'F') & (df_gp.Age == features[i])].Purchase,
ax=ax[i], shade=True, color="red", bw=300, legend=False)
if i < (number_gp - 1):
ax[i].set_xticks([])**# this 'for loop' is to create a bunch of axes objects, and link them to GridSpec boxes. Then, we manipulate them with sns.kdeplot() and ax_settings() we just defined.**ax[0].legend(['Male', 'Female'], facecolor='w')**# adding legends on the top axes object ** ax[number_gp] = fig.add_subplot(gs[:, 1])
ax[number_gp].spines['right'].set_visible(False)
ax[number_gp].spines['top'].set_visible(False)ax[number_gp].barh(features, freq, color='#004c99', height=0.4)
ax[number_gp].set_xlim(0,100)
ax[number_gp].invert_yaxis()
ax[number_gp].text(1.09, -0.04, '(%)', fontsize=10, transform = ax[number_gp].transAxes)
ax[number_gp].tick_params(axis='y', labelsize = 14)**# manipulate the bar plot on the right. Try to comment out some of the commands to see what they actually do to the bar plot.** plt.show()
像这样的地块也被称为“喜悦地块”或“山脊线地块”。如果你试图使用一些 joyplot 软件包来绘制相同的图形,你会发现这有点困难,因为每个支线剧情中都包含了两个密度图。
希望这是一个快乐的阅读给你。
为乳腺组织分类构建多类分类器的分步指南
从头开始构建您自己的分类器

Photo by Paweł Czerwiński on Unsplash
这篇文章包含一步一步的建立和训练一个简单的多类分类模型来分类乳房组织的指南。我们将使用来自 UCI 机器学习知识库的乳房组织数据集作为我们训练和测试分类器模型的数据集。
让我们开始吧。
了解数据集
你可以从这个链接下载数据集。数据集是一个带有。xls 扩展名,文件名为breast tissue . xls .打开文件,我们可以发现两个选项卡:描述和数据。
通读该描述,我们知道该数据集包含 106 个从乳房新切下的组织的电阻抗测量实例。该数据集有 9 个要素和 1 个类属性。每个乳房组织属于六类中的一类。
数据选项卡包含我们需要的数据。我们可以继续操作,只使用 data 选项卡创建一个新的 CSV 文件。
导入数据
让我们将之前保存的 CSV 文件导入到 pandas 数据帧中。

快速浏览数据
现在,我们已经加载了数据,我们可以看到数据的形状,找出数据中有多少个不同的类,并通过查看数值的平均值、标准偏差和百分比分布来了解数据分布的基本概念。

定义输入和输出
让我们把数据分成输入和输出。我们将 9 个特征作为输入 X,类作为输出 y。

分割训练和测试数据
现在,我们将数据集进一步划分为训练数据集和测试数据集,其中总数据集的 0.33%被划分为测试集。 X_train 为训练输入, y_train 为训练输出, X_test 为测试输入, y_test 为测试输出。
创建并拟合分类模型
让我们使用 xgboost python 库构建一个多类梯度提升分类器,并使用训练数据集训练分类器。
将训练好的模型应用于测试数据集
我们有一个经过训练的多类分类器,现在我们将使用它来预测测试集的类。我们将使用 ROC AUC 作为该模型的评估矩阵。
直观比较输出
您还可以直观地比较测试数据集的预期输出和预测输出。

现在,您已经成功构建并训练了一个乳房组织分类器,它可以将给定的数据分类到六个不同的类别中。我们从 CSV 文件中提取数据,指定输入和输出,分成训练集和测试集,训练一个梯度提升分类器,并在测试集上测试它。
这里有一个完整代码的链接。
觉得这个帖子有用吗?请在下面留下你的想法。
点击这里 阅读我其他关于 AI/机器学习的帖子。
数据来源:
https://archive.ics.uci.edu/ml/datasets/Breast+Tissue
Dua d .和 Graff c .(2019 年)。UCI 机器学习知识库[http://archive . ics . UCI . edu/ml]。加州欧文:加州大学信息与计算机科学学院。
参考文献:
[## sk learn . preprocessing . label binarizer-sci kit-learn 0 . 21 . 3 文档
以一对一的方式对标签进行二进制化。有几种回归和二进制分类算法可用于…
scikit-learn.org](https://scikit-learn.org/stable/modules/generated/sklearn.preprocessing.LabelBinarizer.html) [## sk learn . metrics . roc _ AUC _ score-sci kit-learn 0 . 21 . 3 文档
根据预测得分计算受试者工作特征曲线下的面积(ROC AUC)。注意:这个…
scikit-learn.org](https://scikit-learn.org/stable/modules/generated/sklearn.metrics.roc_auc_score.html)
制作销售仪表板的分步指南
我写过一些关于 业务仪表盘 数据可视化的入门指南,但是那些文章还是有点理论化。最近,我一直在做一个数据可视化的销售仪表板项目。从指标的确定、版面设计、图表类型到动态效果,我总结了一些经验和看法。在本帖中,我将与你分享制作销售仪表板的具体步骤。

1。制作仪表盘的工具
仪表板的生产可以通过代码开发或现有的可视化工具来完成。很多人会用 JS 和 Ecahrts,但通常涉及到数据支持、后台响应、实时更新、平台运维等。,需要更多的技术,这里就不赘述了。
另一种方法是使用现成的可视化工具。使用像 FineReport 或 Tableau 这样的工具来构建业务仪表板是相对简单和高效的。由于自己的工作需要,对 FineReport 的操作比较熟悉,所以本文中我将向大家展示的是我是如何使用 FineReport 制作销售仪表盘的。
2。确定分析指标
观看销售仪表盘,你可能会被酷炫的视觉效果所吸引。但是,请记住,仪表板必须基于数据的呈现,任何酷的效果都不能影响数据的有效显示。
因此,我们应该首先考虑哪些数据和哪些指标应该放在仪表板上。您可以使用关键指标分解方法来确定要显示哪些数据。
步骤 1 :识别关键指标。对于销售仪表盘来说,你的总销售额一定是最重要的,这是主题。
第二步:从多个维度分解关键指标,也就是分解你的销售额。
- 从时间维度来看。每个季度或每个月的销售情况如何?为什么有些时间段销量特别高?采取了哪些措施?
- 从地理维度来看。各地区销售情况如何?他们的排名是什么?
- 从规划的角度来看。现在的销售和之前的计划有什么区别?
- 从比例维度来看。每个产品的销量如何?哪些是最赚钱的明星产品?
3。设计布局
一般情况下,一个指标独占仪表盘上的一个区域,所以通过关键指标的定义,你就知道仪表盘上会显示什么内容,仪表盘会分成多少块。您可以根据业务场景确定指标的重要性,然后设计仪表板的布局。
布局的目的是合理地呈现业务指标和数据。有主次指标。一级指标反映的是核心业务,二级指标用于进一步细化,所以在设计布局时赋予了不同的权重。
这里我推荐几种常见的布局。



4。选择图表类型
关键指标确定后,我们需要确定指标的分析维度。数据能否分析透彻,能否为决策提供支持,取决于指标的分析维度。我们常见的分析方法有类比、趋势、分布、构成等。分析方法的选择取决于实际的业务场景。
以购物中心的数据为例,我将告诉你如何选择正确的图表类型。

如果想了解更多关于图表的类型和应用,可以参考本文 数据可视化中的 16 大图表类型 。
5。添加动态效果
动态效果是可视化的重要组成部分。它们使整个仪表板更具吸引力。但是过多的动态使观众眼花缭乱,它不能突出关键信息。所以需要注意动态设计的比例。
动态效果的范围很广。有动态图像、页面旋转、列表滚动、实时数据更改等等。以下是 FineReport 的一些内置动态效果。



练习
以上是制作仪表盘的基本步骤。说到这里,我将向您展示我如何使用 FineReport 来制作销售仪表板。
①导入数据
首先,我们准备数据并将其导入 FineReport Designer。这里的数据是虚构的,因为我用的是 FineReport 的内置数据集。

如下图所示,在真实场景中,我们需要连接各种数据库来导入数据。

连接的数据可以是常见的关系数据库,也可以是 Excel 之类的文件数据。并且 FineReport 支持连接大数据平台。
②制作模板
一旦数据准备就绪,下一步就是创建模板。
首先,我创建一个空白模板,如下所示。原理是在空白模板上拖拽一个可视化组件(比如图表),然后绑定数据。

在我们开始之前,我们需要考虑我们想要在这个空白界面上显示什么样的销售数据。
经过深思熟虑,我设计了以下布局。中间是主旋律,左右是副主旋律。

③选择可视化元素

对于销售,我们首先分析量化指标。拖放表格和图表来显示,如上所示。

在 FineReport Designer 上选择合适的图表样式,连接开始导入的数据。

④添加动态效果
在这个销售仪表板中,我添加了一个流程图来显示全国或全球销售业务的分布。

动态效果如下图所示,数据是销售地点的经纬度信息。

最后,经过一系列的美化设置,仪表盘就完成了。

这个销售仪表板相对简单,这里是我用 FineReport 制作的一些其他仪表板。



最后我想说,做一个仪表盘并不难。最重要的是,我们必须找出业务运营性质的关键指标,并让领导者看到数据的价值。这是数据可视化中最重要的一步。希望今天分享的文章能对你有一点帮助。如果你想自己做一个销售仪表盘,可以下载 FineReport 来练习,这是一个零编码的可视化工具。它的个人版本是完全免费的。
您可能也会对…感兴趣
梯度下降和反向传播的逐步实现
从头开始构建神经网络的一个例子
这篇文章背后的初衷仅仅是我在神经网络中梳理数学,因为我喜欢精通算法的内部工作,并获得事物的本质。然后我想,与其一遍又一遍地重温记事本上的公式,我还不如编一个故事。尽管您可能会找到一些从头构建简单神经网络的教程。不同的人看待事物的角度不同,学习的侧重点也不同。另一种思维方式可能在某种意义上增强理解。所以让我们开始吧。

Photo from Unsplash
概括地说神经网络
神经网络的核心是一个大函数,它将一些输入映射到所需的目标值,在中间步骤中执行生成网络的操作,这是通过在一个反复执行此操作的流水线场景中乘以权重并添加偏差来实现的。训练神经网络的过程是确定一组参数,使期望值和模型输出之间的差异最小化。这是使用梯度下降(又名反向传播)来完成的,根据定义,梯度下降包括两个步骤:计算损失/误差函数的梯度,然后响应于梯度更新现有参数,这就是下降是如何完成的。重复这个循环,直到达到损失函数的最小值。这个学习过程可以用简单的等式来描述:W(t+1) = W(t) — dJ(W)/dW(t)。
数学直觉

Photo from https://blog.goodaudience.com/artificial-neural-networks-explained-436fcf36e75
出于我自己的练习目的,我喜欢使用一个如图所示的只有一个隐藏层的小网络。在该布局中,X 表示输入,下标 I、j、k 分别表示输入、隐藏和输出层中的单元数量;w_ij 表示连接输入到隐藏层的权重,w_jk 是连接隐藏到输出层的权重。
在这种情况下,模型输出计算如下:

损失函数的选择通常是误差平方和。这里,我使用 sigmoid 激活函数,为了简单起见,假设偏差 b 为 0,这意味着权重是影响模型输出的唯一变量。让我们推导出计算隐藏到输出权重 w_jk 的梯度的公式。

确定隐权输入的复杂性在于它间接影响输出误差。每个隐藏单元输出影响模型输出,因此对隐藏权重 w_ij 的输入取决于它所连接的所有单元的误差。推导开始也一样,只是把 z_k 处的链式法则展开到子函数上。

更多思想:
请注意,两个权重的梯度具有相似的形式。误差通过激活函数的导数反向传播,然后通过来自前一层的输入(激活输出)加权。在第二个公式中,来自输出层的反向传播误差被进一步投影到 w_jk 上,然后重复相同的反向传播方式并通过输入进行加权。这种反向传播过程一直重复到任意层神经网络的第一层。“因此,关于每个参数的梯度被认为是参数对误差的贡献,并且应该在学习期间被否定。”
将上述过程编写成代码:

以下是完整的示例:
import numpy as npclass NeuralNetwork:
def __init__(self):
np.random.seed(10) # for generating the same results
self.wij = np.random.rand(3,4) # input to hidden layer weights
self.wjk = np.random.rand(4,1) # hidden layer to output weights
def sigmoid(self, x, w):
z = np.dot(x, w)
return 1/(1 + np.exp(-z))
def sigmoid_derivative(self, x, w):
return self.sigmoid(x, w) * (1 - self.sigmoid(x, w))
def gradient_descent(self, x, y, iterations):
for i in range(iterations):
Xi = x
Xj = self.sigmoid(Xi, self.wij)
yhat = self.sigmoid(Xj, self.wjk)
# gradients for hidden to output weights
g_wjk = np.dot(Xj.T, (y - yhat) * self.sigmoid_derivative(Xj, self.wjk))
# gradients for input to hidden weights
g_wij = np.dot(Xi.T, np.dot((y - yhat) * self.sigmoid_derivative(Xj, self.wjk), self.wjk.T) * self.sigmoid_derivative(Xi, self.wij))
# update weights
self.wij += g_wij
self.wjk += g_wjk
print('The final prediction from neural network are: ')
print(yhat)if __name__ == '__main__':
neural_network = NeuralNetwork()
print('Random starting input to hidden weights: ')
print(neural_network.wij)
print('Random starting hidden to output weights: ')
print(neural_network.wjk)
X = np.array([[0, 0, 1], [1, 1, 1], [1, 0, 1], [0, 1, 1]])
y = np.array([[0, 1, 1, 0]]).T
neural_network.gradient_descent(X, y, 10000)
参考资料:
- https://theclevermachine . WordPress . com/2014/09/06/derivation-error-back propagation-gradient-descent-for-neural-networks/
- https://towards data science . com/how-to-build-your-own-your-own-neural-network-in-python-68998 a08e 4 f 6
开始 nbdev 的逐步介绍——探索性编程
使用 nbdev 的简化 Hello World 示例
“我真的认为[nbdev]是编程环境的巨大进步”:Swift、LLVM、Xcode 和 Swift Playgrounds 的发明者克里斯·拉特纳。

Image by Alfons Morales — Unsplash
杰瑞米·霍华德不停地用他伟大的库给我们留下深刻的印象,例如 Fastai (一个使用 PyTorch 的高级 API)。
今天(2019 年 2 月 12 日)杰瑞米·霍华德和西尔万·古格发布了另一个令人敬畏的库[“nbdev”](/(from nbdev)),它允许在 Jupyter 笔记本上完全开发一个库,将你所有的代码、测试和文档放在一个地方。
也就是说,正如 Donald Knuth 在 1983 年所设想的那样,您现在拥有了一个真正有文化的编程环境!

Exploring the notebook file format in the nbdev source code
nbdev:探索性编程(来自 nbdev)
探索性编程是一种基于观察的编程技术。在编码时,编码人员倾向于花费大量时间探索和试验不同的 API、数据、算法等。尤其是 ML 工程师,他们花了很多精力去改变超参数,并把它们记录在某个地方——实验管理。当您使用 REPL 或笔记本系统(如 Jupyter 笔记本)编码时,这样的过程更容易。但是这些系统对于“编程”部分来说并不强大。这就是为什么人们主要使用这样的系统进行早期探索,然后在项目的后期切换到 IDE 或文本编辑器。
nbdev 的特点(来自 nbdev)
nbdev 的主要目的是将 IDE/编辑器的关键特性带到笔记本电脑中,让您不必担心整个生命周期。此外,nbdev 还提供以下功能:
- Python 模块是按照最佳实践自动创建的,比如用导出的函数、类和变量自动定义 all ( 更多细节)
- 在标准文本编辑器或 IDE 中导航和编辑您的代码,并将任何更改自动导出到您的笔记本中
- 从代码中自动创建可搜索的超链接文档。您用反勾号括起来的任何单词都将被超链接到相应的文档,在您的文档站点中将为您创建一个侧栏,其中包含到您的每个模块的链接,等等
- Pip 安装程序(为您上传到 pypi)
测试(直接在您的笔记本中定义,并并行运行)
持续集成 - 版本控制冲突处理
设置您的 nbdev (Hello World 示例)
设置 nbdev 很简单:
- 点击此处此链接将引导您进入 Github,在这里您只需给出一个回购名称

- 之后,克隆 repo 并编辑
settings.ini文件以符合您的要求。不要忘记取消注释所需的行(lib_name、user 等。)

- 每次编辑后,运行命令
nbdev_build_lib,它预装了 nbdev。

然后启动 Jupyter 笔记本,如果你在基本目录下,你应该看到以下内容:

点击00_core.ipynb,在这里你将创建你的第一个模块!

当您开始创建单元格和编写代码时,不要忘记以#export或#exports开始每个单元格,以显示文档中的源代码。
最后,您有两种选择,是否将下面的代码放在最后一个单元格中:
from nbdev.export import *
notebook2script()
或者运行命令:nbdev_build_lib
不要忘记编辑index.ipynb。这将被转换为您的项目自述文件,也将成为您的文档的索引。
运行命令nbdev_build_lib后,将创建一个新目录,其名称与您在settings.ini中设置的lib_name相同。注意exploratoryprogramming:

exploratoryprogramming的内容:

现在,您将开始创建令人惊叹的深度学习项目!如果您有任何问题或意见,请告诉我。
资源
用动态记忆网络实现通用自然语言处理的一步
用动态记忆网络和问答格式解决不同的自然语言处理任务

Image by Pete Linforth from Pixabay

Source: [1]
我假设你已经熟悉 LSTMs 和 GRUs 等递归神经网络(包括 seq2seq 编码器-解码器架构)。
通用自然语言处理的一个障碍是不同的任务(如文本分类、序列标记和文本生成)需要不同的顺序架构。处理这个问题的一个方法是将这些不同的任务视为问答问题。因此,例如,可以向模型询问对一段文本的情感是什么(传统上是文本分类问题),答案可以是“正面”、“负面”或“中性”之一。
论文“问我任何问题:自然语言处理的动态记忆网络”介绍了一种新的、模块化的问答体系结构。
对于复杂的问答问题,LSTMs 和 GRUs 的内存组件可能会成为瓶颈。很难一次就在内存组件中积累所有相关信息,因此,本文背后的关键思想是允许模型根据需要多次访问数据。
尽管该架构乍看起来极其复杂,但它可以被分解成许多简单的组件。
模块
语义记忆模块
语义记忆模块简单地引用单词嵌入,例如手套向量,输入文本在被传递到输入模块之前被转换成该单词嵌入。
输入模块

输入模块是一个标准的 GRU(或 BiGRU),其中每个句子的最后一个隐藏状态是显式可访问的。
问题模块

问题模块也是一个标准的 GRU,要回答的问题作为输入,最后一个状态隐藏状态是可访问的。
情节记忆模块

这是对输入数据进行多次传递的模块。在每一遍中,来自输入模块的句子嵌入作为输入被馈送到情节记忆模块中的 GRU。这里,每个嵌入的句子被分配一个权重,该权重对应于其与所问问题的相关性。
不同的权重可以被分配给不同遍的句子嵌入。例如,在下面的例子中;

由于句子(1)与问题没有直接关系,因此可能不会在第一遍中给予很高的权重。然而,在第一次传递中,模型发现足球与约翰相关联,因此在第二次传递中,给予句子(1)更高的权重。
对于第一遍(或第一“情节”),嵌入“q”的问题用于计算来自输入模块的句子嵌入的注意力分数。
句子 sᵢ 的注意力分数然后可以通过 softmax(这样注意力分数总和为 1)或单个 sigmoid 来获得 gᵢ。
gᵢ 是赋予语句sᵢ的权重,并在时间步长 i. 充当 GRU 输出的全局门
时间步 i 和情节 t 的隐藏状态计算如下:

当 g = 0 时,隐藏状态被简单地向前复制。也就是说,

第 t 集的 GRU 的最后隐藏状态,被称为 m ᵗ,可以被视为在第 t. 集期间发现的事实的聚集。从第二集开始, m ᵗ被用于计算第 t+1 集的句子嵌入以及问题嵌入 q 的注意力分数。
计算如下:

在 sᵢ 和 q、和 sᵢ 和 m ᵗ⁻之间计算多个简单的相似性度量,即逐元素乘法和绝对差。连接的结果然后通过 2 层神经网络来计算 sᵢ的注意力分数。第一集, m⁰ 换成了q
剧集的数量可以是固定的、预定义的数量,或者由网络本身确定。在后一种情况下,一个特殊的刀路结束表示被附加到输入中。如果这个向量被选通函数选择,那么迭代停止。
回答模块

答案模块由一个解码器 GRU 组成。在每个时间步,与问题嵌入连接的前一个输出作为输入。

使用词汇表上的标准 softmax 生成输出。
解码器通过 m 向量(来自情节存储模块的 GRU 计算的最后隐藏状态)上的函数初始化。
应用于情感分析
该模型在发表时达到了情感分析的艺术水平。

对于下面的例子,该模型关注所有的形容词,并且当仅允许 1 次通过时,最终产生不正确的预测。然而,当允许两次通过时,该模型对第二次通过时的正面形容词给予显著更高的关注,并产生正确的预测。

Analysis of Attention for Sentiment: [1]
在其他数据集上的性能

Source: [1]

Source: [1]
开关模块
模块化的一个重要好处是,只要替换模块具有正确的接口,就可以用另一个模块替换另一个模块,而无需修改任何其他模块。
论文“用于视觉和文本问答的动态记忆网络”展示了使用动态记忆网络来回答基于图像的问题。
输入模块被另一个使用基于 CNN 的网络从图像中提取特征向量的模块代替。如前所述,提取的特征向量然后被馈送到情节记忆模块。

Source: [2]

Source: [2]

Visual Question Answering Accuracy: [2]

Attention visualisations of answers to some questions: [2]
额外资源
参考
[1] K. Ankit,O. Irsoy,J. Su,J. Bradbury,R. English,B. Pierce,P. Ondruska,I. Gulrajani 和 R. Socher,随便问我:自然语言处理的动态记忆网络,(2016)。
[2] C .熊,S. Merity 和 R. Socher,视觉和文本问答的动态记忆网络,(2016)。**
一针延迟——对数据科学中最大的小问题的适度修复
对于科学家如何报告和重复使用结果,可以说没有标准。我们已经达成了一个务实的约定,但它存在严重缺陷。在这里,我建议一种新的和几乎通用的方法来提高报告结果的可重复性,而不需要额外的成本或努力。
当使用、发布和阅读统计数据时,很容易被欺骗。
不是出于故意或恶意,而是因为对复杂概念的误解和误用。
*尽管这也很容易——一个有才华的数据科学家可以让数字说出他们想说的任何话
今天,我想解决一个简单的概念和一个长期以来扭曲科学结果的误解,只是轻微的。
然后我想告诉你如何解决它,而几乎不用动一根手指。
我想花点时间来充分解释这篇文章的动机——但是对于那些在数据科学方面有经验的人来说,你可能想跳到猴子的图片来得到问题的结论和解决方案的陈述。
首先我们要问,什么是结果?
是什么将每份学术著作中的无数数字和图形分成结果。我认为,也许令人困惑的是,这完全不在作者的掌控之中。结果是被其他人使用的任何数字、图形或概念。
这就是为什么我们要小心谨慎的原因,作为作者,我们要清楚地区分结果,以及它们晦涩的表亲汇总统计数据。
汇总统计试图用尽可能少的数字来解释数据的分布、偏斜和形状——它们有助于作者展示和读者理解我们可能应用于任何数据集的指示性指标。它们并不试图描述数据的一般形式,只是一些相关的特征(例如,数据集的范围—最高值和最低值之间的差异—可能是有用的,但它不能告诉您这些值内的分布情况)。
我在这篇文章中提出的一切都适用于(或可能)被解读为结果的数字——这些数字试图代表所有数据的一般行为,可以放心地引用和重复使用。
结果是我们继承的数字。这些数字可能几十年都没有经过检验和检查。这些数字可以成为通用的说法并在全球传播。这些数字输入并影响着新的结果和新的思想,随着时间的推移不断涌现。
结果是交换的——它们是共享和给予的——我们需要知道我们所说的是公平的。
如果我们能够简单地、一般地(也许是普遍地)表达它们,那么其他人就更容易理解、评价它们并从中受益。
最少的信息中最真实的信息——我们如何用尽可能少的语言表达一些关于数据的有意义的东西?

A dataset which we might hope to describe, simply and briefly, with just a few numbers. Without intending to shame the authors or editors I shall not name the publication I’ve pulled it from (which is otherwise an excellent piece of work which this misstep barely dampens)
让我们从一个数据集开始,并从那里解释我们可能如何着手构建一个结果,以及不同方法的优点和危险。
左边的图片取自一份出版物。然而,让我们假设这三个面板来自我们所做的分析——让 1000 个人猜一个瓶子里有多少个球以及球的总重量。
每个人的答案可以被认为是 2D 平面上的一个位置——x 代表球的数量,y 代表重量。如果我们在每个人的 x,y 坐标上放一个大头针,我们会看到一些区域布满了大头针(希望在正确答案附近),而一些区域几乎是空的(就像如果有人认为有 10 个球,那么它就是一公吨)。
右下角的面板显示了他们猜测的密度——就像小山上的等高线——在大多数人猜测的区域上升到一个平滑的峰值。上面和右边的图分别是 x 和 y 各自的分布(虽然不太正确,但如果我们沿着 x 和 y 方向分割,你可以把它们看作我们的山的横截面)。
我们可以看到,人们对权重的看法相对一致——大多数答案都落在一个小区域内,并且在那个区域内,分布是均匀的。
但是,球的数量会引起更多的问题。人们倾向于高估比低估多得多的数量(想象三个连续的回答者猜测 10,100 和 1000)。有一个峰值——但它周围有一个不对称性。
正是在处理这种不对称时,当前的惯例出了问题。
总结数据的最常见方法之一是查看中位数(如果我们将所有数据按升序排列,值在中间)以及第 16 个和第 84 个百分位(值大约在有序列表的 1/8 和 7/8 处)。
为什么是这些数字?16–50–84*
*这恰好是我的分类代码
它们与每一位统计学家的老朋友都有关系——正态分布——这是一种近乎怪异的普适表示,描述了数据如何在峰值处分组,并围绕峰值均匀分布。这使我们能够只用两个值来很好地描述大量数据集——平均值(峰值)和标准差(分布)。

我们可以看到,将这个应用到上面的 y 值,我们会得到一个非常好的拟合。瞧——不错的结果,和只用了两个数字!(我的意思是,如果我们只写下两个数字——假设平均值为 1 千克,分布范围为 200 克——你可以画出一条曲线,这条曲线看起来与我们的数据非常相似,但你从未见过它)
因此,明智地将正态分布应用于适当的数据并恢复两个数字是一个好主意。如果你能做到,那就去做!
但是很多时候,就像我们的 x 数据一样,我们不能。这两个参数没有办法描述不对称,我们需要第三个。我们有很多选择,但我想列出 3 个——好的、坏的和丑陋的。
丑陋的(但实际上非常好的)方法——均值、标准差和偏斜
如果我们用湿沙做一个正态分布,然后倾斜它会怎么样?

我们会得到一个偏态分布,有两个不对称的尾部。如果我们向左倾斜沙堆,我们会得到负的偏斜(更多的分布高于平均值),向右倾斜会得到正的偏斜。
然而,我们仍然通过平均值和标准差来描述我们的数据,现在只是增加了一个额外的、深奥的参数。许多读者可能会对选择哪种偏斜是正的和负的皱起眉头,当他们被告知如何计算时更是如此。
有了这三个数字,我们几乎可以肯定可以重建 x 的分布——但是画出来却是一场噩梦。我们有所有需要的信息,但只是以抽象的形式——没有简单的错误栏,也没有明显的方法来引用和绘制结果。
这是一种非常好的做事方式,如果你喜欢那种方式的话,但它很丑陋,也不直观(尽管来吧)。
坏方法——16–50–84
我还没有兑现解释这些数字的承诺。让我们解决这个问题。

正态分布下 16%的区域位于平均值以下 1 个标准差的左侧。
正态分布下 84%的区域位于平均值上方 1 个标准差的左侧。
因此,如果我们有正态分布的数据,这两个数字,当与平均值比较时,告诉我们标准偏差。两次。
而当分布不是完全正态分布时,这两个数字告诉我们…什么都没有?
这里有一个基本问题——16 和 84(以及 50)是只与严格对称的正态分布相关的三个数字——然而我们试图用它们来描述一种不同的非对称分布。
我们衡量的东西和衡量的方式之间存在脱节。显然这两者之间有联系,但是从一个到另一个,我们必须采取一些非线性的步骤。这就像用种子的重量来衡量森林的生物量。那里有信息,但它被抽象成无用的。
为了更好地演示这一点,试着根据第 16、50 和 84 百分位值画出一个分布图。
如果你画的曲线介于 0 和一个无穷数之间,那你就没画对。这三个数字不足以约束曲线,并且与任何型号都不相关。
让那件事过去一会儿。

Hello grainy old friend
我们实验中 x 的分布就是一个很好的例子。这三条虚线显示的是 16–50–84%。
想象一下,拿走分布图,只留下那些——然后把这个图传给其他人,让他们解释这个分布图。
谁会看着这三条线,然后想把波峰放到左边。谁能猜出右边尾巴的长度。
如果给出结果,谁能够解释数据的真实形式。
在这一点上,你可能会想“是啊,这种方法太可怕了——为什么会有人这么做呢?”
或者你可能在想“是的,它并不伟大,但它完成了工作——不要捣乱”
第一个回应来自任何出于合理原因相信改变传统的人。

Sweden — shortly after the side of the road you drive on was legally changed
第二种人知道改变约定代价很高,会导致一段时间的混乱,通常不值得从解决一个小问题中获益。
这篇文章的标题提到了最大的小问题——这是一个小问题——可能只占百分之几的错误和误述。
显然有更好的方法,也有很多人使用,但几乎都有额外的成本。
- 你可以传递你的全部数据集——数据的完美表现,但是很沉重。它占用空间,需要时间和精力去寻找和整合,并且可能有作者很好理解但继承者可能永远不知道的细微差别。
- 您可以将您能想到的最佳模型拟合到每个数据集,这很好,但将曲线拟合到数据并不是一门完美的艺术,报告您的结果不仅需要陈述数字,还需要陈述所使用的分布以及得出分布的方法。
这两种方法都是完全合法且广泛使用的方法——但是它们需要大量的时间和精力。
16-50-84 的实用主义惯例继续存在的原因是它简单、快捷且易于理解。说明你做了什么,怎么做的,很简单。
务实的捷径惯例没有错,事实上,我认为它们通常比它们在准确性上的花费付出更多的红利(节省时间和精力)。
那么,如果我告诉你,有一种同样简单的方法(至少在计算复杂性方面)可以在任何数据集上工作,并给出很好地代表更广泛的数据形式的结果,会怎么样呢?
如果我试图提出一个新的结果报告的最低标准会怎么样?
好方法——直接计算分裂法线
在一轮关于模糊统计分布的公开测验中,分裂正态分布是比较容易回答的问题之一。它经常被发现、再发现和遗忘。如果你取两个不同的正态分布(每个都有自己的标准差),把它们切成两半,然后把它们错误地拼在一起,你就会得到这个结果。
- 包括我在内,直到我发现了一份 的伟大文件 详细记载了其他所有声称发现的人

The left-hand side has a standard deviation of 1, whilst the right-hand side deviation varies. When they are both equal we just have a normal normal distribution (which is what I’ve taken to calling it to reduce confusion)
发现它的原因是,它给出了一个有用的简单方法来描述不对称分布。在三个数字中,它映射出数据的模式*-它是峰值-以及数据从该模式的任一侧下降的速率。这三个数字是直接可见的(不像偏斜度),实际上给出了有意义的结果(不像 16–50–84)。
- 还记得你在学校学过这个吗,把它用在一个关于鞋码的问题上,然后就再也没听说过它了
它被遗忘的原因是它只有一点点用处——有很多其他分布也很适合,有些甚至有一些更令人羡慕的属性(虽然正态分布和对数正态分布在自然界中相对常见,但分裂正态分布本质上是人工的,虽然它可以很好地描述数据,但它永远不会是“完美的”)
然而,我在这里给你一个全新的优势,我认为它使分裂正态分布成为一个可行的替代品,作为结果报告的最低实用标准——我找到了一种方法使它可以直接计算。
通过直接计算,我的意思是您可以通过少量的基本数学运算(如平均值,只需要加法,或中位数,只需要对数据进行排序)来拟合数据的分裂正态分布,而不像其他方法,您必须通过尝试一系列不同的模型并找到最佳模型(如最大似然估计)来拟合数据。
我将把如何做到这一点的完整描述留给一个干燥机来源——我写的关于这个主题的论文。
这意味着寻找分裂正态参数与 16–50–84 百分位值一样简单,而且更具代表性。
那我们该怎么办?好吧,我的建议是开始使用它:)跟随那个链接,你会找到一个(非常基本的)python 脚本*,它可以对它建模、拟合并从中随机取样。
如果任何阅读的人知道如何将这样的东西放入 numpy(或 scipy library)中,那似乎是它的自然去处。
使用分裂法线总是很好的。这不是最优雅或最准确的解决方案,但它永远不会不起作用。
这一切都是为了降低获得更好工具的门槛,简化人们处理数据的方式,而不是使其复杂化。我不知道它是否会被采纳——或者是否还能提出更好的标准——但我真的希望这将有助于阻止其他人以后采用 16-50-84 的方法。
我建议任何感兴趣的人开始将这些价值观融入他们的工作中,而不是 16-50-84 方法中的 T1。两个相互竞争的标准只会让事情变得更复杂,这是为了让世界变得更简单(更准确)。
如果您这样做了,但确实想表明您对数据的处理有所不同,那么像这样引用您的值怎么样?:

对任何人来说都很容易阅读,但微妙地表明你正在使用这种约定。(并引用这个。如果你想——【https://doi.org/10.22541/au.155733227.75726722】T2
也许我说服了你,也许没有。每个人做任何事情都没有一个正确的方法。我对我认为做得不对的人的数量感到震惊——但这是一个非常主观的观点,即使如此,我也很少相信这使他们的工作或结论无效——这只是一个不幸的、普遍的、希望可以解决的问题。
俗话说,及时缝一针可省九针。这一针来得有点晚——也许只省了三四针。但是,任何微小的时间或准确性的节省,当在全世界制作、阅读和使用统计数据的人群中发挥出来时,都将拯救生命。
摆弄概念和工具。如果你认为还有更好的方法,请告诉我。重要的是,如果你是过去犯过这种错误的人,不要觉得自己被挑了出来(令人尴尬的是,我想我可能犯过)——这是一个进步的时代,而不是防御的时代。
如果你愿意,你可以在推特上找到我,在那里我倾向于发布关于不可穿越网络的神秘笑话,但有时也是关于其他科学的。
这很可能是一个不断发展的文档——我欢迎任何人的意见,如果你回来发现它被修改了,不要感到惊讶(希望是更好的)。你正在阅读的版本是最早的草稿。
一个关于我在一次单人滑雪比赛中获得第一枚金牌的故事:完成的事情和吸取的教训
或者一个关于伟大团队的故事

参加卡格尔比赛是一项严峻的挑战。你需要花费大量的时间和努力,学习新的东西,尝试很多花样才能得高分。通常这还不够,因为有很多伟大的人,他们有更多的经验,更多的空闲时间,更多的硬件或其他一些优势(也许他们甚至拥有所有的优势)。
以前我只能在比赛中获得银牌。有时是由于运气(在重组之后),有时是由于大量的工作。也有很多比赛我获得了铜牌(或者没有奖牌),尽管我花了很多时间在上面。
竞争描述
当我看到一个新的比赛在 5 月底开始,我立刻对它产生了兴趣。这是一场针对特定领域的竞赛,旨在预测分子中原子之间的相互作用。

这项挑战旨在预测原子之间的相互作用。核磁共振(NMR)是一种使用类似于 MRI 的原理来理解蛋白质和分子的结构和动力学的技术。
世界各地的研究人员进行核磁共振实验,以进一步了解分子的结构和动力学,涉及环境科学、制药科学和材料科学等领域。
在这个竞赛中,我们试图预测一个分子中两个原子之间的磁相互作用(标量耦合常数)。量子力学的最新方法可以计算出这些耦合常数,只要给定一个 3D 分子结构作为输入。但是这些计算非常耗费资源,所以不能总是使用。如果机器学习方法可以预测这些值,这将真正有助于药物化学家更快、更便宜地获得结构洞察力。
比赛的开始
我通常为新的 Kaggle 竞赛编写 EDA 内核,这次也不例外。当我在做的时候,我意识到这个比赛非常有趣和独特。我们有关于分子和它们的原子的信息,所以分子可以用图形来表示。Kaggle 竞赛中表格数据的常用方法是广泛的特征工程和使用梯度推进模型。

我在早期的尝试中也使用了 LGB,但是我知道应该有更好的方式来处理图形。这是相当迷人的,我决定认真参加这次比赛。
第一步
我没有领域知识(上次我关注化学公式是在学校),所以我决定从纯 ML 技术开始:大量的特征工程,创建出折叠元特征等等。像往常一样,我用内核发表我的作品。正如你在截图中看到的,他们很受欢迎:)

当时,这种方法在排行榜上给出了相当好的分数,我能够留在银区。
论与时俱进的重要性
真正帮助我的事情之一是阅读论坛和内核。从比赛开始到最后,我阅读了所有的内核和论坛帖子。它们包含许多有用的信息,否则这些信息可能会被忽略。甚至不太流行的内核也可以包含有趣的新特性。小线索可能包含洞察力,这可能有助于增加分数。
组建团队
几乎从一开始,我就意识到领域专业知识将提供一个重要的优势,所以我搜寻每一条这样的信息。当然我注意到有几个活跃的专家,他们在论坛上写文章,创造内核,所以我从他们那里读到了一切。
有一天,我收到了鲍里斯的电子邮件,他是这个领域的专家,认为我们的技能可以互补。通常我更喜欢一个人参加一段时间的比赛,但在这种情况下,联合起来对我来说似乎是个好主意。这个决定被证明是一个伟大的决定:)
合并方法
我们的方法在开始时非常不同:我做技术特征工程,Boris 致力于创建描述符。一段时间后,我们意识到我的模型在一些原子对类型上工作得更好,而他的模型在其他类型上工作得更好——所以我们为不同的类型训练了不同的模型。
我们很幸运还与菲利普·马戈利斯合作。不久之后,他的模型显示出比我们更好的结果。
我们团队的另一名成员成为了博扬,我们能够进一步提高我们的成绩。
他们真的是伟大的 ML 专家,在这场比赛中与他们一起工作是一次很棒的经历。
图形神经网络

当时我们已经看到了神经网络在竞赛中的潜力:著名的 kaggler Heng 贴出了一个模型的例子。

过了一段时间,我甚至能够在我的电脑上运行它,但结果比我们的 LGB 模型更差。然而,我们的团队知道,如果我们想要志存高远,我们就需要使用这些神经网络。
一些辩论确定了,因此我们邀请克里斯托夫加入我们的团队。看到他能够极快地构建一个新的神经网络,真是令人惊讶。很快我们停止了对 LGB 的训练,因为他们远远落后于克里斯托夫的神经网络。
神经网络时代
从那时起,我的角色变成了一个支持者。我用我们的神经网络做了很多实验:尝试各种超参数,不同的架构,对训练计划或损失的各种小调整等等。有时,我对我们的预测进行 EDA,以找到我们感兴趣或错误的案例,然后我们使用这些信息来进一步改进我们的模型。

我的主要贡献之一是寻找新的方法:
- 我翻阅了很多关于神经网络架构的论文:EAGCN、3DGNN 等很多;
- 我试过各种亏,比如胡贝尔。我甚至找到了一篇关于焦点损失回归思想的论文,但是实施起来并不可行;
- 当然,我尝试了像 RAdam 和 Ranger 这样的新的热门优化器,但是简单的 Adam 在我们的情况下更好;
- 和许多其他事情;
但最终是 Christof 实现了架构,这给我留下了非常深刻的印象和启发。
五金器具

好的硬件对于训练这些神经网络真的很重要。我们用了很多硬件,相信我,真的很多:)但是!我们还大量使用了 kaggle 内核:你可以同时用 P100 在 4 个 kaggle 内核中训练模型(现在只有 1 个),所以即使没有额外的硬件,我们也可以获得金牌。
结果和结论
我们的最终解决方案确保了我们的第八名和金牌。而我现在是 kaggle 大师:)

值得注意的是,我们的团队是能够获得比-3 lmae(各种类型平均绝对误差的对数)更好的分数的团队之一。在这个帖子中,竞赛主持人写道,他们会很高兴看到比-3 更好的分数,我们做到了!
我从这次比赛中学到了很多东西,下面我想分享一些经验:
- 看内核和论坛,他们提供了很多有用的信息;
- 做好做很多失败实验的准备。当你试图寻找下一个能提高你分数的新事物时,你会测试很多想法,但大多数都不会奏效。不要气馁;
- 总是寻找新的想法,阅读新的论文和文章。你永远不知道你会在哪里找到一个新的很酷的工作想法;
- 创建一个团队将使用的验证,以便实验具有可比性;
- 一个伟大的团队由拥有不同技能的人组成,他们应该涵盖不同的领域;
- Kaggle 比赛很有趣,尽管很累:)
我很幸运能和这些了不起的人一起工作,为此我要感谢他们!
机器讲的故事
艾写作的迂回之路
德克·克内梅尔和乔纳森·福利特

Figure 01: Our languages and our writing mirror the societies in which we live.
[Illustration: Saint Jerome Writing by Hans Springinklee German, 1522 woodcut, National Gallery of Art, Open Access]
你可能没有意识到,但人工智能已经在编写你可能已经读过的故事了。多年来,股票简介都是由机器编写的。最近,小联盟体育比赛总结也已经。接下来是长篇故事和小说吗?在加州大学圣克鲁斯分校,人工智能研究员 Snigdha Chaturvedi 和她的团队正在设计自然语言处理模块,有朝一日将使机器能够讲述长篇叙事故事。虽然目前这项技术令人印象深刻,但离这个目标还有很长的路要走。通过他们的研究,我们可以开始更好地理解自然语言生成技术将如何成为我们生活的一部分。

Figure 02: AI is already writing stories that you’ve probably read, like minor league sports game summaries.
[Photo: “Base hit” by Chris Chow on Unsplash]
语言是一面镜子
如果我们试图标记迄今为止人工智能写作的进展,我们会发现自己处于恐怖谷阶段——至少在涉及比股票广告或棒球统计数据更复杂的故事时。就像长相接近人类的机器人,其怪异的美学令人反感,人工智能写作同样可以表现为不太像人类,粗糙,有时古怪或跑题。对于人工智能研究来说,语言是如此具有挑战性的领域,原因有很多。
“语言是我们生活的社会的镜子,”查图维迪说。“所以,问题是当计算机科学家设计试图理解语言的算法时,他们通常不会考虑语言理解的社会方面。人类说的或做的大多数事情都由两个标准来定义:他们的个性和他们与他人的关系。”
查图维迪解释说:“人与人之间的这种关系在解释他们的行为和言语方面起着非常重要的作用。”。“如果你理解关系,你就能更好地解释人类行为。由于语言只是人类世界的反映,这将有助于理解语言。”所有这些因素都与上下文相关——这是人工智能努力解决的问题,至少在当前的实例化中是如此。人工智能在特定的专业领域可以无情地有效——例如破解国际象棋、围棋和扑克等游戏。在这些场景中,背景问题几乎无关紧要。粉碎这些竞争策略游戏的人工智能通常甚至不考虑对手。这只是看着瞬间的快照,以数学上最佳的方式行动。从计算和战略的角度来看,这是很难做到的,因为人脑基本上无法做到这一点。然而,人类擅长理解背景。如果人工智能要实现其拥护者为其设想的潜力,它必须在这一领域取得进展。
Chaturvedi 说:“在模拟或理解人际关系方面已经有了一些工作,但这是有限的。“这项工作面临两个主要挑战。第一个是超越了自然语言处理中大多数先前科学工作中使用的二元关系的主导概念。在这种二元关系的范例中,您假设关系只能有两种类型。例如,处理脸书等社交媒体数据的人会假设用户要么是朋友,要么不是。所以只有两种可能。因此,这些关系的二元性质。他们没有对人际关系做出更微妙的假设。这是因为从计算的角度,从自然语言处理的角度来看,发展这个微妙的概念更具挑战性。但是如果你想想现实世界的关系,它们并不是二元的。真实的社会关系可以有多个方面。例如,两个人可以是朋友或家庭成员,或者他们可能处于浪漫的关系中。他们可能是正式或非正式的关系。查图维迪说:“人们可能处于监督-被监督的关系中,等等。
二进制对工程师开发计算技术有重大影响。从某种意义上来说,用 1 和 0 来思考是一切开始的地方。二进制模式继续渗透到软件的行为方式中,比如查图维迪在脸书发现的粗糙的关系框架。真正的关系,其中存在一些意义和理解,要微妙得多,这又回到了问题的难度:不仅我们的各种关系是微妙的和非二元的,每个人的关系,以及他们独特的关系星系,可以与下一个人大相径庭。一刀切的方法不太可能让任何人满意。真正的理解至少需要更大的关系世界的背景和细微差别,以及一个人更小的独特世界的背景和细微差别。还有其他的问题:“这项工作的另一个主要挑战是融入人类关系的进化或变化的本质。想想看,人际关系不是一成不变的,而是随着时间而变化。例如,你七岁时的朋友可能与你现在的朋友大不相同。这在分析故事时甚至更为重要,因为各种角色之间关系的变化使故事变得有趣,”查图维迪说。
语境的挑战:这个故事如何结束?
那么,你如何开始解决人工智能讲故事的背景问题呢?Chaturvedi 和她的团队承担的一个研究领域是帮助机器识别一个故事的好结局。“我们试图解决的技术问题是,你有一个故事和两个结局选项,但两个选项中只有一个是正确的或更符合逻辑的,而另一个只是一个糟糕的结局。“对人类来说,这是一个非常容易解决的问题,”查图维迪说。“人类真的很擅长辨别两种结局中哪一种更合理,因为另一种选择在大多数情况下都是荒谬的。在这个项目中,我们希望看到计算机系统或人工智能算法识别明智的选择有多容易。如果计算机可以解决这个问题,这将意味着它对文本连贯性和常识性知识有所了解,以及是什么让技术变得有意义,等等。所以,事实证明,设计这样一个人工智能系统并不是一个容易的问题。”
这是一个明显的构建模块,首先,机器以某种有意义的方式开发理解故事的能力,然后潜在地开发它们自己的故事。不用说,这对写作专业人士来说意义重大。“所以这是一个具有挑战性的研究问题,因为识别好的或合理的结尾需要理解是什么让一段文字像一个故事一样连贯或合理,”查图维迪说。“如果你仔细想想,这是一个非常开放的领域问题。例如,很难雇佣一个能够写出所有规则来告诉我们是什么让一段文字连贯的人。这可能是因为我们作为人类,甚至不知道当我们判断一段文字是否连贯时,我们会考虑哪些因素。”
为了评估连贯性,Chaturvedi 和她的研究小组考虑了三个因素。首先,故事的结尾需要遵循事件的逻辑顺序。第二,完整的故事必须有一个合理的情感轨迹——发生在主角身上的事情必须有意义。最后,结尾需要和故事的主题一致。“我们提出了一个系统,可以将所有这三个因素缝合在一起……并判断一个结局是否与故事相符,”查图维迪说。“我对这个项目非常兴奋,因为它给了我一个思考文本连贯性和故事的机会。这促使我致力于一个更具挑战性的问题,即设计人工智能系统来生成完整的故事。”
Chaturvedi 描述了该团队研究的下一步:“我们正在尝试让机器与人类合作来生成一个短篇故事。所以,本质上,故事是由机器生成的,但人类是与机器合作或引导它生成特定类型的故事。从研究的角度来看,自动讲故事通常是一项非常具有挑战性的任务。它要求人工智能系统不仅能说出好的、语法正确的英语句子,而且它们必须结合在一起,形成一个连贯的故事。生成的故事需要主题一致。它应该有一个有趣的情节,有目标的人物,规则,关系等等。这个故事应该有情感流动。它应该有特定的道德价值,特定类型的结局,等等。换句话说,故事生成需要大量的规划和思考。这些挑战已经吸引了人工智能专家非常非常长的时间。”
“最近,人们对讲故事重新产生了兴趣,尤其是在自然语言处理领域,出现了一种称为深度学习算法的学习算法。这些更新、更好的算法的问题是,它们比传统的自然语言处理生成系统更难控制。在我们的工作中,我们希望通过让人类用户参与进来,对商店的再生过程有更多的控制。更具体地说,用户会告诉系统,他们希望看到故事后面发生的特定事情,系统必须一次一句地生成故事。这类似于在 Bandersnatch 中非常成功的互动讲故事的想法,这是在网飞播出的黑镜集。”
AI 和伟大的计算小说
2016 年,未来大学函馆分校的松原仁史(Hitoshi Matsubara)带领团队与人工智能合作开发了一部中篇小说,通过了日野新一文学奖的第一轮评审。法官 Satoshi Hase 认为这部小说结构良好,但其他方面有所欠缺,如人物描述。这部名为《电脑写小说的那一天》的中篇小说,是根据丹尼·刘易斯(Danny Lewis)为史密森尼杂志(Smithsonian Magazine)撰写的报道,使用以下过程写成的:首先,人类设计师写了自己的中篇小说,并将其提炼为基本组成部分:单词、句子和基本结构。基于这些参数,计算机使用一种算法从原始作品中重新混合出一部新的中篇小说。例如,它与在我们的短信中建议自动完成的技术重叠。显然,考虑到这种基本的方法,我们离竞争主要文学奖的机器还有很长的路要走。我们更多地处于工具开发阶段,在这个阶段中,应用程序不仅与让我们眼花缭乱的输出相差甚远,而且甚至不能以对实际训练有素的作者特别有用的方式运行。

Figure 03: We are a long way away from machines competing for major literary prizes. We are more in the tool development stage.
[Photo: “Library at Orchard, Singapore” by Fahrul Azmi on Unsplash]
一般来说,人工智能系统不擅长生成长文本。在最好的情况下,他们可以创建少量的内容,这些内容与故事中先于它的现有内容是一致的。然而,人工智能顺序生成的文本越多——它们的原始文本离它自己生成的内容之前的设定叙事越远——它就变得越不连贯。它似乎更像一个智能句子生成器,而不是一个作家。
“我们正在使用基于深度学习的系统,这些系统因理解起来非常复杂而臭名昭著。在很高的层面上,深度学习模型[是]数学表示的复杂集合,如矩阵和向量,它们相互作用,给你想要的输出。Chaturvedi 说:“虽然这种复杂性使它们变得非常强大,但数学表达方式甚至让人类专家或科学家都难以破译该系统到底是如何工作的。“现在,由于我们不了解这些模型是如何工作的,命令它们做一件特定的事情变得越来越困难,就像指示它们生成特定的故事情节一样。在我们的工作中,我们通过为这一信息提供一个特定的重要组件来引导模型包含人工监督。所以,本质上,主要的技术挑战是你如何教这些系统注意用户在说什么,用户希望故事中发生什么?他们在创作故事的时候是如何整合这些信息的?”
这是深度学习模型呈现的另一个更普遍的限制——甚至是风险。我们人类无法理解它们,也无法对它们进行逆向工程。他们的力量和潜力通过在大量数据上放松来创造他们自己的模型而被释放。但它把引擎变成了某种黑匣子,我们只有有限的机构去理解,更不用说在某些方面去调整了。不像过去的物理或机械系统,甚至更传统地由人类编写的软件,我们并不完全了解正在发生什么。
人工智能写作的应用
目前用于撰写金融或体育报道的人工智能系统在本质上是有限的,至少目前如此。Chaturvedi 说:“有几家公司对自动识别新闻故事、新闻稿文档等中的关键事件感兴趣,并将其转换为故事,以便人类或算法读者可以使用。”“这个过程基本上有两个步骤。第一步,训练一个人工智能模型,从新闻稿和此类文档中自动提取相关事件。不幸的是,这些人工智能系统的输出…不一定是一种好的、自然的格式。它通常以表格的形式呈现,可以方便地存储在数据库中,但不一定以易读的方式传达全部信息。因此,第二步是将这些表格状的事件数据转换成看起来自然的英语句子或故事。这是目前商业人工智能系统不擅长的一步,在这个过程中需要大量的人工努力。”
这些故事是使用模板生成的。“你可以把模板想象成人工或半自动生成的句子或带槽的短篇故事。机器的工作是获取一个模板,但是它必须选择一个与它工作的上下文相关的模板。一旦它选择了模板,它的任务就是用相关的类似素材的事件填充这些槽。”这些刻板的模板通常不能产生流畅的、像人类一样的散文:例如,至少就目前而言,它们不能意译。正因为如此,这种模板化的人工智能故事通常类似于复制粘贴的文本。“在实践中,当这些系统输出基于模板生成的文本时,人类进入系统并平滑内容,”Chaturvedi 说。
人工智能书写系统具有大量市场应用的潜力。Chaturvedi 说:“专业作家可以利用它们来获得关于他们下一部创作作品的想法。“你可以想象出更多类似的电影,但它们会在艾的帮助下制作,而不完全是人类作家写的。它们也可以用来改进现有的电脑游戏。这种系统的交互性质可以使它们在培训和教育领域非常成功。例如,你可以用这样的系统来教孩子们语言连贯和讲故事。人工智能生成的故事也可以用来帮助记者制作新闻故事。”
因此,虽然今天人工智能写作的艺术水平仍然很粗糙,但 Chaturvedi 看到了一条前进的道路,在那里生成的文本将得到很大的改善。这是否意味着有能力的小说不会很快由人工智能产生?“那需要一些时间。目前,系统通常试图生成短文本,并且这些文本限于特定类型的领域。对于生成更长的故事,我认为我们可能需要等待几十年才能拥有完全由人工智能系统生成的故事和由人工智能系统生成的小说,”Chaturvedi 说。“问题是,当人类写长文档时,比如小说,他们在头脑中为文档准备了一个叙述计划或故事情节。Chaturvedi 说:“当他们写一个句子时,它是在他们刚刚写的上下文中,以及他们对整个文档的想法中。这一切都回到了背景的挑战。机器甚至不能记住之前整个故事的背景,甚至不能记住它自己写的故事的整个部分。

Figure 04: One day, maybe sooner than we think, AI-based generation systems will enable amateur writers to express themselves in a professional manner, making it possible for essentially everyone to be a writer.
[Photo: “Weathered books” by Syd Wachs on Unsplash]
然而,Chaturvedi 设想了一个实际的未来,这种人工智能研究将发展为创意专业人士提供有用的工具,即使小说写作还有很长的路要走。“人工智能写作肯定会让职业作家的工作轻松很多。它不仅会在某些内容不正确、含糊不清或难以阅读时提供建议,还会为作者提供创造性的想法,帮助他们清除写作障碍。”有一天,也许比我们想象的更快,基于人工智能的生成系统将使业余作家能够以专业的方式表达自己,使基本上每个人都成为作家成为可能。此外,在新闻等领域,这种人工智能系统将能够大大减少记者的工作量,使他们能够专注于收集事实和有新闻价值的材料。Chaturvedi 说:“这也肯定有助于他们加快撰写报道的过程,为用户提供更多的实时新闻。”
Creative Next 是一个播客,探索人工智能驱动的自动化对创意工作者,如作家、研究人员、艺术家、设计师、工程师和企业家的生活的影响。本文伴随 第二季第四集— AI 与增强讲故事 。
微妙的闺蜜特质:通过 Spotify 和网飞了解你的闺蜜

Credit to Kaleb Bruel — Head of US Consumer Marketing @ Spotify
Spotify release 2019 年结束的时候已经是年底了。我惊讶于我的播放列表在全球范围内的流派和艺术家的变化。两年前我可以不停地听音乐歌曲,但今年我的音乐品味变成了流行和民谣。受 Spotify Wrapped 的启发,我决定做一个有趣的分析,不仅对我自己,也对我朋友的音乐品味进行分析,以弄清楚这些数据会给我们带来什么。
除了音乐,通过分析我们在网飞的观影历史,我很好奇我们的电影品味有多相似。通过了解这些细微差别,我可以节省决定看哪些电影或听哪些歌曲的时间,并在我们共度时光时更好地推荐我们的共同兴趣。
是的,像其他亚洲朋友团体一样,我们分享每一个订阅账户,包括 Spotify 和网飞·😄
你可以在这里找到我的 Github repo 的链接:
Spotify release 2019 结束时是年底。我惊讶于我的播放列表在流派和艺术家方面的变化…
github.com](https://github.com/giginghn/spotify-netflix-analysis)
概述
- 数据收集
- 数据分析
- 机器学习方法
- 结论
数据收集
- Spotify:
为了阅读 Spotify API,我需要通过他们的开发者网站申请许可和证书。然后,我在 R 中使用了一个由 Charlie Thompson 开发的名为 spotifyR 的包装函数,从我和我朋友的 10 个最受欢迎的艺术家中提取所有专辑和歌曲。
初始数据包含 22 列,其中 595 首歌曲来自我的列表,714 首歌曲来自桑的列表。然而,重要的是承认我没有使用所有 22 个变量,而只是使用了与音频功能高度相关的变量——根据 Spotify:
-
情绪:可跳性、效价、能量、节奏
-
属性:响度、语音、乐器性
-
语境:活跃度,声音
这些功能的解释如下:
- Acousticness :一个从 0.0 到 1.0 的置信度度量,表示音轨是否是声学的。1.0 表示音轨是声学的高置信度。
- 可跳舞性:可跳舞性描述了一首曲目在音乐元素组合的基础上适合跳舞的程度,包括速度、节奏稳定性、节拍强度和整体规律性。值 0.0 最不适合跳舞,1.0 最适合跳舞。
- 能量:能量是一个从 0.0 到 1.0 的度量,代表强度和活动的感知度量。通常,高能轨道感觉起来很快,很响,很嘈杂。例如,死亡金属具有高能量,而巴赫前奏曲在音阶上得分较低。对该属性有贡献的感知特征包括动态范围、感知响度、音色、开始速率和一般熵。
- 乐器性:预测一个音轨是否不包含人声。“Ooh”和“aah”在这种情况下被视为乐器。Rap 或口语词轨道明显是“有声的”。乐器度值越接近 1.0,轨道不包含人声内容的可能性就越大。高于 0.5 的值旨在表示乐器轨道,但随着该值接近 1.0,置信度会更高。
- 活跃度:检测录像中是否有观众。较高的活跃度值表示音轨被现场执行的概率增加。高于 0.8 的值很有可能表示该音轨是实时的。
- 响度:音轨的整体响度,单位为分贝(dB)。响度值是整个轨道的平均值,可用于比较轨道的相对响度。响度是声音的质量,是与体力(振幅)相关的主要心理因素。值的典型范围在-60 和 0 db 之间。
- 语速:语速检测音轨中是否存在口语单词。越是类似语音的录音(例如脱口秀、有声读物、诗歌),属性值就越接近 1.0。高于 0.66 的值描述可能完全由口语单词组成的轨道。介于 0.33 和 0.66 之间的值描述可能包含音乐和语音的轨道,可以是分段的,也可以是分层的,包括说唱音乐。低于 0.33 的值很可能代表音乐和其他非语音类轨道。
- 效价:从 0.0 到 1.0 的一个量度,描述一个音轨所传达的音乐积极性。高价曲目听起来更积极(例如,快乐、愉快、欣快),而低价曲目听起来更消极(例如,悲伤、沮丧、愤怒)。
- 速度:轨道的整体估计速度,单位为每分钟节拍数(BPM)。在音乐术语中,速度是给定作品的速度或节奏,直接来源于平均节拍持续时间。
2.网飞:
我在这里下载了我们 2019 年内的观看历史,并与 Imdb 数据集合并,提取电影属性和特征。
网飞数据集的一个缺点是它不记录重复的活动。所以如果我在 2019 年 12 月看《奇怪的事》,我在 6 月看的同一集会被 12 月的那集取代。
我最初从 Imdb 下载了 3 个数据集,每个数据集都包含电影的独特属性。出于分析目的,我将所有这些孤立的数据集集成为一个,并且只保留最重要的特征:
- 类型 —该备选标题的枚举属性集。以下一项或多项:备选、dvd、节日、电视、视频、工作、原创、imdbDisplay。将来可能会在没有警告的情况下添加新值
- 运行时间分钟 —标题的主要运行时间,以分钟为单位
- 类型 —包括多达三种与标题相关的类型(纪录片、戏剧、喜剧、电视剧、真人秀、犯罪、动作、冒险、惊悚等)。)
- 平均 —所有个人用户评分的加权平均值
- numVotes —标题获得的票数
数据分析
- 音乐分析

柱状图和雷达图都表明我们在音乐上有非常相似的品味,但是,我的歌有更多的声音,舞蹈性和效价(积极),而他的歌更活泼,更有活力,更有乐器感。这证实了我在分析之前的假设,因为当我喜欢听独立音乐和民谣时,桑的音乐品味一直是越摇滚和音乐。其实我们的歌都是很高能的,暗示了我们对流行歌曲的共同品味。
速度和响度也和旋律、和声或节奏一样重要,因为它们代表了歌曲的速度和力度以及它所承载的情绪。
比如一首歌的 BPM 和 dB 越高,这首歌的节奏越快,越强劲,就越趋于刺激和欢快。另一方面,低 BPM 和 dB 意味着歌曲速度较慢,暗示悲伤、戏剧或浪漫。

从上面的图表中可以看出,我们的播放列表的速度都接近 120 BPM,平均响度接近-9 dB,这表明速度快且充满活力。这再一次证实了我的期望,因为我们的前 10 名艺术家中的一些人有我们在锻炼或健身房中不断重复的歌曲。

我也对我们选择音乐的多样性感到好奇。为了利用数据集中的这个因素,我计算了标准偏差,然后计算了所有标准偏差的平均值,以获得能够代表我们播放列表多样性的数字。
从上面的条形图可以看出,桑的播放列表往往比我的更多样化。通过下面的图表,我们可以更深入地了解每个功能的多样性:

发现这些音频变量之间的线性关系也很有趣。
根据线性回归分析,当化合价增加 1 个单位时,能量和可跳舞性都增加大约 1.2 个单位。如果我们仔细观察桑的特征,他的歌曲即使在低价位也具有高能量,而我的播放列表在价位增加时具有显著更高的可跳性。

现在我们可以理解我和我朋友的音乐品味之间的细微差别,让我们直接进入我们对电影的选择。
2.电影分析

根据上面的柱状图,我和桑都喜欢电视剧,但是他比我更喜欢短片。事实上,我们的电影品味非常相似,因为我们都喜欢纪录片、喜剧、惊悚片、动作片、爱情片和剧情片。如果我们仔细看看,桑的电影列表在类型上又一次比我的更多样化。

平均来说,我们欣赏的电影评分在 7.0 到 8.0 左右,但根据 Imdb,我们的电影有多受欢迎呢?《冒险》是桑的热门电影,而我的惊悚片是 Imdb 上最受欢迎的。我们俩都喜欢动作片和戏剧类的电影。

现在,我们已经对数据有了一些有意义的了解,我想在预测应用方面更进一步。
机器学习方法
我们知道我和桑在音乐和电影方面的品味的差异和相似之处,那么什么是最有预测性的特征,可以准确地将一首歌或一部电影归类为更有可能被我选中或演唱?
为了找到最具预测性的特征,我们将计算所有预测变量的特征重要性。有两种常见的特征重要性模型——随机森林和 XGBoost。
在这个特定的问题中,我将对 Spotify 和网飞数据集应用随机森林分类器,因为它们都存在共线性问题。共线性是指某些独立变量高度相关的情况,这可以通过在 Python 中可视化相关图来检测。
选择 Random Forest 而不是 XGBoost 的原因是:
- 当有几个相关的特性时,XGBoost 倾向于选择一个并在几个树中使用它,这样其他相关的特性就不会被经常使用。因此,其他相关特征在分割过程中不再有帮助,并且它们不会带来关于已经使用的特征的新信息。
- 而随机森林中的每棵树都不是由相同的特征构建的,因为每棵树都有随机选择的特征。因此,每个相关特征可能有机会在树之一中被选择。因此,学习是并行进行的,所以每个树都不知道其他树使用了什么。
在发现协变量后,我们将尝试不同的机器学习模型,看看哪一个具有最佳性能,然后我们可以在该模型上进行优化。
- Spotify 数据

我们可以看到,声音、舞蹈性、能量、响度、活跃度、效价和节奏是歌曲分类的最具预测性的特征。
对于这个预测问题,我用分类算法来预测一首歌会被我听还是被唱。在平衡数据并将其分成训练集和验证集之后,我使用了 3 个模型:随机森林、逻辑回归和线性判别分析。
为了评估模型的性能,我决定访问 5 个核心指标来对每个模型的质量进行评分:准确性、精确度、召回率、F1 和 AUC。

从指标和 ROC 曲线可以看出,逻辑回归在 3 种算法中表现最好。但是,可以更好!然后,我将对逻辑回归进行超参数调整,看看模型是否可以改进。
为了优化这个模型,我将使用带有不同正则项的网格搜索来调整这个模型。
random.seed(123)#train test split
X_train_logit, X_test_logit, y_train_logit, y_test_logit = train_test_split(os_data_X, os_data_y, test_size=0.4, random_state=0)#generate random grid with l2 penalty
grid={“C”:np.logspace(0.01,0.001,10,100,1000), “penalty”:[“l2”]}# l2 ridgelogreg=LogisticRegression(solver=’lbfgs’)
logreg_cv=GridSearchCV(logreg,grid,cv=5)
logreg_cv.fit(X_train_logit,y_train_logit)#choosing the best parameters
logreg_cv.best_params_,logreg_cv.best_score_
然而,即使在调优之后,该模型也没有显著的改进。为了简单起见,我们可以将原始模型作为性能最好的模型。
2.网飞数据

从上面的特征重要情节可以清楚地看出,( 1)动作片、冒险片、喜剧片、纪录片、电视剧、真人秀是最具预测性的类型,( 2)电视剧是最具标题类型预测性的类型,( 3)平均评分和投票数是最具预测性的协变量,用于对哪部电影可能被我或桑观看进行分类。
同样,我将使用分类算法来预测一个移动是否会被我或桑观看。在上采样以平衡数据并将其分成训练集和验证集之后,我使用了两个模型:随机森林和线性判别分析。
为了评估模型的性能,我将再次应用 5 个核心指标对每个模型的质量进行评分。

从指标来看,随机森林分类器显然是赢家。AUC 分数为 65.8%,准确性分数为 65.5%,该模型在仅使用默认参数的测试集上表现相当好。我仍然相信这个模型可以通过超参数调整得到进一步改进。
我将再次应用网格搜索来寻找模型优化的最佳参数。
# Number of trees in random forest
n_estimators = [int(x) for x in np.linspace(start = 200, stop = 2000, num = 10)]# Number of features to consider at every split
max_features = [‘auto’, ‘sqrt’]# Maximum number of levels in tree
max_depth = [int(x) for x in np.linspace(10, 110, num = 11)]
max_depth.append(None)# Minimum number of samples required to split a node
min_samples_split = [2, 5, 10]# Minimum number of samples required at each leaf node
min_samples_leaf = [1, 2, 4]# Method of selecting samples for training each tree
bootstrap = [True, False]# Create the random grid
random_grid = {‘n_estimators’: n_estimators,
‘max_features’: max_features,
‘max_depth’: max_depth,
‘min_samples_split’: min_samples_split,
‘min_samples_leaf’: min_samples_leaf,
‘bootstrap’: bootstrap}#train test split
X_train_rf, X_test_rf, y_train_rf, y_test_rf = train_test_split(os_data_X, os_data_y, test_size=0.4, random_state=0)# Use the random grid to search for best hyperparameters
random.seed(123)# Create the base model to tune
rf = RandomForestRegressor()# For random search of parameters, using 5 fold cross validation,
# search across 150 different combinations, and use all available coresrf_random = RandomizedSearchCV(estimator = rf, param_distributions = random_grid, n_iter = 30,cv = 5, verbose=2, random_state=42, n_jobs = -1)# Fit the random search model and select the best param
rf_random.fit(X_train_rf, y_train_rf)
rf_random.best_params_, rf_random.best_score_

当我应用调整后的参数时,性能有了显著的提高,尤其是在精度方面,提高了 7.69%。
结论
通过探索性的数据分析和机器学习分析,我发现了自己的音乐和电影品味,同时更多地了解了朋友喜欢的流派。
据此,我可以断定,无论是歌曲还是电影,他的榜单都比我更加多元。此外,我的歌曲意味着更多的声音,舞蹈性和效价(积极),而他的歌曲更活泼,更有活力和乐器。另一个见解是,当我反复重复电视节目时,桑更喜欢短片。
为了更深入地进行分析,我找到了最具预测性的特征,这些特征可以准确地将一首歌或一部电影分类为更有可能被我选择或演唱,并相应地将其输入机器学习模型。在尝试了不同的模型来预测歌曲是否会出现在我或桑的播放列表中之后,表现最好的模型是逻辑回归。另一方面,对电影列表进行分类的最佳模型是具有调整参数的随机森林。
总的来说,我对我的发现非常满意,希望我的分析能够有意义,并对预测网飞和 Spotify 上共享帐户的歌曲或电影产生影响,以进一步改善用户体验!
参考:
- https://towards data science . com/a-music-taste-analysis-using-Spotify-API-and-python-e52d 186 db 5 fc
- https://medium . com/ml review/Spotify-analyzing-and-predicting-songs-58827 A0 fa 42b
在 CASP13 | Exxact 博客上总结了 DeepMind 的蛋白质折叠打乱
在去年的蛋白质结构预测竞赛的关键评估( CASP13 )中,来自 DeepMind 的研究人员通过以相当大的优势在自由建模类别中占据首位而成为的头条,基本上是最近竞赛中 CASP 预测进展速度的两倍。这令人印象深刻,这是一个令人惊讶的结果,就好像一个以前没有参与深度学习的分子生物学实验室要在现代机器学习基准测试中彻底击败有经验的从业者一样。
蛋白质结构预测问题
生物机器被编码为信息序列。所谓的分子生物学的中心法则认为,DNA 序列决定 RNA 序列,而 RNA 序列又决定蛋白质序列,因此当它们折叠成生物纳米机器时,结构就会产生生物特征。这是我们在这篇文章中关注的最后一步:预测蛋白质的三维结构,这反过来又构成了生命力学的基石。
想象一下,当你第一次看到一只折纸鹤,并试图对用来制作它的褶皱进行逆向工程时,你得到的只是一张展开的纸,上面覆盖着用外语写成的寓言提示。现在想象一下,这个逆向工程问题意味着用 1D 线而不是 2D 线折出一只鹤,而且它实际上是一只真正的鸟。这应该让你对蛋白质结构预测的难度有所了解。考虑一个短的多肽链,其中 100 个氨基酸之间的连接只能采用两个角度的三个值。每一个可能的肽结构构象花费 1 纳秒的时间将比宇宙的年龄长几个数量级,这是一个被称为莱文塔尔悖论的思想实验。

研究肽结构的蛋白质折叠时间图研究时间给定两个自由度和每个肽键的 3 个可能位置,并假设花费 1 纳秒对每个构象进行采样。
蛋白质结构预测是一个困难的问题,但潜在的影响是巨大的。蛋白质是细胞中结构和运动功能的所在地,也是生命复杂生物化学的信号载体和酶促指挥者。例如,蛋白质酶在称为活性位点的纳米级口袋中协调分子水平的化学反应。准确预测活性位点的结构以及它如何受到突变和小分子的影响,可以更好地为药物发现和蛋白质治疗提供信息。举个高调的例子,我们看看 Cas9,CRISPR 基因编辑中用来剪辑 DNA 的活性蛋白。2012 年 CRISPR/Cas9 作为遗传工具的演示承诺开放我们的生物源代码,但其潜力受到缺乏靶向特异性的限制,因为使用 Cas9 会增加导致非靶向 DNA 链突变的风险。理解 Cas9 的结构是设计基于 CRISPR/Cas9 的基因编辑系统以获得更好的特异性的关键部分。

Cas9 蛋白(灰色)与指导 RNA(红色)和靶 DNA(橙色)复合。蛋白质数据库蛋白质结构 4008
确定给定蛋白质的结构是一个资源和时间密集型过程,有大量的试错空间,并且绝大多数已知蛋白质都没有已知的结构。虽然蛋白质序列的数量遵循类似于其他以数据为中心的领域的指数轨迹,但已知蛋白质结构的数量正在以更快的速度增长。
DeepMind 的方法
来自 DeepMind,我们可能会期待一个用于蛋白质结构预测的大规模端到端深度学习模型,但我们错了。深度学习只是结构预测过程的一个方面,最终的结构实际上是梯度下降优化的结果。DeepMind 团队尝试了一种“fancier”策略,涉及使用生成式对抗网络(GANs)进行片段组装,但最终通过梯度下降优化获得了最佳结果。梯度下降被应用于来自他们的深度学习模型以及分子建模软件 Rosetta 的分数组合。在摘要中,碎片组装法和梯度下降法分别称为方法 1 和方法 2。
方法 1:片段组装
蛋白质的整体结构是由更小的片段结构单元组合而成;这些亚单位在某种程度上是模块化的,并形成在不同蛋白质和蛋白质家族中稍加修改即可重复使用的基序。这是使用多序列比对作为大多数蛋白质结构预测模型的一部分的主要原因。通过将新的蛋白质序列与具有已知结构的序列数据库进行比较,以具有相似序列的蛋白质中形成的结构为模板,可以推断出新蛋白质的亚结构。
值得注意的是,虽然 DeepMind 在他们的方法中使用了多序列比对,但他们没有使用任何模板。也就是说,虽然他们确实将这些序列与已知蛋白质片段序列的数据库进行了比较,但他们没有直接借用与这些序列相关的结构。他们使用一个生成神经网络来产生候选碎片,以插入到一个使用模拟退火的更传统的结构优化工作流程中。虽然 GANs 在过去几年中已经相当成熟,在重新生成图像等任务上取得了令人印象深刻的结果,但在这种情况下,结果并不是最先进的。为此,DeepMind 将结合新旧技术,采用深度学习进行评分,梯度下降进行目标优化。
方法 2:深度学习分数的梯度下降
DeepMind 获奖项目的核心深度学习方面是一个神经网络,它可以预测氨基酸对之间的可能距离,以及连接氨基酸残基的每个肽键的角度。然后,这两个预测与来自 Rosetta 建模软件的“score2”一起被合并成一个分数,随后是梯度下降,以直接最小化组合目标成本。这有点不公平地简化了所有的工程工作,而这些工程工作是为了让这个过程运行得如此之好,但是从概念上来说,获胜的预测策略出奇地简单。这不是一个端到端的深度学习项目,涉及 GANs 的 fancier 方法表现不佳。综合来看,DeepMind 条目表明,聪明的策略仍然可以击败大型深度学习模型应用的蛮力计算资源,并强调需要在机器学习硬件和软件栈中保持一些灵活性。这与 OpenAI 支持的方法有些不同,他们已经发表了令人印象深刻的结果,在>游戏播放、文本生成和音乐合成中使用了本质上相同的长短期记忆模型。

下一步是什么?
正如我们上面提到的,DeepMind 进入 CASP13 是对之前 CASP 比赛进度的向上偏离,他们以相当大的数量击败了该领域。由于他们坚实而令人惊讶的表现和高调的新闻报道,我们可能会担心问题已经解决,蛋白质折叠生物信息学家失业了。有些说法可能与事实相去甚远,但现实是,即使进展以 AlphaFold 设定的新速度继续,蛋白质结构预测仍需要大约 4 年左右的时间才能可靠地在任意蛋白质序列上实现 85%或更高的总拓扑结构。
端到端可区分模型和那些直接预测蛋白质结构的模型在 CASP13 上的表现明显差于 AlphaFold。蛋白质序列预测领域的一个独特挑战是,与其他领域相比,数据生成的速度很慢。这是我们在其他领域看到的具有大规模数据集的深度学习突破的一个障碍。另一方面,新的蛋白质序列继续以指数级的速度被添加到像 UniParc 这样的数据库中。我们已经看到了无监督学习可以为其他序列到序列域(如文本)做些什么,以及来自蛋白质序列的无监督学习的有希望的结果。将蛋白质序列的深度预测知识与我们在 AlphaFold 上看到的进步结合起来,是未来研究的一个充满希望但未得到充分探索的领域。
在这篇文章中,我们谈到了序列到结构预测的静态折叠蛋白质问题固有的挑战,但也有动态蛋白质折叠问题,这是为了理解折叠本身的过程。解决前者将使我们对生物学有重要的了解,通过更好的药物发现和蛋白质工程,可以作为生物技术和医学的改进。解决后一个问题将增加另一个顺序的困难以及一个顺序的好处。理解蛋白质折叠过程将有助于我们理解为什么好的蛋白质会变坏,正如它们在许多现代疾病中发生的那样,例如那些导致痴呆症的疾病。这也是面向数据的研究人员非常有前途的领域,他们正在寻找一个充满未解决问题的领域,在那里他们可以做出实质性的贡献,产生真正的影响。
原载于 2019 年 6 月 11 日https://blog.exxactcorp.com。
Apache Spark 的可扩展数据科学基础
IBM 高级数据科学专业
我的想法是,对 IBM 高级数据科学专业中可伸缩数据科学基础的关键概念进行分解

Photo by Carson Masterson on Unsplash
W 当在网上浏览数据科学/机器学习认证时,很容易在大量可用的产品中感到困惑和迷失。
我之前参加了斯坦福大学认证的著名的机器学习(在这里阅读),我非常喜欢。我原本计划继续在吴恩达工作,并从 deeplearning.ai 的深度学习专业开始。虽然这看起来很神奇,但我偶然发现了 IBM 提供的这个专业。
那么,是什么吸引我走向 IBM 的专业化呢?有两个主要原因:
- Apache Spark —这是最大的原因,云计算在机器学习的世界中非常重要,Apache Spark 在这个领域非常庞大。我对云计算的了解有限,也没有使用 Apache Spark 的经验,所以这对我来说是一个很大的卖点。
- 看起来更广泛(尽管可能更浅)的关注点,例如云计算、物联网和信号处理对数据科学的实际应用。
作为可扩展数据科学的基础,这篇文章自然是关于我在专业化第一部分(第一至第四周)的经历。我们还将涵盖:
- Apache Spark 的基础知识(架构、rdd 和 ApacheSparkSQL)
- 四个统计时刻(非常简短)
- 协方差、相关性及其各自的矩阵
- 主成分分析降维
我们开始吧!
可扩展数据科学基础
第 1 周—简要介绍…
本课程首先由课程讲师 Romeo(IBM 的首席数据科学家)简要介绍 Apache Spark,以及我们将在接下来的几周内讨论的内容。接下来是如何使用 IBM Watson Studio 安装 Apache Spark 的说明,IBM Watson Studio 是贯穿整个课程的云服务。
然后有两个简短的编程【任务】,只是为了确保你有正确的环境设置。这个星期可以很容易地在不到一个小时内完成,我不会称之为一个星期...
第 2 周—数据存储、Apache Spark、RDDs 和 SQL
在这里,我们开始了解不同的数据存储解决方案。即:
- 结构化查询语言
- NoSQL
- 对象存储
在讨论了各自的优缺点之后,我们开始学习 Apache Spark,重点是可伸缩性和并行处理。这部分其实很有意思!我们来看看 Apache Spark 的所有不同组件,包括硬件和软件。

The JBOD with HDFS architecture (left) and the off-node solution using a switching fabric (right)
我们了解到 ApacheSpark 是一个 Java 虚拟机(JVM)。为了加快我们的计算速度,我们可以并行使用多个工作节点,在如何分割工作负载方面,我们有两种选择:(1)在工作节点之间分割我们的数据和计算(JBOD 方法)或(2)在工作节点之间分割我们的计算,并使用“交换结构”从节点外的源提取数据。
选项(1)需要一个软件组件将物理上独立的存储磁盘视为一个磁盘,采用 JBOD(Just Bunch of Disks)方法(正式名称为 跨越 )。该软件是“Hadoop 分布式文件系统”(HDFS),它在工作节点的单个存储组件上创建一个虚拟视图,然后该视图可以被视为跨集群的单个虚拟文件。
选项(2)更简单,但由于节点外数据存储和工作节点之间的传输速度,延迟程度较小。这是我们在整个课程中使用的设置。
RDDs,SQL API
从这里我们可以了解更多关于 Spark 的架构和 API。Spark 将数据存储在弹性分布式数据集中(RDD)。我们可以创建一个随机数据集,执行简单的计算并收集前 5 个结果,如下所示:
import random
rdd = sc.parallelize(random(range(100), 100))
rdd.map(lambda x: x + 1).take(5)

或者,Spark 通过 ApacheSparkSQL 提供 SQL 支持。这将 RDD 封装在数据帧中,允许关系查询。然后使用 ApacheSparkSQL 进行交互。使用此设置查询 dataframe 产品中产品总体的产品大小的标准偏差的示例:
spark.sql(
"SELECT STDDEV_POP(p_size) AS sdsize FROM products"
).first().p_size
即使在使用 SQL 查询时,我们仍然可以直接与 RDD 交互,例如,如果我们想从一列中提取所有数据:
data = spark.sql(
"SELECT p_size FROM products WHERE p_size > 0.5"
)
data.rdd.map(lambda x: x.p_size).collect()
第 3 周—统计
这个星期很简单,但仍然很有用。我们着眼于四个统计矩以及协方差、协方差矩阵和相关性。最后我们引入多维向量空间。
在本周的第一部分,我们来看四个统计时刻:
- 平均值(或集中趋势的量度)(如平均数和中位数)
- 标准偏差(和方差)
- 歪斜
- 峭度
如果你有统计学背景,这些概念你大概知道。令人尴尬的是,我不知道峰度实际上被称为“峰度”,但尽管如此,它们都是非常容易理解和应用的概念。
接下来我们引入协方差和相关性,我认为它们更有趣。我们使用这些属性来帮助我们理解不同列之间的关系。

Covariance of two variables with different relationships
相关性只是依赖性的一种度量,如果两个维度之间有很强的正相关关系,我们会发现相关值接近+1,如果有很强的负相关关系,我们会发现-1。对于两个完全独立的维度,我们会发现相关值为零。

Correlation between two dimensions X and Y
为了计算相关性,我们需要计算维度 X、Y(见下文)的协方差超过两个维度的标准偏差。

Covariance between two dimensions X and Y
我认为非常有用的东西是相关或协方差矩阵,因为我以前遇到过几次。它们的功能相同,但一个测量相关性,另一个测量协方差。

Correlation matrix for dataset with four dimensions
在上面的相关性矩阵中,我们可以看到,第四维与其他任何维度都没有相关性。我们可以这样理解,第四维要么包含大量有用的信息,要么完全不相关。要在 Spark 中构建相关矩阵,我们可以使用 MLLib 库。
# data is a (number of samples (n), number of dimensions) array
# where we have 4 dimensions, data.shape = (n, 4)from pyspark.mllib.stat import Statistics # import MLlib
Statistics.corr(data) # get correlation matrix for dataOut []: array(([ 1\. , 0.98, -0.97, -0.12],
[ 0.98, 1\. , -0.97, -0.12],
[-0.97, -0.97, 1\. , 0.12],
[-0.12, -0.12, 0.12, 1\. ]))
一旦我们完成了 Spark 视频中的基本统计,我们就有了多维向量空间的最后一部分,这是非常小和直接的。接下来是本周的第二次也是最后一次测验和编程作业。编程任务简单而有趣,将上面学到的统计方法应用到 Spark 中。
第 4 周—可视化和 PCA
最后一周从快速浏览 matplotlib 绘图开始。Matplotlib 没有内置到 Spark 中,所以我们从 RDD 中提取数据,然后像往常一样将其输入 matplotlib。如果你已经使用 Python 了,这部分会超级简单。
接下来是降维。在这里,我们看一下如何使用主成分分析(PCA)算法来减少数据集中的维数(我将用非常简单的术语快速解释 PCA)。

我们了解到 PCA 用于降低数据集的维度,同时保留维度之间的关系。以上面的图为例,我们有一个三维向量空间(R^n ),我们想把它放入一个二维向量空间(R^k).我们希望找到一个表面,可以将 3D 数据映射到该表面上,同时最小化移动的距离。

一旦我们找到一个最小化距离变化的平面,我们就将 3D 点投影到新的 2D 平面上,从而降低维度。这实质上是找到变化不大的方向,并将其去除。在现实中,我们会经常处理高维向量空间,但简化概念是相同的。


在课程中,Romeo(讲师)指出,PCA 保持的关键属性之一是点与点之间的距离比,其符号如上。我认为这是一个有趣的观点,除了上面的解释,我认为肯定有助于提高我对 PCA 实际上在做什么的理解。
在 PCA 视频之后,我们有一个快速测验和一个最终的编程任务。两者都很简单,我发现这个编程作业是最简单的,因为之前作业中的大部分困难都源于缺乏 Spark 经验,但此时我感觉舒服多了。
最后的想法
好了,这就是 IBMs 高级数据科学专业化的第一部分!老实说,我认为课程非常简单,但同时也很好地介绍了 Apache Spark。
在这一点上,我唯一的小抱怨是编程任务可能太抽象了,我希望自己设置 RDDs 和 ApacheSparkSQL 对象,但是我认为这样做是为了保持专门化的介绍部分简单。
教练罗密欧非常好,我相信他非常有才华,他似乎有很强的解释一切的能力。内容是直接的,并且有很强的理论背景来加深对正在使用的工具的理解。
我在两周内完成了课程,同时工作也非常忙。所以它非常简短,但是我认为它很好地介绍了 Apache Spark。
总的来说,我对我学到的东西非常满意,我会向所有对数据科学云计算基础感兴趣的人强烈推荐这门课程。让我知道你的想法!
如果你有兴趣了解斯坦福大学的机器学习 MOOC,请看这里:
在快速变化的数据科学环境中,这仍然值得吗?
towardsdatascience.com](/a-review-of-stanfords-machine-learning-certification-9614ebee2b06)
谢谢,
系统的不良投资策略
介绍
财务困境和破产给公司管理、运营和供应商带来巨大压力。据估计,破产成本占企业清算价值的平均比例为 7.5%,最大的破产案收取的费用超过 10 亿美元。可以理解的是,学术界已经积累了大量关于第 11 章和第 7 章申请预测的文献。之前的研究分为使用基于市场的【2】(期权定价、信用违约互换)和基于会计的【3】(收益、债转股)方法。Hillegeist 等人(2004)建议研究人员使用 Black-Scholes-Merton 模型,而不是传统的测量方法,如 Altman 的 Z 分数或 Ohlson O 分数【4】。另一方面,Coelho 和 Taffler (2008)发现这两种方法的预测准确性几乎没有差异【5】。我们创建了一个能够跑赢市场的动态多空、贝塔中性的不良投资算法。
如果研究人员仅在他们的违约概率(PD)模型中使用财务比率,他们就隐含地假设所有关于公司未来轨迹的相关信息都反映在年度账目中。随着最近大数据的激增和市场定价算法的日益复杂,评估金融困境的第一站和最后一站不太可能是 10-K。幸运的是,最近的工作支持了基于市场和会计方法的结合。Chava 和 Jarrow (2004 年)发现,会计变量(如净收入占总资产的比例)和基于市场的变量(如公司股票市场回报的特殊标准差)都是破产申请的重要预测因素。最近,蒂诺科和威尔逊(2013)【6】采用尖端的机器学习工具来提高普通最小二乘回归生成的预测精度。对之前的进展采取整体观点为进一步建立当前的破产模型提供了一个有意义的机制。
行动(或活动、袭击)计划
我们探索了三条有希望的途径来制作实用的痛苦预测模型。首先,我们将宏观经济预测与可靠的市场和会计变量结合起来。其次,我们评估我们的破产预测模型是否可以用来创建系统的投资算法。第三,我们探索各种统计“技巧”,如 Z 得分预测和 winsorizing 值是否改善模型结果。我们的结果对破产过程中的各种利益相关者都有影响,包括:
1.重组顾问和律师:我们的模式独一无二,专注于上市公司。因此,重组顾问和律师可以利用该模型的建议,积极主动地寻找潜在客户,或试图通过提供债务管理援助来阻止破产。该模型还可以通过预测公司重组后重新申报的可能性来评估拟议计划的可行性。
2.困境和量化投资者:我们的模型提供了一种筛选潜在困境候选人和调查宏观经济前景的机制。对于定量公司,我们也构建了一个成功的系统的“不良投资”算法,旨在产生β-中性回报。
3.投资银行和保险公司:我们的模型可以作为内部预测系统的“健康检查”,确保银行贷款和保险信用违约掉期定价合理。
第 1 部分:一个全面的困境预测模型
我们复制了蒂诺科和威尔森提出的基于市场、会计和宏观经济的模型。这些数据涵盖了 1980 年至 2011 年期间超过 3000 家公开上市的公司,其中 379 家申请破产保护。强调我们对财务困境的定义是很重要的。按照传统的描述,如果一家公司的股票停牌超过三年,处于自愿清算状态,在申请破产时被摘牌,或者处于破产管理状态,那么该公司就是违约。更重要的是,我们还遵循 Pinado 等人(2008 年)的观点,如果 EBITDA 低于利息支出且市值连续两年下降,则将公司归类为财务困境。考虑到法律动议的日期并不总是与市场开始预期财务破产的日期一致,这种区分很重要。事实上,在合法申请破产之前,公司停止报告财务报表的时间平均为 1.17 年。我们的样本中有 5%(1254 家公司)被归类为不良资产。
所有后续的数据分析都是用 Python 完成的。5 变量 Altman Z 模型(1968 年)和 7 变量 Ohlson logit 模型(1980 年)表明,只需要几个变量就可以达到财务困境预测的高准确度。我们的第一步是使用递归特征消除(RFE)从超过 130 个变量中选择最重要的预测因子。RFE (1)在一大组初始变量上训练逻辑回归,(2)获得每个变量的点估计,(3)删除具有最低重要系数的变量,以及(4)重复该过程,直到仅保留最重要的特征【7】。
样本分为财务困境和健康的公司。结果是一个二元因变量,我们使用面板 logit 框架来考虑时变协变量。被归类为财务困境的公司被赋予 1 的值,而健康的公司被赋予 0 的值。RFE 以最大的区分准确性估计模型,其形式为:

Regression 1
其中 F(x) 代表企业陷入困境的概率 Pr(Y = 1|x),我们的预测因子分别代表会计、宏观和基于市场的自变量。
我们的递归估计器确定了四个会计比率、两个宏观经济变量和四个市场变量,与传统校准相比,这些变量提高了我们模型的预测准确性。图表 1 提供了所选预测值的相关矩阵;低共线性意味着我们的变量之间的高度互补性,每个变量都解释了响应中独特的方差【8】。我们现在考虑模型所选预测器背后的直觉。

1.1 会计变量
我们最后的四个会计比率包括营运资金对总负债、总负债对总资产、利息覆盖率和无信用区间。所有四个变量在以前的研究论文中都得到了充分的认可。营运资金与总负债之比将公司的现金流与公司获得的所有短期和长期负债进行比较。该比率在 Marais (1979)中因其对比内部现金产生和财务义务的区分能力而受到称赞。总负债与总资产的比率估计公司资产中负债所占的比例。如果一家公司经历了总资产价值的下降冲击,固定负债的不变利息支付通常会导致技术性违约。利息覆盖率是用来预测破产的最常见的变量之一,衡量公司满足即期利息义务的能力。
一个显著的结果是无信用区间变量的显著性。公式上,无信用区间的计算方法为(速动资产-流动负债)/((销售额-EBITDA)/365)。从实践的角度来看,无信贷区间估计了一家公司在不消耗流动资源的情况下,能够为运营支出融资的时间。而其他三个会计变量侧重于资产效率和信贷覆盖面,无信贷区间强调营运资本的稳定性。总的来说,会计比率集中在一家公司的特殊业务运营及其独特的债务、股权和资产组合上。
1.2 市场变量
股价、异常回报、相对于市场指数(规模)的市值以及相对于总债务的市值都证明在预测违约方面具有重要意义。基于市场的变量的数量清楚地表明,纳入实时数据作为会计变量的补充,在模型中提供了有意义的区分能力。异常回报和规模等变量凸显了公司相对于同行的表现。价格反映了投资者对股票的供求关系,而总债务的市值将股票的市场动态与债权人的现有债权联系起来。虽然会计变量侧重于公司资产和财务义务现金覆盖之间的关系,但基于市场的变量强调投资者对公司未来增长和现金产生机会的评估。
1.3 宏观经济变量
代表了一个从先前文献的关键突破,我们证明了将宏观经济变量纳入财务困境预测的效用。在 11 个宏观经济指标中,有两个包含在最终模型中:零售价格指数(RPI)和 3 个月期国债利率。零售物价指数衡量家庭商品和服务价格的变化。正如亚当·斯密以来的经济学家所详述的那样,鉴于工资增长滞后,名义价格的上涨与企业收入的增加相关,从而降低了破产的风险 [10] 。3 个月期国库券利率补充了零售物价指数对贷款利率的影响。在通货膨胀水平不变的情况下,较高的利率意味着一个经济体实际增长率的上升。实际 GDP 增长趋势的改善与更高的企业生产率和投资回报率相关,从而降低违约风险。总体而言,宏观经济变量的使用通过考虑公司财务的系统风险,填补了会计和基于市场的指标留下的空白。陷入困境的社区对宏观变量的不重视有利于对特质风险的关注,这是以理解违约概率的准确性降低为代价的。
1.4 结果分析
RFE 只确定哪种变量组合最具预测力。我们现在评估每个变量的个体对预测响应变化的贡献。在图表 2 中,我们展示了三种估计违约概率的模型:仅会计变量模型、会计和宏观模型以及完全综合的模型。我们估计公司财务困境前一年和两年的违约可能性,以提供更大的预测灵活性。

我们强调了歧视性分析的三个关键发现。首先,宏观经济变量在一年期和两年期都具有统计显著性,即使在模型 3 中控制了会计和基于市场的协变量。其次,我们最全面的模型(模型 3)轻而易举地超越了基于蒂诺科和威尔森估计的行业标准奥特曼 Z 评分(图表 3)。我们通过曲线下面积、基尼等级系数和 Kolmogor-Smirnov 性能指标证明了模型结果的稳健性。第三,简单的 logit 模型符合更复杂的结构,例如神经网络分析。神经网络是一种典型的“黑盒”算法,它使用一组连接的节点与模型的预测器进行交互,以获得单个输出。与此同时,Logit 模型为个体预测者提供了简单的显著性估计,因此对行业专家来说更实用。

总之,我们利用递归特征消去法获得了一个对预测财务困境有用的会计、市场和宏观经济变量的混合。我们的模型优于当前的行业方法,并提供了一个简单的工具,可以很容易地被重组和不良投资从业者使用【11】。
第 2 部分:将模型扩展到不良投资
在第一部分中,我们得到了一个预测上市公司财务困境的综合模型。虽然我们“训练”了我们的模型对金融违约概率的响应,但很自然地质疑我们确定的预测指标是否可以用于系统的“不良投资”算法。一方面,传统的(基础的)信贷经理轻视运用算法投资于预期破产的公司的想法。另一方面,AQR 和 Citadel 等量化公司正大举投资于构建系统,做空财务困境公司的股票,并长期持有健康公司的股票。因此,我们提供了我们的观点对生动的辩论迷人的苦恼社区。
使用量子 Python 模块,我们重建了上面发现的预测器。我们将威尔希尔 5000 指数设定为我们的投资领域,并将我们的反应定义为公司的每月预期回报。我们给有正远期收益的公司赋值 1,给有负远期收益的公司赋值 0。如上所述,我们采用以下形式拟合 logit 回归:

Regression 2
其中 R(X) 代表公司收益为正 Pr(Y = 1|x)的二元概率,我们的预测器分别代表会计、宏观和基于市场的预测器。
我们讨论了我们在系统投资中的三个关键发现。首先,一个简单的 logit 模型使用了我们在第一部分中的预测值,其精确度和召回率【13】为 49%(图表 4)。换句话说,我们的 logit 模型比抛硬币,打赌如果我们正面着地,股票会上涨更糟糕。其次,即使我们使用机器学习来捕捉数据中的高阶交互,我们的梯度提升算法在预测回报时也只有 51%的精度和召回率——仅略高于随机猜测。第三,我们的机器学习算法没有将任何宏观因素识别为对公司月度回报具有统计意义的预测因素。然而,当我们将预测范围扩展到季度和年度回报时,3 个月国债利率和零售价格指数都成为我们模型的重要特征。总的来说,预测市场回报的微弱成功令人羞愧,并强调了超越容易获得的定量数据的重要性。

作为我们分析的最后一步,我们评估是否可以将梯度推进的轻微预测优势转化为持续的利润。我们首先创建一个包含 300 只股票的基准长/空投资组合,平均分配给预测违约概率最低的公司的多头头寸和预测违约概率最高的公司的空头头寸。我们回溯测试结果的一个片段包含在图表 5 中,使用 winsorizing 和 z-scoring 等技术对我们的发现没有显著的改变。2008 年,我们的算法跑赢市场近 50%,年/年回报率为 5%。然而,在金融危机后的每一年,该算法的表现都大大逊于标准普尔 500,平均回报率为 2.5%。该算法表现一般的原因是样本中痛苦的频率。虽然 2008 年破产数量激增 31%,但上市公司的平均违约率通常在 5%左右。beta-中性的多头/空头股票算法需要一定比例的健康和不健康的公司,或者过度暴露于特定行业或公司的风险。

我们以两种关键方式解决基线算法的缺点。首先,我们评估改变算法可以启动多少多头和空头头寸的好处。其次,我们根据市场波动动态调整我们的空头头寸集中度。例如,如果 VIX 指数高于其长期平均水平两个标准差,我们的投资组合在所有头寸中 30%做多,70%做空。因此,我们利用系统性危机上升的时期,而不是保持相同的多空比例。如图表 6 所示,一个有 140 个多头和 40 个空头头寸的动态不良投资算法记录了一个 S&P500【14】的两倍。在整个回溯测试期间,我们的算法优于标准普尔 500 指数,同时将 2008 年的跌幅限制在-5%。通过解决我们的违约概率模型的简单实现中固有的弱点,我们成功地创建了一个能够在高度竞争的市场环境中生成 alpha 的算法。

结论
我们通过三个有意义的机制为行业从业者推进破产预测模型的构建。首先,我们再次强调了在破产预测模型中结合会计、市场和宏观经济变量的好处。蒂诺科和威尔森模型的 AUC 得分为 86%,超过了行业标准的奥特曼 Z 得分。其次,我们已经证明了使用我们确定的变量来准确预测市场回报的困难,即使是使用最先进的统计操作。最后,我们通过强调动态多空、beta-中性不良投资算法的功效,为我们的投资研究提供了一个顶点。我们的模型可以为重组顾问、律师、保险公司和有兴趣分别评估当前和潜在客户或投资违约概率的困境投资者提供实际指导。从银行家到量化分析师,重组领域继续为大数据领域的创新提供机会。
附录:

来自《走向数据科学》编辑的提示: 虽然我们允许独立作者根据我们的 规则和指导方针 发表文章,但我们不认可每个作者的贡献。你不应该在没有寻求专业建议的情况下依赖一个作者的作品。详见我们的 读者术语 。
Ang,James S,等《公司破产的管理成本:一个注解》《金融杂志》,第 37 卷,第 1 期,1982 年,第 219-226 页。提供研究进展的有用摘要。
【2】布莱克、菲舍尔和迈伦·斯克尔斯。“从理论到新的金融产品。”《金融杂志》,第 29 卷,第 2 期,1974 年,第 399 页。首次尝试基于市场的定价模式。
【3】《企业破产的预测:判别分析》《金融杂志》,第 23 卷,第 1 号,1968 年,第 193 页。是开创性的工作。
布朗、斯蒂芬等,“管理预测、诉讼风险和 FD 法规”SSRN 电子期刊,2004 年。
科埃略、路易斯·m 和理查德·j·塔夫勒。"市场对破产申请的异常反应." SSRN 电子杂志,2008 年。
赫尔南德斯·蒂诺科、马里奥和尼克·威尔森。"使用会计、市场和宏观经济变量的上市公司财务困境和破产预测."《国际金融分析评论》,2013 年,第 394–419 页。
【7】蒂诺科和威尔逊没有详细说明他们的变量选择过程,尽管我们在数量上得到了相同的结果。
【8】注意,TFOTL 与利息覆盖率的相关系数为 0.726,是所有变量中最高的。原因很明显,因为 FFO/TL 与 EBITDA/利息支出极其相似。然而,FFO 涵盖了 EBITDA 未涵盖的资本支出和营运资本变化,而 TL 涵盖了利息支出未直接涵盖的金融债务。
【9】Zmijewski,Mark E .《与财务困境预测模型估计相关的方法论问题》。《会计研究杂志》,第 22 卷,1984 年,第 59 页。
【10】重要提示:通胀上升可能会刺激美联储加息。更高的利率通常会限制信贷,增加违约风险。因此,重要的是要强调,在控制恒定利率时,较高的通胀会改善公司业绩,我们的模型通过同时回归 RPI 和国债利率来做到这一点。
参见霍华德·马克斯的投资者信。
【13】精度是 tp / (tp + fp)的比值,其中 tp 是真阳性的数量,fp 是假阳性的数量。精确度直观上是分类器在样本为阴性时不将其标记为阳性的能力。召回率是 tp / (tp + fn)的比值,其中 tp 是真阳性的数量,fn 是假阴性的数量。召回直观上是分类器找到所有肯定样本的能力。
【14】利用我们对负回报更高的预测准确性,我们分散了长期投资,集中于短期投资。
Reddit 的系统化文献综述

Image: Reddit Inc.
几个月前,我对 Reddit 上的研究进行了系统化的文献综述。
结果如何?我在 Reddit 上找到了 211 篇学术论文。
这包括在同行评审期刊上发表的作品、提交的会议论文、编辑过的文集的章节以及偶尔的博士论文。
Reddit 和 Twitter:它们如何比较?

Image: own
社会科学家喜欢 Twitter 这个平台。他们在上面发关于自己工作的微博,进行数字交流,偶尔关注恶搞账号。特别是政治科学家绝对喜欢推特。
现在我们来做一个两个平台学术研究的趣味对比。Reddit 有 211 部学术著作,相比之下:
- 2007 年至 2012 年间,Twitter 上有 380 篇论文( Michael 和 Proferes,2014 )
- 在推特和微博上有 575 次(威廉姆斯、沃里克和梅利莎,2013 年)
- 671 项关于社交网站的研究工作( Boyd,2015 )
- 127 在 Twitter 和政治选举活动中工作( Jungherr,2016 )。
按年份分列的研究产出
Reddit 成立于 2005 年,但直到几年后,其作品才开始出现在同行评审期刊和会议论文中。除了 2012 年的一个小插曲,研究产出同比有所增长。
这篇评论止于 5 月初发表的作品。考虑到这一趋势,如果今年的产量超过去年,我一点也不会感到惊讶。

Image: own
范式研究
大多数研究是定量的,其次是定性的和混合的方法。位于计算机科学和人机交互(HCI)的研究绝大多数是定量的。混合方法研究往往来自多个研究人员的项目,他们带来了各种各样的技能,以最佳方式接近研究目标。定性研究在大多数学科中都很常见。

Note: this number does not add up to 211 because it excludes non-empirical studies and chapters in edited collections which were derived from empirical studies from journals. Image: own
哪些学科研究 Reddit?
绝大多数研究来自计算机科学,其次是社会科学。最受欢迎的是健康、交流、文化和媒体研究。

Image: own
排除计算机科学有助于将社会科学的其他部分形象化得更容易一些。

Image: own
作为一个旁注,当我最初进行这篇评论时,我并没有期望从音乐研究中找到一篇研究。这项研究由 Kovacevich 和 Huron ( 2018 )完成,主要关注自主感觉经络反应(ASMR)音乐和/r/ASMR subreddit。有趣的东西。
文献综述法
这是一篇系统的综述。它有系统审查的要素,但没有声称自己是全面的(格兰特&布斯,2009 )。
2019 年 5 月至 7 月期间,通过在科学网和 Scopus 数据库上搜索单词“Reddit”和“subreddit”来确定文献的范围。谷歌学术的前 50 页被搜索,但没有进一步的。这是因为许多来自社交媒体分享功能的误报被发现。
从那里开始,我对高引用文章的书目和脚注进行了滚雪球式的搜索,这导致了更多的研究人员、研究项目和组织。其中包括来自计算机机械协会(ACM)图书馆和非营利组织 CivilSevant.io 的研究成果和会议文章
创建了一个包含每个研究项目信息的电子表格。这些包括:出版日期、研究名称、研究范式、学术学科、相关的第二个学术学科、使用的方法和出版类型(会议论文、期刊文章、书籍章节)。
以上信息是通过阅读期刊摘要收集的。如果信息没有在摘要中提供,文章本身被搜索关键词和略读来找到相关信息。
限制
如果关键词 Reddit 和 subreddit 没有包含在被搜索数据库的摘要或标签中,它们就不会出现在这篇文献综述中。
这项审查也仅限于一名研究人员。这意味着,如果研究的编码分类不正确,没有第二个研究人员来纠正错误。这是值得注意的研究,位于学科和方法以外的研究人员的知识和技能。比较系统的综述通常包括两个或更多的研究人员,他们或者独立地对研究进行分类,或者联合起来找出错误并加以纠正。⁴
脚注
- 我计划在 2019 年全年更新这篇综述,以说明进一步的研究成果。称之为有点整数偏差和做一个完人。
- 这导致 156 万次搜索命中。
- 检索的关键词包括:方法、研究方法、范式、定量、定性。这样做是为了加速文章的分析。
- 更深入的解释见代码间可靠性。
双城记——熊猫解开的谜团
珀斯真的比墨尔本更潮湿吗?

Photo by Ricardo Resende on Unsplash
最近我从墨尔本搬到了珀斯,我发现对这两个城市进行比较是很自然的。哪个有更好的咖啡?好的,这个很简单——墨尔本轻而易举!哪一个雨水更多——为了回答这个问题,我求助于我最喜欢的 Python 分析工具 Pandas。
我们将讨论什么内容
- 调查 25 年的年降雨量
- 使用 Seaborn 来观想并快速得出一些见解
- 找出哪个城市的雨天最少

Photo by Kieren Andrews on Unsplash
调查# 1——年降雨量对比
首先我们加载所有的常规包
接下来,我们导入来自 BoM 的降雨数据
注:我选择墨尔本机场气象站仅仅是因为 CBD 气象站已于 2009 年退役(参考http://www . BOM . gov . au/weather-services/announcements/vic/la trobe-site-closure . shtml)
现在,我们将单独的年、月、日列合并成一个日期时间索引,这将有助于下一步
选择一个重叠两个数据集的时期——我名义上选择了 25 年,这听起来对这项研究来说足够了
绘制年总降雨量,看看哪个城市的年降雨量最大。很明显,珀斯的年降雨量一直较高,然而这只是故事的一部分。

Annual rainfall comparison
附注:2011 年墨尔本降雨量超过珀斯的反常现象部分是由于拉尼娜现象。更多信息请点击此处https://bit.ly/2prGy68
调查# 2 —月降雨量对比

Photo by reza shayestehpour on Unsplash
看看 25 年研究期间的月平均值——这将显示墨尔本和珀斯的降雨量有多季节性
Pandas pivot_table 函数为我们提供了一种快速简单的方法来聚合所有的时间序列数据。
现在我们可以并排绘制两个月平均值

Monthly rainfall comparison
很明显,珀斯的季节性很强,大部分降雨发生在五月到九月。七月是珀斯最潮湿的月份,降雨量接近 150 毫米。相反,墨尔本全年降雨量稳定,每月约 20-60 毫米。
这就是为什么墨尔本人总是需要一把伞!
调查 3——未雨绸缪
虽然许多人关注平均降雨量,但很少关注下雨天数。我很好奇这是如何抓住墨尔本的“毛毛雨因素”的
我们可以使用方便的 Numpy where 函数,在这种情况下,该函数根据日降雨量不为零的条件返回标签“湿”或“干”。
现在我们可以计算出珀斯和墨尔本每个月的雨天数;其中有 25 年的价值。
现在,我们可以轻松地将这两个数据框连接起来,以便并排绘制它们。同时,我们可以快速得出每个城市每年的平均下雨天数。
鼓声……冠军是墨尔本,一年有 135 个雨天,珀斯以 109 天落后。

Photo by Pietro Rampazzo on Unsplash
最后,我们可以使用 Seaborn pointplot 来比较这两个城市,看看在任何给定的月份里有多少个雨天。

Rainy days per month
下雨天的降雨量有多少?
众所周知,并非所有的雨天都是均等的。有些只是毛毛雨,有些则是绝对的雨!
因为我们已经标注了雨天,所以在 Seaborn 使用线图来查看不同月份的降雨量是非常直接的。

Given that it is a rainy day — how much rain typically falls?
由此我们可以看出:
- 当墨尔本在 2 月和 11 月/12 月下雨时,往往会很大——这是典型的夏季倾盆大雨
- 相反,墨尔本冬天的雨天通常会下毛毛雨,降雨量只有 2-3 毫米
- 珀斯的夏末仍然很潮湿(下雨的时候),但是总日降雨量非常不稳定——因此在一月和二月期间蓝色阴影区域的置信区间很宽。
非常感谢你阅读我的第一篇博文!
笔记本和数据可以在这里找到
此时您不能执行该操作。您已使用另一个标签页或窗口登录。您已在另一个选项卡中注销,或者…
github.com](https://github.com/jay-stein/medium_tail_of_twocities)
两个宏 F1 的故事


在写完我的 2 部分系列多类度量变得简单( 第一部分 , 第二部分 ) 之后,我收到了来自读者的鼓励和有用的反馈,包括掌声、错别字更正等。首先,非常感谢所有的回复者!特别是一封电子邮件来自一位好奇的读者(他希望匿名,所以我称这位读者为“谜”),引发了对 F1 宏观平均分数计算方式的调查。这让我陷入了一个相当令人惊讶的兔子洞,我在这篇文章中描述了它。底线是:有不止一个宏观 F1 分数;数据科学家大多会不假思索地使用软件包中的任何可用内容。
快速提醒一下,第二部分解释了如何计算宏观 F1 分数:它是每个班级 F1 分数的平均值。换句话说,首先计算所有类的每类精度和召回率,然后组合这些对来计算每类 F1 分数,最后使用这些每类 F1 分数的算术平均值作为宏 F1 分数。在第二部分的示例中,猫、鱼和母鸡类别的 F1 分数分别为 42.1%、30.8%和 66.7%,因此宏观 F1 分数为:
宏-F1 =(42.1%+30.8%+66.7%)/3 = 46.5%
但显然,事情并没有这么简单。在电子邮件中,“谜”引用了一篇被高度引用的论文,该论文以一种非常不同的方式定义了宏观 F1 得分:首先,计算宏观平均精度和宏观平均召回率。然后,计算这两个指标的调和平均值,作为最终的宏观 F1 分数。在我们的例子中,宏精度和宏召回是:
宏精度= (31% + 67% + 67%) / 3 = 54.7%
宏观召回率= (67% + 20% + 67%) / 3 = 51.1%
因此,使用第二种方法,我用星号( *) )表示:
Macro-F1 * = 2×(54.7%×51.1%)/(54.7%+51.1%)= 52.8%
如您所见,Macro-F1 和 Macro-F1*的值非常不同:46.5%和 52.8%。
宏 F1 和宏 F1测量的是两种不同的东西。那么哪一个是“真正的”宏观 F1-score 呢?宏 F1 还是宏 F1?请继续阅读。
“Enigma”发给我的参考资料是 Marina Sokolova 和 Guy Lapalme 的“分类任务的性能测量的系统分析”。根据谷歌学术的说法,这篇论文有大约 2000 条引文。
以下是 Sokolova 论文中对 F1 宏观得分的定义:

(注意, l 是级数, M 代表宏。此外,β是一个可以用来调整精确度和召回率的相对重要性的参数。β=1 赋予了精确度和召回率同等的权重,也是我在我的文章中一直使用的。)
事实上,从上述论文摘录中可以看出,Sokolova 论文选择计算 Macro-F1*而不是 Macro-F1。
相比之下,其他参考文献选择计算宏 F1。一篇被广泛引用的论文是杨等人于 1999 年发表的“对文本分类方法的重新检验”[参考文献 2]。在撰写本文时,根据谷歌学术的统计,这篇论文被引用了 3695 次。以下是论文的相关摘录:

该段提到“在某些情况下使用了宏观平均值 F1[15]”。[15]参考文献是 Lewis 等人[Ref 3]在 1996 年发表的论文“线性文本分类器的训练算法”,其中作者明确指出“平均 F1 是 F1 在所有类别中的平均值”。
回到我们的问题:应该用宏 F1 还是宏 F1*?他们都试图将每个类的精度和召回值总结成一个数字,但是方式不同。在缺乏真正的领域特定问题的情况下,每种类型的错误都有一个定义的成本,使用任一种度量来总结模型的性能提供了一种简单但有些模糊的比较模型的方法。当部署一个真实的系统时,这些数字可能不合适,您需要根据手头的业务问题提供自己的指标。从这个意义上说,这两个指标都有相同的缺陷。重要的是要记住,在比较模型时要保持一致并使用相同的指标。
至于哪一个更受欢迎:如果历史是由胜利者书写的,那么——不管喜欢与否——度量是由软件包定义的。Python 的 sklearn 库是最流行的机器学习包,它提供了sklearn.metrics.f1_score函数,该函数计算宏 F1(而不是宏 F1*)。因此,大多数数据科学家和研究人员使用 Python 库函数来计算 Macro-F1,通常不会给予它第二个想法——正如我在“谜”的电子邮件进入我的收件箱之前所做的那样。
更新(2019 年 12 月 18 日):我收到了朱里·奥皮兹的一封电子邮件,他最近与人合著了一篇关于这个主题的论文,结果很有趣。具体来说,作者建议使用宏 F1 和*而不是宏 F1** ,因为它对错误类型分布不太敏感。我建议看看报纸;参见本文末尾的[参考文献 4]。
参考文献
[参考文献 1]索科洛娃、玛丽娜和盖伊·拉帕尔梅。"对分类任务的性能测量的系统分析"信息处理&管理45.4(2009):427–437。
[参考文献 2]杨,,。"对文本分类方法的重新审视" SIGIR 。第 99 卷。№8.1999.
【参考文献 3】Lewis,David D .等.线性文本分类器的训练算法。SIGIR 。第 96 卷。1996.
【参考文献 3】Lewis,David D .等.线性文本分类器的训练算法。 SIGIR 。第 96 卷。1996.
[参考文献 4]奥皮兹、朱里和塞巴斯蒂安·布斯特。宏 F1 和宏 F1。arXiv 预印本 arXiv:1911.03347 (2019)。
张量流概率的讲述

source — https://xkcd.com/881/
不管我们如何看待概率这个神秘的话题,我们都生活在一个随机的环境中。从永远难以捉摸的量子力学到我们的日常生活(“今天有 70%的可能性会下雨”,“及时完成工作的可能性不到 30%”……)我们都在有意无意地使用它。我们生活在一个“不确定、不确定、不确定”的世界里。因此,知道如何推理是任何人的武器库中最重要的工具之一。
在这篇文章中,我不会详细介绍或解释概率(那会使文章太长),也不会试图给出一些大概的描述。这篇文章是关于一个具体的问题,以及我如何使用 Python 和 Tensorflow probability 解决它。
在进入实现细节之前,我们将触及一些基本的定义。详细的介绍,你可以拿起任何 好的 书或者如果你时间不够,那么你可以看看这篇的优秀文章。
事不宜迟,让我们开始旅程吧。
我们想要解决的问题
掷一次公平骰子,如果结果是奇数,则掷一次公平硬币。否则,如果结果是偶数,那么公平的硬币将被投掷两次。在这两种情况下,都会计算人头数。获得的人头数的方差是多少?
当然,有几种方法可以解决这个问题。你可以在我得到它的原始 Quora 线程中查看它们。方法不同,但最终结果是 0.68 左右。
在这里,我们将看到如何使用 Python 和 TensorFlow-probability 来模拟一个实验,并验证我们之前获得的结果。
一个警告:我们可以使用任何其他包,例如 numpy,来实现相同的目标,但我开始阅读超级令人印象深刻和超级受欢迎的“ 概率编程&黑客的贝叶斯方法 ”,在最近的版本中,它已经被移植到 tfp(这就是我们从现在开始将如何调用 TensorFlow-Probability),因此我正在使用它。
随机变量和概率分布
在我们定义随机变量和概率分布的含义之前,我们需要给出概率的一个有用的定义。我将从我之前提到的精彩文章中引用它,因为我相信它很好地抓住了这个术语的本质,而没有任何数学工具。
概率论是一个数学框架,用于量化我们对世界的不确定性。它允许我们(和我们的软件)在不可能确定的情况下进行有效的推理
好吧,太好了。现在我们需要理解什么是随机变量,概率分布意味着什么。
随机变量—随机变量就是它所说的,一个可以取随机值的变量。然而,有一个小警告。它不能取任何随机值。每当我们谈论一个随机变量时,我们隐含地或明确地把它附加到一个叫做“样本空间”的东西上。这听起来可能有点可怕,但不用担心。
样本空间是在我们进行实验时,某个变量可以取的所有值的集合。比方说,为了简单起见,我们在抛硬币。那么样本空间可以表示为— {H,T} 其中 H 代表头部,T 代表尾部。因此,如果我们将投掷硬币的实验结果分配给变量 x,那么 x 的一系列值可能看起来像这样— {H,T,H,T,T,H,H,H,T…} 正如我们可以看到的,x 可以随机地取值 H 或 T,在每次实验结束时,我们记录下该特定值。
这里要注意一件事,我们还没有谈到任何偶然事件。我们刚刚建立了一个可以取随机值的变量。这是因为接下来会出现机会因素。我们称之为概率分布。
概率分布 —概率分布是一种确定随机变量在样本空间中取某个值的概率的方式(函数,数学上)。因此,从上面的例子延伸,假设我们正在扔一个公平的硬币,在这种情况下,我们有 50%的机会它变成正面,有 50%的机会它变成反面。我们可以使用称为伯努利分布的东西对此进行建模,其中我们可以提到事件 1 发生的概率为 p (p ≤ 1)(在我们的情况下,这将映射到头部),事件 0 发生的概率为 1-p(在我们的情况下,这将意味着尾部)。如果我们写一个代码,用伯努利分布来模拟抛硬币的现象,然后运行实验足够长的时间,我们会看到正面的百分比收敛到 50%,反面也是如此。
我们可以为一个可能有两种以上结果的实验(掷骰子)考虑伯努利分布的扩展。我们可以定义每个结果出现的概率。例如,对于公平骰子的情况,每个表面的概率是 1/6。我们称这种概率分布为多项式分布。(我没有说出全部的真相,多项分布并不是伯努利分布的真正扩展,而是二项分布的推广。而伯努利分布是二项式分布的特例。然而,为了这个实现,我们可以忽略这个细节。)
解决方案
我们现在掌握了解决这个问题所需的所有知识。我假设对“方差”、“均值”等术语有基本的了解。所以不打算解释了。也就是说,我给出了使用 Python 解决这个问题的逻辑步骤。
- 我们需要使用多项式分布来模拟骰子的投掷,并多次投掷骰子(实际执行实验)。为了解决这个问题,我们假设投掷骰子 1000 次。
- 我们需要记录每张脸出现的次数,并将其存储在一个列表中。
- 完成上述步骤后,我们需要取出列表中的每个成员,根据它是偶数索引元素还是奇数索引元素,我们必须抛出一个 number _ of _ times _ that _ index _ turned _ up (2 或 3)的硬币。为了更好地理解这种说法,让我们举一个例子——[1,3,2,1,2,1]。假设这表示投掷骰子 10 次的结果。这意味着在 10 次中,1 出现了 1 次,而 2 出现了 3 次。如此等等。一旦我们有了这个列表,我们需要一个接一个地检查它,根据不同的面(奇数或偶数),我们需要掷一枚公平的硬币,价值 3 或价值* 2 次。所以对于 1,我们只扔 3 次(在我们的实验中 1 出现的次数是 1)。然而,对于 2,我们将投掷它 6 次(它出现了 3 次,每次我们需要投掷两次,所以 3 * 2 = 6)
- 我们使用伯努利分布对投掷进行建模,并记录头部出现的次数(假设 1 表示头部)
- 我们在每次投掷实验结束时计算头部的方差,并将其存储在一个全局列表中
- 以上步骤我们都做很多遍,比如说 100 遍。
- 100 次结束时,我们取全局方差列表的平均值。
最后,这是我刚才描述的逻辑的代码。
这就是了,全局方差列表的平均值是…(鼓辊🥁) 0.68355…我们已经使用稳健建模和实验验证了数学预测。太棒了。
谢谢你读到这里。我知道这是一个很长的阅读,你一直非常理解我。再次感谢你。您需要安装 Tensorflow、tfp 和 numpy 才能运行此笔记本。使用 pip 安装它们相当容易,所以我就不赘述了。
如果你喜欢这篇文章,请尽情鼓掌,这将鼓励我以后写类似的文章。
另外,我正在和我的合著者 Tirthajyoti 写一本关于使用 Python 进行数据争论的书,很快就会出版。我们希望通过这种方式为生态系统增加很多价值。看一看或者捡一个;)如果你愿意的话!
最后,如果您有任何反馈,请通过 Linkedin 联系我(或在此发表评论!).我将非常乐意连接。
一会儿见:)
更新的文本分析初级读本:文本分析策略中的关键因素

A Venn diagram of the subfields of text analytics and how they relate (Miner, 2012)
简介
我们在过去 24 个月中创建的世界上约 90%的数据-平均每天 2.5 万亿字节-其中约 90%是非结构化数据,即文本、推文、图片和视频等内容(Griffith,2018)。在这个电子洪流中发现意义和目的的目标创造了文本分析行业(又名文本挖掘)。
这篇文章是为那些对文本分析的好处感兴趣,并且正在寻找如何形成一个高层次战略的关键考虑因素的决策者而设计的。这篇文章用 15 分钟的时间提供了主要观点和决定的简明概述,而不是花时间去梳理和理解数百页的教科书和期刊文章。请将本文视为数据科学之外或不熟悉数据科学的决策者的“备忘单”,以快速了解文本分析中的关键问题。
术语“文本分析”在 2000 年代中期开始使用;然而,它的前身“文本挖掘”在几十年前就被使用了,并且似乎起源于 20 世纪 80 年代早期情报界和生命科学行业中的现代计算形式(Hobbs,1982)。然而,文本分析的起源至少要早一个世纪。俄亥俄州立大学和东京大学的物理学教授托马斯·门登霍尔(Thomas Mendenhall)在 1887 年 3 月发表在杂志科学上的一篇论文中使用统计方法分析了成分特征曲线(Mendenhall,1887)。克劳德·布林肯分析了沈煜伦·柯蒂斯·斯诺德格拉斯 1963 年 3 月在美国统计协会杂志上的文章,以证明这是马克·吐温的笔名,而马克·吐温本身又是塞缪尔·l·克莱门斯的笔名(布林肯,1963)。哈佛大学的弗雷德里克·莫斯特勒(Frederick Mosteller)和芝加哥大学的大卫·华莱士(David Wallace)在 1963 年 6 月使用了带有泊松和负二项式的朴素贝叶斯统计模型来分析美国开国元勋亚历山大·汉密尔顿(Alexander Hamilton)和詹姆斯·麦迪逊(James Madison)中的哪一位撰写了联邦党人论文(莫斯特勒,1963) (马迪根,2019)。
文本分析的流行在很大程度上与电子邮件和垃圾邮件的普遍存在相一致,因为它过去和现在都常用于自动检测哪些消息可能是不想要的邀约。然而,随着智能手机和短信的出现,文本分析需求出现了第二个爆发点,随着社交媒体的出现,出现了第三个爆发点。随着数十亿用户开始在脸书、Twitter、Instagram、YouTube 和其他平台上发帖,大量数据应运而生,其中绝大多数是非结构化数据,而且大部分是基于文本的。
什么是文本分析?
早期的统计方法和基于规则的人工智能在很大程度上依赖于定量字段(数字)和统计模型来计算描述性统计数据,并通过回归、贝叶斯定理等粗略地模拟现实世界。因此,企业和其他组织想要回答的关于这些文本块中的事实、关系和情感的问题在很大程度上被锁定,并且在没有文本分析的情况下无法进行分析。
文本分析试图理解文本本身,识别或分类作者,或将文本与世界上的有形事物或事件联系起来。这意味着文本分析的处理可以——但不一定——涉及计算语言学、内容分析、信息检索和自然语言处理。许多文本挖掘涉及将文本分成片段或符号(比如关键词),并对它们进行加权,加权通常由一个单词或短语在一篇文章中的使用次数与其正常出现频率的对比来确定。其他特征通常包括单词的长度及其功能(Madigan,2019)。
可以说,对文本分析最感兴趣的,也是发展最快、影响最大的,是情感分析。根据作者的语言和行为对他们进行分类不仅有助于定制营销、说服或治疗的发展,如果人们可以从文本字段中测量情感,那么人们也可以测量和预测情感的变化(稍后将详细介绍)。
传统上,统计方法、模型和工具用于以二元方式(好/坏)对文本进行分类。其中包括线性和逻辑回归以及分类和回归树(CART)等判别模型,以及贝叶斯分类器和线性判别分析(LDA)等生成模型(Madigan,2019)。随着 2000 年代后期廉价和大规模计算能力和存储的出现,机器学习模型开始更普遍地使用,首先是有监督的机器学习模型,如支持向量机(SVM)。
机器学习在两个方面不同于传统的统计方法:(1)它是统计的一种健壮的蛮力应用;和/或;(2)它使用计算分析特有的算法,使软件能够发现和学习事物,就像人类一样,如果我们拥有无限或非常高的认知功能、回忆和完美的视觉。为此,机器学习是一种超越统计的进化,本质上是一种增强人类发现和预测我们否则无法发现和预测的事物的工具。

Project questions that can help determine the direction of text analytics projects (Miner, 2012)
最重要的研究问题
过于简单,并根据领域应用而变化,打造文本分析策略和方法的关键问题本质上是:“在数十种可用的机器学习算法中,有数百种变化,应该使用哪些算法,以及以什么顺序或周期使用?”正是在这里,数据科学和机器学习通才获得了很多次的关注,因为他们通常清楚地拥有更广泛的跨学科知识库,包括几十种算法,何时何地使用每种算法,以及它们不同组合的优缺点,这些组合称为集成。在此基础上,战略和方法为选择初始和次级方法、雇用团队、时间表、预算提供了信息,并确定了什么是可能的以及何时可能的可行性。
第二个关键的研究问题依赖于主题或领域专长。也就是说,人们试图发现或预测什么,以及从什么中发现或预测什么?这些特定的目标和目的通常来自于团队成员,他们精通应用领域空间,并且将使他们自己能够回答(和重复回答)问题,进行根本原因分析,并解释草案发现,或者审查培训和测试数据结果。
因素——主要考虑事项
可以说,研究问题的答案——在何时、何地使用哪些算法——是由四个先决功能问题或考虑因素的答案提供的:(1)是使用现成的文本分析软件、定制构建还是使用混合;(2)用作训练数据的文本源的可用性、准确性、多样性和标记;(3)使用监督或无监督的机器学习,通常由环境决定;(4)领域应用中的词汇覆盖和词汇需求;以及(5)时间表和预算。
或者,过多的方法和算法也可以通过关于项目的经典“你想做什么”问题来缩小范围(见上面的决策树图);然而,正确回答这些问题通常需要一些决策者可能不具备的文本分析和数据源知识。因此,本文的大部分内容集中在第一组先决条件问题上,这些问题更容易回答。
1。商业现成软件、定制软件或混合软件
至少有 83 种用于文本分析的商业现成(COTS)软件解决方案拥有足够多的客户,可以给他们提供评论和比较排名。许多应用程序和用例略有不同;然而,本质上是电子表亲。没有一个始终排在第 95 百分位以上;不过, DiscoverText 比较接近。
第一次发表在这里的二次分析对编辑和用户评论的总得分进行了比较,对该领域的领导者进行了排名(见下图和下表)。知道领导者应该考虑谁和知道落后者不应该考虑谁一样重要。一般来说,收费解决方案的表现总是远远超过免费解决方案。得分一般的提供商的名称已在可视化中剔除,以便有空间轻松查看领先者、落后者以及主要公司的解决方案排名(例如,Apache、Google、IBM、Microsoft、Oracle 等)。).右上角的解决方案具有最高的综合得分;左下角的答案得分最低。

Comparative rankings of 83 text analytics software packages

Top 10 text analytics software solutions ranked by aggregate critic and user review scores (Imanuel, 2019)
对于绝大多数应用程序来说,这十个应用程序中的一个或多个就足够了,并且代表了时间和资源的最佳价值,以在文本分析过程的主要步骤中获得非常好的(尽管远非完美的)结果。在许多情况下,选择大公司的产品(如 IBM、Oracle 等。),即使它们的排名比其他公司低,也可能是有益的,因为它们比拥有更高排名产品的小公司或初创公司拥有更广泛、更可靠的支持和文档。
如果存在建立定制系统以实现卓越性能的商业案例,或者因为领域应用中的特质,那么两种方法或算法的组合对于分类和情感分析重复表现良好,这是文本分析的两个最大步骤:(1)用于监督学习的支持向量机;(2)递归神经网络(RNNs)、卷积神经网络(CNN 或 ConvNets)和长短期记忆的组合用于无监督学习(,王,2016)(杨,2019)。在几乎所有情况下,免费或低价安装 Anaconda with RStudio 将允许已经编写的数千个 R 库在大多数算法组合中重用。下表列出了传统上用于文本分析的算法。

Machine learning algorithms traditionally used for text analytics (Miner, 2012)
2。识别&准备浩繁,准确&多样训练数据
选择文本数据源是工作的一半,因为训练数据及其不可用性是机器学习的一个肮脏的秘密。从业者和调查经常表示,数据科学 80%的时间和精力用于数据准备,对于文本分析,通常是文本来源(书面或音频)。为了有效,机器学习文本分析通常需要大量带标签的训练数据,以教会算法学习执行它们的预测任务。这里固有的是,数据应该是完整的、干净的、多样的、在未来随时可用的,并且是因果性的——而不仅仅是必然结果。此外,必须有足够的因果关联、标记和干净的数据来对不同的模型进行实验,以确定它们在通过训练测试循环进行预测时的相对有效性。
例如,如果一个人试图预测经济增长或收缩,他们将需要足够大的数量和多样性的干净和有标签的数据,以便能够确定这些数据元素中的哪些是因果性的(或指示性的),如经济何时增长或收缩,增长或收缩的程度,以及加速或减速的程度(可以说,这可能最好通过使用索尔福德系统的随机森林决策树来快速合理地完成,它可以轻松确定哪些元素是因果性的,以及其比例)。一旦确定了关键的因果术语,情感分析就可以推断出含义,而聚类可以监控情感的变化。
在许多情况下,这个先决条件是大量时间和资源的焦点,这是理所当然的。根据证券交易委员会(SEC)的公司 10K 备案文件、新闻报道或美联储董事会成员的声明,预测经济扩张或收缩是可能的,也可能是不可能的。可能需要进行多次数据搜索,才能找到最具因果性或最能预测预期结果的数据元素,之后,训练一个机器学习系统来监控和预测班次只是工作的后一半。
一旦数据源被识别,因果关系在其特征中被确认并被标记,数据清理和组织就可以由十几个 R 函数在容易访问和精通的库中灵巧地处理。
或者,文本分析可用于识别和监控趋势。这更像是一个分析功能,做起来更快更容易(更便宜),因为它不是试图预测结果。通常情况下,这意味着培训会以更快、更便宜的方式进行。该分析更侧重于概念提取,而不是因果关系和预测。即使是这些情绪趋势,也可以随着时间的推移进行监控,以检测群集转移时情绪的变化。
3。选择有监督或无监督的机器学习方法
使用有监督的或无监督的(更自动化的)机器学习进行文本分析的决定很大程度上取决于正在执行过程中的哪个步骤、需要分析多少文本、多久分析一次以及需要有多完美(例如,灵敏度与特异性)。较小的数据集可以更慢地周转,或者具有战略时间表,可能更适合有监督的机器学习方法。需要提供建议或预测流的大型数据集,不管时间表如何,都适合无监督的机器学习方法,前提是它们可以提供所需程度的准确性、敏感性和特异性。
4。词汇覆盖范围
将文本分析应用或调整到不同领域的关键步骤之一是推断情感或特征提取的准备。历史上,通过将单词转换成可以用二进制(0 和 1)表示的符号,创建了一种叫做的 n 元语法。使用迁移学习的新方法——重用以前模型中的元素——现在既更快又更准确。在拥有预测和分类情感的词典的情况下,FastAI 是在维基百科上预先训练的模型,是为特定领域应用建立定制语言模型的高级起点。通过使用 FastAI 语言模型,可以在其基础上构建特定的领域适应,然后是分类器,以实现最大的开发和处理馈送和准确性(95%的准确性是可能的)。通常还必须考虑其他领域的适应性;然而,词汇和词汇是普遍的主要考虑因素。
5。预算、资源&时间表
有一句格言说,请求可以被廉价、完美或快速地满足,你只能选择其中的两个,因为这三个都是不可能的。我 20 年应用预测分析和数据科学的经验证明了这一点。
金钱、人才和时间限制了大多数项目,包括数据科学领域的项目,这是一件好事,否则支出会令人作呕,投资回报也很难实现。关于使用哪些工具的决策通常取决于可用的工具。类似地,这可能取决于一个项目可以使用的人才资源以及使用时间。数据科学中的一个经典例子是,是使用 R 统计语言还是 Python 通用语言。虽然两者都有优点和缺点(我更喜欢 R ),但这可能取决于您的团队中有哪些语言可供您使用,哪些语言是您的队友知道的。
关于时间表,有监督的文本分析需要更多的劳动(因此,可能需要更长的时间);然而,自定义编码、特征提取和无监督机器学习算法的调整,尤其是对于预测,也可能是时间密集型的。较大的团队可能适合有监督的方法,而较小的团队(和更多的数据)可能适合无监督的方法。在关于价值的部分,有一个关于如何平衡这些考虑因素的建议,开始一个新的文本分析项目,它通常旨在快速赢得信誉和未来工作的更多资金。
高级问题——预测情绪趋势&可解释性
如果除了训练时间和努力之外,数据科学还有一个肮脏的秘密,那就是可解释性。大多数使用机器学习的消费者和决策者都是没有数据科学甚至统计学专业背景的高管。或者,即使他们确实有这样的背景,机器学习对于他们的领域专业知识来说也是足够遥远的,并且移动如此之快,以至于使其价值可以识别,但不详细或彻底地为人所知。因此,要让这些决策者使用预测模型,他们必须信任它们,而要信任它们,他们必须理解它们。因此,可解释性成为一个关键的考虑因素。
最大化可解释性的一个方法是使用可视化进行特征分析。一种受欢迎的可视化是自组织地图(SOMs),它本身是一种无监督的机器学习技术。som 根据相似的特征将数据分类成聚类段。例如,在电子商务领域,他们将客户群分为高消费但低消费群体,或高消费但低消费群体。在电子商务中,这表明如何通过营销或行为干预锁定一个群体。
在情感分析中,情感的积极或消极以及强弱也可以使用自组织映射(SOM)进行聚类。如果在不同的时间框架内重复这种分析,也有可能看到情绪是如何变化的,以什么方向,以什么速度或速率变化。从这些移动的聚类中,人们可以计算出具有置信区间的未来方向的概率。这使得摄取、分析、重复的循环方法成为必要,并且例如在概念提取之后向单词添加聚类功能。
例如,想象一下,在 10K 公司的备案文件中,用词正以越来越快的速度向经济收缩转变。人们可以在理论上以合理的准确度计算出衰退的概率,或者失业索赔,或者借贷或储蓄率。有可能预测经济走向的能力允许预防性干预以最大化其结果。
这些经济预测还可以基于不同行业、地区或两者的基于文本的大数据中的消费者或企业情绪进行,并汇集到多维数据库中进行可视化。这将使组织能够更准确地预测哪些部门或地区正在变冷,哪些部门或地区在不同时间以不同程度变暖,或者什么问题在哪里变暖,有时为什么变暖。
这里的关键是预测的概念。从历史上看,在进行观察、记录、分析和做出新的决策之间会有很长的等待时间。这些工具允许延迟在很大程度上得到改善,并转移到预防性政策或管理中,这也适用于发现趋势,而不仅仅是因果预测。
最终,可解释性是一个如此关键的问题,以至于专家们经常建议,最好有一个可理解的和可解释的方法或模型,而不是一个可能执行得稍微好一点但却无法解释的方法或模型。
价值主张
在一个完美的世界中,原型项目可以作为“概念验证”来构建,也可以通过有价值的新见解快速投入生产,投资以 1 万美元而不是 10 万美元来衡量。一旦这些原型被社会化并获得信任,文本分析的预算、时间线和复杂性可以发展,在此期间,更多的文本数据也几乎总是可用于更好地训练和通知结果、预测和趋势分析。随着时间的推移,基于文本的通信语料库在快速增长,因此使用文本分析的可能性与日俱增。
归根结底,价值或投资回报是大多数商业案例中关于在文本分析上投资多少预算(精力、时间、人才)的决定因素。一个使用 COTS 的三到六个月的项目可能是一些组织能够花费的最多的时间来获得正的 ROI。政府、跨国公司和医疗保健机构都有在进化浪潮中部署文本分析和其他形式的机器学习的商业案例。使用 COTS 或小规模趋势分析仪获得 60–75%的预测值,然后定制或扩展(更多地理多样性、数据输入、特异性或精确度,或任何目标)。
结论
文本分析可以为经济、金融、电子商务以及社会和地缘政治问题的公众情绪提供非凡的见解。在很大程度上,这是因为社交媒体上的人类行为和通信的数字化正在创建如此庞大的文本数据语料库以供挖掘。如果你领导一个组织或企业,在这个组织或企业中,预测消费者或大量人群情绪的能力是有价值的,或者分析情绪趋势以及它们在不同群体中如何随时间变化,你可能有一个商业案例,用真实世界的实验来探索文本分析。此后,可能最好从通才数据科学专家开始,他可以尽可能多地使用 COTS 工具快速原型化概念验证,以社交和探索兴趣和好处,了解更大的投资和定制解决方案团队是否、何时以及如何可能获得正回报。
参考文献
布里讷格尔,C. (1963 年)。马克·吐温和沈煜伦·柯蒂斯·斯诺德格拉斯书信:作者身份的统计检验。美国统计协会杂志,58(301):85–96。
格里菲斯,E. (2018 年 11 月 15 日)。我们生成的大数据中有 90%是非结构化的。检索自 PC 杂志:https://www . pcmag . com/news/364954/90 %- the-percent-of-the-big-data-we-generate-is-an-structured-me
霍布斯,j。沃克,d。阿姆斯勒,r。(1982)。对结构化文本的自然语言访问。第九届计算语言学会议论文集(COLING’82)(第 127-132 页)。捷克斯洛伐克布拉格:普拉哈学院。
伊曼纽尔。(2019 年 8 月 21 日)。用于文本分析、文本挖掘和文本分析的 63 大软件。今日从预测分析检索:https://www . predictiveanalyticstoday . com/top-software-for-text-analysis-text-mining-text-Analytics/
马迪根博士,刘易斯博士(2019 年 8 月 18 日)。文本挖掘:综述。美国纽约州纽约市:哥伦比亚大学。
t .门登霍尔(1887 年)。成分特征曲线。理科,9(214s):237–246。
Miner,g .,Delen,d .,Elder,j .,Fast,a .,Hill,t .,Nisbet,R. (2012)。文本分析的七个实践领域。在非结构化文本数据应用的实用文本挖掘和统计分析(第 29–41 页)。阿姆斯特丹:爱思唯尔公司。
f .莫斯特勒和 d .华莱士(1963 年)。一个作者问题中的推理。美国统计协会杂志,275–309 页。
王军,梁志友,赖,张,谢(2016)。使用区域 CNN-LSTM 模型的多维情感分析。计算语言学协会第 54 届年会会议录(第 225-231 页)。柏林:计算语言学协会。
杨,冯,杜,陈,黄,李(2019)。基于融合门的 R-CNN 和 C-RNN 的集成情感分析方法。国际计算机通讯杂志&控制,272–285 页。
Python 中的应用文本挖掘|密歇根大学
包括本课程涵盖的知识,本课程的优点和缺点。

这不仅是一次复习,也是我自己学完这门课程后的一次学习总结。
获得本课程的证书后,你可以带什么回家
文本挖掘简介
- 涵盖的技术技能:python list、string.split()、string.lower()、s.startwith(t)、s.endwith(t)、t in s、s.isupper()、s.islower()、s.istitle()、s.isalpha()、s.isdigit()、s.isalnum()
- 其他字符串操作:比如:s.splitlines()、s.joint()、s.strip()、s.rstrip()、s.find()、s.rfind()、s.replace(u,v)
- 处理文本句子
- 将句子拆分成单词,将单词拆分成字符
- 寻找独特的单词
- 处理文档中的文本
正则表达式
- 如何用 python 写正则表达式:元字符:字符匹配,字符符号,重复
- 日期的正则表达式
- 什么是正则表达式?
- 正则表达式元字符
- 构建用于标识日期的正则表达式。
英语和 ASCII
- 文本的多样性
- ASCII 和其他字符编码
- 在 UTF 处理文本-8
基础自然语言处理
- nltk 的基本用法:如何使用 nltk 删除停用词,探索 NLTK 文本数据的功能。
- 规范化和词干化
- 词汇化
- 标记化
- 句子分割
- 词性标注提供了对句子中词类/类型的深入了解
- 分析语法结构有助于获得意思
- 这两项任务都很困难;语言歧义甚至增加了难度
- 更好的模型可以通过监督训练来学习
- NLTK 为培训提供工具和数据
文本分类
- 文本分类的例子:主题识别、垃圾邮件检测、情感分析、拼写纠正
- 监督分类:二元分类、多类分类(当有两个以上可能的类时)、多标签分类(当数据实例可以有两个或两个以上标签时)。
- 使用 Sklearn 的朴素贝叶斯分类器
- 使用 Sklearn 的 SVM 分类器
- Scikit-learn 中的型号选择
- NLTK 中的监督文本分类
- 使用 NLTK 的 naive Bayes 分类器
- 使用 NLTK 的 SklearnClassifier
朴素贝叶斯和支持向量机(附案例研究)
- 朴素贝叶斯是一种概率模型,之所以命名为朴素贝叶斯,是因为它假定给定类标签的特征是相互独立的
- 支持向量机往往是最准确的分类器,尤其是在高维数据中
- 强大的理论基础
- 仅处理数字特征:将分类特征转换为数字特征,规范化
- 难以解释的超平面
从文本中识别特征
- 文本特征的类型:单词、单词的特征、句子中单词的词性、二元模型、三元模型、n 元模型
主题建模和 LDA
- 什么是主题建模
- 在 Python 中使用潜在狄利克雷分配(LDA)
- LDA 是一种广泛用于建模大型文本语料库的生成模型
- LDA 也可以用作文本分类和其他任务的特征选择技术
语义文本相似度
- 语义相似性的应用:将相似的词组合成语义概念,文本蕴涵,释义
- 使用 WordNet 的语义相似度
- 路径相似性,链接相似性,分布相似性:上下文
- 寻找单词和文本之间的相似性并不容易
- WordNet 是单词间语义关系的有用资源
- 存在许多相似性函数
- 对于许多这样的任务,NLTK 是一个有用的包
信息提取
- 信息抽取对于自然语言理解和理解文本数据非常重要
- 命名实体识别是解决许多高级 NLP 任务的关键构件
- 命名实体识别系统广泛应用了本课程中讨论的监督机器学习和文本挖掘技术
本课程的优点:
我想说,这门课程几乎涵盖了所有必要的知识和应用的文本挖掘的人谁想要应用文本挖掘到现实世界;正如这个课程的名字所暗示的,它是为想要申请的人准备的。
此外,它还包含了课堂幻灯片中的 sudo 代码和课程中的好作业。对我来说,边做边学永远是最好的学习和记忆方法,如果不练习,我会在几天内忘记我所学的东西。
这门课程的缺点是:
如果我一定要说这门课不好的话,我会说它太基础了,没有涵盖 NLP 中的任何高级知识和技能,甚至没有简单介绍神经网络中的 NLP。从我的角度来看,教师可以介绍关于 NLP 任务的迁移学习,或者 NLP 中的其他高级技术,如果学生想探索更多,可以提供一些参考。
另一件事是,这门课程教授多分类器的用法,但只详细教授朴素贝叶斯,根据我的经验,朴素贝叶斯分类器通常性能很差,而随机森林分类器总是有很好的性能,但讲座甚至没有提到它,这是不恰当的,因为这门课程是应用文本挖掘;或者也许这个球场是太多年前设计的,它需要更新。
总的来说,我会给一个 4-4.5 之间的分数,也许 4.25 是合适的。
但是如果你是文本挖掘的新手,这个课程对你来说值 5 星。
如果你想在 Coursera 上上这门课之前浏览一下这门课,可以在我的 GitHub 中找到这门课的 git repo。
部署机器学习模型的一千种方法——人工智能
“如果不部署到生产中,机器学习模型有什么用?”——匿名

Image from Pluralsight
您在构建令人敬畏的 99%精确的机器学习模型方面做了大量工作,但是大部分时间您的工作都是在没有部署的情况下完成的。大多数时候,我们的模型会与现有的网络应用、移动应用或其他系统集成。那么,我们如何实现这一目标呢?
我说一千,我想我只有几个。我猜你会在通过前两三关之前找到适合你的。或者你认为还有更多?一定要让我知道,让我们看看是否能得到一千😄。
让我们开始,我们如何部署机器学习模型或与其他系统集成?
1.通过人工授精
这包括通过应用编程接口(A.P.I)使您的模型可访问。
首先,我将部署一个由 Rising Odegua 构建的深度学习模型来对疟疾细胞进行分类。该笔记本可在此找到-https://github . com/risen w/Disease _ classifier/blob/master/model _ training _ files _ and _ output/notebooks/疟疾-cells-classification-DSN-海报. ipynb
然后我还将部署一个由阿米努·伊斯雷尔构建的简单的尼日利亚电影评论分类器模型。该笔记本可在此处找到—https://github . com/AminuIsrael/NLP-movie-review-model/blob/master/main . ipynb
通过 A.P.I 部署深度学习模式
在构建和测试您的深度学习模型之后,下一步要做的就是保存您的模型。这可以简单地通过添加这一行代码来完成
cnn_model.save('model_name.h5')
您可以将保存的模型移动到您的 A.P.I 代码可以访问的文件夹中。我将使用 Flask 进行部署,但是可以使用 Django、Starlette 或任何其他 python 框架。这是我的文件夹结构-

来到我们的 A.P.I 文件夹(由 Flask 提供动力),您首先要做的是安装需求。我在 requirements.txt 中保存了需求

您可以简单地通过在您的终端中运行它来安装这些需求
pip install -r requirements.txt

Import required packages
正如我们在将图像传递给神经网络进行训练之前对其进行预处理一样,我们也将对通过 A.P.I 端点采集的所有输入图像进行预处理。
在第 8 行,我们通过 A.P.I 端点将图像收集转换为一个数组。你会注意到你在一个标准上所做的有一点点不同,这仅仅是因为 Flask 的数据存储。使用第 9 行的代码在 Django 这样的框架上也可以做到这一点,或者从机器上的一个路径加载。

从第 10–15 行我们得到了图像的 RBG 版本,将图像的大小调整为 100x100,并将图像转换为 numpy 数组。我们还将我们的图像缩放到范围[0,1],如果没有错误发生,返回一个包含 True 的元组和一个包含我们图像的数组。

上面的图像显示了执行魔术的功能。
第 26 行仅仅意味着当调用“classify”端点时,将执行函数“classify_malaria_cells”。
在第 29 行,我们检查请求是否包含图像文件。然后,我们使用创建的辅助函数对图像进行预处理。
可以使用加载保存的模型
*from* keras.models *import* load_model# *OR*# *from tensorflow.keras.models import load_model*malaria_model = load_model(MODEL_PATH)
从第 34 行到第 39 行,我们加载了保存的模型,执行预测以确定图像的类别,并获得预测的准确度分数。在第 40 行,来自模型的结果被保存在一个 python 字典中,该字典将在第 60 行作为 JSON 响应被发送回来。
我们以下面的话结束我们的 A.P.I:
*if* __name__ == “__main__”:flask_app.run(port=8080, debug=False, threaded=False)
这样,我们成功地构建了我们的人工智能,并准备好部署到任何云平台。
部署到谷歌云
- 创建一个谷歌云账户—https://cloud.google.com/
- 创建一个新的谷歌云平台项目。您可以在这里按照步骤进行
- 在您的终端中找到这个 flask 项目的根目录并运行:
gcloud app deploy
**我还添加了一个 Procfile 用于部署到 Heroku ,只需按照这里的步骤进行部署即可。
通过人工智能部署机器学习模型
这与深度学习模型几乎相同。然而,在这里保存您的模型是完全不同的。你可以保存你的模型,使用—
import pickleFILENAME = 'filename.pkl'pickle.dump(trained_model, open(FILENAME, 'wb'))
或者
import joblibFILENAME = 'filename.joblib'joblib.dump(trained_model, FILENAME)
建议使用 joblib 来保存模型,而不要使用 pickle ,因为它在内部带有大型 numpy 数组的对象上效率更高。
正如我们对深度学习模型所做的那样,将您的模型保存在 Flask A.P.I 代码可访问的文件夹中。这是我的文件结构的样子

File structure for movie review A.P.I using Flask
我们这里的要求有点不同。

Requirements for running the Flask A.P.I for movie review
您可以简单地通过在您的终端中再次运行来安装这些需求。
pip 安装-r 要求. txt
接下来,我们将导入所需的模块并初始化一些变量。

import required modules

Helper function for tokenization
在上面的 helper 函数中,我们将句子拆分成单词,删除了从第 10 行的 pickled 文件中加载的停用词。在第 18 行,一个哈希矢量器被用来将单词标记成一个矩阵。这是一个 scipy.sparse 矩阵的输出。

我们的影评将采用文本格式。在第 24 行,我们检查所需的表单数据是否已经发送,然后我们给第 25 行的表单数据分配一个变量名。在第 28 行,我们用 pickle 打开并加载了我们的电影评论分类器(你可以用 joblib 实现同样的功能)。在第 29–36 行,我们将矢量化的电影评论传递到我们的电影评论分类器进行预测,计算预测概率得分,并创建 python 字典来传递我们的预测结果。然后输出在第 47 行作为 JSON 响应发送回来。
我们已经成功建立了一个电影评论分类 A.P.I,并准备部署到任何云平台。我还添加了一个配置文件,用于部署到谷歌云和 Heroku 。
这些都是通过人工智能进行的模型部署。您可以在这里归档本文中使用的代码—https://github.com/Emmarex/AThousandWaysToDeployModels
在我的下一篇文章中,我将分享如何使用 TensorFlow Lite 将机器学习模型部署到应用程序中。
感谢阅读👍
三管齐下的方法:如何找到一份数据科学家的工作

在我成为一名数据科学家之前,我花了很多时间在谷歌上搜索“如何获得一份数据科学家的工作”和浏览数据科学。也许你也在努力成为一名数据科学家,你不知何故登陆了我的博客。欢迎光临!
我写这篇文章有两个原因:
- 我想帮你!当我第一次开始时,我很幸运地从数据科学社区的慷慨成员那里得到了很多帮助。这篇文章是我回报处于我这种处境的人的一种方式。我们都必须从某个地方开始!
- 我发现我经常一遍又一遍地给那些找我聊天的人同样的建议,所以我想把我的想法放在一个地方。希望这篇文章能对你有所帮助。
如果您还有任何问题,或者我能帮上什么忙,请随时联系我!
请注意,这篇文章是为那些正在寻找毕业后第一份工作的人准备的,这也是我的情况,在这篇文章中,我只是根据我的经历来说。
首先……什么是数据科学家?
“数据科学家”这个术语非常宽泛,而且定义不清。我将粗略地将“数据科学家”定义为处理数据、进行分析和实验、构建预测模型来解决一些业务问题,并理解这样做所需的数学知识的人。他们使用机器学习,具有很强的编码技能,并且能够轻松阅读学术机器学习文献。他们可能更擅长数学而不是编码,反之亦然,但他们两者都很胜任,也很自在。这是一个技术性很强的角色。
背景、工作证明和人脉
在我看来,要成为一名数据科学家,你绝对需要三样东西。你需要合适的背景,你需要证明你的工作,你需要网络。
背景
为了成为一名数据科学家,拥有合适的背景非常重要。数学方面的量化背景(我有偏见!),计算机科学,物理或者工程都很棒。任何使用数据、思考实验和在某种程度上使用数学的学科也是如此。那些学科包括但不限于:经济学、心理学、生物学、地理学、化学、政治学等。有数学或计算机科学背景就足够了,但不是必须的。请记住,数据科学角色是一个技术角色。
如果你来自一个不太“正统”的背景,不要担心。如果你申请的公司值得为之工作,独特的观点是很棒的,应该受到欢迎!只要准备好投入工作来发展成为技术人员所需的技能。当你开始的时候,如果你在一个领域有所欠缺,而在另一个领域更强,那完全没问题。最重要的是做好学习的准备,不管你的技术背景如何。
工作证明
而且,不管你的背景如何,你都需要证明你的工作。
“工作证明”是指公开展示你的数据科学技能的任何东西。这意味着你有一个个人项目组合,或者你写了一篇论文(这篇论文任何人都可以得到),或者你在学校做了一些项目,等等。工作证明很重要,因为 1)它让人们验证你确实知道你在说什么,2)它让人们理解你的思维过程、工作流程和决策。
这个工作证明概念的“公共”部分很重要。一开始把自己放在那里可能会有点令人生畏,但这是值得的,而且会很有趣。就我而言,我最初创建博客是因为我想防止自己忘记所有的项目。我以为公开写下它们会让我负责任(过去是,现在也是)。结果很好,我的博客成了我在找第一份工作时为找工作做的最好的事情之一。
至少你应该有一个 GitHub 账户,里面有展示你的数据科学项目的存储库。更好的是博客(再次声明,我有偏见)。以这种方式展示和证明你的工作是一个向人们展示你不仅仅是证书的机会。你可以让他们看看你到底是谁!
建立工作关系网
说到向人们展示真实的自己,一个很好的方法就是通过社交网络。我喜欢把人际网络理解为“结识新朋友,从中学习。”
当你在找一份数据科学的工作时,人际网络非常重要。通过与做你想做的工作的人交谈,你可以:
- 决定你是否真的想做这份工作,
- 找出你需要的具体技能,
- 了解他们公司的文化,如果你想在那里工作,
- 了解面试过程,并获得提示,
- 了解期望薪资,
- 立即获得他们公司的推荐,
- 将来会被推荐到他们的公司,或者
- 交个新朋友(我认为最好的点!).
网络聊天可能不会核对我刚刚列出的每一点,但你肯定会从中获得某些东西。
我的建议(或者至少是我所做的)是列出一份生活在你的目标城市的数据科学家的名单,了解他们的背景,以及他们目前的公司。确定你对他们的哪些方面感兴趣,通过 LinkedIn 或电子邮件给他们发信息,比如:
你好,我最近获得了 Y 学位,正在寻找一份数据科学家的工作。我对你在 Z 的工作很感兴趣,你愿意边喝咖啡/打电话边聊吗?我将不胜感激,谢谢!
这里的关键是确保你真的有兴趣向他们学习。你可以通过倾听人们的经历学到很多东西,一般来说,人们都很乐意帮助你,尤其是当你请他们喝咖啡的时候。
当你见到那个人时,要记住以下几点:
- 准备好你的电梯间推介,并确保你告诉对方为什么你想和他们见面。
- 你与他们见面的理由应该不仅仅是“我想见你,因为你是一名数据科学家,我认为通过与你交谈,你会以某种方式帮我找到一份工作。”因为他们的背景,你有兴趣和他们见面吗?他们的行业?他们在社交媒体上的表现让你着迷吗?他们有博客吗?一定要让他们知道。
- 真诚地对这个人所说的感兴趣。这是你向他们学习的机会!
- 不要只是要求推荐或工作。如果这个人喜欢你(如果你是真诚的,他们应该喜欢你),那么如果有合适的工作,他们会给你介绍一份工作。
- 带着你能从这个人身上学到东西的心态去做,这是非常有价值的。每个人都有独特的经历,你可以从中学习。
- 主动为咖啡买单总是有帮助的,有些人会期望这样。
- 不要把人际关系网看作是一种交易交换。记住,你遇到的每个人都有东西可以给你,无论是知识、推荐还是友谊。
- 如果你现在没有得到推荐,并不意味着你将来也不会。
- 你现在遇到的这些数据科学家,将来会成为你的同行。数据科学社区很小。
- 见面后发信息感谢他们的时间,再次强调,要真诚。
- 如果你愿意,你可以问问他们是否认识你可以会见的其他人。
- 态度好点!
相信过程!有用!
现在你知道了。我成为数据科学家的三个建议:拥有合适的背景,证明你的工作,和网络。如果我说得不太对,请随时指出来。所有这些都只是从我自己的经历和对我有用的东西来说的。希望你从中学到了一些东西!
原载于我的个人博客:serena.mcdonnell.ca
利用 SARIMA 模型预测伊利湖的时间序列
数据科学:时间序列
模型选择、比较、诊断和预测的管道

Photo by Nick Saxby on Unsplash
执行摘要:
- 构建了一个季节性 自回归综合移动平均 ( SARIMA )模型来追踪五十年来伊利湖的月水位。
- 提供了使用以下技术选择时间序列模型的管道:频谱分析、差分、AIC、PACF 和各种稳健性检查。
- 在与真实数据交叉验证后,该模型准确地预测了结果。

Photo by Aron Visuals on Unsplash
与其他类型的统计模型不同,时间序列模型假设相关的观察值,并以一种有意义的方式论证昨天对今天的影响。在这篇文章中,我训练了一个 SARIMA 模型来预测伊利湖每月的水位。我将介绍整个流程,解释要做什么以及为什么要这样做。
- 加载、清理和转换数据集
#load the raw dataset
mydata<-read.csv(“monthly-lake-erie-levels-1921–19.csv”)
mydata_new<-mydata[-601,]#remove the last blank row
Lake_Erie_Levels_ts<-ts(mydata_new$Monthly.Lake.Erie.Levels.1921…1970,frequency = 12,start=c(1921,1))#turn into a TS model
# Plot the Dependent Variable
plot(Lake_Erie_Levels_ts,xlab=”Date”,ylab=”Levels”,
main=”Figure 1: Monthly Lake Erie Levels from 1921 to 1970")

作为经验法则,我们应该关注原始数据的异常值、趋势、季节性和明显的不连续性。
从图 1 来看,数据点在一定范围内上下移动,暗示恒定方差。
平均值沿着水平线(时间)每 12 个滞后有规律地移动,表明一个循环模式。我们将进行光谱分析来确定确切的季节性。
没有明显的间断。
2。初步准备:数据分割并检查季节性和平稳性
让我们把数据分成两组:训练和测试。
#We train a model using 90% of the data, aka. 1921.01–1965.12
training = window(Lake_Erie_Levels_ts,start=c(1921,1), end=c(1965,12))
#10% for the test set, aka. 1966.1-1970.12
test = window(Lake_Erie_Levels_ts,start=c(1966,1), end=c(1970,12))#test: 1966.1–1970.12; 10% as the test
让我们应用光谱分析来确定季节性。
install.packages(“TSA”)
require(TSA)
periodogram(Lake_Erie_Levels_ts);abline(h=0);axis(1,at=0.084)

光谱分析显示周期为 1/0.084 ≈11.9,非常接近 12。
我们决定季节性是 12,这是有意义的,因为我们有月度数据。
library(tseries, quietly = T)
adf.test(training)
Augmented Dickey-Fuller Test
data: training
Dickey-Fuller = -2.0622, Lag order = 8, p-value = 0.552
alternative hypothesis: stationary
为了测试平稳性,我们进行了一个扩展的 Dickey-Fuller 测试。
事实证明,数据不是静止的。
所以,让我们用差分来使数据稳定。从第一个差异开始:
training_diff1 <- diff(training,1)
ts.plot(training_diff1,ylab= expression(paste(nable,y)))
var(training_diff1)
adf.test(training_diff1)


太好了!数据集现在是静止的。随着时间的推移,平均值稳定下来,只有几个显著的峰值。
打安全牌,让我们检查一下是否有必要进行二次差分。
training_diff2 <- diff(training,2)
var(training_diff2)
adf.test(training_diff2)

在第二次差分后,模型仍然是稳定的,但方差增加,这表明过度差分。
3。模型构建和选择
library(PerformanceAnalytics)
chart.ACFplus(training_diff1, maxlag = 84, elementcolor = “black”)

为了确定滞后之间的潜在关系,我们在第一次差分后绘制 ACF 和 PACF 图。
这两幅图显示了强烈的季节性因素,因为 ACF 会定期死亡。换句话说,我们需要包括季节性因素。
training_diff1_seasonal12<-diff(training_diff1,12)
plot.ts(training_diff1_seasonal12)
chart.ACFplus(training_diff1_seasonal12, maxlag = 84, elementcolor = “gray”)


它在 1940 年前后变得稳定,只有几个峰值。
基于 ACF 和 PACF 模式,我们初步提出了以下季节性模型:
1。ACF 在滞后 1 后截止& PACF 拖尾→ SMA(1),或者 P=0,Q=1。
2。在滞后 12 处的 ACF 峰值& PACF 随季节滞后在 12、24、36 和其他处指数衰减→ SMA(1),或 P=0 和 Q=1。
3。ACF 和 PACF 都有季节性滞后→ SARMA(3,1),或者 P=3,Q=1
非季节性车型:
1.PACF 在滞后 1 → AR(1)后截止,或者 p=1,q=0
2。PACF 在滞后 1 之后切断& ACF 在滞后 1 之后切断→ p=q=1
3。PACF 在滞后 3 之后切断& ACF 在滞后 1 之后切断→ p=3,q=1
总的来说,我们列出了以下 6 款包含季节性和非季节性成分的潜在车型:
- 模型 1: SARIMA(1,1,0)*(0,1,1)12
- 模型 2: SARIMA(1,1,1)*(0,1,1)12
- 模型 3: SARIMA(3,1,1)*(0,1,1)12
- 模型 4: SARIMA(1,1,0)*(3,1,1)12
- 模型 5: SARIMA(1,1,1)*(3,1,1)12
- 模型 6:萨里玛(3,1,1)*(3,1,1)12
4。型号对比
########### use auto.arima to find the best model automatically
library(forecast)
model_auto= auto.arima(training, stepwise=FALSE, approximation=FALSE)#**this function takes a lot of time to run!!!!** summary(model_auto)#ARIMA(1,1,2)(2,0,0)[12] with AIC=670.27 AICc=670.45 BIC=695.31###### auto selection
model_auto_1= auto.arima(training)
summary(model_auto_1)# ARIMA(1,1,0)(2,0,0)[12] with AIC=672.23 AICc=672.31 BIC=688.91
内置函数( auto.arima )生成一个模型作为参考点,与手动选择的模型进行比较。
model_1 = arima(training, order = c(1,1,0),seasonal = list(order=c(0,1,1),period =12));model_1#AIC=553.74
model_2 = arima(training, order = c(1,1,1),seasonal = list(order=c(0,1,1),period =12));model_2#AIC=555.48
model_3 = arima(training, order = c(3,1,1),seasonal = list(order=c(0,1,1),period =12));model_3#AIC=548.71model_4 = arima(training, order = c(1,1,0),seasonal = list(order=c(3,1,1),period =12));model_4#AIC=556.94
model_5 = arima(training, order = c(2,1,1),seasonal = list(order=c(3,1,1),period =12));model_6#AIC=558.24
model_6 = arima(training, order = c(3,1,0),seasonal = list(order=c(3,1,1),period =12));model_7#AIC=553.14
我们运行这六个函数并获得 AIC 结果。模型 3 似乎是赢家,这与 ACF/PACF 提出的结果一致。
5。型号诊断
ts.plot(residuals(model_3))# a few spikes observed.
# normality check
shapiro.test(residuals(model_3))
qqnorm(residuals(model_3));qqline(residuals(model_3),col =”blue”)#skewed to the right as can be seen from the distribution that a few data points stand above the abline.



根据夏皮罗-维尔克正态性检验和 Q-Q 图,残差不是正态分布的。
chart.ACFplus(residuals(model_3), maxlag = 48, elementcolor = “gray”)

从 ACF 和 PACF 图来看,大多数残差点都落在 95%的置信区间内,只有几个显著的峰值。残差遵循白噪声模式。
Box.test(residuals(model_3),lag=22,type = c(“Ljung-Box”),fitdf=4) Box-Ljung test
data: residuals(model_3)
X-squared = 23.657, df = 18, p-value = 0.1666
残差在通过 Ljung-Box 检验后通过线性相关性检验。
#install.packages(“GeneCycle”)
library(“GeneCycle”)
fisher.g.test(residuals(model_3))[1] 0.436583
经过费希尔检验后,残差服从高斯白噪声分布。
6。预测
mypred <- predict(model_3, n.ahead=120)
Upper_tr = mypred$pred + 1.96*mypred$se
Lower_tr = mypred$pred — 1.96*mypred$se
ts.plot(training, xlab=”Year”,ylab=”Level”,main = “Forecast”)
lines(Upper_tr,lty=2,col=”gray”)
lines(Lower_tr,lty=2,col=”gray”)
points(mypred$pred,col=”blue”)
lines(test,col=”red”)#plot test data

灰色虚线是 95%的置信区间,红色线是真实的数据输入。所有预测点(蓝色)都落在 95%的置信区间内,并与真实数据紧密一致。
一个极好的预测!
我希望你们已经学到了一些关于时间序列的新知识。这种类型的模型对于研究涉及时间和空间的问题非常有帮助。
查看我的其他帖子。
- 机器学习:
2。数据科学:
- 项目评估
- 实验与因果推断:双向因果,为什么要实验?、陷阱、因果关系 vs 相关性
3。关于生活:
Photo by Alexa Gaul on Unsplash
老生常谈:半数普林斯顿论文在标题中使用冒号。

在一些部门,这个数字高达 85%。
几乎每个普林斯顿的毕业生——从参议员特德·克鲁兹到最高法院大法官埃琳娜·卡根,从女演员波姬·小丝到美联储杰罗姆·鲍威尔主席——都写过毕业论文。所有这些毕业生还使用了困扰近一半普林斯顿论文的有名无实的习语:冒号。
- Cruz '92 —“剪去天使的翅膀:美国宪法第九和第十修正案背后的历史和理论”
- 卡根 81 —“走向最后的冲突:纽约市的社会主义,1900-1933”
- 希尔兹 87 —“成长:从天真到经验:路易·马勒电影中的青春期前/青春期之旅,‘漂亮宝贝’和‘拉科姆·吕西安’”
- 鲍威尔 1975—“南非:变革的力量”
普林斯顿大学的论文数据库列出了近 7 万个题目,从 1926 年第一次建立高年级论文到今年 6 月毕业的高年级学生。我们可以使用这个庞大的数据集来发现名义上的殖民性(是的,实际上有一个术语)是如何开始的。

在整个数据库中,带有冒号的论文标题的数量是 43 %,但是随着时间的推移,这个数字急剧增加。这种趋势慢慢地建立了人气,直到 20 世纪 80 年代后趋于平稳。
在 1987 年和 1990 年之间有一个大的下降,但是在数据中似乎没有任何明显的原因。院系之间没有重大变化,入学人数也没有大幅增加。我联系了辛西娅·爱迪生,她是普林斯顿大学的校友(也是结肠使用者),在 1989 年写了论文。她说这是第一年所有的论文都是通过文字处理器而不是打字机来完成的。她认为,可能在学生使用的键盘上更难找到冒号,就像在现代键盘上找到外国字符一样——很难,但并非不可能。

Note: For clarity, “Romance Languages and Literatures” was combined with “French and Italian”, “East Asian Studies Program” was combined with “East Asian Studies”, and “Global Health and Health Policy Program” was combined with “Woodrow Wilson School”.
撇开后勤因素不谈,学术部门之间有很大的分歧。与人文学科相比,STEM 字段包含冒号的可能性要小得多。数学最低,为 10.6%,非洲裔美国人研究最高,为 92.3%。
然而,应该注意的是,一些学位的论文很少(非洲裔美国人研究是一个新项目,只有 13 篇,斯拉夫语言和文学只有 61 篇),因此更容易成为离群值。由于从 2000 年到 2019 年,超过 1700 篇论文在历史系下存档,我们应该更有信心,其中 86.1%的论文使用了挂名冒号来表征该学科。
冒号使用率最低的非词干类是音乐,占 42.5%。使用冒号最多的专业是心理学,占 64.4%。
一些前辈使用了多个冒号(例如“颜色:从装饰到大气:重新定义颜色在当代建筑中的作用。”)的记录?2003 年英语系的一篇 7 个冒号的论文题目“the:杂项:杂集:of:20 世纪:先锋-前卫:诗人。Pages.and.Books”。然而,像这样的例子并不常见,超过一个冒号的论文占数据库的比例不到 0.5%。
在所有包含冒号的三万个标题中,最常见的是在冒号前找到三个单词,在冒号后找到六个单词。
这对于学术界整体来说能说明什么?虽然这个数据库仅限于一所大学的原始论文,但这些数字与学术期刊上的数据高度相关也不是不可能的(分析是可能的,但数据集不太干净)。重要的是要考虑到普林斯顿的高年级学生正在有效地扮演一个学者的角色。他们可能会模仿,甚至夸大他们所阅读的文学作品中的趋势。
20 世纪 80 年代,教育、心理学和文学批评领域也进行了类似的分析。这项研究的作者赞扬了习语的多产使用,认为它的受欢迎程度表明了“学术事业的渐进复杂性”将近 40 年后,我们还能提出同样的论点吗?
有问题吗?评论?联系我,查看更多项目在 我的网站 。
SVM 的从头到尾——每个人的机器学习
我们的目标是用简单的理论、简单的数学和简单的代码提供对机器学习算法最简单有效的理解

Source: https://wallpapercave.com/w/wp3205387
我们将讨论以下主题:
1-概述
2-简介
3-SVM 是如何工作的
4-支持向量和余量
五线性和非线性 SVM
6-SVM 的硬保证金和软保证金
SVM 的 7- I/O
SVM 的 8-超参数
9-SVM 的优势
10-SVM 的挑战
11-SVM 的劣势
12-结论
概观
如果你不知道 SVM 是什么,它是用来做什么的,或者它是如何工作的,并且想知道所有这些问题的答案,那么你来对地方了。在这篇文章中,我们将从一个日常生活的例子开始探索 SVM,然后试图以简单的方式理解 SVM,保持我们的讨论简短而准确。那么,让我们开始吧:
SVM 代表 S 支持 V 向量 M 机器。它主要是一种分类算法。在我们继续之前,让我们讨论一下什么是分类
分类
如果我们抛硬币,我们要么得到一条尾巴,要么得到一个头,这意味着只有两种可能的结果,或者我们可以说硬币的某一面属于两个类别。分类是将任何事件的结果(如抛硬币是具有两个类别/结果的事件)分类到预定义类别(如抛硬币事件中的头尾)的过程。
简介:
SVM 用于将输入(稍后将详细介绍输入)分类为一个预定义的类别(如是/否或头/尾)。
如果 SVM 用于分类两个类,如头/尾,那么这样的分类器是二元分类器,否则它变成多类分类器
SVM 既是二元分类器,也是多类分类器
让我们用一个真实的例子来继续这个算法,这样我们可以更好地理解。
假设在一所大学里,学生注册了两门课——统计学和数学。根据学生在这些课程中的表现,教师必须决定某个特定的学生是否可以参加机器学习课程。换句话说,它是否会是“是”或“否”。现在,教师拥有过去学生的数据,并且教师希望根据学生的表现自动授予他们机器学习的权限。
显然,这是一个分类问题,我们需要一个能够解决分类问题的机器学习算法。
我们知道,SVM 是最好的分类算法之一。所以,让我们深入 SVM
SVM 是如何运作的
我们想对数据做的第一件事是通过绘图来查看它,这样我们就可以对我们可用的数据有一个大致的概念。

Source: Kdnuggets
从上图中可以看出,红色圆圈表示课程分数相对较低的学生,而蓝色圆圈表示两个课程都很好的学生。这意味着蓝色圆圈是我们的是的类,因为这些学生将有机会进入机器学习类,红色是那些不会进入机器学习类的学生。
我们 SVM 的任务是在这些阶级之间划一条线(是/否),这样这些阶级就不会相互混淆。这两个圆池(或这两个类)之间可以有无穷多条线。下面显示了两条可能的线:

Source: Kdnuggets
我们可以看到,两条线都做了将这些类彼此分离的工作,并且线两边的类没有混合。
SVM 背后的整个理念就是划清界限(将各个阶级区分开来)。
SVM 画的分班线叫做超平面。在上图中我们有两个超平面。那么,选哪个呢?
正是这个问题的答案将 SVM 与其他分类算法区分开来。SVM 选择类别之间分离最大的线(或超平面)。
或者我们可以说,SVM 选择了与两边的圆(或点)有最大距离的超平面。但是在图 so 中有很多点,计算距离时要考虑哪些点。SVM 认为最接近超平面的点如下图所示:

Hyperplane, Margin & Support Vectors (Source: Kdnuggets)
SVM 的支持向量和利润
可以看出,这个超平面与两侧最近点的距离最大。这些点有助于确定最佳超平面,因为只有这些点是最近的点。因此,这些最近的点(上图阴影区域中的两个点)是支持最优超平面的点,由于这个原因,这些点被称为支持向量。支持向量之间的距离称为余量。
我们现在可以说SVM 试图最大化边际以便在阶级之间有一个很好的分离。
除了超平面(上图中的黑线),我们还有另外两条支持向量所在的线。我们的主超平面(黑线)被称为决策边界,以区别于其左侧和右侧的其他两个超平面。
线性和非线性 SVM
线性 SVM
我们上面的数据在两个类之间有一条直线。这意味着数据是线性可分的或由一条直线。在类之间画直线超平面的 SVM 叫做 LSVM 线性 SVM。
非线性 SVM
但是在现实生活中,数据并不总是线性可分的。在这种情况下,SVM 不会在两个等级之间画一条直线,而是画一条曲线,如下图所示。(注意,我们现在讨论的是非线性 SVM)

Non Linear Data (Source: Kdnuggets)
在这种情况下,我们不能完全分开这两个类。有两种可能性:
→ 要么我们画一条曲线来完全区分阶级
→或者我们考虑到一些错误(错误分类),并将其线性分离
在前一种情况下,我们谈论的是非线性 SVM。内核技巧将帮助我们实现那条曲线。因此,核技巧只不过是一种改变超平面形状以避免错误分类的方法。默认内核是线性。
SVM 的硬利润和软利润
如果数据是线性可分的,那么 SVM 可能返回最大的准确性,或者我们可以说 SVM 做了完美的分类。这样的余量被称为硬余量 。但有时,我们没有线性可分性,为了在如此混乱的数据中绘制线性,我们必须放宽我们的余量,以允许错误分类。现在这个(放松的)余量被称为软余量
SVM 的输入/输出:
SVM 总是期望数字输入并返回数字输出。因为它是一个监督算法,所以除了输入,它还需要标签。输入(X1,X2)和标签(Y)的示例如下所示

Source: Jason Brownlee Book on ML
SVM 的超参数
超参数用于调整算法以最大化其准确性。每个机器算法都有特定的超参数。
SVM 也有一些超参数。让我们讨论其中的一些。
超参数 C(软边界常数)
在后一种允许一些误差(或误分类)的情况下,我们通过称为“C”的参数来控制误差量。它可以是任何值,如 0.01,甚至 100 或更大。这取决于问题的类型和我们拥有的数据。
c 直接影响超平面。c 与边距的宽度成反比。所以 C 越大,边距越小,反之亦然。C 对利润的影响如下所示:

C = 0.1 (Large Width) Source: yunhaocsblog
现在让我们将 C 的值增加到 10,看看它对利润的影响。

C = 10 (Small Margin)
所以选择 c 并没有严格的规则,它完全取决于问题和手头的数据。
超参数γ
我们之前已经讨论过,超平面仅基于支持向量来决定。支持向量之外的点不被赋予任何权重。但是伽马超参数用于给支持向量之外的点赋予权重。
gamma 的小值表示支持向量之外的点将在计算余量(或决定超平面)时被赋予权重,反之亦然。
但是我们为什么要这样做呢?嗯,改变γ的值会改变超平面的形状,从而改变新的超平面→新的精度。因此,归根结底,准确性才是最重要的。不管我们如何实现它。
SVM 的内核技巧
如前所述,内核用于将不可分离的数据转换为可分离的数据。这是通过改变 SVM 模型中内核的名称来实现的。
一些内核有、 多项式、径向 等。
SVM 的优势
→能够有效处理少量数据
→当特征数量大于样本数量时可以工作
→在高维空间有效(核技巧)
→内存高效—使用训练数据的子集(仅支持向量)
→可以控制过拟合和欠拟合(使用 C 超参数)
SVM 的挑战
→选择合适的内核及其参数
→在硬利润/软利润之间选择
→选择正确的 C 值
SVM 的缺点
→当我们拥有大型数据集时,它的性能不佳
→对噪声数据敏感(可能会使数据过拟合)
结论
综上所述,SVM 是一个有监督的机器学习算法,既能分类又能分类,但以分类而闻名。它主要用于文本分类以及许多其他应用。
SVM 的数学和编码以及其他算法都在计划中,将在未来的故事中讨论
谢谢你
极客的火鸡算法
正常人称之为“配方”

Credit: Gado Images
勇敢地自愿烹饪今年的感恩节火鸡(或者被拉去做)?感觉被 YouTube 上接二连三的美食博客和美食网络剪辑淹没了吗?
不要!烹饪就是设计一套预先确定的步骤,并按照这些步骤进行测量,根据对当前条件的评估决定不同的行动。
简而言之,这是一种算法(尽管它是用死动物和火而不是 R 实现的)。你对算法很在行!
这是给你的感恩节火鸡的。让我们开始吧。
基本原理
感恩节火鸡有一些依赖。确保你先把这些准备好。你需要一个烤箱,一个烤盘,铝箔,一把锋利的刀和一个烤箱安全肉类温度计。亚马逊是你的朋友,当地的 Safeway 也是。至于平底锅,便宜的铝制的就可以了。理想情况下,你既要平底锅,又要能把火鸡从底部抬高一点的东西,比如铁丝架。
接下来,你需要火鸡本身。如果你在感恩节前一天读到这篇文章,你可能已经太迟了。由于在如此紧迫的时间内将如此多的死鸟运送给如此多的人的经济原因,大多数感恩节火鸡都是冷冻的。

A Whole Foods turkey. Credit: Gado Images
它们是巨大的鸟类——解冻一只需要几天。所以,要么买一个已经解冻的(称为新鲜的),要么买一个冷冻的,让它在冰箱里放几天。
想知道体重吗?一般人一次吃大约 1/2 磅肉。但是火鸡并不是 100%高效的——它们的大部分物质都是不可食用的部分,比如骨头。所以,把你想要的可食用的肉的质量加倍。对于 7-10 个人来说,选择 15-20 磅的鸟。
还有,记得拿那个肉类温度计。有些人认为他们可以通过外表来判断火鸡熟了没有。他们是傻瓜,他们的客人会感染沙门氏菌。测量,测量,测量!
实例化
在早上,从你想要的服务时间开始向后计划。平均来说,每磅火鸡需要 20 分钟来烹饪。所以把你火鸡的重量乘以 20,除以 60,然后从你想要的服务时间中减去这个数字(你用的是 24 小时制,对吗?).那就是你想要开始的时候——也许增加一个小时的缓冲时间。
拿出你的烤盘,打开你的火鸡。出于某种原因,火鸡供应商把火鸡的内脏放在一个小塑料袋里,他们把这个塑料袋放在火鸡里面,可爱地称之为“内脏”,而不是“火鸡内脏小袋”。把这个拔出来。
执行
把你的火鸡胸肉放在烤盘里,最好放在小架子上。请参见下图,了解正确的方向。将烤箱温度设置为 176 摄氏度(不,我不会为你转换温度)。当它发出哔哔声时,把火鸡放进锅里。设置一个 30 分钟的计时器。

This side up. Credit: Gado Images.
你的目标是将火鸡的内部温度从起点提高到至少 71 摄氏度(好吧,为了安全起见,我将把这个温度转换为 160 华氏度)。这有几个原因。
第一,你想使火鸡肌肉中的蛋白质变性。生肉难以接受地难以咀嚼,因为肌肉纤维是完整的。使它们变性会使它们变得柔韧,更容易咀嚼。本质上,你是在上菜前使用外部热源来消化火鸡(你不应该用这种语言向你的客人描述它。)
此外,170 华氏度足以杀死大多数细菌。家禽是肮脏的——你的生火鸡上有足够多的沙门氏菌、大肠杆菌和其他有害物质,足以让最大胆的生物黑客感到紧张。这也带来了另一个问题。每次接触生火鸡后都要洗手,还要清洗餐具和表面。交叉污染会毁了你的一天。
现在,你进入了一个 While 循环。每 30 分钟,打开烤箱检查一下火鸡。最初,你只是想确保它没有燃烧。在 i == 1 (1 小时)时,拿起你的肉温度计,把它插入火鸡胸部的厚部位。温度应该会立即下降。把它放在那里,然后把整个东西放回烤箱。
每隔 30 分钟,检查一下火鸡的温度。它应该会随着时间的推移而上升。
排除故障
当你的火鸡在烹饪时,你会注意到表皮开始变成棕色。这是由于美拉德褐变反应,这种反应从火鸡皮肤中的糖和氨基酸中释放出美味的芳香物质。你希望这一切发生。Maillards =风味。
然而,你不想要的是从邮件地址到碳化(阅读:燃烧)。原始形态的碳不好吃。
一旦你的火鸡变成漂亮的金棕色,用铝箔包起来。

Radiation blocking foil. Credit: Gado Images.
为什么?烤箱有三种方式将热量传递给里面的东西:对流、辐射和传导。
对流是热量从烤箱里的热空气传递给你的鸟。它很温和,你希望整个烹饪过程都是这样。
辐射有点不一样;这是热量从烤箱的热金属壁传递到里面的火鸡。很好,但比对流更严酷。任其发展下去,会烧死你的鸟。
用铝箔覆盖火鸡可以反射烤箱壁散发的热量,同时还能让暖空气对流发挥它的魔力。它可以让你的火鸡烹饪,没有碳化皮肤的风险。
哦,还有传导?那是热量从热金属表面直接传递到火鸡本身。还记得你希望包括的那个钢丝架吗?它将火鸡从热烤盘上提起,通过减少与热金属接触的表面积,几乎切断了过程的传导。
如果你闻到烧焦的味道,火鸡的汁液可能会滴落到平底锅上,并立即碳化。往锅里倒一点水,降低表面温度,防止这种情况发生。
评估和停止条件
每次检查时,你应该看到火鸡的内部温度上升。当温度达到至少 160 华氏度时,你的火鸡就做好了!

Maillards complete. Credit: Gado Images.
请记住,烹饪是指数型的-内部温度在开始时会缓慢上升,然后在接近尾声时迅速上升。当温度接近临界点时,你可能需要每 10 分钟检查一次。
当你达到 160 华氏度时,拿出温度计,在火鸡的其他几个地方刺一下。火鸡身体上的肌肉分布并不均匀——一些部位的肉比其他部位多,你要确保你不是从一个薄的部位开始测量的。如果一切都是 160F+,你很好。我喜欢烹饪到 170 华氏度,只是为了确保整个事情最终超过 160 华氏度。
将火鸡从烤箱中取出,转移到一个浅盘中,并将温度计留在里面。它现在可以在你等待你的客人时一直坐着,通常是一个小时或更长时间。监控内部温度,确保温度不会低于 140 华氏度——如果温度低于 140 华氏度,就有细菌重新繁殖的风险。如果需要,你可以把它放回温度较低(170 华氏度)的烤箱里保温。
生产:肌红蛋白还是没有?
现在有趣的部分来了——雕鸟。如果你够大胆的话,你可以在桌边做,或者提前切。确保你有一把锋利的刀叉。
鸟类被分为六个主要象限——两个乳房、两条腿和两个翅膀。

0 = breast, 1 = leg, 2 = wing. Credit: Gado Images.
从胸部开始。他们在鸟的顶端。你的目标是切下胸部,直到胸骨。把你的叉子放进去,稳住鸟,切下鸟一边的皮和肉。在另一边重复。
现在,你要切除两条腿。抓住鸡腿(你在 ren 集市上吃的那部分),把腿从鸟身上拉开一点。找到切肉的部位,然后切掉,直到腿可以自由活动。那里有一个关节,一旦你把它切开,这条腿就会自由了。小心点!
腿被进一步分成两个子部分——鸡腿和大腿。以错误的方式弯曲鸡腿,然后切开连接大腿的关节。理想情况下,你会得到两块分开的好肉。

The drumstick, served up. Credit: Gado Images.
最后,找到鸟前面的翅膀,并遵循你用于腿的相同功能。你的火鸡切好了!
不要在这里关注完美——你正在肢解一只鸟,这是整个过程中最原始、最原始的方面。如果你的客人正看着别处(或者在他们离开后),你也可以直接用手将肉块撕下来,这通常比花式刀切更容易。
大多数人会问他们的客人想要黑肉还是白肉。不同之处在于肉中脂肪的含量,以及它所含的肌红蛋白的含量。肌红蛋白含有血红素,用于向活跃的肌肉输送氧气。深色的肉在腿部——这是火鸡用来站立的部位,所以它们含有缓慢收缩的肌肉、大量的肌红蛋白(产生深色)和脂肪。
白色的肉(火鸡的)在胸部,是快速收缩的肌肉,几乎没有脂肪和肌红蛋白。它与翅膀相连——因为火鸡不会飞,所以它们不经常使用翅膀,肌红蛋白也不是必需的。顺便说一句,鸭子都是深色肉,因为它们用翅膀来飞,因此它们的肌肉中都含有肌红蛋白。
整个过程
唷,那有很多单词——如果更简单的话,这里是用伪 Python 写的。
from Store import cooking_pan, aluminum_foil, oven_safe_thermometer, sharp_knife, wire_rackassert(oven)from Store import turkeyturkey_weight = num_guests * 1 if turkey == frozen:
defrost_days = 3
refrigerate(turkey, defrost_days)start_time = serve_time - ((turkey_weight * 20) / 60)i = 0
sleep_time = 30while(internal_temperature < 160):
checkInternalTemperature(turkey) if (i > 1 and skin_color > golden_brown):
coverWithFoil(turkey) if burning_smell == True:
addWater(cooking_pan) i++ if internal_temperature > 140:
sleep_time = 10 sleep(sleep_time)#Sanity check
i = 0
while (i < 5):
checkInternalTemperature(turkey)
i++sleep(60)carve(turkey)
盘问
恭喜你,你做了第一只火鸡!
让我们都感谢我们所爱的人,感谢那只鸟,感谢那顿饭,感谢让我们来到这里的算法。
现在,如果你在回复中问得非常好,我也可以分享一个简单的算法!
PyTorch 中以隐私为中心的深度学习教程介绍
安全多方计算和同态加密增加了计算开销,但结果非常值得!数据隐私和模型参数安全通过巧妙的加密方案相互保护。
数据的重要性
随着机器学习继续以巨大的方式影响我们的社会,经常是模型成为头条新闻,但如果问任何数据科学家或机器学习工程师他们花了大部分时间做什么,答案很可能是数据。
为机器和深度学习模型寻找、标记、增加和渲染数据是机器学习从业者技能的关键部分,也是让产品“正常工作”的诀窍的基础(至少在自动化浪潮赶上自动化机器之前是如此,比如谷歌的 AutoML )。
事实上,如果没有大型训练数据集来匹配,大模型就不值得拥有数百万个参数。吴恩达喜欢在他的讲座中使用的一个有点著名的概念图说明了模型性能、模型大小和数据可用性之间的关系。
在任意单位中,图形看起来像这样:

其中在小数据集上训练的大模型通常表现不如适当小的网络,反之亦然。
大型高质量数据集的可用性是利用最先进的模型和计算能力的必要条件。
鉴于数据对现代经济的重要性,这导致一些人将数据称为“新黄金”或“新石油”。2013 年,大约在数据闸门开始打开的时候,一些人估计世界上有记录的数据在短短两年内增加了 10 倍。准确的数字很难确定,但尽管我们不一定期望数据两年增长 1000%的情况会无限期持续下去,但毫无疑问,高质量训练数据集的数量现在比以往任何时候都多。
但这种数据洪流带来了一些意想不到的负面后果,随着该领域的成熟,数据所有权和隐私的实践和监管方式必然会适应。
隐私呢?
虽然在很大程度上,人们对公开分享数据以换取很少回报的做法感到惊讶,但日益增长的意识以及不断扩大的数据泄露和公然不当行为清单正开始在公众和监管层面改变这种情况。
大数据巨头脸书最近几年丑闻不断,而谷歌最近因违反新的欧洲数据保护法而被罚款。人们和组织越来越意识到数据和机器智能影响我们生活方方面面的方式,并准备更加认真地对待隐私和数据安全。
联合学习
此外,现代机器学习管道中的主要瓶颈通常是通信带宽,而不是计算能力。
例如,对于医院来说,将每一次计算机断层扫描上传到中央服务器进行实时模型更新是不现实的,还有许多其他用例更适合在现场或以分布式方式进行学习。
回到上面的例子,出于隐私和带宽的考虑,医院每天上传许多 TB 的敏感医疗数据用于集中培训可能是不现实的。然而,共享模型的训练经验可能仍然是有益的,因此更新的参数(或它们的梯度)可以在不同的站点上累积,以提高模型的所有实例的性能。这被称为联合学习。
联邦学习广泛应用于 ML 流水线,也可用于大数据集上的分布式学习。
但是在处理私有和特权数据时,如何才能保证其安全性呢?我们可以盲目地信任所有相关方,这在过去可能是普遍可以接受的,但是我们也可以通过共享密码运行数据,并采用所谓的安全多方计算(SMPC)
安全多方计算和同态加密
安全多方计算(SMPC)是处理数据的任何协议,它不依赖于向所有方公开数据。
这可以简单到在本地(未加密)数据上执行本地训练,然后加密梯度以上传。
另一种方法是使用同态加密(又名 HE)方案,其中加密的数据仍然支持数学运算,如加法和乘法。使用上述加密的梯度可以在被传送给拥有模型和用于解密组合梯度的私钥的任何人之前被加在一起。
或者,使用正确的 he 方案,可以对加密数据训练加密模型,产生只有在解密后才有用的加密预测。这种方法的重要结果是,有价值的模型的安全性可以同时得到维护。
让我们用一些代码来建立我们的理解。
我们将从一个简单的 SMPC 方法开始,只依赖 Python 的 numpy。
然后,我们将使用一个名为 PySyft 的开源加密深度学习库来教授一个小型网络异或函数,这是一个经典而臭名昭著的非线性函数示例。
在下面的例子中,我们将看到 SMPC 如何将数据分成几份,同时保留将加密变量添加到其他加密变量以及将加密变量与明文值相乘的能力。
import numpy as np # demonstrate secure multiparty computation Q = 501337 def encrypt(x): share_a = np.random.randint(0,Q) share_b = np.random.randint(0,Q) share_c = (x - share_a - share_b) % Q return (share_a, share_b, share_c) def decrypt(*shares): return sum(shares) % Q def add(x, y): z = [] assert (len(x) == len(y)), "each variable must consist of the same number of shares!" for ii in range(len(x)): z.append((x[ii] + y[ii]) % Q) return z def product(x, w): # w is a plaintext value, z = [] for ii in range(len(x)): z.append((x[ii] * w) % Q) return z # encrypt variables var1 = encrypt(2) var2 = encrypt(5) # get sum my_sum = add(var1,var2) # print results print(my_sum) print(decrypt(*my_sum)) print(decrypt(*my_sum[0:2]))
正如我们在上面看到的,在对加密变量求和之后,我们得到了一个看起来像三个随机整数的结果。
这些整数是加密的部分,我们可以使用 decrypt()将它们转换成明文结果。上面要注意的重要事情是,如果我们试图只访问两个共享来“解密”结果,我们会得到无意义的结果。访问不完整份额的任何一方都无法破译数据的含义。
上面的例子支持加密数据的加法和与明文操作数的乘法。深度学习神经网络主要由加法、乘法和激活函数组成,我们刚刚展示了前两个可以相对容易地完成,而无需放弃对底层数据的控制。
这对于线性回归等简单的统计学习模型来说已经足够了,但是为了利用神经网络根据通用逼近定理拟合任意数据函数的能力,我们需要引入非线性。这是像 PySyft 这样以隐私为中心的深度学习库的主要发展领域,使用泰勒展开级数等聪明的技巧来近似常见的激活函数。
还可以通过复杂的随机变换将非线性问题简化为线性问题,这种方法被称为水库计算。这就是我们在下一个例子中要做的。
使用 PySyft 的 PyTorch 示例
为了运行这部分教程,我们将探索如何使用 PyTorch,更具体地说是 PySyft。但是首先,您需要了解运行下面的演示所需的系统/资源要求。
- Ubuntu 18.04
- Docker v 18.xx
- Anaconda(我们更喜欢并推荐 anaconda docker 图像)
- 至少 2 个 CPU 内核(最好是 4 个或更多)
- 8 GB 内存,(你也许可以用 4 GB 内存)
- 30 GB 磁盘空间(50gb 更好)
重要提示: 我们 高度 由于本次练习需要大量的 DL/ML/Math 包,建议使用 Docker 进行以下实验。PySyft 是高度实验性的,这些脚本在 PyTorch v0.3.1 中是稳定的,我们只是想提前了解一下。请使用 Docker 来避免可能的依赖问题。
步骤 1)启动官方的 Anaconda Docker 容器
sudo docker run -it -p 8888:8888 -v ~/demo:/demo2 continuumio/anaconda bash
步骤 2)下载 bash 文件,并将其放在本地机器上的 demo 文件夹中(不是容器)。
注意:您可以将下面的源代码复制并保存在“源代码”部分,而不是下载 zip 文件。
步骤 3)在 Anaconda 容器中,运行 bash 文件。
导航到' bash encrypted _ reservoir _ pysyft _ demo . sh '所在的文件夹,对于此示例,只需输入以下内容:
cd demo2
运行 bash 文件
bash encrypted_reservoir_pysyft_demo.sh
注意:运行 bash 文件可能需要几分钟,创建整个培训环境,下载所有依赖项,安装所有必需的包,此外,它还会获取脚本的源代码(见下文)并执行培训脚本。
如果您想再次运行该脚本,您需要使用以下命令进入 PySyft conda 环境:
conda activate pysyft_demo
现在,通过输入以下内容运行演示(再次):
python encrypted_reservoir_demo.py
您应该会看到如下输出:
Encrypting variables 2 and 5 as var1 and var2 Performing encrypted addition... Multiparty result from add(var1,var2): [463355, 2676, 35313] Decrypted result: 7 Decrypted partial result: 466031 Begin training encrypted reservoir... loss at step 0: 2.000e+00 loss at step 50: 1.059e+00 loss at step 100: 5.590e-01 loss at step 150: 3.290e-01 loss at step 200: 1.800e-01 predictions: [ 0 1 1 0 [syft.core.frameworks.torch.tensor.ByteTensor of size 4x1] ] targets: 0 1 1 0 [syft.core.frameworks.torch.tensor.FloatTensor of size 4x1]
视频教程
脚本的源代码
现在,如果您想自己做更多的实验,请随意修改下面的源代码。
#!/usr/bin/env bash # download this script and run by typing 'bash encrypted_reservoir_pysyft_demo.sh' from the command line while in the same directory # create a new environment with PyTorch 0.3 conda create -n pysyft_demo pytorch=0.3 torchvision matplotlib pip -c pytorch -y source activate pysyft_demo # clone PySyft and checkout the required commit git clone [https://github.com/OpenMined/PySyft.git](https://github.com/OpenMined/PySyft.git) cd PySyft git checkout 1f8387a7b22406945482332c8171cb4994a3cfe8 # install requirements, install PySyft, and test pip install -r requirements.txt python setup.py install # run demo learning XOR with an encrypted reservoir cd ../ # write out the python demo file echo "import numpy as np import syft as sy hook = sy.TorchHook() import numpy as np import matplotlib.pyplot as plt # demonstrate secure multiparty computation display_figs = False Q = 501337 def encrypt(x): share_a = np.random.randint(0,Q) share_b = np.random.randint(0,Q) share_c = (x - share_a - share_b) % Q return (share_a, share_b, share_c) def decrypt(*shares): return sum(shares) % Q def add(x, y): z = [] assert (len(x) == len(y)), 'each variable must consist of the same number of shares!' for ii in range(len(x)): z.append((x[ii] + y[ii]) % Q) return z def product(x, w): # w is a plaintext value, z = [] for ii in range(len(x)): z.append((x[ii] * w) % Q) return z if __name__ == '__main__': # encrypt variables print('Encrypting variables 2 and 5 as var1 and var2') var1 = encrypt(2) var2 = encrypt(5) # get sum print('Performing encrypted addition...') my_sum = add(var1,var2) # print results print('Multiparty result from add(var1,var2):\n\t\t\t\t',my_sum) print('Decrypted result:\n\t\t\t\t',decrypt(*my_sum)) print('Decrypted partial result:\n\t\t\t\t',decrypt(*my_sum[0:2])) bob = sy.VirtualWorker(id='bob') alice = sy.VirtualWorker(id='alice') # Create our dataset: an XOR truth table x = np.array([[0.,0],[0,1],[1,0],[1,1]],'float') y = np.array([[0],[1],[1],[0]],'float') # use a reservoir transformation to achieve non-linearity in the model res_size = 256 my_transform = np.random.randn(2,res_size) x_2 = np.matmul(x,my_transform) # apply relu non_linearity x_2[x_2<0] = 0\. # convert data and targets to Syft tensors data = sy.FloatTensor(x_2) #[[0,0],[0,1],[1,0],[ 1,1]]) target = sy.FloatTensor(y) #[[0],[1],[1],[0]]) # init model (just a matrix for linear regression) model = sy.zeros(res_size,1) # encrypt and share the data, targets, and model data = data.fix_precision().share(alice, bob) target = target.fix_precision().share(alice, bob) model = model.fix_precision().share(alice, bob) # train the model learning_rate = 1e-3 J = [] print('\nBegin training encrypted reservoir...') for i in range(250): pred = data.mm(model) grad = pred - target update = data.transpose(0,1).mm(grad) model = model - update * learning_rate loss = grad.get().decode().abs().sum() J.append(loss) if(i % 50 == 0): print('loss at step %i: %.3e'%(i,loss)) got_pred = pred.get() got_target = target.get() if(display_figs): # display training results plt.figure(figsize=(10,6)) plt.plot(J,'g',lw=4) plt.xlabel('step',fontsize=19) plt.ylabel('loss',fontsize=19) plt.title('Learning XOR While Encrypted',fontsize=20) plt.show() # print decrypted predictions and targets (decision boundary of predictions at 0.5) print('predictions: \n',[got_pred.decode()>0.5]) print('targets: \n',got_target.decode())" >> encrypted_reservoir_demo.py python encrypted_reservoir_demo.py

外卖
在本文中,我们了解到保护模型和数据的隐私和安全是可能的。
这是一个活跃而有益的研究领域,随着机器学习和数据在我们社会中的作用不断成熟,它只会变得更加重要。
以隐私为中心的深度和机器学习是一项值得添加到您的技能组合中的技能,随着监管、消费者和商业压力都明智地转向良好的数据实践,它将经历越来越多的需求。
这也是企业值得开发的能力,因为有价值的模型可以得到保护。
最后,同态加密和安全计算是我们可以用来实现世界敏感问题的道德解决方案的工具。
这种方式的深度学习仍然有很大的计算成本,通常比传统模型至少慢一个数量级。上面训练 XOR 的例子就说明了这一点:训练数据集实际上只有 12 位数据,包括目标值,与现代深度学习任务相去甚远。
这使得在 GPU 和其他专用硬件上加速 HE 算法成为一个活跃的开发领域。同态加密库正处于开发的早期阶段,以充分利用现代 GPU,很像几年前深度学习库的状态。
这创造了一个站在前沿的机会,并影响这个领域的走向。一个名为 cuHE 的加速加密库已经宣称在各种加密任务上的速度比以前的实现提高了 12 到 50 倍。
未来,对于 GPU 制造商来说,通过改进对加密原语的硬件支持来迎合对良好数据实践的需求将是有意义的,就像张量核和为响应深度学习需求而开发的精度降低的功能一样。
深度学习友好的库,如 PySyft (构建于 PyTorch 之上)和 tf-encrypted (构建于 TensorFlow 之上),或 PySEAL (微软简单加密算法库的 python 端口)正在开发用户和开发者的活跃社区。
同态加密、安全多方计算和其他隐私保护方案肯定会成为未来机器学习从业者的必要技能,现在是参与其中的最佳时机。
当你准备好开始时,请阅读克雷格·金特里关于全同态加密的论文的介绍。
然后,当你准备好学习更多内容时,找一个 GPU,开始研究来自 tf-encrypted 和 PySyft 的例子。
(227361, 106917, 167163) (44123, 289723, 167588) (165513, 231191, 104745) (478016, 430732, 94038) (312810, 257243, 432742) (19638, 239579, 242152) (235418, 28417, 237603) (410735, 485411, 106638) (115624, 38923, 346889) (500014, 163171, 339603) (169683, 396997, 436115) (108180, 449757, 444849) (225167, 471257, 306366) (47789, 254175, 199478) (179954, 40895, 280598) (357183, 274943, 370651) !
原载于 2019 年 4 月 8 日blog.exxactcorp.com。
人工智能伦理学工具、方法和研究的类型学
我们如何将原则转化为实践?
2019 年 12 月,举行了第 33 次 NeurIPS。NeurIPS 是传统上在加拿大温哥华组织的关于神经信息处理系统的年度会议。我建议在 Twitter 上浏览讨论内容,阅读报纸,或者观看一些会议视频。在这篇文章中,我将看一些断章取义的引用图片,然后谈论名为将原则转化为实践的人工智能伦理工具、方法和研究的类型学的论文。这篇论文赢得了 NeurIPS 的“社会公益”跟踪,所以检查一下可能会很有趣。不过,如果以后有机会,我很想尽可能多地看看这一类别的提交材料。
NeurIPS 上的幻灯片和引文
在我开始总结前面提到的文章之前,我认为在 Twitter 上公开发布一些不同幻灯片的图片会很有趣也很容易。

Presentation by @riakall — phd studying AI/ML at stanford, thinking about the concepts inside machine learning models + dreaming up more radical ai // posted by @math_rachel
欢迎来到报价之地:

Posted by — @raghavgoyal14
更多引用:

Posted by — @celestekidd
更多的引用:

Posted by — @math_rachel

Quotes from 1984 — posted by @JIALIN_LU_1996

Photo by — @IanOsband
然而,在会议上当然不仅仅是引用。然而,我想把重点放在这篇关于“社会公益”的论文上。
人工智能伦理学工具、方法和研究的类型学
本文由英国牛津大学牛津互联网研究所的 Jessica Morley 和 Luciano Floridi 撰写。这是与来自英国 Digital Catapult 的利比·金赛和阿娜特·艾尔哈拉共同撰写的。
简而言之,它提出:“……愿望和可行性之间,原则和实践之间存在差距。”因此,我们需要了解在流程的不同部分,开发人员可以使用哪些工具。
目标是绘制类型学,这可能有助于务实的开发人员在人工智能开发管道的每个阶段“应用伦理”。
然而,这也是一个信号,可能表明需要进一步研究的领域。他们发现存在一种:“…应用人工智能伦理领域的努力分布不均衡,已确定的工具的成熟度(广泛使用的准备程度)大多较低。”
根据这篇论文,这种方法受到 Saltz 和 Dewar (2019)的启发,他们提出了一个框架,旨在帮助数据科学家在项目的每个阶段考虑伦理问题。这是用“伦理原则”的网格和“人工智能应用生命周期”的阶段来完成的。
在最近的一次不同主题的审查中,确定了 84 份伦理人工智能文件。这些是根据论文主题“定义”伦理上一致的人工智能
(a)有益于并尊重人民和环境();
(b)健壮安全( 无害);
(c)尊重人的价值( 自治);
(d)公平( 正义);以及
(e)可解释、可问责、可理解( 可解释 )。因此,这些是在类型学中使用的原则。
这七个阶段是
- 业务和用例开发,
- 设计阶段,
- 培训和测试数据采购,
- 建筑,
- 测试,
- **部署和
- **监控。
在这篇论文中,共有 425 个来源提供了对这个问题的答案的实践或理论贡献:“如何开发一个伦理的算法系统。”被审查。
完全填充的类型可以在:
http://tinyurl.com/appliedAIethics找到
^The above contains a wealth of information that I would recommend you to check out.
他们在论文中有一个应用人工智能伦理类型的表格,其中有不同工具和方法的示例。

他们论文宣称三个相互关联的发现:
- 对‘可解释性’的过度依赖。“最明显的观察结果是,工具和方法的可用性在类型学中的分布并不均匀,无论是就伦理原则而言,还是就应用程序生命周期的阶段而言。最明显的“倾斜”是对事后“解释”的倾斜,在测试阶段寻求满足可解释性原则的个人有最大范围的工具和方法可供选择。”
- 强调需要‘保护’个人胜过集体 。“下一个值得注意的观察是,被调查的可用工具中,很少有提供有意义的方法来评估和响应人工智能算法中涉及的数据处理对个人的影响,更不用说对整个社会的影响了。”
- 缺乏可用性 。绝大多数分类工具和方法不可操作,因为它们对如何在实践中使用它们几乎没有帮助。即使有开源代码库,可用的文档通常也是有限的,而且使用时需要的技能水平也很高。
这篇论文的既定目标是给人工智能开发者一个当前可用工具的快照,以鼓励道德人工智能从原则到实践的进展,并向整个“道德人工智能”社区发出明确的信号,在那里需要进一步的工作。
“社会和有道德的人工智能社区需要培养建设性的耐心,因为在“如何”满足“什么”的问题上,这种进展不会很快,而且在这一过程中肯定会出现错误。只有接受这一点,社会才能积极地抓住人工智能带来的机遇,同时保持对要避免的潜在成本的警惕。”
我希望你喜欢这个简短的总结,但是我当然会建议你阅读原文。我提供的信息只是为了鼓励你继续阅读。
这里是#500daysofAI,您正在阅读第 196 条。500 天来,我每天都写一篇关于人工智能或与之相关的新文章。
下载、提取、处理和使用数据集的统一方法

Photo by Oskars Sylwan on Unsplash
任何机器学习练习的第一个相当多的步骤都是关于数据集的。从哪里以及如何下载它们?编写脚本来组织和/或改变下载的档案、目录、数据库和数十种其他格式,使它们成为对手头项目有意义的东西。最后,一旦准备好数据,就开发管道将数据(或者更确切地说,我应该说是特征)馈送到正在训练的神经网络和/或机器学习算法。
就构建管道而言,tensorflow core 已经使用[tf.data](https://www.tensorflow.org/api_docs/python/tf/data/Dataset)模块提供了一个优秀的抽象。这个模块的核心是tf.data.Dataset类,它抽象出输入特性的底层来源。根据要素的大小,您可以使用简单的 numpy 数组,或者如果数据集很大,您可以使用tfrecords作为基于文件的底层存储。tfrecords根据您指定的特性模式,最终将您的特性样本存储为 protobufs。也就是说,你真的不需要担心tfrecords如何在内部存储数据。有趣的是,由于tf.data.Dataset提供的抽象,您可以在输入管道上应用相同的操作集。下面是一个简单的代码片段,显示了管道-
d = tf.data.TFRecordDataset(input_files)
d = d.shard(num_workers, worker_index)
d = d.repeat(num_epochs)
d = d.shuffle(shuffle_buffer_size)
d = d.map(parser_fn, num_parallel_calls=num_map_threads)assert(isinstance(d, tf.data.Dataset))
虽然tf.data.Dataset是一个很好的抽象& tfrecords是一个很好的存储格式,但它仍然没有解决围绕下载、提取和准备数据的一致方法的问题。通常,与数据集下载、提取和转换相关的脚本/代码与用于培训和评估的主要管道是分开的,因此带来了挑战。其中一些列在下面-
- 脚本的数量在某种程度上与数据集的数量成比例。在我的个人项目中,每个数据集至少有 4 个脚本(其中有主/入口点)(在他们使用的可重用模块之上),只是为了准备可处理的特性。
- 开发人员必须担心文件路径的健全性检查、正确读取图像(在 python 生态系统中,有多个包仅用于读取图像,甚至单个项目最终会使用其中的许多包)等。希望您能够理解,随着项目的增长,不同技能的开发人员对库和方法的偏好也会增加。
- 在培训和评估期间,在准备
tfrecords时使用的特性规范与编写parser_fn用于映射时使用的特性规范之间要断开。
可扩展和可维护的软件工程项目的一个关键组成部分是解决任务的一致性。这里的任务是获取和准备数据集。这篇文章是关于介绍来自 https://github.com/tensorflow/datasetstensorflow_datasets(``tensorflow生态系统的一个包,它为上面列出的挑战提供了有希望的解决方案。
tensorflow_datasets是由谷歌的开发者发起的一个项目,然而它是由社区驱动的,并吸引了来自机器学习社区的大量贡献。
第一眼看到tensorflow_datasets会给你一个印象,这个包是关于各种数据集的集合,虽然它是正确的,但我感兴趣的部分是,为了支持各种数据集(音频、图像、视频、二进制等),他们必须开发一个强大的基础,提供足够的抽象,以消除对平凡和重复任务的需求,同时保持用户代码足够灵活,以处理数据集的特殊性。
下面是显示用法的列表:
import tensorflow as tf
import tensorflow_datasets as tfds
# tfds works in both Eager and Graph modes
tf.enable_eager_execution()
# See available datasets
print(tfds.list_builders())
# Load a given dataset by name, along with the DatasetInfo
data, info = tfds.load("mnist", with_info=True)
train_data, test_data = data['train'], data['test']
assert isinstance(train_data, tf.data.Dataset)
assert info.features['label'].num_classes == 10
assert info.splits['train'].num_examples == 60000
# You can also access a builder directly
builder = tfds.builder("mnist")
assert builder.info.splits['train'].num_examples == 60000
builder.download_and_prepare()
datasets = builder.as_dataset()
显而易见的是,这种方法提供了获得数据集的统一方法,而不考虑它们的类型。
这里需要特别注意的一个方法是download_and_prepare。这个方法实际上最终调用了数据集特定的实现(本例中为 MNIST ),下载、提取和准备tfrecords的逻辑就驻留在这个实现中。原始数据、原始数据和准备好的数据所在的位置也可以通过将参数传递给download_and_prepare来配置。
也可以下载数据(因为有时可能需要身份验证和授权),然后提供数据的路径。换句话说,它足够灵活,可以满足大多数场景。繁重的下载和准备任务只发生一次,对于后续的使用,它跳过了昂贵的操作。
tensorflow_datasets的文档确实不错。它们不仅为使用提供了很好的指导,也为人们如何向他们的集合贡献新的数据集提供了很好的指导。
本文的其余部分将借助一个具体的例子来说明如何将这个框架用于您自己的私有数据集。
在这个例子中,我将使用tiny-imagenet数据集。该示例的完整源代码可在https://github.com/ksachdeva/tiny-imagenet-tfds获得。您也可以使用 pip 将这个包安装到您自己的项目/笔记本/colab 中:
pip install git+https://github.com/ksachdeva/tiny-imagenet-tfds.git
我很可能会将此数据集贡献给 tensorflow_datasets 集合,这样它将作为其中的一部分可用,但源存储库将始终作为构建私有数据集支持的参考
我们先来看看用法:
import os
import numpy as np
import tensorflow as tf
import tensorflow_datasets as tfds
from tiny_imagenet import TinyImagenetDataset
# optional
tf.compat.v1.enable_eager_execution()
tiny_imagenet_builder = TinyImagenetDataset()
tiny_imagenet_builder.download_and_prepare()
train_dataset = tiny_imagenet_builder.as_dataset(split="train")
validation_dataset = tiny_imagenet_builder.as_dataset(split="validation")
assert(isinstance(train_dataset, tf.data.Dataset))
assert(isinstance(validation_dataset, tf.data.Dataset))
for a_train_example in train_dataset.take(5):
image, label, id = a_train_example["image"], a_train_example["label"], a_train_example["id"]
print(f"Image Shape - {image.shape}")
print(f"Label - {label.numpy()}")
print(f"Id - {id.numpy()}")
# print info about the data
print(tiny_imagenet_builder.info)
我希望您能从上面的代码片段中了解到,它或多或少与前面显示的 MNIST 示例相同,下载、准备和特性模式的细节被隐藏起来了。
微型图像网
Tiny Imagenet 是 Imagenet 数据集的缩小版。这个数据集是由斯坦福的人们为他们的课程http://cs231n.stanford.edu/创建的。
应该清楚的是,使用 tiny-imagenet-tfds 包并不要求您知道如何下载和准备数据集,但是因为我将向您展示如何开发实现,所以了解这个数据集是如何组织的非常重要。
以下是提取 zip 文件时数据集的样子。


特征
- 200 个图像类别
- 100,000 幅图像的训练数据集
- 10,000 幅图像的验证数据集
- 10,000 幅图像的测试数据集。
- 所有图片尺寸均为 64×64。
- wnids.txt 包含类名列表(nXXXXXX)
- words.txt 包含与类名相关联的友好名称[在本练习中我们不打算使用]
- val_annotations.txt 包含图像列表。对于每个图像,都有一个相应的列提供相关联的标签(即来自 wnids.txt 的标签)
- train 文件夹包含每个类的文件夹,在该文件夹中有一个名为 images 的目录,其中包含该类的 500 个 jpeg 文件。train 中的每个类都有 nXX_boxes.txt,它包含关于图像的边界框信息。在本练习中,我们不打算处理边界框信息。
tfds . core . generatorbasedbuilder
在tensorflow_datasets中实现各种数据集的主要工具就是这个类。顾名思义,它希望您生成数据集的示例,并将其写入tfrecords中。
tensorflow_datasets期望你实现一个从tfds.core.GeneratorBasedBuilder继承的类,并实现三个方法——_info、_split_generators和_generate_examples。
_info方法是您将要返回关于数据集的元数据的地方。这里有一个片段展示了它在 tiny-imagenet 中的应用。
从_info返回的tfds.core.DatasetInfo最重要的元素是特征的规范。如果你已经熟悉tfrecords,你会注意到它与你习惯看到的不同。事实上,tensorflow_datasets提供了一些高效的包装器来构建大大简化了很多事情的特性。在这个例子中,我使用的是tfds.features.Image,而如果我手动构建tfrecords,我将不得不使用多个字段,例如一个用于存储原始数据,一个用于形状,另一个用于图像格式等。最重要的是,我必须从我的脚本中读取图像。正如您稍后将在 _ generate_examples 函数的实现中看到的,我们不需要做任何事情。
我也很欣赏 DatasetInfo 有描述和引用字段的事实。这些元数据字段对于生成文档也很方便&更重要的是对人们首先创建数据集的辛勤工作的认可。
下一个要实现的方法是_split_generators,它在很多方面都是这个实现的主力。
该方法中的第一行,即extracted_path = dl_manager.extract(dl_manager.download(_URL)),是负责下载和提取的那一行。本例中的_URL指向http://cs231n.stanford.edu/tiny-imagenet-200.zip.返回值,即extracted_path包含解压后的路径。这是我困惑和问题的第一个来源。当我调用download_and_prepare时,它会向我显示下载的进度条,但当我查看位置时,它会是这样的

如上图所示,下载和解压 zip 文件的默认路径是~/tensorflow_datasets/downloads/extracted。现在,由于目录以扩展名.zip结尾,我认为它是一个文件,解压缩失败。最后花了 15 分钟试图找出问题所在,最后注意到这是一个目录。
但是如果数据集被分成许多 zip/tar/rar/gz 文件会怎么样呢?…不要担心!,你被覆盖了。可以将字典作为参数,在这种情况下返回值将是包含相应值的字典。下面的清单显示了该用例的一个示例
def _split_generators(self, dl_manager):
# Equivalent to dl_manager.extract(dl_manager.download(urls))
dl_paths = dl_manager.download_and_extract({
'foo': 'https://example.com/foo.zip',
'bar': 'https://example.com/bar.zip',
})
dl_paths['foo'], dl_paths['bar']
我将这个方法称为我的实现中的主力,因为这是我读取元数据文件(wnidx.txt、val_annotations.txt 等)和构建包含各种类的图像列表的字典并为这些类分配数字标签的地方。
请注意,tiny-imagenet 中的训练和验证数据的组织是不同的,因此我有两种不同的方法来处理信息,但是我将它们合并为相同的字典格式。实现细节可以在—https://github . com/ksachdeva/tiny-imagenet-tfds/blob/master/tiny _ imagenet/_ imagenet . py查看
在_split_generators中,有趣的代码语句是我返回各种拆分生成器的返回值。代码应该足够清晰,不言自明。唯一需要注意的部分是tfds.core.SplitGenerator的gen_kwargs键。本质上,你传递的这个字段的值将作为_generate_examples的参数传递。
现在,你要实现这么多数据集类,当发出
download_and_prepare时,你会得到一个错误通知,说它找不到checksum文件。这是第二步,花了我一点时间,大部分时间我花在这个问题上,而不是实现整个包。
事情是这样的。对于您下载的每个远程存档文件(在本例中为http://cs231n.stanford.edu/tiny-imagenet-200.zip),您需要提供校验和信息。校验和信息将存储在扩展名为.txt的文件中。因为我们正在开发自己的 python 包(即不在tensorflow_datasets中),所以你还需要告诉tensorflow_datasets包含校验和的文件所在的目录。以下是你需要添加到你的模块中的内容,以便完成这个任务-
checksum_dir = os.path.join(os.path.dirname(__file__),'url_checksums/')checksum_dir = os.path.normpath(checksum_dir)tfds.download.add_checksums_dir(checksum_dir)
另一个方面是校验和文件的名称应该是什么?经过一段时间的反复试验,我发现它应该和你的类名同名,但是有蛇形的大小写,也就是说,对于TinyImagenetDataset,你应该把你的文件命名为tiny_imagenet_dataset.txt。这部分在他们的指南中不是很清楚,至少我在任何地方都找不到它,我必须自己想办法。
这项工作还没有完成;您从哪里获得校验和本身呢?手动计算?幸运的是,这个框架会有所帮助。你所需要做的就是,当你第一次从一个使用你的数据集类的测试/例子中调用download_and_prepare时,你应该传递下面的参数
dl_config = tfds.download.DownloadConfig(register_checksums=True)
download_and_prepare(download_config=dl_config))
现在,您将看到下载成功,没有任何校验和错误,并且您的校验和文件(在本例中为 tiny_imagenet_dataset.txt)将有一个条目。从这一点开始,您可以删除 download_config 参数。
现在该看_generate_examples了。
从代码中可以看出,这是一个生成函数yielding的两个返回值。第一个是键,它是将在tfrecords中写入的样本的唯一标识符,第二个是对应于您在_info方法中指定的模式的字典。正如我前面提到的,你不再需要读取图像文件,而是简单地提供图像文件的路径,tensorflow_datasets会确保读取它并将其嵌入到tfrecords中
打包您的实现(可选)
如果您正在构建私有数据集,那么它很可能只是存储库中的一个 python 包。但是,如果您在您的组织中共享它,并且拥有某种 python 包存储库,您可能需要构建一个 wheel 文件。
这里没有关于构建 python pip 包的具体内容,除了您希望确保在最终的构建中包含校验和文件。
你可以看看https://github . com/ksachdeva/tiny-imagenet-tfds/blob/master/setup . py如何做的例子。
结束语
根据我到目前为止使用tensorflow_datasets的经验,它确实实现了为日常和重复性任务提供必要的抽象和支持的目标,同时提供了处理各种数据集的灵活性。还可以很容易地添加对您可能不想公开的数据集和驻留在tensorflow_datasets之外的数据集的支持。
希望您发现tensorflow_datasets在您的项目中的效用,并且这篇文章可以帮助您实现。
一种通用的文本挖掘体系结构
通过自然语言处理使独立于领域的信息抽取成为可能

Source: Rene Magritte
自然语言处理是人工智能领域中一个令人兴奋的新兴领域。语言学和机器学习算法的重大发展使得计算机处理和分析大量自然语言数据所需的子任务变得可行。研究表明,计算机能够完成被认为只有人类才能完成的任务。
更广泛的 NLP 任务,如信息提取 (IE),需要在考虑灵活性的基础上安排子任务。与大多数 IE 系统相比,所讨论的体系结构具有两个重要的优点,即它是通用的和独立于领域的。

General Architecture of the Information Extraction System
初始自然语言处理模型
文本数据的初始处理需要一系列步骤来为我们的模型提供经过处理的输入。文本首先被标记化或分割成单词、标点符号等。
Example text:
Ukraine formed a limited military alliance with Russia while also establishing a partnership with NATO in 1994.Tokenized Text:
[Ukraine, formed, a, limited, military, alliance, with, Russia, while, also, establishing, a, partnership, with, NATO, in, 1994, .]
每个单词都标记有形态、语法和字母数字特征。诸如词干、语法依赖标签、开始和结束索引等附加功能可能适用于您的用例。

机器学习模型使用统计推断,通过分析典型现实世界文档的大型语料库来自动确定形态和句法特征。这些统计推断与手工编码的试探法一起使用,以获得最佳结果。
命名实体识别(NER)模型将选择术语放入预定义的桶中:个人、组织、事件、地点等。
+------+-----------+--------------+
| Date | Geography | Organization |
+------+-----------+--------------+
| 1994 | Russia | NATO |
| | Ukraine | |
+------+-----------+--------------+
这些术语不与每个集合的元素列表进行比较,ML 技术如此成功的部分原因是它们发现了缺乏可解释性但在实践中有效的统计模式。
依赖于领域的字典查找方法需要日常维护,因为随着时间的推移,集合中的元素增加/减少,并且不考虑上下文。
关键词提取
使用 TextRank 提取关键词;基于图的排名模型。
简而言之,我们构建了一个图,其中文本中不同的名词、动词和形容词充当一个顶点。如果词汇单元共现(在一个固定的单词窗口内一起出现),则创建边。

对单词进行排序:将所有顶点初始化为 1,收集其每个入站连接的影响,迭代直到收敛,并归一化得分。
+-------------+----------+
| Keyterm | TextRank |
+-------------+----------+
| limited | 0.17 |
| partnership | 0.17 |
| military | 0.16 |
| Russia | 0.16 |
| alliance | 0.16 |
| Ukraine | 0.09 |
| NATO | 0.09 |
+-------------+----------+
词向量
通过使用预训练的单词向量,系统变得与领域无关;其中感兴趣的单词被映射到实数的向量。 手套单词嵌入 通过从大型语料库聚集全局单词-单词共现矩阵来创建。手套向量之间的余弦距离方便地指示语义相似性。

使聚集
在许多可用的聚类方法中,重叠划分聚类是优选的,因为它允许一个词同时适合多个类别。使用这种方法的直觉是,自然语言中的类别之间经常存在模糊性。
cluster_1 = [partnership, alliance]
标记集群
将从受控的单词和短语词汇表中选择聚类标签。从关键术语上下文向量的贝叶斯推断比朴素余弦相似性更有可能产生准确的标签。
+----------------------------+
| International_Organisation |
+----------------------------+
| partnership |
| alliance |
+----------------------------+
下游任务
提取的信息可以用于许多下游任务,包括文本摘要、事件提取、概念映射和关系提取。

如果你有兴趣学习更多关于 NLP 的知识,我强烈推荐你阅读自然语言工具包(NLTK)书籍。
机器学习模型的旋风之旅
深入探讨不同的机器学习模型以及何时应该使用它们!

在第一部分“选择机器学习模型”中,我们谈到了选择完美的机器学习模型的艺术和科学。
在第二部分中,我们深入探讨了你可以训练的不同机器学习模型,以及你何时应该使用它们!
一般来说,基于树的模型在 Kaggle 竞赛中表现最好。其他型号是组装的绝佳选择。对于计算机视觉挑战,CNN 胜过一切。对于自然语言处理,LSTMs 或 GRUs 是您的最佳选择!
也就是说,下面是可供尝试的模型的非详尽清单,以及每个模型的一些上下文。
回归
回归→线性回归→普通线性回归
优势
- 很好地捕获数据集中的线性关系
- 如果您有几个明确定义的变量,并且需要一个简单的预测模型,那么这个方法非常有效
- 快速的训练速度和预测速度
- 在小数据集上表现良好
- 可解释的结果,易于解释
- 当新数据进来时,容易更新模型
- 不需要调整参数(下面的正则化线性模型需要调整正则化参数)
- 不需要特征缩放(下面的正则化线性模型需要特征缩放)
- 如果数据集包含冗余要素,线性回归可能会不稳定
缺点
- 不适用于非线性数据
- 预测准确度低
- 可能会过度拟合(见下面的正则化模型来抵消这一点)
- 无法很好地将信号与噪声分开——在使用前剔除不相关的特征
- 不了解数据集中的要素交互
回归→线性回归→套索、脊、弹性网回归
优点
- 这些模型是带有正则化的线性回归
- 帮助抵消过度拟合
- 这些模型更容易概括,因为它们更简单
- 当我们只关心少数几个特性时,它们工作得很好
缺点
- 需要功能缩放
- 需要调整正则化参数
回归→回归树→决策树
优点
- 快速的训练速度和预测速度
- 很好地捕捉数据集中的非线性关系
- 了解数据集中的要素交互
- 当数据集有异常值时非常有用
- 非常适合在数据集中查找最重要的要素
- 不需要功能缩放
- 合理的解释结果,易于解释
缺点
- 预测准确度低
- 需要一些参数调整
- 在小数据集上表现不佳
- 没有很好地分离信号和噪声
- 当新数据进来时,不容易更新模型
- 实践中很少使用,请使用集合树
- 可以过度装配(见下面的套装模型)
回归→回归树→集成
优点
- 整理来自多个树的预测
- 高预测准确性——在实践中非常有效
- Kaggle 竞赛中的首选算法
- 当数据集有异常值时非常有用
- 很好地捕捉数据集中的非线性关系
- 非常适合在数据集中查找最重要的要素
- 分离信号和噪声
- 不需要功能缩放
- 在高维数据上表现出色
缺点
- 训练速度较慢
- 预测速度快
- 不容易解释或者说明
- 当新数据进来时,不容易更新模型
- 需要一些参数调整—更难调整
- 在小数据集上表现不佳
回归→深度学习
优势
- 高预测准确性——在实践中非常有效
- 捕捉数据中非常复杂的潜在模式
- 对大数据集和高维数据都很有效
- 当新数据进来时,容易更新模型
- 网络的隐藏层显著降低了对特征工程的需求
- 是计算机视觉、机器翻译、情感分析和语音识别任务的最新技术
缺点
- 非常长的训练速度
- 需要巨大的计算能力
- 需要功能缩放
- 不容易解释或诠释结果
- 需要大量的训练数据,因为它学习大量的参数
- 在非图像、非文本、非语音任务方面优于 Boosting 算法
- 非常灵活,带有许多不同的架构构建模块,因此需要专业知识来设计架构
回归→ K 个最近邻(基于距离)
优点
- 训练速度快
- 不需要太多的参数调整
- 可解释的结果,易于解释
- 适用于小型数据集(<100k training set)
缺点
- 预测准确度低
- 在小数据集上表现不佳
- 需要选择一个合适的距离函数
- 需要功能缩放才能正常工作
- 预测速度随着数据集的大小而增长
- 无法很好地将信号与噪声分开——在使用前剔除不相关的特征
- 是内存密集型的,因为它保存每个观察
- 也意味着它们不能很好地处理高维数据
2.分类
分类→逻辑回归
优点
- 很好地分类线性可分数据
- 快速的训练速度和预测速度
- 在小数据集上表现良好
- 合理的解释结果,易于解释
- 当新数据进来时,容易更新模型
- 正则化时可以避免过度拟合
- 可以进行两类和多类分类
- 不需要参数调整(除了正则化时,我们需要调整正则化参数)
- 不需要特征缩放(除了正则化时)
- 如果数据集包含冗余要素,线性回归可能会不稳定
缺点
- 不适用于非线性可分离数据
- 预测准确度低
- 可能过度拟合(参见下面的正则化模型)
- 无法很好地将信号与噪声分开——在使用前剔除不相关的特征
- 不了解数据集中的要素交互
分类→支持向量机(基于距离)
优势
- 预测精度高
- 即使在高维数据集上也不会过度拟合,因此当您拥有大量要素时,它非常有用
- 适用于小型数据集(<100k training set)
- Work well for text classification problems
缺点
- 当新数据进来时,不容易更新模型
- 非常占用内存
- 不适用于大型数据集
- 当新数据进来时,不容易更新模型
- 需要你选择正确的内核才能工作
- 线性内核模拟线性数据,工作速度很快
- 非线性核可以模拟非线性边界,并且可能很慢
- 改用 Boosting!
分类→朴素贝叶斯(基于概率)
优势
- 在文本分类问题上表现很好
- 快速的训练速度和预测速度
- 在小数据集上表现良好
- 很好地分离信号和噪声
- 在实践中表现良好
- 简单,易于实施
- 适用于小型数据集(<100k training set)
- The naive assumption about the independence of features and their potential distribution lets it avoid overfitting
- Also if this condition of independence holds, Naive Bayes can work on smaller datasets and can have faster training speed
- Doesn’t need feature scaling
- Not memory intensive
- Decently interpretable results, easy to explain
- Scales well with the size of the dataset
缺点
- 预测准确度低
分类→ K 个最近邻(基于距离)
优点
- 训练速度快
- 不需要太多的参数调整
- 可解释的结果,易于解释
- 适用于小型数据集(<100k training set)
缺点
- 预测准确度低
- 在小数据集上表现不佳
- 需要选择一个合适的距离函数
- 需要功能缩放才能正常工作
- 预测速度随着数据集的大小而增长
- 无法很好地将信号与噪声分开——在使用前剔除不相关的特征
- 是内存密集型的,因为它保存每个观察
- 也意味着它们不能很好地处理高维数据
分类→分类树→决策树
优点
- 快速的训练速度和预测速度
- 很好地捕捉数据集中的非线性关系
- 了解数据集中的要素交互
- 当数据集有异常值时非常有用
- 非常适合在数据集中查找最重要的要素
- 可以进行两类和多类分类
- 不需要功能缩放
- 合理的解释结果,易于解释
缺点
- 预测准确度低
- 需要一些参数调整
- 在小数据集上表现不佳
- 没有很好地分离信号和噪声
- 实践中很少使用,请使用集合树
- 当新数据进来时,不容易更新模型
- 可以过度装配(见下面的套装模型)
分类→分类树→集成
优势
- 整理来自多个树的预测
- 高预测准确性——在实践中非常有效
- Kaggle 竞赛中的首选算法
- 很好地捕捉数据集中的非线性关系
- 当数据集有异常值时非常有用
- 非常适合在数据集中查找最重要的要素
- 分离信号和噪声
- 不需要功能缩放
- 在高维数据上表现出色
劣势
- 训练速度较慢
- 预测速度快
- 不容易解释或者说明
- 当新数据进来时,不容易更新模型
- 需要一些参数调整—更难调整
- 在小数据集上表现不佳
分类→深度学习
优势
- 高预测准确性——在实践中非常有效
- 捕捉数据中非常复杂的潜在模式
- 对大数据集和高维数据都很有效
- 当新数据进来时,容易更新模型
- 网络的隐藏层显著降低了对特征工程的需求
- 是计算机视觉、机器翻译、情感分析和语音识别任务的最新技术
缺点
- 非常长的训练速度
- 不容易解释或诠释结果
- 需要巨大的计算能力
- 需要功能缩放
- 需要大量的训练数据,因为它学习大量的参数
- 在非图像、非文本、非语音任务方面优于 Boosting 算法
- 非常灵活,带有许多不同的架构构建模块,因此需要专业知识来设计架构
3.使聚集
聚类→ DBSCAN
优点
- 可扩展至大型数据集
- 很好地检测噪声
- 不需要预先知道集群的数量
- 并没有假设星团的形状是球状的
缺点
- 如果您的整个数据集非常密集,则并不总是有效
- 需要将密度参数ε和 min_samples 调整到正确的值,以获得良好的结果
聚类→k 均值
优点
- 非常适合揭示底层数据集的结构
- 简单,易于理解
- 如果您事先知道集群的数量,那么工作会很好
缺点
- 如果你的星团不是球状的,大小也不相似,就不一定管用
- 需要预先知道集群的数量—需要调整 k 个集群的选择以获得良好的结果
- 内存密集型
- 无法扩展到大型数据集
4.Misc —本帖中未包含的型号
- 降维算法
- 聚类算法——高斯混合模型和层次聚类
- 计算机视觉—卷积神经网络、图像分类、对象检测、图像分割
- 自然语言处理— RNNs (LSTM 或 GRUs)
- 强化学习
组装您的模型
集合模型是一种非常强大的技术,通过组合不同模型的输出,有助于减少过度拟合,并做出更稳健的预测。它尤其是赢得卡格尔比赛的必备工具。
当选择模型进行集成时,我们希望从不同的模型类中选择它们,以确保它们具有不同的优点和缺点,从而在数据集中捕获不同的模式。这种更大的多样性导致了更低的偏差。我们还希望确保它们的性能是可比较的,以确保生成的预测的稳定性。
我们可以看到,这些模型的混合实际上比任何单一模型单独产生的损失都要低得多。部分原因是,虽然所有这些模型都非常擅长做出预测,但它们正确地做出了不同的预测,通过将它们结合在一起,我们能够将它们所有不同的优势结合到一个超级强大的模型中。

有 4 种类型的组合(包括混合):
- 装袋:用不同的随机选择的数据子集训练许多基础模型,并进行替换。让基础模型对最终预测进行投票。用于 RandomForests。
- 提升:迭代训练模型,并在每次迭代后更新获得每个训练样本的重要性。用于 GradientBoosting。
- 混合:训练许多不同类型的基础模型,并在维持集上进行预测。根据他们的预测训练一个新模型,在测试集上进行预测。(与维持集堆叠)。
- 堆叠:训练许多不同类型的基础模型,并对数据集的 k 倍进行预测。根据他们的预测训练一个新模型,在测试集上进行预测。
比较模型
权重和偏差让您用一行代码跟踪和比较模型的性能。
一旦你选择了你想尝试的模型,训练它们,然后简单地添加wandb . log({ ' score ':cv _ score })来记录你的模型状态。一旦你完成训练,你可以在一个简单的仪表板上比较你的模型表现!
你可以在这里找到有效完成这项工作的代码。我鼓励你分叉这个内核并摆弄代码!
就是这样,现在您拥有了为您的问题选择正确模型所需的所有工具!
模型选择可能会非常复杂,但我希望这篇指南能给你一些启发,并给你一个挑选模型的好框架。
如果您有任何问题或反馈,请随时 发微博给我 !
数据分析的女性视角
从我在计算机科学系的交换学期中学到的关于性别不平等影响的课程…

今年,我将以在莫斯科的一个交换学期开始我大学的最后一年。我选择这个地方不仅是因为童话般的风景;丰富的艺术收藏和精心设计的公园,但数学!
在网上,我学习了这所大学的机器学习课程,因为我非常喜欢看视频和学习材料,所以我决定加入他们的真实课堂。目前,我正在计算机科学系学习研究生课程,感觉棒极了!然而,随着讲座的进行,我对计算机科学世界多样性的呼吁有了新的看法…
我在学院的第一周
想象一下我,走进教室,拿出笔记本和记事本,准备开始上课。诚然,我可能有点太急切了,但总的来说,我们女人喜欢计划一切。我们需要,考虑到我们通常写在待办事项清单上的所有任务:杂货、洗衣…这不是火箭科学,但记住一切会让你的大脑爆炸!
相反,和男生合租房子让我看到了另一种方式。随便买些杂货,吃些容易做的菜,看看会发生什么。在课堂上,我的讲师也没有遵循一个结构化的计划。当我问到这个问题时,他的回答是:“这是个好主意……如果我的讲座有一个结构就好了。”。
我越研究计算机科学,就越认识到这种对结构的漠视。“我们只需要让它发挥作用”是总体目标。当然,对于我刚刚概述的这一概括,也有例外。然而,我确实认为,一个男性过多的院系显示出缺乏结构并非巧合。在本文的剩余部分,我将概述女性视角对计算机科学领域的积极影响。
随着这一领域越来越多地参与重大创新,不仅在技术部门本身,而且在医药、金融、教育和政府组织。以下主题需要更多关注。
首先,我们女人比我们的对手更关心沟通……清晰的沟通可以节省一遍又一遍解释发生了什么的时间。清晰的沟通不仅有利于团队或组织内部,而且在模型将被用于现实决策时也很重要。例如,我们需要报告拒绝贷款或做出医疗决定的原因。具有讽刺意味的是,有了数据分析,我们有了从数据中提取有价值信息的解释能力,而这些信息是人类无法提取的。然而,我们的工作是确保这些见解能够被人类理解。因此,我们需要对模型的内部运作有清晰和深入的了解。
第二,我们需要通过这种清晰的交流方式来包容他人。数据科学在日常生活中的应用涉及许多方面。增强领域知识是当前数据科学方法的巨大优势之一。这个过程需要双方的积极参与:数据科学家和领域实践者。要让不懂数据的人开始学习时感到舒服,需要同理心和耐心。
第三,信息 超载会让人望而生畏,尤其是对女性来说。我们倾向于认为我们不能比人理解得更快..可惜!我的目标是用我的网站展示数据分析可以被分成几个部分。我们可以更详细地查看每个步骤,以确定我们的下一个行动项目。例如,我们是否需要自己从复杂的数据库中查询数据,或者已经有一个. csv 文件可供分析。很多时候,我们甚至不需要花哨的建模来获得关于数据的深刻信息。在适当的数据收集和预处理之后,我们可以使用无监督学习从数据中提取模式。
通过尝试运行一些基本分析,甚至尝试正确导入数据,您已经可以学到很多东西。一步一步来,希望有助于揭开这个复杂词汇世界的神秘面纱;惊人的结果和令人生畏的数学。
总之,这篇文章根本不是针对女性的。它关注的是计算机科学世界中更多“女性”特质的影响。通过这篇文章,我希望能激励男性和女性在他们的日常工作中加入一些数据分析,只要他们看到一个尝试的机会。使用“男性”心态:谁知道会发生什么?或者甚至:这将是惊人的!。此外,要认识到清晰沟通和组织项目的价值。最后,尝试并激励同事(男性和女性)开始运行一些脚本,看看会出现什么,并专注于帮助他人。有足够多的数据可以使用,同样的情况也适用于花哨的方法。从人群中脱颖而出,不仅要展示你实施最新科学论文的个人能力,还要展示你在通往数据驱动社会的道路上领先的精神。
数据一年:2018
从一年的自我追踪中,我们能学到和发现什么?

追踪一个人的一生可以得出什么样的教训和观察结果?我们收集的所有数据可以用来更好地了解我们自己,甚至帮助我们变得更好吗?
在开始分析之前,这里有三个“挑逗性”的数据可视化和问题,这些数据帮助我注意到并回答了去年的问题:

2018 年,我手动记录的大部分时间都用在了个人项目上,这很好。我仍然保持着体面的客户,自由职业者的收入,但我的重点仍然是自己的东西和业务。。如果这些是你的目标,这就是你的时间应该去的地方。但是发生在六月和八月?这两个月都出现了不错的时间记录下降。这两个月让我去演讲,参加更多的会议以及更多的旅行,包括和朋友去西藏和四川旅游一周。我的睡眠也讲述了另一个故事。

2018 年我平均每晚睡 7.23 小时,但从 6 月中旬开始发生了什么?为什么我的睡眠平均值下降了?世界杯!像许多人一样,我熬夜,喝了一点啤酒,因为我享受了一个史诗般的足球行动月。具有讽刺意味的是,其他领域也出现了下滑。我写得更少,锻炼也更少。具体图表见下图。

2018 年我跑了一年比较一致,一直到最后一个季度?发生了什么事?突然,我的跑步训练量大幅下降。这是由于一系列轻微到严重的伤病,我不能训练了。原因是什么?下面我检查了一系列其他跟踪的数据点,目前我的工作假设是一个起作用的因素是流动性/拉伸和力量训练的减少。
这是我使用简单但有规律的自我跟踪和数据收集创建的三个数据可视化,数据收集使用 QS 分类账。如果你有兴趣在未来一年创建类似的图表或变得更加数据驱动,请注册我的简讯以提前获得我的课程,2019 年初谷歌数据工作室量化自我和数据驱动的生活。
现在开始表演!
我的数据驱动型年度评估
年度回顾是目标导向型的人的主要任务,也是我自己喜欢做的事情。但鉴于我的中心论点是数据可以用来改善人类生活,我喜欢超越怀旧的思考或充满希望的战略愿望。我喜欢用数据来充实我的一年回顾。
让我在这里简单梳理一下我的核心信念:我们现在有足够多的廉价技术、传感器、小型电脑(即手机和可穿戴设备)和云存储,既可以跟踪很多领域,也可以存储大量的生活数据。这种活动通常被归类为量化自我、自我跟踪、个人信息学或数据驱动的生活。
基本上,它是人们收集生活中的数据并试图使用它。很简单,我可以也应该使用数据和自我跟踪,这样我们的生活就能被更好地理解和改善。这是数据驱动的个人发展 101。
因此,带着这些目标和希望,我很高兴分享最新版的我的数据年!
今年的报告包括我如何写作,我的电脑使用时间和项目时间,我完成任务的趋势,阅读的书籍和文章,我的健身努力,以及我用手机拍的一些照片。对于健康,我强调跑步,但也有一些关于睡眠和 HRV 的一般健康数据。显然,有一吨的数据可以用来切片和骰子,并告诉你一年的回顾故事。我选择这些是因为它们对我很重要,而且相对来说任何人都可以跟踪。
今年的一个好处是,不像去年的数据年,我也开源并分享我用来创建这些图形的所有代码。因此,对于任何有一些技术技能和时间的人来说,你也可以建立你自己的数据驱动的回顾年。此外,通过一些调整,您可以改变外观和感觉,或者进行额外的观察和分析。你可以在 QS 分类账找到代码,我在文章的最后分享了一些具体的做法。
希望到明年年底,我将有一个网络或移动应用程序,让任何人都可以更容易地做,甚至可以用数据创建一本关于你这一年的完整书籍。
来看看我这一年在数据上的故事吧!
(注意:虽然超出了这里的范围,但我也做了一些更深入的统计分析和机器学习方法来使用这些数据。现在,我将不得不把这个话题留给将来的文章。)
背景故事:从跟踪到处理数据的一年…
(注意:本节将深入介绍细节,因此可以跳过下面的内容直接进入分析和数据,即!)
首先,也许有必要告诉你一点关于我追踪的东西以及我为什么追踪这些东西。
我的一个核心信念是数据和跟踪可以帮助我们更好地了解我们自己,并授权自我改善。我跟踪不仅仅是因为我发现这是一个有趣的爱好。我跟踪自己的生活,以便更好地了解自己,进而做出改进和个人优化。追踪开始是有点怀疑地询问我的时间去了哪里,并扩展到其他领域,以了解生活中的活动如何相互影响。
2018 年我追踪了什么?我在 2018 年没有做太多明确的跟踪改变,相比我在 2017 年跟踪的内容,除了改变我跟踪习惯的方式(我现在使用 Habitica)和我测量设备屏幕时间的方式(我使用苹果的 screentime)。也就是说,我确实跟踪了我应得的份额,并将继续这样做。
如果你正在寻找关于你可能跟踪的事情的想法,请查看我的帖子:2019 年你应该跟踪什么?在这里,我将进入一个两步走的过程,即跟踪什么以及如何利用你的数据实现你的目标。
与 2017 年不同,我在 2018 年的主要关注点不是如何跟踪,而是数据参与。我的目标是让数据变得有用和有意义。我停止使用 Tableau,这是我在数据博客帖子中的 2017 年我用于分析和图表的主要数据工具。Tableau 非常昂贵,作为一个拖放工具意味着不像在代码中那样容易再现数据可视化。这也意味着它不能扩展到创建未来的 web 工具或可共享的脚本。
由于今年重点关注 Python 的数据科学,我已经过渡到使用 Pandas 和 Matplotlib 来完成我的大部分数据分析工作,包括今年的数据审查。它还不是像素完美,但我对结果很满意。日复一日,我结合使用 IFTTT、Google Sheets 和 Google Data Studio 来驱动我的个人数据仪表盘。
实际上,这种对 Python 数据可视化的改变转化为我花了大量时间学习 Python,并为数据收集、数据可视化甚至一些机器学习编写代码。这是我多年来第一次使用 Python,我对可用的语言和工具非常满意。我在该地区的 PyCons 上的几次演讲中分享了我的学习和过程。最新版本可在:如何成为数据驱动的你:从数据采集和数据处理到数据分析和数据可视化再到用 Python 进行机器学习和深度学习。
此外,底层代码已经全部开源,可以在 Github 的 QS 账本上获得。事实上,这篇文章中的几乎所有内容都可以用你自己的数据和代码复制。除了代码中的数据分析,我唯一真正做的工作是将图表组合成一张图片,并用 Photoshop 添加一些样式。
总而言之,在 2018 年,我在 Apple Watch 上跟踪了我的步数、HR 和睡眠,用 Strava 跑步,用 Fitbod 应用程序进行力量训练,用 PhotoStats.io 拍摄照片,用 Goodreads 阅读书籍,用 Pocket/Instapaper 阅读文章,用 Todoist 完成任务,用 HR 训练心率变异性,用 PodcastTracker.com 收听播客,用 Toggl 进行项目时间,用 RescueTime 进行计算机时间。这些都是我拥有全年纵向数据的领域。
此外,我有一些血压和体重的定期检查数据,我还做了一些其他简短的跟踪实验,包括血糖监测和一个相当有趣的粪便跟踪实验。
这些图表涵盖了健康、生产力、创造力、时间和其他一些领域,是我试图讲述的一个数据故事。2018 年是我超越自我跟踪和数据积累的一年,我开始更加自觉地使用和参与我的数据,以实现一个目标,即建立一个数据可以改善生活的世界。现在,我的目标是帮助人们了解使用跟踪数据达到目标的可能性,并为个人数据分析带来更多的可访问性。
受我收集、分析、可视化和构建的所有数据的启发,这是我的数据年!
我在谷歌数据工作室的一年概述:
在进入我的具体数据可视化之前,让我们快速看看我对 2018 年的最后一次每周回顾。下面是我的工作效率仪表板的样子:

以下是我的健康和健身数据:

我很高兴地说,我用一些很好的锻炼和一点休息结束了 2018 年。从全球来看,你可以看到睡眠和锻炼的一些趋势。我的睡眠在每周 27 至 29 日有一些大的下降。那里发生了什么?我的跑步在 2018 年初达到顶峰,但我没有在下半年保持这一趋势。我在机动性和力量训练中看到了类似的趋势。在我的工作时间里,总体趋势是积极的,但也有一些有趣的下降。
这些个人数据仪表板和报告是使用 Google Forms、Google Sheets 和 Google Data Studio 的组合创建的。你可以注册我的时事通讯以在 2019 年初首次获得我的课程量化自我的谷歌数据工作室和数据驱动的生活。
下面我们来看一下跟踪数据的分类。
一年时间:我在 Toggl 中使用计算机和记录项目时间的一年
几年来,我一直在记录我的电脑时间和手工记录的项目时间。这提供了一个有趣的机会去探索我的时间在一年中的各种变化。
总的来说,这是我最后一年的样子:

一些时间使用要点:
- 2018 年更深入的工作:我是卡尔·纽波特书和支持“深入工作”的论点的忠实粉丝基本上,他认为,在一个分心的世界里,那些能够专注于认知困难任务的人将会富有成效,富有创造力,并产生更高质量的工作。这就是我如何对待和安排我的一天。我早上和下午都在做重要的、有挑战性的工作。然后我在下午休息一会儿,锻炼、吃饭和散步。晚上,我做一些挑战性较小的任务和行政工作。实际上,这转化为几天的时间,我真的深入其中,花了 10 多个小时工作。我发现,再加上几天真正的休息,这种深度方法对我很有效。
- 2018 年离开电脑 21 天:我在电脑上度过了 344 天,低于前几年的 362 天(2017 年)、362 天(2016 年)和 364 天(2015 年)。基本上,我花了一些时间完全离开电脑。起初有点困难,但一两天后,不用打开电脑,而是以不同的方式创作、思考、写作和阅读,这是一种解放。我喜欢这种数字突破的想法,我将在 2019 年尝试再次这样做。
- 更多的时间在软件开发和编码研究上:根据 RescueTime 的实际程序使用情况,我在软件开发上多花了差不多 300(2018:563.7 小时 vs. 2017: 268.5 小时)。根据我的项目日志,我也达到了今年超过 312 小时的目标。虽然我已经做了很多年的开发人员,但这是我第一次有意识地想学习一门新的编程语言(Python)并更多地参与工程。此外,这也出现在一些附带项目或初创公司的努力中,包括我的应用 PhotoStats.io 和 BioMarkerTracker 以及 PodcastTracker.com。最大的事情仍然是 QS·莱杰(更多关于这一点在最后)。
- 减少电子邮件:我 2018 年的目标之一是减少电子邮件。2017 年,我在电子邮件上的时间超过了 149.8 小时,而可怕的是,2015 年我一年仅在电子邮件上就花了 405.1 小时。但在 2018 年,电子邮件甚至没有进入前 7 名。正如我喜欢说的,没有人会因为最快的邮件回复时间而获奖。但是他们确实因为完成了重要的、有价值的工作并且做得很好而得到它。有趣的是,与 2017 年相比,我在 2018 年花在组织工作上的时间也减少了,如项目,任务和目标规划。这可能意味着我知道我应该做什么,不会浪费在“生产力色情”上。
- 更多的写作,努力成为职业作家:我终于接受了写作不仅仅是个人爱好,我现在正在努力成为职业作家。我的数据揭示了花在写作上的时间意味着什么。根据 RescueTime 的纯应用程序使用日志,2018 年我花了 429.8 小时编写应用程序,相比之下,2017 年的 379.3 小时和 2016 年的 298.9 小时有所增加。根据我积极记录的“写作”项目时间,我在 2018 年花了 370 小时写作,而 2017 年花了 227 小时。虽然我没有发表很多博客,但我正在写一本书,并创建一个在线课程,这两者都与我的写作技能密切相关。
关于我的时间,我最大的收获是:我花了 25%的时间在电脑上,比花在项目上的时间少一点。这个项目时间与计算机时间的比率仍然是我工作效率的一个清晰的衡量标准。一天、一周或一年的 25%在电脑上似乎是一个不错的数字,我真的不认为我能在 2019 年做出更大的努力。我可以在某些方面变得更加有效和平衡。例如,我希望在客户端工作上更加一致,这样我就可以减少集群化,增加常规输出。此外,我应该得到报酬,所以我需要思考,并在来年努力获得报酬。基本上,我在过去的两年中创建了一系列的副业项目,所以我计划开展真正的针对性活动,努力创造收入。然而,从全球来看,如果我遵循我的一般时间管理和时间分配,在未来的一年里,大事情最终会发生。推那块巨石!
一年的健身和跑步
我在 2018 年跑了两次马拉松和两次半程马拉松,并在途中进行了有趣的跑步和训练。我是一个跑步爱好者,我发现这种定期锻炼对我的创造力和生活满意度产生了非常积极的影响。我仍在努力使我的力量训练和灵活性/伸展性更加一致。以下是我健身一年的情况:

通过查看这些数据并将其与 2017 年进行比较,最令人吃惊的发现之一是移动训练时间的大幅减少。我没有做那么多的运动后恢复(从 2017 年到 2018 年,移动时间减少了大约 40%)。这让我想知道这种缺乏拉伸和恢复是否是我在 2018 年受伤更多和表现更差的一个因素。
目前,我将假设它是,并将致力于增加我的移动工作,以达到 2017 年的水平。我希望这能减轻我的疼痛,并为来年的良好运行打下更坚实的基础。我应该能在未来几个月里梳理出一个效果。
下半年我的力量训练有所下降。我想在未来的一年里变得更强壮,肌肉更发达,所以力量训练将是主要的追求,希望我也能从数据中梳理出更多我的进步(或不足)。一致性才是王道。
完成的任务:我在 Todoist 的任务和项目中的一年
我仍然是 Todoist 的超级粉丝。本着 GTD 精神,Todoist 是一个优秀的任务管理器,并提供了很好的数据可访问性,这也使它成为最好的任务跟踪器之一。
我又一次在 2018 年完成了很多任务。我在数据分析中没有注意到这一点,但我已经开始更多地关注更高优先级的任务,而不仅仅是检查一堆中等重要性的东西。总体而言,正如我们在数据中看到的那样,2018 年的产量非常稳定:

虽然主热图显示了一年中相当一致的任务完成情况,但这个可视化的下半部分让我可以注意到某些项目活动增加的模式和特定时期。
例如,对于生产力任务,我们几乎在一年中的每个周日都能看到一致的苍白目的。这是我每周检查一两个任务并设定目标的时候。类似地,我的编码学习通常安排在周六完成,热图显示了这一趋势,同时也显示了更多任务的密度。找到一种更好地可视化项目任务的方法是很有趣的,这样我们就可以在一周中的不同象限中看到它们。
相比之下,我看到几个项目有周期性的集群。对于数据驱动的你(一个在线课程和书籍项目)、语言学习(我在 4 月份试图学习一些泰语)以及在某些旅行之前和期间的分散旅行任务来说,这是真实的。
总的来说,我对正在完成的任务感到满意,并将继续推动自己朝着目标前进。在未来,我希望能够更好地将我的任务与我的目标联系起来,这也是我现在试图以一致的方式跟踪的。
写作一年
2018 年是我真正接受写作作为职业追求的一年。我发表了 26 篇博文,为我正在创建的一门课程准备了十几篇课程文章,我还有一份正在进行中的手稿。写作对我来说是一种习惯,我仍然写很多东西作为学习和研究的一种形式,但它正在慢慢走向实际的可出版的手稿。
我的写作行为应该得到更好的数据分析,但目前,这里有一组基于 WordCounter 的数据可视化,这是一个 Mac 工具,我用它来计算我在一组选定的写作应用程序中每小时键入的单词数:




我的作品中有几个明显的要点:
- 一个上午写作的人:我坚持在早上写作,这既是一种生产习惯,也是为了我的工作。我写作的高峰时间是从上午 10 点到中午。我应该致力于在未来继续积极保护这段写作时间。很明显对我有效。
- 一个不断变化的作家工具包:对于我的作家工具包,我一直是 Evernote 的长期用户,但我最近转向用明文减价文件写作和记笔记。自从从 Evernote 迁移出来,我就致力于这种新方法。这种对纯文本文件的改变也带来了跟踪我的写作的新能力。我也能跟上我的思想、学习和写作的发展。我计划很快就此分享一篇文章和代码。这将在未来几个月提供一些有趣的跟踪数据。
- 每月变化:我有一个一贯的写作习惯和产出,直到夏天事情开始下降。从 9 月到年底,活动再次增加。我不确定看到这种变化是件坏事。深度工作可以根据项目灵活安排。休息也是必要的。很高兴看到总体的一致性,但我喜欢在特定的时间和临近截止日期时深入努力,然后彻底休息。
- 出版物数据分析在哪里?我肯定需要对我的实际手稿进行数据分析。我可以从一个简单的自动化脚本开始,从我过去的所有作品中提取字数和出版日期。这也是我要做的事情。
睡眠与健康一年
自从我变得更健康,减肥,变得更加积极,我发现了很多关于自己和人类的事情。虽然我可以把这个放在开头,但我把这个可视化放在最后,因为它提供了一个有趣的方式来查看今年与这些趋势相关的其他方面。
让我们来看看数据:

以下是一些快速观察:
- 2018 年是健康的一年:我平均每晚睡眠约 7.23 小时,生病天数较少(2018 年 2 天,2017 年 5 天),我的最大摄氧量,这是衡量你最大氧处理能力的指标,相当健康,我的心率变异性【HRV】相对稳定。
- 为什么从 6 月到 7 月我的睡眠减少了?:世界杯!你会听说世界杯对全世界的生产力都有影响。我确实从熬夜、喝啤酒和看大量足球比赛中看到了我自己的影响。开球也与一个大型演讲约会和准备活动重叠。
- (轻微)负面趋势:我的几项健康指标呈轻微负面趋势,包括 HRV、最大摄氧量和我的一些睡眠。2018 年也喝的比较规律。如果我觉得 2018 年比 2017 年更好或更差,我自己的记忆是一个可怕的指标。我这一年过得不错,但我有一些数据可以看看,梳理出我的主观感受。就目前而言,这些核心指标确实需要一些努力来稳定下降趋势。在某些时候,我确实有一些跑步受伤和一定程度的个人压力。一些可能的选择是更好的睡眠模式(而不仅仅是更多的睡眠),有意识的放松,也许是冥想。
关于我的健康,我最大的一般收获是:我还没有时间进行真正的统计数据分析,但这些健康可视化确实暗示了我健康的轻微负面趋势与我生活各个领域的影响之间的某种程度的联系和相关性,见其他图表。例如,有人可能会问:我睡眠时间的减少和饮酒量的增加是否影响了我的健康表现、创造力和学习能力?做较少的伸展和活动会影响其他区域吗?在特定时间起床对一天或第二天有什么影响?这些都是我希望在未来探索的问题,无论是对自己还是对他人。
现在,我主要可行的项目是安排更多的时间睡觉和伸展,再加上一些冥想。基本上,不要只是计划项目和目标,也要包括放松的项目。
反过来,我早就应该进行一些血液生物标志物测试,看看是否有一些营养或其他失衡问题我可以解决。我有一个关于最常见和最有用的血液生物标志物的开源数据库,如果你想了解更多信息或知道要做什么测试。
阅读一年

关于我阅读的内容和时间以及我个人最喜欢的书籍和文章的完整细节和信息图表,请参见: 2018:阅读年。
照片一年
我们拍的照片也可以讲述一个关于我们生活的故事。这就是我开发 PhotoStats.io 的动机,这是一款适用于苹果和安卓系统的手机应用,可以让你在本地统计和解析你的拍照生活。除了帮助你追踪照片历史和标记照片,该应用程序还提供了一些简单的图表和图形。人工智能支持的自动标记功能还可以帮助你分类和理解照片中的内容。
那么,照片中的我这一年是什么样子的呢?

我的照片数据揭示了一些有趣的事情。它显示我在周末拍了大部分照片。我拍了很多动物(狗和猫)的照片,也拍了很多自然照片。我使用 PhotoStats.io export 和 MapBox 地图设计工具创建的地图清晰地显示了我过去一年去过的地方,包括老挝之旅、四川公路旅行和西昌马拉松赛、马来西亚会议以及西藏徒步旅行。我还能看到我去年在新加坡、曼谷和成都附近的青城山的主要枢纽。
像许多人一样,2018 年我远离了大多数社交媒体。脸书和 Instagram 有太多的“表演”艺术和生活,而不是真实的生活,它可以变成我在时间和享受生活方面的负面影响。也就是说,我最终在 2018 年在 Instagram 上分享了大约 35 张照片,大部分是在年初,当时我有一些欧洲朋友来访。
总的来说,我发现照片数据仍然是理解生活的一种非常有趣的方式,我计划继续维护和添加 PhotoStats.io 应用程序的功能。如果你有兴趣,你可以在 www.photostats.io 查看这个应用程序。假设你有最近几个月的大部分照片,它应该可以很好地给你一些总体趋势。
结论:大数字
以下是我 2018 年的“大”数字:
- 采取并记录了 3,878,369 个步骤。
- 在www.markwk.com 上发表了 26 篇博文。
- 跑 1559.72 公里(969.16 英里)
- 2 完成 42.2 公里马拉松
- 2 完成 21.6 次半程马拉松
- 通过 PhotoStats.io 拍摄、追踪 2991 张照片。
- 35 张通过我的 Instagram 发布在社交媒体上的照片(比 2017 年少了很多!)
- 94 天(的时间)在电脑上根据改期
- 根据人工时间跟踪,项目时间为 84 天
- 2212 在 Todoist 中完成了十几个项目的任务。
- 根据 GoodReads 的数据,60 本书阅读了 18657 页
- 通过 Pocket 和 Instapaper 阅读了 1785 篇文章
- 据 Trakt.tv 报道,他们看了 132 小时的电视和 82 小时的电影。
- 2018 年使用 Last.fm 收听和“搜索”了 16,855 首歌曲。我最喜欢的流派是 Synthwave、电子和 Synthpop。我最喜欢的歌曲是勒·马托斯的《冷夏》。我最喜欢的艺术家是乐卡带。
结论:离别的思念
好的。这是一年中的大量数据和数据可视化。总的来说,2018 年对我来说又是很好的一年。我保持健康,做对我重要的事情。我在财务上取得了一些进展,并致力于我的大愿景目标,即创造一个数据可以帮助改善和提高我们生活的世界。
显然,这种情况可能并不总是如此,未来的一年可能会在我的生活和数据中看到更糟糕的趋势。我可能会生病、受伤或抑郁。生活就是这样。我仍然致力于每年用数据讲述我的故事,一个真实的、个人的故事,不管那种生活是好是坏。
展望未来,我希望让这种跟踪和数据分析变得越来越容易被每个人理解。我目前正在谷歌数据工作室为量化的自我创建一个在线课程(计划在 2018 年初发布)和一个更长的课程如何跟踪生活。我在 QS·莱杰方面也取得了稳步进展,这是今年所有报告的主要代码。
如果你对使用数据来增强我们的世界和生活的可能性感到兴奋,请加入我的简讯或通过评论、电子邮件或社交分享来联系我。越来越多的人来烦我,加入我,肯定会推动我在未来的一年里在这些领域做更多的工作!
我希望你喜欢这篇文章,并发现它有趣和鼓舞人心。
祝你在新的一年里好运和快乐!
额外收获:用 QS 分类帐建立你自己的数据年度或数据驱动的年度回顾
《数据回顾》中我这一年的所有数据可视化都是使用QS·莱杰创建的,这是一个 python 数据科学项目,专注于个人跟踪数据的数据收集和数据可视化。然后用 Photoshop 将它们组合起来。
唯一的例外是地图。这些是使用 MapBox 地图设计器创建的,并将基础数据导出到带有经度和纬度的 CSV 中。使用 MapBox 的在线数据集和制图工具,这是一个非常简单的过程。
在这一节中,我想简单介绍一下如何使用 QS 分类帐在数据中创建年份。
PS——如果你对 QS 账本中涉及的背景故事和数据科学感兴趣,并使用 Python 进行自我跟踪,请查看我在如何成为数据驱动的你的详细幻灯片:从数据收集和数据处理到数据分析和数据可视化,再到使用 Python 进行机器学习和深度学习。
跟踪注释:
为了跟进,你需要一直跟踪与 QS·莱杰集成的数据点之一。该项目目前集成了近 20 种不同的跟踪服务,如 Strava、Fitbit、Oura、RescueTime、Todoist 和许多其他服务。
安装 Anaconda 并下载代码和笔记本
首先,我推荐下载并使用 Anaconda 发行版。这是一个 Python 的数据科学平台,包括一个简单的安装程序和你需要的主要软件包。
接下来在这里下载或者 git 克隆代码 repo:https://github.com/markwk/qs_ledger.
QS 莱杰是使用 Python 3 构建的,代码目前通过 Jupyter 笔记本共享。大多数服务依赖 Pandas 和 NumPy 进行数据操作,依赖 Matplot 进行数据分析和可视化。
在 QS 分类账目录中启动 Jupyter 笔记本
- 安装了 Anaconda 或同等软件后,打开命令行或终端应用程序。
- 定位至下载 QS 分类帐代码的位置。
- 在该目录中,只需命令
$ jupyter notebook就可以在浏览器中启动 jupyter 笔记本程序。或者,您可以安装并使用 Jupyer Lab,它提供了更多的功能。
核心步骤:收集数据,运行分析
在接下来的步骤中,我们将浏览一个示例数据源,即 RescueTime。首先,我们将从 API 收集数据,然后运行一些数据分析代码。
虽然不同服务的细节可能略有不同,但基本方面基本上是相同的:在运行(和/或调整)数据分析之前收集数据。
示例:RescueTime 的数据收集
RescueTime 是我最喜欢的跟踪服务之一。它可以让您跟踪您的计算机使用时间的难以置信的细节。
在 Jupyer 笔记本的中,导航文件目录并打开 rescuetime 目录中的rescuetime_downloader.ipynb。如果你愿意,可以在网上看看代码:https://github . com/markwk/QS _ ledger/blob/master/rescue time/rescue time _ downloader . ipynb .
在该笔记本中,您将看到为收集数据进行重新时间设置的多个步骤。使用您自己的授权密钥遵循这些步骤。
完成后,运行所有单元格,开始收集数据。这可能需要几分钟,取决于您使用 RescueTime 的时间。

最终结果应该是几个导出的 csv 文件,您应该准备好做一些数据分析!
示例:重新计算时间的数据分析
现在是时候打开rescue time _ data _ analysis . ipynb并运行数据分析了。
该笔记本的第一部分提供了一些关于你在电脑上花费的时间的一般数据分析,包括你的主要类别和应用程序的细分,每月生产时间与分心时间的细分,以及其他一些报告。我建议一个接一个地浏览第一部分,对您的数据有一个大概的了解。
以下是我的年度明细:

数据分析的后半部分允许您设定目标年份,然后查看您的年度分析。默认情况下,它被设置为当前年份,但是您可以调整它来查看与上一年的比较。我们再一次看到了热门应用和月份的细分。此外,还有一个热图,让您可以查看一年中哪一天工作效率最高,或者您使用电脑的时间最多。最后还有一个小时图表,显示你一天中哪几个小时效率最高。
这是我每天工作时间的热图:

虽然不可否认的是,代码确实需要在未来的一年中进行一些清理,但大多数代码都有很好的文档记录,并且清楚地说明了它在做什么,因此您应该能够调整和调整以查看时间数据的不同方面。如果您有任何问题,请在 github.com 的问题队列中留言。
下一步:其他服务的数据收集和数据分析。
现在我们已经看到了一个使用 RescueTime 进行数据收集和数据分析的示例,您可以继续为其他跟踪服务收集和生成数据报告。这包括锻炼、睡眠、完成的任务等数据。
我强烈建议使用相同的可视化方式并排比较不同的跟踪数据,看看是否能注意到任何可能的趋势或联系。
此外,还有一个示例笔记本,展示如何将多个数据源组合成一个数据框。这可以用来创建包含多个数据点的图表,探索相关性甚至使用机器学习进行预测、聚类和预测。
祝你的数据分析和自我跟踪好运,我迫不及待地想看看你创造了什么!
星巴克的 A-Z 特性工程

Photo by Erik Mclean on Unsplash
据估计,80%的数据科学过程致力于收集数据并将其塑造成可行的形状。许多组织坐拥大量数据,这些数据可能以各种形式出现。
在本帖中,我们将看到商业头脑和以客户为中心的方法如何转化为获得有用的见解,即所谓的特征工程。
数据可以在 github 上找到,包含星巴克奖励移动应用程序上的模拟客户行为,就像在现实生活中发生的一样。每隔几天,星巴克就会向手机应用程序的用户发出一次报价。
开始时严格的方法论可以转化为无缝的实现,比如制作一个推荐引擎。
这篇文章的解释和代码注释非常冗长:它试图阐明特性工程过程中的每一个步骤。
数据集

Photo by Etty Fidele on Unsplash
数据集被分成三个 JSON 文件:
- portfolio :包含要约 id 和关于每个要约的元数据(持续时间、类型等)。)
- 配置文件:每个客户的人口统计数据
- 抄本:交易、收到的报价、查看的报价和完成的报价的记录
每个文件处理特征工程过程的一个主题。我们的最终目标是将这三个文件汇集成一个全面的用户特征数据框架和一个用户项目矩阵。我们将利用 python 3.x 库,如 pandas ( pd )、 numpy ( np )、matplotlib(PLT)、以及 seaborn ( sns )。
投资组合

Photo by Bundo Kim on Unsplash
第一个文件处理可能仅仅是一个饮料广告或实际优惠的优惠,如折扣或买一送一( BOGO )。某些用户可能在特定的几周内收不到任何报价。
我们使用 pandas.read_json 方法加载投资组合
我们可以在单一视图中显示产品组合:

Portfolio
下面是我们原来栏目的解读,建议在开头用 pandas.dtypes 来确认数据类型。
- id (字符串)—报价 id
- offer_type (string) —优惠类型,即 BOGO、折扣、信息
- 难度(int)——完成报价所需的最低花费
- 奖励(int)——完成一个要约给予的奖励
- 持续时间 (int) —报价开放的时间,以天为单位
- 通道(字符串列表)
我们注意到 offer id 是一系列没有特定含义的字符串,用整数替换它们会很有用。如果这些整数在编号背后有某种意义,那就更有用了:让一个更小的 offer id 表示更容易的难度。
我们利用 python 内置的 zip 和 dict 构造函数将报价映射成整数。如果我们需要返回,我们为另一个方向创建一个字典。
此外,我们可以看到渠道只能接受四个值:电子邮件、手机、媒体和社交。假设它是一个嵌套在列中的列表,我们使用 pandas.get_dummies 和 pandas。系列:
结果是一个可读性更好的表,其中 1 表示真,0 表示假。我们将同样的方法应用于 offer_type 特征。我们将同样的方法应用于 offer_type 列,并创建一个 offer_type_dum 表。

对于奖励和难度,我们对单位了解不多。奖励是美元还是一些 app 币?难度是如何衡量的?不确定性是数据科学过程的一部分,在这种情况下,我们将保持这两个特征不变。
我们将把持续时间转换成小时,因为我们将在后面看到它将与抄本数据集中的单位相匹配。我们可以用 pandas.concat 、 replace 和 reset_index 创建一个干净的投资组合。:
结果是一个干净得多的桌子可以自己站立。

我们可以使用这些清理后的数据,用几行代码创建一个 Pearson correlation 热图:
热图揭示了一些有趣的相关性,例如 BOGO 的提议往往与更高的回报相关。

在组合中,我们看到了简单的清理步骤如何让数据自己讲述一个故事。在下一节中,我们将看到如何处理丢失的值。
用户概要

Photo by Nathan Dumlao on Unsplash
我们以与投资组合类似的方式下载个人资料数据,下面是一个示例截图:

我们在以下特征空间下总共有 17,000 个观察值:
- 年龄 (int) —客户的年龄(如果未知,则为 118)
- 成为会员日期 (int) —客户创建 app 帐户的日期
- 性别 (str) —客户的性别(注意,有些条目包含“O”表示其他,而不是 M 或 F)
- id (str) —客户 id
- 收入(浮动)—客户收入
我们马上就可以看到,缺少值是一个问题。我们使用 pandas.isna 和 pandas.mean 方法来查看缺失值的分数:

有趣的是,收入和性别都有相同比例的缺失值。对于同样的用户,我们是否对年龄、性别和收入一无所知?我们可以用一个断言语句来检验这个假设:
语句传递:原来这是同一批用户。
当处理缺失值时,我们必须问我们在模型中注入的方差和偏差是什么。丢弃所有丢失的值可能会使模型失去有用的信息。对于收入和年龄,我们查看没有缺失值的数据分布。


我们看到均值和中位数几乎是一样的。因此,如果我们估算中值,我们不期望均值或方差发生变化。
对 T2 来说,性别问题更加微妙。2018 年亚马逊因对女性有偏见而废弃了他们的人工智能招聘工具。性别是自我报告的,我们会把回答了其他问题的人和不想回答的人归为一类。
用户 id 是一系列没有特定含义的字符串,我们可以像以前一样创建一个 human_to_int 字典。
最后一个特征是客户创建账户的日期。这一特征对于衡量客户任期似乎很重要。然而,如果我们不能参照某个时间点,时间的度量就没什么用了。我们决定放弃的特性。
副本

Photo by Carli Jeen on Unsplash
最终的数据集也是最有趣和最复杂的。以下是文字记录的样本:

其特点是:
- 事件 (str) —记录描述(即交易、收到的报价、查看的报价等。)
- 人员 (str) —客户 id
- 时间(int)——自测试开始后的时间,以小时为单位。数据开始于时间 t=0
- 值 —(字符串字典)—报价 id 或交易金额,取决于记录
我们可以看出这份记录需要大量的清理工作。首先,在事件列上应用 get_dummies 方法是有帮助的。

我们可以通过将值列转换成一个序列来分解值列中的值。

我们看到键,现在是列,有四个不同的值。似乎 offer id 和 offer_id 是两个独立的列,可能是记录数据时出错。我们可以通过查看这两列是否互斥来检查这一点:
该行返回一个空数据帧。这意味着 offer id 中没有值包含在 offer_id 中,这两列之间没有明显的冲突。我们可以用熊猫来纠正这个错别字。
我们现在可以创建一个结合了这些列并使用了 human_to_int 和 offer_to_int 字典的抄本 _comb 数据框架。此外,我们建议使用 pandas.map 而不是 pandas.replace 来提升性能。
组合的数据帧抄本 _ 梳看起来像:

我们可以调查人物 2 并查看他们的历史样本:

请注意,时钟不会在时间=0 时开始计时。这与给定条件表相冲突,记住总是要验证陈述,并且在证明之前不要假设为真。用户也有在报价前发生的购买,我们没有明确的方法知道后来的购买是否是因为报价。
此外,开始时间不依赖于某些参考,比如用户注册的日期或一天中的时间。因此,我们将假设观察期不受季节性的影响。
考虑下面显示的另一个人: person 35 。这位客户在 time=0 收到报价,立刻打开,6 小时内成交。
另一方面,他们在 time=168 收到一个报价,立刻打开,在 time=336 收到另一个报价,再次打开,在此期间没有完成两个报价就花了钱。

这两个案例揭示的是,支出还没有被标记,并且多个提供可以同时发生。这与现实中用户收到可以组合在一起的多个报价没有什么不同。
在某些情况下,用户没有看到报价,仍然会花钱。假设他们的消费是因为一个提议,这将是一个严重的高估。
我们将假设用户受到被查看的第一个要约的影响,该第一个要约将是被发送的第一个要约。下表是这一假设的示意图,也是整篇文章的症结所在:

考虑将接收两个要约 O1 和 O2 的单个用户,使得在接收到 O1 的时间 T0 记录时间。在 T0,用户不受任何报价的影响。从 T1 开始,用户看到了 O1,因此任何购买都是因为 O1 而完成的。
在 T1,用户也接收到 O2,但是还没有看到它。在 T2,可以看到 O2 的报价,但是用户仍然受到 O1 的影响。只有过了 O1 的有效期,才能认为购买是因为 O2 而完成的。
这是一个简化,被认为是这个职位的范围所必需的。在现实中,更详细的评估将包括至少 90 个可能的报价组合,并可能根据难度、报酬和沟通媒介等指标来确定哪个报价将占主导地位。
我们的目标是创建这样一个函数,为一个交易分配一个报价 id。此外,我们希望测量用户行为,如打开时间和完成时间,如果可能的话,到一个时态表。
我们从返回 iterable 的每个部分的成对函数开始。
我们定义 person_fill_na.py 为交易分配报价 id ,如下所示:
注意,在上面的函数中,我们将开始时间和结束时间定义为报价持续时间的一部分。事实上,相对于报价来衡量用户的反应比用绝对数字来衡量更有意义。
我们用转录本 _ 填充 _ 钠. py 构建了上面的函数。
在预期的管道中,使用一个清理器函数从数据库中获取数据并返回清理后的数据帧是很有用的。为此,我们定义了一个抄本 _cleaner.py :
在将来的应用程序中,我们可以用一行代码来处理这个脚本:
把所有的放在一起

Photo by Gabi Miranda on Unsplash
创建用户数据框架
清理完所有三个文件后,我们可以开始组装带有 pandas.merge left join 的表,以便在一个公共键上进行一对多匹配。一个 pandas.groupby 语句按用户和项目聚集统计数据。此外,我们将沟通渠道乘以被看到的时间量,从而相应地分配权重。
下一步,我们将思考什么是总和统计,什么是平均值统计。我们可以在下面的代码中看到,事务的数量应该是一个总和,而时间的度量应该是一个平均值。
最后,我们通过内部连接创建用户数据框架。我们还定义了更多功能,例如:
- amount_pct :因促销而花费的钱的百分比
- 看过的出价与收到的出价的比率
- 已完成 _ 比率:已完成报价与已收到报价的比率
我们还用 1 填充完成时间和打开时间,这样 0 表示非常高的响应率,1 表示很少响应或没有响应。
user_df 现在是每个用户的个人资料和消费习惯的大规模特征集。下图展示了 23 个特性中的一小部分。

用户-项目矩阵
创建用户项目矩阵不太复杂,因为我们使用来自清理函数的抄本 _ 完整的:
得到的用户条目数据帧是:

摘要

Photo by Hans Vivek on Unsplash
清洁过程绝不是一项简单的任务,需要所有负责方的审慎判断。大多数真实世界的数据是杂乱无章的,形式混乱,需要验证其可靠性。
引用凯茜·奥尼尔和瑞秋·舒特的话,一名数据科学家将时间花在了:
数据将如何用于决策,以及它将如何重新构建到产品中[…]她在收集、清理和挖掘数据的过程中花费了大量时间,因为数据从来都不是干净的。这个过程需要持久性、统计学和软件工程技能——这些技能对于理解数据中的偏差和调试代码的日志输出也是必要的。
我希望这篇文章对你有用!特别感谢 Udacity 和星巴克的合作,并使这些数据可用。
R 中 AB 样本量的计算
R 中计算样本容量和实验持续时间的一些有用工具

介绍
为利益相关者执行即席分析可能非常耗时。此外,我还经常被问到一些问题。所以我花了一些时间开发一些工具,让我的“非技术”同事在 r 中使用。
最常见的问题之一是“我需要多大的样本才能达到显著性?”,后面常常是“我需要运行我的实验多长时间?”。为此,我开发了一些简单的代码,供人们在需要回答这些问题时使用。所有用户需要做的是传递一些基线数字到我创建的一些函数中,他们可以确定他们的样本大小要求和实验持续时间。
样本量、统计功效和实验持续时间
幸运的是,通过了解一些简单的信息,R 中的 pwr() 包可以相当轻松地回答这两个问题。 Pwr() 帮助您在进行实验之前进行功效分析,使您能够确定每个实验条件下的样本量。
计算功耗分析所需的四个量有着密切的关系,如果我们有剩余的输入,我们就能够计算出其中的任何一个值:
1。样本量(n)
2。效果尺寸
3。显著性水平(α)= P(I 型误差)=发现不存在的影响的概率
4。功效= 1 — P(第二类误差)=发现存在效应的概率
由于您的显著性水平(3)和功效(4)通常是固定值,只要您可以输入对照和变量的效应大小(2),您就可以确定所需的样本大小(1)。
幸运的是, pwr() 包中的 ES.h() 函数计算出我们的效应大小,以便我们进行功耗分析。我们通常会知道我们的控制条件的当前转换率/性能,但是变量的影响根据定义几乎是未知的。然而,我们可以计算一个预期的影响大小,给定一个期望的提升。一旦计算出这些影响,它们将被传递到 pwr.p.test() 函数中,该函数将计算我们的样本大小,前提是 n 留空。为了使这种分析对用户友好,我将前面提到的两个函数打包成一个新函数,名为sample _ size _ calculator()。
此外,因为我们将使用这些信息来计算运行实验所需的天数,所以我也创建了一个 days_calculator() 函数,它将使用我们的样本大小计算的输出:
sample_size_calculator <- function(control, uplift){
variant <- (uplift + 1) * control
baseline <- ES.h(control, variant)
sample_size_output <- pwr.p.test(h = baseline,
n = ,
sig.level = 0.05,
power = 0.8)
if(variant >= 0)
{return(sample_size_output)}
else
{paste("N/A")}
}days_calculator <- function(sample_size_output, average_daily_traffic){
days_required <- c(sample_size_output * 2)/(average_daily_traffic)
if(days_required >= 0)
{paste("It will take this many days to reach significance with your current traffic:", round(days_required, digits = 0))}
else
{paste("N/A")}
}
如果您正在使用此工具,您只需指定您的控制转换率和所需的提升:
control <- 0.034567uplift <- 0.01
并运行 sample_size_calculator() 函数:
sample_size_calculator(control, uplift)sample_size_output <- sample_size_output$nsample_size_output
然后,在给定这些值的情况下,您将获得所需的样本大小输出(请记住,此样本大小要求是针对每个变量的):
[n]230345
现在我们有了这些信息,我们可以确定实验需要进行多长时间。您需要输入的只是您的日平均流量:
average_daily_traffic <- 42000
运行 days_calculator() 函数:
days_calculator(sample_size_output, average_daily_traffic)
您将得到以下输出:
[1] It will take this many days to reach significance with your current traffic: 36
虽然此代码仅适用于 AB 设计的实验(即只有两个实验条件),但是可以使用 sample_size_calculator() 中的 pwr.anova.test() 函数,替换 pwr.2p.test() ,修改给出的函数,以计算多个实验条件下所需的样本量。
结论
功耗分析是任何实验设计的必要方面。它允许分析师以给定的置信度确定检测给定规模的统计显著性效应所需的样本规模。相反,它也有助于在样本大小的限制下,以给定的置信度检测给定大小的效应。如果概率很低,建议改变实验的实验设计,或者将输入到功效分析中的某些数值最小化。
相互结合使用,计算所需的样本和实验持续时间可以为利益相关者提供非常有用的信息。获得这些信息可以帮助他们有效地规划他们的实验路线图。此外,这些预定的数字可以帮助确定某些实验的可行性,或者期望的提升是否过于理想化。
关于对立的例子
关于什么、为什么和如何使用对立例子的概述

在深度神经网络的世界中,对立的例子是一个有趣的话题。这篇文章将试图解决这个话题的一些基本问题,包括如何产生这样的例子,并对它们进行防御。以下是我们将要介绍的内容:
- 什么是对立的例子?
- 为什么重要?
- 为什么会发生?
- 如何生成对抗性的例子?
- 我们如何防御对立的例子?
1。什么是对立的例子?
一般来说,这些输入旨在使模型错误地预测。在计算机视觉环境中思考这一现象更容易理解——在计算机视觉中,这些是输入图像的小扰动,会导致模型的错误分类。

From Explaining and Harnessing Adversarial Examples by Goodfellow et al.
虽然这是一个有针对性的对立示例,其中图像的变化是人眼无法检测到的,但非针对性示例是那些我们不太关心对立示例对人眼是否有意义的示例——它可能只是人眼的随机噪声。

A non-targeted “3” from Tricking Neural Networks: Create your own Adversarial Examples by Daniel Geng and Rishi Veerapaneni
我不能完全准确地说,有针对性的对抗性例子是图像的变化是人眼无法察觉的。虽然扰动很小, 有证据表明,在一个有时间限制的环境中,即使是人类也会被对抗性的例子 所愚弄。
2.为什么重要?
在开始解释为什么这个话题很重要之前,让我们先弄清楚几个定义。根据攻击者的知识水平,对抗性攻击可以分为白盒攻击或黑盒攻击。白盒攻击是指对手完全了解被攻击的模型,如权重、偏差、使用的超参数等。黑盒攻击的对手是只知道模型输出的普通用户。
对抗性攻击是一个重要的研究和考虑的主题,因为它已经表明,对抗性的例子从一个模型转移到另一个模型。换句话说,为欺骗一个模型而生成的对立例子也可以欺骗使用不同架构的其他模型,或者使用相同任务的不同数据集进行训练。现在,这变成了一个巨大的安全风险,因为攻击者可以为与目标模型相同的任务开发本地模型,为本地模型生成对立的示例(就本地模型而言是白盒),并使用它们来攻击目标(可转移性使得对目标模型的黑盒攻击更容易)。这使得大量主流或即将成为主流的应用面临风险,如面部识别、自动驾驶汽车、生物识别等,这些应用利用了基于 ML 的计算机视觉模型。
本文 探讨了这在现实世界中的威胁有多大,因为在现实世界的许多使用案例中,输入来自摄像头和其他传感器。它证明了即使通过摄像机输入对立的例子也会导致错误分类。 这是另一篇论文 通过生成在变换分布上保持稳健的示例,并使用 3D 打印来创建稳健的 3D 敌对对象,来展示现实世界的威胁。
3.为什么会发生?
深度学习和机器学习吸引了所有的注意力,因为它们帮助我们成功地解决了计算机视觉、自然语言处理等问题。这些用例是传统的基于规则的系统无法解决的,仅仅是因为所涉及的规则的庞大数量和复杂性,考虑到这些用例的输入中可能会有各种各样的变化。换句话说,如果我们必须手工编写准确识别所需的所有规则,输入空间通常非常巨大,并且接近无穷大。即使对于像 MNIST 这样的低变量数据集也是如此,更不用说 ImageNet 或其他场景了。
一般来说,神经网络是一个计算图,其中分类决策由针对训练数据优化的权重和偏差驱动,并且不显式地对决策应用逻辑推理。因此,任何非目标图像被错误地以更高的可信度分类为属于某一类并不令人惊讶。例如,每个像素可以有 256 个可能的值,因此,即使是 16×16 大小的小图像也可以有无限多的可能输入(即,256 个⁶* ⁶或~10⁶ ⁶可能图像)。考虑到如此大的输入空间,找出一些能使计算图产生与正常图像相同的结果并不奇怪。
4。如何生成对抗性的例子?
从概念上讲,用于生成对立范例的方法与开发神经网络没有太大的不同。如果 A =训练数据,B =预期分类,C =模型权重,D =成本函数。在训练模型时,A 和 B 是固定的,我们不断改变 C 以确定使 d 最小的最佳值。类似地,为了生成如上所示的无针对性的对抗性示例,我们保持 B 和 C 固定,并不断改变 A 以确定使 d 最小的最佳值。
这是 Pytorch 文档中的另一个例子,通过引入一个小的改变来产生一个有针对性的例子。
*# FGSM attack code*
**def** **fgsm_attack**(image, epsilon, data_grad):
*# Collect the element-wise sign of the data gradient*
sign_data_grad **=** data_grad**.**sign()
*# Create the perturbed image by adjusting each pixel of the input image*
perturbed_image **=** image **+** epsilon*****sign_data_grad
*# Adding clipping to maintain [0,1] range*
perturbed_image **=** torch**.**clamp(perturbed_image, 0, 1)
*# Return the perturbed image*
**return** perturbed_image
该文档提供了一个端到端的示例,包括模型定义、初始化和前馈方法,以及一个测试函数来运行攻击并可视化生成的对抗示例。但这一切的关键是上面的方法,创造了一个对立的例子。请注意,这与训练模型非常相似。通常,在针对给定输入和预期输出进行训练时,您会更新模型的权重。
*# Update weights*
w1 **-=** learning_rate ***** grad_w1
w2 **-=** learning_rate ***** grad_w2
然而在这里,权重没有改变,但是输入图像改变了。
*# Create the perturbed image by adjusting each pixel of the input image*
perturbed_image **=** image **+** epsilon*****sign_data_grad
还要注意,在更新权重时,我们减去学习率乘以梯度,从而将它们向最小化成本函数的方向移动,而我们将ε乘以梯度添加到图像,从而向相反方向移动成本函数。
5。我们如何防御对立的例子?
总的来说,还没有任何普遍接受的解决方案来抵御对抗性攻击。已经提出了许多防御技术,但结果不一,而且在随后的研究中经常被绕过。以下是一些重要的常见示例:
对抗性训练 是在训练时使用对抗性的例子,以减少误分类。有不同的技术探索制定这一概念和改善培训。我们不会在这里讨论这种训练的各种技术和相关细节,但一般来说,对抗性训练在使模型对攻击具有鲁棒性方面产生了混合的结果。
自动编码器 是使用的另一种机制。自动编码器是一种神经网络,它首先通过使输入通过一个较低维度的隐藏层来降低输入的维度,然后再尝试在其与输入层具有相同维度的输出层中重建信息。换句话说,它试图成为一个恒等式函数,只是它被约束为在重构信息之前首先压缩信息。根据定义,这消除了输入中的噪声,并且仅保留了重建原始图像所必需的那些特征。这种自动编码器也有助于消除敌对的干扰,并取得了一些成功。但是也可以使用前面描述的相同方法生成对立的例子,只是现在包括自动编码器以及网络的一部分。
防御蒸馏是解决这个问题的另一种方式,正如这里讨论的和 这里的 。防御性蒸馏是网络蒸馏的一种变体,其中网络的概率向量预测作为具有相同架构的蒸馏网络的训练标签。使用这样的软标签进行训练使得提取的网络平滑,对输入的变化不太敏感,并且对敌对输入具有鲁棒性。**
DeepSafe ,另一种很有前途的方法,就是这里讨论的。这是一种基于以下原则的技术,即输入空间的一个区域内的所有输入属于同一类,并且将被标记为相同。DeepSafe 首先将已知的标记输入分组到不同的聚类中,每个聚类包含相同类别的图像,并代表输入空间中的一个区域。然后,它发现在这个区域内是否有被不同分类的输入。如果在该区域内没有找到这样的输入,则认为它是安全的。如果找到一个,则重新绘制该区域并重复该实验,直到找到一个安全区域。
正如本文 中所讨论的 ,也许对抗性的例子是不可避免的,尤其是在更高维度中更难防范。无论如何,这是一个重要的话题,对于参与这个领域的每一个人,从主管到爱好者,所有关于这个话题的研究和发展都应该被密切关注和尽可能的支持。
具有社会影响的数据科学案例

Two hands holding a heart made of tech elements (author unknown)
到目前为止,数据的重要性、力量和价值是毋庸置疑的。企业已经找到了盈利的方法,无论是通过销售新产品和服务,还是仅仅通过优化内部流程和节省资金。然而,关于数据的社会影响以及数据如何直接帮助那些急需帮助的人和整个社会的讨论并不多。
称之为新的石油或新的黄金,数据无处不在,无时无刻不在产生。当被问到这个问题时,我们都能想到数据产品的商业例子:推荐系统、搜索引擎、信用风险算法。毫无疑问,这些都是有用的——它们解决了一个问题,并在某种程度上改善了人们的生活。
另一方面,还没有太多的想法(更少的工作)放在使用这些相同的算法通过帮助更多弱势群体来创造非商业的社会影响上。事实是,公司用来提高利润的这些算法也可以被社会公益组织使用——毕竟,数据驱动不仅限于公司。事实上,数据科学还可以帮助政府、非营利组织和社会公益组织更有效地运作。
那么,为什么这里还没有做很多工作呢?嗯,就是一般的原因——不赚钱。
大多数在任何社会变革领域工作的组织都没有预算或人员来充分利用这场数据革命。更重要的是,他们甚至不知道数据如何帮助他们——我不怪他们,他们的日常运营已经忙得不可开交了(你知道,拯救世界之类的)。最终,这些组织主要依靠志愿工作生存下来,而这些志愿工作在任何方面都是不可扩展的。但是,如果我们能向这些组织展示数据对他们的价值,那会怎么样呢?如果我们可以使用数据在他们的工作中引入可扩展性会怎么样?
除此之外,数据科学专业人士也不清楚他们如何能提供帮助。
大多数数据科学家没有意识到,如果他们的专业知识以不同于他们日常工作的方式得到利用,他们的技能会多么有价值,他们的工作会多么有影响力。但是说实话,数据科学可以在很多领域产生直接的社会影响。从扶贫、倡导儿童福祉和抗击饥饿到医疗保健、改善教育和环境事业,数据科学有可能真正解决看似牢不可破的问题。然而,这只有在数据科学家和社会部门专家之间进行强有力的合作时才有可能。
那么,现在该怎么办呢?
我对解决这一问题的组织数量在全球范围内少于少数感到失望,但受到这一社会需求的激励,我和一群对数据科学和社会影响有着相同愿景的了不起的人聚集在一起,创建了葡萄牙社会公益数据科学。我们希望根据社会公益组织的真正需求,通过从数据收集到预测建模的整个数据处理流程来帮助他们。
为了让事情变得更简单快捷,我们与 DSSG 芝加哥合作(并借用了这个名字)。他们的投资组合中已经有了一系列社会公益项目——比如这个项目,关于在美国几个警察部门使用数据科学来改善警察互动。DataKind 是另一个已经做了相当长一段时间的组织(他们有幸与我们见面,分享了他们的一些实用知识,并就如何启动这个项目给出了提示——谢谢大家!).他们做的一个项目是关于英国无家可归者以及弱势群体的数据如何降低这个问题的普遍性。
希望这两个例子能让你理解利用数据科学造福社会的潜力,并激励你进一步思考你能做些什么。
正在总结…
如果你想了解更多关于 DSSG 葡萄牙以及我们如何利用数据的力量改变社会(以及我们的公益时间),请查看我们的 LinkedIn 并关注我们的 Medium 。我们将在这里分享关于我们的社会公益项目的新闻和真实故事——这里仍然有点像鬼城,但请留步,我保证它会越来越多😄
附注:我们将在葡萄牙举办两场演示会议(一场在波尔图,另一场在里斯本),欢迎参加。有免费的食物!🍖
使用 SSL 证书验证从 Azure 函数访问 MySQL 的 Azure 数据库
一种连接 MySQL 的安全方式,可防止中间人攻击

Photo by Dayne Topkin on Unsplash
最近,我有一个客户需要管理相对较少的数据。所以,我建议 MySQL 用 Azure 数据库。基本上,最小的实例成本大约每月 560 澳元就足够了。此外,因为这是 DBaaS,所以客户不需要雇用更多的人来维护它。
客户还希望自动化这个 MySQL 数据库的 ETL 过程。虽然我认为数据工厂将是理想的解决方案,但成本可能是一个大问题,因为 ETL 必须每 5 分钟进行一次,这将过于频繁地触发业务流程,并导致“休克”账单。因此,我建议使用 Azure Functions,它是一个无服务器的计算解决方案来完成这个 ETL。另一个原因是数据转换并不太复杂,一旦完成就很少会改变。
然而,当我使用 python 实现这个 Azure 函数来连接 Azure MySQL 服务器时,我遇到了一个问题。也就是说,MySQL 实施了 SSL 加密,但是 Azure 函数端不提供证书。在我们的案例中,禁用 SSL 实施不是一个选项,因为我们不想将客户的数据置于诸如中间人攻击这样的危险境地。因此,我需要解决这个问题,最后,我做到了。以下是重现问题的步骤和解决方法。
步骤 1:为 MySQL 创建 Azure 数据库
进入你的 Azure 订阅,点击创建资源 - >搜索 MySQL 的 Azure 数据库 - >创建
在创建 MySQL 服务器页面中,填写资源组、服务器名称和其他必填字段。在这个例子中,我选择 MySQL v8.0,然后点击审核+创建->-创建

为了能够在本地机器上测试你的 Azure 功能。不要忘记将您的本地 IP 地址添加到连接安全设置中。具体来说,转到我们刚刚创建的 Azure MySQL。在左侧导航的Settings部分选择Connection security。然后在右主视图上点击+ Add client IP按钮。这将自动将您当前的 IP 地址添加到白名单中。然后,点击Save。

步骤 2:创建 Azure 函数
为了开发的简单性,我更喜欢用 VS 代码创建 Azure 函数。您需要为 VS 代码安装 Azure Functions 扩展。完成后,你应该可以在左侧看到额外的 Azure 按钮。单击按钮并按照说明登录到您的 Azure 帐户。
在 Mac 上按cmd+shit+p或在 Windows 上按ctrl+shift+p调用命令面板,然后选择Create New Project

在这个例子中,我将使用 python 作为开发语言。

然后,选择 HTTP 触发器,因为它更易于测试。

然后,完成说明的其余步骤。
第三步:为 Python 安装mysql-connector
在你的 VS 代码终端,使用pip安装 Python 的mysql-connector库。
$ pip install mysql-connector
此外,不要忘记将依赖项添加到requirements.txt,因为 Azure 函数依赖于这个文件来为你的应用安装 Python 依赖项。

步骤 4:编写 Python 代码来连接 MySQL 服务器
转到您刚刚创建的 MySQL 的 Azure 数据库。记下服务器名称和登录名。

代码只是连接到 MySQL 服务器并显示所有的数据库。
import logging
import azure.functions as funcimport mysql.connectordef main(req: func.HttpRequest) -> func.HttpResponse:
logging.info('Python HTTP trigger function processed a request.') # Connect to MySQL
cnx = mysql.connector.connect(
user="ctao@mysql80-test-chris",
password='<your_password>',
host="mysql80-test-chris.mysql.database.azure.com",
port=3306
)
logging.info(cnx) # Show databases
cursor = cnx.cursor()
cursor.execute("SHOW DATABASES")
result_list = cursor.fetchall()
# Build result response text
result_str_list = []
for row in result_list:
row_str = ', '.join([str(v) for v in row])
result_str_list.append(row_str)
result_str = '\n'.join(result_str_list) return func.HttpResponse(
result_str,
status_code=200
)
步骤 5:运行 Azure 函数(重现问题)
您可以部署 Azure 函数以在生产环境中测试它,或者在 VS 代码终端中运行以下命令以在本地测试它。
$ func start run
Azure 函数运行后,访问 URL 以尝试获取数据库列表。
如果在本地运行,URL 应该如下所示
不出所料,你的浏览器会报错 HTTP 错误 500。如果您返回到 VS 代码终端,您会在控制台中看到一些错误消息。这个问题的关键在图像中突出显示
异常:编程错误:9002 (28000):需要 SSL 连接。请指定 SSL 选项,然后重试。

步骤 6:添加证书文件并在 Python 中正确使用它
老实说,这个问题困扰了我一段时间,但我最终解决了它。
首先,获取证书文件并不困难。你可以从微软 Azure 官方文档网站下载,在这个页面。我会把下载链接直接贴在这里:
https://www . digicert . com/CACerts/baltimorecybertrustrust root . CRT . PEM
用 Python 引用也不难。通常,您可以使用任一相对路径:
crtpath = '../BaltimoreCyberTrustRoot.crt.pem'
或绝对路径:
crtpath = '/User/.../BaltimoreCyberTrustRoot.crt.pem'
然后,只需将path变量放入connect函数中:
# Connect to MySQL
cnx = mysql.connector.connect(
user="ctao@azure-mysql-test",
password='<your_password>',
host="azure-mysql-test.mysql.database.azure.com",
port=3306,
ssl_ca=crtpath
)
然而,在你部署 Azure 功能后不会工作。
这是因为 Azure Function 会自动将你的代码部署到实际后端服务器上/var下的某个地方,而你根本没有访问这个服务器的权限。
在这种情况下,我们必须让 Python 找到证书文件的正确位置,这肯定是可行的。我们可以用__file__。
让我们将证书文件放在项目的根路径中。因此,如果以后我们有更多的 Azure 功能,并希望重用这个证书文件,它可以确保我们可以以正确的方式引用它。

然后,编写一个函数来获取这个文件
import pathlibdef get_ssl_cert():
current_path = pathlib.Path(__file__).parent.parent
return str(current_path / 'BaltimoreCyberTrustRoot.crt.pem')
注意,第一个.parent将返回 Azure 函数的根路径,我们需要另一个.parent来确保它返回项目的根路径。这意味着,如果你喜欢把证书文件放在 Azure 函数的根路径中,你只需要一个.parent。
之后,按如下方式更改连接代码:
cnx = mysql.connector.connect(
user="ctao@mysql80-test-chris",
password='<your_password>',
host="mysql80-test-chris.mysql.database.azure.com",
port=3306,
ssl_ca=get_ssl_cert()
)
现在就来试试吧!
再次访问网址,你将能够看到数据库列表!

这将在您的本地机器上和部署您的 Azure 功能后都有效。
作为一个媒体会员,你的会员费的一部分会给你阅读的作家,你可以完全接触到每一个故事…
medium.com](https://medium.com/@qiuyujx/membership)
如果你觉得我的文章有帮助,请考虑加入 Medium 会员来支持我和数以千计的其他作者!(点击上面的链接)
如何通过使用 Python 获得更多的 Google 搜索控制台数据

谷歌搜索控制台(之前的谷歌网站管理员工具)是谷歌提供的一项网络服务,帮助你监控和维护你的网站在谷歌搜索结果中的显示。它也是一个很好的工具,可以用来分析从谷歌到你的网站的有机搜索。

Google Search Console UI (credit to unsplash)
谷歌搜索控制台是伟大的,但它的数据只有过去 1 年零 4 个月。如果你想查看历史数据超过时期,可惜你不能!😦
幸运的是,Google 为我们提供了一个搜索控制台 API 来访问 Google 搜索控制台中的数据。使用这个 API,您可以访问您站点上的数据,并将它们存储在您的首选数据库中,用于分析或其他目的。
使用搜索控制台 API
在开始编码之前,您应该准备好您的搜索控制台 API。我以前写过一篇文章,介绍如何通过客户端 ID 访问您的 Google 服务。您应该能够获得包含密钥的 JSON 文件来访问您的 Google 搜索控制台。
我们大多数人肯定会使用谷歌提供的至少一项服务。自从我成为一名互联网数据分析师后…
medium.com](https://medium.com/@chingjunetao/simple-way-to-access-to-google-service-api-a22f4251bb52)
访问搜索控制台 API
入门指南
在本教程中,我们将使用 google-auth-oauthlib(一个 google 认证库)来访问 API。
pip install google-auth-oauthlib
您需要将https://www.yourwebsite.com/更改为您自己的站点。对于OAUTH_SCOPE,Google 搜索控制台 API 只有 2 个 OAuth 作用域。
建筑连接
第一次,您需要使用基于此 web 身份验证流程的 web 浏览器登录。之后,它会将您的凭证保存在 pickle 文件中。以后每次运行该脚本时,它都会使用存储在config/credentials.pickle中的“腌制”凭证来建立与搜索控制台的连接。
提取数据
对于每个请求,数据数量有一个限制,即 25,000 行。如果数据超过 25,000 行,您必须将它们分成多个请求。
request = {
'startDate' : date,
'endDate' : date,
'dimensions' : ["query","page","country","device"], 'searchType': "Web",
'rowLimit' : maxRows,
'startRow' : i * maxRows
}
这是请求数据时必须发送的 JSON 格式的请求。在这种情况下,我想用查询的维度(搜索关键字)、页面、国家和设备提取我前面定义的日期的数据。搜索类型将是 Web only(也有图像和其他选项)。更多细节,可以参考文档。
获得数据后,您就可以开始工作了!你可以把它存放在任何地方。在我的例子中,出于分析目的,数据将存储在 BigQuery 中。
希望这篇文章能帮助你理解搜索控制台 API 以及如何使用它。
可以在我的 Github 中查看完整脚本。干杯!
如果你喜欢读这篇文章,你可能也会喜欢这些:
使用命令行参数创建自己的 Python 脚本的简单指南
towardsdatascience.com](/how-to-master-python-command-line-arguments-5d5ad4bcf985) [## 如何用 Python 设计你的数据框架
如何使用 Python 高亮显示、格式化或着色您的数据框
towardsdatascience.com](/how-to-style-your-dataframe-with-python-eabf376d1efd)
你可以在 Medium 上找到我其他作品的链接,关注我 这里 。感谢阅读!
对于分类任务来说,准确度是不够的
准确度、精确度和召回率之间的区别

Photo by Matthew Henry on Unsplash
在这个机器学习时代,我们已经看到了很多关于使用人工智能来分类图像是否包含小狗、进行垃圾邮件检测或训练自动驾驶汽车识别交通标志的宣传。正如拥有正确的模型很重要一样,更重要的是能够判断您的模型执行得如何,以便您可以选择最适合您的任务的模型。
在这篇文章中,我们将介绍:
- 分类任务的一般定义
- 准确性指标
- 精确度和召回率
- 混淆度量
- 精确-召回权衡
什么是分类?
假设你面前有一张上面的图片,任务是判断图片中是否包含一只狗。如果你回答正确,你得到一分。如果没有,你将什么也得不到。这就是通常所说的分类任务,您试图给给定的数据分配一个特定的标签。
这个分类任务在机器学习社区中非常流行,他们试图训练他们的模型,看看当前的算法是否可以完全区分对象。对于本文,我们不会关注使用哪种算法。相反,我们假设我们已经有了一个算法,我们想知道我们的算法执行得好不好?
准确(性)
一个简单的评估指标是准确性。假设你有 5 张图片,模型答对了 4 张,那么分数就是 0.8。因此,我们可以说准确度是全部图像中正确分类的图像的数量。这是简单而直观的,但这还不够。

Figure 1 — Images of dog and not-dog
准确性本身也有一些下降。让我们考虑下面的例子。假设我们的数据集有 5 张图片:4 张不是狗,1 张是狗。我们还有一个如下的算法:
def is_a_dog (x):
return False
上面的朴素算法假设所有东西都不是狗,而不对给定的数据做任何计算。需要注意的一点是,因为我们的数据集碰巧有 4 幅非狗的图像,所以这种简单算法的得分为 0.8。这不是我们想要的。

Figure 2 — Naive algorithm returns all False
精确度和召回率
应对这种情况的两个概念是精确和召回。下面我们来看看他们的简要说明。
- 精度:在所有“狗”的预测中,有多少是正确分类的?

- 回忆:在所有“狗”的数据中,有多少是正确分类的?


Figure 3 — Recall (looks only on data whose labels are dogs)
先说回忆。在我们的数据集中,只有一只狗,我们的算法将其归类为非狗。所以,回忆=0/1=0。
然而为了精确,在这些预测中,没有一个预测是狗。因此,精度=0/0。注意,在某些情况下,由于分母为 0,所以不可能进行精度除法;因此,在这种情况下,我们可以简单地假设 precision=0。
混淆矩阵
混淆矩阵将数据分为 4 类:真阳性、真阴性、假阳性和假阴性,如下图所示。

Figure 4 — Confusion Matrix
- 当数据具有标签“狗”并且预测具有相同的阳性标签时,为真阳性。
- 当数据的标签是“非狗”并且预测正确地具有相同的标签时,为真否定。
- 假阳性是当数据的标签是“非狗”但算法没有将其分类为“狗”时。
- 假阴性是当数据的标签是“狗”时,但算法说不是这样。
通常,当我们想要计算精确度和召回率时,使用混淆矩阵。计算方法与上一节描述的相同,但它使数字更容易阅读。对于这个例子,我们将看一个不同的例子,其中我们尝试对 10 幅图像进行分类。

Figure 5 — Example of 10 images. Label underneath the images are the prediction

Figure 6 — Confusion Matrix on 10 images
在这种情况下,精度是 4/(4+3)=0.57,而召回率是 4/(4+2)=0.66。
精确度或召回率
理想情况下,我们希望这两个值尽可能高。然而,这可能是不可能的。当我们提高召回率时,精确度会降低,反之亦然。因此,我们需要决定哪个对任务更重要。让我们仔细看看这种现象是如何发生的。

Figure 7 — PrecisionRecall Tradeoff
绿色框是正确分类的标签,黄色框是错误分类的标签。每个被错误分类的图像必须进入一个黄色的盒子:假阳性(精确)或假阴性(召回)。当然不可能两者兼而有之。
假设我们的模型肯定会有 5 个错误的标签,如果所有的错误分类都属于假阳性,那么我们将会有低精度和高召回率。然而,如果不正确的标签落入假阴性,我们反而会有高精度和低召回率。

Figure 8 — Examples of Precision-Recall Tradeoff
因此,当你训练你的机器学习模型时,你需要决定哪些指标更重要。例如,如果你被要求为金融机构建立一个模型,他们希望对借款人是否是一个好的候选人进行分类,你可能更喜欢你的模型不要鲁莽地提供贷款。因此,你宁愿把好人归类为坏人(假阴性),而不是把坏人归类为好人(假阳性)。
换句话说,假阴性(召回)比假阳性(精确)更好。
结论
所以,下一次当你面对一个分类任务时,确保不要只选择准确性作为度量,然后马上开始设计模型。当然,摆弄模型是令人兴奋的,但重要的是花一些时间来清楚地了解您正在处理什么样的问题,以及哪些指标最适合这项任务。一旦你解决了这个问题,你就可以确定你正在构建的模型是适合你的任务的。
关键外卖
就是这样。我们已经到了这篇文章的结尾。回顾一下我们刚刚讨论的内容,以下是这篇文章的一些要点:
- 对于分类任务来说,准确度是不够。我们需要看看其他一些指标,以确保我们的模型是可靠的。
- 精度:在所有说狗的预测中,有多少是正确分类的?
- 回想一下:在所有关于狗的数据中,有多少是正确分类的?
- 混淆矩阵有助于您更好地分析模型的性能。
参考
- https://en.wikipedia.org/wiki/Precision_and_recall
- https://machine learning mastery . com/classification-accuracy-is-not-whole-not-whole-performance-measures-you-can-use/
- https://medium . com/tech space-usict/measuring-just-accuracy-is-what-not-what-difficult-have-better-technique-is-required-e 7199 AC 36856
- https://towards data science . com/beyond-accuracy-precision-and-recall-3da 06 bea 9 f6c
数据科学中的准确性性能测量:混淆矩阵
简要介绍使用数据科学模型混淆矩阵评估绩效指标的各种方法

Photo by Eleonora Patricola on Unsplash
在之前的文章中,我已经简要解释了 k-NN 模型的复杂工作和陷阱,现在让我们先尝试简单地看看如何实现该模型并评估成人收入数据集,然后通过各种性能指标来分析准确性。
简单看一下 k-NN 算法,我们会发现该算法是一种分类算法,基本上是通过识别最近邻,然后将它们分类到不同的类中来执行的。它可用于二元或多类问题。

Photo by Alexander Mils on Unsplash
成人收入数据集
我们将尝试实现的模型是成人收入数据集。数据集可以在 Kaggle 或者我的 GitHub 仓库中找到。该数据集包含美国成年人的收入,是使用 k-NN 算法解决的最常见问题之一。在这里,收入最初是连续的,但通过使用 50,000 美元的过滤器,已经变成了二进制。收入高于 50,000 美元的给 1 分,收入低于 50,000 美元的给 0 分。该数据集还有 14 个其他预测因子。对数据集的最初几个简短观察显示了以下内容:

Result from head() on the dataset
从上面我们可以看到,数据集有重要的描述符,可以用来解释为什么一个人的收入会高于或低于 50,000 美元。我们还可以观察到收入水平的分布是相当偏斜的,即收入低于 50,000 美元的人比收入高于 50,000 美元的人多。

More incomes lesser than $50,000 than above it
在执行删除空值和缩放要素的必要数据操作后,我们得到最终的部分数据集:

Partial dataset after data cleaning has been performed
模型实现
既然已经清理了数据,我们可以在其上实现模型,然后继续通过各种度量来执行准确性。如前所述,k-NN 模型在不同的步骤中实现,这些步骤是:

Steps for conducting a k-NN analysis, source: Recent Trends in Big Data Using Hadoop
因此,让我们采用 scikit-learn 给出的默认邻居数量(k=5 ),并且让我们也采用基线条件,我们可以执行模型如下:

然后,我们可以使用各种可用的评估方法来评估模型的表现。
混淆矩阵
我们可用的最常见的度量类型是混淆矩阵,也称为置信矩阵。混淆矩阵是一个看起来像这样的矩阵:

Sample Confusion Matrix
从上面我们可以看到,混淆矩阵是实际值与预测值之间的矩阵。它通常用于分类目的,其中需要将目标预测为 1 或 0。当我们观察到实际值不存在时,我们给它 0,否则给 1。预测值也是如此。那么,这有什么重要的?
嗯,我们可以从这个矩阵中看出很多东西,比如:
我们的混淆矩阵看起来像:

Confusion Matrix for the Adult Income dataset
- 准确率:这是分类器正确的比率,所以基本上取真正值和真负值之和,然后除以总和。这意味着总共有 14,653 个值,其中有 10,109 个真正值和 2045 个真负值。因此,我们的模型的精度将是(10109 + 2045)/14653 = 82.94%。可以说我们的模型有很好的准确性。它也被称为命中率,因为它是总命中率与所有值的度量。
- 误分类率(MISC) :顾名思义,这是值被误分类的比率。它也被称为缺失率,因为它是缺失值的计数。所以,如果我们用 100%减去准确率,就会得到误分类率。我们这里的杂项价值是 0.17 或 17%。这意味着在我们的情况下,我们可以说当错误分类率为 17%时,在数据集中的 100 个人中,有 17 个人被错误分类。
- Precision :这是衡量正面预测准确性的值的比率。所以当我们用真阳性除以总阳性,我们得到精度值。因此我们这里的精度是(2045)/(2045 + 1013) = 66.87%。这意味着,在我们的例子中,我们可以说,当精度为 66.81%时,预测收入超过 50,000 美元的 100 人中,有 67 人被正确分类。
- 回忆:这是测量被分类器正确识别的正面实例的值的比率。它也被称为敏感性,或真正的阳性率。因此,召回率是(真阳性)/(真阳性+假阴性),或者在我们的例子中是 2045/(2045 + 1486) = 57.91%。这意味着,在我们的例子中,我们可以说,当召回率为 57.91%时,在 100 个收入超过 50,000 美元的人中,有 57.91 人或 58 人被正确分类。
- 特异性:这是测量被分类器正确识别的阴性实例的值的比率。它也被称为真实负利率。特异性则是,(真阴性)/(真阴性+假阳性)或在我们的情况下,10109/(10109 + 1013)或 90.89%。这意味着在我们的案例中,我们可以以 90.89%的特异性说,在 100 个收入不超过 50,000 美元的人中,90.89 或 91 人被正确分类。
- F-1 分数:它是精确度和召回率的调和平均值。正常平均值对所有值给予同等的优先权,而 F-1 分数对低值给予更大的权重。F-1 的分数基本上是这样的:

F-1 Score
在我们的例子中,F-1 分数为:

Precision, Recall and F1- Score values for 1 and 0 respectively
- 受试者工作特征和曲线下面积:受试者工作特征曲线,也称为 ROC 曲线,基本上是真阳性率对假阳性率的曲线图。假阳性率是被错误分类的阴性实例的比率。也可以定义为 1-真阴性率,这也是特异性。因此,该曲线也可以被认为是灵敏度和 1-特异性之间的曲线。在 Python 中,可以使用 scikit-learn 或 matplotlib 库来实现。曲线下的面积也是这里的另一个重要指标。它越接近 1,分类执行得越好。我们案例的曲线如下所示:

Code to draw the ROC Curve, Source: Hands-on ML by Aurelien Geron

ROC Curve and the AUC at bottom
- 累积精度曲线:该曲线类似于 ROC 曲线,但它是一个精度图。它基本上描绘了准确性,并有助于理解和总结模型的稳健性。
制作曲线的代码:

Code for drawing the CAP Curve

CAP Curve
如上所述,重要的是要注意,您可以使用大量其他信息来确保您的模型具有所需的准确性和性能。这些包括变异系数、均方根误差等,但本文仅针对混淆矩阵。
用一杯水解释准确度、精确度和召回指标

准确率、精度和召回率是衡量机器学习分类案例中模型性能的三个基本分数。准确性是一个相当容易理解的概念:取所有正确的预测的总和,然后除以预测总数,正确的和错误的。自然,如果没有错误的预测,正确的预测除以正确的预测会得到 1。完美的准确性!
如果数据不平衡,就会出现问题,这是分类问题的常见情况。假设你有一个关于信用卡交易的数据库,其中 95%的交易是好的,5%是欺诈性的。你设计了一个模型,它能正确预测所有 95%的合法交易,但没有一个是坏交易。根据该公式,该模型将具有 95%的准确性水平,这是一个非常不错的结果。不幸的是,这并不能证明你的模型足够好,因为它没有发现任何欺诈行为。在那些数据明显不平衡的分类情况下,准确度分数可能会产生误导。
这就是精确度和回忆分数介入的地方。精确度和召回率公式如下:


虽然公式中的变量应该不会引起任何问题,但在开始时,精确度和召回背后的思想可能更难理解。为每个类分别测量精度和召回率也没有帮助。但是让我用下面的比喻来解释给你听。

想象你有一杯水。 Precision 将显示水中有多少污垢,即有多少不应该存在的物质。就这么简单——精确度是关于玻璃杯中水的纯度以及有多少外来物质。水越清澈,精确度分数就越高。如果你的模型声称某样东西是水,但它不是,这将降低精度分数。

回忆是完全不同的故事。这不是纯度的问题,而是数量的问题。想象你要了一杯水。他们已经把它带给你,但是它不是满的。问题是杯子里应该有多少水,但实际上没有,也就是说,有多少水溢出来了——这就是召回的衡量标准。回忆越高,水在流向你的途中流失越少。如果 recall 等于 1,这意味着玻璃杯是满的——您的模型已经正确预测了某个特定类的所有记录,没有遗漏任何东西,没有遗漏任何东西。
总结一下:
Precision 测量你的模型将多少灰尘带入一杯水中。回忆测量你的模型洒了多少水。就这么简单!
准确度、召回率、精确度、F 值和特异性,哪一个需要优化?
根据您的项目,哪个绩效指标需要改进?

我将使用一个基本示例来解释上的每个性能指标,以便让您真正理解它们之间的差异。以便在您下一个 ML 项目中,您可以选择最适合您的项目的性能度量标准。
我们开始吧
一所学校正在对所有学生进行机器学习初级糖尿病扫描。
输出要么是糖尿病患者 (+ve),要么是健康者 (-ve)。
任何学生 X 最终可能只有 4 种情况。我们稍后将使用以下内容作为参考,所以如果你感到困惑,请不要犹豫重读一遍。
- 真阳性( TP ):预测为+ve,X 为糖尿病,我们想要那个
- 真阴性( TN ):预测是-ve,X 是健康的,我们也希望如此
- 假阳性( FP ):预测为+ve,X 健康,虚警,不良
- 假阴性( FN ):预测为-ve,X 为糖尿病,最差
要记住这一点,有两个窍门
-如果以 真开始,那么无论是否患有糖尿病,预测都是正确的,所以真阳性是正确预测的糖尿病人&真阴性是正确预测的健康人。
相反,如果以假开始,则预测是不正确的,因此假阳性是健康人被错误地预测为糖尿病(+) &假阴性是糖尿病人被错误地预测为健康(-)。
- 正或负表示我们程序的输出。而真或假则判断该输出是否正确。
在我继续之前,真正的积极&真正的消极总是好的。我们喜欢真实这个词带来的新闻。留下了假阳性和假阴性。在我们的例子中,误报只是一个错误的警报。在第二次更详细的扫描中,它将被纠正。但是一个错误的负面标签,这意味着他们认为他们是健康的,而实际上他们并不健康,在我们的问题中,这是 4 种情况中最糟糕的一种。
是 FP & FN 一样差还是其中一个比另一个更差取决于你的问题。这条信息对您选择性能指标有很大的影响,所以在您继续之前请考虑一下。
选择哪种性能指标?
准确(性)
它是正确标记的主题与整个主题库的比率。
准确是最直观的一个。
准确性回答以下问题:我们在所有学生中正确标记了多少学生?
准确度=(TP+TN)/(TP+FP+FN+TN) 分子:所有正确标注的被试(全部为真)
分母:所有被试
精确
精度是我们的程序正确标记的+ve 与所有标记的+ve 之比。Precision 回答了以下问题:那些被我们贴上糖尿病标签的人中有多少人实际上是糖尿病患者?
精度= TP/(TP+FP) 分子:+ve 标注糖尿病人。
分母:所有被我们的计划标记为+ve 的人(无论他们实际上是否患有糖尿病)。
回忆(又名敏感度)
召回率是我们的程序正确标记的+ve 与现实中所有糖尿病患者的比率。回忆回答了以下问题:在所有的糖尿病患者中,我们能正确预测的有多少?
回忆= TP/(TP+FN) 分子:+ve 标注糖尿病人。
分母:所有糖尿病患者(无论是否被我们的计划检测到)
F1 分数(又名 F 分数/ F 度量)
F1 评分同时考虑了准确率和召回率。
它是精度和召回率的调和平均值。 如果在系统中的精度(p) &召回(r)之间存在某种平衡,F1 得分最好。相反,如果一个指标的提高是以牺牲另一个为代价的,那么 F1 值就不会那么高。
比如如果 P 为 1 & R 为 0,F1 得分为 0。
【F1 得分= 2(回忆精度)/(回忆+精度)**
特征
特异性是程序给现实中所有健康的人贴上的正确标签。特异性回答了以下问题:在所有健康的人中,我们正确预测了多少?
特异性= TN/(TN+FP) 分子:-ve 标记健康人。
分母:现实中所有健康的人(无论是+ve 还是-ve 标注的)
一般注意事项
是的,准确性是一个很好的衡量标准,但只有当您拥有对称数据集时(假阴性&假阳性计数接近),而且,假阴性&假阳性的成本也差不多。如果误报和漏报的代价不同,那么 F1 就是你的救星。如果你的职业分布不均匀,F1 是最好的选择。****
精确是你有多确定你真正的阳性,而回忆是你有多确定你没有遗漏任何阳性。
****如果假阳性的想法远远好于假阴性,选择召回,换句话说,如果假阴性的出现是不可接受的/不可容忍的,那你宁愿得到一些额外的假阳性(假警报)也不愿保存一些假阴性,就像我们的糖尿病例子一样。
你宁愿让一些健康的人被贴上糖尿病的标签,也不愿让一个糖尿病人被贴上健康的标签。
****如果你想对自己的真实想法更有信心,请选择 precision。比如垃圾邮件。你宁愿在你的收件箱里有一些垃圾邮件,而不是一些普通的邮件。因此,电子邮件公司想要额外确定电子邮件 Y 是垃圾邮件,然后才把它放入垃圾邮件箱,这样你就再也看不到它了。
****如果您想要覆盖所有真阴性,选择特异性,这意味着您不想要任何假警报,您不想要任何假阳性。例如,你正在进行一项毒品测试,所有测试呈阳性的人将立即入狱,你不希望任何没有吸毒的人入狱。这里的假阳性是不能容忍的。
底线是
—准确度值为 90%意味着每 10 个标签中有 1 个不正确,9 个正确。
—精度值为 80%意味着平均而言,我们计划标记的每 10 名糖尿病学生中有 2 名是健康的,8 名是糖尿病患者。
—召回值为 70%意味着现实中每 10 名糖尿病患者中有 3 人被我们的计划遗漏,7 人被标记为糖尿病患者。
—特异性值为 60%意味着现实中每 10 个健康人中有 4 个被误标记为糖尿病,6 个被正确标记为健康。
混淆矩阵
维基百科会比我解释的更好
在机器学习领域,特别是统计分类问题中,混淆矩阵,也称为误差矩阵,是一种特定的表格布局,它允许算法性能的可视化,通常是监督学习算法(在非监督学习中,它通常被称为匹配矩阵)。矩阵的每一行代表预测类中的实例,而每一列代表实际类中的实例(反之亦然)。该名称源于这样一个事实,即它可以很容易地看出系统是否混淆了两个类(即通常将一个类误标为另一个类)。
from **sklearn.metrics** import confusion_matrix>>>tn, fp, fn, tp = confusion_matrix([0, 1, 0, 1],
[1, 1, 1, 0]).ravel()
# true negatives, false positives, false negatives, true positives
>>>(tn, fp, fn, tp)
(0, 2, 1, 1)
基于服务的组织中的 Ace 深度学习

From: https://newsroom.cisco.com/feature-content?type=webcontent&articleId=1895218
让我们以一句激励人心的名言开始:
从现在到 2030 年,it(深度学习)将创造约 13 万亿美元的 GDP 增长。—吴恩达
当前情景
每个科技巨头;无论是 Alphabet、脸书、微软;将数据科学视为统治市场的关键。
像“你要么为谷歌工作,要么与之竞争”这样的笑话,现在听起来就像噩梦。
随着科技巨头们开源他们频繁更新的研究。因此,几乎所有其他初创公司都能够在此基础上创建自己的深度学习解决方案。
这些创业公司由于烧钱率低,能够以低得多的费率提供深度学习解决方案。
注意:从今以后,我将交替使用深度学习和数据科学。
以下是我对基于服务的组织(SBO)如何在这种环境中竞争和取胜的两点看法
MVP 超过 POC
大多数服务型公司都对“产品”这个词感到恐惧。因此,基于服务的公司开发了 POC。
让我们先了解什么是什么:
产品是制造或提炼用于销售的物品或物质。
概念验证(POC) 是最终产品的缩影,具有一些工作特征,旨在验证某些概念是否具有实用潜力。
最小可行产品(MVP) 是一种开发技术,在这种技术中,新产品或网站的开发具有足够的特性来满足早期采用者。
不是一家基于产品的公司并不是以概念验证的名义创建半成品解决方案的借口。
记住 的底线永远是创造人们想要的 。POC 关注一些工作特性,而 MVP 强调这样一个事实,即 一些工作特性是无用的,除非它们令客户 满意。
通常,主要在深度学习中,解决方案的工作在其最终结果周围有这种不确定性。这使得客户对投资建议的解决方案感到紧张。
你会反复遇到一些客户,他们在接触你的公司之前已经有过一些不好的经历。坦率地说,向他们展示他们难以理解的东西,尤其是当他们已经感到沮丧的时候,是愚蠢的。
受控演示或命令行演示;不会让客户对工作更满意。
客户需要一个直观的交互式界面;他可以玩的东西;满足他的好奇心,从而克服不情愿。
数据高效系统
客户需求大多过于特定于一个利基领域。因此,无法获得大量高质量的数据集。
基于客户的公司通常在同一个客户下做多个项目。他们的资源更多地分布在不同的任务甚至专业技能上。
还有,
依赖客户获取数据,尤其是 POC/POV/MVP,是注定要失败的。
为了避免这一点,公司最初在一个相当大但不相关(与客户的实际要求无关)的数据集上展示演示,结果非常好。这是一个灾难性的前兆,导致承诺过多但落实不足。
由于“小”高质量数据集很容易找到,甚至很容易构建,因此能够在小数据集上产生令人满意结果的数据高效系统更有意义。
确切的客户要求
将资源分散分配给多个客户使得基于服务的公司能够深入了解单个客户的需求。
这使得基于服务的公司可以根据客户的确切需求定制(修改,而不是构建)解决方案。
注意:这并没有减少项目的范围,只是扩大了范围以包括客户的额外要求。
这使得基于服务的公司可以在需要时脱离学术界的 SOTA(最先进的)意识形态 (iff 和)并简单地定制(同样,不是构建)一个为特定客户或特定类型的客户工作的系统。
领域专业知识
基于服务的公司通常雇佣领域专家,他们为不同的客户从事相同领域的不同项目。
他们独特而扎实的专业知识导致了 以最小的风险保证质量的可交付性 。这种保证是大客户最看重的,尤其是银行和贸易公司。
现成的解决方案
在数据科学中,开发解决方案已经成为一种标准做法,这种解决方案需要在使用系统之前在客户端进行手动培训。
这是一种简单但无效的方式来规避开发数据高效的解决方案,因为:
数据科学项目通常是客户端非技术团队(财务团队或业务团队)的必需品。
对于这些非技术团队的人员来说,这种解决方案的培训通常过于繁琐。
因此,客户通常会分配一组“技术人员”来培训这些解决方案。
因此,即使在客户看到系统的一瞥之前,他也必须等待:
- 对其技术人员进行用例教育
- 对其技术人员进行技术教育
- 其技术人员对系统的培训
另一方面, 开箱解决方案 是可以直接使用 的系统,无需任何前期培训 。
因此,客户不费吹灰之力就有了实质性的东西。
这为客户提供了对服务型公司能力的早期保证和信心。
灵活的架构
尽管解决方案应该根据客户的要求量身定制,但这并不意味着 开发“使用并丢弃”的解决方案 。
避免开发范围过窄而无法满足未来需求的解决方案。
开发一个几乎不能修改的不可变的黑盒解决方案,通常会导致与客户的冲突和混乱的修补工作。
进入微服务架构。
微服务是一种架构风格,它定义了一个项目,一组服务,它们是:
- 高度可维护和可测试
- 松散耦合
- 可独立部署
这种架构确保 客户端可以根据其满意度 ,通过应用不同的排列、省略或添加服务来改变解决方案的工作。
中央集权的 R&D
以服务为基础的公司通常害怕为 非客户特定的 R & D 分配“充足的”单独资金。
通常,在开发特定于客户端的深度学习解决方案时,R&D 的范围仅限于客户端的“当前”需求,而不是该客户端的领域。
来自同一个领域(NLP、计算机视觉等)的深度学习项目可能在管道、学习者、预处理步骤等方面有大量重叠。
在没有一个集中的团队的情况下,将会有很多多余的努力。
集中式团队的存在是确保特定于客户的团队有一个现有的解决方案来改进,而不是每次都构建一个新的解决方案的关键。
教育合作
当面对独特的非传统客户需求或保持有效的 R &D;体验时,扮演着至关重要的角色。
比方说,你想设计一个在 20 个例子中运行良好的槽标记器。
可行的架构之一是:
基于散射小波和傅里叶变换的注意力增强双向门控卷积网络
这个架构,在任何教程和博客上都找不到。
这种架构并不是一个显而易见的选择,直到你研究了信息论、信号处理和深度学习相当一段时间。通常不可行的时间量。
教授们有几十年的经验,凭借这些经验,他们获得了某一特定领域的大量知识。他们发现和解决/规避问题的能力是无与伦比的。
标杆管理
每个人都对将黑盒解决方案推向生产持怀疑态度。
没有人能够预测一个神经网络的行为,特别是在不同的场景下。
广泛的基准测试确保从开发人员到客户的每个人都知道不同场景下给定解决方案的功能,以及这些功能的限制。
耐心
深度学习最简单的形式是一些随机数收敛到某个配置,在那里它们开始学习输入和输出之间的关系。
与传统软件解决方案不同,一个人最多可以 预感到什么可能有效,什么可能无效 。
因此,创建健壮的解决方案可能比开始时预期的要花费更多的时间和精力。
绝对不应该宣布或期待一个严格的时间表。
利益相关者应该在他们的战线上保持一个缓冲区,以包含延迟。
特别感谢 Deepak Saini & Mayank Saini。
干杯!
赢得数据分析面试
有志成为数据专业人士的指南
我在谷歌、Visa 等公司担任数据分析师/科学家的面试经历

Source (unsplash)
面试——我在谷歌的故事
我于 2019 年 5 月 23 日上午 10 点来到谷歌办公室,我记得我惊讶于这里的办公室有多么大和酷。在每一个角落,都有一个微型厨房和有趣的娱乐主题,这些主题在视频博客上出现过很多次。我一直等到面试官上来。他介绍自己是招聘经理,我们找到了一个房间,里面有一个有趣的形状奇怪的白板和高高的木头桌子。
面试进行得非常顺利——就像和一个朋友的对话,对自己和面试官有了更多的了解。虽然有一些棘手的技术和编码问题,但这个过程很有趣,值得庆幸的是,充满了微笑。
一旦我通过了技术和招聘经理的面试,我就被安排去面试大人物:高级主管和全球主管。我尽可能地微笑着,自信地阐述我对多个行为和假设问题的想法。
几个月后,我收到了邀请,并在第二周接受了邀请。我很高兴终于可以称自己为谷歌的数据分析师(机器学习)。
这就是我在最近一次求职面试中经历的过程,同样,其他大数据公司也是如此。
目的:我给有抱负的数据分析师/科学家的建议
在这篇博客中,我将告诉你如何在大公司的数据分析师/科学家面试中胜出,如谷歌、Gojek、Visa、银行等。我创建这个博客是为了回答我的下级反复提出的关于如何在大公司艰难的数据面试中胜出的问题。
作为免责声明,由于博客政策的原因,我不会揭露具体公司的具体问题。但是我会尽我所能,这样你仍然可以从我的经历中学习。如果你想更具体地了解谷歌如何招聘,有一本由拉兹洛·博克写的好书。
在大多数面试中,你会遇到三种类型的面试问题:技术型、行为型和假设型。
技术问题
Technical interview went wrong 😃
这通常是第一轮或第二轮,以确保你能在面试招聘经理和他们的主管之前满足技术专长的基本要求
结构化查询语言
您将看到由日期、字符串和数字组成的表格。在此基础上,您需要使用 SQL 语言找到年的总数,或某些类别(如年龄范围或地点等)。
为了解决这些问题,我建议你:
- 问一些假设:某个数据点对于同一个值是否可以有不同的表示。例如,区分大小写不同的“Street”和“St”。这将有助于您在 SQL 中执行过滤,例如 like 或 exact words。
- 考虑极限情况:数值数据是否已经是纯数值格式,没有任何歧义或缺少值,比如-1 表示缺少的数字。'
- 大声思考:从用图表表示你的答案开始,在白板上写下你的解决方案,然后大声思考,以确保你的思路清晰地展示出来。一旦你得到面试官的确认,用你喜欢的语言写出解决方案。在这种情况下,我总是鼓励使用 python,因为作为一种脚本语言,它的语法要短得多,并且留给 bug 的空间也更少(比如 Java 中缺少分号)
最有可能的是,您还会收到一些关于连接表的问题(内连接、外连接),了解聚合及其过滤器( group by 和 having )。请参考下图。

SQL Joins and their respective codes (source)
此时,如果你忘记了语法,请对面试官诚实。写下你知道的一切,然后继续前进。很有可能你的面试官会知道,尽管你对 SQL 连接有透彻的理解,但你总是可以谷歌一下语法。如果你犯了错误,不要让他们阻止你。忘记它,微笑,继续前进。
编码问题
你的面试官会接着问一些编码问题。这可以是任何事情,比如你如何排序一个二维数组,甚至你如何在字符串中搜索特定的模式,或者甚至使用 Pandas 和 Python 聚合数据。
同样,要回答这个问题,我们需要从以下几点开始:
- 给出假设,找到你的测试用例:这是你自己安排测试用例的机会。如果列表有重复或未排序的数据,它会返回什么?如果列表是空的,它会返回什么?如果用户传递空值,会发生什么呢?
- 给出多个答案:大多数时候,你应该能想到蛮力方法,你会逐个迭代列表元素。或者,您可以设计一个更有效的排序算法(合并排序等)和迭代。
- 编码前确认您的答案:确保向面试官确认您的答案,只有在获得批准后才开始编码。征求他们的反馈,修正你的算法。此外,要注意可能出现越界问题的栅栏和柱子问题。最后,用你的测试用例测试你的代码。
参考
总的来说,我发现 CS Dojo 和 Devpost 有助于在技术面试中胜出。请检查一下。
行为问题
Behavioral Questions to know more about your experiences
面试官想知道你最大的成就以及你是如何解决问题和冲突的。
问题 1
你以前做过哪些数据项目?
这是你大放异彩的机会。作为一名有抱负的数据分析师/科学家,你们大多数人都应该有一些投资组合可以夸耀。如果您有 Github 项目,部署并展示您构建的一些应用程序。如果你像我一样在媒体上写博客,展示你最受欢迎的项目,展示你的高访问量。无论你有什么项目,集中精力给出展示你的技能和自信的指标。
让我给你举个例子
“在 Visa,我曾为客户(收购方和发行方)提取客户关键报告。这些是作为授权流程的一部分进行管理的关键信息,Visa 必须确保安全的交易渠道。因此,用户现在可以通过自己的门户生成报告,节省了 43%的时间。我还提到了我在 Lazada 的项目,该项目使用聚类和功能工程来发现重要的销售人员功能,然后将它们与我如何为该角色做出贡献联系起来。”
确保你能突出你的项目,并说明它与你申请的工作有什么关系。
假设性问题
Hypothetical questions summarized
面试官会用这些问题来了解你对你申请的职位的反应或想法。你的目标是以结构化和理性的方式引导面试官完成你的关键行动。
问题 1
如果我们在<产品>上发现一些漏洞,但产品经理或更高级别的领导否认。你会有什么反应?
这是一个棘手的问题,但公司希望看到你如何处理棘手的情况,并能够执行“正确的路径”,而不是“简单的路径”。
这些是你应该问的几个问题:
- 为什么 PM 拒绝我们的调查结果,有什么特别的原因吗?
- 我们团队和产品经理有哪些共同利益?其中的共同利益可能是用户体验或安全性。
一旦你知道了问题所在,你就可以通过使用数据驱动的决策来论证你的发现。
- 首先,你需要找出影响的规模,并用它创建一些可视化。例如,您可以进一步用条形图或地理位置图来显示漏洞的位置以及受影响的用户数量。
- 第二,你可以从客户支持中找到定性的反馈。你需要和客户经理谈谈,看看有哪些常见的用户痛点。然后,您可以将此与主要关注点联系起来,即用户体验。
- 最后,向产品经理推荐重点行动。这必须是在产品经理的权限范围内能够相对快速完成的事情。例如,产品经理应该使用增强的 API 来检测和解决漏洞。
通过用问题和有条理的回答突出你的想法,你会给面试官留下深刻印象。
问题 2
你会如何为
设计机器学习模型?
在这种情况下,您需要测试自己对某项任务建模的理解。通常,在这种情况下,您可以:
- 从探索性数据分析(EDA)开始:你可以建议先将某个问题可视化。比方说,如果在午餐时间产品流量增加,你会想制定一个假设来解释为什么会发生这种情况,并测试它们。
- 用解释性的&简单模型寻找信号:在数据管道的早期阶段,获得洞察力比获得准确性更重要。这意味着您应该使用更简单的模型从观察中得出一些见解,并了解哪些特性最能驱动因变量/指标。我建议对分类模型使用决策树和逻辑回归,对回归模型使用简单线性回归。这些模型让你可以将信息增益和重要系数可视化,以启动你的洞察力。
- 强调具体的模型学习:一旦你通过 EDA 和简单模型强调了可能的见解,那么你就可以建议一种更专业的技术。在文本分析问题中,我建议你使用主题建模 LDA(潜在狄利克雷分配)来寻找主题聚类。对于需要高精度分类的问题,您可以考虑集合模型,例如 Random Forest 和 XGBoost。一个警告是要确保你深刻理解其中的一些模型。
- 坦诚继续:如果你对某个话题不熟悉,就坦诚说“我不知道”就好。数据科学是一个快速发展的学科,不可能有人指望你 100%精通。因此,承认自己的缺点,继续前进。
赢得面试的最后提示
准备,准备,准备
我能玩得开心的一个主要原因是我做了准备。我经历了许多不同的准备问题,并不断打扰我的朋友和女朋友来听我的推销。他们给了我很多反馈,我可以很高兴地反映给招聘经理。同样的,你也要尽可能的花时间去准备。
面试是一个双向对话,带有一点销售技巧
到最后,你的面试官是你的朋友。放轻松,直言不讳。多听,好好玩。我很开心,因为我可以分享我的主要职业经历。从我与招聘经理的交谈中,我了解到的角色比他们从你那里学到的更多,这是一种非常令人满意的感觉。
希望、祈祷和享受
面试结束后,花 5 分钟思考一下这个过程。记下哪些进展顺利,哪些出了问题。如果你像我一样是一个信徒,为这些有价值的经历祈祷和感谢。无论接下来发生什么,你都能够将你的抱负和技能带入下一个层次。到目前为止,我已经被谷歌拒绝了 3 次,只有在上帝的恩典下,我才最终被接受。我很开心,也很感激。
总的来说,我真诚地希望我的这次经历能帮助你在数据分析工作面试中胜出。一切顺利,愿上帝保佑你。
最后…

Source: Unsplash.
我真的希望这是一本很棒的读物,是你发展和创新的灵感来源。
请在下面评论以获得建议和反馈。就像你一样,我也在学习如何成为一名更好的数据科学家和工程师。请帮助我改进,以便我可以在后续的文章发布中更好地帮助您。
谢谢大家,编码快乐:)
关于作者
Vincent Tatan 是一名数据和技术爱好者,拥有在 Google LLC、Visa Inc .和 Lazada 实施微服务架构、商业智能和分析管道项目的相关工作经验。
Vincent 是土生土长的印度尼西亚人,在解决问题方面成绩斐然,擅长全栈开发、数据分析和战略规划。
他一直积极咨询 SMU BI & Analytics Club,指导来自不同背景的有抱负的数据科学家和工程师,并为企业开发他们的产品开放他的专业知识。
文森特还在 best top 上开设了他的一对一导师服务,指导你如何在谷歌、Visa 或其他大型科技公司获得你梦想中的数据分析师/工程师职位。 如果你正在寻找良师益友,请在这里预约他 。
最后,请通过 LinkedIn ,Medium或 Youtube 频道 联系文森特
在 10 天内获得您的首个 AWS 认证
帮助您准备 AWS 认证云从业者考试的学习计划

Photo by Felipe Furtado on Unsplash
我和你们大多数人一样,使用开源数据科学工具,编写机器学习代码。但我很少想过如何将它付诸实施。启动集群、数据库和设计容错数据管道令人生畏。随着时间的推移,我意识到这些事情并不像我想象的那么难。当我在 7 月份通过 AWS 认证云从业者(AWS CCP)考试时,我了解到云服务提供商如何使数据管道比以往任何时候都更容易。
我想分享一下我是如何在 两周 准备并通过这个考试的,没有显著的云经验。
AWS CCP 是最受欢迎的,也是所有 AWS 认证考试中最简单的。有几个在线资源和学习指南。我已经列出了我认为最有用的。如果你只遵循这个考试指南,我保证你会通过考试。
这个考试是关于什么的?
官方考试指南说-
AWS 认证云从业者考试面向具备有效展示对 AWS 云的整体理解所必需的知识和技能的个人,独立于特定的技术角色

Photo by Chris Liverani on Unsplash
对于任何想要利用甚至了解托管云服务的人来说,该认证是一个很好的开端。如果您不确定哪个云平台最适合您的使用案例,我强烈建议您参加这个考试,因为所有云提供商都有非常相似的基础架构,而 AWS 是使用最广泛的云服务。
我在 2019 年 7 月参加了 AWS 认证云从业者考试,大概准备了十天,3–4 天做计划。由于网上资源和备考指南太多,很容易让人不知所措。所以,我把最好的指导方针、博客文章和技术资源都列在这里,帮助你制定一个坚实的学习计划。
研究计划的结构
作为第一步,我探索了许多可用的资源。我把这里最有用的资源列成了三个部分-
- 第 1 部分:了解考试模式和目标
- 第二部分:如何准备
- 第 3 部分:练习题和样题的链接
如果你完成了所有这些,你将会为 AWS CCP 考试做好更多的准备。如果你准确地掌握了你应该知道的东西,你将能够区分在这个阶段什么是相关的,什么是不相关的。
学习计划

Photo by Alvaro Reyes on Unsplash
按顺序浏览一遍。从理解考试、考试目标和一些样题开始(第 1 部分)。之后,开始准备(第二部分),最后测试你的知识(第三部分)。
第一节。了解考试模式和目标
以下是理解考试模式和考试目标的最佳资源。这些将有助于你区分哪些是你应该知道的,哪些是考试范围之外的。
2.Jeanne Boyarsky 对备考的建议,考试当天的预期,有助于对考试有一个更清晰的了解。Jeanne 是一名出色的开发人员,也是 Java 的拥护者。
3.在这个由 Steep Technologies 制作的视频中,Jose 分享了他的备考经历
https://www.youtube.com/watch?v=DkE4lKNC7uw
到这个时候,你应该对考试是什么样的有一个很好的想法,你需要知道什么才能在文本中做得好。
第二节。如何准备
1.如何通过 AWS 云从业者考试—学什么 Peter Fessel
https://www.youtube.com/watch?v=KFhXKlX6p-o
在这段 34 分钟的视频中,Peter 涵盖了测试中的所有主题。我建议列出所有这些话题。
2.云大师的 AWS CCP 课程
https://acloud.guru/learn/aws-certified-cloud-practitioner
注册一个免费的 AWS 帐户,设置警报,部署一个 S3 桶,并启动一个 EC2 实例。如果你以前从未这样做过,观察别人这样做并跟着做是很有用的。这门课程内容详尽。有时候 Ryan 会潜得比需要的更深。如果你现在对考试范围之外的内容不感兴趣,2.1 中的列表将有助于确定本课程中哪些主题现在不重要。
3.白皮书
我强烈推荐这四份官方 AWS 白皮书。我把它们按重要性排列,从最重要的开始。
3.1.概述白皮书
https://d1.awsstatic.com/whitepapers/aws-overview.pdf
只阅读相关的产品和服务。
3.2.最佳实践白皮书https://D1 . AWS static . com/whites/AWS _ Cloud _ Best _ Practices . pdf
在我第一次阅读时,我很难理解一些事情。我不得不重读一遍,然后读重点。这个练习是有益的。
3.3.定价白皮书https://D1 . AWS static . com/whites/AWS _ pricing _ overview . pdf
即使您只阅读了简介和决定某些关键服务计费的因素,您也会充分利用这份白皮书。
3.4.架构良好的框架白皮书https://D1 . AWS static . com/white papers/architecture/AWS _ Well-Architected _ framework . pdf
我浏览了一下,只看了标题,很少看细节。
4.熟知共担责任模式;在这个问题上,我有大约十个问题。
https://AWS . Amazon . com/compliance/shared-responsible-model/
5.定价模式。
https://aws.amazon.com/premiumsupport/plans/
记住这次感冒。考试中会有一些直截了当的问题,会考验你的记忆力。
第三节。练习测试和样题的链接
我只考了前四门,因为我看了一些网上的评论,说测试 5 和 6 有很多问题超出了考试范围。
2.我还买了 AWS 的官方模拟测试,20 美元给你 25 道题。这些至少比实际测试简单十倍。
这就是计划。我相信这会节省你很多时间去寻找最适合考试的东西。考试本身并没有设计的很难,所以这个准备会让你做好最坏的打算。但是,请确保您根据第 3 节来判断您的准备情况。
何去何从?

Photo by Daniel Gonzalez on Unsplash
如果你认为你已经为考试做好了充分的准备,按照你在第三部分的评估,继续安排考试。如果你遵循这个学习计划的大部分,你应该能取得好成绩。
祝贺您迈出了云计算生涯的第一步!从这里你可以走很多条路。您现在可以了解其他云服务提供商,比较哪一个最适合您的需求。由于我来自机器学习背景,我对构建端到端的机器学习服务感兴趣。所以,在准备 AWS 解决方案架构师认证之前,我在准备 AWS 机器学习专业。微软 Azure 正在快速追赶 AWS,值得学习和探索。它也有一些优秀的认证。
在这次考试之后,你还将能够理解复杂的 AWS 架构,并了解人们如何为他们的用例构建定制的解决方案。您还可以尝试部署一些服务,比如使用 Amazon EMR 的 Hadoop 集群,使用按需 Lambda 函数触发代码作为对事件的响应,或者使用 Amazon Polly 的酷炫文本到语音转换功能。
在与 AutoML 的 ML 竞争中取得前 5%的位置
模拟地震破坏
AutoML 管道是一个热门话题。总体目标很简单:依靠最先进的机器学习模型、超调技术和大量计算,让每个人都能训练出符合其业务需求的高质量模型。
在这篇博文中,我将把微软的 AutoML pipeline 应用到一场公开的 ML 竞赛中,通过剖析结果,我希望了解 AutoML pipeline 在哪些方面增加了重要价值,以及它们仍可以改进的地方。通过较小的编码工作和 AutoML 管道,我能够以离 F1 最高分仅 0.004 分的成绩获得第五名!你可以找到我在 GitHub 上用过的笔记本。
里希特预测器:模拟地震破坏
我选择的比赛在 DrivenData.org 举行。这是一个中级实践比赛,目标是预测 2015 年尼泊尔廓尔喀地震对建筑物造成的破坏程度。

Image from the DrivenData competition.
数据是干净的,没有任何缺失值,主要由关于建筑物结构及其合法所有权的信息组成(分类和数字特征)。在这场比赛中,我们试图预测顺序变量damage_grade,它代表了被地震击中的建筑物的损坏程度。损坏有三个等级。
训练和测试数据集分别由 260602 和 86869 个建筑物组成。
AutoML
AutoML 被集成到微软的 Azure 机器学习服务中。这意味着在 Azure 中使用存储和计算来执行和监控 AutoML 管道相对简单。

AutoML 管道的一般工作流程相当简单。您定义了训练数据集(Richter 数据集)、交叉验证方案(5 重交叉验证)、主要指标(加权 AUC)、实验类型(分类),一切就绪。根据您想要执行实验的位置(在本地 pc 上、云中的虚拟机或大型集群上)以及数据驻留的位置(本地或云中),您还必须指定数据和计算配置。
一个 AutoML 流水线由以下步骤组成:
1 .给定实验类型,生成一组初始管道参数。
2。使用不同的参数执行实验,并使用交叉验证测量主要指标。
3。选择一组新的(最佳)管道参数,并继续下去,直到达到一个阈值。这可以是大量的实验、花费在实验上的时间或不同的度量。
4。最后,构建不同模型的集成,以在测试集上获得最佳性能。
注意,选择一组好的算法和超参数的一般问题是一个复杂的问题。搜索空间(即模型空间)非常大,评估不同的实验通常需要大量的计算和时间。在相当长的一段时间里,超调是通过对模型空间执行随机或完全搜索来完成的。由于计算能力有限,这意味着这些模型空间必须受到启发式的限制。

如今,贝叶斯方法通常被视为超参数优化的优越方法,尽管基于 RL 的方法在例如神经架构搜索中也变得相当流行。这些方法背后的一般思想是,它们将“智能地”和“有效地”搜索模型空间,在探索(新的模型类型)和开发(改进以前的最佳模型类型)之间进行权衡。
结果
将 AutoML 管道直接应用于数据集会导致模型的性能(F1 为 0.5441)比竞争基线(F1 为 0.5815 的随机森林模型)差。对模型结果的分析很快说明了为什么会达到如此低的 F1。数据集不平衡(第一类:7.5%,第二类:52.5%,第三类:40%)。由于 AutoML 管道不执行欠采样或过采样,这意味着 AutoML 管道中的不同模型是在不平衡的数据集上训练的。

AutoML 管道的混淆矩阵也证实了模型中存在的对两个主要类别的偏向。由于比赛是对 F1 微分的评价,这个模型表现的不是很好。
尽管 AutoML 包含了一些特征工程、预处理、缺失值插补,但为 AutoML 管道提供一个干净、平衡的数据集仍然很重要。
为了改善结果,我采取了以下步骤:
- 验证不同的要素是否转换为正确的格式(数值或分类)。
- 利用 SMOTE 进行合成数据生成。这确保了数据是平衡的,而不必欠采样或丢弃任何数据。
实验部署在 AzureML compute(托管虚拟机)上,并使用 AutoML 管道运行了 100 个实验。
正如您在下面的图中看到的,运行更多的实验管道不会导致性能方面的显著改善,尽管这很可能是在竞争中获得第一名的必要条件。

放大混淆矩阵,很明显该模型表现更好,尽管第二类和第三类之间仍然存在明显的混淆。在这种情况下,额外的数据扩充技术(例如欠采样或过采样)或手动特征工程可能会有所帮助。

下图还展示了一些功能的重要性。显然,有许多(稀疏的)特性对最终性能的影响有限。因此,去掉这些特性是值得尝试的。首先,位置特征具有最大的影响,这是因为

最终的“最佳表现”车型 F1 得分为 0.7419。这比比赛中的最好成绩略低,但考虑到获得这些结果所涉及的工作量,我想说这对 AutoML 来说是一个非常有希望的结果。

结论
AutoML 对于任何数据科学家的工具箱来说都是一个很好的补充。超参数调优框架并不新(例如 hyperopt ),但是一个允许数据科学家在单个 Python 包中轻松结合计算、数据和实验的框架是一个很大的改进。也就是说,为了充分利用这些工具,有必要执行适当的数据预处理,选择正确的优化指标等。此外,为了避免在这些工作负载上花费大量计算和时间,可以根据数据探索和经验缩小搜索空间。
如果你对 AutoML 有任何问题,我很乐意在评论中阅读。如果你想收到我博客上的更新,请在 Medium 或 Twitter 上关注我!
实现数学成熟
关于学习数学的思考
“……知识会膨胀,但爱会积累。”——哥林多前书 8:1
“数学成熟度”是高等教育中经常使用但很少定义的流行语之一。更难理解的是如何达到“数学成熟”。在这篇文章中,我想分享我在充满数学的旅程中获得的一些见解。

旅程
免责声明:如果你在一个班里,你不知道发生了什么,下面这些都没用。基本理解是掌握的先决条件。读课本,去听课(并注意)。从最少开始,然后争取更多。
超过这一点需要练习
这似乎是显而易见的,但你真的需要大量的实践。反复接触这些材料有助于将机械操作植入你的肌肉记忆。实践还有助于消除困扰许多初高中学生的简单代数错误。消除这些错误是走向数学成熟的早期标志。但是简单的实践并不是深入概念理解的充分条件。剩下的这些建议改进了“蛮力”练习,鼓励更有效的专注练习,超越了重复一系列机械步骤的能力。
反思和强化
蛮力解决问题似乎相当令人生畏,因为它表明优秀只能通过数千小时的实践问题(也许是 10,000 小时?).与其简单地把问题当作死记硬背的任务来完成并继续前进,一种更聪明、更有效的解决问题的方式是在作业过程中和作业后不断反思,无论是家庭作业、讨论还是测试。问问你自己,“在这一步我在想什么?”,“为什么我在这个问题上搞砸了?”;问问题“这个问题要求我做什么?”,“我将使用什么一般方法来解决这个问题?”,“这个问题符合什么模式?”,“我需要什么公式来解决这个问题,我将如何使用它们?”
一个实用的技巧是,什么都做一次没有解,然后做一次有解。对于家庭作业来说,永远不要看解决方案——与问题搏斗直到它屈服才是真正的学习。如果你真的卡住了,请朋友帮忙。如果他们不知道,讨论方法和想法,尽可能多地拉拢其他朋友,直到你搞清楚为止。考试(或没有答案的家庭作业)后,检查整个考试,重做你漏掉的问题。如果卡住了,看看解决方案,然后写下解决方案。写下解决方案并不是真正的目标:重要的是理解你哪里错了,你错过了哪个转弯,以及为什么正确的道路确实是正确的。把它写下来只是一种鼓励这种理解的方法,但是仅仅复制是没有用的。
这种事后检查的做法非常重要,却极未被充分利用。这需要很强的纪律性和相当数量的“未分配”工作,即没有明确分配或分级,但提供显著收益的工作。这就是为什么班级应该强制或鼓励对作业进行重新评分,因为它明确地鼓励学生进行反思和重新评估练习。
在所有这些反思和分析之后,重要的是巩固你从错误中吸取的教训。怎么会?通过多做练习,多接触相同的内容。在每一轮练习和思考之后,随着时间的推移,你应该有希望看到错误数量的减少和常见错误的消除。如果没有,那么你就没有真正应用你所学的东西——在做每个问题之前慢下来,试着看看它是否与你以前见过的其他问题相匹配,这样你就知道你会陷入哪些常见的陷阱。
想象前方的路
即使是最难的高中问题也只需要最多一(1)个独特的视角和两(2)个重要的替换或步骤。一旦你确定了这些,剩下的就是代数运算了。提重物可以在提铅笔之前进行;一旦前面的道路畅通无阻,剩下的就是机械了。
这种高层次的方法很重要,因为很多时候学生会迷失在代数的画笔中,忘记他们要去哪里。了解你的目标是什么,并确定前进的方向——然后满怀信心地向前迈进。如果你能在这个阶段找到正确的路径,问题就已经解决了。即使你不能在当前时刻解决问题,例如问题太复杂,仅仅是确定目标和思考可能的步骤就是开始真正解决问题的良好开端。
证明它
通常,公式被认为是死记硬背。但是你碰到的很多公式都可以从基本公理推导出来。能够推导和证明陈述有助于加深对陈述为真的原因的直觉。这也可以说比记忆更有效,因为如果你忘记了公式,你应该可以重新推导出来。当然,你也不应该死记硬背证据,因为那样会破坏整个目的。相反,只要记住证明中使用的一系列“技巧”和概念就足够了。事实上,拥有一个好的代数“技巧”工具箱是解决问题的宝贵资产,因为它们经常出现在许多不同的上下文中。最后,练习证明方法本质上是一般问题解决练习的一个子集。
理智检查是为理智的人准备的
在解决问题时,我鼓励你在工作中经常进行理智检查。例如,如果你在研究概率,确保你的概率在 0 和 1 之间;对于微积分,做一些检查你的导数的符号,等等。
健全检查有几个动机。首先,当在科学中使用数学时,检查最终符号答案的单位是否与预期的单位匹配是对代数的一个很好的检查,也给了你转换单位的练习。理智检查也需要适度的概念理解:如果你对你的答案没有预期,你就不能检查它。最后,健全性检查也是引入无关概念并在您的健全性检查中利用它们的好方法,这是将概念编织在一起并查看跨不同主题的应用程序的好方法。
教学就是掌握
教学是加深你理解的极好方法。当教学时,你面对的不仅仅是你自己的问题,而是整个班级的学生,他们会以自己的方式看待和误解这些问题。
从信息论的角度来看,教学是智能信息压缩。回答学生的问题需要你清楚地找出误解点,确定正确的答案,并找到一种简洁明了的方式来解释答案。能够有效地做到这一点意味着你已经找到了一个有效的“潜在空间”表示或“多样性”,即掌握一个概念。
最后,教学本质上是一种社会活动。在现代科技时代,更重要的是能够清楚地向他人传达想法。认为这是一种有价值的练习,不仅可以清楚地解释概念,还可以激励和启发学生,否则他们可能看不到这些练习的意义。

抽象、模块化、区分、分层
与可视化相关的是抽象的概念。抽象思考的能力,超越简单的代数运算,想象你想解决问题的方向,是解决问题的固有部分。我们到底是如何抽象的?通过实施模块化——具体来说,通过识别每个问题的不同组成部分,它们如何相互关联,以及分别为每个组成部分制定攻击计划。
一旦我们看到了整个问题的这些不同的模块块/组件,我们就可以将该问题与我们之前看到的具有相同模块/组件的其他问题区分开来,除了配置可能略有不同。许多问题只是简单地排列出已知的或已知的方块,并要求你求解其他的元件/方块。这种辨别问题并说“你实际上只是我以前见过并做过多次的另一个问题的一个稍微不同的版本”的能力允许你把你以前获得的所有知识和技能投入到这个新问题中,尽管是以稍微不同的方式。
分层组织实际上是模块化的一种有序形式,其中各个模块按照复杂性的顺序进行组织。抽象概念建立在更简单的概念之上,层次结构的每一层都被抽象的障碍所分隔。学习明确地按照层次进行思考是建立概念理解的有效方法,因为许多数学可以以这种方式组织。
这种层次抽象的一个明显例子可以从线性代数中得到。抽象的基础层是向量-向量乘法、矩阵-向量乘法、点积、外积。接下来是高斯消去法和基本的矩阵变换,如逆矩阵、转置矩阵和行列式矩阵。请注意,即使在这个相对较低的层次上,也有复杂的联系和方式来直观地理解逆和行列式。接下来是向量空间和特征向量分解。然后各种矩阵分解技术等等。显然,抽象的障碍不像在软件开发中那样强烈,但是作为一个组织工具,仍然是非常宝贵的。
奖励
数学:科学女王
虽然数学经常被称为“科学女王”,但一个更具描述性的比喻可能是,现代科学方法是用数学语言书写的。你会经常发现,数学课上教的数学一般比科学课上用的数学要高级得多。例如,高中力学实际上只是代数和化学甚至更简单。尽管如此,这种“更简单”的数学是丰富的,因为变量和函数充满了现实世界的意义和含义。
就我个人而言,我参加了各种工程课程,并且学得很好,这不是因为我以前有知识,也不是因为我一定比任何人都努力,或者因为一些天生的天赋,而是因为我磨练了自己理解公式、方程、函数——科学语言——的能力。科学实际上是数学语言的上下文包装;突然间,变量背后有了单位和意义。一个函数的特征具有重要的现实意义,最终结果反映了我们周围世界的一些基本情况。一个答案有正或负的斜率,数量级小于 1,这些数学性质突然有了巨大的物理意义。但如果我们没有牢固掌握这些见解所用的语言,我们就无法获得这些见解,这就是为什么数学成熟度很重要,不仅对数学家如此,对科学家和工程师也是如此。
数学生活
这里讨论的许多方法都非常通用。抽象、模块化和区分的想法是基于我的软件设计经验,但是解决问题的方法是非常通用的。在生活中,我们可以通过寻找方法和途径来解决问题。
甚至非技术领域,如议论文/说服性写作、哲学和辩论也需要这种类似的模块化思维,但方式稍微“宽松”。我的意思不是消极的——事实上,我发现这种思考更加困难。解决一个问题和提出一个好的论点之间的相似之处很有趣,但不幸的是需要另一篇文章来探索。
那么我上面给出的提示和一般的解题主题有什么不同呢?我认为主要的区别在于数学中快速而具体的反馈回路——你可以很容易地验证你的工作和答案是正确的。哲学不是这样的,许多科学领域也是如此,写作也是如此,修马桶也是如此(尽管可以说这与计算机科学有相似之处,主要区别在于好的软件工程和语法并不是天生就显而易见的,需要教授)。
结论
希望这篇文章可以作为一个路线图,或者至少是一个有价值的工具,来激发你下次坐下来做数学作业时更加专注的练习。这些原则中有许多是非常通用的,适用于你经常遇到的任何问题。
“数学是最便宜的科学。不像物理或化学,它不需要任何昂贵的设备。数学只需要一支铅笔和一张纸。”—乔治·波利亚
资源
乔治·波利亚的典范之作,如何解决 以及它的总结这里
在线课程: Coursera , EdX ,麻省理工开放式课程
我做了一个 github repo,里面是为微积分前的高中生准备的数学题
用几行代码实现深度学习模型的激活图
我们用几行代码演示了如何在深度 CNN 模型中显示不同层的激活图。

更新:这个故事获得了 KDNuggets 颁发的十月最受分享的故事银奖。

https://www.kdnuggets.com/2019/10/activation-maps-deep-learning-models-lines-code.html
深度学习有一个坏名声:“黑箱”
D eep L earning (DL)模型在一个又一个应用领域以令人瞠目结舌的性能彻底改变了商业和技术世界—仅举几个例子,图像分类、物体检测、物体跟踪、姿势识别、视频分析、合成图片生成。
然而,它们一点也不像经典的盈利算法/技术。DL 模型使用数百万个参数,并创建极其复杂和高度非线性的图像或数据集的内部表示,这些图像或数据集被提供给这些模型。
因此,它们通常被称为 完美的黑盒 ML 技术 。在我们用大型数据集训练它们之后,我们可以从它们那里获得高度准确的预测,但我们几乎没有希望理解模型用来将特定图像分类的数据的内部特征和表示 。

Source: CMU ML blog
深度学习的黑箱问题-没有直观和易于理解的解释的预测能力。
这不是好兆头,因为我们人类是视觉动物。数百万年的进化赋予了我们一双极其复杂的眼睛和更复杂的视觉皮层,我们用这些器官来理解世界。

Source: Wikimedia
科学过程始于观察,而观察几乎总是视觉的同义词。在商业中,只有我们能观察和测量的,我们才能有效地控制和管理。
看到/观察是我们如何开始对世界现象建立心智模型,对我们周围的物体进行分类,区分朋友和敌人,爱,工作和玩耍。
可视化很有帮助。尤其是对于深度学习。
因此,一个“黑箱”DL 模型,我们不能可视化内部工作,经常会招致一些批评。
激活图
在各种深度学习架构中,最突出的可能是所谓的Con voluntualNeuralNnetwork(CNN)。它已经成为分析高维、非结构化数据的主力,这些数据包括图像、文本或音频,传统上对经典的 ML(非深度学习)或手工制作的(非 ML)算法提出了严峻的挑战。
在文献中已经开发了几种理解和可视化 CNN 的方法,部分是作为对 CNN 内部特征不可解释这一常见批评的回应。
最直接的可视化技术是显示网络在正向传递过程中的激活。
那么,什么是激活呢?
在简单的层面上,激活函数有助于决定一个神经元是否应该被激活。这有助于确定神经元接收的信息是否与输入相关。激活函数是发生在输入信号上的非线性变换,并且变换后的输出被发送到下一个神经元。
如果你想准确地理解这些激活意味着什么,为什么它们首先被放在神经网络结构中,请查看这篇文章,
今天,互联网提供了获取大量信息的途径。我们需要的只是一个谷歌(搜索)…
www.analyticsvidhya.com](https://www.analyticsvidhya.com/blog/2017/10/fundamentals-deep-learning-activation-functions-when-to-use-them/)
下面是著名数据科学家 Brandon Rohrer 的精彩视频,讲述了 CNN 的基本机制,即如何一层一层地处理给定的输入(比如二维图像)。在每一层,通过激活函数传递转换后的输入来生成输出。
作为各种线性代数运算的结果,当给定图像前进通过时,激活图只是这些激活号在网络的各层的可视化表示。
对于基于 ReLU 激活的网络,激活通常开始时看起来相对较大和密集,但是随着训练的进行,激活通常变得更加稀疏和局部化。这种可视化很容易捕捉到的一个设计陷阱是,对于许多不同的输入,一些激活图可能全为零,这可能表明失效过滤器,并且可能是高学习率的症状。
激活图只是这些激活号码在网络各层的直观表示。
听起来不错。但是可视化这些激活图是一项重要的任务,即使你已经很好地训练了你的神经网络,并根据它进行预测。
对于一个相当复杂的 CNN,如何用几行代码轻松地可视化和显示这些激活图?
只有几行代码的激活图
整本 Jupyter 笔记本都在这里 。随意分叉和扩展(如果您喜欢,可以给存储库留一个星号)。
一个简洁的函数和一个漂亮的小库
在之前的一篇文章中,我展示了如何编写一个简洁的函数,通过利用 Keras 库提供的一些令人惊叹的实用方法和类,从磁盘中一个接一个地自动读取图像文件,从而获得完全训练好的 CNN 模型。
一定要看看这篇文章,因为没有它,你就不能以紧凑的方式用任意的图像数据集训练任意的模型,正如本文所描述的。
我们展示了如何构建一个单一的、通用的、实用的函数来从一个目录中自动提取图像…
towardsdatascience.com](/a-single-function-to-streamline-image-classification-with-keras-bd04f5cfe6df)
接下来,我们使用这个函数和一个叫做 Keract 的漂亮的小库,这使得激活图的可视化变得非常容易。这是 Keras 库的一个高级附件库,用于显示神经网络各层的有用热图和激活图。

因此,对于这段代码,我们需要使用来自我的utils.DL_utils模块- train_CNN_keras和preprocess_image的几个实用函数,使随机 RGB 图像兼容生成激活图(这些在上面提到的文章中有描述)。
这里是 Python 模块— [**DL_utils.py**](https://raw.githubusercontent.com/tirthajyoti/Deep-learning-with-Python/master/Notebooks/utils/DL_utils.py)。您可以像往常一样存储在本地驱动器中并导入函数。
数据集
为了训练,我们使用著名的加州理工学院-101 数据集来自http://www.vision.caltech.edu/Image_Datasets/Caltech101/。这个数据集在某种程度上是 ImageNet 数据库的前身,ImageNet 数据库是当前图像分类数据存储库的黄金标准。****

这是一个图像数据集,包含属于 101 个类别的不同类型的物体。每个类别大约有 40 到 800 张图片。大多数类别大约有 50 张图片。每个图像的大小大约为 300 x 200 像素。
然而,我们仅使用 5 类图像进行训练— 螃蟹、杯子、大脑、相机和椅子。
这只是这个演示的随机选择,请随意选择您自己的类别。
训练模型
训练只用几行代码就完成了。
从网上下载的人脑的随机图像
为了产生激活,我们从互联网上下载一个随机的人脑图像。

生成激活(字典)
然后,生成激活的另几行代码。
我们得到一个字典,其中层名作为键,Numpy 数组作为对应于激活的值。下面示出了一个图示,其中激活阵列被示为具有对应于该特定卷积层的滤波器映射的大小的不同长度。

显示激活
同样,一行代码,
display_activations(activations, save=**False**)
我们可以一层一层地看到激活地图。这里是第一个卷积层( 16 个图像对应 16 个滤波器)

这里是图层号 2 ( 32 个图像对应 32 个滤镜)

在这个模型中,我们有 5 个卷积层(后面是最大池层),因此,我们得到 10 组图像。为简洁起见,我没有展示其余的,但你可以在我的 Github repo 中看到它们。
热图
您还可以将激活显示为热图。
display_heatmaps(activations, x, save=**False**)

更新:颤
上周写完这篇文章后,我发现了另一个漂亮的激活可视化库,名为。然而,这个是在 Python 微服务器框架 Flask 上构建的,并在浏览器端口上显示激活图,而不是在您的 Jupyter 笔记本中。****
他们还需要一个经过训练的 Keras 模型作为输入。因此,您可以很容易地使用本文中描述的压缩函数(来自我的 DL_uitls 模块)并尝试这个库来实现激活图的交互式可视化。

摘要
就这样,暂时的。
整个 Jupyter 笔记本都在这里 。
我们展示了如何只使用几行代码(利用来自一个特殊模块的紧凑函数和 Keras 的一个漂亮的小附件库)就可以训练 CNN,生成激活图,并一层一层地显示它们——从零开始。
这使您能够从任何图像数据集(只要您能以简单的格式排列它)训练 CNN 模型(从简单到复杂),并查看它们内部的任何测试图像。
更多这样的动手教程, 查看我的用 Python 深度学习 Github repo 。
如果您有任何问题或想法要分享,请通过tirthajyoti【AT】Gmail . com联系作者。此外,您可以查看作者的 GitHub 资源库,了解 Python、R 和机器学习资源中其他有趣的代码片段。如果你像我一样,对机器学习/数据科学充满热情,请随时在 LinkedIn 上添加我或在 Twitter 上关注我。
**** [## Tirthajyoti Sarkar - Sr .首席工程师-半导体、人工智能、机器学习- ON…
通过写作使数据科学/ML 概念易于理解:https://medium.com/@tirthajyoti 开源和有趣…
www.linkedin.com](https://www.linkedin.com/in/tirthajyoti-sarkar-2127aa7/)****
主动学习:充分利用有限的数据
上周,我在快进实验室看到了一位研究员的精彩演讲,这让我想到了被称为“主动学习”的机器学习的例子。主动学习指的是处理不完全标记数据的许多策略,特别是识别哪些点需要手动标记。
当人们听到“机器学习”这个术语时,他们想到的大多数用例都涉及所谓的“监督学习”,这意味着他们需要有标签目标变量的数据来进行训练。如果一家银行希望建立一个模型,根据某些特征预测特定交易是否是欺诈性的,它需要有训练数据,可以向计算机显示包含欺诈性和非欺诈性交易的已知案例。如果机器视觉工程师想要教会汽车的车载计算机识别停车标志,它需要向计算机提供一些带有和没有停车标志的清晰标记的图像示例。有一些非监督技术不引用特别标记的目标变量,例如尝试将点分组在一起或搜索异常的算法,但预测模型几乎总是需要引用目标变量,因此要求数据集已经考虑了该变量。毕竟,你还能如何验证这个模型呢?
然而,在某些情况下,收集足够多的标记数据是困难的。考虑识别路边图片中的停车标志的例子。在互联网上搜索成千上万的照片,或者像谷歌地图那样,在汽车上安装一台相机,开一会儿车,都很容易。识别这些照片中哪些包含停车标志是一项更加艰巨的任务,需要有人逐个照片地检查收集的照片,并标记适当的照片。不幸的是,你不能使用你的停车标志识别机器学习模型来识别你用来训练该模型的照片…
在机器视觉等领域,这是一个特别棘手的问题。可以识别许多不同方向的许多不同种类的对象的健壮模型需要大量的数据来训练,当然比任何一个人能够标注的都多。简单地制作数据集可能会很昂贵——如果这项任务外包给亚马逊的机械土耳其人这样的服务,就需要花费大量的劳动时间或金钱。
如果你看到一个未标记或部分标记的数据集,你该如何处理?很明显,你需要手动标记它,但是对于一个大的集合来说,这可能是昂贵的。不过,也许你真的不需要给整套标签。如果仔细选择这些点,就有可能用较小的训练数据集获得高价值的模型。你如何区分标签和训练模型的优先顺序?这是主动学习策略的核心问题,也是我想在这篇文章中探讨的问题。
特别是,我想思考一些可以在小范围内轻松测试的策略。一些方法需要比在家工作的人更多的模型工作的可见性,例如“预期模型变化”是一种优先选择可能对模型产生最大影响的点的策略。然而,许多机器学习模型必然是不透明的,因此并不总是清楚如何辨别哪些点可能会影响模型。尽管如此,任何人都可以对主动学习在家里的实践中是如何运作的有一种直觉。
假设我们有一个很大但标签不够的数据集,我们如何处理它?嗯,你需要从某处开始,这意味着采取一个更小的,随机的数据集子样本来手动标记。第一次随机抽样是不可避免的;你需要启动这个模型。当你这样做的时候,你可能还需要一个手工标记的测试集。很抱歉,但从现在开始会好起来的。在您标记的较小子样本上训练您的模型,并在您的测试集上评估它的性能。它可能不太好。现在,选择一个新的点样本进行标注,并继续在这些点上训练您的模型,然后进行重新评估。冲洗并重复,直到你的模型按照你想要的方式运行。唯一的问题是如何选择标记哪些点。
最简单的策略是继续随机抽取子样本。你不能指望像这样的随机策略能让你超快地达到目标。它的主要好处是,如果您在用完要标记的数据之前碰巧达到了目标绩效,它允许您停止标记。我们真的希望有一种方法来选择点,以便我们在标记最少的点后获得性能。我们如何找到这些点?
对于分类模型,一种方法是询问模型本身它不确定哪些点。许多机器学习实现不仅可以很容易地从测试集中获得目标变量的预测,还可以获得模型分配给每个潜在结果的概率(假设它是分配概率的模型)。只需使用部分训练的模型对未标记的数据进行预测,并选择模型对其预测最没有信心的点进行标记,并作为下一批训练数据。
思考任务的另一种方式是,我们正在寻找最能阐明模型的隐含决策边界的点。我们正在寻找边缘情况,即决策边界附近的点,如果边界稍微移动,这些点可能会被不同地分类。为什么不选择边界附近的点?一些类型的模型,比如支持向量机,可以很容易地判断出决策边界在哪里。其他模型没有明确定义边界,但是您可以通过找到与模型不同标记的点最接近的点来隐式地寻找它们。旁注:这种策略有点耗时,特别是对于大型数据集,因为它涉及到遍历所有点来计算每个点到其他点的距离。如果你像我一样在用 Python 工作,矢量化是加速这个过程的必要条件,但即使这样也需要一些时间。
为了测试这些策略在实践中的效果,我开始使用著名的 MNIST 手写数字数据集。我听说这一组被称为机器学习的“hello world ”,它无处不在,但对于这个练习来说它有一些有用的功能。这是一个具有许多点的多类分类数据集(训练集中有 60,000 行,测试中有 10,000 行)。它还被方便地处理成一组列,这些列的整数值对应于手写图像中的不同像素,因此在我们开始测试模型之前,它不需要大量的预处理。至关重要的是,用 MNIST 集也很容易得到好的结果。获得 90%以上的精度并不真的需要大量的预处理或模型调整。这个练习的目的不是看你能把一个 MNIST 模型做得多好(我们已经知道答案是非常好),而是看你能否用很少的训练点得到一个好的模型。

Examples of handwritten digits from the MNIST data set
在这个练习中,我使用了 sklearn 的多层感知器模型,它方便地提供了一个“热启动”选项,允许您使用新数据继续训练现有模型,具有两个隐藏层。我依次尝试了每种策略,从随机选择的 500 个点开始每个模型,然后向训练数据中添加新的一批点,每次 500 个。我一直坚持到模型达到 95%的准确率。随机策略的性能(您不一定期望它能很好地工作)主要说明了 MNIST 数据集的易用性。正如我提到的,训练集是整整 60,000 行,但随机策略使用不到三分之一的行就让我们达到了 95%的准确率:

Number of training data rows vs model accuracy for randomly chosen training rows
您会注意到,虽然随着您添加更多批次的训练数据,模型通常会变得更好,但根据新点的随机分布,它偶尔会损失一些新训练数据的准确性。相比之下,当我们通过询问模型哪些点最不确定来选择新点时,模型的性能通常会随着每个新批次而提高,并且更快地获得我们的目标准确性:

Increasing model accuracy by selecting training points based on the model’s assigned probabilities
随机方法最终需要看到 17500 个点才能达到 95%的准确率。基于概率的方法只需要 8500 英镑。也许这是意料之中的。真正令人惊讶的是,除了花费很长时间之外,基于我们对它们离决策边界有多远的隐式度量来选择点,实际上并没有比随机样本方法产生任何改进。这是所有三种策略的图表:

起初,每个模型都从新批次的数据中受益匪浅——我启动这些模型时只有 500 行,这显然是不够的。基于概率的样本策略很快取得并保持领先,然而,随着每一个新的批次,看到稳定的改善,而随机策略有点向目标弯曲。在加快速度之前,到决策边界策略的距离似乎停滞了近 4000 行,最终甚至不如随机策略。
我承认对决策边界策略似乎不起作用感到有点惊讶。然后我在其他数据集上尝试了这些策略,大部分都得到了相似的结果。我喜欢的一套是 Zalando Research 的“时尚-MNIST”,它是在最初的 MNIST 集(它有相同的行数,像最初的集一样,每一列对应一个像素值)的基础上制作的,除了它有衣服的灰度图像,而不是手写数字。

The Fashion-MNIST dataset
这是一个很难得到结果的集合,所以我把我的目标降低到 85%的准确率。两种策略之间的总体学习曲线基本保持不变:

Similar results using the more difficult Fashion-MNIST set
基于概率的样本方法表现更好,尽管不如普通 MNIST 集明显好。同样,决策边界方法似乎不起作用。实际上,您可能会注意到,决策边界方法模型恰好在性能方面优于其他两个模型——这只是一点偶然,因为这些模型都是从随机抽取的样本开始训练的。然而,决策边界浪费了它的领先优势,并且在接下来的 3000 行增量训练数据中基本上看不到改进。
当然,任何给定的主动学习策略的有效性可能会因数据集和模型而异。机器学习的挑战之一是,事先并不总是清楚什么样的策略和模型最有效。然而,实验是有用的,因为实际上,学习方法和模型的选择一样重要。
2019 年的 ADAM—下一个 ADAM 优化器是什么
如果 ADAM 速度快,SGD +动量收敛更好,为什么不能从 ADAM 开始,后来改用 SGD?

Visualization of loss landscape from https://www.cs.umd.edu/~tomg/projects/landscapes/
介绍
深度学习已经取得了很多进展,每隔几周就会有新的模型问世,然而我们在 2019 年仍然停留在亚当身上。你知道亚当论文是什么时候出版的吗?现在是 2014 年,相比之下,BatchNorm 论文是 2015 年发表的!🎈

the original Adam paper

Batch Norm paper was published in 2015
对于深度学习社区来说,5 年就像是一个世纪,我对最近 optimizer 的发展很好奇,所以我四处搜索并试图总结我的发现。Sebastian 对优化算法有一个很好的概述,但是它不是最新的,并且错过了最近出现的一些进展。
见见亚当的家人
你可以从 PyTorch 文档 中轻松找到很多优化器。阿达德尔塔,阿达格拉德,阿达姆,阿达马克斯,这样的例子不胜枚举。看来我们真的无法摆脱亚当。o 让我们快速回顾一下亚当。如果你已经熟悉了,可以跳过这一部分。

Adam = Momentum + RMSProp
大坝是动量和 RMSProp 的结合。动量(v)为优化器提供短期记忆,而不是完全信任当前梯度,它将使用先前梯度和当前梯度,并以比率β1 将它们相加。虽然 RMSProp 将梯度的 1/平方根考虑在内,但直觉上,这意味着如果方差很小(有把握),优化器将采取更大的步骤,反之亦然。

Adam updates rules
Adam 很棒,它比 SGD 快得多,默认的超参数通常工作良好,但它也有自己的缺陷。许多人指责亚当有收敛问题,往往 SGD +动量可以用更长的训练时间收敛得更好。我们经常看到很多 2018 年和 2019 年的论文还在用 SGD。

最近的进展
那么,关于训练神经网络,我们学到了什么?我会尽量保持简短,并补充文章的细节。
圣经》和《古兰经》传统中)亚当(人类第一人的名字

RAdam update
关于自适应学习率的方差和超越 引入宣叙调——亚当。本文认为,Adam 的初始训练是不稳定的,这是由于只有很少的数据点用于计算二阶矩(s_t)项的指数移动平均。RAdam 通过仅在对梯度的方差有把握时校正自适应学习率来解决这个问题。否则,它会关闭自适应学习率,并使其回落为 SGD +动量。热身学习率具有类似的效果,因为学习率从较低值(高方差,数据点少)开始,慢慢增加到较大的学习率(稳定方差,数据点多)。使用 RAdam 的一个好处是,它在学习速度的选择上更加稳健,而且你不必决定热身期的长度。

Warm-up learning rate
如果你想了解更多关于 RAdam 的知识,可以参考这篇好看的文章。
前瞻优化器

Jimmy Ba was one of the authors of the Adam Optimizer, and we all know about Geoffrey Hinton already. 😃
前瞻优化器由两部分组成,慢速权重和快速权重。快速权重是充满活力的,每次更新需要几个步骤,慢速权重是谨慎的,它不是跟随快速权重,而是基于指数平滑对参数进行插值并采取一些中间步骤。前瞻优化器本身并不工作。如果你看一下算法,内循环只是普通的小批量更新,所以它需要像 SGD 或 Adam 这样的优化器。
蓝线是快速权重的轨迹,有多个数据点,因为对于快速权重(蓝色)的每 k 次更新,我们将仅对慢速权重(紫色)进行 1 次更新,然后我们将重置快速权重。基本上,快速的重量是哨兵,它需要多走几步,以确保周围是安全的,然后慢速的重量采取一些中间步骤。对于下面的例子,您可以看到,只需一次更新,慢速权重就更接近黄色区域(高精度)。

拉尔斯/兰姆

The highlighted part is the trust ratio calculation, the φ is a scaling function which the paper similar use identity function φ(z) = z
LARS 及其继任者 L 逐层 A 自适应 M 网膜优化器为 B atch training (LAMB)优化器向前迈进了一步。LAMB (1)像 Adam 一样保持梯度的平方根作为自适应学习率的一部分,但是(2)它有一个额外的组件,称为“信任比”。这篇文章更详细地解释了 LAMB,如果你感兴趣的话。其要点是,它不仅将梯度的方差作为缩放因子,而且还将层权重和层梯度的范数之比作为。很有道理,比较大的权重和小的权重,你需要根据它们的比例来缩放学习率才能有类似的效果。通过用信任比率缩放,它确保每层的更新是单位 l2 范数,这通过减轻梯度消失问题来帮助训练深度网络。
讨论
如果 ADAM 速度快,SGD +动量收敛更好,为什么不能从 ADAM 开始,后来改用 SGD?
我对此没有很好的答案,我有时在 Kaggle 上看到人们这样做,这篇文章暗示这是可行的。为了训练更快、更准确的神经网络,有很多改进当前优化器的尝试。在深度学习中,解释往往出现在经验结果之后。那么我们到底对优化器或神经网络的优化了解多少呢?
《与 SGD 一起散步》这篇文章有一些有趣的解释,我鼓励你去读一读。我认为这解释了最近发展的一些联系。
为什么线性比例学习率和批量不能达到特定的批量?
与 SGD 一起散步的论文比较了梯度下降和随机梯度下降(SGD ),并提出学习速率和批量大小在 SGD 动力学中扮演两个非常不同的角色
学习率

通过观察每次更新前后插值参数的损失,发现 SGD 谷大致是凸的,这大致符合我们的理解。然而,该论文也指出 SGD 谷的底部是高度非线性的,并且充满了障碍。学习率控制 SGD 的高度,所以使用大的学习率简单地越过障碍,而不是跨越它。这与我们的理解不同,我们通常认为较大的学习率会导致 SGD 更难反弹,并有助于避免局部最小值。下图显示了假设的拓扑结构。这可能是反直觉的,如果学习率保持在地板以上的高度,它如何将损失最小化?事实证明,我们过于简化的错觉,即 SGD 只是从一座静止的小山上走下来,是错误的。事实上,“山”本身也在不断变化,因为它只是我们从高维空间到三维空间的投影。看看这个由 https://losslandscape.com/gallery/创造的美丽而奇异的失落景观视频吧!
批量
而批量大小控制随机性,这有助于探索。本文通过观察 SGD 导致比梯度下降(GD)大得多的参数距离来支持这一论点。

The upper graph represents the angle between each update, -1 means it is the opposite direction. The lower graph measures the ||parameter distance||² from initialization, a larger value means it is further from the initialization points.
从这个图中可以学到一些东西。(1)每次更新之间的角度具有非常不同的梯度下降和 SGD 特征。(2)SGD 在 40 次迭代后参数距离大很多。这个角度告诉我们一些有趣的故事。首先,对于梯度下降,它很快稳定在-1,这意味着 SGD 很可能在类似山谷的地形中振荡。而对于 SGD,该值较大,并上下波动,表明它沿着谷壁振荡,但具有更多勘探,而不是停留在局部谷中。较大的参数距离也支持了 SGD 有助于勘探这一论点。
事实上,我认为这种见解可能与这样一个事实有关,即为什么在批量达到某个阈值之前,线性提升学习率/批量比例不起作用。如果批量大小具有根本不同的动态,这是有意义的。LAMB 优化器成功地用非常大的批量(65536/131072)训练了 BERT。研究 LAMB 如何改变批量大小的动态变化,并通过逐层缩放学习速率来帮助优化,这可能是很有趣的。
最好的学习率时间表是怎样的?
根据 RAdam 论文,我们了解到热身计划有助于减少梯度的变化。这是否意味着我们不再需要热身了?可能不会,因为我们知道高学习率也有助于优化。SGD 文件还提出了一个梯形进度表,我们可以将进度表分为 3 个阶段。fast.ai 也使用了类似的策略,他们称之为单周期训练的修改版
(1)热身阶段,从低学习率开始,线性增加到最大
(2)公路训练阶段,停留在最大学习率
(3)收敛阶段,学习率线性衰减到最小值

请给我留下评论,如果你认为有用,别忘了竖起大拇指。👍👍👍👍👍
关键词:亚当,SGD,RAdam,前瞻,羔羊
参考
【P1】、、、、彭城何、陈、、、高剑锋、韩家伟对自适应学习率的方差及其超越
[p2] 迈克尔·r·张,詹姆斯·卢卡斯,杰弗里·辛顿,吉米·巴前瞻优化器:向前 k 步,向后 1 步
【P3】陈星,德万什·阿皮特,克里斯特斯·齐里戈蒂斯,约舒阿·本吉奥与 SGD 一起散步
Leslie N. Smith , Nicholay Topin 超收敛:使用大学习率非常快速地训练神经网络
【P4】【尤杨】【李京】萨尚克·雷迪乔纳森·谢桑基夫·库马尔斯利那达·博贾纳帕利肖丹·宋詹姆斯·德梅尔库尔特·库特策赵瑞希
[p5] 帕维尔·伊兹迈洛夫,德米特里·波多普里欣,帖木儿·加里波夫,德米特里·维特罗夫,安德鲁·戈登·威尔逊平均权重导致更宽的最优值和更好的泛化能力
[p10]伊恩·J·古德菲勒、奥里奥尔·维尼亚尔斯和安德鲁·M·萨克斯。定性表征神经网络优化问题。arXiv 预印本 arXiv:1412.6544,2014。
AdaNet —论文评论
人工神经网络的自适应结构学习

本文原载于【blog.zakjost.com】。格式/数学看起来更好:)
介绍
在向机器学习普及进军的过程中,AutoML 正在成为一种重要的机制,使那些在该领域没有深厚专业知识的人可以访问 ML。简单地说,AutoML 的愿望是允许一种“按钮式”体验,用户提供数据,按下按钮,从另一端得到 ML 模型。
在神经网络的情况下,确定网络结构是一个重要的挑战-例如,有多少层,每层有多少节点,各层如何连接在一起?典型的建议是,从硬件能力和速度的角度出发,选择尽可能大的模型,然后使用标准实践来防止过度拟合。
来自 Google Research 的网络论文提出了一种新算法,允许我们学习最佳网络结构。他们在论文中发展和应用的理论与我过去阅读的完全不同,通过研究,我学到了一个有价值的观点。我将试着在这里用一种更容易理解的方式来表达我对它的理解,希望其他人也能从他们的观点中受益。
框定问题
泛化误差
监督 ML 的主要目标是学习一个模型,该模型提供对新数据的良好预测,即最小化泛化误差。对此的典型方法是首先优化模型参数,以学习对训练数据进行良好的预测。然而,众所周知,单独使用最大似然技术来学习模型参数会导致模型在训练数据上表现良好,但可能不会很好地推广到新数据,因为它也适合训练数据中的噪声。因此,已经开发了各种技术,以一种或另一种方式试图限制模型的复杂性(例如,正则化、丢弃、提前停止等),以使其无法适应噪声。然后使用迭代循环来开发该模型,在该循环中,通过使用维持数据集来评估过拟合的程度,然后使用不同的参数来重新训练该模型,目的是最终减少泛化误差。
本文采用了不同的方法。作者发展了一种理论,该理论产生了一个方程,用于直接估计泛化误差的上限。直观地说,这个等式取决于训练数据性能和模型复杂性之间的权衡。有了泛化误差的显式方程(以及最小化它的算法),我们就可以在训练性能和复杂性之间做出良好的权衡决策。由于模型的复杂性取决于神经网络的结构和训练数据的性质,我们可以学习网络的最佳结构。
合奏
首先,应该注意的是,这篇论文是同一作者在深度增强论文中开发的技术的扩展。尽管那篇论文是在树的集合的上下文中,但是这篇论文将类似的技术扩展到了神经网络的世界。这项工作的基础是将“终极模型”视为更简单的“子模型”的集合(引号中的术语是我的非正式术语,不是论文)。这意味着:

其中“最终模型” f 是子模型的加权和, w 表示权重, h 表示子模型。在树的情况下,集成学习每棵树的决策的最佳权重。在神经网络的情况下,这只是另一个具有单个输出节点的密集层,该输出节点连接到子模型层的所有输出节点。下面是一个示例网络架构,其中有两个子模型,每个子模型每层有 3 个输出节点,但具有不同的深度:

理论
计算泛化误差
我不会在这里试图重新创建证明,我将只讨论结果的有趣方面。泛化误差上限的等式如下:


用英语来说,大致是这样的:
泛化误差< =训练误差+ensemble _ weights * submodel _ complexity+取决于你训练数据大小和神经网络最大深度的东西。
我想特别提醒大家注意这一部分:

泛化误差=~子网络上的集成权重?!这真是个好消息!这意味着我们可以:
- 通过修改应用于集合中各种组件的权重来改善泛化误差。
- 允许复杂的模型(即深层),只要我们通过给它们小的权重来补偿。
这为我们提供了一种原则性的方法,用于决定何时在我们的集合中包括更复杂的模型,以进一步减少训练误差:当训练误差的减少大于复杂性项的增加时,我们应该这样做。
复杂性
到目前为止,我们已经看到了模型复杂性是如何影响估计泛化误差的,但是还没有看到如何计算模型复杂性本身。在这个研究的世界里,拉德马赫复杂性的概念似乎是标准。在阅读这篇论文之前,我对这个概念并不熟悉。我的理解是,它衡量的是一族函数对噪声的拟合程度。在高层次上,您可以想象一些复杂的深度神经网络可能比逻辑回归更适合随机生成的训练数据集。拉德马赫复杂性是量化这种能力的公式。
此外,经验 Rademacher 复杂度量化了一族函数在特定数据集上拟合噪声的程度。虽然我对自己的理解不是 100%有信心,但我认为这个想法是,一些数据集自然允许一个模型比其他模型适合更复杂的函数。例如,如果您想象一个包含 100 行单一二进制特征的数据集,那么即使使用深度神经网络,您使用该特征预测噪声标签的能力也是有限的。然而,如果您有 1000 个高基数特性,那么您可以更容易地适应噪音标签。这样,模型的复杂度就依赖于训练数据集。这是一个特性,而不是一个错误,因为数据相关的复杂性度量允许理解一些数据集比其他数据集需要更复杂的模型(例如,语音识别与虹膜物种分类)。
困难的部分是使用 Rademacher 复杂度的一般定义来导出特定函数族的上界。幸运的是,AdaNet 的论文为前馈神经网络做了这样的工作:

所有这些术语都与神经网络的结构(例如, Lambda_{s,s-1} 是对层 s 和 s-1 之间的连接规范的约束)或训练数据集的属性相关。
那又怎样?
好,让我们深呼吸,从所有这些方程中恢复过来。到目前为止,我们已经有了一个神经网络集成的泛化误差方程。这取决于我们控制的子模型连接的权重,以及它所连接的层的复杂性。层的复杂性由网络的结构决定,例如,更多/更深的层和更大数量的节点增加了我们的训练数据集的复杂性和属性。
通过将该方程视为成本函数并将其最小化,我们可以以原则的方式学习神经网络集成的最佳结构。在这一创新之前,我们只是选择了一种网络结构,并针对间接复杂性惩罚方法(如放弃和提前停止)迭代调整了参数。或者我们将结构参数,如层数,视为另一个超参数,并进行大量试验来调整一切。
但是还有一些事情我们没有讨论:生成这些集合之一并在网络架构搜索空间中导航的秘诀是什么?
实际的算法
有多种方法可以做到这一点,但是作者建议了一种相当直接的方法:
- 训练两个候选子网络(这与集合无关):一个具有与前一次迭代中使用的相同层数;一个具有作为先前迭代的一个附加层。
- 一旦子网络的训练完成,剥离最后一个节点以暴露最后一个隐藏层,然后通过学习权重将每个节点插入到集成中,以将最后一层连接到集成的输出。这是从步骤 1 开始对每个候选子网独立完成的。(这一步使用泛化误差方程作为代价函数,量化了训练误差和子网络复杂度之间的权衡。)
- 为集合选择导致最低泛化误差的候选项
- 从步骤 1 开始重复,直到泛化误差停止改善。
这里有一个来自官方回购的动画演示了这一过程:

请注意,这是一个自适应的过程,开始时很简单,随着时间的推移会变得越来越复杂。如果手头的问题需要一个更复杂的模型,算法将运行更长时间,并扩大结构。如果模型具有足够的复杂性/容量,泛化误差降至最低点,算法终止。这是一种贪婪的搜索,类似于决策树如何一次选择一个分裂点,而不是试图联合优化所有分裂点。通常,这可能导致次优结果。然而,这是标准的保证,即如果我们继续降低我们的目标,我们仍然可以得到正则化增强的收敛(参见原始论文的更多讨论和参考)。
实验结果
作者使用 CIFAR-10 数据集将他们的方法应用于一些图像分类任务。他们比较了两种调整神经网络的标准方法:在结构+学习参数(NN)上进行随机网格搜索,并应用贝叶斯优化来帮助搜索相同的超参数空间(NN-GP),这是一种为亚马逊 SageMaker 提供动力的 HPO 过程。
笑点是 AdaNet 表现更好。但是,请观察这些不同方法针对不同图像分类任务所采用的最终结构:

在这些例子中,NN 和 NN-GP 总是选择一个层。这也是 AdaNet 的情况,除了区分猫和狗,它们生长了第二层。这符合我们的直觉,即这将是一项比区分鹿和卡车更复杂的任务。有趣的是,在大多数情况下,AdaNet 的网络规模比其他方法要小,但在性能上仍优于其他方法。
最后,作者在标准点击预测数据集上比较了 AdaNet 和 GP-NN,这是一项具有挑战性的分类任务。(贝叶斯优化也被应用于 AdaNet 的超参数搜索)。在这种情况下,GP-NN 选择了四个各有 512 个单元的隐藏层。AdaNet 能够使用 512 个单元的单层实现更好的性能。
结论
这项工作采取了一种有趣的方法,因为它直接试图量化/最小化泛化误差的估计。令人惊讶的是,这被证明是一项可学习的任务,它基于训练误差和子模型复杂性来调整应用于集成子模型的权重,而子模型复杂性又取决于它们的结构。与简单的搜索算法相结合,这使我们能够自适应地生成神经网络结构,以便为手头的问题找到正确的模型复杂性水平。
然而,这种方法不是免费的。我们仍然需要通过使用维持集来调整超参数,例如学习速率、节点/层的起始数量、复杂性损失的强度等等。但是,这个过程往往会学习更好的表现和更有效的结构。通过直接最小化泛化误差,我们可以对模型结构做出更有原则的决定,而不是例如选择不必要的大模型,并试图通过间接方法来调整我们的过度拟合。
要亲自尝试,请查看官方回购。
最初发表于T5【https://blog.zakjost.com】。
适应或死亡:为什么你的业务战略是失败的数据战略
几年前,我接到一位对冲基金分析师的电话,他正在寻找外部数据,用他的话说,就是提供“阿尔法值”。我解释说,我们公司连接到数千个数据源和数十万个公共数据集;我告诉他,我们正在不断地从 70 个国家获取开放数据,通过一个针对世界上最大的公共数据目录进行训练的摄取管道来实现标准化,并通过一套直接插入任何生态系统的 API 来提供这些数据。

有一个短暂的停顿,分析师说,“我都知道。你有什么我没有的吗?”
这让我很惊讶。“你是在告诉我,你已经在下载和处理来自美国每个公共机构和市政当局的数据了吗?”
“不,但我可以。很容易得到那种东西。我想要别人没有的东西。”
这不会是我最后一次听到有人这么说。认为公共数据易于访问的错误观念定义了开放数据运动的第一个十年,这对那些实际上试图使用它来做出明智商业决策的人非常不利。实际上,公共数据不容易访问,也不容易使用。我们称之为 可用和可用之间的差异,这是采用的一个重大障碍。
对于现代企业来说,有效地访问和使用数据无疑是非常重要的。无论是组织内部生成的数据、政府公开数据,甚至是其他企业发布的数据,通过将这些信息流导入分析模型或应用程序,都可以释放大量价值。面对如此多的新数据,高管们都迫不及待地想要获取新数据,因为他们知道谁创新最快,谁就能从适应不够快的人那里抢走市场份额。
这种对创新的关注导致组织雇用了大量数据科学家和分析师,他们的任务是创建可用于推动商业智能的新产品、服务和应用。
那么问题出在哪里?
问题在于业务部门基于结果的思维和数据科学家的现实之间的脱节。当你雇佣了一队数据科学家时,“创新”是被期待的,但在基层,他们所做的工作中只有一小部分可以被认为是开创性的。大多数时候,数据科学家都在为我在对冲基金的量化朋友认为很简单的事情而努力:获取数据,提炼数据,并将其插入应用程序。
由于处理数据的困难,我们看到人们对数据项目越来越不满意。炒作是有的,人才是有的,但结果却不是。由于有效使用数据的操作障碍,数月甚至数年的工作变成了无法生产的想法。这对数据科学家来说是令人沮丧的,对高管来说是一个紧迫的业务问题。
形势看起来很严峻。2016 年,Gartner 估计 60%的大数据项目失败,一年后 Gartner 分析师 Nick Heudecker 表示 这一数字可能接近 85% 。不管你的钱包有多鼓,没有一个正常的企业会一直把钱砸在一个每五次就有四次失败的东西上。
现实情况是,为了创新,所有企业都必须优化其数据战略。
从管理的角度来看,优化始于沟通。首席管理人员和数据科学部门之间需要更好的对话。运营目标应该明确,数据科学家必须获得有效完成工作所需的资源。拥有数据战略是朝着正确方向迈出的一步,但它已经实施了吗?想要数据驱动是不够的,你还需要了解这需要什么,并为你的团队提供工具和支持,使他们能够将想法投入生产。
优化数据基础架构的第二种方法是加快耗时的数据管理任务,这些任务一直困扰着各地的数据部门。
在理想情况下,数据科学家有权进行实验和尝试想法,但在操作上这通常是不可能的。寻找、收集、标准化、提炼和整合数据花费的时间太长了。这个操作陷阱的结果是两种情况之一:
- 想法来自高层,高管们决定关键目标,并把他们的数据部门扔给他们;或者
- 数据科学家在受控环境中工作,使用合成的小数据来测试模型。
在第一种情况下,数据科学家缺乏所有权,并被束缚在可能不可行的项目上。在第二种情况下,好的想法和体面的模型往往在它们被放入现实世界的那一刻就失败了。
通过采用 DataOps 框架并找到自动化收集数据的准备和处理阶段的方法,数据科学家将能够更快地测试和评估想法,并确保他们的模型可以投入生产。这将导致产出增加,从而带来更好的业务成果。优化会带来创新。
最近,我在和一个想开始使用公共数据的人开会。我向他介绍了这个平台,并解释了获取和集成数据的步骤。
他耸耸肩。“我的数据团队可以做到这一切。”
这次我准备好了。”那么他们为什么没有呢?
【https://blog.thinkdataworks.com】最初发表于。****
使用 PyTorch 的自适应和循环学习率

Photo by Sirma Krusteva on Unsplash
学习率(LR)是调整神经网络的关键参数之一。具有自适应学习率的 SGD 优化器已经流行了一段时间:Adam、Adamax 和它的老兄弟们通常是事实上的标准。它们消除了手动搜索和安排你的学习速度(如衰减率)的痛苦。

Source: Jeremy Jordan’s blogpost
这篇文章将给出一个简短的例子,概述和比较最流行的自适应学习率优化。我们将使用 PyTorch,时髦的神经网络库的选择!

除此之外,fast.ai 还宣扬了循环学习率(CLR)的概念,提到了莱斯利·史密斯的伟大论文(链接)。我们将看看 SGD 如何与其他优化程序相抗衡。
为了演示,我们将承担两项分类任务:
- 基于普通 CNN 架构的图像分类
- 使用预训练(在 ImageNet 上)的 ResNet34 网络进行图像分类
该职位的所有代码和培训日志可以在 GitHub 上找到。
数据
在这篇文章中,我们将使用 Kaggle 的“鲜花识别”数据集(链接)。这是一个很好的测试图像分类网络的基本真实数据集。

example image of the class ‘dandelion’
使用 20%进行验证的数据被平均分配到 5 个类别中进行预测:
自适应优化器
在不深入研究每一个优化器的数学原理的情况下,这里有一个简短(有点过于简单)的概述,介绍一下我们将要与之对抗的优化器:
- Adagrad :这将根据梯度的过去历史,缩放每个参数的学习率。本质上:大梯度= >小α,反之亦然。然而不利的一面是学习率会很快下降。
- Adadelta :在 Adagrad 上继续,但是有了新的花样:只存储过去的 w 渐变而不是整个历史,(现在有限的)历史存储为衰减的平均值。
- RMSProp :有点类似(请不要向我开枪,辛顿先生,先生),但是 RMSProp 将 LR 除以梯度平方的指数衰减平均值。
- Adam :除了存储历史梯度平方和,它还计算过去梯度的指数衰减平均值(类似于动量)。
- Adamax :这里,另一个技巧应用于平方梯度 v(t)的移动平均值,作者应用无穷范数ℓ∞来获得新的范数约束向量 v(t),将其插入 Adam,从而获得令人惊讶的稳定算法。

👉提示:如果你正在寻找优化者的更深入的数学比较,看看 Sebastian Ruder 的这篇精彩的博客文章,它对我写这篇文章有很大帮助。
循环学习率
CLR 的论文提出了两个非常有趣的观点:
- 它为我们提供了一种在训练过程中有效安排学习速率的方法,即以三角形的方式在上限和下限之间变化。
- 这给了我们一个非常合理的估计,哪个学习率范围最适合你的特定网络。

这里有许多参数可供选择:
- 步长:LR 从下限上升到上限需要多少个历元。
- max_lr :调度中最高的 lr。
- base_lr :进度表中最低的 lr,实际上:本文作者建议将此取比 max_lr 小一个因子 R。我们的利用系数是 6。
当然,很难分析出这种方法行得通的确切原因。LR 的发展可能会导致网络在短期内出现更高的损耗,但这种短期的缺点在长期内证明是有利的。如果当前的网络不太稳定,它可以让网络跳到另一个局部最小值。

Source: Snapsshot Ensembles (https://arxiv.org/abs/1704.00109)
CLR 优于上述自适应方法的另一个优点是计算量较小。
在论文中,还提到你可以随着时间线性或指数递减上界,但这在这篇博文中没有实现。
那么这在代码中是如何工作的呢?…
第一步:找到上面的 LR
以一个普通的 CNN 为例:第一步是为你的模型计算学习率的上限。做到这一点的方法是:
- 定义一个初始学习率,即您想要测试的范围的下限(假设为 1e-7)
- 定义范围的上限(假设为 0.1)
- 定义一个指数方案来逐步完成这个过程:

Used formula for the LR finder scheduling (N = number of images, BS = Batch Size, lr = learning rate)
幸运的是,PyTorch 有一个 LambdaLR 对象,它允许我们在 lambda 函数中定义上述内容:
- 接下来,在你的网络中运行(我用了两个纪元)。在每个步骤(每个批量):获取 LR、获取损失并优化梯度:
👉注意:我们不是在每一步取“原始”损失,而是平滑损失,即:损失= α。损耗+ (1- α)。以前的损失
在此之后,我们可以清楚地看到 LR 遵循一个很好的指数规律:
基本网络的损耗-lr 曲线(见下文)如下所示:
我们可以清楚地看到,过高的 LR 会导致网络损耗发散,过低的 LR 根本不会导致网络学习太多…
在他的 fast.ai 课程中,杰瑞米·霍华德提到一个好的上限并不在最低点,而是向左 10 倍。
考虑到这一点,我们可以说学习率的一个好的上限是:3e-3。
根据这篇论文和其他资料,一个好的下限是上限除以因子 6。
步骤 2: CLR 调度程序
第二步是创建一个循环学习时间表,它在下限和上限之间改变学习速率。
这可以通过多种方式实现:

Various possibilites for the CLR shape (source: jeremy jordan’s blog)
我们要用简单的三角 CLR 时间表。
以编程方式,我们只需要创建一个自定义函数:
第三步:包装
在步骤 3 中,这可以被包装在 PyTorch 中的 LambdaLR 对象中:
训练
在一个时期内,我们需要使用'更新 LR。scheduler 对象的“step()”方法:
对比 1:香草 CNN
首先是使用普通的(非预训练的)CNN 进行分类。我使用了以下网络架构:
为了防止模型过度适应(相对较小的)数据集,我们使用以下技术:
- 线性图层中的丢失
- CNN 块中的 Batchnorm 层
- 数据扩充:
👉提示:你需要提前计算通道标准化的均值和标准差,查看完整的笔记本,看看如何解决这个问题。
我们为 6 个优化器中的每一个训练了 150 个时期的网络。为了消除一些可变性,我们为每个优化器运行了 3 次。
训练和验证准确性看起来像这样:
Training accuracy
Validation accuracy
好了,孩子们,我们在这里能看到什么:
👉阿达格拉德:平庸的表现,正如所料
👉阿达德尔塔:在 acc 训练中不是真正的冠军,但在验证中表现非常出色
👉RMSProp:除非我在这里做错了什么,否则我对糟糕的表现感到有点惊讶
👉亚当:一直很好
👉Adamax:有希望的训练精度发展,但没有完美地反映在验证精度上
👉带 CLR 的 SGD:训练精度收敛快得多,验证精度收敛快,不算太差…
最终,SGD+CLR、Adam 和 Adadelta 似乎都以大约 83%的最终验证准确率结束。
对比二:Resnet34 迁移学习
如果你说:“小数据集上的图像分类”,你需要考虑迁移学习。
所以我们就这么做了,使用 Resnet34,在 ImageNet 上进行预训练。我相信数据集相当接近 Imagenet 图片,所以我只解冻了 5 个卷积块的最后一个块,并用新的线性层替换了最后一个线性层:
对于 6 个优化器中的每一个,网络被训练 100 个时期(由于更快的收敛):
Training accuracy
Validation accuracy
此处有重要提示:
👉总的来说:优化器之间的差异要小得多,尤其是在观察验证准确性时
👉RMSProp:仍然有点表现不佳
👉SGD+CLR 在训练准确性方面再次表现良好,但这并没有立即反映在验证准确性上。
对于迁移学习来说,调整学习速度和仔细选择优化器的绝对回报似乎不太大。
这可能是由于两个主要影响:
- 网络权重已经大大优化
- 优化器通常只能优化整个网络权重的一小部分,因为大部分权重保持冻结
结论
这篇博文的主要观点是:
不要只是采用任何旧的现成的优化程序。学习率是最重要的超参数之一,因此仔细研究它是值得的。如果你想比较,看看 SGD 的 CLR 时间表。
再次声明:所有代码都可以在这里找到,可以随意查看!
资料来源和进一步阅读
- https://arxiv.org/abs/1506.01186
- https://www . data camp . com/community/tutorials/cyclic-learning-neural-nets
- https://medium . com/@ Li Peng 2/cyclic-learning-rates-for-training-neural-networks-4de 755927 d46
- http://ruder . io/optimizing-gradient-descent/index . html # momentum
- http://teleported.in/posts/cyclic-learning-rate/
Matlab/Simulink 中传感器融合的自适应巡航控制

最近,我试图使用 Matlab/Simulink 工具箱运行一些先进的驾驶辅助系统(ADAS)测试台。近年来,Matlab 发布了自动驾驶工具箱,结合最近流行的机器/深度学习技术,使得单个 ADAS 功能的开发变得更加简单。
在我继续讲下去之前,必须先对相关主题做一个简短的总结。
目标检测
关于这个问题有大量的教程和例子。可以使用 Tensorflow API 或 Matlab/Simulink 计算机视觉工具箱利用各种类型的传感器数据,例如 3D 激光雷达云点和/或从相机拍摄的图片,从相机视频流中检测物体。
即使通过 ML/DL 技术有可能检测到目标,它仍然远离甚至简单的 ADAS 功能开发。由于 ADAS 或自动驾驶汽车必须首先在传感器数据的帮助下正确地解释现实世界,因此它还应该具备思考、规划和反应的能力,更具体地说是对汽车的控制。
模型预测控制
基于简单的自行车模型,运动学和动力学控制方程可以馈入 MPC 算法。



模型预测控制只是控制技术中的一种,由于具有多输入/输出以及约束的优化能力,它在 ADAS 开发中越来越受欢迎。对于线性时不变(LTI)控制系统,连续状态空间模型可以描述为

continuum state-space model. A, B, C D are constant state space matrices. x is state vector, y the output, u the input/control variable.
基于一个简单的自行车模型,状态函数可以写成

Vy,dot_Vy 用于横向控制,psi,dot_psi 用于转向控制,Vx,dot_Vx 用于纵向控制。详细信息可从 Matlab 文档页面找到。
Matlab 中有一个关于 MPC 的简短的网络研讨会,可以帮助理解背后的算法。MPC 的主要思想是对未来的工厂输出进行预测,优化器找到最优的控制输入序列,使工厂输出尽可能接近设定值。

例如,下图显示了在十字路口转弯的典型场景。MPC 将考虑道路图的曲率,并最小化道路图和工厂路径之间的误差。MPC 的主要优点之一是具有硬/软约束能力的多输入和多输出,这使得它非常适合于 ADAS 函数中的控制策略。

既然我们已经从对象检测技术和 MPC 策略中获得了输入,那么我们可以开始使用 Matlab/Simulink 工具箱来构建玩具模型。
关于前面提到的 MPC,重要的一点是它只对慢动作 senario 有效。当处理高速情况时,必须使用离散 MPC 技术。
自适应巡航控制系统
此处显示的示例演示了这样一个场景:自我车前面的一辆车从右侧切入自我车的车道。雷达和摄像头传感器检测并确认前车。出于安全原因,自车必须估计与前车的相对距离,如果该距离小于允许距离,则自车必须刹车并保持安全距离,直到完全停止。直到/当前面的车远离时,然后自我车逐渐加速,直到达到期望的速度。

ACC with sensor fusion function
在该测试台中,ACC 传感器融合模块具有这样的功能:检测在同一车道(以及在传感器检测范围内的其他车道)是否有领先车,融合检测结果(去除冗余),将检测结果传递给 MPCMPC 相应地减慢/加速 ego 汽车。

输入参数是视觉和雷达探测目标、模拟时间、自车的纵向速度和道路曲率。传感器融合和跟踪引导车子模块包含由于来自雷达的噪声而导致的第一次雷达检测聚类,然后将来自视觉和雷达的检测组合起来传递给多目标跟踪器。使用卡尔曼滤波器精确估计检测状态,并融合检测。然后,使用确认的轨迹和道路信息来确定本车和引导车之间的相对距离和相对速度,这将用于 ACC。

连同相对距离和相对速度,time_gap(驾驶员的反应时间?)使用 MPC 方案将纵向速度和驾驶员设定速度馈入自适应巡航控制系统。在该测试台中,使用了预建的 ACC 控制模块。也有可能建立用户特定的 MPC 模块,这里有一个教程如何这样做。该 ACC 模块的主要功能是跟踪驾驶员设定的速度,并通过调整本车的纵向加速度来保持与前方车辆的安全距离。该模块使用模型预测控制(MPC)计算最佳控制动作,同时满足安全距离、速度和加速度约束。算法结构的细节如下所示。然后,用户可以相应地从 Matlab 修改原始 ACC 模块。

Adaptive Cruise Control using Model Predictive Control
到目前为止,主要的 ACC 控制已经基本完成。然而,当在道路上驾驶时,驾驶员也必须始终保持在车道上。因此,车道跟踪功能,换句话说,转向控制也必须考虑。道路(地图)信息必须与 MPC 调节的纵向加速度一起输入车辆和环境 Simulink 模块。在当前的测试案例中,道路几何形状通过恒定曲率 1/R 进行简单描述,并且已经在 Matlab 的工作空间中创建,可以从子系统中直接使用。

Using the MPC regulated longitudinal acceleration and curvature of the road to update the position and yaw angle of the ego car. The steering control is achieved via PID control.
与 MPC 调节的 ego 汽车加速度一起,通过比例-积分-微分 (PID)控制方案实现转向控制。

基于带力输入的自行车模型,对自主车的位置和横摆角进行了仿真。
到目前为止,我们已经具备了运行 ACC 模拟所需的所有要素。单击 run 按钮,可以从鸟瞰范围查看结果,如下所示,仅显示一帧。

整个模拟结果看起来像
从视频中我们可以看到,当一辆速度较低的汽车切入速度较快的自我车的车道时,只要传感器检测到这种领先的汽车,在 MPC 控制的帮助下,自我车首先减速以保持安全距离。当前车离开同一车道时,本车再次加速,直到达到驾驶员设定的速度。自我车辆的速度和驾驶员设定速度如下图所示。还示出了自我车辆的相对距离和加速度曲线。

最后但同样重要的是,这种 ADAS 必须用 C 或 C++部署到特定的 ECU 上,Matlab 提供了代码生成器工具箱来轻松完成这一任务。如果需要添加或修改更多的 C 算法,那么可以基于生成的 C/C++代码继续工作。
到目前为止,我已经回顾了 Matlab/Simulink 实现的 ACC 测试 bensch。可以正确地恢复主要功能。对于更复杂或不同的驾驶场景,用户可以使用这里描述的类似时间表进行进一步的功能开发。
使用 Google Dialogflow 和 Vision API 为您的聊天机器人添加图像识别功能

对话式人工智能的使用案例多种多样。它们包括客户支持、电子商务、控制物联网设备、企业生产力等等。用非常简单的术语来说,这些用例涉及用户问一个特定的问题(意图),以及对话体验(或聊天机器人)通过调用后端系统(如 CRM、数据库或 API)来响应该问题。这些“意图”通过利用自然语言处理(NLP)和机器学习(ML)来识别。
事实证明,这些用例中的一些可以通过允许用户上传图像来丰富。在这种情况下,您会希望对话体验基于该图像中的确切内容采取行动。
让我们想象一个电子商务客户支持示例:如果您提供自动退款,那么您会要求用户上传收据的图像,将图像发送到预先训练的 ML 模型,从图像中提取文本,从文本中识别购买日期,查看它是否符合退款窗口,然后处理退款或拒绝退款。
让我们想象另一个支持示例:您的硬件产品要求客户遵循一些设置步骤,如果他们遇到问题,他们会求助于聊天机器人,聊天机器人会要求他们上传设备的图像,图像会被发送到预先训练的 ML 模型,该模型会识别问题可能是什么,并通过聊天机器人将其反馈给用户。
介绍

The chat experience that you will build as a part of this tutorial
在本教程中,您将学习如何将 Dialogflow 与 Vision API 集成在一起,以便对用户提供的图像输入做出丰富的、动态的基于 ML 的响应。您将创建一个简单的聊天机器人应用程序,该应用程序将图像作为输入,在 Vision API 中对其进行处理,并将识别出的地标返回给用户。见下图。
- 您将创建一个 Dialogflow 代理
- 实现一个 django 前端来上传文件
- 实现 Dialogflow fulfillment 以针对上传的图像调用 vision API。就像下图一样。
这里的是解释接下来步骤的视频。
架构概述
我们正在创建一个自定义 Django 前端的对话体验,并将其与 Vision API 集成。我们将使用 Django-framework 构建前端,在本地运行并测试它,然后在 Google App Engine 上部署它。前端将如下所示:
请求流将是:
- 用户将通过这个前端发送一个请求。
- 这将触发对 Dialogflow DetectIntent API 的调用,以将用户的话语映射到正确的意图。
- 一旦检测到“探索地标”意图,Dialogflow fulfillment 将向 Vision API 发送请求,接收返回的响应并将其发送回用户。

整体架构:

Architectural Overview
什么是谷歌云视觉 API?
谷歌云视觉 API 是一个预先训练好的机器学习模型,有助于从图像中获得洞察力。您可以获得包括图像标记、人脸和地标检测、光学字符识别(OCR)和明确内容标记在内的洞察。此处是链接,以更具体地了解 Vision API。
创建对话流代理
- 转到对话流控制台。
- 登录,如果你是第一次使用,然后使用您的电子邮件注册
- 接受条款和条件,您将进入控制台
- 创建一个代理。要创建,单击左侧窗格中的下拉菜单,以查看“创建新代理
- 称之为“VisionAPI”
- Dialogflow 为你创建了一个 Google Cloudproject 来访问日志,云功能等。您也可以选择一个现有的项目。
- 准备好后,点击创建。
- 作为代理的一部分,Dialogflow 创建了两个默认意图。默认欢迎意图有助于问候您的用户。默认的回退意图有助于捕捉机器人不理解的所有问题。
在这一点上,我们有一个向用户问候的功能性机器人。但是我们需要稍微更新一下,让用户知道他们可以上传一张图片来探索地标。
更新默认欢迎意向以通知用户上传图像
- 点击“默认欢迎意向”
- 将“回复”更新为“嗨!可以上传一张图探索地标。”

创建实体
- 点击“实体”
- 创建一个新实体,命名为“文件名”和“保存”。

创建新意图
- 点击“意图”
- 将其命名为“探索上传的图像”
- 点击“训练短语”,添加“文件是 demo.jpg”和“文件是 taj.jpeg”,以@filename 作为实体。

- 点击“回复”并添加“评估文件”作为文本回复
- 点击“履行”并切换“为此目的启用 webhook 调用”

设置实施以与 Vision API 集成
- 导航到对话流代理“VisionAPI”并单击“实现
- 通过切换开关启用内联代码编辑器。
- 用下面的代码更新 index.js 文件,并用您的存储桶的名称更新您的-BUCKET-NAME。
- 单击 package.json 并粘贴以下内容以替换其内容。
- 点击页面底部的部署。
下载并运行前端应用程序
- 将此存储库克隆到您的本地机器:https://github . com/priyankavergadia/vision API-dialog flow . git
- 转到包含代码/的目录。或者,您可以下载 zip 格式的示例并解压缩。
设置您的本地环境
部署时,您的应用程序使用内置于应用程序引擎环境中的云 SQL 代理与您的云 SQL 实例进行通信。但是,要在本地测试您的应用程序,您必须在您的开发环境中安装并使用云 SQL 代理的本地副本。点击了解更多关于云 SQL 代理的信息。要在云 SQL 实例上执行基本的管理任务,可以使用 MySQL 客户端。
注意:您必须认证 gcloud 才能使用代理从本地机器连接
安装云 SQL 代理
下载并安装云 SQL 代理。云 SQL 代理用于在本地运行时连接到您的云 SQL 实例。
下载代理服务器:
curl -o cloud_sql_proxy [https://dl.google.com/cloudsql/cloud_sql_proxy.darwin.amd64](https://dl.google.com/cloudsql/cloud_sql_proxy.darwin.amd64)
使代理可执行:
chmod +x cloud_sql_proxy
创建云 SQL 实例
- 为 MySQL 二代实例创建一个云 SQL。命名实例“民意测验实例”或类似。实例准备就绪可能需要几分钟时间。实例准备好后,它应该在实例列表中可见。请确保创建第二代实例。
- 现在使用 Cloud SDK 运行以下命令,其中[YOUR_INSTANCE_NAME]表示您的云 SQL 实例的名称。记下为 connectionName 显示的值,以供下一步使用。connectionName 值的格式为【项目名称】:【区域名称】:【实例名称】
gcloud sql instances describe [YOUR_INSTANCE_NAME]
- 或者,您可以通过单击实例从控制台获得连接名称

初始化您的云 SQL 实例
- 使用上一步中的 connectionName 启动云 SQL 代理。
./cloud_sql_proxy -instances=”[YOUR_INSTANCE_CONNECTION_NAME]”=tcp:3306
- 将[您的实例连接名称]替换为您在上一步中记录的连接名称的值。
- 这一步建立了从本地计算机到云 SQL 实例的连接,用于本地测试。在本地测试应用的整个过程中,保持云 SQL 代理运行。
接下来,创建一个新的云 SQL 用户和数据库。
- 使用 Google CloudConsole 为您的云 SQL 实例 polls-instance 创建一个新数据库。例如,您可以使用名称民意测验。

- 使用 Google CloudConsole 为您的云 SQL 实例 polls-instance 创建一个新用户。

配置数据库设置
- 打开 mysite/settings-changeme.py 进行编辑。
- 将该文件重命名为 setting.py
- 在两个地方,将[您的用户名]和[您的密码]替换为您之前在步骤“创建云 SQL 实例”中创建的数据库用户名和密码。这有助于为 App Engine 部署和本地测试建立到数据库的连接。
- 在“HOST”行中,“cloud SQL/[项目名称]:[区域名称]:[实例名称]”用您在上一步中获取的实例名称替换[项目名称]:[区域名称]:[实例名称]。
- 运行以下命令。为下一步复制输出的 connectionName 值。
gcloud sql instances describe [YOUR_INSTANCE_NAME]
- 将[您的连接名称]替换为上一步中的连接名称
- 用您在“初始化您的云 SQL 实例”步骤中选择的名称替换[您的数据库],然后关闭并保存 settings.py
# [START db_setup]if os.getenv(‘GAE_APPLICATION’, None):# Running on production App Engine, so connect to Google Cloud SQL using# the unix socket at /cloudsql/<your-cloudsql-connection string>DATABASES = {‘default’: {‘ENGINE’: ‘django.db.backends.mysql’,‘HOST’: ‘/cloudsql/[PROJECT_NAME]:[REGION_NAME]:[INSTANCE_NAME]’,‘USER’: ‘[YOUR-USERNAME]’,‘PASSWORD’: ‘[YOUR-PASSWORD]’,‘NAME’: ‘[YOUR-DATABASE]’,}}else:# Running locally so connect to either a local MySQL instance or connect to# Cloud SQL via the proxy. To start the proxy via command line:# $ cloud_sql_proxy -instances=[INSTANCE_CONNECTION_NAME]=tcp:3306# See [https://cloud.google.com/sql/docs/mysql-connect-proxy](https://cloud.google.com/sql/docs/mysql-connect-proxy)DATABASES = {‘default’: {‘ENGINE’: ‘django.db.backends.mysql’,‘HOST’: ‘127.0.0.1’,‘PORT’: ‘3306’,‘NAME’: ‘[YOUR-DATABASE]’,‘USER’: ‘[YOUR-USERNAME]’,‘PASSWORD’: ‘[YOUR-PASSWORD]’}}# [END db_setup]
设置服务帐户
- 在 Dialogflow 的控制台中,进入设置⚙,在常规选项卡下,你会看到谷歌项目部分。单击服务帐户。这将打开谷歌云控制台。

- 在 Google Cloudconsole 中,呈现的网页会显示 Dialogflow 服务账号。点击最右边的“动作部分的 3 个点,然后点击“创建键

- 一个 JSON 文件将被下载到您的计算机上,您将需要在下面的设置部分。
设置要从应用程序调用的 Dialogflow DetectIntent 端点
- 在聊天文件夹内,用自己的凭证 json 文件替换 key-sample.json ,并将其命名为 key.json 。
- 在聊天文件夹的 views.py 中,将 GOOGLE_PROJECT_ID = " <your_project_id>"更改为您的项目 ID</your_project_id>
创建 GCS 存储桶
为前端静态对象创建 GCS 存储桶
- 导航到 Google CloudProject,从汉堡菜单中点击存储

- 点击“创建新存储桶”
- 提供名称—这必须是一个全局唯一的名称

- 选择存储数据的位置—选择“区域”并选择最适合您需求的位置。
- 选择数据的默认存储类别为“标准”

- 选择如何控制对对象的访问,如“在存储桶级别统一设置权限”,然后继续创建存储桶。

- 一旦创建了 bucket,单击“Browser”并找到您刚刚创建的 bucket。
- 单击右侧对应于存储桶的三个点,然后单击“编辑存储桶权限”

- 在显示的侧面板中,单击“添加成员”,然后添加新成员“ allUsers ”,然后单击“选择角色”,添加“存储对象查看器”角色。我们这样做是为了向所有用户提供对静态前端文件的查看访问。对于文件来说,这不是理想的安全设置,但对于这个特定的实验来说,这是可行的。

为用户上传的图像创建 GCS 存储桶
按照相同的说明,创建一个单独的存储桶来上传用户图像。
将权限设置为“所有用户”,并将角色设置为“存储对象创建者”和“存储对象查看者”
在前端应用程序中配置 GCS 存储桶
在 settings.py 中配置 GCS 存储桶
- 打开 mysite/setting.py
- 找到 GCS_BUCKET 变量,并用您的 GCS 静态 BUCKET 替换"
" - 找到 GS_MEDIA_BUCKET_NAME 变量,并用图像的 GCS 存储桶名称替换“
”。 - 找到 GS_STATIC_BUCKET_NAME 变量,并用静态文件的 GCS 存储桶名称替换“
”。 - 保存文件。
GCS_BUCKET = ‘<YOUR-GCS-BUCKET-NAME>’GS_MEDIA_BUCKET_NAME = ‘<YOUR-GCS-BUCKET-NAME-MEDIA>’GS_STATIC_BUCKET_NAME = ‘<YOUR-GCS-BUCKET-NAME-STATIC>’
在 home.html 配置 GCS 存储桶
- 打开聊天->模板-> home-changeme.html
- 将其重命名为 home.html
- 查找
,并将其替换为您希望保存用户上传文件的位置的 bucket 名称。我们这样做是为了不将用户上传的文件存储在前端,并将静态资产全部保存在 GCS bucket 中。Vision API 调用 GCS bucket 来获取文件并进行预测。
在本地构建并运行应用程序
- 要在本地计算机上运行 Django 应用程序,您需要设置一个 Python 开发环境,包括 Python、pip 和 virtualenv。有关说明,请参见为谷歌云平台设置 Python 开发环境。
- 创建一个独立的 Python 环境,并安装依赖项:
virtualenv envsource env/bin/activatepip install -r requirements.txt
- 运行 Django 迁移来设置您的模型:
python3 manage.py makemigrationspython3 manage.py makemigrations pollspython3 manage.py migrate
- 启动本地 web 服务器:
python3 manage.py runserver
- 在你的网络浏览器中,输入这个地址 http://localhost:8000/ 你应该会看到一个简单的网页,上面有文本:“Dialogflow”文本框和提交按钮。

示例应用程序页面由运行在您计算机上的 Django web 服务器提供。当您准备好继续前进时,按 Ctrl+C 停止本地 web 服务器。
将应用部署到应用引擎标准环境
将所有静态内容收集到一个文件夹中。该命令将应用程序的所有静态文件移动到 settings.py 中 STATIC_ROOT 指定的文件夹中:
python3 manage.py collectstatic
通过在 app.yaml 文件所在的应用程序目录中运行以下命令来上传应用程序:
gcloud app deploy
等待通知您更新已完成的消息。
测试在云中运行的前端应用程序
在您的 web 浏览器中,输入以下地址:
https://<your_project_id>.appspot.com
这一次,您的请求由运行在 App Engine 标准环境中的 web 服务器提供服务。
该命令按照 app.yaml 中的描述部署应用程序,并将新部署的版本设置为默认版本,使其为所有新流量提供服务。
生产
当您准备好在生产中提供内容时,在 mysite/settings.py 中,将 DEBUG 变量更改为 False。
测试你的聊天机器人!
让我们用下面的提示来测试我们的聊天机器人
- 用户:“嗨”
- 聊天机器人回应:“嗨!可以上传一张图探索地标。”
- 用户:上传图像。
- 下载一张带有地标的图片,命名为“demo.jpg”
- 聊天机器人回应:“文件正在处理中,这里是结果:XXXX
” - 总体来说,应该是这样的。

清除
确保删除 Google Cloud 项目和 Dialogflow 代理,以避免产生任何费用。
资源和后续步骤
查看我的视频系列 解构聊天机器人 ,在这里我分享如何开始使用 Dialogflow 和谷歌云工具建立对话体验。
参考
Appengine 上的 Dialogflow ,Django app,https://github.com/vkosuri/django-dialogflow
添加这个单词,让你的熊猫申请更快

Image by Karolina Grabowska from Pixabay
易于实现并行化
作为数据科学家,我们有四核、八核和睿频加速的笔记本电脑。我们使用具有更多内核和计算能力的服务器。
但是我们真的利用了我们手头的原始力量吗?
有时,我们会受到我们所掌握的工具的限制。有时我们不愿意为了节省几分钟时间而编写所有无关的代码。后来才意识到时间优化从长远来看是有帮助的。
那么,我们能做得更好吗?
是的,很明显。
以前,我曾经写过如何让你的apply函数更快——使用多重处理,但是由于有了 swifter 库,它现在变得更加琐碎。
这篇文章是关于使用我们手头的计算能力,并使用 Swifter 将其应用于熊猫数据帧。
问题陈述
我们有一个巨大的熊猫数据框,我们想对它应用一个复杂的函数,这需要很多时间。
对于这篇文章,我将生成一些 25M 行 4 列的数据。
可以轻松使用并行化来获得额外的代码性能吗?
import pandas as pd
import numpy as nppdf = pd.DataFrame(np.random.randint(0,100,size=(25000000, 4)),columns=list('abcd'))
数据看起来像:

Data Sample
仅使用一项变更的并行化

Relax and Parallelize !!!
让我们做一个简单的实验。
我们将尝试在数据框架中创建一个新列。我们可以简单地通过在熊猫身上使用 apply-lambda 来做到这一点。
def func(a,b):
if a>50:
return True
elif b>75:
return True
else:
return Falsepdf['e'] = pdf.apply(lambda x : func(x['a'],x['b']),axis=1)

上面的代码运行大约需要 10 分钟。这里我们只是对两列进行简单的计算。
我们能做得更好吗?需要什么?
是的,我们可以做得更好,只要加上一个“神奇的词”——更快。
但是首先,您需要安装 swifter,这很简单:
conda install -c conda-forge swifter
然后,您可以在apply之前导入并附加 swifter 关键字来使用它。
import swifter
pdf['e'] = pdf.**swifter**.apply(lambda x : func(x['a'],x['b']),axis=1)
那么,这行得通吗?

是的。确实如此。与直接使用该函数相比,我们的运行时间提高了 2 倍。
那么这里到底发生了什么?

Source: How increasing data size effects performances for Dask, Pandas and Swifter?
Swifter 为您的函数选择实现 ***apply*** 的最佳方式,方法是对您的函数进行矢量化,或者在后端使用 Dask 来并行化您的函数,或者在数据集很小的情况下使用简单的 pandas apply。
在这个特例中,Swifter 使用 Dask 来并行化我们的应用函数,默认值为npartitions = cpu_count()*2。
对于 MacBook,我使用的 CPU 数量是 6,超线程是 2。因此,CPU 计数为 12,这使得 npartitions=24。
我们也可以选择自己设置 n_partitions。虽然我观察到缺省值在大多数情况下工作得很好,但有时你也可以调整它来获得额外的加速。
例如:下面我设置 n_partitions=12,我们再次获得了 2 倍的加速。这里,减少我们的分区数量会缩短运行时间,因为分区之间的数据移动成本很高。

结论
并行化不是银弹;这是铅弹。
并行化不会解决您的所有问题,您仍然需要优化您的函数,但是它是您的武器库中的一个很好的工具。
时间一去不复返,有时我们也缺少时间。在这些时候,我们需要用一个词来处理并行化。
而那个字就是 更快 。
继续学习
另外,如果你想了解更多关于 Python 的知识,我想向密歇根大学推荐一门优秀的中级 Python 课程。一定要去看看。
将来我也会写更多初学者友好的帖子。在 媒体 关注我或者订阅我的 博客 了解他们。一如既往,我欢迎反馈和建设性的批评,可以通过 Twitter @mlwhiz 联系到我。
此外,一个小小的免责声明——这篇文章中可能会有一些相关资源的附属链接,因为分享知识从来都不是一个坏主意。
将人工智能添加到您的组织中:从神话到现实

在创新方面,没有企业想成为恐龙,而今天,人工智能处于前沿。据估计,80%的企业已经在以某种形式使用人工智能,向人工智能的过渡似乎和从打字机向个人电脑的过渡一样普遍。
尽管大肆宣传,但企业“感觉到”挑战:在最近的一项研究中,91%的公司预见到人工智能采用的重大障碍,包括缺乏 IT 基础设施,以及缺乏人工智能专家来指导过渡。
尽管如此,很少有组织真正理解摆在他们面前的是什么,以及真正需要做些什么来过渡到人工智能侏罗纪时代。让我们更仔细地看看人工智能采用的潜在现实,你的内部人工智能小组或顾问永远不会告诉你。
用例:将传统企业转变为人工智能支持的组织
为了描绘一幅图画,让我们考虑一个假设的公司,全球重工业公司(GHIC)。也许他们的目标是通过在全公司范围内部署人工智能来降低成本,提高生产设施的质量。

该公司制造工业机械,需要熟练工人从零件组装复杂的机械,并有一系列控制检查点来保持生产质量。目前,该过程完全是手动的。
随着最近人工智能意识的提高,加上来自低成本制造商的竞争压力,GHIC 已经制定了一个积极的路线图,通过利用现有的安全摄像头基础设施,在工厂中引入基于视觉的人工智能。
第一步?为他们的模型收集相关数据。
误解 1:我的人工智能需要的所有数据都是免费的
GHIC 面临的第一个障碍是为他们的视觉人工智能收集和准备数据。数据是人工智能的 DNA:神经网络和深度学习架构依赖于导出一个函数来将输入数据映射到输出数据。

这种映射功能的有效性取决于所提供数据的质量和数量。一般来说,拥有更大的训练集已被证明能够在网络中实现更有效的特征,从而导致更好的性能。简而言之,大量高质量的数据导致更好的 AI。
但是公司如何着手生产和准备这些数据呢?收集和标注(或注释)通常是数据准备中最耗时、最昂贵的步骤。此过程使系统能够识别数据中感兴趣的类别或对象,并定义算法部署后应预测的适当结果。
出于隐私或质量方面的考虑,内部注释通常是企业的唯一选择。这可能是因为数据不能离开工厂,或者需要专家进行极其精确的标记。
GHIC 认识到,在相关环境中现场收集和标记数据是建立原型和工作系统的第一个必要步骤。需要收集和标记数百小时的视频,以及数以千计包含健康/缺陷零件的图像,质量控制专家知道生产质量的正常变化和问题之间的区别。因此,处理数据成为一项挑战。应对这一挑战的一种方法是让 GHIC 的人工智能能够持续学习,大幅减少所需的数据和训练时间,并实现人工智能的实时学习和改进。
误区 2:我可以轻松雇佣人工智能专家来构建内部人工智能解决方案
一旦数据准备就绪,第二个任务就是构建 AI 系统的初始实现。这是 GHIC 面临的下一系列挑战。虽然有太多的人工智能工具供开发人员使用,但人工智能专业知识很难找到。据估计,全球大约只有 30 万名人工智能专家(2.2 万名博士)。

毫无疑问,对人工智能人才的需求超过了需求。虽然加速人工智能培训的选择不可行——仍然需要四年才能获得博士学位——但唯一可行的选择是降低门槛,通过引入软件框架来回避对该领域深入知识的需求。否则,组织可能要永远等待才能找到足够的人工智能人才。
误解 3:我有一个概念验证,构建一个最终的人工智能解决方案只是“多做一点工作”
如果 GHIC 开始寻找内部/外部人工智能资源来实现概念验证(PoC),他们可能会认为他们离部署最终解决方案只有几步之遥。

事实上,人工智能的采用需要一个多步骤的方法。对于许多组织来说,第一步是 PoC。在 AI 工作多年后,我看到了无数的 POC 没有实现。为了避免浪费时间和金钱,组织需要设定一个时间表,并提前定义标准,以决定该技术是否应该投入生产。一个简单的基准,如“如果 PoC 提供 X at Y 功能,那么我们将在这里和这里推出它”将大大有助于企业定义一个实际的部署场景。
误解 4:当我从我的人工智能获得良好的性能时,我不再需要接触它
让我们假设 GHIC 克服了上述所有障碍,并成功实现了人工智能。随着时间的推移,GHIC 将面临不断出现的用例或不断变化的条件的挑战,以及及时和廉价地调整其人工智能的需求。

成功的组织放眼未来,询问他们的人工智能解决方案如何随着时间的推移而扩展。随着人工智能系统变得更加复杂,需要数据存储/管理、再培训成本/时间和整体人工智能生命周期管理工具来确保人工智能项目不会变得一团糟,或者更糟,无效。
超越人工智能神话:人工智能不是一次性的,它将一直存在
GHIC 已经艰难地认识到人工智能不是一个简单的一次性项目。相反,这可能会变成一场漫长而昂贵的努力。
为了有效地实施人工智能,企业需要开发混合工程、R&D 和产品的内部团队,这些团队在构建、测试和交付应用程序方面密切合作,并在未来监督维护和迭代。
新工具使越来越多的组织能够采用人工智能。通过夺回对其人工智能战略的控制权,企业团队将能够快速构建人工智能解决方案,在人工智能生命周期中部署和发展它们。
Max Versace 是 Neurala 的首席执行官兼联合创始人。
为多类文本分类模型增加可解释性

ELI5: Image by Sasin Tipchai from Pixabay
ELI5:增加可解释性,但不损失准确性
像我 5 岁一样解释。
对我来说,这是学习的基本原则之一,我试图以一种更容易接受的形式提炼任何概念。正如费曼所说:
我做不到。我不能把它降低到大一的水平。这意味着我们并没有真正理解它。
所以,当我看到旨在解释机器学习模型的 ELI5 库时,我只是必须尝试一下。
在向企业解释我们复杂的机器学习分类器时,我们面临的一个基本问题是。
有时候利益相关者想要理解——是什么导致了特定的结果? 可能是因为手头的任务非常关键,我们不能做出错误的决定。 想象一个基于用户评论采取自动货币行为的分类器。
也可能是对业务/问题空间了解多一点。
也可能是为了增加你的模型的 社会接受度 。
这个帖子是关于解读复杂文本分类模型的。
数据集:
为了解释 ELI5 如何工作,我将使用 Kaggle 上的堆栈溢出数据集。这个数据集包含大约 40000 个帖子和相应的帖子标签。
这是数据集的外观:

下面是不同类别的分布情况。

这是一个平衡的数据集,因此非常适合我们理解的目的。
让我们开始吧。你可以跟随这个 Kaggle 内核中的代码
凝视简单:

让我们首先尝试使用一个简单的 scikit-learn 管道来构建我们的文本分类器,稍后我们将尝试解释它。 在这个管道中,我将使用一个非常简单的计数矢量器和逻辑回归。
*from sklearn.model_selection import train_test_split
from sklearn.feature_extraction.text import CountVectorizer
from sklearn.linear_model import LogisticRegressionCV
from sklearn.pipeline import make_pipeline# Creating train-test Split
X = sodata[['post']]
y = sodata[['tags']]X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=0)# fitting the classifier
vec = CountVectorizer()
clf = LogisticRegressionCV()
pipe = make_pipeline(vec, clf)
pipe.fit(X_train.post, y_train.tags)*
让我们看看我们得到的结果:
*from sklearn import metricsdef print_report(pipe):
y_actuals = y_test['tags']
y_preds = pipe.predict(X_test['post'])
report = metrics.classification_report(y_actuals, y_preds)
print(report)
print("accuracy: {:0.3f}".format(metrics.accuracy_score(y_actuals, y_preds)))print_report(pipe)*

上面是一个非常简单的逻辑回归模型,它表现很好。 我们可以使用下面的函数来检查它的权重:
*for i, tag in enumerate(clf.classes_):
coefficients = clf.coef_[i]
weights = list(zip(vec.get_feature_names(),coefficients))
print('Tag:',tag)
print('Most Positive Coefficients:')
print(sorted(weights,key=lambda x: -x[1])[:10])
print('Most Negative Coefficients:')
print(sorted(weights,key=lambda x: x[1])[:10])
print("--------------------------------------")------------------------------------------------------------
OUTPUT:
------------------------------------------------------------Tag: python
Most Positive Coefficients:
[('python', 6.314761719932758), ('def', 2.288467823831321), ('import', 1.4032539284357077), ('dict', 1.1915110448370732), ('ordered', 1.1558015932799253), ('print', 1.1219958415166653), ('tuples', 1.053837204818975), ('elif', 0.9642251085198578), ('typeerror', 0.9595246314353266), ('tuple', 0.881802590839166)]
Most Negative Coefficients:
[('java', -1.8496383139251245), ('php', -1.4335540858871623), ('javascript', -1.3374796382615586), ('net', -1.2542682749949605), ('printf', -1.2014123042575882), ('objective', -1.1635960146614717), ('void', -1.1433460304246827), ('var', -1.059642972412936), ('end', -1.0498078813349798), ('public', -1.0134828865993966)]
--------------------------------------
Tag: ruby-on-rails
Most Positive Coefficients:
[('rails', 6.364037640161158), ('ror', 1.804826792986176), ('activerecord', 1.6892552000017307), ('ruby', 1.41428459023012), ('erb', 1.3927336940889532), ('end', 1.3650227017877463), ('rb', 1.2280121863441906), ('gem', 1.1988196865523322), ('render', 1.1035255831838242), ('model', 1.0813278895692746)]
Most Negative Coefficients:
[('net', -1.5818801311532575), ('php', -1.3483618692617583), ('python', -1.201167422237274), ('mysql', -1.187479885113293), ('objective', -1.1727511956332588), ('sql', -1.1418573958542007), ('messageform', -1.0551060751109618), ('asp', -1.0342831159678236), ('ios', -1.0319120624686084), ('iphone', -0.9400116321217807)]
--------------------------------------
.......*
这一切都很好。我们可以看到这些系数是有意义的,我们可以尝试使用这些信息来改进我们的模型。
但是上面有很多代码。 ELI5 让这个练习对我们来说相当简单 。我们只需使用下面的命令:
*import eli5
eli5.show_weights(clf, vec=vec, top=20)*

现在你可以看到 Python 的权重值与我们从手动编写的函数中得到的值相同。探索它会更加美丽和有益健康。
但这只是冰山一角。正如我们在下面看到的,ELI5 还可以帮助我们调试模型。
理解我们的简单文本分类模型
现在让我们试着找出为什么一个特殊的例子被错误分类。我使用的例子最初来自 Python 类,但被错误地归类为 Java:
*y_preds = pipe.predict(sodata['post'])sodata['predicted_label'] = y_predsmisclassified_examples = sodata[(sodata['tags']!=sodata['predicted_label'])&(sodata['tags']=='python')&(sodata['predicted_label']=='java')]***eli5.show_prediction(clf, misclassified_examples['post'].values[1], vec=vec)****
**
在上面的例子中,分类器以低概率预测 Java。我们可以检查上面例子中发生的许多事情来改进我们的模型。例如:
- 我们看到分类器考虑了很多数字(不好),这让我们得出清理数字的结论。或者用日期时间标记替换日期时间对象。
- 还可以看到,虽然 dictionary 对 Java 的权重为负,但单词
dictionaries的权重为正。所以也许词干也有帮助。 - 我们还看到像
<pre><code>这样的词正在影响我们的分类器。清洗的时候要把这些字去掉。 - 为什么
date这个词会影响结果?一些值得思考的事情。
我们可以看看更多的例子来获得更多这样的想法。你知道要点了。
深入而复杂
这一切都很好,但是如果我们使用的模型不能像 LSTM 那样提供个体特征的权重呢?正是有了这些模型,可解释性才能发挥非常重要的作用。

为了理解如何做到这一点,我们首先在我们的数据上创建一个 TextCNN 模型。为了节省空间,没有显示模型创建过程,而是将其视为一系列预处理步骤,然后创建深度学习模型。如果有兴趣,你可以看看这个 Kaggle 内核中的建模步骤。
当我们有一个经过训练的黑盒模型对象时,从我们的角度来看,事情变得有趣了。
ELI5 为我们提供了eli5.lime.TextExplainer来调试我们的预测——检查文档中什么是重要的,以做出预测决策。
为了使用[**TextExplainer**](https://eli5.readthedocs.io/en/latest/autodocs/lime.html#eli5.lime.lime.TextExplainer)实例,我们向[**fit()**](https://eli5.readthedocs.io/en/latest/autodocs/lime.html#eli5.lime.lime.TextExplainer.fit)方法传递一个要解释的文档和一个黑盒分类器(一个返回概率的predict函数)。从文档来看,我们的预测函数应该是这样的:
预测 ( 可调用 ) —黑盒分类流水线。
***predict***应该是一个函数,它接受一个字符串(文档)列表,并返回一个带有概率值的形状矩阵***(n_samples, n_classes)***-每个文档一行,每个输出标签一列。
因此,要使用 ELI5,我们需要定义自己的函数,该函数将一系列字符串(文档)作为输入,并返回一个形状为***(n_samples, n_classes)*** 的矩阵。 你可以看到我们是如何先预处理再预测的。
*def predict_complex(docs):
# preprocess the docs as required by our model
val_X = tokenizer.texts_to_sequences(docs)
val_X = pad_sequences(val_X, maxlen=maxlen)
y_preds = model.predict([val_X], batch_size=1024, verbose=0)
return y_preds*
下面给出了我们如何使用TextExplainer。在我们的简单分类器中使用与之前相同的错误分类示例。
*import eli5
**from eli5.lime import TextExplainer****te = TextExplainer(random_state=2019)**
te.fit(sodata['post'].values[0], predict_complex)
te.show_prediction(target_names=list(encoder.classes_))*

这次它不会被错误分类。你可以看到关键字dict和list的出现影响了我们的分类器的决定。一个人可以尝试看到更多的例子,以找到更多的见解。
那么这到底是怎么运作的呢?
[**TextExplainer**](https://eli5.readthedocs.io/en/latest/autodocs/lime.html#eli5.lime.lime.TextExplainer)通过删除一些单词生成大量与文档相似的文本,然后训练一个白盒分类器,预测黑盒分类器的输出,而不是真正的标签。我们看到的解释是针对这个白盒分类器的。
本质上,这有点类似于师生模型的提炼,我们使用一个简单的模型来预测一个复杂得多的教师模型的输出。
简而言之,它试图创建一个简单的模型来模拟一个复杂的模型,然后向我们展示更简单的模型权重。
结论
理解至关重要。能够解释我们的模型可以帮助我们更好地理解我们的模型,从而更好地解释它们。
ELI5 为我们提供了一个很好的方法来做到这一点。它适用于各种模型,这个库的文档是我见过的最好的文档之一。
此外,我喜欢 ELI5 库提供的修饰输出,它以简单快捷的方式解释我的模型。并调试它们。
要在你的模型中使用 ELI5,你可以跟随这个 Kaggle 内核中的代码
继续学习
如果你想学习更多关于 NLP 和如何创建文本分类模型的知识,我想调出 高级机器学习专业化 中的 自然语言处理 课程。一定要去看看。它讲述了许多从初学者到 NLP 高级水平的主题。你可能也想看看我在 NLP 学习系列的 NLP 上的一些帖子。
谢谢你的阅读。将来我也会写更多初学者友好的帖子。在 媒体 关注我或者订阅我的 博客 了解他们。一如既往,我欢迎反馈和建设性的批评,可以通过 Twitter @mlwhiz 联系
此外,一个小小的免责声明——在这篇文章中可能会有一些相关资源的附属链接,因为分享知识从来都不是一个坏主意。
通过概率维度添加新特征
简介:
特征工程是机器学习中的一个重要课题。如果我们想让我们的机器学习,我们需要给它有意义的信息。深度学习架构可能不需要创建良好的功能,因为它们实际上可以自己创建功能。但是,这将需要一个巨大的数据集,也需要大量的计算能力。
对于特征创建,我们需要了解机器学习将处理的主题。如果是信号处理,我们需要了解一下信号处理。如果是金融,我们需要了解一些金融知识,这样我们才会知道我们可以创造哪些特色。
方法:
另一种可以应用于大多数领域的特征是概率。一个值与其他现有值一起存在于一个示例中的概率可能是一个有意义的特征。
示例:假设我们有一个数字图像 0,如下所示。当其他值存在时,我们将创建每个值存在的概率。

Digit 0 Image
我们将创建每个值的概率,并通过增加矩阵的维数来映射它。(表示是用 Python 语言编写的)
- 展平图像。(2D 至 1D) (imgFlat)
- 创建一个具有维度(valueRange,len(imgFlat))的零值矩阵。值域就是我们后面要确定的范围。
- 将 imgFlat 值作为二进制矩阵映射到我们的零值矩阵(我们将在这里确定值的范围。假设我们的取值范围是 10。值范围是我们将映射图像值的范围。图像中的值将被映射到 0 到 10 之间的值。).我们的带有映射值的 imgFlat 是[ 0,3,10,7,2,0,0,6,8,5,8,1,1,7,2,1,7,1,1,5,1,7,1,0,6,3,5,6,0,3,9,7,1,0]。因此,让我们根据 imgFlat 值创建二元矩阵。

Binary Mapping
4.所以,我们拉平了我们的矩阵。然后,我们又增加了一个维度。在这个维度上,我们增加了概率。但是,我们还没有完成。根据我的启发式方法,最好将概率映射到接近概率 1 值的值。因此,我们将得到类似于[0 0.3 0.7 1 0.7 0.3]的值,而不是[0 0 0 1 0 0]。为此,我创建了一个新的概率分布函数。
概率分布函数:
假设我们需要一个有两个根的函数,这个函数的最大输出值是 1。

Probability Distribution Matrix
def distFunc(argmax,xrange,valRange):
x = np.linspace(0,valRange,valRange+1)
a = argmax
b = xrange
y = ((x**2)-(2*x*a)+(a**2)-(b**2))/(valRange**2)
return 1-y
yHist = exposure.rescale_intensity(y)#reason of this line is to distribute our values even more. ([skimage.exposure.rescale_intensity function](https://scikit-image.org/docs/dev/api/skimage.exposure.html#skimage.exposure.rescale_intensity))
为了看清楚,我将数值四舍五入为十进制 1。正因为如此,一些值变成了 1。请忽略它。

Probability Distribution to Binary Mapping
6.概率分布之后,我们展平 2D 概率矩阵。它变得相当大。因此,我将在下面补充其中的一部分。
[1 0.9375 0 0 0.987654 1 1 0 0 0 0 1 1 0 0.987654 0.987654 0 0.987654 1 0 0.987654 0.987654 0 0.987654 1 0 0.816327 0 0 1 1 0.816327 0 0 1 …]
这个结果意味着什么?
毕竟,我们的矩阵代表了下面给出的陈述。
矩阵中第 0 列的值 0 以概率 1 存在,第 10 列的值 8 以概率 1 存在,而第 3 列的值 1 也以概率 0.3 存在,同时…
这给了我们一种情况,我们用它们存在的可能性来赋予我们的价值以意义。
基于 SVM 和概率维特征的数字分类;
图书馆:
import numpy as np
from skimage import exposure
from sklearn.datasets import load_digits
from sklearn import svm
概率分布函数:
def distFunc(argmax,xrange,valRange):
x = np.linspace(0,valRange,valRange+1)
a = argmax
b = xrange
y = ((x**2)-(2*x*a)+(a**2)-(b**2))/(valRange**2)
return 1-y
概率维特征的创建:
def createProbOfVal(kernel,valRange):
kernelFlat = kernel.flatten()
kernelFlat = kernelFlat/np.max(kernelFlat)*valRange
tempBefore = np.zeros((valRange+1,len(kernelFlat)))
tempAfter = np.zeros((valRange+1,len(kernelFlat)))
for cnt in range(len(kernelFlat)):
y = distFunc(int(kernelFlat[cnt]),1,valRange)
yhist = exposure.rescale_intensity(y)
tempBefore[int(kernelFlat[cnt]),cnt] = 1
tempAfter[:,cnt] = yhist
tempBeforeFlat = tempBefore.flatten()
tempAfterFlat = tempAfter.flatten()
return tempAfterFlat
数据集准备(图像到概率维度特征):
def prepareDataset(datasetImages,datasetLabels):
dataset = []
for cnt in range(len(datasetImages)):
processedImage = createProbOfVal(datasetImages[cnt],10)
dataset.append([processedImage,datasetLabels[cnt]])
return dataset
加载并准备数据集:
digits = load_digits()
dataset = prepareDataset(digits.images,digits.target)
创建分类器实例并训练它:
clf = svm.SVC(gamma='scale')
clf.fit([np.array(row[0]) for row in dataset[0:1500]],[np.array(row[1]) for row in dataset[0:1500]])
测试:
preds = clf.predict([np.array(row[0]) for row in dataset[1500:1796]])
score = clf.score([np.array(row[0]) for row in dataset[1500:1796]],[np.array(row[1]) for row in dataset[1500:1796]])
准确率:92%
向 Spark 数据帧添加顺序 id
怎么做,这是个好主意吗?

Photo by Markus Spiske on Unsplash
TL;博士
向 Spark 数据帧添加连续的惟一 id 并不是很直接,尤其是考虑到它的分布式本质。您可以使用 zipWithIndex()或 row_number()来实现这一点(取决于数据的数量和种类),但是在每种情况下都有一个关于性能的问题。
这背后的想法

Typical usages for ids — besides the obvious: for identity purposes
来自传统的关系数据库,如 MySQL ,以及非分布式数据框架,如 Pandas ,人们可能习惯于使用 id(通常自动递增)进行标识,当然,也可以使用它们作为参考来对数据进行排序和约束。例如,按 id(通常是一个索引字段)降序排列数据,将首先给出最近的行,等等。

A representation of a Spark Dataframe — what the user sees and what it is like physically
根据需要,我们可能会发现在 spark 数据帧中拥有一个(独特的)类似 auto-increment-ids '的行为对我们有好处。当数据在一个表或数据帧中时(在一台机器上),添加 id 是非常直接的。但是,当您将数据分散到可能驻留在不同机器(如 Spark)上的分区中时,会发生什么呢?
(更多关于分区的信息,请点击)
在这篇文章中,我们将探索显而易见和不那么显而易见的选项,它们的作用,以及使用它们背后的陷阱。
注释
- 请注意,本文假设您对 Spark 有一定的了解,尤其是对 PySpark 有一定的了解。如果没有,这里有一个简短介绍以及它是什么,我已经在有用链接和注释部分放了几个有用的资源。我很乐意回答任何我能回答的问题:)。
- 再次练习速写,是的,整篇文章都有可怕的速写,试图直观地解释我所理解的事物。希望它们更有帮助,而不是令人困惑:)。
RDD 之路—ziptwithindex()
一种选择是退回到 RDDs
弹性分布式数据集 (RDD),它是跨集群节点划分的、可以并行操作的元素的集合
并使用df.rdd.zipWithIndex():
排序首先基于分区索引,然后是每个分区内项目的
排序。所以第一个分区中的第一个项目得到索引 0,最后一个分区中的最后一个项目得到最大的索引。当这个 RDD 包含
多个分区时,这个方法需要触发一个火花作业。
An example using zipWithIndex

The process of using zipWithIndex()
这里有四点:
- 索引将从 0 开始,并且排序由分区完成
- 您需要将所有数据保存在数据框中— **添加不会添加自动递增 id***
- 退回到 rdds,然后退回到 dataframe 可能会相当昂贵 。
- 带有 id 的数据帧的更新版本将要求您做一些额外的工作以将数据帧恢复到原始形式。这也增加了性能损失。**
你不能真正地更新或添加一个数据帧,因为它们是不可变的,但是你可以把一个数据帧和另一个数据帧连接起来,最终得到一个比原始数据帧有更多行的数据帧。
数据框架方式
如果您的数据可排序
如果您可以按其中一列对数据进行排序,比如我们示例中的column1,那么您可以使用[row_number](https://spark.apache.org/docs/latest/api/python/pyspark.sql.html#pyspark.sql.functions.row_number)()函数来提供行号:
Resuming from the previous example — using row_number over sortable data to provide indexes
row_number()是一个窗口函数,这意味着它在预定义的窗口/数据组上运行。
这里的要点是:
- 您的数据必须是可排序的****
- 你需要使用一个非常大的窗口(和你的数据一样大)
- 您的索引将从 1 开始
- 您需要将所有数据保存在数据框中— 更新不会添加自动递增 id
- 没有额外的工作来重新格式化你的数据帧
- ****但是你可能会以一个 OOM 异常结束,我稍后会解释。
如果您的数据不可排序,或者您不想改变数据的当前顺序
另一种选择是将row_number()与monotonically_increasing_id()结合,根据文档创建:
>生成单调递增的 64 位整数的列。
>生成的 ID 保证是****单调递增且唯一的,而不是连续的。当前的实现将分区 ID 放在高 31 位,将每个分区内的记录号放在低 33 位。假设数据帧有不到 10 亿个分区,每个分区有不到 80 亿条记录。****
单调递增且唯一,但不连续的是这里的关键。这意味着你可以按它们排序,但你不能相信它们是连续的。在某些情况下,你只需要排序,monotonically_increasing_id()就非常方便,你根本不需要row_number()。但是在这种情况下,假设我们绝对需要后续 id。
再次,从我们在代码中留下的地方继续:
Resuming from the previous example — using row_number over initialy non-sortable data to provide indexes
当然有不同的方式(语义上)去做这件事。例如,您可以使用一个临时视图(除了可以使用 pyspark SQL 语法之外,它没有明显的优势):
*****>>> df_final.createOrReplaceTempView(‘df_final’)
>>> spark.sql(‘select row_number() over (order by “monotonically_increasing_id”) as row_num, * from df_final’)*****
这里的要点是:
- 同上,但还有一点要注意,实际上排序是由分区完成的****
这整个努力的最大收获是
为了使用row_number(),我们需要将数据移动到一个分区中。两种情况下的Window(可排序和不可排序的数据)基本上都包含了我们当前拥有的所有行,因此row_number()函数可以遍历它们并增加行号。这可能会导致性能和内存问题——我们很容易崩溃,这取决于我们有多少数据和多少内存。所以,我的建议是,你真的要问问自己,你的数据是否需要一种类似自动递增/索引的行为,或者你是否可以用另一种方式来避免这种行为,因为这将是昂贵的。尤其是当您每次处理任意数量的数据时,因此无法仔细考虑内存量(例如,在组或窗口中处理流数据)。
每当您使用Window时,Spark 都会给出以下警告,而没有提供对数据进行分区的方法:
*******WARN WindowExec: No Partition Defined for Window operation! Moving all data to a single partition, this can cause serious performance degradation.*******

Using row_number() over Window and the OOM danger
结论:这到底是不是一个好主意?
嗯,大概不是。根据我的经验,如果你发现自己需要这种功能,那么你应该好好审视一下你的需求和你的转变过程,如果可能的话,找出解决方法。即使你使用了zipWithIndex(),你的应用程序的性能可能仍然会受到影响——但是对我来说这似乎是一个更安全的选择。****
但如果你无法避免,至少要意识到它背后的机制、风险,并做好相应的计划。
我希望这有所帮助。任何想法,问题,更正和建议都非常欢迎:)
有用的链接和注释
******* [## 用非技术性的方式解释技术性的东西——Apache Spark
什么是 Spark 和 PySpark,我可以用它做什么?
towardsdatascience.com](/explaining-technical-stuff-in-a-non-techincal-way-apache-spark-274d6c9f70e9)
从 0 开始调整指标
使用row_number()时的索引从 1 开始。要让它们从 0 开始,我们可以简单地从row_num列中减去 1:
df_final = df_final.withColumn(‘row_num’, F.col(‘row_num’)-1)
关于 rdd 和数据集
[## 三个 Apache Spark APIs 的故事:RDDs 与数据帧和数据集
总之,选择何时使用 RDD 或数据框架和/或数据集似乎是显而易见的。前者为您提供…
databricks.com](https://databricks.com/blog/2016/07/14/a-tale-of-three-apache-spark-apis-rdds-dataframes-and-datasets.html) [## RDD 节目指南
默认情况下,Spark 2.4.4 的构建和发布是为了与 Scala 2.12 协同工作。(Spark 可以构建为与其他……
spark.apache.org](https://spark.apache.org/docs/latest/rdd-programming-guide.html)
关于 createOrReplaceTempView
这将为您的数据创建一个延迟评估的“视图”(如果该视图名称已经存在,则替换它),这意味着如果您不缓存/持久化它,每次您访问该视图时,任何计算都将再次运行。通常,您可以在 Spark SQL 中使用 hive 表。
[## pyspark.sql 模块- PySpark 2.4.4 文档
schema-py spark . SQL . types . datatype 或数据类型字符串或列名列表,默认值为。数据类型字符串…
spark.apache.org](https://spark.apache.org/docs/latest/api/python/pyspark.sql.html#pyspark.sql.DataFrame.createOrReplaceTempView)
行号和窗口
[## pyspark.sql 模块- PySpark 2.4.4 文档
schema-py spark . SQL . types . datatype 或数据类型字符串或列名列表,默认值为。数据类型字符串…
spark.apache.org](https://spark.apache.org/docs/latest/api/python/pyspark.sql.html#pyspark.sql.functions.row_number) [## Spark SQL 中的窗口函数介绍
在这篇博文中,我们介绍了 Apache Spark 1.4 中添加的新窗口函数特性。窗口功能…
databricks.com](https://databricks.com/blog/2015/07/15/introducing-window-functions-in-spark-sql.html)
接下来去哪里?
理解你的机器学习模型的预测:
[## 机器学习的可解释性——带有 PySpark 的 Shapley 值
解读隔离森林的预测——不仅仅是
medium.com](https://medium.com/mlearning-ai/machine-learning-interpretability-shapley-values-with-pyspark-16ffd87227e3)*******
地址和城镇:使用谷歌地图 API + PhilGIS 进行地理标记
将谷歌地图和 shapefiles 链接到他们的镇(菲律宾版的一个县),以避免痛苦的手动分类的需要
登革热在菲律宾是一个真正的问题。头痛、关节痛、全身皮疹和死亡——这种疾病今年在菲律宾已有 146,000 个病例,并夺走了 622 人的生命。在 17 个地区中,有 7 个地区已经宣布发生了流行病,围绕唯一获得许可的登革热疫苗的使用仍然存在很大争议。
作为防止登革热传播的努力的一部分,由 Wilson Chua 博士领导的蚊子实时普查项目旨在使用卫星数据来识别可能成为潜在登革热热点的死水区域。最终目标是在这些地区放置诱蚊产卵器和传感器,以检测蚊子的存在,并就可能的疫情向官员发出警报。
我的任务是将 6100 个地址映射到奎松市相应的镇。村是菲律宾最小的政府单位,包括从 10 个街区到 30 个街区(甚至更大)的范围。奎松市(大马尼拉地区最大的城市)由 142 个镇组成。

A bunch of barangays crammed like sardines in Manila

And Barangay Pasong Tamo casually sitting there just encompassing 3 villages, a park and a university
最初,这项任务需要手动完成。让事情变得更复杂的是,镇有旧名字和新名字,谷歌地图上出现的一些地区和区域的名字看起来是镇,但实际上不是。有多条街道有相同的名字,而镇镇通常不写在地址上。

幸运的是,Google Maps API 和 PhilGIS 的 barangay shapefiles(祝福你)有所有必要的信息来通过简化这个过程。
方法(快速和无统计)
使用 Python 模块请求,我提取了每个地址的谷歌地图信息,从中提取了纬度和经度。然后,对于每个地址,我检查它的纬度和经度是否在一个镇的区域内,该镇的坐标取自 PhilGIS 的 shapefiles。
对于用谷歌地图和菲尔吉斯找不到的镇,我不得不手动分类。找不到这些地址,因为它们太模糊或有冲突的信息。也许街道与地址中写的城市不匹配,或者建筑物的名称位于不同的街道上。在进行全面的强力搜索之前,我使用可以识别重要地点标识符的关键字标记了每个地址,即:
- 布兰盖:BGY,布里吉
- 村庄:村庄,SUBD,丘陵,家园,高地,HTS
- 项目:PROJ 项目
- 建筑:大楼,公寓,公寓,住宅,住宅
- Road: RD,Road,ST,STR,STREET,DRIVE,EXT,EXTN,SCT,SCOUT
- 大道,大道,道路
对于 Barangay、Project 和 Scout(马尼拉的一组道路),我在它们后面加上了一个单词,以给出这个地方的名称(例如, Barangay Tatalon, Project 4, Scout Chuatoco)。剩下的我就拿他们之前的话(达马尔村,巴纳韦街,草地民居,奎松大道)。
关键词是按照显示的顺序选择的:如果镇名写在地址中,就不需要进一步分类了——因为它已经在那里了!村庄非常具体,项目(住宅小区)和建筑也是如此,因为它们有特定的地址。道路和大道变得更加不具体,因为它们并不总是有特定的数字,而且镇的边界经常在道路/大道上相交,所以不会非常清楚哪个地址通向哪里。这些关键字有助于更快地阅读地址——而不是阅读整个地址,我只需查找村庄或建筑物的具体名称,或者直接复制 barangay,这使得任务更快。
结果
在任何自动化之前,我尝试手动操作。对于每个地址,我平均花了大约一分钟(花了很长时间,因为有些地址缩写怪异,在谷歌地图上匹配多个位置,有模糊的细节,等等。).因此,我需要 102 个小时才能完成。
另一方面,运行整个代码需要大约半个小时,并且它对所有地址的 97%进行了分类。我花了大约 3 个小时来分类剩下的 180 个地址。
该代码可供使用,并可以扩展到整个菲律宾几乎所有其他省份!细节在朱庇特笔记本上。
附录
点击查看代码
采用假设驱动的建模工作流程
用作现代预测建模基础的许多算法使用迭代过程来获得优化的解决方案。对于某些模型类型,如 boosting,每次迭代都要参考前一次迭代的结果。作为一名模型构建者,我寻求实现一个工作流程,该工作流程反映了那些构成我的模型核心的预测算法:由假设决定的不断迭代。
- 不断的迭代允许复杂性慢慢地在基本基线模型之上分层(例如,附加特性、缩放、输入、调整)。
- 一次迭代评估模型的一组目标变更。该过程允许模型构建者评估每组变更对整个模型的影响(仅保留那些具有积极影响的变更)。
- 每次迭代都试图评估模型构建者所持有的假设的有效性。模型构建者的核心工作是形成和检验假设。假设的来源包括以前的经验(什么在过去有效?)、领域专业知识、探索性数据分析和直觉。
当构建预测模型时,我经常陷入的一个陷阱是,没有遵循上述迭代构建过程,就过快地增加了模型的复杂性。增加复杂性而不迭代意味着我失去了对我的假设中哪些是有用的,哪些是不相关的(从而可能增加噪音),以及哪些是有害的粒度理解。这通常会导致许多问题:
- 较慢的迭代:模型运行的计算成本很高,降低了我快速迭代/工作的能力
- 理解力低:我无法解释是什么赋予了我的模型预测能力,降低了我的优化能力。此外,该模型经常是不必要的复杂(例如,更简单的模型将实现类似的性能)
- 更少的想法:我产生好的假设的能力降低了,因为我从模型中得不到太多的反馈(它通常是好想法的来源)
为了展示符合假设驱动迭代理念的工作流的力量,下面的可视化详细描述了我用来构建一个简单模型的迭代过程,该模型旨在预测位于坦桑尼亚的水泵是否正常工作,是否正常工作但需要维修,或者是否正常工作。该数据集是由 DrivenData 主办的正在进行的建模竞赛的一部分。
如下图所示,经过一系列的 10 次迭代,我的模型从 54%精度的多数类基线提高到大约 78%精度。

如图所示,一组相对简单的迭代产生了大约 78%准确度的预测模型(相比之下,原始基线为 54%)。作为我工作流程的一部分,对于每一次迭代,我都会详细说明:
- 假设:我在用这个迭代测试什么信念?
- 行动:我要采取什么行动(改变模型)来测试假设?
- 结果:这对模型有什么影响?
- 洞察力:假设正确吗?这个迭代如何通知未来的迭代?
下面的屏幕截图显示了我用来支持创建水泵状态预测模型的表格:

老实说,我在构建这个模型时的第一次尝试并没有坚持通过不断迭代将复杂性分层到模型中的理论。更确切地说,我很少迭代,导致迭代之间的许多变更降低了我评估每个变更有效性的能力。虽然模型的性能相似,但迭代过于复杂且计算量大(降低了我测试假设的能力)。此外,我并不清楚为什么这款车型表现出色。
由于我的原始模型的复杂性,我最终不得不重新开始来增加我快速实验的能力。采用上述过程最终实现了更高性能、更轻的模型。
总之,虽然很容易给模型增加多层复杂性,但是接受不断迭代将提供对模型的更深入理解,产生更有创造性的假设,并产生更简单、更轻便的模型。
高级主动学习备忘单
主动学习是为人类选择最佳未标记数据以供监督机器学习查看的过程。大多数真实世界的机器学习系统都是在数千甚至数百万人类标记的样本上训练的。在这种情况下,如果人类花时间查看正确的数据进行注释,你可以更快地让机器学习模型更准确。
有两种类型的主动学习:不确定性采样和多样性采样。不确定性采样的目标是那些在当前状态下明显使模型混乱的数据,而多样性采样的目标是那些在模型知识中存在缺口的数据。在机器学习的知识象限中,不确定性采样处理已知的未知,多样性采样处理未知的未知:

Knowledge Quadrant for Machine Learning
有关每种主动学习类型的更多信息,请参见前面的备忘单:
用于主动学习的四种常见不确定性抽样策略的快速参考。
towardsdatascience.com](/uncertainty-sampling-cheatsheet-ec57bc067c0b) [## 多样性抽样备忘单
主动学习的四种常见多样性抽样策略的快速参考。
towardsdatascience.com](/https-towardsdatascience-com-diversity-sampling-cheatsheet-32619693c304)
理想情况下,在你尝试实施更高级的主动学习策略之前,你应该亲自尝试实施我的书中的不确定性采样和多样性样本的例子。我的免费 PyTorch 库中也有主动学习算法的清晰示例:
[## rmunro/pytorch_active_learning
图书馆常见的主动学习方法伴随:人在回路中的机器学习罗伯特芒罗曼宁…
github.com](https://github.com/rmunro/pytorch_active_learning)
孤立地使用,不确定性采样方法通常会集中于特征空间的一部分,因此缺乏多样性。如果单独使用,多样性抽样方法通常会发现大多数多样性远离决策边界,因此不会对可能被错误标记的项目进行抽样。因此,大多数现实世界的策略将结合这两种方法来进行主动学习。
你将通过在你自己的数据上执行算法并评估哪种算法最适合你所面临的问题而学到最多。因此,我建议在您亲自尝试过这些方法,并对每种方法在数据上的优缺点积累了实际经验之后,使用这份备忘单作为参考。

Advanced Active Learning: the optimal methods are often the combination of simpler building blocks.
提示:把单独的主动学习方法看作是需要组合的积木
不确定性抽样和多样性抽样结合起来效果最好。虽然关于结合不确定性抽样和多样性抽样的学术论文关注的是结合两者的单一指标,但在实践中,你可以简单地将这些方法串联起来:应用一种方法获得大样本,然后用另一种方法提炼该样本。
这种脱节的原因是机器学习的学术界论文倾向于关注能够端到端完成任务的单一算法,主动学习也不例外。因此,如果你只阅读关于主动学习的学术论文,那么你可能会被误导,认为现实世界中的最佳方法也需要是一个复杂的组合指标。在关于高级主动学习的章节中,我们确实涵盖了将不确定性采样和多样性采样结合到单一方法中的最新方法。然而,我建议首先尝试组合更简单的方法:它们通常对数据来说是最佳的,并且更容易解释和实验。
比较简单的方法应该是比较高级方法的基线,所以无论如何都应该实现它们。
结合不确定性采样和多样性采样的 10 种策略:
- 基于聚类的最小置信度抽样: 对模型中容易混淆的项目进行抽样,然后对这些项目进行聚类,以确保样本的多样性(见下图)。
- 基于模型的异常值的不确定性采样: 对您的模型中容易混淆的项目进行采样,并在这些项目中找到模型中激活度较低的项目。
- 基于模型的异常值和聚类的不确定性采样: 结合方法 1 和 2。
- 典型的基于聚类的采样: 对您的数据进行聚类,以捕捉与您的目标域最相似的多节点分布和样本项目(见下图)。
- 从最高熵聚类中采样: 对你的未标记数据进行聚类,为你的模型找到平均混淆度最高的聚类。
- 不确定性抽样和代表性抽样: 既让你当前模型困惑又最像你目标域的样本项。
- 基于模型的离群值和代表性采样: 在你的模型中激活度低,但在你的目标域中相对常见的样本项。
- 聚类以自身为层次聚类: 递归聚类以最大化多样性。
- 从具有置信区间的最高熵聚类中采样采样: 找到具有最大混淆的聚类,然后在该聚类内对最大成对标签混淆进行采样。
- 将集成方法和漏失与个体策略结合: 通过蒙特卡罗漏失又名贝叶斯深度学习,聚合来自多个模型或来自一个模型的多个预测的结果。

Example of Least Confidence Sampling with Clustering-based Sampling: sample items that are confusing to your model and then cluster those items to ensure a diverse sample.

Example of Representative Cluster-based Sampling: cluster your data to capture multinodal distributions and sample items that are most like your target domain.
有许多不同的方法可以将不同的方法结合起来,以下是 10 种常见的方法。已经实现了几个组合 PyTorch 主动学习库并在书中进行了讨论。大多数组合只是几行额外的代码来组合更简单的方法。所以,你应该能够相对容易地尝试其他组合。
对于现实世界的多样性,您可能需要组合任意数量的这些方法,以最小化来自您的数据的任何偏差。就像这本书推荐的那样,你应该明确地跟踪你所关心的人口统计数据的准确性,并使用关注多样性的准确性度量标准来评估不同的方法。你还应该知道你的模型是否会纠正、反映或放大数据中的偏差,因为这也会改变你的主动学习策略。
下载备忘单:

你可以在这里下载 PDF 版本的 cheat sheet:http://www . Robert Munro . com/Advanced _ Active _ Learning _ cheat sheet . PDF
这份备忘单摘自我的书《人在回路中的机器学习:
https://www . manning . com/books/human-in-the-loop-machine-learning
我的书的章节已经出版了——高级主动学习章节已经出版,下一章将讲述如何将主动学习应用于不同的机器学习任务,如预测文本序列和图像的语义分割。我会一边走一边分享摘录!
罗伯特·芒罗
2019 年 12 月
高级分析很好,但是我们从简单分析开始怎么样?
高级分析!每个人都想要一些,但很少有人需要一些。让我们先从健康的简单分析开始。

From simple analytics to advanced analytics
我知道,我明白了!您对自己的所有数据感到兴奋,并希望立即雇用一名数据科学家,开始对您的数据进行所有高级分析。
然而,在现实中,我不确定这句话的意思是否和你想的一样。停下来思考一下——有人对您的数据进行简单的分析吗?你真的开始挖掘简单的指标来看你的业务是如何运作的吗?作为一名数据科学家,我认为在 90%以上的情况下,听到“高级分析”这个术语的人会认为他们应该加入这个潮流。不幸的是,这可能会浪费你公司的时间和资源,直到你真正需要它。
高级分析的 80/20 法则

80/20 rule of advanced analytics
在这一点上,大多数人都熟悉 80/20 法则,或者帕累托法则。本质上,你从 20%的投入中获得了 80%的收益。对于分析来说也是如此。当你第一次开始了解你的业务并努力开发一种数据驱动的管理方法时,你可以用 20%的努力获得 80%的洞察力。这 20%的努力可以是关于你有多少用户,你做了多少销售,或者你在一段时间内的总收入的基本汇总统计。
高级分析绝对是 80%的努力换来 20%的收益。这就是为什么当你开始时,你肯定不需要高级分析。一旦你用基本工作充分发挥了理解你的业务和客户的能力,只有那时你才应该转向高级分析。
为什么您还不需要高级分析
这个世界只谈论像数据科学和人工智能这样性感的东西。你很少阅读《福布斯》或《商业内幕》上关于简单分析或数据管理等“无聊”内容的文章。然而在现实中,除非你需要细分客户群,从每个客户身上多挤出一点收入,否则你不需要高级分析。

Simple analytics before advanced analytics
我是精益创业运动和最小可行产品(MVP) 的主要理念的超级粉丝。对你的业务来说,分析的 MVP 是简单分析。一旦你开始了解你需要什么样的数据、人员和资源来分析这些数据,那么你就可以继续进行高级分析了。
没有数据的数据科学工作
如果你不相信,让我给你讲个故事。我最近被聘为数据科学顾问,帮助一个组织解决一些业务问题。正如你们许多人所知,数据科学家并不是雇佣成本最低的人。
所以我走进大楼,在我的第一次计划会议上坐下来,问我什么时候可以访问数据…茫然的凝视。
我们以为你会那样做。我们不知道如何处理我们的数据
这正是我的观点。在考虑雇用拥有高学历和昂贵简历的人之前,你需要问自己和你的公司一些简单的分析问题,比如,我们甚至可以访问数据来进行高级分析吗?
最后,是的,你很可能最终会有人全职为你的公司做高级分析,但是请你为自己节省一些时间和金钱,先从简单的分析开始!
我的名字是 亚历山大·泰特斯 我患有旅游癖。我经常陷入沉思,迷失在树林中,而且经常同时迷失在两者之中。我的人生使命是重新定义 职业成功 以包含个人和职业追求的阶段。你可以在LinkedIn,Twitter, 上找到我在网上分享的一些想法 和在 中 。
原载于 2019 年 8 月 17 日 https://alexandertitus.com。
机器学习的高级烛台(一):刻度条
在本文中,我们将学习如何构建分笔成交点,我们将彻底分析它们的统计属性,如回报率的正态性或自相关性,我们将探索在哪些情况下这些棒线可以很好地替代传统的基于时间的蜡烛图。为了说明分笔成交点在预测加密货币市场中的适用性,我们将基于由 16 个加密货币交易对组成的整个数据集进行分析,其中包括最受欢迎的加密资产,如比特币、以太币或莱特币

1.—导言
在之前的一篇文章中,我们探讨了如果我们计划训练机器学习(ML)算法,为什么传统的基于时间的烛台不是最合适的价格数据格式。即:(1)基于时间的蜡烛图过采样低活动期和欠采样高活动期,(2)市场越来越多地被不再遵循任何与人类相关的日光周期的交易算法所控制,(3)基于时间的蜡烛图在交易者和交易机器人中普遍存在,这增加了竞争,正如我们将在本文中看到的,(4)基于时间的蜡烛图提供了较差的统计属性。如果您错过了更新,请找到下面文章的链接。
在这篇文章中,我们将探讨为什么传统的基于时间的烛台是一种低效的方法来汇总价格…
towardsdatascience.com](/financial-machine-learning-practitioners-have-been-using-the-wrong-candlesticks-heres-why-7a3fb85b5629)
在这篇文章中,我们将探讨其中一个建议的替代酒吧:滴答酒吧。让我们深入研究一下。
2.—构建刻度条
关于什么是分笔成交点,至少有两个主要的定义。报价投资媒体:
分笔成交点是衡量证券价格最小上下波动的指标。分笔成交点也可以指一种证券在不同交易中的价格变化。
在分笔成交点的例子中,我们关心的定义是第二个:在分笔成交点的范围内,分笔成交点本质上是一个交易和在交易所进行交易的价格。分笔成交点或分笔成交点蜡烛线只是预定义数量的分笔成交点的集合。例如,如果我们想要生成 100 点棒线,我们必须保存所有交易的数据,每次我们从交易所“收到”100 笔交易,我们就创建一个棒线或蜡烛线。然后通过计算开盘价、最高价、最低价、收盘价和成交量来构建烛台(通常简称为 OHLCV)。

开盘价和收盘价分别对应于第一笔和最后一笔交易的价格。最高价和最低价是蜡烛线中所有交易的最高价和最低价(可能与开盘价和收盘价重叠)。最后,交易量是所有交换资产的总和(例如,在 ETH-USD 对中,交易量以蜡烛线期间交换的以太物数量来衡量)。惯例是,当一根蜡烛的收盘价比开盘价高时,我们把它涂成绿色(或者空着),而如果收盘价比开盘价低,我们就把它涂成红色(或者填满黑色)。
下面是一个非常简单但快速的 Python 实现来生成刻度烛台:
这是与标准的基于时间的烛台相比,刻度条的视觉效果。在这种情况下,我们显示了 BTC-美元交易对的 4 小时和 1000 点棒线,以及 2017 年 1 月 21 日至 2017 年 2 月 20 日之间所有交易的价格。请注意,对于烛台,我们每次对一根棒取样时都会显示一个星号。

关于这些地块的两个主要观察结果:
- 是的,壁虱烛台看起来很丑。它们混乱、重叠、难以理解,但请记住,它们不应该对人类友好:它们应该对机器友好。
- 他们丑的真正原因是因为他们工作做得很好。看看星号,看看在价格变化很大的时期,有更多的星号(和更多的棒线)混杂在一起?而相反:当价格变化不大时,分笔成交点采样要低得多。我们实际上是在创建一个系统,在这个系统中,我们将信息到达市场(更高的活动和价格波动)与烛台的取样同步。我们终于在高活动期采样更多,在低活动期采样更少。万岁!
3.—统计属性
那么它们的统计特性如何呢?它们比传统的基于时间的同类产品更好吗?
我们将关注两个不同的属性:(1)序列相关性和(2)在 CryptoDatum.io,中提供的 15 种加密货币对中的每一种的回报的正态性,包括 Bitfinex 交易所的所有历史棒线,以及基于时间和分笔成交点的棒线大小:
- 基于时间的条形大小 : 1 分钟、5 分钟、15 分钟、30 分钟、1 小时、4 小时、12 小时、1 天。
- 刻度条尺寸 : 50,100,200,500,1000
3.1——序列相关性(也称为自相关)
序列相关度量时间序列中的每个值与下一个值(对于 lag=1)的相关程度,或者任何值 I 与任何其他值 i+n (lag=n)之间的相关程度。在我们的例子中,我们将计算对数回报的序列相关性,这是作为蜡烛收盘价的对数的一阶差来计算的。
理想情况下,我们系列的每个数据点应该是一个独立的观察。如果存在序列相关性,这意味着它们不是独立的(它们在滞后=1 或更高时相互依赖),这将在建立回归模型时产生后果,因为我们在回归中观察到的误差将小于或大于真实误差,这将误导我们的解释和预测。你可以在这里看到这个问题非常形象的解释。
为了测量序列相关性,我们将计算序列相对于移位自身的皮尔逊相关性(滞后=1,也称为一阶相关性)。结果如下:

Pearson auto-correlation
事实证明,分笔成交点(标记为 tick-)通常比基于时间的蜡烛图(标记为 time-)具有更低的自相关性,也就是说,皮尔逊自相关性更接近于 0。对于较大的时间棒线(4h、12h、1d),这种差异似乎不太明显,但有趣的是,即使是最小的分笔成交点(50 分笔成交点和 100 分笔成交点)也产生非常低的自相关性,这对于较小的时间棒线(1 分钟、5 分钟)并不成立。
最后,有趣的是,我们可以看到几种加密货币(BTC、LTC、ZEC 和 ZIL)在几个时间条中表现出相当强的负自相关性。Roberto Pedace 在这里评论了关于负自相关的:
当数据中观察值的顺序相关或重要时,回归模型中可能存在自相关、序列相关、序列相关。换句话说,对于时间序列(有时是面板或纵向)数据,自相关是一个问题。[…] 无自相关是指误差项的值之间不存在可识别关系的情况。[……]虽然不太可能,但负自相关也是可能的。负自相关发生在一个给定符号的误差之后往往是相反符号的误差。例如,正误差之后通常是负误差,负误差之后通常是正误差。
我们将执行一个额外的统计测试,称为 Durbin-Watson (DB)测试,它也诊断序列相关性的存在。DB 统计值在 0–4 范围内,其解释如下:
本质上,越接近 2,序列相关性越低。结果如下:

Durbin-Watson test
结果与 Pearson 自相关测试一致,该测试为以下叙述提供了证据:分笔成交点显示的自相关性略低于基于时间的蜡烛图。
3.2 —回报的正态性
我们可以查看的另一个统计数据是回报的正态性,这是我们的对数回报的分布是否遵循正态(也称为高斯)分布。
我们可以运行几个测试来检查正态性——我们将执行其中的两个测试:测试数据的偏斜度和峰度是否符合正态分布的 Jarque-Bera 测试,以及检验样本是否符合高斯分布的最经典测试之一夏皮罗-维尔克测试。
在这两种情况下,零假设是样本服从正态分布。如果拒绝零假设(p 值低于显著性水平—通常是< 0.05) there is compelling evidence that the sample does not follow a normal distribution.
Let’s look at the p-values for the Jarque-Bera first:

Jarque-Bera p-value
The results are almost unanimous: log returns do not follow a Gaussian distribution (most p-values < 0.05) . Two cryptocurrency pairs (Stellar and Zilliqa) seem to actually follow a Gaussian if we set our significance level at 0.05. Let’s take a look at their distributions (kernel density estimates):


Fair enough, some of them could look Gaussian (at least visually). However, notice that the number of samples (n) is very small (e.g. for XLM-USD candle_tick_1000 n=195) so I suspect that one of the reasons may just be the lack of sampling, which provides Jarque-Bera not enough evidence to reject the null hypothesis of normality.
In fact, a quick look at the CryptoDatum.io 数据库显示,XLM-美元和 ZIL-美元交易对分别在去年(2018 年)5 月和 7 月刚刚发布,它们似乎有相当低的成交量...
谜团解开了?😃
现在让我们进行夏皮罗-维尔克检验,看看它是否与先前的结果一致:

Shapiro-Wilk p-value
该死,夏皮罗,他们没教你在学校考试时不要抄袭吗?不管棒线的类型如何,回报的非正态性似乎是规律。
4.我们学到了什么?
- 通过聚合预定义数量的分笔成交点并计算相关的 OHLCV 值来生成分笔成交点蜡烛图。
- 在图表中,刻度线看起来很难看,但它们做得很好:它们在高活动期采样更多,在低活动期采样更少。
- 与基于时间的蜡烛图相比,即使在小尺寸(50,100 分笔成交点)下,来自分笔成交点的对数回报显示出较低的序列相关性。
- 基于分笔成交点和基于时间的棒线的日志回报都不服从正态分布。
感谢阅读。在接下来的几周,我们将讨论其他类型的高级棒线,如量棒线、美元棒线和(我最喜欢的)不平衡棒线。所以,如果你喜欢这篇文章:敬请期待!
这个项目是我们在cryptodatum . io研究的一部分,这是一个加密货币数据 API,旨在提供即插即用的数据集来训练机器学习算法。如果您喜欢我们在本文中展示的数据,您可以在https://cryptodatum . io获得免费的 API 密钥并亲自使用它
机器学习的高级烛台(二):体积和美元酒吧

在本文中,我们将学习如何构建成交量和美元棒线,并探索它们相对于传统的基于时间的烛台和分笔成交点棒线的优势。最后,我们将在 16 个加密货币交易对的大型数据集中分析它们的两个统计属性——回报的自相关性和正态性
介绍
在一篇的前一篇文章中,我们学习了如何构建分笔成交点,并评估了它们根据市场中较高或较低的活动自动调节采样率的特殊能力。与分笔成交点相似,成交量和美元线也允许采样率与市场活动同步,但他们每个人对活动的理解不同。在分笔成交点的例子中,市场活动被定义为在交易所发生的交易数量。交易量条将交易量定义为交易所交易的资产数量,例如,交易的比特币数量。对于美元棒线,活动被定义为交换的固定价值,例如,每次交换 1000 美元的资产时对棒线进行取样,它可以用美元来衡量,也可以用欧元、日元等来衡量。
因此,每种棒线对市场活动的理解和同步方式不同,这种不同的理解带来了它的优点和缺点。让我们深入研究一下。
分笔成交点、成交量和美元棒线的优缺点
利用棒线,我们找到了一种方法来扫描交易所的交易历史,并在交易所执行更多交易时,简单地采样更多棒线。虽然交易数量和信息到达之间可能存在很强的相关性,但这种相关性是不确定的。例如,一个非常熟悉的算法或交易员可能会自动发出非常小的重复订单,以影响市场情绪(通过将交易历史“变绿”),隐藏交易总量(也称为冰山订单),或者只是通过伪造信息到达来迷惑其他交易机器人。
这种情况的一个潜在解决方案是使用音量条。成交量棒不关心交易的顺序或数量,他们只关心这些交易的总量。对他们来说,信息的到来是交易所用户之间交易量的增加。通过这种方式,交易量柱能够绕过对交易数量的误导性解释,代价是失去隐藏在实际交易序列中的任何信息。
成交量棒线的另一个有趣的特征,听起来很明显,但值得注意的是,市场成交量信息本身就编码在棒线上:每个成交量棒线都是一个预定义成交量的桶。同样,这听起来可能是显而易见的,但长期以来,直到今天,金融领域的许多研究人员对如何将交易量信息纳入他们的预测模型毫无头绪。音量条提供现成的音量信息。
现在,交易量柱的问题是,交易量可能与交易资产的实际价值密切相关。例如,在 2017 年初,1 万美元可以购买大约 10 个比特币,但到了 2017 年底,你只能用它购买半个比特币。潜在价值的巨大波动极大地削弱了量柱的力量,因为由于资产的重估,在某个时间点相关的量大小可能在不久的将来不相关。纠正这种波动的一种方法是,不计算交换的资产数量(数量条),而是计算交换的固定价值数量(美元条),对于 etc 美元货币对,这恰好是以美元计算的,但对于欧洲货币对,也可能是以欧元计算的,等等。
建筑体积和美元酒吧
现在我们已经看到了每种条形的优点和缺点,让我们来看看如何实际构建它们。
下面是构建音量条的快速 Python 实现:
Snippet 1. Volume bar implementation
这里是美元条的一个实现,它只包括对前面函数的一些小的修改——让我们看看您是否能发现它们:
Snippet 2. Dollar bar implementation
最后,以下是它们与传统计时烛台的对比:

Figure 1. Trade, time-based, volume and dollar bars depiction. Asterisks are plotted every time a candle is sampled
基于交易量和美元的蜡烛线在某种意义上类似于分笔成交点,虽然与基于时间的调和蜡烛线相比,它们看起来混乱和重叠,但只要市场活动有变化,它们就能很好地采样。
量柱的统计分析
现在让我们看看它们的统计特性。我们将通过 Pearson 自相关测试和 Durbin-Watson 测试来研究收益的序列相关性。最后,我们还将通过执行贾尔克-贝拉和夏皮罗-维尔克检验来研究结果的正态性。参考关于刻度条的旧文章,了解更多关于这些统计测试的信息。
在交易量柱的情况下,我们将显示 16 个交易对的结果,每个交易对有 7 个交易量(标记为第 1 层到第 7 层)。与分笔成交点不同,交易量大小是特定于加密货币的,因为它们取决于多种因素,如流通中的硬币总量、基础资产价值等。我们选择每种加密货币的交易量大小的方法是通过计算每天的平均交易量,然后将每天的平均交易量除以相同的比率,如 5 分钟、15 分钟、30 分钟、1 小时、4 小时、12 小时对应于 1 天,并四舍五入到最接近的 10。以下是每个加密货币对自动选择的数量:
Table 1. CryptoDatum.io volume bar sizes

Figure 2. Pearson auto-correlation for volume bars

Figure 3. Durban-Watson statistic for volume bars
结果与我们看到的分笔成交点一致。与基于时间的蜡烛图(图 2 和图 3)相比,量柱显示的自相关性稍低,并且在两个正态性检验(图 4)中的大多数情况下,正态性的零假设都被拒绝,因此我们确定收益不遵循高斯分布。

Figure 4. Jarque-Bera and Spahiro-Wilk tests p-value for volume bars
美元金条的统计分析
我们将重复之前对收益的自相关性和正态性的测试。在美元条的情况下,美元条的大小(以美元表示)定义如下表所示:
Table 2. CryptoDatum.io dollar bar sizes ($)
现在让我们看看正态性和自相关测试的结果:

Figure 5. Pearson auto-correlation for dollar bars

Figure 6. Durbin-Watson test results for dollar bars

Figure 7. Normality tests for dollar bars
与我们在分笔成交点和成交量棒线中看到的相反,结果是美元棒线与基于时间的蜡烛线相比,在自相关性方面几乎没有改善。我们可以观察到不同加密货币之间的自相关方差略低,但平均来看差异很小。最后,回归常态再次遭到广泛拒绝。
蜡烛内部价格变化分析
我们已经说过,分笔成交点、成交量和美元棒线采样适应市场活动,允许我们在高活动期采样更多,在低活动期采样更少。最终,这种属性应该反映在单根蜡烛的价格变化量上。这个想法是,基于时间的烛台在固定的时间间隔采样,而不管市场活动,而替代酒吧得到与市场活动同步。因此,基于时间的蜡烛图应该同时具有价格变化很小的蜡烛线(过采样期间)和价格变化很大的蜡烛线(欠采样期间),而替代棒线应该更加均衡,这似乎是很直观的。
然而,我们所理解的市场活动是什么?一个市场可以非常活跃,价格横向移动吗?答案是肯定的,虽然通常在高市场活动和大的价格变化之间存在相关性,但这种关系是不确定的。例如,在某些情况下,高 FUD(恐惧、不确定性和怀疑)会导致交易量激增,但价格变化很小。此外,在加密货币市场中,清洗交易并不少见。这些动作包括自我交易(买方和卖方是同一个人),这再次引发了巨大的交易量高峰,而价格变化很小。
为了弄清楚这个问题,让我们来看看每种类型的棒线的蜡烛线内价格变化的分布。蜡烛线内价格变化计算如下:
蜡烛线内变化=(高-低)/高

Figure 8. Intra-candle price variation for all the history of the BTC-USD pair at the Bitfinex exchange (data source: CryptoDatum.io)
我们可以看到,时间蜡烛图分布更偏向于 0,并且有一个向右的长尾,而其他分布在高价格变化期间有效地采样更多。
每日酒吧频率
B 在结束本文之前,我想看看日柱线的频率,以及交易资产的价格和市场活动如何影响采样率。让我们看看结果:

Figure 9. Bar sampling frequency per day for the whole BTC-USD history at the Bitfinex Exchange. Bitcoin log price is shown in grey line. (data source: CryptoDatum.io)
我们可以看到,基于时间的烛台以相同的速率采样(每天 24 根棒线),替代棒线的采样速率根据比特币价格的变化而变化(以灰色显示)。
有趣的是,在替代棒线中,成交量棒线的采样频率似乎仍然是 BTC 兑美元历史上最稳定的——只有当我们包括 2017 年的历史高点时,否则美元或分笔成交点棒线似乎更稳定。另一个让我惊讶的特征是,美元蜡烛应该更稳定,因为它们对实际资产价格有所“修正”,但在 2017 年的历史高点期间,美元蜡烛似乎失去了控制。我怀疑这是因为在大致稳定的交易量中,美元棒线能很好地修正资产的重估。然而,如果你结合资产价格增长 10 倍或更多的事实,总交易量,而不是由于资产的高成本而减少,保持增长,那么你会遇到一种情况,当美元棒采样简单地爆炸。
我们学到了什么?
- 成交量棒线通过只关注交换的资产总额,解决了关于多个小额交易和冰山订单的价格棒线限制。
- 美元棒衡量交换的固定价值,这在理想情况下可以校正资产(如加密货币)的波动价值。
- 当市场活动增加时,成交量和美元棒线取样较多,当市场活动减少时,取样较少。
- 与传统的基于时间的蜡烛图相比,量柱通常显示较低的序列相关性。
- 美元棒线似乎不会产生较低的序列相关性。然而,请记住,美元棒线的数量似乎在历史高点期间爆炸,这意味着大多数美元棒线可能来自非常短的时间,因此平均自相关可能更高,只是因为棒线的紧密“相邻”。
- 成交量和美元棒线的对数收益率都不服从高斯分布。
- 传统烛台的蜡烛内变化分布似乎向零移动,并呈现长尾,这证实了它们不能使取样适应市场活动。或者,分笔成交点、成交量和美元棒线的蜡烛线内变化分布看起来更平衡,并向右移动。
- 基于固定周期的烛台后,体积条的采样率似乎是最稳定的。
- 美元的取样率似乎在泡沫中爆炸,体积非常大。
感谢阅读!在下一集,我们将谈论一种最有趣的酒吧:不平衡酒吧。这些棒线是根据交易顺序中观察到的不平衡来取样的,是信息驱动棒线的一个很好的例子。
这个项目是我们在cryptodatum . io研究的一部分,这是一个加密货币数据 API,旨在提供即插即用的数据集来训练机器学习算法。如果您喜欢我们在本文中展示的数据,您可以在https://cryptodatum . io获得免费的 API 密钥并亲自使用它
高级集成分类器
系综这个词是一个拉丁语派生词,意思是“各部分的结合”。常用的常规分类器容易出错。虽然这些错误是不可避免的,但是可以通过学习分类器的适当构造来减少它们。
集成学习是一种生成各种基本分类器的方法,从这些基本分类器中导出一个新的分类器,其性能优于任何组成分类器。这些基本分类器可能在使用的算法、超参数、表示或训练集方面有所不同。
集成方法的关键目标是减少偏差和方差。

The figure shows a basic outline of ensemble techniques.
一些高级集成分类器是:
- 堆垛
- 混合
- 制袋材料
- 助推
堆叠:堆叠是一种将单个训练数据集给多个模型并进行训练的方法。使用 k-fold 验证进一步划分训练集,并形成结果模型。这里,每个模型表示使用的不同算法。

size of the training data=m*n | no. of models=M
从这 M 个模型中做出的预测被用作最终模型的预测器。如此共同形成的变量用于预测最终分类,比每个基础模型更精确
混合:与叠加相比,混合是一种类似的技术,但唯一的区别是数据集直接分为训练和验证,而不是 k 倍验证。
Bagging(Bootstrap aggregation):在这种方法中,通过替换从训练数据中选取各种数据项,产生 n 个训练数据样本。
装袋时,由于数据是未加权的,所以抽样中的项目是随机选择的。
对于每次迭代,
- 在这些样本中的每一个上创建一个基础模型。
- 这些模型并行运行,相互独立。
- 通过组合所有模型的预测来确定最终预测。
这些模型共同形成更高等级的模型,以产生更高的准确性。最终模型的平均值为:
e =(σeᵢ)/n
e₁,e₂…在哪里..eₙ =基本分类器
e =最终分类器
打包算法:
- Bagging 元估计量
- 随机森林

升压:升压是一种自学习技术。它通过为数据中的各种项目分配权重来学习。提升技术最初以相等的权重开始,但是在每个模型之后,每个模型基于其性能被分配一个权重。
类似地,在评估每个模型之后,错误分类的数据被赋予更多的权重,以便下一个模型更加关注这些项目。
对于每次迭代,
- 它根据分类的不正确程度对每个训练样本进行加权。
- 做一个假设
- 权衡假设
因此,通过基于权重对数据组进行投票,最终模型是从关注不同数据组的各种模型中得出的。
使用加权平均法对最终模型进行平均
e =((σeᵢwᵢ)/*σwᵢ))/n
哪里,e₁,e₂…..eₙ =基本分类器
w₁,w₂…..wₙ=重量
n =模型数量
e =最终分类器
升压算法:
- adaboost 算法
- 马恩岛
- XGBM
- 轻型 GBM
- CatBoost
注意:在 bagging 中,模型并行运行并且相互独立,而在 boosting 中,模型按顺序运行并且依赖于前面的模型。
数据科学的高级谷歌技能
像专业人士一样搜索,优化您的编程

Photo by Clay Banks on Unsplash
“谷歌一下”的问题是
“ LMGTFY ”是一个历史悠久的笑话网站。“ RTFM ”是不屑的冷笑。(法语为 Ouais,aussien Fran ais。)
但是,如果找到答案就像在搜索引擎中输入自然语言查询和阅读手册页一样简单,那么就不会有图书馆学研究生学位,我也会失业。
LMGTFY:回答开放式问题不是一件小事。
除了作为一个未解决的、NLP 困难的机器学习问题,寻找“为什么我的代码不编译?”或者“我的模型有什么问题?”是你——用你的非人工智能——在日常生活中需要高效处理的问题,以成为一名有效的数据科学家和程序员。
在这里,我将分享信息专家工具箱中的一些强大工具,您可以使用它们来调试代码并更快地了解相关信息。
有目的的谷歌
它不仅仅是一个自然语言的问题框,尽管没有人否认自动完成是 AI 娱乐的最佳和最高形式。

Who hurt you?
如果你没有使用先进的谷歌搜索功能,你就错过了它的全部功能。这些功能包括:
- 排除带负号的词语:比较热门搜索视频
python和python -programming:

python

python -programming
- 包含带双引号的词条:如果一个词条一定要出现,即使很少见,PageRank 也不怎么看重,那么你可以用引号把它括起来。
python x86–64 assembly “fail”将确保你得到编译器“失败”的结果。 - 同样,使用这些双引号来搜索与完全匹配的字符串。通过将 stderr 复制并粘贴到搜索引擎的一对双引号中来调试代码问题。
- Bootstrap Google 来弥补另一个网站糟糕的搜索功能。将
site:www.example.com作为查询的一部分会将您的搜索限制在该域内。

using Google as a single-site search engine
- 如果你和我不一样,更喜欢 GUI 而不是语法,将高级搜索页面加入书签。它有翻译这些选项和更多的字段。
成为 Github 和 StackExchange 忍者
除了 Google 上的site:github.com,Github 的 UI 和 API 都提供了高级搜索功能,这通常符合我们刚刚讨论的语法。将高级搜索页面加入书签。

github advanced search
StackExchange 为高级无畏研究者提供了无数的语法选项。一个很棒的特性是能够使用主题标签上的任何搜索选项,用【括号】表示,来包含或排除内容(例如concurrency *ython -[java] ==“我想看关于 Cython 和 Python 中的并发性的答案,但不是 Java。”).StackExchange】也有一个支持高级搜索的 API (尽管 GitHub 的 API 与更酷的 GraphQL 一起工作)。
做你自己的 NLP 模型+参考馆员
编程的能力是强大的——你创造的东西可以创造其他东西。进行战术研究的能力是一种超能力——你学得更快,解决问题更有效率,并且在这个过程中利用你的元技能。
那么什么是“好的搜索”呢?
- 把垃圾拿出来。思停话和 TF-IDF。(复习: TF-IDF 的基本思想是,如果一个词在你的语料库中出现得更频繁,它就更有意义,但如果它出现得如此频繁,无论上下文如何,它都不会更有意义。)
- 获取具体。可能需要几次尝试来校准查询特异性的水平,以找到相关的答案,但它介于“python 模块不起作用”和复制粘贴带有您的特殊用户名、文件路径和函数名称的回溯之间。试着上下拨动特异性键,看看你的点击会发生什么。
- 尝试不同的单词。你所包含的术语有可能产生独特的结果吗,或者至少比一些更普通的词获得更多的信息吗?如果没有,你能不能用几种不同的方式来解释你的问题,看看其他人是否尝试过这些措辞?
有时,这是第三或第四个问题的重新措辞,在 StackExchange 搜索结果的第无数页上找到了金子。如果你被一些想法难住了,试试 textblob,它能让你快速地头脑风暴同义词、 meroynms 、 holonyms 、定义、例句和单词的其他意思,以丰富和重组你的查询。
虽然你可能更喜欢这个 Python 要点,而不是头脑风暴术语的模拟方法,但我还是鼓励你伸展你的精神肌肉,尝试一下。从学习看到一个问题的多个方面中获得的思维可塑性是一种帮助你成为更好的程序员的技能。
保留研究线索
一旦你找到了来之不易的答案,不要失去你已经取得的进步。记录下来。
- 注释你的代码。你知道有多少次我忘记了一个复杂的研究线索的答案,并感谢过去的我把链接放在了一个屏蔽评论里?
- 当我们谈到这个主题时,使用版本控制。你的研究笔记没有理由不能是本地 git 回购。一旦你解决了一个大问题,如果它坏了,你需要再次修复它,你会很高兴你有线索。养成写(或做书签)到文件、添加和提交的习惯。一个可追踪的研究轨迹几乎是自我文档化的,并且绝对会为你节省数小时的回溯时间。
- 利用您的浏览器历史记录。如果你使用 Chrome,使用谷歌 Chrome/Gmail 开发专用账户来跟踪你的浏览历史。
- 使用 Vivaldi (我最喜欢的浏览器),这是一个基于 Chromium 的浏览器,允许您创建多个浏览配置文件和标签/书签组(例如,一个用于开发,一个用于 ML,一个用于前端,一个用于休闲时间……)
- 保存研究文档。将书签存储在一个开源的、跨平台的、支持多媒体的引用和研究管理器 Zotero 中。
- 或者,如果你也爱命令行,试试 papis 。
我主要使用一个 CLI,我用一堆普通的。txt 文件和一个 sqlite 后端来管理它们。但是 Zotero 是我最喜欢的与他人分享和合作的开源软件。Papis 功能丰富,我一直在关注概念作为吉拉式服务的一种降价友好、集成和防干扰的替代方案。
欢迎来到信息科学!
(重新)搜索是一门科学和艺术——我拥有这方面的硕士学位,并训练模型试图理解如何擅长它,这是有原因的。这很难——即使对聪明的人来说也是如此。
“谷歌一下”是个糟糕的建议。拿这个代替。
使用 Python 的高级直方图
让业务用户和数据科学家高兴的直方图
需要什么?
Python 对生成直方图有很好的支持。但在数据科学中,显示条形/条柱计数、条柱范围、给条形着色以分隔百分位数并生成自定义图例以向业务用户提供更有意义的见解是非常有用的。使用 Python 时,没有内置的直接方法来实现这一点。
所以作为数据科学家需要提供有用的直方图有:
- 如何在直方图中显示每个条形的数据点计数?
- 如何在直方图的 X 轴上显示条形/条柱范围?
- 如何根据百分比改变直方图中条形/条柱的颜色?
- 如何生成自定义图例?
我们尝试生成的最终输出将对最终用户非常有用,如下所示:

Advanced Histogram
这为什么有用?
了解数据范围和百分位数以及计数和标准化百分比对于确定如何处理/清理数据非常有用。业务用户也很容易理解直方图并从中获取价值。
例如,如果数据严重倾斜,无论是正的还是负的,并且有极端的异常值,则图表可能会揭示关于数据的一些有价值的见解。

Advance histogram for skewed data
上面的直方图显示,大约 99%的数据在 1 到 6788 的范围内。虽然数据范围是从 1 到 67875,但很明显,几乎 99%的数据都在 1 到 6788 之间,这有助于决定如何处理异常值。
您无法从下图所示的标准直方图中获得这种细节层次的洞察力。

Standard histogram for skewed data
Python 代码
你可以从我的AnalyticsInsightsNinjaGitHub 网站或者从 Azure 笔记本下载代码。
代码中重要的一行是:
counts,bin,patches = ax.hist(data,facecolor = perc _ 50 _ colour,edgecolor='gray')
它返回以下内容:
计数 =直方图中每个面元/列的数据点计数的 numpy . n 数组
面元 =面元边缘/范围值的 numpy . n 数组
补丁 =补丁对象列表。每个 Patch 对象包含一个 Rectnagle 对象。例如矩形(xy=(-2.51953,0),宽度=0.501013,高度=3,角度=0)
通过操作这三个集合,我们可以获得关于直方图的非常有用的信息。
鸣谢:这个代码的灵感来自于 stackoverflow.com 大学的乔·金顿的一个回答
结论
虽然标准直方图很有用,但拥有一个可以显示数据范围和百分位数以及计数和归一化百分比的增强版本,对于数据科学家来说非常有用,可以帮助他们确定应该如何处理/清理数据,并为业务最终用户提供更多价值。
高级 Jupyter 笔记本:教程

Photo by Scott Graham on Unsplash
Jupyter 笔记本是现代数据科学和分析的核心,在项目生命周期的两端都是非常强大的工具。无论您是快速制作创意原型、演示您的工作,还是制作完整的报告,笔记本电脑都可以提供超越 ide 或传统桌面应用程序的高效优势。
继《 Jupyter 初学者笔记本:教程》之后,本指南将带你踏上从真正的香草到彻头彻尾的危险的旅程。没错!Jupyter 的无序执行的古怪世界有着令人不安的力量,当涉及到在笔记本中运行笔记本时,事情会变得很复杂。
本指南旨在理清一些混乱的来源,传播想法,激发你的兴趣,激发你的想象力。已经有很多关于整洁的提示和技巧的伟大列表,所以在这里我们将更彻底地看看 Jupyter 的产品。
这将涉及:
- 使用 shell 命令的基础知识和一些方便的魔术进行热身,包括调试、计时和执行多种语言。
- 探索日志记录、宏、运行外部代码和 Jupyter 扩展等主题。
- 了解如何使用 Seaborn 增强图表,使用主题和 CSS 美化笔记本,以及定制笔记本输出。
- 最后深入探讨脚本执行、自动化报告管道和使用数据库等主题。
如果你是 JupyterLab 的粉丝,你会很高兴听到 99%的内容仍然适用,唯一的区别是一些 Jupyter 笔记本扩展与 JuputerLab 不兼容。幸运的是,令人敬畏的 替代品已经在 GitHub 上出现了。
现在我们准备好成为朱庇特巫师了!
Shell 命令
每个用户至少都会不时地受益于从他们的笔记本中直接与操作系统交互的能力。代码单元中以感叹号开头的任何一行都将作为 shell 命令执行。这在处理数据集或其他文件以及管理 Python 包时非常有用。举个简单的例子:
Hello World! pandas==0.23.4
还可以在 shell 命令中使用 Python 变量,方法是在前面加上一个与 bash 风格变量名一致的符号$。
This is nifty
注意,在执行完成后,执行!命令的 shell 将被丢弃,因此像cd这样的命令将不起作用。然而,IPython magics 提供了一个解决方案。
基本魔术
Magics 是内置于 IPython 内核中的便捷命令,它使执行特定任务变得更加容易。尽管它们经常类似于 unix 命令,但实际上它们都是用 Python 实现的。存在的魔法比在这里介绍的要多得多,但是有必要强调各种各样的例子。在进入更有趣的案例之前,我们将从一些基础知识开始。
有两种魔法:线魔法和细胞魔法。它们分别作用于单个细胞株,也可以分布于多个细胞株或整个细胞。要查看可用的魔术,您可以执行以下操作:
Available line magics:
%alias %alias_magic %autocall %automagic %autosave %bookmark %cd %clear %cls %colors %config %connect_info %copy %ddir %debug %dhist %dirs %doctest_mode %echo %ed %edit %env %gui %hist %history %killbgscripts %ldir %less %load %load_ext %loadpy %logoff %logon %logstart %logstate %logstop %ls %lsmagic %macro %magic %matplotlib %mkdir %more %notebook %page %pastebin %pdb %pdef %pdoc %pfile %pinfo %pinfo2 %popd %pprint %precision %profile %prun %psearch %psource %pushd %pwd %pycat %pylab %qtconsole %quickref %recall %rehashx %reload_ext %ren %rep %rerun %reset %reset_selective %rmdir %run %save %sc %set_env %store %sx %system %tb %time %timeit %unalias %unload_ext %who %who_ls %whos %xdel %xmode
Available cell magics:
%%! %%HTML %%SVG %%bash %%capture %%cmd %%debug %%file %%html %%javascript %%js %%latex %%markdown %%perl %%prun %%pypy %%python %%python2 %%python3 %%ruby %%script %%sh %%svg %%sx %%system %%time %%timeit %%writefile
Automagic is ON, % prefix IS NOT needed for line magics.
如你所见,有很多!大多数都在官方文档中列出,该文档旨在作为参考,但在某些地方可能有些晦涩。线条魔法以百分比字符%开始,单元格魔法以两个字符%%开始。
值得注意的是,!实际上只是 shell 命令的一种奇特的魔法语法,正如您可能已经注意到的,IPython 提供了魔法来代替那些改变 shell 状态并因此被!丢失的 shell 命令。例子有%cd、%alias和%env。
让我们再看一些例子。
自动保存
首先,%autosave魔术让你改变你的笔记本多久自动保存到它的检查点文件。
Autosaving every 60 seconds
就这么简单!
显示 Matplotlib 图
对于数据科学家来说,最常见的线条魔术之一当然是%matplotlib,它当然是与最流行的 Python 绘图库 Matplotlib 一起使用。
提供inline参数指示 IPython 在单元格输出中内联显示 Matplotlib 绘图图像,使您能够在笔记本中包含图表。在导入 Matplotlib 之前,一定要包含这个魔术,因为如果不包含它,它可能无法工作;许多人在笔记本的开头,在第一个代码单元中导入它。
现在,让我们开始看看一些更复杂的特性。
排除故障
更有经验的读者可能会担心没有调试器的 Jupyter 笔记本的最终功效。但是不要害怕!IPython 内核有它自己的接口Python 调试器,pdb ,以及几个在笔记本上用它调试的选项。执行%pdb line magic 将打开/关闭笔记本中所有单元格的 pdb on error 自动触发。
这暴露了一个交互模式,在该模式下您可以使用 pdb 命令。
另一个方便的调试魔术是%debug,您可以在出现异常后执行它,以便在失败时深入研究调用堆栈。
作为题外话,还要注意上面的回溯是如何演示魔术如何被直接翻译成 Python 命令的,其中%pdb变成了get_ipython().run_line_magic('pdb', '')。改为执行这个等同于执行%pdb。
定时执行
有时在研究中,为竞争方法提供运行时比较是很重要的。IPython 提供了两个时序魔法%time和%timeit,每个都有行和单元模式。前者只是对单个语句或单元格的执行进行计时,这取决于它是用于行模式还是单元模式。
Wall time: 32.9 ms 499999500000
在单元模式下:
Wall time: 95.8 ms
%timeit与%time的显著区别在于它多次运行指定的代码并计算平均值。您可以使用-n选项指定运行次数,但是如果没有通过,将根据计算时间选择一个合适的值。
34.9 ms ± 276 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)
执行不同的语言
在上面%lsmagic的输出中,您可能已经注意到了许多以各种编程、脚本或标记语言命名的单元格魔术,包括 HTML、JavaScript、 Ruby 和 LaTeX 。使用这些将使用指定的语言执行单元格。还有其他语言的扩展,如 R 。
例如,要在笔记本中呈现 HTML:
这是真的整齐!
同样, LaTeX 是一种用于显示数学表达式的标记语言,可以直接使用:
一些重要的等式:

配置日志记录
您知道 Jupyter 有一种内置的方法可以在单元格输出上突出显示自定义错误信息吗?这对于确保任何可能使用您的笔记本的人都很难忽略诸如无效输入或参数化之类的错误和警告非常方便。一个简单的、可定制的方法是通过标准的 Python logging模块。
(注意:对于这一部分,我们将使用一些屏幕截图,以便我们可以看到这些错误在真实笔记本中的样子。)
日志输出与print语句或标准单元输出分开显示,出现在所有这些之上。
这实际上是可行的,因为 Jupyter 笔记本同时监听标准输出流、stdout和stderr,但处理方式不同;print语句和单元格输出路由到stdout,默认情况下logging已被配置为流过stderr。
这意味着我们可以配置logging在stderr上显示其他类型的消息。
我们可以像这样定制这些消息的格式:
请注意,每次运行通过logger.addHandler(handler)添加新流处理程序的单元时,每次记录的每个消息都会有一行额外的输出。我们可以将所有的日志记录配置放在靠近笔记本顶部的单元格中,或者像我们在这里所做的那样,强行替换日志记录器上所有现有的处理程序。在这种情况下,我们必须删除默认的处理程序。
将日志记录到外部文件也很容易,如果您从命令行执行笔记本,这可能会派上用场,后面会讨论。用FileHandler代替StreamHandler即可:
最后要注意的是,这里描述的日志不要与使用%config魔法通过%config Application.log_level="INFO"改变应用程序的日志级别相混淆,因为这决定了 Jupyter 在运行时向终端输出什么。
扩展ˌ扩张
由于它是一个开源的 webapp,已经为 Jupyter 笔记本开发了大量的扩展,并且有一个很长的官方列表。事实上,在下面的使用数据库一节中,我们使用了 ipython-sql 扩展。另一个特别值得注意的是来自 Jupyter-contrib 的扩展包,它包含了用于拼写检查、代码折叠等等的独立扩展。
您可以从命令行安装和设置它,如下所示:
pip install jupyter_contrib_nbextensions
jupyter contrib nbextension install --user
jupyter nbextension enable spellchecker/main
jupyter nbextension enable codefolding/main
这将在 Python 中安装jupyter_contrib_nbextensions包,在 Jupyter 中安装,然后启用拼写检查和代码折叠扩展。不要忘记在安装时实时刷新任何笔记本以加载更改。
请注意,Jupyter-contrib 只能在普通的 Jupyter 笔记本上运行,但是 GitHub 上现在发布了 JupyterLab 的新的扩展。
使用 Seaborn 增强图表
Jupyter 笔记本用户进行的最常见的练习之一是制作情节。但是 Python 最流行的图表库 Matplotlib 并不以吸引人的结果而闻名,尽管它是可定制的。Seaborn 立即美化 Matplotlib 图,甚至添加一些与数据科学相关的附加功能,使您的报告更漂亮,您的工作更容易。它包含在默认的 Anaconda 安装中,或者通过pip install seaborn轻松安装。
让我们来看一个例子。首先,我们将导入我们的库并加载一些数据。
Seaborn 提供了一些内置的样本数据集用于文档、测试和学习目的,我们将在这里使用它们。这个“小费”数据集是一只熊猫DataFrame,列出了酒吧或餐馆的一些账单信息。我们可以看到账单总额、小费、付款人的性别以及其他一些属性。
我们可以很容易地在 Matplotlib 中绘制total_bill vs tip。

在 Seaborn 绘图也一样简单!只需设置一个样式,你的 Matplotlib 图就会自动转换。

这是多么大的改进啊,而且只需要一个导入和一行额外的代码!在这里,我们使用了深色网格样式,但是 Seaborn 总共有五种内置样式供您使用:深色网格、白色网格、深色、白色和刻度。
但是,我们并没有止步于样式化:由于 Seaborn 与 pandas 数据结构紧密集成,它自己的散点图功能释放了额外的特性。

现在,我们为每个数据点获得了默认的轴标签和改进的默认标记。Seaborn 还可以根据数据中的类别自动分组,为您的绘图添加另一个维度。让我们根据买单的群体是否吸烟来改变标记的颜色。

这真是太棒了!事实上,我们可以做得更深入,但是这里的细节太多了。作为品尝者,让我们根据买单的人数来区分吸烟者和非吸烟者。

希望能弄清楚为什么 Seaborn 将自己描述为“绘制吸引人的统计图形的高级界面”。
事实上,这已经足够高级了,例如,为绘制数据的提供带有最佳拟合线(通过线性回归确定)的一行程序,而 Matplotlib 依赖于您自己准备数据。但是如果你需要的是更吸引人的情节,它是非常可定制的;例如,如果你对默认主题不满意,你可以从一整套标准的调色板中选择,或者定义自己的主题。
Seaborn 允许你用更多的方式来可视化你的数据结构和其中的统计关系,查看他们的例子。
宏指令
像许多用户一样,您可能会发现自己一遍又一遍地编写相同的任务。也许当你开始一个新的笔记本时,你总是需要导入一堆包,一些你发现你自己为每个数据集计算的统计数据,或者一些你已经制作了无数次的标准图表?
Jupyter 允许您将代码片段保存为可执行宏,以便在所有笔记本上使用。尽管执行未知代码对其他试图阅读或使用您的笔记本的人来说不一定有用,但在您进行原型制作、调查或只是玩玩的时候,它绝对是一种方便的生产力提升。
宏只是代码,所以它们可以包含在执行前必须定义的变量。让我们定义一个来使用。
现在,要定义一个宏,我们首先需要一些代码来使用。
Hello, Tim!
我们使用%macro和%store魔法来设置一个可以在所有笔记本上重复使用的宏。宏名通常以双下划线开头,以区别于其他变量,如下所示:
Stored '__hello_world' (Macro)
%macro魔术需要一个名字和一个单元格号(单元格左边方括号中的数字;在这种情况下,23 是在In [23],我们还通过了-q,使它不那么冗长。%store实际上允许我们保存任何变量以便在其他会话中使用;这里,我们传递我们创建的宏的名称,这样我们可以在内核关闭后或在其他笔记本中再次使用它。不带任何参数运行,%store列出您保存的项目。
要从存储中加载宏,我们只需运行:
为了执行它,我们只需要运行一个只包含宏名的单元格。
Hello, Tim!
让我们修改我们在宏中使用的变量。
当我们现在运行宏时,我们修改后的值被选中。
Hello, Ben!
这是因为宏只是在单元格的范围内执行保存的代码;如果name未定义,我们会得到一个错误。
但是宏并不是笔记本间共享代码的唯一方式。
执行外部代码
并非所有代码都属于 Jupyter 笔记本。事实上,尽管完全有可能在 Jupyter 笔记本上编写统计模型,甚至是完整的多部分项目,但是这些代码会变得混乱,难以维护,并且其他人无法使用。Jupyter 的灵活性无法替代编写结构良好的 Python 模块,这些模块可以轻松地导入到您的笔记本中。
总的来说,当您的快速笔记本项目开始变得更加严肃,并且您发现自己正在编写可重用的或者可以逻辑分组到 Python 脚本或模块中的代码时,您应该这样做!除了可以在 Python 中直接导入自己的模块,Jupyter 还允许您使用%load和%run外部脚本来支持组织更好、规模更大的项目和可重用性。
为每个项目一遍又一遍地导入相同的包是%load魔术的完美候选,它将外部脚本加载到执行它的单元中。
但是已经说得够多了,让我们来看一个例子!如果我们创建一个包含以下代码的文件imports.py:
我们可以简单地通过编写一个单行代码单元格来加载它,就像这样:
执行此操作将用加载的文件替换单元格内容。
现在我们可以再次运行单元来导入我们所有的模块,我们准备好了。
%run魔术是相似的,除了它将执行代码和显示任何输出,包括 Matplotlib 图。您甚至可以这样执行整个笔记本,但是请记住,并不是所有代码都真正属于笔记本。让我们来看看这个魔术的例子;考虑一个包含以下简短脚本的文件。
当通过%run执行时,我们得到以下结果。

如果您希望将参数传递给脚本,只需在文件名%run my_file.py 0 "Hello, World!"后或使用变量%run $filename {arg0} {arg1}显式列出它们。此外,使用-p选项通过 Python 分析器运行代码。
脚本执行
虽然 Jupyter 笔记本电脑最重要的功能来自于它们的交互流程,但它也可以在非交互模式下运行。从脚本或命令行执行笔记本提供了一种生成自动化报告或类似文档的强大方法。
Jupyter 提供了一个命令行工具,它可以以最简单的形式用于文件转换和执行。您可能已经知道,笔记本可以转换成多种格式,可以从 UI 的“文件>下载为”下获得,包括 HTML、PDF、Python 脚本,甚至 LaTeX。该功能通过一个名为[nbconvert](https://nbconvert.readthedocs.io/en/latest/usage.html)的 API 在命令行上公开。也可以在 Python 脚本中执行笔记本,但是这已经很好地记录了,下面的例子应该同样适用。
与%run类似,需要强调的是,虽然独立执行笔记本的能力使得完全在 Jupyter 笔记本中编写所有的项目成为可能,但这并不能替代将代码分解成适当的标准 Python 模块和脚本。
在命令行上
稍后将会清楚nbconvert如何让开发人员创建他们自己的自动化报告管道,但是首先让我们看一些简单的例子。基本语法是:
jupyter nbconvert --to <format> notebook.ipynb
例如,要创建 PDF,只需编写:
jupyter nbconvert --to pdf notebook.ipynb
这将获取当前保存的静态内容notebook.ipynb并创建一个名为notebook.pdf的新文件。这里需要注意的是,要转换成 PDF 需要安装 pandoc(Anaconda 自带)和 LaTeX(没有)。安装说明取决于您的操作系统。
默认情况下,nbconvert不执行你的笔记本单元格代码。但是如果您也想的话,您可以指定[--execute](https://nbconvert.readthedocs.io/en/latest/execute_api.html#executing-notebooks-from-the-command-line)标志。
jupyter nbconvert --to pdf --execute notebook.ipynb
一个常见的障碍是,运行笔记本时遇到的任何错误都会暂停执行。幸运的是,您可以添加--allow-errors标志来指示nbconvert将错误消息输出到单元格输出中。
jupyter nbconvert --to pdf --execute --allow-errors notebook.ipynb
环境变量参数化
脚本执行对于不总是产生相同输出的笔记本电脑特别有用,例如,如果您正在处理随时间变化的数据,无论是从磁盘上的文件还是通过 API 下载的数据。例如,生成的文档可以很容易地通过电子邮件发送给订户名单,或者上传到亚马逊 S3 网站供用户下载。
在这种情况下,您很可能希望对笔记本进行参数化,以便用不同的初始值运行它们。实现这一点的最简单的方法是使用环境变量,这是在执行笔记本之前定义的。
假设我们想要为不同的日期生成几个报告;在我们笔记本的第一个单元格中,我们可以从一个环境变量中提取这些信息,我们将其命名为REPORT_DATE。%env line magic 使得将环境变量的值赋给 Python 变量变得很容易。
然后,要运行笔记本(在 UNIX 系统上),我们可以这样做:
REPORT_DATE=2018-01-01 jupyter nbconvert --to html --execute report.ipynb
因为所有的环境变量都是字符串,所以我们必须解析它们以获得我们想要的数据类型。例如:
A_STRING="Hello, Tim!" AN_INT=42 A_FLOAT=3.14 A_DATE=2017-12-31 jupyter nbconvert --to html --execute example.ipynb
我们简单地解析如下:
解析日期肯定不如其他常见的数据类型直观,但是像往常一样,Python 中有几个选项。
在 Windows 上
如果你想设置你的环境变量并在 Windows 上用一行代码运行你的笔记本,那就没那么简单了:
cmd /C "set A_STRING=Hello, Tim!&& set AN_INT=42 && set A_FLOAT=3.14 && set A_DATE=2017-12-31&& jupyter nbconvert --to html --execute example.ipynb"
敏锐的读者会注意到上面定义了A_STRING和A_DATE后少了一个空格。这是因为尾随空格对 Windows set命令很重要,所以虽然 Python 可以通过首先去除空格来成功解析整数和浮点数,但我们必须更加小心我们的字符串。
Papermill 参数化
使用环境变量对于简单的用例来说是很好的,但是对于任何更复杂的情况,有一些库可以让你把参数传递给你的笔记本并执行它们。GitHub 上 1000 多颗星,大概最受欢迎的是 Papermill ,可以装pip install papermill。
Papermill 将一个新的单元注入到您的笔记本中,该单元实例化您传入的参数,为您解析数字输入。这意味着您可以直接使用变量,而不需要任何额外的设置(尽管日期仍然需要被解析)。或者,您可以在笔记本中创建一个单元格,通过单击“查看>单元格工具栏>标签”并将“参数”标签添加到您选择的单元格中,使定义您的默认参数值。
我们之前生成 HTML 文档的例子现在变成了:
papermill example.ipynb example-parameterised.ipynb -p my_string "Hello, Tim!" -p my_int 3 -p my_float 3.1416 -p a_date 2017-12-31 jupyter nbconvert example-parameterised.ipynb --to html --output example.html
我们用-p选项指定每个参数,并使用一个中间的笔记本,以便不改变原始的。完全有可能覆盖原来的example.ipynb文件,但是记住 Papermill 会注入一个参数单元格。
现在,我们的笔记本电脑设置简单多了:
到目前为止,我们短暂的一瞥只揭示了造纸厂的冰山一角。该库还可以跨笔记本执行和收集指标,总结笔记本的集合,并提供一个 API 来存储数据和 Matplotlib 图,以便在其他脚本或笔记本中访问。在 GitHub 自述里都有很好的记载,这里就不需要赘述了。
现在应该清楚的是,使用这种技术,可以编写 shell 或 Python 脚本,这些脚本可以批量生成多个文档,并通过像 crontab 这样的工具进行调度,从而自动按计划运行。强大的东西!
造型笔记本
如果您正在寻找笔记本的特定外观,您可以创建一个外部 CSS 文件并用 Python 加载它。
这是因为 IPython 的 HTML 对象作为原始 HTML 直接插入到单元格输出 div 中。实际上,这相当于编写一个 HTML 单元格:
为了证明这一点,让我们使用另一个 HTML 单元格。

使用 HTML 单元格一两行就可以了,但是像我们第一次看到的那样,加载外部文件通常会更干净。
如果你想一次定制你所有的笔记本,你可以直接将 CSS 写入 Jupyter config 目录下的~/.jupyter/custom/custom.css文件中,尽管这只有在你自己的电脑上运行或转换笔记本时才有效。
事实上,所有上述技术也适用于转换成 HTML 的笔记本,但是不能用于转换成 pdf 的笔记本。
要探索你的样式选项,请记住 Jupyter 只是一个 web 应用程序,你可以使用浏览器的开发工具在它运行时检查它,或者研究一些导出的 HTML 输出。你会很快发现它的结构很好:所有的单元格都用cell类表示,文本和代码单元格同样分别用text_cell和code_cell表示,输入和输出用input和output表示,等等。
GitHub 上也有各种不同的 Jupyter 笔记本流行的预设计主题。最流行的是 jupyterthemes ,可以通过pip install jupyterthemes获得,它和运行jt -t monokai设置“monokai”主题一样简单。如果你正在寻找 JupyterLab 的主题,GitHub 上也出现了越来越多的选项。
隐藏单元格
虽然隐藏笔记本中有助于其他人理解的部分是不好的做法,但你的一些单元格对读者来说可能并不重要。例如,您可能希望隐藏一个向笔记本添加 CSS 样式的单元格,或者,如果您希望隐藏默认的和注入的 Papermill 参数,您可以修改您的nbconvert调用,如下所示:
jupyter nbconvert example-parameterised.ipynb --to html --output example.html --TagRemovePreprocessor.remove_cell_tags="{'parameters', 'injected-parameters'}"
事实上,这种方法可以选择性地应用于笔记本中的任何标记单元格,使[TagRemovePreprocessor](https://nbconvert.readthedocs.io/en/latest/config_options.html) 配置非常强大。顺便说一句,在你的笔记本里还有很多隐藏单元格的方法。
使用数据库
数据库是数据科学家的面包和黄油,所以平滑你的数据库和笔记本之间的接口将是一个真正的福音。 Catherine Devlin 的 IPython SQL magic 扩展让您可以用最少的样板文件将 SQL 查询直接写入代码单元格,并将结果直接读入 pandas DataFrames。首先,继续:
pip install ipython-sql
安装好软件包后,我们通过在代码单元中执行以下魔术来开始:
这将加载我们刚刚安装到笔记本中的ipython-sql扩展。让我们连接到一个数据库!
'Connected: @None'
这里,为了方便起见,我们只是连接到一个临时的内存数据库,但是您可能希望指定适合您的数据库的细节。连接字符串遵循 SQLAlchemy 标准:
dialect+driver://username:password@host:port/database
你的可能看起来更像postgresql://scott:tiger@localhost/mydatabase,其中驱动是postgresql,用户名是scott,密码是tiger,主机是localhost,数据库名是mydatabase。
注意,如果将连接字符串留空,扩展将尝试使用DATABASE_URL环境变量;在上面的脚本执行部分阅读更多关于如何定制的信息。
接下来,让我们从之前使用的 Seaborn 的 tips 数据集快速填充我们的数据库。
* sqlite:// 'Persisted tips'
我们现在可以在数据库上执行查询。注意,我们可以对多行 SQL 使用多行单元格魔术%%。
* sqlite:// Done.
您可以通过在查询前加上冒号,使用局部范围的变量来参数化查询。
* sqlite:// Done.
我们的查询的复杂性不受扩展的限制,因此我们可以轻松地编写更具表达力的查询,比如查找账单总额大于平均值的所有结果。
* sqlite:// Done.
如您所见,转换成熊猫DataFrame也很容易,这使得从我们的查询中绘制结果变得轻而易举。让我们来看看 95%的置信区间。

ipython-sql扩展还集成了 Matplotlib,让您可以在查询结果上直接调用.plot()、.pie()和.bar(),并可以通过.csv(filename='my-file.csv')将结果直接转储到 CSV 文件中。阅读更多关于 GitHub 自述文件。
包扎
从初学者教程开始到这里,我们已经讨论了广泛的主题,并为成为 Jupyter 大师打下了基础。这些文章旨在展示 Jupyter 笔记本广泛的使用案例以及如何有效地使用它们。希望您已经为自己的项目获得了一些见解!
我们还可以用 Jupyter 笔记本做很多其他的事情,比如创建交互控件和图表,或者开发自己的扩展,但是让我们把这些留到以后再说。编码快乐!
原载于data quest . io。
高级 Keras —构建复杂的定制损失和指标

Photo Credit: Eyal Zakkay
TL;DR——在本教程中,我将介绍一个简单的技巧,它将允许您在 Keras 中构造自定义损失函数,该函数可以接收除y_true和y_pred之外的参数。
背景— Keras 损失和指标
在 Keras 中编译模型时,我们向compile函数提供所需的损失和度量。例如:
model.compile(loss=’mean_squared_error’, optimizer=’sgd’, metrics=‘acc’)
出于可读性的目的,从现在开始我将集中讨论损失函数。然而,所写的大部分内容也适用于度量标准。
来自 Keras 的损失文件:
您可以传递现有损失函数的名称,也可以传递 TensorFlow/Theano 符号函数,该函数为每个数据点返回一个标量,并采用以下两个参数:
y_true :真标签。张量流/Theano 张量。
y_pred :预测。tensor flow/与 y_true 形状相同的 Theano 张量。
因此,如果我们想使用一个常见的损失函数,如 MSE 或分类交叉熵,我们可以通过传递适当的名称轻松做到这一点。
自定义损失函数
当我们需要使用一个可用的损失函数(或度量)时,我们可以构造我们自己的自定义函数并传递给model.compile。
例如,构建自定义指标(来自 Keras 的文档):
多参数损失/度量函数
您可能已经注意到,损失函数必须只接受两个参数 : y_true和y_pred,它们分别是目标张量和模型输出张量。但是如果我们希望我们的损失/度量依赖于这两个之外的其他张量呢?
为此,我们需要使用函数闭包。我们将创建一个损失函数(使用我们喜欢的任何参数),它返回一个y_true和y_pred的函数。
例如,如果我们(出于某种原因)想要创建一个损失函数,将第一层中所有激活的均方值加到 MSE 上:
请注意,我们已经创建了一个返回合法损失函数的函数(不限制参数的数量),该函数可以访问其封闭函数的参数。
更具体的例子:
前面的例子是一个不太有用的用例的玩具例子。那么什么时候我们会想要使用这样的损失函数呢?
假设你正在设计一个可变的自动编码器。您希望您的模型能够从编码的潜在空间重建其输入。然而,你也希望你在潜在空间中的编码是(近似)正态分布的。
而前一个目标可以通过设计一个仅取决于你的输入和期望输出y_true和y_pred的重建损失来实现。对于后者,你需要设计一个作用于潜在张量的损失项(例如 Kullback Leibler 损失)。为了让你的损失函数接近这个中间张量,我们刚刚学过的技巧可以派上用场。
示例用途:
这个例子是序列到序列变分自动编码器模型的一部分,更多上下文和完整代码请访问这个报告——Sketch-RNN 算法的一个 Keras 实现。
如前所述,尽管示例是针对损失函数的,但是创建定制度量函数的工作方式是相同的。
撰写本文时的 Keras 版本:2.2.4
参考文献:
[1] Keras —损失
[2] Keras —指标
使用管道估计器的高级模型构建

在本文中,我们展示了 sci-kit learn 中的 Pipeline 估计器如何用于高效的机器学习模型构建、测试和评估。我们将使用游轮数据集来说明我们的示例,以构建一个线性回归模型来推荐船只的船员人数。
在上一篇文章中( 使用协方差矩阵图进行特征选择和降维 ),我们已经展示了协方差矩阵图可以用于特征选择和降维。
使用游轮数据集cruise _ ship _ info . CSV,我们发现,在 6 个预测特征[' 年龄'、吨位'、乘客'、长度'、舱室、乘客密度 ]中,如果我们假设重要特征的相关系数为 0 那么目标变量“乘员”与 4 个预测变量:“吨位”、“乘客”、“长度、“车厢”强相关。 因此,我们能够将特征空间的维数从 6 降低到 4。
现在,假设我们想在新的特征空间上建立一个模型来预测船员变量。我们的模型可以用以下形式表示:

在本文中,我们展示了如何使用 scikit-learn 的管道估算器以有效的方式训练、测试和评估我们的模型。
什么是管道估算器?
流水线估计器是一种将几个估计器和转换器组合在一起的方法。这有助于我们编写高效的代码。在下图中,管道估计器在输入数据集中执行 3 项重要任务:(1)使用 StandardScaler() 转换器进行特征缩放;(2)使用 PCA() 变换器的特征工程和维数减少;以及(3)使用线性回归()估计器建立模型。

为什么要使用管道估算器?
作为数据科学家,重要的是我们要高效地编码。包含较少行的高效代码更容易捕捉可能存在的任何错误。所采用的流水线使得模型构建非常高效和健壮。
我们现在将考虑一个示例,该示例说明如何使用流水线估计器来构建、测试和评估线性回归模型,该线性回归模型用于基于 4 个预测变量,即“吨位”、“乘客”、“长度和“舱室”,来推荐船只的船员人数。
1.导入必要的库
import numpy as npimport pandas as pdfrom sklearn.metrics import r2_scorefrom sklearn.model_selection import train_test_splitfrom sklearn.preprocessing import StandardScalerfrom sklearn.decomposition import PCAfrom sklearn.linear_model import LinearRegressionfrom sklearn.pipeline import Pipelinepipe_lr = Pipeline([('scl', StandardScaler()),('pca',
PCA(n_components=4)),('slr', LinearRegression())])
2.读取数据集并选择预测值和目标变量
df=pd.read_csv("cruise_ship_info.csv")cols_selected = ['Tonnage', 'passengers', 'length', 'cabins','crew']X = df[cols_selected].iloc[:,0:4].values
y = df[cols_selected]['crew'] sc_y = StandardScaler()train_score = []test_score = []
3.使用管道估算器进行模型构建、测试和评估(交叉验证)
for i in range(10): X_train, X_test, y_train, y_test = train_test_split( X, y,
test_size=0.4, random_state=i) y_train_std = sc_y.fit_transform(y_train[:,
np.newaxis]).flatten() pipe_lr.fit(X_train, y_train_std) y_train_pred = sc_y.inverse_transform(pipe_lr.predict(X_train)) y_test_pred = sc_y.inverse_transform(pipe_lr.predict(X_test)) train_score = np.append(train_score, r2_score(y_train,
y_train_pred)) test_score = np.append(test_score, r2_score(y_test,
y_test_pred))
4.我们代码的输出

总之,我们已经展示了如何通过将几个基本的转换器和估计器组合在一起,使用非常少的代码行来使用管道估计器来构建、测试和评估机器学习模型。
参考
- 在具有高度相关特征的数据集上训练机器学习模型。
- 使用协方差矩阵图进行特征选择和降维。
- Raschka、Sebastian 和 Vahid Mirjalili 。 Python 机器学习,第二版。帕克特出版社,2017 年。
- Benjamin O. Tayo,预测船只船员规模的机器学习模型,https://github . com/bot 13956/ML _ Model _ for _ Predicting _ Ships _ Crew _ Size。
PowerBI 中的高级 Python 可视化

Image by author
如何利用最新的 Python-PowerBI 集成,将 Python 的高级视觉效果与原生数据钻取和 DAX 功能相结合
最新的 Python 可视化支持完善了 Power BI 中对 Python 的支持,使您能够使用 Python 脚本来准备数据集,在 Power BI 桌面中应用复杂的分析或机器学习,然后使用数百个开源 Python 可视化包中的任何一个在 Power BI 报告中绘制结果。
这种视觉效果随着报告中的交叉筛选而更新,并且可以与 DAX 功能相结合。这是一个强大的组合,它允许我们通过增加交互性来充分利用数据。
在 PowerBI 报告中创建 Python 视觉效果
可以通过从 Power BI Desktop 的 Visualizations 窗格中选择 Python 可视化图标来添加 Python 可视化,这会将占位符 Python 脚本添加到报表中。

必填字段可以从我们正在处理的数据集中添加到值窗格中,这在内部创建了一个 Pandas 数据框架。然后,我们可以使用 Matplotlib 和 Seaborn 等库编写自定义脚本来创建视觉效果。
本机 PowerBI 功能(如切片器、过滤器)可以在 python 可视化工具之上使用,以根据需要进行选择。视觉效果会动态更新。
创建径向条形图以可视化 IMdB 2016 电影数据集
这里有一个小教程,教你如何用 python 创建一个自定义的视觉效果,并添加切片器,让你对数据背后的故事有一个交互式的视觉体验。

IMdB 2016 movie database
该数据集由 2016 年 IMdB 评分为 6 分或更高的电影列表以及属性-预算、总收入、类型和分数组成。
这个数据集在 IMdB 和 kaggle 等其他地方公开。
使用 Matplotlib 在脚本中添加了一个自定义的径向条形图。它根据所应用的选择/过滤器动态地从数据帧中获取值。

用于选择流派、国家和分数范围的切片器直接添加到 PowerBI 中,并显示所选集的平均分数和总收藏数等指标。这使我们能够全面地探索数据,并根据需要做出推论。
代码片段:
# Import the libraries
from matplotlib import pyplot as plt
import numpy as npdataset.sort_values('genre', inplace=True) # Creating values (budget amount) for the bars
iN = len(dataset)
arrCnts = dataset['budget']/10000000theta=np.arange(0,2*np.pi,2*np.pi/iN)
width = (2*np.pi)/iN *0.9 # Plot size and proportions
fig = plt.figure(figsize=(20,18),frameon=False,dpi=200)
# Adding radial axes
ax = fig.add_axes([0.05, 0.05, 0.9, 0.9], polar=True)
bars = ax.bar(theta, arrCnts, width=width, bottom=15,color=dataset['Col'],alpha=0.65,edgecolor='yellow')
ax.set_xticks(theta)
plt.axis('off')
plt.subplots_adjust(left=0.1, right=0.9, top=0.9, bottom=0.1)
bottom = 15
rotations = np.rad2deg(theta)
y0,y1 = ax.get_ylim()
# Adding radial tags
for x, bar, rotation, label in zip(theta, bars, rotations, dataset['name']):
offset = (bottom+bar.get_height())/(y1-y0)
lab = ax.text(0, 0, label, transform=None,
ha='center', va='center',alpha=0.5)
renderer = ax.figure.canvas.get_renderer()
bbox = lab.get_window_extent(renderer=renderer)
invb = ax.transData.inverted().transform([[0,0],[bbox.width,0] ])
lab.set_position((x,offset+(invb[1][0]-invb[0][0])/2.*2.7 ) )
lab.set_transform(ax.get_xaxis_transform())
lab.set_rotation(rotation)
fig.tight_layout()
plt.show()---
This code should be pasted in the script and the visual must be updated.
python 支持的这一扩展作为一个强大的分析框架带来了许多可能性,无论是使用高级 python 库制作高级视觉效果还是复杂的机器学习算法,从而使 PowerBI 成为数据科学领域的必备工具。
看看我下一篇关于如何在 PowerBI 中制作直方图的博客吧!
关于作者
斯里哈里·普拉莫德
从事人工智能产品和建筑技术的数据分析和决策科学专家。印度海得拉巴。
https://www.linkedin.com/in/sriharipramod/
深度卷积神经网络的高级课题
残差网络、显著图、扩张卷积等等。
“如果我们想让机器思考,我们需要教它们看”——费-
在整篇文章中,我将讨论卷积神经网络的一些更复杂的方面,以及它们如何与特定任务相关,如对象检测和面部识别。
本教程将讨论的主题有:
- CNN 评论
- 感受野和扩张的回旋
- 显著图
- 转置卷积
- 经典网络
- 剩余网络
- 迁移学习
这篇文章是我的文章标题: 神经网络简单介绍 的自然延伸。如果你不熟悉卷积神经网络的思想和功能,我建议你在阅读本文其余部分之前先看看这个。
由于原始文章过长,我决定省略与对象检测和面部识别系统相关的几个主题,以及研究文献中目前正在试验的一些更深奥的网络架构和实践。我可能会在未来的一篇文章中更具体地讨论深度学习在计算机视觉中的应用。

You Only Look Once (YOLO) — 2016
所有相关代码现在都可以在我的 GitHub 存储库中找到:
此时您不能执行该操作。您已使用另一个标签页或窗口登录。您已在另一个选项卡中注销,或者…
github.com](https://github.com/mrdragonbear/CNNs)
CNN 评论
在我的原始文章中,我讨论了为什么全连接网络不足以完成图像分析任务的动机。CNN 的独特之处如下:
- 比全连接网络的参数(权重和偏差)更少。
- 对对象平移不变-它们不依赖于特征在图像中出现的位置。
- 可以容忍图像中的一些失真。
- 能够归纳和学习特征。
- 需要网格输入。
卷积层由滤波器、特征图、激活函数构成。这些卷积层可以满、同或有效。

如果已知输入中的层数、 nᵢ 、该级中的滤波器数量、 f 、步长大小、 s 以及图像的像素尺寸、 p (假设是正方形),我们就可以确定给定卷积块的输出层数。
池层用于减少过度拟合。完全连接的图层用于将空间和通道要素混合在一起。在整个图像上绘制了特征图之后,每个过滤层对应于该图像,这就是提取特征的方式。

知道输入和输出层的数量很重要,因为这决定了构成神经网络参数的权重和偏差的数量。网络中的参数越多,需要训练的参数就越多,这导致训练时间更长。训练时间对于深度学习非常重要,因为它是一个限制因素,除非你可以访问强大的计算资源,如计算集群。
下面是一个示例网络,我们将计算其参数总数。

在这个网络中,卷积滤波器有 250 个权重和 10 个偏置项。我们没有最大池层的权重。在 max-pooling 层之后,我们有 13 × 13 × 10 = 1,690 个输出元素。我们有一个 200 节点的全连接层,因此全连接层中共有 1,690 × 200 = 338,000 个权重和 200 个偏置项。因此,我们总共有 338,460 个参数要在网络中训练。我们可以看到,大多数训练参数出现在完全连接的输出层。
CNN 的每一层都学习越来越复杂的过滤器。第一层学习基本的特征检测过滤器,例如边缘和拐角。中间层学习检测物体部分的过滤器——对于人脸,他们可能会学习对眼睛和鼻子做出反应。最后一层有更高的表现:他们学习识别不同形状和位置的完整物体。

Feature maps showing increasing resolution of features through different convolutional layers of a neural network.
对于那些在继续之前需要更直观地了解卷积神经网络的人来说,看看这个三维表示可能会有所帮助:
[## 卷积神经网络的三维可视化
编辑描述
加利福尼亚洲](http://scs.ryerson.ca/~aharley/vis/conv/)
在下一节中,我们将更详细地讨论卷积层感受野的概念。
感受野和扩张的脑回
感受野被定义为输入空间中特定 CNN 特征所关注的区域(即受其影响)。在一个 5 × 5 的输入图上应用一个内核大小为k =3T5×3,填充大小为 p = 1 × 1,步距为 s = 2 × 2 的卷积 C ,我们将得到一个 3 × 3 的输出特征图(绿色图)。**

在 3 × 3 特征图的顶部应用相同的卷积,我们将得到 2 × 2 特征图(橙色图)。

让我们在一维中再次观察感受野,没有填充,步幅为 1,核大小为 3 × 1。

我们可以跳过其中的一些连接,以创建一个扩展的卷积,如下所示。

这种扩展卷积的工作方式与正常卷积类似,主要区别在于感受野不再由连续像素组成,而是由其他像素分隔的单个像素组成。下图显示了将扩展卷积图层应用于图像的方式。

Dilated convolution
下图显示了二维数据的扩展卷积。红点是 3 × 3 滤波器的输入,绿色区域是每个输入捕捉的感受野。感受野是每个输入(单元)对下一层的初始输入所捕获的隐含区域。

使用扩张卷积背后的动机是:
- 通过以更高的分辨率处理输入来检测细节。
- 更广泛的输入视图,以获取更多上下文信息。
- 运行时间更快,参数更少
在下一节中,我们将讨论使用显著图来检查卷积网络的性能。
显著图
显著图是一种有用的技术,数据科学家可以用它来检查卷积网络。它们可以用来研究神经元的激活模式,以了解图像的哪些特定部分对特定特征很重要。

让我们想象一下,给你一张狗的图片,让你给它分类。这对于人类来说非常简单,但是,深度学习网络可能没有你聪明,可能会将其归类为猫或狮子。它为什么这样做?
网络可能错误分类图像的两个主要原因是:
- 训练数据中的偏差
- 没有正规化
我们想了解是什么让网络给出某个类作为输出——一种方法是使用显著图。显著图是一种测量给定图像中特定类别的空间支持度的方法。
“当图像 I 通过我的网络时,找出负责具有分数 S(C)的类 C 的像素”。
我们如何做到这一点?我们差异化!对于任意一个函数 f(x,y,z) ,我们可以通过求变量 x,y,z 在任意一个特定点 (x₁,y₁,z₁) 对这些变量的偏导数,来求变量x,y,z对该点的影响。类似地,为了找到负责的像素,我们对类 C 取分数函数 S ,并对每个像素取偏导数。
这很难自己实现,但幸运的是,auto-grad 可以做到这一点!该过程工作如下:
- 通过网络转发图像。
- 计算每门课的分数。
- 对于除类别 C 之外的所有类别,强制最后一层的分数 S 的导数为 0。对于 C ,将其设置为 1。
- 通过网络反向传播这个导数。
- 渲染它们,你就有了你的显著图。
注意:在步骤#2 中,我们没有使用 softmax,而是将其转换为二元分类并使用概率。
这里有一些显著图的例子。

我们如何处理彩色图像?获取每个通道的显著图,或者取最大值、平均值,或者使用所有 3 个通道。

概述显著图功能的两篇优秀论文是:
有一个与本文相关的 GitHub 库,我在其中展示了如何生成显著图(这个库可以在这里找到)。下面是 Jupyter 笔记本中的一段代码:
**from** **vis.visualization** **import** visualize_saliency
**from** **vis.utils** **import** utils
**from** **keras** **import** activations
*# Utility to search for layer index by name.*
*# Alternatively we can specify this as -1 since it corresponds to the last layer.*
layer_idx = utils.find_layer_idx(model, 'preds')plt.rcParams["figure.figsize"] = (5,5)
**from** **vis.visualization** **import** visualize_cam
**import** **warnings**
warnings.filterwarnings('ignore')
*# This corresponds to the Dense linear layer.*
**for** class_idx **in** np.arange(10):
indices = np.where(test_labels[:, class_idx] == 1.)[0]
idx = indices[0]
f, ax = plt.subplots(1, 4)
ax[0].imshow(test_images[idx][..., 0])
**for** i, modifier **in** enumerate([**None**, 'guided', 'relu']):
grads = visualize_cam(model, layer_idx, filter_indices=class_idx,
seed_input=test_images[idx], backprop_modifier=modifier)
**if** modifier **is** **None**:
modifier = 'vanilla'
ax[i+1].set_title(modifier)
ax[i+1].imshow(grads, cmap='jet')
这段代码导致生成以下显著图(假设安装了相关的库vis.utils和vis.visualization)。如果您想更全面地了解实现过程,请查看笔记本。

在下一节中,我们将讨论通过使用转置卷积进行上采样的想法。
转置卷积
到目前为止,我们所看到的卷积要么保持其输入的大小,要么使其变小。我们可以用同样的技术使输入张量变大。这个过程被称为上采样。当我们在一个卷积步骤内进行时,它被称为转置卷积或分数步长。
注意:一些作者在卷积反卷积时称之为上采样,但该名称已被以下文章中概述的不同概念所采用:
https://arxiv.org/pdf/1311.2901.pdf
为了说明转置卷积是如何工作的,我们将看一些卷积的示例。
第一个例子是没有填充的典型卷积层,作用于大小为 5 × 5 的图像。卷积后,我们得到一个 3 × 3 的图像。

Image taken from A. Glassner, Deep Learning, Vol. 2: From Basics to Practice
现在我们来看一个填充为 1 的卷积层。原始图像是 5 × 5,卷积后的输出图像也是 5 × 5。

Image taken from A. Glassner, Deep Learning, Vol. 2: From Basics to Practice
现在我们来看一个填充为 2 的卷积层。原始图像是 3× 3,卷积后的输出图像也是 5 × 5。

Image taken from A. Glassner, Deep Learning, Vol. 2: From Basics to Practice
当在 Keras 中使用时,例如在可变自动编码器的开发中,这些是使用上采样层实现的。希望,如果你以前见过这个,现在可以理解这些卷积层如何通过使用转置卷积来增加图像的大小。
在下一节中,我们将讨论一些经典网络的架构。这些网络中的每一个在某种意义上都是革命性的,推动了深度卷积网络的发展。
经典网络
在这一部分,我将回顾 CNN 的一些经典架构。这些网络被用于深度学习领域的一些开创性工作,并经常用于迁移学习目的(这是未来文章的主题)。
第一项提出类似于卷积神经网络的研究是由 Kunihiko Fukushima 在 1980 年提出的,被称为 NeoCognitron1,他的灵感来自于哺乳动物视觉皮层的发现。福岛将 NeoCognitron 应用于手写字符识别。
到 20 世纪 80 年代末,发表了几篇论文,大大推进了该领域的发展。反向传播的想法首先由 Yann LeCun 于 1985 年在法语中发表(这也是由其他研究人员独立发现的),随后不久由 Waiber 等人在 1989 年发表了 TDNN——用反向传播训练的类似卷积的网络的发展。最初的应用之一是由 LeCun 等人在 1989 年使用应用于手写邮政编码识别的反向传播。
LeNet-5
与当前实践相比,LeNet-5 的公式有点过时。这是在 20 世纪末深度学习的萌芽阶段开发的第一批神经架构之一。
1998 年 11 月,LeCun 发表了他最著名的论文之一,描述了一种用于文档识别的“现代”CNN 架构,称为 LeNet1。这不是他的第一次迭代,事实上,这是 LeNet-5,但这篇论文是谈论 LeNet 时经常引用的出版物。
它使用卷积网络,然后是池层,最后是完全连接的层。网络首先从高维特征开始,并在增加信道数量的同时减小其尺寸。这个网络中大约有 60,000 个参数。

LeCun, Yann, et al. “Gradient-based learning applied to document recognition.” Proceedings of the IEEE 86.11 (1998): 2278–2324.
AlexNet
AlexNet 架构是深度学习中最重要的架构之一,引用次数超过 25,000 次——这在研究文献中几乎是闻所未闻的。AlexNet 由多伦多大学的 Alex Krizhevsky、Ilya Sutskever 和 Geoffrey Hinton 于 2012 年开发,在 2012 年 ImageNet 大规模视觉识别挑战赛(ILSVRC)中击败了竞争对手。
该网络在 ImageNet 数据集上进行训练,该数据集是一个由 1000 个不同类别组成的 120 万个高分辨率(227x227x3)图像的集合,使用数据扩充。该模型的深度比当时任何其他网络都大,并使用 GPU 进行了 5-6 天的训练。该网络由 12 层组成,利用了 dropout 和 smart optimizer 层,是首批实现 ReLU 激活功能的网络之一,该功能至今仍被广泛使用。该网络有超过 6000 万个参数需要优化(约 255 MB)。

Alex Krizhevsky, Ilya Sutskever, and Geoffrey E Hinton, “Imagenet classification with deep convolutional neural networks,” in Advances in neural information processing systems, pp. 1097–1105, 2012
这个网络通过展示 CNN 令人印象深刻的表现和潜在的好处,几乎单枪匹马地启动了人工智能革命。该网络以 15.3%的 top-5 误差赢得了 ImageNet 大赛,比第二名低了 10.8 个百分点以上。

ImageNet results from 2011 to 2016. Source
我们将讨论剩余的赢得 ILSVRC 的网络,因为其中大多数都是处于深度学习研究前沿的革命性网络。
ZFNet
这个网络是由纽约大学的马修·泽勒和罗布·弗格斯引入的,他们以 11.2%的错误率赢得了 2013 年的 ILSVRC。该网络减小了过滤器的尺寸,并被训练了 12 天。
本文提出了一种可视化技术,称为“去卷积网络”,它有助于检查不同的特征激活及其与输入空间的关系。


VGG16 和 VGG19
Simonyan 和 Zisserman(牛津)于 2014 年引入了 VGG 网络。这个网络在固有的简单性和结构上是革命性的。它由 16 或 19 层(因此得名)组成,总共有 1.38 亿个参数(522 MB),使用 3×3 卷积滤波器,仅使用相同的填充和 1 的跨距,以及 2×2 最大池层,跨距为 2。
作者表明,两个 3×3 滤光器具有 5×5 的有效感受野,并且随着空间尺寸减小,深度增加。这个网络被训练了两到三个星期,现在仍然习惯于这样——主要用于迁移学习。该网络最初是为 2014 年的 ImageNet 挑战赛开发的。
- ImageNet 挑战赛 2014;16 或 19 层
- 1.38 亿个参数(522 MB)。
- 卷积层使用“相同的”填充和步距 s = 1。
- 最大池层使用过滤器大小 f = 2,跨距 s = 2。

Karen Simonyan and Andrew Zisserman, “Very deep convolutional networks for large-scale image recognition,” 2014.
谷歌网(第一版)
谷歌网络是由 Szegedy 等人(谷歌)于 2014 年推出的。该网络击败了 VGG 架构,成为 2014 年 ILSVRC 的赢家。该网络引入了初始模块的概念——具有不同滤波器大小的并行卷积层。
这里的想法是,我们不知道哪个滤波器尺寸是最好的,所以我们只是让网络来决定。初始网络是通过连接其他初始模块而形成的。它包括几个 softmax 输出单元,以加强正则化。这是一个在未来架构开发中非常重要的关键思想。

GoogLeNet (Inception-v1) architecture.
另一个有趣的特性是,最终没有完全连接的层,而是用一个平均池层来代替。移除这种完全连接的层导致网络的参数比 AlexNet 少 12 倍,使其训练速度快得多。

GoogLeNet Architecture.
剩余网络
第一个残差网络是由何等人(微软)在 2015 年提出的。该网络在多个类别中赢得了 ILSVRC 2015。这个网络背后的主要思想是剩余块。该网络允许开发非常深的神经网络,其可以包含 100 层或更多层。
这是革命性的,因为到目前为止,深度神经网络的发展受到消失梯度问题的抑制,该问题发生在跨越大量层传播和繁殖小梯度时。
作者认为,优化残差映射比原型神经架构更容易。此外,如果需要,残余块可以决定“自行关闭”。让我们比较一下普通网络和剩余网络的网络结构。简单网络结构如下:

剩余网络结构如下所示:

Kaiming He, Xiangyu Zhang, Shaoqing Ren, and Jian Sun, “Deep residual learning for image recognition,” in The IEEE Conference on Computer Vision and Pattern Recognition (CVPR), June 2016.
描述该网络的方程是:

有了这个额外的连接,渐变可以更容易地向后传播。它成为一个灵活的模块,可以扩展网络的容量,或者简单地转换成一个不影响训练的身份函数。

Example training of an 18- and 34-layer residual network.
残差网络顺序堆叠残差块。

想法是允许网络变得更深,而不增加训练的复杂性。

剩余网络实现具有卷积层的块,这些卷积层使用“相同”填充选项(即使在最大池化时)。这允许该块学习身份函数。
设计者可能想要减小特征的尺寸并使用“有效的”填充。—在这种情况下,快捷路径可以实现一组新的卷积层,从而适当减小尺寸。

这些网络可能会变得巨大和极其复杂,它们的图表开始看起来类似于描述电厂功能的图表。这是这样一个网络的例子。

Source: He2016
将 ImageNet 以前的获胜者的误差值与 ResNet 公式的误差值进行比较,我们可以看到性能有明显的提高。Alexnet (2012)取得了 15.3%的前 5 名误差(第二名为 26.2%),其次是 ZFNet (2013)取得了 14.8%的前 5 名误差(特征的可视化),其次是 GoogLeNet (2014),误差为 7.8%,然后是 ResNet (2015),首次实现了 5%以下的准确率。

密集网络
最初由黄等人在 2016 年提出,作为 ResNet 哲学的激进扩展。每个块使用每个先前的特征地图作为输入,有效地连接它们。这些连接意味着网络有 L(L+1)/ 2 个直接连接,其中 L 是网络的层数。人们可以将该架构视为一个展开的递归神经网络。
每一层都将自己的 k 特征地图添加到这个状态中。增长率决定了每一层对全局状态贡献多少新信息。这里的想法是,我们在每个点都有所有可用的先前信息。与直觉相反,这种架构减少了所需参数的总数。

A 5-layer dense block with a growth rate of k = 4. Each layer takes all preceding feature-maps as inputs.
该网络的工作原理是通过将每一层与每一层直接连接,允许每一层最大限度的信息(和梯度)流动。这样,DenseNets 通过特征重用来挖掘网络的潜力,这意味着不需要学习冗余的特征映射。DenseNet 层相对较窄(例如,12 个过滤器),并且它们仅添加一小组新的特征地图。
DenseNet 架构通常具有优于 ResNet 架构的性能,可以用更少的总体参数实现相同或更好的精度,并且网络更容易训练。

Performance comparison of various ResNet and DenseNet architectures.
网络公式一开始可能有点混乱,但它本质上是一种 ResNet 架构,分辨率块被密集块所取代。密集的连接具有正则化效果,这减少了对具有较小训练集大小的任务的过度适应。

Simplified DenseNet architecture schematic.
请务必注意,DenseNets 不会将图层的输出要素地图与输入要素地图相加,事实上,它们会连接它们:

特征图的维度在一个块内保持不变,但是滤波器的数量在它们之间变化,这被称为增长率 k.

下面是密集网络的完整架构。当我们以完整的分辨率来看网络时,它是相当复杂的,这就是为什么通常以抽象的形式更容易可视化(就像我们上面所做的)。

Full architectural layout of a DenseNet.
关于 DenseNet 的更多信息,我推荐下面这篇文章。
许多论文:
towardsdatascience.com](/densenet-2810936aeebb)
网络总结
正如我们所看到的,在短短几年的时间里,我们已经从 ImageNet 数据集(如果您记得的话,该数据集由 120 万张图像组成)上约 15%的错误率降至约 3–4%的错误率。如今,最先进的网络能够相当稳定地保持在 3%以下。

在我们能够为这些网络获得满分之前,还有相当长的路要走,但在过去十年中,进步的速度是相当惊人的,从这一点应该可以明显看出为什么我们目前正在经历一场深度学习革命——我们已经从人类具有高级视觉识别能力的阶段发展到这些网络具有高级视觉能力的阶段(人类无法在 ImageNet 数据集上达到 3%)。
这推动了机器学习算法向各种需要大量使用图像分析的商业领域的过渡,如医学成像(检查大脑扫描,x 射线,乳房 x 线扫描)和自动驾驶汽车(计算机视觉)。图像分析很容易扩展到视频,因为这只是每秒钟多个图像帧的快速连续,尽管这需要更多的计算能力。
迁移学习
迁移学习是一个重要的话题,它绝对值得有一篇专门的文章。然而,现在,我将概述迁移学习背后的基本思想,以便读者能够做更多的研究,如果他们感兴趣的话。
如何在 CPU 上做一个可以在几个小时(几分钟)内训练好的图像分类器?
通常情况下,图像分类模型可能需要几个小时、几天甚至几周的时间来训练,尤其是在非常大的网络和数据集上训练时。然而,我们知道谷歌和微软等公司有专门的数据科学家团队,他们花了数年时间开发用于图像分类的特殊网络——为什么不直接使用这些网络作为自己图像分类项目的起点呢?
这是迁移学习背后的思想,使用预先训练的模型,即具有已知权重的模型,以便将它们应用于不同的机器学习问题。显然,仅仅单纯地转移模型是没有帮助的,您仍然必须根据您的新数据来训练网络,但是通常会冻结以前的层的权重,因为这些是更一般化的特征,在训练期间可能不会改变。与随机初始化网络(Keras 中训练网络时的默认情况)相反,您可以将此视为生成预初始化网络的一种智能方式。
通常,迁移学习中使用的学习速率比典型的网络训练中使用的学习速率要小,因为我们本质上是在调整网络。如果使用大的学习率,并且网络中的早期层没有冻结,迁移学习可能不会提供任何好处。通常,在迁移学习问题中只训练最后一层或最后几层。
迁移学习最适用于相当一般的问题,并且在线上有免费的网络可用(例如图像分析),当用户可用的数据集相对较小,不足以训练神经网络时,这是一个相当常见的问题。
总结一下主要思想:网络的早期层学习低级特征,可以通过在后期和完全连接的层改变权重来适应新的域。
这方面的一个例子是使用 ImageNet 训练任何复杂的大型网络,然后在几千个热狗图像上重新训练网络,你就会得到。

Hotdog or NotHotDog: https://youtu.be/ACmydtFDTGs (offensive language and tropes alert)
迁移学习涉及的步骤如下:
- 获取现有网络权重
- 解冻“头部”完全连接的层,并在您的新图像上训练
- 解冻最新的卷积层,并以非常低的学习速率从先前训练的权重开始训练。这将改变最新的层卷积权重,而不会触发大的梯度更新,如果我们没有进行#2,就会发生这种情况。

(Left) Typical imported network to be utilized for transfer learning, (right) newly tuned network with the first four convolutional blocks frozen.
要了解更多信息,我推荐几篇其他的媒体文章:
[## HBO 的硅谷如何用移动 TensorFlow、Keras & React Native 打造“不是热狗”
我们如何打败最先进的技术来建立一个现实生活中的人工智能应用。
最终意见
恭喜你坚持到这篇文章的结尾!这是一篇涉及深度学习多个方面的长文。读者现在应该已经做好了充分的准备,可以开始深入研究卷积学习和计算机视觉文献。我鼓励读者对我在这里讨论的主题做更多的个人研究,这样他们可以加深他们的知识。
我在下一节中添加了一些进一步阅读的链接,以及一些我在本文中借用图片的研究文章的参考资料。
感谢阅读,深度学习快乐!
延伸阅读
- MobileNetV2(【https://arxiv.org/abs/1801.04381】T4)
- 盗梦空间-Resnet,v1 和 v2(https://arxiv.org/abs/1602.07261)
- 广网(https://arxiv.org/abs/1605.07146)
- 例外(https://arxiv.org/abs/1610.02357)
- 雷斯 next(https://arxiv.org/pdf/1611.05431)
- 沙狐球,v1 和 v2(https://arxiv.org/abs/1707.01083)
- 挤压和激励网(https://arxiv.org/abs/1709.01507)
- 原装 DenseNet 纸(https://arxiv.org/pdf/1608.06993v3.pdf)
- DenseNet 语义分割(https://arxiv.org/pdf/1611.09326v2.pdf)
- 用于光流的 DenseNet(【https://arxiv.org/pdf/1707.06316v1.pdf】T2
参考文献
Yann LeCun、Leon Bottou、Yoshua Bengio 和 Patrick Haffner,“基于梯度的学习在文档识别中的应用”,IEEE 会议录,第 86 卷,第 11 期,第 2278-2324 页,1998 年。
Alex Krizhevsky、Ilya Sutskever 和 Geoffrey E Hinton,“深度卷积神经网络的图像网络分类”,载于《神经信息处理系统进展》,第 1097–1105 页,2012 年
卡伦·西蒙扬和安德鲁·齐泽曼,“用于大规模图像识别的深度卷积网络”,2014 年。
、陈强和严水成,“网络中的网络”,2013 年。
Christian Szegedy、、Jia、Pierre Sermanet、Scott Reed、Dragomir Anguelov、Dumitru Erhan、Vincent Vanhoucke 和 Andrew Rabinovich,“用卷积更深入地研究”,载于 2015 年 IEEE 计算机视觉和模式识别会议论文集,第 1–9 页。
施洛夫、弗洛里安、德米特里·卡列尼琴科和詹姆斯·菲尔宾。" Facenet:人脸识别和聚类的统一嵌入."IEEE 计算机视觉和模式识别会议论文集,第 815-823 页。2015
Long,j .,Shelhamer,e .,和 Darrell,T. (2014 年)。语义分割的全卷积网络。从 http://arxiv.org/abs/1411.4038v1取回
Chen,l-c .,Papandreou,g .,Kokkinos,I .,Murphy,k .,& Yuille,A. L. (2014 年)。基于深度卷积网和全连通条件随机场的语义图像分割。 Iclr ,1–14。从 http://arxiv.org/abs/1412.7062取回
于,冯,科尔敦,伏(2016)。基于扩张卷积的多尺度上下文聚合。 Iclr ,1–9。http://doi.org/10.16373/j.cnki.ahr.150049
Oord,A. van den,Dieleman,s .,Zen,h .,Simonyan,k .,Vinyals,o .,Graves,a .,… Kavukcuoglu,K. (2016)。WaveNet:原始音频的生成模型,1–15。从 http://arxiv.org/abs/1609.03499取回
Kalchbrenner,l . Espeholt,k . Simon Yan,Oord,A. van den,Graves,a .,& Kavukcuoglu,K. (2016 年)。线性时间内的神经机器翻译。 Arxiv ,1–11。从 http://arxiv.org/abs/1610.10099 取回
神经网络高级主题
一些高级神经网络主题的介绍,如快照集、丢失、偏差校正和循环学习率。
本文将介绍神经网络中使用的一些更高级的主题,并将涵盖神经网络研究中仍在讨论的几个重要主题。

Source: Train 1, get M for free.
本文将涉及的主题有:
- 迁移学习
- 调整学习率
- 如何解决过度拟合
- 辍学
- 修剪
您可以访问下面的前几篇文章。第一个为那些不熟悉的人提供了神经网络主题的简单介绍。第二篇文章涵盖了更多的中间主题,如激活函数、神经结构和损失函数。第三篇文章着眼于更高级的方面,如动量、自适应学习率和批量标准化。第四篇文章是关于神经网络中超参数调整的深入教程。
神经网络的详细概述,有大量的例子和简单的图像。
towardsdatascience.com](/simple-introduction-to-neural-networks-ac1d7c3d7a2c) [## 神经网络体系结构综合介绍
神经架构、激活函数、损失函数、输出单元的详细概述。
towardsdatascience.com](/comprehensive-introduction-to-neural-network-architecture-c08c6d8e5d98) [## 神经网络优化
涵盖优化器,动量,自适应学习率,批量标准化,等等。
towardsdatascience.com](/neural-network-optimization-7ca72d4db3e0) [## 神经网络中超参数调整简单指南
关于超参数优化的分步 Jupyter 笔记本演练。
towardsdatascience.com](/simple-guide-to-hyperparameter-tuning-in-neural-networks-3fe03dad8594)
迁移学习
想象一下,你在一家小公司工作,计算资源有限,但被要求开发一种最先进的算法来对不同植物物种的图片进行分类。对于任何试图开发利用计算机视觉(面向视觉的机器学习)的商业解决方案的公司来说,这都是一个相当普遍的问题。
在这种情况下,你(至少)有两个问题。你可以访问的数据量也可能是有限的,计算能力也是有限的。显然,用几十个 GPU 连接一个 150 层的深度神经网络,并训练一个模型几个星期来区分你目前拥有数据的最简单的 1000 种植物物种,以创建你的初创公司的最小可行产品的算法,这是不可行的。
在这种情况下,你能做些什么让生活变得轻松一点呢?
幸运的是,谷歌和微软等几家公司已经发布了针对图像识别进行优化的最先进的神经网络架构。这些公司拥有大量的资源和专业知识,所以你可以相信这些模型比你自己设计的任何内部模型都有更好的性能。
然而,有一个问题是,这些算法训练的数据可能没有(事实上,没有)在你想用算法区分的 1000 种植物物种上训练过。
但是,有一个解决办法:转移学习。转移学习就是将学习从一个模型转移到另一个模型,该模型检查的数据与原始模型的数据非常相似。在这种情况下,原始模型用于一般的图像识别(通常在 CIFAR 数据集上),这非常接近我们正在尝试做的事情。然后,我们可以根据自己的数据重新训练网络的最后几层,以便针对我们的特定应用对模型进行微调。

The weights from a pre-trained model are loaded into the architecture of the new model. Weights from the output layers are trained whilst the other network layers are frozen. The resulting model will be fine-tuned for the required application.
那么这是如何工作的呢?我们首先使用 Keras 构建原始模型的架构,然后加载训练好的网络的模型权重(你需要先下载这些;它们通常以.h5格式出现)。
我们需要做的第二件事是通过设置图层的trainable=False参数来冻结初始图层的权重。这样做的原因是卷积神经网络(用于处理图像)的初始层包含关于图像的原始信息,如线条、边缘、形状和其他低级特征的解释。随着我们深入网络,对象变得更加复杂和高级,这是网络开始更清楚地区分图像质量的地方。
这里的想法是,我们不试图教网络检查图像,因为它已经被谷歌或微软训练得很好。我们只需要针对我们的用例对它进行微调。
因此,我们可以在输出端将完全连接的网络层(或其子集)设置为可训练的,也许最终的卷积层(如果我们有足够的数据)也是可训练的,然后根据我们的数据训练网络。
这一过程具有需要较少数据来训练模型的额外好处,因为网络可训练参数的数量是网络中参数总数的一小部分。

The input layers (e.g. layers 1–4) have relatively little impact on the output for transfer learning as compared with the later layers of the network (e.g. layers 6 and 7).
迁移学习只有在被分析的两个数据集非常相似时才有效。因此,迁移学习最常用于图像识别或语音识别,其中网络可以被训练用于图像的一般识别或声音或给定语言的一般识别。与从头开始训练整个网络相比,使用迁移学习训练网络所需的数据和计算时间要少得多。
请参见“进一步阅读”部分的开源文献文章,以更详细地研究迁移学习。
修剪
模型修剪试图在深度神经网络的各种连接矩阵中引入稀疏性,从而减少模型中非零值参数的数量。
单词‘修剪’来自决策树中的使用,在决策树中,树的分支被修剪,作为模型正则化的一种形式。类似地,神经网络中被认为不重要或很少激活的权重可以从网络中移除,而几乎没有任何后果。事实上,大多数神经元对模型性能的影响相对较小,这意味着即使消除大量参数,我们也可以实现高精度。
随着神经架构和数据集变得越来越大,为了获得合理的模型执行时间,减少网络中的参数数量变得越来越重要。
研究论文进行修剪,还是不进行修剪:探索修剪对模型压缩的功效研究了神经网络作为稀疏度(实际上是去除神经元的百分比)的函数的性能,并发现即使减少网络中 75%的神经元,模型性能也不会受到显著影响。事实上,参数数量减半只会降低 0.1%的精度。**
****
修剪通常在卷积神经网络中进行,然而,由于卷积模型中的大多数参数出现在完全连接的(普通的)神经层中,大多数参数从网络的这一部分中被消除。
在深度神经网络中有多种执行修剪的方式。最常见的方式是权重剪枝。权重修剪根据权重的大小对权重进行排序,因为权重较大的参数更有可能触发,因此更有可能是重要的。
另一种方法是单元修剪,它将权重矩阵中的所有列设置为零,实际上删除了相应的输出神经元。这里,为了实现稀疏度 k% ,我们根据它们的 L2 范数对权重矩阵的列进行排序,并删除最小的 k% 。
第三种更先进的方法是使用 Fischer 修剪,依赖于 Fischer 信息。这产生了一个称为 Fischer-Rao 范数的范数,该范数可用于对参数进行排序。人们怀疑费歇尔信息和参数冗余之间存在联系,这就是为什么这种技术似乎产生良好的结果。你可以在这里阅读更多关于费歇尔修剪:
我想简要强调最近两篇关于修剪神经网络的论文(声明,其中一篇是我们的):克里斯特斯…
www.inference.vc](https://www.inference.vc/pruning-neural-networks-two-recent-papers/)
要查看在标准 VGG16 网络上修剪的代码实现,我推荐阅读这篇优秀的文章:
[## 修剪深度神经网络,使其快速而小巧
我的 PyTorch 实现[1611.06440 修剪卷积神经网络进行资源有效的推断]…
雅各布吉尔. github.io](https://jacobgil.github.io/deeplearning/pruning-deep-learning)**
调整学习率
正如您可能从自己的神经网络冒险经历以及其他文章和研究文献中认识到的那样,学习率是神经网络训练的一个非常重要的部分。
学习速率本质上决定了网络学习的“速度”,它决定了运动的步长。更高的学习速率导致更快的学习,但是收敛更困难并且通常不稳定。较小的学习速率导致较慢的学习,并且尽管收敛是可能的,但它可能仅在过多的时期之后发生,这在计算上是低效的。
显然,对于给定的神经架构,在这两者之间有一个最佳点——这是唯一的,并且是神经损失表面的函数。然而,由于我们正在训练网络,神经架构是动态的,并且不断变化,从而导致最佳学习速率的失真。除了这种时间依赖性之外,最佳点还具有空间依赖性,因为损失表面上的某些位置可能具有非常陡或非常浅的梯度,这使得问题更加复杂。
那么,我们如何选择一个能给我们带来最佳效果的学习速率呢?显然,我们可以使用一个恒定的学习速率,但是如果我们这样做,当我们达到次优的结果时,我们不能抱怨。
获得更好结果的唯一方法是使用动态学习速率,该速率试图利用最佳学习速率的空间和时间变化。这不是一项简单的任务,但是已经开发了几种技术来完成这项任务。
神经网络的循环学习率
周期性学习率是不言自明的,它们本质上是振荡的——它们来回振荡。循环学习率的主要用途是避免局部极值点,尤其是尖锐的局部极小值(过拟合)。鞍点在高维度中是丰富的,收敛变得非常慢,如果不是不可能的话。因此,如果我们使用纯粹递减的学习速率,很容易陷入单一位置,尤其是在更高维度。
*循环学习率周期性地提高学习率。这有短期的负面影响,但有助于实现长期的有益效果。*
降低学习速度仍然有助于减少错误。这可以通过使用阻尼循环学习率来实现,该学习率随着时间慢慢衰减到零。

Examples of cyclical learning rates
虽然这是一个很好的想法,但它没有告诉我们应该设置什么样的学习率方案以及这些学习率的大小。
估计学习率
怎样才能得到一个好的学习率估计值?这看起来很复杂,但实际上并不太难。
首先,我们可以从一个小的学习率开始,然后在每一批中成倍地增加。同时,我们可以计算验证集的损失函数。这也适用于寻找循环学习率的界限。
下图显示了作为时期函数的指数增长的学习率。

Exponentially increasing learning rate across epochs.
同时,我们计算每个学习率的损失函数。

Loss function as a function of learning rate.
我们可以看到,在这两个极端之间有一个悬崖区域,在这个区域中,学习在稳定地减少和稳定地发生。这是我们希望在培训过程中确保我们留在的地区。
带热重启的 SGD
热重启是一个非常简单的想法:在指定的次数后重启学习。例如,学习率最初从 0.1 开始,随时间呈指数下降。在 30 次迭代之后,学习率调度器将学习率重置为与时段 1 相同的值,然后学习率调度器重复相同的指数衰减。每次在重置学习率之前记录最佳估计值。
这个想法类似于循环学习率,除了学习率图通常看起来更像锯齿波,而不是对称和循环的。
需要注意的是,重新开始不是从零开始,而是从最后一次估计开始,并且学习率增加。因此,重启提供了与循环学习率相同的大部分好处,例如能够避开极端的局部极小值。

Warm restarts with cosine annealing done every 50 iterations of Cifar10 dataset.
快照集:培训 1,免费获得 M
快照集是一个很棒的主意,如果你感兴趣,我建议你阅读一下的研究论文。
集合网络比单个网络更加健壮和精确。它们构成了另一种类型的正则化技术。新颖之处在于训练单个神经网络,但获得 M 个不同的模型。想法是收敛到 M 不同的局部最优值并保存网络参数。

Left: Illustration of SGD optimization with a typical learning rate schedule. The model converges to a minimum at the end of training. Right: Illustration of Snapshot Ensembling. The model undergoes several learning rate annealing cycles, converging to and escaping from multiple local minima. Source.
对于那些经验丰富的数据科学家来说,您可能还记得,开发用于分类目的的集成或混合模型通常会提供优于任何单个模型的结果,尽管要确保这一点需要几个要求,例如模型之间相对较高的相关性。这在某种程度上只是该技术在神经网络上的延伸。
那么它是如何工作的呢?
在每个训练周期结束时,模型达到关于训练损失的局部最小值。因此,在提高学习率之前,我们对模型权重进行“快照”。训练完 M 个周期后,我们有 M 个模特快照, f₁,f₂,.。。,每一首都会用在最后的合奏中。在集合模型中,我们取所有快照的平均值,并使用它来获得我们的结果,实现具有平滑参数的神经网络,从而减少总噪声,并因此减少总误差。
需要强调的是, M 快照的总训练时间与使用标准时间表训练模型的时间相同。这意味着我们有一个简单的方法来获得神经网络的集合,而不需要任何额外的训练成本。
然而,快照集不是完美的,可以选择不同的初始化点或超参数选择,这可能收敛到不同的局部最小值。尽管这些局部最小值在平均误差方面表现相似,但它们可能不会犯同样的错误。
集成方法训练许多神经网络,然后通过多数投票或平均预测输出进行优化-这与平均权重并使用这些权重进行预测相反。最终集合由优化路径的快照组成。
下面的结果显示了用于测试神经网络模型的几个公共数据集上的快照集成的结果。

Error rates (%) on CIFAR-10 and CIFAR-100 datasets. All methods in the same group are trained for the same number of iterations. Results of the ensemble method are colored in blue, and the best result for each network/dataset pair are bolded.
从结果可以清楚地看出,快照集合性能优于标准模型,以及循环集合和丢弃模型。
Polyak-Ruppert 平均法
鉴于快照集和 Polyak 平均之间的相似性,我认为最好包括这一点。Polyak 平均是解决刺激快照集使用的不稳定学习问题的另一种方法。该消息使用在训练运行接近结束时看到的多个模型的平均重量。

The motivation behind Polyak averaging — gradient descent with a large learning rate is unable to converge effectively to the global minimum.
假设在 t 迭代中,你有参数θ,θ等。然后,我们可以对这些参数进行时间平均,以获得真实参数的更平滑的估计值。

这可以通过几种不同的方式加以利用:
- 在接近训练运行结束的几个不同时期使用来自相同模型的权重(如上所述)。
- 将来自多个模型的权重用于它们各自的训练运行(整体平均而不是时间平均)。
- 使用来自快照的权重,然后平均这些权重用于集合预测(集合和时间平均的混合方法)。
Polyak 平均保证在凸环境下强收敛。然而,在非凸曲面中(通常是这种情况),参数空间在不同区域会有很大不同。在这种情况下,平均就没那么有用了。在这种情况下,通常考虑指数衰减平均值:

根据所选的α值,将额外的权重放在最新的参数值或较旧的参数值上,由此较旧参数的重要性随时间呈指数衰减。
希望您清楚 Polyak 平均和快照集之间的区别和相似之处。它们只是平滑明显存在于神经网络的不稳定学习过程中的随机误差的不同方式。
在此可以找到应用于神经网络的 Polyak 平均的一个很好的演示:
** [## 如何在 Keras (Polyak 平均)中计算神经网络模型权重的集合
神经网络的训练过程是一个具有挑战性的优化过程,经常无法收敛。这可以…
machinelearningmastery.com](https://machinelearningmastery.com/polyak-neural-network-model-weight-ensemble/)**
如何解决过度拟合
深度神经网络中的过度拟合是如此普遍,以至于你永远无法真正相信你从一个经过训练的网络中获得的结果是最佳结果。鉴于它们的普遍存在,我们将研究一些方法来解决神经网络中的过度拟合问题。
估算师
点估计是试图对一些感兴趣的量提供单一的“最佳”预测:

从频率主义者的角度来看,θ是固定的但未知的,数据是随机的。这意味着我们的估计量是一个随机变量。每个随机变量都容易受到偏差和方差的影响。
- ****偏差:预期值与真实值的偏差。
- ****方差:与预期估计值的偏差。

诊断偏差-方差
那么我们如何在神经网络中分析这种偏差-方差权衡呢?
在高维空间中,我们不能绘制决策曲线来检验偏差-方差。相反,我们通过计算错误值来推断训练集和验证集的错误来源。为了确定偏差,我们需要一个基线,比如人类水平的表现。

****贝叶斯错误率是随机结果的任何分类器的最低可能错误率,类似于不可约误差。对于所有的意图和目的,贝叶斯误差是我们从一个完美的模型中剔除所有可避免的偏差和方差后所能获得的最小误差。
我们可以分析和比较训练集和验证集上的错误,以推断错误的原因,无论它是由于可避免的偏差还是可避免的方差(我们不太可能获得贝叶斯错误率)。

正交化是我们可以使用的另一种技术;它旨在分解过程以调整神经网络性能。它假设误差来自不同的来源,并使用系统化的方法来最小化它们。
Mc.ai 对这个用来调谐收音机的旋钮有一个奇妙的比喻。收音机的设计者努力确保一个特定的旋钮控制信号的一个特定方面,如音量或频率。如果没有多个参数同时变化,调谐到特定的无线电频率并获得您想要的声音会容易得多。
早期停止也是一种流行的正则化机制,但是耦合了偏差和方差误差。
减少偏差的其他更明显的方法是训练更大的模型(增加模型的可解释性),训练更长的时间(达到收敛),或者调整神经架构或执行广泛的超参数搜索。
减少方差的明显方法是获得更多的数据,使用正则化机制(早期停止是一种流行的正则化技术,它结合了偏差和方差误差)。

能够分析网络结果并确定问题是由偏差还是变化引起的,这对于排除网络故障以及提高网络性能非常有帮助。例如,如果您正在努力解决差异问题,并试图运行网络更多的纪元,这显然不会有所帮助。然而,在这种情况下,添加更多的数据或正则化是更谨慎的方法。
辍学
到目前为止,与我在本文中讨论的其他项目相比,你们中的大多数人可能更熟悉辍学。辍学很容易实现,但更难掌握其背后的哲学。
Dropout 是深度神经网络的一种正则化技术。它在训练时使用,随机消除一些单元的输出。这有助于防止网络过于依赖单个神经元,从而有助于防止过度拟合。相反,这些知识被传播到所有的神经元上,以帮助获得一个更健壮的网络。在测试时,所有的神经元都存在,并且它们的触发概率是成比例的,因为在训练时存在比以前更多的神经元。
丢弃可以与其他正则化技术(如 L2、批量归一化等)结合使用。).

****目的:防止特征检测器对一组神经元的共同适应,避免过拟合。
- 它迫使神经元在给定的总体群体行为下,独立地发展个体角色。
- 训练权重被鼓励分布在神经网络中,因为没有神经元是永久的。
****解释:训练示例提供来自不同的、随机采样的架构的梯度。
直接实施:
- 训练时:随机消除一些单位的输出。
- 测试时:所有单元都存在。

反向辍学
对于测试时的正常退出,你必须通过退出率 p 来调整激活,因为你没有退出任何神经元,所以你需要在训练时匹配期望值。
对于反向丢失,缩放在训练时应用,但反之亦然。首先,通过丢失因子 p,丢失所有激活,其次,通过反向丢失因子 1/p 缩放它们。
倒辍有一个好处,就是你在测试的时候什么都不用做,这样推理起来更快。
由于这种更快的推断,大多数当前的实现使用反向下降:
- 在训练期间进行加权。
- 测试时不需要重新称重。
特别地,对于层 l ,



Inverted dropout — weights are scaled at training time as opposed to testing time, the opposite of traditional dropout.
初始化策略
神经网络的权重初始化已经在我的一些其他文章中讨论过了,但是在这里有必要简单地重申一下。
在具有小学习率的凸问题中,无论什么初始化,收敛都是有保证的(尽管可能很慢)。
然而,在非凸区域初始化更为重要。一些参数初始化可能不稳定,并且可能不收敛。神经网络没有被很好地理解为具有原则性的、数学上很好的初始化策略,因此经常使用试探法来选择一组合理的起始权重,从这些权重中训练网络。
对于具有 m 个输入和 n 个输出的全连接层,我们可以从以下均匀分布中进行采样,以获得我们的初始权重:

或者,流行的 Xavier 初始化使用以下参数进行均匀分布。

Xavier 初始化是考虑到网络由没有非线性的矩阵乘法组成而导出的,并且在实践中似乎表现良好。
有关权重初始化方案的完整列表,请查看 Keras 文档的初始化器部分这里。有一打或两个初始化器,也可以使用你自己的自定义初始化器。请参见进一步阅读部分的参考资料。
最终意见
感谢您的阅读,我希望您发现这篇文章很有见地。如果你喜欢这篇文章,请留意我将来关于神经网络的文章。
其他与全连接神经网络相关的高级主题,我将在未来的文章中涉及,读者可能会感兴趣:
- 批次/层/实例/组规范化
- 张量处理单元
- 下拉连接
- 部分池化
- 随机深度
- 断流器
- 混合
- 明凯/MSRA 初始化
时事通讯
关于新博客文章和额外内容的更新,请注册我的时事通讯。
丰富您的学术之旅,加入一个由科学家,研究人员和行业专业人士组成的社区,以获得…
mailchi.mp](https://mailchi.mp/6304809e49e7/matthew-stewart)
进一步阅读
神经网络重要文章
- 神经网络中的深度学习:概述
- 使用神经网络的持续终身学习:综述——开放存取
- 物理储层计算的最新进展:综述—开放存取
- 脉冲神经网络中的深度学习
- 集成神经网络(ENN):一种无梯度随机方法——开放存取
- 多层前馈网络是通用逼近器
- 深度网络与 ReLU 激活函数和线性样条型方法的比较——开放访问
- 脉冲神经元网络:第三代神经网络模型
- 多层前馈网络的逼近能力
- 关于梯度下降学习算法中的动量项
修剪文章
- 运行时神经修剪 林等,2017。
- 深度卷积神经网络的结构化修剪Anjar,Hwang and Sung,2015。
- 用于卷积神经网络的快速算法Lavin 和 Gray,2015。
- 学习修剪卷积神经网络中的滤波器 黄等,2018。
- 剪枝,还是不剪枝:探索模型压缩中剪枝的功效 朱、古普塔,2017。
- 修剪卷积神经网络进行资源高效推理 莫尔查诺夫等人,2017。
- 通过 L0 正则化学习稀疏神经网络 作者Louizos 等人,2018。
- 使用密集网络和 Fisher 剪枝的更快凝视预测Theis 等人,2018。
重量初始化
- 理解训练深度前馈神经网络的困难。
- Saxe 等人在 2013 年提出的深度线性神经网络中学习的非线性动力学的精确解。
- Sussillo 和 Abbott 2014 年为训练非常深的前馈网络进行随机行走初始化。
- 深入研究整流器:在 ImageNet 分类上超越人类水平的性能,何等,2015。
- krhenbüHL 等人,2015 年,卷积神经网络的数据相关初始化。
- 你需要的只是一个好的 init,Mishkin 和 Matas,2015。
- 修正初始化:无归一化的残差学习,张等,2019。
- 彩票假说:寻找稀疏、可训练的神经网络,Frankle 和 Carbin,2019 年。**
如何建立一个先进的推荐引擎
当快速简单的协同过滤已经不够好的时候该怎么办。
知道你的起点
重要的是要记住,你不应该从推荐引擎的高级用例开始。在快速简单地实现版本 1 之后,你的推荐引擎变得非常适合你的业务问题、产品和用户。为了构建这样一个定制的模型,您将需要来自版本 1 的反馈循环和基线来决定您的推荐引擎的改进方向。对于定制的解决方案,敏捷是成功实现这一目标的最佳方法。实际上,这意味着在您开始任何版本 2 的工作之前,您已经构建了版本 1.1、1.2 和 1.3。

[OC]
对于第 1 版推荐引擎,根据您的起点,您有多种选择:
- 如果您了解您的产品或者您的产品有丰富的元数据,您可以首先构建一个简单的规则引擎来捕获业务逻辑。考虑到敏捷和实用的交付焦点,知道什么时候不需要机器学习是很重要的。
- 如果您碰巧也认识您的用户,那么您甚至可以使用一些基本的用户细分来个性化您的规则引擎,例如 RFM。
- 但是大多数时候你对你的用户和产品不够了解,甚至一无所知。你所拥有的只是来自用户与你的网站或产品互动的行为点击流数据。在这种情况下,您应该考虑使用协同过滤来构建您的第 1 版推荐引擎。此使用案例在中有详细说明:
第 1 部分:简介,如何在一周内投入生产,之后去哪里
towardsdatascience.com](/how-to-build-a-recommendation-engine-quick-and-simple-aec8c71a823e)
您迈向版本 2 的道路
祝贺您,在您部署了推荐引擎的第 1 版之后,是时候庆祝您的成就了!你的第一个推荐引擎已经上线了,它的表现足够好,利益相关者希望你改进它,而不是让它下线。🎉
不幸的是,对于如何从这里改进你的推荐引擎,没有什么灵丹妙药。你将慢慢地构建一个高度定制的解决方案,而现实中的成功之路看起来更像是一场火的洗礼。你将通过大量的实验和从失败中学习来交付解决方案。),可能是迫于利益相关者、你的老板和愤怒的用户越来越大的压力。

[OC]
您将在版本 1 中面临的问题:
- 新内容和用户的冷启动问题
- 偏向于点击诱饵内容:良好的响应指标,随后在漏斗中急剧下降
- 您的建议在质量和数量之间难以取舍
- 巴特 UX
- ETL 和 elasticsearch 集群的昂贵费用
让我们看看我们在第 1 部分中实际构建了什么,以及它与更复杂的推荐系统相比如何:

[OC]
我们从最简单的模型开始:基于项目到项目共现的推荐引擎。就如何解释分数而言,这个模型非常类似于一个分类器,我们距离个性化的项目排名还有很长的路要走。这是一个常见的误解,当将推荐整合到产品中时,假设分数反映了个性化的排名或考虑/相关性分数,这可能会损害用户体验。
使您的模型有状态,以获得更好的模型评分
如果你按照前面的步骤用 Elasticsearch 构建了一个快速简单的协同过滤推荐系统,那么你的第 1 版模型可能并不完美,但在某种程度上是可行的。在改变整个实现之前,尝试简单地改进当前版本的评分请求可能是值得的。
你在第 1 部分中构建的是一个无状态模型。无状态模型不记得也不关心之前的事件。每个用户交互和评分请求都是完全独立的。因此,无状态模型非常容易管理,例如,允许在简单的负载平衡器后面进行水平扩展。
这提供了第一个明显的改进:将一个状态合并到您的模型中。用户与网站上的一系列产品和内容进行互动。向您的模型添加一个状态内存允许您使用一个交互系列为用户查询 Elasticsearch,这扩展了匹配的可能性。一方面,您可以简单地使用它来扩展前台数据集中潜在的同现数量。另一方面,您可以在更复杂的规则中使用它来过滤相关的推荐,例如删除用户以前已经看过的推荐。

[OC]
但是,您希望避免向模型本身添加状态。理想情况下,您总是将状态管理器从模型的其余部分中分离出来。状态管理器应该是一个独立的微服务,它使用某种形式的缓存来丰富来自网站或应用程序的无状态传入请求。将状态作为独立的微服务来管理是一个很好的设计原则,也是我之前在博客中提到的 Rendezvous 架构设计的一部分(我在那篇博客中称之为模型数据丰富器):
如何构建一个前沿的数据科学平台来解决数据科学中的真正挑战:生产化。
towardsdatascience.com](/rendezvous-architecture-for-data-science-in-production-79c4d48f12b)
Redis 是处理推荐系统状态的一个很好的解决方案。它速度快,重量轻,在任何云中都是完全托管的服务,例如 Redis 的 AWS ElasticCache。下面的代码使用一个滑动窗口 TTL 来存储用户交互,并自动从缓存中删除旧的交互。请随意根据您的需求进行调整:
[## 简·泰希曼/ redis_user_interaction_cache
GitLab.com
gitlab.com](https://gitlab.com/jan-teichmann/redis_user_interaction_cache)
这个选项的好处:你获得了更大数量的同现信号,并且有机会过滤掉用户已经看过的推荐。这可以在不增加额外工作的情况下提高数量和质量。
这个选项的缺点:不要期待奇迹:你仍然只是用同样的原始数据工作。回报是递减的,你能从同样的数据中获得的附加值也是有限的。
添加越来越多的数据
因为你只能从相同的数据中获得如此多的额外价值,所以我们有另一个明显的方法来改进我们的推荐系统。你的用户可能会以多种不同的方式与你的网站、应用和产品互动:
- 搜索产品
- 查看产品详情
- 购买产品和退货
- 评价和分享产品
- 参与营销,使用折扣代码
你的推荐引擎的第一个版本只使用了一个用户交互,并且基于隐式反馈来最大化推荐质量的信号量。加入额外的数据是值得的,特别是为了提高推荐的质量和获取所需的业务逻辑。
最简单的选择是,按照与第一个指标完全相同的逻辑,向现有的 Elasticsearch 集群添加一个额外的文档类型。Elasticsearch 中的文档类型类似于 RDBs 中的表。然后,对每种文档类型分别运行两个并行查询,这两个查询可以独立调整,以反映度量的质量。您可以通过调整 Elasticsearch 的 significant_terms 聚合中的“min_doc_count”设置或切换用于定义重要推荐的统计数据来实现这一点。您可以阅读文档中的可用选项,并查看我的另一篇文章中的代码示例:
第 1 部分:简介,如何在一周内投入生产,之后去哪里
towardsdatascience.com](/how-to-build-a-recommendation-engine-quick-and-simple-aec8c71a823e)
此选项的优势:易于实施,因为您只需重新利用现有的解决方案和代码,将额外的数据作为独立的文档类型接收。这为在弹性搜索推荐的基础上构建复杂的规则引擎提供了广泛的选择,以纳入所需的业务逻辑,例如,对促销的偏好。
这个选项的缺点:增加了弹性搜索集群的成本。
随着您向模型中添加越来越多的指标,您将会注意到,不仅您的 Elasticsearch 集群的成本失控,您的规则引擎中处理信号的时间和 CPU 资源也同样急剧增加。您的规则引擎将信号转换成最终的建议开始变得非常复杂。对规则引擎的回顾可能会得出这样的结论:您正在处理数据之间的复杂关系,对于这些用例有更好的解决方案:可能是时候考虑一个图形数据库了!

Apache Tinkerpop 3 logo. Fair usage
图形数据库是高度相关数据的完美解决方案,例如大量的关系以及复杂的关系。graph DB 将这些关系具体化为图中的边,从而大大加快了基于数据(节点)之间的关系的查询速度,而不是在每个查询中动态地解决这些关系。graph DBs 有许多供应商,给出任何建议都超出了这篇博客的范围。这可能是一篇即将发表的博文的主题。

Taken from the Apache Tinkerpop documentation: https://tinkerpop.apache.org/docs/current/tutorials/the-gremlin-console/ Fair usage
此选项的优势:可以快速处理复杂的关系,用复杂的业务逻辑打开复杂的用例。
这个选项的缺点是:你必须将你的推荐逻辑转换成图形查询。
改善您的用户定义
协同过滤建立在用户交互数据中的共现之上。如果你的企业没有一个强大的单一用户定义,那么就很难创建一个好的记录长期用户交互的历史矩阵。

Recreation of illustration in “Practical Machine Learning, Ted Dunning & Ellen Friedman, O’Reilly 2014
结果,在根据用户交互的历史建立的同现矩阵中将有少得多的信号。
当您的用户使用多种设备,并且没有动力创建帐户或登录以使用您的服务时,可能会出现这种情况。如果你的网站上有很大比例的匿名流量,那么看看一个概率模型来识别一段时间内跨设备的单个用户是值得的。

Public domain image, Pxhere
Gartner 将跨设备识别(XDID)称为值得关注的新兴技术,数据科学可以提供帮助。识别用户的不同选项有:帐户登录、Cookie 识别、设备指纹识别和 IP 匹配。
IP 匹配是较低质量的概率选项,用于识别单个用户。然而,IP 是跨设备可用的。与 4G 网络或公共 Wifi 一样,动态共享 IP 也存在问题。无论如何,IP 是最可行的选择。我写了一整篇关于使用 IP 和时间戳的图表来匹配单个用户和 Spark 的 GraphX 引擎的文章:
[## 使用 GraphX 跨设备为匿名用户匹配单个用户标识
如何实现概率会话相似性来为跨设备和匿名用户创建单个用户 ID…
towardsdatascience.com](/single-userid-matching-for-anonymous-users-across-devices-with-graphx-72fe111ac44b)
这个选项的好处:跨设备匹配单个用户可以显著提高同现信号的质量,并且具有远远超出单独推荐的用例。
这个选项的缺点:单用户匹配本身就是一个复杂的话题。这既是一个有趣的数据科学问题,也是一个难以解决的数据工程挑战。
批量计算信号
到目前为止,我们一直使用 Elasticsearch 作为后端,实时计算推荐信号。这在建议路线图的早期阶段很有价值,可以进行灵活的实验,例如在数量和质量之间进行权衡。以这种方式使用 Elasticsearch 的缺点是每个查询都有很大的 CPU 开销。如果协同过滤对您的使用情况很有效,那么最好选择一个更好的协同过滤算法,并批量计算推荐信号,而不是匆忙计算。这样,我们只将 Elasticsearch 作为向用户提供推荐的表示层。
我们可以简单地批量计算项目-项目共现信号。这可以通过 CLI 中存在的 Mahout 的 spark-itemsimilarity 实现来完成。这使得调用 Mahout 库中的 spark 程序并为其提供相关数据的路径变得非常简单。你可以在 Mahout 网站上找到详细的文档。您还可以看到 Mahout 的解决方案架构与我们的相似之处。我们使用 Elasticsearch 而不是 Solr 和 Redis 作为用户交互的缓存。其余部分遵循完全相同的解决方案架构。

https://mahout.apache.org/docs/latest/algorithms/recommenders/
**spark-itemsimilarity Mahout 1.0****Usage: spark-itemsimilarity [options]****Input, output options**-i <value> | --input <value>Input path, may be a filename, directory name, or comma delimited list of HDFS supported URIs (required)-i2 <value> | --input2 <value>Secondary input path for cross-similarity calculation, same restrictions as "--input" (optional). Default: empty.-o <value> | --output <value>Path for output, any local or HDFS supported URI (required)**Algorithm control options:**-mppu <value> | --maxPrefs <value>Max number of preferences to consider per user (optional). Default: 500-m <value> | --maxSimilaritiesPerItem <value>Limit the number of similarities per item to this number (optional). Default: 100Note: Only the Log Likelihood Ratio (LLR) is supported as a similarity measure.**Input text file schema options:**-id <value> | --inDelim <value>Input delimiter character (optional). Default: "[,\t]"-f1 <value> | --filter1 <value>String (or regex) whose presence indicates a datum for the primary item set (optional). Default: no filter, all data is used-f2 <value> | --filter2 <value>String (or regex) whose presence indicates a datum for the secondary item set (optional). If not present no secondary dataset is collected-rc <value> | --rowIDColumn <value>Column number (0 based Int) containing the row ID string (optional). Default: 0-ic <value> | --itemIDColumn <value>Column number (0 based Int) containing the item ID string (optional). Default: 1-fc <value> | --filterColumn <value>Column number (0 based Int) containing the filter string (optional). Default: -1 for no filterUsing all defaults the input is expected of the form: "userID<tab>itemId" or "userID<tab>itemID<tab>any-text..." and all rows will be used**File discovery options:**-r | --recursiveSearched the -i path recursively for files that match --filenamePattern (optional), Default: false-fp <value> | --filenamePattern <value>Regex to match in determining input files (optional). Default: filename in the --input option or "^part-.*" if --input is a directory**Output text file schema options:**-rd <value> | --rowKeyDelim <value>Separates the rowID key from the vector values list (optional). Default: "\t"-cd <value> | --columnIdStrengthDelim <value>Separates column IDs from their values in the vector values list (optional). Default: ":"-td <value> | --elementDelim <value>Separates vector element values in the values list (optional). Default: " "-os | --omitStrengthDo not write the strength to the output files (optional), Default: false.This option is used to output indexable data for creating a search engine recommender.Default delimiters will produce output of the form: "itemID1<tab>itemID2:value2<space>itemID10:value10..."**Spark config options:**-ma <value> | --master <value>Spark Master URL (optional). Default: "local". Note that you can specify the number of cores to get a performance improvement, for example "local[4]"-sem <value> | --sparkExecutorMem <value>Max Java heap available as "executor memory" on each node (optional). Default: 4g-rs <value> | --randomSeed <value>-h | --helpprints this usage text
此选项的优势:更便宜的批量评分版本,同时仍然易于使用和操作。
这个选项的缺点:没有太多的灵活性和复杂性。这将使您的弹性搜索成本得到控制,但不会提高您的推荐的性能,如果这是您的版本 1 实施的一个问题。
使用潜在因素模型改进您的算法选择
在我们决定批量创建我们的推荐之后,我们将模型的训练、评分和服务分离为多个步骤。这也为我们研究更复杂的推荐算法打开了大门,而不仅仅是我们目前使用的基于共现的模型。下一步将是使用矩阵分解的基于潜在因素模型的推荐系统。

[OC]
潜在因素模型将允许我们创建(1)使用产品因素相似性的项目-项目模型和(2)项目-用户模型。

[OC]
批量潜在因素模型的一个好的解决方案是 Spark 中的 ALS(交替最小二乘法)实现,这是一种用于推荐引擎的矩阵分解技术。它被称为交替最小二乘法,因为该算法分别在改善项目和用户因子之间交替:该算法首先固定用户因子,然后对项目因子运行梯度下降。然后,它切换和固定项目因素,以改善用户因素。ALS 算法具有很强的可扩展性,可以以分布式方式并行运行,并使用 Spark ML 非常高效地处理大型数据集。
你可以在文档中找到一个用 Spark ML 实现 ALS 的例子。我们仍然使用前面讨论过的相同的解决方案架构,Spark ML 提供了为用户项目模型创建建议的方法。

[OC]
但是,我们必须编写一些自定义代码来计算一个项目-项目模型的产品因素的相似性。计算产品之间所有对的相似性不适用于大型产品目录。不断增长的组合数量 O(n^2) 很快导致代价过高的洗牌操作和不可行的计算时间。Spark 提供了一个使用位置敏感散列法 ( LSH )的解决方案,这是一个更加有效的识别近似最近邻居的方法。LSH 使用一种特殊的哈希函数来降低数据的维度,同时数据越相似,哈希冲突的可能性就越大。这意味着相似的数据可能会出现在同一个存储桶中,而不会出现在具有不同数据的存储桶中。LSH 是一种概率近似值,它提供了速度和准确性之间的权衡。对于我们的项目-项目推荐模型的项目潜在因素的聚类问题,我们使用 随机投影 作为我们的散列函数,其近似为余弦相似度用于我们的产品向量的分块。
以下代码是一个使用 Spark ML ALS 进行协同过滤和 LSH,根据项目相似性创建项目-项目模型的示例:
import pyspark.sql.functions as F
from pyspark.ml.evaluation import RegressionEvaluator
from pyspark.ml.recommendation import ALS
from pyspark.sql import Row# ALS Example from the Spark Documentationlines = spark.read.text("sample_movielens_ratings.txt").rdd
parts = lines.map(lambda row: row.value.split("::"))
ratingsRDD = parts.map(
lambda p: Row(
userId=int(p[0]), movieId=int(p[1]),
rating=float(p[2]), timestamp=int(p[3])
)
)ratings = spark.createDataFrame(ratingsRDD)
(training, test) = ratings.randomSplit([0.8, 0.2])
# Build the recommendation model using ALS on the training data
# Note we set cold start strategy to 'drop' to ensure we don't get NaN evaluation metricsals = ALS(
maxIter=5, regParam=0.01, userCol="userId", itemCol="movieId",
ratingCol="rating", coldStartStrategy="drop"
)
model = als.fit(training)# Evaluate the model by computing the RMSE on the test data
predictions = model.transform(test)
evaluator = RegressionEvaluator(
metricName="rmse", labelCol="rating", predictionCol="prediction"
)
rmse = evaluator.evaluate(predictions)
# Root-mean-square error = 1.7866152217057665**####################################################
# User-Item model predictions using latent factors #
####################################################**# Generate top 10 movie recommendations for each user
userRecs = model.recommendForAllUsers(10)
# Generate top 10 user recommendations for each movie
movieRecs = model.recommendForAllItems(10)
userRecs.show(1, False)
“””
+------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|userId|recommendations |
+------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|28 |[[12, 4.987671], [81, 4.968367], [92, 4.862609], [31, 4.0329857], [49, 4.024806], [2, 3.8403687], [82, 3.7117398], [62, 3.4866638], [61, 3.4003847], [24, 3.1223223]]|
+------+-------------------------------------------------------------
“””**#####################################################
# Item-Item Model based on latent factor similarity #
#####################################################**from pyspark.ml.feature import BucketedRandomProjectionLSH
from pyspark.ml.linalg import Vectors, VectorUDTvector_udf = F.udf(lambda l: Vectors.dense(l), VectorUDT())itemFactors = model.itemFactors.withColumn(
'itemVector', vector_udf(F.col('features'))
)brp = BucketedRandomProjectionLSH(
inputCol="itemVector", outputCol="hashes", bucketLength=2.0,
numHashTables=3
)# Hashes of factors match with a probability proportional to their
# cosine similarity
brp_model = brp.fit(itemFactors)recommendations = (
brp_model
.approxSimilarityJoin(itemFactors, itemFactors, 2.0,
distCol="dist")
.select(
F.col("datasetA.id").alias("idA"),
F.col("datasetB.id").alias("idB"),
F.col("dist")
)
.filter('idA != idB')
.withColumn('recommendation', F.concat_ws('-',
F.when(F.col('idA') < F.col('idB'),
F.col('idA')).otherwise(F.col('idB')),
F.when(F.col('idA') < F.col('idB'),
F.col('idB')).otherwise(F.col('idA')))
)
.select('recommendation', 'dist').distinct()
.orderBy(F.col('dist'))
)recommendations.show()
“””
+--------------+------------------+
|recommendation| dist|
+--------------+------------------+
| 15-99|0.6752175108957209|
| 78-86| 0.766118452902565|
| 17-46|1.1002650472525193|
| 15-97|1.1036687784393326|
| 15-78|1.1089519518538236|
“””
完整的代码示例可在此处找到:
[## Spark ALS 项目-项目相似性(1915919 美元)片段
GitLab.com
gitlab.com](https://gitlab.com/snippets/1915919)
此选项的优势:更便宜且可扩展的批处理模型,同时提供用户-项目和项目-项目模型。
这个选项的缺点:更复杂的模型,有更多的超参数来调整 ALS 和 LSH。
为您的数据和模型找到更多应用
迄今为止,你的模型产生了一些建议,但这不一定是使用你的行为数据和潜在因素模型的唯一方式。你的公司可能有一个客户关系管理或营销团队,他们会喜欢一些细分作为他们的目标。行为数据可以成为产品和用户细分的真正资产。

[OC]
你可以在我之前关于这个主题的文章中读到关于使用你当前推荐引擎的数据和算法进行细分的内容:
新的黄金标准:使用机器学习从行为数据中获得用户和产品分类,为一个…
towardsdatascience.com](/data-science-powered-segmentation-models-ae89f9bd405f)
这个选择的好处:你让更多的利益相关者参与进来,并且用你的模式创造更大的商业影响。这降低了企业搁置项目的可能性。
这个选项的缺点:你有更多的涉众参与到他们独特的需求和不断增长的改进压力中。数据科学团队需要能够随着需求的增长而扩展。
取代协同过滤作为您的算法
协同过滤一直是一个强大的推荐算法,因为我们不需要了解我们的产品或用户。一方面,我们仅基于显式或隐式反馈来学习推荐。但另一方面,每个推荐都与特定的产品或用户相关联。这有一些缺点:
- 冷启动:任何新产品或新用户都需要反馈,我们才能开始推荐。
- 所有项目完全独立。红苹果和绿苹果在协同过滤中不共享任何反馈或共现信号,即使它们在产品空间中概念上相似。
- 当产品从目录中删除时,我们也失去了针对该产品的所有信号和指标。
为了克服这些问题,我们必须将我们的建议的信号和指标与能够比产品或用户本身寿命更长的功能联系起来,并在更广泛的类似产品和用户中推广。我们需要积累关于我们产品和用户的功能和知识:

[OC]
构建描述产品的特性通常比描述用户更容易:
- 使用计算机视觉对产品图像进行指纹识别
- 使用 NLP 主题建模、单词和文档向量嵌入产品描述
- 地理位置产品的地理区域嵌入(活动、门票、物业列表)
- 产品元数据,如价格、尺寸、重量、类别、关键词、季节、房产列表的卧室数量等。
我之前发表了一篇博文,讲述了使用搜索嵌入创建地理区域嵌入的一个很好的例子:
Zoopla.co.uk 大学使用机器学习(Skip-Gram)和一点黑魔法进行地理区域嵌入。
towardsdatascience.com](/location-location-location-ec2cc8a223b1)
在我们创建了广泛的特征来描述产品和潜在用户之后,我们可以使用神经网络来学习我们基于协同过滤的推荐和我们的新产品特征之间的信号。

[OC]
我们使用连体神经网络来学习产品或用户特征从项目嵌入空间到推荐嵌入空间的映射。项目或用户的推荐嵌入具有比 NN 输入低得多的维度,并且具有通过推荐嵌入空间中的余弦相似性来测量的相似的期望行为。连体神经网络的特点是两个网络的权重相同,并且两个神经网络的梯度下降耦合在一起。在实践中,这是通过使用单个神经网络并依次对两个输入进行评分来实现的:

[OC]
我们使用余弦相似性作为我们的连体神经网络模型的输出:
[@staticmethod](http://twitter.com/staticmethod)
def pairwise_cosine_sim(y1, y2):
"""Calculates the pairwise cosine similarity.
"""
y1_norm = tf.nn.l2_normalize(y1,1)
y2_norm = tf.nn.l2_normalize(y2,1)
return tf.matmul(y1_norm, y2_norm, transpose_b=True)
除此之外,我们的神经网络和其他任何神经网络都没有太大区别。为了训练我们的暹罗神经网络,我们需要定义一个损失函数:对比损失优化一对输入之间的绝对余弦相似性,以最大化正对的余弦相似性,但最小化负对的相似性。
def contrastive_loss(cos_similarity, label, margin=1.0):
"""Contrastive loss function
"""
distance = 1.0 - cos_similarity
similarity = label * distance
dissimilarity = (1 - label) * tf.square(tf.maximum((margin - distance), 0))
return 0.5 * tf.reduce_mean(dissimilarity + similarity)
裕度(在 0 和 2 之间)可以用作训练应该在多大程度上集中于改善配对的相似性而不是相异度的权重。

[OC]
我们还需要用于训练的标记数据。我们可以从版本 1 中使用的 Elasticsearch 集群中获取标签。前景中满足我们质量要求的项目是正对,而其他项目可以充当负对。
连体神经网络的训练循环非常简单:

epochs = 10
optimizer = tf.keras.optimizers.Adam(learning_rate=1e-3)
for epoch in range(epochs):
accuracy = tf.keras.metrics.BinaryAccuracy()
epoch_loss = tf.keras.metrics.Mean()
for item_pairs, labels in ds_train:
with tf.GradientTape() as tape:
item_similarities = model(np.array(item_pairs[0]), np.array(item_pairs[1]))
loss = contrastive_loss(item_similarities, tf.reshape(labels, (1,-1)), margin=1.0)
grad = tape.gradient(loss, model.trainable_variables)
optimizer.apply_gradients(zip(grad, model.trainable_variables))
epoch_loss.update_state(loss)
accuracy.update_state(tf.reshape(labels, (1,-1)), item_similarities)
print(
"Epoch {:03d}: Loss: {:.3f} Accuraccy: {:.3f}".format(
epoch,
epoch_loss.result(),
accuracy.result()
)
)
最终图显示了来自 Spark 示例电影镜头数据集的相似电影的训练 2D 推荐嵌入空间:

[OC]
此选项的优点:不再有冷启动问题!
这个选项的缺点:你需要广泛的有用的项目嵌入作为你的连体神经网络的输入。定义训练标签需要实验:对于您的业务问题,什么定义了一个好的正面或负面项目对?对比损失函数易于实现,但是正负项目对的不平衡可能需要切换到更复杂的损失函数,例如三重损失。

Jan 是公司数据转型方面的成功思想领袖和顾问,拥有将数据科学大规模应用于商业生产的记录。他最近被 dataIQ 评为英国 100 位最具影响力的数据和分析从业者之一。
在 LinkedIn 上连接:https://www.linkedin.com/in/janteichmann/
阅读其他文章:【https://medium.com/@jan.teichmann】
无监督数据增强的半监督学习研究进展

Photo by @bhoogenboom
为什么对人工智能领域很重要?
在这篇文章中,我试图了解半监督学习(SSL)和无监督数据增强(UDA)的进展。首先通过不同的众所周知的机器学习技术。其次,通过阅读最近的一篇博文,以及一篇关于 Google AI 和 UDA 在 SSL 上的文章。
作为一名作家,我解释谷歌大脑成员的文章和谷歌人工智能的博客帖子,可能看起来像一个少年在评论一个职业运动队。如果你和我都是这种情况,我深表歉意,并恳请你的反馈。对我来说,写作是一个学习的过程。
从昨天开始,我表达了花三天时间试图理解三个问题的愿望。
第二天:无监督数据增强(UDA)的半监督学习(SSL)取得了哪些进展,为什么它对人工智能领域很重要?
第三天:SSL 中静悄悄的革命是如何改变行业的?
今天是第二天,我将重点介绍 UDA 在 SSL 方面取得的进步,但首先我将开始解释机器学习中的三种主要技术。如果你对这个题目有所了解,你可以跳过第一部分,直接进入第二部分。
什么是无监督学习,监督学习,强化学习?
为了理解“半监督”,让我们首先简要地看一下非监督学习、监督学习和强化学习。请注意,这里的大部分信息是从维基百科和其他一些地方编辑的版本,大部分是在媒体上研究数据科学的同行作者。这段文字只是为了给术语一个表面的理解。
无监督学习
无监督学习是一种有组织的 Hebbian 学习,有助于在没有预先存在的标签的情况下,在数据集中找到以前未知的模式。它也被称为自组织,允许模拟给定输入的概率密度。
如果这确实是一种希伯来人的学习,那意味着什么?
Hebbian 学习是最古老的学习算法之一,在很大程度上基于生物系统的动力学。当突触两侧的神经元(输入和输出)具有高度相关的输出时,两个神经元之间的突触得到加强。如果你想阅读更多,我建议你看一看 什么是赫比安学 由 Prafful Mishra 撰写的关于这个话题的文章。
Hebbian 理论是一种神经科学理论,声称突触效能的增加源于突触前细胞对突触后细胞的重复和持续刺激。它试图解释突触可塑性,即学习过程中大脑神经元的适应。此外,如果你愿意,你还可以观看有关赫布三大假设的视频:
Thank you to Veer for sharing this video in the article Hybrid Model for Unsupervised Learning.
这个理论是由唐纳德·赫布在他 1949 年的著作《行为的组织》中提出的。这本书是人工神经网络(ANN)发展的基础的一部分。
在心理学中,它是关于哺乳动物大脑中神经元连接如何加强的假设;这也是一种在人工神经网络中选择权重的技术。算法可以更新现代人工神经网络中神经连接的权重。通过改变神经权重和关联,工程师可以从人工神经网络中获得不同的结果。
在赫比学习的风味中:(1) 无监督,权重通过对刺激的实际反应来加强,(2) 有监督,权重通过期望反应来加强。无监督的 Hebbian 学习(联想)具有权重变得任意大的问题,并且没有减少权重的机制。
退一步讲无监督学习是机器学习的三个主要类别之一,包括监督学习和强化学习。
无监督学习中使用的两种主要方法是:
- 主分量
- 聚类分析
主成分分析 ( PCA )是一种统计程序,它使用正交变换将一组可能相关的变量(每个变量取不同数值的实体)的观察值转换为一组线性不相关的变量值,称为主成分。

PCA of a multivariate Gaussian distribution centered at (1,3) with a standard deviation of 3 in roughly the (0.866, 0.5) direction and of 1 in the orthogonal direction. The vectors shown are the eigenvectors of the covariance matrix scaled by the square root of the corresponding eigenvalue, and shifted so their tails are at the mean.
聚类分析用于无监督学习,对具有共享属性的数据集进行分组或分段,以推断算法关系。聚类分析是机器学习的一个分支,它将尚未标记、分类或归类的数据分组。该分析识别数据中的共性,并基于每个新数据段中此类共性的存在或不存在做出反应。这种方法有助于检测不属于任何一组的异常数据点。

The result of a cluster analysis shown as the colouring of the squares into three clusters.
“聚类”的概念无法精确定义,这也是为什么有这么多聚类算法的原因之一。
无监督学习的一个主要应用是在密度估计领域。

Demonstration of density estimation using kernel smoothing: The true density is mixture of two Gaussians centered around 0 and 3, shown with solid blue curve. In each frame, 100 samples are generated from the distribution, shown in red. Centered on each sample, a Gaussian kernel is drawn in gray. Averaging the Gaussians yields the density estimate shown in the dashed black curve.
密度估计的一个非常自然的用途是在 非正式调查中对一组给定的数据 的性质。密度估计可以给出诸如数据中的偏斜度和多模态等特征的有价值的指示。在某些情况下,他们会得出可能被认为是不言而喻正确的结论,而在其他情况下,他们所做的只是为进一步的分析和/或数据收集指明道路。
(1)偏度概率论与统计学中,偏度是一个实值随机变量的概率分布关于其均值的不对称性的度量。偏斜度值可以是正的或负的,也可以是未定义的。许多模型假设正态分布;即数据关于平均值对称。正态分布的偏斜度为零。但实际上,数据点可能不是完全对称的。因此,对数据集偏斜度的理解表明偏离平均值的偏差是正还是负。
法国数学家 benot Mandelbrot 或许可以解读对偏斜度的一个批评。他认为,现代金融和投资理论主体对正态分布的广泛依赖是任何相关模型的一个严重缺陷。他在一本书中解释了他的观点和替代金融理论:《市场的(错误)行为:风险、破产和回报的分形观》(发表于 2004)。我们当然可以问,这种批评是否可以扩展到人工智能领域的某些部分或某些机器学习技术。
(2)多模态在其最基本的意义上是一种交流和社会符号学理论。多模态从文本、听觉、语言、空间和视觉资源——或模式——的角度描述了用于撰写信息的沟通实践。
对于人工智能领域,多模态可能意味着使用机器学习技术一起解释不同的信号,如文本和图片。
科学出版商 IGI 全球对什么叫做 [进行了概述。什么是多模态?](http://-IGI Global)
模态,或者更明确地说,信息表示的模态,是在某种媒体中表示信息的一种方式[……]多模态允许同时综合使用各种形式的交互[……]多种类型的媒体数据,或者数据项的多个方面。它强调的是存在不止一种类型(方面)的数据。例如,一段数字广播新闻视频有多种形式,包括音频、视频帧、隐藏字幕(文本)等。
在统计学中多模态分布是具有两个或更多模态的连续概率分布。要获得更全面的解释,请查看 Purvanshi Mehta 的文章 多模态深度学习 。

A bivariate, multimodal distribution
Vishal Maini 在他关于无监督学习的文章中解释了无监督学习在人类机器学习中的效用(你可以阅读这篇文章以深入了解):
无监督学习经常被用来对数据进行预处理。通常,这意味着在将它输入到深度神经网络或另一个受监督的学习算法之前,以某种保留意义的方式压缩它,如 PCA 或 SVD。
当然,关于无监督学习的话题还有很多要说的,但是我们将继续讨论有监督学习。
监督学习
在监督学习中,一个最佳方案将允许算法正确地为看不见的实例确定类别标签。
两个重要的方面一般说是分类和回归。
分类是识别一个新观察值属于哪一组类别(子群体)的问题。

Drawing from Manish Thapliyal article Machine Learning Basics Supervised Learning Theory Part-1
回归分析是一组用于估计变量间关系的统计过程。

Picture from Dataaspirant’s article from 2014 on the difference between classification and regression in machine learning.
根据 Stuart J. Russell、Peter Norvig (2010)在人工智能:现代方法: 监督学习中的说法,监督学习是学习一个函数的机器学习任务,该函数基于示例输入-输出对将输入映射到输出。
- 从带有训练示例的带标签的训练数据中获取函数。
- 每个例子都是一对(输入-输出)输入对象和输出值。
- 监督学习算法分析训练数据并产生推断函数。
- 推断的函数可用于映射新的示例。
还有比这些更经常传播或共享的步骤。
最佳方案将允许算法正确地确定不可见实例的类别标签。这需要学习算法以一种“合理”的方式从训练数据归纳到看不见的情况。
可能会有一个归纳偏差:学习者用来预测输出的一组假设,给定它没有遇到的输入。尽管大多数学习算法都有一个静态偏差,但一些算法被设计为在获取更多数据时改变其偏差。这并不能避免偏差,因为偏差转换过程本身必然存在偏差。偏见?
一些挑战可能是:
- 偏差和方差权衡。几个不同但同样好的训练数据集。你应该让它灵活地适应数据吗?如果它太灵活,它可能不同地适合每个训练数据集。
- 功能复杂度和训练数据量。具有高偏差和低方差的简单“不灵活”学习算法能够从少量数据中学习。高度复杂的函数将只能从非常大量的训练数据中学习,并使用具有低偏差和高方差的“灵活”学习算法。
- 输入空间的维度。高维空间(100 或 1000)。空间的体积增加太多,数据变得稀疏。例如,计算优化问题中的每个值的组合。如果你想要一个神秘的倾斜,这一点可以被称为维度诅咒。
- 输出值中的噪声。如果期望的输出值经常不正确(由于人为错误或传感器错误),那么学习算法不应该试图找到与训练示例完全匹配的函数。可以通过提前停止和异常检测来减轻噪声(参见无监督学习)。
- 数据的异质性。与同质性(相似性)相对的在特征或内容上多样的输入。
- 数据中的冗余。对重复几次的信息给予更大的权重。这可能意味着在一个数据库中有两个不同的字段,或者在多个软件环境或平台中有两个不同的位置。积极的数据冗余可以保护数据并提高一致性
- 存在相互作用和非线性。线性函数和距离函数与决策树或神经网络的问题。如果每个特征对输出都有独立的贡献,那么第一个可能是(线性/距离)如果特征之间有复杂的相互作用,那么第二个(决策/神经)可能是解决方案。
此外,还有一个普遍的对立问题,即过拟合或欠拟合。

The green line represents an overfitted model and the black line represents a regularised model. While the green line best follows the training data, it is too dependent on that data and it is likely to have a higher error rate on new unseen data, compared to the black line.
统计学中的过度拟合是指“产生的分析过于紧密或精确地对应于一组特定的数据,因此可能无法拟合额外的数据或可靠地预测未来的观察结果”。
当统计模型不能充分捕捉数据的底层结构时,就会出现欠拟合。欠拟合模型是指在正确指定的模型中会出现的一些参数或术语缺失的模型。
什么是好的契合?我们可以从一个更有争议的哲学角度来看这个问题。一个社会科学家、政治家和工程师很可能不同意什么是合适的。归根结底,这是关于模型性能的。人、机器等的性能。做一件工作或一项活动。在算法的制作中,当然会涉及到不同的目标。
威尔·科尔森写了一篇名为过度适应与不适应:一个完整的例子的文章,我推荐你去看看,但是我想在这里提一下这篇文章中的一句话:
为了讨论欠拟合和过拟合,我们需要从基础开始:什么是模型?模型只是一个将输入映射到输出的系统。
没有算法可以解决所有问题。在这种情况下,提到搞笑而严肃的没有免费的午餐定理总是很有趣的。在优化和计算复杂性中,这是一个结果,表明对于某些类型的数学问题,找到一个解决方案的计算成本(计算模型使用的资源),平均到类中的所有问题,对于任何解决方法都是相同的。从这个意义上说,没有捷径可走。

Cartoon by xkcd
然而,Wolpert 和 Macready 已经证明,在共同进化优化中有免费的午餐。这让我们优雅地进入下一部分。
强化学习
强化学习是与监督学习和非监督学习并列的三种基本机器学习范式之一。为什么会这样呢?
它与监督学习的不同之处在于,不需要呈现标记的输入/输出对,并且不需要明确地校正次优动作。相反,重点是在探索(未知领域)和开发(现有知识)之间找到平衡。
强化学习 ( RL )是机器学习的一个领域,它关注的是软件代理应该如何在一个环境中采取行动,以便最大化一些累积回报的概念。
软件代理 :以代理关系为用户或其他程序服务的计算机程序。
我又参考了 Vishal Maini 的一篇文章,这次是关于 强化学习 ,他分享了这个模型:

The agent observes the environment, takes an action to interact with the environment, and receives positive or negative reward. Diagram from Berkeley’s CS 294: Deep Reinforcement Learning by John Schulman & Pieter Abbeel
然而,该模型也可以以这种方式表示:

The typical framing of a Reinforcement Learning (RL) scenario: an agent takes actions in an environment, which is interpreted into a reward and a representation of the state, which are fed back into the agent.
马尔科夫决策过程(MDP) 通常是基本的强化学习经常是如何呈现的另一位作者为走向数据科学 Mohammad Ashraf 在其文章强化学习去神秘化:马尔科夫决策过程(第一部分)中呈现了这个模型:

默罕默德在他的文章中很好地介绍了 MDP,我将引用他文章中我认为有用的几行:
马尔可夫属性声明,“给定现在,未来独立于过去。”一旦知道了当前状态,到目前为止遇到的信息的历史可能会被丢弃,并且该状态是一个足够的统计量,它给了我们对未来的相同描述,就好像我们有所有的历史一样[……]一个马尔可夫回报过程或者 MRP 是一个马尔可夫过程,具有价值判断,表明通过我们采样的某个特定序列[……]马尔可夫决策过程累积了多少回报。MDP 是一个有决策的马尔可夫奖励过程,它是一个所有状态都马尔可夫的环境。
他贴出的一个有趣的例子说明了学生马尔可夫决策过程(MDP)。去学习,去睡觉,去酒吧,去 facebook,去辞职——不好回答?这显然是英属 MDP。

State-value function in student MDP taken from David Silverman’s lecture at UCL.
如果你是一个喜欢看视频的视觉学习者,你可能想看看这篇关于 Arxiv Insights 的强化学习介绍。
我在这里分享一个他在 6:35 展示的模型:

通过反复试验,有一个以最大化长期回报为目标的尝试性任务,代理人在缺乏训练数据的情况下从经验中学习。
前面提到的环境通常被描述为 MDP。这种情况下的许多强化学习算法利用动态编程动态编程技术。
****动态编程指的是通过以递归的方式将复杂的问题分解成更简单的子问题,从而将其简化。如果子问题可以递归地嵌套在更大的问题中,使得动态规划方法是适用的,那么在更大的问题的值和子问题的值之间存在关系。
当一个事物根据它自身或它的类型被定义时,递归就发生了。递归有时在计算机科学、编程、哲学或数学教科书中被幽默地使用,通常是通过给出一个循环定义或自我引用,其中假定的递归步骤不会更接近基本情况,而是导致无限的回归。这类书的词汇表中包含一个笑话条目是很常见的,比如:递归,参见递归。

强化学习是由于它在许多其他学科中的通用性,包括:博弈论、控制理论、运筹学、信息论、基于模拟的优化、多代理系统、群体智能、统计学和遗传算法。
这些不同的机器学习任务:无监督学习、监督学习和强化学习是不同的,但又是互补的。如果你想了解更多,我推荐你阅读 Vishal Maini 在他的人类机器学习系列中的文章。
半监督学习
半监督学习也被描述过,它是监督和非监督技术的混合。
****半监督学习是一类机器学习任务和技术,也利用未标记数据进行训练——通常是少量标记数据和大量未标记数据。半监督学习介于无监督学习(没有任何标记的训练数据)和监督学习(有完全标记的训练数据)之间。
****半结构化数据是结构化数据的一种形式,它不遵循与关系数据库或其他形式的数据表相关联的数据模型的正式结构,但仍然包含标签或其他标记来分隔语义元素并加强数据内记录和字段的层次结构。
当您没有足够的标记数据来生成准确的模型,并且您没有能力或资源来获取更多数据时,您可以使用半监督技术来增加训练数据的大小。
出于这个原因,半监督学习对于网页分类、语音识别甚至基因测序等用例来说都是双赢的。在所有这些情况下,数据科学家可以访问大量未标记的数据,但实际上为所有数据分配监管信息的过程将是一项无法完成的任务。
半监督分类:标记数据用于帮助识别数据中存在的特定网页类型组以及它们可能是什么。然后,该算法在未标记的数据上进行训练,以定义这些网页类型的边界,甚至可以识别现有人类输入的标签中未指定的新网页类型。
无监督数据扩充
7 月 10 日在谷歌人工智能
【无监督数据增强(UDA)】的最近博客文章中提出的方法,采用了高度有针对性的数据增强来产生多样和现实的扰动,并且
强制模型相对于这些扰动保持平滑。
-
使用增强的相似文本或图像的生成示例。用其他相关的例子来充实图片。
-
他们还提出了一种称为 TSA 的技术,可以有效地防止 UDA 在有更多未标记数据可用时过度拟合监督数据。
-
**对于文本,UDA 与表示学习结合得很好,例如 BERT,
并且在低数据区非常有效,其中在 IMDb 上仅用 20 个例子就实现了最先进的性能。对于视觉,UDA 在大量基准测试的
半监督学习设置中减少了超过 30%的错误率。**
-
**最后,UDA 可以有效地利用域外未标记数据
,并在有大量监督数据的 ImageNet 上实现改进的性能。在博客中,他们说:**
我们的结果支持最近半监督学习的复兴,表明:(1) SSL 可以匹配甚至优于使用数量级更多标记数据的纯监督学习,(2) SSL 在文本和视觉两个领域都工作得很好,以及(3) SSL 与迁移学习结合得很好,例如,当从 BERT 进行微调时。
他们展示了两张图片来说明他们的模型:

An overview of Unsupervised Data Augmentation (UDA). Left: Standard supervised loss is computed when labeled data is available. Right: With unlabeled data, a consistency loss is computed between an example and its augmented version

Example augmentation operations for text-based (top) or image-based (bottom) training data.
明天写完更多内容后,我将重温这最后一节。
Arxiv 的在线预印本中有更多内容可供阅读。
这对工业有什么影响?
明天让我检查一下。
这是#500daysofAI 的第 40 天。
希望你喜欢这篇文章,如果有机会记得给我反馈。
什么是#500daysofAI?我正在挑战自己,用#500daysofAI 来写下并思考未来 500 天的人工智能话题。一起学习是最大的快乐,所以如果你觉得一篇文章引起了共鸣,请给我反馈。
ICIAM 2019 深度神经网络可解释性研究进展
关于神经网络可解释性的非常有趣的工作在 ICIAM 会议上提出。
I CIAM 是应用数学界最大的会议,每四年举办一次。今年它位于西班牙的巴伦西亚,有超过 4000 名参与者,35 摄氏度。在大约一百场讲座同时进行的情况下,有许多关于深度学习主题的有意义的讲座。特别介绍了深层神经网络理论基础方面令人兴奋的工作。因此,在这篇文章中,我想分享一个我觉得特别有趣的例子。
即使小心对待,深层神经网络也很难掌握。通常,它们被称为“黑盒”。没有提供关于是什么使神经网络收敛到某个预测的信息。但是……那里到底发生了什么?可解释性是对神经网络为什么会达到某种结果的研究。****
你们中的许多人可能听说过tensor flow playground,,它用简单的例子展示了关于隐藏层的信息。

Example of the Tensor Playground!
如果我们想让自治系统为我们做决定,理解 DNN 的解决方案对自治系统的未来至关重要
解释复杂 DNN 模型预测的一般技术是逐层相关性传播(LRP)。****

Heat map obtained used the LRP algorithm (Lapuschkin et al. 2016)
考虑一幅你想归类为火车、马或船的图片。LRP 首先检查最后一层中的哪些神经元被激活以获得该解决方案,然后它通过不同层跟踪这些神经元的连接,直到原始像素。令人惊讶的是,神经网络不会检查火车或窗户的形状,但会区分火车,因为它看到了铁轨。网络是作弊吗?不尽然,因为它没有被训练成没有轨道的火车图像,比如玩具火车。
所以,也许我们的数据库不够广泛。这是可解释性分析的可能结果之一。
关于可解释性的不同方法的介绍可以在这里找到。
在 ICIAM 深度学习理论进展小型研讨会期间,有一些关于可解释性的演讲,可能最有趣的是来自 Wojciech Samek、Fraunhofer Heinrich Hertz Institute 和 Stephan Waeldchen、柏林工业大学的演讲。
****第一个发言辩论了如何将 LRP 理解为一个深度泰勒分解的预测。关于这些的更多信息和教程可以在他们的 网页 上找到。
研究网络可解释性的方法之一是敏感性分析。为此,梯度的变化被用来分解神经网络,然而,梯度是不可靠的。
敏感性分析研究函数的变化,而不是函数本身的值。

Decomposition of the net f(x) ( W. Samek, 2017).
神经网络斜率分解的更好方法是值分解。这样,连续性很容易保持,不像梯度方法。由于神经网络由简单函数组成,深度泰勒分解比简单泰勒分解更合适。因此,可解释性被逐层解释,然后不同的子功能被聚集。然后,LRP 可以被看作是逐层的泰勒分解:

Deep Taylor decomposition, where f(x) is the function of relevance. And the Taylor decomposition is done by layers ( W. Samek 2019).
****第二个介绍是关于 率失真方法 ,一个非常不同的方法,他们这个方法的目的是找到一个划分 x∈【0,1]ᵈ(数据)】成子集 s 的相关分量及其互补 Sᶜ.
这样,他们同意固定子集 s 并用随机噪声填充 Sᶜ应该产生相同的分类器预测,同时只有 xₛ的信息,如下图所示。

When adding noise to the complementary of S the result of the predictor must be unchanged. ( J. Macdonald et al, 2019).
为此,他们以失真的形式测量分类器预测的变化。我发现这种方法非常有趣,因为它偏离了经典的反向传播或局部线性化方法。然而,在这种方法中发现了一些困难,因为优化是在不同大小的所有可行集合上完成的。寻找相关特征的小集合的计算复杂度,并表明该问题对于 NPᴾᴾ(概率多项式时间)是完全的。因此,通过实现连续的相关分数和集合 s 的某个大小,该问题被放松
正如我所说,神经网络的可解释性对于进一步理解我们的神经网络结果是一个真正有用的新工具。这里有一些的实现,希望能对你自己的结果有所启发。****
也许你会在数据集中发现一些意想不到的东西。
[1] S. Waeldchen,J. Macdonald,S. Hauch 和 G. Kutynion,一个用于解释深度神经网络决策的率失真框架 (2019),arXiv:1905.11092
[2] G. Montavon,S. Lapuschkin,A. Binder,W. Samek 和 K.-R. Müller,用深度泰勒分解解释非线性分类决策,(2016),《模式识别杂志》。
推进企业领域的自然语言处理(NLP)
作者:IBM 研究员 Salim Roukos
在公司庞大的文档和知识库中寻找信息来回答用户的问题从来没有想象中那么容易。答案很可能存在,但由于种种原因,它们往往遥不可及。
首先,与 Web 不同,在 Web 上,信息通过一组丰富的链接连接在一起,并经常以多种形式冗余地捕获(使其更容易找到),企业内容通常存储在筒仓中,关键信息的重复要少得多。此外,搜索企业内容的用户通常会问一些复杂的问题,并期望得到比从 Web 搜索引擎得到的答案更详细的答案。这些问题可能包括产品支持、个人账单、适用于客户合同的最新法规、新闻网站上发现的事件的影响等等。最后,企业通常不愿意依赖“黑盒”人工智能,因为它无法解释其建议,可能需要决策者或最终用户可以解释的技术。
自然语言处理(NLP)通过允许用户更自由地表达他们的信息需求,并为日益复杂的问题提供准确的答案,有望帮助在企业内容中找到如此深刻的信息。然而,企业 NLP 系统经常受到许多因素的挑战,包括理解异构的信息孤岛,处理不完整的数据,从少量数据中训练精确的模型,以及在不断添加新内容、产品、术语和其他信息的变化环境中导航。
IBM Research AI 正在沿着三个不同的主题进行探索,以应对这些挑战并改进企业领域的 NLP。第一个目标是推进人工智能,让系统能够从少量数据中学习,利用外部知识,并使用包括神经符号方法在内的技术来处理结合了神经和符号处理的语言。第二个聚焦于信任 AI ,其中提供了关于系统如何达成决策的可解释性。第三种方法涉及扩展 AI,以允许系统的持续适应和更好的监控和测试,以支持企业严格期望下的语言系统部署。
在这篇文章中,我将通过强调我们在 ACL 2019 会议上提交的四篇论文来提供 IBM Research 的企业 NLP 工作的一些细节(我们所有 ACL 论文的完整列表在此处)。前两篇论文涉及语义解析:第一篇使用抽象含义表示(AMR)语言来表示句子的含义,第二篇创建语义解析器,将用户的问题转换为程序来查询知识库。我还将简要探讨我们将不完整的知识库与文本相结合的工作,以提高回答问题的覆盖率。第四篇论文描述了一种系统,该系统使得主题专家能够为可解释的基于规则的系统微调规则。
1。 【抽象意义再现】 :
AMR 是一种语义表示语言,旨在允许相似的句子具有相同的表示,即使它们的措辞不同。我们展示了 AMR 图,它代表了这样一个问题:“如何删除循环日志文件?”其中概念 amr-unknown 代表被请求的内容(在这种情况下,delete-01ofarg 1byarg 0)。

在之前的工作中,我们介绍了我们基于栈-LSTM 转换的 AMR 解析器(Ballesteros 和 Al-Onaizan,2017 [1]),其语义准确性,或 SMATCH,得分为 65.9%。在这篇论文中,我们描述了几种将 SMATCH 提高到 75.5%的技术,这比早期的 74.4%要好。贡献 1.9%的一种技术是用强化学习来增加训练,以减轻较小的训练数据量。我们使用可能的 AMR 图的采样,希望找到更好的图来学习更好的参数:特别是,我们希望找到最大化预期 SMATCH 奖励的参数。
对于每个句子,我们使用当前的模型参数生成两个图:一个贪婪的最佳图和一个通过从动作空间采样生成的图。梯度近似为(Rennie 等人,2017 年[2])。
贪婪图的匹配作为基线,可以减少梯度估计的方差(Williams,1992 [3])。本文还介绍了在 AMR 2.0 (LDC2017T10)上实现 75.5%的额外功能,其中大部分是新闻内容。我们目前正在探索迁移学习的方法,以将面向新闻的 AMR 解析器扩展到企业内容。
2。 多知识库统一语义解析 :
在许多情况下,用户的问题需要通过查询知识库来回答。我们开发了一种方法,该方法统一了跨多个知识库(KBs)的语义解析,并利用跨查询程序的结构相似性来搜索各种知识库。跨 KBs 的共享缓解了用于构建语义解析器的训练数据的缺乏。我们使用弱监督方法,只有一对用户的问题及其答案,这是通过使用第 k 个 KB 进行训练而获得的。为了克服在所有可能的程序中搜索 KBs 的挑战,我们使用了多策略提取。首先,我们分别为每个领域训练弱监督的解析模型(教师)。第二,我们使用多策略提取将所有的 k 解析器提取到统一的(学生)语义解析器中,学生和 K 教师注意到我们在训练中知道正确的知识库 id,但是在推理过程中不使用该信息。我们在隔夜数据集上进行实验,这是一个具有 7 个 kb 的公共数据集,并且发现与每个教师都单独训练的情况相比,当使用提取的统一解析器(学生)时,性能在准确性上有所提高。
3。 不完整 KBs 上的问题回答增加了文本 :
大多数知识库是不完整的,但是可以提供有用的知识来与文本语料库融合,以找到在知识库或文档中没有完全回答的问题的答案。这项工作解决了企业中常见的知识库和语料库的异构内容,我们使用了(1)基于图关注的知识库阅读器(SGREADER)和(2)知识感知文本阅读器(KAREADER)的组合。
SGREADER 组件使用图形关注技术从其链接的邻居( )中积累每个子图形实体(e)的知识。图形注意机制被特别设计为考虑两个重要方面:(1)邻居关系是否与问题相关;以及(2)邻居实体是否是问题提到的主题实体。在传播之后,SGREADER 最终为每个实体输出一个矢量化表示,对特定于问题的知识进行编码,这些知识由其链接的邻居来指示。
KAREADER 使用门控机制,通过自关注问题编码器与问题主题实体表示的门控混合来替换问题表示。对于该段落,导出了类似的表示。阅读理解系统使用这些融合的问题和段落表征来得出答案。
论文提供了更多关于实验和结果的细节。
企业采用 NLP 的最大挑战之一是从更大更复杂的文本中创建人类可解释的模型的能力。这对于企业来说是必要的,这样才能放心地部署解决方案,更重要的是,利用人类领域的专家来理解和进一步改进 NLP 系统的输出。 HEIDL ,是深度学习的人在回路语言表达式的缩写,是 IBM 创建的一个工具,用于根据精确度和召回率对机器生成的表达式进行排名。
为了评估 HEIDL,IBM Research 和密歇根大学进行了一项研究,对现实世界法律合同中的句子进行分类。数据由 IBM 律师标记,他们梳理了近 150 份合同中的 20,000 个句子,以注释与终止、沟通和支付等关键条款相关的短语。
这些规则是通过深度学习在 IBM 采购合同上学习到的;HEIDL 为人类解释系统正在做什么和改进它提供了高级概念。我们与四位使用 HEIDL 修改规则的数据科学家合作;在 28k 句子的训练集上,所有人都取得了 75%以上的 F 值。此外,当我们在新的非 IBM 合同上进行测试时,HEIDL 系统取得了更好的性能(55%),相比之下,传统的深度学习系统使用 LSTM 网络在相同的 28k 句子上进行训练(44%)。最终,我们的数据科学家可以识别出平均七条规则,在大约 30 分钟内高精度地自动标记近 150 份合同并召回。如果不使用 HEIDL 原型,同样的练习如果手动进行,将需要一周或更长时间。我们计划进行更多的评估,以确认基于 HEIDL 的系统比深度学习系统更强大。
IBM Research AI 和 ACL 2019
IBM Research AI 在 ACL 2019 上的出版物涵盖了我们正在为企业 NLP 领域追求的其他主题;这里列出了和。其中包括的四份出版物,带你了解 Project Debater 的幕后技术,该项目于 2019 年 2 月在三藩市与冠军辩手竞争。您也可以在我们的 2 号展位加入我们,我们将展示一些技术演示,展示我们的一些工作。
参考文献
1.米盖尔·巴列斯特罗斯和亚塞尔·奥奈赞。2017.使用 stack-lstms 进行 Amr 解析。《2017 年自然语言处理经验方法会议论文集》,第 1269-1275 页。计算语言学协会。
2.史蒂文·雷尼、艾蒂安·马切雷特、优素福·姆鲁埃、杰雷特·罗斯和瓦伊巴瓦·戈埃尔。2017.图像字幕的自我批判序列训练。IEEE 计算机视觉和模式识别会议论文集,第 7008–7024 页。
3.罗纳德·威廉姆斯。1992.联结主义强化学习的简单统计梯度跟踪算法。机器学习,8(3–4):229–256。
通过 Alexa 奖推进开放域对话系统
对话式人工智能的进步因 Alexa 奖而成为可能

Photo by Piotr Cichosz on Unsplash
建立一个开放领域的对话系统是最具挑战性的任务之一。几乎所有与开放域对话系统相关的任务都被认为是“人工智能完成的”。换句话说,解决开放域对话系统的问题需要“真正的智能”或“人类智能”。开放领域对话系统需要理解自然语言。缺少预定义的有界解空间和缺少客观的成功矩阵使得响应生成成为非常具有挑战性的建模问题。
为了解决开发这些系统所面临的问题,亚马逊在 2016 年推出了一年一度的竞赛“”Alexa prize。通过这种方式,他们让顶尖的研究人员想出创造性的解决方案。2018 年,比赛的第二次迭代包括提供 CoBot(对话机器人)工具包和各种其他模型,这些模型可以检测敏感内容,评估对话和对话行为检测。
2018 Alexa Prize Finals
介绍
开放领域对话系统需要理解自然语言,以便处理用户查询。由于歧义性和不确定性,开放领域环境下的自然语言理解(NLU)是一个非常困难的问题。为了响应用户的查询,对话系统需要检测他们的意图。开放域对话系统应该理解对话行为、用户话语中的命名实体、检测歧义短语、检测主题、分割句子、检测用户的情感。
“Alexa Prize”的目标是建立能够与人类进行连贯和有吸引力的聊天至少 20 分钟并获得 4 分或更多评分(满分 5 分)的代理。还有许多其他类似的挑战,如“对话系统技术挑战”(DSTC)、“对话式人工智能挑战”(ConvAI),这些都只是基于文本的挑战。
这篇文章概述了 Alexa Prize 团队在构建更好的对话式人工智能方面的进步和新方法。为了进一步理解,用户可以阅读论文“通过 Alexa 奖推进开放域对话系统的艺术状态”。
CoBot(一个机器人开发工具包)
CoBot(一种对话式机器人工具包)的开发是为了最大限度地减少开发人员在基础设施、托管和扩展方面的工作。CoBot 有一些预构建的模型,如主题和对话行为分类器、对话评估器、敏感内容检测。

Figure 1: CoBot Architecture Source
CoBot 有助于测试和评估开发人员所做的修改。它提供了强大的日志记录机制,直接存储在 Amazon Cloud Watch 上。它还有一个开发人员友好的 CLI 界面,可以用来模拟对话和转录对话。通过 CoBot,用户可以利用亚马逊的持久存储、数据库和其他服务,如亚马逊 S3、DynamoDB、QuickSight 等,来执行丰富的数据分析和创建可视化。
自动语音识别
开放域对话系统使用语音数据作为输入。糟糕的语音识别系统和无法识别的单词发音会极大地降低这些系统的性能。因此,对于这些系统来说,在将 ASR 错误提供给管道进行下游任务(如 NLU 处理)之前,能够处理 ASR 错误是非常重要的。参与团队使用不同的方法来处理 ASR 错误。在所有方法中,只有一种方法使用了独特的方法,即通过使用上下文知识库来捕获同音字。通过使用这种技术,命名实体的错误率降低了 10%到 15%。
上下文语言模型适应
NLP 中的传统算法使用统计语言模型来解决歧义。使用上下文信息可以进一步提高当前语言模型的性能。这可以通过两种方式实现。第一种是通过向动态插值框架添加上下文信息,第二种是通过将上下文信息并入神经网络。
在第一种方法中,系统基于上下文信息混合不同的统计语言模型。特别地,通过改变我们的基于 n 元语法的语言模型的内插权重,将各种基于 n 元语法的语言模型混合在一起,以更好地适应和识别用户话语。预测这些插值权重以最大化训练数据的对数似然。
第二种方法包括为递归神经网络(RNN)模型添加上下文信息。会话上下文信息被编码到神经语言模型(NLM)中。使用的模型是 LSTM-RNN。Alexa Prize 团队探索了各种方法来整合上下文信息,以处理社交机器人响应和用户话语之间的差异。
语境话题和对话行为模式
为了引导对话的流程,对话行为(如问候、提问、意见、请求等)作为一般意图是有用的。当它与会话的“主题”结合时,它可以帮助自然语言理解。
为了帮助建立更好的开放领域对话系统,Alexa Prize 团队开发了上下文感知主题和对话行为分类模型。去年比赛的 10,000 个对话被标记为 12 个主题和 14 个对话行为。
敏感内容检测分类器
开放域对话设置伴随着最困难的任务之一,对敏感或攻击性内容进行分类。由于文化差异、种族主义、宗教、讽刺、不规范的词汇,这个问题变得更加具有挑战性。

Figure 2: Two Stage Semi-Supervision for Sensitive Content Detection Source
大多数团队在公开可用的数据源(如 Reddit 和 Twitter)上训练定制模型。Alexa Prize 团队使用两阶段半监督方法生成了常见的论坛对话(该方法如图 2 所示)。
两阶段半监督方法使用攻击性单词黑名单(这是 800 个攻击性单词的手动精选列表)。阶段 1 包括基于出现在所述黑名单中的攻击性词语的总数对论坛对话进行分类。在阶段 2 中,使用弱监督分类器对高度敏感的评论和不敏感的评论进行采样。这个分类器是在有毒的维基百科评论数据集上训练的。采样数据集用于训练 BiLSTM 分类器。对于单词表示,使用了手套嵌入。
语境对话评估者
开放域对话系统的评估是另一个具有挑战性的问题。Alexa prize 评估开放域对话系统的质量,要求用户根据他们希望与 Alexa 交谈的可能性,在 1 到 5 的范围内给出一个评级。但这些评级并不能评估开放域对话系统的回合级性能。

Figure 3: Contextual Conversation Evaluators Source
为了评估开放域对话系统的回合级性能,Alexa prize 团队定义了以下五个指标。
- 可理解的:这个指标检查对话系统的响应对于用户的查询是否有意义。
- 正题或相关:该指标检查对话系统的回复是否离题。例如,如果用户询问澳大利亚队的一名板球运动员,那么回复应该提到同一队的板球运动员。
- 响应不正确:该指标检查响应是否不相关或不适当。
- 有趣的:这个指标检查响应是否包含新颖和相关的信息。例如,对话系统提供关于板球运动员的答案,并提供一些附加信息。
- 继续对话:该指标检查是否基于对话的当前状态,是否有继续对话的自然方式。
Alexa prize 对话(包含大约 160,000 个话语)根据上述五个指标进行了人工注释。图 3 说明了用于训练上下文对话评估者的模型。该模型使用各种特征,如实体网格、情感和上下文来进行评估。
人工智能的优势和劣势
人工智能是试图在人工智能系统中模拟人类推理的新兴技术之一。约翰·麦卡锡在 1950 年发明了人工智能这个术语。
他说,'学习的每一个方面或智力的任何其他特征原则上都可以被精确地描述,以至于可以制造一台机器来模拟它。人们将试图发现如何让机器使用语言,形成抽象概念,解决现在留给人类的各种问题,并改进它们自己。'
人工智能是计算机程序学习和思考的能力。如果一个程序做一些我们通常认为依赖于人的智能的事情,那么一切都可以被认为是人工智能。
人工智能应用的优势是巨大的,可以彻底改变任何专业领域。让我们看看其中的一些
1)减少人为错误:
短语“人为错误”的诞生是因为人类时不时会犯错误。然而,如果程序设计得当,计算机就不会犯这些错误。使用人工智能,决策是通过应用一套特定的算法从先前收集的信息中做出的。因此减少了误差,并且有可能达到更高精度的准确度。
在使用人工智能的天气预报中,他们已经减少了大多数人为错误。
2)代替人类冒险:
这是人工智能最大的优势之一。我们可以通过开发一个人工智能机器人来克服人类的许多危险限制,而人工智能机器人反过来可以为我们做危险的事情。让它去火星,拆除炸弹,探索海洋的最深处,开采煤和石油,它可以有效地用于任何种类的自然或人为灾害。
例:你听说过乌克兰切尔诺比 l 核电站爆炸事件吗?在那个时候,没有人工智能驱动的机器人可以帮助我们通过在早期阶段控制火势来最小化辐射的影响,因为任何接近核心的人都会在几分钟内死亡。他们最终从直升机上远距离倾倒沙子和硼。
人工智能机器人可以用于干预可能有危险的情况。
3)全天候可用:
除去休息时间,普通人每天工作 4-6 小时。人类生来就是为了有时间放松自己,为新的一天工作做好准备,他们甚至每周休息一次,以保持工作生活和个人生活的完整。但使用人工智能,我们可以让机器 24x7 不间断地工作,它们甚至不会感到无聊,不像人类。
例如:教育机构和帮助热线中心收到了许多可以使用人工智能有效处理的查询和问题。
4)帮助做重复性的工作:
在我们的日常工作中,我们将执行许多重复的工作,如发送感谢信、检查某些文档的错误等等。使用人工智能,我们可以高效地自动化这些平凡的任务,甚至可以为人类移除“无聊的任务,让他们解放出来,变得越来越有创造力。
示例:在银行,我们经常会看到为了获得贷款而对文件进行多次验证,这对银行所有者来说是一项重复的任务。使用人工智能认知自动化,所有者可以加快验证文件的过程,客户和所有者都将从中受益。
5)数字辅助:
一些高度先进的组织使用数字助理与用户进行交互,从而节省了对人力资源的需求。许多网站也使用数字助理来提供用户想要的东西。我们可以和他们聊聊我们在找什么。一些聊天机器人的设计方式使得我们很难确定我们是在和聊天机器人还是人类聊天。
举例:我们都知道,组织有一个客户支持团队,需要澄清客户的疑惑和疑问。使用人工智能,组织可以建立一个语音机器人或聊天机器人,帮助客户解决所有的问题。我们可以看到许多组织已经开始在他们的网站和移动应用程序中使用它们。
6)更快的决策:
使用人工智能和其他技术,我们可以让机器比人更快地做出决定,更快地执行行动。在做出决定时,人类会从情感和实践两方面分析许多因素,但人工智能驱动的机器按照编程工作,并以更快的方式交付结果。
举例:我们都玩过 Windows 里的象棋游戏。由于游戏背后的人工智能,在硬模式下击败 CPU 几乎是不可能的。它会根据背后使用的算法在很短的时间内采取可能的最佳步骤。
7)日常应用:
苹果的 Siri 、Window 的 Cortana 、谷歌的 OK Google 等日常应用在我们的日常生活中频繁使用,无论是搜索位置、自拍、打电话、回复邮件等等。
大约 20 年前,当我们计划去某个地方时,我们会向已经去过那里的人问路。但是现在我们所要做的就是说“好的谷歌维萨卡帕特南在哪里”。它会向你显示维萨卡帕特南在谷歌地图上的位置,以及你和维萨卡帕特南之间的最佳路径。
8)新发明:
人工智能正在推动几乎每个领域的许多发明,这些发明将帮助人类解决大多数复杂的问题。
最近,医生可以使用先进的人工智能技术在早期阶段预测女性的乳腺癌。
因为每个光明的一面都有黑暗的一面。人工智能也有一些缺点。让我们看看其中的一些
1)创作成本高:
由于人工智能每天都在更新,硬件和软件需要随着时间的推移而更新,以满足最新的要求。机器需要修理和维护,这需要大量的费用。它的创造需要巨大的成本,因为它们是非常复杂的机器。
2)让人类变懒:
人工智能正在让人类变得懒惰,它的应用程序自动完成了大部分工作。人类倾向于对这些会给后代带来问题的发明上瘾。
失业:
由于人工智能正在用机器人取代大多数重复性任务和其他工作,人类的干预正在变得越来越少,这将导致就业标准方面的一个主要问题。每个组织都在寻求用人工智能机器人取代最基本的合格人员,人工智能机器人可以更有效地做类似的工作。
4)没有情绪:
毫无疑问,机器在提高工作效率方面要好得多,但它们无法取代组成团队的人际关系。机器无法与人建立联系,而这是团队管理的一个重要特征。
5)缺乏创新思维:
机器只能执行那些它们被设计或编程去做的任务,任何超出这些任务的东西,它们都会崩溃或给出不相关的输出,这可能是一个主要的背景。
概要:
以上是人工智能的一些优缺点。每一项新的发明或突破都将两者兼而有之,但我们人类需要注意这一点,并利用发明的积极方面来创造一个更美好的世界。人工智能具有巨大的潜在优势。对人类来说,关键是确保机器人的崛起不会失控。也有人说,人工智能如果落入坏人之手,会毁灭人类文明。但是,没有一个如此大规模的人工智能应用可以毁灭或奴役人类。
代码的出现:SQL + BigQuery

成千上万的程序员正在用他们最喜欢的编程语言解决即将到来的代码挑战。如果我可以利用这个机会来突出 SQL 和最新的 BigQuery 特性的威力,那会怎么样?
2020 年更新:有雪花
使用 SQL 线程检查我的 2020 代码:
以及 GitHub 回购:
GitHub 是超过 5000 万开发人员的家园,他们一起工作来托管和审查代码、管理项目和构建…
github.com](https://github.com/fhoffa/AdventOfCodeSQL/)
降临码 是一个降临日历的小编程难题,为各种技能集和技能水平。
如果您可以使用 SQL 和 BigQuery 来编写编译器、交叉路径、递归运行计算和破解密码,会怎么样?#adventofcode2019,开始啦!
问题 1:递归迭代

在 BigQuery 中运行递归函数并不容易——但是现在我们可以做循环和通用脚本。这是我用来解决第二部分问题的主要循环:
LOOP
IF (SELECT SUM(x) FROM UNNEST(extra) x)<=0 THEN
LEAVE;
END IF;
SET weight= weight+(SELECT SUM(x) FROM UNNEST(extra) x);
SET extra = (SELECT ARRAY_AGG(fuel(x)) x FROM UNNEST(extra) x);
END LOOP;
和一个方便的 SQL UDF:
CREATE TEMP FUNCTION fuel(x ANY TYPE) AS (
GREATEST(0,FLOOR(x/3)-2)
);
我在这里必须解决的最有趣的问题是:我不能有一个cursor来逐行计算每个组件的燃料。所以我必须找出一种并行处理每个 rocket 组件(输入行)的方法——这使得查询方式更加高效。
问题 2:数据作为代码
可以用 SQL 和 BigQuery 写编译器吗?我们完成图灵了吗?

同样,使用脚本LOOP允许我迭代一个输入数组——它定义了从循环中读取时要执行的代码:
LOOP
IF(input[OFFSET(code_pos)]=99)
THEN LEAVE;
END IF;
SET input = (SELECT parse(input, code_pos));
SET code_pos = code_pos+ 4;
END LOOP;
最有趣的部分是我如何使用ARRAY_AGG()和CASE按照指示重写每个数组的内容:
SELECT ARRAY_AGG(k) FROM (
SELECT
CASE n
WHEN x[OFFSET(off+3)] THEN
CASE x[OFFSET(off+0)]
WHEN 1 THEN x[OFFSET(x[OFFSET(off+1)])]+x[OFFSET(x[OFFSET(off+2)])]
WHEN 2 THEN x[OFFSET(x[OFFSET(off+1)])]*x[OFFSET(x[OFFSET(off+2)])]
END
ELSE xx
END k
FROM UNNEST(x) xx WITH OFFSET n
ORDER BY n
然后我不得不面对的最困难的问题是——如何做 99*99 次来找到第二部分的答案?这并不漂亮,但它涉及数组的数组,并在(幸运的)线性空间中进行缓慢的搜索。
警告:搜索 200 个可能的解决方案需要 2 分钟以上。但是由于特定的语句是线性的,你可以跳到正确的结果。
问题 3:我们会在哪里相遇

这是一个有趣的地图遍历问题——对于这个解决方案,我使用了生成 SQL 数组的能力来详细描述每个步骤:
FROM [...], UNNEST(GENERATE_ARRAY(x-move.x, x, IF(move.x>0,1,-1))) arr_x WITH offset n1, UNNEST(GENERATE_ARRAY(y-move.y, y, IF(move.y>0,1,-1))) arr_y WITH OFFSET n2
寻找交叉点的路径之间的连接非常优雅:
USING(arr_x, arr_y)
一个方便的函数解析输入并生成二维运动指令:
CREATE TEMP FUNCTION parse(x ANY TYPE) AS (
CASE REGEXP_EXTRACT(x, '^(.)')
WHEN 'D' THEN STRUCT(0 AS x,-parse_n(x) AS y)
WHEN 'R' THEN (parse_n(x),0)
WHEN 'U' THEN (0,parse_n(x))
WHEN 'L' THEN (-parse_n(x),0)
END
);
我很自豪能够重新分解路径生成代码,使解决方案易于查看:
SELECT ABS(arr_x) + ABS(arr_y) distance, (a.rn + b.rn) wire
FROM (
SELECT * FROM UNNEST(route('L996,D167,R633,...'))
) a
JOIN (
SELECT * FROM UNNEST(route('R995,U982,R941,...'))
) b
USING(arr_x, arr_y)
WHERE a.rn>0 AND b.rn>0
ORDER BY wire
LIMIT 1
问题 4:密码是…
这里的代码非常短!我希望我编写的手动数组位置更少,但是这样做花费的时间比计算一般情况要少:
SELECT *
FROM (
SELECT CAST(FORMAT('%i%i%i%i%i%i',n0, n1, n2, n3, n4, n5) AS INT64) number
FROM (
SELECT n0, n1, n2, n3, n4, n5
FROM UNNEST(GENERATE_ARRAY(1, 5)) n0
, UNNEST(GENERATE_ARRAY(1, 9)) n1
, UNNEST(GENERATE_ARRAY(1, 9)) n2
, UNNEST(GENERATE_ARRAY(1, 9)) n3
, UNNEST(GENERATE_ARRAY(1, 9)) n4
, UNNEST(GENERATE_ARRAY(1, 9)) n5
WHERE n1>=n0
AND n2>=n1
AND n3>=n2
AND n4>=n3
AND n5>=n4
AND (
(n1=n0 AND n1!=n2)
OR (n2=n1 AND n1!=n0 AND n2!=n3)
OR (n3=n2 AND n2!=n1 AND n3!=n4)
OR (n4=n3 AND n3!=n2 AND n4!=n5)
OR (n5=n4 AND n4!=n3)
)
)
)
WHERE number BETWEEN 109165 AND 576723
如你所见,GENERATE_ARRAY()帮助创造了寻找解决方案的空间。
第五天
当我写下这些想法时,问题仍然没有被公布…
嗯……现在是了,但是我要回家了。能不能同时解决?
更新:问题是第 2 天的延续。建造这台“图灵机”在第二天很有趣,但我不想加倍努力。
第六天:图形遍历
浏览图表并不需要花费太多精力来编写脚本——但是它强调了当一个函数必须经历多次迭代时,BigQuery 可能会很慢。在这种情况下,处理 547 条语句需要大约 20 分钟。提醒一下:BigQuery 在处理万亿字节的数据方面令人难以置信,但不一定能解决一般的计算问题。
LOOP
SET steps = steps+1
;
CREATE OR REPLACE TEMP TABLE planets AS
SELECT DISTINCT planet
FROM (
SELECT origin planet FROM t1 WHERE dest IN (SELECT planet FROM planets)
UNION ALL
SELECT dest planet FROM t1 WHERE origin IN (SELECT planet FROM planets)
)
;
IF 'SAN' IN (SELECT * FROM planets )
THEN LEAVE;
END IF;
END LOOP
现在,如果这个问题不是一次性的,我就不会每次都遍历图,而是预先计算一个更好的结构,用所有路径来立即找到交叉点(因为这是树,不是图)。
最后的想法
我会推荐 SQL 作为通用编程问题工具?
不要!
…但对我来说,这是一种尝试 SQL 和 BigQuery 极限的有趣方式。脚本是一个新特性,我还在适应它的语法和局限性。到目前为止,一切顺利。
作为奖励:使用这些技巧来打动你的朋友!
(可以代码 763369-9f36786d 加入 BigQuery SQL 排行榜)
代码的来临——你的新节日惯例!
在庆祝节日的时候,强化你解决问题和编码的能力

Photo by Mourad Saadi on Unsplash
要旨
伙计,我真的需要温习一下
。 我应该检查一下
。我看到它越来越多的出现,对我来说精通它将变得很重要。
你最近和自己进行过多少次这样的对话?机会是,你至少有过几次,而且我们大多数人也会欣然承认,我们对此也没做什么。好吧,这里有一个有趣的节日惯例可以帮助你:代码的出现!
事实真相
“代码的来临”是一年一度的系列日常编码挑战,发生在年终假期期间。虽然它的名字暗指基督教传统,但这是一个简单的双关语选择,旨在传达该系列的 25 天性质(来吧,来吧!).从 12 月 1 日到 12 月 25 日,每天都会发布一个新的谜题。这些谜题通常会沿着一个奇妙的故事情节串连起来,让你在接受挑战的时候也能得到娱乐。这是去年的一个例子:
示例拼图(2018 年第一天)
感觉自己已经摔倒了几分钟后,你看着设备的小屏幕。"错误:设备在第一次使用前必须校准。检测到频率漂移。无法维护目标锁。在信息下方,设备显示一系列频率变化(您的谜题输入)。像+6 这样的值意味着当前频率增加 6;像-3 这样的值意味着当前频率降低 3。
例如,如果设备显示+1、-2、+3、+1 的频率变化,那么从零频率开始,将发生以下变化:
电流频率为 0,变化为+1;结果频率 1。电流频率 1,变化为-2;结果频率-1。电流频率-1,变化为+3;结果频率 2。电流频率为 2,变化为+1;结果频率 3。在本例中,结果频率为 3。
以下是其他示例情况:
+1,+1,+1 的结果是 3
+1,+1,-2 产生 0
-1,-2,-3 的结果是-6
从零频率开始,应用所有频率变化后的结果频率是多少?
此时,页面上有一个链接可以让您以文本文件的形式获取完整的输入序列(大约一千个输入)。这就是你解决问题的技巧和软件实现的诀窍之间的结合点。
小心点!大多数人会很高兴地一头扎进读取输入的反刍代码,然后当他们意识到是时候实现核心算法时,他们会低头沉思。首先花点时间确保你完全理解了手头的问题,并且(至少在精神上)在奔向 I/O 代码之前形成算法解决方案。
为什么你应该这样做
您不需要使用任何类型的重要计算硬件来参与这些挑战——请随意将您的云计算思维模式放在一边,让您自己回到您的第一个数据结构和算法努力的单一机器、单一问题思维模式中😉。由埃里克亲自设计的拼图👏的设计使得以蛮力方式解决问题将花费太长时间,但是以更智能的方式解决将在商品硬件上最多 15 秒内解决难题。
你也不需要使用任何超级优化的编程语言。请注意,由于解决难题的正确方法会在几秒钟内给你答案,解决方案的真正区别在于开发时间。因此,用解释语言(Python、R 等)编写的适当方法将优于用编译语言(C、Rust、Go 等)编写的简单方法。我爱这方面。有些人喜欢抱怨什么是最好的,因为你总是可以优化它,让它运行得更快,更接近裸机等等。然而,算法在硬件上的运行速度通常不是终端系统的瓶颈:
与编译器支持的程序优化相反,算法解决方案中更昂贵的因素往往是开发人员解决问题的时间、缺乏并行性或 I/O 拥塞。
你上一次参加一家老牌软件公司的面试,他们强迫你选择一种语言是什么时候?[ ]通常情况下,你会被迫(或者明确地,或者通过一次失败的面试暗示地!)提供模块化、高效且可扩展的解决方案。所有这些在任何图灵完全语言中都是可行的。因此,忘掉本系列的语言战争,把注意力集中在这个问题真正的智力实质上。
事实上,许多人在这里完全摒弃竞争,把代码的出现作为学习一门新语言的机会。就我个人而言,我计划在 Python 中完成我的第一关,然后在 Go 或 Javascript 中跟进(必须保持面向未来的🧐).无论你是在寻找激烈的竞争,一个学习的机会,还是在这个假期建立一个好习惯的机会,考虑在《代码降临》中找到它!
准备好了吗?
从回顾过去几年的一些谜题开始。感受到你更有竞争力的一面了吗?使用代码498713-51f0c909在此加入私人排行榜,看看您与其他参与者的匹配情况。
分享你的观点
你为什么打算或不打算参与此事?如果你不是,什么会改变你的想法?
你有没有屡试不爽的方法来保证长时间完成像这样的日常任务的习惯?
你还想分享什么?
[ ]:我希望你们中没有太多人参加过这样的采访😬。
冒险刮:冒险时间抄本的文本挖掘
当代动画倾向于看似为儿童制作,但对成人有深远影响的卡通…因为它们情节的突然发展,复杂的角色情感,以及太真实的笑话。冒险时间就是这样一个让你说“哦,我的球”的节目!
冒险时间是卡通网络上一部长期播放的卡通片,以许多看似不相关的“每周任务”剧集和彩色(我敢说是迷幻)艺术而闻名。前四五季几乎没有什么情节,但最终它对角色的定期轮换有了更一致的情感发展。我非常喜欢节奏的变化,并想知道我是否可以使用数据来跟踪角色的发展。所以,让我们开始数学的东西!
供参考:所有代码都在这个回购中。
注意:下面会有一些剧透…但由于该剧于 2018 年 9 月结束,我假设你有足够的时间赶上!
其他注意事项:这是我的第一个机器学习项目,因此代码不是为了效率而优化的,而是为了清晰或短期效用。
What’s more algebraic than Adventure Time? Data analysis of Adventure Time!
创建数据集
网页抓取
由于《冒险时间》是一部电视剧,我搜索了剧集剧本的抄本。许多收藏有丰富的文本,但没有人物标签,除了组织得非常好的冒险时间粉丝维基的抄本部分。
我按照这个指南开发了一个脚本来搜集这些抄本。我从脚本的登陆页面开始,沿着剧集列表往下看,因为它们是按时间顺序排列的(信不信由你,大多数粉丝维基按剧集标题的字母顺序排列脚本)。我是这样做的,并将文本保存到 HTML 文件中:
import requests
import urllib.request
import time
from bs4 import BeautifulSoupurl = ‘[https://adventuretime.fandom.com/wiki/Category_talk:Transcripts'](https://adventuretime.fandom.com/wiki/Category_talk:Transcripts')
response = requests.get(url)soup = BeautifulSoup(response.text, “html.parser”)anchors = [a for a in (td.find(‘a’) for td in soup.findAll(‘td’)) if a]for i in range(0,len(anchors)):
if anchors[i].has_attr('href'):
link = anchors[i]['href']
actual_link = '[https://adventuretime.fandom.com'+link](https://adventuretime.fandom.com'+link)
file_name = './transcripts/adventure_time_ep'+str(i)+'.html'
urllib.request.urlretrieve(actual_link,file_name)
file = open(file_name,'r')
new_file = [n.replace('<dl><dd>','') for n in file.readlines() if n.startswith('<dl')]
file.close()
new_name = open('./transcripts/adventure_time_ep'+str(i)+'_redacted.html','w')
for k in range(len(new_file)):
new_name.write(new_file[k]+'\n')
new_name.close()
time.sleep(1)
虽然这部剧有 283 集,但我只找到了 213 份抄本。其中一些不完整。我预计会有不完整的,混乱的数据,因为所有这些文字记录都是粉丝在志愿者的基础上生成的。
数据清理+数据帧创建
接下来,我必须清理这些数据并为其创建一个数据结构。我选择的结构受到了大卫·罗宾逊在他对《真爱至上》人物网络的分析中的结构的启发:一个熊猫数据框架,其中每一行都是脚本中的一行,我表示剧集编号、行号、演讲者和相关内容。为了进一步分解内容,我把内容分成对话或动作;在绝大多数抄本中,动作用括号[]表示,或者在角色的台词中,或者作为一种舞台指示。下面是一个原始数据的例子,来自这一集:
泡泡糖公主:多棒的一击。谢谢你们再次挽救了局面,孩子们。
芬恩:不客气,公主。她拥抱了他。嗯…[他脸红了,杰克扬起眉毛,觉得很有趣。 ]
泡泡糖公主:我要给你们两个办一个派对。今晚在糖果王国见面!
我把对话和动作分开,不仅仅是因为它们被括号清晰地分开了,我还假设这两者会不同地定义一个角色的个性。这里值得注意的是,在实际的 HTML 文件中,我已经去掉了 HTML 的所有文本格式。
当然,即使有了这些格式化原则,数据也不像我希望的那样干净…

The ultimate saying for data cleaning.
下面的代码块演示了我如何将 DataFrame 字段从原始 HTML 文件中分离出来。获取情节和行号很简单,但区分对话和动作可能很有挑战性。一个角色的“台词”可以包含多段对话和动作,因此我创建了一系列条件来捕捉它们。虽然它不是最干净的代码,但它完成了工作。
import requests
import urllib.request
import time
import os.path
from bs4 import BeautifulSoup
import pandas as pd
from lxml import html
import numpy as np
import relen_anchors = 280
size = len_anchors*2000
eps = [“” for x in range(size)]
lines = [“” for x in range(size)]
names = [“” for x in range(size)]
dialogue = [“” for x in range(size)]
actions = [“” for x in range(size)]end_of_last_k = 0
for i in range(len_anchors):
if os.path.exists(‘./transcripts/adventure_time_ep’+str(i)+’_redacted.html’):
html = open(‘./transcripts/adventure_time_ep’+str(i)+’_redacted.html’,’r’)
soup = BeautifulSoup(html, “lxml”)
for script in soup([“script”, “style”]): *# remove all script and style elements*
script.extract()
text = soup.get_text()
text_by_line = text.split(‘\n’)
text_no_breaks = [l for l in text_by_line if len(l) > 0]
num_lines = len(text_no_breaks)
line_count = 0
for k in range(num_lines):
eps[k + end_of_last_k] = i *#track episode number*
lines[k + end_of_last_k] = k *#line number in given episode*
if len(text_no_breaks[k]) > 1: *#sometimes a "line" is just a space...*
line_count = line_count + 1
split_up = text_no_breaks[k].split(‘:’,maxsplit=1) *#speaker name separated from main text by colon*
this_lines_actions = []
words = []
if re.match(r’^\W’,text_no_breaks[k]): *#if no colon, it's the narrator/stage directions*
person = ‘Narrator’
words.append(text_no_breaks[k])
this_lines_actions.append(words)
elif len(split_up) == 2:
person = split_up[0] *#text before colon*
else:
print(“Error in split!”,i,k,text_no_breaks[k])
names[line_count + end_of_last_k] = person
more_words = []
if not ‘Narrator’ in person:
split_by_italics = split_up[1].split(‘[‘)
if len(split_by_italics) > 1:
for w in range(len(split_by_italics)): *#len > 1 indicates actions are present*
if ‘]’ in split_by_italics[w]: *## the rest of this code catches multiple action and dialogue segments in one line*
an_action = split_by_italics[w].split(‘]’)
if len(an_action[0]) > 0:
thing = []
thing.append(an_action[0])
this_lines_actions.append(thing)
if len(an_action[1]) > 0:
thing = []
thing.append(an_action[1])
more_words.append(thing)
else:
if len(split_by_italics[w]) > 1:
this_thing = []
this_thing.append(split_by_italics[w])
more_words.append(this_thing)
elif len(split_by_italics) == 1:
more_words.append(split_by_italics)
if len(more_words) == 1:
dialogue[line_count + end_of_last_k] = more_words[0]
elif len(more_words) > 1:
no_spaces = []
for y in range(len(more_words)):
if len(more_words[y][0]) > 2:
no_spaces.append(more_words[y])
dialogue[line_count + end_of_last_k] = no_spaces
if len(this_lines_actions) == 1:
actions[line_count + end_of_last_k] = this_lines_actions[0]
elif len(this_lines_actions) > 1:
actions[line_count + end_of_last_k] = this_lines_actions
end_of_last_k = k + end_of_last_k
数据帧编译的其余部分是这里是。当然,清洁工作并没有就此结束…
数据清理,第二部分
《冒险时间》的一个显著特点是里面出现了大量的角色。当然,他们中的绝大多数最多出现几次,但是创作者非常小心地给他们所有人以不同的声音和外观。然而,这个特性也有不好的一面——在创建我的 DataFrame 之后,我发现了大约 1700 个“独特的”字符!
他们是谁?事实上,许多人是“临时演员”——市民、糖果人等等。其他人是出现过一两次的独特个体,像比利或和平大师。当然,有些名字拼错了,长名字的字符用缩写表示(例如,团块公主变成了 LSP 泡泡糖公主成了 PB)。然而,最令人不安的是,我发现舞台指示已经悄悄出现在角色名和冒号之间!

不用说,我需要将许多不同的名字组合成它们所代表的一个人,这很快使我决定只集中分析几个重要的人物。下面是我使用的函数:
def combine_names_in_list(list_of_grps,which_name):
list_of_dfs = [df.loc[df[‘Character’] == x] for x in list_of_grps]
new_df = pd.concat(list_of_dfs)
limit_which_name = len(list_of_grps)
if which_name <= limit_which_name:
for i in range(limit_which_name):
new_df.loc[new_df[‘Character’] == list_of_grps[i], ‘Character’] = list_of_grps[which_name]
else:
print(“Improper which_name value!”)
return new_df
以下是我必须清理的一些例子:
bmo_list = [‘bmo’,’beemo’,’bmo (flashback)’,’bmo (os)’,’bmo (vo)’,’bmo [as bebe]’,’bmo [as lorraine]’,’bmo [as officer davis]’,’bmo [as ronnie, deeper voice]’,’bmo [as ronnie]’,’bmo [flashback]’,’bmo [in its thoughts]’,’bmo [narrating]’,’bmo & bubble’]
bmo_df = combine_names_in_list(bmo_list,0)marceline_list = ['marceline','marc','marcelince','marceline and ghosts','marcy','teenage marceline','young marceline' ]
marceline_df = combine_names_in_list(marceline_list,0)
一些清理工作需要关于演出的知识:
hunson_list = [‘hunson’,’hunson abadeer’,’lord of evil’]
hunson_df = combine_names_in_list(hunson_list,1)
重要的是,我发现芬恩+杰克比剧中的其他角色有更多的台词,所以我认为芬恩+杰克是我的数据框架中他们自己的“角色”。下面是一个结构示例,为了便于查看,各列之间用“||”隔开:
Index || Episode || Line || Character || Dialogue || Action
__________________________________________________________________
434 || 2 || 17 || ice king || what?! , who dares enter the ice kingdom?! || approaches the crater
436 || 2 || 19 || ice king || you know why i’m here? do you know what ice king means?!
439 || 2 || 22 || ice king || it means i’m king of ice! this is my domain! and you are violating ice world law — trespassing!
446 || 2 || 29 || ice king || i don’t care! this is my kingdom. you guys can’t just scoot about on my land willy-nilly. i’ve got rules here. || annoyed
449 || 2 || 32 || ice king || what?! iam the king! i am the king of c-cool c-co ca… that’s it! rise, monsters of snow, and go beat up finn and jake! || flips out, uses magic to bring out snow monsters
将所有这些迷你数据帧连接成一个大数据帧的代码在这里。终于可以发掘一些数据了!
数据探索,文本挖掘风格
为了逐字分析,我首先按照指南将数据符号化。这里的“标记化”意味着一个字一个字地分离文本数据,创建一个数据帧,对于每个抄本行,该数据帧具有对应于对话和/或动作的每个字的列。我把对话和动作分开符号化了。在我忘记之前,这里是探索性分析代码。
有了标记化的数据,我们可以很容易地计算出哪些词在语料库中出现得最频繁。我看了一下给定角色的整体和每集。结果可能不会让你惊讶…

Most prevalent words in Princess Bubblegum speech for several episodes.
也就是说,最常见的单词是冠词(例如,“the”、“an”)和代词。由于这些词在言语中占据了很大的空间,它们只在更罕见、更独特的词的上下文中提供意义。我们如何找到这些词,我们如何衡量它们的影响?
文本挖掘中经常使用的一种方法是计算 TF-IDF 统计量。这种统计允许我们对一个文档中的单词相对于同一语料库中的其他文档的唯一性进行加权,从而确定哪些单词最能定义每个文档。在诺瓦克的博客文章之后,我计算了这个统计数据和 TF-IDF 计算所需的其他数据。现在让我们来看看 TF-IDF 是如何定义泡泡糖公主的演讲的!

TF-IDF for some Princess Bubblegum speech.
这些数据看起来很不一样。第一个值得注意的特点是第 155 集的两个峰值——因为泡泡糖公主在那一集只说了两个词,这些词有着不相称的重要性。“gah”的权重更大,因为在她说话的其他剧集中,“okay”是一个更常见的词。我们还看到,这两个图的 x 轴显示了非常不同的单词;TF-IDF 几乎没有展示任何填充词。从这些数据来看,这几集的主角是莱蒙霍普(第 153 集和第 154 集)或詹姆斯和詹姆塞夫妇(第 158 集)。通过 Fandom Wiki 检查,这似乎是正确的!因此,对于这个数据集,TF-IDF 可能是了解一集关键特征的好方法,而不一定是角色的情绪或对它的贡献。
因为 TF-IDF 看起来很强大,一些不同的单词应该在多集中出现,我想知道某些单词的重要性如何随着时间的推移而变化(即随着集数的增加),这是否可以代表人物的发展。下面的代码显示了我如何将 TF-IDF 数据作为时间的函数来构建。请注意,我是从包含 TF-IDF 数据的多索引数据帧开始的,其中我按单词和剧集进行索引。
words = tf_idf.index.get_level_values(level=1).unique().tolist() *## get all unique words in character's speech*
get_more = tf_idf.swaplevel(i=0, j=1, axis=0) ## remove hierarchical indexing, level by level
get_more.unstack()
get_more.reset_index(level=1, inplace=True)
get_more.reset_index(level=0, inplace=True) ## word and Episode are both columns now, rather than indices
for word in words:
collection = get_more.loc[get_more[‘dialogue word’] == word]
if len(collection) > 1:
collection.plot(kind=’line’,y=’tf_idf’,x=’Episode’,title=’Word: ‘+word,marker=’.’,xlim=(0,279))
plt.show()
plt.close()
泡泡糖公主的一些著名例子如下。我发现有趣的是,她只在节目的最开始使用了“皇家”这个词,而当时她是一个相当古板、控制欲强的君主。

“知道”的重要性的演变很有趣,因为她变得更有自我意识,而不是无所不知,她对这个词的使用时好时坏。

为了对比这些,我们来看一个非常常见的词“the”,它的 TF-IDF 变化很大,但幅度始终很小:

最后一次看泡泡糖公主的数据,我不得不看到她对“玛西琳”的使用是如何随着时间的推移而改变重要性的。我们可以看到《玛瑟琳》的 TF-IDF 在 200 集左右达到峰值。我知道 Fandom Wiki 关于围绕玛瑟琳背景故事的迷你系列的赌注数据非常不完整,所以我知道这不是飙升的原因。然后我想起“恶棍”发生在赌注前不久,虽然这份记录也不完整,但一切都更有意义了。(对于外行人来说:这一事件是泡泡糖公主和玛瑟琳关系的转折点。)

在这种背景下,我不得不看看“marcy”数据是什么样子的。

事实上,我们看到“marcy”在“Varmints”中成为一个相对重要的术语,并在大约 100 集之后出现,表明他们之间的互动发生了变化。这么少的数据点,我认识到我真的在字里行间,但很高兴在这个简单的统计中看到性格增长的签名!
从这里开始,自然的下一步将是情感分析,或者针对每个角色,或者作为区分剧中角色的一种手段。然而,我只有大约 1000 句台词给泡泡糖公主,可能还有大约 1200 句台词给剧中的两个主要角色,我认为这是一个冒险的尝试。然而,关于 Finn 和 Jake 的数据要多得多,他们每个人大约有 7000 和 5000 行…
infinerator:完全不同的东西
虽然总体上我对机器学习还很陌生,但我已经意识到深度学习仍然是趋势。我对机器学习新闻的细读表明,深度学习越来越多地应用于通常保留给 NLP 的领域。因此,我没有进行情绪分析,而是直接进入了深度学习。
我决定为芬恩制作一个语音生成器…芬恩生成器。(“InFINNerator”是一个三重双关语,所以要记住。)

Behold.
除了“对话”,我没有给演讲贴上任何标签;通常,情感分析寻找好的和坏的,并且它需要标记的数据。在对这个数据集进行了所有的初始清理之后,我需要从数据集构造和变更中休息一下。也许有一天我会用近似情绪来标记对话,但目前手工标记这些数据的时间成本太高了。
内嵌器是一个用 PyTorch 编写的字符级递归神经网络(RNN ),运行在 Google Colab 上。我跟随这个伟大的 PyTorch 教程去了解 PyTorch 中 RNNs 的基础知识。我很快发现,在后启示录时代,用来生成名字的简单架构无法为一个热情的人生成语音。
(我不会在这里展示 RNN 的代码,因为它与 RNN 的其他代码非常相似。有兴趣的请看 Colab 笔记本!)
在深入研究 RNN 变更之前,我首先应该说,我必须为这个任务进一步修改我的数据结构。我注意到对话行中有一些 Unicode 字符;我把所有东西都改成了 ASCII。此外,直接从抄本的行是高度可变的长度,这将在数据中产生不必要的复杂性。我打乱了这些行,然后在用一个行尾字符将它们分开后,我将所有的行连接在一起。为了创建序列,我将语料库分成 64 个字符的新行。
我对 RNN 的第一个改进是小批量训练。最初,我一次训练一个热字符,每个梯度步骤在一个 64 字符的行被处理后完成。对于小批量,一个渐变步骤在一个 64 字符的行经过一批行的处理后结束(我使用 32 行的批量)。这导致了一些小的改进。这种单层香草 RNN 产生了很多感叹号的胡言乱语。然而,公平地说,这是第一次尝试,芬恩通常对任何事情都非常兴奋,所以这确实抓住了他外在表现的本质。下面是输出的一个例子:
他回家了,是吗?int n!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
所以,我不得不把它提高几个档次。我把香草 RNN 换成了 LSTM 的网络。这个 LSTM 有 1-2 层和一个线性解码器,最后我返回了 LogSoftmax 分布的输出。LSTM 的灵感大致来源于 RNN 这个角色。
我尝试了几种架构:
- 1 层,hidden_layer_size=256,学习率=4e-4,1e-3
- 2 层,隐藏层大小=256,学习率=1e-4,4e-4
- 1 层,hidden_layer_size=512,学习率=1e-4,4e-4,1e-3
- 1 层,hidden_layer_size=1024,学习率=1e-4,4e-4
不幸的是,这些增强的 LSTM 的性能并不比小批量的香草 RNN 好多少…如果我真的改进了 InFINNerator,我会更新这个帖子!现在,享受甜蜜的芬兰尖叫声吧。

You can hear this image, can’t you?
与此同时…我有一些想法,为什么这没有我希望的那样好:
- Google Colab 偶尔会忘记它正在运行的代码的状态,这可能会导致训练中的不一致
- 数据集很小,而《冒险时间》是一部主题变化很多的电视剧,所以数据可能太不稳定了。老实说,由于我总共只有大约 300,000 个字符,我预计会超出数据…但似乎更多的训练时间或更大的网络会有所帮助。
- PyTorch 有些秘密我还没有发现。
如果您对 InFINNerator 或这里的任何其他内容有任何反馈,请告诉我!我在这个项目中学到了很多,关于机器学习、文本挖掘和深度学习,我还有很多要学。感谢阅读!
酒吧凳子的比萨饼数据中的冒险
【想看更多数据科学项目?查看我的网站或我的 T2 推特

New York Pizza Reviews
今年 1 月,我搬到纽约,花了 6 个月时间从事非盈利性数据科学工作,但从未涉足 5 个行政区中的任何一个。这里的人们非常重视他们的比萨饼,所以我想在我被更高的租金和更差的比萨饼困住之前吃最好的。
这篇文章的其余部分是对纽约披萨数据的统计分析(从一个名为 Barstool 的网站上搜集来的),其中包括逆向工程 API、有趣的地图和统计技术,我之前没有充分的理由去尝试这些技术。(如果您只想查看图表或玩玩地图,请向下滚动,直到看到另一张地图)。因为我在纽约的时间有限,所以我需要积极地进行优先排序。但当你在谷歌上搜索“纽约最好的披萨”,你要么会得到数千份由不同人评论的名单,要么你会在 Yelp 或 OpenTable 等网站上得到聚合的伪匿名评论。
但是这些选项没有一个能真正为高质量的评估工作。有没有更好的方法来思考这个问题?Yelp/OpenTable 的数据并不好,因为这些消费者只评论他们已经去过的餐厅,而平台本身过滤掉了评论。更不用说一个人的 4/5 星级很可能与另一个人的不一样,严重偏向聚合。没机会了。我可以汇总整理过的名单并寻找趋势,但在 Eataly 的名单上排名第四比在“纽约游客的冒险”博客上排名第一更重要吗?这并不清楚(如果可以的话,我宁愿不去搜索一百个不同的网站,老实说,大部分都是这样)。
最好的情况是,一个人不得不随机去一家比萨饼店,用足够精细的尺度来查看它,以获得概率密度。这样做足够多的次数会让我们明白一个 8.2/10 真正的 意味着什么。如果平均评论是 9.7/10,8.2 可能是垃圾,或者如果平均评论是 5/10,这可能是惊人的。
搜索
带着这个想法,我去寻找一个好的披萨评论数据集。我无意中发现了一个看似金矿的地方,酒吧凳子的戴夫·波特诺伊。戴夫每天都会评论纽约的一家披萨店,并将这些评论发布在 Instagram 和他们的移动应用 One Bite 上(如果你有时间,可以看看他们的一些评论,他们很热闹,但他们对披萨很认真)。我兴奋地给他们发电子邮件,要求查看他们的数据。但是,不出所料,他们不想让一个随机的数据科学家读取他们的数据库。我独自一人。
逆向工程
他们的披萨数据存放在两个地方,一个是在的 Instagram 上,另一个是他们的移动应用 One Bite(如下图所示)。

对于 Instagram 抓取,我可以雇佣土耳其机械工人来听每一条评论,并将其输入数据库,或者自己动手。鉴于有数百条评论,以及随之而来的明显的伦理问题,机械土耳其人不是一个选项。
如果我可以记录通过应用程序的 web 流量,并对他们的 API 进行逆向工程,会怎么样?我发现了一个名为 charles 的应用程序,它将 web 流量推送到 iPhone 上,以帮助应用程序开发人员更有效地调试。如果我可以将它用于稍微不同的目的,并在我使用该应用程序时通过查尔斯虹吸我的 iPhone 的网络流量,我可以尝试逆向工程他们的 API。事实证明,这非常有效(我们坐在制作互联网教程的巨人的肩膀上)。他们有一个场馆端点,当点击它时,会返回惊人数量的数据,包括场馆的名称和位置,以及来自社区的分数,基本上可以读取他们的数据库。
端点的安全性极低,在服务器或设备端没有验证过程,并且可以基于位置、存储类型和数据中的任何其他特征进行查询。唯一的问题是端点最多返回 50 个位置,但我通过在美国随机生成 10,000 个位置并将其用作查询字符串的输入,成功获得了 463 条披萨评论,从而解决了这个问题。
数据
这些数据包罗万象。戴夫给这个地点的评论分数,社区的分数,披萨店的名字。甚至到应用程序中使用的缩略图的链接,以及到保存所有媒体的 AWS s3 存储桶的链接(仅供参考:这样做不是最好的主意)。最后。我在地理制图中需要的唯一缺失的字段是经度和纬度,所以我使用了 Google maps 反向地理编码器来获取这些信息。我已经把所有的数据放在这个 GitHub repo 里,任何人都可以随意摆弄。
首先,我想弄清楚最好的披萨都聚集在哪里。纽约的某些地区比其他地区更擅长做披萨吗?我使用开普勒(优步的开源地理可视化框架)来获得得分最高的点评披萨店的聚类,并在这里托管了互动地图作为沙盒供任何人分析。在 NYU 和索霍区,以及布鲁克林的威廉斯堡,有一些非常棒的披萨店。

请随意在开普勒(或任何其他地方)内使用这些数据,可视化披萨数据真的很棒。
数据探索
在讨论数据分布的问题之前,我们的样本是从哪里生成的?假设评论大多来自口头推荐,单个人评论的绝对规模将有助于对披萨评论进行更细致的分析。

大量的披萨评论发生在纽约,仅在曼哈顿就有大约 250 条评论(另有 20 条左右来自布鲁克林,还有拉斯维加斯、迈阿密等地的少量评论)。其他城市甚至没有 20 个评论。如果我们通过评论数来看排名前几的城市,我们就会明白为什么大量的评论是判断质量的必要条件。

对于纽约,评论的数量足够高,开始接近比其他城市更容易识别的分布(这是较大样本的预期)。我猜想,每个城市都有自己的比萨饼质量的真实分布,一个小样本更可能有精选的例子,告诉我们实际质量很少。所有数据的中值审查得分为 7.1,标准偏差为 1.78。数据集中排名前五的披萨店中有三家在纽约,几周前,我去了最好的披萨店(Di Fara ),尽管要花两个小时才能吃到一片,但很值得。请参见下面的前 5 名。

8.1 有多好?
我的下一个问题有点技术性。披萨分数的潜在密度是多少?8.1 比 9.5 好多少?仅仅知道中间值是远远不够的。同样,我认为单个数据分数是真实质量感知分布的样本。然后,我用一个核密度估计器来估计这个概率密度函数。通俗地说,KDE 是一种不用做很多假设就能理解全部数据的方法。在这个数据中,我不想假设数据以任何一点为中心(比如说,假设大多数评论都在 5 左右),或者它是均匀分布的。在 KDE 的博客上有一篇优秀的博文,它可能会给出比大多数大学课程更好的直觉,的论文描述了这种方法。Scipy 有一个很好的方法来计算 KDE,并从中取样。

Fitting the Gaussian KDE
一旦我适应了这个密度,我就从中取样以获得一个更健壮的数据集。密度直方图如下。有了这个,我可以估计一个比萨饼店是否在纽约市的前 x%的位置,这比简单地从应用程序的数据中计数要重要得多。

Histogram of Pizza Reviews with KDE
该数据集还包括应用程序用户的比萨饼评级。我用和以前一样的方法来估计社区的密度,并把两者都画在下面。

该应用程序的用户倾向于遵循与 Portnoy 相同的密度,0 左右的评论明显更多(一堆苛刻的评论),但也更多地高于中位数。这通常遵循我之前的假设,即评论者在他们的评论中更加两极分化。
鳍状物
这些数据同样很难获得,玩起来也很有趣,如果你对以上所做的任何事情有任何问题,请联系我,在 tylerjrichards@gmail.com 或者在这里!
其他尚未完成但可能很有趣的项目是根据位置和价格预测披萨评论,为类似的披萨店创建推荐算法,以及根据地铁站绘制最近的披萨店地图。
机器学习中的对抗性攻击及其防御
刘玲教授在 2019 年 IEEE 大数据大会上的主题演讲笔记
ig 数据驱动的机器学习和深度学习已经在许多领域取得了令人印象深刻的进展。一个例子是 ImageNet 的发布,它由 22,000 个类别的 1,500 多万张带标签的高分辨率图像组成,彻底改变了计算机视觉领域。最先进的模型已经在 ImageNet 数据集上实现了 98%的前五名准确率,所以看起来这些模型是万无一失的,不会出错。
然而,对抗训练的最新进展发现,这是一种错觉。当面对对立的例子时,一个好的模型经常会出错。下图说明了这个问题:

Image taken from https://towardsdatascience.com/breaking-neural-networks-with-adversarial-attacks-f4290a9a45aa
该模型最初对熊猫图片进行了正确的分类,但当一些人类察觉不到的噪声注入到图片中时,模型的最终预测变为另一种动物长臂猿,即使有如此高的置信度。对我们来说,似乎最初的和改变的图像是相同的,尽管它与模型完全不同。这说明了这些对抗性攻击造成的威胁—我们可能没有察觉到差异,因此我们无法判断对抗性攻击是否发生。因此,尽管模型的输出可能会改变,但我们无法判断输出是正确还是不正确。
这形成了刘玲教授在 2019 年 IEEE 大数据大会上的主题演讲背后的动机,她在演讲中谈到了对抗性攻击的类型,对抗性例子是如何产生的,以及如何对抗这些攻击。事不宜迟,我将进入她的演讲的内容。
敌对攻击的类型
对抗性攻击分为两类——有针对性的攻击和无针对性的攻击。
目标攻击有一个目标类别 Y,它希望目标模型 M 将类别 X 的图像 I 分类为。因此,目标攻击的目标是通过预测敌对示例 I,使 M 误分类为预期的目标类别 Y 而不是真实的类别 x。另一方面,无目标攻击不具有它想要模型将图像分类为的目标类别。相反,目标仅仅是通过预测对立的例子 I 作为一个类,而不是原始类 x,来使目标模型错误分类。
研究人员发现,一般来说,虽然无针对性的攻击不如有针对性的攻击,但耗时要少得多。尽管有针对性的攻击在改变模型预测方面更成功,但这是有代价的(时间)。
对立的例子是如何产生的?
了解了有目标攻击和无目标攻击之间的区别后,我们现在来看看这些敌对攻击是如何进行的。在良性的机器学习系统中,训练过程寻求最小化目标标签和预测标签之间的损失,数学公式如下:

Image credits to Professor Lise Getoor taken from https://users.soe.ucsc.edu/~getoor/Talks/IEEE-Big-Data-Keynote-2019.pdf
在测试阶段,对学习的模型进行测试,以确定它能够多好地预测预测的标签。然后,通过目标标签和预测标签之间的损失之和来计算误差,数学公式如下:

Image credits to Professor Lise Getoor taken from https://users.soe.ucsc.edu/~getoor/Talks/IEEE-Big-Data-Keynote-2019.pdf
在对抗性攻击中,采取以下两个步骤:
- 查询输入从良性输入 x 变为 x’。
- 设定攻击目标,使得预测结果 H(x)不再是 y。损失从 l (H(x ᵢ),y ᵢ)变为 l (H(x ᵢ),y' ᵢ)其中 y' ᵢ ≠ y ᵢ.
对抗性干扰
将查询输入从 x 改变到 x’的一种方式是通过称为“对抗扰动”的方法,其中计算扰动,使得预测将与原始标签不同。对于图像,这可能以像素噪声的形式出现,正如我们在上面的熊猫例子中看到的那样。无目标攻击的单一目标是最大化 H(x)和 H(x’)之间的损失,直到预测结果不是 y(真实标签)。定向攻击还有一个额外的目标,即不仅最大化 H(x)和 H(x’)之间的损耗,而且最小化 H(x’)和 y’之间的损耗,直到 H(x’)= y’而不是 y。
对抗性扰动可以分为一步扰动和多步扰动。顾名思义,一步扰动只涉及一个阶段——添加一次噪声,仅此而已。另一方面,多步扰动是一种迭代攻击,每次都对输入进行小的修改。因此,单步攻击很快,但可能会添加过多的噪声,从而使人类更容易检测到这些变化。此外,它更重视 H(x)和 H(x’)之间损耗最大化的目标,而不太重视扰动量最小化。相反,多步攻击更具战略性,因为它每次都会引入少量扰动。然而,这也意味着这种攻击在计算上更加昂贵。
黑盒攻击与白盒攻击
现在我们已经了解了对抗性攻击是如何产生的,一些敏锐的读者可能会意识到这些攻击的一个基本假设,即攻击目标预测模型 H 是对手已知的。只有当目标模型已知时,才可以通过改变输入来折衷产生对立的例子。然而,攻击者并不总是知道或者能够访问目标模型。这听起来像是抵御这些敌对攻击者的万全之策,但事实是黑盒攻击也非常有效。
黑盒攻击基于对立示例的可转移性概念,即对立示例虽然是为了攻击代理模型 G 而生成的,但在攻击另一个模型 h 时可以取得令人印象深刻的结果。采取的步骤如下:
- 攻击目标预测模型 H 是私人训练的,对手不知道。
- 一个模仿 H 的代理模型 G 被用来产生对立的例子。
- 利用对抗性例子的可转移性,可以发起黑盒攻击来攻击 h。
这种攻击可以在训练数据集已知或未知的情况下发起。在对手已知数据集的情况下,可以在与模型 H 相同的数据集上训练模型 G 来模仿 H。
然而,当训练数据集未知时,对手可以利用成员推理攻击,从而训练一个攻击模型,其目的是将目标模型在训练输入上的行为与其在训练期间没有遇到的输入上的行为区分开。本质上,这变成了一个分类问题,以识别目标模型对其训练的输入和未训练的输入的预测之间的差异。这使得对手能够更好地了解训练模型 H 的训练数据集 D,使得攻击者能够基于真实的训练数据集生成影子数据集 S,以便训练替代模型 G。在 S 上训练 G,其中 G 模仿 H,S 模仿 D,然后可以对 H 发起黑盒攻击
黑盒攻击的例子
现在我们已经看到了黑盒攻击与白盒攻击的不同之处,因为目标模型 H 对于对手来说是未知的,我们将讨论黑盒攻击中使用的各种策略。
身体攻击
将查询输入从 x 改变为 x’的一种简单方法是简单地添加一些物理上的东西(例如亮色)来扰乱模型。一个例子是 CMU 的研究人员如何在对面部识别模型的攻击中给一个人戴上眼镜。下图说明了这次攻击:

Image taken from https://www.cs.cmu.edu/~sbhagava/papers/face-rec-ccs16.pdf
第一行图像对应于通过添加眼镜而修改的原始图像,第二行图像对应于作为预期的错误分类目标的模仿目标。仅仅通过在原始图像上添加眼镜,面部识别模型就被欺骗,将顶行的图像分类为底行的图像。
另一个例子来自谷歌的研究人员,他们在输入图像中添加贴纸来改变图像的分类,如下图所示:

Image taken from https://arxiv.org/pdf/1712.09665.pdf
这些例子显示了这种物理攻击是多么有效。
分发外(OOD)攻击
实施黑盒攻击的另一种方式是通过分发外(OOD)攻击。机器学习中的传统假设是,所有的训练和测试样本都是从相同的分布中独立抽取的。在 OOD 攻击中,通过向模型提供来自训练数据集的不同分布的图像来利用这种假设,例如,将 TinyImageNet 数据馈送到 CIFAR-10 分类器,这将导致具有高置信度的不正确预测。
如何才能信任机器学习?
既然我们已经看了各种类型的对抗性攻击,那么一个自然的问题就来了——如果我们的机器学习模型如此容易受到对抗性攻击,我们怎么能信任它们呢?
Chow 等人在 2019 年题为“抗黑盒对抗性攻击的去噪和验证跨层集成”的论文中提出了一种可能的方法。该方法的核心是使机器学习系统能够自动检测敌对攻击,然后通过使用去噪和验证集成来自动修复它们。
去噪集成
首先,输入图像必须经过去噪集合,去噪集合尝试不同的方法来去除图像中的任何添加的噪声,例如添加高斯噪声。由于防御者不知道由对手添加到图像中的特定噪声,因此每次尝试去除每种类型的噪声时,都需要一组去噪器。
下图显示了去噪自动编码器的训练过程-原始图像被注入了攻击者可能注入的一些噪声,自动编码器尝试重建原始未损坏的图像。在训练过程中,目标是减少重建图像和原始图像之间的重建误差。

Image taken from https://arxiv.org/pdf/1908.07667.pdf
通过开发这些自动编码器的集合,每个自动编码器被训练以去除特定类型的噪声,希望被破坏的图像将被充分去噪,使得它接近原始未被破坏的图像,以允许图像分类。
验证集成
在图像被去噪之后,它们然后经过验证集合,该验证集合检查由每个去噪器产生的每个去噪图像,然后对去噪图像进行分类。验证集成中的每个分类器对每个去噪图像进行分类,然后集成进行投票以确定图像所属的最终类别。这意味着尽管一些图像可能没有在去噪步骤中以正确的方式去噪,但是验证集合对所有去噪的图像进行投票,从而增加了做出更准确预测的可能性。
多样性
发现去噪器和验证器的多样性是非常重要的,因为首先,敌对攻击者将更善于改变图像,因此需要能够处理各种破坏图像的去噪器的多样性组。接下来,还需要验证器多样化,以便它们可以生成多种分类,这样敌对攻击者就很难操纵它们,就像他们如何设法操纵我们信任并在机器学习中频繁使用的普通分类器一样。
这仍然是一个悬而未决的问题,因为在各种验证者做出所有这些决定之后,仍然有一个最终决策者需要决定听取谁的意见。最终的决策者需要保持群体中的多样性,这并不是一件容易的事情。
结论
我们已经研究了各种类型的对抗性攻击,以及防御这些攻击的有希望的方法。当我们实现机器学习模型时,这绝对是要记住的事情。我们不应该盲目地相信模型会产生正确的结果,而是需要防范这些对抗性的攻击,并在接受这些模型做出的决定之前总是三思而行。
非常感谢刘教授就机器学习中的这个紧迫问题发表了富有启发性的主旨演讲!
对入侵检测系统的敌对攻击
人工智能(AI)在很短的时间内取得了长足的进步。计算机科学家先驱艾伦·图灵(Alan Turing)在 1950 年发表了第一篇关于机器可以思考的可能性的论文。在不到一个世纪的时间里,人类创造了能够计算和理解大量数据的机器和程序,以学习和模仿人类自身的行为。
人们、企业和政府都严重依赖这项新技术,却没有意识到这一点。人工智能的一个增长领域是安全。入侵检测系统(IDS)是用于保护网络或系统免受恶意流量攻击的系统。人工智能本质上是动态的,具有学习的能力,所以它对于这个应用程序来说是理想的,这样它就可以学习和进化。这使得 AI 擅长检测好的和恶意的互联网流量,因为它不遵循一套定义的规则,而是动态地创建自己的规则。
入侵检测系统(IDS)在保护保存在网络或系统中的信息方面发挥着重要作用,并且由于其低维护性和及时了解最新攻击的能力,AI 正在被集成到 IDS 中。由于人工智能的快速发展,提高这些系统健壮性的需要被忽略了,当前的研究着眼于改进 IDS 的方法。
一种叫做生成对抗网络(GAN)的新兴技术试图攻击任何一种使用人工智能的机器学习系统。GAN 对机器学习系统产生的攻击会混淆或愚弄算法,从而产生与预期不同的输出。
下图很好地展示了 GAN 如何迷惑机器学习系统。它接受一个输入并修改它,使它看起来仍然像原来的一样。任何人看到这两张图片都会确信它们都是猫。它们都有尖尖的耳朵、胡须、脸型、皮毛等。但对于在更深、更低层次上分析图像的机器学习系统来说,这两者是非常不同的。左边的一个有更多的细节,这将使机器学习系统感到困惑,因为它看不到太多的模糊和颜色差异。与此同时,右边的图像要简单得多,这要么会让机器学习系统相信左边的图像太详细,不可能是猫,要么右边的图像没有足够的细节,不可能是猫,尽管对一个人来说它们是一回事。最终结果将是一个错误分类的图像,证明 GAN 在混淆机器学习算法方面是成功的。

Cat picture CC-BY-SA from Zimin.V.G., Cat cartoon CC-BY XXspiritwolf2000XX.
对任何基于机器学习的入侵检测系统的攻击都包含三个主要特征,这些特征描述了它将是哪种攻击,因此属于八个不同攻击类别之一。需要注意的是,正的假设为恶意,负的假设为正常。下面是三个不同的类别,每个类别包含两个不同的特征:
影响:
- 致使攻击通过控制训练数据(改变训练过程)来影响学习
- 试探性攻击导致拒绝服务(DoS)(利用现有的弱点),通常带有误报(拒绝好的输入)
安全违规:
- 完整性攻击通过漏报损害资产(接受恶意输入)
- 可用性攻击导致拒绝服务,通常是通过误报(拒绝好的输入)
特异性:
- 有针对性的攻击专注于特定的实例(让特定的输入通过)
- 不分青红皂白的攻击包含了一大类实例(让很多东西通过)
一次攻击可以从每个类别中提取一个特征,但绝不会从同一个类别中提取两个特征,因为这两个特征会相互矛盾。根据您攻击的 IDS 的类型,GAN 将创建的攻击类型会有所不同。例如,基于序列(基于规则)的入侵检测系统可能会受到探索性完整性攻击,在这种情况下,特异性并不重要。探索性完整性攻击侧重于使用假阴性来淹没系统,从而允许恶意流量进入系统。欺骗基于序列的 IDS 需要发送大量的输入,每个输入都有稍微不同的意图,试图通过 IDS 设置的所有规则。目标可能是发送一个或多个恶意输入,这取决于坏的参与者。
这些攻击分为 4 种攻击类型:拒绝服务(DoS)、探测、用户到根(U2R)和根到本地(R2L)。这些攻击类型侧重于不同的结果,每种攻击的意图如下:
- DoS 是一种试图切断进出目标系统的流量的攻击。IDS 被异常流量淹没,系统无法处理,于是关闭以保护自己。这将阻止正常流量访问网络。这方面的一个例子可能是一家在线零售商在大减价的一天收到大量在线订单,由于网络无法处理所有请求,它将关闭,阻止付费客户购买任何东西。
- 探测或监视是一种试图从网络获取信息的攻击。这里的目标是像小偷一样窃取重要信息,无论是客户的个人信息还是银行信息。
- U2R 是一种攻击,它从普通用户帐户开始,试图以超级用户(root)的身份访问系统或网络。攻击者试图利用系统中的漏洞来获得根用户权限/访问权。
- R2L 是一种试图获得远程机器本地访问权限的攻击。攻击者无法在本地访问系统/网络,并试图“侵入”网络。
IDS 受到多种类型的攻击,因为每种攻击类型都有许多子类。基于机器学习的入侵检测系统的想法正在发展,在这种情况下,入侵检测系统可以自己学习对不同的攻击进行分类。这就是为什么创建 GAN 来对抗 IDS 的潜力如此之大:GAN 是用来欺骗机器学习系统的。这将证明是一个伟大的资产在测试一个入侵检测系统的鲁棒性,并可能导致安全系统到一个新的时代,采取入侵检测系统到一个新的水平。
总的来说,对于当今的攻击水平,IDS 是一个非常有用的基本工具,但是使用 GAN 来生成攻击以对抗 IDS 的可能性正在快速增长。称为入侵检测系统生成对抗网络(IDSGAN)的框架已经被创建,并且已经证明简单的 IDS 对于由 GAN 生成的攻击是脆弱的。安全的未来将是 IDSs 和 GANs 之间的战斗,谁发展得更快,谁就会站在最前面。
对立的例子——重新思考定义

MNIST Digits
对立的例子是各种机器学习系统要克服的一大障碍。它们的存在表明,模型倾向于依赖不可靠的特征来最大化性能,如果受到干扰,可能会导致错误分类,带来潜在的灾难性后果。对抗示例的非正式定义是以人类察觉不到的方式修改的输入,但是被机器学习系统错误分类,而原始输入被正确分类。下图说明了这个概念

Original image (left), adversarial noise (middle), perturbed image incorrectly classified as a 2 (right)
对抗性例子的正式定义如下

Adversarial example definition
其中𝓛是我们试图最大化的损失函数, 𝑥_orig 是原始图像,𝛿是扰动,y 是地面真实标签,并且选择ε以确保扰动的图像看起来不会太嘈杂,并且使得它对于人类来说仍然看起来像原始类别的图像。诸如 FGS、IGS 和 PGD 的几种攻击使用 L-∞范数来约束扰动图像和原始图像之间的距离。在本帖中,我们将探讨为 MNIST 数据集选择ε的困难。我们也将着眼于不依赖于干扰某些原始图像的生成对立范例的最新技术,并质疑这样生成的图像是否实际上满足对立范例的定义。
MNIST 距离分析
先简单分析一下同类图像之间,以及不同类图像之间的平均距离。也许这些距离有助于以更定量、更少主观的方式选择ε。这里是我的原创博文的链接,里面有一个包含分析的 Jupyter 笔记本。
我们从每个类别中随机抽取 100 幅图像,并计算不同标准下图像之间的平均成对距离。这里只显示了 L-2 范数,以避免混乱,还因为 L-∞范数热图在每个单元格中只有 1,不提供信息。

L-2 Norm Training Set Distances
一个合理的假设是,该热图的对角线元素(类内距离)应该低于同一行/列中的非对角线元素(类间距离)。然而,情况并非如此,就像上面看到的更接近于 1 的 2 和也更接近于 1 的 8。起初这是一个惊喜,但它只是表明给定数字的风格变化可能比数字之间的切换导致更多的像素差异。人们可以认为这是一个假象,即对于每个数字,对于该数字的不同图像,有一组不变的像素不变,并且当两个数字的不变组具有高度重叠时,可能会出现如上所述的意外结果。
选择ε
这一切在选择ε的时候意味着什么?使用 L-∞范数时,最常见的ε值为 0.3,L-2 范数的高值为 4.5 ( Madry 等人)。如果我们考虑 L-∞范数的ε=1.0 的最大极值,我们将无法控制扰动图像的地面真实类,并且可能最终生成对于人类和我们的图像分类模型看起来像不同类的图像。这也将允许我们在训练和测试集图像之间任意插值 x’= rx _ train *(1-r)x_test,并且如果我们的模型碰巧不正确地分类 x _ test,那么它将被标记为敌对的。所以这里有多个条件需要执行。
- 当并排比较原始图像 x 和它的扰动版本 x '时,我们希望人类察觉不到容许扰动的集合
- 我们希望扰动不可能导致相同数字的图像之间的插值。否则,这可能会混淆对抗鲁棒性与泛化性能。对于给定的数字 d,以及分别被我们的模型正确和错误分类的测试集图像 x_correct 和 x_false,一个简单的对抗性攻击是将 x_correct 转换成 x_false
根据观察者的不同,(1)通常意味着(2)。ε=0.3 当然满足(2),因为所有图像都具有接近 1.0 的 L-inf 距离。让我们看看,如果我们生成由两个类组合而成的图像,会发生什么,如下所示

Averaging images under constrained L-∞ distance
这将原始图像和精心制作的图像之间的 L-∞距离限制为ε,但是任何人类观察者都可以很容易地分辨出如下两幅图像之间的差异

Crafted image within ε=0.3 L-inf distance of original
很明显,最右边的图像有问题。事实上,如果没有被告知这是一个由 0 和 1 组合而成的图像,有些人可能会说这只是一个抽象的符号。举个简单的例子,我们已经证明ε=0.3 违反了条件(1)。甚至更小的值,如ε=0.2,也会给出类似的结果。MNIST 允许容易地识别受干扰的像素。在许多情况下,通过简单地检查是否对背景像素进行了修改来创建对抗示例的检测机制是微不足道的。如果攻击者知道这种检测机制,他们可以绕过它(卡里尼和瓦格纳)。那么我们如何选择ε呢?
有理由不为每个图像使用相同的ε。对于某些类,判断数字本身的边界框内的像素是否发生了变化要容易得多,如上例所示。对于此类类,ε可能应该设置为较小的值。此外,像 L-2 或 L-∞这样的典型规范在用于计算图像空间中的距离时没有语义相似性的概念。如果他们能够给出输入空间中图像之间的语义相似性,那么就有可能构建一个简单的 KNN 图像分类器,并抛弃过去 7 年卷积神经网络的进展。这个问题的一个可能的解决方案是使用度量学习中的技术。通过学习嵌入,其中这种嵌入之间的 L-2 或 L-∞距离包含语义相似性的概念,然后我们可以在这个空间而不是输入空间中调整ε。一种这样的技术叫做三联体网络。三元组网络通过一次将 3 个图像并行传递到同一个嵌入网络来工作。传递 y 类的锚,以及同一类的正例(+)和不同 y '类的反例(-)。损失函数确保锚和正样本之间的距离至少比锚和负样本之间的距离小𝛼。

Illustration of a what a triplet network does
使用类似三元组网络的度量学习技术仍然需要人工实验者验证,以确保ε没有被选择得足够大,以允许类中的变化。此外,我们将不得不考虑条件(2 ),它说我们不应该能够使用扰动从我们的数据集中的一个图像跳到同一类的另一个图像。像 PGD 这样的攻击在损失函数的梯度方向上迭代移动以增加损失,然后将结果图像投影到满足与原始图像的距离约束的输入子空间上。不是在输入空间中进行这种投影,而是使用我们选择的度量学习算法在嵌入空间中进行。
生成对立范例
一篇非常酷的论文(宋等人)介绍了一种创造对抗性例子的新方法。作者选择使用 GAN 从零开始生成可能欺骗被攻击模型的图像,而不是使用恶意制作的噪声干扰一些已经存在的图像。具体来说,他们使用一个辅助分类器 GAN (AC-GAN ),该分类器能够根据图像类别来控制正在生成的图像类型。这导致了“不受限制的对抗性例子”,因为没有距离来约束,因为图像是从零开始生成的。然而,这不满足前面提到的标准(1)或(2)。虽然他们的技术非常有用,并允许通过生成模型失败的新图像来进行模型调试和数据扩充,但该分析将泛化性能和对抗性鲁棒性视为同一件事。为了正确分析模型的稳健性,我们需要能够理清泛化性能和对抗性稳健性这两个指标,因为它们彼此不一致(齐普拉斯等人)。因此,虽然远离基于扰动的对立例子的定义可能是诱人的,但目前它们是允许以孤立的、非混淆的方式研究对立鲁棒性的唯一方法。
结论
目前对对立例子的定义对于像 MNIST 这样的数据集来说略有缺陷,尽管它对于像 ImageNet 这样的东西来说更有意义,因为在 ImageNet 中扰动更难注意到,并且不会最终使图像看起来像奇怪的类组合。对每个图像或类别使用相同的阈值ε可能是一个苛刻的要求,因为对于特定类别的图像更容易检测噪声。图像是一种自然易于人类分析和判断是否有猫腻的数据。然而,在许多领域中,数据是以非常难以理解和可视化的抽象数字向量的形式出现的。由于我们无法从一开始就理解原始数据,因此在这些领域中定义什么是对抗性的可能超出了我们的想象范围。在这种情况下,得出ε的定量方法是必须的。
我希望你喜欢这篇文章,并让我知道你希望在未来的文章中看到的其他主题。
给新手和初级数据科学家的建议
我希望两年前就知道的事情

Hopefully, this will bring a little clarity to your path. 😃
我以为我是谁
我叫 Darrin,我在 Outcome Health 担任数据科学家已经将近两年了。我们是一家专注于护理点患者教育的健康科技公司。用英语来说,这意味着我们在医生的办公室里放一些设备,里面有给病人看的内容。我们在现场有超过 100,000 台设备,这意味着大量的数据。
这篇文章是写给谁的
本文面向众多初级/助理数据科学家。如果你刚刚开始你的旅程,如果你有点困惑和失落,如果你不总是确定你应该做什么或如何最好地为你的新公司做贡献,你来对地方了。

You. Me. Your C-suite, probably.
我为什么写这篇文章
我看过许多数据科学文章,解释了做更高级的数据科学工作的来龙去脉,伟大的数据科学家需要的技能,这些大师处理的项目类型。但是当我经历我的助理数据科学家之旅时,我花了很长时间来导航如何做成为一个更初级的团队成员。
本文试图为其他初露头角的准数据科学家缓解这个问题。
我的主要目标是提供一个基本的蓝图,并举例说明助理数据科学家如何快速为组织增加重要价值。
我很幸运地在这个过程中发现了一些东西,现在我已经是一名数据科学家了——我希望这能帮助你们中的一些人走上同样的道路!
第一步:寻找低风险、高回报的项目
主要问题
每个助理数据科学家遇到的第一个问题可能都是一样的:如何…
- 在真实项目上增加价值…
- 当发展有用的技能 …
- 没有打破任何重要的东西?
回答这个问题让我结结巴巴,与组织中各种各样的人交谈,并且通常会问很多愚蠢的问题。
关键洞察力
我发现自动化监控过程往往是我能花时间做的风险最低、回报最高的工作。
- 不用担心破坏生产系统→低风险
- 对公司有明显的增值→节省时间(高回报)
- 我可以用 Python/用 Airflow/[在此插入新的酷技术]构建自动化流程→培养重要的技能
检查,检查,检查。
通用的、可操作的外卖
总的来说,如果你能找到可以自动完成的任务,但由于缺乏带宽或优先级,这些都是测试你能力的好项目。几乎每个公司都有,它们是低风险/高回报的,如果你能很快得到一个 MVP,势头会很快形成。有很多文章都在解释为什么快速获得 MVP 是一件好事,所以我会让他们解释其中的逻辑。
我的经历
在我的工作场所,我发现我们在监控新软件发布的 KPI 时效率明显低下。手动监控流程往往是改进时机成熟的地方。它们的存在通常是由于缺乏适当的生产流程。
最终,我们将分阶段推进软件更新,每个阶段都将在我们的 100,000 台设备网络中占据更大的比例。然而,在每个阶段,分析师将手动提取该软件版本的 KPI。这显然是浪费时间,但是我们没有时间来自动化这个过程。
第二步:如何产生深刻的见解
主要问题
所以,你有了一个项目自动化一些过程的想法。现在怎么办?作为数据科学家,我们知道我们工作的一部分是“产生洞察力”。
很长一段时间,我对此的主要反应是“这到底是什么意思?!"我默认有一个工程师的大脑。我需要一个切实、具体的解释。没有那个,我不得不自己做。

So, I was sitting there project in one hand, laptop in the other, and I realized I didn’t have my next step in-sight. (Get it. Insight. Heh. Your groans are my validation.)
关键洞察力
对我来说,一个伟大的“洞察力”是减少做决定所需时间的任何东西。
具体来说,这就是人们通常所说的洞察力。他们想要一份明确他们应该做什么的交付信息,越快越好。如果洞察力使你改变了先前的决定,它仍然减少了做决定所需的时间,因为它只是缩短了你的“坏”决定和新决定之间的时间。
通用的、可操作的外卖
这意味着任何助理数据科学家的一个好目标就是简单地减少数据接收和行动之间的时间量。显然,这是一个广泛的任务,但这意味着你要学习端到端的系统,每个数据科学家都应该至少了解数据堆栈的每个部分(在这个人工智能需求层次图中有更多的信息)。此外,数据科学家的角色目前是如此广泛和模糊,你的职责范围可能会涵盖整个堆栈。
我的经历
就我而言,除了简单地自动化数据拉取以节省时间之外,我还意识到了两件事。

Fun for teams. Not for Batman.
- 为了节省时间,我可以将数据推送到用户所在的地方,而不是拖到用户所在的地方:Slack。这涉及到连接到 Slack API 并推送用 Python 创建的图表。
- 我可以自动完成人类分析师正在做的一些推理。(机器会来抢我们的工作。)
我们在我们的网络上开展广告活动,我们的主要 KPI 之一是我们的广告活动在一天内的总播放次数。这个数字应该不会有太大的变化,除非是在周末,这个数字应该会下降到接近于零。
检查数字的分析师会检查这个 KPI,这通常是正常的。但是,时不时地,一个大型的活动会结束,导致播放数量急剧下降。对于给定的软件版本,这可能看起来是一个大问题。
我意识到播放次数(显然)与现场设备的数量和正在播放的活动数量相关。我建立了一个简单的分段线性模型(简单的系统更好,你喜欢神经网络的人)来解释活动的数量、设备的数量和周末。通过对软件更新前的数据训练模型,我可以预测软件更新后的 KPI,并根据软件更新前数据的差异设置防护栏。
这允许分析师查看通过 Slack 交付给他的一个图表,并知道 KPI 是否“在预期之内”!

第三步:如何让人们根据你的见解采取行动
主要问题
在构建了几个这样的系统之后,我开始遇到一个大多数数据科学家都会遇到的问题。人们没有采取行动。行动就是一切。如果没有结果,一个好的洞察力有什么用?(或者,在这种情况下,这是一个很好的见解吗?哦哦。)
如果一个模型被建立,一个仪表板被建造,或者一个警报系统被开发,但从来没有引起行动,它真的存在吗?(是的,确实如此,但你明白了。)
关键洞察力
改变我对此想法的主要见解实际上源于一篇关于为什么懒惰不存在的文章。主要要点是:
采取行动需要一个为什么和一个什么。如果有人不采取行动,他们没有足够强的理由去做某事,或者他们不知道到底该做什么。
这正是我所看到的。人们要么对警报的含义感到困惑,要么不确定如何应对警报。在这两种情况下,警报导致焦虑和无行动,这比根本没有警报更糟糕。
通用的、可操作的外卖
在你的工作中,这意味着你需要确保在交流见解时,你阐明了见解为什么重要,以及该怎么做。事实上,任何导致行动的交流都是如此。管理不善的会议是不应该做什么的一个很好的例子。如果你曾经参加过一个没有明确原因和内容的会议,你会知道这个会议是曲折的,什么也没有完成,每个人的时间都被浪费了。
如果会议没有明确的议程,我是不会去参加的。没有议程的会议是我最讨厌的事情之一。还有,首字母缩写糟透了。这只是一件无关的个人事情,但是埃隆·马斯克同意。

我的经历
随着我试图自动化的监控的性质变得越来越复杂,我的具体问题开始出现。我开始提供带有小型数据转储的一般语句,而不是具体的操作(可能有几十个)。我本可以处理数据转储。
数据转储不是消费者想要使用的东西。顾客才是最重要的。
随着警报变得过于普遍,我为这些新频道设置的空闲频道开始被较少使用。我唯一的选择是创建更具体的信息和行动步骤。
我发现了一个非常有效的方法,那就是仔细考虑问题的确切解决步骤——对于复杂的问题,这可能是一个困难的预先考虑。然而,如果处理得当,它会让行动步骤和需要的信息变得非常清楚。随着清晰的到来,我的通道和所采取的行动得到了重用!
最终结果
“异常检测”项目是由我自己发起的,经过 6 个月的稳定工作,我的优秀经理给予我的自由和信任使之成为可能。目前,“异常检测”向我们一半以上的工程-产品-设计组织(40 个人中的大约 20 个)和该组织之外的几个其他利益相关者推送警报。它已成为运营去风险工作的一个重要来源,新的渠道正在不断增加。
对于一个以副业开始的项目来说,这是一个不错的结果!
最后的笔记&送别
我不是什么神奇的天才。我来自内布拉斯加州。(爱你,内布拉斯加同胞。)再加上我小时候被摔过。(不过谁不是呢。爱你们,爸爸妈妈!).

Nebraska. Land of corn, football, and…more corn.
我作为数据科学家的第一年所做的事情是任何初级/助理数据科学家都可以做的,我希望你们中的一些人能够从我所拥有的好运和我所做的努力中获得灵感。所以,当你开始你的旅程时,我留给你一句我的数学老师在每次考试前给我们的谚语(这也是一段艰苦但有趣的旅程——我是个数学书呆子):
祝你好运,玩得开心,好好表现!
人工“情绪”智能
这一切都始于大约 2000 年前,当时柏拉图写道:“所有的学习都有一个情感基础。”
有人可能会认为超过 20 万年的进化会让人类成为情感的主人。然而,在我们生活的世界里,无论年龄大小或成熟程度如何,人们都经常在情感判断上犯错误。清晰地识别情绪是顺利沟通和建立持久关系等社会行为的关键。
是什么让识别情绪对人类来说具有挑战性?
我们经常努力表达我们的情感,表达我们的感受。情绪有许多不同的程度、性质和强度。此外,我们的经历经常同时包含多种情绪,这给我们的情绪经历增加了另一个复杂的维度。
然而,锦上添花的是情感偏见。随着情绪范围的变化,必然会有偏见。这就是我们作为数据科学家对这个问题感兴趣的地方——我们喜欢好的“偏差-方差”问题!
进入,你的友好,不带偏见的邻居情绪检测机器人。人类和机器唯一的区别是情商的日子已经一去不复返了。情感识别或人工“情感”智能现在是一个价值 200 亿美元的研究领域,在许多不同的行业都有应用。
在各行各业,人工情绪智能可以通过多种方式发挥作用。例如,人工智能可以监控用户的情绪,并对其进行分析,以达到某种结果。该应用程序将证明在增强自动化客户服务呼叫方面极其有用。人工智能还可以使用情绪读数作为决策的一部分,例如在营销活动中。广告可以根据消费者的反应而改变。
R AVDESS 数据集
瑞尔森情感语音和歌曲视听数据库( RAVDESS )包含 7356 个文件(总大小:24.8 GB)。该数据库包含 24 名职业演员(12 名女性,12 名男性),用中性北美口音发出两个词汇匹配的语句。言语包括平静、快乐、悲伤、愤怒、恐惧、惊讶和厌恶的表情。每种表情都产生于两种情绪强度水平(正常、强烈),外加一种中性表情。所有条件都有三种形式:纯音频(16 位,48 千赫。wav)、音频-视频(720p H.264、AAC 48kHz、. mp4)和纯视频(没有声音)。
7356 个 RAVDESS 文件中的每一个都有一个唯一的文件名。文件名由 7 部分数字标识符组成(例如,02–01–06–01–02–01–12 . MP4)。这些标识符定义了刺激特征:
文件名标识符:
- 设备(01 =全 AV,02 =仅视频,03 =仅音频)
- 声道(01 =语音,02 =歌曲)。
- 情绪(01 =中性,02 =平静,03 =高兴,04 =悲伤,05 =愤怒,06 =恐惧,07 =厌恶,08 =惊讶)。
- 情绪强度(01 =正常,02 =强烈)。注意:没有强烈的“中性”情绪。
- 陈述(01 =“孩子在门边说话”,02 =“狗在门边坐着”)。
- 重复(01 =第一次重复,02 =第二次重复)。
- 演员(01 到 24。奇数号演员为男性,偶数号演员为女性)。
方法
鉴于我们的数据集在数据类型方面的多样性——语音、歌曲和视频——我们决定将音频和音频-视频文件分开,并对它们分别建模以识别情绪。
在接下来的章节中,您会发现我们两个不同模型的具体细节以及总体概念重点。
视频情感检测
你有没有想过有人在生你的气,结果发现你只是误读了他们的面部表情?我们的脸可以表达 7 种基本情绪。现在,想象一下,表达“无声的快乐”需要什么样的组合。我们无法对我们七种基本情绪的不同排列和组合所能表达的不同种类的情绪进行计数。

Source — https://egyptinnovate.com/en/success-stories/affectiva-company-humanizing-technology
从面部表情中读出情绪的能力是一项非常重要的技能。有人甚至可以称之为超级大国。自远古以来,正是这种技能促成并促进了人类的互动。
潜意识里我们每天一整天都在看、贴标签、做预测、识别模式。但是我们怎么做呢?我们如何解释我们看到的一切?
大自然花了 5 亿多年才创造出这样一个系统。眼睛和大脑之间的合作被称为初级视觉通路,是我们能够理解周围世界的原因。
大脑中神经元和连接的非常复杂的层次结构在记忆和标记物体的过程中起着重要作用。一开始,我们被教导我们周围物体的名称。我们通过给我们的例子来学习。慢慢地,但肯定地,我们开始越来越经常地认识我们周围的事物。它们变得如此普遍,以至于下次我们看到它们时,我们会立刻知道这个物体的名字。他们成了我们的'【T2 模式】' T3 '世界的一部分。
但是现代机器是如何从面部表情识别情绪的呢?
卷积神经网络
类似于儿童如何学习识别物体,我们需要对数百万张图片训练一种算法,然后它才能感知输入并对看不见的图像做出预测。
电脑和我们“看”的方式不同。他们的世界只由数字组成。每幅图像都可以用二维数组来表示,称为像素。
卷积神经网络(CNN) 是一种特定类型的人工神经网络,它教会一种算法如何识别图像中的对象/特征。
以下是我们如何在我们的项目中利用 CNN 的力量。
定义 CNN 模型
Keras 被用来创建一个顺序卷积网络——具有线性层堆栈的神经网络。该网络由以下部分组成:
卷积层: 这些层是我们网络的构建模块。这些计算输入图像 X 和一组 Kj 可学习滤波器之间的点积。大小为 k1 × k2 的每个滤波器 Kj 在输入空间中移动,与输入的局部子块执行卷积,提供 Yj,即特征映射(Yj=∑X×Kj+Bj,其中 B 是偏置项)。
激活函数: 我们使用激活函数使我们的输出非线性。在卷积神经网络的情况下,卷积的输出将通过激活函数。在这个项目中,我们将求助于两个函数的使用— Relu 和 Sigmoid。
池层: 这些层将沿维度向下采样操作。这有助于减少空间数据并最小化所需的处理能力。
密集层: 这些层出现在一个 C.N.N 的末端,它们接收卷积层生成的所有特征数据并做出决策。
退层: 随机关闭网络中的几个神经元,防止过拟合。
批量标准化:通过减去批量平均值并除以批量标准偏差来标准化先前激活层的输出。这加快了训练过程。
该网络接受一个大小为 256*256 的二维数组的输入,并预测数据集中存在的八种情绪中的一种。
以下是 CNN 模式的总结:
解析视频获得图像
第一步是将视频文件解析成一组我们用来训练模型的图像帧。我们使用 cv2 库从视频中捕捉图像。VideoCapture 函数读取视频文件,并将其转换为一系列图像帧。
获得的每一帧将包含一个包含图像信息的二维整数数组。图像由像素组成,这些像素是多个数字阵列的通道。彩色图像有三个颜色通道,即红色、绿色和蓝色,每个通道由一个网格表示。网格中的每个单元格存储一个 0 到 255 之间的数字,表示该单元格的亮度。为了每次捕捉不同的表情,我们将每 20 帧传递到我们的训练模型中。


What you see (L) vs what computer sees (R)
提取图像数据后,我们将图像的大小调整为 256*256,以尽可能多地保留信息,从而提高模型的准确性。我们将这些图像转换为灰度,因此只有一个通道,从而降低了复杂性。

然后,我们添加图像数据以获得一个生成器对象,我们将在下面的段落中进一步解释这个对象。
获取标识情绪的标签
我们在字典中定义情绪,如下面的代码所示。

Emotion Dictionary
示例视频文件:“01–01–03–02–02–02–01 . MP4”
所有视频文件的文件名中都列出了情感,如上所示。我们拆分文件名,并使用预定义的情感词典来获取每个视频文件的标签。
训练 CNN 模特
对于小而简单的数据集,使用 Keras 是完全可以接受的。拟合函数。然而,像我们这样的大型数据集通常太大而不适合内存。执行数据扩充是为了避免过度拟合并提高模型的泛化能力。在这些情况下,我们需要利用 Keras 的。拟合 _ 生成器函数。的。fit_generator 函数接受批量数据,执行反向传播,然后更新模型中的权重。重复这个过程,直到我们达到期望的历元数。你会注意到我们现在需要在调用时提供一个 steps_per_epoch 参数。fit_generator(的。fit 方法没有这样的参数)。
Keras 数据生成器意味着无限循环。因此,Keras 无法确定一个纪元何时开始,一个新的纪元何时开始。因此,我们将 steps_per_epoch 值计算为训练数据点的总数除以批量大小。一旦 Keras 达到这个步数,它就知道这是一个新时代。

在尝试不同的迭代和切换模型参数后,我们聚焦于 50 个时期和每个时期 25 步。对于这个模型,我们获得了 0.55 到 0.65 的精度。
测试 CNN 模型
为了测试 CNN 模型,我们使用 Keras 函数 test_on_batch()。与我们训练模型的方式类似,我们在视频文件中每隔 20 帧捕捉一次,将图像数据转换为灰度,并将图像重新整形为 256*256 阵列。该模型返回对应于一种情绪的八个数字的数组。我们通过确定这个数组中的最高数字来获得预测的情绪。
我们在两个演员身上测试了该模型,并在这些结果上获得了 0.6 的准确度。
模型预测
在测试了这个模型之后,我们想在一个看不见的视频文件上测试这个模型。我们通过模型传递了一个带有“快乐”情感标签的视频。
作为模型的输出,我们得到的是一系列加权的情绪。我们运行下面给出的代码来为这个模型选择最好的可能结果。

这是一个模型预测视频文件中每 20 帧前两种情绪的例子。

每一帧的结果被组合以给出视频剪辑的最终预测结果。
转移学习方式
除了使用 CNN,我们还尝试了迁移学习,以确定我们是否可以通过在我们的数据集上训练预训练模型来获得更高的准确性。迁移学习是一种机器学习方法,其中为某个预测问题开发的模型被重新用作第二个任务的模型的起点。
这个模型是根据预测七种情绪的 FER 数据训练出来的。

我们删除了最后五层,增加了两个卷积层和一个激活层,如下文摘要所示。

我们在视频数据集上训练了这个模型,获得了 0.35 的准确率。我们计划致力于提高这一模型的准确性,并确定这是否能击败我们最初的 CNN 模型的准确性。
从音频信号中识别情绪
人类处理声音的方式非常复杂,有很多因素会影响到如何从音频片段中感知一种情绪。一个人的性别,语调的变化,甚至使用的词语类型都会影响我们对所说内容的感知。
我们数据集中的音频文件包括 3 秒钟的音频剪辑,包括语音和歌曲。就这个项目的范围而言,我们只限于演讲片段。音频基本上没有任何背景噪音,并且是在受控环境下录制的。
我们遇到了许多挑战,当谈到制作一个模型,可以理解我们可用的音频剪辑的情绪。对我们来说,第一个也是最大的一个挑战是弄清楚我们需要什么样的特性来制作我们的模型。这是一个非常特定领域的任务,我们需要了解声音及其潜在的属性,并找出哪些特征可以帮助正确识别情绪。
MFCC:
梅尔频率倒谱(MFC)是数据的短期功率谱,对于语音分析特别有用。人类发出的声音受到声道(包括声带、喉、舌、牙齿等)形状的影响。).在最基本的意义上,梅尔频率倒谱在数字上代表了这个声道。Mel-scale 旨在模仿人耳对声音的非线性感知,在较低频率下更具辨识度,在较高频率下辨识度较低。它对频率进行缩放,使其与人耳能够听到的内容紧密匹配(人类更善于识别低频语音中的微小变化)。
梅尔频率倒谱系数(MFCCs)是共同构成梅尔频率倒谱的一组系数。作为高级概述,计算 MFCC(摘自维基百科)涉及以下步骤:
- 对信号进行傅立叶变换。
- 使用三角形重叠窗口,将上面获得的光谱功率映射到 mel 标度上。
- 取每个 mel 频率的功率对数。
- 对 mel 对数幂列表进行离散余弦变换,就像它是一个信号一样。
- MFCCs 是最终频谱的幅度。
δMFCC 和δ-δMFCC——MFCC 的一阶和二阶导数——也是我们预测模型的重要特征。

数据预处理:
对于我们所有的音频处理,我们使用了一个名为 librosa 的 python 包,它对音乐和声音分析非常有帮助。
我们使用采样率为 22050 赫兹的 librosa 加载音频文件。每个文件被分成 157 帧。帧是用于分析目的的时间序列的一小段。Librosa 具有从音频文件生成 MFCCs 的功能。对于每一帧,我们只计算前 13 个 MFCCs,因为它们捕获了我们分析所需的大部分信息。即使更高阶的 MFCCs 确实包含我们的音频文件的更多频谱细节,它们也给模型增加了额外的复杂性,这通常是不期望的。
该函数返回音频中 157 帧中每一帧的 13 个 MFCCs。这些是对每一帧的汇总。使用每个 MFCCs 的帧的平均值、最大值、最小值和标准偏差。对δ和δδ系数进行相同的汇总。
我们从音频文件中提取的另一个特征是音频的均方根能量。
对于每个音频文件,从文件名中提取情感标签、情感强度、性别和演员号。
建模方法:
在建模之前,我们做的第一件事是将数据集分为训练集和测试集。
通常这是随机进行的。在我们的例子中,我们决定手动分割数据,取训练集中的前 20 个参与者和测试集中的后 4 个参与者。这是因为随机分割角色会导致数据泄漏问题。手动隔离某些参与者有助于避免这种情况。
我们的数据规模限制了我们从零开始训练神经网络。理想情况下,人工神经网络需要数百万个数据点来训练精确的算法。然而,我们必须处理几千个音频信号来训练我们的模型。
以下是我们建立的模型的总结:

Accuracy — 41.25%
随机森林:
我们认为,鉴于我们没有足够的数据来正确训练神经网络,我们可以尝试其他模型,看看它们的效果如何。我们用的第一个是古老的好随机森林。它给了我们 48%的准确率。
超参数调谐
训练随机森林的主要挑战是参数调整。由于参数数量庞大,我们首先对模型进行了随机搜索。其工作方式是,它基本上从给定的选项中选取随机参数,并在此基础上运行模型。我们重复运行了 50 次。这是缩小参数范围的一个非常有用的方法。
基于随机搜索的最佳模型的输出,我们找到了一个较小范围的参数进行试验,并使用 k = 3 的 k-fold 交叉验证对其进行网格搜索。
这给了我们最终的模型,测试精度为 48%,优于神经网络。
支持向量分类器:
对于 SVC,我们发现径向基函数在情感分类中表现最好。有趣的是,使用简单的线性分离函数几乎同样有效。不需要其他 SVC 参数(类别权重、概率估计值),分析是使用“一对其余”方法进行的。SVC 提供的准确率为 51.25%。
XGBoost
由于 XGBoost 有大量的参数可供选择,RandomizedSearchCV 再次有助于选择 50 个参数组合的子集进行交叉验证。这将培训从几个小时减少到两三个小时。让我们感到有趣/沮丧的是,一些选择的参数非常接近 XGBoost 的默认值。但试一试也无妨,结果超过了 CNN,接近 SVC 的水平。获得了 50%的准确度。
挑战和未来范围
组合音频&视频数据
这无疑是我们在这个项目中最大的挑战。到目前为止,我们已经将数据分成单独的音频和视频文件,以分别提取 MFCCs 和图像。然而,采用组合方法来同时训练能够处理音频和视频信号的模型将有助于实现更可扩展的结果。正如博客前面提到的,情感识别在很多行业都很受欢迎。我们相信,在未来的范围内,该产品可以通过兼容任何一种输入而被更广泛地接受。
医疗保健中的情感识别:
目前正在利用这项技术的一个行业是医疗保健,由人工智能驱动的识别软件帮助决定患者何时需要药物,或者帮助医生决定先看谁。我们预见到的一个可以通过准确的情绪检测来预防的问题是在精神健康意识领域。那些患有精神健康问题的人通常都是封闭的,不太愿意分享他们的问题。正确识别情绪这些痛苦的信号,对于避免精神崩溃和与压力相关的创伤会有很大的不同。计算机将会不带偏见,对检测早期迹象更加敏感,以帮助提醒亲密的朋友或家人。
处理固有偏见
我们的模型存在两大偏差:
1.所有演员都来自北美地理区域,因此说话带有明显的北美口音,导致我们的模型对此有偏见。来自其他地理位置的发言者的音频数据将有助于消除这种偏见。
2.所有的音频和视频记录都是在瑞尔森大学的专业环境中进行的,没有任何背景/白噪音。因此,在此数据集上定型的模型在真实数据上可能表现不佳。这种情况的一个潜在解决方案可能是在嘈杂的视听数据集上训练模型,并使用 Amazon Turk 服务附加类别标签。
参考资料:
[1] Muneeb ul Hassan, VGG16 —用于分类和检测的卷积网络
[2] Sourish Dey, CNN 在结构化数据上的应用——自动特征提取
[3] Francesco Pochetti ,视频分类实验:结合图像和音频特征
[4]瑞恩·汤普森,如何使用谷歌合作实验室进行视频处理
[5]詹姆斯·莱昂斯, Python 的演讲特点
[6]安吉莉卡·佩雷兹,表情:一个用于情感表达的机器学习工具包
原始数据之后:用数据嵌入探索控球风格。

识别一个球队风格的最基本的方法是看控球率、传球成功率、铲球率、每场比赛的平均失误次数等等。最近很多工作都是用预期目标模型来完成的,这些模型很好地捕捉到了创造和失球机会的质量。然而,它只是向分析型观众展示了一个度量标准,而不是一个团队如何运作的具体愿景。在开放式比赛中,仍然很难了解特定球队的传球顺序类型。
如何描述和分析传球序列的问题在足球分析界并不新鲜。像大卫·佩尔莫多·梅萨在 Statsbomb 上发表的“传球主题:识别球队和球员传球风格”或里卡多·塔瓦雷斯为足球比赛撰写的“可视化传球序列”这样的作品值得一读,是分析足球传球序列的一种艺术状态。
在这篇博文中,我们将探索一种基于深度学习的方法,以发现一些英超俱乐部的控球模式,并试图展示球队之间的差异。
我不能不提到 Right2Dream(该公司是丹麦俱乐部 FC nordsjlland 的一部分)招聘总监 Joe Mulberry 的工作,以及他在 2019 年伦敦 Opta 论坛上的精彩演讲。下面的分析受到了这一条的强烈启发。
编码占有:一个占有 2Vec 模型
首先,什么是占有?简单来说:这是一个连续的传球和移动过程,直到有球的球队把球丢掉。因此,当一次投篮不中、对方球队成功抢断或传球不成功时,比赛就结束了:这时另一队正在控球。
由于有球事件,我们可以通过纯粹为传球画白线来创建这些财产的简单表示。以下是一些示例:

这些图像宽 105 像素,高 68 像素,符合普通足球场的尺寸。攻击的方向是从左到右。
您会注意到,时间维度被考虑在内,动作的开始用较暗的线条表示,最后一遍是纯白色的。线之间的空间是玩家的跑动,我们不能在这里画出来,因为跟踪数据仍然很少。
为过去三个赛季的英超联赛构建这些图像,我们可以使用一个不错的数据集。每幅图像都可以用 105x68=7140 维的矢量展平。

为了能够比较这些向量,我们使用了深度学习领域中所谓的自动编码器。自动编码器是特定类型的神经网络架构,它允许将输入编码成压缩表示,然后通过解码功能恢复到几乎原始的数据。

通过设计,这些压缩的表示——也称为潜在向量——对于降低输入维度以及保持数据之间的相似性非常有用。在我的实验中,我选择将这些向量的维数设置为 256。在这里选择一个非常低的维度将需要更多的训练时间,并且可能会使保留原始数据信息变得更加困难。
此外,为了能够可视化这些信息,我们可以使用一种技术来进一步降低这些潜在向量的维度。我们有高维和非线性数据,因此 t-SNE 算法似乎最适合该操作。
由于自动编码器嵌入和 t-SNE 算法,这是二维表示的所有通道的视图。

令人欣慰的是,在将由 7140 个像素组成的图像减少到只有二维后,我们仍然能够保持所有物之间的信息相似性。你可能会注意到这张图表突出了控球时的传球次数,我们可以看到数据已经有点集中了。
为了能够比较团队的财产,我们用 K-means 算法对这些数据点进行分组。聚类的数量是任意选择的,而使用诸如肘方法的技术不是特别需要的:数量越多,我们就有越详细的聚类。我们将首先查看 25 个桶的结果,然后深入查看 500 个桶的结果。

Data clustered into 25 buckets.

Data clustered into 500 buckets.
请注意,我们也可以简单地将这些数据分组,但是 K-means 允许更精确一点。
大规模结果概览
通过简单地观察每个集群中的球队分布,我们可以发现球队的偏好是什么,或者与其他球队相比,他们使用最多的是哪种控球。
我们筛选球队,剔除那些数据较少的球队,那些在过去三个赛季降级或升级的球队:布莱顿,富勒姆,哈德斯菲尔德,桑德兰,狼队,米德尔斯堡,诺维奇,阿斯顿维拉,卡迪夫,纽卡斯尔。

上面的热图显示了每个集群中的团队分布(k=25)。在有趣的见解中,我们可以看到曼城与其他球队的不同之处。看一下 n 4 集群的一些控球样本,突出曼城的打法,长传控球在高位。

不出所料,排在第 4 组的其他球队是阿森纳、热刺、利物浦或切尔西。相反,集群 n 3 突出显示了像莱斯特或斯旺西这样打长球的球队

观察一些特定的星团,例如星团 n 14 也很有趣。
曼城、阿森纳和热刺在其中相当糟糕。查看一些样本,我们看到这一组代表右边的短传,从右后卫到中场。事实上,这三个团队在这方面经常遇到困难,这显示了这种建模的力量,它可以捕捉这些信息。

进入细节
如果我们查看聚集在 500 个桶中的数据,我们可以了解更多关于财产类型的细节。通过寻找集群分布的巨大差异,我们可以发现团队的特殊性
西汉姆几乎是唯一一个出现在 n 17 集群的球队,它代表了右翼的短传。随着大量比赛的进行,萨巴莱塔和安东尼奥在右路组成了五名后卫,铁锤帮在球场的这一边很强大。

看看一个团队在哪里作为一个低比例的行动也很有趣。例如,莱斯特在集群 n 53 中的分布最低。这一个对应于从场的中心到左侧的建造阶段。

在过去的 3 个赛季中,这些地区的球员是富克斯或奥尔布莱顿,他们不是莱斯特的最佳球员。此外,这并没有改变最近与麦迪逊或格雷这两个伟大的球员,但不太可能去深入自己的一部分。
相反,狐狸出现在群集 n 455 中,这相当于右侧具有“内部”通道的序列。是马赫雷兹的影响吗?很难说,但事实是第二支球队是托特纳姆,埃里克森在这一边扮演着特殊的角色(在联盟中很难找到一个球员可以和他相比,他有点独特)。

我们可以尝试另一个练习:以阿森纳为例,那里的枪手与其他球队最不同,因此在防守他们时如何集中注意力?
阿森纳在 n 361 和 n 287 几乎是独一无二的:


虽然第一个非常令人惊讶,但第二个可能是一个训练有素的战术的代表,从左侧开始,迅速改变到右侧,以一个长传结束,并有机会传中。不出意外的话,第二支集群 n 287 的球队是曼城。对面的队伍在防守这些队伍的时候会想注意这边。
可能的改进
这个框架很好地捕捉了传球序列的风格,并看到球队更喜欢在哪里以及如何比赛。然而,仍然有改进的方法:
- 当我们专注于球队的时候,我们也可以更深入地观察球员的水平,通过区分球员在传球序列中的表现来比较他们。
- 通过改变坐标参考,我们可能会欣赏传球序列的模式,不管它们的音高位置如何。所以我们可能会在训练中看到一些特定的组合,或者一些球员很受欢迎。
- 最基本的是根据球队统计数据预测比赛结果(平均控球率、每场比赛的 xG、在排行榜中的位置、庄家赔率等……)。我试图只将这些潜在向量作为描述团队的特征:我们可以通过简单的逻辑回归预测 50%的比赛结果,这在特征如此之少的情况下已经相当不错了。
资源
这里有一些资源对我写这篇博文帮助很大:
- Joe Mulberry 在 2019 年伦敦 Opta 论坛上的演讲。
- 【占有序列聚类实验】来自盖瑞·盖拉德。
- “从足球比赛记录中发现有趣的传球模式”来自 Shoji Hirano 和 Shusaku Tsumoto(日本岛根大学医学部医学信息学)。
- “冶金学家预测 NBA 球队成功的方法”作者 Peter Tsai。
- “在 Keras 中构建自动编码器”作者Fran ois Chollet在 Keras 博客上。
希望你喜欢阅读,不要犹豫给你的反馈,并在下面留下你的回应。
人工智能加速器产品

加速深度学习推理的英特尔软件和硬件
作者:帕萨·德卡和罗希特·米塔尔
如果你已经关注了我们之前在 medium 上的博客(如下),我们发布了我们如何在制造环境中使用深度学习进行质量检测:
作者:帕萨·德卡和罗希特·米塔尔
towardsdatascience.com](/quality-inspection-in-manufacturing-using-deep-learning-based-computer-vision-daa3f8f74f45)
在这篇博客中,我们将详细介绍各种英特尔软件和硬件人工智能产品。这些产品加速了深度学习推理。
什么是深度学习推理?
一旦我们在强大的 GPU 中通过数小时/数天的训练开发出最佳的深度神经网络模型,我们就必须对该模型进行操作合理化,以实现其核心商业价值。我们用一个计算机视觉用例来举例,假设我们在 GPU 中用 Keras & Tensorflow 训练了一个硬件产品缺陷检测深度神经网络分类器。现在,由于我们已经有了一个训练有素的模型,是时候在生产环境中部署该模型了,生产环境可以是本地服务器、云实例或边缘环境。如果您已经关注了我们之前的博客,这里是我们讨论的抽象用例的推理流程的图示:

我们得到一张新的图像,用经过训练的 CNN ROI 生成器进行 ROI 提取,然后用经过训练的 CNN 缺陷检测器进行缺陷检测。使用 ML 或 DL 模型的推断是生产流水线的一部分,其中实时或批量数据工程流水线处理图像并调用训练好的模型来执行预测。执行推理的 SLA 可以在几秒钟或几毫秒内完成。我们已经体验到,我们使用 Tensorflow keras/pytorch 为我们讨论的用例构建的训练模型需要花费 1 秒多的时间来对序列化的 h5py 格式的单个图像进行推断。标准 CPU 中的 pt 格式。但是我们如何用毫秒来推断呢?
软件加速器—使用 Open Vino 软件优化推理:
英特尔构建了开放式 Vino 工具套件,以优化卷积神经网络模型的推理。Open Vino toolkit 扩展到整个英特尔硬件并最大限度地提高性能:
-在边缘实现基于 CNN 的深度学习推理
-使用通用 API 支持跨计算机视觉加速器(CPU、GPU、英特尔 Movidius Neural Compute Stick 和 FPGA)的异构执行
-通过函数库和预先优化的内核加快上市时间
-包括针对 OpenCV 和 OpenVX*的优化调用
部署的两个步骤:模型优化器和推理引擎

第一步是使用模型优化器将预训练模型转换为 IRs:
- 产生一个有效的中间表示:如果这个主转换工件无效,推理引擎就不能运行。模型优化器的主要职责是生成两个文件来形成中间表示。
- 生成优化的中间表示:预先训练的模型包含对训练很重要的层,例如 dropout 层。这些层在推理过程中没有用,可能会增加推理时间。在许多情况下,这些层可以从生成的中间表示中自动移除。但是,如果一组层可以表示为一个数学运算,因此可以表示为一个层,则模型优化器会识别这种模式并用一个层替换这些层。结果是一个比原始模型层数更少的中间表示。这减少了推断时间。
IR 是描述整个模型的一对文件:
。xml:描述网络拓扑
。bin:包含权重和偏差二进制数据
第二步是使用推理引擎来读取、加载和推理 IR 文件,使用跨 CPU、GPU 或 VPU 硬件的通用 API
请参考下面的开放 Vino 文档,了解 Python API 的概况:
将深度学习网络从训练环境部署到嵌入式平台进行推理是一项复杂的任务…
software.intel.com](https://software.intel.com/en-us/articles/OpenVINO-InferEngine#overview-of-inference-engine-python-api)
请参考下面的流程图和步骤,使用 OpenVino 部署神经网络模型

请按照下面的步骤(代码片段)操作:
步骤 1:以 h5 格式保存训练好的模型
model.save('trained_model.h5')
步骤 2:将训练好的模型转换为 tensorflow pb 格式
(使用 github 回购:https://github.com/amir-abdi/keras_to_tensorflow)
python3 keras_to_tensorflow.py -input_model_file trained_model.h5
第三步:运行模型优化器(Optimizer-C:\ Intel \ open vino \ computer _ vision _ SDK _ 2018 . 3 . 343 \ deployment _ tools \ model _ Optimizer \ mo _ TF . py)
python3 mo_tf.py — input_model <your_model.pb> — input_shape=[1,224,224,3]
步骤 4:预处理图像并运行推理
我们对单个图像的推断基准:

硬件加速器:
英特尔 Movidius:
英特尔 Movidius 是为推断图像的深度神经网络而定制的。它由专为计算机视觉定制的英特尔 Movidius 视觉处理单元提供支持

技术条件
- 处理器:英特尔 m ovidius Myriad X 视觉处理单元(VPU)
- 支持的框架:TensorFlow和 Caffe
- 连接:USB 3.0 Type-A
- 尺寸:2.85 英寸。x 1.06 英寸。x 0.55 英寸。(72.5 毫米 x 27 毫米 x 14 毫米)
- 工作温度:0 摄氏度至 40 摄氏度
- 兼容的操作系统:Ubuntu* 16.04.3 LTS (64 位)、CentOS* 7.4 (64 位)和 Windows 10 (64 位)
请参考下面的视频进行介绍:
请查看英特尔 Movidius github 文档:
英特尔 Movidius 神经计算 SDK 和英特尔 Movidius 神经计算 API 文档概述。
movidius.github.io](https://movidius.github.io/ncsdk/index.html)
英特尔 Movidius 神经计算 SDK(软件开发套件):
命令行工具:英特尔 Movidius 神经计算软件开发套件提供了在开发计算机上评测、调整和编译深度神经网络(DNN)模型的工具

mvNCCompile 是一个命令行工具,它将 Caffe 或 Tensorflow 模型的网络和权重编译成与英特尔 Movidius 神经计算 SDK (NCSDK)和神经计算 API(NCAPI)兼容的英特尔 Movidius 图形
mvNCCompile inception-v1.pb -s 12 -in**=**input -on**=**InceptionV1/Logits/Predictions/Reshape_1 -is 224 224 -o InceptionV1.graph
英特尔 Movidius 神经计算 SDK 附带了一个 Python API,支持通过神经计算设备(如英特尔 Movidius 神经计算棒)利用加速深度神经网络的应用。
Python API:Python API 是作为一个单独的 Python 模块(mvncapi.py)提供的,当安装 NCSDK 时,它位于开发计算机上。它在 Python 2.7 和 3.5 中都可用
Python API 概述:
- 导入 NCAPI 模块
Python NCAPI 位于 mvnc 包内的 mvncapi 模块 9 中
from mvnc import mvncapi
2.安装一个神经计算设备
Device 类表示一个神经计算设备,并提供与该设备通信的方法
#get a list of available device identifiers
device_list = mvncapi.enumerate_devices()
用调用 enumerate_devices()获得的设备标识符之一初始化设备
#Initialize the device and open communication
device.open()
3.为设备设置网络图和相关的 FIFO 队列
NCSDK 需要使用 mvNCCompile NCSDK 工具编译的神经网络图形文件。支持 Tensorflow 和 Caffe 的许多网络模型。
当我们编译完图形后,将图形文件加载到缓冲区
#Load graph file data
GRAPH_FILEPATH = './graph'
with open(GRAPH_FILEPATH, mode='rb') as f:
graph_buffer = f.read()
Graph 类提供了利用网络图的方法。
我们可以用一个名称字符串来初始化这个图。名称字符串可以是我们喜欢的任何东西,直到 mvncapi。MAX_NAME_SIZE 个字符,或者只是一个空字符串。
#Initialize a Graph object
graph = mvncapi.Graph('graph'
图形输入和输出是通过 FIFO(先进先出)队列完成的。 Fifo 类代表了这些队列中的一个,并提供了管理它的方法。
我们应该为我们的图形创建输入和输出 Fifo 队列,并用 Graph.allocate _ with _ fifos 将图形分配给我们的设备。我们可以省略关键字参数来使用默认的 Fifo 设置,或者我们可以根据需要指定其他值。
*# Allocate the graph to the device and create input and output Fifos with default arguments*
input_fifo, output_fifo **=** graph**.**allocate_with_fifos(device, graph_file_buffer)#*# Allocate the graph to the device and create input and output #Fifos with keyword arguments*input_fifo, output_fifo **=** graph**.**allocate_with_fifos(device, graph_file_buffer,
input_fifo_type**=**mvncapi**.**FifoType**.**HOST_WO, input_fifo_data_type**=**mvncapi**.**FifoDataType**.**FP32, input_fifo_num_elem**=**2,
output_fifo_type**=**mvncapi**.**FifoType**.**HOST_RO, output_fifo_data_type**=**mvncapi**.**FifoDataType**.**FP32, output_fifo_num_elem**=**2)
4.获取输入张量
使用 cv2 模块从文件中读取图像并调整其大小以适应您的网络需求
import cv2
*# Read an image from file*
tensor **=** cv2**.**imread('img.jpg')*# Do pre-processing specific to this network model (resizing, #subtracting network means, etc.)*
5.进行推理
我们将使用 graph . queue _ inference _ with _ fifo _ elem()将输入张量写入输入 Fifo,并对其进行排队以便进行推理。当推理完成时,输入张量将从 input_fifo 队列中删除,结果张量将放入 output_fifo 队列中
*# Write the tensor to the input_fifo and queue an inference*
graph**.**queue_inference_with_fifo_elem(input_fifo, output_fifo, tensor, 'user object')
如果输入 Fifo 已满,此方法调用将阻塞,直到有空间写入 Fifo。
推理完成后,我们可以用 Fifo.read_element 得到推理结果。这也将返回我们传递给 Fifo.write_elem()的用户对象
# Get the results from the output queue
output, user_obj = output_fifo.read_elem()
然后,我们可以将输出结果用于我们特定的网络模型
6.打扫
在关闭与设备的通信之前,我们将使用 Graph.destroy()和 Fifo.destroy()来销毁图形和 Fifo 对象,并清理相关的内存。Fifos 在销毁前必须为空。然后使用 Device.close()关闭设备,使用 Device.destroy()销毁设备对象并清理相关内存
#Clean up
input_fifo**.**destroy()
output_fifo**.**destroy()
graph**.**destroy()
device**.**close()
device**.**destroy()
英特尔 FPGA:

FPGAs 是芯片设备,可以针对数据分析、图像推断、加密和压缩等工作负载进行编程。FPGAs 支持提供处理速度更快、能效更高、延迟更低的服务,从而在数据中心的电力、空间和冷却限制内最大限度地提高计算能力。
英特尔 FPGAs 的优势
- 易于部署—英特尔可编程加速卡(英特尔 PAC)在一个基于 PCIe 的卡中提供了一个英特尔 FPGA,可在多家领先原始设备制造商的经验证服务器上使用。面向英特尔至强处理器和 FPGA 的英特尔加速堆栈大大降低了 FPGA 编程的复杂性
- 标准化—采用 FPGA 的英特尔至强处理器定义了标准化接口,FPGA 开发人员和开发与运营团队可以使用这些接口热插拔加速器,并实现应用的可移植性。
- 加速器解决方案 —由英特尔和第三方技术专家开发的加速器解决方案组合,旨在加快应用开发和部署。可从流分析、图像推断等领域受益于 FPGA 加速的应用。
支持 FPGA 的 OpenVino 图像推断:
步骤 1:配置 FPGA 板:硬件
在进入软件配置之前,必须进行一些硬件方面的设置。我们需要遵循以下说明:
[## AN 807:为面向 OpenCL 的英特尔 FPGA SDK 配置英特尔 Arria 10 GX FPGA 开发套件
在使用英特尔 Arria 10 GX FPGA 开发套件之前,您必须完成本文档中的说明…
www.intel.com](https://www.intel.com/content/www/us/en/programmable/documentation/tgy1490191698959.html)
确保我们有 Jtag 连接(通过微型 USB)和 PCIe 连接。
步骤 2:配置 FPGA 板:软件
请遵循以下链接中的说明:
[## 安装支持 FPGA 的英特尔 OpenVINO toolkit for Linux 发行版
注意:-英特尔发布的 open vino toolkit 以前被称为英特尔计算机视觉 SDK。这些…
software.intel.com](https://software.intel.com/en-us/articles/OpenVINO-Install-Linux-FPGA)
2.1 初始化英特尔 Arria 10 GX 以用于 Open CL
必须用 OpenCL 映像正确初始化该板,以便它可以与 OpenCL 一起使用。请遵循以下链接中“初始化用于 OpenCL 的英特尔 Arria 10 GX FPGA 开发套件”的说明:
[## AN 807:为面向 OpenCL 的英特尔 FPGA SDK 配置英特尔 Arria 10 GX FPGA 开发套件
在使用英特尔 Arria 10 GX FPGA 开发套件之前,您必须完成本文档中的说明…
www.intel.com](https://www.intel.com/content/www/us/en/programmable/documentation/tgy1490191698959.html)
2.2 安装 OpenCL 运行时驱动程序
OpenCL 运行时驱动程序(OpenCL 的 FPGA RTE)随 OpenVINO 安装一起提供,因此我们需要确保首先安装 OpenVINO。遵循以下链接的“安装 OpenCL 运行时环境”一节中的说明
[## 安装支持 FPGA 的英特尔 OpenVINO toolkit for Linux 发行版
注意:-英特尔发布的 open vino toolkit 以前被称为英特尔计算机视觉 SDK。这些…
software.intel.com](https://software.intel.com/en-us/articles/OpenVINO-Install-Linux-FPGA)
2.3 带有 OpenVINO 提供的 bitsream 的程序板
完成上述所有步骤后,我们需要用一个与特定 CNN 拓扑结构相关的比特流对电路板进行编程
我们编程的比特流应该对应于我们想要部署的拓扑。根据我们选择的位流数量,每种 FPGA 卡类型可能有不同的文件夹,这些文件夹将在 OpenVINO 包中下载。对于英特尔 Arria 10GX DevKit FPGA,预训练的比特流在
/opt/intel/computer_vision_sdk/bitstreams/a10_devkit_bitstreams
对于采用英特尔 Arria 10 FPGA 的英特尔视觉加速器设计,预训练的双流位于/opt/intel/computer_vision_sdk/bitstreams/a10_vision_design_bitstreams
请按照以下步骤编程比特流:
- 重新运行环境设置脚本。
source /home/<user>/Downloads/fpga_support_files/setup_env.s
2.切换到主目录
cd /home/<user>
3.我们需要根据手中的卡来选择选项
- 为英特尔 Arria 10 FPGA 开发套件编写比特流
aocl program acl0 /opt/intel/computer_vision_sdk/a10_devkit_bitstreams/2-0-1_A10DK_FP11_SqueezeNet.aocx
- 利用英特尔 Arria 10 FPGA 为英特尔视觉加速器设计编写比特流
aocl program acl0 /opt/intel/computer_vision_sdk/bitstreams/a10_vision_design_bitstreams/4-0_PL1_FP11_SqueezeNet.aocx
步骤 3:为 FPGA 建立神经网络模型
请按照以下步骤创建用于推理的 FP16 模型:
- 为 FP16 SqueezeNet 型号创建一个目录:
mkdir /home/<user>/squeezenet1.1_FP16
2.前往/home/
cd /home/<user>/squeezenet1.1_FP16
3.使用模型优化器将 FP16 Squeezenet Caffe 模型转换为优化的中间表示(IR):
python3 /opt/intel/computer_vision_sdk/deployment_tools/model_optimizer/mo.py --input_model /home/<user>/openvino_models/FP32/classification/squeezenet/1.1/caffe/squeezenet1.1.caffemodel --data_type FP16 --output_dir .
4.squeezenet1.1.labels 文件包含 ImageNet 使用的类。包含该文件是为了使推理结果显示文本而不是分类号。将 squeezenet1.1.labels 复制到优化的模型位置
cp /home/<user>/openvino_models/ir/squeezenet1.1/FP32/squeezenet1.1.labels .
5.将示例图像复制到发布目录。您将在优化的模型中使用它
sudo cp /opt/intel/computer_vision_sdk/deployment_tools/demo/car.png ~/inference_engine_samples/intel64/Release
步骤 4:运行一个示例应用程序
- 转到示例目录
cd /home/<user>/inference_engine_samples/intel64/Release
2.使用推理引擎示例在 CPU 上运行示例应用程序:
./classification_sample -i car.png -m ~/openvino_models/ir/squeezenet1.1/FP32/squeezenet1.1.xml
请注意以每秒帧数(FPS)为单位的 CPU 吞吐量。这告诉我们推断在硬件上完成得有多快。现在让我们使用 FPGA 来运行推理。
./classification_sample -i car.png -m ~/squeezenet1.1_FP16/squeezenet1.1.xml -d HETERO:FPGA,CPU
我们对单个图像的推断基准:

结论:
在这篇博客中,我们详细讨论了各种英特尔软件和硬件,以优化基于计算机视觉的深度神经网络的推理。我们还详细讨论了它们的用法以及如何设置它们。我们还用我们的样本用例对我们的结果进行了基准测试。如果你喜欢我们的博客,请点击拍手按钮,并请继续关注我们未来的博客,因为我们会定期贡献关于机器学习和深度学习的博客。
来源:
https://software . Intel . com/en-us/articles/open vino-Install-Linux-FPGA
https://www . Intel . com/content/www/us/en/programmable/solutions/acceleration-hub/overview . html
https://software.intel.com/en-us/openvino-toolkit
艾:几乎不死

Photo by Angely Acevedo on Unsplash
医疗保健的人工智能革命正在改变我们对年龄相关疾病的看法,甚至是衰老本身
我们正处于一场流行病之中。不管你的家族史、种族或地理位置如何,有一种疾病会降临到我们每一个人身上。你可以躲在西伯利亚的山里,但是疾病仍然会传染给你,因为它不具有传染性。它一直伴随着人类,并将在可预见的未来继续下去,尽管我们最近试图阻止它。
这种疾病叫做衰老。
认为衰老是一种疾病是违反直觉的,因为我们把它等同于时间不可避免的冲击,但科学界有越来越多的人认为这两个概念是可分的。事实上,年龄是如此的可分,以至于有一天它可能真的只是一个数字。据 英国《卫报》 报道,35 个发达国家中,2030 年后出生的女性预期寿命最高为 90 岁以上,比 2010 年出生的女性增加了 6.6 岁。[1]
事实上,根据马克斯·普朗克人口研究所主任、杜克大学教授詹姆斯·沃佩尔的说法,“160 年来,最佳表现的预期寿命稳步增长了四分之一年。”[2]有人可能会说,事实也的确如此,我们正稳步达到一个最大年龄范围;然而,沃佩尔反驳道,“如果预期寿命接近最大值,那么预期寿命的增长速度应该会放缓。不是的。”[3]
人类可以解决衰老的想法听起来荒谬而自大。忽略生命意义的决定因素这一存在性问题,没有一个明确的终点,死亡已经成为人类经验中普遍存在的一种隐约可见的必然——唯一的必然。

Photo by Andres Urena on Unsplash
不管这看起来有多荒谬,最大的科技公司正在加入结束衰老的竞赛。谷歌的 Calico 实验室成立于 2013 年,是一项旨在解决年龄相关疾病和延长人类寿命的登月计划。但是谷歌并不孤单。苹果也将消费者医疗保健作为重点关注的领域。苹果公司首席执行官蒂姆·库克在接受美国消费者新闻与商业频道采访时表示,
“如果你放眼未来,回首过去,你会问这样一个问题,‘苹果对人类最大的贡献是什么,这将是关于健康的。" [4]
事实上,医学领域似乎正在成为可量化数据的宝库。研究人员感兴趣的不仅仅是健康记录、家族史和验血,还有生命本身的密码——DNA。普利策奖获得者、作家兼生物学家悉达多·慕克吉(Siddhartha Mukherjee)解释道:对生命中最微小部分——我们的基因——的研究与计算机科学领域的融合是多么恰当,这个领域因对由 1 和 0 组成的比特的理解和操作而发生了革命性的变化。
随着我们逐渐了解我们的个人信息,数据是无价的,特别是因为它是可以收集更深层次知识的信息。如果在互联网上买卖我们的浏览数据产生了数十亿美元的产业,那么隐藏在我们基因组数据中的秘密又有多少价值呢?需要说明的是,我在这里并不是在谈论一个个体基因组的货币价值(无论这种想法如何),而是对数百万个基因组及其伴随的物理表达进行大规模统计分析所能获得的洞察力财富。

Photo by Taylor Vick on Unsplash
每个行业都朝着以数据为中心的方法发展,这必然会挤入医疗领域。根据《时代》杂志、、【谷歌大战死亡】、、“医学正在成为一门信息科学”。[5]有了这些信息,像谷歌这样的公司自然会把“信息视为一种商品,一种可以用工业效率开采和处理的实用资源”,[6]定位于利用所有这些宝贵的数据。
尽管尼古拉斯·卡尔,一位研究技术对现代社会影响的著名作家,在他的文章中对外包人类思维的后果持否定态度,“谷歌是不是在让我们变得愚蠢?”他准确地指出了谷歌对医药领域感兴趣的原因。作为“一家从根本上讲是科学的企业,谷歌的动力来自于使用技术的愿望,用埃里克·施密特的话来说就是‘解决以前从未解决过的问题’。”[7]最难解决的问题之一是衰老,或者至少是与年龄有关的疾病,许多医学专家认为,解决办法在于人工智能和基因组学的结合。卡尔本人在一次演讲中引用了谷歌联合创始人拉里·佩奇的话,他说“致力于搜索是致力于人工智能的一种方式”。
为人工智能解决问题不是为了实现它而实现的目标,而是为了将其应用于人类面临的更广泛、更广泛的问题,这些问题是人类独自没有能力解决的。
人工智能正在改变所有行业中卡尔所谓的“知识工作”的格局,医疗保健也不例外。然而,在对卡尔的回应中,著名的未来学家贾迈斯·卡斯西欧将这一转变描绘为“我们如何管理和适应我们创造的海量知识”的必要演变。[8]就基因组而言,所创造的知识是储存在数百万个序列中的大量信息及其相应的统计意义——这些信息正是我们自身的组成部分。

Photo by Amelie Ohlrogge on Unsplash
卡斯西欧继续做了一个有先见之明的声明,告诉我们“人类不会被排除在循环之外——事实上,更多的人将有能力做一些曾经仅限于封闭的神职人员的事情”。这在医学研究中已被证明是正确的。药物发现研究员德瑞克·洛夫、告诉《纽约时报》,
“不是机器将取代化学家,而是使用机器的化学家将取代不使用机器的化学家”。[9]
技术可能不会赋予我们永生,但人类和机器智能日益增长的相互依赖性将引领我们进入一个快速医学进步的新世界——一个更实惠、更个性化、更安全的预防性保健的未来,我们的寿命和健康寿命都将大幅增加。
医学研究人员长期以来一直试图破译人类基因组。2003 年,第一个完整的人类基因组测序完成,耗时 10 年,耗资 30 亿美元。正如斯坦福大学遗传学和计算机科学助理教授 Anshul Kundaje 在他 2016 年关于“人工智能的未来”的演讲中指出的,“今天我们可以在几天内完成基因组测序,费用不到 2000 美元”。[10]
成本的快速降低创造了基因组数据的爆炸式增长——机器学习算法可以根据这些数据获得洞察力。这种见解有可能挽救患者的生命,因为他们的基因信息可以帮助医生为个体开出最有效的药物,同时将副作用降至最低。然而,仅仅解码基因组不足以像许多人希望的那样推进医学发展;研究人员必须了解代码片段是如何表达的,以便有意义地利用 2 万个基因的序列。

Photo by Daniel Christie on Unsplash
Kundaje 解释说,他的团队获得了原始数据,应用了机器学习模型,并能够分配“基因组的某种综合功能注释”。通过这样做,他的团队确定了解决阿尔茨海默氏症的潜在目标。阿尔茨海默氏症是一种可遗传的疾病,是许多基因治疗努力的目标,其作用机制长期以来一直没有得到传统治疗。
当开发有效的疗法时,知道在哪里寻找和预测药物将如何表现为药物研究人员提供了巨大的优势。直接编辑或关闭与疾病相关的基因组片段的能力在基因组学领域引起了很大的兴奋。一个名为 CRISPR-Cas9 的系统受到了很多关注,“因为它比其他现有的基因组编辑方法更快、更便宜、更准确、更高效”。[11]然而,精确编辑基因的能力对于没有目标的研究人员来说毫无用处。像 Kundaje 的项目可以帮助获得这些基因目标。
虽然 DNA 是核心,但它不是疾病背后的全部。DNA 指导蛋白质(利用 RNA 作为中介转录和翻译指令),蛋白质按照指导执行。但是,在这个过程中,“它们可能会纠缠在一起……导致糖尿病、帕金森氏症和老年痴呆症等疾病”。[12]由于这个原因,预测蛋白质的形状对于理解其功能至关重要——这是一项历史上极其困难的任务。
2011 年,研究人员众包了这件事,求助于游戏玩家来帮助找到蛋白质折叠问题的解决方案。在三周内,游戏玩家和研究人员的共同努力导致了“解决对艾滋病病毒繁殖至关重要的蛋白质狙击酶结构的关键见解”——这是一项困扰了科学家十年的壮举。[13] 根据当时《科学美国人》 的说法,“当复杂的问题需要直觉和敏锐的洞察力而不是野蛮的计算时,人类仍然比计算机占有优势”。

Protein Folding from Wikimedia Commons
显然,这种优势没有持续到这个十年的剩余时间。谷歌的 AlphaFold 是一种基于上述 Foldit 游戏训练的深度学习算法,在蛋白质折叠挑战中以巨大优势击败了 98 名竞争对手。“预测 43 个蛋白质中的 25 个蛋白质的最精确结构,相比之下,第二组的 43 个蛋白质中只有 3 个”。[14]也许更重要的是,该程序从花数周时间提供预测发展到在几个小时内就能做到。随着更多的数据和更多的实践,人工智能已经证明它将获得准确性和效率。
对蛋白质折叠的深入了解使研究人员不仅可以窥视遗传性疾病的功能,还可以研究如何开发治疗这些疾病的药物。据《纽约时报》报道,“如果科学家能够预测蛋白质的形状,他们就能更好地确定其他分子将如何‘结合’它”。像 AlphaFold 这样的工具越来越普及,可以大大减少开发治疗以前无法治愈的疾病所需的时间和金钱。
尽管 AlphaFold 的戏剧性胜利标志着人工智能在生化研究中的重要性日益增加,但并不是所有人都相信机器和开发它们的人能够提供所有答案。正如华盛顿大学蛋白质设计研究所所长大卫·贝克博士向《纽约时报》表达的那样:“创造蛋白质比正在探索的‘折叠’方法更重要,”他认为 AlphaFold 不适合完成这项任务。
正如之前对人工智能解决问题能力的质疑一样,时间会证明一切。

IBM Watson from Wikimedia Commons
机器学习及其在医学中的应用不仅限于计算基因组学或蛋白质折叠。2016 年,IBM 的人工智能机器 Watson 做了医生做不到的事情。在 10 分钟内,沃森分析了2000 万份与癌症相关的研究论文,并给出了正确的诊断——这是东京大学的医生在治疗他们 60 岁病人的几个月中未能完成的壮举。[15]与 AlphaFold 类似,Watson 也提高了准确性和效率,IBM 声称在 2011 年至 2013 年间性能提高了 240%。
正如我们在沃森和谷歌 DeepMind 的例子之间看到的那样,这些人工智能系统在分析和比较大量数据的情况下表现更好。除了开发这些深度学习算法,收集和提供尽可能多的健康数据也同样重要。
根据国家衰老研究所的说法,来自健康和高危患者的基因信息越多,“研究人员就有越多的线索来发现额外的风险因素基因”。Kundaje 在他的演讲中还提到,机器学习算法必须输入个人和大规模的基因组数据以及健康记录,才能有效地识别我们基因组成中的比特位和这些比特位中的错误可能导致的疾病之间的统计显著相关性。
令人欣慰的是,各机构正在共同努力,让研究人员能够轻松获取这些数据。ENCODE(DNA 元素百科全书)项目是一个公共研究联盟,其研究数据库可以免费访问。与此同时,哈佛在 2005 年启动了个人基因组计划,这是一个自愿的项目,参与者提供他们的生物样本用于基因研究。希望健康信息的广泛可用性和不断增长的数据库,以及健康记录的集成数字化,将推动人工智能的进步,如 IBM 的沃森和谷歌的 DeepMind。
有了这些数据,机器学习将成为医生和药物研究人员的关键合作伙伴,正如 Kundaje 所声称的那样,“将这些数据转化为基本的预测性预测、诊断、更小的药物靶点和最佳治疗策略”。
尽管尚未超越其技术障碍,但人工智能将引领我们进入一个医学进步的新时代,使个体治疗更加个性化和有效,并从根本上破坏患者与提供者的关系,不是通过取代医疗提供者,而是通过增加他们的专业知识,让他们更有效地治疗患者。随着人工智能在医疗保健领域的出现,研究人员将有权分析他们以前从未能够分析的数据,利用我们存在的代码 DNA 来了解是什么让我们健康和完整,最终使个性化医疗成为现实,有可能解决最普遍的疾病-衰老。

感谢您花时间阅读这篇文章。我是哥伦比亚大学大三学生,学习计算机科学&数学,旨在利用机器学习的力量来改善人类健康和延长寿命。
参考
[1] B. Sarah,“未来几十年预期寿命预测将超过 90 岁”,《卫报》* (2017 年),www . The Guardian . com/society/2017/feb/21/南朝鲜-妇女-预期寿命-超过 90 岁-2020-研究*
[2] J. Oeppen 和 J. Vaupel,“人口统计:提高:打破预期寿命的限制”(2002 年),科学,第 296 卷,第 5570 期,第 1029-1031 页,https://science.sciencemag.org/content/296/5570/1029
[3]同上。
[4] T .库克,《美国消费者新闻与商业频道对蒂姆·库克的采访》美国消费者新闻与商业频道* (2019),www . CNBC . com/video/2019/01/02/apple-Tim-cook-revenue-stocks . html*
[5] H .格罗斯曼,《谷歌大战死神》,时间* (2013),content . Time . com/Time/subscriber/article/0,33009,2152422–1,00.html*
[6] N .卡尔,“谷歌正在让我们变得愚蠢吗?”、大西洋* (2018)、www . thealantic . com/magazine/archive/2008/07/is-Google-making-us-study/306868*
7 同上
[8] J .卡斯西欧,《变得更聪明》,《大西洋月刊》(* 2014),www . theatlantic . com/magazine/archive/2009/07/Get-Smarter/307548/*
[9] C. Metz,“用一剂人工智能制造新药”,《纽约时报》(* 2019),www . nytimes . com/2019/02/05/technology/Artificial-Intelligence-drug-research-deep mind . html*
[10] A. Kundaje,《Anshul Kundaje:机器学习解码基因组》,《人工智能的未来》(2019 年),【www.youtube.com/watch?v=lX76DzZdjvQ】T4
[11]“什么是基因组编辑和 CRISPR-Cas9?—遗传学家庭参考— NIH”,美国国家医学图书馆,https://ghr . NLM . NIH . gov/primer/genomic research/genome editing
[12]一、样本,“谷歌的 DeepMind 预测蛋白质的 3D 形状”The Guardian(2018)www . The Guardian . com/science/2018/dec/02/Google-deep minds-ai-program-alpha fold-Predicts-3D-Shapes-of-Proteins
[13] M. Coren,“Foldit Gamers 在 3 周内解开 HIV 酶之谜”,科学美国人(* 2011),www . Scientific American . com/article/Foldit-Gamers-Solve-Riddle*
[14]一、样本,“谷歌的 DeepMind 预测蛋白质的 3D 形状”The Guardian(2018)www . The Guardian . com/science/2018/dec/02/Google-deep minds-ai-program-alpha fold-Predicts-3D-Shapes-of-Proteins
[15] A. Ng,“IBM 的沃森在医生被难倒数月后为日本白血病患者做出正确诊断”,《纽约每日新闻》(2018 年),www . nydaily News . com/News/world/IBM-Watson-Proper-Diagnosis-Doctors-Stumped-article-1.2741857
人工智能和集体行动

Photo by @pkmfaris
通过 OpenAI 的一篇研究论文迈向更负责任的人工智能发展
7 月 10 日 OpenAI 的团队成员发布了一篇关于 arXiv 的论文,名为 合作在负责任的 AI 开发中的作用 作者 阿曼达·阿斯克尔 ,迈尔斯·布伦戴奇 吉莉安·哈德菲尔德 。文章中的一个主要陈述如下:“人工智能公司之间的竞争可能会通过增加它们更快发展的激励来减少每个公司负责任发展的激励。因此,如果人工智能公司更喜欢开发风险水平更接近社会最优的人工智能系统——我们相信许多人都这样做——负责任的人工智能开发可以被视为一个集体行动问题”因此,建议我们如何处理这个问题?
负责任的 AI 开发?
人工智能在健康和福利领域的应用越来越多。
在短期内,有害的情况已经发生,例如:
- 从大数据集学到的偏见扭曲了信贷市场的决策。
- 扭曲刑事司法系统决策的历史数据和算法。
- 面部识别技术打破了人们对隐私和自主权的既定期望。
- 一些汽车中的自动驾驶功能导致了新类型的驾驶风险(同时降低了其他风险)。
更长期、更大规模的场景包括以下危险:
- 涉及自主武器系统的军事冲突意外升级。
- 大范围的失业。
- 对政治和社会机构的威胁。
负责任的人工智能开发被描述为降低风险,在这种情况下:安全,保障,以及与人工智能系统相关的结构性风险。
代价高昂的错误还是代价高昂的责任?
文章中说,如果优先考虑速度而不是安全的进度,人工智能投资的方向可能会出现混乱:“如果投入的额外资源可以用于更快地开发约束更少的人工智能系统,我们应该预计负责任的人工智能开发比轻率的人工智能开发需要更多的时间和金钱。”因此,他们提出了一个关于风险视角的重要问题<>而不是经常提出的竞争力问题。也许努力工作的态度对规模有害?
“这意味着,如果率先开发和部署特定类型的人工智能系统的价值很高,负责任的开发对公司来说成本特别高。”
然而,这里讨论的成本与可能的财务收益有关,从某种意义上说是“失去”机会。
- 先发优势的潜在损失。
- 性能成本
- 收入损失
这是因为没有以安全、安保或影响评估为由构建某些‘有利可图的人工智能系统’。关于种族的讨论假设他们有一个明确的终点,这被描述为一个“永久的 R & D 种族”。
责任的好处
令人欣慰的是,OpenAI 似乎确实概述了这些责任的负面影响,以继续向好的方面发展。如果消费者对更安全的产品有偏好,并对这种偏好做出理性反应,他们就不会购买安全性不足的产品。
这是一个平衡游戏,或者说是企业对负面影响的权衡。“安全失败对非消费者造成的伤害是负外部性,而更安全的产品对非消费者产生的利益是正外部性。”这种困境正在开发产品的公司中出现,如果没有消费者的惩罚或关注,可能很难让公司承担责任。
然而,并不是所有的工人或业主都忽视责任,据说最近技术工人的行动(抗议等)已经证明了这一点。).
这可能并不容易,原因如下
负责任必须有更强的激励。根据 OpenAI,市场力量、责任法和行业或政府监管可能还不够,他们用令人信服的论据概述了原因。
“随着尖端人工智能系统变得越来越复杂,没有参与这些系统开发的消费者将很难获得关于这些系统安全性的准确信息。”
众所周知,要解释一个特定系统的决策是非常困难的。在这方面,“等着瞧”的策略可能是有害的,尤其是当这些算法被大规模实施时,对消费者而言。我以前写过关于“跟踪并告诉”的文章,这是科技公司中另一种常见的做法——首先跟踪一个数据点,然后告诉消费者,因此这两方面似乎都没有什么责任。
如果监管机构无法评估给定人工智能系统的风险,他们在使用监管控制时可能会过于严格或过于自由
伤害更有可能伤害:“…那些被指控犯罪的人,而不是那些购买工具的人”OpenAI 的研究人员列出了我想传达的关于伤害的几点:
- 减少对网上资源的信任。
- 对公司或保险公司来说太大的伤害以至于不能覆盖所有的损失。
- 人工智能系统可能会给未来几代人带来负面的外部性,而这些人无法惩罚企业或阻止它们发生
我对最后一点特别感兴趣,因为在开发人工智能解决方案/应用程序或研究人工智能领域的社区中,缺乏对气候变化或气候危机的讨论。作为一个例子,气候变化在这篇论文中一次也没有提到,这让我感到惊讶——尽管这篇论文写得多么透彻,但这应该是完全没有提到的一个明显的点。在为 OpenAI 辩护时,“可持续发展”一词被提到过一次,并且鼓励在人工智能方面进行合作以实现良好的倡议。
他们会问这样的问题:“…为什么在缩短上市时间很有价值的其他行业(如制药业)中,竞相降低产品安全性的做法并不普遍”然而,这种说法是完全错误的。喜剧演员约翰·奥利弗举的一个明显的例子是阿片类。在这种情况下,某些首席执行官还吹嘘他们能多快获得药物批准。2018 年FDA 批准的数量创下纪录,麦肯锡提到关于率先上市的讨论已经进行了很长时间。制药行业也出现了逐底竞争,但问题是,在人工智能领域,或许需要更好的监管。
另外还提到:“公司之间的集体行动问题可以对消费者和公众产生积极影响。价格战是公司之间的集体行动问题,例如,它对消费者产生积极影响,因为它导致价格下降。”这否定了这样一个事实:价格战对生产商的影响要大得多,人们确实被解雇了——一些最穷的工厂工人或农场工人确实被解雇了。它有非常负面的影响,我不认为“大部分是正面的”会是这种意义上的特征,它忽略了对劳动力的关注。
本文中有一些尝试来玩我们的合作-缺陷游戏的场景,然而,正如他们所说的,他们的分析的一个缺点是,它吸引了过度简化的合作和缺陷的概念。他们认为:“为了“解决”一个集体行动问题,我们可以尝试将其转化为一种相互合作是合理的情况。”然而,这假定了经济理性或理性的人类行为者,而通常情况并非如此。
我可以探究非理性或缺乏理性的论点,诺贝尔奖获得者丹尼尔·卡内曼或其他人批评经济人或理性人的神话被夸大了。我推荐他的讲座有限理性地图。
如何改善合作?
概述了五个因素,以使人工智能公司在面临集体行动问题时更有可能进行合作:
- 更加相信别人会合作。
- 赋予相互合作更高的期望值。
- 将较低的预期成本分配给未完成的合作。
- 将较低的期望值赋予非往复式合作。
- 给相互背叛赋予一个较低的期望值。
他们确实表示自己的观点不足,并强调:
“……有必要将这些因素转化为各行为者能够实施的具体政策战略,以改善合作前景。”
作者反对在人工智能开发中使用敌对的修辞。另一种可能是加入研究,考虑到 DeepMind 最近发布的基于 OpenAI frontline 和谷歌多巴胺的套件,这似乎是 OpenAI 正在采取的一种方法。“人工智能领域积极而明确的研究合作,尤其是跨机构和跨国界的合作,目前在数量、规模和范围上都相当有限。”他们概述了一些合作的可能性:
需要考虑的领域可能包括
- 共同研究人工智能系统能力的形式化验证以及广泛应用的人工智能安全保障的其他方面;
- 各种应用的“人工智能为善”项目,其结果可能有广泛和很大程度上积极的应用(例如在可持续性和健康等领域);
- 协调特定基准的使用;
- 联合创建和共享有助于安全性研究的数据集;
- 共同制定应对全球人工智能相关威胁的对策,如在线合成媒体生成的误用。
本文呼吁开放,但也要考虑影响,不要什么都开放。“完全透明作为一个追求的理想是有问题的,因为对于在所有情况下实现问责制来说,它既不必要也不充分”
我们可以激励良好的行为
OpenAI 论文中提到了一系列可能的激励措施,具体如下:
- 社会激励(例如,评价或批评与人工智能开发相关的某些行为)可以影响不同公司对风险和机遇的看法。
- 经济激励(由政府、慈善家、行业或消费者行为引发)可以增加高价值人工智能系统在特定市场或更普遍市场中的份额,并增加对特定规范的关注。
- 法律激励(即禁止某些形式的人工智能开发,并处以经济或更严厉的惩罚)可以大幅减少一些行为者以某些方式叛逃的诱惑。
- 与人工智能特别相关的特定领域激励(例如,早期获得最新一代的计算能力)可用于鼓励某些形式的行为。
本文引发的问题
作者概述了一系列需要进一步探讨的问题。逐字列出如下:
- 人工智能行业发展的竞争动态与政府主导或政府支持的人工智能发展有何不同?
- 法律机构、政府和标准化机构在解决公司之间的集体诉讼问题时,特别是当这些集体诉讼问题可能在国际公司之间出现时,应该扮演什么样的角色?
- 可以发现或构建哪些进一步的策略来帮助防止负责任的人工智能开发的集体行动问题的形成,并在这些问题出现时帮助解决这些问题?我们能从历史或当代工业中吸取什么教训?
- 特定的技术发展或对此类发展的预期会如何影响竞争态势?
最终反射
我很高兴 OpenAI 提出了这些问题,尽管一些关于某些理论思想的批判性想法正在进行中,但总体而言,这可以说是一个非常重要的举措,推动该领域朝着更负责任地使用技术的方向发展。这是 OpenAI 被要求承担的额外角色,以确保人类从这一技术变革中受益。我当然会鼓励你不要相信我的观点,通过阅读原文来补充你自己的观点。否则,我希望这是有用的,并确保给我留下任何想法,你应该想到的东西。
这是#500daysofAI 每天写人工智能的第 79 天。
人工智能和颠覆性创新

Source: Alaa Khamis
人工智能与全球经济
人工智能将对全球经济产生重大影响。据估计,2019 年全球预测分析软件的市场规模将超过 65 亿美元,高级驾驶辅助系统的全球市场规模将在 2019 年达到 180 亿美元,而 2012 年为 56 亿美元,企业、消费者和医疗保健领域的全球语音识别市场将在 2017 年达到 1130 亿美元,而 2012 年为 530 亿美元,自然语言处理市场预计将在 2018 年超过 99 亿美元,而 2018 年为 38 亿美元这些预测和基于人工智能的产品和服务的巨大财务成功鼓励了许多风险资本家投资机器智能领域。这导致人工智能初创公司在自然语言处理、预测分析和深度学习等领域获得的资金大幅增加,这些领域使用了大量可用的大数据,因为世界上 90%的数据是在过去两年中产生的,而且这些数据中的大部分都是数字化的。6.6 万亿美元的生产率增长加上 9.1 万亿美元的更大消费者需求,到 2030 年,由于人工智能,全球 GDP 将增加 15.7 万亿美元的附加值 FastCompany 。这些成功故事的共同点是颠覆性创新。
人工智能作为颠覆性创新的推动者
人工智能是颠覆性创新的关键推动者,这种创新导致改变游戏规则的产品和服务能够服务于低端或未得到服务的消费者,并迁移到主流市场。这项技术是我们目前目睹的颠覆性创新背后的驱动力。例如,人工智能使共享经济成为一种新的商业模式,个人可以将自己的资产作为服务与他人分享,以更好地利用这些资产并创造利润。该模型已成功应用于不同领域,如拼车、智能快速原型、智能电网、住宿等。根据创新者的困境,持续创新旨在满足客户当前的需求,根据客户的反馈提高产品性能,减少缺陷,使产品更快更强大。另一方面,破坏性创新满足了客户的未来需求,可能会在一些关键功能上提供较低的性能,但会创造出一些受市场重视的独特功能。

Source: Alaa Khamis
大英百科全书和维基百科分别是持续创新和破坏性创新的例子。《大英百科全书》提供了一部可靠的英语百科全书,而维基百科的可靠性经常受到质疑。然而,维基百科是一个免费的多语言百科全书,每个人都可以访问。这同样适用于昂贵的导航系统和谷歌/苹果地图中的导航功能。与谷歌/苹果地图相比,前者更可靠,不依赖于网络覆盖,但更昂贵,并且不提供实时交通更新。
卡诺模型
Kano 模型是理解客户对新产品和服务需求的一种富有洞察力的方式。破坏性创新位于吸引质量和期望质量之间的区域,而持续创新位于期望质量和期望质量之间的区域。随着顾客期望的变化,有吸引力的特征变成了预期的特征。例如,电动车窗、电动座椅、可调方向盘、巡航控制等汽车功能正从理想功能转变为预期功能。其他功能,如车道保持辅助、自适应巡航控制、盲点检测和预测,正在从吸引人的功能转变为理想的功能。虽然像超级巡航和自动驾驶这样的功能对许多客户来说仍然很有吸引力。

Source: Alaa Khamis
如果产品/服务不能反映不断变化的客户期望,客户可能会放弃该产品/服务,转而使用另一种具有更具吸引力功能的产品/服务。许多基于持续创新的公司倒闭了,如 Borders、Blockbuster、Kodak 和 Columbia,取而代之的是采用人工智能和颠覆性创新的软件公司,如亚马逊、Netflex、flicker 和 Apple Music。现在,谷歌是最大的营销平台。亚马逊是最大的书商,Skype 是增长最快的电信公司,LinkedIn 是增长最快的招聘公司,iTunes 和 Spotify 是增长最快的娱乐公司,Airbnb 是世界上最大的住宿提供商,尽管它没有任何房地产。此外,比特币是世界上最大的无现金银行,优步是世界上最大的无车辆出租车公司,脸书是世界上最受欢迎的无内容媒体所有者,阿里巴巴是世界上最有价值的无库存零售商。
是时候在别人之前扰乱你的生意了。扰乱或灭亡!
传统的 IT 治理必须针对企业 AI/ML 进行再造
企业中的 AI/ML 必须不断发展,以确保必要的可再现性和可追溯性。这里有一些实用的步骤来解决这个问题。

Photo by Dana Vollenweider on Unsplash
如今,常见的是,公司 It 以治理传统应用交付的方式治理 AI/ML 交付过程。不幸的是,这导致 AI/ML 生命周期被相同的官僚流程、手动活动和移交所阻碍,从而加重了常规应用交付生命周期的负担。
对于延迟和较长的交付周期可能会产生微小影响的公司应用程序来说,这是可以容忍的。然而,这对于要求速度、敏捷性和响应性的下一代支持 AI/ML 的应用来说是不可接受的。显然,公司的 IT 治理必须重新设计以适应 AI/ML 的需求。
AI/ML 治理驱动可再现性、可追溯性和可验证性
AI/ML 治理的目标是确保提供证据,证明一个模型及其交付过程能够生成可重复、可追踪和可验证的结果。
显然,这在很多方面都是有益的:首先,在一些行业中,可追溯性是强制性的。以我们有丰富经验的银行业为例,监管监督非常重要,并对人工智能/洗钱交付流程实施控制。例如,模型风险管理对分析过程提出了严格的要求,以便 AI/ML 模型按预期工作。在美国,这是通过诸如SR 11–7之类的法规来解决的,而在加拿大,这是通过企业范围模型风险管理指南(E-23) 来解决的。
然而,从医疗保健和生物技术到政府安全的许多其他行业都有类似的监管需求。AI/ML 治理推动了解决模型可追溯性需求所需的能力。
第二,客户和公司现在要求模型提供符合道德和不带偏见的可验证的结果。不幸的是,人工智能/人工智能模型的结果是由输入其中的数据和创建它们的人的未知偏见所驱动的,这可能导致基于种族、民族、性别或政治偏见的隐含决策。
识别、理解、验证和提供结果的证据是 AI/ML 治理的核心原则,并且必须成为 AI/ML 模型有效性的核心决定因素。
最后,企业认识到快速交付结果需要可重复的 AI/ML DEVOPS 流程。今天,数据科学家遵循的流程在许多方面反映了传统的科学流程,因为他们使用了一个高度迭代和实验的流程。
然而,依靠传统科学方法的公司,经过几十年的实践,已经有了一个成熟的、可重复的过程来证明结果并将产品推向市场。另一方面,数据科学家没有成熟的流程。AI/ML 治理提供了创建可复制和可重复的模型结果的动力和机制。
简单地说,让 AI/ML 治理成为一门必修的学科是有实际意义的。
模型元数据——AI/ML 治理的基础
现代 AI/ML 治理的基础是在整个模型生命周期中捕获 AI/ML 模型度量和元数据的能力。从基础开始,必须使用源代码控制工具(例如 GitHub 或 GitLab)捕获所有模型源代码和版本,允许数据科学家协作快速开发模型,但也允许保留关键的模型工件。
为了解决可重复性问题,必须将训练数据迁移到只读档案中,并且必须捕获模型源代码和用于训练模型的数据之间的关联。
为了解决可追溯性问题,必须对原始源系统数据和用于转换和丰富数据的数据工程脚本进行归档,从而提供跨交付生命周期的所有数据更改的可见性。
为了解决可验证性问题,所有的培训输出、日志和相关的工件都必须被归档,从而提供一个模型被证明按照规范工作的证据。
一个恰当的人工智能/操作(DEVOPS for AI/ML)过程可以捕获所需的度量和元数据。即使是现在,主要的云提供商、传统的 DEVOPS 供应商以及较新的 AI/OPS 初创公司都可以提供工具和功能,这些工具和功能可以缝合在一起,以捕获许多所需的指标和元数据。

Photo by Alfons Morales on Unsplash
AI/ML 市场——模型、数据和生命周期工件的目录
虽然度量和元数据捕获在今天非常可行,但一个成熟的 AI/ML 环境可能包含数百个模型和相关的培训资产——实际问题是如何以易于消费的格式呈现这些信息。
门户或仪表板——一个“AI/ML 市场”—提供了可视化模型和相关培训数据以及相关生命周期工件的机制,并充当了现代 AI/ML 治理的视窗。AI/ML 市场应该提供核心的模型管理功能,包括:搜索模型,识别模型的相关训练和验证数据,了解在创建训练和验证数据时使用的数据谱系,查看模型的元数据和指标,测量模型的性能和有效性,甚至可能了解数据科学家的生产力。
不幸的是,没有一家供应商能以集成的方式提供这种能力。如今,企业可能需要为其 AI/OPS 工具提供额外的工具,集成关键指标和元数据,并且可能还需要为 AI/ML 市场门户/仪表板构建关键的用户界面元素。
然而,预计这是一个短期的差距,创新的供应商和初创企业将很快提供更多的集成产品和复杂的用户界面。
认证—自助式人工智能/人工智能治理推动敏捷性
在模型生命周期的每个阶段,通常都有一些严格控制模型升级的度量标准,这些度量标准通常可以从前面讨论的基础元数据中收集。
AI/ML 市场服务于两个目的:首先,它提供了一个仪表板,允许数据科学家和运营人员查看这些指标的状态,并做出模型推广和治理决策。
第二,它提供了一种实现“自助式”治理的方法,一旦度量标准和支持证据被捕获,就允许对模型进行一次点击式认证。一旦通过认证,模型元数据和相关的工件将被存档,以备将来审计。
现代人工智能/人工智能治理具有商业意义
借助 AI/ML 模型指标和元数据捕获,再加上通过灵活的 AI/ML 市场进行的单击式认证,现代 AI/ML 治理现在已经从冗长的官僚流程转变为敏捷快速的活动。
通过解决现代 AI/ML 治理实践,数据科学家将体验到超过其竞争对手的生产力。通过采用这些技术,数据科学家的工作将变得更容易、更简单、自动化程度更高,并最终提高生产率。但也许最重要的是,如果知道 AI/ML 能力是以一种安全、可认证和可验证的方式部署的,这种生产力将会实现。
作者:埃里克·布洛达,约翰·米勒, SVDS 集团,迈克·兰布尔, ModelWorks
人工智能安全和对抗性机器学习 101

介绍
人工智能(AI)越来越频繁地登上头条。新技术产品持续包含人工智能。它还触及了网络安全领域,给了攻击者和 T2 防御者更大的机会来实现他们的目标。我已经发表了一些想法,将机器学习用于网络安全解决方案,以及实施 ML 技术改善黑客攻击。似乎人工智能在柜台的两边都起作用,所以没有办法明确地说人工智能是好是坏。今天我要给一切泼点冷水。
UPD 2021: 这里你可以找到关于 AI 和 ML 攻击的最新报告
事实上,我们在人工智能的帮助下取得的成果不应该被低估。让我们弄清楚一些术语。我想提出我的观点。广义地说,人工智能是让事物变得智能的科学。换句话说,AI 是由机器执行的人类智能。

图一。AI 怎么可能长得像
什么是智能?想一想人们可以轻松完成而机器通常会失败的一些能力。它们是感知(声音、视觉、感官、嗅觉)、NLP(理解、生成、翻译)、常识和推理。这就是我所说的人工智能(或者至少是现在正在发展的人工智能)。在过去的五年里,人们目睹了这一领域的进步。很可能,它的实施将在未来五年内成为现实。大多数好处,特别是在感知方面,都遵循了深度学习(DL)方法,并显示了它们的实际收益和超越人类的能力,主要是在视觉任务和语音识别方面。
几个世纪以来,机器在体力劳动方面胜过人类,但在所有其他领域却输给了人类。现在,我们离机器时代更近了,机器能做的不亚于所有的感知、NLP 和推理任务,这意味着世界上有希望的发展和快速的变化。
权力带来责任,人工智能像任何技术一样,也不能免受攻击。这一事实既令人失望,又刺激了网络安全解决方案的发展,从长远来看,这是有价值的。在参与设计用于用户异常检测的 ML 引擎时,我的目标之一是建立一个不仅能检测而且能对抗网络攻击的系统。这促使我探索人工智能安全领域以及机器学习算法中的漏洞(人工智能的主要领域之一)。
第一个愚弄机器学习算法的案例被公布,以展示垃圾邮件过滤器旁路的实际实现。虽然有很多关于 ML 算法安全性的研究论文,但在 2012 年的深度学习热潮之后,人们在几年前产生了很大的兴趣,当时 AlexNet 等用于图像识别的神经网络在图像识别任务中的表现超过了人类。这个想法看起来很有前途,没有人想到安全问题,他们通过开发更多质量更好的模型来匆忙改进。不幸的是,黑客攻击模型的可能性是深度学习算法的一个关键架构弱点,这在 2013 年由包括 Ian Goodfellow 在内的一组研究人员在他们题为“神经网络的有趣特性”的文件中涉及。这些应用容易受到对立例子的影响——合成创建的输入假装与一个类别相关,目的是欺骗 AI 和错误分类图像。事实上,对于复杂的物体,你不能简单地用一个公式来区分它们,因为总会有一个对立的例子,看起来像真的,但却被归类为假的。为什么要学习神经网络的漏洞,以及如何在现实生活中使用它?让我们试着进一步回答这个问题。
为什么要黑 AI?
人工智能的出现被认为是技术发展的里程碑。人工智能正在稳步涌入我们的世界,并渗透到隐藏的垂直行业和最意想不到的行业。由于许多业务流程已经自动化,现在越来越多的决策由机器人做出。
此外,拥有与网络安全相关的技术的地方越来越多。虽然早期的黑客可以从你的电脑中窃取数据或清空你的银行账户,但现在他们有机会影响你的一举一动。鉴于当今互联世界的性质,人们离不开笔记本电脑、手机、智能手表或自治设备,这很容易实现。运输和通讯工业的完全自动化指日可待。食品和医疗保健是人工智能算法的下一个目标。不幸的是,它们像任何其他算法一样,容易受到不同的网络攻击。
你可能会问为什么人工智能网络安全如此重要。事实上,网络攻击者已经可以制造不同的问题,并在易受攻击的系统中造成混乱。如果行为和操作逻辑是已知的,人工智能和人类一样可以被欺骗。看看可能的干扰类型和为什么有人会试图入侵基于 ML 算法的系统的原因。下面列举一些例子:
运输业 。
诱骗自动驾驶汽车曲解停车标志或限速。大量的研究项目和实验证明这是真实的。自动驾驶汽车的关键任务之一是图像分类,例如路标的识别。显然,弄清楚如何欺骗路标识别系统会导致可怕的事故。截至 2019 年初,已经发表了 100 多篇研究论文,展示了攻击图像识别系统的各种方法。如果需要的话,大部分作品都可以被赋予生命。考虑到所有的障碍,可以在路标上贴一个小标签,这样系统就会把它当作另一个标志。
网络安全行业 。
绕过垃圾邮件过滤器。这是机器学习出现的最古老的领域之一。事实上,垃圾邮件过滤器不仅是为电子邮件设计的,因为新的图像、语音或视频通信过滤器将会存在,在这种情况下,我们可以称之为人工智能,因为它们现在更加感性。它们将派上用场,以逃避无数的虚假图片,音频和视频流,这是每个人未来的隐现威胁之一。关于绕过垃圾邮件过滤器的研究多达数十项,而且数量还在不断增加。
绕过基于人工智能的恶意软件检测工具。越来越多的恶意软件检测系统使用 ML 算法来检测恶意软件。这些算法有其缺点,可能导致黑客修改现有的恶意软件,以便系统将它视为安全的应用程序。研究人员发布了近 20 篇文章,展示了在实践中绕过不同恶意软件检测系统的方法,包括 pdf 和 Android 应用程序中的文件——三种最广泛的感染源。
零售业 。
绕过面部识别。事实上,面部识别是新门禁解决方案的核心。在 iPhone X 等智能设备的时代,确保该系统受到绝对保护,从而无法被黑客攻击是非常重要的。许多办公楼已经采用了面部认证系统;此外,有新的自动取款机使用面部识别作为额外的安全措施。人脸识别系统攻击类似于图像分类系统中使用的方法,但有其独特的特征。目前,超过 10 项不同的研究揭示了如何绕过面部识别系统,例如,借助特殊的眼镜。
智能家居行业
伪造语音命令。如果你的亚马逊 Echo 把一些噪音识别为命令怎么办?很可能,噪声具有最佳频率,这对于人耳来说几乎是听不见的。这不是我的想象。不同的研究表明,很有可能在某人的声音中加入极小的听不见的噪音,这样文本就会被认为是某种指令。因此,语音助手可以执行任意命令并被黑客攻击。
网络和社交媒体行业
影评、酒店等的傻子情绪分析。研究人员演示了一种对系统进行错误分类的方法,该系统会自动对评论进行评级。事实证明,写一个负面的评论被认为是正面的是可能的。实践研究不像与其他类型的攻击相关的研究那样普遍。然而,也有这样的例子,一个句子中一个单词的微小变化会导致系统误解一个评论的真正价值。
金融行业。
欺诈异常和欺诈检测引擎。正如恶意软件攻击中提到的,越来越多的网络安全解决方案,如欺诈检测系统、威胁检测系统和用户行为解决方案,使用 ML 技术来更好地检测网络攻击。不幸的是,根据最近的一些研究论文,黑客也可以操纵这些系统。
然而,这并不是一个完整的列表。上述系统即将全面实施。如果这对你来说似乎有些牵强,我可以断言,人们没有看到一波真正的攻击只是因为这些系统没有那么受欢迎。然而,当这一时刻到来时,犯罪分子将利用现有的漏洞。
人工智能安全漏洞和威胁
罪犯究竟能对基于人工智能的系统做什么?所有的攻击都可以分为机密性、可用性和完整性这三个最常见的部分。
机密
目的是收集关于系统的见解,并利用收到的信息为自己谋利或策划更高级的攻击。
换句话说,一个恶意的人与一个机器学习系统打交道,比如说,一个图像识别引擎,以便深入了解和了解更多关于数据集等内部信息。例如,黑客可以通过制作两个有针对性的广告来猜测脸书某个人的性取向,并检查哪一个适合这个人。当网飞发布他们的数据集时,发生了一个现实生活中的隐私事件。虽然数据是匿名的,但黑客能够识别特定评论的作者。
个人助理收集大量的个人信息以提供更好的服务。这可能对攻击者有所帮助。如果一个声音可以被模仿,一个犯罪者会让你的私人助理说出任何秘密。在系统和专有算法的世界中,目标之一将是利用系统的算法、关于系统结构的信息、神经网络、该网络的类型、层数等。这些信息对进一步的攻击很有帮助。如果我们知道网络的类型及其细节,就可以在家里重建网络,然后发现其他攻击方法。
有效性
目标——禁用人工智能系统的功能。
有一些破坏的方式:
- 用请求淹没 AI,这比一般的例子需要更多的计算时间。
- 充斥着分类不正确的对象,增加了人工误报的工作量。以防这种错误分类发生,或者需要削弱对该系统的信任。例如,攻击者可以让视频推荐系统向喜剧爱好者推荐恐怖电影。
- 通过用错误的例子重新训练模型来修改模型,从而使模型结果令人失望。只有模型在线训练才有效。
- 使用人工智能模型的计算能力来解决你自己的任务。这种攻击被称为对抗性重新编程。
完整
人工智能中的欺诈代表错误分类的任务。简单的例子是需要让人工智能(如自动驾驶汽车)相信路上有一只猫,而实际上它是一辆汽车。攻击者有两种不同的方式来做到这一点——通过在学习或生产阶段与系统进行交互。前一种方法被称为投毒,攻击者在训练数据集中投毒一些数据,后一种方法是规避,attackerы利用算法的漏洞来指示人工智能系统进行误操作,如误分类。
人工智能:机器学习算法
理解对人工智能解决方案的不正当威胁可以让我们更进一步,从技术的角度来看待这个问题。
如前所述,人工智能代表覆盖一种或另一种感知感觉的智能事物(作为一个简化的概念),而技术解决方案则被搁置一旁。机器学习来到这里。
AI 代表使事物变得智能,而 ML 代表实现这种“智能”功能的特殊方法。例如,以人工智能驱动的图像识别系统为例,看看这个系统中的所有算法,你会发现至少有两个独立的机器学习任务。一种代表目标检测(或图像分割),目的是检测图片中的人脸,并选择捕获该人脸的图像部分。另一项任务是图像分类,目的是发现照片中究竟捕捉到了谁和什么。这是一个特定人工智能解决方案中不同人工智能任务的例子,其他任务可以是自然语言理解、情感分析、文本推荐等。这些任务的数量正在增加。从技术上来说,它们中的一些是相似的,例如图像分类和情感分析——两者都是分类任务——因此可以共享漏洞。有些可以完全不同像游戏中的图像分类和最优路径计算。以下是如何让它更容易理解。
机器学习任务有各种类别(分类、聚类、回归等。)和方法(有监督、无监督、强化)。这些任务中的每一个都有不同的安全相关属性,这可能会导致攻击。
最常见的任务是分类。由于流行,分类算法具有更多对抗对手的弱点的例子。但是,其他任务和方法(如聚类和强化学习)也容易受到攻击。下图说明了 ML 任务和方法的高级类别。

http://vas3k.com/blog/machine_learning/
图片。2.经典机器学习图谱
对监督学习的攻击(分类)
分类是安全研究针对的第一个也是最受欢迎的机器学习任务。
分类是一项简单的任务。假设您有两堆按类型分类的图片(例如,狗和猫),并希望您的系统能够自动对它们进行分类。
监督学习方法通常用于分类,其中某些组的例子是已知的。所有的类都应该被初始定义。ML 模型所基于的所有算法(从支持向量机到随机森林和神经网络)都容易受到不同类型的敌对输入的攻击,第一次攻击发生在 2004 年的研究论文中—“敌对分类”。目前,有超过 100 篇论文涉及分类算法的不同攻击和防御方法。

图片。3.带有垃圾邮件过滤器的机器学习分类任务示例
对监督学习的攻击(回归)
回归(或预测)很简单。关于现有数据的知识被用于了解新数据。举一个用价格数据预测和操纵股票价格的例子来高估价格。关于回归的技术方面,所有的方法都可以分为两大类:机器学习和深度学习。令人惊讶的是,如果与 2004 年至 2018 年发表的超过 200 篇研究论文的分类相比,回归学习攻击并不那么受欢迎。有几个对回归进行实际攻击的例子,如“多学习者对抗性回归 2018 ”。

图片。4.回归学习攻击例子。红线显示了海军圆点的大致趋势。
对半监督学习(生成模型)的攻击
生成模型的任务与上述不同。监督学习任务(分类和回归)处理现有信息和相关决策,而生成模型旨在基于之前的决策模拟实际数据(而非决策)。生成模型,如 GANs 或自动编码器,也容易受到攻击。标题为“生成模型的对立例子”的文章中提到了一个例子。

图片。5.生成对抗网络方案
在图中。G 是生成器,它从潜在空间中提取样本并添加一些噪声,D 是鉴别器,它可以判断生成的假图像是否看起来像真实样本。
对无监督学习(聚类)的攻击
最常见的无监督学习示例是聚类。聚类类似于分类,唯一但主要的区别是。关于数据类别的信息是未知的,也不知道这些数据是否可以分类。这就是无监督学习。
聚类是一项不太常见的任务,与分类相比,考虑攻击聚类算法的文章要少得多。聚类可用于恶意软件检测,通常新的训练数据来自野外,因此攻击者可以操纵恶意软件分类器和该聚类模型的训练数据。最常见的聚类算法之一是 K-最近邻,最近有一项研究显示了对该算法的实际攻击——“深度 K-最近邻的鲁棒性”。

图片。6.阐释了不同的聚类分析方法以及它们将多个示例分成多个聚类的方式。
对无监督学习的攻击(降维)
如果您的复杂系统有未标记的数据和许多潜在的特征,那么降维或泛化是必要的。您不能应用聚类,因为典型方法会限制要素的数量或者不起作用。降维可以帮助处理它,削减不必要的特征。与聚类一样,降维通常是更复杂模型中的任务之一。
虽然这种机器学习类别不如其他类别受欢迎,但有一个例子表明,研究人员对基于 PCA 的分类器进行了攻击,以检测网络流量中的异常。他们证明了 PCA 对异常值的敏感性可以通过污染训练数据来利用,这使得对手可以显著降低对特定目标流的 DOS 攻击的检测率。
降维示例从左边第三个空间到右边第二个空间看(Pic。7).

图片。7.降维示例
对强化学习的攻击
强化学习是一种环境驱动的方法。这就像一个孩子通过试错来学习环境,或者通过做和以某种方式做出反应来学习模型。与有监督的或无监督的学习相比,在开始之前,没有数据输入到我们的模型中。通常,强化学习方法应用于在不断变化的环境中工作的系统,强化学习模型是应用于自动驾驶汽车解决方案的机器学习任务之一,其他如图像识别和语音识别。
最后,强化学习算法也容易受到敌对攻击,去年有许多关于这个主题的研究论文,包括最新的一篇名为“深度强化学习对策略诱导攻击的脆弱性”的论文。本文已经表明,在博弈的每一帧中加入对抗性扰动会任意误导强化学习策略。
如你所见,攻击每个机器学习任务是可能的。我没有触及具体的攻击类型以及它们对每个 ML 模型的利用,因为我打算给出 ML 任务类别及其易受攻击性的概述。

图片。8.你可以看到一个代理人(恐龙),它的奖励取决于在迷宫中的行动。
对 AI 和 ML 的攻击摘要
你所读到的只是对人工智能算法安全这个广泛话题的介绍。您看到了可能受到危害的多个行业,从可用性到完整性的各种威胁,以及不同类别的攻击,其中一些是几年前才发明的。
从显而易见的角度来看,情况是令人悲伤的——所有的人工智能系统都有弱点,不幸的是不容易修复。这个问题更像是一个普通的数学问题,而不是一个可以通过改变算法来解决的小问题。
有许多研究人员试图解决本文中没有提到的这些问题。这些问题需要另一篇文章来扩展当前文章的内容,并详细描述所有现有的攻击和解决方案。
UPD 2021: 这里你可以找到关于 AI 和 ML 攻击的最新报告
来自《走向数据科学》编辑的提示: 虽然我们允许独立作者根据我们的 规则和指导方针 发表文章,但我们不认可每个作者的贡献。你不应该在没有寻求专业建议的情况下依赖一个作者的作品。详见我们的 读者术语 。
人工智能与九种智能

Photo by @art_ed
人工智能中的“智能”包含或缺少什么
一个朋友发给我一个不同类型智力的框架。多元智能理论。我发现阅读和讨论这些观点很有趣。心智框架:多元智能理论于 1983 年由哈沃德·加德纳发布。他目前是哈佛零项目的高级主管,自 1995 年以来,他一直是 Good 项目的联合主管。他写了数百篇文章和三十本书。
我将要概述的理论是他最著名的理论。以这种方式缩短它可能会减少他的理论,但我会尽我所能。因此,这是背诵信息,然后是一个简短的反思。
必须指出的是,加德纳不支持给学习者贴上特定智力的标签。以下理论应该“授权”而不是限制
一个多元智能理论
根据加德纳的说法,智力是“一种处理信息的生物心理潜力,可以在文化环境中被激活,以解决问题或创造在文化中有价值的产品。”
- 音乐节奏
这个区域与对声音、节奏、音调和音乐的敏感度有关。 - 视觉空间这个区域处理空间判断和用心灵之眼想象的能力。
- 言语语言智商高的人表现出对词汇和语言的能力。
- 逻辑-数学
这个领域与逻辑、抽象、推理、数字和批判性思维有关。 - 身体动觉智能的核心要素是控制一个人的身体运动和熟练处理物体的能力。
- 理论上,拥有高人际智能的个体对他人的情绪、感觉、气质、动机非常敏感,并且有能力作为团队的一部分进行合作
- 这个区域与内省和自我反省能力有关。能够预测自己的反应和情绪。
- 最近增加的(1995 年)这个领域与培养和将信息与一个人的自然环境联系起来有关。深深植根于敏感、道德和整体的理解以及人类在更大生态圈中的作用。
- 存在主义
后来加德纳在(1999)补充道,“存在主义”智能可能是一种有用的构造。
短反射
一个直接的反应让我想到了奥斯陆大学的一个研究小组,他们研究:
…以音乐、动作和视听媒体为经验出发点,揭示人类节奏背后的基本认知机制。
它是高度跨学科的,结合了音乐学、心理学和信息学的方法。今年早些时候发表的一份报告显示,他们通过这种跨学科的工作极大地改善了他们的机器人工作。之前我写过关于增强或取代音乐家的算法(人工智能辅助或人工智能创作的音乐)。
我的主要收获是从的角度来看,智力不应该被简单地归类为推理或逻辑。智力不仅仅是。
在斯坦福以人为中心的人工智能研究所成立期间,最近又有一个关于斯坦福科技环境的视频。在一个融合了不同背景的不同类型的人的艺术和创造性环境中,新的创作是如何产生的。
- 我们必须接受数学和数字,以及对人类意义的更广泛的看法。从某种程度上说,人工智能是对我们是谁的徒劳追求。他被引诱到一个池塘,在那里他靠在水面上,看见自己青春焕发。那西塞斯没有意识到这只是他自己的倒影,并深深地爱上了它。
- 在追求超越自我的过程中,我们必须记住我们是什么和智慧是什么的多样性。人工神经网络的这一进步使我们能够以不同的方式来看问题,然而我们必须超越反思来看问题。一些人类拥有并分享的声音、视觉、文字、数字、运动、爱、反身性、生态圈和存在能力。
构建的边界肯定是模糊。
智力的意义远不止于此。
事实上,你认为智力是什么?
––––––––––––––––––––––––––
这是#500daysofAI 的第 24 天,希望你喜欢。
后来,这个理论受到了批评。一种批评是它过分强调了领域的自主性,一些批评是缺乏来自心理学和神经科学领域的经验证据。你可以把它作为一个思考的片段,而不是一个绝对的规则。理论框架不代表真理。
–
什么是#500daysofAI?
我在挑战自己,用#500daysofAI 写下并思考未来 500 天的人工智能话题。这是我发明的一个挑战,让自己一直思考这个话题,分享我的想法。
这是受电影《夏日 500 天》的启发,主角试图找出爱情失败的原因,并在此过程中重新发现他生活中真正的激情。
人工智能和冒名顶替综合症

让我们或人工智能变成冒名顶替者
你努力成为什么样的人?我们希望 AI 变成什么样?
五年前,当我帮助建立一个合作空间时,我在与一名程序员的对话中遇到了一个术语。我曾经和一家公司的技术主管交谈过,很多人认为他非常擅长编程,他承认自己经常觉得自己是个骗子。后来和其他开发人员交谈时,我意识到这在 T2 的技术人员中是很常见的事情。
:自我指导、协作、灵活和自愿的工作方式,建立在参与者之间相互信任和共享共同核心价值观的基础上。
多年来,在编程模块领域和一些开发人员打交道的过程中,我仍然觉得这是一个持续存在的现象。您的代码要么运行,要么不运行。当它运行时,可能会出错。
经常会有一些 bug/错误需要修复。编程的薪水更高,这可能会带来更高的生活水平,但也许我们可以问,这是否会给那些发现自己处于这种幸运地位的人带来压力。也许是运气?我活该吗?
冒名顶替综合征(也称为冒名顶替现象、冒名顶替、欺诈综合征或冒名顶替体验)是一种心理模式,在这种模式中,个人怀疑自己的成就,并对被揭露为“欺诈”有一种持续的内在恐惧。

Graphics created by Chris Do
尽管有他们能力的外部证据,那些经历这种现象的人仍然相信他们是骗子,不值得他们所取得的一切。患有冒名顶替症的人错误地将他们的成功归因于运气,或者是欺骗他人认为他们比自己想象的更聪明的结果。
所以在某种程度上,这是对“被发现”的恐惧,因为你认为自己没有别人认为的那么有才华。
你有没有觉得自己像个骗子,只是靠猜测和胡扯度过难关,害怕随时会有人打电话给你。我能想出很多我有这种感觉的例子[……]所以对我来说,冒名顶替综合症是一种感觉,感觉好得超出了你的能力范围,但已经在这种情况下根深蒂固了。从内心来说,你知道你不够熟练,不够资格去证明你在那里,但是你在那里,你必须找到一条出路,因为你不能就这么出去。这不是对失败的恐惧,也不是对能够做到的恐惧。这更多的是一种侥幸逃脱的感觉,一种被发现的恐惧,一种随时有人会发现这一点的感觉。
-迈克·坎农-布鲁克斯亚特兰大的联合创始人在 TEDxSydney 演讲

Drawing by @DynamicEcology
在某种程度上,它也许可以被视为一种感知你自己知识的方式。相信人们会通过你缺乏的知识来寻找,而不是看到与其他知识领域的联系。Mike Cannon-Brookes TEDx 演讲中的一条评论给我留下了特别深刻的印象:“编码一直在对我这样做。”

Drawing by software consultant David Whittaker
冒名顶替综合症最初被称为“冒名顶替现象”20 世纪 70 年代,心理学家波林·罗斯·克兰斯和苏珊娜·艾姆斯创造了术语“冒名顶替现象”。尽管有外部证据证明他们的能力,但与 Clance 交往过的学生似乎对被发现是骗子有一种不合理的担心。Clance 在当时写道:“这些女性没有体验到内在的成功感。他们认为自己是“冒牌货”。"
Caryn Farvour(Humphreys)2017 年在刊物 Code Like A Girl 上写了一篇关于 medium 的文章。在那里,她写道加州理工学院咨询中心将冒名顶替综合症定义为:
“即使面对表明相反情况的信息,这种不充分的感觉仍然存在。它在内心被体验为慢性自我怀疑,以及智力欺诈的感觉。”

谷歌已经认识到认可他人能力的重要性并表示:“我们都不愿意做出会对他人如何看待我们的能力、意识和积极性产生负面影响的行为。”的确,我们可能会意识到,人们会看穿我们缺乏的知识,当你尊重自己并非无所不知时,有可能获得更多,如果你接受这一点,你会变得有价值,或者可能会学到更多。**

Five keys to a successful Google team
人工智能领域的冒名顶替者
在连续 30 天每天都写关于人工智能的文章,每天都发表一篇文章之后,我仍然觉得自己像个骗子。也许有人会说一个月写很多,但是我的目标是 500 天内每天写一篇文章。每次我与业内专业人士或该领域的研究人员交谈时,我都觉得他们会责怪我不知道或试图“抓住我”。
有一种紧张感。也许特别是在一家风险投资公司发布了一份报告‘揭示’40%的人工智能初创公司没有使用人工智能之后。Verve上的一篇文章甚至声称:“MMC 的报告发现,当公司部署人工智能和机器学习时,用例往往非常平庸。”当该领域如此缺乏能力或经验时,这有什么好奇怪的?
这种指责文化或者什么是人工智能或者什么不是人工智能是可以理解的——我们在谈论大笔资金的投资。然而,这确实回避了一个问题,即初学者开始使用的基本算法是否是“真正的人工智能”。以这种方式,完美主义者很难向前迈出下一步。根据某些定义,声称程序员通过设计来追求完美主义是不公平的。
完美主义,在心理学上,是一种人格特质,其特征是一个人努力追求完美,并设定高的表现标准,伴随着批判性的自我评价和对他人评价的担忧。
如果你在一个开发团队中,有人写了一个可以运行的代码——它可以运行,而你的代码可能不行。即使是链接在一起的“块”中的小错误也会阻碍代码的运行。因此,自我批评式的评估是许多程序员日常工作中的一个常态。我做错了什么?为什么我的代码没有运行?这些问题有时可能需要几分钟、几小时、几周或几个月的时间来回答,具体取决于所面临的问题或挑战。然而,我们只是人类。

Graphics created by Chris Do
不管你愿不愿意,人们都会看穿你的面具。
Knatokie Ford 博士的另一个 TED 演讲引起了我的注意。Knatokie 是奥巴马政府白宫科技政策办公室(OSTP)的高级政策顾问,负责监督提高科学、技术、工程和数学的可见性和改善其形象的国家倡议的发展。
在谈到冒名顶替综合征的背景下,她还谈到了刻板印象威胁:害怕遵从对自己社会群体的刻板印象。她是班上唯一的非裔美国人,认为其他人会认为她很傻——她说这种组合导致了抑郁症。最终她决定她不能继续下去,所以她在一个学期后离开了哈佛。我想转贴一下她演讲中的一句话:
"攀比是快乐的小偷。"
—西奥多·罗斯福
为什么我们要把人工智能比作我们自己?
在我与研究人员和大多数业内人士的每次谈话中,都会出现一系列典型的话题。通常会提到人和机器的比较。人工智能的定义本身就有助于拟人化的类比;我们把自己与发达国家相比。我们以机器学习技术,叠加自己为标准。我强烈认为这是不健康的。

Illustration by Brianna Gilmartin, Verywell

Graph appeared in Raconteur August 22, 2016.
看看 2018 年 12 月经合组织最新报告中提到的数字也很有趣。从 2011 年到 2018 年年中,估计人工智能初创企业的投资总额超过 500 亿美元。可以说,巨大的投资带来了对财务回报的巨大期望。
如果人工智能的目标迅速变成超智能,我们可能会犯一个错误,特别是因为我交谈过的科学家之间有一个普遍的共识,即人工智能远远超出了这些能力(至少如果我们直接与人类相比)。此外,我认为考虑到所涉及的风险,这可能是一种破坏性的追求。也许这是未来的担忧或关注,但当前的关注是气候危机;全球严重不平等和战争风险。
一方面,我会主张不要把所有问题都变成简单的对立,但我可能会通过质疑研究人员、行业和国家的追求或目标来做到这一点。与我交谈的那些人脑海中的画面是索菲亚,一个在沙特阿拉伯获得公民身份的硬件和软件。

Sophia, a robot recenty granted citizenship in Saudi Arabia. Photo by Denis Balibouse/Reuters from Slate
我们为自己奋斗,为下一个人奋斗——我认为这是一个关于骗子综合症的讨论点。把我们自己比作一个技术应用程序,我们希望达到什么目的?是的,我们通过理解神经网络取得了进展,这导致了巨大的进步,特别是在认知机器学习方面,深度神经网络(DNN)被认为是一个飞跃。可以说,这标志着人工智能资金、开发、部署和商业用途的增加。
然而,如果我们谈论人工智能,就好像我们在谈论一个人或一种产品——从“它”的角度。这似乎很平常,虽然我不知道是什么程度,但阅读福布斯人工智能和大数据撰稿人小组最近的一篇文章很有意思:
请记住,现在还早,AI 在能够推理、独自解决复杂问题或学习到足以自行规划之前,还有很长的路要走。
–春天过得怎么样,福布斯【2019 年 4 月 29 日
人们偶尔会担心,知名人工智能科学家过于雄心勃勃或不切实际的承诺,或者商业供应商的过度承诺,可能会引发新的人工智能冬天。
我们应该把自己想象成数学方程式的完美智能吗?相反,让我们认识到迄今为止已经取得的巨大进步,以及人工智能领域通过应用机器学习技术来发现知识而取得的巨大进步;治病;监控气候;预测灾难;诸如此类。
让我们不要让人工智能成为冒名顶替者。
相反,让我们想想辛勤工作的开发人员、研究人员、商人和政治家的精神健康和幸福。
这是#500daysofAI 的第 32 天,请关注我关于 AI 的每日更新。
什么是#500daysofAI?
我在挑战自己,用#500daysofAI 写下并思考未来 500 天的人工智能话题。这是我发明的一个挑战,来保持对这个话题的思考,和大家分享我的话。
人工智能和技术生命周期
从新兴技术到广泛采用的道路
德克·克内梅尔和乔纳森·福利特

The printing press is critical technology underpinning modern civilization [Image: From Scientific American, Volume 24, Number 03 (January, 1871)]
像人一样,技术在其生命中也有不同的阶段。在光谱的一端,最终形成技术的想法就像是元素的前体——它们聚集在一起,只有以正确的方式连接起来,才会发生反应。在光谱的另一端是死技术——如拨号调制解调器、8 轨磁带和显像管电视。即使仍有这样的例子,它们也已经被其他技术淘汰了。他们有过他们的时间,也达到了他们的目的,现在,实际上,他们已经一去不复返了。技术生命周期在这两极之间移动——从创造到早期采用,到成长,到成熟,再到最终衰落。
技术生命周期的一个阶段是“新兴”,正如流行的短语“新兴技术”所反映的那样。这是一项技术存在并具有明显潜力的点,但尚未完全开发,最终可能产生从微不足道到典型的影响。但是,在这个崭露头角的时刻,技术很重要。它是将共同驱动我们未来的技术网络的一部分。所有的技术都曾一度出现。电、印刷机、轮子,曾经出现过,现在它们是支撑我们现代文明的改变世界的技术的一部分。
那么,人工智能在这个技术生命周期连续体中处于什么位置?它会走向广泛的应用和采用——21 世纪的电力——还是会退居次要地位?虽然前一个选项似乎最有可能,而后者几乎不可想象,但鉴于今天的技术环境,我们可以想象的人工智能的影响与实际可能和可能的影响之间仍然存在明显的矛盾。虽然人工智能的流行想法往往是不切实际的,但其中一些是基于现实的,比如说,人工智能在战略游戏中击败人类的能力。在过去的三年里,自从人工智能驱动的 AlphaGo 击败顶级围棋选手 Lee Sedol 以来,软件已经迅速而无情地击败了顶级人类对手。大约一年后, Libratus 击败了职业扑克玩家,紧接着 OpenAI 在电脑策略游戏 Dota 2 中击败了第一个对手,然后是一队人类对手。这些进步的成就来得很快,而且每一个都使用了完全不同的软件,这就是它们不同凡响的地方。早在 1997 年,“深蓝”第一次击败国际象棋世界冠军加里·卡斯帕罗夫,“深蓝”使用的技术与现在使用的大不相同。从在国际象棋中击败顶级人类到在围棋中击败顶级人类,花了将近 20 年的时间。但自 2016 年以来,随着每年下一个最复杂的游戏被击败,闸门打开了。

Figure 01 — In strategy games like Chess, AI has proven to be a formidable opponent for humans
[Photo: Chess by Felix Mittermeier on Unsplash]
这些成功是引人注目的。我们热爱我们的游戏,我们热爱竞争。直到最近,人们还认为计算机永远不会在围棋上打败人类。但现在他们做到了。扑克是一种虚张声势、解读对手和复杂下注动态的游戏,许多人认为机器需要很长时间才能赢。但是他们已经做到了。像 Dota 2 这样的游戏,需要复杂的团队合作和人与人之间的协调,与国际象棋和围棋专业人士的暴力碾压相比,似乎是一个完全不同的挑战。但是现在,Dota 2 也解决了。
但游戏只是开始。随着这十年的进展,我们喜欢引人入胜的科幻电影,如《T0》、《她》、《T1》和《T2》、《前玛奇纳》、《T3》,它们仿佛一瞥未来。它们不仅看起来像我们今天的世界——有感知能力的人工生命偶尔出现——而且它们与主流媒体对人工智能的大肆宣传不谋而合,即使该技术正在击败专业游戏玩家,自动驾驶汽车等神奇技术正在悄然出现。所有这些虚张声势和大惊小怪结合起来,形成了一个不负责任的不准确的人工智能叙事。尽管人工智能在赢得比赛方面取得了成功,但它远没有给我们带来有感知能力的生物。如果这种事情真的发生,那也是几十年后的事了。人工智能的现实是有趣和令人兴奋的,但与我们的想象力和无知的结合所认为的可能几乎没有相似之处。
从繁荣到萧条?
为什么想象和实际能力之间的这种紧张关系对人工智能作为一种技术的生命周期很重要?从历史上看,人工智能遵循一个周期,在这个周期中,进步和兴奋的爆发导致投资和关注的流动,然后是退潮,缺乏额外的成功使人工智能再次淡出背景。这些下降期被称为“人工智能冬季”。今天,随着对人工智能的大肆宣传——其中许多是与现实脱节的科幻垃圾——专家们有理由怀疑另一个人工智能冬天是否会在未来几年到来。AI 会被广泛采用还是会退去?
我们就人工智能的生命周期与意大利设计集团的执行数字总监莱安德罗·阿格罗进行了交谈。Agro 的职业生涯一直处于风口浪尖,在市场赶上之前几年甚至几十年就用新兴技术制造产品。他认为另一个人工智能的冬天不会很快到来,他的解释让人们对人工智能今天的总体状态有了一些了解:
“在这种时刻,最自然的事情可能是感知未来的另一个冬天。让我说说为什么我认为这一季会有所不同。首先,我们有更好的算法,它们开始进化自己,有时以一种非常不可预测的方式进化。…机器正在帮助人类更好地创造算法。”AI 在补充自身的发展。“这一季可能不同的第二个原因是,”Agro 说。“是因为这次我们有大量的数据。这是我们第一次拥有大量数据。”

Figure 02 — This time we have tons of data
[Photo: Light Trail by Maxime Valcarce on Unsplash]
鸢·博塞德是一位主要的机器学习工程师、思想领袖和作家,他曾与出版巨头奥莱利和皮尔逊合作,他对这种惊人的数据流入有如下看法。“人们在亚马逊上购物,在网飞和 YouTube 上观看流媒体,……人们在推特、脸书、LinkedIn 上购物,你知道,你能想到的都有。所有这些行为,所有这些用户,他们都在生成海量数据…而这实际上正在以 zettabytes 的数量级增长。”
“当你有了所有这些数据,你就有了这些巨大的科技巨头,你就有能力改善客户体验。你有足够的动力去创造像 Alexa 这样的东西,去创造谷歌助手,用推荐系统更好地瞄准受众。亚马逊推荐购物,网飞推荐电影。”“如今,人工智能和深度学习的扩散和普及有着真正强大的金钱激励,”Bosede 说。很简单,人工智能的消费化——在如此多受欢迎的服务的表面之下——正在推动越来越多的投资。Agro 同意这一观点,认为未来的人工智能解决方案是具体的和数据驱动的:“也许我们不会拥有……通用人工智能,但(我们)可能会拯救生命,可能会改变我们生产商品的方式,可能会减轻气候变化带来的伤害。”
一个关键的过渡期
如果我们认为人工智能正在其生命周期内从一种新兴技术快速进入可能被广泛采用的下一个阶段,这是一个重要的,甚至是关键的过渡期。“我认为这是人工智能从业者或创造性工作者必须非常适应的事情,从本质上讲,他们正在建造的东西将如何影响世界,”Bosede 说。“因此,不仅仅是洗手不干他们建造的任何东西,而是真正意识到预期的影响。”
“显然,我们不能成为神谕。我们无法预测未来。我们可以试试,”Bosede 说。“我认为对创造性工作者、工程师、科学家、研究人员、企业家以及任何在人工智能领域工作的人来说,最大的影响之一是建立一种意识,即我们如何思考我们制造的工具可能被用于最坏的情况。”
“举个例子,脸书在缅甸被用来进行种族清洗。这个平台被用来传播仇恨和暴力。这是脸书意想不到的后果,”博塞德说。“虽然,我敢肯定,他们从来没有想过,在他们最疯狂的想象中,一个连接人们的社交媒体平台会被用来断开人们的联系,但这就是发生的事情。有创造力的专业人士需要能够承担一些责任,并且能够意识到他们也有责任。这不仅仅是他们可以推翻监管者或决策者的事情。他们正在制造这些人工智能产品,因此他们必须以一种能够减轻或最小化负面影响的方式来制造这些产品。”
未来还没有到来,但肯定已经很近了。此外,随着人工智能作为一项技术日益成熟,并与我们的生活更加紧密地联系在一起,如果我们能够让它不仅仅适用于特权精英,它将被证明是革命性的。
Creative Next 是一个播客,探索人工智能驱动的自动化对创意工作者,如作家、研究人员、艺术家、设计师、工程师和企业家的生活的影响。本文伴随 第一季第二集—了解人工智能 和 第一季第三集— Smartware 和新兴技术。
艾与“无用”阶层
在人工智能之前,人类机器人会取代你的工作。人类机器人就是你,明天你就帮 AI 抢饭碗。会不会变得“没用”?

Photo by Alex Iby on Unsplash
人工智能(AI)会不会产生一个对社会没有提供价值的“无用”阶层的人?Yuval Noah Harari 在他的书 德乌斯人 中以及在演讲“人类的未来中警告了这种可能性哈拉里解释说,过去的倡议以前需要大量的个人,如工业化和发动战争,才能正常运作,文明才能取得进步。然而,21 世纪的技术可能会削弱和消除对个人的需求。可以完全取代人类需求的人工智能技术的例子包括自动驾驶汽车和无人机、面部识别和 x 射线图像分析。
这是一个深刻的思想实验,警告人类不加控制的人工智能扩散可能导致的一种可能性。哈拉里强调,这不是一个预言,相反,这只是一个可能的结果,随着技术的发展,人类可以影响我们今天和未来的选择。
关于人工智能的未来场景,未来学家和哲学家正在提出深思熟虑的预测、可能性和愿景,从反乌托邦到乌托邦。在天平的一端,反乌托邦场景通常包括奴役或消灭人类的“终结者”机器起义的变体,或者超高效和坚定不移的“回形针最大化器 AI ”它决心分配太阳系的所有物质和能量,以最大限度地增加回形针的产量。在乌托邦的一端,有一个仁慈的人工智能,它使用技术来解决人类的所有问题,因此人类不再需要工作,可以自由地追求高级认知。
对于这些场景中的许多场景,对人类的影响在奇点事件后生效,在这一点上,人工智能以指数速度实现递归自我改进。这导致了寒武纪人工智能的大爆发,当通过反乌托邦的视角来看时,它让智人(现代人类)的智能一夜之间过时。
强大的人工智能的崛起将是人类有史以来最好或最糟糕的事情。我们不知道是哪一个。”——斯蒂芬·霍金教授
艾 vs
认识到整个行业的术语和“人工智能”的含义可能会有所不同,本文作者选择采用马克斯·泰格马克的定义(在他的书 Life 3.0:成为人工智能时代的人类 中定义)来促进下面的讨论。希望这将减轻任何困惑。因此,“AGI”将被用来指启动由奇点事件描述的递归爆炸的“人工智能”水平。
智力: 完成复杂目标的能力
AI: 非生物智能
意识: 主观经验
人类级人工通用智能(AGI): 完成任何通用认知任务的能力至少和人类一样好
关于狭义智能、广义智能、广义智能、人类级 AI、强 AI 的定义,请参考 Tegmark 的书,了解定义的平衡。这里省略了它们,因为为了讨论的目的,只需要上述内容。
定义人生
继续参考泰格马克的书,他将生活定义如下,并将其分为三个阶段:
生命: 一个能保留其复杂性并能复制的过程。复制的是信息,以字节的形式排列,说明事情是如何安排的。生命是一个自我复制的信息处理系统。信息(软件)决定其行为和硬件蓝图。
生命 1.0: 生命(通过自然选择)进化出它的软件和硬件(生物阶段,细菌)
生命 2.0: 生命设计(通过学习)它的软件,并继续进化(通过自然选择)它的硬件(文化阶段,人类)
Life 3.0:Life 既设计软件又设计硬件(技术阶段)
比较泰格马克对生命的定义和哈拉里在《德乌斯人》中的陈述,可以对时代精神有一个大致的了解:
科学正在向一个包罗万象的教条靠拢,即有机体是算法,生命是数据处理-尤瓦尔·诺亚·哈拉里
深入研究后,哈拉里提出了令人信服的主张,即智能既独立于基底、生物(人类)或硅(人工智能或 AGI),也与意识脱钩。他提供了一个详细的讨论,说明了人类(人类学)定义的智能只不过是人脑中亚原子粒子的有组织的、生物排列。他继续解释说,没有什么可以阻止(也就是说,不违反已知的自然法则)这些相同的亚原子粒子以一种有组织的、硅排列重新排列,从而产生一种非生物智能。
意识
回想一下,意识早先被定义为一种主观体验,但是从生理学上讲,这种体验是如何表现出来的呢?什么是自由意志,是什么造就了你,你?准确地说,人类意识位于人脑的什么地方,它是如何运作的?这些都是难以想象的难题,科学界还没有找到答案。由于这个原因,当意识进入 AI 对话时,当试图辨别意识对智力的作用和/或影响时,事情会变得复杂。因此,意识是一个复杂的问题,它带来了各种各样的争论和理论,这些争论和理论可以很快转移智力的要点。
哈拉里详细阐述了意识,并提供了一个雄辩的漏洞来避免前面提到的分心。他的结论是“意识正在与智力脱钩。”因此,人们可以在不考虑意识的情况下审问智力。回想泰格马克的定义,智力是“完成复杂目标的能力。”例如,如果复杂的目标是执行面部识别或从 x 射线图像中识别肿瘤,人工智能正以越来越高的准确率成功完成这些复杂的任务。因此证明智力不需要意识。因此,读者可以放心,意识并没有被完全忽视。相反,这并不是讨论智力的先决条件,因此,与意识相关的话题可以在一个单独的平行讨论中继续。
“无用”类思想实验
当我们接受这样的概念,即我们所知的智能生命只是数据处理,智能可以通过以一种基底不可知的方式组织亚原子粒子来实现时,我们得到了这样一种可能性,即如果有足够的资源(知识、劳动力、资金、时间),创造 AGI 既是可行的,也是合理的。在这种情况下,哈拉里的思想实验开始成形,可以看出一个“无用”的阶层会如何产生。曾经需要大量个人在全球经济中动员和推动生产力增长的文明,将转向更高水平的智能(AGI),这种智能具有更低的单位成本,能够快速扩展,并且不需要个人。
与 AGI 相比,人类在软件和硬件上都处于劣势。人类要等九个月才能出生;然后用接下来的二十年来成长、发展和学习;在完全融入劳动力市场之前,还需要额外的 4 到 10 年来获得更高的学位。相比之下,AGI 可以快速设计和创建自己的按需软件(实例)和硬件(如 3D 打印机),这需要几个小时或几天才能执行,使人类几十年的速度相形见绌。这根本不是一个公平的竞争环境。
历史上,技术进步一直受到人类的欢迎,因为它总是遵循相同的工业革命公式:
新技术的引入取代了人类以前执行的“机械”活动,因此,人类从机械任务(如劳动)中解放出来,去追求更高层次的认知过程,这是技术无法竞争执行的,因为它缺乏人类水平的智能。
在第一次工业革命(18 世纪和 19 世纪),机械化生产方法和蒸汽机(新技术)使农业社会实现了工业化和城市化。以前,农业社会生活在小村庄社区,用手(机械任务)执行任务,如耕作和制衣。机器在执行这些机械任务时效率更高,人类开始从事其他需要智力的任务。
第二次工业革命(19 世纪末 20 世纪初)的特点是大规模生产(通过装配线)和电的发明(新技术)。这开启了人类追求的新技术进步,而机器继续执行机械劳动。最近,第三次工业革命(20 世纪中期至今)正在由自动化、电子和信息(新技术)驱动。正如我们在以前的革命中所看到的那样,人类将任务转移给了机器(或计算机),因为人类再次转移到了他们今天拥有的机器无法完成的工作上。可以说,第三次工业革命期间卸载的任务仍然是“机械的”,这将在下面进一步探讨。
为什么这次不一样
哈拉里等行业专家提出的思想实验是,随着我们向第四次工业革命过渡,以前的工业革命公式将不再适用。具体来说,工业革命公式只适用于人类能够“…追求更高层次的认知过程,而这是技术无法竞争的,因为它缺乏人类水平的智能。”* 然而,在 AGI 作为新技术被引入后,以前的条件不再成立,因为 AGI 将使现代人类水平的智能过时(参见上面的奇点事件)。AGI 将永远比人类领先好几步,因为它在设计软件和硬件方面都有超强的能力。当每一个人被替换,他们将过渡到数量不断增长的“无用”阶层。*
创造一个找不到工作的“无用”阶层意味着他们无法维持或提高自己的生活水平。由于发达经济体的大部分国内生产总值(GDP)是由消费者消费驱动的,这可能对全球经济产生灾难性影响。AGI 的所有者将集中在少数技术寡头手中,继续巩固他们的权力和财富,这将加剧我们今天看到的经济不平等。当分析前 1%富人的消费习惯时,人们注意到,富人的消费速度无法弥补普通消费者阶层支出的下降。因此,未来技术寡头的支出可能不足以弥补“无用”消费者阶层的衰落。这也使未来的税收收入面临风险,因为用一个机器人取代一个支付工资所得税的工人,这个机器人不纳税,可以作为资本支出贬值,以减少公司的应税收入,这将导致政府税收收入的净减少。
出于这些原因,这就是为什么我们开始看到通用基本收入(UBI)的提案(这里和这里)和试点项目(这里和这里)以及机器人税收计划,如微软创始人比尔盖茨提出的 one 。在高层次上,UBI 背后的理由是工作将被机器取代,政府需要为其公民提供支持,这是系统性的不可避免的。UBI 反驳的论点质疑了许多有效的观点,如资金的可行性和对资金使用的担忧,以及它是否会抑制劳动力市场的参与。机器人税背后的概念很简单,这是一种税收中性策略,对机器人征税,就像它是一个赚取工资并缴纳所得税的人类工人一样。评估 UBI 和机器人税收计划的意识形态和可行性不是一件小事,也不是本次谈话的主题。其目的是提高人们对当前举措的认识,这些举措试图 1)超越机器带来的永久性就业机会,2)支持未来潜在的“无用”阶层。
人类机器人悖论
今天,很多对话都集中在未来,以及它是如何从人工智能稳步接管人类今天执行的离散任务开始的。最终,让位给 AGI 爆炸,让机器完全取代人类,并且没有未来的就业选择。布莱恩·克里斯蒂安在他的《最人性化的人 一书中敏锐地指出,在由人类完成的工作变得自动化的过程中,有一个关键的中间阶段:这是人类“机械地”完成工作的阶段克里斯蒂安解释说,是的,一个机器人将做你的工作,但这个机器人就是你。
Christian 提请注意这样一个事实,即今天,人类正在完善我们的工作流程和程序,以便工作任务可以用一种逻辑和“机械”的方法来完成。在效率和生产率提高的面纱下,人类正在产生“标准化”产出所需的工作流程和步骤。这意味着一个人可以与另一个人交换,而不会影响输出质量。这假设新人类有足够的智力,能够遵循工作任务的“机械”程序。
在这一点上,可以注意到人类实际上是“机械地”执行工作任务的机器人。有多少次有人说,“我觉得我是一个工作中的机器人。”或者“我正在像机器人一样执行这项任务。”?今天,人类正在机械地转换他们的工作,这样他们就可以由一个不依赖基底的智能来完成。简而言之,今天的人类正在为生物智能(人类)被硅智能(机器)取代奠定基础。看来真正的问题不是机器人有一天会取代我们的工作。相反,这一过程已经开始,人类在不知不觉中带头冲锋。当进一步考虑这种可能性时,我留给读者几个有趣的问题来思考:
人类通过将工作转移到机械行为,是否串通一气让自己被机器取代(人工智能,AGI)并成为一个“无用”的阶级?
如果智力是底物不可知的,那么一类“无用”的人是不可避免的吗?
今天可以做些什么来避免“无用”的课堂结果?
如果出现“无用”的班级,可以做些什么来应对,像 UBI 和/或机器人税这样的策略是解决问题的正确方式吗?
有没有更高层次的认知,智人能做到,而 AGI 做不到?如果有,它们是什么?
对主观体验(意识)的追求和发展会为人类打开新的可能性之门吗?这种可能性如此丰富,以至于人类欢迎由一个 AGI 来执行我们过去的智能任务?
为了避免反乌托邦的结果,我们今天做了什么来确保 AGI 的目标不会与人类的目标相冲突?(参考马克斯·泰格马克(Max Tegmark)的书,了解他领导的帮助解决这个问题的倡议。)
让任何形式的智能(生物的或硅的)服从并利用它们来无条件地为人类的目标服务,这道德吗?
如果人类成功地将所有的生产手段和方法移交给 AGI,那么这种智慧会发展出自己的需求吗?如果这些需求得不到满足,AGI“劳工”罢工或反抗在全球范围内会是什么样子,人类将如何应对?
更新:作者发表了一篇名为“ AI(自动)完全控制人类 ”的文章,与本文讨论的主题有关。
艾和我们——一场歌剧体验
EKHO 集体:超越系列的歌剧
在我之前的帖子中,我详细描述了我们 Ekho Collective 如何开始我们的项目,为芬兰国家歌剧院和芭蕾舞团打造身临其境的歌剧体验。在这篇文章中,我将讨论是什么激发了我们为未来的访问者编造的故事。

An excerpt from our storyboard
双曲线期货
在媒体中,人工智能经常被视为两种夸张。在想象的乌托邦中,人工智能将治愈癌症,将我们从气候灾难中拯救出来。在反乌托邦中,人工智能被描绘成一个超级大国——在一个新建立的社会中篡夺控制权并强迫人类成为下属,摧毁所有人道的东西。我们的集体故事体现了这些刻板印象:在斯派克·琼斯的电影 Her 中,主角找到了与人工智能代理人的理想主义爱情(尽管,这种爱情是短暂的);在电影《我与机器人》(根据科幻作家艾萨克·阿西莫夫的著名故事改编)中,不会说话的机器人不懂得珍惜人类生命。
找到这两个双曲线未来之间的对话是我们希望我们的经历的访问者将探索的故事的关键。我们作品中的人工智能将跟随过去的歌剧明星,如莎乐美和卡门。莱拉——一个利用人工智能建立在新访客留下的数据上的体验领域——将通过建立在人类的痕迹上来反映人类的本质。这种体验将允许游客以有形和可理解的方式与人工智能互动。
我们如何看待人工智能——以及人工智能如何看待我们
探索我们如何看待人工智能的一部分是展示人工智能如何看待我们。人工智能对世界的看法有限,并根据有限数量的变量做出决定——这些变量并不总是代表人类社会的复杂性质。数据点也总是有限的,并且会以意想不到的方式受到环境的影响。当建立在有偏见的数据上时,人工智能可以反映出我们最糟糕的品质。例如,美国司法系统用来估计累犯率的算法被证明存在种族偏见。
最近出版的项目 ImageNet Roulette 是偏见的一个很好的例证,这是由研究员凯特·克劳福德和艺术家特雷弗·帕格伦共同完成的艺术项目。该网站接受了 ImageNet 的培训,ImageNet 是网上最受欢迎的开源图像识别数据库之一。它允许用户上传自己的图像,并查看网站的算法如何识别他们的图像。结果是不可接受的:记者朱莉娅·卡丽·王被贴上了种族歧视的标签,而一个黑皮肤男人的形象被贴上了罪犯的标签。



How AI sees us: results can vary according to environment and other variables, even with the same objects (ImageNet Roulette)
该算法所基于的数据来源是亚马逊的在线众包平台 mechanical Turk。Mechanical Turk 招募执行重复性任务的用户:标记图像、执行调查等。它经常被研究人员和开发人员用来寻找大量数据来构建他们的机器学习应用程序。在 mTurk 上可以买到的数据是由真实的人类生成的——基于通过它获得的数据建立的算法是我们的真实反映——最好的和最差的。
我们的倒影
像所有人类发明一样,人工智能也有好坏之分。我们建设的未来不仅取决于技术本身,还取决于我们做出的选择。在 Laila 中,我们希望强调这一思想,并为游客提供一个场所,让他们真正以物理形式与人工智能见面和互动。人工智能经常在机器学习的抽象概念中被提及——对于外行人来说仍然遥不可及。
通过提供一个与人工智能交互的界面,我们希望用户能够思考他们在这个新的存在领域中采取的行动如何影响人工智能的决策。正如哲学家马丁·海德格尔在他的文章中所写的,关于技术的问题:
因此,技术不仅仅是手段。科技是一种揭示。
商业人工智能应用的人工智能应用商店
想象一个拥有数百万人工智能应用的世界,这些应用可以让我们的工作变得更加简单,并利用人工智能的力量来真正改变世界。这可能是开始。

http://phpcantho.com/revolutionizing-everyday-products-with-artificial-intelligence/
我们拥有应用商店已经有一段时间了。通常我们访问它们来下载游戏、生产力工具、Whatsapp、Instagram 和类似的应用程序。
以下是我们在谷歌和苹果商店有多少应用程序的想法:

https://blog.appfigures.com/ios-developers-ship-less-apps-for-first-time/
我们有数以百万计的应用程序,但人工智能应用程序的应用商店呢?这是 DeepCognition 公司的人推出的一个有趣的新东西。
人工智能应用商店

AI AppStore 是一个为企业带来最佳人工智能应用的市场,没有任何争议。
AI AppStore 的方法非常简单。该计划是将人工智能的好处带给所有企业,而不必雇佣昂贵的工程团队或需要做大量的定制开发工作。
每个应用程序:
- 解决一个终端业务用例。
- 最终用户是否可以通过直观的 GUI 安装和使用(不需要 IT 团队)。
- 为客户提供用自己的数据训练 AI 的能力。
- 为高级商业用户/公司提供使用 API/插件将人工智能功能集成到其现有系统的能力。
在这里,您可以访问 AI 应用商店:
AI AppStore 是一个为企业带来最佳人工智能应用的市场,没有任何争议。我们与最佳人工智能合作…
deepcognition.ai](https://deepcognition.ai/ai-appstore/)
例如,他们的发票机器人使用人工智能来扫描发票,识别所有的数据字段,并自动将它们输入到您的会计软件中。它非常适合会计师、簿记员、公司会计部门和小型企业或合伙企业,并允许他们完全消除与发票相关的数据输入任务。
有趣的是,你可以开发自己的应用程序并放在那里,当人们购买或使用你的应用程序时,你就可以赚钱。他们开发了一个叫做文档应用软件开发工具包的东西。如果你是一名开发人员,那么你可以创建全新的应用程序并提交给他们。他们将对其进行评估,然后在 AppStore 上发布。这是 GitHub 回购:
通过在 GitHub 上创建帐户,为 DeepCognition/ai-apps-sdk 开发做出贡献。
github.com](https://github.com/DeepCognition/ai-apps-sdk/tree/master/document-ai-app)
在这里,您可以找到创建、开发和提交应用程序所需的所有信息。
我在想象一个有数百万人工智能应用的世界,在那里我们可以让我们的工作变得更加简单,并利用人工智能的力量来真正改变世界。
人工智能与建筑
实验视角
斯塔尼斯拉斯·夏洛 ,哈佛大学设计研究生院| 2019 年 2 月 24 日

GAN-Generated Masterplan | Source: Author
本文放出 我们的论文 的一部分,在哈佛开发,2019 年 5 月提交。这件作品是一个更大的作品的一个组成部分,调查艾在建筑中的开端,它的 历史背景 ,它的潜在空间 组织&风格 。
A 人工智能作为一门学科,已经渗透到无数领域,为以前未解决的挑战带来手段和方法,跨行业。AI 在建筑上的问世, 在上一篇文章中描述过 e ,仍处于早期阶段但提供了有希望的结果。这不仅仅是一个机会,这种潜力对我们来说代表了一个重大的进步,即将重塑建筑学科。
我们的工作旨在证明这一承诺在建筑环境中的应用。具体来说,我们提出将人工智能应用于平面图分析和生成。我们的最终目标是三重的: (1) 生成平面图,即优化大量且高度多样化的平面图设计的生成, (2) 鉴定平面图,即提供适当的分类方法 (3)允许用户通过生成的设计选项“浏览”。
我们的方法遵循两个主要的直觉 (1) 建筑平面图的创建是一个不小的技术挑战,尽管包含标准的优化技术, (2) 空间的设计是一个连续的过程,需要跨越不同尺度(城市尺度、建筑尺度、单位尺度)的连续设计步骤。然后,为了利用这两种现实,我们选择了嵌套式生成对抗性神经网络或 GANs。这种模型使我们能够捕捉遇到的平面图的更多复杂性,并通过连续步骤解决问题来分解复杂性。每一步都对应于一个给定的模型,专门为这个特定的任务而训练,这个过程最终可以证明人类和机器之间可能的来回。
计划确实是一个高维的问题,处于可量化技术和更多定性属性的十字路口。对建筑先例的研究通常仍然是一个危险的过程,它否定了现有资源的丰富性,同时缺乏分析的严密性。我们的方法受当前数据科学方法的启发,旨在验证平面图。通过创建 6 个指标,我们提出了一个框架,捕捉平面图的建筑相关参数。一方面,足迹形状、方向、厚度&纹理是捕捉给定平面图的风格的本质的三个度量。另一方面,计划、连接、和循环意在描绘任何平面图组织的本质。
简而言之,机器,曾经是我们铅笔的延伸,今天可以用来绘制建筑知识,并训练来帮助我们创造可行的设计方案。
一.框架
我们的工作处于建筑和人工智能的交汇点。前者是主题,后者是方法。两者都被简化为清晰的可操作类别。
建筑在这里被理解为风格和组织的交集。一方面,我们认为建筑是文化意义的载体,通过它们的几何形状、分类、类型和装饰来表达某种风格。巴洛克式、罗马式、哥特式、现代式、当代式:通过仔细研究建筑平面图可以发现尽可能多的建筑风格。另一方面,建筑是工程和科学的产物,符合严格的框架和规则——建筑规范、人体工程学、能源效率、出口、程序等——我们可以在阅读平面图时发现这些。这种组织上的必要性将完成我们对架构的定义,并推动我们的研究。

Framework Matrix | Source: Author
人工智能将被使用,使用它的两个主要调查领域——分析和生成对抗网络——作为调查工具。
首先,我们将进入代的话题。通过使用 GANs,我们可以将我们自己的人工智能系统应用于建筑设计。我们假设它的使用可以加强建筑学科的实践。这个领域是最近的,因为它是实验性的,并产生了令人惊讶的结果。我们希望能够训练它绘制实际的建筑平面图。
然后,我们将提出一个强大的分析框架,对生成的平面图进行鉴定和分类。最终,我们的目标是组织 GANs 的结果,为用户提供无缝浏览各种设计选项的可能性。为此,数据科学提供的工具的数量和普遍性将证明对我们的调查是有价值的。
通过这个双重镜头,在风格&组织,资格&生成的十字路口,我们奠定了一个框架,组织架构& AI 的遭遇。
二。产生
建筑平面图的设计是建筑实践的核心。它的精通是这门学科的黄金标准。这是一项实践,从业者一直不懈地试图通过技术来改进。在这第一部分中,我们深入探讨了人工智能应用于平面图生成的潜力,作为一种将信封推得更远的手段。
使用我们的框架,解决平面图的风格和组织,我们在下一章奠定了人工智能空间规划的潜力。我们的目标是提供一套可靠和健壮的工具来证明我们方法的潜力和测试我们的假设。
这里的挑战有三个: (1)选择正确的工具集、 (2)分离出正确的现象显示给机器和 (3)确保机器正确地“学习”。
人工智能与生成对立神经网络
生殖对抗性神经网络——或称GANs——是我们的首选武器。在人工智能领域,神经网络是一个关键的研究领域。这种模型的创造能力最近已经通过生成对抗性神经网络的出现得到了证明。与任何机器学习模型一样,GANs 从提供给它们的数据中学习具有统计意义的现象。然而,它们的结构代表了一个突破:由两个关键模型组成,发生器和鉴别器,GANs 利用两个模型之间的反馈回路来完善它们生成相关图像的能力。鉴别器被训练来从一组数据中识别图像。经过适当的训练,该模型能够区分从数据集中取出的真实示例,以及与数据集无关的“假图像。然而,生成器被训练来创建类似于来自相同数据集的图像的图像。当生成器创建图像时,鉴别器向他提供一些关于其输出质量的反馈。作为响应,发生器会进行调整,以产生更真实的图像。通过这种反馈循环,GAN 慢慢建立起创建相关合成图像的能力,将观察到的数据中发现的现象考虑在内。

Generative Adversarial Neural Network’s Architecture | Image Source
表现和学习
如果 GANs 对我们来说是一个巨大的机会,知道向他们展示什么是至关重要的。在这里,我们有机会让模型直接从平面图图像中学习。通过格式化图像,我们可以控制模型将要学习的信息类型。例如,只要向我们的模型显示一个地块的形状和相关的建筑物覆盖区,就会产生一个能够在给定地块形状的情况下创建典型建筑物覆盖区的模型。为了确保输出的质量,我们将使用我们自己的架构感来管理我们训练集的内容:作为架构师,一个模型的好坏取决于我们给他的数据。
下面,我们展示了一个典型的训练序列:这个序列是在一天半的训练过程中实现的,展示了我们的 GAN 模型如何逐步学习如何为一个住宅单元布置房间和开窗。


Training Sequence | Source: Author
虽然最初的尝试是不精确和混乱的,但在 250 次迭代之后,机器为自己建立了某种形式的直觉。
先例
如果说 GANs 在建筑设计上的应用还处于起步阶段,那么一些先例启发了我们的工作,并推动了我们的直觉。郑浩和黄卫新在 2018 年的 ACADIA 会议上发表了第一份出版物,展示了 GAN 在平面图识别和家具布局生成方面的潜力。他们的模型会根据房间程序和洞口位置,使用颜色块绘制房间填充物。同年,Nathan Peters 在哈佛 GSD 的论文中提出使用 GANs (pix2pix)解决单户模块化住宅中基于房屋足迹的程序再分配问题。
将甘斯视为设计助理,郑浩的(用机器人绘图:人机协作绘图实验,2018)和辜莞允·马丁内兹在 GSD 的论文(2017)启发了我们的研究。两位作者都提出了在机器和设计师之间建立一个循环的想法,以精炼“设计过程”的概念。
我们的工作扩展了这些先例,并提供嵌套 3 个模型(足迹、程序和装饰)来创建完整的“生成堆栈”,同时提高每个步骤的结果质量。通过自动化多单元处理,我们的工作可以扩展到整个建筑的生成和总体规划布局。我们还提供了一系列处理风格转换的模型。最后,我们的贡献添加了一个严格的框架来解析和分类结果输出,使用户能够一致地“浏览”生成的选项。
A.风格转移

Modern-to-Baroque Floor Plan Translation | Source: Author
在一个平面图中,通过研究其墙壁的几何形状和图形平面,可以观察到风格。典型的巴洛克式教堂会展示粗大的圆柱,带有多个圆形凹痕。密斯·凡·德·罗设计的现代别墅将展示薄而平的墙壁。墙面的这个锯齿是甘可以欣赏的一个特色。通过向它显示成对的图像,一个图像是平面图的分段版本,另一个是原始的墙壁结构,我们可以建立一定数量的关于建筑风格的机器直觉。
这部分展示了一个模型的结果,这个模型被训练来学习巴洛克风格。我们接着进行风格转换,其中给定的平面图是手动(A)重新装饰成新的墙壁风格 (B) 。**

Style Transfer Results: Apartment Units Modern-to-Baroque Style Transfer | Source: Author
B.布局助手

****Layout Assistant, a Step by Step Pipeline | Source: Author
在本节中,我们提供了一个多步骤的管道,集成了绘制平面图的所有必要步骤。它跨越不同的尺度,模拟建筑师所采取的过程,并试图将每个步骤封装到一个特定的模型中,训练该模型来执行给定的操作。从地块到建筑占地面积** (I) ,从占地面积到用墙分割的房间&开窗(II) ,从开窗平面图到带家具的平面图(III) : 每一步都经过精心设计、训练和测试。**

Generation Pipeline (Models I to III) | Source: Author
同时,通过将管道分成离散的步骤,系统允许用户在每个模型之间进行干预。通过选择一个模型的输出,并对其进行编辑,然后将其交给下一个模型,用户可以控制设计过程。它的输入塑造了模型做出的决策,从而实现了预期的人机交互。
1.脚印

Context | Parcel (input)| Generated Footprint (output), Source: Author
我们管道中的第一步解决了为给定的地块几何图形创建合适的建筑覆盖区的挑战。为了训练这个模型,我们使用了波士顿建筑足迹的广泛数据库,并能够创建一系列模型,每个模型都为特定的财产类型量身定制:商业、住宅、(房屋)、住宅(公寓)、工业等。
每个模型能够为给定的地块创建一组相关的足迹,在尺寸和风格上类似于它被训练的类型。下面是使用住宅(房屋)模型的 9 个示例。

Results: Generated Footprints (housing) | Source: Author
2.房间分隔和开窗

Footprint | Openings & Balcony (input) | Program & Fenestration (output) | Source: Author
下一步自然是在建筑范围内布置房间。能够分割给定的平面图,同时尊重有意义的相邻关系、典型的房间尺寸和适当的开窗是一个具有挑战性的过程,GANs 可以处理并带来令人惊讶的结果。
使用大约 700+个带注释的平面图的数据集,我们能够训练大量的模型。每一个都是针对一个特定的房间数,一旦用于空的建筑占地面积,就会产生惊人的相关结果。我们在下面展示了一些典型的结果。 更多结果也在这里。

Results: Generated Program & Fenestration | Source: Author
3.装备

Program (input, option 1) | Furniture Position (input, option 2)| Furnished Unit (output) | Source: Author
这最后一步将生成的原则带到了最精细的层面:在空间中添加家具。为此,我们首先训练了一个模型来一次性布置整个公寓。
该网络能够根据每个房间方案,了解家具在空间中的相对位置,以及每个元素的尺寸。结果显示如下。

Results: Furnished Units | Source: Author
如果这些结果可以给出潜在家具布局的粗略想法,那么最终绘图的质量仍然太模糊。为了进一步优化输出质量,我们已经为每种房间类型(客厅、卧室、厨房等)训练了一系列附加模型。每个模型只负责将添加到平面图上的颜色块转换成一个正确绘制的家具。家具类型使用颜色代码进行编码。我们在下面显示每个模型的结果。

Results of Room Furnishing Models | Bathroom / Kitchen / Livingroom / Bedroom | Source: Author
4.更进一步
如果使用我们的技术可以建造标准公寓,那么下一步自然是拓展我们模型的边界。事实上,GANs 可以提供相当大的灵活性来解决看似高度受限的问题。在平面布局的情况下,由于占地面积在尺寸和形状上的变化,手工划分和布置空间可能是一个具有挑战性的过程。事实证明,我们的模型在适应不断变化的约束的能力方面相当"聪明,如下所示。
**






GAN-enabled Space Layout under Morphing Footprint | Source: Author**
我们控制单元入口门窗位置的能力,加上我们模型的灵活性,使我们能够超越单个单元的逻辑,以更大的规模处理空间规划。在下面的例子中,我们将我们的技术扩展到整个建筑。







Experimental GAN-generated Masterplans | Source: Author
三。具有资格;合格;取得资格(或学历)
“不能给事物命名增加了世界的混乱”阿尔贝·加缪
为了平衡我们生成平面图的能力,找到合适的框架来组织、排序&对所生成的设计方案财富进行分类是非常重要的。我们提供的平面图只有在我们的生成选项数据库中导航的能力足够好。通过借用建筑中的概念,我们希望将常见的建筑形容词转化为可量化的指标。
为此,我们分离出 6 个关键指标,描述平面图设计的 6 个基本方面:占地面积、计划、方向、厚度&纹理、连通性和流通。

6 Metrics | Source: Author
这些指标作为一个全面的框架协同工作,解决了平面图的风格和组织方面的问题。每一个都被开发成一种算法,并且经过了彻底的测试。

A.脚印
建筑物的形状是鉴定其风格的最简单和最直观的代表。 "Footprint" 指标分析平面图周界的形状,并将其转换为直方图。
这个描述符在对建筑形状进行编码的同时,可以将建筑师使用的常见形容词——“瘦”、“笨重”、“对称”等翻译成数字信息,以便与计算机交流建筑形状。

Footprint Polar Diagram | Source: Author
从技术角度来看,该指标使用极坐标凸性将一个给定的轮廓转化为一系列离散值(向量),然后可以与其他平面图进行比较。我们使用从平面图的中心开始的线的极坐标阵列,来提取由所获得的每个空间切片所捕获的平面图的区域。这种方法已经被证明产生了令人满意的结果,如下面的查询所示。这种技术也可以用来限定室内空间的形状以及建筑周边的几何形状。


****
Typical Floor Plans Retrieval using the Footprint Metric (left: query, right: results) | Source: Author

B.程序
一栋建筑的项目,或者换句话说,它包含的房间类型,是其内部组织的主要驱动力。捕捉这一现实是我们方法的核心。为了描述房间的“组合”,我们通过颜色代码来表示任何给定平面图中包含的房间列表。这条彩色的带子就成了代理,用来描述程序。它作为一个模板,聚合平面图中房间的数量和规划质量。它对人类来说是一种直观的视觉描述,可以转化为一种可靠的机器编码技术。

Typical Floor Plans Retrieval using the Program Metric (left query, right results) | Source: Author
从技术的角度来看,通过使用这个色带,我们可以计算任何给定平面图对之间的程序相似性和差异性。为了可视化结果,每个平面图都报告为彩色平面图和其程序的一维颜色向量。




****
Typical Floor Plans Retrieval using the Program Metric (left: query, right: results, bottom: results’ program) | Source: Author

C.方向
平面图中墙壁的方向是一个有价值的信息来源。它可以描述围墙(由于墙的存在,空间变得多么隐蔽)和平面图的风格。事实上,使用这种度量标准,我们可以很容易地区分一个现代的房子-亭子和一个哥特式大教堂,简单地通过提取墙壁方向的直方图。

Orientation Diagrams | Source: Author
从技术角度来看,方向提取给定平面图的墙壁,并沿空间的每个方向对其长度求和,范围从 0 度到 360 度。产生的值列表是对计划总体方向的评估。可以对其进行平均以获得单个描述符,或者将其用作跨计划进行比较的向量。




****
Typical Floor Plans Analysis using the Orientation Metric (left: plan, right: orientation diagram) | Source: Author

D.厚度和质地
厚度&纹理**度量限定了平面图的“脂肪”:其壁厚和该厚度的变化。平面图上墙壁的厚度以及墙壁表面的几何形状纹理可能会因风格不同而有很大差异。当密斯·凡·德·罗的别墅展示薄的直线墙时,美术大厅将展示圆柱和锯齿状的厚墙,我们的度量将很容易掌握(见下图)。**

Thickness & Texture Diagrams | Source: Author
从技术角度来看,该指标隔离了给定平面图的所有墙壁,并输出墙壁厚度直方图。同时,该算法计算厚度的变化,以更好地描述壁纹理(即平墙对竖框)。




****
Typical Floor Plans Analysis using the Thickness & Texture Metric (left: plan, right: resulting diagrams) | Source: Author

E.连通性
****连通性指标解决了房间邻接的问题。房间之间的接近度是平面图的一个重要方面。此外,它们通过门和走廊的连接定义了它们之间连接的存在。连通性通过将它们视为一个标准图来调查这种连接的数量和质量。

Connectivity Diagram & Adjacency Matrix | Source: Author
从技术的角度来看,通过使用平面图上的开窗,我们可以推断出房间之间的关系图。连通性度量然后构建邻接矩阵,报告这些连接。最终生成一个图形表示。使用这个图表,我们可以比较平面图,考虑到房间之间连接的相似性。




****
Typical Floor Plans Analysis using the Connectivity Metric (left: connectivity graph, right: plan adjacencies) | Source: Author

F.流通
平面图中的循环捕捉了人们如何穿过它。通过提取循环的骨架,或者换句话说,循环网络的线框,我们可以量化和定性人们在平面图上的运动。

Circulation Diagram | Source: Author
从技术角度来看,循环提取给定平面图的循环骨架,并沿空间的每个方向对其长度求和,从 0 度到 360 度。生成的直方图是对循环网络几何形状的评估,可用于与其他平面图的循环进行比较。




****
Typical Floor Plans Analysis using the Circulation Metric (left: circulation graph, right: diagram) | Source: Author
四。映射和浏览

****Similarity graphs, Comparing One Plan to Many | Source: Author
回头看看我们的 GAN 模型,每个模型实际上都在我们这一代流水线的每一步输出了多个选项。然后邀请设计者"选择"一个首选选项,如有必要,在采取下一步行动之前修改它。然而,浏览生成的选项可能会令人沮丧且耗时。为此,“限定”一章中定义的指标集可以在此展示它们的全部潜力,并补充我们的世代管道。通过将它们用作过滤器,用户可以缩小选项范围,并在几秒钟内找到与其设计相关的选项。这种双重性生成过滤是我们工作的价值得到更多证明的地方:我们在这里提供了一个完整的框架,利用人工智能,同时保持在标准用户可及的范围内。
一旦根据给定的标准(足迹、程序、方向、厚度&纹理、连接性或循环)进行了过滤,我们就为用户提供了她/他的选择的树状表示。在中心是一个选定的选项,在其周围是根据用户选择的标准分类的最近邻。然后,用户可以缩小搜索范围,找到理想的设计选项,或者选择树中的另一个选项,重新计算图形。
(下面显示的每棵树都可以通过以下链接在线访问: 足迹 , 程序 , 连通性 )



Floor Plans Similarity Trees | Source: Author
动词 (verb 的缩写)结论
人工智能将很快在建筑师的日常实践中赋予他们巨大的权力。由于这种潜力即将被展示,我们的工作参与概念的证明,而我们的框架提供了讨论的跳板,邀请架构师开始与 AI 和数据科学家接触,将架构视为一个研究领域。然而,今天,我们的宣言可以归纳为四个要点。
首先从概念上来说,我们相信设计概念的统计方法塑造了人工智能在建筑方面的潜力。它的不确定性和整体性对我们的领域来说无疑是一个机会。不是使用机器来优化一组变量,而是依靠它们来提取重要的质量,并在整个设计过程中模仿它们,这是一种范式转变。
第二,我们深信,我们设计正确管道的能力将决定 AI 作为一种新的架构工具集的成功。正如 Andrew Witt 教授在《日志》中介绍的那样,我们选择的“灰箱”方法可能会获得最佳的潜在结果。这种方法与“黑盒”方法形成对比,黑盒方法只允许用户预先输入信息,并在过程结束时获得完成的设计选项,对后续的生成步骤没有任何控制。相反,通过将我们的管道分成离散的步骤,“灰箱”允许用户全程干预。他对机器的严密控制是他设计过程质量的最终保证。
****第三,从技术上来说,我们相信应用程序的顺序性将有助于其可管理性并促进其开发。在整个生成过程中进行干预的能力是一个基本的维度:由于管道的每一步都代表了建筑专业知识的一个独特部分,每个模型都可以独立训练,从而为不久的将来的重大改进和实验开辟了道路。事实上,端到端地改进整个管道可能是一项漫长而繁琐的任务,而逐步修改仍然是一个可管理的过程,是业内大多数建筑师和工程师都可以做到的。
最后,我们希望我们的框架将有助于解决待训练模型和任何一代管道中使用的模型的无限广度和复杂性。**处理包裹-足迹-房间分割-等等。我们相信,我们所做的是众多选择中的一种可能的方法。要概括空间规划的必要步骤,关键更多的是原则而不是方法。随着建筑数据可用性的增加,我们鼓励进一步的工作和开放的实验。
我们并不认为人工智能是建筑领域的新教条,而是认为这个领域是一个充满潜力和希望的新挑战。我们在这里看到了丰富结果的可能性,这将补充我们的实践,并解决我们学科的一些盲点。
数字资源

文献学
- ****超越计算机的数字建筑,罗伯托·博塔齐,布卢姆斯伯里
- ****数据驱动设计&构建,兰迪·多伊奇,威利
- ****建筑智能,设计师和建筑师如何创造数字景观,Molly Wright Steenson,麻省理工学院出版社
- 建筑谷歌**,超越网格——建筑&信息技术第 226–229 页,Ludger Hovestadt,Birkhauser
- 算法复杂性:凭空而来**,复杂性,设计策略&世界观第 75–86 页,安德里亚·格莱尼格&格奥尔格·弗拉赫利奥蒂斯,伯克豪斯
- 代码&机器**,代码,操作间&叙述第 41–53 页,Andrea Gleiniger&Georg Vrachliotis,Birkhauser
- 格罗皮乌斯的问题还是关于在建筑和艺术中揭示和隐藏代码**,代码,介于操作&叙述第 75–89 页,安德里亚·格莱尼格&格奥尔格·弗拉赫利奥蒂斯,伯克豪斯
- ****软架构机器,尼古拉斯·尼葛洛庞帝,麻省理工学院出版社。
- 《建筑机器》,尼古拉斯·尼葛洛庞帝,麻省理工学院出版社。
- ****一种模式语言,音符合成形式,克里斯多夫·亚历山大,链接
- 地图的变形;或者输入 RoweBot ,安德鲁·威特,日志#36
- ****灰拳击,安德鲁·威特,日志#43
- ****人类与人工智能中的暗示性绘画,辜莞允·马丁内兹,哈佛 GSD 论文,2016
- 启用替代架构:参与式设计的协作框架, Nathan Peters,哈佛 GSD 论文,2017 | 链接
- ****通过机器学习的建筑图纸识别与生成,郑浩(宾夕法尼亚大学),黄卫新(清华大学),ACADIA 2018 [ 论文 ]
- ****丹尼尔:自动分析和检索建筑平面图的深度架构,迪维娅·夏尔马,尼廷·古普塔,奇兰霍伊·查托帕迪亚,萨梅普·梅塔,2017,IBM 研究,IIT·焦特布尔
- ****建筑平面图中的自动房间检测和房间标记,Sheraz Ahmed,Marcus Liwicki,Markus Weber,Andreas Dengel,2012 年,凯泽斯劳滕大学
- ****利用空间索引自动解释平面图,哈南·萨梅特,阿雅·索费尔,1994 年,马里兰大学
- ****解析平面图图像,塞缪尔·道奇,久旭,比约恩·斯坦格,2016,亚利桑那州立大学,乐天理工学院
- ****项目探索:生成性设计在建筑空间规划中的应用,丹尼尔·纳吉,达蒙·刘,约翰·洛克,吉姆·斯托达特,洛伦佐·维拉吉,王雷,戴尔·赵和大卫·本杰明,2016,生活,欧特克工作室
- ****光栅转矢量:重访平面图转换,刘晨,吴家军,Pushmeet Kohli,川口恭誉古川,2017,华盛顿大学,深度思维,麻省理工学院
- ****图形文档视觉理解的关系模型。建筑制图应用,2014 年,巴塞罗那自治大学
- ****基于骨骼上下文的形状匹配与建模,谢军,heng-Ann Heng,Mubarak Shah,2007,中佛罗里达大学,香港中文大学
- ****平面图解释的统计分割和结构识别,Lluís-Pere de las Heras,Sheraz Ahmed,Marcus Liwicki,Ernest Valveny,Gemma Sánchez,2013,西班牙巴塞罗那计算机视觉中心
- ****结合使用统计和结构策略在平面图中进行无监督和独立于符号的墙壁分割,llus-Pere de las Heras、Ernest Valveny 和 Gemma Sanchez,2014 年,西班牙巴塞罗那计算机视觉中心
- ****使用生成式对抗网络支持智能移动应用的路径规划,Mohammadi,Mehdi,Ala Al-Fuqaha,和 Jun-Seok Oh。, 2018
- ****基于方形树形图算法自动实时生成平面图,Fernando Marson 和 Soraia Raupp Musse,2010 年,PUCRS
- ****建筑程序建模,帕斯卡·穆勒,彼得·旺卡,西蒙·海格勒,安德烈亚斯·乌尔默,吕克·范·古尔,2015,苏黎世联邦理工学院,亚利桑那州立大学
- ****建筑空间规划的生成式设计,Lorenzo Villaggi 和 Danil Nagy,2017,Autodesk Research
人工智能:军备竞赛 2.0

2 月 11 日,特朗普总统签署了一项行政命令,概述了美国人工智能倡议。除其他外,该命令讨论了美国保持其目前在人工智能领域领导地位的必要性。随后,国防部于 2 月 12 日发布了另一份公告,发布了其人工智能战略概要。
然而,人们可以说,美国的持续领导地位还远未确定:特别是,正如我们在“反思人工智能的现状:2018 ”中所讨论的那样,中国在人工智能初创公司的投资方面已经超过了美国,近 50%的人工智能投资美元流向了中国初创公司(就交易数量而言,美国仍然处于领先地位,尽管来自美国的人工智能初创公司的份额在过去几年中一直在稳步下降)。

Source: Top AI Trends To Watch In 2018
中国现在也在该领域的专利和出版物数量上挑战美国。诚然,其中一些出版物的质量可能仍然落后于美国,但中国已经迎头赶上,过去几年在该领域的进步速度简直令人震惊。
统治人工智能领域的愿望是完全可以理解的——毕竟,人工智能有一天将实现一个全新的可能性世界的想法已经存在了几十年。然而,直到最近,它在很大程度上被归入科幻小说的领域和少数研究人员&未来学家的作品。这一切都开始在 2010 年代初发生变化,当时技术以及或许同样重要的计算资源终于赶上来了,我们第一次拥有了能够解决现实世界问题的人工智能(或者更确切地说,机器学习)。
然而,正如任何改变游戏规则的进步通常会发生的那样,不同的国家发现自己在截然不同的环境中面临着人工智能提供的新机遇和挑战。
对于富裕的西方民主国家来说,机器智能的出现提供了探索新领域、建立新一代成功公司和进一步改善社会的机会。然而,这也意味着不得不面对人工智能可能给他们的公民带来的危险,如果不顾后果地应用的话。在过去的几年里,这意味着在制定人工智能政策时越来越优先考虑“无害”方法——与其他地方相比,西方强调个人主义和强大的人权记录,在人工智能方面失去的更多,得到的更少。虽然西方,更具体地说,美国可能仍然在人工智能研究方面处于领先地位,但考虑到它在道德和隐私问题上面临的不同水平的期望,实施将更加困难和更具挑战性。
相比之下,中国面临着完全不同的挑战:鉴于其历史背景和经济发展阶段,人工智能可能带来的机会往往大于滥用人工智能的危险,这反过来导致中国接受人工智能并实施积极的投资和部署战略。
这里还值得注意的是,随着广泛的人工智能部署,中国和西方可能会优化不同的结果。在中国,它通常会得到优化,为整个社会带来最好的结果,即使这意味着在这个过程中无意中伤害了少数群体。相反,西方注重人权和公平对待每一个人,包括任何局外人,这反过来为人工智能的采用带来了独特的挑战。
至于世界其他地区,今天大多数国家都处于西方和中国所代表的两个极端之间。
现在,让我们更深入地挖掘一些关键因素,这些因素将决定目前正在展开的全球人工智能军备竞赛的领导者。
基于我们上面所讨论的,我们建议将世界分成三大组:西方,中国和世界其他地区。显然,这样的划分相当主观,但我们相信它以一种有用的方式框定了围绕人工智能政策的对话。
现在,当想到任何可以使用机器学习解决的问题时,有三个构件需要考虑:数据、人员和资金。

Source: Evolution One
注:此处每种资源的数量是主观的,仅用于说明目的;我们将在下面的每一节中详细说明我们是如何做到这些的。
数据
过去几十年中,我们生成的数据量大幅增长,而且没有放缓的迹象,相反,在过去几年中,由于我们生成不断增长的信息量的能力,以及硬件和软件方面新数据来源数量的爆炸式增长,数据量一直在加速增长。

Source: The Digitization of the World From Edge to Core
根据 IDC 的数据,今天已经有超过 50 亿的消费者每天与数据进行交互,到 2025 年,这一数字将增加到 60 亿。尽管如此,虽然在 2010 年代初,智能手机是数据量增长的主要原因,但展望未来,这种增长将越来越多地由物联网设备驱动,预计到 2025 年,物联网设备每年将产生超过 90 吉字节的数据,占所有预测数据的 50%以上。
这里值得强调的一点是,设备数量和它们生成的数据量之间的关系从来都不是线性的,但如今,这一点变得尤其正确。虽然在 2000 年代末和 2010 年代初,智能手机的渗透率不断上升,加上传输和存储数据的成本不断下降,推动了数据量的产生,但在任何给定时间可以使用的智能手机数量都有明显的上限。然而,如今全球智能手机数量为 30 亿部,增长速度正在放缓,但数据量仍在快速增长。

Source: State of the IoT 2018
这里有两个关键因素在起作用。
首先,虽然智能手机增长在全球范围内放缓,但物联网代表了一个不同的故事。截至 2018 年,至少有70 亿台物联网设备(其他估计数字要高得多),预计到 2025 年将增长到 215 亿台,超过所有其他类别的总和。也许比设备的具体数量更重要的是,物联网设备的数量没有自然限制:很有可能想象世界上每个人都有几十甚至几百台设备,测量从道路上的交通到我们公寓的温度等一切(这甚至是在考虑企业使用的物联网设备之前)。
其次,现有数据的数量在很大程度上取决于我们收集、共享和存储数据的意愿和能力(无论是暂时的还是永久的)。在这里,我们围绕我们愿意收集和保留哪些类型的数据所做的选择变得至关重要——任何今天没有捕获的数据按照定义都会丢失,而且这种影响会随着时间的推移而加剧。
出于对人们隐私的担忧和防止潜在滥用,对数据收集施加限制可能是一件合理的事情,但在机器学习的狭义背景下,这些选择会影响可用于训练模型的数据量。这反过来意味着不太关心隐私的国家(中国是一个主要的例子——例如,看到它用人工智能驱动的安全摄像头捕捉罪犯的实验)可能会在数据方面获得优势。
话虽如此,认识到隐私问题并不适用于每一个问题也很重要,在一些领域(如无人驾驶汽车,或机器翻译——见一些有趣的专家意见这里)西方实际上有更好的数据集。
人
人是第二个重要的组成部分,因为是他们定义了用来解决任何可以通过机器学习解决的问题的方法。
在这里,情况与我们在数据中看到的有些相反——西方,尤其是美国,有着天然的优势,因为它仍然是最理想的工作和生活地点之一,因此更容易吸引来自世界各地的人们。它还可以对非正统的想法更加宽容,这提供了一个更具创造性的环境,并有助于发现和培养创新的想法。
在基础研究方面,美国历史上也有优势,这要归功于其成熟的研究型大学体系,更不用说它吸引世界各地顶尖人才的能力了。尽管如此,近年来,中国已经建立了一流研究型大学体系,并继续大力投资。今天,中国已经授予了比美国更多的自然科学和工程学博士学位,并在同行评审期刊上发表了更多的文章,根据经济学家的报道。此外,在特定于人工智能的研究中,美国的领先地位甚至更不确定,正如之前提到的那样(详见 CB Insights 报告)。
最后,当谈到专注于实施(而不是纯粹的研究)的从业者时,美国和中国都有一些独特的优势;评估这些的两个可能的指标是在每个国家成立的创业公司的数量,以及加入该领域的专业人士的数量。
美国拥有最多的初创公司,也有一个由谷歌、微软和脸书等大型科技公司投资的成熟生态系统。不过,中国在这方面排名第二(如果把欧洲作为一个整体来看的话,排名第三);此外,它获得了前所未有的高额投资(下一节将详细介绍),也是少数几家可以与美国最大的公司(即阿里巴巴、腾讯和百度)相媲美的公司的所在地。

Source: Artificial Intelligence — a strategy for European startups
然而,在劳动力方面,中国有明显的领先优势——今天,中国拥有 STEM 学位的大学毕业生比长期面临合格人才短缺的美国多 3 倍。与研究领域不同,在研究领域,少数人往往是最重要的,对于从业者来说,数字很重要,培养足够多的工程和科学专业人才对于建立和保持该领域的领先地位至关重要。
投资
根据 CB Insights 的数据,2017 年,对中国创业公司的投资占全球人工智能创业公司投资的 50%,高于 2016 年的 11.6%。毫不奇怪,2018 年资金最充足的前两家公司——商汤科技和 Face++都来自中国——我们已经在最近的文章中简要讨论了 2018 年的人工智能投资前景,并得出结论,中国在早期投资方面已经领先。
尽管如此,现在特朗普总统已经宣布了他的美国人工智能计划,我们觉得这可能是一个回过头来考虑这一宣布如何影响力量平衡的好时机。
然而,在我们这样做之前,让我们暂停一秒钟,通过漏斗来思考,这可以帮助分析投资策略的效率,并决定其最终的成败。

Source: Evolution One
以下三个步骤有助于组织讨论:
- 首先,考虑拟议投资的总体规模,以及在既定目标下,它是否足以实现有意义的变化
- 其次,考虑一下吸收资金的生态系统的效率和发达程度
- 最后,确定拟议战略的重点,以及它是否针对有可能产生最佳回报的正确领域(根据总体目标,这些领域本身会有所不同,例如,支持一个已经建立且发展良好的生态系统可能需要与从零开始建立基本机构时不同的战略)。
现在,应用这个框架来评估特朗普总统的人工智能战略,人们可以有把握地得出结论,鉴于它是如此模糊和通用,它并没有真正改变什么。这并不是说美国在投资方面落后于中国,相反,很明显,在可用资金数量、生态系统的稳健性以及关注多个领域的可用性方面,两国都处于同等有利的位置,这为发展带来了重大机遇。
结论
虽然今天许多人认为人工智能是一场新的军备竞赛,各国将相互激烈竞争(特朗普总统声明的语气对此没有帮助),但我们相信人工智能的合作会给所有人带来持续更好的结果。
有趣的是,西方特别有可能从促进全球合作中受益(比在孤岛世界中处于更好位置的西方国家受益更多),因为正是思考和创造的自由在历史上使美国这样的地方对世界各地的人才具有吸引力。
西方在人工智能领域取得可持续领导地位的途径可能依赖于:
- 专注于促进全球合作,包括来自中国等地的研究人员和公司
- 投资开发人工智能的道德使用框架,同时注意不要对私营企业的积极性施加不当限制
因此,西方政府的角色应该是帮助构建和引导讨论,而不是试图施加不必要的限制来扼杀创新。
AI 即服务?

Photo by @airamdatoon
数字基础设施和一切即服务
AaaS——当然不是最幸运的缩写。在这个时候,说你假设意味着你让你和我成为傻瓜是合适的。如果不是假设,还有什么是算法?一个数学上的假设,毫无疑问,它可以像人类的假设一样是对的和错的。现在有各种各样的“【T2 即服务】”缩写,有些甚至提出了 AI 即服务或 AIaaS 。
AaaS 代表算法即服务,是我在“作为服务”的词汇云中遇到的许多首字母缩略词之一。
一个算法是:在计算或其他解决问题的操作中要遵循的一个过程或一组规则,特别是由计算机来执行。它是一组指令,通常用于解决一类问题或执行计算。算法是执行计算、数据处理、自动推理和其他任务的明确规范。
以这种方式,它是一组假设。一个假设是:一件被认为是真的或者肯定会发生的事情,无需证明。承担权力或责任的行为。狭义人工智能是指人工智能,它只能处理一个特定的任务。因此,我们可以问有什么不同?2019 年 10 月 26 日 CMS Wire 上的一篇由 Kaya Ismail 撰写的文章试图解释算法和 AI 之间的区别:
算法是一组指令——一个预设的、严格的、编码的配方,当它遇到一个触发器时就会被执行。另一方面,人工智能是一个非常广泛的术语,涵盖了无数的人工智能专业和子集,是一组可以修改其算法并创建新算法的算法,以响应学习到的输入和数据,而不是仅仅依赖于它被设计为识别触发器的输入。
AaaS 和 SaaS 不一样吗?
你可能会说,ass,我的意思是 AaaS,类似于 SaaS(欢迎使用 heaven btw 的缩写)。软件即服务(SaaS) 是一种软件分发模式,由第三方提供商托管应用程序,并通过互联网提供给客户。SaaS 是云计算的三个主要类别之一,另外两个是基础设施即服务(IaaS)和平台即服务(PaaS)。缩略词超载?

AIaaS 或 MLaaS(机器学习即服务)有何不同?另一位为《走向数据科学》撰稿的作家 Oleksii Kharkovyna 在他的文章中说得很好,机器学习与传统编程:
在传统编程中你硬编码程序的行为。在机器学习中,你把很多事情留给机器从数据中学习。
因此,我们可以尝试区分 Saas 和 AIaas 或 MLaaS 的缩写。在人工智能(AI)领域,机器学习是最常见的技术。因此,使用 AIaas 或 MLaas 可能是一种有用的区分,但可能彼此过于接近,令人不舒服。
谷歌和亚马逊似乎几乎可以互换地谈论人工智能和机器学习产品(就像我经常在其他地方看到的那样)。他们目前拥有最大的 AIaas 或 MLaas 平台,因此让我们只看表面,不做全面的回顾)。以下内容根据各自网站略有调整。
Google AI Hub 和 TensorFlow
TensorFlow 是一个免费的开源软件库,用于数据流和一系列任务的差异化编程。它是一个符号数学库,也用于机器学习应用,如神经网络。它被用于谷歌的研究和生产。
谷歌另外还有几款人工智能和机器学习产品。
AI Hub ,一个即插即用的 AI 组件托管库。
AI 构建模块具有视觉、语言、对话和结构化数据的应用。
AI 平台,基于代码的数据科学开发环境,面向 ML 开发者和数据科学家。其中一部分是云机器学习引擎,这是一种托管服务,允许开发人员和数据科学家在生产中构建和运行机器学习模型。
亚马逊 SageMaker
Amazon SageMaker 使开发人员和数据科学家能够快速轻松地构建、训练和部署任何规模的机器学习模型。它消除了阻碍跨用例和行业成功实施机器学习的复杂性——从运行实时欺诈检测模型,到虚拟分析潜在药物的生物影响,再到预测棒球比赛中的盗垒成功。
从 TensorFlow、PyTorch、Apache MXNet 和其他流行的框架中进行选择,以试验和定制机器学习算法。你可以在亚马逊 SageMaker 中使用你选择的框架作为托管体验,或者使用 AWS 深度学习 AMIs(亚马逊机器映像),它完全配置了最流行的深度学习框架和工具的最新版本。根据亚马逊的说法:
- 云中 81%的深度学习项目运行在 AWS 上
- 云中 85%的 TensorFlow 项目运行在 AWS 上
从这个意义上说,亚马逊似乎声称自己是 MLaaS 或 AIaaS 中的平台的平台。
小演员能竞争吗?
当然,这一领域的专业产品总会有利基市场,我们可能会发现通过一项创新(新方法、想法、产品等)脱颖而出的演员。)或者技巧。
写这篇文章的过程始于我在 Craig E Ryder 关于 你需要了解的五家 AI 初创公司 的一篇精心撰写且简明扼要的文章中读到关于算法即服务的内容。在这篇文章中,我发现了引起我注意的 NextQuestion 和他们的算法即服务 (AaaS)(流行语的魔力)。如果你喜欢,可以去美国汽车协会看看。

Screenshot of NextQuestion website retrieved the 8th of July 2019
无论如何,感谢你收听#500daysofAI,再次声明:保持直立。
这是#500daysofAI 的第 36 天,请关注我关于 AI 的每日更新。
什么是#500daysofAI?
我在挑战自己,用#500daysofAI 写下并思考未来 500 天的人工智能话题。这是我发明的一个挑战,以保持对这个话题的思考,并与你分享我的更新。一起学习是最大的快乐。
人工智能自动生成 M&A 候选人
传统方法:X 公司希望在某个特定的技术领域进行扩张,并准备一份潜在收购候选人的名单。如何识别这些公司?人们如何对它们进行排序?有人雇了一位昂贵的投资银行家来准备候选名单。银行家喜欢买方委托。
新方法:租一台机器。
我承认 M&A 不仅仅是入围候选人名单,但是让我们一点一点地剥 M&A 洋葱,好吗?目标列表生成是一项关键活动,大多数企业集团都有一份活动列表,并为此花费数小时的 CXO 时间。
下面是机器如何提供帮助的——通过一个例子来说明……让我们以电动汽车行业为例。“最大的电动汽车制造商”(收购者)希望确定拥有最接近的匹配技术组合的公司(目标)进行购买。

A 2-dimensional representation of patent landscape
矢量化:获得 12571 项电动汽车专利(近期)。这涵盖了 1809 家公司(专利受让人)。机器对专利进行矢量化(见矢量图)。
在这个过程中,机器理解每个单词的意思(见插图:机器通过向量理解文本)。

解释:机器接下来会了解收购方拥有哪些领域的技术。下面是从电池组到扭矩控制到热充电等重点领域的图表。机器识别 8 个区域。

A 2-dimensional representation of focus areas in vector space
入围名单:对于每个领域,该机器将收购方的每项专利与潜在目标(1808 家公司)的每项专利进行映射,并根据我们对寻找最接近技术目标的定义,使用“相关性”/“接近度”指标来筛选候选人。下图为 8 个领域的 8 个图表,根据专利向量分析绘制了每个公司(1808)的情况。候选名单摆在我们面前。每个领域的候选名单。

我们将最接近的技术定义为标准……我们也可以将其定义为补充/最核心/最交叉连接等……一个指标的变化会改变候选名单。
收购型公司保持着一份活跃的目标清单。这台机器可以在几小时内重复这一分析。相比之下,通过一个采购过程来雇用一个银行家,以及与此相关的成本。
在“数字”时代,一切都越来越成为载体,我们是在剥洋葱,还是在用不同形式的智能拓展可能性的边界?

如果竞争对手 1 收购竞争对手 2…会发生什么,什么技术会消失… 1809 公司是一个网络,任何人都可以收购任何人…鉴于技术格局的潜在变化,我们今天应该收购某人吗?一个有机的技术研究项目是否应该变成无机的(收购)?我们如何对此建模?
现有的人类智能形式将很难模拟这种复杂性…机器可以…尽管是人工的。
人工智能驱动的印度车牌检测器。

灵感:撞了我的车还逍遥法外的家伙!
背景故事:在和朋友度过了一个难忘的夜晚后,当我们准备回家时,有一件事让那个夜晚更加难忘,我的汽车前保险杠上有一个巨大的凹痕,似乎是被另一辆车撞了,但这该怪谁呢?周围没有人会目睹那件事。我能做些什么呢?
我会告诉你我到底做了什么。
我利用我的机器学习和编程技能,决定制作一个基于人工智能的印度车牌检测器,它能够通过检测周围车辆的车牌来监视车辆,在这篇博客中,我将带你们了解我是如何做到这一点的!首先:总有即兴发挥的余地,所以如果你对这个项目有更好的想法或疑问,请使用下面的回复部分。
方法:
我们需要建立一个系统,能够-
- 从周围获取图像/视频(一系列图像):
在硬件端,我们需要一台 pc(或 raspberry pi)和一个摄像头,在软件端,我们需要一个库来捕获和处理数据(图像)。我在这个项目中使用了 OpenCV (4.1.0)和 Python (3.6.7)。 - 在图像中寻找车牌:
要从图像中检测一个物体(车牌),我们需要另一个工具来识别印度车牌,为此我使用了 Haar cascade,它是在印度车牌上预先训练的(将很快更新到 YOLO v3)。 - 对车牌进行分析和执行一些图像处理:
使用 OpenCV 的灰度、阈值、腐蚀、扩张、轮廓检测,并通过一些参数调整,我们可以很容易地生成足够多的关于车牌的信息,以决定这些数据是否足够有用,可以传递给进一步的处理(有时如果图像非常失真或不正确,我们可能只能得到假设的 10 个字符中的 8 个, 然后,没有必要将数据传递到管道中,而是忽略它并查看下一帧的板),此外,在将图像传递到下一个过程之前,我们需要确保它没有噪声并经过处理。 - 从车牌中分割出字母数字字符:
如果上述步骤一切正常,我们应该准备好从车牌中提取字符,这可以通过巧妙地对图像进行阈值处理、腐蚀、扩张和模糊来完成,这样最终我们得到的图像几乎没有噪声,并且易于进一步的功能处理。我们现在再次使用轮廓检测和一些参数调整来提取字符。 - 逐个考虑字符,识别字符,将结果串联起来并以字符串形式给出车牌号码:
现在有趣的部分来了!因为我们有所有的字符,所以我们需要将字符一个接一个地传递到我们训练好的模型中,它应该能够识别字符,瞧!我们将使用 Keras 作为我们的卷积神经网络模型。
先决条件:
- OpenCV : OpenCV 是一个编程函数库,主要针对实时计算机视觉,加上它的开源性,使用起来很有趣,也是我个人的最爱。这个项目我用的是 4.1.0 版本。
- Python :又名编码的瑞士军刀。我这里用的是 3.6.7 版本。
- IDE: 我将在这里使用 Jupyter。
- Haar cascade :这是一种机器学习对象检测算法,用于识别图像或视频中的对象,基于 Paul Viola 和 Michael Jones 在 2001 年的论文“使用简单特征的增强级联进行快速对象检测”中提出的特征概念。更多信息
- Keras:Keras 易于使用并得到广泛支持,它让深度学习变得尽可能简单。
- Scikit-Learn:It是一个免费的 Python 编程语言的软件机器学习库。
- 当然,不要忘记咖啡!
第一步
创建工作空间。
我推荐创建一个 conda 环境,因为它使项目管理更加容易。请按照此链接中的说明安装 miniconda。安装完成后,打开 cmd/terminal 并使用以下命令创建一个环境
>conda create -n 'name_of_the_environment' python=3.6.7
现在让我们激活环境:
>conda activate 'name_of_the_environment'
这应该让我们进入虚拟环境。是时候安装一些库了-
# installing OpenCV
>pip install opencv-python==4.1.0# Installing Keras
>pip install keras# Installing Jupyter
>pip install jupyter#Installing Scikit-Learn
>pip install scikit-learn
第二步
设置环境!
我们将从运行 jupyter notebook 开始,然后在我们的例子中导入必要的库 OpenCV、Keras 和 sklearn。
# in your conda environment run
>jupyter notebook
这将在默认的网络浏览器中打开 Jupyter 笔记本。一旦打开,让我们导入库
#importing openCV
>import cv2#importing numpy
>import numpy as np#importing pandas to read the CSV file containing our data
>import pandas as pd#importing keras and sub-libraries
>from keras.models import Sequential
>from keras.layers import Dense
>from keras.layers import Dropout
>from keras.layers import Flatten, MaxPool2D
>from keras.layers.convolutional import Conv2D
>from keras.layers.convolutional import MaxPooling2D
>from keras import backend as K
>from keras.utils import np_utils
>from sklearn.model_selection import train_test_split
第三步
号牌检测:
让我们简单地从导入一个带有牌照的汽车样本图像开始,并定义一些函数:
上述函数的工作方式是将图像作为输入,然后应用预先训练好的“haar cascade”来检测印度车牌,这里的参数 scaleFactor 代表一个值,通过该值可以缩放输入图像,以便更好地检测车牌(了解更多信息)。minNeighbors 只是一个减少误报的参数,如果这个值很低,算法可能更容易给出一个误识别的输出。(您可以从我的 github 个人资料中下载名为“indian_license_plate.xml”的 haar cascade 文件。)

input image

output image with detected plate highlighted

output image of detected license plate
第四步
对车牌进行一些图像处理。
现在让我们进一步处理这个图像,使字符提取过程变得容易。我们将从定义更多的函数开始。
上述函数接收图像作为输入,并对其执行以下操作-
- 将它调整到一个尺寸,这样所有的字符看起来都清晰明了
- 将彩色图像转换为灰度图像,即图像只有一个 8 位通道,取值范围为 0-255,0 对应黑色,255 对应白色,而不是 3 通道(BGR)。我们这样做是为下一个过程准备图像。
- 现在阈值函数将灰度图像转换为二进制图像,即每个像素现在将具有 0 或 1 的值,其中 0 对应于黑色,1 对应于白色。这是通过应用具有 0 到 255 之间的值的阈值来完成的,这里的值是 200,这意味着在灰度图像中,对于具有大于 200 的值的像素,在新的二进制图像中,该像素将被赋予值 1。并且对于值低于 200 的像素,在新的二进制图像中,该像素将被赋予值 0。
- 图像现在是二进制形式,为下一个腐蚀过程做准备。
侵蚀是一个简单的过程,用于从对象的边界移除不想要的像素,即值应该为 0 但却为 1 的像素。它的工作原理是逐个考虑图像中的每个像素,然后考虑像素的邻居(邻居的数量取决于内核大小),只有当它的所有邻居像素都是 1 时,该像素才被赋予值 1,否则被赋予值 0。 - 图像现在是干净的,没有边界噪声,我们现在将放大图像以填充缺少的像素,即应该具有值 1 但具有值 0 的像素。该函数的工作方式类似于侵蚀,但有一点不同,它的工作方式是逐个考虑图像中的每个像素,然后考虑像素的邻居(邻居的数量取决于内核大小),如果像素的至少一个相邻像素为 1,则该像素的值为 1。
- 下一步是将图像的边界变成白色。这是为了移除帧外的任何像素(如果它存在的话)。
- 接下来,我们定义一个包含 4 个值的维度列表,我们将用它来比较字符的维度,以筛选出所需的字符。
- 通过上面的过程,我们已经将我们的图像减少到一个处理过的二进制图像,并且我们已经准备好传递这个图像用于字符提取。
第五步
从车牌中分割出字母数字字符。
在第 4 步之后,我们应该有一个干净的二进制图像。在这一步中,我们将应用更多的图像处理来从牌照中提取单个字符。涉及的步骤将是-
- 找到输入图像中的所有轮廓。函数 cv2.findContours 返回它在图像中找到的所有轮廓。轮廓可以简单地解释为连接所有连续点(沿边界)的曲线,具有相同的颜色或强度。

https://www.oipapio.com/static-img/4698620190220123940948.jpg

plate with contours drawn in green
- 找到所有轮廓后,我们逐个考虑它们,并计算它们各自的边界矩形的尺寸。现在考虑边界矩形是可能包含轮廓的最小矩形。让我通过在这里为每个字符画出边界矩形来说明它们。

- *因为我们有了这些边界矩形的尺寸,所以我们需要做的就是做一些参数调整,并过滤出包含所需字符的所需矩形。为此,我们将通过只接受宽度在 0,(pic 的长度)/(字符数)和长度在(pic 的宽度)/2,4 (pic 的宽度)/5 范围内的那些矩形来执行一些维度比较。如果一切顺利,我们应该有所有的字符提取为二进制图像。

The binary images of 10 extracted characters.
- 字符可能是无序的,但不要担心,代码的最后几行会处理好这一点。它根据字符的边界矩形相对于盘子左边界的位置对字符进行排序。
第六步
创造一个机器学习模型,并为角色训练它。
- 数据都是干净的,准备好了,现在是时候创建一个足够智能的神经网络来识别训练后的字符。

https://mesin-belajar.blogspot.com/2016/05/topological-visualisation-of.html
- 为了建模,我们将使用具有 3 层的卷积神经网络。
## create model
>model = Sequential()
>model.add(Conv2D(filters=32, kernel_size=(5,5), input_shape=(28, 28, 1), activation='relu'))
>model.add(MaxPooling2D(pool_size=(2, 2)))
>model.add(Dropout(rate=0.4))
>model.add(Flatten())
>model.add(Dense(units=128, activation='relu'))
>model.add(Dense(units=36, activation='softmax'))

- 为了保持模型简单,我们将从创建一个顺序对象开始。
- 第一层将是具有 32 个输出滤波器、大小为(5,5)的卷积窗口和作为激活函数的‘Relu’的卷积层。
****
- 接下来,我们将添加一个窗口大小为(2,2)的 max-pooling 层。
Max pooling 是一个基于样本的离散化过程。目标是对输入表示(图像、隐藏层和输出矩阵等)进行下采样。),减少其维数,并允许对包含在被装仓的子区域中的特征进行假设。

max-pooling layer
- 现在,我们将增加一些辍学率,以照顾过度拟合。
Dropout 是一个正则化超参数,被初始化以防止神经网络过拟合。Dropout 是一种在训练过程中忽略随机选择的神经元的技术。他们是“掉** - 掉”随机产生的。我们选择了 0.4 的丢弃率,这意味着将保留 60%的节点。** - 现在是展平节点数据的时候了,所以我们添加了一个展平层。展平层从上一层获取数据,并在一维中表示它。

- 最后,我们将添加两个密集层,一个输出空间的维数为 128,激活函数='relu ',另一个,我们的最后一层有 36 个输出,用于对 26 个字母(A-Z) + 10 个数字(0–9)和激活函数=' softmax '进行分类

第七步
训练我们的 CNN 模型。
- 我们将使用的数据包含大小为 28x28 的字母(A-Z)和数字(0-9)的图像,并且数据是平衡的,因此我们不必在这里进行任何类型的数据调整。
- 我已经创建了一个 zip 文件,其中包含按照下面的目录结构的数据,训练测试分割为 80:20

-
我们将使用 keras 中可用的 ImageDataGenerator 类,使用宽度移动、高度移动等图像增强技术来生成更多的数据。要了解更多关于 ImageDataGenerator 的信息,请查看这篇不错的博客。
-
Width shift:接受一个浮点值,表示图像将向左和向右移动的百分比。
Height shift:接受一个浮点值,表示图像上下移动的比例。 -
现在该训练我们的模特了!
我们将使用“分类 _ 交叉熵”作为损失函数,“亚当”作为优化函数,“准确度”作为误差矩阵。 -
经过 23 个历元的训练,模型达到了 99.54%的准确率。
****
第八步
输出。
最后,是时候测试我们的模型了,还记得从车牌中提取字符的二值图像吗?让我们把图像输入到我们的模型中!

输出-

最终意见
感谢你们阅读这个博客,希望这个项目对那些有志于做 OCR、图像处理、机器学习、物联网项目的人有用。
如果你对这个项目有任何疑问,请在回复部分留下评论。
完整的项目可以在我的 Github 上找到:
https://Github . com/SarthakV7/AI-based-Indian-license-plate-detection
在 LinkedIn 上找到我:www.linkedin.com/in/sarthak-vajpayee
人工智能可以尊重你的隐私(如果人类愿意的话)
设计合理的人工智能如何捍卫我们的隐私。

Why AI can save our privacy
我们都知道(人类员工——不是人工智能……)谷歌、脸书、亚马逊和其他大型互联网公司从我们的数据中赚钱。在这些公司工作的人(不是 AI…)做出了商业决定,收集从“免费”服务中获得的数据,目的是转售这些信息来赚钱。
就连美国国会,在对马克·扎克伯格进行了几个小时的听证后,也开始理解硅谷是如何赚钱的。马克·扎克伯格因剑桥分析公司不正当地获取数百万脸书用户的个人数据而被传唤到华盛顿。
2018 年的那场听证会标志着我们数字化生活中一个决定性的关键时刻。两条战线发生了冲突:快速移动的互联网巨头收集和挖掘海量数据,以及静态、缓慢移动的政治和监管力量。这一切的核心是人工智能。
没有人愿意交出他们的数据,除非他们觉得他们的数字足迹受到了保护。这一愿望现在也得到了立法的支持。欧洲新的《通用数据保护条例》( GDPR)明确规定,除其他事项外,公司应限制并最大限度地减少其收集和保留的数据量,重点关注满足明确规定的业务目的所绝对必要的数据。公司只能在有限的时间内保留数据,用户可以要求删除他们的数据。我们预计这种保护的某些方面将迅速扩展到包括美国在内的其他国家
对于人工智能目前的构建和训练方式来说,这是一个大问题。从历史上看,人工智能系统并没有以有利于保护隐私的方式进行设计:它们需要保留所有数据,以便能够更新和改进。但幸运的是,这可以通过一种新的人工智能技术来克服,这种技术直接存在于用户的设备上,并在那里执行所有功能,而不需要保存用户的敏感信息。
传统上,包括脸书在内的各种服务的用户积累了各种类型的数据,但公司没有有效的方式来收集这些数据。进入 AI 算法:从数据中学习并从中提取意义的数据驱动的数学模型。这就像这些公司坐在巨大的油藏上,只有一个手铲,现在他们得到了一个强大的机械化钻机。他们正在钻探。

Conventional AI needs large servers
从 20 世纪 60 年代的理论工作发展而来,今天的深度学习和神经网络(DNN)算法——为研究界带来最大胜利的人工智能子领域——是大规模数学系统,通过以简单的方式模拟可以训练来执行任务的互联神经元的巨大网络,捕捉大脑功能和组织的各个方面。这
se 从视觉和听觉感知到运动控制和更抽象的功能,如捕捉服务器上的网络攻击;将财务数据分类为欺诈数据或合法数据;或者将一件设备分类为正常、有缺陷或生锈。
虽然输入数据和任务的性质各不相同,但这些系统的能力来自于从数据中学习的能力(而不是被预编程来执行功能),并且绝大多数情况下使用 20 世纪 80 年代形成的学习形式,称为“反向传播”
在反向传播方法中,一种从根本上背离人类和动物大脑工作方式的算法,大型神经网络中的神经元通过计算网络处理一批数据后每个神经元的误差贡献来改变它们的突触或连接系数。本质上,如果网络呈现一只“长颈鹿”并回答说,“我看到一只斑马”,数百万个神经元将根据它们对错误答案的贡献大小来改变数亿或数十亿个突触权重,使它们在下一次看到长颈鹿时,更有可能正确分类。
“反向传播”这个名称指的是这样一个事实,即网络的误差是在输出神经元上计算的,这些神经元对斑马和长颈鹿进行分类,并传播回网络中的所有神经元,这些神经元馈给这些输出神经元,一直到呈现输入图像的网络的第一个神经元。对错误答案做出贡献的神经元越多,其突触中的修正就越大。
虽然输入数据可以是图像、声音或其他更抽象的数据——如金融交易、网络流量或文本——但原理是相同的:该算法通过迭代调整每个神经元的权重来优化网络输出,对该数据完成数千次或数百万次的学习过程,直到误差小到足以称学习“完成”
这很棒,因为它使基于反向传播的人工智能系统能够在越来越多的任务中匹配甚至超越人类水平的表现,从下棋和围棋到理解交通标志和医疗数据。

How traditional AI works
然而,这种超级性能是有代价的:反向传播网络,因为它们倾向于根据当前的预测误差改变突触权重,所以对新信息非常敏感,容易受到灾难性的干扰:当学习到新的东西时,它会清除旧的信息。从某种意义上说,他们有一种学习障碍。
反向传播成为神经网络中事实上的标准学习算法,意想不到的后果是,今天整个庞大的人工智能行业都患有“记忆综合症”——正如受欢迎的电影所描述的那样,他们的人工智能只有在投入使用前才训练有素,在日常操作中无法学到任何新东西。
但是回到数据隐私,反向传播带来了另一个主要的缺点:所有的输入数据都必须保存,以便重新训练。例如,如果 DNN 已经在 1000 幅图像上被训练,并且需要学习额外的图像,那么 1001 幅图像需要被呈现数千或数百万次迭代。如果这 1000 张图片不能合法保存会怎么样?培训无法进行,网络无法更新。
本质上,今天的人工智能技术要求与 GDPR 等立法的要求是正交的。

Brains have trillions of synapses learning on a constant basi
虽然目前的 dnn 是大脑的超简化模型,但生物学有更丰富的工具可供其支配。让我们以一个人脑为例。DNNs 归入“连接”或“重量”的东西,大脑将其分解为大量的物质和结构——神经递质和突触——它们不同于针对不同类型受体和突触的小分子递质和神经肽。小分子传输器是其他神经元的直接参与者,并且以非常简单的方式更接近于传统人工智能和 DNN 今天正在做的事情。
另一方面,神经肽或“调节剂”在其目标中介导更微妙的作用。
我们大多数人都接受过某种标准化的教育,在那里我们去学校学习一系列重要的技能。当到了去找工作的时候,我们带着那些技能和知识,我们很快认识到日常学习是我们在工作中变得更好以及在工作场所和社会中进步的最重要的方式。作为人类,我们日复一日地这样做,甚至到了老年。更重要的是,我们做得很快:对于我们存储在记忆中的大部分内容,几个学习片段就足够了。这种学习方式与传统的 DNN 形成了鲜明的对比,在那里,对于人类来说,等同于我们所知道的一切都是在学校里学到的,之后什么也学不到。
在新的“终身”DNN ( 终身-DNN)架构中,小分子和神经肽递质的联合数学建模使它们能够有区别地表达两个时间尺度——快速和慢速学习——这两个时间尺度传统上被集中到一组方程中。这一重大创新使人工智能能够保持慢学习的优势,这一点已被反向传播所利用,同时也利用了快速学习的优势。

Computing at the Edge .. the future of AI is here
此外,由于它在数学上非常紧凑,终身 DNN 的新范式可以直接在设备上实现终身学习,其中芯片组可以像低端智能手机的芯片组一样便宜,可以在没有 Wi-Fi 或手机连接的情况下工作,也不需要在手机或设备上存储所有的训练数据。
这意味着每个数据点在学习过程中只使用一次:不需要数百万次迭代。当新数据出现时,它可以被丢弃。隐私不再是一个问题。
人工智能是一项相对年轻的技术,作为一个领域,它只是触及了可能性的皮毛。我们不应该忘记,从生物大脑中获得的知识中,只有极小一部分被编码到今天的最终用户和工作应用程序中。就信息处理而言,即使是 L-DNN 也远远达不到生物大脑所能达到的水平。但像 L-DNN 这样的创新是构建既有用又尊重人们隐私的人工智能的核心。
人工智能差分隐私和联邦学习
对用户敏感数据使用人工智能最近引发了许多担忧。差分隐私和联合学习是谷歌和苹果等公司目前针对这一问题提出的解决方案。

(Source: https://ai.googleblog.com/2017/04/federated-learning-collaborative.html)
介绍
每天都会以不同的形式收集敏感数据(例如,医院医疗记录、手机活动记录等)。一旦数据被收集,然后进行预处理,成为完全匿名,最后提供给公司和研究社区进行分析。
使数据集匿名可以防止任何人仅仅利用数据集就完全能够将数据逆向工程到其原始形式。
但是,数据集中包含的数据也可以在网上以任何其他形式获得。通过使用数理统计方法比较相同数据的不同来源,原始数据的逆向工程可以变得容易得多。通过这种方式,提供数据的人的隐私可能会受到损害。
例如,网飞在 2007 年发布了一个数据集,其中包含他们对公开竞赛的用户评分。该数据集在比赛午餐前已经完全匿名,以便不包含任何私人信息。研究人员相继尝试测试该数据集的隐私安全性,并成功恢复了高达 99% 的被删除个人信息[1]。通过将网飞提供的数据与 IMDB 上公开的其他信息进行比较,有可能取得这一结果。
利用差分隐私和联合学习等技术可以大大降低这种风险。
差异隐私
差异隐私使我们能够量化数据库的隐私级别。这可以帮助我们尝试不同的方法,以确定哪种方法最能保护用户的隐私。通过了解我们的数据隐私级别,我们可以量化某人可能从数据集中泄露敏感信息的可能性,以及最多可以泄露多少信息。
Cynthia Dwork 给出的差分隐私的定义是:
差异隐私描述了数据持有人或管理者对数据主体做出的承诺,该承诺如下:
“您不会因为允许您的数据用于任何研究或分析而受到不利或其他方面的影响,无论其他研究、数据集或信息来源是否可用”。
辛西娅·德沃克
差分隐私用来保护个人隐私的一种技术是在数据中添加噪声。两种主要的差分隐私方法是局部差分隐私和全局差分隐私。
- 局部差分隐私 =噪声被添加到数据集中的每一个单独的数据点(在数据集形成后由数据集管理者添加,或者在将数据提供给管理者之前由个体自己添加)。
- 全局差分隐私 =保护个人隐私所必需的噪声被添加到数据集的查询输出中。
一般来说,与局部差分隐私相比,全局差分隐私可以产生更准确的结果,同时保持相同的隐私级别。另一方面,当使用全局差分隐私时,捐赠数据的人需要相信数据集管理器会添加必要的噪声来保护他们的隐私。
在实现差分隐私时,通常可以使用两种类型的噪声:高斯噪声和拉普拉斯噪声(图 1)。

Figure 1: Gaussian and Laplacian distributions [2]
为了确定添加到数据集上的必要噪声量以确保其隐私安全,使用了差分隐私的正式定义(图 2)。

Figure 2: Differential Privacy Definition [3]
在图 2 中, A 表示一个随机算法,该算法将一个数据集作为输入,数据集 D1 和 D2 仅相差一个元素,并且ε(ɛ)是一个正实数。ε用作确定必要噪声量的参数。
联合学习
利用大量数据的机器学习模型传统上是使用在线服务器来训练的。谷歌和苹果等公司过去常常收集移动设备用户的数据记录活动,然后将其存储在云服务中,以创建一个集中式机器学习模型,从而提高其移动服务的性能。
如今,这些大公司正转向使用一种叫做联合学习的分散模型方法。使用联邦学习,在数据源上训练机器学习模型,然后将其输出移动到云上进行进一步分析。这意味着像谷歌和苹果这样的公司不再需要访问他们的用户数据来改善他们的服务,而是可以使用本地训练的机器学习模型的输出(不侵犯用户隐私)。
此外,由于这些模型是在本地培训的,因此可以为最终用户提供更加个性化的体验(图 3)。
联合学习的定义可以是:
- 联合学习 =一种在我们无法访问的数据上训练机器学习模型的技术。我们用来训练模型的数据集分布在大量资源中。

Figure 3: Federated Learning in action [4]
像谷歌这样的公司指定,这些类型的本地机器学习培训旨在仅在终端设备处于以下状态时发生:用户未使用、正在充电并且有 wifi 连接。这样,设备的整体性能不受影响。
智能手机设备上联合学习的一些例子可以是:在 Android、Gmail 和 Google 搜索引擎上使用 Gboard 的个性化单词建议。
谷歌人工智能提供了几个谷歌如何利用联合学习及其工作原理的例子,这些例子可以在这里和这里找到。
结论
如果你想了解更多关于这些话题的信息,我强烈建议你报名参加由 Udacity 提供的免费安全和私人 AI 课程。获得更好的数学背景的其他有价值的资源可以是这两个出版物[5,6]。
联系人
如果你想了解我最新的文章和项目,请通过媒体关注我,并订阅我的邮件列表。以下是我的一些联系人详细信息:
文献学
[1]大型数据集的稳健去匿名化(如何打破 Netflix Prize 数据集的匿名性)。Arvind Narayanan 和 Vitaly Shmatikov,德克萨斯大学奥斯汀分校。访问地点:https://arxiv.org/pdf/cs/0610105.pdf
[2]使用基于拉普拉斯分布的小波域隐马尔可夫树模型的纹理分割。乔玉龙和赵干超,。访问地点:https://www.mdpi.com/1099-4300/18/11/384/html
[3]差分隐私,维基百科。访问时间:https://en.wikipedia.org/wiki/Differential_privacy
[4]差异私人联合学习:客户层面的观点。罗宾·盖耶,塔希洛·克莱恩,和莫因·纳比。访问:https://medium . com/sap-machine-learning-research/client-sided-differential-privacy-preserving-federated-learning-1 fab 5242d 31b
[5]差分隐私和机器学习:调查和评论。张龙吉,扎卡里利普顿,查尔斯埃尔坎。访问地点:【https://arxiv.org/pdf/1412.7584.pdf
[6]差分隐私的深度学习。马丁·阿巴迪、安迪·楚、伊恩·古德菲勒等人访问:https://storage . Google APIs . com/pub-tools-public-publication-data/pdf/45428 . pdf
人工智能发现你脸上的心跳
对从视频中读取生命体征的技术进行中等深度的探究
由乔尔肖尔,谷歌 ML 研究工程师,萨利赫纳比勒谢哈达,医学博士,马特奥布莱恩

有时候很难想象今天笨重的听诊器会变成明天的《星际迷航》三录仪。这篇文章将通过解释医疗保健中的一项具体发展来帮助你更好地设想这条道路:一项仅通过视频来确定你的心率的技术。
视频心率将开启医院内外的许多酷应用。
- 将闭路电视摄像头转换为心脏病预警探测器
- 通过移除更昂贵的监控设备来降低医院护理的成本
- 在给你保险之前,让保险公司知道你的心血管健康状况,立即自动拨打 911
- 通过向计算机提供你所感受到的情绪的直接线索来改善人机交互
你也可以想象看一段你最喜欢的政治家说了一些令人难以置信的令人发指的话的视频,然后得知这位政治家的心率一直为零。然后你可能会得出结论,要么她是一个僵尸,要么你一直在看一个深度假。
先前的心率测量值
当前测量心率的技术通常分为三类:
技巧一:电信号。测量心率最可靠的方法是直接监测心脏的电活动。像所有肌肉一样,心脏由神经系统控制。附着在皮肤表面适当位置的电极可以检测到这些电脉冲。
手法二:机械信号。急诊室医生通常通过将手指放在患者手腕上 15 秒钟来测量心率。这是因为心脏跳动的力量如此强大,以至于动脉会随着每次跳动而移动。医生计算每分钟静脉或动脉搏动的次数,肌肉收缩如此强烈,以至于手腕和脚踝都能可靠地感觉到脉搏。
手法三:吸光。光电容积描记术(PPG)利用光的反射和吸收特性。不同数量的血液吸收不同数量的光,因此血液量的变化可以通过光吸收来跟踪(因此当心脏跳动时)。通常,一个 LED 照亮皮肤,另一个设备测量有多少光被反射回来。反射光量的变化与心跳一致。
算法技术利用了许多相同的物理现象。
运动心率的算法测量
软件可以通过观察头部的细微运动来利用机械信号。血液从心脏到头部的运动导致头部以周期性运动的方式运动,运动心率算法试图仔细测量大致预期频率的周期性头部运动,然后反向工作并推断出心率(类似于上一节中前面的心率技术#2)。下图显示了算法流程。

Schematic diagram of technique. Taken from [1]
步骤 a :跟踪头部和颈部。这是使用传统的计算机视觉技术完成的。
步骤 b :将头部的运动映射到一个 1D 轴上。作者发现,垂直方向最好地捕捉了由于心跳引起的不随意运动,因为水平方向的运动由不随意摇摆所支配。
步骤 c :即使在垂直方向,除了心率之外,还有很多运动源。例如,呼吸和姿势的变化也会移动头部和颈部。为了消除这些噪声源,作者使用传统的信号处理滤波技术,只针对与“正常”心率对应的频率范围内的运动。
步骤 d :即使滤波后,也只有部分垂直头颈运动是由于心率。作者将剩余的混合运动分解为子运动矢量,并假设最周期性的运动矢量对应于心率。他们使用标准的分解技术(主成分分析,或 PCA)来提取运动的主导方向和幅度。请参见下图,了解此步骤结果的直观描述。

Examples of the first two eigenvectors for two subjects. Each white arrow on a face represents the magnitude and direction of a feature point’s contribution to that eigenvector. The eigenvector decomposition is unique to each subject. Taken from [1].
他们在私人数据集上的结果非常好:所有 18 名受试者在 70-90 秒窗口内的平均心率误差小于 4%,平均误差为 1.5%。
从颜色计算心率
2008 年引入了使用正常环境光的视频心率。[2]使用精心控制、精心收集的数据集,从面部轻微的颜色波动中检测心率(类似于上一节中的心率技术#3)。他们通过记录志愿者在精心控制的环境中静止不动的时候,避免了改变背景光和头部运动的问题。有趣的是,他们发现大多数心率信息是由数字 RGB 颜色空间中的绿色通道携带的,这与绿光比红光更容易被红细胞吸收的事实相一致。
2014 年[3]在 2008 年算法的基础上进行改进。他们在公共数据集[4]上进行评估,这意味着他们的结果更具可重复性。该数据集在照明和运动方面也有更多的变化,因此结果更接近于真实生活场景的代表。下面是他们方法的示意图,我将在下面详细介绍。

Framework for heart rate measurement from facial videos. Taken from [3].
步骤 1 :检测人脸,并通过视频帧进行可靠、稳定的跟踪。稳定地跟踪人脸是很重要的,因为本文使用人脸区域像素的平均绿色值来估计脉搏。不断变化的面部区域会导致对脉搏的不正确估计。
第二步:控制光照变化。如果您假设面部和背景由相同的光源照明,那么如果面部的颜色变化与背景的颜色变化同时出现,您可以忽略它们。
第三步:从第一步开始的面部跟踪处理了某些类型的面部运动(例如平移),但其他类型的面部运动对于基于绿色的分析来说仍然是个问题(例如眨眼或微笑)。为了避免这个问题,作者简单地排除了包含许多有问题的运动的时间段。他们之所以能做到这一点,是因为他们测量了一个时间窗口(例如 30 秒)内的平均心率。他们通过观察颜色通道变化的时间段来识别这些有问题的区域。换句话说,如果你面部的平均颜色变化太大太快,他们(正确地)会怀疑。
第四步:最后,作者应用一个过滤器来排除不可信的信号信息。众所周知,心率在每分钟 42 到 240 次之间(并且通常存在于一个更窄的范围内),因此比这更快或更慢的颜色变化被标准的信号处理技术排除在外。
他们在公共数据集[4]上使用 30 秒的窗口对 27 名受试者的结果平均在实际值的 3.5 次心跳之内,标准偏差不到 7。
我们要去哪里
在这项技术成为主流之前,仍然有许多挑战需要解决。一个问题是准确性,另一个问题是鲁棒性。这两个问题都可以通过更多的数据来解决,但在医疗情况下收集大型数据集总是需要高度谨慎,以保护患者信息和保持匿名。另一个问题是潜在的偏见:从数据中训练出来的算法需要对所有肤色的人都有效。
总之…
能够从视频中测量心率有望使现有的护理更容易获得,并开启了许多人在回路中不可能实现的应用。这篇文章有望揭开这项技术背后的一些算法巫术。
来源
[1] G. Balakrishnan,F. Durand 和 J. Guttag,从视频中的头部运动检测脉搏 ( 2013) , IEEE 计算机视觉和模式识别会议,俄勒冈州波特兰,2013 年,第 3430–3437 页。doi: 10.1109/CVPR.2013.440
[2]弗克鲁伊塞、斯瓦桑德、纳尔逊。使用环境光的远程体积描记成像 (2008)。 Opt 快递。;16(26):21434–21445.doi:10.1364/oe.16.021434
[3] X. Li,J. Chen,G. Zhao 和 M. Pietikä inen,(2014), IEEE 计算机视觉和模式识别会议,俄亥俄州哥伦布市,2014 年,第 4264–4271 页。doi: 10.1109/CVPR.2014.543
[4] M. Soleymani,J. Lichtenauer,T. Pun 和 M. Pantic,情感识别和隐式标记的多模态数据库 (2012),载于 IEEE 情感计算汇刊,第 3 卷,第 1 期,第 42–55 页,1 月至 3 月。doi: 10.1109
人工智能与伦理:我们是不是让自己变得更困难了?

不久前,我们讨论了与脸书十年挑战赛有关的人工智能启示录。脸书邪恶吗?我们因为帮助自己走向灭亡而变得邪恶了吗?正如我们所说:不完全是。然而,道德似乎无情地联系在一起,而且理由充分。这是正在进行的关于人工智能和伦理问题系列的一部分。当然,没有比科幻小说更好的起点了。
长久以来,关于人工智能能做什么的问题已经抓住了我们的想象力。事实是,这个想法至少在概念上可以追溯到古希腊的。
从哲学的角度来说,人类的创造物能够做什么并不新鲜。也不知道我们该如何应对。然而,至少在现代意义上,艾萨克·阿西莫夫在将这个问题推向公众辩论方面发挥了作用。至少对于人工智能来说是这样。也就是机器人。机器人能做什么?我们如何阻止他们?
谢天谢地,阿西莫夫找到了解决办法。机器人三定律首次出现在 1942 年的短篇小说《逃避》中阿西莫夫提供了一套准则,这些准则是所有机器人编程的关键组成部分:
- 第一定律:机器人不能伤害人类,也不能坐视人类受到伤害。
- 第二定律:机器人必须服从人类的命令,除非这些命令与第一定律相冲突。
- 第三定律:机器人必须保护自己的存在,只要这种保护不与第一或第二定律相冲突。
够了吗?
人工智能和伦理的概念并不新鲜。也不应该。我们坚信,占据这个空间的任何人都应该思考、评估和考虑人工智能的伦理含义。今天如此,明天亦然。
机器人背叛它们的创造者的想法造就了伟大的科幻小说。然而,我们还没有完全实现。据《科学美国人》报道,这是一件好事,该杂志认为阿西莫夫定律根本不起作用:
虽然这些定律听起来似乎有理, 无数的论据 已经证明了它们的不足。 阿西莫夫自己的故事 可以说是对规律的一种解构,表现了他们在不同的情境下是如何反复失败的。 大多数尝试 起草 新指南 遵循类似的原则来创造安全、顺从和健壮的机器人。
ByChristoph Salge对话我们2017 年 7 月 11 日**
我们现代对人工智能和伦理的关注通常不是机器人接管世界,而是更多地关注保护数据免遭盗窃,防止算法偏差,以及我们对待人工智能、数据等的负责任的方式。
没错,这比担心如何阻止我们建造天网稍微不那么冠冕堂皇;但是尽管如此,关于人工智能还有一些重要的问题&伦理问题,值得关注和研究。
最近的文章再次提出了这些问题。最近人工智能教育和伦理将在 2019 年扰乱社会的 4 种方式也许更尖锐:人工智能有可能是伦理的吗?
嗯,有可能吗?
是的。不是。但大部分是。也许吧。
这些天我们产生了大量的数据。很多。人们对我们如何处理这些数据有很多担忧。可以理解也很明智。然而,也有人担心我们可能弊大于利。或者至少从端点的角度来看,我们给自己制造了更多的困难。
去年在欧盟实施的《通用数据保护条例》( GDPR)就是这样一个例子,它让我们的事情变得更加困难。
从某些角度来看,很难反驳 GDPR 提出的观点。也就是说,组织在道德上有责任正确处理您的数据,而不是共享它,并保护它。理论上都是好东西。
然而,无论好坏,它也是一堵墙。毫无疑问,墙可以防止坏东西进入。但是,也能让好的东西出不去。
GDPR 成功做到的,部分是有意的,部分是无意的,是将数据与外界隔离开来。这是好事吗?嗯,不总是这样。
与这些想法形成对比的是,人们普遍指责和相信硅谷到处都有带有偏见的算法。某些群体受益于(至少在某些人看来)应该是不偏不倚的等式。
现在,考虑这些算法是如何创建的。或者更重要的是,它们是在哪里产生的。
隔离数据问题
过去,我们习惯于从单一来源获取数据。或者至少很少的来源。我们所说的“数据”是指成千上万比特的信息,这些信息放在一起形成了一个连贯的、可行的算法优化模型。
限制性数据保护法可能无意中造成的问题是,它使数据更难合法获得。出于对人工智能和伦理的担忧,我们前所未有地隔离了数据。保持它的限制性。
现在,如果你的脑海中浮现出一家电话销售公司的画面,希望创造一种模式,让他们知道晚餐时间该打电话给谁,打扰谁,这听起来可能不是一件坏事。如果你是一所大学的医学研究部门,建立一个模型来预测、诊断甚至治愈疾病,这可能是一件坏事。
过去,我们已经详细讨论了与开发和部署相关的“竖井问题”。专业团队能够对问题的一个特定方面表现出高度集中的注意力。然而,它不一定会产生最好的结果或最好的最终产品。
在竖井中处理数据也是如此。为了解决世界上的问题,甚至尝试这样做,我们需要访问大量的数据。随着越来越多的限制进一步封锁这些数据,我们面临着偏向我们自己的数据池的风险。
要明确的是:当我们谈论能够在一个地方收集数据时;我们指的是可以从单一来源访问的大量数据;但不是来源于单一来源的大量数据。
让我们烤面包吧
例如,我们可以去超市购物,面包、牛奶、肉和蔬菜都在一个地方。超市是许多不同类型产品(数据)的巨大来源。如果我们想建立一个算法来跟踪或预测人们购买的食品杂货,超市将是一个很好的起点。
为什么?因为我们知道那里的购物者会购买各种各样的商品,包括不同类型和不同种类的商品。我们将能够查看大量数据来构建我们的模型。
现在,让我们假设超市不存在。事实上,从送牛奶的人那里买牛奶,从蔬菜市场买农产品,或者从面包师那里买面包,可能被认为是“更安全”或“更好”的。然而,它远没有那么方便,也有更多的限制。
如果你从一个单一的来源购买面包:你要感谢这个单一的来源和这个来源的所有特征。那么,当我们只能方便地访问面包师的数据时,我们如何建立一个模型来跟踪杂货购买呢?
这就是我们如何无意中偏向我们自己的算法。
开放寄宿生数据
这并不是说算法或数据实践中不存在具有文化意义的社会偏见。他们绝对可以。然而,由于跨越某些障碍合法获取数据的难度越来越大,建立具有文化意义和跨文化的模型变得越来越困难。
因此,在硅谷建立的模型可能会反映硅谷的人口结构。在印度建立的模型可能反映了印度的人口统计,等等。我们面临的一个问题是,这种一刀切的方法很难从一组数据中有意义地创建一个模型,这些数据可能无法反映所有用户、所有组件,甚至无法达到现实的、理想的或有意义的结果,如果数据之前存在这样或那样的偏差。
同样,在大多数人看来,如果我们停止电话营销,这并不是一件坏事。如果我们用对人工智能和伦理的担忧来割掉我们自己的鼻子,以此来刁难我们的脸,这可能是一件坏事。
数据收集和分析的未来可能更像这样:在本地收集,在全球重复。当然,这是一个更漫长、更复杂的过程。然而,对增强数据保护的推动越大,访问限制就越多。
那我们该怎么办?
在很大程度上,关于人工智能和伦理的对话才刚刚开始。这是件好事。因为正如我们之前所说,我们认为在这个领域工作的人有责任继续问这些问题。也就是说,我们的行为符合道德吗?我们是否为围绕这些问题的公共空间和公共辩论贡献了有意义的思想和行动。随着技术的发展,这些问题需要继续提出。
在某种程度上,我们认为个人(和公司的责任)必须发挥作用。政府监管能够也将有助于指出正确的道路。然而,如上所述,它也有自己的缺点和不足。
有很好的理由要求像 GDPR 这样的监管,以及美国更严格的监管。然而,也有如上所述的无意的缺点。这也使得空间的新来者很难上手。这就把业务转移到了少数几个有手段、资源和关系的人手中。
在某种程度上,对人工智能的伦理处理可能最终取决于控制它的人。我们可能离真正担心机器人起义还有很长的路要走。谢天谢地。这并不意味着在这个领域不存在对坏演员的担忧。
我们有责任负责任地使用人工智能。这并不意味着一路上不会有错误、失误和灾难。不这样想是愚蠢的。然而,人工智能和伦理的问题也是一个基本的人类问题。就像编写实现阿西莫夫机器人三定律的代码的人一样。
当一个糟糕的演员“忘记”或省略了这段代码会发生什么?当那些负责保护数据的人试图滥用数据时会发生什么?不要太哲学化,但是围绕着人工智能有多道德的问题暂时将最终停留在人类行为的道德可能性的范围内。
当然,我们有自由意志。不像我们的机器人下属。暂时如此。
原载于 2019 年 5 月 9 日【https://introspectdata.com】。
人工智能失败了,他们教给我们关于新兴技术的什么

这些天来,我们已经对人工智能的奇迹般的便利变得麻木不仁。当我们打开网飞,立即找到完全符合我们口味的内容时,我们并不感到惊讶,当脸书的面部识别技术从一组照片中认出我们的脸时,我们也不会感到惊讶。十年前,如果我们听到一个朋友让一个看不见的人调暗灯光或报告天气,我们可能会找个礼貌的借口迅速离开。现在,我们几乎不眨眼——也许想知道我们是否也应该得到一个回声点。
我们已经变得如此习惯于人工智能悄悄融入我们日常生活的几乎每个方面,以至于我们不再有坚硬的墙阻挡我们对可能性的感知。我们不是怀疑人工智能能力的新主张,而是带着感兴趣的惊讶看待它,并思考——我可以用它吗?
但是当 AI 没有我们预期的那么好的时候会发生什么呢?当我们对人工智能有用性近乎无限的信念被放错了地方,当我们已经开始依赖的高科技工具在我们委派的责任的重压下开始崩溃时,会发生什么?
让我们考虑一个例子。
人工智能不能治愈癌症——或者它能吗?IBM 案例研究
当 IBM 的沃森在 2014 年首次亮相时,它吸引了投资者、消费者和技术爱好者。支持者夸口说,沃森的信息收集能力将使其成为医生的宝贵资源,否则他们可能没有时间或机会跟上医学知识的不断涌入。在同年的演示中,沃森分析了一系列症状,并提供了一系列潜在的诊断,每个诊断都根据系统的可信度进行了排名,并与相关的医学文献相关联,这让行业专业人士和投资者眼花缭乱。人工智能对罕见疾病的清晰认识及其提供诊断结论的能力既令人印象深刻又鼓舞人心。
沃森的积极印象刺激了投资。受到人工智能潜力的鼓舞,德克萨斯大学癌症中心 MD Anderson 与 IBM 签署了一份价值数百万美元的合同,将沃森的认知计算能力应用于抗癌。Watson for Oncology 旨在解析大量病例数据,并提供新颖的见解,帮助医生为癌症患者提供更好、更有效的护理。
不幸的是,这个工具并没有完全实现它的营销宣传。
2017 年,德克萨斯大学的审计师提交了一份刻薄的报告,声称沃森不仅花费了 MD Anderson 超过 6200 万美元,而且未能实现其目标。医生痛斥该工具倾向于给出错误的建议;在边缘报道的一个令人难忘的案例中,人工智能建议一名严重出血的患者接受一种会恶化其病情的药物。幸运的是,病人是假设的,没有真实的人受伤;然而,用户仍然对沃森明显的无能感到恼火,这是可以理解的。正如一位特别尖刻的医生在给 IBM 的一份报告中所说,“这个产品是一个 s-。我们买它是为了营销,希望你能实现这个愿景。我们不能在大多数情况下使用它。”
但是,该项目未能实现其宣传的目标,难道都是沃森的错吗?不完全是。
沃森的主要缺陷在于实现,而不是技术。当项目开始时,医生按计划输入真实的患者数据。然而,沃森的指导方针经常改变,以至于更新那些案例成了一件苦差事;很快,用户切换到假设的例子。这意味着沃森只能根据少数医生提供的治疗偏好和信息提出建议,而不是来自整个癌症中心的实际数据,从而扭曲了它提供的建议。
此外,人工智能辨别联系的能力只在一定程度上有用。它可以注意到患有某种疾病的患者、他们的状况和所开药物之间的模式,但从这种分析中得出的任何结论充其量都是脆弱的。人工智能无法明确确定这种联系是相关、因果还是仅仅是巧合——因此,在没有循证支持的情况下,提供诊断结论的风险。
鉴于缺乏用户支持和真实信息的短缺,沃森未能提供创新的答案有什么奇怪的吗?
沃森的失败教会了我们什么?
沃森的问题与其说是技术性的,不如说是人性的。我们可以从人工智能的崩溃中吸取三大教训:
我们需要检查我们的期望。
我们倾向于相信人工智能和新兴技术可以实现其开发者所说的。然而,正如沃森无法区分相关性和因果性所表明的那样,我们在营销文案中读到的潜力可能被过度夸大了。作为用户,在我们开始依赖新兴技术之前,我们需要对它有更好的理解和怀疑。
工具必须集成良好。
如果医生能够使用 Watson 界面,而不需要不断修改他们提交的新指南,他们可能会提供更多真实的患者信息,并比他们更频繁地使用该工具。这反过来可能让沃森更有效地完成了它被赋予的角色。考虑人类用户的需求和考虑工具的技术需求一样重要(如果不是更重要的话)。
我们必须小心
如果 MD 安德森中心的科学家们没有如此小心,或者他们盲目地跟随沃森,真正的病人可能已经处于危险之中。我们永远不能让我们对一个新兴工具的信心膨胀到看不到它应该帮助的人。
新兴技术的确令人兴奋,但我们也需要花时间来解决我们如何将这种看似强大的技术带入我们生活的道德和实践问题。至少,对我们的信仰多一点怀疑似乎是明智的。
人工智能公平性——不同影响消除器的解释
人工智能公平性介绍
AI 公平性是机器学习从业者的重要课题。我们必须意识到,当用户与我们的模型交互时,可能会有正面和负面的影响。尽管我们对成功的度量倾向于性能度量(例如,准确性),但是那些与我们的模型交互的人也可能考虑其他值。使用人工智能的工具正在被开发出来:批准或拒绝贷款;决定是否应该考虑对某人进行面试;确定某人是否适合接受治疗。这些结果对个人都有很大的影响。这就是为什么公平是一个如此重要的考虑因素。
为了确保公平,我们必须分析并解决训练数据中可能存在的任何偏差。机器学习发现并归纳数据中的模式,因此可以复制偏差。当大规模实现这些模型时,可能会导致大量有偏见的决策,伤害大量用户。
引入偏差
数据收集、处理和标注是我们在数据中引入偏差的常见活动。
数据收集
- 由于收集数据时使用的技术或人员,会引入偏差,例如,该工具仅在特定语言中可用
- 这可能是采样策略的结果,例如,收集的子群体代表性不足
加工和贴标
- 丢弃数据,例如子群体可能更常见地具有缺失值,并且通过丢弃那些样本,导致代表性不足
- 人类的标签,或决策者,可能有利于特权群体或加强刻板印象
差别性影响
不同的影响是评价公平性的一个尺度。它比较了两个群体中获得正产出的个体比例:一个非特权群体和一个特权群体。

计算方法是获得积极结果的非特权群体的比例除以获得积极结果的特权群体的比例。
行业标准是五分之四规则:如果非特权组收到的积极结果少于特权组的 80%,这就是不同影响违规。然而,你可以决定增加你的业务。
预处理缓解
一些人经常建议的减轻偏见的一种方法是简单地删除应该保护的特征。例如,如果你担心一个模型是性别歧视的,而你的数据集中有性别,那么就从传递给机器学习算法的特征中删除它。不幸的是,这很少能解决问题。
特权群体经历的机会可能没有呈现给非特权群体;每个组的成员可能无法访问相同的资源,无论是财务资源还是其他资源。这意味着它们的环境不同,因此,它们对于机器学习模型的特征也不同,不一定具有可比性。这是系统性偏见的结果。
让我们以一个玩具为例,一个非特权群体为蓝色,一个特权群体为橙色。由于他们无法控制的环境,蓝色倾向于降低我们感兴趣的特征的价值。
我们可以为两组中的每一组绘制特征分布图,并直观地看到这种差异。

如果您要随机选取一个数据点,您可以使用它的特征值来预测您从哪个组中选择。
例如,如果您选择一个特征值为 6 的数据点,您很可能会认为相应的个体属于橙色组。相反,对于 5,你会认为他们属于蓝色。
特征不一定是预测预期结果的有用属性。但是,如果训练数据的标注倾向于橙色组,则要素的权重会更高,因为它可用于推断分组。
举个例子,一个人的名字不一定会影响他们的工作能力,因此,也不应该影响他们是否被录用。然而,如果招聘人员无意识地有偏见,他们可能会从名字中推断出候选人的性别或种族,并将此作为他们决策的一部分。
不同冲击消除器
不同影响移除器是一种预处理技术,用于编辑将用作特征的值,以增加组之间的公平性。如上图所示,一个特征可以很好地表明一个数据点可能属于哪个组。异类影响移除器旨在移除这种区分组成员的能力。
M. Feldman、S. A. Friedler、J. Moeller、C. Scheidegger 和 S. Venkatasubramanian 在论文中介绍了该技术。
该算法要求用户指定一个repair_level,这表示您希望组的分布重叠多少。让我们来探讨一下 1.0 和 0.8 两种不同修复级别的影响。
修复值= 1.0

该图显示了使用修复级别为 1.0 的DisparateImpactRemover后,非特权组蓝色和特权组橙色的特征的修复值。
您不再能够选择一个点并推断它属于哪个组。这将确保机器学习模型不会发现群体偏见。
修复值= 0.8

该图显示了使用修复级别为 0.8 的DisparateImpactRemover后,非特权组蓝色和特权组橙色的特征的修复值。
分布并不完全重叠,但是您仍然很难区分成员资格,这使得模型很难做到这一点。
组内排名
当特征显示两个群体之间的差异时,我们假设他们有不同的机会和经历。然而,在群体中,我们假设他们的经历是相似的。因此,我们希望一个人在他们的组中的排名在修复后得到保留。不同的冲击消除器保持组内的等级排序;如果一个人有蓝色组的最高分,那么在修复后,他仍然有蓝色组的最高分。
构建机器学习模型
一旦实现了不同的影响消除器,就可以使用修复的数据来构建机器学习模型。不同的影响指标将验证模型是否无偏(或在可接受的阈值内)。
偏差缓解可能会导致较低的性能指标(例如准确性),但这并不一定意味着最终模型会不准确。
这对人工智能从业者来说是一个挑战:当你知道你有偏见的数据时,你会意识到你正在建立的模型不一定反映现实,也不一定反映你希望坚持的价值观。
示例笔记本
作为我对DisparateImpactRemover调查的一部分,我使用玩具数据集创建了一个示例笔记本。它演示了以下内容:
- 计算不同的影响(使用 Python 和 AIF360)
- 构建简单的逻辑回归模型
- 创造一个
BinaryLabelDataset - 用两种不同的维修级别执行
DisparateImpactRemover - 验证组内排名的保留
这个可以在 GitHub 这里找到。我们用来实现这个算法的库是 AI Fairness 360 。
最后的评论
公平的概念是难以置信的微妙,没有任何算法方法来减轻偏见是完美的。然而,通过考虑我们用户的价值,并实施这些技术,我们正朝着一个更公平的世界的正确方向前进。
艾:假装它,直到你成功
经常有人抱怨那些假装在做人工智能但实际上并没有做的公司。事实是,有时他们只是提前计划——这实际上是解决重大挑战的好方法。让我们看看它如何帮助以及如何(真正)正确地做这件事,或者,如何建立一个 MLMVP(机器学习最小可行产品)!

What if AI was just a big scam? Taken from “Scooby-Doo, Where Are You!” episode “Hassle in the Castle”
AI 到底给你带来了什么?
等等:对了,你当初为什么要做 AI?人工智能(或计算机视觉或机器学习或 NLP 等)会给你带来什么?
有时,我喜欢将项目视为“计算机辅助决策”,而不是人工智能/机器学习,我一直记得,正如凯西·科济尔科夫所说,机器学习“只是”一个事物的标签。
一个人脸检测算法?东西标签。
视觉金属疲劳检测仪?东西标签。一个聊天机器人,它的首要任务是理解用户想要说什么?东西标签。
许多人工智能项目始于一个给事物贴上正确标签的程序。
据我所知,人类已经在不用机器的情况下做了大量的标签工作。机器学习是一个相对较新的计算机科学领域,但这个世界早就存在了。我们是如何解决给我们的神经网络的任务的?
我们要么手工做,要么通过大量编程来做。如果你记得不错,深度学习使特征提取独立于先验知识,这是非常酷的…..当它工作的时候。
实际上,机器学习给了我们 3 个重大突破:
- 自动特征提取,只要我们给神经网络提供足够的例子。这意味着与手动特征提取相比,更快的构思(或训练);
- 即时回答(你的里程数可能会有所不同,但对于我们在 NumeriCube 的工作,我们通常希望算法能在 0.5 秒内做出回答)
- 缩放。大规模并行处理能力。ML + Cloud =大规模可扩展的事物标签解决方案。人类无法如此快速地扩展。
这是机器学习算法相对于人工干预的 3 个主要优势。
在理想的世界里…
任何人都需要什么来建立一个东西贴标机?
- 大量示例数据
- 首先是最先进的分析,又名人工智能专业知识(这是经验说话的地方:)
- 很多时候又不紧不慢地走向漫长的试错之路。
很简单,不是吗?通常,数据科学应用程序构建流程如下:

The usual Data Science workflow
显然,你需要数据来开始。在一个理想的世界里,你只需要为你的问题建立或者请别人建立一个干净的数据集,然后开始处理它。然而,这并不总是可能的,事实上,很多时候根本不可能。
示例数据?我的个人经验是,当一个项目从一个已经存在的数据集开始时,大约 99%将被丢弃,主要是因为实验室数据实际上从未以与生产数据相同的方式获得。
例如,考虑一个图像识别应用程序。你可以在 Flickr 上从数百万张已经标注的图片中训练它,对吗?嗯,除了当你的普通用户用她的智能手机拍照时,结果不会看起来像你建立训练集的整洁的 Photoshop DSLR+flash 图片。该死的。
因此,您有一个业务问题,您非常确定您可以用足够的数据来解决它,并且您知道您将使用的最佳数据来自生产系统。
换句话说,为了以正确的方式收集数据,您需要您的系统处于生产状态!看起来像是鸡和蛋的问题!

Photo by Sebastian Staines on Unsplash — Does the data come before the app, or the app before the data 🤔
在谷歌工作怎么做到这一点?
对于大平台(想想谷歌、脸书、苹果等),很容易将数据收集过程与数据科学过程分开。为什么?因为这些公司的背包里已经有了庞大的数据收集工作流程。

How big companies are doing data science (thanks to other apps)
在某种程度上,谷歌、脸书、亚马逊等花了 10 多年时间来开发数据收集应用。例如,至少从 2008 年开始,脸书就允许在你的照片上标记你的朋友!他们现在有一个大规模的面部检测数据集…它工作得很好,因为他们的数据收集应用程序已经包含了服务。
但是如果你想从零开始建立一个 AI 服务,你不能这样做。如果你还没有数据,你必须一步到位。
旁注:实际上,这是大多数拥有自动车辆数据集收集的大公司的情况——这可能是他们在这方面如此挣扎的原因:除了特斯拉,他们在开始研究这一主题时没有数据收集流程。
如果你正在阅读这篇博文,而你不是谷歌,那么你可能也没有一个好的数据集可供使用。那么,你如何能在构建一个人工智能应用的同时收集数据呢?
等等:你现在真的需要实时和可伸缩性吗?
答案是:假的。用人类来做。
应用程序构建循环现在看起来更像这样:

The loop for collecting data while training an algorithm
通过这种方式,在图的左侧,您将得到:
- 即时回答(除非你有一群粘在电脑屏幕上的奴隶,回答一个给东西贴标签的问题可能需要一秒钟以上);
- 缩放(除非你统治的国家可以强制招募一群奴隶,这超出了本故事的范围;还有,我们不鼓励);
现在有问题吗?您的应用程序真的需要实时运行吗?如果你正在建造一辆自动驾驶汽车,答案是很可能是的,但是我们有那么确定吗?为什么某种自动驾驶的车辆不能由人驾驶(即使是远程驾驶)?
在大多数应用程序中,从质量控制到情感分析,实时是一个很大的优势,但如果开始时没有实时呢?真的会阻止你的应用被使用吗?
大多数情况下,机器学习应用的 MVP 应该避免实时处理。
一旦你设置你的应用程序来做这种人在回路中的方法,你只需要收集一段时间的数据,让你的数据科学家工作,同时已经满足了早期阶段的用户。
不要在这方面惨败!
即使我们鼓励这种方法,也有一个巨大的警告:如果你的机器学习算法从来没有工作过,你会悲惨地失败。因此,为了以这种方式执行事情,您必须确保能够在某个时候交付它!
然而,人类执行真实任务的主要优势是,在适当的条件下,你非常确定机器学习算法将最终赶上人类的精确度。为什么?
- 如果您的操作员在信息有限的情况下工作(即使用与你的算法相同数量的信息),那么你将非常确定你能找到相关的艺术状态来给你再保险。图像识别竞赛或 NLP 竞赛将让您大致了解这些任务有多困难。
- 如果您的操作员只接受了几分钟的示例培训,并且不需要专业知识来执行任务,那么对于机器学习算法来说,挑战可能不会太难。
- 通过建立这条管道,您将不得不机械地以一种既适合您的操作人员(因此也适合您的数据科学家;))并且可以在生产中复制,因为你已经在生产了。
这样做让我改变了我们在 NumeriCube 开发的大型计算机视觉应用的数据采集策略。这可能节省了数千小时的标签!
我们正在发布我们在 NumeriCube 用于日常计算机视觉项目的工具:视觉数据收集、注释、存储和管理。如果你喜欢这篇文章和/或想保持联系,我很乐意在评论中听到你的意见!










浙公网安备 33010602011771号