TowardsDataScience 博客中文翻译 2019(二十一)

原文:TowardsDataScience Blog

协议:CC BY-NC-SA 4.0

可视化文本数据集的设计者指南

原文:https://towardsdatascience.com/a-designers-guide-to-visualize-a-text-dataset-1d534756e914?source=collection_archive---------12-----------------------

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

The Office — Season 5, Episode 17 — Golden Ticket

数据可视化

用 Python 和 R 创建数据驱动的可视化

在本文中,我探索了一种使用 Python 和 R 代码可视化文本数据集的方法。作为一名用户体验和信息设计师,我想提高我的技术技能。我通过结合我的“兴趣”和挑选一个不寻常但有趣的数据集来实现这个目标。

经过一番寻找,我在布丁旁边的看到了这个精彩的互动 dataviz 项目 【办公室】五图对话。这个项目是一个很好的开始参考,它也给我指出了一个我可以想象的可怕的数据集。这个数据集本质上是《办公室》每一集所有台词的集合。

太好了!我找到了数据,现在我终于可以开始了!

第一步

首先,我决定根据我的技术能力和我希望学习的技能为这个项目设定一些目标和限制。

我需要知道我自己的项目的原因。

我当初为什么要启动这个项目?我希望学到什么?我想完成什么?

我这个项目的目标是:

  • 使可视化代码足够简单,并且能够创建有趣的模式。
  • 使用现有的 python 知识。
  • 学习 R studio 中的图形渲染。
  • 培养非数字数据的设计思维。
  • 全职工作的同时管理兼职项目。

第二步

接下来,为了指导我的设计,我开始思考这个可视化的目标。我的方法是开始问一些可以探究的问题。

我们的目标不是回答所有的问题,而是用它们来集思广益可视化的概念和想法。

例如,一些问题是

  • 每个角色的心路历程是怎样的?
  • 每个角色的屏幕时间是多少?
  • 所有的角色之间是如何互动的?
  • 每一集都有哪些主角?

第三步

基于现有的数据和我的目标,我想出了一些想法和可行的解决方案。我的想法围绕着表示从基于文本的数据集导出的数值。

在开始编码之前,我决定勾勒出我的最终设计。这被证明是一个有用的工件,用于计算数学和逻辑。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

在这里,我以非线性方式可视化了一个线性对话。

**一集中所说的每一段对话都被表示为一个线段。**为了传达对话的连续性,所有的线段都要相互连接。然而,它们以直角连接,即在一个线段的末端,下一个线段开始,但是具有 90°的枢轴。

如设计所示,我用以下方式编码数据-

  • 对话(说出的单词数)→线段的长度
  • 字符→颜色

非线性数据可视化的美妙之处在于,

真的真的真的真的(!)长文本可以包含在有限的空间内。

第四步

我需要将这个数据集转换成一个更加明确的结构,以便能够对它做一些有用的事情。现在,我的想法是使用 python 来清理数据,并使用 R 将其呈现为可视化形式。

python 程序的输出成为 R 程序的输入。

那么,我期望 python 程序的输出是什么呢?

一个 CSV 文件,可以导入到 R studio 中,它包含关于每个线段的坐标及其颜色的信息。

我从一个随机的插曲开始- 办公室奥林匹克
(也恰好是我的最爱之一!)

我开始从网站上复制对话框并粘贴到一个中。txt 文件。我想也可以编写 python 代码来从网站上收集必要的数据。数据清理包括删除不是对话框的文本。在这个网站上,一集的故事情节,即每个角色的行为都被放在方括号中,并从整体文本中删除。

下一个任务是,计算数学。正如设计建议的那样,我根据说对话的角色和它的长度,为每个线段计算颜色和坐标。

步骤五

执行完这段 python 代码后,我有了必要的输入。我使用 python 程序生成的 CSV 文件,通过 R studio 绘制了基于线的数据可视化。尽管它是一小段相对简单的代码,但编写它是对**ggplot2**库的一次有用的学习经历。

瞧啊。就是这么做的。

最后的结果

在 Illustrator 中做了一些修改后,下面是这个项目的一些输出。我为不同的图案修补了颜色。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

The Office — Season 2, Episode 3 — Office Olympics

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

The Office — Season 1

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

The Office — Some of my favorite cold opens

最终意见

我可以假设这可能不是你读过的最精彩或最复杂的东西。然而,我真的希望这是你今天遇到的最有趣的事情之一。

在这篇文章中,我想鼓励你,

  • 从小做起,然后迭代。你不必总是去追求一个“惊人”的想法。最好创建一些有多个微小失败循环的东西。
  • 思考盒子的外面和里面。
    你并不总是需要新的解决方案。通常,创新的解决方案是用新的方式做同样的事情。
  • 投身于你舒适区之外的项目。
    接受挑战,以适应不舒服。

最后,如果您正在寻找与数据可视化相关的灵感,这里有一些项目可以帮助您开始:

[## 少年派的艺术

探索隐藏在π中的艺术

www.visualcinnamon.com](https://www.visualcinnamon.com/portfolio/the-art-in-pi) [## 文学星座

文学星座是一系列海报,旨在类似星座地图,但不是基于…

www.c82.net](https://www.c82.net/blog/?id=73)

看看我的另一个项目,在那里我创建了手绘可视化来表示数据。

[## 数据在艺术里!

利用颜色、形状和涂鸦来理解软数据和小数据

towardsdatascience.com](/the-data-is-in-the-art-b97cf2ceda7c)

对贝叶斯规则的不同看法

原文:https://towardsdatascience.com/a-different-take-on-bayes-rule-e303c1d7d5f6?source=collection_archive---------23-----------------------

从机器学习和增量学习的角度,对术语“后验”、“先验”和“可能性”有更多的直觉。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Bayes Rule — θ refers to the model, D refers to a data point

本文的目标

大多数阅读本文的人都看过贝叶斯规则中每个概率分布的演示。大多数阅读这篇文章的人已经正式了解了术语“后验”、“先验”和“可能性”。如果没有,那更好!

我认为将贝叶斯规则视为增量学习规则对许多人来说是一个新的视角。此外,我相信这个观点会给更好的直觉,为什么我们使用术语“后”和“前”。最后,我认为这个观点有助于解释为什么我不认为贝叶斯统计比频率主义统计导致任何更多的归纳偏差。

注释

在深入研究贝叶斯规则本身之前,首先重要的是就符号达成一致。 θ 指的是我们的模型。一个模型可以通过一个类和一组参数来识别。例如,我们的模型类可以是高斯分布。这个模型的参数是均值和方差。

另一个示例模型类是具有一个隐藏层和 256 个节点的神经网络。该模型的参数是与网络的每个节点相关联的权重。

D 指一组数据点。在上面的例子中 D 是一组标量值。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Theta is the set of parameters mu and sigma-squared referring to the mean and variance respectively.

术语

老实说,我讨厌行话。我知道当双方共享一个共同的词汇时,它允许更快和更精确的交流,但我发现过度依赖行话会导致忘记信息密集术语的含义。也就是说,让我们进入一些行话!

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Posterior distribution

在后面的

给定数据的模型的概率。在贝叶斯世界中,我们不是在处理一个单一的实例化模型。我们处理模型上的概率分布。这个分布表示“根据我观察到的数据,我认为你的模型为 θ 的概率是 22%。”我们可以用许多不同的模型来查询这个分布,以询问每个模型给出观测数据的可能性有多大,或者我们可以询问这个分布最可能的模型是什么。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Prior distribution

在先的;在前的

一个模型的概率。贝叶斯概率最有争议的部分之一是包含先验分布。用机器学习的术语来说,你可以认为这是正则化的一种形式。先验允许你指定一个特定模型的概率,不管你观察的是什么数据。这让你可以说“我知道男性的平均身高不超过 8 英尺,给做出这种说法的模型分配零概率。”

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Likelihood

可能性

如果这些数据是使用我的模型生成的,那么观察到这些数据的概率有多大?这种可能性让我们可以问,如果世界按照我们的模型运行,会发生什么。我们会看到这些特殊的样本吗?

想象一下,我们使用一个模型,这个模型说一个随机的人有 99%的可能性非常富有。然后,我从世界各地随机抽取一组人作为样本,问“根据我的世界模型,我画出这组人的概率是多少?”因为大多数人并不非常富有,在集合中,远少于 99%的人会非常富有。这种模式的可能性相当低。

增量学习

将贝叶斯规则视为增量学习规则的第一步是识别后验和先验之间的关系。通过天真地分析单词——忽略等式本身——人们可能会猜测先有先验,后有后验。让我们在等式中加入时间指数来使这一点更加清楚。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

回忆条件概率的一个性质也很有用。当随机事件以非随机事件为条件时,随机事件的概率不变。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

如果 A 是随机事件而 B 不是,那么当以 B 为条件时 A 发生的概率不变。

利用这个特性,我们可以对贝叶斯规则方程进行最后的修改。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

The only thing that changed was the prior probability distribution.

我们的先验分布现在是以我们以前观察到的数据为条件的。这是对先验的合法更改,因为过去的数据不再是随机的。

为了理解为什么过去的数据不是随机的,想象你在时间步 t-1 上。你刚刚收到一个数据样本,你想知道你收到那个特定数据点的可能性有多大。这是因为你的数据是随机抽取的。你相应地改变你的模型,向前迈出一步。在时间步长 t 上,您在 t-1 上使用的样本会突然改变吗?没有。那个样本永远定格在历史里;它不再是一个随机变量。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Top — The posterior written as a function of the prior. Bottom — Stochastic Gradient Descent.

这样写贝叶斯规则,可以看出后验和先验的关系。在接收到一个数据点后,我们可以从模型的先前估计转向新的估计,即后验估计。我写的随机梯度下降更新规则是为了比较。在从之前的权重中减去一步后,我们计算出新的权重估计值 W

起点

贝叶斯统计的一个很有争议的点是先验分布的选择。当将贝叶斯规则视为增量学习规则时,我们可以很容易地看到,这并不是贝叶斯统计所独有的。任何增量学习规则必须选择一个起点,一组初始的权重或参数。贝叶斯法则也不例外。

我指出这一点只是因为在线学习社区似乎对贝叶斯统计有特殊的看法。有许多反对贝叶斯统计的论点(也有许多赞成!),但我认为归纳偏差论点并不是一个有效的例子。

结论

采用贝叶斯规则的增量学习观点可以理解与之相关的术语的选择。理解这个观点也打开了更深入理解贝叶斯推断和贝叶斯优化的大门。

在 Spark 上部署 Python 模型的不同方式

原文:https://towardsdatascience.com/a-different-way-to-deploy-a-python-model-over-spark-2da4d625f73e?source=collection_archive---------15-----------------------

将预测方法与 Python 类的其余部分分开,然后在 Scala 中实现

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Instead of using the whole thing, just take the pieces you need.

前阵子,我写了一篇关于如何在 Spark 上部署 Python 模型的帖子。方法大致如下:

  1. 根据全部数据的样本在 Python 中训练模型。
  2. 将测试数据收集到任意大小的组中——大约 500,000 条记录对我来说似乎很好。
  3. 广播训练好的模型,然后使用用户定义的函数对每组记录整体调用模型的predict方法,而不是对每条单独的记录(如果对未分组的数据帧调用 UDF,Spark 就会这样做)。

该方法利用了支持 scikit-learn 的支持 numpy 的优化,并减少了您必须经历序列化和反序列化模型对象的昂贵过程的次数。

我最近采用了一种不同的方式在 Spark 上部署 Python 模型,不需要对大量数据进行分组和分解。我仍然在 Python 中对全部数据的样本进行模型训练,但是我将调用 predict 方法所需的一切存储在一个 JSON 文件中,然后该文件可以被调用到一个可以实现 predict 方法的 Scala 函数中。

例如,以 sci kit-learnRandomForestRegressor为例。predict方法是一堆个体决策树的predict方法结果的平均值,但是方法本身的实现根本不使用树结构。它将所有内容编码成一系列列表。

以下代码创建了一个纯 Python 函数,该函数将精确再现经过训练的 RandomForestRegressor 的预测:

看一下tree_template字符串。我们从五个列表开始——每个列表都有树中的节点。features列表中的唯一值与模型训练所依据的特征一样多。我们从列表的第一个值开始—索引 0。如果索引 0 处的值是,比如说,3,那么我们取出模型被训练所基于的第三个特征的值。然后我们从thresholds列表中取出索引零值。如果所选特征的值小于或等于相应阈值的值,那么我们查看children_left列表的零索引值。否则,我们查看children_right列表的零索引值。不管怎样,这个值就是我们的新索引,然后我们重新开始这个过程。我们一直这样做,直到子列表中的值成为“您已经到达了树的末尾”的占位符。在 scikit-learn 中,这个占位符的默认值是-2。此时,无论您当前在哪个索引上,您都可以从values列表中查找该索引的值。那是你的预测。

所以,是的,这是一个很大的数据量——拥有几十个特征的决策树回归器通常有大约 100,000 个节点。但是导航树以获得预测的逻辑非常简单。因此,您所要做的就是创建一个包含每棵树的列表的函数,以及从一个索引跳到另一个索引的逻辑。然后取一组特征,从每棵树上得到预测值,并取平均值。那是你的随机森林。

很容易将所有这些信息转储到 JSON。下面的函数就是这样做的。它只需要一个经过训练的 RandomForestRegressor 对象、按照训练中使用的顺序排列的特性列表,以及一个将 JSON 文件转储到的文件路径。

单棵树的输出如下所示:

下一段代码来自我的同事 Sam Hendley,他已经忘记了比我所知道的更多的 Scala 知识。它从 JSON 文件中读入树信息,实现每棵树的预测逻辑,然后对整个森林进行平均。

在 Scala 中实现预测避免了对函数的 Python 表示进行序列化和反序列化的过程——一切都可以直接在 JVM 上完成。随机森林是这里最复杂的用例之一。在任何产生系数的模型中,将预测函数转换成 JSON 和 Scala 甚至更容易。

神圣的机会

原文:https://towardsdatascience.com/a-divine-chance-eb36d865027d?source=collection_archive---------48-----------------------

我在数据领域的第一份工作的期望与现实

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Photo taken on a recent hike to Mission Peak

自从我开始攻读商业分析硕士学位以来,我唯一的职业目标就是获得一份工作,在这份工作中,我可以应用我的技能,做出成绩,并拓宽我在数据科学方面的知识。5 月份从硕士项目毕业后,我很快参加了旧金山一个非常有名的数据科学训练营。毕业后的第二天就开始找工作了。

在我继续说下去之前,这篇文章不是关于我的求职,那将是一篇完全不同的文章,但这更多的是关于我在我的专业职位的前两个月观察到的。经过一场涉及无数编码挑战、数据集、无数自动拒绝邮件(有些甚至在夜里 2:00)等的严格求职,上帝保佑我在旧金山湾区一家知名公司的人工智能部门找到了一个数据工程师的职位。刚从一个硕士项目毕业时,我在人工智能团队中期待的是现成的数据集(csv ),它们大声疾呼“请在我身上应用一个模型,并获得最佳预测或分类分数!”。基本上是一场卡格尔比赛。事实绝对不是这样,事后看来,我离真相已经不远了。

人工智能团队是一个新团队,作为数据工程师的第一项任务是促进数据。通俗地说,“没有现成的数据,你的工作是收集所有可用的非结构化信息,给出结构并组织起来”。我花了相当长时间学习的有价值的机器学习 scikit-learn 模型突然退居二线。

如今,在一位杰出导师及其 rockstars 团队的帮助和指导下,我已经完成了两个月的工作,创建了自动组织和构建数据的脚本,促进了数据流和连续数据流入数据湖,还创建了几个有用的仪表板可视化工具来分析实时输入的原始数据。最初的几个月教会了我比硕士课程和训练营加起来还要多的东西。

我知道我在这里仅仅触及了表面,但我写这篇文章的原因是为了强调我们所有有志于成为数据专业人士的人都需要灵活地学习和做更多的事情。这正是这份工作教给我的东西,也绝对是我职业发展的绝佳机会。

一种狗检测器和品种分类器

原文:https://towardsdatascience.com/a-dog-detector-and-breed-classifier-4feb99e1f852?source=collection_archive---------6-----------------------

在像物理学这样的领域,事情变得越来越难,以至于除非用高度简化的术语,否则很难理解前沿发生了什么。然而,在计算机科学中,尤其是人工智能,世界各地的人们经过 70 多年慢慢积累起来的知识仍然是非常直观的。事实上,由于高级编程语言、框架和重视以易于访问的格式共享知识的社区,进入这个领域变得越来越容易了!

在这篇博文中,我们将做一些十年前不可能的事情,但像我这样的学生现在可以用几行 Python 代码完成;建立一个系统,可以识别照片中是人还是狗,并告诉我们它是什么品种(或者最像!).

你可以在我的 Github 找到代码。

探测人和狗

有几种方法可以解决图像分类问题。在这篇博文中,我们将使用卷积神经网络来确定狗的品种。在此之前,我们将使用 Viola-Jones haar 级联分类器方法来检测照片中是否包含人脸。

CNN 现在得到了最多的关注,但是你以前肯定见过 Viola-Jones 方法。每当你打开相机,它就会在人脸周围画出方框。诺丁汉大学的迈克·庞德做了一个很棒的视频讲解,可以在这里观看。简而言之,我们找出哪些过滤器最擅长区分人脸和非人脸。最佳滤波器应用于图像的每个区域。如果一个区域通过,它将在下一个过滤器上被测试。对大约 6000 个其他过滤器重复这一过程,如果一个区域通过了所有这些过滤器,我们就断定它包含一张脸。

报纸上还有很多其他的东西。例如,作者开发了一种简单而聪明的方法来有效地计算图像中某个区域的像素值。我们所需要做的就是从一个名为 OpenCV 的库中下载这些预先训练好的滤镜,并通过它们运行我们的照片。

import cv2def face_detector(img_path):
    img = cv2.imread(img_path)
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    faces = face_cascade.detectMultiScale(gray)
    return len(faces) > 0

就这样,它计算出图像中有多少张人脸!

不幸的是,OpenCV 的好人们没有为我们建立一些好的 haar 过滤器。相反,我们将使用 ImageNet,这是一个由 1400 万张图片组成的数据集,分为 2 万个类别。在过去十年中,它一直是领先的计算机视觉基准之一。我们将使用一个较小版本的 ImageNet,包含 1000 个类别,其中类别 151–268 是狗的品种。

我们可以使用一个名为 Resnet 的预训练 CNN,我们可以从 Keras 的网站上下载(稍后会有更多关于 Keras 的内容)。

from keras.applications.resnet50 import ResNet50ResNet50_model_ = ResNet50(weights='imagenet')

我们需要做一些预处理,以便模型可以对我们的图像做出预测:

from keras.preprocessing import image             
from tqdm import tqdmdef path_to_tensor(img_path):
    img = image.load_img(img_path, target_size=(224, 224))
    x = image.img_to_array(img)
    return np.expand_dims(x, axis=0)def paths_to_tensor(img_paths):
    list_of_tensors = [path_to_tensor(img_path) for img_path in tqdm(img_paths)]
    return np.vstack(list_of_tensors)

现在,我们可以看到模型做出的预测是否符合某个犬种类别:

from keras.applications.resnet50 import preprocess_input, decode_predictionsdef ResNet50_predict_labels(img_path):
    img = preprocess_input(path_to_tensor(img_path))
    return np.argmax(ResNet50_model_.predict(img))def dog_detector(img_path):
    prediction = ResNet50_predict_labels(img_path)
    return ((prediction <= 268) & (prediction >= 151))

最后,当我在 100 张样本图像上测试检测器时,人脸和狗的检测器没有任何假阴性。狗探测器也没有任何误报!

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Our human face detector results

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Our dog detector results

决定狗的品种

所以我们可以说在这幅画中有某种狗或人。但我本可以做到的。我能说出 117 个不同品种的区别吗?可能不能。让我们看看是否可以用机器学习来区分。

是时候破解 Keras 库了。像 Tensorflow、Pytorch、Theano 或 CNTK 这样的框架为我们执行机器学习操作。Keras 是一个建立在这些之上的库,所以我们可以用一种更简洁易读的方式编写代码。

以下是我们在 Keras 对 CNN 的定义:

model = Sequential()model.add(Conv2D(32, (3, 3), input_shape = (224, 224, 3), use_bias=False))
model.add(BatchNormalization())
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size = (2,2)))
model.add(Dropout(0.2))model.add(Conv2D(64, (2,2), use_bias=False))
model.add(BatchNormalization())
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size = (2,2)))
model.add(Dropout(0.2))model.add(Conv2D(128, (2,2), use_bias=False))
model.add(BatchNormalization())
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2,2)))
model.add(Dropout(0.2))model.add(Flatten())model.add(Dense(512, use_bias=False))
model.add(BatchNormalization())
model.add(Activation('relu'))
model.add(Dropout(0.2))model.add(Dense(256, use_bias=False))
model.add(BatchNormalization())
model.add(Activation('relu'))
model.add(Dropout(0.2))model.add(Dense(len(dog_names), activation='softmax'))model.summary()

