TowardsDataScience-博客中文翻译-2016-2018-八-

TowardsDataScience 博客中文翻译 2016~2018(八)

原文:TowardsDataScience Blog

协议:CC BY-NC-SA 4.0

用张量流计算 D&D 损伤

原文:https://towardsdatascience.com/calculating-d-d-damage-with-tensorflow-88db84604f0a?source=collection_archive---------7-----------------------

在过去的几天里,我一直在头脑风暴关于数据科学技术的博客主题,我没有写太多。然后我想起来,我实际上还没有使用 Tensorflow 的对象检测库做多类模型的帖子。一旦技术想法确定下来,我只需要决定一个应用它的主题。

我在看我最喜欢的每周 D&D 秀《关键角色》的时候想到了一个有趣的点子。《关键角色》是一部由一群书呆子配音演员聚在一起扮演 D & D 的电视剧,自 2015 年开播以来,我一直在关注它。这也启发了我在地下城主屏幕的两边玩几个战役。无论如何,下面是我对这篇文章想法的总结。

无论你是一个名叫瓦克斯·伊尔丹的半精灵盗贼,在一次偷袭中对煤渣之王索达造成 118 点伤害,还是在九头蛇吃掉你的队伍之前砍倒它来拯救队伍,D&D 都会在伤害计算中加入大量的骰子。如果你像我一样,实际上不喜欢数它们…为什么不让神经网络来帮你数呢?!?

首先,不,我不想只是使用电子掷骰子机,因为我真的很喜欢掷骰子…这就像用电子掷骰子机玩骰子一样…只是感觉不对…建立一个模型来总结骰子对我来说似乎是一个很好的妥协,正如他们所说的那样,懒惰刺激创新。

这是一个我可以用多种方式解决的问题。我最初想到的方法是以两个阶段的方式构建它,其中第一个模型只提取给定骰子的顶面,而第二个阶段对数字进行分类。然而,这实际上并不涉及我想为帖子构建的多类检测器。因此,我最终做的是测试一个更快的 R-CNN 模型如何处理一个定制的多类问题,我在 6、8、10 和 12 面骰子上跟踪骰子 1-12 的数字。我将在后面讨论当前模型的缺点时谈到这些权衡。大多数问题都是以处理骰子旋转变化的形式出现的。

我没有包括所有重要的 D20 的原因是,你通常只是一次滚动一个 20 面骰子,我没有包括 4 面骰子的原因是,我只有菱角/金字塔形状的 4 面骰子,所以我不能从顶部读取它们。我需要得到一个不同形状的 4 面模具来测试,我不想等待建立模型。

链接到完整的 github 回购这里

This problem is made a bit trickier for an object detection model because the dice can take on any orientation, with a standard CNN I could probably just train a 12 class model with a lot of data augmentation. For this object detection model I just add more data

D&D 骰子

这只是对 D&D 中使用的不同骰子的一个快速概述。

左后方的金字塔形骰子是一个四面的骰子,通常形状像金字塔,如果你踩上去会像菱角一样疼。它的右边是一个 12 面骰子,每个面是一个五边形。中间的是 20 面骰子,除了 D&D 中的伤害外,还用于其他掷骰。中间的左边是标准的 6 面骰子。中间的右边是一个 8 面骰子,是两个相互堆叠的金字塔。前面的两个骰子是 10 面骰子的两个版本,一个显示 0-9 的值,另一个以 10 为增量显示 10-90。另一个变化是,模型需要考虑 0 和 10 都是 10。D10 有两种格式,因为它们偶尔用于滚动百分点。所以你可以想象,非标准六面骰子的使用给这个问题增加了一点复杂性,使得分析变得愉快。

Etsy metal dice set. (left to right) back: d4, d12, middle: d6, d20, d8, front: d10, d10

现在,让我们言归正传。

数据收集和注释

为此,我需要一个相当大的数据集骰子。我可能只是从互联网上抓取图像,但对于这个用例,我的想法是我可以安装一个网络摄像头或类似的东西来获得骰子的俯视图。因为这个用例,我想我可以在我简单的黑色骰子盒里滚动它们,这样可以提供一致的背景,并用我的相机拍摄滚动的照片。然后,我可以用骰子位置和类别来注释照片,以便在对象检测模型中使用。

我第一次掷骰子时拍了 200 张照片。每个图像将有 6-10 个骰子。一些图片只有一种类型的骰子,而其他图片有混合。在注释了这些图片并训练了第一个模型后,我发现它的表现不如我所希望的那样好。所以我又加了 200 卷并做了注解。这个我会在最后再讲。

为了给我的 400 张图片添加注释,我使用了 labelimg ,就像我对其他物体检测管道一样。一旦你习惯了热键系统,它会加速注释过程。此外,注释这些对象检测数据集比图像分割数据集更容易。

Fair to say I got tired of looking at dice after annotating 2400–3000 of them…

所以一旦 400 张图片和大约 2400 个骰子被标注(大概花了 2 个小时?《夜魔侠》第三季的几集,我就可以开始训练模特了。

张量流对象检测配置

不久前,我配置了我的 Tensorflow 对象检测库,但在进行 windows 配置时,使用了由 EdjeElectronics 提供的本教程作为指南。他用一个更快的 R-CNN 模型为纸牌搭建了一个 6 级检测器,你可以在这里下载这个模型。我发现我在其他任务中使用这个模型取得了很好的成功,但是您也可以根据您的用例为其他人检查 T ensorflow 模型动物园

训练 Tensorflow 对象检测模型的基本过程是对一些数据集进行注释,从而得到包含图像注释的图像和 xml 文件。将它分成训练和测试文件夹。使用名为 xml_to_csv.py 的文件将这些注释转换成 CSV 格式,该文件指向包含测试和训练数据的文件夹。然后使用名为 generate_tf_record.py 的脚本为训练和测试拆分生成 TF 记录文件。这个 python 文件是您真正需要修改任何代码的第一个位置。我在注释器中的标签只是数字 1-12,当 python 读取它们时,它们以 int 的形式出现,所以最初我遇到了一个问题。我只需通过转换 generate_tf_record 脚本中的原始 row_labels 来修复它,以便将它们作为字符串读入。

def class_text_to_int(row_label):
    row_label = str(row_label) if row_label == '1':
        return 1
    elif row_label == '2':
        return 2
    elif row_label == '3':
        return 3
    elif row_label == '4':
        return 4
    elif row_label == '5':
        return 5
    elif row_label == '6':
        return 6 ... elif row_label == '12':
        return 12
    else:
        return none

随意查看 tf 记录和 xml 到 csv 脚本这里

一旦您有了训练和测试分割的 TF 记录文件,您就可以很好地处理数据部分,并且只需要配置模型管道。

通过向 labelmap.pbtxt 文件添加标签映射来配置管道。您可以根据需要继续列出项目,我有一个“…”来显示标签 4-11,因为我不想在这里列出它们。

item {
  id: 1
  name: '1'
}

item {
  id: 2
  name: '2'
}

item {
  id: 3
  name: '3'
}...

item {
  id: 12
  name: '12'
}

现在剩下的就是使用更快的 R-CNN 配置文件来配置训练管道。

  • 第九行。把 num_classes 改成你问题中的类的数量,对我来说是 12。
  • 107 号线。将 fine_tune_checkpoint 更改为:您之前下载或从 model zoo 获得的模型中的“model.ckpt”文件。
  • 第 123 和 125 行。在 train_input_reader 部分,将 input_path 和 label_map_path 更改为:指向 labelmap.pbtxt 和您生成的 train 记录文件。
  • 132 号线。将 num_examples 更改为\images\test 目录中的图像数量。
  • 第 137 和 139 行。在 eval_input_reader 部分,将 input_path 和 label_map_path 更改为:之前生成的 labelmap.pbtxt 和 test.record 文件的位置。

随意查看配置和 labelmap.pbtxt 文件这里

与所有对象检测模型进行交互的方式非常相似,您只需调整它指向的文件,就可以开始了。因此,请随意测试您在模型动物园中找到的不同产品。

模特培训

现在一切都准备好了,我们可以开始了。您可以使用 train.py 或 model_main.py 文件运行模型。我仍然使用 train.py 文件,并且在 model_main.py 上有问题,暂时没有问题。

下面是我在 cmd 上输入的运行模型的例子。在我的对象检测文件夹中有许多训练管道,所以这个管道被称为“training_dice”。基本上,模型将使用您指向的配置文件运行,并在您标记的训练目录中记录模型检查点。

python train.py --logtostderr --train_dir=training_dice/ --pipeline_config_path=training_dice/faster_rcnn_inception_v2_pets.config

一旦你进入它,给 Tensorflow 30 秒到 1 分钟开始运行,你会看到它开始输出步骤,他们的损失,以及他们花了多长时间。此时,您可以启动 tensorboard,以便更容易地跟踪模型性能。见下文,但它非常简单,只需将 tensorboard 指向你用来存储检查点的文件夹,并给你一个查看模型性能的 URL。

tensorboard --logdir=training_dice

因此,我喜欢看的是分类损失及其随时间的趋势,这个训练图看起来很好,从高开始,随着时间的推移越来越好。我让它运行了 6 个小时左右,基本上 2 点睡觉,8 点醒来评估。不是最科学的,但性能始终低于 0.05。我在我做过的其他项目中发现这个截止值对这个模型很好,EdjeElectronics 也注意到了这个模型的优点。虽然它只走了 24K 步,所以我可能跑得更久,但我在早上感觉不耐烦了。

Training graph of the classification loss from the 12 class object detection model. Ran for around 6 hours.

调整 Tensorflow 可视化文件:

对于这个问题,我想做的不仅仅是将骰子面识别为某个类/值,还要将所有值相加,以提供屏幕上骰子值的计数。我发现实现这一点的简单方法是修改 Tensorflow 对象检测源库中的可视化函数,不仅输出印有盒子和标签的图像,还输出为盒子生成的原始类标签列表。

我修改了源实用程序可视化脚本中第 640 行附近的 visualize _ boxes _ and _ labels _ on _ image _ array 函数。我所做的只是添加代码来构建并返回一个类字符串列表。

class_list = []for box, color in box_to_color_map.items():
    class_list.append(box_to_display_str_map[box]) #added to get class listing

它返回的标签列表是一个列表列表,其中每个子列表都包含一个类名和一个以百分比表示的置信水平字符串。然后,我检查并清除列表值,以分离出类名,因为每个类名都是一个数字,我只需将所有类名相加,就可以得到给定帧中屏幕上检测到的所有骰子面的值。

在所有的计算完成后,我只写给定帧的骰子值等于类名的总和。

image, class_list = vis_util.visualize_boxes_and_labels_on_image_array(
        image,
        np.squeeze(boxes),
        np.squeeze(classes).astype(np.int32),
        np.squeeze(scores),
        category_index,
        use_normalized_coordinates=True,
        line_thickness=8,
        min_score_thresh=0.80)print(class_list)
    class_sum = 0
    for class_val in class_list:
        i_hold = int(class_val[0].split(":")[0])
        class_sum += i_holdfont                   = cv2.FONT_HERSHEY_SIMPLEX
    CornerOfText = (10,50)
    fontScale              = 2
    fontColor              = (0,255,0)
    lineType               = 2cv2.putText(image,'Dice value: '+str(class_sum), 
    CornerOfText, 
    font, 
    fontScale,
    fontColor,
    lineType)

请随意检查修改后的可视化工具文件和修改后的图像视频文件,以使用课程列表

评估结果

总的来说,我认为这个模型做得相当好,给出了 12 个类,400 个样本,以及骰子形状和如何读取 8 对 10 对 12 面骰子的变化。然而,它仍然有改进的空间,例如,下面的第一个图像在最右边有一个骰子是 3,而不是检测到的 2。我发现这个相当奇怪,因为它甚至在正确的方向。第二张图片为 3,被归类为 8。这两个问题似乎都可以通过更多的数据扩充来解决。

然而,无论方向如何,检测骰子值的整个问题对于单个对象检测模型来说更加困难,因为它不具有与经典 CNN 中相同的数据扩充,以获得不同方向骰子的额外曝光。当我第一次训练模型时,它在奇怪方向的骰子上表现不佳,所以我将样本量增加了一倍,达到 400,这有助于解释这一点。但是即使这样做了,它仍然不总是得到正确的类。

3 gets marked as a 2

3 on the 8 sided die near the bottom gets marked with an 8 instead of the actual 3

我认为,当你知道图像中会有很多旋转变化时,处理这种情况的方法是建立一个第一阶段的模型,从图像中裁剪出物体,然后用翻转和旋转形式的大量数据增强来训练第二阶段的 CNN。

Depending on the orientation it does a good job of reading the 10 sided die. The die at the bottom has 4 or so values showing and I can see how it would be hard to read. The die on the right has a lot of values, but the top most one is reflecting light which probably makes it easier to detect. Another note is that for 10 sided dice, they show the 10 as either a 0 or a 10 depending on the dice.

下面是一个 12 面骰子的例子。在这一个中,它在检测它方面做得不错,但是因为我滚动这些最少的模型在跟踪数字 11 和 12 处有最少的暴露。

下面的 12 面骰子被归类为 2。如前所述,这可能是一个弱点,因为在我的数据集中滚动的 12 面骰子较少。我在掷骰子时有这种偏差,因为 D&D 使用的主要骰子是 6 面和 8 面骰子。随着 10 面和 12 面骰子越来越多地用于更难击中的法术和武器,但频率较低。

考虑到所有的事情,我认为这个模型对于一个相当小的 12 类分类数据集来说做得还不错。

结束语

要在我的 D&D 游戏中使用这个功能,安装一个面朝下的摄像头并让它在游戏中运行是相当容易的。由于它是在英伟达 1080 GTX GPU 上运行的单一模型,因此在接近实时的情况下完成这项工作应该没有问题。有趣的事情可能是训练一个较小的模型来制作树莓派或类似的东西。当我把模型放在 raspberry pi 上时,最大的担心是处理能力相当有限,但一个版本的 SSD 移动网络应该可以做到这一点。

因此,虽然这个对象检测模型相当成功,但如果我对性能更挑剔,我可能会将其构建为两阶段流水线。首先在所有 400 幅图像上运行我的对象检测模型,提取 2400 个骰子面,并使用它来训练 12 路分类器。这是我关于如何构建它的第一个想法,但我想测试一个更大的多类对象检测模型,因为我通常不会在我完成的大多数任务中超过 3 个类。

然后,为了实现该流水线,对象检测器将处理原始图像以检测骰子面,然后后端 CNN 将确定可用于合计面值并返回骰子总值的类。

链接到完整的 github 回购这里

手动计算梯度下降

原文:https://towardsdatascience.com/calculating-gradient-descent-manually-6d9bee09aa0b?source=collection_archive---------1-----------------------

一步一步:神经网络背后的数学

Title image: Source

这就是我们的问题。我们有一个只有一层(为了简单起见)和一个损失函数的神经网络。这一层是一个简单的全连接层,只有一个神经元,许多权重 w₁,w₂,w₃ …,一个偏置 b ,以及一个 ReLU 激活。我们的损失函数是常用的均方误差(MSE)。知道了我们的网络和损失函数,我们如何调整权重和偏差来最小化损失?

第一部分中,我们了解到,我们必须找到损失(或成本)函数的斜率,以便将其最小化。我们发现我们的成本函数是:

Image 1: Cost function

在第二部分中,我们学习了如何求偏导数。这很重要,因为这个函数中有不止一个参数(变量)可以调整。我们需要找到成本函数相对于权重和偏差的导数,偏导数就起作用了。

第三部分中,我们学习了如何求向量方程的导数。成本函数中的权重和偏差都是向量,因此学习如何计算包含向量的函数的导数是非常重要的。

现在,我们终于有了找到成本函数的导数(斜率)所需的所有工具!

神经元的梯度

我们需要逐步解决这个问题。让我们首先找到单个神经元相对于权重和偏差的梯度。

我们神经元的功能(伴随着激活)是:

Image 2: Our neuron function

其中它将 x 作为输入,将其与权重 w 相乘,并添加偏差 b

这个函数实际上是其他函数的组合。如果我们让f(x)=w∙x+b,g(x)=max(0,x) ,那么我们的函数就是神经元(x)= g(f(x)。我们可以用向量链法则来求这个函数合成的导数!

我们神经元的衍生物很简单:

Image 3: Derivative of our neuron function by the vector chain rule

其中z = f(x)=w∙x+b

这个导数有两个部分:相对于 wz 的偏导数,以及相对于 z神经元(z) 的偏导数。

z 相对于 w 的偏导数是多少?

z 有两部分: w∙x+b 。先来看 w∙x

w∙x ,或者说点积,实际上就是向量中每个元素的元素乘法的总和。换句话说:

Image 4: Expanded version of w∙x, or the dot product

这又是一个函数的组合,所以我们可以写成v=wxu=sum( v )。我们试图找出 u 相对于 w 的导数。在第三部分中,我们已经学习了这两个函数——逐元素的乘法和求和。它们的衍生物是:

Image 5: Derivative of u with respect to v and derivative of v with respect to w; where u=sum(wx)

(如果您不记得它们是如何推导出来的,请回头查看)

因此,由矢量链法则可知:

Image 6: Derivative of u with respect to w

就是这样!现在,让我们找出 z= u+b 的导数,其中 u= w∙x 相对于权重 w 和偏差 b. 记住,函数相对于不在该函数中的变量的导数为零,因此:

Image 7: Derivative of z with respect to the weights and biases, where z=sum(wx)+b

就是这样!这两个是 u 关于权重和偏差的导数。

神经元(z)对 z 的偏导数是多少?

神经元(z)=max(0,z)=max(0,sum(wx)+b)。

max(0,z)函数只是将所有负值视为 0。因此,该图看起来像这样:

Image 8: Max(0,z) // Source

查看该图,我们可以立即看到导数是分段函数:对于所有小于或等于 0 的 z 值,导数为 0,对于所有大于 0 的 z 值,导数为 1,或者:

Image 9: Derivative of max(0,z)

现在我们有了这两部分,我们可以将它们相乘,得到神经元的导数:

Image 10: Derivative with respect to the weights of our neuron: max(0, sum(wx)+b)

并将 z= w∙x +b 代入:

Image 11: Substituting w∙x+b for z

瞧啊。我们得到了神经元相对于其重量的导数!类似地,我们可以对偏差使用相同的步骤:

Image 12: Derivative of our neuron with respect to bias

这就对了。我们现在有了神经网络中一个神经元的梯度!

损失函数的梯度

第 1 部分中定义的我们的损失函数是:

Image 13: Loss Function

我们可以立即确定这是一个函数的组合,它需要链式法则。我们将把中间变量定义为:

Image 14: Intermediate variables for loss function

*注意,这里的 uv 与上一节使用的 uv 不同。

让我们首先计算相对于重量 w 的梯度。

相对于重量的梯度

u 简单来说就是我们的神经元函数,我们之前已经解决了。因此:

Image 15: Derivative of u=max(0, sum(wx)+b) with respect to the weights

v(y,u) 简单来说就是 y-u 。因此,我们可以利用分配性质,代入 u 的导数,求出它的导数(相对于 w ):

Image 16: Derivative of v=y-u with respect to the weights

最后,我们需要找到整个成本函数相对于 w 的导数。利用链式法则,我们知道:

Image 17: Derivative of cost function

让我们先找到等式的第一部分,即 C(v) 相对于 v 的偏导数:

Image 18: Derivative of cost function with respect to v

从上图(图片 16 ,我们知道 v 相对于 w 的导数。为了求 C(v)的偏导数,我们将两个导数相乘:

Image 19: Derivative of cost function with respect to w

现在用 y-u 代替 v ,用 max(0, w∙x + b) 代替 u :

Image 20: Derivative of cost function with respect to w

由于 max 函数在我们分段函数的第二行,这里 w∙x + b 大于 0,所以 max 函数将总是简单地输出 w∙x + b 的值:

Image 21: Derivative of cost function with respect to w

最后,我们可以将求和移到分段函数中,并稍微整理一下:

Image 22: Derivative of cost function with respect to w

就是这样!我们对重量求导!然而,这意味着什么呢?

w∙x + b-y 可以解释为误差项——神经网络的预测输出与实际输出之间的差异。如果我们称这个误差项为 ei,我们的最终导数为:

Image 23: Derivative of cost function with respect to w represented with an error term

这里,误差越大,导数越高。换句话说,导数代表斜率,或者说,为了使误差最小化,我们必须移动多少重量。如果我们的神经网络刚刚开始训练,并且具有非常低的精度,则误差将会很高,因此导数也将会很大。因此,我们将不得不迈出一大步,以尽量减少我们的错误。

您可能会注意到,这个梯度指向更高的成本,这意味着我们不能将梯度添加到我们当前的权重中,这只会增加误差,并使我们远离局部最小值。因此,我们必须用导数减去当前重量,以便更接近最小化损失函数:

Image 24: Gradient descent function

这里η代表学习率,我们作为程序员可以设定。学习率越大,步幅越大。然而,设置太大的学习率可能会导致采取太大的步骤,并跳出局部最小值。更多信息,请查看这篇关于梯度下降的文章这篇关于设置学习率的文章

相对于偏差的梯度

同样,我们有中间变量:

Image 25: Intermediate variables for loss function

我们还有 u 相对于之前计算的偏差的导数值:

Image 26: Derivative of u with respect to the bias.

同样,我们可以利用分配性质,代入 u 的导数,求出 v 相对于 b 的导数:

Image 27: Derivative of v with respect to the bias

同样,我们可以使用向量链规则来找到 C 的导数:

Image 28: Derivative of cost function with respect to the bias

C 相对于 v 的导数与我们为重量计算的导数相同:

Image 29: Derivative of cost function with respect to v

将两者相乘得到 C 相对于 b 的导数,用 y-u 代替 v ,用 max(0, w∙x + b) 代替 u ,得到:

Image 30: Derivative of cost function with respect to the bias

同样,因为第二行明确声明了 w∙x + b > 0,所以 max 函数将始终只是 w∙x + b. 的值

Image 31: Derivative of cost function with respect to the bias

就像之前一样,我们可以代入一个误差项,e = w∙x + b-y :

image 32: Derivative of cost function with respect to the bias, represented with an error term

就像关于权重的导数一样,这个梯度的大小也与误差成比例:误差越大,我们向局部最小值前进的步伐就越大。它还指向更高成本的方向,这意味着我们必须从当前值中减去梯度,以更接近局部最小值:

Image 33: Gradient descent function for the bias

恭喜你写完这篇文章!这很可能不是一个容易的阅读,但你一直坚持到最后,并成功地手动梯度下降!

正如我在本系列第 1 部分中所说的,如果不理解每行代码背后的底层数学和计算,我们就无法真正理解“创建神经网络”的真正含义,也无法理解支持我们编写的每个函数的复杂性。

我希望这些方程和我的解释是有意义的,并帮助你更好地理解这些计算。如果你有任何问题或建议,不要犹豫,在下面留下评论!

如果您还没有,请在此阅读第 1、2 和 3 部分:

此处下载原论文

如果你喜欢这篇文章,别忘了留下一些掌声!如果您有任何问题或建议,请在下面留下您的评论:)

需求的价格弹性,用 Python 进行统计建模

原文:https://towardsdatascience.com/calculating-price-elasticity-of-demand-statistical-modeling-with-python-6adb2fa7824d?source=collection_archive---------2-----------------------

Photo credit: Pexels

如何实现利润最大化

需求价格弹性(【PED】)是经济学中用来表示当只有价格变化时,商品或服务的需求量对其价格变化的反应性,或弹性。更准确地说,它给出了价格变化 1%时需求量的百分比变化。

在经济学中,弹性是衡量需求或供给对价格的敏感程度。
在营销中,消费者对产品价格变化的敏感程度。

它回答了以下问题:

  • "如果我降低一种产品的价格,销量会增加多少?"
  • “如果我提高一种产品的价格,会如何影响其他产品的销售?”
  • “如果一种产品的市场价格下降,这将在多大程度上影响企业愿意向市场供应的数量?”

我们将构建一个线性回归模型来估计 PED,我们将使用 Python 的 Statsmodels 来估计我们的模型,并进行统计测试和数据探索。我们开始吧!

数据

我们将研究牛肉价格和需求数据,这些数据可以从这里下载。

%matplotlib inlinefrom __future__ import print_function
from statsmodels.compat import lzip
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import statsmodels.api as sm
from statsmodels.formula.api import olsbeef = pd.read_csv('beef.csv')
beef.head(10)

Figure 1

回归分析

普通最小二乘(OLS)估计

beef_model = ols("Quantity ~ Price", data=beef).fit()
print(beef_model.summary())

Figure 2

观察:

  1. 小 P 值表明我们可以拒绝价格对数量没有影响的零假设。
  2. 高 R 平方表明我们的模型解释了很多反应的可变性。
  3. 在回归分析中,我们希望我们的回归模型有显著的变量,并产生高的 R 平方值。
  4. 我们将展示图表来帮助更直观地解释回归分析结果。
fig = plt.figure(figsize=(12,8))
fig = sm.graphics.plot_partregress_grid(beef_model, fig=fig)

Figure 3

该趋势表明,预测变量(价格)提供了关于响应(数量)的信息,并且数据点不会进一步偏离回归线,并且给定从大约 29 到 31 的预测区间,预测非常精确。

分量-分量加残差(CCPR)图

CCPR 图通过考虑其他独立变量的影响,提供了一种判断一个回归变量对响应变量的影响的方法。

fig = plt.figure(figsize=(12, 8))
fig = sm.graphics.plot_ccpr_grid(beef_model, fig=fig)

Figure 4

正如你所看到的,用价格解释的数量变化之间的关系是确定的线性关系。没有太多的观察对关系产生相当大的影响。

回归图

我们使用 plot _ regress _ exog 函数来快速检查关于单个回归变量(在本例中为价格)的模型假设。

fig = plt.figure(figsize=(12,8))
fig = sm.graphics.plot_regress_exog(beef_model, 'Price', fig=fig)

Figure 5

递归最小二乘

最后我们应用递归最小二乘(RLS)滤波器来研究参数不稳定性。

在 RLS 估计之前,我们将处理数据并创建一个日期时间索引。

beef['Year'] = pd.to_datetime(beef['Year'], format="%Y")from pandas.tseries.offsets import *
beef['Date'] = beef.apply(lambda x:(x['Year'] + BQuarterBegin(x['Quarter'])), axis=1)
beef.drop(['Year', 'Quarter'], axis=1, inplace=True)
beef.set_index('Date', inplace=True)beef.head(10)

Figure 6

RLS 估计

endog = beef['Quantity']
exog = sm.add_constant(beef['Price'])mod = sm.RecursiveLS(endog, exog)
res = mod.fit()print(res.summary())

Figure 7

RLS 模型递归地计算回归参数,所以有多少数据点就有多少估计值,汇总表只显示对整个样本估计的回归参数;这些估计相当于 OLS 估计。

RLS 图

我们可以生成给定变量的递归估计系数图。

res.plot_recursive_coefficient(range(mod.k_exog), alpha=None, figsize=(10,6));

Figure 8

为了方便起见,我们使用 plot_cusum 函数直观地检查参数的稳定性。

fig = res.plot_cusum(figsize=(10,6));

Figure 9

在上面的图中,CUSUM 统计量没有超出 5%的显著性范围,因此我们无法在 5%的水平上拒绝稳定参数的零假设。

源代码可以在 Github 上找到。祝你周末愉快!

参考资料:

统计模型

使用 Python 计算投资组合的夏普比率

原文:https://towardsdatascience.com/calculating-sharpe-ratio-with-python-755dcb346805?source=collection_archive---------2-----------------------

在本文中,我将向您展示如何使用 Python 来计算包含多只股票的投资组合的夏普比率。夏普比率是指每单位波动率(在股票市场中,波动率代表资产的风险)所赚取的超过无风险利率的平均回报。它允许我们使用数学来量化平均日收益率和日收益率的波动性(或标准差)之间的关系。

简单来说,夏普比率越大,风险调整后的回报越有吸引力。

根据我们的风险偏好,这种计算也有助于我们找到投资组合中每只股票的“最佳”配置。

[## 用 Python 绘制马科维茨有效边界

基于历史数据,这个边界将允许你根据你的期望优化你的投资组合配置…

towardsdatascience.com](/python-markowitz-optimization-b5e1623060f5) [## 可视化你的股票的一些关键财务指标

使用 Python 创建一个仪表盘,帮助您对公司做出更明智的投资决策

medium.datadriveninvestor.com](https://medium.datadriveninvestor.com/visualizing-some-key-financial-metrics-for-your-stocks-f987ea37035e)

一旦你准备好创建一个完全定制的仪表板来跟踪你的投资组合,我将通过两个课程教你

首先,我们需要股票价格数据。我将使用四个简单的文件,有两列——日期和收盘价。你可以用自己的数据,或者在 Quandl 里找点东西,这个用途很好。我们有 4 家公司——亚马逊、IBM、思科和苹果。苹果数据的前五行打印如下。

AAPL = PD . read _ CSV(' AAPL _ 关闭',索引 _ 列= '日期',解析 _ 日期=真)

After reading the files, this is what all the dataframes should look like (aapl, amzn, cisco and ibm)

现在我们需要为每个股票数据框架添加几列。通过几个简单的循环的,我们可以将标准化收益、我们在投资组合中的股票配置以及每只股票每天的头寸价值相加。首先是归一化收益,它只是将每个收盘价除以数据中的最后一个收盘价。

对于 stock_df in (aapl,cisco,ibm,amzn):
stock _ df[' Norm return ']= stock _ df[' adj . Close ']/stock _ df . iloc[0][' adj . Close ']

我们假设我们的投资组合将包括:苹果 35%,思科 25%,IBM 和亚马逊各 20%。

对于 stock_df,在 zip 中的分配((aapl,cisco,ibm,amzn),[.35,. 25,. 2,. 2]):
stock _ df[' Allocation ']= stock _ df[' Norm return ']*分配

循环的最后一个将添加一列位置值。假设我们的投资组合规模在第一天是 10k。我们只需将它与已经调整到标准化回报的分配列相乘。

对于 stock_df in (aapl,cisco,ibm,amzn):
stock_df['位置'] = stock_df['分配']*10000

这是现在四个数据帧的样子。对于每一天,你都知道你的头寸对四只股票的价值。

为了在一个表中得到我们所有的头寸,我们可以从每只股票中分离出列“Position ”,并将其合并到一个名为“portf_val”的新数据框架中。然后,我们重命名列以匹配每只股票。

all_pos = [aapl['position'],cisco['Position'],ibm['Position'],AMZN[' Position ']
portf _ val . columns =[' AAPL Pos ','思科 Pos ',' IBM Pos ',' AMZN Pos ']
portf _ val = PD . concat(all _ Pos,axis=1)

我们还可以创建一个列来显示所有头寸的总和,这就是我们的总头寸。

portf _ val[' Total Pos ']= portf _ val . sum(axis = 1)
portf _ val . head()

从这里,我们实际上可以绘制一些图表,以了解在我们的数据中的所有日子里,我们的投资组合价值发生了什么。

将 matplotlib.pyplot 导入为 PLT
PLT . style . use(' fivethirtyeight ')
portf _ val[' Total Pos ']。plot(figsize=(10,8))

它实际上表现得非常好(不要忘记,大约从 2009 年开始,我们一直处于牛市之中!).我们的个股怎么样?他们表现如何?

portf_val.drop('总位置',轴=1)。plot(figsize=(10,8))

我们可以看到亚马逊(绿色)表现很好,但另一方面,IBM(黄色)表现不佳。这里有一个很好的例子来说明为什么多样化很重要!

让我们看看我们的累计回报率是多少。

cumulative _ return = 100 *(portf _ val[' Total Pos '][-1]/portf _ val[' Total Pos '][0]-1)
print('您的累计回报为{:.2f}% '。format(cumulative_return))

output of the print statement above

我们可以检查 portf_val 的最后一行,看看我们的投资组合值多少钱。

portf_val.tail(1)

Our portfolio value grew from 10k to more than 22.5k

126.5%是非常体面的回报!我们将向我们的 portf_val dataframe 添加另一列。这一次,我们将添加每天的百分比变化,因此在下面的公式中为 1。日回报率对于计算夏普比率很重要。

portf_val['每日回报'] = portf_val['总头寸']。pct_change(1)

The first daily return is a non-value since there is no day before to calculate a return

现在是时候计算夏普比率了。这个公式非常简单直观:从预期投资组合回报中去掉你从无风险投资中获得的回报率。将结果除以投资组合的标准差。如今,由于利率如此之低,人们普遍认为无风险利率为零,因为如果你把钱存入储蓄账户(无风险资产的一般例子),你只能得到很少的钱。

所以这个公式就是日收益的平均值,除以日收益的标准差。在 Python 中,它看起来像这样:

S harpe_Ratio = portf_val['日线回报']。mean() / portf_val['每日回报']。标准()

为了完成这篇文章,我们需要按年计算夏普比率,因为我们是从每天的数值计算出来的。一年有 252 个交易日,所以年化的简单方法是用夏普比率乘以 252 的平方根。

就是这样!我们有年度夏普比率,我们准备在未来的文章中使用它来优化我们的股票配置。

如果你对 Python 的金融分析感兴趣,有两本很棒的书,几乎涵盖了你需要的所有内容:

另外, Investopedia 是定义这些指标的最佳资源之一。

欢迎留下任何问题或评论,或通过 LinkedIn 联系我。披露:上面的一些链接是附属链接。这意味着,对你来说零成本,如果你通过链接完成购买,我将赚取代销商佣金!

数据科学中的微积分及其应用

原文:https://towardsdatascience.com/calculus-in-data-science-and-its-uses-3f3e1b5e5b35?source=collection_archive---------2-----------------------

微积分是一种以纯粹形式发展起来的抽象理论。

微积分,更确切地说是分析,是数学的一个分支,研究数量的变化率(可以解释为曲线的斜率)以及物体的长度、面积和体积。微积分分为微分和积分。

Differentiation

Integration

微积分这个词来源于拉丁语,意思是“小石头”,
因为它就像通过观察小碎片来理解事物一样。

微积分是数学的一个固有领域,尤其是在许多机器学习算法中,你不可能想到跳过这门课程来学习数据科学的本质。

微分学把东西切成小块,看看它是怎么变化的。

积分学把小块连在一起(积分)算出有多少。

现在,我再次强烈推荐您观看来自 3blue1brown 频道的《微积分精粹》视频,该视频教授数据科学中所需的一些微积分重要支柱。

如果你有任何一种过敏或者没有通过视频学习的心情,可以参考这个。它涵盖了微积分的所有基本思想。

[## 微积分菜单

微积分这个词来源于拉丁语,意思是“小石头”,因为它就像通过看东西来理解一样…

www.mathsisfun.com](https://www.mathsisfun.com/calculus/)

我希望你已经理解了微分和积分的基础知识。数据科学家几乎对每个模型都使用微积分,机器学习中微积分的一个基本但非常优秀的例子是梯度下降。

梯度下降

梯度衡量的是,如果你稍微改变输入,函数的输出会有多大的变化。

假设你有一个球和一个碗。无论你把球滑到碗里的什么地方,它最终都会落在碗底。

正如你看到的,这个球沿着一条路径,在碗的底部结束。我们也可以说球在碗的底部下降。正如你从图像中看到的,红线是碗的坡度,蓝线是球的路径,随着球的坡度的减小,这被称为梯度下降。

在我们的机器学习模型中,我们的目标是降低输入数据的成本。成本函数用于监控 ML 模型预测中的误差。因此,最小化这一点,基本上意味着尽可能获得最低的误差值,或者提高模型的精度。简而言之,我们在调整模型参数(权重和偏差)的同时,通过迭代训练数据集来提高精确度。

让我们考虑一下,我们有一个用户的数据集,包括他们在某些科目上的分数和他们的职业。我们的目标是通过考虑一个人的分数来预测这个人的职业。

在这个数据集中,我们有约翰和夏娃的数据。有了约翰和夏娃的参考数据,我们不得不预测亚当的职业。

现在把学科里的分数想成一个梯度,把专业想成底层目标。你必须优化你的模型,以便它在底部预测的结果应该是准确的。使用 john 和 Eve 的数据,我们将创建梯度下降并调整我们的模型,这样,如果我们输入 John 的分数,那么它应该预测梯度底部的医生的结果,Eve 也是如此。这是我们训练过的模型。现在,如果我们给模型的主题打分,那么我们就可以很容易地预测这个职业。

理论上这是梯度下降,但计算和建模,梯度下降需要微积分,现在我们可以看到微积分在机器学习中的重要性。

首先让我们从你现在知道的话题开始。线性代数。让我们首先使用线性代数和它的公式为我们的模型。

我们可以在这个模型中使用的基本公式是

y = m*x +b

在哪里,

y =预测值,m =斜率,x =输入,b = y-截距。

解决这类问题的标准方法是定义一个误差函数(也称为成本函数),用于衡量给定线的“好”程度。该函数将接受一个(m,b)对,并根据直线与数据的吻合程度返回一个错误值。为了计算给定线的误差,我们将遍历数据集中的每个(x,y)点,并对每个点的y值和候选线的y值(在mx + b计算)之间的平方距离求和。传统的做法是平方这个距离,以确保它是积极的,并使我们的误差函数可微。

更适合我们的数据的线(其中更好是由我们的误差函数定义的)将产生更低的误差值。如果我们最小化这个函数,我们将得到数据的最佳线。由于我们的误差函数由两个参数(mb)组成,我们可以将其视为一个二维表面。这是我们数据集的样子:

这个二维空间中的每个点代表一条线。函数在每一点的高度就是那条线的误差值。您可以看到,有些线产生的误差值比其他线小(例如,更符合我们的数据)。当我们运行梯度下降搜索时,我们将从这个表面上的某个位置开始,向下移动以找到误差最小的线。

在微积分的本质视频中,你已经看到,为了计算斜率,我们使用微分。

The graph of a function z=f(x,y)z=f(x,y) is a surface, and fixing y=by=b gives a curve (shown in green). The partial derivative ∂f∂x(a,b)∂f∂x(a,b) is the slope of the tangent line to this curve at the point where x=ax=a.

为了对这个误差函数进行梯度下降,我们首先需要计算它的梯度。坡度就像指南针一样,总是指引我们下坡。为了计算它,我们需要对误差函数求导。由于我们的函数是由两个参数定义的(mb),我们需要计算每个参数的偏导数。这些衍生工具的结果是:

我们现在有了运行梯度下降所需的所有工具。我们可以初始化我们的搜索,从任何一对mb值(即任何一条线)开始,让梯度下降算法在我们的误差函数上朝着最佳线向下行进。每一次迭代都会将mb更新为一条线,该线产生的误差比前一次迭代稍低。使用上面的两个偏导数计算每次迭代的移动方向。

学习速率变量控制着我们在每次迭代中走下坡路的幅度。如果我们迈得太大,我们可能会跳过最小值。然而,如果我们采取小步骤,将需要多次迭代才能达到最小值。

虽然我们能够对学习梯度下降有所了解,但还有几个我们无法讨论的额外概念值得注意。其中一些包括:

  • 凸性–在我们的线性回归问题中,只有一个最小值。我们的误差表面是凸起的。不管我们从哪里开始,我们最终都会达到绝对最小值。一般来说,情况不必如此。梯度搜索可能会陷入局部极小值。有几种方法可以减轻这种情况(例如,随机梯度搜索)。

  • 收敛–我们没有讨论如何确定搜索何时找到解决方案。这通常是通过寻找迭代间误差的微小变化来实现的(例如,梯度接近零的地方)。

多元微积分

现在让我们深入学习多变量微积分,这将在多变量数据中教授微积分,我们最终会在现实生活中得到这些数据。

[## 多变量微积分|可汗学院

免费学习数学、艺术、计算机编程、经济学、物理学、化学、生物学、医学、金融…

www.khanacademy.org](https://www.khanacademy.org/math/multivariable-calculus)

要获得最新的更新、提示和任何你想要的或有问题的东西,只需在评论中发表。

在那之前…

快乐编码:)

别忘了拍手拍手拍手…

参考

[## 多变量微积分|可汗学院

免费学习数学、艺术、计算机编程、经济学、物理学、化学、生物学、医学、金融…

www.khanacademy.org](https://www.khanacademy.org/math/multivariable-calculus) [## 微积分-维基百科

它有两个主要分支,微分学(关于瞬时变化率和曲线斜率),和…

en.wikipedia.org](https://en.wikipedia.org/wiki/Calculus) [## 练习微积分|太棒了

采取有指导的、基于解决问题的方法来学习微积分。这些汇编提供了独特的视角和…

brilliant.org](https://brilliant.org/calculus/)

号召一支由法西斯组成的军队!

原文:https://towardsdatascience.com/call-for-an-army-of-be-a-sts-f751436671be?source=collection_archive---------16-----------------------

推动一个更加民主化的人工智能。

人工智能将由三个领域提供动力,即对自然语言的更好理解,从概率分布(GANs,VAEs)中学习的生成模型,以及通过强化学习(RL)算法进行的主要成分训练。让我们来谈谈 RL,它是前进的方向,因为它学习解决问题,而不仅仅是监督算法所做的后验映射。你可以向它抛出一个下棋的问题,不管有没有你的帮助,它都会学会下棋,或者下围棋、Dota2、星际争霸,甚至是股市!

他们通过与环境互动来做到这一点,模拟你希望代理做的事情。OpenAI 和健身房一起使这个领域民主化,推动了人们的参与和对这个想法的认识。这些环境是开源力量的一个很好的例子,它是免费的,非常强大,并且有一个开发者和用户社区的支持,他们可以在瞬间解决你的问题。尽管很棒,但它缺少一个非常重要的项目,一个复杂的策略游戏,比国际象棋和其他棋盘游戏更复杂。一些有规章制度,需要大量创造力的事情。

尽管 OpenAI gym 很棒,但它缺少一个非常重要的项目,一个复杂的策略游戏,比国际象棋和其他棋盘游戏更复杂。

A screenshot of DeepMind’s Starcraft-2 environment

如果我们看看这个领域中更多的开源项目,会发现没有什么比这更好的了。来自 DeepMind 安全研究和暴雪的星际争霸-2 环境是开创性的,但仍然受到许多问题的困扰,不是开源的,缺乏完整版本,主要是它的大小为 30 GB!所有这些问题使得它的使用很困难。

那我们做一个吧

我个人在这方面已经工作了一段时间,在得到了业内一些顶尖人士的大量反馈和验证后,终于开放了。Freeciv 是一款开源的基于回合的多人深度策略游戏,有规则,这使它成为使用它作为环境的完美候选。不仅有趣,它还是人们仍然喜欢玩的最古老的游戏之一,最初的提交是在 1996 年完成的,陈旧的分支可以追溯到 21 年前!我们正在为它编写一个 python 绑定器。你可以在这里查看,我们已经上传了为一篇论文所做的原创工作,该论文名为“通过阅读蒙特卡洛框架中的手册来学习获胜”。

A screenshot from freeciv 2.4

这项工作不仅重要,而且事后看来将是最有影响力的工作之一。这个项目不仅需要优秀的人才,还需要最优秀的人才。

有一个小团队正在努力工作,但我们需要更多的人来启动这个项目并真正建立起来。但是我们需要你的帮助。在编写代码和动态环境方面需要做大量的工作。我们从一个简单的需求开始,编译源代码并记录这个过程。最终目标是创造一个智能体,它可以在人类最少的帮助下(唯一的支持应该是基本的指令)学会自己在复杂的环境中穿行和玩耍。

在这里应用深度强化学习

这个环境将为测试人工智能提供一个巨大的机会,因为以下原因,你也可以把这作为我们需要在这个项目中实现和贡献的事情的宣言:

  1. 开放式奖励结构:由于可以采取如此多样的游戏产品和行动,用户将获得原始信息,如果他们愿意,可以编写自己的奖励结构,尽管我们将提供基本奖励。最近大多数突破性的模型都应用了元学习风格的体系结构,具有自动奖励理解。这种环境将推动这一进程更上一层楼。
  2. 深层次结构:游戏需要做的事情太多了,这就要求代理对各个层次应该做什么有更深的理解,而不仅仅是看一下画面就决定下一步的行动。
  3. 长期游戏性:由于游戏可以持续许多回合,它需要代理人进行非常长期的战略思维处理。比现在任何环境都要长,也更多样化。
  4. 信息类型:游戏不只是发送一个原始图像,而且其中许多,代理得到各种各样的地图(资源,单位,财产)而不是一个单一的图像。文本中有规则和规定,许多策略指南,使你的模型能够处理不同类型的信息,我们人类认为这些是理所当然的。
  5. 一般智能:游戏中的多样性、结构和要做出的决定是如此开放和广阔,以至于你的代理人(或全体)需要有一个非常一般的思维过程。这种平台将导致研究和代理,这将使我们对人工智能的理解和发展更好。
  6. 大小:目前最大的优势是大小,一个全功能的互动游戏不到 100MB,游戏中有 API 的源代码,所以你可以记录你的动作,然后用它们来训练你的模型。
  7. 【奖金】小游戏:为了让初学者更容易开始这方面的工作,我们旨在发布各种各样的小游戏,就像星际争霸 2 中的环境一样,这将帮助你在进入主游戏之前测试你的模型到简单的任务。

Let’s not be this dumb

这一切都是这个环境所提供的;主要的困难是,我们需要建造并测试这个东西。回购是新的,项目将被添加到其中,以指导我们并为项目设定基准。

github 回购链接:https://github.com/yashbonde/freeciv-python

欢迎贡献者,如果你有任何疑问/想法,请打我的 LinkedIn 联系我,我不介意现在是凌晨 4 点,我会回复你。

干杯!

电脑能说出口红的颜色吗?

原文:https://towardsdatascience.com/can-a-computer-name-lipstick-colors-1897a8208b17?source=collection_archive---------6-----------------------

我经常想知道是谁给化妆品的颜色命名的。如果你从来没有浏览过当地药店的化妆品通道,你可能不会注意到区分无穷无尽的口红颜色的调情标签。例如,露华浓出售大胆的淡紫色,敢于裸体,富家女红,可亲吻的粉红色和无情的葡萄干。

根据我的直觉,这些口红的名字遵循某种不言而喻的公式,我想知道计算机是否可以学习它们的模式并产生新的模式。我从丝芙兰网站上购买了数百种唇色(包括香膏、唇彩、眼线笔和口红),还从露华浓等药店购买了其他颜色。我将这个数据集输入到一个神经网络中,这是一个深度学习模型,可以学习文本的结构,并可以对任何经过训练的材料进行自己的再现。你可以在这里得到我自己用的模型

这是它想出来的,以自制插图为特色。从我的最爱开始…

还有更多…

凉鞋太阳

黑暗的扑通声

玫瑰犯罪

吹玫瑰

糖潘趣酒

玫瑰上的性爱

Pop 购物桃

把它烤成珊瑚色

玫瑰色

克朗布罗斯

性感

曼·布朗

朱岳鹏·皮卡特

我的虱子

波普空心珍珠

爱情 Snop

棒棒糖

胭脂人民

卡洛

热红色米色

淡紫色的血

赤裸裸的不友好

方法说明

虽然我能够收集到数百个口红颜色的名称,但就神经网络可用的原始文本而言,这实际上是一个非常小的数据集,因为这些名称很少超过 2-3 个单词。当神经网络拥有大量训练数据时,它们往往表现最佳。我用来获得更好的训练的一个廉价而肮脏的技巧是简单地通过重复几次唯一名称的列表来扩大训练集。我担心这将导致过度拟合和简单地重复训练集名称,但在这种情况下没有。我训练了一个 3 层 256 节点的网络,在温度刻度盘上找到了一个“最佳点”。太低了,而网络大多一次又一次地产生了“粉红”这样的常用词。太高了,它吐出胡言乱语。但是在 0.45-0.6 左右,我得到了一些非常好的新口红名字,这些名字几乎是可信的。

深度神经网络可以作曲吗?

原文:https://towardsdatascience.com/can-a-deep-neural-network-compose-music-f89b6ba4978d?source=collection_archive---------6-----------------------

当我去年九月开始读研时,我想尽快投入到深度学习的热潮中。当我在纽约作为一名软件开发人员工作时,我不断听到关于深度学习的惊人事情: DeepFace 可以像你和我一样识别人的脸, AlphaGo 在一场最初对人工智能来说似乎难以捉摸的游戏中摧毁了玩家, GANs 刚刚开始获得动力。所以当我得知我的部门要办他们第一个真正的深度学习班的时候,我立马就报名了。尤其是因为它将由计算机视觉领域的一位名人来教授,埃里克·勒德-米勒,他在这里经营着计算机视觉实验室。顺便说一下,值得表扬的是,最初的课程是由费-李非斯坦福视觉实验室的主任安德烈·卡帕西开发的。

快进过去一些巨大的任务,使我们实现了神经网络框架的本质,包括密集层、漏失层、批量规范层、卷积层、递归层、你能想到的每一个激活层、市场上可用的所有优化器、反向传播以及计算机视觉中的一系列应用,如对象识别、图像字幕和图像生成, Sam Witty 和我最终必须选择我们想要为我们的最终项目做什么。由于山姆是一个名为 白卡带 的乐队的键盘手,这意味着他在与音乐相关的一切方面都绝对。凭借他的专业知识和我严重缺乏的音乐天赋,我们决定看看是否可以像人一样使用深度学习作曲。

Source: Music Lover Stock

这让我们看到了丹尼尔·约翰逊在一个名为六面体的博客中发的一篇非常甜蜜的帖子。丹尼尔建立了一个可以创作古典钢琴曲的深度神经网络。在那篇文章的帮助下,我和萨姆开始了我们的最终项目——遗憾的是,我们不假思索地将其命名为Deep Jammer——通过学习巴赫、贝多芬、莫扎特和其他著名作曲家的大量音乐,可以无休止地创作古典钢琴曲。如果你想了解详情,你可以查看我们的报道、海报和 T21。我们也使用迁移学习来创作爵士乐,但是我们将把它留到另一篇文章中。虽然 Deep Jammer 是基于 Daniel 所做的,但我们重构了他的许多代码(他甚至承认这些代码很乱),优化了设计和超参数,并在 Keras 中实现了一个更干净的版本,这个版本可以工作,但不太好。言归正传,下面是 Deep Jammer 作曲的一首古典钢琴曲的预告:

背景故事够多了。让我们继续表演吧。既然对这篇文章标题的明显回答是响亮的是,现在让我们问一个不同的问题。

深度神经网络如何作曲?

概观

为了让你对我们所做的有一个基本的概念,让我们对我们的最终项目有一个大概的了解。看看这个:

如您所见,该图只有三个部分:

  • 代表一段音乐的输入矩阵
  • 输出矩阵,表示对下一步播放什么的预测。
  • 通过听大量音乐来学习模式的神经网络

因为这可能现在对你来说很模糊,让我们慢慢地走过输入矩阵、输出矩阵和神经网络。没那么糟。

投入

我们网络的输入是一段音乐,我们把它转换成一种特定的表达方式。说得好听点,我们把这个叫做。这只是一个三维矩阵:

  • 时间:该段有 128 个时间步长*。打个比方,每个时间步长就像一首歌的 100 毫秒。类似于一首活页乐谱,这将帮助我们了解一个片段如何随时间变化。*
  • 注:每个时间步有 88 个* 。我们有 88 个,因为一架钢琴上有 88 个键。再一次,如果我们想到乐谱,这代表了五线谱上所有的线条和空间。*
  • 属性:每个音符有 78 个属性* 描述该音符的状态,我们将在后面介绍。基本上,对于每一个音符,我们都需要知道一些关于它的事情。*

由于谈论三维矩阵可能会令人困惑,现在让我们把所有的东西放在一起。第一,输入只是一段。第二,每段有 128 个时间步长来表示时间。第三,钢琴上每个键的每个时间步有 88 个音符。第四,每个音符有 78 个属性来概括音符的状态。简而言之,输入——我们称之为片段的三维矩阵——只是描述了一段音乐。

到目前为止,我们还没有讨论每个音符的属性是什么样的。那么它们是什么呢?请看下面:

  • 位置:钢琴上相应音符的键的位置。这个范围从 1 到 88,因为钢琴上有 88 个键。更重要的是,我们需要这一点,因为网络必须理解相同音高的音符之间的差异,就像当我们有两个不同八度的 a 时。
  • 音高类:一个数组,每个元素对应一个音高( CDEFGAB 连同降半音和升半音)。与相应音符相关联的音高被设置为真。每隔一个间距设置为
  • neighborhood:包含与相应音符相邻的音符状态的数组。我们为每个相邻的音符存储两个值:如果它刚刚被弹奏,我们存储(1) (否则存储);如果它刚刚被按住,我们存储(2) (否则存储)。为了简单起见,我们只采集相应音符的上下八度音程中的相邻音符。
  • 节拍:在其小节中对应音符的位置。例如,一个音符与一个从 0 到 16 的整数相关联,因为我们的时间分辨率在第 16 个音符。然而,这可能会随着训练集中古典钢琴作品的分辨率而改变,我们将会谈到这一点。

输出

我们网络的输出预测了在输入段之后的下一个时间步应该播放什么。再一次,说得好听点,我们称之为预测 这只是二维矩阵:

  • 注:预测有 88 个音符*对于像输入一样的钢琴的每个键。*
  • 属性:每个音符有 2 个属性* 描述该音符的预测状态。*

那么属性是什么呢?请查看以下内容:

  • 弹奏概率:音符在下一时间步弹奏的概率。
  • 发音概率:音符在下一时间步被保持的概率。

体系结构

现在我们已经了解了网络的输入和输出,让我们来看看每一层的作用。但是,在我们这样做之前,先来看一个简化的图表,它给出了大致但很好的概述:

这些层看起来和听起来都比它们实际上更令人困惑。如果我们把每一个都分解开来,那就很简单了。顺便说一句,如果你不知道什么是 LSTM,它只是一种特殊类型的 RNN。如果你想了解更多,可以在 colah 的博客上查看这篇文章。在任何情况下,检查每一层:

  • 时间层:捕捉音乐时间模式的 LSTM 层。我们将之前的时间*维度视为 LSTM 的时间维度。这意味着网络学习每个音符的属性如何随时间变化。比如这里可以想到琶音和音阶。*
  • 转置层:转置时间维度和音符维度的处理层。为什么我们要翻转这两个维度?这将音符*维度设置为 LSTM 的新时间维度,为下一层做准备。*
  • 音符层:LSTM 层,捕捉音乐的空间(或音符)模式。我们将之前的音符*维度视为 LSTM 的时间维度。这使得网络能够了解属性如何随着音符而变化。最好的例子是一起演奏的一个和弦或一组音符。(我同意你的观点。这是一个奇怪的想法。)*
  • 致密层:全连通层,将注层的高维输出降低为非标准化预测。这一层*总结了时间层笔记层*所学的
  • 激活层:对来自密集层*的非标准化预测的每个元素进行标准化——或挤压——的层。我们使用 sigmoid 激活函数来完成此操作:*

请注意,我们可以在架构中调整几件事情,如时间注释密集层的数量以及每层中的节点数量。如果愿意,我们还可以添加辍学层。我将忽略这一点,因为它们是实现细节。

培养

走过了我们网络的一切,是时候训练它了。这和你训练任何网络没什么不同。我们是这样做的:

  1. 我们从这里收集了 325 首古典音乐作品。它们是 MIDI 文件。如果你不知道那是什么,我也不会担心。MIDI 只是一种将音乐编码为一系列事件的格式。为了简洁起见,我们跳过细节。
  2. 我们一拿到 MIDI 文件就做了一个训练集。为此,我们从 MIDI 文件中随机取样,并将它们转换成适合我们网络的表示形式。在我们的训练集中,一个训练示例是一对两个矩阵(即我们已经讲过的输入和输出矩阵): **(a)特征只是一段(具有时间注释属性**维度的三维矩阵)。
    **(b)
    标签** 是一个预测(二维矩阵用标注属性维度)。
  3. 我们设计了一个定制的损失函数,因为我们跳过了太多的符号,所以我们将忽略它。如果你感兴趣的话,报纸上有这方面的报道。除了损失函数,我们还导出了反向传播的梯度。
  4. 我们使用 adadelta 来训练我们的网络,这是一种自适应学习率梯度下降方法,用于 5000 个时期,批量大小为 5 个段。

如果你有兴趣,你可以看看下面这个训练损失的好图。这里没有什么太令人惊讶的。它像大多数训练损失曲线一样减少。

每隔 100 个时代,我们用我们的网络作曲,看看随着训练损失的持续减少,音乐是什么样子的。看看下面的可视化。请注意,时间轴代表时间步长,音符轴代表 88 个琴键。你可以看到随着网络训练越来越多,音乐变得越来越好。到最后,你肯定能看到琶音、音阶和和弦。

产生

现在我们已经训练了我们的网络,让我们创作一些古典钢琴曲。为此,我们一遍又一遍地重复以下步骤:

  1. 我们从训练集中随机选择了一个片段。
  2. 我们将该片段作为输入输入到网络中。
  3. 我们从网络得到一个预测作为输出。
  4. 我们将预测转换成一个新的部分。
  5. 跳到第二步

简单地说,我们输入一个片段,得到一个预测,然后将预测反馈给网络。如果我们跟踪每一个预测,我们就可以把一首听起来不太糟糕的古典钢琴曲串起来。

结果

为了评估我们的网络创作的古典钢琴音乐,我们发出了一份调查,参与者必须从 10 首作品中选出一组不同的作品进行评分。此外,我们还加入了一首真正的古典钢琴曲,它来自一位不为参与者所知的著名作曲家。由于我们的海报已经过时,这里有一些最新的有趣数据:

  • 我们电视网的最佳节目平均得分为 7.5
  • 真品的平均评分为 7.9 分
  • 奇怪的是,有三个人不相信真正的曲子是人类创作的
  • 12 个人更喜欢我们电视网的最佳节目

现在我们已经结束了,是时候听一些由我们的网络创作的古典钢琴曲了!我希望你喜欢这场表演。停留片刻,倾听:

机器会有种族歧视吗?

原文:https://towardsdatascience.com/can-a-machine-be-racist-5809b18e5a91?source=collection_archive---------10-----------------------

人工智能已经成为一个家喻户晓的词。它也成了所有家庭的操纵者。人工智能在所有业务和商业模式中的无节制爆炸一直是增长的惊人动力,但它也提出了需要回答的问题。

数据科学家和人工智能研究人员将越来越多地驱动人类行为,影响企业的决策方式,甚至引导政府。此外,这些模型将越来越多地从传统的人类可理解的设计转向复杂的深度学习模型,其中涉及的复杂性令人难以置信。在实践中,这种情况很少或根本没有围绕这种系统的伦理进行讨论。

人体扩增

当我们使用 ML 来增强或执行通常由人类执行的任务时,我们有机会消除影响判断并导致糟糕决策的偏见。我们人类会变得疲惫或懒惰,会变得种族主义或性别歧视,会变得傲慢或过于自信,这样的例子不胜枚举。所有这些特征使人类成为糟糕的决策者——不管这些决定是不是有意的。

人工智能有能力消除决策过程中的人为因素。也许最重要的是,它可以根据原始客观数据做出纯粹客观的决策。当我们将伦理应用到这些系统的设计中时,每个人最终都会过得更好。伦理提供了一个客观的框架来判断什么是对的,什么是错的。在这篇文章中,我希望让你相信人工智能带来的危险和好处,并为企业和数据科学家提供一个简要的框架。

在你继续之前,请记住这不是一篇危言耸听的文章。目前人工智能的好处远远大于后果。我正在关注人工智能中的一个具体问题,我希望通过尽早认识到这个问题,我们可以在这个讨论的基础上从这个强大的工具中获得最大的好处。

为什么道德很重要

在成为数据科学家之前,我是一名机械工程师。我的学位让我选修了多门伦理学课程,而我的职业生涯要求我全程选修伦理学课程。

我研究了许多工程事故,这些事故导致了数百人不必要的死亡和伤害,以及数不清的环境破坏。安全设计的规模和重要性,极度关注细节的重要性,以及导致失败的罕见事件。在我学习期间,职业道德不断地灌输给我。相比之下,人工智能经常停留在道德黑洞中。人工智能的现实是,一些模型做出的决策对企业和社会都不利。

目前,机器学习中的伦理困境无法与工程界的伦理困境相提并论。很难想象一个机器学习系统会因为错误的设计而杀死数百人,但它们仍然会造成伤害。我们经常将身体伤害提升到金融、政治或操纵痛苦之上,但人工智能系统将在较小范围内影响数十亿人的事实最终使它们变得更加重要。

根据真实故事改编

假设您在一家银行工作,想要创建一个模型来预测客户的违约概率。然后,您希望将此预测用于贷款利率。对于这个例子,让我们假设我正在以最大化我的算法为目标来处理这个任务,而没有任何关于道德的想法。我的方法是机器人式的,我会消耗任何增加我的模型预测能力的数据。

您会使用哪些功能来训练您的模型?

  • 客户居住的街道
  • 性别
  • 人种
  • 语言
  • 婚姻状况
  • 脸书上的朋友,朋友数量
  • LinkedIn 上的关系
  • 年龄
  • 教育
  • 医院就诊次数

这样的例子不胜枚举。几乎任何东西都可以做成模型。一些公司需要脸书数据作为其贷款申请流程的一部分。他们可以解析你的朋友,你的帖子,你朋友的帖子…你明白了。

那么什么时候可以呢?这种模式有完全有效的积极的社会论据。它可以让原本无法获得信贷的人获得信贷。事实证明,它可以减少对被传统金融体系拒之门外的人的掠夺性贷款。我还敢打赌,许多(或所有)经济学家都会同意,更广泛的信贷渠道对经济更有利。

然而,你可以很容易地看到我们如何开始更深地隔离我们的社区。这些算法将输出越来越准确的违约率,但收取的高利率将成为一个强化循环。随着农行普通客户继续获得更高的贷款利率,他们违约的概率将会上升。算法的下一次更新将考虑到这一点。情况并非总是如此,但在实践中可能会发生。正是设计糟糕的算法成为了其预测的牺牲品。

我认为那家伙应该升职

让我们想象同样的过程应用于其他问题——预测组织中的高绩效员工。你输入员工的所有数据(年龄、性别、绩效分数、能力测试),结果就出来了。如果您使用的是基于回归的算法,您可以确定该算法使用哪些数据来做出决策。由于该算法着眼于人类行为(过去的绩效评估和以前的晋升非常主观),它仅仅是现有做法的反映。此外,如果你在没有任何道德标准的情况下使用它,它会加重任何已经存在的人类偏见。它很快变得比组织本身更有偏见!

如果性别是一个强有力的预测因素,会发生什么?如果种族是一个强有力的预测因素会发生什么?如果一个领域是由一种性别主导的,比如教学是由女性主导的,或者工程是由男性主导的,那么算法就有可能抓住这一点,并相应地对人们进行细分。

数据中存在这些偏差可能有完全有效的原因,但这并不能阻止算法找到它们并加以利用。也许你的组织中外国人的比例很低——你的算法可以利用这一事实来提高其准确性。或者,我们可以想象这样一个场景,A 公司有一个种族主义的招聘经理,这个经理的行为会影响模型的预测。毕竟模型没有感觉,也没有情绪;它只是试图预测你让它做什么。如果你打算预测人类行为,而人类行为是有偏差的,那么它就是将被嵌入算法中。

如果我用这个算法来告知你的决策精度,它会开始鼓励它首先发现的偏差。这是完全可能的,事实上也很有可能,你更有可能提升来自业务所在国的员工,而不是外籍员工。同样,可能有完全合理的理由——本地员工更有可能在该公司工作更长时间,或者更有可能在工作中掌握更好的语言。话又说回来,它们可能只是不公平的做法。

事实是你不知道。

这个事实导致了一种算法,它以一种你永远不会允许自己去做的方式运行。它变得类似于一个分数系统,人们根据他们的肤色或性别来打分。这也是你永远不会作为公司政策写下来的东西,但你却允许你的算法这样做。是不是因为电脑做到了就变得 OK 了?号码

发生这种情况的例子有很多,但总体来说,在这个领域很少有这方面的培训或讨论。只是在最近,人工智能中的伦理话题才变得更加普遍。

让人工智能去思考

我最近在为一个朋友搜索疫苗信息,我不得不进入我的搜索引擎的第二页去寻找来自 CDC,NHS 和加拿大政府的信息。最可信的来源不应该是第一位的吗?

为什么会这样?

根据过去的搜索历史提供搜索结果可能是危险的 —当你进入搜索引擎并键入“疫苗安全吗”时,你是在问一个有倾向性的问题。一般来说,认为疫苗安全的人懒得问这个问题,搜索引擎算法说你有点像这些问类似问题的人,这给了你怀疑的博客。它甚至会扭曲你对这场争论是否存在的看法。

事实是,绝大多数医生和科学家都有结论和数据支持疫苗是安全的这一共识。我甚至无法开始描述疫苗给人类带来的好处。

如果你向人们展示基于他们对替代事实偏好的搜索结果,你对他们有好处吗?或者你只是在夸大他们的偏见,认为权威的地位是不可信的?在人工智能的发展过程中,许多这类问题都没有被问过。

分析会扼杀客观性吗?

在一个充斥着异常善于分析的人的领域,伦理学已经被抛在了一边。事实上,缺乏伦理关怀和对预测能力的追求导致了善于分析的人使用主观数据。在任何模型中使用主观数据时都应该非常谨慎,应该避免使用个人数据来预测人类行为。具有讽刺意味的是,一个本应客观的领域,却往往是主观建造的。

此外,主观算法通常对它们的创造者没有好处。机器可以通过绕过使我们的行为偏离客观性的认知偏见来做伟大的事情。众所周知,人类会错误地感知一系列反应和结果。他们会犯错,会疲劳——机器可以检查这些固有的缺陷。

伦理道德在哪里?

也许这是因为在数学等许多量化领域并不真正需要进行伦理讨论,而这些正是越来越多地进入 AI 领域的人。为了优化他们的算法,获得更多的数据,并提高准确性,许多从业者正在开发影响行为和决策的算法。数据科学领域应该关注工程师和医生已经安装的系统,以确保他们的领域为人类造福。道德设计需要成为任何课程的要求,像我这样自学成才的设计师需要熟悉这些想法。

业务影响

经历这个过程有点困难。最终,这将落到领先的数据科学家和雇佣数据科学家的公司的肩上。

关于伦理设计的讨论应该成为现状。否则,目前的方法将开始损害公司的声誉,或者导致公众对人工智能的强烈反对。你永远不应该把数据输入到一个你不会在公司政策中用来做决定(或者实际上是自己做决定)的算法中。就像你永远不会明确地使用性别、种族和语言来提升他人一样(不考虑隐含的偏见),除非你明白后果,否则你永远也不应该把它们输入算法。

外卖——保持认知和警觉,但避免敲响警钟

可以肯定的是,在有些地方使用这种主观数据是合乎道德的,甚至是一种要求(例如,医疗保健),但关键是这种讨论对于大多数数据科学领域来说尚不存在。

任何时候你在算法中使用人类行为,你都需要小心。人类是有缺陷的;人类可以因为任何原因产生任何数量的偏见。基于它们的算法将不可避免地成为这种行为的延伸。一个设计不当的算法预测出最佳表现者,不太可能是一个数学专家,而更可能只是模仿你当前流程的行为(尽管是以一种更具成本效益的方式)。

这从两个方面伤害了公司:

  • 第一,它未能完成设计它的目标任务。
  • 第二,如果算法偏差被人知道或公开,这可能会成为一场噩梦

所以回到题目;机器会有种族歧视吗?我说不。机器只做它被设计做的事。如果你设计了一台糟糕的机器,它会做出种族歧视的决定,但那是设计者的错,而不是机器的错。就像工程师把一座桥的失败归咎于设计者一样,我们是否应该把一个人工智能系统的失败归咎于它的程序员。

通过使用正确的特征,坚持分析数据而不是主观数据,算法可以极大地改善你的决策。仅仅有客观的输入是不够的,但是你需要优化一个客观的结果。对很多人来说,这是数据科学中最难、最麻烦的部分;问正确的问题。

一个简单的 CNN 能像面部识别一样区分红发人吗?

原文:https://towardsdatascience.com/can-a-simple-cnn-work-as-well-as-facial-recognition-for-differentiating-redheads-18596b05fdec?source=collection_archive---------3-----------------------

简单的卷积神经网络(CNN)在区分图像方面工作得非常好,但它在区分人脸方面也能工作得一样好吗?面部识别当然会在算法中使用 CNN,但它们要复杂得多,这使得它们在区分面部方面更有效。

在我的小而有趣的项目中,我想测试一个简单的有 3 层卷积层的 CNN 如何区分我和其他红发男人。我认为这将是一个有趣的项目,因为人们似乎总是把我和其他红发人搞混,所以我想知道人工智能是否也会这样做。

我将讨论的内容:

  • 我的假设是什么
  • 我如何着手这个项目
  • 我的方法的缺陷
  • 结果

我的假设是什么:

我曾经和简单的 CNN 一起工作,把狗和猫区分开来,效果非常好,所以我也相信一个简单的 CNN 在区分我和其他有 3 个卷积层的红头发的时候有 80%的准确率。

我如何着手这个项目:

简单 CNN:

CNN 要想做好,需要大量的图片作为参考。我在网上获得了 1300 张其他红发男性的照片,并给自己拍了大约 400 张照片。1300 张其他红发人的照片由 15 名年龄在 20-30 岁之间的不同男子组成,在许多不同的背景下,他们的脸清晰可见。我的照片大多是用不同的背景和服装自拍的。我的脸也出现在每张照片中。

https://www.clarifai.com/technology

我不想太深入了解 CNN 是如何工作的,但如上所述,它有一个卷积层、池层、全连接层和输出层。这是非常高的水平,因为有不同的激活功能,惩罚和 softmax 功能也涉及。

我决定在我的模型中使用三个卷积层和池层,ReLu 作为激活函数。我本来可以在我的模型中添加更多的卷积层,但我认为即使对于我正在使用的 GPU (AWS)来说,它的计算量也会变得太大。

考虑到只有 400 张我自己的照片和 1300 张其他红发男人的照片的不平衡的阶层,我包括了 50%的退出率来帮助弥补这个差异。

亚当·盖特基的人脸识别:

我利用了一个由 ageitgey 构建的人脸识别库,其中他们使用 dlib 来构建。据称,“该模型在野生基准中的标记人脸上的准确率为 99.38%。”

如果你看了亚当·盖特基的 Medium 帖子,就会深入了解这是如何运作的。

首先,看一张照片,找出照片中的所有面孔

第二,专注于每一张脸,并能够理解即使一张脸转向怪异的方向或在光线不好的情况下,它仍然是同一个人。

第三,能够挑选出你可以用来区别于其他人的面部特征——比如眼睛有多大,脸有多长,等等。

最后,将这张脸的独特特征与你认识的所有人进行比较,以确定这个人的名字。

Result of locating the 68 landmark features on your face

当用它来区分自己和其他红发人时,效果非常好。只是为了好玩,我试着用在我的狗身上,但是没用。在我 12 岁时的旧照片上使用时,它也不起作用。当然,即使对人眼来说,这也变得更加复杂。

我的方法的缺陷:

我的方法最大的缺陷是没有足够的图片和不平衡的数据。

为什么会有这些可能的问题?

  • CNN 需要大量的图片才能正常工作。很多时候 CNN 模型使用数百万张图片,当然这并不总是必要的,但会导致更好的结果。
  • 不平衡的数据会导致过度拟合,这是不好的。例如,如果 90%的数据属于第 1 类,10%属于第 2 类,那么模型将会假设所有数据都属于第 1 类。为了帮助这个过程,我引入了退出作为惩罚措施,但是引入合成采样或者只是给自己拍更多的照片可能是有益的。

结果

我的 CNN 模型工作得非常好,准确率高达 94%!然而,如前所述,一些陷阱可能会提高这种准确性。当我使用 ageitgey 的人脸检测库时,它每次都能识别我,然而我只尝试了 50 次。鉴于 Adam Geitgey 发现的 99.38%的准确率,在区分人脸时使用人脸识别显然是有意义的。然而,简单的美国有线电视新闻网似乎在区分我和我的红发男同胞方面做得很好。这个小项目产生了有趣的结果,我很高兴人工智能能把我和其他红头发区分开来,而陌生人却不能:)!

AI 能有创造力吗?

原文:https://towardsdatascience.com/can-ai-be-creative-2f84c5c73dca?source=collection_archive---------0-----------------------

全面审视计算机和创造力的现状

2015 年,研究人员安托万·库里、杰夫·克伦、达内什·塔拉波和让·巴普蒂斯特·穆雷在他们的屏幕上看到了一个古怪的异常现象。

他们在模拟环境中训练机器人,如果它们的腿受伤了,就能适应行走。当他们试图找到机器人行走所需的与地面的最少接触时,他们发现了一个不可能的值——计算机计算出机器人可以在脚与地面 0%接触的情况下行走。

机器人不接触地面怎么可能行走?

当他们播放视频时,他们发现了一些惊人的东西。计算机已经提出了一种步态,在这种步态中,机器人可以翻转自己,用肘关节行走,从而将脚的接触减少到 0。

The AI came up with a creative solution to walk without any of its feet

如果这项任务交给人类,他们似乎不太可能考虑不使用腿的机器人行走步态。人工智能自己想出了一个独特的解决方案。

那么问题就来了——人工智能有创造力吗?

创造力是我们通常认为人类独有的技能。有史以来,我们一直是地球上最有创造力的生物。鸟类可以筑巢,蚂蚁可以筑巢,但在地球 5.101 亿公里的表面上,没有任何其他物种能接近我们人类表现出的创造力水平。

然而,就在过去的十年里,我们已经获得了用电脑做惊人事情的能力,就像机器人一样。随着 2010 年代的人工智能热潮,计算机现在可以识别人脸,在各种语言之间进行翻译,为你接听电话,并在世界上最复杂的棋盘游戏中击败玩家,等等。

突然间,我们必须面对这样一种可能性,即我们的创造力在宇宙中并不是无与伦比的。

那么,创造力不再是人类独有的特征了吗?人工智能能有创造力吗?

反对人工创造的论点

Computers enabled a 16 y/o me to create this (questionable) art

反对计算机有创造力的通常论点是,它们只能做被告知要做的事情。人类是给它们编程的人,它们只是给定指令的奴隶,并据此执行任务。他们是机器人——这个术语来自捷克语 robota ,字面意思是强迫劳动

另一方面,人类不受规则的约束,他们可以创新,跳出框框思考;他们很有创造力——无中生有。

但这一论点在两个层面上失败了。

首先,认为人类摆脱了“编程”的束缚是自私的,因为在现实中,我们就像计算机一样,固有地运行在一套基本规则上,只是我们的编程不是用 0 和 1,而是用 A、C、T 和 Gs。

正是这些相互对立的规则创造了我们定义为创造力的复杂性。然而,这同样适用于计算机。在目前可能是计算机科学中最热门的领域之一——机器学习中,计算机通过融合成千上万个人工神经元的计算来进行学习。人们很容易将计算机视为许多简单规则的组合,但复杂性只不过是复合的简单性。

其次,考虑一个 AI 如何学习。在当今最成功的方法之一中,计算机被输入了数千条(如果不是数百万条的话)与它要学习的任务相关的数据。例如,如果它需要检测图像中的肿瘤,它会被输入突出显示肿瘤的 x 光图像。它试图检测肿瘤,并根据它是对还是错,调整自己以更加准确。在看过数百万张这样的图像后,计算机学会了如何突出肿瘤的图像。

复杂只不过是复合的简单。

人类的学习方式几乎相同。我们反复尝试,基于我们是对还是错,我们调整我们的方法,直到我们达到一定的能力水平。

因此,即使我们的学习方法非常相似,当计算机做独特的事情时,我们经常会找到方法避免称之为创造性。

对创造性计算的偏见

当人类想出新奇和令人惊讶的东西时,它被视为创造性天才,被称为洞察力。

当计算机创造一些新奇和令人惊讶的东西时,我们认为创造者是有创造力的,或者认为它是危险的,需要人工智能来解释自己。

在许多情况下,这种解释是有根据的。如果一辆自动驾驶汽车做出了转向以避免杀死乘客或保持路线以避免杀死行人的决定,伤亡者的家属会想要一个解释,为什么人工智能做出了这个决定,即使得到这个问题的答案并不容易

A trolley problem for the 21st century

另一方面,当一个人工智能学习生成莫奈风格的绘画时会怎么样?我们认为人工智能和艺术家做同样的事情一样有创造力吗?通常,这种创造力被置之不理,理由是计算机用原始数学来做,而人类会用直觉来做。

事实上,每当计算机学会做一些我们认为只有人类才能做的事情时,我们就会改变我们的假设,认为这种活动对计算机来说很简单。

例如,自动字幕视频,下棋,甚至垃圾邮件检测曾经被认为是极其困难的,甚至是计算机不可能做到的,但现在是规范。从本质上说,我们对计算机已经取得的进步视而不见,因为我们一直通过贬低它们执行的任务来忽视它们的创造力。

重要的是要记住,与人类相比,人工智能已经走了多远。然而,了解他们的缺点也很重要。

人类和人工智能的区别

Perhaps one of the better style transfers I’ve made

我们人类在许多领域都有中等的才能,而人工智能只在一个极其狭窄的领域有着极高的能力。

人类可以学习走路、说话、理解、绘画、创作音乐、与他人交流等等。人工智能只能做其中一件事,但做得很好。

例如,研究人员训练一个人工智能将绘画风格转换为普通照片的内容。与人类不同,人工智能可以在一小时内数字化复制数千幅这些风格化的画作。然而,同样的人工智能不能做任何其他事情。

因此,有人可能会说,如果没有人类创造和部署人工智能来完成这些任务,人工智能什么也做不了——作为它们的创造者,它们的创造力实际上就是我们的创造力。

然而,如果没有人工智能中数千个神经元的数学计算值,这些画也不会被制作出来。

创造性的输出——绘画,既依赖于人工智能,也依赖于人类,所以它们不能在不包括另一个的情况下归于任何一个。

数字艺术家的崛起

Bloomberg’s Cover Featuring AI Art

人工智能和人类的这种结合在任何领域都比不上最典型的创造性学科——艺术。

有无数的艺术家结合他们的艺术洞察力和人工智能的创造能力,在网上创造惊人的创造力展示。

Twitter 用户 Manoloide 和 Robbie Barrat 利用电脑创作出令人惊叹的艺术作品;罗比·巴拉特制作的人工智能艺术甚至登上了彭博杂志的封面。

人工智能本身对哪种艺术好看没有任何品味或洞察力,但如果没有人工智能,人类就无法做出他们目前所做的令人惊叹的创作。

[## 马诺洛伊迪(@马诺洛伊迪)|推特

Manoloide 的最新推文(@manoloidee)。创意编码员和生成设计师。可供自由职业者使用…

twitter.com](https://twitter.com/manoloidee) [## 罗比·巴拉特(@DrBeef_) |推特

Robbie Barrat 的最新推文(@DrBeef_)。📺+👁//我爱机器学习🤖💭+艺术🎨+植物🌱🌷//就……

twitter.com](https://twitter.com/DrBeef_)

创造力的未来

总之,人们经常说计算机只能做它们被明确编程的事情,因此它们不可能有创造力。然而,随着机器学习的兴起,AI 现在可以学习某些技能。

这就是说,人工智能只会像它的训练一样好,除了它被训练的狭窄领域之外,它将无法在其他领域做任何事情。这需要人类组装数据集并为人工智能编码。人工智能在理解上也没有任何判断或细微差别。这是人类带来的技能。

所以,AI 和人类放在一起,可以成就大事。他们可以成为世界上最好的棋手,将世界名画的风格转移到成千上万的图像中,并为我们认为不可能解决的问题找到极具创造性的解决方案。

我将引用美国历史学家梅尔文·克兰兹伯格的一句话来总结这个观点

一场音乐会后,一位女士来到伟大的小提琴家弗里茨·克莱斯勒面前,激动地说:“大师,你的小提琴奏出了如此美妙的音乐。”克里斯勒把他的小提琴举到耳边说:“我没听到里面有任何音乐。”你看,乐器,硬件,小提琴本身,没有人的因素是没有用的。但是话说回来,没有乐器,克里斯勒就不可能创作音乐。

人工智能是未来创造力的画笔。对于它来说,创造它的艺术,它需要一个人类的使用者,而对于人类来说,创造艺术,它需要画笔的笔触。

AI 可能吗?

原文:https://towardsdatascience.com/can-ai-be-possible-880580febb17?source=collection_archive---------6-----------------------

https://en.wikipedia.org/wiki/The_Creation_of_Adam

如今,大多数被视为科技行业先驱的人都在谈论人工智能及其对我们日常生活的潜在或好或坏的影响。甚至他们中的一些人以人工智能可能对人类具有破坏性的方式来解释他们的观点。但在这个故事中,我不打算以社会学的方式讨论和参加这场辩论。因为,我想提一下,有没有可能通过模仿或不模仿来创造人工智能/以人工方式再造自然智能,在结论部分,我的想法只是简单地得出结论,这种社会学讨论目前是走向人工智能的不成熟的步骤。

在阐述我关于人工智能的可能性的想法之前,我想澄清一些主要的概念和定义,使我的想法更加精确。正如塞尔(1980)所说,有两种类型的人工智能。这些都是弱强 AI。弱 AI(我称之为“非常弱的 AI”)可以参考现在的机器学习应用。有一些系统可以通过使用监督或无监督的学习算法来预测/产生给定输入的输出,而无需显式编程。事实上,人工智能炒作被这种弱人工智能加速了,当人们谈论智能系统时,他们指的是弱人工智能,而不是有意的强人工智能。另一方面,强人工智能意味着类似人类的系统,包括自我意识和意识等。(我也不打算定义这些术语,因为有很多数百页的书籍试图定义它,它们的成功是值得怀疑的,但所有人都“理解”我的意思)。当我听到一个流行词“人工智能”时,不像其他人,我只想到强人工智能。我相信技术专家喜欢谈论人工智能(指弱人工智能),以关注和声称它具有自我意识,并改变我们的整个生活方式甚至人类,因为当人们被鼓励想象机器人做和我们完全一样的事情时,他们是迷人的(世界上所有人听到人工智能时,只有三件事总是迷人的,外星人,金钱)。

但这是真的吗?,我对此表示怀疑。让我们讨论一下深度学习作为创造人工智能的最合理和可行的计算视角。整个软件行业试图通过提供容量、存储、软件框架等来支持神经网络。我应该承认,我也是深度神经网络的粉丝,因为它有可能彻底改变我们的生活方式(我知道作为一名计算机科学家,对某些东西着迷是错误的)。但这并不意味着深度学习是创造由意识组成的人工智能的最合适的方法。例如,您有 1 TB 的猫图像,并训练您的卷积神经网络,您的系统通过预测世界各地不同图像中的整只猫来正常工作。你的系统可能看起来很智能,因为你的系统是猫的专家。然而,当我试着给狗用的时候。你的答案是显而易见的:我们可以用狗来训练这个神经系统,它现在成为了狗的专家。但我们应该承认,在地球的生态生活中,即使是最简单的生物也有这样的能力,我不是在说已经进化了数百万年的哺乳动物(我们为恐龙的花生大小的大脑感到遗憾,相反,与我们在认知任务方面的深层神经网络相比,它们可以被视为天才)。我仍然不会通过谈论意识或语言习得来放松我的辩护。

另一件事是为什么深度学习和其他机器学习算法不能创造强大的人工智能,它们受限于梯度下降及其衍生。我知道今天最优化的唯一解决方案是梯度下降,但它只存在于一些维微积分和一些图形中。我不相信我们复杂的大脑是以这种方式工作的(我们应该承认,我们没有需要解决的局部最小值问题)。

为了阐明我们为什么远离 AI,我想提一下关于视觉认知。我选择它是因为它似乎是最接近的外围模块,我们可以创建它的计算算法。有许多计算机科学家致力于这一课题,以创建/开发一种能够识别类似于我们视觉系统的物体的软件或算法。其中一些人声称他们是成功的。是吗?。我们的视觉系统通过语义构建来工作。

http://cogprints.org/442/1/node1.html

例如,如上所述,每一个健康的人通过构建矩形障碍物后有一个圆来构建 B 和 D。我们的视觉认知已经进化到即使物体被遮挡也能理解它们。因为我们可以从语义上构造对象,而不是使用一些预先训练好的机制。视觉搜索也是另一个非常困难的问题(即使与其他认知任务相比似乎很容易),从计算的角度来看,我们还远远没有克服。因此,尽管深度神经网络架构看起来像我们的神经网络系统。它看起来只是在类比,而不是功能。

在解释了为什么当前创建人工智能的方法不够充分以及人们在谈论人工智能时指的是什么之后,我想深入更抽象的方面,以揭示我们如何才能创建强大的人工智能。

我不是数学家,也不打算对哥德尔的不完全性定理做详尽的解释。但简单地说,我们试图通过使用我们的理解和创造机制来理解和创造类似人类的智能。系统试图理解自己。这是一项递归任务,我们的能力有限。这就是为什么,哲学辩论陷入了一种定性,无法超越这种定性(Dennet(1971)的立场解释似乎是合理的,但没有线索表明我们如何才能用数学建模)。但是我们有一种强大的表达语言,可以超越我们的思维能力:数学。例如,根据爱因斯坦的相对论,时间是第四维,而根据量子物理学,可能还有其他维度。但是从进化的角度来看,我们已经进化到生活在三维空间。因为既然我们是狩猎采集者,仅仅通过适应三维空间就足以生存和进化。虽然我们不能把时间想象成一个维度,但我们有能力用数学来表达它。此外,我相信,虽然我们不能把时间想象成一个维度,但我们的大脑在没有通知我们的意识部分的情况下可以做到。让我们把我的话解释得更清楚些,即使我们没有想象时间的能力,我们的大脑意识到时间是一个维度(我试图在下一个故事中证明我的说法),接受时间是一个维度的唯一解决方案是使用数学。我们正试图创造类似人类的智能(强人工智能),而不处理时间维度,但根据我的说法,我们应该这样做,即使是在深度学习中。因为,鸟类知道他们应该在“时间”到来时迁徙,另一方面,我们的神经网络不知道三秒钟前发生了什么。

但是出现了另一个问题,即当前的计算物理体系结构(计算机)不适于为人工智能的创造而设计,这是一个障碍。它们被保存在二进制环境中,当事物可以用二进制形式表示时,计算机才具有表示能力。这就带来了为什么恐龙比我们的神经网络聪明。

总而言之,你可以叫我物理学家,但人类是基于空间法则的。为了揭示包括黑洞、上帝粒子、暗物质在内的整个空间规律,我们应该使用数学。同样的规则也适用于自我意识。但是,即使我们创造了类似人类智能的数学和计算公式,我们也应该尝试不同的计算架构,而不是当前的计算机(如今量子计算机似乎是这方面的更好候选)。我们现在似乎还不能创造出强大的人工智能,总有一天会的。

人工智能能做 10 分钟的核磁共振吗?

原文:https://towardsdatascience.com/can-ai-enable-a-10-minute-mri-77218f0121fe?source=collection_archive---------4-----------------------

MRI 机器(磁共振成像)是一头笨重的野兽。站在超过 7 英尺高,像一辆家用汽车一样宽,重量超过一吨,不断发出令人不安的滴答“嘶嘶”声,不完全是一件对病人友好的医疗设备。

也可能是致命的。任何近在咫尺的铁磁性物体都会以加速的速度被强大的磁场吸走,消灭其路径上的任何东西。再加上你必须躺在其中的导致幽闭恐惧症的隧道(大约 60-70 厘米宽,平躺时刚好够你的鼻子通过),它一旦启动就会发出令人震惊的嘈杂混乱的撞击声,加上在整个过程中(长达一个小时)需要绝对静止不动,你就可以开始理解为什么病人对他们的 MRI 扫描有点紧张了。

一位病人向我描述它为“一个活棺材……当死神从另一边大声撞击时,我们有足够的时间去思考人生和来世”。

那么,为什么我们医生要让我们的病人经历这种经历呢?不是残忍,而是善良。核磁共振成像是医学技术的现代奇迹,是英国人引以为豪的发明,它让临床医生可以看到人体内部的精致细节,而没有 X 射线或 CT 扫描带来的任何副作用或辐射风险。人体解剖很大程度上是基于水的(氢和氧原子),磁共振利用这种生化组成,通过使用强大的磁场梯度来控制体内每个氢原子的方向,在释放它们之前将它们排列在一个统一的方向上,并让它们以只有微调接收器才能检测到的频率旋转。它背后的物理学是复杂而令人震惊的,由此产生的图像是非常简单的惊人。

病人为这种优秀所必须付出的小小代价是长时间呆在被嘈杂噪音包围的静止的禁闭室内。

目前…

在匹兹堡举行的最后一次年度医学成像信息学学会 (SIIM)会议 2017 上,学者和医生聚集在一起讨论放射学的最新研究。展出了数百张科学海报和演示文稿,来自医学成像所有子领域的专家们带来了最新的理论和突破。一个评委小组宣布第一名获奖的研究海报来自宾夕法尼亚大学,题为“优化低剂量计算机断层扫描数据的机器学习算法的诊断质量”(Cross 等人,U Penn)。

这张海报简单明了,描述了 CT 成像中的一个巨大突破,这是一种基于 X 射线辐射的成像方式。他们使用获得专利的 FDA 批准的算法来评估算法增强的低剂量 CT 图像的诊断质量。实质上,CT 扫描是在超低辐射剂量下进行的,几乎相当于简单的胸部 X 射线,并与正常的高剂量 CT 图像进行比较。他们发现 91%的 AI 增强低剂量图像被放射科医生评估为诊断性的,而只有 28%的未增强图像是诊断性的。

这类似于侦探剧里的场景,剧中人物看着屏幕上模糊的闭路电视镜头或照片,有人大喊“增强!”IT 人员神奇地敲敲键盘,图像立刻变得非常清晰。只不过这是真的,而且对 CT 图像有效。更好的是,它可以处理来自任何供应商的辐射剂量远低于标准技术的 CT 图像。

该算法的开发人员(PixelShine,来自 Sunnyvale 的 pre-Series B 初创公司,名为 Algomedica )声称,原始噪声功率谱(所有频率的噪声纹理)完全保持不变,同时通过降低噪声幅度来提高诊断图像质量,这是典型的剂量减少技术(如迭代重建)无法有效做到的。(事实上,使用的重建迭代次数越多,图像质量就越差。)但他们的算法并非如此——看看下面的例子…

Left: Standard high dose CT at 12.4mGy. Middle: Ultra-low dose CT at 1.3mGy. Right: AI-enhanced ultra-low dose CT at 1.3mGy. Diagnostic image quality between the left and right images was rated as comparable by independent radiologists, despite a significant dose reduction of 11.1mGy. The middle image is noisy and non-diagnostic. Images courtesy of Algomedica.

这种技术的含义可能会改变游戏规则。如果被证明能够在不损失临床重要细节的情况下稳定工作,那么就有可能将标准 CT 辐射量降低几个数量级。目前的辐射剂量,取决于被扫描的身体部位和其他因素,大致相当于在切尔诺贝利事故现场呆一个小时所受到的辐射量(见下图)。这不足以构成任何重大风险,但多次扫描将随着时间的推移增加个体风险,如组织损伤和诱发新的癌症。事实上,为了保持放射科医生期望的图像质量,ct 扫描仪的供应商受到一种不正当的激励而不是减少太多剂量(尽管他们确实提供一些减少剂量的技术)。然而,通过执行超低剂量 CT,然后使用人工智能对图像进行后处理,这些风险可能会大大降低,特别是对儿童而言,使辐射剂量接近几乎可以忽略不计(例如,相当于长途飞行穿越美国的辐射量)。此外,理论上这可以通过消除对昂贵的高性能组件的需求来降低 CT 扫描仪的成本,这也是大供应商可能不喜欢的。这才是真正的颠覆。

辐射安全领域有一些指导原则,被称为 ALARP & ALARA (尽可能低的合理可行/可实现水平),即医疗程序的辐射暴露必须尽可能低,同时仍能保持诊断效用。深度学习算法在增强超低剂量 CT 方面的新潜力可能会重新定义我们认为实用和可实现的东西。蛋糕上的樱桃是,这些算法可以在任何 CT 供应商生产的任何剂量的图像上工作,这意味着可扩展性和采用是需要克服的低障碍。我期待着临床试验的结果,以确定这些算法的有效性。

Image courtesy of xkcd.com

那么,这如何转化为 10 分钟的核磁共振成像呢?

Algomedica 也在使用深度学习网络进行研究,以增强欠采样的 MRI 图像数据。CT 有辐射的缺点,MRI 有采集时间延长的缺点。如果能够开发出算法来增强在缩短的时间帧内产生的噪声、颗粒状欠采样 MRI 图像,那么就有可能将花费在 MRI 扫描仪上的时间减少 2/3。客观地说,腰椎核磁共振成像的标准研究需要大约 30 分钟。深度学习算法可以将这一时间缩短到仅仅 10 分钟。这比花在听死神敲打你的临时棺材上的时间要少得多!

深度学习应用的研究在该领域相对年轻,在纽卡斯尔国王学院都有一些活动,但在其他地方与深度学习相关的结果很少发表(来自一个中国小组的【2012 年的这篇论文是该领域最早的论文之一,但没有使用 DL)。使用稀疏图像数据采集来减少 MR 次数是可以实现和可用的,但并没有达到深度学习承诺的结果。例如,就在最近,斯坦福大学的研究人员报告了 PET(正电子发射断层扫描)的一些结果,放射性示踪剂剂量减少了 99%。这与英国尤其相关,英国有可能脱离欧洲原子能共同体,成为英国退出欧盟的一部分,因此无法获得 PET 成像所需的大量放射性同位素。

毫无疑问,PET、MR 和 CT 扫描仪的大供应商也将意识到这一潜在的利基——他们毕竟已经引入了品牌特定的剂量减少技术(如 CT 的迭代重建)——并且很快将开始竞赛,以找出谁能够在最短的时间内提供最佳质量的 MRI 图像,并以最低的辐射剂量提供 PET 和 CT。这项工作当然需要高性能计算基础设施的支持,因为 MRI 数据比其他成像模式大得多。它还需要放射科医生的大量输入,以提供可接受的图像质量水平建议,以确保诊断和临床安全,以及医学物理学家的建议,以调整扫描仪的采集参数,但如果要实现最终目标,这些技术和合作挑战是值得克服的。

MRI 吞吐量提高了 3 倍

假设该技术被证明是可行的,那么将 MRI 患者吞吐量增加三倍肯定会对成像研究的等待时间产生显著的积极影响,特别是对于肌肉骨骼问题和癌症,这是 MR 成像的主要内容。同样,减少辐射暴露将使 CT 扫描的使用增加和更加自由。在医院里,我们甚至可以看到“平片”标准 X 射线的减少,因为 MR 和 CT 都成为了首选方式。我当然可以想象这样的场景,例如,在一个& E 怀疑手腕骨折直接进行快速核磁共振扫描,呼吸急促的患者避免胸部 x 光检查,直接进行低剂量 CT 胸部检查。PET-CT 可能会成为医院癌症诊断的首选检查手段,而不是现在的附属品。这项技术可能还会增加对某些身体部位的小型专用扫描仪的需求——脚踝/膝盖 MR 机器不需要像它的全身同类产品一样大,而大脑 CT 扫描仪现在可以安装在救护车内,以当前辐射剂量的一小部分提供对威胁生命状况的急性成像。

当然,这种开发和实现必须通过为周围的基础设施提供更多的资源来支持。花在这里的钱将会带来预期的节省。为了以更高的吞吐量操作设备(放射技师)和报告增加的图像量(放射科医生——除非人工智能图像感知算法接管,但这是一个单独的论点!)都需要增加人员。).还需要考虑改进预约安排,以适应增加的吞吐量,我们甚至可能需要更大的病人等候区和更好的设施,以便让病人换上病号服和进出扫描仪!

在我看来,所有这些都是有可能的,但要实现这一目标需要付出艰苦的努力。尽管有争议的算法仍处于临床验证阶段,但这项研究肯定会取得进展。我希望看到更多的医院在早期阶段参与这类工作,进行更多的试验。

在此之前,我们需要时间来节省时间、拯救生命和提高护理水平。

如果你和我一样对放射学人工智能的未来感到兴奋,并想讨论这些想法,请保持联系。我在推特上 @drhughharvey

如果你喜欢这篇文章,点击推荐并分享它会很有帮助。

关于作者:

Harvey 博士是一名委员会认证的放射科医师和临床学者,在英国国民医疗服务体系和欧洲领先的癌症研究机构 ICR 接受过培训,并两次获得年度科学作家奖。他曾在 Babylon Health 工作,领导监管事务团队,在人工智能支持的分诊服务中获得了世界第一的 CE 标记,现在是顾问放射科医生,皇家放射学家学会信息学委员会成员,以及人工智能初创公司的顾问,包括 Algomedica 和 Kheiron Medical。

AI 能否重塑机场卓越?

原文:https://towardsdatascience.com/can-ai-reinvent-airport-excellence-bbf581939c4e?source=collection_archive---------19-----------------------

Photo credits : International Airport Review

如果航班调节着机场的心跳,那么管理就是它的灵魂。

几乎在任何地方,管理层都可以利用数据来提高机场服务质量。开放数据的集成可以减少进入机场和航站楼登机口的排队时间。更好地利用信息可以促进飞机、乘客和物资的实时流量预测。通过更深入地了解客户、员工部署和资源分配,机器学习可能是优化流程的关键。随着机场从航站楼向多模式商务和休闲中心发展,人工智能可以成为收入机会的来源。将有利可图的大数据和人工智能应用于机场管理的关键成功因素是什么?

大数据方法解决了改善机场流程的五大挑战。数量机场管理数据,传统上与其他行业相比并不多,但现在由于安全和监管限制而呈指数级增长。随着数据科学团队希望更好地了解飞机、资源和人员的移动,数据的多样性正成为一个真正的挑战。随着自动化空侧操作成为现实,数据的速度也成为一个紧迫的问题。随着管理团队努力理解实时数据、数据科学和预测分析的重要性,数据的准确性现在是一个关键的成功因素。最后,数据的与改善个人和集体航空旅行体验的应用直接相关。

人工智能的商业价值与其降低商业预测成本和减少运营过程中的可变性的潜力相关联。人工智能的应用已经证明了它们在自动化计划、组织和预算方面的价值。在不久的将来,机场管理层将专注于定义和评估人工智能的方向和采用率,以优化主动员工和预测人工智能代理的团队。随着机场从航站楼演变为多模式服务中心,经理们今天需要思考机场有一天可能会是什么样子,并问自己人工智能实验在什么程度上可以证实这种愿景。

不幸的是,从这里到那里的飞行路线没有清晰的轨迹。今天的大多数机场离人工智能就绪的组织还很远。机场不是传统意义上的连贯组织,而是复杂的适应系统,容纳了多个业务,它们具有相互竞争的逻辑、网络和目标。“机场”不仅接待航空公司制造商、运营商、监管者,还接待共享机场空间的零售、餐饮、休闲和娱乐实体。这些企业对经济周期、政治和环境压力、社会人口统计和技术创新的反应可能大不相同。几乎没有共同的流程,没有单一的控制点,也没有创建世界级机场的“唯一最佳方式”。利用数据或开发人工智能应用程序,必须考虑机场的现状以及未来的发展趋势。

在这样的背景下,过程挖掘可能是数据科学最有用的应用之一。流程挖掘是流程管理领域的一系列技术,支持基于不同机场技术留下的数据线索的业务流程分析。流程挖掘不是试图开发机场应该如何运营的更好模型,而是试图将运营流程与不同客户、代理和经理的互动方式相协调。这种“翻转”过程模型的目标是从经验中学习,而不是从专业知识中学习。虽然在这一领域的第一次实验主要集中在行李处理和队列管理上,但人们可以预期,过程挖掘技术将在解决机场当局目前面临的许多挑战方面产生红利。

人工智能的最终目的不是让机器变得更聪明,而是帮助管理者在他们的组织环境中做出更好的决策。管理决策不是基于数据,而是基于对数据的理解,这些数据本身就受到移情、直觉、想象力和情感的影响。在复杂的机场中,管理层根据可用数据与运营伙伴协商共同决策。如果机器学习旨在突出数据集的相似性,管理层将继续关注运营流程中异常(异常值)的重要性。与过去一样,在可预见的未来,管理人员的表现将不会根据他或她在电脑后对数据的处理来评估,而是根据他们在同事和客户面前对信息的处理能力来评估。

我将在法兰克福机场卓越运营和自动化 IQPC 会议上讨论和发展这些主张。我们将与其他会议发言人一起讨论如何使 IT 流程适应实际的机场和航空公司实践。我们将扩展讨论,探索人类和人工智能之间的相互关系如何真正为机场生态系统增加价值。我期待在法兰克福见到你。

商业分析研究所的 Lee SCHLENKER 博士

2018 年 10 月 12 日

Lee Schlenker 是商业分析和社区管理教授,也是 http://baieurope.com 商业分析研究所的负责人。他的 LinkedIn 个人资料可以在查看你可以在的 Twitter 上关注白

人工智能能帮助你找到爱情吗:理解婚介行业

原文:https://towardsdatascience.com/can-artificial-intelligence-help-you-find-love-understanding-the-business-of-matchmaking-2b51a8cc8f76?source=collection_archive---------5-----------------------

我认为我这一代人是极其幸运的一代,他们处在由技术革命推动的世界巨变的尖端。我们伴随着盒式录像带和录音机、有线电话和大盒子电脑、充满书香的大图书馆长大。然后,几乎不知不觉地,我们过渡到了 iPods 和 YouTube,智能手机和 iPads 和电子书。我猜想,数百年或数千年后,当人们回头看时,我们将正好处于这条线的中间,这条线不亚于现代版的公元前和公元——“谷歌之前-苹果-脸书”和“谷歌之后-苹果-脸书”。

也许更微妙,但更重要的是,我们也正处于风口浪尖的变化是技术的到来在社会学上意味着什么。个人关系变了。互动的模式和渠道已经演变。“做朋友”有了不同的含义。一个看不见的在线网络越来越多地定义了社会。当我思考这个问题时,它让我想到了另一个方面——坠入爱河的概念和行为是否也发生了变化?

你还记得在那些简单的日子里,爱是如何到来的吗?相亲是由朋友和了解你的人安排的。你和人们面对面交流,看看你们是否有共同的兴趣和信仰。相容性是由相处时间决定的。切入今天的世界——在为你寻找完美伴侣的过程中,数据科学和人工智能越来越多地取代了你的朋友、家人、同事、熟人甚至你自己的判断。

交战规则(一语双关)围绕两个轴心发生了变化:

  1. 你如何连接潜在的爱情兴趣,即介绍和交流的渠道。现在物理会议来的晚多了。你的手机、平板电脑或电脑是你发现和建立潜在浪漫关系的大厦。你用手指轻轻一划就能做出选择。你通过屏幕说话,表情符号代表真实的表情。你希望爱情开花结果。
  2. 你和谁联系,也就是你可以从中选择的一群人。对我来说,这是更明显的变化,在某些方面也更可怕。不再是你或你认识的人提出潜在的匹配。机器已经取代了这个角色。

在当前的范式中,人——人类和个人——可以被参数化,归结为一个“特征集”,然后人工智能驱动的算法可以找到最“最佳匹配”,即你最有可能与谁兼容。让我们把它分解一下,看看这个“爱的事业”到底是如何在幕后运作的。

推荐引擎如今被广泛应用于我们生活的方方面面。当你在亚马逊上购物时,你会得到关于你可能购买的商品的建议,这就是推荐引擎在起作用。当网飞向你推荐你可能喜欢的电影时,情况也是如此。这种应用的清单今天是无止境的。简单地说,这些引擎通常以三种方式之一工作:

  • 历史趋势:基于人 X 过去的行为,引擎会尝试预测 X 未来可能做出的选择的可能性。
  • “像你一样的人”:在这种方法中,首先基于机器学习的聚类算法将确定倾向于相似的人群。相似性可以通过行为(例如,他们购买或浏览什么,他们如何支付,购买频率,以及无数其他类似的事情)或特征(例如,他们的年龄、性别、地点等)来定义。)或者两者都有。然后,推荐引擎不仅会根据 X 过去做过的事情,还会根据其他“喜欢 X”的人做过的事情来预测 X 的选择。
  • 【基于内容】:这种方法更关注目标项目及其特征,而不是人的特征。所以在网飞电影的例子中,这将转化为识别 X 喜欢看的电影的特征(类型、长度、语言、年代、演员等。)来确定他可能感兴趣的内容。

实际上,大多数推荐引擎可能会混合使用以上所有方式。反馈越多,引擎就能越准确地预测行为。反馈实质上是特定的预测(也称为推荐)是否被接受。

现在,让我们回到爱情的话题上。这种相似之处很容易画出来。

  • 不再是被预测有可能被接受的物品或电影,而是 X 可能与之一见如故的人。
  • 历史趋势指的是任何关于 X 以前关系的数据。
  • 喜欢 X '的人将根据 X 自己的行为和特征来确定,例如年龄、种族、教育程度、地点、就业状况、食物偏好、爱好、眼睛颜色、体型、身高等。
  • 目标项目特征现在将指属于预期目标列表的个体中的这些相同特征。

这些特征的列表越长,算法的效果就越好。请记住,X 没有必要明确提供这些数据——在我们今天生活的世界中,大多数这些信息都以某种方式、形式或形式在互联网上围绕着每个人流动——这只是关于访问和挖掘这些信息。

一旦这些数据点可用,人工智能算法就可以施展魔法,为每个潜在客户分配可能性或概率分数,以确定 X 最有可能选择和喜欢的人。和其他情况一样,系统会自我学习,因此它会随着每次反馈变得越来越好,即每次 X 接受或拒绝建议的匹配。

你可能会同意,这背后的科学并不难理解。但这种暗示并不一定令人舒服。理论上,这种方法实际上可以非常好地找到你的爱。像我一样经常网上购物的人可能会同意,亚马逊似乎比你自己更清楚你会对什么感兴趣。它非常好用。这和做媒很像。

这里有一个陷阱——这整个方法有一个潜在的假设,即寻找爱情是基于规则或逻辑的。这就是我个人认为婚介业务永远无法像几乎所有其他应用程序那样从人工智能中获益的地方。因为在现实中,或者说我愿意相信,寻找爱情并不总是合乎逻辑的。因此,尽管机器和人工智能越来越多地扩散到我们生活的各个方面,但我坚信,在这个特定的领域,神秘和神奇可能会挥之不去。

大数据能给农业带来巨大回报吗?

原文:https://towardsdatascience.com/can-big-data-deliver-big-returns-for-agriculture-8800d31440a?source=collection_archive---------0-----------------------

你好 2017!这是一个大胆的新年,也是开始一些新习惯的好时机。我围绕太阳旋转的目标之一是写更多我热爱的事情。

尤其是……技术。农业。初创企业。和其他相关的东西。

我喜欢阅读这些话题,但是我没有看到足够的关于它们的文章。特别是农业科技。为什么会这样?

所以我想在 2017 年,我将停止抱怨,开始贡献我自己在农业科技领域的经验和教训。这是一个令人兴奋且快速增长的领域,需要更多的关注。我希望我能帮助照亮一些光。

同时,我会分享我对创办农业科技公司其他方面的想法。是的,所有这些其他的(有时是混乱的)幕后活动都是将想法转化为市场所必需的。比如创新、犯过的错误、吸取的教训、建立一个团队/产品,以及创办、运营和发展一家科技公司的基本要素。

四年前,我创办了 AgDNA ,并成功地走过了艰难的创业之路,建立了一家正在崛起的伟大的农业科技公司。我也将分享一些我在硅谷和风险投资领域的经历。虽然 AgDNA 没有筹集风险投资基金(我们选择保持私有),但我也学到了很多关于 AgTech 创业场景的那一面。

因此,为了不跑题,不让人觉得我是在推销,我想从大数据这个话题以及它如何惠及农业开始。我希望这将是有趣的农业科技系列文章的第一篇。

享受吧。

大数据的前景

你可能听说过科技行业中提到的术语大数据。这是一个经常被放错地方的标题流行语。在农业方面尤其如此。

大数据通常以数量、多样性、速度、可变性和准确性为特征。农业绝对有这些!

数量——仅美国就有 3.5 亿英亩农场。

多样性——不同的作物类型、拖拉机、技术提供商、数据格式。

速度—拖拉机现在每秒钟可以在整个田地中记录多达 5 次的数百个数据点。

可变性——土壤类型、降雨模式、温度、风暴事件,还需要我多说吗!

真实性——糟糕的手机连接、恶劣的环境条件、大量的断点。

农业绝对有资格成为大数据参与者!

农业部门在利用大数据技术方面处于有利地位,许多公司正在为其成功做出贡献。所有主要的拖拉机制造商都在他们的设备中嵌入了传感器,将他们的机器连接到云端。科学气象研究人员创造了专门针对农业的天气解决方案。出现了无数的初创公司,它们开发各种各样的田间传感器,以捕捉土壤、水分、作物和其他关键数据点。

然而,最终结果往往是数据过载。

除此之外,气候模式的变化也导致了复杂多变的作物生产环境。数据过载会很快导致数据混乱。

这是大数据解决方案真正大放异彩的地方。

大数据幻觉

各地的农业科技公司都在谈论他们的大数据解决方案、云、数据分析和其他技术术语,这些听起来很聪明,但没有充分说明对种植者的真正价值。现在,我确信这些公司中有许多是出于好意,但从我的观察来看,他们中的许多人甚至没有触及我们新兴的大数据世界需要什么或可能什么的表面。

收集大量数据是一回事。将它转化为可操作的见解,进而转化为种植者更高的利润率,则完全是另一回事。农业科技公司必须投入艰苦的努力,代表客户爬上从数据到知识的金字塔。最终我们必须获得智慧,但这是另一篇文章本身。

攀登金字塔是一个滑动的斜坡,有许多移动的部分来开发所需的大数据解决方案,从季节开始到收获,一路上展示明确的经济价值。

DIKW Pyramid Source: https://en.wikipedia.org/wiki/DIKW_pyramid

大数据机遇

那么什么是大数据,为什么它对农业如此重要?

大数据本质上是使用非常强大的计算机来执行数据分析任务,这些任务无法由人类在使用传统软件的标准计算机上轻松执行。由于持续不断的数据流经常 24/7 全天候传输,而且不断变化的信息涉及气候、作物、空间变异性、农业设备和其他条件监控传感器,因此自动化和智能化的大数据解决方案至关重要。

大数据可以开始揭示对任何个人来说都不明显的问题和趋势。复杂的数学技术,如机器学习也在这里发挥作用(我将把它作为另一个话题)。

不用说,确定这些趋势和见解对农业部门来说是至关重要的结果。对于一些种植者来说,耕作是艰苦的,有时甚至是与世隔绝的。”。

通常情况下,种植者会根据他们传统的作物管理方法、农学家的建议以及在当地咖啡店的谈话来为他们的农场做出决策。但是你怎么知道是否有一个更优的决策是基于以前的经验在其他地方做出的呢?

这就是大数据和基准测试可以发挥作用的地方。

大数据的承诺

想象一下,一个种植者准备在他的农场种植玉米,土壤类型从轻沙质土壤(持水能力差)到重粘土(持水能力高)。除此之外,还有一些有陡峭山脊和山坡的田地,以及一些排水不畅的大面积平地。已经有许多关于地形、地表水管理的考虑,我们甚至还没有开始处理天气!

这种情况可能会进一步加剧,因为雨季开始时天气潮湿寒冷,在收获前雨水很少,天气相当干燥。围绕种植什么、如何管理作物以及在整个季节采取什么行动的决策是复杂的。也很难知道赛季结束后会发生什么。

是的,农业是艰苦的!

大数据不寻找因果关系。相反,它寻找趋势。大数据并不试图告诉你为什么会出现特定的结果,但它可以告诉你结果是最佳的,并且代表了非常广泛的数据集。把它想象成一个非常大的现场试验。

通过汇总大量具有相似特征的农场的结果,大数据可以寻找以前不明显的趋势。这可以是根据预测的气候条件将种子品种与特定的土壤类型相匹配。同样的种子品种在其他土壤类型或不同的天气模式下可能表现得非常不同。

大数据平台及其底层算法的作用是分析这些信息,并确定哪些种子品种将在各种土壤类型和生长条件下实现最高产量。这最大限度地减少了每个种植者进行田间试验的需要,而是依赖于大型匿名真实数据集的结果。

*优化种子选择是大数据解决方案的众多可能结果之一。

大数据隐私

关于数据隐私和安全已经写了很多,这是正确的。然而,对于那些选择追求大数据道路并选择匿名分享数据的种植者来说,他们将获得巨大的回报价值。在当今大宗商品价格低迷的经济环境下,这一信息可能意味着是实现盈利,还是安排与当地银行经理的另一次会面。

不以销售其他产品(或数据)为经济动机的独立公司正带头冲锋陷阵。聚合大数据解决方案的投资回报(ROI)越来越有价值,不容忽视,这些解决方案可提供用于提供可操作见解的公正决策信息。

大数据的未来

良好的农业通常是关于风险管理的。种什么。如何管理。何时收割。这些都是至关重要的决定,而且做出这些决定的环境也每年都在变化。不同的杂交种子,新的种植技术,化学和肥料解决方案的变化,它们都在决策过程中发挥作用。天气就更不用说了!

大数据是农民和整个行业解决问题并取得阶段性成果的唯一途径。随着大量连续数据(有时是非结构化数据)源源不断地流向云,大数据算法将处理这些数据,以寻求洞察力。

最终,在种植者知道该问什么问题之前,大数据就会给出答案。

除了大数据在农业中的作用,下一代软件系统的工作流程和易用性也得到了简化。至关重要的是,整个行业要继续改进技术解决方案,使其易于农民使用。无论拖拉机是红色、黄色、蓝色还是绿色,工具都必须能够跨不同制造商的数据集进行互操作。玉米、小麦或水稻,数据互操作性是关键。

短期内,农业的经济状况可能会继续艰难。然而,长期前景是光明的。大数据等下一代技术正在进入农业生态系统,将为各地的种植者带来巨大的经济价值并显著改善风险管理。

因此,下次你在媒体上提到大数据这个术语时,请注意,因为它将成为未来几年农场管理的重要组成部分。

如果处理得当,大数据甚至不会显而易见。这将是一个简单的提醒,在你的智能手机开始影响产量之前,你有一个值得检查的潜在问题。

一个简单的消息,可能会节省数千美元!

关于 AgDNA

AgDNA 正在通过智能软件帮助种植者最大限度地提高每英亩土地的收益,从而塑造农业的未来。它的企业级精准农业平台结合了数据科学和物联网(IoT ),帮助商业作物生产商提高产量、降低投入成本和最大化农场盈利能力。被 Lux Research 评为 2015 年十大最具创新性的公司,AgDNA 被认为是世界上最智能的农业平台之一。

"我能在你的电脑上训练我的模型吗?"

原文:https://towardsdatascience.com/can-i-train-my-model-on-your-computer-f59329eacd0?source=collection_archive---------6-----------------------

(Photo by Hal Gatewood on Unsplash)

对强大计算能力的需求

电脑擅长一件事:速度快。它们的速度足以进行光速计算。足以在瞬间将信息发送到全球各地。然而,它仍然不够快。软件和硬件之间的持续竞争仍在继续。随着硬件速度越来越快,我们的要求也越来越高。如果速度不够快,我们会要求更多的处理器进行并行计算。获得更快的处理器使我们能够推进数据科学的前沿。由于硬件的进步和可用性,人工智能可以在复杂的视频游戏中击败人类(这里是),合成音乐,让我们不要忘记在 youtube 视频中检测猫!

(Hardware used in OpenAI Five)

计算能力与人工智能的成功相关。你可以看到,在过去,机器学习的研究受到可用计算能力的限制。即使他们有大量的数据和我们今天使用的现代方法,他们也不能充分发挥他们的潜力。因此,机器学习和数据科学的应用和影响受到了限制。随着研究人员和从业者获得更多的计算能力,该领域随着先进的方法和有趣的应用而蓬勃发展。

(Hardware used in a study in 2006)

对极限的挫败感

如果你是机器学习或数据科学的从业者,你很有可能会遇到计算资源匮乏的烦恼。你等了多少次午夜来运行你的实验?你减少了多少次超参数搜索量,以便它能更快结束?这种限制对我来说是一个很大的挫折来源。就在这个月,我不得不放弃一个个人项目,因为它需要大量的资源。我要么为一个实验等待数周,要么在云服务上花费大量金钱。我还记得当我告诉经理该项目的每一次实验将花费 200 美元时,他的面部表情。我也多次看到有人,或者是他们中的一员,请求朋友或同事帮忙在他们不用的机器上运行一些实验。

睡眠装置

我被我在学术界时拥有的高性能集群宠坏了,在那里我可以并行运行数千个作业。但是当我离开的时候,我拥有的资源变得稀缺。当我在寻找更多的计算能力时,我意识到到处都有计算机,它们在相当长的时间里无所事事!我的同事每天下班后都会关掉电脑。我所有的设备,只是在晚上睡觉,什么也不做。我们所拥有的设备,每天在相当长的时间里只是“睡眠”而无所事事。

我们不断地浪费我们放在口袋和袋子里的资源。你的手机、电脑、智能电视和基本上任何有处理器的东西都是计算设备。他们会计算,这正是我们所需要的。问问你自己,在一天的循环中,你积极使用设备的时间有多长?最基本的例子就是夜间。每天晚上,我都会把手机连接起来充电,然后把它放在床头柜上,睡上几个小时,我也睡了。

使用“睡眠装置”的想法并不新鲜。欧洲核子研究中心有一个网络,人们可以捐赠他们的电脑给科学家使用。加密货币依赖于人们将其计算机连接到网络才能存活。尽管这个概念并不新颖,而且有一些可行的例子,但是问题还没有解决。当每个人都可以使用计算设备、电力和互联网,将他们的所有设备连接到计算网络,这是一件非常合乎逻辑的事情时,问题就解决了。

我们现在需要资源

我们作为数据科学家所需的资源现在已经有了。它们在人们的口袋里,在他们的床头柜上,在办公室上锁的柜子里。然而,我们无法访问它们。我们愿意为资源付费,但是资源是不可访问的。持有计算设备的大部分人并不知道它们的价值。他们可以将这些资源转化为金钱,但是缺少一个环节。

缺少的环节是在供应商和消费者之间。数据科学家希望消耗资源以换取金钱,我相信供应商希望通过在他们不使用设备时出租他们的设备来获得信用。我认为,当供应商和消费者之间的不平衡变得足够大,不可忽视时,双方之间的联系就会建立起来。在那之前,我会继续支付云服务费用,请求帮助使用下班后睡觉的电脑。

它能制图吗?

原文:https://towardsdatascience.com/can-it-chart-8bf6139f1ae8?source=collection_archive---------9-----------------------

注:我申请的链接可以在 这里 找到。输入歌曲及其对应的艺术家,看看它在 Billboard Hot-100 中的表现如何。中间的图表是每首歌曲的音频特征与普通公告牌歌曲的音频特征相比的指数。要查看艺术家的整体评价,请点按“艺术家页面”部分。

概述

在音乐行业,A&R 分部传统上负责通过“直觉”和依靠业内“引领潮流者”等方法来发掘人才。这对于希望成名的新艺术家来说可能是一个问题,但不一定有良好的关系。随着艺术家越来越多地使用社交媒体渠道,创作音乐的门槛越来越低,A&R 分部可能会在决策过程中受到阻碍。

但是,如果我们尝试自动化寻找新人才的过程会怎么样呢?作为一个初步的搜索工具,我们能找到有潜力成为下一个大事件的歌曲和艺术家吗?

我开发了一个名为“它能制图吗?”,它使用 Spotify 的歌曲特征来预测一首歌是否有能力出现在 BillBoard Hot 100 上。

方法学

对于我的目标变量,我想看看一首歌是否在公告牌百强排行榜上。热门 100 排行榜是美国歌曲的行业标准排行榜,主要基于销售、电台播放和在线流媒体。从商业的角度来看,如果你能找到一个有潜力进入 Billbaord Hot 100 的艺术家,你最终可以增加你的唱片公司的盈利能力。

这个项目是一个二元分类问题,有以下标签:

  • 第 0 类——“不会图表”
  • 第 1 类——“意志图表”

为了不错过“下一件大事”,我对 1 级回忆进行了大量优化。然而,找到被错误分类的歌曲是可以的,因为这些歌曲在以后的评估中可能会被认为是“荣誉奖”。

获取数据

在 SongFacts.com,我使用 BeautifulSoup,一个网络搜集库,获得了从 2010 年 1 月 1 日到 2018 年 5 月 6 日发行的歌曲列表。然后我把同一时期所有的 Billboard 热门 100 首歌都加入了 SongFacts.com 排行榜。从那里,我利用 Spotify API 为歌曲集提取音频功能和艺术家流派。

到最后,我有一个不平衡的类集合:类 0:类 1 = 4:1。

模特培训

当训练我的模型时,我希望我的模型有某种可解释性。虽然支持向量机乍看起来表现不错,但它们缺乏讲故事的能力。我决定采用逻辑回归,因为它在我的受试者操作特征曲线下的面积是所有模型中最高的。然而,我的回忆很低,所以我需要微调一些超参数。

在调整我的超参数以最大化召回率后,我能够将我的 1 类召回率提高到 78%。从这个模型中,我提取了特征系数,发现摇滚和独立艺术家不太可能出现在 Billboard Hot 100 上,但乡村艺术家更有可能出现。此外,一首歌越适合跳舞或越响亮,它就越有可能出现在 Billboard Hot 100 上。

精确度和召回率之间有一个内在的平衡,虽然精确度=召回率的平衡存在于 0.63 左右,但我想在不损失太多精确度的情况下尽可能提高召回率。通过将阈值从 0.5 移动到 0.46,我能够将 1 类召回率提高 7%,而精确度仅损失 2%。

注意:发布这个项目后,我研究了加权类,发现通过给类增加一个权重而不是“平衡”,我可以在不移动阈值的情况下实现 85%的召回率和 35%的准确率。

模型示例

我在五月初创建了这个项目,大约在那时幼稚的甘比诺的《这就是美国》出版了。我的模型预测这首歌有 85%的可能性会登上排行榜,它在2018 年 5 月 14 日的 Hot-100 排行榜上排名第一。还不错。

在另一个例子中,我的模型预测艾丽西亚·凯斯的《你不知道我的名字》不会出现在 Billboard Hot-100 上。然而,这首歌在 2004 年 1 月 31 日登上了公告牌百强榜的第三名。我的模特怎么会和这首歌差这么远?也许在 2000 年早期,流行的是 R & B 歌曲,而这些歌曲并不代表当前十年的流行音乐。将来,我需要将更多的歌曲放入数据集中,并淡化公告牌歌曲占所有歌曲的比例,以总体上代表音乐。

感谢阅读!

线性模型能预测一个足球运动员的价值吗?

原文:https://towardsdatascience.com/can-linear-models-predict-a-footballers-value-33d772211e5d?source=collection_archive---------2-----------------------

Photo by Emilio Garcia on Unsplash

本着 2018 年世界杯的精神,我决定展示我最近做的一个项目,它融合了我最强烈的两个兴趣——数据科学和足球!目的是看看在英超联赛中一名球员的受欢迎程度和他的市场价值之间是否有关系,因为仅仅通过他的统计数据很难恰当地评估一名球员的价值。一个简单的例子是防守型中场球员通常看起来做得更少但对任何球队都是非常有价值的。我还扯进了一些关于球员和前 6 名球队的有趣观察!

这里使用的数据是从各种来源搜集来的,包括 transfermrkt.com 和梦幻英超。它包含了 FPL 网站上列出的每支球队的所有球员,他们都有相应的市场价值。例如,transfermrkt.com 的 FPL 队名单上有麦克托米内,但他没有市场价值,这意味着他被排除在数据之外。这是 2017/18 赛季英超联赛所有球员的综合数据集,于 7 月 20 日得到确认。因此,可能会有一些后来签署的遗漏。

抓取使用了一些很酷的 RVest 和 Selenium 技术——点击此处了解更多细节。

一些初步分析

谁是 EPL 最有价值的球员?

正如所料,游戏中的一些最大的名字正在英格兰超级联赛中比赛。

谁是最受欢迎的球员?

鲁尼显然是第一名,他效力于曼联,是英超传奇人物。

市场价值分布

显然不是正态分布,但这是意料之中的。球队往往很少有精英球员,而在他们的阵容中有大量低+中价值球员。对球队前 15 名球员的分析可能看起来更像是正态分布,因为我们排除了低价值的边缘/青年球员。

前 6 名看起来有什么不同吗?

1 indicates top 6, 0 indicates other

有意思。前 6 名似乎有分散的球员,而其他人的大部分球员价值都在 1000 万以下(transfermrkt 的估值,不是我的)。

流行度分布

类似的市场价值分布,除了最后的两个异常值——韦恩·鲁尼和保罗·博格巴。虽然鲁尼已经是目前最知名的英格兰足球运动员,但他也打破了博比·查尔顿爵士保持的曼联进球最多的纪录。这一点,加上对他曼联生涯的不断猜测,无疑导致了他的页面浏览量的增加。另一方面,保罗·博格巴是严格审查的结合体(是世界上最昂贵的转会)(更新:不再是了!),回到曼联(可以肯定地看到人们在寻找他),以及他是一个非常有市场的,可见的球员的事实。

前 6 名与其他人

Graph 1 indicates top 6 teams, 0 indicates other teams

同样,排名前 6 的俱乐部似乎有着广泛的球员受欢迎程度。此外,韦恩鲁尼现在在埃弗顿,为其他球队解释离群值。

详细分析

显然,我试图建立的案例是,似乎有证据表明一个球员的市场价值与他的受欢迎程度相关联。这很有趣,因为在足球界,能力和表现是出了名的难以量化。这取决于位置、教练的战术、对手、联赛、你自己队友的能力等等。因此,给一个球员估价是非常困难的,尽管这是必须要做的。
像 WhoScored 这样的网站有每个球员每场比赛的分数,而 Fantasy Premier League 会在每个球员的头上贴上一个数值。看看受欢迎程度能否被用作能力的基本代表将会很有趣,这也是我将通过回归模型尝试的。

FPL 估价

FPL 价值和 transfermrkt 价值之间似乎有很好的一致,尽管 FPL 的估值显然是短期的,所以年龄不是一个重要因素。我期待看到更多球员出现在右下方——老球员,市场价值低,但 FPL 价值高,理论上像彼得·切赫和亚亚·图雷。也许有更好的方式来强调这一点。

这似乎是对的。如果 FPL 的价值等同于转会市场的价值,我们会看到一个恒定的比率,跨越年龄组。但事实上,最低的 FPL 价值是 400 万,非常年轻和未经证明的球员比例很低。同样,在另一端,老球员的市场价值很低,但他们在下个赛季仍然有价值。有趣的是远期交易的比率如何在超过 32 时跌落悬崖,这可能意味着它们的市场估值非常低。

随着年龄增长的市场价值

一般来说,老玩家的市场价值会更低,这是相当直观的。粗略的说明-

高价值玩家集中在 24-32 岁之间,在 27 岁左右达到顶峰。重要的是要注意,这绝不是线性关系,这就是为什么我在下面的回归模型中使用年龄类别。另一种方法是做一个变点回归,这意味着建立两个模型,其中一个模型的年龄=阈值。

谁在哪个位置进货?

曼城拥有潜力巨大的前锋和攻击型中场,但他们的防守非常薄弱(自从门迪、沃克和达尼洛到来后就没有了——但他们不在这个数据集中)。就位置优势而言,前六名的排名如何?

曼城的进攻总市值遥遥领先于其他球队。不过,他们和利物浦的后防明显较弱,哪个城市已经整改。曼联的德基和罗梅罗显然是 6 强中的佼佼者。

受欢迎程度是能力的代表

正如下一节所解释的,我们测试了能力和受欢迎程度之间存在关系的假设。能力很难通过绩效指标来衡量和比较。出于本节的目的,我假设 FPL 估值是一个公平的能力衡量标准。尽管这可能并不完美,我们还是应该能够阿瑟能力和声望之间的关系。

FPL 的估值和受欢迎程度之间似乎有一种很好的线性关系,只有几个明显的例外(韦恩·鲁尼,唉)。精彩!这将有助于下面的模型。

回归模型

主要目的是看看市场价值是否可以用知名度作为能力的代表来确定。一个玩家的市场价值可以直观地表示为-

市值~能力+职位+年龄

这应该理解为市值能力、职位年龄的函数。

后两个很容易观察到,但是能力是一个很难衡量的属性。有各种各样的衡量标准,但我决定用一个简单的指标来衡量——流行度(或者更具体地说,去年维基百科的页面浏览量)。我选择维基百科观点的原因如下-

  • 比 Twitter/脸书要好,因为它不依赖于玩家是否有个人资料。
  • 比脸书/Instagram 的粉丝要好,因为这些人也受到球员帖子的参与度的影响。
  • 很容易得到所需的时间框架——我想排除 5 月至 7 月,因为这将夸大 2016/17 赛季转会球员的受欢迎程度。

使用页面浏览量有其自身的问题与其他因素的相关性-

  1. 来自英格兰本土的球员可能会得到更多的点击率,因为他们在自己的主场联赛中比赛,即球员的国籍可能很重要。
  2. 不同类别的球员得到不同程度的关注——前锋肯定比后卫受欢迎得多!
  3. 新的签约可能会得到更多的关注,甚至超过转会期。
  4. 顶级俱乐部拥有更多的国际观众。
  5. 玩家可能会获得大量的点击率,因为在此之前他们几乎不为人知。想想 2016/17 赛季的马库斯·拉什福德。
  6. 长期受伤的球员可能只有很少的安打,仅仅是因为他们没有上场比赛。

在模型中,我控制 1–4,但不控制 5 和 6。5 和 6 都需要大量的工作来确定突破和长期伤害,这可能是有用的未来模型的补充。

对于因素 1-4:

  1. 检索每个玩家的国籍,并将其放入 4 个桶中:
  • 1 代表英国
  • 2 代表欧盟(英国退出欧盟将此作为自然分类)
  • 3 适用于美洲
  • 4 适用于世界其他地区

创建了一个名为region的新列,作为具有 4 个级别的因子。

  1. 包括用于页面视图和位置类别的交互术语。
  2. 标记了 2016/17 赛季的新签约,并与页面浏览量进行了互动。
  3. 创建了一个由曼联、曼城、切尔西、阿森纳、利物浦和热刺组成的专栏。这也与页面浏览量有关。

除了这些相互作用,年龄也作为一个分类变量包括在内(由于它与市场价值的非线性关系)。

数据集修改

  1. 新晋级的俱乐部被排除在数据之外,只是因为英超联赛提供了更高水平的宣传,而这些俱乐部在前一年没有接触过。
  2. 出于同样的原因,17/18 赛季来自国外的新援也被排除在外。但是,英超内部转会的球员会被保留。这意味着林德洛夫被排除在外,但卢卡库没有。
  3. 采用market_value的 sqrt 值,因为market_value是右尾重的,这可能导致异方差。
  4. 但是,这就导致了sqrt(market_value)page_views的关系看起来是这样的——

我也在page_views上应用了一个 sqrt 转换,得到了下面的图表

这看起来大致是线性的,韦恩·鲁尼是个例外。

现在对该数据应用多元线性回归模型得到的 R 值超过 70%!此外,page_views的系数极其显著。显然,sqrt(market_value)sqrt(page_views)之间是线性关系。

残差图能告诉我们什么?

残差图应该能够告诉我们数据中是否存在异方差问题。

Error Distribution Plot

Q-Q Plot

残差图似乎有随机分布的误差,qq 图证实它们是正态分布的。

EPL 人气

一个有趣的副产品是,与其他联赛相比,英超联赛有多受欢迎。由于从国外联赛引进的球员数量很少,这仍然是一个粗略的方法。然而,差异大到足以大于噪声。

我们知道这种模式肯定有效,因为它有来自其他联盟的被低估的球员。理由是——EPL 2000 万球员的点击率比法甲 2000 万球员的点击率高。正因为如此,每次页面浏览量的远低于 EPL。但由于模型是用 EPL 的数据建立的,页面浏览量的系数是从 EPL 得出的。因此,来自不太受欢迎的联赛的外国球员被低估了。

我希望你和我一样觉得这很刺激。如果你觉得有趣,请投赞成票!

要访问该项目中使用的数据和代码库,请单击此处的。

机器能学习正弦的概念吗

原文:https://towardsdatascience.com/can-machine-learn-the-concept-of-sine-4047dced3f11?source=collection_archive---------2-----------------------

众所周知,人工神经网络擅长模拟任何函数。我想知道他们是否能更进一步,学习一个函数的广义模型。为简单起见,让我们尝试学习一个只有一个参数 A 的正弦函数,它控制频率:

y = sin(A*x)

对于我们人类来说,一旦我们理解了正弦函数,我们就知道它在任何参数 A 下的行为。如果我们看到一个部分正弦波,我们就可以知道 A 应该是什么,我们可以将该波外推至无穷大。

ML 能预测一个它没见过的参数 A 的正弦波吗?

实验设置

让我们做一个实验来找出答案。我们把这个问题描述为一个时间序列预测问题。给定一些与函数 sin(A*x)匹配的数据点,尝试预测未来值。当然,挑战在于我们想学习正弦的一般概念。我们希望能够预测未来值,甚至是我们的模型在训练期间从未见过的参数(A)。

我们将使用 Keras,并尝试几种不同的模型——常用于函数建模的全连接网络,常用于模式识别的 CNN,以及常用于序列建模(如 NLP)的 LSTM。

对于每个模型,我们将在(0.06,0.12)范围内的参数 A 下进行训练。对于测试,我们将尝试在 0.033、0.06、0.083 和 0.163 的值下进行预测。这样,我们可以看到在训练范围内有 2 个参数,在训练范围外有 2 个参数的性能。

在测试过程中,我们将从正确 A 下的真实 sin(Ax)值历史开始,这相当于给人一个部分正弦波。当我们进行预测时,值 y 的未来预测将使用 y 的早期预测值。举个例子,假设我们从 40 个真实数据样本开始,y[0] … y[39],y[i] = sin(Ai)。我们使用我们的模型来预测 y[40]。然后我们会用 y[1] … y[40],其中 y[40]是预测值,来预测 y[41]。

我们这样做,而不是使用 sin(A*i)来预测 y[i+1]的原因是,通过累积误差,使我们的模型中的误差更容易看到。

全连接网络

在 Keras 中,完全连接的层称为密集层。我们在 FC 网络中使用 3 个密集层。

model = models.Sequential()
model.add(Dense(100, input_shape=(INPUT_COUNT,)))
model.add(LeakyReLU(alpha=0.03))
model.add(Dense(100))
model.add(LeakyReLU(alpha=0.03))
model.add(Dense(1))

输入形状是 INPUT_COUNT(定义为 40)之前的数据点。最后一个密集层有一个单元,因为我们在给定前 40 个值的情况下预测下一个值。

下面是结果。绿色虚线是预测。同样,在训练期间,参数 A 在 0.06 至 0.12 的范围内。

正如我们所看到的,我们的模型很好地管理了 0.06 和 0.083 的值,但是对于 0.033 和 0.163 却表现不佳。基本上一旦参数 A 超出训练范围,我们的模型就处理不了。

请注意,在图表上,我们的函数不是从 0 开始,因为我们使用了 40 个数据点作为历史数据来输入模型。所有图表都偏移了这 40 个数据点。

美国有线新闻网;卷积神经网络

我们使用 Conv1D 层,因为我们的数据是一维的。

model = models.Sequential()
model.add(Conv1D(100, 3, strides=1, input_shape=(INPUT_COUNT, 1)))
model.add(LeakyReLU(alpha=0.03))
model.add(Conv1D(100, 3, strides=1))
model.add(LeakyReLU(alpha=0.03))
model.add(Flatten())
model.add(Dense(100))
model.add(LeakyReLU(alpha=0.03))
model.add(Dense(1))

对于卷积,我们使用大小为 3 的滤波器,步长为 1。我们没有做最大池,因为位置在回归问题中很重要。

与 FC 网络类似,输入是 40 个先前的数据点,输出是曲线上的下一个点。

结果类似于完全连接的网络。在给定任何参数 a 的情况下,它不能学习正弦的一般公式。

LSTM

LSTM 网络保留了它在过去看到的数据的记忆。因此,我们输入的数据是不同的形式。我们只需要一次输入一个数据点,而不是 FC 和 CNN 模型过去 40 个数据点的历史记录。如下图所示,input_batch_size 为(1,1,1)。

model = models.Sequential()
model.add(LSTM(100, batch_input_shape=(1, 1, 1), return_sequences=True, stateful=True))
model.add(LSTM(100, return_sequences=False, stateful=True))
model.add(Dense(1))

因为我们一次只能输入一个数据点,因为后面的数据点依赖于前面的数据点建立的 LSTM 内部状态,所以我们不能利用硬件中的并行性。结果训练真的很慢。因为这个原因,我没有对 LSTM 参数做太多的实验。这是结果。

结果比 FC 和 CNN 还惨。同样,这可能是因为我没有做足够的工作。另一方面,我也不指望它表现得更好,因为其他模型有足够的历史数据,而且数据是重复的。

结论

我发现这个问题很有趣,因为在生活中我们经常需要使用历史数据来预测时间序列中的未来。如果神经网络模型能够推广重复模式的概念,甚至在频率变化时也能预测模式,那么它们在我们的应用中将更加强大。

在我们的实验中,我们看到模型都学习了正弦函数的一般形状,但未能在训练范围之外的频率下生成未来的数据点。

这里的结论是 NN 模型很难概括正弦的概念,还是简单地说我很烂,没能建立一个能解决这个问题的模型?我的代码在 github 上:

[## 松散连接/ml-示例

机器学习的例子。

github.com](https://github.com/looselyconnected/ml-examples)

请使用它,将您的意见发送给我,并让我知道是否有更好的模型可以解决这个问题。谢谢你。

机器学习能回答“我们从哪里来”这个问题吗?

原文:https://towardsdatascience.com/can-machine-learning-answer-the-question-where-did-we-come-from-223894bfeea6?source=collection_archive---------6-----------------------

为了了解我们从哪里来,科学家们从探索星系为什么会诞生,如何成长,以及为什么会死亡开始。

我们生活在一个星系中,每个星系的生命周期都是一个故事,总是有这三个阶段。很容易看到每个阶段的星系,但是如果没有更好地了解恒星的形成以及气体是如何变成恒星的,我们将永远不会知道它们为什么会衰老,为什么会死亡。

50 多年来,天文学家一直在人工测量和模拟恒星的形成,但未来的理解取决于分析更大的新一代望远镜的更多数据。在无法利用测量恒星形成所需的大量数据的情况下,理论家们转而依赖于通常令人信服但未经证实的模型。

这一切都将改变。

上周,我向公众发布了一个机器学习代码库,从根本上提高了科学家分析下一代望远镜数据的能力。

我开发了算法,和对应的代码,当时我还是威斯康星大学的博士后研究员。该代码库允许在 2015 年发表的一篇论文中概述的算法的实际应用。这项工作由威斯康星大学麦迪逊分校天文系教授 Snezana Stanimirovic 获得的国家科学基金会资助。

Gausspy 允许科学家们首次使用来自更大望远镜的更多数据来测试理论,以找出恒星形成的原因,它们老化和死亡的原因,并更接近理解我们为什么在这里的最基本问题。

那么,为什么从坐在实验室手动分析光谱的科学家到机器学习用了 50 年?

科学需要有人从需要它的领域之外的角度来解决这个问题。

射电天文学需要它来了解它们的光谱。我的背景是机器学习应用于需要人类解决的棘手问题。我个人选择这个项目不仅仅是为了科学,而是因为我看到了他们面临的一个巨大的问题,并且知道我可以在这个问题上做出很大的努力。这个问题困扰了射电天文学家几十年。

早期的采用令人印象深刻,并证实了这项创新对天文学的未来有多么重要。

虽然代码库上周才刚刚发布,但我在 2015 年完成了 Gausspy,并开始寻找下一个机器学习挑战。就在我离开博士后岗位的时候,我遇到了我的合作伙伴,并成立了 VEDA Data Solutions

我总是最喜欢从一个领域跳到另一个领域,解决长期存在的数据问题,做出颠覆性的发现,然后转向下一个最“不稳定”的领域。所以我的知识面很广。我带来了解决问题的最佳技术和能力,因为我从我看到的每个领域中获取了最佳的数据分析风格,并将其应用于其他没有考虑这些方式的领域。

我在 VEDA 的风格只是这个链条中的下一步,不仅跨越领域,还跨越部门和垂直领域。我很高兴能与科学界分享 Gausspy,并期待通过我们在 VEDA 的工作解决更多的问题和分享新的发现。

机器学习能预测贫困吗?

原文:https://towardsdatascience.com/can-machine-learning-predict-poverty-5b4847a2f6b4?source=collection_archive---------3-----------------------

世界银行在竞赛主办网站 drivendata.org 主办了贫困预测竞赛。比赛的链接是这里。我们决定在这个数据集上测试我们的机器学习技能。在 ParallelDots 的大多数常规工作都围绕三个主题:图像和视频的视觉分析、医疗保健人工智能和自然语言处理,这三个主题都是使用深度学习技术解决的。这个比赛是一个尝试新事物的机会,并建立我们的内部代码库来处理表格数据集,就像我们在比赛中一样。

我们希望从竞赛中获得的最终结果是:

  1. 尝试多种可能解决问题的机器学习模型。
  2. 尝试现有的 AutoML 方法。(AutoML 方法只需要你自己进行特征工程并找出管道的其余部分)
  3. 创建一个最佳模型来解决问题,而不需要集合太多的模型来提高分数。由于 AIaaS 是我们的日常工作,优化一个好的模型对我们来说更重要,因为集成很难作为服务部署。
  4. 建立一个代码库来解决未来的数据科学和机器学习问题。

分析数据集(不费吹灰之力)

在任何机器学习项目中,第一项任务是分析数据集并查看其属性。通过查看数据集,我们可以获得一些正确的信息:

  1. 有三个不同国家的数据文件。
  2. 所有的字段都是匿名和编码的,所以你不知道这些字段是什么意思。这将特定领域特性工程的可能性降低到零。
  3. 这三个国家的数据完全不同,因此需要建立三个模型,每个国家一个。

(快速)深入数据的一个方法是使用新的软件包 Pandas-Profiling(可以从 GitHub 这里下载)。这个包做了大量的初步分析,并将它们保存为漂亮的 HTML 文件,人们可以在浏览器上查看。我们对所有三个国家的数据进行了 Pandas-Profiling 分析,以了解数据类型、频率、相关性等。

在下图中可以看到其中一个国家的示例输出:

Pandas Profiling shows overview for the country C data

Feature Level Statistics details created by Pandas Profiling

Correlations amongst different features

我们可以得出的更多结论是:

  1. 大多数分类字段似乎都有一个默认值,这是该字段最常见的值。(例如,在上图中,您可以看到字段 AOSWkWKB 有一个默认值,它需要 80%以上的时间)
  2. 数据集是高度不平衡的,我们需要在训练时注意这一事实。

建立数据模型的两种方法

如果查看对象的数据类型,可以看到数据是分类值(可以从常量可枚举值中取一的属性)和数值(浮点数和整数)的混合。事实上,这就是世界银行提供的随机森林基准的建模方式,可在此处获得。然而,当你看数字量时,它们并不多,可能代表出生日期等数量。(如果你上过的 Coursera 课程,Dmitry 在处理匿名化数据集一节中谈到了类似的领域)。因此,我们想尝试的另一种方法是将所有字段视为分类属性。我们最终都尝试了。

数据不平衡

数据集的另一个重要属性是+ve 和-ve 类之间的不平衡(非贫困人口远远超过贫困人口)。对于国家 A,数据仍然是平衡的,但是对于 B 和 C,数据具有非常偏斜的分布。为了在这种扭曲的数据上训练模型,我们使用 Python 中的不平衡学习库尝试了不同的方法:

  1. 在倾斜的数据集上进行训练(效果不错,不太好)
  2. 在负类欠采样的数据集上训练(表现非常差,即使最好的机器学习模型也可以与该数据集的基线一样好地工作)
  3. 对+ve 类进行过采样(工作得相当好)
  4. 使用 SMOTE 算法的过采样(不如正常的过采样有效,主要是因为 SMOTE 算法不是真正为分类属性定义的)
  5. 使用 ADASYN 进行过采样(不如正常过采样有效)

预处理

数据集预处理如下:

  1. 所有分类特征都被转换成二元特征。
  2. 数值被归一化。测试了最大-最小和平均-标准差归一化。
  3. 家庭一级和个人一级的数据被合并(个人一级的数据为所有家庭的每个成员提供单独的数据)。对于个人和家庭数据中常见的属性,只保留了家庭一级的数据。家庭中的所有数字特征都取平均值(这可能不是最好的方法),并且所有分类值都聚合为家庭中最奇怪的值(例如,如果特征 X 在家庭中的值为 1,1,1,0,我们会将家庭的组合值取为 0)。原因是许多分类变量都有默认值,而我们期望奇数值有更多的信息。

我们尝试过的方法

我们现在讨论我们尝试过的多种方法。

  • 首先,我们来谈谈那些不起作用的事情:
  1. 我们认为分类字段的默认属性可能对建模没有用处。为了检查这一点,我们训练了具有和不具有默认属性的机器学习模型。没有输入缺省属性的模型比输入缺省值的模型表现更差。
  2. SMOTE 和 ADASYN 过采样并没有给出比正常过采样更好的结果。
  3. 两个阶段的机器学习,第一个阶段创建决策树以获得特征的重要性,另一个阶段训练最重要的特征。我们尝试这种技术没有任何收获。
  4. 尝试不同的方法来标准化数值数据并没有改变准确性。然而,非规范化数值属性的准确性较差。
  • 帮助我们提高分数的窍门:
  1. 数字和分类特征组合比所有分类属性更适合于训练算法。至少对决策树来说是这样。
  2. 为缺失数据选择默认值有助于我们提高准确性。我们开始时将所有缺失的值设为 0,但后来使用了更好的-999。
  3. 跨机器学习超参数的网格搜索让我们不费吹灰之力就在验证集上获得了 2–4%的提升。
  4. 一个强大的 AutoML 基线可以帮助我们很好地开始。
  • 我们想尝试但不能/没有/懒得编码的招数:
  1. 通过获取非默认分类值的笛卡尔乘积,然后选择重要特征来训练模型的特征工程。
  2. 通过以不同方式组合数字特征并对生成的特征进行特征选择的特征工程。
  3. 尝试多个模型的集合。我们之前设定的目标是得到一个好的模型,但最终还是训练了很多方法。我们可以把它们组合成一个整体,就像堆叠一样。

机器学习算法

我们使用的库:SKLearn、XGBOOST 和 TPOT

我们现在将讨论我们尝试过的机器学习方法。按时间顺序谈论事情,如我们尝试方法的顺序。请注意,自从我们第一次尝试以来,所有对我们有用的技巧都不存在了,我们一个一个地把它们包括进来。请看每一次试验的要点,了解当时的管道是什么。除非另有说明,所有使用的机器学习模型均来自 Scikit 学习库

  • 带有默认参数的常见疑点
  1. 我们开始用默认参数尝试常见的可疑情况。逻辑回归、SVM 和随机森林。我们还尝试了一个名为 CATBOOST 的新库,但是我们找不到很多关于它的超参数的文档,也不能很好地适应数据,所以决定用更著名的 XGBOOST 替换它。我们还了解 XGBOOST 超参数调优(我们知道我们必须在后面的阶段进行)。
  2. 第一次尝试将所有列建模为分类数据和不平衡数据集。
  3. 所有的模型都符合要求,并且在验证数据上给了我们比扔硬币更好的准确性。这告诉我们,数据提取管道是好的(没有明显的错误,但需要更多的微调)。
  4. 像竞争提供商提供的基线一样,随机森林和带有默认超参数的 XGBOOST 显示了良好的结果。
  5. LR 和 SVM 可以很好地模拟数据(不如 RF 和 XGBOOST,因为默认超参数的方差较小)。SVM (SKLearn SVC)也有很好的准确性,但它返回的概率在 SKLearn 中并不真正可用(我发现这是默认超参数的常见问题),这使我们放弃了 SVM,因为竞争是根据平均对数损失进行判断的,这需要额外的努力来确保概率数字是正确的。只是 SVC 收益的概率不完全是概率,而是某种分数。
  • TPOT: AutoML 做了一个很好的基线
  1. 仍然继续所有的特征都被认为是分类的,我们试图用一种叫做 TPOT 的自动方法来拟合基线。
  2. TPOT 使用遗传算法为手头的问题找出一个好的机器学习管道,以及与之一起使用的超参数。
  3. 这使我们在提交时在竞赛公共排行榜上名列前 100。
  4. TPOT 需要时间来找出管道,并在几个小时内对整个数据集进行收敛。

  • 神经网络可以用吗?有人知道神经网络吗?

我们对深度学习的热爱让我们跃跃欲试,试图用神经网络来解决这个问题。我们开始训练一个好的神经网络算法来解决这个问题。请注意,此时我们正在做实验,将所有列都视为分类。有很多分类变量,需要预测一个标签的问题是什么?文本分类。这是神经网络大放异彩的一个地方。然而,与文本不同,这个数据集没有序列的概念,所以我们决定使用文本分类中常见的神经网络,但不考虑顺序。那个算法就是 FastText 。我们编写了一个(深度)版本的快速文本,就像 keras 中的算法一样,在数据集上进行训练。我们训练神经网络的另一件事是过采样少数类,因为它不能很好地训练不平衡的数据。

FFNN Used

我们尝试使用最近提出的自归一化神经网络进行训练。这给了我们在验证集上的自由碰撞的准确性。

Self Normalized FFNN (SELU) we used

虽然当我们使用深度神经网络,特别是神经网络时,我们在验证集上获得了准确性。在 B 国,我们获得了最高的准确率(甚至比我们表现最好的模型还要好),这是因为我们使用了自标准化深度神经网络,结果并没有转化到排行榜上,我们一直得到低分(高对数损失)。

  • 改进 AutoML 基线并调整 XGBOOST

我们创建的 AutoML 基线仍然盯着我们的脸,因为我们所有的手工方法仍然更差。因此,我们决定改用经过测试的 XGBOOST 模型来提高分数。我们编写了一个数据管道,用于尝试我们在该部分开始时提到的不同技巧(成功/不成功),以及一个管道,用于在不同的超参数上进行网格搜索,并尝试 5 重交叉验证。

Grid Search Example for the single validation set

上面的技巧与网格搜索相结合,极大地提高了我们的分数,我们可以击败 0.2 logloss,然后也可以击败 0.9 logloss。我们尝试了另一个 TPOT AutoML,使用我们成功的技巧生成的数据集,但它只能占用排行榜上接近 0.2 logloss 的管道。所以最终 XGBOOST 模型被证明是最好的。当我们尝试对随机森林算法的参数进行网格搜索时,我们无法获得相同数量级的精度。

与公开比赛排行榜相比,我们在私人排行榜上的得分/排名略有下降。我们在 90%左右结束了比赛。

我们希望你喜欢这篇文章。请注册一个免费的平行账号开始你的 AI 之旅。你也可以在这里查看 PrallelDots AI API的演示。

点击阅读原文

神经网络能解决任何问题吗?

原文:https://towardsdatascience.com/can-neural-networks-really-learn-any-function-65e106617fc6?source=collection_archive---------0-----------------------

可视化通用逼近定理

Let’s see you try modeling that, neural network!

在你深度学习之旅的某个时候,你可能会遇到通用近似定理

具有单一层的前馈网络足以表示任何函数,但是该层可能大得不可行,并且可能无法正确地学习和概括。

——伊恩·古德菲勒, DLB

这是一个令人难以置信的说法。如果你认为大多数问题都可以归结为函数,那么这种说法意味着神经网络在理论上可以解决任何问题。如果人类智能可以用函数来建模(也许是非常复杂的函数),那么我们今天就有了复制人类智能的工具。神经网络可能是人工智能版的巴贝奇分析引擎(1822),而终结者需要一台 Macbook Pro,但仍然如此。也许 UAT 解释了为什么深度学习如此成功地解决了人工智能中的“难题”——图像识别、机器翻译、语音转文本等。

TLDR;我用视觉和经验向自己证明,使用单个隐藏层和 6 个神经元,UAT 适用于非平凡函数( x +x -x -1) 。我假装自己是一个神经网络,试图自己“学习”正确的权重。我还在代码中验证了这一点。

神经网络怎么可能模拟任何功能?

这个问题难倒了我很久,我在网上找不到很好的解释。大多数句子与等式的比率高于 0.57 的解释应该是这样的:

通过激活函数引入非线性允许我们逼近任何函数。很简单,真的。—埃隆·马斯克

所以非线性激活函数是秘方?我们真的可以通过将一系列 Sigmoid 激活链接在一起来模拟任何功能吗? ReLU 功能怎么样?肯定不是——里面有单词 linear !校正线性单位!

我最终发现了迈克尔·尼尔森的教程,它是如此之好,以至于几乎使这篇文章过时(我强烈建议你阅读它!),但现在让我们回到过去,假装迈克尔那天带着他的家人去了迪斯尼乐园,而不是写有史以来世界上最伟大的神经网络教程。谢谢你,迈克尔;)

手动执行梯度下降

我很早就意识到我不会赢得这场钻研数学证明的战斗,所以我决定采取一种实验性的方法。我去了德斯莫斯,开始将 ReLU 激活函数链接在一起,看看我是否能构建一些看起来有趣的东西。每次尝试后,我都调整我的函数,使它们看起来更像目标——听起来熟悉吗?

Left: target function Right: raw materials

我选择 x +x -x -1 作为我的目标函数。仅使用 ReLU max(0,x) 我反复尝试不同的 ReLU 组合,直到我有一个大致类似目标的输出。这是我用 3 个 ReLUs 的加权和得出的结果。

Left: 3 ReLU functions Right: Weighted sum of the 3 ReLU functions

还不错?左图显示了 ReLU 函数。右图显示了我的模型与目标相比的输出。你可以把每个 ReLU 函数想象成一个神经元。因此,组合 3 个 ReLU 函数就像训练一个由 3 个隐藏神经元组成的网络。这是我用来生成这些图表的方程式。

每个神经元的输出等于 ReLU 环绕加权输入 wx + b

我发现我可以通过改变偏差来左右移动 ReLU 函数,并通过改变权重来调整斜率。我将这 3 个函数组合成加权输入的最终和( Z ),这是大多数神经网络的标准做法。

Z 中的负号代表最后一层的权重,我将其设置为-1,以便沿 x 轴“翻转”图形,以匹配我们的凹形目标。在又玩了一会儿之后,我终于得出了下面的 7 个等式,这 7 个等式加在一起大约是 x +x -x -1。

所以至少在视觉上,用一个隐藏层和一些神经元来模拟非平凡函数是可能的。相当酷。

将我的体重硬编码到一个真实的网络中

这是一个用我的假权重和偏见初始化的神经网络图。如果你给这个网络一个类似于 x +x -x-1 的数据集,它应该能够近似得到-2 和 2 之间的输入的正确输出。

最后一个语句,是-2 和 2 之间任何输入的近似正确输出,是关键。通用逼近定理指出,对于在 特定范围 内的输入,具有 1 个隐层的神经网络可以逼近任何 连续 函数。如果函数跳跃或者有很大的间隙,我们就无法逼近它。此外,如果我们在 10 和 20 之间的输入上训练一个网络,我们不能肯定地说它是否将在 40 和 50 之间的输入上工作。

我的重量真的有用吗?

我想以编程的方式证明,当插入一个有一个隐藏层和 6 个神经元的基本神经网络时,我得出的权重实际上是有效的。然而,我没有训练网络来学习权重,而是用自己挑选的值替换了它的默认权重和偏差。下面的方法feed_forward() 采用输入向量(例如[-2,-1,0,1..])并使用我的权重输出预测向量。事情是这样的:

Zh,Zo: weighted inputs . Wh,Wo: weights. Bh,Bo: biases. Ah,Ao: activations

看那个!我是个天才。这正是我们想要的。但是如果我们的老板要求我们将范围从-2 扩大到 2 呢?如果她想要-5 比 5 呢?

x = np.arange(-5, 5, .1)

啊,不太好。但这实际上支持了我们早先的结论:一个具有一个隐藏层的神经网络可以逼近任何连续函数,但仅适用于特定范围内的输入。如果像我们一样,在-2 和 2 之间的输入上训练一个网络,那么它将对类似范围的输入工作良好,但你不能指望它在不重新训练模型或添加更多隐藏神经元的情况下推广到其他输入。

我的体重可以学吗?

现在我们知道 Brendan Fortuner 可以自己学习这些权重,但是具有 1 个隐藏层和 6 个神经元的真实世界神经网络是否也可以学习这些参数或导致相同结果的其他参数?让我们用 scikit-neuralnetwork 来测试这个理论。我们将设计一个网络,使其适用于回归问题,并将其配置为使用 ReLU、随机梯度下降和均方误差——通常的组合。

成功了!

以下是 Scikit 学到的重量。它们显然与我自己的不同,但数量级是相同的。

*hiddenLayerWeights = [
 [-1.5272, -1.0567, -0.2828, 1.0399, 0.1243, 2.2446]
]
finalLayerWeights = [
  [-2.2466],
  [ 1.0707],
  [-1.0643],
  [ 1.8229],
  [-0.4581],
  [ 2.9386]
]*

也许如果我把这篇博文重写 10 万遍,我会自己得出这些参数,但是现在我们只能推测。也许有一天,我会对我的赞成票求导,并朝着观点最大化的方向更新我的句子。

如果你喜欢阅读,请点击下面的【♥】按钮!

python 可以用于脸书聊天备份吗?当然可以!

原文:https://towardsdatascience.com/can-python-be-used-for-facebook-chat-backup-of-course-it-can-877226b57ac8?source=collection_archive---------14-----------------------

Web 抓取和 Scrapy 框架的简单演练

Photo by Glen Carrie on Unsplash

你好世界!!我们中的大多数人都会有这样的情况,我们必须滚动浏览我们在脸书的对话,以回忆事情,重温时刻或开怀大笑我们的旧对话,你经常这样做,希望有一个备份,这是给你的。在文章的最后,你可以用 csv 或 json 格式的结构化方式备份你的对话。

放弃

这篇文章不是为像 【鲍勃】 这样的人写的。抱歉 鲍勃 ,如果这以任何方式冒犯了你!!

为什么??怎么会??

在继续之前,我想回答几个你在阅读这篇文章时可能会想到的问题。

  1. 为什么要这么做!因为我们可以。😎
  2. 为什么我们不点击加载更多/向上滚动几个小时到达我们希望阅读的对话!,每次都要滚动对话,超级无聊。
  3. 为什么我们不能使用脸书的默认数据备份功能!,我们不能得到全部的内容,有一个上限。
  4. 为什么是 python!,它是一种广泛用于网络抓取的语言,拥有许多有用的库,如 scrapy,request。#还是我熟悉的那个!!😃
  5. 为什么刺儿头!,这是一个相当全面和易于使用的数据抓取库,当遇到困难时,它有一个活跃的社区帮助!

安装/设置

Python 安装:Windows 安装文件 zip 可以在这里找到,Ubuntu 运行命令

sudo apt-get 安装 python3

零碎安装:在 Windows 和 Ubuntu 上,运行下面的命令

pip 安装废料

事情是怎么做的!

如果你还没有进入如何刮是如何完成的,你可以跳到" 如何使用" 部分。

在深入到编码部分之前,在技术方面存在挑战,比如访问脸书数据、处理 javascript 和 ajax 调用。通过请求库重新创建相同的 ajax 调用是一件非常令人头疼的事情,但却失败得很惨。

然后,我试着用工具【硒】刮数据。如果您对此不熟悉,Selenium 可以用于自动化您在浏览器上的活动,允许您像人类一样控制和使用您的浏览器(如单击搜索框、输入关键字和单击搜索按钮)。

我的 Selenium 所做的是:进入 Facebook.com->登录->进入聊天列表并选择一个对话->向上滚动时开始抓取。脸书拒绝在几页之内从他们的服务器访问更多的数据!!是的,他们擅长检测机器人。

花了几个小时在谷歌上搜索后,找到了尝试“移动优化网站”的建议,它实际上是一个不使用任何 AJAX 的老派网站mobile.facebook.com。终于!!能够使用 scrapy 不间断地获取数据。

入门指南

在你开始刮之前,你必须建立一个新的刮项目。输入您想要存储代码并运行的目录

scrapy startproject facebook

这将创建一个包含以下内容的facebook目录:

facebook/
    scrapy.cfg            *# deploy configuration file* facebook/             *# project's Python module, you'll import your code from here*
        __init__.py items.py          *# project items definition file* middlewares.py    *# project middlewares file* pipelines.py      *# project pipelines file* settings.py       *# project settings file* spiders/          *# a directory where you'll later put your spiders*
            __init__.py

如果你没有得到,不要担心发生了什么,我们不会担心他们中的大多数人,我们唯一的改变是写一个 蜘蛛 抓取内容,并改变ROBOTSTXT _ observe = False**在 settings.py 文件中脸书不允许僵尸程序登录。你可以在这里了解更多关于 robots.txt

让我们建造我们的蜘蛛

在 spiders 目录下创建一个 python 文件,然后导入 scrapy、pandas 和 FormRequest,我们将使用它们来提供登录凭证。

这里 fb_text 是我们的蜘蛛的名字,我们可以在我们的蜘蛛目录下写任意数量的蜘蛛,它们可能服务于不同的目的,在我们的例子中,我们可以写一个用于抓取帖子和评论等。每个蜘蛛都应该有自己独特的名字。

然后我们通过终端获取登录凭证,在那里我们将运行我们的蜘蛛

scrapy crawl fb_text -a email="FB 用户电子邮件"-a password="FB 用户密码"

在我们将凭证提供给 FormRequest 之后,它将在start _ URLs' https://mbasic . Facebook . com '中填写表单( user_email and password) ,并返回主页。

让我们给我们的蜘蛛增加一些超能力吧

完成了结构的定义,是时候给我们的蜘蛛一些超能力了。一个是它应该能够通过网页抓取内容,另一个是抓取内容/数据。

请求函数将向回调函数发送响应,在我们的例子中,我们到达消息页面,然后获取我们对话的人及其链接。从那份名单中,我们会刮出一个。

以上是蜘蛛的核心部分,它获取实体之间的对话,并把它写在一个 csv 文件中。完整的蜘蛛文件可以在这里找到。

为了简单和容易理解,items.py 不用于存储数据。

如何使用

如果您跳过了前一部分,请确保克隆这个存储库。浏览项目的顶级目录,并使用以下内容启动 scrapy:

scrapy crawl fb -a email="EMAILTOLOGIN" -a password="PASSWORDTOLOGIN"

这将给出最近的 10 个对话,从中选择要废弃的对话,机器人/蜘蛛将抓取对话,直到该对话中的最后一个文本,并返回一个 csv 文件,其中包含列->名称,文本,日期。看看下面的例子。

路到此为止。

Github 回购

在准备中

数据是解决任何 ml/ai 问题的来源,而不是每次我们拥有一个结构良好的数据。这就是网络抓取派上用场的地方,用它我们可以从网站上抓取/获取数据。关于基础网页抓取的教程将会在未来发布,请务必关注和支持。

我们到此结束,希望我已经对 word2vec 嵌入做了一些介绍。在这里检查其他作品

哈哈,如果你这么认为,我们就在同一页上。下面我们来连线Linkedin脸书

我们能复制大脑吗?

原文:https://towardsdatascience.com/can-we-copy-the-brain-9ddbff5e0dde?source=collection_archive---------3-----------------------

IEEE Spectrum 特别报告综述:我们能复制大脑吗?

本月的 IEEE Spectrum 有一个关于合成大脑的故事。在这篇文章中,我将回顾这个故事,并对探索的现状进行评论:在合成系统中复制人脑。这篇文章是关于神经科学,神经形态学,人工神经网络,深度学习,生物和合成中的计算硬件,以及所有这些如何在创造人类水平或高于人类水平的合成大脑的人类大挑战中走到一起。

为什么我们要复制大脑 : 我们之所以要这样做,是因为我们想创造出能替我们工作的智能机器。为了做我们的工作,机器将不得不生活在我们的环境中,拥有与我们相似的感官,并能够完成同样的任务。它还不止于此:在大多数任务中,机器能比我们做得更多更好,就像我们比其他生命形式做得更好一样。我们希望他们做我们做不到的事情,把我们能做的事情做得更好。这叫做进步,我们需要这样做来绕过生物进化,加快生物进化的速度。这篇文章很好地总结了这将是什么,以及机器将为我们做什么。更多评论见下文 PS1 部分。关于工作,请参见 PS3。

未来,机器会借用我们大脑的最佳招数 : 人脑是我们所知的最高效的计算机器之一。从这个意义上说,它是已知宇宙(人类已知的)中最好的“大脑”。什么是大脑?它是一台允许我们在自己的环境中生活的电脑。人生是什么?哦,好吧,也许现在,让我们只说我们的生活致力于繁衍后代,确保我们的后代最好的,促进下一代和他们的成功,保护所有这一切发生的最佳环境(或者我们现在?).

今天,我们人类受自己大脑的启发,正试图建造人造大脑。而慢慢的,近几年(网上更多文章和评论!),人工神经网络和深度学习已经慢慢侵蚀了计算机和人类能力之间的很多差距。只是 不可避免 它们会变得越来越像一个人,因为我们实际上是带着那个目标在建造它们!我们希望他们为我们做事,比如驾驶我们的汽车,提供客户服务,做一个完美的数字助理,阅读你的思想、预测你的需求。也渗透到世界上的每一个仪器和传感器中,所以它们可以更好地帮助我们在正确的时间获得正确的信息,有时甚至不需要我们去要求。

但是建造一个合成大脑并不意味着我们需要复制我们自己的大脑。事实上,这根本不是我们的目标,我们的目标是做一个更好的!我们的大脑是由细胞和生物组织构成的,我们的合成大脑是由硅和电线构成的。这些媒体的物理性质并不相同,因此我们只能从大脑算法中获得灵感,一步一步地构建更好更大的合成硬件。我们已经在梦想能够自己创建计算架构的神经网络。与神经网络训练其权重的方式相同,它也可以训练消除所有这一切中的最后一次人工输入:学习创建神经网络模型定义

即使我们想限制自己创造一个我们大脑的克隆体,它仍然会迅速进化超出我们的能力,因为建造它的目标之一是不断学习新知识和改善行为。因此,不可避免的是,我们最终会拥有一个比我们更好的大脑,好得我们甚至无法想象。也许就像我们的大脑被比作昆虫的大脑一样——甚至更多。一个生物可以变得多么聪明和有知识是没有限制的。

作为计算机的大脑:数学不好,其他都好 :我们人类研究神经网络已经很久了。我们也已经研究我们的大脑很长时间了。但是我们仍然不知道如何通过观察一个场景来预测将要发生的事情,这是我们生活中每时每刻都在做的事情。我们仍然不知道我们如何学习新概念,我们如何将它们添加到我们已经知道的东西中,我们如何利用过去预测未来,以及我们如何识别复杂的时空数据,例如识别现实世界中的行为。见本摘要。我们也不知道如何最好地与真实或模拟的世界互动,或者我们如何学习与世界互动。

我们可能不知道这一切。但是我们正在取得进展。我们从学习识别物体(和脸,和道路场景)开始。然后我们学习了分类和创建序列(包括演讲、文本理解、语言翻译、图像到文本的翻译、图像到图像的翻译等等)。我们还在尝试学习如何在没有大量标记数据的情况下进行学习(无监督学习)。我们开始玩电子游戏,先是简单的,然后是难的,现在是非常复杂的。人工智能算法将了解我们世界的力学和物理学只是时间问题。

我们真的很擅长这个,在所有这些任务中比人类做得更好——或者一些!我们不打算停止,直到我们有机器人可以为我们做普通的任务:烹饪,清洁,洗碗,叠衣服,与我们说话(Alexa,Siri,Cortana 等),理解我们的感觉和情绪,以及更多与人类智力和能力相关的任务!但是我们如何到达那里呢?我们非常擅长让神经网络对事物进行分类,现在我们需要它们进行预测。学习长序列事件,对长序列事件进行分类。由于有无限多的可能事件,我们无法用例子训练一个人工智能,我们没有所有的例子,所以我们需要它自己学习。关于我们的大脑如何学习做到这一点的最佳理论是通过不断预测未来,因此它知道忽略所有不重要的和以前见过的事件,但同时知道一些事件是否是新的。无监督和自我监督学习将是重要的组成部分。更多在此。

还要注意的是,这种深度学习的进步大部分不是来自神经科学或心理学,就像制造好电池不是来自炼金术一样。

本文还提到了计算硬件,指出传统计算机可能不如某些神经形态计算机方法好。我们在这里评论这个话题。肯定会有更高效的硬件出现,这些硬件可能能够运行最新和最伟大的深度学习算法,例如我们在这里的工作。而且可能有神经形态的成分,比如尖峰网络,稀疏数据的异步通信,但不是这一天。如今,神经形态硬件尚未运行任何类似于深度学习算法的巨大成功,例如手机上的谷歌 / 百度、手机上的谷歌文本翻译,或者云端图像的标记。这些是我们今天取得的切实成果,他们使用深度学习,他们在标记数据集上使用反向传播,他们使用传统的数字硬件,很快将成为专用硬件

智能机器需要向新大脑皮层学习什么 : 这是一个的时刻。杰夫·霍金斯写了一本非常激动人心的书,就在十年前左右。它极大地鼓舞了我所有的学生、我们的电子实验室和我自己,去研究合成大脑,并从我们所知道的和可以测量的人脑中获取灵感。

但从那以后,人工神经网络和深度学习抢了他的风头。当然,我们需要学会重新布线。当然,我们正在学习一种稀疏表示。所有深度神经网络都是这样做的——参见 PS2。当然,我们需要学习在环境中表演(化身),我们已经通过学习玩视频游戏驾驶汽车做到了这一点。

但是当然,它没有说如何处理现实世界的任务,因为 Numenta 仍然停留在它独特的商业模式中,在这种模式中,它既不能帮助自己,也不能帮助社区。最好是倾听社区的声音,分享它的成功,资助聪明人和创业公司。也许杰夫确实认为他一个人就能解决这一切,而且比任何人都强。我们都是这种自我中心行为的受害者…

我必须补充一点,我同意杰夫对以分类为中心的深度学习算法无法处理更复杂任务的沮丧。我们已经在这里写了这个。但是正如你在这个链接中看到的,我们都在这个领域工作,很快就会有很大的进步,就像在分类任务中一样。请放心!杰夫说:“当我考虑未来时,我担心我们的目标不够高”。如果杰夫和努门塔加入,我们会更快更好,并重新定位我们的目标。

AI 设计师在老鼠大脑中寻找灵感 : 这里我们来了解一下大脑/认知/智力所有问题的罪魁祸首:研究大脑。我花了 10 多年时间试图建立更好的神经科学仪器,目标是帮助神经科学家了解人类如何感知视觉世界。参见第 16 页上的内容。这是在人们仍然用 1 根或几根导线刺激神经元的时候,并且在我最感兴趣的主题上只取得了有限的进展:理解神经网络是如何连接的,对信息进行编码,以及构建真实世界的更高级表示。我为什么关心这个?因为知道大脑是如何做到这些的,可以让我们更快地构建一个合成大脑,因为我们会首先应用生物学的原理,而不是试图通过试验和错误来弄清楚事情。请记住,无论如何,生物学是在数十亿年的进化中,通过反复试验才达到这一步的…

随着时间的推移,我对大脑研究和神经科学的进展越来越失望,因为:

  • 我们没有合适的仪器来研究小型或中型神经网络规模的大脑,这一领域的大多数科学建议都是在我们现有的基础上进行小规模的渐进改进,而不是系统地建立一套新的神经科学工具和仪器
  • 许多同事仍然认为,脉冲神经网络有一些特殊之处,没有模型能够捕捉到真正的生物大脑,或者生物神经元的细节是神奇的,永远无法在人工神经元中复制
  • 由于缺乏能够记录真实神经网络中所有可能的输入和输出的工具,研究内层神经元的表示仍然是不可能的。绘制连接图会有所帮助,但至少在某种程度上,必须知道每个神经元应该做什么
  • 为了帮助解决这个问题,我们提出了复杂的光基因记录仪器,可以研究现实生活条件下(行为动物)大脑的时空演变,但很少有研究人员想使用它们,摆脱电极神经记录的潮流

使用人工神经网络可以超越这些限制,同时保持对生物学原理的不同程度的忠诚。人工神经网络可以在计算机上模拟设计,可以运行得非常快,并且可以在今天用于实际任务。这基本上是深度学习在过去 5-10 年里一直在做的事情。这些系统也是完全可观察的:我们确切地知道神经元如何工作,它们给出什么样的反应,以及在所有条件下输入是什么。我们也完全知道他们是如何被训练以特定的方式表演的。

但问题是:遵循什么生物学原理是重要的?虽然我们没有这个问题的答案,但我们可以肯定地得出结论,如果人工神经网络能够解决实际任务,它将是重要的,不管它是否完美地模仿了生物对应部分。研究 1 毫米厚的大脑皮层,并希望我们能够了解大脑是如何工作和学习的,这是站不住脚的。我们可能会得到很多数据和细节,但所有这些都可以被丢弃,因为唯一潜在的工作原理是重要的。例如:我们不需要知道每一个分子或每一滴水在溪流中的位置,我们只需要知道它的平均流向和溪流的平均大小。为了测试这些潜在的模型,我们可以使用我们的想法或模拟,或者更好的是,设计一个可以为我们设计合成系统的系统。我们不需要对一块组织的每个方面进行逆向工程,因为它与其底层算法和操作原理几乎没有关联。同样,我们不需要知道我们的耳朵和声带是如何工作的,就可以用无线手机向全世界发送声音,超越这个星球上任何生物实体的能力。飞机机翼也是如此。

文章说:“AI 是而不是建立在类似大脑中的“神经网络”上?他们使用过度简化的神经元模型。差异很多,而且很重要”。这种说法已经被多次提出,声称生物学有一些我们不知道的特殊属性,不知道它我们就不能取得任何进展。这显然是没有意义的,因为我们在不知道所有细节的情况下已经取得了很多进展,事实上这可能证明细节不重要。没有任何证据表明,如果我们向深度学习的简单人工神经元添加一些“细节”,系统可以提高性能。没有证据表明,因为所有的神经形态系统都在玩具模型和数据上运行,并且不能够扩展到深度学习的成功。所以至今无法比较。也许有一天会是这样,但我向你保证,你的“细节”可以简单地编码为更多的神经元和更多的层,或者简单的重新布线。

阅读 Spectrum 上的这篇文章让我想起在过去的 5-10 年里情况并没有改变,我们仍然不知道大脑有多少功能,我们仍然没有工具来研究这个问题。有很多来自 T2 的信息来支持这种说法,在美国的 T4 和欧洲的 T7 都有两个关于研究大脑的大型项目,但都非常有限。我并不否定这个领域,我只是在这里陈述我的观察。我希望一些聪明的人来发明新的工具,就像我已经尝试过的,现在可能已经失败了。但请让我们停止用几根电线戳大脑,并继续声称脑电图有一天会解决我们所有的问题。如果我们能在神经科学领域取得一些进展,我会是一个非常高兴的人,但我认为目前的做事方式、基础研究、目标和工具必须重新设定和设计。

也许这就是为什么在这篇 IEEE Spectrum 文章中,所有神经科学家都说要达到人类水平的人工智能需要数百年,而所有人工智能研究人员都说需要 20-50 年。因为在神经科学中,到目前为止,在解释神经网络方面几乎没有进展,而在人工智能/深度学习中,进展每天都在发生。我称之为人工智能/神经科学鸿沟,它只会越来越大。

神经形态芯片注定要进行深度学习——或者默默无闻 我们现在就可以建造一个人工大脑 :这个我们已经在这篇文章中广泛讨论过了。

为什么鼠脑机器人如此擅长导航不熟悉的地形 : 注意我们在这里实现了一个类似的系统。它所要做的就是记住某个位置的景色。因为导航是任何在环境中移动的物体的基本需求,所以从某个角度来看,它可以被实现为空间的表示。知道自己在哪里,就意味着回忆起某个景色。

能否量化机器意识? 意识只是世界和自己的模型。喜欢从另一个人的角度看自己,但完全意识到自己的感觉和感官。任何具有足够计算能力的大脑都将能够做到这一点,无论是在硅中还是在生物学中。随着我们构建越来越复杂的人工神经网络,我们看到了同样的模式:最终,少数神经元对各种“体验”进行编码。现在他们可能会对对象和类进行编码,但他们也可以对奖励和惩罚进行编码,并且很快会对动作和延期奖励等长序列进行编码。这些与人类的经历没有什么不同,甚至就神经科学所能告诉我们的而言。

我不相信意识是人类的特权,任何足够大的人造大脑都能够创造一个自身和环境的模型。事实上,我们已经论证过这必须能够预测环境中发生的事情以及我们行动的结果。我对这篇文章评价不高,我更希望看到作者用他们的智慧来帮助我们创建有用的系统,而不是那些关于哲学和任何人都可以谈论的事情的猜想。

最让我困扰的固着是:人类是特殊的,人类的大脑是特殊的,没有什么会永远比较,没有什么能更好。这都是胡说八道。在进化史上,我们看到这种情况一直在发生。我们已经从单细胞生物进化成我们现在的样子,尽管我们更有能力适应其他生命形式,但这并不意味着我们将永远如此,或者我们有一种特殊的属性。我们的 DNA 基本上和这个星球上的许多其他生物是一样的!我们一直在进步,我们很幸运现在处于领先地位,但这并不意味着会持续下去。不管有没有你,进化都在继续。

而我们在这个星球上的进化就是使用的生物材料没有人说我们不能从岩石和金属中,或者从火和烟中创造智慧。事实上,它可能已经发生了,但我们有限的感官可能阻止我们看到它。认为人类在任何方面都是特殊的想法都不是很开明,事实上,如果你环顾四周,你会看到人类在未来的某个时候会像现在的蟑螂一样。

后手稿

PS1:为什么我们要复制大脑,第二部分:许多人认为人脑和人类是特殊的,但如果你看看进化树,我们可以看到我们唯一的优势是我们在金字塔的顶端。但没别的了。其他较低的生命形式与我们有很多共同之处:当我们面对更高的智慧时,我们会有同样的命运。我们可能被更高的智慧拜访,或者我们可能创造它,我认为这将在很短的时间内发生。正如 Jürgen Schmidhuber 在文章中所说,一旦我们创造出比我们更有智慧的东西,这种智慧很可能会想要探索和理解我们生活的宇宙,不受生物躯体和(相对)较短时间框架的限制。

但在真正的超人 AI 出现之前,我们将尝试在计算机程序中复制许多其他人类能力,如绘画、制作艺术、绘画、雕刻、制作音乐等。虽然开始时合成艺术可能只和人类一样好,但它最终会进化到更高的形式,也许是我们永远无法理解的形式。

关于这个话题的一部有趣的电影是超越。我喜欢这部电影中的人工智能为了更大的利益与人类融合的方式。

PS2: 如果一个神经元有 10000 个输入,但只有 100 个是活跃的,这是一个稀疏信号。如果你有一个 100 个输入都活跃的神经元,这并不稀疏,但交流的数据是相同的,因此系统的效率。

如果你担心机器会抢走我们的工作,不要担心!在一个机器做我们所有工作的世界里,我们将不再需要工作,我们可以只是玩耍和娱乐!我们也不想要那些机器将会做的工作,因为我们正试图摆脱危险和无聊的工作,花更多的时间像《T4》中的人类一样结束自己的一生

更多信息:

想了解更多你在这里读到的内容:请看这段视频。

关于作者

我在硬件和软件方面都有将近 20 年的神经网络经验(一个罕见的组合)。在这里看关于我:媒介网页学者LinkedIn 等等…

我们能不能不要再用单词云了

原文:https://towardsdatascience.com/can-we-please-stop-using-word-clouds-eca2bbda7b9d?source=collection_archive---------2-----------------------

自然语言处理中有很多有趣的、更科学的问题,但我今天在这里只是和大家分享一个观点。

字云是一流的丑陋。

有时候感觉就像人们把他们漂亮的大数据放进一个单词云生成器,把它粘在一个布里斯托尔板上,然后在科学展上迟到两个小时。

我刚刚关闭了本来会是一篇好文章的浏览器,因为他们巨大的文字云刚刚开始对我大喊大叫。“数据科学”、“机器学习”、“内容分析”!我已经读了标题,我看到了标签…那张图片真的有任何附加值吗?它向读者传达了什么重要的信息吗?

这就是为什么我对他们有如此强烈的感觉。语言的意义不仅仅存在于关键词中。

名词、形容词、动词重要。并不意味着停止单词限定词介词删除。

如果你必须重读最后两句话,你可能会意识到除了关键词之外,保留停用词(如“the”、“of”、“should”)也是必要的。比如的句子“生存还是毁灭”,虽然有些古旧,但是 完全是由停止词 组成的。

从文章 URL 的搜索引擎优化(SEO)角度来看,这可能是一个更好的停用词移除出错的例子:

  • https://www。 …。/伴着失聪长大→/伴着失聪长大
  • /听力受损的世界→/听力受损的世界
  • /什么是听力损失→/什么是听力损失

(来源: 网络媒体大师 )

或者,这里有一些昨天的热门推文,没有停用词:

  • "很遗憾听到马尔科姆·杨,优秀的球员."
  • “马克·斯通男孩”
  • “亚历克斯·崔贝克应得人物乡村游戏节目主持人。”

如果人类有这些我们实际上经常使用却没有注意到的奇怪的习惯用语会怎么样呢?

  • “他打了…指甲…头”
  • “……果壳”
  • “她今天真的……很开心”

停用字词删除减少了处理时间。它使语言分析的效率大大提高(对计算机来说!).但是,如果你曾经生成过一个词云,提取了一个完全不相关的关键词(比如来自马克·斯通的词云,其中有“男孩”),你可能会同意关键词频率或词袋不能是一个独立的分析。

语言数据可视化需要有一些分类的成分(见:任何好的机器学习)。

我们都为此感到内疚。我做过一两个单词云。但是我们不再需要文字云了。我们比那更好!我想介绍 3 个我觉得更有趣(也更有知识性)的选择。)而不是这些美化的标签。

桑基图

UX 设计师罗宾·维斯用一年半的时间绘制了她的哭泣模式。她想更好地理解自己的情绪。通过创建桑基图,她能够显示她对每种叫声的分类,以观察趋势。

A Classification Diagram of Cries

以下是桑基图的工作原理。他们想象从一套价值观到另一套价值观的流动。它们非常适用于分级多元分类数据。连接被称为链接,就像一个树形结构,被连接的东西被称为节点(来源: Google Charts )。

韦斯发现,分手和恋爱是她 63%哭泣的根源。她根据原因对她的哭声进行了分类。在分手的情况下,她确定了不忠,损失,试图让它工作,并管理他人的反应。从那以后,她用形容词来提炼她为什么会哭背后的情感。在这里阅读全文

这是一种有机的、令人难以置信的独特方式来展示关键词分析,只需要一个小数据集,想必也不需要什么花哨的机器学习。接受吧,情感分析。

平行集

并行集也显示数据流。来自英国的自由软件开发者杰森·戴维斯创造了一个泰坦尼克号幸存者的可视化图像。去这里看互动版。 他的代码也在这里。

乍一看似乎很吓人(也很催眠),但下面是这张图所暗示的。

  1. 女性幸存者的相对比例远远大于男性幸存者。(第 1 行,蓝色)
  2. 船上大约一半的孩子活了下来。(第二排最左边)
  3. 一眼就可以看出,这些数据与疏散过程中“妇女和儿童优先”的方法相关。

戴维斯说如何阅读图表:

“对于每个维度(幸存者、性别、年龄和阶级),每个可能的类别都会显示一个水平条。条形的宽度表示该类别匹配的绝对数量。

“从第一维度(幸存)开始,它的每一个类别都与下一维度的若干个类别相连,显示出那个类别是如何被细分的。这种细分递归重复,产生一个“丝带”树。

因此,平行集提供了一种方法,可以同时可视化不同种类的数据,并快速从中得出结论。如果你有混合了人口统计信息和语言信息的数据,那么很容易回答“谁说了什么”。比“没人说一个字云什么的”有趣一点。

聚类图

我发现这个提交给联邦通信委员会的关于网络中立性的意见的惊人的可视化。旧金山一家名为 Quid 的数据分析公司对近 25 万份提交材料进行了主题建模。这不是一个小壮举。你可能需要一点深度学习。还有资金。和来自科幻的天才。

简而言之,每个集群都有一个不同的主题,响应的比例以灰色显示。更紧凑的集群争议更少。更接近其他聚类的聚类显示主题之间的相关性。如上所述,外围集群对整个对话来说不太重要,但它们被认为更独特。

话虽如此,但如果能更深入地了解这种方法,看看是如何偷工减料的,那就更好了。作为局外人,它看起来像是一种无监督的机器学习算法,可能是 K-means,这通常意味着将观察值划分为指定数量的簇。或者,如果这是某种贝叶斯分类,我也不会感到惊讶,这种分类对语言数据很有效。这里看起来它最大的优点也是它最大的缺点——这是一个非常固执己见的分析。

不是每个人都能做机器学习。请放心,我一点也不想忽视这样一个事实:从数据收集到一幅漂亮的图片,需要数周的数据清理、数据透视表和对一切事物的质疑。但是数据科学中的想法是一样的。将您的数据分类。画趋势线。如果有必要,可以手动操作。做一些假设,建议一些关联,或者根本不做分析。

不要让数据自己说话。聚集你的云。

我们能预测烂番茄收视率吗?

原文:https://towardsdatascience.com/can-we-predict-rotten-tomatoes-ratings-8b5f5b7d7eff?source=collection_archive---------13-----------------------

什么时候一部电影其实是烂的还是新鲜的?

像 IMDb 和烂番茄这样的电影评论网站已经成为许多影迷生活的一部分。

电影观众可以通过查看一个数字(电影评级在 0%到 100%之间)轻松确定观看什么电影并比较某些电影。

但是……你有没有想过这些评级是如何确定的?

Picture Source: http://you-deserve-this.blogspot.com/2012/08/imdb-top-250-vs-rotten-tomatoes.html

一些票房大片和“经典”在这些网站上的电影评级相当低,这并不罕见。这让我们想知道你在网上看到的电影评论实际上是否反映了大众的观点?

看看 IMDb 和烂番茄,我们发现这两个电影聚合网站都没有说明他们的电影评级百分比是如何计算的。

IMDb 的帮助页面:

我们采用 IMDb 注册用户的所有个人评分,并使用它们来计算单个评分。我们不使用算术平均值(即所有投票的总和除以投票数),尽管我们在投票细分页面上显示了平均值和平均投票数;相反,显示在标题页面上的评级是一个加权平均值。

烂番茄《关于页:

Tomatometer 评分代表专业评论家对给定电影或电视节目的正面评价的百分比。在电影或电视节目收到至少五条评论后,就可以计算出电影或电视节目的自动评分。

由爆米花桶表示的观众分数是对电影或电视节目给予正面评价的所有用户的百分比。

最初,我们感兴趣的是了解 IMDb 加权平均的特征,但是他们的使用条件禁止数据抓取。因此,为了我们的项目,我们与烂番茄合作。

构建电影评分模型

我们最感兴趣的是回答两个关键问题。

  1. 在计算收视率时,烂番茄是否更强调电影评论的某些方面?
  2. 烂番茄的收视率和它的观众评分有关系吗?

在我们探索是否可以创建我们自己的评分机制的过程中,我们采取了几个步骤。

阶段 1:定义数据集

我们手动选择了大约 150 部烂番茄观众评分在 0-100%之间的电影。我们的目标是让电影收视率在四分位数之间平均分布。下面展示了落入每个四分位数范围的电影的分布。为了保持一致性,我们将 0–25%的电影作为第一个四分位数,26–50%作为第二个四分位数,51–75%作为第三个四分位数,最后 76–100%作为第四个四分位数。

数据集中观众和观众评分的分布:观察值

我们在建立电影列表时注意到的一件事是,烂番茄电影的收视率很少低于 25%。因此,您可以看到,虽然收视率在前三个四分位数的电影数量相对一致,但在收视率前四分位数和前四分位数的电影数量之间存在明显差异。

我们认为,缺乏收视率很低的电影是因为收视率是由大量烂番茄用户产生的,他们没有权力或资格对电影进行评级。任何人都可以去烂番茄给任何电影打分。因此,分数可能会被那些仅仅因为喜欢这部电影而给出很高评级的人扭曲。或者,因为这些评级是由所有用户产生的,它们更准确地描绘了公众的意见,人们通常倾向于喜欢大多数电影,并给它们更高的评级。

Number of Movies for each Quartile for Tomatometer and Audience Scores

有趣的是,尽管我们的数据集是根据观众评分建立的,但我们注意到观众评分的四分位数之间的差异程度较低。

我们认为这是因为 Tomatometer 评级是由合法的、经认可的电影和电视评论家制作的。这些评论家的职业是比较和评价电影,因此,他们能够确定在电影业中什么被认为是“坏”或“好”的电影。因为他们在电影评级方面更有技巧,我们认为这些评论家可能对电影持有更强烈的观点,并倾向于根据他们的观点对电影进行很高或很低的评级。

接下来,我们对这部电影的哪些信息最感兴趣?

Screenshots from Titanic on Rotten Tomatoes

  • 观众评分。这个分数“是所有给电影…正面评价的用户的百分比,” 3.5/5 星及以上是正面的。任何烂番茄用户都可以给出观众评分,而不仅仅是电影或电视评论家。
  • 观众点评。书面评论
    附有任何烂番茄用户给出的星级评定。
  • 烂番茄电影页面网址。我们跟踪 URL 更多是为了日常管理,以防我们想要返回页面收集更多信息。

阶段 2:收集数据

因为访问烂番茄的 API 需要批准,所以我们转向使用 BeautifulSoup 来构建我们的数据集。

在收集数据的过程中有两个主要步骤。

  1. 网络抓取:我们迭代开发了几个 Python 类,帮助我们获得前面提到的正确的电影属性。我们类中最重要的部分之一是有一个分页参数,在这里我们可以指定我们想要多少页观众评论。
  2. 迭代地将数据写入输出文件:JSON 输出文件被迭代地写入,以防止脚本可能崩溃并清除先前擦除的数据。这在初始测试中特别有用,可以帮助我们调试和简化流程。
class TextReviews():def __init__(self, url, limit=1):
  self.page = AudienceReviews(url)
  self.limit = limit
  self.reviews = []# helper function to page for reviews, outputs as an array of reviews
 def getReviews(self):
  for i in range(self.limit):
   self.reviews += self.page.getReviews()
   next_page = self.page.nextPage()if next_page:
    self.page = AudienceReviews(next_page)
   else:
    break# return ''.join(self.reviews)
  return self.reviews

[*score.py*](https://github.com/estherelle/fresh-or-rotten/blob/master/score.py)节选,我们用来刮烂番茄的观众评论。**

我们为我们的电影列表和每个相应的 URL 创建了一个. csv 文件。我们从每部电影中提取所需的数据,转换成 JSON 数据格式,如左图所示。我们还将每部电影添加到其相应的分级四分位数中。

Dataframe of Movies after Loading JSON

然后,我们将数据加载到 pandas 数据框架中,如上所示。我们将包含每部电影的观众评论的字符串列表转换为一个字符串。然后,我们通过执行基本的文本预处理(如小写、标点符号删除和停用词删除)来清理数据。除此之外,我们还做了词汇化,而不是词干化,因为它将单词转换成它的词根,而不是去掉后缀。

阶段 3:创建分类器

现在,我们需要创建分类器,将观众评论字符串转换为评级(为了提高准确性,我们选择按四分位数 1、2、3、4 对其进行评级,而不是分配精确的评级)。

我们的目标是建立一个分类器,预测给定电影的评级落在哪个点范围内——或者哪个四分位数。对于我们的初始数据集,我们试图从收视率似乎均匀分布的电影列表中抓取。我们还将观众评论的页数限制在 20 页,这样我们就可以最大限度地减少流行电影和不太流行电影的观众评论数量之间的差异。

为了使矢量器、转换器和分类器更容易使用,我们使用了一个 scikit-learn 管道类,其行为类似于一个复合分类器。使用普通的 TF IDF 和朴素贝叶斯分类器,我们得到了 28%的准确率——非常低。我们意识到这是因为我们的分类不是二元的,而是多类的,这意味着它使用了多个相互排斥的标签。因此,我们切换到 OneVsRest 分类器,仍然使用 TF IDF。我们的准确度结果要好得多。

分类器准确度

TOMATOMETER

正如我们的图表所示,我们的分类器在预测电影时最准确,这些电影将落入电影评分的第二和第三个四分位数。

收视率

正如我们的图表所示,我们的分类器最准确地预测了将落入观众评级第一四分位数的电影。

我们认为观众评论总能准确预测收视率,这让我们对这些结果感到非常惊讶。因此,我们已经证实了我们的假设,即这些电影评级并不反映一般公众的实际意见。这让我们相信,也许烂番茄在收视率中包含了其他他们没有透露的因素。

TOMATOMETER 与观众评分

对于第一个和第四个四分位数,我们的分类器对收视率产生了更准确的预测。然而,对于第二和第三个四分位数,我们的分类器更准确地预测了 Tomatometer 评级。我们的分类器向我们表明,使用烂番茄的观众评论,我们无法始终准确地预测这些电影的观众评级或自动评分。因此,很明显,在决定烂番茄网站上显示的评分时,还有其他因素需要考虑。

摘要

从我们的研究中,我们能够确定烂番茄上的电影评分,以及其他网站上的评分,并没有准确地显示公众对这部电影的看法。尽管我们预计观众评分与观众评论的制作评分不匹配,但我们惊讶地发现,观众评分也没有反映观众评论。

这是一个非常有趣的尝试,看看我们如何根据公众评论建立自己的电影评级机制。观众影评中的一些值得注意的词显示在下面的词云中:

Word Cloud Generated from Review Text Input

我们建议电影观众警惕他们在电影网站上看到的电影评级,如烂番茄和 IMDb。这些分数中包含的信息不能准确反映人们对这部电影的真实想法。由于各种原因,这些分数可能会有偏差,并且可能会受到烂番茄的影响,从而影响利润和收视率。我们希望继续这项研究,以发现这些分数中包含的元素是什么,以及它们是否准确反映了人口的意见。

如果有兴趣,可以在这里查看我们的代码。我们的存储库包含运行烂番茄刮刀和分析所需的所有源代码。

【2018 年秋季 DIS 大数据计算分析最终项目

在媒体上关注我们:罗宾·罗斯萨尼卡·巴帕特埃斯特·l .

我们能拯救 DataViz 吗?还是现在只是仪表盘?

原文:https://towardsdatascience.com/can-we-save-dataviz-or-is-it-just-dashboards-now-f55b6097172b?source=collection_archive---------9-----------------------

Not this.

2012 年是令人兴奋的一年。我离开了科学,试图将平面设计这一爱好转化为职业。我没有意识到的是我的时机是多么幸运。数据可视化在公众眼中获得了极大的吸引力:为了应对大数据,报纸、品牌代理和企业都想加入到第一波数据浪潮的顶峰信息图表中。

对信息图表的需求,以及更普遍的数据可视化,为怪人提供了一个独特的机会:一个科学和艺术相遇的地方;编程、分析和设计方面的技能可能都有用——并带来有报酬的、不无聊的工作。

我很幸运,也许是有天赋,现在能够在这个奇怪的十字路口生活一段时间了。但我担心它变小了。信息海报的时尚肯定已经结束(尽管有限的需求依然存在)。记者们仍在制作图表(有时非常有创意),但有多少媒体能真正资助这项工作呢?细读求职公告板,现在所有与可视化相关的东西都是业务分析——也就是仪表盘。

正如 Elijah Meeks 和其他人所指出的,这种工作是合法的,但也是极端保守的:主要是线条、栅栏,也许还有一个燃料表。这与“数据艺术”相去甚远(在学术界之外,原始的 ggplot2 图表仍然是完全可以接受的)。自然,被雇佣来做这项工作的是工程师;因为它主要是技术性的。就是前端开发,数据角力,管道,数据库。

就目前而言,这一切都很好。但是我想知道,设计在哪里呢?独特技能的交集在哪里?

当然,这对企业来说不是问题:他们没有义务雇佣我做我想做的工作。但对于数据 viz 领域来说,这可能是一个问题,如果它真的存在的话。如果我们只有工程和一些 D3 库,我们终究没有一个独特的领域。我们所拥有的,也许是工程和设计的短暂融合,这种融合再次分化。设计师,甚至是“信息设计师”大多会回到他们在“DataViz”出现之前的小口袋里。

与此非常相关的问题,也是以利亚提出的问题,是当前人们在数据世界中会发生什么。当他们 30 多岁的时候,他们会去哪里,他们厌倦了做繁重的工作(有点像代码猴子、分析师和初级设计师)。没有明显的晋升途径,除非在极少数情况下,报社或设计室在 DataViz 雇佣了很多人,并且需要一个部门主管。因此,你让工程类型的人跳过去称自己为数据科学家,或者最终成为管理人员。设计总是有一个狭窄的晋升通道,紧随其后的是设计师:艺术/创意总监。但是一个也懂数据的创意总监有什么作用呢?因此,当有经验的从业者试图走出战壕时,我们又有了分歧:他们必须在别处找到一个更传统的家。

我希望数据可视化,或者说数据设计,成为一个东西。我希望它成为一条可行的职业道路——即使是一个小领域。我想要这个有几个原因。

第一个:我很自私,想要选择更有趣的工作——尽管我从来没有很难找到工作。

两个:对于那些坐在艺术和科学以及技术性的分界线上的人来说,已经没有足够多的职业轨迹了(建筑是其中之一;也是一种艰难的谋生方式)。

三个:数据在我们的世界里真的很重要,交流数据也很重要;这不仅仅是一项工程任务。

:我担心大企业最终会意识到实时仪表盘没那么有用。也许它们都只是一时的流行。那么谁还需要 DataViz 呢?让人工智能告诉我们该做什么。

我错过了什么吗?DataViz 将何去何从?

我们能用数据来巩固民主吗?

原文:https://towardsdatascience.com/can-we-use-data-to-fortify-a-democracy-adb019d35ba9?source=collection_archive---------9-----------------------

作者安迪·克拉科夫

无论你的政治信仰是什么,我想我们都同意,现在很难——也许比十年或二十年前更难——与不同立场的人就政治进行坦诚、富有成效的辩论。

如今,政治对话似乎很容易演变成党派之争,很快变得具有煽动性,站在过道对面的其他人会引用人们可能会质疑其真实性的信息。然而,我想到,我可能提出来支持我的论点的看似客观的信息可能同样会被驳回,被贴上不可靠的标签,其来源的偏见是显而易见的。

这让我开始思考,当我们不都在参考同一个剧本时,民主是否真的能有效运作。

如果我们不能消化大致相同的信息来帮助我们做出公共决策,我们能像一个国家一样,一起走过同样的路吗?

这些天来,我们似乎越来越有可能从量身定制的来源获取信息,以反映我们的个人兴趣和观点,无论是从符合我们政治倾向的有线新闻频道、脸书、推特、博客圈还是其他地方。毕竟,现在获取定制信息是如此容易,而以前我们的媒体选择更加有限。结果,我们最终消化了不同的信息,并相互交谈,而不是相互交谈。

上个世纪我们赖以为决策提供基础的中间立场不再像过去那样稳固。例如,我们曾经为了提供一个共同的脚本并作为更有意义的对话和辩论的催化剂而求助的新闻媒体现在被贴上了假新闻的标签,败坏了整个新闻领域的名声。

在这个新的信息环境中,我一直想知道数据能发挥什么作用?也就是说,纯粹的事实——比如来自人口普查局(如贫困率)、州教育部(如阅读能力得分)或劳工统计局(如失业率)等政府来源的事实——能为我们集体提供一些共同的工作基础吗?

这个前提听起来很天真,好像我是某种不可救药的浪漫主义者。我当然认识到,有些人可能有理由怀疑是否存在纯粹的客观性,即使有数据也是如此。例如,我们中的一些人可能会质疑政府数据的来源,或者我们可能会质疑信使——倡导组织、学术研究等。—提供对政府调查结果的二次分析。不过,我不禁想到,公共数据可能是我们可以用来弥合信息桥梁的少数来源之一,而这座桥梁曾经是我们不同观点的交汇点。

如果我们能够找到与事实的共同点,例如关于我们社区状况的当地数据,我们可以利用这些信息来帮助讨论如何解决当今的紧迫问题,如阿片类药物滥用、犯罪、就业和工资增长等。

这给事实和数据带来了很大的压力,特别是因为我们这些在社会部门工作的人,我认为,在利用数字提升公共话语方面取得了可疑的成功。当然,有数据帮助左右公众舆论、授权社区动员行为改变或教育我们政策选择的例子,但这些成功的故事似乎都太罕见了。

然而,尽管在使用数据实现社会影响方面缺乏具体的成功,但更多的社区和组织显然正在使用数据参与作为推动变革的战略。因此,随着我们这些社会部门的人越来越依赖数据作为教育和说服的手段,我们可以共同做些什么来确保这些数据具有说服力?根据我在过去六个月里与公共部门的一系列人员的交谈——研究人员、流行病学家、倡导组织、政府机构的领导、公民技术专家——以下是我听到的关于数据如何产生更大影响的信息。

1.我们需要将数据与讲故事结合起来

我们的大脑对故事感兴趣,毫无疑问,当信息被呈现为关于受影响个人的个人的辛酸故事,而不是关于趋势和差异的匿名汇总数据时,我们大多数人会更加注意。我想这可以归结为进化生物学。如果你看看人类历史的轨迹,你会发现我们大部分时间都生活在不到 100 人的小部落和社会单位中,所以我们可能很难从认知上理解几十万人的城市或拥有几百万居民的多样化国家的概念。

俄勒冈大学的心理学教授保罗·斯洛维奇注意到了这一现象,他观察到,“如果我看着质量,我永远不会行动。”他解释道:“我们的认知和感知系统似乎旨在让我们对环境中的微小变化保持敏感,这可能会降低我们检测和应对大变化的能力。”他最后指出,“行为理论和数据证实了敏锐的人类行为观察者早已知道的东西。人类生命的数字表示不一定传达这些生命的重要性。很多时候,这些数字代表的是干巴巴的统计数据,“眼泪已经流干的人类”"

所以,毫无疑问,我们需要故事来帮助我们追求的目标公开化。但是我们也不应该离数据太远。毕竟,我们肯定需要关于问题的程度和性质的数据来帮助我们创造持久、可行的解决方案。

在数据和故事之间取得平衡绝非易事。我们中的一些人只是用数字来思考。例如,当我在加州卫生保健基金会(California Health Care Foundation)帮助卫生部门更好地与数据沟通时,一位流行病学家观察到,“对数据人员来说,最难的事情是说英语,第二难的事情是用英语写作。”当然,我们中的其他人通过故事的语言进行交流,并没有很好地掌握如何用数据进行论证。因此,我们在历史上将两者一分为二。我们所呈现的要么是数据,要么是故事,但不是两者都混合在一起。

幸运的是,如今人们越来越关注数据故事,这对我们试图用数据影响他人是个好兆头。但是意识到需要用数据来讲述故事是不够的。就我所见,我们大多缺乏用数据讲故事的集体技能和经验;这不是我们习惯使用的肌肉。在这方面,我们有太多的东西要学习,这是我的组织 Velir 想要帮助解决的问题,包括为我们的客户和其他专注于通过数据进行社会变革的人举办会议,并与客户合作,帮助他们培训数据故事。了解其他人在做什么也是很棒的,可以帮助我们社会部门更好地用数据讲述故事。

2.在发布数据可视化之前,我们需要站在终端用户的角度考虑问题。

当我们发布数据发现时,我们通常不会考虑最终用户希望如何消化我们提供的信息并与之互动。他们会在公开会议上查看这些数据吗?当他们第一次接触数据时,他们会在电脑或手机上吗?他们希望在线查看信息还是通过打印的情况说明书查看信息?

很多时候,我们根本没有这类问题的答案。我们花费了如此多的精力去寻找、分析和可视化数据,以至于我们几乎没有时间去思考如何最好地展示和包装这些发现。当我们了解到即使是少量的设计思维——也就是站在最终用户的立场上,根据他们的反馈对原型进行迭代——也能对创建有用的数据工具大有帮助时,我们的情况会好得多。

例如,我记得我在 LiveStories 时所做的工作,帮助加州各县交流阿片类药物流行的数据。我对如何最好地呈现这些信息做了一个假设——也就是说,作为长篇新闻,观众可以垂直滚动浏览一张由图表和地图组成的报告卡。然而,我遇到的一个在加州农村地区负责阿片类药物滥用工作的人向我指出,这种演示在她分享发现的场所——面对面的社区论坛或通过对县监事会的现场演示——根本不会有效。

她的需求要求以另一种方式包装信息——例如,以一系列幻灯片和打印的情况说明书的形式,人们可以在会议结束后随身携带。仅仅接触这个人并在喝咖啡时进行对话就有助于提供如此有价值的见解,我相信如果我们在构建之前留出一点时间来了解最终用户希望如何与数据交互,我们都会从我们的数据项目中受益。

3.我们需要将数据导向解决方案

我们从政府来源获得的大部分数据都暴露了不足之处,而且从经常被负面框定的发现中采取行动肯定不会令人鼓舞。要求政府机构收集和报告不太关注问题的数据可能有点过分。那是一项艰巨的任务。毕竟,我们以这种方式收集数据是有充分理由的,例如,衡量那些生活在贫困中的人,而不是那些生活在贫困中的人。这些行政数据通常是以这些负面的方式收集的,因为政府需要知道他们必须向谁提供服务。

尽管如此,过多地关注数据来框定问题,而不是解决方案,可能会削弱我们。一位在县政府工作的人曾对我说,数据来得很快,就像她说的那样——也就是说,她可以在短短 15 分钟的数据分析中提出几十个问题。然而,她指出,如果她将这些发现分享给那些在紧张的预算下努力满足现有需求的过度劳累的非营利组织,根据她的数据分析,解决更广泛需求的想法将会打击非营利组织的士气。

数据不应该打击我们的士气。

那么,如果我们不能轻易地重新构建收集和报告负面数据的方式,我们能做些什么呢?如今,人们越来越关注编目解决方案。例如,解决方案新闻网络维护着一个故事追踪器,它现在运行着大约 2900 个故事,在这些故事中,记者报道了社会问题的解决方案。这意味着,即使数据总是将问题框定为问题,我们也可以更容易地找到解决方案——甚至可能是来自与我们的概况相匹配的社区的解决方案,并且是积极的异常值(也就是说,在度量上比预期表现得更好)。

当我们采取将数据与解决方案相结合的方法时,我们将处于一个更好的位置来激励和指导行动,而不是主要关注通过数据来暴露缺陷。

4.我们都需要教练。

作为 Velir 在发展中国家开展的医疗保健项目的一部分,一位拥有多年医疗保健数据工作经验的著名学者向我观察到,当个人看到与他们相关的数据时,例如他们所服务的社区的健康结果,用他的话说,他们可能会有“矛盾的感觉”。客观地说,他们理解这些发现,但是很难从等式中去除他们的激情和偏好。因此需要教练。这个人设想的是公正的个人,可以为那些生活在这些数字中的人解开数据发现;帮助我们看到意义以及具体要关注什么;引导我们找到解决方案。

“事实是,当我们被与我们相关的数据所冲突时,我们可能不在最佳行动位置,但如果我们有教练可以陪我们一起走下去,我们可能会发现从问题走向解决方案会更容易。”

这种数据教练的想法肯定不容易广泛实施。已经有一些公正的教练帮助社区理解关于他们的数据的例子。我们应该试着从这些例子中积累经验,看看是否有经济有效的方法来实施数据训练计划。例如,一个县的卫生部门主任可以指导另一个县的卫生部门主任,而另一个卫生部门主任可以指导她吗?

5.如果你建造了它,他们就会来(但前提是你要传达你所建造的东西!)

当我们启动一个数据可视化/讲故事的项目时,我们通常会松一口气,因为它已经完成了。但是真的做到了吗?没有一种神奇的方式可以让一个形象简单地出现在某人的脑海中,这意味着我们必须做艰苦的(并且经常被最小化的)工作来传播我们发布的内容。

沟通计划可以包括社交媒体、新闻策略、电子邮件推广、面对面演示或其他组织和激励社区人员的方式,当然,这可能意味着与您所在组织中能够帮助传播信息的信息大使合作。然后,你可能需要在持续几个月而不是几天的活动中重复这些步骤。

把注意力放在这上面似乎很费时间,但是除非我们花时间,否则我们就冒着构建惊人的可视化效果而不被注意的风险。如果他们没有被注意到,我们如何根据这些明智的信息采取行动呢?只有当你主动推出信息并加以利用时,你才会开始看到天平的指针从仅供参考的一方倾斜到行动的一方,甚至是我们可以根据调查结果认真讨论政策方向的一方。

所有这些都不容易实现,但如果数据以枯燥的方式呈现,无法激励我们采取行动,那么这些数据又有什么用呢?如今,我们对数据寄予了很大的希望——这是正确的——但我们必须学会如何说服数据并与之沟通,而不仅仅是被动地展示发现。

我想了很多华盛顿这些天是如何制定政策的。在大多数情况下,我不知道我们的医疗保健系统或税法的这种重大变化是否对我们的集体有利。我有我的偏见,这通常是由我选择消化的信息决定的。问题是,当我们没有一个集体的机会来评估,使用我们都同意的度量标准时,政策就被匆忙实施了。

结果,我们只能靠自己的手段来帮助引导理解,而这通常意味着要听政客们的花言巧语,这些花言巧语表现为尖声辱骂和对政策的消极或积极后果的夸张讨论。这是形成能对我们和我们的孩子产生持久影响的有效政策的方法吗?

我们的民主还能承受多少没有事实根据的政治争论?

我们显然需要更好地将数据整合到我们的决策中。我想我们很多人都会同意这一点。但是我们也需要知道如何更好地利用这些数据来为公众辩论提供信息。

通过我在 Velir 的工作,我尽最大努力将我们从客户和亲密合作伙伴那里学到的这些智慧结晶铭记于心,确保它们是 Velir 与我们的客户一起工作的前沿和核心,我们的客户对实现数据的影响力非常感兴趣。

我肯定还有其他我没有在上面提到的步骤。你从数据参与前沿学到了什么吗?我很想听听你想到了什么。请在 andy.krackov@velir.com 给我发一封短信。另外,请在下面添加您的评论或发微博给我们, @Velir

你现在能听到我吗?远场声音

原文:https://towardsdatascience.com/can-you-hear-me-now-far-field-voice-475298ae1fd3?source=collection_archive---------1-----------------------

在我之前的帖子中,我提出了一个案例,即成功的人工智能公司将通过围绕数据创造网络效应或开发专有算法,在“计算语音”价值链中开发一条护城河。在这篇文章中,我将研究价值链的第一步,语音信号的最初拾取,并找出创业公司可以成功的机会。

放大声音

语音控制是一种与硬件和相关服务交互的直观方法。这比连接键盘和鼠标、敲击屏幕键盘或点击遥控器要自然得多。

随着我们看到越来越多的语音激活设备,了解设备如何能够监听和理解语音命令是非常重要的。这个过程中有许多组件,但我们将研究的两个组件是麦克风阵列(硬件)和深度学习架构(软件),它们使这样一个复杂的系统工作。

硬件|麦克风阵列

语音识别系统通常使用多个麦克风来降低混响和噪声的影响。每一代 iPhone 的麦克风数量都在增加,从第一代 iPhone 的一个增加到 iPhone 5 和 6S 的四个。

甚至像亚马逊 Echo 这样的智能扬声器设备也使用了多达 7 个麦克风。实际上,回声麦克风是以六边形布局排列的,每个顶点一个麦克风,中间一个麦克风。每个麦克风接收信号之间的延迟使设备能够识别声音的来源,并消除来自其他方向的噪声。这种现象被称为波束形成。

软件|深度学习

深度学习在语音拾取方面发挥了基础性作用。识别口语的能力是几年前建立的,但深度神经网络(DNNs)等基于学习的技术已经允许语言处理在许多测试案例中达到或超过人类的表现。

AI Progress Measurement | Electronic Frontier Foundation: https://www.eff.org/ai/metrics

只有硬件和语音识别算法的强大结合才能带来产品的成功。对于糟糕的麦克风,无论采用多智能的深度学习模型,识别精度都会下降。另一方面,拥有次优机器学习的优秀麦克风并不能产生必要的准确性。

远场拾音的问题

虽然最先进的语音识别系统在麦克风靠近说话的情况下表现相当好,但在麦克风远离用户的情况下性能会下降。

想象一个常见的场景,一个人在室内,对着亚马逊回声说话。

回声捕获的音频将受到以下因素的影响:1)扬声器对着房间墙壁的声音,2)来自外部的背景噪声,3)来自设备扬声器的声学回声,以及 4)对着房间墙壁的输出音频。

这些因素都会导致低信噪比(SNR)、房间混响以及语音和噪声的未知方向,所有这些都是需要解决的重要挑战。随着用户远离产品的麦克风,语音级别会降低,而背景噪音级别保持不变。除了噪音和混响,其他挑战包括缺乏大规模远场数据和未经探索的高效深度学习架构。底线是,在这些远场场景中,语音识别和人类表现之间仍然存在巨大的差距。

远场拾音是如何工作的?

语音识别系统通常使用单独的模块来执行语音识别。

  1. 音频输入被发送到声学传感器,
  2. 其将声音信号转换成电子信号,然后转换成数字信号。
  3. 然后,它进入一个数字信号处理芯片,在那里用固定的嵌入式算法进行语音增强。这些嵌入式算法执行传统的信号处理技术:声源定位(定位声音的方向)和波束形成(抑制背景噪声)。
  4. 得到的增强信号进入用于语音识别的传统声学模型。

麦克风技术旨在用基于深度学习的可训练算法取代固定的嵌入式算法。

固定算法和组件的缺点是,它们无法适应建立在它们之上的可训练机器学习系统的其余部分。当你把一个可训练的深度学习系统放在一组固定的芯片上时,深度学习模型必须学习嵌入式算法正在做什么,撤销它,并在它的基础上执行自己的计算。这使远场语音识别变得复杂,因为音频输入已经失真,并且在 1)将信号从声音转换为电信号再转换为数字信号,然后 2)预处理的每个步骤中,您都会丢失信息。

谷歌一直处于这项研究的前沿,展示了使用原始波形作为声学传感器的输出,从而避免了当今系统内置芯片所做的任何预处理(即定位、波束形成)。

Google’s neural network adaptive beamforming model architecture

实质上,谷歌希望将这一过程中的第 3 步和第 4 步结合起来。这个想法是给麦克风阵列更多的自由度来优化基于数据的算法。对于声学传感器,你只希望它能够正确检测,不会增加太多的噪声或失真,并且系统的其余部分可以使用可训练的深度学习架构来检索其信息。

创业的机会

通常,固定算法是基于试探法为一般情况开发的,而基于深度学习的算法是用实际数据本身为特定任务训练的。当你有一个基于深度学习的系统时,由嵌入算法的固定芯片组成的麦克风可能不是你想要的。

在这种情况下,任何语音识别应用的理想硬件设置都应该在这些固定的嵌入式芯片上进行最少的数字信号处理。它应该接受原始波形,并在其上建立复杂的深度学习算法,这些算法既可训练又灵活。

接下来的问题就变成了,你是否可以收集大量的训练数据,为那个特定的硬件训练一个深度学习算法,或者使用其他深度学习技术来补偿声学传感器的差异。如今的问题是,深度学习语音识别模型是在不同硬件上收集的数十万小时的数据上训练的。

为了与拥有完整设计能力的大型科技巨头竞争,初创公司需要寻找机会通过数据、软件或自动化来破坏价值链。

硬件领域有着巨大的潜力,因为复杂的深度学习技术必须部署在高度定制的廉价硬件上。

the battle of voice-enabled hardware, @ziwang ’s toys

所有现有的主要数据集都将得到利用,这些模型的使用范围很广。为尚不存在的数据集构建基础设施来收集、注释和训练新模型的公司将会成功。

就拿像 Vesper 这样的公司来说。他们正在通过利用压电材料的物理特性来改变麦克风的设计方式(我将在未来的帖子中解释底层技术)。因此,他们的麦克风技术不会像传统麦克风那样受到灰尘和环境退化的影响,因此他们的麦克风质量更高,从而提供更高的保真度结果,作为传输的信号进行进一步处理。

生产级识别的关键是数据的广泛使用、数据扩充的先进技术和模型架构。

固定算法和组件的弱点在于,它们无法适应建立在它们之上的可训练机器学习系统。但是,如果你的端到端模型像上面讨论的那样,深度学习模型实际上可以通过将它们与总体目标相关联来学习应该提取哪些信息特征,这就是语音识别中解码的字符或单词。

自动化将包括个性化设备和持续学习。

例如,利用从特定用户收集的数据,可以优化整个管道以更好地了解该用户。

但是个性化仍然带来许多问题。在部署了良好的初始系统之后,随着行为的改变,深度学习算法需要基于使用的持续训练。

无论是为用户提高性能(例如,使用他们的语言、语音等),都需要优秀的硬件和智能软件。)或提供用户特定的解决方案(例如,具有个性化语音、个性等的助理。).个性化的硬件和深度学习系统可以在这两个领域带来竞争优势。

百度最近发布了他们的深度语音 2 系统,走在了这项研究的前沿。该系统完全由深度神经网络构建而成,仅用半小时的音频就可以学习一个人声音的细微差别,并可以学习模仿数百种不同的说话者。该系统赋予机器新的语音多样性,并将极大地为语音识别带来个性化和亲切感。

对于初创公司来说,一个有趣的个性化机会是率先将他们的语音识别系统应用于其他语言并进行营销。虽然像百度这样的公司可能会在不久的将来将 Deep Voice 2 改编成中文这样的语言,但这样的公司今天忽略了这个问题。

个性化的另一个有趣的领域和垂直利基可能是可访问性。例如,艾娃正在使用语音识别软件为有听力障碍的人将对话翻译成文本。同样,土耳其一家名为 WeWalk 的有趣初创公司正在为视障人士制造智能拐杖,并利用细微差别通信来实现他们的语音技术。

个性化和持续学习将加速语音优先革命,允许机器复制类似人类的交互,平滑尴尬的对话,并实现定制。

流利。总部位于蒙特利尔的 AI 公司正在软件和个性化方面进行改进。这家公司的解决方案试图直接从音频输入到自然语言处理,中间没有语音到文本的步骤,直接从口头命令和上下文中提取意图。通过这样做,他们的意图识别系统变得真正个性化,从用户依赖的口音、变化的上下文和声学行为中学习,以识别不同环境影响下的常用短语。

通过与原始设备制造商和供应商的进一步合作,Fluent。人工智能解决方案能够对收集的数据进行更多的控制。通过这种合作关系,流利。与传统技术相比,人工智能可以为原始设备制造商提供更快、更具成本效益的市场之路,以及更广泛的覆盖范围。

综上所述,如果一家规模较小、反应敏捷的公司专注于数据、软件和自动化这三个关键领域中的一个或多个,那么它就有很大的发展空间。最终,能够拥有整个语音堆栈的创业公司——包括通过硬件收集的数据和软件中可训练的深度学习算法——将具有竞争优势,在语音识别和语言理解方面提供更好的性能。

顶尖人工智能研究者对“模拟假说”的坦诚思考

原文:https://towardsdatascience.com/candid-thoughts-on-the-simulation-hypothesis-from-top-ai-researchers-c3e2cdea3ffa?source=collection_archive---------3-----------------------

我在奶头的一个黑暗的房间里,在一个之前的派对上,探究人工智能科学家的一些最深层的意图和信念。

  1. 我们生活在模拟世界里吗?
  2. 如果单方面选择,他们会摧毁文明和我们已知的宇宙吗?
  3. 他们计划在多大程度上确保我们的未来是“完全令人敬畏的”?

关于我们是否在模拟中的极端分歧

在自我介绍为 Quasar(模拟他们宇宙的研究生)后,我问他们在这个很难测试的命题上给出的概率是多少:“你生活在一个模拟中。”

如你所见,它们到处都是。 7 名研究人员有这样或那样的最大信心(0-1%或 99-100%),只有 9 人认为可能性在 10%到 90%之间。如果这个命题更容易检验,将会有一些重大的下注机会。

一名人工智能研究人员似乎完全准备好扼杀我们的宇宙

When asked why they answered: “Stare into the abyss, and the cocaine stares back.”

如果没有苦难,如果外面有比我们更聪明的生命,我们文明的终结就不会那么悲惨,但我坚定地站在地球生命延续的阵营里。接受调查的 26 名研究人员中有 25 名似乎同意我的观点。

4 名研究人员最初对上述问题的回答是肯定的。2 pretty 立刻承认他们是在开玩笑。一名研究人员承认,他只是出于病态的好奇心想要毁灭我们的宇宙,我不认为这种好奇心会发展到真的去按一个红色的大按钮。但是剩下的研究员似乎很认真。当被问及原因时,他们回答道:“凝视深渊,可卡因也会凝视你。”

一个数据点是很少的证据。但是考虑到 1%的精神病患病率,这些结果与预期相符(从调查犯罪人口中推断)。我仍然非常担心在未来的世界里会有更多的人可以单方面毁灭文明。熬过古巴导弹危机和其他类似的危机已经够难的了。

肯尼迪总统说,他认为导弹危机导致核战争的可能性为 30%到 50%。

对声明的反应:如果 AGI 是在一个“强大的技术安全领域”发展起来的,那么完全令人敬畏的结果的几率会高出 20%。(期待 10^ 35 吸毒生活)

Note: there are many points they may disagree with.

我发现令人稍感欣慰的是,26 名参与者中有 6 名完全感受到了我,并且已经开始行动了。这比我预期的要高一点,但我使用了非常宽泛的安全工作定义:

强大的投资看起来像是超过 30%的顶级研究人员时间投入到诸如健壮性、人工监督、可解释性、安全性、安全探索、对齐等问题上。

之所以选择这个论点,是因为它避免了典型框架问题的两大陷阱。这是积极的,因为末日警告通常与宗教狂热者和阴谋论者的模式相匹配。它没有触及在没有干预的情况下“完全棒极了”的几率是多少,因为这是有争议的,与决策无关。我希望得到不止一个“嗯。没错。我有很多事情要考虑”。我很想看到对这个协议更有说服力的版本的研究。

最后

这些科学家因幽默而获得报酬,所以这是一个明显的混淆因素。这个反面角色的经历已经向你和你在 dystopiaroom.com的朋友们公开了。如果你想复制这些结果,你应该知道我用这个星形投影仪作为情绪照明。我在推特上承诺,如果有更多的人经历了 dystopiaroom.com 事件,我会更新这个分析。

感谢丽娃·泰兹、亚历克斯·马茨纳、汤姆·布朗、达拉戈·巴克利、 瑞安·马茨纳 、克里斯汀·桑福德、埃里克·马茨纳和伊桑·马茨纳审阅本协议草案。

用同音异义词和单词向量来扫“不能”的兴

原文:https://towardsdatascience.com/canning-the-cant-fun-with-homonyms-and-word-vectors-179ab58c76d2?source=collection_archive---------8-----------------------

XYZ 派高级 NLU 工程师亚历山大·维考特伦。

作为一家专门从事自然语言理解的公司,单词嵌入是我们技术的组成部分之一。我们的 NLU 模型需要能够正确“理解”所写或所说的内容。一种方法是使用意图分类模型:当用户输入一个句子时,该模型预测一个意图。因此,准确的意图分类对于交互的顺利进行至关重要。虽然我们的模型是我们所知道的最准确的,但有时分类会出错,偶尔这会导致有趣的对话。最近,一个基于我们的 NLU 模型的聊天机器人未能识别用户的诙谐讽刺,并以下面的被动-主动方式做出回应:

用户:谢谢你没有回答,天才。机器人:不客气!

这句话被误认为是“谢谢”的意思,对此机器人非常礼貌地给出了正确的回答。我们发现的许多错误分类都可以追溯到我们使用的单词嵌入和它们被创建的方式。

有几种训练单词嵌入的方法,但大多数方法的共同点是,单词嵌入的整个概念都是基于这样一种想法:词汇语义是分布式的:意思相似的单词出现在相似的上下文中,相似的上下文包含相似的单词。

“从一个人交的朋友就可以知道他说了什么!”,约翰·鲁珀特·弗斯— 语言学理论概要

但这真的足够了吗?只看上下文就能得到一个词的全部意思吗?语境是什么意思?哪里出了问题?通过在这里分享这些问题,我希望人类语言的奇妙复杂性能给你带来和给我一样的惊奇感。

将上下文放入单词中。

简单地说,经典的 word2vec 单词嵌入将单词表示为它们可能出现的上下文的平均值。一个词出现的“语境”可以在不同的层面上描述。你可以谈论一个单词的句法环境。例如,一些单词有不同的词性,因此也有不同的意思,这取决于它们出现的句法环境。

我非常努力地工作,因为我热爱我的工作。

第一次出现的 work 是动词,表示动作。另一方面,第二次出现是一个名词,表示一项活动。虽然我们可以同意这两个词在许多方面是相似的——它们是同音异义词,有着相同的词根作品——但它们在意思上是不同的。然而,它们将有一个单一的向量表示,总结了这些单词和它们可能出现的上下文。
让我们看另一个例子:

厨房地板上有咖啡。请给我来一杯咖啡。

在这里, coffee 的两个出现都是名词,但是它们的含义因出现的上下文而不同。在第一句话中, coffee 指代一种物质,它是一个物质名词,而在第二句话中, coffee 指代一杯黑金。我们怎么知道?句法环境。不定限定词“a”的出现表明咖啡的出现是可数的,因此我们自动推断应该有一个杯子。然而,你不能对所有单词都这样做。无论你把哪个限定词放在前面,沙子都是不可数的。所以,是的,语义是分布式的,从某种意义上说,单词的意义取决于它们出现的上下文,单词不能出现在特定的上下文中,因为它们的意义不允许它出现。

同样,语义语境也可以“改变”一个单词的意思。看看下面的例子。

低音低音演奏了低音

bass 的两个实例都是名词,前面都有相同的限定词,但它们显然有不同的意思。我们面对的是一条渴望音乐的鱼。我们怎么知道?嗯,只有贝司能弹,贝司不能。注意,尽管句法语境(更具体地说是词序和主客体关系)有助于我们解释低音的每次出现,但主要是 played 的语义与低音的语义相互作用,这有助于我们消除含义的歧义。在下面的例子中,我们切换了主客体关系和词序,但由于 played 的存在,我们仍然得到了相同的两种低音解释:

贝斯演奏贝斯。(等等…也许贝司终究是可以弹的…做鱼的戏码!)

最后,我们有语用语境。语用学指的是语言的使用,很多人性在这里发挥作用。人类使用语言的目的多种多样,不仅是为了传递思想和信息,也是为了让别人做事情。人类使用一种语言的不同变体来显示他们在社会群体中的包容性或遵守某些社会规则。与我们这里的讨论最相关的是寄存器的作用。在不同的社会背景下,我们倾向于使用不同的语言。差异可能在发音上(我不知道我不知道),也可能在我们选择使用的词汇上。我们可以请朋友给我们拿杯咖啡(在杯子里),但我们很可能会请同事给我们拿杯咖啡。完全相同的语法,相同的语义,甚至相同的意图(我懒得去买咖啡,所以我希望你不要明确告诉你该做什么,因为我重视我们的关系和我们生活的社会规则,规定我们要有礼貌,因此使用问题而不是命令来保持良好的关系)。不过,背景不同。不是语言学,而是语用学。

你能像罐头工人一样装罐头吗?

原因之一(还有很多,单词嵌入很牛逼!)为什么单词嵌入如此受欢迎是因为它们允许我们计算单词相似度。如上所述,相似的单词可以出现在相似的上下文中,所以假设单词向量代表单词可以出现的平均上下文,我们期望相似的单词具有相似的单词向量。然而,就像上下文一样,单词相似性可以指代多个概念。
单词“相似”到底是什么意思?单词可以在很多方面相似:它们可以有相同的拼写 ( 地址地址)或者相同或相似的发音 ( 两个)。话可以相似的是有同一个 : 有同一个根,但是没有,它有另一个根。记得呼吸,别搞混了。

单词也可以有相同的词性 : work 和 sing 相似之处在于都是动词,work 和 song 相似之处在于都是名词(而 work 和 work 相似之处在于都有相同的词根 work)。

最后,单词可以有相同或相似的含义。不过还是那句话,意思差不多是什么意思?两个词的意思可以是相似的,因为它们指的是同一本体的实体,例如苹果牛排都指的是可食用对象类的实体。苹果甚至有更相似的意思,因为它们不仅都指可食用物类中的实体,而且还指水果类中的实体,甚至更严格地说,指梨子类。然而,当谈到相似的词时,大多数人会想到同义词或近义词:指同一实体、动作或概念的词。单词嵌入不会。他们想到几种相似性,并把它们混合在一起。

适者生存。

正如我上面提到的,单词向量代表它们出现的上下文的平均值。我们将一个巨大的语料库输入到一个智能算法中,我们得到了语料库中单词的一系列数字表示。相似的向量代表相似的单词,因为它们出现在相似的上下文中。

由于单词-上下文相互作用的复杂性,向量相似性不会总是代表我们所追求的相似性类型。例如,其中一个与的向量最相似的词可以,是不能(检查你最喜欢的词向量!).我想我们都同意,这两个词的意思并不完全相同,那么为什么它们的向量如此相似呢?实际上很简单:两个单词都可能出现的上下文的一个方面比其他方面有更大的权重,这将决定它们向量的形状。在这种情况下,句法环境胜出。可以不可以都只能出现在一组非常有限的语法上下文中。作为助动词,它们只能出现在其他助动词或词汇动词之前的位置,或者在句子是疑问句的情况下出现在句子的开头。此外,它们糟糕的语义内容使得 cancannot 都与大量的动词和名词兼容,所以它可以出现的语义上下文是非常不确定的。因此,这些词的向量将主要代表它们的句法分布,并且从词向量的角度来看,它们将非常类似于具有相同句法分布和较差语义内容的词,例如所有其他助动词。can 中否定的存在没有足够的权重来补偿 cancan之间的句法相似性。幸运的是,有一些方法可以确保考虑到非常相关的语义差异,例如通过使用硬编码的否定提取器,它可以识别否定元素,如 no ,以及 un-anti -。自从我们开始使用这样的否定提取器,我们的机器人变得不那么自大了。
句法语境决定了所有虚词的向量表示,如限定词、数词、介词代词。它们的语义内容只是不够强,不足以体现在它们的向量表示中,并且它们的句法分布是如此受限制,以至于单词向量将基本上表示它们经常出现的句法上下文。

另一种情况是当语用语境具有最大权重时。如果你在 fastText 预训练词向量中查找与 nope 最相似的词,你会注意到前十名包含了大量在非正式语域中频繁使用的短词,如反正fwiwyeahhmmm 。同样,这些词几乎没有语义内容。它们在句法上也是相当独立的(它们可以是独立的“句子”)。这就给语用学留下了空间来确定它们的分布,而这将在它们的词向量中表现出来。

语义语境到底有没有影响?当然有!尤其是那些具有强烈的、专门的、语义内容的、相当自由的句法分布的、与任何语域都没有语用联系的词。许多名词、动词和形容词都是如此。与最相似的词是 a.o. ,是同义词。然而,单词的语义内容越一般,因此它可以出现的语义上下文的种类越多,其单词向量中的语义表示就越“一般”。就拿 make 来说吧,它的前十名里有 create ,还有 givebringget ,这些和 make 一样,都是有多重含义的动词,取决于它们出现的语境(我造的!vs. 我做了个煎蛋。所以显然制造的平均意义(不管那是什么意思)和给予的平均意义相似。由词向量表示的语义相似性通常是类相似性。类似于李子因为它们出现在水果环境中,而流感类似于登革热麻疹因为它们出现在发烧环境中。

现实与可能性的差异。

那么为什么在寻找相似向量时很少会弹出同义词呢?并不是因为两个词可以出现在同一个语境中,它们才会出现。同义词之间往往有所不同,因为其中一个词经常与另一个词一起使用。想想我们亲爱的朋友贝斯。最相似的词是吉他,前十名中没有鱼,可能是因为我们不像谈论乐器那样经常谈论鱼。另一个原因是,单词很少在所有上下文中都是同义词:方言变体在谈论语言学时可以互换使用,但这是唯一可能的上下文。变体可以出现在如此多的其他语境中,这些语境会将词向量拉向某个方向,远离方言。在一种语言的所有变体中,同义词并不总是同义词。 Verlof (假日或休假)在佛兰德荷兰语中是 vakantie (假日)的同义词,但在来自荷兰的荷兰语中不是。最后,在某些语域中,同义词是首选的。 Brofriend 的同义词,但不是和老板说话的时候。很明显,使用单词向量来寻找同义词不是一个好主意。尽管有一些替代的方法来构建一个好的同义词提示器。这一次,您可以利用内置的同义词库,并使用单词预测技术来预测哪个候选同义词最有可能出现在给定的上下文中。无论如何,一个经验法则是,你需要考虑具体的上下文,因为两个词是否是同义词,往往取决于它们出现的上下文。

一般的结论。

单词向量代表单词的平均上下文。语境的所有方面:句法、语义和语用。如果一个方面比另一个方面具有更大的权重,这将在单词向量表示中可见。如果一个单词在一个上下文中比在另一个上下文中出现得更频繁,这将在单词向量表示中可见。如果一个单词以它的一种含义更频繁地出现,这将在单词向量表示中可见。所以如果你想用词向量来计算相似度,要当心相似度复杂度
尽管词向量在许多方面非常有用,并让我们在 NLU 取得了巨大的进步,但它们是基于一种相当简单的语言方法(我们必须从某个地方开始……)。语言中有如此多的微妙之处,人类凭直觉就能理解,甚至不用思考就能应付。我们能够推断出许多甚至没有用语言表达的意思,仅仅基于我们使用语言的语境,或者我们对与我们互动的人的了解和关系,以及许多其他因素。所以让我们继续努力,处理好单词向量的缺点,因为有一天我想要一个宠物机器人。有什么改进的办法吗?取得联系!

原载于 2018 年 3 月 20 日www . paintity . XYZ

CAP 定理和分布式数据库管理系统

原文:https://towardsdatascience.com/cap-theorem-and-distributed-database-management-systems-5c2be977950e?source=collection_archive---------0-----------------------

过去,当我们想要存储更多数据或提高处理能力时,常见的选择是纵向扩展(获得更强大的机器)或进一步优化现有的代码库。然而,随着并行处理和分布式系统的进步,更常见的是进行水平扩展,或者让更多的机器并行执行相同的任务。我们已经可以在 Apache 项目中看到一堆数据操作工具,比如 Spark、Hadoop、Kafka、Zookeeper 和 Storm。然而,为了有效地选择工具,CAP 定理的基本思想是必要的。CAP 定理是一个分布式数据库系统只能拥有 3 个中的 2 个的概念:一致性、可用性和分区容忍度。

CAP 定理在大数据世界中非常重要,尤其是当我们需要根据我们独特的用例在三者之间进行权衡时。在这篇博客上,我将试着解释每一个概念和权衡的原因。我将避免使用具体的例子,因为 DBMS 正在迅速发展。

分区容差

这种情况表明,尽管节点之间的网络延迟了大量消息,系统仍会继续运行。容许分区的系统可以承受任何数量的网络故障,而不会导致整个网络的故障。数据记录在节点和网络的组合中得到充分复制,以保证系统在间歇性故障中正常运行。在处理现代分布式系统时,分区容错不是一个选项。这是必须的。因此,我们必须在一致性和可用性之间进行权衡。

高一致性

这种情况表明所有节点同时看到相同的数据。简单地说,执行一个操作将返回最近的操作的值,导致所有节点返回相同的数据。如果事务以系统处于一致状态开始,以系统处于一致状态结束,则系统具有一致性。在这种模型中,系统可以(而且确实)在事务期间转换到不一致的状态,但是如果在流程的任何阶段出现错误,整个事务都会回滚。在图中,我们有两个不同的记录(“妙蛙种子”和“皮卡丘”),它们的时间戳不同。第三个分区上的输出是“皮卡丘”,最新的输入。然而,这些节点需要时间来更新,并且不会经常出现在网络上。

高可用性

这个条件声明每个请求在成功/失败时得到一个响应。在分布式系统中实现可用性要求系统 100%的时间保持运行。无论系统中任何单个节点的状态如何,每个客户端都会得到响应。这个度量是微不足道的:要么可以提交读/写命令,要么不能。因此,数据库与时间无关,因为节点需要随时在线。这意味着,与前面的例子不同,我们不知道是“皮卡丘”还是“妙蛙种子”先被添加。输出可能是其中之一。因此,当以高频率分析流数据时,高可用性是不可行的。

结论

分布式系统使我们能够获得一定水平的计算能力和可用性,这在过去是不可能的。在遍布全球的数据中心中,我们的系统具有更高的性能、更低的延迟和接近 100%的正常运行时间。最重要的是,今天的系统运行在商品硬件上,这些硬件很容易获得,并且可以以可承受的成本进行配置。然而,这是有代价的。分布式系统比单一网络系统更复杂。理解分布式系统中产生的复杂性,为手头的任务(CAP)做出适当的权衡,并为工作选择正确的工具对于水平扩展是必要的。

毕业率

原文:https://towardsdatascience.com/capstone-blog-62002ebacf6b?source=collection_archive---------11-----------------------

对于我完成的编码训练营的最后一个项目,我想看一些将我以前的兴趣与我当前的数据科学知识相结合的东西。因为我从头到尾都要选择这个项目的每个方面,所以我想看看现实世界的问题。低收入社区存在一个巨大的问题,学生在没有准备好的情况下被鼓励进入大学,并带着大量学生债务辍学,没有任何表现。

第一步是寻找数据!我从国家教育统计中心 (NCES )找到了一组数据,这是从 2002 年开始对 16000 名学生从高中开始到高中毕业后 8 年的纵向研究。这听起来像是完美的数据集,我唯一的问题是它有太多的数据,这从来不是一个真正的问题。有超过 10,000 个变量,所有这些变量都是分类调查数据。使用分类数据可能会有其自身的问题;主要的一点是排序,并确保数据的顺序对回归模型有意义。幸运的是,国家教育统计中心在整理数据方面做得很好,所以这并不像我担心的那样是个大问题。

得到数据后,下一步是缩小变量范围。由于这个数据集包含了学生的个人信息,许多数据在数据集的公共版本中是“受限的”。为了获得完整的数据集,您必须申请受限使用数据许可证。此后,我申请了其中一个,试图让我的发现更有用,但我发现公共使用数据集相当有限。公共使用数据集抑制了所有人口统计信息,这些信息可能是非常好的预测工具,使我的预测更具普遍性。

我的第一步是删除所有以 F3 开头的栏目,因为这意味着来自第三次跟进调查。当我第一次发现与我的目标变量(称为“F3 achievement ”)高度相关的列时,所有的变量都来自第三次跟踪调查。我发现这对于概括预测特别没用,因为知道一个学生大学毕业或没毕业后会发生什么不会帮助某人预测谁会大学毕业。所以我决定去掉这些变量。

下一步是确保调查中留下的学生曾经上过大学。因为我只是在寻找那些愿意或不愿意大学毕业的人,所以我决定只调查那些上过大学的人。

变量选择的最后一步是确定哪些变量与目标变量的相关性超过 0.25。这给我留下了大约 25 个变量,在去掉彼此高度相关或者有很多缺失值的变量后,我最后只剩下 11 个变量。我认为这个数字比我开始时的 4000 英镑要合理得多。

我发现一些变量仍然彼此高度相关,所以我创建了交互项来避免这个问题。

我建立了 5 个不同的模型,发现逻辑回归和线性判别分析表现最好。因为我想要一个更白盒的方法,因为我关心哪些变量是最重要的,所以我选择使用逻辑回归。我发现最重要的变量是学校的类型和他们上大学的时间。这是有道理的,因为正如我们在之前的图表中看到的,与就读于非盈利性大学的学生相比,就读盈利性大学的学生毕业的可能性要小得多。没有全日制上学的学生毕业的可能性也小得多。这些都是学生可以用来决定上哪所大学以确保毕业的可操作的小事情。

鉴于本次调查的基线为 69%,这些模型的性能仅比基线高出约 5%。在未来,我希望获得完整的数据集,并利用人口统计数据做出更好、更有趣的预测。如果这个模型可以获取一个大学生的一些基本信息,并告诉你他们是否有无法毕业的风险,那就更好了。虽然美国高中推动所有学生上大学,但可能有一些学生应该追求另一条道路,如实习或学徒。

[## Jupyter 笔记本浏览器

在我的顶点项目中,我想看看我在教学工作中遇到的一个现实世界的问题。很多低…

nbviewer.jupyter.org](http://nbviewer.jupyter.org/github/rowandl/portfolio/blob/master/How to Improve College Graduation Rates/How to improve college graduation rates.ipynb)

胶囊神经网络:下一代神经网络?第一部分:CNN 及其问题。

原文:https://towardsdatascience.com/capsule-neural-networks-are-here-to-finally-recognize-spatial-relationships-693b7c99b12?source=collection_archive---------3-----------------------

可选(“常规”)神经网络是机器学习领域的最新热点,但它们也有缺陷。胶囊神经网络是 Hinton 的最新发展,它帮助我们解决了其中的一些问题。

这是系列帖子的一部分,旨在教授胶囊神经网络。这第一篇文章将解释“正常”(卷积)神经网络及其问题。

神经网络可能是机器学习中最热门的领域。近年来,有许多新的发展,改善神经网络和建设,使他们更容易。然而,它们大多是渐进式的,例如增加更多的层或稍微改进激活功能,但没有引入一种新的类型的架构或主题。

Geoffery Hinton 是许多高度利用的深度学习算法的创始人之一,包括神经网络的许多发展——难怪,有神经科学和人工智能背景。

2017 年 10 月下旬,Geoffrey Hinton、Sara Sabour 和 Nicholas Frosst 在 Google Brain 下发表了一篇名为“胶囊间动态路由”的研究论文,介绍了神经网络的一项真正创新。这是令人兴奋的,因为这种发展已经被期待了很久,将可能刺激更多的研究和围绕它的进展,并被认为使神经网络比现在更好。

基线:卷积神经网络

卷积神经网络(CNN)是非常灵活的机器学习模型,它最初是受我们大脑工作原理的启发。

神经网络利用“神经元”层将原始数据处理成模式和对象。

神经网络的主要构件是“卷积”层(因此得名)。它是做什么的?它从上一层获取原始信息,理解其中的模式,并将其向前发送到下一层,以理解更大的画面。

如果你是神经网络新手,想了解它,我推荐:

  1. 观看由 3Blue1Brown 制作的动画视频。

  2. 想要更详细的文字/视觉指南,你可以看看这个初学者博客

  3. 如果你能处理更多的数学和细节,你可以阅读斯坦福大学 CS231 的指南。

    以防你没有做到以上任何一点,并打算继续,这里有一个手动波浪形的简要概述。

卷积神经网络背后的直觉

让我们从头开始。
神经网络接收原始输入数据。假设这是一只狗的涂鸦。当你看到一只狗,你的大脑会自动检测出它是一只狗。但是对于计算机来说,图像实际上只是代表颜色通道中颜色强度的一组数字。假设它只是一个黑色的白色涂鸦,那么我们可以用一个数组来表示它,其中每个单元格代表像素从黑到白的亮度。

Example dog face for a Neural Network to recognize. Source: The Sun, image: lovable dog rescue

我们的目标是什么?我们的目标是让网络从视觉上理解图片中的内容(对它来说,图片只是一个数字序列)。一种方法是自下而上的:首先查看小组像素,理解它们(如小线条和曲线:狗耳朵的曲线,瞳孔的小圆圈,腿的小线条),然后建立这些线条和曲线的更大组(如:耳朵,鼻子,鼻子,眼睛),理解这些形状的更大组(如:脸,腿,尾巴),最后理解狗的整个图片。

它是通过许多层将信息按顺序从一层传递到另一层来实现的。
如果这对你来说是新的,请看我对卷积网络结构的总结: 了解卷积神经网络

如果你没读过,但对你来说还是新的,下面是一个更短的摘要:

了解卷积神经网络

  1. 卷积层。第一个卷积层将图像空间映射到一个更低的空间,总结每组中发生的事情,比如说 5x5 像素,这是一条垂直线吗?水平线?什么形状的曲线?这发生在逐元素乘法中,然后将滤波器中的所有值与原始滤波器值相加,并求和为单个数字。
  2. 这就引出了 神经元,或者说 卷积 滤波器 。每个过滤器/神经元被设计成对一种特定的形式(一条垂直线?一条水平线?等等……)。来自第 1 层的像素组到达这些神经元,并根据该切片与神经元寻找的内容的相似程度来照亮与其结构匹配的神经元。
  3. 激活(通常是“ReLU”)层 —在每个卷积层之后,我们应用一个非线性层(或激活层),这将非线性引入系统,使其能够发现数据中的非线性关系。ReLU 非常简单:将任何负输入设为 0,或者如果是正的,保持不变。 ReLU(x) = max(0,x)。
  4. 汇集层。这允许减少“不必要的”信息,总结我们对一个地区的了解,并继续提炼信息。例如,这可能是“MaxPooling ”,其中计算机将只取传递的该补丁的最高值,以便计算机知道“在这些 5x5 像素周围,最主要的值是 255。我不知道具体在哪一个像素上,但确切的位置并不重要,因为它就在附近。→ 注意:这个不好。我们在这里丢失信息。胶囊网这里没有这个操作,这是一个进步。
  5. 辍学层。该层通过将激活设置为零来“删除”该层中的一组随机激活。这使得网络更加健壮(有点像你吃泥土增强你的免疫系统,网络对小的变化更加免疫)并减少过度适应。这仅在训练网络时使用。
  6. 最后一个完全连接的层。对于一个分类问题,我们希望每个最终神经元代表最终的类。它查看前一层的输出(我们记得它应该代表高级功能的激活图),并确定哪些功能与特定的类最相关。
  7. SoftMax — 有时添加这一层是为了以另一种方式表示每个类的输出,我们稍后可以在损失函数中传递这些输出。Softmax 表示各种类别的概率分布。

通常,有更多层提供非线性和维度保持(如在边缘周围填充 0 ),这有助于提高网络的鲁棒性和控制过拟合。但是这些是你需要理解接下来会发生什么的基础。

现在重要的是,这些层只是按顺序连接。这与胶囊网络的结构相反。

Neural Network Structure, From a Google article be Szegedy, Toshev & Erhan presenting Neural Networks

W 卷积神经网络的问题在哪里?

如果你对此感兴趣, 观看韩丁的讲座 解释到底他们有什么问题。下面你会看到胶囊网络改进的几个关键点。

Hinton 说,他们的子结构层次太少(网络是由神经元组成的层组成的,就是这样);我们需要将每一层中的神经元分组到“胶囊”中,就像迷你列一样,进行大量的内部计算,然后输出一个汇总结果。

问题#1:共享会丢失信息

CNN 使用“汇集”或等效的方法来“总结”在较小区域发生的事情,并理解图像中越来越大的块。这是一个让 CNN 运行良好的解决方案,但是它丢失了有价值的信息。

胶囊网络会计算出一个(平移和旋转)较小特征之间的关系来组成一个较大的特征。
这种信息的丢失导致空间信息的丢失。

问题# 2:CNN 没有考虑图像各部分之间的空间关系。因此,它们对方向也过于敏感。

二次采样(和合并)会丢失鼻子和嘴等高级部分之间的精确空间关系。身份识别需要精确的空间关系。

*(韩丁,2012 ,在他的讲座中)。

CNN 不考虑底层对象之间的空间关系。通过这些平坦的神经元层根据它们看到的物体而发光,它们识别出这些物体的存在。但是随后它们被传递到其他激活和汇集层,并传递到下一层神经元(过滤器),而不识别我们在该单层中识别的这些对象之间的关系
他们只是说明自己的存在。

所以一个(简单化)神经网络会毫不犹豫地将这两只狗,巴勃罗和毕加索,归类为“柯基-比特-牛头梗混血儿”的同样好的代表。*

Normal (Convolutional) Neural Network will recognize both of these lovely dogs as the same type of dog face, because it does not care about WHERE the elements of the dog’s face are located relatively to each other in space. Picasso (the dog on the left) will luckily not be discriminated against by the model, but we really want a model to realize this is not a regular example of a corgi-pit-bull-terrier mix dog. Image source: The Sun. Image: Lovable Dog Rescue

网络会将这两只狗归类为“柯基-比特-牛头梗混合”狗的类似良好表示,因为它们在面部合成卷积层回答相同的条件,例如:

*if: (2 eyes & pitbullmix_snout 
     + pitbullmix_wet_nose & mouth)
then: pitbullmix_face*

错误地激活 pitbullmix_face 的神经元,而不是类似于:

*if: 2 eyes 
& BELOW: pitbullmix_snout 
     & pitbullmix_wet_nose 
& BELOW: mouth 
then: pitbullmix_face*

*相反,胶囊网络代表方向以及内容,并连接神经元胶囊之间,以推断空间关系并保留姿势信息。

缺少分组的胶囊表示、姿态计算,以及胶囊之间的重叠检查导致下一个问题。*

问题# 3:CNN 无法将对几何关系的理解转移到新的观点上。

*这使得它们对原始图像本身更敏感,以便将图像分类为同一类别。

CNN 在解决与他们接受过训练的数据相似的问题方面非常棒。它可以对图像或其中与它以前见过的东西非常接近的物体进行分类。但是如果物体稍微旋转,从稍微不同的角度拍摄,特别是在 3D 中,倾斜或在另一个方向上,而不是 CNN 所看到的-网络不会很好地识别它。

一种解决方案是人工创建图像或组的倾斜表示并将它们添加到“训练”集中。然而,这仍然缺乏一个更坚固的结构。*

编码视点不变的空间关系姿态

那么我们如何对 3D 对象之间的空间关系进行编码呢?辛顿从一个已经解决了这个问题的领域获得了灵感:3D 计算机图形学。
在三维图形中,一个
矩阵 是一种表示物体之间关系的特殊技术。姿态本质上是代表平移加上旋转的矩阵。现在我们明白了。我们可以使用子对象之间的姿势关系来保留空间关系信息;测量物体之间的相对旋转和平移作为 4D 姿态矩阵。
这将是理解胶囊间动态路由的关键。******

既然我们已经知道了神经网络及其空间识别问题的基础知识,我们可以继续了解最近开发的解决方案:胶囊神经网络。这将是我下一篇文章的主题。 敬请期待!

胶囊神经网络–第 2 部分:什么是胶囊?

原文:https://towardsdatascience.com/capsule-neural-networks-part-2-what-is-a-capsule-846d5418929f?source=collection_archive---------6-----------------------

胶囊神经网络中的这些“胶囊”是关于什么的?这篇文章将以简单的语言(和狗脸)给你完整的直觉和洞察力,以及后来深入理解它们的技术细节。

这是胶囊网络解释系列的第二部分。帖子#1 在这里,如果你还没看的话,看看吧。

胶囊:直觉

在经典的 CNN 中,第一层的每个神经元代表一个像素。然后,它将这些信息转发给下一层。接下来的卷积层将一群神经元组合在一起,这样单个神经元就可以代表一整帧(一群)神经元。因此,它可以学习表示一组看起来有点像鼻子、的像素,特别是如果我们的数据集中有许多这样的例子,当识别图像是否是狗时,神经网络将学习增加那个鼻子神经元特征的权重(重要性)。

Abstraction 1 of how a regular Convolutional Neural Network would recognize sub-structures present in the big picture, regardless of their location

然而,这种方法只关心特定位置周围的图片中对象的存在;但是它对物体的空间关系和方向不敏感。
但不惧!胶囊来拯救我们了!胶囊 s 是一个新概念,它可以包含更多关于每个【对象】的 信息。

胶囊是一个 向量 (一个具有大小和方向的元素)指定了对象的特征及其 可能性 。这些特征可以是任何实例化参数,如“姿态“”(位置、大小、方向)、变形、速度、反照率(光反射)、色调、纹理等。

因此,例如,神经网络可以学习拥有一个代表“眼睛”的胶囊,它将包含关于它所看到的所有眼睛变化的信息,而不是针对不同眼睛变化的不同神经元。例如,除了关于看起来像“眼睛”的像素组的信息之外,胶囊还可以指定它的属性,如角度和大小,因此,如果我们使用这些角度或大小参数,它可以用相同的一般眼睛信息来表示各种眼睛。

Abstraction of how a Capsule Neural Network would recognize sub-structures present in the big picture, along with information about the location and direction of these elements.

现在,就像神经网络有多层神经元一样,胶囊网络也可以有多层胶囊。所以可能有更高的胶囊代表它们下面的一组物体(胶囊)。例如,在第三层你可能有代表“眼睛”、“鼻子”、“嘴”的胶囊,在第四层你可能有代表“狗脸”的胶囊。因此,胶囊在识别一系列变化的特征时更加灵活和稳健。

但是等等……还有更多!

我们的智能胶囊可以利用这些信息进行更好的识别。直观上,**胶囊网络可以问:所有这些特征都是相似的旋转和大小吗?*** 如果不是,这个有问题的图像不太可能是狗脸(这个标签会得到较低的概率分数)。如果是的话,这增加了我们的信心,这具有重要的意义:我们刚刚创建了一个网络,它可以识别对象,即使它们是从原始输入转换而来的。下面再详细说说这两点。

(1)capsnes 可以根据方向和大小的不一致性进行更好的分类以便识别。如果子元素(鼻子、眼睛和嘴巴)在方向和大小上彼此不一致(比如我们的毕加索!) t 这时较高的胶囊会注意到并且会不太确定这是一张(常规的)狗脸。对于中枢神经系统中的正常神经元,我们无法做到这一点;我们只有可能让一组像素看起来像没有方向信息的东西。通过比较胶囊每个特征的兼容性,我们可以发现它们是不一致的,并且(遗憾的是)排除了 Picasso 的可能性。

②观点不变性。经典的 CNN 只能基于以相似的方向和大小存储的相似的狗脸检测器来识别狗脸。这是因为狗脸的特征存储在像素帧内的位置。例如,它可能有一个狗脸的表示,其中鼻子在像素[50,50]左右,嘴在像素[50,20]左右,眼睛在像素[20,70]和[70,70]左右。然后,它将只识别在图片中相似位置具有相似特征的图像。因此,对于“旋转 30°的狗脸”或“小狗脸”,它必须有一个单独的表示。这些表示最终会映射到同一个类,但这仍然意味着 CNN 必须事先看到每种类型转换的足够多的例子,以创建它的内部表示,并在将来识别它。相比之下,胶囊网络可以具有“狗脸”的一般表示,并检查其每个特征(鼻子、嘴等)的变换(旋转、大小等)。它检查是否所有特征都以相同的量和方向旋转或变换,从而更加确信它确实是一张狗脸。神经网络可以直接检测到这个子结构集合实际上等同于由相同数量转换的更高结构。这意味着 capsnes将类一般化,而不是记住该类的每个视点变量**,因此它对视点是不变的。***

这是个好消息!为什么?因为视点不变意味着: (a)它对输入的方向和大小的变化更鲁棒(b)它将需要少得多的 数据(这通常很难得到)内部表示,从而更有效地正确分类。这意味着(c)**caps net 可以识别新的、未见过的类变体,而无需对它们进行训练!****

**从概念上讲,这是一个非常好的消息,因为更像是 更像是我们人类在视觉上所做的,因此是一个重要的改进 *。当鼻子在 1.70 米,嘴在 1.67 米时,我们不是记住一张脸,而是存储嘴和鼻子之间的关系,从而可以检测出它们的任何变化。

辛顿把这种称为胶囊的等方差
等变是对一类对象的检测,这些对象可以相互变换(即,通过旋转、移位或任何变换)。除了识别物体本身及其变形之外,CapsNetequ variance还意味着它们可以检测出 物体现在处于何种变形状态。 我们强制模型将特征变体学习到一个胶囊中,这样我们可以用更少的训练数据更有效地推断可能的变体。
所以当物体移动,倾斜,或者大小不同时,但是是同一个底层物体,胶囊还是会以很高的概率检测到这个物体。这是可能的,因为胶囊在以长度为概率的向量中包含关于对象的信息,所以如果对象被变换,长度将不会改变,但是它朝向它所表示的变换维度的方向将会改变。对象的这种更健壮的表示也可以使其对对抗性攻击更健壮。简而言之,对抗性攻击是一种“愚弄”神经网络的方法,通过以人眼几乎察觉不到的方式调整图像中的像素,来确定一个对象[dog]实际上是另一个东西[Trump],但在神经网络代表另一个对象的方向上刚好足够,直到网络认为它是另一个对象。具有该对象的更一般化、更健康和更健壮的表示,特别是具有对对象修改的视点不变性和弹性,可以帮助网络保持识别它是相同的对象,从而减轻这些攻击。*******

这对于当神经网络图像识别决定现实生活事件时很重要:像自动驾驶汽车检测 **[STOP]** 迹象。一个(受过良好教育的)罪犯可以在那个标志上贴一个几乎看不见的标签,然后“黑掉”汽车,将这个标志识别为一个[“Speed = 60”]标志并继续行驶。但是,一个基于 CapsNets 而不是 CNN 的系统将更能抵御这种敌对攻击。我针对一种常见的对抗性攻击“FGSM”测试了该模型,在噪声= 50 的水平下,它的准确率下降到了 73%。它没有抗药性,但比正常的中枢神经网络表现更好。****

你大概知道了。

现在让我们开始讨论细节。

胶囊:定义

*****胶囊是一个抽象的概念,由一组神经元组成,其活动向量包含关于该对象的更多信息。有许多方法可以实现这一点。Hinton 等人选择了一种特殊的方法来实现这一点,这种方法允许使用“动态路由”。我们将在这里讨论这个实现。

Sabour,Frosst & Hinton (2017)用这个定义和概述打开了他们的论文:*****

胶囊是一组神经元,其活动向量表示诸如对象或对象部分的特定类型的实体的实例化参数。我们用活动向量的长度来表示实体存在的概率,用它的方向来表示实例化参数。处于一个级别的活动胶囊通过变换矩阵对更高级别的胶囊的实例化参数进行预测。当多个预测一致时,更高水平的胶囊变得活跃。”

胶囊代表什么?

在他们的论文和所有可用的实现中,胶囊网络被用于 MNIST 手写的 0-9 位数数据集——经典的 ML 分类任务。现在让我们来看这个例子。

  • 每个囊都是一组神经元。
  • ****在 DigitCaps 层中,每个神经元代表一个维度,其中数字可以不同:比例和粗细、笔画粗细、倾斜、宽度、平移等。作者在每个胶囊中使用 16 个神经元来代表 16 个维度,其中一个数字可以不同。

*****我们最想从胶囊中得到的是它的输出。
胶囊的输出是一个矢量。
向量本身的长度表达了“实体的存在”——意思是这个物体被[ 5 ]的概率。向量的 方向 被强制表示属性本身(宽度、厚度、倾斜...).它的大小被强制小于 1(因为大小它总是正的,所以在 0-1 之间),并表示成为该类的概率。它指向一个点,这个点代表它有多大,它的角度是什么。

我们来勾画一个简单的例子。
之前,我们让一个神经元接收表示子对象的单个标量,并输出单个标量。假设我们有一些“5”数字神经元靠近 CNN 的末端,接收来自一种特殊的 5:*****

现在,我们可以对更多的信息进行编码,如果不是一个神经元,而是一个有两个神经元的囊,也可以指示手指的角度。向量本身的长度表示该输入有多可能是该胶囊所表示的;与单个神经元输出的概率信息相同。

*****长度计算为矢量的大小。如果第一个向量是 v=(0,0.9),那么它的长度就是= sqrt√(0^2 + 0.9^2) = 0.9。现在我们可以在胶囊中添加更多的神经元来捕捉更多的维度:尺度和厚度、宽度、笔画粗细、倾斜等。

Hinton 等人(2017)在其论文中展示了在 MNIST 数据集上训练的 DigitCaps 图层胶囊中各种维度的结果,其中包含这些维度:*****

From the original paper: Sabour, Frosst and Hinton (2017), Google Brain [https://arxiv.org/pdf/1710.09829.pdf]

胶囊是做什么的?

胶囊学习正确的转换并优化其输出。这是怎么回事?首先,让我们回忆一下传统神经元在 CNN 中的作用:

Traditional Neuron part — image from Naturomics

  1. 接收标量作为输入(X1,X2,X3),附加常数(1)表示偏置权重
  2. 对输入标量执行加权求和(通过标量权重 w1、w2、w3 和 b)
  3. 应用非线性激活函数f()
  4. 输出标量 h(取决于其学习的权重参数 w,b.

我们自己的太空舱也以类似的方式运作,但有很大的不同。

Capsule Networks Neuron structure. Image from Naturomics

****1。输入一个矢量( u_i )。传统神经元接收单个标量作为输入并输出单个标量,而胶囊接收输入向量并输出向量。这些输入向量 u1、u2、u3 来自前一层的胶囊。假设他们代表眼睛,鼻子/鼻子和狗嘴。它们的长度代表了它们正确识别所接收内容的概率。它们的方向表示胶囊的维度空间中底层对象的变化/状态。

请注意,第一层胶囊没有相同的输入,因为它不是由其他胶囊产生的。这个后面会讨论。

还要注意,没有偏置作为输入。该偏差可以包含在下一阶段“仿射变换”中,其中变换矩阵 Wij 可以包含该偏差和更复杂的运算。

****2。仿射变换

这一步是胶囊独有的。它将一个变换矩阵 Wij 应用于前一层的矢量 u1/u2/u3 。例如,假设我们从一个大小为m××k的矩阵和一个大小为( k,d)的输入向量 ui 开始,我们将该向量转换为一个大小为 (m,D) 的新矩阵u【̂Ji。((m×k)×(k×1)⟹m×1)。********

这个转换矩阵很重要;它可以表示丢失的空间关系以及输入的子对象(狗的鼻子、狗的右眼)和输出的高级对象(狗的脸)之间的其他关系。例如,矩阵 W1j 之一可以表示右眼在狗脸的右上部分的信息,狗脸应该大大约 20 倍,并且脸的角度应该与眼睛的角度相同。这个矩阵的目的是将输入向量转换成代表下一级的预测输出向量的位置——人脸(更高级别的特征)。在这个矩阵乘法之后,我们得到了面部的预测位置。这发生在每个矢量上。所以 u1 代表根据眼睛预测的狗脸位置,u2 代表根据鼻子预测的狗脸位置,u1 代表根据嘴预测的狗脸位置。这样,我们可以叠加这些预测,看看它们是否相关或相互干扰。如果他们都预测在同一个地方应该有一只狗,我们对 dog_face 的预测就更有把握了。基于每个输入叠加 dog_face 预测的示例:**

3.输入向量 U^j|i 的加权和( S ums C_ij****

Weighted Sum of input vectors

  • C_ij 是“耦合系数”,我们使用动态路由算法(将在下面解释)找到它。它们的加权和∑ cij 被设计为和为 1。就目前而言,动态路由的一个简短直觉是,它是一种胶囊"决定"向何处发送其输出的方式。这是通过预测如果它和这个太空舱一起走,它的变形会落在太空的什么地方来实现的。我们从所有的胶囊到所有的胶囊,所以对于每一个下一个胶囊,我们有一个空间充满了前一层胶囊的假设点。这个胶囊将到达它的投影更靠近来自其他胶囊的其他点群的地方。**
  • 因此口鼻囊可以投影哪个较高层次的囊会与其投影更一致—(在面部囊、躯干囊、腿囊之间;吻部的投影将更接近面部被膜上的投影)。因此,它将基于此拟合来优化其 C_ij 权重,最大化与 face_capsule 的拟合,最小化与 legs_capsule 的拟合。

4。“挤压函数”:一种新的矢量非线性激活函数

Squashing function breakdown

  1. 传统上,神经元层映射到一个非线性“激活”函数的不同层,这个函数最常见的是 ReLU (简单到 f(x)=max(0,x),只把所有的负值消去为 0)。
  2. 胶囊网络需要从向量转换到向量,Hinton 的设计要求输出向量的长度必须在 0-1 之间(或者更准确地说,0-单位长度),才能表示概率。然而,它必须保持其方向。它如何确保这一点?他们创造了一种新的激活功能,称为“挤压”功能。它将向量缩小到 1 或更小,同时保持它们的方向。具体来说,它将大约 3–4 以上的长向量缩小到大约 1(单位向量大小),小于 1 的向量大幅缩小(在等式的左侧,它们被平方并被自身+ 1 除)。注意,这个向量的大小表示对象属于这个胶囊的概率。
  3. (例如,对于||Sj||=1,这部分应该是 1/2=0.5,但是对于大小为||0.1||,0.1/1.1 = 0.09091 的向量
  4. 挤压函数可以计算为(从 gram-ai 的 PyTorch 实现开始,我们将在后面介绍):
*****# squashing function as we’ve seen before
def squash(self, tensor, dim=-1):
   squared_norm = (tensor ** 2).sum(dim=dim, keepdim=True)
   scale = squared_norm / (1 + squared_norm)
   return scale * tensor / torch.sqrt(squared_norm)*****
  1. ****输出:产生的矢量。成品。

摘要

总之,胶囊的内部工作是:

  1. ****接收输入向量(代表眼睛)
  2. ****应用编码空间关系的“仿射变换”或变换矩阵(在眼睛和 dog_face 之间,投影脸部应该在的位置)
  3. 通过路由算法学习的 C 个权重应用加权和
  4. 使用非线性“挤压”激活功能将其“挤压”至 0–1
  5. 得到了我们的新矢量,准备发送。

自然组学的这张表很好地总结了正常“神经元”和胶囊之间的主要差异:

Key differences between a traditional neuron and a capsule. Source: Naturomics

恭喜你。如果你一路走到了这里(即使只是略读了一些技术部分),你就知道了关于“胶囊”你需要知道的一切!

但是我们仍然需要知道: 你用这些胶囊做什么?你如何将它们连接成一个神经网络?下一篇文章将解释胶囊之间动态路由信息的算法和架构

如果你想看到下一个帖子以及未来更多的帖子,请鼓掌!

直到下一次,

托梅尔

linkedin.com/in/tomere

车祸和天气:环境条件对交通事故率影响的探索性分析

原文:https://towardsdatascience.com/car-crashes-and-the-weather-an-exploratory-analysis-of-environmental-conditions-impact-on-traffic-12bcb7f9afed?source=collection_archive---------4-----------------------

在恶劣天气条件和光线不足的情况下驾驶会增加事故风险,这似乎是一个合理的假设,但我对英国交通事故数据的分析显示了一些令人惊讶的结果。

这篇文章改编自一篇更详细的报告,该报告可以在 GitHub 上找到,以及分析中使用的代码和数据。

在英国,每年有超过 130,000 起涉及伤害的交通碰撞报告给警方,导致 1,700 到 1,800 人死亡[1]。交通部每年发布这些事故的数据[2],自 1979 年以来,一直以类似的格式记录和发布,尽管在这项工作中,我只关注了 2016 年,这是可获得结果的最近一年。

与数据一起发布的还有一份报告[1],该报告对事故和死亡率的年度趋势给出了一些有趣的见解,并通过查看特定的道路使用者类型(如汽车驾驶员、骑自行车者、行人等)对数据进行了细分。).它还考虑了可能相关的因素,如天气、酒后驾车率,甚至国内生产总值对事故率的影响。然而,该报告几乎没有详细说明地区趋势、全年或全天的模式,或者物理环境和撞车率之间是否存在关系。

我想调查这些点,通过挖掘数据来探索全国事故状况的模式,并看看我是否能揭示环境条件和事故率之间的任何关系。

数据

数据由三个主表组成:

  1. 事故——32 个变量,详细说明位置、时间、日期、照明、天气和路面状况、伤亡人数、道路类型和其他变量。每个观察结果都代表了 2016 年向警方报告的 136,621 起涉及伤害的碰撞中的一次。
  2. 伤亡人数——通过“事故指数”链接到事故表,该表有 16 列,提供了有关伤亡人数的详细信息。共有 181,384 行,每行代表一个在碰撞中受伤的人。
  3. 车辆——此表给出了涉及碰撞的车辆的详细信息,但不用于本次调查

我还获得了政府对 2016 年英国不同类型道路上行驶距离的估计[3],2016 年每周每天每小时的道路交通相对密度[3],以及 2016 年地方当局(LA)层面的英国人口[4]。国家统计局提供的给出每个洛杉矶地理边界的 shapefile 用于制图目的[5]。

数据准备

数据中的分类变量存储为数字代码,单独的电子表格详细说明了每个变量的每个代码的含义。为了将数据转换为可读的格式,它与数据字典一起被加载到 Pandas 数据框中,代码被转换为值,然后被导出到一个新的 csv 中,用于所有剩余的工作。

初次查看时,数据似乎几乎完全完整,但仔细检查后发现,一些值相当于缺失数据(例如“未知”)。有 3999 项记录的关键变量数据缺失。这些只代表了不到 3%的数据,所以我认为它们对整体结果影响很小,并将其删除。

为了调查不同道路类型的事故率,我需要对不同道路类型的行驶距离进行综合评估[3]。这两个数据集对道路类型使用不同的分类,因此我将主数据集中更细粒度的道路类型转化为行驶距离估算中使用的类型。

国家一级

首先,我选择检查每起事故发生时的照明条件、路面条件和天气条件,以及它们发生的时间。

照明、道路和天气条件

所有这些变量显示了相似的分布(见图 1),一类占观察值的 70-85 %,二类占 10-25 %,其余为不常见情况。这并不奇怪,因为尽管没有关于天气状况的数据,我们知道在英国天气通常是干燥和晴朗的(与刻板印象相反!),但有时会下雨,更多的驾驶是在白天进行的。

Fig 1: Occurrence of Environmental Conditions

跨时间分布

接下来我想寻找的是一种季节性模式。按日期对事件进行分组产生了图 2 所示的曲线图。虽然方差在冬季月份略高,但全年的总比率变化很小(月平均值的标准偏差小于 5%),如虚线回归线所示。考虑到每月交通量的变化,标准偏差仍然只有 8%。

有趣的一点是 12 月下旬的三个异常值。这是一年中撞车次数最少的三天:圣诞节、节礼日和除夕。

Fig 2: Traffic accidents throughout the year. Outliers (>2sd from mean) are highlighted in red.

按一天中的时间对事故进行分组显示,早晚高峰时的事故率不足为奇,夜间的事故率比白天低得多。将原始数据除以每小时的相对交通流量显示出非常不同的模式,夜间的相对事故率远远高于白天,高峰时间的影响较小。

然而,这种变化似乎不太可能是光照条件的结果,因为 12 月和 6 月的模式没有显著差异,尽管这两个月的日照时间非常不同。

Fig 3: Distribution of accidents throughout the day

比较地方当局

为了在区域之间进行比较,我将分类变量“光照条件”、“天气条件”和“地表条件”转换为虚拟变量,并按 LA 分组,给出每个 LA 的每个值出现的频率。

在这一阶段还纳入了人口估计,从而能够计算每 1000 名居民的洛杉矶事故率。这显然是一个不完善的衡量标准,因为它假设了一个地区的常住人口和开车到那里的人之间的关系,这不一定有效,但它为分析提供了一个良好的起点。洛杉矶的道路交通量在这里非常有用,但它们仅在国家一级可用。

为了避免扭曲结果,一个极端的异常值洛杉矶,伦敦金融城,被确定并删除。由于其居民人口少,但非常繁忙,该市的事故率为每 1000 名居民 38.8 起,是第二高的洛杉矶事故率的六倍多(威斯敏斯特为 5.94 起,可能受到类似偏见的影响,但程度较低,不会明显影响结果)。

虚拟变量计数被转化为每个 LA 的总事故计数的比例。在没有详细天气数据的情况下,这为我提供了一个每个地方的天气状况的代理。

考虑到这些变量的偏斜性质(参见照明、道路和天气条件部分),并且为了便于变量之间以及 LAs 之间的比较,这些比例在 LAs 中的分布在 0 和 1 之间进行了重新调整。

这一过程产生了 18 个新列。将每一项与事故、伤亡、重伤和死亡率相对照,并计算 Pearson 和 Spearman 的等级分数,结果显示这些组合中的大多数并没有很强的相关性。在进行的 72 次比较中,表 1 列出了绝对相关系数大于 0.3 的 5 次比较。值得注意的是,没有一个选定的环境条件与照明有关。

Table 1:Correlation between environmental conditions and accident or casualty rate

确定了潜在的相关性后,下一步是建立一个回归模型,看看这个模型如何适用于全国。多元回归假设预测变量之间没有关系,但很明显在这种情况下会有一些关系。两个天气条件值和两个路面条件值是源自相同变量的成对值。此外,潮湿的路面显然与下雨有关,干燥的路面则与好天气有关。图 4 证实了所有四个变量都是密切相关的。

Fig 4: Confirming co-linearity of potential predictors

这允许使用简单的单变量回归模型。选择“没有大风的雨”是因为它与事故率的相关性最强。图 5 显示了它们的关系。然后从每个地方当局的真实事故率和图 6 中绘制的残差中减去得到的多项式回归模型(以红色显示)。

Fig 5: Raining, no high winds against Accident Rate

该模型没有显示出明显的区域模式,尽管在伦敦和伯明翰周围的郊区可以看到高于预期的事故率。

Fig 6: A map of the UK showing the difference between true accident rate and that predicted by a linear regression model based on rainy, low wind weather conditions. High values indicate a higher than expected accident rate.

随着天气和地表条件被确定为事故率的一个可能的促成因素,我想看看是否有可能确定这些条件具有相似频率的 LAs 组。k 表示在重新标度的路面条件下的聚类没有提供好的结果。还尝试了聚类,将变量重新调整为均匀分布,但这给了较罕见的条件太多的权重。回到原来的比例产生三个清晰的集群。图 7 显示了最接近每个集群质心的 LA 的轮廓和集群的地理分布

Fig 7: Clustering on Surface Conditions. Left: Geographical distribution of clusters. Right: Parallel coordinates plot showing the profile of the LAs closest to the cluster centroids.

讨论结果

这项调查的预期是,在黑暗中和恶劣天气下驾驶是危险的,这将通过冬季以及在通常更寒冷和更潮湿的地区(该国的北部和西部)较高的车祸率得到证明,但这并没有得到结果的支持。全年交通事故率无明显变化;每月的事故率变化很小,12 月和 6 月的每小时事故模式非常相似。分析还发现,在不同照明条件下发生的事故比例与这些事故的发生率或严重程度之间没有联系。

天气/路面状况与事故率之间存在关系,但与预期相反。涉及潮湿条件的事故比例较高的 LAs 的总体事故率往往较低。

一个可能的原因是,糟糕的天气不但没有导致更多的事故,反而减少了事故,因为它会阻碍驾驶,导致司机减少,道路不那么拥挤,车速降低。这种关系不是特别强,但这可以支持上述假设,因为无论天气如何,经常需要旅行。准确的洛杉矶每日天气记录和交通流量估计将允许在这一地区进行更大的调查。

按照城市区域的清晰地理模式,该国温暖、干燥的南部和东部,寒冷、潮湿的北部和西部,以及一些海拔较高的地区,如奔宁山脉,有可能识别出具有类似事故状况的 LAs 集群(图 7 ),这些集群与预期相符。

虽然结果有些令人惊讶,但调查的目标已经达到,但仍有许多数据领域可以进一步调查,例如在不同条件下,交叉口布局或车辆类型如何与碰撞率相关。

最后…

感谢阅读!如果你喜欢我的作品,请留下一些掌声。如果你想了解更多,我使用的代码可以在 GitHub 上找到,还有随同工作的原始报告,比这篇文章更深入一点。

工具

除了在 Excel 中为准备加载数据而做的一些微小的格式更改之外,所有其他工作都是使用 Python 完成的。Numpy 和 Pandas 用于大部分数据操作。Sci-kit Learn 用于归一化数据(quantile_transform 和 MinMaxScaler)、Kmeans 聚类(KMeans)和识别最接近每个聚类中心的 LA(pairwise _ distances _ arg min _ min)。Matplotlib 和 Seaborn 用于基于图形的可视化,Geopandas 用于地理可视化。

参考

[1] D. for T. UK 政府,“英国报告的道路伤亡人数,年度报告:2016—gov . UK”[在线]。可用:https://www . gov . uk/government/statistics/reported-road-residences-great-Britain annual-report-2016。【访问时间:2017 年 10 月 30 日】。

[2] D .代表英国政府,“道路安全数据—数据集”,2017 年。【在线】。可用:https://data.gov.uk/dataset/road-accidents-safety-data.【访问时间:2017 年 10 月 30 日】。

[3] D .对于 T. UK 政府,“GB 道路交通计数-数据集。”【在线】。可用:https://data.gov.uk/dataset/gb-road-traffic-counts.【访问时间:2017 年 11 月 5 日】。

[4] O 代表 N. S .联合王国政府,“联合王国、英格兰和威尔士、苏格兰和北爱尔兰的人口估计数——国家统计局。”【在线】。可用:https://www . ons . gov . uk/peoplepulationandcommunity/populationandmigration/populationestimates/datasets/populationestimates forukenglandwalesscotland northern Ireland。[访问日期:2017 年 11 月 30 日]。

[5] O .对于 N. S. UK 政府,“英国地方当局辖区(2016 年 12 月)完全剪切边界—数据集。”【在线】。可用:https://data . gov . uk/dataset/local-authority-district s December-2016-full-clipped-boundaries-in-great-Britain 2。【访问时间:2017 年 11 月 30 日】。

新加坡的汽车注销:可以预测吗?

原文:https://towardsdatascience.com/car-de-registrations-in-singapore-can-they-be-predicted-e531327ea1c7?source=collection_archive---------17-----------------------

R 中使用 ARIMA 和随机森林的时间序列建模

(编辑:我最近在 Python 上复制了整个项目,GitHub repo 的链接是这里!)

“你好世界!”

对于我的第一篇帖子,我想简单谈谈我在 2018 年夏天从事的一个预测项目。这是一个令人愉快的过程,而且非常有趣。鉴于我在维也纳的冬季交流项目中获得的一些教育启示(基本上我有很多空闲时间),我决定就我的结果写一篇短文。此外,这将是一个从更广泛的社区寻求反馈和评论的好时机,作为更广泛的学习体验的一部分。

免责声明:我涉足统计学/数据科学/ML 纯粹是出于兴趣(当然也是为了赶上 21 世纪的潮流),所以我尽最大努力让自己掌握所有必要的知识。如果在下面的帖子中有任何技术上的误解,请告诉我正确的方向!😃

我们走吧!:

语境

在新加坡,与世界上其他国家的居民相比,个人拥有汽车对新加坡人来说有着更不同的意义。为了成为一个“备受尊敬”的车主,你必须首先获得一个有效期为 10 年的权利证书。确切地说,在这里获得 COE 的过程对我来说有点混乱,但这涉及到某种形式的投标。只有当您成功地为您的车辆获得正确的 COE 类别时,您才能最终拥有您的汽车。

也就是说,当汽车的 COE 达到 10 年标志时,它的道路使用不再合法。因此,车主可以选择购买一辆拥有新 COE 的新车,更新他们的 COE,或者干脆报废汽车以获得某种形式的折扣。在任何情况下,如果您选择不更新当前汽车的 COE,您将需要注销它。

那么汽车注销数据到底有什么大不了的呢?:

  • 可以说,汽车注销的趋势对于那些产品围绕汽车 10 年生命周期的公司的商业决策具有重要意义。
  • 这些趋势也可能是消费者情绪的宏观经济指标。

在这篇文章中,我将只是(无聊地)试图无力地预测新加坡汽车注销的未来价值。我在这个项目上的 Github repo 可以在这里找到!

第 1 部分:数据准备和可视化

所有数据都可以在 Singstat 表格生成器上找到,这是一个非常棒的工具。我要看的车的类别是B 类是 1600cc 及以上的车,或者发动机功率输出超过 97 kW。该数据为月度序列,第一个时间点为 1990 年 2 月。对时间序列图的初步扫描显示了一些异常值,我决定使用 tsclean 函数清除这些异常值。

Figure 1: Time Series of Cat B car de-registrations

对我来说看起来很像时间序列图。我观察到某种形式的单周期行为(但在没有更多数据点的情况下,我们不能太确定),没有明显的季节性和总体上升趋势。

在通过任何预测模型运行数据之前,我会首先将它们分成训练/测试集。对于这篇文章,训练集将是截至 2018 年 3 月的所有数据点,我将在随后的 4 个月(2018 年 4 月:7 月)测试我的模型。为了便于说明,训练和测试数据分割显示为上面时间序列中紫色虚线左侧和右侧的点。

第 2 部分:拟合 ARIMA 模型

我想尝试的第一个模型是 ARIMA 模型。本质上,ARIMA 由三部分组成:自回归部分(AR(p))、积分部分(I(d))和移动平均部分(MA(q))。我很想深入了解更多的细节,但我不认为我是合适的人选。对于 ARIMA 更多的技术解释,我发现在谷歌上搜索“什么是 ARIMA”的第一个链接是最有信息量的!

我在这里的任务是指定这三个参数 (p,d,q) 到底是什么,这可以手动完成——这是我接下来要做的,并且使用预测包中的 auto.arima 函数在 R 上自动完成。

为了让我能够拟合 ARIMA 模型,数据必须首先是稳定的。平稳本质上意味着时间序列的均值和方差不是时间的函数。根据这一假设,我认为从图 1 中可以很清楚地看出,这一时间序列不是平稳的。为了证实这一点,我绘制了时间序列的 ACF 和 PACF 图,以及一个增强的 Dickey Fuller (ADF)平稳性测试来证明我的说法:

Augmented Dickey-Fuller Test
Dickey-Fuller = -1.268, Lag order = 6, p-value = **0.8854**
alternative hypothesis: stationary

Figure 2: ACF and PACF plots of the Cat B vehicle de-registration

ADF 的高 p 值告诉我们,我们不拒绝零,表明序列确实是非平稳的。从 ACF/PACF 图中,我们可以推断出两件事:

  • 在 ACF 图中,稳定下降的模式表明了 B 类车辆注销与其滞后之间的相关性,本质上意味着该序列不是稳定的
  • ACF 的稳定下降模式和 PACF 的急剧下降(滞后 3 之后)表明 3 阶 MA 模式(q = 3)

为了将我的非平稳序列转换成平稳序列,我将对序列进行一次差分,并运行与上述相同的程序来测试差分后的序列现在是否平稳。

Augmented Dickey-Fuller Test
Dickey-Fuller = -6.3372, Lag order = 6, p-value = **0.01**
alternative hypothesis: stationary

Figure 3: ACF and PACF plots of the Cat B vehicle de-registration after 1st differencing

不错,在对序列进行一次差分后,ADF 测试现在显示序列是稳定的,但 ACF 图仍然显示一些与滞后相关的迹象,每 2 个滞后出现一次。类似地,PACF 图显示了每 5 或 6 个滞后的循环模式。也许可能的模型会有参数 (p = 5:6,d = 1,q = 2) ?为了便于练习,我确实循环了几个 (p,d,q) 的组合,并选择了 AIC 值最低的模型,这可以在我的脚本中看到。然而,在这篇文章中,我将展示来自 auto.arima 函数的结果。

Series: train_ts_arima$Catb_clean 
**ARIMA(3,1,2)** with driftCoefficients:
 ar1 ar2 ar3 ma1 ma2 drift
 -1.4925 -1.3896 -0.4577 0.9660 0.7325 8.7529
s.e. 0.0963 0.0992 0.0625 0.0965 0.0872 5.4097sigma² estimated as 25681: log likelihood=-2166.91
AIC=4347.81 AICc=4348.16 BIC=4374.49

嘿!至少我有两个参数是正确的! auto.arima 函数指定 (p = 3,d = 1,q = 2) 为现在的最佳模型,让我们看看模型残差是否有意义,以及我是否可以使用该模型进行未来预测。

Figure 4: ARIMA model residual,

嗯。模型残差似乎具有变化的方差,并且在 ACF 和 PACF 图中有显著的尖峰,特别是在滞后 12 左右重复出现。对此能做些什么?也许我可以试着将 p或 q设置为 12,然后看看结果如何,或者我也可以在拟合 ARIMA 模型之前对这个系列进行自然记录(事后看来,我应该早点这么做)。尽管如此,为了便于说明,请允许我仅使用这个当前模型来预测未来四个月的情况- 注意,这个模型可能不是最准确的。

Figure 5: Actual values in black, fitted ARIMA values in red, new forecasted values in blue

嗯,样品内拟合似乎很有希望。在我的拟合值中似乎有一个周期的超前,但这可能是因为在拟合函数中的 h 规范,它定义了它将预测多少步。样本外性能如何?

放大到图形的右上方(蓝色)会产生:

Figure 6: Forecasted values for (April : July 2018) using ARIMA model in blue, actual figures in black

2018 年 4 月至 7 月的预测值似乎有点偏离,但嘿,我想这是意料之中的。我可以想象大量的宏观经济和社会因素/指标可能会对汽车注销产生影响,因此期望该模型仅根据其历史价值来预测未来价值可能会有所推动。将来,引入其他解释变量的 ARIMAX 模型可能有助于改进模型预测。

第 3 部分:随机森林时间!

在维也纳的冬季交流中,我主要学习了机器学习应用模块,并正式接触了当今世界使用的各种预测模型。我的教授接着开玩笑说,“如果你不知道如何处理你所有的数据,就把它们扔进一个随机的森林模型,看看会有什么结果”。为什么我们不这样做呢?

从我的脚本中可以看出,在幕后,一些额外的数据准备是必要的。TLDR:

  • 增加了新加坡的 GDP 值、人口规模、失业数据和每个投标窗口收到的投标数量。凭直觉,我认为这些预测因素应该在影响汽车注销数量方面发挥作用。所有数据集都可以从 Singstat 获得。
  • 对于 GDP、人口和失业等数据,我需要从中获得月度数据。不幸的是,这些数据大约每季度公布一次。因此,我在 splinefun 函数下使用了一种叫做三次插值的方法来生成每月的数字。
  • 然后,我创建了所有预测值的滞后值。回想一下,到目前为止,我的四个主要预测指标是:B 类车辆注销、GDP、人口、失业和投标数据。对于 B 类车辆注销数据,我包括了多达 12 个标记,对于其余数据,我包括了多达 5 个标记。要包括的滞后数是任意确定的。
  • 训练和测试分割保持不变,但是必须对训练集进行小的调整,以减少 NA 值的数量。在这种情况下,我的训练集的起点从 1990 年 5 月移到了 2002 年 2 月。

完成后,是时候创造一个森林了!

为了实现随机森林,我将使用 caret 包, method = "rf" 。要调优的超参数只有一个,就是 mtry 。为此,我进行了网格搜索,以找出最佳值。对于交叉验证过程,我使用常见的 10 重交叉验证来减少过度拟合,并增加我的随机森林的健壮性。

结果呢?让我们来看看随机森林模型的样本内性能:

Figure 7: Actual values of Cat B vehicle de-registration in black, fitted RF model values in red, forecasted values in blue

还不错!这些预测在预测峰值方面有所欠缺,但总体趋势是存在的。样本外性能如何?

Figure 8: Actual values in black, forecasted RF values in red

在预测 2018 年 4 月至 7 月的价值方面,RF 模型似乎做得更好。如您所见,至少在四月和五月,预测值似乎非常接近实际值。然而,它没有预测到 6 月份的下降,7 月份的预测也略有偏差。

同时,让我们来看看变量的一些相对重要性:

Figure 9: Variable importance plot (note that if a variable is a lagged variable it is denoted “…_lag”.

这里的一个要点是,前 7 个“最重要”的变量是滞后值。现在我知道这是有意义的,因为我们经常查看当前时间段内发生的事情,以便为下一个时间段做出决定,但在真实世界的数据集中看到这种情况是非常令人着迷的。

结论

嗯,就是这样!这标志着我第一次尝试在真实世界数据集(而不是通常的 iris 或 titanic 数据集)上玩预测建模的结束。从商业角度来看,鉴于汽车市场在消费者家庭支出中所占的比重如此之大,我相信这些模型会有很多应用。写这篇文章是一个非常愉快的过程,我非常感谢反馈和评论!

参考

[## ARIMA 预测简介

具体话题经验:新手职业经验:一些行业经验以前的知识…

www.datascience.com](https://www.datascience.com/blog/introduction-to-forecasting-with-arima-in-r-learn-data-science-tutorials)

《转行》:等等,什么?

原文:https://towardsdatascience.com/career-change-wait-what-3c687f05fc49?source=collection_archive---------4-----------------------

作为一个刚刚转行 10 年的人,面试官通常会问这样一个问题:“你转行的灵感是什么?”

我讨厌“职业改变”这个词,它意味着我已经改变了定义我是谁和我人生道路的东西。Pivot 似乎更准确地描述了我在过去 12 个月里所完成的事情。

Taking another path around that braid in the stream. (Photo credit: Zoltan Sylvester)

我进入地球科学的原因和大多数同龄人一样:

  1. 我喜欢在外面
  2. 我喜欢科学
  3. 我是一个天生的故事讲述者

地球科学是野外工作和讲述地球故事的科学的完美结合。这要求我在科学工具领域全面发展,调用化学、物理和(有时)生物学来剖析岩石、褶皱或山脉带的故事。

临近研究生毕业时,我不得不面对下一步该做什么的艰难决定。学术界的职业?出版还是灭亡?或者……选择从事石油和天然气行业?在休斯顿…

我选择了石油和天然气行业,与一家(超级)大型石油公司签约。

我的头几年有点像蜜月期。一切都很好,我从运营部开始,那里的事情进展很快。我负责就我们定期在岸上钻探的油井做出价值约 100 万美元的决策,并且每天都在学习新东西。我在其他几个轮岗中取得了进展,担任了油田开发、评估准入机会、勘探和评估方面的角色。我最终专注于现场评估,这是一个金发女孩的情况,既不是太少的数据让一个人发疯,也不是太多的数据与之前根深蒂固的假设相矛盾(它发生了)。

随着时间的推移,我开始看到装甲扭结。从纸面上看,一切仍然令人惊叹和壮观。我是一名探险家、地图绘制者和高知名度项目的不确定性/风险评估员(甚至是 B 级!).

然而,我在事业上相当不开心。这项工作听起来很吸引人,我在新的前沿领域研究尖端的“大”数据。这太令人着迷了。然而,在更深的层面上,时间表(很多时候是 5-10 年的现场开发决策)太长了,让我无法保持参与。老实说,很多天我都没有发挥出自己的潜力,这最终令人不满意。

好吧,够了。在当前工业不景气的情况下,当有人给我一份诱人的遣散费时,我就上钩了。

我离开这个行业时,只有一个模糊的想法,想做一些事情,在那里我可以将我的建模、不确定性和风险评估技能运用到另一个行业。我知道里面一定有什么东西,我只是不太确定“它”是什么…

我开始探索各种途径。保险核保?金融?正式的风险评估?所有这些领域都激起了我的兴趣,但似乎并没有触及我真正想要的职业。

然后我开始在网上看到数据科学这个术语,但还没有正式接触过这个术语。我进一步研究了一下,找到了我想要的东西。

数据科学对不同的人和组织有不同的意义。然而,在其核心,数据科学归结为使用数据来帮助企业做出更好的决策。在一天结束的时候,尽我最大的努力帮助一家公司做出更明智的决定,这让我感到满意。

这对于我和公司来说都是一个绝佳的机会:

  1. 允许我增长和多样化我的行业曝光
  2. 根据我以前的行业经验,让组织从我的独特观点中受益

我的观点是,地球科学家是在四个主要方面填补数据科学角色的完美候选人。

  1. 我们习惯于杂乱的数据——这是我们的面包和黄油,几乎所有在大型或中型独立石油公司工作过的地球科学家都解释过不完整和杂乱的数据集。威尔科克斯/古近纪盐下带疯狂突出的解释?我们搞定了。这很好地解释了科技行业中杂乱数据的世界。关于如何估算或处理数据集中缺失值的想法?我们掩护你!
  2. 我们讲述令人信服的故事——在解释我们的数据后,我们最终必须自上而下和自下而上地讲述故事,以说服管理层投资钻探我们的前景或证明我们的评价井和开发井的位置。这填补了许多数据科学家的空白,能够讲述数据驱动的故事,迫使管理层做出高层业务决策。
  3. 我们每天都在使用概率/统计数据——从潜在客户的成功概率计算,到执行蒙特卡罗模拟来评估现有石油量的不确定性范围,我们拥有强大的概率和统计工作知识。
  4. 我们每天都在处理不确定性和风险评估。从执行油藏评价计划的信息价值计算,到详细的多学科全领域风险评估,我们从一开始就是决策过程中的合作伙伴。我们知道不确定性和风险之间的区别,可以帮助您理解这些模糊性对于制定大大小小的商业决策的底线意味着什么。地球不是同质的。磨练对各种各样的结果 进行建模的技能,并将它们适当地传达给管理层,这是一项在数据科学中经常被忽视的技能。

对我来说,斗争不在于我是否适合数据科学的职位,而是更符合如何让别人相信我适合这个角色和组织。石油和天然气行业以外的大多数人都没有接触过企业地球科学家的工作角色和职责,因此需要对双方进行教育。

在接下来的几周里,我将概述我是如何成功地从地球科学家转型为成熟的数据科学家的。

继续看第二集第三集第四集第五集第六集第七集第八集

CarND 项目 1:车道线检测—完整的管道

原文:https://towardsdatascience.com/carnd-project-1-lane-lines-detection-a-complete-pipeline-6b815037d02c?source=collection_archive---------0-----------------------

你们中的一些人可能知道我最近开始了 Udacity 的自动驾驶汽车工程师纳米学位。这是一个令人惊叹的独特计划,由许多关于自动驾驶主要方面的项目组成。这是我对第一个项目的解决方案:车道线检测。首先,看下面的视频——我非常相信先获得灵感,然后再深入细节。

现在你看到这个项目有多酷了,让我们深入了解一下实现的细节。

这个项目的目标是建立一个简单的图像管道(从视频中提取一帧作为输入,做一些事情,返回该帧的修改版本),它允许在简单的条件下检测车道线:阳光明媚的天气,良好的能见度,视野中没有汽车,只有直道。还有一点:我们的车道线检测器应该是线性的。还不允许多项式!

当然,这是一个玩具项目,它并不打算用于生产,但它确实有助于获得自动驾驶汽车工程师解决的问题的一些直觉。

我的成就:

—完全丢弃硬编码的感兴趣区域(除了必须初始化通道的第一帧)。
—无需任何调整,代码在任何项目 1 和项目 4(高级车道线)视频上都能很好地工作(除了最后一个更难的挑战)。无论如何,山路不在本项目范围内。

图像管道解释

让我从代码中复制并粘贴image_pipeline函数的签名和 docstring:

该管道获取一个 3 通道 RGB 图像,对其进行过滤和转换,更新LaneLine对象的内部状态,并在该图像上绘制所有需要的元素。我们可以这样想象整个管道:

我们可能会注意到阶段 1 和阶段 2 是相互独立的。我们可以(也应该)抽象出每个阶段的细节,以便能够以模块化的方式修改代码。

阶段 1:预处理和矢量化

第一个阶段是数据科学家和任何处理原始数据的人都熟知的:我们需要对它进行预处理,使用我们认为合适的任何矢量化程序将其转换为工作数据集。以下代码将原始图像转换为我们可以在阶段 2 中使用的矢量化数据集:

让我们简单讨论一下代码。我们的项目基于 OpenCV,这是一个非常棒的库,使用矩阵运算在像素级上进行图像操作。由于我们的管道质量依赖于正确的颜色选择,我们需要一种方法来有效地选择一系列相似的颜色(在我们的例子中是白色和黄色)。标准的 RGB 调色板不适合这个——我们必须先将我们的图像转换成 HSV 调色板

RGB (left) and HSV (right) palettes

接下来,我们跳过推荐的灰度和高斯模糊阶段。我发现我们可以直接进行二值化——将二值掩码与模糊图像相结合只会给我们的矢量器增加不必要的噪声。我们选择黄色和白色范围,并得到我们的帧的二进制掩码:

最后,我们准备矢量化这个图像。我们应用两种转换:

  1. Canny 边缘检测:一种算法,计算图像的强度梯度,并应用双阈值来确定边缘(我们在canny函数中使用(280, 360)作为阈值)。
  2. 霍夫线变换:当我们从 canny 检测中得到单个边缘时,我们可以用线将它们连接起来。我们不打算深入挖掘这个算法的细节(如果你好奇,请查看上面的链接,这里是和另一个),但主要的收获是我们确实得到了一组线(每一个都是一个Line实例,具有计算的斜率、截距等等)。

为了初始化视频第一帧的车道线,我们必须使用一个感兴趣的区域来屏蔽图像的其余部分。接下来,我们删除该区域,仅使用LaneLine类中的域逻辑来过滤噪声数据,并决定是否将霍夫变换的输出视为车道线的候选线段。

阶段 2:车道线更新

使用image_pipeline中的一个函数update_lane(segments)调用这样的更新。正如我们看到的,我们从最后一个阶段得到了segments对象(这只是来自霍夫变换的Line对象)。

为了方便整个内务处理,我决定使用 OOP 方法,将车道线表示为Lane类的属性:Lane.left_line, Lane.right_line。我本来可以使用global对象,但是我不喜欢这种方法:污染全局名称空间肯定是一种不好的做法,并且会给代码增加混乱和不确定性。

让我们看一下LineLane类和实例。

Line instance 表示一条直线:一段车道线或者我们从 Hough 变换中得到的任意一条直线。Lane对象的主要目的是计算它与车道线的关系:我们是否可以考虑将它作为车道线的一部分?为此,我们使用以下领域逻辑:

如此保守和挑剔的候选人选择过程让我放弃了投资回报率。我们可能仍会得到有噪声的数据,但该过程仅接受接近车道线且看起来也与当前车道线相似的线的一部分。

我们使用一个简单的逻辑来确定一个Line实例属于哪条车道线:这是由这条线的斜率决定的。这里有很大的改进空间。

Lane类是两条车道线的容器(是这个Lane类的实例——这个部分需要重构)。它还提供了许多与车道线相关的方法,其中最重要的是fit_lane_line。为了得到一条新的车道线,我将正的Line候选表示为点,并用numpy.polyfit例程拟合一个一级多项式(这只是一条线)。

车道线稳定。这是一个需要解决的重要问题。我使用了几种稳定技术:

  1. 缓冲液。我的车道线对象记忆 N 个最近状态,并通过从当前帧插入一个线状态来更新缓冲器本身。
  2. 智能车道线状态更新。如果我们在过滤后仍然得到有噪声的数据,线拟合很容易出错。如果我们看到当前帧的拟合线的估计斜率与缓冲区的平均值相差太多,我们需要更保守地处理这条线。为此,我创建了DECISION_MAT,这是一个关于如何组合当前行位置和缓冲区平均位置的简单决策矩阵。

例如,对于DECISION_MAT = [[0.1,0.9],[1,0]],我们只有两种情况:不稳定线(与平均值的斜率差太高)和稳定线。对于不稳定的线,我们使用车道当前位置和缓冲区平均值的0.10.9的加权平均值。对于稳定的线,我们简单地使用其当前位置,而不使用历史数据进行任何加权。当前帧的车道线稳定性指示器在Lane.right_lane.stableLane.left_lane.stable布尔属性中描述。如果它们中的任何一个变成了False,我会把它想象成两条车道线之间的红色多边形(稍后你会在这篇文章中看到)。

最后,我们得到了相当稳定的车道线:

Hough lines converted to points (left). Fitted regression line (right)

阶段 3:绘制和更新初始图像

为了很好地渲染车道线,我写了一个计算消失点(两条车道线相交的点)坐标的程序。目前为止,消失点在我的项目中有两个目的:

  1. 限制车道线外推至其坐标。
  2. 消失点以上的每条霍夫线都不能被认为是候选线。这是一种定义感兴趣区域的软方法(而不是硬编码)。

我喜欢很多漂亮的可视化效果,所以我决定实现更多的绘图例程,并为它们使用统一的签名:

绘制本身是作为对初始图像进行变换的一个步骤来实现的:

正如我们在这里看到的,我渲染了两个快照,并将它们添加到第三个图像的仪表板上,这是一个经过转换的初始图像,上面有车道线。这种结构使得重新组合要在图像上呈现的内容变得很简单,并有助于可视化多个组件——所有这些都没有任何麻烦或重大的代码更改。

This is the video for Project 4. Linear detector works pretty well on it

顺便说一下,车道线之间的绿色多边形偶尔会变成红色,这是我前面描述的车道线的稳定性指示器。

从这里去哪里?

这个项目远远没有结束。我接触它越多,我就越能发现新的工作内容:

  • 使得检测器是非线性的。据我所知,这是项目 4 的主要目标:高级车道线检测。
  • 代替图像二值化的简单方法(选择颜色范围),实现一个 CNN,它可以在不同条件下检测车道线的部分。
  • 道路检测。检测道路本身并将其用作 ROI 是一件很棒的事情。

这个项目的完整代码可以在 GitHub(Jupyter 笔记本的直接链接)上获得:https://GitHub . com/kidra 521/carnd/blob/master/P1 _ lane _ lines _ detection/P1 . ipynb

附:有趣的部分

当然,这个帖子里应该有好玩的部分!现在让我们看看,当遇到山路时,这种线性检测器是如何失败的。虽然对于这样一个快速变化的斜坡来说太慢了,但它的开始还是令人满意的:

但是在森林中,当光线变化很快时,它会被完全破坏:

这太棒了——我将有机会在项目 4 中应对这一挑战。

敬请期待未来更多无人驾驶汽车的精彩!

猫还是狗?朴素贝叶斯简介

原文:https://towardsdatascience.com/cat-or-dog-introduction-to-naive-bayes-c507f1a6d1a8?source=collection_archive---------14-----------------------

如果你读过任何关于机器学习的介绍性书籍或文章,你可能会偶然发现朴素贝叶斯。这是一种通俗易懂的分类算法。

让我们退一步,解开朴素贝叶斯。

简而言之,朴素贝叶斯就是

  • 分类算法
  • 监督学习算法
  • 概率分类器

朴素贝叶斯是一种分类算法。一个复杂的名字来说,给定一个例子,朴素贝叶斯能够给它分配一个类别,就像给它贴上一个标签说,如果它看到一只猫的图像或一只狗的图像。

它也是被称为监督学习算法的算法家族的一部分。这是通过查看正确分类的示例来学习的算法类型。按照机器学习的说法,每个例子都是一组特征,即描述特定例子的属性。该算法用来学习的一组例子被称为训练集,它用来检查其分类能力的新的和从未见过的例子被称为测试集。算法最终向其分配一个标签。

朴素贝叶斯也是一个概率分类器。算法学习来预测的类或标签是创建它所显示的所有类的概率分布的结果,然后决定将哪个分配给每个示例。概率分类器查看条件概率分布,即在给定一组特定特征的情况下分配一个类别的概率。

假设你有这个(微小的)数据集,将动物分为两类:猫和狗。

A minuscule, dummy dataset 😁

如果该算法要计算出将哪个类分配给与上述类似的示例,即预测其类,它将考虑两件事:

a)假设毛发颜色为黑色,体长为 18 英寸,身高为 9.2,体重为 8.1 磅,…

b)在给定相同特征的情况下,成为狗的概率。

一般来说,条件概率是 P(类别|特征集)。在我们的例子中,classes = {cat,dog}和 feature set = {hair color,body length,height,weight,ear length,爪子}。

朴素贝叶斯将计算所有类的条件概率,因为它是朴素的,它将假设每个特征都是相互独立的。它将假设任何特征之间没有相关性,因此,它们对预测类的贡献不受其他特征的影响。

名字说明了一切。它使用贝叶斯定理来计算条件概率

Bayes Theorem

概率 P( | 特征集)也被称为后验,即在考虑所有给定条件后,事实发生后的概率。它是给定一组可以在猫身上观察到的特征(属性),将一幅图像分类为一只猫的图像的概率。P( )被称为先验,因为它是你事先知道的所有信息,是猫还是狗的概率。P( 特征集)被称为证据,因为它是你所观察到的概率,特征集。而 P( 特征集 | )被称为可能性,意思是给定这个特定的特征集,这是一个猫的图像的可能性有多大。

计算完所有类别的概率后,就该做决定了。

我应该给这个例子分配什么类呢?

将一个类别分配给一个新的、从未见过的特征集的决策是一个 最大后验决策 。一种是估计哪个后验概率,例如 P(特征集|猫)或 P(特征集|狗),将最大化看到该特定类的实例的可能性。

一般来说,你有

左手边那个戴着帽子的就是你的预测。

该算法将挑选具有较高概率的类。

总之,朴素贝叶斯利用贝叶斯定理来学习最能描述训练集中提供的示例的特征。它依靠最大后验决策规则来预测测试集中提供的每个新的、以前从未见过的示例的类别。

主要优点是

  • 简单
  • 需要小的训练集
  • 计算速度快
  • 与特征和训练示例的数量成线性比例
  • 处理二进制(猫,不是猫)和多类分类(猫,狗,老鼠)

缺点

  • 在现实世界中很少成立的强特征独立性假设。记住,这是天真的
  • 基于其独立性假设,可能提供较差的估计

感谢阅读!

CatBoost 与轻型 GBM 和 XGBoost

原文:https://towardsdatascience.com/catboost-vs-light-gbm-vs-xgboost-5f93620723db?source=collection_archive---------0-----------------------

谁将赢得这场预言之战,代价是什么?我们来探索一下。

我最近参加了这个 Kaggle 竞赛(斯坦福大学的 WIDS·数据通),在那里我使用各种推进算法进入了前 10 名。从那以后,我一直对每个模型的精细工作非常好奇,包括参数调整、优点和缺点,因此决定写这篇博客。尽管最近神经网络重新出现并受到欢迎,但我还是专注于 boosting 算法,因为它们在有限的训练数据、很少的训练时间和很少的参数调整专业知识的情况下仍然更有用。

由于 XGBoost(通常称为 GBM 黑仔)在机器学习领域已经有很长一段时间了,现在有很多文章专门讨论它,这篇文章将更多地关注 CatBoost 和 LGBM。以下是我们将涉及的主题-

  • 结构差异
  • 每个算法对分类变量的处理
  • 了解参数
  • 数据集上的实现
  • 每种算法的性能

LightGBM 和 XGBoost 的结构差异

LightGBM 使用一种新颖的基于梯度的单侧采样(GOSS)技术来过滤数据实例,以找到拆分值,而 XGBoost 使用预先排序的算法&基于直方图的算法来计算最佳拆分。这里的实例指的是观察结果/样本。

首先,让我们了解预排序拆分是如何工作的

  • 对于每个节点,枚举所有功能
  • 对于每个特征,按特征值对实例进行排序
  • 使用线性扫描来决定沿着该特征基础的最佳分割信息增益
  • 根据所有功能选择最佳分割解决方案

简而言之,基于直方图的算法将一个特征的所有数据点分割成离散的仓,并使用这些仓来找到直方图的分割值。虽然它在训练速度上比列举预排序特征值上所有可能的分裂点的预排序算法更有效,但在速度上仍落后于 GOSS。

那么是什么让这种戈斯方法如此有效呢? 在 AdaBoost 中,样本权重作为样本重要性的一个很好的指标。然而,在梯度提升决策树(GBDT)中,没有本地样本权重,因此不能直接应用为 AdaBoost 提出的采样方法。接下来是基于梯度的采样。

梯度表示损失函数的正切的斜率,因此在逻辑上,如果数据点的梯度在某种意义上很大,这些点对于找到最佳分裂点是重要的,因为它们具有较高的误差

GOSS 保留所有具有大梯度的实例,并对具有小梯度的实例执行随机采样。例如,假设我有 500,000 行数据,其中 10,000 行具有更高的梯度。所以我的算法会选择(较高梯度的 10k 行+随机选择的剩余 490k 行的 x%)。假设 x 是 10%,根据找到的拆分值,所选的行总数是 500K 中的 59k。

这里采用的基本假设是,具有小梯度的训练实例的样本具有较小的训练误差,并且它已经被很好地训练。
为了保持相同的数据分布,在计算信息增益时,GOSS 对梯度较小的数据实例引入了常数乘数。因此,GOSS 在减少数据实例的数量和保持学习决策树的准确性之间取得了良好的平衡。

Leaf with higher gradient/error is used for growing further in LGBM

每个模型如何对待分类变量?

CatBoost

CatBoost 可以灵活地给出分类列的索引,以便可以使用 one_hot_max_size 将其编码为一键编码(对于不同值的数量小于或等于给定参数值的所有要素使用一键编码)。

如果您没有在 cat_features 参数中传递任何东西,CatBoost 会将所有列视为数字变量。

注意:如果 cat_features 中没有提供包含字符串值的列,CatBoost 会抛出一个错误。此外,默认情况下,具有默认 int 类型的列将被视为数字,必须在 cat_features 中指定它,以使算法将其视为分类。

对于具有大于 one_hot_max_size 的唯一类别数的剩余分类列,CatBoost 使用一种高效的编码方法,该方法类似于均值编码,但减少了过度拟合。过程是这样的—
1。以随机顺序排列该组输入观察值。产生多个随机排列
2。将标签值从浮点或类别转换为整数
3。使用以下公式将所有分类特征值转换为数值:

其中, CountInClass 是对象的标签值等于“1”的次数,当前分类特征值
之前是分子的初始值。它由起始参数决定。 TotalCount 是具有与当前值匹配的分类特征值的对象总数(直到当前值)。
在数学上,这可以用下面的等式来表示:

LightGBM

与 CatBoost 类似,LightGBM 也可以通过输入特性名称来处理分类特性。它不会转换为一键编码,并且比一键编码快得多。LGBM 使用一种特殊的算法来寻找分类特征的分割值[ 链接 ]。

注意:在为 LGBM 构建数据集之前,应该将分类特征转换为 int 类型。即使通过 categorical _ feature 参数传递,它也不接受字符串值。

XGBoost

与 CatBoost 或 LGBM 不同,XGBoost 本身不能处理分类特征,它只接受类似随机森林的数值。因此,在向 XGBoost 提供分类数据之前,必须执行各种编码,如标签编码、均值编码或一键编码。

超参数的相似性

所有这些模型都有许多参数需要调整,但我们将只讨论重要的参数。下面是这些参数的列表,根据它们的功能以及它们在不同型号中的对应关系。

数据集上的实现

我使用的是 2015 年航班延误的 Kaggle 数据集,因为它同时具有分类和数字特征。该数据集大约有 500 万行,对于每种类型的提升,该数据集有助于判断优化模型在速度和准确性方面的性能。我将使用这个数据的 10%的子集~ 50 万行。
以下是用于建模的特征:

  • 月、日、星期几:数据类型 int
  • 航空公司和航班号:数据类型 int
  • 出发地 _ 机场目的地 _ 机场:数据类型字符串
  • 出发时间:数据类型浮点型
  • ARRIVAL_DELAY :这将是目标,并被转换为布尔变量,指示超过 10 分钟的延迟
  • 距离和飞行时间:数据类型浮点

XGBoost

轻型 GBM

CatBoost

在优化 CatBoost 的参数时,很难传递分类特征的索引。因此,我在没有传递分类特征的情况下调整了参数,并评估了两个模型——一个有分类特征,另一个没有分类特征。我单独调整了 one_hot_max_size,因为它不会影响其他参数。

结果

结束注释

对于评估模型,我们应该从速度和准确性两个方面来考察模型的性能。

记住这一点,CatBoost 在测试集上具有最高的准确性(0.816),最小的过拟合(训练和测试准确性都很接近)以及最小的预测时间和调整时间。但这仅仅是因为我们考虑了分类变量并调优了 one_hot_max_size。如果我们不利用 CatBoost 的这些特性,它的表现最差,只有 0.752 的精度。因此,我们了解到,只有当我们在数据中有分类变量并且我们适当地调整它们时,CatBoost 才表现良好。

我们的下一个表演者是 XGBoost,它通常工作得很好。它的准确性非常接近 CatBoost,即使忽略了我们在数据中有分类变量的事实,我们已经将其转换为消费的数值。然而,XGBoost 唯一的问题是它太慢了。特别是调整它的参数真的令人沮丧(我花了 6 个小时来运行 GridSearchCV——非常糟糕的主意!).更好的方法是单独调优参数,而不是使用 GridSearchCV。查看这篇博客文章,了解如何智能地调整参数。

最后,最后一名是 Light GBM。这里需要注意的重要一点是,当使用 cat_features 时,它在速度和准确性方面的表现都很差。我认为它表现不佳的原因是因为它对分类数据使用了某种修改的均值编码,这导致了过度拟合(与测试精度相比,训练精度相当高,为 0.999)。然而,如果我们像 XGBoost 一样正常使用它,它可以实现类似的(如果不是更高的)精度,但速度比 XGBoost
(LGBM — 0.785,XGBoost — 0.789)快得多。

最后,我不得不说,这些观察对于这个特定的数据集是正确的,对于其他数据集可能有效,也可能无效。然而,有一点是肯定的,XGBoost 比其他两种算法要慢。

那么你最喜欢哪一个呢?请评论原因。
非常感谢您的任何反馈或改进建议!

查看我的其他博客这里

领英:www.linkedin.com/in/alvira-swalin

资源

  1. http://learningsys.org/nips17/assets/papers/paper_11.pdf
  2. https://papers . nips . cc/paper/6907-light GBM-a-highly-efficient-gradient-boosting-decision-tree . pdf
  3. https://arxiv.org/pdf/1603.02754.pdf
  4. https://github.com/Microsoft/LightGBM
  5. https://www . analyticsvidhya . com/blog/2017/06/which-algorithm-take-the-crown-light-GBM-vs-xgboost/
  6. https://stats . stack exchange . com/questions/307555/mathematical-differences-between-GBM-xgboost-light GBM-catboost

如果你能抓住我:GANs 或决斗神经网络的简单英语解释

原文:https://towardsdatascience.com/catch-me-if-you-can-a-simple-english-explanation-of-gans-or-dueling-neural-nets-319a273434db?source=collection_archive---------5-----------------------

Photo by CloudVisual on Unsplash

根据《麻省理工科技评论》的年度十大科技榜单,深度学习是 2018 年最大的突破性技术之一

【熟能生巧】

我不太确定人类,但任何从事机器学习的人都会同意,实践,或优质训练数据让机器变得完美。嗯,差不多了..但绝对比我们凡人多得多。

一个完美的 AI 实现在任何领域都和魔术没什么区别。但问题是,随着机器开始学习,它们对数据的渴望是无法满足的……就像希腊神话中的坦塔罗斯,他的渴望永远无法满足。

数据科学家的时间都花在获取(和清理)越来越多的数据以输入机器上。他们的夜晚都浪费在教授机器从所有这些数据中学习,一遍又一遍地训练模型。

“数据”和“训练”两方面的严重缺陷使得 A & I 从 m A g I c 中消失,变得毫无意义。这,就是今天 AI 进步的最大瓶颈。

但是等等..如果机器可以承担任何人类的任务,为什么这个不能呢?我们能让机器自学吗?不,这不是文字游戏。和..是的,这是可行的。

(Pic source: stavos on flickr)

决斗神经网络

输入 GANs ..或其复杂的声音扩展,生成敌对网络。如果深度学习是下一个拿走蛋糕的大东西,那么甘就是蛋糕上的奶油。可能性从未如此令人兴奋!

但是,首先什么是 GAN?我们会试着用简单的英语来完成接下来的对话,不要使用令人讨厌的术语。所以,对诸如'概率'、感知器'、激活'、卷积等天书一样的东西,绝对说不。

我给你讲个故事吧。

上演完美的猫捉老鼠游戏

想象一部典型的电影,两个疏远的兄弟拥抱相反的人生哲学。一个人以 【操纵者】 的身份开始了印制假币的新黑社会行动,另一个人则加入了一个局,成立了一个新的部门,以 【执法者】 的身份检测假币。

首先,假设黑社会中的‘操纵者’一开始就处于劣势,对原始货币的样子一无所知。该局的【执行者】只知道真实货币看起来有多少的基本情况。

然后游戏开始了。

机械手开始印刷,但是最初的赝品很糟糕。它甚至不需要训练有素的眼睛来检测假货,并且每一个假货都被执法人员迅速检测出来。

操纵者很勤奋,不断制造假货,同时也学习以前的尝试中没有成功的地方。通过对假货的大量实验&一些反馈,假货的质量开始慢慢上升(当然,前提是运营没有停止!)

最终,操纵器开始获得一些随机的仿冒品,而这没有被执行者发现。因此,另一边是它的学习时间,而执行者学习如何检测这些更聪明的伪造品。

随着执法者变得更加聪明,假货再次被发现。操纵者别无选择,只能升级制假操作以制造更多看起来像真的假货。

这场持续的猫捉老鼠的游戏还在继续,并最终让操纵者执行者都成为专家。以至于赝品与真品难以区分,而且对如此精巧的赝品的检测变得几乎不可思议。

你明白了。这就是 GANs 的基本概念。

Photos ©Dreamworks

语境中的生成性对抗网络

现在让我们把我们的故事和演员翻译成 GANs。

GANs — a schematic flow with the key players

机械手执行器都是模型,是深度学习神经网络的变种。

操纵器被称为 ' 生成器网络 ' ,它的任务是创建训练数据,随机启动并尽可能地逼真。执行者' 鉴别器网络 ' ,其工作是检测并分类这些为‘真’或‘假’,并变得相当擅长。

通过将两个模型作为对手进行配对,我们为它们设置了一个健康的竞争。每个人都尝试在数千次迭代中掌握自己的工作,没有人工干预。瞧,我们最终得到了看起来像真的赝品,还有一个可以检测出大多数骗局的模型。

这就是为什么 GANs 是人工智能中的大师,因为它们既解决了现实世界中的问题当你没有足够的数据开始时生成“数据”,又解决了“训练”模型没有人工干预,这是一种无监督学习的形式。

至少这是他们要去的地方,而且他们已经开始行动了。在过去的几年里,GANs 稳步发展,产生了数百种变体,更多的创新正在进行中。

生成对抗网络是近十年来机器学习中最有趣的想法。— Yann LeCun,脸书人工智能公司董事

甘斯的效用是什么?

一台完美的货币印钞机或概念上类似的东西会给世界带来什么好处?显然很多,让我们看看 3 个广泛的领域。

1。创意追求

难以置信的是,机器终于打开了它们的右脑。毕竟,当一个书呆子程序员突然开始写获奖的诗歌时,谁不会感到惊讶呢?

用一种新发现的模仿真实图像的方法,GANs 开始创造想象中的名人,或带有艺术家独特签名的新杰作。这种能力的潜在用例跨越了创造性学科。

Imaginary Celebrities: Nvidia GANS model generated images using Celeb faces dataset as reference. (Paper)

2。翻译文本

假设你想知道一个人不戴眼镜或者换个新发型会是什么样子,你只需要创建这个。这与询问当天的天气或规划即将到来的通勤没有太大区别。

通过创造新的动植物来满足用户的需求,甘斯就像一个实现愿望的精灵。遗憾的是他们不能给作品注入生命..至少现在还没有。

Text to Image synthesis (Paper: https://arxiv.org/abs/1612.03242)

3。生成训练数据

GANs 承担着创建大量训练数据的重任,这些数据可以将人工智能带入进步的快车道。想象一下 GANs 产生了和我们相似的真实 3D 世界,有数百万英里的道路&所有可能的交通场景。

与其让无人驾驶汽车或无人驾驶飞机在现实世界中接受训练并引发可怕的事故,不如让它们在虚拟世界中接受训练并成为专业驾驶员。有了 GPU 计算,这可以瞬间完成。

Synthesising roads & real-life objects (GitHub: https://tcwang0509.github.io/pix2pixHD/)

虽然这些都是方向性的应用,但是 gan 已经被应用于高影响力的商业应用中,如药物研发,并且在实验的早期阶段有数百个用例。

虽然这听起来可能已经是革命性的,但甘斯最好的还在后头。本文的目的是分享一个简单、全面的教程来传播对这一重要技术的认识。现在,让我们等待魔法的展现吧!

对数据科学充满热情?随意在 LinkedIn 或者Twitter上加我。

[## Ganes Kesari | LinkedIn

在其他网站上包含此 LinkedIn 个人资料

www.linkedin.com](https://www.linkedin.com/in/ganes-kesari/)

搭乘航班:使用 Networkx 和底图可视化社交网络

原文:https://towardsdatascience.com/catching-that-flight-visualizing-social-network-with-networkx-and-basemap-ce4a0d2eaea6?source=collection_archive---------2-----------------------

Image source: Pixabay

“如果你把这些数字制成图表,就会出现一些模式。自然界到处都有模式。”

麦克斯·科恩(在达伦·阿罗诺夫斯基的电影《少年派》中由肖恩·格莱特饰演)

今天,我将介绍非常强大的网络可视化工具——Networkx 和 Basemap。许多有趣的问题自然来自或启发某种形式的图模型——顶点(或节点)和连接这些顶点的边之间的关系。例如:网站的外部链接和内部链接结构可以由有向图表示,其中顶点表示网页,有向边表示从一个页面到另一个页面的链接。再比如朋友圈,顶点代表不同的人,边代表关系的类型。

当涉及到复杂的网络时,如病毒爆发、国家间的现金流动或 2005 年地震的地震波,直观、描述性和有效地说明网络的属性仍然是一个挑战。我们希望观众能够快速掌握网络的地理环境。Networkx 和 base map(matplotlib 包的工具包)提供了一个“端到端”的解决方案。前者创建网络图并计算各种度量,而后者能够呈现直观且信息丰富的简洁可视化。

在本例中,我们来看一下美国各机场之间的航班航线网络。目标是表示顶点(机场)和边(飞行路线),并保持不同顶点之间的地理关系(例如:我们想看着图,并告诉这个顶点是 JFK 或洛根机场或什么)

By the end of this tutorial, you shall be able to construct visualization of flight network such as this

首先,我们加载相关的包:

**import** pandas **as** pd**import** networkx **as** nx**import** matplotlib.pyplot **as** plt**from** mpl_toolkits.basemap **import** Basemap **as** Basemap

matplotlib 底图工具包是一个用于在 Python 中的地图上绘制 2D 数据的库。Networkx 是一个研究网络结构的综合库。

读取机场数据:

第一步是获取数据并进行处理。在这里,我使用 OpenFlight 数据库来获取关于机场和路线的信息。他们有非常全面的数据。不幸的是,路由数据库不是最新的。它目前包含全球 531 家航空公司的 3,209 个机场之间的 59,036 条航线。直到今天,世界上有多达 17678 个商业机场。然而,当前的数据集对于我们今天的演示来说已经足够好了。

有两个相关的数据集:

  • airport.dat 数据集包含所有列出的机场的地理信息

Table 1: a quick peek at what the airport.dat dataset looks like

  • routes.dat 数据集包含所有列出的机场的地理信息

Table 2: the routes.dat dataset

处理机场和路线数据集:

Networkx 无法读取原始形式的数据,因此我们的首要工作是处理数据,以获得 Networkx 可以读取的干净的路由数据帧。这里,我们使用 熊猫 将 Excel 文件解析成数据帧,提取并处理信息。请注意这两个数据集是如何通过机场代码(三个字母的 IATA 代码)连接起来的。你可以在我的源代码这里找到处理数据的完整代码。

我们数据处理步骤的目的是获取以下两个 Panda 数据帧:

  • 一个压缩的 routes_us 数据框,其中每一行代表一条唯一的航线以及在该航线上运营的航空公司总数(例如,有 3 家航空公司运营从利哈伊谷机场(ABE)到亚特兰大国际机场(ATL)的航班)。

Table 3: a condensed and cleaned routes dataframe. This dataframe is used by Networkx to construct the graph network with nodes and edges

  • 一个压缩的 位置 数据框架,其中每行代表每个美国机场,带有 IATA 代码,更重要的是经度和纬度细节

Table 4: a condensed and cleaned position of airport dataset. This dataframe is used by Basemap to plot the nodes (airports) correctly on a USA map

有了前面的数据框架,我们就可以画出飞行网络的第一张草图了。

首先,我们将数据帧转换成一个图表。请注意,我们的图是一个有向图,也就是说,一个图有一组由边连接的顶点,这些边有与之相关的方向。这意味着在我们的图中,两条路由 JFK-ATL 和 ATL-JFK 是不同的,因为即使它们连接相同的 2 个节点,这两条路由具有不同的(相反的)方向。

我们使用 Networkx 的 from_panda_dataframe() 函数来快速导入我们的图表。在这里,我们从我们的数据帧 routes_us 创建一个图,其中源是“源机场”列,目标是“目的地机场”列,使用有向图模型。edge_attr 意味着我们可以向图的边添加信息。我添加了在一条路线上运营的航空公司的数量作为边属性

graph = nx.from_pandas_dataframe(routes_us, source = 'Source Airport', target = 'Dest Airport', edge_attr = 'number of flights',create_using = nx.DiGraph())

Networkx 确实有一个图形工具,我们可以用它来绘制我们的网络。

plt.figure(figsize = (10,9))nx.draw_networkx(graph)plt.savefig("./images/map_0.png", format = "png", dpi = 300)plt.show()

Graph drawn by Networkx’s default draw network function

这种粗略网络的问题在于,我们真的无法分辨哪个机场是哪个机场,以及各条航线之间是如何关联的。也许在美国地图上准确地标出机场的地理位置是个更好的主意。我们该怎么做?啊哈,底图!!!

使用底图绘制网络:

现在,我们需要帮助底图定义美国的边界线。让我们定义一个相对较大的地图,包括阿拉斯加和波多黎各。需要注意的一点是,我们有很多方法可以将一个大的区域,比如一个大陆,映射到一个 2-D 表面上。例如,我们可以选择等距圆柱投影,这是一种简单的投影,它将地球分成大小相等的矩形。更熟悉的方法是墨卡托投影,这是一种圆柱形的保形投影,在高纬度有很大的失真。是的,这是每个教室里被误导的地图,阿拉斯加和非洲大陆的面积一样大

a Mercator projection of the Earth (Image source: wikipedia)

我也选择熟悉的墨卡托投影。这

plt.figure(figsize = (10,9))m = Basemap(projection='merc',llcrnrlon=-180,llcrnrlat=10,urcrnrlon=-50,urcrnrlat=70, lat_ts=0, resolution='l',suppress_ticks=**True**)

现在,我们需要定义我们的机场在底图上的位置。到目前为止,我们只有它们的经度和纬度信息。我们需要找到它们在底图表面上的实际投影。注意我是如何调用我们的 位置 数据集,获取经度和纬度数据,并将它们投影到底图表面上的

mx, my = m(pos_data['Long'].values, pos_data['Lat'].values)pos = {}**for** count, elem **in** enumerate (pos_data['IATA']): pos[elem] = (mx[count], my[count])

下一步是要求 Networkx 将节点、边及其属性添加到底图中。这可以通过以下方式完成:

nx.draw_networkx_nodes(G = graph, pos = pos, node_list = graph.nodes(),node_color = 'r', alpha = 0.8, node_size = 100)nx.draw_networkx_edges(G = graph, pos = pos, edge_color='g', alpha=0.2, arrows = **False**)

最后一步是画出国家、海岸线和国境线。

m.drawcountries(linewidth = 3)m.drawstates(linewidth = 0.2)m.drawcoastlines(linewidth=3)plt.tight_layout()plt.savefig("./images/map_1.png", format = "png", dpi = 300)plt.show()

Basic graph drawn by Networkx and Basemap

嗯,这块地非常不符合气候。看起来不错,但不是很好。除了地图看起来很丑这一事实之外,我们无法从图表中看出任何东西。例如,我们希望看到更多信息,如:

  • 哪些机场很忙?
  • 哪些航线比较突出?

要回答这些问题,也许将每个机场的进出航班总数合并起来,并绘制成机场的大小是一个好主意。例如,有很多进出航班的机场会有一个更大的尺寸,在地图上看起来更明显。

为此,我们重复相同的代码,并做了一点小小的调整:

nx.draw_networkx_nodes(G = graph, pos = pos, node_list = graph.nodes(), node_color = 'r', alpha = 0.8, node_size = [counts['total_flight'][s]*3 **for** s **in** graph.nodes()])

Graph drawn by Networkx and Basemap, where the node size represents the relative amount of flights in and out the airports

这就好多了,一旦您更熟悉使用 Networkx 和底图,您就可以根据您的使用情况开始使用个性化地图。例如,在这里,我将我的地图限制在大陆机场,并对地图的样式稍作不同

Graph drawn by Networkx and Basemap, where nodes are label and split into groups of large and small airports.

我们可以开始进行各种有趣的观察:例如,许多大型机场大多位于沿海地区(以及拉斯维加斯、丹佛、达拉斯/沃斯堡、休斯顿和亚特兰大)。我们可以开始看到,与其他地理位置相比,西海岸地区的国内航线尤其密集。有趣的是,像 DEN(丹佛国际机场)这样的机场似乎起着枢纽的作用,也就是说,它是将乘客送到最终目的地的中转(或中途停留)点。在以后的文章中,我将介绍 Networkx 工具,使用 Networkx 分析这样一个网络中的边分布和节点特征

如果你喜欢这篇文章,你可能也会喜欢我的另一篇文章《体育可视化》:

关于其他有趣的统计事实和经验法则的深入分析:

本文的完整 Python 脚本可以在我的 Github 页面找到。

数据来源:OpenFlight。机场、航空公司、航线数据 2017https://openflights.org/data.html

因果推理 101:差异中的差异

原文:https://towardsdatascience.com/causal-inference-101-difference-in-differences-1fbbb0f55e85?source=collection_archive---------3-----------------------

案例研究:谁为强制分娩保险买单?

在今天的公共财政 III 讲座@斯坦福上,Petra 教授介绍了一种最广泛使用的因果推理技术:差异中的差异(diff-in-diff)。为了让我们的讨论不那么枯燥,她在强制福利的背景下激发了对这种酷技术的需求。

问题

当政府强制雇主提供福利时,谁真正买单?是雇主吗?还是员工以降薪的形式间接买单?

在这次演讲中,佩尔松教授定量地回答了这个问题,使用了一种叫做“T2”的酷技术。

为了使我们的讨论更容易理解,我们把重点放在一个案例研究上:分娩的强制医疗保险。这项分析是由 T4 的乔纳森·格鲁伯于 1994 年首次进行的,他是麻省理工学院的教授,同时也是 NBER 国家经济研究局医疗保健项目的负责人。迄今为止, 强制性福利的发生率 仍然是医疗保健经济学中最有影响力的论文之一。截至 2018 年 4 月 24 日,被其他 1148 篇学术论文引用。

时间表:强制性分娩保健覆盖面

理解时间线对于确定因果关系非常重要:

  • 1978 年以前:分娩的医疗保险有限。
  • 1975–1979:一些州通过了法律,强制规定分娩的医疗保险。
  • 从 1978 年开始:联邦立法要求所有州的分娩医疗保险覆盖范围。

询问数据:女性是否通过减薪间接为福利买单?

第一次尝试

第一步是比较年轻已婚女性的工资,任务前后:

Numbers in cells: log hourly wages. Numbers in parenthesis: standard deviation

我们看到,强制令颁布后,女性的实际工资下降了 3.4%。这种影响在统计学上是显著的。

我们能否得出结论,女性通过减薪 3.4%间接支付了薪酬?

还没有!为了让 3.4%成为真实的影响,我们需要假设,在此期间,强制令是唯一可能影响工资的因素。但事实可能并非如此。

第二次尝试

如果在这一转变过程中,整个国家陷入衰退,那该怎么办?那么无论如何,所有年轻已婚女性的实际工资都会被削减。

为了解决这个问题,我们来看看居住在尚未通过该法案的州的年轻已婚女性的变化。关键假设是:尚未通过授权的州提供了一个很好的反事实。这有助于我们理解,如果他们的州没有通过这项法令,年轻已婚女性的工资会发生什么。在学术术语中,这被称为“平行趋势假设”。你无法测试这一假设,但你可以通过绘制预趋势图来看看它有多大可能成立——年轻已婚女性的实际工资在有和没有强制规定的州是否平行变化。

Source: Columbia University Population Health Methods, and Gruber (1994)

在还没有通过这项法令的州,年轻已婚女性的实际工资实际上增长了 2.8%!所以在那些通过了强制令的州,年轻、已婚女性的实际工资变化是-3.4% -2.8% = -6.2%。这个-6.2%的估计是“不同中的不同”估计。

但是我们还没有结束。

第三次是一种魅力

但是如果平行趋势假设不成立呢?例如,可以想象,有一些 X 因素与分娩保险的强制规定在同一时期生效。那么实际工资的 6.2%的变化可能归因于这个 X 因素,而不是分娩保险的强制规定!

Source: Quick Meme

这似乎是一个不可能解决的批评。但我们并没有完蛋。

Triple-diff 来救援!

为了检验这种可能性,让我们对未受分娩保险影响的人群——男性——重复差异中的差异分析。

这个想法是说,在这段时间里,上述 X 因素会影响到每个人;但是分娩保险的要求只会影响年轻的已婚妇女。如果男性的 diff-in-diff 估计值为-6.2%,那么我们应该把实际工资的所有变化都归因于这些 X 因素,而不是生育指令。

幸运的是,男性的差异-差异估计值为-0.8%,在统计上微不足道。但是为了完整起见,我们仍然会计算三重差异估计值= (-6.2%) - (-0.8%) =-5.4%!

总结和总结课

  • 平均而言,年轻已婚妇女的实际工资下降了 5.4%,以应对分娩保险的要求。
  • 这到底是不是一个有益的改变?只有个人能对此负责。对一些人来说,这可能不是一个大的下降。但是如果你是一个不打算要很多孩子的年轻女性,你可能不会那么高兴。
  • 这个结果防弹吗?当然不是。但是任何替代解释的门槛现在都非常高。任何其他解释都需要找出一个 X 因素,这个因素使得年轻已婚女性的工资在一个州的分娩令通过后立即下降 5.4%,但在任何其他时间段或任何其他人群中都没有。
  • 外卖教训:当试图确定一个事件的因果关系时,仅仅比较前后是不够的。通过巧妙的去意。你可以保护自己不被低估或高估因果关系。记住,关联!=因果关系!

附录:回归规范

如果您想自己实现这种回归,下面是回归规范。如果你发现我的推理有任何错误,请不要犹豫给我留言!

直到下次:)

购买者自负,计算社会科学

原文:https://towardsdatascience.com/caveat-emptor-computational-social-science-8c2c2d5a7cc5?source=collection_archive---------15-----------------------

广泛发布的 Reddit 数据集中大规模缺失的数据可能会破坏你的研究质量

随着研究人员利用大型数据集大规模研究复杂的社会行为,这种计算社会科学的有效性取决于数据的完整性。这就是为什么研究人员有责任检查数据集,而不是凭信念假设它们的质量。

Fragments of Plato’s Phaedrus found in Oxyrhynchus. Datasets used by computational social scientists are often just as fragmented, though gaps may not be as obvious.

2015 年 7 月 2 日,杰森·鲍姆加特纳发布了一个数据集,宣称包含“所有公开的 Reddit 评论”,这个数据集很快在 Bittorrent 和互联网档案馆上被分享。这些数据很快成为许多学术论文的基础,这些论文的主题包括机器学习、社会行为、政治、突发新闻和仇恨言论。在最近发表的一篇由内森·马蒂亚斯撰写的文章的预印本中,我们发现了该数据集中的实质性差距和局限性,这可能会导致该研究结果的偏差。

d .加夫尼、J. N .马蒂亚斯(2018)。 购者自负,计算社会科学家:大规模数据缺失在广泛出版的 Reddit 文集 arXiv:1803.05046【cs。SI]

在我们的论文中,我们记录了数据集、数据集中大量缺失的观察值,以及这些缺口对研究有效性带来的风险。总的来说,我们发现 2015 年 1 月 23 日至 2017 年 6 月 30 日之间可能有 3600 万条评论和 2800 万条提交内容丢失的证据,这些证据以目前不可预测的方式分散在整个数据集中。我们还概述了计算社会科学中从缺失数据到常用方法的风险:

强风险:

  • 用户历史记录
  • 网络分析

中度风险:

  • 社区之间的比较
  • 参与水平

低,但真实的风险:

  • 机器学习和任何其他避免对人、社区或行为做出断言的研究

我们相信使用这个数据集的论文总数,无论是已经发表的还是正在进行的,都在几十篇以内。我们的论文直接引用了我们知道的 15 篇论文来使用这些数据(我们预计我们遗漏了一些)。自数据集发表以来,这些工作跨越了近两年的学术时间,代表了广泛多样的研究目标。

确定 Reddit 数据集中的差距

我们对缺失数据的分析始于在数据集中找到容易识别的不可能:一些评论是对语料库中不存在的帖子的回应。这些“悬空引用”是引用帖子或其他评论的评论(因为参与 Reddit 评论线程是嵌套评论的“树”),这些评论在数据集中是缺失的。我们还绘制了“未知的未知”,这是“应该”存在于 Reddit 数据集中,但在语料库中找不到的 id。Reddit 采用了一个基数为 26 的 ID 系统,该系统对于平台上的所有内容都是单调递增的——第一条评论是评论 ID #1,第二条是评论 ID # 2,依此类推。

基于这些知识,我们浏览了提交和评论的 ID 空间。遗漏的评论在子 reddit 和时间上分布不均匀,这种不均匀的误差分布(到目前为止)不能简单地用 Reddit 在特定时间点的大小或子 Reddit 的大小来解释。

Missing data rates for Reddit comments to June 2017 — medium blue is total missing per month, light blue is a rolling average missing amount, and dark blue is the cumulative error rate throughout the dataset. That the dark blue line is reliably linear after 2013 indicates a chronic portion of missing data.

基于我们的研究,杰森·鲍姆加特纳发布了数据集的补丁,填补了一些,但不是所有的空白——一些缺失的数据现在是任何人都无法获得的。此外,我们正在向提供从数据集开始到 2017 年 6 月(我们检查的最新日期)数据集中所有已知缺失缺口的副本。

通过公开讨论缺失数据问题来改进研究

我们并不打算让这篇文章成为针对现有文献的“抓住问题”的文章。我们已经向我们引用的所有研究团队发送了我们论文的副本,一些团队已经根据我们的了解更新了他们的发现(当有更多可用时,我们将在下面发布链接)。Jason 与我们密切合作,尽可能多地了解和解决问题。

我们的发现只是计算社会科学中一个持久问题的一个实例——研究受到我们使用的数据集和这些数据集中存在的任何已知或未知的偏见的限制。

杰森·鲍姆加特纳的数据集已经成为计算社会科学的非凡资源,我们预计它将继续产生重要的发现。研究人员有责任认识到数据的局限性,适当地解释它们,并记录这些问题如何影响我们的发现。

请将这篇文章分享给任何你认识的想要使用这个数据集的人。我们也鼓励审稿人要求作者解释他们论文中任何缺失的数据。

如果你是一名想使用 Reddit 数据集的研究人员,请 不要只引用我们的论文而忽视我们提出的问题 。我们强烈鼓励任何研究人员采取以下步骤:

  • 用 Jason 的更新修补数据集,知道它只是填补了一些空白
  • 报告影响你论文的缺失数据量,在你研究的数据集部分应用类似于我们的方法
  • 通过模拟数据来填补空白,找出您的发现对缺失数据的敏感程度,然后使用模拟数据来计算您的发现的上限和下限

计算缺失数据需要花费时间,并且会增加您完成研究的时间。由于有缺陷的发现一旦公之于众就很难纠正,我们鼓励你在用这个数据集做研究时投入时间。

我们感谢所有根据这些发现回顾他们过去研究的作者。出于这个原因,我们计划更新这篇文章和我们论文的附录,提供历史上使用过这些数据的研究人员进行的任何重新分析的信息。我们希望这将有助于每个人提高我们共同工作的质量。

庆祝迈向数据科学一周年

原文:https://towardsdatascience.com/celebrating-1-year-of-towards-data-science-ca13cf65481?source=collection_archive---------6-----------------------

迈向数据科学始于一年前的 2016 年 10 月 21 日。

我们现在已经成长为一个在 Medium 上拥有超过 3 万名粉丝的社区,并在脸书推特LinkedInInstagram 上出现。

请回顾一下我们历史上阅读量最大的文章。看起来 Tensorflow 是去年的热门话题——在接下来的一年里,一定要跟上我们,看看接下来会发生什么!

感谢我们伟大的作家们的所有贡献。

1。言情小说,由人工智能生成

这篇关于由神经网络生成的爱情小说标题的文章获得了超过 37,000 次阅读,感谢 Elle O'Brien 分享你的作品。

有一天在你附近的书店寻找不可能的婴儿、伯爵的藏罐人、便利夫人

2。 用 Tensorflow 和 Opencv 构建实时物体识别 App

Dat Tran 开发了一个很棒的物体识别应用程序,并分享了超过 35,000 次阅读的结果。

3。参加 Deeplearning.ai 课程后的感想

感谢 Arvind N 向超过 33,000 名读者分享他关于参加 Deeplearning.ai 课程的想法!

4。 LSTM 举例使用张量流

长短期记忆,以 Tensorflow 为例,由罗威尔·阿蒂恩萨撰写,拥有 25000 名读者。

5。 在 Python 中展平 JSON 对象

19300 名读者从 Amir Ziai 那里学习了如何使用 Python 展平 JSON 对象。

Embedded arrays pose a problem for json_normalize

Use pip install flatten_json to fix it

6。如何用 TensorFlow 的物体检测器 API 训练自己的物体检测器

TensorFlow 是今年的热门话题,有 17,100 人收听学习如何从 Dat Tran 训练他们自己的物体探测器——祝贺你两次进入十大名单!

7。深度学习的线性代数小抄

Brendan Fortuner 分享了他的小抄,16200 人欣然接受了帮助。

8。Google Tensorflow 物体检测 API 是实现图像识别最简单的方法吗?

Priya Dwivedi 的 Tensorflow 对象检测 API 获得了 15,900 次阅读。

9。软件架构模式

Anuradha Wickramarachchi 教我们软件架构模式和分层架构,阅读量超过 14000 次。

10。Python 中的简单和多元线性回归

前十名中最后但同样重要的是 Adi Bronshtein 向超过 13,000 名读者解释如何用 Python 进行简单和多元线性回归。

感谢我们的作者推动我们走向数据科学!

产品推荐系统面临的挑战和解决方案

原文:https://towardsdatascience.com/challenges-solutions-for-production-recommendation-systems-d656024bbdca?source=collection_archive---------10-----------------------

有很多关于培训和评估推荐者的文章,但很少有人解释如何克服建立全面系统所涉及的挑战。

大多数库不支持现成的可伸缩生产系统。挑战通常是:

  • 动态预测 —当你有一个非常大的用户/项目维度时,预先计算所有的推荐可能是非常低效的,或者是不可能的。
  • 优化响应时间 —当您动态创建预测时,您需要检索它们的时间非常重要。
  • 频繁更新模型 —当系统需要整合新数据时,频繁更新模型至关重要。
  • 基于看不见的数据进行预测 —这意味着处理看不见的用户或项目,并不断改变功能。

这篇文章将告诉你如何修改一个模型来扩展它在一个完整的生产环境中的功能。

混合推荐模型能更好地应对现实世界的挑战

我们使用一个 LightFM 模型,这是一个非常流行的 python 推荐库,它实现了一个混合模型。它最适合中小型推荐项目,在这种情况下,您不需要分布式培训。

不同推荐方法的简短回顾

有两种基本的推荐方法:

协作 模型仅使用协作信息——用户与项目的隐式或显式交互(如观看、评级或喜欢的电影)。他们不使用任何关于实际项目的信息(如电影类别、流派等)。).

协作模型可以用很少的数据达到高精度,但是无法处理未知的用户或项目 ( 冷启动问题)。

基于内容的 模型纯粹对关于物品或用户的可用数据起作用——完全忽略用户和物品之间的交互。—所以他们对待建议的方式与协作模型非常不同。

基于内容的模型通常:

  • 需要更多的训练数据(你需要有几乎每个用户/项目组合的可用用户/项目示例),以及
  • 更难调整吗?

但是他们可以对看不见的项目做出预测,并且与合作模型相比,通常有更好的覆盖率,合作模型倾向于给予流行项目更多的关注。

混合推荐器——像 light FM——结合了两种方法,克服了每种方法的许多挑战。

他们可以处理新物品或新用户:

当您将协作模型部署到生产中时,您经常会遇到需要为看不见的用户或项目进行预测的问题,比如当新用户注册或访问您的网站时,或者您的内容团队发布了一篇新文章时。

通常你必须至少等到下一个训练周期,或者直到用户与某个项目交互,才能为这些用户做推荐。

但是混合模型即使在这种情况下也能做出预测:它将简单地使用部分可用的特性来计算推荐。

混合动力车型还可以处理缺失的功能:

有时,某些用户和项目的特性会丢失(仅仅是因为您还不能收集它们),如果您依赖于基于内容的模型,这将是一个问题。

混合推荐器适用于老用户(那些通过培训认识的用户)以及新用户/项目,只要你有他们的特征。这对于项目尤其有用,对于新用户也是如此(当用户第一次访问你的网站时,你可以问他们对什么感兴趣)。

系统组件

**该系统假设项目比用户少得多,因为它总是检索所有项目的预测。但是它可以作为更复杂的推荐器的基础

系统的核心是一个 flask app ,它接收一个用户 ID 并返回该用户的相关项目。它将(重新)加载 LightFM 模型,并在 Redis 实例中查询条目和/或用户特性。

我们将假设用户和项目特征被存储和序列化在 Redis 数据库中,并且可以由 flask 应用程序随时检索。

所有应用程序都将通过 docker 容器部署为微服务。

LightFM 如何进行预测

但是它是如何工作的呢?

LightFM 的论文对于学术读者来说信息量很大,但是对于不太熟悉这个领域的人来说可能有点简短。我将在下面更简单地概述 LightFM 模型预测过程。

**公式解释:

  • 小写字母指向量,大写字母指矩阵。
  • 下标 u 指单个用户, U 指所有用户的完整集合。项目以同样的方式引用。(下标由 Medium 支持,因此您可以看到它们由下划线分隔)

这里的大部分命名与 LightFM 论文一致。

模型组件

因此,LightFM 结合了协作和基于内容的方法的优点。你可能会说它为两种方法中的每一种建模一个组件。这两者对于我们从推荐者那里得到我们想要的属性都是必要的。

协作组件

协作组件允许您在没有任何功能的情况下依靠协作过滤算法——或者这些功能不提供信息。

最先进的协同过滤算法是通过矩阵分解实现的。他们估计了两个潜在的(未观察到的)矩阵表示,当它们彼此相乘时,将重现模型在训练期间看到的每个项目和用户的交互矩阵。当然,有一个误差项可以考虑噪声并避免过度拟合。

一个简单的类比:尝试因式分解 12。我们可以用 2 和 6,3 和 4,1 和 12 等等来做这个。矩阵也是如此。

我们称这些矩阵为潜在代表,因为它们是我们交互数据的压缩形式。

基于内容的组件

基于内容的组件允许您获得预测,即使您没有交互数据。

LightFM 通过将特征与潜在表示相关联来合并用户和项目特征。假设特征和潜在表征是线性相关的。所以在矢量形式中:

q_u 是潜在用户表示, f_u 是单个用户的特征行向量, E_u 是估计的项目嵌入, b_u 是用户嵌入的偏差。(为了简单起见,我们从现在开始将它们省去。)

看起来和线性回归差不多吧?只不过 E_U 是一个矩阵,而相反,后者通常是一个向量。事实上,这实际上执行了多重回归:每个模型组件一个。同样,对于物品来说也是类似的。

在训练期间,借助于梯度下降算法来估计用户嵌入和项目嵌入。对于每个特征,嵌入矩阵将有一行。嵌入矩阵的列称为分量。组件的数量被设置为模型超参数,从现在开始我们称之为 d。

上图概括了所有用户和所有项目的流程。因此,在步骤 I 中,我们有形状为N _ 用户 x N _ 用户 _ 特征的用户特征矩阵与形状为N _ 用户 _ 特征* x d 的嵌入矩阵的矩阵乘法。这同样分别适用于项目特征与项目嵌入的第二次乘法。来自步骤 I 的结果分别是形状为 N_users x dN_items x d 的两个矩阵。因此,每个用户/项目被表示为大小为 d 的潜在向量。*

在最后一步中,这两个矩阵相乘,得到每个用户和形状为 N_users x N_items 的项目的最终得分。

现在,您可以使用以下术语轻松获得单个用户的所有表示:

q_u 是用户潜在表征的行向量, Q_I 是所有项目潜在表征的矩阵。

使用指标矩阵支持退回到协作模式

LightFM 可以从纯协作信息中生成模型。

它使用了一个非常有效的技巧:如果根本没有使用用户或项目特征,该模型将接受一个大小分别为 N_usersN_items 的单位矩阵。这非常有效,因为它会学习组件——每个用户一个。这样,模型总是可以依靠最佳的纯协作方法。您可以将这些组件视为模型在训练过程中已经看到的用户和项目的记忆。

您还可以强制模型退回到协作模式——即使您确实有特征:*您可以通过向特征矩阵添加一个单位矩阵来修改它**。有时候你需要这个来让你的模型收敛。但是,这通常意味着您的要素噪音太大,或者没有携带足够的信息,因此模型无法自行收敛到最小值。*

最后,使用这种技巧会增加将模型投入生产所需的工作量:在训练期间,用户的索引用于检索相应特征/身份矩阵的正确行,而这些信息在生产环境中可能不再可用;另外,LightFM 模型将这个责任交给了用户。

有趣的事实

仅使用指示器特征可以获得的相似项目/用户(在协作信息方面)的潜在 表示将在欧氏空间中接近。该模型基于协作信息来估计它们。所以你可以用这些来找到你的物品或用户之间的相似之处。

动态重新创建指示器和功能

现在让我们实现一个模型,它可以依赖于协作模式,跟踪 IDs,从而能够重建正确的特性和指标。

我们将专注于实现一个完整的方法。这是相当复杂的,因为同时,它应该能够在大多数情况下给出预测。我们将创建 LightFM 类的子类,并添加一个特殊的predict_online方法,该方法将在生产过程中使用。

这样,我们仍然可以使用 LightFM 的 cythonised 预测功能,避免分别处理用户和项目 id 映射。

它应满足以下要求:

  1. 如果在训练期间看到用户/项目,则重建指示器特征;
  2. 无论某个用户有什么数据,都可以进行在线预测;
  3. 尽快做出这些预测。

ID 映射

为了达到第一个要求,你也必须在训练中使用同样的课程。您还需要调整您的子类,以便它在训练期间只接受稀疏度稀疏帧对象,并因此创建和保存 ID 映射。

重构特征

为了达到第二个要求,您需要在每次收到请求时检查可用的数据。你要处理 16 个案子:

在情况 IVVIIIXII 中,我们简单地返回我们的基线预测。对于案例 XIIIXVI ,我们无法给出任何预测,因为我们对条目的了解还不够。

总结:我们基本上想要创建一个包含用户特征的行向量,如果它们可用的话。否则在各自的索引处都是零。如果在训练期间看到用户,它还将包含设置在正确索引处的用户指示器特征。

项目特性类似于用户特性,除了我们希望它们能够很容易地适应内存以允许缓存。您可以根据您的用例考虑使用不同的缓存策略(比如 TTLCache ),或者根本不缓存。

我们还希望支持而不是添加指示器,或者只将它们添加到用户或项目特性中,这可能会使实现稍微复杂一些。尽管如此,我们还是尽量保持简单。

您将在这里找到上述方法的示例实现。该实施应能正确处理所有情况,直至 VIII 。但是有可能不是所有的条目都被实现了,因为我们的应用程序不需要它。因此,预测没有项目特征的已知项目是不可能的,但应该很容易添加。

履行

查看示例实现

请随时寻求帮助或添加任何意见。我很乐意回来回答他们。

观点

本文的第二部分使用这个类,将它连接到 Redis 数据库,并使用 flask 动态地为它提供预测。我们还将向您展示如何使用从 flask 应用程序内部启动的后台线程在不停机的情况下更新模型。

最初发表于T5【www.datarevenue.com】

机会是不够的:用排列评估模型的重要性

原文:https://towardsdatascience.com/chance-is-not-enough-evaluating-model-significance-with-permutations-e3b17de6ba04?source=collection_archive---------16-----------------------

理解你的回归

Python 模拟展示了为什么模型精度应该与排列而不仅仅是机会进行比较

当训练机器学习模型进行分类时,研究人员和数据科学家经常将他们的模型性能与机会进行比较。然而,这通常是不够的。通过将模型与垃圾标签上训练的模型集合进行比较,可以实现真正的显著性测试。如果大量根据垃圾数据训练的模型也可以用来预测,这表明你的模型并不比垃圾模型好多少。因此,在某些情况下,明智的做法是不仅将模型的准确性与概率进行比较,还与垃圾模型的表现进行比较。在本教程中,我们比较了比机会更好的分类性能实际上并不一定比随机模型好得多。

让我们考虑一个假设的研究,在这个研究中,我们试图对参与者从他们的大脑活动中看到的图像进行分类。参与者看了 10 次带有快乐脸(标为 1)或愤怒脸(标为 0)的图像,每个参与者有 20 次试验。在这个设置中,预测一个条件优于另一个条件的几率是 50% 。我们为 40 名参与者(组)生成 800 次试验的 60 个体素(特征)数据,这意味着每位参与者都有 20 次(=800/40)试验。在这 20 次试验中,一半是快乐的脸,另一半是愤怒的脸。所有特征都是从 0 到 1 之间的均匀分布中随机抽样的,平均值为 0.5。为了给模型提供分类的有用特征,我们将一组具有相同分布的随机值添加到数据中的每第 8 个值,以便试验 0、8、16 等将具有更高的值,可以利用这些值来对笑脸进行分类。

# Load required packages. 
%matplotlib inline import numpy as np, pandas as pd, matplotlib.pyplot as plt, seaborn as sns, os, glob 
import matplotlib.gridspec as gridspec 
from sklearn.linear_model import LogisticRegressionCV 
from sklearn.model_selection import LeaveOneGroupOut 
from scipy import stats # set random seed for same answers np.random.seed(1) 
n_samples = 800 # Total number of samples 
n_features = 60 # Total number of features (~voxels) 
n_groups = 40 # Total number of participants 
n_features_useful = 10 # Subset of features that would be useful n_skip = 8 # Every Nth trial that would be infused with slightly useful features # Generate random data 
X = np.random.rand(n_samples,n_features) # Add random values to make every n_skip-th feature useful X[::n_skip, :n_features_useful] = X[::n_skip,:n_features_useful]+np.random.rand(X[::n_skip,:n_features_useful].shape[0],X[::n_skip,:n_features_useful].shape[1]) # Generate labels 
y = np.tile([0,1],int(n_samples/2)) 
# Generate groups 
groups = np.repeat(range(0,n_groups),int(n_samples/n_groups))

现在让我们可视化两个受试者(40 次试验)的数据子集。请注意列之间的水平亮光,这是我们的模型应该能够用来预测笑脸的特征(Y 的暗条)。

# Here we visualize the data 
gs = gridspec.GridSpec(1,5) 
ax1 = plt.subplot(gs[0, :3]) 
ax2 = plt.subplot(gs[0, 3]) 
ax3 = plt.subplot(gs[0, 4]) sns.heatmap(X[:40,:30],cbar=False,ax=ax1) ax1.set(xlabel='Features',ylabel='Samples') sns.heatmap(np.array([y]).T[:40],ax=ax2,xticklabels='Y',cbar=False) sns.heatmap(np.array([groups]).T[:40],ax=ax3,xticklabels='',yticklabels='',cmap=sns.color_palette("Paired",40),cbar=False) ax3.set(xlabel='Groups') 
plt.suptitle('X and y visualization',y=1.02) 
plt.tight_layout()

现在,我们使用留一名受试者交叉验证的逻辑回归来训练我们的预测模型。对于每一个被遗漏的对象,我们训练一个内置交叉验证的新模型来选择最佳的正则化强度(详见)。

logo = LeaveOneGroupOut()scores = []
for train_ix, test_ix in logo.split(X,y,groups):
    X_train, X_test = X[train_ix], X[test_ix]
    y_train, y_test = y[train_ix], y[test_ix]
    clf = LogisticRegressionCV()
    clf.fit(X_train,y_train)
    score = clf.score(X_test,y_test)
    scores.append(score)
mean_score = np.mean(scores)
t,p = np.round(stats.ttest_1samp(scores,.5),3)
title = f'Mean accuracy: {mean_score}\n  1-sample t-test against chance : t = {t}, p = {p}'f,ax = plt.subplots(figsize=(4,3))
sns.barplot(scores,ci=95,orient='v', capsize=.1,ax=ax)
sns.stripplot(scores,ax=ax,orient='v',color='k',alpha=.5,jitter=.05)
ax.axhline(.5,color='r',linestyle='--')
ax.set(ylabel='Accuray (%)')
plt.title(title, pad=10)
plt.show()

这是结果,红色虚线表示几率为 50%。

呜-呼!我们的交叉验证模型显示了 57.5%的交叉验证准确性,这明显优于 t-检验和 bootstrapped 置信区间(柱状图中显示的 95% CI)。不是世界上最好的模型,但仍然比机会好,所以我们应该很好地发表,对不对?

没那么快。

很有可能这个模型并没有比任何从数据中产生的垃圾模型做得更好。一个更严格的测试是将模型精度与根据随机标签训练的垃圾模型的精度分布进行比较。这样,你就可以估计出你的模型比垃圾模型好多少。

为了建立这种准确度分布,我们在每个交叉验证折叠中训练 50 个额外的模型,最终创建 2000 个准确度的分布。在每一次折叠中,训练集的标签被打乱以预测被遗漏的对象的真实标签。显著性得分由得分优于真实模型得分的排列的数量决定。

np.random.seed(1)
logo = LeaveOneGroupOut()
n_permute = 50
permuted_scores = []
count = 0 
for train_ix, test_ix in logo.split(X,y,groups):
    X_train, X_test = X[train_ix], X[test_ix]
    y_train, y_test = y[train_ix], y[test_ix]
    train_df = pd.DataFrame({'y':y_train,'groups':groups[train_ix]})
    for permute_ix in range(n_permute): 
        count+=1
        if count%100==0:
            print(count,end=',')
        y_train_shuffled = train_df.groupby('groups')['y'].transform(np.random.permutation).values
        clf = LogisticRegressionCV()
        clf.fit(X_train,y_train_shuffled)
        score = clf.score(X_test,y_test)
        permuted_scores.append(score)
train_shuffled_score = np.mean(permuted_scores)
score_percentile = np.mean(mean_score < permuted_scores)
title = f'True score percentile : {score_percentile}'f, ax = plt.subplots() 
plt.hist(permuted_scores,bins=15)
ax.axvline(train_shuffled_score,color='k',linestyle='--',label='Chance')
ax.axvline(mean_score,color='r',linestyle='--',label='True classification score')
ax.set(xlim=[0.1,.9],xlabel='Accuracy (%)',ylabel='Count',title = title)
plt.legend()

在这个过程之后,我们发现我们的 57.5%的模型性能实际上并不比垃圾模型的精度好多少。p = .256 的百分位数 p 值表明,大约 26%的混合标签训练模型实际上比我们的模型表现得更好。

在 scikit-learn 中,这个方法也被实现为[permutation_test_score](https://scikit-learn.org/stable/modules/generated/sklearn.model_selection.permutation_test_score.html#sklearn.model_selection.permutation_test_score),它混合了训练和测试标签。在某些情况下,这可能会产生比仅混洗训练标签更紧密的分布。

np.random.seed(1)
logo = LeaveOneGroupOut()
n_permute = 50
permuted_scores = []
count = 0 
for train_ix, test_ix in logo.split(X,y,groups):
    X_train, X_test = X[train_ix], X[test_ix]
    y_train, y_test = y[train_ix], y[test_ix]
    train_df = pd.DataFrame({'y':y_train,'groups':groups[train_ix]})
    test_df = pd.DataFrame({'y':y_test,'groups':groups[test_ix]})
    for permute_ix in range(n_permute): 
        count+=1
        if count%100==0:
            print(count,end=',')
        y_train_shuffled = train_df.groupby('groups')['y'].transform(np.random.permutation).values
        y_test_shuffled = test_df.groupby('groups')['y'].transform(np.random.permutation).values
        clf = LogisticRegressionCV()
        clf.fit(X_train,y_train_shuffled)
        score = clf.score(X_test,y_test_shuffled)
        permuted_scores.append(score)
train_test_shuffled_score = np.mean(permuted_scores)
score_percentile = np.mean(mean_score < permuted_scores)
title = f'True score percentile : {score_percentile}'f, ax = plt.subplots() 
plt.hist(permuted_scores,bins=14)
ax.axvline(train_test_shuffled_score, color='k', linestyle='--',label='Chance')
ax.axvline(mean_score,color='r',linestyle='--',label='True classification score')
ax.set(xlim=[0.1,.9],xlabel='Accuracy (%)',ylabel='Count',title = title)
plt.legend()

在我们的模拟数据中,我们看不出混合训练和测试标签与仅混合训练标签之间有多大区别。

在这里,我们模拟数据,以显示比较模型准确性的机会,有时可能会误导。一个比机会稍微精确一点的模型可能不会比其他在混洗标签上训练的垃圾模型好很多。然而,我们也应该考虑到每个受试者的样本数量可能会限制你的置换模型真正的“随机”程度。例如,如果每个对象只有 2 个样本,那么混洗这些样本不会像你想的那样给你一个大的准确度分布。

这里有一些关于这件事的文件:

奥贾拉和加里加。研究分类器性能的排列测试。《机器学习研究杂志》(2010 年)第 11 卷

标签:[machine-learning](http://jinhyuncheong.com/tag/machine-learning) [chance](http://jinhyuncheong.com/tag/chance) [significance](http://jinhyuncheong.com/tag/significance) [permutations](http://jinhyuncheong.com/tag/permutations) [analysis](http://jinhyuncheong.com/tag/analysis) [data](http://jinhyuncheong.com/tag/data)

原载于 2018 年 12 月 5 日jinhyuncheong.com

变换

原文:https://towardsdatascience.com/change-of-basis-3909ef4bed43?source=collection_archive---------8-----------------------

如果你认为这很容易,你可能做错了。

If you’re struggling with coordinate system conversion, enjoy this sunset for a second, knowing your answer is just below.

我最近一直在做 USD Unity SDK ,有一个话题出现了几次,就是从右手系统(比如 OpenGL/USD)到左手系统(比如 Unity/DirectX)的基础转换。如果你需要将一个矩阵或向量从左手坐标系转换到右手坐标系,你知道我的痛苦;本着务实的精神,我将首先提出解决方案,然后我们可以深入讨论细节。我也将展示一个奇怪的技巧,谁知道呢,也许我们 可以 只是将 Z 乘以-1。

TL;速度三角形定位法(dead reckoning)

下面是基本公式的完全通用的变化:

B = P * A * inverse(P)

博学的读者会将这种基变换公式识别为相似变换。它可以应用于右手坐标系中的矩阵A以产生左手坐标系中的等价矩阵B。矩阵P是基变换的变化。那么到底什么是基矩阵的变化呢?如果您的目的是将值从 DirectX 转换到 OpenGL 默认坐标系,这两个坐标系在 Z 轴上相差-1 的比例,那么基矩阵的变化就是这些坐标系之间的转换:

P = [[ 1  0  0  0]
     [ 0  1  0  0]
     [ 0  0 -1  0]
     [ 0  0  0  1]]

这个矩阵有一个特殊的性质,就是它是对合(在求逆下不变)。还要注意,用这种基变换矩阵改变基公式只会导致六次不同的乘法。为了使解决方案完全具体化,下面是使用 Unity Engine API 的 C#实现:

Matrix4x4 ChangeBasis(Matrix4x4 input) {
    var basisChange = Matrix4x4.identity; // Invert the forward vector.
    basisChange[2, 2] = -1; // Note the inverse of this matrix is the matrix itself.
    var basisChangeInverse = basisChange; // This multiply could be simplified to
    // -1 * elements [2,6,8,9,11,14], which can be simplified 
    // further; see [Eberly's proof](https://answers.unity.com/storage/temp/12048-lefthandedtorighthanded.pdf) for details.
    return basisChange * input * basisChangeInverse;
}Vector3 ChangeBasis(Vector3 point) {
    UnityEngine.Matrix4x4 mat = UnityEngine.Matrix4x4.identity;
    mat[2, 2] = -1;
    return mat.MultiplyPoint3x4(point);
}

因此,对于矢量、变换、相机和灯光,你有了一个完全通用和对称的解决方案。请注意,更改整个资源的基础意味着转换点、变换、法线、切线和所有辅助数据(例如,作为着色器参数的方向向量)。这不是一个小任务。如果资源是动画的,您可能也需要每帧都这样做。

你可能会问自己,“但是我不能通过使用一个奇怪的技巧来避免所有这些乘法吗?”是的,但这实际上是两个技巧,而且是有代价的;但在进入技巧之前,让我们首先同意改变基础是正确的一般解决方案。

寻找火焰

任何需要在 DirectX 和 OpenGL 之间交换数据的人都感受到了需要在两个坐标系之间转换基础的痛苦。在找到完全通用的解决方案之前,我花了太多的时间寻找错误的解决方案,其中我试图简单地反转所有值的 Z 坐标。在检查位置时,这似乎是正确的,但是它没有考虑到旋转和转向。为了理解为什么这是不正确的,看一下一个矩阵的基的适当改变的效果是有帮助的:

[[ 1  0  0  0]      [[1 1 1 1]    [[1  0  0  0]     [[ 1  1 **-1**  1]
 [ 0  1  0  0]   x   [1 1 1 1]  x  [0  1  0  0]  =   [ 1  1 **-1**  1]
 [ 0  0 -1  0]       [1 1 1 1]     [0  0 -1  0]      [**-1 -1**  1 **-1**]
 [ 0  0  0  1]]      [1 1 1 1]]    [0  0  0  1]]     [ 1  1 **-1**  1]]

哦嗨,不止是 Z 翻译颠倒了!我们现在看到了我上面提到的六次乘法,很明显,这并不等同于 Z 乘以-1,但是为什么这个解是正确的呢?

也许你也偶然发现了大卫·埃伯利的这篇文章。虽然合乎逻辑,看似正确,并且只需要在三种特殊情况下进行四次矩阵乘法,但我很难看出它是如何推广的,我不想在没有真正理解我在做什么的情况下盲目应用该公式。

从线性代数中,我知道我真正想要的是执行基的变换,所以我开始为而不是寻找一些数学基础。我最终发现的是教科书中对基础变化的定义。

相似变换

在维基百科上,你会发现上面的公式,但是伴随着一个比艾伯利的更难以理解的描述。这种转变的基础实际上很容易计算和理解,但很难解释,所以在这里,我将引导您观看关于基础变化的 3Blue1Brown 视频。他在视频开始 11 分钟后到达相似性转换。

好了,现在我们都同意基的变化公式是完全通用的,完全正确的,让我们变得怪异。

一个奇怪的技巧:部分改变基础

我不喜欢这种转换需要每次转换两次矩阵乘法(模优化),并且必须应用于资产中的每个点、转换和法向(等等);同样,这对于动画来说可能特别慢——所以我们不能避免它吗?互联网的知识会告诉你,“不,这是无法避免的,忍着吧”,但这并不完全正确,假设你对一些警告感到满意。

让我们想一想基变换的变化是如何在我们的数据中体现出来的。假设我们有一个应用于顶点位置的变换链。在真实资产中,我们有大量的其他数据,但这种有限的世界观足以说明这个想法。我们的目标是将一个点从物体空间转换到世界空间。假设 T0..T2 是 4x4 矩阵变换,V 是要变换的 4x1 向量位置,当应用完全通用的基变换时,我们的矩阵乘法看起来像这样:

V' = P * T0 * inverse(P)
   * P * T1 * inverse(P)
   * P * T2 * inverse(P)
   * P * V

所有这些矩阵乘法看起来非常多余,难道我们不能在一个中间空间中操作,只在完成后应用转换吗?是的,但是我们希望避免在系统中的每个着色器中显式地编写这些代码。相反,我们利用了这样一个事实,即我们知道在一致的空间中有一个连续的子图(即一个输出对话步骤就足够了)。

V' = P * T0
       * T1
       * T2 * V

这是一个巨大的工作量减少!只有根变换需要转换,所有其他数据都可以保留在其原生坐标空间中。这行得通,因为 T0..T2 和 V 在同一个坐标系中,所以旋转按预期进行。此外,最终的输出转换 P 正确地转换了结果点,因为根据定义,它不能是旋转(它只是一个位置)。最后,摄像机位于 P 输出的空间中,因此结果场景看起来是正确的。那么有什么问题呢?

如果我们在包含相机变换时应用这个技巧,相机必须完全转换,或者我们将最终顶点值留在不同的坐标空间中,而不是通过这个相机查看它时它开始的位置。然而,为了将所有场景数据保持在一致的坐标空间中,我们可以改为通过相机的视图变换来完成基变换的部分改变:

C' = C * inverse(P)

现在,当我们在右手坐标系中渲染左手相机和数据时(例如),典型的相机空间变换将导致正确的最终相似性变换,如下所示:

CameraSpaceV = (view) * (model) * (vertex)
             = C * T0 * T1 * T2 * V
             = inverse(P) * C * P * T0 * T1 * T2 * V
             = **P * C * inverse(P)** * T0 * T1 * T2 * V

现在我们有两个奇怪的把戏:)

最终结果是将输入资产数据的 O(N)次矩阵乘法减少到 O(1)。

警告选择器

实际上有几个值得一提的注意事项:

  1. 导入时,这会将原始矩阵和顶点数据留在另一个坐标系中。任何手动检查这些数据的人可能会对他们所看到的与数据的值相比较而感到困惑。
  2. 根变换将包含负比例。简单的矩阵分解算法将无法正确处理这种情况,并且会将缩放转换为旋转。当分解一个矩阵时,有可能检测到基标度的这种变化并正确地处理它。
  3. 如果您正在操作直接应用于视图转换的矩阵数据,这个技巧将需要额外的修复。

结论

最重要的是,我希望这个完全通用的解决方案对任何在互联网上寻找快速解决方案的人都有帮助。其次,我希望指出所有数据都必须转换的事实揭示了这样一个推论,即它实际上充满了危险,并且“一个奇怪的把戏”/部分改变基础的警告在某些情况下可能实际上更可取,不仅是为了性能,而且是为了正确性。

有目的的改变:为什么我决定加入 Neva

原文:https://towardsdatascience.com/change-with-purpose-why-i-decided-to-join-neva-8b80d9c1950a?source=collection_archive---------10-----------------------

新的道路,同样的使命

在加入 Neva 之前,我是 IDC 客户端虚拟化和 IT 服务管理软件研究实践的首席分析师。在这个职位上,我有机会也有特权与一些世界上最大的企业以及中小型企业的无数 IT 领导进行磋商。基于这些合作,我能够为广泛的 IT 管理软件供应商和解决方案提供商提供战略市场和产品方向,帮助他们为客户提供解决具有挑战性的技术导向计划所需的工具。

在担任行业分析师之前,我花了 12 年多的时间领导多个 IT 服务管理组织。作为美国空军和公司企业的 IT 从业者以及市场研究员,我在 ITSM 行业工作了近二十年,见证了许多技术和工作场所的变革。不祥之兆是,云计算和移动计算等领域的持续进步只会加快工作场所技术和文化的变革速度。此外,快速获取和利用先进技术的能力将对每个企业当前和未来的成功产生深远的影响。

在我的分析师职业生涯中,我有幸与 Neva 的联合创始人兼首席产品官 Dan Turchin 共事并结识了他。Dan 胸怀大志,致力于推动技术创新,帮助组织实现其业务目标。这些年来,我们已经进行了许多前瞻性的对话,这些对话与授权 IT 组织推动业务价值有关。

去年 12 月,在波士顿地区的一家小咖啡店里,Dan 和我就人工智能(AI)和机器学习(ML)技术在企业中的价值进行了一次特别有趣的讨论。正是在这次会议上,我第一次了解到 Neva 以及该公司的战略重点和将人工智能和人工智能能力应用于企业服务管理的技术方法。Dan 和我都对转变企业服务的机会充满热情。

Dan 和 Neva 的 boarder 领导团队在建立交付优秀产品的优秀团队方面有着良好的记录。同样,Neva 现在雇佣了一些世界上最受尊敬的数据科学家和本体学家。因此,当有机会加入 Neva 时,我既谦卑又兴奋地成为团队和使命的一部分。

让技术驱动的企业走向成功

虽然 it 交付和支持的服务类型必须不断跟上不断发展的工作场所和技术趋势,但 IT 始终通过智能技术投资创造业务价值是至关重要的。随着 IT 组织努力扩展技术服务和支持以满足当今始终在线和始终保持联系的工作人员的需求,实现这一价值主张变得越来越困难。

ITSM 社区由充满激情的个人组成,他们不仅对自己的角色感到非常自豪,而且乐于接受持续改进。保持这些属性对于支撑一个肯定会持续动荡的环境至关重要。然而,在当今日益分散和混合的技术环境中,利用手动、繁琐的流程作为服务交付渠道根本无法扩展,甚至会极大地阻碍最敬业的支持团队。

我加入 Neva 是为了成为团队的一员,该团队的使命是提供基于人工智能和人工智能的解决方案,使组织能够实现服务自动化,并提供更加个性化和及时的支持体验。

推进目标

缺乏与业务用户的一致和可靠的合作,使得 it 组织几乎不可能正确地衡量其服务的有效性。IT 部门的跟不上是助长影子 IT 等趋势的原因,影子 IT 往往会影响生产力、安全性和业务连续性。

幸运的是,服务管理平台供应商并没有忽视这些挑战。例如,ITSM 解决方案在用户界面设计、服务目录和自助服务功能方面取得了显著进步。这些创新使得 ITSM 产品和最佳实践得到了更广泛的采用,使 IT 部门能够从技术消费和需求方面积累大量有关最终用户偏好、优先事项和实践的数据。此外,ITSM 平台越来越多地被开发和用于支持 IT 部门以外的业务部门,如人力资源、设施、客户服务等。

因此,IT 和商业领袖都在密切关注人工智能和人工智能技术,因为它迅速发展到这样一种状态,即自主代理可以有效地利用服务管理平台以及其他记录系统中的数据来维持与客户的信息丰富、互动、智能的对话。此外,AI 和 ML 驱动的自动化支持服务组织增加其支持功能的规模,提高服务质量,同时降低运营成本。

有目的地拥抱变化

“用提议改变”始于保持对核心原则的坚定承诺,同时继续保持足够的灵感和好奇心来拥抱确保目标实现的新方法。

是什么促使我决定加入 Neva?首先也是最重要的,我认为这一举动是继续做有意义的工作,实现我长期以来帮助服务和支持组织向客户提供一流体验的热情。知道 Neva 的愿景与这一目标一致是我决定的关键部分。

虽然基于人工智能和机器学习的服务管理可能看起来大胆而有远见,但我相信这是未来十年推动创新的方式。因此,加入一家正在定义企业服务未来并让组织能够提供吸引人和令人愉快的客户体验的公司,我感到无比兴奋。

我们需要混沌来保持机器学习的智能

原文:https://towardsdatascience.com/chaos-is-needed-to-keep-us-smart-with-machine-learning-217cb8179fa3?source=collection_archive---------13-----------------------

我喜欢机器学习如何进入我们的生活,以及它如何使与技术的交互比以前更加清晰和自然。我喜欢 you tube 根据我以前看过的视频向我推荐我下一个要看的视频。我喜欢谷歌地图知道我想早上 6 点去练瑜伽,9 点去上班。我喜欢我不需要按照字母顺序浏览网飞的电影列表,但它知道我最喜欢哪一部。我喜欢基于机器学习的软件预测、学习、推荐和自我纠正的能力。随着我们与这些后台算法的互动越来越多,它们会变得更好,为我们提供量身定制的产品。这就像走进一家餐馆,没有我的要求,就有一套根据我的口味定制的入围菜肴。等等,我们已经有了,对吗?

我们喜欢科技的这个角度是因为它让我们的生活变得更容易。它减少了删除那些我们不感兴趣的信息的痛苦,这些信息在我们看来是噪音。对我来说是噪音的东西,对你来说可能不是噪音,因此机器学习正在以一种相对的方式从我们的生活中消除噪音。“相对降噪”有助于我们更加信任人工智能(AI)。由于人工智能的力量,技术采用的加速是一个自我维持的循环:通过增加我们对技术的信任,我们更多地使用它,这进一步改进了技术。一旦我们信任技术,我们就允许它给我们建议,与我们竞争,帮助我们,教育我们。我们引导自己让人工智能学习我们的口味,并在此基础上更进一步。

人工智能的“相对降噪”范式正在减少你在与技术互动中看到的离群值。然而,你看不到的噪音在某种程度上缩小了你的边界。作为一名数据科学家,我很高兴看到我的算法实现了高精度的预测,并很好地推荐和自我修正。但是这些算法从他们所看到的事物中学习,这些事物与历史完全或部分相似。他们没有也不可能提出我的大脑在探索过程中会提出的东西,而没有任何证据表明我对历史有明显的兴趣。这给我们带来了人工智能的“副作用”——无意识地削减创造力。我有看天文相关纪录片的兴趣,谷歌、脸书、Instagram、YouTube、LinkedIn 甚至 Pinterest 似乎都意识到了这一点。然而,不知何故,一个连锁反应引发了我对天文学的海量资源。我们如何让人工智能技术的用户通过偶尔向他们展示一些完全出乎意料的东西来拓宽他们的视野?我们如何确保人性和学习能力的力量嵌入到我们设计的建议中?这种哲学中似乎有一种固有的观念,即你必须是“一门手艺的主人”。我更喜欢做“万金油”。

我们在生活中捕捉的混乱是很重要的。这在接触知识资源时尤为重要。虽然通过协同过滤等算法的机器学习建议为用户提供了它认为有用的定制曝光,但同时,它们也给噪音添加了一种结构,随着时间的推移,噪音被完全消除。一旦我们没有接触到嘈杂的推荐,我们接触的外围就被历史所束缚。因此,重要的是,通过数据科学或以“量身定制的解决方案”为借口有选择地暴露内容的推荐范式足够嘈杂,以确保我们拥抱人类天生的创造力。当你在你的数据中发现一个异常值时,常识是把它当作稀罕物,不要据此得出结论,但是异常值包含有价值的信息。我们的算法应该从历史中的离群值中学习,我们以数据清理为借口忽略的每个尖峰都需要成为机器学习过程中最有价值的创造性元素。在真正意义上,这将是机器像人类一样“学习”的范例。

参考资料:

https://greatperformersacademy . com/books/4-我们从局外人身上学到的关键经验-成功的故事

https://towards data science . com/a-brief-overview-of-outlier-detection-techniques-1e 0 b 2c 19 e 561

第四章:Azure Batch HPC,20 秒学习 2000 万收视率

原文:https://towardsdatascience.com/chapter-4-azure-batch-hpc-learning-20-million-ratings-in-20-seconds-980a7fa50d51?source=collection_archive---------8-----------------------

这个故事是系列“ 你真正需要什么来设计一个真正的推荐引擎(与 Azure)的一部分

**

“随着 NVIDIA GRID 软件和 NVIDIA Tesla M60 在 Azure 上运行,微软正在提供基于云的 RDSH 虚拟应用和桌面的优势,以在云中实现大规模图形加速虚拟化,满足任何企业的需求”NVIDIA GRID 副总裁 John Fanelli

领先的微软和英伟达合作伙伴关系

自去年第四季度以来,图形处理单元(GPU)开始在微软的云上普遍可用,并逐渐在亚马逊和谷歌等并发提供商的平台上可用。数字市场上机器学习(ML)需求的显著增长和游戏行业广泛加速的 GPU 快速民主化,有利于实际领导者 Nvidia 和主要云参与者之间的排他性合作伙伴关系。推动基于按使用付费模式提出硬件而不是实际获得高性能代码(HPC)基础设施硬件的成功战略,微软向一个新市场开放,从 3D 建模、远程游戏到科学研究应用。如今,这一领域的活动如此频繁,以至于供应商有时甚至很难满足客户的需求。随着新的最快的 GPU 以越来越快的速度上市,这种情况注定会升级。

随着这些内容的编写,微软提出了 NC 系列专用虚拟机,旨在通过单个或多个 GPU 进行繁重的图形渲染和视频编辑。后者采用 NVIDIA Tesla 加速平台和 NVIDIA GRID 2.0 技术,提供当今云中可用的最高端图形支持。

有了这样唾手可得的能力,不尝试一下并采用推荐引擎(RE)领域中计算量特别大的著名算法是不合理的。

基于协同过滤的推荐器

在广泛的 RE 领域中,协同过滤(CF)是一个特定的领域,其中通过在大量人群中发现用户的行为模式来预测评级。主要原则依赖于找到具有相似评级习惯的用户,并推荐彼此集合中仍然缺少的项目。虽然不像社交网络过滤(SNF)那样容易受到恶意攻击,但 CF 的主要警告在于,在产生任何好的推荐之前,许多用户必须已经提供了他们的评级。这个问题严重限制了 CF 在系统刚刚启动的场景中的实用性。

主要是因为这个原因,现代 RE 提出了不同的混合方法,旨在缓解被称为冷启动效应的相关问题、长尾非平凡推荐、提高的准确性以及提供为什么推荐一个项目的清楚解释。另一方面,CF 有很大的优势,可以给推荐带来惊喜,并向主题打开用户档案,这是基于语义过滤(SF)的推荐器所没有的。

一种强有力的方法:奇异值分解

虽然仅仅依靠 CF 来设计 RE 是不明智的,但是一些方法,例如奇异值分解(SVD ),在自动发现没有被项目或用户明确定义的潜在特征方面提供了特别有效的好处。在适当的条件下,仅这个属性就可以产生基于抽象概念的优秀推荐,这些抽象概念不能从它们的特征直接清楚地解释,但是从数学的角度来看是完全有效的。因此,有可能发现令人惊讶的用户群共享一些概念,例如特定的电影氛围、其隐含的目标观众、政治方面或者仅仅是任何语义描述中可能不包含的类型。

SVD 背后的线性代数旨在通过仅提取最重要的特征值同时最小化相关损失函数来找到矩阵的低秩表示。它作为一种破坏性的图像压缩方法,在图像处理中得到广泛应用。在 CF 的情况下,这是通过分别包含用户特征向量、特征值和电影特征向量的三个矩阵的因式分解来实现的。

一个有用的案例研究:预测电影收视率

因为人人都爱电影……芝加哥国际电影节

MovieLens 20M 四联数据集的情况下,评级矩阵提出了极其稀疏的额外挑战,因为每个用户只对所有可能项目中的一小部分进行评级。有 27,000 部电影和 138,000 个用户,尽管已经产生的数据集仅占整个矩阵的 0.53%。

使用[R]进行的快速分析还揭示了总体评分的偏态正态分布(全球平均值为 3.423)以及学术门户网站活动期间的用户评分趋势。

编写 SVD 的第一个串行版本

虽然本文的目标是探索设计现代可扩展的基于 Azure 的 re 的真正解决方案,而不是一门关于机器学习或统计学的课程,但准确地说,下面介绍的所有实验都基于完全相同的设置仍然是有用的。首先,总体平均值、用户平均值、电影平均值、方差、标准偏差和收视率统计,使用以下在线算法进行增量计算:

第二,通过随机选择 20%的用户简档评级作为“维持”交叉验证测试集,将数据集一分为二,剩余的 80%保留用于模型的训练。

令人惊讶的是,现在仍然很少找到用于 re 的 SVD 的良好实现,据我所知,Spark 或其他可扩展的生态系统都没有提出任何可直接使用的预先编写的模型。此外,让我们诚实地说,在设计新系统时,对算法实际上是如何工作的,它可能的实现和含义有一个完美的理解通常是一个更好的想法。特别是 SVD 是一个广泛的模型,有许多不同的版本,尤其是在可伸缩性和并行性有问题的时候。此外,在 RE 的情况下,通常不使用实 SVD,而是使用一种称为最大间隔矩阵分解(MMMF)的变体,其最简单的表达式如下:

因此,本文中使用的初始版本是用 C#从头开始编写的,并通过 MMMF 的双凸属性优化了模型,其中用户和电影功能是同时学习的。

为可扩展性而设计

休斯顿,我们有一个问题…,阿波罗 13 号,1995

当谈到并行化诸如 SVD 之类的算法以便能够吸收近乎无限的增长时,有几种可能的方法。第一种方法旨在通过将整个矩阵分割成更小的块并独立学习它们来减少工作量。虽然理论上是正确的,但是这种依赖于创建子时期和权重同步的“分而治之”策略不太适合 RE 的情况,并且可能仅与几个太字节和更密集矩阵的巨大数据集相关。

尽管具有良好的可扩展性,但传输数据所花费的时间大大超过了计算收益,并且因为块不是随机采样的,所以评级明显较低的块比其他块计算得更快,最终导致几个节点无所事事,等待其同系物完成。

另一种策略是简单地在多核机器上执行计算,从而摆脱数据传输瓶颈。不幸的是,即使在摩尔定律的帮助下,将单台计算机的性能提升到期望的水平仍然很少或不可能。在最好的情况下,商用硬件可以达到 8 或 16 个内核,然后有义务将部分工作委托给另一个节点,并再次陷入数据传输的复杂性。尽管如此,对这样一个解决方案进行基准测试,以便了解它与其他选项相比的最大性能,仍然很有意思。为此,我们编写了一个并行但不可伸缩的 SVD C #版本,并在后面章节中进一步介绍的基准测试中使用。

利用大规模并行架构

《钢铁侠 2008》托尼·斯塔克

正如本文标题所暗示的,GPU 和大规模并行架构很可能为我们的可伸缩性和并行化问题提供解决方案。首先,GPU 可以通过其单指令/多数据(SIMD)架构提议数千个内核来处理庞大的数据集。其次,它们的高速内存在一个齿轮上可以达到十分之几 GiB,最好的超级计算机可以并行安装多个互通卡。因此,毫无疑问,在 GPU 上部署 RE 的 SVD 等算法的潜在结果可以极大地受益于这些质量,并立即解决上述所有问题。尤其是因为在最好的情况下,用户和电影数量不太可能超过几十亿…

QuantAlea GPU:瑞士领导者

因为好消息很少是单独出现的,最近在著名的微软 9 频道电视上运行的技术情报报告说,位于苏黎世的一家瑞士公司正在提供一个框架,该框架能够从任何地方透明地编译所需的 CUDA 代码。网语。据我所知,QuantAlea 是唯一的专业人士。Net 框架提议直接访问所有的 NVIDIA GPU 功能。知道了用繁琐的 Boost 库和 CUDA 开发工具包创建 C++项目的开销,这种新的可能性是一种不可否认的生产率提高,并且只要使用非企业 GPU 就可以免费使用。

大规模并行化 SVD 算法

“权力越大,责任越大。”蜘蛛侠 2002

为了获得令人满意的结果,很好地理解在图形处理单元(GPGPU)上提供通用处理的大规模并行架构非常重要。用 QuantAlea 框架直接转换现有代码会产生欺骗性的结果,并导致错误的结论,即只能获得最小的速度增益。下图简洁地描述了如何利用可支配的能力,并可能给出一两个想法,为什么这种实现仍然不是这种架构的最佳可能情况。

其他算法,如人工神经网络,更适合于非常技术性的方面,如共享内存。然而,在 GPU 上如何学习 SVD 模型的随机性质具有间接的好处,可以更好地模拟其理论属性,并避免在第一个用户配置文件上过度拟合,因为在单线程版本上就是这种情况。

试驾和结果

由于本文作者尚未拥有能够在速度方面展示最佳可能结果的超级计算机,因此使用了具有以下规格的高端戴尔外星人笔记本电脑作为上述所有版本的基准。

  • 处理器:英特尔酷睿 i7–6700 HQ CPU,2.60GHz,8 个逻辑内核
  • 内存:16 GiB
  • GPU:NVIDIA GeForce GTX 1060–1280 CUDA 内核— 6 GiB GDDR5

下面的图表显示了训练一个唯一 SVD 历元需要多少秒。有了现成的硬件,GPU 版本比原始版本快 12 倍,比多核版本快近 4 倍。

对于 SVD 的整个训练,可以注意到 GPU 实现比其并发运行更多的时期,尽管具有完全相同的参数。这实际上是一件好事,符合上面讨论的统计特性。训练一个 SVD 是一个随机的过程,最终只能用大规模分布式架构来正确模拟。即使有更多的迭代,总的训练时间仍然远远低于具有更好准确性的原始最佳版本。

但是 Azure 产品怎么样呢?

“医学博士?分子脱离装置。我们叫她‘小博士’。”2013 年《安德的游戏》

在 today Azure 产品上运行相同的实验将允许使用不少于 4992 个内核的 Tesla K80。但新的特斯拉 P100 已经宣布上市,并将推动任何 HPC 应用程序的理论上的 2tb 全局内存的极限。从用户的角度来看,一张约 10,000 美元的卡肯定会受益于按使用付费计划…

使用 Azure Batch 运行 HPC SVD 算法

在上一篇文章“Azure Machine Learning:Not Your 平常的回归”中,Azure Machine Learning 满足了大多数基础设施需求。在当前情况下,SVD 算法比用于拟合独立用户简档的弹性网络回归大得多。因此,我们需要一个更复杂的架构基础设施,使用 Azure Batch 来训练模型,使用独立可扩展的 Azure WebApp 来提供个性化预测。此外,必须建立排队机制,以要求推荐者安全地处理所需的工作流步骤。同样重要的是要注意,没有提到当对他们的评级进行改变时,如何递增地重新训练简档。这种操作通常被称为“折叠”,超出了本文的范围。

另一个非常重要的点是将已经相当可观的 2000 万收视率数据集传输到计算集群所需的时间。在现实世界中,从磁盘数据存储器中一个等级接一个等级地重复执行这种操作通常是不切实际的。后者需要大规模扩展,才能达到与 Event Hub 相当的性能,后者是该领域最快的解决方案。因此,不是沿着这条路走下去,而是将包含所有评级的映射文件上传到单个 blob,并由集群的每个节点直接下载。第一个数据集可以被看作是一个种子,最终可以存储在分布式内存服务中,比如 Redis Cache。因此,相对于云架构提供了最大可能的速度。唯一的另一种选择是使用 Spark 弹性分布式数据集(RDD),但由于不需要所有的转换机制,这个解决方案暂时被搁置一边。

最后,人们可以想象每天从内存中非常快速地重新计算整个数据集,或者创建一个新版本的算法,允许稳定的增量学习,非常像第一章中介绍的与在线计算均值和方差相关的简单方程。

设置 Azure Batch HPC 集群

依我拙见,Azure Batch 是 Azure 的一个很好的未被充分利用的服务,直接经历了 Hadoop MapReduce 当前的流行,没有特别的技术原因。Azure Batch API 易于使用,并通过 C#代码或简单的 Powershell 命令实现自动化。该门户还提供了大多数功能,但应该仅用于实际监控已部署的虚拟机和正在运行的作业,因为它缺乏任何可编程的可操作性。

出于演示目的,部署了一个包含四个虚拟机(VM)的简单集群,采用标准计划。这些节点中的每一个都被要求用特定的参数训练一个版本的 SVD,以便快速找到满意的组合。推进这一方面将导致实现完全并行的遗传算法(GA ),以达到接近最优的解决方案。当参数的数量变得很重要时,手工处理这项任务变得很困难。

创造有意义的工作

Azure Batch 的众多出色特性之一在于可以在作业中定义任务依赖关系,从而提供了等待一组操作完成后再继续的能力。每次任务启动时,它都会下载一个应用程序包和评级数据集。下图显示了为实验选择的实际树:

集群中总共有 4 个节点同时运行一个多线程任务。每当一个任务完成时,它将获得的最佳 RMSE 和相应的参数存储在一个 blob 中,允许下一个任务从获得的结果开始并进一步优化。

出于实际原因,最终使用了 SVD 算法的多核版本。QuantAlea GPU 在企业级 GPU 上使用他们的框架每年收费 2000 美元,显然超出了目前的概念验证预算。

监控培训

同样,Azure 的用户体验非常好。可以在门户上直接监控不同节点的活动。

此外,Azure Batch blade 允许探索每个节点,并最终使用远程桌面会话主机(RDSH)直接登录相应的虚拟机,以调查最终的问题或获得更精确的遥测数据。

最后,通过观察下面显示的高偏差/高方差指标,获得了最佳 RMSE,从而成功地结束了这一真实场景。

结论和进一步的思考

从微软文化的角度来看,很高兴看到 Azure 在可伸缩应用领域的良好竞争力,这个领域主要由 Apache Unix / Java 项目主导。尽管如此,人们还是可以从这家企业的产品中看到更多的创新。为了实现这一目标,MS 技术必须找到一种在相关领域中被更广泛采用和欢迎的方法。如果提出了好的解决方案,没有理由不这样做,因为部署在生产中的系统从今天的 ms 技术中获得了真正的生产力提升。

Azure Batch 是一个很好的服务,肯定会从更好地向公众展示中受益。在人工智能非常中介和有用的时期,一个关于在 Cortana 智能诉讼中拥有相当于火花 RDD 的可能性的解决方案将是非常诱人的。同样,来自金融行业的 QuantAlea GPU 等计划无疑正朝着正确的方向发展,以缓解该领域对 MS 的接受。

现在众所周知,许多企业和云供应商正在他们的产品中提出机器学习功能。通常的营销信息表明,每个应用程序都可以很容易地集成 ML 功能。但这一格言往往不符合所涉及的实际理论和技术复杂性、可能性的多样性和技术的快速发展,特别是对于最先进的情况。操作数据科学很难,如果从错误的角度着手,很容易适得其反。

关于 RE 领域,构建甚至正确使用推荐器仍然是一项具有挑战性的工作。所需的经验和洞察力最终形成了一个共同的文化背景,整个社区自然地聚集在一起,就像在 Netflix 奖挑战赛期间创造的一样。虽然有些学科确实被缩小到特定的科学领域,但它们对大多数人来说是有用的、广泛的、现代的、受欢迎的和与商业相关的,并且无疑将在未来的几十年里继续逐步融入我们的日常生活。

来源

带 Keras 的字符级 CNN

原文:https://towardsdatascience.com/character-level-cnn-with-keras-50391c3adf33?source=collection_archive---------4-----------------------

在这本笔记本中,我们将使用 Keras 构建一个角色级别的 CNN 模型。可以在本文中找到模型细节:用于文本分类的字符级卷积网络

文章的其余部分组织如下。

  • 模型介绍
  • 为什么是这种模式?
  • 预处理
  • 负载嵌入重量
  • 模型构建
  • 培养

车型简介

模型结构:

这个图表可能看起来很难理解。这是模型设置。

如果你想看这个模型的细节,请移动到这个笔记本

我们选择小帧,卷积层 256 个滤波器,密集层 1024 个输出单元。

  • 嵌入层
  • 6 个卷积层,3 个卷积层,然后是最大池层
  • 两个完全连接的层(keras 中的致密层),神经元单位是 1024 个。
  • 输出层(密集层),神经元单位取决于类。在这个任务中,我们将它设置为 4。

为什么是这种模式?

在 Kim 提出用于句子分类的卷积神经网络之后,我们知道 CNN 可以在 NLP 任务中有很好的表现。我也实现了这个模型,如果你有一些兴趣,你可以在这里找到细节: cnn-text-classification 。但是在这个模型中,它是从词的层面来取句子特征的,这就造成了 无词汇()的问题。

为了处理 OOV 问题,人们提出了许多方法。这个人物级别的 CNN 模型就是其中之一。顾名思义,这个模型在字符层次上处理句子。通过这种方式,可以在很大程度上减少未登录词,使 CNN 能够提取模式特征,提高文本分类性能。

预处理

这里为了简单起见,我将所有预处理代码写在一起。如果你对预处理步骤中发生的事情感兴趣,请移至这里:如何用 Keras 预处理字符级文本

负载嵌入重量

为了理解如何给嵌入层分配嵌入权重,这里我们手动初始化嵌入权重,而不是随机初始化。

首先,我们要确认我们的词汇量有多少。

我们可以看到,除了 68 个字符之外,我们还有一个UNK(未知令牌)来表示词汇中的稀有字符。

然后我们用一热向量来表示这 69 个单词,也就是说每个字符有 69 个维度。因为 Keras 使用 0 表示填充,所以我们添加一个零向量来表示填充。

现在,这个句子由索引来表示。例如,I love NLP被表示为[9, 12, 15, 22, 5, 14, 12, 16]。第一个索引9对应的是embedding_weights[9],它是字符I的向量。

在我们得到这个嵌入权重之后,我们应该通过它来初始化嵌入层。

模型构建

首先,我们给出了参数设置。

然后,我们按照设置所说的那样构建模型。

model.summary()的输出

培养

我们的目标是学习如何构造模型,所以这里我只是用 CPU 来运行模型,只用 1000 个样本进行训练,100 个样本进行测试。由于数据集较小,该模型容易过拟合。

将所有代码汇总在一起。

这篇文章的笔记本这里是,整个剧本这里是**。预处理条是 这里是****

我创建了一个存储库来存放我作为初学者学习 NLP 时的工作。如果你觉得有用,请启动这个项目。我很高兴听到反馈或建议。
NLP-初学者-指南-keras

查看我的其他帖子 一个分类查看
GitHub:
bramble Xu LinkedIn:徐亮 博客:bramble Xu

字符级语言模型

原文:https://towardsdatascience.com/character-level-language-model-1439f5dd87fe?source=collection_archive---------1-----------------------

Iphone’s text suggestion

简介

你有没有想过 Gmail 自动回复是如何工作的?或者你的手机在发短信时如何提示下一个单词?或者甚至神经网络是如何生成音符的?生成文本序列的一般方法是训练一个模型,在给定所有先前单词/字符的情况下预测下一个单词/字符。这样的模型被称为统计语言模型。什么是统计语言模型?统计语言模型试图捕捉它所训练的训练文本的统计结构(潜在空间)。通常使用递归神经网络(RNN) 模型族来训练模型,因为它们非常强大且具有表现力,通过它们的高维隐藏状态单元来记忆和处理过去的信息。任何语言模型的主要目标都是学习训练文本中字符/单词序列的联合概率分布,即试图学习联合概率函数。例如,如果我们试图预测一个由 T 个单词组成的序列,我们试图得到尽可能大的联合概率 P(w_1,w_2,…,w_T) ,它等于所有条件概率∏ P(w_t/w_{t-1}) 在所有时间步(T)的乘积。

在这篇文章中,我们将讨论字符级语言模型,其中几乎所有的概念都适用于任何其他语言模型,比如单词语言模型。字符级语言模型的主要任务是在给定数据序列中所有先前字符的情况下预测下一个字符,即逐字符生成文本。更正式地说,给定一个训练序列(x,…,x^T),RNN 使用其输出向量(o,…,oT)的序列来获得预测分布序列*p(xt/x^{t-1})**= softmax(o^t)*。

让我们以我的名字(“imad”)为例来说明字符级语言模型是如何工作的(这个例子的所有细节见图 1)。

  1. 我们首先构建一个词汇字典,使用语料库中名称的所有唯一字母作为关键字,每个字母的索引从零开始(因为 Python 是一种零索引语言)以升序排列。对于我们的例子,词汇字典应该是:{"a": 0," d": 1," i": 2," m": 3}。因此,“imad”将成为以下整数的列表:[2,3,0,1]。
  2. 使用词汇字典将输入和输出字符转换成整数列表。在这篇文章中,我们假设所有的例子都是 x = \vec{0}。因此, y = "imad" 和 x = \vec{0}\ + "ima" 。换句话说, x^{t + 1} = y^t 这就给了我们: y = [2,3,0,1]x = [\vec{0},2,3,0]
  3. 对于输入中的每个字符:
  4. 将输入字符转换成一键向量。注意第一个字符是:零矢量
  5. 计算隐藏状态层。
  6. 计算输出图层,然后将其通过 softmax 以概率形式获得结果。
  7. 将时间步(t)的目标字符作为时间步 (t + 1) 的输入字符。
  8. 回到步骤 A 并重复,直到我们完成名称中的所有字母。

目标是在概率分布层中使绿色数字尽可能大,红色数字尽可能小。原因是,通过使其尽可能接近 1,真实指数应该具有最高的概率。这样做的方法是使用交叉熵来测量损失,然后计算损失相对于所有参数的梯度,以在梯度方向的相反方向上更新它们。多次重复该过程,其中每次我们基于梯度方向调整参数–>模型将能够使用训练文本中的所有名称,在给定所有先前字符的情况下,正确地预测接下来的字符。请注意,隐藏状态\(h⁴\)有所有字符的所有过去的信息。

Figure 1: Illustrative example of character-level language model using RNN

:为了缩短帖子的长度,我删除了所有 python 函数的 docstrings,也没有包括一些我认为对理解主要概念没有必要的函数。创建这个帖子的笔记本和脚本可以在这里这里找到。

培养

我们将使用的数据集有 5163 个名字:4275 个男性名字,1219 个女性名字,331 个既可以是女性名字也可以是男性名字。我们将用来训练字符级语言模型的 RNN 架构被称为多对多,其中输入的时间步长 T_x =输出的时间步长 T_y 。换句话说,输入和输出的序列是同步的(见图 2)。

Figure 2: RNN architecture: many to many

字符级语言模型将在名字上进行训练;这意味着在我们训练完模型之后,我们将能够生成一些有趣的名字:)。

在这一部分,我们将讨论四个主要部分:

  1. 正向传播。
  2. 反向传播。
  3. 取样。
  4. 拟合模型。

正向传播

我们将使用随机梯度下降法(SGD ),其中每批只包含一个样本。换句话说,RNN 模型将分别从每个示例(名称)中学习,即,对每个示例运行向前和向后传递,并相应地更新参数。以下是向前传球所需的所有步骤:

  • 使用唯一的小写字母创建一个词汇词典。
  • 创建一个字符索引字典,将每个字符按升序映射到其对应的索引。例如,“a”的索引为 1(因为 python 是一种零索引语言,我们将为 EOS“\ n”保留 0 索引),而“z”的索引为 26。我们将使用这个字典将名字转换成整数列表,其中每个字母将被表示为一个 hot vector。
  • 创建将索引映射到字符的字符索引字典。该字典将用于将 RNN 模型的输出转换成字符,这些字符将被翻译成名称。
  • 初始化参数:权重将被初始化为来自标准正态分布的小随机数,以打破对称性,并确保不同的隐藏单元学习不同的东西。另一方面,偏差将被初始化为零。
  • W_hh :连接先前隐藏状态 h^{t — 1} 到当前隐藏状态 h^t 的权重矩阵。
  • W_xh :连接输入 x^t 到隐藏状态 h^t 的权重矩阵。
  • b :隐藏状态偏置向量。
  • W_hy :连接隐藏状态 h^t 到输出 o^t 的权重矩阵。
  • c :输出偏置矢量。
  • 将输入 x^t 和输出 y^t 各转换成一个热点向量。独热向量的维数是 vocab_size x 1。除了字母在(t)处的索引是 1 之外,其他都是 0。在我们的例子中, x^t 将与 y^t 一样向左移动,其中 x = \ vec { 0 };然而,从开始 t = 2x^{t + 1} = y^t 。比如我们用“imad”作为输入,那么 y = [3,4,1,2,0]而 x = [\vec{0},3,4,1,2]。请注意,x = \vec{0}而不是索引 0。此外,我们使用“\n”作为每个名字的 EOS(句尾/名字),这样 RNN 就可以像学习其他字符一样学习“\n”。这将有助于网络了解何时停止生成字符。因此,所有名称的最后一个目标字符将是代表名称结尾的“\n”。
  • 使用以下公式计算隐藏状态:

注意,我们使用双曲正切作为非线性函数。双曲正切函数的主要优点之一是它类似于恒等函数。

  • 使用以下公式计算输出图层:

  • 通过 softmax 层传递输出,以标准化输出,使我们能够将其表示为概率,即所有输出将介于 0 和 1 之间,总和为 1。下面是 softmax 公式:

softmax 层与输出层具有相同的维度,即 vocab_size x 1。结果, y^t[i] 是索引 i 在时间步(t)成为下一个字符的概率。

  • 如前所述,字符级语言模型的目标是最小化训练序列的负对数似然性。因此,时间步长(t)的损失函数和所有时间步长的总损失为:

由于我们将使用 SGD,损失将是嘈杂的,有许多振荡,因此使用指数加权平均平滑损失是一个好的做法。

  • 将目标角色 y^t 作为下一个输入 x^{t + 1} 传递,直到我们完成序列。

反向传播

对于基于 RNN 的模型,将使用的基于梯度的技术被称为通过时间的反向传播(BPTT) 。我们从最后一个时间步\(T\)开始,对所有时间步的所有参数进行反向传播损失函数,并将它们相加(见图 3)。

Figure 3: Backpropagation Through Time (BPTT)

此外,由于已知 rnn 具有陡峭的悬崖(在 L 中突然急剧下降),梯度可能会超过最小值,并取消许多已完成的工作,即使我们使用 RMSProp 等自适应学习方法。原因是因为梯度是损失函数的线性近似,并且可能不会捕获比其评估点更远的信息,例如损失曲线的曲率。因此,通常的做法是将渐变裁剪到区间[-maxValue,maxValue]内。在这个练习中,我们将把渐变剪辑到区间[-5,5]内。这意味着如果坡度是> 5 或< -5,它将分别被修剪为 5 和-5。以下是计算所有时间步长下所有参数的梯度所需的所有公式。

请注意,在最后一个时间步骤 T ,我们将把 dh_next 初始化为零,因为我们无法从未来获取值。由于 SGD 可能有如此多的振荡,为了稳定每个时间步的更新,我们将使用一个自适应学习方法优化器。更具体地说,我们将使用均方根传播(RMSProp) ,它往往具有可接受的性能。

抽样

采样使得 RNN 在每个时间步生成的文本成为有趣/有创意的文本。在每一个时间步(t)上,RNN 输出给定所有前面字符的下一个字符的条件概率分布,即 P(c_t/c_1,c_2,…,c_{t-1}) 。让我们假设我们在时间步 t = 3 并且我们试图预测第三个字符,条件概率分布是:P(C3/C1,C2)=(0.2,0.3,0.4,0.1) 。我们会有两个极端:

  1. 最大熵:使用均匀概率分布随机挑选角色;这意味着词汇词典中的所有字符都有相同的可能性。因此,我们在选择下一个字符时会以最大的随机性结束,生成的文本将没有意义或听起来不真实。
  2. 最小熵:条件概率最高的字符将在每个时间步被选中。这意味着下一个字符将是模型根据训练文本和学习参数估计的正确字符。因此,生成的名称既有意义又听起来真实。然而,它也将是重复的并且不那么有趣,因为所有的参数都被优化以学习预测下一个字符的联合概率分布。

随着我们增加随机性,文本将失去局部结构;然而,随着我们降低随机性,生成的文本听起来会更真实,并开始保留其局部结构。在这个练习中,我们将从模型生成的分布中取样,这可以被视为最大和最小熵之间的中间随机水平(见图 4)。对上述分布使用这种抽样策略,指数 0 有 20% 的概率被选中,而指数 2 有 40% 的概率被选中。

Figure 4: Sampling: An example of predicting next character using character-level language model

因此,将在测试时使用采样来逐字符生成名称。

拟合模型

在涵盖了字符级语言模型背后的所有概念/直觉之后,现在我们准备好拟合模型了。我们将使用 RMSProp 的超参数的默认设置,并运行模型 100 次迭代。在每次迭代中,我们将打印出一个采样的名称和平滑的损失,以查看随着更多的迭代,生成的名称如何开始变得更有趣,以及损失将开始减少。完成模型拟合后,我们将绘制损失函数并生成一些名称。

下面是培训期间生成的一些输出:

There are 36121 characters and 27 unique characters.

Epoch 0
=======
Sampled name: Nijqikkgzst
Smoothed loss: 23.0709Epoch 10
=======
Sampled name: Milton
Smoothed loss: 14.7446Epoch 30
=======
Sampled name: Dangelyn
Smoothed loss: 13.8179Epoch 70
=======
Sampled name: Lacira
Smoothed loss: 13.3782Epoch 99
=======
Sampled name: Cathranda
Smoothed loss: 13.3380

Figure 6: Smoothed loss

15 个时代后,产生的名字开始变得更有趣。我没有包括所有时代的结果来缩短帖子;但是,你可以在与这篇文章相关的笔记本中查看结果。其中一个有趣的名字是“Yasira”,这是一个阿拉伯名字:)。

结论

统计语言模型在语音识别和机器翻译等自然语言处理中至关重要。在这篇文章中,我们使用字符级语言模型展示了统计语言模型背后的主要概念。该模型的任务是使用从包含 5,163 个姓名的人口普查数据中获得的姓名来逐字符生成姓名。以下是主要要点:

  • 如果我们有更多的数据,更大的模型,训练更长的时间,我们可能会得到更有趣的结果。然而,为了得到一个非常有趣的结果,我们应该转而使用长短期记忆(LSTM) 模型,具有一层以上的深度。人们已经使用了 3 层深度 LSTM 模型,当应用于烹饪书和莎士比亚诗歌时,能够产生非常有趣的结果。LSTM 模型优于简单 RNN,因为它能够捕捉更长的时间相关性。
  • 对于我们使用的采样技术,不要期望 RNN 生成有意义的字符序列(名称)。
  • 我们在这篇文章中使用每个名字作为它自己的序列;但是,如果增加批量,我们也许可以加快学习速度,获得更好的结果;假设从一个名字到 50 个字符的序列。
  • 我们可以使用采样策略来控制随机性水平。在这里,我们在模型认为它是正确的角色和随机性水平之间进行了平衡。

原载于 2018 年 2 月 22 日imaddabbura . github . io

用 PageRank 描述科学影响——第一部分

原文:https://towardsdatascience.com/characterizing-scientific-impact-with-pagerank-part-i-1ac8e000c466?source=collection_archive---------5-----------------------

人们常说,学术的生死系于引用之剑。我目前在学术界,我想说在我的学科中这是真的。在这篇博客中,我将分享我从事的一个附带项目的一些结果,通过使用替代性的度量标准来衡量科学影响,从而了解网络。特别是,通过 page rank——谷歌搜索引擎最初基于的算法——而不是通常的指标,如引用总数,来评估出版物的影响和作者的累积影响。

在继续之前,让我对我的学科做一些概述。我在粒子物理领域(又名“高能物理”)。我认为这个领域包括大约 10,000 名物理学家,分为两类:理论家和实验家。我属于前者。领域相对开放,学院化,这是一件很棒的事情。

我们(最终)在同行评议的期刊上发表我们的结果,虽然被评议的论文肯定仍然是一个重要的指标——特别是对于晋升、实验者的重大发现等——但几乎每个人都在 a rXiv 上看论文,论文的预印版本在那里发表。由于声誉是科学界的主要货币,只有在预印版本经过社区的非正式同行评审后,它才会被提交给期刊。

HEP 的另一个很好的资源是 InspireHEP ,这是一个强大的数据库,你可以在其中搜索发表在同行评审期刊或 arXiv(或两者兼有)上的论文,也可以搜索作者等。InspireHEP 允许你查找任何作者的科学统计数据。例如,诺贝尔物理学奖获得者史蒂芬·温伯格的累积数据可以在这里找到:

Citation statistics summary for Steven Weinberg, Nobel Prize in Physics in 1979 for the formulation of the Standard Model of Particle Physics (along with Glashow and Salam!).

现在,史蒂芬·温伯格有多达 70,487 次的引用,所以如果你假设一篇论文的科学影响力与它的引用成正比,这在这种情况下肯定是正确的。然而,这篇论文并不是粒子物理学中被引用最多的论文,在这篇论文中,温伯格提出了粒子物理学的标准模型,并使他与格拉肖和萨拉姆一起获得了 1979 年的诺贝尔奖。

这就引出了一个问题:科学的影响力是通过引用的数量来衡量的吗?引用被赋予了很大的权重,尤其是在聘用教员或博士后研究人员时。问题是你可以想出几个系统被玩的方法(不一定是故意的),比如:

  • X 引用 Y,Y 引用 X 作为回报;或者
  • 每当 X 写一篇新论文时,X 就引用 X 的每一篇旧论文;或者
  • X 主要写关于统计侥幸的论文,这让很多其他人兴奋,所以 X 通过成为第一个发表关于侥幸可能是什么的解释(在侥幸最终消失之前)的从那些其他容易兴奋的人那里收集了很多引用;诸如此类。

似乎今天的论文有更多的参考文献,所以有可能新的论文比过去的论文被引用的次数更多。

因此,有了这样的背景,这里是一个附带项目的初步结果,我用谷歌的 PageRank 量化了 HEP 的论文和作者的影响。

注:在做这个项目作为学习网络的有趣方式时,我偶然发现了这篇 论文 。据我所知,他们是第一个使用谷歌搜索算法来评估科学论文的人。他们集中研究了 1893-2003 年左右发表在《物理评论》杂志上的论文。除此之外,接下来的结果是我自己的。

为了清楚起见,让我通过一个简单的例子简单回顾一下 PageRank (PR)是如何工作的。假设你有 3 个网站,A,B,c。我们最初假设总公关等于 1,并平均分配给所有网站,因为每个网站都同样重要。所以,首先,A,B,C,都有 1/3 的 PR。现在,如果例如 B 在它的站点上有到 A 和 C 的链接,A 或 C 的 PR 是:PR(A 或 C) = 1/N + PR(B)/L(B),其中 N 是站点的总数,L(B)是 B 链接的站点的总数。所以现在站点 A 和 C 同等重要,并且比 B 更重要。在实践中,你迭代几次直到每个站点的 PR 收敛到一个稳定的值。我不会写 N 个网站的通用表达式,但本质上,每个网站都将其 PR 平等地赋予它链接的网站。这个算法向我们展示的是被其他人认可的站点,这些站点本身被许多其他人认可,比没有被其他人认可的站点更重要。一个技术问题:该算法还有另一个称为“阻尼因子”的参数,它大致对应于随机用户点击当前网站链接的概率。人们选择的典型值是阻尼因子= 0.85,据我所知,这是从社会实验中获得的(见维基百科文章)。我将在以后评论阻尼因子的不同选择。现在,这里我将连接网站→发表,应用 PR 算法找到“重要”的论文。好了,现在来看结果。

一些程序细节

对于这项研究,我从 InspireHEP 下载了整个数据库,可以在这里找到。它有几种格式,JSON 格式很方便,所以它对 Python 非常友好。它包含了从 1962 年以来的每一篇论文的元数据,并包括迄今为止大约 120 万篇出版物。它为我们提供的每个记录 id(纸张)的相关信息是:

  1. 作者;
  2. 论文中的参考文献;
  3. 论文的引用;和
  4. 出版日期。

现在,这意味着我们可以为每篇论文 i 创建一个“边缘” (i,j) ,其中 j 是我 i 引用的论文。类似地,我们可以创建形式为 (k,i) 的边,其中 k 是引用 i 的论文。因此,边的集合允许我们形成一个(有向)网络。

你可以在我的 GitHub 这里找到我为这个项目编写和使用的代码。

评估论文的影响

因此,现在专注于描述论文,你可能会问 InspireHEP 上 PR 最高的论文是什么。前三名是:

  1. 史蒂芬·温伯格的轻子纸模型。正是这篇论文让他获得了诺贝尔奖。迄今为止,它被引用了 10,709 次,但它不是 HEP 上被引用最多的论文。

2.第二,我们有肯·威尔逊关于夸克禁闭的论文。迄今为止,它“仅仅”被引用了 4483 次,但是它的重要性怎么强调都不过分。顺便说一下,威尔逊是另一个诺贝尔奖获得者,尽管他并不是因为这篇论文而获奖。

3.最后,在第三位,我们有 Kobayashi 和 Maskawa 关于电荷宇称破坏的论文。又一篇获得诺贝尔奖的论文。

为了完整起见,如果你要按照论文被引用的次数来排列,前三名应该是:

  1. 胡安·马尔达西那关于广告的论文/CFT。它基本上开创了一个全新的领域。它被引用了将近 13000 次。

Maldacena’s paper on AdS/CFT. The top-cited paper on HEP.

2.温伯格关于“轻子模型”的论文。

3.超新星宇宙学项目合作论文,他们在论文中确立了宇宙正在膨胀。这为佩尔穆特赢得了 2011 年的诺贝尔奖(与施密特和里斯一起)。

The third most cited paper on HEP.

好了,论文到此为止。有趣的是,虽然被引用次数最多的论文肯定是有影响力的,但基于公关的影响力衡量指标确实捕捉到了一些不同于仅仅依赖引用的东西。特别是,威尔逊的论文似乎是一个巨大的离群值。在下一篇文章中,我会看到这一点,并更详细地量化 PR 与引用的关系以及量化作者的影响。

用 PageRank 描述科学影响——第二部分

原文:https://towardsdatascience.com/characterizing-scientific-impact-with-pagerank-part-ii-2c1830bba9c3?source=collection_archive---------5-----------------------

或者说,如何鉴别一个诺贝尔奖获得者

这是我写的一系列博客中的第二篇,记录了一个描述科学影响的附带项目(你可以在这里找到第一部分)。特别是网络和图,我觉得很有意思。因此,作为一个有趣的练习,我使用 PageRank (PR),谷歌用于在其搜索引擎中对网站进行排名的算法,来量化论文和个人作者在高能物理(HEP)中的科学影响。在前一篇文章中,我主要关注论文。在这里,我会告诉你更多关于衡量个人作者的重要性,以及公关和更多标准指标之间的关系,如引用总数。

评估作者的影响

现在让我们关注作者。我们必须回答的第一个问题是如何将论文的 PR 分配给作者。你可以选择把论文的 PR 奖给每一个作者。虽然我在这里没有选择这种方法,但为了完整起见,我使用这一指标计算了作者的影响,发现 PR 权重最高的作者大多属于大型实验合作项目,如大型强子对撞机、ATLAS 和 CMS 的通用实验。这些合作有数千名物理学家参与,他们发表了许多(非常好的)物理分析,这些分析依次被引用多次。一般来说,每个合作成员都会在实验发表的每篇论文上写下自己的名字。所以也许这个结果并不太令人惊讶。

相反,我要做的是把一篇论文的 PR 看作一个奖项,所以它应该在这篇论文的作者之间平均分配。因此,如果一篇论文有 N 个作者,那么每个作者都会从这篇论文中获得 PR/N。因此,对于 HEP 中的每一位作者,我们可以简单地以这种方式将他们的论文总 PR 相加。这些是使用整个 HEP 数据库信息的 PR 最高的物理学家(你可以在本系列的第一篇文章中阅读数据集):

The authors in High Energy Physics (HEP) with the highest PageRank (PR) as awarded by the PR of the papers that they have (co-)authored. If a publication has N authors, its PR is divided equally amongst the scientists. There are 14 authors in the top 30 who have earned a Nobel Prize in Physics.

所以,我们有它。名单是由一些有影响力的人组成的。特别是,前 30 名作者中约有一半是诺贝尔奖获得者。另一半由一些非常有名的人组成(没有指名道姓,许多人认为这个名单中没有诺贝尔奖的少数人应该获得一个)。将此与我们使用引用总数作为衡量标准时的类似分布进行比较:

The authors in High Energy Physics (HEP) with the highest citation count.

上面的大部分作者都属于大型实验合作,如上所述,我在这个名单中没有认出任何诺贝尔奖获得者。我想说的是,公关的确捕捉到了一些不同于总引用的东西。你可能会问这样一种情况,我们不是给一篇论文的每个作者分配引用总数,而是做一些类似于我正在使用的 PR 分配方法的事情,我们根据作者的数量进行处罚。我也尝试了这种方法,发现前 30 名作者中只有大约 20%是诺贝尔奖获得者。

PageRank 和引文相关性

那么,PR 和引用次数有关联吗?让我们量化一下作者的情况。从现在开始,让我们选择一个更窄的日期范围。特别是,让我们关注从 1997 年 1 月 1 日至今发表的论文所构建的网络边缘,我们通过在出版物的作者之间平均分配来奖励 PR。

Scatter plot of the number of citations vs the PR of authors in HEP for papers published from 1997–2017.

显然存在正相关,但正如之前的结果所暗示的那样,似乎存在巨大的差异。为了完整起见,让我们将数据拟合为一条直线,以确定关于 PR 与引用次数 N 成比例的假设的一些最大异常值是什么:PR(N) = a + bN,其中 a 和 b 是我们通过线性回归找到的系数。

我们发现,线性假设下最大的异常值确实是具有最大 PR 的作者。以下是 10 大异常值(同样针对过去 20 年发表的论文)。

The top 10 authors with the highest PR for papers published in HEP in the last 20 years. They are also the biggest outliers under the hypothesis that PR is proportional to the author’s total number of citations.

总之,我们已经看到,通过使用 PR 来量化论文和作者的影响,我们能够挑选出与依赖总引用量时不同的特征。有趣的是,当我们研究 InspireHEP 上的全部文章时,通过选择 PR 值最高的作者,我们可以很好地识别谁是诺贝尔奖获得者。

暂时就这样了。在不久的将来,我想把重点放在这种评估重要性/影响的方法的潜在应用上:

  1. 到目前为止,我们已经对一个跨越几十年时间的数据集进行了非常粗略的描述。现在,如果我们能把这种方法用作推荐系统,那将会很有趣。例如,假设 X 大学正在招聘一名新教师。到目前为止,有机会在这样一个委员会任职的人,除了推荐信之外,倾向于非常依赖引用。因此,作为下一步,让我们看看我们是否可以在这样一个假设的搜索中使用 PR 作为衡量标准,而不是引用来推荐谁是最佳候选人。在下一篇文章中,我将通过一个简单的例子来探讨这个问题。
  2. 除了公关和网络之外,我们能在出版物出版时识别出有影响力的出版物吗?也许作为第 0 步,我们可以以类似于构建垃圾邮件过滤器的方式进行,我们可以在由有影响力的论文文本组成的训练样本上构建我们的模型。

用 PageRank 描述科学影响——推荐聘用决定

原文:https://towardsdatascience.com/characterizing-scientific-impact-with-pagerank-recommending-hiring-decisions-e394f02989c0?source=collection_archive---------12-----------------------

这是我正在撰写的系列文章的第三部分,记录了一个关于通过网络分析评估科学重要性的附带项目。作为一个案例研究,我一直在使用 PageRank (PR)来量化高能物理学(HEP)中论文和作者的重要性。在前两篇博客文章中,我们主要看到了自 20 世纪 60 年代初以来 HEP 所做工作的广泛描述。这被证明是一种识别 HEP 诺贝尔奖获得者的简洁方法,这是引用次数等更标准的指标无法充分捕捉的。在这里,我描述了这种衡量重要性的方法的一个简单应用:作为学术界招聘决策的推荐系统。

我在终身职位上的第一年即将结束,我有机会参加博士后研究员和教师级别的招聘委员会。引用是人们非常重视的一个指标,尤其是对于教师招聘和高级博士后研究员。一个例外是:当雇佣一个直接从博士学位毕业的博士后时,引用证明不那么重要,因为人们主要依赖申请人的博士导师的信。当然,还有其他重要因素在起作用,比如业内资深人士的推荐信。然而,在这个例子中,我将只依靠单个作者的 PR 权重。为了完整起见,让我总结一下我是如何获得作者的 PR 的。通过将出版物的 HEP 网络视为节点,其中有向边由处方形成:(引用的论文,被引用的论文),我们可以为出版物分配 PR 权重。所以一个出版物的“重要性”与其公关成正比。现在,我们可以将出版物的 PR 分配给作者,方法是在他们之间平均分配。然后每个作者得到该论文总的 PR 的( 1/N)PR* ,其中 N 是手稿中作者的总数。一个特定作者的总 PR 是他们每篇论文的 PR 的总和。

让我们讨论一下如何推荐一个特定的人。让我们来关注一下 2017-2018 学年的招聘情况。任何被聘为教员的人都将在今年九月左右开始工作。不管是好是坏,HEP 在一年中有一些特定的时间是招聘季节。因此,所有 2017 年的职位都将在 2016 年秋季发布。大多数地方在 2017 年 3 月或 4 月之前发出要约。那么,如果你是这一季招聘委员会的成员,你应该关注谁呢?我们可以依靠历史趋势来缩小范围。这是一个人走向教师工作的“典型”路径:

  1. 在 5 年内完成他们的博士学位,尽管有些人确实在 4 年内完成;然后
  2. 在被雇佣之前,继续参加一两个三年期的博士后研究。

这些当然不是规则。我知道一些明显的例外,比如那些在第三个三年博士后任期内被聘用的人。但是现在让我们采用这个简单的方法。有一个潜在的问题我们必须解决:我从 InspireHEP (一个 HEP 论文和作者的数据库和搜索引擎)下载的出版物数据库没有作者的博士学位授予日期。我们仍然可以通过下载 HEPNames 数据库来获得这些信息,该数据库提供了作者信息,但是让我们采用一种简单的替代方法,即依靠历史趋势。因此,我们将使用作者的第一次出版日期来代替作者的博士日期。大多数人在研究生院的第二或第三年发表他们的第一篇论文。同样,这一趋势也有明显的例外。但是,让我们看看我们的建议使用这些简化的假设结果是什么。

R 结果

好吧,假设招聘委员会真的想要一个年轻的人,所以他们只想看着申请人完成他们的第一个三年博士后。这样做的理由是,在这一点上,申请人已经证明了他们的独立研究能力,但仍然有很大的潜力进一步发展。所以,让我们不情愿地考虑委员会的愿望。然后,对于 2017-2018 学年,我们需要找到在 2014 年开始博士后研究,并在 2010-2011 年左右发表第一篇论文的人。当我们这样做的时候,这是三个公关最好的作者:

  1. 道格拉斯·斯坦福。
  2. 蒂姆.林顿。
  3. Sudhaker Upadhyay。

PR 最高的人,斯坦福,其实是 2010-2014 年拿到博士的。他现在是普林斯顿高等研究院的博士后,并将于今年秋天在斯坦福大学开始教职。(奇怪的是,考虑到他的姓)。

Publication statistics for D. Stanford, the author with the highest PR in HEP who got their PhD around 2013-2014.

林登于 2008 年至 2013 年在圣克鲁斯获得博士学位,现在是他在俄亥俄州的第二个博士后,此前他在芝加哥进行了两年的博士后研究。我知道他的工作。我想他很快就会得到一份教职。

另一名研究员 Upadhyay 于 2008 年至 2013 年在印度获得博士学位,目前是那里的博士后。我不知道他的工作,因为我们在不同的学科,但我看到他已经写了多达 60+的论文!

现在,如果我们只依靠引用,引用最多的人,他们在三四年前获得博士学位,都是 CMS 或 ATLAS 的成员。如前所述,实验合作的成员通常会在实验出版的每一份出版物上署上他们的名字。

原则上,我们可以将这种方法应用于推荐前几年的招聘职位,以确定我们得到的实际招聘决定有多接近。但有一个复杂的问题是,我计算了截至今年六月的论文和作者的 PR。因此,如果我们想向 2000 年招聘的教师遴选委员会推荐一个招聘决定,我们获得的 PR 包括潜在申请人在 2000 年的未来工作。而当时审查申请的委员会只能访问在做出雇用决定时计算的 PR。我可能会在将来的某一天回到这里进行研究。

总之,在这篇博文中,我描述了一个简单的应用程序,它利用通过公关获得的作者的重要性,向学术界的教师招聘委员会提出招聘建议。

在实验中追逐统计幽灵

原文:https://towardsdatascience.com/chasing-statistical-ghosts-in-experimentation-3f393323a1c1?source=collection_archive---------8-----------------------

科林·麦克法兰,汤姆·奥利弗和利兹·埃德里

实验都是关于因果关系的,但是正确的因果关系很容易出错!在这一系列的博客文章中,根据对 Skyscanner 的大规模实验工作的观察,我们将强调一些通过实验得出错误结论的反直觉方法。

让我们从一些定义开始,以确保我们都在同一页上。运行实验或 A/B 测试是我们用来确定我们对产品或服务所做的更改是否会产生我们应该做出反应的信号或我们应该保持不确定的噪音的程序。我们使用一种频率主义方法,特别是零假设显著性检验,来进行这些因果推断。

因果推断本身涉及真实效应(数据中的真实差异来自治疗表现的真实差异)、假阳性(数据中的虚假差异,而不存在真实效应)、假阴性(当真实效应可能存在于具有更高统计功效的样本中时,明显未能检测到数据中的差异)和机会(框架并不完美,因此总会有一个被设置为显著性水平的测量误差分配)。

当实验分析宣称真效应无效应而假阳性或假阴性在实验过程中被低估时,我们称之为统计幽灵。这些是实验从业者中常见的误解,导致比现实更多的赢家和比可能发现的更多的失手

这是一个正在进行的系列的一部分。看看这些:

👻实验的第一个幽灵:要么有意义,要么有噪音
👻实验的第二个幽灵:基于会话的度量标准的谬误👻实验的第三个幽灵:多重比较

鸣谢 Ronny Kohavi、Ben Dressler、Lukas Vermeer、Aleksander Fabijan、和 Duan。建筑原作出自 草席

与我们合作

我们在 Skyscanner 以不同的方式做事,我们正在全球办事处寻找更多的工程团队成员。看看我们的 Skyscanner 工作岗位寻找更多空缺。

Team in action

聊天机器人数据分析——业务优化的下一件大事

原文:https://towardsdatascience.com/chatbot-data-analytic-the-next-big-thing-for-business-optimization-da43d686e5f3?source=collection_archive---------4-----------------------

从技术上来说,聊天机器人是为了理解人类的行为实践而开发的。作为自学过程的一部分,他们可以系统地记录数据、指标、偏好和趋势,最终帮助他们监控用户交互,相应地调整相关性和响应。幸运的是,这一特性使 Chabot 也能够在数据分析领域发挥重要作用,Chabot 开发公司试图利用最佳策略、工具和技术来实现这一点。

聊天机器人和当前数据爆发场景

在这个时代,聊天机器人的活力更加重要,而数据爆发不断走向更高的点。例如,根据 IDC Digital Universe 的一项研究,到 2020 年,每年创建的数字数据量将为 35 吉字节。此外,考虑到人工智能和物联网因素,该数字被提升至 40 ZB,然后又被提升至 44ZB。在另一项研究中,IDC 估计,到 2020 年,通过互联网进行的商业交易(包括 B2B 和 B2C)将达到每天 4500 亿次(它们也将产生大量数据)。

技术和商业世界都在探索分析这些数据的最佳机会,以产生有意义和可操作的见解,从而做出战略性商业决策。作为这些交易或互动的一部分,机器人在分析领域的扩展功能使它们更加引人注目。

聊天机器人和数据值

Chabot 在数据和分析方面的第一个业务领域是,用户利用机器人的接口直接与数据本身进行交互。因此,结合了数据分析能力的高效 bot 架构通过提供运营体验、客户体验和分析来提供卓越的商业价值。

第二个领域是自动化数据收集。在对话期间,机器人会询问更多信息,以澄清用户的倾向和偏好。甚至包括银行在内的一些金融机构也使用机器人来实现数据查询的自动化。这个属性也可以扩展到信息收集,用于不同的目的。可以根据需要对收集的数据进行处理和分析。

聊天机器人——客户体验背景下的成熟阶段

一些公司使用聊天机器人互动来了解客户的偏好或选择。他们使用算法来问几个问题,并根据答案来感知客户的选择。这样他们就很容易推荐产品了。然而,许多公司使用机器人来增加用户参与度,从而增加客户获取量,并通过自动化流程来实现总体经济高效的货币化。根据行动的目的,聊天机器人在客户体验方面有三个成熟阶段。

  1. 信息交互:

这些机器人理解自然语言,并回答提出的问题。它们提供较少的交互式客户体验,但适合 FAQ 回复或类似类型的对话。

2。个性化互动:

与后端的相关系统或应用程序连接,这些机器人可以生成用户特定的响应。他们也会问一些简单的问题来识别用户的意图。这里的互动听起来更像人类,在这种情况下有可能提供令人惊叹的客户体验。

3。交易交互:

这些智能机器人旨在通过一系列指令或交互来帮助用户完成特定的任务、动作或活动。与相关后端系统连接,还可以集成客户数据。点对点的简化说明,让用户快速而有趣,是提供卓越客户体验的关键。

聊天机器人分析和数据交互

在这个互联的世界中,B2B 或 B2C 客户互动格局正在发生巨大的变化,而且变化速度非常快。此外,聊天机器人已经成为改造的相当一部分。由于 Bot 执行与最终用户的直接交互,它在培养新的和不断增长的数据集(其中也包括业务关键数据)方面有更大的责任要履行。

随着人工智能和机器学习的不断发展,聊天机器人的范围不再局限于对话代理或虚拟助理。企业已经开始思考 Bot 战略的类型,在这种战略中,他们可以以最佳方式将他们的 Bot 与客户体验和数据技术栈结合起来。下面是一个出租车预订聊天机器人应用程序的示例分析报告,帮助组织了解他们的用户行为。

Consistently decreasing ratio of returning user informs the company about service improvements and requirement of loyalty programs.

聊天机器人和预测分析

总的来说,预测分析就是观察和分析正在进行的以及先前的基于数据的事实,并预测未来。即使是对聊天机器人数据的简单观察也可以解决业务查询,例如在客户行为的上下文中发生了什么?此外,分析可以帮助找出为什么会发生,接下来会发生什么?

预测分析依赖于各种统计技术,如数据挖掘、预测建模、模式匹配以及最终的机器学习。对机器人相关技术和算法的有效使用,使得获得不仅可以优化客户体验,而且可以优化业务几乎所有方面的洞察力变得容易。

高级行为分析

聊天机器人使企业能够更深入、更广泛地进行数据分析。将先进的行为分析技术集成到聊天机器人中是目前流行的做法。可以作为独立软件或内置功能,甚至机器人流程自动化功能也很好,并为客户体验分析提供量身定制的解决方案。因此,公司可以定义客户体验的新高度,以将其作为竞争优势因素。

下面是一个基本报告,显示了用户旅程的“关键查询”指标,随着时间的推移,这些指标导致了显著的用户偏好洞察。

当然,作为进化过程的一部分,当前的机器人将在不久的将来经历几次强化。例如,提高准确性,机器学习之外的工具和技术,以及在循环中为人类个体提供正确和高产的角色。因此,bot 技术将能够在更有目的的规模上自我定位。

结论:

机器人分析使我们能够了解客户行为,是什么驱使他们做出相关决策,是什么让他们失望,是什么让他们更容易留住他们等等。因此,毫不夸张地说,在未来,机器人和聊天机器人开发战略都将在增强甚至重构业务流程方面发挥作用。

聊天机器人很酷!使用 Python 的框架

原文:https://towardsdatascience.com/chatbots-are-cool-a-framework-using-python-part-1-overview-7c69af7a7439?source=collection_archive---------3-----------------------

Kelly — Movie Bot

你喜欢你在凯利电影机器人视频上看到的吗?如果答案是“是”,并且你想实现一个聊天机器人,你可以开始阅读这篇文章。这篇文章很详细。我把整篇文章分成几部分。所以,坐好,放松!我们将详细介绍每一部分,最后在文章的结尾,您应该已经在 Slack 中部署了一个聊天机器人。

  1. 第 1 部分:概述
  2. 第二部分:数据
  3. 第三部:松弛
  4. 第 4 部分:使用 IBM Watson 的 NLP
  5. 第 5 部分:定制 NLP 解决方案
  6. 第 6 部分:日志
  7. 第 7 部分:最终注释

本文的受众:我设计了一个通用的聊天机器人框架,并在本文中讨论了如何覆盖广泛的受众。任何对 Python、Jupyter 笔记本有基本了解并且能够执行 pip 安装的人都应该能够完成这个系列并看到结果。

你对这个系列有什么期待?

bot 框架是模块化的,这为读者设计和实现他们自己的功能提供了一系列机会。集成可以在框架中轻松完成。此外,因为它被设计为即插即用,所以失败的可能性是最小的。

初学者:对如何为这个特定项目开发和使用框架的总体想法。您应该能够从 Github 下载代码并成功完成安装。这包括软件包安装、slack 和 IBM Watson 帐户创建和设置、运行一次性文件以生成链接和电影推荐。您可以在 IBM Watson 中添加额外的技能(比如生成静态响应的闲聊),并在 slack 环境中查看结果。

中级:你应该能够使用这个框架作为模板来设计你自己的聊天机器人,它可以部署在不同的领域。此外,您可以通过添加新的数据源来扩展聊天机器人的知识库,包括编写代码来连接不同的数据库(弹性搜索、SQL 数据库、Excel 等)..).此外,您可以向 bot 添加额外的 NLP 特性,并在 slack 环境中查看结果。

专家:你应该能够通过集成 Slack/NLP 的 API 连接来添加/扩展 bot 特性。我使用 IBM Watson 来识别问题类别并生成静态响应。您可以通过设计自己的 NLP 功能来取代框架中的 IBM Watson。此外,您可以为不同的平台(Web、Skype 等)扩展 bot 集成..)

第 1 部分:概述

Credit: Pixabay

什么是聊天机器人?

聊天机器人是一个检索信息和产生类似人类对话的工具。它主要是一个旨在解决/服务于特定目的的对话系统。根据设计的不同,聊天机器人通常分为 4 类。

Credit — Types of Chatbot.

开放域

开放域机器人也称为通才机器人。今天我们使用的 Alexa、Google Home、Siri、Cortana 都属于这一类(开放领域/基于生成的)。这些机器人试图模仿类似人类的对话。同样,它回答了大多数人提出的问题(比如 FAQ)。然而,他们不能回答基于特定领域的问题。比如:我公司销售部门上个季度表现如何?这就是基于开放域/检索的机器人无法构建的原因之一。

闭域

封闭域机器人也称为专业机器人。根据类型的不同,它可以很容易(基于检索)或很难(基于生成)开发。本文中讨论的 bot 是一个专家 bot,它属于封闭域/基于检索的类别。这一类别中的其他机器人包括——订购披萨、预订航班/餐厅/酒店/约会。另一方面,生成型机器人包括客户服务聊天机器人,它们在回答客户问题时试图像代理一样模仿。这些机器人很难构建,因为它们试图让客户相信它们正在与一个真实的人交谈。

聊天机器人是如何工作的?

聊天机器人需要理解以下内容来回答用户的问题。

  1. 用户在说什么?(意图)
  2. 用户提到什么具体的东西了吗?(实体)
  3. 为了从用户那里获得更多的细节,机器人应该问什么?(对话/维护上下文)
  4. 如何满足用户的要求?(回应/履行)

让我们用一个下面显示的飞行机器人例子来详细理解每一个部分。用户说“我想为两个人预订一张从纽约到西雅图的机票,9 月 15 日出发,9 月 19 日返回”。

Credit: Flight Bot

目的

用户的意图是预订航班。

实体

实体也称为关键字或槽。这里有多个实体。

出发地-纽约

去西雅图

出发日期-9 月 15 日

返回日期-9 月 19 日

人- 2

对话/维护上下文

对话是机器人和用户之间的来回交流。上下文让机器人知道机器人当前处于什么状态。有三种状态——以前、现在和将来。当用户启动对话时,机器人重复用户的旅程,然后与用户核对“这个信息是正确的吗?”。这里,先前状态为空白,当前状态为“用户验证”,未来状态为“基于用户验证提供响应”。当用户回答“是”时,则机器人状态分别变为“用户验证”、“基于用户验证提供响应”和“预订航班”的先前、现在和未来状态。如果不维护上下文,机器人就无法建立来回通信。在飞行机器人的例子中,如果没有维护上下文,机器人会问“这个信息是正确的吗?”每次直到用户放弃。

回应/履行

满足用户请求是机器人对话的最后一步。在这里,机器人以链接“查看所有结果”的形式提供结果。因此,当用户点击链接时,他们将能够看到航班并进行预订。

基于生成的机器人使用人工智能和机器学习来生成用户响应。所以他们不需要理解意图和实体来响应用户。

我找到了这篇文章,它涵盖了我们到目前为止讨论过的许多主题,以及可以用来构建聊天机器人的机器人框架。这是一本好书。

[## 聊天机器人 API 的比较分析

人工智能正在崛起!不是作为遥远未来对人类创造者的机器反抗,而是作为…

www.datasciencecentral.com](https://www.datasciencecentral.com/profiles/blogs/a-comparative-analysis-of-chatbots-apis)

让我们开始工作吧

好了,现在是时候部署凯利电影机器人了。它是一个简单的机器人,可以回答关于电影的问题。用户可以询问评级、电影投票人数、流派、电影概述、类似电影、 imdbtmdb 链接、预算、收入和成人内容。本练习的数据集取自 Kaggle — movies_metadata 。这个项目的完整代码可以在 Github 中找到。

[## sundar 0989/电影 _ 机器人

https://youtu.be/7hQhPMPNY6A.在 GitHub 上创建一个帐户,为 Sundar0989/Movie_Bot 开发做贡献。

github.com](https://github.com/Sundar0989/Movie_Bot)

凯利设计

这种设计需要注意的一点是,数据和处理都在本地系统中处理。尽管我们使用 IBM,但它被用作 API 服务,没有任何内部数据被发送到 IBM。这样,整个设计可以在您的工作场所实现,而不必担心数据传输。

Kelly Design

步骤 1(用户提问):

用户可以通过 Slack 与 Kelly 互动。一旦用户发布了一个问题,它将被传递到后端系统进行分析。

步骤 2 和 3 (NLP 处理并返回 NLP 结果):

所有的自然语言处理都发生在第二步。这包括 IBM Watson 处理、相似性搜索、基于协同过滤的推荐。NLP 处理完成后,我们有三个输出

  1. 意图——用户想问或询问什么?
  2. 实体—他们正在寻找的确切字段或列是什么?
  3. 对话/交互—为用户问题提供适当的请求/响应。

步骤 4 和 5(查询数据):

目前,数据保存在 excel 文件中。但是,如果需要,您可以添加多个数据库/excel 文件来访问不同的源。基于步骤 3 的结果,查询适当的数据库/excel 文件并返回结果。

第 6 步(向用户发布结果):

从后端获得的结果通过 Slack 发布给用户

第 7 步(日志维护):

用户之间的交互被记录并存储在文本文件中。此外,如果机器人无法识别用户的问题,它会将这些问题添加到后续文件中。

Main.py

包装进口

像往常一样,我们通过导入包来定义程序。请注意,这里写着“slack.slack_commands”和“nlp.nlp_commands”。这将分别从 slack 和 nlp 文件夹导入 python 程序 slack_commands 和 nlp_commands。此外,还导入了配置文件中的几个函数。

变量初始化

用户上下文在“上下文”变量中维护。一旦聊天开始,IBM Watson 生成的上下文变量如下所示,

{'conversation_id': '76e59c57-8257-4390-ae15-ba75e7576476',
 'system': {'_node_output_map': {'node_2_1541443578896': [0]},
  'branch_exited': True,
  'branch_exited_reason': 'completed',
  'dialog_request_counter': 1,
  'dialog_stack': [{'dialog_node': 'root'}],
  'dialog_turn_counter': 1,
  'initialized': True}}

它有一个“conversation_id ”,用于跟踪会话流的状态(以前/现在和将来的状态)。在对话开始时,它被赋予一个空的字典值。

除了保持对话,我们还应该让机器人知道何时停止对话。这是通过“current_action”变量实现的。结束对话的示例如下所示。

每当用户调用“再见”意图时,机器人将“end_conversation”分配给“current_action”变量。稍后在 main.py 程序中,将对该变量进行评估,以重新分配上下文、current_action 和 session_df 变量,如下所示。

另一个关键变量是“会话 _df”数据帧。当用户开始与机器人对话时,会创建一个会话。这确保了用户和机器人之间的上下文是基于每个用户来处理的。当同一用户在多个通道中与机器人对话时,它们被作为不同的会话来处理。因此,机器人和用户之间的对话没有重叠。

当用户提出机器人无法处理的随机问题时,它会触发“follow_ind”将问题写入后续文本文件。在对话开始时,它被分配给 0。最后两个变量“bot_id”和“RTM_READ_DELAY”对应于 slack。当 bot 被调用时,会分配 bot_id。RTM 代表实时信息。该变量将等待一秒钟,然后从用户那里读取下一条输入消息。

调用代码

最后,程序的其余部分确保机器人持续运行并寻找来自用户的输入消息。下面提到的一些函数——parse _ bot _ commands、handle_command 和 output_command 将在后面的部分详细讨论。

就是这样。我们启动了凯利机器人。我们的下一步是理解用于本练习的数据。

第二部分:数据

Credit: Pixabay

这个练习的数据来自下面的 Kaggle 链接。数据集的名称为“movies_metadata.csv”。

[## 电影推荐系统| Kaggle

编辑描述

www.kaggle.com](https://www.kaggle.com/rounakbanik/movie-recommender-systems/data)

数据集包含大量与电影相关的信息,用户只需较少的预处理。我们使用 Pandas 导入数据集,然后准备我们的数据。

<class 'pandas.core.frame.DataFrame'>
RangeIndex: 45466 entries, 0 to 45465
Data columns (total 24 columns):
adult                    45466 non-null object
belongs_to_collection    4494 non-null object
budget                   45466 non-null object
genres                   45466 non-null object
homepage                 7782 non-null object
id                       45466 non-null object
imdb_id                  45449 non-null object
original_language        45455 non-null object
original_title           45466 non-null object
overview                 44512 non-null object
popularity               45461 non-null object
poster_path              45080 non-null object
production_companies     45463 non-null object
production_countries     45463 non-null object
release_date             45379 non-null object
revenue                  45460 non-null float64
runtime                  45203 non-null float64
spoken_languages         45460 non-null object
status                   45379 non-null object
tagline                  20412 non-null object
title                    45460 non-null object
video                    45460 non-null object
vote_average             45460 non-null float64
vote_count               45460 non-null float64
dtypes: float64(4), object(20)
memory usage: 8.3+ MB
adult                        0
belongs_to_collection    40972
budget                       0
genres                       0
homepage                 37684
id                           0
imdb_id                     17
original_language           11
original_title               0
overview                   954
popularity                   5
poster_path                386
production_companies         3
production_countries         3
release_date                87
revenue                      6
runtime                    263
spoken_languages             6
status                      87
tagline                  25054
title                        6
video                        6
vote_average                 6
vote_count                   6
dtype: int64

结果发现数据中有很多缺失值。所以我们去掉了丢失值百分比高的变量。此外,我删除了一些其他变量,以保持数据简单。下面的代码用于从数据集中移除变量。

“imdb_id”和“poster_path”变量中缺少值。我必须使用下面的代码删除这些变量中缺少值的观察值。

现在,让我们看看数据集中的流派变量。

流派名称以词典列表格式存储。为了使它成为一个干净的格式,我们需要在下面应用一个准备代码。

格式很好,对吧。现在让我们移动到我们的最后一步,创建 IMDB,TMDB 和图像 url 链接。

瞧。我们完成了数据准备,最后使用下面的代码导出准备好的数据集。

metadata.to_csv('metadata_prep.csv')

下面的笔记本中提供了完整的数据准备代码。

[## sundar 0989/电影 _ 机器人

https://youtu.be/7hQhPMPNY6A.在 GitHub 上创建一个帐户,为 Sundar0989/Movie_Bot 开发做贡献。

github.com](https://github.com/Sundar0989/Movie_Bot/blob/master/data/Data_Preparation.ipynb)

就是这样。数据准备过程到此结束。我们的下一步是理解松弛过程。

第三部分:松弛

Credit: Pixabay

好了,现在是时候理解松弛过程以及它在框架中是如何处理的了。第一步是创建一个 slack bot 并将其安装在工作区中。下面的链接将指导您创建 slack 应用程序。在配置文件中,您需要编辑 Slack Bot 令牌和 Slack 验证令牌。这就是 slack 所需的全部设置。

[## sundar 0989/电影 _ 机器人

https://youtu.be/7hQhPMPNY6A.在 GitHub 上创建一个帐户,为 Sundar0989/Movie_Bot 开发做贡献。

github.com](https://github.com/Sundar0989/Movie_Bot/blob/master/slack/Create_slack_app.ipynb)

有 6 个为 Kelly bot 编写的 slack 函数。

  1. 解析机器人命令
  2. 解析 _ 直接 _ 提及
  3. 输出命令
  4. 文件 _ 上传
  5. 松弛 _ 平铺
  6. 消息 _ 按钮

让我们详细研究一下每个功能。

解析机器人命令

当用户在 slack 中键入消息时,parse_bot_commands 函数被调用。在 slack 中,实时消息(RTM)事件(slack_events)存储关于特定用户对话的所有信息。这包括谁在问这个问题(message_user),他们使用哪个团队和渠道(team,channel),来自用户的消息或问题是什么(message)以及他们是在和其他人还是机器人说话(user_id)。因为,在 slack 中,用户可以通过调用用户名前面的@符号与不同的用户对话。例如—“@ person 1 给我看电影《玩具总动员》”和“@Kelly 给我看电影《玩具总动员》”是不同的。第一个指向人员 1,第二个指向 Kelly bot。这里,只有当“user_id”与“bot_id”匹配时,机器人才会处理用户消息或问题。

解析 _ 直接 _ 提及

这是 parse_bot_commands 的一个子功能。来自用户“@Kelly 给我看看电影《玩具总动员》”的问题有两部分。第一部分是 bot 用户名“@Kelly”,第二部分是来自用户“给我看看电影《玩具总动员》”的问题。该函数从 slack 事件(message_text)中提取文本,并将用户问题与 bot 用户名分开。

输出命令

output 命令用于将响应发送回 slack。这个函数只支持文本输出(slack_output)。“渠道”变量用于标识用户发布问题的松散渠道,并使用相同的渠道来引导响应。

在 Kelly bot 中,output 命令函数产生的 slack 输出如下所示。

文件 _ 上传

文件上传可以用来上传文件到 slack。文件上传功能支持多种文档类型。其中包括 PDF、Word、Excel、gif、png 等。支持的文件类型的完整列表可以在下面的链接中看到。

[## 文件类型|时差

editable 属性指示文件以可编辑模式存储。is_external 属性指示…

api.slack.com](https://api.slack.com/types/file#file_types)

凯利机器人不使用该功能。但是,它在这里是作为附加功能提供的。

松弛 _ 平铺

松弛平铺是在松弛状态下向用户显示输出的另一种方式。我用这个函数来显示电影推荐。该函数的输出如下所示。

很酷吧。图像使用平铺显示,这样可以立即吸引用户的注意力。当你仔细看时,电影的名字有超链接。因此,当你点击电影名称时,它会将你重定向到 IMDB 电影页面。同样,这是在 slack 中显示输出的一种简单而优雅的方式。

该函数有 5 个输入。

  1. 前面讨论的“channel”变量用于发布到用户提问的相应频道。
  2. “search_term”变量的值为“玩具总动员”。因为我用问题“给我看电影《玩具总动员》”开始了我的机器人对话,所以电影名称被自动存储在 search_term 中,并且每次用户提问时上下文被维护,直到用户重新开始。由于保留了上下文,当我问问题“给我推荐类似这部的电影”时,它在第一行回答说“推荐玩具总动员”。
  3. “title”变量具有电影标题推荐。基于在协作过滤方法中获得的最高分数(这将在后面的第五部分:定制 NLP 解决方案中讨论),它选择标题并将它们存储在 python 列表中。然后在函数中处理这个列表,同时显示输出。
  4. “标题 url”具有对应于电影推荐的 IMDB 链接
  5. “image_url”具有用于电影推荐的相应的 TMDB 图像链接。

消息 _ 按钮

消息按钮也是 Slack 中显示输出的一种不同风格。这类似于松弛平铺,除了它没有图像显示。相反,输出包含与 IMDB 链接相关的按钮。当用户试图搜索一部电影时,此功能在开始时使用。我不记得我头顶上看过的所有电影名字。所以,我使用基于关键字的电影搜索,这个功能也是以同样的方式实现的。处理基于关键字的搜索(相似性搜索)的 NLP 程序将在第五部分:定制 NLP 解决方案中讨论。然而,我想展示这是如何与消息按钮一起工作的。

在这里,当我开始搜索电影时,我没有提到“玩具总动员”,而是以“我正在寻找一部带玩具的电影”开始对话,它给了我“玩具总动员”作为我的第五个选项。这种类型的搜索称为相似性搜索。现在,用户可以点击按钮,以确保他们正在寻找的电影是相同的,然后继续下一步。按钮名称存储在“button”变量中,相应的 IMDB 链接存储在“url”变量中。

就是这样。松弛过程到此结束。我们的下一步是使用 IBM Watson 理解自然语言处理。

第四部分:IBM 沃森

Credit: Time

聊天机器人框架

开发聊天机器人的一个快速简单的方法是使用框架。市场上有很多框架,可以帮助我们构建机器人。其中有几个包括— IBM WatsonLuisWitDialogflow拉莎·NLUBotkit微软 Bot 框架等等。你可以选择任何一个框架来构建你的机器人。同样,编码的复杂性可能会因您选择的框架而异。对于这个练习,我使用了 IBM Watson 框架。下面的链接将帮助您创建一个 Watson 用户帐户,并开始 IBM Watson 对话。

[## sundar 0989/电影 _ 机器人

https://youtu.be/7hQhPMPNY6A.在 GitHub 上创建一个帐户,为 Sundar0989/Movie_Bot 开发做贡献。

github.com](https://github.com/Sundar0989/Movie_Bot/blob/master/nlp/IBM_Watson_Conversation_setup.ipynb)

IBM Watson framework 被用作 API 服务来执行自然语言处理。Kelly bot 的构建方式是没有任何信息存储在 IBM Watson 中。所有的信息处理都发生在你的本地系统中。IBM Watson 服务只处理来自用户的问题,以提供意图、实体、对话和响应。除此之外,没有任何信息存储在 IBM Watson 中。

这些快速课程可以让你开始构建意图、实体和对话。

[## 对话—沃森助手介绍| Coursera

IBM 为课程“如何不用编码构建聊天机器人”制作的视频。在线学习并获得有价值的证书…

www.coursera.org](https://www.coursera.org/lecture/how-to-build-your-own-chatbot-without-coding/dialog-Cupqp) [## 改变意图、实体和对话——IBM 开发人员课程

步骤 3:创建意图意图代表用户输入的目的。你可以把意图想象成你…

developer.ibm.com](https://developer.ibm.com/courses/change-intents-entities-dialog/)

凯利-电影机器人沃森对话

对于本练习,您可以上传 Github 中的代码附带的“bot.json”文件,并将其导入到您的 IBM Watson 对话帐户中,以便开始使用。导入 json 文件后,页面应该如下所示。

意图

实体

我想谈一些关于如何在 Watson、Slack 和你的 python 代码之间建立联系的事情。所以,让我们先看看实体。

这里,看期权实体。它只能取 5 个可能的值。如果您还记得在 slack 流程中,我们使用消息按钮从用户那里获得电影名称选项。

对话

比方说,如果用户选择 6 而不是 5。机器人会回应说“请提供一个有效的选项——1、2、3、4 或 5”。这是使用 IBM Watson 中的对话框特性建立的。那么让我们来看看这个特性。对话框页面应该如下所示。

我们以说“你好”开始谈话。Watson 会将其识别为“hello”意图,将值“hello”赋给上下文变量“currentIntent”。此外,它将响应发送回 python 代码“请输入电影名称以开始”,然后跳转到评估电影名称条件。

在电影名称条件评估中,我有两个子节点,如下所示。

第一个子节点评估用户是否提供了响应。在 IBM Watson 中,这是使用“”选项捕获的。然后机器人响应用户选择电影选项,如下所示。

最后,根据用户选项,它评估该选项是否有效。如果没有,它会要求用户提供一个有效的选项。

这个 Watson 对话设置对应的 slack 接口交互如下所示。

Python 后端

在 python 端,这是通过如下所示的 handle_command 函数建立的。

当使用 IBM Watson API 服务时,它返回一个在“response”变量中捕获的响应。注意,我们每次都将上下文变量传递给 Watson 服务。这用于维护机器人响应的上下文。此外,使用响应变量,我们提取上下文、实体和机器人响应,并将它们分别分配给“上下文”、“搜索关键字”和“松弛输出”。“search_term”变量包含对应于用户选择的电影名称。现在,我希望这能给出 IBM Watson 前端和后端 python 代码之间的交互情况。

就是这样。这部分到此结束——使用 IBM Watson 的 NLP。我们的下一步是理解为 Kelly bot 编写的自定义 NLP 解决方案。

第 5 部分:自定义 NLP 解决方案

Credit: Pixabay

很多时候,我们需要添加额外的 NLP 功能来增强机器人的技能。好吧,现在是你变得更有创造力并开始添加定制解决方案的时候了。我为 Kelly Bot 添加了两个自定义解决方案。(位于 nlp/nlp_solutions 文件夹中)。

  1. 基于元数据的协同过滤电影推荐
  2. 用于识别电影标题的余弦相似搜索

这两个函数的代码驻留在“nlplearn.py”和“onetime _ run _ file.py”中。所以让我们开始吧。

一次性运行文件

这个函数有一些代码,我们需要在启动 Kelly bot 之前运行一次。这种一次性设置在数据不断变化并且机器人需要快速适应这些数据变化的情况下更加容易。我们需要做的就是在需要的时候运行这个文件,而不需要改变机器人的任何内部功能。很酷吧。当文件运行完成时,它会生成一个“one time . txt”pickle 文件,该文件将在 bot 启动时使用。

现在,我们来讨论一下“nlplearn.py”中可用的函数。它有 5 个功能,

  1. 文本 _ 准备
  2. tfidf_fit(余弦相似性搜索)
  3. 相似性搜索(余弦相似性搜索)
  4. 元数据过滤(基于元数据的协同过滤)
  5. 获取推荐(基于元数据的协同过滤)

文本 _ 准备

这个函数接受一个单独的文档(“演示?电影标题“类似于玩具总动员#####”)并通过移除空格和不良字符来准备文本。此外,它还从文本中删除停用词。处理后的文本看起来有点像这个“显示电影标题类似玩具总动员”。

tfidf_fit

该函数获取步骤 1 中准备好的文本,并创建一个 tfidf 拟合。“tf”表示术语频率,“Idf”表示反向文档频率。你可以在这里的链接中阅读关于 tdidf 的内容。拟合完成后,拟合和矩阵存储在 pickle 文件中,以供将来处理。这是通过“一次性运行文件. py”中的代码完成的。

相似性 _ 搜索

该函数计算用户查询和存储在由 tfidf_fit 函数创建的 tfidf_matrix 中的电影标题之间的余弦相似性。首先,它对用户查询执行 tfidf_fit,然后计算 fit 和 tfidf_matrix 中的元素之间的余弦距离。具有最高余弦相似性分数的前 5 个元素被选择并发送回 slack 接口。这用于我们之前讨论过的 Slack 中的消息按钮。

元数据 _ 过滤

该功能执行用于电影推荐的基于元数据的协同过滤。你可以在这里的链接中读到这个功能。最终的“余弦 _sim”函数存储在 pickle 文件中,以供将来处理。同样,这也是通过“onetime _ run _ file.py”中的代码完成的。

获取 _ 推荐

该功能用于根据用户搜索获得电影推荐。它返回 3 部相似的电影并发送回 slack 接口。这个结果用于我们之前讨论过的松弛瓦片。

现在,让我们看看这些定制的 NLP 解决方案在 Slack 中是什么样子的。

基于元数据的协同过滤

参考:https://www . data camp . com/community/tutorials/recommender-systems-python

余弦相似性搜索

就是这样。定制 NLP 解决方案部分到此结束。我们的下一步是理解日志处理。

第六部分:日志

Credit: Pixabay

到目前为止,我们已经实现了运行 bot 所需的所有特性。那么我们为什么需要讨论日志呢?日志文件给 bot 框架带来了什么重要性?

背景

让我们看一个例子来说明它的重要性。假设我们有一个“反馈”意图,并且意图中的示例用户查询包括“我对你的服务满意”、“我不喜欢你的服务”、“你很棒”、“你是一场灾难”等等。当我们发展这种意图时,我们只提供几个例子。将来,假设一个用户说“嘘”。我们知道这应该被归类为“反馈”意图。然而,我们的机器人没有受过这方面的训练。因此,它会显示为导致糟糕用户体验的其他意图。此外,这些类型的用户响应是随机出现的,我们需要一种方法来识别和捕捉它们。

收集用户查询最简单的方法是通过日志。因此,在未来,如果用户提出一个与我们定义意图的方式不同的问题,我们可以捕捉这些响应,并将它们包含在意图模型训练中。通过这种方式,我们改善了整体客户体验。

在这个 bot 框架中,我们有两种类型的日志处理

  1. 日志文件
  2. 跟进文件

日志文件

输出日志文件如下所示。

正如我们在这里看到的,所有信息都被捕获,这使得将来的用户查询处理更容易。此外,它还包括日志文件中的处理时间(倒数第二列)。使用这些输入,我们可以优化需要更多时间处理的查询,从而提高机器人的效率。

跟进文件

后续文件也作为日志文件处理的一部分生成。如果机器人不能向用户查询分配任何意图(“任何其他”意图),则调用“follow_ind”。这将把用户查询写入一个名为“followup_file”的新文件中。' TXT '如下图所示。

这个文件稍后可以使用下面的代码通过电子邮件发送给 bot 开发人员。

就是这样。这就结束了这一部分—日志处理。

第七部分:期末笔记

Credit: Pixabay

我假设如果你还在读这篇文章,你已经成功地完成了这个练习。干得好!好吧,那下一步是什么?

正如我之前所说,我们可以通过添加新的 bot 功能、扩展 NLP 功能以及在其他消息传递平台中实现 bot 来进行试验。这个框架的中心思想是——如果您需要更换平台,并且为了方便添加/扩展技能,所有完成的工作都可以重用。也就是说,我不能涵盖所有可能的选项,因为机器人的应用程序可以根据用户的需求而变化。因此,探索和实现它们取决于您。祝你好运!

如果你正在寻找建立一些基于人工智能/机器学习的聊天机器人,那么请参考下面的链接。

[## bAbI 任务的 DMN+

编辑描述

ethancaballero.pythonanywhere.com](https://ethancaballero.pythonanywhere.com/) [## 使用 Tensorflow 的上下文聊天机器人

在对话中,语境是王道!我们将使用 Tensorflow 构建一个聊天机器人框架,并添加一些上下文处理来…

chatbotsmagazine.com](https://chatbotsmagazine.com/contextual-chat-bots-with-tensorflow-4391749d0077) [## llSourcell/tensorflow_chatbot

Youtube 上@Sirajology 的 Tensorflow 聊天机器人演示。为 llsourcel/tensor flow _ chatbot 开发做出贡献,创建…

github.com](https://github.com/llSourcell/tensorflow_chatbot)

就是这样。最后一部分到此结束。如果您需要讨论任何特别的事情,或者您对任何模块有反馈,请留下评论或通过 LinkedInTwitter 联系我。

玩得开心!

变得更聪明的聊天机器人

原文:https://towardsdatascience.com/chatbots-that-get-smarter-8491f8cd65e6?source=collection_archive---------4-----------------------

写一个不会说话的聊天机器人很容易。编写一个智能的程序,对你问它的任何事情都做出明智的反应,要难得多。一些著名的例子:如果一个人提到哈里森·福特,他们可能不是在谈论汽车。

有三种不同的聊天机器人,它们都越来越难编写。

  1. 最简单的聊天机器人只是一个方便的命令行界面:在 Slack 或 Hipchat 中,通常会有“斜杠”命令。开发人员将设置一个程序,当它进入一个从 git 中提取最新源代码、编译它并显示单元测试输出的房间时,它将唤醒“/build”。因为这是一个非常狭窄的领域,所以很容易做对,而且因为这对程序员有利,所以花一些程序员的时间来改进任何不好的东西总是划算的。
  2. 下一个最简单的是订购机器人,它们通过不让用户偏离批准的对话路径来控制对话。如果你正在订购比萨饼,机器人可以问你关于配料和大小的问题,直到它得到它需要的一切。本质上,这只是一个带有某些字段的 web 表单的替代品,但在某些市场(如中国),有近乎通用的聊天平台,这可能非常方便。
  3. 最难的是无法控制对话的机器人,用户可能会问任何问题。

支持机器人是最后一种类型的例子:用户可以向服务台询问任何事情,支持机器人需要智能地响应。

我做了一个快速调查,发现至少有 50 家初创公司试图编写各种各样的帮助台机器人。这是一个有利可图的市场,因为如果你能把 10%的服务台电话变成与机器人聊天,这意味着巨大的员工成本节约。我有一个客户,其服务台有 150 多名全职员工,可以节省数百万美元。

不幸的是,我见过的几乎每一家初创公司都完全没有达到他们的目标,对他们在聊天机器人上的投资感到满意的客户实际上非常少。

我见过三个陷阱:

  • 一些创业公司缺乏相信自己开发者的勇气。人们相信,微软、脸书、亚马逊、IBM 和谷歌拥有所有的答案,如果我们利用 api.ai 或 wit.ai 或 lex 或 Watson 或他们本月推出的任何东西,只需简单的“服务台知识和个性”就可以放在上面,就像蛋糕上的糖衣。从根本上来说,这是行不通的:出于非常合理的商业原因,大玩家正在研究取代网页表单的机器人技术,这种偏见带来了许多限制性假设。
  • 许多初创公司(以及更大的公司)认为,如果你从内部网搜集到足够多的数据——例如分析 Confluence 中的每一篇文章——你就能够为用户提供完全正确的答案。其他人更进一步,试图刮公共论坛。这不起作用,因为首先,用户通常不能很好地解释他们的问题,所以没有足够的信息来理解用户想要什么;其次…你真的读过 IT 人员放入他们知识库的内容吗?
  • 有很多不同的事情可能出错,也有很多不同的方法来解决问题。如果你试图让你的支持聊天机器人完全自主,能够回答任何问题,你会花很多钱来处理可能永远不会再发生的奇怪的小案件。

我见过的最有希望的方法是我去年年底合作的一家初创公司采用的方法。当他们决定转向另一个方向时,我从他们那里买回了源代码。

关键的想法是这样的:如果我们的支持聊天机器人不能回答每一个问题——事实上它永远不会回答——那么聊天机器人必须有一种方法让人类来回答。如果一个人做出了回应,那么聊天机器人应该知道这是它应该做出的回应。如果聊天机器人可以学习,那么我们根本不需要做任何前期编程,我们可以让聊天机器人从过去的对话中学习。或者甚至让聊天机器人在刚打开的时候完全幼稚。

挑战在于,在支持聊天室中,通常很难理清支持团队的每个答案指的是什么。我已经实现了一些技术(例如,基于时间接近度的解开、@提及等等)。一种保守的方法是有一个单独的机器人培训室,只有准备干净的对话发生。采取这种方法意味着我们用昂贵的高薪程序员来代替编写代码来处理对话,用一个实习生来编写一些文本聊天。

找一个只想整天泡在聊天室的实习生其实并不难。

无论您采用哪种方法,您最终都会得到一个对话集:大量用户提问、从支持部门获得响应、阐明他们想要什么,然后获得答案的例子。

预测接下来要说的合适的话变成了一个机器学习问题:给定一个新的,否则看不见的数据 blob,预测它属于哪个类别。数据块是到目前为止在对话中说过的所有事情,类别是人工支持服务台代理最有可能作为响应说过的任何事情。

关于如何用自然语言文本来处理机器学习问题,有大量的研究文章和许多广为人知的最佳实践。在支持向量机、深度神经网络的 LTSM 架构、句子的 word2vec 嵌入中已经找到了好的解决方案。

事实证明,20 世纪 60 年代的技术非常有效,你可以在几个小时内编写出一个解决方案。我使用了一个词袋模型结合逻辑回归,我得到了相当令人满意的结果。(在这一点上,几乎任何严肃的数据科学家或人工智能大师都应该在后台窃笑,但请原谅我。)

单词袋模型认为,当用户提问时,你可以忽略他们所写内容的结构和语法,只关注关键词。如果用户提到“密码”,你可能甚至不需要知道这句话的其余部分:你知道这是哪种支持电话。如果他们提到“Windows”,下一个可能的回答几乎总是“你试过重启吗?”

如果你说的语言有 70,000 个不同的单词(包括缩写词在内的所有变体),那么你在聊天中键入的每条消息都会变成一个由 70,000 个元素组成的数组,其中大部分是零,有几个 1 对应于你在该消息中碰巧使用的单词。

支持代理说的第一句话很少是问题的完整解决方案。所以我为用户和代理添加了一个“记忆”。用户在说最后一句话之前说了什么?我通过指数衰减实现了这一点。如果你的“记忆”向量是 x,你最后说的是 y,那么当你说 z 的时候,我会把记忆向量更新为(x/2 + y/2)。那么你下一条消息之后,就会变成(x/4 + y/4 + z/2)。在预测接下来会发生什么时,你刚才说的事情渐渐变得不那么重要了。

将此与逻辑回归相结合,本质上,你为每个单词在每个上下文中的强度分配一个分数作为预测值。在你的上一封邮件中出现的单词“password”在密码重置的回复中得分很高,但是单词“Windows”在密码重置的回复中的预测能力很弱。即使在你的历史中看到“Linux”这个词,对“你试过重启它了吗”来说也是一个负面的强度预测,因为人类很少会给出这样的回答。

你在现有的数据语料库上训练逻辑回归器,它会计算强度矩阵。这是一个大矩阵:四个不同地方的 70,000 个单词(用户说的最后一句话,支持代理说的最后一句话,用户的记忆,支持代理的记忆)给你 280,000 列,你训练它的每个对话(可能是上千个对话)的每一步都是一行。

但没关系,这是一个非常稀疏的矩阵,现代计算机可以在千兆字节的数据上训练逻辑回归器,而不需要任何特殊的硬件。这个问题至少从 20 世纪 70 年代就已经被很好地研究过了,并且有大量的图书馆来有效地实现它。

这就是你所要做的,来制造一个惊人成功的聊天机器人。你可以调整聊天机器人在说话之前需要有多自信(例如,不要说话,除非你有 95%的信心你会像支持代理那样回应)。你可以列出优势矩阵,看看为什么聊天机器人在出错时选择给出答案。如果它需要学习更多的东西或者犯了错误,你可以给它另一个例子。

这种方法比雇佣一个开发人员和数据科学家团队要便宜得多,比依赖任何今天在这里,明天就过去的人工智能初创公司要安全得多,比调用由知名供应商运行的 web APIs 的系统更容易支持。

我在巴塞罗那的阿特拉斯营地做过这个演讲,希望今年晚些时候我能在圣何塞重复这个演讲。这是视频:https://youtu.be/YMW27HjJPAw

聊天机器人与现实:如何建立一个有效的聊天机器人,明智地使用自然语言处理

原文:https://towardsdatascience.com/chatbots-vs-reality-how-to-build-an-efficient-chatbot-with-wise-usage-of-nlp-77f41949bf08?source=collection_archive---------4-----------------------

第 1 部分:聊天机器人范例

本文是“聊天机器人的自然语言处理”系列的一部分:

  1. 聊天机器人范式(本帖)
  2. 如何建立一个聊天机器人使用拉沙 NLU
  3. 如何使用 Rasa 核心构建和改进聊天机器人
  4. 更深入:向 Rasa NLU 添加组件

我开始独立写这篇文章,但是很快它就失去了控制…所以:这是 4 篇文章系列的第 1 部分。它将讨论设计聊天机器人的常见范例。第 2、3 和 4 部分将展示构建这样一个 bot 的实际例子。

介绍

在研究了机器学习为聊天机器人提供的可能性一段时间后,我最近开始用 Interactbot 开发一个大型聊天机器人项目。因此,我决定写一系列的帖子,讨论和展示聊天机器人中 NLP 的一些能力和局限性。

在我看来,和图像问题一起,文本理解是现在机器学习的两大顶级任务之一(top 有点模糊……也许是从牵引力、努力度和兴趣度来说)。因此,对我来说,认真解决一个更有趣且未解决的问题是很有趣的。

然而,虽然图像任务令人印象深刻地一个接一个地解决了,但文本任务有点落后:开发一个合适的聊天机器人所需的真正好的对话技能甚至还没有接近解决。

Y 你可以在这篇文章中读到一些选定的 NLP 问题的(有些不成熟的)状态,这将在后面的帖子中讨论

所以你可能会想:“如果 NLP 有这么多挑战,为什么有人要投资聊天机器人?”在某种程度上,你可能是对的。甚至像苹果、亚马逊和谷歌这样的机器学习巨头也经常在对话界面上遭遇惨败(见下面的例子)。似乎机器学习还没有解决这类问题的答案。那么,为什么有人会因为商业原因而费心去开发聊天机器人呢?

A well-known example to Siri, a chatbot by Apple, common type of fail

原因是,就像在大多数基于机器学习的产品中一样:虽然你不能完美地做每件事,但你可以做一些有帮助的事情。例如,你不能建造一个聊天机器人来讨论生命的意义,或一个机器人来帮助解决一些复杂的问题,但你肯定可以建造一个聊天机器人来回答基本的互联网提供商支持问题,并通过明智的产品设计,将节省大量时间花在令人厌倦的电话菜单上。

因此,在这篇文章中,我将讨论聊天机器人的一些功能,以及我们试图缩小机器学习研究和生产之间差距的一些方法。

聊天机器人的能力和问题:瞄准哪里?

如前所述,机器学习的完整对话技能离我们很远,机器人仍然有用。想想 Siri、Google Home 和 Alexa,这是几个非常受欢迎的聊天机器人平台:尽管并不完美,但它们被许多人认为是非常好的产品。您可以使用它们来执行以下操作:(以及其他操作::

  • 安排会议
  • 点餐
  • 叫辆出租车

聊天机器人对于简单的对话任务也非常有用,比如(基本的)客户支持、内容发现,或者作为更智能的搜索引擎和更多的

现在想想你最后一次与支持代表交谈,第 1000 次向他解释你的问题,得到的回答是他重复了 10K 时间。

有许多单调的任务可以被一种基本的对话技巧所取代,包括几十/几百个指定的答案。

缺乏解决“对话技能”问题的能力,要求聊天机器人的构建者具有创造性,并设计一个任务流水线,当与一些业务规则和搜索启发相结合时,可能会产生一些有用的聊天机器人。

意图-实体范式

希望你能看到聊天机器人的潜力,尽管可能存在缺陷。现在让我们讨论如何建立一个。

聊天机器人和自然语言处理

虽然我没有明确地说,聊天机器人不一定有 NLP。如果在聊天机器人规模的一端有“完全对话机器人,它具有类似人类的对话技能,另一方面有确定性机器人,它具有基于许多 if-else 语句的预定义对话树(通常 3-4 层深)和“类似% x %”SQL 查询

An example for a conversation tree in Deterministic bot

从这个基本机制出发,NLP 可能在以下部分有用:

  • 用户输入/问题分类
  • 更好的单词/实体识别
  • 状态识别(我们在树中的什么位置)
  • 答案生成

解释了意图-实体范式

在做了一些研究之后,我发现一个很好的方法是意图-实体范例,正如它的名字所暗示的,它通过两个步骤工作:意图分类和实体识别。

我们假设我们知道我们在对话流中的位置,并忽略状态、内存答案生成,其中一些将在接下来的帖子中讨论。

这种范式有利于机器人的设计和培训工作,但不利于技术人员,并被大多数知名聊天机器人接口使用: wit.aiapi.airecast.ai 等。

这个概念可能不被认为是自然语言处理任务本身,而是自然语言处理任务的流水线。意图分类与文本分类相关,启动条件不同,实体识别与命名实体识别任务并行,这里也适用不同的条件。

让我们看一个例子。一个餐馆搜索机器人的例子,它松散地基于这里的基本例子。该机器人将具有以下可能的能力:

  • 餐馆搜索 —这意味着用户寻找特定的或一系列的餐馆。
  • 餐桌订单 —用户想在某家餐馆订购一张餐桌。
  • 一般查询 —用户有一个关于餐馆的特定查询,例如,它是否是素食友好的,或者它是否是犹太的。

此外,我们希望在用户查询中找到以下对象,如果提到的话:

  • 美食 —将代表美食类型,例如意大利、亚洲等。
  • 位置 —所需餐厅的位置。
  • 属性 —餐厅的属性,例如纯素食、犹太食品、准入

意图分类

在这个范例中,意图意味着用户查询的一般目的,例如,搜索一家企业或一个地方,安排一次会议,等等。

机器人应该对你的查询进行分类,并采取相应的行动(搜索一个地方,获得尽可能多的细节。用于安排会议、请求会议细节、出席者等。)所以很容易看出这是一个普通的文本分类挑战。

文本分类是一项经过充分研究的机器学习任务,然而,很大一部分研究是在宽松的问题设置上进行的,如情感分析。在现实世界中的机器人,你几乎从来没有少于 5 个可能的意图。

在不太具体的情况下,这种模型的精度取决于各种参数:

  • 意向计数 —一个应用的平均意向数量应为 5-10 个。意图越少越简单,而意图越多越不利于准确性。
  • 数据量 和质量 —我们都知道,在任何机器学习任务中,我们拥有的数据越多,越接近推理查询,我们就会有更好的结果
  • 转移学习的可能性— 转移学习,或者换句话说,如果可行的话,使用一个预先训练好的模型来解决类似的问题可能会非常有帮助
  • 推理输入大小——用户在查询我们的机器人时并不倾向于简洁。因此,文本汇总工具,其中包括提示用户简明扼要,将有助于我们的应用程序有更好的准确性

如果我们能够“优化”上述超级参数,我们通常能够在不太费力的情况下达到大约 80%的准确度,并将开始努力达到 90%的准确度,这是一个挑战,但可以轻松地认为是生产就绪。低于 80%的结果将导致令人沮丧的产品。

实体识别

文本中的实体可以是企业、位置、人名、时间等。一个在查询中有意义并且在 bot 逻辑中有进一步意义的对象。

实体识别本身也是一个众所周知的自然语言处理问题,这也是令人烦恼的问题之一:它非常强烈地依赖于数据集和试探法(例如,大写字母,问号)。

有很多解决这个任务的库,例如我最喜欢的 spacy ,它做得非常好。

在这里你可以看到 spacy 的一位创作者深入讨论了他们的 NER。

拉萨·NLU

前面提到过,Rasa NLU 是一个很好的开源库,可以用来查找文本中的意图和实体。

Rasa NLU illustration

当第一次在一个组织中处理机器学习问题时,使用现成的开源工具,然后围绕它构建一个良好的基础设施是一个很好的实践。

拉莎·NLU 声称会给你付费/黑盒图书馆(前面提到的)给你的东西,甚至更多。我必须承认,我只进行了一些基本的比较,但正如你将看到的,拉沙 NLU 的结果客观上是相当不错的。

此外,开源允许您查看代码,了解正在使用的方法(当您看到模型的简单性时,可能会有点失望),然后自己开发额外的组件(这个选项是可能的,但在 Rasa 中没有记录)

此外,组织看到了内部系统的高价值,开源的 rasa-NLU 提供了以此为基础,并在此基础上开发更多功能的能力。

起初,拉沙 NLU 看起来有点像一个黑匣子:用特定格式的小数据集训练模型,然后推断出意图和实体。

我必须承认,Rasa 的文档有时可能相当混乱,但几个小时的彻底检查代码将揭示它的大部分“秘密”。

数据

Rasa NLU 收到了大量的查询,并以以下格式标记了意图和实体:

{
  "text": "show me chinese restaurants",
  "intent": "restaurant_search",
  "entities": [
    {
      "start": 8,
      "end": 15,
      "value": "chinese",
      "entity": "cuisine"
    }
  ]
}

与所有机器学习问题一样,数据越多,得到的模型越好。然而,Rasa 的一些组件可能非常慢,并且在训练示例方面非常有限。另一方面,即使有几百个例子,合理的结果也开始出现。

基础模型

一般来说,Rasa 使用两种可互换的“语言模型”,即 MITieSpacy ,此外还有无处不在的 sklearn。

Mitie 和 Spacy 是彼此非常不同的库:第一个库使用更多的通用语言模型,因此训练非常慢,而 Spacy 使用更多的特定任务模型,训练非常快。

在 Interactbot 中,我们最初因为技术原因开始使用 MITie,但由于它的训练速度很快就转移到了 Spacy。两个软件包的结果非常相似。

管道

如前所述,RASA 基于 NLP 任务流水线。流水线不一定是线性的,不同的组件输出不同的东西。在这里可以找到(相当欠缺的)文档。

正如您在文档中看到的,可以手动装配管道,但建议从一个预定义的管道开始。让我们检查一下 Spacy-SKlearn 管道:

["nlp_spacy", "tokenizer_spacy", "intent_entity_featurizer_regex", "intent_featurizer_spacy", "ner_crf", "ner_synonyms", "intent_classifier_sklearn"]

这条管道有点杂乱,但重要的组件是intent _ classifier _ sk learn,它使用句子特征上的 SVM(基于 word2vec)以及预测实体的 ner_crf ner _ synonyms**。将在下一篇文章中进一步讨论。**

上述组件由“intent _ entity _ featurezer _ regex”(regex 特征)和“intent _ featurezer _ spacy”(word 2 vec 特征)提供特征。

结果

在文本上运行 Rasa 模型的输出将是下面的预测,应该进一步滚动到业务逻辑和数据库查询,以便为用户提供正确的答案:

**{
    "text": "I am looking for Chinese food",
    "entities": [
        {"start": 8, "end": 15, "value": "chinese", "entity": "cuisine", "extractor": "ner_crf"}
    ],
    "intent": {"confidence": 0.6485910906220309, "name": "restaurant_search"},
    "intent_ranking": [
        {"confidence": 0.6485910906220309, "name": "restaurant_search"},
        {"confidence": 0.1416153159565678, "name": "affirm"}
    ]
}**

摘要

在这篇文章中,这是该系列的第一部分,我们已经讨论了聊天机器人的意图-实体范式。我们熟悉了拉莎·NLU 的产品包,以及其中的一些模型。

在下面的帖子中,我们将学习如何用拉莎·NLU 和其他工具构建一个对话界面。我们还将讨论对所用模型的评价和改进。

在上一篇文章中,我们将集成新的包— Rasa Core,它将允许我们添加新的功能,如内存、图形推理和更多很酷的功能。

希望你喜欢这篇文章!如果是这样,请随时关注我这里或那里: TwitterLinkedIn

特别感谢 哈利·霍恩里奇 以及 互动机器人 中的所有伙计们

检查您对数据的假设

原文:https://towardsdatascience.com/check-your-assumptions-about-your-data-20be250c143?source=collection_archive---------2-----------------------

没有人喜欢糟糕的假设

The book (now in print!) has an awesome picture on the cover.

在这本书的节选中,我讨论了识别和检查你对正在处理的数据的任何假设的重要性。

节省 37 折 像数据科学家 用代码fccgodsey

不管我们愿不愿意承认,我们都会对数据集做出假设。我们可以假设我们的数据包含在特定的时间段内。或者,我们可以假设包含电子邮件的文件夹的名称是这些电子邮件的主题或分类的适当描述符。这些关于数据的假设可以是预期或希望,有意识的或潜意识的。

关于数据内容的假设

让我们考虑一下安然数据例子中的时间因素。当我开始查看这些数据时,我当然认为这些电子邮件会跨越从 20 世纪 90 年代末电子邮件出现到 21 世纪初公司倒闭的几年时间。由于日期格式中潜在的错误或损坏,我可能弄错了。实际上,我看到的日期远远超出了我假设的范围,还有其他一些有问题的日期。我对日期范围的假设当然需要验证。

如果我们想使用电子邮件帐户中的文件夹名称来通知我们其中的电子邮件内容,则有一个隐含的假设,即这些文件夹名称是信息性的。我们希望检查这一点,这可能需要大量的人工工作,例如阅读一堆电子邮件,并使用您的最佳判断来判断文件夹名称是否描述了电子邮件中的内容。

需要特别注意的一点是缺失数据或占位符值。我们倾向于假设——或者至少希望——数据中的所有字段都包含有用的值。但是,电子邮件通常没有主题,或者在“发件人”字段中缺少名称,或者在 CSV 数据中可能有“NA”、“NaN”或应该是数字的空格。检查这样的占位符值是否经常出现并导致问题总是一个好主意。

关于数据分布的假设

除了数据的内容和范围,我们可能对其分布有进一步的假设。老实说,我知道很多统计学家对这一部分的标题感到兴奋,但对其内容感到失望。统计学家喜欢检查分布假设的适当性。试试谷歌“常态测试”或者直接去维基百科页面,你就会明白我的意思。似乎有一百万种方法可以检验你的数据是否是正态分布的,这是的一种统计分布。

我可能会因为写这篇文章而被禁止参加所有未来的统计会议,但是:我通常没有那么严谨。一般来说,使用直方图或散点图来绘制数据可以告诉您想要做出的假设是否合理。例如,图 1 中的插图来自我的一篇研究论文,其中我分析了田径运动中的表现。图中是有史以来最好的男子 400 米成绩的直方图(取对数后),叠加的是正态分布曲线。顶级表现符合正态分布的尾部,这是我研究的关键假设之一,我需要证明这个假设。我没有使用任何正态性的统计测试,部分原因是因为我处理的是分布的尾部——只是最好的表现,而不是历史上的所有表现——还因为我打算使用正态分布,除非它明显不适合数据。对我来说,直观地比较直方图和正态分布图就足以证明这个假设。对于我的目的来说,直方图与钟形曲线足够相似。

Figure 1 The logarithms of the best men’s 400 m performances of all time seem to fit the tail of a normal distribution.

虽然我可能对田径数据的分布不太严格,但我不想轻视检查数据分布的价值。如果你认为你有正态分布的数据,而你没有,那么糟糕的事情就会发生。假设正态分布的统计模型不能很好地处理异常值,大多数流行的统计模型都假设正态性。这包括最常见的线性回归和 t 检验。当你的数据甚至不接近时假设正态性会使你的结果看起来很重要,而事实上它们是无关紧要的或错误的。

这最后一个陈述对任何统计分布都有效,不仅仅是正态分布。您可能认为分类数据是均匀分布的,但实际上某些类别出现的频率远远高于其他类别。社交网络统计数据,比如我从安然公司的数据集中计算出来的那种——电子邮件集的数量,一天内联系的人数,等等。众所周知是不正常的。它们通常呈指数或几何分布,这两种分布我都会在假设之前核对数据。

总而言之,跳过检查您的数据是否符合分布的统计测试是可以的,但是要小心,确保您的数据与任何假设的分布相匹配,至少大致匹配。跳过这一步对结果可能是灾难性的。

揭穿你假设的妙招

如果你觉得你没有假设,或者你不确定你的假设是什么,或者即使你认为你知道你的假设,试试这个:

向朋友描述您的数据和项目——数据集中有什么以及您将如何处理它——并写下您的描述。然后,剖析你的描述,寻找假设。

例如,我最初的项目涉及安然公司的数据,我可以描述为:

我的数据集是一堆电子邮件,我将使用社交网络分析的技术,通过人们的网络建立整个组织的行为模式。我想对员工的反应以及在层级“上”的沟通(即与老板的沟通)做出结论。

在剖析这种描述时,我首先识别短语,然后思考在它们下面可能隐藏着什么假设,例如:

  • “我的数据集是一堆电子邮件”——这可能是真的,但它可能值得检查一下,看看是否可能有其他非电子邮件数据类型,如聊天消息或通话记录。
  • “组织范围”——什么是组织?我们是假设它被明确定义了,还是有模糊的边界?它可能有助于运行一些关于组织边界的描述性统计,可能是具有特定电子邮件地址域的人,或者是写了超过一定数量的邮件的人。
  • “行为模式”——你对什么构成“行为模式”有什么假设?是否每个人都需要从事相同的行为才能被宣布为“模式”,或者我们是否有一组模式,可以与单个示例进行比较,以找到与这些模式匹配的模式?
  • “人际网络”——网络中的每个人都需要被连接起来吗?会有没有联系的人吗?我们是否计划从社会网络分析文献中假设某种统计模型;它需要某些假设吗?
  • “响应性”——我们假设这个术语是什么意思?我们能否用统计学的方法定义它,并通过使用基本定义和一些描述性统计来验证数据是否支持这样的定义?
  • “层级”——我们是否假设我们对组织的层级有完整的了解?我们假设它是刚性的,还是变化的?

意识到我们在做假设的时候——通过剖析我们的项目描述,然后问这样的问题——可以帮助避免以后的许多问题。我不想在完成分析,发现奇怪的结果,然后回去调查之后才发现一个关键假设是错误的。更重要的是,我不希望一个关键的假设是错误的,却从来没有注意到它。

要了解更多信息,请下载免费的第一章 像数据科学家 一样思考,并查看此 幻灯片演示文稿 了解更多信息和折扣代码。

Brian Godsey 博士是一名数学家、企业家、投资者和数据科学家,他的著作 像数据科学家一样思考 现已有印刷版和电子书。——【briangodsey.com】

如果你喜欢这个,请点击💚下面。

**[## 通过问好问题来设定目标

数据科学和入门艺术

medium.com](https://medium.com/@briangodsey/setting-goals-by-asking-good-questions-2fdce0c91423)**

用 t-SNE 检验降维

原文:https://towardsdatascience.com/checking-out-dimensionality-reduction-with-t-sne-78309b2ca67d?source=collection_archive---------7-----------------------

今天我探索了在两个高维数据集上应用 t-SNE:经典的 MNIST 和新时尚主义者。

你可以在这里阅读所有关于 fashionMNIST 的内容,它被设定为复杂程度更高的 MNIST。

MNIST 包含从 0 到 9 的手写数字,而 fashionMNIST 包含从 t 恤到裙子到裤子的 10 种不同的服装。

我在 MNIST 的整个原始训练集上运行了 t-SNE,这是相当好的分离,并与 fashionMNIST 进行了比较。

MNIST in 2D

并在 fashionMNIST 中观察到一些重叠。

fashionMNIST in 3D

我们可以在 plotly 中进一步旋转它,并删除明显分开的类,以识别重叠的类:t 恤,衬衫和外套。

这是我关于数据科学和视觉故事的# 100 日项目的第 53 天。我的 github 上的全部代码。感谢阅读。欢迎新主题的建议和反馈。

Check Mate 深度学习

原文:https://towardsdatascience.com/checkmate-deep-learning-fb86fa044d60?source=collection_archive---------4-----------------------

人机交互如何打败深度学习。

Human vs Robot, by Frank Steiner, CC-BY-SA-4.0

深度学习正在主导这些天的人工智能新闻。人们看不到的——深度学习是可以被打败的。不要误解我。深度学习很奇妙。它开辟了机器学习的新领域。它惊人的图像结果给数据科学家和感兴趣的公众留下了深刻的印象。除了图像分析,您还可以在文本和时间序列分析领域发现有趣的新结果。所有这些都很棒;但被高估了。Kaggle 最近的一篇文章显示,线性回归方法击败了神经网络。那么诀窍是什么呢?如何能轻松检查 mate 深度学习?

深度学习不那么秘密的酱料

现代神经网络体系结构具有一些重要的特征,这些特征使它们在许多用例中获得成功。它们能够解决非线性问题,善于接收复杂的输入,并且能够在内部进行特征选择。

最常被引用的秘密是内部特征生成。深度学习架构在其节点中为自己构建了新的参数。你可以把它归结为一句简单的话:

在深度学习中,架构工程是新的特征工程 Stephen Merity ,Salesforce 的高级研究科学家

虽然这是一个优点,但它引入了更多的自由度。这最终会产生一个问题,即您需要输入足够的信息来设置这些自由度。值得注意的是,信息必须来自更多的线,而不是更多的特征。事实上,更多的功能使问题变得更加困难。这被称为维数灾难。

真实生活的例子

在实践中,您经常会遇到记录的例子数量有限的用例。我最近有一个用例,在那里我处理书面的维护记录。工程师正在记录维修原因。那是在大型机器上,那里没有数百万台机器。这导致了几百行错误。用例是为了确定与其他部门的相关性。

将这些记录输入深度学习算法并没有产生任何好的结果。维护记录中的语言富含用例相关的术语。有限的行数阻止了深度学习结构学习底层因素。

通过特征工程传递知识

我们确实知道零件 v 120–3 和 v 120–4 属于同一类型。所以我们可以用一个令牌 V120 来代替两者。我们所做的是通过生成新的特征将世界的知识转移到模型中。

虽然这听起来微不足道,但它有两个迷人的方面。首先,这种特征工程可以降低问题的复杂性和非线性。我们手动“设置”模型的自由度。斯科特·凯勒的线性回归有很多工程特征。我认为这种线性回归就是用一种非常类似于 SVM 中手工制作的内核的方法来解决非线性问题。

另一个更重要的部分是,我们输入关于世界的信息。原始数据中不包含此信息!我们将关于同义词或关系的信息转移到模型中。这是特征工程所独有的。我们确实有像 word2vec 或 GloVe 这样的自动方法来尝试获取单词的意思。但是都需要数据。如果你没有相应的数据,你就无法提取这些模式。另一方面,人类知道这些关系,并能把它输入进去。检查队友?

大数据拯救世界;不是!

解决数据有限问题的一个常见答案是大数据。但(可悲的是)这通常没有任何帮助。让我们在机器上安装大量的传感器。这些传感器连接到云环境。我们现在可以分析万亿字节的数据;这很酷,但很可能没有帮助。

我们正在重新研究这几百个例子,工程师写下了发生的事情。当然,我们可以用更多关于机器状态的信息充实每一行。但是我们没有生成更多相关的行。大数据往往并不意味着大样本量,而是每行包含大量信息。

迁移学习——答案?

深度学习挨打了吗?说实话,也不尽然。在深度学习的前沿,许多科学家正在尝试为深度学习结构进行迁移学习。一个关键的想法是将单词之间的关系或潜在的图像模式转移到其他用例中。这个想法是,识别图片中的一条线的网络也可能在其他应用中有用。

这个深度学习领域正在后院兴起。但迟早会冲击商业应用。如果你对如何在深度学习中进行迁移学习感兴趣,请看看 Sebastian Ruder 的精彩博文。

“Cherchez la Tech”或如何增加你发现今天的谷歌的机会

原文:https://towardsdatascience.com/cherchez-le-tech-or-how-to-increase-your-chances-of-spotting-the-google-of-today-200ece78f690?source=collection_archive---------9-----------------------

为早期投资者制定投资方案的系统方法

摘要

“软件正在吞噬世界”,安德森·霍洛维茨公司的马克·安德森有句名言。我完全同意。然而,世界很大,有很多软件。如果你是一个有抱负的技术投资者,对行业有一些不可知的看法,你从哪里开始呢?你能在 1999 年发现谷歌,2005 年发现脸书,2010 年发现优步,或者 2011 年发现 DeepMind 吗?

考虑一个我半开玩笑地称之为“Cherchez la Tech”的框架,它有三个关键部分:

  1. 一项成熟的技术,
  2. “随时准备颠覆”的部门,以及
  3. “最佳交付”商业模式

颠覆始于某项面向大众应用的技术的成熟,这项技术必须既有效又足够便宜。一旦确定了技术,寻找特定技术有潜力创造新产品和服务或使现有产品和服务更快、更好或更便宜的部门和更重要的部分。最后,选择一个最适合在你所选择的领域提供技术的商业模式。

“Cherchez la Tech” framework, Cornel Chiriac

请继续阅读,了解更多详情。

技术:圣杯

技术为选择行业细分和商业模式焦点提供了强有力的指导,两者都遵循。作为这个过程的第一步,我问自己“现在什么技术正在成熟?”时机是相关的,因为已经成熟的技术很可能实现了先进的商业应用。空间将会或开始变得拥挤,新来者将处于不利地位。

回到 90 年代末。个人电脑在美国的渗透率超过了 50% ( Pegasus Research ),互联网的使用处于大规模采用的边缘,很快接近 50%的采用率大关(互联网实时统计)。成熟的互联网接入技术为网上超市(如亚马逊)和世界信息的组织者(如谷歌)铺平了道路。它还允许“车库销售”走向全球(如易趣),通过可信的方法(如贝宝)完成交易。那个时代的远见者抓住了技术成熟的机会。一旦他们开始,很少有人加入他们在同一空间的金字塔顶端的行列。未来的大部分现金流已经分配出去了。

快进到 2000 年中期,社交网络革命正在进行。这是社会行为因素综合作用的结果,如个人在日益增长的技术、全球化和个人对拓展和社会友谊的渴望中的孤立。科技使之成为可能。同样的技术进步在 90 年代末引发了在线商务的发展,让人们能够相互联系和分享经验。如果有人在那个阶段发现了这一趋势,并在 MySpace、Friendster、脸书和其他几个人之间平均分配 10 万美元,那么今天的结果将是数百万美元(约 5000 万美元),尽管脸书是唯一一个站在人群中的人。当然,有很多方法可以增加投资成功初创企业的机会,但这是有据可查的,这篇文章的重点是“空间”而不是“空间内的目标”

那么,如何知道哪种技术正在成熟呢?下面的列表(Tech 2.0)是对主导初创企业生态系统或即将进入市场的技术的广泛当前指示。外面还有更多。订阅技术博客,了解最新动态。跟踪顶尖大学的研究成果(例如麻省理工学院、加州理工学院和我自己的母校芝加哥大学)。阅读思想领袖的作品,比如彼得·迪亚曼迪斯的指数技术。例如,跟随该领域的专家,如 Yann LeCun、吴恩达、Geoffrey Hinton 和其他机器学习专家。

“Technology commercialisation”, Cornel Chiriac

举一个例子——机器学习——我们正在见证这个领域前所未有的进步。随着机器学习算法在图像识别和语言处理等专业任务上变得比人更好,我们可以看到这些进步为许多高价值行业带来了颠覆。这让我想到了下一步——关注一个对商业采用成熟技术阻力最小的大行业。

扇形:阻力最小的路径

“我想投资一家使用机器学习的初创公司。现在怎么办?”这种追求本身愚蠢地进入了无数急于吹捧“我们是扰乱 X 部门的人工智能初创企业”的创始人圈子。机器学习本身不是目的,而是达到目的的手段。虽然机器学习只是一种用于构建智能企业的工具,但它可以作为筛选下一个可能经历革命的行业的起点。那么,应该怎么做呢?

在选择行业重点时,问问自己:

  1. 在哪个部门和分部门,一项特定的成熟技术会将现状提高一个数量级?
  2. 行业(机会的大小)是否足够大?
  3. 它为技术采用做好准备了吗?

一种观点将这一领域分为数字化和欠数字化两部分。麦肯锡 2015 年的一项研究指出,美国 65%的部门(按 GDP 份额计算)数字化不足。数字领导者平均为其底线增加了 6%至 11%,而落后者则保持不变或利润下降(衡量 1993 年至 2013 年)。这两个群体在美国国内生产总值中占有相似的份额——分别为 30%和 35%。“机会的大小”是可比的,因此数字化水平的差异是由于“采用的准备程度”。尽管领导者很早就接受了技术创新,落后者却没有。然而,潮流正在改变,我们看到越来越多的资本流入“无聊”的行业,颠覆了它们(正如 CB Insights 经常指出的)。彻底改变传统的、数字化不足的业务的机会是巨大的,这个空间作为一个整体资产配置类别是有意义的。从低基数开始,数量级的飞跃更容易。我们很可能会看到新的技术巨头在突破性技术的推动下出现在这些领域。

资料来源:麦肯锡全球研究院,2015 年 12 月( 链接 )

话虽如此,这个游戏通常是在子行业层面上进行的。在高度数字化的行业中也有“绿色领域”的机会,尽管它们可能更难找到。成功的初创企业可能会为自己赢得一席之地,但很快就会被现有的科技巨头之一吞并(这是一个不错的结果)。然而,这种战略不太可能让一家初创企业成为科技巨头。现任者已经获得了相当大的权力来控制最大的份额,而新来者如果不被收购,很可能最终会失败。

为了举例说明技术进步如何改变一个行业,让我们看看医疗保健。医疗保健是前面提到的麦肯锡研究中提到的数字落后者之一。计算机视觉和图像处理的技术发展对成像和诊断的医疗保健领域产生了革命性的影响( CB Insights )。计算机视觉技术成熟的早期迹象可以追溯到 2009 年,当时 ImageNet 在一个免费提供给计算机视觉研究的数据库中收集了 1500 万张图像。在 2012 年,谷歌大脑发现了一只猫,没有任何标签数据的帮助。2014 年,谷歌收购了机器学习初创公司 Deep Mind,该公司在该领域取得了令人印象深刻的成果。2016 年,谷歌 DeepMind 与 NHS 合作,利用机器学习对抗失明。人工智能很可能将计算机辅助青光眼诊断带入现实,并预防 98%的最严重视力丧失病例(眼科时报)。

资料来源:CB Insights《医疗保健中的 AI》,2016 年 9 月( 链接 )

发现 2009 年至 2010 年计算机视觉技术的进步,并将这些进步与成像和诊断应用联系起来,会直接帮助投资者押注于一个即将被颠覆的领域。

商业模式:最佳递送代理

这个相对简单。一旦缩小了技术和部门的关注范围,接下来的任务就是确定哪些模型最有可能服务于业务。

在过去二十年里,商业模式从简单的电子商务结构发展到旨在实现网络效应的市场,最后发展到 SaaS(尽管它主导了电信业几十年,但仍是初创企业的宠儿)。由于技术的进步,它们像部门一样进化。如果没有编程语言的优雅、基础设施(高性能计算、计算堆栈本身、存储)和连接速度的进步,SaaS 在当前的采用规模下是不可能实现的。看起来,SaaS 以其各种各样的方式主导着当前的风险投资环境。暂时如此。

“Business model evolution in the start-up ecosystem”, Cornel Chiriac

Greylock Partners 的陈佳瑞在“新护城河”中介绍了“智能系统”的概念,作为下一个可防御的商业模式。陈认为,强大的技术,如机器学习(ML),将与数据、业务流程和企业工作流相结合,以创建一个智能系统的环境。例如,陈将谷歌定位为将 ML 应用于流程和工作流的早期先驱:谷歌收集了更多关于每个用户的数据,并应用机器学习在网络搜索的工作流中提供更及时的广告。

出处:“ 【新护城河】 ”,灰锁伙伴的陈佳瑞

Gil Dibner 进一步发展了智能系统的概念,并将其作为一个新兴的风险投资元论题。网络效应作为有意义的进入壁垒的时代正在结束。技术可能正在经历价值倒置。吉尔的最后声明称,“在评估‘智能系统’公司的价值时,我们必须关注该公司正在创建的特定系统所造成的进入壁垒。价值不会仅仅来自于“智力”。价值在系统本身。”

确定最适合建立有意义的进入壁垒和建设智能企业的商业模式,可以为投资者指明钟形曲线前方的空间。在关于如何构建企业的无数选择中,只有一个最佳选择。确定最佳选择是一个过程,涉及对技术、其行业应用和行业本身的深刻理解。

结束语

软件将继续蚕食世界。在早期技术投资的大量机会中,专注、时机和深入的尽职调查是最重要的。在投资者将资本分配给机会并对特定目标进行尽职调查之前,最好设定“在哪里玩”的界限。我相信,技术将继续充当探路者,并在以最佳方式应用于成熟行业时,引领公司和投资者获得更高的经济回报。Cherchez la Tech,你可能会发现在选择行业和商业模式的重点清晰。

我很想听听你的想法,

山茱萸

__

特别感谢韦弗利·多伊奇费尔南德·伦多耶维多利亚·鲁斯纳克弗拉德·卡拉教授在撰写本文时提供的宝贵反馈。

__

以上帖子并非投资建议。所有观点,如果没有出处,都是主观的。这篇文章表达了对行业层面资产配置的看法,不涉及任何与目标尽职调查相关的话题。请在投资前进行彻底的尽职调查,并在适用的情况下寻求专业的投资、法律和会计建议。

樱桃树和全球变暖:开花还是不开花?

原文:https://towardsdatascience.com/cherry-tree-and-global-warming-to-bloom-or-not-to-bloom-23176eba32eb?source=collection_archive---------3-----------------------

T 他的回答似乎是“要开花”,请让我再加上“越来越早”。在京都,一个美丽的日本城市,也因春天盛开的樱花而闻名,几乎是一个真实的事实,春天每年都开始得越来越早。

由于 Aono,Kazui 和 Saito 的精心工作,京都樱花开花的历史系列物候数据可以通过上面的链接提供给每个人。据我所知,这个物候数据集在世界上是无与伦比的,因为它跨越了 1000 多年的时间!

“我从历史时期京都的皇帝、贵族、统治者和僧侣写的许多日记和编年史中搜索和收集了樱桃树(樱花)完全开花日期的物候数据。举行樱花观赏会或观察到樱花盛开的日期是从旧文献中收集来的。在这一页,你可以看到自 9 世纪以来京都樱花盛开的一长串物候数据。”青野康之。

数据科学的激情与对自然的热爱混合在一起,加上几行 Python 代码,产生了下面的情节。x 轴代表公元年,从公元 812 年开始。y 轴计算自每年 1 月 1 日以来经过的天数。对于有物候数据的每一年,开花日期用一个蓝点表示。正如你所看到的,波动性很大,但是取一个滚动的平均值来说明开花日期的趋势:这是红色曲线。浅蓝色区域代表平均值周围的+/- 1.96 标准偏差范围。红色曲线越低,樱桃树开花越早,反之亦然。

Plot of the whole Historical Series of Phenological data for Cherry Tree Flowering at Kyoto City

从公元 1825 年前后开始,滚动平均值显示出明显的下降趋势:平均而言,樱花每年开花越来越早。这是因为全球变暖还是仅仅因为当地天气或气候的影响?

在公元 1250 年至 1750 年之间缩放,显示出平均开花相对较晚的三个时期:它们或多或少以公元 1350 年、公元 1540 年和公元 1680 年为中心。它们与分别开始于公元 1315 年、公元 1550 年和公元 1650 年的欧洲小冰期有密切关系吗?也许是的…

Zooming between 1250 AD and 1750 AD. Are peaks related to the Little Ice Ages?

参考

Aono 和 Kazui,2008;Aono 和 Saito,2010 年

Aono 和 Kazui,2008;Aono 和 Saito,2010 年

2012 Aono(2012;全球环境,17,21–29)

http://atmenv.envi.osakafu-u.ac.jp/aono/kyophenotemp4/

ChiPy 数据科学导师,pt。一

原文:https://towardsdatascience.com/chipy-data-science-mentorship-pt-1-aa4972f8148e?source=collection_archive---------6-----------------------

这篇文章是关于我作为数据科学项目 ChiPy 导师项目的学员经历的三部分系列文章的第一部分。ChiPy 是芝加哥 Python 用户组的简称,是一个由才华横溢、热情洋溢的个人组成的社区,他们因对编程语言 Python 的欣赏而聚集在一起。这个小组的热情和兴奋是更大的 Python 社区的缩影,也是我发现 Python 如此吸引人的部分原因。

我是在参加大会的数据科学沉浸式项目时接触到 ChiPy 的,在这个项目中,我们使用 Python 编写大部分代码。在我的第一次 ChiPy meetup 上,我了解了导师计划,并急切地申请了学习更多 Python 知识和融入社区的机会。鉴于我相对来说还是一个编程新手,我很感激有机会在社区环境中继续学习。

我的导师

当我得知 GrubHub 的高级数据科学家 Kevin Goetsch 被指定为我的导师时,我激动万分。我已经有机会与 Kevin 会面,因为他和我的 GA 导师以前是 Braintree 的同事,并且看过他的 PyData 关于使用 Scikit Learn 进行流水线操作的演讲。谈到编程,我真的很欣赏 Kevin 的精神:他是工具不可知论者,相信一个好的、工作的模型比一个永远不会被使用的完美模型更好,并且专注于产品如何被清洁地生产。实际上,蒂姆·古恩“让它工作”的编程方法。

项目

我的项目的指导问题是:我们能否在一款啤酒投入生产之前预测它在 Untappd(一个致力于啤酒的有影响力的社交媒体平台)上的评级?第二个问题是——这切中了数据科学的核心——我们为什么要在乎?

我们必须先回答后一个问题,以便为前者制定一个进攻计划。如果原因的答案是“因为我想知道哪些 IPA 最受欢迎”,那么我们可以进行一些数据分析,并将我们的数据科学工具箱放在棚子里。如果答案是,“因为我希望我生产的啤酒在 10 次评级后被评为 4 星或更高”,那么在我们的模型中包括 100,000 次评级的啤酒可能没有意义。

为了这个项目,我们将假设原因如下:

我们希望能够为不同的啤酒厂提供关于他们即将推出的啤酒的建议,并就他们如何在 Untappd 上获得更高的评级提出建议。

Sample Untappd beer entry; target variable in red

为了做到这一点,我们需要建立一个模型,可以准确预测啤酒的评级。这个问题可以分成四个不同的部分:

  1. 从未开发的目标变量(啤酒等级)和潜在特征中获取数据
  2. 数据清理和探索性数据分析
  3. 迭代模型测试和持续特征工程
  4. 将训练好的模型嵌入到 webapp 中,以按需提供预测

目标

在本次导师计划结束时,我希望完成以下工作:

Trying to avoid this

  • 打造我的 Python 流畅性!更加熟悉不同的结构,写更多的文章
  • 通过带有请求和漂亮汤的网络抓取来获取数据
  • 用我以前没用过的库可视化我的结果
  • 成功实施尖端的机器学习技术,如神经网络和极端梯度推进,并将其功效与行业标准进行比较
  • 通过将我的模型构建到一个 Scikit-Learn 管道对象中并对其进行酸洗,从而将它生产化
  • 通过构建一个 Flask 应用程序来提供预测,我尝试了一下 web 开发

关于我

我最近从 DC 的华盛顿州搬到了芝加哥。在此之前,我在北卡罗来纳州的戴维森学院获得了比较文学学位。我对数据科学感兴趣,因为它是一种发现的手段和一种讲故事的方式(我肯定这里面有一个很好的中间笑话)。我生在丹佛,长在丹佛,现在仍然对人们认为它有多酷感到惊讶。不出所料,我喜欢啤酒。

请继续关注第 2 部分!

当…时,选择很容易

原文:https://towardsdatascience.com/choices-are-straightforward-when-everyone-does-what-they-were-supposed-to-do-61b4b5ebdd28?source=collection_archive---------9-----------------------

每个人都做了他们应该做的事。不幸的是,我们每天面对的大多数决定都是针对那些不完全按照计划进行的情况。

让我们假设它的季后赛时间,篮球馆挤满了人。第 22 区的 250 名球迷都购买了半场附近的指定座位。然而,一名青少年在开球前两个小时决定和他的朋友坐在第三排,而不是自己的座位。之后,粉丝们鱼贯而入,试图坐在自己的座位上,但如果他们的座位已经被占了,他们会在这个区域随机选择一个座位。你工作到很晚,不幸地在比赛开始后到达,发现只剩下一个座位——号码被人群遮住了。选择坐在最后一个座位上,实际上是选择了一个你没有购买的座位,这有什么风险?

管理不是告诉人们做什么,而是帮助他人做出最好的选择。与缺乏数据相比,人们的决策往往会受到对风险不确定性模糊性的认知的阻碍。在日常生活中,风险与避免“糟糕”的选择——我们对形势的客观看法——联系在一起。风险方面的传统权威弗兰克·h·奈特(Frank H. Knight)谈到了事件和备选方案的分类既客观又可知的情况。风险可以被定性为“客观的”这一事实假定决策者理解他或她所面临的问题的性质。

如果风险的概念假设决策者感知清晰的选择,那么不确定性对应于选择不清晰和/或其后果难以衡量的情况。两个人对于一个给定的事件可能有不同的概率信念,如果一个人不能使另一个人相信他的方法是错误的,不确定性来自于“状态的穷尽分类的不可能性”。类似地,任何利用当前事件来预测未来的尝试,很大程度上都是基于判断和直觉——因此从定义上来说是主观的。决策者面对的是主观概率,因为未来是未知的——我们不仅不知道某些事件的概率,也无法合理预测潜在事件的范围。

模棱两可是由于缺乏明确的上下文而产生的。模糊决策是指决策者没有足够的信息来确定他或她的直觉是正确的。模糊性是指决策者对他或她所感知的事物的信念以及他或她对风险的态度。情况从来都不是模棱两可的,但是我们对情况的看法可能是模棱两可的。因此,歧义可以有多种解释:它是人们偏好和行为的一种属性,而不是语境本身。如果我们改进决策的过程,我们就会减少模糊的感觉。

管理就是做出更好的决定,不管是你自己的还是你周围的人的。改善决策需要处理判断失误的根源:风险、不确定性和模糊性。在处理风险时,我们需要确定一个问题或机会的预计成本和收益的可验证数据。在处理复杂问题分析中的不确定性时,我们需要了解概率的基本原理,以便做出更好的选择。为了减少模糊性,我们需要了解手头数据的质量,我们面临的问题的性质,以及哪种方法将产生最好的结果。如今的管理挑战与其说与我们可支配的数据和软件数量有关,不如说与我们改善决策背后的心理过程的能力有关。

你应该过度担心篮球比赛迟到和找不到指定座位的风险吗?这个问题类似于 Brett Berry 在最近的一篇文章中提出的飞机概率问题。在分析你所掌握的数据和问题的性质时,无论你是在比赛前一个小时到达还是晚到了几分钟,你的座位都有 50%的机会被占用。如果座位是由球迷随机选择的,你将有 1/250 的机会获得自己的座位。然而,这里的情况并非如此,因为粉丝们只是在自己的座位已经有人的情况下才随机选择座位。这意味着很可能有一半的情况会自行解决(一个没有找到自己座位的球迷会选择青少年的场边座位),而另一半会在其他人的位置上结束。不管你什么时候到达竞技场,你都有百分之五十的可能性找到你的座位。

改善管理决策是商业分析研究所的核心和灵魂。在巴约纳的暑期学校,以及在欧洲的大师班,我们让分析为您和您的组织服务。该研究所专注于数据科学在管理人员中的五个应用:在数字时代工作、数据驱动的决策、机器学习、社区管理和视觉通信。培养你做出更好决定的能力会对你未来的工作和职业生涯产生影响。

【我】贝里,b .(2017)。飞机概率问题,medium.com,https://medium . com/I-math/solving-an-advanced-Probability-Problem-with-virtually-no-math-5750707885 f1

Lee Schlenker 是 Pau 商学院的教授,同时也是商业分析学院http://baieurope.com的负责人。他的 LinkedIn 个人资料可以在wq 查看。你可以在推特上关注我们,网址是【https://twitter.com/DSign4Analytics】

选择正确的编码方法——标签与 OneHot 编码器

原文:https://towardsdatascience.com/choosing-the-right-encoding-method-label-vs-onehot-encoder-a4434493149b?source=collection_archive---------1-----------------------

您选择的编码如何在您的预测模型中发挥重要作用

Gateway Of India- Mumbai, India Pic by Rahil Hussain Shaikh

在最大似然模型中,我们经常需要将分类的,即文本特征转换成数字表示。两种最常见的方法是使用标签编码器或 OneHot 编码器。然而,大多数 ML 新手并不熟悉编码的选择对他们的模型的影响,通过在正确的场景中使用正确的编码,模型的准确性可能会有很大的变化。

在这篇文章中,我们将一步一步来

  1. 了解标签和 OneHot 编码。
  2. Python 中使用标注和一次热编码对预测准确性影响的实际示例。

了解标签和 OneHot 编码。

让我们了解 Label 和一个 hot 编码器的工作原理,并进一步了解如何在 python 中使用这些编码器,以及它们对预测的影响

标签编码器:

使用 Sklearn 库可以实现 Python 中的标签编码。Sklearn 提供了一个非常有效的工具,用于将分类特征的级别编码成数值。用 0 和 n_classes-1 之间的值对标签进行编码,其中 n 是不同标签的数量。如果某个标签重复,它会将之前分配的相同值分配给。

考虑下面的例子:

如果我们必须将这些数据传递给模型,我们需要使用 Label Encoder 将 Country 列编码成它的数字表示。应用标签编码器后,我们将得到如下结果

The categorical values have been converted into numeric values.

这就是标签编码的全部内容。但是取决于数据,标签编码引入了新的问题。例如,我们将一组国家名称编码成数字数据。这实际上是分类数据,行与行之间没有任何关系。

这里的问题是,由于同一列中有不同的数字,模型会将数据误解为某种顺序,即 0 < 1 <2。

该模型可能会得出一种相关性,如随着国家数量的增加,人口也会增加,但这显然可能不是其他一些数据或预测集中的情况。为了克服这个问题,我们使用一个热编码器。

一个热编码器:

现在,正如我们已经讨论过的,根据我们拥有的数据,我们可能会遇到这样的情况,在标签编码后,我们可能会混淆我们的模型,认为某一列具有某种顺序或层次结构的数据,而我们显然没有它。为了避免这种情况,我们对该专栏进行了“一个酒店编码”。

一种热编码的做法是,获取一个包含分类数据的列,该列已经过标签编码,然后将该列拆分为多个列。数字由 1 和 0 代替,这取决于哪一列有什么值。在我们的示例中,我们将得到四个新列,每个国家一列—日本、美国、印度和中国。

对于第一列值为日本的行,“日本”列将为“1 ”,其他三列为“0”。同样,对于第一列值为美国的行,“美国”列为“1 ”,其他三列为“0 ”,依此类推。

OneHot encoded country values.

关于使用标注和一个热编码对预测的影响的 Python 实例。

我们将使用医疗成本个人数据集来预测基于各种特征的汽车医疗费用,您可以从这里下载数据集。本博客使用的数据只是一个样本数据,但通过均方根误差评估预测结果,可以清楚地看到预测结果的差异,rmse 越接近 0,模型预测越好。

我们将运行 xgboost 回归算法模型(您可以使用您选择的任何回归算法),并使用标签编码器预测价格,然后使用一个热编码器并比较结果。

我从 insurance.csv 文件中取出了最后 37 条记录,并创建了一个新的文件 insuranceTest.csv,以预测对看不见的数据的收费。

代码片段:

import pandas as pd
import numpy as np
import xgboost
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import LabelEncoder
from math import sqrt
from sklearn.metrics import mean_squared_errordata = pd.read_csv('D://Blogs//insurance.csv')testdata = pd.read_csv('D://Blogs//insuranceTest.csv')mergedata = data.append(testdata)
testcount = len(testdata)
count = len(mergedata)-testcount
X_cat = mergedata.copy()
X_cat = mergedata.select_dtypes(include=['object'])
X_enc = X_cat.copy()#ONEHOT ENCODING BLOCK#X_enc = pd.get_dummies(X_enc, columns=['sex','region','smoker'])

#mergedata = mergedata.drop(['sex','region','smoker'],axis=1)#END ENCODING BLOCK# =============================================================================
# #LABEL ENCODING BLOCK
# 
X_enc = X_enc.apply(LabelEncoder().fit_transform) #
mergedata = mergedata.drop(X_cat.columns, axis=1)
# #END LABEL ENCODING BLOCK
# 
# =============================================================================FinalData = pd.concat([mergedata,X_enc], axis=1)
train = FinalData[:count]
test = FinalData[count:]
trainy = train['charges'].astype('int')
trainx = train.drop(['charges'], axis=1)test = test.drop(['charges'], axis=1)
X_train,X_test, y_train,y_test = train_test_split(trainx, trainy, test_size=0.3)clf = xgboost.XGBRegressor()
clf.fit(X_train,y_train)
y_testpred= clf.predict(X_test)
y_pred = clf.predict(test)dftestpred = pd.DataFrame(y_testpred)
dfpred = pd.DataFrame(y_pred)rms = sqrt(mean_squared_error(y_test, y_testpred))print("RMSE:", rms)

RMSE 的产量:RMSE:18960 . 688888886867

现在,让我们取消注释代码片段中的一个热编码器块,注释标签编码器块见 RMSE

import pandas as pd
import numpy as np
import xgboost
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score, confusion_matrix
from sklearn.preprocessing import LabelEncoder
from math import sqrt
from sklearn.metrics import mean_squared_errordata = pd.read_csv('D://Blogs//insurance.csv')testdata = pd.read_csv('D://Blogs//insuranceTest.csv')mergedata = data.append(testdata)
testcount = len(testdata)
count = len(mergedata)-testcount
X_cat = mergedata.copy()
X_cat = mergedata.select_dtypes(include=['object'])
X_enc = X_cat.copy()#ONEHOT ENCODING BLOCKX_enc = pd.get_dummies(X_enc, columns=['sex','region','smoker'])mergedata = mergedata.drop(['sex','region','smoker'],axis=1)#END ENCODING BLOCK# =============================================================================
# #LABEL ENCODING BLOCK
# 
#X_enc = X_enc.apply(LabelEncoder().fit_transform) #
#mergedata = mergedata.drop(X_cat.columns, axis=1)
# #END LABEL ENCODING BLOCK
# 
# =============================================================================FinalData = pd.concat([mergedata,X_enc], axis=1)
train = FinalData[:count]
test = FinalData[count:]
trainy = train['charges'].astype('int')
trainx = train.drop(['charges'], axis=1)test = test.drop(['charges'], axis=1)
X_train,X_test, y_train,y_test = train_test_split(trainx, trainy, test_size=0.3)clf = xgboost.XGBRegressor()
clf.fit(X_train,y_train)
y_testpred= clf.predict(X_test)
y_pred = clf.predict(test)dftestpred = pd.DataFrame(y_testpred)
dfpred = pd.DataFrame(y_pred)rms = sqrt(mean_squared_error(y_test, y_testpred))print("RMSE:", rms)

RMSE 的产量:RMSE:18360 . 688888868617

一个热编码器的 RMSE 小于标签编码器,这意味着使用一个热编码器可以提供更好的精度,因为我们知道 RMSE 越接近 0,精度越好,同样不要担心这么大的 RMSE,因为我说过这只是一个样本数据,帮助我们了解标签和一个热编码器对我们模型的影响。

如果你觉得这篇文章有用,给它一个掌声与你的朋友分享

谢谢

使用 Keras 为简单 LSTM 选择正确的超参数

原文:https://towardsdatascience.com/choosing-the-right-hyperparameters-for-a-simple-lstm-using-keras-f8e9ed76f046?source=collection_archive---------0-----------------------

Photo by Mika Baumeister on Unsplash

构建机器学习模型从未如此简单,许多文章对什么是数据科学以及它可以做的惊人事情进行了高度概述,或者深入讨论了一个非常小的实现细节。这使得像我不久前一样有抱负的数据科学家经常看着笔记本电脑,心想:“它看起来很棒,很有效,但为什么作者选择了这种类型的架构/神经元数量或这种激活功能,而不是另一种呢?在这篇文章中,我想就如何做出一些决定给出一些直觉,比如在建立模型时找到正确的参数,在一个非常基本的 LSTM 上演示根据给定的名字预测性别。由于有许多关于递归神经网络(RNN)背后的数学和一般概念的伟大课程,例如吴恩达的深度学习专业化或这里的媒体,我不会深入挖掘它们,并认为这些知识是已知的。相反,我们将只关注使用 Keras 的高级实现。我们的目标是对构建这样的神经网络所做的决策有更实际的理解,尤其是如何选择一些超参数。

带有代码和输出的完整文章可以作为笔记本在 Github 上找到。

在 Keras 上:自 2017 年支持 TensorFlow 以来的最新产品, Keras 作为更复杂的机器学习库的易于使用和直观的界面,引起了巨大的轰动。因此,构建实际的神经网络以及训练模型将是我们脚本中最短的部分。

第一步是确定我们要使用的网络类型,因为这个决定会影响我们的数据准备过程。任何名字(或单词)中的字符顺序都很重要,这意味着,如果我们想用神经网络分析一个名字,RNN 是合乎逻辑的选择。长短期记忆网络(LSTM)是 RNNs 的一种特殊形式,当输入组块链变长时,它在寻找正确特征方面特别有效。在我们的例子中,输入始终是一个字符串(姓名),输出是一个 1x2 向量,表示该姓名属于男性还是女性。

做出这个决定后,我们将开始加载我们将需要的所有包以及数据集——一个包含超过 150 万德国用户及其姓名和性别的文件,女性编码为 f ,男性编码为 m

预处理数据

任何自然语言处理的下一步都是将输入转换成机器可读的矢量格式。理论上,Keras 中的神经网络能够处理形状可变的输入。在 praxis 中,使用 Keras 中的固定输入长度可以显著提高性能,尤其是在训练期间。这种行为的原因是,这种固定的输入长度允许创建固定形状的张量,因此更稳定的权重。

首先,我们将把每个名字转换成一个向量。我们将使用的方法是所谓的一键编码。这里,每个单词由 n 个二进制子向量的向量表示,其中 n 是字母表中不同字符的数量(使用英语字母表是 26)。为什么我们不能简单地将每个字符转换到它在字母表中的位置,例如 a-1、b-2 等。)这将导致网络假设字符是有序的,而不是分类的——字母 Z not 比字母 A 更“有价值”。

例:
S 变为:
【0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0】

你好变成:
[[0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 0,0,0,0,0,0],
【0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0

既然我们已经确定了输入应该是什么样子,我们有两个决定要做:char 向量应该有多长(我们允许多少个不同的字符)和 name 向量应该有多长(我们想要查看多少个字符)。我们将只允许使用德语字母表(标准拉丁语)中最常见的字符和连字符,连字符是许多旧名称的一部分。
为了简单起见,我们将名称向量的长度设置为数据集中最长名称的长度,但以 25 为上限,以确保我们的输入向量不会因为一个人在名称输入过程中出错而变得过大。

Scikit-learn 已经在其预处理库中整合了一个热门编码算法。然而,在这种情况下,由于我们的特殊情况,即我们不是将标签转换成向量,而是将每个字符串拆分成其字符,因此创建自定义算法似乎比其他情况下所需的预处理更快。

已经证明【Numpy 数组需要的内存比 Python 列表少 4 倍左右。出于这个原因,我们使用 list comprehension 作为创建输入数组的一种更 pythonic 化的方式,但是已经将每个单词向量转换为列表内部的数组。当使用 Numpy 数组时,我们必须确保所有组合在一起的列表和/或数组具有相同的形状。

现在我们已经准备好输入,我们可以开始建立我们的神经网络。我们已经决定了模型(LSTM)。在 Keras 中,我们可以简单地将多层堆叠起来,为此我们需要将模型初始化为Sequential()

选择正确数量的节点和层

对于应该选择多少个节点(或隐藏神经元)或多少层,没有最终的、明确的经验法则,并且对于您的个别问题,试错法通常会给出最佳结果。最常见的框架很可能是 k 倍交叉验证。然而,即使对于一个测试过程,我们也需要选择一些( k )数量的节点。
下面的公式或许可以给你一个起点:

Nᵢ 是输入神经元的数量, Nₒ 是输出神经元的数量, Nₛ 是训练数据中的样本数量, α 代表一个比例因子,通常在 2 到 10 之间。我们可以计算 8 个不同的数字,输入到我们的验证过程中,并根据得到的验证损失找到最佳模型。

如果问题很简单,时间也是一个问题,那么有各种其他的经验法则来确定节点的数量,这些法则大多简单地基于输入和输出神经元。我们必须记住,虽然易于使用,但它们很少会产生最佳结果。这里只是一个例子,我们将在这个基本模型中使用:

如上所述,对于要使用的隐藏层的数量,也存在相同的数量不确定性。同样,任何给定用例的理想数字都是不同的,最好通过运行不同的模型来决定。一般来说,两层已经足够检测更复杂的特征。层数越多越好,但也越难训练。一般来说,一个隐藏层处理简单的问题,就像这样,两个隐藏层足以找到相当复杂的特征。
在我们的例子中,添加第二层仅在 10 个时期后将精度提高约 0.2% (0.9807 对 0.9819)。

选择附加超参数

每个 LSTM 层都应该有一个下降层。该层将通过在训练期间忽略随机选择的神经元来帮助防止过度拟合,并因此降低对单个神经元的特定权重的敏感性。20%通常用作保持模型准确性和防止过度拟合之间的良好折衷。

在我们的 LSTM 层做了所有的工作来转换输入,以使预测朝着期望的输出可能,我们必须减少(或,在罕见的情况下,延长)形状,以匹配我们期望的输出。在我们的例子中,我们有两个输出标签,因此我们需要两个输出单元。

要添加的最后一层是激活层。从技术上来说,这可以包含在密度层中,但有理由将其分开。虽然与此不相关,但分割密度层和激活层可以检索模型密度层的缩减输出。使用哪种激活功能同样取决于应用。对于我们手头的问题,我们有多个类(男性和女性),但一次只能出现一个类。对于这些类型的问题,一般来说, softmax 激活函数效果最好,因为它允许我们(和你的模型)将输出解释为概率。

损失函数和激活函数经常一起选择。使用 softmax 激活函数向我们指出交叉熵是我们优选的损失函数,或者更准确地说是二进制交叉熵,因为我们面对的是二进制分类问题。这两个函数彼此配合得很好,因为交叉熵函数抵消了 soft-max 函数两端的平稳状态,因此加快了学习过程。

在选择优化器时,自适应矩估计(short Adam)已被证明在大多数实际应用中工作良好,并且仅在超参数变化很小的情况下工作良好。最后但并非最不重要的是,我们必须决定,在哪个指标之后,我们要判断我们的模型。Keras 提供了多种精度功能。在许多情况下,从整体准确性的角度来判断模型的性能是最容易解释的选择,也足以产生模型性能。

构建、训练和评估模型

在对如何选择最重要的参数有了一些直觉之后,让我们把它们放在一起,训练我们的模型:

Training output

98.2%的准确率令人印象深刻,这很可能是因为验证集中的大多数名字已经出现在我们的测试集中。使用我们的验证集,我们可以快速查看我们的模型在哪里得出错误的预测:

Model validation output

查看结果,至少一些错误的预测似乎发生在那些在名字字段中输入他们的姓的人身上。看到这一点,下一个好的步骤似乎是清除那些案例中的原始数据集。目前,结果看起来很有希望。以我们所能达到的精确度,这个模型已经可以用于许多真实世界的情况。此外,为更多时期训练模型可能会提高其性能,这里重要的是注意验证集的性能,以防止可能的过度拟合

最后的想法

在这篇文章中,我们成功地构建了一个小模型,以超过 98%的准确率从一个给定的(德国)名字预测性别。虽然 Keras 让我们从编写复杂的深度学习算法中解放出来,但我们仍然必须在这个过程中就一些超参数做出选择。在某些情况下,例如选择正确的激活函数,我们可以依靠经验法则,或者可以根据我们的问题确定正确的参数。然而,在其他一些情况下,最好的结果来自于测试各种配置,然后评估结果。

度量标准有什么问题?

原文:https://towardsdatascience.com/choosing-the-right-metric-is-a-huge-issue-99ccbe73de61?source=collection_archive---------3-----------------------

或者任何类型的机器学习问题,你必须知道你将如何评估你的结果,或者评估标准是什么。

在本帖中,我们将查看最常见的指标,并根据目标和我们试图解决的问题讨论每个指标的有用性。

分类指标

准确(性)

可能是分类器性能的最直接和直观的度量。它只是简单地计算我们在预测总数中预测正确类别的次数。

当面对阶级不平衡的问题时,准确性显然是一个错误的衡量标准。假设你有两个类:A 类是你的数据集的 99%,B 类是剩下的 1%。通过预测每个时间案例的 A 类,您可以达到 99%的准确率。这看起来是个好成绩,但事实并非如此。

精确度和召回率

一般来说,在召回(被如此分类的真正肯定的实例的百分比)和精度(真正肯定的肯定分类的百分比)之间存在权衡。

在您想要检测少数类的实例的情况下,您通常更关心召回率而不是精确度。正如在欺诈检测的情况下,错过正面实例通常比错误地标记负面实例代价更高。

f-测度

我们都希望的理想场景是拥有高精度高召回率!

但要选择你的最佳模式,你需要一个单一的数字性能总结。F1 得分是精确度和召回率的调和平均值:

F1 分数没有一个很好的直观解释,它是一个被称为 F-Beta 分数的指标的特例,F-Beta 分数衡量的是用户对回忆的重视程度是对精确度的重视程度的β倍。

卡帕

Kappa 或 Cohen 的 Kappa 类似于分类准确性,只是它是在数据集的随机机会基线上进行标准化的:

其中 po 是观察到的一致,pe 是预期的一致。

它基本上告诉你你的分类器(po)的性能比一个简单地根据每个类(pe)的频率随机猜测的分类器的性能好多少。

没有标准化的方法来解释它的值。兰迪斯和科赫(1977) 提供了一种表征价值观的方法。根据他们的方案,a 值 0 表示不同意,0-0.20 表示轻微,0.21-0.40 表示一般,0.41-0.60 表示一般,0.61-0.80 表示基本同意,0.81-1 表示几乎完全同意。

罗马纪元

这是业内使用的流行指标之一。

AUC 代表曲线下面积。该曲线可以代表 ROC 曲线或 PR 曲线。

PR 曲线说明了在不同阈值设置下精度召回之间的权衡。

ROC 曲线是通过在不同的阈值设置下绘制 TPR (真阳性率),也称为灵敏度,相对于 FPR (假阳性率),也称为特异性而创建的。

以下是 ROC 曲线绘制的可视化效果:

Each point on the ROC curve (left)represents a different cutoff value — The curves on the right represent the Class-Conditional Probabilities

让我们看看当重叠部分的百分比增加/减少时会发生什么:

ROC curve (left) and Class-Conditional Probabilities (right) — varying the the percentage of overlapping for a fixed threshold

重叠越少,误差越小,ROC 曲线向上和向左移动得越远。所以,分班越好,AUC 就越高。

换句话说,AUC 不在乎绝对值,只在乎排名。你只需要很好地分开你的类,以获得高 AUC。

ROC 和 PR 有什么区别?

召回率=真阳性率(TPR)。所以区别在于精度和假阳性率。

这两种度量的主要区别在于,精度分母包含假阳性,而假阳性率分母包含真阴性。

精度衡量的是被分类为阳性的样本实际上是阳性的概率,而假阳性率衡量的是阴性样本中假阳性的比率。

应该用哪个?

对于任何度量标准来说,这完全取决于您打算如何处理数据。如果你的模型需要在正类和负类上表现的一样好。例如,为了对猫和狗之间的图像进行分类,您希望模型在猫和狗身上都表现良好。为此,您可以使用 ROC-AUC。另一方面,如果您对模型在负类上的表现并不真正感兴趣,而只是希望确保每个正预测都是正确的(精度),并且您得到尽可能多的正预测(回忆),那么您应该选择 PR-AUC。

简而言之:

使用 PR-AUC 关注小阳性类别

当两类检测同等重要时,使用 ROC-AUC

当阳性结果占多数时,使用 ROC-AUC,或者切换标签,使用 precision 和 recall

注意:许多人倾向于坚持使用 ROC,因为在大多数情况下这是一个更容易解释的指标。除此之外,计算精确的 PR 曲线就不那么直接了。(查看此链接了解更多详情)。

也就是说,AUC 也有其缺点:它可能会给出潜在的误导性结果…见下图!!

Both models A and B have an equal area under the ROC cure. However, in the high FPR range, model B is better than A, whereas in the low FPR range model A is better than B.

有些人不建议使用 AUC,原因如下:

(1)它忽略了预测的概率值和模型的拟合优度

(2)它总结了在人们很少操作的曲线空间区域上的测试性能

(3)它同等重视遗漏和犯错误

(4)它没有给出关于模型误差的空间分布的信息

(5)模型执行的总程度高度影响良好预测的缺席率和 AUC 分数

豪尔赫·洛沃、阿尔韦托·希门尼斯·瓦尔夫德和雷蒙多·雷亚尔

部分 AUC (pAUC)

部分 AUC 已被提议作为标准 AUC 的替代措施。当使用部分 AUC 时,只考虑 ROC 空间的特定区域。

pAUC denotes the area of shaded region

双向 pAUC

双向 pAUC 不是只限制假阳性率(FPR),而是关注曲线下的部分区域,同时具有水平和垂直限制。已经表明,pAUC 对真阳性率(TPR)的间接控制在概念上和实践上都是误导的。

Two-way pAUC denotes the area of shaded region A. This shaded region is directly determined by explicit FPR upper bound p0 (= 0.5) and TPR lower bound q0 (= 0.65). In contrast, pAUC denotes the area of both region A and B. Its indirect FPR lower bound (green dotted line) is determined by the TPR lower bound q0

对数损失

对数损失是基于概率的最重要的分类度量之一。

其中 yi 是真实标签,pi 是 yi = 1 的概率。

这完全是关于信心:如果对于一个特定的观察,分类器分配一个非常小的概率给正确的类,那么相应的对日志损失的贡献将会非常大。对数损失度量可以被视为精确度的“软”度量。

2 different models — same AUC but different LogLoss

这两个模型输出有相同的排名,因此相同的 ROC-AUC,PR-AUC

但是,根据 LogLoss 值,右边的模型比左边的要好。

这是显而易见的,因为 Logloss 包含了概率置信度的概念。

这个指标的一个缺点是多数阶级可以支配损失!!

学习对指标进行排序

现在让我们来看看如何评估一个搜索引擎、一个推荐系统或者任何输出商品列表的系统。

在研究文献中,排序“项目”被称为学习排序。

Example of ranked urls for a given query

两个最流行的排名指标是地图@k 和 NDCG@k。让我们看看他们是如何工作的…

符号:

rel(i) 是指示函数,如果等级 I 处的项目是相关的,则等于 1,否则等于 0。

P(i) 是 top-i 集合中相关的返回项目的比例。

n 是系统做出的预测次数。

m 是项目全空间中相关项目的个数。

Q 是查询总数。

为了解释 MAP@k 做什么,我们需要从 AP@k 开始……

美联社@k

这个度量关心第 k 项的平均精度

当推荐的数量不可能捕获所有正确的推荐时,所使用的标准化因子防止 AP@k 分数被不公平地抑制。

……不要担心,这里有一个简单的例子可以更好地理解公式:

考虑一下,对于一个给定的查询,您必须预测一个包含多达 10 个项目的有序列表。并且只有 4 个可能的正确预测(地面真相)。

对于每一个预测,你都需要检查它是否正确。如果不是,你的预测就没有分数。如果它是正确的,你得到的点数等于正确预测的点数,包括这一个。

你除以的数就是可能的点数。换句话说,这是 10 个(你最多能预测的)和 4 个实际正确答案中的较小者。

因此:AP@10 = (1/2 + 2/3 + 3/5 + 4/9 ) / 4 = 0.55

地图@k

MAP@k 计算所有查询的平均精度(AP@k) 的平均值。对,一个平均一个平均!!

AP@k 是一个度量,它接受前 k 个项目的排序列表,并将其与给定查询的真实“相关”项目集的列表进行比较。AP@k 奖励你在你的列表中有很多相关的条目,并且把最可能正确的条目放在最上面。因此,顺序 对于计算 AP@k 分数很重要。MAP@k 只是计算 AP@k 在所有查询中的平均值。

现在,让我们解释另一个流行的排名质量指标…

NDCG@k

该指标声明了以下内容:

  1. 非常相关的结果>稍微相关的结果>不相关的结果(Cu 累计 G ain)。
  2. 当相关结果出现在结果集的前面时,它们会更有用( D iscounting)。
  3. 排序的结果应该与所执行的查询无关( N 规范化)。

【CG】是检索到的候选项的相关性得分的总和。它被计算为前 k 个相关性分数的总和:

贴现 CG (DCG) ,基本上根据项目的位置来惩罚相关性分数。使用对数衰减:

提出了一个替代方案以更加强调检索相关项目:

名词(noun 的缩写)b:当相关值为二进制时, DCG@k 的这两个公式是相同的。

然而,这个分数没有固定的上限,因为它取决于查询返回的结果的数量,因此为了比较不同查询的 DCG,我们必须 将它们 归一化。为了实现这一点,我们将 DCG 值除以最佳可能( 【理想】 )排名,得到,一个介于 0 和 1 之间的值。

地图@k vs NDCG@k:主要区别?

顺序对 MAP@k 和 NDCG@k 都很重要。但主要区别是 MAP@k 假设二元相关性(一个项目是感兴趣的还是不感兴趣的),而 NDCG@k 允许实数形式的相关性分数。

连续变量的度量呢?

回归度量

当谈到回归性能指标时,MAE 和 RMSE 是两个最流行的指标。

绝对平均误差

均方根误差

梅与 RMSE:应该使用哪一个?

以下几点可能有助于你做出决定:

当误差分布预期为高斯分布时,RMSE 比 MAE 更适合表示模型性能。

MAE 适用于描述均匀分布的误差。

MAE 对异常值更稳健:最小化平方误差导致找到它的平均值,最小化绝对误差导致找到它的中值。我们都知道中位数比简单平均数对异常值更稳健。

RMSE 避免使用绝对值,这在许多数学计算中是非常不可取的。例如,可能很难计算 MAEs 相对于某些模型参数的梯度。

….那 R 呢?

r 平方

R 平方的定义相当直接:它是用线性模型解释的响应变量变化的百分比。

误解: R 不在 0 和 1 之间。R 的最大值是 1,但也可能是负值。

R 有什么问题吗?

是啊!!!当增加新的预测值时,r 总是增加,不管它们是否有用:

每当您向模型中添加一个变量时,其估计系数的值可以为零,在这种情况下,解释方差的比例保持不变,也可以采用非零值 ,因为它提高了拟合的质量 。通过构造,你的 R 不能在增加一个变量后变小- Maxime Phillot 在 Quora 上的响应

我们如何克服这个问题?

调整后的 R

其中 n 是观察值的总数,k 是预测值的数量。

如果添加有用的术语,该指标将会增加,如果添加不太有用的预测值,该指标将会减少。

更多指标!!!!

NLP/NLG 指标:BLEU 和 ROUGE

这两个指标是互补的,主要用于评估文本的自动摘要和机器翻译。

双语评估替补演员

胭脂(面向回忆的吉斯丁评价替角)

胭脂只基于回忆。

基于用于计算召回的特征,胭脂可以有许多类型:

  • ROUGE-N 基于一元、二元、三元或更高阶的 N -gram 重叠。
  • ROUGE-L/W/S 分别基于 L ongest 公共子序列(LCS)、 W eighted LCS 和 S kip-bigram 共现统计。

有关这些指标的更多信息,您可以参考林的论文。

语音识别指标:WER(单词错误率)

WER 是用于评估 ASR(自动语音识别)系统的常用指标。这里有一个简单的方法来理解 WER 是如何计算的:

删除:

语音输入:我昨天连接了
ASR 结果:我昨天连接了

插入:

语音输入:昨天连接了
ASR 结果:昨天连接了

替代:

语音输入:昨天连接了
ASR 结果:连接了是

奖金!

走到最后是你应得的。

以下是您可以在网上找到的挑战列表,这些挑战使用我们提供的一个指标来评估参与者模型的性能。

结论

没有硬性规定可以找到一个理想的指标来说明在所有情况下应该最小化/最大化什么!这完全取决于业务需求和您试图解决的问题的背景。主要的信息很简单,当定义一个问题时,度量应该被接受并扮演一个关键的角色。

请继续关注,如果你喜欢这篇文章,请留下👏!

参考文献

[1] Jorge M. Lobo,A. Jiménez 和 R.Raimundo,AUC:对预测分布模型性能的误导性衡量,2007 年

[1] 卢琨,双向部分 AUC 及其性质,2017

[2] 斯坦福大学信息检索导论课程

[2] 林金耀,胭脂:摘要自动评价软件包,2004

棋盘游戏:骰子有多随机?

原文:https://towardsdatascience.com/christmas-games-how-random-are-dice-969f8a935b18?source=collection_archive---------12-----------------------

用 openCV 和假设检验分析骰子的随机性

Image via photodune.net under license to mtstrauss

虽然节日应该是快乐和幸福的源泉,但玩桌游可能是一种微妙的消遣。总有一些人似乎比预期的更有运气。一个典型的问题是骰子是公平的还是被操纵的。这里我们就通过反复掷骰子来分析骰子随机性。对于评估,我们将使用两种关键方法:圆检测来计算骰子图像上的点数,以及假设检验来对骰子的随机性进行定量说明。

由于 n 越大统计越好,一些爱好者甚至掷骰子 10.000 次来测试他们骰子的公平性。由于我不想手动掷骰子,我决定用一些乐高、Arduino 微控制器和网络摄像头来制作一个小型自动掷骰子器。基本上,骰子位于一个轮子上的一个小室中,轮子旋转,使骰子旋转。Arduino 转动滚轮 1.5 秒,再停 1.5 秒,然后网络摄像头拍摄结果,并重复该过程。在下面的 gif 图中可以看到机器运行和该机制的延时。

Dice Rolling Mechanism: An Arduino controls a LEGO® motor, which rotates wheels to rotate the die. A webcam captures the outcome.

Dice Rolling Mechanism Close Up Timelapse: The two rounded parts allow the die to flip around randomly.

由于轮子只在一个方向旋转,我在两个圆形部分的形式上增加了一点不对称,这样骰子也可以在垂直轴上旋转。我让机器运行了大约 2.5 小时,以创建一个大约 3000 次投掷的数据集。如果对 Arduino 代码或布线感兴趣,请随时联系我。

现在让我们进入分析部分。有几种方法可以计算点数,例如,我们可以使用形态学操作,通过应用二进制阈值并选择其凸包来掩盖骰子的朝上面(它明显比背景亮)。然后,可以通过对区域进行计数或者仅仅通过确定黑色像素与白色像素的比率来确定 pip 的数量。我尝试了几种方法,但最终决定使用 OpenCV 的 HoughCircles 函数,因为它需要最少的代码来实现。一般介绍可以在这里找到。在试验了这些参数之后,人们能够很快在圆检测中获得不错的结果:

Webcam image of the die and the detected pips using OpenCV ‘s HoughCircles function

接下来,我们计算每个图像的点数。当检测不到圆时,将指定 0 值:

为了检查算法的结果,我们绘制了每个类别的图像:

由于人类的大脑在识别错误分类方面速度超快,我决定检查这些类并手动纠正它们。检查还让我意识到,实际上有许多投掷是不明确的,因为骰子是站在边缘上的(它们被分配到零类)。

注意,HoughCircles 函数在大约 90%的情况下做了正确的分类。由于手动校正,现在人们也有了训练集,并且可以花费更多的时间来构建更好的分类器(即,当增加 n 时)。让我知道,如果你想得到数据集,有兴趣玩一玩,并建立一个基于此数据的骰子分类器。

现在,我们可以珍惜一个正确分类的骰子汇编。在所有六个数据集的下面(如果你发现一个不属于那里的,请告诉我):

All sixes of the dataset.

现在我们已经对所有的图像进行了正确的分类,我们现在可以测试我们的骰子是否是公平的了。首先,我们将绘制每个数字的出现次数:

正如我们所观察到的,第一种情况发生得更频繁。现在我们如何发现这个偏差是否显著?我们可以使用的一个统计检验是卡方检验。为了执行这个测试,我们计算预期结果的数量(E),计算与预期发生的差异(O-E),平方这个值((O-E)),然后通过预期值的数量将其归一化((O-E) /E)。卡方检验统计量是所有标准化值的总和。为了计算显著性水平,我们将检验统计量与 5 度的卡方分布(6–1)进行比较。

The results data frame

要使用卡方检验,我们不需要总是计算表(虽然这样便于理解检验),但是也可以使用 stats 库直接计算值。

from scipy.stats import chisquare1 - chisquare(counts).pvalue

最终,测试显示骰子在 97%的显著性水平上有偏差,因此这是不公平的。从上表判断,这种情况比正常情况多出现了 12%。毕竟,我现在找到了一个合理的解释,来解释为什么我用这个骰子输掉了过去的游戏。

讨论

这里,我们使用 OpenCV 的 HoughCircles 函数来计算骰子图像上的点数。使用卡方检验,我们能够在 97%的显著性水平上检验我们的假设,即骰子是不公平的。
然而,另一个问题是为什么死得不公平。我会假设它源于制造问题,所以质心错位,一些边缘比其他边缘更圆。在浏览专业骰子时,我注意到很多骰子都有锋利的边缘。
可能的后续行动是调查其他几款骰子,并寻找最公平骰子的最佳制造商。此外,骰子投掷机可以通过嵌入平面来模拟更真实的投掷来改进。

当然,另一个主要的限制是掷骰子是否是随机的。给定有限数量的相互作用,人们可以认为最终位置是由起始条件决定的。

至于这个特定的骰子,请放心,它将被排除在下一个棋盘游戏会话之外,以拯救家庭和平。

基于机器学习的客户流失预测

原文:https://towardsdatascience.com/churn-prediction-with-machine-learning-e6612cd5538f?source=collection_archive---------3-----------------------

客户流失是一个用来量化离开公司的客户数量的指标。对于 SaaS 企业来说,它可以由那些取消订阅或取消之前签订的服务的人来定义。但对于销售不需要订阅的产品的电子商务公司来说,判断顾客何时购买是相当棘手的。

与其他指标一起,客户流失对于评估一段时间内的客户满意度至关重要,尤其是在衡量网站、产品供应商和其他方面最近的变化可能导致客户离开的负面影响时。

例句:你在你的电子商务平台上推出了一个新的布局,随后客户数量增加了。

客户流失也可以成为你做出更好营销决策的最好朋友。尽早发现有流失风险的客户是细分营销活动的最佳方式,以便及时有效地重新吸引这些用户,因为获得新客户比留住老客户更昂贵、更耗时。对于电子商务公司来说,这种说法非常正确。获得新客户总是需要大量的营销努力,公司必须在潜在消费者想到点击“购买”按钮之前向他们展示值得信赖。这通常需要时间。老顾客对商店很熟悉,他们不需要在网站上注册就可以方便地回到那里,因为他们已经在第一次购买时浏览过了。

总之,客户流失或流失率是一个温度计,显示客户对所提供的产品和服务是否有良好的体验。因为否则,他们显然会离开。

但是公司如何预测客户流失呢?这个问题没有正确答案。人们认为,当顾客不满意并准备离开时,他们会以某种方式做出类似的行为。这些信号可能很多,比如不回复营销邮件、不登录、不搜索产品、在网站上投诉、住在竞争对手突然变强的地区等等。

这就是为什么机器学习在检测客户流失方面变得非常受欢迎。通过向机器显示积极的流失案例,该模型计算出某人即将离开的概率。识别出那些处于风险中的顾客,公司可以发送一个特别的报价来吸引他们回到商店。它可以以折扣券或热身信息的形式出现,以提醒客户他们对公司的重要性。

机器学习在这种背景下如何运行?粗略地说,它是一个经过训练的模型,可以学习如何根据以前的数据,通过真实的案例来预测流失。记录所有客户在网站上随时间执行的交互的日志很容易成为无法操纵的无尽数据集,在这种情况下,机器学习是一个不断输入新信息的自动化程序,根据不同的场景调整预测。因此能够做出更好的预测。

尽管客户流失和机器学习是一个高度复杂的领域,缺乏改进,但幸运的是,涉及流失率和机器学习的测试越来越受欢迎,每天都有新的结果出现,以澄清所有这些混乱。

建议?想法?欢迎在下方评论或联系我LinkedIn😃

张量流中的 CIFAR-10 影像分类

原文:https://towardsdatascience.com/cifar-10-image-classification-in-tensorflow-5b501f7dc77c?source=collection_archive---------1-----------------------

Photo by rawpixel on Unsplash

在这个故事中,我将对来自 CIFAR-10 数据集的图像进行分类。这个故事包括预处理图像和训练/预测卷积神经网络模型。

这个笔记本的一些代码和描述是借用了这个回购Udacity 提供,但是这个故事提供了更丰富的描述。代码和 jupyter 笔记本可以在我的 github repo 里找到,https://github . com/deep-diver/cifar 10-img-classification-tensor flow

我的深度学习背景是uda city { Deep Learning ND&AI-ndwith contentrations(CVNLP ,VUI)},Coursera Deep Learning . AI Specialization(AI-ND 被拆分成 4 个不同的部分,我是和之前版本的 ND 一起完成的)。还有,我目前正在服用 Udacity 数据分析师 ND ,已经 80%完成。

在跳进去之前…

  • 理解原始数据和原始标签

实施预处理功能

  • 规格化,一个热编码
  • 培训/开发/测试集中的数据分割

建立网络

  • CNN 模型及其代价函数和优化器

训练神经网络

  • 超参数
  • 训练模型

测试模型(预测)

在跳进去之前…

文件列表

Fig 1. list of files of batch

如图 1 所示,数据集被分成几批以防止你的机器运行出内存。CIFAR-10 数据集由 5 个批次组成,命名为data_batch_1data_batch_2等。如官方网站所述,每个文件使用 python 中的 pickle 模块打包数据。

了解原始影像数据集

原来的一个批量数据是用 numpy 数组表示的 (10000 x 3072)矩阵列数,(10000),表示样本数据的数量。如 CIFAR-10/CIFAR-100 数据集中所述,行向量,(3072)代表一幅 32×32 像素的彩色图像。因为这个项目将使用 CNN 进行分类任务,所以原始的行向量是不合适的。为了将图像数据馈入 CNN 模型,输入张量的维数应该是(宽度 x 高度 x 数量 _ 通道)(数量 _ 通道 x 宽度 x 高度)。这取决于你的选择(查看 tensorflow conv2d )。我要用第一种选择,因为 tensorflow 的 CNN 操作中默认选择是这样的。

如何重塑成这样的形态?

如果您计算 32323 == 3072,则图像的行向量具有完全相同的元素数量。为了将行向量重新整形为(宽度 x 高度 x 数量 _ 通道)形式,需要两个步骤。第一步是使用[**reshape**](https://docs.scipy.org/doc/numpy/reference/generated/numpy.reshape.html)功能,第二步是使用 numpy 中的[**transpose**](https://docs.scipy.org/doc/numpy/reference/generated/numpy.transpose.html)功能。

根据 numpy 官方网站的定义,[**reshape**](https://docs.scipy.org/doc/numpy/reference/generated/numpy.reshape.html)将数组转换成新的形状,而不改变其数据。在这里,短语不改变其数据是一个重要的部分,因为你不想伤害数据。[**reshape**](https://docs.scipy.org/doc/numpy/reference/generated/numpy.reshape.html)运营应分三个更详细的步骤进行。下面的方向是用逻辑概念描述的。

  1. 行向量分成 3 块,每块代表一个颜色通道。
    -得到的数组有(3×1024)个矩阵,总共就有(10000×3×1024)个张量。
  2. 用 32 将中的每 3 块进一步分割。32 是图像的宽度和高度。
    -这导致(3×32×32),这使得
    (10000×3×32×32)张量总计

为了实现 numpy 中的逻辑概念,[**reshape**](https://docs.scipy.org/doc/numpy/reference/generated/numpy.reshape.html)应该用下面的自变量来调用,(10000,3,32,32)。正如您所注意到的,当提供第三个值(32,width)时,reshape 函数不会自动进一步分割。您需要明确指定最后一个值(32,height)

Fig 2. reshape and transpose

故事还没有结束。现在,一个图像数据被表示为(num_channel,width,height)形式。然而,这并不是 tensorflow 和 matplotlib 期待的形状。他们期待不同的形状(宽度,高度,通道数)。你需要交换每个轴的顺序,这就是[**transpose**](https://docs.scipy.org/doc/numpy/reference/generated/numpy.transpose.html)的作用。

[**transpose**](https://docs.scipy.org/doc/numpy/reference/generated/numpy.transpose.html)可以接受一个轴列表,每个值指定它想要移动的维度的索引。例如,在(num_channel,width,height)的 numpy 数组中调用 transpose with argument (1,2,0)将返回(width,height,num_channel)的新 numpy 数组。

Code 1. reshape and transpose after loading

了解原始标签

标签数据只是一个包含从 0 到 9 的 10000 个数字的列表,对应 CIFAR-10 中的 10 个类中的每一个。

  • 飞机:0
  • 汽车:1
  • 小鸟:2
  • 猫:3
  • 鹿:4
  • 狗:5
  • 青蛙:6
  • 马:7
  • 船舶:8 艘
  • 卡车:9 辆

代码 1 定义一个函数,返回一个方便的图像类别列表。该功能将用于预测阶段。因为预测的输出是一个数字,所以它应该被转换成字符串,以便人们能够阅读。

Code 2. label names

探索数据

你可以在 my github 通过改变batch_idsample_id来玩笔记本中的代码单元。batch_id是一个批次(1-5)的 id。sample_id是批次中图像和标签对的 id。

下面定义的 display_stats 回答了一些问题,比如在给定的一批数据中..

  • “所有可能的标签是什么?”
  • "图像数据的取值范围是什么?"
  • "标签是有序的还是随机的?"

Code 3. showing sample image in batch #3

我已经尝试了第三批和第 7000 张图片。如图 3 中的结果所示,每个类别的图像数据的数量大致相同。

Fig 3. showing sample image in batch #3

实现预处理功能

您可能会注意到,一些框架/库,如 TensorFlow、Numpy 或 Scikit-learn,提供了与我将要构建的类似的功能。这反映了我不太依赖框架或库的目的。我相信我可以把自己的模型做得更好,或者复制/试验论文中介绍的最先进的模型。对于这个故事,我将实现**normalize****one-hot-encode**函数。

使标准化

**normalize**函数获取数据x,并将其作为规范化的 Numpy 数组返回。x可以是任何东西,也可以是 N 维数组。在这个故事中,它将是一个图像的三维数组。 最小-最大归一化 ( **y = (x-min) / (max-min)** ) 技术被使用,但是也有其他选项。通过应用最小-最大归一化,原始图像数据将在 0 到 1 的范围内进行变换。为什么应该执行规范化的一个简单答案与激活函数有些关系。

Code 4. min-max normalize function

例如, sigmoid 激活函数接受一个输入值,输出一个新值,范围为从 0 到 1 。当输入值较大时,输出值很容易达到最大值 1。同样,当输入值稍小时,输出值很容易达到最大值 0。

Fig 4. sigmoid function

再比如, ReLU 激活函数取一个输入值,输出一个范围从 0 到无穷大的新值。当输入值稍大时,输出值线性增加。但是,当输入值稍小时,输出值很容易达到最大值 0。

Fig 5. ReLU function

现在,当您考虑图像数据时,所有值最初的范围是从 0 到 255。这听起来像是当它被传递给 sigmoid 函数时,输出几乎总是 1,而当它被传递给 ReLU 函数时,输出可能非常巨大。当执行反向传播过程以优化网络时,这可能导致爆炸/消失梯度问题。为了避免这个问题,最好让所有的值都在 0 和 1 之间。

独热编码

稍后,我将解释模型。目前,你需要知道的是模型的输出。它是基于模型预测结果的每类图像的一组概率。为了在代码中表示这些概率,需要一个具有与图像类别数量相同的元素数量的向量。例如,CIFAR-10 提供了 10 种不同的图像类别,因此您还需要一个大小为 10 的矢量。

Fig 6. one-hot-encoding process

此外,我们的模型应该能够比较预测与地面真相标签。这意味着标签数据的形状也应该转换成大小为 10 的向量。相反,因为 label 是基本事实,所以将值 1 设置为相应的元素。

**one_hot_encode**函数接受输入**x**,这是一个标签列表(基本事实)。列表中元素的总数是一个批次中样本的总数。**one_hot_encode**函数返回一个二维张量,其中行数是批量的大小,列数是图像类的数量。

Code 5. one hot encoding function

预处理所有数据并保存

Fig 7. train/valid/test set

下面的代码 6 使用之前实现的函数**normalize****one-hot-encode**来预处理给定的数据集。如图 7 所示,来自每个批次的 10%的数据将被合并以形成验证数据集。其余 90%的数据用作训练数据集。最后,有测试数据集已经提供。下面的代码单元将预处理所有的 CIFAR-10 数据,并将其保存到外部文件中。

Code 6. preprocessing

张量流基础

在开始构建网络和训练过程之前,提醒自己 TensorFlow 是如何工作的以及有哪些包是很好的。

TensorFlow 软件包

TensorFlow 附带一堆包。您甚至可以找到具有类似功能的模块。例如,tf.nn.conv2d 和 tf.layers.conv2d 都是二维卷积运算。以下是每个包的类别的用途。

**tf.nn** :神经网络的低层 APIs】

  • 这个包中的每个 API 都有其唯一的用途
  • 例如,为了在 conv2d 之后应用激活函数,您需要两个单独的 API 调用
  • 你可能需要自己手动设置很多设置

**tf.layers** :神经网络的高级 API

  • 这个包下的每个 API 可能都有简化的过程
  • 例如,为了在 conv2d 之后应用激活函数,您不需要两次单独的 API 调用。此程序包下的 Intead,conv2d API 具有激活参数
  • 这个包中的每个 API 在参数中都有很多默认设置

**tf.contrib** :包含易变的或者实验性的 API

  • 就像文档解释的那样,这个包提供了实验代码
  • 您可能会找到更方便的 API
  • 当你在主包下找不到功能的时候,你可以去看看这个包
  • 它意味着包含最终应该合并到核心 TensorFlow 中的特性和贡献,但是您可以将它们想象为正在构建中

我将在每个不同的包下使用 API,这样我可以熟悉不同的 API 用法。

张量流工作流

根据官方文档, TensorFlow 使用一个数据流图来根据各个操作之间的依赖关系来表示您的计算。这导致了一个低级编程模型,其中您首先定义数据流图,然后创建一个 TensorFlow 会话来跨一组本地和远程设备运行图的一部分。

数据流并行计算的通用编程模型。在数据流图中,节点代表计算单元,边代表计算消耗或产生的数据。例如,在 TensorFlow 图中,tf.matmul 操作将对应于具有两条传入边(要相乘的矩阵)和一条传出边(相乘的结果)的单个节点。

大多数 TensorFlow 程序从数据流图构建阶段开始。在这个阶段,您调用 TensorFlow API 函数来构造新的 tf。操作(节点)和 tf。张量(边缘)对象,并将它们添加到一个**tf.Graph**实例中。 TensorFlow 提供了一个默认图,它是同一上下文中所有 API 函数的一个隐式参数。

**tf.Session.run** 方法运行 **tf.Operation** 或评估 **tf.Tensor**的主要机制。您可以将一个或多个**tf.Operation****tf.Tensor**对象传递给**tf.Session.run**,TensorFlow 将执行计算结果所需的操作。

Fig 9. TensorFlow dataflow graph

建立网络

下面的图 8 简单地显示了模型将会是什么样子。

Fig 8. classification model

为模型准备输入

为了训练模型,至少应该提供两种数据。应该将图像数据输入到模型中,以便模型可以学习并输出其预测。应该在模型的末尾提供标签数据,以便与预测输出进行比较。要提供的值有很多,但我只打算再包括一个。**keep_prob**是单个数字在什么概率下每层应该保留多少个单元。这就是所谓的辍学技术

无论进给数据应该放在模式的前面、中间还是最后,这些进给数据都称为输入

Code 7. input tensors

TensorFlow 中的[**tf.placeholer**](https://www.tensorflow.org/api_docs/python/tf/placeholder)创建一个输入。每个输入需要指定期望的数据类型及其维度形状。形状中无表示长度未定义,可以是任何长度。

创建模型

整个模型总共由 14 层组成。除了下面列出的层什么技术适用于建立模型。

  1. 与 64 个大小为(3x3)的不同滤波器卷积
  2. 最大 2 池
    • ReLU 激活功能
      -批量正常化
  3. 与 128 个大小为(3×3)的不同滤波器卷积
  4. 最大池乘 2
    • ReLU 激活功能
      -批量正常化
  5. 与 256 个大小为(3×3)的不同滤波器卷积
  6. 最大 2 池
    • ReLU 激活功能
      -批量正常化
  7. 与大小为(3x3)的 512 个不同滤波器卷积
  8. 最大 2 池
    • ReLU 激活功能
      -批量正常化
  9. 展平最后一次卷积操作的三维输出。
  10. 全连通 128 层
    -脱扣
    -批量正常化
  11. 256 单元全连接层
    -脱扣
    -批量正常化
  12. 全连接 512 层
    -漏接
    -批量归一化
  13. 1024 单元全连通层
    -漏接
    -批量归一化
  14. 具有 10 个单元(图像类别数)的全连接层

下图 9 描述了当您使用【通道 x 宽度 x 高度】张量格式时,概念卷积操作与 TensorFlow 实现的不同之处。

Fig 9. convolving operation in tensorflow with [NCWH] form of input

下面的代码 8 展示了如何在 TensorFlow 中构建模型。我们先来看看卷积层。可以使用[**tf.nn.conv2d**](https://www.tensorflow.org/api_docs/python/tf/nn/conv2d)[**tf.layers.conv2d**](https://www.tensorflow.org/api_docs/python/tf/nn/conv2d)创建卷积层。后一种更方便,因为它有更多可选参数。前一种选择创建了最基本的卷积层,您可能需要在**tf.nn.conv2d**之前或之后添加更多卷积层。比如激活函数可以在**tf.layers.conv2d**中直接指定为参数,但是在使用**tf.nn.conv2d**的时候要手动添加。

构建卷积层时,有三点需要考虑。这就是步幅、填充和过滤器。步长决定了滤波器的窗口在每个卷积步骤中应该移动多少,它是一个长度为 4 的一维张量。但是,从技术上来说,官方文件说'必须有步幅[0] =步幅[3] = 1' 。所以你只能控制步幅[1]和步幅[2]的值,但是把它们设置成相等的值是不是很常见。[1,1,1,1]和[1,2,2,1]是最常见的用例。我将使用[1,1,1,1],因为我想逐个像素地进行卷积。

当一个完整的卷积操作完成后,图像的输出尺寸变得小于输入尺寸。但是,您可以通过在图像周围应用额外的 0 值像素来强制保持不变。当填充设置为“相同”时,图像的输出大小将保持与输入图像相同。另一方面,当填充被设置为“有效”时,它会更小。我将使用“相同的”填充样式,因为它更容易管理每个卷积层中图像的大小。

可以用[**tf.Variable**](https://www.tensorflow.org/api_docs/python/tf/Variable)定义过滤器,因为它只是一堆权重值,并且随着时间的推移在训练网络时会发生变化。过滤器应该是形状为[过滤器 _ 高度,过滤器 _ 宽度,入口 _ 通道,出口 _ 通道]的 4-D 张量。in_channels 表示当前卷积运算所应用的通道数,out_channels 表示当前卷积运算将要产生的通道数。

Code 8. CNN model

如前所述,[**tf.nn.conv2d**](https://www.tensorflow.org/api_docs/python/tf/nn/conv2d)没有将激活函数作为参数的选项(而[**tf.layers.conv2d**](https://www.tensorflow.org/api_docs/python/tf/nn/conv2d)有),[**tf.nn.relu**](https://www.tensorflow.org/api_docs/python/tf/nn/relu)被明确地添加在**tf.nn.conv2d**操作之后。然后通过使用[**tf.nn.max_pool**](https://www.tensorflow.org/api_docs/python/tf/nn/max_pool)功能应用最大池化。max pooling 操作可以被视为一种特殊的 conv2d 操作,只是它没有权重。目的是通过保留最强的值来缩小图像。ksize=[1,2,2,1]和 stamps =[1,2,2,1]表示将图像缩小一半。

[**tf.contrib.layers.flatten**](https://www.tensorflow.org/api_docs/python/tf/contrib/layers/flatten)[**tf.contrib.layers.fully_connected**](https://www.tensorflow.org/api_docs/python/tf/contrib/layers/fully_connected)[**tf.nn.dropout**](https://www.tensorflow.org/api_docs/python/tf/nn/dropout)功能直观易懂,使用非常方便。只有一件重要的事情要记住,你不要在完全连接的层列表的末尾指定激活函数。这将在稍后定义成本函数时指定。

超参数

超参数是通过十几次实验选择的。需要注意的一点是,必须在定义优化器之前定义 learning_rate,因为这是您需要将 learning rate 作为构造函数参数的地方。

Code 9. hyper parameters

成本函数和优化器

最后,您将定义成本、优化器和准确性。[**tf.reduce_mean**](https://www.tensorflow.org/api_docs/python/tf/reduce_mean)取一个输入张量进行约简,输入张量是预测结果和地面事实之间某些损失函数的结果。因为 CIFAR-10 必须测量 10 个等级的损耗,所以使用了[**tf.nn.softmax_cross_entropy_with_logis**](https://www.tensorflow.org/api_docs/python/tf/nn/softmax_cross_entropy_with_logits)函数。在训练网络时,您想要的是通过应用您选择的算法来最小化成本。可能是 SGDAdamOptimizeradagradmoptimizer之类的。你必须研究每种算法是如何工作的,以选择使用什么,但是 AdamOptimizer 通常适用于大多数情况。

Code 10. cost function & optimizer & accuracy

训练神经网络

您已经定义了成本、优化器和准确性,它们实际上是什么..

  • 成本
    -
    reduce_mean = >约化后的张量
  • 优化器
    -
    AdamOptimizer = >应用指定渐变的操作
  • 精度
    -
    化简 _ 均值= >化简张量

tf。官方文档中的 Session.run 方法解释了它运行 TensorFlow 计算的一个“步骤”,通过运行必要的图形片段来执行每个操作,并在获取中评估每个张量,用**feed_dict**中的值替换相应的输入值。获取参数可以是单个图形元素,或者任意嵌套的列表、元组等。

这里真正的图元是**tf.Tensor****tf.Operation**。成本、优化和准确性就是其中之一。这意味着它们可以被指定为提取参数的一部分。然后,你可以在这个过程中加入一些变量。这是张量流的一个便利特性。一旦构建了图表,您需要做的就是将数据输入图表并指定要检索的结果。

单一优化

**train_neural_network**函数对给定的一批数据运行优化任务。它将在一个循环中使用,并在以后的多个时期和批次中使用。简单来说,**session.run**照顾工作。它将第一个参数作为要运行的内容,将第二个参数作为数据列表提供给网络,以便从第一个参数中检索结果。如前所述,您希望通过运行 optimizer 来最小化成本,因此这必须是第一个参数。

Code 11. single optimization task

显示统计数据

**print_stats**显示当前训练步骤的成本和准确性。与**train_neural_network**功能类似的过程也适用于此。不是将优化器交付给**session.run**函数,而是给出成本和精度。请注意**keep_prob**被设置为 1。辍学率必须适用于培训阶段,否则必须根据论文设置为 1。

Code 12. showing stats

分批训练模型

**train_neural_network**函数在给定批次上运行优化任务。因为 CIFAR-10 数据集有 5 个单独的批次,并且每个批次包含不同的图像数据,所以应该对每个批次运行 train_neural_network。这可以用简单的代码来完成,如代码 13 所示。代码 13 为每个批次运行 10 个时期的训练,图 10 显示了训练结果。

Code 13. train over batches

Fig 10. loss and accuracy

测试模型

Fig 11. prediction result

参考

花旗自行车 2017 年分析

原文:https://towardsdatascience.com/citi-bike-2017-analysis-efd298e6c22c?source=collection_archive---------5-----------------------

此分析的目标是创建 2017 年花旗自行车的运营报告。以下工作在不到五个工作日内完成。在每张图片下,我都加入了自己的想法,如果没有时间限制,我会考虑哪些内容。花旗自行车的分析是基于如下所示的模拟案例:

概述:您的客户,纽约市市长,需要更好地了解花旗自行车骑行的情况。他想要一份 2017 年的运营报告,在周末之前放在他的办公桌上。根据之前的约定,我们知道市长非常喜欢在图表中可视化数据。具体来说,市长希望看到各种数据可视化,以了解

  • 开始次数最多的前 5 个电台(显示开始次数)
  • 按用户类型划分的行程持续时间
  • 基于始发站和停靠站的最受欢迎的行程)
  • 基于平均行程距离(站到站)、中间速度(行程持续时间/行驶距离)的按性别和年龄划分的骑手表现
  • 2017 年纽约最忙的自行车是什么?用了多少次?使用了多少分钟?

此外,市长有一个想法,他想推销给花旗自行车,并需要您的帮助来证明其可行性。他希望花旗自行车能给他们的自助服务终端增加一项新功能:“输入一个目的地,我们会告诉你行程需要多长时间”。我们需要你建立一个模型,在给定起点和目的地的情况下,预测一次旅行需要多长时间。

客户:比尔·白思豪纽约市市长
目标:通过创建 2017 年运营报告,帮助市长更好地了解花旗自行车骑行情况(仅限纽约市)。

提问:

  1. 开始次数最多的前 5 个电台(显示开始次数)
  2. 按用户类型划分的行程持续时间
  3. 最受欢迎的行程(基于始发站和停靠站)
  4. 基于平均值按性别和年龄划分的骑手表现。行程距离(站与站之间)、中间速度(行程持续时间/行驶距离)
  5. 2017 年纽约最忙的自行车是什么?用了多少次?使用了多少分钟?
  6. 一个模型,可以预测一次旅行需要多长时间,给定一个起点和目的地(不要使用谷歌地图 API)。

数据来源于花旗自行车的亚马逊服务器,可以在这里访问。本文使用的代码可以在这里找到。*

首先,让我们最小化来自服务器的数据集中的工作和负载。很明显,这些文件非常大,每个都有几百兆字节。

!curl -O "[https://s3.amazonaws.com/tripdata/2017[01-12]-citibike-tripdata.csv.zip](https://s3.amazonaws.com/tripdata/2017[01-12]-citibike-tripdata.csv.zip)"
!unzip '*.zip'
!rm *.zip
files = !ls *.csv #For Ipython only
df = concat([read_csv(f, header=None,low_memory=False) for f in files], keys=files) 

列名中有空格,出于工作目的,最好将其删除。如果我在一个团队或者一个长期项目中工作,我会稍微不同地配置列名,使它们更容易使用。然而,为了本文的目的,我保持了简单易懂的名称。

数据集非常庞大,大约有 1600 万行。大数据工具会有所帮助,但是,大多数需要您付费或拥有企业许可证或有限试用。此外,数据非常脏。不同的文件有不同的列名,需要考虑这一点。白思豪市长没有技术背景。这里的图表尽可能简单但信息丰富。我本可以做出更复杂的情节,但是,对市长来说,这些情节不会提供太多信息。这些图表是为用户设计的。

最后,我的分析尽量遵循下面概述的 crisp-dm 方法。

Taken from SafariBooksOnline.com

让我们来理解我们正在处理的数据,并简要概述每个特性代表或应该代表什么。

1\. Trip Duration (seconds) — How long a trip lasted
2\. Start Time and Date - Self explanatory
3\. Stop Time and Date - Self explanatory
4\. Start Station Name - Self explanatory
5\. End Station Name - Self explanatory
6\. Station ID - Unique identifier for each station
7\. Station Lat/Long - Coordinates
8\. Bike ID - unique identifier for each bike
9\. User Type (Customer = 24-hour pass or 3-day pass user;  Subscriber = Annual Member) - Customers are usually tourists, subscribers are usually NYC residents
10\. Gender (Zero=unknown; 1=male; 2=female) - Usually unknown for customers since they often sign up at a kiosk
11\. Year of Birth - Self entered, not validated by an ID.

第 1 部分:排名前五的电台

让我们检查一下在创建图表之前是否有任何干扰或需要清理的地方。

  1. 有缺少的值吗?

  • 大多是出生年份
  • 用户类型很少。
  • 花旗自行车客户(一日通票或三日通票)通常是游客,可能不会匆忙或因其他原因填写出生年份
  • 花旗自行车的用户往往是纽约市的居民,通过盲目删除缺少值的行,我们将丢失关键信息,并可能引入偏见。

2.让我们了解一下我们正在处理的数据:

3.花旗自行车骑手经常会碰到坏掉的自行车。作为用户,我对这种困境相当熟悉。让我们删除任何行程持续时间少于 90 秒的行程起点站==终点站。90 秒是一个任意的选择,基于骑车人意识到自行车工作不正常并回到车站归还自行车并换上新自行车所需的时间。另一个可以使用的度量是 372 秒(25%四分位数)。这是基于这样一个假设,如果某人正在进行一次往返旅行,它最有可能是执行一些快速的任务,这些任务离得不够近,不能步行到达,因此这次旅行应该至少比最短的旅行稍微长一点。如果是短途旅行,让我们添加额外的条件,以确保起点和终点站名相同。

4.诸如盗窃和破损码头之类的异常情况对这个指标来说不重要,可以在以后处理。

Considered a pie chart for this, however, these stations make up less than 5% of the total starts in this dataset

下一步和业务用例:在地图上可视化这些车站,看看它们彼此之间有多近,会很有趣。这可用于确定哪些区域需要额外的加油站或自行车。

第 2 部分:按用户类型划分的行程持续时间

就如何处理异常而言,这个问题有点不清楚,所以我将制作两个图表。一个有异常,一个没有。

用户类型的数据集中有 NA 值,如上面缺失的表格图所示。因为它只占数据的 0.09%,所以可以安全地删除它。

根据花旗自行车的网站:年度会员每次骑行的前 45 分钟包括在内,日卡用户每次骑行的前 30 分钟包括在内。如果你想把自行车放在外面更久,每多 15 分钟只需额外支付 4 美元。

可以肯定的是,没有人(或很少人)愿意租一辆超过 2 小时的自行车,尤其是一辆笨重的 citibike。如果他们这样做了,假设他们是年度用户,他们将额外花费 20 美元。对于他们来说,如果他们想锻炼身体,买辆自行车会更经济;如果他们想骑自行车游览和探索这座城市,他们可以在中央公园骑辆自行车。可能有一个更好的方法来选择一个最佳的截止日期,但是,时间是客户项目的关键。或者只是接受治疗,再买一辆自行车。自行车的实际成本是 24 小时累计的。

异常:任何超过 2 小时(7200 秒)的行程都可能表明自行车被盗、异常或自行车停靠不正确。作为一名狂热的花旗自行车用户,我亲身体会到一个人骑自行车超过一个小时是没有任何意义的!不过,我加了一个小时的缓冲以防万一。没有骑手会计划超过允许的最长 45 分钟。然而,为了建模的目的,我计划在将来把这个时间减少到一个小时。

  1. 前半段——数据集中出现异常
  • 每种用户类型的平均行程持续时间条形图。这是有帮助的,但最好是看到一个盒子情节或小提琴情节。在几分钟内会更容易解释。

  • 第二张图是一个基本的小提琴图,包括了一些异常现象。正如我们所见,噪声太大,这是没有用的。最好不要出现异常情况。

2。后半部分—数据集中无异常

  • 基于用户类型的行程持续时间的信息量更大的图表,异常情况如上所述。“传单”已从下图中移除。

Note: User Type will most likely be a strong predictor of trip duration

  • 基于用户类型突出显示每次旅行平均持续时间的条形图

可以肯定地说,用户类型将是旅行持续时间的一个强有力的预测因素。这是目前需要注意的一点,我们可以稍后再回到这一点。

后续步骤&业务用例:客户每辆自行车允许 30 分钟,而用户每辆自行车允许 45 分钟。数据清楚地表明,消费者倾向于使用自行车的时间更长。如果主要关注的是在码头有自行车可用,那么目前的时间限制是有意义的。然而,如果花旗自行车希望以用户为中心,让客户每辆自行车有更多的时间是值得探索的。

第三部分:最受欢迎的旅行

要获得最受欢迎的旅行,最方便的方法是使用 pandas 中的 groupby 功能。它类似于数据透视表。

trips_df = df.groupby([‘Start Station Name’,’End Station Name’]).size().reset_index(name = ‘Number of Trips’)

groupby 功能使识别最受欢迎的旅行变得极其容易和方便。

下一步&业务用例:在地图上看到这一点会很有意思,看看骑手是从北到南、从东到西等等。此外,根据一天中的时间来查看最受欢迎的旅行也不错。这可以帮助 Citi Bike 根据一天中的时间来确定在哪里存放自行车以及在哪里有码头。假设骑车人早上朝一个方向去上班,晚上朝相反的方向回家。

第 4 部分:按性别和年龄划分的骑手表现

提问:根据平均行程距离(站与站之间)、中间速度(行程持续时间/行驶距离)按性别和年龄划分的骑手表现

让我们确保我们在这里处理的数据是干净的。

  1. 缺少性别和出生年份值?—检查上面的缺失表
  • 性别不行。出生年份是
  • 约 10%的人缺少出生年份。不是一大块数据。可以估算缺失值或删除它。由于它不到数据的 10%,可以安全地假设其余的 90%是数据的代表性样本,我们可以根据性别和起始站 ID 用中值替换出生年份。我选择这种方法是因为大多数同龄的人住在相似的社区(例如:年轻人住在东村,老年人住在上东区,等等。).这将在异常被消除和速度被计算之后进行。可能有更好的方法来估算这些数据,请在下面的评论部分分享你的想法。
df['Birth Year'] = df.groupby(['Gender','Start Station ID'])['Birth Year'].transform(lambda x: x.fillna(x.median()))

2.有异常吗?

  • 至于出生年份,有些人出生在 1960 年之前。我可以相信一些 60 岁的老人可以骑自行车,这是一个延伸,然而,任何人“出生”之前骑花旗自行车是一个异常和虚假的数据。可能会有一些老年人骑自行车,但可能性不大。
  • 我的方法是找出低于平均值的 2 岁标准差。计算出这个数字后,mean - 2stdev,我去掉了数据的尾端,1956 年之前的出生年份。
df = df.drop(df.index[(df['Birth Year'] < df['Birth Year'].mean()-(2*df['Birth Year'].std()))])

3.计算年龄栏,使视觉效果更容易理解:

df['Age'] = 2018 - df['Birth Year'];
df['Age'] = df['Age'].astype(int);

4.计算行程距离(英里)

  • 没有可靠的方法来计算自行车路线,因为没有每辆自行车的 GPS 数据,我们无法知道骑车人走了什么路线。
  • 可以使用谷歌地图,并使用纬度,长坐标找到自行车路线的距离。然而,这将需要超过 API 调用的每日限制。使用 geopy.distance 包,该包使用 Vincenty 距离,使用更精确的椭球体模型。这比哈弗辛公式更准确,但对我们的目的来说并不重要,因为地球的曲率对纽约市自行车出行的距离影响可以忽略不计。
  • 将来,对于这种规模的数据集,如果速度更快,我会考虑使用哈弗辛公式来计算距离。下面的代码在这样大小的数据集上运行时间太长。
dist = []
for i in range(len(df)):
    dist.append(geopy.distance.vincenty(df.iloc[i]['Start Coordinates'],df.iloc[i]['End Coordinates']).miles)
    if (i%1000000==0):
        print(i)

5.计算速度(分钟/英里)和(英里/小时)

  • (分钟/英里):可以像短跑时间(这个人跑多快)一样使用
df['min_mile'] = round(df['Minutes']/df['Distance'], 2)
  • (英里/小时):常规方法。英里/小时是一个容易理解的度量单位,也是大多数人习惯看到的单位。因此视觉将基于这种理解而产生。
df['mile_hour'] = round(df['Distance']/(df['Minutes']/60),2)

6.处理“循环”旅行

  • 循环旅行是在同一个车站开始和结束的旅行。这些行程的距离将为 0,然而,事实并非如此。这些点会扭曲数据和视觉效果。将删除它们以解决此问题。
  • 对于模型来说,这个数据也是无关紧要的。因为如果有人要进行一次循环旅行,唯一知道旅行要花多长时间的人是骑手,假设她/他知道。因此,为模型删除这些数据是安全的。
df = df.drop(df.index[(df['Distance'] == 0)])

7.我们有一些起始坐标为(0.0,0.0)。这些旅行是为了修理或其他目的而被带走的。这些应该被放弃。如果保持的话,这些行程的距离是 5389 英里。由于这个原因,我放弃了任何距离大得惊人的点。此外,我们还缺少一些值。因为它是很小的一部分,所以让我们根据性别和起始位置来替换丢失的值。

Apologies for separate images

  • 在一些行程中,骑车人的速度超过每小时 200 英里。这可能是由于用于距离计算的公式或一些其他错误。有记录以来,世界上在平坦路面上骑自行车最快的人达到了每小时 82 英里。可以肯定的是,花旗的自行车手没有一个能达到这个速度。由于这一点以及骑自行车者平均速度为 10 英里/小时的事实,我决定删除所有以英里/小时为单位的速度大于 20 英里/小时且小于平均值 2 标准偏差的数据,因为这可能是骑自行车者发现码头已满并使用另一个码头代替的往返。

8.数据清理后按年龄和性别划分的骑手表现(英里/小时)

There’s a bit of a difference in speed, however, it doesn’t seem drastic enough to have a major impact. Surprising thing is that age doesn’t have a strong impact on speed either.

9.按年龄和性别划分的骑手平均里程表现

Barely a difference in distance travelled, age doesn’t seem to have an impact either except for folks aged 16–25

下一步&业务用例:值得探究基于性别和年龄的旅行次数。这有助于根据自行车使用情况创建不同的顾客购物篮。如果工作人员更频繁地使用花旗自行车,他们可能会被收取更高的费用。如果老年人使用花旗自行车,他们应该因为保持健康和活跃而受到奖励。这些信息可以传达给他们的保险公司,以奖励他们对健康的关注。

第 5 部分:按使用时间和分钟划分的最繁忙自行车

提问:

  1. 2017 年纽约最忙的自行车是什么?
  2. 用了多少次?
  3. 使用了多少分钟?
  • 最繁忙的自行车和计数可以通过 groupby 函数来识别。下面的功能还将识别自行车被使用的次数
bike_use_df = df.groupby(['Bike ID']).size().reset_index(name = 'Number of Times Used');
bike_use_df = bike_use_df.sort_values('Number of Times Used', ascending = False);

Most popular bike by number of times used: Bike 25738 (2355 times)

  • 一个类似的 groupby 函数调用 sum on minutes,它可以识别自行车被使用的分钟数。
bike_min_df['Minutes Used'] = df.groupby('Bike ID')['Minutes'].sum()
bike_min_df = bike_min_df.sort_values('Minutes Used', ascending = False)

Most popular bike by number of minutes used: Bike 25738 (31,340 minutes)

后续步骤&业务使用案例:如果结合花旗自行车维护数据,这些信息可用于确定自行车何时需要维护和修理。这有助于减少坏自行车占用车站码头的问题,这是许多骑车人面临的问题。这些信息也可用于建立品牌和营销目的。拥有一辆“花旗年度自行车”会很不错,这是公开宣传的最常用的自行车,作为增加纽约市自行车使用的象征。

第 6.1 部分:预测模型—基线模型

提问:建立一个模型,在给定起点和目的地的情况下,该模型可以预测旅行需要多长时间。

关于信息亭如何工作的假设: 让我们假设当用户输入起点和终点车站时,他们在输入起点和终点车站之前刷他们的密钥卡(如果他们是订户)并在信息亭上输入他们的信息(如果他们是“顾客”)。这意味着我们将知道他们的性别和年龄。因此,这些变量可用于建立模型。

第一步。

  • 这个数据集非常庞大。差不多一千四百万行。在我们构建和评估模型时,让我们研究一个随机子样本。如果我试图在整个数据集上构建和评估一个模型,每次运行将花费我大约 10 多分钟,具体取决于模型。决定使用哪部分数据的一个好方法是使用学习曲线。然而,我的内核在试图创建学习曲线时不断崩溃。如果我们要处理多年的数据,我们需要重新考虑这种方法。然而,鉴于上述原因,让我们抽取 10%的数据。它仍然有大约 130 万行,应该是一个有代表性的样本,因为它是随机选择的。为了确保它是一个有代表性的样本,我们应该查看原始数据集和样本数据集的描述。最后,我们可以通过使上面的图像与随机样本相似来确保数据具有代表性。10%的数据通过了上述测试。
  • 此外,花旗自行车旅行对订户的限制为 45 分钟,对客户的限制为 30 分钟(参见上文“根据花旗自行车网站”)。在这些各自的时间限制之后,骑手要付费。为了对我们的数据建模,包含持续时间超过规定的 45 分钟的行程是没有意义的。骑手不经常计划超过分配的时间,也没有明确的方法知道谁计划超过分配的时间。这是一个值得探讨的问题,然而,这些数据对于我们的模型来说是噪音。
df = df.drop(df.index[(df['Trip Duration'] > 2700)])
df_sample = df.sample(frac = 0.1, random_state = 0)

第二步。

  • 让我们得到一个基线。如果我只是运行一个简单的多元线性回归,我的模型会是什么样的,它会有多精确?需要为多元回归准备数据
  1. 删除不相关的列
  • 旅行持续时间:我们有分钟列,这是目标变量
  • 停止时间:在现实世界中,我们在预测行程持续时间时不会有这些信息。
  • 起点桩号 ID:起点桩号名称捕获此信息
  • 起点桩号纬度:起点桩号名称捕获此信息
  • 起点桩号经度:起点桩号名称捕获此信息
  • 起点坐标:起点桩号名称获取此信息
  • 终点桩号 ID:终点桩号名称捕获此信息
  • 终点桩号纬度:终点桩号名称捕获此信息
  • 终点桩号经度:终点桩号名称捕获此信息
  • 终点坐标:终点桩号名称获取此信息
  • 自行车 Id:我们不知道用户最终会使用哪辆自行车
  • 出生年份:年龄记录了这些信息
  • min_mile:当与距离结合时,实际上是与结束时间相同的信息。我们在现实世界中不会有这些信息。
  • mile_hour:当与距离结合时,实际上是与结束时间相同的信息。我们在现实世界中不会有这些信息。
(Speed * Distance = Trip Duration): Which is why speed is dropped
  • 起点桩号名称和终点桩号名称:距离变量捕获相同的信息。对于该模型,如果用户输入起点和终点,我们可以构建一个简单的函数来计算距离,这将捕获相同的信息。有人可能会认为应该保留这些信息,因为这是将在信息亭提供的信息。然而,假设有超过 800 个站,如果我们保留这些信息,我们需要为任何回归算法对其进行编码。这将创建 800 个要素(约 1500 万行),产生大量数据,但没有多少信息增益。
  • 在上述清理之后,用于基线模型的最终预测因子是距离、用户类型和性别。从第四部分的图片中可以看出,年龄似乎没有影响。为了证实这一点,我运行了有年龄和无年龄的模型。年龄对模型几乎没有影响。

  • 我选择进行线性回归。数据的规模和资源的限制使得运行更复杂的模型变得不那么有吸引力。集成算法已经过测试,但是运行时间太长。
  • 这个模型对于一个 R 值为 0.774 的基线模型来说是相当好的。距离似乎对旅行持续时间有很大的影响,这是有道理的。

第 6.2 部分:预测模型—包括日期

  • 进行改进的步骤:

1.按以下格式添加回溯时间

  • 是在工作日还是周末乘车。工作日,大部分时间是上下班高峰期,可能是从家到单位。周末可能是一个更长,更休闲的旅程,并且有更高的可变性。
  • 中的乘车时间是上午、下午、晚上还是晚上。准确的时间将基于基于一天中不同时间的旅行持续时间的差异。会在下面有图片。

2.现在是什么季节?

  • 十二月—二月=冬天
  • 三月—五月=春天
  • 六月—八月=夏天
  • 9 月—11 月=秋季
def get_date_info(df):
    df['d_week'] = df['Start Time'].dt.dayofweek
    df['m_yr'] = df['Start Time'].dt.month
    df['ToD'] = df['Start Time'].dt.hour df['d_week'] = (df['d_week']<5).astype(int) df['m_yr'] = df['m_yr'].replace(to_replace=[12,1,2], value = 0)
    df['m_yr'] = df['m_yr'].replace(to_replace=[3,4,5], value = 1)
    df['m_yr'] = df['m_yr'].replace(to_replace=[6,7,8], value = 2)
    df['m_yr'] = df['m_yr'].replace(to_replace=[9,10,11], value = 3)

    df['ToD'] = pd.cut(df['ToD'], bins=[-1, 5, 9, 14, 20, 25], labels=['Night','Morning','Afternoon','Evening','Night1'])
    df['ToD'] = df['ToD'].replace(to_replace='Night1', value = 'Night')
    df['ToD'] = df['ToD'].cat.remove_unused_categories()

    df['m_yr'] = df['m_yr'].astype('category')
    df['d_week'] = df['d_week'].astype('category')return(df)

  • 模型 1:R 中可忽略的改进:77.7%(取决于所使用的 random_state)
  • 安全地假设我们可以放弃这些变量,因为它们没有重大影响。
  • 有点令人惊讶的是,工作日变量几乎没有影响,因为人们最有可能在周末骑自行车休闲,而不是工作。这可以通过获得骑手的分类来解释。可能很多花旗单车用户都是大学生。
  • 另一种可能性是,该特征的效果被这样的事实所扭曲,即在该数据集中既有客户又有订户,并且该特征对两个变量的效果是不同的。然而,现在还没有明确的解释。值得考虑为订阅者和客户建立一个单独的模型,因为他们的行为如第 2 部分所示有很大的不同。

第 6.3 部分:预测模型—改进模型 1

  • 下一步将根据性别和行程考虑速度和距离。由于无法对始发站和终点站进行编码(由于点的数量太多),我们正在丢失旅程本身的关键信息。我们需要另一种方法来替代这些措施。
  • 我可以做的另一个改变是将 age 放入桶中。然而,数据表明年龄对旅行持续时间没有相关性或影响。这是反直觉的,然而,我没有很好的理由来反驳这些数据。
  1. 包括基于行程(起点站+终点站)和用户类型的平均速度。
  • 旅行原因:有些旅行是上山,有些是下山。根据直觉,有些路线,比如穿过时代广场的路线,交通会很拥挤。
  • 用户类型的原因:根据数据,游客(客户)通常会比订户骑得更慢,并经常停车。

2.包括每次旅行的平均持续时间,基于:上述原因的旅行和用户类型

def get_speed_distance(df): df['Start Station Name'] = df['Start Station Name'].astype(str)
    df['End Station Name'] = df['End Station Name'].astype(str)
    df['Trip'] = df['Start Station Name'] + ' to ' + df['End Station Name']
    df['Trip'] = df['Trip'].astype('category')

    df['avg_speed'] = df.groupby(['Trip','User Type'])['mile_hour'].transform('mean')
    df['avg_duration'] = df.groupby(['Trip','User Type'])['Trip Duration'].transform('median')

    return df

  • 这个模型要好得多。但是还能更好吗?
  • 对出行持续时间有重大影响的一个因素是交通。然而,由于我们不知道骑手走的是哪条路线,所以很难整合这些信息。最后,谷歌地图 API 有使用上限,所以我们不能用它来轻松识别交通模式。

第 6.4 部分:预测模型—改进模型 2

  • 很多人认为天气是旅行持续时间的一个很好的预测因素。我个人不同意。天气影响用户是否会骑车,而不是他们会骑多长时间。如果下雪,我不会骑自行车去上班。如果天气好,我将骑自行车去上班。不管我的观点如何,我都要检验这个假设。如果天气不是一个强有力的指标,我将在下一个模型中删除它。
  • 气象数据是从国家环境信息中心获得的。来自网站的数据是每日总结。属性包括:高温(华氏度)、低温(华氏度)和降水量(英寸)。
def get_weather(df):
    df['DATE'] = to_datetime(df['Start Time'].dt.date)
    df = df.merge(df_weather, on = 'DATE', how = 'left')
    return df

  • 模型几乎没有改进。天气几乎没有影响。
  • avg_duration 的系数急剧上升。不知道为什么,但较高的系数是有意义的,因为持续时间是我们的目标变量,avg_duration 是一次旅行最可能花费多长时间的可靠代理(锚)。
  • 让我们通过交叉验证来确认模型的有效性:
CV accuracy: 0.874 +/- 0.001

  • 基于上面的一些观察,我在没有天气和日期信息作为预测的情况下运行了上面的相同模型。
  • 正如我们所看到的,R 有非常小的下降。另一个有趣的观察是该数据对用户类型系数的影响,它几乎减半。
  • 对随机样本的影响很小,但是,对于 10 倍的数据量,影响可能会稍大一些,因此对于最终模型,我们保留日期信息。
  • 最后,我选择测试其他回归算法,比如随机森林,看看另一个回归变量是否表现得更好。出于运行时的考虑,我选择保持 n_estimators 较低。当此参数设置为 80 时,模型需要 10 分钟运行,R 与线性回归的 R 相同。通过优化其他参数(如 min_samples_leaf)来追踪随机森林可能是值得的。一种方法可能是查看行程持续时间的分布,以确定花费 5-6 分钟、6-7 分钟等的行程数量。这可以帮助识别 min_samples_leaf 参数。在现实世界中,我们不需要精确到精确到秒。只要我们能在一分钟内预测旅程需要多长时间,在我看来这就是一个可靠的结果。谷歌地图不会告诉你你的旅程需要多长时间,精确到秒,它会给你以分钟为单位的整数预测。

第 6.5 部分:预测模型—最终模型

  • 我本来可以使用 XGboost 和其他高级算法,但是,对于这种规模的数据集,运行时间太长,而且即使有收益也不值得。
  • 最终模型:线性回归(值得探索套索)
  • 预测因素:基于行程和性别、用户类型和日期信息的距离、性别、平均持续时间和平均速度

CV accuracy: 0.852 +/- 0.000

*代码是一项正在进行的工作,并且会根据您的反馈不断进行更改和改进。请在下面的评论区留下你的想法。

花旗自行车:泽西城加入了吗?

原文:https://towardsdatascience.com/citi-bike-has-jersey-city-jumped-on-board-4c29e5017196?source=collection_archive---------18-----------------------

乘客使用情况、模式和城市最受欢迎的自行车站点

当我第一次听说花旗自行车将在泽西城推出时,我欣喜若狂。夏天的许多周末早晨,我会去林肯公园散步,感受微风,迈着轻快的步伐。我把花旗自行车看作是对我无忧无虑的童年时代的回归,在公园里骑自行车,外加有氧运动。赢赢!如果我喜欢它,我会在纽约的日常通勤中尝试一下,因为 JC 会员资格也允许在那里使用。

Citi Bike NYC 于 2013 年 5 月 23 日推出,拥有 332 个自行车站点和 6,000 辆自行车。两年多后,花旗自行车新泽西城于 2015 年 9 月 21 日开业,共有 35 个站点和 350 辆自行车。进展如何?其他人会像我一样兴奋地加入并把它用于娱乐或日常通勤吗?在泽西城骑花旗自行车的到底是谁?

我把我的探索集中在两个最重要的问题上:

背线用法
首先,全面概述一下花旗自行车 JC 的用法。

Figure A: Citi Bike Jersey City Cumulative Trips — September 21, 2015 (Launch) to July 26, 2016

在 10 个月内进行了超过 161,000 次旅行(图 A),平均每天 520 次旅行。相比之下,纽约在 2015 年有 1000 万次旅行,大约每天 2.7 万次。

Figure B: Citi Bike Jersey City Trips per Month
Trips taken September 21, 2015 to July 26, 2016

每月乘客量如何?

月度细分(图 B)显示,随着 2016 年 5 月和 6 月这几个温暖的月份的到来,使用量有所增加。7 月份的数据不完整,但与 6 月份的趋势一致。

乘客量模式
我们对整个泽西城的乘客量进行了概述,但是所有泽西城的乘客量是否相等?我们先来看看泽西城所有的花旗自行车站。

截至 2016 年 7 月,泽西城共有 47 个车站。更多车站(Astor Place、Communipaw & Berry Lane、Brunswick & 6th 等。)已被添加。

下面的地图显示了 JC Citi 自行车站的使用情况,其中包括从一个 Citi 自行车 JC 站开始的所有行程。前 10 个最活跃的车站中有 9 个位于 JC 市中心(从该车站出发的乘车总次数),唯一一个异常的 Sip 大道位于 Journal Square。

** Citi Bike Jersey City trips taken September 21, 2015 to July 26, 2016

你还会注意到使用范围已经扩展到了泽西城以外,进入了曼哈顿,甚至布鲁克林。这是非常小的一部分,在 161,000 次旅行中只有 84 次,但仍然很有趣。2 个可能的解释:1)泽西城的骑车人把自行车带上轨道列车,或者骑着自行车穿过桥梁和隧道进入纽约市,或者 2)花旗自行车的员工发现废弃的自行车,并在纽约市的车站重新装上。我没有亲眼见过这两种情况,但我更倾向于相信第二种情况

大多数最活跃的电视台都位于市中心,你对此感到惊讶吗?花旗自行车可能只是吸引了一部分客户。事实上,引用了 60%的花旗自行车用户居住在 07302 邮政编码,包括大部分市区。

Figure C: Citi Bike Jersey City Trips by Neighborhood, Start Station
Trips taken September 21, 2015 to July 26, 2016

如果我们直接观察邻近地区的出行(图 C),70%的出行始于市中心的一个车站,Journal Square 位居第二,但在所有出行中占 16%。

市中心有什么吸引了这么多用户?它真的对普通市区居民有吸引力吗?也可能不是骑手的问题,更多的是车站的位置问题。这些车站是否位于交通便利的地点,靠近步行交通便利的泽西城商业区或其他公共交通枢纽?

Figure D: Citi Bike Jersey City Most Popular Start Stations
Trips taken September 21, 2015 to July 26, 2016

让我们来了解一下!以下是最受欢迎/最活跃的起点站(图 D)。

****前 10 个车站中,有 5 个(Grove St PATH、Exchange Place、Sip Ave、Newport PATH、Essex Light Rail)距离其他形式的公共交通、PATH 站或轻轨非常近。在前 10 名中,Sip 大道甚至不在市中心。Sip Avenue 站就在 Journal Square 交通枢纽的外面,乘客可以乘坐轨道列车进入泽西城、霍博肯、曼哈顿市中心区的其他地区,或者选择乘坐巴士环游泽西城或前往霍博肯、巴约纳或曼哈顿。

****但是靠近交通枢纽并不是成功的立竿见影的方法。Garfield Ave、West Side 和 MLK 轻轨 Citi 自行车站的使用率都在三分之一以下。然而,市中心可能是一个神奇的社区——前 20 个车站中有 13 个在市中心。注意:莫里斯运河、泽西第六街&和泽西第三街&的使用率确实很低,但这些站点是 2016 年 7 月才增加的,所以你最多只能看到 3 周的使用率。此外,这里没有列出的几个市区车站没有任何乘客,但几个月后我们就可以看到采用率是否上升。

Figure E: Citi Bike Jersey City Most Popular Routes
Trips taken September 21, 2015 to July 26, 2016

最后,让我们从另一个角度来看乘客量:最受欢迎的路线(图 E)。

到目前为止,我们并不惊讶地得知 10 条最受欢迎的路线中有 8 条的起点或终点都在市中心。但是看看 4 号,麦金莱广场- > Sip Ave。麦金莱广场甚至没有打破我们的十大起点站,但是作为骑手常规路线的一部分,它就在那里。因为我是泽西城的居民,所以我能猜到原因。麦金莱广场自行车站就在哈德逊天主教地区高中外面,是一个相当活跃的公交车站。学生们可以离开教室,跳上一辆花旗自行车去 Sip Ave(就在期刊广场),然后换乘只有在 JSQ 站才有的 PATH 火车或公共汽车。

你有没有注意到最受欢迎路线的下半部分正好是上半部分路线的反方向?我乐在其中!这可能是一个迹象,表明这些骑车人正在遵循一个日常或至少是规律的模式:早上跳上一辆花旗自行车去上班,把它停靠在终点站(靠近另一个交通枢纽),在一天结束时,如果他们选择,就把花旗自行车直接开回家。然而,因为反向旅行的数字并不完全反映对应的,有可能他们正在寻找另一条回家的路。当然也可以反过来,前 5 条路线实际上可以从骑手的工作场所开始。我需要将路线数据按时间分段来找出答案。我们将把这个分析留到下一天。

在我的 的下一篇文章 中,我们将看看工作日与周末的使用情况,以及花旗自行车新泽西城骑行者的人口构成。

— —

花旗自行车出行信息数据来自泽西城开放数据门户 此处
花旗自行车站位置 此处

城市级项目#2

原文:https://towardsdatascience.com/cityclass-project-2-e08530dd0ccc?source=collection_archive---------7-----------------------

结论和进一步措施

urban pattern convolution layer

城市级—第一部分

令我高兴的是, 城市级 项目受到了城市规划专家、城市规划专家和 IT 专家的广泛关注。幸运的是,我赶上了机器学习的潮流,它在不同的领域传播。特别是可以在莫斯科研究所 Strelka “机器能看见”的文章中读到。

我从双方那里得到了很多有意义的反馈。这表明所选择的活动方向比以往任何时候都更重要,而且有必要继续这项工作。最重要的事件是受邀参加 Yandex Data &科学大会:城市,在那里我做了详细的报告(Yandex——俄罗斯最大的搜索引擎和 IT 公司。视频记录,俄语,见页面底部)。为这次活动准备了额外的材料,我将在下面概述这些材料。

城市+数据科学=:)

结论和补充

也许最重要的结论是,对于那些人们已经学习了多年的特定知识,机器学习的可能性非常大,并且委托给神经网络来做专家在大多数时间里做的事情。机器学习的这种结果可以完全改变既定的方法和实践。本研究项目是对本论文的实践验证。

人们特别感兴趣的是观察深层神经网络内层的图像。我的神经网络包括如下 3 个卷积层(LeNet-like):

#Keras  CNN-model
model = Sequential()model.add(Convolution2D(32, 3, 3, input_shape=(3, 300, 300)))#1 conv
model.add(Activation('relu')) #2 activation
model.add(MaxPooling2D(pool_size=(2, 2)))#3 MaxPoolingmodel.add(Convolution2D(64, 3, 3)) #4 conv
model.add(Activation('relu')) #5 activation
model.add(MaxPooling2D(pool_size=(2, 2))) #6 MaxPoolingmodel.add(Convolution2D(64, 3, 3)) #7 conv
model.add(Activation('relu')) #8 activation
model.add(MaxPooling2D(pool_size=(2, 2))) #9 MaxPoolingmodel.add(Flatten()) 
model.add(Dense(128)) #all connected layers
model.add(Activation('relu'))
model.add(Dropout(0.5))
model.add(Dense(nb_classes)) #7 classes
model.add(Activation('softmax'))

由于下面的过程,使用 theano 函数,我们可以从所需的层中获得图像数组,然后将它们可视化。

LayerID = 0  # layer to viz (0..8)output_layer = model.layers[LayerID].output 
output_fn = theano.function([model.layers[0].input], output_layer) output_image = output_fn(input_image)

在直觉层面上,神经网络的图像处理可以描述如下:

  • 在第一卷积层(1.conv ),网络感知输入图像,揭示其中的特征轮廓;
  • 在随后的层(2-6)上,识别出单独的结构,在这种情况下是道路和房屋;
  • 在最后一个卷积层(7.conv)上,将分离的结构组装成一些复合体,这些复合体是该类的特征,在此基础上图像被进一步分类。

分析中间图像,人们可以注意到隐藏的模式和启发,当考虑原始图像时并不总是清楚的。

俄罗斯城市的一些城市模式和内层可视化:

Private housing; Historic district

Urban blocks mid 20th; Microrayon

城市群分析和预测的新工具

基于在第一部分中获得的数据,可以获得所考虑城市的城市规划情况的概化方案。
需要强调的是,城市的一个区域超出了的行政边界。因此,机器学习是一种具有巨大潜力的工具,用于分析和修复发生在最大城市的聚集过程。今后,这些方案可用于制定总体规划和其他相关文件的方案。

根据我的经验,我认为在项目设计和城镇规划中使用机器学习的可能场景如下:

  • 总体规划方案
  • 帮助决策
  • 信息图表和商业分析
  • 与 CAD 和 BIM 设计系统集成
  • 描述和预测城市发展的新方法
  • 见解!

未来计划

CityClass 项目显示了使用机器学习作为与城市和集聚区合作的新工具的巨大潜力。因此,我将沿着以下方向发展我的工作室 建筑 :

  • 对世界其他城市的报道和分析
  • 从细胞网格撤退,基于街道网络的分裂和区分
  • 基于其他标准、类别的培训模型
  • 对象检测和生成
  • 过渡到张量流

кучуков/罗曼·库丘科夫—

建筑师、城市规划者和城市研究者;
工作室的创始人 建筑

市级项目

原文:https://towardsdatascience.com/cityclass-project-eng-15bc5fcd8e1?source=collection_archive---------1-----------------------

基于神经网络的城市模式识别

这是我长期项目【aitecture.com】的一部分

城市级—第二部分

人工智能技术现在已经渗透到经济的许多领域,建筑、设计和城市化也不例外。它们有巨大的潜力,直到完全修改已建立的方法和实践。我的研究是我们如何利用人工智能完成特定的任务——以俄罗斯城市为例识别城市模式。

和一个城市打交道,无论是城市规划、概念还是研究,都要把握它的结构。地图服务的可用性并不能给出城市的总体概念。

这种方法采用了神经网络,它可以学习如何识别不同的城市模式,最终得到一个整体的画面。所以我们可以对这个城市和它的景观有一个新的认识。

如果一个人在看卫星地图时能够区分工业区和住宅区,那么计算机就能为我们做到这一点。任务是训练它,从而将知识从人转移到神经网络。

在我的研究中,我分析了五个人口超过 100 万的俄罗斯大城市:

莫斯科,下诺夫哥罗德,喀山,萨马拉,叶卡捷琳堡。

许多俄罗斯城市的特点是它们有共同的城市发展模式(形态类型)。例如,住宅区由典型的系列建筑组成,根据一个原理——这种类型或住宅区称为‘微住宅区’。因此,俄罗斯城市的地貌类型可以在单一模式集合的基础上进行分析。

该方法包括两个阶段:

1)学习:培训模式

在这一阶段,获得足够数量的高质量训练数据集非常重要。为此,一个专家——一个可以对物体进行分类的人(在这种情况下——我自己),以随机的顺序,对数据库中的单个物体进行分类,例如总数的 10%。越大越好。然后,当训练数据集被收集时,就可以训练神经网络模型——分类器。

2)预测:样本分类

当模型被训练时,无限数量的样本可以通过它。输出是样本的预测类别。

我们训练了一台计算机,现在它为我们产生新的知识!

Preliminary (expert) classification

我用了一个工作流带:

  • GIS 包 Qgis,带模块 Open Layers for Google maps,还有我自己的脚本用于样本的初步分类和导出;
    -带有机器学习库的 Python 环境:Keras,Theano。

作为机器学习的模型,我使用了卷积神经网络(CNN),它用于 LeNet 项目。

LeNet project —handwriting recognition

对于 CityClass 项目,选择并分类了 1686 个样本( 1267 训练/ 419 验证)。有可能通过 70–75%的验证集实现分类的准确性,这对于小型数据库来说仅仅是一个很好的指标,并且考虑到不是所有的样本都可以明确确定。

模式的类别

所有城市被划分为一个网格,网格大小为 600 x 600 m,从中选择了 7 个典型的城市模式类别。根据样品中的主要成分,对整个样品进行了分类。

Classes: 1, 2, 3

  • 1 —私人住宅区;
  • 2 —历史街区,20 世纪初以前。;
  • 3 —拥有独立住宅建筑的城市街区,也就是所谓的“斯大林风格”,小写——20 世纪上半叶,1930-1960;

классы 4, 5, 6, 7

  • 4——大众住宅公寓建筑— 微型住宅,1960 年至 1990 年;
  • 5 —现代住宅开发,从 2000 年代开始;
  • 6—工业和公共区域:工业区、火车站、购物中心、体育场、基础设施;
  • 7 —自然和混合区域。

结果

莫斯科

7636 个样本

Moscow

公认的大区域,由许多瓦片组成:莫斯科的历史中心,公园,莫斯科的河床,工业区,城市主要部分以外的低层居住区网络。

城市的放大片段:

在放大的片段上,单个物体清晰可见,例如:列宁斯基前景(街道)、铁路基础设施、前 ZIL 工厂等。

其他城市也有类似的描述。

喀山

1389 个样本

Kazan

下诺夫哥罗德

1188 个样本

Nizhny Novgorod

翅果

691 个样本

Samara

叶卡捷琳堡

1254 个样本

Yekaterinburg

结论

我很高兴我设法以我构想的形式实现了这项研究的想法,同时达到了 70%以上的分类准确率的计划水平。

这只是如何在城市/城市发展实践中使用深度机器学习技术的一个例子。例如,你可以训练一个神经网络来区分区域和公共空间,提取它们的具体特征以便以后使用。

通过同样的技术,我们可以分类其他城市,例如在欧洲或美国。

从神经网络的内层获取图像也是一个好主意。这将是下列职位之一。

结果,我们用电脑看待城市的方式来看待城市。

基于 R 的大规模噪声数据集的分类

原文:https://towardsdatascience.com/classification-on-a-large-and-noisy-dataset-with-r-c10cf14cbae6?source=collection_archive---------6-----------------------

几天前,我写了一篇文章,描述了一个全面的监督学习工作流程,使用 caret 和 caretEnsemble 包进行多种建模。当时我提到我使用的是一种简单的T4,在某种意义上,它是全数字的,完全填充的(没有一个缺失值),没有分类特征,没有类别不平衡(当然,因为这是一个回归问题),并且它是一个相当小的数据集,只有 8 个预测值。

这感觉就像是作弊,但它确实帮助了我写的第一篇文章,也帮助我顺利地完成了整个工作流程,并最终使用caretEnsemble.做了一些多重建模

所以现在我决定把这个从简单难度提升到普通难度。

在这种意义上,我在我打算使用的 UCI 机器学习库中遇到了这个数据集

我们在这个数据集上遇到的新困难是什么?我来总结一下:

  1. 目标变量是分类二项式的,具有非常高的类别不平衡
  2. 数据集的大小相当大。训练集是 60,000 x 171,测试集是 16,000 x 171
  3. 巨大的价值缺失问题
  4. 异常值和多重共线性的潜在存在
  5. 第一类错误和第二类错误都有特定的成本,这就要求我们尽量减少第二类错误。

这是存储库所有者对数据集和任务的描述:

“数据集包含从日常使用的重型斯堪尼亚卡车上收集的数据。重点介绍的系统是空气压力系统(APS ),它产生压缩空气,用于卡车的各种功能,如制动和换档。数据集的正类包括 APS 系统特定组件的组件故障。负类包括与 APS 无关的部件出现故障的卡车。这些数据由专家选择的所有可用数据的子集组成。

出于专有原因,数据的属性名称已被匿名化。它由单个数字计数器和直方图组成,直方图由不同条件的仓组成。(…)总共有 171 个属性,其中 7 个是直方图变量。缺失值用“na”表示。

—挑战指标

失误分类的成本度量:

在这种情况下,成本 _1 指的是需要由一名机械师在车间进行不必要检查的成本,而成本 _2 指的是遗漏一辆故障卡车的成本,这可能会导致故障。

*Total_cost = Cost_1 * No_Instances + Cost_2 * No_Instances*

我们会试试看!

环境

1.1)我们试图预测什么?

我们需要预测系统故障的类型。它可以是 APS 的故障组件,也可以是与 APS 无关的故障组件。这一点非常重要,因为我们的预测误差会导致公司不必要的支出。具体来说,我们希望避免类型 2 错误(错过故障卡车的成本,这可能会导致故障)

2.2)这是什么类型的问题?监督学习还是非监督学习?分类还是回归?二元还是多类?单变量还是多变量?

这是一个具有多个特征的二元分类问题。

2.3)我们有什么类型的数据?

我们有两个 csv 文件,一个用于培训,一个用于测试。在实际数据开始之前,两者都显示了 20 个不重要的文本行,我们必须在导入数据框时跳过这些行。列名有一行,缺少的值用“na”表示,因此我们将确保在读取CSV 时包含这些值。

2.4)导入数据集

training_data <- read.csv("aps_failure_traning_set.csv",
                          skip = 20, 
                          na.strings = "na")test_data <- read.csv("aps_failure_test_set.csv",
                      skip = 20, 
                      na.strings = "na")

我们检查两个数据集的维度:

dim(training_data)
dim(test_data)[1] 60000   171
[1] 16000   171

2.5)激活项目期间要使用的包

library(dplyr)
library(caret)
library(caretEnsemble)
library(mice)
library(doParallel)
library(car)

探索性数据分析

2.1)查看数据(str 或 dplyr 的一瞥)。第一眼。有什么奇怪的吗?

导入集合时指定na.strings=”na"允许 R 将每个特性识别为数字。如果我们不这样做,每列中出现的 na 会自动导致它们被归类为字符类型。

使用下面的代码,我们可以看到除了我们的响应变量class,所有其他的特性都是数字的。

glimpse(training_data)glimpse(test_data)

2.2)它是一个“整洁”的数据集吗?需要“聚集”还是“分散”呢?它是以一种我们可以合作的方式呈现的吗?

很整洁。每行是一个观察值,每列是一个特征。

2.3)行名和列名可以吗?我们应该改变他们吗?

我看不出有什么理由要改变它们。

2.4)检查数据类型。他们还好吗?如果没有,转换

我们已经评估过数据类型是可以的。在这里,您还需要检查响应变量是否属于 factor 类型,以及预期的两个级别。

2.5)我们的响应/目标变量是什么?阶层失衡?研究一下

我们的目标变量是class,有两个级别: negpos 。积极类包括 APS 系统特定组件的组件故障。负类包括与 APS 无关的部件出现故障的卡车。

每组有多少个阴性阳性

summary(training_data$class)
summary(test_data$class) **neg   pos 
59000  1000 
  neg   pos 
15625   375**

让我们检查一下比例:

options(digits = 2)prop.table(table(training_data$class))
prop.table(table(test_data$class))**neg   pos 
0.983 0.017****neg   pos 
0.977 0.023**

好吧,看起来这里有个问题。阶级完全不平衡。

我们可能会想出一个无用的模型,将每个观察结果分类为阴性并获得 97.7%的准确性,所以让我们小心我们的准确性分数解释。

稍后我们会看到我们如何处理阶级不平衡。

2.6)其余功能。汇总统计数据。了解您的数据

我们正在处理 171 个特征,所以在整个数据集上调用summary()在视觉解释方面不会有太大帮助。相反,我们将使用summary()函数创建一个数据框。这将使我们能够计算一些新的统计数据,特别是与缺失值相关的统计数据,正如您将看到的,这是该数据的另一个大问题。

利用这个汇总数据框架,我们还将计算所有数据的平均四分位数。这也将允许我们了解更多关于特征的分布和丢失值的平均数。

options(scipen = 999)**summary_df** <- do.call(cbind, lapply(training_data[, 
                      2:ncol(training_data)], summary))
**summary_df_t** <- as.data.frame(round(t(summary_df),0))**names**(summary_df_t)[7] <- paste("Missing_values")summary_df_t_2 <- summary_df_t %>% 
                      mutate(obs = nrow(training_data),
                             Missing_prop = Missing_values / obs)print(summary_df_t_2)

Each row is a feature. In this case we are just looking at the first 10 features

summary_df_t_2 %>% summarise(Min = mean(Min.),
                             first_Q = mean(`1st Qu.`),
                             Median = median(Median),
                             Mean = mean(Mean),
                             third_Q = mean(`3rd Qu.`),
                             Max = max(Max.),
                             mean_MV = mean(Missing_values),
                             obs = mean(obs),
                             mean_MV_perc = mean_MV / obs)

Summary of all features using the mean of each column

我们可以看到,在 60,000 个样本中,每个特征的平均缺失值数为 5,000。这意味着每列平均有 8.3%的缺失值。太多了!

让我们对我们的测试集进行同样的检查:

同样,我们还有 8.4%的缺失值。我们将不得不处理他们,之后会有一个特别的部分。

2.7)分类数据/因素:创建计数表以了解不同的类别。全部检查一下。

除了我们的响应变量,我们不使用任何其他分类特征。

2.8)不必要的列?我们可以很快理解我们不需要的列。放下它们

到目前为止,我们还没有检测到任何要删除的列。这个我们以后再说。

2.9)检查是否有缺失值。多少?在哪里?删除它们?归咎于他们?

我们的特征平均存在超过 8%的缺失值。

因为我们不想失去很多信息,所以我们的方法是估算它们。但是首先,我们不想使用一种技术来分别估算我们的两个集合(训练和测试)。它必须是使用全部信息的一次性估算。为了做到这一点,我们将结合这两个集合,对它们进行处理,然后再次分离。

#replicate our sets
training_data_bind <- training_data
test_data_bind <- test_data#create a new column "set" to label the observations
training_data_bind$set <- "TRAIN"
test_data_bind$set <- "TEST"#merge them into 1 single set
full_dataset <- rbind(training_data_bind, test_data_bind)
dim(full_dataset)[1] 76000   172

我们最终得到包含 76,000 个样本的单个集合(16,000 个来自测试集,60,000 个来自训练集)。列数为 172 (171 个功能+ 1 个“设置”列)

缺失值插补

我们将使用包鼠标来估算缺失值。这里有一个关于鼠标如何工作的很好的解释

下面的公式允许我们使用均值插补来插补整个数据集:

set.seed(123)
imputed_full <- mice(full_dataset, 
                     m=1, 
                     maxit = 5, 
                     method = "mean", 
                     seed = 500)

现在我们存储估算值:

full_imputed <- complete(imputed_full, 1)

然后,我们检查是否仍然保持相同的尺寸:

dim(full_imputed)[1] 76000   172

现在让我们检查我们没有丢失值:

(na_count_full_imputed <-data.frame(sapply(full_imputed, function(y) sum(length(which(is.na(y)))))))

等等。如果您运行该代码并查看每一行,您会注意到有些特性仍然缺少值。具体来说有 9 行。

让我们来看看是什么导致了它们:

issue_columns <- subset(imputed_full$loggedEvents, 
                        meth == "constant" | meth == "collinear")
print(issue_columns)

我过滤了估算数据框的$loggedEvents属性。这里我们看到一些特征被标记为常数共线。其中一个是我们的集合列(我们用来把两个集合合二为一的那个),所以我们不担心那个。其余的主要是共线变量和一个常量变量。鼠标会自动跳过这些栏,让我们知道问题。我们希望删除这些要素,这样我们就有了一个完整的数据集,不会丢失任何值。

为此,我们首先存储列名,注意不要存储集合的列名(我们需要它)

#create vector of column names
issue_columns_names <- as.character(issue_columns[, "out"])
issue_columns_names <- issue_columns_names[-2]
print(issue_columns_names)[1] "cd_000" "bt_000" "ah_000" "bu_000" "bv_000" "cq_000" "cf_000" "co_000"

然后,我们使用存储的向量从数据框中移除这些列,并将其存储为最终的估算数据框:

full_imputed_filtered <- full_imputed[ , !(names(full_imputed) %in% 
                                      issue_columns_names)]
dim(full_imputed_filtered)[1] 76000   164

请注意,列数从 172 减少到了 164。

现在我们不再有缺失值了!(查一下!)

最后,是时候将我们的完整估算数据集再次分成训练集和测试集,我们需要将其分成与之前完全相同的样本。为此,我们只需使用我们的 set 列过滤数据帧。

#subset the full_imputed_filtered dataset
training_data_imp <- subset(full_imputed_filtered, set == "TRAIN")
test_data_imp <- subset(full_imputed_filtered, set == "TEST")#drop the "set" column, we don't need it anymore
training_data_imp$set <- NULL
test_data_imp$set <- NULL#check dimensions
dim(training_data_imp)
dim(test_data_imp)[1] 60000   163
[1] 16000   163

太好了!,我们有我们的训练和测试集分裂,没有丢失值!

2.10)检查异常值和其他不一致的数据点。箱线图。厨师的距离。DBSCAN?

对于该数据集,我们将使用库克距离:

cooksd <- cooks.distance(glm(class ~ ., 
                             family = "binomial", 
                             data = training_data_imp))

让我们画出结果:

plot(cooksd, 
     pch="*", 
     cex=2, 
     main="Influential Obs by Cooks distance") abline(h = 4*mean(cooksd, na.rm=T), col="red")

在这个图中,看似一条又黑又粗的黑线,实际上是我们所有的数据点。在右上角,我们还可以看到似乎有 1 个异常值,或者一堆异常值组合在一起。

让我们看看有多少:

outliers <- rownames(training_data_imp[cooksd > 4*mean(cooksd, na.rm=T), ])
print(outliers)[1] "617"   "3993"  "5349"  "10383" "10829" "18764" "19301" "21138" "22787" "24360" "24975" "29146" "30633" "33684"
[15] "38785" "45978" "50283" "51003" "52573" "53283" "54957" "57186"

根据 cook 的距离测试,总共有 22 个点被认为是异常值。

因为与我们的总数 60,000 相比,这是一个非常低的观察值,所以我决定不删除它们。这似乎只是测量中的可变性,而不是实验误差。

2.11)检查数字数据中的多重共线性

EDA 阶段的最后一步是检查多重共线性。我们已经删除了一些被小鼠检测为共线的列。这里,我们将分析有多少双变量关系具有高相关性,如果比例非常高:

sum((correlation > 0.5 | correlation < -0.5) & correlation < 1) / (162*162)
[1] 0.12sum((correlation > 0.7 | correlation < -0.7) & correlation < 1) / (162*162)
[1] 0.047sum((correlation > 0.9 | correlation < -0.9) & correlation < 1) / (162*162)
[1] 0.0055

这意味着在 26,244 个可能的变量相关性中:

  • 12%的人得分高于 0.5
  • 比 0.7 高 4.7%
  • 比 0.9 高 0.55%

我不会做更多的讨论,并且认为多重共线性在这一点上不是一个大问题。

特征工程

我们也不会花时间在这个已经加载了大量功能的数据集中设计功能。没有我们可以使用的额外信息。

系统模型化

我们现在已经为建模准备好了训练和测试数据集。我们估算了缺失值,移除了共线要素,并验证了异常值和多重共线性不是我们应该关注的大问题。

由于数据的大小,我们将训练一个逻辑回归模型和一个朴素贝叶斯模型。与 r andom forestsSVMs梯度推进模型等更先进的算法相比,两者都非常快。

我在这里不是为了赢得比赛,而是为了证明自己有一个可以接受的分数。

我将使用caretEnsemblecaretList()在同一时间用相同的重采样来训练两者。

请注意,我在trainControl()中指定了“上升”——采样。这将解决等级不平衡关于上采样的更多信息

registerDoParallel(3)
getDoParWorkers()set.seed(123)my_ctrl <- trainControl(method = "cv", 
                        number = 5,
                        classProbs = TRUE,
                        savePredictions = "final",
                        index = 
                        createResample(training_data_imp$class, 3),
                        sampling = "up",
                        allowParallel = TRUE) model_list <- caretList(class ~ .,
                        data = training_data_imp,
                        methodList = c("glm", "nb"),
                        metric = "Kappa",
                        tuneList = NULL,
                        continue_on_fail = FALSE,  
                        preProcess = c("center", "scale"),
                        trControl = my_ctrl)

我们的结果:

Logistic Regression model

Naive Bayes model

请注意,我们的准确性得分低于我们的无用户 预测全否定 模型的 97.7%。我们没有获得更高分数的原因是因为我们对数据进行了上采样,从而生成了新的数据点来修复类别不平衡。我们在 caret 的 trainControl 中将其作为一个参数集,所以我不会显示任何细节,但通过这样做,我们提高了预测正类(在这种情况下为“neg”)的能力,而不仅仅是为了最大限度地提高准确性。

对看不见的(测试)数据的性能

让我们快速检查一下混淆矩阵:

#Logistic Regression model
confusionMatrix(predict(model_list$glm,test_data_imp, type = "raw"), test_data_imp$class)#Naive Bayes model
confusionMatrix(predict(model_list$nb,test_data_imp, type = "raw"), test_data_imp$class)

Logistic Regression performance on test set

Naive Bayes performance on test set

根据每种错误的成本矩阵,我们的得分为:

逻辑回归模型:52 x 500 + 834 x 10 = 34,340

朴素贝叶斯模型:42 x 500 + 498 x 10 = 25,980

对于这种快速的建模来说,这已经是不错的表现了。我敢打赌,通过更多的努力,我们可以非常接近最佳的 3 名选手:

预期寿命数据的分类技术

原文:https://towardsdatascience.com/classification-techniques-on-life-expectancy-data-118e6f22a877?source=collection_archive---------15-----------------------

大陆分类法

Photo by chuttersnap on Unsplash

我们人类被赋予了分类的概念。我们对所有东西进行分类,从衣柜里所有的牛仔裤放在一个架子下,所有的衬衫放在另一个专为衬衫准备的架子上,到手机上的应用程序和电脑上的文件,每种文件或应用程序都有单独的文件夹。

现在,分类的一个更“数据科学”的定义是,它是一种数据分析形式,提取描述重要数据类别的模型或预测分类变量(类别或目标)值的任务。基本上,找出一个新的观察将属于哪一组预定义的类别。一个非常常见的例子是,我们希望将某些邮件归类为垃圾邮件,而将其他邮件归类为非垃圾邮件。机器能够通过从已知类别的训练数据中学习来完成这项任务。

只有当我们有离散标签作为输出时,才能使用分类算法。像上面的例子中,电子邮件是否被分类为垃圾邮件,只有两种可能的结果,这种情况被称为二元分类。

另一种类型是多标签分类。在多标签分类中,可以将多个标签分配给一个实例。这主要用于音视频分类、文本分类、情感分析中的情感分类等。

无论如何,这是继续阅读本文所需的基础知识和先决条件。

在本文中,我们将对各大洲进行分类,这是标签,将在预期寿命数据集中用作一个类别。

这是一个非常小的数据集,有 6 列 223 行,每个国家一行。栏目分别是排名、国家、整体生活、男性生活、女性生活和大洲。

为了执行这种分类,我们将使用 5 种不同的分类技术和算法,计算每种算法的精确度和准确度,并对它们进行比较。这 5 种分类算法是:

  • KNN — K 近邻算法使用类似距离函数(distance measures)的相似性度量对经过训练后的新数据点进行分类。
  • SVM —支持向量机是一种监督学习算法,它将创建一个模型,使用训练集将新的点分配到一个或另一个类别。根据问题,分配可以是线性的或非线性的。
  • OneR — OneR 基本上是一个规则算法,这个算法为数据中的每个预测器生成一个规则,然后选择误差最小的规则作为答案。尽管这看起来是一个非常简单的算法,因为它只生成一个规则,但它比一些更复杂的分类算法执行得更好。
  • RIPPER —RIPPER 是一个基于规则的学习器,它建立了一套识别类的规则,同时最小化了错误的数量。误差由被规则错误分类的训练样本的数量来定义。这是执行基于规则的分类的直接方式。
  • C 4.5 — C4.5 是一个统计分类器,因为它生成决策树。它像 ID3 一样从训练数据中构建决策树,并在树的每个节点上选择数据的属性,该属性最有效地将其样本集分成富含一个类或另一个类的子集。这是一种间接的基于规则的分类方法。

现在让我们从使用 R 编程的分析开始,让我们看看哪个分类器执行得最好。

我们将在整个代码中使用以下库/包:e1071、class、caret、rJava、RWeka。

#loading libraries
library("e1071")
library(class)
library(caret)
library(rJava)
library(RWeka)

数据预处理

  1. 数据预处理的第一步包括以下内容:
  • 使用 read.csv() 函数导入 R 中的数据集。
  • 通过查看数据集执行一些可视化的描述性分析,并使用 summary()和 str() 函数获得数据集的摘要。
  • 通过分解将类别标签 continental 转换为分类变量。
  • 一些不相关的列也将被删除,这些列不会在分析中使用。像第一个,秩列。
#importing csv file in R
dataset <- read.csv(file.choose())#displaying head(first five) elements
head(dataset) 
str(dataset)
#dimentions
dim(dataset) #Converting Continent to factor
dataset[c("Continent")]<- lapply(dataset[c("Continent")], factor)#removing the first (irrelevant) coulmn
dataset <- dataset[,-1]str(dataset)
summary(dataset)

输出

head(), str(), dim() functions

str(), summary() functions after the removal of the first column and the factor converstion

观察

尽管 Continent 列已经是 factor 数据类型,但我们仍然运行命令使其成为 factor。有了这个数据视图,我们可以清楚地了解数据的样子, head() 函数可以做到这一点。汇总函数向我们展示了一些重要的描述性信息。最重要的是,我们可以看到有多少国家位于哪个洲,这将有助于我们以后检查准确性。我们还可以观察整体、男性和女性预期寿命的均值,分别为 72.49、70.04 和 75.02。还可以观察中间值、四分位数、混合值和最大值。

2.对于数据预处理的第二部分,我们将:

  • 通过使用样本方法生成训练和测试元素的随机排列,将数据集以 80:20 的比例划分为训练集和测试集。
  • 将训练和测试样本保存在输出变量的列表中。
  • 我们可以通过打印输出变量来查看训练和测试样本。
#sampling 80% training data
traindata <- sample(seq_len(nrow(dataset)), size = floor(0.80 * nrow(dataset)))
data_train <- dataset[traindata, ]
data_test <- dataset[-traindata,]
t_train <- dataset$Continent[traindata]
t_test <- dataset$Continent[-traindata]output<-list(data_train,data_test,t_train,t_test)#a view of the devided data(into train and test)
print(output)

KNN-K 最近邻算法

KNN 分类将在预处理和训练方法的帮助下执行,可在 caret 包中获得。训练方法中的隧道长度将根据拟合模型结果选择为 20,这将帮助我们自动选择最佳值。

在我们的例子中,K 被选择为 5。此外,精确度用于选择使用最大值的最佳模型。

#KNN#setting seed
set.seed(12345)knn_train_test<-output
let_train<-knn_train_test[[1]]
let_test<-knn_train_test[[2]]#Preprocessing and training
trainX <- let_train[,names(let_train) != "Continent"]
preProcValues <- preProcess(x = trainX,method = c("center", "scale"))
print(preProcValues)#Fit Model- Using Caret's train model to find best k
ctrl <- trainControl(method="repeatedcv",repeats = 3)
knnFit <- train(Continent~., data = let_train, method = "knn", 
                trControl = ctrl,preProcess = c("center","scale"), 
                tuneLength = 20)
print(knnFit)
plot(knnFit)#Make predictions
knnPredict <- predict(knnFit,newdata = let_test )
knnPredict#Confusion Matrix
confusionMatrix(knnPredict, let_test$Continent )#Accuracy
knnoutput<-mean(knnPredict== let_test$Continent)
knnoutput

输出

preprocessing using the caret package and finding the knn fit i.e. value of K

plot depicting the choice of the value of K by using accuracy

prediction, confusion matrix and accuracy

观察

  • 首先,我们观察到,通过查看最高精度(通过重复交叉验证),K 的最佳值被选择为 5。
  • 该图还显示 K=5 时的最高精度值为 0.562,K=17 时的精度为 0.559。
  • KNN 的准确率是 44%。

SVM —支持向量机

SVM 分类功能将借助调整方法并使用 e1071 软件包进行部署。通过从调整方法中选择核为线性且成本为 1 来调整 svm 拟合分类。

#SVM #setting seed
set.seed(12345)train_test<- output
let_train<-train_test[[1]]
let_test<-train_test[[2]]#Fit model
svmfit <- svm(Continent ~., data = let_train, kernel = "linear", scale = FALSE)
svmfit
svm#Tune to check best performance
tuned <- tune(svm, Continent ~., data = let_train, kernel = "linear", ranges = list(cost=c(0.001,0.01,.1,1,10,100)))
summary(tuned)#Make predictions
p <- predict(svmfit, let_test, type="class")
length(let_test$Continent)
table(p, let_test$Continent)#Analyse results
#Confusion matrix
confusionMatrix(p, let_test$Continent )#Accuracy
#print(mean(p== let_test$Continent))
svmoutput<-mean(p== let_test$Continent)
svmoutput

输出

fitting the model using svmfit()

tuning to check for the best performance and predicting the classes

creating the confusion matrix and calculating the accuracy

观察

  • 我们观察到 SVM 的准确率为 55%

OneR —一个规则算法

#OneR#setting seed
set.seed(12345)oner_train_test<- output
let_train<-oner_train_test[[1]]
let_test<-oner_train_test[[2]]#Fitting model
model <- OneR(Continent~.,let_train)
model#prediction
pred <- predict(model, let_test)
predtable(pred,let_test$Continent)
summary(model)#confusion matrix 
confusionMatrix(pred, let_test$Continent)#Accuracy
acc<-mean(pred==let_test$Continent)
acc

输出

model 1/2

model 2/2

prediction() function, table and summary of the model

confusion matrix and accuracy

观察

  • 我们观察了使用训练数据映射的 178 个实例的建模。
  • 当使用测试数据进行预测时,只有 38 个正确分类的实例,而 140 个错误分类的实例,因为非洲被作为一个规则。
  • 这使得 OneR 算法的准确率只有 20%。

RIPPER —重复增量修剪以产生误差减少算法

Ripper 分类功能将借助 RWeka 包中的 JRip 方法进行部署。

#RIPPER Algorithm#setting seed
set.seed(12345)ripper_train_test<- output
let_train<-ripper_train_test[[1]]
let_test<-ripper_train_test[[2]]#fitting model using Weka control function of JRip
model1 <- JRip(Continent~., data=let_train) 
model1#prediction
pred1 <- predict(model1, let_test)
pred1table(pred1, let_test$Continent)
summary(model1)#confusion matrix
confusionMatrix(pred1, let_test$Continent)#Accuracy
acc<-mean(pred1==let_test$Continent)
acc

输出

modeling, prediction, tabulation of the prediction and summary

confusion matrix and accuracy

观察

  • 当使用测试数据进行预测时,95 个实例被正确分类,而 83 个被错误分类。
  • 混乱矩阵清楚地显示了哪个大陆被归类为什么。
  • 使用 RIPPER 算法可以观察到 48%的精度

C 4.5 算法

借助 RWeka 包中的 J48 方法部署了 C4.5 分类功能。

#C.45 Algorithm#setting seed
set.seed(12345)c45_train_test<- output
let_train<-c45_train_test[[1]]
let_test<-c45_train_test[[2]]# fit model-Using Weka Control function of J48
fit <- J48(Continent~., data=let_train)# summarize the fit
summary(fit)# make predictions
c45predictions <- predict(fit, let_test)# summarize accuracy
tb<-table(c45predictions, let_test$Continent)#Confusion Matrix
confusionMatrix(c45predictions, let_test$Continent )#Accuracy
#print(mean(c45predictions== let_test$Continent))
c45output<-mean(c45predictions== let_test$Continent)
c45output

输出

summary of the fit, confusion matrix and accuracy

观察

  • 通过总结拟合度,我们可以看到 138 个实例被正确分类,而 40 个被错误分类。
  • 使用 C4.5 算法得到的准确率为 48%
  • 精确度与 RIPPER 算法非常相似。

结论

最后,让我们列出本文中使用的各种分类器的所有精度值。

精度值——由分类器确定

  • KNN——44%
  • SVM——55%
  • OneR — 20%
  • 裂土器— 48%
  • C4.5 — 48%

显然,SVM 的表现远远超过了所有其他分类技术。RIPPER 和 C4.5 是最接近的,都显示出 48%的准确率,这是非常令人印象深刻的。OneR 算法表现最差,只有 20%的准确率。

在 Keras 中用深度学习对蝴蝶图像进行分类

原文:https://towardsdatascience.com/classify-butterfly-images-with-deep-learning-in-keras-b3101fe0f98?source=collection_archive---------5-----------------------

不久前,我在荷兰组织 Vlinderstichting 的网站上读到了一篇有趣的博文。每年他们组织一次蝴蝶计数。志愿者帮助确定他们花园里不同的蝴蝶种类。Vlinderstichting 收集并分析结果。

由于蝴蝶种类的确定是由志愿者完成的,这个过程不可避免地容易出错。因此,Vlinderstichting的工作量太大,因为他们必须手动检查提交的内容是否正确。

具体来说,有三种蝴蝶的 Vlinderstichting 得到了许多错误的判定。这些是

在本文中,我将描述拟合深度学习模型的步骤,该模型有助于区分前两种蝴蝶。

使用 Flickr API 下载图像

为了训练一个卷积神经网络,我需要 找到带有正确标签的蝴蝶图像 。当然,我可以自己给我想分类的蝴蝶拍照。他们有时在我的花园里飞来飞去…

开玩笑,那要花很长时间。为此,我需要一种自动获取图像的方法。为此,我通过 Python 使用了 Flickr API

设置 Flickr API

首先,我用 pip 安装了 flickrapi 包 。然后我在 Flickr 网站上创建必要的 API 键来连接 Flickr API。

除了 flickrapi 包之外,我还导入了 osurllib 包,用于下载图像和设置目录。

from flickrapi import FlickrAPI
import urllib
import os
import config

config 模块中,我为 Flickr API 定义了公钥和密钥。这只是一个 Python 脚本(config.py ),代码如下:

API_KEY = 'XXXXXXXXXXXXXXXXX'  // replace with your key
API_SECRET = 'XXXXXXXXXXXXXXXXX'  // replace with your secret
IMG_FOLDER = 'XXXXXXXXXXXXXXXXX'  // replace with your folder to store the images

出于安全原因,我将这些 密钥保存在一个单独的文件中 。因此,您可以将代码保存在公共存储库中,如 GitHub 或 BitBucket,并将 config.py 放在. gitignore 中。因此,您可以与其他人共享您的代码,而不必担心有人会访问您的凭据。

为了提取不同蝴蝶种类的图像,我写了一个函数download _ Flickr _ photos。我会一步一步解释这个函数。此外,我已经在 GitHub上发布了完整的代码。

输入参数

首先,我检查输入参数的类型或值是否正确。如果没有,我会抛出一个错误。参数的解释可以在函数的 docstring 中找到。

if not (isinstance(keywords, str) or isinstance(keywords, list)):
    raise AttributeError('keywords must be a string or a list of strings')if not (size in ['thumbnail', 'square', 'medium', 'original']):
    raise AttributeError('size must be "thumbnail", "square", "medium" or "original"')if not (max_nb_img == -1 or (max_nb_img > 0 and isinstance(max_nb_img, int))):
    raise AttributeError('max_nb_img must be an integer greater than zero or equal to -1')

其次,我定义了稍后将在 walk 方法中使用的一些参数。我为关键字创建了一个列表,并确定需要从哪个 URL 下载图像。

if isinstance(keywords, str):
    keywords_list = []
    keywords_list.append(keywords)
else:
    keywords_list = keywords
if size == 'thumbnail':
    size_url = 'url_t'
elif size == 'square':
    size_url = 'url_q'
elif size == 'medium':
    size_url = 'url_c'
elif size == 'original':
    size_url = 'url_o'

连接到 Flickr API

接下来,我连接到 Flickr API。在 FlickrAPI 调用中,我使用了配置模块中定义的 API 键。

flickr = FlickrAPI(config.API_KEY, config.API_SECRET)

为每种蝴蝶创建子文件夹

我将每种蝴蝶的图片保存在单独的子文件夹中。每个子文件夹的名称是蝴蝶物种的名称,由关键字。如果子文件夹还不存在,我就创建它。

results_folder = config.IMG_FOLDER + keyword.replace(" ", "_") + "/"
if not os.path.exists(results_folder):
    os.makedirs(results_folder)

在 Flickr 图书馆里漫步

photos = flickr.walk(
    text=keyword,
    extras='url_m',
    license='1,2,4,5',
    per_page=50)

我使用 Flickr API 的 walk 方法来搜索指定关键字的图像。这个 walk 方法与 Flickr API 中的搜索方法具有相同的参数。

文本参数中, 我使用关键字来搜索与该关键字相关的图片。其次,在 extras 参数中, 我指定 url_m 为小、中尺寸的图片。在这个 Flickcurl C 库中给出了关于图像大小和它们各自 URL 的更多解释。

第三,在 许可参数中, 我选择了带有非商业许可的图像。关于许可证代码及其含义的更多信息可以在 Flickr API 平台上找到。最后, per_page 参数 指定了我允许每页显示多少张图片。

因此,我有一个名为 的图片生成器 来下载图片。

下载 Flickr 图像

有了照片生成器,我可以下载搜索查询中找到的所有图片。首先,我得到了下载图片的具体网址。然后我增加 count 变量,并使用这个计数器来创建图像文件名。

使用 urlretrieve 方法,我下载图像并保存在蝴蝶种类的文件夹中。如果出现错误,我会打印出错误消息。

for photo in photos:
    try:
        url=photo.get('url_m')
        print(url)
        count += 1
        urllib.request.urlretrieve(url,  results_folder + str(count) +".jpg")
    except Exception as e:
        print(e, 'Download failure')

为了下载多种蝴蝶,我创建了一个列表,并在循环 中调用函数 download_flickr_photos。为了简单起见,我只下载了上面提到的三种蝴蝶中的两种。

butterflies = ['meadow brown butterfly', 'gatekeeper butterfly']
for butterfly in butterflies:
    download_flickr_photos(butterfly)

图像的数据扩充

在少量图像 上训练 convnet 将导致 过拟合 。因此,该模型在分类新的、看不见的图像时会出错。数据扩充有助于避免这种情况。幸运的是,Keras 有一些很好的工具来轻松转换图像。

我写了另一篇关于如何防止过度合身的文章,你可以点击下面的链接。

我想和我儿子在路上给汽车“分类”的方式做个比较。目前他只有 2 岁,还没有见过像成年人一样多的车。所以你可以说他的图像“训练集”相当小。因此,他更有可能将汽车分类错误。例如,他有时会误把救护车当成警车。

随着他年龄的增长,他会看到更多的救护车和警车,以及我将给他的相应标签。因此,他的训练集将变得更大,从而他将更正确地对它们进行分类。

出于这个原因,我们需要 向 convnet 提供比目前更多的蝴蝶图片 。一个简单的解决方案是数据扩充。简而言之,这意味着对 Flickr 图像应用一组变换。

Keras 提供了 大范围的图像变换 。但首先,我们必须转换图像,以便 Keras 可以使用它们。

将图像转换为数字

我们从导入 Keras 模块开始。我们将用一个示例图像来演示图像转换。为此,我们使用了 load_img 方法。

from keras.preprocessing.image import ImageDataGenerator, array_to_img, img_to_array, load_imgi = load_img('data/train/maniola_jurtina/1.jpg' )
x = img_to_array(i)
x = x.reshape((1,) + x.shape)

load_img 方法创建一个 Python 图像库文件。我们需要将它转换成一个 Numpy 数组,以便稍后在imagedata generator方法中使用。用方便的 img_to_array 方法就搞定了。因此,我们有一个 75x75x3 形状的数组。这些尺寸反映了宽度、高度和 RGB 值。

事实上,图像的每个像素有 3 个 RGB 值。这些范围在 0 到 255 之间,代表红色、绿色和蓝色的强度。较低的值代表较高的强度,较高的值代表较低的强度。例如,一个像素可以表示为这三个值的列表[ 78,136,60]。黑色将表示为[0,0,0]。

最后,我们需要添加一个额外的维度,以避免在应用转换时出现值错误。这是通过 整形 功能完成的。

好了,现在我们有东西可以用了。让我们继续转换。

旋转

通过指定一个 0 到 180 之间的值,Keras 将 随机选择一个角度 来旋转图像。它会顺时针或逆时针转动。在我们的例子中,图像最大旋转 90 度。

ImageDataGenerator 还有一个参数 fill_mode 。默认值为“最近”。通过在原始图像的宽度和高度范围内旋转图像,我们得到了“空”像素。fill_mode 然后使用最近的像素来填充这个空白空间。

imgGen = ImageDataGenerator(rotation_range = 90)i = 1
for batch in imgGen.flow(x, batch_size=1, save_to_dir='example_transformations', save_format='jpeg', save_prefix='trsf'):
    i += 1
    if i &gt; 3:
        break

方法中,我们指定将转换后的图像保存到哪里。请确保该目录存在!为了方便起见,我们还给新创建的图像加上前缀。flow 方法可以无限运行,但是对于这个例子,我们只生成三个图像。所以当我们的计数器达到这个值时,我们就中断 for 循环。你可以在下面看到结果。

宽度移动

width _ shift _ range参数中,您可以指定图像向左或向右移动的原始宽度的比率。同样,fill_mode 将填充新创建的空像素。对于其余的示例,我将只展示如何用相应的参数实例化 ImageDataGenerator。生成图像的代码与旋转示例中的代码相同。

imgGen = ImageDataGenerator(width_shift_range = 90)

在变换后的图像中,我们看到图像向右移动。空像素被填充,这使它看起来有点拉伸。

通过为height _ shift _ range参数指定一个值,同样可以实现上移或下移。

重新调节

在任何其他预处理之前,重新缩放图像会将每个像素的 RGB 值 乘以选定的值 。在我们的示例中,我们对值应用最小-最大缩放。因此,这些值的范围将在 0 和 1 之间。这使得值更小,模型更容易处理。

imgGen = ImageDataGenerator(rescale = 1./255)

剪(羊毛)

使用 剪切范围 参数,我们可以指定必须如何应用剪切变换。当该值设置得太高时,这种变换会产生相当奇怪的图像。所以不要定的太高。

imgGen = ImageDataGenerator(shear_range = 0.2)

一款云视频会议软件

这种变换将 放大到画面 内部。就像剪切参数一样,这个值不应该被夸大以保持图像的真实感。

imgGen = ImageDataGenerator(zoom_range = 0.2)

水平翻转

这种变换水平翻转图像。生活有时会很简单…

imgGen = ImageDataGenerator(horizontal_flip = True)

所有转换组合

现在我们已经分别看到了每个变换的效果,我们一起应用所有的组合。

imgGen = ImageDataGenerator(
    rotation_range = 40,
    width_shift_range = 0.2,
    height_shift_range = 0.2,
    rescale = 1./255,
    shear_range = 0.2,
    zoom_range = 0.2,
    horizontal_flip = True)i = 1
for batch in imgGen.flow(x, batch_size=1, save_to_dir='example_transformations', save_format='jpeg', save_prefix='all'):
    i += 1
    if i &gt; 3:
        break

设置文件夹结构

我们需要将这些图像存储在特定的文件夹结构中。因此,我们可以使用方法flow _ from _ directory来扩充图像并创建相应的标签。该文件夹结构需要如下所示:

  • 列车
  • 马尼奥拉 _ 尤尔蒂纳
  • 0.jpg
  • 1.jpg
  • pyronia_tithonus
  • 0.jpg
  • 1.jpg
  • 验证
  • 马尼奥拉 _ 尤尔蒂纳
  • 0.jpg
  • 1.jpg
  • pyronia_tithonus
  • 0.jpg
  • 1.jpg

为了创建这个文件夹结构,我创建了一个要点img _ train _ test _ split . py。请随意在您的项目中使用它。

创建发电机

和以前一样,我们为训练生成器指定配置参数。验证图像将不会被转换为训练图像。我们只划分 RGB 值,使它们变小。

flow _ from _ directory方法从 train 或 validation 文件夹中获取图像,并生成 32 个转换图像的批次。通过将 class_mode 设置为‘二进制’,基于图像的文件夹名称创建一维标签。

train_datagen = ImageDataGenerator(
    rotation_range = 40,
    width_shift_range = 0.2,
    height_shift_range = 0.2,
    rescale = 1./255,
    shear_range = 0.2,
    zoom_range = 0.2,
    horizontal_flip = True)validation_datagen = ImageDataGenerator(rescale=1./255)train_generator = train_datagen.flow_from_directory(
    'data/train',
    batch_size=32,
    class_mode='binary')validation_generator = validation_datagen.flow_from_directory(
    'data/validation',
    batch_size=32,
    class_mode='binary')

不同的图像尺寸呢?

Flickr API 允许您下载特定大小的图像。然而, 在现实应用中,图像尺寸并不总是恒定的 。如果图像的纵横比相同,我们可以简单地调整图像的大小。否则,我们可以裁剪图像。不幸的是,很难在保持我们想要分类的对象完整的同时裁剪图像。

Keras 可以处理不同大小的图像。配置模型时,您可以在input _ shape中为宽度和高度指定 None。

input_shape=(3, None, None)  # Theano
input_shape=(None, None, 3)  # Tensorflow

我想展示的是,它可以处理不同的图像尺寸,然而,它有一些缺点。

  • 并非所有层(如展平)都将“无”作为输入尺寸
  • 运行起来计算量可能很大

构建深度学习模型

在本文的剩余部分,我将讨论卷积神经网络的结构,并用我们的 butterfly 项目中的一些例子来说明。在本文的最后,我们将有我们的第一个分类结果。

卷积神经网络由哪几层组成?

当然,您可以选择将多少层及其类型添加到您的卷积神经网络(也称为 CNN 或 convnet)。在这个项目中,我们将从以下结构开始:

让我们了解每一层的作用,以及我们如何用 Keras 创建它们。

输入层

这些不同版本的图像通过几次变换进行了修改。然后,这些图像被转换成数字表示或矩阵。

这个矩阵的尺寸将是 宽 x 高 x(颜色)通道数 对于 RGB 图像,通道数量为三个。对于灰度图像,这等于 1。下面你可以看到一个 7×7 的 RGB 图像的数字表示。

由于我们的图像大小为 75×75,我们需要在添加第一个卷积层时在 input_shape 参数中指定。

cnn = Sequential()
cnn.add(Conv2D(32,(3,3), input_shape = (3 ,75 ,75)))

卷积层

在前几层中,卷积神经网络将寻找的低级特征,如水平或垂直边缘。我们在网络中走得越远,它将寻找更高级的特征,例如蝴蝶的翅膀。但是,当它只获得数字作为输入时,它如何检测特征呢?这就是过滤器发挥作用的地方。

过滤器(或内核)

您可以将滤镜想象为扫描图像的特定大小的探照灯。下面的过滤器示例的尺寸为 3x3x3,包含检测垂直边缘的权重。对于灰度图像,尺寸应该是 3x3x1。通常,过滤器的尺寸小于我们要分类的图像。通常使用 3×3、5×5 或 7×7。第三维应该总是等于通道的数量。

扫描图像时,会转换 RGB 值。它通过将 RGB 值乘以滤镜的权重来完成这一转换。最后,相乘后的值在所有通道上求和。在我们的 7x7x3 图像示例和 3x3x3 滤镜中,这将导致 5x5x1 的结果。

下面的动画说明了这个 卷积运算 。为简单起见,我们只在红色通道中寻找垂直边缘。因此,绿色和蓝色通道的权重都等于零。但是您应该记住,这些通道的乘法结果会添加到红色通道的结果中。

如下所示,卷积层将产生数值结果。当您有较高的数字时,这意味着过滤器遇到了它正在寻找的特征。在我们的例子中,垂直边缘。

我们可以指定想要一个以上的过滤器。这些过滤器可以在图像中寻找它们自己的特征。假设我们使用 32 个大小为 3x3x3 的过滤器。在我们的示例中,所有过滤器的结果叠加在一起,最终得到一个 5x5x32 的体积。在上面的代码片段中,我们添加了 32 个大小为 3x3x3 的过滤器。

进展

在上面的例子中,我们看到滤镜 一次上移 一个像素。这就是所谓的跨步。我们可以增加过滤器上移的像素数量。增加步幅将更快地减小原始图像的尺寸。在下面的示例中,您可以看到滤镜如何以步长 2 移动,这将导致 3x3x3 滤镜的 3x3x1 结果和 7x7x3 图像。

填料

通过应用滤镜,原始图像的 维度被快速缩小 。尤其是图像边缘的像素在卷积运算中只使用一次。这导致了信息的丢失。如果要避免这种情况,可以指定填充。填充会在图像周围添加“额外像素”。

假设我们在 7x7x3 图像周围添加一个像素的填充。这产生了 9x9x3 的图像。如果我们应用一个 3x3x3 的过滤器,步长为 1,我们最终得到 7x7x1 的结果。因此,在这种情况下,我们保留原始图像的尺寸,外部像素被多次使用。

您可以计算具有特定填充和步长的卷积运算的结果,如下所示:

1 + [(原始维度+填充 x 2 —过滤维度)/步幅大小]

例如,假设我们有这样的 conv 层设置:

  • 7x7x3 图像
  • 3x3x3 过滤器
  • 1 个像素的填充
  • 2 像素的步幅

这将得出 1+[(7+1 x 2–3)/2]= 4

为什么我们需要卷积层?

使用 conv 层的一个好处是估计的参数数量 要少得多 。比普通隐藏层低得多。假设我们继续使用 7x7x3 的示例图像和 3x3x3 的滤镜,没有填充,步幅为 1。卷积层将有 5x5x1 + 1 个偏差= 26 个权重要估计。在隐层中具有 7x7x3 输入和 5x5x1 神经元的神经网络中,我们将需要估计 3.675 个权重。想象一下,当你有更大的图像时,这个数字是多少…

ReLu 层

整流线性单元层。 这一层给网络增加了非线性。卷积层是线性层,因为它将滤波器权重和 RGB 值的乘积相加。

对于 x <= 0. Otherwise, it is equal to the value of x. The code in Keras to add a ReLu layer is:

*cnn.add(Activation(‘relu’))*

Pooling

Pooling aggregates the input volume in order to 的所有值,ReLu 函数的结果等于零。进一步减小尺寸 。这加快了计算时间,因为要估计的参数数量减少了。除此之外,通过使网络更加健壮,它有助于避免过拟合。下面我们举例说明最大池的大小为 2×2,步幅为 2。

Keras 中添加大小为 2×2 的池的代码是:

*cnn.add(MaxPooling2D(pool_size = (2 ,2)))*

全连接层

最后,convnet 能够检测输入图像中的更高级特征。然后,这可以作为全连接层的输入。在此之前,我们将展平最后一个 ReLu 层的输出。展平意味着我们把它转换成一个矢量。然后向量值被连接到完全连接层中的所有神经元。为了在 Python 中做到这一点,我们使用了以下 Keras 函数:

*cnn.add(Flatten())        
cnn.add(Dense(64))*

拒绝传统社会的人

就像合用一样,辍学可以帮助 避免过度适应 。在模型训练期间,它随机将输入的指定部分设置为零。辍学率在 20%到 50%之间被认为是有效的。

*cnn.add(Dropout(0.2))*

乙状结肠激活

因为我们想要产生一个 概率 图像是两个蝴蝶种类之一(即二进制分类),我们可以使用一个 sigmoid 激活层。

*cnn.add(Activation('relu'))
cnn.add(Dense(1))
cnn.add(Activation( 'sigmoid'))*

卷积神经网络在蝴蝶图像中的应用

现在我们可以定义完整的卷积神经网络结构,如本文开头所示。首先,我们需要导入必要的 Keras 模块。然后,我们可以开始添加我们上面解释的层。

*from keras.models import Sequential
from keras.layers import Conv2D, MaxPooling2D
from keras.layers import Activation, Flatten, Dense, Dropout
from keras.preprocessing.image import ImageDataGeneratorimport timeIMG_SIZE = # Replace with the size of your images
NB_CHANNELS = # 3 for RGB images or 1 for grayscale images
BATCH_SIZE = # Typical values are 8, 16 or 32
NB_TRAIN_IMG = # Replace with the total number training images
NB_VALID_IMG = # Replace with the total number validation images*

我做了一些额外的参数明确的 conv 层。这里有一个简短的解释:

  • kernel_size 指定过滤器的大小。因此,对于第一个 conv 层,这是 2×2 的大小
  • padding = ' same '表示应用零填充,这样原始图像尺寸被保留。
  • padding = ' valid '表示我们不应用任何填充。
  • data _ format = ' channels _ last '只是在 input_shape 参数中最后指定颜色通道的个数。
*cnn = Sequential()cnn.add(Conv2D(filters=32, 
               kernel_size=(2,2), 
               strides=(1,1),
               padding='same',
               input_shape=(IMG_SIZE,IMG_SIZE,NB_CHANNELS),
               data_format='channels_last'))
cnn.add(Activation('relu'))
cnn.add(MaxPooling2D(pool_size=(2,2),
                     strides=2))cnn.add(Conv2D(filters=64,
               kernel_size=(2,2),
               strides=(1,1),
               padding='valid'))
cnn.add(Activation('relu'))
cnn.add(MaxPooling2D(pool_size=(2,2),
                     strides=2))cnn.add(Flatten())        
cnn.add(Dense(64))
cnn.add(Activation('relu'))cnn.add(Dropout(0.25))cnn.add(Dense(1))
cnn.add(Activation('sigmoid'))cnn.compile(loss='binary_crossentropy', optimizer='rmsprop', metrics=['accuracy'])*

最后,我们编译这个网络结构,并设置损失参数为binary _ cross entropy,这对于二进制目标是好的,并使用 准确度 作为评估度量。

在指定了网络结构之后,我们为训练和验证样本创建生成器。在训练样本上,我们如上所述应用 数据扩充 。对于验证样本,我们不应用任何增强,因为它们仅用于评估模型性能。

*train_datagen = ImageDataGenerator(
    rotation_range = 40,                  
    width_shift_range = 0.2,                  
    height_shift_range = 0.2,                  
    rescale = 1./255,                  
    shear_range = 0.2,                  
    zoom_range = 0.2,                     
    horizontal_flip = True)validation_datagen = ImageDataGenerator(rescale = 1./255)train_generator = train_datagen.flow_from_directory(
    '../flickr/img/train',
    target_size=(IMG_SIZE,IMG_SIZE),
    class_mode='binary',
    batch_size = BATCH_SIZE)validation_generator = validation_datagen.flow_from_directory(
    '../flickr/img/validation',
    target_size=(IMG_SIZE,IMG_SIZE),
    class_mode='binary',
    batch_size = BATCH_SIZE)*

使用生成器上的flow _ from _ directory**方法,我们可以轻松地遍历指定目录中的所有图像。**

最后,我们可以在训练数据上拟合卷积神经网络,并用验证数据进行评估。模型的最终权重可以被保存并在以后重用。

**start = time.time()
cnn.fit_generator(
    train_generator,
    steps_per_epoch=NB_TRAIN_IMG//BATCH_SIZE,
    epochs=50,
    validation_data=validation_generator,
    validation_steps=NB_VALID_IMG//BATCH_SIZE)
end = time.time()
print('Processing time:',(end - start)/60)cnn.save_weights('cnn_baseline.h5')**

历元的数量 被任意设置为 50。一个时期是向前传播的循环,检查误差,然后在向后传播期间调整权重。

steps _ per _ epoch设置为训练图像的数量除以批量大小(顺便说一下,双除法符号将确保结果是整数而不是浮点数)。指定一个大于 1 的批量将会加快进程。validation_steps 参数同上。

结果

运行 50 个纪元后,我们的训练精度为 0.8091,验证精度为 0.7359。所以卷积神经网络仍然遭受相当多的过拟合。我们还看到验证的准确性变化很大。这是因为我们有一小组验证样本。最好每轮评估都做 k 倍交叉验证。但这需要相当长的时间。**

为了解决过度拟合问题,我们可以:

  • 增加辍学率
  • 在每一层应用下降
  • 查找更多培训数据

我们将研究前两个选项并监控结果。我们第一个模型的结果将作为基线。在应用额外的漏失层并增加漏失率后,模型的过度拟合程度会有所降低。

我希望你们都喜欢读这篇文章,并且学到了一些新的东西。完整代码可在 Github 上获得。干杯!

从音频数据中分类歌曲流派

原文:https://towardsdatascience.com/classify-songs-genres-from-audio-data-554546280817?source=collection_archive---------14-----------------------

这些建议非常中肯!这个播放列表怎么这么了解我?

Photo by bruce mars on Unsplash

介绍

在过去的几年里,拥有巨大目录的流媒体服务已经成为大多数人收听他们喜爱的音乐的主要方式。但与此同时,提供的音乐数量之多意味着用户在试图寻找符合他们口味的新音乐时可能会有点不知所措。

出于这个原因,流媒体服务已经开始研究对音乐进行分类的方法,以便进行个性化推荐。一种方法包括直接分析给定歌曲中的原始音频信息,根据各种指标对原始数据进行评分。在本文中,我将检查由一个名为 Echo Nest 的研究小组收集的数据。我们的目标是浏览这个数据集,将歌曲分为“嘻哈”或“摇滚”——所有这些都不需要我们自己去听。在这样做的过程中,我们将学习如何清理我们的数据,进行一些探索性的数据可视化,并通过一些简单的机器学习算法(如决策树和逻辑回归)使用特征约简来实现馈送数据的目标。

那么,让我们开始吧

  1. 加载并准备数据集

首先,让我们加载关于我们的跟踪的元数据以及由 Echo Nest 编译的跟踪度量。一首歌不仅仅是它的标题、艺术家和收听次数。我们有另一个数据集,它有每个音轨的音乐特征,比如从-1 到 1 的范围内的danceabilityacousticness。它们存在于两个不同的文件中,格式不同——CSV 和 JSON。CSV 是表示表格数据的流行文件格式,而 JSON 是另一种常见的文件格式,数据库经常使用这种格式返回给定查询的结果。

同样,让我们检查一下我们的数据框看起来像什么

。连续变量之间的成对关系

我们通常希望避免使用相互之间相关性很强的变量,从而避免特征冗余,原因如下:

  • 为了保持模型简单并提高可解释性(对于许多特性,我们冒着过度拟合的风险)。
  • 当我们的数据集非常大时,使用较少的特征可以大大加快我们的计算时间。

为了了解我们的数据中是否有任何强相关的特征,我们将使用pandas包中的内置函数。

从上面的图中,我们可以看到任何特征之间都没有很强的相关性。因此,我们不需要从数据中删除任何特征。

3。归一化特征数据

如前所述,简化我们的模型并使用尽可能少的必要特征来获得最佳结果是非常有用的。由于我们没有发现我们的特征之间有任何特别强的相关性,我们可以使用一种称为 主成分分析的通用方法来减少特征的数量。

不同流派之间的差异可能只由数据集中的几个特征来解释。PCA 沿最高方差轴旋转数据,从而允许我们确定数据的每个特征对类间方差的相对贡献。

但是,由于 PCA 使用要素的绝对方差来旋转数据,因此相对于其他要素而言,具有更大范围值的要素会压倒算法并使算法产生偏差。为了避免这种情况,我们必须首先规范化我们的数据。有几种方法可以做到这一点,但一种常见的方法是通过标准化,这样所有的特征都有一个mean = 0standard deviation = 1(结果是一个 z 值)。

让我们看看标准化后我们的数据框是什么样子的

4。对我们的缩放数据进行主成分分析

既然我们已经对数据进行了预处理,我们就可以使用 PCA 来确定我们可以将数据的维度减少多少。我们可以使用 scree-plots累积解释比率图来找到用于进一步分析的组件数量。

Scree-plots 根据每个组件解释的方差显示组件数,按方差降序排序。Scree-plots 帮助我们更好地理解哪些成分解释了我们数据中足够多的差异。当使用碎石图时,图中的“拐点”(从一个数据点到下一个数据点的陡峭下降)通常用于决定适当的截止点。

不幸的是,在该碎石图中似乎没有明显的弯头,这意味着使用该方法不容易找到固有维度的数量。

5。PCA 的进一步可视化

但是并没有失去一切!相反,我们也可以查看累积解释方差图来确定需要多少特征来解释,比如说,大约 90%的方差(这里的临界值有些随意,通常由“经验法则”决定)。一旦我们确定了合适的组分数量,我们就可以用那么多组分进行 PCA,理想地降低我们数据的维数。

现在,我们可以使用数据的低维 PCA 投影来将歌曲分类成流派。为此,我们首先需要将数据集分为“训练”和“测试”子集,其中“训练”子集将用于训练我们的模型,而“测试”数据集允许模型性能验证。

6。训练决策树对流派进行分类

在本文中,我们将使用一个简单的算法,称为决策树。决策树是基于规则的分类器,它接受特征并遵循二元决策的“树结构”,最终将数据点分类为两个或更多类别中的一个。除了易于使用和解释之外,决策树还允许我们将模型从训练数据生成的“逻辑流程图”可视化。

虽然我们的树的性能还不错,但是立即认为它是这项工作的完美工具是一个坏主意——总有其他模型表现更好的可能性!至少测试几个其他算法并找到最适合我们数据的算法总是一个值得的想法。

第七期。将我们的决策树模型比作逻辑回归

有时最简单的是最好的,所以我们将从应用逻辑回归开始。逻辑回归利用所谓的逻辑函数来计算给定数据点属于给定类别的概率。一旦我们有了这两个模型,我们就可以在一些性能指标上对它们进行比较,比如假阳性和假阴性率(或者有多少点被错误分类)。

我们的两个模型都做得很好,平均精度都达到了 87%。然而,在我们的分类报告中,我们可以看到摇滚歌曲被很好地分类了,但是嘻哈歌曲被不成比例地错误分类为摇滚歌曲。

为什么会这样?

好吧,仅仅通过查看每个类别的数据点数量,我们就可以看到摇滚类别的数据点远远多于嘻哈类别的数据点,这可能会扭曲我们的模型区分不同类别的能力。这也告诉我们,我们的模型的大部分准确性是由其仅分类摇滚歌曲的能力驱动的,这并不理想。

8。平衡我们的数据以获得更好的性能

考虑到这一点,我们可以对每个类别中正确分类的值进行加权,使其与每个类别中数据点的出现次数成反比。因为“摇滚”的正确分类并不比“嘻哈”的正确分类更重要(反之亦然),所以我们只需要在这里衡量我们的类别时考虑数据点的样本大小的差异,而不是每个类别的相对重要性。

我们现在已经平衡了数据集,但在这样做的过程中,我们删除了许多可能对训练我们的模型至关重要的数据点。让我们测试一下,看看平衡我们的数据是否能在保持总体分类性能的同时,改善模型对“岩石”分类的偏向。

9。平衡我们的数据集能改善模型偏差吗?

请注意,我们已经减小了数据集的大小,并且将在不应用任何降维的情况下继续前进。在实践中,当处理非常大的数据集和计算时间变得非常大时,我们会更严格地考虑降维。

成功!平衡我们的数据消除了对更普遍的阶级的偏见。为了更好地了解我们的模型实际表现如何,我们可以应用所谓的交叉验证 (CV)。这一步允许我们以更严格的方式比较模型。

10。使用交叉验证评估我们的模型

由于我们将数据分割成训练集和测试集的方式会影响模型性能,CV 尝试以多种方式分割数据,并在每次分割时测试模型。虽然有许多不同的 CV 方法,都有各自的优缺点,但我们在这里将使用所谓的 K 倍交叉验证。K-fold 首先将数据分成 K 个不同的大小相等的子集。然后,它迭代地使用每个子集作为测试集,同时使用剩余的数据作为训练集。最后,我们可以汇总每个折叠的结果,得到最终的模型性能分数。

现在,我们已经对我们的数据集执行了 k 倍交叉验证,我们可以非常确定我们的模型将在未来看不见的数据点上概括 72%的时间。

来源:https://www.datacamp.com/projects/449

基于自动视觉的猫狗图像分类

原文:https://towardsdatascience.com/classifying-cats-dogs-images-with-automl-vision-235b6d6bf27f?source=collection_archive---------20-----------------------

我第一次正式接触谷歌云平台是在 2018 年 11 月参加 CalHacks 5.0 的时候。我很快发现他们的云 AI 套件由一系列机器学习产品组成——Cloud AutoML、Cloud Natural Language、Cloud Vision API,仅举几例。

在本学期早些时候我的一次 DataX 课上,我们使用 Python Keras 库对猫和狗的照片进行分类。这给了我用类似的数据集工作的想法。出于一个更无聊的原因,我的兄弟们非常喜欢宠物(尤其是猫和狗),我认为部署这种模型对他们来说也是一件有趣的事情。

通过 Keras 进行图像分类通常需要我(1)找到并标记数据集;(2)训练一个 ML 分类器;(3)部署 ML 模型;& (4)使用 REST API 创建一个服务器来调用 web 上的 ML 分类器。

多亏了 Cloud AutoML,我们只需要执行上面的步骤 1!

数据集:猫和狗的图像

幸运的是,为此目的找到一个合适的数据集并不是一件容易的事情。我输入“kaggle 猫狗数据集”,这个链接作为谷歌搜索结果之一弹出。我分别选取了 150 张猫狗的图片,将这些图片导入到云平台上。之后,我给每张照片贴上“狗”或“猫”的标签。

Uploading a total of 300 images for the model (150 each for cats and dogs respectively)

培训和评估

下一步是训练模型。默认情况下,AutoML Vision 在训练模型时会将数据集随机分为 3 个独立的集合。

  • 训练数据集:80% —用于训练
  • 验证数据集:10% —用于超参数调整和决定何时停止训练
  • 测试数据集:10% —用于模型评估

对模型进行训练和评估后,我发现了以下情况:

Precision and Recall values for the Model

准确率和召回率都是 100% —这意味着什么?从所有被分配了猫/狗标签的测试示例中,所有的测试示例实际上都被准确地分类了。并且,在所有应该被分配了猫/狗标签的测试例子中,所有的例子实际上都被分配了正确的标签。

根据混淆矩阵,ML 模型能够准确地对所有照片进行分类(100%)。毕竟没有那么令人困惑。

用新图像进行预测

接下来,我用新图像测试了 ML 模型。我下载的数据集实际上有超过 10 000 张图片,所以我随机选择了一张狗和一张猫的图片,并将这些图片上传到模型中。

I uploaded an image of a cat for prediction, and the model was able to predict with 100% accuracy that it was indeed a cat!

Also predicted with 100% accuracy that it was a dog!

即使有了新的图像,这个模型也预测得很好。

不过,我不相信。所以我在网上寻找斯芬克斯的照片——这是一种与狗有着高度相似外貌的猫。我想知道 ML 模型是否会与这张图片混淆。

Sphynxes — a breed of cats that resembles dogs; I was mildy surprised to find out that the ML model was still able to classify this 100% with a “cat” label

事实证明,这个模型仍然能够以 100%的准确率预测出这是一张猫的照片。

但是…如果我们有一只猫和一只狗在同一个图像中会怎么样?

看起来这个模型在这里有点混乱——但是这绝对是我需要努力的地方。

滑稽的吉娃娃对松饼挑战怎么样?

你可能已经在互联网上看到了“吉娃娃 vs 松饼”的迷因——这里是。鉴于巧克力碎片松饼(事后看来也可能是巧克力碎片饼干)与吉娃娃的高度相似性,我想测试一下这个模型是否能区分这两者。

看起来它被愚弄了。但老实说,我认为这也可能让人类眼花缭乱。

下一步是什么?

鉴于猫狗分类是一个相对典型的机器学习图像分类问题,算法可能已经针对它进行了良好的训练。我们可以看到,当我们试图将分类问题复杂化时,出现了一些复杂性。

虽然它可能没有最复杂的算法来解决挑战性问题,但它仍然为非 ML 专家提供了一个非常友好的切入点来开始涉足一点 ML!

嗯,下次更好玩的实验!

使用无监督学习基于投票历史对科罗拉多县进行分类

原文:https://towardsdatascience.com/classifying-colorado-counties-based-on-voting-history-using-unsupervised-learning-aff83d20b64d?source=collection_archive---------12-----------------------

随着选举季节的临近,我想是时候写一写我几个月前做的一个项目了。这个项目围绕一个问题展开,“政治评论家如何判断一个县在历史上是投票支持民主党、共和党还是被认为是摇摆县?”我问了科罗拉多州的两位政治顾问这个问题,他们都以同样的方式回答了这个问题,“根据我们在科罗拉多州工作的经验,我们知道。”作为一名数据科学家和分析型思想家,这个答案并没有让我满意,因此我选择了这个项目。

带着一个问题,下一步是想出我将如何回答这个问题。第一部分是寻找、选择和收集我的数据。由于许多投票信息都是公开数据,我首先去了科罗拉多州的州务卿网站。接下来,我要对将要使用的数据做出一些选择。科罗拉多州州务卿的网站上有所有投票结果,所以我可以从所有可能的结果中选择。我知道,当人们投票给其他人时,投票率会增加,名字越大,也有助于激励公众投票。这让我决定我想要“最高票选举”的投票结果。这些类型的选举往往是人们谈论最多的,也是大多数人投票的原因。出于这个原因,我选择了总统、州长、参议员和国会竞选的投票结果。还有,我只回到了 2012 年。这让我把注意力集中在五年的时间跨度上,包括八场不同的比赛。我的想法是,这些数据足以得到准确的结果,但不能追溯到仅仅了解当前的政治气候。此外,为了简单起见,我只统计了每场竞选中民主党和共和党得票最多的人的票数。

在设置了我的数据参数并在科罗拉多州州务卿的网站上找到数据后,在训练一个模型之前,我必须做一些清理和加入工作。获取信息的最佳方式是从网站上复制下来,粘贴到 excel 电子表格中。(我知道懒惰,但这比使用可下载的杂乱无章的 excel 电子表格或废弃更乱的网站要容易得多。有时候你得做最容易的事。)当我得到可用格式的数据时,是时候为一些比赛做一些连接了。这对于所有的国会竞选都是必要的,因为有些国会选区会将县分开。例如,博尔德县是国会第二选区和第四选区的一部分。在这种情况下,我将博尔德县第 2 区和第 4 区的民主党人的选票相加,得到博尔德县民主党人的总票数。我对共和党的选票和其他几个处理分裂选区的县也采取了同样的做法。为了使数据正常化,我计算了每个政党总票数的百分比。这将使我能够更好地比较不同大小的县,无论是大县还是小县,都不会影响或扭曲我的模型。

我的下一步是建立一个模型。对于这种类型的问题,我知道我需要一个无监督的学习模型,因为我没有目标变量来训练模型。对于那些不熟悉无监督学习的人,我能找到的最好的单一定义来自 Techopedia。

https://www.techopedia.com/definition/30390/unsupervised-learning

旁注,但无监督学习已经慢慢成为我最喜欢的方法来分析数据,找到我看不到或想不到要寻找的模式。我认为它难以置信地未被充分利用,并且可以为人们试图解决的许多问题提供价值,但是,这可能是另一个博客的话题。无论如何,我强烈建议人们去调查一下。

我需要用来解决这个问题的模型类型叫做聚类模型。我想看看哪些县的表现彼此相似,并对它们进行分组标记。我知道两种主要的聚类无监督学习模型,K-Means 和 DBSCAN(基于密度的含噪声应用空间聚类)。虽然这两个模型都是无监督聚类模型,但它们之间有一个很大的区别。K-Means 让您选择模型将找到多少个分类,而 DBSCAN 将选择模型将自己给出多少个分类。虽然这两个模型都适用于这个数据集,但我的问题陈述要求 3 个不同的群体,共和党、民主党或摇摆派。因此,我使用 K-Means 纯粹是因为我能够设置我的模型将搜索的聚类数。

在运行 K-Means 模型时,它会根据所分配到的分类为每个数据点分配一个数字。我选择 K=3,这是我想要的 3 个集群,这些数字是 0、1 和 2。根据我的问题背景,为了找出这些数字的含义,我用配对图绘制了我的数据点,并将图形的色调设置为模型给该点的标签。在对图表的标签进行了一些分析和放大之后,我确定了每个标签的含义,并将它们重新标记为 DEM、REP 或 Swing,以便于理解。

为了仔细检查我的模型并查看我的结果,我将所有的数据转移到 Tableau,并在那里绘制每场比赛。当我仔细查看我的结果时,我开始注意到我的摇摆或“中间”分类并没有徘徊在投票范围的中心。

这些县中的大多数总是投票给共和党。虽然这一分类是科罗拉多州中三分之一的县,但它不包括在投票百分比方面仅徘徊在中心标记附近的县(每个政党的投票百分比相等)。这让我回到我的数据,并尝试一个不同的模型。我接下来尝试的型号是 DBSCAN。结果不如我已经试过的 K-Means 模型那样好。大多数县将导致“-1”分类。这意味着数据点噪音太大,无法对模型进行分类。即使在测试不同的最小样本和不同的 EPS 值后,(EPS 是两个点的最大距离,可以被认为是相同的分类),大多数县仍然被归类为“-1”。由于大多数点没有被分类,我知道 DBSCAN 模型不会满足我的需要。

我的下一步是回到 K-Means 模型,在模型中尝试不同的 K。我试过的不同 K 是 4,5,6。粗略地看了一下每个模型的结果,我知道我更加接近我所寻找的了。我将这些结果加载到 Tableau 中,并能够仔细查看每个模型以查看分类。我知道超过 3 个分类,我需要更多的标签名称,而不仅仅是民主党,共和党和摇摆。我将在民主党和共和党前面添加“精简”、“安全”和“稳固”等词,以便在对这些新标签进行分类时给我一些灵活性。

K-表示其中 K=4 包括标签;精简的民主党,精简的共和党,坚定的民主党,坚定的共和党。

虽然我认为 K=4 的 K-Means 模型在对县进行分类方面比 K=3 模型做得好得多,但它不能识别我正在寻找的“摇摆”县。

K-表示其中 K=5 包括标签;Leam 民主党,Lean 共和党,Safely 共和党,Solid 民主党和 Solid 共和党。

K=4 和 K=5 的主要区别在于,新的分类(我称之为安全共和党)是 K=4 的坚定共和党的一个子部分。这个模型没有提供太多新的信息,也没有识别出我要寻找的“摇摆”县。

K-表示其中 K=6 包括标签;摇摆不定,精益民主党,精益共和党,安全共和党,坚实的民主党和坚实的共和党。

就是这个。我能够确定四个郡正好位于投票范围的中间。虽然共和党人确实倾向于赢得这些县,但通常情况下,这场比赛在几个百分点之内,民主党人在这些县中获胜,这足以赢得“摇摆”的分类。这些县是 K=4 和 K=5 模型中精益共和党分类的一个子部分。下面是科罗拉多州的全貌以及每个县的分类。

现在戴上政治迷的帽子,为感兴趣的人谈谈我发现的一些有趣的事情。

在进行这个项目的过程中,有几场比赛吸引了我的注意力,我发现它们很有趣。引起我注意的第一批比赛都是众议院的比赛。首先引起我注意的是这些比赛是所有图形中线性度最低的。此外,众议院的比赛也是最混乱的分类。这是因为众议院选举不是全州范围的选举,每个地区都有自己的竞选人。这使得每个人都有很高的机会在选举中表现异常,导致上面图中提到的差异。一个很好的例子是 2016 年的选举,如下图所示。

另一个有趣的点是,每年的高姿态比赛比当年的其他选举更加线性。总统竞选往往是最引人注目的竞选,也往往有最高的投票率。当用图表表示时,这些往往比州长、参议院或众议院的竞选更加线性。以下是 2012 年总统竞选和 2014 年州长竞选。

我想说的最后一点是关于 2014 年的州长竞选,如上图所示。这是两个级别之间交叉最少的比赛,实际上根本没有交叉。我不知道这是不是侥幸,因为我的数据中只有一次州长竞选。如果这不是偶然的,其他州长竞选也是如此,那么可以肯定地说,了解科罗拉多州的最好方式是通过它的州长选举。

要查看其余的图表,请访问我的 Tableau 公开简介:https://public.tableau.com/profile/cbjohnson30#!/
要查看用于此的代码,请访问我的 GitHub:https://github.com/CBJohnson30

危机报告分类

原文:https://towardsdatascience.com/classifying-crisis-reports-17464661221d?source=collection_archive---------6-----------------------

这篇文章描述了我对日益增长的不稳定性的解决方案:由英国科技部、军情五处和军情六处组织的危机报告分类挑战。该解决方案在 579 个竞争对手中获得第三名。 链接到最终排行榜

任务描述

文本分类是给一段文本分配一个类别或范畴的任务。它是自然语言处理领域的一个分支,在情感分析、垃圾邮件检测和标签等方面都有应用。在这个挑战中,目标是用危机标签对《卫报》的文章进行分类。标签的几个例子是“澳大利亚安全和反恐”,“集束炸弹”,“埃博拉”,“法国火车袭击”,“美国枪支控制”。

挑战提供了一个训练集和一个测试集。训练集包括从 1999 年到 2014 年的所有新闻文章及其标签。大约有 160 万篇文章。测试集由 2015 年和 2016 年的文章样本组成。主题词典提供了所有的危机标签。主题词典中共有 160 个标签。标签可以分为两种类型:

  • 围绕特定事件的话题。例如“里约 20 地球峰会”、“突尼斯袭击 2015”。与这些主题相关的文章通常只在某一段时间内(一个月或一年)出现
  • 围绕概念的话题。例如“伦理”、“印度”、“德国”。与这些主题相关的文章在大多数年份都有。但是,内容每年都不一样。

任务的评估指标是微观平均 F1 分数。这是通过对测试示例的每个单独决策的真阳性、假阳性和假阴性求和来获得的,以产生其中每个测试示例(文档)被同等加权的全局平均值。

F1 得分= 2×TP / (2×TP + FP + FN)

数据集探索和基线

大多数文章的标签不在主题词典中。训练集中大约有 235,000 篇文章具有出现在主题词典中的标签。我们使用这个子集进行开发和验证。

Fig 1: Number of articles per topic

一些主题如“英国犯罪”、“伊拉克”、“宗教”和“移民”有大量的文章(超过 15000)。大多数题目至少有 100 个例子。有趣的部分是 12 个主题没有任何文章。分别是'布鲁塞尔袭击'、'巴士底日卡车袭击'、'寨卡病毒'、'奥兰多恐怖袭击'、'柏林圣诞市场袭击'、'查理周刊袭击'、'突尼斯袭击 2015 '、'圣贝纳迪诺枪击案'、'巴黎袭击'、'和平与和解'、'土耳其政变企图'、'法国火车袭击'、'激进主义'、'慕尼黑枪击案'。这些主题大多是发生在 2015 年和 2016 年的事件(除了“和平与和解”和“激进主义”),因此没有关于它们的培训数据。

这个挑战是一个多标签分类的例子,其中多个标签可以分配给每件商品。我把标签编码成一个 160 维的热向量。我尝试的两个基线是单词包和平均单词向量。在前一种情况下,我将文章转换成一袋单字和双字,并使用它们的频率作为特征。在后者中,我首先使用训练集来训练 300 维的单词嵌入。然后我把每篇文章转换成一个 300 dim 的均值嵌入。前一个特征集是稀疏向量,而后一个是密集向量。我在这两个特征集上应用的两个机器学习算法是前馈神经网络和梯度推进决策树。F1 的最佳基线得分为 0.38。

体系结构

我在这次挑战中使用了两种方法:

  • 在训练集中有文章的主题的监督学习。这让我在公开数据上的 F1 分数达到了 0.64 左右。
  • 用于在训练集中没有文章的主题的规则引擎,其在公开数据上将上述分数提高到 0.6626 F1 分数。

对于监督学习部分,这里是我实验的算法。所有模型都是用 Keras 实现的:

  • 卷积神经网络:CNN 是用于文本分类的常用模型之一。Kim Yoon 关于用于句子分类的卷积神经网络的论文是一个很好的起点。我通过修改过滤器的数量、池大小和过滤器大小来试验不同的架构。我还用预先训练的手套向量、谷歌新闻向量和输入数据上训练的嵌入进行了实验。对我有用的架构是使用在输入上训练的嵌入。随后是 5 个卷积层,滤波器尺寸为 3、5、7、9 和 11。在这之后,有一个合并层,然后依次是 3 个卷积,池和辍学层。最后一层是尺寸为 160 的 softmax 层。
    模型的最后一部分是确定每个主题的阈值。最初,我尝试将所有主题的阈值设为 0.5。然而,为每个主题选择不同的阈值有相当大的提升。阈值是在验证集上学习的。最好的成绩是 F1 得分 0.615。

Fig 2: CNN architecture diagram Source: http://www.aclweb.org/anthology/D14-1181

  • 具有 softmax 层的双向 LSTM:这是另一种用于文本分类的通用架构。基本层是单词嵌入,接着是双向 LSTM 层和 softmax 层。在对这个模型做了一点试验后,我意识到它有两个缺点。首先,与 CNN 模型相比,它在每个时期花费了大约 3 倍的时间(所有训练都是在 AWS p2.xlarge 中完成的,其中有 Tesla k80 GPU)。二是性能比 CNN 机型差很多。最好的 F1 成绩是 0.52。因此,我决定不再继续这种模式。

Fig 3: LSTM network for classification Source: http://deeplearning.net/tutorial/lstm.html

  • 关注 GRU 网络:我试验的下一个模型是 GRU 网络上的关注层。gru 在某种意义上类似于 LSTMs,它们使用门控机制来学习长期依赖性。然而,它们具有较少的门(它们没有输出门),因此具有较少的参数。他们的训练速度相当快,F1 分数为 0.621。
  • 分层注意模型:该体系结构首先由杨等人在论文【用于文档分类的分层注意网络】中提出。艾尔。这个模型的独特之处在于,它有两个层次的注意机制,既适用于单词,也适用于句子。这有助于它有区别地识别更多和更少的重要内容。我在这里使用了 Richard Liao 实现的模型。这个模型的优点是,当我们查看给定文本的注意力权重时,我们可以了解哪些单词和句子对标签有贡献。这对于调试非常有用。这也被证明是最佳的单一网络模型,F1 值为 0.626。

  • 以上模型的叠加:在检查了这些模型的输出后,我意识到,对于很多题目来说,输出并不是高度相关的。这为堆叠这些模型提供了机会。我使用开发集的交叉验证,从每个模型中创建了一个 160 维的特征向量。这导致了一个 640 维的特征向量,我通过一个前馈网络。该网络有两个隐层,分别为 480 和 320 个单元。这给了我最好的 F1 成绩 0.6415。

到目前为止,我对没有训练数据的主题的预测为零。由于许多话题都是欧洲的重大恐怖袭击,我预计《卫报》会有大量报道。我试验的最初模型是检查文章中是否存在主题字符串。例如,对于主题“巴黎袭击”,将所有具有字符串“巴黎袭击”的文章标记为真。但是这个模型导致了召回率的损失,并且没有特别高的精度(与《查理周刊》袭击事件相关的文章也有‘巴黎袭击’这个短语)。该模型的下一次迭代涉及使用主题字符串中所有标记的计数作为特征,并使用手动阈值进行区分。然而,选择最佳阈值是困难的,我没有取得任何重大进展。

到目前为止,我还没有在任何文章中使用过的一个特性是文章的日期。这在这里很有用,因为在袭击发生之前不会有关于“巴黎袭击”的文章。另一个认识是,在攻击后的几天内,它的主题标签和攻击位置的主题标签有很高的相关性。例如,在巴黎袭击之后,标签“法国”和“巴黎”与“巴黎袭击”有很强的相关性。我使用这种相关性来创建一个种子文章集,这些文章极有可能属于新标签。考虑作为种子集一部分的文章是在攻击当天到攻击后一周内发表的文章(对于覆盖范围更大的攻击,这可能会增加)。然后,我建立了一个命名实体袋监督学习模型,以在结束后对文章进行分类(我最初尝试使用单词袋,但它给出的结果比命名实体袋差)。对于模型的反面例子,我使用了该日期之前文章的随机样本。这在实践中效果很好,我能够在公共数据集上获得 0.6626 的分数。

未来的工作

我很想在未来探索一些想法,但是没有足够的带宽:

  • 为每个主题标签建立一个模型,而不是一个统一的模型。
  • 将所有的 CNN、RNN 和注意力模型合并成一个大的神经网络,而不是堆叠。
  • 探索没有训练数据的主题的替代模型。
  • 更好地利用日期特性进行分类。直觉上,一篇 1999 年的文章和一篇 2014 年的文章权重相同是没有意义的。

不幸的是,作为竞赛协议的一部分,我们不得共享数据和代码。但是,希望这篇文章对所有文本分类从业者有用。

利用机器学习对市场库存进行大规模分类

原文:https://towardsdatascience.com/classifying-marketplace-inventory-at-scale-with-machine-learning-99e69eac585e?source=collection_archive---------7-----------------------

克里斯 联合创始人&CTO attop hatter。这最初是向我们的工程团队内部发布的,但我们决定向其他对学习如何将机器学习应用于大规模分类问题感兴趣的人开放。

为什么这很重要?

分类法在像 Tophatter 这样的市场中扮演着几个重要的角色。

对于购物者:它支持浏览&深入体验,有助于信息检索。直觉上,我们期望一条通向客户关心的产品集的高效路线胜过一条低效路线。

对于 Tophatter: 是商业智能的一种形式。更具体地说,这是一种对产品进行分组的有效方法,以便识别关键的异常值(表现优异或表现不佳),并发现存在供需不平衡的领域。这些见解可用于对我们优先考虑的产品分销做出有影响力的改变。在一个典型的日子里,Tophatter 购物者进行近 100,000 次购买,每次购买都代表我们的库存调度算法的一个实例,该算法从数百万个产品中选择一个特定的产品进行优先排序。为了做出明智的选择,这种调度算法需要很好地理解产品是什么,以及它的性能如何。分类法是元数据的关键部分,它使调度算法能够做出明智的决策。

有哪些挑战?

对于一个有用的分类法,它应该是(1)正确地应用于所有产品,(2)易于使用,以及(3)当新的产品类别弹出时易于改变(有人坐立不安吗?).这具有挑战性,原因如下:

  • (1)正确性:市场通常依靠销售者对产品进行分类。这总是会导致一些不正确的分类。
  • (2)易用性:分类法可能经常很大而且不明确——一个产品可能看起来适合多个分支。此外,没有“标准”分类法。亚马逊、易贝和谷歌都有自己的,具体程度差别很大。这种复杂性在向市场添加库存时会引起摩擦,因为销售者必须将他们的内部分类映射到特定于他们希望销售的市场的分类。这既烦人又容易出错。
  • (3)易更改性:向分类中添加一个新节点很容易,但是我们将如何对应该映射到这个新节点的现有产品进行重新分类呢?删除节点也有同样的问题。

我们如何解决这个问题?

一种选择是定义一组标签来表示我们库存中不同类型的产品,手动将这些标签应用于我们产品的子集,并采用机器学习技术来训练分类器,以准确预测给定产品的适当标签。

让我们来看看这个解决方案的利弊:

赞成的意见

  • 如果我们的模型是好的,我们解决了“正确性”问题。不再有人为失误。
  • 从卖家的角度来看,它非常容易使用——系统会自动对每个产品进行分类,因此卖家什么都不用做!
  • 在大多数标签系统中,添加或删除标签很简单,如果我们的标签集发生变化,我们可以每天自动对产品进行重新分类。

骗局

  • 标签没有层次结构,而层次结构对于浏览/下钻很有用。
  • 该系统需要大量的人工工作来为产品手工贴标签,以便生成训练数据。此外,还有维护成本。我们需要一个反馈循环来增加我们的训练数据,这样我们的模型才能不断改进。
  • 这个系统比卖家给自己的产品分类的系统更复杂。复杂得多。它需要一个数据管道来推动未分类的产品通过分类器并存储结果。

让我们假设这是一个合理的解决方案,并探索一个简单的实现。

标签工具(Ruby,Rails,JS)

后端

有许多优秀的通用对象标记实现可用于各种 web 框架。对于 Rails,acts-as-tagable-on是一个很好的选择。

假设您有一个Product模型,您可以通过以下方式启用标记:

给产品添加标签就像product.tag_list.add('foo')一样简单。

前端

为创建、添加和删除标签构建一个良好的前端是至关重要的,因为管理标签的过程是生成我们需要的数据以训练我们的模型并随着时间的推移对其进行改进的过程。

为此,我选择使用一个与 Bootstrap 兼容的 jQuery 插件, bootstrap-tagsinput ,它允许我们快速地异步添加和删除标签。它还支持与 typeahead.js 的集成,因此我们可以执行标记自动完成,以加快标记速度并减少错误。

在我们的后端之上构建了一个前端标记工具之后,我们得到了以下结果:

机器学习(Python,Scikit-Learn)

给定一组用标签正确标记的 k 个产品示例,训练分类器来预测标签相对容易。我们将使用 scikit-learn 来完成这项工作。

培训用数据

为了让我们开始,我使用上面的标签工具来标记我们几百个最畅销的产品。决定一个框架来指导标记过程是很重要的,并且应该由您的分类法用例来指导。你需要知道需要什么样的特异性。我的经验是生成包含 3 个或更少单词的最具体的标签。比如,我没有选择“戒指”,而是选择了“[材质]戒指”(即“纯银戒指”)。我没有选择“平板”,而是选择了“安卓平板”。

这个手动标记步骤完成后,我将全套标记产品导出到一个 CSV 文件中。这是我们的训练数据。

我们可以很容易地用pandas加载它:

让我们快速浏览一下数据:

这些标签似乎对这些产品名称有意义。以下是标签在我们数据集中的分布情况:

有些标签没有很多例子。当预测在训练数据中不经常出现的标签时,我们的模型可能不会做得很好。这是我们可以在数据生成反馈回路中解决的问题。稍后会详细介绍。

特征探索

可以说,解决这种类型的机器学习问题时,最重要的步骤是探索训练数据,并搜索可能产生良好预测的特征。这可能需要一段时间。

为了简单起见,我们假设一般来说,产品的标题是标签预测的一个重要特征。实际上,有几个其他产品属性会非常有用(例如,描述、材料、价格、卖家等),我们应该尝试使用所有这些特性。

特征转换

为了将标题转换成我们可以用来使我们的模型适合我们的训练数据的向量,我们将使用CountVectorizer:

我们的词汇表中有大约 11K 个单词。现在让我们将标题转换成向量:

让我们检查一个特征向量:

注意,它只在内存中存储向量的非零部分。这个向量表明,我们的文本包含一个出现在索引241的单词,一个出现在索引1508的单词,等等。

培养

让我们使用多项式朴素贝叶斯分类器来拟合我们的训练数据:

让我们在不在我们的训练集中的产品上测试分类器:

该分类器似乎工作…至少对于坐立不安纺纱。我想知道它和热狗会有什么关系?😃

我们来看看分类器有多准确。我们将使用 70%的数据进行训练,然后使用剩余的 30%来测量准确性。

我们得到大约 96%的初始精确度。

根据最佳实践,我们应该始终有一个比较基准。为此,让我们将我们的结果与随机算法进行比较:

毫不奇怪,随机猜测很糟糕(即使分层)。

网格搜索优化

现在,让我们创建一个适当的管道,并使用网格搜索来调整CountVectorizer参数。你可能已经注意到我们没有使用停用词。相反,我们将调整我们的最小和最大文档频率参数,这将自动过滤掉出现频率过高(如停用词)或过低的单词。

你还会注意到我们引入了二元语法的概念——这为相邻词对的特征向量增加了列,可以改进我们的算法。当我们考虑相邻单词之间的关系时,我们将使用网格搜索来看看我们的算法是否更好。

这是我们的网格搜索尝试:

让我们以 70% / 30%的比例尝试这些参数:

不错——我们改进了一点。

其他分类器

现在让我们尝试一些不同的分类器,看看它们的表现如何:

看来LogisticRegression大有可为。我们暂时坚持这一点。

推算概率

当我们对产品的完整库存运行模型时,我们会遇到现有标签都不合适的情况。随着时间的推移,我们将希望扩展标签集,以包括几乎所有产品的适当标签,但我们还没有做到这一点。因此,我们想要抛弃明显不好的预测。

我们可以询问分类器,对于我们集合中的任何标签,它认为正确的概率是多少。这里有一个例子:

注意,我输入了一个标题,专门引用了两种不同类型的产品。分类器发现 2 个标签高于 0.1 的概率阈值。

反馈回路

我们需要弄清楚什么是合理的门槛。现在,我们将只选择概率最高的标签,并构建一个验证工具来显示概率,并允许人们接受或拒绝预测(确保跳过有把握的预测,以防止不必要的工作)。在这个过程中,我们可以添加新的标签来构建我们的标签集,并通过纠正错误的预测来改善我们的训练数据。这是使我们的模型表现良好的关键反馈循环。

这是我们验证工具的预览,它允许我们快速接受、拒绝或修正预测:

如果您想要快速改进模型,使该工具高效且易于使用是至关重要的。

投入生产

最后一步是弄清楚如何将未标记的产品输入到这个模型中,并通过验证工具持久化消费预测。如果您的产品数据库很大(就像我们的一样),您可能会希望使用 build 来处理大量数据,比如 Spark。你甚至可以相对容易地将这个 scikit 模型移植到 Spark ML 上。也许这是未来的博客文章🙂).

如果你的产品数据库没有数百万行,你可以在一个简单的 Python 脚本中做任何事情——如果你喜欢使用 ORM 进行数据库读/写,我们是 SQLAlchemy 的忠实粉丝。

关于 Tophatter

Tophatter Inc 由 Ashvin Kumar(首席执行官)和 Chris Estreich(首席技术官)创建,于 2012 年 1 月推出。迄今为止,该公司已经从 CRV 的古德沃特资本公司和奥古斯特资本公司筹集了 3500 万美元。该公司在全球拥有 75 名员工,并正在硅谷和上海的办公室积极招聘员工。更多关于 Tophatter 的信息,请访问:【http://www.tophatter.com/about】T4。

用卷积神经网络对皮肤损伤进行分类

原文:https://towardsdatascience.com/classifying-skin-lesions-with-convolutional-neural-networks-fc1302c60d54?source=collection_archive---------10-----------------------

医学深度学习指南和介绍。

Photo by Rawpixel on Unsplash.

想象一下。

你醒来后发现皮肤上有一个可怕的疤痕,于是你去医生办公室检查。他们说没事,所以你可以回家,几个月内不要担心,但随后你会从那个地方开始一跳一跳地疼——现在看起来很丑,很危险。由于你的医生的误诊,它已经发展成了恶性肿瘤。误诊的普遍程度很吓人。一项研究表明,超过 1/20 的美国成年人在过去被误诊,其中一半以上是有害的。许多皮肤损伤可能是无害的,但其他的可能会威胁生命。立即发现这些肿瘤非常重要,因为这是治疗它们最容易的时候。

最近,我们看到人工智能已经成为我们日常生活中不可或缺的一部分。我们发现它被用在我们的文本推荐、广告个性化、虚拟助手等等。随着人工智能在这些领域取得如此巨大的进步,它有无限的潜力通过深度学习对医疗保健产生影响。考虑到这一点,我着手制定一个端到端的解决方案,使用深度学习对皮肤病变进行分类。

我们可以通过使用卷积神经网络来实现准确可靠的医学图像分析技术,卷积神经网络是一种用于分析图像的深度神经网络。在我们进入 CNN 之前,让我们稍微回溯一下,看看神经网络是如何工作的。神经网络本质上是以类似于人脑工作方式的方式模拟的计算机程序。像我们的大脑一样,神经网络由一大堆神经元组成,这些神经元不能单独做很多事情,但当它们在网络中连接在一起时,可以完成一些非常难以置信的任务。

神经元是做什么的?

A neuron takes in some inputs, operates on it, and gives an output. Source.

神经元的工作很简单,它接受几个输入;让我们称它们为 X1、X2 和 X3,如图所示,然后输出一个结果。每个输入都有一个与之相关的权重系数。这些权重影响神经元的输出,并且它们被不断地改变以获得改进的输出(这更准确)。

把神经网络想象成一群白蚁。一只白蚁本身是微不足道的,并不能真正做任何事情,但当你有数百万只白蚁在一起时,它们可以通过学习并最终进化来完成令人难以置信的任务。

A neural network with 2 hidden layers. Source.

神经网络通常被用作监督学习的一种方法,这基本上意味着它们学习如何通过识别数据中的模式来进行预测。我们给它的数据越多,它就越有可能做出更好的预测。但是神经网络如何在我们处理的一些非常复杂的数据中找到模式呢?

它的学习方式与人类相似。首先,它浏览数据并做出超级随机的预测,这些预测根本不太准确,然后它使用一种叫做 反向传播 的技术,从它犯下的错误中学习,然后试图修复它们。它做得越多,预测就越准确。它们甚至经常能够识别人类永远看不到的模式和相互关系!

那么我们如何将这一点应用到皮肤病变的图片上呢?我们使用一种特殊类型的神经网络,称为卷积神经网络。

卷积神经网络

卷积神经网络不同于普通的神经网络,因为它们包含一种特殊类型的层,称为卷积层,它包含一个过滤器,能够理解图像中某些类型的模式。

A graphical demonstration of a filter. Source.

你可以把滤镜想象成手电筒。你将它照射在一张照片的不同部分,寻找一些特征,并在特征图上写下它是否存在(或在多大程度上存在)。通常,位于最开始的图层会被用于一些非常简单的事情,比如边缘检测。随后,图层可以检测更复杂的特征,如眼睛、鼻子和手指。所有这些特征图被放入网络末端的一长串特征中,用于最终对图像进行分类。

除了卷积层,CNN 还包含几个其他层,即池和分类层。

Standard architecture of a CNN

汇集层对于确保 CNN 的训练不会花费太多时间是非常重要的。他们通过缩小图像的尺寸来做到这一点。它的工作方式与卷积层非常相似,在卷积层中,过滤器会通过图像,但现在,过滤器会通过数据,提取最重要的信息,并将其放入较小的矩阵中。这使得您的计算机更容易使用。

A Pooling Layer reducing a feature map by taking the largest value. Source.

所有这些层在最后连接在一起,成为一个产生最终分类的soft max函数(分类层)。

构建分类器

让我们开始构建我用来对皮肤损伤进行分类的模型。我使用 native Keras 构建了 CNN,如果您没有机器学习的经验,请不要担心,通过本指南,您应该能够很好地理解它是如何工作的!我使用了转移学习来创建这个模型,这意味着我使用了一个叫做 MobileNet 的预训练网络,它是用超过 1400 万张图像的数据集 ImageNet 训练的,并且给它添加了一些层,所以它可以对皮肤病变进行分类。这个想法是,我们采用一个用大量数据训练的模型,并将其用于我们没有那么多数据的新任务。通常,这有助于提高最终模型的准确性,并减少训练时间!****

我们使用 MobileNet 主要是因为它的速度。当我开始做这个项目时,我遇到的一个问题是像 Resnet50 这样的模型在训练速度和实时预测方面的性能非常差。

是什么让 MobileNet 更快?

之前,我解释了卷积层如何通过图像上的过滤器。当图像有不止一个颜色通道时(RGB 有 3 个通道),这很难计算。这就是深度方向可分离卷积发挥作用的地方。这就是 MobileNet 的特别之处,也是它比其他网络快得多的原因。

深度方向卷积将卷积过程分为两步。它将滤镜传递给图像中的每个单独的层,使滤镜的深度为 1。如果有三层,红色,绿色和蓝色,它将通过不同的过滤器通过每一层。之后,它通过一个称为逐点卷积的过程,对所有层应用 1x1 卷积来合并层。深度方向可分离卷积的总计算量比标准卷积低8-9 倍,这使得它能够在移动设备上运行!我简单地看了一下,如果你想更好地理解深度方向的卷积,看看这篇论文。

10000 哈姆

HAM10000 数据集中,我们将获得训练模型所需的图像。这是 7 种不同类型的皮肤损伤的大约 10,000 个标记图像的集合。

这些是在数据集中发现的病变类型:

  • 光化性角化病
  • 基底细胞癌
  • 良性角化病
  • 皮肤纤维瘤
  • 恶性黑色素瘤
  • 黑素细胞痣
  • 血管病变

你可以在这里找到更多关于它的信息。

现在我们来看一下代码。

我们从导入我们需要的所有库开始。一大堆 Keras 进口需要构建我们 CNN 的不同部分。我们还导入了 NumpyitertoolsScikit-Learn 。随着我们的发展,我们将探索这些功能的用途!

现在,让我们声明一些变量,这些变量在以后会对我们有用。我们设置了一些变量,这些变量包含了训练数据和评估数据的位置,这样我们更容易处理。样本的数量就是我们使用的数据集中有多少图像。批量大小是指在网络权重更新之前您处理的图像数量。我们输入到神经网络的图像的大小是 224x224,稍后我会详细介绍这一点。最后,我们需要声明网络需要向前/向后传递多少次,直到它分析了每一张图像,我们可以通过将数据中的图像总数除以批量大小,然后取整来完成。

我们需要做的另一个真正重要的步骤是数据预处理,因为我们使用的是 MobileNet 的迁移学习。我们需要重新训练这个网络中的几个层,以便它能处理皮肤损伤图像。注意,MobileNet 接收 224x224 尺寸的输入图像,我们需要预处理数据以符合这个标准。

在这里,我们对网络进行了一些重要的更改。MobileNet 模型通过添加一个丢弃层和一个密集输出层进行了修改。我们使用 dropout 来防止过度拟合数据。当网络变得非常非常擅长对你给它的数据进行分类时,这种情况就会发生,但除此之外就没什么了。在添加这一层之后,我们添加最后的致密层,它具有附加的激活功能。这需要它收集所有的特征地图,然后给我们预测。在我们对网络结构做了这些改变后,我们想冻结一些层来加快训练速度。在这种情况下,我们冻结了除最后 23 层以外的所有内容,因此我们的图像数据仅在 MobileNet 的最后 23 层上进行训练。

既然我们已经微调了我们的模型,我们需要创建几个度量来确定我们的模型有多精确。然后我们为我们的模型编辑所有的信息,这样它就可以被训练了。对于训练,我们使用 Adam 优化器分类交叉熵损失函数。本质上,损失函数测量模型预测的错误程度,优化器改变权重,试图使模型更加准确。这两个函数在机器学习中非常重要,你可以在上面的链接中了解更多。

现在,最后,我们训练模型,将我们上面创建的所有组件拼凑在一起。程序将此保存到文件中,如果我们想要实现这个模型,这是至关重要的。

该模型获得了大约 85%的准确率,用 HAM10000 数据集进行了测试,但是,我预测在现实世界中它不会那么可靠。当然,这个问题很容易解决,只要有一个更大的图像集合来训练它,并在更广泛的环境中进行训练。

为了在网络上运行这个,我将 Keras 模型转换为 TensorflowJS 模型,并且能够通过遵循这个指南很容易地在网络上实现它。

你可以在我的网站上看到这个模型的实现这里,如果你想仔细看看这个模型,一定要看看我的 GitHub

Web implementation of the model.

这里是模型的 web 实现,我已经提供了项目的描述以及一些关于皮肤损伤类型的信息,来源于这里

如果您没有任何图片来测试它,我还为每个类提供了一些示例图片。该模型在非皮肤背景的病变图片上表现不太好,因为它没有经过这样的图像训练。正如我上面所说的,从 HAM10000 数据集计算的准确性约为 85%,虽然这对于医疗用途来说肯定是不够的,但专业支持和更大的数据集将产生一个可用于临床使用和家庭诊断的模型。

像这样的技术的影响是巨大的。通过使用人工智能技术,我们有可能消除临床上的误诊,就像这样。我们拥有的数据和支持越多,它就越能成长并变得更加准确。只有 10,000 张图像,我们达到了大约 85%的准确率,但是想象一下,如果我们有数百万张图像,会有多好。这些模型将拥有医生的技能,医生已经看过并从数百万张图像中学习。你能想象吗?

人工智能已经在扰乱医疗保健领域。随着我们继续将它纳入主流医学,治疗和诊断的质量将会大大提高。我们已经看到人工智能取代了许多制造和文书工作,但许多人不认为人工智能对医疗保健这样重要的领域有影响。通过使用人工智能进行诊断,我们可以消除可预防的疾病,并创造一个我们不再需要担心获得准确诊断的未来。

如果你喜欢我的文章或者学到了新东西,请务必:

  • LinkedIn 上与我联系。
  • 给我发一些反馈和评论(aryanmisra@outlook.com)。
  • 查看 web 实现

一个数据科学家的干净代码(?)

原文:https://towardsdatascience.com/clean-code-for-a-data-scientist-f4b760374b74?source=collection_archive---------10-----------------------

Keep it clean!

“我是一名数据科学家..我不需要写干净的代码,因为我的大部分代码都是一次性的”。“干净的代码和敏捷有利于软件开发..这在我的作品中毫无意义”。我听到上面这些话的次数&甚至不愿意尝试一些关于干净代码的建议,让我困惑。

让我告诉你..你也不需要为软件开发写干净的代码。你也不需要为软件开发实践敏捷。即使没有上述内容,你也可以制作一个完美的软件(维护/修改/扩展会变得困难。但这不是本文的重点)。当你在团队中工作时,你需要遵循干净的代码实践!不管你是在开发一个软件还是一个算法,或者必须尝试多种算法。

干净代码的基本思想是你的团队成员应该能够理解你写的东西。这在数据科学中尤其重要。作为一名科学家,你的实验必须是可重复的。必须可以验证。这意味着你团队中的其他人应该能够理解&重现你的结果。

我们存在于一个团队中。一个人做数据科学家是不可能的。在工业界,大多数时候你会从事应用科学的工作。这意味着你必须理解其他人的问题&他们(团队、业务人员)也需要理解你的解决方案。

作为一名数据科学家,您将与团队的以下成员(不限于)频繁互动:

其他数据科学家/数据分析师(此处可互换使用)—在算法、模型、结果解释、特征工程等方面与其他数据科学家协作。

数据工程师——你不想最终自己处理所有的数据。数据工程师可以优化查询,在最短的时间内获得综合结果。他们需要了解你需要什么数据。

业务分析师(BA)/领域专家—从业务角度来看,您的结果意味着什么?BAs 需要了解您的输入变量意味着什么&您的结果将对业务产生什么影响。从本质上理解这个领域。

既然我们已经确定了协作对于数据科学家的重要性,那么让我们来谈谈通过代码使协作变得有效的方法。这些是唾手可得的果实:

1.有意义的名字——你的团队成员不应该问你变量是什么意思。使用能清楚表达意图的名称。名字长是可以的。解决这个问题的方法是使用更好的编辑器(这样你就不必每次都输入完整的变量名)&不要缩短变量名从而使它变得晦涩难懂。还有,请不要神奇的数字

2.避免心理映射——你知道你的代码中的哪些参数需要改变以获得想要的结果。其他人没有。如果你必须记住所有需要同时改变的变量,那么你就是在浪费团队的大量时间。有人(包括你)会忘记改变其中一个变量而运行代码。这意味着运行是一种浪费&代码需要重新运行。考虑到一些算法需要的时间,这应该是一个

3.难道T5 对同一个东西有多个名字。一旦你们团队决定了,就要坚持下去。

4.使用商业域名名称。保持你的创造力来设计特征、分析、创建模型。不要发明名字。

5.评论很快就过时了。代码总是说真话。因此,通常不鼓励评论。这同样适用于数据科学代码。但是,我会在这里破例—添加一些评论,表明您使用/不使用某些型号/功能的意图。可以评论:“这将需要 5 个小时”或“使用径向基核 SVM 以加快收敛”

6.模块化你的代码。理解一个大斑点并不容易。不管它现在在你脑子里有多好。在以后的时间里,你会花时间去理解它。其他人需要时间来理解它。为什么?因为人们必须仔细阅读每一行代码才能理解它在做什么。当你创建的函数正如它的名字所说的那样,你不需要遍历它里面的每一行。读者仍然会理解正在做什么。

7.不要重复自己!不要复制和粘贴那些代码行,因为你在别的地方也需要完全相同的东西。在一个函数中提取出来&重用那个函数。这确保了一致性。

8.单元测试 —是的,它们与数据科学代码非常相关。数据科学代码还是代码!测试您的函数,这些函数根据将要采取的业务决策产生数字,这变得越来越重要。为什么你甚至没有想到测试你的函数会有这么多的反响。你所有的功能都应该被测试,以确保它们做你期望它们做的事情。写一个识别平稳信号的函数?用一个稳定的信号来测试它,确保你的函数返回这样的信号。

9.格式 —决定你们团队想要遵循的格式。这包括在缩进、目录结构、文件命名约定、输出结果格式等方面使用空格还是制表符。

我完全赞成以一种快速而肮脏的方式尝试各种事物/方法/模式。这对于理解一个人应该在哪个方向投入多少时间非常有效。但是,一旦你最终确定了你的方法,并将其融入到你的工作代码中,一定要清理干净。以上所有的概念都有助于人们作为一个团队工作。我发现它很有用,即使我独自工作。它帮助我在以后的某个时间点理解我的工作。它让我能够解释我的结果&让我能够快速地交叉询问令人惊讶(或震惊)的结果。

《干净的代码》一书很好地解释了上面提到的所有观点。所以,如果你是一名数据科学家&将在一个团队中工作,请阅读&实现干净的代码:)每个科学家都有自己的规则。但是在团队工作的时候,团队是有规则的。

使用无监督的机器学习清理您的数据

原文:https://towardsdatascience.com/clean-your-data-with-unsupervised-machine-learning-8491af733595?source=collection_archive---------5-----------------------

清理数据不一定是痛苦的!这篇文章是一个快速的例子,展示了如何使用无监督的机器学习来清理堆积如山的杂乱的文本数据,使用现实生活中的数据。

我们在对付什么?

在这个例子中,我们面对的是从 HMTL 和 PDF 文件中抓取的数千篇文本文章。返回文本的质量在很大程度上取决于抓取过程。从抽样检查的一些结果中,我们知道存在从坏链接、不可读的 pdf 到已经成功读入的项目的问题,但内容本身完全是垃圾。

与公司现代奴隶制相关的文章从这个数据库返回:https://www.modernslaveryregistry.org/

这些现在存在于 Pandas 数据框中,每一项都有“元数据”,如公司名称和出版年份,以及从回复中提取的文本:

This is the starting point — the text data is the last column in the data frame

快速题外话:错过没有

python Missingno 包超级有用。它可以用 4 行代码在数据框上安装和运行,如果数据框中有任何缺失信息,它会快速突出显示。它还能够对数据集中的行进行采样,因此可以轻松处理非常大的数据帧。

!conda install -c conda-forge missingno — y
import missingno as msno
%matplotlib inline
msno.matrix(combined.sample(250)) #combined is the df

在我们的数据框上运行这个程序,显示出除了一列之外,数据是完整的。由于我们不使用它进行分析,所以不需要做进一步的工作,但是如果在其他区域有缺口,我们必须考虑如何最好地处理这些缺口(例如删除这些行或尝试估算缺失值)。

The chart shows all but one column are complete — we can now focus on our text data

…回到清理文本数据

浏览数据框中的文本显然存在问题。例如,读取此项目中的 PDF 文件时出现问题:

CMR644311ABP 英国现代奴隶制声明 2017 年 9 月)ABP 英国现代奴隶制声明 2017 年 9 月 ABP 英国现代奴隶制声明 2017 年 9 月 AABP 英国现代奴隶制声明 2017 年 9 月 bABP…..

这个看起来更糟:

!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"#!)%!+!,(-&(#!。/&0#&-!!1!!2–34!5!5/6!!1!!7–8(&9%!!1!!7:;!<=>!.3–8(%&-($9!!!!!!!!!!!!!!学术界有限公司现代奴隶制合规状态。

这些显然是无法修复的——但是我们如何将它们从正确读取的文本文件中分离出来呢?

机器学习拯救世界

我们可能会花费大量时间试图从真实数据中分离出这些损坏的信息,但这正是机器学习的亮点。希望我们可以用它来发现数据中的模式,并自动将其聚类成干净和杂乱的数据,从而节省大量工作。使用 Python,只需三个步骤就能快速轻松地完成这项工作:

第一步。为算法创建特征:

以下代码将单词计数、字符计数和唯一单词数作为新列显示在我们的数据框中:

#The data frame is called 'combined'
def uniqueWords(X):
    X = X.split(' ')
    X = set(X)
    X = len(X)
    return Xcombined['charCount']   = combined['text'].str.len()
combined['wordCount']   = combined['text'].str.split(' ').str.len()
combined['uniqueWords'] = combined['text'].apply(uniqueWords)

第二步。将数据可视化:

使用 Spotify 真正优秀的图表库, Chartify,我们可以使用我们刚刚创建的新功能快速绘制数据图表:

ch = chartify.Chart(blank_labels=True)
ch.plot.scatter(
    data_frame=combined,
    x_column='wordCount',
    y_column='uniqueWords',
    size_column='charCount',
    alpha = 0.3)
ch.set_title("Text data quality")
ch.set_subtitle("Size is the character count")
ch.axes.set_yaxis_label('Unique words')
ch.axes.set_xaxis_label('Total words')
ch.show()

这个图表告诉我们大量关于数据集的信息。有明显的词、字、独字增多的趋势。这是意料之中的,但是在这下面还有一大串项目,在底部有一行项目,它们的字数很少,但是字符数很高:

第三步。创建集群:

通过使用机器学习对数据进行聚类,我们应该能够自动分割出我们在图表中看到的每个区域,并进一步研究这些区域。以下代码缩放数据,然后对其应用 K-Means 聚类:

from sklearn.cluster import KMeans
from sklearn.preprocessing import StandardScaler#The data frame is called 'combined'
X = combined[['charCount','wordCount','uniqueWords']]
scaler = StandardScaler()
X = scaler.fit_transform(X)
kmeans = KMeans(n_clusters=7, random_state=0).fit(X)
combined['Cluster'] = kmeans.labels_

再次运行我们的观想,我们得到以下结果:

# Overview
ch = chartify.Chart(blank_labels=True)
ch.plot.scatter(
    data_frame=combined,
    x_column='wordCount',
    y_column='uniqueWords',
    size_column='charCount',
    alpha = 0.3,
    color_column='Cluster')
ch.set_title("7 clusters help to split out issues")
ch.set_subtitle("Color represents each cluster, size is the character count")
ch.axes.set_yaxis_label('Unique words')
ch.axes.set_xaxis_label('Total words')
ch.show()

这在划分问题领域方面做得很好。看起来集群 1、4 和 5 需要一些进一步的调查。在此之前,让我们放大图表的左下方,以确保聚类仍在此处工作,因为在当前图中很难看到:

魔法;即使在点之间有重叠的地方,该算法也足够健壮,能够仅基于字符数来区分它们。

为什么我们决定选择 7 个集群?反复试验。7 是仍然以有效方式分割数据集的最小数字。

检查结果

这一切看起来很棒,但是我们真的实现了我们设定的目标吗?我们可以通过检查每个集群中的内容来检查这一点,特别是集群 1、4 和 5。

卡斯特 1:

#locate cluster 1 and return the text column as a list:
combined.loc[combined[‘Cluster’]==1].text.valuesreturns:
3M United Kingdom PLC: modern slavery statement. This statement has been published in accordance with the provisions of the Modern Slavery Act 2015\. It sets out the steps taken by 3M United Kingdom PLC ending 31 December 2016 to prevent modern slavery and human trafficking in its business and supply chains. Introduction from Christiane Gruen, Managing Director of 3M UK.  We, as an organisation, are proud of the steps we have taken, and continue to take, to combat slavery and human trafficking. Global Human Rights Policy was adopted in 2013...

这很有趣,文本在这里看起来完全没问题。上面的例子来自 3M,但其他返回区域也是干净的。因此,聚类 1 是从现代奴隶制陈述中获得的真实数据的一部分,而不是较差的数据质量。当我们进一步分析数据时,我们希望研究为什么这个集群存在

群组 4 和 5:

#locate cluster 4 and 5 and return the text column as a list:
combined.loc[(combined['Cluster']==4) | (combined['Cluster']==5)].text.valuesreturns:
...UK MODERNSLAVERY ACTStatement for the financial year ending 31 December 2016lUK MODERNSLAVERY ACTStatement for the financial year ending 31 December 2016oUK MODERNSLAVERY ACTStatement for the financial year ending 31 December 2016yUK MODERNSLAVERY ACTStatement for the financial year ending 31 December 2016eUK MODERNSLAVERY ACTStatement for the financial year ending 31 December 2016eUK MODERNSLAVERY ACTStatement for the financial year ending 31 December 2016sUK MODERNSLAVERY ACTStatement for the financial year ending 31 December 2016 UK MODERNSLAVERY ACTStatement for the financial year ending 31 December 2016aUK MODERNSLAVERY ACTStatement for the financial year ending 31 December 2016n...

这是我们杂乱的数据。令人印象深刻的是,即使单个单词有意义,该算法也足够智能,可以正确地对上面的例子进行聚类。

我们现在需要做的就是从数据集中排除这些聚类,然后继续分析一组漂亮、干净的数据。

在 Python 中清理和准备数据

原文:https://towardsdatascience.com/cleaning-and-preparing-data-in-python-494a9d51a878?source=collection_archive---------3-----------------------

Photo by Artem Bali on Unsplash

每个数据科学家工作中无聊的部分

数据科学听起来很酷,很棒。它被描绘成很酷很棒的东西。众所周知,这是 21 世纪最性感的工作(我甚至不会把链接加到:D 那篇文章上)。所有很酷的术语都与这个领域相关——机器学习、深度学习、人工智能、神经网络、算法、模型……

但这一切只是冰山一角。我们 70–80%的工作是数据预处理、数据清理、数据转换、数据再处理——所有这些枯燥的步骤都是为了使我们的数据适合将创造一些现代奇迹的模型。

今天我想列出所有可以帮助我们清理和准备数据的方法和函数。

那么我们的数据会有什么问题呢?很多事情其实:

  • 不相关的列名
  • 极端值
  • 复制
  • 缺失数据
  • 必须处理的列
  • 意外的数据值

探索性分析

为了快速概述,我们可以使用数据帧的以下方法和属性:

df.head() # show first 5 rows
df.tail() # last 5 rows
df.columns # list all column names
df.shape # get number of rows and columns
df.info() # additional info about dataframe
df.describe() # statistical description, only for numeric values
df['col_name'].value_counts(dropna=False) # count unique values in a column

至少其中一个的输出将为我们提供第一手线索,告诉我们应该从哪里开始清理。

另一种快速检查数据的方法是将其可视化。我们使用条形图表示离散数据计数,直方图表示连续数据计数。

df['col_name'].plot('hist')
df.boxplot(column='col_name1', by='col_name2')

直方图和箱线图有助于直观地发现异常值。散点图显示了两个数值变量之间的关系。

df.plot(kind='scatter', x='col1', y='col2')

可视化数据可以带来一些意想不到的结果,因为它为您提供了数据集中正在发生的事情的视角。从上面看。

整洁的数据

整理数据是通过数据整理过程获得的数据。这是大数据处理过程中重要的清理过程之一,也是数据科学实践中公认的步骤。整齐的数据集有结构,使用它们很容易;它们易于操作、建模和可视化。整齐数据集的主要概念是以这样一种方式安排数据,即每个变量是一列,每个观察(或案例)是一行。

整齐的数据为数据清理提供了标准和概念,有了整齐的数据,就不需要从头开始,重新发明新的数据清理方法。

特点:

  • 您测量的每个变量应该在一列中。
  • 该变量的每个不同的观察值应该在不同的行中。
  • 每一种变量都应该有一个表。
  • 如果您有多个表,它们应该在表中包含一个允许它们被链接的列。
  • (以上均摘自维基百科)

为了转换我们的数据并使其整洁,我们可以使用熔化。

pd.melt() # transform columns to rows

有两个参数你要注意: id_varsvalue_varsid_vars 表示您不希望融合的数据列(即,保持其当前形状),而 value_vars 表示您希望融合为行的列。默认情况下,如果没有提供 value_vars ,所有没有在 id_vars 中设置的列都将被融化。

new_df = pd.melt(df, id_vars = 'do not melt')

与熔化相反的操作是旋转。这里,我们将唯一值转换为单独的列。当我们希望将数据从分析形式转换为报告形式,从机器可读形式转换为人类可读形式时,我们会使用它。

df.pivot(index='date', columns='element', values='value')

虽然,这个方法不能处理重复的值。在这种情况下,我们应该使用。pivot_table() 有一个额外的参数— aggfunc ,它将根据我们提供的函数(sum、count、mean、min、max 或用户定义的函数)处理这些重复项。

df.pivot_table(index='date', columns='element', values='value', aggfunc=np.mean)

解析数据

有时,我们可能会错误地存储数据。例如,存储为“m014”、“f014”、“m1528”、“f1528”的性别组的值。你不能说这是完全错误的,但是最好将这些值分成“性别”和“年龄”两列。为了做到这一点,我们使用 Python 通过访问。对象类型列的字符串属性。

df['gender'] = df.variable.str[0] 
df['age_group'] = df.variable.str[1:]

串联数据

此外,数据可能不会出现在一个巨大的文件中,而是被分成几个不同的块,所以我们必须能够连接所有的数据,并清理它或清理第一个样本,然后对其余部分应用相同的过程。为此,我们可以使用熊猫。concat 方法,它提供了一个数据帧列表,将所有数据帧连接起来。默认情况下,它将存储原始索引,这将导致重复的索引值。为了防止这种情况,我们必须通过传递附加参数 ignore_index=True 来重置新数据帧的索引。

concatenated = pd.concat([df1, df2], ignore_index=True)

但是如果我们有成千上万的文件呢?一个一个的导入,清洗,再重复,会很傻。我们不傻,我们知道 Python 中的循环。唯一缺少的部分是找到所有要导入的文件。我们可以通过 glob library 做到这一点。因此过程如下:编写一个模式,将所有文件保存到一个列表中,遍历 csv 文件,导入每个文件并将数据帧连接成一个。看起来并不困难,但是有了代码示例就好得多了:

# Import necessary modules
import glob
import pandas as pd # Write the pattern: pattern 
pattern = '*.csv' # Save all file matches: csv_files
csv_files = glob.glob(pattern) # Create an empty list: frames
frames = [] # Iterate over csv_files 
for csv in csv_files:     # Read csv into a DataFrame: df 
    df = pd.read_csv(csv)     # Append df to frames 
    frames.append(df)# Concatenate frames into a single DataFrame: final_df
final_df = pd.concat(frames)

合并数据

合并与 SQL join 操作相同。您可以通过每个表中都存在的键将两个或多个表合并成一个表。有三种类型的联接:一对一、一对多、多对多。在 SQL 中,这个过程是高级的,有许多选项和修改,您必须显式地指定想要加入什么以及如何加入。在这里,所有的工作都由一个函数来完成,连接的类型只取决于数据帧中的数据。如果两个数据帧中用作键的列名相同,则使用参数' on '。

merged = pd.merge(left=df1, right=df2, on=None, left_on='col1', right_on='col2')

转换数据类型

拥有正确数据类型的数据是非常重要的,因为以后它可能会跟你和你的分析开一个糟糕的玩笑。还记得有一次我没有将一个列转换为正确的数据类型,花了 1 个小时试图从 string 😄 中减去 float:所以要小心:d .这是数据中的一个典型错误,可以用 pd.to_numeric()errors = ' constrate '修复,它会将所有的 err 值转换为 nan。

要转换数据,我们可以使用。astype() 方法对一系列。还要记住“category”类型——它减少了数据帧的大小,加快了计算速度。我们可以转换成任何可以用作类别的值——星期几、性别、洲缩写——取决于上下文。

df['column1'] = df['column1'].astype(str) 
df['column1'] = df['column1'].astype('category')
df['column1'] = pd.to_numeric(df['column1'], errors='coerce')

重复值和缺失值

我们最喜欢的部分,不是吗?要删除重复项,我们可以使用 druuuuuuuuumsdrop _ duplicates()方法。

df = df.drop_duplicates()

对于缺失值,情况稍微复杂一点。通常有三种方法来处理缺失数据:

  • 保持原样
  • 放下它们
  • 填充缺失值

要删除丢失的值,我们可以使用。dropna() ,但是要小心——它可能会删除你 50%的数据——这不是很好。但同样,这取决于背景。

为了填补缺失值,我们使用。fillna() ,也要小心——如果我们填充缺失的值,它们必须合理且有意义。

有一篇关于处理缺失数据的精彩文章,我真的没有什么要补充的。这是链接别忘了给作者一点掌声,因为那部作品太棒了。

维护

我们还可以使用 assert 语句以编程方式检查我们的数据。如果结果为真,则不返回任何内容,否则返回错误。

assert 1 == 1 # returns nothing 
assert 1 == 2 # returns error
assert df.notnull().all().all() # returns error if at least one column has one missing value

我跳过了正则表达式,因为它值得另写一篇文章,但是概括了我用于数据预处理的工具。请让我知道,如果有其他东西可以添加,有一个伟大的一天,并使用数据科学的好处🙂

原载于sergilehkyi.com

用 Python 清理金融时间序列数据

原文:https://towardsdatascience.com/cleaning-financial-time-series-data-with-python-f30a3ed580b7?source=collection_archive---------7-----------------------

“Black and white photo of the street sign for Wall St in New York City” by Rick Tap on Unsplash

假设有一家公司, ABC 金融服务公司 根据公司的经济研究代表其客户做出金融投资决策。这些决策中有许多涉及对金融工具未来价格的投机。ABC 公司利用几个经济指标,但有一个指标在他们的分析中特别重要,那就是密歇根大学的消费者情绪调查 (CSI)。

唯一的问题是,他们必须等待这些数据的发布(每月发布一次),这削弱了 ABC 在市场上的一些优势。为了保持竞争力,他们希望能够提前预测这个数字。我建议使用一种机器学习(ML)的形式对尚未发布的最终消费者情绪数据进行时间序列预测。

为此,我们将使用在 CSI 之前发布的其他经济数据(作为 ML 算法的特征)。我们将使用这些数据构建最终数据集,为预测算法做好准备。

多个数据集

我们将使用的历史数据集如下所列,可从以下链接下载:

工具

我们将使用 Python 和 Pandas 库来处理我们的数据清理任务。我们将使用 Jupyter Notebook,这是一个开源的 web 应用程序,允许您创建和共享包含实时代码、等式、可视化和叙述性文本的文档。对于数据科学家来说,这是一个非常棒的工具。你可以前往Anaconda.org下载大多数数据科学库预装的最新版本。

我们将使用 pandas 将上述数据集合并到一个表中,然后进行必要的清理。上述部分数据集已经过季节性调整,以消除可预测的季节性模式的影响。在实际的预测学习/测试中,我们将对两种类型的数据集进行实验。

数据清理在很大程度上取决于数据的类型和您试图完成的任务。在我们的例子中,我们组合来自不同来源的数据,并清理产生的数据帧。在图像分类数据中,我们可能需要对图像进行整形和调整大小,并创建标签,而情感分析任务可能需要检查语法错误和关键词提取。

目视检查数据帧

为此,我们需要从 python 库中导入一些内容,如下所示。

*# Import necessary modules***import** **numpy** **as** **np**
**import** **pandas** **as** **pd**
**import** **matplotlib.pyplot** **as** **plt**
**import** **seaborn** **as** **sns**
%matplotlib inline
**from** **scipy** **import** stats
**from** **datetime** **import** datetime
**from** **functools** **import** reduce
**import** **datetime**

将数据表导入 Pandas 数据框架。

*# load all the datasets to pandas DataFrames*dow     = pd.read_csv('data/Dow Jones Industrial Average DJI.csv')
unemp   = pd.read_csv('data/Civilian Unemployment Rate UNRATE.csv')
oil     = pd.read_csv('data/Crude Oil Prices MCOILBRENTEU.csv')
hstarts = pd.read_csv('data/Housing Starts HOUST.csv')
cars    = pd.read_csv('data/Total Vehicle SalesTOTALSA .csv')
retail  = pd.read_csv('data/Advance Retail Sales_RSXFS.csv')
fedrate = pd.read_csv('data/Federal Interest Rates FEDFUNDS.csv')
umcsi   = pd.read_excel('data/consumer_sent_UMCH_tbmics.xls',header=3)

加载完数据后,我们要做的第一件事就是目视检查数据,了解数据的结构、内容,并注意任何异常情况。您将遇到的大多数数据至少有数千行长,所以我喜欢一次检查随机的行块。

我们使用 head()tail() 函数分别检查表格的顶部和底部。

# view the top of the dow jones tabledow.head()

# view the top of the umcsi tableumcsi.head()

# view the bottom of the data tableumcsi.tail()

我们还可以使用一个循环来遍历所有的表,并获取大小。从这一步开始,我们可以开始预测我们需要做的连接的种类,或者决定我们是否有足够的统计数据来开始。记住坏数据比没有数据更糟糕。

*# get the shape of the different datasets*

dflist = [dow, unemp, oil, hstarts, cars, retail, fedrate, umcsi]
**for** i, dfr **in** enumerate(dflist):
 print(dflist[i].shape)

当我们检查数据时,另一个有用的 pandas 工具是 describe() 函数,它给出了数据中所有数字列的一般统计信息的快照。

*# we look at the statistical charateristics of the datsets*

**for** i, dfr **in** enumerate(dflist):
    print(dflist[i].describe())

The table above contains more columns as indicated by the back slash at the top right

我们还想知道我们是否正在处理包含空值的数据,因为如果忽略,这可能会导致坏数据。获取空值的一种方法是使用 isnull() 函数来提取这些信息。我们使用下面的循环来迭代所有的数据表。

*# see which datasets have null values*

**for** i, dfr **in** enumerate(dflist):
    print(dflist[i].isnull().sum().sum())

对数据进行观察

  • 下面的一些观察结果在上面的图片中并不明显,但在我的 GitHub 库中的这里的原始笔记本中可以看到。
  • 在这种情况下,我们获得的数据对于数百个列来说并不太复杂,但是记住这一点是有好处的,因为情况并不总是如此,我们必须能够轻松处理非常大的杂乱数据。
  • 从上面的检查来看,在我们能够实现最终的干净数据集之前,有一些事情需要纠正。
  • 所有数据集的日期格式都需要转换成统一的格式。
  • 日期范围也很不一致。开始日期从 1947 年到 1992 年。
  • umcsi 中的日期在两列中(字符串浮点),很难与该列中的其他数据集合并。
  • umcsi 也有 3 个空值,因此我们必须删除存在空值的整行。
  • 出于我们的目的,道琼斯数据框架也有额外的列,所以我们需要去掉一些。
  • 这些只是我能观察到的一些修改,但很可能会有其他的并发症。
  • 注释你的代码也是必要的,这样你的同事就能理解你在做什么。
  • 在某些时候,我们还必须将日期格式从字符串更改为支持绘图的格式。

数据清理

道琼斯数据附带了许多我们在最终数据框架中不需要的额外列,因此我们将使用 pandas drop 函数来释放额外的列。

*# drop the unnecessary columns*

 *dow.drop(['Open','High','Low','Adj Close','Volume'],axis=1,inplace=True)*# view the final table after dropping unnecessary columnsdow.head()

*# rename columns to upper case to match other dfs*

dow.columns = ['DATE', 'OPEN', 'HIGH', 'LOW', 'CLOSE', 'ADJ CLOSE', 'VOLUME']# view result after renaming columns
dow.head()

这些步骤中的大部分可以合并成更少的步骤,但我将它们分解,这样我们就可以遵循,并且我们还可以确认我们正在实现预期的结果。接下来,我们从数据表中删除那些具有空值的列。有时候,我们可能需要组合这些空列,然后在以后删除它们,这样我们就可以填充其他表中的值或获得额外的列(信息)。

下面的原位标志永久删除被删除的行。

*# drop NaN Values*

umcsi.dropna(inplace=**True**)

umcsi 表包含数据类型为 float 的年份值,当我们开始获取年份的小数数字时,这可能会有问题。我创建了一个函数,它从 float 列创建一个新的 integer 列。然后我们可以将旧的 float year 列放到()中。有时日期列是字符串格式,我们必须使用内置函数来解析日期,或者我们可以为那些特殊的情况创建自己的列。当您清理数据时,会有很多这样的情况。

*# create 'Year' column with int values instead of float*# casting function
**def** to_int(x):
    **return** int(x)# use function to convert floats to int

umcsi['Year'] = umcsi['Unnamed: 1'].apply(to_int)
umcsi.head()

请注意,我们将月份和年份作为单独的列,需要将它们组合起来,以匹配其余数据表中的日期格式。为此,我们使用 pandas datetime 函数,它能够处理大多数日期和时间操作。事实证明,其他表的日期数据类型为 string,因此我们还必须将 umcsi 日期列更改为 string。这很有意义,因为作为一个时间序列,任何表连接都将在日期列上作为键。

*# combine year columns to one column format*

umcsi['DATE'] = umcsi.apply(**lambda** x: datetime.datetime.strptime("**{0}** **{1}**".format(x['Year'],x['DATE OF SURVEY']), "%Y %B"),axis=1)*# turn date format to string to match other DATE's. We'll merge the data on this column so this is a vital step.*

**def** to_str(x):
    **return** str(x)[:10]

umcsi['DATE'] = umcsi['DATE'].apply(to_str)
umcsi.head()

我们的 umcsi 表看起来很好,除了旧的浮动日期列和月份列,所以我们必须去掉它。为了保持条理,我们还应该把最后的日期列移到前面的列。

*# drop unneeded columns column*
umcsi.drop(['Unnamed: 1','Year','DATE OF SURVEY'], axis=1, inplace=**True**)

*# move 'DATE' column to the front*
cols = list(umcsi)
cols.insert(0, cols.pop(cols.index('DATE')))
umcsi = umcsi.reindex(columns = cols)
umcsi.head()

A more useful table than we started of with.

有了内聚格式的所有表,我们可以继续连接它们并做一些最后的清理步骤。我们将用日期列作为键来连接这些表。我们将使用强大的 lambda 函数来快速完成这个任务。实际上,我们将封装更多的函数来展示 pandas 在数据操作方面有多么强大。

*# concatenate all dataframes into one final dataframe* dfs = [dow,unemp,oil,hstarts,cars,retail,fedrate,umcsi] # we perform the joins on DATE column as key and drop null valuesdf = reduce(**lambda** left,right: pd.merge(left,right,on='DATE', how='outer'), dfs).dropna() df.head(5)

我们现在有了一个最终的熊猫数据框架,尽管它还需要更多的清理。接下来,我们必须从我们的最终表中删除异常值,因为这些异常值可能会在稍后的机器学习任务中引入大量噪声。

*# remove all rows with outliers in at least one row*

df = df[(np.abs(stats.zscore(df.drop(['DATE'], axis=1))) < 3).all(axis=1)]# show final size after removing outliers
df.shape

Final dataframe shape

Python 有一种专门的格式来处理时间列,这种格式非常有效。我们可以使用 strip() 函数从当前的字符串格式中提取出 datetime.datetime 格式。同样,我们将使用 lambda 函数动态地将其应用于所有行。

*# change the DATE column from String to python's 
# datetime.datetime format* df['DATE'] = df['DATE'].apply(**lambda** x: datetime.datetime.strptime(x,"%Y-%m-**%d**"))

最后一步是将这些列重命名为更便于用户使用的名称,以便那些继续使用这些数据的用户使用。

*# rename columns to more user friendly names*

df.columns = ['DATE', 'OPEN', 'HIGH', 'LOW', 'CLOSE', 'ADJ CLOSE', 'VOLUME', 'UNEMP %','OIL PRICE','NEW HOMES','NEW CARS SOLD',
                    'RETAIL SALES','FED INTRST %','CSI' ]# preview final table
df.head(20)

FINAL pandas dataframe

数据清理结论

  • 数据清理有各种形式和大小,没有一个模板可以处理所有情况。
  • 虽然我们不知道数据在预测 CSI 的任务中表现如何,但我们知道所提供的数据已经过处理,以便在 ML 环境中快速采用和测试。
  • 当然,我们可以设计出更多的功能,并对当前的功能进行更多的处理,但对于我们来说,ML 团队将如何进行就太放肆了。例如,我们可以将特征归一化到统一的比例,但没有这样做。
  • 总之,像数据科学领域的大多数任务一样,我们最多只能在合适的团队中不断提问,并根据这些问题进行更深入的实验。

清理债务:熊猫之道

原文:https://towardsdatascience.com/cleaning-up-debt-a-pandas-approach-4093937388de?source=collection_archive---------7-----------------------

不良贷款(NPL)数据的数据争论和探索性数据分析

最近对东南亚信贷市场的分析揭示了这一特定地区信贷文化的一些细微差别。这些数据让我开始思考全球信贷健康状况和全球不良贷款率。鉴于我最近对数据分析的尝试,我认为一个笔记本是合适的。

但首先,什么是信贷市场,什么是不良贷款?

通过考察信贷市场,我们看到了个人、公司和政府向投资者借钱的市场。这种形式的借款可以采取许多不同的形式,从你的日常信用卡支出到你的下一个海滩房屋的抵押贷款。

不良贷款(NPL)是指借款人在一段时间内(通常超过 90 天)无法按期还款的贷款。

当不良贷款水平上升时,通常是信贷市场健康状况恶化的指标。简而言之,更多的人没有偿还他们所欠的债务。

我们将从世界银行数据库中调查不同国家的不良贷款水平。

首先,我们从导入必要的包开始…

因为有些行包含填充列信息,所以我用 islice 跳过前 4 行。

缺失数据

看一下数据框架,似乎表明有许多缺失的数据,尤其是前几年的数据。为了更好地了解通常缺失的数据,我们使用 missingno 来快速可视化。

但是,在使用 missingno 之前,空数据似乎是由 numpy 字符串表示的。因此,我们希望用 np.nan 替换所有这样的实例,以使 missingno 可视化工作。

Any white space indicates missing data

这种可视化似乎表明大量数据缺失,尤其是截至 2010 年的年度数据。相对于之前的 6 年,2016 年似乎缺少更多数据。缺少 2010-2015 年数据的国家因此被剔除。

此外,“指标名称”和“指标代码”这两列似乎也不是特别有用。

我们将创建一个新的数据框架,其中仅包含国家、国家代码和 2010 年至 2015 年的数据。我们还将设置列名,这些列名当前位于第一行。

No missing fields now

数据类型

好多了。剩下 144 个国家/地区的每一列都有值。一些行索引可能不是特定于国家的。但是首先,有数据类型的问题。

检查列的数据类型,所有数据看起来都是非空对象。出于分析代表百分比的 NPL 水平的目的,这些应该是浮动类型的。

将数据类型更改为 float 后,describe()函数再次工作,平均值似乎保持在一个相对较窄的范围内。2010 年和 2011 年的最低不良贷款似乎有一个特殊的异常值。不良贷款可以在 0%吗?似乎是一个幻想世界。

汤加似乎是个例外,2012 年不良贷款跃升至 14%。或许他们只是在 2012 年才开放信贷市场?谷歌快速搜索揭穿了这一说法。这可能是一个错误的条目,我们将从分析中删除汤加。

“过剩”数据

看一下“国家名称”一栏,发现有 143 个“国家”,但其中许多是指特定的地区和分类,如“南亚(IDA & IBRD)”。我们只想要纯国家数据,所以我们将从 country_list 导入一个已知国家名称的列表,并过滤掉它们。

有许多方法可以着手清理国家名单。更好的方法包括寻找最接近的匹配和按分数过滤。例如,ous ful给出了一个使用模糊集寻找近似匹配的很好的例子。

然而,鉴于这是一个相对较小的指数值集,我们可以简单地查看在与国家列表交叉引用时被过滤掉的国家。

在删除的 44 个值中,“波斯尼亚和黑塞哥维那”、“文莱达鲁萨兰国”、“刚果共和国”、“捷克共和国”、“冈比亚”、“中国香港特别行政区”、“吉尔吉斯共和国”、“中国澳门特别行政区”、“马其顿、FYR”、“斯洛伐克共和国”、“特里尼达和多巴哥”等国名似乎应该保留。

然后,我们继续使用列表理解来查找最终的过滤国家列表。

The wonders of list comprehension

现在,我们已经在数据框架中包含了我们想要的国家,让我们添加一些由世界银行提供的相同数据集的其他属性。在单独的 csv 中,他们提供了关于国家所在地区及其人口收入群体的信息。可以对国家代码(文件之间的公共列)进行合并。

融化的

太好了,现在我们有了一个包含相关信息的国家列表。然而,年度不良贷款数据的格式仍然反映了原始数据条目的格式。有了“整洁”的数据结构,EDA 和进一步的分析会更容易。从 2010 年到 2015 年的列名作为值可能比列名更有用。

因此,我们将“融化”数据集。这也被称为从宽格式到长格式。

Long form data for Argentina

添加类别

我们可能在一个数据帧中有了我们想要的数据,但是这是否意味着它已经可以进行分析了呢?快速浏览 info()会得到一个响亮的“不”。

如果我们要进行任何类型的时间序列分析,那么“year”列作为一个非空对象实际上是没有用的,因此它应该被转换为整数或日期时间对象。

此外,虽然你可以按收入群体对数据进行分组,但如果我们在数据上附加一个尺度,可能会更能说明问题。虽然这种标量转换不太适用于地区,但人们可以可靠地对收入群体进行加权。

现在数据集更清晰了,让我们看看数据告诉了我们什么。

不良贷款分布

首先看一下不良贷款水平的分布,就会发现它并不完全是正态分布,而是一种偏态分布。偏斜度和峰度值的计算似乎支持这一点,两者都偏离了“正常”范围。

注意这种偏斜度和峰值的值是很重要的,因为它们会极大地影响任何预测模型。

散点图和识别聚类

接下来,我们来看看这些不良贷款水平在不同收入群体中的分布。然后这些点用颜色编码来代表年份。

我最初预计低收入群体的不良贷款会高得多,因此最突出的是高收入群体国家的大量异常值。债务市场上的这些坏演员是谁?

“坏演员”名单似乎被少数几个国家所控制,如爱尔兰、希腊、圣马力诺和塞浦路斯。

尽管它们的收入水平相对较高,但它们拥有一些最高的不良贷款水平。

这些不良贷款水平很好地反映了现实生活中的事件,爱尔兰在 2012 年重新陷入衰退,塞浦路斯在 2012-2013 年发生金融危机,圣马力诺的金融部门受到欧元区危机的重创,希腊面临着自 2009 年以来的大规模债务危机。

我们还可以进一步了解不同地区的不良贷款水平。快速浏览一下过去几年按地区分组的不良贷款集群,就会发现欧洲、中亚和撒哈拉以南非洲的不良贷款率明显较高。

信用透明度

我们拥有的每个地区的数据量可以作为信贷市场透明度的指标吗?我们数据框架中的国家是近年来拥有充足的不良贷款信息的国家。我们来比较一下各个地区的相对代表性。

“欧洲&中亚”和“北美”地区似乎是不良贷款数据最透明的地区。大多数其他地区徘徊在 50%左右,而“中东和北非”在信贷透明度方面明显落后,只有 19%的国家有不良贷款数据。

后续步骤

对全球不良贷款数据的初步研究得出了一些非常有趣的结果。然而,鉴于这一过程的主要目的是整理世界银行的数据,仍有很大的探索空间。我希望将其他行的数据汇总到这个数据框架中,或许进行一个面板数据分析。

调查每个地区/国家的本地因素以更好地量化信贷文化肯定会很有意思。信贷文化可以是一个相对任意的术语,它的大多数定量测量是基于还款历史和其他贷款数据。将“软”指标纳入对信贷文化的审查是很有趣的。这些“软”指标可能包括对债务的文化观点、贷款积极性、社区信任以及自我概念和借贷或欠款中的“面子”的检查。

如果您对代码感兴趣,请查看 Jupyter 笔记本这里

感谢阅读!

澄清困惑:人工智能 vs 机器学习 vs 深度学习的差异

原文:https://towardsdatascience.com/clearing-the-confusion-ai-vs-machine-learning-vs-deep-learning-differences-fce69b21d5eb?source=collection_archive---------0-----------------------

如果你陷入了区分人工智能(AI)与机器学习(ML)和深度学习(DL)的困惑,请举手…

把你的手放下来,伙计,我们看不见!

尽管这三个术语通常可以互换使用,但它们并不完全指同一事物。

德国计算机专家 Andrey Bulezyuk 在教授人工智能系统如何工作方面有超过五年的经验,他说“这个领域的从业者可以清楚地说出这三个密切相关的术语之间的区别。”

所以,人工智能、机器学习、深度学习有区别吗?

这是一张试图将它们之间的区别形象化的图片:

在上面三个同心圆的图像上可以看到,DL 是 ML 的子集,ML 也是 AI 的子集。

有意思?

因此,AI 是最初爆发的无所不包的概念,然后是后来蓬勃发展的 ML,最后是有希望将 AI 的进步提升到另一个水平的 DL。

让我们更深入地挖掘一下,这样你就能明白哪个更适合你的具体用例:人工智能,机器学习,还是深度学习。

什么是人工智能?

顾名思义,人工智能可以被松散地解释为将人类的智能融入到机器中。

人工智能是一个更广泛的概念,包括从优秀的老式人工智能 (GOFAI) 到深度学习等未来技术的一切。

每当机器根据一套规定的解决问题的规则(算法)完成任务时,这样的“智能”行为就是所谓的人工智能。

例如,这种机器可以移动和操纵物体,识别是否有人举手,或者解决其他问题。

人工智能驱动的机器通常分为两组——通用型和窄型。一般的人工智能 AI 机器都是可以智能解决问题的,像上面说的那些。

狭义智能人工智能机器可以很好地执行特定的任务,有时甚至比人类更好——尽管它们的范围有限。

Pinterest 上用于分类图像的技术就是狭义人工智能的一个例子。

什么是机器学习?

顾名思义,机器学习可以宽泛地解释为赋予计算机系统“学习”的能力。

ML 的目的是使机器能够使用提供的数据进行自我学习,并做出准确的预测。

ML 是人工智能的子集;其实简单来说就是一种实现 AI 的技术。

这是一种训练算法的方法,这样它们就可以学习如何做出决策。

机器学习中的训练需要向算法提供大量数据,并允许它学习更多关于处理过的信息。

例如,下面的表格根据水果的特征确定了水果的类型:

正如你在上面的表格中看到的,水果是根据它们的重量和质地来区分的。

然而,最后一行只给出了重量和质地,没有给出水果的类型。

而且,可以开发一种机器学习算法来尝试识别水果是橙子还是苹果。

在该算法获得训练数据后,它将学习橙子和苹果之间的不同特征。

因此,如果提供重量和质地的数据,它可以准确地预测具有这些特征的水果的类型。

什么是深度学习?

如前所述,深度学习是 ML 的子集;事实上,它只是一种实现机器学习的技术。换句话说,DL 是机器学习的下一次进化。

DL 算法大致受到人脑中发现的信息处理模式的启发。

就像我们用大脑来识别模式和分类各种类型的信息一样,深度学习算法可以被教会为机器完成同样的任务。

大脑通常试图解读它接收到的信息。它通过给物品贴上标签并将其归入不同的类别来实现这一点。

每当我们接收到新信息时,大脑都会试图在理解它之前将其与已知项目进行比较——这与深度学习算法采用的概念相同。

例如,人工神经网络(ann)是一种旨在模仿我们大脑决策方式的算法。

比较深度学习和机器学习可以帮助你理解它们的细微差异。

例如,DL 可以自动发现用于分类的特征,而 ML 需要手动提供这些特征。

此外,与 ML 相比,DL 需要高端机器和相当大量的训练数据来提供准确的结果。

收尾

你现在明白 AI vs ML vs DL 的区别了吗?

然后,举起你的手…

我们承诺开发一种人工智能算法,当有人举手时,它会告诉我们。

使用 TensorFlow.js 进行客户端预测

原文:https://towardsdatascience.com/client-side-prediction-with-tensorflow-js-e143ed53235b?source=collection_archive---------1-----------------------

大家好,我叫 Matvii,是一名数据科学家。我的工作包括数据预处理、开发/训练和部署模型。所以今天我将尝试分享我的知识,并展示如何部署一个模型,一些计算将由客户端完成。下面的帖子是为那些创建了一个模型,并想通过将预测部分委托给客户端来减少服务器负载的人准备的。尤其是对于日常使用 Python 并且对 JavaScript 一知半解的数据科学家来说。可以跳过这个帖子,直接进入我的Github资源库。****

指标 0。简介
1。创建模型
2。设置烧瓶服务器
3。正在创建index.html
4。正在创建
main . js5。更新烧瓶**服务器
**

0。简介
让我们想象你已经创建了一些深刻而令人敬畏的模型,它做了一些伟大的事情 并且帮助人们。例如,该模型通过人们杯子的照片来预测他们最喜欢的表情符号。你把这个模型放在网上,每天的使用量大约是 1000 次查询,不是很多。简单的服务器可以处理它,但是有一天这个模型被公众发现了,你开始每天接收 10 万个查询,同一个服务器可能会死掉。因此,现在您可以扩展服务器并添加越来越多的内存,或者尝试在客户端重写预测。如果你选择第二个选项,这里有一个教程给你。

为了实现目标,我们将拥有以下组件
后端 : Flask,任何你想在 python 中对一个图像进行预处理的库
前端 : tensorflowjs
最近 tensorflowjs 增加了对 node.js 的支持,不过,我们将使用 Flask ,这是一个 python 库。通常,一些经过训练的模型需要数据
预处理才能正确执行。到目前为止,预处理在 python 中比在 javascript 中更方便。(我希望有一天也能在客户端进行预处理)

1。创建模型
你可以通过运行train_model.py为 MNIST 训练模型,或者你可以创建和训练任何你想要的模型。这里重要的一点是保存模型的拓扑和权重。如果你的模型是用 keras 写的,简单的加上这个。

保存模型后,您将拥有一个包含以下内容的文件夹。

其中* — 的group \ -shard \ 是二进制权重文件的集合,
model.json — 是模型拓扑和配置。
**

2。设置 Flask 服务器
是因为我们希望用户访问我们的模型。

简单的服务器到目前为止,没有什么复杂的,只是一个路径返回我们的静态页面index.html。** 还有,系统的一般架构会是这样的。**

3。创建 index.html 我们需要一些入口点,用户将与它交互,我们将在那里运行我们的预测。因此,让我们设置**index.html。**

我们的第一个版本将是这样的。这里唯一重要的是在第 6 行上,它从 cdn 添加了 tensorflowjs。 下一步是添加一些 HTML 主体以便用户能够上传图像和点击按钮。:)在这里。

我们的 HTML 部分的下一步也是最后一步,是给我们的页面添加一些样式,从而给 HTML 元素带来类,同时创建 main.js 文件,该文件将包含我们的神奇预测部分。现在让我们看看index.html 的最终版本。****

您的index.html可能与我的不同,您也可以添加或删除一些部分,但是,这里重要的是:
第 6 行(在头部添加来自 CDN 的脚本——对于生产版本的代码来说是一个不好的做法,但是,我不想麻烦任何人解释什么是 npm
node _ modules)
第 13 行 如果你想让用户上传一张图片,你也可以使用不同类型的输入)
第 20 行(我们的脚本做客户端预测)
****

4。Creating main.js 现在是带来魔力的时候了。首先我们需要初始化按钮、输入、模型和预测的功能。

第 3 行我们有我们模型的 URL,到目前为止它在我的本地机器上,但是一般来说它可以部署在任何地方。此外,稍后我们将在 Flask 中为该模型创建一条路线。
现在让我们添加将下载我们的模型的部分,然后拍摄用户上传的图像并将其发送到服务器进行预处理

我们将图像发送到 /api/prepare/ 我们稍后将添加的路线。我们还将来自服务器的响应从字段图像放到tf.tensor2d
现在是时候为我们的张量添加预测,然后将预测和图像渲染到用户的视图中。最后就是添加一些按钮例程和函数调用。

所以带有客户端预测的神奇脚本的最后一个版本看起来会像这样。

请随意重写获取部分,以便在一个帖子中发送完整的批文件
不要忘记根据用于训练模型的形状对返回的数组进行整形!

5。更新 Flask 服务器
现在我们必须更新我们的服务器,这样它就可以为 /api/prepare 对图像进行预处理,并且还可以为 /model 的 model 提供前端服务。服务器的最终版本将类似于此。

对于的预处理部分,我们有两个函数:
准备(调用/API/prepare)
预处理(拍摄一幅图像,将调整后的图像返回到 numpy 数组,这个函数可以做任何你喜欢的预处理,只要它返回 numpy 数组,一切都会正常工作)
模型部分:

为什么我们需要两个函数和两个独立的 API 来服务一个模型,而不是一个?

tensorflowjs 的下一个版本中,当我们为某个 API model = await tf.loadModel(modelURL); 加载模型时,它首先从modelURL加载模型,这是一个 JSON 文件,然后它自动向域名根发送几个帖子,以便加载碎片(在服务器日志中的演示中查看这些帖子)。因为我不想把我的模型放在服务器旁边的根目录中,所以我需要两个函数,一个用于 model.json ,另一个用于 shards

就是这样!现在,你可以将预测人们最喜欢的表情符号(根据他们杯子的照片)发送到客户端,或者像我一样,只发送 MNIST!此外,如果一切正常,您将会看到类似这样的内容。

感谢您的阅读!随意添加/重写你喜欢的任何部分!尽情享受吧!
Github

克隆人类驾驶员的行为,并将其应用于自动驾驶汽车

原文:https://towardsdatascience.com/clone-a-human-drivers-behavior-and-mimic-it-to-let-a-vehicle-drive-autonomously-e2930a61b42c?source=collection_archive---------10-----------------------

如何克隆人类司机的行为?嗯,首先,我们需要去兜兜风,同时采集一些数据。听起来不错。让我们开始吧。没那么快。你会问为什么?因为我车里没有设备来完成这件事。好吧,我会退而求其次:一个由 Udacity 创建的模拟环境,它服务于我的目的:在模拟环境中驾驶汽车并捕捉数据。听起来像是轻而易举的事,但我不知道我的游戏技能充其量也就是一般水平。我试了 20 多次才让这辆车在跑道上行驶而不撞车。现在我有了一些数据,我需要建立一个卷积神经网络(CNN),并训练它模仿我捕捉的数据。如果一切顺利,CNN 模型将学习模仿驾驶行为,并克隆学习自己驾驶。如果你只对最终结果感兴趣,就跳到这个 视频 。关于详细的讨论,请继续阅读。

希望一切顺利,我建立了模型,训练了它,并在模拟器上焦急地测试它,以查看结果:当我的车可以自主游泳和越野时,谁想模仿我的驾驶!看看下面的视频,你就会明白我在说什么了。在那一瞬间,我觉得我的冒险车是最酷的!它可以越野行驶,也可以游泳。直到它翻转过来的那一刻😒。回到基础,我去了。

第一步:收集和探索数据

我最初捕捉到的训练数据是在赛道上跑一圈多一点。我需要更多的数据和更好的模型。为了获取更多的数据,我没有重新使用我糟糕的视频游戏技能,而是选择用 Udacity 提供的额外数据来扩充我的数据。模拟器有一辆带有三个捕捉图像的前置摄像头的汽车:左视图、中间视图和右视图各一个。它还输出一个包含以下六列数据的 CSV 文件:第 1 列:中间图像的图像路径,第 2 列:左侧图像的图像路径,第 3 列:右侧图像的图像路径,第 4 列:转向角度,第 5 列:油门,第 6 列:刹车

我在专栏 1-3 中使用了所有三张图片,因为它们提供了道路的不同视角。然而,左和右相机图像的转向角需要通过校正因子来调整,以考虑相机位置。我绘制了转向角的直方图(图 1)以探索数据的分布,并发现许多数据集中在零附近,即直线行驶。这是有意义的,因为赛道上有很多直线行驶,这将导致模型中直线行驶的偏差。

Fig 1: Histogram of Steering Angles distribution

第二步:处理和扩充数据

为了解决驾驶偏向直线的问题,我删除了一些接近零转向角的数据点,并使它们下降,以便分布均匀。当我绘制这些数据的直方图(图 2)时,它看起来确实更加一致。

Fig 2: Histogram of Steering Angles distribution after removing biases

图像大小为 160x320x3(图 3)。然而,顶部图像的三分之一是与模型无关的数据:地平线以上的天空和树木等。底部的 25 个像素也无关紧要,因为它有汽车的引擎盖。我裁剪了图像,去掉了这些区域,使图像尺寸缩小到 70x320x3。

Fig 3: Sample image of the input dataset

由于树木的原因,图像中似乎有阴影,我想确保汽车可以在不同的照明条件下行驶。所以,我用随机的阴影和亮度增强来处理一些受这篇帖子启发的图片。随机亮度&阴影增强的结果如图 4 & 5 所示。

Fig 4: Images with varying brightness

Fig 5: Images with random shadows

模拟器轨道也有许多左转,这些数据会导致模型偏向于向左行驶。为了解决这个问题,我将一半的图像随着转向角度翻转,以生成向右行驶的图像。现在,我相信我已经有了一个平衡的数据集,可以将模型推广到各种情况下的驾驶,图 2 中的直方图证实了这一点。

第三步:建立一个 CNN 模型

我在这个项目中使用了英伟达的 CNN 模型的改编版,因为它是为自动驾驶而设计的。我用 Keras 建立了这个模型。经过实验(步骤 4),我用 L2 正则化和 ELU 激活对模型进行了微调,得到了图 6 中的架构。

Fig 6: Network Architecture Details

第四步:训练和微调模型

我以 85/15 的比例将输入数据集分成训练和验证数据集,并训练 CNN 模型。与交通标志分类问题不同,该项目的目标是预测转向角,这可以通过线性回归实现。我使用 Adam 优化器来获得预测转向角的最佳均方误差(MSE)值。我用 10 个历元进行训练,批量为 64 个。为了提高内存效率,我没有将预处理过的数据一次性存储在内存中,而是使用了生成器函数来提取数据片段,并根据需要动态处理它们。模型训练的结果总结以及训练和验证损失如图 7 所示。由于 AWS 的处理能力,这些训练运行非常快(大约 7 分钟)。我不认为如果这些运行需要很长时间,我会用不同的设置做很多实验,因为如果我在我的本地计算机上运行,他们会这样做。

Fig 7: Model training results

第五步:在模拟器上测试模型

我拿着经过训练的模型,启动模拟器来测试我的模型,看看它在自主模式下表现如何。经过多次实验,我终于能够让汽车在稳定的基础上自动驾驶。

Results Video of a car driving autonomously

总结:

这是一个非常有趣和令人兴奋的项目。从一辆会游泳的车,到一辆能在赛道上自主驾驶的车,我走过了漫长的道路。在许多领域都有改进的空间,我想在时间允许的情况下重新审视这个项目,让这个模型很好地推广到不同的赛道,在有车道的赛道上驾驶,最终在车流中驾驶。多亏了论坛、其他学生的建议和 Udacity 的资源,我能够测试许多想法,并挑选出最适合我的项目的想法。

这个项目的代码可以在我的 GitHub 库中找到。

结束销售

原文:https://towardsdatascience.com/closing-the-sale-predicting-home-prices-via-linear-regression-2eac62c72818?source=collection_archive---------21-----------------------

通过正则化线性回归预测房价

在今年秋天完成我的数据科学沉浸式学习时,我们的第一个“真正的数据科学项目”之一是分析艾奥瓦州的一组样本住房数据T1 】,这些数据是通过埃姆斯评估办公室收集的,用于计算 2006 年至 2010 年在艾姆斯出售的个人住宅物业的评估值。具体来说,我们被要求创建一个模型来预测预期的房屋价值,并最小化均方根误差(RMSE)

这个数据集已经在一个非常受欢迎的 Kaggle 竞赛系列中使用,并作为一个很好的学习工具来练习应用完整的数据科学模型工作流:从导入/清理到模型预测。

对于这一挑战,我们的队列仅限于使用线性回归来寻找预分割测试数据子集的期望值。这在几个方面很重要:

  1. 因为整个数据集已经被分割成一个测试集,这减少了我们的模型可以训练的实例的数量。虽然建议您通常在建模时执行训练/测试分割,但进一步减少训练集可能会限制整体性能。
  2. 如数据描述中所述,有五个观察值被认为是异常值:“三个...真正的异常值(可能不代表实际市场价值的部分销售)和两个…简单的不寻常销售(价格相对合理的非常大的房子)。”这很有帮助,因为我们可以很容易地量化/识别在我们的训练和测试数据集中有多少离群值。因为我们的线性回归不太可能预测这些异常值,并且评分是基于 RMSE 的,所以我们的模型从训练数据归纳到测试数据的能力将受到这些异常值的数量是否在训练集内的更大影响。
  3. 由于销售价格的广泛分散和正偏差,部分由于上述异常值,该模型将倾向于低估多于高估。这可以通过记录目标要素(和/或任何其他非正态分布的要素)来归一化值的范围来解决。然而,结果很难解释(以对数或平方根美元表示的销售价格),我们无法预测哪个训练或测试集中有哪些异常值。

然而,作为数据科学家,我们必须做出某些假设,并在当前可用数据的范围内工作。

导入、数据清理和 EDA

清理和 EDA 对于这项挑战非常重要,因为该数据集包含许多在分类中可能很重要的有序/分类特征,并且需要转换为数值。

作为基线,我导入了以下库来清理、探索和建模训练数据。

我的第一个预处理步骤是将所有对象类型转换成可用于线性回归的数字特征。根据数据字典,有几个本质上是有序的分类特征。根据我个人的判断,我将对潜在购房者来说很重要的值从 0(如果 n a 是一个选项)或 1(如果 NA 不是一个选项)向上转换(取决于功能的数量)。

虽然我可以使用get_dummies方法,但通过使用一系列值(然后可以缩放)可以得到更多细微差别,并减少总体特征的数量。

Converting some of the categorical features

此外,该数据集中有许多需要估算的缺失/空值。对于具有大量缺失值的要素(如“地块临街面”),更希望使用“真实”值而非“虚拟”值(如 0)来估算这些要素。这可以通过使用均值、中值、众数或其他相关函数来实现。

为了简单和节省时间,我没有使用计算来估算所有缺失的值。相反,我关注的是空值比例最大的变量。对于所有其他特性,我使用了.fillna(0)。使用一个基本的、有点随意的假设,我通过以下方式估算了地段临街面的缺失值:

我通过将某些数字特征转换成字符串,准备了通过.get_dummies转换的非序数分类特征:

Converting numerical features to string types

最后,为了证实我对功能重要性的最初假设,我创建了一个 Seaborn heatmap,它计算了与我的目标功能:销售价格相关的 Pearson 系数。

特征工程和选择

所有数据科学家的一项关键技能是特征选择的艺术和科学。这需要严格的统计测试和专业知识(或直觉)来从噪音中过滤信号。在进行最初的数据探索时,我发现了一个有趣的现象,即包裹 ID 和销售价格之间存在明显的相关性。通过散点图,我们可以发现宗地 ID 中的分歧(5 对 9)以及 PID 以 9 开头的房屋聚集在较低值的趋势。虽然这可能具有统计学意义,但我没有进行假设检验来验证。结果,我考虑到这种噪音,去掉了 PID 列。

由于该数据集的特征(多个相关特征),存在冗余和多重共线性的可能性。虽然我们可以使用某些正则化技术(如套索)来补偿,但我也决定创建特征交互,希望隔离/放大最有影响力的特征。

因为我生成的要素使用不同的比例,所以在拟合模型之前,我应用了StandardScaler作为预处理集进行归一化。

拟合和交叉验证模型

为了验证我的线性回归模型的性能,我实例化并交叉验证了四个变量:多元线性回归、Lasso、Ridge 和 ElasticNet。虽然我的训练数据包含 350 多个特征,但通过使用正则化函数,我能够更准确地微调我的预测。最终,《套索》在 RMSE 和 R。

结论

虽然我非常具体的 Lasso 线性回归在我的训练数据和 Kaggle Challenge(不到 2 万美元 RMSE)的 30%测试数据中表现得相当好,但当该模型应用于其余 70%的测试数据时,我最终失败了。由于存在显著的异常值(我在训练集中去掉了这些异常值),我的模型没有一般化,而是过度拟合了。

尽管如此,我希望我在这篇文章中展示的一些技术对其他有志于学习回归建模的数据科学家有用。

RMSE for Training and Test Data

云计算机视觉

原文:https://towardsdatascience.com/cloud-computer-vision-d5708a3d4e05?source=collection_archive---------4-----------------------

测试概述

我的目标

有时我会把照片上传到像 Shutterstock 或 Depositphotos 这样的网站上。为了更好地被发现,照片应该包含适当的关键字和标题。Depositphotos 没有关键字的建议工具。Shutterstock 在手机应用程序中可以根据图片上的内容神奇地建议关键词。我很感兴趣,并决定创建一个脚本,可以为我所有的照片做同样的事情(我将能够使用它与存款照片)

为什么是云

起初,我尝试使用 OpenCV——它是一个用于计算机视觉的开源库。这个库是这样工作的:你需要提供一些参数(矩阵),这些参数定义了搜索一个图片的内容和图片本身。我开始搜索这些参数,但我发现的只是简单的几何图形和人脸的识别。在哪里找到合适的矩阵或者如何自己创建它还不清楚。那么,为什么是云呢?这样更方便快捷。

微软认知服务

我召回微软服务是因为https://how-old.net网站。比方说,病毒效应是成功的。因此,微软将牛津实验项目更名为认知服务,现在他们提供付费服务。除了计算机视觉,还有一批不同的 API,如文本到语音转换、搜索、人脸检测。注册非常顺利,几分钟后我就可以测试我的照片了。MS Cognitive Service 的一个很好的功能——它可以为图片创建一个标题。

谷歌云愿景

谷歌还提供计算机视觉服务,作为大型谷歌云平台的一部分。意味着更严重更复杂。注册真的很长,需要信用卡。谷歌云的一个很好的功能是地标探测——它可以在图片上找到著名的地方并命名。

克拉里菲

这是一家成立 4 年的纽约公司。他们主要也是唯一的服务是云计算机视觉。他们在 ImageNet 竞赛中获得了 5 个名次(这是一种计算机视觉的奥林匹克竞赛)。真正流畅的注册和完美的用户体验。除此之外,他们有真正准确的识别引擎。

我是如何测试的

所有这 3 个服务都有一个在线演示,你可以把你的图片放在那里,并立即得到结果。我用 4 种不同类型的图像进行了测试:特写建筑、城市景观、自然和倒影。以下是微软的一些结果:

Microsoft Computer Vision

所以,微软对大部分图片都做得很好。它为除了有灯笼的图片之外的所有图片提供了一些漂亮的标题和少量的或多或少相关的标签。接下来是谷歌:

Google Cloud vision

你可以在这里看到更多与图片密切相关的标签。没有地标,但是这个服务也可以提供它(像罗马圆形大剧场或者埃菲尔铁塔)。谷歌也有一个用提灯检测图片的问题。接下来是 Clarifai:

Clarifai API

Clarifai API 显示了这几组照片的最佳结果。正如你所看到的,它提供了大量强相关的标签,也很好地识别了灯笼照片。

с对照表

由于复杂的注册和信用卡要求,以及不明确的配额行为,我决定不使用谷歌云视觉。我处理地理相关的标签只是使用免费的地理编码 API。官方 SDK 的缺乏很容易被非官方的掩盖。而且一般来说这只是一个简单的 HTTP 请求。

附加服务

我没有试过亚马逊 Rekognition,因为它需要注册和信用卡,没有在线演示。IBM Alchemy 没有通过我最初的测试。它提供了非常少量的标签,有时标签是不相关的。
还有一堆不同的提供计算机视觉的网络服务,我在 Mashape 博客上发现了几个列表,大多数都已经死了,或者需要复杂的注册而没有在线演示,或者只提供付费服务。

结论

现在用计算机视觉开始工作真的很容易。大多数情况下,它只需要注册,然后发布带有特殊标题的请求。带有 JSON 响应格式的 REST API。但遗憾的是,并不是 100%正确。我想甚至不是 90%。在我的情况下,结果应该由人来审查。对于其他情况,如人脸检测或成人内容,它的效果要好得多。

我希望你喜欢这篇小评论。如果是这样,请不要犹豫,按下心脏按钮。谢谢!

有用的链接

云计算 AWS #1:简介和 EC2 实例创建(通过控制台)

原文:https://towardsdatascience.com/cloud-computing-aws-1-introduction-ec2-instance-creation-via-console-5177a2b43359?source=collection_archive---------12-----------------------

大家好!欢迎来到 AWS 教程。如果你还不认识我,我是 NYU 大学的一名研究生,我冒险进入了写作的世界,与你们分享我有限的知识。我目前正在 NYU 学习“云计算”课程,我认为分享我所学到的东西是值得的。我也在写关于机器学习的文章,所以也来看看这些文章吧!

在这个系列中,我将主要关注实现部分,较少关注理论部分。我知道有许多与 AWS 相关的文章,但它们分散在不同的文章中,我觉得有必要将它们“捆绑”在一起。此外,我计划在接下来的文章中写一些关于使用 AWS 创建 web 应用程序和聊天机器人的内容。

来源

本文的灵感来自各种材料,包括但不限于:

  1. Amazon Web Services in Action 由 Michael Wittig 和 Andreas Wittig
  2. AWS 官方文档
  3. Sambit Sahu 教授的讲座、笔记和幻灯片,以及
  4. 互联网

什么是云计算?

让我们从 NIST(美国国家标准与技术研究院)的官方定义开始:

云计算是一种支持对可配置计算资源(例如,网络、服务器、存储、应用程序和服务)的共享池进行无处不在、方便、按需的网络访问的模型,可配置计算资源可以通过最少的管理工作或服务提供商交互来快速供应和释放。

你脑子进水了,是吗?只要记住这一点:

云计算提供了对随需应变资源的访问,例如计算能力、数据库存储、应用程序和其他一些 IT 资源。

详细定义参见

云可以分为三种类型:

  1. Public -由组织管理的云,对公众开放使用
  2. 私有云 -在单个组织内虚拟化和共享 IT 基础设施的云
  3. 混合云——混合了公共云和私有云的云

云服务也可以分为三种类型:

  1. 基础设施即服务(IaaS) -使用 Amazon EC2 等虚拟服务器提供计算、存储和网络功能等基础资源
  2. 平台即服务(PaaS) -提供将定制应用部署到云的平台,例如 AWS Elastic Beanstalk 和 Heroku
  3. 软件即服务(SaaS)——结合基础设施和运行在云中的软件,包括办公应用程序,如谷歌办公应用程序和微软 Office 365

为什么 AWS 优于其他云平台?

有几个原因:

  • 它是最成熟的云平台
  • 它支持最多的 SDK 语言
  • 社区支持比任何其他云平台都大

AWS 入门

注册过程主要包括五个步骤:

  1. 提供您的登录凭证

前往https://aws.amazon.com,点击创建免费账户/创建 AWS 账户按钮。按照屏幕上的步骤创建您的帐户。

2.提供您的联系凭据

只需在必填字段中填写您的联系信息。

3.提供您的付款详情

是的,您必须提供您的付款详情才能创建 AWS 帐户。请注意,AWS 支持万事达卡和维萨卡。

4.验证您的身份

完成上述步骤后,您将会接到 AWS 的电话。你的屏幕上会显示一个密码,你必须通过电话向机器人语音提供这个密码。

5.选择您的支持计划

选择基本计划,因为它是免费的。

恭喜你!您成功创建了一个 AWS 帐户。您现在可以在https://console.aws.amazon.com登录您的 AWS 管理控制台

注意:强烈建议您按照 AWS 的建议设置计费警报:http://mng.bz/M7Sj

EC2 实例

创建 EC2 实例类似于用编程语言编写“Hello World”程序。理解创建该实例所涉及的各种过程是至关重要的。

EC2 是弹性计算云的缩写。它是一种服务,为我们提供了一个叫做实例的虚拟服务器。使用 Amazon EC2,您可以设置和配置操作系统,并在这个实例上安装应用程序。

启动 Amazon EC2 实例的架构如下所示:

实例是一个 Amazon EBS 支持的实例,即 root 是一个 EBS 卷。Amazon EBS(弹性块存储)提供持久的块存储卷供实例使用。亚马逊 EBS 提供以下内容:

  • 保护实例免受组件故障的影响
  • 提供高可用性和耐用性
  • 提供一致的低延迟性能
  • 在几分钟内增加或减少您的使用

您可以为您的实例指定可用性区域(它应该在那里运行),或者由 AWS 自动为您指定。

要启动您实例,您需要通过指定一个密钥对和一个安全组来保护它。

一个密钥对由一个私钥和一个公钥组成。公钥将被上传到 AWS 并插入到虚拟服务器中。你应该保存私人钥匙;它就像一个密码,但更安全。当您想要连接到实例时,您需要验证您的身份。这是通过使用私钥的认证来完成的。

安全组是 AWS 的一项基本服务,像防火墙一样控制网络流量。当实例启动时,一个或多个安全组与其相关联。有关安全组的更多信息,请参考 AWS 官方文档:https://docs . AWS . Amazon . com/AWS C2/latest/user guide/using-network-security . html

理论说够了!现在,我们将研究以两种方式启动实例:

  1. 通过控制台
  2. 通过命令行

通过控制台创建 EC2 实例

我们将为 Linux 创建一个 EC2 实例,因为这样做很容易。这一过程包括三个主要步骤:

  1. 启动实例
  2. 连接到您的实例
  3. 终止您的实例

1.启动实例

  • 登录控制台:https://console.aws.amazon.com/
  • 在继续下一步之前,请确保您在美国东部(N. Virginia)地区(这只是出于一致性目的)

  • 导航至服务 - > EC2

  • 点击启动实例

  • 现在,选择一个亚马逊机器图像(AMI) 推出了。AMI 充当您的实例的基本模板。选择第一个 AMI(HVM 版)。

  • 选择 t2.micro 实例类型。这是唯一符合“符合自由层条件”的实例类型。 T2 实例为您的虚拟实例提供基线硬件配置。接下来,点击查看并启动。

  • 在这个页面上,您将看到 AWS 为您自动创建了一个安全组。如果要使用现有的安全组,导航到编辑安全组->-配置安全页面->-选择一个现有的安全组。在本教程中,我们将使用自动为我们创建的安全组。点击发射

  • 将弹出一个密钥对。因为我们没有现有的密钥对,所以选择创建新的密钥对选项。写下密钥对的任意名称。我将称它为‘我的钥匙对’。点击下载密钥对。私钥文件将被下载到您的系统中。保管好它。接下来,点击启动实例

  • 您的实例现在将开始运行。导航至页面底部,点击查看实例

  • 现在,您可以看到正在运行的实例的详细信息。花些时间探索和谷歌出某些术语,如“实例 ID”、“公共 DNS (IPv4)”、“IPv4 公共 IP”等。因为如果你理解它们的意思,它会很好地为你服务。同样,等待状态检查栏从 初始化 变为 2/2 检查通过。

2.连接到您的实例

有两种方法可以连接到实例:

  • 通过浏览器(在这种情况下,您需要安装 Java)
  • 通过独立的 SSH 客户端

官方 AWS 文档提供了通过浏览器连接实例的指南。然而,我们将通过独立的 SSH 连接我们的实例。还要注意,我将通过 Mac 连接实例,但我会尽可能为 Window 用户提供说明。

对于 Linux(和 Mac)用户:

  • 大多数 Linux 机器默认安装了 ssh 客户端。您可以通过在终端上键入 ssh 来检查您是否有 ssh 客户端。如果你的电脑不能识别这个命令,那么去http://www.openssh.com/portable.html并按照那里的指示去做。

  • 接下来,安装 AWS CLI。现在并不真的需要这样做,但是稍后当我们尝试以编程方式创建实例时会用到。如果安装了 pip,请键入以下命令:

  • 验证您已经通过该命令安装了 awscli :

  • 在步骤 1 中,我们下载了一个扩展名为'的密钥。pem。找到密钥并记下其路径。我的道路是:

downloads/我的密钥对. pem

  • 使用 chmod 命令确保您的私钥不会被公开。该命令如下所示:

  • 现在,使用 ssh 命令连接到实例。 ssh 命令的语法如下:

ssh-I[私钥路径]用户名@[公共域名或 IPv4 地址]

  • 亚马逊 Linux 的用户名是ec2-用户public_dns_nameIPv4_address 就是您之前记下的那个。写完 ssh 命令后,提示您输入。输入

恭喜你!您现在已经连接到 Amazon Linux AMI。

对于窗口用户:

Window 用户日子有点不好过。默认情况下,他们没有 SSH 客户端,所以他们需要安装免费的 SSH 客户端。如果你有旧版本的 PuTTy,建议安装最新版本。我不会提供一步一步的指示;相反,我会把你重定向到你可以自己做这件事的链接。

  • 从这里下载 PuTTy:【http://www.chiark.greenend.org.uk/~sgtatham/putty/】
  • 为您的 Linux 实例启用入站流量:https://docs . AWS . Amazon . com/AWS C2/latest/user guide/authoring-access-to-an-Instance . html
  • 使用 PuTTYgen 转换私钥: PuTTYgen 会在您安装 PuTTy 时安装。PuTTy 不支持。pem 扩展名,但它可以将。pem 扩展到。使用 PuTTYgen 的 ppk。
  • 启动一个 PuTTY 会话:打开 PuTTY 。从类别窗格中,选择会话并完成主机名 (ec2-user@[public_DNS_name 或 IPv4_address])。然后在连接类型下,选择 SSH 。最后,确保端口号22
  • 接下来,在类别窗格中,展开连接->-SSH->Auth。选择浏览 - >选择。你生成的 ppk 文件->-打开。如果这是您第一次连接到实例,将显示一个安全警告对话框,询问您是否信任该连接。选择。一个窗口打开,您现在连接到您的实例。

最后三条说明,参考 AWS 官方文档:https://docs . AWS . Amazon . com/AWS C2/latest/user guide/putty . html

3.终止您的实例

使用实例后将其终止是很重要的。由于您使用的是实例的 AWS 自由层版本,如果您只是让实例闲置,您将会产生费用。下面是实现它的步骤:

  • 在 EC2 控制台中,单击 Instances 并选择实例。

  • 选择动作->-实例状态->-终止

  • 当提示确认时,点击是,终止

  • 该实例将需要一些时间来终止。等待它关闭。实例状态应该从关闭终止

唷!那是一把!我们终于学会了如何创建一个实例,通过 SSH 访问该实例,并终止它。

对这些人来说就是这样!下周,我们将学习做同样的事情,即以编程方式创建一个 Amazon Linux 实例。敬请期待!

cLPR:一个用于学习姿态和旋转的 3D 数据集

原文:https://towardsdatascience.com/clpr-a-3d-dataset-for-learning-pose-and-rotation-44a39e0a528a?source=collection_archive---------10-----------------------

如果你仍然在媒体上阅读这篇文章,我已经把我的博客搬到了 http://yvanscher.com/blog.html

今天我将发布 cLPR 数据集,一个用于在 3D 机器学习中工作的数据集。该名称代表立方体用于学习姿势旋转。目标是为测试机器学习算法提供许多不同位置的彩色 3D 立方体的良好基线数据集,这些算法的目标是学习姿势和旋转。

在此下载数据集:

https://bit.ly/2yeeA15

数据

数据集包含立方体的 32x32、64x64、128x128、256x256 jpeg 图像(3d 对象的 2d 投影)。jpegs 没有任何质量损失。数据看起来像这样:

The cube in 3 different positions. The first and third image are showing 2 of the same sides (red and cyan).

标签

标签在二进制 numpy 文件中提供。该文件被称为cube1–1.14.3–2018–06–10–12–30–10.npy,通常为cubeN-x.xx.x-datetime.npy,其中x.xx.x是用于转储文件的 numpy 版本,N是该数据文件的多维数据集。它包含数据集中所有图像的立方体中节点的每个位置和旋转。对于这个数据集,结构是 250047 x 8 x 6,它的位置 x 节点 x 6 numpy 数组,其中最后一个维度(0,1,2)的前 3 个值是 x,y,z 位置,最后一个维度(3,4,5)的后 3 个值是以弧度表示的 x,y,z 旋转。您也可以通过修改脚本在rotation_positions数组中存储的内容来创建您想要的任何标签(projector.py,第 90 行)。

所以结构看起来像:

制作数据集

数据集是使用名为pygame的包生成的,该包最初是为制作 python 游戏而设计的。这个包很不错,因为它让你可以轻松地绘制和渲染 2d 或 3d 对象。我使用 pygame 是因为我希望代码足够简单,能够让图形经验和矩阵乘法基础知识有限的人理解。

用于生成数据集的代码在 github 上。让我们来看看这些代码是如何在高层次上工作的。

创建一个线框

首先,我们创建一个立方体的线框。这个线框由节点、边和面组成。节点是空间中的点,每个用 x,y,z 坐标表示。我们将所有节点存储在一个 8x3 的 numpy 数组中。边是两个节点(numpy 数组中节点的索引)。面是连接在一起的 4 个节点(也是 numpy 数组中节点的索引)。

您可以像这样创建一个线框:

我用它来创建 8 个节点,6 个面。您实际上不需要指定边,只需要指定节点和面。您可以测试立方体线框创建;运行存储库中包含的python wireframe.py脚本:

对于这个线框类别,wireframe.py唯一的外部依赖是numpy。这个脚本将创建一个立方体并打印节点、边和面。

产生旋转

然后,我生成一组旋转,我想在三维应用到立方体的节点(立方体的角落)。为了生成旋转,我只需遍历 0-6.3 弧度范围内所有可能的旋转组合(接近 2π弧度,但不完全完美)。

上面的代码片段将生成大约 360 度,2π弧度的旋转。然后在 pygame 的每一帧/迭代中,我们将抓取其中一个旋转并显示出来。

步骤 3 渲染线框

我使用 pygame 的函数绘制多边形来渲染线框。该函数获取一系列边(2 个点,[(x,y,z),(x,y,z)])并在屏幕上以给定的点和边的顺序用该颜色绘制一个多边形。下面是我的代码的快速和肮脏的版本;实际的脚本要复杂一些。

第 4 步应用一个旋转和重新中心立方体

为了对这个立方体进行旋转,我对适当的轴使用了一个旋转矩阵。所以要绕着 x 轴旋转,我会用wireframe.pycreate_rot_x。该函数返回一个矩阵,用于在 x 轴上旋转我们需要的弧度数。然后我在transform函数中在线框的节点和我们创建的旋转矩阵之间做一个点积。所有这些只是将我们节点的 x,y,z 位置乘以矩阵中正确的数字,这样新的位置就会沿着 x 旋转任意多的弧度。我对这次旋转的 xyz 弧度重复上述过程。完成后,重新调整立方体的中心,使它的中间在屏幕的中心。

步骤 5 将立方体节点重置到它们的初始位置

我存储初始位置,并在每次旋转+重定中心+立方体快照后重置它。这使得推理立方体在每次迭代中做什么变得更容易,移动到我给它的旋转。从一个旋转运动到另一个旋转运动也可能会有万向节锁的问题。这有点令人迷惑,所以我想完全避免它。

重复第 3-5 步

当我这样做时,我在每次旋转后截屏 pygame 屏幕,并将位置信息存储在一个 numpy 数组中。在这个过程中,我将图像写入磁盘,最后保存一个包含所有节点位置和旋转的 numpy 数组。

最后一步

标签的目视检查和程序测试。我回放了 numpy 文件(projector.py-t输入选项回放了 npy 文件),看到旋转看起来不错。还通过test_npy_positions功能(输入到projector.py-n输入)运行它,该功能将它与每个部分位置的已知正确值进行比较。上面的解释旨在让你了解代码是如何工作的,更多细节见 github 上的代码。代码并不完美,数据集也不完美,还有很大的改进空间(例如,为标签添加颜色映射以使跟踪更容易)。请随时提出拉请求或自己动手。我真的很感激。

你能用这个数据集做什么?

你可以做的一件事是训练可变自动编码器。为了展示如何使用这个数据集,我提供了两个不同的自动编码器(一个经典的一个传统的)。都有点,泛泛而谈…但重点只是展示一个例子,并不是要有一个完美的模型。

下面是一张图片,其中每个单元代表一个潜在空间的区域,我已经采样,然后通过我们的解码器网络生成一个立方体:

不是所有这些看起来都像立方体,但是嘿,有几个看起来像!代码在这个笔记本里

不要气馁。生成模型是出了名的困难和挑剔,这里有一个我失败的模型输出的例子:

Failed (yet cool) cube outputs.

以下是我在上述数据子样本训练中制作的 vae 模型的必选 gif(每个时期的快照):

GIF of training VAE

如果你想要一个更好的例子,让自动编码器在 autoencoder 中尝试不同的发行版,请看看这篇文章(以及附带的 github 代码),作者是我在阿姆斯特丹大学的朋友 Tim Davidson 和他的几个同事。还有一篇关于 SO3 自动编码器的非常酷的论文使用了这个数据集的一个变种。

结论

谢谢你坚持到最后。如果您发现数据集或任何脚本有问题,请联系我;人们已经在研究论文和项目中使用这种数据(预发布),因此问题应该被了解、公布和调试。

如果您想引用该数据集,您可以这样做:

Yvan Scher (2018). cLPR Dataset. Brooklyn, NY: The InternetOR@misc{Scher:2018,
author = "Yvan Scher",
year = "2018",
title = "cLPR Dataset",
url = "[https://bit.ly/2yeeA15](https://bit.ly/2yeeA15)",
institution = "The Internet"}ORJust say you used the cLPR dataset and link back to this post :)

我要感谢彼得·科林里奇他有一些不错的 pygame 教程。如果你感兴趣的话,我用 pygame 写了其他的博客。如果你想了解图形和人工智能领域的最新项目和有趣的事情,你应该订阅我的时事通讯: 一代机器

干杯!

客户细分的聚类算法

原文:https://towardsdatascience.com/clustering-algorithms-for-customer-segmentation-af637c6830ac?source=collection_archive---------1-----------------------

上下文
在当今竞争激烈的世界,了解客户行为并根据其人口统计和购买行为对客户进行分类至关重要。这是客户细分的一个重要方面,它允许营销人员在促销、营销和产品开发策略方面更好地针对各种受众群调整营销工作。

目标
这篇文章展示了使用 python 中的 k-means 聚类对电子商务网站的客户数据集进行细分的概念。数据集包含大约 300 名客户的 年收入 和他们在电子商务网站上的 年支出 。我们将使用 k-means 聚类算法得出最佳聚类数,并根据提供的数据了解潜在的客户群。

关于数据集
数据集由 303 名客户的年收入(以 000 美元计)和他们一年内在电子商务网站上的总支出(以 000 美元计)组成。让我们使用 python 中的 numpypandas 库来研究这些数据。

#**Load the required packages**
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt#**Plot styling**
import seaborn as sns; sns.set()  # for plot styling
%matplotlib inlineplt.rcParams['figure.figsize'] = (16, 9)
plt.style.use('ggplot')#**Read the csv file**
dataset=pd.read_csv('CLV.csv')#**Explore the dataset**
dataset.head()#top 5 columns
len(dataset) # of rows#**descriptive statistics of the dataset**
dataset.describe().transpose() 

dataset.head()

dataset.describe().transpose()

数据集由 303 行组成。平均年收入为 245000 英镑,平均年支出为 149000 英镑。年收入和年支出的分布用 distplotviolinplot 表示。

可视化数据 disp plot 和 violinplot 显示收入和支出的数据分布。

**#Visualizing the data - displot**
plot_income = sns.distplot(dataset["INCOME"])
plot_spend = sns.distplot(dataset["SPEND"])
plt.xlabel('Income / spend')

Distribution plot of Income & Spend

**#Violin plot of Income and Spend**
f, axes = plt.subplots(1,2, figsize=(12,6), sharex=True, sharey=True)
v1 = sns.violinplot(data=dataset, x='INCOME', color="skyblue",ax=axes[0])
v2 = sns.violinplot(data=dataset, x='SPEND',color="lightgreen", ax=axes[1])
v1.set(xlim=(0,420))

聚类基础 聚类是一种无监督的机器学习技术,其中没有定义的因变量和自变量。数据中的模式用于识别/分组相似的观察结果。

Original Dataset

After Clustering

任何聚类算法的目标都是确保一个聚类中数据点之间的距离与两个聚类之间的距离相比非常小。换句话说,一个群体的成员非常相似,而不同群体的成员极其不相似。

我们将使用 are k-means 聚类来根据客户的收入和支出数据创建客户细分。

K-均值聚类
K-均值聚类是一种迭代聚类算法,其中聚类数 K 是预先确定的,并且该算法基于特征相似性迭代地将每个数据点分配给 K 个聚类之一。

k 均值算法的主要步骤

聚类的数学方法

聚类背后的数学原理,简单来说,就是最小化聚类质心与其相关数据点之间距离的平方和:

  • K =集群的数量
  • N =数据点的数量
  • C=群集 j 的质心
  • (xij—CJ)–数据点与其被分配的质心之间的距离

确定最佳聚类数“K” K-means 聚类的主要输入是聚类数。这是使用 最小化平方(WCSS) 内聚类和的概念导出的。创建一个 scree 图,它在 X 轴上绘制聚类数,在 y 轴上绘制每个聚类数的 WCSS。

Scree plot / Elbow method to determine optimum number of clusters

随着星团数量的增加,WCSS 不断减小。WCSS 的下降最初是陡峭的,然后下降的速率变慢,导致肘形图。弯头形成处的簇数通常给出了最佳簇数的指示。应该结合对业务需求的具体了解来决定最佳集群数量。

对于我们的数据集,我们将使用肘方法得出最佳聚类数:

**#Using the elbow method to find the optimum number of clusters**
from sklearn.cluster import KMeans
wcss = []
for i in range(1,11):
    km=KMeans(n_clusters=i,init='k-means++', max_iter=300, n_init=10, random_state=0)
    km.fit(X)
    wcss.append(km.inertia_)
plt.plot(range(1,11),wcss)
plt.title('Elbow Method')
plt.xlabel('Number of clusters')
plt.ylabel('wcss')
plt.show()

Scree plot of given datatset on customer Income & Spend

根据肘图,我们可以选择 4、5 或 6 个集群。让我们尝试集群的数量和可视化集群,以决定集群的最终数量。

将 k 均值拟合到 k=4 的数据集

**##Fitting kmeans to the dataset with k=4**
km4=KMeans(n_clusters=4,init='k-means++', max_iter=300, n_init=10, random_state=0)
y_means = km4.fit_predict(X)**#Visualizing the clusters for k=4**
plt.scatter(X[y_means==0,0],X[y_means==0,1],s=50, c='purple',label='Cluster1')
plt.scatter(X[y_means==1,0],X[y_means==1,1],s=50, c='blue',label='Cluster2')
plt.scatter(X[y_means==2,0],X[y_means==2,1],s=50, c='green',label='Cluster3')
plt.scatter(X[y_means==3,0],X[y_means==3,1],s=50, c='cyan',label='Cluster4')plt.scatter(km4.cluster_centers_[:,0], km4.cluster_centers_[:,1],s=200,marker='s', c='red', alpha=0.7, label='Centroids')
plt.title('Customer segments')
plt.xlabel('Annual income of customer')
plt.ylabel('Annual spend from customer on site')
plt.legend()
plt.show()

Cluster plot : k=4

该图显示了 4 个集群的分布。我们可以将他们理解为以下客户群:

  1. 第 1 类:中等年收入和低年支出的客户
  2. 第 2 类:年收入高、年支出中等偏高的客户
  3. 第三类:年收入低的客户
  4. 第 4 类:年收入中等但年支出高的客户

集群 4 是一个潜在的客户群。然而,群 2 和群 3 可以被进一步细分以达到更具体的目标客户群。现在让我们来看看当 k=6 时,集群是如何创建的:

**##Fitting kmeans to the dataset - k=6**
km4=KMeans(n_clusters=6,init='k-means++', max_iter=300, n_init=10, random_state=0)
y_means = km4.fit_predict(X)**#Visualizing the clusters**
plt.scatter(X[y_means==0,0],X[y_means==0,1],s=50, c='purple',label='Cluster1')
plt.scatter(X[y_means==1,0],X[y_means==1,1],s=50, c='blue',label='Cluster2')
plt.scatter(X[y_means==2,0],X[y_means==2,1],s=50, c='green',label='Cluster3')
plt.scatter(X[y_means==3,0],X[y_means==3,1],s=50, c='cyan',label='Cluster4')
plt.scatter(X[y_means==4,0],X[y_means==4,1],s=50, c='magenta',label='Cluster5')
plt.scatter(X[y_means==5,0],X[y_means==5,1],s=50, c='orange',label='Cluster6')plt.scatter(km.cluster_centers_[:,0], km.cluster_centers_[:,1],s=200,marker='s', c='red', alpha=0.7, label='Centroids')
plt.title('Customer segments')
plt.xlabel('Annual income of customer')
plt.ylabel('Annual spend from customer on site')
plt.legend()
plt.show()

Cluster plot : k=6

将聚类数设置为 6 似乎可以提供更有意义的客户细分。

  1. 第 1 类:中等收入,低年支出
  2. 第二类:低收入,低年度支出
  3. 集群 3:高收入,高年度支出
  4. 集群 4:低收入,高年度支出
  5. 第 5 类:中等收入,低年支出
  6. 集群 6:非常高的收入,高的年支出

因此,很明显,6 个聚类提供了更有意义的客户细分。

细分客户的营销策略
根据这 6 个集群,我们可以制定与每个集群相关的营销策略:

  • 一个典型的策略是将某些促销努力集中于集群 6 和集群 3 的高价值客户。
  • 集群 4 是一个独特的客户群,尽管他们的年收入相对较低,但这些客户倾向于在网站上花费更多,这表明他们的忠诚度。可能会有一些基于折扣价格的促销活动来吸引这一群体。
  • 对于收入和年度支出都较低的第 2 组,可能需要进一步分析以找出支出较低的原因,并且可以引入对价格敏感的策略来增加该细分市场的支出。
  • 尽管年收入不错,但第 1 类和第 5 类客户在网站上的花费并不多——对这些细分市场的进一步分析可能会导致对这些客户的满意度/不满意度的深入了解,或者降低电子商务网站对这些客户的可见性。策略可以相应地发展。

我们已经看到,我们如何通过使用聚类算法来生成客户细分,从而获得有意义的见解和建议。为了简单起见,数据集只使用了两个变量——收入和支出。在一个典型的业务场景中,有几个变量可能会产生更加现实和特定于业务的见解。

聚类和协作过滤——使用单词嵌入

原文:https://towardsdatascience.com/clustering-and-collaborative-filtering-using-word-embeddings-56ee60f0575d?source=collection_archive---------3-----------------------

第二部分,我训练了一些神经网络:

[## 聚类和协同过滤—实现神经网络

第 1 部分,我探索数据集并使用 t-SNE 算法对其进行可视化:

medium.com](https://medium.com/@gabrieltseng/clustering-and-collaborative-filtering-implementing-neural-networks-bccf2f9ff988)

内容:

  1. 理解和实现单词嵌入
  2. 训练一个“真正的”深而广的网络

动机:我在第二部分最后一点训练的深度和广度神经网络不是真正的深度和广度模型,因为神经网络的‘广度’部分没有使用任何额外的特征;该模型可以更好地描述为“宽浅”模型。

然而,MovieLens 提供了一组额外的信息,我还没有利用这些信息。每个用户都可以“标记”他们评价的电影。

An example of a tag. movieId 339 is for ‘While you were sleeping (1995)’.

挑战在于将这些标签转化为我的神经网络可以用来衡量用户对电影的感受的东西。

  1. 单词嵌入

1.1。单词嵌入简介

第 2 部分中,我了解并实现了嵌入;这将一些输入转换成一个数组。例如,在实现电影的嵌入时,我将每个 movieId 转换成一个长度为 55 的数组。然后这个数组根据数据进行训练,因此它包含了用户对每部电影的感受信息;对于我的神经网络来说,这比随机分配的单个整数电影 ID 更能提供信息。

单词嵌入包括做同样的事情,除了单词。

就像在 ImageNet 的 150 万张图像上训练的 VGG 模型一样,存在大量的嵌入,这些嵌入在大量的文本语料库上训练,以识别单词的特征是什么。

这些单词嵌入是通过大量的句子来训练的。例如,单词表示的全局向量或 GloVe,来自维基百科和 Gigaword ,一个报纸文章的集合。然后替换每个句子中间的一个单词;这很可能使这个句子变得荒谬。嵌入被训练来识别句子是否有意义。

A comparison of superlatives, showing how GloVe captures the similar relationships between the words (credit to GloVe for this plot).

使用预先训练的单词嵌入不同于使用预先训练的模型进行图像识别。因为每幅图像略有不同,当使用 VGG 预训练模型进行图像识别时,我必须下载一个完整的模型,以及它的权重。然而,对于单词嵌入,我可以下载一个字典,将每个单词链接到某个维度的数组(GloVe 有 50、100、200 和 300 维向量)。

An example of a dictionary item in GloVe

1.2。将单词嵌入到 MovieLens 中

[链接到代码](http://LearningDataScience/Recommender_System/Word Embeddings.ipynb)

为了将标签添加到我的神经网络中,我将标签分解成它们各自的单词,并将这些标签附加到各自的用户和电影上。

The pandas Dataframe created

然后,我使用手套字典将这些标签转化为数组,使用 50 维单词嵌入。

由于神经网络的输入需要具有一致的大小,我取了最长标签的长度(19 个单词),并为每个用户和电影制作了一个 19 乘 50 的带有零的“标签数组”。然后,我根据需要用相应的单词 embedding from GloVe 填充尽可能多的行。这与使用 Keras 的填充没有什么不同。

2。训练一个神经网络

利用这个,我可以训练我的神经网络。

A graph of my neural network. Batch Normalization was implemented at each step, and dropout was used based on the values found in part 2.

不幸的是,这种神经网络的性能明显比没有标签时差:

The validation loss for this network was 1.1400, compared to a best of 0.7699 using the ‘deep only’ model.

我认为这种性能上的差异可以归因于标签的稀疏性;在分配的 100,004 个分级中,只有 1296 个具有标签。因此,从神经网络的大部分传来的绝大多数只是零的阵列(这也可以解释为什么模型对数据拟合不足)。

尽管性能令人失望,但这是对单词嵌入的一个很好的介绍,希望在进行更复杂的自然语言处理时会有用。

基于聚类的无监督学习

原文:https://towardsdatascience.com/clustering-based-unsupervised-learning-8d705298ae51?source=collection_archive---------1-----------------------

无监督机器学习是从“未标记的”数据(分类或归类不包括在观察值中)推断描述隐藏结构的函数的机器学习任务。使用无监督学习算法的常见场景包括:
-数据探索
-离群点检测
-模式识别

虽然有一个详尽的聚类算法列表(无论您使用 R 还是 Python 的 Scikit-Learn),但我将尝试涵盖基本概念。

k 均值

最常见和最简单的聚类算法是 K-Means 聚类。这个算法包括你告诉算法在数据集中有多少可能的聚类(或 K)。然后,该算法迭代地移动 k-中心,并选择聚类中最接近质心的数据点。

以 K=3 为例,迭代过程如下:

一个显而易见的问题是选择 K 值的方法。这是使用肘形曲线完成的,其中 x 轴是 K 值,y 轴是某个目标函数。一个常见的目标函数是数据点和最近质心之间的平均距离。

K 的最佳数值是“肘部”或扭曲区域。在这一点之后,通常认为添加更多的集群不会为您的分析增加显著的价值。以下是在 iris 数据集上使用 Scikit-Learn 的 K-Means 的示例脚本:

from sklearn.cluster import KMeans
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
import numpy as np
%matplotlib inline
from sklearn import datasets#Iris Dataset
iris = datasets.load_iris()
X = iris.data#KMeans
km = KMeans(n_clusters=3)
km.fit(X)
km.predict(X)
labels = km.labels_#Plotting
fig = plt.figure(1, figsize=(7,7))
ax = Axes3D(fig, rect=[0, 0, 0.95, 1], elev=48, azim=134)
ax.scatter(X[:, 3], X[:, 0], X[:, 2],
          c=labels.astype(np.float), edgecolor="k", s=50)
ax.set_xlabel("Petal width")
ax.set_ylabel("Sepal length")
ax.set_zlabel("Petal length")
plt.title("K Means", fontsize=14)

如上面的 3D 图所示,K-means 的一个问题是它做硬标签。但是,您可以看到紫色和黄色集群边界上的数据点可以是任意一个。对于这种情况,可能需要不同的方法。

混合模型

在 K-Means 中,我们做了所谓的“硬标记”,在这里我们简单地添加最大概率的标记。然而,存在于聚类边界处的某些数据点可能仅仅具有在任何一个聚类上的相似概率。在这种情况下,我们看的是所有的概率,而不是最大概率。这就是所谓的“软标签”。

from sklearn.mixture import GaussianMixture
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
import numpy as np
%matplotlib inline
from sklearn import datasets#Iris Dataset
iris = datasets.load_iris()
X = iris.data#Gaussian Mixture Model
gmm = GaussianMixture(n_components=3)
gmm.fit(X)
proba_lists = gmm.predict_proba(X)#Plotting
colored_arrays = np.matrix(proba_lists)
colored_tuples = [tuple(i.tolist()[0]) for i in colored_arrays]
fig = plt.figure(1, figsize=(7,7))
ax = Axes3D(fig, rect=[0, 0, 0.95, 1], elev=48, azim=134)
ax.scatter(X[:, 3], X[:, 0], X[:, 2],
          c=colored_tuples, edgecolor="k", s=50)
ax.set_xlabel("Petal width")
ax.set_ylabel("Sepal length")
ax.set_zlabel("Petal length")
plt.title("Gaussian Mixture Model", fontsize=14)

对于上面的高斯混合模型,数据点的颜色基于靠近聚类的高斯概率。RGB 值基于与红色、蓝色和绿色聚类的接近度。如果您查看蓝色和红色集群边界附近的数据点,您将看到紫色,表明数据点靠近任一集群。

主题建模

既然我们已经讨论了数值,让我们转向分类值。一个这样的应用是文本分析。解决这类问题的常用方法是主题建模,将文档或文档中的单词分类成主题。其中最简单的是 TF-IDF 模型。TF-IDF 模型根据单词的重要性对其进行分类。这取决于它们在特定文档中的出现频率(例如科学期刊中的特定科学主题)以及在所有文档中常见的词(例如停用词)。

我最喜欢的算法之一是潜在的狄利克雷分配或 LDA 模型。在这个模型中,文档中的每个单词都有一个基于整个文档语料库的主题。下面,我附上了华盛顿大学机器学习专业化课程的幻灯片:

LDA 模型本身背后的机制很难在这篇博客中解释。然而,人们的一个常见问题是决定主题的数量。虽然对此没有确定的答案,但我个人更喜欢实现每个文档的单词向量的 K 均值的肘形曲线。每个词向量的接近程度可以通过余弦距离来确定。

隐马尔可夫模型

最后,让我们介绍一些时间序列分析。对于聚类,我最喜欢的是使用隐马尔可夫模型或 HMM。在马尔可夫模型中,我们寻找状态和给定当前状态的下一个状态的概率。下面的例子是一只狗在马尔可夫模型中的生活。

让我们假设狗生病了。鉴于目前的状态,它有 0.6%的几率在下一个小时继续生病,0.4%的几率在睡觉,0.5%的几率在拉屎,0.1%的几率在吃东西,0.4%的几率会恢复健康。在 HMM 中,您提供时间序列数据中可能有多少个状态供模型计算。下面给出了波士顿房价数据集的一个示例,包含 3 个州。

from hmmlearn import hmm
import numpy as np
%matplotlib inline
from sklearn import datasets#Data
boston = datasets.load_boston()
ts_data = boston.data[1,:]#HMM Model
gm = hmm.GaussianHMM(n_components=3)
gm.fit(ts_data.reshape(-1, 1))
states = gm.predict(ts_data.reshape(-1, 1))#Plot
color_dict = {0:"r",1:"g",2:"b"}
color_array = [color_dict[i] for i in states]
plt.scatter(range(len(ts_data)), ts_data, c=color_array)
plt.title("HMM Model")

与每个聚类问题一样,决定状态的数量也是一个常见问题。这可以是基于域的。例如,在语音识别中,通常使用 3 种状态。另一种可能性是使用肘部曲线。

最后的想法

正如我在博客开始时提到的,我不可能涵盖所有的无监督模型。同时,基于您的用例,您可能需要算法的组合来获得相同数据的不同视角。至此,我想以 Scikit-Learn 在玩具数据集上著名的聚类演示结束您的演讲:

基于相似性传播的加密货币聚类

原文:https://towardsdatascience.com/clustering-cryptocurrencies-with-affinity-propagation-b0ca9e105bb6?source=collection_archive---------9-----------------------

为了更好地理解硬币相关性,我们部署了一种相似性传播算法,并在市值表的顶端发现了三个不同的加密资产集群,它们协同移动。

介绍

几个月前,拉迪奇的研究团队开始研究区块链复合指数,不是作为一种投资工具,而是为了在评估加密经济中新的分散化项目时有一个清晰和公正的基准。本文讨论了一些初步的统计工作,帮助我们更好地理解硬币运动。简而言之,我们部署了机器学习来解决一场内部辩论——加密货币是独立的资产,根据其价值主张具有独特的运动,还是它们都完全与比特币动荡的新闻周期相关?

为什么这很重要?如果每一个代币都简单地跟随比特币的运动,那么综合指数就不是评估表现的有用机制。

当前的工具和最佳实践还不足以回答这个问题。在光谱的一端,您会发现带箭头的时间序列图意在传达关于世界的一些无可争议的事实,而在另一端,相关矩阵提供了一个很好的总体概念,说明加密资产在一段时间内协同移动的程度,但没有足够的粒度背景来得出决定性的结论。

幸运的是,这个问题的设置看起来几乎像一个标准的无监督聚类问题——我们有一些未标记的数据,我们希望通过相似性组织成组。我说几乎是因为,如果你是一名数据科学家,你应该注意到普通聚类任务的三个区别:(1)时间序列数据,(2)加密经济中的市值是幂律分布的,以及(3)我们不希望像 k-means 聚类那样预先指定返回的聚类数,因为那样会违背本练习的整个目的。

(Left) Time series plot of crypto market capitalizations since January, 2017. (Right) Estimated probability density function of crypto market caps using KDE.

随着问题的明确定义,我们部署了一个相似性传播算法来寻找三个不同的加密资产集群,它们位于市值表的顶端,具有相似的移动。本文的其余部分讨论了我们方法的理论和实践基础,详细说明了结果,并以一些简短的结论性意见结束。

在继续之前,必须一如既往地强调,统计方法,无论多么详尽,都只能提供一个关于世界的概率观点。他们不宣称因果关系,也不宣称绝对真理。尽管如此,这给了我们很多思考。希望你会同意。

为什么要亲和传播?

从一开始,我们就确定了算法需要维护的一些基本需求,以便产生科学勤奋的结果。总的来说,我们发现相似性传播不仅满足了我们所有的需求,而且在理论和实践上也是一个非常强大的算法。

Frey 和 Dueck 在 Science 上发表的 Affinity Propagation 将数据点之间的相似性度量作为输入,并在数据点之间交换实值消息,直到高质量的聚类自然出现。在交换消息时,算法识别样本,样本是很好地描述集群的观察结果。您基本上可以将样本视为质心,只是它们不是每个组中所有对象的平均值,而是描述其最近邻居的真实观察数据点。出于我们的目的,这意味着我们的样本将是一些真正的加密资产。也就是说,在运行算法后,我们仍然计算质心“趋势”线,并在下面的图中显示它们,以便于解释。

识别样本后,算法本身会推断出数据中存在多少自然聚类。根据创造者的说法,唯一真正需要仔细调整的超参数是阻尼因子,当信息在数据点之间传递时,它被设置为以避免数字振荡。创作者建议将阻尼系数设置为 0.9 。在我们的任务中,介于 0.5 和 0.83 之间的值导致识别出四个聚类。将其增加到 0.83 以上会产生三个聚类。更具体地说,设置较高的阻尼因子将组合来自较低阻尼集的第三和第四类,而前两类完全不变。最后,我们将阻尼因子设置在 0.83 以上,因为结果稍微更直观。

我们考虑了一些其他的算法,但是,没有一个能满足我们的一个或多个需求。我们知道,识别一年中只有几个月非常相似,但一年中其他时间完全不同的加密货币是不可取的。同样重要的是,我们想尽可能地测量并隔离新闻周期对市值的日常影响;忽略任何延迟效应。因此,需要在每个日期索引上专门评估相似性,但要跨整个数组。动态时间扭曲,这是一种流行的方法,用于测量具有不同长度和异相相似性的时间序列数据的相似性,但不会起作用,因为它试图找到异相相似性。我们有一个奢侈的问题,数据是有意同相的,长度相同。如上所述,k-means 聚类及其许多变体不会工作,因为我们不想告诉机器人应该有多少个聚类。

对于距离度量,如果我们可以标准化幂律分布数据,标准负欧几里得距离将很好地完成工作。为了做到这一点,每个向量首先进行对数变换,然后通过减去其平均值并除以其标准偏差进行标准化;产生一个干净的和可比较的数据集。

方便的是,以上所有暗示了 sci-kit learn 的相似性传播实现将会很好地满足我们的目的。2 月初,我们从 Coinmarketcap.com 获取了市值排名前 50 位的加密资产的历史数据。在这 50 家公司中,只有 26 家已经存在了足够长的时间,足以进行有效的聚类(至少一年)。

结果

下面的并排图对应于三个已识别的集群中的每一个。在左边,我们以时间序列的形式显示集群,样本为白色,集群中所有对象的质心线为亮黄色。空间中的其他成分显示为淡黄色。在右侧,我们展示了每个集群对应的方框图,这有效地从不同的角度提供了对相同数据的查看。相似性传播算法找到了三个样本:Ripple、Tether 和 DigixDAO。第一个集群主要由已建立的加密资产组成。

Note: The clusters start at index zero.

该集群中值得注意的资产是以太坊和 Ripple,分别是市值第二和第三大资产。集群中的其他应用包括平台(BitShares)、支付网络(Stellar)、货币(Litecoin、Nem、Bytecoin、Verge、Dogecoin)和去中心化应用(Siacoin)。所有这些资产都是在 2015 年或之前创建和推出的,远远早于加密热潮的到来。

下一个聚类包含比特币、Tether、Dash、Monero 和整个样本的总市值。这个集群中的资产都是货币,Dash 和 Monero 是关注隐私的匿名硬币。这是一个有趣的结果,因为有人认为 Tether 正在支撑比特币,从而支撑整个市场,代币据称与美元的比例为 1:1。 Tether 于 2017 年 12 月初被美国商品期货交易委员会传唤

至于第三组,我们真的不知道它是什么。虽然我们预计比特币和以太坊之间可能会出现一些分歧,但这一集群表明,加密领域的异质性比我们预期的要多。我们的密码分析师注意到,这些趋势是 dApp 平台,它们似乎是稍微新的资产。像往常一样,我的观点是,现实世界比我们通常假设的要复杂得多,如果我们增加加密资产的样本,我们可能会发现更多像这样的集群。

结束语

从上面的图表中可以推断出许多值得注意的见解。第一个是显而易见的,我们发现了不止一个集群,这意味着,不,加密资产并不完全遵循比特币不稳定的新闻周期。也就是说,似乎确实存在一前一后移动的自然硬币群,我们预计随着加密样本的增加会有更多。

总的来说,这项研究帮助我们得出结论,评估加密资产的基础框架是一种适当的方法。

其他视角

[## 在两轮融资之间,你应该瞄准多少跑道?

企业家对硬数据的访问是有限的,这些数据可以帮助他们在试图建立一个…

medium.com](https://medium.com/radicle/how-much-runway-should-you-target-between-financing-rounds-478b1616cfb5) [## 按阶段剖析启动失败率

几周前,在一篇题为“在两轮融资之间,你应该瞄准多少跑道?”,我们发现…

towardsdatascience.com](/dissecting-startup-failure-by-stage-34bb70354a36)

法律免责声明 : Radicle 不是投资顾问,并且 Radicle 不就投资于任何证券、资产、代币、基金或其他投资工具的合理性做出任何陈述。拉迪奇不是税务顾问。radic e 在 radic e 复合材料或任何 radic e 分析中包含证券、资产或代币并不是 radic e 购买、出售或持有此类证券的建议,也不被视为投资建议。复合材料的过往表现并不代表或保证未来的结果。所有的胚根材料都是基于公众普遍可获得的信息和据信可靠的来源,仅为信息目的而准备的。所示的综合数据和分析并不代表可投资资产/证券的实际交易结果。Radicle 维护综合数据并计算显示或讨论的综合水平和绩效,但不管理实际资产。

用 K-means 聚类用电曲线

原文:https://towardsdatascience.com/clustering-electricity-profiles-with-k-means-42d6d0644d00?source=collection_archive---------6-----------------------

Photo by Fré Sonneveld on Unsplash

机器学习在能源领域有广泛的应用。一个非常令人兴奋的是提取对电力消费行为的见解。个人或家庭一天中使用能量的方式也被称为“能量指纹”。

在本文中,我们将介绍如何使用 K-means 聚类算法来发现单个家庭的日常负载模式。

该数据集包含 2006 年 12 月至 2010 年 11 月(47 个月)期间收集的 2075259 个测量值。你可以在这里找到

首先,让我们准备好数据

上面的图显示了 1456 天的所有日负荷曲线。通过观察较暗的区域(这里集中了更多的曲线),我们可以看到两种清晰的消费行为模式。

K-均值聚类

K-means 是一种无监督机器学习算法,其中必须事先定义聚类的数量。这就留下了选择多少个集群的问题。

解决这一问题的常用方法是使用轮廓值。这是一个衡量点与自己的聚类相比与其他聚类相似程度的指标。其范围从-1 到 1,其中高值表示某个点与其所属的聚类匹配良好。

我们对所有负载曲线的轮廓取平均值,以便对算法的执行情况有一个全面的了解。

我用一系列的集群数(从 2 到 30)进行实验。重要的是在相同的范围内缩放每个周期,以便能量负载的大小不会干扰群集的选择。

最大平均轮廓出现在只有 2 个聚类时,但是为了更好地说明这个例子,我选择 3 个。让我们看看它们是什么样子:

正如我们所看到的,K-means 发现了三组独特的负载曲线。

绿色集群包含在整个下午保持稳定能源使用的负载。也许这些天居住者呆在家里,像周末和特殊的日期。

蓝色集群在早上有一个高峰,在下午使用量下降,在晚上再次达到高峰。这种模式似乎适合居住者上班和/或上学的工作日。

最后,红色聚类显示全天消费量较低的日子。也许是假日里只有几个电器开着的情况?

用 t-SNE 验证结果

我们可以验证聚类算法结果的一种方法是使用一种形式的维度缩减并在 2D 平面中绘制点。然后,我们可以根据它们所属的集群给它们上色。

为此,一种流行的算法叫做 t-SNE 。算法的内部工作超出了本文的范围,但是可以在这里找到一个很好的解释。

需要记住的是,SNE 霸王龙对 K-means 发现的聚类一无所知。

在上面的图中,每个点代表一个每日的负载曲线。它们从 24 维减少到 2 维。理论上,高维空间中的点之间的距离保持不变,因此相互靠近的点指的是相似的载荷分布。大多数蓝色、红色和绿色点相互靠近的事实表明聚类效果良好。

结论和进一步的工作

本文提出了一种利用 K-means 算法发现用电量聚类的方法。我们使用剪影分数来寻找最佳的聚类数,并使用 t-SNE 来验证结果。

至于下一步,我们可以尝试不同的聚类算法。Scikit-learn 有很多值得探索的地方。一些不需要先验地选择聚类的数量。

另一个有趣的应用是将这个模型扩展到不同的家庭,并找到家庭中相似能源消耗行为的聚类。

我希望你喜欢它!如果您有任何意见和/或建议,请随时联系我。

群集以太坊地址

原文:https://towardsdatascience.com/clustering-ethereum-addresses-18aeca61919d?source=collection_archive---------10-----------------------

使用交易活动中的模式对地址进行分类

介绍

以太坊用户可能是匿名的,但他们的地址是唯一的标识符,在区块链上留下了公开可见的痕迹。

我建立了一个基于交易活动的聚类算法,将以太坊用户划分为不同的行为子群。它可以预测某个地址是属于 exchange、miner 还是 ICO wallet。

数据库使用 SQL 构建,模型用 Python 编码。源代码可以在 GitHub 上获得。

3D representation of Ethereum address feature space using T-SNE

背景

以太坊区块链是一个名为智能合约的去中心化应用平台。这些合同通常用于代表其他资产。这些资产可以代表现实世界中的物理对象(如房地产所有权),也可以是纯粹的数字对象(如公用令牌)。

执行智能合同所需的计算是用生态系统的本地货币 ether 支付的。

以太存储在被称为地址的加密账户中。

动机

许多人认为加密货币提供了数字匿名,这种想法有一定的道理。其实匿名是 MoneroZCash 的核心使命。

然而,以太坊的应用更加广泛,其广泛的灵活性产生了丰富的、公开的交易行为数据集。因为以太坊地址是唯一的标识符,其所有权不会改变,所以可以跟踪、汇总和分析它们的活动。

在这里,我试图通过有效地集群以太坊地址空间来创建用户原型。这些原型可以用来预测未知地址的所有者。

这开启了一系列广泛的应用:

  • 了解网络活动
  • 增强交易策略
  • 改进反洗钱活动

结果

以太坊生态系统中的参与者可以通过他们交易活动中的模式来区分。已知属于交易所、矿商和ico的地址定性地表明聚类的结果是准确的。

技术细节

请随意跳到下面的解读结果

特征工程

以太坊交易数据集托管在 Google BigQuery 上。使用具有最高以太网余额的 40,000 个地址,我创建了 25 个特征来表征用户行为的差异。

Features derived for each address

选择适当数量的集群

使用剪影分析,我确定聚类的最佳数量大约为 8。

这种选择最大限度地减少了具有负轮廓分数的样本的数量,负轮廓分数表明样本可能被分配到错误的聚类。

但是我们怎么知道它是否有效呢?

通过从ethers can . ioblock explorer 抓取数据,我在我的数据集中收集了 125 个地址的众包标签。

大多数标签分为三类:

交易所、矿工和 ICO 钱包。

聚类是一种无监督的机器学习技术,所以我不能使用标签来训练我的模型。相反,我使用它们将用户原型分配给集群,基于每个集群的最高标签密度。结果可以在这里找到

2D visualization of initial clustering. Known addresses on the left.

重新聚类

Exchangeminer 的地址一开始是混在同一个集群里的。为了将它们分开,我执行了第二轮聚类,只使用该聚类中的地址。

通过将相异度从欧几里德距离改为余弦距离,我极大地改善了交易所和矿工之间的分离。

Improved separation of exchanges and miners. Known addresses on the left.

通过将重新聚类的结果代入原始分析,我们最终得到 9 个聚类。

2D visualization of final clustering results. Known addresses on the left.

解释结果

我们可以根据相应的聚类质心得出关于用户行为的结论。

Radar plot — cluster centroid address features

交换

  • 高乙醚平衡
  • 高流入和流出交易量
  • 交易之间的时间非常不规则

交易所是加密空间的银行。这些结果是直观的。

矿工

  • 低乙醚平衡
  • 小平均交易规模
  • 更有规律的交易间隔时间

矿工通过消耗计算能力来保护区块链,并获得以太奖励。矿工团体经常“集中”他们的资源以减少支出的差异,根据贡献的资源来分配收益。

ICO 钱包

  • 高乙醚平衡
  • 少量大额交易
  • 交易之间最有规律的时间

ico(首次公开募股)是加密初创公司常用的融资方式。这些初创公司会有大量的资金,并定期出售大量资金来支付日常业务开支,这是有道理的。

其他类别

  • 交易所矿业集群高度相似,因为它们是在第二轮集群中创建的。
  • 集群 7 中的地址具有大量智能合约活动。
  • 聚类 2 和聚类 5 是高度不同的。

你能识别这些用户群吗?

后续步骤

扩展这项工作将允许对以太坊区块链数据更细致的观察。以下是一些特别有趣的领域:

  • 基于图论和网络分析添加特征
  • 区分机器人和人类
  • 扩展智能合同分析
  • 重复分析 ERC-20 令牌交易活动

有问题吗?建议?

你可以在 Twitter 或者 LinkedIn 上找到我。

参考

Etherscan.io 标签词云

掌握以太坊

表征以太坊地址空间

一把比特币:无名男子的支付特征

感谢 Brandon Martin-Anderson、Alex Cuevas、John Braunlin 和 Eric Bragas 审阅本文草稿。

日常生活中的聚类——第 1 页,共 2 页

原文:https://towardsdatascience.com/clustering-for-everyday-life-1-of-2-cf641ad769b4?source=collection_archive---------4-----------------------

让我们来考虑这个场景:我喜欢步行,所以当我游览一个城市时,我想尽可能多地步行,但我想优化我的时间来观看尽可能多的景点。现在我想计划我的下一次哥谭市之旅,去参观一些蝙蝠侠的地方。我找到了 1000 个蝙蝠侠出现的地方,我最多还有 4 天。我需要把这 1000 个地方分成 4 个桶,这样这些点就可以靠近我可以停车的中心,来计划我的每一天旅行。我该怎么做?

这类问题可以归为聚类问题。但是什么是集群呢?聚类或聚类分析的任务是将一组数据分组到同类或相似的项目中。同质或相似的概念就是这样定义的。所以解决这类问题是必要的:

  • 定义元素之间的“相似性”度量(相似性的概念)
  • 根据所选的度量,找出元素的子集是否“相似”

该算法确定哪些元素形成一个聚类,以及在一个聚类中它们的相似度。参考我的上一篇文章,聚类是一个可以用属于无监督方法的算法来解决的问题,因为算法不知道任何关于聚类的结构和特征的信息。

特别是,对于这个问题,我将使用 k-means 算法:k-means 是一种在给定数据集上查找 k 个组(其中 k 是定义的)的算法。每个组由一个质心来描述,该质心代表每个聚类的“中心”。中心的概念总是指我们为特定问题选择的距离的概念。

对于我们的问题,距离的概念很简单,因为两点之间的真实距离是由一个纬度和一个经度定义的。为此,不能用欧几里得距离而是有必要引入球面余弦定律来计算从到地理点的正确距离。

但是 k-means 算法是如何工作的呢?它遵循一个迭代过程:

这种算法的流行来自于它的:

  • 收敛速度
  • 易于实施

另一方面,该算法不能保证达到全局最优。最终解决方案的质量在很大程度上取决于初始集群集。由于该算法非常快,所以可以应用几次并选择最佳解决方案。

该算法从 k 个聚类的定义开始,其中 k 由用户定义。但是用户如何知道 k 是否是正确的数字呢?他如何知道这些集群是否是“好”集群?测量聚类质量的一个可能的度量是 SSE(误差平方和),其中误差是从聚类质心到当前点的距离。因为这个误差是平方的,所以它更强调远离质心的点。

在下一篇文章中,我将展示一种在 TensorFlow 中解决这个问题的可能方法。

原载于 2017 年 5 月 14 日【devklaus.wordpress.com

日常生活中的聚类—第 2 页,共 2 页

原文:https://towardsdatascience.com/clustering-for-everyday-life-2-of-2-8c57538ec2ce?source=collection_archive---------3-----------------------

在我的上一篇文章中,我写了关于聚类和 k-means 算法的内容。在这篇文章中,我想用这些概念和 TensorFlow 写一个简单的例子。(并帮助自己计划下一次去哥谭市的旅行)。

对于这个实现,我们需要 Python(我使用 3.7,但 2.x 也可以)和一些包:

  • matplotlib
  • 张量流
  • numpy
  • 熊猫

安装这些软件包很简单:

  • 对于 python 2.x: pip 安装<包名>
  • 对于 python 3.x: pip3 安装<包名>

在任何情况下,您都可以遵循每个软件包文档中的安装说明。

到目前为止还好吗?好了,让我们深入代码:

首先,我定义了问题的参数:

  • 点数:1000
  • 集群数量:4
  • 计算步骤数:100

在这个特殊的例子中,我使用了一组随机生成的 1000 个 GPS 位置作为训练集[从第 27 行到第 36 行]关于位置:45.7±9.1。如果你有一个坐标正确的文件,你可以加载并使用正确的坐标。第 34 行到第 36 行显示了训练集:

在第 42 行中,向量值被转换成张量流可用的常数。

在随机建立了训练集之后,我们需要质心[从 44 到 50 的线]并将其转换为将由 TensorFlow 操纵的变量。这是 K-means 算法的关键,我们需要一组质心来开始迭代。

K-means 的代价函数是点和质心之间的距离,该算法试图最小化该代价函数。正如我在以前的帖子中所写的,两个 GPS 点之间的距离不能用欧几里德距离来计算,有必要引入一种更精确的方法来计算 di 距离,这种方法之一是球面余弦定律。对于这个例子,我使用了近似的球面余弦定律。这种近似对于像城市距离这样的距离非常有效,并且在计算上比整个算法的实现更有效。要了解更多关于这个近似值和误差的信息,请阅读这篇有趣的帖子。[第 53 至 63 行]

最后,更新质心[第 65 行]

第 68 行到第 75 行初始化所有变量,实例化评估图,运行算法并可视化结果:

结论:

我的前两篇文章关注的是聚类问题的一种算法:K-means。该算法对数据做了一些假设:

  • 每个属性分布的方差是球形的
  • 所有变量都有相同的方差
  • 每个聚类的先验概率是相同的

如果违反了这些假设,那么算法就失败了。

这种算法的一个可能的缺点是必须事先定义聚类的数量。如果您不知道您的聚类如何,您可以选择另一种聚类算法,如 DBSCAN 或 OPTICS(这些算法基于密度模型而不是质心模型)。或者,您可以在 K-means 中引入后处理步骤,聚合(或分割)两个或更多质心,然后在相同的训练集上重新启动整个算法,但使用新的质心集。

从计算的角度来看,K-means 算法对数据对象的数量是线性的,其他聚类算法具有二次复杂度。所以这是需要记住的重要一点。

原载于 2017 年 5 月 25 日【devklaus.wordpress.com】

欧盟国家集群

原文:https://towardsdatascience.com/clustering-of-eu-countries-b7cbef32c619?source=collection_archive---------9-----------------------

欧盟国家的细分,包括基于消费者的聚类分析&商业信心指标

在本文中,我使用了一个公开的欧盟统计局数据集,来对欧盟国家进行细分。该数据集由 5 个置信度指标组成:

  • 消费者信心指数
  • 建筑业信心指数
  • 工业信心指数
  • 零售信心指数
  • 服务信心指标

这些指标是通过每月在以下领域进行的定性调查形成的:制造业、建筑业、消费者、零售业、服务业和金融服务业。这些调查始于 1980 年,并逐渐包括所有欧盟新成员。目前,整个欧盟每月都有大约 137,000 家公司和超过 41,000 名消费者接受调查。

所使用的指标是余额,即肯定答案和否定答案之间的差异(占总答案的百分比),作为指标,作为置信度指标(余额的算术平均值)。

有关这些调查的更多信息,请点击此链接

欧元区由 19 个国家组成:奥地利、比利时、塞浦路斯、爱沙尼亚、芬兰、法国、德国、希腊、爱尔兰、意大利、拉脱维亚、立陶宛、卢森堡、马耳他、荷兰、葡萄牙、斯洛伐克、斯洛文尼亚和西班牙。

用于获取原始数据集的欧盟统计局包

关于 ETL 步骤的更多细节可以在实际代码中找到,在文章结尾的链接中。

ETL 和探索性分析

原始数据集包含 11,340 个观察值,其中包括欧盟国家每月的这些指标。在处理过的数据集中,我使用了 2014 年以后的观察值& ii)每个州的每个变量的中值,因此最终数据集总共由 28 个观察值组成。通过对所有商业相关的信心指标(建筑、工业、零售和服务信心指标)进行平均,创建了另一个变量,以使用通用的商业信心指标

看到信心指数的地图会很有趣。下面是消费者和平均商业信心指标的图表。

  • 很明显,各国之间存在显著差异。
  • 北欧国家往往有更高的消费者信心指数。
  • 这里有一些异常值。希腊的信心指数明显低于其他国家。

下面是一个散点图,带有标记标签,表明每个国家在消费者和企业信心指标方面的定位。

我们可以从上面的图中看出一些模式,类似于之前的发现:

  • 有一些异常值,比如希腊(左下角)和瑞典(右上角)
  • 有一组国家位于图的中间,表明消费者和企业的平均信心
  • 在所有国家,商业信心都大大高于消费者信心

分割

由于各国之间在信心指标方面存在相当多的差异,因此开发一个细分市场来检查各国组建团队的情况将会非常有趣。
k-means聚类算法用于分割。这是最广泛使用的无监督学习算法。该过程遵循一种简单且容易的方式,通过预先确定的固定数量的聚类(假设 k 个聚类)对给定数据集进行分类。主要思想是定义 k 个中心,每个聚类一个。这些中心应该被巧妙地放置,因为不同的位置会导致不同的结果。因此,更好的选择是将它们放置在尽可能远离彼此的地方。下一步是获取属于给定数据集的每个点,并将其与最近的中心相关联。当没有分数悬而未决时,第一步完成,早期小组年龄结束。在这一点上,我们需要重新计算 k 个新的质心作为上一步得到的聚类的重心。在我们有了这 k 个新的质心之后,必须在相同的数据集点和最近的新中心之间进行新的绑定。已经生成了一个循环。作为这个循环的结果,我们可以注意到 k 个中心一步一步地改变它们的位置,直到不再发生变化,或者换句话说,中心不再移动。

指出合适的集群数量

下面的肘形图(scree)用于检查簇的合适数量。所以我们要寻找的是曲线开始变平的点。

具体而言,计算类内平方和的总和(每个观察值和对应于该观察值被分配到的类的质心之间的欧几里德距离的总和)。

剪影分析

一般而言,轮廓分析确定每个观察值与相应聚类的吻合程度(值越高越好)。

它包括计算每次观察的轮廓宽度:

  • 接近 1 的值表明该观察值与其当前聚类非常匹配。
  • 值为 0 表示它位于两个集群的边界上,并且可能属于其中任何一个集群。
  • 接近-1 的值表示观察值更适合其最近的相邻聚类。

总之,我从两个方面着手,因为从技术和实践的角度来看,这两个方面都更合适。

下面是一个图表,其中包含关于所有集群的信息,指示集群中每个置信度指标的平均值

  • 在建筑信心指标、消费者信心指标和服务信心指标上,A 类往往比 B 类具有更高的值
  • 这两个集群在工业信心指数和零售信心指数上的值相似

主成分

最好能画出这些聚类结果并直观地检查出来。但是不可能想象如此多的变量,因为需要不同的维度。克服这一点的一种方法是使用某种降维技术。特别地,使用 PCA(主成分分析)。它在特征中找到结构并帮助可视化。特别是:

  • 它会找到一些变量的线性组合来创建主成分(新特征)
  • 维护数据中的大部分差异
  • 主成分(新特征)是不相关的(即彼此正交)

下图(双图)显示了绘制在前两个主成分上的所有原始观察值。

  • 集群 A 明显地从集群 B 中脱颖而出
  • 只是有一点重叠

  • 总的来说,北欧国家往往有较高的信心指数,将其归入 A 类
  • 聚类结果可以证实双速欧盟理论(各国在生活水平等许多方面存在显著差异。)

下面是所有欧盟国家的表格,显示了它们的集群和中值信心指标(自 2014 年以来)

全 R 码

混合类型数据的聚类

原文:https://towardsdatascience.com/clustering-on-mixed-type-data-8bbd0a2569c3?source=collection_archive---------0-----------------------

Which methodology to group individuals based on their common patterns and similarities when expressed in multiple data types?

一种使用 R

关于;在…各处 ;大约

聚类 无监督数据 并不是一件容易的事情。事实上,在这种情况下,数据处理和探索通常是由领域知识驱动的,如果不是纯粹的直觉,并且由于没有方法来测量所得分割的准确性(与监督学习相反),因此变得很困难。

此外,无监督学习的入门课程相当经常地讨论理想的用例,比如 k-means 教程,它只适用于数字特征。

然而,真实的业务情况往往会偏离这些理想的用例,需要分析由混合类型数据构成的数据集,其中数值(两个值的差是有意义的)、名义(分类的,不排序的)或序数(分类的,排序的)特征共存

在这篇文章中,我将关注这种情况,在使用 R 的无监督分类练习的背景下。

  • 第一部分包括方法论:我正在讨论使用距离的数学概念来衡量个体之间的相似性的问题。然后,我将介绍 PAM 聚类算法(围绕 medoids 进行划分)以及一种选择最佳聚类数(轮廓系数)的方法。我最后用一句话来结束对的解读
  • 在第二部分中,我将使用 uci 的机器学习库上的银行营销数据集以及来自clusterRtsne包的一些有用的函数来说明方法。该数据集与葡萄牙银行机构的直接营销活动(电话)相关,传统上用于监督学习讨论(分类目标是预测客户是否会认购定期存款)。但是,它包含一些关于银行客户的信息,我们将尝试对这些信息进行“先验”聚类

我们开始吧!

第一部分:方法

如何度量相似度

Data Scientists aiming at clustering ‘unknown’ data, sometimes without business knowledge, use distance to avoid subjectivity and ensure consistent approach to all features

距离是个体之间距离的数值度量,即用于测量个体之间的接近度或相似度的度量。存在许多距离度量,其中一个实际上对破解我们的案例非常有用,那就是高尔距离 (1971)。

高尔距离被计算为个体间部分差异的平均值。每个部分不相似性(以及高尔距离)在[0±1]范围内。

Gower distance’s formula

部分相异 ( d_ij^f ) 计算取决于被评估变量的类型。这意味着将对每个特征应用特定的标准化,并且两个个体之间的距离是所有特征特定距离的平均值。

  • 对于一个数字特征 **f**,偏相异度是 1)观察值x_ix_j的绝对差值与 2)从所有个体观察到的最大范围:d_ij^f = |x_i — x_j| / |(max_N(x) — min_N(x))|,N 是数据集中个体的数量。

Partial dissimilarity computation for numerical features (R_f = maximal range observed)

  • 对于一个定性的特征f,只有当观测值y_iy_j具有不同的值时,偏相异度才等于 1。否则为零。

:使用cluster 包中的daisy()功能,可在 R 中获得更高的距离。特征首先自动标准化(即重新调整至[0 1]范围内)。

聚类算法:MEDOIDS 周围划分(PAM)

高尔距离非常符合 k-medoids 算法。k-medoid 是一种经典的聚类划分技术,它将 n 个对象的数据集聚类成 k 个先验已知的聚类

k-means 算法非常相似,PAM 具有以下特征:

  • ****优点:与 k-means 相比,它直观、对噪声和异常值更鲁棒(由于所使用的距离属性),并且它为每个聚类产生一个“典型个体”(对解释有用)。
  • ****缺点:耗时耗机(运行时间和内存是二次的)。

评估数据集群内的一致性

除非你有一个很好的先验原理来强制一个特定的数量的簇 k** ,否则你可能会对计算机询问一个基于统计的推荐感兴趣。存在几种方法来限定所选数量的聚类的相关性。在第二部分中,我们使用轮廓系数。**

轮廓系数将到同一簇中元素的平均距离与到其他簇中元素的平均距离进行对比。具有高轮廓值的对象被认为是良好聚类的,具有低值的对象可能是异常值。该指标适用于 k-medoids 聚类,并且用于确定最优聚类数。请阅读维基百科页面,了解关于计算和解释的更多细节。

解释

基本上有两种方法来研究这种聚类工作的结果,以便得出一些与业务相关的解释。

  • 1.每簇的汇总,使用 r 中的summary()函数
  • 2.低维空间中的可视化,使用 t-SNE ,使用 r . t-分布式随机邻居嵌入(t-SNE)中的Rtsne()函数是一种降维技术,特别适合于高维数据集的可视化。

我们在用例(第二部分)中涵盖了这两种情况。理论够了,来应用和举例说明吧!

第二部分:用例

在这个用例中,我们将尝试根据以下特征对银行客户进行聚类:

  • ****年龄(数字)
  • ****工作类型(分类):‘行政’、'蓝领'、'企业家'、'女佣'、'管理'、'退休'、'个体户'、'服务'、'学生'、'技术员'、'失业'、'未知'
  • ****婚姻状况(分类):“离婚”、“已婚”、“单身”、“未知”
  • ****教育(分类):“初级”、“中级”、“高级”、“未知”
  • ****违约:有信用违约?(分类):“否”、“是”、“未知”
  • ****余额(数字):年平均余额,单位为欧元
  • ****住房:有住房贷款?(分类):“否”、“是”、“未知”
#' Load useful packages
library(cluster)
library(dplyr)
library(ggplot2)
library(readr)
library(Rtsne)#' Load data
df <- read_csv2("../data/001_unsupervised_mixed_types_data/bank.csv")

根据高尔距离,最相似和最不相似的客户:

#' Compute Gower distance
gower_dist <- daisy(df, metric = "gower")gower_mat <- as.matrix(gower_dist)#' Print most similar clients
df[which(gower_mat == min(gower_mat[gower_mat != min(gower_mat)]), arr.ind = TRUE)[1, ], ]# A tibble: 2 x 7
    age job        marital education default balance housing
  <int> <fct>      <fct>   <fct>     <fct>     <int> <fct>  
1    **52 technician married secondary no          196 yes **   
2   ** 52 technician married secondary no          195 yes**#' Print most dissimilar clients
df[which(gower_mat == max(gower_mat[gower_mat != max(gower_mat)]), arr.ind = TRUE)[1, ], ]# A tibble: 2 x 7
    age job     marital  education default balance housing
  <int> <fct>   <fct>    <fct>     <fct>     <int> <fct>  
1   ** 60 retired married  primary   no        71188 no   **  
2    **26 admin.  divorced secondary yes          -3 yes**

在商业环境中,我们通常寻找一些既有意义又容易记忆的聚类,例如最多 2 到 8 个。轮廓图有助于我们确定最佳选择。

sil_width <- c(NA)
for(i in 2:8){  
  pam_fit <- pam(gower_dist, diss = TRUE, k = i)  
  sil_width[i] <- pam_fit$silinfo$avg.width  
}plot(1:8, sil_width,
     xlab = "Number of clusters",
     ylab = "Silhouette Width")
lines(1:8, sil_width)

7 clusters has the highest silhouette width. 5 is simpler and almost as good. Let’s pick k = 5

解读

  • 每个集群的摘要
k <- 5
pam_fit <- pam(gower_dist, diss = TRUE, k)
pam_results <- df %>%
  mutate(cluster = pam_fit$clustering) %>%
  group_by(cluster) %>%
  do(the_summary = summary(.))
pam_results$the_summary

Clusters’ scorcard

在这里,我们可以尝试为集群中的客户端导出一些通用模式。例如,集群 1 由“管理 x 三级 x 无违约 x 无住房”客户组成,集群 2 由“蓝领 x 二级 x 无违约 x 住房”客户组成,等等。

  • 低维空间中的可视化
tsne_obj <- Rtsne(gower_dist, is_distance = TRUE)tsne_data <- tsne_obj$Y %>%
  data.frame() %>%
  setNames(c("X", "Y")) %>%
  mutate(cluster = factor(pam_fit$clustering))ggplot(aes(x = X, y = Y), data = tsne_data) +
  geom_point(aes(color = cluster))

Clients observed in a lower dimensional space

虽然不完美(尤其是聚类 3),但颜色大多位于相似的区域,这证实了分割的相关性。

结论

这篇文章是我在尝试对混合类型的无监督数据集进行聚类练习时的想法的总结。我认为这可能对其他数据科学家有附加价值,因此分享。

****然而,仍存在一些挑战,包括:

  • 如何处理海量数据集(cf 内存密集)?
  • 一种热编码可能是一种解决方案;这两种方法的优缺点是什么?

请不吝评论并分享您对如何应对这一挑战和改进这一拟议方法的看法。

来源

用变换的文档向量聚类文本

原文:https://towardsdatascience.com/clustering-text-with-transformed-document-vectors-1e14c9f0f198?source=collection_archive---------19-----------------------

距离度量不能跨变换空间进行比较。本文还提出了一种度量方法来测试文档的变换,以提高文档的聚类能力

机器学习中分类的一个姐妹任务是聚类。虽然分类需要用类信息预先标记训练数据,但聚类是无监督的。无人值守的磁盘文本分组有很大的好处,我们想知道单词嵌入是否有帮助。事实上,一旦被识别,这些聚类就可以继续充当类似的未来传入文本的目标分类桶。如果我们成功做到了这一点,我们就不需要预先贴标签了!有价值的目标,但稍后会更多。

单词嵌入产生了从n-长( n 是组成文本语料库的词汇的大小)稀疏文档向量到p-长密集向量的线性变换,其中 p < < n 。在文档向量分类的背景下,我们得出结论,使用 tf-idf 向量和朴素贝叶斯分类器是一个很好的起点。虽然我们不能一概而论,但用预先训练/定制的数字向量替换单词似乎对分类质量没有太大帮助。这篇文章(以及下一篇文章)的总体目标是为一个集群任务重复这个练习。在这篇文章中,我们关注以下几点。

  • 比较和对比文档的距离/相似性度量
  • 变换如何影响向量的可聚集性
  • 如何比较不同转换在集群中的有效性?

1.文档的聚类与分类

聚类依赖于对象之间距离的概念,而分类依赖于对象相似性的概念。这里的对象是按照经过测试和尝试的单词袋方法及其变体(包括单词嵌入)表示为数字向量的文档。我们可以选择使用欧几里德距离度量进行聚类,使用余弦相似性进行分类。直觉上,我们期望相似的文档彼此距离很近。但是这并不能保证,除非我们在实现中明确要求它。在对文档向量进行分类时,我们不必担心的事情对聚类任务很重要。其中一些如下。

  • 在任何给定的空间中,长度归一化对于聚类文档向量是重要的,但是对于分类它们却不是
  • 不同变换空间中的距离和相似性不能直接在数量上进行比较以得出任何结论
  • 转换不需要保持距离或相似性,我们实际上希望它们变得更好,因为首先应用转换是没有意义的。

让我们更详细地看看这些,主要集中在向量之间的距离。

2.长度标准化

用于文档的向量空间模型的核心假设是,如果两个文档包含具有相同相对频率相同单词,那么它们很可能在谈论相同的事情。因此,建立在该前提上的向量通过产生单位余弦相似性来反映它。我们也希望在聚类练习中得到相同的最终结果。也就是说,我们想要构建文档的聚类,其中每个聚类中的文档彼此之间的相似度要高于它们与其他聚类中的文档的相似度。有道理对吗?

但是聚类通常是基于特征空间中向量之间的距离和基于余弦相似性的而不是。也许我们可以使用余弦相似性本身作为距离度量。大多数 K-means 聚类的实现(例如 scikit-learn )不允许自定义距离函数。因此,如果我们想要使用 scikit 中的 K-means 实现对文档进行聚类,我们需要文档的距离度量与其余弦相似性表现相同,以获得对文档进行聚类的良好结果。余弦相似性不受向量大小的影响,而向量之间的距离则不受影响。因此,我们要求在执行聚类任务之前,所有的文档向量都被归一化为具有相同的长度。

为了说明,考虑下面图 1 中的向量 OPOAOBOQOA 就是简单的 OP 但是幅度更大。同样,OB 是 OQ的放大版。但是 OAOBOPOQ 之间的角度相同,因此它们的余弦相似性不受影响。

Figure 1. (A) Magnitude of vectors affects their difference but not their cosine similarity. So we need to normalize document vectors for clustering (B) Linear transformation of vectors does not in general preserve angles or lengths. So once again the document vectors should be normalized after a transformation if clustering is the objective.

Equation 1

让我们非常清楚,我们需要在聚类文档向量的上下文中进行长度归一化,我们希望距离度量表现得像余弦相似性度量一样…长度归一化不是对任何向量集进行聚类的一揽子建议…事实上,它会破坏我们在以前的帖子中获得的完美聚类,其中距离需要是原始向量之间的良好距离…

3.转换

考虑长度为 n 的两个向量 XY ,词汇量的大小。我们通过使用单词嵌入将它们转换成更短的 p 维向量 XY 。我们知道(例如参见单词嵌入和文档向量:第 2 部分。分类)变换与 X' = WX 和 Y' = WY 是线性的其中 Wpxn 矩阵其中 p 是字向量的长度。余弦相似度和新空间中的距离可以如下导出。

Equation 2

显然,在 p 空间中的向量之间的角度和距离是 W 的函数。当且仅当 W 正交时,它们才是不变的。

Equation 3

但是没有理由期望 W 是正交的,因为单词向量是根据底层算法以各种方式从摘要文本中导出的,并且不要求它们是正交的。当我们在这里处理文档时,根据第 1 节中的论点,我们需要,

在进行聚类任务之前,对转换后的文档向量的长度进行归一化

4.距离测量

我们希望向量的线性变换将使我们能够更好地解读数据中的潜在聚类。每次转换都将文档向量带到不同的空间。虽然我们可以在一个空间内比较距离,但我们不能在不同的空间内进行比较。参见下面的图 2,其中 2A 的聚类数据通过线性变换 W_1W_2 进行了变换,分别产生了我们在 2B 和 2C 中看到的聚类。

Figure 2. The relative changes in inter/intra cluster distances are the key. W2 is a preferable transformation than W1 even while it reduces the intercluster separation in absolute terms. The ratio inter/intra cluster distances is larger with W2

图 2B 显示了集群之间距离的较大绝对值。但是图 2C 更好地划分了集群。原因很清楚。在图 2B 中,星团内和星团间的距离都变大了。在图 2C 中,虽然总距离被挤压,但是簇内距离比簇间距离被挤压得更多。这是关键。为了更好地描绘集群,我们需要各个集群尽可能紧凑,同时尽可能远离其他集群。常识对吗?我们可以这样来形式化这一点

我们更喜欢增加集群间距离与集群内距离之比的线性变换……事实上,我们应该期望产生最高比率的变换能够显示集群任务的最佳结果

由于有许多聚类内和聚类间的距离,这里有一个合理的程序来比较聚类任务的不同降阶线性变换。

  1. 选择一个转换
  2. 对于每个聚类 C_i 找到其成员到其质心的中间距离。计算这些中间值的平均值。这是该坐标系的“代表性”距离度量。
  3. 用这个从 1 开始的代表性距离度量值除以每个集群间距离。求这些比值的平均值。
  4. 对每个转换重复 1–3。在 3 中产生较大值的转换应该更适合执行聚类任务

5.一个例子

我们用一个例子来结束这篇文章,这个例子巩固了我们在前面章节中的观察。考虑如下图 3A 所示的具有可识别聚类的 2-d 特征空间。重现这些结果的代码可以从 github 下载。

Figure 3. Cluster detection with transformed vectors. The ratio of intercluster to intracluster distance measures is the metric to evaluate and compare across transformations. (A) Original vectors that show two clusters. (B) The clusters are better separated than in A © The transformation did not help with improving cluster detection here (D-E) Distribution of intracluster distances upon transformation. The whiskers are at 5 and 95 percentile values. The intracluster cluster distances got blown up in 3E as expected from 3B. The intracluster distances got squished in 3D agreeing with 3C.

对这些数据进行简单的线性变换,我们得到了如图 3B 所示的聚类。图 3B 中观察到的正交性并不令人惊讶,因为“我们作弊”并选择了与图 3A 中这些簇的主导方向有些一致的线性变换。我们一般没有这种奢侈,但这只是为了放大变换对聚类检测的影响。应用不同的随机变换会产生如图 3C 所示的挤压星团。根据这些变换,簇内距离(距簇的质心)的实际分布已经改变。3C/3D 中距离的压缩和 3B/3E 中距离的扩展是显而易见的。

很明显,在图 3B 中获得的聚类比图 3A 或 3C 中的聚类分离得更好。对于图 3B,簇间距离与平均簇内中值距离的比值也具有最高值。这就是我们在这篇文章的第 2 到第 4 部分所要建立的观点

6.结论

这个帖子有点短,但也差不多了。我们已经为使用降阶转换对文档进行聚类打下了基础。进入细节和结果会使这个太长。我们将在下一篇文章中讨论这个问题,并结束这个系列。

原载于 2018 年 11 月 26 日【xplordat.com

美国人口聚类:观察加权 k-均值

原文:https://towardsdatascience.com/clustering-the-us-population-observation-weighted-k-means-f4d58b370002?source=collection_archive---------0-----------------------

感谢 Chris Decker 提供以下信息:

对于最近几年发现这个帖子的人: scikit learn 在 2018 年 0.20.0 的 KMeans 中实现了一个“sample_weight”参数再也不用自己卷了。

———
在这篇文章中,我详细介绍了一种 k-means 聚类形式,其中权重与个体观察值相关联。

k 均值聚类近 60 年来一直是机器学习的主力。它简单、有效、直观。我喜欢它的原因之一是,你可以随着时间的推移绘制集群任务,并看到它学习。

From: https://datasciencelab.wordpress.com/2013/12/12/clustering-with-k-means-in-python/

但是,它的伸缩性不是特别好。在笔记本电脑上,你能聚集 10,000 个点吗?当然,没问题。一百万?也许吧,但是会很慢。一亿分?Fuhgeddaboutit!

假设我们想对美国人口进行聚类。为什么?我们可以设置 k=48,并根据当前的人口中心来确定较低的 48 个州的情况。或许,我们想在全国设立 k=1000 个配送中心。也许我们要设置 k = 1000 万个星巴克位置。

美国人口有 3 亿多人。你如何使用 k-means 对它们进行聚类?忽略并行 k-means,让我们限制它在一台笔记本电脑上运行不到 3 分钟。想法?

你可以做的一件事是对数据进行采样;也就是说,用减少的、有希望是代表性的数据子集来运行。另一种方法是聚合数据,大大减少点的数量,但将每个点与每个聚合点代表的原始样本大小相关联。换句话说,对每一点进行加权。

我们可以从哪里获得这样的数据集?美国人口普查局。它们提供了一个非常方便的数据集,其中包含每个邮政编码的居民数量。美国大约有 43,000 个邮政编码,这个数字我们可以轻松地在笔记本电脑上聚集起来。想象一下,我们有一个由邮政编码、经纬度对(k-means 使用的 x-y 坐标)和该邮政编码中的居民数量(体重)组成的数据文件:

“zip”,”state”,”latitude”,”longitude”,”population”
“00601”,”PR”,18.180103,-66.74947,19143
“00602”,”PR”,18.363285,-67.18024,42042
.
.
.
99929,”AK”,56.409507,-132.33822,2424
99950,”AK”,55.875767,-131.46633,47

履行

当然,我们可以去 scikit-learn 或 R 或其他主要的机器学习库运行一些加权 k-means 算法。可惜不是。在一些库中有加权 k-means,但是它们不是我们想要的那种。它们不是为观察值而是为特征提供权重。

也就是说,使用特征权重,我们可以指定纬度应该比经度更影响质心。然而,我们想要指定观察值-权重,使得邮政编码=10012(一个密集的曼哈顿邮政编码)对质心的吸引力远远大于 59011(蒙大拿州一个广阔的低密度区域)。

核心思想非常直观。取(x,y)平面上的四个等权点,质心为(mean(x),mean(y))。

如果我们应用权重,比如说 w=(13,7,4,4),那么权重为 13 的点具有大得多的引力,应该会将聚类中心拉得更靠近它。加权质心现在是:(加权平均(x,w),加权平均(y,w))

距离度量可以是我们通常的欧几里德距离。然而,当我们处理纬度-经度对时,正确的直线距离度量被称为 H 反正弦距离,所以我们将使用它。

我无法在主要的库中找到实现。就连 stackoverflow 都让我失望了。来自那里的一个建议是复制数据点。也就是说,如果加权数据如图所示(上图),将会创建等效的未加权数据集(下图):

显然,这存在扩大数据规模的问题——这正是我们想要解决的问题——而且这只适用于小整数权重。

相反,我从 stackexchange 中找到了一个不错的“常规”k-means 示例(感谢 Gareth Rees !)我将其剥离并修改为观察加权:

import random
import numpy as np
import pandas as pd 
import scipy.spatial
from haversine import haversinedef distance(p1,p2):
  return haversine(p1[1:],p2[1:])def cluster_centroids(data, clusters, k):
  results=[]
  for i in range(k):
    results.append( np.average(data[clusters == i],weights=np.squeeze(np.asarray(data[clusters == i][:,0:1])),axis=0))
  return resultsdef kmeans(data, k=None, centroids=None, steps=20):
  # Forgy initialization method: choose k data points randomly.
  centroids = data[np.random.choice(np.arange(len(data)), k, False)] for _ in range(max(steps, 1)):
    sqdists = scipy.spatial.distance.cdist(centroids, data, lambda u, v: distance(u,v)**2) # Index of the closest centroid to each data point.
    clusters = np.argmin(sqdists, axis=0) new_centroids = cluster_centroids(data, clusters, k) if np.array_equal(new_centroids, centroids):
      break centroids = new_centroids

  return clusters, centroids#setup
data = pd.read_csv(“us_census.csv”)
data = data[~data[‘state’].isin([‘AK’,’HI’,’PR’])]
vals = data[[‘population’,’latitude’,’longitude’]].values
k = 3
random.seed(42)#run it
clusters,centroids=observation_weighted_kmeans(vals,k)#output
data[‘c’]=[int(c) for c in clusters]
lats = [centroids[i][1] for i in range(k)]
data[‘clat’] = data[‘c’].map(lambda x: lats[x])
longs = [centroids[i][2] for i in range(k)]
data[‘clong’] = data[‘c’].map(lambda x: longs[x])
data.to_csv("clustered_us_census.csv", index=False)

在旧的 Macbook Air 上,运行时间从 2 秒(k=1)到 160 秒(k=48)不等。

结果

美国人口的质心在哪里(即 k=1)?似乎是在密苏里州东南部。

对于 k=10,

最后,如果我们根据人口密度“重新划分”我们的州,那么我们会看到一个非常不同的画面。至少 5 个状态将被划分给邻居,并且 CA 和 TX 被分成四个或五个区域。

更新(2017–05–09):以下是完整源代码:https://github . com/leaping llamas/medium _ posts/tree/master/observation _ weighted _ k means

更新(2018–06–10):上面显示的中 post 代码存在一些 bug。然而,github 代码工作得很好。为了明确起见,请确保您正在运行:https://github . com/leaping llamas/medium _ posts/blob/master/observation _ weighted _ k means/medium . py

P.S .如果您要对数据的某个子集进行聚类,比如说对一个州内的地区进行聚类,您需要确保调整质心初始化。也就是说,确保初始质心随机分布在感兴趣的区域内(而不是像示例代码中那样分布在更大的范围内),否则它们将在单个聚类中结束。

聚类——无监督学习

原文:https://towardsdatascience.com/clustering-unsupervised-learning-788b215b074b?source=collection_archive---------0-----------------------

机器学习

什么是聚类?

“聚类”是将相似的实体组合在一起的过程。这种无监督机器学习技术的目标是找到数据点中的相似性,并将相似的数据点分组在一起。

为什么使用聚类?

将相似的实体分组在一起有助于描述不同组的属性。换句话说,这将让我们深入了解不同群体的潜在模式。对未标记的数据进行分组有许多应用,例如,您可以识别不同的客户群/细分市场,并以不同的方式营销每个客户群,以最大化收益。另一个例子是将属于相似主题的文档分组在一起。当你处理大量的变量时,聚类也被用来减少数据的维数。

聚类算法是如何工作的?

有许多算法被开发来实现这一技术,但对于这篇文章,让我们坚持机器学习中最流行和最广泛使用的算法。

  1. k 均值聚类

2.分层聚类

k 均值聚类

  1. 它以 K 作为输入开始,这是你想要找到的聚类数。将 K 个质心放置在空间中的任意位置。
  2. 现在,使用数据点和质心之间的欧几里德距离,将每个数据点分配给与其接近的聚类。
  3. 将聚类中心重新计算为分配给它的数据点的平均值。
  4. 重复 2 和 3,直到没有进一步的变化发生。

现在,你可能会想,我如何在第一步决定 K 的值。

其中一种方法叫做法,可以用来决定一个最优的聚类数。这里,您将对 K 值范围运行 K 均值聚类,并在 Y 轴上绘制“解释的方差百分比”,在 X 轴上绘制“ K ”。

在下面的图片中,你会注意到,当我们在 3 之后添加更多的集群时,它并没有给出更好的数据建模。第一个集群增加了很多信息,但在某个点上,边际增益将开始下降。

Elbow Method

层次聚类

与 K 均值聚类不同,分层聚类从将所有数据点指定为自己的聚类开始。顾名思义,它构建层次结构,在下一步中,它组合两个最近的数据点,并将其合并为一个集群。

1.将每个数据点分配给自己的聚类。

2.使用欧几里德距离找到最接近的聚类对,并将它们合并到单个聚类中。

3.计算两个最近的聚类之间的距离,并进行组合,直到所有项目都聚集到一个聚类中。

在这种方法中,您可以通过注意哪些垂直线可以被水平线切割而不与聚类相交并覆盖最大距离来决定最佳聚类数。

Dendogram

使用聚类算法时要记住的事情:

  • 将变量标准化,以便所有变量都在相同的范围内。这在计算距离时很重要。
    在形成聚类之前处理离群数据,因为它会影响数据点之间的距离。

如果你从这篇文章中学到了什么,那么请❤点击下面,这样其他人会在媒体上看到它。

集群:为什么要使用它

原文:https://towardsdatascience.com/clustering-why-to-use-it-16d8e2fbafe?source=collection_archive---------3-----------------------

作为一名没有编程背景的数据科学新生,我喜欢用简单的方式解释复杂的主题。好像在我的节目开始前自言自语。好吧,我希望你们都准备好了一些集群。

让我们从什么是集群开始?事实上,你已经做过很多次了。这是寻找相似之处并将这些相似点放入一个组(或集群)的行为。让我们都回想一下上次出去吃饭的情形。你首先要弄清楚的是你想要什么类型的食物,墨西哥的、中国的、意大利的等等。你正在制造具有这些属性的多个餐馆的集群。

现在来看一个更加数据科学的例子,我将观察种子的不同属性,看看对这些属性进行聚类是否有助于预测种子是否属于某个物种。

直接进入代码,我们需要导入库来执行下面几行。我还将在底部读取我的数据集

%matplotlib inline 

**import** **pandas** **as** **pd**
**import** **numpy** **as** **np**
**from** **sklearn** **import** cluster
**from** **sklearn** **import** metrics
**from** **sklearn.metrics** **import** pairwise_distances
**import** **matplotlib.pyplot** **as** **plt**
**import** **matplotlib**
matplotlib.style.use('ggplot') 

**import** **seaborn** **as** **sns**seeds = pd.read_csv("../assets/datasets/seeds.csv")

看看我的数据框的前几行,这就是它的样子。使用 pandas 查看这一点的代码是 seeds.head(),它将显示前 5 行

seeds.species.nunique()

然后,我查看了我的“物种”列中独特值的数量,这是“目标值”列(我们试图预测的东西)。我们的数据集中有三个物种

*# Plot the Data to see the distributions/relationships*
cols = seeds.columns[:-1]
sns.pairplot(seeds, x_vars=cols, y_vars= cols, hue='species')

这是一个散点图,显示了我们不同的变量是如何相互联系的,颜色(或我上面设置的色调)是每个不同的物种。因此,你可以开始看到,一般来说,对于我们的大多数变量(预测),种子往往与它们自己的物种聚集在一起。

因为我们有一个目标值,所以我们可以在这里停止聚类,但是很多时候我们会在没有目标值的时候使用聚类。因此,我将放弃我们的目标,看看我们的聚类是否会发现差异,并很好地预测哪些种子应该聚集在一起。

X = seeds.drop("species", axis = 1)**from** **sklearn.metrics** **import** pairwise_distances
**from** **sklearn** **import** cluster, datasets, preprocessing, metrics
X_scaled = preprocessing.normalize(X,axis=0)

我放弃了目标值,我还从 sklearn 导入了几个库,这样我就可以规范化我的数据。规范化数据是组织数据库的属性和关系以缩放范围[0,1]内的所有数值变量的过程。我们这样做是为了使 permiter 等值为 15 的列不会比紧致度等值低于 1 的列更重要

**from** **sklearn.cluster** **import** KMeans

k = 3
kmeans = cluster.KMeans(n_clusters=k)
kmeans.fit(X_scaled)

我使用 kmeans 集群来解决这个问题。它设置随机质心(每组的中心点),这些质心将不断移动,直到它们位于一组点的中心,以使所有点的平均距离尽可能小。

inertia = kmeans.inertia_
**print** 'Silhouette Score:', metrics.silhouette_score(X_scaled, labels, metric='euclidean')

我在上面所做的是查看两个不同的指标来分析我们的聚类方法做得有多好。惯性是每个聚类的误差平方和。因此,惯性越小,集群越密集(所有点越靠近)

轮廓分数从-1 到 1,显示了聚类之间的距离以及聚类的密度。你的轮廓分数越接近 1,你的聚类就越明显。如果你的分数是 1,把你的集群想象成完美的小球,它们彼此远离,没有分类失误。

聚类可以用在很多问题上,不管你有没有目标值,都有助于寻求洞见,看到关系。

CDN —内容交付网络

原文:https://towardsdatascience.com/cnd-content-delivery-networks-b4e6998216cc?source=collection_archive---------3-----------------------

什么,为什么,怎么做?

CDN Connectivity

什么?

什么是 CDN?Well 是一个专注于传递内容的复杂网络。什么内容?你从一个流行的网络服务上下载的几乎所有内容都会通过 CDN 传送。例如,FaceBook、网飞和 YouTube 使用内容交付网络来服务数十亿从其服务器请求数据的用户。CDN 背后的主要思想是以改善空间(基于位置)和时间(基于访问时间)位置的方式分发内容。

举个例子 通常网飞会在世界各地不同的 ISP 为服务器用户安装冗余服务器。这些服务器被称为开放连接设备,根据访问权限在本地保存内容。任何到达网飞核心的新东西都会被推送到这些网站上,这样当地用户就能及时了解最新的展览目录。

An Open Connect Appliance

为什么?

想想网飞或 FaceBook 的故事。世界各地的大量用户不断请求内容,显然,由于许多原因,拥有一个庞大的服务器群不是一个解决方案。

  • 单点故障(SPOF)
  • 网络延迟
  • 成本(ISP 必须跳过许多 BG——连接不同 ISP 的边界网关。这要花费!!)
  • 需要故障安全冗余

此外,如果您检查 FaceBook 的 DOM(文档对象模型),您可以看到以下内容。

Content Loaded over CDN

FaceBook 的图像通常使用 Akamai CDN 渲染。这里 可以找到更多使用 Akamai 的人。

怎么会?

cdn 大多是相互对话的分布式系统。根据分布式系统的定义,整个系统对任何到达它的人来说都是一个端点。

简化过程

How CDN get updates

全局重定向器

在 cdn 上讨论全局重定向器的概念很重要。这些是 ISP 级别或区域级别的重定向,用于到达具有所请求内容的最近的服务器。

键入www.google.com,你将被重定向到 www.google.lk (因为我是在斯里兰卡写的)。这是全局重定向。

为什么打开 Connect Appliances

为什么ISP没有一个单独的服务器机架来缓存所有的东西,为什么cdn把他们自己的设备推到 ISP 的场所?如果互联网服务提供商知道你的请求,他们将不得不打开并通过互联网查看你请求的内容。现代网络实施 HTTPS,这使得这不可能。如果他们要打开你的请求,他们必须是一个中间人,这将再次在浏览器中失败,因为这将使 SSL 证书验证失败。因此 CDN 发布自己的设备,以更安全可靠的方式完成任务。

对于互联网服务提供商来说,这听起来可能是一项令人讨厌的任务,因为他们需要在自己的场所安装一些机顶盒。嗯不是!!这是因为拥有这样的设备将使他们能够减少通过 ISP 并到达 WWW 的请求数量。这是一个巨大的成本降低。最终 CDN 和 ISP 都很开心,我们也是。

感谢您的阅读。希望你学到了新东西。干杯!😃

CNN 在结构化数据中的应用——自动特征提取

原文:https://towardsdatascience.com/cnn-application-on-structured-data-automated-feature-extraction-8f2cd28d9a7e?source=collection_archive---------4-----------------------

Deep Learning based Automated Feature Engineering

作者:2018 年 8 月 13 日作者:酸溜溜的 Dey

T3【https://www.linkedin.com/in/sourish-dey-03420b1a/】T5

重要特征工程:

在我的上一篇文章中,我讨论了从有限的特性中创造丰富特性的重要性。事实上,机器学习/深度学习模型的真正质量来自广泛的特征工程,而不是建模技术本身。虽然特定的机器学习技术可能最适合特定的业务问题/数据集,但功能是任何建模项目的通用驱动因素/关键组件。从可用数据集中提取尽可能多的信息对于创建有效的解决方案至关重要。

在这篇文章中,我将讨论一种在行业中不太流行的特征工程方法(至少对于结构化数据而言),即使用 CNN(是的,你没听错,卷积神经网络)从结构化数据中生成特征,这是一种现代深度学习模型,广泛用于计算机视觉问题领域。我们还将在一个小数据上测试这种方法,以实际操作来创建特征——就好像它没有运行,它没有完成。

为什么要进行自动化特征工程:

传统上,分析师/数据科学家使用来自领域/业务知识的手动过程来创建特征。通常它被称为手工特征工程。虽然在数据科学中,我们不能否认领域知识的重要性,但这种类型的特征工程有一些缺点:

1.繁琐:手工特征工程可能是一个繁琐的过程。从父变量列表中可以创建多少个新特征?例如,从日期变量中,数据科学家可以创建 4 个新特征(月、年、小时和星期几)。然而,另一位数据科学家可以创建 5 个附加功能(周末指示器、节日指示器、X-mass 月指示器、季节性指数、一个月中的第几周等等)。与其他变量有关系/交互作用吗?因此,人工特征工程受到人类时间限制和想象力的限制:我们无法设想每一个可能有用的特征。

2.人类偏见的影响:通常,任何从事特定领域/建模项目的人,都会对某些特性产生深刻的偏见(尤其是如果这些特性是由分析师早先创建的话!),不管它是否给模型增加了价值。

自动化特征工程的力量来了。这里可以创造的特征实际上是无限的,没有任何人为的偏见。此外,这捕获了特征之间所有可能的复杂非线性交互。当然,我们可以在任何时间点应用降维/特征选择技术来去除冗余/零重要性特征。

商业问题和 CNN 的相关性

这里的业务目标是根据信用卡所有人的支付状态、余额和过去几个年份(预测期的最后 6 个月)监控的支付历史来预测信用违约的概率。为了简单起见,让我们忽略滞后期(通常在客户信息提取和数据上传到系统进行分析之间存在滞后)。这个业务问题和数据准备的动机来自https://medium . com/@ guai sang/credit-default-prediction-with-logistic-regression-b 5 BD 89 f 2799 f

我没有使用跨部门的组成部分(如性别、教育等。)中,并且只保留时间序列变量(余额、支付历史等。)来介绍一下 CNN 这个商业问题。本文的目标是在这种结构化数据上概念化和实现 CNN,并使用 CNN 模型从这种数据中生成 100 个新特征。你可以在这里得到的数据和全部代码。

关于数据:

数据集使用二元变量“下个月的默认付款”(Yes = 1,No = 0)作为响应变量。该集合中有 18 个特征(不包括 ID ):

  • 1:6 =X1 预测期最后一个月的还款情况;。。。;X6 =预测期前第 6 个月的还款情况。还款状态的衡量标准是:-1 =按时支付;1 =延迟一个月付款;2 =付款延迟两个月;。。。;8 =付款延迟八个月;9 =付款延迟 9 个月及以上。0 表示没有交易
  • X7 =参考时间范围最后一个月的账单金额;….X12 =参考时间范围之前第 6 个月的账单金额;
  • X13 =参考时间范围最后一个月的账单金额;….X18 =参考时间框架前第 6 个月的支付金额;

CNN 格式的数据表示:

深度学习方法,特别是 CNN,已经在基于图像的数据领域取得了很多成功,其中数据在规则的像素网格中提供了清晰的结构化拓扑。虽然关于卷积神经网络(CNN,或 ConvNet)的详细讨论超出了本文的范围,但让我们来看看是什么让 CNN 如此受欢迎?

深度学习方法,特别是 CNN,已经在基于图像的数据领域取得了很多成功,其中数据在规则的像素网格中提供了清晰的结构化拓扑。虽然关于 CNNConvNet 的详细讨论超出了本文的范围,但是让我们来看看是什么让 CNN 如此受欢迎?

缩减参数(参数共享):在卷积运算(层)时,每个输出值(图中卷积特征)不需要连接到前一层(图中图像)的每个神经元,只需要连接到当前应用卷积核的那些被称为感受野的神经元。卷积层的这种特性称为局部连通性。同样,相同的权重应用于卷积,直到参数的下一次更新。卷积层的这种特性称为参数共享。与通常的 ANN(人工神经网络)结构相比,这些大大减少了所需的参数数量,在 ANN 结构中,每一对输入/输出神经元之间都有一个连接。

移位/平移方差:表示当输入移位时,输出也移位,否则保持不变。具体到一幅图像,你可以把一个物体识别为一个物体,即使它的外观以某种方式变化

因此,简而言之,要对任何数据应用 CNN,需要以某种方式准备数据,以便存在局部模式,并且相同的局部模式在任何地方都是相关的。具体到我们的数据,我们有时间序列的事件范围(平衡,支付等。)对于单个客户,这使得数据充满了她本地的模式,因此这些参数可以在客户之间共享。我们只需要准备适合馈入个人客户的 CNN 特征矩阵的数据,与 d * w * n 的图像帧矩阵相同(d、w 和 n 是图像帧的深度、宽度和通道号)。

详细说明我们是否有 m 个特征的 N 个客户(这里是余额/付款等。)跨越 t 个时间范围(此处为第 1 个月、第 2 个月等。)对于 p 不同的交易(交易是不同的信用额度,如零售卡、抵押贷款等。).因此,单个客户的 m 个特征、t 个时间范围和 p 个交易类似于图像特征阵列的宽度、深度和通道数。准确地说,对于我们的数据,每个客户的维度将是 m * t * p,整个数据的维度将是 Nmt*p。现在,这使得原始结构化数据成为图像帧类型的数据,非常适合应用 CNN 通过卷积运算提取客户间复杂的非线性局部模式。

数据准备:

原始数据集由一张贸易-零售卡组成。为了使它更相关和更具挑战性,我为一个额外的交易——抵押贷款创建了虚拟数据集(将目标变量状态标记为原始数据)。数据比零售卡数据稀疏,值可能不是 100%符合逻辑。最终数据集( CreditDefault.csv )保存在这里

因此,我们有 30k 个不同的客户 id 和总共 60k 个观察值,前 30k 个观察值是零售卡的,接下来 30k 个是抵押贷款的。

包含数据准备代码的详细解决方案在https://github . com/nitsourish/CNN-automated-Feature-Extraction/blob/master/CNN _ Feature _ Extraction . ipynb。这是这个问题的棘手部分是准备格式(像图像格式)的数据,以便我们可以应用 CNN。准确地说,对于我们的数据,每个客户的维度将是 3(特征数量)* 6(时间范围)* 2(交易),并且将有 30000 个该维度的框架。因此,对于整个数据,它将是一个 30000 * 3(宽度)* 6(深度)* 2(通道数)的数组。所以这些数据对于训练一个卷积网络来说是完美的。

Pipeline- CNN Feature Extraction

准备好特定于渠道的数据后,我们可以看到维度:

shape of channel1(retail)data: (30000, 3, 6, 1)
shape of channel2(mortgage)data: (30000, 3, 6, 1)

在合并这两个阵列之后,数据适合于馈入 CNN 作为输入体,以提取具有非线性交互的复杂特征。

shape of input volume(layer)data: (30000, 3, 6, 2)

现在数据看起来像图像帧数据图像像数据(体积 362 的 30000 个图像帧)。现在,我们需要以一种热编码格式将目标变量(下个月的默认付款)映射到客户 ID。

X = np.concatenate((retail, mort),axis=3)Y = event_id[['default payment next month']].valuesY = to_categorical(Y,2)
In our data we have payment default rate is: 28.402671 percent

在数据中,我们有 28.40%的付款 _ 违约率。虽然事件发生率不是 50%,但我们可以说这是一个相当平衡的数据。所以不需要做任何重量校正

CNN 的特征提取

为了从 CNN 模型中提取特征,首先我们需要用最后的 sigmoid/logistic 密集层(这里是维度 2) w.r.t .目标变量来训练 CNN 网络。训练网络的目标是通过多次向前和向后迭代来识别网络的正确权重,最终尝试最小化二进制交叉熵(误分类成本)。这里我将使用 keras 框架,后端为 TensorFlow(tf)。对于我们的业务问题,AUC 是评估指标,我们将通过最大化每个时期的 AUC 值来进行优化(Keras 没有默认的 AUC 指标。但是,我们可以利用 tf 为 AUC 创建定制的评估函数。)

CNN 架构

在到达最后一个 sigmoid 输出层之前,我们用 4 个 conv 层(conv +激活+池化(可选))和 2 个 FC(全连接层)构建了以下 CNN。

我们利用早期停止来训练 epochs = 100 的模型,以防止过度拟合。使用我的 NVIDIA GTX GeForce 1060 GPU(val _ AUC = 0.8317)进行训练用时不到 10 分钟。

特征提取方法

现在,通过使用预训练的模型,我们可以直接将这些权重应用于数据,去除最后的 sigmoid/logistic 层(在这个问题中,直到 100 维的密集层)。我们可以用这一点来计算任何新数据的相同商业问题的这些特征。我们只需要前馈网络,它将直接映射最终权重来计算某个中间层的要素,而无需再次构建网络。这是一种迁移学习。基于我们对特征数量的要求,我们可以在任何具有期望维度的中间密集层提取特征。对于这个问题,我们将使用一个中间模型来提取特征,直到 CNN 的“特征密集”层。

*#Preparing Indermediate model-removing last sigmoid layer*
intermediate_layer_model = Model(inputs=model.input,outputs=model.get_layer('feature_dense').output)
intermediate_layer_model.summary()

输出层的维度是 100,所以如果我们预测用这个网络对一个新的数据用同样的输入维度,我们可以创建 100 个新的复杂特征。

*#predict to get featured data*
feauture_engg_data = intermediate_layer_model.predict(X)
feauture_engg_data = pd.DataFrame(feauture_engg_data)
print('feauture_engg_data shape:', feauture_engg_data.shape)
feauture_engg_data shape: (30000, 100)
  • 我们成功地捕捉了原始变量之间的 100 个复杂的相互作用。

对 feauture _ engg _ data 的进一步探讨

让我们偷偷看看这些特性是否有价值。尽管有一些更好的方法,但为了简单起见,让我们捕捉这些新特性与目标变量“下个月的违约付款”之间的一些二元关系。虽然对于分类目标变量相关性不是 100%正确的方法,但我们将计算所有新值与目标变量的相关性,作为变量的近似值,这对最终模型可能很重要。

*#Sorting correlation values in decsending order*
new_corrs = sorted(new_corrs, key = lambda x: abs(x[1]), reverse = True)
*#Let's see top 10 correlation values*
new_corrs[:10] 
[('PAY_1', 0.32479372847862253),
 ('PAY_2', 0.26355120167216467),
 ('PAY_3', 0.2352525137249163),
 ('feat_78', -0.22173805212223915),
 ('PAY_4', 0.21661363684242424),
 ('PAY_5', 0.20414891387616674),
 ('feat_86', -0.20047655459374053),
 ('feat_6', -0.19189993720885604),
 ('PAY_6', 0.1868663616535449),
 ('feat_3', -0.17394080015462873)]

我们可以看到 4 个新创建的变量(feat_78,feat_86,feat_6,feat_3)在与“下个月违约付款”的相关性(伪)方面排名前 10。虽然在此基础上没有什么具体的可以说这些变量的预测强度,但至少这些变量值得进一步研究。

我们还可以根据绝对幅度相关性来查看最高相关变量的 KDE(核密度估计)图。

强调 CNN 用于特征提取

现在关键的问题是为什么 CNN/深度学习方法只用于特征提取。为什么不用它作为分类器呢?有两个主要原因:

局部模式:我们在这个商业问题中使用的数据(适用于我们使用结构化数据的大多数场景),也包括横截面(静态)变量,在这里我们不会发现任何局部模式。所以我们不能用 CNN 对整个数据做分类器。当然,对于具有平移/平移不变性的数据,我们可以使用 CNN 作为最终分类器。

基础设施挑战:构建大规模工业数据并投入生产需要大量基础设施支持(GPU、AWS 等)。),这可能并不适用于每个组织。

模型运行中的延迟:即使有适当的基础设施,相当复杂的深度学习模型的前向传播也要比 XGBoost、RF、SVM 等高效分类器花费更长的时间。事实上,在某些需要超快的实时预测的应用中,最好的解决方案是使用自动技术(如 CNN 特征提取)提取特征,然后添加相对简单的分类器。

Automated Feature Extraction + Classifier

监管挑战:尽管对机器学习/人工智能有着巨大的关注,但在实施预测模型之前,特别是进入银行/保险/金融领域的组织必须通过内部/外部监管流程,这可能需要艰苦的劝说才能在生产系统中使用这些最新技术。相反,如果最终分类器是传统模型,则从建模方法的角度来看,可能不存在挑战。

改进和前进的道路:

作为现代人工智能深度学习大师,吴恩达准确地说,“……应用机器学习基本上是特征工程。”创建有意义的特征空间的重要性不能被夸大,并且自动化特征工程技术旨在帮助数据科学家解决特征创建的问题,从原始数据集无缝地构建成百上千的新特征。但是,目的不是取代数据科学家。相反,这将使她能够专注于机器学习管道中其他有价值的部分,如功能选择、探索新方法、将健壮的模型交付到生产中等。我们刚刚讨论了自动化特征工程的一种潜在方法。当然还有一些其他类似的技术。我喜欢在未来探索这些。同时渴望听到 CNN 在结构化数据(关系数据库)上的其他应用,在任何其他商业问题上的应用。

基于 CNN 的人脸检测器

原文:https://towardsdatascience.com/cnn-based-face-detector-from-dlib-c3696195e01c?source=collection_archive---------3-----------------------

Image Source: Google Images

如果你对任何类型的图像处理、计算机视觉或机器学习感兴趣,你很有可能在旅途中的某个地方遇到/使用过 dlib。

根据 dlib 的 github 页面介绍,dlib 是一个用 C++制作真实世界机器学习和数据分析应用的工具包。虽然这个库最初是用 C++编写的,但它有很好的、易于使用的 Python 绑定。

我主要使用 dlib 进行 面部检测面部标志检测 。dlib 中的正面人脸检测器效果真的很好。它很简单,开箱即用。

该检测器基于梯度方向直方图(HOG)线性 SVM。(解释这个检测器如何工作超出了这篇博文的范围。可能是改天讨论的话题)

虽然基于 HOG+SVM 的人脸检测器已经存在了一段时间,并聚集了大量的用户,但我不确定我们中有多少人注意到了 dlib 中基于 CNN(卷积神经网络)的人脸检测器。老实说,我没有。我是在浏览 dlib 的 github 资源库时偶然发现的。

我当时的想法是,

哇。是否优于现有的检测器?有多准确?它能全方位检测人脸吗?它能在实时视频上运行吗?

嗯,这就是这篇文章的内容。试图找出上述问题的答案。

如果你曾经在 dlib 中使用过基于 HOG 的人脸检测器,你可能知道它不会检测奇数角度的人脸。它应该是一个很好的"正面"人脸检测器,它确实是。

它可以检测到人脸,即使它们的正面并不十分突出。这对于正面人脸检测器来说非常有用。但是你只能期待这么多。

同时,基于 CNN 的检测器能够检测几乎所有角度的人脸。不幸的是,它不适合实时视频。它应该在 GPU 上执行。为了获得与基于 HOG 的检测器相同的速度,您可能需要运行强大的 Nvidia GPU。

然而,这不应该阻止我们在静止图像上尝试它。

在这篇文章的剩余部分,我将向你展示如何在图像上使用基于 CNN 的人脸检测器,并将结果与基于 HOG 的检测器和现成的 Python 代码进行比较。

让我们直接开始编码吧。

入门指南

让我们从导入必要的包开始。如果您尚未安装这些软件包,您可以通过在终端中键入以下命令来安装它们。

pip install opencv-python dlib argparse time

(argparse 和 time 更有可能预装在 Python 中)

如果您没有使用 Python 的虚拟环境,我强烈建议您开始使用它。需要起点的可以查看我之前的帖子

命令行参数

这个脚本需要两个命令行参数。

  • 输入图像
  • 模型重量

您可以通过在终端中键入以下命令来获取模型权重文件。

wget [http://arunponnusamy.com/files/mmod_human_face_detector.dat](http://arunponnusamy.com/files/mmod_human_face_detector.dat)

默认情况下,如果您没有提供任何特定的路径,代码会在当前目录中查找模型文件。

例如,您可以通过键入以下命令来运行

python cnn-face-detector-dlib.py -i input.jpg

(如果input.jpg模型权重文件都在与 python 脚本相同的当前目录中,这将起作用)

或者你可以通过输入,

python cnn-face-detector-dlib.py -i <path-to-image-input> -w <path-to-weights-file>

(python CNN-face-detector-dlib . py-I ~/Downloads/input . jpg-w ~/Downloads/mmod _ human _ face _ detector . dat)

( 我假设你已经安装了最新版本的 Python。必须是 3.0+)

初始化

读取提供的输入图像,并检查其类型是否为无。如果是,打印错误声明并退出程序。

初始化基于 HOG 和基于 CNN 的人脸检测器,我们将应用于输入图像。

对于基于 HOG 的,我们不需要提供任何文件来初始化。它是预先构建在 dlib 内部的。只需调用方法就足够了。

对于基于 CNN 的,我们需要提供权重文件来初始化。

应用猪脸检测

让我们在输入图像上应用检测器。

faces_hog = hog_face_detector(image, 1)

1 是对图像进行向上采样的次数。默认情况下,1 适用于大多数情况。(对图像进行上采样有助于检测较小的面部)

time.time()可以用来测量以秒为单位的执行时间。

一旦检测完成,我们可以在检测到的人脸上循环。要在检测到的人脸上绘制方框,我们需要向 OpenCV 提供(x,y) —左上角和(x+w,y+h) —右下角。

dlib 和 OpenCV 中的矩形格式有点不同。我们可以在这里使用 skimage 将 dlib 矩形对象直接叠加在图像上。但是当我们用 OpenCV 处理实时视频时,熟悉 dlib 和 OpenCV 之间的转换将会很有帮助。

**cv2.rectangle(image, (x,y), (x+w,y+h), (0,255,0), 2)**

上面的线将在输入图像上检测到的人脸上绘制一个矩形。(0,255,0)代表 BGR 顺序中盒子的颜色(本例中为绿色)。2 代表线条的粗细

应用 CNN 人脸检测

除了检测器返回矩形对象之外,这个过程与前面的检测器几乎相同。让我们用红色来区分 CNN 检测到的人脸。

显示结果

为了区分 HOG 和 CNN 检测器的检测,让我们在图像的右上角写下哪种颜色是哪种颜色。

cv2.imshow()将显示运行脚本时的输出图像。

cv2.waitKey()指定显示窗口关闭前应等待的时间。例如cv2.waitKey(500)将显示 500 毫秒(0.5 秒)的窗口。如果你不传递任何数字,它会一直等到你按下任何键。

cv2.imwrite()将输出图像保存到磁盘。

一旦我们完成了显示,释放所有的窗口是一个好的习惯。

完整的代码可在这里获得。

执行时间

给你一个执行时间的概念,对于一个 620x420 的图像, HOG 花费大约 0.2 秒,而 CNN 花费大约 3.3 秒在 CPU 上( Intel i5 双核 1.8GHz )。

Execution time on CPU (in seconds)

根据您的硬件设置和映像的大小,确切的数量可能会有所不同。底线是 HOG 需要不到一秒钟,而 CNN 只需要几秒钟。

检测奇数角度的人脸

重要的部分来了。

基于 CNN 的检测器可以检测到基于 HOG 的检测器可能检测不到的奇数角度的人脸吗?

嗯,答案是“ 差不多 ”。(我还没有经过严格的测试来给出一个自信的“是”。但是据我测试,它对非正面的图像非常有效。

让我们看一些例子,其中基于 HOG 的检测器失败,但 CNN 能够检测。

****

这样的例子不胜枚举。

这并不是说基于 HOG 的检测器对非正面图像完全不起作用。事实上,它确实检测到一些非正面图像,如下图所示。

All the images above are taken from Google Images. I do not own the copyright.

摘要

在这篇文章中,我们研究了 dlib 的基于 CNN 的人脸检测器,并与广泛使用的基于 HOG+SVM 的人脸检测器进行了比较。

我们观察到,基于 CNN 的检测器对于非正面人脸在奇数角度下工作得非常好,而基于 HOG 的检测器很难工作。

不幸的是,基于 CNN 的检测器计算量很大,目前不适合实时视频。如果您已经注意到检测器函数调用(dlib.cnn_face_detection_model_v1()),它显示 v1 是版本 1。这意味着作者很有可能会推出轻量级的、可用于实时应用程序的下一个版本。

让我们期待 dlib 下一个版本中的轻量级版本。

好了,暂时就这些了。欢迎在下面的评论中分享你的想法,或者你可以在 twitter 上联系我,电话:@ ponnum Samy _ arun

如果你对这篇文章感兴趣,你可以订阅我的博客来获得新文章上线的通知。(别担心,我每个月只发表一两篇文章)

干杯。

更新:

如果你关心实时性能,检查一下 cvlib 中的人脸检测器。它可以检测(几乎)所有角度的人脸,并能够处理实时输入。

Udacity 驾驶模拟器中的 CNN 模型比较

原文:https://towardsdatascience.com/cnn-model-comparison-in-udacitys-driving-simulator-9261de09b45?source=collection_archive---------0-----------------------

对于 Udacity 的自动驾驶汽车 Nanodegree 项目 3,他们创建了一个驾驶模拟器,可用于训练和测试自动驾驶模型。我使用模拟器中车辆的前向图像和转向角度,训练并比较了两个架构差异很大的卷积神经网络(CNN)模型。结果表明,对于这种类型的任务,CNN 架构的选择不如所使用的数据和增强技术重要。在结果中可以看到模拟器中模型的并排视频。

方法

我对这个项目的一般方法是使用 Udacity 提供的训练数据和尽可能多的必要的数据增强技术来产生可以在模拟器中成功绕过不同轨道的模型。我尝试了两种不同的 CNN 模型:第一种是他们论文中公认的 NVIDIA 模型:

https://images . NVIDIA . com/content/tegra/automotive/images/2016/solutions/pdf/end-to-end-dl-using-px . pdf

第二个是我为 Udacity 的开源挑战#2“使用深度学习预测转向角度”开发的类似模型:

https://github . com/Chris gundling/自驾车/树/主/转向模型/社区模型/cg23

这些模型非常不同,因为 NVIDIA 只使用了大约 25 万个参数,而我尝试的原始 VGG 风格模型有近 3400 万个参数。

我试验了各种数据预处理技术、7 种不同的数据扩充方法,并改变了我测试的两个模型中每一个的压差。最后我发现,虽然 VGG 风格的模型驾驶稍微平稳,但需要更多的超参数调整。NVIDIA 的架构在推广到测试轨道(Track2)方面做得更好,付出的努力更少。最终的 NVIDIA 模型没有使用 dropout,并且能够在轨道 1 和 2 上行驶。我在 CPU 上的模拟器中测试时,遇到了较大的 VGG 风格模型的转向延迟问题。我最终将这个模型的图像尺寸从 128X128X3 缩小到 64X64X3,并将全连接层的尺寸减半。这使得 VGG 风格的模型可以在赛道 1 和 2 上行驶。

承认

我要感谢 Vivek Yadav 在这个项目上的精彩帖子。实现的一些数据增强技术是他在这篇文章中描述的想法:

https://chatbotslife . com/using-augmentation-to-mimic-human-driving-496 b 569760 a9 # . yget 03 t5g

我还要感谢 Udacity 的 Yousuf Fauzan 对旋转透视变换的实现。我在“线外”活动中遇到了优素福,他在 Udacity 的挑战#2 中运用了这一技术。该脚本使用旋转矩阵对图像进行不同程度的透视变换。

数据探索

Udacity 提供的数据由 8036 个中心、左侧和右侧组成。jpg 图片,总数据量为 24109 个例子(只有 323 MB 的数据!).这些训练图像都来自轨道 1。这些图像宽 320×高 160。下面的示例显示了从汽车上以一个时间步长拍摄的左/中/右图像。

Left, Center and Right Camera Images Respectively from the Simulator Vehicle on Track 1

Udacity 数据集驾驶日志中提供的转向角绘制如下。转向角以 1/25 的因子进行预缩放,因此它们在-1 和 1 之间(模拟器产生的最大/最小转向角为+/- 25 度)。

Udacity Provided Training Data

我知道模型训练需要一个评估指标,所以我分离出 480 个中心摄像机图像和它们对应的转向角度,用于验证集。这是一个比我通常使用的验证集更小的验证集,但是我不想放弃太多的训练数据。我考虑实现 k-fold 交叉验证来开发一个更好的验证误差度量,但是我发现单个验证集与实际驾驶能力相当一致。我没有使用专门的“测试集”来计算均方根误差,而是将第 2 轨的性能作为我的测试集。

数据预处理

我密切关注了关于收集培训数据的 Slack 的讨论。似乎很多人很难只用他们的电脑键盘来收集“平稳”的驾驶数据。Udacity 的数据在一定程度上解决了这个问题,但基于使用 Udacity 挑战#2 中真实人类转向数据的经验,所提供的模拟器转向数据仍然看起来更像是阶跃。

指数平滑

我通过对驾驶训练数据应用指数平滑来解决这个问题。指数平滑(布朗的方法)有助于产生更平滑的转向过渡,但也会截断和移动数据。我应用了一个缩放比例来恢复一些转向幅度,并将数据移动了几个时间步长,这样转向就不会被延迟。对于前 1200 个训练示例,可以在下面看到指数平滑的结果。

Exponential Smoothing of Udacity Steering Data

正常化

我使用等式(x-128)/128 将所有图像像素值标准化。这会将值规范化为介于-1 和 1 之间。我这样做是为了训练数据、验证数据,并在模拟器驾驶脚本中实现它来测试模型。

裁剪

在增强后,我从每张图像中剪掉了底部的 20 个像素和顶部的 40 个像素。这从图像中移除了汽车的前部和地平线以上的大部分天空。

调整规模

对于 NVIDIA 型号,我与他们的方法保持一致,使用高度为 66 像素、宽度为 200 像素的图像。对于 VGG 风格的模型,我使用了 64 高 64 宽的图片来缩小来自 Udacity 挑战#2 的原始模型。

数据增强

使用了七种不同的增强技术来增加模型在训练期间可以看到的图像数量。这大大降低了模型过度拟合数据的趋势。

增量的另一个主要好处是它们可以模拟恢复。视点变换、图像移位和使用左/右图像都添加了模拟汽车恢复到中心的训练数据,而实际上不必收集任何恢复数据。使用定制的生成器/产量方法在运行中执行扩增。实施的数据扩充技术如下:

  1. 透视/视点变换 —与 NVIDIA 论文中描述的类似,旋转透视变换应用于图像。我必须对透视变换的转向角度调整做一些调整,因为我发现一对一的透视变换角度对转向角度调整太大了。我决定在-80 到 80 度之间均匀地旋转图像透视。然后,我将视角除以 200,以调整转向角度。这提供了+/- 0.4 单位或 10 度的最大/最小转向角调节。
  2. 图像翻转 —由于训练数据中的左转弯和右转弯不均匀,因此图像翻转对于模型泛化到轨迹 2 非常重要。当图像翻转时,我也翻转了转向角的符号。
  3. 左/右摄像机图像 —我使用了来自汽车的左/右摄像机图像,这立即使训练数据的大小增加了三倍。在仔细检查左/右图像并寻找中心图像的共同特征后,我估计左/右图像从中心摄像机水平偏移了大约 60 个像素。基于这些信息,我为这些左/右图像选择了+/- 0.25 单位或+/- 6.25 度的转向角校正。
  4. —我对图像进行了水平和垂直移动。我的最大/最小水平和垂直位移是每个方向 40 像素。我在模型训练时调整了这个值。考虑到我估计左/右图像会偏移 60 个像素,我对最大水平偏移应用了稍微小一点的转向角校正。垂直移动没有转向角校正。
  5. 图像亮度 —我通过转换到 HSV 色彩空间和将 V 像素值从 0.5 缩放到 1.1 来调整图像的亮度。这主要是为了帮助推广到轨迹 2,那里的图像通常更暗。
  6. 图像模糊 —我不确定这种技术对模拟器有多大用处,但这种技术应该有助于模型在使用更多“真实世界”类型的数据时进行归纳,这些数据有时会出现模糊。我使用了可变高斯平滑来模糊图像。
  7. ***图像旋转***——与透视变换不同,我对图像进行了小旋转,以模拟相机的抖动。同样,不确定这对模拟器有多大用处,但对自动驾驶汽车上的真实摄像头会有用。

对于视点变换、图像偏移和左/右图像,我还尝试实现了基于速度的转向角校正。我的直觉是,在更高的速度下,转向校正应该更小或更平缓。我惊讶地发现,我不能让这个工作,以及有一个恒定的转向角校正。随着进一步的调整和对左/右相机图像位置的更好的了解,我认为这个方法会起作用。

基于速度的转向调整是通过定义汽车返回中心的 2 秒响应时间来实现的。随着车速的增加,在 2 秒钟内返回中心所需的转向角减小。下图显示了转向角校正的计算方法:

Speed Based Steering Adjustment

数据生成程序

所实现的数据生成器在左/中/右图像之间随机选择,并且还随机选择要应用的增强技术。我发现仅提供增强的训练数据不如用非增强的原始图像和增强的图像的组合来训练模型有效。

首先用较大的转弯训练模型,然后让较小转弯的数据慢慢漏入训练中。这个想法直接归功于其他几个在 Medium 上发布这个想法的学生。如果该模型最初是用低转向角训练的,它将偏向于更直的驾驶,我发现它在最尖锐的弯道中表现不佳。使用数据生成器,下图显示了数据生成器在训练运行期间为前 30 个训练示例生成的图像和增强选项。这些图像已经被裁剪和调整大小。图像标题如下所示:

  • ang:图像的转向角度标签
  • 凸轮:相机选择(左/中/右)
  • 8 月:1 是不增加,2 是增加
  • opt:数据扩充选项为: 1。翻转、抖动、模糊、亮度2。移动图像和 3。旋转视点变换

Image Augmentation Examples

模型设置和超级参数

我的目标是训练这两个模型中的每一个。NVIDIA type 和 2。具有尽可能多的相似超参数的 VGG 类型。我使用以下参数来训练这两个模型。

  • 最大历元数— 8 (5 或 6 个历元的训练通常为 NVIDIA 提供最佳模型,而 VGG 风格只有 1-3 个历元)
  • 每个时期的样本数— 23040
  • 批量大小— 64
  • 优化器—学习率为 1e-4 的 Adam
  • 激活—VGG 风格的 Relu 和 NVIDIA 型号的 elu

在 Keras 中实现的 NVIDIA 模型如下所示:

**# Layer 1x = Convolution2D(24, 5, 5, activation=’elu’, subsample=(2, 2), border_mode=’valid’, init=’he_normal’)(img_input)# Layer 2x = Convolution2D(36, 5, 5, activation=’elu’, subsample=(2, 2), border_mode=’valid’, init=’he_normal’)(x)# Layer 3x = Convolution2D(48, 5, 5, activation=’elu’, subsample=(2, 2), border_mode=’valid’, init=’he_normal’)(x)# Layer 4x = Convolution2D(64, 3, 3, activation=’elu’, subsample=(1, 1), border_mode=’valid’, init=’he_normal’)(x)# Layer 5x = Convolution2D(64, 3, 3, activation=’elu’, subsample=(1, 1), border_mode=’valid’, init=’he_normal’)(x)# Flatteny = Flatten()(x)# FC 1y = Dense(100, activation=’elu’, init=’he_normal’)(y)# FC 2y = Dense(50, activation=’elu’, init=’he_normal’)(y)# FC 3y = Dense(10, activation=’elu’, init=’he_normal’)(y)# Output Layery = Dense(1, init=’he_normal’)(y)model = Model(input=img_input, output=y)model.compile(optimizer=Adam(lr=1e-4), loss = ‘mse’)**

模型建筑

这两个模型的模型架构如下所示。如简介中所述,这些模型的主要调整参数是压差。对于 NVIDIA 型号,令人有些惊讶的是,该型号在轨道 1 和 2 上都表现最佳,没有掉线。任何掉线都会导致赛车在弯道中转向不够有力。对于 VGG 型模型,最后一个 conv 层和全连接层中的一些丢失提高了性能。

NVIDIA 型号结构和参数

这使得每个图像向前传递 0.6 MB,向后传递 1.2 MB。使用 64 的批处理大小,在向后传递期间最大内存使用量将是 75 MB。

VGG 型号结构及参数

这使得每个图像向前传递 1.2 MB(约 0.3MB * 4 字节),向后传递 2.4 MB。使用 64 的批处理大小,在向后传递期间最大内存使用量将是 150 MB。将结构和参数与 NVIDIA 的模型进行比较,在近 430 万个参数中,该模型的参数明显多于 NVIDIA 的。

结果

以下视频显示了路线 1 和路线 2 的两种型号的并排比较。虽然 VGG 风格的车型似乎驾驶稍微顺畅,但英伟达的车型在赛道 2 上表现更好。我在使用 VGG 风格模型过度拟合轨道 1 时遇到了麻烦,驾驶行为高度依赖于模型训练的下降和时代数。

以 0.2 节气门开度在轨道 1 上行驶

Track 1 Driving — NVIDIA Model on Left and VGG Style Model on Right

在 0.3 节气门开度的轨道 2 上行驶

Track 2 Driving — NVIDIA Model on Left and VGG Style Model on Right

结论

自从 Udacity 首次发布 Nanodegree Term 1 项目以来,我最期待的就是参与这个项目。由于在道路上收集高质量和高数量的真实世界数据存在困难,因此能够在模拟器中用看似无限的数据训练这些模型可能会在自动驾驶方面取得重大突破。正如在这个项目中所看到的,即使使用相对少量的数据和相当简单的 CNN 模型,车辆也能够成功地通过这两个过程。

我期待着继续这项工作,并一直致力于实施 RNN/LSTM 和强化学习方法来控制转向,油门和刹车。我也很好奇使用真实世界和模拟器数据的组合来训练这些模型,以了解如何在模拟器中训练的模型可以推广到真实世界,反之亦然。

硬件/测试设置

我使用 Udacity 的 CarND AWS AMI 的修改版和 g 2.2x 大 GPU 来训练这些模型,并在我带 CPU 的 Macbook Pro 笔记本电脑上测试这些模型。模拟器被设置为“最快”的设置,屏幕分辨率为 640 X 480。

密码

这个项目的所有代码都是用 Python 实现的,可以在我的 github 档案中找到:

**【https://github.com/chrisgundling **

卷积神经网络— I

原文:https://towardsdatascience.com/cnn-part-i-9ec412a14cb1?source=collection_archive---------1-----------------------

在我们进入完整的卷积神经网络之前,让我们先了解基本的底层概念,然后在此基础上进行构建。

本帖将解释以下内容:

  • 卷积概念
  • 卷积神经网络
  • 交错回旋

卷积概念

对于那些上过数字信号/图像处理课程的人来说,他们应该对协解的概念比较熟悉。对于我们其他人,让我们快速浏览一下这个概念,这样我们就可以深入到实际的cnn实现中。

如果你有一个城市的图像,有很多如下的建筑,你想从图像中提取所有的边缘,你会怎么做?

Fig 1. Edge detection on an image using convolution. Note how all the edges separating different colours and brightness levels have been identified

每当需要修改一个信号以从中提取一组所需的特征时,该过程被称为滤波。现在,为了进行滤波,需要另一组信号,我们以某种方式将其施加/应用于原始信号 S,称为滤波器 (F)。这些滤镜也可以称为遮罩,因为它们帮助我们“遮罩”除了我们想要的图像特征之外的所有图像特征!

现在,所有的遮罩都可以显示出图像所需的效果,如果它们以下面动画演示的方式与图像像素卷积的话。

Fig 2. GIF demonstrating result of filter convolution on an image. Source

为了更好地理解卷积,请参考这篇文章

卷积神经网络

Fig 3. Architecture of LeNet a Convolutional Neural Network here for digits recognition. Each plane is a feature map ie a set of units whose weights are constrained to be identical. Source

上图来自[Prof Yann Lecun](http://yann.lecun.com/)的原始论文,展示了卷积网络中的所有基本组件和数据流。

以可量化的形式来说,每个 CNN 都有以下组件/层:

  • 输入图像
  • 卷积层
  • 池层(最大池或平均池)
  • 变平
  • 完全连接层(默认神经网络)

我们将在随后的文章中更深入地探讨以上每一层的细节。

交错回旋

当我们处理非常大的图像的卷积时,并不总是需要对图像的每个像素进行卷积。因此,我们可以将后续卷积设置为在垂直轴或水平轴上移动一个以上的像素。

Fig 4. Effect of strided convolutions on an image dimensions

在随后的回旋中的这种移动被称为stride,因此命名为跨步回旋。

如果我们有一个尺寸为n x n的图像,带有一个填充p,它与尺寸为f x f的滤波器进行卷积,步长为s,那么输出尺寸可以使用下面的通用公式来确定:

Fig 5. Equation governing the resultant image/signal dimension after applying a filter (f x f) with padding (p) and stride (s)

PS:在数学卷积运算中,我们翻转一个被卷积的信号,就像在镜子里看到的一样。我们上面使用的运算实际上是互相关,但一般在深度学习卷积中是用于它的术语!

结论

在这篇文章中,我们已经理解了帮助我们建立整个卷积神经网络的基本概念。我们讲述了卷积如何使用不同的过滤器或遮罩处理图像数据。此外,我们还谈到了 CNN 的各种构件,以及步长卷积如何影响图像/数据的维度。

在下一篇文章中,我将更详细地介绍卷积,以及它如何应用于具有许多过滤器的体积。

原载于 2017 年 11 月 10 日mandroid 6 . github . io

在推特上关注我:https://twitter.com/mandroid_6

查看我关于机器学习和深度学习的其他帖子:https://medium.com/@razzormandar

Code2Pix —面向图形用户界面的深度学习编译器

原文:https://towardsdatascience.com/code2pix-deep-learning-compiler-for-graphical-user-interfaces-1256c346950b?source=collection_archive---------7-----------------------

你好!我叫诺亚·冈多拉,是加州大学伯克利分校的二年级学生。我现在展示的是加州大学伯克利分校统计学本科生协会( SUSA )与 Uizard 合作的原创研究。

在 SUSA,我带领另外 4 名加州大学伯克利分校的本科生在 2018 年春季学期开展了这个项目。接下来的作品是我们小组许多看不见的工作、失败和乐趣的高潮。我们希望你会喜欢阅读我们的研究!

这篇博客分为 6 个部分,还有一个简短的致谢部分。

TL;DR —摘要

我们为从文本描述生成图形用户界面(GUI)的问题提供了深度学习解决方案。这项研究可用于提高 pix 2 代码的准确性,以及从图形用户界面生成代码的未来模型(相反的任务);这个问题在人机交互文献中被称为用户界面逆向工程。此外,中间工作暗示了跨多个平台工作的单一文本到 GUI 编译器的可能性。

1 —简介

当我第一次读到 Pix2Code paper 的时候,我震惊了。托尼·贝尔特拉梅利(Tony Beltramelli)一个人提出了深度学习的新应用,实现了一种方法,并将其开源。该论文提出了一种深度学习模型,能够将图形用户界面的草图转化为实际代码。这对我来说似乎是革命性的。我想这是我看到的事情之一,突然我明白了为什么这么多人对机器学习感兴趣——我真的觉得这是“人工智能”

Pix2Code 是机器学习工程的一个非常了不起的壮举。为了改善它,托尼建议试验一个补充项目。称为 Code2Pix,它的作用与 Pix2Code 相反。Pix2Code 来自 GUI,并把它们转换成特定领域语言(DSL)的文本描述。Code2Pix 接受 DSL 中的文本描述并生成 GUI。因此,Code2Pix 实际上是一个能够呈现接口的深度学习“编译器”。为了避免与真正的编译器混淆,我们将它称为深度学习渲染器

Simplified visual description of code2pix’s inputs and outputs. This particular example is from the iOS dataset provided in the original pix2code repo.

本着 Pix2Code 的精神,我们正在发布与这个项目相关的所有代码。我们希望我们能激励其他工程师参与这个项目,并通过对社区的贡献来帮助这个领域向前发展。

2 —为什么选择 Code2Pix?

我们开始通过建立一个生成式对抗性神经网络(GAN)来改进 Tony 的模型 Pix2Code。最近在这一领域的 工作表明,相互竞争的神经网络(GANs)可以为图像提供比标准模型更好的字幕。这就需要一个 发生器 模型和一个 鉴别器 模型来工作。Pix2Code 可用于生成用户界面的代码(DSL ),我们可以使用 Code2Pix 来查看字幕与真实图像的接近程度。Pix2Code 是生成器,Code2Pix 是鉴别器。它们一起可以形成一个 GAN,它能够比 Pix2Code 本身更准确地为 GUI 生成代码。

Code2Pix 的工作与任何普通的渲染器一样。事实上,任何处理用户界面代码的渲染器都是“代码到像素”系统。但是 Code2Pix 不一样,因为它是可微的。这意味着我们可以使用我们的深度学习渲染器 Code2Pix,通过其各层传播错误信号来训练其他深度学习模型。这对于标准渲染器是不可能的。

Pix2Code GAN architecture. This is an example of how Code2Pix could be used in conjunction with Pix2Code to improve Pix2Code accuracy in subsequent research.

3 —解决代码 2 修复

这是领导这个项目最有趣也是最令人羞愧的部分。我们最初的方法花了我们 2-3 个月的时间来构建和迭代,但是最后一步没有使用我们之前的任何工作。最终的工作模型被证明是一个非常简单,几乎是幼稚的方法。尽管如此,我认为我们的过程值得分享,出于教育目的,以及展示一个有趣的和相对较新的应用程序,使用深度学习进行跨平台用户界面设计。此外,我们相信这个项目是一个很好的例子,简单优雅的解决方案往往比复杂的解决方案表现得更好。

方法

把代码变成图片的问题可以分解成三块。首先,我们需要使用 DSL 来捕获用户界面,以降低问题的复杂性,并使使用深度学习系统变得可行。其次,我们将为每个数据集创建一个自动编码器。第三,我们将使用 Code2Pix 模型中自动编码器的解码器部分,将编码空间转换为呈现 GUI 的像素。

Our approach to building code2pix. Separate the model into two distinct portions. One for handling the textual information, and the other for constructing the GUI. We refer to these respectively as the “token encoder” and the “image decoder.”

幸运的是,Tony 已经创建了一种领域特定语言(在这种情况下,DSL 可以被视为用户界面的伪代码),可以将编译为每个数据集的实际代码(即原生 iOS、原生 Android、web HTML/CSS)。Pix2Code 和 Code2Pix 使用相同的领域特定语言,捕捉每个数据集的基本特性。这解决了我们的第一步。如果你想知道这是怎么做到的,看看这里。

我们的下一步是训练自动编码器,目标是使用自动编码器模型的一部分作为 Code2Pix 中的“图像解码器”。

自动编码器

这些是深度学习中的特殊模型,在数据集上训练,作为解决该数据上的任务的先驱。自动编码器学习将数据压缩为低维编码,然后还学习将编码解压缩为原始数据。它们是了解数据重要特征的好方法。编码器部分通常会被导入到其他深度学习架构中,以传输它学习编码的特征。这就是所谓的迁移学习。我们对解码器部分特别感兴趣,因为它学习解释抽象的有意义的编码,并将它们转换成用户界面的图片。

If we train an autoencoder that can compress and decompress GUIs, then we get a free “image decoder” to use in code2pix.

我们尝试了标准的自动编码器架构来解决这一任务,但学到的解码器在解决我们的任务时不是很有用。因此,我们设计了一个新的架构:一个多头模型来同时解决所有三个数据集(Android、iOS 和 Web)的任务。在这个被称为“Hydra”的模型中,解释图像编码的解码器依赖于图像来自的数据集。例如,要通过模型传递 Android 图像,我们将手动选择通过 Android 解码器头来获得最终结果。

The specific autoencoder design we used shared the same image encoder between all three image decoders. This ended up being a very efficient model, and produced generalizable image decoders.

我们在 Code2Pix 模型设计中使用解码器头。为了查看编码器和解码器头的具体底层架构,我们将读者引向我们的 Github repo

走向通用的跨平台用户界面

我们的 Hydra autoencoder 学习了嵌入技术,这使我们相信系统可以编译通用用户界面。根据我们的 autoencoder,下面的图片是 3 张图片在不同平台上的样子。例如,最左边的一栏是 Android GUI 在 iOS 和 Web 上的样子。

Three different images in three columns being interpreted similarly between each platform. The left column is an Android image, middle is an iOS image, and the right column is a Web image. Each row represents what that image would look like on a different platform.

左右两栏显示出惊人的结构相似度。在左栏中,iOS 头看到的 Android 按钮为橙色框,web 头看到的按钮与绿色按钮相同。在右栏中,我们可以看到 Android 和 iOS head 都捕捉到了 Web GUI 的基本分段结构,使用按钮和滑块的组合来复制 Web 的 div 元素。

每个图像在解释到新平台时仍然保留结构的事实给了人们希望,有一天可能会有一个深度学习编译器,能够在 Android、iOS 和 Web 后端之间无缝翻译用户界面代码。这是一个非常简单、不完善的模型,但是随着时间和经验的增加,它可能会产生更复杂的结果。这些结果表明,由自动编码器学习的编码空间具有足够的结构,在未来的应用中是有用的。

为了验证嵌入空间的结构,我们查询模型以在不同的图像之间进行插值。借鉴著名的“国王男人+女人=王后” 的论文,我们做了自己的“用户界面代数”

“A is to B as C is to D.” Here we compute B — A + C = D in order to obtain the result above. The main difference between B and A is the toggle in the second row. By adding B — A to C, we can see D now has a button in the second row.

我们注意到,并不是所有的图像组合都像上面的例子一样清晰。然而,这只是更大目标的第一步:真正的用户界面代数和跨 Android、iOS 和 Web 界面工作的 GUI 编译器。

More Eyecandy: Using the Web decoder to translate between two different Web GUIs.

Code2Pix 模型设计

在分析了自动编码器的编码之后,我们准备进入最后一步。我们希望将模型设计过程构建为一个编码器-解码器的动态过程。必须有一部分模型来解释代码标记,并且它必须与一个模型进行通信,该模型再次将编码解码成实际的图片。

我们一开始试图从 Pix2Code 模型中导入预训练的 LSTMs(深度学习层,非常擅长学习顺序数据),但这并没有显示出任何前景。然后我们对卷积层进行了实验,最后使用 1D 卷积层对来自特定领域语言的代码标记进行编码。我们通过将序列的每个 DSL 令牌转换为一个 hot 表示来训练我们的模型,然后将它们连接起来以创建一个矩阵,然后我们可以将这个矩阵提供给 Code2Pix 模型。我们将填充序列归零,这样它们都具有相同的长度。

Final architecture for the Code2Pix model.

4-代码 2 修复结果

该模型训练速度非常快,并且为所有三个图像产生令人惊讶的干净输出图像。为单个数据集训练 Code2Pix 大约需要 55 个历元,在两个英伟达 GTX 1080 上大约需要 30 分钟。有趣的是,该模型在 iOS 和 Web 数据集上表现同样出色,但难以为 Android 数据集生成细粒度的细节。

这个最终架构的一个令人惊讶的结果是,预训练的图像解码器根本没有帮助训练 Code2Pix 模型。事实上,在没有预训练重量的情况下训练模型和在有预训练重量的情况下训练一样快。一个自然的结论是,对于这个任务和数据集,这是一个非常稳定的模型架构。下一个假设是,像素到像素问题的编码向量空间实际上不同于文本到像素问题的编码向量空间。因此,在 GUI 到 GUI 问题上使用预先训练的权重并不能为模型提供有价值的信息来更快地学习 DSL 到 GUI 问题。

以下图片是从我们的验证数据集中选择的示例。

(Web) Corresponding code: header { btn-inactive btn-active btn-inactive btn-inactive btn-inactive } row { quadruple { small-title text btn-green } quadruple { small-title text btn-red } quadruple { small-title text btn-red } quadruple { small-title text btn-orange } } row { single { small-title text btn-green } } row { double { small-title text btn-red } double { small-title text btn-green } }

(Android) Corresponding code: stack { row { radio } row { label slider label } } footer { btn-notifications btn-home btn-notifications btn-home }

我们看到这个的时候真的很开心。为这个模型给出的文本描述相对复杂,图片也相对复杂——但是模型抓住了这一点。鉴于 Code2Pix 模型是如此简单,它能够达到如此高的分辨率这一事实是非常令人惊讶的。

Code2Pix 在生成 Android 图像的清晰分辨率图像时遇到了最大的麻烦。Android 图像可能比其他 GUI 有更复杂的细节,比如滑块上的点。

(iOS) Corresponding code: stack { row { label btn-add } row { label btn-add } row { label slider label } row { label slider label } row { label switch } row { label slider label } row { label slider label } } footer { btn-download btn-search btn-search }

iOS 的图像比 Android 的干净得多。此外,iOS Code2Pix 模型能够处理更复杂的文本描述。

5 —限制

我们的深度学习渲染器的表达能力受到数据集和领域特定语言的限制。DSL 必须与合成数据集一起手工制作,以扩展深度学习编译器可以支持的 UI 元素的数量和种类。此外,深度学习编译器生成的图像不如真实图像清晰。我认为这与模型学习在一些看起来模糊的 UI 元素上“对冲赌注”有关,比如滑块。有可能这只是一个假象,可以通过一些微调或更多数据来消除。

但问题是,这些实验只是开始。从事这些项目感觉就像学习如何进行化学实验。现在,我们只是把氢和氧结合起来制造水,但是我们还有很长的路要走。我们甚至还没有开始研究火箭燃料。如果说 Uizard 的演示向我们展示了什么,那就是未来有太多的东西等待着我们。

6-回顾:犯过的错误,吸取的教训

在这个项目中,我们重新认识到了基础知识的重要性。在解决 Code2Pix 的过程中,我们进行了自底向上的开发,构建了最终在最终模型中不一定需要的自动编码器。我们可以从构建 Code2Pix 的基线模型开始。这可以加速我们的模型开发过程。

此外,我个人犯的最大错误是一个技术上的失误。在开发最终的 Code2Pix 模型时,我未能验证数据是否被正确加载。结果是(x,y)对在加载时不匹配。这花费了我们 2-3 周的宝贵模型设计和应用程序优化时间。我学到了什么?对数据管道流程进行单元测试,或使用其他验证流程。例如,我可以只导入 Pix2Code 的数据管道过程。相反,我们的研究代码有 3-4 种不同的数据加载方式,不幸的是只有 2-3 种有效。不要再犯同样的错误。

总的来说,我学到的更重要的经验教训是那些难以表达的软经验教训,它们现在已经融入了我的职业道德。调整我的沟通技巧,减少微观管理,有时不均衡的信任发展,以及控制我在团队会议中的冗长设置。这些都是有趣的课程!

承认

非常感谢我在 SUSA 的团队对我的领导能力的信任,以及为此投入的大量工作。感谢 Samyak Parajuli、Luke Dai、Ajay Raj、Aismit Das、Dennis Yang 和 jap jot Singh——感谢你们,与你们一起工作充满了乐趣。

没有 Tony Beltramelli 的大力指导和指导,我们不可能完成这个项目。感谢托尼对我们的指导!

感谢您的阅读!如果您对我们的研究有更多问题,请随时发送电子邮件至noah.gundotra@berkeley.edu。如果你有兴趣在 Uizard 工作,看看他们的职业页面

整理您的工作流程

原文:https://towardsdatascience.com/codify-your-workflow-377f5f8bf4c3?source=collection_archive---------14-----------------------

设计和数据科学

从长远来看,对我的工作流程进行编码可以节省时间和精力,但这也要求我首先明确我的工作流程是什么。

编辑:我最近重构了这篇文章的代码,并将其发布为python 包。

我想我和大多数数据科学家一样,在项目中我倾向于重复做某些事情:我检查某些模式,或者我绘制某些东西,或者我试图理解某些关系。有时是因为我犯了足够多的错误,所以我发现自动防范它是值得的。有时候是因为我发现,就我个人而言,看待问题的某些方式有助于我理解这个问题。在任何情况下,我的任何给定项目的大部分工作流经常看起来非常类似于我以前项目的大部分工作流。毫不奇怪,我发现减少这些重复活动的开销很有用。

虽然自从我学会如何编码以来,我已经理解了通过自动化减少开销的价值,但是我从来没有得到多少关于如何做的建议。这只是我得到的一些东西。在这篇文章中,我试图总结我学到的一些东西,并且我将使用我工作流程中最近自动化部分的一些代码作为例子。

逻辑美

好的设计建议至少在维特鲁威写了十本关于建筑的书(仍然值得一读)之后就已经存在了,他在书中说好的设计实现了稳固、有用和愉悦。将前两个理念转化为工作流自动化设计是相对容易的:无论我们构建什么,它都应该以我们需要的规模、速度和质量一致地完成我们希望它做的工作。但是我认为最后一个理想——快乐——通常会决定一个可行的设计和一个好的设计。 Fred Brooks 认为在技术设计的背景下,愉悦应该被认为是“逻辑美”,并且认为 一个逻辑美的产品是一个最小化脑力劳动的产品。

我认为最小化脑力劳动是数据科学工作流的一个有趣的目标,因为数据行业最近的许多尴尬似乎都是由从业者没有花费足够的脑力思考他们的设计决策的潜在后果而引起的。 所以我们需要仔细选择哪些区域的脑力劳动要最小化 。这意味着一个好的设计的第一步是,不管听起来有多老套,决定我们想要完成什么。

想想开车吧。我尽可能高效地开车去我要去的地方。一辆设计良好的汽车应该能够让我尽可能地将注意力集中在与实现我的目标最直接相关的事情上。这意味着尽量减少其他事情上的精神负担。换句话说,当我开车时,我应该能够集中精力在正确的地方转弯,避开行人或灯柱之类的东西。我不应该专注于确保发动机运转,或者换挡,或者刹车如何工作。如果我把车用于其他目的,我可能会专注于这些事情,但它们对于完成我选择的特定目的来说并不合适。一个好的设计不应该分散我的注意力,也不应该阻止我去关注那些可能妨碍我实现目标的事情。

得体是谈论相关性的一种有点过时的方式。布鲁克斯将设计中的得体定义为“不要引入无关紧要的东西。”我发现根据我在类比中使用的权衡来考虑适当性是很有用的。如果做某件事能确保我不被阻止实现我的目标,那么它对那个目标来说是恰当的。如果做某件事只是为了达到目的,那对这个目的来说是不合适的。如果不能避开行人或灯柱,我将无法到达我想去的地方。如果我乘汽车、步行、滑板、自行车、飞机或火车旅行,那是真的。没有内燃机不一定会阻止我去我想去的地方;因此,这种设计是不合适的,不管它在实现上有多方便。所以在我们定义了我们的目标之后,定义什么是适合这个目标的:作为一个经验法则,如果它能让我们前进,它可能是也可能不是合适的;如果能阻止我们前进,那就是正当的。 好的设计能最大限度地减少不符合我们预期目的的任务所耗费的脑力

正交性是逻辑美的另一个组成部分。布鲁克斯对此总结为“不要把独立的东西联系起来”。换句话说:我避开行人和灯柱的能力部分取决于能否看到这些东西,部分取决于能否操纵汽车避开它们。挡风玻璃的功能和方向盘的功能应该相互独立。一个不能保持独立性的设计将是一个糟糕的设计。因此,在我们定义了工作流的适当组件之后,我们将依赖性最小化。 好的设计会将合适的组件与不合适的组件分开,这样我们就不会不小心将花费在真正需要我们全神贯注的事情上的精力减到最少。同样,好的设计让不合适的组件相互隔离,这样我们就不会意外地以我们没有预料到的方式减少脑力劳动。

通用性是我在继续讲这个例子之前要讲的最后一个原则。布鲁克斯将其总结为“不要限制固有的东西。”换句话说,轮胎(或引擎或电线等。如果没有一个很好的理由,就不应该设计成只适合那辆车。 好的设计在限制一个功能可以应用的用例之前需要一个理由。 这使得我们更容易适应意料之外的需求,而无需重新构建整个产品。

所以,总结一下:

  1. 决定我们想要达到什么目的。
  2. 确定哪些任务适合完成该目的。
  3. 通过将适当的任务与不适当的任务分开,以及将不适当的任务彼此分开,来最小化依赖性。
  4. 在保持适当性或正交性的同时,尽可能将每个任务规划为通用的。

遵循上述原则的设计往往在逻辑上是美丽的,因为它们在所有正确的地方最小化了我们的精神努力。

工作流设计的一个极简例子

我经常处理地理位置数据,并且经常需要绘制这些数据。有时我需要绘制形状,有时我需要点。有时我需要在卫星图像的背景下看到这些物体,以获得一些粗略的背景,有时我需要道路或标签的更详细的背景。我通常不得不一周几次使用这种工作流程。有时候我一天要经历上百次。无论如何,我必须经常这样做,这是减少脑力劳动的好方法。所以我只有一个目的:在一张图片上用图形表示经度和纬度对,这张图片表示这些坐标的真实环境。这个目的定义了适当性:任何实际上没有在图片上放置形状的东西对我的目的来说都是不适当的,因此花费在那件事情上的精神努力应该被最小化。就目前的例子而言,界定目的和正当性相对容易。情况并非总是如此。

现在我需要担心正交性。想象一下,和一个完全没有技术专长的人说话。我通常会想象,要么是我最早的一位经理将所有涉及代码的事情都描述为“新奇”,要么是我母亲仍然拒绝得到电子邮件地址,要么是一名主修人文学科的大学新生。你明白了。我的任务创造了一系列问题,我想象中的新手会认为这些问题对于创造我想要的结果是必要的和充分的。如果我想象中的新手可以说“但是你为什么需要 X 的答案?”,这意味着我包含了一个不必要的问题。如果我想象中的新手可以说“但是我不明白 X,Y,Z 的答案将如何导致结果”,那意味着我要么错过了一个问题,要么没有问对问题。我喜欢用一个虚构的新手作为共鸣板的原因是,当我试图设计所有东西时,我往往会变得太专业太快。因为我知道如何实现事情,所以我的大脑比它应该做的更快地跳到实现问题上。如果你有一个真正有血有肉的新手愿意并且能够成为你的传声筒,那就用那个人,而不是一个想象出来的人。

如果我的目标是在图片上得到形状,那么我只有三个问题:

  • 我在哪里得到形状?
  • 我在哪里得到照片?
  • 我如何得到图片上的形状?

很基本的问题,对吧?但是这些基本问题迫使我从基本构件的角度来思考,这使得保持正交性变得更加容易。如果我最终构建的任何东西的运行方式是,在不改变我如何将这些形状放在图片上的情况下,我无法改变我如何获得这些形状,那么我可能构建的东西是错误的。功能的不同部分应该尽可能的独立。

现在我有了正交分量,我想让它们尽可能通用。为此,我需要用例。在我需要做的三件事情中,我已经偏向于偏好的方式,但是从长远来看,如果我能想出尽可能多的方式——偏好的或不偏好的——我会更好。我可能不会实现对我列出的所有用例的支持:这将取决于项目的约束(主要是我有多少时间、多少资源和多少竞争优先级)。最好还是预先知道尽可能多的用例——通常,在实现对关键用例的支持的过程中,支持额外的、还不需要的用例只是理所当然的事情。这可以减少沮丧和路上浪费的时间。以下是当前示例的一些用例:

我从哪里得到这些形状?

从哪里获取图片?

我如何得到图片上的形状?

当然,这个列表并不详尽。如果我有更多的时间来考虑,我可以建立一个更完整的清单,可能会更好。但是由于我的时间有限,还有其他事情要做,我很满足于每个问题至少有两个答案。我真正想做的是避免只关注眼前需求的短视行为。

从设计到实施

您可以跳到这一节的底部来查看我实现的完整代码,但是先通读一下这个讨论来理解我做了什么可能会有所帮助。

我选择完全依靠散景库来绘制图片上的形状,因为我已经知道并喜欢这个库——它很容易快速启动并运行。同样,我选择完全依靠谷歌地图来获取图片,因为它为卫星图像、地图和这两种东西的注释版本提供了单一来源,还因为 Bokeh 已经提供了一种调用谷歌地图 API 的便捷方式。

我很少在工作流程的这些部分上花费精力,因为精心制作可视化的外观和感觉——选择背景图像,决定绘制什么形状,以及设计和注释这些形状——都符合我的目的,所以我想尽可能地保持对这些事情的细粒度控制。

我实现的 Python 类有一个“prepare_plot”方法,它在很大程度上只接受传递给该方法实例化的 Bokeh“gmapplot”对象的可选关键字参数:

该类还有一个“add_layer”方法,用于在图片上放置形状:

这个方法调用只有两个必需的参数。一个是标签,告诉该方法该形状应该引用什么数据源(同样,稍后会详细介绍)。另一个是散景模型——我最常用的两个模型是“面片”,用于绘制多边形,和“圆”,用于绘制坐标对。有一个可选的“工具提示”参数,它采用一个字符串或一个元组列表来创建当鼠标悬停在一个形状上时应该出现的工具提示。所有其他关键字参数都被传递给散景模型,这让我可以更好地控制形状的外观。大多数散景模型允许形状的边框和区域采用不同的样式。例如,如果我想要一个带有黑色边框的红点,我会将“填充颜色”设置为红色,将“线条颜色”设置为黑色。同样,如果我想填充 50%透明,但边框是 0%透明,我会设置'填充阿尔法'为 0.5 和'线阿尔法'为 1.0。通常,我希望填充和线条的样式相同,所以“add_layer”方法接受额外的关键字。如果我将‘alpha’设置为 0.5,那么‘fill _ alpha’和‘line _ alpha’都将被设置为 0.5。这是脑力劳动的一个小小的减少,但这种减少足以方便。

然而,我所做的大部分脑力劳动都与准备绘图数据有关。我提到的获取形状的所有四个用例——经度/纬度对、知名文本、shapely 对象和 geo hashes——是我在日常工作中经常遇到的用例。我发现我研究数据的很多时间并没有花在真正理解情节上,而是花在将数据转换成我需要的格式上。当我不得不在分析过程中中途切换数据源类型时,我尤其会产生大量开销(例如,我可能设置了一个工作流来绘制地理坐标对,然后突然发现我需要绘制地理散列;这要求我重组我的部分工作流程)。

“添加源”方法需要数据和标签:

数据可以是包含我提到的四种输入值之一的列表,也可以是一个数据帧,其中一列包含这些输入值(并且必须明确指定该列)。该方法执行四个基本功能:

  • 它调用_process_input_value,自动验证输入类型(geohash vs. coordinate pair 等。)并将其格式化为一个 x 坐标列表和一个 y 坐标列表。在众所周知的文本或表示多重多边形或一些其他多重几何图形集合的有形状的对象的情况下,它将格式化列表的列表。` _process_input_value '方法作为一个切换面板,完全消除了适当格式化输入值的开销,假设值是受支持的类型之一。
  • 它向输入值追加元数据。在数据帧输入的情况下,不包含输入值的数据帧的每一列都将被用作元数据。在列表输入的情况下,任何关键字参数都将被用作元数据(假设参数是与输入值列表长度相同的列表。
  • 它扩展了源数据帧以适应多种形状。如果输入值类似于一个多面,它会将其分割成单独的面,并将多面的元数据追加到每个单独的面。这类似于 SQL 中分解数组的概念。
  • 完成上述所有处理后,它调用_set_coordinate_bounds,更新绘图边界(最小和最大 x 和 y 值)。确定谷歌地图缩放级别时会参考这些界限。

这个类还做了很多其他的事情,但是在大多数情况下,这个类本身的结构只不过是我的工作流程的三个关键部分的实例化:获取形状,获取图片,将形状放到图片上。因为我使用一些合理的设计原则(目的→适当性→正交性→一般性)来编写工作流,所以扩展该类以适应新的需求相对容易。例如,我想扩展这个类来使用 WMTS 地图而不是谷歌地图。由于该类的设计方式,我可以或多或少地只对“prepare_plot”方法进行修改,而不做其他任何事情。如果我想使用传单或 Matplotlib 或其他东西来渲染情节,这将需要一些更广泛的更新,但效果仍然不会波及整个代码库。

然而,最大的好处不在于我如何编写代码,而在于我是否编写了任何代码。是的,从长远来看,对我的工作流程进行编码可以节省时间和精力,但是 它也要求我首先明确我的工作流程是什么 。在编写这段代码的过程中,我发现了工作流中让我不开心的几件事。例如,当我想要绘制多边形而不是点(或点而不是多边形)时,我讨厌花费大量时间来管理数据,所以我将“add_source”方法更改为始终假定多边形,并将“add_layer”方法更改为每当使用假定点数据但引用包含多边形数据的数据源的散景模型时自动计算质心并更新数据源。我在没有意识到的情况下,将关于数据的多边形与点结构的假设融入到了工作流中。通过整理我的工作流程,我认识到了这个假设,决定不喜欢它,并删除了它。

整理我的工作流程会让我的工作流程更好,而让我的工作流程更好会让我成为更好的程序员。在明确考虑代码和工作流的设计时,我让旧的工作更容易用于新的问题,并与同事分享我的工作。

代码

我想不言而喻,这段代码并不是我之前概述的设计原则的完美体现。设计是一个方向,而不是终点。我痛苦地意识到代码有多少需要改进的地方!

初学者的深度学习编码——线性回归(第三部分):梯度下降训练

原文:https://towardsdatascience.com/coding-deep-learning-for-beginners-linear-regression-gradient-descent-fcd5e0fc077d?source=collection_archive---------6-----------------------

Source: https://reconsider.news/2018/05/09/ai-researchers-allege-machine-learning-alchemy/

这是系列“初学者深度学习编码”的第 5 篇文章。你可以在这里找到所有文章、链接,以及第一篇文章* 底部关于下一篇文章 预计发布日期的一般信息。它们也可以在我的开源文件夹— MyRoadToAI 中找到,还有一些迷你项目、演示、教程和链接。*

目标

在本文中,我将解释用梯度下降训练机器学习算法的概念。大多数监督算法都在利用它——尤其是所有的神经网络。这是一个至关重要的话题,也是开始机器学习的人需要克服的最大障碍之一。这是因为它是基于微积分的,有些人在学校没有学过,或者他们的知识生锈了。

但是不要担心,即使你对数学不熟悉或者根本不懂微积分,你仍然可以理解它,学习它,并使用它。我会告诉你怎么做!

靠蛮力训练

由于上一篇文章中介绍的成本函数,已经可以训练模型来预测克拉科夫公寓的价格。模型只使用了公寓的尺寸,所以它的形式并不太复杂:

其中:

  • ŷ —预测房价,
  • x—户型,
  • w —分配给公寓大小的重量,
  • b —偏置。

下标“0”代表特征在数据集 X 的每个矢量中的位置,为了提高可读性,省略了该下标。

训练过程的目标是找到 wb 参数的组合,为此成本函数返回尽可能小的误差

为了提高模型性能,会做一些非常幼稚的事情。在许多迭代中,参数将通过一个小的固定步长改变,并且不知道参数值是否应该改变以及在哪个方向上改变。因此,将计算所有可能组合的成本值,以找到最佳修改,这就是为什么它被称为“暴力训练”在每次训练迭代中,可以对参数执行三个动作:增加、减少、不变。两个参数,这意味着每次迭代将有 3 = 9 组参数来检查,并对其进行预测,计算成本。模型将使用成本最低的设置进行更新。

Training with Brute Force — diagram showing how to train model with two parameters (w and b) without using Gradient Descent algorithm.

让我们实现它,看看结果。大多数操作已经在上一篇文章中编码了,因此只剩下训练循环需要实现。

Full code available under this link.

只有两个参数,代码已经足够复杂,可以省略一些部分来提高可读性。隐藏部分的实现与图中所示非常相似——唯一的区别是数学运算符从+=变为-=,或者有时根本不使用。

代码片段以从copy模块导入deepcopy函数开始。需要复制存储在model_parameters字典中的模型参数及其内容。在任何训练发生之前,函数predictmse使用model_parameters通过计算其初始误差来测量模型的潜力。

然后model_parameters被复制九次。每个副本都以不同的方式(加法、减法、无变化)被step值修改,然后用于预测。根据candidate_pred的正确性,副本具有作为candidate_error变量分配给它的成本值。误差和参数存储在candidateserrors列表中。在计算了每个候选项并测量了它们的性能后,使用成本最低的一组参数来代替model_parameters。它发生iterations次,默认设置为 100。请注意,函数train没有返回任何结果,并且model_parameters被就地修改。

在所有这些之后,可以对加载的数据和初始化的模型参数使用train函数,以便找到将误差最小化的值:

可以将简单的print函数添加到train函数体中,并显示训练过程如何改变模型参数(如果您以前没有这样做,请查看此链接以获得完整代码):

Initial state:
 - error: [75870.4884482]
 - parameters: {'w': array([0.]), 'b': 0.0}

Iteration 0:
 - error: [73814.2609893]
 - parameters: {'w': array([0.1]), 'b': 0.1}

Iteration 20:
 - error: [38764.28631114]
 - parameters: {'w': array([2.1]), 'b': 2.1}

Iteration 40:
 - error: [15284.92972772]
 - parameters: {'w': array([4.1]), 'b': 4.1}

Iteration 60:
 - error: [3376.19123904]
 - parameters: {'w': array([6.1]), 'b': 6.1}

Iteration 80:
 - error: [1753.32046443]
 - parameters: {'w': array([7.1]), 'b': 8.1}

Final state:
 - error: [1741.85716443]
 - parameters: {'w': array([7.1]), 'b': 10.0}

误差随着每次迭代而减小。这是因为所有的训练样本都在每次迭代中使用——但是在以后的文章中会有更多的介绍。另一个重要的观察结果是训练结束后误差值不等于零。仅仅用线性函数是不可能遍历所有的点的。

最后,可以显示训练的结果,并查看模型如何能够估算公寓价格:

Model projection after training. Code used to create the chart is available here.

结论

训练这样一个简单的模型并找到可以在给定数据上表现良好的参数,不需要任何复杂的技术。但是目前的方法有很多局限性:

  • 一大堆样板代码
  • 在每次迭代中需要测试太多的组合。这个模型只使用了两个参数。想象一下在像神经网络这样的模型中会发生什么,其中参数的数量有时以百万计——3⁰⁰⁰⁰⁰⁰不是一个好数字…
  • 改变参数的步骤对于每个参数是固定的其值的范围也是未知的,有时 0.1 可能太大,有时可能太小。
  • 每个参数应该改变的方向是未知的,这就是为什么必须尝试所有可能的改变。它需要大量的计算能力,并且非常慢。

衍生工具的作用

矛盾的是,当涉及到重用已经发明的涉及梯度下降的机器学习概念时,理解哪些导数可以用于比能够计算它更重要。 Andrew Trask 在他的书“探索深度学习”中提供了非常好的关于什么是衍生品以及它如何运作的直觉。本文的解释将使用类似的推理。

直觉

想象有两根杆子伸出墙外。让我们将它们命名为杆 A 和杆 b。杆 A 比杆 b 短两倍。为了了解杆之间的关系,进行了两个实验:

  • 首先,杆 A 被推入墙中。可以观察到的是,木棒 B 的长度随着木棒 A 一起缩短,但是缩短了两倍。
  • 其次,杆 A 被拉出墙壁,其长度增加。结果,杆 B 也伸长了,但速度快了两倍。

现在让我们试着用数学方程的形式描述两杆之间的关系。在两种情况下,都可以观察到杆 B 的长度总是杆 A 的两倍:

其中:

  • l_A —杆 A 的长度,
  • l_B —杆 B 的长度

稍等片刻,想想数字 2 在这个等式中的作用。l_B 相对于 l_A 的导数,可以写成:

从中可以学到什么?

  • 导数描述了一个变量被修改时,另一个变量是如何变化的。那么在这种情况下,当杆 A 的长度被修改时,杆 B 的长度以什么因子延伸或收缩。
  • 计算两个变量之间的导数。
  • 当导数为正值时,两个值的变化方向相同。如果杆 A 延伸,那么杆 B 也延伸,因为 2 是正数。反之亦然,如果导数为负值,则值向相反方向变化。****

请记住:

对于可微函数,有可能找到两个变量之间的关系——当一个变量通过使用导数被修改时,一个变量改变了多少以及在什么方向上改变。

考虑到之前关于“暴力学习”的问题,导数有一些有趣的性质可以用来解决这些问题。

梯度下降

凸函数 最小值的一种迭代优化算法。它基于微积分— 依赖于一阶导数的性质来寻找在什么方向和用什么幅度系数来修改函数。****

在之前的文章中提到,用于测量机器学习模型性能的成本函数需要是可微分的。如果不是这种情况,那么梯度下降算法不能应用。

让我们以均方误差函数为例,它被广泛用作回归模型的成本函数。

  • i —样品指数,
  • ŷ —预测值,
  • y —期望值,
  • m —数据集中的样本数量。

预测值 ŷ 可以用公寓价格近似模型的公式代替。让我们也稍微调整一下使用的命名法,如用大写字母 J 来命名机器学习模型的错误非常流行。

现在很容易看出误差值取决于 wb 系数。参数 mxy 可以被视为常量,其值是已知的,并由训练模型的数据集确定。

已经说过,计算任何两个函数参数之间的导数是可能的,并且它将提供当一个参数改变时另一个参数改变的信息。 J 的派生结果:

  • 关于参数 w 提供了如何调整参数 w 的值以最小化或最大化 J、的值的信息

  • 关于参数 b 提供了如何调整参数 b 的值以最小化或最大化 J. 的值的信息

如果模型有更多的参数,那么需要计算更多的导数。这就是微积分派上用场的时刻。在大多数情况下,使用梯度下降算法不需要数学。机器学习、详细计算或代码实现中使用的各种函数的衍生物** 在 web 中全局呈现。**

首先,在网上查找答案是很好的。使用微积分的能力肯定会导致更好地理解各种机器学习机制是如何工作的。它还将提供检查其他人的代码的能力。

如果你想知道这两个导数是如何计算出来的,那么试试这篇博文或者看看伊恩·古德菲勒的书《深度学习》的第 106 页(T2)。

几何解释

可以考虑在给定点处曲线切线的斜率的导数。“梯度”一词的同义词是“坡度”

模型参数值通常在开始时是随机的。它们的值误差曲线(对于一个参数的模型)误差曲面(对于两个参数的模型)或误差超平面(对于两个以上的参数)上强加点的位置。梯度下降算法的目标是找到参数值,因此该点总是出现在最低区域,因为那里的误差值最低。

以下是展示单参数模型如何根据随机生成的数据进行迭代改进的可视化效果。有两种情况:

  • 随机化的权重值太小,需要增加,

  • 随机权重值太大,需要减小。

有一些重要的观察结果:

  • 请注意,权重值太小,则导数为负,而权重值太大,则导数为正。因此,为了最小化误差函数,需要从权重中减去导数,以使该点更接近全局最小值。如果加上导数,误差反而会增加。
  • 随着权重更新使误差值更接近全局最小值,导数值正在减少。从几何角度来看,这也是正确的,因为切线的“斜率”也随着每次迭代变得不那么陡
  • 点与点之间的距离称为梯度步长。请注意,导数值远大于 x 轴上的重量值。如果第一个陈述为真,从重量中减去导数值不会以如此小的数字改变重量值。这是因为当使用梯度下降更新参数时,只需要使用导数的很小一部分来保持数值稳定性,并且不会跳过全局最小值。应该使用导数的哪一部分或者梯度步长应该有多大由学习速率超参数决定。

当学习率太大时,数值开始从曲线反弹,误差无限增加:

如果模型依赖于两个参数而不是一个参数,那么为了显示误差值,需要额外的轴(用于附加参数)。这自动将可视化从 2D 平面带到 3D 表面。下面是在网上找到的一个很好的例子,说明这种错误表面可能是什么样子:

Source: https://towardsdatascience.com/improving-vanilla-gradient-descent-f9d91031ab1d

对于两个以上的参数,可视化是非常困难和棘手的。通常,依靠诸如 PCA 等降维方法是很重要的。幸运的是,数学与此非常相似,可以扩展到任意数量的参数。

更新规则

为了更新模型参数,从而实现收敛,必须迭代应用以下数学公式:

其中:

  • w’—新重量值,
  • b’—新偏差值,
  • w —当前重量值,
  • b —电流偏置值,
  • α —学习率,
  • dJ(w_0,b)/dw_0—J 关于 w _ 0 的导数,
  • dJ(w0,b)/db—J 相对于 b 的导数。

应该更新参数,直到成本函数值不再降低,并且如果当前模型状态已经令人满意,则可以停止整个过程。

实施

让我们编写使用梯度下降算法的新train函数:

由于仅使用特定点的导数值0.0005,参数变化很小。它接管20000迭代以获得好的结果。如果输入数据事先经过标准化,则整个过程可以加速。

在每次迭代期间,计算每个数据样本的部分梯度,并对整个数据集求和。此后,累积的梯度被平均并用于在梯度步骤结束时更新参数(参数被更新的迭代)。

现在新的train功能可以像以前一样使用:

这产生以下结果:

Initial state:
 - error: [75870.4884482]
 - parameters: {'w': array([0.]), 'b': 0.0}

Iteration 0:
 - error: [13536.3070032]
 - parameters: {'w': array([10.17501967]), 'b': array([0.17843399])}

Iteration 4000:
 - error: [1737.28457739]
 - parameters: {'w': array([7.09101188]), 'b': array([10.96966037])}

Iteration 8000:
 - error: [1707.33242182]
 - parameters: {'w': array([6.9583785]), 'b': array([18.67110985])}

Iteration 12000:
 - error: [1692.21685452]
 - parameters: {'w': array([6.86415678]), 'b': array([24.14215949])}

Iteration 16000:
 - error: [1684.5886765]
 - parameters: {'w': array([6.79722241]), 'b': array([28.02875048])}

Final state:
 - error: [1680.73973307]
 - parameters: {'w': array([6.74968272]), 'b': array([30.78917543])}

比较这两种训练方法没有意义。蛮力训练的主要问题是效率低下。在梯度下降算法的情况下,模型迭代地达到收敛 ,不需要检查所有可能的修改。在处理复杂的问题——高维数据时,这将带来巨大的不同。

最后让我们看看模型投影:

Model projection after training. Code used to create the chart is available here.

摘要

我们非常接近创建我们的第一个机器学习模型——线性回归,用 Python 从头开始编写,能够预测克拉科夫公寓的价格。利用已经提供的知识,你可以自己创造最终的解决方案!

在本文中,我已经向您展示了训练循环如何工作以及如何使用成本函数来找到模型的最佳参数。然后指出了现有方法的诸多缺点。在下一部分,我们解释了什么是导数,以及它在中的用途。我已经从理论、数值和几何角度告诉过你什么是梯度下降算法,使用均方误差函数示例作为解释的帮助。最后,我已经把解释过的概念变成了代码,并用它来训练我们的模型的单一特征——公寓大小。

我们现在缺的是… 泛化。所有的概念和代码片段都是针对一维数据的简单问题而提出的。这种简化当然是有意的。在下一篇文章中,,我将向你展示如何重构所有这些概念,使它们适用于任何数量的特性,并且永远不需要再次编辑!通过矩阵乘法可以实现,整个过程称为向量化

下一篇文章

期待下一篇2018 年 8 月 30 日左右

初学者的编码深度学习—线性回归(第一部分):初始化和预测

原文:https://towardsdatascience.com/coding-deep-learning-for-beginners-linear-regression-part-1-initialization-and-prediction-7a84070b01c8?source=collection_archive---------2-----------------------

这是“初学者深度学习编码”系列的第 3 篇文章。在这里,你可以在第一篇文章 的底部找到所有文章议程的链接,以及关于下一篇文章* 预计发布日期的一般信息。它们也可以在我的开源文件夹— MyRoadToAI 中找到,还有一些迷你项目、演示、教程和链接。*

你也可以在我的个人网站上阅读这篇文章,为了提高可读性(支持代码语法高亮、LaTeX 方程式等等),我的个人网站由 Jekyll 主办。

为什么是线性回归?

你们中的一些人可能想知道,为什么关于解释和编码神经网络的系列文章是从基本机器学习算法开始的,比如线性回归。从那里入手是很有道理的。首先,它是一个非常简单的算法,因此读者可以掌握对基本机器学习概念的理解,例如监督学习成本函数梯度下降。此外,在学习线性回归之后,理解逻辑回归算法是非常容易的,不管你信不信,可以将它归类为小型神经网络。在接下来的几篇文章中,您将会看到所有这些,甚至更多!

工具

让我们介绍一下最流行的库,它们可以在每一个基于 Python 的机器学习或数据科学相关项目中找到。

  • NumPy —一个科学计算库,非常适合多变量微积分&线性代数。提供 ndarray 类,可与 Python 列表进行比较,可被视为矢量或矩阵
  • Matplotlib数据可视化工具包,允许创建各种 2d 和 3d 图形。
  • 熊猫—这个库是 Matplotlib 和 NumPy 库的包装器。它提供了数据帧类。它将 NumPy 矩阵视为表,允许通过附加的名称访问行和列。在数据加载、保存、争论和探索过程中非常有帮助。提供一个功能接口,使部署更快。

使用 Python PyPi 可以单独安装每个库。它们将以下列别名导入到每篇文章的代码中。

什么是线性回归?

这是一个监督学习算法,其目标是基于给定的数据输入预测连续的数值。从几何角度来看,每个数据样本都是一个点。线性回归试图找到线性函数的参数,因此所有点与直线之间的距离尽可能小。用于参数更新的算法称为梯度下降

Training of Linear Regression model. The left graph displays the change of linear function parameters over time. The plot on the right renders the linear function using current parameters (source: Siraj Raval GitHub).

例如,如果我们有一个由某个特定区域的公寓属性及其价格组成的数据集,可以使用线性回归算法来查找一个数学函数,该函数将尝试根据其属性来估计不同公寓(在数据集之外)的价值。

另一个例子是根据销售数据预测杂货店的食品供应量。这样,企业可以减少不必要的食物浪费。这种映射对于任何相关的输入输出数据对都是可以实现的。

数据准备

在编码线性回归部分之前,最好有一些问题要解决。在像 UCI 知识库Kaggle 这样的网站上可以找到很多数据集。在经历了许多之后,没有一个适合本文的研究案例。

为了获得数据,我进入了波兰网站 dominium.pl ,这是一个在我居住的克拉科夫市寻找公寓的搜索引擎。我完全随机选择了 76 套公寓,写下它们的属性并保存到。csv 文件。目标是训练能够预测克拉科夫公寓价格的线性回归模型

数据集在我的 Dropbox 上的这个链接下。

加载数据

让我们从读取数据开始。csv 文件转换为熊猫的 DataFrame 对象并显示一些数据行。为了达到这个目的,将使用 read_csv 函数。数据用冒号分隔,这就是添加sep=","参数的原因。函数 head 以易读的 HTML 表格的形式呈现前五行数据。

代码的输出如下所示:

DataFrame visualisation in Jupyter Notebook.

如表中所示,有四个特征描述公寓属性:

  • distance _ to _ city _ center-步行从住所到克拉科夫主广场的距离,用谷歌地图测得,
  • 房间 -公寓房间数,
  • 面积 -户型面积以平方米计量,
  • 价格 -目标值(需要模型预测的),以波兰国家货币计量的公寓成本——兹罗提

可视化数据

始终理解数据的结构非常重要。功能越多越难。在这种情况下,散点图用于显示目标和训练特征之间的关系。

Charts show whole data from cracow_apartments.csv. It was prepared with Matplotlib library in Jupyter Notebook. The code used to create these charts can be found under this link.

根据需要显示的内容,一些其他类型的可视化(例如盒状图)和技术可能是有用的(例如聚类)。这里,可以观察到特征之间的线性相关性——随着 x 轴上值的增加,y 轴上的值也相应地线性增加或减少。这很好,因为如果不是这样(例如,关系将是指数的),那么将很难拟合一条穿过所有点的线,并且应该考虑不同的算法。

公式

线性回归模型是一个数学公式,它以的数值向量(单个数据样本的属性)作为输入,并使用它们进行预测

将相同的陈述映射到所呈现的问题的上下文中,有 76 个样本包含 Cracow 公寓的属性,其中每个样本从数学角度来看都是向量。每个特征向量与目标值配对(公式的预期结果)。

根据该算法,每个特征都分配有一个权重参数。表示其对模型的重要性。目标是找到权重值,因此每个公寓数据都满足以下等式。

等式的左侧是一个线性函数。如操纵权重值可以改变线条的角度。虽然,还是缺少了一个元素。当前函数总是通过坐标系的(0,0)点。为了解决这个问题,增加了另一个可训练参数。

该参数被命名为偏差,它赋予公式在 y 轴上上下移动的自由度

紫色参数属于模型,用于预测每个传入的样本。这就是为什么找到一种对所有样品都最有效的解决方案是必要的。形式上,该公式可以写成:

初始化

这是一个创建第一个模型版本的阶段。初始化后的模型已经可以用于预测,但如果没有训练过程,结果将远远不是好的。有两件事要做:

  • ****在代表权重和偏差参数的代码中创建变量,
  • ****决定模型参数的初始值

模型参数的初始值对于神经网络来说是非常重要的。在线性回归的情况下,参数值可以在开始时设置为零

函数init(n)返回包含模型参数的字典。根据数学公式下方图例中的术语, n 是用于描述数据样本的特征数。NumPy 库的 zeros 函数使用它来返回一个 ndarray 类型的向量,该向量有 n 个元素,每个元素都赋有零值。Bias 是一个设置为 0.0 和的标量,将变量保持为浮点数而不是整数是一个好习惯。相应地,权重和偏差都可以在“w”和“b”字典键下访问。

对于 Cracow 公寓数据集,有三个特征描述每个样本。下面是调用init(3)的结果:

预言;预测;预告

模型可以使用创建的模型参数进行预测。公式已经显示出来了。现在是时候把它变成 Python 代码了。首先,每个特征都必须乘以其相应的权重并求和。那么偏差参数需要加到前面操作的乘积上。结果是一个预测。

函数predict(x, parameters)有两个参数:

  • 代表数据样本的特征向量x(例如单身公寓),
  • Python 字典parameters存储了模型的参数及其当前状态。

组装

让我们将创建的所有代码部分放在一起,并显示在结果中。

****只有一个特征用于预测什么简化公式形成:

这是有意为之,因为显示超过 1-2-3 维的数据的结果变得很麻烦,除非使用降维技术(例如 PCA )。从现在起,出于学习目的,所有代码开发将只在尺寸特征上进行。当线性回归代码完成时,将显示使用所有功能的结果。

Line used to fit the data by Linear Regression model with current parameters. Code for visualisation is available under this link.

模型参数用零值初始化,这意味着公式的输出将总是等于零。因此,prediction是一个包含 76 个零值的 Python 列表,它们分别是每套公寓的预测价格。但是现在没关系。使用并解释梯度下降训练后,模型行为将会改善。****

代码片段的额外收获是:

  • 模型使用的特征和目标值存储在featurestarget Python 列表中。由于这一点,如果要使用一组不同的特性,就不需要修改整个代码。
  • 使用 as_matrix 函数可以将 DataFrame 对象解析为 ndarray。

摘要

在本文中,我介绍了我将在整个文章系列中使用的工具。然后我提出了我要用线性回归算法解决的问题。最后,我展示了如何创建线性回归模型并使用它进行预测。

在下一篇文章中,我将解释如何比较参数集和测量模型性能。最后,我将展示如何用梯度下降算法更新模型参数。

下一篇

下一篇文章可点击这里

初学者深度学习编码—线性回归(第二部分):代价函数

原文:https://towardsdatascience.com/coding-deep-learning-for-beginners-linear-regression-part-2-cost-function-49545303d29f?source=collection_archive---------1-----------------------

Evaluating model performance during training process. (Source http://neuralnetworksanddeeplearning.com/)

这是“初学者深度学习编码”系列的第 4 篇文章。在这里,你可以在第一篇文章 的底部找到所有文章议程的链接,以及关于下一篇文章* 预计发布日期的一般信息。它们也可以在我的开源文件夹— MyRoadToAI 中找到,还有一些迷你项目、演示、教程和链接。*

你也可以在我的个人网站上阅读这篇文章,为了提高可读性(支持代码语法高亮、LaTeX 方程式等等),我的个人网站由 Jekyll 主办。

概述

上一篇文章介绍了线性回归实施完成后将要解决的问题。目标是预测克拉科夫公寓的价格。数据集由三个特征描述的样本组成:到城市中心的距离房间大小。为了简化可视化并提高学习效率,将只使用尺寸特征。

此外,给出并解释了线性回归模型背后的数学公式。为了使方程完整,它的参数需要有指定的值。然后,该公式准备好返回任何给定输入样本的数值预测。

这里描述的两个步骤称为初始化预测。两者都被转化为独立的 Python 函数,并用于创建线性回归模型,其中所有参数都被初始化为零,并用于根据大小参数预测公寓价格。

Code used to prepare the graph is available under this link.

下一个要解决的问题

由于模型的所有权重和偏差都等于零,具有当前参数的模型将为面积参数的每个值返回零。现在让我们修改参数,看看模型的投影是如何变化的。

Code used to prepare these graphs is available under this link.

有两组参数会导致线性回归模型为每个大小要素值返回不同的公寓价格。由于数据具有线性模式,在适当校准参数后,模型可以成为价格的精确近似值。

要回答的问题

对于哪一组参数,模型返回更好的结果?

  • 橙色:w = 3b = 200
  • 石灰:w = 12b = -160

即使有可能通过视觉判断正确猜出答案,计算机也不会想象——它会比较这些值。这就是成本函数的用处。

价值函数

这是一个函数,测量机器学习模型对于给定数据的性能。成本函数量化了预测值和期望值之间的误差,并且以单个实数的形式呈现。根据问题的不同,成本函数可以用许多不同的方法来构成。成本函数的目的是:

  • 最小化——那么返回值通常称为成本损失错误。目标是找到成本函数返回尽可能少的模型参数值。
  • 最大化——然后它产生的价值被命名为奖励。目标是找到返回数尽可能大的模型参数值。

对于依赖梯度下降优化模型参数的算法,每个函数都必须是可微分的。

剪裁成本函数

给定一个使用以下公式的模型:

其中:

  • ŷ -预测值,
  • 用于预测或训练的数据的 x 向量,
  • 重量级。

注意偏置参数被故意省略。让我们试着找出权重参数的值,所以对于下面的数据样本:

模型的输出尽可能接近:

现在是时候为权重参数分配一个随机值,并可视化模型的结果。让我们暂时选择w = 5.0

Code used to prepare the graph is available under this link.

可以观察到模型预测与预期值不同。怎么用数学表达?最直接的方法是将两个值相减,看运算结果是否等于零。任何其他结果都意味着值不同。接收数字的大小提供了关于错误有多严重的信息。从几何角度来看,可以说误差是坐标系中两点之间的距离。让我们将距离定义为:

根据公式,计算预测值和期望值之间的误差:

如前所述,成本函数是描述模型性能的单一数字。因此,让我们总结错误。

然而,现在想象有一百万个点而不是四个。对于在较大数据集上进行预测的模型来说,累积误差会比在较小数据集上进行预测的模型大。因此,这些模型无法进行比较。这就是为什么它必须以某种方式缩放。正确的想法是将累积误差除以点数。这样陈述成本是模型对给定数据集产生的误差的平均值。

不幸的是,这个公式还没有完成。在此之前,所有情况都必须考虑,所以现在让我们尝试选择较小的权重,看看创建的成本函数是否有效。现在,权重即将被设置为w = 0.5

Code used to prepare the graph is available under this link.

预测又一次落空了。然而,与前一种情况相比,不同之处在于预测点低于预期点。数字上的预测更小。成本公式将出现故障,因为计算出的距离为负值。

成本值也是负的:

说距离可以有负值是不正确的。可以对高于或低于预期结果的预测附加更大的惩罚(一些成本函数就是这样做的,例如 RMSE),但值不应为负,因为它会抵消正误差。那么将不可能适当地最小化或最大化成本函数。

那么用距离的绝对值来修正问题怎么样?在将距离表示为:

每个重量值的成本为:

现在,权重w = 5.0w = 0.5的成本都计算正确了。可以比较这些参数。成本值越小,模型对w = 0.5的效果越好。

创建的函数称为 平均绝对误差

绝对平均误差

测量一组预测中平均误差大小的回归度量,不考虑它们的方向。换句话说,它是预测和预期结果之间绝对差异的平均值,其中所有个体偏差都具有同等重要性

其中:

  • i -样本索引,
  • ŷ -预测值,
  • y -期望值,
  • m -数据集中的样本数。

有时可能会看到预测值和期望值互换的公式形式,但工作原理是一样的。

让我们把数学变成代码:

该函数将两个相同大小的数组作为输入:predictionstargets。公式的参数m是样本数,等于发送数组的长度。由于数组具有相同的长度,因此可以同时迭代两个数组。计算每个predictiontarget之间的差值的绝对值,并加到accumulated_error变量上。在收集了所有对的误差后,累加的结果由参数m平均,该参数返回给定数据的平均误差。

均方误差

最常用和最先解释的回归指标之一预测和预期结果之间的均方差。换句话说,MAE 的一种变化,其中不是取差值的绝对值,而是取它们的平方。

在 MAE 中,部分误差值等于坐标系中点之间的距离。关于 MSE,每个部分误差相当于由测量点之间的几何距离产生的正方形的面积。所有区域面积相加并平均。

Code used to prepare the graph is available under this link.

MSE 公式可以写成这样:

  • i -样本索引,
  • ŷ -预测值,
  • y -期望值,
  • m -数据集中的样本数。

MSE 公式有不同的形式,其中分母中没有除以 2。它的存在让 MSE 推导演算更干净。

使用绝对值计算方程的导数是有问题的。MSE 代之以使用指数运算,因此具有良好的数学性质,这使得与 MAE 相比其导数的计算更容易。当使用依赖于梯度下降算法的模型时,它是相关的。

MSE 可以用 Python 编写如下:

与上一段中介绍的mae(predictions, targets)功能的唯一区别是:

  • predictiontarget之差的平方,
  • 2在求平均分母中。

MAE 和 MSE 的区别

有更多的回归度量可以用作成本函数,用于测量试图解决回归问题的模型的性能(估计值)。MAE 和 MSE 看起来比较简单,很受欢迎。

为什么有这么多指标?

每个指标都以独特的方式处理观察结果和预期结果之间的差异。例如,不同的指标,如 RMSE,对低于预期值的预测比高于预期值的预测惩罚力度更大。它的使用可能会导致创建一个返回夸大估计值的模型。

MAE 和 MSE 是如何对待这两点之间的差异的?为了验证这一点,我们来计算不同重量值的成本:

Table presents the errors of many models created with different weight parameter. Cost of each model was calculated with both MAE and MSE metrics.

并显示在图表上:

The graphs show how metric value change for different values of parameter w. Code used to prepare these graphs is available under this link.

可以观察到:

  • MAE 不会给点与点之间的距离增加任何额外的权重——误差增长是线性的。
  • MSE 误差随着距离值的增大呈指数增长。这是一个度量标准,即对远离的点增加一个巨大的惩罚,而对接近预期结果的点增加一个最小的惩罚。误差曲线具有抛物线形状。

此外,通过检查各种重量值,有可能发现误差等于零的参数。如果使用w = 2.0来构建模型,那么预测看起来如下:

Code used to prepare the graph is available under this link.

当预测和预期结果重叠时,则每个合理的成本函数值等于零

回答

是时候回答这样一个问题了,哪一组参数,石灰能更好地估计克拉科夫公寓的价格。让我们用 MSE 来计算两个模型的误差,看看哪个更低。

在前一篇文章中解释了大部分代码。不是调用init(n)函数,而是手动创建参数字典用于测试目的。注意,这一次两个模型都使用了偏差。函数predict(x, parameters)用于不同parameters参数的相同数据。然后名为orange_predlime_pred的结果预测成为mse(predictions, targets)函数的参数,该函数分别返回每个模型的误差值。

结果如下:

  • 橙色: 4909.18
  • 石灰: 10409.77

这意味着 orange parameters 以更小的成本创造了更好的模型

摘要

在本文中,我解释了成本函数的概念——一种允许我们评估模型参数的工具。我已经向您介绍了两个最常用的回归度量 MAE 和 MSE。

在下一篇文章中,我将向您展示如何使用梯度下降算法来训练模型参数。

下一篇文章

下一篇文章可从这里获得。

面向初学者的编码深度学习—开始!

原文:https://towardsdatascience.com/coding-deep-learning-for-beginners-start-a84da8cb5044?source=collection_archive---------0-----------------------

基于直觉的一系列关于神经网络的文章,献给希望理解代码背后的基本数学的程序员和希望知道如何将数学转化为代码的非程序员。

这是“初学者深度学习编码”系列的第一篇文章。你可以在这里找到到所有文章日程的链接,以及底部关于下一篇文章 预计发布日期的一般信息。它们也可以在我的开源文件夹— MyRoadToAI 中找到,还有一些迷你项目、演示、教程和链接。

你也可以在我的个人网站上阅读这篇文章,该网站由 Jekyll 主办,目的是提高可读性(支持代码语法高亮显示、LaTeX 方程式等等。

如果你读了这篇文章,我假设你想了解最有前途的技术之一——深度学习。声明 艾是新电 最近越来越流行了。科学家们认为,随着蒸汽发动机发动机,后来的电力以及最后的电子已经彻底改变了这个行业,后来的一个人工智能即将再次改造它。几年后,机器学习的基础知识将成为任何开发人员的必备技能。即使是现在,我们也可以观察到编程语言越来越受欢迎,这些语言主要用于机器学习,如 Python 和 r。

具有魔力的技术

在过去的几年里,深度学习的应用在许多领域取得了巨大的进步,引起了人们的惊讶,他们没有想到技术和世界变化如此之快。

让我们从 2016 年 3 月超级计算机 AlphaGo 与最强围棋选手之一、18 次世界冠军李·塞多尔之间的历史比赛说起。人工智能以 4 比 1 的结果结束了胜利。这场比赛对围棋界产生了巨大的影响,因为 AlphaGo 发明了全新的棋步,让人们试图理解和再现它们,并创造了如何玩游戏的全新视角。但这还没完,2017 年 DeepMind 推出了 AlphaGo Zero 。已经不可战胜的机器的新版本能够在没有任何初始数据或人类帮助的情况下学习一切。所有这些的计算能力比它的前身少 4 倍!

AlphaGo versus Ke Jie in May 2017 (source: The Independent)

可能你们中的许多人已经听说过无人驾驶汽车项目,该项目已经开发了几年,由像 Waymo (谷歌)特斯拉丰田沃尔沃等公司开发。还有自动驾驶卡车已经在美国的一些高速公路上使用。许多国家都在慢慢准备在自己的道路上引入自动驾驶汽车,但预计未来十年将达到高峰。

但是自主飞行汽车怎么样呢?就在最近,Udacity 宣布了他们新的 Nanodegree 项目,开发者可以学习如何成为飞行汽车工程师并创造自动飞行汽车!

[## 飞行汽车和自主飞行| Udacity

掌握工作就绪的自主飞行软件工程技能,因为你处理先进的挑战,写真正的代码…

www.udacity.com](https://www.udacity.com/course/flying-car-nanodegree--nd787)

最近,由于人工智能语音识别的改进,像 Google Home 或 Google Assistant 这样的语音界面成为全新的开发分支。

Google Advertisement on Google Assistant product.

未来,人工智能将通知你因为交通而提前离开家,购买电影票,重新安排日历会议,控制你的家等等,比你想象的更近。

当然,这个列表还可以更长:人工智能能够用多种方言复制人类语言人工智能比人类更擅长诊断癌症人工智能开创哈利波特新篇章

提到所有这些的关键点是让你明白,这些发明中的每一项都使用了深度学习技术。总而言之,深度学习目前在以下任务中表现出色:

  1. 图像识别
  2. 自动驾驶汽车
  3. 像围棋、象棋扑克这样的游戏,但最近还有电脑游戏
  4. 语言翻译(但仅限几种语言)
  5. 语音识别
  6. 手写文本分析

这仅仅是个开始,因为技术每天都在变得大众化,随着越来越多的人能够使用它,越来越多的研究被完成,越来越多简单的想法被测试。

那么什么是深度学习呢?

这是基于学习数据表示的机器学习算法的子集,称为神经网络。基本想法是这样一个算法以数字数据的形式显示现实的一部分。在这个过程中,它在积累经验,并试图对给定的数据建立自己的理解。这种理解具有层次结构,就像算法具有一样。第一层学习最简单的事实,并连接到下一层,下一层使用前一层的经验来学习更复杂的事实。层数称为模型的深度。图层越多,模型可以学习的数据表示就越复杂。

Neural Network that is used for face detection. It learns hierarchy of representations: corners in first layer, eyes and ears in the second layer, and faces in the third layer (source: strong.io)

深度学习真的是新技术吗?

你们中的一些人可能认为深度学习是最近开发的技术。那不完全正确。深度学习有非常丰富的历史,并且根据哲学观点有各种各样的名称。一百多年前,在第一个数学概念建立之前,人们就梦想着智能机器。经历了三次发展浪潮。

在第一波浪潮中,深度学习被称为控制论。现代深度学习的第一个前辈是受神经系统研究启发的线性模型——神经科学。神经元(1943 年)的第一个概念,即神经网络的最小部分,是由麦卡洛克-皮特提出的,试图实现大脑功能。几年后,弗兰克·罗森布拉特将这个概念变成了第一个可训练的模型——马克 1 感知机。

Mark 1 Perceptron (source: Wikipedia)

但是人们很难用当时可用的理论来描述大脑行为。这就是为什么在接下来的 20 年里人们对它们的兴趣下降了。

第二次浪潮始于 80 年代,名为连接主义,但术语神经网络也开始被更频繁地使用。主要的想法是,当神经元大量聚集在一起时,可以实现更智能的行为。这个概念是由 Hinton 提出的,被称为分布式表示(1986) 。它仍然是今天深度学习的核心。第二次浪潮的另一个伟大成就是 Yann LeCun (1987) 发明的反向传播——这是一种核心算法,直到今天仍用于训练神经网络参数。同样在 1982 年约翰·霍普菲尔德发明了递归神经网络,在 1997 年 LSTM的额外介绍后,今天被用于语言翻译。这几年对神经网络的大肆宣传已经结束,因为各种投资者对在产品中实现人工智能的期望没有实现。

Image of LSTM cell based Recurrent neural Network (source: http://colah.github.io/posts/2015-08-Understanding-LSTMs/)

第三次浪潮始于 2006 年。那时,电脑成了每个人都能买得起的更普通的东西。得益于各种群体,例如游戏玩家,强大的 GPU 市场不断增长。每个人都可以上网。公司开始更加关注分析——以数字形式收集数据。作为一个副作用,研究人员有更多的数据和计算能力来进行实验和验证理论。因此,由于 Geoffrey E. Hinton 成功训练了多层神经网络,这又是一个巨大的进步。从那时起,许多不同的多层神经网络结构的建议开始出现。科学家将神经网络的层数称为“深度”——层数越多,就越深。非常重要的是在图像分类竞赛 ILSVRC-2012 中使用了卷积神经网络 AlexNet 。它为许多行业提供了可靠的图像检测机制,使许多机器能够看到自动驾驶汽车,从而彻底改变了许多行业。

Structure of AlexNet CNN (source: Alex Krizhevsky, Ilya Sutskever, Geoffrey E. Hinton, “ImageNet Classification with Deep Convolutional Neural Networks”, 2012)

2014 年,Ian Goodfellow 引入了一种新型的神经网络,称为生成对抗网络。在这种结构中,两个神经网络相互竞争。第一个网络试图模仿一些数据分布。第二个网络的作用是辨别它收到的数据是真是假。第一个网络的目标是欺骗第二个网络。竞争提高了第一网络的性能,并使任何类型的数据——图像、音乐、文本、语音——的生成成为可能。

GAN used to transfer style of one image into another (source: https://github.com/lengstrom/fast-style-transfer)

我想就这样了。第三波持续到今天,这取决于我们能走多远!

我为什么要创作这个系列的文章?

我真的对机器学习,尤其是深度学习充满热情。我的梦想是成为机器学习专家——与人合作解决问题并使知识大众化的人。我每天都在努力达到这个目标,这个博客是其中的一部分。所以跟我一起学习吧!

在我看来,获得这项技术的最大问题是,它是在大学和实验室由高水平的博士科学家开发的,并且仍然部分停留在那里。这是可以理解的,因为一切都强烈基于线性代数概率信息论、 数值计算。但是为了成为一名车手,你不需要了解发动机,对吗?人们仍然相信,要在这个领域工作,你需要有博士学位,但是在软件工程方面,这种观念已经开始改变。

对拥有这些技能的人的需求将会变得如此之大,以至于不可能让每个人都拥有博士头衔。这就是为什么为了让人们使用它,必须有人能把它翻译给别人,同时跳过复杂的证明,科学的符号,并增加更多的直觉。

我希望向你展示的是

我的目标是对与深度学习相关的大多数热门话题提供强有力的理解。在挑选内容的时候,我不想保护你——我想向你展示更复杂的东西,同时,尽我所能为你提供理解它们的直觉。我的主要任务是让你理解这些算法是如何工作的,并教你如何从头开始编码。就像 Mark Dao ust(tensor flow 的开发者项目工程师)曾经对我说的那样:

每个人都应该从头开始编写一次神经网络代码…但只能编写一次…

所以会有很多代码我打算仔细解释。在这些主题中,你可以期待我将向你展示如何使用我们所学的迷你项目。知识跟随着实践真的很重要。

这种方法将是自下而上的:

  • 底层——基础(和解释的)数学变成 Python NumPy 代码,
  • 中级——tensor flow(TF . nn 和 tf.layer 模块),我已经向您展示的大部分内容都可以在一行代码中自动完成,
  • 高层——非常流行的框架,可以让你非常快速地创建神经网络——Keras。

这个项目将只关注多层感知器。已经有很多工作要做了。如果它成功了,我可能会考虑对卷积神经网络、递归神经网络和生成对抗神经网络进行扩展。

议程

将来,您可以看到涵盖以下主题的文章(顺序可能会改变):

  1. 【25 . 07 . 2018】机器学习的类型
  2. 【1 . 08 . 2018】线性回归(第一部分):初始化和预测
  3. 【8 . 08 . 2018】线性回归(第二部分):成本函数
  4. 【23 . 08 . 2018】线性回归(第三部分):梯度下降训练
  5. [30.08.2018]线性回归(第四部分):矢量化
  6. [06.09.2018]线性回归(第 5 部分):可重复使用的分类器的创建

要涵盖的概念:

  • 逻辑回归和激活函数
  • 多层感知器的思想
  • 用例子详细解释反向传播
  • 梯度检查
  • 为神经网络准备数据—标准化、规范化
  • 激活功能及其背后的直觉
  • Softmax,一个热编码
  • 权重初始化、消失渐变、爆炸渐变
  • 随机梯度下降,小批量,批量梯度下降
  • 乐观主义者
  • 调谐超参数
  • 学习曲线、过度拟合、偏差
  • 正规化的方法——退出、批量正规化

面向初学者的编码深度学习

原文:https://towardsdatascience.com/coding-deep-learning-for-beginners-types-of-machine-learning-b9e651e1ed9d?source=collection_archive---------2-----------------------

Image source: http://www.cognub.com/index.php/cognitive-platform/

机器学习的类型

这是系列“初学者深度学习编码”的第二篇文章。在这里,你可以在第一篇文章 的底部找到所有文章议程的链接,以及关于下一篇文章* 预计发布日期的一般信息。它们也可以在我的开源文件夹— MyRoadToAI 中找到,还有一些迷你项目、演示、教程和链接。*

你也可以在我的个人网站上阅读这篇文章,为了提高可读性(支持代码语法高亮、LaTeX 方程式等等),我的个人网站由 Jekyll 主办。

目标

进入机器学习领域并不是一件容易的事情。我很想爱护读者。这就是为什么有时你会看到只关注理论的文章。因为长文章不鼓励学习,所以我会把它们保持在5-8 分钟的阅读时间。我不能把所有东西都放在一篇文章里——代码片段、数学、术语——因为那样会减少对基本概念的解释。我相信将知识分成更小的部分并扩展到更多的文章中会使学习过程更顺利,因为没有必要停下来走弯路。

机器学习模型

从“模型”的定义开始,这个定义从现在开始会经常出现。如线性回归逻辑回归决策树等名称。只是算法的名字。那些只是理论上的概念,描述了为了达到特定的效果应该做些什么。模型是一个数学公式,它是机器学习算法实现的一个结果(在这些文章的情况下——在代码中)。它有可测量的参数,可用于预测。可以通过修改模型的参数来训练模型,以便获得更好的结果。可以说,模型是机器学习系统从训练数据中学到的东西的表示。

Diagram visualising difference between Machine Learning Algorithm and Machine Learning Model.

机器学习的分支

机器学习有三个最常见的类别:

  • 监督学习
  • 无监督学习
  • 强化学习

监督学习

需要由示例输入输出对组成的 数据集的算法组。每一对由用于进行预测的数据样本和被称为标签的预期结果组成。“受监督的”一词来源于标签需要由人类管理者分配给数据的事实。

在训练过程中,样本被反复输入到模型中。对于每个样本,模型使用参数的当前状态并返回预测。预测与标签相比较,其差异称为误差。误差是对模型的反馈,说明哪里出了问题,以及如何自我更新,以减少未来预测中的误差。这意味着模型将根据其创建所基于的算法改变其参数值。

Diagram demonstrating how Supervised Learning works.

监督学习模型试图找到参数值,使它们能够在历史数据上表现良好。然后,它们用于对未知数据进行预测,这些数据不是训练数据集的一部分。

监督学习可以解决两个主要问题:

  • 分类为输入的数据样本分配类别的过程。示例用途:预测一个人是否生病,检测欺诈交易,人脸分类器。
  • 回归预测输入数据样本的连续数值的过程。示例用途:评估房价,预测杂货店食品需求,温度预测。

Example of Classification and Regression models.

无监督学习

试图从非标记数据中得出推论的一组算法(不参考已知或标记的结果)。在无监督学习中,没有正确答案。基于这种算法的模型可以用来发现未知的数据模式和数据结构本身。

Example of Unsupervised Learning concept. All data is fed to the model and it produces an output on it’s own based on similarity between samples and algorithm used to create the model.

无监督学习最常见的应用是:

  • 模式识别和数据聚类将相似数据样本划分并分组在一起的过程。组通常被称为簇。示例用途:超市分割、用户群分割、信号去噪。
  • 降低数据维度 -数据维度是描述数据样本所需的特征数量。降维是一个过程,将特征压缩成所谓的主值,简洁地传达相似的信息。通过仅选择几个组件,减少了特征的数量,并且在此过程中丢失了一小部分数据。示例用途:通过减少计算次数来加速其他机器学习算法,在数据中找到一组最可靠的特征。

Dividing data from various countries around the world into three clusters representing Developed, Developing and Underdeveloped nations (source: Tableau blog).

强化学习

机器学习算法的分支,产生所谓的代理。代理角色与经典模型略有不同。它从环境中接收信息,并通过执行动作对其做出反应。信息以数字数据的形式提供给代理,称为状态,状态被存储,然后用于选择正确的动作。因此,代理人会收到一个奖励,奖励可以是正的,也可以是负的。奖励是代理可以用来更新其参数的反馈。

代理人的培训是一个试错的过程。为了学习,它需要在各种情况下找到自己,并在每次采取错误行动时受到惩罚。优化目标可以根据强化学习方法以多种方式设定,例如基于价值函数梯度策略环境模型

Interaction between Agent and Environment.

强化学习的应用范围很广。他们中的大多数是发明,经常被认为是人工智能最具创新性的成就。

Example of solutions where Reinforcement Learning is used. From self-driving cars through various games such as Go, Chess, Poker or computer ones — Dota or Starcraft, to manufacturing.

模拟 3D 模型的运动是一项复杂的任务。这种模型需要在给定的环境中与不同的模型进行交互。强化学习正越来越多地被用作解决这一问题的工具,因为它产生的结果对人眼来说似乎非常可信,并且算法能够自动适应描述环境的规则。

Main video accompanying the SIGGRAPH 2018 paper: “DeepMimic: Example-Guided Deep Reinforcement Learning of Physics-Based Character Skill”.

总结

仅此而已。在下一篇文章中,我将解释线性回归算法的基础和实现,这是一种基本的监督学习算法。

下一篇文章

下一篇文章可在这里

公开编码

原文:https://towardsdatascience.com/coding-in-the-open-349e07d25898?source=collection_archive---------6-----------------------

2017 年图灵节上你应该从全栈工程中知道的 3 件事

Coding in the open

艾瑞克·阿特罗斯科

今年图灵节的工程赛道挤满了令人惊叹的演讲者,涵盖了广泛的主题,从英国政府如何免费提供他们的一些服务代码,如何在开源项目中做更好的贡献者,到云的发展方向以及它可以解决什么问题。

我想谈谈三个与开源项目、内部项目和软件开发相关的会议。

公开编码

这一天开始于来自政府数字服务 (GDS)的安娜·希普曼分享她的故事,当用户报告一个问题时,从长达 18 个月的等待获得代码修复,到能够在不到一周的时间内发布用户贡献的代码修复。这是通过取得平台代码的所有权以及公开代码以使每个人都可以对其做出贡献的组合来实现的。由于默认为开源项目,可见性增加,这也意味着服务/代码可以在 GDS 的不同项目中重用。与任何足够大的公司一样,你会有不一定经常在一起工作的人和项目,但是他们都面临类似的问题,并且很可能会针对这些问题制定自己的解决方案。在许多情况下,重复的努力是一种浪费,通过公开代码,他们能够防止这样的情况经常发生。

Skyscanner 我们鼓励内部对项目做出贡献,这样当你发现有些事情不太对劲,或者你看到你可以为之做出贡献的改进时,你就能够并被鼓励采取行动。通过遵循开源项目的原则,我们鼓励每个项目都有一个自述文件,包含入门步骤和投稿指南。通过降低其他人开始工作的门槛,我们增加了人们和团队之间的协作,这些人和团队通常不会在日常基础上相互交流。

Anna Shipman (GDS), Turing Fest 2017

演讲中提到的另一点是,通过公开代码,您可以获得新的反馈。这也导致人们更加关注并质疑他们是否愿意接受某些设计和实现决策,因为这些决策将会向更广泛的受众发布。

为了保持建设性的反馈流,并增加让遇到类似问题的其他人意识到您正在解决或已经解决了这个问题的机会,我们有专门设计的论坛来呈现、回顾、讨论和提供反馈。

贡献

开源也是接下来演讲的主题。Mike McQuaid 谈到了有效的开源交互。我们讨论了与您的操作系统交互的三种不同人群:

  1. 用户
  2. 贡献者
  3. 保持器

我们讨论了每个群体的典型需求,以及人们如何在这些群体之间移动。我们讨论了围绕维护人员的部分职责引入过程如何能够为技术工作腾出时间。我们看了一些为自制软件(迈克是维护者)管理和获取贡献的过程的例子,以及如何减少贡献的摩擦,无论是通过提交错误报告、功能请求还是实际的代码贡献。这是通过为如何恰当地提交错误报告提供清晰的步骤来实现的,自动化了贡献所需的一些令人困惑的(对于经验不足的用户)和耗时的步骤。OSS 项目的关键成分是社区,你希望你的社区积极参与并做出贡献。您的社区中的大多数人将是用户,您将有一些贡献者,维护者的百分比通常会更小。我相信 Mike 称之为追加销售。通过接触用户来吸引你的社区,让他们更多地参与进来,允许他们挠痒痒,并为修复他们发现的问题做出贡献——甚至改善他们已经想了一段时间的事情。

Mike McQuaid talked about effective open source interactions

和任何项目一样,不管是内部的还是其他的,你都会从处理用户反馈、特性请求和用户贡献的过程中受益。当开始一个新项目时,重要的是要考虑你创建的产品/服务/工具是否是你希望人们为之做出贡献的东西。也许这将是他们生产道路的一部分。如果是这样的话,你应该创建一个清晰的贡献指南以及一套规则,在项目生命周期的早期设定对贡献的期望。这样你就可以把最大的时间花在软件本身上,而不是(例如,当项目获得牵引力时)处理不断涌入的需要你宝贵注意力的请求。

这是我们想要做好的事情。我们有许多项目,合并请求源源不断地到来。在许多情况下都有很好的支持文档,而且投稿过程通常都经过了深思熟虑。但这并不意味着我们不能变得更好,无论是涉及架构的变化以确保迭代可以更快更容易地实现,还是改变团队处理外部请求的方式,同时照顾他们自己的 backlog。

在更个人的层面上,几年前我曾经嘲笑通过写文档、投稿指南和仔细考虑这些问题来开始一个项目的想法。我想从架构的角度解决一个问题,弄清楚实现将从哪里开始,以及什么是难点。我的现实检查是我的团队第一次继承了一个在生产中运行的服务——没有文档和指南,基本上除了远程访问操作基础设施和源代码什么都没有。当然,我们遇到了一些直接影响生产的问题,上周就需要解决了!所以我们需要问问以前的房主。问题是,最初负责编写服务的工程师已经在三年前离开了公司。

事情在发生,人们在移动,项目在易手,服务经常被遗忘,在后台运行,直到出现问题。问题不在于“是否”会出错,而在于“何时”会出错,因此重要的是要腾出时间来编写文档,并确保未来的项目移交是无痛和无缝的——而不是在项目结束时疯狂地匆忙或事后思考(因为让我们面对现实吧,如果在长期运行或延迟的项目结束时要删除一些东西,那肯定是文档)。

炉边谈话

当天的第三场会议是与迈克尔·普赖尔(Fog Creek Software、Trello 和 Stack Overflow 的创始人)和约翰·皮布尔斯(爱丁堡创业公司行政的首席执行官)的炉边聊天。作为一个每天与 Stack Overflow 和 Trello 打交道的人,我发现听一听参与创建这两家公司的人说些什么很有意思。

对话把我们带回到博客还不存在的时候,也没有一种简单的方法来为开发者分享想法和经验。虽然当时有一些公司关注这一点,但数量非常少。开发人员主要履行支持角色,这导致了不满——但最终也认识到事情可以(并且应该)以更好的方式完成。

就在那时,迈克尔和乔尔·斯波尔斯基决定创办自己的公司,并弄清楚怎样才能建立一家工程师们希望 T1 去工作的公司。聆听他们使用 Fog Creek 软件的历程、他们学到的经验、犯过的错误以及他们设法学到的东西,也是一次令人谦卑的经历。

我最喜欢的一句话是:

"我们经历了十年的失败,建立了堆栈溢出."

人们往往倾向于认为那些已经取得很大成就的人并没有犯很多错误,他们只是第一次尝试就把事情做对了。那里躺着疯狂;很容易给自己施加巨大的、不必要的压力,消耗时间、理智和生产力。许多成功人士犯了错误,但仍然继续做着伟大的事情,那么为什么要陷在没有结果的事情上呢?我从这次演讲中得到的主要启示是,要预料到会犯错误,不要担心会犯错误,而是要从中吸取教训……下次做得更好,不管你在做什么。

那么……判决。

我参加了这两天的会议,参加了所有专题(战略、产品、工程和营销)的混合会议,很容易说这是一次精彩的会议,有强大的阵容和出色的演讲者。讨论的话题范围很广,这意味着每个人都有感兴趣和有价值的东西。

与我们合作

我们在 Skyscanner 以不同的方式做事,我们正在全球办事处寻找更多的工程团队成员。看看我们的 Skyscanner 职位寻找更多空缺。

Team in Action

关于作者

我是 Irek Atroszko,是 Skyscanner 的软件工程师。我主要从事后端服务。工作之余,我的兴趣主要在于上好的咖啡、书籍、锋利的日本刀和定期的苏格兰徒步旅行。

Irek Atroszko, Skyscanner

编码神经网络—辍学

原文:https://towardsdatascience.com/coding-neural-network-dropout-3095632d25ce?source=collection_archive---------3-----------------------

Figure 1: Dropout

辍学是一种正规化技术。在每次迭代中,我们随机关闭每层上的一些神经元(单元),并且在前向传播和反向传播中都不使用这些神经元。由于在每次迭代中被丢弃的单元将是随机的,学习算法将不知道在每次迭代中哪些神经元将被关闭;因此,强制学习算法分散权重,而不是专注于某些特定特征(单元)。此外,退出有助于通过以下方式改善泛化误差:

  • 因为我们在每次迭代中丢弃一些单元,这将导致更小的网络,这反过来意味着更简单的网络(正则化)。
  • 可以看作是装袋技术的近似。每一次迭代都可以被看作是不同的模型,因为我们在每一层随机放置不同的单元。这意味着误差将是来自所有不同模型(迭代)的误差的平均值。因此,平均来自不同模型的误差,特别是如果这些误差是不相关的,将减少总误差。在误差完全相关的最坏情况下,在所有模型中求平均值根本没有帮助;然而,我们知道在实践中,误差在某种程度上是不相关的。因此,它总是会改善泛化误差。

我们可以在每一层使用不同的概率;然而,输出层将总是具有keep_prob = 1,而输入层具有高keep_prob,例如 0.9 或 1。如果一个隐藏层有keep_prob = 0.8,这意味着;在每次迭代中,每个单元有 80%的概率被包含,20%的概率被删除。

在计算机视觉问题中经常使用 Dropout,因为我们有很多特征,但没有很多数据。此外,相邻的特征(像素)通常不会增加很多信息。所以,模型总是会出现过拟合的情况。

为了说明 dropout 如何帮助我们减少泛化错误,我们将使用我们在以前的帖子中使用的相同数据集。该数据集有猫和非猫的图像。我们将尝试建立一个神经网络来分类图像是否有猫。每幅图像的 RGB 比例为 64 x 64 像素。让我们导入数据,看看形状以及来自训练集的猫图像样本。

# Import training data
train_dataset = h5py.File("../data/train_catvnoncat.h5")
X_train = np.array(train_dataset["train_set_x"])
Y_train = np.array(train_dataset["train_set_y"])

# Plot a sample image
plt.imshow(X_train[50])
plt.axis("off");

# Import test data
test_dataset = h5py.File("../data/test_catvnoncat.h5")
X_test = np.array(test_dataset["test_set_x"])
Y_test = np.array(test_dataset["test_set_y"])

# Transform data
X_train = X_train.reshape(209, -1).T
X_train = X_train / 255
Y_train = Y_train.reshape(-1, 209)

X_test = X_test.reshape(50, -1).T
X_test = X_test / 255
Y_test = Y_test.reshape(-1, 50)

# print the new shape of both training and test datasets
print("Training data dimensions:")
print("X's dimension: {}, Y's dimension: {}".format(X_train.shape, Y_train.shape))
print("Test data dimensions:")
print("X's dimension: {}, Y's dimension: {}".format(X_test.shape, Y_test.shape))Training data dimensions:
X's dimension: (12288, 209), Y's dimension: (1, 209)
Test data dimensions:
X's dimension: (12288, 50), Y's dimension: (1, 50)

Figure 2: Sample image

现在,我们将编写在前向传播和反向传播上应用压差所需的函数。请注意,我们将利用我们在以前的帖子中编写的函数,如initialize_parameters

def drop_out_matrices(layers_dims, m, keep_prob):
    np.random.seed(1)
    D = {}
    L = len(layers_dims)

    for l in range(L):
        # initialize the random values for the dropout matrix
        D[str(l)] = np.random.rand(layers_dims[l], m)
        # Convert it to 0/1 to shut down neurons corresponding to each element
        D[str(l)] = D[str(l)] < keep_prob[l]
        assert(D[str(l)].shape == (layers_dims[l], m))
    return D

def L_model_forward(
   X, parameters, D, keep_prob, hidden_layers_activation_fn="relu"):
    A = X                           # since input matrix A0
    A = np.multiply(A, D[str(0)])
    A /= keep_prob[0]
    caches = []                     # initialize the caches list
    L = len(parameters) // 2        # number of layer in the network

    for l in range(1, L):
        A_prev = A
        A, cache = linear_activation_forward(
            A_prev, parameters["W" + str(l)], parameters["b" + str(l)],
            hidden_layers_activation_fn)
        # shut down some units
        A = np.multiply(A, D[str(l)])
        # scale that value of units to keep expected value the same
        A /= keep_prob[l]
        caches.append(cache)

    AL, cache = linear_activation_forward(
        A, parameters["W" + str(L)], parameters["b" + str(L)], "sigmoid")
    AL = np.multiply(AL, D[str(L)])
    AL /= keep_prob[L]
    caches.append(cache)
    assert(AL.shape == (1, X.shape[1]))

    return AL, caches

def L_model_backward(
   AL, Y, caches, D, keep_prob, hidden_layers_activation_fn="relu"):
    Y = Y.reshape(AL.shape)
    L = len(caches)
    grads = {}

    # dA for output layer
    dAL = np.divide(AL - Y, np.multiply(AL, 1 - AL))
    dAL = np.multiply(dAL, D[str(L)])
    dAL /= keep_prob[L]

    grads["dA" + str(L - 1)], grads["dW" + str(L)], grads[
        "db" + str(L)] = linear_activation_backward(
            dAL, caches[L - 1], "sigmoid")
    grads["dA" + str(L - 1)] = np.multiply(
        grads["dA" + str(L - 1)], D[str(L - 1)])
    grads["dA" + str(L - 1)] /= keep_prob[L - 1]

    for l in range(L - 1, 0, -1):
        current_cache = caches[l - 1]
        grads["dA" + str(l - 1)], grads["dW" + str(l)], grads[
            "db" + str(l)] = linear_activation_backward(
                grads["dA" + str(l)], current_cache,
                hidden_layers_activation_fn)

        grads["dA" + str(l - 1)] = np.multiply(
            grads["dA" + str(l - 1)], D[str(l - 1)])
        grads["dA" + str(l - 1)] /= keep_prob[l - 1]

    return grads

def model_with_dropout(
        X, Y, layers_dims, keep_prob, learning_rate=0.01, num_iterations=3000,
        print_cost=True, hidden_layers_activation_fn="relu"):
    # get number of examples
    m = X.shape[1]

    # to get consistents output
    np.random.seed(1)

    # initialize parameters
    parameters = initialize_parameters(layers_dims)

    # intialize cost list
    cost_list = []

    # implement gradient descent
    for i in range(num_iterations):
        # Initialize dropout matrices
        D = drop_out_matrices(layers_dims, m, keep_prob)

        # compute forward propagation
        AL, caches = L_model_forward(
            X, parameters, D, keep_prob, hidden_layers_activation_fn)

        # compute regularized cost
        cost = compute_cost(AL, Y)

        # compute gradients
        grads = L_model_backward(
            AL, Y, caches, D, keep_prob, hidden_layers_activation_fn)

        # update parameters
        parameters = update_parameters(parameters, grads, learning_rate)

        # print cost
        if (i + 1) % 100 == 0 and print_cost:
            print(f"The cost after {i + 1} iterations : {cost:.4f}.")
        # append cost
        if i % 100 == 0:
            cost_list.append(cost)

    # plot the cost curve
    plt.plot(cost_list)
    plt.xlabel("Iteration (per hundreds)")
    plt.ylabel("Cost")
    plt.title(f"Cost curve for the learning rate = {learning_rate}")

    return parameters

最后,我们准备好建立我们的神经网络。首先,我们将建立一个完全连接的网络,没有掉线。也就是说,keep_prob = 1。接下来,我们将建立另一个网络。最后,我们将比较两个网络的泛化误差,并看看丢弃技术如何帮助我们改善泛化误差。

# setup layers dimensions, number of examples, and keep probabilities list
m = X_train.shape[0]
keep_prob = [1, 1, 1, 1]
layers_dims = [m, 10, 10, 1]

# train NN with no dropout
parameters = model_with_dropout(X_train, Y_train, layers_dims,      keep_prob=keep_prob, learning_rate=0.03, num_iterations=1000, hidden_layers_activation_fn="relu")

# print the test accuracy
print("The training accuracy rate: {}".format(accuracy(X_train, parameters, Y_train, "relu")[-7:]))
print("The test accuracy rate: {}".format(accuracy(X_test, parameters, Y_test, "relu")[-7:]))The cost after 100 iterations : 0.6555.
The cost after 200 iterations : 0.6468.
The cost after 300 iterations : 0.6447.
The cost after 400 iterations : 0.6442.
The cost after 500 iterations : 0.6440.
The cost after 600 iterations : 0.6440.
The cost after 700 iterations : 0.6440.
The cost after 800 iterations : 0.6440.
The cost after 900 iterations : 0.6440.
The cost after 1000 iterations : 0.6440.
The training accuracy rate: 65.55%.
The test accuracy rate: 34.00%.

Figure 3: Cost curve with no dropout

# setup keep probabilities list
keep_prob = [1, 0.5, 0.5, 1]

# train NN with no dropout
parameters = model_with_dropout(X_train, Y_train, layers_dims,      keep_prob=keep_prob, learning_rate=0.03, num_iterations=1000, hidden_layers_activation_fn="relu")

# print the test accuracy
print("The training accuracy rate: {}".format(accuracy(X_train, parameters, Y_train, "relu")[-7:]))
print("The test accuracy rate: {}".format(accuracy(X_test, parameters, Y_test, "relu")[-7:]))The cost after 100 iterations : 0.6555.
The cost after 200 iterations : 0.6467.
The cost after 300 iterations : 0.6445.
The cost after 400 iterations : 0.6437.
The cost after 500 iterations : 0.6412.
The cost after 600 iterations : 0.6338.
The cost after 700 iterations : 0.6108.
The cost after 800 iterations : 0.5367.
The cost after 900 iterations : 0.4322.
The cost after 1000 iterations : 0.3114.
The training accuracy rate: 74.16%.
The test accuracy rate: 44.00%.

Figure 4: Cost curve with dropout

以上结果表明,有丢包的网络测试准确率提高了 30%。请注意,这只是一个说明性的例子,以显示辍学技术的有效性。在这个例子中,我们选择了任意的概率;然而,我们可以调整每一层上的丢弃概率,以产生最佳的验证损失和准确性。

结论

Dropout 是一种非常有效的正则化技术,在卷积神经网络中被大量使用。以下是一些要点:

  • 使用梯度检测时设置keep_prob = 1;不然就不行了。
  • 辍学仅在培训期间使用。不要在测试/预测新示例时使用它。
  • keep_prob越低→神经网络越简单。随着keep_prob的减少,偏差增加,方差减少。因此,具有更多神经元的层预期具有较低的keep_prob以避免过度拟合。
  • 在计算上,这是一种改善泛化误差和帮助解决过度拟合的廉价方法。
  • 人们可以调整keep_prob来获得手头任务的最佳结果。

创建这篇文章的源代码可以在这里找到。帖子的灵感来自 deeplearning.ai 课程。

原载于 2018 年 5 月 20 日imaddabbura . github . io

编码神经网络——前向传播和反向传播

原文:https://towardsdatascience.com/coding-neural-network-forward-propagation-and-backpropagtion-ccf8cf369f76?source=collection_archive---------1-----------------------

为什么是神经网络?

根据通用逼近定理,给定足够大的层和期望的误差范围,神经网络可以逼近、学习和表示任何函数。神经网络学习真正功能的方式是在简单的基础上建立复杂的表示。在每个隐藏层上,神经网络通过首先计算给定输入的仿射(线性)变换,然后应用非线性函数来学习新的特征空间,该非线性函数又将成为下一层的输入。这一过程将继续下去,直到我们到达输出层。因此,我们可以将神经网络定义为从输入端通过隐含层流向输出端的信息流。对于一个三层神经网络,学习的函数将是: f(x) = f_3(f_2(f_1(x))) 其中:

  • f1(x):在第一个隐藏层学习的函数
  • F2(x):在第二隐藏层学习的函数
  • F3(x):在输出层学习的功能

因此,在每一层上,我们学习不同的表现,随着后面的隐藏层变得更加复杂。下面是一个 3 层神经网络的例子(我们不考虑输入层):

Figure 1: Neural Network with two hidden layers

比如计算机不能直接理解图像,不知道如何处理像素数据。然而,神经网络可以在识别边缘的早期隐藏层中建立图像的简单表示。给定第一个隐藏层输出,它可以学习拐角和轮廓。给定第二个隐藏层,它可以学习鼻子等部位。最后,它可以学习对象身份。

由于真相从来都不是线性的并且表示对于机器学习算法的性能非常关键,神经网络可以帮助我们建立非常复杂的模型,并将其留给算法来学习这种表示,而不必担心特征工程,这需要从业者花费非常长的时间和精力来策划一个好的表示。

这篇文章有两部分:

  1. 神经网络编码:这需要编写所有的助手函数,使我们能够实现一个多层神经网络。在这样做的时候,我会尽可能地解释理论部分,并给出一些实现上的建议。
  2. 应用:我们将实现我们在第一部分中编写的关于图像识别问题的神经网络,看看我们构建的网络是否能够检测图像中是否有猫或狗,并看到它在工作:)

这篇文章将是一系列文章中的第一篇,涵盖了在 numpy 中实现神经网络,包括梯度检查,参数初始化,L2 正则化,丢失。创建这篇文章的源代码可以在这里找到。

# Import packages
import h5py import
matplotlib.pyplot as plt
import numpy as np
import seaborn as sns

I .神经网络编码

正向传播

输入 X 提供初始信息,然后传播到每层的隐藏单元,并最终产生输出 y^.。网络的架构需要确定其深度、宽度和每层使用的激活函数。深度是隐藏层数。宽度是每个隐藏层上的单元(节点)数量,因为我们不控制输入层和输出层的尺寸。有相当多组激活函数,如整流线性单元、Sigmoid、双曲线正切等。研究已经证明,更深的网络优于具有更多隐藏单元的网络。因此,培养一个更深层次的关系网(收益递减)总是更好,也不会有坏处。

让我们首先介绍一些将在本文中使用的符号:

接下来,我们将以通用形式写下多层神经网络的维度,以帮助我们进行矩阵乘法,因为实现神经网络的主要挑战之一是获得正确的维度。

我们需要实现前向传播的两个方程是:这些计算将发生在每一层上。

参数初始化

我们将首先初始化权重矩阵和偏差向量。值得注意的是,我们不应该将所有参数初始化为零,因为这样做会导致梯度相等,并且每次迭代的输出都是相同的,学习算法不会学到任何东西。因此,将参数随机初始化为 0 到 1 之间的值很重要。还建议将随机值乘以小标量,如 0.01,以使激活单元处于活动状态,并位于激活函数导数不接近零的区域。

激活功能

对于哪种激活功能在特定问题上效果最好,没有明确的指导。这是一个反复试验的过程,人们应该尝试不同的功能集,看看哪一个最适合手头的问题。我们将介绍 4 种最常用的激活功能:

  • 乙状结肠函数(σ):g(z)=1/(1+e^{-z})。建议仅在输出图层上使用,这样我们可以很容易地将输出解释为概率,因为它将输出限制在 0 和 1 之间。在隐藏层上使用 sigmoid 函数的一个主要缺点是,在其域的大部分上,梯度非常接近于零,这使得学习算法学习起来缓慢且困难。
  • 双曲正切函数:g(z)=(e^z -e{-z})/(ez+e^{-z})。它优于 sigmoid 函数,在 sigmoid 函数中,其输出的平均值非常接近零,换句话说,它将激活单元的输出集中在零附近,并使值的范围非常小,这意味着学习速度更快。它与 sigmoid 函数共有的缺点是在域的好的部分上梯度非常小。
  • 整流线性单元(ReLU):g(z)**= max { 0,z} 。接近线性的模型易于优化。由于 ReLU 与线性函数有许多相同的性质,它在大多数问题上都表现得很好。唯一的问题是导数没有定义在 z = 0 ,我们可以通过在 z = 0 将导数赋值为 0 来解决这个问题。然而,这意味着对于 z ≤ 0,梯度为零,再次无法学习。
  • 漏整流线性单元:g(z)=max {α z,z}* 。它克服了 ReLU 的零梯度问题,并为 z ≤ 0 指定了一个小值 α

如果你不确定选择哪个激活函数,从 ReLU 开始。接下来,我们将实现上面的激活函数,并为每个函数绘制一个图表,以便更容易地看到每个函数的域和范围。

正向输送

给定来自前一层的输入,每个单元计算仿射变换 z = W^Tx + b ,然后应用激活函数 g(z) ,例如 ReLU 元素方式。在这个过程中,我们将存储(缓存)在每一层上计算和使用的所有变量,以便在反向传播中使用。我们将编写将在 L 模型正向传播中使用的前两个助手函数,以使其更易于调试。请记住,在每一层上,我们可能有不同的激活函数。

费用

我们将使用二元交叉熵成本。它使用对数似然法来估计其误差。代价是:上述代价函数是凸的;然而,神经网络通常会陷入局部极小值,不能保证找到最优参数。我们将在这里使用基于梯度的学习。

反向传播

允许信息通过网络从成本回溯,以计算梯度。因此,以相反的拓扑顺序从最终节点开始循环遍历节点,以计算最终节点输出相对于每条边的节点尾部的导数。这样做将帮助我们知道谁对最大的错误负责,并在那个方向上改变参数。下面的导数公式将帮助我们编写反向传播函数:因为 b^l 总是一个向量,所以总和将是跨行的(因为每一列都是一个例子)。

二。应用

我们将要处理的数据集有 209 张图片。每幅图像的 RGB 比例为 64 x 64 像素。我们将建立一个神经网络来分类图像是否有猫。因此,* 。*

  • 我们将首先加载图像。
  • 显示猫的样本图像。
  • 改变输入矩阵的形状,使每一列都成为一个示例。此外,由于每张图片的大小为 64 x 64 x 3,因此每张图片有 12,288 个特征。因此,输入矩阵应为 12,288 x 209。
  • 将数据标准化,这样梯度就不会失控。此外,它将有助于隐藏单位有类似的价值范围。现在,我们将每个像素除以 255,这应该不成问题。但是,最好将数据标准化为平均值为 0,标准差为 1。
*Original dimensions:
--------------------
Training: (209, 64, 64, 3), (209,)
Test: (50, 64, 64, 3), (50,)New dimensions:
---------------
Training: (12288, 209), (1, 209)
Test: (12288, 50), (1, 50)*

Figure 3: Sample image

现在,我们的数据集已准备好用于测试我们的神经网络实现。先写多层模型函数,用预定义的迭代次数和学习速率实现基于梯度的学习。

接下来,我们将训练两个版本的神经网络,其中每个将在隐藏层上使用不同的激活函数:一个将使用整流线性单元( ReLU ),第二个将使用双曲正切函数( tanh )。最后,我们将使用从两个神经网络中获得的参数对训练示例进行分类,并计算每个版本的训练准确率,以查看哪个激活函数在这个问题上效果最好。

*# Setting layers dims
layers_dims = [X_train.shape[0], 5, 5, 1]# NN with tanh activation fn
parameters_tanh = L_layer_model( X_train, y_train, layers_dims, learning_rate=0.03, num_iterations=3000, hidden_layers_activation_fn="tanh")# Print the accuracy
accuracy(X_test, parameters_tanh, y_test, activation_fn="tanh")The cost after 100 iterations is: 0.6556 
The cost after 200 iterations is: 0.6468
The cost after 300 iterations is: 0.6447
The cost after 400 iterations is: 0.6441
The cost after 500 iterations is: 0.6440
The cost after 600 iterations is: 0.6440
The cost after 700 iterations is: 0.6440
The cost after 800 iterations is: 0.6439
The cost after 900 iterations is: 0.6439
The cost after 1000 iterations is: 0.6439
The cost after 1100 iterations is: 0.6439
The cost after 1200 iterations is: 0.6439
The cost after 1300 iterations is: 0.6438
The cost after 1400 iterations is: 0.6438
The cost after 1500 iterations is: 0.6437
The cost after 1600 iterations is: 0.6434
The cost after 1700 iterations is: 0.6429
The cost after 1800 iterations is: 0.6413
The cost after 1900 iterations is: 0.6361
The cost after 2000 iterations is: 0.6124
The cost after 2100 iterations is: 0.5112
The cost after 2200 iterations is: 0.5288
The cost after 2300 iterations is: 0.4312
The cost after 2400 iterations is: 0.3821
The cost after 2500 iterations is: 0.3387
The cost after 2600 iterations is: 0.2349
The cost after 2700 iterations is: 0.2206
The cost after 2800 iterations is: 0.1927
The cost after 2900 iterations is: 0.4669
The cost after 3000 iterations is: 0.1040 'The accuracy rate is: 68.00%.'*

Figure 4: Loss curve with tanh activation function

*# NN with relu activation fn
parameters_relu = L_layer_model( X_train, y_train, layers_dims, learning_rate=0.03, num_iterations=3000, hidden_layers_activation_fn="relu")# Print the accuracy
accuracy(X_test, parameters_relu, y_test, activation_fn="relu")The cost after 100 iterations is: 0.6556
The cost after 200 iterations is: 0.6468
The cost after 300 iterations is: 0.6447
The cost after 400 iterations is: 0.6441
The cost after 500 iterations is: 0.6440
The cost after 600 iterations is: 0.6440 
The cost after 700 iterations is: 0.6440 
The cost after 800 iterations is: 0.6440 
The cost after 900 iterations is: 0.6440 
The cost after 1000 iterations is: 0.6440 
The cost after 1100 iterations is: 0.6439 
The cost after 1200 iterations is: 0.6439 
The cost after 1300 iterations is: 0.6439 
The cost after 1400 iterations is: 0.6439 
The cost after 1500 iterations is: 0.6439 
The cost after 1600 iterations is: 0.6439 
The cost after 1700 iterations is: 0.6438 
The cost after 1800 iterations is: 0.6437 
The cost after 1900 iterations is: 0.6435 
The cost after 2000 iterations is: 0.6432 
The cost after 2100 iterations is: 0.6423 
The cost after 2200 iterations is: 0.6395 
The cost after 2300 iterations is: 0.6259 
The cost after 2400 iterations is: 0.5408 
The cost after 2500 iterations is: 0.5262 
The cost after 2600 iterations is: 0.4727 
The cost after 2700 iterations is: 0.4386 
The cost after 2800 iterations is: 0.3493 
The cost after 2900 iterations is: 0.1877 
The cost after 3000 iterations is: 0.3641'The accuracy rate is: 42.00%.'*

Figure 5: Loss curve with ReLU activation function

请注意,上述准确率预计会高估概化准确率。

结论

这篇文章的目的是一步一步地编写深度神经网络,并解释其中的重要概念。我们现在并不关心准确率,因为我们可以做很多事情来提高准确率,这将是后续帖子的主题。以下是一些要点:

  • 即使神经网络可以表示任何函数,它也可能因为两个原因而无法学习:
  1. 优化算法可能无法找到期望(真实)函数的参数的最佳值。它会陷入局部最优。
  2. 由于过拟合,学习算法可能发现不同于预期函数的不同函数形式。
  • 即使神经网络很少收敛,总是陷入局部极小值,它仍然能够显著降低成本,并以高测试精度提出非常复杂的模型。
  • 我们在这篇文章中使用的神经网络是标准的全连接网络。然而,还有另外两种网络:
  1. 卷积神经网络:不是所有的节点都连接在一起。图像识别类最好。
  2. 递归神经网络:有一个反馈连接,模型的输出反馈到它自己。它主要用于序列建模。
  • 完全连接的神经网络也会忘记前面步骤中发生的事情,并且也不知道关于输出的任何事情。
  • 我们可以使用交叉验证来调整许多超参数,以获得最佳的网络性能:
  1. 学习率(α):决定每次参数更新的步长。

A.小α会导致收敛缓慢,并且可能会在计算上变得非常昂贵。

B.大的α可能会导致超调,我们的学习算法可能永远不会收敛。

2.隐藏的层数(深度):隐藏的层数越多越好,但是要付出计算的代价。

3.每层隐藏单元的数量(宽度):研究证明,每层大量的隐藏单元并不能改善网络。

4.激活函数:在不同的应用程序和领域中,在隐藏层上使用的函数是不同的。这是一个反复试验的过程,尝试不同的功能,看看哪一个效果最好。

5.迭代次数。

  • 标准化数据将有助于激活单元具有相似的值范围,并避免梯度失控。

原载于 2018 年 4 月 1 日imaddabbura . github . io

编码神经网络—梯度检验

原文:https://towardsdatascience.com/coding-neural-network-gradient-checking-5222544ccc64?source=collection_archive---------4-----------------------

在之前的帖子编码神经网络——前向传播和反向传播中,我们在numpy中实现了前向传播和反向传播。然而,从头开始实现反向传播通常更能减少错误。因此,在对训练数据运行神经网络之前,有必要检查我们的反向传播实现是否正确。在我们开始之前,让我们重温一下什么是反向传播:我们从最后一个节点开始,以相反的拓扑顺序遍历节点,计算成本相对于每条边的节点尾部的导数。换句话说,我们计算成本函数相对于所有参数的导数,即∂J/∂θ,其中θ表示模型的参数。

测试我们实现的方法是计算数值梯度,并与反向传播(分析)的梯度进行比较。有两种计算数值梯度方法:

  • 右侧表格:

  • 双面形式(见图 1):

Figure 1: Two-sided numerical gradients

近似导数的双侧形式比右侧形式更接近。让我们用下面的例子来说明,使用函数 f(x) = x ,在对 x = 3 求导。

  • 分析导数:

  • 双侧数值导数;

  • 右手数值导数:

如上所述,解析导数和双边数值梯度之间的差异几乎为零;但是解析导数和右侧导数相差 0.01。因此,我们将使用双边ε方法来计算数值梯度。

此外,我们将标准化数值之间的差异。使用以下公式的梯度和分析梯度:如果差值≤ 10e-7,那么我们的实现是好的;否则,我们会在某处出错,不得不返回并重新访问反向传播代码。

以下是实施梯度检查所需的步骤:

  1. 在计算数值梯度和分析梯度时,从训练数据中选择随机数量的示例来使用它。
  • 不要使用训练数据中的所有示例,因为梯度检查非常慢。

2.初始化参数。

3.计算前向传播和交叉熵成本。

4.使用我们的反向传播实现来计算梯度。

5.使用双边ε方法计算数值梯度。

6.计算数值梯度和分析梯度之间的差异。

我们将使用我们在“编码神经网络-前向传播和后向传播”帖子中编写的函数来初始化参数,计算前向传播和后向传播以及交叉熵成本。

我们先导入数据。

# Loading packages
import sys
import h5py
import matplotlib.pyplot as plt
import numpy as np
from numpy.linalg import normimport seaborn as sns sys.path.append("../scripts/")
from coding_neural_network_from_scratch import (initialize_parameters, L_model_forward, L_model_backward, compute_cost)# Import the data
train_dataset = h5py.File("../data/train_catvnoncat.h5")
X_train = np.array(train_dataset["train_set_x"]).T
y_train = np.array(train_dataset["train_set_y"]).T
X_train = X_train.reshape(-1, 209)
y_train = y_train.reshape(-1, 209)X_train.shape, y_train.shape((12288, 209), (1, 209))

接下来,我们将编写帮助器函数,帮助将参数和梯度字典转换成向量,然后再将它们转换回字典。

def dictionary_to_vector(params_dict):
L = len(layers_dims)
parameters = {}
k = 0
for l in range(1, L):
# Create temp variable to store dimension used on each layer
w_dim = layers_dims[l] * layers_dims[l - 1]
b_dim = layers_dims[l]
# Create temp var to be used in slicing parameters vector
temp_dim = k + w_dim
# add parameters to the dictionary
parameters["W" + str(l)] = vector[ k:temp_dim].reshape(layers_dims[l], layers_dims[l - 1]) 
parameters["b" + str(l)] = vector[ temp_dim:temp_dim + b_dim].reshape(b_dim, 1)
k += w_dim + b_dim
return parametersdef gradients_to_vector(gradients):
# Get the number of indices for the gradients to iterate over valid_grads = [key for key in gradients.keys() if not key.startswith("dA")]
L = len(valid_grads)// 2
count = 0
# Iterate over all gradients and append them to new_grads list
for l in range(1, L + 1):
if count == 0:
new_grads = gradients["dW" + str(l)].reshape(-1, 1)
new_grads = np.concatenate((new_grads, gradients["db" + str(l)].reshape(-1, 1)))
else:
new_grads = np.concatenate((new_grads, gradients["dW" + str(l)].reshape(-1, 1)))
new_grads = np.concatenate( (new_grads, gradients["db" + str(l)].reshape(-1, 1)))
count += 1
return new_grads

最后,我们将编写梯度检查函数,它将计算解析梯度和数值梯度之间的差异,并告诉我们反向传播的实现是否正确。我们将随机选择一个例子来计算差异。

def forward_prop_cost(X, parameters, Y, hidden_layers_activation_fn="tanh"):
# Compute forward prop
AL, _ = L_model_forward(X, parameters, hidden_layers_activation_fn) # Compute cost
cost = compute_cost(AL, Y)
return cost def gradient_check( parameters, gradients, X, Y, layers_dims, epsilon=1e-7, hidden_layers_activation_fn="tanh"):
# Roll out parameters and gradients dictionaries
parameters_vector = dictionary_to_vector(parameters) gradients_vector = gradients_to_vector(gradients)
# Create vector of zeros to be used with epsilon
grads_approx = np.zeros_like(parameters_vector)
for i in range(len(parameters_vector)):
# Compute cost of theta + epsilon
theta_plus = np.copy(parameters_vector)
theta_plus[i] = theta_plus[i] + epsilon
j_plus = forward_prop_cost( X, vector_to_dictionary(theta_plus, layers_dims), Y, hidden_layers_activation_fn)
# Compute cost of theta - epsilon
theta_minus = np.copy(parameters_vector)
theta_minus[i] = theta_minus[i] - epsilon
j_minus = forward_prop_cost( X, vector_to_dictionary(theta_minus, layers_dims), Y, hidden_layers_activation_fn)
# Compute numerical gradients
grads_approx[i] = (j_plus - j_minus) / (2 * epsilon)# Compute the difference of numerical and analytical gradients numerator = norm(gradients_vector - grads_approx)
denominator = norm(grads_approx) + norm(gradients_vector)
difference = numerator / denominatorif difference > 10e-7:
print ("\033[31mThere is a mistake in back-propagation " +\ "implementation. The difference is: {}".format(difference))
else:
print ("\033[32mThere implementation of back-propagation is fine! "+\ "The difference is: {}".format(difference))return difference# Set up neural network architecture
layers_dims = [X_train.shape[0], 5, 5, 1]# Initialize parameters parameters = initialize_parameters(layers_dims)# Randomly selecting 1 example from training data
perms = np.random.permutation(X_train.shape[1])
index = perms[:1]# Compute forward propagation
AL, caches = L_model_forward(X_train[:, index], parameters, "tanh") # Compute analytical gradients
gradients = L_model_backward(AL, y_train[:, index], caches, "tanh") # Compute difference of numerical and analytical gradients difference = gradient_check(parameters, gradients, X_train[:, index], y_train[:, index], layers_dims)There implementation of back-propagation is fine! The difference is: 3.0220555297630148e-09

恭喜你!我们的实现是正确的:)

结论

以下是一些关键要点:

  1. 双侧数值梯度比右侧形式更接近解析梯度。

2.因为梯度检查非常慢:

  • 将它应用到一个或几个训练例子中。
  • 在确定反向传播的实现是正确的之后,在训练神经网络时关闭它。

3.应用退出方法时,梯度检查不起作用。使用 keep-prob = 1 检查梯度检查,然后在训练神经网络时更改它。

4.ε= 10e-7 是用于分析梯度和数值梯度之差的常用值。如果差值小于 10e-7,则反向传播的实现是正确的。

5.感谢 Tensorflow 和 Pytorch 等深度学习框架,我们可能会发现自己很少实现反向传播,因为这样的框架为我们计算;然而,要成为一名优秀的深度学习实践者,了解幕后发生的事情是一个很好的实践。

创建这篇文章的源代码可以在[这里](http://(https://github.com/ImadDabbura/blog-posts/blob/master/notebooks/Coding-Neural-Network-Gradient-Checking.ipynb)找到。

原载于 2018 年 4 月 8 日imaddabbura . github . io

编码神经网络——参数初始化

原文:https://towardsdatascience.com/coding-neural-network-parameters-initialization-f7c2d770e874?source=collection_archive---------4-----------------------

在机器学习/深度学习的背景下,优化是改变模型参数以提高其性能的过程。换句话说,它是在预定义的假设空间中寻找最佳参数以获得最佳性能的过程。有三种优化算法:

  • 非迭代优化算法,仅求解一个点。
  • 本质上是迭代的优化算法,并且收敛到可接受的解决方案,而不管参数初始化,例如应用于逻辑回归的梯度下降。
  • 本质上是迭代的优化算法,应用于一组具有非凸损失函数的问题,如神经网络。因此,参数的初始化对于加快收敛速度和降低错误率起着至关重要的作用。

在这篇文章中,我们将看看参数初始化的三种不同情况,看看这是如何影响错误率的:

  1. 将所有参数初始化为零。
  2. 将参数初始化为标准正态分布或均匀分布的随机值,并乘以一个标量,如 10。
  3. 基于以下内容初始化参数:
  • 泽维尔推荐。
  • 何推荐。

我们将使用我们在 “编码神经网络-正向传播和反向传播” 帖子中编写的函数来初始化参数,计算正向传播和反向传播以及交叉熵成本。

为了说明上述情况,我们将使用猫和狗的数据集,该数据集由 50 幅猫的图像和 50 幅狗的图像组成。每幅图像的 RGB 色标为 150 像素 x 150 像素。因此,我们将拥有 67,500 个特征,其中输入矩阵中的每一列都是一幅图像,这意味着我们的输入数据将具有 67,500 x 100 的维度。

在启动辅助函数之前,让我们先加载数据并展示两幅图像的样本。

Figure 1: Sample images

我们现在将编写所有帮助函数,帮助我们基于不同的方法初始化参数,并编写 L 层模型,用于训练我们的神经网络。

将所有参数初始化为零

在这里,我们将初始化所有的权重矩阵和偏差为零,看看这将如何影响错误率以及学习参数。

# train NN with zeros initialization parameters
layers_dims = [X.shape[0], 5, 5, 1]
parameters = model(X, Y, layers_dims, hidden_layers_activation_fn="tanh", initialization_method="zeros") accuracy(X, parameters, Y,"tanh")The cost after 100 iterations is: 0.6931471805599453
The cost after 200 iterations is: 0.6931471805599453
The cost after 300 iterations is: 0.6931471805599453
The cost after 400 iterations is: 0.6931471805599453
The cost after 500 iterations is: 0.6931471805599453
The cost after 600 iterations is: 0.6931471805599453
The cost after 700 iterations is: 0.6931471805599453
The cost after 800 iterations is: 0.6931471805599453
The cost after 900 iterations is: 0.6931471805599453
The cost after 1000 iterations is: 0.6931471805599453 The accuracy rate is: 50.00%.

Figure 2: Cost curve using zero intialization method

如成本曲线所示,神经网络什么都没学到!这是因为所有神经元之间的对称性导致所有神经元在每次迭代中都具有相同的更新。因此,不管我们运行优化算法多少次迭代,所有的神经元仍然会得到相同的更新,并且不会发生学习。因此,在初始化参数时,我们必须打破对称性,以便模型在梯度下降的每次更新时开始学习。

用大随机值初始化参数

如果从标准正态分布或均匀分布初始化随机值,没有很大的区别,所以我们将在我们的例子中使用标准正态分布。此外,我们将随机值乘以一个大的数,比如 10,以表明将参数初始化为大值可能会导致我们的优化具有更高的错误率(在某些情况下甚至会发散)。现在让我们训练我们的神经网络,其中所有的权重矩阵已经使用下面的公式初始化:np.random.randn() * 10

# train NN with random initialization parameters
layers_dims = [X.shape[0], 5, 5, 1]
parameters = model(X, Y, layers_dims, hidden_layers_activation_fn="tanh", initialization_method="random") accuracy(X, parameters, Y,"tanh")The cost after 100 iterations is: 1.2413142077549013
The cost after 200 iterations is: 1.1258751902393416
The cost after 300 iterations is: 1.0989052435267657
The cost after 400 iterations is: 1.0840966471282327
The cost after 500 iterations is: 1.0706953292105978
The cost after 600 iterations is: 1.0574847320236294
The cost after 700 iterations is: 1.0443168708889223
The cost after 800 iterations is: 1.031157857251139
The cost after 900 iterations is: 1.0179838815204902
The cost after 1000 iterations is: 1.004767088515343 The accuracy rate is: 55.00%.

Figure 3: Cost curve using random initialization method

这里的随机初始化是有帮助的,但是损失函数仍然具有很高的值,并且可能需要很长时间来收敛并达到非常低的值。

基于 He 和 Xavier 的建议初始化参数

我们将探讨两种初始化方法:

  • 当应用于隐藏层的激活函数是校正线性单元(ReLU)时,明凯 He 方法是最好的应用。因此每个隐藏层上的权重将具有以下方差:var(W^l )= 2/n^(l-1).我们可以通过将标准正态分布的随机值乘以

  • 当应用于隐藏层的激活函数是双曲正切时,最好应用 Xavier 方法,使得每个隐藏层上的权重具有以下方差:var(W^l )= 1/n^(l-1).我们可以通过将标准正态分布的随机值乘以

我们将使用这两种方法训练网络,并观察结果。

# train NN where all parameters were initialized based on He recommendation
layers_dims = [X.shape[0], 5, 5, 1]
parameters = model(X, Y, layers_dims, hidden_layers_activation_fn="tanh", initialization_method="he") accuracy(X, parameters, Y,"tanh")The cost after 100 iterations is: 0.6300611704834093
The cost after 200 iterations is: 0.49092836452522753
The cost after 300 iterations is: 0.46579423512433943
The cost after 400 iterations is: 0.6516254192289226
The cost after 500 iterations is: 0.32487779301799485
The cost after 600 iterations is: 0.4631461605716059
The cost after 700 iterations is: 0.8050310690163623
The cost after 800 iterations is: 0.31739195517372376
The cost after 900 iterations is: 0.3094592175030812
The cost after 1000 iterations is: 0.19934509244449203The accuracy rate is: 99.00%.

Figure 4: Cost curve using He initialization method

# train NN where all parameters were initialized based on Xavier recommendation
layers_dims = [X.shape[0], 5, 5, 1]
parameters = model(X, Y, layers_dims, hidden_layers_activation_fn="tanh", initialization_method="xavier") accuracy(X, parameters, Y,"tanh")accuracy(X, parameters, Y, "tanh")The cost after 100 iterations is: 0.6351961521800779
The cost after 200 iterations is: 0.548973489787121
The cost after 300 iterations is: 0.47982386652748565
The cost after 400 iterations is: 0.32811768889968684
The cost after 500 iterations is: 0.2793453045790634
The cost after 600 iterations is: 0.3258507563809604
The cost after 700 iterations is: 0.2873032724176074
The cost after 800 iterations is: 0.0924974839405706
The cost after 900 iterations is: 0.07418011931058155
The cost after 1000 iterations is: 0.06204402572328295The accuracy rate is: 99.00%.

Figure 5: Cost curve using Xavier initialization method

应用这四种方法的结果表明,参数的初始值在实现低成本值以及收敛和获得较低的训练错误率方面起着巨大的作用。如果我们有测试数据,这同样适用于测试错误率。

结论

深度学习框架可以更容易地在不同的初始化方法之间进行选择,而不用担心我们自己实现它。尽管如此,理解参数初始值在网络整体性能中的关键作用还是很重要的。以下是一些关键要点:

  • 精心选择的参数初始化值导致:
  1. 加速梯度下降的收敛。
  2. 增加梯度下降的可能性,以找到更低的训练和泛化错误率。
  • 因为我们处理的是非凸损失函数的迭代优化算法,不同的初始化会导致不同的结果。
  • 随机初始化用于打破对称性,确保不同的隐藏单元可以学习不同的东西。
  • 不要初始化太大的值。
  • 明凯 He (He)初始化适用于具有 ReLU 激活函数的神经网络。
  • Xavier 初始化适用于具有双曲正切激活函数的神经网络。

创建这篇文章的源代码可以在这里找到。

原载于 2018 年 4 月 20 日imaddabbura . github . io

编码神经网络—正则化

原文:https://towardsdatascience.com/coding-neural-network-regularization-43d26655982d?source=collection_archive---------3-----------------------

Source

偏差-方差权衡

泛化(测试)误差是机器/深度学习中最重要的度量。它为我们提供了对未知数据的模型性能的估计。测试误差被分解为 3 个部分(见图 1): 方差、平方偏差和不可约误差

Figure 1: Bias and variance as a function of model complexity (flexibility). Source

具有高偏差的模型对于数据来说不够复杂(太简单),并且往往不适合。最简单的模型是取目标变量的平均值(模式)并将其分配给所有预测。相反,具有高方差的模型通过紧密跟随(模仿)训练数据来过度拟合训练数据,其中学习算法将跟随信号和噪声。请注意,随着模型的复杂性(灵活性)增加,⟹模型将变得更难解释,如神经网络。下面是偏差-方差分解:

其中:

  • var(ε):由每个例子中省略的特征和不可测量的变化引起的不可约误差。
  • 偏差( ):用简单模型近似现实生活中的问题而引入的误差。
  • var( ):如果我们使用不同的数据集进行估算, 将发生变化的量。

因此,我们只能控制的方差和偏差,而不能控制不可约误差。因此,我们的工作是尝试估计正确的复杂度水平,以实现最低的测试误差。

正规化

正则化通过使学习算法对训练数据和过程不太敏感来增加学习算法的稳定性。由于我们不知道也无法访问可用于比较估计函数的真实函数,因此最佳策略是构建一个非常复杂的模型,该模型非常适合训练数据(过度拟合),并对其进行调整,使其具有良好的泛化(测试)误差。当使用正则化时,我们试图减少泛化误差,这可能会导致过程中训练误差的增加,这是可以的,因为我们关心的是模型泛化的程度。通过正则化,我们试图通过增加偏差和减少方差,将过度拟合的非常复杂的模型恢复为良好的模型。这建立在复杂模型具有大参数而简单模型具有小参数的假设上。

以下是用于正则化的一些方法:

  1. L2 参数正则化:又称权重衰减。该方法在目标函数中加入 L2 范数罚函数,使权值向原点移动。即使该方法将所有权重以相同的比例向零收缩;然而,它永远不会使任何权重恰好为零。
  2. L1 参数正则化(Lasso) :可以看作是一种特征选择方法,因为;与 L2 正则化相反,一些权重实际上为零。它通过在目标函数中加入 L1 范数惩罚,将所有权重缩小相同的量。
  3. 辍学:辍学可以被视为一种近似套袋技术。在每次迭代中,我们随机关闭每层上的一些神经元,并且在前向传播和反向传播中都不使用这些神经元。这将迫使神经网络分散权重,而不是专注于特定的神经元,因为它永远不会知道哪些神经元会在每次迭代中出现。因此,它可以被视为在每次迭代中训练不同的模型。此外,由于我们在每次迭代中丢弃了一些神经元,这将导致更小的网络,这反过来意味着更简单的网络。
  4. 增强:通过使用训练样本添加虚假数据,并在图像识别的情况下对其添加扭曲,如重新缩放和旋转图像。这里的想法是,最好根据更多的数据来训练模型,以获得更好的性能。请注意,扩充示例不会像独立示例那样为模型添加太多信息,但当收集更多数据不可行时,它仍然是一种有效的替代方法。
  5. 提前停止:该方法试图优化代价函数并使其正则化,从而使其具有更低的泛化误差。它的工作方式是,在每次迭代中,我们记录验证错误。如果验证误差有所改善,我们将存储参数的副本,并将继续下去,直到优化算法终止。如果计算时间和资源对我们来说是个问题,这是个好方法。

在这篇文章中,我们将讨论 L2 参数正则化。

L2 参数正则化

我们通常不正则化偏差,只正则化权重。我们可以使用 hessian 矩阵及其特征值和特征向量来查看权重对权重衰减的敏感度。权重 wi 将使用(λi/λi + α) 进行重新调整,其中λi(特征值)测量 hessian 矩阵在该方向(特征向量)上的灵敏度,而 α 是正则化超参数。因此,

  • 如果λi ≫ α ,则成本函数在该方向上非常敏感,并且相应的权重显著降低了成本,⟹不会衰减(收缩)太多。
  • 如果λi≪ α ,则成本函数在该方向不敏感,并且相应的权重不会显著降低成本,⟹向零衰减(收缩)。

目标函数(二进制交叉熵)将从:

收件人:

此外,新的梯度和更新方程将是:

注意,这里 α 是学习率,λ是正则化超参数。随着λ增加,偏差增加(模型变得不太灵活),出现以下极端情况(见图 2):

  • λ = 0,无正则化。
  • λ → ∞时,模型变得非常简单,所有权重基本为零。在回归的情况下,我们最终得到的截距只等于目标变量的平均值。

Figure 2: Model complexity (underfitting/overfitting) as a function of regularization parameter λ

有时,使用法线方程来了解 L2 参数正则化是如何工作的可能会有所帮助。正常方程是:

这意味着:

  • 将λ加到方差上会降低权重,因为

  • 即使 X^TX 不可逆,给每个特征加λ也会使其满秩矩阵⟹可逆。

为了说明正则化如何帮助我们减少概化错误,我们将使用 cats_vs_dogs 数据集。该数据集包含猫和狗的图像。我们将尝试建立一个神经网络来分类图像中是否有猫或狗。每幅图像的 RGB 比例为 64 x 64 像素。

我们将使用我们在 “编码神经网络-前向传播和反向传播” 帖子中编写的函数来初始化参数,计算前向传播、交叉熵成本、梯度等。

让我们导入数据,看看形状以及来自训练集的猫图像样本。

Training data dimensions:
X's dimension: (12288, 209), Y's dimension: (1, 209)
Test data dimensions:
X's dimension: (12288, 50), Y's dimension: (1, 50)

Figure 3: Sample image

训练集有 209 个示例,测试集有 50 个示例。让我们首先编写所有能帮助我们编写多层神经网络的辅助函数。

现在我们准备训练神经网络。我们将首先建立一个没有正则化的神经网络,然后建立一个正则化的神经网络,以查看哪一个具有更低的泛化误差。请注意,应该调整λ以获得最佳结果,但是我们将在这里选择一个任意值来说明这个概念。两个神经网络都有 2 个隐藏层,每个隐藏层有 5 个单元。

# set up layers dimensions
layers_dims = [X_train.shape[0], 5, 5, 1]# train NN
parameters = model_with_regularization(X_train, Y_train, layers_dims, learning_rate=0.03, num_epochs=2500, print_cost=True, hidden_layers_activation_fn="tanh", lambd=0)print("The training accuracy rate: {}".format(accuracy(X_train, parameters, Y_train, "tanh")[-7:]))print("The test accuracy rate: {}".format(accuracy(X_test, parameters, Y_test, "tanh")[-7:]))The cost after 100 iterations: 0.6555634398145331
The cost after 200 iterations: 0.6467746423961933
The cost after 300 iterations: 0.6446638811282552
The cost after 400 iterations: 0.6441400737542232
The cost after 500 iterations: 0.6440063101787575
The cost after 600 iterations: 0.6439697872317176
The cost after 700 iterations: 0.6439570623358253
The cost after 800 iterations: 0.6439491872993496
The cost after 900 iterations: 0.6439407592837082
The cost after 1000 iterations: 0.6439294591543208
The cost after 1100 iterations: 0.6439131091764411
The cost after 1200 iterations: 0.6438883396380859
The cost after 1300 iterations: 0.6438489715870495
The cost after 1400 iterations: 0.6437825798034876
The cost after 1500 iterations: 0.6436617691190204
The cost after 1600 iterations: 0.6434191397054715
The cost after 1700 iterations: 0.642864008138056
The cost after 1800 iterations: 0.6413476000796884
The cost after 1900 iterations: 0.6360827945885947
The cost after 2000 iterations: 0.6124050450908987
The cost after 2100 iterations: 0.511236045905345
The cost after 2200 iterations: 0.5287658028657057
The cost after 2300 iterations: 0.43124104856359174
The cost after 2400 iterations: 0.38213869447364884
The cost after 2500 iterations: 0.3386708692392079The training accuracy rate: 82.30%.
The test accuracy rate: 78.00%.

Figure 4: Cost curve with no regularization

训练准确率为 82.30%,测试准确率为 78%。训练和测试精度之间的差别并不大,也就是说,我们没有太多的过度拟合。所以稍微正则化一点可能会有帮助比如λ= 0.02。从业者推荐的λs 值有:0.02,0.04,0.08,0.16,0.32,0.64,1.28,2.56,5.12,10.24。

# train NN with regularization
parameters = model_with_regularization(X_train, Y_train, layers_dims, learning_rate=0.03, num_epochs=2500, print_cost=True, hidden_layers_activation_fn="tanh", lambd=0.02)

print("The training accuracy rate: {}".format(accuracy(X_train, parameters, Y_train, "tanh")[-7:]))print("The test accuracy rate: {}".format(accuracy(X_test, parameters, Y_test, "tanh")[-7:]))The cost after 100 iterations: 0.6558634554205135
The cost after 200 iterations: 0.6470807090618383
The cost after 300 iterations: 0.6449737235917311
The cost after 400 iterations: 0.6444519406797673
The cost after 500 iterations: 0.6443191828114609
The cost after 600 iterations: 0.6442831256251426
The cost after 700 iterations: 0.6442705985766486
The cost after 800 iterations: 0.6442628048800636
The cost after 900 iterations: 0.6442544325786784
The cost after 1000 iterations: 0.6442432311807257
The cost after 1100 iterations: 0.6442270988055475
The cost after 1200 iterations: 0.6442027847231018
The cost after 1300 iterations: 0.6441643410411311
The cost after 1400 iterations: 0.6440998547029029
The cost after 1500 iterations: 0.6439832000181198
The cost after 1600 iterations: 0.6437505375793907
The cost after 1700 iterations: 0.6432228625403317
The cost after 1800 iterations: 0.6417982979158361
The cost after 1900 iterations: 0.6369273437378263
The cost after 2000 iterations: 0.6152774362019153
The cost after 2100 iterations: 0.5207828651496548
The cost after 2200 iterations: 0.5145012356446598
The cost after 2300 iterations: 0.40757220705507585
The cost after 2400 iterations: 0.517757346098386
The cost after 2500 iterations: 0.4574831239241244 The training accuracy rate: 65.55%.
The test accuracy rate: 80.00%.

Figure 5: Cost curve with regularization

如以上结果所示,我们通过将测试精度从 78%提高到 80%来改善泛化误差。另一方面,训练准确率从 82.30%下降到 65.55%。

结论

正则化是解决过拟合的有效技术。由于我们不知道数据的真实分布,基于经验分布的经验风险容易过度拟合。因此,最佳策略是很好地拟合训练数据,然后使用正则化技术,以便模型能够很好地推广。L2 参数正则化和丢失是机器学习中最广泛使用的两种正则化技术。

  • 诸如 L2 和 L1 参数正则化的正则化技术的隐含假设之一是参数的值应该为零,并且试图将所有参数收缩为零。这意味着避免很好地遵循训练数据,这使得学习算法挑选一些在应用于看不见的数据时没有帮助的噪声。
  • λ的值应该被调整以获得最佳的泛化误差。当比较具有λs 值的模型时,我们通常使用验证集,并选择具有最低验证误差的模型。
  • 如果模型遭受过拟合,即训练误差≪validation 误差,则仅使用正则化。
  • 如果使用正则化后验证误差仍然很高,那么我们很可能处于欠拟合区域。换句话说,我们的模型仍然过于简单,已经有很高的偏差。因此,增加模型的复杂性,然后使用正则化。
  • 由于我们试图解决的大多数任务没有足够的数据(或者收集更多数据的成本很高),鉴于神经网络的复杂性,过度拟合将比欠拟合在深度学习中更普遍。

创建这篇文章的源代码可以在这里找到。帖子的灵感来自 deeplearning.ai 课程。

原载于 2018 年 5 月 8 日imaddabbura . github . io

从头开始编写神经网络分类器

原文:https://towardsdatascience.com/coding-up-a-neural-network-classifier-from-scratch-977d235d8a24?source=collection_archive---------0-----------------------

A single-layer fully-connected neural network used for classification

TensorFlow、Keras 和 Pytorch 等高级深度学习库通过隐藏神经网络的许多繁琐的内部工作细节,在使深度学习从业者的生活变得更容易方面做了出色的工作。尽管这对深度学习很有好处,但它也有一个小缺点,那就是让许多基础知识不足的新手去别处学习。我们在这里的目标是简单地提供一个从零开始编写的 1 隐藏层全连接神经网络分类器 (没有深度学习库),以帮助消除您可能对神经网络的神秘黑盒感觉。该项目的 Github repo 位于:

https://github.com/ankonzoid/NN-scratch】T5T6

所提供的神经网络对描述属于三类小麦的谷粒的几何属性的数据集进行分类(您可以很容易地用您自己的定制数据集替换它)。假设 L2 损失函数,并且在隐藏层和输出层中的每个节点上使用 sigmoid 传递函数。权重更新方法使用德尔塔规则,该规则是具有 L2 范数的梯度下降。

在本文的剩余部分,我们将概述我们的代码构建和训练用于类预测的神经网络的一般步骤。更多我关于深度学习和强化学习的博客、教程、项目,请查看我的Medium**和我的 Github **

我们从零开始构建单层神经网络分类器的步骤

1.设置多重交叉验证

对于我们的 N 重交叉验证,我们随机排列所有 N 个示例索引,然后将大小为~N/n 的连续块作为我们的折叠。每个折叠充当许多交叉验证实验之一的测试集,而补体指数充当训练集。

2.建立和训练神经网络模型

我们有两个完全连接的权重层:一个连接输入层节点和隐藏层节点,另一个连接隐藏层节点和输出层节点。如果没有任何偏差项,这应该总计为网络中的(n _ input * n _ hidden+n _ hidden * n _ output)个权重。我们通过对正态分布进行采样来初始化每个权重。

每个节点(神经元)有 3 个属性存储在内存中:一个将自身连接到其输入节点的权重列表,一个通过前向传递一些输入计算的输出值,以及一个代表其在输出层的后向传播分类不匹配误差的增量值。这三个属性相互交织,并通过以下三个过程循环进行更新:

(A)向前传递训练示例,以在给定当前节点权重的情况下更新节点输出。每个节点输出计算为其前一层输入(无偏置项)的加权和,后跟一个 sigmoid 传递函数。

(B)在给定当前节点权重的情况下,反向传递分类错误以更新节点增量。为了更多地了解这些德尔塔,我们建议阅读https://en.wikipedia.org/wiki/Delta_rule,因为我们使用的德尔塔规则方程是从对 L2 损失函数应用梯度下降得到的。

(C)我们使用更新的节点输出增量来执行前向传递以更新当前的权重

对于每个训练时期,对每个训练实例执行(A ) → ( B ) → ( C)的训练循环过程。

3.进行班级预测

经过训练后,我们可以简单地使用该模型,通过将文本示例向前传递到训练好的神经网络中,获得输出的 argmax,来对我们的测试示例进行分类预测。准确度分数是网络正确分类的实例数除以实例总数的直观分数(在来自 n 重交叉验证的训练和测试集中)。

咖啡,伟大的连接器!

原文:https://towardsdatascience.com/coffee-the-great-connector-69b4eaf99b58?source=collection_archive---------21-----------------------

使用 Python 和图论分析面包店的交易数据

Image from pexels.com

面包店有一种魔力。咖啡和面包的味道,温暖,色彩,数据!人们来来去去,再回来买咖啡、面包、糕点等各种组合。我们能否利用这些交易数据来发现模式,并深入了解哪些项目在我们的烘焙食谱中更为重要?

我使用了一个面包店的交易数据集和一些图论来可视化经常一起购买的物品,看看我是否能提取出任何见解。

数据集

我使用了一个名为“面包店交易”的数据集的数据,出于我不知道的原因,这个数据集在 Kaggle 中不再可用。数据集包含了从 2016 年 10 月 30 日到 2017 年 4 月 9 日这段时间内苏格兰一家面包店的每笔交易的数据。总共有 94 个不同项目的 9,531 个交易。

图论方法

每个交易可以包括多个项目。我的方法是基于数据集中的所有交易创建一个数学图。如果事务包括面包和咖啡,我在面包节点和咖啡节点之间添加了一个连接(即边)。如果面包和咖啡同时出现在不止一个交易中,我会为每个交易增加一个面包-咖啡边缘的权重。如果一个事务包含 3 个项目,那么我为每个(无序的)项目对添加一条边。

在上述过程的最后,我得到了一个无向加权图,其中的节点代表了数据集中观察到的所有唯一项目。节点 x 和节点 y 之间的边表示项目 xy 在同一事务中出现的次数。请注意,该图还包括在交易中单独出现的项目的自身边。最后,直觉上,两个节点之间的边的权重越高,这两个项目就越“接近”。我也通过为每条边分配一个距离来捕捉它,这个距离是边的权重的倒数。因此,两个项目一起出现的事务越多,该边的权重就越大,这两个节点之间的距离就越小。

因此,如果面包和咖啡一起出现在 10 个交易中,面包-咖啡边的权重将是 10,其距离将是 0.1。

利用图论中的一些基本概念,我的目标是发现在图结构中处于中心位置的商品,希望中心位置能告诉我们一些关于顾客如何购买这些商品的有意义的信息。

代码

我使用了 python 包 networkx ,这是我在用 python 创建和分析图形时最喜欢的选择。你可以在这里找到包含所有代码的 jupyter 笔记本。

结果

就像我上面提到的,我检查了每一笔交易,并为交易中出现的每一对商品添加了一条无向边。只有一个项目的事务在图中为该项目添加了一个自边。得到的图有 94 个节点(等于数据集中出现的唯一项目的数量)和 1104 条加权边(包括自边)。这里有一些有趣的花絮。

  1. 图形连接如果您忽略交易中出现的几个“项目”,如“调整”,但显然不是实际项目,则生成的图表是连接的。
  2. 咖啡和面包可以搭配任何食物。 在计算唯一邻居时,Coffee 有 79 个唯一邻居,这意味着它至少出现在一个交易中,数据集中有 94 个唯一条目中的 79 个。如果不算咖啡的话,93 分之 78。面包以 75 度紧随其后。茶、蛋糕和果汁的度数分别为 68、64 和 58。
  3. 但是咖啡什么都配它的加权度为 7,285,而面包的加权度为 4,722。茶和蛋糕仍然排在第三和第四位(分别是 2572 和 1997),但现在我们的糕点排在前五位,果汁勉强进入前十。**
  4. 果汁有更多的朋友,但糕点是更好的朋友,因为它的种类更少。 从上面的第 2 点和第 3 点我们可以看出,尽管糕点在交易中伴随着较少的项目(糕点在图中具有更少的唯一邻居),但是糕点具有更高的加权度。这意味着糕点可以搭配很少的食物,但是可以很好的搭配这些食物。
  5. 咖啡的介数中心性最高。 手中有了一个结构良好的图,我们就可以计算出各种节点的中心性度量。这里我只阐述中间中心性特征向量中心性的结果。让我们从中间性开始(见下面的特征向量中心性)。中间中心性大致意味着一个节点在两个其他节点之间充当桥(或桥的一部分)的次数。对于图中的每两个节点,我计算了它们之间的 Dijkstra 最近路径,其中“最近”意味着最小化路径中边的距离之和的路径。这产生了一组 4,186 条路径(92 选择 2 种组合。我们只有 92 个项目,而不是 94 个,因为那是最大连接组件的大小)。然后我数了每一项在这些最接近的路径中出现了多少次。这个数字大致代表了每个节点的介数中心性。到目前为止,咖啡的中间中心度最高,出现在 3950 条路径中,而面包的中间中心度为 1012 条。茶,斯堪的纳维亚和艺术托盘分别以 529,190 和 182 的路径关闭了前 5 名。
  6. 咖啡具有最高的特征向量中心性。 也许图中最广泛使用的中心性概念是特征向量中心性。这个中心性粗略地指示了所有其他节点该节点在图中的中心程度。因此,这不仅是关于你在图中的中心位置,也是关于你的邻居 T21 的中心位置。这是谷歌最初的 PageRank 算法背后的主要思想。计算事务图的特征向量中心性向我们显示,Coffee 具有最高的中心性,但是与中间中心性相比,前 5 名更加接近。面包、茶、蛋糕和果汁是前五名中剩下的不到 0.2 个单位(这个指标从 0 到 1)。

这种图论方法还可以应用于哪些数据集,它能告诉我们什么?

你可以在这里 找到 jupyter 笔记本的所有代码和数据集

感谢阅读!

认知机器人:学习环境感知

原文:https://towardsdatascience.com/cognitive-robotics-learning-environment-perception-9f13ebfd89be?source=collection_archive---------3-----------------------

Image source: Autonomous Intelligent Systems Group, University of Bonn

为了让机器人成功地感知和理解它们的环境,必须教会它们以目标导向的方式行动。虽然绘制环境几何图形是许多移动机器人应用的必要先决条件,但理解环境的语义将使新的应用成为可能,这需要更高级的认知能力。

波恩 大学 自主智能系统组的负责人斯文·贝恩克,正在通过结合密集几何建模和语义分类来解决机器人学的这一领域。通过这个,环境的 3D 语义地图被建立。Sven 的团队已经展示了认知机器人在多个具有挑战性的应用领域中的语义环境感知的效用,包括家政服务、太空探索、搜索和救援以及捡垃圾箱。

在 6 月 28 日至 29 日在阿姆斯特丹 举行的 机器智能峰会上,Sven 将分享他和他的团队为学习任务开发的方法的专业知识,如表面分类、物体的检测、识别和姿态估计,以及将操作技能转移到新物体。为了了解更多信息,我在峰会前问了他几个问题。

你能告诉我们更多关于你的工作吗?

波恩大学的自主智能系统小组研究认知机器人和深度学习。我们为半结构化领域开发了多个机器人系统,如家政服务、搜索和救援、空中检查、太空探索、捡垃圾和踢足球。我们工作的主要重点是感知,即解释 3D 激光扫描仪和 RGB-D 相机等机器人传感器的测量结果,以获得适合规划机器人行动的环境模型。

我们还研究了机器人系统中运动和操纵以及学习的有效规划。我们将我们的开发集成到自主执行复杂任务的系统中。我们团队 NimbRo 的机器人在多个机器人比赛和挑战中表现出色,包括 DARPA 机器人挑战赛、RoboCup 足球和@Home、欧洲机器人挑战赛、亚马逊采摘挑战赛、DLR SpaceBot 杯和 MBZIRC。

您认为是什么主导因素推动了认知机器人技术的最新发展和普及?

传感方面的进步,如负担得起的 RGB-D 相机和小型 3D 激光扫描仪,以及计算方面的进步,如微型电脑和可编程图形处理器,构成了环境语义感知的基础。语义感知是通过收集大型注释数据集和执行例如图像分类、对象检测、姿态估计、语义分割等的深度学习方法来实现的。这些语义感知与高效的同步定位和地图创建方法(SLAM)相结合以获得 3D 语义地图。

另一个有利因素是更轻、更顺从的驱动,这允许人-机器人协作和身体接触。规划方面的进步,例如通过分层的、组合的方法,使得实时的自适应机器人动作的鲁棒生成成为可能。最后,更好的连接和云服务将认知机器人嵌入更大的基础设施。

认知机器人的哪些现在或未来潜在的应用最让你兴奋?

目前,高级驾驶辅助系统和自动驾驶汽车肯定是影响最大的认知机器人应用。使用协作机器人的灵活工业自动化正在获得动力。我最感兴趣的是认知服务机器人,它结合了半结构化环境中的鲁棒移动性、类似人类的操纵技能和直观的多模态人机交互。这种机器人可能会彻底改变餐馆和医疗保健等专业服务行业,但也可以在日常环境中提供帮助和做家务。

你觉得未来哪些行业会被认知机器人最大程度地颠覆?

所有人类重复劳动的行业都会受到影响。工业生产、农业、交通和物流领域的自动化程度将大幅提高。还有专业服务,如清洁、转售、餐馆、护理设施等。会越来越依赖认知机器人助手。一旦认知机器人变得负担得起,它们也将在我们的家中提供帮助。

在接下来的五年里,我们可以期待看到认知机器人技术的哪些发展?

我期待着功能的增加和成本的降低,这将使越来越多的应用领域成为可能,并创造一个认知机器人产业。

另一个令人兴奋的发展可能是人类和认知机器人系统之间更紧密的共生关系,这不仅是为了补偿身体或认知缺陷,也是为了提高生活质量和增强人类能力。

Sven Behnke 将在 6 月 28 日至 29 日在阿姆斯特丹举行的机器智能峰会上发表讲话,同时还将举行 自动驾驶汽车机器智能峰会 。会见领先的专家并向他们学习人工智能将如何影响交通、制造、医疗保健、零售等领域。现在门票有限,在这里注册参加。

其他确认的演讲者包括 Roland Vollgraf,研究负责人,Zalando Research;Neal Lathia,高级数据科学家,Skyscanner;科学主任 Alexandros Karatzoglou,télefonica;Ingo Waldmann,高级研究科学家,UCL;以及深度学习能力中心主任 Damian Borth, DFKI 。点击查看更多演讲者和话题。

机器智能峰会和自动驾驶汽车中的机器智能峰会也将于 11 月 9 日至 10 日在香港举行。

本次采访中表达的观点可能不代表 RE WORK 的观点。因此,有些观点甚至可能与 RE WORK 的观点相左,但发布这些观点是为了鼓励辩论和全面的知识共享,并允许不同的观点呈现给我们的社区。

口红推荐的协作嵌入

原文:https://towardsdatascience.com/collaborative-embeddings-for-lipstick-recommendations-98eccfa816bd?source=collection_archive---------8-----------------------

Sephora SEA 机器学习案例研究

对于一家电子商务公司来说,花时间和精力去了解客户行为,对客户和公司本身来说都是一种双赢的策略。

Embeddings: turning beauty products into vectors

例如,执行良好的产品策划是销量和多样性关键驱动力,也是客户参与品牌的关键驱动力。它还能让购物者花更少的时间浏览他们真正想要的东西。

在我的公司 Sephora SEA,我们利用客户生成的数据来更好地了解我们的业务,并为我们的客户创造愉快的购物体验。

在这个故事中,

  • 我演示了如何将来自自然语言处理 (NLP)的研究思想,更准确地说是来自手套论文【1】的研究思想,移植到项目到项目** 产品推荐系统中。**
  • 我展示了如何利用丝芙兰电子平台上的顾客浏览数据了解美容产品的 密集表示,也就是又名。嵌入。
  • 我用嵌入的可视化基础代数研究了通过算法学到了什么。
  • 我介绍了推荐系统离线评估的度量标准,并给出了不同方法的基准。

在行业中已经有相当多的嵌入式应用记录[4][5]。本案例研究旨在补充那些特别关注产品发现嵌入代数的案例。

这篇文章的布局是

  • 0 |单词嵌入入门
  • 1 |构建协同推荐系统
  • 2 |离线基准
  • 3 |产品发现的嵌入代数
  • 4 |视角

0 |单词嵌入入门

NLP 中的一个主要挑战在于文本数据的数学表示。

一个产生有趣结果的简单方法在于单词的一键编码:对于给定的词汇集【V| V |,每个单词都用它在 V 中的位置来表示。

反过来,一个文档【d】由它的字 W 中的 V 中的位置来表示。结果是一个长度为“在 V 中的字数”的稀疏向量,除了在 W 的位置之外,所有系数都为零。

Example of one-hot encoding of a sentence. Semantic and syntactic similarities are omitted.

一键编码的问题是,它认为单词是完全离散的实体,完全由其拼写定义:它忽略了单词的语义和句法相似性

例如,在这个模型中,“狗”与“拉布拉多”的不同之处就像它与任何其他单词的不同之处一样,比如“滑板”。

提出密集(≠稀疏),低维(∼30 到 300)单词表示,具有语义和句法规则,在 2001 年首次成为感兴趣的领域[2],并在 2013 年开始广泛流行[3]。

这些表示被称为 嵌入

这个想法在于使用巨大的文本语料库来学习那些嵌入,目的是在相同上下文中经常出现的单词应该具有相似的向量

特别是,GloVe 算法[1]因其简单性和有效性而脱颖而出:它建议将问题视为矩阵分解问题。

要分解的矩阵是单词到单词共现矩阵:a |V|×|V| 矩阵,其中每个系数是两个单词在同一上下文中出现的次数。

"词汇和美容产品都是可以放入语境中的独立实体."

注意:上下文的定义取决于用户。例如,可以使用 3 个单词的滑动窗口。

Context generation with 3-word-long sliding window

词语和美容产品都是可以放入语境中的独立实体。

对于电子商务中的美容产品,上下文可以由以下内容组成:

  • 结账篮
  • 意愿列表共现
  • 产品浏览会话上的滑动窗口
  • 和许多其他信号

听起来手套的原理可以用来衍生产品的密集表示。让我们看看如何做到这一点。

1 |建立协同推荐系统

在本案例研究中,我们的输入信号将完全来自客户浏览会话,其中产品上下文由滑动窗口生成。

How contexts can be derived from browsing sessions

从这个上下文生成方案中,我们可以导出一个产品共现矩阵 X

The co-occurrence matrix

该矩阵是输入数据的汇总,也是我们将使用的唯一信号。

直觉上,

  • 强相关产品应具有高共现编号
  • 强相关产品出现在相似语境中。它们与产品目录中的产品的共现特征应该相似。
  • 非常受欢迎的产品可能会与目录中的许多产品出现强烈的同现号。但这并不意味着它们与所有产品都相关。这相当于 NLP 中的 停用词

模型

GloVe 建议的是将 log(X) 分解为具有加性偏差的嵌入矩阵的点积。关于这个模型的细节和原因的更多信息,我强烈建议你参考最初的论文

在本案例研究中,我们选择考虑一个与要学习的参数密切相关的分解模型:

  • 嵌入矩阵 E ,大小为|VDD 是嵌入物的尺寸。注意,t39】dt41】≪|t43】vt45】|。****
  • 偏置向量 b ,大小为| V |。我们稍后会看到,这是一种产品流行偏见,它有助于应对过度流行产品的影响。

The factorisation model

Representation as a (very) shallow neural network

相应的目标函数(损失最小化)为:

Objective function

参数【E】b 可以通过例如小批量随机梯度下降来学习:该算法将迭代地查看小批量的产品对,并相应地利用同现计数来优化它们相应的嵌入和偏差。

一旦嵌入被学习,向量相似性的一个普通度量余弦相似性

因此,它可以用于导出完全协作的项目到项目推荐系统。

Cosine similarity for embeddings

可视化

Tensorboard 投影仪这样的工具可以帮助可视化 2D 或 3D 投影中的嵌入。

这里有一些关于你如何自己使用它的提示

Tensorboard projector for 3D embeddings visualisation. Each point is a product. Its colour corresponds to its highest-level category.

另一个我个人喜欢的可视化是在色标上绘制嵌入系数值。以某种方式订购产品有助于展示有趣的图案。

On the top plot, the products are randomly ordered. On the bottom plot, they are ordered according to brand. The latter exhibits horizontal patterns and shows how brand information was implicitly learnt. Note that the bottom ruler indicates brand.

偏见 b 怎么样?这些对应什么?

当绘制学习偏见与产品受欢迎程度(在视图中)的关系时,有一个明显的相关性。手套策略允许将流行性从嵌入中抽象出来,这确实是一个很好的特性。

定性示例

一些单品对单品推荐示例:

更进一步:加入边信息

嵌入成功地学习了一些产品关联。特别是,推断出了产品元数据(品牌、类别、范围、属性、益处……)。如果该信息已经可用,则可以将其集成到学习逻辑中。

例如,在美容产品的情况下,我们可以查看产品的品牌及其类别

举个例子,

这些元数据的嵌入也可以被学习并用于丰富产品向量表示。

GloVe for product representation learning, with side-information. The mean layer following the category embedding layer is to manage multi-category products.

注意,每种元数据类型的影响都可以通过为它们各自的嵌入选择维度来监控(维度越高,影响越强)。

这种架构在非常稀疏的共生矩阵或冷启动 ( ie)的情况下非常有用。新引入)项,因为它弥补了缺乏与产品元数据的协作数据

Embeddings learnt with a GloVe-like strategy with side-information. Products are ordered by brand. The bottom ruler represents brand. The concatenated brand and category embeddings are clearly visible.

另一种方法[6]是将元数据实体视为产品本身:具有相同品牌的产品更接近于相同的品牌嵌入。优点是预测时的架构类似于没有边信息的网络。

2 |离线基准测试

为了评估推荐的性能,没有什么比现场测试更好的了,无论是通过 A/B 测试(见我的前一篇)还是强化学习。

尽管如此,你仍然可以通过分割你的训练集并尝试预测下一次购买/观看来验证你的算法。

虽然这些基准测试的准确性很重要,但一个经常被忽略的考虑因素是推荐项目的多样性。

关于长尾产品

Illustration of a long tail (from wikipedia). In our current context, X-axis: products ordered by descending popularity. Y-axis: popularity

在绝大多数零售公司中,受欢迎程度(例如以购买数量来衡量)远远不是同质的。

相对较少的产品会占据销售额的大部分。

其余产品不常购买,代表收入机会(长尾产品)。

可发现性的度量

应对这类产品的一种方法是通过推荐来确保它们的可发现性。因此,我们着眼于系统对每个产品的公平性。

为此,对于给定的推荐系统 R ,我们为每个产品 i 引入一个可发现性评分( dscore )。

This dscore measures how well product i is being represented in the other products’ recommendations. The rank function is the rank of product i in recommendations coming from j, under system R.

人们可以查看目录中所有产品的 dscore 的重新分配,按降序 dscore 排序。再一次,再分配很可能是尾巴形的,但是尾巴越重,所有产品的代表就越公平

Repartition of dscores for all products, ordered in descending dscore, given different recommender systems

评论

  • 天真的一起购买/观看推荐系统简单地包括,对于一个产品,查看在相同的收银台/观看环境中出现最多的产品。
  • 包含了一个随机推荐系统的基线曲线。毫无意外,它实现了最佳发现性能,代价是大部分不相关的推荐。它提醒我们不能只考虑这个评估指标。
  • 一起购买实现最差的发现性能,主要是因为在考虑篮子时,共生矩阵的稀疏性更大。在这种情况下,冷启动产品更有可能出现。
  • 一起看一起买获得更好的发现性能,这要归功于更密集的同现矩阵。但是,它受到产品流行偏见的限制。
  • GloVe 实现了更好的发现性能,这要归功于在学习算法中集成了流行度偏差(如上所示)。此外,注入产品元数据使冷启动产品更容易被发现。

在前面的定性例子中,你可能会认为推荐大多来自同一个品牌。

虽然按品牌购买美容产品并不罕见,但这些建议可能会让顾客保持循环,并影响其他品牌的发现。

让我们看看解决这个问题的方法。

3 |产品发现的嵌入代数

嵌入有一个令人惊讶的特性,基本代数(平均值、和、差)可以用它们来执行,同时使人类理解。

这是令人惊讶的,因为这种考虑没有出现在模型中。

让我们看几个美容产品的例子。

产品超群

从学习到的产品嵌入中,你实际上可以通过平均来自同一品牌的产品向量来导出品牌的嵌入。

品牌相似性和品牌映射可以从那里计算出来。

Brand embeddings visualised in Tensorboard Projector (2D t-SNE projection)

与品牌无关的表述

如果我们只对产品的功能和好处感兴趣,而对品牌不感兴趣,那会怎样?我们能想出品牌不可知的向量表示和品牌不可知的推荐器吗?

实现这一点的一个方法是,对于一个给定的产品,从它的嵌入中提取它的品牌向量表示。

3D projection of the original embeddings. Each colour corresponds to a product’s highest-level category.

3D projection of brand-agnostic embeddings. Notice how their were shifted to a more spherical catalogue projection.

让我们看一些定性的例子。

相同的产品,但来自另一个品牌

如果您已经熟悉了嵌入,那么您很可能在 NLP 中遇到过几乎太常用的例子

“国王”——“男人”+“女人”=“女王”

是的,嵌入可以用于某种类型的问题回答。在前面的例子中,什么是“女人”什么是“国王”什么是“男人”?→《女王》

以丝芙兰 SEA 为例,是否可以利用嵌入来推荐类似的产品,但在丝芙兰(丝芙兰系列)的品牌中?

即。

“Fenty Beauty Pro Filt ' r Soft Matte Longwear 粉底”——“Fenty Beauty”+“丝芙兰系列”=?

In practice, it really outputs interpretable results!

和以前一样,一些定性的例子,

4 |候选人

我在这个案例研究中提出的框架实际上对许多情况非常适用。你所需要的就是为你要嵌入的对象导出同现上下文

最重要的是,上下文的定义可以像您希望的那样灵活。在这里,我只考虑了浏览会话,但也可以混合其他信号。

此外,我只展示了单品到单品的推荐,但是通过平均嵌入输入产品,来自客户过去购买或当前购物篮的推荐是完全可以实现的。

参考

[1] Pennington 等人,GloVe:Global Vectors for Word Representation,2014
【2】Bengio 等人,一种神经概率语言模型,2001
【3】miko lov 等人,Vector Space 中单词表示的高效估计,2013
【4】Mihajlo Grbovic列出搜索排名中的嵌入 (Airbnb 用 Uber Eats 发现食物:构建查询理解引擎,2018 年 6 月
【6】Vasile 等人, [Meta-Prod2Vec -产品嵌入使用边信息进行推荐](http://Product Embeddings Using Side-Information for Recommendation),2016

协作过滤和嵌入—第 1 部分

原文:https://towardsdatascience.com/collaborative-filtering-and-embeddings-part-1-63b00b9739ce?source=collection_archive---------1-----------------------

推荐系统就在我们身边。从网飞、亚马逊到 even Medium,每个人都在试图理解我们的口味,这样他们就能促使我们持续参与。你会惊讶于这背后的工作量。让我们试着理解开发推荐系统的一种方法的机制。

介绍

在这一系列文章中,我将解释协作过滤,这是开发自动推荐系统的一种非常常见的技术(尽管用例不限于推荐)。然而,使这个讨论有趣的是我们如何在实现这个技术的同时理解一个更一般的嵌入的概念。如果你没有听说过这个术语,不用担心,在这篇文章结束时你会有一个好主意。

第一部分:

  • 协同过滤背后的基本思想
  • 一个在 excel 中实现协同过滤的简单算法(是的你没看错!!)
  • 理解嵌入和偏差的概念

第二部分:

  • 利用 fastai 库实现协同过滤
  • 解释和可视化嵌入

协同过滤和嵌入—第二部分

这篇文章中提出的大多数想法都来自于杰瑞米·霍华德作为T21数据研究所的一部分进行的 深度学习 MOOC - v2 。这篇文章只是我尝试分享我在这个课程中学到的一些惊人的东西。

现在,事不宜迟,让我们开始吧…

什么是协同过滤?

Figure 1: Collaborative filtering [1]

推荐系统的上下文中,协同过滤是一种通过分析与所述用户相似的用户的喜好来预测用户兴趣的方法。通过协作多个观点来过滤模式的想法是它被称为协作过滤的原因。

协同过滤方法的基本假设是,如果一个人 A 在一个问题上与一个人 B 有相同的观点,那么 A 在另一个问题上比随机选择的人更有可能有 B 的观点

——维基百科[2]

协同过滤是一个通用的概念,有几种算法来实现它。查看这篇比较不同算法性能的文章。

[## 协同过滤的各种实现

利用协同过滤构建推荐系统的不同方法比较

medium.com](https://medium.com/@pgrover3/various-implementations-of-collaborative-filtering-100385c6dfe0)

一种这样的算法是概率矩阵分解。不要被名字吓到。我们将使用 excel 中的虚拟示例来理解这一点。

Excel 中的协同过滤

方案

如图 2 所示,我们有不同用户对不同电影的评分数据,评分范围为 0-5。空白单元格表示用户尚未对电影进行评级。我们的目标是尽可能地模拟这个系统。

Figure 2: Original ratings

模型

Figure 3

在图 3 中,您可以看到完整的框架。让我们试着去理解用户-电影(乔恩-阿甘)的特定组合在这里发生了什么。

本质上,这个模型就是这个等式:

模型预测的评分(黄色单元格中的 3.25)= 2 个绿色矢量(嵌入矢量)的点积+ 0.14(电影偏差)+ 0.87(用户偏差)

类似地,我们将预测每个用户-电影组合的评分,除了那些在实际数据中不存在用户-电影评分的组合。基于此,我们将通过比较预测评级和实际评级来计算损失( RMSE(均方根误差)(在我们的例子中:底部的红色单元格)。

很明显,我们的预测是基于这些 2 个嵌入矩阵和 2 个偏差矩阵。但是里面的数字呢,它们看起来是随机的,实际上是随机初始化的。那么,什么样的正确数字会让我们的预测接近实际的收视率呢?

是的,你猜对了。我们将通过使用某种优化算法使损失最小化来学习这些数字。事实上,这可以在 excel 中完成!!

梯度下降

转到数据→解算器,您将看到以下窗口。在设置目标中选择损失单元,在可变单元中选择嵌入和偏置矩阵范围。点击求解,求解器将通过最小化损失开始学习嵌入和偏差矩阵中的正确值。

Figure 4

Figure 5 : Predicted ratings using collaborative filtering

我们可以在图 5 中看到,求解器已经学习了嵌入和偏差矩阵中的值。我们的损失从 26.04 减少到 4.58 。我们从模型中得到的预测似乎也接近实际的收视率。所以现在我们有了一个看起来运行良好的模型。但是我们仍然不知道它为什么有效。基本上这个算法背后有 3 个关键的想法。

嵌入

关键思想#1:找到每个用户和每部电影作为嵌入的正确表示

是时候解决房间里的大象了。我们来看一个具体的例子。这里,乔恩阿甘向量(求解器已经学习的一串 5 个数字)表示。这些向量被称为嵌入。本质上在一个 5 维向量空间中,乔恩和阿甘由这两个嵌入向量表示。

Embedding : Jon

Embedding : Forrest Gump

嵌入是特定实体的多维向量表示

这种将实体表示为高维向量的方式是关键。这种表示可以捕捉不同实体之间的复杂关系。

为什么是 5?

嵌入向量的维数没有特定的规则,更多的是关于实验。维度应该足以捕捉实体的复杂性。一维或二维向量可能无法捕捉 Jon 的复杂性。但也不应该过高。我们的乔恩和阿甘没那么复杂。

嵌入向量中数字背后的直觉

您可以将这些数字视为捕捉它所代表的实体的不同特征。比如乔恩 (1.34) 中的第一个数字,可能代表他有多喜欢奇幻小说。而《阿甘正传》中的第一个数字 (-1.72) 告诉了我们在多大程度上可以把阿甘当做幻想(由于数字是负数,所以非常少)。

注意:从理论上讲,这是一个思考嵌入向量中的数字的好方法,但是我们永远不能真正说出每个数字实际上在捕捉什么。我们可以做一个有根据的猜测。

嵌入空间的封闭性

关键思想#2:如果一部电影和一个用户在一个向量空间中很接近,那么用户很可能会给这部电影很高的评价

捕捉接近度有不同的方法:点积,欧氏距离,余弦相似度。在我们的例子中,我们使用了点积

偏见的作用

关键思想#3:实体有一个独立于它与其他实体的交互的固有性质

简而言之,一些用户比其他人更挑剔。类似地,一些电影可以被普遍认为是好的,并且会被大多数用户评价很高。这些信息是通过偏见获得的。

该模型的建议

现在,我们有了一个训练有素的模型,它已经为每个用户和电影学习了正确的嵌入和偏好。考虑这样一种情况,我们必须向用户推荐一组电影中的一部电影(假设该组中的所有电影都没有被该用户看到)。

使用计算出的嵌入和偏差,我们可以预测用户将对该组中的每部电影给出的评级。所建议的电影将是具有最高预测等级的电影。

预测评分=嵌入向量点积(用户、电影)+用户偏差+电影偏差

链接到 excel 文件:https://github . com/shik 3519/collaborative-filtering/blob/master/collab _ filter . xlsx。受此文件启发→[3]

结束注释

这篇文章中讨论的方法肯定不是实现协同过滤的最佳方式。使用神经网络有更好的执行算法,但是嵌入的核心思想是共同的。

看看这篇文章,它讨论了神经网络的实现以及其他很多东西。

[## 协同过滤的各种实现

利用协同过滤构建推荐系统的不同方法比较

medium.com](https://medium.com/@pgrover3/various-implementations-of-collaborative-filtering-100385c6dfe0)

接下来

的下一篇文章中,我将讨论我们如何使用由杰瑞米·霍华德 等人开发的名为 fastai 的库来实现协同过滤。这个库构建在 pytorch 之上,专注于更容易实现的机器学习和深度学习模型

此外,我们将了解如何使用【t-SNE】****和Bokeh(Python 交互式可视化库,面向现代 web 浏览器进行演示)。下面是一个什么在商店的预告。****

【协同过滤与嵌入—第二部分

更多资源

**** [## 一口气学习实体嵌入

也许不会,除非你经常打破屏住呼吸的世界纪录!从好的方面来看,实体…

medium.com](https://medium.com/@apiltamang/learning-entity-embeddings-in-one-breath-b35da807b596) [## 结构化深度学习

快的

towardsdatascience.com](/structured-deep-learning-b8ca4138b848) [## 面向程序员的深度学习——36 小时免费课程

fast.ai 面向编码员的实用深度学习 MOOC。学习 CNN,RNNs,计算机视觉,NLP,推荐系统…

course.fast.ai](http://course.fast.ai/lessons/lesson4.html)

参考

[1]https://commons . wikimedia . org/wiki/File % 3a collaborative _ filtering . gif

[2]https://en.wikipedia.org/wiki/Collaborative_filtering

[3]https://github . com/fastai/fastai/blob/master/courses/dl1/excel/collab _ filter . xlsx

[4]http://www . wired . co . uk/article/how-do-netflixs-algorithms-work-machine-learning-helps-to-predict-what-viewers-will-like****

协作过滤和嵌入—第 2 部分

原文:https://towardsdatascience.com/collaborative-filtering-and-embeddings-part-2-919da17ecefb?source=collection_archive---------3-----------------------

Movie embeddings

在第一部分的中,我已经介绍了协同过滤背后的基本思想以及嵌入偏差的概念。建议您在继续之前阅读该帖子。

协同过滤和嵌入—第一部分

在这一部分,我将讨论我们如何使用由杰瑞米·霍华德 等人开发的一个名为 fastai 的库来实现协同过滤。这个库建立在 pytorch 的基础上,专注于更容易实现的机器学习和深度学习模型

此外,我们将了解如何使用【t-SNE】****和Bokeh(Python 交互式可视化库,面向现代 web 浏览器进行演示)。****

这篇文章中提出的大多数想法都来自于 深度学习 MOOC - v2杰瑞米·霍华德作为 数据研究所 的一部分进行的。这篇文章只是我尝试分享我在这个课程中学到的一些惊人的东西。****

资料组

我用过movie lens【1】数据集( ml-latest-small )。该数据集描述了来自电影推荐服务 MovieLens五星评级和自由文本标记活动。它包含 100004 评级1296 标签应用横跨 9125 部电影。这些数据是由 671 位用户在 1995 年 1 月 09 日至 2016 年 10 月 16 日之间创建的。

我们将使用两个文件:ratings.csvmovies.csv

使用 fastai 的协同过滤

开始之前,我们需要两件东西:

  • 支持 GPU 的机器(本地或 AWS)
  • 在你的机器上安装 fastai 库:pip install fastai

注意:在这篇文章的最后,我已经详细解释了如何为 fastai 设置你的系统

下面是使用 fastai 实现的一步一步的代码演练。底层算法和我们在 第一部分 讨论过的一样。

步骤 1:数据加载

我们正在看 2 个文件:收视率和电影

Figure 1: Ratings

评分包含不同用户对不同电影的评分。

Figure 2: Movies

电影包含关于电影的元数据。movieid是连接 2 个数据集的关键。

第二步:模特训练

**#fastai function
**val_idxs = get_cv_idxs(len(ratings))** #get validation indices** 

我们将把数据分为训练集和验证集。我们的验证是原始数据集的 20%。

****wd=2e-4** #weight decay
**n_factors** = 50 #dimension of embedding vector**

我们将使用 重量衰减 来减少过度拟合。我们还必须定义我们的嵌入向量的维度。

**#fastai function
**cf = CollabFilterDataset.from_csv(path, 'ratings.csv', 'userId', 'movieId', 'rating')** #creating a custom data loader**

现在我们必须为协同过滤创建一个数据对象。你可以把它看作是将原始数据转换成模型所要求的形式的东西。from_csv意味着输入应该是一个 csv 文件

函数的参数:

  • path:CSV 文件的位置路径
  • ratings.csv:CSV 文件的名称。它应该是图 1 所示的长格式
  • userID/movieID:2 个实体的列名
  • rating:要预测的因变量的列名
**#create a learner (model) and specify the batch size and optimizer 
**learn = cf.get_learner(n_factors, val_idxs, 64, opt_fn=optim.Adam)** 
#fastai function**

下一步是创建一个模型对象,它是我们已经创建的数据对象的函数。learner在 fastai 库中与 model 同义。该函数采用以下参数:

  • n_factors:嵌入向量的维数(在我们的例子中为50
  • val_idxs:验证时必须考虑的 ratings.csv 文件中的行索引
  • batch size:梯度下降的每一步传递给优化器的行数。在我们的例子中,每次迭代将传递 64 行数据
  • opt_fn:我们想要使用的优化器。在我们的例子中我们使用的是 亚当 。在这个库中,你可以访问不同的优化器

Figure 3: Optimisers

**#training with learning rate as 1e-2 
**learn.fit(1e-2, 2, wds=wd, cycle_len=1, cycle_mult=2, use_wd_sched=True)** 
#fastai function**

训练的最后一步是实际训练模型。在learner对象上调用fit训练模型并学习嵌入和偏置矩阵中的正确值。

函数的参数:

  • learning rate : 1e-2 是我们用于优化的学习率
  • wd:通过重量衰减
  • cycle_len/cycle_mult:这些是 fastai 的好东西,整合了最先进的学习率计划方法。帖子末尾包含与此相关的有用文章的链接。**
  • use_wd_sched:是否使用体重衰减时间表

当您运行上面的代码时,模型将开始训练,如下所示。您可以在每个时期后观察训练(左)和验证(右)损失。我们优化的损失函数是MSE (Mean squared error)

Figure 4: Model training

步骤 3:验证预测

****preds = learn.predict()** #prediction on validation
**math.sqrt(metrics.mean_squared_error(y,preds))** #calculating RMSE**

我们将使用训练好的模型来预测验证并计算 RMSE 。我们得到了一个 ~.90 的 RMSE,与该数据集的当前基准相当。

****y=learn.data.val_y** #actual ratings for validation
**sns.jointplot(preds, y, kind='hex', stat_func=None);****

Figure 5: Predictions (y) vs Actual (x) (Ratings)

我们还可以看到,我们从模型预测与实际收视率相符。

现在,我们将尝试解释嵌入和偏见,看看它们是否捕捉到一些有意义的信息。

解释嵌入和偏见

我们将把重点放在电影的嵌入和偏见上,因为我们有电影的实际名称

电影嵌入

我们知道我们的嵌入向量的维数是 50 。可视化这样的高维向量是困难的,几乎是不可能的。

t-分布式随机邻居嵌入(t-SNE) 是一种有效的方法,可以在较低的维度上可视化它们,同时保持这些向量之间的空间关系

使用上面的代码,我已经将嵌入向量的维数减少到 2 (t-SNE 分量)。下面我们可以看到为 3000 部电影嵌入的 2 个 t-SNE 组件。每个点代表一部电影。

y-tsne vs x-tsne components of embedding vectors (3000 movies)

你可以在这里玩这个剧情:http://tsne.getforge.io/

进一步放大我们可以看到来自同一个系列的电影在嵌入空间非常接近(几乎重叠)。这表明嵌入不仅仅是为了减少损失而优化的一些数字。

我们希望同一个系列的电影在风格、导演、演员等方面或多或少有些相似。嵌入空间的紧密性反映了嵌入正在捕捉这些特征

电影偏见

电影偏差可以被认为是对电影实际质量的一种度量,针对不同用户的不同分级模式进行调整

偏见可以被认为是电影实际上有多好/受欢迎的代表

让我们看看这是否反映在我们模型的偏差中

Bottom 15 movies based on bias

Top 15 movies based on bias

看着这个列表,我想大多数人都会同意这个列表看起来或多或少是合适的,并且更接近我们的大多数期望。

基于偏见对电影进行排名比仅仅平均所有用户给出的评级更有意义。与名字相反,它实际上使排名不偏不倚

嵌入聚类(基于评级)

对我来说,这是最有趣的部分。下面我挑选了一个评价电影数量最多的用户( userID:547 )。现在我在尝试看看用户给出的评分和不同电影的嵌入向量之间有没有什么看得见的关系。

猜猜看…

t-SNE components of movie embeddings clustered by ratings (userID: 547)

很明显,高评级(黑与红)的电影集中在嵌入空间的一部分。类似地,那些等级低的电影(绿色和蓝色)集中在空间的另一部分。

链接到 html 文件的情节。下载并在浏览器中打开:https://github . com/shik 3519/collaborative-filtering/blob/master/t-SNE _ cluster _ rating . html

嵌入聚类(基于偏差)

类似地,我也尝试过根据电影偏好对电影嵌入进行聚类。期望具有相似偏差(如所讨论的无偏流行度的度量)的电影在嵌入空间中应该是接近的。****

我们可以在下图中看到。

t-SNE components of movie embeddings (clustered by movie bias)

好(或坏)的电影都有一些共同的特征,这些特征被嵌入捕捉到了

链接到绘图的 html 文件。下载并在浏览器中打开:https://github . com/shik 3519/collaborative-filtering/blob/master/t-SNE _ emb _ cluster _ bias . html

我觉得很新奇,所以我试着想象电影嵌入的三个 t-SNE 组件。每个点代表一部电影,点的大小和颜色取决于偏差。

下面是实际剧情的链接:https://plot.ly/~shik1470/2/****

链接到用于此图的数据:https://github . com/shik 3519/collaborative-filtering/blob/master/t-SNE 1 . CSV

最后的想法

到现在为止,我想你会有点相信嵌入的想法是非常强大的。这个概念可以扩展到任何有大量分类变量的结构化数据问题。

分类变量的每一级可以被表示为高维向量,该向量可以捕获标签或一位热码编码未能捕获的关系。标签或一个热编码假设每个实体都是相互独立的,如果你仔细想想,肯定不是这样。

这是另一个关于在结构化环境中使用嵌入的很酷的帖子,你一定要看看。

**** [## 结构化深度学习

快的

towardsdatascience.com](/structured-deep-learning-b8ca4138b848)

有用的资源

  1. 学习率选择和调度:

[## 提高我们的工作方式和学习速度。

一.导言

techburst.io](https://techburst.io/improving-the-way-we-work-with-learning-rate-5e99554f163b) [## 估计深度神经网络的最佳学习速率

学习率是用于训练深度神经网络的最重要的超参数之一。

towardsdatascience.com](/estimating-optimal-learning-rate-for-a-deep-neural-network-ce32f2556ce0) [## 探索重新开始的随机梯度下降(SGDR)

这是我第一篇深度学习的博文。我在 2017 年 1 月左右开始了我的深度学习之旅,在我听说了…

medium.com](https://medium.com/38th-street-studios/exploring-stochastic-gradient-descent-with-restarts-sgdr-fa206c38a74e)

2.t-SNE:

[## 如何有效地使用 t-SNE

一种流行的探索高维数据的方法叫做 t-SNE,是由范德马滕和辛顿提出的…

蒸馏. pub](https://distill.pub/2016/misread-tsne/) [## 在 Python 中使用 PCA 和 t-SNE 可视化高维数据集

任何与数据相关的挑战的第一步都是从探索数据本身开始。这可以通过查看…

medium.com](https://medium.com/@luckylwk/visualising-high-dimensional-datasets-using-pca-and-t-sne-in-python-8ef87e7915b) [## LDA 和 T-SNE 交互式可视化

使用 NIPS 2015 论文中的数据

www.kaggle.com](https://www.kaggle.com/ykhorramz/lda-and-t-sne-interactive-visualization)

3.法斯泰:

设置 fastai 的说明:

  1. 本帖 GitHub 回购 : 本回购包含本帖中显示的笔记本和剧情

参考文献和引文

[1] F .麦克斯韦·哈珀和约瑟夫·康斯坦。2015.电影镜头数据集:历史和背景。ACM 交互式智能系统汇刊(TiiS) 5,4,第 19 篇(2015 年 12 月),19 页。http://dx.doi.org/10.1145/2827872****

基于协同过滤的推荐系统举例..

原文:https://towardsdatascience.com/collaborative-filtering-based-recommendation-systems-exemplified-ecbffe1c20b1?source=collection_archive---------1-----------------------

在我的上一篇文章中,我对推荐系统做了简单的解释,举例说明了各种类型的推荐系统。在这篇文章中,我将使用 Python 实现一些这类推荐系统的简单例子。

给定下面的用户项目评级矩阵 M,其中 6 个用户(行)对 6 个项目(列)进行了评级。评级可以取 1-10 之间的整数值,0 表示没有评级。(注意,我们对行和列使用 Python 中使用的从零开始的索引。但是,对于用户输入,user_id 将占用 1–6 之间的数字,item_id 将占用 1–6 之间的数字。假设,我们必须发现用户 3 是否会喜欢项目 4。因此,用户 3 成为我们的目标用户或活动用户,项目 4 是目标项目。

sample user-ratings matrix

基于用户的协同过滤

首先,我们必须预测用户 3 对项目 4 的评分。在基于用户的 CF 中,我们会找到与用户 3 最相似的 k=3 个用户。常用的相似性度量有余弦、皮尔逊、欧几里德等。这里我们将使用余弦相似度,其定义如下:

和,皮尔逊相关,定义为:

在 sklearn 中, NearestNeighbors 方法可以用来基于各种相似性度量来搜索 k 个最近邻居。

查看我的 Jupyter 笔记本下面嵌入的

[## csaluja/JupyterNotebooks-中号

在 GitHub 上创建一个帐户,为 JupyterNotebooks-Medium 开发做出贡献。

github.com](https://github.com/csaluja/JupyterNotebooks-Medium/blob/master/CF Recommendation System-Examples.ipynb)

findksimilarrusers函数使用此方法返回活动用户的 k 近邻的相似度和索引。函数predict _ user based**使用基于用户的 CF 方法进一步预测用户 3 将给予项目 4 的评级。预测计算为邻居平均值偏差的加权平均值,并将其添加到活跃用户的平均评级中。偏差用于调整与用户相关的偏差。由于某些用户可能总是倾向于给所有项目高或低的评级,所以会出现用户偏差。**

其中 p(a,I)是项目 I 的目标或活动用户 a 的预测,w(a,u)是用户 a 和 u 之间的相似性,K 是最相似用户的邻域。

基于项目的协同过滤

在这种方法中,使用余弦相似性度量来计算项目对之间的相似性。活跃用户 a 的目标项目 i 的评分可以通过使用简单加权平均来预测,如下所示:

其中 K 是活动用户 a 评价的最相似项目的邻域,w(i,j)是项目 ij之间的相似度

在 Jupyter Notebook embed 中检查,函数findksimilaritems使用利用余弦相似度的最近邻居方法来查找与项目 i. 相似的 k 个项目,函数predict _ item based使用基于项目的 CF 方法(上面的公式)进一步预测用户 3 将给予项目 4 的评分。

调整后的余弦相似度

将余弦相似性度量用于基于项目的 CF 方法不考虑用户评级的差异。调整后的余弦相似性通过从每个共同评级对中减去相应用户的平均评级来弥补这一缺陷,并且定义如下

为了在 Python 中实现调整后的余弦相似度,我定义了一个名为 computeAdjCosSim,的简单函数,该函数返回调整后的余弦相似度矩阵,给定评级矩阵。函数findksimilaritems _ adj cospredict _ item based _ adj cos利用调整后的余弦相似度来寻找 k 个相似项目并计算预测评分。

功能re commenditem提示用户选择推荐方式(基于用户(余弦)、基于用户(相关)、基于项目(余弦)、基于项目(调整余弦)。基于所选择的方法和相似性度量,该功能预测指定用户和项目的评级,并且还建议是否可以向用户推荐该项目。如果用户尚未对该项目进行评级,并且如果预测评级大于 6,则向用户推荐该项目。如果评级小于 6,则不向用户推荐该项目。

相似性度量的选择

在选择相似性度量时,一些有用的线索是

当您的数据受到用户偏差/不同用户评级尺度的影响时,请使用 Pearson

如果数据稀疏(许多评级未定义),请使用余弦

如果您的数据不稀疏并且属性值的数量很大,请使用欧几里得

对基于项目的方法使用调整余弦来调整用户偏差

推荐系统的评价

评价推荐系统的评价指标有很多。然而,最流行和最常用的是 RMSE(均方根误差)。函数 评估者 使用 sklearn 的均方误差函数计算预测额定值和实际额定值之间的 RMSE,并显示所选进近的 RMSE 值。(为了解释简单,使用了小数据集,因此没有将其分成训练集和测试集;本帖也不考虑交叉验证)。

在用户基数很大的应用程序中,基于用户的方法面临可伸缩性问题,因为它们的复杂性随着用户数量的增加而线性增长。基于项目的方法解决了这些可伸缩性问题,根据项目相似性推荐项目。混合技术利用了各种此类方法的优势,并以多种方式将它们结合起来以实现更好的性能。

感谢阅读。这篇文章是为了分享我对推荐系统的理解,欢迎任何关于改进这个实现的反馈。

变形应用的协同过滤

原文:https://towardsdatascience.com/collaborative-filtering-for-morphing-applications-af4f9f7cc259?source=collection_archive---------9-----------------------

ecSys 第一周:这篇文章是对论文' 【协同过滤推荐系统】 的简要总结和个人评论,发表在'【自适应网络'这本书上,作者是本·斯查费、丹·弗兰科斯基、乔恩·赫洛克和施罗德·森,2007 年。这篇博客是作为智利天主教大学推荐系统 (IIC3633)课程的每周读物而写的。

收到推荐在每个消费产品中都很常见,我们经常从朋友那里得到推荐,比如一部很酷的电视剧或一本鼓舞人心的书。但不仅仅是人,像 Amazon.com 这样的网站向你推荐相机,或者 Spotify 告诉你一个你从未听说过的团体。但是 Amazon.com 怎么知道你会喜欢那台相机,或者 Spotify 上关于那个团体的信息呢?他们主要使用协同过滤系统,预测你是否会喜欢一个产品。

协同过滤(CF)系统的一些想法试图模仿口碑相传的行为,让用户向其他可能喜欢该项目的人发送推荐,或者你可以看看你信任的某个朋友给出的评级:这被称为主动 CF。但由于这些依赖于人们做工作的系统的存在,还有自动 CF (ACF),其中使用不同算法的计算机生成推荐。
由于我们经常有一个与我们品味相似的朋友,我们可以从他那里获得推荐,常见的 ACF 系统也试图这样做,并寻找与每个人的品味相似的用户或物品。为了确定两个人是否相似,他们比较他们给出的评分,他们越接近,那么这个人就越相似。

但是如何为一个新用户做推荐,或者像脸书的宣传那样,没有给出评级?现在在网页上跟踪用户交互变得非常普遍。例如,看一个产品的描述所花的时间,在 Instagram 上滚动时你停留的图片,你首先注意到的新闻的位置(通过鼠标的位置或点击它们来识别)。
以上例子是隐性的信息收集方法,不一定完全可靠。也许你花了很多时间阅读亚马逊上某个产品的描述,结果却发现它并不是你所需要的,但是你的主页上却显示了这个产品。但是,对于用户和提供商来说,相关信息仍然可以通过这种方法获得,并且不一定产生产品的推荐。

Behavior gathering. Source: http://www.gravityrd.jp/en/technology

与这个主题相关,我认为作者没有为 CF 系统添加一个有趣的使用案例(可能只是因为这些跟踪实现的新颖性)。我们经常听说脸书优秀的 A/B 测试系统,它允许他们决定,例如,哪种布局对他们的用户更有吸引力。诸如此类的事情,几乎不能被用户评价,因为他们可能不会注意到大的差异,允许提供一个更令人满意的应用程序体验。

如果我们可以基于用户配置文件个性化整个应用程序结构,会怎么样?一些用户可能喜欢不同的 SAP 仪表板,一些用户可能讨厌脸书视频的自动播放(并且不知道它可以被禁用)。正如我们可以为购买者的兴趣生成一个配置文件一样,通过使用跟踪实现,实际上不同的应用程序可以交付给使用它时具有相似行为的用户组。有了变形应用,我们不仅可以满足大多数人的偏好,还可以满足几乎所有人的偏好,并提高应用的整体满意度。

为了建立用户档案,我们可以跟踪的一个例子是:

  • 执行一个动作所花费的时间(越少越好)。
  • 花在应用上的时间(时间越多越享受)。
  • 点击链接的数量。
  • 等等。

当然,也有许多必须面对的困难,比如实现这种变形应用程序的方法,或者允许我们跟踪感兴趣的行为的系统,但也有一个好的部分,这将是过去几年在推荐系统方面取得的进展,一旦收集到正确的数据,它将允许匆忙建立简档。

感谢您的阅读,如果您喜欢这篇文章,您可以点击这里的在它的 Steemit 链接上投稿。任何更正,评论,相关阅读我都会欣然接受。对于这篇文章,我并不打算曲解或指出这篇文章的大部分内容(如果不是全部的话)是基于什么样的原著。

协同过滤:从浅到深的学习

原文:https://towardsdatascience.com/collaborative-filtering-from-shallow-to-deep-learning-680926d5d844?source=collection_archive---------3-----------------------

协同过滤通常用于创建推荐系统(例如,网飞演出/电影推荐)。当前最先进的协同过滤模型实际上使用了一种非常简单的方法,结果证明效果很好。在这篇文章中,我将概述这些利用“浅层学习”的最新模型,然后介绍一种更新的方法(在我看来很有前途!),它利用了深度学习。在这篇文章中,我将使用 MovieLens 数据集 作为例子,其中包含用户对电影的评级。我还在我的 Github 上提供的脚本中演示了如何使用浅层和深层协同过滤,所以如果你想使用这些模型,请查看我的 Github!这个脚本利用了优秀的深度学习库 fastai(写在 PyTorch 之上)和 PyTorch。

浅薄的学问

当前最流行的协同过滤模型利用了一种叫做嵌入矩阵的东西。嵌入矩阵包含多维信息。例如,假设我们有一个包含三个因素的电影嵌入矩阵。这三个因素可能对应于电影的动作片程度、电影的浪漫程度以及电影是否更像纪录片。当然,这些因素可以对应于任何东西(并且不一定容易解释),嵌入矩阵通常包含许多因素。正是这些矩阵在训练协作过滤模型时被更新。使用 MovieLens 数据集示例,通过我们的标准协作过滤技术,我们将拥有用户和电影的嵌入矩阵(见下图)。矩阵的大小将是用户或电影的数量乘以我们选择的因素的数量。关于选择嵌入矩阵中因子的数量,这需要一些试错法。在我的Github 上的示例脚本中,嵌入因子的数量被设置为 50。在训练开始之前,这些嵌入矩阵中的值被随机初始化。在训练期间,这些值被更新以减少损失(即,使预测评级更接近实际评级)。在训练的每次迭代期间,对于每个用户对电影的评级,取相应向量的点积。这个点积就是预测评级。点积是针对每个用户对每部已评级电影的评级(注意:未被用户评级的电影被设置为 0),并将预测评级与实际评级进行比较。然后,使用随机梯度下降(或随机梯度下降的近似变体)来更新嵌入矩阵内的值,以减少损失函数。除了嵌入矩阵之外,现有技术的协同过滤模型包含偏差项,其本质上是考虑总是给出更高或更低评级的某些用户或者总体上被给出更高或更低评级的电影(即,好电影或坏电影)。这些偏置项被加到点积上。

这就是最先进的协同过滤模型的全部内容。正如你所看到的,所有这些背后的数学非常简单,如果你看一看我的 Github 上发布的附带脚本,你会看到使用 fastai 库,只需几行代码就可以创建和训练一个最先进的协作过滤模型。

深度学习

好了,我们已经介绍了当前最先进的协同过滤模型,它工作得很好,并利用了“浅层学习”,但该领域的下一步是什么?一个有前途的方向可能是深度学习的协同过滤,因为(1)深度学习在其他工作领域(例如,计算机视觉)非常成功,以及(2)它允许更大的模型规格,这乍听起来真的很烦人,但可能允许机器学习实践者创建适合他们数据集的模型。据我所知,深度学习协同过滤的想法最初是在 fastai MOOC 中提出的,我认为这是该领域一个非常令人兴奋的方向!在进入深度学习协同过滤的细节之前,我必须承认,使用示例 MovieLens 数据集,浅层学习模型优于深度学习模型。然而,我认为只要对模型的架构进行足够的修改,并使用正确的数据集(可能是更大的数据集——我只使用了 MovieLens 数据集的一部分),深度学习的协同过滤可以胜过浅层学习模型。

在这里,我将检查一个只有一个隐藏层的模型,但是这些模型可以按照你想要的任何方式定制!注意:我确实尝试添加了更多的层,对于这个数据集,一个隐藏层模型表现得最好。

就像之前一样,我们首先用随机初始化的权重为电影和用户创建一个嵌入矩阵(大小是用户或电影的数量乘以指定数量的因子)。然后,对于每个用户和相应的电影嵌入因子向量,我们连接这些向量(见下图)。在示例脚本中,在这一点(0.05)有一点点下降,以防止过度拟合。然后,我们将级联的嵌入因子向量乘以另一个矩阵,该矩阵的嵌入因子大小为*2(在该示例中,必须是这个,因为这是级联的嵌入向量中的列数)乘以某个其他数(在该示例中,我有 10)。然后,矩阵乘积通过整流线性单位激活函数(ReLU 这是负值被改成 0 的一种花哨说法);这在深度学习中非常常见,会使函数变得非线性。同样,为了防止过度拟合,我们应用更多的压差。然后,我们取矩阵乘积(经过 ReLU 和 dropout ),并将其乘以一个具有其他行数(在本例中也是 10 行)和一列的矩阵。因此,矩阵乘法的输出将是一个数字,这正是我们想要的,因为我们试图预测一个评级。然后,将该预测评级通过 sigmoid 函数(乘以[(最大评级-最小评级)+最小评级]),以使预测值更接近数据集中的实际预测值。这对于单个用户和评级的所有事情都是重复的,就像之前一样,预测值与实际值进行比较,我们的模型中的值通过反向传播的随机梯度下降进行更新(就像任何深度学习问题一样)。

这里需要注意的是,我没有提到任何关于偏差的东西,这是因为 PyTorch 中的线性层已经考虑了偏差,所以我们不必担心它。

同样,正如我之前提到的,深度学习模型比浅层学习模型做得更差,但我相信这个框架是一个有前途的工作路线。如果你想试试这篇文章中提到的例子,看看我的 Github 。我期待听到读者的评论,或许还能看到协同过滤与深度学习的其他用途。

通过熊猫图书馆获取交易数据🐼

原文:https://towardsdatascience.com/collect-trading-data-with-pandas-library-8904659f2122?source=collection_archive---------4-----------------------

“A street sign pointing to Wall Street in black and white” by Chris Li on Unsplash

(我的博客里也有这个帖子)

Pandas 是一个开源库,为 Python 编程语言提供高性能、易于使用的数据结构和数据分析工具。Pandas 是最受欢迎的交易策略开发工具之一,因为 Pandas 有各种各样的数据收集、操作和分析工具。

对于相信交易的定量分析师,他们需要访问股票价格和交易量,以便计算技术指标的组合(例如,SMA、BBP、MACD 等)。)进行策略。幸运的是,这些数据可以通过 REST APIs 在许多平台上获得(例如 IEXQuandl )。更幸运的是,pandas_datareader 为您从这些平台收集数据提供了一致的简单 API。在这个故事中,我将介绍如何用熊猫收集股票数据。

先决条件:Python 3

步骤 1:环境设置(虚拟环境)

python3 -m venv tutorial-env
source ~/tutorial-env/bin/activate
pip install panda
pip install pandas_datareader
pip install matplotlib
pip install scipy

(不要忘记激活环境“source ~/tutorial-env/bin/activate”或选择 IDE 中的虚拟 env)

步骤 2:代码(获取数据并转储到 csv 文件)

**import** matplotlib.pyplot **as** plt
**import** pandas_datareader.data **as** web
# collect data for Amazon from 2017-04-22 to 2018-04-22
start = **'2017-04-22'** end = **'2018-04-22'** df = web.DataReader(name=**'AMZN'**, data_source=**'iex'**, start=start, end=end)
print(df)
df.to_csv(**"~/workspace/{}.csv"**.format(symbol))

数据帧的输出

open       high        low    close    volume
date                                                         
2017-04-24   908.680   909.9900   903.8200   907.41   3122893
2017-04-25   907.040   909.4800   903.0000   907.62   3380639
2017-04-26   910.300   915.7490   907.5600   909.29   2608948
2017-04-27   914.390   921.8600   912.1100   918.38   5305543
2017-04-28   948.830   949.5900   924.3335   924.99   7364681
2017-05-01   927.800   954.4000   927.8000   948.23   5466544
2017-05-02   946.645   950.1000   941.4130   946.94   3848835
2017-05-03   946.000   946.0000   935.9000   941.03   3582686
2017-05-04   944.750   945.0000   934.2150   937.53   2418381
...

在本例中,相应的 csv 文件保存在输出目录(~/workspace/AMZN.csv)中。

步骤 3:可视化用 matplotlib 收集的内容

*# select only close column* close = df[[**'close'**]]
*# rename the column with symbole name* close = close.rename(columns={**'close'**: symbol})
ax = close.plot(title=**'Amazon'**)
ax.set_xlabel(**'date'**)
ax.set_ylabel(**'close price'**)
ax.grid()
plt.show()

就是这样!现在您已经下载了用于分析的股票数据。

整个例子

**import** pandas_datareader.data **as** web
**import** matplotlib.pyplot **as** plt

*# collect data for Amazon from 2017-04-22 to 2018-04-22* start = **'2017-04-22'** end = **'2018-04-22'** symbol=**'AMZN'** df = web.DataReader(name=symbol, data_source=**'iex'**, start=start, end=end)
df.index = df.index.to_datetime()
print(df)
df.to_csv(**"~/workspace/{}.csv"**.format(symbol))
*# select only close column* close = df[[**'close'**]]
*# rename the column with symbole name* close = close.rename(columns={**'close'**: symbol})
ax = close.plot(title=**'Amazon'**)
ax.set_xlabel(**'date'**)
ax.set_ylabel(**'close price'**)
ax.grid()
plt.show()

如果你想了解更多关于机器学习的知识,educative.io 中有一系列有用的课程。这些课程包括像基本的 ML,NLP,图像识别等主题。

最后一句话,如果你觉得用 Excel 更舒服,并且有兴趣轻松地分析股票,广墨有一个关于用 Intrinio Excel addin 收集数据的帖子

推荐阅读:

动手机器学习

用于数据分析的 Python:与熊猫、NumPy 和 IPython 的数据角力

对冲基金真正在做什么

我的帖子:

我关于金融和科技的帖子

我的 YouTube 频道

我关于 FAANG 访谈的帖子

从 CRUD web 应用开发到语音助手中的 SDE——我正在进行的机器学习之旅

全栈开发教程:将 AWS Lambda 无服务器服务集成到 Angular SPA 中

全栈开发教程:用运行在 AWS Lambda 上的无服务器 REST API 提供交易数据

全栈开发教程:在 Angular SPA 上可视化交易数据(1)

强化学习:Q 学习简介

使用 Python 收集您自己的 Fitbit 数据

原文:https://towardsdatascience.com/collect-your-own-fitbit-data-with-python-ff145fa10873?source=collection_archive---------0-----------------------

Python Generated Fitbit Cloud

所以你在圣诞假期有了你的 Fitbit,你也有了一些新年决心。你上网查看仪表盘上的图表,但还是不满意。你想要更多的数据、更多的图表和更多的信息。好了,不多说,因为我将教你如何收集你自己的 Fitbit 数据,只用一点 Python 代码。有了这个教程,你可以得到你难以捉摸的分分钟数据(也称为日内数据),这是你第一次得到 Fitbit 时不容易得到的。

第一步:设置你的账户并创建应用程序

你需要做的第一件事是创建一个 Fitbit 账户。一旦你完成了这些,你就可以去 dev.fitbit.com 的 T4。在“管理”下,转到“注册应用程序”。这将引导您进入一个如下所示的页面:

Application Registration

对于应用网站和组织网站,可以用“http://”或“https://”开头的任何名称命名。其次,确保 OAuth 2.0 应用程序类型为“个人”,因为这是允许我们下载当天数据的关键。最后,确保回调 URL 是“http://127.0.0.1:8080/”,以便让我们的 Fitbit API 正确连接。之后,点击协议框并提交。

注意:根据应用程序的不同,我们可能需要一个额外的步骤来填写表格,以便在这个链接获得我们当天数据的许可。Fitbit 支持个人项目和任何其他非营利研究,因此这些应该已经可以调用,但商业应用程序可能需要更长时间才能获得批准。

之后,您将被重定向到如下页面:

Registered Application

我们将从这个页面中需要的部分是 OAuth 2.0 客户端 ID 和客户端密码。

第二步:API

一旦第一步完成,我们的下一步是使用一个 Fitbit 非官方 API 。点击右侧的绿色按钮下载回购文件,然后解压文件。然后,打开命令行,将目录切换到包含解压缩文件的目录,并快速运行“sudo pip install-r requirements/base . txt”。

现在我们终于准备好开始编码了。首先,我们需要导入必要的包,并引入之前的 Client_ID 和 Client_Secret 来授权我们自己。

import fitbit
import gather_keys_oauth2 as Oauth2
import pandas as pd 
import datetimeCLIENT_ID = '22CPDQ'
CLIENT_SECRET = '56662aa8bf31823e4137dfbf48a1b5f1'

使用 ID 和 Secret,我们可以获得授权我们获取数据的访问和刷新令牌。

server = Oauth2.OAuth2Server(CLIENT_ID, CLIENT_SECRET)
server.browser_authorize()ACCESS_TOKEN = str(server.fitbit.client.session.token['access_token'])
REFRESH_TOKEN = str(server.fitbit.client.session.token['refresh_token'])auth2_client = fitbit.Fitbit(CLIENT_ID, CLIENT_SECRET, oauth2=True, access_token=ACCESS_TOKEN, refresh_token=REFRESH_TOKEN)

What the page should look like after authorization and signing in

我们进去了。…但没那么快。我们已经验证了自己的身份,但仍未获得数据。在开始之前,我有一个方便的技巧,可以节省大量的手工输入:许多调用都需要日期格式(YYYY-MM-DD)作为字符串格式。因此,如果您每天收集数据,我们必须每天手动更改该字符串。相反,我们可以导入有用的“datetime”包,让它替我们格式化。

yesterday = str((datetime.datetime.now() - datetime.timedelta(days=1)).strftime("%Y%m%d"))yesterday2 = str((datetime.datetime.now() - datetime.timedelta(days=1)).strftime("%Y-%m-%d"))today = str(datetime.datetime.now().strftime("%Y%m%d"))

第三步:采集数据

我们现在终于可以调用我们的数据了。

fit_statsHR = auth2_client.intraday_time_series('activities/heart', base_date=yesterday2, detail_level='1sec')

Heart Rate Data

虽然这些数据对我们来说是可读的,但它还不能保存在我们的电脑上。以下代码读取字典格式并遍历字典值——在将两者组合成一个熊猫数据帧之前,将各自的时间和值保存为列表。

time_list = []
val_list = []for i in fit_statsHR['activities-heart-intraday']['dataset']:
    val_list.append(i['value'])
    time_list.append(i['time'])heartdf = pd.DataFrame({'Heart Rate':val_list,'Time':time_list})

Our Newly Created Fitbit pandas data frame

现在终于可以在本地保存我们的数据了。考虑到未来,我们将一次一个数据地调用我们的数据(1 个文件= 1 天),所以我们希望有一个良好的命名约定,以防止任何未来的混淆或覆盖数据。我的首选格式是 heartYYYMMDD.csv。以下代码获取我们的心脏数据帧,并将其作为 csv 文件保存在/Downloads/python-fitbit-master/Heart/目录中。

heartdf.to_csv('/Users/shsu/Downloads/python-fitbit-master/Heart/heart'+ \
               yesterday+'.csv', \
               columns=['Time','Heart Rate'], header=True, \
               index = False)

Small army of heart rate files

但是等等!还有更多!

阅读文档,我们还可以收集很多其他数据,比如:

我们的睡眠日志数据:

"""Sleep data on the night of ...."""fit_statsSl = auth2_client.sleep(date='today')
stime_list = []
sval_list = []for i in fit_statsSl['sleep'][0]['minuteData']:
    stime_list.append(i['dateTime'])
    sval_list.append(i['value'])sleepdf = pd.DataFrame({'State':sval_list,
                     'Time':stime_list})sleepdf['Interpreted'] = sleepdf['State'].map({'2':'Awake','3':'Very Awake','1':'Asleep'})
sleepdf.to_csv('/Users/shsu/Downloads/python-fitbit-master/Sleep/sleep' + \
               today+'.csv', \
               columns = ['Time','State','Interpreted'],header=True, 
               index = False)

Sleep Log

或者我们的睡眠总结:

"""Sleep Summary on the night of ...."""fit_statsSum = auth2_client.sleep(date='today')['sleep'][0]ssummarydf = pd.DataFrame({'Date':fit_statsSum['dateOfSleep'],
                'MainSleep':fit_statsSum['isMainSleep'],
               'Efficiency':fit_statsSum['efficiency'],
               'Duration':fit_statsSum['duration'],
               'Minutes Asleep':fit_statsSum['minutesAsleep'],
               'Minutes Awake':fit_statsSum['minutesAwake'],
               'Awakenings':fit_statsSum['awakeCount'],
               'Restless Count':fit_statsSum['restlessCount'],
               'Restless Duration':fit_statsSum['restlessDuration'],
               'Time in Bed':fit_statsSum['timeInBed']
                        } ,index=[0])

Sleep Summary

这就是开始收集所有 Fitbit 数据所需的全部内容!所以,再玩一会儿,阅读 Python Fitbit 文档,完全沉浸其中,找到出路,看看你的心脏数据有多棒。如果你想知道如何利用这些数据,这里有一个链接指向我对自己心脏数据的分析。

感谢您花时间阅读我的教程,并随时在 LinkedIn 上发表评论或联系,因为我将发布更多关于数据挖掘和数据科学的教程。

参考资料:

  1. Orcas Fitbit API Github
  2. Python-Fitbit 文档
  3. 官方 Fitbit API 文档
  4. Fitbit 日内访问表
  5. 个人 Github 与所有代码
  6. 熊猫数据框文档

收集数据科学备忘单

原文:https://towardsdatascience.com/collecting-data-science-cheat-sheets-d2cdff092855?source=collection_archive---------0-----------------------

正如你可能已经知道的,我已经专门为那些刚刚开始接触数据科学的人或者那些在处理数据科学问题时需要额外帮助的人制作了 Python 和 R 备忘单。

现在,您可以在 DataCamp 社区的一个地方找到它们。

你可以在这里 找到所有的小抄

概括地说,这些是迄今为止我们已经制作并与社区分享的数据科学备忘单:

基础知识

数据操作

机器学习、深度学习、大数据

数据可视化

IDE

尽情享受,随意分享!

PS。您是否看到了另一份想要推荐的数据科学备忘单?让我们在这里了解

使用 CoreML 的碰撞检测系统

原文:https://towardsdatascience.com/collision-detection-system-using-coreml-f453923670a4?source=collection_archive---------15-----------------------

最近在 WWDC 17,苹果推出了 CoreML 和 ARKit。这开启了无数的可能性,让数以百万计的人可以通过他们的手机来设计令人惊叹的应用程序。利用这些新技术,我们想为什么不设计一个可以在日常通勤中帮助每个人的应用程序。经过一番头脑风暴,我们决定建立一个驾驶辅助 dashcam 应用程序。

我们计划设计的驾驶员辅助应用程序将由一个碰撞检测管道组成,该管道将检测驾驶员是否会撞到车辆前方的障碍物。该应用程序将不断从相机中获取帧,检测每帧中的对象,找到每个对象的深度,传感器融合以计算车辆的速度和碰撞时间。

物体检测:

从上面的讨论中,我们可以理解,解决这个问题的第一个里程碑是使对象检测算法在移动电话上工作。理想的算法应该以最高的精度预测障碍物,几乎实时运行,并且没有假阳性。基于这些要求,解决对象检测问题的最佳方法是使用深度学习算法。

以对象检测问题而闻名的深度学习算法有 R-CNN、快速 R-CNN、更快 R-CNN、YOLO、YOLO 9000、SSD、MobileNet SSD。

经过一个月的头脑风暴和编码,我们使用 CoreML 框架实现了 YOLO,达到了目标检测的里程碑。

Object Detection Prototype

我们在下面的博客中记录了我们是如何完成这项任务的— 链接

深度计算:

障碍物的深度可以定义为障碍物距离摄像机的距离。

Depth (or) Distance of obstacle from car

一般来说,深度可以通过一些特殊的硬件立即计算出来,这些硬件通常被称为 RGBD 相机。现在流行的消费级 RGBD 相机是微软的 Kinect (Xbox)。但另一方面,消费者手机没有深度传感器。它们只是 RGB 相机(又称单目视觉)。我们怎么计算深度呢?

为了使用单目摄像机计算与汽车的距离,我们可以遵循以下策略之一

  1. 时间方法——根据图像中运动的时间顺序计算深度(例如:视觉里程计)
  2. 每帧方法-其中在当前帧中计算的深度独立于先前的帧(例如:三角测量技术,或深度学习技术等)。)

在我们的例子中,我们现在选择了每帧三角测量法,并提出了一些数学公式,找到了计算汽车深度的方法。用我们的公式计算的深度在米的尺度上是精确的,但在厘米的尺度上就不那么精确了。因此,我们决定保持三级(安全、中等和危险)碰撞检测报警系统,而不是非常精确的深度精度。

传感器融合:

一旦我们从上述阶段计算出深度,我们将使用传感器融合来组合手机中的各种传感器,以获得我们汽车的速度。然后,我们在简单的运动学公式中使用它来计算特定帧中的 T.T.C(碰撞时间)。在研究人类对警报的平均反应时间的基础上,我们战略性地将 T.T.C .划分为警报系统的三个阶段。

此外,假设用于检测汽车的算法是鲁棒的并且视野良好,那么我们很有可能在一帧中检测到许多汽车。在这种情况下,我们可能需要找到一辆我们将来可能会撞上的车。通过传感器融合,我们通过图像处理技术稳健地计算我们汽车的轨迹,将问题从' n 辆汽车归结为 1 辆汽车,然后我们计算那辆特定汽车的 T.T.C。

Trajectory of car estimation from sensor fusion and T.T.C

将这些放在一起,我们已经准备好了管道的基本工作演示,可以在下面的视频中看到。

Demo (Testing Phase)

未来工作:

在这篇博客中,我们展示了如何利用 CoreML、计算机视觉和传感器融合的力量来创建一个能够真正帮助人们日常通勤的应用程序。我们正在积极工作,使用深度学习技术或鲁棒的视觉惯性里程计技术来改进检测到的车辆的深度估计。此外,我们正在计划是否可以使用 iPhone 7 Plus(窄基线相机系统)中提供的两个相机的功率来估计深度。根据从两个不同视点(或两个相机)捕获的图像来估计场景中对象的深度的区域被称为“来自立体的深度”。这个领域是受人类视觉系统的启发而产生的,下图概括了我试图解释的内容。

Depth estimation of objects through stereo vision

感谢您阅读本博客,并请留下您对我们工作的评论/看法。我还要感谢苹果公司的 CoreML 团队,是他们惊人的 API 让这一切成为可能。

口袋妖怪图像的均值聚类

原文:https://towardsdatascience.com/color-difference-clustering-on-pokemon-images-68c6f0a3245b?source=collection_archive---------7-----------------------

Developing strategies to group similar Pokemon Images

探索性算法是在数字属性上明确定义的,通过提供描述性统计的摘要,然后是可视化,如直方图、散点图和其他一些可能与问题相关的内容。然而,简单的摘要更容易与图像数据集混淆。

图像数据聚类,也称为图像检索,有许多有趣的算法,如使用自动编码器来获得图像相似性。然而,这些算法很难实现,并且需要一些时间来训练。本文的目的是尝试一个简单的概念,根据与平均图像的距离对相似图像进行分组。

在浏览 Kaggle 内核时,我看到了一个非常有趣的想法,即使用“平均图像”对国际足联球员数据库中的人脸图像进行聚类:

在面部数据集上,平均面部图像的概念是相当直观的,然而,我怀疑这将如何转化为其他数据集。

尽管如此,我还是开始了这个项目,来看看在一个由口袋妖怪图像组成的数据集上,普通的图像会是什么样子。我最初的反应是,这种方法实现起来比构建卷积自动编码器简单得多,因此,如果这能产生有意义的聚类,它将是有用的。

在本文中,我们将探索一个包含 150 个原始口袋妖怪图像的数据集,并根据它们与平均图像的差异对它们进行聚类。本文将进一步探讨均值图像的使用,以及如何使用它在图像数据中形成聚类。

图像聚类的一个潜在应用可能是改进数据扩充算法。图像聚类对于改进用于添加数据的生成对抗网络(GANs)的使用非常有用。我们将从本文中导出的集群中进行采样,而不是从整个数据集中进行采样。

以下是我们将遵循的形成口袋妖怪图像集群的工作流程:

# Load Images
# Calculate Mean Image
# Calculate Distance from Mean to each Image
# Sort by Distance
# Select Clusters based on Distance Quantiles

我已经在 Github 上传了我在这里使用的口袋妖怪图片:

所有代码都是用 Python 写的

# Load Pokemon Imagesfrom PIL import Image
import numpy as np
import os
from random import shuffle
from tqdm import tqdm
import matplotlib.pyplot as pltDIR_NAME = './Pokemon'
IMG_SIZE = 100pokemon = []
for img in tqdm(os.listdir(DIR_NAME)):
    path = os.path.join(DIR_NAME, img)
    if "DS_Store" not in path:
        img = Image.open(path)
        img = img.convert('L')
        img = img.resize((IMG_SIZE, IMG_SIZE), Image.ANTIALIAS)
        pokemon.append(np.array(img))

print(type(pokemon[0]))
print(pokemon[0].shape)
plt.imshow(pokemon[0], cmap = 'gist_gray')
plt.show()

现在我们已经加载了图像,我们想要计算整个数据集的平均图像:

# Calculate Mean Image
sums = np.zeros((100, 100))
for x in range(len(pokemon)):
    for i in range(100):
        for j in range(100):
            sums[i][j] += pokemon[x][i][j]
#print(sums)
for idx in range(100):
    for idy in range(100):
        sums[idx][idy] /= len(pokemon)
#print(sums)
plt.imshow(sums, cmap='gist_gray')
plt.show()

平均图像:

前 5 幅图像的平均图像:

# Define Distance functiondef SquaredDistance(x, y):
    return (x-y)**2
def ImageDistance(img1, img2):
    distance = 0
    for i in range(100):
        for j in range(100):
            distance += SquaredDistance(img1[i][j], img2[i][j])      
    return distance

我们将使用距离的平方来计算每个口袋妖怪与平均口袋妖怪图像的距离。

# Calculate Distance from Mean Image to each Imagemean_image = sums
Distance_Dict = {}
for i in range(len(pokemon)):
    Distance_Dict[i] = ImageDistance(mean_image, pokemon[i])

本词典采用以下形式:

0: distance from image 0 to mean image
1: distance from image 1 to mean image
...
150: distance from image 150 to mean image

现在,我们根据这个排序的分区对字典和集群进行排序:

import operator
sorted_d = sorted(Distance_Dict.items(), key=operator.itemgetter(1))
print(sorted_d)

最后,让我们想象一下每个集群中的一些图像,看看我们在这里做了什么…

总之,使用均值距离来形成聚类并没有什么好处。虽然它在基于图像的集中暗度对图像进行聚类方面做得很好,但它没有捕捉到我们在图像聚类中想要的任何视觉相似性(除了第一组中的 Diglet 和 Dugtrio)。我很高兴能继续研究图像检索和相似性技术,以形成更有意义的基于除颜色密度之外的视觉特征的图像簇,感谢阅读!

CShorten

Connor Shorten 是佛罗里达大西洋大学计算机科学专业的学生。对软件经济学、深度学习和软件工程感兴趣。

图像中的颜色识别

原文:https://towardsdatascience.com/color-identification-in-images-machine-learning-application-b26e770c4c71?source=collection_archive---------1-----------------------

机器学习应用

Photo by Henry Lorenzatto on Unsplash

我最近开始阅读如何用 Python 处理图像。当我偶然发现 OpenCV 允许用 Python 导入和处理图像时,我开始想知道是否可以使用机器学习从这些图像中提取信息并以某种方式使用。

我们都知道,我们可以基于某些过滤器进行在线搜索,其中一个过滤器是颜色。我受到启发,实际上编写了代码,可以从图像中提取颜色,并根据这些颜色过滤图像。

在本文中,我解释了我如何理解 OpenCV 的基础知识,使用 KMeans 算法从图像中提取颜色,并基于颜色的 RGB 值从图像集合中过滤图像。完整的笔记本可以在这个资源库中找到。我点击了sample_image.jpg,文件夹images中的其他 5 张图片取自 Unsplash

导入库

我们导入的基本库包括matplotlib.pyplotnumpy。为了提取计数,我们将使用集合库中的Counter。要用 OpenCV,我们就用cv2KMeans算法是sklearn's cluster子包的一部分。为了比较颜色,我们首先使用rgb2lab将它们转换到 lab,然后使用deltaE_cie76计算相似度。最后,为了在从目录中读取文件时组合路径,我们导入了os

使用 OpenCV

Sample Image

为了读取任何图像,我们使用方法cv2.imread()并指定作为 Numpy 数组导入笔记本的图像的完整路径。然后我们可以使用 pyplot 的方法imshow()来绘制它。

数组的形状是(3456,4608,3)。前两个值匹配图像的像素。第三个值设置为 3,因为每个像素表示为三种颜色(红色、蓝色和绿色)的组合。

Image read by OpenCV

图像的颜色看起来有点不对。这是因为,默认情况下,OpenCV 按照蓝绿色红色(BGR)的顺序读取图像。因此,为了查看实际的图像,我们需要将渲染转换为红绿蓝(RGB)。

方法cvtColor允许我们将图像渲染转换到不同的颜色空间。为了从BGR色彩空间移动到RGB,我们使用方法cv2.COLOR_BGR2RGB

RGB Colors set for the image

在某些情况下,我们可能想要黑白图像。在这种情况下,我们可以将图像表示为灰色。我们现在使用转换空间作为cv2.COLOR_BGR2GRAY,并用色图显示输出作为gray

Gray Image

我们还可以将图像调整到给定的尺寸。我们使用cv2提供的方法resize。第一个参数是我们要调整大小的图像,第二个参数是括号内定义的宽度和高度。

Resized image to 1200 x 600

现在让我们来识别图像中的颜色,并将顶部的颜色显示为饼图。

颜色识别

RGB 到十六进制转换

我们将首先定义一个将RGB转换为hex的函数,这样我们就可以将它们用作饼图的标签。

在读取RGB空间中的颜色时,我们返回一个字符串。{:02x}简单显示相应颜色的十六进制值。

读取 RGB 颜色空间中的图像

接下来,我们定义一个方法,它将帮助我们在RGB空间中把一个图像放入 Python。

我们提供图像的路径作为参数。首先,我们使用imread读取文件,然后在返回之前改变它的颜色空间。

从图像中获取颜色

我们现在将完整的代码定义为一个方法,我们可以调用该方法从图像中提取顶部的颜色,并将它们显示为饼图。我将该方法命名为get_colors,它有 3 个参数:

  1. image:我们希望提取颜色的图像。
  2. number_of_colors:我们要提取的总颜色。
  3. show_chart:决定是否显示饼图的布尔值。

为了更好的理解,我们来分解一下这个方法。

首先,我们将图像调整到尺寸600 x 400。不需要将其调整到较小的尺寸,但我们这样做是为了减少像素,从而减少从图像中提取颜色所需的时间。KMeans 期望输入是二维的,所以我们使用 Numpy 的 reshape 函数来整形图像数据。

KMeans 算法根据提供的分类计数创建分类。在我们的例子中,它将形成颜色的集群,这些集群将是我们的顶部颜色。然后,我们在同一幅图像上用fitpredict将预测提取到变量labels中。

我们使用Counter来计算所有标签的数量。为了找到颜色,我们使用clf.cluster_centers_ordered_colors遍历 count 中出现的键,然后将每个值除以255。我们可以直接将每个值除以 255,但是这样会打乱顺序。

接下来,我们得到hexrgb颜色。正如我们之前将每种颜色除以 255 一样,我们现在在寻找颜色时再次将其乘以 255。如果show_chartTrue,我们绘制一个饼图,每个饼图部分使用count.values()定义,标签为hex_colors,颜色为ordered_colors。我们最终返回了rgb_colors,我们将在后面的阶段使用它。

瞧啊。!我们都准备好了!!

让我们把这个方法叫做get_colors(get_image(‘sample_image.jpg’), 8, True),我们的饼状图显示了图像的前 8 种颜色。

Identified colors

这为许多高级应用打开了大门,例如在搜索引擎中搜索颜色,或者寻找一件有某种颜色的衣服。

我们刚刚确定了图像中存在的 8 种主要颜色。让我们尝试实现一个搜索机制,它可以根据我们提供的颜色过滤图像。

使用颜色搜索图像

我们现在将深入研究基于我们想要的颜色过滤一组五个图像的代码。对于我们的用例,我们将提供颜色绿色蓝色黄色的 RGB 值,并让我们的系统过滤图像。

获取所有图像

图像在文件夹images中。我们把COLORS定义为颜色的字典。然后,我们读取该文件夹中的所有图像,并将它们的值保存在images数组中。

显示所有图像

我们首先使用下面提到的for循环显示文件夹中的所有图像。

我们将该区域分割成与图像数量相等的支线剧情。该方法采用的参数为行数= 1列数=所有图像,即在我们的例子中为 5 以及索引

All images in the ‘images’ folder

用颜色匹配图像

我们现在定义一个方法match_image_by_color来过滤所有匹配所选颜色的图像。

我们首先使用之前定义的方法get_colorsRGB格式提取图像颜色。我们使用方法rgb2lab将选择的颜色转换成我们可以比较的格式。for循环简单地遍历从图像中获取的所有颜色。

对于每种颜色,循环将其更改为lab,在迭代中找到所选颜色和该颜色之间的差值(基本上是差异),如果该差值小于阈值,则选择该图像与该颜色匹配。我们需要计算增量,并将其与阈值进行比较,因为每种颜色都有许多阴影,我们无法始终将所选颜色与图像中的颜色完全匹配。

通过说绿色,用户可以指浅绿色、绿色或深绿色。我们需要扫描所有的可能性。

如果我们从一幅图像中提取 5 种颜色,即使其中一种颜色与所选颜色匹配,我们也会选择该图像。threshold基本上定义了图像和所选颜色的差异。

让我们考虑这样的情况,我们试图找到绿色的图像。如果阈值太高,我们可能会在搜索中看到蓝色图像。类似地,另一方面,如果阈值太低,那么绿色甚至可能不匹配包含深绿色的图像。这都是基于手头情况的需要,我们可以相应地修改这些值。我们需要仔细设置threshold值。

显示选定的图像

我们定义了一个函数show_selected_images,它遍历所有图像,调用上面的函数根据颜色过滤它们,并使用imshow将它们显示在屏幕上。

我们现在将简单地调用这个方法,并让它绘制结果。

过滤结果

我们按如下方式调用该方法。我们将变量selected_color替换为绿色的COLORS['GREEN'],蓝色的COLORS['BLUE'],黄色的COLORS['YELLOW']。我们设置阈值为60,从图像中提取的总颜色为5

寻找绿色

Search for ‘GREEN”

寻找蓝色

Search for ‘BLUE’

寻找黄色

Search for ‘YELLOW’

结论

在本文中,我们讨论了使用 KMeans 算法从图像中提取颜色,然后使用该算法基于颜色搜索图像的方法。

希望你喜欢我的作品。请分享你的想法和建议。

机器学习算法的颜色参数

原文:https://towardsdatascience.com/color-parameters-for-a-machine-learning-algorithm-fc19487d2b6f?source=collection_archive---------9-----------------------

说到机器学习,你不能低估数据工程的重要性。

在为我的项目准备数据时,我遇到了几个挑战,我正在开发一种机器学习算法,根据影响彩色宝石价值的参数来预测它们的价格。挑战之一是颜色。

颜色是宝石的一个极其重要的特性,因为它对宝石的价值有很大的影响,将颜色参数正确地输入系统是至关重要的。

广泛使用的用于描述宝石颜色的模型是 GIA(美国宝石学院)提出的模型。它通过三个参数来描述每种颜色——色调、色调和饱和度。

色调定义了宝石的暗度或明度,可以很容易地用数字表示(GIA 建议从 2 到 8 的整数范围,较大的数字对应较暗的色调)。

这同样适用于饱和度,其范围从较弱的饱和度到生动的饱和度。它也可以映射到一个数字范围(1 到 8,较大的数字对应于更鲜明的饱和度)。

GIA® Hue wheel. ©GIA

当你开始使用色调时,问题就出现了。标准 GIA 色调色轮由 31 个描述彩色宝石的色调名称组成。对于宝石专业人员来说,这是一种很好的颜色视觉表现,在他们的日常工作中非常实用。但是为了将色调参数传递给算法进行进一步分析,我们需要用数字来表示它。

糟糕的是,如果你只是简单地将色调名称映射到 1 到 31 的数字(对于你的特定任务,你也可以考虑将色调映射到 0 到 360 的角度值),你会丢失非常重要的关于颜色的实际接近度的信息,这些信息位于数字范围的最开始和最末端。

例如,如果我们从映射到 1 的“红色”开始,我们以映射到 31 的名为 slpR 的“略带紫红色”的颜色结束。所以,这两种在现实中非常接近的颜色在机器学习算法看来会完全不同。算法的这种颜色错误表示对于整体成功是至关重要的,必须避免。

那么,我们如何将色轮中的色调值映射到一个数字表示中,而不会丢失关于颜色接近度的重要信息呢?

乍一看,这里可以应用的一个可能的变通方法是用两个参数定义色调值,这两个参数可以作为 Sin 和 Cos 函数来计算。看看这个图表。

Replacing one Hue parameter with Sin and Cos seems to solve the problem. But this is not good!

这样,在色轮上具有接近 0 度或接近 360 度的色调的颜色将由数值接近的成对 Sin(色调)Cos(色调)呈现。答对了,我们已经解决了问题!或者我们有吗?

等等,我们现在已经向算法传递了 4 个描述颜色的参数——色调、饱和度、Sin(色调)、Cos(色调)!因此,我们增加了模型的维度,而我们希望尽可能地减少维度以避免数据稀疏。因此,这种方法似乎不是最佳解决方案。

换句话说,我们来思考这个问题。我们在这里试图实现的是在 3D 空间中找到这样一种颜色位置的数字表示,它将保留关于该空间中实际颜色的接近度的信息。

HSL color model based on polar coordinate system

用色调、色调和饱和度操作的颜色模型通常被称为 HSL 颜色模型 (L 代表亮度,在我们的例子中是色调)。HSL 模型基于柱坐标系,而柱坐标系本身是将极坐标系统扩展到三维的结果。

正如我们已经了解的,极坐标系统的缺点是当用数字表示边缘颜色时,不能解决它们的接近性。但是,如果我们研究另一种流行的坐标系类型——笛卡尔坐标系,我们会发现这种类型的系统对于进一步的机器学习目的来说没有这种缺点。

A Cartesian coordinate system

有几种基于笛卡尔坐标系的颜色模型,RGB 就是其中之一。在 RGB 中,我们通过对应于 RGB 3D 颜色空间中三个轴上的坐标的三个数字来寻址颜色。如果我们写下上例中颜色“红色”(色调= 1)和颜色“略带紫红色”(色调= 31)的坐标(r,g,b ),我们会看到这两种颜色的 r g b 值非常接近。Vuala!我们的算法将理解这两种颜色彼此接近,它现在可以正常工作了。非常重要的是,我们避免了增加模型的维数,因为我们仍然只用三个参数来描述颜色。

最后一点是在将颜色信息传递给算法之前,将我们的颜色从 HSL 颜色模型转换为 RGB。这可以通过使用 Python 中的colorsys模块非常容易地实现。本模块定义了colorsys功能。hls _ to _ rgb(h,l,s) 将颜色从 HLS 坐标转换到 RGB 坐标。

这些是我从这个案例中得出的结论:

  • 当心机器学习系统的极坐标系统的数字表示的限制
  • 选择合适的颜色模型,并在输入算法之前转换您的颜色数据
  • 小心导致维度增加的快速解决方案

这个案例是我现实生活项目Gemval(【www.gemval.com】T2)的一部分——基于机器学习算法的在线宝石鉴定服务。

使用整数规划的彩色地图

原文:https://towardsdatascience.com/colour-maps-using-integer-programming-e46b6297aad4?source=collection_archive---------14-----------------------

运筹学有很多很酷很实用的应用,比如供应链优化(我的最爱!)、乘务调度、车辆路径和投资组合优化。

本文讨论了这些酷运筹学应用之一。我们将使用一种称为整数规划(IP)的技术来解决地图着色难题。该难题指出,给定一个带有边界实体(例如国家、州、县)的地图,为每个实体着色所需的最少颜色数是多少,使得没有两个相邻实体具有相同的颜色。

这个地图着色问题对应于运筹学中一个著名的问题,称为顶点着色问题。在顶点着色问题中,给我们一个无向图,要求我们给它的顶点分配颜色,使得没有两个相连的顶点具有相同的颜色,当然,使用尽可能少的颜色。地图着色和顶点着色之间的对应是非常明显的,这使得它成为“商业问题”如何映射到“一般运筹学问题”的一个很好的例子,正如我在以前的文章运筹学的大图景中所讨论的。

下图描述了一般流程。

  • 选择未着色的地图
  • 将地图建模为无向图
  • 用你最喜欢的算法给无向图上色
  • 将彩色无向图转换回相应的地图

我写了两个 Python 包,顶点颜色解算器地图绘制器,它们将帮助我们用大约 10 行代码完成这个过程。让我们浏览一下代码。

首先,您需要按照 Github 存储库上的说明安装软件包。

成功安装软件包后,导入以下类和函数

from vertex_colorer.solver import Solverfrom map_grapher.core import load_map_data, plot_map, color_map,\save_to_file, build_adjmat

map_grapher 加载的函数允许你选择一个地图,将其建模为一个无向图,并使用一个彩色无向图给你的地图着色。该软件包目前支持美国所有州的县地图以及一个国家地图。

在这个演示中,我将选择亚利桑那州作为一个例子。让我们加载地图

state = load_map_data('Arizona')

状态变量保存从 geojson 文件加载的地图数据。接下来,我们将使用 plot_map 函数绘制地图

figure = plot_map(state, map_title='Arizona map')

如果您使用 Jupyter 笔记本,您可以直接从图形查看地图,如果您在命令行上,您可能希望将图形保存到文件中

save_to_file (figure, 'arizona_black_and_white_map.png')

不错!现在下一步是将这个地图建模为一个无向图。我们可以使用下面的代码做到这一点

matrix = build_adjmat(state)

build_adjmat 函数获取地图数据并将其转换为邻接矩阵,这是我们将用来表示无向图的数据结构。邻接矩阵看起来像这样

[[1, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0],
 [0, 1, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 0, 1],
 [0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 1],
 [1, 0, 0, 1, 1, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0],
 [1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0],
 [0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1],
 [0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0],
 [0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0],
 [1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0],
 [0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0],
 [0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0],
 [0, 1, 1, 1, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 1],
 [1, 1, 0, 1, 0, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0],
 [0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1],
 [0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 1]]

每个元素代表无向图的两个顶点之间的一条边。如果有边(即两个顶点相连,或者从业务问题的角度来看,对应的地图实体相邻),则值为 1,否则为 0。

我们现在可以将这个矩阵传递给我们的求解器

solver = Solver(matrix)

求解器被实例化并保存无向图。为了给图表上色,你需要选择一种方法来使用。这里我使用术语“方法”而不是“算法”,因为它们并不完全相同。例如,我们将在本演示中使用的 IP 求解器将无向图本身建模为一个整数程序,然后使用分支算法(以及其他方法)来求解该模型,然后将其转换回无向图。或者,我们可以使用动态规划算法或贪婪启发式算法直接在无向图上操作。

让我们要求求解器使用 IP 给无向图着色

solver.solve('IP')

瞧啊。我们完了。可以使用解决方案属性访问该解决方案。

solver.solution

这将为我们提供以下数据结构

[[0, 0], [1, 1], [2, 3], [3, 1], [4, 2], [5, 0], [6, 2], [7, 3], [8, 3], [9, 3], [10, 3], [11, 0], [12, 2], [13, 1], [14, 2]]]

列表中的每一对都有两个值,第一个是顶点标识符(索引),第二个是指定的颜色。

最后,我们使用颜色映射函数将这个解决方案传递给业务层面的问题

colored_map = color_map(state, solver.solution)

我们按照同样的步骤绘制地图并保存到文件中

fig = plot_map(colored_map, map_title='map of Arizona')save_to_file (fig, 'arizona_colored_map.png')

这是完整的脚本

#!/usr/bin/env python from vertex_colorer.solver import Solverfrom map_grapher.core import load_map_data, plot_map, color_map,\save_to_file, build_adjmat SELECTED_MAP = 'Arizona' if __name__=="__main__": state = load_map_data(SELECTED_MAP) figure = plot_map(state, SELECTED_MAP+'_bw') matrix = build_adjmat(state) solver = Solver(matrix) solver.solve('IP') colored_map = color_map(state, solver.solution) fig = plot_map(colored_map, map_title=SELECTED_MAP+'_colored') save_to_file (fig, 'arizona_colored_map.png')

你应该能够自己使用代码并给一些地图上色。请注意,根据您选择着色的州,求解器运行时间会有所不同。在我自己试验了几个州之后,我建议你从没有那么多县的州开始,然后一步步往上。您会注意到,运行时间不是县(顶点)数量的线性函数,而是连接密度的线性函数。当你尝试管理加州时,你会看到这一点(祝你好运!).

到目前为止,我只实现了 IP 解算器。下一步是实现其他求解器,如约束编程、动态编程和贪婪试探法,看看它们与 IP 相比如何。完整的代码和更详细的解释可以在这个要点中找到。如果你有任何问题,请尽情享受并随时给我写信!

组合优化:使用 Google 的 OR 工具从理论到代码

原文:https://towardsdatascience.com/combinatorial-optimization-from-theory-to-code-using-googles-or-tools-2e55da55f028?source=collection_archive---------9-----------------------

在这篇文章中,我将考虑一个来自组合优化的问题,这个问题可以理解为一般图上的约束优化。这让我有机会以一种比通常只涉及神经网络更普遍的方式介绍复杂网络的概念和语言。这里开发的概念将用于神经网络模型物理学的后续系列。

我不会从最一般的角度来讨论网络理论,我将在这里专注于解决一个特定的问题,从建立数学模型到使用 Google 的运筹学(或工具)库对其进行数值实现。最后,我将讨论组合优化的一些应用以及它与统计力学和计算机科学的联系。这篇文章本质上是技术性的,我决定不回避方程,而是一步一步地引导你通过数学。希望这能引发你的好奇心!

如何用最少的切口在饥饿的孩子中分享巧克力棒?

让我们开始定义我们想要解决的问题。有长度不等(整数)的 m 巧克力棒和想要不同数量巧克力的 n 饥饿儿童。你可以切巧克力棒,目标是确保每个孩子都能得到他们想要的量。写一个程序来分配巧克力,这样你可以切得最少。

解决方案:我决定解决问题的方式是把它映射成一个网络优化问题。我们有两个长度为 m 的输入向量 BC

表示巧克力棒的数量。每个酒吧有 b1,b2 …可用的巧克力单位

n 是孩子的数量,每个孩子想要 c1,c2,…块巧克力。我们定义了全连接(FC)有向网络(意味着连接仅从源节点到漏节点)。下图是 B = (2,5,7,3)和 C = (3,2,6,1,2)的问题实例。

请注意,连接有一个箭头来定义它们的方向。在数学上,这些连接被编码在一个连接矩阵中

其条目指定从源节点 i 移动到漏节点 j 的单元数量。我们为每个连接分配一个成本

我们希望优选完美匹配(例如,示例中的 2 — >2 和 3 — >3),即零成本。这意味着供应和需求节点之间的“距离”必须为零。将欧几里德距离作为图上的自然度量,我们定义:

此时我们需要定义系统的目标函数,或者用物理学家的语言来说,问题的哈密顿量:

第二个等式中的表达式是哈密顿量的“矢量化”实现;我们已经定义了

作为长度为 m 的单位向量,而 Ic 的长度为 n 。注意,矩阵 MX 之间的乘积是逐元素的。这是最小成本问题的哈密顿量;通过最小化哈密顿量,我们选择成本较低的矩阵元素 X 。我们现在推测最小截形对应于图上最小长度(即成本)的路径。有两个约束要强加:一个关于“当前”守恒,另一个关于 X 的元素是正定的。在节点之间流动的两股“电流”表示:

如果我们将通过网络的“通量”定义为

和偏置向量

然后我们需要加强元素方面的“巧克力保护”约束:

最后,我们需要强制连接矩阵的矩阵元素都是正的:对于[1,m]中的所有 i 和[1,n]中的 j ,X >0。这个问题可以用拉格朗日形式重新描述为:

其中我们引入了两个拉格朗日乘数λ和μ来加强约束。注意不等式约束需要遵循卡鲁什-库恩-塔克条件[2]: X > 0, mu > 0 和

上述示例的解决方案如图所示。

切割对应于每一行 X 上非零元素的数量。我们认为一个切割是一个分叉,所以在下面的例子中,单元 2(自下而上计数)用一个切割将原来的 5 个单元一分为二。因此,切割对应于在每一行 X 上具有 l > 1 个非零矩阵元素。你可以在我的 GitHub 上找到解决问题的 python 代码,连同一步一步的讲解,或者下面随便看看。我使用过谷歌的约束优化库,我发现相对于 Scipy 的优化工具来说,它更容易使用,也更有效。因此,如果您对学习如何使用这些库感兴趣,您会发现这里考虑的简单问题是解决更复杂问题的有用教程。另请注意,OR tools 已经实现了一个最小成本函数,您可以调整该函数来解决上述问题。如果你不想从头开始做这件事,这是一个有效的选择…但是乐趣在哪里呢?

最小费用问题是组合优化中的经典问题之一;左图给出了这个问题的一个更经典的表述:

工厂(节点 1)生产一定数量的货物,需要通过不同的路线运送到目的地(节点 4 和 5)。每条路线都有相关的成本和可以运输的货物的最大容量。这个问题可以按照上述步骤连同对矩阵元素边缘连接矩阵的进一步限制来解决,

其中 l 是每个边的最大容量。

从这里去哪里

在过去的几十年里,物理学家被随机、组合优化问题所吸引,因为它们与统计力学有关,见参考文献。[1,3].这些问题与一类被称为自旋玻璃的模型有关,这类模型对应于具有随机耦合的伊辛模型。这些模型展示了几个有趣的特征,并且是几个神经网络模型的灵感来源。

在下面的帖子里会有更多关于这个的内容!目前,我只想展示巧克力分配问题是如何在随机输入/输出关系的统计力学问题中被重新铸造的。关联吉布斯测度和约束配分函数:

请注意,该问题的哈密顿量是无量纲的,因此可以认为逆“温度”在 h 中被重新调整。如果β是随机变量,我们需要对其分布的自由能进行平均

其中最后一个表达式是复制的分区函数。如何解决这类问题将是以后文章的主题。

一些有用的参考资料:

[1] M. Mezard,A. Montanari,信息、物理和计算,牛津大学出版社(2009)

[2] C. M. Bishop,模式识别与机器学习,Springer (2006)。

[3] M .梅扎德,g .帕里西,《形体快报》杂志,1985 年,46 期(17),第 771–778 页

理论物理学家,从事复杂系统和量子突现现象的研究。我目前在人工智能领域工作,尤其对神经网络、它们与物理学的联系以及相关的基础问题感兴趣。查看 Mirco Milletari 的所有帖子

发布2018 年 1 月 28 日 2018 年 1 月 30 日

原载于 2018 年 1 月 28 日 equat10ns.wordpress.com

结合 LDA 和词嵌入的主题建模

原文:https://towardsdatascience.com/combing-lda-and-word-embeddings-for-topic-modeling-fe4a1315a5b4?source=collection_archive---------5-----------------------

“Business newspaper article” by G. Crescoli on Unsplash

潜在狄利克雷分配(LDA)是一种经典的主题建模方法。主题建模是无监督学习,目标是将不同的文档分组到同一个“主题”中。

一个典型的例子是将新闻聚集到相应的类别,包括“金融”、“旅游”、“体育”等。在单词嵌入之前,我们可能大部分时间使用单词袋。然而,在 Mikolov 等人于 2013 年引入 word2vec(单词嵌入的例子之一)后,世界发生了变化。Moody 宣布了 lda2vec,它将 lda 和词嵌入结合起来解决主题建模问题。

看完这篇文章,你会明白:

  • 潜在狄利克雷分配
  • 单词嵌入
  • lda2vec

潜在狄利克雷分配

Photo: https://pixabay.com/en/golden-gate-bridge-women-back-1030999/

LDA 在主题建模领域很有名。基于单词使用的文档聚类。简单来说,LDA 使用单词袋作为聚类的特征。详细情况,你可以看看这个博客

单词嵌入

Credit: https://pixabay.com/en/books-stack-book-store-1163695/

单词嵌入的目标是解决自然语言处理问题中的稀疏和高维特征。有了单词嵌入(或向量),我们可以使用低维(大多数时候是 50 或 300)来表示所有单词。详细情况,你可以看看这个博客

lda2vec

lda2vec 包括两个部分,即单词向量和文档向量,用于预测单词,以便同时训练所有向量。它通过跳格模型构建了一个词向量。简而言之,它使用目标词预测周围的词来学习向量。第二部分是文档向量,由

  • 文档权重向量:每个主题的权重。利用 softmax 将权重转换为百分比。
  • 主题矩阵:主题向量。一列表示一个主题,而一行存储每个主题附近的相关单词。

https://multithreaded.stitchfix.com/blog/2016/05/27/lda2vec/#topic=38&lambda=1&term=

文档向量的公式为

Moody, Mixing Dirichlet Topic Models and Word Embeddings to Make lda2vec (2016)

  • DJ:j 文档向量
  • pj0:“0”主题中 j 文档的权重
  • pjn:“n”主题中 j 文档的权重
  • t0:“0”话题的向量
  • TN:“n”话题的向量

当主题向量被共享时,文档之间的权重是不同的。更多细节,你可以查看穆迪的原创博客

拿走

对于源代码,你可以看看这个笔记本

  • 正如作者所建议的,如果你想拥有人类可读的主题,你应该使用 LDA。如果你想用另一种方式重做光学模型或者预测用户的话题,你可以试试 lda2vec。

关于我

我是湾区的数据科学家。专注于数据科学、人工智能,尤其是 NLP 和平台相关领域的最新发展。你可以通过媒体博客LinkedInGithub 联系我。

参考

穆迪·克里斯托弗。“混合狄利克雷主题模型和单词嵌入来制作 lda2vec”。2016.https://arxiv.org/pdf/1605.02019.pdf

用 D3.js 从玩具视觉过渡到真实应用

原文:https://towardsdatascience.com/combining-d3-with-kedion-graduating-from-toy-visuals-to-real-applications-92bf7c3cc713?source=collection_archive---------10-----------------------

将 UI 元素绑定到 D3 视觉效果

注意 : D3 现在使用了 Observable,我在这篇文章中提到过。

我们经常孤立地学习技术和方法,与数据科学的真正目标脱节;创造由机器学习驱动的真实应用。但是我说的真正的是什么意思呢?对我来说,真实意味着我们接触的任何技术都应该是整体应用的一部分,提供真正的用户体验。

训练新的 TensorFlow 模型?建立一个基于面部识别的应用程序。编写了一个自动执行常见数据清理任务的库?创建一个界面,使团队能够通过浏览器合并和清理数据。发现了一种新的文档分类方法?制作一个上传公司电子邮件档案的工具,识别与相关主题相关的所有主题,如团队建设。

我热衷于制造真正的产品,因为我知道这是在这个领域做好的唯一途径。我们需要通过人们与之互动的真实软件来表达机器学习概念,并理解如何用数据来打造用户体验。

孤立工作的一个常见例子是数据可视化。虽然“用数据讲故事”可能很强大,但故事本身并不能带来真正的解决方案。如果您的数据科学从未超越幻灯片,那么您就没有真正做过数据科学。利益相关者需要接触和感受解决方案的样子。有了今天的高级工具,数据科学家没有借口不编写真正的应用程序来展示他们的工作。

如果您的数据科学从未超越幻灯片,那么您就没有真正做过数据科学。

在这篇文章中,我将展示如何通过结合 D3 和 Azle 来构建真正的应用程序。让这些应用成为现实的是 D3 的绑定到应用中的 UI 元素。正是元素和视觉之间的这种联系确保了可视化不仅仅是讲故事的人;它们是解决实际问题的应用程序的组成部分。

内容

  • 简介
  • 设置您的项目
  • 构建一个 AZLE 应用程序
  • 增加 D3 视觉效果
  • 包装器参数和额外函数
  • 将 D3 绑定到 UI 元素
  • 添加动画
  • 动态改变数据
  • 图表间的通信
  • 运行时间表
  • 委托点击事件
  • 客户端数据

我创建了一个演示应用程序,展示了本文中讨论的主题。你可以在这里查看应用以及在 GitHub 上对应的回购

Example application that combines Azle with D3.

D3 和 AZLE

在我题为学习构建机器学习服务、原型化真实应用程序以及将您的工作部署给用户的文章中,读者第一次接触到了 Azle 。Azle 使用布局、预样式元素和易于使用的 REST API,支持快速的产品原型开发。

D3.js 是一个 JavaScript 库,用于生成动态的、交互式的数据可视化。D3 能够生成由数据驱动的图表和图形,并且已经成为行业标准的可视化工具。

虽然在 D3 的网站上有很多视觉效果的例子,但是对于如何在应用程序中包含这些视觉效果却没有什么支持。尽管许多库有助于更容易地创建 D3 视觉效果,但这并不等同于实现应用程序和 D3 之间的通信。

我们可以尝试使用我们组织当前的技术堆栈进行原型制作,但是当我们想要快速产生一个新的想法时,这是多余的。我们也可以使用一个包,允许我们用 R 或 Python 来构建“交互式 web 应用程序”。但是这种选择并不能使应用程序具有组织现有产品的外观和感觉。想象一下,试图用 Shiny 重现亚马逊或网飞的界面。还有一种将 UI 元素添加到视觉效果的“小部件方法”,但这将 UI 限制在视觉效果本身,而不是与完整的应用程序集成。

Azle 对 D3 的支持是不同的,因为没有你不能用 Azle 完成的布局或样式。任何 HTML、CSS 或 JavaScript 都可以添加到 Azle 应用程序中,尽管您通常只需要它自己高度声明性的语法。您组织的产品的外观和感觉可以很快被模仿,这意味着您的机器学习正在利益相关者认可的应用程序上进行测试。从对知名产品进行改进的原型中赢得认同要容易得多。

让我们开始吧。

设置

在这一节中,我将介绍设置 D3 与 Azle 一起工作的必要步骤。一旦你完成了这些步骤几次,你会发现设置你的 Azle_D3 项目又快又简单。这些步骤对于您决定与 Azle 一起使用的任何 D3 可视化都是相同的。

步骤 1:选择初学者视觉

网上有大量的 D3 例子,从头开始构建 D3 是没有意义的。你可能要重新发明轮子,把宝贵的开发时间花在寻找现有视觉效果上。第一步是从 D3 的网站选择一个现有的 D3 视觉。你可以点击顶部的例子来预览许多视觉效果,这里有更大的列表。

D3 Website

让我们选择一个基本图表来展示我们如何设置我们的项目。我将选择这里的条形图:

[## 条形图

迈克·博斯托克街区 3885304 号

bl.ocks.org](https://bl.ocks.org/mbostock/3885304)

步骤 2:创建目录结构

与任何应用程序一样,我们需要创建一个目录结构来保存我们的文件。你可以在这里下载目录结构以节省时间。下载后,检查您的下载文件夹。您应该看到以下内容:

**azle_d3_directory**
├── **d3_visuals** └── barchart.html
├── **data** └── barchart.tsv
├── index.html
├── **scripts**

d3_visuals 文件夹保存 d3 提供的 html 文件。数据文件夹保存 D3 读取的本地数据。脚本保存任何 Azle 脚本,index.html是我们应用程序的主页面。这些文件现在是空的,因为我们将在本文中粘贴所需的代码。

无论我们需要支持多少视觉效果或数据集,这种相同的结构都将服务于我们的应用程序。更多的 D3 视觉效果意味着更多的。d3_visuals 文件夹中的 html 文件,以及 data 文件夹中的更多数据集。

步骤 3:从 D3 添加 HTML 和数据

因为我们使用 D3 的条形图,所以我们将添加 D3 示例页面上提供的 HTML 和数据用于条形图。

获取 HTML:

Grabbing html from D3 example page

在上面的 GIF 中,你可以看到我从 D3 的条形图示例中抓取 html,并将其粘贴到 d3_visuals 文件夹中的 barchart.html 文件中。

获取数据:

Grabbing data from D3 example page

上面,我从 D3 的条形图示例中抓取 data.tsv,并将其粘贴到 data 文件夹中我的条形图. tsv 文件中。D3 使用的另一种常见数据格式是 CSV。数据格式并不重要,因为我们正在抓取的视图已经被创建来读取这种数据类型。稍后,我们还将看看使用 JavaScript 对象存储在客户端的本地数据。

步骤 4:从 Azle 添加 HTML 模板

我们现在准备开始使用 Azle 创建一个与 D3 条形图交互的应用程序。我们从所有 Azle 应用程序开始;通过使用 Azle 的 html 模板文件:

Beginning HTML template for Azle application.

这是我们开始添加 Azle 函数来构建我们的应用程序所需要的一切。

步骤 5:包装 D3 视觉效果

我们需要一种方法来将数据从我们的应用程序传递到我们的 D3 视图。为了做到这一点,我们使用以下 3 个步骤对 D3 HTML 文件(【barchart.html】T2)做了一个小小的修改:

  1. 将 Azle 库添加到 D3 文件中;
  2. 所有原生 D3 代码包装在 draw_visual 函数内;
  3. 将所有函数参数设置为 azle_args。

让我们用条形图视觉效果来做这些事情:

Azle has been added to D3’s .html file. Also, all D3 code has been wrapped inside the draw_visual function. Finally, we have set arguments[0] to azle_args.

取任意一个 D3 代码,简单地用 draw_visual 函数将它包装起来。还要添加行 azle_args = arguments[0] 。这使得数据和函数能够进出我们的 D3 视觉。

寻找钩子

有了上面的步骤,我们可以使用 Azle 将数据和函数传入传出我们的 D3 visual。决定传递哪些数据/函数取决于我们希望动态改变什么。

例如,假设我们希望允许用户通过简单地单击应用程序中的一个按钮来更改驱动可视化的数据集。在这种情况下,我们查看 D3 代码以了解数据集在哪里被读取,并用 azle_args 和我们选择的替换文件名:

Finding D3 hooks and replacing with azle_args.

在上面的 GIF 中,我使用了 [“数据选择”]。这个键可以是您喜欢的任何键,只要您在 wrapper_arguments 中使用相同的键,这将在下面讨论。换句话说,azle_args 用于接受来自 azle 的数据,并使用它的值替换 D3 的硬编码部分。

我们可以在 D3 中找到各种挂钩,将我们的视觉绑定到应用程序的其他部分。另一个例子是使用 Azle 的颜色选择器来允许用户改变我们的条形图的颜色。在这种情况下,我们在 D3 内部查找设置条形颜色的位置,并用 azle_args["bar_color"]替换颜色。

用 D3 制作真正的应用程序

现在我们已经设置好了一切,我们可以将我们的 D3 可视化添加到一个真实的应用程序中。因为 Azle 是为构建应用程序而设计的,所以让我们创建一个 Azle 布局添加我们的条形图。然后我们会看到我们如何与我们的视觉沟通。

1)启动一个简单的 Web 服务器

为了使用我们的应用程序,我们需要一个 web 服务器。这些很容易在任何本地机器上创建。例如,在我的 Mac I 上打开终端,进入 azle _ d3 _ 目录,运行下面一行:

python3 -m http.server

现在我打开浏览器,进入 http://localhost:8000

2)准备页面

我们一如既往地从准备 Azle 的基础页面开始。虽然我有一个脚本文件夹,但我会将脚本标签之间的所有内容放在我的 index.html 文件的底部,create_azle 函数内的:

Basic page setup for Azle.js

让我们给我们的应用程序添加一些基本的样式、一个部分和一个布局:

我们现在有了一个布局,可以用来在屏幕上定位我们的内容:

An Azle layout

我使用 1 行 2 列的布局,因为我希望我的 UI 元素在左边,我的 D3 视觉在右边。

4)添加 D3 可视化

在我们的应用程序中添加 D3 视觉效果需要 3 个主要部分:

  1. add_d3_visual 函数;
  2. wrapper_arguments 对象;
  3. 额外功能对象。

add_d3_visual

为了添加我们的 D3 视觉,我们使用 Azle 的 add_d3_visual 函数。在这里,我将条形图添加到我在上面创建的布局的第二个单元格中:

Adding a D3 visual in Azle

注意我是如何在 add_d3_visual 函数中指定 wrapper_argumentsextra_functions 的。我们现在将创建这些对象。

包装 _ 参数

与任何 JavaScript 对象一样,wrapper_arguments 是一个属性列表,每个属性是一个键/值对。在这里,我们列出了想要传递给 D3 视觉效果的任何值(就像上面的 data_choice 示例)。我将在我的条形图中找到一串我想使用 Azle 设置的钩子(并最终在我的应用程序中使用 UI 元素动态控制)。下面是我的条形图的 wrapper_arguments 对象:

Setting properties in wrapper_arguments object

对于其中的每一个,我都用 azle_args["key"] (例如,azle_args["bar_color"])替换了我的条形图 D3 代码的一部分。

额外功能

实际上有 2 种方法我们可以使用 Azle 将信息传递给 D3 。我们已经看到了如何使用 wrapper_arguments 传递数据。只要我们在 D3 中找到挂钩,我们只需添加 azle_args["key"]来控制该属性。但是如果我们的 D3 视觉是用 CSS 而不是 D3 来样式化的呢?

例如,我们的条形图中的条形颜色使用 CSS 设置在顶部:

在这种情况下,我们可以像上面一样修改 D3 代码,使用 azle_args 为条形着色,或者我们可以将一个函数传递到我们的 visual 中,并直接设置“bar”类的样式。让我们来看看这两种场景的区别。

场景 1 :用 azle_args 传递值

在下面的 GIF 中,我在 D3 内部查找创建条形图的位置,然后添加必要的代码以接受来自 azle_args 的条形图颜色:

Modifying D3 to accept bar color dynamically using azle_args.

这意味着我添加到我的 wrapper_arguments(在 barchart_wrapper_args 中)的 bar_color 属性将被传递到我的 D3 visual 中,并且条将被适当地着色。

场景 2 :将函数直接传递给 D3

在这个场景中,我将使用 extra_functions 来设置条的颜色,允许我们在视觉中操作 CSS。在这种情况下,我们使用我们想要影响的元素的类名。上图(红色箭头)中,我们看到我们的酒吧的类名是“酒吧”Azle 使用类名来定位元素,所以这是一个自然的选择。也就是说,JavaScript 和 D3 在样式和事件方面有一些差异,所以我们将在额外的函数中使用 Azle 专用的 style_d3 函数。

因为我们已经使用 wrapper_arguments 很好地实现了条形颜色,所以我将使用其他颜色。事实上,我发现如何使用 D3 给条形图上的标签着色和调整大小很有挑战性。在一些 D3 例子中,我们看到这些标签使用 CSS 样式,使用名称文本以及填充字体大小。让我们在 extra_functions 中使用 Azle 的 all_style_d3 函数来定位“文本”:

我们将我们的 style_d3 函数添加到 extra_functions 对象中,我称之为条形图 _extras:

Creating a barchart_extras object

style_d3 前面的 all_ 前缀是 Azle 定位一个类的所有实例的方式。因为我们想给所有的条着色,所以我们在这里使用它。你可以回顾一下 Azle 的文档来熟悉 Azle 的风格语法。

现在,当我们的 add_d3_visual 函数被调用时,两个包装器 _ 参数额外 _ 函数都将被传递给我们的 D3 visual :

让我们为更好的对比设计我们的应用程序。

az.**style_sections**('my_sections', 1, {
     "background" : "darkslategrey"
 })

我们可以看到,因为列在 wrapper_arguments 中,所以设置了条形颜色,因为在 extra_functions 中使用了 all_style_d3,所以对文本标签进行了着色和调整大小。

添加条形图后,我们的布局有点变形,但我们会尽快修复。

我们不必在 extra_functions 中使用 Azle 函数。我们还可以使用 extra_functions 将普通的 Javascript 传递给任何 D3 visual。只要确保函数用引号括起来。

5)添加 UI 元素

让我们在布局的左侧添加一些 UI 元素。我首先将另一个布局添加到我的原始布局的第一个单元格,以便将我的 UI 元素放置在左侧。然后,我将我的 UI 元素添加到新布局的每个单元格中:

Adding UI elements to Azle Application

让我们清理一下我们的布局,做一些基本的样式。首先,我将设置第一个布局上每一列的宽度:

az.**style_layout**('my_layout', 1, {
     "column_widths" : ['20%', '80%']
 })

我们可以看到 UI 元素和 D3 visual 现在在布局中的位置是正确的。我还想让左边的 UI 元素在它们自己的单元格内居中。

az.**all_style_layout**('element_layout_cells', {
     "halign" : "center"
 })

另外,默认的按钮颜色滑块标签与深色背景不太匹配。让我们改变这些:

az.**style_button**('data_button', 1, {
     "background" : "rgb(254, 225, 180)",
     "color" : "black"
 })

 az.**style_slider**('my_slider', 1, {
     "color" : "white"
 })

最后,让我们移除两个布局上的边框,给我们一个干净的应用程序。将两种布局样式都设置为包含 0 的边框属性:

az.**style_layout**('my_layout', 1, {
     "column_widths" : ['20%', '80%'],
     "border" : 0
 })

 az.**style_layout**('element_layout', 1, {
     "border" : 0
 })

Removing Borders on Azle Layouts

既然我们已经知道了如何添加一个可视元素,以及一些基本的 UI 元素,那么是时候开始将我们的 D3 可视元素绑定到 UI 元素了。

将 D3 视觉效果绑定到 UI 元素

用 D3 创建真正的软件是为了确保我们可以在应用程序中使用 UI 元素与可视化交互。Azle 使用了 2 个函数来与 D3 交互:

  1. call_d3_wrapper
  2. call_d3_extra

调用 _ d3 _ 包装器

在上面的第 4 部分中,我们使用了 wrapper_arguments 来列出我们想要传递给 D3 visual 的任何值。 call_d3_wrapper 函数用于动态改变我们的 wrapper _ arguments。这意味着我们放在 D3 视觉元素中的任何挂钩(使用 azle_args)都将响应我们在 call_d3_wrapper 中指定的更改。

call_d3_wrapper 函数使用普通的 Azle 风格的目标,带有 target_class 和 target_instance,还列出了与我们的 wrapper_arguments 相关的属性:

*az.**call_d3_wrapper**('my_barchart', 1, {
    "wrapper_arguments" : barchart_wrapper_args,
    "extra_functions" : barchart_extras,
    "bar_color" : passed_value
})*

注意 call_d3_wrapper 函数期望 列出 wrapper_arguments extra_functions 。我们指定 extra_functions 的原因是为了在重绘视图时保留样式。在上面的例子中,我计划向“bar_color”属性动态传递一个值。

让我们将更改数据按钮绑定到条形图上。在 Azle 中,我们使用 add_event 函数来将事件附加到 UI 元素:

*az.**add_event**('data_button', 1, {
     "type" : "click", 
     "function" : ""
 })*

这里我们简单地指定了事件的类型(比如点击)和事件触发时调用的函数。我们想在用户点击按钮时调用 call_d3_wrapper 函数。为了让这更有用,让我们允许用户在点击按钮时在数据集之间来回切换。我将创建两个独立的 change_data 函数,每个函数都用适当的 data_choice 调用自己的 call_d3_wrapper。然后我会用 Azle 的 toggle_functions 作为 add_event 里面的函数。让我们使用 Azle 的包装函数来组织我们的代码。

结果:

我们刚刚创建了 UI 元素和 D3 视觉元素之间的第一个绑定。

对于下拉菜单,让我们允许用户在 3 种不同的颜色中选择我们的条。首先,我们需要返回到我们的 add_dropdown 函数,并添加选项,我们最初将其留空:

*az.**add_dropdown**('element_layout_cells', 2, {
     "this_class" : "choose_drop", 
     "title" : "choose color...",
     "options" : ['blue', 'yellow', 'hotpink']
 })*

我还把标题改成了“选择颜色”

现在我们可以像以前一样使用 add_event ,但是这一次将目标指向我们的 dropdown 元素,并选择 change 作为事件类型。我将把我的 call_d3_wrapper 放在一个名为 recolor_bars 的函数中,然后用我的 add_event 调用它:

Binding a dropdown to a D3 Visual in Azle

注意,这次我是向 add_event 内部的函数传递一个参数(recolor _ bars()函数)。我传递的参数是从下拉列表中选择的值(使用 this.value 是 JavaScript 中的标准做法)。

结果:

现在让我们将滑块绑定到条形图上。现在我们知道该怎么做了。这次最大的不同是事件类型被称为 as_change 。当滑块移动时,该事件类型传递参数。让我们允许用户更改图表的上边距:

Binding a slider to a D3 Visual in Azle

如果你试着移动滑块,你会发现图表变化不大。我们需要增加滑块元素的取值范围,使其对我们的用例有用:

*az.**add_slider**('element_layout_cells', 3, {
     "this_class" : "my_slider", 
     "min_value" : 0,
     "**max_value**" : 100,
     "default_value" : 5
 })*

结果:

call_d3_extra

正如我们有一个函数可以动态改变我们的 wrapper _arguments 一样,我们也有一个函数可以动态改变我们的 extra_functions。我们在上面的第 4 节中使用了 extra_functions 来设置文本的颜色和大小。让我们使用 call_d3_extra 将我们的滑块绑定到文本大小,允许用户动态地改变文本大小。 call_d3_extra 函数的使用方式与 call_d3_wrapper 相同:**

Dynamically changing tick size in a D3 visual using Azle

注意,当我们使用 call_d3_extra 时,转换更加平滑,因为图表没有被重画。

我想展示的另一个 UI 元素是颜色选择器。让我们添加另一个按钮,它提供了一个颜色选择器,用户可以使用它来动态地改变条形的颜色。首先,我们需要向 elements_layout 添加另一行。然后我们可以添加并样式化我们的按钮,并使用 add_event 来触发 add_color_picker 函数:

结果:

Using the color picker in Azle

在本文的剩余部分,我将展示视频开头提到的演示应用程序中内置的示例。这个包含所有源代码的完整示例应用程序可以在 GitHub 这里找到。

添加动画

我们有很多方法可以将 Azle 功能与 D3 混合搭配。一种选择是添加动画。我们可以结合* call_d3_extra 和 Azle 的 animate_element 函数来动画化 d3 里面的一个特定元素。*

在这种情况下,我们需要为 D3 中的每个元素分配一个惟一的 id。我们可以在 D3 中直接这样做,或者使用 Azle 的 all_apply_id 函数。

一旦分配了 id,我们就可以使用 Azle 的 all_add_event 函数来添加一个悬停事件,每当元素被悬停时,该事件就会调用 Azle 的 animate_element 函数。

结果:

注意我们没有使用 all_ 前缀来动画显示所有的条。这将导致当只有一个条被悬停时,所有的条都被激活,这不是期望的行为。

这是另一个动画示例:

你可以用 Azle 提供的任何动画进行实验。

动态更改数据

一个常见的场景是允许用户更改驱动特定视觉的数据。我们已经看到了这样的例子。下面是演示应用程序中使用的示例:

这里有一个带有单选按钮的按钮,我们可以在不同的数据集以及数据子集之间进行选择:

稍后,我们将看到如何使用从 REST API 获取的客户端数据来实现这一点。

保留样式

需要注意的一件重要事情是,我们如何在 UI 元素之间移动,而不破坏最近的更改。例如,在下面的散点图中,我可以更改圆形大小,然后更改图表宽度,更改数据集,并过滤数据,同时始终保持样式(注意 GIF 动画使过渡看起来不太平滑)。

2 个 D3 图表之间的通信

让 2 D3 图表相互交流通常很有用。例如,允许用户与一个视觉对象交互,并让该交互影响显示相应信息的第二个视觉对象,这可能是有意义的。

我们简单地添加 2 个视觉效果和一个桥接功能来完成这个工作。让我们试一试。

我们创建一个布局,用 1 行和 2 个单元格来容纳两种视觉效果。我称之为双重布局。然后我们像往常一样添加视觉效果:

条形图图表添加到布局单元格 1

折线图添加到布局单元格 2

将悬停事件添加到条形图中,即调用一个 桥函数 :

Calling a 2nd D3 visual with Azle

这里,我们将一些属性添加到条形图的 extra_functions 对象中。最重要的一个是“call_line_chart”,在这里我做了以下事情:

  • 将 id应用于所有条形元素;
  • 将悬停事件添加到所有 bar 元素中;
  • 悬停时调用桥接函数

前两步和我们制作动画的步骤是一样的。bridge 函数是当用户将鼠标悬停在条形图上的某个条上时调用的函数。桥函数需要调用第二张图上的call _ D3 _ wrapper:

桥接功能:

注意我们的条形图上的悬停事件是如何调用桥函数的。它使用前缀。这是因为桥函数存在于 D3 视觉之外。它还使用 Azle 的 get_target_instance()函数来获取使用其 id 的 bar 的实例。

结果:

2 D3 charts communicating with each other using Azle

注意,我们为这个条形图重用了相同的 HTML 文件(与本文开始时使用的相同)。我们只改变了它的 wrapper_arguments 和 extra_functions。

在上面的例子中,我使用 Azle 将一个悬停事件添加到视觉效果中。但是 D3 有自己的事件,使用 visual 自带的事件可能更有意义,尤其是 D3 支持的非标准事件。在下面的例子中,我使用 Azle 将笔刷可视化和水平条形图结合起来。在这里,我将左边刷牙的最小值和最大值传递给右边的条形:

在这种情况下,我找到了在 D3 中更新刷取值的位置,并使用了前面示例中讨论的相同的父前缀和桥函数方法,将这些值传递给我的 call_d3_wrapper 函数:

Passing Values from D3’s Brush Visual to Azle’s call_d3_wrapper

我创建了一个GithubGist你可以查看,查看上面例子的所有文件。

运行时间表

随着时间的推移,有时自动播放一组视觉效果是有意义的。当我们需要用时间维度的数据讲述一个故事时,这是有意义的。在下面的例子中,我将 call_d3_wrapper 与 Azle 的 call_every 函数结合起来,来遍历一组视觉效果:**

结果:

Using Azle’s call_every function to play timelines with D3

委派点击事件

委托 click 事件也是有用的,这样就可以有计划地点击 D3 visual* 中的元素。例如,D3 上的圆形包装视觉通常期望用户点击不同的圆形来放大。让我们允许用户从下拉菜单中选择一个选项来放大视图的各个部分。***

为此我们使用 Azle 的 click_d3 函数。

结果:

Using Azle’s click_d3 with packing visual

同样的方法,这次用的是地图:**

Using Azle’s click_d3 with map visual

…以及可折叠采油树:**

Using Azle’s click_d3 with tree visual

客户端数据

到目前为止,我们假设 D3 数据保存在磁盘上。例如,上面我们使用了 TSV 和 CSV 文件。对于模拟应用程序,这通常就足够了。但是有时我们需要使用客户端数据,在这种情况下,数据作为 JavaScript 对象被存储、读取或上传。

在这一节中,我将通过 3 种主要的客户端场景展示如何使用 Azle 和 D3:

  1. JavaScript 对象硬编码到我们的文件中;
  2. 从 RESTful API获取数据**
  3. 通过浏览器上传数据。

文件中的 JavaScript 对象

有时我们不需要磁盘上的数据,比如当我们模仿一个快速演示应用程序或使用不变的数据时。

在这个例子中,我将展示如何在数据存储为 JavaScript 对象的数据集之间进行转换。我将使用和弦图,它使用值的矩阵作为数据。首先,让我们创建 3 个矩阵,并将它们存储在一个名为 all_chord_data 的 JavaScript 对象中。我还将创建一个名为 switch_client_side 的函数,它使用 call_d3_wrapper 来设置 data_choice,就像我们之前所做的那样:

Switching between D3 datasets stored client-side using Azle

我们简单地将单选按钮绑定到 Azle 的 call_d3_wrapper 函数,以更改我们的 chord 图上的数据集。

结果:

从 REST API 获取数据

任何应用程序中的一个常见场景是从 REST API 获取数据。在需要运行分析并将结果返回给产品的机器学习应用中尤其如此。

Azle 的 call_api 函数就是用于这个目的。熟悉我的文章构建机器学习服务和原型化真实应用的读者会认识到这个功能。这允许我们进行 REST 调用,等待响应,然后在收到数据后运行我们选择的函数。让我们使用 call_api 从我为本文编写的 api 中获取数据:

结果:

这里我们可以看到从 call_api 接收到新数据后和弦图的变化。

从浏览器上传数据

允许用户从浏览器上传数据会很有用。与其他客户端场景一样,这适用于较小的汇总数据集。

在这里我创建了一个名为 my_data.json文件。在这个文件中是和弦图的矩阵,正如我们在上面看到的:**

my_data.json

这是标准的 JSON 格式,允许我索引不同的数据集。这里我只在我的文件中存储了一个矩阵,但是它可以是多个,就像我们在上面使用 JS 对象时所做的那样。

我们将使用 Azle 的 add_upload_button 函数来添加必要的 UI 元素:

Adding an upload button in Azle

数据文件上传后,我们必须决定要做什么。这里,我将在 function 属性(在 JavaScript 中称为“字符串文字”)的单引号之间嵌入我的 call_d3_wrapper 函数:

结果:

我们可以看到在上传时驱动我们视觉变化的数据集。

摘要

在本文中,我展示了如何将 D3 和 Azle 结合起来。具体来说,我们已经看到了如何将 UI 元素绑定到可视化,以确保我们的故事被集成到一个真实的应用程序中。如果 D3 和/或 Azle 不是你选择的工具,那也没关系。重要的是构建真正的应用而不是仅仅停留在幻灯片上的东西。你的组织将更好地理解数据和机器学习的好处,你的个人数据科学教育将增加十倍。**

一如既往,请在评论区提问。

如果您喜欢这篇文章,您可能也会喜欢以下内容:

*** [## 学习建立机器学习服务,原型真实的应用程序,并部署您的工作…

在这篇文章中,我将向读者展示如何将他们的机器学习模型公开为 RESTful web 服务,原型真实…

towardsdatascience.com](/learn-to-build-machine-learning-services-prototype-real-applications-and-deploy-your-work-to-aa97b2b09e0c) [## 机器学习工作流的 GUI 化:快速发现可行的流水线

前言

towardsdatascience.com](/gui-fying-the-machine-learning-workflow-towards-rapid-discovery-of-viable-pipelines-cab2552c909f) [## 创建 R 和 Python 库的分步指南(在 JupyterLab 中)

r 和 Python 是当今机器学习语言的支柱。r 提供了强大的统计数据和快速…

towardsdatascience.com](/step-by-step-guide-to-creating-r-and-python-libraries-e81bbea87911)

奖金票据

通过 call_d3_extra 使用其他 JavaScript

如果您对普通 JavaScript 和/或 jQuery 的语法更熟悉,您可以使用它们。任何脚本都可以传入 call_d3_extra 函数。下面是一个使用 jQuery 设计图表中条形样式的示例:

Passing regular jQuery into D3 visual using Azle

wrapper_arguments 和 extra_functions 中的“调用”属性

有时我们用 Azle 动态地改变 D3 值,并且需要我们前端的 UI 元素来记住我们传递的最后一个值。例如,假设我们在一个模态中有一个滑块,我们用它来调整我们的 D3 视觉。当我们关闭模型时,滑块消失了,每次弹出模型时,滑块都是从头开始创建的。为了确保滑块记住相同的值,我们可以简单地访问我们的 wrapper_arguments 对象:

Recalling the last set property in wrapper_arguments in Azle

现在,每当我们再次打开滑块时,该值就是我们最后设置的值。这可以防止 D3 在我们重新绘制图表时跳跃:

我们可以对我们的 extra_functions 对象使用类似的方法,尽管这次我们不能像上面那样只访问属性的键值。相反,我们使用 Azle 的 get_current_d3_value 函数,传递 barchart_extras 对象、我们赋予样式的名称以及样式本身:

Recalling the last set property in extra_functions in Azle

Azle 中的嵌入式函数

在本文使用的大多数例子中,从函数调用函数是通过如下方式实现的:

在这种情况下,我们从 add_event 内部调用 change_data,change_data 是它自己包含的函数。

另一种选择是直接将 嵌入 change_data()中的一个“字符串文字

为了嵌入函数,我们将要嵌入的函数放在两个单引号中。

这可能是编写应用程序的一种更快的方式,但是它也导致代码的模块化程度降低。向嵌入式函数传递参数也会带来一些挑战。您应该尝试使用 Azle 的 add_wrapped_function 来代替,如前所述,因为它允许我们将一组函数分组到一个单独的命名函数中。

更改个人 Web 服务器上的端口

如果您的端口 8000 已经被占用,您可以简单地在命令末尾添加您想要的端口号:

python3 -m http.server 7777

提交。失败。提高。

原文:https://towardsdatascience.com/commit-fail-improve-5c915c33dd86?source=collection_archive---------8-----------------------

这是我今年在加州圣地亚哥举行的数据科学围棋大会上,在 400 多人面前演讲的书面形式。

你如何将你的热情转化为事业?

我的答案是:通过不计后果的承诺。

去年,我参加了我的第一次数据科学会议。会议期间,我在笔记本上做了笔记,每个人都收到了一份礼包。在所有这些笔记中,有一个特别的笔记在一年内彻底改变了我的生活。

2017 年 11 月。加州圣地亚哥。我刚刚从德国飞过来参观第一届数据科学 GO 会议,由基里尔·叶列缅科和他的超级数据科学团队组织。在在线教育平台“Udemy”上成功教授超过 600,000 名学生数据科学知识后,他们希望召集有抱负的数据科学家参加一个拥挤的会议。

由于这也是我第一次参加会议,我不太知道会发生什么。但是我思想开放,什么都愿意做。当时,我的目标是进入数据科学领域,我对自己说:如果我能遇到一个人,一个唯一能在这个旅程中激励我的人,那就值了。

第一天,第二次谈话。这是本·泰勒的演讲(如果你不知道本,他是 Quora 上人工智能的头号作家。这应该暗示了他讲话的质量。).他在谈论如何成为一名摇滚明星数据科学家,他的观点之一是关于不计后果的承诺。

"如果你想进入数据科学领域,不要犹豫不决."

本认为,在这个领域,任何人都可以从零到六位数的年薪。但是这需要极大的热情和承诺。这肯定会很难。但是他建议:如果你刚刚从零开始,并且想进入这个领域,那么今天就开始参加聚会吧。今天去参加一个,然后承诺 3 个月后参加下一个。一定要提出一个让每个人都印象深刻的话题,比如胶囊网络或连体网络。
通常,Ben 对这一建议的第一个回答是,顺便说一下,这也是我当时作为数据科学新手的第一个想法:

“但我不是专家”——我不知道那个题目!”——“如果我让自己难堪了怎么办?”

正如你所看到的,逻辑阻碍了。而且理由很充分!你不是专家。你可能是数据科学的初学者,所以这看起来完全不合逻辑。但是本说:

“如果你承诺在 3 个月后的一次聚会上发言,3 个月后你就会成为那个主题的专家。”

尽管我有疑虑,但我很好奇。想想看:
我们参加多少次会议,得到多少启发?
在我们的生活中,有多少次我们会遇到鼓舞人心的人,并被激励去改变一些事情?

起初,我们非常活跃。但问题是,一旦我们开始以理性的方式思考改变某件事是否有意义,我们就会拖延。
更糟糕的是,几天后,我们在会议后达到顶峰的动力又降了下来。
什么都没变。
逻辑挡路。因此,我们找到了行不通的原因,并回到了老的做事方式。但是我们有办法防止这种情况吗?

这就是鲁莽承诺这个概念出现的地方:
先承诺。不考虑是否可能。

“如果你承诺在三个月后的一次聚会上展示自己,你将在三个月后成为一名专家”。

致力于你为自己设定的目标,一旦你在脑海中形成了这个目标是什么的形象,你的大脑就会激发你的创造力,让你想出一些东西。也就是说,你的大脑会告诉你如何到达那里,哪些资源可能有帮助,以及如何开始。

当我从会议回来时,我发现自己处于那种兴奋的状态。我在周末遇到的所有人和得到的所有意见都让我深受鼓舞。我以前也经历过这种问题:我有动力去改变生活中的某些事情,但却一直推着它,直到我失去了灵感。所以我向自己保证,这次不会了。我飞了半个世界不是为了这个。受本演讲的启发,我想参加一个聚会来谈论某个话题,这样我就可以成为这方面的专家。回家的同一天晚上,我带着笔记本电脑去汉堡查看是否有任何与人工智能相关的聚会,这是我目前居住的城市。但是什么都没有。

那时,我仍然兴奋不已,我决定干脆创建自己的聚会。为了确保我能信守承诺,我把第一次约会定在了 12 月中旬。由于我在那年 11 月中旬回来,我有一个月的时间。

做出这样的承诺感觉很棒,因为我终于做了一些事情,让自己免于陷入失去最初灵感的陷阱。但是,说实话,我真的没有考虑过后果:
仅仅两天后,我创建的小组已经有了 100 多名成员,一周后,有 250 多人加入了这个小组。慢慢地,一些疑问开始浮现,我想这是否是一个合理的决定。因为那时,我从未组织过活动。我甚至还没去过聚会。事实上,当本告诉我这件事的时候,我甚至不知道 Meetup 是什么!

但是我已经设定了目标。关于外部承诺的事情是这样的:他们让你负责。日历上有这件事,人们期待着我做些什么。我已经告诉了我的一些朋友,所以它必须发生。他们说:

"如果你想占领这个岛,那就烧了船"

设定这些外部承诺是我破釜沉舟的方式。所以我想了想第一场比赛我可能需要什么。我的清单包括:
-演讲者
-场地
-餐饮
-赞助商
,当然,还要确保人们到场!我必须保证不仅仅是我和另一个人进行一对一的交流。

一个月后的一个周五晚上:
在花了很大力气与人交谈并试图让一切运转起来之后,这是第一次活动的日子。我非常兴奋。它将在我大学的一个演讲室举行。这个房间可以容纳大约 150 人,我点了餐饮服务,以确保每个人都玩得开心。这是我们大学里比较好的房间之一,有非常舒适的椅子。我告诉了我所有的朋友,总共有 120 个回复。

不幸的是,事情并不总是按计划进行。好消息是:我们得到了所有的赞助。
坏消息:在报名参加活动的 120 人中,只有三分之一的人真正到场。我们两个演讲者中的一个根本没有准备,在演讲中东拉西扯。最重要的是,我们吃了太多的食物,因为我估计至少有 100 个人。40 人到场。嗯,至少每个人都可以带些第二天的午餐回家。
玩笑归玩笑。想象一下,我坐在那里。人们似乎很沮丧,他们一直看着我。我很沮丧。有些人提前离开了活动,这是最糟糕的感觉,因为你知道你可能已经毁了他们的夜晚。
我们的赞助商在那里,他们肯定不兴奋。
我呢? 我失败了;没有把一切都计划好。

我从 Ben 在 Data Science GO 上的演讲中学到的一点是:
首先提交。但是最重要的是,我知道你必须愿意失败。所以首先要承诺,但要做好在通往目标的路上失败的准备。但是现在最重要的部分来了:

我仍然给自己设定了一个目标:在汉堡创建一个人工智能社区,以便能够随时与志同道合的人交流。几个月后,我敢于再次尝试。我采纳了负面反馈,从中吸取了教训,并修正了我们的路线。这次我们在不同的地方,没有食物,我事先检查了两个扬声器。最后,有 100 人到场,一切都按计划进行,我们收到了很好的反馈。我们的一位演讲者来自柏林,所以活动结束后,我们与他合作,在那里开设了第二个 Meetup 小组。

在这一点上,我想强调的是,如果我一开始没有做出承诺,我永远不会这么做。我会永远不会组织活动。我甚至从未想过组织一次活动。
先提交
做好失败的准备。
但要准备好改进
因为今天,我们是德国发展最快的聚会。
2000 名会员,人数还在增加。
我们在德国两个最大的城市汉堡柏林经营最大的聚会。
事后我明白了,失败很酷,只要你从反馈和正确的过程中学习。

“没有所谓的失败,只有暂时的失败。”

永远坚持尝试,永远进步。提交。失败。提高。

大约在参加会议的六个月前,我刚刚开始学习深度学习和人工智能的在线课程。通过这些课程,我有机会看到许多实际应用和使用案例,并看到了巨大的潜力。我现在工作的公司是德国最大的电子商务服务提供商之一,为最大的零售商建立网上商店。客观地说,我们的一个客户在德国相当于亚马逊在美国的地位。这就是为什么我知道会有很多数据要处理,因此会有一个应用人工智能的巨大机会。当我查找并发现许多使用案例时,我正在考虑让一个研究小组研究其中的一些应用程序,以使我们的产品和流程更加高效。

唯一的问题是,我不知道如何向我们的执行团队提出整个事情,因为从逻辑的角度来看,这没有意义。想象一下,在你的公司里,某个自下而上的人会过来告诉你如何运行你未来的数据战略。
再次,逻辑挡住了的路。整个努力似乎遥不可及,因此我一直在拖延。我一直把它往后推。
但是我从数据科学围棋大会回来之后,我就下定决心了。
回到工作的第一天,我做出了一个承诺,我给我们的一位董事发了一封电子邮件,说了这样的话:
“我想向你推销这个想法。下周有空吗?”

那时我几乎一无所有。我没有计划。我没有统计数据。只是我想推销的东西的一个模糊的想法。
所以这可能不是最合理的决定……

一周后,我演讲的那天:
这是我第一次向一位高管演讲,我非常紧张。让我告诉你,这不是一个好的演示。
现在回过头来看,它实际上相当糟糕。但是这个想法本身就足以说服我的概念总监,所以我继续努力。
我保持改进。几周后,我想出了一个结构化的计划。我安排了一次会议,向我们整个执行团队推销这个计划。
这次会议的结果是,我获得了启动人工智能研究实验室的批准。
我们制作的产品现已集成到我们的在线商店软件中。当我开始学习人工智能时,我的梦想是有一天应用它来解决实际问题。
因为我做了一个承诺,这个梦想变成了现实。
先提交。从某处开始。然后利用你能得到的任何反馈来改进和不断修正你的路线。提交.失败.改进。

我在这里写的东西最棒的一点是,这些概念没有一个是我或本的观点。它深深植根于我们大脑的工作方式。我们给它一个目标,它就想出了如何实现的方法。把它想象成一枚自导鱼雷。目标是已知的,目的是达到它。鱼雷通过前进、犯错误和不断修正错误来完成它的目标。它以之字形运动向目标前进。仔细想想,当我们试图完成任何目标时,这正是我们大脑的工作方式。想一些简单的事情:比如从地上捡起一支笔。我们所做的只是选择目标,我们的大脑会自动找到到达目标的方法。不涉及也不需要有意识的思考。
我们不认为:“现在我必须用我的肩部肌肉来抬高我的手臂,然后我必须用我的二头肌来伸展我的手臂。”因为实际上我们甚至不知道涉及哪些肌肉。我们所做的就是设定目标,让我们的大脑想出实现目标的方法。就像本说的那样:如果你承诺在三个月后的一次聚会上展示自己,你将在三个月后成为一名专家。把它想象成一辆自行车:只要朝着某个方向前进,自行车很容易保持平衡。当你坐着不动,无处可去,试图保持平衡时,麻烦就出现了。
看,你走得快还是慢都没关系。只要你一直在前进,平衡会更容易,你会更接近你的目标。
你需要给你的大脑一个目标。
提交。失败。提高。*

事实上,我已经写了一篇关于汽车的文章,有这样一个故事:

19 世纪初,工程师们发现了如何用蒸汽机来驱动车轮,于是蒸汽机车诞生了。最初它只是用来运输货物和资源,人们很快发现它也是一种很好的运输工具。
然而,由于当时的科学水平,早期的采用者建议火车不要以超过 30 英里的时速运行,因为车上的人体会爆炸。

是的,你没看错。
人们真的相信如果他们的速度超过 30 英里每小时,他们的身体会爆炸。
幸运的是,一些“寻求刺激的人”无论如何都决定开到 31 英里,而我们现在开着时速超过 280 英里的车。

“我们能做多少往往只取决于我们尝试了多少。”

想象一下被堵在高速公路上。
以每小时 30 英里的速度向前爬行。如果不是因为那个疯子,我们的速度会是最快的。
首先承诺,在真正可能的事情上突破界限。

总的来说,我认为大多数人看到的问题是,他们可能会想:
在这种情绪状态下做出承诺难道不危险吗?未经深思熟虑就做出承诺不是很危险吗?如果我失败了怎么办?
我完全能理解这种观点,但请这样想:
如果你发现自己真的想改变什么,如果你对目前的状况不满意:
没关系。你必须做出改变才能前进。你必须站出来做些不同的事情。即使有风险。

最大的风险是不要冒险。

正如马克·扎克伯格所说:“在这个快速变化的世界里,唯一肯定会失败的策略就是不冒险。”

现在。如果你想承诺什么,我请你闭上眼睛。
我希望你考虑任何目标。想想你想改变的事情,你渴望完成的事情。不一定是和职业相关的事情。它必须是你真正热爱的事情。
想想目标是什么?时间框架是什么?这是你想在下周、几个月后或明年实现的事情吗?细节很重要。你在哪里?你和谁在一起?考虑一下环境。现在生动地想象如果你成功了会发生什么。试着在那一刻描绘出自己的样子。那让你感觉如何?你感到兴奋吗?好吧,现在你正处于做出承诺的最佳状态。写下你的想法并付诸行动!你可以随时把你的目标发给我,我很乐意和你聊聊。

因为这正是我去年在大会上所做的。在本文的开头,我谈到了去年我参加的一个会议的笔记本中的一个笔记,它改变了我的生活。
事后看来,那张纸条引发了我所写的一切。
那张纸条启发我创建了一个聚会。
那张纸条促使我去找公司的高管,为一个人工智能研究实验室做宣传。
如前所述,我在会议期间做了一些笔记。在本·泰勒演讲的时候,我在第三页的背面草草写了些东西。我对自己做出了承诺。

我想通过这篇文章表达的是,一切皆有可能。这听起来肯定让你疲惫不堪,但我确信你可以实现你下定决心要做的任何事情。因为一旦你为自己设定了目标,你就会清楚地知道自己在朝着什么方向努力。在这个信任点上,当你做出承诺并相信找到方法的可能性时,机会很快就会向你敞开。这可能需要一天、一周甚至一个月。但是在某些时候,你的大脑会给你一些想法,你可以用它们来开始。
有时候,你认为需要多长时间就需要多长时间。

“可能的程度往往受到我们尝试的程度的限制”

当我写下那张纸条的时候,我想这是绝对不合逻辑和不可能的。
为什么他们会允许一个 21 岁的孩子在这个会议上发言?我能贡献什么呢?我怎样才能获得必要的经验来确保这是一次成功的演讲?我能谈些什么呢?

在去年数据科学围棋大会的第一天结束时,也就是我写下那张纸条的那一天,我忘记了所有这些问题,去找了会议的组织者基里尔·叶列缅科。对他来说,这是漫长的一天,他看起来非常疲惫,但我当场告诉他,我想在明年的会议上发言。这是我的承诺。我非常认真。那时候我没有任何答案。但是我知道我会找到他们的。他回头看着我,只是说:“嗯,首先你得成功”。

*对于任何感兴趣的人,我强烈推荐阅读以下深入这一概念的书籍:
心理控制论,麦克斯韦·马尔茨
思考致富,拿破仑·希尔
思考的魔力,大卫·施瓦茨

致力于健全

原文:https://towardsdatascience.com/committing-to-sanity-67eddaa8eb35?source=collection_archive---------15-----------------------

【blog.zakjost.com】本文原载于

介绍

你成功地完成了一个建模项目,三个月过去了。您已经学到了一些东西,需要回去进行更改并重建模型。所以,你开始浏览你的项目目录。嗯,最终的模型训练代码是在test_90_new_features-Copy4.py还是prod_90_add_attrs-Copy2.py?你是用data_prep-Copy2_with_ohe.py还是full_data_pipe-Copy4.py生成训练数据的?

如果这听起来很熟悉,那么您没有使用版本控制作为您工作的基本方式,这对您不利。在这篇文章中,我将讨论为什么 git 应该被数据科学家所接受。在第 2 部分中,我将提供一些关于我如何构建项目的实现细节来帮助你开始。

饭桶

如果你不熟悉的话, git 是一种版本控制技术,它本质上是拍摄你的项目的快照。如果您更改了某个文件,它会知道,并且会记录对所有跟踪文件所做的所有更改。当你完成一件事,你告诉 git 做一个快照。因为它知道所有的变化,它可以很容易地撤销它们。

对于我们这些已经听了磁带音乐的人来说,你应该记得需要倒带或快进来排队等候某首歌曲的麻烦。按下按钮,等待几秒钟,停止,播放,意识到你过了或还没有到达那里,重复。有了 CD 就有了检查点,这样你就可以快速导航到歌曲的开头。现在很难想象没有有这种选择。同样,您会想知道在没有可以轻松导航和恢复的逻辑检查点的情况下,您是如何管理建模实验的。

检查点的可用性带来三个主要好处:安全性、清晰性和可重复性。让我们更深入地了解每一项。

安全

很明显,有了常规的检查点,你的工作会更安全,因为当你走进死胡同时,你可以点击“撤销”按钮。但是有一些相关的好处可能不那么明显。首先,你可能还会与一个远程 git 服务器同步,比如 GitHub,所以你的工作会被备份到另一台机器上。通过使用版本控制,您已经自动获得了备份工作的好处。当一切运行良好时,这可能无关紧要,但当您将咖啡洒在笔记本电脑上时,这就非常重要了。

第二,额外的安全性导致更大的实验意愿。有多少次不是直接修改一个函数,而是复制/粘贴它,在名字前加“_v2”,然后修改,以防万一你可能想还原回来?这是可怜人的版本控制,结果一塌糊涂。有了检查点,您可以放心大胆地进行更改,因为您可以随时恢复。死角可以删除,突破可以合并,潜在有用的切线可以束之高阁。

清楚

当您可以自由地删除与手头特定任务无关的代码时,您的代码会变得更加集中和清晰。如果你正在测试的新模型没有使用那个死端特征工程代码块,那么就删除它。这避免了在最终结果不确定的环境中,从实验中出现的难以理解的代码的大网络的增长。

可重复性

当您的代码分布在 Jupyter 笔记本的多个副本上,需要以非常特殊的顺序运行来生成模型时,就会出现可重复性问题。虽然除了早期试验之外,使用 Jupyter 笔记本做任何事情都可能不是一个好主意,但是使用版本控制来保持代码简洁/干净降低了风险,并使其更容易移植到适当的模块中。未来的你或未来的队友将会非常高兴,因为只有一个数据管道和一个模型构建。

履行

Git 通常在软件工程领域被考虑,在那里你可能有一个团队所有人都在相同的代码基础上工作。这带来了许多挑战,在这种背景下出现了一些最佳实践。虽然肯定有很多重叠,但这与个人进行数据科学实验并不完全相同。查看第 2 部分,获得关于这些差异的更详细的讨论,以及作为数据科学家如何有效地使用版本控制的一些想法。

**你可以在blog.zakjost.com找到我所有的内容并订阅

posted @ 2024-10-13 15:12  绝不原创的飞龙  阅读(321)  评论(0)    收藏  举报