库尔、喀拉斯和张量流
代码可在 GitHub 上获得
用三个机器学习框架 Kur,Keras,Tensorflow 写的同一个模型的简单概述。用 TFRecords 探索张量流的数据管道。
大约一年前 Tensorflow 问世时,我和许多其他人一样,下载了它,并试图开始构建令人难以置信的机器学习模型,却发现这实际上是一件有点困难的事情。
事实证明,构建节点应用程序和构建 ML 模型的难度并不完全相同,但是围绕 ML 的工具似乎变得更容易使用,上周我又做了一次尝试。
我找到了 Kur ,由 DeepGram 的人构建,它提供了比 Keras 更高级别的 api,并且可以使用 Tensorflow 作为后端。我经常发现自上而下的学习更容易,Kur 的 yaml 模型定义看起来是如此的平易近人。
从 Kur,我挖到 Keras,然后 Tensorflow 建立了两个密集层的相同简单模型。
Keras Sine Wave Model
目标是建立一个模型来预测给定点是在正弦波之上还是之下。这很琐碎,但是知道每一行代码是什么是一个足够小的问题。这是数据的可视化,其中红色点属于正弦波的上方,蓝色点属于正弦波的下方。
Visualizing the data
库尔
Kur 的模型定义出现在一个 yaml 文件中。上面的模型是这样的:
Kur model Definition
培训、测试和评估都非常简单,他们网站上的教程非常精彩。这个框架真的不妨碍你快速训练和测试一个想法。如果需要的话,你总是可以用一个 kur 模型并在一个较低层次的 api 中对它进行编码,但是这似乎是我开始下一个项目的地方。
Keras
Keras 的 api 也很简单,但是您不需要在 yaml 文件中指定模型,而是编写普通的 python。Keras 中的相同模型定义如下所示:
Keras model definition
它的编码也很简单,并且在 Tensorflow 的 Tensorboard 中也有一些很好的挂钩(你可以在 GitHub 上找到它的实现),这让你不费吹灰之力就能得到清晰的损耗和准确度图表。
Accuracy from Tensorboard. over 98%!
张量流
我在 Tensorflow 中遇到的最大问题是将数据正确地输入到模型中。Tensorflow 自己的数据管道使用 TFRecords,这有很多好处,但也比将 numpy 数组塞进模型中更复杂。
TFRecords 的一个好处是,一旦你正确地设置了阅读器,它们可以被批量处理,并自动随机化。当数据集达到一定大小时,试图一次加载整个数据集会耗尽内存。
一旦管道建立起来,将数据塞进模型是一件痛苦的事情。我到处扔重塑的东西。当然,这部分是因为我对 python 缺乏经验,但是其他两个框架帮我解决了这个问题,真是太好了。
另一件要注意的事情是,Tensorflow 模型的准确性比其他两个框架差。这显然是我的一个错误,但是我对从 tf 记录中读取数据感到满意。这个问题阻止了我继续上一次的讨论,下一个项目可以更关注模型本身,解决一个更有趣的问题。
查看 GitHub 上的代码,希望它能为你节省一些设置数据管道的时间!
用于深度学习任务的 Kuzushiji-MNIST -日本文献备选数据集
加上我们的 VGG-雷斯内特系综模型与国家的艺术成果
MNIST 是一个拥有 70,000 张手写数字标记图像的数据集,二十多年来一直是图像处理和分类中最受欢迎的数据集之一。尽管它很受欢迎,但当代深度学习算法很容易处理它,经常超过 99.5%的准确率结果。一篇新的论文介绍了库祖什基-MNIST,一个比 MNIST 更难的备选数据集,同时还介绍了两个更难的库祖什基数据集。
有趣的是,Kuzushiji 数据集也可能有助于恢复一种几乎失传的语言——草书 Kuzushiji。草书 Kuzushiji 是一种使用了 1000 多年的日本文字,没有共同的标准,有时同一个词会有几十种风格和格式。在 19 世纪,日本改革了其官方语言和书写系统,并使其标准化,随着时间的推移,《文库世纪》灭绝了,导致数百万份日本文化和历史文件无法为大多数人所用。
数据集
Source: Clanuwat et al
数据集
日语可以分为两种体系:
- 标识系统,其中每个字符代表一个单词或一个短语(有数千个字符)。一个突出的标识系统是汉字,它是基于中文系统。
- 音节符号系统,其中单词由音节构成(类似于字母表)。一个突出的音节系统是具有 49 个字符的平假名(Kuzushiji-49),在 Kuzushiji 标准化之前,每个平假名字符有几种表示。
Kuzushiji 数据集包括汉字和平假名字符,基于 18 世纪 35 本书的预处理字符图像。它包括 3 个部分:
《字谜 MNIST》在格式上与原版《MNIST》相似,但由于每个汉字都有多种变化,分类难度更大。其他数据集包括更多的类,并基于人物在书中出现的频率,有些类只包括几个样本。
Source: Clanuwat et al
数据集可以从这里下载。作者计划扩大数据集并添加更多样本。
结果
Kuzushiji-MNIST 数据集的创建者通过训练一些分类算法并将其与 MNIST 进行比较,创建了一个基线。最好的算法(PreActResNet-18)在 MNIST 上达到了 99.56%,而在 Kuzushiji-MNIST 和 Kuzushiji-49 上分别只有 98.83%和 97.33%。
附加分析
为了评估 Kuzishiji-MNIST,我们比较了几种架构——VGG、ResNet-18、胶囊网络以及这些架构的组合。最好的结果是用 VGG 和雷斯内特的组合获得的——在测试集上有 98.9%的准确率,这是在新数据集上的最新结果
代码可以在这里找到。
结论
Kuzushiji 数据集可以作为分类算法的新基准系统,比传统的 MNIST 更具挑战性。如图所示,诸如 ResNet 和 VGG 等算法可以在库祖什基-MNIST 数据集上取得优异的结果,但在其他数据集上仍有改进的空间。最后,对库祖什基数据集的研究也可能有助于从这种失传的语言中恢复数百万本书籍。
L1 和 L2 正则化方法
机器学习
在我的上一篇文章中,我介绍了监督学习模型中的正则化。在这篇文章中,让我们回顾一些广泛使用的正则化技术以及它们之间的主要区别。
当数据集中有大量要素时,为了创建不太复杂(简洁)的模型,一些用于解决过度拟合和要素选择的正则化技术包括:
-
L1 正规化
-
L2 正规化
使用 L1 正则化技术的回归模型被称为 套索回归 ,使用 L2 的模型被称为 岭回归 。
这两者的主要区别在于刑罚期限。
岭回归将系数的平方值作为惩罚项添加到损失函数中。这里高亮显示的部分代表 L2 正规化元素。
Cost function
这里,如果λ是零,那么你可以想象我们回到了 OLS。然而,如果λ非常大,那么它将增加太多的重量,并且将导致装配不足。话虽如此,如何选择λ很重要。这种技术可以很好地避免过度拟合的问题。
Lasso 回归(最小绝对收缩和选择算子)将系数的大小的绝对值作为惩罚项添加到损失函数中。
Cost function
同样,如果λ为零,那么我们将得到 OLS,而非常大的值将使系数为零,因此它将欠拟合。
这些技术之间的关键区别是套索将不太重要的特征的系数缩小到零,从而完全删除了一些特征。因此,在我们有大量特征的情况下,这对于特征选择很有用。
交叉验证、逐步回归等处理过度拟合和执行特征选择的传统方法适用于小的特征集,但当我们处理大的特征集时,这些技术是很好的替代方法。
洛杉矶地铁自行车共享数据第 1 部分—纸浆线性优化
使用 Python 中的线性规划推导总收益最大化的定价方案
二次优化的第二部分 这里 。
随着 Bird 和 Lime 最近的大规模筹款活动,滑板车和自行车为城市交通增添了新的维度。
然而,在这些初创企业的宠儿到来之前,许多城市已经有了根深蒂固的自行车共享系统。其中最著名的包括花旗自行车纽约,Divvy,和资本自行车份额。
这个生态系统中的一个小得多的参与者是洛杉矶地铁自行车公司,该公司始于 2016 年,已记录了 58 万次骑行。之前他们因每 30 分钟 3.5 美元的价格而受到批评,最近他们因调整定价结构而成为头条新闻。
在这种新的结构下,每半小时的价格降低了 50%,为 1.75 美元。此外,基于时间的通行证现在也更便宜了。
虽然这一价格变化相当剧烈,但是否有更好的定价选择?Python 中的优化模型能对此有所帮助吗?我和 Shreenath Bhanderi 开始回答这些问题。
我们首先从洛杉矶地铁数据网站提取一年的自行车共享数据。然而,在我们开始优化 PuLP 之前,我们要经历通常的数据清理过程。
数据清理
我们看到,在过去的 4 个季度中,有超过 286,000 次乘坐。这些数据还为我们提供了关于使用了哪些自行车、起点和终点的位置以及每次骑行的长度的信息。
与大多数数据集一样,日期在读入时是字符串。我们运行一个快速的 pd.to_datetime 函数,将 start_time 和 end_time 列转换为 datetime 对象。
我们使用 missingno 包来检查数据帧中的 NA 值。由于缺失值的数量与观察值的总数相比几乎可以忽略不计,因此我们删除了这些行。
删除了大约 4849 行,占全部行的 1.7%。
填写自行车起止站数据
我们需要更多关于自行车站的详细信息,如码头数量和地址。为此,我们从洛杉矶地铁下载 json 文件,其中包括不同自行车站的地址和容量。
解析出相关字段后,我们获得 kiosk_id 来标识主数据帧中的站点、地址信息以及每个站点的停靠站数量。
然后,我们将该站数据与主数据帧合并两次,一次用于起点站,一次用于终点站。
再次快速查看 missingno 表明,大约有 20%的记录缺少电台信息。由于这是数据集的一个相当大的部分,我们可以仔细看看如何处理这些丢失的值。
由于填写车站的所有信息可能是一项繁琐的工作,所以让我们首先仔细看看车站周围的描述性统计数据。
最常见的起点站出现在 11,437 次乘坐中,而最不常见的起点站仅出现在 6 次乘坐中。我们应该只填充高于 2269 计数平均值的站点吗?
中值为 1544,看起来 2269 计数可能太高了。因此,我们将使用中位数 1544 来代替。只有高于 1544 计数的站点才会填入信息。
看一下码头的平均数和中位数,它们都在 22 左右,我们可以合理地用 22 来填充缺失的码头值。
通过创建一个掩码和快速过滤器,我们获得了一个可用于填充数据帧的站点 id 列表。
通过手动搜索和 Google API 的结合,我们获得了以下关于一些缺失站点的信息。
用 DataFrame 填充额外的站信息。在这里,我们再看一下 missingno 矩阵。
在删除最后的空值后,我们获得了一个包含 250,513 条记录的数据帧。在填写一些地址细节后,我们获得了大约 25,000 个额外的值。
活动自行车
另一个值得注意的话题是洛杉矶地铁自行车车队的利用。
虽然所有的自行车在过去的一年里都是活跃的,但大约 1259 辆或大约 86%的自行车在过去的一个月里至少使用过一次。这似乎是一个相对健康的数字,但是实际的利用率和库存分析将在本系列的下一部分进行。
现在,我们确定在过去 6 个月中闲置的自行车,并在另一列中将其编码为 0。上个月活跃的自行车得到 1 分。
虚拟变量
数据集还包括多个分类变量。稍后可能特别感兴趣的两个是护照持有者类型和旅行类别。
在这里,我们为两者创建虚拟变量列,并将它们连接到主数据集。
30 分钟时间段的计数
鉴于洛杉矶地铁自行车的定价系统是基于用户在自行车上花费了多少 30 分钟的时间,将编码一个额外的列来计算每个乘客在一次旅行中花费的 30 分钟时间。
鉴于通行证持有者在乘车的前 30 分钟是免费的,他们将比无电梯乘车者少付费一个时间段。
随着数据集在很大程度上得到清理并添加了额外的功能,我们可以开始解决优化问题。
定价计划优化
定义优化目标和限制
这一优化的目标是使洛杉矶地铁自行车的总收入最大化。对于这种线性优化,我们将利用纸浆库。
收入的两个主要来源是:
- 所有乘坐的总票价
- 通行证销售总额(每日、每月、每年)
洛杉矶地铁可以通过改变定价结构或改变提供的计划来增加总收入。
洛杉矶地铁自行车最近实施了如下新的价格结构。以前的计划和现在的计划如下:
为了得出适当的价格与需求关系,必须对进一步的需求模型进行估计。然而,要在优化中考虑价格和数量的关系,需要一个二次公式。这将在下一篇文章中通过 SciPy 和 CVXOPT 来完成。
对于简单的线性模型,我们试图回答两个关键问题:
- 洛杉矶地铁是否应该维持现有的每日、每月和年度计划体系,以实现收入最大化?
- 在以前和新的价格结构中,这种情况如何变化?
估算每种通行证类型的售出通行证数量
我们将要求估算每种通行证类型的售出数量,以估算总收入。我们首先看一下一些聚合指标:
由于我们没有针对通行证持有人的唯一标识符,我们参考洛杉矶地铁自行车的数据页面来了解已经售出了多少通行证。
自 2016 年 7 月成立以来,已经完成了约 575,281 次行程,售出了 42,870 张通行证,预计在长达一年的分析期间,将售出约 20,000 张通行证。
我们将从盈亏平衡的角度估计每种通行证的销售额。支付一张通行证的价格平均需要多少次旅行?
由于大多数行程(> 60%)是从地铁站出发的“最后一英里”行程,行程的中位持续时间为 12 分钟,我们对 30 分钟以下的行程进行了以下盈亏平衡分析。
通过使用当前和以前的票价和通行证费用的平均值,我们得出以下结果:
Rides per day required for daily pass: 2.0
Rides per month required for monthly pass: 5.714285714285714
Rides per year required for annual pass: 22.857142857142858
看看保本所需的乘车次数并评估这些数字,这些数字似乎偏低。
如果购买每日通行证,每日通行证持有者可能会进行多次往返旅行。
月票持有者可能是偶尔的通勤者,即使是保守的每周 2 次乘车上班,一个月也要 8 次。
How often do you bike to work?
由于上一个定价计划中弹性点的价格为 40 美元,因此年度通行证持有者最难衡量。目前,它们将被缩放到与日和月票号码相同的因子。
将每日乘车次数提高到保守的 3 次乘车次数会增加 50%,而将每月乘车次数提高到保守的 8 次乘车次数会增加 40%。对于保守的估计,我们将这三个估计值按 40%的公共因子进行缩放。
Rides per day required for daily pass (scaled): 2.8
Rides per month required for monthly pass (scaled): 8.0
Rides per year required for annual pass (scaled): 32.0
因此,通过将每种票类型中的总乘车次数除以达到盈亏平衡所需的平均乘车次数来计算估计售出的票,得出以下结果:
Estimated passes sold for daily pass: 5229
Estimated passes sold for monthly pass: 18317
Estimated passes sold for annual pass: 287
Total passes sold: 23833
在此期间售出的入场券总数估计约为 23 833 张。这与我们先前估计的 20,000 人大致相符。
现在让我们为这个优化模型公式化目标函数,以最大化来自通行证销售和乘坐的总收入。
总收入可分为以下几部分:
- 来自无预约用户的总收入= 30 分钟使用价格*无预约用户的 30 分钟总块数
- 日通票、月通票用户的总收入= 30 分钟的使用价格*前 30 分钟免费后的 30 分钟总时长
- 销售门票的总收入=相应门票的价格*相应门票类型中售出的门票总数
现在可以进行一个快速计算,看看我们当前的总收入是多少,以及过去一年售出的门票的估计数量。
这里使用旧的定价方案来估算价格。在这里,年卡持有者每年支付 40 美元购买年卡,每半小时支付 1.75 美元。前半小时不是免费的。
Total revenue: $ 961,924.5
现在我们可以用纸浆来表示这个目标函数。
纸浆线性优化
在 PuLP 中,一个易于遵循的线性规划框架如下:
- 引发纸浆问题
- 定义决策变量
- 形式目标函数
- 表单约束
- 解答和解释
为了回答我们之前提出的两个关键问题,我们需要两个独立的纸浆模型。一个包含以前的定价结构,另一个包含当前的定价结构。
1。引发纸浆问题
这里,我们在 PuLP 中创建一个 LpProblem,并用 pulp.LpMaximize 将其设置为一个最大化问题。
2。定义决策变量
为总共 6 个二元变量创建 3 对决策变量。每一对表示是否实现一个传递类型的“是”和“否”决定。
例如,month_yes 表示应该出售月票,month_no 表示不应该出售月票。
3。表单目标函数
现在我们需要为这个优化模型制定关于总收入的目标函数。
我们当前总收入的细分如下:
- 按半小时收费的无电梯总收入。
- 每个套票类别的游乐设施总收入。如果我们取消特定的传递类型,则值为 0。
- 如果取消套票,每个套票类别的替代定价总收入。如果我们维护特定的通行证类型,则值为 0。
- 出售门票的总收入。如果我们取消传递类型,则值为 0。
关于取消通票类型的替代定价,我们假设乘车将按无电梯收费。
鉴于乘客已经在抱怨每小时 3.50 美元的轮挡费用,在过去的定价方案中,任何通行证的减少都会导致乘客数量的急剧下降。此外,鉴于自行车和滑板车共享领域的激烈竞争,某些通行证的掉落可能会导致车手转向其他竞争者。
我们假设每个类别的基线磨损为 30%,并在运行模型时调整参数。
用 Python 表示每个收入流,我们得到了以下结果:
然后,我们将其添加到纸浆模型中。
4。形式约束
然后,我们必须定义额外的约束,使得每个二进制对中只有一个决策变量可以并且必须是真的。
例如,二进制变量 month_yes 和 month_no 可以表示 0 或 1。这两个变量的总和不能是 0 或 2,因为这意味着不可能同时实施和不实施月度计划。
我们通过将总和设置为 1 来实施这个约束。
5 .解析
让我们看看我们的模型现在是什么样子:
Revenue Maximization Previous:
MAXIMIZE
26602.1*annual_no + 30481.5*annual_yes + 94366.65*day_no + 78387.75*day_yes + 405700.39999999997*month_no + 399696.75*month_yes + 626132.5
SUBJECT TO
_C1: day_no + day_yes = 1
_C2: month_no + month_yes = 1
_C3: annual_no + annual_yes = 1
VARIABLES
0 <= annual_no <= 1 Integer
0 <= annual_yes <= 1 Integer
0 <= day_no <= 1 Integer
0 <= day_yes <= 1 Integer
0 <= month_no <= 1 Integer
0 <= month_yes <= 1 Integer
使用 model.solve()求解模型,我们得到了以下解:
Status: Optimal
Optimal Solution to the problem: 1156681.05
Individual decision_variables:
annual_no = 0.0
annual_yes = 1.0
day_no = 1.0
day_yes = 0.0
month_no = 1.0
month_yes = 0.0
上述解决方案可以这样理解:
- 取消日票和月票。
- 维护年度通行证。
- 总收入将为 1,156,681.05 美元
如果任何通行证被取消,减员率为 30%,即得出了这一结论。事实是,不同通行证的流失率会有所不同。
例如,那些持有年度通行证的人不太可能磨损,因为他们可能是最需要使用自行车的人。
在调整了一些参数和损耗率后,我们得出以下结论:
- 如果取消计划的自然减员率高于 41%,则应保留日间计划。
- 如果取消计划的流失率高于 31%,则应保留每月计划。
- 如果取消计划的自然减员率高于 19%,则应保留年度计划。
按照这些边际损耗率计算的总收入为我们带来了优化的 1,136,357 美元总收入。
由于洛杉矶地铁此前一直收取 3.50 美元的高价,这些高流失率是有道理的。如果假设自然减员率为 30%,且洛杉矶地铁取消了月度计划,他们将能够通过向剩余的 70%的乘客收取步行费率来获得收入。
现在让我们对当前的定价重复同样的方案,费率减半。
由于新的年度定价方案与以前的年度(flex)通行证完全不同,并且在数据中单独列出,我们保持 40 美元的年度通行证价格。目前 150 美元的价格被考虑到以后的优化中。
我们得到了以下解决方案:
Status: Optimal
Optimal Solution to the problem: 1053249.14
Individual decision_variables:
annual_no = 1.0
annual_yes = 0.0
day_no = 0.0
day_yes = 1.0
month_no = 0.0
month_yes = 1.0
考虑到将半小时费率减半至 1.75 美元的严厉措施,如果任何计划被取消,自然减员也不太可能如此之高。
此外,当前的最佳解决方案表明,即使没有损耗,我们可以按加价向每个通行证持有者收费,也应该保留每日和每月通行证。
另一方面,年度计划只有在超过 25%的年票持有者因计划取消而流失的情况下才能保留。考虑到年卡持有者最不容易发生摩擦,因为如果他们支付了年卡费用,他们可能确实需要通勤服务,洛杉矶地铁最近决定取消这一年度(弹性)计划很可能是正确的举措。
虽然 PuLP 只能处理简单的线性优化,但是还有许多其他强大的库,比如 CVXPY、IPOPT 和 SciPy。
在下一篇文章中,我用一些需求曲线估计来解决二次优化问题,看看洛杉矶地铁自行车的其他定价方案。
感谢您的阅读,您可以在 Github 上查看笔记本,并在 LinkedIn 上联系!
洛杉矶地铁自行车共享数据第 2 部分—使用 SciPy 进行二次优化
使用 SciPy 分析最近的价格变化并找到最佳价格组合
在第 1 部分中,我们清理了数据集,并通过 pulp 运行了一个简单的线性优化模型。正是在撰写第一部分的最后,洛杉矶地铁自行车的 2018 年第三季度数据公布。
这可能只是一个额外的数据点,但我们现在可以拟合一个基本的线性需求曲线,用于模型约束,以允许价格和需求波动。
在我们得到这些曲线之前,我们先确定一些用于后续分析的常数。
竞争基准
其他多家运营商最近也进入了自行车/滑板车共享市场。像 Bird、Lime 和 Jump 这样的名字应该是生活在洛杉矶地区的大多数人所熟悉的。
从竞争对手的角度来看,定价方案有多种构建方式。我们可以实施和比较的一些选项如下:
- 每分钟可变利率
- 按时间间隔可变费率(目前洛杉矶地铁为 30 分钟)
- 任何乘坐的固定费用
- 在实施可变费率之前的一段时间间隔内的固定费用
- 涵盖特定时间内所有游乐设施的周票、月票。此后可变利率
为了与其他自行车和踏板车运营商的定价进行比较,让我们为所有运营商绘制不同的定价曲线。
纵观洛杉矶自行车和踏板车运营商的不同定价方案,洛杉矶地铁刚刚颁布的当前定价绝对是最便宜的,一小时的自行车骑行价格为 3.50 美元。
下一个最便宜的选择是 Lime 踏板自行车,它比洛杉矶地铁的 walk on riders 便宜,骑行时间不到 15 分钟,骑行时间在 30 到 50 分钟之间。
因此,我们将设置价格上限,并在优化模型中将其用作常数:
- 无通行证每分钟可变费率设置在 0.05 美元和 0.15 美元这两个最常见价格的平均值之下:
无通行证每分钟可变费率<= 0.10 美元 - 有计划的每分钟可变费率设置在洛杉矶地铁当前的 0.06 美元和 Jump 的 0.07 美元的平均值之下:
有通行证的每分钟可变费率<= 0.065 美元 - 每 30 分钟变化率设置在最近的竞争对手(石灰踏板)下:
每 30 分钟变化率< = $2.5
总需求曲线
2018 年 Q2 是价格变化前的最后一个数据点,2018 年第三季度是之后的第一个数据点。我们将 y 设为每 30 分钟乘车的价格,x 设为该季度乘车的总次数。
使用简单的斜率估计,我们得到以下结果:
The linear function from two data points is:
y = -9.762356353899364e-05 x + 11.05186600468593
Where y = price for half hour block
x = rides in fiscal quarter
按客户细分的需求曲线
如果我们按客户细分细分需求会怎么样?
我们首先创建 2018 年 Q2 和 2018 年第三季度的分组表格。
Left: 2018 Q2 figures, Right: 2018 Q3 figures
我们可以看到新的年度通行证还没有完全流行起来,在通行证季度仅售出 12 张通行证。150 美元的价位可能有点高。
有趣的是,价格下降并没有真正影响到任何通票持有者,但却使无电梯乘客的数量增加了一倍。
让我们看看其他需求曲线是什么样的。
Walk up demand function estimate
The linear function from two data points is:
y = -9.159905783826223e-05 x + 5.871041612143418
Daily pass demand function estimate
The linear function from two data points is:
y = 0.006183745583038869 x + -27.542402826855124
Monthly pass demand function estimate
The linear function from two data points is:
y = 0.026923076923076925 x + -1181.9769230769232Annual(Flex) pass demand function estimate
The linear function from two data points is:
y = 0.0020759193357058124 x + -1.5237247924080664
有趣的是,一条典型的负斜率需求曲线只出现在步行骑车者身上。鉴于费率从 3.50 美元大幅降至 1.75 美元,似乎许多乘客只是开始成为无电梯乘客,而不是购买通行证。由于通行证价格的下降与半小时费率的下降不成比例,因此放弃通行证变得更加经济。
基本二次优化模型
我们从定义目标函数开始,就像在纸浆中一样。
当我们在 PuLP 中将所有模型组件“添加”到一个问题中以创建模型时,SciPy optimize 只需要为目标函数和各种约束创建函数,然后将它们作为参数传递给 minimize 函数。
由于二次优化问题自然是一个极小化问题,所以我们将总收入返回为带负号的’-total_revenue ',以获得最大值。
还要注意的是,目标函数中只有一个参数,你初始化的每个变量都是从这个列表中传递过来的。
约束同样被定义为单个变量具有相同索引的单个函数。
然后创建一个字典来标记约束的类型并列出所有单独的约束。
界限由元组表示。例如,b1 将代表收费率的上限和下限。1.5 代表速率的下限,2.5 代表速率的上限。
b2 代表总乘坐次数的范围。上限为 140,000,鉴于目前的市场形势,总乘坐次数翻倍似乎不现实。
然后将边界添加到一个元组中,作为函数参数传递给 minimize 函数。
x0 指的是你对变量的最初猜测。在这里,我们选择当前的定价和总乘坐价值作为我们的初步猜测。
一旦创建了所有函数参数,我们就可以将它们传递给 optimize 中的 minimize()函数。
fun: -1623030.3308773183
jac: array([-5.59883906e+04, -1.65781250e+01])
message: 'Optimization terminated successfully.'
nfev: 41
nit: 10
njev: 10
status: 0
success: True
x: array([1.50000000e+00, 9.78438571e+04])
根据这一优化,当价格设置为每半小时 1.50 美元时,收入似乎得到了优化。这将使总乘坐次数增加到 97,844 次。
总收入将增加到 1 623 030 美元。
似乎负需求斜率意味着将价格降至下限是最有效的收益最大化策略。
如果我们调整变量的界限呢?如果允许最低价格进一步降至 1 美元以下会怎样?如果竞争比预期更激烈,最大乘坐增长限制在 100,000 次以下,会怎么样?
我们将下列界限添加到灵敏度分析中:
循环上述价格和附加条款范围的所有组合,我们获得以下总收入数字:
Total rev | Rate | Total riders | Rate range | Rider range
1678530 1.0 102966.0 (1, 2.5) (50000, 140000)
1678530 1.0 102966.0 (1, 2.5) (50000, 120000)
1651146 1.0 100405.0 (1.25, 2.5) (50000, 140000)
1651146 1.0 100405.0 (1.25, 2.5) (50000, 120000)
1646752 1.0 100000.0 (1.25, 2.5) (50000, 100000)
1646752 1.0 100000.0 (1, 2.5) (50000, 100000)
1623030 2.0 97844.0 (1.5, 2.5) (50000, 140000)
1623030 2.0 97844.0 (1.5, 2.5) (50000, 120000)
1623030 2.0 97844.0 (1.5, 2.5) (50000, 100000)
1594182 2.0 95283.0 (1.75, 2.5) (50000, 140000)
1594182 2.0 95283.0 (1.75, 2.5) (50000, 120000)
1594182 2.0 95283.0 (1.75, 2.5) (50000, 100000)
1372815 2.0 80000.0 (1.75, 2.5) (50000, 80000)
1372815 2.0 80000.0 (1.5, 2.5) (50000, 80000)
1372815 2.0 80000.0 (1.25, 2.5) (50000, 80000)
1372815 2.0 80000.0 (1, 2.5) (50000, 80000)
根据给定的需求曲线,似乎采用 1 美元的最低可能价格会导致最多 102,966 次乘坐。它还会产生最高收入 1,678,530 美元。
总的来说,似乎只要我们能够吸引 10 万次以上的乘坐,策略应该是降低价格。鉴于我们在这里看到的,也许从以前的定价方案大幅下降 50%是合理的。
如果我们创建一个基于分段需求曲线的新模型会怎么样?公式化的约束如下所示:
由于之前的年票/灵活票被取消,年票的需求曲线可能不再相关。
重新制定目标和解决这个新的方程产生了一个较低的无电梯乘车的最优价格和一个接近价格上限的其他组的价格。
但是,对于每次迭代,我们都会获得以下消息:
message: 'Positive directional derivative for linesearch'
success: False
看起来,使用我们当前的公式,优化器无法找到一个下降方向来足够快地降低目标函数。最终,这意味着结果不可能是最佳的。
鉴于每种通行证类型的粗略需求估计,等待更多新价格数据出来以适应不同细分市场的更好需求模型将是有益的。
此外,模型公式的改进可以帮助我们整合其他可变数据,如我们上面确定的基于分钟的定价。
Maybe for the next project.
在下一部分中,我们将从清理后的数据集中查看更多基于地理的数据和库存。感谢阅读!笔记本可以在 Github 上找到,也可以在 LinkedIn 上随意连接!
用谷歌视觉 API 标记 instagram 照片
今天我将使用谷歌云视觉分析 instagram 图片
方法
主要涉及两个技术步骤:
由于关于 RoogleVision 和 instaR 的操作方法已经在这里和这里介绍过了,这两者都涉及到设置开发者账户和认证,所以我将重点介绍使用它们的体验和结果。
观察结果
我学到的一件事是,instagram 只允许在沙盒模式下抓取 20 张最新照片,除非你提交应用程序进行审查。此外,如果你使用的是“轮播”模式,在一篇文章中汇集几张照片,instaR 将只下载封面图片。由于我不经常发 instagram,这就涵盖了过去 3 个月的照片,也让我对我发布的内容有了更好的理解。
结果
labelled instagrams
一些观察结果:
- 该 api 正确地标记了大多数照片,除了非常抽象的照片,如沙滩上的沙子(标记为纹理)。谷歌视觉 API 更关注标签、颜色组合等,似乎不提供字幕
- 标签检测算法将返回几个最高概率的排序结果。具有预支配色块的图片更多地被标记为颜色而不是物体,即,穿红色衣服的人被标记为“红色”作为第一标签,而“面部表情”作为第二标签
- 还有一张复杂的照片没有标注。这张照片包含一幅 3D 壁画和食物。壁画似乎很难让图像识别 api 理解
- 我想量化我通常拍摄更多的主题,但是考虑到 20 张照片的限制,我只能说我有关于花和天空的重复帖子
这是我关于数据科学和视觉故事的# 100 日项目的第 45 天。我的 github 上的全部代码。感谢阅读。欢迎新主题的建议和反馈。
基于深度学习的土地利用/土地覆盖分类
Land use classes
在环境监测和许多其他子领域中,识别地球表面的物理方面(土地覆盖)以及我们如何开发土地(土地利用)是一个具有挑战性的问题。这可以通过实地调查或分析卫星图像(遥感)来完成。虽然进行实地调查更加全面和权威,但这是一个昂贵的项目,而且大多需要很长时间来更新。
随着最近航天工业的发展和卫星图像(免费和商业)可用性的增加,深度学习和卷积神经网络在土地利用分类方面显示了有希望的结果。
在这个项目中,我使用了免费提供的 Sentinel-2 卫星图像对 9 个土地利用类别和 24000 张带标签的图像进行了分类(图 2)。原始数据集包含 10 个类和 27000 个带标签的图像,可从这里获得。
Figure 2— Land use classes
这里有一些不同土地利用类型的可视化图像。
Figure 2- Visualization
Sentinel-2 的数据是多光谱的,在可见光、近红外和短波红外光谱中有 13 个波段。这些波段具有不同的空间分辨率,从 10 米到 60 米不等,因此图像可被归类为高-中分辨率。虽然有其他分辨率更高的卫星可用(1 米至 0.5 厘米),但 Sentinel-2 的数据是免费的,重访时间长(5 天),这使它成为监测土地利用的最佳选择。
Sentinel-2 Bands, Wavelength, and Resolution
数据预处理
虽然一些深度学习架构可以将所有 13 个波段作为输入,但有必要对数据进行预处理。这些图像是 TIFF 格式的,我尝试的一些架构不能适应它。我选择使用 GDAL 和 Rasterio,这是我最喜欢的工具,也是我最熟悉的工具,将它们转换成 JPG 格式并选择乐队。gdal_translate 成功了。
gdal_translate -of GTiff -b 1 -b 10 -b 13 input_sentinel_13_band.tif output_RGB.tif
这些是我尝试过的一些乐队组合:
- 所有 13 个乐队
- 红、绿、蓝(RGB)波段
- 短波红外线(SWIR)
- 高分辨率波段(10-20 米波段)
- 特殊波段组合——遥感领域的知识很有帮助。一些波段组合可以引出农业、植被、水或土地。
- 使用不同组合的数据增强(即具有特殊波段的 RGB)
建模
我用 Fastai 库的迁移学习(Resnet50)来训练我的模型。感谢 Fastai 团队令人惊叹的深度学习课程,这里使用的技术来自深度学习课程材料。我训练模型的步骤是:
- 训练最后一层
- 试试数据扩充
- 冻结所有层并从头开始重新训练
建模中使用的技术包括:学习率查找器、带重启的随机梯度下降和退火。
结果
正如在预处理部分提到的,我已经试验了不同的波段组合。我的模型的最高精度为 0.94,虽然这低于原始论文中报告的数据集的精度(0.98),但对于我的项目及其目标来说,这是相对较高的。我所有实验的结果都在下表中(对关键要点的思考部分):
+------------------------+-----------------------------+
| Bands | Result(Accuracy) |
+------------------------+-----------------------------+
| All Bands | 0.83 |
| RGB | 0.84 |
| High Resolution Bands | 0.81 |
| **Special Bands** | **0.94 ** |
| RGB+Special Bands | 0.80 |
+------------------------+-----------------------------+
模型发现难以区分的一些类别是森林和海湖,如混淆矩阵所示(图 3)。仔细观察这两类的图像,人们可以推断,即使是人眼也很难清楚地区分。
Figure 3 — Confusion Matrix
关键要点:
波段组合的领域知识有助于改进这一特定模型。我在土地利用/土地覆被分类的深度学习应用中看到的所有文献都使用相同的波段作为所有的类输入(即 RGB 或 SWIR)。我的方法让我提高了将近 10%的准确率。
虽然我假设更多的波段肯定会改善我的模型,但我发现事实并非如此。使用所有 13 个波段效果不佳。这可归因于包含了低分辨率波段。但同样,仅使用高分辨率波段的精度最低(0.81)。
另一个实验是通过将 RGB 图像和特殊波段组合添加到同一个文件夹中来增加数据集,从而使可用于训练的图像数量翻倍。这个精度最低(0.80)。笔记本在这里可用。
利用深度学习进行车道检测(第一部分)
这是我的车道检测深度学习解决方案的第一部分,涵盖了我之前方法的局限性以及使用的初步数据。第二部分可以在这里找到*!它讨论了我创建的各种模型和我的最终方法。这里和后面帖子中提到的代码和数据可以在我的*Github repo中找到。
即使在各种各样的条件下,人们也可以相当容易地找到道路上的车道线。除非有雪覆盖地面,降雨量非常大,道路非常脏或年久失修,我们可以告诉我们应该去哪里,假设这些线实际上是有标记的。虽然你们中的一些人可能已经想挑战其他司机是否真的成功地保持在线内(特别是当你想超越他们的时候),即使没有任何驾驶经验,你也知道那些黄线和白线是什么。
另一方面,计算机发现这并不容易。阴影、眩光、道路颜色的微小变化、线路的轻微阻塞……所有这些人们通常仍然可以处理,但计算机可能会与之进行激烈的斗争。这当然是一个有趣的问题,以至于在 Udacity 的无人驾驶汽车纳米学位的第一期,他们将五个项目中的两个集中到了这个问题上。第一个是一个很好的介绍,用来向学生介绍一些基本的计算机视觉技术,如 Canny 边缘检测。
Canny Edge Detection
第二次,在学期的第四个项目中,我们做得更深入一点。这一次,我们使用了一个叫做透视变换的概念,它将图像中的某些点(在这种情况下,是车道线的“拐角”,从图像的底部,车道在汽车下方延伸到地平线附近的某个地方,这些线在远处会聚)延伸到目的地点,对于道路来说,这使你看起来像是一只在头顶上飞行的鸟。
Perspective Transformation of an Image
在透视变换之前,可以使用梯度(当您穿过图像时像素值的变化,如黑暗的道路变为亮线的地方)和颜色阈值来返回二进制图像,只有当这些值高于您给定的阈值时,才会激活该图像。透视变换后,可在线上运行滑动窗口,以计算车道线曲线的多项式拟合线。
The ‘S’ channel, or Saturation, with binary activation
A few more thresholds (left) for activation, with the resulting perspective transformation
Sliding windows and a decent-looking result
这看起来一开始还不错,但是有一些很大的限制。首先,透视变换对于摄像机(在变换之前也需要单独保持不失真)、摄像机的安装,甚至汽车所在道路的倾斜都是相当特定的。其次,各种渐变和颜色阈值仅在一小部分条件下起作用——我在开始时提到的计算机在查看车道线时遇到的所有问题在这里变得非常明显。最后,这种技术很慢——我用来将预测的车道检测返回到视频的技术只能以大约每秒 4.5 帧(fps)的速度运行,而来自汽车的视频可能会以大约每秒 30 帧或更高的速度运行。
When Lane Detection Goes Wrong
SDCND 第一学期的其他两个项目专注于深度学习,在这些情况下,用于交通标志分类和行为克隆(让虚拟汽车根据输入的图像以特定角度转向,在训练它时复制你的行为)。五个项目中的最后一个也可能通过深度学习来实现,尽管主要方法使用了不同的机器学习技术。我实际上一直在推迟我的独立机器学习纳米学位的顶点项目,特别是为了尝试在车道检测上使用深度学习方法,现在我已经完成了所有这些项目,包括车道检测和深度学习,这似乎是尝试我的顶点的完美时间。
数据
我的第一个决定,也许是最关键的(不幸的是,也许也是最耗时的),是决定创建我自己的数据集。尽管有很多数据集被用于训练潜在的无人驾驶汽车(几乎每天都在增加),但它们大多没有根据汽车自己的车道进行标记。此外,我认为创建一个足够精确的数据集来训练深度神经网络将是一个有趣而有益的挑战。
收集数据很容易。我住在加州圣何塞,有很多地方我可以开车去。我从我以前的深度学习项目中知道大型数据集有多重要,但也许更重要的是,拥有一个平衡的数据集有多重要。晚上,在雨里,我沿着山坡上非常弯曲的道路,在高速公路和岔路上行驶,到达一个最喜欢的徒步旅行点(幸运的是,当我去收集这些数据时,加利福尼亚的干旱完全逆转了)。虽然听起来可能不多,但我最终用了近 12 分钟的驾驶时间,相当于 21,000 多张单独的图像帧,全部来自我的智能手机。
在找到提取图像帧的好方法后,我几乎立刻就注意到了一个问题。虽然我在明亮条件下驾驶较慢的视频主要由高质量的图像组成,但夜间高速公路驾驶和在雨中驾驶有大量模糊的图像(我将夜间高速公路驾驶问题归咎于圣何塞高速公路的颠簸,正如我的手机在黑暗中的问题一样)。我必须逐个浏览每一张图片,否则我的神经网络可能永远也学不会任何东西。我突然减少到 14,000 张图像,仍然故意留下一些稍微模糊的图像,希望能够在未来进行更强大的检测。
An example of poor data obtained and removed. The trained model, that never saw this image, actually did okay in later predicting the lane for this frame!
为了真正标记我的数据集,我计划仍然使用我的旧的基于计算机视觉的技术。这意味着通过我的旧算法运行图像,而不是输出顶部绘制有预测车道的原始图像,而是输出六个多项式系数,或者每条车道线三个(即方程 ax +bx+c 中的 a、b 和 c)。当然,如果我只是打算在标记中纯粹使用我的旧算法,我只是打算训练我的神经网络来解决与旧模型相同的问题,并且我希望它更健壮。我决定用单色手动重新绘制真实车道线(我选择了红色),这样我可以使用红色通道阈值来更好地检测车道线。在短暂的疯狂时刻,我原本以为我会为 14,000 张图片这样做,但很快意识到这将花费太长时间(除非我像 comma.ai 一样幸运/人脉广泛,可以众包我的标签)。相反,考虑到时间对数据的影响(如果我低速输入几帧内的图像,模型可能会“窥视”自己的验证集,因为预计变化很小),我决定只对十分之一的图像进行这一过程,从而创建了一个由 1,400 幅训练图像组成的早期集。
Drawing over some blurry lines. Given the final model’s ability to still detect lines even in blurry night images, it appears this method did assist in robustness.
此时,我创建了一个程序,可以在道路图像上使用我的旧的基于 CV 的模型,检测线多项式,并使用多项式重新绘制线,类似于我在以前的项目中所做的。这保存了每个生成的图像,所以我可以检查哪些是不够的标签。我注意到了一个直接的问题——尽管我给老款车提供了大量弯曲的道路,但它几乎无法正确检测所有这些道路上的线条。我输入的 1400 张照片中,有近 450 张无法使用,其中大部分是曲线。
然而,我意识到这是由于原始方法本身的性质,由于其滑动窗口的工作方式。如果车道线偏离了图像的一侧,原始的滑动窗口将继续在图像上垂直向上,导致算法认为这条线也应该朝着那个方向绘制。这是通过检查窗口框是否接触到图像的侧面来解决的——如果是,并且窗口已经在图像上前进了一点点(防止模型在开始时完全失败,如果窗口一开始就靠近侧面的话),那么滑动窗口就会停止。**
The original sliding windows on a curvy road, versus cutting the window search at the edge (also more windows)
成功了!我将失败率减半,从最初的 450 张图像减少到 225 张。他们仍然有很多极端的曲线在这里失败,所以我想检查一下标签的实际分布情况。我这样做是通过使用直方图实际检查六个系数中每一个的分布。我又一次失望了。数据仍然过于偏向直线。我甚至回去添加了额外的图片,这些图片来自我拍摄的弯道视频。当我看这些照片时,问题仍然很明显——即使在非常弯曲的道路上,大多数车道仍然相当直。
The original distribution of one of the lane line coefficients — too heavily centered around straight lines
在我的独立交通标志分类项目中,一个很大的不同之处是,通过对数据中几乎没有表示的任何交通标志类别添加原始图像集的小旋转,创建了“假”数据。再次使用这种方法,对于某个分布范围之外的任何系数标签(我迭代了大约外部 400、100 和 30 个图像,这意味着最外部实际上经历了过程 3X),图像稍微旋转,同时保持相同的标签。
The more well-distributed data for a single line coefficient after adding image rotations for the curvier data
经过这一过程后,每个系数的数据分布终于稍微均匀了一些。我还为我的图像和标签使用了一些其他的快速预处理项目。训练图像从最初的 720 x 1280 重新调整了大小(我最终尝试了缩小 4 倍、8 倍和 16 倍的不同版本)并进行归一化(这有助于模型的最终收敛)。我还使用 sklearn 的 StandardScaler 标准化了标签(如果你这样做,请确保保存了 scaler** ,这样你就可以在你的模型结束时反转它了!).这种标签的标准化可能会欺骗你一点,因为训练中的损失会自动降低,但我发现当绘制到图像上时,最终结果也更加令人印象深刻。**
我终于准备好创建和训练一个模型。
准备好第二部分了吗?在这里 阅读关于我的车道检测模型 。
基于深度学习的车道检测(下)
这是我的车道检测深度学习解决方案的第二部分,涵盖了我在寻找问题的最终解决方法时创建的实际模型,以及一些潜在的改进。请务必阅读第一部分*,了解我之前方法的局限性以及在我做出以下更改之前使用的初步数据。这里和之前帖子中提到的代码和数据可以在我的*Github repo中找到。
创建了一个不错的数据集,我准备好制作我的第一个使用深度学习来检测车道线的模型。
透视变换模型
你可能会问,“等等,我还以为你是想摆脱透视变换呢?”这是事实。然而,为了创建一个初始的模型架构,我想检查一下,在数据集有些有限的情况下,深度学习是否可以学习做与基于 CV 的模型相同的事情。因此,这里的输入是透视变换的道路图像,由此神经网络学习系数似乎更容易,这似乎是合乎逻辑的。
我在这里使用了一个与我之前在行为克隆项目中使用的类似的模型架构,包括一个批量标准化层,接着是一些卷积层、一个汇集层、扁平化层和一些全连接层。对于要预测的车道线系数的数量,最终全连接图层的输出大小为 6。我还使用了 Keras 的 ImageDataGenerator 来尝试使模型变得健壮(主要是额外的旋转、高度移动和垂直翻转——水平翻转让我担心,因为标签真的需要更改才能准确描绘线条信息)。经过一点微调(模型架构、参数和输入图像大小),模型产生了一个良好的结果,但是它非常严格地依赖于输入和输出的透视变换——它根本不能很好地概括。
道路图像模型
在发现深度学习可以与我的数据集一起工作后,我接着着手创建了一个模型,它可以在没有任何透视变换的情况下接收道路图像。我使用了与之前完全相同的架构,除了添加了一个裁剪层来剪切图像的上三分之一。我的预期是,任何给定道路图像的顶部三分之一很少包含检测车道所需的信息。该模型很容易收敛到与透视变换模型相似的结果,所以我知道我可以抛弃对输入到模型的原始图像进行透视变换的需要。
在这一点上,我想使用不同于我自己手机的相机给我的模型一些额外的数据(考虑到不同的相机失真),所以我给了它一些来自我之前项目的 uda city常规项目视频的帧。然而,这里的问题是为这些数据创建新的标签——我为标记我自己的数据所使用的透视变换与这个单独视频的不同。这也让我意识到我最初如何处理这个问题的一个巨大问题——从鸟瞰的角度来看,标签本身是多项式系数,这意味着在预测和绘制车道之后,车道仍然需要逆变换回原始图像的角度。
这导致了一个似乎很难概括的模型,但通过查看我自己的一个视频中产生的结果,我意识到,也许该模型仍然正确地检测到线条,只是由于预测后仍在使用透视变换,所以无法再现良好的视觉结果。model 看起来似乎在视角不同的地方遇到了麻烦(在单独的 Udacity 视频和我自己的视频中的更多丘陵地带)。但是,如果它真的学会了检测这些线条,如果我能直接观察这些层本身的活动,又会怎样呢?然后,我可能会在原始视频的顶部显示层的激活。
使用 keras-vis 的激活图
我很快发现了 keras-vis 的巨大知识库,这正是我所需要的。在此之前,我找到了一些关于相同概念的研究论文,但是我找不到重现结果所需的实际代码。keras-vis 库非常棒,因为它允许您将训练好的模型输入到函数中,并返回所需层的激活图,这在技术上是为典型分类神经网络中的每个“类”制作的,但在这种情况下是为我的每个多项式系数制作的。
Activation maps of the first few layers (note that the layers have been cropped by the top third)
这是一种非常有趣的方式,可以确切地看到我的卷积神经网络在我的道路图像中看到了什么。虽然上面的图片在第一层看起来很好,当然,这种方法有更多的问题。
首先,在我的许多弯曲道路图像中,模型实际上只看了一条的线条。我的模型已经知道了线之间的关系,这是因为-在大多数情况下,车道线将是平行的,所以如果你只看一条线(假设它总是两条线中的同一条),你就可以大致了解另一条线的位置。但这并没有帮助我,因为我希望能够显示两条线或车道本身的位置。此外,如果你在上面注意到,可能由于我的图像在模型的生成器中翻转,激活也大量发生在天空中——模型正在学习根据天空在图像中的位置确定自己的方向,所以如果我想在我的原始视频上显示它,我必须以某种方式删除这个激活区域。
Deeper layers visualized
第二个问题更加令人困惑。弯曲的道路倾向于在单条线和天空上激活,而直的道路在图像底部的汽车本身以及汽车本身正前方的空间上激活,而在附近的线本身上不被激活。在图像的上方,这些线条有时会被激活。如果曲线和直线之间的激活没有任何一致性,这种方法就无法工作。
迁移学习
我试图挽救 keras-vis 方法的最后一招是使用迁移学习。我已经完全忘记了我的行为克隆项目,在这个项目中,一辆模拟汽车已经学会了根据提交给它自己训练过的神经网络的图像来驾驶自己。等等——我用超过 20,000 张图片训练了一个模型,让它在路上行驶——它是在看什么来做到这一点的?
One of the simulated car’s input images
答案实际上是整条道路本身(在 Udacity 的模拟器中没有单独的车道),但我想知道我是否可以使用迁移学习来更好地集中模型的注意力。有了一个大得多的数据集来开始训练,我就可以用特定于我的车道检测的新数据添加一点额外的训练,希望有更好的激活层。使用 model.pop()从该项目加载训练好的模型后,我从其中删除了最终输出层(对于转向角,它是一个单一输出),并用我的系数标签的六个输出来替换它。请注意,如果你是自己用一个模型来匹配输入图像的大小,或者它不会工作。
它工作得稍微好一点,因为模型在用我自己的数据进行一些额外的训练后,开始查看车道线而不是整条道路来激活。然而,仍然有很大的一致性问题,图像的哪些部分被激活,它们被激活的程度如何,等等。
完全卷积的方法
感觉自己正处于失败的边缘,我开始寻找一种新的方法。我最近看到几个不同的小组对来自汽车摄像头的图像进行处理的一个领域是图像分割——将给定的图像分成几类,如道路、汽车、人行道、建筑物等。SegNet 是我感兴趣的图像分割技术之一,他们甚至发布了他们的通用模型架构,该架构使用卷积层(批量归一化和 ReLU 激活)结合下行时的池层,以及从中点到分割图像的上采样(本质上是非池化)和去卷积层。这种方法跳过了所有完全连接的层,形成了一个完全卷积的神经网络。
这似乎是一个潜在的解决方案,可以解决车道可能在错误的角度重新绘制的问题——为什么不直接让神经网络自己重新绘制预测的车道呢?我仍然可以输入道路图像,同时使用原始系数标签创建的车道图作为新标签(即输出图像)。考虑到我已经用绿色画了车道,我决定让我的模型的输出“过滤器”仅仅是 RGB 的“G”通道(并且仅仅用它堆叠两个空白过滤器,以使相应的图像与原始道路图像混合)。这也帮助我将我的数据集扩大了一倍——还记得我之前是如何担心水平翻转图像的潜在副作用吗,因为系数标签不会与神经网络看到的匹配得很好?通过切换到这种方法,在预处理数据时,我可以同时翻转道路图像和车道图像标签。
One of the new labels — a lane image
我将快速后退一步,查看此时的数据集:
- 我的原始数据拉有 1,420 张图像(视频中“好”帧的十分之一)。我删除了其中 227 个无法正确标注的项目。
- 我只添加了 568 张来自弯曲道路视频的图片(从我试图使用的 1636 张图片中——由于我用于标记的 CV 模型不够充分,很多图片还是失败了)
- 另外 217 张图片来自 Udacity 的常规项目视频
- 总共 1978 张图片
- 这是低的,并且分布不均匀,所以由于原始系数上的各种小图像旋转没有很好地表示,我最终得到了 6382 个图像
- 水平翻转增加了一倍,达到 12,764 张图片
请注意,我仍然能够对这些新标签使用图像旋转,方法是在我检查哪些系数位于主分布之外时,确保道路图像、系数标签和车道图像标签保持链接。
鉴于我以前从未使用过完全卷积的神经网络,我想非常接近 SegNet 的架构。幸运的是,使用 Keras 做到这一点并不太复杂——解卷积层的一个不同之处是,您必须确保实际上数学与您想要做的事情正确匹配。我通过在最终的合并图层后精确地镜像我的模型,并对我的输入图像使用 80 x 160 x 3 的稍微不同的纵横比(而保持原始纵横比将会有 90 x 160 x 3)来使这变得容易。这样做也是为了让数学更容易,因为我对我的池层使用 2 x 2,从 90 开始会很快到达不能被 2 整除的层,导致在试图镜像前半部分时模型的另一面出现问题。
A quick mock-up of my new structure (left to right)
Comparing results from different models
最终的结果要好得多,从这里的视频中可以看到。当然,这个视频已经看到了一大块图像(可能在 10-20%之间),所以就此打住是欺骗,尽管它在旧的基于 CV 的模型最初未能产生足够标签的领域更有效。真正的测试是来自高级车道线项目的 Udacity 的挑战视频——我的模型从未见过它的任何一帧。但它在这个视频上也表现不错!它对高速公路立交桥下的阴影有一点问题,但在其他方面学会了推广到一个全新的视频。此外,它比旧型号快得多——通常能够用 GPU 每秒处理 25-29 帧,仅次于 30 fps 的实时速度。即使没有 GPU 加速,它仍然比 CV 模型略快,达到 5.5 fps,而之前只有 4.5 fps。
The old CV model vs. the new. You can’t really see it, but the CV-based model actually thinks both lines are on the right.
潜在的改进
这是我用深度学习进行车道检测的方法。当然,它并不完美。它比基于 CV 的模型更健壮,但在 Udacity 发布的更难挑战视频中,虽然做了一个令人钦佩的尝试,但在光影转换中,或当非常高的眩光击中窗户时,仍然会迷失方向。以下是我对未来改进我的模型的一些想法:
- 更多数据。当然,在深度学习中总是如此,但我认为随着更多的条件(如光线和阴影之间令人讨厌的过渡)和更多不同的相机,模型可以变得更好。
- 递归神经网络的使用。我还没有学会实际创建其中一个网络架构背后的技术,但是考虑到它能够使用过去的信息进行下一次预测,我认为这将是一个非常有用的研究途径。有趣的是,我目前在 SDCND 的第 2 学期研究专注于本地化的递归方法(尽管没有深度学习),我预感那里也有潜在的深度学习应用。
- 使用没有车道线或只有一条车道线的数据。这当然可以用在更多的情况下——许多城市以外的社区或地区并不标记所有的东西
- 扩展模型以检测更多项目——类似于图像分割,为什么不添加车辆和行人检测?最后,我可以在单独的滤波器上完成这些操作,越过我用于通道“G”通道的一个滤波器(也不一定仅限于“R”和“B”通道)。这可能比常规的图像分割好,也可能不好。
我也希望听到更多关于改进我的方法的想法。我真的很喜欢找出这种方法,我希望你也喜欢检查它!
独立于语言的文档聚类
我探索了一种新颖的独立于语言的文档聚类方法。关键是,它适用于任何语言的任何文本。数据发生变化时,过程保持不变。
让我用要点来说明这种方法:
- 从可用数据中构建单词向量。
- 建立文档词向量的词簇。
- 找出最能代表文档的聚类。
- 聚集这些集群(相似的集群聚集在一起)。
- 具有相似簇的文档放在一起。
现在,我们将浏览流程和代码。我们将从创建单词向量开始。在那之前
在自然语言处理(NLP)中,90%的工作是预处理——某研究人员
因此,请确保您对数据做了所有需要做的预处理。因为这是一个概念验证,所以我排除了进行预处理的部分。
我们将使用 gensim python 包来构建单词向量。下面的函数创建向量,并以二进制格式保存它们。
# Create wordvectors
def create_vectors(filename):
sentences = []
with bz2.open(filename, 'rt') as df:
for l in df:
sentences.append(" ".join(l.split(",")).split())
model = Word2Vec(sentences, size=25, window=5, min_count=1, workers=4)
model.save(r"filename.vec") # Line changed refer code on github
return model
一旦单词向量准备好了,我们就可以进入下一步,这是一个非常有趣的步骤。我从博客这里偷来的。它非常简单而且有效!
假设我们有一个包含 n 个单词的文档。我们将从第一个单词开始,并在模型中查找该单词的向量(单词向量),该向量进入一个聚类,然后向前移动,我们以概率 1/(1+n)将该单词分配给预先创建的聚类或新的聚类。如果我们决定分配给一个现有的聚类,我们就把这个词分配给最相似的聚类。这种方法创建的簇或多或少地将单词分成有意义的组,请看。
Language Independent Document Clustering
更多例子在本笔记本这里。
以下函数是上述算法的实现,也称为中餐厅流程。
Python Implementation of CRP
我已经把代码放在 github 上了,还有一个附带的笔记本,你可以看看。https://github.com/kaustubhn/doc_clust
丰富
对上述算法的几点改进建议。
- 更多数据
- 更好的预处理
- 多维向量(我们使用 25 维)
- 匹配聚类的更好方法(除了余弦方法)
注意:这是一个非常实验性的方法,到目前为止还有很多不清楚和不明确的地方,我会继续改进和完善这个方法。感谢您的评论。
要取得联系,请发微博给我,地址是 kaustubhn 。
使用 Spark 进行大规模图挖掘:第 1 部分
本教程分为两部分:
Part 1 (你来了!):无监督学习的图。
第二部 (点击此处) :如何施展神奇的图形力量。我们将讨论标签传播、火花图框架和结果。回购与样本图和笔记本在这里:https://github.com/wsuen/pygotham2018_graphmining
我也将在 PyGotham 2018 上就这个话题发表演讲。😃
如果您是一名工程师,您很可能使用过图形数据结构来实现搜索和查找算法。你也用它们来解决机器学习问题吗?
你为什么关注图表?
对于数据科学家来说,图表是一个非常迷人的研究主题。对于机器学习问题来说,标记数据并不总是可用的。图在这些无人监管的环境中非常强大,因为它们通过利用数据的底层子结构来充分利用你拥有的数据。
对于一些机器学习问题,图表可以帮助你在没有标签的地方得到标签数据!
我将教你如何在图中找到相关数据点的簇,使用一套被称为社区检测的方法。我们将使用 Spark GraphFrames 来处理我从 2017 年 9 月的通用抓取数据集中创建的大型 web 图。
Hey Boromir, have you tried community detection?
图表 101
图是用于表示对象之间成对关系的数据结构。图形由节点(也称为顶点)和边组成。它们也可以是有向的或无向的。例如,Twitter 关注可以是一个有向图;这种关系是单向的。我关注另一个用户,并不意味着他们也关注我!
Example of a directed graph.
我专注于网络图表。网络图捕捉不同网站之间的链接关系。每个网页都是一个节点。如果从一个页面到另一个页面有一个 html 链接,在这两个节点之间画一条边。
当你对越来越多的页面这样做时,你会注意到子结构的出现。在真实的 web 数据上,这些子结构可能非常大和复杂!
这是一个新闻网站下所有页面的样本图。
- 每个淡蓝色的点代表一个单独的网页,或节点。
- 每条深蓝色的线代表两页之间的链接,一条边。
Subpage structure of a news site, generated by me using Gephi.
即使在这个级别,您也可以看到密集的**集群、或社区、**页面。您可以发现具有较高中心度的节点(有大量其他页面链接到它们的页面)。
如果单个网站的连接如此密集,想象一下我们可以从成千上万个网站中挖掘出什么!
图表为什么有用?
好吧,那个蓝色水母看起来很酷,但是为什么要做这些呢?
-你呢
有许多机器学习问题,其中标签(关于数据点是属于一个类还是另一个类的信息)不可用。无监督学习问题依赖于寻找数据点之间的相似性来将数据分类成组或聚类。与监督方法形成对比,在监督方法中,数据用适当的类别进行标注,您的模型学习使用这些标签来区分类别。
Source: http://beta.cambridgespark.com/courses/jpm/01-module.html
当你不容易获得更多数据时,无监督学习是非常有用的,因此你可以利用你所拥有的数据的更多价值。标签可能不可用;即使有,也可能太费时或太贵而无法获得。在一个机器学习问题的开始,我们也可能不知道我们到底在寻找多少类对象!
这就是为什么我们希望我们的工具包中有图表:
图表让我们在无人监管的环境下从数据中获得更多价值。我们可以从图中得到聚类。
**无监督学习与人类的学习方式并无不同!**你最初是怎么学会分辨狗和猫的?我猜对大多数人来说,没有人会让年轻的自己坐下来,用精确的分类学术语定义什么是狗或猫。你的父母也没有给你一个由数以千计的猫和狗的照片组成的语料库,每张照片都有标签,并要求你画出一个准确划分这两类动物的界限。
如果你的童年和我一样,你可能见过几只猫,见过几只狗。与此同时,你幼小的心灵识别出这两种动物之间的显著差异,以及每种动物的相关共同特征。我们的大脑不可思议地从我们的环境中吸收信息,综合这些数据,并在我们一生中遇到的完全不同的事物之间形成共同点。
集群有很多令人兴奋的应用。我的工作中出现了一些例子:
- 预测没有标签可供学习的数据集的类别标签 。
- 为受众细分和分类生成分组。
- 为相似的网站建立一个推荐者。
- 发现异常。
- 使用集群作为半监督机器学习集合的一部分。聚类可以帮助您将已知标签扩展到附近的数据点,以增加训练数据的大小,或者如果立即需要标签,可以直接使用聚类,直到辅助系统可以对其进行分类。
关键在于:在无监督学习中,集群就是社区!而社区就是集群!
图形社区也是集群!
唯一的区别是,你没有使用工程化的特性,而是依靠你的图中的底层网络结构来派生集群。您可以使用图形中的边来度量数据点之间的相似性,而不是使用预定义的距离度量。
我之前提到过他们,所以我应该适当地介绍一下社区。没有一个唯一的定义。一个一般的描述:一个社区是一个图的子结构,其中结构内的节点比子结构外的节点彼此连接得更紧密。找到这些社区或集群的过程被称为社区检测。
Zachary karate club. Image from: KONECT, April 2017., dataset from original 1977 Zachary study.
扎卡里空手道俱乐部数据集模拟了空手道俱乐部各成员之间的关系。有一次,俱乐部的两名成员发生了冲突,俱乐部最终分裂成多个社区。您可以看到用 4 种颜色表示的社区。
想想无监督聚类算法是如何工作的。您依赖于这样一个事实,即在您选择的特征空间中,一些数据点比其他数据点更接近。数据越接近,越相似。然后,根据选择的距离度量,将数据分配到相似对象的集群中。
图表可以帮助您实现相似的聚类,而没有像传统聚类那样选择特征的麻烦。
等等,为什么会这样?
我们来深入挖掘一下!我们做了哪些假设,让我们依靠社区检测来找到相关节点?
最重要的一条:
节点之间的边不是随机的。
如果你的图形是随机的,这些都不会起作用。然而,现实生活中的大多数图表都不是随机的;这些边缘以某种方式相关联。两种机制有助于解释为什么会出现这种情况:
- 影响。连接的节点倾向于共享或传播特征。想象你的几个朋友学会了使用 Spark 是多么的神奇。从与他们的联系中,你可能也更倾向于开始使用 Spark。“我所有的朋友都在做这件事,所以我也要做。”
- 同宗。拥有共同特征或某种关系的节点更有可能连接起来。例如,如果你和我都对 python 和图形感兴趣,我们更有可能在图形上联系在一起。这也叫做分类混合。“物以类聚,人以群分。”
在现实生活中,这些机制能够并且确实相互作用!
研究人员利用这些现象用图表来模拟有趣的问题。例如,Farine 等人根据动物最强联系的位置预测了狒狒的位置——这是对行为生态学的影响的一个很好的应用。
Farine, Damien R., et al. “Both nearest neighbours and long-term affiliates predict individual locations during collective movement in wild baboons.” Scientific reports 6 (2016): 27704
同性在社交网络研究中被频繁使用。Adamic 和 Glance 在 2004 年大选期间对政治博客做了一项有趣的研究。他们制作了一张图表,展示不同博客之间的相互引用;蓝色节点代表自由派博客,红色节点代表保守派博客。也许不出所料,他们发现博客倾向于引用其他具有相同政治倾向的博客。
Adamic, Lada A., and Natalie Glance. “The political blogosphere and the 2004 US election: divided they blog.” Proceedings of the 3rd international workshop on Link discovery. ACM, 2005.
即使在个人层面上,同性恋也是有意义的。你自己的朋友网络很有可能是由和你同龄、住在同一个城镇、有相同爱好或上过同一所学校的人组成的。你是工作中同性恋的活生生的例子。请随意将它添加到您的简历中!
我们已经讨论了图表如何利用数据的底层网络特征来返回聚类。在 web 图中,这些聚类对于推荐系统、受众细分、异常检测等应用非常有用。
在第 2 部分(此处发布)中,我们将深入社区检测技术,并学习如何从我们使用公共爬行数据集创建的网络图中获得聚类。
承认
感谢 Yana Volkovich 博士深化了我对图论的学习,是一位伟大的导师。也感谢我的其他同事,他们对我的演讲给予了反馈。
参考
亚当,拉达,和娜塔莉·葛拉。"政治博客圈和 2004 年美国大选:分裂他们的博客."第三届链接发现国际研讨会会议录。美国计算机学会,2005 年。
常用抓取数据集(2017 年 9 月)。
Farine,Damien R .等,“最近邻居和长期附属者都预测野生狒狒在集体运动中的个体位置。”科学报道6(2016):27704
Fortunato,Santo。“图中的社区检测”物理报告 486.3–5(2010):75–174。格文、米歇尔和马克·EJ·纽曼。"社会和生物网络中的社区结构."美国国家科学院学报 99.12(2002):7821–7826。莱斯科维克、朱雷、阿南德·拉贾拉曼和杰弗里·大卫·厄尔曼。海量数据集的挖掘。剑桥大学出版社,2014 年。Raghavan,Usha Nandini,Réka Albert 和 Soundar 鸠摩罗王。"在大规模网络中检测社区结构的近似线性时间算法."物理审查**E 76.3(2007):036106。
扎卡里空手道俱乐部网络数据集— KONECT,2017 年 4 月。**
使用 Spark 进行大规模图挖掘:第 2 部分
分为两部分的教程:
第一部分 :无监督学习的图形。
第二部分(你来了!):如何施展神奇的图形力量。我们将讨论标签传播、火花图框架和结果。回购样品图和笔记本在这里:https://github.com/wsuen/pygotham2018_graphmining
在第 1 部分中(这里是),我们看到了如何用图解决无监督的机器学习问题,因为社区是集群。我们可以利用节点之间的边作为相似性或关系的指标,就像特征空间中的距离用于其他类型的聚类一样。
在这里,我们深入探讨社区检测的方法。我们构建并挖掘了一个大型 web 图,学习如何在 Spark 中实现一种称为标签传播算法(LPA)的社区检测方法。
使用标签传播检测社区
虽然有许多社区检测技术,但我只关注一种:标签传播。对于其他方法的概述,我推荐 Santo Fortunato 的“图中社区检测”。
Graph with communities. From Girvan, Michelle, and Mark EJ Newman. “Community structure in social and biological networks.” Proceedings of the national academy of sciences 99.12 (2002): 7821–7826.
进入标签传播算法(LPA) 由 Raghavan,Albert,和鸠摩罗王(2007) 提出。LPA 是一种迭代的社区检测解决方案,其中信息基于底层的边结构在图中“流动”。LPA 是这样工作的:
Raghavan, Usha Nandini, Réka Albert, and Soundar Kumara. “Near linear time algorithm to detect community structures in large-scale networks.” Physical review E 76.3 (2007): 036106.
- 开始时,每个节点从自己的社区开始。
- 对于每次迭代,随机遍历所有节点。对于每个节点,用其大多数邻居的标签更新该节点的社区标签。随意打破任何联系。
- 如果节点现在用其邻居的多数标签来标记,则该算法已经达到停止标准。如果没有,重复步骤 2。
Image Source
Or just, you know, stay home? Image Source.
标签传播有意义直觉上。假设有一天在工作中,某人得了感冒,并“传播”疾病,直到你工作场所的每个人都像他们的邻居一样生病。与此同时,街对面的富宝员工感染并传播了 流感 。你和 FoobarCo 之间联系不多,所以当每个社区的成员都染上了当前的疾病时,“传播”就停止了。实现收敛!不过,抽鼻子和头痛真糟糕。
为什么用 LPA?
- 带标签的数据很好,但不是必需的。使 LPA 适合我们的无监督机器学习用例。
- 参数调整非常简单。LPA 使用 max_iterations 参数运行,使用默认值 5 可以得到一些好的结果。Raghavan 和她的合著者用几个标记网络测试了 LPA。他们发现至少 95%的节点在 5 次迭代中被正确分类。
- 聚类的先验数量、聚类大小、不需要的其他度量。如果你不想假设你的图有一定的结构或层次,这是至关重要的。对于我的网络图的网络结构、我拥有的社区数据的数量或者这些社区的预期规模,我没有先验的假设。
- 接近线性运行时。LPA 的每一次迭代都是 O(m ),边数是线性的。与一些先前的社区检测解决方案的 O(n log n)或 O(m+n)相比,整个步骤序列以接近线性的时间运行。
- 可解释性。当有人问,你可以解释为什么一个节点被分组到某个社区。
Language communities in Belgium mobile network (red = French, green = Dutch). Image from Blondel, Vincent D., et al. “Fast unfolding of communities in large networks.” Journal of statistical mechanics: theory and experiment 2008.10 (2008): P10008…
工具选择
首先,快速而非详尽地分析一下工具领域。我根据图的大小、库是否能很好地与 Python 配合,以及生成简单可视化的难易程度来划分工具。
Some common graph-mining tools.
工具的非详尽菜单:
- 对于适合单台机器的数据,networkxPython 包是易于使用的图形探索的好选择。它实现了最常见的算法(包括标签传播、PageRank、最大团检测等等!).简单的可视化也是可能的。
- Gephi 是一个开放的图形分析工具。Gephi 不是一个 Python 包,而是一个独立的工具,具有健壮的 UI 和令人印象深刻的图形可视化功能。如果您正在处理较小的图形,需要强大的可视化,并且更喜欢使用 UI 而不是 Python,请尝试 Gephi。
- Spark 有 2 个图库,【GraphX】和GraphFrames。当您的图形数据太大而无法在单台机器上显示时(受限于分配给 Spark 应用程序的资源量),想要利用并行处理和 Spark 的一些内置容错功能时,Spark 是一个很好的解决方案。spark 的 Python API py Spark 非常适合集成到 scikit-learn、matplotlib 或 networkx 等其他库中。****
- Apache Giraph 是 Google 创建的图形处理架构 Pregel 的开源实现。与之前的解决方案相比,Giraph 的准入门槛更高。虽然 Giraph 对于大规模图形分析部署来说非常强大,但我选择了同时具有 Scala 和 Python APIs 的更轻量级的工具。
- Neo4j 是一个图形数据库系统。它有一个 Python 客户端,尽管你必须单独安装 Neo4j。因为我的分析只是一个概念验证,所以我想避免维护和部署一个与我现有代码不集成的完全独立的工具。
- 最后,理论上你可以实现自己的解决方案。对于最初的数据科学探索,我不鼓励这样做。许多定制的图挖掘算法是针对非常具体的用例的(例如,只在图聚类方面超级高效,而不是其他方面)。如果你确实需要处理非常非常大的数据集,首先考虑对你的图进行采样,过滤感兴趣的子图,从例子中推断关系,基本上是从现有工具中获得更多收益的任何事情。
鉴于我正在处理的数据量,我选择了 Spark GraphFrames 。
记住:对你的项目来说最好的图形库取决于语言、图形大小、你如何存储你的图形数据以及个人偏好!
构建通用抓取 Web 图
太好了!我完全相信图表有多棒,它们是有史以来最酷的东西!如何开始在真实数据上使用社区检测?
-你呢
步伐
1.获取数据:通用抓取数据集是一个开放的网络抓取语料库,非常适合网络图形研究。抓取结果以 WARC (网络存档)格式存储。除了页面内容,数据集还包含爬网日期、使用的标题和其他元数据。
我从 2017 年 9 月的抓取中抽取了 100 个文件。文件warc.paths.gz
包含路径名;使用这些路径名,从 s3 下载相应的文件。
Indeed.
2.解析和清理数据:作为第一步,我们需要每个页面的 html 内容。对于每个页面,我们收集 URL 和任何链接的 URL 来创建我们的图表。
为了从原始的 WARC 文件中提取边缘,我写了一些数据清理代码,这些代码可能永远不会被公之于众。至少它完成了工作,所以我可以专注于更有趣的事情!我的解析代码是用 Scala 写的,但是我的演示是用 pyspark 写的。我使用了 WarcReaderFactory 和杰里科解析器。对于 python 来说,像 warc 这样的库看起来可以满足你的数据管理需求。
在我将所有的href
链接从 html 内容中取出后,
- 我在域名之间画了边,而不是完整的 URL。我没有创建
medium.com/foo/bar
和medium.com/foobar
,而是只创建了一个节点medium.com
,它捕获与其他域之间的链接关系。 - 我过滤掉了循环。循环是将节点连接到自身的边,对我的目的没有用。如果
medium.com/foobar
链接到同一个域,比如说medium.com/placeholderpage
,则不画边。**** - 我删除了许多最流行的资源链接,包括流行的 cdn、追踪器和资产。对于我的初步探索,我只想关注人们可能会访问的网页。
3.初始化火花上下文:对于在家跟随的人,请参见https://github.com/wsuen/pygotham2018_graphmining的演示。这个演示只能在你的本地机器上运行。你不会得到一个分布式集群的所有计算资源,但是你会知道如何开始使用 Spark GraphFrames。
我将使用 Spark 2.3。导入pyspark
和其他需要的库,包括graphframes
。然后创建一个 SparkContext,这将允许您运行 pyspark 应用程序。
*****# add GraphFrames package to spark-submit
import os
os.environ['PYSPARK_SUBMIT_ARGS'] = '--packages graphframes:graphframes:0.6.0-spark2.3-s_2.11 pyspark-shell'import pyspark# create SparkContext and Spark Session
sc = pyspark.SparkContext("local[*]")
spark = SparkSession.builder.appName('notebook').getOrCreate()# import GraphFrames
from graphframes import ******
4.创建一个图表框架:一旦你有了干净的数据,你就可以把你的顶点和边加载到 Spark 数据框架中。
vertices
包含每个节点的id
和节点的name
,后者表示域。edges
包含我的有向边,从源域src
到源链接到的域dst
。
*****# show 10 nodes
vertices.show(10)+--------+----------------+
| id| name|
+--------+----------------+
|000db143| msn.com|
|51a48ea2|tradedoubler.com|
|31312317| microsoft.com|
|a45016f2| outlook.com|
|2f5bf4c8| bing.com|
+--------+----------------+
only showing top 5 rows# show 10 edges
edges.show(10)+--------+--------+
| src| dst|
+--------+--------+
|000db143|51a48ea2|
|000db143|31312317|
|000db143|a45016f2|
|000db143|31312317|
|000db143|51a48ea2|
+--------+--------+
only showing top 5 rows*****
然后你可以用你的顶点和边创建一个GraphFrame
对象。瞧啊。你有图表!
*****# create GraphFrame
graph = GraphFrame(vertices, edges)*****
5.运行 LPA:一行代码可以让你运行 LPA。在这里,我用 5 次迭代运行 LPA(maxIter
)。
*****# run LPA with 5 iterations
communities = graph.labelPropagation(maxIter=5)communities.persist().show(10)+--------+--------------------+-------------+
| id| name| label|
+--------+--------------------+-------------+
|407ae1cc| coop.no| 781684047881|
|1b0357be| buenacuerdo.com.ar|1245540515843|
|acc8136a| toptenreviews.com|1537598291986|
|abdd63cd| liberoquotidiano.it| 317827579915|
|db5c0434| meetme.com| 712964571162|
|0f8dff85| ameblo.jp| 171798691842|
|b6b04a58| tlnk.io|1632087572480|
|5bcfd421| wowhead.com| 429496729618|
|b4d4008d|investingcontrari...| 919123001350|
|ce7a3185| pokemoncentral.it|1511828488194|
+--------+--------------------+-------------+
only showing top 10 rows*****
运行graph.labelPropagation()
返回一个带有节点的数据帧和一个表示该节点属于哪个社区的label
。您可以使用label
了解社区规模的分布,并放大感兴趣的区域。例如,发现与pokemoncentral.it
在同一个社区中的所有其他网站(老实说,谁不想呢?),过滤所有其他节点,其中label = 1511828488194
。
结果
当我在我的通用抓取 web 图表样本上运行 LPA 时,发生了什么?
- 我从超过 1500 万个网站的原始数据开始。这是大量的节点,其中许多包含冗余信息。我描述的清理过程将图形压缩成更少、更有意义的边。
- LPA 发现了超过 4700 个社区。然而,一半以上的社区只包含一个或两个节点。
- 另一方面,最大的社区有超过 3500 个不同的网站!为了给出一个范围的概念,这大约是我的最终图形后过滤的 5%的节点。
社区规模的极端说明了 LPA 的一个缺点。太多的融合,可能会有太大的集群(由控制密集连接网络的某些标签引起)。融合太少,你可能会得到更多、更小、更没用的社区。我发现最有趣的集群最终处于两个极端之间。
收敛和小世界网络效应
在我的数据集中,LPA在 5 次迭代左右收敛。你可以看到社区的数量稳定在 4700 个左右。Raghavan 和她的同事也用他们的标号图证明了这个性质。****
解释这一点的一个可能机制是小世界网络效应——图形聚集的趋势,但与节点数量相比,路径长度也较短。换句话说,虽然图有簇,但是你也期望能够在 5-6 次跳跃内从一个朋友旅行到你网络中的另一个朋友。许多真实世界的图形,包括互联网和社交网络,都具有这一特性。你可能也知道这是六度分离现象。
Number of communities levels off after 5 iterations.
样本集群
粗略地看,我们来看一些样本集群。与传统的无监督聚类一样,社区可以是不同站点的混合,尽管没有 LPA 我们不会发现一些感兴趣的主题!从左至右:
- 电子学习网站:与电子学习页面相关或链接的网站。我该去找一些新的数据科学 MOOCs 了!
- 臭虫网站:与房地产和臭虫相关的网站。所有这些网站都使用相同的模板/图片,只是域名略有不同。我不认为我会知道真相。
- 星球大战社区:谈论星球大战电影、事件和纪念品的网站经常互相链接。
值得强调的是,我们在没有文本处理和特征选择、手动标记、域名特征或者甚至不知道要查找多少社区的情况下获得了这个集群。我们通过利用网络图的底层网络结构发现了兴趣社区!********
从这里去哪里
我几乎没有触及网络图形社区的表面。未来的研究可以有很多方向。例如:
- 分层并传播元数据*:如果我们向数据中添加边权重、链接类型或外部标签等信息,我们能在图中多好地传播这些信息?***
- 删除/添加节点并测量对社区的影响:我很好奇添加或删除高边缘中心性的节点如何改变 LPA 的有效性和最终社区的质量。
- 观察 web graph 随时间的演变:每个月都有一个新的通用抓取数据集!看看随着时间的推移会出现什么样的集群会很有趣。反过来,有哪些社群不变?众所周知,互联网不是静态的。
用于演示的Github repo包含一个 10k 节点的小型样本 web 图。此外,还有使用 Docker 进行设置和运行 pyspark 笔记本的说明。我希望这将有助于启动 web 图数据的实验,并学习 Spark GraphFrames 来解决您自己的数据科学问题。
探索愉快!
We’re pioneers! Graph pioneers. 😃 Image Source.
承认
感谢博士 Yana Volkovich 深化了我对图论的学习,是我的良师益友。也感谢我的其他同事,他们对我的演讲给予了反馈。
参考
***亚当,拉达,和娜塔莉·葛拉。"政治博客圈和 2004 年美国大选:分裂他们的博客."第三届链接发现国际研讨会会议录。美国计算机学会,2005 年。
常用抓取数据集(2017 年 9 月)。Farine,Damien R .等人,“最近的邻居和长期的附属者都预测野生狒狒在集体运动中的个体位置。”科学报道6(2016):27704
Fortunato,Santo。“图中的社区检测”物理报告 486.3–5(2010):75–174。格文、米歇尔和马克·EJ·纽曼。"社会和生物网络中的社区结构."美国国家科学院学报 99.12(2002):7821–7826。莱斯科维克、朱雷、阿南德·拉贾拉曼和杰弗里·大卫·厄尔曼。挖掘海量数据集。剑桥大学出版社,2014 年。Raghavan,Usha Nandini,Réka Albert 和 Soundar 鸠摩罗王。"在大规模网络中检测社区结构的近似线性时间算法."物理审查**E 76.3(2007):036106。
扎卡里空手道俱乐部网络数据集— KONECT,2017 年 4 月。*****
使用 Datashader 进行大规模可视化和制图
旧金山商业鸟瞰图。
如果你曾经试图用 Matplotlib 或 Seaborn 创建一个超过 100,000 点的群体图或关系图,你会对在加载图时摆弄拇指的场景并不陌生。
当最终绘制该图时,由于点的数量或不同类别绘制的顺序,结果可能不会揭示太多数据。
计算效率和过度绘制只是绘制大型数据集的众多问题中的两个。幸运的是, Datashader 是一个以有意义的方式快速表示大型数据集的绝佳选择。
“这个过程中的计算密集型步骤是用 Python 编写的,但使用 Numba 透明地编译成机器代码,并使用Dask灵活地分布在内核和处理器之间,提供了高度优化的渲染管道,即使在标准硬件上也可以使用极大的数据集。”
对于那些感兴趣的人,Youtube 上有一个很棒的视频揭示了传统可视化中的问题以及 Datashader 如何帮助解决这些问题。
数据清理
我们正在使用的数据集来自 T21,包括旧金山所有的纳税企业。
“企业位置”列包含每个企业的位置数据,格式如下:
加利福尼亚州旧金山市汤森路 153 号,邮编:94107 (37.77982,-122.391555)
因此,采取了以下步骤来清理数据:
- 删除所有没有“商业地点”的条目,因为没有纬度和经度。
- 删除所有“城市”不在旧金山的条目。
- 删除所有带有“业务结束日期”的条目。如果该字段不是 NA,则意味着该业务不再有效。
- 编写助手函数,用 regex 解析出纬度和经度。
地图的 Web 墨卡托坐标
为了在 Datashader 中绘制这些点,我们必须首先将纬度和经度坐标转换为 Web 墨卡托坐标。
web 墨卡托坐标系用于 Web 制图应用程序。它的受欢迎程度可以归因于它被谷歌地图采用。为了用 Datashader 绘图,我们必须将纬度、经度对投影到这个新平面上。Datashader 有一个内置的方法可以帮我们做到这一点:lnglat_to_meters
然后,我们将第 1 个和第 99 个百分点作为地图显示的界限。选择这些百分点值是为了在确定地图边界时剔除异常值。这些坐标然后被再次投影到 Web 墨卡托平面。
地图设置
将坐标投影到新平面后,我们可以开始设置地图。
我们设置了部分对象“导出”和“cm”。“导出”有助于将创建的图导出到预定路径,而“cm”有助于颜色映射。
画布对象 ds。Canvas()设置了预定的宽度和高度。包含地图边界的 SF 对象也被传入。
我们之前使用的 pandas 数据帧被转换为 Dask 数据帧,并且使用传入的 x,y 对在画布上生成点(在本例中为东距和北距列)。
测绘
现在设置已经完成,我们可以开始用一行代码绘制和导出图,如下所示。色彩映射图,标准化都是可以轻易改变的参数。
绘制旧金山 10 万家企业,清晰勾勒出这些企业所在的街道。金融区和教会区似乎是商业最集中的地方。
最古老的企业位于哪里?我们可以对商业时代排名前十的企业进行筛选。
Distribution of oldest businesses in SF
不出所料,最古老的企业主要集中在金融区。
不同的业务类别呢?让我们画出餐饮服务企业和房地产企业的分布图。
Left: Distribution of Food Service businesses Right: Distribution of Real Estate businesses
里士满和日落区的餐饮服务相对较少。然而,似乎有相当多的房地产企业在这些地区,因为他们是住宅区。
在地图数据上叠加点
不过,黑色背景已经够了。你如何在实际地图上覆盖这些点?Datashader 与 Holoviews、Geoviews 和 Bokeh 结合使用使这变得非常容易。
Viewing business positions when zoomed in on the map.
聚合器函数中也可以使用其他列。例如,我们可以使用每个区域的业务年龄平均值来确定点的显示。
最终的图确实显示了旧金山东北部地区的老企业密度更高(深蓝色点)。
使用 Datashader 还可以做更多的事情,在这个例子中只绘制了 100,000 个点。进一步的定制选项和实际的大数据正在等待使用 Datashader 及其附带包的进一步项目的探索。例如,GPS 数据非常有趣,因为它们通常包含数百万(或数十亿)个点,并且可以追踪和分析路线。
结果代码可以在 Github 上找到,也可以在 LinkedIn 上自由连接!感谢阅读,节日快乐!
基于 Python 的潜在语义分析和情感分类
photo credit: Pexels
自然语言处理,LSA,情感分析
潜在语义分析 (LSA)是一种通过应用于大型文本语料库的统计计算来提取和表示单词的上下文使用意义的理论和方法。
LSA 是一种信息检索技术,它分析和识别非结构化文本集合中的模式以及它们之间的关系。
LSA 本身是一种在文档集合中发现同义词的不受监督的方式。
首先,我们来看看潜在语义分析是如何在自然语言处理中用于分析一组文档和它们所包含的术语之间的关系的。然后我们进一步对情感进行分析和分类。我们将在此过程中回顾特征选择的卡方。我们开始吧!
数据
数据集包括超过 50 万条亚马逊美食评论,可以从 Kaggle 下载。
import pandas as pddf = pd.read_csv('Reviews.csv')
df.head()
Figure 1
TFIDF
TF-IDF 是一种信息检索技术,它衡量术语的频率(TF)及其逆文档频率(IDF)。每个单词都有各自的 TF 和 IDF 得分。一个单词的 TF 和 IDF 得分的乘积被称为该单词的 TFIDF 权重。
简单来说,TFIDF 得分(权重)越高的词越稀有,反之亦然。
from sklearn.feature_extraction.text import TfidfVectorizertfidf = TfidfVectorizer()
tfidf.fit(df['Text'])
Figure 2
X = tfidf.transform(df['Text'])
df['Text'][1]
Figure 3
参考上面的句子,我们可以检查这个句子中几个词的 tf-idf 得分。
print([X[1, tfidf.vocabulary_['peanuts']]])
T11【0.37995462060339136】
print([X[1, tfidf.vocabulary_['jumbo']]])
【0.530965343023095】
print([X[1, tfidf.vocabulary_['error']]])
【0.2302711360436964】
在“花生”、“jumbo”、“错误”三个词中,tf-idf 给“jumbo”的权重最高。为什么?这表明“jumbo”是一个比“peanut”和“error”更罕见的词。这就是如何使用 tf-idf 来表明文档集合中单词或术语的重要性。
情感分类
为了对情绪进行分类,我们删除了中性分数 3,然后将分数 4 和 5 分组为正(1),将分数 1 和 2 分组为负(0)。经过简单的清理,这就是我们将要处理的数据。
import numpy as npdf.dropna(inplace=True)
df[df['Score'] != 3]
df['Positivity'] = np.where(df['Score'] > 3, 1, 0)
cols = ['Id', 'ProductId', 'UserId', 'ProfileName', 'HelpfulnessNumerator', 'HelpfulnessDenominator', 'Score', 'Time', 'Summary']
df.drop(cols, axis=1, inplace=True)
df.head()
Figure 4
列车测试分离
from sklearn.model_selection import train_test_splitX = df.Text
y = df.Positivity
X_train, X_test, y_train, y_test = train_test_split(X, y, random_state = 0)print("Train set has total {0} entries with {1:.2f}% negative, {2:.2f}% positive".format(len(X_train),
(len(X_train[y_train == 0]) / (len(X_train)*1.))*100,
(len(X_train[y_train == 1]) / (len(X_train)*1.))*100))
训练集共有 426308 个条目,其中 21.91%为负数,78.09%为正数
print("Test set has total {0} entries with {1:.2f}% negative, {2:.2f}% positive".format(len(X_test),
(len(X_test[y_test == 0]) / (len(X_test)*1.))*100,
(len(X_test[y_test == 1]) / (len(X_test)*1.))*100))
测试集共有 142103 个条目,其中 21.99%为阴性,78.01%为阳性
你可能已经注意到我们的班级是不平衡的,负面和正面的比例是 22:78。
对抗不平衡类的策略之一是使用决策树算法,因此,我们使用随机森林分类器来学习不平衡数据并设置class_weight=balanced
。
首先,定义一个函数来打印出准确度分数。
from sklearn.feature_extraction.text import CountVectorizer
from sklearn.ensemble import RandomForestClassifier
from sklearn.pipeline import Pipeline
from sklearn.metrics import accuracy_scoredef accuracy_summary(pipeline, X_train, y_train, X_test, y_test):
sentiment_fit = pipeline.fit(X_train, y_train)
y_pred = sentiment_fit.predict(X_test)
accuracy = accuracy_score(y_test, y_pred)
print("accuracy score: {0:.2f}%".format(accuracy*100))
return accuracy
为了进行有效的情感分析或解决任何自然语言处理问题,我们需要很多特性。很难计算出所需功能的确切数量。所以我们准备试试,一万到三万。并打印出与特征数量相关的准确度分数。
cv = CountVectorizer()
rf = RandomForestClassifier(class_weight="balanced")
n_features = np.arange(10000,30001,10000)def nfeature_accuracy_checker(vectorizer=cv, n_features=n_features, stop_words=None, ngram_range=(1, 1), classifier=rf):
result = []
print(classifier)
print("\n")
for n in n_features:
vectorizer.set_params(stop_words=stop_words, max_features=n, ngram_range=ngram_range)
checker_pipeline = Pipeline([
('vectorizer', vectorizer),
('classifier', classifier)
])
print("Test result for {} features".format(n))
nfeature_accuracy = accuracy_summary(checker_pipeline, X_train, y_train, X_test, y_test)
result.append((n,nfeature_accuracy))
return resulttfidf = TfidfVectorizer()
print("Result for trigram with stop words (Tfidf)\n")
feature_result_tgt = nfeature_accuracy_checker(vectorizer=tfidf,ngram_range=(1, 3))
Figure 5
不错!
在我们完成这里之前,我们应该检查分类报告。
from sklearn.metrics import classification_reportcv = CountVectorizer(max_features=30000,ngram_range=(1, 3))
pipeline = Pipeline([
('vectorizer', cv),
('classifier', rf)
])
sentiment_fit = pipeline.fit(X_train, y_train)
y_pred = sentiment_fit.predict(X_test)print(classification_report(y_test, y_pred, target_names=['negative','positive']))
Figure 6
特征选择的卡方检验
特征选择是机器学习中的一个重要问题。我将向您展示在我们的大规模数据集上进行基于卡方检验的特征选择是多么简单。
我们将计算所有特征的卡方得分,并可视化前 20 名,这里术语或单词或 N-grams 是特征,正面和负面是两个类别。给定一个特征 X,我们可以用卡方检验来评估它区分类的重要性。
from sklearn.feature_selection import chi2
import matplotlib.pyplot as plt
%matplotlib inlineplt.figure(figsize=(12,8))
scores = list(zip(tfidf.get_feature_names(), chi2score))
chi2 = sorted(scores, key=lambda x:x[1])
topchi2 = list(zip(*chi2[-20:]))
x = range(len(topchi2[1]))
labels = topchi2[0]
plt.barh(x,topchi2[1], align='center', alpha=0.5)
plt.plot(topchi2[1], x, '-o', markersize=5, alpha=0.8)
plt.yticks(x, labels)
plt.xlabel('$\chi^2$')
plt.show();
Figure 7
我们可以观察到,具有高χ2 的特征可以被认为与我们正在分析的情感类别相关。
例如,卡方检验选出的前 5 个最有用的特征是“不”、“失望”、“非常失望”、“不买”和“最差”。我想它们大多来自负面评论。卡方检验选择的下一个最有用的特征是“棒极了”,我假设它主要来自正面评论。
今天到此为止。源代码可以在 Github 上找到。我很高兴听到任何问题或反馈。
在 1 周或更短时间内推出 AI
无论你是一家新的创业公司还是现有的企业,这里有一种方法可以让人工智能产品或服务在 1 周或更短时间内投入生产。你当然不一定要相信我的话,我会和你分享一些工具,你可以用它们来真正加快速度。
第一天
挑一个可以用机器学习解决的问题。这听起来很明显,但是相信我,并不总是这样。我已经写了很多关于机器学习的好的和坏的用例,所以看看这些或者做一些研究,确保你正在处理一些可能的事情。
想想标记产品图片、推荐内容、让数据更容易搜索或对推文进行分类,而不是预测股市或制造无人驾驶汽车。
对于机器学习和人工智能来说,实际上有很多非常好的用例,关键是要想得简单,随着时间的推移,你可以变得更复杂。
让我们来看看一个新闻聚合网站的想法,它让你的用户可以根据主题、人物和内容进行搜索。
首先,坐下来决定你想让你的用户浏览哪类新闻。也许它们是科学、体育、政治、健康、技术和犯罪。
你可以用第一天剩下的时间收集数据。走出去,在这些类别中尽可能多地抓取文章,并按照类别名称将它们组织到文件夹中。
每个类别都有相同数量的例子,这一点很重要。
第二天
确保每个类别中有 100-500 篇文章(越多越好)。现在有趣的部分来了。访问 https://machinebox.io 下载 Classificationbox。你必须注册你的邮箱,安装 Docker,然后运行一个终端命令。不会超过几分钟。
一旦 Classificationbox 启动并运行,克隆这个开源工具,让你从你电脑上的文本文件中创建一个机器学习模型。在你的文件夹上运行textclass
,里面有文章样本。
/training-data
/sports
sports-example1.txt
sports-example2.txt
sports-example3.txt
/politics
politics-example1.txt
几秒钟后,你就会有一个可以自动对新闻文章进行分类的机器学习模型。假设数据集是好的,你的准确率应该在 90%以上。如果不是,考虑稍微清理一下数据集,或者简单地给每个类别增加 100 个左右的样本。
还不到上午 10 点,你就已经有了一个准备投入生产的机器学习模型。但是让我们继续。
下一件你想做的事情是让你的文章变得可搜索,但是当你开始聚集数百万篇文章时,如果你试图索引每一个单词,你会很快碰壁。此外,如果你搜索单词Radcliffe
,你希望能够返回相关的结果,无论那个人是在搜索丹尼尔·雷德克里夫的地方还是新闻。
再次,访问机器框并下载文本框。Textbox 是一个关键字和命名实体提取工具,它将为每篇新闻文章提供一点不错的元数据,可以在弹性搜索中很好地工作。这里有一些关于如何做到这一点的细节,但重点是:
- 按人员、地点、时间等过滤搜索。
- 轻松构建整个数据集的可视化,并查看趋势。
- 以惊人的速度处理和分析数据
- 还有更多…
第三天
文章有时附有人物和地点的照片。您可能希望能够标记文章中的人物,标记图像中的事物,以进一步改进搜索和分类。
机器箱有两个工具让这变得非常简单;面框和标签框。继续下载这两个。
虽然 Tagbox 可以使用自定义标签进行教学,但它也预先准备了成千上万个标签,因此它真的很容易开始,无需投入任何工作。当您开始编写应用程序的 web 服务部分时,您可以轻松地将每张照片传递到 Tagbox,并将响应存储在弹性搜索中。你甚至可以选择前两个标签,或者高于某个置信度的标签。
你可能也想开始识别文章中照片上的人。第一步是将每张照片传入 Facebox,然后将面纹存储到数据库中。你可以在这里阅读更多关于面纹是如何工作的。
一旦你建立了一个很好的面部指纹数据集,你就可以在任何时候浏览并教 Facebox 这些人是谁。它不仅会在你给它的新照片中识别你教它的这些人,而且你可以通过简单地更新你数据库中面纹与name
的关系,将时间上的学习应用到你已经处理过的照片上。
现在你已经准备好了机器学习模型,你可以在第三天下午开始构建 web 应用程序。
第 4/5 天
用这两天的时间构建 web 应用程序,汇总新闻故事,决定如何向客户显示信息,集成弹性搜索,也许还要处理客户登录。
然后,为每一个新的文章建立一个流,通过不同的机器盒子,并处理输出。
部署到您最喜欢的托管站点。
第二周
现在,你已经有了一个集成了多个机器学习模型的产品,可以做任何事情,从根据文章的写作方式对新闻文章进行自动分类,到使用照片和文章本身的内容来改进搜索。
你还可以做更多的事情。你可以开始推荐文章,人们更有可能根据他们是谁点击,检测并清除假新闻,或者建立自己的语言检测模型来进行自动翻译。
关键是,你应该能够在不到一周的时间内推出一个带有人工智能的产品或服务,即使你是从零开始。
什么是机器盒子?
Machine Box 将最先进的机器学习功能放入 Docker 容器中,这样像您这样的开发人员就可以轻松地将自然语言处理、面部检测、对象识别等融入其中。到您自己的应用程序中。
盒子是为规模而建的,所以当你的应用真正起飞时,只需添加更多的盒子
启动和扩展数据科学团队:业务利益相关者行动手册
与您的数据科学团队互动的最佳实践行动手册
这篇文章旨在成为与数据科学团队互动的最佳实践指南。本节摘自我关于启动和扩展数据科学团队的 摘要 ,并包含与 数据科学 IC 和 数据科学经理 行动手册的部分重叠。我的目标是一名业务利益相关方(PM、运营总监、业务分析师、CMO),他们非常依赖他们的数据科学团队,但在与个人沟通和与团队工作流集成方面存在困难。这篇文章是为那些提出以下问题的人写的:“我知道我需要与我在 __________ 的数据科学团队合作取得更好的结果,但是我不知道如何获得这些结果,或者我可以做些什么来改善这些结果。”
四句话总结:知道什么是可能的,什么是你想要的。在全公司范围内强制协调“业务影响”。发展商业智能技能。推广数据文化。
知道什么是可能的,你想要什么
(此部分与数据科学 IC 行动手册的“发现您自己的问题”部分有很多重叠)
我问我的受访者:“在你合作的团队中,什么最让你沮丧?”商业利益相关者和 IC 数据科学家经常给出的答案是同一个硬币的两面。利益相关方:
- “很难理解他们在做什么或如何工作,很难让他们交流他们在做什么。”
- “对于两周和两个月的项目缺乏共识。一切都承诺过多,兑现不足。”
- “他们给出了一个学术性的答案,而不是务实的.”
- “我们聊了很多。五周过去了,我们仍在努力解决数据管道问题。”
来自数据科学家:
- “利益相关者不知道数据集做什么和不存在什么.”
- “他们不明白工作的复杂性,也不明白为什么事情要花这么长时间。当我们建立一个测试时,他们没有意识到它必须出现在三个不同团队的路线图上,他们也不理解我们给他们的测试指标。"
- “我们总是遇到非范围内的问题”
- “他们不知道什么是科技债务,也不知道为什么我们有时需要清理这些债务。对他们来说一切都是临时的。他们无法解读数据科学的结果。”
- “没有什么东西是以一种让我们看得见的方式组织起来的”
过于简单地说:利益相关者因为无法理解他们的数据科学家而感到沮丧,数据科学家因为感觉被误解而感到沮丧。 XKCD 再次引用:“在 CS【数据科学】中,很难解释容易和几乎不可能之间的区别”。作为一个非技术利益相关者,你必须意识到:除非你投入了工作,否则你将不知道你的数据科学团队能够做什么。举个例子:我花了大约六周的时间,为 Wayfair US 编写了一个推荐算法,将“实际”性能提升到贝叶斯“实际与预期”性能。Wayfair Germany 团队认为不值得要求同样的算法——他们认为这对一小部分业务来说过于重要。实际上,为 wayfair.de 构建这个算法需要用四行代码(或类似代码)将WHERE storeid=”wayfair.com”
更改为WHERE storeid=”wayfair.de”
。如果你是一个商业利益相关者,你必须足够了解什么是微不足道的要求。
另一方面,数据科学家和利益相关者都认为,引发一连串问题的因素尚不可知。如果你的团队基于现有的数据,他们应该能够很快得出结论。其他问题则要困难得多—如果数据不存在,这可能需要前端团队收集工作,DBA 编写工作,ETL 团队添加到管道中/清理/标准化工作。A/B 测试将需要与店面和所有其他团队进行更多的协作,以便安排他们自己的测试。了解存在哪些数据集,以及数据科学团队在响应您的请求时面临哪些依赖关系。
务实/学术方面的紧张气氛经常出现。可以肯定的是,数据科学家的责任是产生对你来说被理解和有价值的工作。话虽如此,你的技术界限限制了数据科学家所能做的工作。如果你依赖于数据科学家,你需要培养一种起码的能力来理解他们构建了什么以及他们如何评估成功。回归、分类、聚类、均方误差、f1 评分、交叉验证和 p 值并不一定是你的第二天性,但你应该足够熟悉,能够理解为什么你的数据科学家建立了他们所做的工作。一位股东对他们的 DS 团队说:“不要提出我不理解和不同意的建议。”发展你的背景,了解你的团队的建议。
迫使全公司在“业务影响”上保持一致
(此部分与数据科学经理行动手册中的“有意安排优先级流程”部分有很多重叠)
*“知道什么是可能的,你需要什么”*填补你的数据科学团队能够做什么、什么是容易的、什么是几乎不可能的盲点。认识到你也拥有不对称信息,你知道商业环境。为了让您的数据科学团队与公司保持一致,您必须填补他们对工作价值的盲点。这必须是利益相关方主导的对话;如果您的团队不能就数据科学项目的“业务影响”达成一致,您甚至无法尝试有效地分配数据科学资源。来自分析学的 SVP:“你需要通过练习将任何东西转换成一种通用货币。你可以将任何事情转化为投资回报,挑战在于剔除扯淡的商业案例和分配项目,因为轮到某人获得数据科学资源了。”重复一下数据科学经理剧本,优先化可能有点政治性(“这是一个足够小的公司,知道你是否过度使用或未充分使用数据科学资源”)到高度政治性(“我们支持的每个团队都平等地使用我们的时间”)。您的公司需要根据投资回报(在这种情况下,是数据科学家的时间)进行优先排序。您必须知道如何估计所需的数据科学资源,并以一种可以与他人的潜在项目进行比较的方式,提供真实的点对点业务结果影响。
让您的数据科学家参与到对话中。通过在优先级会谈期间将 DS 团队带入房间,您可以填补他们业务环境中的空白,允许他们在未来开发自己的项目。我采访过的运作最好的团队有一个共同点:项目可以以精英管理/自上而下的方式产生,数据科学家应该提出一些工作建议。伟大组织中的人知道如何消除彼此的盲点。
此外,与您的团队分享过去项目的成果。数据科学家可以感觉他们在一个模型上努力工作,成功地实现它,然后:无线电静默。让您的数据科学团队更好地了解没有该解决方案会发生什么。他们创造了一些重要的东西,但往往没有意识到他们带来的成功。事实上,尽可能向上游发送结果。当一个业务利益相关者将一美元的成功归功于构建模型的数据科学团队、构建管道的 ETL 工程师、存储代码的 DBA 以及现场设置代码的前端工程师时,这种反应是会传染的。这是一种让每个人都感到兴奋并准备好赢得下一场胜利的沟通方式。
发展商业智能技能
如果“知道什么是可能的”部分是关于了解你的数据科学家的能力,这是关于帮助他们(或者至少,不打扰他们)做其他事情。商业智能意味着拥有在 SQL 中提取数据并自己执行基本分析的技术能力,并且能够围绕报告自助处理事实问题。数据科学家的一个一贯的挫折是缺乏利益相关者的分析能力:门槛越低,需要清除的障碍就越高,以获得对解决方案的认可。
这篇文章是为“非技术”商业领袖写的。我已经看到太多的利益相关者倾向于这个短语,好像它是一个骄傲的徽章。不要认为“非技术”是一成不变的,非技术经理有不同的等级,你和你的团队应该每天努力提高你的技术敏锐度。您的团队必须在您的数据科学支持下帮助迭代解决方案,如果您无法从 SQL 中提取数据来确认其工作,他们就无法为问题构建复杂的解决方案。
我采访的一位数据科学家曾在几个地方工作过,他热爱自己目前的工作,因为没有人会问:“你能帮我们实现这个目标吗?”他可以要求业务分析师自己获取数据,每个人都同意输入数据——来自数据库的特定 SQL 查询作为基本事实。另一位 DS 经理觉得自己被拉向了相反的方向,她一直觉得自己工作的一部分是保护自己的团队免受应由另一个团队承担的特别报告任务。
也许证明开发这些技能的最简单的方法是通过查看项目积压和您的数据科学部门的工资。高水平的数据科学家是昂贵的。不要让他们做你的临时报告——让他们自由地做你雇他们做的工作。
推广数据文化
我为这些文章采访的许多人都是前 Wayfair 员工,他们加入了其他科技公司。他们分享的一个令人惊讶的观察结果是,你能从创始人身上看出多少公司的 DNA。我们大多数人都觉得 Wayfair 在很大程度上是由试图找出如何销售家具的工程师经营的。Airbnb 以产品驱动著称。其他公司更注重高层次的商业/营销。我采访过的一家公司有着深厚的新闻调查传统,另一家公司在结束会议时会问这样如何能让客户更开心。数据科学团队成功与否的一个重要预测因素是公司的“数据文化”:对话在多大程度上基于分析,决策在多大程度上基于分析。
我参加过这两类公司的会议。在拥有良好数据文化的公司,任何业务建议都需要数据来支持,或者需要生成数据的计划。在另一种情况下,有人会为一个重大问题编写一个非凡的、有证据支持的解决方案,但会遭到拒绝,“我不知道 CRO 会怎么想——我们需要在 30 秒内做出一些我们可以向他解释的东西,否则就太复杂了。”你必须建立一个生态系统,在这个生态系统中,决策是由事实驱动的,而不是由个性驱动的,信息是不断被寻找和利用的。
我采访过的许多公司天生就有良好的数据文化。然而,我与一家缺乏数据文化的公司进行了一些最具启发性的对话:首席运营官进来后发现了一家老派公司,他们的思维模式是:“我们已经在这里 50 年了,从来不需要数据科学家。”创建数据文化尤其困难,因为该公司一直做得很好,而且对过去的成功存在巨大的确认偏差。他们的 DS 团队被雇佣更多是为了应对竞争对手的行动,而不是出于内部的愿望,他们随后在组织中被牵制。首席运营官分享了两个教训:数据科学团队必须被邀请参加会议,那些最兴奋地接受数据科学见解的人已经是最有自我服务能力的人了。他最需要的利益相关者是:“能够帮助我为事情做商业案例,并愿意接受和支持数据科学团队的人。帮助建立全公司感兴趣的人的联盟。”
在一个没有数据文化的公司,你需要一个来自技术方面的第一信徒。从首席运营官的角度来看,首先有一个利益相关者愿意加入数据科学并与之互动是非常必要的。“你花时间在电脑上精通技术,这是你需要添加到技能组合中的新事物。没有强迫任何人,但它最终会通过收养或替代发生。”尽你的一份力量在你的公司建立数据文化,因为它正以这样或那样的方式发生着。
启动和扩展数据科学团队:DS 个人贡献者行动手册
构建数据科学职业生涯的最佳实践行动手册
本文旨在为个人贡献者的数据科学职业生涯提供最佳实践指南。这一节摘自我关于启动和扩展数据科学团队的 摘要 。我的目标是一位数据科学家,他通过行业外的任何来源开发了一个标准工具包。在我看来,有大量的资源可以将 ICs 从零扩展到 Kaggle master/面试就绪。这篇文章是那些资源的延续,对于问这个问题的数据科学家来说:“我已经学会了技巧。我已经通过面试了。这是我在 ______ 的第一天。现在怎么办?”
四句话总结:把自己嵌入业务中。寻找自己的问题。迭代求解。知道你什么时候完成。
融入企业
像 Spotify 和网飞这样的推荐算法在很大程度上依赖于过去对用户行为的观察来提供未来的内容推荐。这种“协同过滤”方法在稳定状态下工作得很好,但是当用户或内容是全新的,或者当所有用户/内容都是新的(例如,服务的第一天)时就失败了。这被称为“冷启动”问题,这个名字来源于一辆在低温下不能很好启动的汽车,但当它加速时却能很好地工作。
同样的事情也存在于数据科学家的第一天工作中。Kaggle 和在线课程为数据科学家提供了一个完全包容的数据集,其中包含经过清理和良好记录的数据以及明确定义的目标(最小化预测房价的均方误差,最大化图像预测标签的 F1 分数)。这并不是工业中项目的建议、优先排序或评估方式。这可能是一个显而易见的观察结果,但重点仍然是:这些信息是没有给出的,你有责任发展商业头脑和关系来发现它。你需要将自己融入到业务中。
嵌入意味着了解坐在你上游的人:数据库管理员、机器学习工程师、基础设施工程师等。记住他们的名字,他们坐在哪里,知道什么是快速请求,什么不是。了解如何将您的请求放在他们的优先列表中(空闲时的快速请求,票务系统/电子邮件中的较大请求?).了解他们是如何被评估的,他们关心的指标是什么。了解什么会惹恼他们,不要去做。
嵌入意味着了解商业利益相关者:坐在你下游并依赖你工作的人。了解他们想做什么,熟悉你为他们所做工作的业务应用。告诉他们什么是有帮助的,他们的盲点是什么,他们希望他们的解决方案是什么形式。
嵌入意味着非常广泛地理解业务环境。组织内的各种孤岛是什么,他们试图优化哪些部分?是什么让 CEO 夜不能寐?公司范围内的重要权衡是什么?为了让公司发挥潜力,需要发生什么,你的工作如何配合?
将自己嵌入到团队的工具箱中。数据科学家通常只有“Macbook Pro”经验:个人对给定数据集编写的一次性分析/模型构建/预测。你必须从 Macbook Pro 数据科学转向行业数据科学。从本地小的.csv
文件,到跨分布式服务器持续运行的数据管道。了解如何在协作环境中构建防弹模型,这可能意味着管理代码库的 Git、依赖关系的 Docker、作业调度的 Airflow、模型部署的 AWS 以及一般的软件工程。特别是对于学者来说,工程最佳实践可能是一个巨大的盲点。很有可能,在完成一个项目之前,您需要学习一些与编写 xgboost 分类器完全无关的工具。弄清楚那些工具是什么,比任何人都学得好。
最后,嵌入到您团队的工作流程中。就像你的团队有偏好的工具一样,他们也有使用这些工具的偏好方式。你的团队是如何工作的?项目是如何优先化、分配、完成、沟通和评估的?数据科学 MOOCs 不会强迫你问这个问题。了解别人能为你的项目做出什么贡献,以及你能为别人做出什么贡献。最终,你的长期成功取决于持续的技能发展。了解你的团队是如何获取知识、分享知识和相互发展的。想想如何兑现你的承诺。扩大您团队的总知识库,使某人能够更好地完成工作。
来源自己的问题
我采访的一位数据科学家告诉我:“你经常坐在技术问题和业务问题之间。如果你不能翻译它们,你就不能在这个领域取得成功。”数据科学家和业务利益相关者之间的一个持续挑战是缺乏知识重叠:业务利益相关者不知道技术上什么是可能的,数据科学家对业务的了解不足以解决重要的问题。你将自己嵌入到业务中来建立这种知识。下一步是采取行动,主动寻找数据科学解决方案能够给公司底线带来巨大变化的机会。再说一次,这不是卡格尔教你的一课。
没有 XKCD 的参考,任何科技文章都是不完整的。“在 CS(数据科学)中,很难解释容易和几乎不可能之间的区别。”从这个角度考虑你的公司所面临的挑战,并把为重要问题寻找技术上简单的解决方案视为你的责任。这一点对我个人来说很重要,因为我不认为我在工作的头几年学到了这一点。尤其是在一个庞大的公司,已经有了一个人可能不知道的更多列数据和一年的积压票据,很难认为你想出的主意实际上是对你时间的最好利用。
在我为 Wayfair 编写推荐算法的第二年,我终于明白了这一点。我们的想法是显示分段的邮政编码特定排序——这个想法是,即使我们以前从未见过一个人,他们来自的邮政编码可能是我们可以利用的东西;与普通人相比,他们的偏好可能与所在地区的其他人更相似。不幸的是,我们没有在任何地方记录这些数据,也没有办法重新创建这些数据。这让我很失望,但直到一位 ETL 工程师说“如果你放入一张票,我们就可以记录它”,我才意识到甚至有可能改变我的数据集。一周后,我们开始记录数据,两个月后,我们推出了新的分类,这是一个巨大的胜利。
这里的要点是,您需要与 DBA/ETL 团队保持足够的协调,知道可以添加什么,知道业务问题是什么,并且足够有创造力/足够现实,知道记录一条新数据可以让您首次解决某个问题。商业知识会比技术知识让你走得更远,但前提是你要将你的商业知识付诸行动。
换句话说,业务利益相关者对他们的数据科学团队的一致抱怨是,他们倾向于采用过于学术和科学的方法来解决问题。许多经理和利益相关者经常持批评态度,认为他们在协作流程中的角色是控制个人贡献者的数据科学马力,并为他们指明正确的方向。不要强迫别人把你从一个学术练习拉回到一个实用的解决方案,要成为实用解决方案的推动力。
迭代求解
一旦你确定了一个重要问题的实用解决方案,就带头与业务涉众一起迭代以得到一个实际上对他们有效的解决方案,然后是一个更好的版本。这个等式的迭代部分很重要,因为这也不是数据科学教育的一部分。你不能去参加 Kaggle 比赛,然后说,“我知道你要求的是均方差,但是绝对误差在这种情况下更有意义吗?”或者,“此栏似乎主要是 2016 年的垃圾数据—还有其他地方可以找到当前数据吗?”或许最重要的是,
这仍然是你对这个问题的想法吗?这看起来像是你的团队可以接受的好的解决方案的开始吗?我完全跑题了吗?我们在为正确的事情优化吗?
一位经历过这种痛苦的 IC 说:“你可以在一个项目上走得很远,同时做出一个别人不同意的假设。”迭代方法是数据科学和商业领袖之间积极工作关系的关键。利益相关者反复遇到的一个挫折是科学家缺乏数据灵活性。一位非技术项目经理对他的数据科学团队有这样的看法:
真正聪明的人,有能力,有技能。我们给他们工具和数据。他们告诉我们‘数据在说一些具体的东西,所以这是我们必须做的。’他们对我们的投入很固执。不要做“幕后的巫师”。不要拿出一个我不理解不认同的推荐。
最后一句话有点矛盾,(你要么不理解,要么不同意……但不能两者都理解),但它阐明了一个极其重要的真理。不管你的工作在分析上有多正确,如果你工作的团队不理解你的解决方案,你都不会接受。永远不要低估一个非 STEM 背景的同事无法区分你所说的是观点还是事实;“我们应该这样做”可以有多种含义。记住,理解的责任在交流者身上。
我采访的一位 IC 说“我根据利益相关者的反馈来评估项目的成功。如果我建立了一个伟大的模型,但没有人使用它,没有人得到帮助。“我的利益相关者觉得我有用吗,他们的衡量标准有所改进吗?”“这是一种正确的思维方式,但 ICs 应该更进一步:将为评估成功的方法做出贡献以及就您的工作对您的利益相关者进行教育视为您的责任。商界的一个老生常谈是,在没有就观众将会收到的内容进行指导的情况下,永远不要进入最终演示。在数据科学中同样如此。表述项目的一个好方法是:
“问题,老办法,新办法,改进。”
与业务利益相关者一起工作,不断地进行压力测试,以确保你正在做的工作仍然适合这个框架。
转向迭代过程对你培养的声誉也很重要。再一次,从教育/Kaggle 竞争的角度来看,你只有一次机会找到解决方案,你的客户并不重要。在一家公司解决问题根本不是一次性的表现,所以不要把它当成一次性的。借用一个体育比喻来说:你应该尽可能多地打出积极的结果,而不仅仅是一个本垒打。避开“头戴式耳机,低头,带有 zenburn 配色方案的垂直屏幕,窗帘后面的向导”的描述。巩固并增加你人际关系中的开放文化。尽你的一份力量去赢得尊重和信誉,人们会信任你的意见和优先安排你的工作和时间的能力。
知道你什么时候完成
我问我采访的数据科学家:“你如何知道一个解决方案何时完成?”许多人不知道。一个 IC 说,“老实说,这取决于数据科学家个人。如果你一直致力于一个问题,我认为没有人会阻止你,直到它成为一个问题。”DS 经理经常指出这是一种挫折,一位经理说,“我的团队一直在进行超参数调优,我对此也感到内疚。看不到大局是一个大问题。”另一位经理说:“我必须确保人们用他们的时间为商业价值做出贡献,而不是建造自舔冰淇淋甜筒。在这一行,人们不想成为 PM-y,他们不想做除了写代码以外的任何事情。”要知道这是数据科学家当之无愧的刻板印象。你是如何成为例外的?
几乎所有的集成电路表示,时间管理是他们可以努力的事情,他们缺乏对何时进入下一个项目的意识。发展这个框架。这里的一些必读资源是机器学习:技术债务的高息信用卡和这个 Reddit 关于“你有哪些不受欢迎的数据科学观点”的帖子。山羊安德烈·卡帕西写道:“在伸手拿火箭筒之前,应该总是先试一试 BB 枪。”
做一些必要的工作来理解时间和复杂性的权衡,并且有意识地说出你的决定。一位数据科学主管告诉我:
存在更多代码、低质量代码和复杂性的成本。这些成本会随着时间的推移而增加。如果你想做一件更复杂的事情,那很好,但是告诉我你为什么要支付这个费用。可以用 tensorflow,但不要先用。
就这一点而言,我以前见过一个用于 126 个数据点的递归神经网络。126 个数据点要用 Excel 分析。从那个相同的 Reddit 线程,
商业知识会比技术知识让你走得更远。对于很多问题,xgboost +贝叶斯优化会非常快地让你获得 95%的价值,你可以通过识别新的机会并快速而不是完美地解决它们来产生更大的影响。此外,对于任何刚刚开始探索数据科学的组织来说,实施几个“足够好”的模型将比构建一个极其精确的模型在短期内提供更多的价值。
我从一位数据科学项目经理那里得到了一个很好的建议,她以前和软件工程师一起工作,她觉得他们在迭代和有效工作方面做得更好:当你估计你将在一个项目上花费的时间时,把它作为一个决策树来做。强迫自己提前定义停止点,当事情足够好,增加的一小时或一天可以更好地利用时。这又回到了“迭代”部分:如果线性回归现在已经足够好了,可以轻松地删除项目的第二和第三部分。
启动和扩展数据科学团队:DS 经理行动手册
构建和管理数据科学团队的最佳实践行动手册
这篇文章旨在成为管理数据科学团队的最佳实践指南。本节摘自我的 摘要 关于启动和扩展数据科学团队的内容,并包含与 数据科学 IC 剧本的部分重叠。我的目标是一名数据科学家,他作为个人贡献者取得了成功,目前正在努力解决经典的管理问题:我如何扩展、聘用、评估和沟通?在数据科学领域,考虑到合格候选人背景的巨大差异,这是一个更加棘手的问题。这篇文章是为那些问这个问题的人写的:“作为一个数据科学 IC,我已经取得了成功,也承担了责任。我的任务是在 ________ 发展和领导一个团队。现在怎么办?”
四句话总结:不断调整你的组织结构。最大化团队的知识转移。有意识地安排你的优先顺序。强调解决方案的最低复杂度。
持续调整您的组织结构
在我剧本的所有句子四句话总结中,这是迄今为止最笼统/定义不清/晦涩难懂的。我很抱歉。然而,有一个原因:弄清楚如何建立一个数据科学团队真的很难;没有固定的“最佳实践”,它高度依赖于公司和员工,而且完全可以肯定的是,无论您现在有什么设置,都不是六个月前或六个月后的正确设置。我找到的资源和我采访过的经理给出了不同的、通常是矛盾的解决方案。我已经研究了如何建立一个数据科学团队足够长的时间,以确信没有正确的答案。作为一名经理,你能做的最好的事情就是不断调整你的组织结构、数据架构、工作流程和文化,以确保你积极地扩展你的团队来满足你公司当前和未来的需求。
数据科学组织最大的问题:你的团队是集中式的还是嵌入式的?集中式:坐在一起工作的数据科学团队,扮演内部顾问的角色。DS 团队的“时间”是分配给业务涉众的资源。嵌入式:个体数据科学家坐在特定的产品团队中,他们的日常工作在团队中高度迭代,他们的项目范围有限。DraftKings 有一个集中的团队,Zillow 也是。Wayfair 两样都有。 Airbnb 因为这个原因从集中式迁移到混合式:
我们从集中式模型开始,被它提供的相互学习的机会所吸引,并在度量、方法和过去工作的知识上保持一致。虽然这都是真的,但我们最终是在决策业务中,并且发现我们无法成功地做到这一点,因为我们的合作伙伴团队不完全了解如何与我们互动,我们团队中的数据科学家不了解他们要解决的问题的完整背景,也不知道如何使其可行。
Chuong Do 有一篇关于集中式/嵌入式的优秀文章,强调了这两种方法的一些主要缺点。分散化可能会导致知识孤岛、更少的协作机会、更难实现标准(从代码库到雇佣),以及难以共享基础设施/最佳实践。集中化可能会导致团队缺乏业务背景或合作伙伴的支持,还可能导致“数据科学被视为一种支持功能,回答产品经理的问题,而不是作为真正的思维伙伴运营,并从数据知情的角度积极推动对话。”
在采访 DS 经理时,我普遍发现每个人都认为他们有一个混合解决方案,该方案吸收了集中化和嵌入式的最佳部分。这既是不可能的,也是努力的目标。要认识到,在非常成功的公司里,非常有才华的人对实现这一点的最佳方式意见不一,所以作为经理,你的职责是在这个时候为你的团队做出最佳决策,并完全适应这种结构可能不再有意义的时候。以下是我对构建一个组织结构的想法,并警告说它们可能会在未来发生变化。
从一个集中的团队开始。当你开始雇佣数据科学家时,你会有许多需要支持的业务团队,而数据科学家太少,无法嵌入。在拥有小团队的小公司,知识共享/业务背景/跨职能协作更容易。办公室可以很小,你知道每个人在做什么。“知识筒仓”风险较小。
当算法密集型项目变得足够大,以至于永远需要数据科学家时,嵌入数据科学家。Wayfair 慢慢将数据科学家嵌入他们的定价、推荐和营销团队;认识到这些业务部门是如此基于算法和分析,他们需要由面向业务的数据科学家领导。Zillow 的 Zestimate 团队也是如此。Wayfair 和 Zillow 都有一个集中的数据科学团队来支持他们的其他业务。要小心,从招聘和资源管理的角度来看,嵌入数据科学家更难——这些 IC 需要有高水平的商业敏锐度,他们不会在其他任何事情上工作。因此,在为嵌入式结构招聘员工时,时机更为关键。
嵌入式数据科学家应该尽可能长时间地向中央数据科学部门报告。嵌入肯定会导致业务环境的知识孤岛。这里的目标是尽可能长时间地调整其他一切。数据科学家如何工作、协作、共享代码和结果、评估成功。这是针对*知识转移、*的优化,我们稍后会谈到。
当你捉襟见肘时,向外看,扩大你的团队规模。但是要非常挑剔,尤其是更早的时候。永远不要低估糟糕招聘的复合成本。要深思熟虑,不仅要评估人才,还要看是否是合适的人才。你需要一个研究型的雇员来不断完善业务的核心部分,还是需要一个快速行动的 IC 来支持许多团队,完成许多 2-3 天的问题来获得 90%的正确答案,然后继续下一件事?在接下来的六个月里,这些需求会有什么变化?
最后,根据你的非技术业务团队的能力和支持做出人事决策。他们能力如何?在这家公司做分析师意味着什么:轻 Excel 技能还是重 SQL?您公司的其他部门与数据科学团队的关系如何?业务利益相关者是强烈要求 DS 解决方案,还是抗拒改变?我交谈过的大多数公司都是技术型的(< 10 年历史,裸露的砖块,免费的十字架,站立的桌子,桌上足球),并希望获得更多的数据科学支持,但我与一家 40 多年历史的媒体公司进行了一些最有趣的对话,该公司以不使用技术和自动化而自豪。我从首席运营官那里得到的建议是:
我们不希望这些人在组织中四处游荡,寻找需要解决的问题。最坏的想法是把它们抓来放走。你必须有一个与愿意接受数据文化的利益相关者高度接触的模型。花点时间与目标团队坐下来,听听他们的痛点、机会点,以及对他们的评估。让他们问:“你能给我们展示一下你在做什么吗,它是如何令人沮丧的,我们每天都在做什么,我们是如何获胜的。”
首席运营官的经历让我大开眼界;在我工作过的所有地方,企业都想要更多的数据科学资源。这不是普遍真理。作为一名经理,你需要了解企业的数据文化,以及利益相关者为你的 ICs 提供成功所需的环境和支持的能力。你必须在 DS 团队和公司其他人之间建立信任点,这需要雇佣能够与你的利益相关者合作的 ICs。你的数据科学家越是以商业为导向,你的公司越是技术能力强和开放,这就变得越容易。
最大化您团队的知识转移
我开始我的项目是为了传达这一点,我怎么强调都不为过。IC 数据科学家可以像对待个人运动一样对待他们的工作,而你的工作就是让他们像团队一样工作。Kaggle 和大多数数据科学教育资源都是个人行为。你不能假设一个具有定义的工作流和编码标准的协作团队会自己出现,事实上,我见过相反的情况——个人并肩工作,在他们的本地机器上,用 Python 2.7、3.5 和 r 多次解决相同的问题。
你的目标必须是增加团队成员之间的知识转移和指导,这将产生更好的代码和更强大的团队。这需要从“个人贡献者”到“团队成员”的文化转变。没有这种转变,你就无法培养出工业级的数据科学团队。你必须强调,集成电路评估将不仅仅基于项目,还基于开发其他项目和改进团队工作流程、标准和工具。从代码审查开始。
代码审查:通常,人们认为这是一种在网站崩溃之前检测有缺陷代码的方法。这当然是好的,也是必要的,(当我忘记在“ORDER BY
”中的“DESC
”来对产品排名进行排序时,我会喜欢代码审查,这导致 Wayfair 在四个小时内从最差到最好地推荐项目,这在当时是一个 20 万美元的错误),但当代码不能关闭网站时,或者没有人在技术上像编写它的人一样有能力时,代码审查通常被视为没有必要。
这错过了代码审查最好的部分:这是一个学习机会,一个专门的“双向道”知识转移,迫使团队成员学习其他人如何编写代码。团队中最没有经验的成员可以从审查别人的代码中学到很多他们不理解的东西,而最有经验的成员可以学习如何指导。代码评审不应该只是回答这个问题,“这会破坏网站吗?”。审查应侧重于:
- 这段代码是否可读、有弹性、注释良好、符合团队标准?是正确的抽象/参数化/模块化水平吗?(计算机科学原理)
- 这些数据科学和统计方法是否合理?(数据科学原理)
- 这些连接是否有效,这些表的结构是否针对日常插入进行了优化,它们的设计是否正确(基于它们应该是读的还是读/写的)?这对以任何方式使用 Hive/HDFS/Presto 或 ETL 的团队来说都是必不可少的。(数据库管理员原则)
- 这项工作是正确的,可操作的,令人信服的,表达良好的,可实施的吗?(商业原则)
为了使知识转移和代码审查有效,团队必须对“好”的样子有一套共同的信念。因此,管理人员必须以协作、灵活的方式定义一套团队标准和工作流程——同时告诫人们,鼓励个人寻找更有效、更强大的方法来改进这些标准和工作流程。对这个问题的答案进行逆向工程:“如果我团队中的一名数据科学家想出了一种更好的方法来做某事,那么这种知识如何每天以非选择退出的方式传递给其他人?”Domino 写道:目标是以模块化的方式实现复合协作。“当高绩效的数据科学团队站在前人的肩膀上时,他们的工作效率最高。”这是我理想世界中的一个团队工作流程/标准集的例子:
我们的团队使用相同版本的库 Python、Scikit Learn、Presto、Tensorflow 和作为 SQL IDE 的 DBeaver、作为 Python IDE 的 Jupyter 以及用于作业调度的 Airflow。在所有这些领域,人们有不同的偏好和不同的知识基础。这是一种优势——帮助我们提出新的和改进的管道和标准。就像个人因对业务产生积极影响而受到鼓励和奖励一样,他们应该不断寻找更有效或更强大的方法来改善团队的工作流程和习惯。将有代码审查,无论是业务案例,效率案例,以及代码是否写得正确。(符合 PEP8 标准,棉绒)。只有格式正确的代码才会被提交。代码审查被看作是一个教授和学习以及捕捉错误的机会。回购是在项目层面上组织的,人们通过协作工作,让新的集成电路达到速度,并让有经验的集成电路有能力承担教学/领导角色。
关于业务背景和过去团队项目的知识也必须转移。公司有许多名称的解决方案:站立,讲故事活动,学习学院,午餐和学习,头脑风暴会议,知识仓库,维基。Airbnb 有一篇关于数据民主化的博文,他们所有的项目都以一页纸开始,上面写着“项目的意义是什么,我将如何去做,我将如何衡量成功”。
这些解决方案中的任何一个都可以在给定的时间点上为一个团队工作,但是我与之交谈的许多人都警告说它们不能很好地扩展。关于讲故事活动:“我们曾经有两个团队,每个月做一次报告。现在有九个团队——我的人已经工作了六个月,但我不知道三个团队在做什么。”在头脑风暴会议上:“当我们还小的时候,这很有效,现在我有一些我没见过的人给我建议,告诉我如何解决他们以前没见过的问题。”午餐时,他学到:“一旦事情变得太大,人们就不再去了”。
代码评审必须以非选择退出的方式执行,当你的组织规模扩大到原来的三倍时,知识转移也必须如此。您的工作是让您的团队支持有效的流程,并传达数据科学 IC 工作的一个重要部分是记录他或她试图解决的问题、他们如何解决问题以及解决方案的成功。
有意识地安排你的优先顺序
IC 数据科学家和商业利益相关者的一个普遍共识是,他们不知道项目是如何优先排序的。优先级划分的范围从高度数据驱动(“我们根据每个数据科学家周的估计收入增长来考虑所有事情”)到故意不根据数据驱动(“没有必要确定优先级,我们只是做重要的事情,事情不需要被证明是合理的或优先的”)到有点政治性(“这是一个足够小的公司,知道你是否过度使用或未充分使用数据科学资源”)到高度政治性(“我们支持的每个团队都平等地使用我们的时间”)。同样,IC 数据科学家扮演的角色从“我选择我的项目”到“我不选择我的项目,十个项目被分配给十个人,他们不知道为什么。”
作为数据科学领导者,您必须迫使您的公司在“业务影响”是什么以及如何衡量它这两个问题上保持一致,并且您必须确保您的 ICs 和业务利益相关方之间关于优先顺序的对话是自下而上和自上而下的。您必须引入数据科学团队通常不具备的透明度。一位 DS 经理告诉我,“每个项目都有不同的价值,我们无法相互比较。”如果你不能比较项目,除了政治上的,你怎么可能分配它们?在同样的程度上,你必须认识到,在数据科学中,很难解释容易和几乎不可能之间的区别。您的数据科学家对于要做的业务问题肯定有不完善的信息,您的利益相关者对于解决方案需要做多少工作肯定有不完善的信息。您必须从业务利益相关者和 ICs 处获取项目,汇总关于这些项目的预期成本/收益的完整信息集,汇集这些数据,并以一种对各方都显而易见的方式呈现这些数据。
这一过程的关键是确定您的数据科学团队是合作伙伴,而不是服务提供商。你的团队必须通过证明他们的价值来建立信任和权威:寻找好的项目,获得巨大的成功,并就此进行报告。这允许团队开始文化:“如果你有一个想法,我们会和你一起工作,但我们有一个桌子上的座位。”你应该避免门票系统和政治,团队资源按比例分配给依赖的利益相关者。做到这一点的最佳方式是证明你和你的团队有足够的业务背景,可以与他人合作——如果你给我们解决这些问题的空间,我们会的。
强调解决方案的最低复杂度
数据科学 IC 行动手册的了解何时完成 部分与本部分高度重叠。翻新:通过学术或在线方式接受教育的 IC 数据科学家没有接受评估其算法复杂性的培训。许多 IC 承认他们不知道问题何时解决,大多数表示时间管理是他们正在努力改进的。你的工作是建立准确性与时间和复杂性之间权衡的框架,并帮助你的直接下属找出他们应该继续前进的时间。认识到你的集成电路有一种自然的倾向,那就是花费太长的时间来构建太复杂的解决方案。设置护栏是这项工作的一个重要部分,培养团队的常识和直觉以正确的方式开始解决问题也是如此。
你必须平衡这些标准和个人发展:认识到人们确实需要学习和成长的空间,这需要用新技术解决新问题。众所周知,数据科学组织深受对工具的执着之苦,我一直站在这两方:在我职业生涯的早期,我故意将自己放在较低优先级的点击流项目上,以学习分布式计算原理/Hadoop/Hive,当队友们做了同样的事情,为了构建卷积神经网络而构建卷积神经网络时,我感到沮丧(我们稍后将弄清楚图像分类如何改善业务)。目前,这种对工具的执着是 Tensorflow、Spark Streaming、GANs 和 RNNs,但过去是其他东西,将来也会是其他东西。多米诺称之为“一种‘银弹’思维文化,一些数据科学家认为只要获得 Spark Streaming 和 TensorFlow 就能解决他们的所有问题……在许多情况下,数据科学家将他们的工具争论作为一种荣誉徽章,这个徽章被包装在他们的身份中。”一个 IC 告诉我,“我知道 Tensorflow 不是解决我的问题的正确方法,但总是有同行的压力要使用这个很酷的东西。该公司的博客帖子和学习学院不是为了减少随机森林分类器的客户流失。这个行业发展如此之快,我需要跟上。”另一个人说,她衡量自己的个人成长,她实施了哪些新技术。
这两位数据科学家都不是不讲道理。拥有 Tensorflow 和 Spark Streaming 的经验可以在简历上产生很大的影响,你不会学到用同样的工具解决稍微不同的问题。DS 经理必须意识到具有正确工具/复杂性的解决方案与作为学习机会的解决方案之间的矛盾。您必须在工程解决方案与团队快乐和发展之间找到适当的平衡。像其他事情一样,认识到这是你需要有意识的、透明的和灵活的事情。一个很好的解决方案是给你的团队一个明确定义的时间段,让他们可以用他们想学的工具做他们想做的事情,但也给他们提供指导和阻力:“如果你想做一个更复杂的思考,告诉我你为什么要支付这个成本。”与你的团队交谈,确保他们感觉像是在学习,当你有机会让某人用对他们来说是新的解决方案或技术解决实际问题时,相应地分配“延伸”项目。
启动和扩展数据科学团队:项目摘要
将数据科学融入组织的最佳实践行动手册
这是一个关于公司内数据科学领导力和组织的秋季学期独立项目的最终成果。我在哈佛商学院读 MBA 的第二年,技术与运营(TOM)部门的Kris ferre IRA是我的导师。我采访了 13 家公司的 29 个人(DS 个人贡献者、DS 经理、非技术业务领导)。我利用这些采访制定了启动和扩展数据科学团队和职业的最佳实践行动手册:一份针对 数据科学家 ,一份针对 数据科学经理 ,一份针对 业务利益相关者 。
介绍
这个项目的想法是在我开始一份新工作时产生的。数据科学入门总是一个混乱的过程,但我喜欢按照这个顺序开始:数据、代码库、工作流。深入一个数据集需要你张开双臂去寻找任何地方,任何人都在记录你可能感兴趣的东西,并找出公司具体的细微差别。它会问这样的问题:“重定向邮件存储在哪个数据库中?那个服务器的登录信息是什么?agent_id
、uu_id
、agentuu_id
有什么区别?为什么order_id
一栏出现负数和重复数?”概括地说,我将每天使用哪些表和数据库,并最终记住它们?
接下来是代码库:在我之前的那些人是如何用他们挖掘的数据建立管道、预测、解决方案和分析的?他们已经解决了哪些我不需要自己解决的问题?
最后,工作流程:这个团队如何编写代码?他们坚持自己的标准是什么?他们如何对项目进行优先排序,验证和交流结果,分享知识,他们如何让自己变得更好?
我发现的数据集是标准的——大部分是结构化的 SQL 表,分布在几个文件系统中,还有一些额外的文本和图像数据。然而,代码库和工作流程与我习惯的非常不同。团队成员在他们的本地机器上编写、测试和保存代码。代码库是个人的(“Ian 的 git repo”),而不是基于项目的(“定价算法 v2”)。团队成员用 R 和 Python 解决同样的问题。团队坐在一起,却不在一起工作。
我以前在类似的项目中用类似的数据集做过类似的工作,但是从组织上来说,这是一个很大的不同。我过去的团队有一个标准化的工作流程,共享一套开发工具,共享一套编码标准。团队设计和工作流程旨在增加团队成员之间的知识转移和指导,从而产生更好的代码、更好的业务成果和更强大的团队。对你的评估不仅基于你作为个人贡献者的工作,还基于你作为团队成员的工作;基于发展他人和改进团队工作流程、标准和工具的评估。
我的经历迫使我意识到,尽管有许多令人难以置信的方法来培养数据科学家,但在如何在公司内组建和扩大数据科学团队方面,几乎没有资源或专家。将数据科学团队整合到更广泛的组织中可能会导致困难、误解和运营效率低下。个人贡献者数据科学家(ICs)、数据科学管理和非技术业务领导者都有机会帮助弥合组织之间的信息鸿沟,并改变围绕数据科学家/数据科学团队工作的文化。
我调查了依赖数据科学团队解决核心问题的公司的 ICs、数据科学管理和非技术业务利益相关方。我试图找出他们是如何工作、沟通、协作、区分优先次序和评估的——以及这个过程中的盲点和偏差。我利用这些对话编写了三份启动和扩展数据科学团队和职业的最佳实践指南:一份针对数据科学家,一份针对数据科学管理,一份针对依赖于数据科学团队的业务利益相关者。但是,要理解当今数据科学团队的问题,我们必须理解我们是如何走到这一步的。
数据科学的兴起
“数据科学”的兴起是迅速的,并且有据可查。根据 Google Trends 的数据,这个词开始流行是在 2012 年,也是哈佛商业评论将“数据科学家”命名为 21 世纪最性感的 T2 工作的时候。一个产生数百万个数据点的现代公司必须有一个数据科学团队,并且普遍存在人才短缺的问题。HBR 的文章描述了 2012 年的挑战:
如果利用大数据取决于雇佣稀缺的数据科学家,那么经理们面临的挑战是学会如何识别人才,将人才吸引到企业,并使其富有成效。这些任务都不像其他既定的组织角色那样简单。首先,没有提供数据科学学位的大学项目。对于该角色在组织中的位置、数据科学家如何增加最大价值以及如何衡量他们的绩效,也没有达成共识。
很明显,情况发生了很大变化:六年后,现在有 160 多所大学授予“数据科学”学位。但是许多挑战和机遇依然存在。数据科学家仍然可以来自任何地方。成为一名数据科学家的过程是很容易实现的,很少有令人满意的/高薪的工作是这样的。除了付费学位,还有吴恩达的 Coursera 机器学习课程、edx.orgMITx、HarvardX、ColumbiaX 或 UCSanDiegoX 的课程、物理和基于网络的教科书、 Youtube 频道、个人博客、公司博客等等。
一系列教育选择的价格点和数据科学家背景的多样性导致了广泛的技能组合、兴趣和解决问题的风格。在一家公司内,这对于思想的多样性是一个巨大的积极因素,会带来非常积极的内部学习环境。这也会导致商业敏锐度/背景、兴趣和一般工作经验的巨大差异。有些杰出的数据科学家从未在 Outlook 中预定过会议室,从未将某人转移到密件抄送:或进行过绩效评估。Kaggle 有一位竞赛特级大师,他是十七岁 岁;说明了开源教育是如何精英化的,也说明了一个 17 岁的孩子在这种特定的人才评估中可能是最棒的。
卡格尔
Kaggle 是一个基于数据科学挑战的网站,在这里不同天赋水平的用户可以聚集在一起,竞争建立精确的模型。一家对招募数据科学家感兴趣的公司发布了一个测试和训练数据集,解释了相关功能,并要求用户预测一个输出。一个竞争的例子: Airbnb “挑战你预测一个新用户将在哪个国家进行他或她的第一次预订”,通过发布关于用户、浏览器会话和国家数据的伪装数据。提交的格式是高度指定的,评估指标也是如此。个人提交预测,最准确的会登上公共排行榜的首位。排名靠前的提交经常被微小的数量分开。公司可以利用竞争领导者来发现和招募顶尖人才。
Kaggle 竞赛可以成为开发和展示建模技能的重要资源。Kaggle 的问题是 Kaggle 的吸引力:它给你所有你需要的数据,告诉你要预测什么。实际上,这是最难做到的部分。我采访的一位数据科学经理说:
真正起作用的是你如何收集数据,制定问题,并告诉模型它需要学习或预测什么。我见过一些数据科学类型的人在数据科学环境中效率很低。Kaggle 是狗屎,不是数据科学家做的,大多数系统不是这样。我们大部分时间都在问,需要解决的问题是什么,你是如何制定的?一旦你进入模型拟合阶段,实现是微不足道的,我发现旋钮调谐的回报相当低。
Kaggle 风格的竞赛(和大多数面试)也不评估时间和复杂性的权衡,因为它们本质上是根据单一标准评估的。行业数据科学解决方案必须权衡复杂性。众所周知,网飞举办了一场比赛来改进他们的推荐算法,他们也因没有实现获胜的算法而出名:“我们测量的额外准确性收益似乎并不证明将它们引入生产环境所需的工程努力是合理的。”Kaggle 没有强迫竞争对手开发一个框架,来评估通过另外一百行代码或在一个项目上再花两天时间来解锁 0.1%的收益是否有意义。
出色地将数据转化为对某一指标的预测是一项关键技能。然而,正如马克斯·伍尔夫写的:“建模只是一个非常复杂的系统的一部分(通常也是最简单的部分)”。如果你能做到这一点,并且只能做到这一点,你就是数据科学中相当于球门线往回跑的人,你忽略了剩下的 90%。不管来源如何,数据科学教育可以让 IC 在构建和调整复杂模型方面极具天赋,但对第一天的工作毫无准备。那么,如何发展、扩大和管理数据科学家团队呢?
成为一名数据科学经理并不容易,也没有多少人拥有领导数据科学团队的相关经验。如果你认为现代数据科学已经存在了不到十年,本质上,没有人有十年的管理经验。由于该行业刚刚起步,最佳实践很难获得。资源有限。很少有榜样可以教你如何领导,还有许多持续的挑战。
数据科学经理的任务是组建一个 IC 团队,了解他们的背景、动机、优势和劣势。当构建他们的团队和数据架构时,他们必须面对困难的决策。“所有权”的问题会不断出现。领导者必须帮助填补数据科学家的空白:你如何为你的员工提供成功所需的商业环境?你如何建立项目优先化、代码标准、时间和复杂性权衡的框架?你如何教导你的团队取得成功?管理人员必须调整组织、数据平台、项目工作流程和整体文化,以建立一个优秀的团队;尽管我们知道这个问题没有确定的答案:“理想的数据科学团队是什么样的?”
数据科学家的领导还必须指定业务利益相关者与数据科学部门互动的方式。当一个部门有一个请求时,这项工作是如何沟通、区分优先级、执行和报告的?最终产品是什么样的,谁对最终产品负责?虽然这应该是微不足道的,但通常很难就项目何时完成达成一致。业务方面的个人如何支持数据科学家,反之亦然,如何促进这些对话?
企业利益相关者和数据科学团队之间的关系因公司而异。“非技术”是一个谱,不同公司差异巨大。公司“数据文化”的力量和业务利益相关者的分析理解水平高度预示着数据科学团队的适应程度。如果你是一名数据科学经理,你如何确保你的团队的工作甚至可以被必要的利益相关者消费/实现?
商业利益相关者也面临着一场艰苦的战斗。数据科学家听起来总是像在说一种不同的语言。如果你第一次与数据科学团队互动,你会觉得他们是完全不同的物种。你如何弥合这一差距?你知道“数据科学”涉及使用数据来推动业务,但你如何了解这个团队能为你做什么,更不用说他们是否能真正执行该计划。你如何对你所要求的事情进行优先排序,结果你如何做出更好的决定?数据科学家如何帮助您取得成功,您如何帮助他们取得成功?
我希望这些最佳实践行动手册能有所帮助:
以多种语言启动 ParallelDots AI APIs
随着持续数十年的数字化浪潮,数字化形式的文本数据量呈指数级增长。理解和分析这些数据变成了一种练习,就像从消防水管里喝水一样。在 ParallelDots AI APIs,我们旨在让您的生活更简单,并帮助您提供工具,通过几个 API 调用或舒适的 excel 表格中的简短公式来有效地分析这些数据。我们的客户一直敦促我们将我们的服务扩展到多种语言——这正是我们所做的。我们现在为真正的全球客户群提供以下关键 API 语言选项(情感分析、情绪分析和关键字生成器):
如何使用我们的多语言 API?
请按照以下步骤使用 API:
- 在此注册一个免费账户。(如果尚未注册)
- 登录你的仪表板,在这里附上你的信用卡。这是一项高级服务,需要用户升级到标准层。
- 输入您的信用卡详细信息。标准层的计费与使用量相关联,除非您超出了免费使用限额,否则不会向您收取任何费用。
- 点击查看文档获取代码片段。只需复制代码片段,调整输入文本参数,添加 API 键,更改语言代码,就可以开始使用我们的 API 了。
有问题吗?—请随时联系我们 apis@paralleldots.com 公司
你也可以点击查看演示。
定价
多语言 API 面向利基市场,作为我们高级 API 的一部分提供。定价计划的详情如下:
- 需要信用卡
- 每月免费 100 次点击
- 每月 100 到 100 万次点击——每 1000 次点击收取 2 美元
结论
这一新举措使我们离成为全球客户群首选文本分析解决方案的使命更近了一步。这是对我们最近提高模型准确性的举措的补充,通过新的 API 添加了更多的分析选项,并添加了新的交付选项(通过 Excel 插件)。如果您是一家寻求解决特定文本分析用例的企业,我们将很乐意通过提供定制的解决方案来帮助您。
最后,如果您有任何问题,或者希望我们专门为您选择的任何特定语言提供 API,请联系我们 apis@paralleldots.com。
法律与词序:法律技术中的自然语言处理
法律的核心是语言,所以长期以来,基于自然语言运行的软件在法律职业的某些领域发挥作用也就不足为奇了。但是在过去的几年里,人们对将现代技术应用于更广泛的问题越来越感兴趣,所以这篇文章着眼于自然语言处理在当今法律领域的应用。
法律 NLP 前景
自然语言处理的应用,以及更普遍的人工智能,在法律行业中并不是一件新鲜事。搜索在线法律内容的最早系统出现在 20 世纪 60 年代和 70 年代,法律专家系统是 20 世纪 70 年代和 80 年代讨论的一个热门话题(例如,参见 Richard Susskind 的《法律中的专家系统,牛津大学出版社,1987 年)。但在过去几年中,人们对该领域的兴趣大幅上升,正如你可能预料的那样,包括越来越多的初创公司声称在特定的法律应用背景下应用深度学习技术。
在最近的一个项目中,我不得不回顾 NLP 是如何被应用在法律技术中的。这是一个人口密集的空间:斯坦福大学的一个网站列出了 1084 家“改变法律运作方式”的公司。在回顾这样的风景时,有一张地图会有所帮助。方便的是,法律实践是一种结构良好的活动,对于典型的律师事务所面临的许多特定任务,可以提供点解决方案。我认为 NLP 在五个法律活动领域发挥着越来越大的作用:
- 法律研究:寻找与法律决定相关的信息
- 电子发现:确定文档与信息请求的相关性
- 合同审查:检查合同是否完整并避免风险
- 文档自动化:生成日常法律文档
- 法律建议:利用问答对话提供量身定制的建议
这些简短的定义隐藏了一些复杂性,我将在下面依次考虑每个领域时解开这些复杂性。
法律研究
法律研究是寻找支持法律决策所需信息的过程。在实践中,这通常意味着搜索成文法(由立法机关制定)和判例法(由法院制定),以找到与手头某一具体事项相关的内容。
这是你在法庭剧和访谈节目中看到的律师办公室墙壁上整齐排列的厚厚装订书籍的主要目的。然而,这些书经常被称为“布满灰尘的大部头书”是有原因的:在法律图书馆的桌子上仔细阅读书页早已被电子搜索和检索机制所取代。
LexisNexis (当时简称 LEXIS)最早出现在 20 世纪 70 年代初,最初提供俄亥俄州和纽约州判例法的全文搜索;它就从那里开始生长。到 20 世纪 70 年代末,律师们能够通过 1200 波特的调制解调器从专用终端使用拨号服务访问数据库。到了 20 世纪 90 年代末,这些数据都出现在了网上。今天,Lexis Nexis 声称拥有超过 30TB 的内容。 Westlaw ,法律数据库领域的另一个巨头,也成立于 20 世纪 70 年代中期,并于 1996 年被汤姆森公司(现为汤姆森路透)收购。再加上沃尔特斯·克鲁瓦和彭博法律,你就有了这个领域的四大老牌供应商。大多数律师事务所都会订阅部分或全部这些服务。
尽管事实上主要的参与者已经非常成熟,但是,一些新的参与者已经通过提供旨在提高搜索精度和召回率的更智能的技术占领了一些市场份额,超过了使用“传统技术”所能达到的效果,在这里“传统技术”相当于良好的老式布尔搜索和手工构建的索引。显然,搜索结果的质量很大程度上取决于提出正确的查询。两个案例正文(成立于 2013 年,出资 2080 万美元;此处提供的所有资金数据均来源于 2018 年 11 月底左右的 Crunchbase)和 CaseMine (成立于 2013 年,资金情况不明)提供的界面可以让你通过上传一段话甚至整个简介来找到相关材料,为搜索提供上下文,从而支持“按文档查询”。在每种情况下,这种功能都通过一系列简洁的 UI 特性得到了增强,从而方便了搜索任务。这不仅避免了在适当详细的搜索查询上花费精力的需要,还增加了通过典型查询没有找到的附加相关材料将被定位的可能性。
采用稍微不同的方法,使用 IBM Watson 的 Ross Intelligence (成立于 2014 年,融资 1310 万美元)和使用 Vincent 产品的 vLex (成立于 1998 年,融资 400 万欧元)提供自然语言查询界面,因此“你可以像与另一位律师交谈一样提出你的研究问题”。
当然,四大已经迅速建立了自己的“人工智能”解决方案。2018 年 7 月,LexisNexis 推出了 Lexis Analytics ,这是一款法律研究工具,其中包括机器学习和 NLP 初创公司 Ravel Law 的收购。几乎与此同时,汤森路透推出了 WestSearch Plus ,这是一个新的搜索引擎,声称使用了最先进的人工智能。
电子发现
电子发现,或称 e-discovery,是为响应法律诉讼或调查中的出示请求而识别和收集以电子方式存储的信息的过程。面对可能驻留在典型硬盘上的成千上万的文件,这里的一个关键问题是将这些内容分成相关的(或“响应性的”,在该领域的术语中)和不相关的。在最近与苹果公司的专利纠纷中,三星收集并处理了大约 3.6TB,即 11,108,653 份文件;在 20 个月的时间里处理这些证据的费用据说超过 1300 万美元。
如今,市场份额之争围绕着优化技术展开,这些技术用于尽可能快速高效地对文档是否相关进行分类。这一过程被称为“技术辅助审查”(TAR),多年来一直是 TREC 法律轨道的活动焦点。与法律研究一样,传统方法包括关键字或布尔搜索,然后是人工审查。更现代的方法使用机器学习进行文档分类,在法律专业中称为“预测编码”。您希望最大限度地提高精确度和召回率,同时将所涉及的工作量(就一个人必须注释或审阅的文档数量而言)保持在一个合理的水平。法律界对各种技术的利弊存在一些争论,特别是围绕什么算作合理的种子集,以及被动学习还是主动学习更好,其中前者涉及随机选择文档进行人工标记,而后者涉及对不确定或假设相关的示例进行有意的机器选择。(此处见,此处见。)
这个领域最大的玩家可能是extero(成立于 2004 年,融资 1 亿美元;Exterro 的博客是电子发现的有用信息源。他们的最新技术称为智能标签,避免了用户提供人类标记文档的初始种子集的需要,从审查过程的一开始就选择最相关的文档进行审查。 DISCO (成立于 2012 年,融资 5060 万美元)在其“优先审查”流程中也有类似的基于深度学习的解决方案。
Everlaw (成立于 2010 年;另一方面,资助 3460 万美元)似乎仍在使用一种方法,即必须首先标记初始种子集(他们建议 200 个文档)。UI 功能可能是重要的差异化因素: Relativity (成立于 2001 年,融资 1.25 亿美元),之前被称为 kCura,也提供了一个手机应用程序,这样你就可以“在通勤途中或沙发上编写文档”。律师也是全天候的。
有趣的是,通用的 NLP 提供商也正在进入这个领域。OpenText 推出了一个名为 Axcelerate 的电子发现平台;以翻译产品和服务闻名的 SDL 提供了一个[多语言电子发现解决方案](https://www.sdl.com/software-and-services/integrations/solutions-forediscovery. html),通过翻译可以访问外语案例相关内容。
合同审查
律师的一个常见活动是审查合同,提出意见和修改,并建议他们的客户是否签署或谈判更好的条款。这些合同可能相对简单,如保密协议,也可能非常复杂,长达数百页。
自动合同审查系统可用于审查就其包含的内容种类而言相对标准化和可预测的文件。这个过程包括将合同分解成单个的条款,然后对每个条款进行评估,要么提取关键信息,要么与某个标准进行比较(该标准可能只是公司持有的此类合同的其他实例的集合)。因此,举例来说,一个合同审查系统可能会指出没有涵盖贿赂的条款,或者指出涵盖价格上涨的条款没有规定百分比限制。
合同审查可能是在单个合同的层面上,或者说,在对公司收购进行尽职调查的情况下,它可能涉及审查数千份存档的合同。在后一种情况下,该技术还开始纳入被称为法律分析的方面,聚合整个数据集的信息以检测异常和异常值,并生成图表或表格,以便于跨文档进行比较。
在过去的几年里,合同审查引起了人们极大的兴趣。早期的方法再次使用关键术语和标题的存在来指导信息提取,很可能许多产品仍然使用一些基于规则的技术;然而,毫不奇怪,几乎所有最近进入该领域的人都在使用更复杂的机器学习技术。
这里最大的三家 140 强企业是 Kira Systems (成立于 2015 年,融资约 6500 万美元) Seal Software (成立于 2010 年,融资 4300 万美元)和 LawGeex (成立于 2014 年,融资 2150 万美元)。Kira 为涵盖一系列合同类型的约 500 种常见条款提供了预建模型;您可以指出哪些与正在审查的合同相关,还可以为尚未考虑的条款构建定制模型。Seal 提供了类似的功能,但增加了一个逻辑引擎,允许您将业务逻辑应用于从已审核的合同中提取的数据;LawGeex 强调将合同与预先定义的公司政策进行比较的能力。
新进入者和小进入者的一个典型策略似乎是从关注非常具体的文档类型开始,如 NDA、房地产租赁和隐私政策,然后随着公司赢得客户和吸引力而增加处理的文档的范围。勒弗顿(2012 年资助;融资 1500 万欧元,19 从 DFKI 剥离出来,主要专注于房地产文件。它以拥有大量房地产投资组合的公司为目标,用 20 种语言处理合同。其他值得一看的较小公司有 eBrevia (成立于 2012 年,融资 430 万美元) Eigen Technologies (成立于 2014 年,融资 1300 万美元) LegalSifter (成立于 2013 年,融资 620 万美元) Luminance (成立于 2003 年,融资 1300 万美元),但还有许多其他公司。
毫不奇怪,通用文本分析公司也被这个用例所吸引:参见 ABBYY 合同文本分析、 Ayfie 合同分析和 OpenText Perceptiv 。
ContractProbe 和 T2 privacy policy check 都有在线演示,可以让你上传文件进行审核。这些产品比上面讨论的产品要简单得多,但是它们让我们了解了合同评审应用程序的功能。
文件自动化和法律咨询
文档自动化系统和法律咨询应用程序之间有一个模糊的界限,所以我将把这两个类别放在一起考虑。
法律顾问是交互式系统,它根据系统提出的一系列问题,根据用户的情况和要求提出建议。在许多情况下,输出是某种法律文档,因此法律建议通常相当于文档自动化。
另一方面,文档自动化系统通常使用某种填空模板机制来创建符合特定标准的法律文档。在某些情况下,生成文档所需的数据是通过反复的问答对话框获得的:如果您愿意,可以称之为聊天机器人。在这种情况下,文档自动化系统具有与法律咨询系统提供的界面相同的界面。
最受公众关注的法律顾问是 DoNotPay,这是一个互动工具,其最初的重点是[帮助普通公众对停车罚单提出上诉](https://www.theguardian.com/technology/2016/jun/28/chatbot-ai-lawyerdonotpay- parking-tickets-london-new-york)。从那时起,应用程序的范围已经大大扩展了;在撰写本文时,DoNotPay 应用程序支持 [14 种不同的用例](https://www.artificiallawyer.com/2018/10/12/the-genius-of-donotpay-givingyou- what-is-already-yours/),包括对抗不公平的银行、信用卡和透支费用,当司机走错路时从优步和 Lyft 获得退款,以及为延迟的包裹交付申请退款。
斯坦福大学的学生约书亚·白劳德为了回应自己的停车罚单经历,创造了 DoNotPay 但是律师事务所也对提供法律咨询系统感兴趣。自动化在这方面有明显的优势,使那些可能负担不起或不愿意支付法律服务费用的人能够获得法律服务。
因此,例如,澳大利亚律师事务所 Norton Rose Fulbright 在 2017 年底发布了一款针对隐私法问题的聊天机器人。该工具使用 IBM Watson 构建,回答了关于数据泄露的标准问题。该公司后来扩展了应用程序,以处理 GDPR 查询。
Neota Logic ,从 2010 年开始,提供了一个创造专家顾问的平台;事实上,这项技术的应用范围比这要广得多,因为它还可以用于工作流自动化和相关任务,包括文档自动化,这是我接下来要谈到的。
法律文档自动化应用已经存在很长时间了,可以说是最早的商业自然语言生成系统之一。一些研究人员不愿意将这些基于模板的系统称为 NLG,但事实是,所使用的技术与当今领先的商业 NLG 供应商提供的技术相似。
如上所述,这些系统通常通过填写表格或通过问答会话从用户处收集相关数据来工作。然后,通过条件文档组装和模板槽填充的组合,以基于规则的方式使用累积的数据来制作定制的文档。
这一类别中最著名的是汤森路透的合同快递,其目标市场是希望提高效率的律师事务所。还有其他一些著名的参与者,包括 Rocket Lawyer (成立于 2008 年,融资 4620 万美元),它更关注消费者,以及 Neota Logic(如上所述),它们既提供通用的智能文档自动化工具,也提供更加面向最终用户的特定应用程序调用 PerfectNDA 。
更一般地说,许多组织将其文档自动化产品定位于诉诸司法领域,使定制的法律文档易于为公众所用。两个这样的例子是 A2J 作者和helpesellegal。
最后判决
如同在许多其他领域一样,法律专业的工作性质更普遍地受到 NLP 和 AI 的威胁。2016 年初,德勤发现[法律部门 39%的工作将在未来十年实现自动化](https://www.legaltechnology.com/latest-news/deloitte-insight-100000-legalroles- to-be-automated)。最近,麦肯锡[估计 22%的律师工作和 35%的法律助理工作可以自动化](https://www.linkedin.com/pulse/how-much-what-lawyers-do-can-automatedlook- new-research-peter-nussey/)。正如在其他领域常见的那样,你经常会看到积极的一面,通常的说法是“技术解放了工人,让他们做更有趣的事情”。但是技术吸收的利与弊是该行业偶尔激烈辩论的焦点,理查德·特罗曼斯将其描述为由想要保持现状的保守派和想要改变的进步派组成。当然,变革的一个主要障碍是法律职业传统上是以计费时间为基础的。在这种情况下,如果一项技术提高了效率,它也会减少你可以在时钟上投入的时间。另一方面,面对世界各地诉诸司法运动日益增长的需求,传统方法的中断是不可避免的。
我得说陪审团已经不在这个案子上了。
如果你想收到关于商业 NLP 世界正在发生的事情的简短每周简讯, 在 NLP 中注册本周。
延迟加载 R 中的数据
最近,我发现自己需要加载和处理大型数据文件以显示在闪亮的仪表板上,但是一次性加载和处理整个文件需要很长时间。这将迫使用户在显示结果之前盯着空白屏幕看一段时间。我想出了一个粗略的解决方案来“延迟加载”数据,并根据需要处理它们。当我说延迟加载时,我的意思是只加载/处理用户当前需要的部分并缓存它们。想象一下 YouTube,一边看一边加载部分视频。
我觉得有两个关键的 R 概念值得解释,因为它们真正塑造了延迟加载技术:环境和方法调度。
环境和方法分派
在高层次上,我创建了一个定制的环境对象,并在需要时基于索引重写了[
方法调度进程。
环境
r 不支持引用调用。在像C++
这样的语言中,引用(指针)可以作为参数传递给函数。不过有一个解决方法,使用环境。环境是 R 的秘密“引用调用”。在这里,我使用它们来缓存我的使用环境的结果。当一个环境被传递给一个函数时,它被自动地通过引用传递,因为环境是而不是复制到 R 中的(更多在这里)。让我们看一个例子
A human
can have only one age. And celebrating birthdays globally increments age by one, no matter where you are.
数组和方法分派
下一块是法派,具体是[
上的法派。这非常类似于 Java 中的运算符重载。
A demonstration of method dispatch
第 11 行的输出并不是我们所期望的数组类对象的输出。定义一个[
方法调度是将对象伪装成数组的简单方法。另请注意第 32 行,其中方法分派是用函数中的一些操作定义的,以支持返回结果之前的处理。
为什么要关心定义[
方法调度呢?老实说,没关系。有了这种语法糖,代码读起来就简单多了。我喜欢让我的代码尽可能的干净和简单。
惰性装载
正如我之前提到的,我将延迟加载称为一种仅在需要时加载或处理数据的技术。想象一下 YouTube 或网飞,视频分部分加载,而且只加载用户想看的部分。如果任何一方要求用户等待完整视频下载后再播放,那将是一场灾难。从磁盘加载和处理大文件也是类似的概念。
Very generic lazy loader
这里我创建了一个接受inputs
和FUN
的构造函数。inputs
可能是一个数组,一个列表,或者另一个对象,基于你的用例。这里我做了一个数组。而FUN
是一个函数,你可以用它来处理inputs
中的每个元素。为了启用缓存,我还定义了一个returns
数组。同样,这可以是任何东西,而不仅仅是一个数组。在第 8 行定义自定义类对于以后创建方法分派很重要。例如,如果我想延迟处理(平方一个数)一个数的数组,这将是理想的。
inputs <- 1:10
FUN <- function(x) x * x
我们期望的returns
是
returns <- c(1, 4, 9, 16, 25, 36, 49, 64, 81, 100)
对于 lazy process,当我从新对象lazy.object[idx]
请求任何项目时,我希望它会返回该索引的结果。为了帮助索引,我定义了[
方法分派。
你会注意到我所做的就是调用FUN
并传递我想要处理的项目。如果您正在处理数组,那么您可以跳过 sapply,但是对于其他类型,这是合适的。对于列表,我会使用lapply
。
现在,为了缓存结果以备将来使用,我们对方法 dispatch 做了一点小小的修改。
Notice no processing message for code in line 25
第 3–7 行检查returns[i]
是否为 NA,只有当它为 NA 时才进行计算。为了演示,我修改了函数,以便在调用它时打印消息。
为了更清楚地了解情况,我还为对象定义了一个print
方法分派。
Notice line 24, with populated values in positions 3:8
如您所见,当创建对象时,ll
有一个空的returns
数组。当ll[3:8]
被计算时,结果被缓存。同样,虽然我使用了数组和一个简单的函数,但是可以很容易地修改它来支持复杂的对象和函数。
趣味中的多重争论
有时你需要做的不仅仅是计算平方,也许是两个数的和。因此,您的函数需要两个(或者可能更多)输入。有两种方法可以实现这一点:
- 为环境中的第二个输入定义一个新的
inputs
,并将两个值传递给该函数 - 使用带有多个参数的 R 的
[
我将在下面介绍这两种方法,并说明我认为每种方法的最佳用途。
定义另一个input
我发现这种方法在两个输入相差很大或者依赖于索引时最有用。您将定义输入并更新方法分派。
对于更多的输入,这变得有些费力,但仍然比让用户等待要高一步。
传递带切片索引的参数
方法分派就像 r 中的任何其他函数一样,因此,像任何其他函数一样,可以向它传递多个参数。这个方法实际上要求你把...
放在两个地方,这样你就完成了!当我对一些指数有相同的输入集时,我会使用这种方法。比如每个数字加 5。
Notice line 26
两种方法都很棒,但我个人更喜欢第二种。只是工作量更少:P
缓存失效
我想说这是一个高级主题,大多数普通读者可以跳过这一部分。如果输入有可能在运行时改变,那么我们需要一种方式通知加载器缓存的结果不再有效,需要重新计算。您可以创建一个新的对象,并重新计算或复制有效的结果,但有一个更简单的方法。为每个索引使用一个标志。
Cache invalidation
通过向每个索引添加一个有效的标志,加载程序只需检查是否设置了标志,并在需要时重新计算。我将[<-
方法分派定义为语法糖。但要点是通过将有效标志设置为内部的FALSE
来使索引无效。之后每个命令的输出有助于更好地理解该过程。
最后的话
当输入很大并且需要某种耗时的预处理时,这种技术非常有用。可以把这想象成一种有助于简化某些流程的设计模式。如有任何问题,请随时与我联系!
附:这是我的第一篇博客。请务必分享和评论!😄
惰性神经网络
对于困难的问题,神经网络有时可能缺乏鲁棒性,因此它们可能无法对分类不足的例子和边缘情况进行准确的预测。即使选择了合适的架构,这种情况仍然存在。我讨论了如何将注意力从模型架构转移到智能数据选择策略和成本函数设计上,这通常是一个更有用的策略。
在我进入解决方案之前,我认为讨论深度学习的一些首要主题是重要的。
培训目标
请记住,当我们创建一个神经网络时,我们实际上是在设计一个实验。我们有数据、模型架构和培训目标。你提供的数据是模型的范围,损失函数基本上是神经网络如何根据这个目标来评估自己。最后一点至关重要。损失函数基本上在训练期间向架构提供反馈,有效地陈述-是架构内参数的当前状态,做出准确反映我们的训练目标的预测,数字越低越好。
数据分类是使用深度学习解决的常见问题。无论你试图对猫和狗、路上的汽车还是购买行为进行分类。这种问题的训练目标是简单地最小化错误分类的例子的数量。当前的范例是使用称为交叉熵的损失函数,其训练目标是最小化总输出。在数学上,这表示为:
或者在第一种情况下,可以直观地表示为:
Cross-Entropy Loss (CE)
虽然你们中大多数熟悉深度学习的人可能厌倦了人们解释交叉熵,但我想强调几件事。看上面曲线的形状,试着想象训练时发生了什么。参数被随机初始化,然后随着数据的传递而更新。由于损耗越低越好,如果这些随机初始化的权重导致预测概率 p 接近于零,那么损耗输出将会非常高(曲线趋于无穷大)。如果参数是完美的,使得它以 100%的准确度预测训练集中的一切,那么输出是零,不能再低了。如果它在任何中间位置,它将总是试图瞄准这个零值。这是因为我们的训练目标是最小化总损失,并且许多小值的总和优于许多大值的总和。
上面的方法似乎不需要修改。我们有一个连续的函数,告诉神经网络不断尝试改进,直到它完美为止。一会儿我将回到为什么这种方法会有问题。
神经网络变懒
数据对于深度学习模型至关重要。但是得出数据越多越好的结论未免过于简单化了。少量高质量的例子对于一个有效的模型来说是绰绰有余的。然而,理解整个训练过程对于拥有一个健壮的模型是很重要的。
神经网络不是用常识初始化的。他们从不知道正在学习什么开始,通过查看数据来逐渐更新参数,然后基于给出最佳总体性能的内容进行评估,标准是我们为其定义的总损失。类别不平衡可能导致网络在不确定的情况下简单地预测主导类别。不确定性本身可能来自于数据的微小变化。
如果您将数据视为模型的世界,大量简单、分类良好的示例可以增强模型的信念,即根本不存在这种类型的变体。例如,一个被训练来识别人的物体检测器可能很难定位一个远处的人,如果它被训练的只是护照照片的话。
即使你的数据集中有一些可变性,大量简单的例子也能强化一个网络对其宇宙的信念。再次考虑交叉熵损失曲线。神经网络可能不会尝试从困难的例子中学习,因为其总损失的风险太高。这样做的不幸后果可能是一个网络说“什么也不做”、“站着不动”或“不知道”。在另一种情况下,想象你正试图训练一个网络玩石头、剪子、布。它可能会知道大多数人总是玩摇滚,然后不断地输出纸张,而实际上你想让它学习更复杂的关系。这就是为什么简单地添加更多的数据并不总是理想的,因为这个概念可能会进一步加强。
一个更有用的方法是问这个问题我的神经网络哪里不好,并使这些情况在你的数据集中得到更多的体现。这种想法被称为自举或硬负挖掘。历史上,计算机视觉使用这种方法处理懒惰模型的问题。在对象检测问题中,背景和前景类可能在 1000:1 的比例上占主导地位,并且从未学会将学习集中在对象本身上。关键思想是通过选择检测器触发错误警报的那些例子来逐渐增加或引导背景例子集。这种策略导致迭代训练算法,该算法在给定当前样本集的情况下更新检测模型,然后使用更新的模型来寻找新的误报以添加到受限制的训练集中之间交替。该过程通常从一个训练集开始,该训练集包括所有对象示例和一个小的随机背景示例集[1]。
这里的要点是,更多的数据可能是有用的,但不要简单地将其扔在你的网络上,并期待更好的结果。
数学直觉
我不认为要成为一名优秀的机器学习实践者,你需要广泛的数学技能,当然不是与编程或一般问题解决技能相比。我甚至不认为你不能阅读论文,除非你理解了正在被证明的东西背后的神秘的数学解释。然而,我想说的是,能够在深度学习中可视化重复出现的数学概念确实为你提供了另一种工具,用于理解为什么神经网络最终可能不健壮,以及是否有改进的空间。
当你阅读报纸时,很难直观地理解正在发生的事情。了解一些数学函数可视化的基本技巧可以让它变得更简单。
让我们暂时忘记深度学习功能,只想象一个简单的正弦曲线。最简单的修改是将它乘以一个常数,在这种情况下,这个常数小于 1。效果是相同的形状,但值被缩放。
Effect of scaling by a constant
接下来想象我们的正弦曲线乘以一个变化的函数,在这种情况下是一条简单的线( y = x )。正弦波通常在–1 和 1 之间振荡。通过将其乘以另一个函数,它现在被迫在该函数的正值和负值之间振荡,在这种情况下为 -x 和 x 。
Effect of scaling by another function
焦损
鉴于这种认识,让我们回到交叉熵损失曲线:
Cross-Entropy Loss (CE)
如果我们记得我们正在做一个由数据、架构和损失函数组成的三个组件的实验;除了另外两个为什么不改变损失函数?如果我们不想让自己的神经网络变懒,如何改变这个功能?更具体地说,我们如何减少大量简单例子的贡献,这样参数就不会在这些例子中被细化?我们怎样才能迫使它发现更复杂的关系,这些关系只存在于更难描述的例子中?通过将两个函数相乘(如正弦函数所示),应该可以按照我们想要的方式正确地计算示例的成本,从而对交叉熵损失进行整形。
这就是焦点损失函数所实现的。在论文中首次介绍了密集物体的焦点损失 检测 (2017),以解决计算机视觉中的类别不平衡问题,作为硬负挖掘和多阶段模型的更简单替代方案。基本上,目标是识别图像中的对象,相对于人们试图预测的对象类别,背景和前景类别之间存在巨大的类别不平衡。基本上,很难让网络尝试对对象进行分类,因为神经网络认为丢失的风险太高。
焦点损失只是将交叉熵损失乘以一个比例因子,该比例因子随着正确类别的置信度增加而衰减到零[2]。
如果我们分别表示交叉熵损失和比例因子:
Cross-Entropy Loss and the scaling factor for case when gamma is 2
现在我们一起来比较一下未缩放的版本:
Comparison between Focal Loss and Cross-Entropy Loss
您可以直观地看到,无论概率是 0.7 还是 0.99,靠近曲线下端的分类良好的示例都将返回相似的值。换句话说,对于这个范围内的例子,它不会尝试改进它的参数,但当它不在这个范围内时,它会这样做。因此,它将迫使网络学习更复杂的关系,这些关系只出现在困难的例子中——使它不懒惰。
有趣的是,这个看似简单的变化直到 2017 年才引入深度学习社区。理论上,任何人都需要意识到这是如何缩放函数背后的一点数学直觉(如所展示的),以及意识到损失函数与数据和架构相比起着重要的作用。
总结
- 训练神经网络包括选择数据、合适的结构和损失函数。
- 神经网络会变得懒惰并强化它们的信念
- 不要盲目地添加更多的数据,而是使用谨慎的策略,如硬负挖掘。
- 当试图生成更鲁棒的网络时,不要忽略损失函数。
- 焦点丢失是一种让网络专注于更难的例子和学习更复杂的关系的策略。
参考文献
- [1]使用在线硬示例挖掘训练基于区域的对象检测器(Abhinav Shrivastava 等人)(2016 年)
- [2]密集物体探测的焦点损失(宗-林逸等人)(2017 年)