这是怎么回事?我们有 3 个卷积层,后面是 3 个全连接层。这最后一层有一个 softmax 激活函数,这意味着我们的输出将是一个有 1000 个值的概率分布,我们使用的 ImageNet-1000 数据库中的每个可能结果都有一个值。

接下来我们将定义优化器和损失函数。这一行有许多术语,所以我将试着解释一下。

  • SGD 或随机梯度下降是最好的比喻,滚下一座山。如果你找到了下去的路,继续走。如果没有,请尝试不同的方向。请记住,在多维数学世界中,不仅仅只有 3 个维度可供选择。当你在某个方向达到局部最小值时,你就会知道,因为你所在的曲线的梯度会变小。这些都是在引擎盖下为我们处理的。
  • lr 是我们的学习率。给定一条新信息,我们应该在多大程度上改变模型?小比率意味着缓慢的训练,但大比率意味着我们可能会跳过最佳解决方案到山谷的另一边。最佳解决方案是使用…
  • 衰减意味着我们开始时学习率很高,当我们接近山/谷底部时,学习率随着每个时期而降低。
  • clipnorm 用于裁剪渐变,这样它们就不会变得过大或过浅,这会使渐变下降变得困难。 clipnorm 如果发生这种情况,剪辑值,但也缩放梯度,所以我们没有剪辑一些而不是其他的
  • 涅斯捷罗夫动量是我们向前看了一步后计算的梯度。这有助于我们更快地训练。
  • 分类 _ 交叉熵是损失函数。这意味着我们正在判断模型的性能,以及我们需要在多大程度上调整它,这取决于我们在检查结果后收到了多少新信息。如果我确定我见过一只金毛寻回犬,并且我是对的,那么就没有多少新的信息被创造出来。如果我不确定,那么已经创造了一些。如果我确定它不是金毛寻回犬,但它确实是,那么大量的信息就产生了。
  • 准确性是我们将监控的指标。它就像罐头上说的那样。它为多类分类问题计算所有预测的平均准确率。换句话说,有多少狗被正确分类。
sgd = SGD(lr=0.01, clipnorm=1, decay=1e-6, 
          momentum = 0.9, nesterov=True)model.compile(optimizer=sgd, loss='categorical_crossentropy',   
              metrics=['accuracy'])

然后我们就好训练了!

checkpointer = ModelCheckpoint(     
             filepath='saved_models/weights.best.from_scratch.hdf5', 
             verbose=1, save_best_only=True)model.fit(train_tensors, train_targets, 
          validation_data=(valid_tensors, valid_targets), epochs=5,   
          batch_size=20, callbacks=[checkpointer], verbose=1)

如果我们运行 6 个时期,会发生以下情况:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

The training and validation losses as our model trained

培训损失随着我们的培训而改善,但验证损失看起来将趋于平缓。这意味着如果我们长时间训练它,我们的模型将开始过度拟合。

在测试集上,该模型正确预测了它看到的 3.7%的狗的品种。这比随机猜测要好 4 倍,但仍有相当大的改进空间。

迁移学习

进入迁移学习。我们可以采取一个预训练的模型,就像我们对探测器所做的那样,并在它的末端添加我们自己的层来为我们做出预测。我们将使用的模型是 Resnet50,已经由微软的研究人员在更大的机器上进行了训练,时间超过了我所能获得的时间。

我们可以下载权重,将它们存储在本地,然后像这样解包特性:

bottleneck_features = np.load(
                           'bottleneck_features/DogResnet50Data.npz'
                           )
train_Resnet50 = bottleneck_features['train']
valid_Resnet50 = bottleneck_features['valid']
test_Resnet50 = bottleneck_features['test']

使用 Keras 很容易获得 Resnet50 并在它的末尾添加我们自己的层。同样,我们希望我们的输出是每个品种的概率分布

Resnet50_model = Sequential()
Resnet50_model.add(
        GlobalAveragePooling2D(input_shape=train_Resnet50.shape[1:])
        )
Resnet50_model.add(Dense(133, activation='softmax'))

之后就和以前一样了

Resnet50_model.compile(
                       loss='categorical_crossentropy', 
                       optimizer=sgd, 
                       metrics=['accuracy']
                      )checkpointer = ModelCheckpoint(
                 filepath='saved_models/weights.best.Resnet50.hdf5', 
                 verbose=1, 
                 save_best_only=True
                 )resnet50_hist = Resnet50_model.fit(
                    train_Resnet50, 
                    train_targets, 
                    validation_data=(valid_Resnet50, valid_targets),
                    epochs=20, 
                    batch_size=56, 
                    callbacks=[checkpointer],    
                    verbose=1
                    )

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

这种模式有多好?在测试集上,它正确预测了 84%的品种!这比我和我的疯狗家庭得到的要多得多。

尝试一下

将我们的人类和狗检测器与品种预测器结合起来,让我们在一些照片上尝试一下。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Correct! Not even the Barbour jacket confuses it

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Correct! Ironically, my it’s my dog who is overfitting in this photo (those ducks are plastic!)

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Wrong, this is actually a Border Collie.

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

But he does look like an Australian Shepherd

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Silky Terrier, who knew?

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

It’s got a bit confused by Pongo…

然而,如果我们仔细观察模型的预测,我们可以看到达尔马提是第二名,所以不算太坏。

bottleneck_feature = extract_Resnet50(path_to_tensor('images/pongo.png'))
predicted_vector = Resnet50_model.predict(bottleneck_feature)top_predictions = np.argpartition(predicted_vector.flatten(), -4)[-4:]
for i in top_predictions:
    print(dog_names[i])

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Well you can’t win them all!

潜在的改进

我们在这里可以做更多的事情。世界上最好的模型在有更多可能类别的 ImageNet 版本上获得了比我更好的测试精度。我们可以通过租用多个 GPU、获取更多带标签的图像等来获得一些改进,但这基本上归结为花钱,在概念上不是很有趣。

我们可以改进这个模型的一个方法是使用数据扩充。例如,通过翻转、移动、旋转、变暗、变亮、添加噪声和许多其他可能的操作,我们可以人为地增加模型可以暴露的图像的数量。我在这个项目中试验了数据扩充,结果令人失望。有可能通过一些参数调整和更长时间的训练,我会看到一些改善。

我们可以改变 CNN 本身。有可能更多的层,更多的特征,不同的损失函数,学习率和其他各种变化会使它表现得更好。深度学习的很大一部分是对模型进行修改,只有在它确实改善了事情的情况下才进行学习。如果我有更多的 GPU 时间,我可能会尝试使用网格搜索在一夜之间系统地实验不同的超参数。

结论

在本帖中,我们有:

  • 从 ImageNet 加载并预处理图像。
  • 加载了一些预训练的 haar 级联分类器,以便使用 Viola Jones 方法检测人脸。
  • 加载了一个预先训练好的 CNN 来探测狗。
  • 从头开始编写和训练了一个 CNN 来对狗的品种进行分类。这在测试集上成功了 3.7%,这听起来很低,但比机会好 4 倍。
  • 使用迁移学习从根本上改善了 CNN 的性能,使其在测试集上的准确率达到 84%。
  • 用我自己的几张照片测试了这个模型。
  • 讨论了未来改进模型的方法。

也许你在这篇文章中学到了一些东西。我从写作中学到了很多。如果你发现了一个错误,或者认为有些东西可以更好地措辞,让我知道,我会更新它!

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Happy Coding!

ML 和敏捷注定的联姻

原文:https://towardsdatascience.com/a-doomed-marriage-of-ml-and-agile-b91b95b37e35?source=collection_archive---------28-----------------------

如何不对 ML 项目应用敏捷

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Photo by photo-nic.co.uk nic on Unsplash

TLDR :在一个 ML 项目中过分使用敏捷和塞巴斯蒂安的话的三个错误。我认为在 ML 项目中什么是敏捷的,什么是不敏捷的。

免责声明 :这篇文章没有得到我工作的任何公司或我提到的任何工具或服务的支持或赞助。我交替使用人工智能、数据科学和 ML 这三个术语。

喜欢读什么? 跟我上 LinkedIn,或者*Twitter。还有,作为一名数据科学家,要不要学习商业思维和沟通技巧?查看我的《 用机器学习影响 》指南。*

一份供词

现在是 2016 年 11 月 3 日晚上 11 点 35 分。我坐在多伦多市中心海湾街的一间会议室里。我盯着街道那头空荡荡的办公室的地板。我房间的灯暗了下来。我的手机亮了。我收到了三份通知。

//10 小时后的执行演示。

//打电话给杰斯。在 12 小时内发送最终的婚礼后勤细节。

//去机场。18 小时后飞往香港参加我们的婚礼。

“Fck… Fck。Fck!”*

我敲了敲键盘;笔记本电脑已打开;弹出了一个号码。还是不行。我该如何解释预期转化率下降 35%的原因?

我拿起电话打给西蒙,他是我的同事,会在演示中支持我:“让我们计划一下损失控制。”

“喂,你在想我们的婚礼吗?”我可爱的妻子杰斯问道。

我突然回到现在。现在是 2019 年 11 月 5 日。我坦白。不,我不是在想我们的婚礼,而是结婚纪念日快乐!我永远不会忘记这个日子。

该死的,塞巴斯蒂安

我喜欢关于 ML 的成功故事。但是,让我们面对现实:大多数 ML 项目都失败了。很多项目失败是因为我们试图用 ML 解决错误的问题;有些失败是因为我们没有足够重视最后一英里问题工程和组织问题。有几个失败了,因为我们觉得数据科学很无聊并且不再关心。剩下的和我告白里的那个一样,都是因为项目管理不善而失败的。

如果我要从这次经历中吸取一个教训,那就是:不要过度敏捷。这一切都是从巴斯蒂安·特龙的一张图开始的。

这是我最喜欢的 ML 工作流程图,部分原因是 Sebastian 拥有最好的手写效果,是用电脑写字板写的(真的)。但是,这里有一个重要的细微差别。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Sebastian Thrun, Udacity — Introduction to Data Science, the Best Online Course!

我的无知,细微差别,以及发生了什么

首先,我必须承认我自己的无知。我是一个天真的敏捷方法论的拥护者,因为瀑布是如此的老派和无趣。像我一样,你们中的许多人可能听说过敏捷:迭代允许我们快速学习、测试和失败。(此外,我们通过节省撰写技术规范的论文来减少砍伐树木,这些技术规范没有人阅读,而且在早期项目中可能是错误的)。

细微差别。不应有箭头指向问题和评估(绿色和红色文本)阶段。敏捷的迭代原则不应该应用到我们定义核心问题和评估度量的阶段。

核心问题必须尽早清楚地阐明。然后,必须立即想出子问题(参见假设驱动的问题解决方法)。他们帮助 1)识别好的特性想法并推动探索性分析,2)计划时间表,以及 3)决定每个敏捷 Sprint 应该关注什么。必须根据核心问题仔细选择评估指标。我在我的指南中详细讨论了这个过程。

***那么,发生了什么?*未能认识到自己的无知和 ML 工作流程中的细微差别导致了 3 个致命错误。

错误#1: 我们中途更改了目标变量,因为对核心业务问题的定义有误。这导致了数据泄露破坏了我们的模型性能。我们不得不对大约 35%的代码库进行重新编码,并花费大约 2 周的时间重新尝试不同的数据转换和模型架构。那是一场噩梦。

错误#2: 我们优先考虑低影响特征,因为我们的子问题没有经过深思熟虑。嗯,其中一些功能是创新的,但回想起来并没有用。这浪费了宝贵的开发时间,而这在有时间限制的咨询环境中是极其重要的。

错误#3 : 我们改变了评估指标。我们必须重新设计我们的模型架构,并重新运行超参数搜索。这需要新的测试用例。我们不得不手动运行许多回归测试。

所有这些错误都反映在客户体验、团队士气和时间表上。最终,他们导致了我婚礼前的一个非常紧张的夜晚。

变得更聪明

好吧。说句公道话。我确实断章取义了塞巴斯蒂安的建议。他是曼梯·里最好的老师(对不起,吴恩达)。

Sebastian 的工作流程主要是为以实验为中心的 ML 项目而设计的(例如 BI 或洞察发现)。对于像我们这样的以工程为重点的 ML 项目(例如,全栈 ML 系统),工作流程应该基于软件工程和产品管理的最佳实践进行优化。

以下是我对什么是敏捷或者不是敏捷的看法。这对于有时间限制的咨询或内部原型项目尤为重要。没有十全十美的方法,所以不要走得太远,要聪明地运用。

敏捷能力:

  • 数据特征的发展
  • 模型架构的开发
  • 面向用户的用户界面的设计和开发(例如仪表板、网络用户界面等)。)
  • 设计开发 CICD 测试用例

不灵活:

  • 如果最终消费者是人,用户体验;如果最终消费者是系统,集成模式和协议
  • 核心、子问题和主要功能想法列表的定义
  • 目标变量的定义(不惜一切代价避免改变。但是如果业务需求发生变化,锁定 CICD 管道非常有助于捕捉数据或软件错误。)
  • 评估指标
  • 管道:数据到模型和 CICDDVC
  • 基础设施:集成模式、服务层、关键数据库和硬件平台

到目前为止效果还不错。一如既往地欢迎任何反馈。

根据对这篇文章的反应,我可能会跟进如何使用瀑布和敏捷来计划一个 ML 项目的工作计划图和需求示例。

请在 MediumLinkedInTwitter 上关注我。如果你喜欢这篇文章,请分享,这样其他人就可以加入对话。

正如你所看到的,能够清晰地表达核心问题并得出分析、特征想法和模型选择对项目的成功至关重要。我整合了我在 影响力与 ML 迷你课程中提供给学生和从业者的研讨会材料。希望你觉得有用。

喜欢你读的书吗?你可能也会喜欢我这些受欢迎的文章:

* [## 最有用的 ML 工具 2020

每个懒惰的全栈数据科学家都应该使用的 5 套工具

towardsdatascience.com](/the-most-useful-ml-tools-2020-e41b54061c58) [## 被遗忘的算法

用 Streamlit 探索蒙特卡罗模拟

towardsdatascience.com](/how-to-design-monte-carlo-simulation-138e9214910a) [## 越狱

我们应该如何设计推荐系统

towardsdatascience.com](/how-to-design-search-engines-24e9e2e7b7d0) [## 12 小时 ML 挑战

如何使用 Streamlit 和 DevOps 工具构建和部署 ML 应用程序

towardsdatascience.com](/build-full-stack-ml-12-hours-50c310fedd51) [## 数据科学很无聊

我如何应对部署机器学习的无聊日子

towardsdatascience.com](/data-science-is-boring-1d43473e353e) [## 抵御另一个人工智能冬天的最后一道防线

数字,五个战术解决方案,和一个快速调查

towardsdatascience.com](/the-last-defense-against-another-ai-winter-c589b48c561) [## 人工智能的最后一英里问题

许多数据科学家没有充分考虑的一件事是

towardsdatascience.com](/fixing-the-last-mile-problems-of-deploying-ai-systems-in-the-real-world-4f1aab0ea10) [## 我们创造了一个懒惰的人工智能

如何为现实世界设计和实现强化学习

towardsdatascience.com](/we-created-a-lazy-ai-5cea59a2a749)*

Google Coral 开发板上的一种 FaceNet 风格的面部识别方法

原文:https://towardsdatascience.com/a-facenet-style-approach-to-facial-recognition-dc0944efe8d1?source=collection_archive---------6-----------------------

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

介绍

在这篇博文中,我们介绍了面部识别的主题,并描述了我们对之前博文中介绍的问题的解决方法。

当决定实现面部识别时,首先想到的是 FaceNet。FaceNet 是一个人脸识别管道,它学习从人脸到多维空间中一个位置的映射,其中点之间的距离直接对应于人脸相似性的度量。

以下摘自 FaceNet 的论文给出了其主要概念的概述:

“[……]我们致力于从图像 x 到特征空间的嵌入 f(x),使得独立于成像条件,相同身份的所有人脸之间的平方距离很小,而来自不同身份的一对人脸图像之间的平方距离很大。

这允许一个身份的面孔生活在一个流形上,同时仍然加强了与其他身份的距离和区分度。”

FaceNet 的 TensorFlow 实现目前在 GitHub 上可用。

基于之前在 FaceNet 上的工作,我们的解决方案分为三个阶段:

1.预处理 —一种用于获取一组图像并将其全部转换为统一格式的方法——在我们的例子中,是一个仅包含人脸的正方形图像。当使用边缘 TPU 时,由于我们的计算资源有限,因此统一数据集有助于减少训练时的方差。
2。嵌入 —这是一个过程,是 FaceNet 工作方式的基础,它在多维空间中学习人脸的表示,其中距离对应于人脸相似性的度量。
3。分类 —使用嵌入过程给出的信息来分离不同人脸的最后一步。

我们还想实现的另一个功能是重量印记。权重印记是一种将训练过程分为两步的方法,第一步在大型数据集上训练整个模型,第二步仅在新数据上训练最后一层,同时利用前一步中获得的知识。重量印记允许在设备上进行学习,只需要很少的样本图像。它可以学习从未见过的人脸的内在属性,并将这些属性与它从已知数据集学习到的属性进行比较。

我们解决方案的架构

鉴于我们前面描述的三个阶段,我们为我们的具体实现构建了一个架构,并考虑了在 Edge TPU 上实现它的实用性。

该架构将使用以下方法:

1.使用对齐脚本进行预处理;
2。训练深度 Mobilenet 模型以识别人脸,然后在表示嵌入的层将其分割;
3。附加单层分类模型并使用权重印记来训练它。

对准

训练和推理过程的第一步都是对齐图像。这将总是发生在除了 Edge TPU 之外的机器上,因为 Edge TPU 环境不支持所需的库。我们目前正在运行来自 Facenet GitHub 库align_dataset_mtcnn.py 脚本。

通过执行脚本,我们可以指定面部缩略图的大小,并对齐它们。

这一步对于确保数据集中的一致性非常重要。如果没有这种一致性,模型将不得不学习对同一张脸的图像之间存在不必要差异的数据集进行分类。一个强大到足以做到这一点的模型对于第一次尝试在 TPU 边缘实现某些东西来说可能太复杂了。

在我们的例子中,为了处理图像,我们必须在服务器上运行脚本,因为本地机器需要大量的时间。
执行的命令是:

for N in {1..20}; do \
python3 src/align/align_dataset_mtcnn.py \
—image_size 182 \
—margin 44 \
—random_order \
—gpu_memory_fraction 0.05 \
& done

在一台 20 核服务器上,我们花了大约 30 分钟来对齐包含数十万张图像的 CASIA Webface 数据集。相比之下,我们预计在 MacBook Pro 上运行类似的脚本至少需要 2.5 小时。

把…嵌入

与对齐相反,嵌入和分类旨在在边缘 TPU 上运行。

嵌入模型是卷积层的串联,它寻找特征并将它们映射到多维空间。为了获得我们的嵌入层,我们从 MobileNet 模型的预训练版本开始——我将在下一篇文章中详细介绍——并重新训练它。值得注意的是,我们使用了整个模型,这意味着它既创建了嵌入,也对它们进行了分类。然而,该模型随后被分割,因此我们可以使用其输出(嵌入)作为单一层分类模型的输入。

为了进行训练,我们使用了mobilenet _ v1 _ L2 norm _ train . py脚本,该脚本将 TFRecord 格式的数据集和检查点作为输入,这些都是预训练模型提供的。

然后,我们必须保存模型的一个 GraphDef *并冻结图形。我们通过训练时创建的新检查点实现了这一点。重要的是,与我们之前描述的面网分类器相比,我们还去除了 L2 范数算子,因为它不受边缘 TPU 的支持。

为了冻结图表,我们使用了 Tensorflow 工具 freeze_graph ,这是一个简单的程序,只需要训练后的检查点。通过使用转换图工具,将冻结图作为输入,该模型去除了 L2 范数算子。

*更多关于 Tensorflow 中图形对象的信息可以在这里找到。

分类

对于分类,我们必须将模型分成两部分——嵌入提取器和分类层——然后将它们重新连接起来。

这种分离的原因是,如前所述,我们计划使用嵌入作为单层分类模型的输入。这一步确保了我们能够使用权重印记,这意味着该模型将能够在有限的数据集(大约 5 到 10 张图像)上训练(在 TPU 边缘),以识别一张从未见过的脸。

为了实现这一点,我们首先使用 tflite_convert 将整个冻结的图形转换为一个 TFLite 文件,它接受 GraphDef 文件并输出一个 tflite 文件。
由于 tflite_convert 不支持**,我们随后使用 toco 创建了基础图作为其自己的文件。tflite** 文件作为输入。

由此,我们有了与分类层完全分离的嵌入提取器。然后,我们使用 toco 创建头部图,然后使用 Edge TPU 编译器编译基础图。

最后一步是使用谷歌的 join_tflite_models 工具重新连接编译好的基础图和头部图。

摘要

我们从分析 FaceNet 论文开始,提出了面部识别系统的三步计划:预处理、嵌入和分类。

为了进行预处理,我们使用了服务器上的 FaceNet git 存储库中的一个脚本。然后,我们在我们选择的数据集上重新训练了一个预训练模型,并冻结了它的图形。最后,我们将模型分为一个基础(嵌入)和一个头(分类)以允许我们稍后进行权重印记。然后,我们应该有一个在我们选择的数据集上训练的工作编译模型。

MixMatch 的 fastai/Pytorch 实现

原文:https://towardsdatascience.com/a-fastai-pytorch-implementation-of-mixmatch-314bb30d0f99?source=collection_archive---------20-----------------------

在这篇文章中,我将讨论和实现“MixMatch:半监督学习的整体方法;由贝特洛,卡利尼,古德菲勒,奥立佛,帕伯诺和拉斐尔[1]。MixMatch 于 2019 年 5 月发布,是一种半监督学习算法,其性能明显优于以前的方法。这篇博客来自加州州立大学东湾分校 Ehsan Kamalinejad 博士的机器学习研究小组的讨论。

MixMatch 的改进有多大?当在具有 250 个标记图像的 CIFAR10 上训练时,MixMatch 在错误率(11.08%对 36.03%;作为比较,在所有 50k 个图像上完全监督的情况具有 4.13%的误差率)。[1]这些远远不是增量结果,该技术显示出显著改善半监督学习状态的潜力。

半监督学习在很大程度上是一场反对过度适应的战斗;当标记集很小时,不需要非常大的神经网络来记忆整个训练集。几乎所有半监督方法背后的一般思想是利用未标记数据作为有标记数据训练的正则化器。对于各种半监督学习方法的概述,请参见 Sebastian Ruder 的这篇博客文章。不同的技术采用不同形式的正则化,MixMatch 论文将它们分为三组:熵最小化、一致性正则化和一般正则化。由于所有三种形式的正则化都被证明是有效的,MixMatch 算法包含了每种形式的特征。

MixMatch 是对近年来出现的几种技术的组合和改进,包括:刻薄老师[2]、虚拟对抗训练[3]和 Mixup [4]。在高层次上,MixMatch 的思想是使用来自模型的预测来标记未标记的数据,然后以多种形式应用大量正则化。第一种是执行几次数据扩充,并对标签预测取平均值。这些预测然后被“锐化”以减少它们的熵。最后,在标记和未标记的集合上执行混合。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Diagram of MixMatch — Image taken from original paper [1]

我这篇文章的目标是那些熟悉 Pytorch 的人,但不一定是 fastai。这篇文章的 Jupyter 笔记本版本包含了重现所有结果所需的全部代码,参见这个资源库。

法斯泰

在进入本文之前,我将简要介绍一下 fastai 。Fastai 是一个基于 Pytorch 的库,它使得编写机器学习应用程序变得更加容易和简单。Fast.ai 还提供了一个非常棒的在线课程,涵盖了 fastai 和深度学习。与纯 Pytorch 相比,fastai 大大减少了生成最先进的神经网络所需的样板代码的数量。这里我们将使用 fastai 的数据管道和训练循环特性。

Imports

成分

让我们首先描述组装 MixMatch 所需的各个部分,然后在最后将它们放在一起形成完整的算法。根据本文,我们将使用 CIFAR10 并随机选择 500 张图像作为标记的训练集。标准的 10000 图像测试装置用于所有精度测量。

数据扩充

数据增强是一种广泛使用的一致性正则化技术,其最大的成功(到目前为止)是在计算机视觉领域。这个想法是在保留语义标签的同时改变输入数据。对于图像,常见的放大包括旋转、裁剪、缩放、增亮等。—不改变图像基本内容的所有变换。MixMatch 通过多次执行增强来产生多个新图像,从而更进一步。然后对这些图像上的模型预测进行平均,以产生未标记数据的目标。这使得预测比使用单一图像更加稳健。作者发现仅仅两次增加就足以看到这种好处。

Fastai 有一个高效的转换系统,我们将在数据上加以利用。然而,由于它被设计为每个图像只产生一个增强,而我们需要几个,我们将从修改默认的 LabelList 开始,以发出多个增强。

Multiple Augmentation

Fastai 的数据块 api 允许灵活地加载、标记和整理几乎任何形式的数据。然而,它没有一种方法来获取一个文件夹的子集和另一个文件夹的整体,而这是这里所需要的。因此,我们将对 ImageList 类进行子类化,并添加一个自定义方法。我们将使用不带参数的 fastai 的get_transforms方法来使用默认的图像转换;它们是围绕中心 y 轴翻转、旋转 10 度、缩放、光照变化和扭曲。Fastai 的变换系统在应用时会自动随机化每个变换的确切参数。

混合

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Mixup

Mixup 首先由张、西塞、多芬和洛佩兹-帕兹[4]在 2018 年提出,属于一般或传统正则化的范畴。Mixup 不是将单个图像传递给模型,而是在两个独立的训练图像之间执行线性插值,然后将其传递给模型。使用与图像相同的λ系数,图像的一个热编码标签也被内插。该系数是从贝塔分布中随机抽取的,由阿尔法参数化。通常,α需要根据数据集进行调整。当α值较小时,贝塔分布的大部分权重在尾部,接近 0 或 1。随着α的增加,分布变得均匀,然后在 0.5 左右逐渐达到峰值。因此,α可以被视为控制混合的强度;较小的值只会导致少量的混合,而较大的值偏向于最大混合(50/50)。在极端情况下,α=0 导致完全没有混合,当α→∞,β接近以 0.5 为中心的狄拉克δ分布。作者建议从 0.75 开始,如下图所示,大部分重量仍然在尾部。本文对原方法做了一处修改,即把λ设为 max(λ,1-λ);这使混音偏向原始图像。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Beta Distribution

Mixup

磨刀

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Sharpen

作者使用上述方程作为熵最小化的一种形式,增强了模型对未标记数据的预测。如果温度 T 这个相对简单的步骤,不涉及任何学习参数,对算法来说非常重要。在一项烧蚀研究中,该论文报告称,当移除锐化步骤(将 T 设置为 1)时,精度降低了 16%以上。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Sharpening random distribution

半监督学习中熵最小化背后的思想是分类器的决策边界不应穿过数据空间的高密度区域。如果是这种情况,边界会将非常接近的数据分开。此外,微小的扰动会导致预测的巨大变化。由于决策边界附近的预测更不确定,熵最小化寻求使模型对其预测更有信心,从而使边界远离数据。虽然其他方法[3]将熵项添加到损失中,但是 MixMatch 通过上面的等式直接降低了未标记目标的熵。

作为这种技术的一个例子,让我们尝试一个比 CIFAR-MNIST 更简单、更容易可视化的分类问题。我们仍然将 500 个随机样本作为带标签的训练集,而将其余的样本作为无标签的训练集。完整的图像用于训练,但我们也将使用 tSNE 将每个图像缩减为二维图像进行可视化。按照 MixMatch 关于未标记数据的相同方法,以半监督方式进行训练,我们将使用模型本身来生成伪标签。该模型仅由两个卷积层和一个线性头部组成。没有使用混淆或数据扩充,所以我们可以隔离熵最小化的影响。损失函数在很大程度上也与 MixMatch 相同,对标记数据使用交叉熵,对未标记数据使用均方误差(有关其背后的原理,请参见下面的损失部分)。上面的图像是在没有使用锐化的情况下训练的,而在下面的图像中,伪标签是用 T =0.5 锐化的。分别对十个时期进行训练,非锐化模型的测试准确率为 80.1%,锐化模型的准确率为 90.7%。在下图中,颜色对应于预测的类,标记大小与预测置信度成反比(标记越小越有把握)。如标记大小所示,非锐化模型有很多不确定性,尤其是在聚类的边缘周围,而锐化模型在其预测中更有信心。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

The effect of sharpening on the semi-supervised training of MNIST. Images in MNIST were reduced to two dimensions using tSNE. Colors correspond to predicted class, and marker size is inversely proportional to prediction confidence (smaller markers are more confident). The upper image depicts training with T=1, and the lower image with T=0.5.

MixMatch 算法

现在所有的部分都准备好了,完整的算法就可以实现了。下面是单个训练迭代的步骤:

  1. 提供一批带标签的数据和一批无标签的数据
  2. 扩充标记的批次以产生新的训练批次。
  3. 将未标记批次中的每个图像放大 K 倍,以产生总共批次大小* K 个新的未标记样本。
  4. 对于未标记批次中的每个原始图像,将 K 个扩充版本传递给模型。对增强的模型预测进行平均,以产生增强图像的单个伪标签。
  5. 锐化伪标签。
  6. 扩充的标记数据集及其标签形成集合 x。扩充的未标记数据及其(预测的)标签形成集合 u。
  7. 将集合 U 和 X 连接成集合 w。
  8. 通过对集合 X 和|X|应用混合来形成集合 X。
  9. 通过对集合 U 和步骤 8 中未使用的 W 中的示例应用混合来形成集合 U′。

然后将集合 X '(标记的混合)和 U '(未标记的混合)传递给模型,并使用相应的混合标签计算损失。

模型

我们将使用 28 层的宽 resnet 模型,生长因子为 2,以匹配纸张。我们将使用 fastai 包含的 WRN 实现,并与本文中使用的架构相匹配。

失败

有了数据和模型,我们现在将实现训练所需的最后一部分——损失函数。损失函数是两项的总和,即标记损失和未标记损失。标记损失使用标准交叉熵;然而,未标记的损失函数是 l2 损失。这是因为 l2 损失对非常不正确的预测不太敏感。交叉熵损失是无界的,并且随着模型的正确类别的预测概率趋向于零,交叉熵趋向于无穷大。然而,对于 l2 损失,由于我们正在处理概率,最坏的情况是当目标为 1 时模型预测为 0,反之亦然;这导致损失 1。由于未标记的目标来自模型本身,该算法不想过于严厉地惩罚不正确的预测。参数λ ( l在代码中,因为λ是保留的)控制这两项之间的平衡。

我们将通过在第一个 3000 次迭代(大约 10 个时期)中线性增加未标记损失的权重来稍微偏离本文。在应用这个 rampup 之前,训练模型有困难;我们发现,在早期,精确度增长非常缓慢。由于训练开始时预测的标签本质上是随机的,所以延迟未标记损失的应用是有意义的。当未标记损失的权重变得显著时,模型应该做出相当好的预测。

培养

在培训之前,让我们回顾一下已经介绍过的超参数。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Hyperparameters

该论文的作者声称,T 和 K 应该在大多数数据集上相对恒定,而α和λ需要在每个数据集上进行调整。我们将使用与论文的官方实现相同的超参数值。

一个实现细节:该论文提到,它不是学习速率退火,而是用训练模型参数的指数移动平均值来更新第二个模型。这是另一种形式的正则化,但对算法来说并不重要。对于那些感兴趣的人来说,存储库中有使用 EMA 模型进行培训的代码。然而,在学习速率调度上没有明显的好处,为了简单起见,我们将放弃 EMA,使用 fastai 的单周期策略的实现来调度学习和动量速率。

我们将使用 fastai 的回调系统来编写一个处理大多数 MixMatch 步骤的方法。这个方法从有标签和无标签的集合中分批获取,得到预测的标签,然后执行混合。

fastai Learner对象包含数据加载器和模型,负责执行训练循环。它也有很多效用函数,如学习率发现和预测解释。该实现中的时期是通过整个未标记数据集的一次。

Learner

结果

作为参考,这些测试是在一个有 16 个 CPU 和一个 P100 GPU 的谷歌计算引擎虚拟机上运行的。第一步是建立一些基线,以便可以比较 MixMatch 的性能。首先,我们将使用所有 50k 训练图像尝试完全监督的情况。接下来,我们将只对 500 个带标签的图像进行训练,没有非监督的组件。最后,我们将使用上一节定义的学习器,用 MixMatch 进行训练。这些跑步的全部细节可以在邮报的资料库的笔记本中找到。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Results

结论

MixMatch 显然拥有令人印象深刻的性能,但缺点是额外的培训时间成本。与完全监督的情况相比,训练 MixMatch 需要大约 2.5 倍的时间。其中一些可能是由于实现中的低效率,但是生成多个增强然后获得标签的模型预测具有显著的成本,尤其是在一个 GPU 的情况下。我们使用官方的 Tensorflow 实现进行比较,并验证 MixMatch 需要很长时间才能完全收敛;超过 12 个小时的训练导致的错误率比论文中报道的要高几个百分点。在 P100 装置上需要将近 36 个小时的训练才能完全匹配他们的结果。然而,几个小时的训练将实现绝大多数的准确度提高,最后的百分之几花费了总训练时间的大部分。

虽然增强和锐化非常有益,但这篇论文的烧蚀研究表明,从误差角度来看,最重要的一个因素是混淆。这也是为什么它如此有效的最神秘的部分——为什么在图像之间的预测中实施线性会有助于模型?当然,它减少了训练数据的记忆,但数据扩充也是如此,在这种情况下效果不尽相同。甚至最初的 MixUp 论文也只提供了关于其功效的非正式论证;根据该论文:

“我们认为,这种线性行为减少了在训练样本之外进行预测时不必要的振荡。此外,从奥卡姆剃刀的角度来看,线性是一个很好的归纳偏差,因为它是最简单的可能行为之一”[4]

其他研究扩展了这一思想,例如通过混合中间状态而不是输入[6],或者使用神经网络而不是β函数来产生混合系数5。然而,我无法找到一个坚实的理论依据;这是另一种属于“它只是工作”类别的技术。很难进行生物学类比——人类很难通过将一个概念与一个不相关的概念混合来学习它。

MixMatch 是一种非常有前途的方法,适用于计算机视觉以外的领域。看到它被进一步理解和应用将会很有趣。

参考

[1]:贝特洛、大卫、尼古拉斯·卡里尼、伊恩·古德菲勒、尼古拉斯·帕伯诺、阿维塔尔·奥利弗和科林·拉斐尔。" MixMatch:半监督学习的整体方法."ArXiv:1905.02249 [Cs,Stat],2019 年 5 月 6 日。http://arxiv.org/abs/1905.02249

[2]:塔尔瓦伊宁、安蒂、哈里瓦尔波拉。"平均教师是更好的榜样:加权平均一致性目标提高了半监督深度学习的结果."ArXiv:1703.01780 [Cs,Stat],2017 年 3 月 6 日。http://arxiv.org/abs/1703.01780

[3]:宫藤,Takeru,前田信一,小山正德,石井信。"虚拟对抗训练:监督和半监督学习的正则化方法."ArXiv:1704.03976 [Cs,Stat],2017 年 4 月 12 日。【http://arxiv.org/abs/1704.03976】T4。

[4]:张、、穆斯塔法·西塞、扬恩·多芬和·帕斯。"混淆:超越经验风险最小化."ArXiv:1710.09412 [Cs,Stat],2017 年 10 月 25 日。http://arxiv.org/abs/1710.09412

[6]:维尔马、维卡斯、阿历克斯·兰姆、克里斯多夫·贝克汉姆、阿米尔·纳杰菲、约安尼斯·米特利亚格卡斯、亚伦·库维尔、戴维·洛佩斯-帕兹、约舒阿·本吉奥。“流形混合:通过插值隐藏状态实现更好的表示”,2018 年 6 月 13 日。https://arxiv.org/abs/1806.05236v7

关于软件工程现状的几点看法

原文:https://towardsdatascience.com/a-few-points-on-the-state-of-software-engineering-9256c98fac4b?source=collection_archive---------14-----------------------

在这篇短文中,我对当代软件工程实践的挑战进行了简短的讨论,确定了其当前状态的一些潜在原因。在随后的文章中,我将介绍和讨论主流范例用来最小化软件复杂性的策略。这里的观察主要来自我自己的实地经验。因此,这里进行的审查不能说是详尽无遗的。强烈建议被激发进一步研究这个主题的读者去研究参考文献中提到的作品。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Monet’s Rouen Cathedral (cropped). It reminds me of Concepts, Techniques, and Model of Computer Programming.

毫不奇怪,软件工程包含大量的认知努力。要获得软件的所有方面并拿出一个成品,需要跨学科的努力:从需求分析到规范,到设计,到编码,到测试,到评估,以及维护。软件工程使用计算机科学来设计和分析算法,使用工程工具来构建基础设施,使用管理技术来定义权衡、风险、监督人员和监控进度。E. E .小大卫指出[1]:

很少有人认识到今天如此著名的高科技本质上是一种数学技术。

与一些人愿意相信的相反,软件工程不仅仅是写代码。然而,学习软件工程的一种方法是学习编程,这是本文的主要兴趣所在。根据 Brooks 的说法,编程的本质是连锁概念的构建和表示:算法、数据结构、功能以及它们之间的关系[2],而对 Dijkstra 来说,它是*“组织复杂性的艺术”*【3】。这两种观点相互补充,因为在大多数情况下,软件系统的元素以非线性方式相互作用,整体的复杂性增加得更快。正因为如此,在大多数情况下,对程序正确性的推理,无论是正式的还是非正式的,从非平凡到几乎不可能。尽管如此,证明程序具有所需属性的能力是程序员的基本职责之一。

在这种情况下,一个大型软件系统的复杂性经常超出任何一个人的理解和控制。由此而来的是对高效沟通的需求。为了能够协调许多专业人员的项目开发,不仅要掌握复杂社会系统的内部运作,还要组织个人之间的有效知识转移,因为缺乏这种能力可能会导致对需求的误解和丧失远见。Dijkstra 指出:“磨练你自己的智力是不够的(那将和你一起进入坟墓),你必须教别人如何磨练他们的智力” [4]。不幸的是,目前的教育体系似乎不能满足对熟练软件开发人员的极高需求。J. C. Adams 注意到*“需要高级计算技能的公司发现对稀缺资源——拥有这些技能的人——的激烈竞争”* 5。软件工程的短缺不仅仅是缺乏任何个人,而是缺乏有经验的专业人员。

然而,我们必须记住,编程只是在 20 世纪 80 年代初才作为一种职业出现的。因此,它相对较新且不成熟,许多软件公司和从业者缺乏对该技术的深刻理解。用 Dijkstra 的话来说,许多急需的工具都需要打磨。现有技术的优势、局限性和需求是可疑的。这同样适用于软件范例、技术,特别是设计用来代表计算机编程当前趋势的语言。在过去的 20 年里,数十种不同的语言被引进和抛弃。根据我的经验,许多主流工具,比如 JavaScript,几乎都有严重缺陷的名声。

这门学科的年轻也反映在它的科学研究上。尽管研究团体很活跃,但是到目前为止,他们还不能准确地整理出许多关于软件工程的基本概念。例如,Baragry 指出,尽管从 20 世纪 50 年代就开始讨论软件体系结构,但是只有 Shaw 1989 年的大型系统需要更高层次的抽象【6】,以及 Perry 和 Wolf 随后的论文软件体系结构研究的基础【7】,为软件体系结构作为一个主要研究领域的出现奠定了基础。即使是 Garlan 和 Shaw 给出的最广泛使用的定义,也没有被社区普遍接受[8]。

人们必须记住,尽管编程的技术和科学取得了令人难以置信的成果,但它们都非常年轻,并且在这种特性和所生产的软件质量之间存在着明显的相关性。要了解这一点,可以考察一下编程劳动的成果。

行业状况

软件业的兴起时期是一个艰难的时期。尽管它带来了二十世纪最伟大的工程成就之一——阿波罗制导系统,但它却被臭名昭著的质量问题所困扰[9]。许多预算超支(如 OS/360)、财产损失(跨西伯利亚天然气管道爆炸)甚至重伤和死亡(臭名昭著的 Therac-25 事件)导致了 1968/1969 年软件危机的认定。许多软件问题导致北约科学会议确定软件不可靠、不可维护、交付延迟且超出预算[10]。1972 年,Dijkstra 指出了同样的问题[11]。

最近的失败

虽然自 20 世纪 60 年代以来,软件工程已经走过了漫长的道路,但尚不清楚这场危机是否已经完全消退。不幸的是,近代史上不乏悲惨的软件故障。1991 年,一枚弹道导弹袭击了美国驻沙特阿拉伯的军营,造成 28 人死亡,96 人受伤。1997 年,一个车载地面高度预警系统是造成 228 人死亡的韩国空难的部分原因[13]。2018 年,优步的一辆自动驾驶汽车的软件计算错误导致一名行人死亡[14]。最后,在狮航波音 737 Max 8 喷气式飞机于 2018 年坠入爪哇海,造成 189 名乘客和机组人员死亡后,联邦航空管理局向波音 737 Max 8 和 9 飞机的运营商发出紧急通知,警告说有故障的“迎角”传感器读数*“可能导致机组人员难以控制飞机。”坠机事件的调查人员将飞机飞行控制系统的故障描述为小故障。132 天后,埃塞俄比亚航空公司的波音 737 飞机在亚的斯亚贝巴郊外坠毁,157 人遇难。*

鉴于航空航天事故数量惊人,N. G. Leveson 警告说,紧密耦合的系统极其复杂,它们之间的相互作用失调[16]:

本文调查的所有事故都显示了系统事故的某些方面。交互的复杂性和紧耦合导致系统事故。软件允许我们构建复杂程度和耦合度超出我们控制能力的系统;事实上,我们正在构建的系统中,组件之间的交互(通常由软件控制)无法全部被计划、理解、预期或防范。

斯坦迪什报告及其批评

1994 年,独立的国际 IT 研究组织 Standish Group 发表了臭名昭著的 Chaos 报告,报告显示了令人震惊的 16%的软件项目成功率。2004 年,29%的项目成功,53%受到质疑,18%失败。在两个最初的报告中,项目的成功是基于它是否“在合理的估计时间内,保持在预算内,并且包含大量估计的特性和功能”完成的在 2015 年,结果是相似的,29%的项目成功,52%被认为有挑战,19%失败,其中项目的成功是基于它是否“在合理的估计时间内解决,保持在预算内,并交付客户和用户满意,而不管最初的范围”[17]。

Standish 最初和最近的数据经常被认为是软件业失败的证据。然而,多年来,提出了许多反对意见,质疑斯坦迪什的方法。许多人认为斯坦迪什的数字是*“不可靠,不一定反映现实”*【18】【19】【20】。

埃尔·埃马姆等人指出[21]:

尽管有各种关于软件项目失败率的行业报告,但实际数字仍然不确定。研究人员在 2005 年和 2007 年对全球 IT 部门进行了网络调查。结果表明,软件危机可能被夸大了,大多数软件项目都交付了。然而,对于一个应用学科来说,总的项目失败率,包括被取消的和已完成的但表现不佳的项目,仍然是很高的。

软件工艺

不管实际情况如何,随着技术的进步,新的劳动力进入市场,关于危机的争论逐渐平息。从作者的个人经验来看,软件产品的质量似乎在整个行业中分布得很不均匀,在具体的努力领域之间有显著的差异。这与没有既定做法的新兴市场的不同质量标准、不同水平的期望和所生产软件的重要性以及财务利润优先于责任有关。毫不奇怪,在工艺不被关注的市场上,软件的低质量更容易被忽视。

为了应对对行业未来日益增长的担忧,《敏捷宣言》(Agile manifesto)的合著者、《坚实的原则》(SOLID principles)以及工匠精神运动的支持者罗伯特·c·马丁(Robert C. Martin)向程序员们提出了一个誓言(类似于《日内瓦宣言》(Declaration of Geneva),要求*“捍卫和维护职业的荣誉”。那些宣誓成为程序员的人,除了其他人之外,还应该发誓“无所畏惧,坚持不懈地抓住每一个机会改进代码”*【22】。

行业人口统计

当讨论这个行业的弊病时,人们必须记住当前的行业劳动力是多么年轻。自 20 世纪 80 年代以来,软件工程才成为一个普遍的职业。罗伯特·c·马丁推测,到 1980 年,以前来自工程、科学或数学等领域的高技能个人(通常在三四十岁)被数百万刚刚毕业的年轻人所取代[23]。在那之前,程序员是训练有素的专业人士,他们受雇于其他工作职能部门,通常更老更成熟,不需要太多的管理。在某种程度上,这场革命是由家庭和商业计算的出现促成的。Martin 接着说,粗略地说,程序员人数每五年翻一番(或者说过去是这样),这意味着,在任何时候,一半的程序员只有不到五年的经验。不管这个观察多么正确,一个不可否认的事实是,现在,一般的程序员都很年轻。

2018 年,致力于编程的热门问答网站 StackOverflow 进行了一项 30 分钟的调查,覆盖了全球超过 10 万名开发者[24]。调查的主题从人工智能到编码伦理。结果显示,在专业开发人员中:

  • 30.1%的人参加 0-2 年的专业课程,27.4%的人参加 3-5 年的专业课程,14.6%的人参加 6-8 年的专业课程。换句话说,72.1%的职业受访者拥有 0 至 8 年的经验;
  • 46.1%拥有学士学位,22.6%拥有硕士学位,在本科专业中,只有 63.7%的学位是计算机科学、计算机工程或软件工程;
  • 26.1%小于 25 岁,49.2%在 25 至 34 岁之间。

总之,StackOverflow 的发现似乎支持马丁关于计算机编程行业永远缺乏经验的说法。马丁还指出,由于教育系统无法弥补行业的高速增长,年轻人注定会一次又一次地重复同样的错误。一些程序员将这种现象称为业界的十年失忆【26】。

摘要

正在进行的辩论似乎难以解决,而且可能永远如此。无论如何,重要的是不要自满。Moseley 和 Marks 认为复杂性是当今软件绝大多数问题的根源[25]:

不可靠性、延迟交付、缺乏安全性——通常甚至是大规模系统中的低性能都可以被认为是源于不可管理的复杂性。复杂性作为这些其他问题的主要原因的主要地位仅仅来自于这样一个事实,即能够理解一个系统是避免所有这些问题的先决条件,当然,复杂性摧毁的正是这一点。

在他的经典论文 No Silver Bullet 中,Brooks 指出软件的复杂性是一个基本属性[2]。由此,我们可以得出结论,软件系统中的大部分复杂性是必不可少的。Moseley 和 Marks 不同意这种观点,他们指出软件系统中的大部分复杂性实际上是偶然的,并且是可以消除的[25]。具体来说,他们认为复杂性的主要来源是对主流语言中状态的错误处理。

我们将在以后的文章中研究这个想法。在此之前,敬请关注,感谢您的阅读。

如果您有任何反馈(尤其是批评性的),请评论或给我发电子邮件至 iwoherka@gmail.com**。**

参考

  1. W.洛杉矶.弗里德曼。解决现实世界问题的课程。工业和应用数学学会,第一版,1987 年。
  2. F.软件工程的无银弹本质和事故。计算机,20(4):10–19,1987 年 4 月。
  3. E.迪克斯特拉,奥达尔和 c .霍尔。结构化程序设计笔记。数据处理中的 APIC 研究,8,1972。
  4. E.w .迪杰斯特拉。我对计算科学的希望(ewd709)。《第四届国际软件工程会议论文集》, ICSE '79,第 442-448 页,美国新泽西州皮斯卡塔韦,1979 年。IEEE 出版社。
  5. 计算机是当今最安全的职业选择。https://cacm.acm.org/blogs/blog-cacm/ 180053-计算机是最安全的职业选择-今天/全文。访问时间:2019–03–30。
  6. 米(meter 的缩写))肖。更大规模的系统需要更高层次的抽象。《第五届软件规范和设计国际研讨会论文集》, IWSSD '89,第 143-146 页,美国纽约州纽约市,1989 年。ACM。
  7. D.e .佩里和 A. L .沃尔夫。软件体系结构研究基础。SIGSOFT Softw。英语。注释,17(4):40–52,1992 年 10 月。
  8. J.巴拉格雷和 k .里德。为什么定义软件架构如此困难?《第五届亚太软件工程会议论文集》, APSEC '98,第 28 页,美国 DC 华盛顿州,1998 年。IEEE 计算机学会。
  9. 页(page 的缩写)诺尔和 b .兰德尔,编辑。软件工程:由北约科学委员会主办的会议报告,德国加米施,1968 年 10 月 7-11 日,布鲁塞尔,北约科学事务处。1969.
  10. 页(page 的缩写)诺尔和 b .兰德尔,编辑。软件工程:由北约科学委员会主办的会议报告,德国加米施,1968 年 10 月 7-11 日,布鲁塞尔,北约科学事务处。1969.
  11. E.w .迪杰斯特拉。谦逊的程序员。Commun。美国计算机学会,15(10):859–866,1972 年 10 月。
  12. R-17 vs 爱国者:四舍五入的问题。https://www.viva64.com/en/b/0445/.访问时间:2019–03–30。
  13. 疲劳和失误被指在关岛坠机。https://www.nytimes.com/1999/11/03/us/疲劳和错误被引用于关岛坠机事件. html .访问时间:2019–03–30。
  14. 报道:软件 bug 导致优步自动驾驶撞车死亡。【https://arstechnica.com/tech-policy/】T22018/05/report-软件-bug-导致死亡-无人驾驶-撞车/。访问时间:2019–03-30。
  15. 当一个软件故障导致一架客机坠毁时,一些棘手的问题被提了出来。https://www.viva64.com/en/b/0445/。访问时间:2019–03–30。
  16. 名词(noun 的缩写)g .莱韦森。软件在航天器事故中的作用。宇宙飞船和火箭杂志,41(4):564–575,2004。
  17. 南团体。混沌报告:2015,2015
  18. R.格拉斯。斯坦迪什报告:它真的描述了一场软件危机吗?Commun。美国计算机学会,2006 年 8 月,49:15–16。
  19. 米(meter 的缩写))乔根森和 k .莫洛肯-奥斯特瓦尔德。软件成本超支有多大?对 1994 年混沌报告的评论。Inf。Softw。技术。,48(4):297–301,2006 年 4 月
  20. C.伊夫琳斯。混沌报告数字的起伏。IEEE 软件,27(1):30–36,2010 年 1 月。
  21. K.埃马姆和克鲁。it 软件项目失败的重复调查。IEEE Softw。,25(5):84–90,2008 年 9 月。
  22. 程序员的誓言。https://blog . clean coder . com/uncle-bob/2015/11/18/the programmerswear。 html。访问时间:2019–03–30。
  23. 编程的未来。https://www.youtube.com/watch?v=ecIWPzGEbFc.访问时间:2019–03–30。
  24. 堆栈溢出—开发者调查结果:2018 年。https://insights.stackoverflow.com/survey/2018/.访问时间:2019–03–30。
  25. B.莫斯利和 p .马克斯。从沥青坑里出来。2006 年软件实践进步(SPA)课程。
  26. 功能极客——第一集——罗伯特·c·马丁。https://www . functional geekery . com/episode-1-Robert-c-Martin/

构建闪亮应用程序时需要注意的几件事

原文:https://towardsdatascience.com/a-few-things-to-take-care-of-while-building-shiny-apps-888e4676090b?source=collection_archive---------24-----------------------

构建 RShiny 应用程序时克服障碍和节省时间的简化技术

自从 2011 年末 RStudio 的发展以来,Rshiny 已经被广泛用于构建仪表板和应用程序,这些仪表板和应用程序具有 web 上的后端 R 支持和部署。现在,通过专用的包将 CSSJavaScript功能嵌入 Rshiny 应用程序是可能的,其目的是提高交互性并提供动态界面。我已经开发和部署 Rshiny 应用程序 3 年多了,所以通过这篇博客,我将分享一些障碍以及如何在开发产品时用简单的技巧克服它们。

首先,让我简单介绍一下初级/中级优秀程序员在设计应用程序时可能会遇到的障碍。

1.花在设计上的时间

美学是最重要的,正如人们所说的那样——“许多难以设计的东西证明很容易实现”——塞缪尔·约翰逊。

虽然 ShinyDashboardShinyDashboardPlus 提供了设计 Dashboard 的模板,但在提供动态 UI 方面,它们往往有所欠缺。例如,引导模式在使用 shinydashboard 页面时失败。为了克服这个问题,需要使用引导页面设计一个仪表板,但是这样你就失去了设计的机会,因为你需要从头开始重新构建它,而且这需要大量的研究,这几乎占用了总时间的 30- 40 %。对于一个刚刚开始使用 RShiny 设计应用程序的初学者来说,可能会觉得它很慢。

2.没有时间进行测试——再次构建和测试

虽然看起来应用程序运行良好,但在演示中你的应用程序突然下毛毛雨,这表明控制台上有一个错误。此错误可能是由于不合逻辑的数据操作或子集操作导致的,这些操作返回了零个条目,并且有时它没有指出错误发生的位置。当您修复代码并使工具再次运行时,您会看到一些之前没有注意到的错误。这也发生在我身上。

原因是我们过多地参与了逻辑与设计的集成,以至于我们几乎没有足够的带宽来适当地处理错误。

3。随机应变…适应…克服挑战

假设您为仪表板中的一个页面编写了一个逻辑,并将其展示给客户。突然,你的客户要求对它进行细微的改变,这可能需要你改变现有工具的反应,你发现自己很痛苦。当你正在设计的工具有多个模块,而你/你的客户从来没有想到这个即将到来的逻辑会被证明是有价值的时候,这种情况经常发生。它为你的工作增加了价值,但是要花费大量的时间重新回到前面。

解释完挑战后,现在让我们来关注如何应对它们。

1.始终遵循 SDLC { 软件开发生命周期 }

构建 RShiny 应用程序是一个项目,每个项目都有阶段。虽然我们大多数人都知道 SDLC,但是我们很少打算实现它。大部分时间花在设计上,没有时间测试和集成。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Easy way to understand SDLC | Dignitas Digital

拥有预定义的 SDLC 不仅有助于软件开发,还有助于跟踪我们在每个阶段投入了多少时间。

这是我在开始这个项目之前使用的一种方法:

  • 设计线框:总是设计一个线框,它只不过是一个网页的布局,展示什么样的界面元素将存在于关键页面上。你可以使用任何工具,甚至可以在普通纸上设计。手里有线框将帮助你确定需要什么成分来开发页面,因此反过来,在实现美学方面将节省大量时间。

2。截止日期和工作量分配

虽然构建闪亮的应用程序在开始时似乎很容易,但将后端与前端集成起来需要付出很多努力。如果您正在设置部署的截止日期,请确保:

—牢记要解决的测试案例。

—设计时,确保检查元素以调整浏览器本身的宽度和高度。 示例 :通过手动微调,确定合适的框宽或高度。

Changing Aesthetics on the fly in Rshiny app.

—将代码分离到模块中,并在页面数量增加时相应地分配带宽。例如,一个页面的前端代码和后端代码将作为单独的 R 脚本保存,这些脚本将在服务器中使用 source 命令导入。所以,如果你有一个团队在开发这个应用程序,每个人都可以用来创建一个单独的模块,这个模块可以在以后集成。关于它的更多信息在这里 提到

—如果有大量数据需要与后端集成,尝试将代码分成三个部分,即。全球。r,服务器。r 和 UI。r,这里是全局。r 将只包含初始数据获取和数据清理操作。

—如果您的数据导入和清理需要很长时间,请尝试在运行 global 后存储初始工作空间环境。r 作为工作空间图像(. RData ),这样以后导入它所花的时间就会减少,节省下来的时间可以用来增强 UI。

3.快速获取有用的资源

在设计闪亮的应用程序时,许多概念将成为新的搅拌机。因此,在短时间内找到合适的资源将证明是有益的。除了寻找解决堆栈溢出的方法,这里还有一些我在 RShiny 上工作时期待的资源**

Asking Questions on GitHub

结束注释

因此,在了解了建议的漏洞并将其应用到您的 RShiny 项目之后,我希望它能帮助您节省大量的时间。

接下来,我将分享一些 R 技巧和 Rshiny 功能,它们将帮助你平稳高效地构建 RShiny 应用。

进入科技行业前你应该知道的几件事

原文:https://towardsdatascience.com/a-few-things-you-should-know-before-going-into-tech-aebc77c4f6cf?source=collection_archive---------31-----------------------

对最近科技发展趋势的快速总结

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Median Salary in Tech in the US (2018), based on Operating System used

很少有行业像科技这样随着新趋势而蓬勃发展。每年都有新的框架、编程语言和技术颠覆这个行业的核心。科技无疑是当今最有趣、最赚钱的工作领域之一。

一个新人在找这个领域的工作的同时,肯定要对这个行业的实际趋势和需要的技能做一些研究。无论一个人是对最新技术感兴趣,还是仅仅想要一份高薪的技术工作,知道什么是热门,什么不是很重要。

本文根据 Stackoverflow 进行的问卷调查提供了一些有趣的见解。调查问卷可追溯至 2013 年和 2018 年,包含约 20,000 条(干净的)观察结果。为了确保结果的可比性,数据集只关注美国市场和全职工作岗位。这几年间的问卷结构发生了显著变化,但经过广泛的数据清理,仍然可以得出有趣的结论。我们将在下面的段落中讨论它们。

  1. Python 热,PHP 不热

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

上面两张图表显示了 2013 年和 2018 年编程语言的相对受欢迎程度*。由于不同年份之间 Stackoverflow 问卷结构的变化,上述两个图并不完全可比。但是,有些趋势还是很明显的。

在常见的“前端-后端-数据库”工具箱(Java、C、Javascript、SQL)后面,唯一一种相对份额在这些年来有所增加的语言是 Python。另一方面,C#和 PHP 正在失去它们在编程语言组合中的份额和地位。这并不奇怪,因为 Pythons 的功能和库在过去的几年里显著增加了。在以前没有使用 Python 的领域,例如前端开发,python 正成为开发人员的首选工具。

2。大数据意味着更多的数据管理员

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

上面的图表显示了技术工作在不同职业/职位中的分布情况。在两次问卷调查过程中,一些职位名称发生了变化,这可能会导致模糊的结论。然而,数据库管理员的角色保持不变,其在技术领域的份额在 5 年间从 2%跃升至 5%。这种变化的确令人印象深刻,但也是直觉的。

最新技术允许科技公司存储海量数据,并利用这些数据获得有价值的见解。维护和结构化数据变得越来越重要,数据库管理员的角色也随之变得越来越重要。

3。经验很重要

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Feature Table explaining the Salary in US (2018)

Stackoverflow 问卷还询问了受访者的工资。我试图利用 2018 年的数据,找出哪些特征最能解释工资。使用的模型是随机森林分类,其中工资被分成 50K、100K、150K 箱。虽然分类结果很差(测试集的加权 F1 分数为 51%),但特征重要性结果很有趣。重要的是,这些结果与其他几个模型(线性回归、随机森林分类)的相同结果非常吻合。

从上面的特征表中我们可以看到,最能解释工资的因素是“编码年数”。看来,较早进入该行业并获得经验的受访者可以期待更高的薪水。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Median Salary in US in Tech for different levels of Experience

还有最后两点。

从特性表和本文开头的柱状图中,我们注意到开发人员在哪个操作系统中工作很重要。Unix 开发人员有望获得大约 12 万美元的最高年薪。

了解替代编程语言似乎是有利可图的。虽然 Java,C,Javascript 等。是最受欢迎的语言,使用 Hack、Scala 和其他“特殊用途”语言的专业人士可以期望赚得更多。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Median Salary across programming languages in US (2018)

结论

在这篇文章中,我们回顾了科技行业的一些变化趋势,并试图揭示解释该领域薪资的一些特征。使用的数据是 Stackoverflow 年度问卷数据。

总而言之:

1- Python 越来越受欢迎,而 PHP 和 C#却落后了

2-需要数据库管理员

3-经验是导致高薪的最重要的特征。然而,精通“专用”编程语言和在不太传统的操作系统如 BSD/Unix 和 MacOs 中工作也能带来高收入。

这篇文章后面的完整代码可以在这里找到,问卷数据在这里

*调查问卷的参与者回答了他们精通哪种编程语言(通常不止一种)。这里的流行度是一种编程语言在所有回答中的相对出现率。

有几次,我打碎了熊猫

原文:https://towardsdatascience.com/a-few-times-i-managed-to-broke-pandas-d3604d43708c?source=collection_archive---------26-----------------------

这里有一个场景。我希望其他人能从我这里的错误中受益。

W 当我将大部分工作从 Stata 转移到熊猫时,我遇到了一些障碍。好吧,我承认。我写了一些糟糕的代码。这是我做错的一个例子。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Image credit: Author. “Broken Pandas.” Image Credit: “Via Design Pickle” — More on attributions.

重复的列名

其他统计语言更严格地防止重复的列名。然而,熊猫可以被欺骗允许重复的列名。

如果您计划将数据集转换为另一种统计语言,重复的列名是一个问题。它们也是一个问题,因为它会在 Python 中导致意想不到的、有时难以调试的问题。

公平地说,复制这一点并不容易,下面的代码展示了如何复制:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

How I broke Pandas. Image Credit: “Author’s Screen Capture” — More on attributions.

上述数据框的用例是一个作者列表,他们被分配写两个主题中的一个。因此,主题列是分类变量或因子变量。

所以,到目前为止,没有错误。直到您尝试将选项标签映射到'topic'下的选项值,这是操作分类或因子变量时的常见操作。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Error that occurs when a Pandas data frame has more than one identically named columns. Image Credit: “Author’s Screen Capture” — More on attributions.

检查列名唯一性的一个快速方法是评估'len(df.columns) == len(set(df.columns))。如果语句评估为False,这表明您可能有重复的列名。

愚蠢的错误。很容易解决。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

How I fixed the data frame that I managed to break above. Image Credit: “Author’s Screen Capture” — More on attributions.

[## 加入我的介绍链接媒体-亚当罗斯纳尔逊

作为一个媒体会员,你的会员费的一部分会给你阅读的作家,你可以完全接触到每一个故事…

adamrossnelson.medium.com](https://adamrossnelson.medium.com/membership)

感谢阅读

把你的想法和主意发给我。你可以写信只是为了说声嗨。如果你真的需要告诉我是怎么错的,我期待着尽快和你聊天。推特:@ adamrossnelson| LinkedIn:亚当·罗斯·纳尔逊 |脸书:亚当·罗斯·纳尔逊

手腕轻轻一弹:定义下一代人机交互

原文:https://towardsdatascience.com/a-flick-of-the-wrist-defining-the-next-generation-of-human-computer-interaction-7c8f962bd014?source=collection_archive---------13-----------------------

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

以下是我在 2019 年 1 月在 TedX Goldey Beacom 上的一次演讲的书面版本。他们拍了下来,你可以在这里观看!

多年来,我们一直被魔法的概念所迷惑。有人认为,只要挥一挥魔杖,打个响指,或者说一些特殊的话,就可以在瞬间彻底改变他们周围的世界,这种想法在历史上一直占据着人们的头脑。

任何足够先进的技术都和魔法没什么区别。
—亚瑟·C·克拉克爵士

现在,我们生活在一个在屏幕上操控人类全部知识的世界里,屏幕仅仅比信用卡大一点。我敢打赌,这个房间里的每个人口袋里都有一个设备,它的计算能力比我们用来把人送上太空的技术还要强。相对于人类历史的其余部分,这一切都发生在眨眼之间。即使在我的有生之年,也很难夸大我们已经走了多远。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

St. Peter’s Square in 2005 via NBC

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

St. Peter’s Square in 2013 via NBC

随着扩展现实、机器学习和其他新兴技术的出现,我们与计算机以及彼此之间的工作方式将在未来几年内发生巨大变化。我们越来越能够不仅感知三维的数字世界,还能与它们互动并被它们看到。这本质上就是人机交互领域正在发展的东西。

今天,我将向您展示一些正在推动技术边界的 HCI 研究项目。我邀请你展望未来,看看它们将如何从根本上改变我们与计算机、信息以及彼此之间的互动方式。

但首先,花点时间和我一起做梦。今天是 20XX 年,星期二。

想象一下,一个孩子第一次上化学课。还记得学分子几何吗?原子排列成各种三维形状,像四面体和三棱锥?你必须把它们画在纸上,只用一支铅笔和一把尺子来想象这些构成我们世界基本组成部分的抽象形状。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

或者,也许你更幸运一点,参加了一个活动,像我在高中时那样安排橡皮泥和牙签。他们真的很悲伤,萎靡不振。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

相反,20XX 的孩子们玩全息图,在太空中徒手构建八面体和跷跷板。他们可以直观地操纵原子键,玩数字表示,就像我们在原子水平上理解事物一样。

想象一下,你正在远足,看到了壮丽的山景。受到它们的美丽的启发,你拿出了你的素描本,但你并没有自己身上所有的颜料。但这没关系,当你画出细细的摇摆不定的线条时,它就在你眼前变成了一幅如画的风景画。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

你下班回到家,投入到一个游戏中,这个游戏基本上把你带入了母体。作为孤胆英雄,你独自站在一个充满敌意的世界里。你被特工包围,用整个身体慢动作躲避子弹。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

现在,你想告诉我所有这些听起来很疯狂,需要我们没有的技术,对吗?但事实证明,“20XX”其实是 2018 年。这些是我们去年做的一些事情。

化学申请是卡内基梅隆大学的项目学生

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Project Pupil Chemistry Demo via Yujin Ariza

那幅画?由备忘录 Akten 提出的申请。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Learning to See via Memo Akten

慢镜头射手?超级热门的,你现在就可以去虚拟现实街机玩。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

via Super Hot VR Trailer

那么,这些东西到底是什么?我们如何做到这一点?

对于外行人来说,XR 是一个总括术语,用来描述真实和虚拟对象协同交互的连续统一体。这包括像虚拟现实这样的技术,在虚拟现实中,你的整个环境是数字的,增强现实中,你将平面图像叠加到现实世界中,以及两者之间的任何维度。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Leap Motion Mirrorworlds Concept Video

也许你玩过原始的增强现实系统,比如口袋妖怪 Go

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

或者有幸尝试过像 Beat Saber 这样的虚拟现实系统卖家。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Beat Saber via LIV and SwanVR

XR 技术的一个共同点是它们使用计算机来塑造你的感知。XR 作为一个光谱可以把你放在一个全新的和不同的环境中,或者简单地给现实世界添加信息。

机器学习本质上是使用特定的算法来教计算机如何解决问题。它被用于各种应用,从掌握围棋

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

…到为自动驾驶汽车的大脑提供动力

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

…以从少量线条中生成猫

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

via pix2cats

我画了最后一个,他大概是。

使用机器学习通过计算机的眼睛看世界有很多令人兴奋的工作。

我们能够让人工智能展示世界的一部分。我们可以向他们展示我们的身体,我们的绘画,物体如何相互作用看他们想出什么,并利用这些来塑造我们的感知。机器学习能够理解现实中的大量信息,而 XR 将帮助我们更清楚地看到这些信息。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

All watched over by machines of loving grace: Deep-dream edition (2015) via Memo Akten

我觉得一些最令人兴奋的发展是通过开源和公共资助的研究项目实现的。

OpenPose 是卡耐基梅隆大学的一个研究项目,它使用机器学习来检测单个图像中的身体。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

它已经被用作其他工作的主干,包括帮助你将整个身体放入虚拟现实的研究项目

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Deep Learning for VR/AR: Body Tracking with Intel RealSense Technology

…帮助你(或者至少是你的视频)表演复杂的芭蕾舞。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Everybody Dance Now via Caroline Chan

Pix2Pix 是伯克利的一个项目,它使用神经网络根据训练数据生成图像。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Pix2Pix via a Affinelayer

它被进一步混合到应用程序中,使你的网络摄像头变成鲜花

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Learning to See: Gloomy Sunday

…或者将威尔明顿天际线的照片变成模仿范·高的华丽画作。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

via Deep Dream Generator

Project North Star 是一款增强现实耳机,你可以在世界任何地方进行 3D 打印。有一个社区正在围绕这些耳机的采购和制造成长,我认为随着它变得更容易获得,我们将会看到一些有趣的应用。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

这些都是开源的,所以任何人都可以利用他们的成果,在此基础上开发各种应用程序。

“他们”包括我。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Me in my North Star via UDaily

我目前正在建造自己的北极星。我在特拉华大学能够 3D 打印的一些部分,其他部分来自项目周围突然出现的社区成员。这大部分发生在 UD 的夏季学者计划中,在那里我花了 10 周时间学习 XR 开发的基础知识。学期开始后,我将这一经历转化为一个本科生研究项目,专注于让跨学科的学生一起开发 XR 应用程序。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

就在上周,我去了麻省理工学院媒体实验室的黑客马拉松 Reality Virtually 。我和其他 400 多名开发人员、艺术家、设计师和程序员一起开发 XR 应用程序。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

The University of Delaware Human-Computer Interaction at Reality Virtually. Right to left: Zhang Guo, Dr. Roghayeh Barmaki, Alina Christenbury, Yan-Ming Chiou

黑客马拉松所有项目的一个规则是,它们必须是开源的,这样世界上的任何人都可以利用它们创造出新的有趣的应用程序。我们一起制作了不到 100 个 XR 项目,包括物理治疗和无障碍工具,还有游戏和互动艺术。我的团队在不到 5 天的时间里制作了一个虚拟现实逃生室,我的顾问巴马基博士的物理治疗项目获得了“最佳虚拟现实应用”。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Escape the Witch’s Grotto

在我看来,这项技术真正融合在了镜像世界的概念中。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Illustration by Anna Mill

这项技术将帮助将你周围的物理空间转换到另一个平行维度,而不是离开你的物理空间。椅子变成了山,墙壁变成了日落,“地板是熔岩”从一个简单的儿童游戏变成了一种发自内心的体验。您可以像与物理对象交互一样与数字对象交互,并且与物理对象的交互效果更好。你的环境可以向你展示它是如何工作的,就像物品向你展示如何使用它们一样。一把吉他可以教你如何弹奏它自己,告诉你如何最好地握住它来弹奏特定的和弦。或者物体可以完全改变,比如桌子变成触摸屏,铅笔变成魔杖。

是时候将话题从 AR 系统应该是什么样子转移到 AR 体验应该是什么感觉上了。大卫·霍尔茨

问题不再是“我们如何让这个工作?”而是“这应该是什么感觉?”我们正处在历史的某个点上,被认为是“魔法”的东西是真实的。就在这里,就是现在。所以,我留给你们这个:

你会用它做什么?

为了准备这个,我读了很多很多的东西,以便为这个演讲创造一个稍微有点像叙事的东西。我尽了最大努力保存来源,其中大部分都链接到 throughout,但请随意查看来源以获得完整列表。这篇文章也可以在我的网站 alinac.me 上找到。

我也有邮件列表!如果你想偶尔收到我在 alinac.me/subscribe的邮件,请注册

管理模型风险的框架

原文:https://towardsdatascience.com/a-framework-for-model-risk-5953dedbe112?source=collection_archive---------31-----------------------

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Photo by Dakota Roos on Unsplash

近年来,银行在使用定量分析和模型方面面临监管压力。因此,法规正在到位,以确保模型得到有效管理,从而降低模型风险。

美联储将模型风险定义为[1]:

基于不正确或误用的模型输出和报告的决策的潜在不利后果。模型风险可能导致财务损失、糟糕的业务和战略决策,或者损害银行组织的声誉

以银行监管为起点,我们将定义一个可用于任何机器学习部署的框架,以量化和最小化模型风险。

我们的模型风险可以分解为 4 个关键轴[2,3]:

  • 模型定义
  • 模型治理
  • 模型验证
  • 模型监控

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Model Risk Framework

模型定义

建立一个拥有明确所有者的模型清单,定义组织内运行的每个机器学习模型的目标、假设和限制

第一步是建立一个在生产中运行的机器学习模型的清单,以及它们如何相互交互。通过创建模型清单,您将能够找出哪些模型由于潜在的级联故障而具有最大的内在风险。

您的清单的目标不应该是创建技术文档,而是给涉众一个模型做什么和它的限制是什么的高层次概述

它应包括:

  1. 型号名称和描述
  2. 开发阶段(已实施使用、开发中或近期退役)
  3. 高等级风险评估
  4. 模型目标
  5. 模型假设
  6. 型号限制

评估模型重要性有助于定义与每个模型相关的高级风险。通过根据容量、使用环境和财务影响分解每个模型,您可以为每个模型分配一个风险分数[4]。例如,很少使用的模型不会像影响关键业务决策的模型那样带来很大的风险。

其中一个风险是,随着时间的推移,该模型清单会过时,为了避免这种情况,您应该指定一个人明确负责确保该文档保持最新。这并不意味着这个人应该编写所有的文档,而是他们应该跟进模型所有者,以确保他们的模型文档是最新的。

模型治理

指定负责开发、实施和使用模型的模型所有者。他们的部分职责是与高级管理层合作,为新模型的部署制定签署政策。

考虑模型治理的良好开端是定义:

  • 模型所有者:模型所有者负责确保模型得到适当的开发、实现和使用。
  • 模型开发人员:模型开发人员在模型所有者的领导下创建并实现机器学习模型。
  • 模型用户:模型用户可以是企业内部的,也可以是外部的。对于这两种情况,清楚地确定他们的需求和期望是很重要的。他们还应该参与模型开发,并可以帮助验证模型的假设。

明确地定义不同的涉众将会使分配角色和职责变得更加容易,这在模型发展和团队变化的时候尤其重要。

良好的模型治理也是关于跟踪模型的初始开发以及它如何随着时间的推移而变化。通过记录模型开发过程,即使所有者发生变化,您也能够更快地迭代。

再现性很重要,但还不够,你的文档还应该解释为什么选择一种方法而不是另一种方法,以及探索的死胡同。

在开发模型治理策略时,最后一个好的实践是定义在部署新模型之前需要什么样的管理签署。鉴于机器学习模型可能产生的影响,定义谁负责签署新模型的部署非常重要。管理层签核可以基于每个模型,也可以基于验证指标自动进行。

模型验证

定义一个外部或内部的验证过程,以确保模型按预期执行,并在部署之前进行记录。

一旦开发了模型,就需要在部署之前对其进行验证。可以通过两种方式进行验证:

1.外部验证:由外部审计师或独立方
2 执行。内部验证:验证由同一个团队或部门执行

虽然一些监管机构要求外部验证,但对于大多数不受监管的行业,您可能会在内部验证您的模型。为了最小化确认偏差,验证过程应该在模型开发人员很少或没有输入的情况下进行。这也将有助于识别模型开发过程的文档中的潜在差距。

为了使内部验证有效,应该根据模型用户的输入提前定义验证指标和阈值。验证不应仅限于简单地评估性能指标,还应包括对方法的审查,以确定尚未考虑的模型偏差或边缘情况。验证者还应该检查用于构建模型的代码,并确保它的版本是正确的。

模型监控

使用与传统 IT 系统类似的流程,定义流程来检测和解决潜在问题。

在前面的章节中,我们已经定义了流程,以确保关键的利益相关者意识到正在开发的模型中的内在风险,并确保它们是可重复的和可迭代的。

即使有好模型治理,使用机器学习模型也有风险。这些风险可以细分为:

  1. 依赖关系的变化
  2. 数据质量问题
  3. 您正在建模的过程中的变化——通常被称为概念漂移

处理模型风险意味着制定一个计划来检测和修复这些潜在的问题。做到这一点的一种方法是实施与传统 IT 系统类似的监控策略,但使用针对机器学习系统的指标。

我以前写过一些您应该监控的核心指标:部署后的模型生命周期

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Example Monitoring Dashboard — Stakion

结论

模型风险对于任何部署机器学习模型的组织来说都是一个现实,但也是经常被忽视的东西。

建立具有明确定义的模型目标、假设和限制的准确模型清单是最小化模型风险的第一步。定义模型开发、验证和签署的过程也将确保只有你满意的模型才开始被使用。最后,一旦部署了模型,您应该有一个监控策略来跟踪模型依赖性、数据质量和概念漂移。

参考:

运行数据科学项目的框架

原文:https://towardsdatascience.com/a-framework-for-running-data-science-projects-fd37b26a4389?source=collection_archive---------25-----------------------

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Seattle photo by Luca Micheli & Boston photo by Osman Rana on Unsplash

开始一个数据科学项目

对于从数据领域起步的人来说,从零开始建立一个项目似乎有点令人生畏。这可能很有诱惑力,只是把你所知道的一切都投入进去,看看什么会有效,但事实上(和其他事情一样),耐心最终会有回报的。这就是为什么数据科学家开发了各种旨在帮助管理数据项目和提供结构的框架。这些框架中的大多数都遵循类似的步骤,这些步骤将在本文中概述。

为了给出一个真实的例子,我将参考我一直在做的一个项目,比较西雅图和波士顿的 Airbnb 数据,试图提取有用的商业见解。遵循本文中的步骤将会给你一个开始的地方,并有希望让你专注于底层数据。

了解你的目标(主题理解)

在执行任何任务之前,重要的是要知道分析的目标是什么,或者你要解决什么问题。这似乎是显而易见的,但是你会惊讶于很多次有人会要求你做一些没有明确目标的事情。首先,你应该问为什么要执行任务,找出利益相关者的目标,理解关键绩效指标(KPI)。在整个项目中记住这些事情是很重要的,这样你就不会忽略什么是重要的。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Airbnb conference photo by Teemu Paananen on Unsplash

在我的案例中,使用 Airbnb 数据的目的是根据各种因素(例如位置、便利设施或大小)向用户推荐一个挂牌价格。这个商业案例很简单;价格更好的用户不会低估他们的财产而导致收入损失,也不会高估他们的预订损失。为了让我在项目过程中保持专注,我想出了一些简短的商业目标,以便在实现最终目标的过程中回答:

  • Airbnb 两个市场的价格会随季节变化吗?
  • Airbnb 的哪些房源变量会对价格产生最大影响?
  • 我能根据市场、设施和季节性预测价格吗?

将一项任务分解成业务问题、小目标或里程碑有助于保持专注,确保实现核心业务目标。

数据理解

现在是时候尝试一下,看看你有什么可用的数据。一个很好的起点是考虑你可能需要哪些数据点来实现你的目标,以及这个目标如何与你当前的数据保持一致。在 Airbnb 项目中,我需要我的因变量:我想要预测的价格。为了创建我的模型,我还需要我的独立变量,例如评论分数、位置、客人数量和设施。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

An example of a Pandas DataFrame during the Data Understanding step

接下来,检查数据的质量是很好的。我这样做是通过寻找 NaN 的,简单的错误,并检查以确保所有的数据集可以合并。这最后一点听起来微不足道,但如果我的因变量和自变量有不同的标识符,数据将是无用的。最后,在这一点上创建最初的可视化将有助于对数据的整体理解。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Initial analysis | Distribution of Airbnb prices

上面的直方图显示了 Airbnb 各个市场的价格差异。与波士顿相比,西雅图的平均价格较低,差价较小。这表明项目后期可能需要考虑地区差异。它显示,波士顿的平均房价将远远高于西雅图的房价。

在数据中翻箱倒柜之后,你可能会发现几个结果中的一个:你已经有了执行分析所需的一切,需要更多的数据,或者项目不可行,因为所需的数据不可用。

数据准备

现在我们已经有了所有需要的数据,是时候将它处理成所有分析和建模所需的格式了。这通常是流程中最耗时的部分(60–80%的时间),并且随着数据需求的发展,可能会与任何分析/建模交织在一起。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Python photo by Chris Ried on Unsplash

首先要做的是对数据进行一些清理。这可能包括处理 NaN、格式化日期、合并文件、剥离字符串、编辑价格等等。在 Airbnb 项目的这一点上,我为清理和合并我的数据做了一些基本的功能。我强烈建议这样做,因为您可以将它们添加到一个包中,并在整个项目中多次使用它们。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Example from a basic cleaning function used on the Airbnb dataset

下一部分将取决于项目最终想要达到的目标。在进行更多清理之前,我做了一些基本分析,以了解更多关于 Airbnb 的数据。对于许多项目,将需要一些更高级的处理,尤其是执行机器学习(ML)任务。例如,对分类变量进行编码,对基于文本的数据运行 NLP(自然语言处理),或者执行 PCA(主成分分析)来降低维数。任何建模之前的最后一步是在训练和测试数据集之间分割数据,因为这允许您保留一些数据用于模型调整和评估。

系统模型化

这是大多数博客文章、研究论文和面向客户的演示会关注的部分。然而,如果你幸运的话,它最多会占用你 10-20%的时间。在这一部分,我们创建机器学习模型,有洞察力的可视化或执行投影。

在我的项目中,我做了一些分析,试图解决我的第一个商业问题:Airbnb 两个市场的价格是否随季节变化?

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Seasonal trends | Seattle & Boston

季节性趋势变得相当令人惊讶,因为这两个市场全年的变化程度相似。它们在年初都有一个季节性低点,在 8 月份左右有一个高点。这种季节性变化可用于调整最终的 ML 模型,以获得全年价格的更好预测。

在上面的分析之后,我继续讨论 Airbnb 数据集的核心建模问题。为此,我进行了回归分析,根据因变量来预测上市价格。使用的回归模型是一种被称为随机森林的集合方法(这种方法的细节可以在这里找到)。模型训练如下所示:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Parameterisation of the Random Forests ML model

当优化任何形式的建模时,确保用可靠的性能指标来验证测试是很重要的。这些将根据业务案例而有所不同。在我的回归分析中,我使用了 MAE(平均绝对误差),因为它不会像 RMSE(均方根误差)等其他方法那样对较大的误差进行加权。这对于预测 Airbnb 价格很有用,因为我们更喜欢一个更通用的模型,即使一些离群值被预测错了。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Performance metrics for model parameterisation showing RMSE and MAE

模型制作和优化后,在部署任何东西之前,都需要检查、测试和评估。

估价

评估您的模型/分析是该过程中最重要的步骤之一。这是为了评估模型或见解在多大程度上可以推广到新的数据集。该过程的第一步是使用建模前搁置的测试数据,以确保模型在参数化过程中不会过度拟合。

我的模型评估的另一个重要部分是查看每个变量如何影响模型预测。这被称为功能重要性,有助于回答我的第二个商业问题:Airbnb 的哪些房源变量将对价格产生最大影响?

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Feature importance of the Random Forests model

从上面的图来看,影响价格的最重要的特征是(如你所料)房产大小指标,如卧室、浴室和客人。驱动该模型的令人惊讶的特征是,该物业是否有急救箱或一氧化碳探测器;这些可能是价格较低的房产正在提升其舒适度的一个指标。执行特征重要性的另一个关键要点是,一些变量对模型有负面影响,因此应该在建模前移除。

评估建模效果的最后一步是将该过程应用于另一个市场,并观察结果的对比。对我来说,这有助于回答整个商业问题:我能根据市场、变量和季节性预测价格吗?

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Actual Airbnb prices against the predicted prices

上面的结果显示了 Airbnb 的实际价格和预测价格。这条线代表完美的预测,从这条线到每个点的距离就是预测的误差。总的来说,模型很好地预测了总体趋势,除了异常值属性。这些异常值可能预订率低,或者有其他原因导致价格与趋势不符(例如 Airbnb 的质量)。总的来说,该模型可以很好地预测价格,为用户提供建议,从而实现核心业务目标。

通过查看您的模型验证指标和 KPI,您可以最终决定您是否成功实现了您的业务目标。

成果和部署

最后,是时候将你创造的一切付诸实践了。这可能是为外部流程部署一个模型(想想网飞推荐引擎),或者根据分析得出的见解调整内部流程。对于 Airbnb 项目,这将需要根据用户提供的便利设施在托管页面上执行价格建议。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Just sit back and relax! Photo by Ali Yahya on Unsplash

如果你认为项目到此结束,那你就大错特错了,在现实世界中,一旦你部署了一个项目,就会有无穷无尽的改进、更新和错误修复要处理。就结论而言,你能做的最好的事情就是希望你在所有的迭代之间得到一个新的项目来集中你的注意力!

完成流程

总之,在任何项目中要经历的主要步骤是:

  1. 主题理解(上下文和业务案例)
  2. 数据理解(收集和初步分析)
  3. 数据处理(准备、清理、擦洗和争论)
  4. 建模(建模、分析、探索和验证)
  5. 评估(解释、优化和评估)
  6. 部署(实施、改进和迭代)

上面的框架很大程度上遵循了 CRISP-DM 流程,并添加了来自其他框架的额外注释。这在很大程度上被视为执行数据科学项目的行业标准,应该为运行任何数据项目提供坚实的基础。

传统数据科学框架

这篇文章从 CRISP-DM 之外的一些数据框架中获得了灵感。这里有几个例子,如果你想谷歌一下或者进一步研究的话:

  • CRISP-DM(数据挖掘的跨行业标准流程)
  • KDD(数据库中的知识发现)
  • OSMEN(获取、擦洗、探索、建模、解释)
  • 数据科学生命周期

关于我

目前,我是 ASO Co(一家应用营销公司)的数据科学家。有关该项目的任何进一步信息或查看我在分析中的表现,请在下面找到我的各种社交平台的链接:

GitHub:https://github.com/WarwickR92/Airbnb-Market-Analysis

领英:https://www.linkedin.com/in/warwick-rommelrath-a7b4575a/

这个项目中的所有数据都是通过 Kaggle 上的 Airbnb 提供的,并与我的 Udacity 数据科学家 Nanodegree 一起使用。

跨团队分发数据项目的框架

原文:https://towardsdatascience.com/a-framework-to-distribute-data-projects-across-teams-15e2b9f9662?source=collection_archive---------21-----------------------

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Photo by Ansgar Scheffold on Unsplash

介绍

当您开始一个新项目或加入一个新团队时,您将经历一系列步骤来设置您的本地环境,并准备好共享您的项目。在这篇文章中,我总结了我实现这个目标的步骤。这是我一直遵循的框架,也是我在团队中实施的框架。这是我多年经验中最有效的方法。希望能对你以后的项目有所帮助。

我假设您的团队选择的开发工具如下:

  • 源代码是用 Python 写的。
  • Pycharm 是构建项目的 IDE。
  • 探索性分析在 Jupyter 笔记本上完成。
  • Gitlab 是你的 Git 库平台。

在这篇文章中,我将简要介绍 python 虚拟环境以及如何创建它们。然后,我将解释如何将它们添加为本地 Jupyter 安装的内核。之后,我将定义启动一个项目或使用 Pycharm 从 GitLab 克隆它的步骤。最后,我将描述编写项目依赖项并将其打包的最佳方式。

Python 虚拟环境

python 的虚拟环境是 Python 应用、机器学习和数据科学项目的关键。

虚拟环境是一种工具,它通过使用特定版本的库接口为项目和系统中的其他安装创建一个隔离的环境,来帮助将项目的依赖项与它们分开。

关于详细的介绍和说明,你可以阅读 python 官方文档中的虚拟环境和包的介绍。

因此,我们采取的第一步是用指定版本的 Python 创建一个虚拟环境,并将其作为项目的解释器。

如何创建虚拟环境?

我使用“ conda ”,但是你也可以使用 python 的模块“ venv ”,这两个工具都会创建一个“环境”来隔离软件包安装。

要使用 conda 创建一个新的虚拟 env,请确保您的计算机中已经安装了它,并且 Conda 可执行文件的路径已经添加到您的系统路径中,这样您就可以从命令行访问命令- conda

$ conda -V
conda 4.7.12

如果您可以运行前面的命令并看到安装的版本,那么您可以继续。现在我将用 Python 3.5 创建一个名为“py35-ygroup”的虚拟环境。

$ conda create --no-default-packages -n py35-ygroup python=3.5
...
Proceed ([y]/n)? y
...
Preparing transaction: done
Verifying transaction: done
Executing transaction: done
#
# To activate this environment, use
#
#     $ conda activate py35-ygroup
#
# To deactivate an active environment, use
#
#     $ conda deactivate

就这样,您已经有了一个干净的 python 安装,可以使用了。我将把它作为一个内核添加到一个现有的本地 Jupyter 服务器上,以防你使用 Jupyter 笔记本,然后我将在我们的 IDE 中把它设置为项目的解释器。

将环境添加到 Jupyter 笔记本中

Jupyter 笔记本自动从您的系统中提供 IPython 内核。然而,我想在新环境中使用内核,所以我需要手动注册它。

$ source activate py35-ygroup
# you will see the name of the venv
(py35-ygroup) $ conda install ipykernel
(py35-ygroup) $ python -m ipykernel install --user --name py35-ygroup --display-name "Python3.5 (YGroup)"

如果你有一个 Jupyter 服务器运行,你可以刷新用户界面,当你创建一个新的笔记本时,你应该可以看到环境。

下一步是在 PyCharm 中设置项目和环境。有两种可能的情况:

  1. 开始一个新项目
  2. 从 Gitlab 克隆项目

开始一个新项目

在 PyCharm 中,使用现有环境创建新项目非常简单,一旦打开初始窗口,您将看到选项:

  • +新建项目→项目解释器→现有解释器。

现在,您可以从之前创建的 env 中选择 Python 可执行文件,默认情况下,它应该位于 conda env 的文件夹中(或者 Anaconda,如果您通过它安装了 conda),对于我:"/Anaconda 3/envs/py35-ygroup/bin/Python "

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

adding a virtual environment as the project’s interpreter — PyCharm

现在,您可以开始在您已经创建的环境中工作了。在环境中安装软件包可以通过 conda 或 pip 使用 IDE 中的终端或您系统中的终端(Windows 的 CMD 或 macOS 用户的终端)来完成。确保在安装库之前已经激活了虚拟环境,否则你会将它们安装在你的根或系统 python 中。

注意:不幸的是,当 conda 和 pip 一起使用来创建环境时,可能会出现问题…在 conda 环境中通过 pip 执行安装之前,请确保您阅读了本指南:[在 Conda 环境中使用 Pip](https://www.anaconda.com/using-pip-in-a-conda-environment/),如果您在运行代码时遇到任何问题,这将有助于您了解/修复您已安装的库。

总结和共享您的项目

将库添加到项目中之后,您可以创建包含在另一台机器(比如您同事的计算机)中重新创建环境的信息的 requirements.txtrequirements.yaml 文件。您必须将此文件添加到项目的根目录中;从终端导航到根目录,并运行以下命令:

(py35-ygroup) $ conda env export > requirements.yml

现在您可以保存项目并通过 Git 共享它。我将在下一节讨论在虚拟环境中安装库。

从 Gitlab 克隆项目

在这一部分中,我假设您在 Gitlab 中有一个存储库来托管您的项目,在这种情况下,您可以使用 SSH 或通过 Gitlab.com 的用户/密码验证来克隆项目。我将讨论前一个,但是出于安全原因,最好还是选择第一个选项。这是一个相当快的步骤,作为一个附加说明,你可以随意命名项目,它不一定需要与你的项目在回购中的名称相同,但要使路径不被使用

您需要获得 PyCharm 连接到 Gitlab 所需的插件。转到 IDE 插件并下载以下插件:

安装了它们之后,你应该能够从 IDE 的启动窗口中检查 VS 的项目,点击“git”并提供你的用户名和密码。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Check out from Version Control — PyCharm

您克隆的默认分支应该是主分支。此时,您可以从 IDE 的左下角(或通过终端)更改、签出或创建新的分支,这里重要的部分是现在在本地运行项目。为此,您需要从安装在虚拟环境中的 requirements.txt 或 YAML 文件中获取所有需求,让我们将新创建的虚拟环境定义为项目解释器,然后获取需求。

按照“ 开始一个新项目 的初始指令,得到虚拟 env 作为项目的解释器。完成后,您可以从 IDE 中打开终端并开始安装依赖项。

安装需求

要重新创建虚拟环境,请导航到项目的根目录,需求文件就在那里,然后运行:

(py35-ygroup) $ conda env update --file requirements.yml

在这种情况下,存储库有一个 requirements.txt 文件,您可以使用 pip 安装依赖项,而不是运行您可以运行的前面的命令:

(py35-ygroup) $ pip install -r requirements.txt

此时,您已经准备好继续开发,直到项目准备好被共享,一旦完成,您应该更新需求文件并将变更推送到存储库。

结论

这篇文章中描述的基本步骤将使您和您的团队更容易共享项目,并且在处理分析或数据项目时也是一个很好的实践。至此,您已经学习了如何创建一个新的虚拟环境,如何使用 PyCharm 从 GitLab 克隆一个现有的项目,以及如何通过安装需求文件中包含的库来重新创建虚拟环境。

我希望这篇文章能帮助你下次进入一个新的项目,如果你有任何问题或意见,请在评论区分享,反馈总是受到欢迎:)

全栈数据科学项目

原文:https://towardsdatascience.com/a-full-stack-data-science-project-part-1-9f73a997dc4d?source=collection_archive---------5-----------------------

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Photo by Chris Ried on Unsplash

我涉足数据科学已经有一段时间了——我会从 Kaggle 下载一个数据集,启动一个内核,进行探索性分析,数据清理,使用 sklearn 或 fast.ai 建立一个基线机器学习模型或神经网络,结果只是被工作分散了注意力,暂时失去了兴趣,后来又对不同的比赛或数据集重复相同的过程。

在与一些从业的数据专业人士交谈后,我逐渐意识到,虽然 Kaggle 极具竞争力,并为世界上一些顶级数据科学家的同行提供了无与伦比的学习机会,但 Kaggle 数据集始于数据科学生命周期的中间某个地方——数据收集、解释、清理、屏蔽(去标识)这些平凡但最重要的步骤都已经完成。我想建立一个数据科学项目,整合生命周期的所有方面——数据收集、清理、分析和模型构建。我还希望它能成为我学习数据科学和神经网络不同方面的平台。从而开始寻找一个“好”的数据集。

在一次与工作相关的旅行中,我在机场的一家书店浏览,我想知道是否可以围绕与书籍相关的数据建立一个数据科学项目。从一本书的导语中可以收集到什么信息?还是它的封面?当我仔细考虑这个想法时,我意识到关于一本书的其他信息,如评分、评论、描述等。进行一些实验可能也是有价值的。目标是获得从头构建模型的经验。

我将尝试遵循数据科学项目的标准工作流程,如下图所示。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

经过一番研究后,我决定使用 Goodreads 作为我的数据集的来源,因为他们的书籍页面上的信息量非常全面,而且基本上是标准格式。我决定“收集”以下信息:

  • 标题
  • 描述
  • 作者
  • 版本
  • 格式
  • 国际标准图书编号
  • 页数
  • 评级
  • 评级数量
  • 评论数量
  • 体裁
  • 书籍封面图像

我举了一个 Goodreads 的书籍网页的例子,下面标注了各种信息。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

An annotated image of a Goodreads page, highlighting the fields that will be extracted

在下一节中,我们将详细了解数据收集中涉及的步骤。

1.数据收集

因为我们的目标是为大量的书籍建立一个数据集合,所以我从查看这里的可用书籍列表开始。“有史以来最好的书”列表中有超过 50000 本书,我决定用它作为我的培训数据来源。为了使数据收集更容易,我将这个过程分为三个部分:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

1.1 URL 集合

第一步是通过抓取图书列表来收集单个图书页面的 URL:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

An example of a book “list” to be scraped.

Python 中用来从网页中收集静态数据的最流行和易用的包之一是 BeautifulSoup 。它以 Pythonic 的方式提供了对页面中各种 HTML 元素的访问。如果页面内容是使用 JavaScript 动态生成的,那么 Selenium 将是更好的选择,尽管速度较慢。幸运的是,我们分析所需的所有内容在 Goodreads 网页上都是静态的。

BeautifulSoup 包中最流行和最强大的两个方法是 find 和 find_all。只要我们可以使用标签和类来识别元素,我们就可以使用这两种方法从网页中提取几乎任何信息。我从 web 页面收集数据的方法是开始“检查”包含数据的元素,找出它在 HTML 格式中的结构。例如,在上面显示的列表中,右键单击“动物庄园”标题,然后单击“检查”,显示页面上的图书数据以表格的形式排列,并且在表格数据标签中可用,< td >:

<td width=”100%” valign=”top”>
 <a class=”bookTitle” itemprop=”url” href=”/book/show/7613.Animal_Farm”>
 <span itemprop=”name”>Animal Farm</span>
</a>

因此,通过访问表的每一个行中的标记,我们可以使用几行代码提取 URL:

1.2 数据收集

现在我们已经在 books.csv 文件中收集了 URL,下一步是收集文件中每本书的数据。这将是一个漫长的过程,因为抓取每本书的网页数据会耗费大量时间。我们还应该记住,服务器不应该因为我们的请求而过载,所以我们应该在请求 web 服务器之间留出足够的时间。

与 URL 收集不同,数据收集过程中的每个数据元素在 HTML 网页中都有不同的声明方式。因此,对于每个元素,我们需要弄清楚它是如何构造的,要访问哪个标签和类,以及如何提取数据用于我们的分析。我没有一个一个地遍历这些元素,而是在下表中给出了用于访问它们的 HTML 元素和一个例子。

Data attributes from the book web page and their corresponding HTML tags

用于提取这些数据的代码可在这里获得。

1.3 图像收集

下一步是收集书皮。这相对容易,因为我们已经收集了图书封面的图片 URLs 所需要的只是简单地下载它们。下面是我用 wget 包做同样事情的代码:

我也按照这些步骤收集了 2018 年最佳书籍的数据,这些数据可以在这里的列表中找到。我用这个作为我的测试数据集,来评估我在有史以来最好的书籍上收集的数据上训练的任何模型。

需要注意的一些最佳实践:

  1. 始终确保在向服务器请求之间留出足够的时间,以避免过载和被踢出局
  2. 每隔几次迭代就保存您的工作
  3. 并非所有数据元素在所有网页上都可用,因此在代码中包含检查以解决相同的问题

为了便于加载和使用这两个数据集,我已经将它们上传到 Kaggle。你可以在这里找到他们这里这里。另外,用于数据收集的代码在 GitHub 上,这里是

在下一节中,我们可以在开始进行特定的分类或预测任务之前,研究数据以了解不同的特征。

2.数据探索

探索这些数据的笔记本可以在 GitHub 这里找到。

不管您正在执行的数据分析是什么,也不管您认为自己对数据的了解程度如何,在开始进行特定的预测或分类任务之前,查看数据并了解各种特征始终是一个好主意。让我们先来看看我们收集的数据:

The first 10 rows of the training dataset (Best books ever, from Goodreads)

从数据集的初始视图来看,有几件事很突出:

  • 英语不是唯一的语言——数据集中还有其他语言,这需要探索
  • 一本书可以属于多个流派

让我们先来看看流派。

2.1 流派

我们应该记住,Goodreads 网站上的体裁是由用户提供的,而不是作者或出版商给出的该书的“官方”体裁。这可能导致多种类型的重复或琐碎。让我们先来看看每本书的流派数量分布。

我们可以看到,书籍的平均数量在 5 到 6 本左右,分布有点右偏。下一个问题:有多少独特的流派,哪些是最常出现的?

数据集中有多达 866 个独特的流派!我认为这是因为它们是由用户提供的,并且许多流派可能会重复拼写错误。不管怎样,让我们看看数据集中的热门流派:

即使在前 50 名的榜单中,似乎也有相当长的流派尾巴。有趣的是,与小说(约 26K)相比,非小说类书籍的数量相当低(约 7.5K)。这些类型中的大多数都属于小说类(幻想、浪漫、青少年和不同类型的小说,如科学、历史、女性、现实等)。书的封面反映了一本书被标记的类型吗?让我们检查一下。

2.2 书籍封面

我随机抽取了一些书籍封面样本,并检查了它们所标注的类型:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

据我所知,仅仅从书的封面来分类一本书的类型是很困难的。当然,在某些情况下,我们可能知道作者以前的作品(例如斯蒂芬·金的《恐怖片》),并且可以猜测其类型,但是孤立的书籍封面似乎不能提供足够的信息来确定类型。

经过进一步的研究,我发现这是一篇研究论文的主题,题为“通过封面来判断一本书”,可在此处获得。该论文的作者在他们的任务中确实取得了一些成功,但是指出:

许多书的封面图像具有很少的视觉特征或模糊的特征,导致许多不正确的预测。在揭示 CNN 发现的一些设计规则时,我们发现书籍也可能有误导性的封面。此外,因为书籍可以是多种体裁的一部分,CNN 在榜首的表现很差。

了解到目前为止我们收集的关于书籍封面的信息,它们可能不会成为我们分析的一部分。让我们继续讨论下一个参数:语言。

2.3 语言

我们对数据集的初步了解告诉我们,我们的列表中包含了一些非英语书籍。让我们看看数据集中所有可用的不同语言。

langdetect 包帮助找出一段给定文本的语言。这对于通过使用图书的描述(代码如下)来确定数据集中可用的图书的不同语言非常有用:

绘制每种语言的图书数量,我们可以看到几乎 90%的图书是英文的:

出于我们的分析目的,我们可以删除对应于非英语书的记录。然而,出于好奇,让我们检查一下数据集中非英语书籍的数量:

相当多的欧洲语言出现在这个列表中。我也对这里有相当多的印度语言这一事实感兴趣。来自印度钦奈,我想知道哪些泰米尔书籍是有史以来最好的书籍的一部分:

Ponniyin Selvan ,被认为是有史以来最伟大的泰米尔小说,出现在这个名单上!很高兴知道:)

后续步骤

探索这些数据帮助我们认识到,试图从书籍封面预测流派可能不是一个很有成效的练习(我也可能是错的!).我会试着用这本书的描述来预测流派。这可能是一个相当琐碎的任务,但它肯定会有助于理解如何从头构建一个递归神经网络,并为其准备数据。关于流派另一个需要注意的点是,独特流派的大量存在使得它成为一个非常难以预测的目标参数。通过对数据进行相应的预处理,将一本书分类为小说或非小说是有意义的。我将在接下来的小节中介绍这些步骤。

3.数据清理

尽管 Goodreads 上可用的数据在很大程度上是结构化和格式化的,但数据集仍有一些问题需要解决。因为我们分析的感兴趣的数据是书的描述和相关的类型,这些是我遇到的问题:

  • 有些唱片没有任何流派
  • 一些记录没有有效的描述
  • 一些唱片的标签类型列表中既没有“小说”也没有“非小说”
  • 正如我们前面看到的,一些记录有非英语的描述
  • 一些图书描述有不可打印的字符和格式问题

发现这些问题需要反复试验,尤其是格式问题,需要仔细检查描述本身。尽管如此,我还是为上面提到的每个步骤编写了助手函数,并通过训练和测试数据集运行它们:

似乎有相当数量的唱片被丢弃了,因为它们被贴上了既非小说也非非小说的标签。当我检查这些记录时,我发现要么是因为用户没有给它们加标签,标签就不见了,要么是因为它们属于中性类别,比如诗歌等等。

4.数据预处理

既然我们已经处理了数据中尽可能多的问题,我们应该准备好将数据输入到模型中。实现这一点的第一步是确保所有输入模型的数据都是相同的格式和长度。自然,所有书籍的描述都有不同的长度。我们如何确定输入神经网络模型的描述的最佳长度?

4.1 剪辑和填充

我将假设,如果我们能够在一定长度(即字数)内容纳至少 80%的图书描述,那么我们的模型应该表现得相当好。为了确定这个长度,让我们绘制一个训练数据集中描述长度的累积直方图:

如果你将鼠标悬停在上图中的条柱上,你可以观察到大约 80%的记录字数在 207 字以下。让我们把最大阈值字数定为 200。这是什么意思?这意味着对于描述少于 200 个单词的记录,我们将用空值填充它们,而对于描述多于 200 个单词的记录,我们将对它们进行裁剪,只包含前 200 个单词。除了最大阈值,我们还需要一个最小阈值来确保描述至少有几个词来实际预测流派。

4.2 标记化

与递归神经网络相关的标记化是指将事物序列(无论是字符还是单词)转换为整数序列的过程。这仅仅意味着,对于我们跨训练和测试数据集的描述语料库中的每个单词,我们分配一个整数,我们将称之为“令牌”。因此,神经网络的输入将是代表形成描述的单词的符号序列。

Keras ,由Fran ois Chollet开发的令人敬畏的深度学习库,有一个预定义的方法来标记序列。然而,我想自己构建标记化器只是为了好玩。标记化的第一步是建立描述中所有可用单词的词汇表。一旦这个词汇表可用,分配标记就是一个简单的任务,即引用词汇表中单词的索引。在标记化的过程中,我们还可以进行之前看到的裁剪和填充。关于填充,有几点需要注意:

  • 因为我们将使用整数零进行填充,所以在词汇表中不要给这个令牌分配任何单词是很重要的。
  • 递归神经网络将从左到右阅读令牌序列,并输出一个预测,判断该书是小说还是非小说。这些标记的内存被一个接一个地传递给最终的标记,因此,对序列进行预填充而不是后填充是很重要的。这意味着零添加在令牌序列之前,而不是之后。存在后填充可能更有效的情况,例如在双向网络中。

下面给出了我用来将描述标记成固定长度的整数序列的代码。

4.3 训练和验证数据集

虽然创建训练和验证集是一个相当标准的过程,但当数据集不平衡时,即目标变量的分布不均匀时,我们应该确保训练-验证分裂是分层的。这确保了目标变量的分布在训练和验证数据集中得到保留。

5.模型开发

下一步是建立一个递归神经网络来处理符号化的描述,并将它们分类为小说或非小说。为此,我使用 Keras 库构建了一个顺序模型。Keras 是目前可用于神经网络开发的最佳 API 之一,尤其以其用户友好性和易于理解的结构而闻名。

我在顺序模型中使用的层如下(按此顺序):

5.1 嵌入

在我们进入嵌入层的细节之前,让我们看看为什么它在这种情况下是有用的。我们前面看到,我们构建了描述中所有可用单词的词汇表,并将描述转换为标记序列(整数)。现在,这些整数不能以原始形式传递给神经网络,因为这些整数的大小实际上没有任何意义。例如,对应于令牌 1 的单词是“gremlin ”,而令牌 2 的单词是“collaborated”。这并不意味着“合作”是“小淘气”的两倍。那么,我们该怎么处理呢?

这种变量称为分类变量,通常通过一键编码传递到机器学习模型中。例如,如果我们的词汇表中有 5 个单词,我们将它们标记如下:

[outbound, hearse, select, dogged, rowboats][1, 2, 3, 4, 5]

其中出站对应 1,灵车对应 2,以此类推。这种标记化表示的独热编码版本应该是:

outbound: [1, 0, 0, 0, 0]hearse: [0, 1, 0, 0, 0]select: [0, 0, 1, 0, 0]dogged: [0, 0, 0, 1, 0]rowboats: [0, 0, 0, 0, 1]

因此,每个单词都由一个向量来表示,向量的长度是词汇表中单词的总数。如果类别的数量很少,这种分类变量的表示很有效。在我们的例子中,类别的数量实际上是我们的词汇中独特单词的数量,超过 90000 个。如果我在数据集中的每条记录中有 200 个单词,这意味着我的数据集变成了一个 n90000200 张量,其中 n 是记录的总数。当有太多类别时,独热编码的另一个问题是表示变得太稀疏,即,与矩阵中的 1 相比,有太多的 0。一些算法可能不能很好地处理稀疏表示。因此,我们需要一种替代的方式来表示我们的输入。这就是嵌入的用武之地。

简单地说,嵌入层“学习”每个输入类别的固定长度数字表示。嵌入向量的长度可以由用户决定。一般来说,更长的嵌入能够学习更复杂的表示。在我们上面看到的例子中,假设我们训练长度为 10 的嵌入层,训练后得到的嵌入向量可能如下所示:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

因此,如果我们训练一个长度为 200 的嵌入层来表示我们的词汇,该层有效地将输入的维数从 n90000200 减少到 n200200。这使得计算变得容易得多,我们的表现也更加密集。

5.2 叠 LSTM

我们模型的下一层是递归神经网络的核心——LSTM(长短期记忆)层。简而言之,无论序列有多长,LSTM 层通常都会保留记忆。它能记住多少是基于输入序列和目标变量之间的关系来学习的。在我们的例子中,我们将长度为 200 的序列传递给 LSTM 层。在序列中的每个字处,LSTM 层产生一个输出状态,该输出状态被传递到下一个字,并且如果需要的话,可选地产生一个隐藏状态,该隐藏状态被传递到另一个 LSTM 层。起初我发现 LSTM 的概念非常复杂,但是克里斯多夫·奥拉的这篇文章很好地解释了这个概念:

[## 了解 LSTM 网络——colah 的博客

这些循环使得循环神经网络看起来有点神秘。然而,如果你想得更多一点,事实证明…

colah.github.io](http://colah.github.io/posts/2015-08-Understanding-LSTMs/)

在我们的例子中,我使用了一个两层 LSTM,其中第一层产生一个隐藏状态序列,该序列被传递到第二层。

5.3 完全连接

全连接(也称为“密集”)层获取 LSTM 层的输出,并通过 sigmoid 激活将输入压缩为 0 到 1 之间的数字,将其映射到单个目标变量。

为了更好地理解,下面给出了网络架构的直观表示:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

下面给出了创建顺序模型的代码。

Keras 给出的模型摘要:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

6.模型评估

最后一步是训练我们的模型,根据验证集进行评估,并用我们的测试数据集进行测试。该模式能够在具有 2 个时期的训练的验证集上实现超过 90%的准确度,并且在测试数据集上实现大约 95%的准确度。

Train on 23393 samples, validate on 5848 samples 
Epoch 1/2 23393/23393 [==============================] — 162s 7ms/step — loss: 0.3532 — acc: 0.8542 — val_loss: 0.3033 — val_acc: 0.9020 
Epoch 2/2 23393/23393 [==============================] — 160s 7ms/step — loss: 0.1660 — acc: 0.9393 — val_loss: 0.2347 — val_acc: 0.9152 
657/657 [==============================] — 13s 19ms/step
[0.14756220990516913, 0.9482496194824962]

结论

所有用于数据收集、探索和模型开发的代码都可以在 GitHub 上找到,网址是:

[## meet naren/Goodreads-图书-分析

根据简介或描述将一本书分类为小说或非小说的数据科学项目…

github.com](https://github.com/meetnaren/Goodreads-book-analysis)

我还尝试在 PyTorch 这里复制模型开发。PyTorch 可以更好地控制数据如何进入网络,并允许我们定义构成网络转发的操作。对于像本文中描述的简单序列模型,Keras 是一个很好的选择。

一个全职 ML 角色,100 万博客浏览量,10k 播客下载量:一个社区教授 ML 工程师

原文:https://towardsdatascience.com/a-full-time-ml-role-1-million-blog-views-10k-podcast-downloads-a-community-taught-ml-engineer-96f99b91c5ee?source=collection_archive---------14-----------------------

快速回顾一个社区教授 ML 工程师的旅程。

里程碑和全职工作

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

2019 年 10 月 15 日标志着一个特殊的里程碑,实际上是相当多的里程碑。所以我考虑以博客的形式分享它,在一个出版物上,这是我所有帖子的家:)(注意:这最初是在 HackerNoon 上发布的)

网络社区对我太好了,这些博客帖子成了我和那些我通过 slack 小组认识的了不起的人庆祝任何或大或小的成就的一种方式:KaggleNoobs,ODS。AI、TWiMLAI、数据科学网、fast.ai 论坛甚至 Twitter 以及分享我的失败,未经过滤,尽管用手挠我的后脑勺,但这个令人惊叹的社区仍然对我太好了,即使在我失败了我最大的一次梦想面试时。

因此,如果我不分享我最终在“人工智能”领域的领导者之一获得了一个惊人的全职机会,这将是很不礼貌的。公司肯定不需要介绍了,这里就略过赞了。

在我写这篇文章的时候,我将开始在 H2O.ai 做一名全职的机器学习工程师和 AI 内容创作者。尽管全职工作是我一直向往的,但我还是很难接受这个事实。另外,鉴于我的博客帖子以及柴时间播客所取得的一些其他里程碑式的成就,我真的很兴奋,也非常感谢 ML 在线社区,它一直对我非常热情和友好。

我想这篇文章也可以让我快速回顾一下我的旅程,正如你可能知道的,我一直乐于通过这篇博客公开记录我的失败和成功,目的是留下一个公开的旅程记录,这样任何和我处于类似情况的人都可以从这些文章中受益,不会重复我的错误。

里程碑之前的旅程:)

旅程

在我的前一篇标志着几个里程碑的帖子中,我已经与谷歌人工智能驻地的分享了我的拒绝,但甚至在那之前,当我去互联网上寻找更多有趣的想法和“最新”的大学学习主题时,我的旅程才真正开始。我想,要么我可以抱怨大学教学大纲太过时,与行业不同步,要么我可以出去搞清楚这个行业实际上是什么,什么是“机器学习”,什么是“模型”。你可以想象这个列表。

我参加了网上课程,在我还在上大学的时候就参加了相当多的网上课程。然后在 9 月 29 日。我从地球的另一边收到了这封邮件,我记得我在凌晨 4 点读了它(是的,我醒得很早,然后我做的第一件事就是有时读邮件)

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

这一直是我最亲爱的“证书”有趣的事实,在“柴时间数据科学”工作室:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

这是现存的唯一一份装裱好的打印件。虽然我不确定它是否会出现在那里的 RGB 娱乐中。

这让我进入了另一个探索周期,因为杰里米是我遇到的最好的教授。我结束了花大量时间“观看”课程的生活。回想起来,这些钱应该花在编码和“训练大量模型”上(杰里米的顶级建议,来自 Lex Fridman 的《神奇的人工智能》播客)

与此同时,我鼓起勇气访问了 kaggle dot com(我想强调一下 dot,听起来更好,不是吗?)有一两次,我确信我应该投资一台“DL 笔记本电脑”(因为我还在上大学,所以不可能买盒子)。这本身就导致了论坛上一长串的讨论我终于在 2018 年底开始使用 Kaggle。此外,我需要一大笔钱来买笔记本电脑,所以我又开始上网,因为我还有一年的大学时间,我不能在大学期间做“工作”。我的“自由职业者”/合同工就是这样开始的。

新年伊始,我收到了一封来自谷歌的邮件,让我大吃一惊。我进入了人工智能住院医师面试的最后一轮,然后被拒绝了。当这封信送达时,我已经勾掉了我的几个“2019 年决心”。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

  • 成为 Kaggle 专家
  • 创建一个好的 Kaggle 内核
  • 每周写一篇博客:)
  • 实现一些文件。

所以我决定花些时间在社区里,心中没有最终目标。我真的想回馈社区,因为我已经大学毕业,我有时间和许多了不起的人交谈,并通过 slack 提供帮助,主持学习小组甚至研讨会。

第一份“远程工作”,社区活动

到了四月底,我有了一次惊人的求职面试经历。

我通过他们的社区工作认识了一个了不起的人: Aakash N S 发布了他们公司的一个职位。于是我 pinged 了他们,有了最酷的面试体验。一个 45 分钟的视频电话,而不是一个关于责任和我的长期目标的友好讨论。下一个电话是入职电话。

等等,让我理解一下。

我提到那个 fast.ai 社区就是这个意思,真的很神奇。由两位 fast.ai 研究员( Aakash N SSiddhant Ujjain )创建的一家公司在另一个城市遇到了另一位 fast.ai 研究员,经过一场小讨论后,他们邀请他在同一个团队工作。多牛逼啊!

该公司名为 Jovian.ml,真正建立在几个 fast.ai 哲学之上,这确实是一个天然的契合点,但创始团队的社区努力和 kaggle 的目标确实与我和整个董事会相呼应。因此,团队让我远程兼职工作,这样我也可以在 Kaggle 和社区工作上分配时间。

我最自豪的时刻之一是为印度最大的社区之一:数据科学网络做出了贡献,并组织了印度最大的 KaggleDaysMeetup 之一。

博客

fast.ai 最令人惊讶的一个方面是强调将博客作为投资组合或项目建设练习。整个社区甚至杰瑞米·霍华德本人都非常强调博客,这就是我开始写博客的原因。

有一次,我邀请了我的几个朋友: Dominic MonnTuatini GODARD 采访他们的旅程,因为他们两人在回答我的愚蠢问题时给了我很大的帮助,他们的旅程对我很有启发。这些采访很受社区欢迎,所以接下来我来到了一个十字路口:

要么我继续尝试技术文章,解释 CNN、LSTM、Transformer 等概念。或者真正专注于分享这些采访,因为我觉得这是社区中真正缺失的。所以我选择把创建教程和帖子的工作留给比我更聪明更有智慧的人,比如“4 分钟 PyTorch 基础知识”,并接触了大量我真正钦佩的“机器学习英雄”。

我仍然不相信是怎么回事,但这导致了 25 次博客采访。

尽管这很可怕,因为我正稍微远离分享工程和代码遍历,这是对我的期望,对于我渴望的数据科学和 ML 的角色,但我仍然坚持采访系列。

现在我已经毕业,找到了更多的带宽,我决定重新开始这个系列,但这次是以播客的形式:视频、音频和博客格式。

我想澄清一点,我从来没有将这些帖子货币化,我也从来没有打算这样做,我也没有期望柴时间数据科学播客是一个“商业”,它对我来说是一个新的媒介,作为一个媒介(太元了,不是吗?)通过 3 种不同的格式分享这些故事,以真正允许社区所有选项来消费这些“我的机器学习英雄”的惊人故事

柴时间数据科学播客

再次与播客,我在一个有趣的十字路口,我选择发布视频,音频采访,处理编辑(最费力的任务),采访和发布。

因为我真的很喜欢这些面试,所以我选择通过终止一些自由职业者的合同/协议来腾出时间,并决定在几个月内放弃 90%的收入,专注于让这些令人惊叹的旅程变得更容易实现。我真的很感谢木星的团队,让我继续播客,同时也在为“木星”工作。事实上,Aakash 还好心地设置了一个 Zoom 账户,通过这个账户进行采访。没有这一点,就不会有第一批采访或电话。

我真的很享受这个过程,现在能够和我的 ML 英雄们聊上一两个小时。播客电话真的是我做过的最好的活动之一。尽管这也让我在 Kaggle 竞赛和练习更多编码之间做了一个权衡,但我还是设法每天挤出几个小时来练习编码。我想我真的坚持了蒂姆·德特默给应届毕业生的建议:“你有时间。放轻松,享受过程,享受学习。总有一天,你的任务会变得重复,所以慢慢来,理解你的激情。我真的很高兴我做到了:)

里程碑

我真的想分享三个里程碑,几个我从未真正期望会发生的点:

我的博客点击量达到了 100 万次。

对,100 万!想象一下,开始一个在线课程建议的活动,一个在线社区教你的活动,然后能够与这么多人分享!

我非常感谢 Hackernoon 热情地接受了我的所有采访和所有帖子,也感谢 David(Hackernoon 的首席执行官)在我试验性帖子的最初几天给了我很多反馈。

我不会分享任何写博客的建议,而是分享我用过的最好的一个。

这是我每篇文章的指导方针。

我也非常感谢每一个阅读我的帖子的人,特别是那些“机器学习英雄”,他们友好地与一个刚刚开始旅程的新手分享了他们的旅程。

10k 播客下载

柴时间数据科学上线 1.5 个月后下载量达到 10k!我不是一个播客,也不是一个好的统计人员,但这对我来说是一个巨大的数字,我真的很高兴播客作为一种媒体达到了很多观众,并分享了这些伟大的故事,建议。我希望继续保持我带来的疯狂的发布时间表。

另一个疯狂的事实,柴时间数据科学,在写作的时候,已经流过 80 个国家。什么!?

我真的很喜欢互联网(或者只是它上面的 ML 社区:)

Fast.ai

我把旅途中最精彩的部分留到了最后一节。😃

在我上面提到的所有统计数据中,这可能是我最自豪的一个,甚至可能超过我的 Kaggle 等级(也许)(尽管我想完全指出,所有的 Kaggle“奖牌”或“等级”都是由于我在一个团队中有机会遇到和工作令人惊讶的 kagglers,所以如果没有我有机会与之合作的令人惊讶的人,我完全不可能实现它们。我不是一个聪明的 kaggler,我也不会假装聪明,但我绝对相信 Kaggle 是一个很好的学习平台,也是数据科学的真正家园,我认为我不能再强调这一点了)

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

亲爱的 fast.ai 团队:杰瑞米·霍华德瑞秋·托马斯和西尔万·古格,还有 fast.ai 一家,(这是一个我喜欢称之为家庭的在线社区)。自学或社区教育的一个方面是,我的教育只能和社区的资源和建议一样好。

在我之前的帖子中,我并没有很不幸地真正感谢 fast.ai 团队,但最终得到了一份梦寐以求的工作,这是我做梦都不敢想的(又太元了?)我想我终于可以把我的成就归功于 fast.ai 课程、图书馆和社区了。

我学到的很多东西:在 kaggle 上竞争、博客、软件工程和深度学习,甚至是一些小事情,比如如何阅读论文、如何筛选数学方程,不要迷失在希腊语中,而是找出代码。我能够做的这些事情,在某种程度上或者更大程度上,都要归功于我通过 fast.ai 体验获得的曝光率。我承认我可能不是最好的学生,因为我还没有完成 swift for TF 课程,尽管我已经在 swift 上写了几篇博文,我还没有观看 V2 演练,所以我可能不是 fast.ai 全球课堂上最真诚的学生。然而,我真的真的很感谢杰瑞米·霍华德、瑞秋·托马斯、西尔万·古格和所有我在论坛上认识的了不起的人。

我还想指出的是,像 Kaggle 这样的东西在课程中被轻描淡写地强调了,所以它不是我提到的所有上述要点的必经之路,你可能还需要做功课。但正如他们所说,核能是由铀产生的,而不是发生的副产品,我认为 fast.ai 是这种连锁反应的铀,如果你正确地遵循,你可能会获得惊人的结果!😃

然而,如果我没有加入 KaggleNoobs 社区、DSNet、ODS,这对我来说是不可能的。AI 和 TWiMLAI 也是。所有这些对我来说都是一个惊人的学习点,尽管我没有参与太多的对话或最新的论文讨论,因为我已经承诺了播客的发布时间表。然而,我真的很感激这些社区和他们中的每个人对我的欢迎。(同样,我是通过 fast.ai 论坛发现这些的:)

最后,我要提到,当我说“在线或社区或自学”(我更喜欢这三个词之外的社区教育)时,我确实遵循并追求了传统的 CS 本科学位,我所有的在线学习都是从那里开始的。但是,我对机器学习世界的了解(非常少)真正归功于在线资源。我只从事我真正喜欢教学大纲的大学课程,并真正浏览了其他课程,我不知道为什么,但我确实获得了“IET 奖”,正如他们所说,“这是由大学提供给他们最优秀的学生的”。我给大学里任何人的唯一建议是,追随你的激情,不要害怕寻求帮助,无论是在线还是离线。

我在机器学习旅程中的下一个角色和下一部分

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

从页面https://www.h2o.ai/team

我非常幸运,也非常兴奋能够在 H2O.AI 开始全职担任“机器学习工程师和人工智能内容创作者”。

这绝不是将我归类为专家,该公司本身就是许多令人惊叹的 kagglers 和世界顶级数据科学家的家园,我对我旅程的下一部分感到非常兴奋,并准备了解更多。

多亏了互联网, fast.ai 和在线 ML 社区定义了我的道路,并特别感谢我的父母,他们同意了这个完全疯狂的计划,甚至在播客最初增长缓慢时支持了我,或帮助我开始使用我的第一个 GPU,甚至在我选择退出大学校园实习时更早,因为他们大多数人都是全栈角色,我真的想转而 Kaggle(对任何竞争数据都没有经验 科学竞赛)并花时间学习在线课程,尽管这个计划听起来很疯狂(我的父母支付了我的大学费用,甚至是我追求的在线课程),但我的父母一直是最支持的。 我的母亲更是如此,她总是忍受着一个儿子,他经常在一个房间里呆上几天,在一个产生高电气噪音的 GPU 环境中喝下数不尽的茶。

我将继续通过 Hackernoon(和 Medium)的博客分享我的旅程,不加过滤,定期发布。感谢所有和我一起经历这个奇妙旅程的人。

你可以在推特上找到我@ bhutanisanyam 1

订阅我的时事通讯,获取深度学习和计算机视觉阅读的每周精选列表

10 分钟内一个功能齐全的聊天机器人

原文:https://towardsdatascience.com/a-fully-functional-chatbot-in-10-mins-8ecd69dff789?source=collection_archive---------23-----------------------

聊天机器人很酷,没有什么比在 10 分钟内制作一个聊天机器人更令人满意的了。我们也对最佳实践感到非常兴奋。因此,尽管这篇文章是针对第一次构建聊天机器人的人,但即使是有经验的开发人员也会带回家一些好东西。就这样,让我们以菜谱的方式进行构建…

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Sanbot King Kong for hospitality By QIHAN Technology — Own, CC0, https://en.wikipedia.org/w/index.php?curid=55094935

— — — — 如何制作聊天机器人 — — —

先决条件:

你肯定需要一个烤箱,在这种情况下,这是你的 Azure 订阅(https://azure.microsoft.com/en-us/free/)

配料:

  1. 写 Python 代码的地方。我正在使用 Visual Studio 代码(https://code.visualstudio.com/)看看 Visual Studio 安装和入门的评论部分。

2.Azure 中的 QnA Maker 服务

3.Azure Bot 服务版本 4

说明:

步骤 1: 让我们为 python 设置虚拟环境。python 虚拟环境只是一个自包含目录,其中包含特定版本的 python 安装和项目/程序/模块所需的相关库。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Python Virtual Env set up in VS Code

#命令:

#来自项目根文件夹

mkdir 虚拟 _ 环境

光盘。\虚拟环境\

python -m venv 聊天机器人 _env

set-execution policy-Scope Process-execution policy Bypass(特定于 Windows 的命令)

。\ chatbot _ env \脚本\激活

第二步:接下来,我们需要建立 QnA Maker 服务。QnA Maker 是一个基于云的 API 服务,在您的数据上创建一个对话、问答层[1]。

QnA Maker 使您能够根据半结构化内容(如常见问题解答(FAQ)URL、产品手册、支持文档和自定义问答)创建知识库(KB)。QnA Maker 服务通过将用户的自然语言问题与知识库中 QnA 的最佳答案进行匹配,来回答用户的自然语言问题。逐步指南可参考以下文件:

[## 设置 QnA Maker 服务— QnA Maker — Azure 认知服务

在创建任何 QnA Maker 知识库之前,您必须首先在 Azure 中设置 QnA Maker 服务。任何人有…

docs.microsoft.com](https://docs.microsoft.com/en-us/azure/cognitive-services/QnAMaker/how-to/set-up-qnamaker-service-azure) 外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

create a QnA Maker service from Azure Portal

提示:为这个项目创建一个资源组[2],并将与本练习相关的所有内容放入其中,这样您就可以从资源组管理与这个项目相关的所有内容。

您还可以使用 azure 资源管理器模板(JSON 格式的)[3]来自动化部署。

部署完成后,您将能够看到 Azure 为您创建所需的资源。平台即服务不是很有魅力吗?

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

QnA Maker Deployment Summary from Azure Portal

第三步:现在我们需要建立知识库。QnA Maker 知识库[4]由一组问题/答案(QnA)对和与每个 QnA 对相关联的可选元数据组成。

关键知识库概念:

问题:问题包含最能代表用户查询的文本。

答案:答案是当用户查询与相关问题匹配时返回的响应。

元数据:元数据是与 QnA 对相关联的标记,表示为键值对。元数据标签用于过滤 QnA 对,并限制执行查询匹配的集合。

您可以根据自己的内容(如常见问题解答或产品手册)创建 QnA Maker 知识库(KB)。

在这里,我将使用 https://azure.microsoft.com/en-us/free/free-account-faq/的来构建一个聊天机器人。

使用您的 Azure 凭据登录qnamaker . ai门户,然后按照下面文档中的逐步指导进行操作:

[## 创建、培训和发布知识库— QnA Maker — Azure 认知服务

您可以根据自己的内容(如常见问题解答或产品手册)创建 QnA Maker 知识库(KB)。QnA 制造商…

docs.microsoft.com](https://docs.microsoft.com/en-us/azure/cognitive-services/QnAMaker/quickstarts/create-publish-knowledge-base) 外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

QnAMaker.ai portal

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

QnAMaker.ai portal create knowledge base step 1

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

QnAMaker.ai portal create knowledge base step 1_1

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

QnAMaker.ai portal create knowledge base step 1_2

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

QnAMaker.ai portal create knowledge base step 1_3

我们有一个包含 101 个 QnA 对的初始知识库,需要保存和训练。当然,我们可以修改和调整它,使它更酷。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

QnAMaker.ai portal create knowledge base step 2

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

QnAMaker.ai portal create knowledge base step 2_1-> Save and Train

一旦我们完成了培训,就该测试QnA 制造商了。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

QnAMaker.ai portal create knowledge base step 3_1-> Test

我们还可以检查测试响应,选择最佳答案或添加备选措辞进行微调。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

QnAMaker.ai portal create knowledge base step 3_2-> Inspect Test results

现在是时候发布知识库了。您需要从门户网站中点击“发布”选项卡。

当您发布知识库时,知识库的问题和答案内容会从测试索引移动到 Azure search 中的生产索引。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

QnAMaker.ai portal create knowledge base step 4_1-> Publish

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

QnAMaker.ai portal create knowledge base step 4_2-> Publish wait for completion

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

QnAMaker.ai portal create knowledge base step 4_3-> Service deployed/published

在我们继续创建聊天机器人之前,让我们接下来以编程方式调用 qnamaker。

**Python 程序调用并测试 qnamaker。**代码出现在这里:https://github.com/RajdeepBiswas/Ten_Minute_ChatBot_Python,解释和设置过程起草如下,作为主要文章步骤的一部分。

第 4 步:密钥、密码和秘密不能在众目睽睽之下…让我们建立一个配置文件来保存我们的 python 项目的秘密和密钥。

我们将从 qnamaker.ai 服务发布页面的 curl 部分获取值。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Get the config values from QnAMaker.ai portal

根据上面的值设置 config.py 文件。不要忘记放置 init。py 使配置文件可调用😊

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

config.py file to store the secrets

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

init.py file to make the config referable

现在,我们已经做好了配置准备。

提示:不要忘记将 config.py 包含到。gitignore 如果你想把代码放到 github 里。

文件可在以下位置找到:

[## RajdeepBiswas/Ten _ Minute _ ChatBot _ Python

在 GitHub 上创建一个账号,为 RajdeepBiswas/Ten _ Minute _ ChatBot _ Python 开发做贡献。

github.com](https://github.com/RajdeepBiswas/Ten_Minute_ChatBot_Python/tree/master/secret_keys)

第五步:现在我们需要编写客户端 python 程序。这里用到的程序可以在 github 中找到:https://github . com/RajdeepBiswas/Ten _ Minute _ ChatBot _ Python/blob/master/call _ qna . py

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Call QnA maker from python code

第六步:终于到了创建聊天机器人的时候了……哇呜!!!

QnAMaker.ai 门户的服务部署页面点击创建聊天机器人。这一步将把您重定向到 Azure 门户,您需要在那里创建 Bot 服务。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Create bot from QnAMaker.ai portal

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Azure portal create bot service

如果存在资源提供者注册错误,可以通过多种方式解决。

这里,我在 Azure cli 中使用了以下命令:

az 提供者注册—微软命名空间。僵尸服务

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

create bot error resolution

有关更多信息,请参考:https://docs . Microsoft . com/en-us/azure/azure-resource-manager/resource-manager-register-provider-errors

然后刷新 Azure 门户页面以创建聊天机器人:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Azure portal create bot service

点击“创建”后,将会有一个自动验证步骤,然后将会部署您的资源。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Bot service deployment

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Bot service deployed

部署完成后,转到 azure portal 中的 webapp bot。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Web App Bot

现在,让我们在网络聊天中测试我们的机器人:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Test in Web Chat

**奖励环节:**你可以把你的机器人连接到不同的频道。

通道是机器人和通信应用程序之间的连接。您可以配置一个 bot 来连接到您希望它可用的频道。通过 Azure 门户配置的 bot 框架服务将您的 bot 连接到这些通道,并促进您的 Bot 和用户之间的通信。你可以连接到许多流行的服务,如 Cortana,Facebook Messenger,Kik,Skype,脸书,Telegram,Twilio,Slack 以及其他一些服务。网络聊天频道是为您预先配置的。更多信息可以在这里找到:https://docs . Microsoft . com/en-us/azure/bot-service/bot-service-manage-channels?view=azure-bot-service-4.0

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Connect bot to channels

如果你已经成功地做到了这一步,我肯定会认为你未来探索人工智能机器人开发的旅程将会更有收获,更顺利。请让我知道你的任何问题或意见。

参考文献

[1]

“QnAMaker”,2019 年 4 月 4 日。【在线】。可用:https://docs . Microsoft . com/en-us/azure/cognitive-services/qna maker/overview/overview。

[2]

“资源组”,[在线]。可用:https://docs . Microsoft . com/en-us/azure/azure-resource-manager/resource-group-overview # resource-groups。

[3]

“模板-部署”,[在线]。可用:https://docs . Microsoft . com/en-us/azure/azure-resource-manager/resource-group-overview # template-deployment。

[4]

“知识库”,2019 年 6 月 4 日。【在线】。可用:https://docs . Microsoft . com/en-us/azure/cognitive-services/qna maker/concepts/knowledge-base。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值