TowardsDataScience-博客中文翻译-2016-2018-三十-

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

原文:TowardsDataScience Blog

协议:CC BY-NC-SA 4.0

感知器:人工神经元(麦卡洛克-皮茨神经元的本质升级)

原文:https://towardsdatascience.com/perceptron-the-artificial-neuron-4d8c70d5cc8d?source=collection_archive---------0-----------------------

深度神经网络的最基本单元被称为人工神经元,它接受输入,对其进行处理,将其传递给类似 Sigmoid 的激活函数,并返回激活的输出。在这篇文章中,我们将只讨论在“激活”部分出现之前提出的感知机模型。

美国心理学家弗兰克·罗森布拉特(Frank Rosenblatt)在 1958 年提出了经典感知机模型。由明斯基和 Papert (1969)进一步提炼和仔细分析——他们的模型被称为感知器模型。这是我上一篇关于麦卡洛克-皮茨神经元的文章的后续,我建议你至少快速浏览一下,以便更好地欣赏明斯基-帕佩特的贡献。

引用注:本文的概念、内容和结构灵感来自于 米特什·m·卡普拉 教授关于NPTEL 深度学习 课程的精彩讲座和材料。看看吧!

感知器

Minsky-Papert 提出的感知器模型是一个比麦卡洛克-皮茨神经元更通用的计算模型。它通过引入输入的数字权重(重要性的度量)的概念和学习这些权重的机制,克服了 M-P 神经元的一些限制。输入不再像 M-P 神经元那样局限于布尔值,它还支持实输入,这使它更加有用和通用。

现在,这非常类似于 M-P 神经元,但是我们取输入的加权和,并且仅当和大于任意阈值( 、θ)时将输出设置为 1。然而,根据惯例,我们没有手动编码阈值参数 thetha ,而是将其添加为输入之一,权重为- theta ,如下所示,这使得它可以学习(在我的下一篇文章中会详细介绍这一点— 感知器学习算法)。

考虑使用可用的行为数据预测我是否会在电视上观看随机的足球比赛的任务(与我的 M-P neuron 帖子中的例子相同)。让我们假设我的决定完全依赖于 3 个二进制输入(为简单起见是二进制)。

在这里, w_0 之所以被称为偏见,是因为它代表了先验(preference)。一个足球狂可能有一个非常低的门槛,可以观看任何足球比赛,而不考虑联赛、俱乐部或比赛的重要性[ theta = 0 ]。另一方面,像我这样的选择性观众可能只观看英超联赛的足球比赛,以曼联比赛为特色,并且不友好。重点是,权重偏差将取决于数据(在这种情况下是我的观看历史)。

根据数据,如果需要,模型可能必须赋予 isManUnitedPlaying 输入很大的重要性(高权重),并惩罚其他输入的权重。

感知器 vs 麦卡洛克-皮茨神经元

使用感知器可以实现什么样的功能?它与麦卡洛克-皮茨神经元有多大不同?

从等式中可以清楚地看出,即使是一个感知器也会将输入空间分成两半,正的和负的。产生输出 1 的所有输入位于一侧(正半空间),产生输出 0 的所有输入位于另一侧(负半空间)。

换句话说,单个感知器只能用来实现线性可分功能,就像 M-P 神经元一样。那有什么区别呢?为什么我们声称感知器是 M-P 神经元的升级版?这里,包括阈值的权重可以是学习的和输入可以是真实的值。****

使用感知器的布尔函数

还是功能——能做!

只是重温过去的美好时光,或者用感知机的方式发挥作用。

Try solving the equations on your own.

上面的‘可能解’是通过解左边的线性方程组得到的。很明显,解决方案将输入空间分成两个空间,负半空间和正半空间。我鼓励您尝试使用 AND 和其他布尔函数。

现在,如果你真的试着解上面的线性方程,你会发现可能有多个解。但是哪种解决方案是最好的呢?为了更正式地定义“最佳”解决方案,我们需要理解错误和错误表面,这将在我的下一篇关于感知器学习算法的文章中进行。

XOR 函数—做不到!

现在让我们来看一个非线性布尔函数,也就是说,你不能画一条线来区分正输入和负输入。

请注意,第四个等式与第二个和第三个等式相矛盾。关键是,对于非线性分离的数据,没有感知器解决方案。因此,关键是一个单个** 感知器无法学会分离本质上是非线性的数据。**

异或事件

在 Minsky 和 Papert 于 1969 年出版的书中,作者暗示,由于单个人工神经元无法实现某些功能,如逻辑功能的 XOR,因此更大的网络也有类似的局限性,因此应该放弃。后来对三层感知器的研究显示了如何实现这样的功能,从而避免了这项技术被抹杀。

维基百科

(可选)乙状结肠神经元的动机

正如我前面提到的,我们今天使用的人工神经元与我们看到的感知器略有不同,区别在于激活功能。给你。有些人可能会说一个感知器使用的阈值逻辑非常苛刻。例如,如果你看一个决定我是否要看电影的问题,只基于一个实值输入( x_1 = 评论),如果我们设置的阈值是 0.5(w _ 0=-0.5)和*【w _ 1***= 1,那么我们的设置将是这样的:**

对于一部= 0.51 的电影,会有什么样的决定?是的! 对于一部= 0.49 的电影,会有什么决定?不!有些人可能会说,我们会看一部评分为 0.51 的电影,而不是一部评分为 0.49 的电影,这太苛刻了,这就是西格蒙德出现的原因。现在说服你自己,这个苛刻的阈值并不仅仅归因于我们在这里选择的一个特定问题,它可能发生在我们处理的任何或每一个问题上。这是感知器*功能本身的一个特征,其行为类似于阶跃函数。*****

z 值越过阈值(- w_0 )时会有这种决策的突变(从 0 到 1)。对于大多数真实世界的应用,我们期望一个从 0 到 1 逐渐变化的更平滑的决策函数。

引入输出函数比阶跃函数平滑得多的 sigmoid 神经元似乎是一件合乎逻辑且显而易见的事情。请注意,sigmoid 函数是一个具有典型“S”形曲线的数学函数,也称为 sigmoid 曲线。有许多功能可以帮您完成这项工作,下面列出了一些:

- Wikipedia

最简单的一个例子是逻辑函数。

Quick Question: What happens to y when z is infinite? Or when it is -infinite?

我们不再看到围绕 w_0 的急剧转变。此外,输出不再是二进制的,而是介于 0 和 1 之间的真实值,可以解释为概率。因此,我们得到的不是“是/否”的决定,而是“是”的概率。这里的输出是平滑*、连续可微,这是任何学习算法都喜欢的。要自己验证这一点,请翻翻深度学习中的反向传播概念。***

结论

在这篇文章中,我们看了一个感知器,深度神经网络的基本单元。我们还通过例子展示了感知器与麦卡洛克-皮茨神经元相比,如何更加一般化,并克服了当时的一些相关限制。我们也简单地建立了乙状结肠神经元的动机。**

在我的下一篇文章中,我们将仔细观察著名的 感知器学习算法 ,并尝试获得它为什么工作的直觉,而不进入任何复杂的证明,以及从头开始用 Python 实现该算法。

感谢您阅读文章。自己活也让别人活!

Photo by Clint Adair on Unsplash

感知器、逻辑函数和异或问题

原文:https://towardsdatascience.com/perceptrons-logical-functions-and-the-xor-problem-37ca5025790a?source=collection_archive---------1-----------------------

深度学习药丸#2

今天我们将探索感知器能做什么,它有什么限制,我们将为超越这些限制做准备!图形和代码支持的一切。

来自深度学习药丸#1 的元素

在本系列的第 1 部分中,我们引入了感知器作为实现以下功能的模型:

对于参数 wb 的特定选择,输出ŷ仅取决于输入向量 x 。我用ŷ(“y 帽”)来表示这个数字是由模型产生/预测的。很快,你就会体会到这种符号的简易性。

计算图形

为了可视化一个模型的架构,我们使用了所谓的计算图:一个用来表示数学函数的有向图。变量和操作都是节点;变量被输入到操作中,操作产生变量。

我们感知机的计算图是:

σ符号通过权重w 和偏差 b 表示输入x 的线性组合。由于这种符号非常复杂,从现在开始,我将按照以下方式简化计算图形:

感知器能做什么?

我正在介绍一些感知器可以用它的能力实现什么的例子(我将在本系列的后续部分讨论这个术语!).逻辑函数是一个很好的起点,因为它们将把我们带到感知器背后的理论的自然发展,因此也是神经网络

非逻辑函数

让我们从一个非常简单的问题开始:

感知器能实现非逻辑功能吗?

NOT(x)是一个 1 变量函数,这意味着我们一次只有一个输入:N=1。此外,它是一个逻辑函数,因此输入和输出都只有两种可能的状态:0 和 1(即假和真):Heaviside 阶跃函数似乎符合我们的情况,因为它产生一个二进制输出。

考虑到这些因素,我们可以说,如果存在一个可以实现 NOT(x)函数的感知器,它就像左边显示的那样。
给定两个参数 wb ,它将执行以下计算:
ŷ=θ(wx+b)

最基本的问题是:是否存在两个值,如果作为参数选取,允许感知器实现非逻辑功能?当我说*感知器实现一个函数时,*我的意思是,对于函数域中的每个输入,感知器返回相同的数字(或向量),函数将返回相同的输入。
回到我们的问题:这些值之所以存在,是因为我们可以很容易地找到它们:让我们选择 w = -1b = 0.5。

我们得到了:

NOT(0) = 1
NOT(1) = 0

我们得出结论,初始问题的答案是:是的,一个感知器可以实现 NOT 逻辑功能;我们只需要正确设置它的参数。请注意,我的解决方案不是唯一的;事实上,对于这个特殊的问题,作为(w,b)点的解是无限的!可以用自己喜欢的;)

和逻辑功能

下一个问题是:

感知器能实现 AND 逻辑功能吗?

AND 逻辑函数是一个二元函数,和(x1,x2) ,具有二进制输入和输出。

该图与以下计算相关:
ŷ=θ(w1 * x1+w2 * x2+b

这次我们有三个参数: w1 、 *w2、*和 b 。你能猜出这些参数的哪三个值能让感知机解决和问题吗?

解:
w1 = 1,w2 = 1,b = -1.5

它会打印:

AND(1, 1) = 1
AND(1, 0) = 0
AND(0, 1) = 0
AND(0, 0) = 0

或逻辑函数

或(x1,x2) 也是一个二元函数,它的输出是一维的(即一个数),有两种可能的状态(0 或 1)。因此,我们将使用一个与之前相同架构的感知器。解决 OR 问题的三个参数是什么?

解:
w1 = 1,w2 = 1,b = -0.5

OR(1, 1) = 1
OR(1, 0) = 1
OR(0, 1) = 1
OR(0, 0) = 0

XOR —所有(感知器)对一(逻辑功能)

我们的结论是,一个单一的感知器与亥维赛激活功能可以实现每一个基本的逻辑功能:非,与和或。它们被称为基本的,因为任何逻辑函数,无论多么复杂,都可以通过这三者的组合来获得。我们可以推断,如果把我们刚刚搭建的三个感知器适当的连接起来,就可以实现任何逻辑功能!让我们来看看如何:

我们如何建立一个由基本逻辑感知器组成的网络,使其实现异或功能?

解决方案:

输出是:

XOR(1, 1) = 0
XOR(1, 0) = 1
XOR(0, 1) = 1
XOR(0, 0) = 0

这些就是我们一直在寻找的预测!我们只是把上面的三个感知器组合起来,得到一个更复杂的逻辑函数。

有些人可能想知道,就像我们对前面的函数所做的那样,是否有可能找到单个感知器的参数值,这样它就可以自己解决 XOR 问题。

我不会让你为寻找这三个数字而大费周章,因为那是没有用的:答案是它们不存在。为什么?答案是异或问题不是线性 可分,我们在本系列下一章深入讨论!

我将在几天后发表它,我们将讨论我刚才提到的线性可分性。我将从几何的角度重塑我今天介绍的主题。这样,我们今天得到的每一个结果都会得到它自然直观的解释。

如果你喜欢这篇文章,我希望你能考虑给它一些掌声!每一次鼓掌都是对我极大的鼓励:)还有,随时在Linkedin上联系我!

很快再见,
弗兰克

实时风格转换和超分辨率的感知损失

原文:https://towardsdatascience.com/perceptual-losses-for-real-time-style-transfer-and-super-resolution-637b5d93fa6d?source=collection_archive---------5-----------------------

[Fig. 1] Two toons discussing Neural Style Transfer at the beach.

这是一篇论文的论文摘要: 实时风格传递和超分辨率的感知损失 作者:贾斯廷·约翰逊,亚历山大阿拉希,李菲菲。
论文:

概观

本文提出使用 感知损失函数 来训练用于图像变换任务的前馈网络,而不是使用* 逐像素损失函数 。*

每像素损失函数?
根据两幅图像各自的像素值进行比较。
因此,如果两个图像在感知上相同,但是基于甚至一个像素彼此不同,那么基于每像素损失函数,它们将彼此非常不同。

感知损失函数?
基于来自预训练卷积神经网络(在图像分类任务上训练,比如说 ImageNet 数据集)的高级表示,比较两幅图像
。**

他们在两个图像转换任务上评估他们的方法:
(i)风格转换
(ii)单幅图像超分辨率

对于风格转移,他们训练前馈网络,试图解决 Gatys et al. 2015 提出的优化问题。

对于超分辨率,他们尝试使用感知损失,并表明它比使用每像素损失函数获得更好的结果。

方法

[Fig. 2] Model Architecture

所提出的模型架构由两个组件组成:
(i)图像变换网络(f_{w} )
(ii)损失网络(φ)

图像变换网络

图像变换网络是一个深度残差卷积神经网络,它被训练来解决 Gatys 提出的优化问题。

给定一个输入图像(x ),该网络将其转换成输出图像(ŷ).

使用使用输出图像(ŷ)计算的损失并将其与以下各项进行比较来学习该网络的权重(w):风格转移情况下的风格图像(y_{s})和内容图像(y_{c})的表示
-超分辨率情况下的内容图像y_{c}

使用随机梯度下降来训练图像变换网络,以获得最小化所有损失函数的加权和的权重(W)。

[Fig. 3] Weight update equation Explained.

损耗网络

损耗网络(φ)是 ImageNet 数据集上预先训练的 VGG16。

损失网络用于从内容和样式图像中获得内容和样式表示:
(i)内容表示取自层*relu3_3*。【图 2
(二)样式表示取自图层*relu1_2**relu2_2**relu3_3**relu4_3*。【图 2

这些表示用于定义两种类型的损失:

特征重建损失
用输出图像(ŷ)和来自层` relu3_3 '的内容表示并在图像中使用以下损失函数

[Fig. 4] Feature Reconstruction Loss Explained.

风格重建损失 利用输出图像(ŷ)和来自层 *relu1_2* 、 relu2_2 *relu3_3* 和 relu4_3 的风格表示,并使用来自图像的以下损失函数

[Fig. 5] Style Reconstruction Loss Explained.

在风格转移的情况下,总损失通常是特征重建损失和风格重建损失的加权和。和超分辨率的特征重建损失的加权乘积。

这些损失用于学习图像变换网络的权重。

结果

风格转移

[Fig. 6] Results of Style Transfer (from the paper)

  • 在 COCO 数据集上训练的网络(用于内容图像)。
  • 80k 训练图像调整为 256x256 补丁。
  • 批量:4 个
  • 40k 次迭代(大约 2 个时期)
  • 使用的优化器:Adam
  • 学习率:1e-3
  • 在 Titan X GPU 上进行培训大约需要 4 个小时
  • 对比 Gatys 等人提出的方法【1】

单幅图像超分辨率

[Fig. 7] Results of Super-Resolution (x4) (from paper)

  • 使用来自 MS-COCO 的 10k 图像的 288x288 补丁进行训练
  • 通过使用宽度σ=1.0 的高斯内核进行模糊处理和使用双三次插值进行下采样,准备好低分辨率输入。
  • 批量:4 个
  • 迭代次数:20 万次
  • 优化器:亚当
  • 学习率:1e-3
  • 对比 Sr CNN【3】**

[Fig. 8] Table showing the speed in seconds of the approach in this paper against Gatys’ paper (from the paper)

正如我们所看到的,我们使用本文的方法得到了相似的结果,并且在推理过程中比 Gatys 的方法几乎快3 个数量级。**

这种方法的最大缺点是,我们必须针对每种风格或每种分辨率训练 一个网络, 即不能仅使用一个网络来执行 任意 风格转换。

使用 Gatys,我们能够仅使用一个网络来执行 任意 风格的传输,这是我们使用本文提出的方法无法做到的。

参考

*****【1】*贾斯廷·约翰逊、阿拉希、李菲菲。:实时风格转换和超分辨率的感知损失。arXiv:1603.08155(2016 年 3 月)

*****【2】*Gatys,L.A .,Ecker,A.S .,Bethge,m .:艺术风格的神经算法。arXiv 预印本 arXiv:1508.06576 (2015)

*****【3】*董,c,洛伊,C.C .,何,k,唐,x .:学习一种用于图像超分辨率的深度卷积网络。参加:计算机视觉-ECCV 2014。施普林格(2014 年)

所以,简而言之,这就是论文的全部内容! 如果我发现一些有趣的见解需要补充,我会更新这个故事! 一定要走纸!

喜欢什么你请 read❓
👏 👏 👏 👏 👏

喜欢我的作品❓
跟着我❗️

** [## 阿鲁纳瓦查克拉博蒂| LinkedIn

查看 Arunava Chakraborty 在 LinkedIn 上的职业简介。LinkedIn 是世界上最大的商业网络,帮助…

www.linkedin.com](https://www.linkedin.com/in/iarunava/) [## 阿鲁纳瓦(@amArunava) |推特

阿鲁纳瓦(@amArunava)的最新推文:“从@fastdotai 上的#DeepLearning 课程 1 开始,已完成第 1 周…

twitter.com](https://twitter.com/amArunava) [## 阿鲁纳瓦

订阅深入了解 Python 里的所有东西。

www.youtube.com](https://www.youtube.com/channel/UC2ZFGaNzZt-sUy2qZT6L7Zw)

给我发消息!
我们连线吧!**

性能爆炸!TigerGraph 开发者版简介

原文:https://towardsdatascience.com/performance-exploding-introduction-to-tigergraph-developer-edition-486d6e6a409?source=collection_archive---------24-----------------------

This document is translated from: 性能炸裂!图数据库 TigerGraph 开发者版本入门 — 知乎

介绍

图数据库是随着大数据的普及而增长的一种数据库类型。

在多年专注于商业市场后,TigerGraph 发布了其免费开发者版。TigerGraph 本身自称是 Graph Database 3.0,具有处理海量数据的能力,支持实时更新和查询,它还定义了一种新的语言,称为 GSQL。这对于图形数据库爱好者来说无疑是一个好消息。

开发者版可在https://www.tigergraph.com/download/获得填写表格后,下载链接和相关文件将发送到您的电子邮件地址。

接下来,我们将逐步安装 TigerGraph,并尝试加载一个 31G 的社交网络数据集。TigerGraph 在测试结果中展现了他惊人的力量,在业界遥遥领先。

装置

目前,TigerGraph 支持包括 Ubuntu 和 CentOS 在内的主要 Linux 平台。

首先,我们需要解压缩下载的文件:

ubuntu@ip-172-31-6-254:~$ tar -xzvf tigergraph-developer-latest.tar.gz
tigergraph-2.1.2-developer/
tigergraph-2.1.2-developer/tsar.tar.gz
tigergraph-2.1.2-developer/LICENSE.txt
...

然后,以 root 权限运行install.sh

ubuntu@ip-172-31-6-254:~/tigergraph-2.1.2-developer$ sudo ./install.sh -n
   _______                 ______                 __
  /_  __(_)___ ____  _____/ ____/________ _____  / /_
   / / / / __ `/ _ \/ ___/ / __/ ___/ __ `/ __ \/ __ \
  / / / / /_/ /  __/ /  / /_/ / /  / /_/ / /_/ / / / /
 /_/ /_/\__, /\___/_/   \____/_/   \__,_/ .___/_/ /_/
       /____/                          /_/Welcome to the TigerGraph platform installer![PROGRESS]: Checking operation system (OS) version ...
[NOTE    ]: OS obtained: UBUNTU 16.04
[NOTE    ]: OS check passed [OK]
...
---------------------------------------------------------------
Congratulations! Installation Finished!
---------------------------------------------------------------Thank you for using TigerGraph platform!
[PROGRESS]: Cleaning up ...
DONE
[NOTE    ] The TigerGraph user: tigergraph
ubuntu@ip-172-31-6-254:~$

现在,/home/tigergraph/tigergraph/下已经安装了 tigergraph。有两点需要注意:

  1. 安装过程中会创建一个操作系统用户tigergraph。由于我们使用了-n选项(默认配置),所以密码也是tigergraph
  2. 所有后续操作都应该在用户tigergraph下完成,而不是拥有root权限的原用户。

服务管理

TigerGraph 使用命令gadmin来管理系统,该命令应该在 OS 用户tigergraph下运行。

开始和停止

默认情况下,TigerGraph 将在安装后启动。

gadmin startgamin stop可用于启动和停止服务。

系统状况

命令gadmin status可用于检查各部件的状态。

tigergraph@ip-172-31-6-254:~/$ gadmin status
Welcome to TigerGraph Developer Edition, for non-commercial use only.
=== zk ===
[SUMMARY][ZK] process is up
[SUMMARY][ZK] /home/tigergraph/tigergraph/zk is ready
=== kafka ===
[SUMMARY][KAFKA] process is up
[SUMMARY][KAFKA] queue is ready
=== gse ===
[SUMMARY][GSE] process is up
[SUMMARY][GSE] id service has NOT been initialized (online)
...
=== Visualization ===
[SUMMARY][VIS] process is up (VIS server PID: 37708)
[SUMMARY][VIS] gui server is up

应用

接下来,我们将创建一个最简单的图形,加载数据并运行一些简单的查询来查看 TigerGraph 的性能。

硬件和数据集

TigerGraph 的要求比较低,最低 8G 内存,20G 磁盘空间,这样就可以在虚拟机中运行。当然,加载大型图形需要更多的磁盘空间和内存。

可以在亚马逊共购网数据集上做简单测试,解压缩后只有 12.6M。

为了让它更有趣,这里我们使用 Friendster 社交网络数据集,它与亚马逊共同购买网络具有相同的格式,但是具有更多的顶点和边:650 万个顶点和大约 20 亿条边。测试在 AWS EC2 c4.8xlarge 上进行,带 GP2 磁盘,操作系统为 Ubuntu 16.04。

首先我们需要解压数据文件:gunzip com-friendster.ungraph.txt.gz

未压缩的数据文件大小为 31G。在开始测试之前,我们先检查一下磁盘使用情况,加载后可以对比一下。

tigergraph@ip-172-31-6-254:~/data$ ll com-friendster.ungraph.txt  --block-size=G
-rw-rw-r-- 1 tigergraph tigergraph 31G Nov 13  2012 com-friendster.ungraph.txt
tigergraph@ip-172-31-6-254:~/data$ df -h
Filesystem      Size  Used Avail Use% Mounted on
udev             30G     0   30G   0% /dev
tmpfs           5.9G  8.5M  5.9G   1% /run
/dev/xvda1      194G   67G  127G  35% /
tmpfs            30G     0   30G   0% /dev/shm
tmpfs           5.0M     0  5.0M   0% /run/lock
tmpfs            30G     0   30G   0% /sys/fs/cgroup
tmpfs           5.9G     0  5.9G   0% /run/user/1000

为了感受这个数据集有多大,我们可以运行time wc -l com-friendster.ungraph.no.header.txt:

tigergraph@ip-172-31-6-254:~/data$ time wc -l com-friendster.ungraph.no.header.txt
1806067135 com-friendster.ungraph.no.header.txtreal    3m8.286s
user    0m31.372s
sys     0m18.412s
tigergraph@ip-172-31-6-254:~/data$ ls -al --block-size=G com-friendster.ungraph.no.header.txt
-rw-rw-r-- 2 tigergraph tigergraph 31G Jun 12 05:36 com-friendster.ungraph.no.header.txt

从结果中我们可以看到,这个文件有 18 亿行,在 SSD 上运行wc -l差不多要 4 分钟!

创建图表

创建图表有两种方法,要么通过 cmd 工具gsql,要么通过 GUI 工具GraphStudio

这里我们使用 GraphStudio。要访问 GraphStudio,在浏览器上键入http://localhost:14240。如果是远程服务器,只需将localhost更改为远程 IP,主页将显示:

TigerGraph Home Page

切换到左侧面板中的Design Schema,添加一个顶点,设置属性、颜色和图标,点击箭头指向的按钮:

Add Vertex

要添加边,点击下一步按钮,然后选择源顶点和目标顶点,会弹出一个对话框:

Add edge

然后,只需点击publish按钮,图表将被创建。

Publish

添加数据源

切换到左侧面板上的Map Data To Graph。点击如图所示的按钮上传文件:

Add source

考虑到本次测试的数据文件太大,并且已经在服务器上,我们可以直接将其移动到/home/tigergraph/tigergraph/loadingData/或者使用ln命令创建一个硬链接,而不是上传。

在选择了正确的文件类型和分隔符后,我们可以将数据源添加到操作面板中。在这里,我们可以点击如图所示的按钮,然后选择名为friend的文件和边,我们可以很容易地指定数据到属性的映射。

File Mapping

加载数据

切换到Load Data,点击start按钮,加载开始。点击loading log按钮可以看到加载日志。

Load Data

Loading log

以下是加载日志的一部分:

filename = .gsql.loader.progress.2018.6.12-5.57.54, progress size = 309
...
906761 lines/second|------------------- |99 %
899769 lines/second|------------------- |99 %
907965 lines/second|--------------------|100%
352247 lines/seconddestroy worker06:41:54.181621 gcleanup.cpp:38] System_GCleanUp|Finished

我们可以看到,31G 的原始数据,从 5:57 开始到 6:41,总共需要 44 分钟。其实我们创建的是无向图,所以实际加载的数据量要翻倍,相当于 62G 的有向图。这只是开发者版,太神奇了!

这是磁盘使用情况

tigergraph@ip-172-31-6-254:~$ df -h
Filesystem      Size  Used Avail Use% Mounted on
udev             30G     0   30G   0% /dev
tmpfs           5.9G  8.5M  5.9G   1% /run
/dev/xvda1      194G  110G   85G  57% /
tmpfs            30G     0   30G   0% /dev/shm
tmpfs           5.0M     0  5.0M   0% /run/lock
tmpfs            30G     0   30G   0% /sys/fs/cgroup
tmpfs           5.9G     0  5.9G   0% /run/user/1000

当前磁盘使用量为 110G,加载前为 67G,与原始数据相当于 62G 有向图相比,磁盘使用量只增加了 43G!

让我们看看记忆,

tigergraph@ip-172-31-6-254:~/data$ free -m
              total        used        free      shared  buff/cache   available
Mem:          60382       24114       19564          16       16703       35686
Swap:             0           0           0

加载后,磁盘使用量只有 24G。

询问

数据加载后,我们可以切换到Explore Graph进行一些基本的查询。因为 TigerGraph 是一个实时数据库,数据加载过程是在线的。因此,实际上我们不需要在运行查询之前等待加载完成。

下图显示了拾取顶点、1 步邻居和 6 步连通子图的结果。

Query Neighbors

K-step Subgraph

发动机反应如此之快,没有明显的延迟。

Write Queries面板中,使用查询语言 GSQL,可以完成更多的定制查询。GSQL 的风格类似于一些常用的编程语言,很容易上手。IDE 非常强大,有漂亮高亮显示和实时的语法和语义检查。

给定一个顶点,下面是一个简单的 k 步邻居查询。

CREATE QUERY k_step_neighbor(VERTEX<person> p, int k) FOR GRAPH MyGraph { 
  initial_set = {p};
  result = initial_set;
  FOREACH i in RANGE[1, k] DO
    result = SELECT dest_vertex 
      FROM result:start_vertex-(friend)->person:dest_vertex
    ;
  END;
  PRINT result;
}

保存并安装查询后,我们就可以运行它了

此外,更多的条件和过滤器可以添加到查询中,例如,顶点和边属性上的过滤器。这里我们不赘述。

在附录中提到的 TigerGraph 的 testdrive 中还有更复杂的用例可用,比如反欺诈、供应链、社交网络、公司信息知识图、

结论

TigerGraph 开发者版性能惊人。UI 工具 GraphStudio 提供了流畅的入门体验,查询语言也很容易学习。

TigerGraph 开发版的推出可能会开启图形数据库的新时代。

附录

蒙特卡洛树搜索在梦幻足球选秀中的表现

原文:https://towardsdatascience.com/performance-of-monte-carlo-tree-search-for-fantasy-football-drafts-269075d08088?source=collection_archive---------10-----------------------

本帖中的代码也可作为 Jupyter 笔记本

在我之前的帖子中,我们看到了使用蒙特卡洛树搜索法为你的梦幻足球选秀。这篇文章将分析我们的 MCTS 算法的性能。

Photo by Tajuana Delamora on Pixy

设置迭代次数

在我们开始研究性能之前,您可能记得 MCTS 的一个参数涉及到要运行的迭代次数。上次我们将其设置为 1000 次迭代(相当随意),但这可能值得研究一下。一个简单的分析方法是让 MCTS 和另一个迭代次数更多的 MCTS 竞争。如果后者优于前者,那么至少有更高的迭代次数是有意义的,并且测试更高的迭代次数是否仍然优于后者。在某些时候,我们期望迭代次数达到一个平衡,在这种情况下,我们可以停止增加迭代次数。

下面我们看到了这个练习的结果。事实证明,对于可接受的性能来说,1000 次迭代似乎就足够了。

随机策略下的绩效

作为一个基本的基准,现在让我们来看看 MCTS 是如何对付一个随意选秀的对手的。这个策略的实现非常简单。

def random_draft(state):
    return np.random.choice(state.GetMoves())

下面是两种策略在不同蛇顺序位置的结果。正如所料,MCTS 胜过随机策略。

针对贪婪策略的性能

接下来,让我们看看 MCTS 对一个采用贪婪策略选秀的对手的表现。贪婪的意思是你在你的花名册上选择现在最有价值的位置,而不考虑未来选择的后果。例如,首先选择四分卫可能会增加很多价值,但以后可能会错过优秀的跑卫,因为他们很快就会变得稀缺。该策略的实现如下所示。

def greedy_draft(state):
    def result(move):
        st = state.Clone()
        st.DoMove(move)
        return st.GetResult(st.playerJustMoved)

    res, move = max((result(m), m) for m in state.GetMoves())
    return move

我们很高兴地看到,下面的结果表明,我们的 MCTS 算法仍然优于这种贪婪策略——但请注意,贪婪策略似乎比随机更差!

蛇订单位置的值

最后,让我们看看你的蛇顺序位置有多重要。很多人都在讨论第一次选人的价值——以及等待下一次选人的漫长时间——与随后的选人相比。我们可以在多个草稿上运行我们的 MCTS 算法,然后查看每个草稿位置的平均结果。

而且,是的,这似乎证实了拥有第一选择的确很重要…在一个糟糕的赛季后的另一个借口;-)

起草愉快!

Tableau 的性能优化思想

原文:https://towardsdatascience.com/performance-optimization-ideas-for-tableau-e222fe3b9320?source=collection_archive---------13-----------------------

数据无处不在,它本身正在成为一种货币。像脸书这样的公司将信息作为他们的主要收入来源。为了有用,数据需要被处理、理解,甚至转换成可爱的图形表示。Tableau 可以成功地做到所有这些,并且让用户继续在本地系统中工作,如电子表格、关系数据库、云环境或 OLAP。通过一个简单的连接,所有这些都成功地导入到 Tableau 中,并准备接受分析。然而,当出现明显的延迟和明显的性能下降时,您能做些什么呢?

这是谁的错?

每次发现性能下降时,您都需要确定原因。是硬件还是软件?是本地机器造成的还是服务器造成的?你能实施快速解决方案吗,或者你需要重新评估你的工作模式吗?

过时的硬件

要解决的最直接的问题,尽管不是最便宜的,是升级本地设备。要了解这是否有必要,请在您怀疑速度太慢的计算机和一台好得多的计算机上测试同一工作簿。如果有显著差异,请升级。

服务器问题

如果工作簿位于服务器上的共享数据连接上,可能是您过度使用了可用资源。例如,如果计算是在共享源中定义的,您可能希望使用本地源进行故障排除,以避免服务器过载。

直播的麻烦

想想保持 Tableau 直播的必要性。除非项目必须有实时提要,否则通过创建定期更新的摘录来节省资源。

当实时流是一个基本条件时,考虑定制 SQL 的必要性。这些是一些最低效的连接,应该尽可能地加以限制。为了提高速度,直接在 Tableau 中定义连接,而不是 SQL。看看那些需要加倍努力的不必要的条款。这样的例子是“ORDER BY ”,因为 Tableau 在加载后会对数据进行重新排序。

更好的数据管理

数据对性能有直接影响。始终只处理各自任务所需的数据。空闲列只会降低 Tableau 环境的速度。只提取一个样本或完全删除不必要的列。这将转化为更短的刷新时间和更高的速度。

摘录是你最好的朋友。把它们想象成一个“手提箱”,你把当前任务需要的数据放在里面,就像你度假时只带你需要的东西,而不是家里的所有东西。甚至有一个案例研究描述了使用这种方法后,报告的计算时间减少了 99%。

过滤微调

快速滤镜是你的画面表现的无声杀手之一。这些缺省值看似无害,但实际上,对于仪表板中出现的每个缺省值,都有一个在后台执行的连接查询。当然,保留那些你需要的,但是也考虑用“动作”过滤器替换,因为这些过滤器不会触发查询。

减少不必要的服务器资源负担的另一种方法是在通过上下文过滤器需要连接之前计算连接。这是一种创建非规范化表的方法,速度可节省 90%。事实上,这可以作为良好的实践。

关于计算的决定

逻辑条件会对分配的资源造成真正的损失。一些最贪婪的子句是 IF-ELSE 结构。如果不是太多,只要有与值的比较,这些都可以被布尔条件成功替代。

数据的类型对计算速度有很大的影响。要知道字符串是最容易使用的资源,其次是日期、布尔值,最后是数字。

另一个技巧是去掉使用组,用“格”来代替。当添加满足底层条件的新成员时,这甚至更有用。在分组的情况下,这应该是手工完成的,因此对于输入来说也是节省时间的操作。

如果您在本地进行计算,这会降低工作簿的速度。尽量利用服务器方法的优势。此外,无论如何都要避免在行级别使用参数进行计算。

标志和图像

每个数据点被称为一个标记,显示它会降低系统速度。想想每一列或每一行的必要性,不要因为你太懒就把它们摆在那里。

将图片的使用限制在绝对必要的范围内。尝试使用透明背景的 png,既能达到设计目的,又能占用更少的空间。

布局提示和技巧

每个布局都需要自己的资源,超过四个会大大降低仪表板的性能。尽量在你的小组中包含练习册,并确保你最大限度地使用你选择的练习册。

这听起来可能令人惊讶,但是为你的仪表板设置一个尺寸可以提高性能。原因在于,将它设为“自动”,这是默认设置,将迫使工作簿根据每个不同用户的屏幕大小来适应他们的偏好。对于环境来说,这类似于为每个用户打开不同的仪表板,即使信息是相同的。

优化 Tableau 有意义吗?

Tableau 是 BI 最强大的工具之一。这是因为它主要是一个具有计算能力的数据可视化工具,对技术技能的要求很低,而且非常直观。它还可以处理大量数据,同时连接到实时源或与其他电子表格环境通信。

由于这种多功能性,使用这个工具并使其尽可能快速高效是有意义的。当然,它并不完美,但通过首先解决硬件问题,然后更加关注数据管理和计算逻辑,只需稍加调整,它就可以变得快如闪电。

也许是有史以来最简单的对立例子介绍

原文:https://towardsdatascience.com/perhaps-the-simplest-introduction-of-adversarial-examples-ever-c0839a759b8d?source=collection_archive---------3-----------------------

在本文中,我们将理解对立例子的直觉,以及如何用 Python 创建它们。

在撰写本文的时候,我只是深入研究了这个公式,并试图根据我为上一篇文章创建的逻辑回归示例(链接)对它进行编码。

所以,我可以向你保证我的介绍很简单,非常基础。然而,这里的直觉可以扩展到更高维度和更复杂的模型,如深度学习。

一切从最简单的数据开始

回到我在第一篇文章中提出的简单问题,如果我们想要区分红色和蓝色类,我们可以立即知道决策边界应该在两个集群的中间,如下所示。在这种情况下,位于右上角区域的任何新数据将被分类为蓝色,位于左下角区域的数据将被分类为红色。

反面例子是精心设计的样本,意图让机器学习出错。如果我们不能移动紫色线,我们怎么能让紫色线出错**?**

事实证明,这一点也不难,我们只需要将样本移动到对面区域,使蓝点落在红点区域,红点落在蓝点区域。一点也不意外。

Epsilon 是一个控制对抗性攻击大小的小数字,为了有效但又不太明显,需要选择它。

随着ε的增加,我们可以预见到决策边界无法算出。当ε变为 0.2 时,逻辑回归模型误差从 2.9%增长到 7.6%,当ε变为 0.5 时,增长到 22.6%。

快速梯度符号法

上面图形显示的实际上是使用 FGSM。

本质上,FGSM 是添加方向与代价函数相对于数据的梯度相同的噪声(非随机噪声)。噪声按ε缩放,ε通常通过最大范数限制为一个小数值。在这个公式中,梯度的大小并不重要,重要的是方向(+/-)。

翻译成 Python 代码

FGSM 可以在 Python 中用几行代码实现。

在梯度下降中,成本相对于权重的梯度为(Y _ Prediction-Y _ True)X

在对立的例子中,成本相对于数据的梯度是(Y _ Prediction-Y _ True)W

这个小小的改变意味着我们可以通过用权重替换数据来回收梯度计算的代码。

直觉和外卖

以下是我在试图理解这个公式时问自己的问题。

直觉 1:为什么公式与成本函数的梯度有关?

增加模型误差意味着增加成本函数。

直觉二:看起来像梯度下降优化。不是吗?

梯度下降是通过获得相对于权重的梯度来更新模型的权重,从而最小化成本函数。在这种情况下,由于我们无法改变权重,为了增加成本,唯一的办法就是改变数据。

从某种意义上说,我们是在做成本函数相对于数据的梯度上升来增加成本,从而增加模型误差。

直觉 3:对立的例子有助于提高逻辑回归的质量吗?逻辑回归如何防御这种攻击?

从我的直觉来看,使用逻辑回归无法避免这种攻击。如图所示,无论你把紫色线放在哪里,误差仍然会很高,因为对立的例子使两个集群变得模糊。然而,对抗例子对于帮助非线性模型建立对这些攻击的防御是非常有用的。

完整的 python 代码可以在这个链接找到。

PS:我不是这方面的专家,但绝对是发烧友。这篇文章不是技术性的,但是我希望从最简单的案例中得到的直觉可以扩展到所有的案例。如果这个介绍有帮助,请鼓掌!

强人工智能的 24 种已知成分

原文:https://towardsdatascience.com/periodic-table-of-ai-at-the-edge-of-chaos-6666598c7d3c?source=collection_archive---------0-----------------------

本文汇集了有益于人工智能开发的观点和见解。

这些理论是用来构建整个智力理论的候选理论。有 24 分。结合任何 2 或 3 点,你会得到一个 AGI 发展的新方法。祝你好运。

列表里除了我混乱的视野,没有任何系统。好消息是有一个理论,一些有趣的东西只能出现在混沌的边缘

  • 艾在近。我的意思是,我们到处都有智能,能够进行必要数量的实验,以获得关于这一现象的所有信息。
  • 人工模拟环境。(例如来自 OpenAI 或任何其他模拟的宇宙。)这些世界应该使得在现实世界中引入 AI 成为可能。但是智能和所有需要进一步改进的过程的出现在那里是可能的。这里重要的部分是代理从周围的世界获取信息,这个世界必须充满不同的动态。
  • 定义。至少是最初的近似值。M. Hutter 已经做了相关的研究。累积的定义是— 智能衡量一个代理在广泛的环境中实现目标的能力
  • 图灵机就是一切,一切都是 TM 。我们的世界有史以来最大。没有一个系统在某种程度上是孤立存在的。
  • TM 的简化与转化。我认为无论是我的知识还是总体的计算机科学都存在巨大的差距。假设我们有模拟月球绕地球飞行的程序。我们如何重写它使它变得更简单?如果我们有一个程序来模拟癫痫轨道中一个点是如何围绕另一个点运动的呢?我们如何用关于物体大小的附加信息来扩展它呢?关键是我们(人类)很容易做到。
  • 概括能力。接近 TM 的简化。这个世界如此复杂,如果不进行归纳,我们就无法处理所有的数据。重用它的能力很重要。
  • 系统以这样的方式运行,某个量变成它的最小(小于:最大)可能值。热力学第二定律就是这个原理的一个基本例子。关于神经网络,反向传播代表了最小化错误率的能力。从神经网络的内部来看,反向传播看起来像基本定律。槽 vs 进化
  • solomonff 感应 。算法概率。信息距离。
  • AIXI 模型 和其实现。尽管有各种限制,我认为在某种意义上这是最接近真正的 AGI 技术的想法。
  • 优化。我们知道多少种优化?计算能力优化,即使用更有效的算法。降低内存消耗的内存优化。电源优化。更一般的优化——比如创建更好的编程语言来优化开发时间。还有很多。优化使少花钱多办事成为可能。这就是我们希望人工智能做的——用最少的干预为我们处理很多事情。
  • A 哥德尔机 采用了 Jürgen Schmidhuber 提出的递归自我改进架构。
  • 机器理解错误。这是机器的一种问题。
  • 自组织。混乱的边缘。Prigogine 的耗散系统理论解释了“从某种事物中可以产生某种完全不同的事物”。思想和法律如何从无到有?
  • 创新的演变和潜在规律。从基因编程玩具到生物进化,甚至进一步到进化的元理论。
  • 使用人类最强大的工具——类比。类比思维或同构思维同构的类比可以用于科学假说的归纳。这个想法有双重好处;在研究中使用它的能力对发明来说是至关重要的。它如何工作的理论可能对重建机器的智能至关重要。
  • 翻译。这一点值得大量的研究,但接下来的想法是:翻译的过程在所有情况下都非常相似。要么把英文文本翻译成中文,要么把一个程序的要求翻译成源代码,要么把房子的蓝图翻译成房子。另外,翻译必须是对称的。点击此处阅读更多内容:

[## 是什么让翻译成为智能的本质

你们中有多少人认识上图中的图案?是的,是斐波那契数列:

medium.com](https://medium.com/@mikecorp/what-makes-translation-the-essence-of-intelligence-4f67302bbc35)

  • 种子 AI 概念渐进学习。从我们探索和研究的第一步开始,进化就给了我们适应周围世界的能力。
  • 迁移学习是存储在解决一个问题时获得的知识,并将其应用于另一个相关问题。学而不忘与泛化思想密切相关。
  • 能够处理不完整信息。好消息, AI 已经会玩扑克了
  • 递归和自引用可能性。
  • 正式系统。人们赋予系统意义的方式。数学作为一个正式的系统,在人类的意义上有很多意义。FS 应该相对于 哥德尔的不完全性定理 来考虑。
  • AGI 出现的风险。风险考量是 AI 不可分割的一部分。
  • 深度学习作为****最有前途和最广泛发展的技术。关于它已经写了太多,但还不足以将一个强大的人工智能带到现实中。
  • ****ML 算法。他们每一个都是通用人工智能的特例。

那么,你觉得错过了什么?列表中是否提到了关键成分?

如果你觉得这篇文章有趣按下心脏分享这篇文章。****

另外,目前我正在寻找人工智能或人工智能领域的工作**。**

你可以在这里找到我:脸书页面Linkedin 页面

AB 检验样本量不够大时的排列检验

原文:https://towardsdatascience.com/permutation-tests-when-ab-testing-sample-size-is-not-big-enough-f1a7967ce729?source=collection_archive---------9-----------------------

在开始排列测试的本质之前,让我们回顾一下经常出现的情况。你想分析一个实验,但是你意识到你没有足够的数据来应用它。您已经开始分析,但现在意识到,就目前的结果而言,没有足够的统计功效来确定统计显著性。这是一个典型的场景,通常源于用于实现统计功效的有限样本量。

选项

  • 根据收到的数据执行计算,这不是一个好主意,因为此类数据可能会严重失真
  • 应用 bootstrap 解决问题。然而,在应用 bootstrap 来接受或否定零假设(H0)之后,唯一的选择是使用置信区间

然而,如果我们想用多个预测值来描述指标,或者从某个标准中提取统计数据,该怎么办呢?在这种情况下,引导程序不会非常有用。现在你已经准备好解释排列测试以及何时需要它们。

让我们假设您决定使用学生的 t-test 来计算您的 a/b 测试。你假设你的数据是正态分布的,并且方差相等(例如,你用 Bartlett 的测试证实了这一点)。接下来,您将计算 t 统计量并将其与理论分布进行比较,以此类推,从而剔除 H0。

置换测试可以使用稍微不同的方法

  1. 按照通常的方法计算 t 统计量;我们就叫它 t0 吧
  2. 例如,将所有 10 个值放在一个组中
  3. 随机将 5 个值放入 A 组,另外 5 个放入 B 组
  4. 计算新的 t 统计量
  5. 重复步骤 3 和 4 2n 次
  6. 将从 t 统计中提取的值按升序排列
  7. 如果 t0 不包括在经验分布的中间 95%的值中,那么您应该拒绝关于两个样本的平均值相等的零假设,概率为 95%

这种方法可能会让你想起贝叶斯。在 R 中,这种方法的实现是在 Coin 包中实现的,但是您也可以使用标准函数或 boot 包来实现。

排列测试是处理样本大小不足以获得足够的统计能力来确定结果的显著性的情况的一种方法。但是,你需要记住,没有任何“小技巧”可以取代样本量来实现实验的最佳功效。只有在理解了这种方法的适用性和数据的性质后,才应该应用这种方法。

最初发表于【awsmd.com】

困惑直觉(及其衍生)

原文:https://towardsdatascience.com/perplexity-intuition-and-derivation-105dd481c8f3?source=collection_archive---------1-----------------------

永远不要再被困惑所困扰。

您可能在 NLP 类中看到过类似这样的内容:

A slide from Dr. Luke Zettlemoyer’s NLP class

或者

A slide of CS 124 at Stanford (Dr. Dan Jurafsky)

在课堂上,我们真的没有花时间去推导困惑。也许困惑是一个你可能已经知道的基本概念?这篇文章是为那些不知道的人写的。

一般来说,困惑是一个概率模型如何预测样本的度量。在自然语言处理的背景下,困惑是评估语言模型的一种方式。

但是为什么 NLP 中的困惑是这样定义的呢?

如果你在维基百科上查找离散概率分布的困惑:

from https://en.wikipedia.org/wiki/Perplexity

其中 H(p)是分布 p(x) 的熵,而 x 是所有可能事件的随机变量。

在之前的帖子中,我们从零开始推导了 H(p) 并直观地展示了**为什么熵是我们对信息进行编码所需的平均位数。**如果你不明白 H(p) ,请先阅读此⇩ 再进一步阅读。

[## 香农熵背后的直觉

【警告:太容易了!]](https://medium.com/@aerinykim/the-intuition-behind-shannons-entropy-e74820fe9800)

现在我们同意 H(p)=-σp(x)log p(x)。

那么,困惑只是熵的一个幂运算**!**

是的。熵是对随机变量中包含的信息进行编码的平均位数,因此熵的幂应该是所有可能信息的总量,或者更准确地说,是随机变量具有的选择的加权平均数

例如,如果测试集中的平均句子可以用 100 比特编码,则模型困惑度是每个句子 2 ⁰⁰。

让我们确认维基百科中的定义与幻灯片中的定义相匹配。

在哪里

p :我们要建模的概率分布*。*从 p 中抽取一个训练样本,其分布未知。

q :提出的概率模型。我们的预测。

我们可以通过测试从 p. 抽取的样本来评估我们的预测 q ,然后基本上就是计算交叉熵。在上面的推导中,我们假设所有单词在 p 中具有相同的概率(1 /单词数)。

评论

  • q(x) = 0 时,困惑度将为 。事实上,这也是 NLP 中引入平滑概念的原因之一。
  • 如果我们对 q (简单来说就是所有单词的 1/N)使用统一的概率模型,那么困惑度就等于词汇量。
  • 以上推导仅用于说明目的,以便得出 UW/斯坦福幻灯片中的公式。在这两张幻灯片中,它假设我们正在使用一个 unigram 模型计算整个语料库的困惑度,并且没有重复的单词。(它假设总单词数(N)与唯一单词数相同。)此外,它假设所有单词具有相同的概率 1/N。这些都不是现实的假设。

外卖

  • 较小的熵(或较少无序的系统)比较大的熵更有利。因为可预测的结果优于随机性。这就是为什么人们说低困惑是好的,高困惑是坏的,因为困惑是熵的幂(你可以放心地认为困惑的概念是熵)。
  • 语言模型是句子的概率分布。最好的语言模型是能够最好地预测一个未知测试集的语言模型。
  • 为什么我们要用困惑度而不是熵? 如果我们把困惑想象成一个分支因子(一个随机变量拥有的选择的加权平均数),那么这个数字比熵更容易理解。我觉得这很令人惊讶,因为我以为会有更深刻的原因。我问 Zettlemoyer 博士,除了容易理解之外,是否还有其他原因。他的回答是“我想就是这样!这在很大程度上是历史性的,因为许多其他指标也可以合理使用!”

docker 和云的持久数据

原文:https://towardsdatascience.com/persistent-data-for-docker-and-the-cloud-a395dc42f2d7?source=collection_archive---------1-----------------------

当我们谈论计算时,有两种类型的数据,非持久或临时数据,以及持久数据。

非持久性

临时数据也具有滑动标度,

  • 在线游戏中用于决策的随机数;需要,但持续时间不到一秒,
  • 用于跟踪您在网站上的登录详细信息的会话 ID;通常持续整个疗程,大约 30-45 分钟,
  • 在线商店购物篮的内容;亚马逊会保存几天,甚至几年。

如果丢失了其中的任何一个,也不是什么难事,新的数据可以很快被重新创建。

坚持的

持久数据旨在具有更长的生命周期,并且通常难以再生

  • 银行交易,
  • 客户关系系统(CRM)中的客户记录,
  • 你的照片上传到云存储。

数据存储在哪里?

这对不可变的服务器模式有明显的影响,在这种模式下,服务器的生命周期很短,部署一个服务器,当不需要它或者发生一些配置或软件更新时,部署一个新的,旧的被销毁(蓝/绿部署)。当我描述这种模式时,通常会被问及的第一个问题是,数据呢?它去哪里或从哪里来?当我使用 9–5 台服务器时,这一点尤其重要。他们在工作时间之外根本不存在。这也适用于运行在 Docker 容器中的应用程序。有三个地方可以存储这些数据。

  • 备份设备或存储上,如自动气象站 S3。
    这个访问速度很慢,但是非常便携和可靠。存储在这里的数据通常会被复制到可以访问的地方。当构建 web 服务器前端时,它将保存 web 应用程序的配置和静态文件。
  • 在共享数据服务器上,可由“计算”服务器在运行时访问。他们通过网络访问数据。
    这个快一点,便携,可靠。这里的问题归结为哪个服务器托管数据。你可以有一个网络文件系统(NFS)服务器,但是,你可能最终会得到一个“宠物”。我在关于宠物和牛的帖子里讨论过宠物服务器。
  • 在服务器本身,这是从备份位置恢复的,然后在服务器或群集上进行管理。
    有了这一选择,您可以快速、可靠地挑选,但不便于携带。有些应用程序会支持可移植性,但这主要是在应用程序设计层面。如果它不支持,我们必须使用第三方工具来完成。

为了说明我的意思,我们举三个例子。

wordpress 软件

目前部署最多的开源网站管理系统是。
这个软件作为一个单独的安装程序运行良好,但是扩展它会是一件非常痛苦的事情。最大的问题是 wordpress 将网站的数据存储在本地服务器上。如果您有多个 web 前端,它们将很快变得不同步。你为你的博客上传了一个文件,它只存储在其中一个服务器上。
Wordpress 确实有一些插件,我们可以告诉它使用 S3 作为共享数据位置,但是配置文件仍然保存在每个服务器的本地。对于这些数据,NFS 可以作为一个在线共享数据源,但是你最终可能会得到一个宠物服务器。这可以通过使用另一个 AWS 服务器弹性文件系统(EFS) 来避免。

数据库

数据库管理员最头疼的是输入/输出操作(IOPS)。为了从数据库获得快速响应,它读取的数据需要尽可能接近。这排除了上面详述的共享网络选项。几个数据库系统将在一个集群中工作,在节点间共享和分发数据。MySQL、MongoDB 和 CouchDB 等软件支持分布式节点之间的同步,以扩展部署,CouchDB 将此作为核心设计目标。这些系统支持添加和删除节点(支持故障和替换),同时保持数据安全和一致。然而,你会发现一些数据滞后,最终一致性。

码头工人

docker 容器之间的数据同步对于这项发展中的技术来说仍然是一个很大的问题。一些解决方案正在开发中,包括 ClusterHQ with Flocker、Portworx、Hedvig 和 StorageOS。我将在整理客户的整个应用程序堆栈时检查这些内容。我已经成功地使用了 BTSync ,它将数据保存在容器中,而不是托管卷上。这样就把数据和 Docker 主机分开了(避开另一个宠物)。

你见过哪些解决方案?有你想要我尝试的吗?请在下面的评论中告诉我。

本文原帖 在我自己的网站

性格:是机器学习模型的重要变量吗?

原文:https://towardsdatascience.com/personality-an-important-variable-for-machine-learning-models-e834e429c8b7?source=collection_archive---------17-----------------------

在这个机器学习的世界里,每家公司都在试图实现不同的预测模型,以了解他们的客户未来的行为。在本文中,让我们尝试关注几乎每个金融机构都面临的一个典型问题,即对违约和非违约客户进行分类,以及是否可以通过在评估程序中添加与个性相关的问题来提高准确性(是否在这里很重要)。

典型的金融机构在向客户提供贷款之前首先评估他们的客户,大多数评估问题是关于客户的主要收入和活动、他们的家庭信息、支出等。根据这些变量,这些机构建立一个模型来对他们的客户进行分类。客户分类可以通过多种方式完成,使用监督学习方法,如逻辑回归、线性判别分类、支持向量机和神经网络,或者通过 K-means 聚类,这是最常用的非监督学习技术。今天这里的主要目的不是建立一个模型,但首先重要的是要理解:为什么客户会违约?仅仅在评估过程中增加几个与性格特征相关的问题就能改变什么吗?

从机构选错客户,缺乏金融素养到不愿意还款,客户不还款,违约的原因有很多。在我看来,至少它可以提高预测能力,但最棘手的部分是应该添加什么样的问题?对于经理来说,这一部分一直是一个黑匣子,他们中的大多数人都不认为它有任何重要性。要理解这种相关性,首先应该理解理性和非理性的思维方式,一个聪明的人(理性的)永远不会把手头的现金花在不太重要的事情上,除非同一个人(完全非理性的)很容易受情绪的影响或操纵。

是的,我们都有两面性。

性格告诉我们一个人的思想、情感反应和行为,这些在不同的情况下显然是不同的,但可以用来预测一个人的诚实和正直,这在以后可能有助于改善。关键是要问正确的问题。

你的聊天机器人的个性与循环神经网络

原文:https://towardsdatascience.com/personality-for-your-chatbot-with-recurrent-neural-networks-2038f7f34636?source=collection_archive---------0-----------------------

Hello, how can I help you today?

之前的一篇短文中,我介绍了聊天机器人:它们目前的高人气,一些平台选项和基本的设计建议。

在这篇文章中,我将阐述我认为更有趣的场景:****基于深度学习的解决方案,用于构建聊天机器人的跑题行为和“个性”。换句话说,当遇到离题的问题时,机器人会试图仅基于预先训练的 RNN 模型,从头开始自动生成可能相关的答案。

接下来是四个自成一体的部分,所以你应该能够跳来跳去,只关注你感兴趣的部分,没有问题。

聊天机器人

聊天机器人(或对话代理)可以分解为两个独立但相互依赖的任务:理解和回答。

理解是对用户输入的语义和语用意义的解释和分配。回答是根据理解阶段获得的信息和聊天机器人的任务/目标,提供最合适的回答。

这篇文章很好地概述了回答任务的两种不同模型,并深入探讨了深度学习在聊天机器人中的应用。

对于基于检索的模型,回答过程主要包括从一组预定义的答案中进行某种查找(具有不同的复杂程度)。当前在生产环境中使用的、向客户和顾客展示或处理的聊天机器人很可能属于此类。

另一方面,基于生成的模型被期望,嗯…生成!它们通常基于基本的概率模型或机器学习模型。他们不依赖于一套固定的答案,但他们仍然需要接受训练,以产生新的内容。马尔可夫链最初用于文本生成的任务,但最近,递归神经网络(RNN)获得了更多的流行,在许多有前途的实际例子和展示之后(卡帕西的文章 )
聊天机器人的生成模型仍然属于研究部门,或者属于那些只是喜欢构建和演示他们自己的模型的测试应用的人的游戏领域。
我认为,对于大多数业务用例来说,它们仍然不适合生产环境。我无法想象如果提出一个生成模型选项,客户不会提出 Tay

RNN 模型

递归神经网络是专门用于处理序列的深度学习模型。这里,内部状态负责考虑并正确处理连续输入之间存在的依赖性(RNN速成班)。
除了相对优雅的模型之外,仅仅从展示其生成能力的许多在线演示和示例中,就不可能不被它捕获和迷住。从手写电影剧本生成

鉴于其特性,该模型确实非常适合各种 NLP 任务,并且正好在文本生成上下文中,我开始探索它,使用 TheanoTensorflow 玩基本概念,然后转移到 Keras 进行最终的模型训练。Keras 是一个高级神经网络库,可以运行在 Theano 或 Tensorflow 之上,但如果你愿意学习和玩 RNN 和机器学习模型的更基本的机制,我建议尝试一下提到的其他库,特别是如果再次遵循 Denny Britz 的伟大教程

在我的任务中,我训练了一个单词级的序列对序列模型:我向网络输入一个单词列表,并期望得到相同的输出。我没有使用普通的 RNN,而是使用了长期/短期记忆(LSTM)层,这保证了对网络记忆机制的更好控制(理解 LSTM )。最终的架构只包括两个 LSTM 层,每一层后面都有一个 dropout。
至于现在我还是依靠每个单词的一键编码,往往限制了词汇量的大小(< 10000)。强烈建议下一步是探索使用单词嵌入的选项。

我在不同的语料库上训练模型:个人对话、书籍、歌曲、随机数据集和电影字幕。最初的主要目标是纯文本生成:从零开始,生成任意长的单词序列,就像 Karpathy 的文章一样。通过我的适度设置,我仍然获得了相当好的结果,但是您可以看到这种方法在聊天机器人文本生成的相同假设下是如何不起作用的,聊天机器人最终是一个问答场景。

聊天机器人训练

问答是 NLP 研究的另一个大问题,它有自己的复杂和组件异构管道生态系统。即使只关注深度学习,也存在不同复杂程度的不同解决方案。我在这里想做的是首先用我的基线方法进行实验,看看离题问题处理的结果。

我使用了康奈尔电影对话语料库,并基于类似问答情景的两个连续互动的串联建立了一个训练数据集。每个这样的问答对最终构成了最终训练集的一个句子。在训练期间,模型获得从最后一个元素截断的句子作为输入,而期望的输出是从第一个单词截断的相同的输出。

在这样的前提下,模型并不是真的学习什么是答案,什么是问题,而是应该建立一个能够连贯地生成文本的内部表示。这或者通过从随机元素开始从头生成句子,或者简单地通过一次一个单词地继续完成种子句子(潜在问题),直到满足预定义的标准(例如,产生标点符号)。所有新生成的文本都会被保留并作为候选答案提供。

你可以在我的 Github 库中找到更多的细节和 WIP 实现。我们非常欢迎所有的批评和评论。

体系结构

与聊天机器人交互就像在脸书·梅桑格上发送消息一样简单,但完整的解决方案涉及不同的异构组件。这是当前架构的最小视图

Chatbot Solution Architecture

数据处理和 RNN 模型训练已经在 IBM 数据科学平台的 Spark 实例上运行。我通过 Jupyter 笔记本直接与它交互,简直太棒了!使用 Keras callbacks 系统,我在训练期间自动跟踪模特的表现,并在适当的时候备份重量。在每次训练结束时,最佳快照(模型权重)以及 Keras 模型架构和与训练语料库相关的附加数据(例如词汇索引)被持久地移动到与 Spark 实例连接的对象存储中。

第二部分是模型即服务组件;一个基本的 Flask RESTful API,通过 REST 调用公开文本生成的训练模型。每个模型是一个不同的端点,接受不同的参数用于生成任务。参数的示例有

  • 种子:用于生成任务的种子文本
  • 温度:一个方差指数,或者在预测过程中你想给模型多少“自由”
  • 句子最小长度:生成的句子可接受的最小长度

在内部,该应用程序负责从远程对象存储中检索模型并将其加载到内存中,以便当调用相应的端点时,它们准备好生成文本。

最后一个组件是一个 Java Liberty web 应用程序,它充当脸书 Messanger 平台的代理。它负责处理脸书网页挂钩和订阅,存储用户聊天记录,并实现应答任务逻辑。一方面,它依赖于我在上一篇文章中描述的系统,使用 IBM Watson 服务,如语言识别和对话,另一方面,当满足特定要求或没有提供有效答案时,它可以依赖于文本生成位,并在最方便的端点调用 Flask API。

Java 和 Python 应用程序都托管在 Bluemix 上,关于前者,我目前正在覆盖其他消息平台,如 Slack、Whatsapp 和 Telegram。

给我看看机器人!

你可以简单地通过脸书·梅桑格与聊天机器人互动,但要让你的机器人公开(任何进入其页面的人都可以使用)需要一些工作、演示视频和脸书连续的官方批准。至于现在,我必须手动添加人作为我的应用程序的测试人员,以允许他们使用它,所以如果你有兴趣,就给我留言。

尽管如此,我不得不承认,已经看到少数当前测试者的互动是一个相当有趣的经历,一个很好的娱乐、羞耻、恐惧、骄傲的情绪过山车…

让我们从一些混合的结果开始(右边是机器人的回复,左边是一些朋友的输入,很好地匿名化了)。

请注意,这里有混合行为:“嫁给我”响应是基于自然语言分类的,而其余的都是生成的。已经有语法错误的句子了,但与此同时,第二个答案给我留下了很好的印象,我被愚弄了,从中读出了一种有意识的无所不能的感觉。

有时回复看起来完全是随机的,但仍然建立了一个很好的互动,一个害羞、困惑和羞愧人格的模拟,也许还有点浪漫。

给定训练数据,它还学习了正确的标点符号,因此如果之前的输入不以标点符号结尾,它可能会以一个以标点符号开头的句子来回复。
它也能想出一些看似深奥的东西,但最终惨败,尤其是考虑到短暂的新的高预期。

请注意,答案之间绝不存在上下文保留,它只是没有建立在模型或系统中,只是产生这种错觉的交互流,有时会巧合地给人留下非常好的印象:

我知道这一切都没有突破,结果可能会让我“失望”,但毕竟,很多人对他们的“婴儿的第一句话”感到疯狂兴奋,据我所知,这远远低于我在这里设定的标准…

在观察它说话的同时,我对其背后的机制有了相当好的理解,这让一切变得更加迷人。它所能表达的一切令人感到不合理的惊讶,没有关于它被告知什么和它回复什么的实际语义知识,只有统计信号和模式……我想知道,毕竟,有多少人可能实际上以几乎相同的方式工作,只是他们的大脑中有一个更强大的借来的计算实例,他们的肩膀上有一个更长更丰富的跑步训练。

皮尤研究中心对人工智能和人类未来的回答

原文:https://towardsdatascience.com/pew-study-answers-on-artificial-intelligence-and-the-future-of-humans-a0f9f71bdccb?source=collection_archive---------15-----------------------

The AI future is uncertain, but generally, I think it will improve life.

我是皮尤研究中心昨天发布的研究报告“人工智能和人类的未来”采访的 900 多名未来学家之一这项研究是与埃隆大学合作进行的,围绕着人工智能和互联网 50 周年。

该报告提出了三个问题,以了解如果新兴的算法驱动的人工智能(AI)继续传播,人们的生活会比现在更好吗?以下是被问到的确切问题,以及我的完整回答。你还可以在报告第 92 页看到我引用的话。

皮尤/埃隆: 请勾勒出 2030 年人机/AI 协作将如何运作的愿景。请举例说明典型的人机交互在特定领域的外观和感觉,例如在工作场所、家庭生活、医疗保健环境或学习环境中。

为什么?你的希望或恐惧是什么?可以采取什么行动来确保最好的未来?

我:AI 这个词误导人。我们应该称之为趋势机器学习或算法。所谓的“弱”人工智能——今天的人工智能——减少了大多数人认为平淡无奇的重复任务。这反过来又产生了一个逃离无产阶级陷阱的机会,他们被迫从事单调的劳动来谋生。

我们不应该去想“终结者”,而应该将当前的趋势视为一个机会,去寻找和拥抱我们真正热爱的任务,包括更多的创造性追求。如果我们接受不可避免的技术进化来取代多余的任务,我们就可以鼓励今天的年轻人追求更具创造性和战略性的追求。此外,今天的工人可以学习如何管理机器学习或接受培训,以追求他们可能更喜欢的新职业。

我担心的是,许多人会简单地拒绝改变,指责技术,就像他们经常做的那样。有人可能会说,今天我们在全球经历的许多民粹主义起义都是在当前以智能制造为代表的机器学习导致的取代中找到根源的。如果是这样的话,前进的道路将会充满麻烦,充满黑暗的弯路和转弯,作为文化和国家,我们可能会后悔。

***皮尤/埃隆:***2019 年将是第一个主机对主机互联网连接 50 周年。请思考下一个 50 年。半个世纪后,互联网和数字生活将会怎样?请告诉我们您认为互联技术、平台和应用将如何融入人们的生活。你可以解决这个问题中对你重要的任何方面。

你可以考虑关注这样的问题:你希望在数字世界的平台公司中看到什么变化?你认为互联网上的应用和功能会有什么变化?数字工具将如何融入日常生活?什么将是全新的?从今天的互联网来看,什么将会发展并被认可?在这几年间,互联网工程中的哪些新规则、法律或创新会改变当今互联网的特征?

**我:**技术将成为大多数人的无缝体验。只有那些买不起技术的穷人和那些可以选择脱离技术的富人才能摆脱连接。

当我考虑当前的人工智能对话时,我经常认为有意识生物的真正进化将是人类和机器之间的混合连接。我们的存在和日常体验将通过一种增强的体验来实现,这种体验以更快的思维和更空灵的快乐为特征。

这就带来了一个问题,什么是人?由于我们大多数人将生活在一个机器增强的世界里,人类现实的前景将永远受到质疑。大多数人将只是简单地通过他们的存在而没有思考,能够用新的软件包和算法改变它,接受他们的现实作为新常态。的确,感知会变成现实。

会有一些人谴责这种向前发展的运动,并希望回到过去那种不插电的状态。2070 年的反互联网运动意义重大,但就像今天的勒德分子一样,它会发现自己是极少数。因为尽管文化影响将是巨大的,但 2070 年的互联网给世界带来了更加繁荣和便捷的生活。大多数人会选择舒适而不是独立于设备。

我们在网上经历的不和谐,比如 Twitter 上的争吵和标签之争,也会变得不那么明显。我想关掉噪音会容易得多。当然,这意味着越来越多孤立的人群,反过来,他们可能会对生活产生奇怪的、有时甚至是有害的看法和态度。这可能是新互联网的最大危险,发展暴力和破坏性生活方式的微型邪教的能力。

那些完全拥护这场运动的人将继续在技术上进步,也许是盲目的。他们将带领我们走向新的维度。人类的灵魂何时能够超越肉体,进入机器或真正的虚拟体验?对我来说,这是未来互联网的真正问题。

PEW/ELON: 解释你对上一个问题的回答,并描述你所看到的未来 50 年数字生活的变化影响个人的方式。

我:总的来说,我认为人们在生活中会更快乐。他们会不那么讨厌自己的工作,因为他们会做自己喜欢的事情。他们会因为没有工作而更能追求真正的兴趣。饥饿和住所将更容易解决,因为我们将利用技术更好地解决这些挑战。

相反,疼痛将成为一个存在的问题,而不是马斯洛对生理需求和安全的追求。这并不是说贫困和冲突将不复存在,但我确实相信气候变化代表着世界文化将面临的最大的物理危险。

战争将会因为谁能以庇护所和食物的形式获得安全而爆发。那些输掉战争的人将不会拥有技术。我最大的希望是[富人]会明白,如果少一些痛苦,对每个人都更好。也许会提供一个基本的技术水平和生理安全水平的等级支持。

从长远来看,由银行账户决定输赢的零和游戏对全球没有帮助。在未来,贪婪是最大的危险。因为贪婪只能在科技力量中表现出来。强迫他人陷入技术贫困将成为一种残忍的行为。

精选图片由作者本人原创。

天气数据、绘图和代码

原文:https://towardsdatascience.com/pgh-weather-data-plot-and-code-19d8e8b670f?source=collection_archive---------3-----------------------

改编自 Austin Wehrwein 的博客文章和 Claus O. Wilke 的 Cran page 。地下气象站的数据。

生成如上图的 R 代码可以在 Austin Wehrwein 的博客和这个 Cran page 上找到,但是我也把它包含在下面,做了一些小的修改和如何从 Weather Underground 检索你自己的数据的细节。

数据:

在这个 Weather Underground 页面上选择地区和自定义时间段。将表格数据复制/粘贴到 Excel 中(可能需要删除额外的列标题)。按照格式“%d-%b-%y”或“2016 年 1 月 1 日”重新标记日期。重新标记列标题。另存为 CSV。

注:你可以尝试用这个教程直接从 R 抓取,但是吴最近改了他们的 URL 方案,所以这个技术可能不行。

Your data should look something like this. Mean Temp (Col C) is what I plotted, but pretty much any numeric variable can be used.

图书馆:

library(viridis)     ## color palette
library(ggjoy)       ## ridges
library(hrbrthemes)  ## plot theme

导入和次要数据清理:

pgh_weather <- read.csv("weather_data.csv") ## setwd() to your own
months <- c("December","November","October","September","August","July","June","May","April","March","February","January") ## need this string vector for sorting laterpgh_weather$months <- as.Date(pgh_weather$CST, format = "%d-%b-%y") %>%
  months() %>%
  as.factor() %>%
  factor(., levels = months)#scales
mins <- min(pgh_weather$Min.TemperatureF)
maxs <- max(pgh_weather$Max.TemperatureF)

情节:

## black and white
ggplot(pgh_weather,aes(x = Mean.TemperatureF,y=months,height=..density..))+
  geom_joy(scale=3) +
  scale_x_continuous(limits = c(mins,maxs))+
  theme_ipsum(grid=F)+
  theme(axis.title.y=element_blank(),
        axis.ticks.y=element_blank(),
        strip.text.y = element_text(angle = 180, hjust = 1))+
  labs(title='Temperatures in Pittsburgh',
       subtitle='Median temperatures (Fahrenheit) by month for 2016\nData: Original CSV from the Weather Underground', x = "Mean Tempterature [ºF]")## in color
ggplot(pgh_weather, aes(x = `Mean.TemperatureF`, y = `months`, fill = ..x..)) +
  geom_density_ridges_gradient(scale = 3, rel_min_height = 0.01, gradient_lwd = 1.) +
  scale_x_continuous(expand = c(0.01, 0)) +
  scale_y_discrete(expand = c(0.01, 0)) +
  scale_fill_viridis(name = "Temp. [ºF]", option = "C") +
  labs(title = 'Temperatures in Pittsburgh',
       subtitle = 'Mean temperatures (Fahrenheit) by month for 2016\nData: Original CSV from the Weather Underground', 
       x = "Mean Temperature") +
  theme_ridges(font_size = 13, grid = TRUE) + theme(axis.title.y = element_blank())

后续步骤:

下载年度数据,用 GIF 或褪色的脊线追踪上升的温度。

使用 ML 检测网络钓鱼 URL

原文:https://towardsdatascience.com/phishing-domain-detection-with-ml-5be9c99293e5?source=collection_archive---------0-----------------------

网络钓鱼是一种欺诈形式,在这种形式中,攻击者试图通过在电子邮件或其他通信渠道中以信誉良好的实体或个人的身份发送来获取登录凭据或帐户信息等敏感信息。

通常,受害者会收到一封看似由已知联系人或组织发送的邮件。该邮件包含针对用户计算机的恶意软件,或者具有将受害者引向恶意网站的链接,以欺骗他们泄露个人和财务信息,如密码、帐户 id 或信用卡详细信息。

网络钓鱼在攻击者中很流行,因为欺骗某人点击看似合法的恶意链接比试图突破计算机的防御系统更容易。邮件正文中的恶意链接旨在使邮件看起来像是发送到了使用该组织徽标和其他合法内容的欺骗组织。

在这篇文章中,我解释了:网络钓鱼域(或欺诈性域)的特征,区分它们与合法域的特征,为什么检测这些域很重要,以及如何使用机器学习和自然语言处理技术来检测它们。

许多用户每天每小时都在不知不觉中点击钓鱼域名。攻击者的目标是用户和公司。根据 2014 年 2 月发布的第三份 Microsoft Computing Safer Index 报告,网络钓鱼每年在全球造成的影响可能高达 50 亿美元。

这个成本的原因是什么?

主要原因是用户的认知度不够。但安全卫士必须采取预防措施,防止用户面对这些有害的网站。要防止这些巨大的成本,除了建立强大的安全机制,能够检测和防止网络钓鱼域到达用户之外,还可以从提高人们的意识开始。

网络钓鱼域的特征

让我们检查 URL 结构,以便清楚地了解攻击者在创建网络钓鱼域时是如何思考的。

统一资源定位符(URL)是为处理网页而创建的。下图显示了典型 URL 结构中的相关部分。

它从用于访问页面的协议开始。完全限定的域名标识托管网页的服务器。它由一个注册域名(二级域名)和我们称之为顶级域名(TLD)的后缀组成。域名部分受到限制,因为它必须向域名注册机构注册。主机名由子域名和域名组成。网络钓鱼者可以完全控制子域部分,并可以设置任何值。URL 还可能包含路径和文件组成部分,这些内容也可能被网络钓鱼者随意更改。域名和路径完全可以被网络钓鱼者控制。在本文的其余部分,我们使用术语 FreeURL 来指代 URL 的这些部分。

攻击者可以注册任何以前没有注册过的域名。URL 的这一部分只能设置一次。网络钓鱼者可以随时更改 FreeURL 来创建新的 URL。安全卫士努力检测钓鱼域名的原因是因为网站域名的独特部分(免费网址)。当一个域被检测为欺诈性时,很容易在用户访问它之前阻止该域。

一些威胁情报公司检测并发布欺诈性网页或 IP 作为黑名单,从而防止其他人获得这些有害资产变得越来越容易。( cymonfireho l)

攻击者必须明智地选择域名,因为目标应该是说服用户,然后设置 FreeURL 使检测变得困难。让我们分析下面给出的一个例子。

虽然真正的域名是 active-userid.com,但攻击者试图通过添加 FreeURL 使该域名看起来像 paypal.com。当用户在 URL 的开头看到 paypal.com 时,他们可以信任该网站并连接它,然后可以将他们的敏感信息分享给这个欺诈网站。这是攻击者经常使用的方法。

攻击者经常使用的其他方法是域名抢注和域名抢注。

域名抢注(也称为域名抢注)是指恶意注册、买卖或使用域名,意图从属于他人的商标商誉中获利。域名抢注者可能会以高价向拥有域名中所含商标的个人或公司出售该域名,或将其用于欺诈目的,如网络钓鱼。例如,你的公司名称是“ABC 公司”,你注册为 abcompany.com。然后,网络钓鱼者可以注册 abcompany.biz,abcompany.biz,abcompany.biz,他们可以使用它进行欺诈。

域名抢注,也称为 URL 劫持,是域名抢注的一种形式,它依赖于互联网用户在网络浏览器中输入网站地址时出现的打字错误或快速阅读时很难注意到的打字错误。用域名仿冒创建的 URL 看起来像一个受信任的域。用户可能会意外输入错误的网站地址或单击看似可信域的链接,这样,他们可能会访问网络钓鱼者拥有的替代网站。

域名仿冒的一个著名例子是goggle.com,一个极其危险的网站。另一个类似的东西是 yutube.com 的**,它类似于 goggle.com,除了它的目标是 Youtube 用户。类似地,被错别字为将用户引向一个兜售打折旅游的网站。其他一些例子;paywpal.commicroroft.comapplle.comappie.com**

用于网络钓鱼域检测的功能

在学术文献和商业产品中,有许多用于网络钓鱼检测的算法和各种各样的数据类型。网络钓鱼 URL 和相应的页面有几个可以与恶意 URL 区分开来的特征。比如说;攻击者可以注册长而混乱的域名来隐藏实际的域名 ( 域名抢注,域名抢注)。在某些情况下,攻击者可以使用直接 IP 地址,而不是使用域名。这种类型的事件超出了我们的范围,但是它可以用于相同的目的。攻击者还可以使用与合法品牌名称无关的短域名,并且没有任何免费网址。但是这些类型的网站也不在我们的讨论范围之内,因为它们与欺诈性域而不是网络钓鱼域更相关。

除了基于 URL 的特征之外,还使用了在学术研究的检测过程中的机器学习算法中使用的不同种类的特征。从学术研究中收集的使用机器学习技术进行网络钓鱼域检测的特征分组如下。

  1. 基于 URL 的功能
  2. 基于领域的功能
  3. 基于页面的功能
  4. 基于内容的功能

基于 URL 的功能

URL 是分析一个网站以确定它是否是网络钓鱼的第一件事。正如我们之前提到的,钓鱼网站的网址有一些独特之处。当处理 URL 时,获得与这些点相关的特征。下面给出了一些基于 URL 的功能。

  • URL 中的位数
  • URL 的总长度
  • 正在检查 URL 是否被仿冒。(google.com→goggle.com)
  • 检查它是否包括一个合法的品牌名称(apple-icloud-login.com)
  • URL 中的子域数量
  • 顶级域名(TLD)是常用的域名之一吗?

基于领域的功能

网络钓鱼域名检测的目的是检测网络钓鱼域名。因此,与域名相关的被动查询,我们希望将其归类为网络钓鱼或不钓鱼,为我们提供了有用的信息。下面给出了一些有用的基于域的特性。

  • 其域名或其 IP 地址在知名信誉服务黑名单中?
  • 自域名注册以来已经过去了多少天?
  • 注册人姓名是否隐藏?

基于页面的功能

基于页面的特征使用关于计算的信誉等级服务的页面的信息。这些特征中的一些给出了关于一个网站有多可靠的信息。下面给出了一些基于页面的特性。

  • 全球页面排名
  • 国家网页排名
  • 在 Alexa 前 100 万网站的位置

一些基于页面的功能为我们提供了目标网站上用户活动的信息。下面给出了其中的一些特征。获得这些类型的特征并不容易。有一些付费服务可以获得这些类型的功能。

  • 估计每天、每周或每月访问该域的次数
  • 每次访问的平均浏览量
  • 平均就诊时间
  • 每个国家的网络流量份额
  • 从社交网络到给定域的引用计数
  • 领域的类别
  • 类似的网站等。

基于内容的功能

获取这些类型的特征需要主动扫描目标域。我们会对页面内容进行处理,以检测目标域是否用于网络钓鱼。下面给出了一些关于页面的已处理信息。

  • 页面标题
  • 元标签
  • 隐藏文本
  • 正文中的文本
  • 图像等。

通过分析这些信息,我们可以收集如下信息:

  • 需要登录网站吗
  • 网站类别
  • 关于观众简介等信息。

上面解释的所有特征对于网络钓鱼域检测都是有用的。在某些情况下,使用其中一些功能可能没有用,因此使用这些功能有一些限制。例如,将某些功能(如基于内容的功能)用于正在开发的快速检测机制可能是不合理的,该机制能够分析 100,000 到 200,000 之间的域名数量。另一个例子是,如果我们要分析新注册的域名,基于网页的功能不是很有用。因此,检测机制将使用的特征取决于检测机制的目的。应该仔细选择在检测机制中使用哪些特征。

检波过程

检测网络钓鱼域是一个分类问题,因此这意味着我们需要在训练阶段将样本作为网络钓鱼域和合法域的标记数据。将在训练阶段使用的数据集是建立成功的检测机制的非常重要的点。我们必须使用类别确切已知的样本。因此,这意味着,被标记为网络钓鱼的样本必须绝对被检测为网络钓鱼。同样,被标记为合法的样本必须被绝对检测为合法。否则,如果我们使用不确定的样本,系统将无法正常工作。

为此,一些公共数据集被创建用于网络钓鱼。其中比较知名的是 PhishTank 。这些数据源通常用于学术研究。

收集合法域名是另一个问题。为此,通常使用站点信誉服务。这些服务对现有网站进行分析和排名。这种排名可以是全球性的,也可以是基于国家的。排名机制取决于各种各样的功能。排名分数高的网站是经常使用的合法网站。其中一个知名的信誉排名服务是 Alexa 。研究人员正在使用合法网站 Alexa 的顶级列表。

当我们有网络钓鱼和合法网站的原始数据时,下一步应该是处理这些数据并从中提取有意义的信息,以检测欺诈性的域。用于机器学习的数据集实际上必须包含这些特征。因此,我们必须处理从 Alexa、Phishtank 或其他数据资源收集的原始数据,并创建一个新的数据集来用机器学习算法训练我们的系统。特征值应该根据我们的需要和目的来选择,并且应该为每一个特征值进行计算。

机器学习算法有很多,每种算法都有自己的工作机制。在本文中,我们解释了 决策树算法 ,因为我认为,这个算法是一个简单而强大的算法。

最初,正如我们上面提到的,钓鱼域名是分类问题之一。因此,这意味着我们需要标记实例来建立检测机制。在这个问题中,我们有两个类别: (1) 网络钓鱼和 (2) 合法。

当我们计算选择了我们的需求和目的的特征时,我们的数据集如下图所示。在我们的例子中,我们选择了 12 个特征,并对它们进行了计算。因此,我们生成了一个数据集,该数据集将用于机器学习算法的训练阶段。

决策树可以被认为是一种改进的嵌套式 if-else 结构。每个特征将被逐一检查。下面给出了一个示例树模型。

生成树是检测机制的主要结构。黄色和椭圆形代表特征,这些被称为节点。绿色和有角的代表类,这些被称为叶子。当一个示例到达时,检查长度,然后根据结果检查其他特征。当样品的旅程完成时,样品所属的类别将变得清楚。

**现在,关于决策树最重要的问题还没有答案。问题是,**将作为根定位哪个特性?哪些必须跟在根后面?智能选择特征直接影响算法的效率和成功率。

那么,决策树算法是如何选择特征的呢?

决策树使用信息增益度量,该度量指示给定特征根据训练样本的目标分类来分离训练样本的程度。方法的名字叫信息增益**。下面给出了信息增益方法的数学方程。**

高增益分数意味着该特征具有高区分能力。因此,具有最大增益分数的特征被选为根。是信息论中的一种统计度量,它描述了任意样本集合的(不)纯度。熵的数学方程如下所示。

原始熵是一个常数,相对熵是可变的。低相对熵值意味着高纯度,同样高相对熵值意味着低纯度。当我们沿着树向下移动时,我们希望增加纯度,因为叶子上的高纯度意味着高成功率。

在训练阶段,通过比较特征值将数据集分成两部分。在我们的例子中,我们有 14 个样本。“+”符号代表网络钓鱼类别,而“-”符号代表合法类别。我们根据长度特征将这些样本分成两部分。其中七个在右边,另外七个在左边。如下图所示,树的右边部分具有高纯度,因此它意味着低熵值(E),同样树的左边部分具有低纯度和高熵值(E)。所有的计算都是根据上面给出的方程进行的。关于长度特征的信息增益得分为 0,151。

决策树算法为每个特征计算该信息,并选择具有最大增益分数的特征。为了增长树,叶子被改变为代表特征的节点。随着树往下长,所有的叶子都会有很高的纯度。当树足够大时,训练过程就完成了。

通过选择最显著的特征而创建的树代表了我们的检测机制的模型结构。创建成功率高的机制依赖于训练数据集。为了系统成功的一般化,训练集必须由取自各种数据源的各种各样的样本组成。否则,我们的系统可能在我们的数据集上以高成功率工作,但是它不能在真实世界的数据上成功工作。

Photoshop 2.0

原文:https://towardsdatascience.com/photoshop-2-0-a49990e483?source=collection_archive---------5-----------------------

如果说软件 2.0 是深度学习,Photoshop 2.0 就是 GAN

Photoshop 1.0 是什么?

我们可以使用 Photoshop 来“改变”图像,比如照片、下载的图标或扫描的艺术品。改变图像包括做一些事情,比如改变图像内的颜色修改图像的尺寸比例,或者将一张图片“放入”另一张图片。

需要多少时间?那**完美呢?**你还是设法做到了。那很好。

甘家擅长什么?甘是如何有所作为的?

生成性对抗网络擅长将图像从一个领域翻译到另一个领域。

比如:从用户草图生成猫。

我们所有人都不擅长编辑照片。但有时我们必须自己去做。假设你想改变头发的颜色或者尝试不同的发型,该怎么做呢?如果你不熟悉这些工具,就很难把图像转换成你想要的样子。

GANs 可以将你的草图转换成逼真的图像。

Semantic label Map

Real Image

生成器可以将语义标签图翻译成逼真的图像,而鉴别器 D 旨在将真实图像与翻译后的图像区分开来。

pix2pix 架构

pix2pix 方法是一个条件 GAN 框架,用于在给定输入语义标签图的情况下对真实图像的条件分布进行建模。

Conditional GANs

条件 GAN是 GAN 框架的扩展。这里我们有条件信息 Y,它描述了数据的某些方面。例如,如果我们在处理人脸,Y 可以描述头发颜色或性别等属性。

当生成高分辨率图像时,结果不令人满意。所以为了提高的真实感的分辨率,开发了一种新的架构。

开发了一个粗到精生成器、一个多尺度鉴别器架构和一个鲁棒的对抗学习目标函数

粗到精发生器

Network architecture of the generator.

生成器由全局生成器网络(G1)局部增强器网络(G2)组成。

全局生成器(G1) 从语义图中提取降采样输入,并生成低分辨率输出。局部增强器(G2) 组合来自生成器和原始标签图的特征图,以产生最终输出。

为了以更高的分辨率合成图像,可以使用附加的局部增强器网络

生成器 G={G1,G2},输出图像分辨率 =2048×1024

生成器 G={G1,G2,G3},输出图像分辨率 =4096×2048

在训练过程中,我们首先训练全局生成器,然后按照分辨率的顺序训练局部增强器。然后我们一起微调所有的网络。

多刻度鉴别器

多尺度鉴别器由 3 个鉴别器(D1,D2,D3) 组成,它们具有相同的网络结构,但在不同的图像尺度下工作。

他们接受过训练,能够以 3 种不同的比例区分真实图像和合成图像。

在最粗尺度下工作的鉴别器具有最大的感受野。另一方面,以最精细的尺度操作的那个引导生成器产生更精细的细节。

对抗性学习目标函数

基于鉴别器的特征匹配损失是不可行的。从鉴别器的多个层提取特征,并学习匹配来自真实和合成图像的这些中间表示。

学习实例级特征嵌入

添加低维特征通道作为生成器的输入,可以产生多样的图像,并允许实例级控制

训练一个编码器网络来为地面真实图像中的每个对象实例找到低维特征向量。然后,我们将这些特征与标签图连接起来,生成最终的图像。我们可以通过操作不同的特征来产生不同的输出。

结果

Semantic labels → Cityscapes street views

参考

https://tcwang0509.github.io/pix2pixHD/

使用 Jupyter 笔记本进行物理计算

原文:https://towardsdatascience.com/physical-computing-using-jupyter-notebook-fb9e83e16760?source=collection_archive---------5-----------------------

了解如何在树莓 Pi 上安装 Jupyter Notebook,并直接在上面读取传感器并对执行器进行操作。

我们都知道 Jupyter Notebook 是一个非常棒的工具,或者更好,是一个开源的 web 应用程序,它允许您创建和共享包含实时代码、等式、可视化和叙述性文本的文档。

Jupyter 笔记本很大程度上用于数据科学,清理和转换数据,做数值模拟,统计建模,数据可视化,机器学习,等等!

但是,用 Jupyter 笔记本控制树莓 Pi GPIOs 怎么样?

这就是我们在本教程中要做的。我们将学习如何在树莓 Pi 上安装 Jupyter Notebook,并直接在其上读取传感器并对执行器进行操作。

1.介绍

这张图表给我们提供了该项目的概况:

这部电影可以给你一个提示,当 Pi 遇到 Jupyter 时可能会得到什么!

2.硬件

材料清单

  • 树莓 Pi V3
  • DHT22 温度和相对湿度传感器
  • DS18B20 防水温度传感器
  • BMP180 气压、温度和海拔传感器
  • LEDS (3x)
  • 按钮(1x)
  • 电阻器 4K7 欧姆(2x)
  • 电阻器 1K 欧姆(1x)
  • 电阻器 330 欧姆(3x)
  • 原型板和电缆

电气图

让我们按照上面的电路图,将所有 3 个传感器、按钮和 led 连接到 Raspberry Pi。

本项目中使用的传感器与我的教程中使用的传感器相同:

带 RPi 和 ESP8266 的物联网气象站

我建议您看一下那个教程,在那里我一个一个地解释了如何安装传感器和它们的库,在运行完整的程序之前单独测试它们。

3.安装 Jupyter

要在您的 Raspberry 上安装 Jupyter(将与 Python 3 一起运行),请打开终端并输入以下命令:

sudo pip3 install jupytersudo ipython3 kernelspec install-self

现在,在您的终端上,运行命令:

jupyter notebook

就是这样!!!!太神奇了!非常简单容易。Jupyter 笔记本将作为服务器运行在:

http:localhost:8888

但是,这对你来说并不重要,因为,你的默认浏览器会自动在那个地址打开,运行一个“主页”。

要停止服务器并关闭“内核”(Jupyter 笔记本),您必须使用键盘上的[Ctrl] + [C]。

从现在开始,任何时候你启动你的 Pi 并想使用 Jupyter 笔记本,只需在你的终端上键入命令“Jupyter 笔记本”并让**让它一直运行。**这很重要!如果您需要使用终端执行其他任务,例如运行程序,请打开一个新的终端窗口。

4.在 Jupyter 笔记本上运行 Python 脚本

我们假设你熟悉 Jupyter 笔记本。它将在您的 Pi 上工作,就像在您的桌面上工作一样。

网上有“大量”好的 Jupyter 笔记本教程,只要浏览一下,你肯定会找到一个更适合你的。

让我们玩一个我已经为本教程创建的笔记本。

从我的 GitHub 下载:气象站传感器—执行器

将笔记本保存在您的树莓 Pi 上。在我的情况下,我把它保存在我的主目录中(见上面的主页打印屏幕)。观察我主目录中现有的 4 个笔记本(笔记本有一个“小笔记本”图标)。只要点击它。笔记本将被加载,显示如上图所示。如果你再次看到主页,你会意识到“笔记本图标”现在是“绿色”,这意味着它正在运行。

此外,请注意,在我的笔记本电脑的第一个单元有一张硬件的图片。为了让图片正确显示,你必须将它放在同一个目录中(这是我的情况),或者如果你使用另一个目录来存储图片,则改变它在笔记本上的路径。

您可以在笔记本电脑上直接输入 Unix 命令,就像在终端上一样

例如,该命令:

ls

将列出笔记本运行的当前目录中的所有文件,如下所示:

5.初始化(1):在 Jupyter 笔记本上创建 Python 脚本并导入库

因此,我们的想法是以您习惯使用 Python IDE 的相同方式(和顺序)开始编写脚本。

我将把我的笔记本分成 3 个阶段,我们将这样做:

  1. 初始化
  • 导入库
  • 定义 GPIOs
  • 初始化 GPIOs
  • 创建重要功能

2.读数传感器

3.读取和操作 GPIOs(按钮和 led)

请注意,通常情况下,您只需运行一次初始化阶段。之后,您可以使用您的传感器和 GPIOs,只运行为阶段 2 和 3 创建的相关单元,如本例所示。

为了更好地理解第一阶段,您可以跟随介绍电影。

6.初始化(2):定义和初始化 GPIOs

7.初始化(3):显示数据的函数

8.初始化(4):处理传感器的功能

9.初始化(5):用于处理 GPIOs 的函数

10.获取传感器数据并使用 GPIOs 进行处理

运行单元[11]您将获得所有传感器数据:

Widgets

在这里,重要的是要引起对“小部件”的注意。

小部件是多事件的 python 对象,在浏览器中有一个表示,通常是像滑块、文本框等控件。您可以使用小部件为您的笔记本构建交互式 GUI。您还可以使用小部件在 Python 和 JavaScript 之间同步有状态和无状态信息。

在本例中,我们使用小工具(“滑块”)来控制单元[12],实时控制致动器的状态,在本例中,打开或关闭 led。小工具可以为 Jupyter 笔记本电脑添加更多动态行为。

正如你所看到的,在代码中,我们必须在任何时候运行单元[11]来更新传感器的值,但是当然,这里也可以实现一个小部件来自动完成,或者通过按下一个按钮来完成。我会把它作为对你的挑战!;-)

安装

为了使用小部件,您必须安装 Ipywidgets 库。对于以下命令使用:

sudo pip3 install ipywidgets
jupyter nbextension enable --py widgetsnbextension

安装后,只调用 Jupyter 笔记本上的库。

请注意,我们已经在初始化阶段完成了这项工作:

# widget library
from ipywidgets import interactive
import ipywidgets as widgets
from IPython.display import display

这个小部件“交互式”易于实现,而且功能非常强大。点击此链接可以了解更多关于互动的内容:互动小工具

11.数据科学、机器学习、物理计算、计算机视觉、物联网和……未来!

我正在这个迷人的技术世界开始新的旅程。我们今天看到的一切都与数据相关,更好地了解这些数据是帮助人们的相关项目的关键。你会在这里和我的博客 MJRoBot.org上看到越来越多的教程,其中数据科学与物理计算、计算机视觉、机器学习和物联网相结合。

作为一个例子,我使用了以前的物联网项目的数据,ArduFarmBot:

使用在物联网平台上记录的数据,ThingSpeak 和 appliyng 机器学习这些数据,可以预测(事实上确认)灯和泵应该何时打开。

结果很惊人!!!!!!

可以在我的 GitHub 上看到 Jupyter 笔记本和最终报告:ArduFarmBot _ Data _ Analysis

就这些了,伙计们!;-)

12.结论

一如既往,我希望这个项目可以帮助其他人找到进入令人兴奋的电子世界的方法!

详情和最终代码请访问我的 GitHub 仓库: Pyhon4DS/RaspberryPi

更多项目,请访问我的博客:MJRoBot.org

敬请期待!下一个教程我们将基于 Raspberry Pi Flask Web 服务器将数据从远程气象站发送到中心气象站:

来自世界南部的 Saludos!

下节课再见!

谢谢你,

马塞洛

物理引导的神经网络

原文:https://towardsdatascience.com/physics-guided-neural-networks-pgnns-8fe9dbad9414?source=collection_archive---------5-----------------------

Talking some sense into gradient descent.

基于物理的模型是当今科技的核心。近年来,数据驱动模型开始提供一种替代方法,并在许多任务中胜过物理驱动模型。即便如此,他们也渴望数据,他们的推论可能很难解释,归纳仍然是一个挑战。结合数据和物理可以揭示两个世界的精华。

当机器学习算法在学习时,它们实际上是在你选择的算法、架构和配置所定义的假设空间中搜索解决方案。即使对于相当简单的算法,假设空间也可能相当大。数据是我们在这个巨大的空间中寻找解决方案的唯一指南。如果我们可以利用我们对世界的了解——例如,物理学——以及数据来指导这种搜索,会怎么样呢?

这就是 Karpatne 等人在他们的论文中解释的物理引导神经网络(PGNN):在湖泊温度建模 *中的应用。*在这篇文章中,我将解释为什么这个想法至关重要,我还将通过总结这篇文章来描述他们是如何做到的。

想象一下你把你的外星人👽朋友(优化算法)到一家超市(假设空间)去买你喜欢的奶酪(解)。她唯一的线索就是你给她的奶酪的照片(数据)。由于她缺乏我们对超市的先入之见,她将很难找到奶酪。她可能会在到达食品区之前逛逛化妆品和清洁用品。

Finally reached the food section (courtesy of Dominic L. Garcia).

这类似于梯度下降等机器学习优化算法寻找假设的方式。数据是唯一的指南。理想情况下,这应该工作得很好,但大多数时候数据是嘈杂的或不够的。将我们的知识整合到优化算法中——在食品区搜索奶酪,甚至不要看化妆品——可以缓解这些挑战。接下来让我们看看,我们实际上是如何做到这一点的。

如何用物理学指导一个 ML 算法

现在,让我总结一下作者如何利用物理学来指导机器学习模型。他们为此提出了两种方法:(1)使用物理理论,他们计算额外的特征(特征工程)以与测量值一起输入到模型中,以及(2)他们将物理不一致项添加到损失函数中,以便惩罚物理不一致的预测。

(1) Feature engineering using a physics-based model

(2) Data + Physics driven loss function

第一种方法是特征工程,广泛用于机器学习。然而,第二种方法令人信服。非常类似于添加一个正则项来惩罚过度拟合,他们在损失函数中添加了一个物理不一致性项。因此,有了这个新术语,优化算法还应该注意最小化物理上不一致的结果。

在论文中,Karpatne 等人将这两种方法与神经网络相结合,并展示了一种他们称为物理导向神经网络(PGNN)的算法。PGNNs 可以提供两个主要优势:

  • 实现泛化 是机器学习中的一个根本性挑战。由于物理模型大多不依赖于数据,它们可能在看不见的数据上表现良好,即使来自不同的分布。
  • 机器学习模型有时被称为黑盒模型,因为并不总是清楚模型如何达成特定决策。有相当多的工作进入 可解释的 AI (XAI) 来提高模型的可解释性。PGNNs 可以为 XAI 提供一个基础,因为它们提供了物理上一致和可解释的结果。

应用示例:湖泊温度建模

文中以湖泊温度建模为例,验证了 PGNN 的有效性。水温控制着湖中生物物种的生长、存活和繁殖。因此,对温度的准确观察和预测对于理解社区中发生的变化是至关重要的。任务是开发一个模型,可以预测给定湖泊的水温,作为深度和时间的函数。现在让我们看看他们是如何应用(1)特征工程和(2)损失函数修正来解决这个问题的。

(1)对于特征工程,他们使用了一种称为 通用湖模型(GLM) 的模型来生成新的特征并将它们输入到神经网络中。这是一个基于物理学的模型,它捕捉了湖泊温度动态的控制过程(太阳加热、蒸发等。).

(2)现在让我们看看他们是如何定义这个物理不一致性术语的。众所周知,密度较大的水下沉。水温与其密度之间的关系也是已知的。因此,预测应该遵循这样的事实:点越深,预测的密度越高。如果对于一对点,模型预测离表面越近的点密度越高,这是物理上不一致的预测。

现在有可能将这一想法纳入损失函数。如果ρA> ρB,我们就惩罚它,否则什么也不做。而且,对于较大的不一致,处罚力度应该更高。这可以很容易地通过将函数 max( ρA- ρB,0) 的值加到损失函数上来实现。如果ρA > ρB(即不一致),该函数将给出一个正值,该正值将增加损失函数(我们试图最小化的函数)的值,否则将给出零,保持损失函数不变。

此时,为了正确使用该函数,需要对其进行两处修改。重要的是所有对的平均不一致性,而不是一个对。因此,可以对所有点的 max( ρA- ρB,0) 求和,然后除以点数。此外,控制最小化物理不一致性的相对重要性也很关键。这可以通过将平均物理不一致性乘以超参数(类似于正则化参数)来实现。

Physical inconsistency term of the loss function

结果

以下是 4 个模型的结果。它们是:

  • PHY: 将军湖模型(GLM)。
  • NN: 一个神经网络。
  • PGNN0: 具有特征工程的神经网络。GLM 的结果作为附加特征输入到神经网络中。
  • PGNN: 具有特征工程和修改的损失函数的 NN。

和两个评估指标:

  • RMSE: 均方根误差。
  • **物理不一致:**模型做出物理不一致预测的时间步长的分数。

Results on Lake Mille Lacs

Results on Lake Mendota

将神经网络与 PHY 进行比较,我们可以得出结论,神经网络以物理上不一致的结果为代价给出了更精确的预测。比较 PGNN0 和 PGNN,我们可以看到,由于修改的损失函数,物理不一致性被消除。精度的提高主要是由于特征工程以及损失函数的一些贡献。

总而言之,这些初步结果向我们表明,这种新型算法 PGNN 非常有希望提供准确且物理上一致的结果。此外,将我们对世界的知识结合到损失函数中提供了一种改善机器学习模型的泛化性能的优雅方式。这个看似简单的想法有可能从根本上改善我们进行机器学习和科学研究的方式。

你可以在推特上找到我 @malicannoyan

延伸阅读
理论指导下的数据科学:从数据中进行科学发现的新范式

物理学通知深度学习(上):非线性偏微分方程的数据驱动解

物理、脚趾和机器学习

原文:https://towardsdatascience.com/physics-toes-and-machine-learning-ad3ba2d5d7d8?source=collection_archive---------3-----------------------

我很早就对机器学习、物理和生命(生物学)之间的联系感兴趣。例如,我一直想知道一个人是否可以把进化理解为一个学习过程(把它想象成"超个体学习适应"),或者像莱斯利·瓦里安在他的可进化性理论中建议的那样:【自然进化可以被理解为 PAC 可学习性的一个受限情况。

同样,我经常思考,我们对物理学中“优雅”理论的追求(包括一个脚趾)是否应该受到我们在理论模型选择中研究的同样强烈的适应性-简单性张力的影响,例如在贝叶斯机器学习中,正如我的问题希望说明的那样。

关于这个话题,我最近在通勤途中阅读了马克斯·泰格马克的《我们的数学世界》。这引发了我对数学宇宙假说的兴趣。一句话,这个假设很大程度上说明了所有可计算的数学结构都是存在的。这是一个强有力的断言,但我真的很喜欢这本书,并强烈推荐给任何对计算机科学和物理有广泛兴趣的人。

今天,我看到了下面的摘录。这是相信 Max 所说的终极系综 的一个很好的理由,也就是他提出的囊括我们所有物理现实的多节层级的最后一层。任何对为什么我们的宇宙似乎如此微调以及奥卡姆剃刀在 ML 和物理学中扮演的角色感兴趣的人可能会发现这很有启发性,如果不是令人信服的话(重点在我下面):

整个合奏往往比其中一个成员简单得多。使用算法信息内容的概念可以更正式地陈述这个原理。粗略地说,一个数字中的算法信息内容是将产生该数字作为输出的最短计算机程序的长度。

例如,考虑所有整数的集合。哪一个更简单,整套还是只有一个数字?你可能会天真地认为单个数字更简单,但整个集合可以由一个非常简单的计算机程序生成,而单个数字可能非常长。所以,整套其实更简单

(同理),更高层的多元宇宙更简单。从我们的宇宙到第一层多重宇宙消除了指定初始条件的需要,升级到第二层消除了指定物理常数的需要,第四层多重宇宙消除了指定任何东西的需要。

所有四个多重宇宙层次的一个共同特征是,最简单也可以说是最优雅的理论默认涉及平行宇宙。要否认这些宇宙的存在,我们需要加入实验上无法支持的过程和特别的假设,让理论变得复杂:有限空间、波函数坍缩和本体不对称。因此,我们的判断归结为我们发现哪个更浪费和不优雅:许多世界或许多单词。也许我们会逐渐习惯我们宇宙的怪异方式,并发现它的奇特是其魅力的一部分。

PiExa--> Raspberry Pi+Amazon Alexa:使用 Raspberry Pi 构建自己的免提 Alexa 的分步指南

原文:https://towardsdatascience.com/piexa-raspberry-pi-amazon-alexa-a-step-by-step-guide-to-build-your-own-hands-free-alexa-with-285c4bc73705?source=collection_archive---------3-----------------------

M otivation M onk:读日常没人读的东西,想日常没人想的东西。思想总是一致的一部分是不好的。

PiExa??我知道你们一定想知道这个作者在做什么,PiExa 是什么,为什么这个术语会和亚马逊 Alexa 和树莓 Pi 有关系。好了,我的读者朋友们,你们所有明确的问题、疑惑都将通过这篇文章的结尾得到解答。

目标:这篇文章是一步一步的全面指导,使用 Alexa 语音服务(AVS),用 Raspberry Pi 3 构建你自己的免提亚马逊 Alexa。通过这篇文章,我将演示如何使用 Java 示例应用程序(运行在 Raspberry Pi 上)、Node.js 服务器和第三方 wake word 引擎来访问和测试 AVS。所以,到这篇文章结束时,如果你跟着我,你可能会有你自己的手免费 Alexa 起来和你说话。

命名:我特意创造了“**PiExa”**这个术语,清楚地反映了树莓 Pi 与亚马逊 Alexa 的融合。

倒叙:几周前,当我为 Raspberry Pi 构建了自己的基于开源自然语言处理的语音助手Mycroft——Picroft时,我开始思考是否有可能使用 Raspberry Pi 制作自己的 Alexa,使用廉价的扬声器和通用串行总线(USB)麦克风,就像我构建 Picroft 一样。

我好奇的头脑和少量的谷歌搜索把我带到了 Alexa 知识库,它让我把我简单的想法变成了现实。

因此,没有任何进一步的欺骗,让我们开始一步一步地用 Raspberry Pi 3 构建自己的 Alexa。

硬件需求:

  1. 树莓 Pi 3 (推荐)或 Pi 2 Model B (支持)。
  2. 树莓派的微型 USB 电源线。
  3. 微型 SD 卡(最低 8 GB) —您需要一个操作系统才能开始使用。NOOBS(新的开箱即用软件)是一个易于使用的树莓 Pi 操作系统安装管理器。你可以很容易地下载并安装在你的 SD 卡上(查看这里)。
  4. USB 2.0 迷你麦克风 —树莓 Pi 没有内置麦克风;要与 Alexa 互动,你需要一个外部插件。
  5. 带 3.5 毫米音频线的外置扬声器。
  6. 一个 USB 键盘和鼠标,以及一个外部 HDMI 显示器。
  7. 互联网连接(以太网或 WiFi)

在你为这个项目收集所有的成分(硬件)之后,开始按照下面提到的步骤。

步骤 1:设置您的 Pi

N 注:除非您已经在 Pi 上安装了 Raspbian Stretch 或 Jessie,否则请遵循指南— 设置 Raspberry Pi ,该指南将引导您完成下载和安装 Raspberry Pi 以及连接硬件的过程(如果您不熟悉 Raspberry Pi,我强烈建议您遵循上面的指南,在继续下一步操作之前设置好 Pi 并做好准备)。

如果您已经在您的 Pi 上安装了 Raspbian Stretch Lite,那么您将需要安装 Java 以便启动并运行 Java 示例应用程序。只要您有互联网连接,就可以使用以下命令来实现:

sudo apt-get update
sudo apt-get install oracle-java8-jdk

第二步:注册一个亚马逊开发者账户

除非你已经有了一个,否则就去 developer.amazon.com创建一个免费的开发者账户。请务必在此处查看 AVS 条款和协议

步骤 3:创建设备和安全配置文件

按照这里的步骤注册您的产品并创建安全配置文件。

请注意以下参数。在下面的步骤 5 中,您将需要这些。

  • ProductID
  • ClientID,以及
  • ClientSecret

重要提示:确保在安全配置文件> Web 下设置了允许的来源和允许的返回 URL(参见创建设备和安全配置文件):

步骤 4:克隆示例应用程序

打开终端,并键入以下内容:

cd Desktop
# (Information: Currently the GitHub link is down due to some maintenance issue)git clone [https://github.com/alexa/alexa-avs-sample-app.git](https://github.com/alexa/alexa-avs-sample-app.git)

步骤 5:用您的凭据更新安装脚本

在运行安装脚本之前,您需要使用您在步骤 3 中获得的凭证来更新脚本— ProductIDClientIDClientSecret。在终端中键入以下内容:

cd ~/Desktop/alexa-avs-sample-app
nano automated_install.sh

粘贴从上面第 3 步中获得的ProductIDClientIDClientSecret的值。

更改应该如下所示:

  • ProductID="RaspberryPi3"
  • ClientID="amzn.xxxxx.xxxxxxxxx"
  • ClientSecret="4e8cb14xxxxxxxxxxxxxxxxxxxxxxxxxxxxx6b4f9"

键入 ctrl-X 和 Y,然后按 Enter 保存对文件的更改。

步骤 6:运行安装脚本

您现在可以运行安装脚本了。这将安装所有依赖项,包括 Sensory 和 KITT.AI 的两个唤醒词引擎。

注意:安装脚本将在运行脚本的文件夹中安装所有项目文件。

若要运行该脚本,请打开“终端”并导航到克隆项目的文件夹。然后运行以下命令:

cd ~/Desktop/alexa-avs-sample-app
. automated_install.sh

在继续之前,系统会提示您回答几个简单的问题,回答这些问题并完成所有必要的先决条件。

当向导启动时,完成整个过程需要 25-30 分钟,所以在此期间,你可以去喝杯茶或咖啡来打发时间。

第 7 步:运行你的网络服务,样本应用程序和唤醒词引擎

现在安装已经完成,您需要在三个独立的终端窗口中运行三个命令:

  1. 终端窗口 1:运行 web 服务进行授权
  2. 终端窗口 2:运行示例应用程序与 AVS 通信
  3. 终端窗口 3:运行唤醒词引擎,允许您使用短语“Alexa”开始互动。

注意:这些命令必须按顺序运行。

终端窗口 1

打开一个新的终端窗口,键入以下命令以打开用于授权 AVS 示例应用程序的 web 服务:

cd ~/Desktop/alexa-avs-sample-app/samples
cd companionService && npm start

服务器现在运行在端口 3000 上,您已经准备好启动客户端。

参见 API 概述>授权了解更多关于授权的信息。

让我们来看一下与窗口 2 相关的下几个步骤。

  1. 当你运行客户端时,会弹出一个窗口,显示一条消息

请在网络浏览器中访问以下 URL 并按照说明注册您的设备:https://localhost:3000/provision/d 340 f 629 BD 685 deeff 28 a 917。是否要在默认浏览器中自动打开该 URL?

单击“是”在默认浏览器中打开该 URL。

2.如果你用 Pixel desktop(和 Chromium 浏览器)运行 Raspbian,你可能会从浏览器得到一个警告。你可以通过点击高级->进入本地主机(不安全)来避开它。

3.你将被带到一个登录亚马逊网页。输入您的亚马逊凭证。

4.您将进入开发人员授权页面,确认您希望您的设备访问之前创建的安全配置文件。

单击确定。

5.您现在将被重定向到一个以https://localhost:3000/authresponse开头的 URL,后跟一个查询字符串。网页正文将显示设备令牌就绪。

6.返回到 Java 应用程序并单击 OK 按钮。客户端现在可以接受 Alexa 的请求了。

终端窗口 3

注意:跳过这一步,在没有唤醒词引擎的情况下运行相同的应用

这个项目支持两个第三方唤醒词引擎:Sensory 的 truly 免提和 KITT。艾的雪娃娃。-e参数用于选择代理,支持}的两个值:kitt_aisensory

打开一个新的终端窗口,使用以下命令从 Sensory 或 KITT.AI 调出唤醒词引擎。唤醒词引擎将允许您使用短语“Alexa”启动交互。

要使用感官唤醒词引擎,请键入-

cd ~/Desktop/alexa-avs-sample-app/samples
cd wakeWordAgent/src && ./wakeWordAgent -e sensory

或者,键入这个来使用 KITT。AI 的唤醒词引擎-

cd ~/Desktop/alexa-avs-sample-app/samples
cd wakeWordAgent/src && ./wakeWordAgent -e kitt_ai

现在你有一个工作免提 AVS 原型!

使用以下资源了解有关可用唤醒词引擎的更多信息:

第八步:和 Alexa 谈谈

你现在可以通过简单地使用唤醒词“Alexa”来与 Alexa 交谈。尝试以下方法-

说“Alexa”,然后等哔声。现在说“几点了?”

如果你愿意,你也可以点击“听”按钮,而不是使用唤醒词。在“听”按钮上点击一次,在释放点击之后,在开始讲话之前等待音频提示。可能需要一两秒钟才能听到音频提示。

步骤 9:如何注销示例应用程序

按照以下说明退出 AVS java 示例应用程序:

  1. 退出 AVS java 示例应用程序(CTRL + C)。
  2. 打开/samples/javaclient/config.json并清除您的sessionId。它应该是这样的:

"sessionId": ""

3.删除samples/companionService中的refresh_tokens文件。

下次登录时,系统会提示您进行身份验证。

演示时间

下面是有和没有唤醒词“Alexa”的视频,所以只要坐下来享受:

第 1 部分:没有唤醒词“Alexa”

https://www.youtube.com/watch?v=T1uyG9YNWbk(视频 1)

第 2 部分:用唤醒词“Alexa”

https://www.youtube.com/watch?v=a2XvL1L65tM(视频 2)

因为,现在你们都知道从上到下用 Raspberry pi 3 构建自己的免提亚马逊 Alexa 的每一步,使用 Alexa 语音服务(AVS)。因此,我想鼓励我所有的读者朋友、深度学习/机器学习实践者、爱好者和爱好者拿出你自己的带 Raspberry pi 3 的免提亚马逊 Alexa,并在上面发布 LinkedIn 或 twitter 帖子(** 但不要忘记给我加标签:)。我将急切地等待你的帖子。

参考资料:

  1. 要了解更多关于 Alexa 语音服务的信息,请点击这里
  2. 要了解更多关于语音助手的信息,请点击这里
  3. 我用来实现这个项目的库可以在这里找到。(信息:目前 GitHub 链接由于一些维护问题而关闭)

感谢您的关注

你利用你的时间阅读 T21,我的工作对我来说意味着一切。我完全是这个意思。

如果你喜欢这个故事,疯狂鼓掌吧👏 ) 按钮!这将有助于其他人找到我的工作。

还有,跟我上 LinkedinTwitter如果你想!我很乐意。****

改变您的硬件以在您的 PC 上实现更快的深度学习

原文:https://towardsdatascience.com/pimp-up-your-pc-for-machine-learning-d11f68c2815?source=collection_archive---------5-----------------------

为深度学习系列提升您的电脑——第 1 部分

诸如 TensorflowPytorchTheano认知工具包(CNTK) 等框架(以及与其一起工作的任何深度学习库,例如 Keras )允许在使用 GPU(图形处理单元)支持时进行比使用 CPU 快得多的深度学习训练。然而,对于那些框架可用的 GPU 支持,GPU 本身必须与 CUDA 工具包和任何额外需要的 GPU 加速库兼容,例如 cuDNN

目前 CUDA 兼容性仅限于Nvidia GPU。*因此,如果你有其他的 GPU 硬件(例如 AMD),你将不得不把它从你的电脑中换出来,并安装新的驱动软件。*这是我不得不为我的旧电脑做的事情,这篇文章将一步一步地指导你完成这个过程。

:因为我的 PC 安装了 64 位 Windows 10(至少目前如此),所以下面关于使用软件和卸载安装 GPU 驱动的说明都会参考 Windows 10。然而,由于我计划将这台电脑用于机器学习和其他编程项目,我将擦拭 Windows 并在其位置上安装 Linux Ubuntu 18.04 LTS(长期支持)——请关注此空间的未来帖子。

第一步:通过操作系统检查电脑上现有的显卡和驱动软件

升级电脑的第一步是检查你已经有的电脑。我的电脑是一台 Chillblast Fusion Inferno 2 游戏电脑,我最初是在 2016 年 1 月购买的。Chillblast Fusion 在主板上有一个 AMD 镭龙 R7 图形驱动程序(6595 MB 内存,VRAM 991 MB 和 5604 MB 共享内存)。

您可以使用 windows 上的“DirectX”诊断工具来检查这一点。你可以进入 Windows 开始菜单,输入“运行”,图 1 所示的窗口就会弹出。

Fig 1: Checking the onboard graphics card via DirectX diagnostic tool on Windows

如图 1 所示,键入“dxdiag ”, DirectX 诊断工具打开(图 2)。从这个工具中,我可以看到我有一个 AMD 镭龙 R7 图形处理器,它与 CUDA 不兼容。这证实了 GPU 升级的必要性。

Fig 2: DirectX Diagnostic Tool for checking system and display hardware

除了通过 Windows 进行检查,我认为在选择或订购新的 GPU 之前检查 PC 内部也很重要。这是为了确认,首先,什么插槽将可用于 GPU,其次,任何可用的电源。许多 GPU 需要自己的冷却系统,因此需要使用电源设备。这在步骤 2 中执行。

第二步:在选择新的 GPU 之前,先看看你的电脑内部

上面已经提到,一个新的 GPU 安装需要你的主板上有一个可用的插槽;这是一个 PCI express (PCIe)插槽。打开电脑,确认有一个插槽可用于安装 GPU。图 3 显示了我的电脑。

Fig 3: Motherboard with empty PCI Express slot and clip available for the new GPU

除了主板上的插槽要求之外,大多数 Nvidia GPUs 都需要专用电源来冷却。打开电脑外壳有助于检查已有的电源(如果没有电源,可订购一个额外的电源)。

我的电脑中可用的电源是 500 W(见图 4)。它还有一根备用电缆,其中一根有一个 6 针连接器。电缆未被使用,被塞在 PC 机箱的角落里,6 路引脚可以连接到 GPU 插座,为 it 提供冷却所需的电力。

Fig 4: Inside the Chillblast PC — showing 500 W power supply and spare 6-way pin which will be able to provide power to the GPU when installed

第三步:选择一个新的 Nvidia 兼容的 GPU

GTX 1000 系列中的大多数卡需要一个单独的电源单元(PSU),尽管 GTX 1050 Ti 具有不需要来自 PSU 的额外电源连接器的优势,因此如果您不想购买额外的硬件,这是一个不错的入门级选择。我选择了 EVGA Geforce GTX 1060 6GB,这被认为是一个具有成本效益的入门解决方案。这里有一个关于各种 Nvidia GPU 选项的很好的讨论。

Fig 5: My new Nvidia compatible GTX 1060 graphics card by EVGA

查看 Geforce GTX 1060 GPU 的硬件要求:

  • 显卡所需功率为 120 W
  • 推荐的 PSU(电源装置)最低为 400W
  • GPU 的电源连接是来自 PSU 的 6 针连接器

之前在步骤 2 中对我的电脑内部进行的检查表明,我已经拥有的 500 W 电源足够了,由于电源也有一个可用的 6 针连接器,我拥有连接 Geforce GTX 1060 GPU 所需的一切。

步骤 4:卸载旧 GPU 的驱动程序

为了删除下载的软件,最好使用显示驱动卸载程序(“DDU”)。我用的是Wagnardsoft;这是免费软件,但是开发者会感谢捐赠。DDU 软件建议您在删除驱动程序时将电脑重启至安全模式。一旦你在安全模式下重启(在 Windows 10 上有很多方法可以做到这一点),转到你下载 DDU 软件的文件夹,右击显示驱动卸载程序(它有文件类型:应用程序),图 4 中的窗口就会出现。

Fig 4: Display Driver Uninstaller (DDU) software detecting and uninstalling the AMD graphics driver on my PC

在图 4 所示的 DDU 选项中,最好的选择是“清理并重启(强烈推荐)”——这样在删除驱动程序时,您至少可以检查您的机器是否再次启动。图 4 所示的“清理并关闭(用于安装新显卡)”选项可能听起来更适用于这种情况,但它并不像您在重启时无法检查 PC 那样有用。

步骤 5:安装新的 GPU 硬件

我不得不移除机箱后面的两个面板,以便 GPU 可以放进去;这在图 5 中示出。一旦安装了 GPU,就可以从电脑机箱的背面直接接触到它的连接插槽。

Fig 5: GPU installation — removal of 2 slots from the side of the PC case at the back to enable the GPU to fit. The GPU’s socket (HDMI and DVI) connections are then accessible from the back of the computer via those slots

当 GTX 1060 GPU 作为新品到达时,它在要插入 PCIe 插槽的引脚上有一个保护性的黑色橡胶盖。首先从引脚上取下保护盖。握住 GPU 的风扇一侧(即印刷电路板的另一侧),小心避免静电放电,在触摸 GPU 之前,触摸大型金属物体(如计算机机箱)可能会损坏 GPU。将 GPU 推到 PCIe 插槽上;您应该会感觉到 PCIe 插槽夹卡嗒一声卡住了 GPU。图 6 显示了我的电脑的最终设置。

Fig 6: Nvidia GPU pushed and clipped into the PCIe slot; the GPU power socket are shown (top) and the screw hole where the GPU can be attached securely to the PC housing is also shown (bottom)

一旦 GPU 已经安全地插入到 PCIe 插槽中,将 500 W 电源的 6 针电源插入到 GPU 单元的顶部。GPU 上的电源插座如图 6(顶部)所示,插上电源的 GPU 如图 7(底部)所示。

此外,它有一个 GPU 的螺丝附件;这可用于将其牢固地拧到电脑机箱上,如图 7(顶部)所示。

Fig 7: Installed GPU screwed to case and with the 500 W power supply now plugged in

既然 GPU 已经固定到位,请在外壳一侧关闭的情况下启动计算机,以确保 GPU 上的风扇正在旋转。当你很高兴你的 GPU 布线整齐存放,风扇正在运行,你可以关闭你的电脑外壳。

连接电脑显示器的注意事项

在安装 GPU 之前,我的显卡通过插入主板的 HDMI 电缆连接到我的 PC 显示器上;参见图 8 中的 HDMI 插座(主板)标签)。安装 GPU 时,它带有几个连接,包括自己的 HDMI 和 DVI 插座(在图 8 中分别标记为“HDMI 插座(GPU)”和“DVI 插座(GPU)”。当电脑仍然关闭时,我从主板上拔下 HDMI 电缆,并将其插入 GPU。然后我打开电脑,它重新启动进入 windows。如果在打开和启动之前没有将显示器连接器(HDMI 或 DVI)从主板插座切换到 GPU 插座,尽管您的计算机启动了,但您的显示器仍会出现黑屏。您的电脑现在可以在启动时识别 GPU,默认显示输出从主板切换到新的 GPU。

Fig 8: The back of the computer case showing existing (motherboard) and new (GPU) DVI and HDMI sockets respectively

终于把你的电脑组装好了,是时候为你的新 GPU 安装驱动程序了。

第六步:为你的新 GPU 获取驱动软件

如果你购买了新的 Nvidia GPU 驱动程序,会附带一张驱动程序光盘,但是,当你得到它时,它可能已经过时了。另一种选择(也可能是更好的选择)是直接从 Nvidia 网站这里下载驱动软件。Geforce GTX 1060 驱动程序软件被列为 Geforce 10 系列的一部分,如图 9 所示。

Fig. 9: Downloading the Geforce GTX 1060 driver software from the Nvidia site

选择图 9 中的选项并点击“搜索”会将您带到图 10 所示的下载页面。

Fig 10: Driver download for the GTX 1060

下载并运行软件后,您将看到图 11 中的消息,提示您提取并安装 Nvidia 软件。

Fig 11: Downloading and installing Nvidia display driver software

故障排除说明

一旦我按照上面的安装过程,包括 Nvidia 显示驱动程序软件,我发现我的电脑没有立即检测到我的新 Nvidia GPU。我试图解决这个问题的一个方法是“关机再开机”——简单的重启。这对我很有效。但是,如果您发现您的系统无法检测到您的新 GPU,我发现下面的链接是一个有用的资源,可以帮助您诊断为什么会出现这种情况。

[## 完全修复:在 Windows 10、8.1 和 7 上检测不到 Nvidia 显卡

您的图形卡是电脑上最重要的组件之一。然而,许多用户反映英伟达…

windowsreport.com](https://windowsreport.com/nvidia-graphics-card-windows-10/)

步骤 7:在 Windows 中检查 GPU 安装

当你的 GPU 安装最终被识别时,它应该会以一些形式出现在 Windows 上。首先,您应该能够在“设备管理器”中看到它(如图 12 所示)。

请注意,我禁用了微软基本显示适配器(也列在图 12 中),因为它显示了一个错误,从我删除旧的 AMD 驱动程序时开始;在任何情况下,我都不需要 microsoft basic 显示适配器。

Fig 12: Windows 10 device manager showing display adapters (including new NVIDA GeForce card); I have disabled the Microsoft Basic Display Adapter

在 Windows 任务管理器中,您的新 GPU 也应该作为附加 GPU 列出。从图 13 可以看出,我的原始 GPU——“GPU 0”被列为 AMD 镭龙(TM) R7 图形,而新的 GPU——“GPU 1”现在是 Nvidia GeForce GTX 1060 6GB。

Fig 13: Windows task manager showing the new GPU 1 Nvidia GeForce GTX 1060 6GB

结论

本文介绍了如何检查当前计算机是否适合 GPU 升级,以及如何在计算机中安装新的 GPU 和驱动程序。该系列的下一步将是 CUDA 和 CUDnn 的安装,因为在将深度学习框架与 GPU 支持(如 Tensorflow、Pytorch 等)放在一起之前需要这些。

这篇文章也发表在这里https://schoolforengineering.com上。

Pinterest 的视觉镜头:计算机视觉如何探索你的品味

原文:https://towardsdatascience.com/pinterests-visual-lens-how-computer-vision-explores-your-taste-5470f87502ad?source=collection_archive---------7-----------------------

个性化视觉推荐背后的科学

当谈到寻找你想尝试的东西时——一个新的沙拉食谱,一件新的优雅服装,一把客厅的新椅子——你真的需要先看看它。人类是视觉动物。我们用眼睛来决定某样东西是否好看,或者是否符合我们的风格。

我是 Pinterest 的超级粉丝,尤其是它的视觉镜头。为什么?它让我发现让我感兴趣的事物,并让我深入其中。当我在世界上发现一些看起来有趣的东西,但当我稍后试图在网上搜索它时,我说不出话来。我脑海中有这个丰富多彩的画面,但我无法翻译成我需要找到它的文字。Pinterest 的视觉镜头是一种发现想法的方式,而不必先找到合适的词来描述它们。

只需将镜头对准一双鞋,然后点击查看相关的风格,甚至是搭配什么的想法。或者在桌子上试一试,寻找相似的设计,甚至是同一时代的其他家具。也可以用镜头配食物。只要把它指向花椰菜或土豆,看看会出现什么食谱。图案和颜色也可以引导你走向有趣的方向,甚至是怪异的新方向。

那么 Pinterest 是如何通过视觉搜索并为用户提供个性化视觉推荐的呢?经过两周对该公司的工程博客和媒体曝光的挖掘,我很感激终于得以一窥幕后。事实证明,该产品是 Pinterest 的机器学习应用程序的一个实例,这些应用程序广泛应用于各种商业领域。让我们缩小一下,看看机器学习在 Pinterest 是如何使用的。

Pinterest 使用机器学习的概述

作为一个视觉发现引擎,Pinterest 有许多具有挑战性的问题,这些问题可以使用机器学习技术来解决:

  • 我们应该向新用户推荐什么样的兴趣?
  • 如何产生引人入胜的主页反馈?
  • 引脚之间是如何关联的?
  • 一根针属于什么利益?

关键时刻发生在 2015 年 1 月,Pinterest 收购了Kosei——一家擅长推荐系统的机器学习初创公司。从那时起,机器学习已经在多个领域跨 Pinterest 使用:从提供推荐、相关内容和预测一个人将内容锁定的可能性的发现团队;成长团队使用智能模型来确定发送哪些电子邮件,并防止流失;来自做广告表现和相关性预测的货币化团队;给用 Spark 构建实时分布式机器学习系统的数据团队。

让我们更深入地了解一下 Pinterest 的工程师们是如何利用机器学习来保持该网站 1.75 亿多用户的锁定和共享的:

  • **识别视觉相似性:**机器学习不仅可以确定图像的主体,它还可以识别视觉模式,并将其与其他照片进行匹配。Pinterest 使用这项技术每月处理 1.5 亿次图像搜索,帮助用户找到看起来像他们已经上传的图片的内容。
  • **分类和管理:**如果用户锁定了一张上世纪中期的餐桌,该平台现在可以提供同一时代其他物品的建议。钥匙?元数据,如发布图片的公告板和网站的名称,有助于平台理解照片代表了什么。
  • **预测参与度:**虽然许多平台优先考虑用户朋友和联系人的内容,但 Pinterest 更关注个人的品味和习惯——他们在什么时候发布了什么——这使得该网站能够提供更多个性化的推荐。
  • 优先考虑本地口味: Pinterest 是一个日益全球化的平台,超过一半的用户位于美国以外。它的推荐引擎已经学会用用户的母语推荐他们当地的热门内容。
  • 超越图片:分析照片中的内容是网站推荐的一个重要因素,但它并不能提供全部信息。Pinterest 还会查看以前固定内容的标题,以及哪些项目被固定在同一个虚拟板上。举例来说,这使得 Pinterest 可以将一件特定的衣服与经常钉在旁边的一双鞋子联系起来,即使它们看起来一点也不像。

Pinterest Lens 是识别视觉相似性的努力的一部分,还有许多其他工程作品。它们都在一个不断发展的领域中利用机器学习算法和技术,这个领域称为计算机视觉,我将在下面深入解释。

Pinterest 的计算机视觉简史

计算机视觉是计算机科学的一个领域,也是机器学习的一个子领域,致力于使计算机能够像人类视觉一样看到、识别和处理图像,然后提供适当的输出。这就像把人类的智慧和本能传授给计算机。Pinterest 大量使用计算机视觉来支持他们的视觉发现产品。

Pinterest 在 2014 年将目光投向了视觉搜索。那一年,该公司收购了一家图像识别初创公司 VisualGraph ,并与一小群工程师一起建立了其计算机视觉团队,并开始展示其工作。

2015 年,它推出了 视觉搜索 **,**一种无需文字查询的搜索创意的方式。第一次,视觉搜索给了人们一种方法来获得结果,即使他们找不到合适的词来描述他们正在寻找的东西。

2016 年夏天,随着 Pinterest 推出 对象检测 ,视觉搜索得到了发展,它可以实时找到一个大头针图像中的所有对象,并提供相关结果。此后,视觉搜索成为其最常用的功能之一,每月有数亿次视觉搜索,检测到数十亿个物体。

2017 年初,它在视觉发现基础架构上推出了 3 款新产品:

  • Pinterest Lens 是一种通过手机摄像头发现创意的方式,其灵感来自用户看到的周围世界。
  • 购物外观是一种购物和购买用户在胸针内看到的产品的方式。
  • 即时创意是一种只需轻轻一点,就可以用类似的创意改变用户主页内容的方式。

最近大约 2 个月前,它宣布了为用户寻找产品和想法的更多方法:

  • Lens Your Look 是从你的衣柜和 Pinterest Lens 的下一个重大步骤中获得灵感的一种新方法。
  • 响应式视觉搜索是一种通过放大大头针对象来搜索图像的无缝沉浸式方法。
  • Pinterest Pincodes ,你只需拿出 Pinterest 相机,扫描任何 Pincode,就能看到 Pinterest 上的策划创意,灵感来自你在现实世界中看到的东西。

让我们更深入地挖掘 Pinterest 工程师在 Pinterest Lens 背后用于视觉发现工作的计算机视觉模型。

Pinterest 镜头如何工作

1 —镜头架构:

Lens 将 Pinterest 对图像和对象的理解与其发现技术相结合,为 Pinners 提供了一系列不同的结果。例如,如果你拍了一张蓝莓的照片,Lens 不只是返回蓝莓:它还会给你更多的结果,如蓝莓烤饼和冰沙的食谱,排毒磨砂等美容想法或种植自己的蓝莓灌木的技巧。

为此,Lens 的整体架构分为两个逻辑组件。

  1. 第一个组件是一个查询理解层,在这里 Pinterest 导出关于给定输入图像的信息。在这里,Pinterest 计算视觉特征,如检测物体,计算突出的颜色,检测照明和图像质量条件。使用视觉特征,它还计算语义特征,例如注释和类别。
  2. 第二个组件是 Pinterest 的混合器,因为 Lens 返回的结果来自多个来源。Pinterest 使用视觉搜索技术返回视觉上相似的结果,使用对象搜索技术返回具有视觉上相似的对象的场景或项目,使用图像搜索返回与输入图像语义上(非视觉上)相关的个性化文本搜索结果。混合器的工作是根据查询理解层中获得的信息动态地改变混合比率和结果源。

如上所示,镜头结果在视觉上并不严格相似,它们来自多个来源,其中一些仅在语义上与输入图像相关。通过为 Pinners 提供视觉相似之外的结果,Lens 是一种新型的视觉发现工具,它将现实世界的相机图像与 Pinterest 味觉图联系起来。

让我们继续分析 Lens 混合组件,包括图像、对象和视觉搜索。

2 —图像搜索:

Pinterest 的图像搜索技术可以追溯到 2015 年,当时该公司分享了一份白皮书,详细介绍了其系统架构和从实验中获得的见解,以建立一个可扩展的机器视觉管道。Pinterest 使用基准数据集和 A/B 测试的组合对两个 Pinterest 应用程序、相关 pin 和一个具有相似外观的实验进行了一系列全面的实验。

特别是,相似外观的实验允许 Pinterest 根据大头针图像中的特定对象显示视觉上相似的大头针推荐。它尝试了不同的方法来使用表面对象识别,这将使 Pinner 点击到对象。然后,它使用对象识别从大头针的图像中检测出包、鞋和裙子等产品。从这些检测到的对象中,它提取视觉特征来生成产品推荐(“相似的外观”)。在最初的实验中,如果针中的物体上有一个红点,Pinner 就会发现建议。点击红点会载入一系列视觉上相似的物品。

3 —视觉搜索:

当 Pinterest 在 2016 年为 Pinterest 上最受欢迎的类别引入自动对象检测时,视觉搜索得到了显著改善,因此人们可以在一个大头针的图像内视觉搜索产品。

由于一张图片可以包含几十个对象,Pinterest 的动机是尽可能简单地从其中任何一个开始发现体验。与自动完成改善文本搜索体验的方式相同,自动对象检测使视觉搜索体验更加无缝。视觉搜索中的对象检测也启用了新功能,如对象对对象匹配。例如,假设你在 Pinterest 或朋友家里发现了一张你喜欢的咖啡桌,很快你就能看到它在许多不同的家居环境中会是什么样子。

Pinterest 在构建自动对象检测方面的第一个挑战是收集图像中感兴趣区域的标记边界框作为我们的训练数据。自推出以来,它已经处理了近 10 亿个图像作物(视觉搜索)。通过在数百万张参与度最高的图片中聚合这种活动,它可以了解 Pinners 对哪些对象感兴趣。它将视觉上相似的结果的注释聚合到每个裁剪中,并在数百个对象类别中分配一个弱标签。下面的热图显示了这种情况的一个示例,其中形成了两个用户裁剪聚类,一个围绕“围巾”标注,另一个围绕“包”标注。

由于 Pinterest 的视觉搜索引擎可以使用任何图像作为查询——包括网络上看不见的内容,甚至是你的相机——检测必须实时进行,在几分之一秒内。Pinterest 广泛试验的最广泛使用的检测模型之一是 更快的 R-CNN ,它使用深度网络在两个主要步骤中检测图像中的对象。

首先,它通过在输入图像上运行完全卷积网络来产生特征图,从而识别图像中可能包含感兴趣对象的区域。对于特征图上的每个位置,网络考虑一组固定的区域,这些区域的大小和长宽比不同,并使用二进制 softmax 分类器来确定每个区域包含感兴趣对象的可能性。如果找到一个有希望的区域,网络还输出对该区域的调整,以便它更好地框住对象。

一旦网络发现了感兴趣的区域,它就检查最有希望的区域,并试图将每个区域识别为特定类别的对象,或者如果没有发现对象,就丢弃它。对于每个候选区域,网络在卷积特征图的相应部分上执行空间汇集,从而产生具有固定大小的特征向量,而与区域的大小无关。该汇集的特征然后被用作检测网络的输入,该检测网络使用 softmax 分类器来将每个区域识别为背景或我们的对象类别之一。如果检测到对象,网络再次输出对区域边界的调整,以进一步改进检测质量。最后,对检测执行一轮非最大值抑制(NMS ),以过滤掉任何重复的检测,并将结果呈现给用户。

4 —对象搜索:

传统上,视觉搜索系统将整个图像视为一个单元。这些系统索引全局图像表示以返回与给定输入图像整体相似的图像。随着深度学习的进步带来了更好的图像表示,视觉搜索系统达到了前所未有的精确度。然而,Pinterest 希望推动视觉搜索技术的界限,超越以整个图像为单位的界限。通过利用其数十亿对象的语料库,结合其实时对象检测器,Pinterest 可以在更细粒度的水平上理解图像。现在,它知道其图像语料库中数十亿个对象的位置和语义。

物体搜索是以物体为单位的视觉搜索系统。给定一张输入图像,Pinterest 在几分之一秒内从数十亿张图像中找到视觉上最相似的对象,将这些对象映射到原始图像,并返回包含相似对象的场景。

Pinterest 视觉发现的未来

在一个每个人口袋里都有相机的世界里,许多专家认为,视觉搜索——拍照而不是通过文本查询进行搜索——将成为我们查找信息的事实方式。

Pinterest 坐拥可能是世界上最干净、最大的数据集来训练计算机看图像——这相当于一个隐藏着核军备的小国。这是数十亿张家具、食物和服装的照片,多年来一直由 Pinterest 的用户手工标注。

在 Pinterest,用户可以随意浏览“美好生活”,从非常不具体的查询开始,比如“晚餐创意”或“时尚”,他们可能会一周又一周地反复搜索。由于这种行为和网站照片大头针的网格布局,Pinterest 可以在其平台中建立视觉搜索,而不是提供一个完美的答案,而是一个不完美的灵感集合。

据 Pinterest 的首席执行官本·希伯尔曼称,该公司正在用计算机视觉做三件事。他们试图了解产品或服务的美学品质,这样他们就能提供更好的建议。他们希望能够看到包含多个项目的图像内部,放大其中的一部分,然后通过计算说,“嘿,就是这种类型的对象。你可以在这里找到类似的东西。”然后,最终,他们想让相机工具,你可以查询你周围的世界。计算机视觉是驱动这三者的基础技术。

最后一次外卖

Pinterest 有一个指导他们计算机视觉工作的基本原则:帮助人们发现和做他们喜欢的事情。视觉是一个罕见的、未被封闭的空间。文字分享?这个象限属于脸书和推特。视觉分享?脸书、Instagram 和 Snapchat。搜索文本?那就是谷歌和必应。但是通过视觉搜索呢?Pinterest 似乎在引领潮流。

我希望这是有益的,并像它一样激起你的好奇心。目前,我将通过我自己的 Pinterest 镜头工作,发现我新喜欢的对象,了解并欣赏所有在幕后进行的计算机视觉。

— —

如果你喜欢这首曲子,我希望你能按下鼓掌按钮👏这样别人可能会偶然发现它。你可以在 GitHub 上找到我自己的代码,在【https://jameskle.com/】上找到更多我的写作和项目。也可以在 推特 上关注我直接发邮件给我 或者 在 LinkedIn 上找我。

其他来源:

向商务人士推销人工智能

原文:https://towardsdatascience.com/pitching-artificial-intelligence-to-business-people-f8ddd8fb2da2?source=collection_archive---------12-----------------------

从银弹综合症到一线希望

在这篇文章中,我计划与你分享我们最近向商界人士推销人工智能的经验,以及我们在这一过程中吸取的教训。

作为一家人工智能专家的小公司,我们遵循认知营销方法。我们不是仅仅依赖一个营销渠道,而是参加像多伦多机器学习峰会这样的会议。虽然这是一个很好的方式来满足上升的人才,并产生线索和压力,在线游戏也很重要。

Sam and I manned the booth @ TMLS. Special thanks to Dave Scharbach for continuing to exceed expectations on organizing the 1K person annual event.

我们已经为企业客户提供人工智能咨询近 3 年了,几个月前,我们认为几个简短的营销视频是与世界分享我们所做事情的好方法。

事实证明,我们有很多东西要了解商业人士在观看视频时是如何误解人工智能技术的当前能力的。我们的内容营销方法在博客和 LinkedIn 上效果很好,但是视频营销的效果不佳。让我们来谈谈哪里出了问题,以及我们做了什么来修复它。

我们开始将我们的能力提炼成一些有趣的片段(见下文),向决策者展示我们在做什么,以及为什么这对他们很重要。第一步是建立概念:展示人工智能的各种应用,以暗示我们的专业知识。

以下是我们想要传达的 6 条关键信息:

  • **适应或者死亡:**不采用 AI 的人会被采用 AI 的竞争对手和新人吹走
  • **AI 分析的文档:**目前由人类执行的文档处理解决方案的自动化。更一般地说,业务流程自动化
  • **我们的人工智能开发能力:**一般来说,定位我们,说我们为企业客户做人工智能的事情
  • **释放数据的价值:**通过创建人工智能系统来提高收入、质量和成本等关键绩效指标,从而实现数据货币化
  • **边缘计算:**将你的 ML 模型部署到移动应用中,这样你就不需要海量的 GPU 能力来做推理了
  • **人工智能真正的样子:**在 tensorboard 中显示嵌入向量,因为它很酷

愿景对我们来说似乎很清晰,我们直接投入了生产。

银弹综合症——严酷的现实考验

我们对我们的新视频内容感到非常自豪,我们计划并在 LinkedIn 上发布我们的视频,但令我们惊讶的是,我们获得了很多浏览量,却很少有线索。总之,这些线索并没有改变我们人工智能产品和服务的销售。

在跳到解决方案之前,让我们先看一下我们创建的内容,让您对这个问题有个大概的了解。以下播放列表包含 10 个预告视频。花点时间看看这些短片,想想一个没有 AI 背景的 CxO 的反应,或者它是如何工作的。以下是预告视频的播放列表:

A playlist of 10 teaser videos advertising our AI services.

一旦我们了解到活动进展不顺利,我们就从广告上退一步来评估哪里出了问题。

发生的情况是,我们的“决策者”客户在 C-suite 职位上对内容做出了我们没有预料到的假设。当我们展示一个人工智能生成艺术的例子时,我们的观众认为我们有一个只进行人工智能艺术生成的产品。更狭隘的是,他们认为我们只制作日本动漫艺术。我们试图展示专业知识,但却被解释为产品特性和功能的狭窄范围。我们的目标客户认为我们在销售视频中的应用程序,而不是制作应用程序所需的功能,这是我们的错误。

问题:我们试图展示专业知识,但却被解释为产品特性和功能的狭隘范围。

有过这种经历后,我喜欢用一个类比来说明,潜在客户认为刀切肉的视频告诉他们,我们卖的刀只切肉。然而,我们卖切蔬菜、手指、费用和时间的刀。我们的结论是,为了解释先进的人工智能能力,需要更长更深入的内容。观看上面的视频,回想起来,你会发现理解一个复杂主题的短视频中的信息是多么困难。

一线希望——我们发现并修复了问题

那么,有哪些有效内容的例子

基本上是长格式内容,高制作价值的真实媒体机会。以下是我们点击的 4 个内容示例。双关语。我选择了 4 个不同的人工智能项目来表明,推介人工智能更多的是关于价值信息,而不是人工智能本身。

详细内容:在 VanillaSoft 为 Lemay.ai 举办的人工智能网络研讨会

This one hour long webinar on AI led to a bunch of leads and conversations that we did not see from the teaser videos.

在我们的一个客户那里举行的网上研讨会是一个友好的场所,在现场观众的参与下,讨论了我对行业发展的看法。我去年曾指出,由于缺乏数据科学家,小公司比大公司更糟糕,现在我们已经成长,行业也成熟了,我觉得是时候重新讨论人工智能咨询业务的发展了。我们获得了很好的注册人数(约 150),这些人数转化成了潜在客户,然后我们还从在线观看内容的人那里获得了后续联系。

解说视频: Stallion.ai 文档理解介绍

Stallion.ai document understanding intro video (2 minutes instead of 13 seconds). Stallion.ai is our venture in the UAE, serving the MENA region.

一旦我们理解了短视频的问题所在,我们就能在视频制作中获得更多的细节。这段讲解文档处理的视频介绍了问题、解决方案、价值主张以及解决方案的一般性。新视频并没有展示一个飞过的演示,而是希望观众能明白其中的意思,而是清楚地展示了这项技术的能力,以及价值得以实现的原因。

高级别介绍:内部审计人工智能 AuditMap.ai

AuditMap.ai intro video on making sense of internal reports with AI. It is one minute long.

在这个视频中,我们决定不显示用户界面,因为它会随着我们为客户添加新功能而不断变化。我们实际上是在上述 10 个预告剪辑之前开发了这个审计图介绍视频。在播放这个视频后,我们一直在问一个主要问题,那就是“我能看看演示吗?”我对这个问题没有问题,因为我们为大约 1 小时的演示保留了好的内容。AuditMap 非常复杂,我们不想在与客户(通常在银行业)实际交谈之前展示太多内容,以便在电话直播中解决他们的问题。

激发用例:investifai.com人工智能资产管理简介

3 minute intro video to investifai

它需要大量的内部审议和客户互动,以找出什么样的信息对投资者有效。他们是与我们通常的决策者客户完全不同的细分市场。我们必须非常简单地强调关键点:人工智能不是情绪化的。没有计算机,投资组合管理对人类来说太复杂了。在这个周期结束的时间点,风险调整后的回报是必不可少的,市场变得越来越可怕,将资金投入一个资产类别不是一个明智的选择。

到目前为止,这个视频的反馈是积极的。

结论

在这篇文章中,我开始给你一个快速回顾我们在营销我们的人工智能开发能力和解决方案的道路上的坎坷。我们发现,为了解释这些人工智能能力,需要更长的内容。不管底层技术如何,内容需要向观众推销为什么解决方案更好,而不是为什么解决方案更酷。

如果你喜欢这篇文章,那就看看我过去读过最多的文章,比如“如何给人工智能项目定价”和“如何聘请人工智能顾问”我还准备了一些关于寻求采用机器学习的公司所面临的其他问题的文章,比如“没有云和 API 的机器学习

下次见!

丹尼尔

您可能喜欢的其他文章:

张量流批量范数的缺陷和训练网络的健全性检验

原文:https://towardsdatascience.com/pitfalls-of-batch-norm-in-tensorflow-and-sanity-checks-for-training-networks-e86c207548c8?source=collection_archive---------2-----------------------

在这篇文章中,我将写下我们在编写深度学习模型和一些健全性检查时犯的错误,这将帮助你缩小小守护进程的范围,并挽救你的夜晚睡眠。

I .让我们一劳永逸地完成 TensorFlow 中的批量定额

批量标准化的简要理论

这项革命性的技术是由 Sergey Ioffe,Christian Szegedy 在论文 中介绍的,到目前为止被引用了 4994 次。根据该论文,批量标准化减少了内部协方差移动,即,它使得网络中各层的学习更加相互独立。批量范数层的目标是向激活层输入,单位高斯,使得神经元在 sigmoid 和 tanh 的情况下不会饱和。它有助于网络的快速收敛,允许你不用关心权重的初始化,作为正则化来代替丢失和其他正则化技术。现在我不会讨论太多的理论细节,而是更多地讨论实现。我将带您了解 TensorFlow 及其数学中批处理规范的实现。
在训练的时候-

At training time. Images taken from Batch Normalization paper.

现在假设卷积层和激活层之间使用批量范数层,那么 x 是卷积层的输出, y 是批量范数层的输出,输入到激活层,可能是 ReLU,sigmoid 等。批量定额层学习参数 γβy 取决于它们的值。因此,示出了使用 γβ 来学习 x 的最佳表示。请注意另外两个统计量,即***【x】Var【x】***、总体均值和方差。它们是通过训练期间的移动均值和移动方差来估计的。

在推断的时候-

At inference time

推理时向前通过批范数层与训练时不同。在推断时,我们不用批均值()和方差(【σ2*)而是用总体均值(e【x】)和方差(var【x】)来计算 x^ 。假设您在推断过程中给定批量大小为 1 的批,并使用批均值和批方差进行归一化,在这种情况下,μ=x 然后 y=β ,这表明层输出(y)对于任何输入 ( )因此,为了在推断时进行标准化,我们使用总体均值和方差,这是我们在训练期间使用移动均值和方差计算的。在下一节中,我们将介绍 TensorFlow 中批处理规范的实现。*

TF 中批量定额的注意事项

  • 移动平均值和方差不更新: 张量流是基于图形的,计算按依赖关系的顺序进行。
**import tensorflow as tfa = tf.placeholder(tf.float32, shape=[1,3])
b = tf.placeholder(tf.float32, shape=[1,3])
c = tf.Variable(tf.zeros([1, 3]), dtype=tf.float32) def train(a,b):
    c = tf.add(c,a)
    e = some_train_op(a,b)
    return eoutput = train(a,b)
loss = tf.log(output)sess = tf.Session()
saver = tf.train.Saver()
sess.run(tf.global_variables_initializer())for itr in range(1000):
    ls = sess.run(loss, {a:x, b:y})saver.save(sess, some_path)#Note that this code is for reference only.** 

现在,在此我们运行 损失 张量在每次迭代中,对于每次迭代 列车 函数都会被调用。 c 是一个变量,对所有迭代的 a 的值求和。因此,当我们保存模型时,我们期望变量 c 等于在每次迭代中传递给占位符的所有值的总和。

让我们详细分析一下,这个模型的图中的依赖关系。当我们运行 损失 张量, 输出 将被计算然后 输出 将调用 列车e 中需要哪个值,将使用b 来计算在所有这些计算中 c 根本不会被计算为 损失 张量的值不依赖于 c 。解决方法是在计算*e 之前加上 c 作为依赖。因此,解决方案***

**def train(a,b):
    c = tf.add(c,a)
    with tf.control_dependencies([c]):
        e = some_train_op(a,b)
    return e**

在训练网络时,我们调用优化器 op 来完成所有计算并更新所有权重,但是优化器 op 从不依赖于移动平均值或方差的计算。因此,移动平均值和方差永远不会更新,而是保持其初始值。

解决方案:TensorFlow 为批量规范化提供了三个主要函数

****tf.nn.batch_normalization()** - Never use this for training, it just compute the y = gamma*x^hat + beta where x^hat = (x-mean)/std_dev.
It doesn't account for keeping moving mean and variance. **tf.layers.batch_normalization()** -This function can be used for your model. Note: Always add batch norm dependency when using this, either on optimizer op or any other op which you sure that will execute when optimizer op is run. ex:-update_ops = tf.get_collection(tf.GraphKeys.UPDATE_OPS)                            with tf.control_dependencies(update_ops):                                                            
    self.solver = tf.train.AdamOptimizer(learning_rate=1e-04) 
                  .minimize(self.loss)Here tf.GraphKeys.UPDATE_OPS is the collections which have moving mean and variance op. **tf.contrib.layers.batch_norm()** - This function is in contrib module of TensorFlow. This function gives two ways to add dependencies as follows:
1.It has '*update*' parameter, set *update=None* while calling the function and dependency will be added inside the function itself and you don't have to anything else.
**Note:This is believed to be slow in comparison to the next method.**2\. Let the *update* parameter have it's default value which is "*tf.GraphKeys.UPDATE_OPS*". Now here also you have to manually add dependency as above with tf.layers.batch_normalization().**

因此,您可以使用TF . layers . batch _ normalization()或 TF . contrib . layers . batch _ norm()进行适当的更新依赖处理。

  • 训练和测试时的不同用法:
    从训练到测试时,我们要在批均值和方差或者总体均值和方差之间切换。我们在 tf.contrib.layers.batch_norm()和 tf.nn.batch_normalization()中分别有参数is_trainingtraining 。当其值为True时,使用批均值&方差并更新移动均值和方差来估计总体均值和方差。在False上,使用总体均值和方差。因此你应该为此使用一个占位符train_phase。因此,解决方案如下所示
**def Bn(x, **is_train**):
        return tf.contrib.layers.batch_norm(x, decay= 0.99,                                                                                                               
          ***is_training=is_train***,center= True, scale=True, 
          reuse= False)*train_phase = tf.placeholder(tf.bool, name="is_training")*
data = tf.placeholder(tf.float32, shape=[None,240,240,3],                                                                                                        name="Image") bn_layer = Bn(data, train_phase)loss = some_loss_op()solver = tf.train.AdamOptimizer().minimize(loss)# Training iteration
sess.run(solver, {data: input_data, *train_phase:True*})#Validation iteration
sess.run(loss, {data: input_data, *train_phase:False*})**
  • 共享批次范数参数: 通常你在两个并行网络中共享权重,比如 siamese 或者在 GANs 的鉴别器中。当您共享您的重量时,批量定额参数也会被共享。有时候,跨两个网络共享批量定额参数也不能健康,具体什么时候我会告诉你。
    假设我们正在训练一个 GAN,它将有两个具有共享参数的鉴别器实例,当训练开始时,伪图像和真实图像的分布是不同的。现在我们用两种不同的分布来更新移动平均值和方差,一种是假图像,另一种是真实图像。但是随着训练的继续和生成器学习真实数据的分布,假数据和真实数据的分布最终变得近似相同。然后我们在更新同分布的均值和方差,所以我们的总体均值和方差应该是完整训练后真实数据的估计统计量。因此,理论上,在 GANs 的情况下,共享批量定额参数可能不是一个大问题。但是我会在这两种条件下做一些实验,并在新的博客上更新实验结果。
    现在 这篇博文 可以很好地解释共享批量定额参数会对模型的准确性产生不利影响的情况,并具有更好的可视化效果。
    简而言之,在两个共享批次范数层的输入分布相同之前,共享批次范数参数是可以的,如果不是这种情况,请尝试在上述批次范数函数中使用reuse=False,这将允许您在想要共享权重的两个网络中拥有独立的批次范数参数。

二。健全性检查和调试-

  • 端到端图像模型:
    在图像分割或深度预测等以图像为输入的任务中,我们希望输出大小相同的图像。训练您的模型以学习身份函数,即将输入图像作为目标图像。在这种情况下,网络将代表身份功能。如果这是完美的训练,但你仍然无法学习分割或深度,可能是你的模型没有足够的能力。你可以尝试添加更多的层或可能更好的损失功能为您的任务。
  • 目标和输出范围:
    如果您已经将目标图像归一化为 0 到 1,那么请确保在图像生成层中使用 sigmoid 作为激活函数,而不是 tanh,因为 tanh 将具有-1 到 1 的范围,这将使学习变得困难。如果归一化在-1 到 1 之间,则使用双曲正切。
  • 波动损失:
    最可能的原因可能是您的机型没有足够的容量。因此,权重快速改变以学习模型,但是由于容量有限,它们保持快速改变它们的权重,但是从未接近最优。你也应该试着降低学习速度。
  • 超参数:
    千万不要忽略超参数。一般来说,它们对于你的网络的准确性和性能可能不是非常关键,但是对于训练的收敛性和稳定性绝对是非常重要的。疏忽的权重初始化可能导致网络中的梯度或 NaNs 被利用/消失。如果你使用正态分布,检查你的权重初始化的 std_dev,范围[0.2,0.01]是可以的。如果损失表现异常,学习率和批量大小是首先要试验的。
  • 顺序数据的混排:
    当您的输入数据是顺序数据时,这种情况在视频中最常见,如自动驾驶中的分段、深度预测等。你应该考虑改变数据,用连续数据训练会对测试中的模型准确性产生负面影响。
    注:每当任务需要时间一致性时,如光流、视觉里程计等,你应该有顺序数据。
  • 缩放损耗:
    如果您在网络中使用一种以上的损耗类型,例如 mse、对抗性、L1、特征损耗SSIM ,那么请确保所有损耗都被适当缩放到相同的阶数,即 MSE 为 1e-01,特征损耗为 1e03,然后将特征损耗缩放到相同的阶数。
  • 图形可视化,这场战争中最大的武器:
    如果你使用 TF 和其他有可视化工具的框架。您应该使用可视化来检查连接,它们将帮助您找出遗漏的连接、尺寸误差或重量分配误差。
  • 共享批量定额参数:
    如上所述,如果您在两个网络中共享批量定额参数,那么请确保两个网络的输入数据分布相同。

这篇博文还详尽列举了你的网络失败的其他原因。

感谢大家阅读这篇博客,希望它能拯救你与批量定额和培训网络的斗争。我欢迎您的所有评论,如果您想添加任何内容或觉得任何内容有误导性,请告诉我。如有疑问,可发邮件至 dishank.bansal@iitkgp.ac.in 联系我。

参考资料:

简单估计量

原文:https://towardsdatascience.com/plain-and-simple-estimators-d8d3f4c185c1?source=collection_archive---------2-----------------------

机器学习很棒,除非它强迫你做高等数学。机器学习的工具变得越来越好,训练你自己的模型变得前所未有的简单。

我们将利用我们对数据集的理解,而不是对原始数学的理解来编写一个模型,让我们获得洞察力。

在这一集里,我们将只用几行代码来训练一个简单的分类器。以下是我们今天要看的所有代码:

机器学习的张量流估计器

为了训练我们的分类器,我们将使用 TensorFlow,谷歌的开源机器学习库。TensorFlow 有一个相当大的 API 面,但是我们要关注的部分是高级 API,称为估计器。

评估人员为我们打包了训练循环,因此我们可以通过配置它来训练模型,而不是手工编码。这去掉了许多样板文件,允许我们在更高的抽象层次上思考。这意味着我们将开始玩机器学习的有趣部分,而不会陷入太多的细节。

由于到目前为止我们只讨论了线性模型,我们将把它放在这里。我们将在将来再次讨论这个例子,以扩展它的功能。

花卉分类:就像葡萄酒 vs 啤酒一样有趣?

本周我们将建立一个模型来区分三种不同类型的非常相似的花。我意识到这是一个有点不如前一集的啤酒和葡萄酒令人兴奋,但这些花有点更难区分,使这成为一个更有趣的挑战。

[## 机器学习的 7 个步骤

从检测皮肤癌,到分拣黄瓜,到检测需要维修的自动扶梯,机器学习已经…

medium.com](https://medium.com/towards-data-science/the-7-steps-of-machine-learning-2877d7e5548e)

特别是,我们将对不同种类的鸢尾花进行分类。现在,我不确定我能从一片玫瑰丛中挑出一朵鸢尾花,但我们的模型旨在区分鸢尾、杂色鸢尾和海滨鸢尾。

Iris Setosa, Iris Versicolour, and Iris Virginica

我们有一个测量这些花的花瓣和萼片的高度和宽度的数据集。这 4 个栏目将作为我们的“特色”。

加载数据

导入 TensorFlow 和 NumPy 后,我们将使用 TensorFlow 的load_csv_with_header函数加载数据集。数据或特征以浮点数表示,每行数据或目标的“标签”记录为整数:0、1 或 2,对应于 3 种花卉。

我已经打印出了我们加载的结果,我们可以看到,我们现在能够使用命名属性访问训练数据和相关联的标签或目标。

建立模型

接下来,我们将构建模型。为此,我们将首先设置特性列。要素列定义了进入模型的数据类型。我们使用一个 4 维特征列来表示我们的特征,并将其命名为“flower_features”。

使用估计量建立我们的模型非常简单。使用“tf.estimator.LinearClassifier ”,我们可以通过传入刚刚创建的特征列来实例化模型;模型预测的不同输出的数量,在本例中为 3;以及一个存储模型的训练进度和输出文件的目录。这使得 TensorFlow 可以在需要时从中断的地方继续训练。

输入功能

这个分类器对象将为我们跟踪状态,我们现在几乎准备好继续训练了。将我们的模型与训练数据联系起来还有最后一个环节,那就是输入函数。输入函数的任务是创建张量流操作,为模型生成数据。

因此,我们从原始数据到输入函数,输入函数传递数据,然后由特征列映射到模型中。请注意,我们对特性使用了与定义特性列时相同的名称。这就是数据的关联方式。

运行培训

现在是时候开始我们的训练了。为了训练我们的模型,我们只需运行 classifier.train(),将输入函数作为参数传入。这就是我们连接数据集和模型的方式。

train 函数处理训练循环并在数据集上迭代,每一步都提高其性能。就这样,我们完成了 1000 个训练步骤!我们的数据集并不大,所以完成得相当快。

评估时间

现在是时候评估我们的结果了。我们可以使用之前的相同分类器对象来实现这一点,因为它保存了模型的训练状态。为了确定我们的模型有多好,我们运行 classifier.evaluate()并传入我们的测试数据集,并从返回的指标中提取准确性。

我们得到了 96.66%的准确率!一点都不差!

评估人员:简单的工作流程

让我们在这一周暂停一下,回顾一下到目前为止我们使用估算器所取得的成果。

Estimators API 为我们提供了一个很好的工作流程:获取原始数据,通过输入函数传递数据,设置我们的特征列和模型结构,运行我们的训练,以及运行我们的评估。这个易于理解的框架允许我们考虑我们的数据及其属性,而不是数学的基础,这是一个很好的地方!

下一步是什么

今天我们看了 TensorFlow 的高级 API 的一个非常简单的版本,使用了一个固定的估计器。在未来的几集中,我们将探讨如何用更多的细节来扩充这个模型,使用更复杂的数据,并添加更多的高级功能。

喜欢这一集吗?在 YouTube 上查看整个播放列表!

行星蜂巢

原文:https://towardsdatascience.com/planet-beehive-aeca53ba0326?source=collection_archive---------24-----------------------

Ep。1:探索我们星球的旅游活动

Our output for today; Make sure to read below how we get there; Calculate our measures and for a interactive visualization

闭上你的眼睛一秒钟,忽略外面的雨滴,新邮件的嘟嘟声,深入思考你的待办事项清单上的十项全球活动..

老实说,有多少人参加了世界上最常去的活动?这没什么不好,他们来访是有原因的。然而,它们真的值得我们花费有限的资源去那里旅行吗?或者有没有其他没有立即想到的选择?

这些问题是我们今天想要回答的问题。我们能否客观地创建一个衡量标准,不仅代表访问量最大的活动,还代表评分最高的全球活动,我们能否将这些活动可视化为一个易于发现的新珍珠地图?

我们的方法

  1. 我们将查看当前可用的度量,并根据需要对数据进行 转换 以增强下游分析和可视化

  2. 在地区、国家和个人活动水平上执行 探索性数据分析 ,以验证我们新创建的衡量标准

  3. 将我们的数据可视化到一个交互式图表中,我们将在接下来的几集里将这些数据修改到一个交互式仪表盘中

数据

我们今天将使用的数据包括:活动元数据、评论数量、用户评级和一些额外的地理数据。我们最初将从以下来源获得这些信息:

  • :收集的活动,用户评论数和他们的评分 ,他们收集的活动将是我们的起点。在这里,我们只关注在每个国家的“首要任务”清单上的活动或有超过 750 条评论的活动。****
  • Google : 通过使用 Google Places 和 Geocoding API,我们丰富了来自猫途鹰的活动数据,收集来自 Google 用户的 地理数据 (即坐标)以及****
  • CIA World Factbook : 关于国家的参考数据(大小,公民等。)我们将使用《中情局世界概况》中的综合数据库。我们从 174 个国家开始

数据转换

我们的数据集从 7,044 个活动开始,其中 5,971 个活动我们还可以得到谷歌用户评级。今天练习的良好开端。

让我们通过创建两个散点图来看看数据是什么样的,这两个散点图包含我们最关心的 4 个指标:一个包含纬度经度,另一个包含评论数量每项活动的平均评分

********

Fig. 1, 2 Scatter plots created with Matplotlib in Python

以下是一些初步要点:

  • 欧洲的活动似乎非常多。这可能是由使用猫途鹰的用户偏见造成的。然而,总的来说,我们的地理数据看起来很干净,我们有一个适当的全球多样化。
  • 我们喜欢给高收视率!几乎没有低于 6/10 的评分,显然大多数评分都高于 8/10。简单的平均综合评分甚至是惊人的 8.98/10!
  • 说到评论的数量,似乎大多数活动只有 20,000 或更少的评论。与此同时,有相当多的离群值,以及超过 120,000 条评论的明确亮点活动!(你能猜出这是哪个亮点吗?)
  • 评论的数量和平均评级标准都不是正态分布的

而后者是我们这里的重点。因为我们今天的目标是使用这些度量来进行比较,所以我们希望在这两种情况下获得尽可能多的正态分布度量集。图 2 告诉我们一些关于这两个度量的信息,以及它们是如何分布的。

首先来看一下评论数量,考虑到大量较小的值和非常有限的非常高的值,我们似乎正在处理一个对数正态分布。为了证实这一观察结果,我们将绘制两个 QQ 图,一个具有正常轴,另一个具有对数轴,一条直对角线将证实正态分布:

Fig. 3, 4 QQ plots with regular y-axis (left) and log y-axis (right) produced with Probscale in Python

正如所料,对数标度比常规标度更适合正态分布数据集。因此,我们将对审核措施的数量应用 LOG10 转换。我们将使用这一新方法来比较未来的评论。

****然后进行平均评级的分配。这里的问题似乎不一定代表数据的偏斜,而是用户给出过高评级的问题。如果只看 8 分以上的评分,这种分布似乎更接近正常。

Fig. 5 Boxplots produced with Pandas in Python

我们可以用左边的方框图来证实这一观察结果。查看每个评级值以及两个来源的平均值,我们可以看到,在 8 到 10 之间的分布可以被视为正态分布,任何低于 8 的评级都有异常值。

因此,我们将把数据转换成一个新的衡量标准,其最低阈值为 0.8(意味着 0.8 等于≤ 0.8)

最后一步,我们将对这两个测量值应用最小最大归一化。

现在,我们可以在下面的 jointplot 比较中比较转换后的度量的分布与原始度量的分布:

********

Fig. 6, 7 Combined distribution plots Before and After respectively created with Seaborn in Python

由此,我们可以创建一个新的度量,它应该代表这两个度量的最佳组合。将它们相乘将得到一个值,该值代表评论数量的加权分数(即评论越多,其评级越可靠):

活动评分:

正常。平均下限。访客评级*

(规范。log10 审核计数/平均值(标准。log10 审核计数))

探索我们的活动

既然我们已经创建了评分标准,我们就可以开始研究数据了。

让我们首先将全球区域的活动评级与每项活动的平均点评数进行比较:

Fig. 8 Scatter plot generated with Seaborn in Python

现在越来越有趣了!这里有些非常特殊的事实可能会违背你的先入之见。

首先,在高水平上,这两个变量之间显然存在正相关关系。这自然是有道理的,活动评价越高,就会有越多的人来参观。当然,直到你到达一个点,访问者的数量在评级中变成一个负变量:

没人去那里了。太拥挤了。

其次,看看平均评论数量排名前三的地区,这些似乎是我们许多人都可以猜到的顺序。西欧、南欧和北美有许多著名的旅游热点,接待许多游客,因此平均每项活动也有许多评论。

排名前三的地区也是如此:澳大利亚和新西兰、中美洲和北美洲是经常被称赞的地区。我个人认为最令人惊讶的地区是东欧,排名第四,领先于任何其他欧洲地区!

最后,从大洲的角度来看:美洲和欧洲表现最好,而亚洲、大洋洲和非洲则表现得更加分化。尤其是西部和中部非洲在这两项指标上都是绝对垫底的,而南部和北部非洲也没有落后其他地区太多。

让我们转到国家视图,根据加权平均评级绘制排名前 10 位和后 10 位的国家,看看我们能从中得到什么:

俄罗斯占据了头把交椅!对于我们中的一些人来说,这可能是出乎意料的,但同时我们看到乌克兰也进入了前 5 名,与之前的地区概况完全一致,另外两个东欧国家也进入了前 15 名(白俄罗斯和斯洛文尼亚)

我想对我们大多数人来说,前 15 名中的所有其他国家都是显而易见的,它们都是非常著名的度假目的地。可能最令人惊讶的是看到辣椒击败所有其他美国南部国家。

很高兴看到前 15 名来自七大洲中的 5 个国家。但是排名最后的 15 个国家看起来没有那么多样化,而且几乎完全由非洲国家主导(更准确地说,主要是西非和中非)。朝鲜是唯一一个来自另一个大陆的国家,能够融入这个不那么有声望的名单。

为了让这些国家的热点在全球范围内更加明显,我们可以创建一个全球热图,绘制每个国家的加权平均活动得分:

Interactive Chart #1. Choropleth Map created with Plotly

这个图很大程度上证实了我们以前已经发现的东西。有明显的热点地区,包括欧洲(尤其是东欧和西南欧)、北美(尤其是加拿大和中美洲)、大洋洲和南美洲,尽管巴拉圭和北部的一些小国是这些地区的负面离群值。

“冷”点在非洲中部和西部最为明显。而南部、北部以及东部非洲的一些地区得分略高。亚洲的情况非常复杂,一些国家属于绝对寒冷地区(朝鲜、巴布亚新几内亚、吉尔吉斯斯坦),而其他国家的得分很高(泰国、土耳其、也门)。

到目前为止,我们已经很好地了解了地区和国家是如何被同路人评价的,现在是时候看看个人活动了。毕竟,我们今天的目标是在地图上标出每个活动,并使其在平均评分和评论数量上具有可比性。

因此,在下面的图中,我们看到了纯粹基于评论数量的前 15 项活动,以及基于我们新创建的评分标准的前 15 项活动:**

多么有趣的差异啊!一些关键要点:

  • 评论数前 15 名的活动,可能没有一个让任何人感到非常惊讶;完全被欧洲和北美(实际上是纽约)的著名活动所主导。
  • 同时,我们新创建的加权评分指标中的前 15 项活动反映了当前各大洲的高度多样性(7 个中的 5 个),并且肯定包括了一些我个人的新列表条目。
  • 令我惊讶的是,没有一个基于评论数量的顶级活动也能进入加权得分排行榜。这意味着他们在网上获得的平均评分明显低于加权评分活动的前 15 名。
  • 虽然上面的图表主要是欧洲的活动,但第二个图表只包括欧洲的两项活动。因此,虽然他们收到了大量的评论(和访客),但他们的评级却比其他(较少访问的)活动稍低。

总结图表

现在是时候让我们所有人自己探索所有活动,同时能够清楚地区分每个活动的评级和评论数量了。我们现在将绘制所有活动,标记填充是最低平均评级,而标记的大小是评论的数量。当您将鼠标悬停在标签上时,每个活动的所有详细信息都会显示在标签中。

此外,您还可以在下面找到基于我们新创建的衡量标准的前 100 项活动,以供进一步参考。

一定要放大你的祖国(不要责怪地图上的细节少了点)或你的下一个旅行目的地,因为你可能会发现一些真正的好东西!

Interactive Chart #3 scatter plot with hex bins as markers with Plotly

星球,重访

原文:https://towardsdatascience.com/planet-revisited-ca37faefab45?source=collection_archive---------24-----------------------

用 fastai 1.0 进行卫星图像分析。

我想在xfiew数据集、 DIUx 的卫星图像竞赛上工作。我已经有一段时间没有做计算机视觉工作了,随着 fastaiPyTorch 的 1.0 发布和预发布,我认为重温星球亚马逊 Kaggle 竞赛将是一个很好的热身。

我的目标是在继续前进之前打破最高分。那个位置由最合适的占据,他现在是 Kaggle 上排名第二的竞争者,之前是第一。所以我的第一站是查看他的采访——因为 Kaggle 在其博客上采访比赛获胜者。实际上,我有几次回想起这件事:第一次很困惑,感觉“哦,就这样了?”最后一次。

有件事。当你阅读一个知道自己在做什么的人写的新的技术- 任何东西时,真的很容易失去平衡。你一遍又一遍地发现,那些看起来很重要的事情,其实并不重要。机器学习(或任何领域)任务的基本概念通常非常简单。能够从低级细节到高级概述进行上下文切换是非常有价值的。

所以第一个命令是,看看胜利者是如何做到的。xView 将有创新的空间;我的目标是尽快度过难关,比赛结束。所以让我们看看什么有效。

我想我把采访看了三遍,并写了两遍,画了一个关于 bestfitting 所说的图表,以便在整个过程中帮助我。它的要点是这样的:

  • 使用去雾算法预处理图像(使模糊→清晰)
  • 使用大约一打模特的组合
  • 将每个模型的输出馈送到其自己的岭回归模型/层以学习数据中的相关性
  • 将集合的输出提供给最终的岭回归模型。
  • 也使用 F2 损失函数

什么是岭回归?几天到一周的迷茫 阅读 后来,我得到的是:‘岭回归’是损失函数中加入平方和项的线性回归。Anuja Nagpal 的帖子是我理清事情的关键。因此… ' 岭回归'将 L2 正则化添加到损失函数中…(并有一个 L1 对应项,添加了一个幅度和项,称为'拉索回归')。

from Nagpal’s post

还有一件事。当我听说某个工具被用来“寻找数据中的相关性”和“选择最强的模型来预测每个标签”时,我的想法是进城,尤其是当这个工具有自己的名字时。因为第一次,我很难想象带有平方和项的回归会做一些听起来很聪明的事情。它不可能是你可以从 scikit-learn 导入的东西,或者作为一个层编码到神经网络中,对吗?

但还是 怎么办?“选择一个模型”等等。我到了那里会告诉你的。然而,事物的内部名称增加了进入一个领域的摩擦。就叫它是什么吧。

在这一点上,我对“岭回归”或“L2 回归”等的唯一困惑。,就是通过做才能得到答案的东西。当 bestfitting 说他们使用一个模型时,他们是指他们在 PyTorch 中编写了一个迷你神经网络,还是从 scikit-learn 中导入的?或者只是一个神经网络的线性层(比方说,附加在 CNN 模型的分类器头上)与 L2 正则化?最后一个更有道理…但是你怎么训练它呢?看,模型回归器是有意义的:把它做成一层,然后正常训练。但是整体回归器…你不能一次就建立一个巨大的神经网络。即使你有资源,不同的模型也会有不同的训练方案。所以最后一个回归变量要么是 PyTorch 要么是 scikit-learn 模型,对吗?听起来像是必须的。然后你也拟合它,在“原始”预测和实际标签之间,对吗?

…不幸的是,你必须被列为“贡献者层”才能被允许在 Kaggle 上联系其他人,所以我不能轻易要求。到了那里就知道了。

这留下了工作前的最后一个细节:去雾。去雾就像它听起来的那样:它只是从模糊的图像中去除薄雾。

from: anhenghuang/dehaze

Bestfitting 使用了一种基于论文的算法:使用暗通道先验的单幅图像去雾。它显示了令人印象深刻的结果。我决定不去实现它——我在玩这样一个想法:快速完成一个项目包括选择在哪个山头插上你的剑。我就找了个好的外挂-&-玩版。我还是花了一天时间在这上面。我找到了一个 Python 版本的,但运行起来需要一秒钟,所以我找到了一个 C++版本的,在我完成了与 Xcode 的战斗并重新学习了如何在其中构建一个项目之后,运行起来需要更长的时间。所以我想,“让我们用神经网络来做这件事吧”。但是我想知道如何正确地做这件事?我不想沉溺于设置一个环境来运行一个我只作为预处理器使用过一次的模型。于是找了个现成的 Caffe 型号!从来没有使用过编译过的神经网络,最好学一段时间。一个陷阱。如何安装Caffe?最好不要因为你打算用一次的东西而改变你的系统。啊,有一种方法可以将 Caffe 转换成 Caffe 2(T18)(它来自 PyTorch 的 conda 安装)……这涉及到caffe导入,因此需要Caffe——你知道我对 python 版本的看法。**

——我还在 github 上找到了几个其他的 dehazers。 DCPDN & AOD 网。—

现在我准备好实际做一些深度学习了。嗯,还没有,因为在玩 Xcode 和 HomeBrew 以及其他东西的时候,我设法破坏了我的 Mac 的 Python 2 安装——顺便提一下,这就是谷歌使用的,因此为什么 gcloud 不能连接到我的 GCP 实例;而是抛出一个令人困惑的“找不到模块 zlib”导入错误。我忘了我是怎么修好那个的。从苹果开发者网站下载 Xcode 命令行工具有问题,因为它不能从命令行运行。然后是自制的东西。那花了一天时间。可能是同一天。

像这样的噩梦是我使用清单的原因。

**现在我准备好开始使用 fastai 。我将在下一篇文章中讨论这个问题。

星球,重访 2

原文:https://towardsdatascience.com/planet-revisted-2-b47995a8567?source=collection_archive---------19-----------------------

fastai 1.0 卫星影像分析

[ 第一部分

这篇文章有点像实验。莱斯利·史密斯和杰瑞米·霍华德等研究人员的工作质量和数量一直给我留下深刻印象,也让我感到困惑——他们的实验从外表看起来是多么复杂。学习人工智能的最大挑战之一就是简单地跟踪我在做什么以及为什么。当你同时进行多个实验并且还有其他事情要做的时候,你如何组织一个项目?记笔记可能是个好主意……

为了做更好的实验,这篇文章主要是边工作边记笔记的结果。它已经帮助我发现了一些错误,并磨练了一些想法。首先,回顾一下自上次以来一些重要的工作基础设施的发展。

第 1.5 部分:

这是对第 1 部分的一点跳跃。长话短说:为了把行星数据下载到虚拟机上,发生了很多冲突,为了让 Kaggle 的 API 工作,又发生了更多的冲突。这一切都被新的 fast.ai 课程笔记本里的几行代码代替了。稍微修改一下,使设置过程非常快速(这些是在 Linux 机器上的 Jupyter 笔记本中完成的):

在您的环境中安装 Kaggle API:

! pip install kaggle --upgrade

创建 Kaggle API 密钥后,将其移动到需要的位置:

! mkdir -p ~/.kaggle/
! chmod 600 kaggle.json
! mv kaggle.json ~/.kaggle/

制作一个数据目录(在from fastai import *之后):

path = Config.data_path()/'planet'
path.mkdir(parents=True, exist_ok=True)

下载数据:

! kaggle competitions download -c planet-understanding-the-amazon-from-space -f train-jpg.tar.7z -p {path}

(&对test-jpg.tar.7ztrain_v2.csvtest_v2_file_mapping.csv做同样的事情)

拉开拉链。zip 是这样的:

! unzip {path}/train_v2.csv.zip -d {path}

像这样解压. tar.7z 文件:

! 7za -bd -y x {path}/train-jpg.tar.7z -o{path}
! tar -xf {path}/train-jpg.tar -C {path}

并清除存档文件(这将删除所有。zip、. 7z 和。{path}中的 tar 文件,无需确认):

! rm -rf {path}/*.zip
! rm -rf {path}/*.7z
! rm -rf {path}/*.tar

大概就是这样。其他大的收获是学习如何在 fastai 库中做一些基本的事情,并找到更好的方法来实现快速实验(如指定分类截止阈值,基于这些自动创建提交文件,并上传到 Kaggle)。我想我会就此写一个小帖子,因为机械/基础设施之类的东西在你让它们工作之前是项目中最难的部分,之后看起来如此简单,你几乎会忘记它们。我这样做的时候会在这里放一个链接

第二部分:

我们的目标是在继续进入xfiew数据集之前,赢得行星亚马逊 Kaggle 竞赛。我的想法是使用获胜的解决方案作为起点。但在此之前,我想用 ResNet34 击败一个人工基准: 0.93 (私人排行榜),只是为了确保我有一个可靠的模型在工作。

起初,我无法在 fast.ai 课程实现上有太多改进。我尝试了“渐进式重新冻结”,这是在解冻模型后锁定层,尽管验证指标看起来不错,但两次都失败了。这导致排行榜分数从大约 0.92 下降到 0.3——如果我玩有门槛的游戏,则为 0.5。从第 100 名下降到第 920 名,总共 938 名。像这样的崩溃通常是由于搞乱了提交文件,但是我还没有测试出到底发生了什么。

我正要继续前进,直到我在一个晚上得到了我的第四个最好成绩两次。其中一个分数只训练了 80%的数据。目前是 0.92638 。但是为什么是第四呢?因为在 2017 年跟随该类的一个早期版本,我用 ResNet34 得到了 0.92873 。我是如何用同样的模型和 fastai 库更有限的版本(0.7)得到更好的成绩的?

看着那本笔记本,有一个重要的直觉:

https://github.com/WNoxchi/Kaukasos/blob/master/FADL1/L3CA_lesson2-image-models.ipynb

卷积层的训练比正常情况下更加积极,因为它们是在 ImageNet 上预先训练的 ImageNet 不包含任何卫星图像。嗯,有道理。我使用了一个 3 倍的学习速率,而不是典型的每层组 10 倍的变化。以及非常大的初始学习率(lr=0.2)。(看起来你也微调线性层更多,但我一开始错过了这一点)

第二天(实际上是今天)我回来测试这个想法。与旧的学习率相比,似乎更积极的区别学习率(DLRs)在早期做得更好。损失下降得很快…但它似乎从一个更高的值下降到另一个更高的值。

**注意:**我将提到以几种不同方式训练的同一个模型。这样就不那么令人困惑了:norm-1在我开始研究更大的学习率之前,这个模型是否经过了“正常”的训练。aggr-n是第 n 个训练有素的模特。通常情况下,aggr的层组之间的幂差为-3(比如:LR/9,LR/3,LR),而norm-1的幂差为-10。除非另有说明,所有运行总共训练 24 个周期:每个阶段长度为 6±1 个周期(1:线性,2:全 conv),每个尺寸。

第二阶段积极运行的规模图 128:

f1. the aggressive model experiences a sharp loss drop, but froma higher starting point

并将其与第一轮(norm-1)的大小 128 第二阶段进行比较:

f2. the ‘normally-trained’ model has a shallower loss drop, but from and too lower values

积极运行的最终损失图(橙色表示验证):

f3. final loss plot of the aggressive run, aggr1

与正常运行相比:

f4. final loss plot of the normally-trained run, norm1

你想要的是类似后者的东西。 OneCycle 探索“解决方案空间”,给出一个损耗突增,然后稳定在一个接近恒定的低值。这不太符合新一轮的情况…所以要么是我太过于咄咄逼人,要么是我需要更长时间的训练来让事情稍微稳定下来;因为上面的图表看起来像是在不断变化。

此外,如果你想知道的话,我在 jupyter 实验室使用了材质黑暗主题。我发现自己使用 jupyter lab 比使用 notebook 多,因为虽然它的有用扩展比 notebook 少,但它内置了视图,所以你可以同时查看多个笔记本或笔记本的多个部分。

向 Kaggle 提交预测后…新模型并没有做得更好。我有一种预感,这是因为我把学习率——所有的学习率— 定得太激进了。对于尺寸为 128 的第二阶段,我使用了learn.lr_range(slice(lr/2/9, lr/2)) = lr/2/9, lr/2/3, lr/2,但是在尺寸为 256 的第二阶段,我使用了:lr/9, lr/3, lr

将结果转换成可读的形式:

f5. results for norm-1 and aggr-1

norm-1是继 fastai 课程笔记本之后的 ResNet 机型。aggr-1是第一款‘进取型’车型。我认为我在新型号中用我的 DLRs 做得太过分了。在某些情况下,我在比以前高 3 个数量级的LRs 训练。

但这里有另一个想法:在第一次尝试之后,有多少“积极的微调”需要完成?你能从现实世界到卫星图像“模式”的艰难转向开始调整重量,然后回到“更平静”的训练计划吗?我现在要试试。

中场休息

我试过了(aggr-2),它比 norm-1 或 aggr-1 都差…损失图看起来不错,但我认为它只是没有得到足够的训练。从数字上看,这款车型看起来不足。训练损失比验证高 1.8%:0.083386 对 0.081870,阈值准确度下降了百分之一,fbeta 得分从 0.924608 上升了约 0.3%,达到 0.927831。

:看起来和原装笔记本最大的区别就是增加了。除此之外,它似乎遵循每个阶段 6 个时期,每个大小 2 个阶段(冻结,解冻),训练格式。

旧笔记本从 64 号开始,然后是 128 号,然后是 256 号。我可能想试试这个

但是在那之前…关于 aggr2 的额外训练…LRs 减半的额外 6 长度 256 阶段 2 循环…实际上比 aggr2 执行得更好,而不是崩溃。最终的损失图看起来就像你预期的那样:

f6. final losses of aggr2 trained for an extra cycle at 1/2 DLR

嗯,这很有意思

这里有一些注释。我最初认为aggr1的表现优于norm1,因为我混淆了这两个值(我在 f5 处向上修正了结果)。事实证明并非如此,但是额外的训练确实对aggr2x有持续的帮助。

f7. private leaderboard results for all models

积极的训练正在起作用,看起来我并没有对 LRs 表现得太积极。尽管过去的经历令人困惑,但在最后训练第二阶段实际上对模型有一点帮助。

现在是时候训练aggr1(因为我保存了重量,我可以重新加载)一个额外的周期,看看会发生什么。接下来,我将尝试通过 64–128–256 逐步调整大小。

中场休息 …

f8. That’s an interesting looking plot..

有趣的是,在 96%的准确率下,我们实际上只是在追逐一个数字。这是 96%的准确度,计算方法如下:

((preds>thresh).float()==targs).float().mean()

这就创建了一个独热编码张量(例如[0.,1.,1.,0.,..]),只要预测与目标匹配,张量就为 1,其他地方为零。平均值作为精度值返回。

预测是有阈值的:任何更大的概率转换为 1,否则为 0。这与目标(也是 1-hot)相比较。

这也隐藏了一个事实,即模型可以通过学习忽略罕见的类(0==0) = 1来获得非常高的精度。尽管如此,排行榜上的 F2 分数仍然是+0.92。

不幸的是模型没有改进。我想知道重新加载一个模型,然后进一步训练——正如我在这里所做的——是否会有不同于继续训练你已经在工作的模型的结果。我现在没时间测试这个。相反,是时候用最佳工作模式逐步调整大小了。这至少需要一个小时。我真正喜欢人工智能工作的一点是它如何推动你变得有条理。如果你安排好你的工作,为等待时间做好计划,你会有很多空闲时间。

我认为这是这篇文章的一个很好的结束点。接下来将是从 64 码开始逐步调整大小的结果,将 6 周期模型与 7 周期模型以及两倍长度的第 6 周期模型进行比较。之后,就是“在整个数据集上训练最好的一个,看看你得到了什么”。*之后:*用 ResNet50 再做一次,注意看更大的模型是否能更好地处理更大的学习率。

完成所有这些后,实现去模糊器,看看添加 L2 回归是否值得,这将是一件迫在眉睫的事情。我的目标是后天,也就是周一开始使用 xView,所以我们会看看进展如何。

在查看更长或多个周期(这给了我一些不好的结果)之前,或者参考 2017 年的笔记本,我要看看如果我在 LR/2 和 LR/5(这是“正常”模型的最大值)训练 size256 模型会发生什么。

动态规划规划:强化学习

原文:https://towardsdatascience.com/planning-by-dynamic-programming-reinforcement-learning-ed4924bbaa4c?source=collection_archive---------4-----------------------

第三部分:解释动态规划、策略评估、策略迭代和价值迭代的概念

在这篇博文中,我将解释如何使用动态编程来评估和寻找最优策略。这一系列的博客文章包含了 David Silver 在强化学习简介中解释的概念总结。

零件:1234

我们现在将使用前面部分中讨论的 MDPs 和 Bellman 方程等概念来确定给定策略有多好,以及如何在马尔可夫决策过程中找到最优策略。

动态规划

动态规划是一种通过将复杂问题分解为子问题来解决复杂问题的方法。子问题的解决方案被组合以解决整体问题。

动态编程的两个必需属性是:

  • 最优子结构 :子问题的最优解可以用来解决整体问题。
  • 重叠子问题 :子问题多次重复出现。子问题的解决方案可以被缓存和重用

马尔可夫决策过程满足这两个性质:

  • 贝尔曼方程给出了递归分解,它告诉我们如何将最优值函数分解成两部分。即一个步骤的最佳行为,然后是剩余步骤的最佳值。
  • 价值函数存储并重用解决方案。缓存所有 MDP 的好信息,告诉你从那个状态开始你能得到的最佳回报。

动态规划规划

当有人告诉我们 MDP 的结构(即当我们知道转移结构、奖励结构等)时,动态规划可以用来解决强化学习问题。).因此用动态规划对 规划 中的一个 MDP 进行求解:

  • 预测问题 (政策评估):

给定一个 MDPS,一个 P,一个 R,一个γ>和一个策略 π 。求价值函数 v_π (它告诉你在每种状态下你将要得到多少奖励)。也就是说,目标是找出一个政策 π 有多好。**

  • 控制问题(找到在 MDP 最好做的事情):

给定 MDP *< S,A,P,R,γ >。*求最优值函数 v_π和最优策略 π。*也就是说,我们的目标是找到能给你带来最大回报的政策,并选择最佳行动。

政策评价

问题 : 评估一个给定的策略 π 和 MDP。(找出一个政策 π 有多好)
:贝尔曼期望备份的迭代应用。

方法: 从初始值函数v₁(MDP 中所有状态的一个值)开始。例如以值 0 开始。因此没有奖励。然后用贝尔曼期望方程计算 v₂ ,重复多次,最终收敛到 v_π。

实现这种收敛的一种方法是使用同步备份,其中我们在每一步都考虑所有状态。

  1. 在每次迭代 k+1 时,对于所有状态 s ∈ S
  2. 更新 vₖ₊₁(s)vₖ(s'),其中*s’*是 s 的继承状态

vₖ(s') 使用第 2 部分中讨论的贝尔曼期望方程进行更新。

Bellman Expectation Equation

举例: 假设我们有一个有 14 个状态的网格世界,其中每个方块代表一个状态。我们还有 2 个终端状态,一个在网格世界的右下角,另一个在左上角。我们可以采取将向上向下向左向右动作,我们采取的每一个过渡都会给我们一个 -1即时奖励,直到达到一个终止状态。由于折扣因子γ=1 ,我们给定的代理策略 π 遵循统一的随机策略:

我们需要计算处于每个状态的值,以确定我们定义的策略 π 有多好。

1.按照我们上面描述的方法,我们可以从初始值函数 v₀开始,所有值都是 0。

v₀

2.接下来,我们通过应用一步前瞻,使用贝尔曼期望方程来计算新的价值函数 v₁。

v₁: Blue block is calculated using the Bellman Expectation Equation such that 0.25(-1+1(0))+0.25(-1+1(0))+0.25(-1+1(0))+0.25(-1+1(0)) = -1

3.重复使用 v₁计算 v₂的过程

v₂: Blue block is calculated using the Bellman Expectation Equation such that 0.25(-1+1(-1))+0.25(-1+1(-1))+0.25(-1+1(-1))+0.25(-1+1(0))=-1.75

4.用 k=∞ 重复这个过程,最终将我们的价值函数收敛到 v_π。

因此,对于我们的策略 π ,我们计算了 MDP 中每个州的相关值。

如何完善一项政策? 在上面的方法中,我们已经评估了一个给定的策略,但是没有在我们的环境中找到最佳的策略(要采取的行动)。为了改进给定的策略,我们可以评估给定的策略 π 并通过*相对于 v_π贪婪地行动来改进策略。*这可以使用 策略迭代 来完成。

策略迭代

问题 : 为给定的 MDP 寻找最佳策略*【π*】*。
解法 :贝尔曼期望方程政策迭代与行事贪婪。

方法: 以给定策略开始 π

  1. 使用策略评估来评估策略 π (如上所述)
  2. 通过 v_π 的贪婪 行为来改进 π 的策略,得到新的策略π’
  3. 重复直到新策略*π’收敛到最优策略 π

为了贪婪地行动,我们使用一步前瞻来确定给予我们最大 行动值函数 (在第 2 部分中描述)的行动:

回想动作值函数有以下等式:

action-value function

值迭代

控制问题的另一种方法是使用贝尔曼最优方程进行数值迭代。首先,我们需要定义如何使用 最优性原则将一个最优策略分成几个部分。

最优性原理 任何 最优策略 都可以细分为使整体行为最优的两个组成部分:
-最优的第一个动作A∫
-随后是后续状态的最优策略 S

定理(最优性原理) A 策略 π(a|s) *从状态 s 达到最优值,*v _π(s)= v∫(s)当且仅当:

  • 对于从s--可达的任意状态 s '达到最优值

值迭代(应用)

问题 : 求给定 MDP 的最优策略*【π*】*。
:贝尔曼最优备份的迭代应用

方法: 利用同步备份更新价值函数,直到计算出最优价值函数而不计算动作价值函数。

  1. 在每次迭代 k+1 时,对于所有状态 s ∈ S
  2. 更新 vₖ₊₁(s)vₖ(s'),其中*s’*是 s 的后继状态

vₖ(s') 使用第 2 部分中讨论的贝尔曼最优方程进行更新:

Bellman Optimality Equation

通过重复上述过程,最终收敛到 v。*注意,该过程不同于策略迭代,因为中间值函数可能不对应于任何策略。

摘要

这篇文章中描述的所有算法都是强化学习中规划问题的解决方案(这里我们给出了 MDP)。这些规划问题(预测和控制)可以使用同步动态规划算法来解决。

预测问题可以用贝尔曼期望方程迭代 ( 政策评估 )来解决。

控制问题可以用贝尔曼期望方程策略迭代&贪婪 ( 策略改进 )或贝尔曼最优方程 ( 值迭代 )来解决。

参考

如果你喜欢这篇文章,并想看到更多,不要忘记关注和/或留下掌声。

为高速公路上的自动驾驶汽车规划路径

原文:https://towardsdatascience.com/planning-the-path-for-a-self-driving-car-on-a-highway-7134fddd8707?source=collection_archive---------5-----------------------

用数据做酷事!

Car deciding to make a lane change

路径规划是自动驾驶汽车的大脑。这个模块试图复制我们人类在驾驶时的思维和决策——阅读地图,分析我们的环境(其他车辆和行人),并根据安全、速度和交通规则决定最佳行动。

对于我在 Udacity 自动驾驶汽车工程师 Nanodegree 项目第三学期的第一个项目,我实现了一个高速公路路径规划器,以在模拟的多车道和交通的高速公路上驾驶汽车。见下面的 gif 和视频。模拟器为我们提供汽车和交通的当前位置和速度,然后我们将下一个 x 和 y 位置发送给模拟器,这样它就可以将汽车开到那里。目标是驾驶汽车成功地避免任何碰撞,安全地改变车道,保持低于速度限制,但不要太慢,并尽量减少对乘客的冲击。

你可以在我的 Github repo 上找到完整的代码

Highway Path Planning

这是汽车启动,改变速度和车道,避免碰撞的视频。请注意终端是如何为用户显示所有有用信息的。

路径规划是怎么做的?

第一步:分析传感器融合数据,并对其进行有意义的分类

从模拟器中,我们获得模拟器中其他车辆的数据。这些数据包括汽车 id、汽车位置(x 和 y)、汽车速度(vx 和 vy)、汽车 s(沿车道的距离)和汽车 d(沿车道宽度的距离)..我获取了数据,并将模拟器中的所有汽车分为我自己的车道、我的左车道或我的右车道(如果这些车道存在的话)。然后,我计算出决策所需的重要指标。这些是

  • 在我的车道上-到我前面最近的车的距离和最近的车的速度
  • 相邻车道-左侧车道前后最近车辆的距离,右侧车道也是如此

我还确保了——如果我在最左边的车道上,那么我设置 violate_left = 1 来确保我不会左转。类似地,如果我在最右边的车道,那么我设置 violate_right = 1。如果我的车道是空的或者任何其他车道是空的,那么最近的车距被设置为 999

第二步:计算决策成本,选择成本最低的行动
我想到了我的汽车在任何情况下都可能做出的 4 个决策:

1.继续在我的车道上以最大速度行驶

2.继续在我的车道上行驶,但是减速到和前面的车差不多的速度

3.换到左侧车道

4.向右转

我决定为所有这些不同的功能分配成本:
成本功能—在我的车道上继续

  • 如果我的车道上没有车辆,那么成本= 0(记住,我们希望最小化成本,所以这是最好的结果)
  • 如果有交通,但前面最近的汽车>缓冲区(设置为距离差> 50 个单位),则成本= 0
  • 如果前面最近的汽车比缓冲器更近(距离差≤ 50 个单位),则可能发生碰撞,因此成本增加到 50

成本函数—变更为左车道/右车道

  • 如果我们可以转弯的车道不存在,那么碰撞是可能的,因此成本增加到 500
  • 如果车道存在并且可以安全转弯,那么成本= 150(安全转弯定义为最近的汽车前方距离单位为 50,最近的汽车后方距离单位为 12。我通过在模拟器中玩来决定这些数字)
  • 如果车道存在,但转弯不安全,则可能发生碰撞。所以成本= 500
  • 我补充的一个额外条件是,如果前面最近的车是 200+的距离单位(前面的车道有点空),那么这条车道的成本稍微低一些。我这样做是为了让程序可以选择一条车道,如果两条车道都可以安全转弯的话

代价函数——慢行于我的车道

我设定减速的代价= 200。这样做是为了使这个动作不如变道好,但比碰撞好。

在每个实例中,计算与所有决策相关的成本,并且最优决策是具有最小成本的决策

第 3 步:一旦做出决定,确定该决定的目标速度和车道

为了在模拟器中驾驶汽车,我采用了使用其 d 值(指示沿车道宽度的距离的参数)来决定目标车道的方法。通道 1 的目标差值为 2,通道 2 的目标差值为 6,通道 3 的目标差值为 10。因此,根据决定(留在车道上,或左转或右转),我决定了目标 d 值
来控制模拟器中的速度,我使用了 s 增量(表示沿车道长度的距离的参数)..我发现 s 增量越小,汽车越慢,而 s 增量越大,汽车越快。为了以最大速度驾驶,我选择了 0.415 的 s 增量。当我需要在我的车道上刹车时,我根据我前面汽车的速度减少 s 增量。

步骤 4:创建加加速度最小化轨迹

为了获得平稳的驾驶体验,我们应该将加速度的导数——加加速度最小化。本质上,我们应该有更平滑的加速度增加和减少。我这样做是通过存储 s 和 d 参数的先前值,并在许多时间步长内逐渐改变它们。最后,我用样条拟合地图和目标 s 和 d 来决定 next_x 和 next_y 值。这些被发送到模拟器,汽车移动到这个位置。对参数做了一些调整后,汽车在模拟器中平稳地行驶了。

总的来说,这是一次奇妙的经历!

后续步骤

我的代码大部分时间都在模拟器中工作,但仍有一些改进的机会

  1. 在程序中包含行为预测。我们可以通过观察他们相对于车道宽度的 d 位置来预测模拟器中其他汽车的计划吗?

这个想法是,如果另一辆车正在接近其当前车道的右侧,那么它很有可能正计划右转。诸如此类。

2.有时我的车在最左边的车道,中间的车道有车辆,转弯不安全,但最右边的车道是空的。一种更好的逻辑是识别出这一点,并执行一系列快速变道,以到达最右边的车道,而不是在当前车道减速。本质上,该逻辑当前在做出决定时仅查看紧邻的通道

3.我希望有更好的方法来设计加加速度最小化的轨迹,使用讲座中建议的一些数学方法

给我一个❤️,如果你喜欢这个职位:)希望你拉代码,并尝试自己。

其他著述:【https://medium.com/@priya.dwivedi/】T2

PS:我住在多伦多,我希望将职业生涯转向深度学习。如果你喜欢我的帖子,并能把我联系到任何人,我将不胜感激:)。我的电子邮件是 priya.toronto3@gmail.com

参考文献:

乌达城无人驾驶汽车纳米学位——我感谢乌达城、巴斯蒂安·特龙、大卫·西尔弗和其他参与开发这门课程的人给我机会成为他们新的无人驾驶汽车项目的一部分。这是一次非常有趣的旅程。这里的图片和视频参考在课堂上被分享了

植物人工智能—部署深度学习模型

原文:https://towardsdatascience.com/plant-ai-deploying-deep-learning-models-9dda5f6c1088?source=collection_archive---------3-----------------------

所以在我的上一篇中,我谈到了我是如何构建植物 AI 的——一个使用卷积神经网络的植物病害检测模型。最后,我们有了一个模型,将在本文中部署。工厂 AI 的代码可以在这里找到,输出这里找到。

但是一个不能用的模型有什么好?因此,在这篇文章中,我将讲述我是如何通过 API 将这个模型部署到 Android 应用程序中的。

为了通过 API 部署我们训练好的模型,我们将做一些类似于下面的事情:

  • 加载我们的训练模型
  • 接受传入数据并对其进行预处理
  • 使用我们加载的模型进行预测
  • 处理预测输出。

我们可以在生产中以多种方式使用我们的模型,例如:

  • 将它直接加载到我们的应用程序中:这里我们假设您的模型可以与其他应用程序文件一起保存。这允许我们直接加载模型。我们可以通过简单的编写来加载我们的模型

model _ file = pickle . load(open(" CNN _ model . pkl ",' rb '))

或者 model _ file = load _ model(' my _ model . H5 ')

  • 通过 API 使模型可用。这就是我为植物人工智能所做的。有许多方法可以让我们通过 API 获得一个模型。其中一些包括:

用 Django 或 Flask 定制 REST-API:在这种情况下,我们用 FlaskDjango 之一构建一个定制 REST-API。这样,我们必须使我们的模型在我们的项目文件夹中可用,如上所述,加载它并执行预测,然后将结果作为 JSON 响应发送回来。

Tensorflow :我们也可以使用 Tensorflow 部署我们的机器学习模型,使用 Tensorflow 服务。Tensorflow Serving 是为将机器学习模型部署到生产中而开发的,因此它包含用于与 Tensorflow 模型或任何其他模型集成的开箱即用工具。你可以看看这篇关于如何用 Tensorflow 机器学习模型的文章。

AWS Lambda/无服务器:这涉及到使用 AWS Lambda 使你的深度学习模型可用。你可以查看 AWS 文档关于用 Tensorflow 部署深度学习模型的帮助。

另一个选择是利用 Kubernetes 来部署你的模型。你可以查阅 Kubernetes 文档或这篇中型文章来获得如何使用 Kubernetes、Docker 和 Flask 部署深度学习模型的指导

我用 Django — Python Web 框架开发了 Plant AI 的 API。无论您决定使用哪种 Python 框架,过程都应该是相同的。

  • 首先确保您已经安装了这些软件包

Django :一个 python web 框架。使用 Flask 或者你选择的任何其他 Python web 框架都没问题。

Django-Heroku(仅当您将在 Heroku 上托管您的应用时需要)

Django-rest framework**:**构建 web APIs 的强大工具。

guni corn:是一个用于 UNIX 的 WSGI HTTP 服务器。

Numpy:Python 编程语言的库,增加了对大型多维数组和矩阵的支持,以及对这些数组进行操作的大量高级数学函数。(来源:维基百科)

Keras : Keras 是用 Python 编写的开源神经网络库。它能够在 TensorFlow、微软认知工具包或 Theano 上运行。旨在实现深度神经网络的快速实验,它专注于用户友好、模块化和可扩展。(来源:维基百科)

Sklearn :一款免费软件 机器学习 Python 编程语言。它具有各种分类回归聚类算法,包括支持向量机随机森林梯度推进、 k -meansDBSCAN ,旨在与 Python 数值和科学库 NumPy互操作(来源:维基百科)

Django-cors-headers:一款 Django App,为响应添加 CORS(跨源资源共享)头。

  • 设置您的 Django 项目。
  • 接下来,确保您的模型在项目文件的一个文件夹中。你可以在这里下载植物 AI 的模型
  • 下面是我的代码的样子

像往常一样,在线 1–7上,我导入了所需的必要包。

的第 33 行**,我将通过 API 端点发送的数据(base64 中患病植物的图像)保存在 request_data 中。然后在第 34 行我分割数据,只得到图像。然后使用下面的 convert_image 函数将图像转换成一个数组。该函数将返回一个图像数组,或者不返回任何图像数组,如果有错误消息,则返回一条错误消息。**

在下面的第 38 行,我使用 Pickle 加载了生成的模型。然后在第 39 行,我将图像数组传递给模型。这将返回一个二进制化的标签。在我们的项目中加载的标签二进制化器的帮助下,我能够将模型预测转换成任何可用的标签(在这种情况下是各种植物疾病)。

****第 41–43 行包含一个 Python 字典,该字典包含该 API 将要传递的输出。在第 60 行上,这个 dict 作为 JSON 响应被发送回来。是的,就是这样!!!

使用 Postman 测试我的 API,在大约 47312.525 毫秒(47.3 秒)内给出了我想要的结果。

这个项目可以在 Github 这里获得。感谢阅读。

柏拉图、亚里士多德和机器学习

原文:https://towardsdatascience.com/plato-aristotle-and-machine-learning-521c3252cbd1?source=collection_archive---------7-----------------------

雅典学院是世界上最著名的壁画之一。这是一幅描绘古典时代伟大哲学家的文艺复兴杰作,由拉斐尔于 1509-1511 年间创作。

The School of Athens, Fresco by Raphael, 1509–11.

虽然这幅壁画中有很多值得讨论的地方,但我想请大家注意其中的两个中心人物:指向天空的柏拉图和指向大地的他的学生亚里士多德。

Plato (left) and Aristotle (right)

拉斐尔为什么要这样描绘他们?

柏拉图认为我们生活的这个世界,物质世界,只是理想世界的一个影子。例如,我们在这个世界上看到的苹果是理想世界中完美苹果的不完美反映。柏拉图称这些完美或理想的事物为它们的形式,因此有了他的形式理论。形式论不限于对象,我们还可以谈教育的形式,友谊的形式等等。然而,亚里士多德反对他的老师,声称物质世界是真实的。他认为形式存在于正在讨论的事物内部,存在于物质世界中。如果没有苹果,就没有苹果身份。他们都相信形式,但不同意它们是否存在于另一个世界(柏拉图)或这个世界(亚里士多德)。

现在你可能会猜到拉斐尔想要传达的信息,柏拉图指出天空是因为他相信形体在另一个世界,相反亚里士多德指出地球说形体实际上可以在物质世界中找到。

这个讨论属于形而上学中的共相问题的范畴。共性是两个或两个以上的实体所共有的东西(例如,根据柏拉图,是一只猫或理想的猫),一个共性有称为细节的实例。加菲猫是一只特别的猫。他有所有猫共有的属性,像试图适应一个盒子,以及其他属性,不是每只猫都有,如懒惰,愤世嫉俗和橙色。哲学家讨论共相是否真的存在,如果真的存在,它们存在于何处。

但是这一切和机器学习有什么关系呢?在回答这个问题之前,我将尝试从数据、信号和噪声方面解释什么是机器学习。让我们首先澄清这些术语:

数据:您观察或测量的值。

**信号:**观察或测量的期望值。

**噪声:**导致期望值和观察值不同的缺陷。

基于这些定义,我们可以说数据=信号+噪声。让我试着用一个具体的例子来解释这个概念。

你如何绘制一个 m = 2 kg 的物体的力(N)与加速度(m/s)的关系曲线?理想情况下,它应该遵循牛顿第二定律,F = ma。然而,在我们生活的世界中,我们知道事情并不完美。因此,观察到的行为将类似于 F = ma +噪声。下面您可以看到这些图以及用于生成这些图的代码:

m=2 #mass of the object
a=10*np.random.rand(50,1) #50 random acceleration values
F_ideal=m*a #Ideal F
F_observed=m*a+np.random.randn(50,1) #Observed F

Ideal vs. Observed behavior

Data = Signal + Noise

本质上,机器学习算法试图学习数据内部的信号。需要强调的是,给了这些算法数据,但它们不知道数据的哪一部分是信号,哪一部分是噪声。

例如,让我们对上面生成的数据应用线性回归。可以看到拟合度几乎等于信号。机器学习算法不知道我用来生成这些数据的信号,但它能够找到一个非常接近的近似值。

import sklearn
from sklearn import linear_model
model = linear_model.LinearRegression()
model.fit(a, F_observed)

Fit tries to find the signal

现在,我们可以看到机器学习和共性问题之间的对应关系。

**机器学习:**数据=信号+噪声

**共相问题:**我们所见=共相+特殊性质

假设您的朋友要求您构建一个孟加拉猫分类器。您收集孟加拉猫图像(数据),并为此任务训练卷积神经网络(CNN)。该算法查看数据,将信号(通用孟加拉猫)与噪声(特定事物,例如一只猫有伤疤,在另一幅图像中背景处有一棵树等)分开。)因此学会了一只理想的孟加拉猫应该是什么样子。该算法将学习到的内容存储为称为“权重”的参数。换句话说,训练后的 CNN 的权重对应于通用的孟加拉猫——信号。

Blueprint of a Bengal cat (the ideal Bengal cat), is captured by the weights of a CNN. Edges are captured by the first layer, the second layer learns the contours, the third layer learns the eyes, ears, and the tail. Source

这篇文章的关键是,机器学习算法的目标是学习数据中的共性(也称为形式或信号)。希望这能帮助你从不同的角度看待机器学习中的一些概念,并更容易掌握它们。

你可以在推特 @malicannoyan 上找到我。

数据的魔力|泰坦尼克号生存预测

原文:https://towardsdatascience.com/play-with-data-2a5db35b279c?source=collection_archive---------5-----------------------

在我以前的文章中,我们讨论了数据特征以及与之相关的常见问题和挑战,还简要讨论了应该遵循什么方法来处理它。

这些文章从总体上给出了一些关于数据清理过程的想法,让我们尝试一下对真实数据集的理解。为了让事情变得简单有趣,我选择了 Kaggle 下的 泰坦尼克号:机器从灾难中学习竞赛 下的泰坦尼克号生存数据集。

在这个挑战中,我们需要使用 ML 技术来分析人们的生存状况。我将在这个实验中使用 iPython Jupyter 笔记本,人们可以根据自己的舒适度选择使用 R 或其他。

我们先来了解一下可用于预测的目标和数据集。我建议大家阅读下面快照中提到的数据定义或者直接从 Kaggle 页面 中获取。

简而言之,我们有两个数据集,一个用于训练,一个用于测试。 数据集中的生存属性是目标属性。 生存归因在训练数据集中可用,但在测试中不可用,因为我们需要预测同样的结果。最后,我们需要得出一个结果集,其中给定一个来自测试集的 PassengerId,我们应该有生存预测。**

加载训练数据

Loading Training Data

Training Data Set

数据集由 12 个混合了定性(分类)和定量(数字)的属性组成。

定性属性: PassengerId,幸存,Pclass,性别,车票,客舱&上船。
数量属性: SlibSp,Parch &车费。

加载测试数据

这只是为了对测试数据集有个大概的了解。 我们可以观察到,它没有目标属性。

Loading Test Data Set

结果集

Result Set (Need to be produced)

特色工程

让我们检查缺失值上下文中的所有属性。

**

很明显,年龄、船舱和船只是我们唯一缺少价值的属性。

让我们逐一检查每个属性,看看它对训练数据的影响。

PassengerId 是一个名义属性,这意味着如果我们重新分配所有乘客 Id,对数据集没有任何影响,因此我们现在可以忽略它。

幸存下来的是目标属性。

Pclass 是数字属性,它没有任何缺失值,让我们检查它对目标属性的影响。

这里我们取了平均值,这个数据代表 Pclass=1 存活率是 62.96%。

性别属性是值为男性或女性的分类属性,没有缺失值。

雌性更安全 ,雌性存活率比雄性多。

SibSp 是代表兄弟姐妹/配偶的数值属性。

Parch 也是代表孩子/父母的数值属性。

家庭规模

基于 SibSp & Parch 的影响,让我们创建一个名为“家庭规模”的新属性。

这似乎对我们的预测有很好的影响,让我们看看独自在这艘船上会有什么影响。

艾索隆

至少有时独处是好的:)

着手进行

已装载的属性缺少值,填充该属性的最佳方式是使用最常出现的值。在该数据集中,已装载属性最常出现值是' S'。

Fare 是一个数字属性,它也有缺失值。对于票价,用中位数填充缺失值将是比平均值更好的选择。它是一个数值属性,因此我们需要将其转换为分类属性,以便为我们将要使用的 ML 算法做好准备。在这里,我们将票价分为 4 类。

年龄也是一个数字属性,并且有缺失值。填充年龄属性中缺失的值是一件棘手的事情。我们正在生成(平均值 std)和(平均值 + std)之间的随机数,并对其进行填充。我们把年龄分成 5 个范围。

***Name,*我首先想到的是忽略 Name 属性,但是如果仔细观察,就会发现 names 有可能对目标属性产生影响的标题。让我们交叉检查相同的。

到目前为止,我们已经研究了所有的属性,引入了一些新的属性,并填充了缺失的值。现在是准备数据并为 ML 算法做好准备的时候了。

数据清理

在我们当前的数据集中,我们很少有非数字的属性/特征。这是将它们转换成数值的时候了。

  • 性别属性有值(女性/男性),我们分别将其映射到 0/1。
  • 标题新生成的属性被映射到 1/2/3/4/5 值,缺少的值用 0 填充。
  • 基于站台上车,已上车属性被映射到 0/1/2。
  • 四个票价类别映射到四个分类值(0/1/2/3)
  • 五个年龄类别映射到五个分类值(0/1/2/3/4)
  • 删除预测不需要的属性,如乘客 Id、姓名、机票、舱位、SibSp、Parch 等。

下面是结果,现在数据看起来干净。

应用分类器

人们可以对这些数据应用多分类器,在本练习中,我将使用scikit learn内置库。以下是我现在想到的分类器列表。

  • 邻居分类器(3)
  • SVC(概率=真)
  • 决策树分类器()
  • RandomForestClassifier()
  • AdaBoostClassifier()
  • GradientBoostingClassifier()
  • 高斯安 b()
  • 线性判别分析()
  • QuadraticDiscriminantAnalysis()
  • 物流回归()

让我们从 KNeighborsClassifier 开始,并检查其准确性以供参考,我们将使用分层洗牌分裂交叉验证器来分裂训练和测试数据。

KNN Accuracy on Titanic Data Set

拥有 scikit 使所有的工作变得简单,您可以通过编写 3-4 行代码来应用大多数分类器。类似地,我们可以应用分类器列表并比较不同模型的准确性,请查看我的笔记本此处查看 titanic 数据集上分类器列表的完整代码。结果表明,在下表提到的分类器中,SVM 是该数据的最佳分类器。

魔法:预言

现在我们已经准备好了模型,是变魔术的时候了。我们可以使用 SVM 分类器,并通过编写下面的代码来预测测试数据集的存活。

Scikit 你真棒!

由于我们有预测结果,我们可以将其加载到数据框中,并生成所需的输出格式。

C 如果你在这个练习中观察,我们大部分时间花在分析和清理数据上。一旦数据准备好了,就很容易使用不同的分类器,因为市场上有标准的库,一个很好的例子就是 scikit

感谢您的阅读,请在评论中分享您的想法、反馈和想法。你也可以通过推特上的@ simplykk87linkedin 联系我。

R 参考文献

* [## 泰坦尼克号生存预测

使用泰坦尼克号的数据:灾难中的机器学习

www.kaggle.com](https://www.kaggle.com/borntomine/titanic-survival-prediction/notebook)*

操场地球

原文:https://towardsdatascience.com/playground-earth-238f8253b030?source=collection_archive---------17-----------------------

Ep。2:使用分类数据挖掘对活动进行分类

Part of our output today; Network chart visualizing the co-occurrences between our categorical data

你同样喜欢瀑布、海滩、博物馆、食物、山脉、自然、游乐园、水族馆和城市地标还是你对假期有一些偏好?或许你知道。然而,在第一集中,我们客观地将世界上排名第一和第二的活动设定为瀑布..但是如果你不喜欢瀑布呢?你可能已经完成了这篇文章,并且完全不同意我们得出的任何结论。

为了管理我们的主观偏好,我们将需要我们的算法能够按照用户的期望处理类别的有限子集 的输入。由于活动的描述有很多种,我们今天的主要目标是将所有这些种类归纳为“核心”活动的子集。例如上面描述的那些。

很好,听起来我们今天要深入文本分类数据挖掘了!

我们的方法

  1. 首先,我们必须将来自源数据的类别之间的关系创建到一个 共现矩阵中。 这将帮助我们建立最常提到的活动。
  2. 这个矩阵可视化成一个 网络图 并检索每一个共现组合的权重。
  3. 通过查看最高加权类别和(如果需要)人工干预,检索根类别子集
  4. 转换为父子层次 并为每个存在的子类别派生父根类别。从每个孩子开始,每次都是到它的最大权重的父母,直到我们到达一个根类别变量。

数据

对于今天的练习,我们可以完全依靠在第 1 集中已经准备好的数据。来自猫途鹰和谷歌的数据都包括每个活动的一个或多个分类值。这些组合成一个列表,构成我们每个活动的总类别集。

此时,没有必要从其他外部数据源进一步丰富这些数据,我们完全可以从第 1 集停止的地方开始。

概括我们的类别

Fabrica La Aurora, San Miguel de Allende, Mexico — image source http://fabricalaaurora.com

让我们从一个为什么我们的分类数据需要一般化的例子开始:墨西哥圣米格尔德阿连德的 Fabrica La Aurora。从网站上的图片(如上)和信息来看,这是一个很棒的艺术中心,由多个画廊、一些购买艺术相关物品的商店以及一些吃喝场所组成。听起来像是我假期绝对想去的地方,但它在我们的数据中属于哪一类呢:

美术馆;美术馆;咖啡馆;珠宝店;家具店;家居用品店;存储;餐厅;食物;

这些是许多不同的类别,许多重叠的类别(即艺术画廊与艺术画廊),而且类别太广泛,不足以作为我们算法的输入过滤器。而且还有泛化的需要!

在我们 7,044 项活动中,共有 235 个不同类别的 14,806 次提及。这意味着平均每个活动有 2.1 个不同的类别。有了这些数字,我们也可以非常有把握地假设这 235 个类别的多种组合将在多个活动中同时出现(即最有可能的是美术馆将经常与美术馆同时出现)

为了探索当前类别之间的关系,我们将使用一种业余爱好者的方法来研究网络理论。最终目标是导出根值(最常发生的活动)和它们与较少发生的活动的链接(将它们作为叶子映射到它们的根)。

为此,我们首先需要创建一个共生矩阵。顾名思义,这意味着我们为 235 个类别中的两个类别的所有可能组合创建一个出现次数矩阵。

这种共现矩阵在网络图中最直观,该图将显示我们的类别之间的联系,还将显示最常见的共现活动和联系:

Fig. 1 Network chart of all our activities’ mentioned categories; Created with Gephi

从这张图表中,我们可以立即看到一些最常出现的关键类别:食物、公园、博物馆、商店、餐馆、历史遗迹、自然景观等等。

还有一些联系相当清楚:'礼拜场所'显然与'教堂'、清真寺'、'印度教寺庙神圣的&宗教场所'联系在一起,但也与'建筑'联系在一起;而'商店'、餐厅'、咖啡馆'、酒吧'和'美食'也经常齐头并进。

目标是定义一个可管理的根类别子集,通过这些共现,所有其他类别都可以与之相关联。

Fig. 2 Root categories

为了建立这些初始根类别,我们将使用图表后面返回的相关表,该表包括每个可能的类别组合的出现权重。

查看每个活动聚集的权重值的分布,我们将从筛选权重> 200 的类别开始。这将把我们带到图 2 左侧显示的根活动。

我们将这些类别中的每一个都映射到一个友好的名称,这个名称为我们提供了 12 个不同的类别,我们现在将这些类别视为我们的根类别子集,以进行进一步的分析。

下一步是为上面列表中的而不是的所有 235 个类别导出相关的根类别。为此,我们可以构建一个父子层次结构,并基于权重遍历所有类别,直到我们到达第一个根值。

换句话说,让我们寻找不在上面列表中的每个类别,根据权重它与哪个类别最同时出现,如果该活动不在根中,我们将再次寻找它最同时出现的类别,并且继续,直到我们找到在根中的类别。

下面的例子将告诉你这是如何工作的。在这种情况下,我们希望找到类别“露营地”的根类别。结果是''(注意,当应用相等的权重时,以字母顺序为准):

Fig. 3 relation tree for category ‘Campground’ ending into root category ‘Park’

将这个转换应用到每一个类别,将会为每一个活动提供一个(或者多个)根类别。

所以回到 Fabrica la Aurora 为例;最初,我们看到谷歌/猫途鹰联合推出了以下类别:

美术馆;美术馆;咖啡馆;珠宝店;家具店;家居用品店;存储;餐厅;食物;

上述实施转换的结果分别概括为以下根类别:

博物馆和画廊;博物馆和画廊;食物和饮料;购物;购物;购物;购物;食物和饮料;食物和饮料;

或者说,应用唯一性的时候:博物馆&画廊,购物美食&饮品。还不错!这意味着,只要上述三个类别中的*任何一个(或全部)*作为输入给出,该活动就会包含在算法的输出中。

在这一步之后,让我们为这些自动派生的根活动中的每一个补充将被过滤的活动数量的平衡:

Fig. 4 number of activities per root category, produced with Seaborn

手动干涉

这种做法显然不防水,所以这里我想手动干预一些类别。让我们更详细地看看四个主要类别和'其他'类别(我们希望尽可能小)的子类别。

Fig. 5 Overview of all remaining categories to be mapped

在左边我们看到这些子类别;我想手动修改的,我在这里突出显示了。

首先,让我们将“海滩”和“山脉”从“自然”中分离出来,分别放入新的根类别中。尽管这种分配可以被认为是准确的(对自然而言),但它们是假日如此重要的特征,以至于它们本身应该是根类别。

第二,我们看到一些错误分配的类别,这些类别可以归为一个新的类别'地标,包含子类别:'名胜古迹&地标','建筑','城堡'和'古迹&雕像'

最后,在' other '中的子类别' neighborhood '具有足够的权重来单独作为一个类别而不是其他类别。所以我们也将单独映射它。

做了这些调整后,我们最终得到了 16 个最终根类别,并由此产生了以下数量的与之相关的活动:

Fig. 6 final number of activities per root category, produced with Seaborn

因此,从我们的 235 个不同的类别中,我们成功地将它们归纳为 16 个不同的类别。我们只需手动干预这 235 项活动中的 7 项!我对结果很满意,让我们的最终算法能够轻松地过滤输入类别中的旅游活动。

把我们的分数加进去

现在我们有了我们的活动,我们可以回到我们在第 1 集中创建的评分标准,并将两者结合起来。我们已经了解了按地区、国家和个人活动划分的加权平均分,现在让我们来看看哪些是评分最高的类别:

Fig. 7 score per category barplot produced with Seaborn

山脉绝对是我们最喜欢的(我个人非常同意)。紧随其后的是稍远处的水体、历史遗迹和自然景观。

由于图片胜过千言万语,让我们来看看每个类别中的前 3 项活动:

Top 3 mountains: #1 Table Mountain, Capetown, South Africa | #2 Serra de Tramuntara, Mallorca, Spain | #3 Aguille du Midi, Chamonix, France

Top 3 bodies of water: #1 Jokulsarlon Lagoon, Iceland | #2 Lagunas Miscanti y Miniques, San Pedro de Atacama, Chile | #3 Moraine Lake, Lake Louise, Canada

Top 3 historic sites: #1 Jerusalem Old City, Jerusalem, Israel | #2 Angkor Wat, Siem Reap, Cambodia | #3 St. Peter’s Basilica, Vatican City, Italy

Top 3 nature: #1 Niagara Falls, Canada | #2 Iguazu Falls, Foz do Iguacu, Brazil | #3 Table Mountain, Capetown, South Africa (yes, again)

嗯,我刚刚用这些发现更新了我的遗愿清单!

乍一看,对我们的概括结果的准确性感到非常惊喜。以及就地区和大陆而言,顶级类别中的巨大多样性。

结论

今天,我们已经成功地利用网络理论的基本形式,将我们所有的 235 个不同类别归纳为 16 个。为了以简化的方式过滤活动,同时仍然能够让算法只选择相关的活动,这是非常重要的。

下一篇文章,我们将关注聚集我们在实际度假目的地的活动!

要进一步了解,请查看下面的热图,比较每个地区的最佳得分活动:

Fig. 8 Heat map produced with Seaborn in Python

关于我自己的更多信息,请随时查看我的 LinkedIn

用 6 个神经元玩雅达利|开源代码

原文:https://towardsdatascience.com/playing-atari-with-6-neurons-open-source-code-b94c764452ac?source=collection_archive---------12-----------------------

#2 研究论文讲解

这篇论文为机器学习社区打开的大门是惊人的。这个微小的网络实际上玩的是 Atari 游戏,只有 6 个神经元相当,偶尔还会更胜一筹,让以前的网络看起来像笑话。最棒的是,代码在 GitHub 上是开源的,每个人都可以玩。所以,让我们开始吧…

SOURCE

怎么可能!!!

我们已经知道,玩 atari 游戏的深度强化学习网络基本上是一个密集的深度神经网络既有又有的职责,通过将像素映射到中间表示(也称为特征提取)内部学习从图像中提取特征,允许最后(少数)层将这些表示映射到动作和策略或决策。

因此,两者是同时学习的,这使得分开研究政策几乎是不可能的。

Source

因此,仅仅通过将表示学习部分从策略学习部分中分离出来,就可以使网络免于构建中间表示,从而使其能够专注于策略逼近,该策略逼近是根据通过交互获得的观察结果在线训练的。

本文有助于在复杂 RL 设置中同时学习功能而分别学习功能

这使得一个较小的政策网络更具竞争力,并以更复杂的方式解决问题。

我们可以通过将它们分成两个不同的网络来更好地控制学习。

学习特征提取

本文采用了两种新的方法来训练网络:基于矢量量化的方法称为增加字典(VQ) 和基于稀疏编码的方法称为直接残差 SC

让我们看一些命令行程序来快速理解基本概念,然后我会在文章的后面解释新的东西。

矢量量化是一种神经网络算法,用于通过使用称为字典的矢量列表来学习二元或多元分类。

**注:**我鼓励你进一步学习 矢量量化稀疏编码 以便更好的理解。

学习决策政策

使用能够应对维度增长的专门版本的指数自然进化策略来训练策略。

让我们建立系统💻

现在让我们了解一下他们是如何实现这篇论文的。我们的系统可以编码成 4 的简单步骤:

1.环境👾

该系统建立在 Atari 2600 的 OpenAI 框架上,具有原始控制台的所有限制。观测值由一个[210×180×3]张量组成,代表屏幕输入的 RBG 像素。

网络的输出被解释为 18 个离散动作中的一个,代表来自操纵杆的潜在输入。跳帧次数固定为 5。

2.压缩机💼

你也可以称之为预处理器。

压缩器是一个神经网络,当与环境交互时,它以一种在线方式从观察中提取低维代码。

为了获得在线学习的最佳性能,本文采用了两种新的方法,并将它们结合在一起。

增加字典矢量量化

这个版本的 VQ 增加了字典的大小,不像矢量量化有固定的字典大小。

字典大小的增长由阈值δ调节,指示被认为是有意义的增加的最小聚集残差。

直接残差稀疏编码

基于字典的算法的性能更多地取决于编码而不是字典训练。因此,为了提高 IDVQ 的性能,使用了直接剩余 SC。详细解释请点击此处

3.控制器🎮

所有实验的控制器都是单层全连接递归神经网络(RNN)。

每个神经元通过加权连接接收以下输入:网络的输入、来自先前激活的所有神经元的输出(最初为零)和恒定偏置(总是设置为 1)。

输入的数量在任何给定的时间点都等于来自压缩机变化输出的代码的大小。

输出层中的神经元数量保持等于每个游戏的动作,如 ALE 模拟器所定义的。这在一些游戏中低至 6,最多 18。

4.【计算机】优化程序🚀

优化器是我们的学习算法,随着时间的推移提高网络的性能,在这种情况下,一种称为...

指数自然进化策略💁论文

自然进化策略是一个进化算法家族,它控制着个体的显式种群参数。

结果

下面给出了在 OpenAI 的 ALE 框架上,从数百个可用游戏中选出的 10 个 Atari 游戏的比较结果。

他们将他们的工作与最近的两篇论文进行了比较,这两篇论文提供了 Atari 游戏的广泛结果。

RESULTS

结论

我们提出了一种在强化学习任务(如 Atari 游戏)中学习视觉控制有效策略的方法,该方法使用比通常用于这些问题的深度神经网络小两个数量级的微小神经网络。

这是通过将策略学习与特征构建分离来实现的。

特征构造是在网络外部通过一种被称为递增字典矢量量化的新颖且有效的矢量量化算法来执行的,该算法是根据网络与环境的交互所获得的观测值来在线(即沿着网络)训练的。

如果你喜欢拍拍与社区分享这个的解释。关注我的 MediumTwitter 以获取更多# 研究论文解释通知…

如果你对这篇论文有任何疑问,或者想让我解释你最喜欢的论文,请在下面评论。

你会喜欢的以前的故事:

[## DeepMind 惊人的混搭 RL 技术

2018 年 6 月发布的研究论文解释

hackernoon.com](https://hackernoon.com/deepminds-amazing-mix-match-rl-techique-a6f8ce6ac0b4) [## 纪元与批量大小与迭代次数

了解您的代码…

towardsdatascience.com](/epoch-vs-iterations-vs-batch-size-4dfb9c7ce9c9) [## 50 tensor flow . js API 5 分钟讲解| TensorFlow.js Cheetsheet

TensorFlow API Cheetsheet

towardsdatascience.com](/50-tensorflow-js-api-explained-in-5-minutes-tensorflow-js-cheetsheet-4f8c7f9cc8b2) [## 激活函数:神经网络

Sigmoid,tanh,Softmax,ReLU,Leaky ReLU 解释!!!

towardsdatascience.com](/activation-functions-neural-networks-1cbd9f8d91d6) [## 手机上的 TensorFlow:教程

在 Android 和 iOS 上

towardsdatascience.com](/tensorflow-on-mobile-tutorial-1-744703297267)

华盛顿特区自行车共享需求的预言家游戏(上)

原文:https://towardsdatascience.com/playing-with-prophet-on-bike-sharing-demand-time-series-1f14255f7ff0?source=collection_archive---------2-----------------------

更新:此处 勾选本文第二部分

最近,我发现脸书发布了一个名为 Prophet 的时间序列预测工具。它对 R 和 Python 都可用。

[## 先知

Prophet 是一个用 R 和 Python 实现的预测程序。它速度很快,并提供完全自动化的预测…

facebookincubator.github.io](https://facebookincubator.github.io/prophet/)

根据官方网站:

“它(Prophet)基于一个加法模型,非线性趋势与每年和每周的季节性以及假期相适应。它最适用于具有至少一年历史数据的每日周期数据。Prophet 对缺失数据、趋势变化和较大的异常值具有稳健性。”

更多细节,我建议阅读论文快速入门指南。

我想尝试一下这个新包,并决定使用两年前在华盛顿特区举行的与预测自行车共享需求相关的 Kaggle 比赛的数据集

这个项目的所有代码都可以在这个 repo 中获得。

数据

数据集包含几个特征,包括:

  • 日期-时间
  • 假日(作为一个二元变量,表示该日是否被视为假日)
  • 天气状况(一个有 4 类的分类变量)
  • 温度
  • 湿度
  • 风速
  • 自行车租赁总数

该数据集提供了跨越两年(2011 年和 2012 年)的每小时租金数据。对于比赛来说,训练集由每月的前 19 天组成,而测试集则是每月的第 20 天到月底。目标是仅使用租赁期之前的可用信息,预测测试集覆盖的每小时租赁的自行车总数。

因为数据来自一场比赛,测试集不包含租赁自行车的总数,所以对于这个实验,它不能用于评估模型的性能。另一个问题是,Prophet 最适合每日周期数据,所以我必须将数据从每小时转换为每天。

从上面的特性中,我们感兴趣的是日期时间、假期和自行车租赁的总数。

设置

我用的是 r 的 Prophet 包。文档写得很好,提供了几个学习如何使用 Prophet 的例子。据此,有几个易于解释的参数,允许用户改进或调整预测。虽然默认的参数值可以很好地开始工作,但是我想使用非穷举的网格搜索来确定最佳的参数值。

首先,我决定将竞赛网站提供的训练集分成三部分:2011 年全年用于模型拟合,2012 年上半年作为参数调优的验证集,2012 年下半年作为检验所选模型性能的测试集。虽然我们没有整个月的数据,但这似乎不是 Prophet 软件包的问题,因为它对丢失的数据很健壮。

假日特性是一个二元变量,它只告诉我们日期是否是假日,但不提供它所指的是哪个假日的信息。我不得不做一些研究来确定这些日期,因为 Prophet 使用这些信息来正确地确定特定节日的贡献(这是非常有用的)。我使用了这个网站,它包含了美国联邦假日的详细信息。

最后,需要一些调整的参数与我们希望给予模型的灵活性有关,以适应变化点、季节性和节假日。进行非详尽的网格搜索只是为了对参数的最佳值有一个模糊的概念。如果用户对手头的任务有一些专业知识,可以跳过这一步。

模型

使用平均绝对误差(MAE)作为性能度量来执行网格搜索,以识别最佳参数。

找到的最佳参数是:

  • 运载能力:8000 人
  • 改变点先验比例:0.5
  • 季节性先验标度:10
  • 假日优先比例:1

然后,在训练集和验证集上使用这些参数重新训练该模型。

确定的最佳模型的建模和预测自行车共享需求时间序列如下所示。可见大势已被捕捉。

Modeled and predicted bike sharing demand time series using the Prophet package.

此外,Prophet 还提供了绘制时间序列中不同部分的功能。这些显示如下,可以观察到一些有趣的事情。首先,似乎有些节日会增加租赁数量(如独立日-7 月 4 日),而其他节日则会减少(如元旦)。第二,租金记录较少的一天是星期三。此外,随着周末的临近,租金往往会上涨,周六达到最高。最后,一年中,夏季月份的租赁次数往往高于冬季月份。

Time series components identified using the Prophet package.

最后,剩下的唯一事情是在测试集上观察模型的性能。下面显示了用于绘制它的代码。总的来说,我们可以说这个模型在预测方面做得很好。

Modeled and predicted bike sharing demand time series using the Prophet package. The black points correspond to the training set, the green ones to the validation set, and the red ones to the testing set.

评论

经过训练的最终模型似乎能够很好地捕捉总体趋势。我对 Prophet 软件包的易用性和用户可获得的灵活性印象深刻。

这只是一个小项目,有几件事可以考虑改进它:

  • 使用原始的每小时数据集,而不是每天数据集。
  • 将其余特征(天气和环境变量)纳入模型。这可以提供额外的信息,用于做出更好的预测。
  • 纳入 NARX 建模方法,以包括外生变量。
  • 为参数调整执行贝叶斯优化。
  • 为正确的模型选择执行模拟历史预测。

更新:查看本文第 2 部分 此处

在 python 中处理时间序列数据

原文:https://towardsdatascience.com/playing-with-time-series-data-in-python-959e2485bff8?source=collection_archive---------0-----------------------

时间序列是日常生活中最常见的数据类型之一。股票价格、销售额、气候数据、能源使用量甚至个人体重都是可以定期收集的数据示例。几乎每个数据科学家都会在工作中遇到时间序列,能够有效地处理这些数据是数据科学工具箱中的一项重要技能。

这篇文章是开始使用 python 处理时间序列的快速介绍。这包括时间序列的小定义和一些数据操作,使用熊猫访问伦敦家庭的智能电表能耗数据。这篇文章中使用的数据可以在这里检索。我在我认为有用的地方添加了代码。

让我们从基础知识开始,时间序列的定义:

*时间序列是按时间顺序索引、列出或绘制的数据点的集合。*最常见的是,时间序列是在连续的等间隔时间点获取的序列。因此它是一个离散时间数据序列。

时间序列数据是围绕相对确定的时间戳组织的;因此,与随机样本相比,可能包含我们试图提取的额外信息。

装载和处理时间序列

数据集

举个例子,让我们用 2011 年 11 月至 2014 年 2 月间参与英国电力网络领导的低碳伦敦项目的伦敦家庭为样本,使用一些以千瓦时(每半小时)为单位的能耗数据。我们可以从制作一些探索性的图开始,最好是了解结构和范围,这也将使我们能够寻找最终需要纠正的缺失值。

在这篇文章的剩余部分,我们将只关注日期时间千瓦时列。

重采样

让我们从简单的重采样技术开始。重采样包括更改时间序列观测的频率。您可能对时间序列数据的重采样感兴趣的一个原因是要素工程。事实上,它可以用来为监督学习模型的学习问题提供额外的结构或洞察力。pandas 中的重采样方法与其 groupby 方法类似,因为本质上是按特定的时间跨度进行分组。然后,您可以指定重新采样的方法。让我们通过看一些例子来使重采样更加具体。我们将从每周总结开始:

  • data.resample()将用于对数据帧的 kWh 列进行重新采样
  • “W”表示我们希望按周重新取样。
  • sum()用于表示我们需要这段时间内的总千瓦时。

对于每日摘要,我们可以做同样的事情,对于每小时摘要,我们可以使用 groupby 和 mean 函数:

为了进一步进行重采样,pandas 提供了许多内置选项,您甚至可以定义自己的方法。以下两个表分别显示了表周期选项和一些可用于重采样的常用方法。

附加探索

以下是您可以利用这些数据进行的一些探索:

用先知造型

脸书 Prophet 于 2017 年发布,可用于 Python 和 r。Prophet 旨在通过显示不同时间尺度上的模式的日常观察来分析时间序列。Prophet 对缺失数据和趋势变化非常稳健,通常能够很好地处理异常值。它还具有高级功能,可以对节假日对时间序列的影响进行建模,并实现自定义的变点,但我将坚持使用基本功能来建立并运行模型。我认为 Prophet 可能是快速预测的好选择,因为它有直观的参数,可以由具有良好领域知识但缺乏预测模型技术技能的人调整。关于先知的更多信息,读者可以在这里查阅官方文档

在使用 Prophet 之前,我们将数据中的列重命名为正确的格式。日期列必须名为' ds ,我们要预测的值列必须名为' y '。在下面的例子中,我们使用了每日汇总数据。

然后我们导入 prophet,创建一个模型并拟合数据。在 prophet 中,change point _ prior _ scale参数用于控制趋势对变化的敏感程度,数值越高越敏感,数值越低越不敏感。在试验了一系列值之后,我将这个参数从默认值 0.05 设置为 0.10。

为了进行预测,我们需要创建一个所谓的未来数据框架。我们指定要预测的未来时间段的数量(在我们的例子中是两个月)和预测的频率(每天)。然后我们用我们创建的预言家模型和未来的数据框架进行预测。

这很简单!未来数据框架包含未来两个月的估计家庭消费。我们可以用一个图来形象化这个预测:

黑点代表实际值,蓝线表示预测值,浅蓝色阴影区域表示不确定性。

如下图所示,不确定性区域随着我们未来的进一步发展而增长,因为初始的不确定性会随着时间的推移而传播和增长。

Prophet 还允许我们轻松地可视化整体趋势和组件模式:

年度模式很有趣,因为它似乎表明家庭消费在秋季和冬季增加,在春季和夏季减少。直觉上,这正是我们期望看到的。从每周趋势来看,周日的消费似乎比一周中的其他几天多。最后,总体趋势表明,在缓慢下降之前,消费增长了一年。需要进一步的调查来试图解释这一趋势。在下一篇文章中,我们将尝试找出这是否与天气有关。

LSTM 预测

长短期记忆递归神经网络有希望学习长序列的观察结果。这篇名为“理解 LSTM 网络”的博客文章以一种简单易懂的方式很好地解释了潜在的复杂性。这是描绘 LSTM 内部细胞结构的图像。

Source: Understanding LSTM Networks

LSTM 似乎非常适合时间序列预测,事实也可能如此。让我们再次使用我们的每日汇总数据。

LSTMs 对输入数据的比例很敏感,特别是在使用 sigmoid 或 tanh 激活函数时。通常,将数据重新调整到[0,1]或[-1,1]的范围内是一种好的做法,也称为规范化。我们可以使用 scikit-learn 库中的 MinMaxScaler 预处理类轻松地规范化数据集。

现在,我们可以将有序数据集分为训练数据集和测试数据集。下面的代码计算拆分点的索引,并将数据分成训练数据集,其中 80%的观察值可用于训练我们的模型,剩下的 20%用于测试模型。

我们可以定义一个函数来创建新的数据集,并使用该函数来准备用于建模的训练和测试数据集。

LSTM 网络期望输入数据具有特定的数组结构,其形式为:[样本、时间步长、特征]。

我们的数据目前以[样本,特征]的形式出现,我们将每个样本的问题框定为两个时间步。我们可以将准备好的训练和测试输入数据转换成预期的结构,如下所示:

仅此而已!现在,我们已经准备好为我们的示例设计和安装我们的 LSTM 网络。

从损失图中,我们可以看到,该模型在训练和测试数据集上都具有相当的性能。

在下图中,我们看到 LSTM 在拟合测试数据集方面做得非常好。

集群

最后但同样重要的是,我们还可以对样本数据进行聚类。有相当多不同的方式来执行集群,但是一种方式是分层地形成集群。您可以通过两种方式形成层次结构:从顶部开始并拆分,或者从底部开始并合并。我决定在这篇文章中看看后者。

让我们从数据开始,我们简单地导入原始数据并添加两列,分别表示一年中的某一天和一天中的某一小时。

连锁和树状图

链接函数获取距离信息,并基于相似性将对象对分组到聚类中。这些新形成的集群接下来相互连接,形成更大的集群。重复该过程,直到原始数据集中的所有对象在分层树中链接在一起。

要对我们的数据进行聚类:

搞定了。!!这很简单,不是吗?

嗯,当然是,但是“病房”是什么意思,它实际上是如何工作的?正如 scipy linkage 文档告诉我们的,ward 是可以用来计算新形成的星团之间距离的方法之一。关键字“ward”使链接功能使用 Ward 方差最小化算法。其他常见的链接方法,如单一、完整、平均和不同的距离度量,如欧几里德、曼哈顿、汉明、余弦,也可以使用。

现在让我们来看看这种层次聚类的所谓树状结构。树状图是聚类的层次图,其中条形的长度表示到下一个聚类中心的距离。

哇哦。!!!!!如果这是你第一次看到树状图,那看起来很吓人,但是不要担心,让我们来分析一下:

  • 在 x 轴上你可以看到标签。如果你没有指定其他的东西(比如我),它们就是你的样本在 x 轴上的索引。
  • 在 y 轴上你可以看到距离(在我们的例子中是沃德方法的距离)。
  • 水平线是聚类合并
  • 垂直线告诉您哪些分类/标签是形成新分类的合并的一部分
  • 水平线的高度告诉您形成新的集群需要“桥接”的距离

即使有了解释,之前的树突还是不明显。我们可以切掉一点,以便更好地查看数据。

好多了,不是吗?查阅凝聚集群文档以了解更多信息并使用不同的参数。

参考资料和进一步阅读:

季后赛勒布朗

原文:https://towardsdatascience.com/playoff-lebron-40ff6f1630fb?source=collection_archive---------11-----------------------

近年来,NBA 球队在比赛的许多方面变得更加聪明,一个主要的例子是球员在漫长而艰苦的常规赛中休息和调节的重要性。

这导致越来越多的人猜测,NBA 的一些大牌球星在整个常规赛中都处于“巡航控制”状态,在季后赛“按下开关”之前等待时机。自我标榜的“季后赛-P”角色(俄克拉荷马雷霆队的保罗·乔治)表明,球员们意识到了这种看法,但真正让我质疑的是勒布朗·詹姆斯迄今为止在东部季后赛中的主导表现——推动一支看似毫无生气的骑士队进入了东部决赛——勒布朗是否真的在季后赛中比常规赛运转得更好,这是最近的现象还是球员们在职业生涯后期可能会做的事情,以延长他们的寿命。

那么,“季后赛勒布朗”是真的吗?为了进一步调查,我在数据中做了一些挖掘。

将一些基本的和高级的统计数据分为常规赛和季后赛,然后只限制给定球员进入季后赛的赛季,我们可以从职业生涯的平均数据开始。绘制一组选定球员的常规赛和季后赛 PER ( 球员效率等级)的差异(注意:不是所有球员!),我们看到以下内容:

看来季后赛对球员效率的要求很苛刻!应该指出的是,有许多更先进的方法来区分常规赛和季后赛之间的差异,但这些是球员在常规赛和季后赛之间的 PER 的原始差异。

如果我们看看另一个高级统计,BPM ( 框加减),我们可以开始看到一些明显的区别:

从这几个图表来看,勒布朗、迈克尔·乔丹和拉塞尔·维斯特布鲁克真的会出现在季后赛中!也许与流行的观点相反,克里斯·保罗在我们的季后赛排名中也有很高的评价——事实上,他有历史上最高的季后赛 per,但一些高调的失误玷污了他的季后赛声誉。

原始得分数据呢?嗯,你可能已经猜到了,乔丹在这里是一个非常明显的领跑者,在季后赛中每场得分比常规赛多 3 分以上:

尽管一些球员得分上升,他们的得分效率在季后赛中如何转化?为此,我选择了 eFG% ( 有效投篮命中率),尽管真实投篮命中率可能会得出类似的结果:

有一种普遍的看法认为,比赛在季后赛中会变慢,变得“更丑”。这是因为团队有更多的时间和动力去侦察和制定游戏计划,特别是去关闭他们的对手人员和最喜欢的场景。对方球队甚至可以刺激明星球员只采用效率最低的投篮类型,导致整体投篮效率下降。有趣的是,常规赛的效率之王——克里斯·保罗——在季后赛中奇迹般地拥有稍高的eFG %!上帝,这才是重点。

对于其他人来说,效率的下降也可能是由于单个玩家工作量的变化。我们知道,在季后赛中,轮换时间大大缩短,明星球员尽可能多地留在场上。让我们看看这在数据中是否突出:

看起来一些有史以来最好的球员在季后赛中被更多的使用,乔丹和勒布朗每场比赛都获得了更高的上场时间。

球员处理球的时间有多长,或者他们在球场上消耗了多少财产?这可以在 USG% ( 使用率)中说明:

虽然勒布朗的使用率在季后赛中没有明显增加,但这可能是因为他在常规赛中的使用率已经非常高了,因为他在职业生涯的大部分时间里一直担任名义上的“控球后卫”。有趣的是,我们看到在我们的球员组合中,传统控卫(即克里斯·保罗、拉塞尔·维斯特布鲁克和史蒂夫·纳什)的使用量大幅上升——这是他们试图作为球队的首席调解人来做所有事情,还是季后赛期间进攻或防守理念战略差异的结果?有趣的是,许多得分后卫(如科比、詹姆斯·哈登、韦德、斯蒂芬库里)的使用率都下降了。在季后赛中,对手会更有效地阻止他们吗?像往常一样,蒂姆邓肯仍然是一致性的典范,无论在一年中的哪个季节,他都几乎没有改变他那令人难以置信的发挥!

最后,我想看看他们在整个职业生涯中,季后赛表现和常规赛表现之间的差异是如何演变的,而不是看球员的职业生涯平均值。人们常说,年轻球员在季后赛中挣扎,而老将被认为在季后赛中茁壮成长。我们对明星球员的分析证明了这一点吗?让我们先来看看 PER 数字:

尽管由于单个球员在一个赛季中参加的季后赛次数相对较少,数据存在较大差异,但随着球员的发展,似乎有明显的上升趋势。对于我们选择的超级巨星来说,他们 27-28 岁的赛季似乎代表了一个转折点,他们在季后赛的表现开始超过他们在常规赛的表现。这可能是因为季后赛的舒适度增加了,常规赛的方式更放松了,或者更有可能是两者的结合!然而,迈克尔·乔丹 22 岁的季后赛和勒布朗·詹姆斯 24 岁的季后赛真的很突出。让我们看看 BPM 数字来证实这一影响:

根据这个标准,看起来 MJ 在季后赛中一直都很棒——没有什么好惊讶的!不像飘忽不定的“Vino”,看起来勒布朗像一瓶好酒一样老化,自从他 27 岁的赛季以来,他的季后赛平均 BPM 通常超过他的常规赛数字。

他能保持这种状态多久还有待观察,但与此同时,看起来“季后赛勒布朗”绝对还活着&很好!(季后赛)王者万岁!

用于分析的完整代码可用 此处

在 3D 中绘制决策边界—逻辑回归和 XGBoost

原文:https://towardsdatascience.com/plotting-decision-boundaries-in-3d-logistic-regression-and-xgboost-e68ce0535b4b?source=collection_archive---------7-----------------------

View from Mt. Timpanogos trail, UT, photo by myself

把机器学习模型想象成一个函数——数据帧的列是输入变量;预测值是输出变量。这个函数的水平集(或 coutour)在 ML 术语中称为决策边界

有很多关于划分决策界限的在线学习资源。比如下面这张取自 sklearn 文档的图,就挺受欢迎的。图中 x 轴和 y 轴变量代表数据帧的两个特征(变量),颜色代表预测值。

http://scikit-learn.org/stable/auto_examples/classification/plot_classifier_comparison.html

最近,来自脸书的 Brandon Rohrer 制作了一个视频展示决策树是如何工作的。看完之后,读者可能会对决策界限有更好的认识。

虽然已经有相当多的学习资源了,但我相信一个好的互动 3D 情节肯定会帮助读者获得对 ML 模型的直觉。这里我挑选两个模型进行分析: Logistic 回归,易于训练和部署,在很多领域都是常用的; XGBoost ,梯度增强树家族(gradient boosting,LightGBM 等)领先的 ML 算法之一。).

(这次跳过了随机森林,因为只有两个特征被用作可视化目的的模型输入,我不知道如何从仅有的两列中随机选择任何有意义的列。)

开始之前的一些注意事项

Dataset 1, 2, and 3

  • 红点是标签为 1 的行,蓝点是标签为 0 的行。
  • 表面图是由相应的 ML 模型生成的函数。
  • x 轴和 y 轴变量都用作输入变量(要素),z 轴变量表示散点图的真实值或表面图的预测值。
  • 在下面的交互式可视化中,圆点不会显示,直到你拖动图形。
  • 为了了解这些情节是如何创造的,一个不错的学习资源是斯特凡·尼克的 d3 积木:https://bl.ocks.org/Niekes

数据集 1

对于逻辑回归图,点击此处

对于 XGBoost 图,点击此处的。

对于这个玩具数据集,两个模型都非常适合训练集。但实际上,数据永远不会是这个样子。

数据集 2

对于逻辑回归图,点击此处

对于 XGBoost 图,点击此处

逻辑回归可以捕捉线性,但不能捕捉单调性。另一方面,许多基于树的模型可以在这个数据集中表现良好。

数据集 3

对于逻辑回归图,点击这里

对于 XGBoost 图,点击这里

这些数据更加混乱,看起来更像真实世界的数据。在这种情况下,逻辑回归只能捕获数据分布的大致趋势,但不能识别阳性或阴性病例密集的关键区域。另一方面,XGBoost 可以识别关键区域,并且还可以避免在正反例都密集的区域上过度拟合。

为什么 XGBoost 决策边界看起来像这样?

XGBoost 算法是梯度提升树算法的一种。它首先生成一个优化目标函数的决策树(更准确地说,是目标函数的二阶泰勒近似,带有额外的正则化项),然后将每棵树乘以一个常数(学习率)。下一棵树如何生长是基于所有先前的树,加上目标函数的效果。

因为每个决策树是特征空间的一个分区,其中每个区域具有不同的输出值,所以这些树的任何线性组合仍然是特征空间的一个分区。当模型中使用更多的树时,我们将得到更好的划分。

曲线拟合

许多机器学习专家表示,ML 只是曲线拟合(1-D 中的曲线,更高维度中的曲面)。从这些例子中,我们可以看到模型是以“适合”这些点的方式创建的。

模型性能不仅取决于“曲线”与训练数据集的拟合程度,还取决于测试数据的分布与训练数据的分布有多接近。如果训练数据和测试数据差异很大,并且您有一个非常“适合”训练数据的模型,这意味着该模型“过度适合”。

感谢阅读。

误用雷达图来区分多维数据

原文:https://towardsdatascience.com/plotting-in-many-dimensions-382fbd7fe76e?source=collection_archive---------1-----------------------

常见的图表以二维或三维的形式显示数据,但除此之外呢?(对于不耐烦的人:滚动到底部观看演示和一些代码)

一位同事最近带着一个问题来找我:他们正在开发一个点击式工具,通过将一组节点放置和连接在一起并创建一个图表,帮助用户可视化地设计系统。每个节点有许多(大约 30–40 个)不同的可配置设置,通常有不同的可能值:一些是数字,一些是布尔,一些是分类。

How is “Da” different than the other “Da”s?

问题是,查看每个节点并不能告诉您任何关于它的设置的信息,并且查看每个节点的许多设置的列表是非常耗时和令人沮丧的。我们如何让不同类型设置的节点一眼就能区分开来?

当我们有更多的维度,并且数据点具有不可比较的特征时(例如,每个变量可能有不同的最小值/最大值,一些可能是分类的,一些是数字的,等等),视觉上区分数据变得更加困难。

下面是用条形图网格绘制多维图的样子:

Source: “Visualization of Food-Based Dietary Guidelines”, Koening

在我们的例子中不同的是,我们的远不止 3 个参数,也就是说,每个图表中有更多的条形。最重要的是,我们并不总是能够将迷你图表排列成整齐的网格(也称为“小倍数”),这使得发现模式和差异变得更加困难。

Source: “The Semiology of Graphics”, Bertin

数据可视化理论认为,人们可以使用“通道”对信息进行可视化编码(阅读更多关于 Bertin 的视网膜变量)。但是这对我们没有太大的帮助:工具已经牺牲了位置和大小(我们必须将节点放在图中),而且一开始就没有那么多变量。

戴上我的数据科学帽子,首先想到的是降维(例如 PCAt-SNE )。这是一种数学方法,它获取你的数据集,并神奇地吐出一个新的数据集,它具有更少的维度,以便于绘图。尽管很容易发现相似和不相似的数据点,但通常很难描述这些减少的维度意味着什么。

我同事的第一个建议完全不同——雷达图!这让我大吃一惊。雷达图得到很多高射炮火,而且往往有充分的理由。

Source: https://commons.wikimedia.org/wiki/File:Spider_Chart.svg

不过,我越想,就越觉得值得一试。通常在雷达图中,所有的轴都有相同的域(例如 1 到 10),但事实并非如此。我们可以将每个轴重新想象为一个单独的维度,然后它可以作为一个 n 维的图。

雷达图的一个问题是,它们对形状进行了过度编码,这意味着对于人类来说,每个轴上的微小差异并不突出,但单个数据点的怪异多边形形状却很突出。但在这种情况下,我们可以利用这一点!

Source: https://commons.wikimedia.org/wiki/File:Spider_SSI2008.gif

方法如下:人类擅长注意形状之间的差异。我们试图做的是一眼就注意到广泛的差异,所以也许我们可以使形状本身更加突出,而单独的数据点不那么突出。最后,我们得到的是不同节点看起来不同的多边形形状,以及相似节点看起来相似的多边形形状。

解决这个问题的另一种方法是平行坐标图,它是我们假设的图表的近似展开版本:

Source: https://en.wikipedia.org/wiki/Parallel_coordinates#/media/File:ParCorFisherIris.png

我更喜欢雷达版本的一个原因是因为它产生了一种紧凑的表示形式——径向线形成的多边形几乎就像是数据生成的符号。这允许您使用类似于迷你图的压缩表示,可以在另一个应用程序中使用。另一个原因是,我认为单独的线条不如多边形形状容易记忆。

另一个有趣的选择是切尔诺夫的脸,它们有相似的脉络,很搞笑,但人们很难认真对待:

Multivariate data abound!

显然,还有切尔诺夫鱼。无论如何,这个想法让我很兴奋,我开始工作。我从使用 d3 的 Nadieh Bremer 的优秀雷达图文章和示例代码开始:

The code was so nicely commented!

我移除了径向网格圆,以消除轴之间的连续性感觉——毕竟,它们现在代表不同的量。我还去掉了大部分美学上的细微差别,当你缩小图表的尺寸时,这些细微差别并不真正相关。

类似地,我也考虑过完全移除轴之间的径向线/区域,只在每个轴上有大点,但最终这些线作为视觉辅助工具帮助生成了一个整体多边形,似乎比彩色点更容易比较。

我不得不修改大量代码来支持多个不同的轴。此外,基于数据集逐个配置每个轴听起来很痛苦,所以我添加了一些代码来基于数据集本身自动生成刻度和轴:使用一些简单的标准(当前变量的类型——是字符串、布尔还是数字?),你就可以半知半解的决定用什么样的轴了。您还可以查找最小值和最大值(在线性刻度的情况下)或所有唯一值(在分类变量的情况下)。你可以表面上更聪明地扩展它,例如,你可以测量一个变量的偏斜度,然后决定用对数轴来绘图。

这是一个中间结果,在同一组轴上绘制多个数据点,有些是分类的,有些是线性的:

当然,对于多个数据点来说,这并不实际,因为多边形开始重叠。更重要的是,让我们用一些实际数据来看一个小倍数的例子。我的同事试图为一个研究项目可视化数据结构的不同配置参数。因为我对这个数据集的主题有所了解,所以我希望看到不同的图形组,它们看起来彼此相似,但与其他的不同。

我认为它基本上实现了我们设定的主要目标:具有完全不同设置的节点看起来完全不同(例如,Trie 与范围划分),而具有相似设置的节点看起来相似(例如,所有 B 树变体、所有数据页变体、链表和跳过列表)。

会扩大到 40 吗?我认为这是可疑的:

这并不奇怪——40 是很多。我怀疑这取决于你所看到的数据的结构。删除维度确实有点像作弊,但是我们仍然显示了比大多数其他可视化类型更多的维度。

要考虑的一件事是轴的顺序:因为变量之间没有特定的关系,所以不清楚什么顺序是最佳的。但是,保持相关的轴彼此靠近可能有助于生成更容易区分的形状。或者,先对分类轴进行分组,然后对附近的顺序轴进行分组可能会有所帮助。

另一个方面是颜色——使相似的形状看起来颜色相似可能是一个很大的改进,例如,像链表和跳表这样的南北向重的实例可以看起来不同于像 datapage 和 trie 这样的东西向重的实例。如何最好地做到这一点并不明显。

我不喜欢这个图表是因为它让分类变量看起来是有序的。无论如何,你必须在轴线上有一个定义好的类别选项顺序。这更像是语义上的吹毛求疵——因为目的是让不同的数据点看起来不同,这不一定那么重要:单个值不如成功的比较重要。

我们可以做一些更聪明的事情:最不常见的选项可以最接近原点,而最常见的选项可以最远,这意味着最“平均”的数据点将类似于一个大的等半径多边形,而该数据点的不常见变量将显示为易于区分的“倾斜”。

Slightly subtler styling. The first 4 shapes remind me of Darwin’s finches for some reason.

总的来说,这对于相对较少的努力来说是不错的!如果你想试试,这里有一些演示和代码:

[## 不同坐标轴的多元雷达图

Mehmet Ali "Mali" Akmanalp 区块 9cb 99571 ee 74 b 169 DC 109 EC 3 fc 3d 4920

bl.ocks.org](http://bl.ocks.org/makmanalp/9cb99571ee74b169dc109ec3fc3d4920)

它不是防弹的,因为我没有花太多时间在它上面(“最后的 20%花费了 80%的时间”),但它只是几行代码来画一个图表,它应该可以完成工作!

鸣谢 :感谢 Nicky Case、John Christian、Katherina Nguyen、Will Strimling 和 Justin Woodbridge 提供的宝贵帮助、建议和反馈!

播客片段:与 StitchFix 的首席算法官在第 9 集的背景中

原文:https://towardsdatascience.com/podcast-take-in-context-episode-9-with-stitchfixs-chief-algorithms-officer-7c96a1cbd830?source=collection_archive---------17-----------------------

语境播客的最新一集是机器学习领域任何人的必听内容。Context 的主持人, integrate.ai凯瑟琳·休姆,总是向一群令人印象深刻的客人提出商业和技术问题的完美平衡。

如果你以前没有听过语境中的,我强烈推荐订阅!另一个很棒的剧集是第 7 集的“了解数据产品市场”,由 Clare Corthell 和 Sarah Catanzaro 主演。

埃里克·科尔森目前是在线订阅个人购物服务公司 StitchFix 的首席算法官,他最近首次公开募股。在 Stitch Fix 之前,Eric 是网飞数据科学&工程副总裁,这是另一家将机器学习深度融入客户体验的公司。不用说,StitchFix 肯定是以切实的方式利用机器学习来影响其商业目标的顶级公司之一,其他公司还有优步、谷歌、Airbnb 和苹果。

虽然播客的标题专注于为 autonomy 招聘,但实际上这一集涵盖了许多有趣的主题——从构建数据科学团队到在组织中脱颖而出,“fullstack 数据科学家”,以及 StitchFix 自己的机器学习项目。

Stitch Fix’s Algorithms team has a dedicated website that shows algorithms are integrated into every step of the Stitch Fix customer experience — highly recommend!

在本帖中,我将提供这一集的摘要,以及我的主要观点和听完后需要考虑的开放性问题。

注意事项:

1:24–1:34 >开始播客的关键问题:“你如何发展一种促进问责制和自主权的文化?在数据科学+机器学习的背景下,自治是否面临特定的挑战?”

3:30–4:37缝合修复允许用户记录他们的偏好,然后将填充他们的选择。

4:50–7:26 > Kathryn 提出了这样一个问题:“人工智能是否会夺走我们意外发现的能力?”(减少自我决定)Eric 用他使用 Stitch Fix 的经验来回应,他声称让人们在服装选择上有更多的发现和信心。

9:30–10:30 > Eric 谈到了 Stitch Fix 机器学习团队使用的不同算法:它们通过人类处理者(造型师)的判断来扩展经典的推荐系统。他指出,机器学习已经取得了进步,但仍然缺乏移情和建立关系的特定技能。

10:31-12:18 > Stitch Fix 有超过 85 名算法开发人员,其中只有 5 人从事推荐算法方面的工作。库存管理、需求管理、物流和服装设计算法是 Stitch Fix 管道中的一些其他算法,有助于该公司相对于其他零售商的可持续竞争优势。

12:26–12:56 >根据 Kathryn 指出的两个趋势,围绕 ML 算法作为可防御护城河的讨论:(1)开源的兴起和(2)工业和学术界之间权力动态的转移。

12:58 -14:42 >数据作为杠杆。组织结构实际上作用于/拉动杠杆,因此公司实际上可以有效地利用数据和算法。 Stitch Fix 的组织结构将数据科学与其他关键业务职能相提并论。

15:34–17:55 > Eric 描述了 Stitch Fix algorithms 团队的部门如何与营销或造型等其他合作伙伴业务部门保持一致,以创造一种持续的主动性,而不仅仅是一个项目。合作模式允许思想的双向流动。

18:07- 19:00 > Kathryn 注意到这种合作关系如何为清晰的**“想象力的地平线”**-本质上,就是关于机器学习的可行性的知识。

19:03–21:34 >数据科学团队如何工作的两个特性: (1)构思概念和(2)构思概念。Eric 主张让数据科学家参与其中,尤其是因为人们可能仍然没有清晰的想象力。

22:00–24:18 > Kathryn 关于 Stitch Fix 是否有专门从事基础研究的人员的问题引发了围绕移交风险的全面讨论。 Eric 描述了 Stitch Fix 算法团队如何通过拥有端到端流程来实现“自主、精通和有目的”。凯瑟琳将这种方法与其他公司的专业角色(商业分析师、数据科学家和工程师)进行了对比。

24:20 -29:35 > Eric 提出需要全栈数据科学家进行更多迭代流程,避免协调成本+等待时间的噩梦!🦄

32:05–36:35 > Stitch Fix 数据科学候选人来自广泛的学术领域,但通常都具有定量思维和基础,并且偏向于行动。埃里克还强调了从理论到实践的经验过渡的必要性。

41:29 -43:20 > Eric 认为已经专业化的组织可以转向更通用的自治结构。

要考虑的要点和问题:

播客中最引人注目的部分是 Eric 提出组织需要脱离专业角色,支持数据科学通才。Stitch Fix 似乎在这种模式下取得了成功,因为他们的文化、与其他业务部门的关系以及招聘流程有助于这种成功——看不出没有这些其他组件的公司会轻易改变结构。

老实说,我能看到在一个人领导下做事情的好处,让事情变得更快。我很想知道我们如何改善交流和分享,这样人们在拥有自主权和责任的同时还能合作。

需要思考的一些问题—

  1. 数据科学家愿意做全栈数据科学家吗?雇佣这些“独角兽”真的像看起来那么难吗?
  2. Stitch Fix 的组织结构与您的团队/公司有何不同?您认为这对于完成工作和推动业务影响会更有效吗?
  3. 数据产品在目标和需求方面与其他产品有何不同?
  4. 你和你的团队正在做任何需求未知的任务吗?
  5. 专业化和让多个利益相关者参与进来有什么好处?这些是否超过了让一个人在整个过程中完全自主的好处?
  6. Eric 描述了 Stitch Fix 算法团队如何针对“差异化能力的快速开发”进行优化——您的团队针对什么进行了优化?

想知道更多吗?还有一些其他令人惊叹的机器学习播客系列。从马特·福格尔的名单这里开始

觉得这篇文章有用?在 Medium 上关注我们( Comet.ml )!

Cecelia Shao 是 Comet.ml 的产品负责人。🚀🚀🚀

在 Comet.ml 之前,她是 IBM Watson 的机器学习平台的产品经理,并在包括 Mattermark 和 Gemini 在内的几家初创公司运营。作为一名用户驱动的项目经理,交流数据的结果和建议是她的专长。

PoetBot:一个推荐诗歌的电报聊天机器人

原文:https://towardsdatascience.com/poetbot-2-a-telegram-chat-bot-for-poem-recommendation-70d1b809761c?source=collection_archive---------2-----------------------

从头开始构建你的第一个诗意聊天机器人

谁不需要生活中的一点诗意来度过呢?谁不想找一点代码让它发光呢?本教程的目的是为 Telegram 中的诗歌推荐建立一个全功能的聊天机器人,这是一个类似于 WhatsApp 的即时通讯平台,除了比好得多好得多。我们将把工作流程分成三大块:

  1. 在网上搜索浪漫,输入我们的数据库。
  2. 编写一个 Python 脚本来处理文本处理和标记
  3. 将聊天机器人嵌入电报。

你准备好了吗?现在,在我们开始之前,让我给你介绍一个人…

Hey, please meet PoetBot.

第一步:爬行

首先:在我们开始构思诗歌推荐引擎之前,我们必须有一些很酷的诗歌要分发。由于找不到符合我们需要的诗歌数据库,我们决定从网上搜集资料,建立自己的数据库。人们的目光很快停留在 Pomemhunter.com,这是一个提供来自世界各地酸甜苦辣的内容的门户网站。我们花了一些时间研究网站的架构,发现用户排名的前 500 首诗存储在 20 个相邻的网页上,其逻辑如下:

https://www.poemhunter.com/p/m/l.asp?a=0&l = top 500&order = title**&p = 1**首诗 1 至 25 首
https://www.poemhunter.com/p/m/l.asp?a=0&l = top 500&order = title**&p = 2**首诗 26 至 50 首https://www.poemhunter.com/p/m/l.asp?a=0&l = top 500&order =首

随着 p1 增加到 20

实际上,我们可以循环 p 属性来获得包含 500 首诗的 20 个页面的 URL 列表。这用 Python 来翻译(警告:代码开始):

我们现在知道指向每首诗的超链接存储在哪里,我们需要做的就是检索它们。回到这里并按下 ctrl+U ,我们注意到各个诗歌的 URL 包含在一个标签为‘title’的< td >元素中。根据这些信息,我们使用 requests 和 BeautifulSoup 编写一个代码来创建一个收集 500 个 URL 的列表(代码中的“链接”)。

所以,工作完成了一半。我们现在可以一首接一首地连接到诗歌,并保存每个作者、标题和全文。最后,我们将结果保存在一个 csv 表中供以后使用。

太好了,我们把所有的数据都放在一个地方。**辛苦工作之后,我们可以放松一下,享受一点诗歌,不是吗?**浏览我们刚刚创建的表格(顺便说一句,你会在这里找到它和所有其他代码),第 13 首最受欢迎的诗是罗尔德·达尔著名的“电视”,在这首诗中,这位英国作家对现代技术并不轻松(我一直同意你的观点)。关于孩子看电视,它是这样的:

他们坐着,凝视着,凝视着,坐着
直到他们被它催眠,
直到他们被那些令人震惊的可怕的垃圾完全灌醉。
哦,是的,我们知道它让他们保持安静,
他们不会爬出窗台,
他们从不打架或踢或打,
他们让你自由地做午饭
和在水槽里洗碗—
但是你有没有停下来想一想,
想知道这对你心爱的孩子到底有什么影响?

The culprit.

第二步:锁定目标

在开始锁定目标之前,我们需要清理我们的数据。我们的策略如下:我们从刚刚创建的上传原始文本,对于每首诗,我们将标题和文本连接在一起,我们删除停用词、标点符号和数字,我们标记,我们计算平均标记长度,我们截断太长的诗,我们扩展太短的诗以获得等长的行。‘Pfiu!,我试着尽可能快地说出来。如果你想详细了解这是如何做到的,请参考下面的笔记本。如果没有(谁怪你),就在' tokenized_poems.csv '随便看看,继续下一段。

好了,我们现在准备写我们的定位算法。当用户与机器人互动时,他们将被要求输入一个句子和/或一系列单词来描述他们想要的诗歌是什么样子的。依靠如此小的数据集,尝试将诗歌聚类成主题并使用它们作为目标是没有意义的。然后我们选择了一个简单得多的解决方案,老一套:“给我一袋单词,我会还给你包含最多单词的那首诗!“我们是有想象力的人,我们设计了一个 Python 类,它将优雅地接受一个字符串并返回我们的目标诗歌的全文。把刚才说的重新组织成子句和循环,代码看起来很庞大,如果你感兴趣的话,看看这里的。否则就继续读吧,在教程的最后,我会解释如何在不知道里面有什么的情况下使用这个机器人。

为了利用我们的类(对不起,Karl 不是那个意思),我们写了一个‘main . py’程序,它为 Poet_class 创建了一个实例,并在其上调用‘get _ poem’方法。非常简单快捷:

第三步:将聊天机器人嵌入电报

最后,我们都在等待的时刻。我们有我们的数据,我们有如何选择诗歌的规则,我们知道如何从数据库中提取它们。我们所需要的是创建我们的机器人,并附上一套指令!为了做到这一点,我们首先导入相关的库并启动一个记录器,在错误发生时向终端显示错误。

然后我们定义一组机器人能够处理的指令。下面,每个函数对应一个方法。告诉机器人类似“/poem about cactus and roses”的内容将激活“poem”方法,该方法将处理输入并调用 Poet_class 来选择目标诗歌及其文本。

好了,一堆台词就给不出思路了。让我们试试机器人直播吧!从终端启动脚本并连接到 PoetBot,我们发出第一个请求:

工作正常!我们可以给机器人一个更简单的表达式,看看会有什么结果。

Guess what the word is…

机器人似乎再次做出了很好的反应,搜索“爱”这个词出现最多的诗歌(在这种情况下,它出现了很多)。

现在,完成了。你可以用更复杂的查询来测试这个算法,并希望从中获得一些奇怪和有趣的东西!注意:PoetBot 还没有部署,所以如果你想使用它,你必须自己获得它(说明如下)。万一有(烧瓶?)开发者正在看这个,想帮我们放到云上,请给我们喊一声,我们提供电子啤酒作为交换(互联网第 0 法则:如果你能想到,大概它已经存在了)。感谢大家的阅读。

建立你自己的机器人

安装你自己的机器人的步骤如下:

  1. 下载电报应用到你的手机。
  2. 问候 BotFather(默认情况下他会在你的联系人列表中),然后告诉他你想创建一个新的 bot。命令: /newbot
  3. 给你的机器人一个名字(将显示什么)和一个用户名(将用于识别)。在我的例子中,我选择了 PoetBotVioletsAreBlueBot 。请不要问。
  4. 爸爸会给你一个令牌。把它保存在某个地方。
  5. 这个 github repo,克隆到你的本地机器' bot.py ',' poet_class.py ',' tokenized_poems.csv ',' poems_collection.csv '和' requirements.txt '。
  6. 在 bot.py 中,插入 BotFather 给你的令牌。
  7. 通过访问您的本地文件夹,后跟命令“pip install -r requirements.txt”来安装要求
  8. 运行“python3 bot.py”
  9. 通过使用用户名作为搜索标准在 Telegram 上找到您的机器人,并享受它:)

【poet bot 图片鸣谢:Ivan Kershner。】

口袋妖怪代沟?(Python 数据分析)第 1 部分:清理,EDA

原文:https://towardsdatascience.com/pokemon-generation-gap-python-data-analysis-part-1-cleaning-eda-265ff3cb5dff?source=collection_archive---------4-----------------------

Photo by Thimo Pedersen on Unsplash

我一直在通过网络课程学习 Python 进行数据分析,有时也会学习 Youtube 视频等。我知道我只迈出了第一步,但我忍不住想把我学到的东西付诸实践。我坚信,知识不是你的,直到你实际应用和使用它。我没有那种“美丽心灵”类型的大脑,我不能仅仅通过观看来理解我头脑中的事物。考虑到我目前的 Python 流畅程度,我先从一些简单的基础分析开始。

我不是口袋妖怪极客,但我确实玩过口袋妖怪 Go。不幸的是,我是那些提前离开的人之一。我想我升到了 25 级,就这样了。我确实看过几集电视剧,但只是偶然。那么,为什么是口袋妖怪呢?我想从轻松、不太严肃也不太复杂的地方开始。当我在浏览 Kaggle 的数据集时,我发现了口袋妖怪数据集!数据的大小对我来说是可管理的,不包含太多的列,每一列对我来说都很容易理解。还有口袋妖怪很可爱…

我首先浏览了口袋妖怪数据集中的所有内核,许多很酷的分析有些对我来说太高级了,有些我能理解。所以我先从一个简单的问题开始。“不同年代的口袋妖怪有区别吗?”(从 1996 年到 2017 年跨越了 7 个不同的世代)

首先,我下载了数据集并保存在我的电脑中,以便用 Python 阅读和查看。

import pandas as pd
df = pd.read_csv('Pokemon.csv')
df.head()

通过查看前 5 项数据,我已经发现了两个问题。第一,' # '列有重复,并且似乎口袋妖怪的巨型进化形式与其原始形式具有相同的 ID 号(巨型进化是口袋妖怪的终极形式,并不适用于所有口袋妖怪)。但是大进化前后肯定是不一样的。不仅他们的统计数据会改变,他们的长相也会改变。例如,第三个条目 Vensaur 的总属性点是 525,而第四个条目 Mega Venusaur 的总属性点是 625。外观如下。

Left: Venusaur, Right: Mega Venusaur (and No! they are not the same, take a closer look)

第二个问题是第四个条目 Mega Venusaurs 在名称列值的前面重复了 venus aur;“VenusaurMega Venusaur”。这需要处理。

只看前五个条目并不能给我完整的数据。所以为了看到更广阔的图景,我称之为“info”方法。

df.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 800 entries, 0 to 799
Data columns (total 13 columns):
#             800 non-null int64
Name          800 non-null object
Type 1        800 non-null object
Type 2        414 non-null object
Total         800 non-null int64
HP            800 non-null int64
Attack        800 non-null int64
Defense       800 non-null int64
Sp. Atk       800 non-null int64
Sp. Def       800 non-null int64
Speed         800 non-null int64
Generation    800 non-null int64
Legendary     800 non-null bool
dtypes: bool(1), int64(9), object(3)
memory usage: 75.9+ KB

我可以看到有 800 个条目,列的值是“object”或“int64”或“bool”,意思是字符串或整数或布尔值。对于“Type 2”变量,只有 414 个非空条目,这意味着缺少 386 个值。需要谨慎处理缺失值。它们丢失可能是有原因的,通过找出原因,您可能会发现一些有用的见解。有时缺失的部分甚至会扭曲整个数据。但在这种情况下,这只是因为一些口袋妖怪没有二级类型。对于我的分析,我不会使用“Type 2”属性,所以我会让它保持原样。

现在是时候来点 EDA(探索性数据分析)了!EDA 有两个方面,数字汇总和一些可视化方法,如图表。在 Python 中,只需一种方法“describe”就可以轻松提取汇总统计数据。

df.describe()

我可以在一个表中看到计数、平均值、标准差、最小值、四分位距、最大值,现在我对数据有了更好的理解。(“描述”方法只从数值中抓取结果。因此,具有字符串、布尔值:“名称”、“类型 1”、“类型 2”、“传奇”的列没有在此处显示。)尽管这个数据集很容易看出每一列的含义,但有时查看数据集的原始文档是非常有帮助的。根据上传数据集到 Kaggle 的 Alberto Barradas 的说法,描述如下。

#:每个口袋妖怪的 ID

名称:每个口袋妖怪的名字

类型 1:每个口袋妖怪都有一个类型,这决定了弱点/对攻击的抵抗力

类型 2:一些口袋妖怪是双重类型,有 2 个

总计:在此之后所有统计数据的总和,一个口袋妖怪有多强的一般指南

生命值,或者生命值,定义了一个口袋妖怪在晕倒前可以承受的伤害

攻击:普通攻击的基础调整值(例如抓伤,猛击)

防御:对普通攻击的基础伤害抗性

特殊攻击,特殊攻击的基础调整值(例如火焰冲击,气泡光束)

SP Def:对特殊攻击的基础伤害抗性

速度:决定每轮哪个口袋妖怪先攻击

我猜‘世代’和‘传奇’变量是后来加上的。只是为了帮助你理解,“一代”变量是关于它是哪一代的口袋妖怪,“传奇”是口袋妖怪是否是一个传奇类。

我们继续吧。我首先想解决我在调用“df.head()”时看到的两个问题。“#”列的重复项和“名称”列的陌生名称。

df = df.drop(['#'],axis=1)
import re # importing regex library to use in below line
df.Name = df.Name.apply(lambda x: re.sub(r'(.+)(Mega.+)',r'\2', x))
df.head()

好的。我完全删除了“#”栏,也删除了超级进化形态前面重复的口袋妖怪名字。现在看起来好多了。让我们通过调用“tail”方法来查看条目的结尾。

df.tail()

哦等等。有些事情看起来不太对劲。条目编号 797,798 似乎在名字前面有重复。供您参考,胡帕是正确的名称,而不是胡帕胡帕,他们看起来像下面。

Left: Hoopa Confined, Right: Hoopa Unbound

我最好为胡帕整理一下这个名字。所以我写了另一个代码来修复两个胡帕条目。

df.Name = df.Name.apply(lambda x: re.sub(r'(HoopaHoopa)(.+)','Hoopa'+r'\2',x))
df.tail()

老实说,为了弄清楚是否还有其他奇怪的名字需要修改,我还打开了 csv 文件,并扫描了所有 800 个条目的“名称”列。我想我不能为 10,000 或 100,000 个条目这样做,可能需要考虑更聪明的方法来解决这个问题。但无论如何,我发现只有超级进化形态的口袋妖怪或胡帕在他们的“名称”列值中有这种问题。

最后,我准备好继续进行一些可视化 EDA。既然我想弄清楚口袋妖怪一代比一代有什么不同,那么把参赛作品按不同代分组,看看它们在剧情上的样子是个不错的主意。

“总计”栏是所有统计值的总和,我认为这是一个口袋妖怪整体统计的良好指标。所以,让我们看看'总'值是如何在同一代口袋妖怪中分布的。

根据 Seaborn 的文件记载,“小提琴情节扮演着与盒子和胡须情节相似的角色。它显示了一个(或多个)分类变量的几个水平上的定量数据的分布,以便这些分布可以进行比较“”。violin 图的优势在于,你可以从图中看到分布形状。有了箱线图,你永远无法知道分布是单峰还是多峰

Anatomy of Violin Plot

%matplotlib inline
import matplotlib.pyplot as plt
import seaborn as sns
sns.violinplot(x='Generation',y='Total',data=df)

看起来第 1 代和第 3 代比其他代更分散,而第 4 代看起来最短,有两个明显的峰值。至少,从情节来看,几代人之间可能会有一些显著的差异,但现在说还为时过早。

当我在寻找小提琴情节的定义和解释时,我发现了一件有趣的事情。虽然小提琴图显示了更多的信息,但它们可能比盒子图更嘈杂。嗯嗯是这样吗?我想我必须画一个方框图,看看它们有什么不同。

我觉得帖子太长了。我就讲到这里,继续讲第二部分。

下面是我用上面的代码创建的要点的链接。请随时查看,如果您有任何建议或反馈,请告诉我。

简而言之,政策梯度

原文:https://towardsdatascience.com/policy-gradients-in-a-nutshell-8b72f9743c5d?source=collection_archive---------2-----------------------

本文旨在对强化学习中最重要的一类控制算法——策略梯度——提供简明而全面的介绍。我将依次讨论这些算法,从头开始得出众所周知的结果。它针对的是对机器学习中的任何其他主题有合理背景的读者。最后,我希望你能够阅读大量(如果不是全部)强化学习文献。

介绍

强化学习(RL)指的是学习问题和机器学习的子领域,它最近在新闻中有很大的原因。基于 RL 的系统现在已经击败了围棋世界冠军帮助更好地操作数据中心掌握了各种各样的雅达利游戏。研究界看到了更多有希望的结果。有了足够的动力,现在让我们来看看强化学习的问题。

强化学习是对学习问题的最一般的描述,其目的是最大化一个长期目标。系统描述由一个代理组成,该代理通过其在离散时间步骤的动作与环境交互,并接收奖励。这将代理转换到新的状态。下图描述了一个典型的代理-环境反馈循环。

The Canonical Agent-Environment Feedback Loop

学习问题的强化学习味道与人类如何有效地行为惊人地相似——体验世界、积累知识并利用学到的知识处理新的情况。像许多人一样,这个问题的吸引人的本质(尽管更难表述)让我兴奋,并希望它也能让你兴奋。

背景和定义

RL 背后的大量理论基于奖励假设的假设,该假设概括地说,一个主体的所有目标和目的都可以用一个称为奖励的单一标量来解释。这仍然是一个争论的话题,但是已经很难反驳了。更正式的说法是,奖励假设如下

奖励假说:我们所说的目标和目的都可以被认为是接收到的标量信号的累积和的期望值的最大化(称为奖励)。

作为一名 RL 实践者和研究人员,一个人的工作是为一个已知的问题找到正确的奖励集,称为奖励形成

代理必须通过一个被称为马尔可夫决策过程的理论框架正式工作,该过程包括一个决策(采取什么行动?)在每个州进行。这产生了一系列的状态、行动和奖励,被称为轨迹

目标是最大化这些奖励。更正式地说,我们看马尔可夫决策过程框架。

马尔可夫决策过程:一个(贴现)马尔可夫决策过程(MDP)是一个元组(S,A,R, pγ ,这样

其中S _ t,S _(t+1)∈S(状态空间), A_(t +1) ∈ A(行动空间), R_(t +1), R_t ∈ R(报酬空间), p 定义过程的动态, G_t 为贴现收益。

简而言之,MDP 定义了转换到一个新状态的概率,在给定当前状态和执行一个动作的情况下获得一些奖励。这个框架在数学上令人满意,因为它是一阶马尔可夫链。这只是一种奇特的说法,即接下来发生的任何事情都只取决于现在,而不是过去。只要你做到了,你如何到达当前状态并不重要。这个框架的另一个重要部分是贴现因子 γ 。随着时间的推移,将这些回报与来自未来的回报的不同程度的重要性相加,导致了贴现回报的概念。正如人们所料,较高的 γ 会导致对未来回报的更高敏感度。而 γ =0 的极端情况,完全不考虑来自未来的奖励。

环境 p 的动态在代理的控制之外。为了内化这一点,想象一下站在一个有风的环境中的一块地上,每秒钟向四个方向中的一个方向迈一步。风是如此之大,以至于你很难朝着与北、东、西或南完全一致的方向前进。这种下一秒降落在新状态的概率是由风场的动力学 p 给出的。这当然不是你(代理人)能控制的。

然而,如果你以某种方式理解了环境的动态,并朝着除了东、西、南、北之外的方向移动,那该怎么办呢?这个策略就是代理控制的。当一个代理遵循一个策略 π 时,它生成一系列的状态、动作和奖励,称为轨迹

策略:策略被定义为给定状态下动作的概率分布

记住所有这些定义,让我们看看 RL 问题的形式。

政策梯度

强化学习代理的目标是在遵循策略 π 时最大化“预期”回报。像任何机器学习设置一样,我们定义了一组参数 θ (例如,复杂多项式的系数或神经网络中单元的权重和偏差)来参数化该策略— π_θ (为了简洁,也写为 π )。如果我们用 r ( τ )来表示给定轨迹 τ 的总回报,我们会得到下面的定义。

强化学习目标:遵循参数化策略,最大化“预期”回报

所有有限 MDP 至少有一个最优策略(能给出最大回报),并且在所有最优策略中,至少有一个是稳定的和确定的。

像任何其他机器学习问题一样,如果我们能找到使 J 最大化的参数 θ ⋆,我们就解决了这个任务。在机器学习文献中,解决这种最大化问题的标准方法是使用梯度上升(或下降)。在梯度上升中,我们使用以下更新规则来逐步通过参数

挑战来了,我们如何找到上面包含期望的目标的梯度。积分在计算环境中总是不好的。我们需要找到绕过它们的方法。第一步是从期望值的扩展开始重新制定梯度(稍微滥用符号)。

保单梯度定理:期望报酬的导数是保单对数的报酬与梯度乘积的期望 π_θ

现在,让我们扩展一下 π_θ ( τ )的定义。

为了理解这个计算,让我们把它分解一下——P 代表在某个状态下开始的遍历分布 s_ 0。从那时起,我们应用概率的乘积法则,因为每个新的行动概率都独立于前一个(还记得马尔科夫吗?).在每一步,我们使用策略πθ和环境动力学 p 来采取一些行动,以决定转换到哪个新状态。这些乘以代表轨迹长度的 T 时间步长。相当于,取日志,我们有

这个结果本身就很漂亮,因为它告诉我们,我们不需要知道状态 P 的遍历分布,也不需要知道环境动力学 p 。这是至关重要的,因为对于大多数实际目的来说,很难对这两个变量建模。摆脱他们,当然是好的进步。因此,所有使用这个结果的算法都被称为“无模型算法”,因为我们没有对环境进行“建模”。

“期望”(或者相当于一个积分项)仍然存在。一个简单但有效的方法是对大量轨迹进行采样(我真的是指大量!)然后平均一下。这是一种近似,但却是无偏的,类似于用区域中的一组离散点来近似连续空间上的积分。这种技术在形式上被称为马尔可夫链蒙特卡罗(MCMC),广泛用于概率图形模型和贝叶斯网络中以近似参数概率分布。

在我们上面的讨论中,有一项没有涉及到,那就是轨迹 r ( τ )的回报。尽管参数化政策的梯度不依赖于报酬,但这一项在 MCMC 抽样中增加了许多方差。实际上,有 T 个方差源,每个 R_t 都有贡献。然而,我们可以利用回报 G_t ,因为从优化 RL 目标的角度来看,过去的回报没有任何贡献。因此,如果我们用贴现回报 G_t 代替 r ( τ ),我们就得到经典算法策略梯度算法,称为加强。当我们进一步讨论时,这并不能完全缓解问题。

强化(和基线)

再次重申,增强算法计算策略梯度的方式如下

加固坡度

我们仍然没有解决采样轨迹的方差问题。认识到这个问题的一个方法是重新设想上面定义的 RL 目标为似然最大化(最大似然估计)。在 MLE 设置中,众所周知,数据压倒了先验——换句话说,无论初始估计多么糟糕,在数据的限制下,模型都会收敛到真实参数。然而,在数据样本具有高方差的设置中,稳定模型参数可能是众所周知的困难。在我们的背景下,任何不稳定的轨迹都可能导致政策分配的次优转变。奖励的规模加剧了这个问题。

因此,我们试图通过引入另一个称为基线 b 的变量来优化报酬差异。为了保持梯度估计的无偏性,基线独立于政策参数。

用基线加固

要了解原因,我们必须表明,随着附加项的增加,梯度保持不变(略有滥用符号)。

在理论和实践中,使用基线可以减少方差,同时保持梯度不偏不倚。一个好的基线是使用状态值当前状态。

状态值:状态值定义为给定一个状态遵循策略 π_θ 的期望收益。

演员-评论家方法

找到一个好的基线本身是另一个挑战,计算它又是另一个挑战。相反,让我们用参数 ω 来近似计算 V^ω_ ( s )。我们使用可学习的 V^ω_ ( s )引导梯度的所有算法都被称为行动者-批评家算法,因为这个价值函数估计的行为就像一个“批评家”(好的 v/s 坏的值)到“行动者”(代理的策略)。然而这一次,我们必须计算演员和评论家的梯度。

单步 Bootstrapped Return :单步 Bootstrapped Return 获取直接回报,并通过使用轨迹中下一个状态的 bootstrapped value-estimate 来估计回报。

演员-评论家政策梯度

不言而喻,我们还需要更新评论家的参数 ω 。这里的目标通常是均方损失(或不太苛刻的 Huber 损失)和使用随机梯度下降更新的参数。

评论家的目标

确定性政策梯度

通常,在机器人学中,可微分的控制策略是可用的,但是动作不是随机的。在这种环境下,很难像以前那样建立随机政策。一种方法是将噪声注入控制器。此外,随着控制器维数的增加,以前看到的算法性能开始变差。由于这种情况,让我们直接学习给定状态的确定性动作,而不是学习大量的概率分布。因此,最简单的形式,贪婪的最大化目标是我们所需要的

确定性动作

然而,对于大多数实际目的来说,这种最大化操作在计算上是不可行的(因为除了搜索给定动作值函数的整个空间之外没有其他方法)。相反,我们可以渴望做的是,建立一个函数近似器来近似这个 argmax ,因此被称为确定性政策梯度 (DPG)。

我们用下面的等式来总结这个。

DPG 目标

确定性政策梯度

这个值变成了另一个期望值,我们可以使用 MCMC 采样再次估算,这应该不足为奇了。

通用强化学习框架

我们现在可以得出一个通用算法,看看我们所学的所有部分在哪里组合在一起。所有新算法通常是下面给出的算法的变体,试图攻击问题的一个(或多个)步骤。

密码

对于熟悉 Python 的读者来说,这些代码片段是对上述理论思想的更具体的表达。这些都是从真实代码的学习循环中提取出来的。

政策梯度(同步行动者-批评家)

深度确定性政策梯度

完成实施

可在activatedgeek/torch rl查看完整流水线的完整模块化实现。

参考

**【萨顿和巴尔托,1998】**萨顿,R. S .和巴尔托,A. G. (1998)。强化学习导论。麻省理工学院出版社,美国马萨诸塞州剑桥,第一版。

**【迪米特里,2017】**迪米特里,P. B. (2017)。动态规划与最优控制。雅典娜科学

**【Lilli crap 等人,2015】**Lilli crap,T. P .、Hunt、J. J .、Pritzel,a .、Heess,n .、Erez,t .、Tassa,y .、Silver,d .和 Wierstra,D. (2015)。深度强化学习的连续控制。ArXiv 电子印花。

**【沃特金斯和达扬,1992】**沃特金斯,C. J. C. H .和达扬,P. (1992)。q-学习。机器学习,8(3):279–292。

**【威廉姆斯,1992】**威廉姆斯,R. J. (1992)。联结主义强化学习的简单统计梯度跟踪算法。强化学习,第 5-32 页。斯普林格。

**【西尔弗等人,2014】**西尔弗,d .,利弗,g .,赫斯,n .,德格里斯,t .,维斯特拉,d .,里德米勒,M. (2014)。确定性策略梯度算法。Xing,E. P .和 Jebara,t .编辑,第 31 届机器学习国际会议论文集,机器学习研究论文集第 32 卷,第 387-395 页,北京,中国。PMLR。

本文原载此处

强化学习中的政策网络与价值网络

原文:https://towardsdatascience.com/policy-networks-vs-value-networks-in-reinforcement-learning-da2776056ad2?source=collection_archive---------1-----------------------

在强化学习中,代理在他们的环境中采取随机决策,并学习从许多决策中选择正确的决策来实现他们的目标,并以超人的水平进行游戏。策略和价值网络在像蒙特卡罗树搜索这样的算法中一起使用,以执行强化学习。这两个网络都是一种叫做 MCTS 探索算法的方法的组成部分。

它们也被称为策略迭代&值迭代,因为它们被计算多次,使得它成为一个迭代过程。

我们来了解一下为什么它们在机器学习中如此重要,它们之间有什么区别?

什么是政策网络?

考虑世界上的任何游戏,输入🎮用户给予游戏的动作称为动作。每一个输入(动作)都会导致不同的输出。这些输出被称为游戏的状态 **s**

由此,我们可以制作不同的状态-动作对**S** = **{(**s0,a0**)**,s1,a1**)**,...,**(**sN,aN**)}**,表示哪个动作aN导致哪个状态sN.同样,我们可以说 S 包含策略网络学习到的所有策略。

通过给博弈一个特定的输入来学习给出一个确定的输出的网络被称为策略网络

Policy Network (action1️, state1) , (action2, state2)

比如:输入a1给出一个状态s1(上移)&输入a2给出一个状态s2(下移)在游戏中。

此外,一些行动增加了玩家的点数,导致奖励 r

States Getting Rewards

让我们来看看一些明显的符号:

Usual Notations for RL environments

Optimal Policy

为什么我们要使用贴现因子γ

它被用作一种预防措施(通常保持在 1 以下)。它阻止报酬达到无限。

对一项政策的无限奖励会压垮我们的代理人&偏向于特定的行动,扼杀探索未知领域和游戏行动的欲望😵。

但是我们怎么知道你下一步该选择哪个州,最终进入最后一轮呢?

什么是价值网络?

价值网络通过计算当前状态**s**的预期累积分数来为游戏状态分配价值/分数。每个州都要经过价值网络。获得更多奖励的州显然在网络中获得更多价值。

请记住,奖励是**预期奖励,**因为我们从一组状态中选择了正确的一个。

Value Function

现在,关键目标总是最大化回报*(又名马尔可夫决策过程)*。导致良好状态的行为显然比其他行为获得更大的回报。

因为任何游戏都是通过一个接一个的动作赢得的。博弈的最优策略***π**** 由许多有助于赢得博弈的状态-行动对组成。

获得最大回报国家-行动对被认为是最优政策。

使用 arg max 将最优策略的等式正式写成:

Optimal Policy ***π****

因此,最优策略告诉我们应该采取哪些行动来最大化累积折扣回报。

策略网络学习到的最优策略知道在当前状态下应该执行哪些动作以获得最大回报。

如果您有任何疑问、疑问或需求,请在下面评论或发微博给我。

鼓掌吧…分享一下!在 关注我获取类似的好玩内容。

要获得即时通知,请在 Twitter 上关注我。

乐意帮忙。值得称赞。

你会喜欢的以前的故事:

[## 蒙特卡罗树搜索

每个数据科学爱好者的 MCTS

towardsdatascience.com](/monte-carlo-tree-search-158a917a8baa) [## TensorFlow 图像识别 Python API 教程

在带有 Inception-v3 的 CPU 上(以秒为单位)

towardsdatascience.com](/tensorflow-image-recognition-python-api-e35f7d412a70) [## 激活函数:神经网络

Sigmoid,tanh,Softmax,ReLU,Leaky ReLU 解释!!!

towardsdatascience.com](/activation-functions-neural-networks-1cbd9f8d91d6) [## DeepMind 的游戏《用深度强化学习捕捉旗帜》

#4 研究论文解释

towardsdatascience.com](/deepminds-playing-capture-the-flag-with-deep-reinforcement-learning-a9f71256442e)

堕胎问题上的政治分歧

原文:https://towardsdatascience.com/political-gap-on-abortion-5d983e0d0fdc?source=collection_archive---------4-----------------------

作为他的第一批行动之一,特朗普总统通过了一项行政命令,阻止美国向从事堕胎或提供堕胎信息的外国组织提供援助。自从 1984 年里根总统的“墨西哥城政策”开始实施以来,共和党和民主党总统就一直在这个问题上进行政治拉锯战。

在美国,最高法院在 Roe v . Wade(1973)一案中具有里程碑意义的判决在政治上分裂了国家,并使堕胎成为“文化战争”的一部分。有趣的是,直到 90 年代初,民主党人和共和党人对堕胎的态度差异相对较小。正如下面的分析所示,自克林顿担任总统以来,公众意见发生了巨大的分歧。

下图显示了按受访者意识形态分类的各类堕胎的时间趋势。有趣的是,斯坦福大学杰出的政治学家莫里斯·菲奥莉娜在他的畅销书*“文化战争?一个两极化的美国的神话”来断定公众对堕胎的意见并不分歧。在第五章(仔细观察堕胎)中,菲奥莉娜总结道..我们经常被告知,这个国家在堕胎问题上存在两极分化。*这种说法是错误的(第 80 页)。

性别差异

让我们看看对“允许强奸堕胎”的态度,并探讨其他人口统计学的相互作用。这个问题最近变得很突出,因为众议员托德·阿金(R-Mo。)为他对堕胎的极端反对进行辩护,声称“合法强奸”的受害者很少怀孕,因为“女性身体有办法关闭这一切。”

有趣的是,保守女性的态度比其他群体变化更大,这或许为 2016 年克林顿/特朗普选举中观察到的性别投票模式提供了线索。

附录:

分析中使用的数据来自综合社会调查(1972-2014 年),该调查提供了不同情况下(例如,婴儿有严重缺陷的风险,太穷而负担不起对孩子的长期护理)合法堕胎公众意见的长期趋势。

I 交互式可视化以及 R 代码和数据可在http://onsocialtrends.org/找到

图表在 Highcharter 中生成(R 包装到 Highcharts )

政治党派:看看数据

原文:https://towardsdatascience.com/political-partisanship-a-look-at-the-data-e71946199586?source=collection_archive---------1-----------------------

传统观点认为,特朗普时代是近期政治中政治极化最严重的时期。我决定看看一些数据,看看是否真的是这样。利用布鲁金斯学会(Brookings)关于国会的重要统计数据,我研究了 1953 年至 2015 年国会政党投票团结和意识形态得分差异。不出所料,我发现这两个指标都处于历史峰值。当前的政治时刻是人们记忆中党派之争最激烈的时刻。

我在 Jupyter 笔记本上为这篇文章写了代码,你可以在这里看到。

国会党派投票团结

民主党人和共和党人多久投票一次?这很容易让人想到著名的党派投票,比如 2010 年 ACA 投票中每个共和党人都投了反对票。最近,上周参议院未能通过同一 ACA 的“小废除”,每一位参议院民主党人都投了反对票。但看看整体数据,就会发现一幅更复杂的画面。如果我们衡量“党内团结投票”(定义为大多数投票民主党人反对大多数投票共和党人的投票)的百分比,随着时间的推移,似乎没有明显的趋势。

很明显,在过去 5 年左右的时间里,国会的党派投票达到了前所未有的统一水平。但是这种趋势会持续下去吗?90 年代中期(金里奇革命前后)也见证了党派团结投票的高峰,但显然几年后事情平静了下来。为了进行预测,我们需要我们亲爱的朋友线性回归的帮助。

首先,让我们制作一些预测线(又名最佳拟合线)。我们将测试的假设是,未来的数据将接近这些线。

在进行测试之前,很明显可以看到过去的数据并不符合这些曲线。肯定有一个微弱的积极趋势,但在某一年,很容易出现比前几年急剧下降的情况。不出所料,一个双边 t 检验揭示了令人难以置信的高置信度(众议院 p=0.9999,参议院 p=1),我们不得不拒绝未来国会将继续看到更高的政党投票团结水平的预测。

需要注意的是,这个测试范围很窄。这并不是说政党投票的统一性会下降——它可能会停留在这个历史峰值。这也不是一个很好的衡量标准:我使用的数据集将“党内团结投票”计算为大多数民主党人投票反对大多数共和党人的投票——但它忽略了低级别的确认、无意义的重命名事物的法案等常规投票,也没有跟踪从未进入议会的法案。

国会意识形态得分

支持党派偏见增加的另一种观点可能指向两党之间日益扩大的意识形态鸿沟。很难量化一名官员的“开明”或“健谈”程度,但一个广泛使用的衡量标准是普尔-罗森塔尔 DW-提名分数。在他们的自由-保守轴下,高负分表示高度自由的国会议员,高正分表示保守,接近 0 表示温和。

在这里,数据讲述了一个清晰得多的故事。与政党团结投票的百分比不同,数据点非常接近它们的最佳拟合线。一个简单的相关性测试(我使用了非参数的斯皮尔曼相关系数)发现了一个非常强的正相关关系。

众议院和参议院都表现出非常强的相关性,r≈0.98(5*10^(-23 的 p 值))和 r≈0.94(7∗10^(−17 的 p 值),r=1 是完美的相关性。相比之下,众议院和参议院的政党团结投票率分别为 0.46%和 0.66%,这仍然是一个积极的关系,但要弱得多。

像政党团结投票的百分比一样,这些数据也有局限性。我只使用了 Poole 和 Roosenthal 的意识形态分数的 1 个维度(“自由-保守”轴),但他们的系统使用了超过 10 个维度,并得出结论认为 2 维模型是最适合的。我怀疑更详细的数据会揭示这个故事更复杂。此外,我只研究二战后的数据,当时两党之间的距离处于历史低点。很有可能,这种统一是一种历史异常,一旦没有战争来统一这个国家,这种异常就结束了。

结论

从这些数据来看,很明显,党派之争达到了历史最高点。这一趋势是否会继续,在政党团结投票的情况下仍有争议,但意识形态的差距几乎肯定会继续扩大。这种分离的趋势可能会增加国会的僵局和对另一方的不信任,这是一个旨在以共识为基础运作的系统的关键弱点。

当然,党派偏见是否增加是一个简单的问题。更重要的问题是如何应对——我不确定我们是否有数据来回答这个问题。

将大规模枪击事件政治化——当我们可以谈论枪支管制的时候

原文:https://towardsdatascience.com/politicizing-mass-shootings-when-we-can-talk-about-gun-control-f196ebee2b0c?source=collection_archive---------2-----------------------

2017 年 10 月 1 日,一名枪手从拉斯维加斯一家酒店房间内射出子弹,造成 59 人死亡,546 人受伤。这是美国近代史上最致命的大规模枪击事件。

在每一次大规模枪击事件后,这种叙述都变得很熟悉,几乎是照本宣科。两边的政治家都为受害者及其家人祈祷,而民主党人利用这个机会吸引人们对枪支管制的关注,共和党人谴责民主党人“将悲剧政治化”

让我们从表面上接受这种政治化的论点,并说在大规模枪击事件后立即谈论枪支管制是不合适的。那什么时候可以谈论它?假设用以下两个标准来决定是否可以谈论枪支管制:

  1. 当天没有大规模枪击事件(4 起或更多枪击或死亡,不包括枪手)
  2. 距离上次大规模枪击事件已经过去至少 3 天了

以下是我利用美国 2017 年大规模拍摄数据得出的结论:

让我们从一些推论开始:

  1. 根据这一标准,在下一次枪击事件发生之前,你最多有连续两天的时间谈论枪支管制和枪支问题。
  2. 你不能在一月、六月、八月、九月、十月谈控枪。
  3. 总的来说,我们有 15 天的时间可以谈论枪支管制——仅仅超过 2 周。

3 天,虽然是一个任意的数字,但与事实相差并不太远,因为 10 月 4 日(拉斯韦加斯枪击案发生 3 天后)发表了数十篇观点 文章抨击民主党人将悲剧政治化。

所以,也许这不是为了防止悲剧被政治化。也许是不想谈论枪支管制,并批判性地审查第二修正案,以采取政策防止此类枪击事件再次发生。

多项式回归

原文:https://towardsdatascience.com/polynomial-regression-bbe8b9d97491?source=collection_archive---------0-----------------------

这是我在机器学习系列的第三篇博客。这个博客需要线性回归的先验知识。如果您不了解线性回归或者需要复习一下,请浏览本系列以前的文章。

线性回归要求因变量和自变量之间的关系是线性的。如果数据的分布更复杂,如下图所示,会怎么样?线性模型可以用来拟合非线性数据吗?我们怎样才能生成一条最好地捕捉数据的曲线,如下图所示?那么,我们将在这篇博客中回答这些问题。

目录

  • 为什么是多项式回归
  • 过度拟合与欠拟合
  • 偏差与方差的权衡
  • 将多项式回归应用于波士顿住房数据集。

为什么要多项式回归?

为了理解多项式回归的需要,让我们首先生成一些随机数据集。

生成的数据如下所示

让我们对这个数据集应用一个线性回归模型。

最佳拟合线的曲线为

我们可以看到,直线无法捕捉数据中的模式。这是欠装配的一个例子。计算线性线的 RMSE 和 R 分数得出:

RMSE of linear regression is **15.908242501429998**.
R2 score of linear regression is **0.6386750054827146**

为了克服欠拟合,我们需要增加模型的复杂度。

为了生成高阶方程,我们可以添加原始特征的幂作为新特征。线性模型,

可以转化为

这仍然被认为是线性模型,因为与特征相关的系数/权重仍然是线性的。x 只是一个特征。然而,我们正在拟合的曲线实际上是二次曲线。

为了将原始特征转换成它们的高阶项,我们将使用由scikit-learn提供的PolynomialFeatures类。接下来,我们使用线性回归来训练模型。

To generate polynomial features (here 2nd degree polynomial)
------------------------------------------------------------polynomial_features = PolynomialFeatures(degree=2)
x_poly = polynomial_features.fit_transform(x)Explaination
------------Let's take the first three rows of X: 
[[-3.29215704]
 [ 0.79952837]
 [-0.93621395]]If we apply polynomial transformation of degree 2, the feature vectors become[[-3.29215704 10.83829796]
 [ 0.79952837  0.63924562]
 [-0.93621395  0.87649656]]

对变换后的要素拟合线性回归模型,给出了下图。

从图中可以清楚地看出,二次曲线比线性曲线更能拟合数据。计算二次图的 RMSE 和 R 分数给出:

RMSE of polynomial regression is **10.120437473614711**.
R2 of polynomial regression is **0.8537647164420812**.

我们可以看到,与直线相比,RMSE 降低了,R 值增加了。

如果我们尝试将三次曲线(次数=3)拟合到数据集,我们可以看到它通过的数据点比二次曲线和线性曲线多。

三次曲线的度量标准是

RMSE is **3.449895507408725**
R2 score is **0.9830071790386679**

下面是在数据集上拟合线性、二次和三次曲线的比较。

如果我们进一步增加次数到 20,我们可以看到曲线通过更多的数据点。下面是 3 度和 20 度的曲线比较。

对于 degree=20,模型也捕捉数据中的噪声。这是过度拟合的一个例子。即使这个模型通过了大部分数据,它也无法对看不见的数据进行归纳。

为了防止过度拟合,我们可以添加更多的训练样本,这样算法就不会学习系统中的噪声,可以变得更一般化。(注意:如果数据本身就是噪声,添加更多数据可能会有问题)。

我们如何选择一个最优模型?要回答这个问题,我们需要理解偏差与方差的权衡。

偏差与方差的权衡

偏差是指由于模型在拟合数据时过于简单的假设而产生的误差。高偏差意味着模型无法捕捉数据中的模式,这导致欠拟合

方差是指由于复杂模型试图拟合数据而产生的误差。高方差意味着模型通过了大多数数据点,导致过度拟合数据。

下图总结了我们的学习。

从下图中我们可以观察到,随着模型复杂性的增加,偏差减少,方差增加,反之亦然。理想情况下,机器学习模型应该具有低方差和低偏差。但实际上不可能两者兼得。因此,为了实现一个在训练和看不见的数据上都表现良好的好模型,进行了折衷

Source: http://scott.fortmann-roe.com/docs/BiasVariance.html

到目前为止,我们已经讨论了多项式回归背后的大部分理论。现在,让我们在我们在之前的博客中分析的波士顿住房数据集上实现这些概念。

对住房数据集应用多项式回归

从下图可以看出,LSTAT与目标变量MEDV有轻微的非线性变化。在训练模型之前,我们将把原始特征转换成高次多项式。

让我们定义一个函数,它将原始特征转换为给定次数的多项式特征,然后对其应用线性回归。

接下来,我们调用上面的次数为 2 的函数。

使用多项式回归的模型性能:

**The model performance for the training set** 
------------------------------------------- 
RMSE of training set is 4.703071027847756 
R2 score of training set is 0.7425094297364765 **The model performance for the test set**
------------------------------------------- 
RMSE of test set is 3.784819884545044 
R2 score of test set is 0.8170372495892174

这比我们在之前的博客中使用线性回归获得的结果要好。

这个故事到此为止。这个 Github repo 包含了这个博客的所有代码,用于 Boston housing 数据集的完整 Jupyter 笔记本可以在这里找到。

结论

在这个机器学习系列中,我们介绍了线性回归和多项式回归,并在波士顿住房数据集上实现了这两个模型。

我们将在下一篇博客中讨论逻辑回归。

感谢阅读!!

再倒一杯咖啡!—为什么所有业务都将成为数据业务

原文:https://towardsdatascience.com/pour-another-coffee-why-all-businesses-will-become-data-businesses-3bb63c943b23?source=collection_archive---------10-----------------------

在我与多个垂直业务领域的首席技术官和首席信息官的多次交谈中,我听到的最常见的主题是: “我们的组织落后了,我们需要振兴——我们现在希望成为数据驱动的企业” 。如果这听起来很熟悉,要知道你并不孤单,你可以与大量优秀的资源合作,为推动这一转型提供一个平台(想想微软、IBM、亚马逊和谷歌),以及一系列智能系统集成商(普华永道、埃森哲等)。)来帮助部署。但这不是一场向你灌输产品和解决方案的竞赛,这是求爱之外的第一个阶段,也是共生伙伴关系的开始。了解你的业务,它是如何运作的,以及对你的客户来说什么是最重要的,这已经成为一次优雅的技术对话的中心。组织的数据存放在哪里、用于什么目的、如何分析以及谁需要根据数据中的趋势洞察做出决策不再仅仅是 it 部门的事了,现在这些都属于高管层。

根据国际数据公司(IDC)在刚刚过去的 2017 年 3 月发布的研究新闻稿,组织中超过 47%的 IT 支出现在将属于核心运营业务部门,业务线(LoB)支出的复合年增长率为 5.9%。(关于这笔支出是如何分配的,见下图)。这在哪些业务领域最为普遍?根据同一项研究,前五大业务线包括: 【离散制造、医疗保健、媒体、个人和消费者服务以及证券和投资服务】

(2017 年业务线支出最多的领域:应用、面向项目的服务和外包 )

好吧,所以我们不要开始挑剔它,它们不会很快被机器人取代,它们仍然承载着数据驱动型组织中最重要的业务功能:安全*(它们有助于保护我们的数据免受网络攻击,还记得 Equifax 吗?)*。现在,IT 比以往任何时候都更紧密地融入到企业利用数据的方式中,他们不能/不会独自完成这项工作。但是,当首席技术官&首席信息官致力于为这个多节点技术机场建造一条新跑道时,你作为<插入营销、财务、运营、销售的副总裁>将需要让飞机着陆。

“首席执行官,您的数据需要您的帮助!”

IBM 的首席执行官 Ginni Rometty 在她的 CES 2016 主题演讲中说了一些让我非常感动的话:

“数据是世界上最宝贵的自然资源……80%的数据是黑暗的……挑战在于理解它”

这种想法是,暗数据,或者说我们生活中每时每刻都可以收集的数据,是一种丰富的资源,只等着那些处于战略地位并有能力这样做的企业来收集。

想一想你一周的典型旅程图*(或者与我们的会议更相关,想一想零售中心的顾客旅程图:见下文)*。周一早上你开车去上班,和同事一起吃午饭,发一些邮件。当然,我们知道我们开了多少英里,吃了多长时间的午餐,但这里缺少了一些有价值的遥测数据:我们在通勤途中听了多少分钟的播客,它如何影响了你从上午 9 点到 11 点的项目效率?在特定时间吃特定的一餐会影响发送的邮件数量、长度或获得快速回复的成功率吗?我们开车的方式和我们走的路线与我们一天的开始或结束有关联吗,通过心率、睡眠习惯等来衡量。为了这些想法,请将隐私放在一边,想象一下,我们日常生活中的每时每刻背后的遥测技术如何帮助卡车车队减少事故,人力资源提高工作效率或增加员工在工作场所的保留率,并使大学能够构建智能地为最佳学习环境做出更多贡献的课程。

*(*典型顾客体验之旅图 在零售中心购买运动服装:非常感谢我的同事“快乐源于设计” 团队成员,我在奥斯汀的设计思维商业案例挑战赛中向他们展示了我们的原型,我们的原型获得了第一名。)

根据全球领先的技术研究和咨询公司 Gartner 的一些预测,到 2022 年,物联网(包括收集环境数据)将每年为消费者和企业节省 1 万亿美元的耗材、服务和维护成本。关键是,我们日常生活中的环境信息可以被捕获并用于绘制模式,以便更深入地了解*(想想 FitBit 让我们可以测量睡眠模式和步行活动)*我们是谁,以及我们如何才能达到/超过最佳基准。这是一个非常宝贵的商业机会,将结构化和非结构化数据收集到一个安全的存储库中,以便对其进行提取、建模和理解,将允许进一步渗透到为您的客户服务的空白领域。当然,人工智能是过去 20 年来科技领域最热门的话题 ( 见下文 ) 人工智能在公司收益电话会议中的持久性,现在正成为商业领域最热门的话题,但人工智能不能没有大量数据课程,它必须建立在这些数据之上并从中学习。

微软用“联网牛”做了一件令人兴奋的事情。牛群管理公司 SCR Dairy 与微软合作,帮助评估母牛何时发情,以便它们可以在正确的时间进行人工授精,实现最佳的小牛产量。这些数据是在连接到雌性奶牛的物联网设备上收集的,通过人工智能建模确定了雌性奶牛行走的步数与其发情倾向的相关性。事情并没有就此结束,随着所有数据的收集,更多的洞察力被用来创造“黑暗收入”,包括与雌性小牛出生的最高概率(这提供了更大的收入产生)的行走步数、小牛的健康等相关的模式。该系统还设计用于移动部署,以帮助牧场经理在野外进行扩展,从而降低劳动力成本并增加收获的数据。想象一下您自己的组织中可能出现的用例?

拉长长尾:从数据故事中获取$美元

随着企业变得更加数字化,他们参与创造额外收入流的能力将变得更加丰富,这要归功于我们的朋友:长尾。这一理论认为,当企业专注于特定的战略计划(服务和产品)时,在这些焦点上产生最大的收入,当他们离开这些点并进入他们不熟悉的点时,收入就会下降。尽管随着更多产品和服务的加入,收入现在会通过这些额外的产品和服务矢量进行汇总,如下图所示。当然,这是假设这些额外的新的点不是非常成本高昂或资产沉重(进入数据故事)。亚马逊 vs 沃尔玛,在沃尔玛成为“砖头和点击”之前,是长尾理论在起作用的一个完美例子。沃尔玛可能只想在它的砖臼中储存“前 40 本书”,而亚马逊理论上可以在其庞大的互联仓库网络中储存任意多的书籍。尽管亚马逊提供的利基“猫书”并不是最畅销的,但这些书的广泛可用性沿着尾巴向下延伸,增加了更大的收入。

( )——感谢马丁·福特,在他的书中提出了这些观点:《机器人的崛起》

回数据。让我们以汽车制造商为例。传统汽车制造商的重点领域可能包括几个不同的收入来源,主要是汽车销售和服务(即通用汽车的安吉星)。现在,如果通用汽车将自己定位为战略性地利用其数据资产,利用数据提供更多的创收服务,这些服务单独来看并不令人印象深刻,但累积起来会提供令人印象深刻的产品/服务流“长尾”,当然还有收入。基于从多年的历史和流式(IoT)服务数据中生成的关于轮胎磨损和刹车使用的预测分析,构建一个移动平台,以便在用户的车辆需要维护时联系他们。使用相同的数据来预测客户何时会来进行特定的维护项目,为连接的供应链提供及时的交付,智能的劳动力调度,或规定地建议销售团队为特定的汽车 / 加满油,并为客户来进行例行维护做好试驾准备。这些数据是否可以用来计算客户按月付费的多层消费模式会员资格,并驾驶一个**【共享】**车队?

在这里,我们相互问了很多问题,我们也涉及了很多领域——总的来说,技术有很多不同的方式从成本中心发展到增长中心。它发生得非常快。

现在,您可以在本季度开始做些什么,以确保您的业务更多地成为经济驱动力,并拥有数据驱动的副驾驶员?

请随时联系我进行更多讨论,也可以在 LinkedIn 上关注我。

单个神经元的功率

原文:https://towardsdatascience.com/power-of-a-single-neuron-perceptron-c418ba445095?source=collection_archive---------6-----------------------

Neuron (Image Source: https://pixabay.com/illustrations/nerve-cell-neuron-brain-neurons-2213009/)

Basic Unit of a Artificial Neural Network — Artificial Neuron

神经网络是由个基本神经元 —也叫个感知器(上图所示的一个基本单元——中间的绿色圆圈)排列成多层网络的组合(下图中的*)。要了解大型网络的工作原理和功率,首先我们需要了解单个单元的工作原理和功率。这就是我们在这篇文章中要关注的!*

A Network of Neurons

理解任何算法工作的最好方法是尝试自己编写代码。如果您可以编写一个简单的代码,通过计算每次迭代中的质心来创建数据聚类,那么您就知道 k-means。如果您可以编写一个简单的代码,在一个数据子样本上创建多个决策树,并从每个树上获取最大投票来分类一个数据点,您就知道随机森林。同样,如果您可以编写一个简单的代码,通过使用梯度下降来求解一个简单的线性方程、两个线性方程和多个线性方程,您就理解了神经网络和梯度下降。

梯度下降

神经网络的主干是梯度下降。要编写梯度下降的代码,我们首先需要理解它。

假设我们有一个简单的线性方程来求解

这里,我们需要找到 w1 和 w2 的值,这使得等式对于给定的 y、x1 和 x2 的值为真。如果我们简单地猜测 w1 和 w2 的值,我们将得到 y_hat

我们可以通过下式计算由于猜测 w1 和 w2 的值而产生的误差

Cost Function

也就是我们一般所说的成本。现在,我们的目标是找出 w1 和 w2 的值,使得成本 C 最小。成本 C 是相对于 w1 和 w2 的可微分函数。根据一些微积分复习资料,如果我们对 w1 和 w2 的函数进行微分(求导),并使其等于 0,我们将得到 w1 和 w2 的值,此时成本将达到最小值。

Gradients

这些导数称为梯度。基本上,函数在某点的导数是该函数在该点的切线或梯度。看上面的等式,我们不能得到 w1 和 w2 的值,其中成本导数将是 0,因为它们依赖于 w1 和 w2。

现在,为了达到最小值,我们将通过每次少量更新权重,开始朝着最小值的方向(这意味着与梯度方向相反)迈出小步。简而言之,我们是在切线或梯度的相反方向下降——这就是名字**“梯度下降”的原因。**

Gradient Descent

Pictorial Representation of Gradient Descent (Image Source: https://scipython.com/blog/visualizing-the-gradient-descent-method/)

手动编码单神经元解简单线性方程

使用实现梯度下降的 numpy

纪元是我们朝着成本最小化迈出一小步的迭代。学习速度告诉你要迈出多小的一步。一大步永远不会让你达到最小值,而非常小的一步要花太多时间才能达到成本最小值。

通过让 x1 = 3、x2 = 8 和 y = 41 来测试函数

Results

人们可以争辩说,一个方程可以有多个解——神经元将找到最接近开始猜测的解。

单神经元求解两个线性方程

同一个函数可以修改为求解两个方程。这个时间成本函数将是

Cost Vs Epochs

单个神经元求解多个线性方程组

同一个函数可以修改成解多个方程。这个时间成本函数将是

Cost function for Multiple Equations

如果误差随着每个 epoc 的增加而增加,则降低学习率。如果误差减小,但没有低于阈值,则增加周期数(n _ 周期)。

本文简单介绍了梯度下降算法,以及如何使用 numpy 求解线性方程来创建基本神经元。

以上所有代码都可以在我的 git repo 找到。

欢迎评论和反馈!

举重数据和探索性数据分析第 1 部分

原文:https://towardsdatascience.com/powerlifting-data-and-exploratory-data-analysis-part-1-6f21d79ac5db?source=collection_archive---------3-----------------------

几周前,我发现自己在互联网上搜索起重数据。我一直喜欢健身,我想知道是否有任何可行的数据集,可以量化我的一个爱好。然后我偶然发现打开了 Powerlifting 的力量举数据库。OpenPowerlifting 存储了全国各地 Powerlifting 会议上完成的 300,000 多台电梯的数据。我很快发现自己在搜索著名的举重运动员,如马克·贝尔、布兰登·莉莉、斯坦·埃弗丁和乔尼·坎迪托。找到那些大人物后,我也在数据集中搜索朋友 AlanZhou 。我对 OpenPowerlifting 收集的数据感到高兴和好奇。我决定,当我有时间时,我会重新访问数据集,看看是否有什么我可以做的。

以下是 OpenPowerlifting 对他们的数据的看法:“OpenPowerlifting 项目旨在创建一个永久、准确、方便、可访问、开放的世界举重数据档案。为了支持这一使命,所有的 OpenPowerlifting 数据和代码都可以以有用的格式下载。没必要刮这个网站。”过去我花了几天时间浏览网站,破译写得很糟糕的 HTML 代码,很高兴在 OpenPowerlifting 的 Github 上找到了一个可随时下载的 CSV 文件。

其他数据工程师、数据科学家、软件开发人员和数据分析师喜欢举重,这让我欣喜若狂。OpenPowerlifting 背后的人和我有两个共同点,举重和数据科学。我决定把计时器打开半小时,看看我能做些什么数据。我实施这个时间限制仅仅是因为我可以看到自己在数据上花费了过多的时间,而且我还有其他更紧迫的截止日期要赶。

下表是三大电梯的简单分类。我把数据分成男性和女性两组。此外,我已经包括了总数和威尔克斯系数的平均值。

现在,我要说的是,其中的一些测量对我来说似乎有点偏差。为了更好地理解分布情况,我绘制了直方图,并将它们包含在下面。力量举重的年龄分布特别有希望。我们看到大量年轻人加入这项运动并参与竞争。这可能是由于 YouTube 健身名人的受欢迎程度,如马克·贝尔、奥马尔·伊素福、沉默的麦克、杠铃旅和坎迪托训练总部。希望这一趋势在未来继续下去。

观察男性和女性的散点图表明,体重和举重之间存在正相关。这是显而易见的。但是基于这些散点图,我相信与深蹲相比,体重增加一个单位增加一个人的板凳深度最少,硬拉增加最多。我将在本分析的第二部分尝试证明(或否定)这一假设。我把这个小项目分成两部分的原因是,在我的 30 分钟结束时,我只完成了很少的工作。我计划在第二部分做一些实际的机器学习,所以敬请关注!

一旦我完成分析,我会在 Github 上公开我的 Jupyter 笔记本。下面是打开力量举重的链接。

http://www.openpowerlifting.org/data.html

https://github.com/sstangl/openpowerlifting

数据科学写作的实用建议

原文:https://towardsdatascience.com/practical-advice-for-data-science-writing-cc842795ed52?source=collection_archive---------5-----------------------

(Source)

撰写数据科学项目的有用技巧

写作是每个人都想做的事情,但是我们经常发现很难开始。我们知道写关于数据科学项目的文章可以提高我们的沟通能力,打开大门,让我们成为更好的数据科学家,但是我们经常纠结于我们的文章不够好或者我们没有必要的背景或教育。

我自己也一直在与这些感觉作斗争,在过去的一年里,我已经形成了一种克服这些障碍的心态,以及关于数据科学写作的一般原则。虽然写作没有一个秘诀,但有一些实用的小技巧可以让你更容易养成高效的写作习惯:

  1. 目标达到 90% :完成的不完美的项目比你从未完成的完美项目要好
  2. 一致性有助于:你写得越多,就越容易
  3. **不要担心证书:**在数据科学中,没有任何障碍阻止你贡献或学习任何你想学的东西
  4. 最好的工具是完成工作的工具:不要过度优化你的写作软件、博客平台或开发环境
  5. **广泛而深入地阅读:**借鉴、混合和改进他人的想法

在这篇文章中,我们将简要地讨论每一点,并且我将谈到我是如何实现它们来提高我的写作水平的。在几十篇文章的过程中,我犯了很多错误,你可以从我的经历中学习,而不是自己犯同样的错误。

完美被高估了:目标是 90%

我必须克服的最大的精神障碍,也是我经常听到其他人与之斗争的想法是“我的写作/数据科学技能不够好。”这可能会使人变得虚弱:当考虑一个项目时,人们会合理化,因为他们不能达到完美,他们甚至还不如不开始。换句话说,他们让 完美成为了 善的敌人。

这里的谬误是,只有完美的项目才值得分享。然而,一个粗略完成的项目要比一个永远无法完成的理想化项目好得多。

虽然在某些领域,完美的表现是可以预期的——你希望你的汽车刹车每次都能正常工作——但写博客不在这些领域之内。回想一下您最近一次阅读数据科学文章的情形。我猜(尤其是如果你读了我的一篇文章)它至少有一些错误。然而,你可能还是完成了这篇文章,因为重要的是内容的价值。只要文章有引人注目的内容,我们愿意忽略一些错误。

当我写作时,我的目标是让我的文章可读,并做一些编辑,但我不再要求它们完全没有错误。实际上,我的目标是 90%,超过 90%就是额外奖励。发布一篇有一些错误的文章总比一点错误都没有要好(如果你关心语法/风格,我推荐免费的语法工具)。

这种态度不仅限于编写数据科学项目本身。总会有另一种方法可以尝试,或者进行另一轮模型调整。在某一点上,这项工作的回报将少于投入的时间。知道何时停止优化是一项重要的技能。不要让这成为一个半途而废的项目的借口,但是不要强调试图达到不可能的 100%。如果你犯了几个错误,那么你有机会通过把你的工作拿出来征求反馈来学习。

愿意完成不完美的工作,积极回应建设性的批评,这样下次你就不会犯同样的错误。

做一次事情不会让你变得更好:一致性很重要

虽然10000 小时法则已经被揭穿(事实证明,当你练习时专注,被称为“刻意练习”,至少和你练习多少一样重要)对于在一项任务中积累更多的经验还是有好处的。写作不是一项需要特殊能力的活动,而是一个需要反复掌握的过程。

写作也许从来都不简单,但随着练习,它会变得越来越容易。此外,写作是一个正反馈循环:随着你继续写作,它会变得更容易,你的写作也会变得更好,从而让你想写更多。

我写作的一个重要障碍是开始,我喜欢把它看作是激活能量。随着你写得越来越频繁,开始写作的障碍就越来越低,开始写作所需的摩擦也就越来越少。一旦你开始了,你通常会度过最困难的部分。

如果你坚持写作,你可以把你的心态从“现在我要去从这个活动中抽出时间来写”转变为“现在我已经完成了这个项目,是时候像往常一样写了。”即使是写失败的项目也会很有价值。对每个项目进行写作强化了这样一个概念,即写作不是一件额外的苦差事,而是数据科学管道的一个关键部分。

写作往往不仅仅意味着分享文章。当你在进行分析时,试着在你的 Jupyter 笔记本上添加更多的文本单元格来解释你的思维过程。这是我最初开始写博客的方式:我开始彻底注释我的笔记本,并意识到写一篇文章只需要多做一点工作。此外,当你开始向你的代码添加解释时,你未来的自己和看你作品的同事会感谢你。

写我的前几篇文章确实感觉像是一件苦差事,但当我习惯了这不会是一次性的事情的想法,它变得容易得多,直到我达到了它是我工作流程中被接受的一部分的地步。习惯极其强大写作和其他习惯一样都是可以习得的。

头衔在数据科学中毫无意义:不要担心证书

想想你上一次安装 Python 包或者从 GitHub 派生 repo 的时候。你搜索过拥有高等学位的作者吗?你只看了专业软件工程师写的代码吗?当然不是:您甚至在检查作者的证书之前就已经查看了存储库的内容(如果您愿意的话)。

同样的概念也适用于数据科学文章:对它们的评判是基于工作的质量,而不是作者的资历。在互联网上——不管是好是坏——出版没有任何障碍。不需要任何证书,不需要攀登象牙塔,不需要通过考试,也没有门卫阻止您学习和撰写任何数据科学方面的内容。虽然某方面的大学学位是有用的(我有一个机械工程学位,尽管从未使用过,但我并不后悔),但对数据科学做出贡献肯定是不必要的(T2)。

在这篇出色的文章中,专业机器学习研究人员 Rachel Thomas 给出了她的观点,即为什么即使在深度学习中,高级学位也不是必要的。以下是她列出的没有博士学位的深度学习贡献者的部分列表:

A partial list of contributors to deep learning who don’t have a PhD. (Source)

在数据科学中,你获取新知识的能力比你的教育背景更重要。如果你对某个科目没有信心,那么有很多资源可以让你学习你需要知道的东西。我个人可以推荐 Udacity,Coursera,还有 Scikit-Learn 和 TensorFlow 的优秀的动手机器学习作为我最喜欢的资源,但是还有无数其他的。虽然 MOOCS 没有在所有科目上完全“民主化教育”,但它们在数据科学上取得了成功。

不要因为你认为自己没有背景而阻止自己接受一个项目。我最初担心我的资历,但在我从读者的角度思考之后——人们在网上阅读他们的文章之前不会考虑某人的头衔——我发表文章变得容易多了,不用担心我的背景。此外,一旦你意识到你的教育来自哪里并不重要,你会发现学习起来容易得多,因为你可以不再认为正规教育是唯一的信息宝库。对于数据科学,你可以从互联网上了解你需要的一切,通常比你在教室里学到的要快得多。

保持开放的心态也很重要:当我不完全确定我是否使用了正确的方法时,我会在文章中承认,并且我总是欢迎任何纠正。做数据科学没有标准的方法,但是你仍然可以从其他有解决类似问题经验的人那里学到很多。

认识到你可以学习任何必要的东西来独自承担任何数据科学项目,但也要虚心接受建议。

最好的工具是完成工作的工具

Windows vs MacOS。 R vs Python 。崇高 vs 原子 vs 皮查姆。媒体 vs 你自己的博客。这些争论都是无益的。正确的回答是使用任何能让您解决问题的工具(在您的环境范围内)。此外,具有更多选项的工具并不总是更好的

虽然更多的功能听起来很棒,但它们经常会妨碍你的工作。一般来说,我尽量让事情简单。当人们问我关于写作平台的建议时,我说中等,因为它的功能有限。当我写作时,我想把注意力集中在内容上,而不是花时间试图按照我想要的格式编排每一件事。

更多的定制选项意味着更多的时间来定制这些选项,而更少的时间来做你应该做的事情——写作或编码。

我以前陷入过工具优化循环:我被说服转而使用新技术,花时间学习新功能,却被告知这项技术已经过时,下一个将会让我更有效率。不久前,我停止了 ide(集成开发环境)之间的切换,只选择了 Jupyter + Sublime Text,因为我意识到额外的东西只会妨碍编写代码。

当论点足够有力时,我并不反对转换工具,但是仅仅为了新奇而转换工具并不是提高生产力的良方。如果你真的想开始,挑一叠坚持下去。如果你开始一个项目,并注意到你的工具中缺少一些东西,那么你可以开始寻找你需要的东西。不要轻信承诺更多功能的华而不实的新工具,直到你知道你需要那些功能(这也适用于买车)。换句话说,不要让工作程序的优化妨碍工作。

Choose a strategy and stick with it! (Source)

从哪里获得你的想法:广泛而深入地阅读

伟大的想法不会脱离所有其他想法而自行涌现。相反,它们是通过将旧的概念应用到新的问题中来创造的,混合两种现有的想法,或者改进一个已被证实的设计。想知道该写些什么的最好方法是阅读其他数据科学家正在写的东西。当我陷入一个问题或者需要一些新的写作想法时,我不可避免地开始阅读。

此外,如果你对自己的写作风格不自信,可以从模仿你最喜欢的作家开始。看看他们文章的结构,以及他们如何处理问题,并尝试将相同的框架应用到你的项目和文章中。每个人都必须从某个地方开始,建立在别人的技术上并不可耻。最终你会发展出你自己的写作风格,然后其他人可以适应,等等。

我建议广泛阅读和深入阅读,以平衡探索与开发。探索/利用问题是机器学习中的一个经典,特别是在强化学习中:我们有一个代理需要平衡对环境的更多学习,探索,与选择基于它认为会导致最高回报的行为,利用

通过广泛阅读,我们探索了数据科学的许多不同领域,通过深入阅读,我们加深了对特定专业领域的理解。你可以通过练习已经掌握的技能——利用——并经常学习新的技能——探索,将这一点应用到你的写作和数据科学中。****

我也喜欢将探索/利用的想法应用于选择数据科学项目。这两个极端都可能导致令人不满意的项目:只根据你过去做过的事情来选择一个项目,你可能会发现它已经过时并失去兴趣。如果你选择了一个你不能应用任何先验知识的项目,那么你可能会感到沮丧并放弃。相反,找一些中间的东西,你知道你可以建立那些你已经拥有的技能,但也需要学习一些新的东西。

我对选择项目的最后建议是从小处着手。项目只会随着你的工作而成长,无论你分配给项目多少时间,它都会花费更长的时间。承担一个完整的机器学习项目可能很诱人,但如果你仍在尝试学习 Python,那么你可能想一次解决一部分。也就是说,如果你有足够的信心承担整个项目,那就去做吧!没有比练习更有效的学习方法了,尤其是把所有的碎片放在一个问题里。

结论

正如任何延迟长期回报的活动一样,写作有时会很困难。尽管如此,还是有一些具体的行动让这个过程变得更容易,并且创造了正反馈循环。写作没有一个秘密,而是一系列的步骤,减少开始写作的摩擦,帮助你坚持下去。当您开始或推进您的数据科学职业生涯时,请记住这些提示,以建立和保持高效的写作习惯。

我欢迎关于写作建议、评论和建设性批评的讨论。可以通过推特 @koehrsen_will 联系到我。

相关性测量实用指南

原文:https://towardsdatascience.com/practical-guide-to-correlation-measures-cf8abf534649?source=collection_archive---------6-----------------------

TLDR: 在大多数情况下,使用肯德尔是最好的选择。

Image source

相关性度量

相关性度量用于衡量两个变量之间的相关程度。根据数据类型和用例,可以使用不同种类的相关性度量。一些常见的相关性度量是皮尔逊、斯皮尔曼和肯德尔相关性。在这篇文章中,我将试着简要解释这些工具的作用以及何时使用它们。这些公式可以很容易地在其他地方找到,实现可以在 Pandas 库中找到。

皮尔逊

可以计算两个变量之间的相关程度,但是它假设数据是线性的和同方差的。

  • 线性:如果 X,Y 是直线,则 X,Y 是线性的
  • 同方差性:X,Y 是同方差的,如果它们来自某个高斯分布。

那是什么意思?用简单实用的观点来说。

使用时

  • 数据似乎有一个简单的线性关系(如果有的话)。
  • 数据是稳定的(均值、方差等)。不要改变)
  • 数据似乎正态分布在一个中间点周围,有一些差异。
  • 有一些测试可用于确定数据是否来自正态分布。

不使用时

  • 数据是不稳定的
  • 数据不是线性相关的
  • 如果你把它用于非线性、非高斯数据,它会给出一些读数,但这些不会是可靠的相关性指标。

斯皮尔曼相关

这是一个更稳健的相关性度量,因为它没有对数据的分布做任何假设。然而,它只寻找单调的关系,通常适用于顺序变量。找出学生完成比赛的顺序和他们练习的时间之间的关系。注意,这仅捕获单调关系,如图 1 所示,然而它不能捕获如图 2 所示的非单调相关变量。

Fig 1: Spearman coeff = 1

Fig 2: Spearman coeff = 0

注意:Spearman 相关性有助于确定两个变量是否独立,但是当它们相关时,它不能传达太多信息。

使用时

  • 这种关系是单调的(要么总是增加,要么总是减少)
  • 变量值的顺序可能是感兴趣的(Spearman rho)
  • 有必要检查独立性

肯德尔相关

肯德尔相关性不像 Spearman 那样对数据的分布做任何假设。Spearman 有一个缺陷,即很容易发现是否存在单调相关性,如果存在单调相关性,则值很难解释。另一方面,Kendall 可以量化变量之间的依赖强度。

优点

  • 非参数(不假设数据的分布)
  • 可用于确定两个变量是否相关
  • 可以量化,有多少依赖。

参考

Minitab Express Support 的相关页面
statistics solutions . com 的相关页面
维基百科—皮尔森相关
维基百科—斯皮尔曼相关
Statsdirect —肯德尔相关
维基百科—肯德尔相关

原载于say tosid . github . io

实用强化学习—02 Q-Learning 入门

原文:https://towardsdatascience.com/practical-reinforcement-learning-02-getting-started-with-q-learning-582f63e4acd9?source=collection_archive---------0-----------------------

最简单的 Q 学习入门。浏览器中的代码,未安装:)

Smart Cab — GridWorld

这一次,我们将教会我们的自动驾驶汽车开车送我们回家(橙色节点)。我们必须小心,因为一些街道正在建设中(灰色节点),我们不希望我们的车撞上它。

如你所见,我们有从 0 到 8 的街道。这给了我们 9 个独特的(街道)。在任何给定的时间,我们的汽车(代理)可以处于这 9 种状态之一。状态 8 是我们的目标,也称为终端状态

我们的车可以左、右、上、下行驶。换句话说,我们的代理可以采取四种不同的动作。我们把它写成:A∈A {上,下,左,右}

代理因达到终止状态而获得奖励 10,除此之外没有奖励。

Q 学习和 Q 表

现在我们将创建一个矩阵,“Q”也称为 Q-table,这将是我们代理的大脑。矩阵 Q 被初始化为零,因为代理开始时什么都不知道(就像约翰·斯诺;))。当它学习时,它用状态-动作对的新值更新 Q 表。下面是计算 Q[状态,动作]的公式

Q[s,a] = Q[s,a] + alpha(R + gammaMax[Q(s ',A)] - Q[s,a])

哪里;

  • alpha学习率,
  • 伽玛贴现因子。它量化了我们对未来奖励的重视程度。在未来的奖励中估算噪音也很方便。伽玛从 0 到 1 不等。如果 Gamma 接近于零,代理人将倾向于只考虑直接的回报。如果 Gamma 更接近 1,代理人将考虑更大权重的未来奖励,愿意延迟奖励。
  • Max[Q(s ',A)]给出下一状态中所有可能动作的最大 Q 值**。**

代理探索不同的“状态-动作”组合,直到它达到目标或落入洞中。我们将把每一次探索称为。每次代理到达目标或被终止,我们开始下一集。

Q-table

下面用一些简单的数学来演示 Q-table 是如何更新的:
取学习率(alpha)为 0.5 &折现因子(gamma)为 0.9
Q[s,a] = Q[s,a] + alpha*(R + gammaMax[Q(s ',A)] — Q[s,a])
早期剧集
Q[3,L] = Q[3,L]+0.5
(10+0.9Max[Q(8,U) 同样 Q[6,D] = 5
下一集
Q[2,L] = Q[2,L]+0.5
(0+0.9*Max[Q(6,U),Q(6,D),Q(6,R),Q(6,L)]-Q(2,L))
Q[2,L] = 0 + 0.5 * (0 + 0.9 * Max [0,5,0,0] -0)
Q[2

勘探与开采—ε(ε)

当代理开始学习时,我们希望它采取随机行动来探索更多的路径。但是随着代理变得更好,Q 函数收敛到更一致的 Q 值。现在,我们希望我们的代理利用具有最高 Q 值的路径,即采取贪婪的行动。这就是艾司隆的用武之地。

智能体对概率 ε 采取随机行动,对概率采取贪婪行动(1-ε*)。*

Google DeepMind 用了一个衰减的ε-贪婪动作选择。其中ε 随时间从 1 到 0.1 衰减*——开始时,系统完全随机地移动以最大化地探索状态空间,然后它稳定到固定的探索速率。*

q 学习伪代码

是时候动手 Q 学习了

现在继续用 OpenAI 健身房练习 Q-learning。你可以在你的浏览器中使用 azure 笔记本来完成。或者克隆这个 git 回购

更多资源

强化学习:简介 —第六章:时差学习
大卫·西尔弗的强化学习课程第四讲 —无模型预测
大卫·西尔弗的强化学习课程第五讲 —无模型控制

希望这篇教程对刚接触 Q-learning 和 TD-reinforcement 学习的人有所帮助!

如果你想关注我关于强化学习的文章,请在 Medium Shreyas Gite 或 twitter @shreyasgite 上关注我。
如有任何问题或建议,请随时给我写信:)

更多来自我的实用强化学习系列:

  1. 强化学习简介
  2. Q-learning 入门

将风格转移到工作中的实用技巧

原文:https://towardsdatascience.com/practical-techniques-for-getting-style-transfer-to-work-19884a0d69eb?source=collection_archive---------3-----------------------

不熟悉风格转移的可以看这篇总结风格转移的博文

作为杰瑞米·霍华德的第二部分课程“程序员的前沿深度学习的参与者,我想建立一个风格转移神经网络,它的性能与 prisma 不相上下(在生成图像的时间和图像质量方面)。该项目涉及许多有趣的挑战(图像质量、推理时间)。

我首先进行了许多实验,看看如何提高生成图像的质量。以下两篇博文详细介绍了这些实验:

  1. 风格转换不同损失配置实验
  2. 让初始架构与风格转移一起工作

这篇博文总结了我从这些实验中学到的东西,并包含了一些更实用的技巧来实现风格的转变。

实际环境中的风格转换

上述两篇博文使用了基于图像优化的方法进行风格转换,即通过最小化损失来学习图像像素。在实际设置中,假设你正在构建一个像 prisma 这样的应用程序,这种技术是没有用的,因为它非常慢。因此,取而代之的是使用基于神经网络的方法,其中训练神经网络从内容图像生成风格化图像。这些是在 AWS p2x.large 实例上使用两种方法对一个 1000x1000 图像所花费的时间:

基于优化的方法(NVIDIA K80 GPU): 172.21 秒

基于神经网络的方法(NVIDIA K80 GPU): 1.53 秒

基于神经网络的方法(英特尔至强 E5–2686 v4):14.32 秒

显然,基于神经网络的方法是这里的赢家。基于神经网络的风格转换只是基于优化的方法的近似,但是要快得多。

要详细了解基于神经网络的方法是如何工作的,您可以阅读以下文章:

  1. 实时风格转换和超分辨率的感知损失
  2. 艺术风格的学术表现

基于优化的方法描述于:

  1. 艺术风格的神经算法

提高生成图像的质量

让深度学习变得众所周知困难的一件事是搜索最佳超参数。并且风格转移涉及各种超参数,如使用哪些内容层来计算内容损失、使用哪些风格层来计算风格损失、内容权重(与内容损失相乘的常数)、风格权重(与风格损失相乘的常数)、电视权重(与总变化损失相乘的常数)。幸运的是,在风格转换中找到最佳超参数要容易得多。

简单的窍门是:

不使用基于神经网络的方法来训练和寻找最佳超参数,您可以简单地在您的测试图像上使用基于优化的方法来创建它们的风格化版本和交叉验证。

以下是我从实验中学到的关于如何使用基于图像优化的方法来寻找风格化超参数的一些东西。

1.使输出图像更平滑

总变差损失是输入图像中相邻像素值的绝对差值的总和。这衡量图像中有多少噪声。

如这篇博客文章的中的实验 10 所示,将总变差损失添加到训练损失中去除了图像的粗糙纹理,结果图像看起来更加平滑。

2.选择样式层

在大多数发表的作品中(包括的开创性论文),从网络中选择一些层来计算风格损失,并给予相等的权重。正如我在这篇博文中的实验#1 所示,这没有意义,因为不同层次对风格损失的贡献可能相差很大数量级。为此,我首先从每一层中找出输出,一次一个。然后通过给每一层赋予权重来创建一个组合图像。通过交叉验证可以再次找到权重。

3.选择内容层

与选择样式层的情况不同,选择内容层的组合不会产生太大的差异,因为优化一个内容层的内容丢失会优化所有后续层。使用哪一层可以通过交叉验证再次找到(如这篇博文的的实验#2 所示)。

4.修改损耗网络以改善收敛性

vgg-16/vgg-19 网络(在 imagenet 上预训练)通常用于计算内容损失和样式损失。正如我在这篇博文的的实验 8 中所示,用平均池替换最大池显著减少了收敛时间。

我尝试的另一个改变是,用有效的填充替换相同的填充,但效果并不明显。

5.样式图像的大小和裁剪区域

正如我在这篇博文的实验 4 中所展示的,风格图像的大小很重要。如果您使用的是较小尺寸的样式图像,则网络无法计算出足够的样式信息,并且生成的图像质量较差。根据我的实验,我会说风格图片的尺寸至少应该是每边 512。

这篇博文的实验 11 所示,风格图像的裁剪区域也很重要,这应该根据包含我们想要的风格化图像中的笔触的区域来选择。

6.选择内容、风格权重和电视权重

这些权重只能通过交叉验证找到。但是这里有几条规则,我遵守了,并且做得很好。

当你开始训练时,首先风格损失迅速降低到某个小值,然后内容损失开始降低,风格损失要么降低得更慢,要么波动。这个内容损失和风格损失减少的图表可以在这篇博文的实验#6 中看到。此时,内容权重应使内容损失明显大于样式损失。否则网络将不会学习任何内容。

电视权重应该是这样的,即在训练的后期迭代中,电视损失是内容损失的一半。这是因为如果电视损耗非常高,图像中相邻物体的颜色会混合在一起,图像质量会很差。

7.选择损耗网络

的实验#3、#4、#5、#6 这篇博文详细介绍了如何通过使用不同的初始网络来生成不同种类的图像。使用盗梦空间网络生成的图像看起来更像蜡笔画。

的实验#5 这篇博文比较了使用 vgg-16 和 vgg-19 生成的图像。我的猜测是,使用 vgg-16 生成的图像也可以使用 vgg-19 生成,只需调整内容和样式损失即可。这是因为从这些网络中产生的仿制品没有太大的不同。使用 vgg 网络生成的图像看起来更像油画。

所以如果你针对的是油画质感,就用 vgg-16 和 vgg-19。如果你的目标是蜡笔纹理,使用任何一个初始网络(交叉验证后)。

改善训练和推理时间

假设您正在尝试 10 种不同的风格转换架构,以找出哪种最有效。加速训练以快速交叉验证你的模型变得非常重要。

如果你是和 Prisma 竞争,你需要保证你的网络的推理时间和他们的不相上下。

以下是我用来提高训练和推理时间的技巧。

1.对训练图像进行下采样

最简单的做法是将图像从 512x512 下采样到 256x256,然后测试生成的图像看起来有多好。它将训练时间减少了 4 倍,但可以很容易地用于寻找最佳网络架构,因为使用 512 生成的图像质量与使用 256 生成的图像质量非常相似。

2.使用深度方向可分离卷积代替卷积

这是改善推断时间的最标准的技巧,其中卷积层被深度方向可分离的卷积代替。这导致计算量显著减少。下面是在 aws p2x 大型实例上使用卷积和深度方向可分离卷积的图像的 CPU 和 GPU 推理时间。

inference times using convolution (in secs)

inference times using separable convolution (in secs)

可以看出,图像的推理时间在 CPU 上大约减半,在 GPU 上减少 5-6 倍。生成的图像质量没有明显差异。

3.对图像进行下采样,最后添加上采样层和卷积层

我尝试了许多非标准的架构变化来减少推理时间。一是减少神经网络的层数。另一个是改变卷积运算(将 filter _ size * filter _ size * in _ depth * out _ depth 卷积转换为 filter _ size * filter _ size * in _ depth * k,然后是 11k*out_depth 卷积,其中 k<<out_depth></out_depth>

有效的技巧是,在将图像输入神经网络之前,通过双线性插值将图像的高度和宽度减半。并添加上采样层,然后在末尾添加卷积层。这样你就是在训练你的神经网络学习风格转移和超分辨率

为什么会有帮助?与以前的方法相比,所有中间层的计算量减少了 1/4。增加的额外计算是由于一个额外的层和双线性插值。但是他们并没有增加很多时间,净时间要少得多。这些是 aws p2x 大型实例上图像的 CPU 和 GPU 推理时间。

inference times using baseline architecture (in secs)

inference times using the resize trick (in secs)

正如我们所看到的,这大大缩短了 CPU 的推断时间。并且还减少了大多数图像的 GPU 推断时间。

将此与可分离卷积技巧相结合,得到:

inference times using separable convolution and resize trick (in secs)

正如我们所见,结合使用这两种技巧可以将所有图像的 CPU 推断时间减少 3 倍,将 GPU 推断时间减少 8-10 倍。我在手机上运行了同样的神经网络。1000 x 1000 的图像需要 6.5 秒。作为对比,prisma 同样的图像需要 9 秒。

更酷的是。这两个技巧适用于任何图像生成方法,而不仅仅是风格转换。

此外,生成的图像质量是相同的:

image generated using baseline architecture (left) and using separable convolution and resize trick(right)

4.预计算训练数据的内容要素

训练数据中的每个图像都需要通过损失网络。并且一些层的输出将用于计算内容损失。这些内容层输出可以预先计算。这样可以节省训练时间。

以下是预计算和未预计算特征的训练时间:

average time without features precomputed

average time with features precomputed

因此,预计算特性带来了 10%的加速,虽然不是很显著,但已经足够了。所用的内容层是 conv4_1。

这些实验中使用的所有代码都可以从 github 上获得

如果你喜欢这篇文章,请点击下面的小拍手图标帮助他人找到它。非常感谢!

基于张量流服务的实用文本生成

原文:https://towardsdatascience.com/practical-text-generation-with-tensorflow-serving-3fa5c792605e?source=collection_archive---------1-----------------------

在这篇文章中,我将讨论深度学习模型通过 Tensorflow 的暴露和服务,同时展示我对灵活实用的文本生成解决方案的设置。

使用文本生成,我打算自动生成可变长度的新的语义有效的文本片段,给定一个可选的种子字符串。这一想法是为了能够利用不同用例的不同模型(Q & A,聊天机器人工具,简化,下一个单词建议),也基于不同类型的内容(例如,叙事,科学,代码),来源或作者。

这是句子建议的第一个预览。

Text generation example using seed text (the selected part in the video) for different training sources (i.e. song lyrics, Bible, Darwin)

这段录音显示了使用三种不同模型的按需文本生成,每种模型都基于不同的种子字符串,在相应的文本源(即歌词、钦定版《圣经》和达尔文的《物种起源》)上进行训练。正如预期的那样,每个模型都反映了原始资料的基调和内容——所有其他潜在的模型都是如此——并显示了其特定用途和场景的潜力,这仍然主要取决于作者的需求和期望。预览还允许获得模型性能的直观感受,暗示哪个模型需要改进以满足定义的需求。

下面的段落将准确地描述我遵循的体系结构方法,以获得第一个和后面的示例背后的文本生成功能的提供和使用。

建筑预览

即使 showcase 的重点是文本生成任务,许多与模型管理相关的内容也可以抽象出来。例如,我们可以确定三个独立的步骤,这些步骤已被证明适用于各种不同的用例及情况:

  • **训练:**很多领域里的东西大多都习惯;调查最佳方法,定义架构/算法,处理数据,训练和测试模型。
  • **上菜:**将训练好的模型曝光消费
  • **消费:**使用暴露的模型从原始数据中获得预测

最后两个步骤之间的区别更加微妙,并且很大程度上取决于工作设置和被识别为*的型号。*对于初学者来说,想想你为训练所做的数据预处理有多少实际上没有嵌入到你使用 Keras(或任何其他库)的实际训练中。所有这些工作只是转移到下一个架构块,但是需要委托给一个消费中间件,这样我们就可以通过一个干净的接口只公开基本的所需功能。

这里是我们的架构步骤和交互的示意图。

培养

我不打算深入研究文本生成训练的技术细节,但是如果感兴趣的话,您可以在这个 Jupyter 笔记本中找到本文的大部分训练代码,以及额外的指针和资源。

服务架构的好处是培训可以与其他组件高度分离。这允许通过提供更好的执行模型来快速、简单和透明地交付改进的版本。更好的训练数据、更可控的训练过程、更复杂算法的实施或新架构的测试,都是可以产生更好的模型的选项,这些模型反过来似乎可以取代当前提供的模型。

关于打破完美解耦的方面,例如考虑以下最紧迫的依赖关系:

  • 模型签名(输入/输出形状和类型),客户必须知道并遵循。目前没有办法直接从服务服务器发现这一点,因此需要“手动”保证与训练步骤的一致,以避免错误。一旦定义了一个签名,您就可以为新版本的模型服务,或者测试新的架构,而没有额外的负担,只要它在所有这样的模型中是一致的。
  • 培训时操作的前后处理需要在消费层“复制”。
  • 前/后处理的外部/附加模型数据(如单词索引)需要提供给消费层,同时保证与培训期间使用的数据一致。

模型

模型是我们训练过程的产物。我们可以首先根据它们的功能(例如分类、文本生成、问答)对它们进行分类,然后根据版本进行分类。

对于我们的文本生成案例,即使基本任务实际上是相同的,我们也可以考虑模型根据它们被训练的文本内容提供不同的功能。在大多数情况下,训练过程/代码实际上是相同的,改变的是所使用的训练数据。然后,版本化将特定于该模型功能和内容,并且可以在最简单的情况下通过沿着多个时期的训练过程的基本快照来确定,或者通过采用或测试新的算法和架构来确定。

这样做的想法是建立一个包含大量模型的中央存储库,可以根据需要添加新训练的版本。

作为一个实际的例子,考虑我的文件夹的这个快照,用于我们的三个模型的基本文本生成,每个模型都有可能有多个服务就绪版本、更细粒度的训练检查点(或快照)选择和单词索引数据。

partial tree of the models folder

服务

模型已经准备好了,我们需要一种方法来服务于它们:让它们可以被有效地使用。

TensorFlow 服务是一种灵活、高性能的机器学习模型服务系统,专为生产环境而设计对于那些已经熟悉 Tensorflow 并且没有心情编写自己的服务架构的人来说,这是一种非常好的直接方法。
它包括基于相关模型目录的自动化模型管理,并通过 GRPC 公开它们。樱桃放在上面,可以很容易的 Dockerized。

model config example

您可以在运行 Tensorflow 服务器的机器上拥有所有模型和相关版本的副本,或者您已经可以根据需要进行过滤,以拥有更轻的服务容器。然后,您可以指定直接运行哪个模型,或者通过启动服务服务器时需要传递的模型配置文件来运行。该文件应该为我们计划公开的所有模型指定一个模型配置列表。

然后,Tf 将负责为每个列出的模型提供服务,并自动管理版本。Tensorflow 将自动获取新版本的插入,而全新模型的注入将需要重新启动服务。
所有这些都可以手动完成,但对于生产设置,人们可能更喜欢开发一个“同步”实用程序,它应该负责从托管训练步骤实际结果的任何外部存储中同步 Tensorflow 服务容器内的模型数据。

强烈的

考虑我们当前的用例:我们想要获得特定类型或特定来源的生成文本,并且可选地以种子文本为条件。不幸的是,纯 Tensorflow 服务端点远没有这么直接。我们不仅需要转换文本(输入和输出),而且我们还必须实现一个生成过程,我们希望在最终的界面中完全透明。所有这些都需要委托给消费者中间件来实现。

这适用于许多其他数据科学场景,在这些场景中,导出的模型实际上只是从原始数据到可用预测的管道中的一部分。正如最初的架构模式中所描述的,将需要一个消费者中间件来填补这个预处理和后处理的空白。对于我们的文本生成案例,这个中间件和相关代码再次在我的 Github 库中定义。它包括一个负责文本预处理和后处理的基本类,一个文本生成过程(建立在多个模型调用和二级需求之上)和一个处理不同模型的代理。

假设所需的依赖关系已经解决,可以直接使用代理,否则我建议进一步简化任务,将所有内容公开为一个真正基本的 REST API:使用 Python 和 Flask ,只需要几行代码。此外,我们所有组件的模块化使得通过 Docker 和 AWS 等技术将解决方案外部化和扩展变得容易。

展示时间!

如何实际利用到目前为止描述的设置纯粹是想象和需求的问题(这篇文章很好地探索了各种形式的机器辅助写作)。最好的方面是,我们现在有了一个灵活的架构,可重用于各种场景,而没有太多额外的操作负担。

我烘焙的第一个实际例子是一个基本的文本编辑器插件,现在我正在积极地使用它。在我的情况下,我依靠崇高 3记事本++ T7。一旦我启动并运行了文本生成 API,为前者编写插件就相当简单了;下面实际上是所有需要的代码。

Sublime3 plugin for text-generation via REST API

这里发生的事情是,我自己写一些东西,选择我想用作种子的文本,然后调用首选模型上的生成。这是另一个例子。请再次注意,我在这里依靠三个不同的模型,分别接受了关于歌词的训练,詹姆斯国王版本的圣经和达尔文的物种起源。

text gen on same seed for different models. Again notice the weaker Bible one.

这个“文本应用插件”允许我从内容(完整的句子或单个单词)中获得灵感,否则很少会从我纯粹自发的写作中出现。虽然叙事和诗歌的更具创造性的上下文似乎更好地利用了这一工具,但我经常发现对更正式和“严格”类型的内容也有很好的建议,我相信用于训练的源数据集,同时相信“更有可能意味着正确”。

我正在开发的另一个应用是一个用于聊天和即时消息自动回复的 web 浏览器插件,也是通过简单地利用公开的 REST API。我们将会看到有多少我的朋友能区分我和 RNN。

words suggestion based on the song-lyrics dataset

words suggestion based on Darwin’s On the Origin of Species

结论

基于深度学习的技术的文本生成能力已经得到证明,并且适用于各种不同的用例及场景。在这篇文章中,我展示了一个基于 Tensorflow 的基础架构解决方案如何保证高度的灵活性和有效性,为您的内部作者创建一个实用的小文本生成工具箱。

我还相信,我们很快就会看到对预训练模型的更结构化、更精细和更民主化的访问。一种自助服务存储库——类似于其他流行服务——这样人们可以轻松地即插即用新模型,并将它们直接嵌入到任何选择的环境中,而不必从头开始训练它们。
例如,在本文的上下文中,如果能够访问其他人针对不同任务、文本内容或作者训练的模型,并且能够在一个公共平台或“模型中心”上分享我自己的训练结果,那就太好了。

但现在去;好好利用这些强大的机器来达到你的生产和创造目的;用不了多久,他们就会变得非常聪明,不适合这项任务。

专业数据科学初学者实用技巧。揭穿几个神话!

原文:https://towardsdatascience.com/practical-tips-for-beginners-in-data-science-debunking-few-myths-30537117a4e4?source=collection_archive---------11-----------------------

“A robot named Pepper holding an iPad” by Alex Knight on Unsplash

当我在 2015 年开始我的旅程到我现在的位置时,通过专业经验、MOOCs 和在线社区,我学到了很多东西。我认为是时候开始回报数据科学世界了,我以一些我觉得有必要谈论的事情开始了我的博客系列。

这篇文章特别针对那些刚开始数据科学职业生涯(或转投 it 行业)并且对与职业经历相关的一些事实有偏见/不了解的人。

1.黑客马拉松没有教会你的事情——定义问题

大多数人热衷于将机器学习算法应用于已经给出的原始(实际上并不那么原始)数据集,并给出明确的问题陈述。他们通常听起来像这样—“XYZ 公司希望自动化他们的贷款审批流程。使用给定的训练数据,您能识别分类和预测贷款批准的重要因素吗?请注意,评估您的标准是准确性"。这些问题陈述不知不觉地简化了某些事情,如定义问题、获得最终数据集、确定评估指标等。但在现实世界中,情况并非如此。

“记住,你 60%以上的时间都花在了识别/定义问题、集思广益和获取相关数据上。”

要开始解决这个问题——找到开源数据集,提出你的假设,问问自己这个数据集能解决什么问题,想想你可能用什么其他相关数据来解决这个问题。您可能最终会使用带有一些漂亮可视化效果的 t-test 来解决您的问题:)

2.SQL——最被低估的工具

SQL 对于数据科学就像高塔姆·甘比尔对于印度板球一样。如果你没有一个好的开始,你会在比赛中挣扎,但是,有时候,你会被胜利的 76 人遗忘。

毕竟 SQL 是用来取一些数据的。但是想象一下,您在客户级别的数据集上做了整个建模练习,意识到由于数据争论期间的一些错误的“SQL 连接”,数据有客户重复。“重复”是数据获取时的一个主要问题,这可能是因为您的 SQL 代码或后端数据库中的问题。在 SQL 数据争论的每一步之后,都需要进行彻底的质量评估,因为**“没有语法错误的执行并不意味着它按照你想要的方式执行。”**

对于初学者来说,大多数参考资料教授的是基本的 SQL,重点是语法部分,SQL 逻辑如此简单的观念变得越来越普遍,经常被忽视。我建议你选择一个不同主题(航空、电子商务、零售等)的关系数据库(一套 3-10 个表)。)并问一些棘手的业务问题。这将需要执行几个 SQL 块,并将充分测试您的技能。

3.r 还是 Python?两个都学。

已经有很多关于这个主题的博客,如果你读了其中的一些,Python 将会是赢家(以微弱优势)。我不想讨论每种方法的利弊,也不想决定什么,但是,我建议你学习两种方法,并在其中一种方法上获得专业知识。

比方说,RaceR 先生被介绍给 r。在他的旅程中,他喜欢 dplyr 的直观性,他觉得 ggplot2 是继他的女朋友和他的一行花式决策树情节之后的下一个美丽的东西。突然有一天,他接到了他梦想中的公司的面试电话,有一个绝佳的机会。但他知道的唯一令人心碎的事情是,那里的人觉得熊猫很可爱,他们通过 matplotlib 生成报告,并在云 GPU 上运行基于 Jupyter 笔记本的深度学习模型。他觉得他整个余生都是谎言。虽然我把这个故事戏剧化了,但寓意是学习并适应这两者,直到切换变得相当容易(可能是因为工作变化、客户需求、运行时数据问题、更好的包/模块可用性等)。毕竟,语言只是完成事情的工具。你永远不知道还有第三种语言在等着打破风暴。
仅供参考——我喜欢 R,因为我一开始就喜欢它:)

4.先学传统的机器学习,再开始深度学习

我这样建议是因为两个主要原因。第一,你应该喜欢探索未知的数据。结构化数据将是开始的最佳方式,该过程涉及双变量分析、测试一些假设、缺失值处理、异常值识别等。第二——您将经历变量选择、特性工程、参数调整以及最后检查模型变量的业务含义的迭代过程。另一方面,在深度学习中,网络架构负责大多数特征工程部分,超参数调整成为该过程中必不可少的一部分。此外,向业务涉众解释模型是项目不可或缺的一部分,因此,ML 模型在变量重要性方面的直观性(如逻辑回归、决策树)使其成为许多行业中最受欢迎的选择(对于结构化数据)。

5.并不是每个问题都以建立模型告终

是的,重读一遍。

数据科学的艺术不在于构建最佳模型,而在于将数据作为资产来解决问题

还有许多其他传统的方法和技术在行业中广泛使用。

仪表板和报告 —这些是许多业务不可或缺的一部分,涉及使用 SQL 创建自动化数据管道、与利益相关者进行头脑风暴以了解 KPI、用强烈的视觉美感叙述故事

实验设计 —了解特定服务/活动/促销的效果总是至关重要的,衡量它们的影响对于做出关键决策也变得至关重要。测试控制分析,A/B 测试通常用于量化这种影响

对数据进行分段,直到您能够 —通过适当设计的 EDA 和分段,可以快速解决某些问题

对于初学者,我会建议你选择感兴趣的领域,找到相关的数据集(电影、体育等)。创建 Tableau/RShiny 公共仪表板时要记住两件事。信息流动得有多好,图表描述这些信息有多容易。此外,阅读案例研究,重点是设计和制定解决某些问题的方法。

6.不要被可用的资源淹没

是的,在某个时间点,你会迷失在数据科学的数字学习世界中。这并不意味着你必须完成所有的课程才能成为专家。为了摆脱这种偏见并获得持续的学习体验,你应该根据你的学习风格和动机来创建你的学习路径和设定原则。

  1. 第一,知道自己想采取什么样的方式;自上而下或自下而上。我属于前一种类型的人,希望在应用理论知识之前了解足够多的理论知识,但这完全取决于个人
  2. 根据目标和上述选择的方法准备学习路线
  3. 一次做一件事,完成它。让它成为 Coursera 上的一门课程,Kaggle 上的一个项目,或者创建你的 tableau 仪表盘
  4. 为每一次学习做笔记
  5. 坚持每天读一篇博客的目标。记下两件你可以带回家的东西
  6. 最后,一致性是关键

非常感谢你一直读到最后。如果你喜欢,请点击拍手,如果你有什么要说的,请在下面发表评论。它会帮我完善我的帖子:)

这个帖子是基于我到目前为止的职业经验。如果你有任何反馈或主要的补充,你想指出给初学者,请随时发表意见。

在 LinkedIn 上联系我:www.linkedin.com/in/muralimohanakrishnadandu

二进制分类中类别不平衡的实用技巧

原文:https://towardsdatascience.com/practical-tips-for-class-imbalance-in-binary-classification-6ee29bcdb8a7?source=collection_archive---------1-----------------------

0.简介和动机

二元分类问题可以说是机器学习中最简单和最直接的问题之一。通常我们想学习一个模型,试图预测某个实例是否属于某个类。它有许多实际应用,从垃圾邮件检测到医学测试(确定患者是否患有某种疾病)。

稍微正式一点,二进制分类的目标是学习一个函数f(x),该函数将 x (一个实例/例子的特征向量)映射到预测的二进制结果 ŷ (0 或 1)。大多数分类算法,例如逻辑回归、朴素贝叶斯和决策树,输出属于正类的实例的概率:Pr(y= 1 |x)。

类别不平衡是指在一个分类问题中,类别没有被平等地表示,这在实践中是很常见的。例如,欺诈检测、罕见药物不良反应预测和基因家族预测(如激酶、GPCR)。未能解决类别不平衡通常会导致许多分类算法的预测性能不准确和下降。在这篇文章中,我将介绍一些关于如何在二进制分类中克服类不平衡的实用技巧,其中大部分可以很容易地适应多类场景。

1.分层很重要!

首先,您需要对数据进行分层,以便进行训练和验证。分层是一种基于样本类别平均分配样本的技术,以便训练集和验证集具有相似的类别比例。

确保您的训练集和验证集共享来自每个类的大约相同比例的示例是非常重要的,这样您就可以在两个集中获得一致的预测性能分数。一些分类算法对它们被训练的数据的类别比率也极其敏感。例如,朴素贝叶斯分类器使用它从训练数据中的类比率中学习的类先验来进行预测。训练集和验证集之间类比率的较大差异导致类先验估计不准确,降低了朴素贝叶斯分类器的预测性能。类似地,k-最近邻也受到这个问题的困扰,因为它只是记住了用于训练的所有数据点,这几乎肯定会在推理阶段从训练数据中搜索 k-最近邻时引入源于类别不平衡的偏差。

scikit-learn 有一个分层的实现[StratifiedKFold](http://scikit-learn.org/stable/modules/generated/sklearn.model_selection.StratifiedKFold.html)将其放入代码中:

然后,我们可以比较分层和随机交叉验证(CV)的得分,这通常会对对类别不平衡敏感的分类器产生影响:

2.二元分类的性能度量

有许多度量来评估二元分类器在预测实例/例子的分类标签方面做得有多好。下面是一些关于选择和解释适当指标的警告和建议。

  • 准确性可能会误导人。因为准确性是简单的正确预测的实例与用于评估的所有实例的比率,所以有可能获得相当好的准确性,同时对于少数类具有大多数不正确的预测。

ACC: Accuracy, TP: True Positive, TN: True Negative

  • 混淆矩阵有助于分解不同类别的预测性能。

  • 基于二分的度量(精确度、召回率、F1 分数等。)默认情况下,计算两个类的平均分数。也许对许多人来说并不明显,人们实际上可以得到每门课的分数细目。在这种情况下,[classification_report](http://scikit-learn.org/stable/modules/generated/sklearn.metrics.classification_report.html)函数非常有用:

  • 对于不平衡数据,推荐使用精确召回曲线而非 ROC 曲线。如下图所示,ROC 曲线可能高估了不平衡数据上分类器的性能,而 PR 曲线揭示了不平衡数据在相同召回水平下的精度下降。本文详细讨论了如何选择合适的分类标准。

Fig. 4. Graphical representation of classifier performance avoids setting an exact threshold on results but may be insensitive to important aspects of the data. (from Lever et al. (2016) Nat Methods)

3.重新采样以获得更平衡的数据

既然我们已经知道了如何设置评估方案,以及为不平衡数据的分类问题选择什么度量标准,我们就可以继续应用一些技术来解决类别不平衡问题。最直接的方法是通过重采样来平衡数据:

  • 向下采样(欠采样)多数类
  • 向上采样(过采样)少数类
  • 许多更高级的采样技术,如合成少数过采样技术(SMOTE) ( Chawla 等人, 2012 ),在不平衡学习库中实现

重采样技术可以与诸如随机森林的 Bagging 集合模型相结合。Bagging 代表 bootstrap-aggregation,它们通过在构建单个估计器(通常是决策树)时引导数据来工作,然后聚合单个估计器的预测。由于自举(带替换的随机采样)本质上是一种重采样技术,我们可以用其他重采样技术(如下采样或上采样)来替换自举,以平衡数据。

下面是一些实现随机森林的核心 Python 代码,带有上/下采样。实现重采样森林的完整代码可以在这里找到。

接下来,我们可以比较随机森林在不同重采样技术下的性能。该图表明上采样和下采样都提高了随机森林对不平衡数据的预测性能。

Performance of Random Forest coupled with different resampling techniques on imbalanced dataset.

4.类别加权/成本敏感学习

在不重新采样数据的情况下,还可以通过将类的权重合并到成本函数(也称为目标函数)中来使分类器意识到不平衡的数据。直觉上,我们想给少数类更高的权重,给多数类更低的权重。scikit-learn 有一个方便的实用函数,可以根据课程频率计算权重:

**from** sklearn.utils.class_weight **import** compute_class_weight
class_weights = compute_class_weight('balanced', np.unique(y), y)

交叉熵是许多二元分类算法(如逻辑回归)的成本函数的常见选择。交叉熵被定义为:

交叉熵=ylog(p)—(1—y)log(1—p)

其中 y 是类别二进制指示符(0 或 1 ), p 是例如属于类别 1 的预测概率。为了将两个类别(0 和 1)的权重合并到交叉熵中,可以定义一个加权交叉熵:

,其中 w_0 和 w_1 分别是类 1 和类 0 的权重。可以使用[tf.nn.weighted_cross_entropy_with_logits](https://www.tensorflow.org/api_docs/python/tf/nn/weighted_cross_entropy_with_logits)在 Tensorflow 中实现类权重。在 Keras 中,class_weight可以在训练时作为参数传递给模型的fit方法。将来我会在 Tensorflow 和 Keras 中实现代价敏感分类器的例子。

也可以通过在许多 scikit-learn 分类器(如支持向量机(SVM)和随机森林)中设置class_weight参数来实现敏感学习。

Classification boundaries for cost-sensitive and cost-insensitive linear SVM

  • 在随机森林中:
  1. class_weight='balanced':使用 y 值自动调整输入数据中与类别频率成反比的权重
  2. class_weight='balanced_subsample':与“平衡”相同,只是权重是根据每棵生长的树的 bootstrap 样本计算的。

5.梯度推进

一些分类模型内置了对抗类别不平衡的方法。例如,梯度推进机器(GBM)通过基于错误分类的例子构建连续的训练集来处理类别不平衡。在不平衡数据集上,它通常优于随机森林:

Comparing GBM with Random Forests (RF) with different balancing techniques on imbalanced dataset. 20 trees are grown for every ensemble model.

我希望这些提示有助于改进不平衡数据集的分类模型。我的 GitHub 上有本教程的 Jupyter 笔记本版本:

[## Wang 10/class _ 失衡

二进制分类中类别不平衡的 Jupyter 笔记本演示

github.com](https://github.com/wangz10/class_imbalance)

感谢阅读!

练习 AI 的团队不知道偏见

原文:https://towardsdatascience.com/practicing-ai-teams-dont-know-about-bias-b6e8d8e27c54?source=collection_archive---------13-----------------------

人工智能设计 2018 报告,第 1 部分

我们总是试图向学术界和工业界的其他人学习。单独研究成 AI,机器学习,深度学习等。自 1996 年以来增加了 9 倍。我们想知道当将这些技术应用于人们的问题时,行业中的其他人在做什么,并导致我们创建了“人工智能设计”调查。

起初,我们真的专注于设计方面,并想知道其他团队是如何做的。超过 18 个问题(平均每个回答约 7 分钟)我们深入到人们如何在构建人工智能的团队中工作。我们会发现对 UX 设计的关注较少,而对团队沟通的关注较多。

你可以在这里看到整个报告:

[## 2018 人工智能设计报告

今天,团队被推至包括人工智能(AI)、机器学习(ML)、深度学习(DL)和…

哲学是](https://philosophie.is/design-for-ai-report-2018)

虽然在报告中有很多有趣的信息,但我想进一步探讨一些要点,并提供一些我们必须解决它们的建议。特别是,我想谈谈结盟,沟通,以及在构建人工智能项目时,团队应该更多地关注什么。

最具影响力

调查的影响部分旨在了解人们在构建人工智能系统时在哪里花费脑力。“数据可用性”和“数据清洁度”在影响中排名靠前是有道理的。关于全套因素请查看报告

没有影响力

最低的影响因素是“伦理”和“法律”业内一直在讨论道德问题,以及当出现不良人类后果时,工程师应该如何更好地考虑这一问题。然而,我不确定这是思考这个问题的正确方式。伦理显然是人类的问题,而不是机器的问题。为什么我们认为工程师不会像他们团队中的其他人一样关注道德?法律是一个很好的例子,说明公司已经有了相关的专家:律师。

最具争议

我们想知道什么是有争议的,所以我们计算了在没有/低影响和一些/高影响之间总体上最接近零的那些。

最让我着迷的是“假阳性/假阴性”和“最坏结果”当处理这些系统的非确定性方面时,我们并不总是知道它将如何失败。由于这一事实,我本以为审议会更加一致。我们发现像混淆映射这样的练习可以帮助每个人在这些问题上达成共识。

最不为人知

最后,一个最少被考虑的因素(大多数“不知道”的回答)今天得到了很多媒体的关注:“偏见。”与伦理不同,偏见是机器知道的东西。他们可以分析识别人类偏见的模式。

我们使用的数据集将严重影响我们系统中的偏差量。机器学习可能是一种可以帮助我们检测和纠正它的机制(正如在深度领域混淆:最大化领域不变性中所讨论的)。

最大的问题是,团队甚至不知道偏见是否应该影响他们的人工智能项目。他们甚至没有进行对话。

接下来是什么:更多的对话

需要就所有这些因素进行更多的对话,尤其是那些没有被提及的因素。

在接下来的两篇文章中,我们将讨论如何在技术和非技术团队成员之间进行讨论,以及如何实现这一点的一些案例研究。

我们如何让包括顾客在内的每个人都有一席之地?

关于克里斯·巴特勒

我帮助团队理解他们应该用以人工智能为中心的解决方案解决的真正的商业问题。我们工作的团队通常被要求用他们拥有的数据“做一些有趣的事情”。我们通过偶发事件相关性帮助他们避免局部极值,并专注于解决巨大的业务问题。我的背景包括在微软、KAYAK 和 Waze 等公司超过 18 年的产品和业务开发经验。在 Philosophie,我创造了像机器移情映射混淆映射这样的技术,以在构建人工智能产品时创建跨团队对齐。如果你想了解更多或通过电子邮件联系,LinkedIn 或访问 http://philosophie.is/human-centered-ai。

自然语言机器学习中的预处理

原文:https://towardsdatascience.com/pre-processing-in-natural-language-machine-learning-898a84b8bd47?source=collection_archive---------1-----------------------

我们很容易忘记我们每天的对话中存储了多少数据。随着数字景观的演变,挖掘文本或自然语言处理(NLP)是人工智能和机器学习中一个不断增长的领域。本文涵盖了应用于 NLP 问题的常见预处理概念。

文本可以有多种形式,从单个单词的列表,到句子,再到包含特殊字符的多个段落(比如 tweets)。像任何数据科学问题一样,理解被问的问题将告知可以采用什么步骤来将单词转换为与机器学习算法一起工作的数字特征。

不良贷款的历史

当我还是个孩子的时候,科幻小说几乎总是有一台电脑,你可以吠叫命令,让他们理解,有时,但不总是,执行。当时,这项技术似乎还很遥远,但今天我口袋里装着一部手机,它比任何人想象的都要小,而且功能更强大。语音转文本的历史复杂而漫长,但却是 NPL 的萌芽。

早期的努力需要大量手工编码的词汇和语言规则。1954 年在乔治敦大学首次实现的从英语到俄语的自动翻译仅限于少数几个句子。

1964 年,第一个聊天机器人伊莱扎在麻省理工学院诞生。它建立在模式匹配和替代的基础上,通过提出开放式问题来模拟治疗过程。虽然它似乎复制了意识,但它没有真正的对话背景。尽管能力有限,许多人还是对这种人性化的互动感到惊讶。

该领域的大部分发展实际上始于 20 世纪 80 年代,当时引入了机器学习算法。研究人员从更严格的转换语法模型转向了在缓存语言模型中描述的更宽松的概率关系,这允许更快速的缩放,并更轻松地处理不熟悉的输入。

整个 90 年代,计算能力的指数级增长推动了科技的进步,但直到 2006 年 IBM 的沃森(Watson)上了《危险边缘》(Jeopardy)节目,公众才看到计算机智能的进步。对我来说,是 2011 年 iPhone 引入 Siri 让我意识到了它的潜力。

当前的 NLP 前景很容易成为它自己的文章。私营公司前所未有的投资和普遍的开源态度已经扩展了一些很大程度上为更多的受众和应用所专有的东西。一个有趣的例子是在翻译领域,谷歌正在努力翻译任何语言(即使用户体验中的一些错误需要解决)。

[## 谷歌的即时翻译 Pixel Buds 是其迄今为止最令人难以置信的版本

谷歌昨天宣布了许多激动人心的发布,但也许最激动人心的当然是…

betanews.com](https://betanews.com/2017/10/05/google-pixel-buds/)

预处理的重要性

如果没有大量的后端工作,上面描述的魔术就不会发生。将文本转换成某种算法可以消化的东西是一个复杂的过程。有四个不同的部分:

  • 清理包括通过去除停用词来去除文本中不太有用的部分,处理大写和字符以及其他细节。
  • 注释包括对文本应用一个方案。注释可能包括结构标记和词性标注。
  • 标准化包括通过词干化、词汇化和其他形式的标准化来翻译(映射)方案中的术语或语言简化。
  • 分析包括对数据集进行统计探测、操作和归纳,以进行特征分析。

工具

有多种预处理方法。下面的列表并不全面,但它确实给出了从哪里开始的想法。重要的是要认识到,就像所有的数据问题一样,将任何东西转换成机器学习的格式都会将其简化为一种一般化的状态,这意味着在此过程中会损失一些数据的保真度。真正的艺术是了解每一种方法的利弊,从而谨慎地选择正确的方法。

资本化

文本常常有各种反映句子开头、专有名词强调的大写形式。为了简单起见,最常见的方法是将所有内容都简化为小写,但重要的是要记住,一些单词,如“us”到“US”,在简化为小写时可能会改变含义。

无用词

给定文本中的大多数单词是句子的连接部分,而不是显示主语、宾语或意图。像“the”或“and”这样的词可以通过将文本与停用词列表进行比较来删除。

IN:
['He', 'did', 'not', 'try', 'to', 'navigate', 'after', 'the', 'first', 'bold', 'flight', ',', 'for', 'the', 'reaction', 'had', 'taken', 'something', 'out', 'of', 'his', 'soul', '.']OUT:
['try', 'navigate', 'first', 'bold', 'flight', ',', 'reaction', 'taken', 'something', 'soul', '.']

在上面的例子中,它将 23 个单词减少到了 11 个,但是需要注意的是,单词“not”被删除了,这取决于我在做什么,这可能是一个大问题。根据所需的敏感度,用户可以手动创建自己的停用词词典或利用预建的库。

标记化

标记化描述了将段落分割成句子,或者将句子分割成单个单词。对于前一个句子,可以应用边界歧义消除 (SBD)来创建单个句子的列表。这依赖于预先训练的语言特定算法,如 NLTK 的 Punkt 模型。

通过类似的过程,可以将句子拆分成单个单词和标点符号。最常见的是这种跨越空格的拆分,例如:

IN:"He did not try to navigate after the first bold flight, for the reaction had taken something out of his soul."OUT:['He', 'did', 'not', 'try', 'to', 'navigate', 'after', 'the', 'first', 'bold', 'flight', ',', 'for', 'the', 'reaction', 'had', 'taken', 'something', 'out', 'of', 'his', 'soul', '.']

当一个单词被缩写、删节或被所有格时,这有时会引起问题。专有名词在使用标点符号的情况下也会受到影响(比如奥尼尔)。

词性标注

理解词类对确定句子的意思有很大的影响。词性(POS)通常需要查看前面和后面的单词,并结合基于规则或随机的方法。然后,它可以与其他过程相结合,以实现更多的功能工程。

IN:
['And', 'from', 'their', 'high', 'summits', ',', 'one', 'by', 'one', ',', 'drop', 'everlasting', 'dews', '.']OUT:
[('And', 'CC'),
 ('from', 'IN'),
 ('their', 'PRP$'),
 ('high', 'JJ'),
 ('summits', 'NNS'),
 (',', ','),
 ('one', 'CD'),
 ('by', 'IN'),
 ('one', 'CD'),
 (',', ','),
 ('drop', 'NN'),
 ('everlasting', 'VBG'),
 ('dews', 'NNS'),
 ('.', '.')]Definitions of Parts of Speech
('their', 'PRP$') PRP$: pronoun, possessive
    her his mine my our ours their thy your

堵塞物

很多自然语言机器学习都是关于文本的情感。词干化是通过去掉不必要的字符(通常是后缀)来去除词尾变化,从而将单词简化为词根的过程。有几个词干模型,包括波特和雪球。结果可用于识别大型数据集之间的关系和共性。

IN:
["It never once occurred to me that the fumbling might be a mere mistake."]OUT:
 ['it', 'never',  'onc',  'occur',  'to',  'me',  'that',  'the', 'fumbl',  'might', 'be', 'a', 'mere',  'mistake.'],

显而易见,缩减可能会产生一个不是真正单词的“根”单词。这不一定会对其效率产生负面影响,但如果像“universe”和“university”这样的词被简化为“univers”的同一个词根,就有“越界”的危险。

词汇化

词干变化是从词干变化到消除词形变化的另一种方法。通过确定词性和利用 WordNet 的英语词汇库,词汇化可以得到更好的结果。

The stemmed form of leafs is: leaf
The stemmed form of leaves is: leavThe lemmatized form of leafs is: leaf
The lemmatized form of leaves is: leaf

Lemmazation 是一个更密集,因此更慢的过程,但更准确。词干在数据库查询中可能更有用,而词汇化在试图确定文本情感时可能工作得更好。

计数/密度

也许特征工程的更基本的工具之一,增加字数、句子数、标点数和行业特定的字数可以极大地帮助预测或分类。有多种统计方法,其相关性严重依赖于上下文。

单词嵌入/文本向量

单词嵌入是将单词表示为向量的现代方法。单词嵌入的目的是将高维单词特征重新定义为低维特征向量。换句话说,它表示 X 和 Y 向量坐标上的单词,其中基于关系语料库的相关单词被更紧密地放置在一起。 Word2VecGloVe 是最常见的将文本转换为矢量的模型。

结论

虽然这远不是一个全面的列表,但准备文本是一门复杂的艺术,需要在给定数据和问题的情况下选择最佳的工具。许多预建的库和服务可以提供帮助,但有些可能需要手动映射术语和单词。

一旦数据集准备就绪,就可以应用有监督和无监督的机器学习技术。从我最初的实验(这将是我自己的文章)来看,对单个字符串应用预处理技术与对大型数据帧应用预处理技术有很大的不同。调整步骤以获得最佳效率将是面对扩展保持灵活性的关键。

如果你喜欢这篇文章,请鼓掌,如果你有兴趣看更多关于自然语言处理的文章,请关注!

额外资源

[## 自然语言处理-维基百科

自然语言处理是计算机科学、人工智能和计算科学的一个领域

en.wikipedia.org](https://en.wikipedia.org/wiki/Natural_language_processing) [## 理解和实现自然语言处理的终极指南(带 Python 代码)

根据行业估计,只有 21%的可用数据以结构化形式存在。正在生成数据…

www.analyticsvidhya.com](https://www.analyticsvidhya.com/blog/2017/01/ultimate-guide-to-understand-implement-natural-language-processing-codes-in-python/) [## 深入 NLTK,第一部分:NLTK 入门

第一部分:NLTK 入门(本文)第二部分:句子标记化和单词标记化第三部分:词性…

textminingonline.com](http://textminingonline.com/dive-into-nltk-part-i-getting-started-with-nltk) [## 当帕里遇到伊莱扎时:1972 年的一段可笑的聊天机器人对话

他们可能没有通过图灵测试,但他们赢得了这场古怪之战。

www.theatlantic.com](https://www.theatlantic.com/technology/archive/2014/06/when-parry-met-eliza-a-ridiculous-chatbot-conversation-from-1972/372428/)

使用 InsightR R 包进行沉淀

原文:https://towardsdatascience.com/precipitation-with-the-insightr-r-package-bdda409321ba?source=collection_archive---------2-----------------------

使用 Insight API 的好处之一是数据的质量和分辨率。大多数气象 API 依赖于一个点观测系统。这意味着当你询问你所在地的天气时,你实际上可能得到的是 20 英里外某个地方的天气。这对于很多用例来说是好的,但是对于其他用例来说就很糟糕了。降水是这种方法失败的一个常见用例:相隔几英里的两个站点收到的总降雨量相差很大的情况并不少见。

Insight API 建立在我们的 SkyWise 数据之上,而不是仅仅依赖于观察站点。这些数据是通过运行一个集成了观测站、卫星和雷达的 1 公里模型产生的。你可以在下图中看到它的好处。如果你依靠一个点观测系统,你可能在你的位置有大雨,而观测站什么也没有收到,反之亦然。

我一直在听新闻报道说俄克拉荷马州中部需要降雨,所以我决定借此机会做一个小项目。

我决定在 R 做这个项目作为学习练习。我的第一步是实际学习一些 r。我从 Rkoans 项目开始,并修复了所有的测试。在编写了一些示例代码之后,我认为一个包是合适的。我发现希拉里·帕克的这个关于创建 R 包的很好的参考。接下来我开始阅读 Hadley Wickham 的一些优秀教程,尤其是编写 API 包装器的最佳实践。完成后,让我们看看如何用它来测量降水量。

首先,我们需要安装软件包:

devtools::install_github('wdtinc/InsightR')

加载后,您需要存储您的认证凭证(免费演示注册):

Authenticate('your_app_id', 'your_app_key')

然后,只需调用包装函数:

dp <- DailyPrecipitation(35.235762, -97.428966, "2017-05-01", "2017-06-13")

假设一切顺利,我们就可以得到总降雨量并绘制数据:

> dp$response$status_code == 200
[1] TRUE
> x <- as.Date(dp$content$series[[1]], "%Y-%m-%d")
> y <- dp$content$series[[3]]
> sum(y)
[1] 39.44
> plot(x,y, xlab="date", ylab="precip in mm")

让我们与几英里外的一个地点进行比较:

> dp <- DailyPrecipitation(35.183235, -97.437611, "2017-05-01", "2017-06-13")
> x <- as.Date(dp$content$series[[1]], "%Y-%m-%d")
> y <- dp$content$series[[3]]
> sum(y)
[1] 77.19

77.19mm vs 39.44mm 就差几里!

在一开始对 R 的语法有点反感之后,我发现自己真的很喜欢写 R 代码。尤其是 RStudio。包装器有点不完整:它缺少文档和测试,并且它目前不支持 Insight API 的“资产”特性,该特性允许您检索字段级轮廓。也就是说,基本级别的功能已经存在,希望有些人会发现它很有用。

用 R 预测客户流失

原文:https://towardsdatascience.com/predict-customer-churn-with-r-9e62357d47b4?source=collection_archive---------0-----------------------

Photo credit: Pixabay

对于任何一家定期计费的服务公司来说,一个关键的变量就是流失率。《哈佛商业评论》2016 年 3 月

对于这个“即服务”的世界中几乎所有的成长型公司来说,两个最重要的指标是客户流失率和终身价值。创业者,2016 年 2 月

介绍

当客户或订户停止与公司或服务做生意时,就会发生客户流失,也称为客户流失。它也被称为失去客户或顾客。流失率特别有用的一个行业是电信业,因为大多数客户在一个地理位置内有多种选择。

类似于预测员工流动的概念,我们将使用电信数据集预测客户流失。我们将介绍逻辑回归、决策树和随机森林。但这一次,我们将在 r 中完成上述所有工作。让我们开始吧!

数据预处理

数据是从 IBM 样本数据集下载的。每行代表一个客户,每列包含该客户的属性:

library(plyr)
library(corrplot)
library(ggplot2)
library(gridExtra)
library(ggthemes)
library(caret)
library(MASS)
library(randomForest)
library(party)churn <- read.csv('Telco-Customer-Churn.csv')
str(churn)

Figure 1

  • customerID
  • 性别(女性、男性)
  • 老年人(无论客户是否是老年人(1,0))
  • 合作伙伴(无论客户是否有合作伙伴(是,否))
  • 家属(客户是否有家属(是,否))
  • 任期(客户在公司工作的月数)
  • 电话服务(无论客户是否有电话服务(是,否))
  • 多条线路(客户是否有多条线路(是,否,无电话服务)
  • 互联网服务(客户的互联网服务提供商(DSL、光纤、否)
  • 在线安全(客户是否有在线安全(是,否,无互联网服务)
  • 在线备份(无论客户是否有在线备份(是,否,无互联网服务)
  • 设备保护(客户是否有设备保护(是,否,无互联网服务)
  • 技术支持(无论客户是否有技术支持(是,否,无互联网服务)
  • 流媒体电视(客户是否有流媒体电视(是,否,无互联网服务)
  • 流媒体电影(无论客户是否有流媒体电影(是,否,无互联网服务)
  • 合同(客户的合同期限(逐月、一年、两年)
  • 无纸账单(无论客户是否有无纸账单(是,否))
  • 付款方式(客户的付款方式(电子支票、邮寄支票、银行转账(自动)、信用卡(自动)))
  • 月度费用(每月向客户收取的金额—数字)
  • 总费用(向客户收取的总额——数字)
  • 客户流失(客户是否流失(是或否))

原始数据包含 7043 行(客户)和 21 列(特性)。“客户流失”专栏是我们的目标。

我们使用 sapply 来检查每一列中是否有缺失值。我们发现“总费用”列中有 11 个缺失值。因此,让我们删除所有缺少值的行。

sapply(churn, function(x) sum(is.na(x)))

Figure 2

churn <- churn[complete.cases(churn), ]

看变量,可以看到我们有些扯皮要做

  1. 我们将六个栏目的“无互联网服务”改为“无”,它们是:“在线安全”、“在线备份”、“设备保护”、“技术支持”、“流媒体电视”、“流媒体电影”。
cols_recode1 <- c(10:15)
for(i in 1:ncol(churn[,cols_recode1])) {
        churn[,cols_recode1][,i] <- as.factor(mapvalues
                                              (churn[,cols_recode1][,i], from =c("No internet service"),to=c("No")))
}

2.我们将把“多线”栏中的“无电话服务”改为“无”

churn$MultipleLines <- as.factor(mapvalues(churn$MultipleLines, 
                                           from=c("No phone service"),
                                           to=c("No")))

3.由于最短任期为 1 个月,最长任期为 72 个月,我们可以将他们分为五个任期组:“0-12 个月”、“12-24 个月”、“24-48 个月”、“48-60 个月”、“60 个月以上”

min(churn$tenure); max(churn$tenure)

【1】1

【1】72

group_tenure <- function(tenure){
    if (tenure >= 0 & tenure <= 12){
        return('0-12 Month')
    }else if(tenure > 12 & tenure <= 24){
        return('12-24 Month')
    }else if (tenure > 24 & tenure <= 48){
        return('24-48 Month')
    }else if (tenure > 48 & tenure <=60){
        return('48-60 Month')
    }else if (tenure > 60){
        return('> 60 Month')
    }
}churn$tenure_group <- sapply(churn$tenure,group_tenure)
churn$tenure_group <- as.factor(churn$tenure_group)

4.将“老年人”列中的值从 0 或 1 更改为“否”或“是”。

churn$SeniorCitizen <- as.factor(mapvalues(churn$SeniorCitizen,
                                      from=c("0","1"),
                                      to=c("No", "Yes")))

5.删除分析中不需要的列。

churn$customerID <- NULL
churn$tenure <- NULL

探索性数据分析和特征选择

数值变量之间的相关性

numeric.var <- sapply(churn, is.numeric)
corr.matrix <- cor(churn[,numeric.var])
corrplot(corr.matrix, main="\n\nCorrelation Plot for Numerical Variables", method="number")

Figure 3

每月费用和总费用是相互关联的。因此其中一个将从模型中移除。我们取消所有指控。

churn$TotalCharges <- NULL

分类变量柱状图

p1 <- ggplot(churn, aes(x=gender)) + ggtitle("Gender") + xlab("Gender") +
  geom_bar(aes(y = 100*(..count..)/sum(..count..)), width = 0.5) + ylab("Percentage") + coord_flip() + theme_minimal()
p2 <- ggplot(churn, aes(x=SeniorCitizen)) + ggtitle("Senior Citizen") + xlab("Senior Citizen") + 
  geom_bar(aes(y = 100*(..count..)/sum(..count..)), width = 0.5) + ylab("Percentage") + coord_flip() + theme_minimal()
p3 <- ggplot(churn, aes(x=Partner)) + ggtitle("Partner") + xlab("Partner") + 
  geom_bar(aes(y = 100*(..count..)/sum(..count..)), width = 0.5) + ylab("Percentage") + coord_flip() + theme_minimal()
p4 <- ggplot(churn, aes(x=Dependents)) + ggtitle("Dependents") + xlab("Dependents") +
  geom_bar(aes(y = 100*(..count..)/sum(..count..)), width = 0.5) + ylab("Percentage") + coord_flip() + theme_minimal()
grid.arrange(p1, p2, p3, p4, ncol=2)

Figure 4

p5 <- ggplot(churn, aes(x=PhoneService)) + ggtitle("Phone Service") + xlab("Phone Service") +
  geom_bar(aes(y = 100*(..count..)/sum(..count..)), width = 0.5) + ylab("Percentage") + coord_flip() + theme_minimal()
p6 <- ggplot(churn, aes(x=MultipleLines)) + ggtitle("Multiple Lines") + xlab("Multiple Lines") + 
  geom_bar(aes(y = 100*(..count..)/sum(..count..)), width = 0.5) + ylab("Percentage") + coord_flip() + theme_minimal()
p7 <- ggplot(churn, aes(x=InternetService)) + ggtitle("Internet Service") + xlab("Internet Service") + 
  geom_bar(aes(y = 100*(..count..)/sum(..count..)), width = 0.5) + ylab("Percentage") + coord_flip() + theme_minimal()
p8 <- ggplot(churn, aes(x=OnlineSecurity)) + ggtitle("Online Security") + xlab("Online Security") +
  geom_bar(aes(y = 100*(..count..)/sum(..count..)), width = 0.5) + ylab("Percentage") + coord_flip() + theme_minimal()
grid.arrange(p5, p6, p7, p8, ncol=2)

Figure 5

p9 <- ggplot(churn, aes(x=OnlineBackup)) + ggtitle("Online Backup") + xlab("Online Backup") +
  geom_bar(aes(y = 100*(..count..)/sum(..count..)), width = 0.5) + ylab("Percentage") + coord_flip() + theme_minimal()
p10 <- ggplot(churn, aes(x=DeviceProtection)) + ggtitle("Device Protection") + xlab("Device Protection") + 
  geom_bar(aes(y = 100*(..count..)/sum(..count..)), width = 0.5) + ylab("Percentage") + coord_flip() + theme_minimal()
p11 <- ggplot(churn, aes(x=TechSupport)) + ggtitle("Tech Support") + xlab("Tech Support") + 
  geom_bar(aes(y = 100*(..count..)/sum(..count..)), width = 0.5) + ylab("Percentage") + coord_flip() + theme_minimal()
p12 <- ggplot(churn, aes(x=StreamingTV)) + ggtitle("Streaming TV") + xlab("Streaming TV") +
  geom_bar(aes(y = 100*(..count..)/sum(..count..)), width = 0.5) + ylab("Percentage") + coord_flip() + theme_minimal()
grid.arrange(p9, p10, p11, p12, ncol=2)

Figure 6

p13 <- ggplot(churn, aes(x=StreamingMovies)) + ggtitle("Streaming Movies") + xlab("Streaming Movies") +
  geom_bar(aes(y = 100*(..count..)/sum(..count..)), width = 0.5) + ylab("Percentage") + coord_flip() + theme_minimal()
p14 <- ggplot(churn, aes(x=Contract)) + ggtitle("Contract") + xlab("Contract") + 
  geom_bar(aes(y = 100*(..count..)/sum(..count..)), width = 0.5) + ylab("Percentage") + coord_flip() + theme_minimal()
p15 <- ggplot(churn, aes(x=PaperlessBilling)) + ggtitle("Paperless Billing") + xlab("Paperless Billing") + 
  geom_bar(aes(y = 100*(..count..)/sum(..count..)), width = 0.5) + ylab("Percentage") + coord_flip() + theme_minimal()
p16 <- ggplot(churn, aes(x=PaymentMethod)) + ggtitle("Payment Method") + xlab("Payment Method") +
  geom_bar(aes(y = 100*(..count..)/sum(..count..)), width = 0.5) + ylab("Percentage") + coord_flip() + theme_minimal()
p17 <- ggplot(churn, aes(x=tenure_group)) + ggtitle("Tenure Group") + xlab("Tenure Group") +
  geom_bar(aes(y = 100*(..count..)/sum(..count..)), width = 0.5) + ylab("Percentage") + coord_flip() + theme_minimal()
grid.arrange(p13, p14, p15, p16, p17, ncol=2)

Figure 7

所有的分类变量似乎有一个合理的广泛分布,因此,他们都将被保留,以供进一步分析。

逻辑回归

首先,我们将数据分成训练集和测试集:

intrain<- createDataPartition(churn$Churn,p=0.7,list=FALSE)
set.seed(2017)
training<- churn[intrain,]
testing<- churn[-intrain,]

确认分割正确:

dim(training); dim(testing)

【1】492419

【1】2108 19

拟合逻辑回归模型:

LogModel <- glm(Churn ~ .,family=binomial(link="logit"),data=training)
print(summary(LogModel))

Figure 8

特征分析:

前三个最相关的功能包括合同,任期 _ 组和无纸账单。

anova(LogModel, test="Chisq")

Figure 9

分析偏差表,我们可以看到每次增加一个变量时偏差的下降。加入互联网服务、合同和保有权组显著降低了剩余偏离度。其他变量如 PaymentMethod 和 Dependents 对模型的改善似乎较小,尽管它们都具有较低的 p 值。

评估逻辑回归模型的预测能力

testing$Churn <- as.character(testing$Churn)
testing$Churn[testing$Churn=="No"] <- "0"
testing$Churn[testing$Churn=="Yes"] <- "1"
fitted.results <- predict(LogModel,newdata=testing,type='response')
fitted.results <- ifelse(fitted.results > 0.5,1,0)
misClasificError <- mean(fitted.results != testing$Churn)
print(paste('Logistic Regression Accuracy',1-misClasificError))

【1】Logistic 回归精度 0.789373814041746

逻辑回归混淆矩阵

print("Confusion Matrix for Logistic Regression"); table(testing$Churn, fitted.results > 0.5)

Figure 10

赔率比

逻辑回归中一个有趣的性能测量是优势比。基本上,比值比是一个事件发生的概率。

library(MASS)
exp(cbind(OR=coef(LogModel), confint(LogModel)))

Figure 11

决策树

决策树可视化

为了便于说明,我们将只使用三个变量来绘制决策树,它们是“合同”、“任期 _ 组”和“无纸账单”。

tree <- ctree(Churn~Contract+tenure_group+PaperlessBilling, training)
plot(tree)

Figure 12

  1. 在我们使用的三个变量中,合同是预测客户流失与否的最重要变量。
  2. 如果客户是一年期或两年期合同,无论他(她)是否有纸质账单,他(她)都不太可能流失。
  3. 另一方面,如果客户签订的是逐月合同,租期为 0-12 个月,并且使用无纸化账单,那么该客户更有可能流失。

决策树混淆矩阵

我们使用所有变量来制作混淆矩阵表并做出预测。

pred_tree <- predict(tree, testing)
print("Confusion Matrix for Decision Tree"); table(Predicted = pred_tree, Actual = testing$Churn)

Figure 13

决策树精度

p1 <- predict(tree, training)
tab1 <- table(Predicted = p1, Actual = training$Churn)
tab2 <- table(Predicted = pred_tree, Actual = testing$Churn)
print(paste('Decision Tree Accuracy',sum(diag(tab2))/sum(tab2)))

【1】决策树准确率 0.780834914611006

决策树的准确性几乎没有提高。让我们看看使用随机森林是否能做得更好。

随机森林

随机森林初始模型

rfModel <- randomForest(Churn ~., data = training)
print(rfModel)

Figure 14

预测“否”时错误率相对较低,预测“是”时错误率高得多。

随机森林预测和混淆矩阵

pred_rf <- predict(rfModel, testing)
caret::confusionMatrix(pred_rf, testing$Churn)

Figure 15

随机森林错误率

plot(rfModel)

Figure 16

我们用这个图来帮助我们确定树的数量。随着树的数量增加,OOB 错误率降低,然后变得几乎恒定。我们不能在大约 100 到 200 棵树后降低 OOB 错误率。

调整随机森林模型

t <- tuneRF(training[, -18], training[, 18], stepFactor = 0.5, plot = TRUE, ntreeTry = 200, trace = TRUE, improve = 0.05)

Figure 17

我们用这个图来给我们一些选择项目数量的想法。当 mtry 为 2 时,OOB 误码率最低。因此,我们选择 mtry=2。

调整后拟合随机森林模型

rfModel_new <- randomForest(Churn ~., data = training, ntree = 200, mtry = 2, importance = TRUE, proximity = TRUE)
print(rfModel_new)

Figure 18

OOB 误差率从图 14 的 20.61%下降到 20.41%。

随机森林预测和调优后的混乱矩阵

pred_rf_new <- predict(rfModel_new, testing)
caret::confusionMatrix(pred_rf_new, testing$Churn)

Figure 19

与图 15 相比,精确度和灵敏度都得到了提高。

随机森林特征重要性

varImpPlot(rfModel_new, sort=T, n.var = 10, main = 'Top 10 Feature Importance')

Figure 20

摘要

从上面的例子,我们可以看到,逻辑回归,决策树和随机森林可以用于客户流失分析这一特定的数据集一样好。

在整个分析过程中,我学到了几件重要的事情:

  • 诸如使用权组、合同、无纸账单、月费和互联网服务等功能似乎在客户流失中发挥了作用。
  • 性别和客户流失之间似乎没有关系。
  • 月结合同、无单据账单且任期在 12 个月以内的客户更有可能流失;另一方面,拥有一年或两年合同、超过 12 个月任期、不使用无纸化计费的客户不太可能流失。

创建这篇文章的源代码可以在这里找到。我将很高兴收到关于上述任何反馈或问题。

使用深度学习预测黑色星期五的客户购买量

原文:https://towardsdatascience.com/predict-customer-purchases-on-black-friday-using-deep-learning-8f9547c1d18d?source=collection_archive---------5-----------------------

也许机器学习在零售业中最明显的应用之一是预测顾客在商店可能会花多少钱。这种预测器对店主具有明显的商业价值,因为它将有助于他们的财务规划、库存管理、营销和广告。

Analytics Vidhya 提供了一个关于黑色星期五顾客购买模式的很好的数据集。我是通过阅读由 Phani Srikanth 撰写的帖子来了解数据集的。Phani 很好地解释了他如何使用随机森林和 XGBoost 构建预测器。我决定将深度学习模型应用于该问题,并看看它们的表现如何。

问题陈述

这个数据集的优点是它简单明了的特性。图 1 显示了训练数据集的快照。

Figure 1: A snapshot of the Black Friday dataset.

目标是在给定所有其他特征的情况下预测购买字段。大多数特性都是不言自明的。最后三个描述了产品的可能分类。我用 0 替换了这三个字段中缺少的值。完整的描述。

数据探索

我在本笔记本中描述了对数据集的详细探索性分析。这些信息包括:

  • 这个数据集中有 50 多万行
  • 几乎所有的列都代表分类特征
  • 产品类别 2 和 3 有许多缺失值,现在表示为类别 0
  • 用数字而不是用类别来表示停留在当前城市的年数可能会有用。
  • 特征交叉有很大的实验空间。例如年龄×婚姻状况或性别×职业
  • 分别有 5891 和 3623 个不同的用户和产品 id。所以这两个特性都可以从嵌入中受益。

黑色星期五预测者

深度神经网络在正确选择超参数和网络架构以及一些特征工程的情况下表现良好。使用深度学习的数据科学家知道,需要大量的实验才能找出最佳配方。

虽然模型设计因问题而异,但建模、训练、评估和部署深度神经网络的整个过程都非常标准。因此,已经开发了一些框架来自动化这一过程并隐藏其复杂性。对于这个问题,我将使用谷歌的框架 Tensorflow,这是建立可扩展和高效的深度学习模型的最佳工具之一。

使用 Tensorflow,我构建了黑色星期五预测器应用,允许其用户针对这一特定问题快速构建和测试深度神经网络模型。使用该应用程序,您可以指定架构、超参数,甚至使用单个命令来试验特征交叉。然后,您可以使用 tensor board(tensor flow 的另一个强大功能)来比较您的模型,并找出最佳候选对象。要安装和使用该应用程序,请遵循这些说明

特征工程和建筑

安装应用程序后,创建一个新的目录来存储模型

mkdir my-project
cd my-project

现在你可以开始实验了!

首先,我们将开始训练一个简单的模型,作为我们其余实验的基线。应用程序自带的默认值应该足够了。使用默认值训练模型相当于运行以下命令

train --model-name baseline \--estimator-type DNN_REG \--indicators "Age" "Gender" "Occupation" "City_Category" "Stay_In_Current_City_Years" "Marital_Status" "Product_Category_1" \--embeddings '{"Product_ID":4, "User_ID":4}' \--hidden-units 100 200 100 \--training-steps 10000

请注意,此模型省略了 Product_Category_2 和 Product_Category_3 列,没有通过功能交叉构建任何新功能,并且具有相对较少的隐藏单元和仅 3 个隐藏层。尽管如此,它应该提供一个良好的基线,并快速训练。

训练完成后,你应该会发现两个新目录:my-project中的savedmodelstensorboard目录

要了解您的第一个模型的表现,让我们使用 tensorboard

tensorboard --logdir tensorboard

Figure 2: Average loss of the baseline model (tensorboard visualization)

对于基线来说还不错!如果你检查 tensorboard 上的均方根误差(RMSE)部分,你应该看到一个 2780 的 RMSE。RMSE 是我们用来比较模型的指标。RMSE 越低,模型越好。

我们有许多方法可以进一步调整模型,使其做得更好。我们可以研究如何表示我们的特征(特征工程),修改模型的架构,或者改进训练。在这篇博文中,我们将重点讨论前两类。

让我们从试验我们的特性开始。该应用程序旨在使这一过程变得非常简单。这样,我们就专注于实验背后的逻辑,而不是代码。

我们可以做的第一个改进是增加 User_ID 和 Product_ID 列的嵌入维度。每个的默认值是 4 维。让我们试着把这个数字提高到 100(我自己做了几次实验后得出了这个值)。

train --model-name emb_100 \--estimator-type DNN_REG \--indicators "Age" "Gender" "Occupation" "City_Category" "Stay_In_Current_City_Years" "Marital_Status" "Product_Category_1" \--embeddings '{"Product_ID":100, "User_ID":100}' \--hidden-units 100 200 100 \--training-steps 10000

注意,我给了这个模型一个描述性的名字。这在 tensorboard 中比较不同模型时非常有用。运行此命令,将训练一个新模型,将其存储在“savedmodels”目录中,并将事件文件写入tensorboard

Figure 3: RMSE of the embed_100 model vs baseline models (tensorboard visualization)

不错!我们的 RMSE 仅仅通过改变嵌入维数就下降了 40 点。为自己尝试一些价值观,不断尝试。

我们可以通过一起创建新功能来进一步改进我们的模型。这可以通过将特征组合在一起(特征交叉)来实现。有很多方法可以做到这一点,所以检查探索性分析笔记本以获得更多的细节。一个有趣的特征是年龄和婚姻状况。让我们试试看

train --model-name emb_100_ageXms \--estimator-type DNN_REG \--indicators "Age" "Gender" "Occupation" "City_Category" "Stay_In_Current_City_Years" "Marital_Status" "Product_Category_1" \--embeddings '{"Product_ID":100, "User_ID":100}' \--crossings '["Age", "Marital_Status", "ind", 1000]' \--hidden-units 100 200 100 \--training-steps 10000

有关 crossing 参数的更多详细信息,请查看应用程序文档和 tensorflow 功能专栏教程

现在让我们看看我们的新功能如何改进我们的结果

Figure 4: Feature crossing age and marital status improves lowers RMSE (tensorbaord visualization)

好多了!将年龄与婚姻状况交叉确实产生了一个具有新信息的特征。我在探索性分析笔记本中提供的跨越这些特性的推理只是一个例子。我们不能真正说出这些特征之间存在什么潜在的关系,但是我们知道它是有效的。

让我们试试另一个?这一次,我将跨越性别和职业

train --model-name emb_100_ageXms_gendXocc \--estimator-type DNN_REG \--indicators "Age" "Gender" "Occupation" "City_Category" "Stay_In_Current_City_Years" "Marital_Status" "Product_Category_1" \--embeddings '{"Product_ID":100, "User_ID":100}' \--crossings '["Age", "Marital_Status", "ind", 1000]' '["Gender", "Occupation", "ind", 1000]' \--hidden-units 100 200 100 \--training-steps 10000

像往常一样,我们用 tensorboard 找出新模型与其他模型的比较

Figure 5: Feature crossing gender and occupation barely adds any value to our model(tensorbaord visualization)

啊!不是一个令人印象深刻的结果。好了,不要气馁,继续尝试自己的特色穿越组合。思考推理和潜在的关系。当你想出一个有趣的组合时,一定要让我知道!

现在,我们转到改进模型的第二种方法:修改架构。到目前为止,我们使用了默认的简单架构,它由一个 3 层网络组成,每个网络上有 100、200、100 个单元。让我们通过增加一层来加深我们的网络,并将每层的单元数量增加两倍。

train --model-name deeper_model \--estimator-type DNN_REG \--indicators "Age" "Gender" "Occupation" "City_Category" "Stay_In_Current_City_Years" "Marital_Status" "Product_Category_1" \--embeddings '{"Product_ID":100, "User_ID":100}' \--crossings '["Age", "Marital_Status", "ind", 1000]' '["Gender", "Occupation", "ind", 1000]' \--hidden-units 200 400 400 100 \--training-steps 10000

请注意,我们可以通过修改一行代码来做到这一点(嗯,还可以修改模型的名称,但这不算数!) .现在运行命令,看看这个模型是如何执行的。

Figure 6: Adding an extra hidden layer and increasing the number of neurons per layer lowers RMSE further (tensorboard visualization)

更好!这仅仅是通过加深网络和增加更多的神经元。其他更复杂的方法可能会进一步提高性能。请注意,训练时间将显著增加,因为我们增加了可训练变量(参数)的数量。

结论

黑色星期五预测器是一个 tensorflow 应用程序,允许您快速方便地为黑色星期五数据集设计和训练深度学习模型。特征工程和模型架构可以提高模型的性能,但是需要大量的实验来找出最佳方案。现在,您已经知道如何使用该应用程序,并且从探索性分析中对数据集有了很好的直觉,请继续亲自尝试,让我们看看您可以将 RMSE 分数降低多少。玩得开心!

用 Python 预测员工流动率

原文:https://towardsdatascience.com/predict-employee-turnover-with-python-da4975588aa3?source=collection_archive---------0-----------------------

“大数据可以让公司识别出预测自己队伍中人员流动的变量。”《哈佛商业评论》2017 年 8 月

“员工流失分析是评估员工流动率的过程,旨在预测未来并减少员工流失。”福布斯 2016 年 3 月

介绍

本文展示了一个员工离职分析项目的参考实现,该项目是使用 Python 的 Scikit-Learn 库构建的。在本文中,我们介绍了逻辑回归,随机森林和支持向量机。我们还测量通过使用机器学习建立的模型的准确性,并评估进一步发展的方向。我们将用 Python 来完成以上所有的工作。我们开始吧!

数据预处理

数据是从 Kaggle 下载的。这很简单。每行代表一名员工,每列包含员工属性:

  • 满意度 _ 级别(0–1)
  • last_evaluation(自上次评估以来的时间,以年为单位)
  • number_projects(工作时完成的项目数)
  • 平均每月小时数(工作场所平均每月小时数)
  • time_spend_company(在公司工作的时间,以年为单位)
  • 工作事故(员工是否发生工作场所事故)
  • 离开(无论员工是否离开工作场所(1 或 0))
  • promotion_last_5years(员工在过去五年中是否得到晋升)
  • 销售(他们工作的部门)
  • 工资(相对工资水平)
import pandas as pd
hr = pd.read_csv('HR.csv')
col_names = hr.columns.tolist()
print("Column names:")
print(col_names)print("\nSample data:")
hr.head()

栏目名称:
['满意度 _ 等级','上次 _ 评估','人数 _ 项目','平均 _ 月 _ 小时','时间 _ 花费 _ 公司','工作 _ 事故','离职','促销 _ 上次 _ 5 年','销售','薪资']

样本数据:

Figure 1

将列名从“销售”重命名为“部门”

hr=hr.rename(columns = {'sales':'department'})

列的类型如下所示:

hr.dtypes

Figure 2

我们的数据非常干净,没有缺失值

hr.isnull().any()

Figure 3

该数据包含 14,999 名员工和 10 项功能

hr.shape

(14999,10)

“左”列是记录 1 和 0 的结果变量。1 为离职员工,0 为未离职员工。

数据集的部门列有许多类别,为了更好地建模,我们需要减少类别。“部门”列有以下类别:

hr['department'].unique()

数组(['销售','会计','人力资源','技术','支持','管理',【T25 ',' IT ','产品 _mng ','营销',' RandD'],dtype =对象)

让我们将“技术”、“支持”和“IT”结合在一起,称之为“技术”。

import numpy as np
hr['department']=np.where(hr['department'] =='support', 'technical', hr['department'])
hr['department']=np.where(hr['department'] =='IT', 'technical', hr['department'])

更改后,部门类别的外观如下:

【'销售' '会计' '人力资源' '技术' '管理' '产品 _ mng '】
【市场营销' '随机】】

数据探索

首先,让我们找出离开公司和没有离开公司的员工人数:

hr['left'].value_counts()

Figure 4

剩下 3571 名员工,11428 名员工留在我们的数据中。

让我们来了解一下这两个类别的数字:

hr.groupby('left').mean()

Figure 5

几种观察:

  • 留在公司的员工的平均满意度高于离开公司的员工。
  • 离开公司的员工平均每月工作时间比留下来的员工多。
  • 发生工伤事故的员工比没有发生工伤事故的员工更不容易离职。
  • 与过去五年中没有获得晋升的员工相比,过去五年中获得晋升的员工离职的可能性更小。

我们可以计算分类变量(如部门和工资)的分类平均值,以获得更详细的数据,如下所示:

hr.groupby('department').mean()

Figure 6

hr.groupby('salary').mean()

Figure 7

数据可视化

让我们将数据可视化,以便更清楚地了解数据和重要特征。

条形图为部门员工工作争取和离职频率

%matplotlib inline
import matplotlib.pyplot as plt
pd.crosstab(hr.department,hr.left).plot(kind='bar')
plt.title('Turnover Frequency for Department')
plt.xlabel('Department')
plt.ylabel('Frequency of Turnover')
plt.savefig('department_bar_chart')

Figure 8

很明显,员工流动的频率在很大程度上取决于他们工作的部门。因此,部门可以很好地预测结果变量。

员工薪资水平和离职频率条形图

table=pd.crosstab(hr.salary, hr.left)
table.div(table.sum(1).astype(float), axis=0).plot(kind='bar', stacked=True)
plt.title('Stacked Bar Chart of Salary Level vs Turnover')
plt.xlabel('Salary Level')
plt.ylabel('Proportion of Employees')
plt.savefig('salary_bar_chart')

Figure 9

员工流动的比例在很大程度上取决于他们的工资水平;因此,工资水平可以是预测结果的一个很好的预测因素。

在探索阶段,直方图通常是我们可以用于数值变量的最有用的工具之一。

数值变量直方图

num_bins = 10hr.hist(bins=num_bins, figsize=(20,15))
plt.savefig("hr_histogram_plots")
plt.show()

Figure 10

为分类变量创建虚拟变量

数据集中有两个分类变量(部门、薪水),它们需要转换成虚拟变量才能用于建模。

cat_vars=['department','salary']
for var in cat_vars:
    cat_list='var'+'_'+var
    cat_list = pd.get_dummies(hr[var], prefix=var)
    hr1=hr.join(cat_list)
    hr=hr1

一旦创建了虚拟变量,就需要删除实际的分类变量。

为分类变量创建虚拟变量后的列名:

hr.drop(hr.columns[[8, 9]], axis=1, inplace=True)
hr.columns.values

数组(['满意度 _ 等级','上次 _ 评价','人数 _ 项目',
'平均 _ 月 _ 小时','时间 _ 花费 _ 公司',
'离职','晋升 _ 最近 _ 5 年','部门 _ 随机',
'部门 _ 会计','部门 _ 人力资源','部门 _ 管理',【T26'部门 _ 营销',
'部门 _ 产品 _ 管理',【部门 _ 销售',【部门 _ 技术】,【薪资 _ 高】,
'薪资 _ 薪资

结果变量为“左”,其他变量均为预测变量。

hr_vars=hr.columns.values.tolist()
y=['left']
X=[i for i in hr_vars if i not in y]

特征选择

递归特征消除(RFE) 的工作原理是递归地移除变量,并在剩余的变量上建立模型。它使用模型精度来确定哪些变量(和变量组合)对预测目标属性贡献最大。

让我们使用特征选择来帮助我们决定哪些变量是重要的,可以非常准确地预测员工流动率。X 总共有 18 列,选 10 列怎么样?

from sklearn.feature_selection import RFE
from sklearn.linear_model import LogisticRegressionmodel = LogisticRegression()rfe = RFE(model, 10)
rfe = rfe.fit(hr[X], hr[y])
print(rfe.support_)
print(rfe.ranking_)

***【真真假假真真假假真真假假真真假假

【1 1 3 9 1 1 1 1 1 1 1 5 1 1 6 8 7 4 1 1 2】***

您可以看到 RFE 为我们选择了 10 个变量,它们在 support_ 数组中标记为 True,在 ranking_ 数组中标记为 choice“1”。它们是:

['满意度 _ 等级','上次 _ 评价','时间 _ 花费 _ 公司','工作 _ 事故','晋升 _ 最近 _ 5 年','部门 _ 随机','部门 _ 人力资源','部门 _ 管理','薪资 _ 高','薪资 _ 低']

cols=['satisfaction_level', 'last_evaluation', 'time_spend_company', 'Work_accident', 'promotion_last_5years', 
      'department_RandD', 'department_hr', 'department_management', 'salary_high', 'salary_low'] 
X=hr[cols]
y=hr['left']

逻辑回归模型

from sklearn.cross_validation import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=0)from sklearn.linear_model import LogisticRegression
from sklearn import metrics
logreg = LogisticRegression()
logreg.fit(X_train, y_train)

LogisticRegression(C = 1.0,class_weight=None,dual=False,fit_intercept=True,intercept_scaling=1,max_iter=100,multi_class='ovr ',n_jobs=1,penalty='l2 ',random_state=None,solver='liblinear ',tol=0.0001,verbose=0,warm_start=False)

from sklearn.metrics import accuracy_score
print('Logistic regression accuracy: {:.3f}'.format(accuracy_score(y_test, logreg.predict(X_test))))

逻辑回归精度:0.771

随机森林

from sklearn.ensemble import RandomForestClassifier
rf = RandomForestClassifier()
rf.fit(X_train, y_train)

RandomForestClassifier(bootstrap = True,class_weight=None,criterion='gini ',max_depth=None,max_features='auto ',max_leaf_nodes=None,min _ infinity _ split = 1e-07,min_samples_leaf=1,min_samples_split=2,min_weight_fraction_leaf=0.0,n _ estimators = 10,n_jobs=1,oob_score=False,random_state=None,verbose=0,warm _ start = False)【T24

print('Random Forest Accuracy: {:.3f}'.format(accuracy_score(y_test, rf.predict(X_test))))

随机森林精度:0.978

支持向量机

from sklearn.svm import SVC
svc = SVC()
svc.fit(X_train, y_train)

SVC(C=1.0,cache_size=200,class_weight=None,coef0=0.0,
decision _ function _ shape = None,degree=3,gamma='auto ',kernel='rbf ',
max_iter=-1,probability=False,random_state=None,shrinking=True,
tol=0.001,verbose=False)

print('Support vector machine accuracy: {:.3f}'.format(accuracy_score(y_test, svc.predict(X_test))))

支持向量机精度:0.909

获胜者是… 随机森林 对吧?

交互效度分析

交叉验证试图避免过度拟合,同时仍然为每个观察数据集生成预测。我们使用 10 重交叉验证来训练我们的随机森林模型。

from sklearn import model_selection
from sklearn.model_selection import cross_val_score
kfold = model_selection.KFold(n_splits=10, random_state=7)
modelCV = RandomForestClassifier()
scoring = 'accuracy'
results = model_selection.cross_val_score(modelCV, X_train, y_train, cv=kfold, scoring=scoring)
print("10-fold cross validation average accuracy: %.3f" % (results.mean()))

十重交叉验证平均准确率:0.977

平均精度保持非常接近随机森林模型精度;因此,我们可以得出结论,该模型具有良好的通用性。

精确度和召回率

我们构建混淆矩阵来可视化分类器做出的预测,并评估分类的准确性。

随机森林

from sklearn.metrics import classification_report
print(classification_report(y_test, rf.predict(X_test)))

Figure 11

y_pred = rf.predict(X_test)
from sklearn.metrics import confusion_matrix
import seaborn as sns
forest_cm = metrics.confusion_matrix(y_pred, y_test, [1,0])
sns.heatmap(forest_cm, annot=True, fmt='.2f',xticklabels = ["Left", "Stayed"] , yticklabels = ["Left", "Stayed"] )
plt.ylabel('True class')
plt.xlabel('Predicted class')
plt.title('Random Forest')
plt.savefig('random_forest')

Figure 12

逻辑回归

print(classification_report(y_test, logreg.predict(X_test)))

Figure 13

logreg_y_pred = logreg.predict(X_test)
logreg_cm = metrics.confusion_matrix(logreg_y_pred, y_test, [1,0])
sns.heatmap(logreg_cm, annot=True, fmt='.2f',xticklabels = ["Left", "Stayed"] , yticklabels = ["Left", "Stayed"] )
plt.ylabel('True class')
plt.xlabel('Predicted class')
plt.title('Logistic Regression')
plt.savefig('logistic_regression')

Figure 14

支持向量机

print(classification_report(y_test, svc.predict(X_test)))

Figure 15

svc_y_pred = svc.predict(X_test)
svc_cm = metrics.confusion_matrix(svc_y_pred, y_test, [1,0])
sns.heatmap(svc_cm, annot=True, fmt='.2f',xticklabels = ["Left", "Stayed"] , yticklabels = ["Left", "Stayed"] )
plt.ylabel('True class')
plt.xlabel('Predicted class')
plt.title('Support Vector Machine')
plt.savefig('support_vector_machine')

Figure 16

当一名员工离职时,我的分类器多久能正确预测一次?这种测量被称为“召回”,快速浏览这些图表可以证明随机森林显然最适合这一标准。在所有的周转案例中,random forest 在 1038 个案例中正确检索了 991 个案例。这转化为约 95% (991/1038)的周转“召回”,远好于逻辑回归(26%)或支持向量机(85%)。

当一个分类器预测一个员工将离开时,这个员工实际上多久离开一次?这种测量称为“精度”。随机森林再次以大约 95%的精度(1045 中的 991)优于其他两个,逻辑回归为大约 51%(540 中的 273),支持向量机为大约 77%(1150 中的 890)。

ROC 曲线

from sklearn.metrics import roc_auc_score
from sklearn.metrics import roc_curvelogit_roc_auc = roc_auc_score(y_test, logreg.predict(X_test))
fpr, tpr, thresholds = roc_curve(y_test, logreg.predict_proba(X_test)[:,1])rf_roc_auc = roc_auc_score(y_test, rf.predict(X_test))
rf_fpr, rf_tpr, rf_thresholds = roc_curve(y_test, rf.predict_proba(X_test)[:,1])plt.figure()
plt.plot(fpr, tpr, label='Logistic Regression (area = %0.2f)' % logit_roc_auc)
plt.plot(rf_fpr, rf_tpr, label='Random Forest (area = %0.2f)' % rf_roc_auc)
plt.plot([0, 1], [0, 1],'r--')
plt.xlim([0.0, 1.0])
plt.ylim([0.0, 1.05])
plt.xlabel('False Positive Rate')
plt.ylabel('True Positive Rate')
plt.title('Receiver operating characteristic')
plt.legend(loc="lower right")
plt.savefig('ROC')
plt.show()

Figure 17

受试者操作特征(ROC) 曲线是二进制分类器使用的另一个常用工具。虚线代表纯随机分类器的 ROC 曲线;一个好的分类器尽可能远离那条线(朝向左上角)。

随机森林模型的特征重要性

feature_labels = np.array(['satisfaction_level', 'last_evaluation', 'time_spend_company', 'Work_accident', 'promotion_last_5years', 
      'department_RandD', 'department_hr', 'department_management', 'salary_high', 'salary_low'])
importance = rf.feature_importances_
feature_indexes_by_importance = importance.argsort()
for index in feature_indexes_by_importance:
    print('{}-{:.2f}%'.format(feature_labels[index], (importance[index] *100.0)))

晋升 _ 最后 _ 5 年-0.20%
部门 _ 管理-0.22%
部门 _ 人力资源-0.29%
部门 _ 随机-0.34%
薪资 _ 高-0.55%
薪资 _ 低-1.35%
工作 _ 意外-1.46%
最后 _ 评估-19.19%
时间 _ 花费 _ 公司-25.77

根据我们的随机森林模型,上面以升序显示了影响员工是否会离开公司的最重要的特征。

摘要

这就把我们带到了文章的结尾。我不打算打印出模型预测他们可能会辞职的员工名单。这不是本分析的目的。记住我们不可能有一个适用于所有人的算法。员工离职分析可以帮助指导决策,但不能做出决策。小心使用分析以避免法律问题和员工的不信任,并结合员工反馈使用它们,以做出最佳决策。

创建这篇文章的源代码可以在这里找到。我将很高兴收到关于上述任何反馈或问题。

使用 NLP 模型预测产品成功

原文:https://towardsdatascience.com/predict-product-success-using-nlp-models-b3e87295d97?source=collection_archive---------9-----------------------

预测时尚电子商务下一个趋势的教程

先决条件

特定主题的经验:新手

专业经验:无行业经验

机器学习的知识不是必需的,如果读者熟悉基本的数据分析会有所帮助。文章中的所有概念都是为初学者从头开始详细解释的。要跟进,请在此下载样本数据集。本教程解释了自然语言处理的商业应用,以获得可操作的见解。

自然语言处理和商业用例介绍

在线上常见的自然语言处理(NLP)的一个非常简单的定义是,它是对自然形式、书面文本或语音中使用的语言应用计算技术,以分析并从中获得某些见解。这些见解可以有很大的不同,从理解一段文字中的情感到识别句子中的主题。

分析的复杂程度也可能从简单到非常复杂。例如,你可能想将文本分类,比如来自 Twitter 的数据,分为正面情绪和负面情绪。另一方面,您可能希望从大型数据集中的产品评论数据中提取产品建议/投诉,以确定新产品发布策略。聊天机器人正在做的工作,理解文本查询并对其做出回应;垃圾邮件检测等。属于 NLP 的范围。

这个领域可能包含许多应用程序,因此也包含许多技术,这使得它成为一个相当大的主题。在这个特别的教程中,我们将详细讨论 NLP 的商业案例应用,以获得电子商务领域中实用且可行的见解。

了解业务场景

本教程使用了 Kaggle 上的一个数据集,来自电子商务时尚领域。这可以在https://www . ka ggle . com/nica potato/women-ecommerce-clothing-reviews找到

这个数据集似乎是大多数电子商务市场的典型,因此它是一个很好的代表。这是一个数据集,其中有数字评级数据以及对几件女装的文本评论。这些商品有一个“服装 ID ”,这是一个唯一的标识符。有两种评级——数字 1 到 5 表示产品评级,1 或 0 表示是否推荐产品,二项式属性,即只有两个可能的值。还有其他描述项目类别、评论者年龄等的属性。仔细想想,该数据集中提供的这些属性是大多数此类在线购物门户的典型特征。事实上,这并不仅限于时尚领域,因此这里应用的技术也应该可以扩展到其他领域。

有了这个数据集,探索文本评论是否可以预测该项目是否会成为趋势将是有趣的。这对时装业来说是非常有用的信息。如果这种对产品的洞察是准确的,产品或品类经理就可以对产品的库存策略、促销等做出合理的决策。这是我们的业务问题。

因此,我们的目标是建立一个自动化系统,可以分析客户对新产品最初的一些评论,并预测新推出的产品是否会成功。有了这些信息,就可以建立产品库存,并通过供应链进行销售。通过这种方式,人们可以实施软产品发布,并响应市场对产品的接受度。

本实验使用的两个工具是 Excel 和 Rapidminer。这个工作流程有两个部分。首先在 excel 中执行一些功能工程,然后在 Rapidminer 中执行实际的模型训练和测试。

第 1 部分:Excel 中的特征工程

有了给定的数据,我们需要首先得出“趋势产品”的数学定义。在这个阶段,业务领域的知识就派上了用场。我们知道,如果一个产品做得很好,如果客户对它满意,他们会努力写关于它的正面评价。人们通常倾向于写详细的评论,如果他们非常高兴或者非常不满意。如果他们开心,他们倾向于写好的评论,并给予高度评价。此外,做得好的产品会得到很多评论,大多数评论者会对评级高的产品有类似的看法。

用数学方法来解释。产品的成功与评论数量、产品的平均评级有直接关系,与产品评级的标准偏差有反比关系。也就是说,如果市场喜欢它,许多客户往往会在没有太大变化的情况下给予它很高的评价。基于这种理解,我们可以创建一个新的特征。

借用在神经网络训练中使用的 tanh 激活函数,我们可以如下定义新的特征“评级强度”。

【评级强度=(评级因子)

在哪里,

其中,“评论比例”是项目从完整数据集
收到的评论的比例,平均值和标准差不言自明。

这将创建一个值介于 0 和 1 之间的新要素。接近 1 的值被分配给有大量评论、评级良好且评级差异非常低的项目,即每个人都给它评级良好。更接近 0 的值被分配给没有产生太多兴奋的项目-评论的数量很少,并且评级很低,差异很大。这个数学定义的主要目的是获得一个代表产品成功的数字特征,最好是 0 到 1 之间的值,而不是未缩放的大值。

这样,您可以创建一个名为“Item_success”的二项式标签,其中有两个可能的值“trending”或“Not trending”,其中“Trending”被分配给评级强度高于某个临界值的项目,而“Not trending”被分配给低于该临界值的项目。对于这个数据集,我选择了临界值 0.00036。这个截止值是通过简单地查看数据集来确定的,但是可以有更好的自动化方法来完成这个任务。然而,这种手动决策是一种非常简单快捷的解决方案。对于使用这些产品的人来说,这是一个相当直接的决定。下面是数据集的一个片段。

Feature engineered dataset (snippet)

根据可用要素在数据集中创建新要素的过程称为要素工程。这是一个有用的步骤,可以部署到机器学习问题。到目前为止,所有的活动都是在 Microsoft Excel 中进行的。下一步是开发一个模型来预测我们创建的这个二项式标签。预测建模部分在 Rapidminer 中进行。

第 2 部分:Rapidminer 中的预测建模

设置

这一部分是在 Rapidminer 中进行的。问题基本上是语言处理。给定一个新的评论,我们希望预测该项目是否会成为趋势。在评论的语言中肯定包含了一些信息,这些信息可以提供该项目是否会成功的线索。给定过去的数据,我们应该能够预测正在审查的新项目。

本质上,我们需要使用过去的数据来建立一个模型,该模型可以从已知成功产品的评论语言中学习,并在未来产品的新评论中使用这种学习来预测其成功的机会。

Rapidminer 中使用的工艺流程如下所示:

Model training in Rapidminer

Rapidminer 是一个非常易于使用的机器学习平台,非常适合业务经理,他们可能不是数据科学家,但热衷于将这些技术快速应用于他们的业务需求。在 Rapidminer 中,通过将相关操作符拖放到工作空间中,并以图形方式连接输入数据,即可轻松执行每项操作。在上图中,您可以看到每个阶段的数据流和处理过程。

让我们来看一下上面使用的每个运算符:

1.检索:我们首先需要检索我们在第 1 部分中创建的数据集。为此,我们可以读取 excel 文件本身,或者首先将数据导入 Rapidminer,然后访问它。在这种情况下,我们采取的是后者。首先必须导入数据,这非常简单,有一个向导可以一步一步地进行导入,您可以通过单击 Rapidminer 中的“添加数据”按钮开始导入。在 Retrieve 操作符的设置中,我们定义了要访问的数据集的名称,该名称是在导入过程中定义的。

2.示例:数据集包含近 19500 行。但是我们不想使用完整的数据集。这将耗费时间,并可能导致过度拟合。因此,在样本运算符中,我们可以定义要选择多少样本。我选择了 4500 个样品。

3.设置角色:我们需要定义哪个特征是我们感兴趣的,我们想要预测的。对于我们来说,它是“Item_success”列,我们将此功能定义为标签*。标签是需要预测的特征。*

4。 选择属性:在我们的数据集中,我们定义了新的列,如平均评分、评分的标准差、评论的比例等。以达到“项目成功”特征。从将被提供来训练模型的训练数据中移除这些特征是非常重要的。这一点非常重要。这些列将不可用于未来的实时数据,在此包含它们可能会给出错误的准确性级别,并且模型在部署中将不起作用。您可以浏览 excel 文件来更好地理解这些列。所以实际选择的特性如下:
年龄
类别名称
部门名称
部门名称
项目 _ 成功
评分
推荐 IND
审核文本
标题
这些特性在部署时都可以用于新数据。

5。 名义到文本:这是一个数据类型转换器。我们用它将评论文本转换成文本数据类型。这对于流程中的下一个操作员是必要的。

6.处理文档:这是此类文本分类应用的关键步骤。这是一个嵌套运算符,即该运算符中有一个流程,如下所示:

Process flow to generate n-Grams

它将文本分解成符号化的 n 元文法,这里 n 被设置为 2。这些 n 元语法成为单词包的一部分,模型稍后使用该单词包来理解评论中的单词和标签特征之间的关系。对文档进行分词,提取词干并过滤掉停用词(如 a、an 等。)都是标准做法。词干标记都转换为小写,我们过滤掉少于 5 个字符或多于 25 个字符的标记。最后,生成 2 个字母的单词,形成一大袋短语。这是模型学习的主要数据。

7.存储:存储操作符用于存储流程文档步骤生成的词表。在对新数据应用学习模型时,必须使用这种方法。这是需要记住的重要一点。

8。分割验证:下一个任务是训练和测试模型。拆分验证运算符用于此目的。这也是一个嵌套操作符。它将数据分为训练数据和测试数据,并对测试数据使用训练好的模型。该运算符的内部流程如下所示:

Split validation sub-process

这里使用了梯度增强树,再次使用如上所示的存储操作符来存储训练的模型以供将来使用。应用模型操作符对数据的测试部分应用训练模型,性能二项式分类操作符用于测量模型对测试数据的性能。性能运算符生成一个 2x2 表,其中包含模型预测的分类和实际分类的详细信息。

培训和评估

在 Rapidminer 中设置流程后的下一个阶段是尝试各种模型,看看什么能产生好的结果。这是你实际训练你的机器学习模型的部分。

有几种算法可以尝试。从 k-NN 这样的简单模型开始通常是很好的做法。k-NN 技术是最简单的可能模型,可以用于几乎所有的机器学习问题。这有助于您建立一个好的基准,然后您可以根据它来尝试更高级的技术。使用 Rapidminer,只需用您选择的任何其他预测模型替换上图所示的梯度增强树模型,只需右键单击运算符并选择替换即可。当然,不是所有的模型都适用于所有的情况。有些模型只接受数字数据。这个阶段最好的方法是试错,通过实践,事情会变得清晰。

Replacing an operator for trials

k-NN 模型获得的结果如下所示。

k-NN results

继续该过程,尝试了以下模型,这些模型的相应结果在下面给出。

Naive Bayes results

Decision Tree results

Random Tree results

Gradient Boosted Trees’ results

梯度推进树(GBT)给出了所有试验模型的最佳结果。对整个数据集的子集进行了反复试验。现在,我们可以重复使用学习过的 GBT 模型,并将其应用于整个数据集,并检查结果如何。检索存储的 GBT 模型和相关单词列表的过程如下所示,重要的是使用在模型训练期间生成的相同单词列表。该步骤有助于检查学习的模型没有过度拟合训练数据;如果它确实过拟合,那么它对于实时应用将不是非常有用。以下流程也可用于将学习到的模型应用于新数据,即在生产中使用该模型——只需用新数据替换第一个操作符,其他一切将保持不变。

Applying the learnt GBT model to the full dataset

较大数据集的 GBT 结果如下所示:

GBT results for wider dataset

能够预测这样的产品的成功机会在计划库存和分销中非常有用。也许可以预测不同人口统计和地理位置的成功率,这对规划正确的产品分销非常有用。与任何模型一样,通过与实时数据并行运行来进一步测试它以进一步优化模型的准确性是非常重要的。这种应用清楚地显示了这种技术的效用,并且它们的普及只会增加。

一旦经过训练的模型和单词列表被存储,它可以被重新用于新数据的应用。这将涉及以与训练数据相同的格式获得新产品的审查和评级数据,并在上述应用学习的 GBT 模型的过程中,用新数据替换第一个操作员。运行这个过程,看看预测是什么。处理各种产品的品类经理可以以设定的频率运行这一过程,系统将帮助他在几分钟内找到正确的方向。当然,也有方法将预测数据输出到 excel 文件中,该文件可以分发给团队,以帮助他们对产品的供应链方面做出决策。

仍然有办法进一步改进这个系统。也许不需要用数学方法来定义成功的产品,如果可以挖掘出提供产品实际成功或失败的数据,准确性就可以提高。在本教程中,我们创建了一种基于可用数据的技术,人们甚至可以尝试不同的方法来获取丰富的数据,知道可以使用的工作流,这也需要一些工作来实现这样的数据创建和收集,但可能是最准确的。预先了解数据将如何使用以及机器学习系统如何使用 NLP 工作,对于设计数据收集和准备过程非常有用。

总之,我们已经实现了一个基于 NLP 的快速模型,它根据产品的文本评论来预测产品的成功几率。这样的系统可以帮助品类经理处理大量的产品和 SKU。将模型应用于新数据所消耗的时间仅仅是几分钟甚至几秒钟的事情,这可以被高频率地利用。Rapidminer 流程、数据集和结果可从这个 Github 存储库获得。

使用机器学习预测在线零售商的搜索相关性

原文:https://towardsdatascience.com/predict-search-relevance-using-machine-learning-for-online-retailers-5d3e47acaa33?source=collection_archive---------4-----------------------

Photo credit: Unsplash

高质量的搜索就是返回相关的结果,即使数据在变化或结构不良,查询也不精确。

大型在线零售商通常使用基于查询的搜索来帮助消费者在其网站上找到信息/产品。他们能够利用技术为用户提供更好的体验。因为他们知道搜索相关性的重要性,而且长时间和/或不成功的搜索会让他们的用户离开,因为用户习惯于并期待即时的相关搜索结果,就像他们从谷歌和亚马逊得到的一样。

似乎产品搜索只在亚马逊有效。例如,键入搜索术语“淋浴专用水龙头”,一种水龙头,我得到我正在寻找的。

Source: Amazon.ca

尽管搜索对任何电子商务业务的成功都至关重要,但它并不总是像看起来那么容易,尤其是对中小型在线零售商而言,因为它通常需要大量人工标记的数据和机器学习技术。

高质量的搜索就是返回相关的结果,即使数据在变化或结构不良,查询也不精确。我们今天要做的是:只给定原始文本作为输入,我们的目标是预测产品与家得宝网站搜索结果的相关性,从而帮助他们改善顾客的购物体验。我们开始吧!

数据

该数据集包含了家得宝网站上的大量产品和真实顾客搜索词。为了创建基本事实标签,家得宝将搜索/产品配对众包给了多个人工评级机构。我们将从 Kaggle 下载三个表格:

  • 训练集 train.csv 包含产品、搜索和相关性分数。
  • 包含每个产品的文本描述。
  • attributes.csv 提供了关于产品子集的扩展信息。

这三个表包含以下数据字段:

  • id,一个唯一的 Id 字段,表示一个(搜索术语,产品 uid)对。
  • product_uid,产品的 id。
  • 产品标题,产品标题。
  • product_description,产品的文本描述(可能包含 HTML 内容)。
  • search_term,搜索查询。
  • 相关性,给定 id 的相关性评级的平均值(我们将为给定的搜索词预测的特征)。
  • 名称,一个属性名称。
  • 值,属性的值。
import numpy as np
import pandas as pd
from nltk.stem.porter import *
stemmer = PorterStemmer()
import re
import randomrandom.seed(2018)df_train = pd.read_csv('train_depot.csv', encoding="ISO-8859-1")
df_pro_desc = pd.read_csv('product_descriptions.csv')
df_attr = pd.read_csv('attributes.csv')

对于属性表,我们只对品牌名称感兴趣,因为有时查询包含品牌名称。然后我们通过“product_uid”合并这三个表。

df_brand = df_attr[df_attr.name == "MFG Brand Name"][["product_uid", "value"]].rename(columns={"value": "brand"})
df_all = pd.merge(df_train, df_pro_desc, how='left', on='product_uid')
df_all = pd.merge(df_all, df_brand, how='left', on='product_uid')

Figure 1

文本预处理

在应用任何机器学习 NLP 算法之前,文本处理是一个重要的阶段。虽然文本处理在技术上可以在特征生成过程中完成,但我想先进行所有处理,然后再进行特征生成。这是因为相同的处理过的文本被用作输入来生成几个不同的特征。在我们的数据集中,有几个方面的文本处理。

  • 搜索词拼写纠正。我们将使用来自 Kaggle 论坛的谷歌词典
df_all['search_term']=df_all['search_term'].map(lambda x: google_dict[x] if x in google_dict.keys() else x)
  • 统一单位。
  • 删除特殊字符。
  • 词干文本
  • 标记文本

str_stem

我们将对所有文本特征应用 str_stem 函数。

df_all['product_title'] = df_all['product_title'].apply(str_stem)
df_all['search_term'] = df_all['search_term'].apply(str_stem)
df_all['product_description'] = df_all['product_description'].apply(str_stem)
df_all['brand'] = df_all['brand'].apply(str_stem)

之后,我们的文本看起来干净多了。

a = 0 
for i in range(a,a+2):
    print(df_all.product_title[i])
    print(df_all.search_term[i])
    print(df_all.product_description[i])
    print(df_all.brand[i])
    print(df_all.relevance[i])
    print()

Figure 2

特征生成

任何机器学习项目中最重要也是最耗时的部分是特征工程。在我们的例子中没有例外,特别是,我们的主要数据是文本。新创建的特征可以分为几类:

  • 计数特征:查询长度、标题长度、描述长度、品牌长度、查询和标题之间的共克数、查询和描述之间的共克数、查询和品牌之间的共克数。

例如,查询是“仅淋浴龙头”,相关联的产品标题是“铬制 Delta Vero 1-手柄仅淋浴龙头装饰套件(不包括阀门)”,相关联的产品描述是“用铬制 Delta Vero 单手柄淋浴龙头装饰套件更新您的浴室”。它具有时尚、现代和简约的美感。多选择通用阀将水温保持在+/-3 华氏度范围内,有助于防止烫伤。加利福尼亚居民:参见 65 号提案信息仅包括阀内件套件,粗进套件(R10000-UNBX)单独出售包括手柄即使在系统其他地方打开或关闭阀门时,也能保持冷热水压力平衡。由于纽约州的水感法规,请确认您的运输邮政编码没有被限制使用不符合水感要求的物品。

在本例中,整个查询只在产品标题中出现过一次,而没有在产品说明中出现。

在同一个例子中,在查询中出现的三个单词也出现在产品标题中,因此,在查询和产品标题之间有三个共同的单词。在查询中出现的两个词也在产品描述中出现,因此,在查询和产品描述之间有两个共同的词,等等。

  • 统计特征:标题长度与查询长度之比、描述长度与查询长度之比、标题与查询常用字数与查询长度之比、描述与查询常用字数与查询长度之比、查询与品牌常用字数与品牌长度之比。

为了创建新的特性,我们需要创建几个函数来计算普通克数和普通整词数。

str_common_whole_word

接下来是新功能的创建过程:

feature_generation

df_all.drop(['id', 'product_uid', 'product_title', 'search_term', 'product_description', 'brand', 'product_info', 'attr'], axis=1, inplace=True)

删除我们不再需要的列后,下面是我们将要开发的功能:

df_all.columns

Figure 3

模型

在文本处理和特征工程之后,训练/预测将变得快速和容易。

from sklearn.model_selection import train_test_splitX = df_all.loc[:, df_all.columns != 'relevance']
y = df_all.loc[:, df_all.columns == 'relevance']
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=0)

随机森林回归

random_forest_regression

Figure 4

岭回归

ridge_regression

Figure 5

用于回归的梯度增强

gradient_boosting_regressor

Figure 6

Xgboost 用于回归

Xgboost_regressor

Figure 7

XGBoost 库提供了一个名为plot_importance()的内置函数,用于绘制按重要性排序的特性。

from xgboost import plot_importance
plot_importance(xgb);

Figure 8

Jupyter 笔记本可以在 Github 上找到。享受这周剩下的时光吧!

参考:卡格尔

预测 Instagram 上的赞数

原文:https://towardsdatascience.com/predict-the-number-of-likes-on-instagram-a7ec5c020203?source=collection_archive---------1-----------------------

在本文中,我们将展示我们预测 Instagram 帖子点赞数的方法。我们首先回顾一下如何收集数据集和分析数据。然后,我们将提供一个基本模型,而不用使用 XGBoost 查看图像。下一步,将使用自然语言处理(NLP)来提取一些特征。最后,卷积神经网络(CNN)被开发用于从图像中提取特征。

Github 链接:https://github.com/gvsi/datascience-finalproject

一、动机

  • **目标:**预测给定 Instagram 帖子的赞数。
  • 背景:社交媒体影响者从数字营销商那里获得报酬,以推广产品或服务。
  • **应用:**使用在线营销中开发的模型来寻找对给定帖子产生最多印象的影响者。

举一个这样的帖子的例子,这个有影响力的人正在旅行,在这张照片中,她放置了一种产品,一种除臭剂,很可能是公司为此支付的。

Post by Léa Camilleri: https://www.instagram.com/p/BRNlFUBAG5i/

2。数据

构建数据集

与项目相关的挑战之一是为我们正在处理的用例聚集足够的相关数据。

建立数据集的第一步是收集 Instagram 影响者的名单,也就是说,作为职业的一部分,用户会发布营销 Instagram 帖子。

找到这类信息本身就是一个挑战,因为这类名单不容易被公众获得。

最终,我们遇到了 Inconosquare 指数影响者,这是一个由 2000 多个 Instagram 影响者组成的列表。这个索引可以在https://influence.iconosquare.com上找到。

我们不得不爬取 70 多页的影响者,以获得他们在可用列表中的句柄。

现在真正的挑战来了:搜集这些用户的 Instagram 资料。这包括从个人资料中读取元数据(关注者/跟随的数量,帖子的数量,个人资料的描述),从用户那里抓取 17 个最新的图像(JPG 格式的图像,喜欢的数量,评论的数量,时间戳,描述文本)。

最终结果是每个用户的 JSON 文件,如下所示:

JSON file obtained for a given user

刮刀

Instagram 的 API 对其后端服务器的请求限制为每小时 60 个,这使得它对任何真正的应用程序或数据收集完全无用。官方 API 的替代方法是以编程方式抓取每个页面。

我们使用的 scraper 是用 Selenium 编写的,Selenium 是一个旨在为 web 应用程序构建功能测试的框架。Selenium 在这种情况下用于抓取网页并从中收集数据。

scraper 最初线性扫描用户的最新帖子,然后打开每个帖子来检索与每个图像相关的更细粒度的信息。

下面是铲运机的运行演示:

Scraper in action

收集了来自 972 名 Instagram 影响者的 16539 张图像来训练和测试我们的模型。

数据集分析

关于所收集数据的一些简要数据指标。我们可以看到,点赞数有一个很高的标准差,61 224.20。看起来差距很大,平均值为 24 416.38,但 75%的帖子的赞数少于 18 359。

Dataset summary

下面的直方图证实了表中显示的值,大多数帖子的赞数都低于 20 万。在我们感兴趣的应用程序中,删除拥有大量关注者(超过 1 00 万关注者)和高平均点赞数(超过 20 万)的人是有意义的,因为他们不再被视为有影响力的人,而是名人/明星。这也将有助于减少我们模型的误差。

我们过滤了我们的数据集,只保留平均点赞数低于 20 万的 Instagramers,并且他们的粉丝必须少于 1 00 万。经过筛选,我们保留了 746 个 Instagramers,对应 12678 个帖子。点赞数的标准差下降到 9999.27,均值下降到 8306.93。上图右侧显示了点赞数量的直方图。

关注者数量不一定意味着影响力大

我们绘制了点赞数和关注数的图表。

有增加的趋势,但是,不显著。它似乎有很多噪音。仅关注者的数量可能不是预测给定帖子的点赞数量的好指标,因为我们可以看到,拥有大量关注者的人不一定有大量的点赞。

3.模型

我们将首先开发一个基本模型,其中包含从数据集获得的一些基本特征。然后,我们将添加从自然语言处理(NLP)获得的特征,最后,添加从卷积神经网络生成的特征。

为了比较不同的模型,我们将使用两个性能指标:均方根误差(RMSE)和 R 值。

A .基础模型

基本模型包括以下特征:

给定功能:

  • 关注者数量
  • 下列数量
  • 员额数

提取的特征:

  • 网站:我们将用户描述中提供的网站分为不同的类别:Youtube、脸书、Twitter、博客、音乐和其他。然后我们对不同的类别进行一次性编码。
  • 星期几:使用每个数据贴的数据,我们对星期几进行了热编码

生成的特征:

  • 平均点赞数:我们观察到,关注者的数量不一定会产生高点赞数。不活跃和虚假的追随者会影响结果,一个更好的衡量标准似乎是每个用户的平均点赞数。其余的功能应该根据平均点赞数来增减点赞数。

从生成的特征中,我们发现:

网站

11%的用户拥有 Youtube 频道或视频作为他们的网站,4%的用户拥有脸书个人资料,2%的用户拥有博客,1%的用户拥有与音乐相关的网站(Soundcloud 或 Spotify)。88%的用户在他们的用户档案中有一个网站。

星期几

上传图片数量最多的一天是周日,占 18%,然后是周六和周四,占 15%,周五和周三,占 14%,最后是周一,占 11%。似乎只有两天有不同的统计数据,周日有更多的帖子,周一较少。

XGB

对这些特征应用具有以下参数的 XGBoost 模型:max_depth=4,learning_rate=0.01,n_estimators=596,我们获得了 2876.17 的 RMSE 和 0.92 的 R。

从 XGBoost 给出的特征重要性图中,我们可以看到平均点赞数显著影响了 XGB 模型的结果。F 值 4084,比其他所有特征加起来都大。在基本特征方面,帖子数量、关注人数和关注人数的 F 值较低。就提取的特征而言,星期六似乎比其他日子有更大的影响。或许这表明周六发帖会比其他时间获得更多的赞。之前有人说,一周内的帖子分布比较均匀,周日发布的帖子多,周一发布的帖子少。

B.自然语言处理

我们的数据集包含一些我们处理过的文本数据。首先,有用户传记数据。此字段包含用户为介绍自己和其个人资料所写的信息。第二个字段是每篇文章的标题。这个标题还包含用户添加到标题中的任何相关的标签。第三个字段包含帖子中提到的所有用户。最后,有一个字段用于显示 post 发生的位置。

由于我们没有太多的时间,我们决定采取词汇袋的方法。首先,我们清理数据,并使其进入可工作状态。然后,我们删除了文本中所有的标点符号、停用词和表情符号(稍后会详细介绍表情符号)。然后,我们拆分单词,并使用 scikit-learn 函数 CountVectorizer 对文本进行矢量化。我们还尝试对 TF-IDF 使用 scikit 函数,但是,似乎 CountVectorizer 工作得更好。当我们为帖子的标题做这个过程时,我们最终得到了 7000 多个独特的单词。这导致非常稀疏的 16k×7k 矩阵。为了减少矩阵的稀疏性,我们采用了一种技术,在这种技术中,我们只使用文本中顶部的单词,而不是所有的单词。因此,在评估我们的功能时,我们能够使用前 100、200、300 个词。

研究表情符号很有趣,因为在 Instagram 上使用表情符号非常流行。与实际的文本数据不同,我们必须以不同的方式处理表情符号。然而,因为表情符号是 unicode 的,所以我们能够为它们创建自己的 CountVectorizer 函数。然后,像标题文本数据一样,我们能够根据出现的次数,将热门表情符号的子集作为特征。

当试图找出我们将在最终模型中使用的 NLP 特征子集时,我们试图预测给定 NLP 数据子集的帖子的点赞数。我们选择了降低 RMSE 最大的数据子集。在测试了几个子集后,我们发现最好的子集是这样的:来自个人帖子标题的前 500 个单词/标签,以及出现超过 175 次的表情符号(37 个表情符号)。

下面是一些前 500 个单词的例子(我展示的是前 500 个单词中长度超过 5 个字符的子集):

实际上冒险几乎已经总是惊人的另一个任何人任何事物建筑周围可用真棒巴塞罗那美丽的美丽的景点美丽成为落后相信柏林更好的生日早餐加利福尼亚照相机挑战机会改变巧克力科切拉咖啡收藏即将评论社区保护夫妇课程美味的灯杆设计细节不同的复活节足够欧洲每个人都兴奋的体验探索家庭时尚最喜爱的特色感觉最后健身跟随追随者忘记法国星期五朋友地理感恩指南标签健康图像重要的不可思议的灵感激发 insta gram island journey liketk liketkit like know little living location London looking 可爱的 madwhips 杂志化妆制作梅赛德斯百万富翁时刻周一早晨母亲山 natgeo natgeo creative national natural natural natural natural natural natural natural natural nature nothing 官方网上装备人们完美的表演摄影摄影师摄影照片图片地点请 porque pretty prints profile project 真的食谱记得周六季系列分享某人某事有时特别赞助春季开始的故事夏季周日日落支持感谢 photosociety 的事情虽然明天晚上想在一起旅行尝试土耳其度假想穿周末没有狼百万富翁的精彩工作锻炼昨天 youtube

以下是排名前 37 位的表情符号:

Top 37 emojis

当我们将这些特征添加到基础模型的特征中时,我们的 RMSE 实际上恶化了。事实是,这些额外的 NLP 特征与基本模型特征中的平均特征相比并不重要。由于基础+ NLP 模型较少依赖均值特征来预测喜欢,我们的 RMSE 实际上恶化了。我们的 RMSE 分数上升到 2895.90,我们的 R 分数变成了 0.9163。由于有超过 500 个特性,这个模型的特性重要性图很难读懂。

但是,使用此功能:

vec = model_xgb.feature_importances_for i in range(len(vec)):if vec[i] > .01:print(X_train.columns[i])

我们发现最重要的自然语言处理特征是单词:ada amazing AMG code El going to make man thank time

C.迁移学习

我们采用的另一种方法与图像处理和计算机视觉有关。

目的是识别与图像相关的特征,这些特征可能对确定最终的点赞数有意义。

虽然基本模型中的特性是我们认为在这个回归问题中最有意义的,但我们认为在我们的模型中实现最微小的改进是一个巨大的成功。

迁移学习涉及使用预先训练的深度 ConvNet 的过程,并以此为起点建立考虑图像特征的模型。

有两种使用预训练模型的方法,我们都可以解决:

  • **使用 Inception V3 对 ConvNet 进行微调:**这是采用预训练的 ConvNet 权重,移除最后完全连接的层,并根据需要扩展网络。然后,我们通过继续反向传播来微调预训练网络的权重。我们使用的模型是 Inception v3。最后两个完全连接的层被删除,我们添加了三个额外的层。我们在 EC2 机器上用 GPU 对我们的数据点进行了重新训练。
  • 使用 VGG 的固定特征提取器 19: 这是移除最后一个完全连接的层,然后将 ConvNet 的剩余部分视为新数据集的固定特征提取器。VGG 19 是一个图像分类网络,在 ImageNet 数据集上的 1400 多万张图像上进行了预训练。移除最后一个完全连接的层为每个图像产生大小为 4096 的特征向量。我们可以使用这个(稀疏)向量作为基础模型中的特征。

结果

不幸的是,这两种方法都没有对我们的基本模型产生显著的改进。我们将这一点与这样一个事实联系起来,即这些深度网络是在头脑中有一个分类任务的情况下被训练的,这可能不一定适应像我们这样的回归问题。此外,我们的基本分类器使用了一个 XGBoost 模型,我们将其余的特征拟合到该模型中。XGBoost 通常具有混合的结果和非常稀疏的特征矩阵。

D .卷积回归神经网络

动机

我们推测转移学习方法不成功,因为转移网络是为分类问题训练的,而我们有一个回归目标。因此,我们的下一个想法是用谷歌的 TensorFlow 机器学习平台建立和训练我们自己的卷积神经网络(CNN),这是专门为回归设计的。

设计

像所有 CNN 一样,我们的设计从 c 卷积层开始,卷积层被展平成 f 全连接层。完全连接的层将过滤成最后一层 1 ReLU 激活的神经元,该神经元将输出喜欢的数量。我们首先想到的是连接我们在基本模型中使用的数字元特征(如关注者数量、数字跟随等。)作为图像分析的控制参数。我们认为这是有帮助的,因为不管图片如何,一个帖子获得的赞数都受到用户帖子的严重影响。例如,一个非常受欢迎的用户可能会发布一个普通物体的图片,比如一把椅子,但仍然会收到相对大量的赞。

建筑

选择神经网络的体系结构是一个艺术过程。在所有的机器学习问题中,模型设计者总是被以正确的方式选择超参数所困扰,既要给模型足够的自由来捕捉数据中的模式,又要对模型进行足够的约束以避免过度拟合。在神经网络设计中,这一问题因以下事实而变得更加复杂,即一切都是超参数——层数、层大小、通道数量、卷积滤波器大小、滤波器步幅等。为了解决这个问题,我们以这样一种方式编写代码,即模型初始化参数采用一种描述网络架构的紧凑形式。这使得我们能够非常快速地测试许多不同的架构,而无需重写任何代码。我们架构的标准是,在几个训练时期之后,模型不会很快开始过度拟合,并且 ReLU 激活不会太稀疏。下面是我们选定的架构。它成批接收 256 x 256 个图像,有 4 个卷积层和 5 个全连接层。对于卷积层,方框顶部的数字表示每个通道的输出形状,底部的数字表示通道的数量。对于完全连接的层,该数字简单地描述了该层中神经元的数量。

结果

CNN 被训练为一个独立的模型,但是为了将它集成到整个模型中,我们删除了每个图像的最终层的 8 个输出,并将它们用作主 XGBoost 中的功能。不幸的是,正如我们在 NLP 和迁移学习方法中看到的,我们的测试 RMSE 从 2876 增加到 2964。

改版

我们推断 RMSE 的上升可以归因于用户元特征被连接到完全连接的层。因为这些特征比图像本身更具预测性,网络学会了忽略图像,本质上像标准神经网络一样训练这些特征。下一步是简单地从网络中移除这些特征,并仅在图像上进行训练。当只对图像进行训练时,独立模型的 RMSE 预期要差得多。然而,当进行特征提取并与联合模型集成时,我们发现我们的 RMSE 比基本模型从 2876 减少到 2837。当分析联合 XGBoost 回归的重要特征时,我们发现实际上它从图像中发现了一个重要的特征。绘制所有样本的这一特征,我们看到它呈现高斯分布的形状。由此我们推测,它是所有图像的连续特征,如对比度或亮度,而不是离散值,如“这张照片中有一个人吗?”。下面你可以看到标记为“1_”的第二个特征来自卷积神经网络

这是感兴趣的特征的分布,关于所有的样本帖子。

Histogram of NN feature 1_

结论

在我们的基础模型上添加不同的子模型,如 NLP 或 CNN,表明除了用户特定的功能外,很难从 instagram 帖子中提取额外的预测能力。此外,即使有了基本模型,那些喜欢远远超出典型范围的用户也被大大低估了,他们丢掉了 RMSE 或者需要过滤。在我们的模型中缺乏帖子敏感性可能是由于每个用户都有一个具有足够独特品味的追随者,我们的模型无法在广泛的范围内概括这些偏好。一些可能的解决方案是创建特定于用户的模型,或者收集大量数据(数百万条帖子,而不是数千条),试图准确概括所有 instagram。最后,我们所有的模型和子模型都可以进行更优化的调整,希望获得更好的后期灵敏度,但我们的开发时间限制极大地限制了我们找到这个高度复杂问题的创造性解决方案的能力。

Corentin Dugué、Giovanni Alcantara、Joseph Shalabi 和 Sahil Shah。

预测新用户将在哪里预订他们的第一次旅行体验

原文:https://towardsdatascience.com/predict-where-a-new-user-will-book-their-first-travel-experience-e6c9ada67cf4?source=collection_archive---------11-----------------------

Photo credit: Pixabay

用户意图预测,学习排名

Airbnb 网站的核心是它的搜索。其搜索的一个最重要的特点是搜索排名。

Airbnb 显示的搜索结果是个性化的,针对他们预测最适合该用户的列表和体验。

这篇文章详细介绍了对 Airbnb 发布的两个数据集的探索,其目的是预测 Airbnb 用户预订旅行的第一个国家。更具体地说,以相关性递减的顺序预测前 5 个旅游目的地国家。

我们希望通过根据客人的人口统计信息和会议活动推断客人的偏好来实现一定程度的个性化,因为客人通过参与列表和进行查询来计划他们的旅行。

数据

数据集可以从 Kaggle 下载,我们将使用三个数据集:

  • train _ users.csv
  • 测试 _ 用户. csv
  • sessions.csv

有 16 个特征来描述每个用户,它们是:

  • id:用户 id
  • date_account_created:帐户创建日期
  • timestamp_first_active:第一个活动的时间戳,注意它可以早于 date_account_created 或 date_first_booking,因为用户可以在注册之前进行搜索
  • date_first_booking:首次预订的日期
  • 性别
  • 年龄
  • 注册方法
  • 注册流:用户注册的页面
  • 语言:国际语言偏好
  • affiliate_channel:什么样的付费营销
  • affiliate_provider:营销的地方,如谷歌,craigslist,其他
  • first_affiliate_tracked:用户在注册之前互动的第一个营销是什么
  • 注册应用程序
  • 第一设备类型
  • 第一个浏览器
  • country_destination:这是我们要预测的目标变量

描述每个 web 会话有 6 个特征,它们是:

  • user_id:与 users 表中的列' id '连接
  • 行为
  • 动作类型
  • 行动 _ 详细信息
  • 设备类型
  • secs _ elapsed

用户探索

import pandas as pd
import numpy as np
import seaborn as sns
import matplotlib.pyplot as plttrain_users = pd.read_csv('train_users_2.csv')
test_users = pd.read_csv('test_users.csv')
print("There were", train_users.shape[0], "users in the training set and", test_users.shape[0], "in the test set.")
print("In total there were", train_users.shape[0] + test_users.shape[0], "users.")

Figure 1

我们将探索训练和测试数据集中的所有用户。

df = pd.concat((train_users, test_users), axis=0, ignore_index=True)

缺失数据

在性别栏和第一浏览器栏中有“未知”,我们将用“男”填充“未知”。此外,在测试集的 date_first_booking 列中没有任何信息,因此,我们将放弃这个特性。

在此之后,我们可以看到有许多数据丢失。

df.gender.replace('-unknown-', np.nan, inplace=True)
df.first_browser.replace('-unknown-', np.nan, inplace=True)
df.drop('date_first_booking', axis=1, inplace=True)
df.isnull().sum()

Figure 2

用户年龄

df.age.describe()

Figure 3

最大年龄是 2014,这是不可能的。好像有些用户填了一年而不是年龄。同样,1 岁的最小年龄听起来很荒谬。根据服役期限,官方规定的最低年龄是 18 岁,但实际上这并不是强制性的。如果你不满 18 岁,拥有信用卡或借记卡,并且相当有礼貌和成熟,你使用 Airbnb 不会有任何问题。

df.loc[df['age'] > 1000]['age'].describe()

Figure 4

df.loc[df['age'] < 18]['age'].describe()

Figure 5

因此,我们将首先纠正每个错误填写的年龄,然后为年龄设置限制,并为异常值设置“NaN”。

df_with_year = df['age'] > 1000
df.loc[df_with_year, 'age'] = 2015 - df.loc[df_with_year, 'age']df.loc[df.age > 95, 'age'] = np.nan
df.loc[df.age < 16, 'age'] = np.nandf['age'].describe()

Figure 6

看起来更合理。我们现在可以可视化用户的年龄。

plt.figure(figsize=(12,6))
sns.distplot(df.age.dropna(), rug=True)
sns.despine()

Figure 7

不出所料,Airbnb 用户最常见的年龄在 25 岁到 40 岁之间。

用户性别

plt.figure(figsize=(12,6))
df["gender"] = df['gender'].fillna('M')
sns.countplot(data=df, x='gender')
plt.xticks(np.arange(4), ("NaN", "Male", "Female", "Other"))
plt.ylabel('Number of users')
plt.title('Users gender distribution')
sns.despine()

Figure 8

近似的 45%的用户性别未显示。并且在 Airbnb 的平台上,女性和男性用户之间没有显著差异。

旅游目的地国家

这是我们将在测试数据中预测的。

plt.figure(figsize=(12,6))
sns.countplot(x='country_destination', data=df)
plt.xlabel('Destination Country')
plt.ylabel('Number of users')
sns.despine()

Figure 9

近 60%的用户没有预订任何目的地(NDF)。预订最多的国家是美国(近 30%的用户预订了我们),因为数据集中的所有用户都来自美国。我们可以说,数据集中的美国旅行者更有可能在美国境内旅行。

从现在开始,我们将只研究至少进行了一次预订的用户。

plt.figure(figsize=(12,6))
df_without_NDF = df[df['country_destination']!='NDF']
sns.boxplot(y='age' , x='country_destination',data=df_without_NDF)
plt.xlabel('Destination Country box plot')
plt.ylabel('Age of Users')
plt.title('Country destination vs. age')
sns.despine()

Figure 10

预订不同目的地的用户之间没有明显的年龄差异。然而,预订英国的用户往往比预订西班牙和葡萄牙的用户年龄稍大。

用户注册

plt.figure(figsize=(12,6))
df_without_NDF = df[df['country_destination']!='NDF']
sns.countplot(x='signup_method', data = df_without_NDF)
plt.xlabel('Destination Country')
plt.ylabel('Number of users')
plt.title('Users sign up method distribution')
sns.despine()

Figure 11

数据中超过 70%的预订者使用基本的电子邮件方式注册 Airbnb,不到 30%的预订者使用他们的 facebook 帐户注册。数据中只有 0.26%的预订者使用他们的谷歌账户注册。

plt.figure(figsize=(12,6))
sns.countplot(x='country_destination', data = df_without_NDF, hue = 'signup_method')
plt.xlabel('Destination Country')
plt.ylabel('Number of users')
plt.title('Users sign up method vs. destinations')
sns.despine()

Figure 12

对于至少预订过一次的用户来说,他们中的大多数都是通过基本的电子邮件方式与 Airbnb 签约的,无论他们要去哪个国家旅行。

plt.figure(figsize=(12,6))
sns.countplot(x='signup_app', data=df_without_NDF)
plt.xlabel('Signup app')
plt.ylabel('Number of users')
plt.title('Signup app distribution')
sns.despine()

Figure 13

数据集中超过 85%的预订者在 Airbnb 的网站上注册,超过 10%的预订者在 iOs 上注册。

plt.figure(figsize=(12,6))
sns.countplot(x='country_destination', data=df_without_NDF, hue='signup_app')
plt.xlabel('Destination Country')
plt.ylabel('Number of users')
plt.title('Destinatiuon country based on signup app')
sns.despine()

Figure 14

美国旅行者比其他国家的旅行者有更多种类的注册应用。为了看得更清楚,我们去掉了我们。

df_without_NDF_US = df_without_NDF[df_without_NDF['country_destination']!='US']
plt.figure(figsize=(12,6))
sns.countplot(x='country_destination', data=df_without_NDF_US, hue='signup_app')
plt.xlabel('Destination Country')
plt.ylabel('Number of users')
plt.title('Destinatiuon country based on signup app without the US')
sns.despine()

Figure 15

在数据中,通过 Airbnb 网站报名是预订每个目的地国家最常见的报名。

关联公司

plt.figure(figsize=(12,6))
sns.countplot(x='affiliate_channel', data=df_without_NDF)
plt.xlabel('Affiliate channel')
plt.ylabel('Number of users')
plt.title('Affiliate channel distribution')
sns.despine()

Figure 16

plt.figure(figsize=(20,6))
sns.countplot(x='affiliate_provider', data=df_without_NDF)
plt.xlabel('Affiliate provider')
plt.ylabel('Number of users')
plt.title('Affiliate provider distribution')
sns.despine()

Figure 17

近似的 65%的预订者直接注册,没有任何附属计划,超过 23%的预订者通过谷歌附属计划注册,然而,如果你记得,只有 0.26%的预订者通过他们的谷歌账户注册。

第一

plt.figure(figsize=(12,6))
sns.countplot(x='first_affiliate_tracked', data=df_without_NDF)
plt.ylabel('Number of users')
plt.title('First affiliate tracked distribution')
sns.despine()

Figure 18

plt.figure(figsize=(18,6))
sns.countplot(x='first_device_type', data=df_without_NDF)
plt.xlabel('First device type')
plt.ylabel('Number of users')
plt.title('First device type distribution')
sns.despine()

Figure 19

plt.figure(figsize=(18,6))
sns.countplot(x='country_destination', data=df_without_NDF, hue='first_device_type')
plt.ylabel('Number of users')
plt.title('First device type vs. country destination')
sns.despine()

Figure 20

大约 60%的预订者使用苹果设备。尤其是在美国。

plt.figure(figsize=(18,6))
sns.countplot(x='country_destination', data=df_without_NDF_US, hue='first_device_type')
plt.ylabel('Number of users')
plt.title('First device type vs. country destination without the US')
sns.despine()

Figure 21

然而,在美国之外,Windows 桌面更加普遍,特别是在加拿大和澳大利亚,Mac 桌面和 Windows 桌面的使用差异很小。

plt.figure(figsize=(20,6))
sns.countplot(x='first_browser', data=df_without_NDF)
plt.xlabel('First browser')
plt.ylabel('Number of users')
plt.title('First browser distribution')
plt.xticks(rotation=90)
sns.despine()

Figure 22

数据中几乎 30%的预订者使用 Chrome 浏览器。

用户的首选语言

plt.figure(figsize=(12,6))
sns.countplot(x='language', data=df_without_NDF)
plt.xlabel('language')
plt.ylabel('Number of users')
plt.title('Users language distribution')
sns.despine()

Figure 23

绝大多数预订者的语言偏好是英语,这并不奇怪,因为数据集中的大多数用户来自美国。

plt.figure(figsize=(12,6))
sns.countplot(x='language', data=df_without_NDF_US)
plt.xlabel('language')
plt.ylabel('Number of users')
plt.title('Users language distribution without the US')
sns.despine()

Figure 24

除了美国,英语仍然是最受欢迎的语言,有趣的是,在数据中,中文是预订者第二受欢迎的语言。

日期

为了可视化时间序列,我们首先需要将数据类型转换为日期时间。

df_without_NDF['date_account_created'] = pd.to_datetime(df_without_NDF['date_account_created'])
df_without_NDF['timestamp_first_active'] = pd.to_datetime((df_without_NDF.timestamp_first_active // 1000000), format='%Y%m%d')plt.figure(figsize=(12,6))
df_without_NDF.date_account_created.value_counts().plot(kind='line', linewidth=1.2)
plt.xlabel('Date')
plt.title('New account created over time')
sns.despine()

Figure 25

plt.figure(figsize=(12,6))
df_without_NDF.timestamp_first_active.value_counts().plot(kind='line', linewidth=1.2)
plt.xlabel('Date')
plt.title('First active date over time')
sns.despine()

Figure 26

帐户创建日期和首次激活日期之间的模式看起来很相似,这是应该的。从这两个地块可以看出 Airbnb 在 2014 年到 2015 年的成长速度有多快。

df_2013 = df_without_NDF[df_without_NDF['timestamp_first_active'] > pd.to_datetime(20130101, format='%Y%m%d')]
df_2013 = df_2013[df_2013['timestamp_first_active'] < pd.to_datetime(20140101, format='%Y%m%d')]
plt.figure(figsize=(12,6))
df_2013.timestamp_first_active.value_counts().plot(kind='line', linewidth=2)
plt.xlabel('Date')
plt.title('First active date 2013')
sns.despine()

Figure 27

当进入 2013 年时,我们看到 Airbnb 预订者有几个高峰期,如 7 月、8 月和 10 月,而 12 月是 Airbnb 预订者最不活跃的月份。此外,它遵循相似的模式,例如相似距离处的峰值和非峰值。

用户会话探索

sessions = pd.read_csv('sessions.csv')print("There were", len(sessions.user_id.unique()), " unique user IDs in the session data.")

Figure 28

动作类型

动作类型有“难”和“未知”。所以我们将“未知”改为“南”。

sessions.action_type.replace('-unknown-', np.nan, inplace = True)
sessions.action_type.value_counts()

Figure 29

行动

sessions.action.value_counts().head(10)

Figure 30

行动细节

sessions.action_detail.value_counts().head(10)

Figure 31

设备类型

plt.figure(figsize=(18,6))
sns.countplot(x='device_type', data=sessions)
plt.xlabel('device type')
plt.ylabel('Number of sessions')
plt.title('device type distribution')
plt.xticks(rotation=90)
sns.despine()

Figure 32

这肯定了之前关于用户的发现。Airbnb 用户中最常见的设备类型是苹果产品。

已预订用户的会话

从前面的分析中,我们知道哪些用户通过 Airbnb 平台进行了预订,所以我们想探索这些 bookers 会话数据。和非预订者有区别吗?

Bookers 操作类型

booker_session = pd.merge(df_without_NDF, sessions, how = 'left', left_on = 'id', right_on = 'user_id')
booker_session.action_type.value_counts()

Figure 33

Bookers 热门活动

booker_session.action.value_counts().head(10)

Figure 34

不幸的是,预订者和所有用户之间的行为没有显著差异。

数据预处理和特征工程

train_users = pd.read_csv('train_users_2.csv')
test_users = pd.read_csv('test_users.csv')
df = pd.concat((train_users, test_users), axis=0, ignore_index=True)
df.drop('date_first_booking', axis=1, inplace=True)

日期时间特性

  • 将日期时间列转换为属性日期时间格式。
  • 将日期分为日、周、月、年。
  • 获取帐户创建日期和首次激活日期之间的差异(时滞)。
  • 最后,我们删除不再需要的列。

datetime_features

年龄特征

将年份转换为年龄,设置年龄限制,并用-1 填充 NaNs。

age_features

用户会话动作特征

有 10,567,737 个记录的会话,数据中有 135,483 个独立用户。

我们将按 user_id 分组,计算每个用户执行操作的次数、操作类型和操作细节。做groupby.agg(len)大概比groupby.size()快一倍。因此,我使用groupby.agg(len)。对于设备类型,我们按 user_id 分组,合计每个用户的总秒数。最后,我们为每个用户最常用的设备添加一个名为“最常用设备”的新列。

sessions_features

用户会话 secs_elapsed 特性

我们将从每个用户的 secs_elapsed 特征中提取信息,例如总和、平均值、最小值、最大值、中值、方差,如果 secs_elapsed 的总和大于 86,400 秒,我们考虑 day_pause,如果 secs_elapsed 的总和大于 300,000 秒,我们考虑它是长暂停,如果 secs_elapsed 的总和小于 3,600 秒,我们考虑它是短暂停。之后,我们将会话数据与用户数据合并。

以下脚本借用自 Kaggle

secs_elapsed

编码分类特征

categorical_features = ['gender', 'signup_method', 'signup_flow', 'language','affiliate_channel', 'affiliate_provider', 'first_affiliate_tracked', 'signup_app', 'first_device_type', 'first_browser', 'most_used_device', 'weekday_account_created', 'weekday_first_active']
df = pd.get_dummies(df, columns=categorical_features)

归一化贴现累计收益(NDCG)

NDCG 是折现累积收益(DCG) 度量的归一化。NDCG 是一个排名措施广泛使用的家庭实践。特别是,NDCG 在评估网络搜索方面非常受欢迎。

有几篇关于 NDCG 的优秀论文可以在这里这里找到。

我们的评估指标是 NDCG @k,其中 k=5。所以我们选择前 5 名,然后取平均值。

ndcg_score

使用 Xgboost 进行交叉验证

  • 我们将使用训练数据进行交叉验证
  • 我们将用-1 填充 NaN。
  • 我们如下设置通用参数、树助推器参数和学习任务参数,我们的评价指标是 mlogloss(多类 logloss)。关于如何设置 Xgboost 参数的详细指南可以在其官方网站上找到。

xgb_cv

Figure 35

从上面的脚本中,我们已经达到的最高平均测试 NDCG 分数是 0.827582。

Jupyter 笔记本可以在 Github 上找到。享受这周剩下的时光吧!

用分类和回归树预测 90 多种葡萄酒

原文:https://towardsdatascience.com/predicting-90-wines-with-classification-regression-trees-7a30b4577e4c?source=collection_archive---------4-----------------------

分类回归树(CART)是解决分类问题的灵活工具。它很受欢迎,因为它的适应性和性能很好,几乎不需要调整。我将使用 CART 从葡萄酒评论数据中预测 90+点的葡萄酒,并展示它的特点和陷阱。

我将使用的数据来自《葡萄酒爱好者》杂志,可以在 https://www.kaggle.com/zynicide/wine-reviews 免费获得。它包含了 150,000 种葡萄酒的分数,以及每瓶葡萄酒的价格、酒厂、产区、品种&等信息。对于这个项目,我将只使用美国种植的葡萄酒。

一个合理的假设是,价格较高的葡萄酒比价格较低的葡萄酒更容易获得 90+分。正如下面的 hexbin 图所示,有一些证据支持这一点——但更尖锐的是,有相当多的昂贵葡萄酒根本得不到很高的分数。

另一个假设可能是,某些地区可靠地种植 90 度以上的葡萄酒,而其他地区注定只能种植得分较低的葡萄酒。同样,数据显示了对此的一些支持——但在任何给定的地区,评分结果都有很大的差异。下面的小提琴图描绘了 30 个得分最高的地区的葡萄酒得分密度,每个地区都有 50 种或更多的葡萄酒。

单独使用这些标准中的任何一个,人们都可以开发出一套预测 90+葡萄酒的规则——但这样一个模型的准确性会很差。CART 模型允许跨许多不同特征的直观分类,并且易于在许多不同类型的数据(分类的、定量的)上实现。CART 模型识别将数据分割成越来越同质的组的方式,并且递归地执行这些分割,直到(a)不可能进一步分割或者(b)达到一些用户定义的终止标准。

为了说明这一点,让我们使用 sci-kit learn 的工具在葡萄酒评论数据上训练一个购物车模型:

我的购物车模型由 20,081 个不同的终端“叶子”组成,在这种情况下,每个叶子都由一个或多个来自训练数据的观察结果组成,这些观察结果不能再进一步分割,要么是因为它们是 100%同质的,要么是因为这些观察结果之间不存在特征差异。

上面,我们观察了 CART 模型的主要缺陷:它们很容易过度适应训练它们的数据。当我在一个 30%随机维持数据集(名为“test”)上测试我的 CART 模型时,分类准确率下降了 10%以上。

解决这一缺点的最佳方法是构建不超过必要大小的树。这个标准有点主观,但是本质上在模型复杂性(叶子的数量)和你正在寻找的过度拟合之间有一个平衡。本讨论的其余部分将直接解决这个问题。

CART 模型的一个有用特性是能够比较不同模型特性的“重要性”。这里重要的是每个特征对分类同质性的贡献。

在使用的四个特征中,每种葡萄酒的产地和葡萄酒品种的特征重要性最低。让我们再次运行该模型,这一次删除了这两个特征:

在这里,我们看到训练和测试数据的预测准确率都有所下降,但两者之间的差异也有所下降。这离我们最终要寻找的东西越来越近了:一个可以预测各种数据样本的模型。

除了移除对观察同质性贡献低的特征之外,解决过度拟合的第二个工具是修剪树枝。实际上,修剪是通过在训练模型时设置终止标准来完成的。终止标准可以设置在增长新分割之前所需的最小样本数上,或者设置在模型的最大深度上——起始节点下的子分割数。

对于我的 90+分葡萄酒分类器,我运行了数以千计的购物车模型,每一个我都在增长过程中更快地停止。下图说明了模型精度和我的终止标准(最大叶子数)之间的权衡。

当叶子的数量被限制在大约 7,500 时,CART 模型的准确性开始下降,并且在该点之上相对稳定。但有趣的是,当用于测试数据时,在大约 6000 片叶子以下,4 特征和 2 特征模型之间几乎没有区别。在 2,500 个最大叶子的情况下,仍然有接近 80%的测试样本准确率,并且 2 特征训练和测试样本准确率之间只有大约 5%的差异。

最终,购物车模型标准的选择将取决于手头任务的独特目标。如果对于 90+点的葡萄酒预测,80%是可接受的平均准确率,那么具有大约 2,500 片叶子的 2 特征 CART 模型将为我们提供一个模型,该模型将以合理的确定性在样本间表现一致。

[## dasotelo/Wine_Classify.py

github.com](https://github.com/dasotelo/Python_Projects/blob/master/Wine_classify.py)

预测波士顿(昂贵的)房地产市场

原文:https://towardsdatascience.com/predicting-bostons-expensive-property-market-bdcd9db6a218?source=collection_archive---------14-----------------------

Boston’s Back Bay Neighborhood

众所周知,波士顿是一个生活成本很高的城市。

(如果你需要令人信服的话,这个 238 平方英尺的工作室公寓卖了 40 万美元,这个停车位 待定 35 万美元。)

使用来自波士顿城市的公开可用的 2018 年房地产评估数据,我开始发现一些关于波士顿房地产的更有见地的发现,并使用机器学习来尝试和预测整个城市的房地产价值。

完整的 Python 项目代码和更详细的发现可以在这里找到

我们正在处理哪些数据?

与任何项目一样,第一次打开一个数据集会带来更多的问题而不是答案。有哪些最值得关注的数据点?可用的特征中,哪些与我们的发现实际相关?

幸运的是,数据附有一张有用的表格来解释每一个变量。我可以用它来删除大约 12 个我无法想象会在任何分析中使用的列。接下来,我只过滤了住宅物业代码,因为我想给项目一个更有针对性的重点。

生成的数据只有不到 140,000 行(观测值)和 60 多列(要素)。每个观察值代表一个单独的住宅物业,特征包括物业的特征,如位置(邮政编码、街道、单元号)、应纳税价值、平方英尺、建造/改造年份、状况等。

数据有什么有趣的地方?

波士顿是什么时候建成的?

知道了波士顿有许多历史建筑,我们可以从看看这些年来今天的城市是如何建造的开始:

波士顿大约一半的现有住宅建于 1925 年,在 1880-1930 年间有了显著的增长。

从下图中,我们可以看到这种分布在一些更受欢迎的社区中是如何变化的。到 1900 年,比肯山已有近 80%的建筑建成,而这个海港的住宅建筑几乎有一半是在 21 世纪初建成的。

波士顿房产价值

转移到房地产价值,正如所料,豪华市场主导着波士顿。约 60%的城市住宅物业总价值(约 113,057,142,300 美元)来自 20%的财产。

当然,在数据中还可以找到更多——在伴随代码的中也有更多——但是为了简洁起见,本文的其余部分将集中在该项目的机器学习方面。

预测波士顿房产价值

该项目的目标是创建一个预测波士顿房地产价值的模型。我之前只过滤了住宅物业的数据,对于预测,我进一步过滤了数据,只包括了公寓和总价值(约 300 万美元)的 98.5%的数据。

上述原因是:( 1)我需要在我的计算机上本地处理数据,因此多次使用 4 个模型的全部 100,000+文件是不可行的,所以我必须缩减数据;( 2)有少量大的异常值可能会影响预测,我需要一个可以概括大多数属性的模型。

型号选择

从表面上看,这是一个经典的回归问题:获取一系列输入,计算每个输入的相对影响(斜率),并预测一个连续变量。

事实上,在这个项目的过程中,我测试了 Python 的 sklearn 库中的 4 个回归模型——线性、随机森林、KNeighbors 和梯度推进。

每个型号是什么?

线性回归试图通过最小化均方误差产生一条最佳拟合的线。或者,换句话说,该线被构造成使得所有输入和预测线之间的距离最小化。

随机森林回归创建一系列单独预测属性值的决策树,然后对所有树的预测值进行平均,得到最终预测值。 KNeighbors 回归找到最接近的(即大小、卧室数量、邻居等。)“k”个数据点指向每个输入,然后对这些“k”(用户自定义)点的总数进行平均,作为预测值。

最后,梯度推进回归器是我最近学到的一个新模型,概念上我理解它,但是算法背后的数学需要更多的工作。该模型通过分析误差并根据误差移动不同点的权重(误差越大=下一次迭代中的重点越多),迭代地建立在每个连续的预测集上。

准备数据

机器学习和预测不仅对大量、多样和准确的数据是有效的,而且当数据在输入模型之前准备妥当时也是有效的。

我们的数据预处理将采取两个步骤。首先,我们要缩放连续变量。接下来,我们要对分类列进行编码和二进制化。

我们将使用的连续变量包括总平方英尺、卧室数量、公寓所在的楼层,以及自装修以来的年数(如果公寓从未装修,则为自建造以来的年数)。

平方英尺明显大于卧室的数量,但不一定更重要。为了抵消这种缩放偏差,我们将应用标准缩放器,使每一列的平均值为 0,标准差为 1。

对于分类变量,我们创建二进制(值为 1 或 0)列,当列值与新的二进制列匹配时,这些列被“激活”。例如,在左边的例子中,在我们的预处理步骤之前,5 个属性中的 4 个具有值“A ”,而另一个不包含这些值。

view_dummies = pd.get_dummies(predict_df.U_VIEW, prefix='View')view_df = pd.concat([predict_df, view_dummies], axis=1)

模型创建和测试

准备好数据后,建模过程分为 3 个步骤:

  1. 特征工程和模型测试
  2. 最终特征选择
  3. 模型调整

特征工程和模型测试:

我的模型构建过程从使用最基本的特性开始,然后测试添加附加特性的影响。我只从数据中的连续变量开始(在预处理中提到过),结果非常糟糕。均方根误差为 250,000 美元以上,而平均绝对误差为 150,000 美元以上(预测误差平均超过 150,000 美元)。

然而,有足够的机会用其他变量来改进模型。第一个增加是为房产所在的社区创建并包含虚拟变量,因为正如下面的箱线图所示,价值因位置而有显著变化。

事实上,包括邻居极大地改善了结果。例如,Random Forest 的 MAE 从大约 150,000 美元下降到大约 63,000 美元,降幅接近 60%。

我继续添加数据特征,如视图(特殊到差)和方向(后方、前方、通过等。)和测试模型,每一个都显示出递增的改进。

然后,我希望从数据本身开发额外的功能。例如,我创建了一个“奢华”变量(其思想是,在其他条件相同的情况下,奢华的房产可以卖更高的价格),将厨房或浴室风格的房产标记为奢华。我还创建了多项式特性来尝试捕捉连续变量和属性值之间的非线性和交互关系。

最后,我引入了邮政编码级别的外部数据。我找到了一个 Python 包,它接受邮政编码并返回平均收入、土地面积和人口密度等信息。

**import** **uszipcode**
**from** **uszipcode** **import** ZipcodeSearchEnginezips_list = []

**for** zipcode **in** zips:

    search = ZipcodeSearchEngine()
    zippy = search.by_zipcode(zipcode)
    zips_list.append(zippy)

A sample result for the above code

我还搜索并最终找到了邮政编码级别的人口统计数据,并将其合并到预测数据信息中,如该社区的种族构成(白人与少数族裔)和年龄细分(千禧一代与中年人和退休者),目的是找到其他相关变量。

虽然没有一个对添加像邻域这样的东西的大小产生影响,但我们确实看到了每种模型类型的误差度量(平均绝对误差,MAE)的总体下降趋势,没有一个较新模型的 KNeighbors 出现单个峰值。平均绝对误差从开始到结束的级数如下。

框中的值代表最终模型在每条虚线之前的 MAE,最左边的框是只有连续变量的第一个模型的 MAE:

功能选择

虽然创建和添加要素有助于了解不同要素如何影响我们的模型,但我们的最终结果不一定是最佳输入集。我们可能有多重共线性需要在我们的要素中解决(要素之间的相关性),而其他可能对我们的预测没有帮助。

有几种不同的方法来处理特性选择,我尝试了两种不同的方法。首先是主成分分析 (PCA),它基于特征的解释方差来减少维数。这一过程分为两步:用未定义数量的成分拟合 PCA,分析解释的方差,然后用最少数量的成分重新拟合,以获得最大的方差。

pca = PCA()
pca.fit(poly_df_s, predict_df.AV_TOTAL)

我们看到几乎 100%的差异是由大约一半的特征解释的。然后,我们可以对 PCA 和 40 个特征使用维数减少,目标是实现与所有特征相似的结果。

fitted_pca = pd.DataFrame(PCA(n_components=40).fit_transform(poly_df_s, predict_df.AV_TOTAL))

对具有 40 个分量的 PCA 转换数据运行模型,对于梯度增强算法产生了类似的结果-证明我们大约一半的特征对于该模型是无关紧要的-而 KNeighbors 和 Random Forest 的性能略有下降。

第二种方法使用 SelectKBest 函数搜索要使用的最佳特性。我针对从 20 到最大列数的 5 个 k 值测试了模型,结果是 60 产生了最好的结果。

# select_k_best_model_test is a function defined earlier in the code # that fits a SelectKBest model, tests the models on that data, and # returns both the results of the test (MAE, RMSE, score) plus a    # data frame of the condensed columnsk_to_test = [20, 30, 40, 60, 84]

**for** i **in** k_to_test:

    result, df = select_k_best_model_test(i)

    print('The results for the best **%i** features' %i)
    print(result)
    print('**\n**')

在用 60 列拟合 SelectKBest 模型之后,我试图通过删除相关列(我认为是那些相关性高于 0.8 的列)来抵消多重共线性问题。

corr_matrix = best_k.corr().abs()

*## Select upper triangle of correlation matrix*

upper = corr_matrix.where(np.triu(np.ones(corr_matrix.shape), k=1).astype(np.bool))

*## Find index of feature columns with correlation greater than 0.8*

to_drop = [column **for** column **in** upper.columns **if** any(upper[column] > 0.8)]*## Drop columns with a correlation about 0.8* best_k_consolidated = best_k.drop(to_drop, axis=1)

最终结果是一个有 37 列的模型——比我们最初的 84 列减少了很多——的表现和其他任何模型一样好,甚至更好。 其余栏目包括居住面积的抽样(sq。脚)、基础楼层(即一楼、二楼等。)、看法(一般、优秀等。)、多个邻域虚拟变量等;大约三分之一的最终列是我们的特征工程和/或引入其他外部数据的结果。

模型调整

在经历了变量创建和从这些变量中选择特征之后,是时候看看我们是否可以通过调整超参数来改进开箱即用的模型了。

我根据模型使用了 GridSearchCVRandomizedSearchCV 的组合来搜索最佳结果的参数。这些函数要么搜索参数输入的每个组合(GridSearch),要么搜索一定数量的随机选择的输入(RandomizedSearch)。

params_grid_gbr = {'loss':['ls','lad','huber'], 'learning_rate':np.arange(0.02, 0.4, 0.03), 
                   'n_estimators':np.arange(100, 500, 50), 'min_samples_split': np.arange(2, 50, 5), 
                   'max_depth':np.arange(3, 15, 3)}

gbr = GradientBoostingRegressor(random_state=66)

gbr_grid = RandomizedSearchCV(gbr, params_grid_gbr, n_iter=10, cv=5, scoring='neg_mean_absolute_error',)gbr_grid.fit(tr_x, tr_y)

运行这些算法的结果是,对于每个被调整的模型,基于被测试的输入的一组最佳参数。这里需要注意的是,最优参数是我们测试的参数的函数,因此实际上它们可以被认为是局部最优而不是全局最优(即,如果我们要测试每一个可能的参数组合)。

梯度推进回归器从调优中获得了最大的改善,MAE 从大约 80,000 美元下降到大约 55,900 美元,改善了大约 30%!其他的,比如 Random Forest,没有看到任何有意义的调整,而由 MAE 测量的 KNeighbors 的性能下降了 6%多一点。

胜负

完成以上所有工作后,是时候看看我们的工作成果了。我们将从查看一些指标开始,然后是我们的一个模型的错误的说明性可视化表示。

根据一个简单的“基线”模型,该模型预测房地产价值是所有房地产的平均值,我们的最佳预测将 MAE 从 290,000 美元减少到 53,600 美元。从第一个连续变量模型到调整后的模型,最小 MAE 从大约 150,000 美元下降到 53,600 美元,降幅为 64%,R2 从 0.5-.68 的范围提高到 0.8–0.95。

Untuned first model scoring

Untuned final model scoring

最终调整后的模型的平均绝对误差值为:

  • 兰登森林:53699 美元
  • 邻居:63230 美元
  • 梯度推进:55906 美元

总的来说,我们的模型与实际的财产价值相差约 10%。我们的预测绝非完美,但也大致如此。我很想知道其他人可以在我进行的过程之上做出的改进,或者超出我当前技能的更复杂的模型的结果会是什么。

我将提供的最后一个视觉效果是检查我们的一个模型的错误,并寻找是否有任何模型无法捕捉的系统偏差(例如,通过属性值、邻域、一致的过/欠预测)。下图显示了随机森林模型的绝对误差,按邻域着色,气泡大小是误差的大小(因此中间 45 度线上的空白区域-小误差=小气泡)。

事实上,我们没有看到任何明确的数据误差模式。我们看到的最大错误分组是,模型预测的价值在大约 100 万美元到大约 100 万美元 2M 之间,而实际价值不到 100 万美元。我很想知道是什么属性“愚弄”了模型,以至于预测如此之远。

结论:我们学到了什么?

这些项目的目标不仅是能够分享有趣的结果,而且是发展更好的数据技能。考虑到这一点,我从这个项目中得到的一些最大的收获如下:

  • 预测房产难!我确信,第一个包含平方英尺和卧室等变量的线性模型至少会产生一个令人尊敬的预测,但它还远远不够,而且随着时间的推移,增加变量的大量努力提供了递减的回报。
  • 不同回归模型的性能存在显著差异,并且测试多个模型很重要。如果使用我们的最终特征,简单的线性模型不会比大约 130,000 美元的平均误差做得更好,但是通过其他回归模型,我们能够将平均误差降低近 60%。
  • 最大的收益来自功能工程,这还远远不够。虽然超参数调整从选择的特征中提取了最后的预测能力(特别是对于梯度增强),但它是在从更好的特征中显著减少的基础上增加的。
  • 特征工程超越了缩放或测试样品内特征。大约 30%的最终特征是根据现有数据(即添加奢侈品标签或多项式特征)或外部数据(邮政编码级别的人口统计数据、收入)创建的。数据集变量之外的特征工程降低了我们的误差幅度,从约 6%(近邻)到约 30%(梯度增强)
  • 最后… 功能选择具有挑战性!我在该项目的大部分时间都在试图了解不同的特征选择标准,以便在不过度拟合模型的情况下获得最大的预测能力。我以为会有一种简单的方法来插入特性和目标——瞧!—完美的特征依然存在。相反,我循环使用了几种不同的方法,在这个过程中加深了我的学习。

该模型并不完美,但至少它是一个案例,说明了添加额外特征(样本内外)的价值以及特征选择的重要性。 我们的模型对于右边的 37 列和所有的 84 个 一样强大。

所以,是的,波士顿的房地产很贵,预测它是一个挑战,但最终我觉得对我的城市和我的数据技能都更了解了。

我欢迎任何人对代码、功能或想法的反馈。请随时到 jordan@jordanbean.com 找我。

用人工智能预测大学录取

原文:https://towardsdatascience.com/predicting-college-acceptance-with-ai-6d8abd702385?source=collection_archive---------2-----------------------

大约在去年的这个时候,我正忙着敲击键盘,向世界各地的大学申请。当我填写面前看似无穷无尽的申请表时,我突然意识到这完全是低效和冒险的。

每年有超过 200 万份大学申请被提交,每一份都带有一定的偶然性。即使是学术水平最高的学生申请也带有一定的随意性,结果往往会面临困境——大学录取中固有的精英制度让位于不确定性、怀疑和焦虑。

当然,许多因素影响录取,但众所周知,有两个因素在决定录取时举足轻重:GPA 和 SAT/ACT 分数。虽然其他因素肯定会被考虑在内,但不可否认的是,这两个指标对学生的申请有着不可思议的重要性——尽管没有人真正知道大学是如何判断和筛选这些指标的。

但是说到底,这两个指标是指标:可以使用数据科学分析趋势和关系来轻松评估的数字。因此,尽管我非常不耐烦和焦虑,我还是决定尝试预测大学录取情况,而不是等待决定出台。虽然有成千上万种统计方法来分析 GPA/考试成绩和申请结果之间的趋势,但我选择了一种最近流行的预测方法:机器学习。

机器学习是一个广泛的领域,有许多解决方案和应用,但我特别专注于人工神经网络。鉴于我的输入完全是数字,我的输出可以一次性编码成二进制值(0 表示拒绝,1 表示接受),人工神经网络工作得相当好。

Tensorflow 中实现了一个架构之后,我在专门为卡内基梅隆大学收集的数据集上训练了我的网络(这只是一个例子,大约有 90 个数据点)。经过大约 150,000 次迭代(在 GeForce 1060 GPU 上大约 1 分钟),我能够达到介于**75–80%**之间的精确度。虽然这可能看起来不太准确,但它足以得出一些结论,并且肯定比任意的线性模型更好。

Decreasing Loss over 150,000 steps (faded blue line is cross validation, no overfitting + room for more training)

从命令行中,我能够收集到一些相当不错的预测大学录取的结果:

Using a randomly high GPA and high SAT.

(美丽的日志由来源构建的[console-logging](https://github.com/pshah123/console-logging)提供)

为了便于使用,我用 Bootstrap 3 设计了一个简单的 GUI:

总而言之,它不仅在平息我的焦虑方面,而且在过滤我的申请以限制我可能进入的学校方面,证明是有点用的。具有讽刺意味的是,它甚至预言了我被卡内基梅隆大学拒绝!

该项目的完整来源可在 Github 在这个回购。

[## pshah123/ChanceyNN

利用人工智能预测大学申请结果

github.com](https://github.com/pshah123/ChanceyNN)

像这样,还有更多?在 Aiko AI ,我们热爱开源项目以及探索和可视化数据!

预测新西兰道路交通事故的严重程度

原文:https://towardsdatascience.com/predicting-crash-severity-for-nz-road-accidents-6214117e73fb?source=collection_archive---------27-----------------------

从技术和业务角度对机器学习项目进行端到端的工作——顶点项目回顾

P values for the Chi2 Test of independence of every (categorical) feature pair in the dataset.

最近看完了 Udacity 的机器学习 Nanodegree。这是一次伟大的经历,以著名的顶点项目而告终,在这篇文章中,我想分享我的经历。

TL;博士:

理解数据及其上下文比选择和调整超参数的算法更重要。这就是 EDA 至关重要的原因。另外,它也是一个很好的第一轮功能选择。

降维并不总是产生有用的结果。

过采样技术通常是克服目标变量类别不平衡的好策略。

有一个基准来比较性能是很重要的。如果这是不可能的,那么理解问题的背景和领域就变得更加重要。

最终,成功应该总是在业务目标、可用时间和追求任何特定想法或分析的成本的背景下定义。

首先,简单介绍一下我是谁

这些年来,我一直是各种类型的软件开发人员。我创建了数据密集型的内部网系统,并开发了使用相同数据的网络应用程序。我做过业务、功能和技术分析师;理解并确定这些应用和系统应该做什么以及应该如何做。我一直是企业数字化转型的顾问,这些企业希望通过自动化将数据货币化并简化运营。

目前,我是一名*产品经理和投资组合专员;*创造新产品和服务,将我公司的数据货币化,并利用这些服务推动我们客户各自的业务;也是我们自己的。

我有一个未完成的纯数学学位——这是我最大的爱好,其次是技术。

最后,我未来五年的目标是参与可再生能源、可持续发展和智能城市。我确信这些主题——以及区块链和物联网(IIoT)——将在很大程度上驱动和定义我们未来几十年将生活的社会和世界。

关于车祸

车祸和交通事故可能被认为是一个老话题。然而,随着汽车的进步和它们所承载的技术能力,更重要的是要有工具和手段来减少它们的发生,以及它们对所涉及的人的影响和后果。但是预测车祸的严重程度并不容易。即使在可能的情况下,精度水平也会有很大差异,这取决于许多因素,包括可用的数据和问题建模的好坏。

数据集

在为我的顶点项目寻找有意义的数据集时,我偶然发现了data . govt . NZ由中央政府发布的与新西兰各种活动相关的开放数据集的存储库。所选的数据集直接来自于新西兰运输署。它包含从 2000 年 1 月 1 日至今的车祸数据,并且每季度自动更新一次。数据集附带一个 pdf 文件,其中包含每个可用要素的清晰定义。

项目大纲

本文的大部分内容摘自该项目的最终报告。该报告连同所有笔记本、代码和数据都可以在我的 GitHub 个人资料这里找到。此外,还有一个 Tableau 工作簿,我在其中构建了大部分初始 EDA 可视化,我在整个项目以及报告中都使用了它。该工作簿可在我的 Tableau 公共档案这里获得。

我们的目标是预测车祸的严重程度。在数据集中,目标变量称为 crashSeverity ,取四个不同的值: N 表示无伤害M 表示轻微S 表示严重,以及 F 表示致命

为了实现我们的目标,我们将经历以下步骤:

功能探索(带数据清理)

降维

模型构建(包括基准和基线模型)

优化和最终型号选择

考虑到我们的问题是一个多类分类问题,我们将使用 F1 分数来评估我们将训练的不同模型的性能。对于每个模型,全局得分的值将依次是每个类别的 F1 得分的平均值。因此,我们将使用一对一对全部的方法。不过,我们也会仔细看看精度精度召回;因为它们都为理解模型如何运行提供了有价值的见解。

最后,我们将解释并详细说明进一步提高所选模型的整体性能和可解释性的一些可能的后续步骤。

功能探索(又名 EDA)

数据集最初总共有 655,697 个样本。每个都有 89 个不同的特征,既有数字的也有分类的。

简单地从上面提到的 pdf 中读取每个特性的定义,我们可以看到有一些特性的值是从其他特性中派生出来的。这些衍生的特征并没有给数据集增加内在价值,因为它们被用于,例如,以一种更简洁的方式总结车祸的特征,正如 pdf 所描述的,用于管理目的。因此,我们将移除它们以防止不必要的特征相关性。这同时将有助于将数据集的大小保持在最小,这将有助于模型的训练时间。

另一方面,有一些特性的值是在崩溃被报告和处理后根据其严重性提供的。具体来说,minorinjuricount、 *seriousInjuryCount、*和 fatalCount (不言自明)就是这样提供的。因此,它们会将数据泄漏到我们的目标变量中,我们必须移除它们。此外,这些功能在首次报告事故时不可用——这是我们的模型进行实时预测的时候——紧急机构需要尽快做出适当的反应。

除了这些特殊的特征,其余的大部分都是绝对的。表明撞车时的状况不同。像 weatherAweatherB,都用来表示天气的两个不同方面。或光、道路曲率、交通控制车道数,用于描述不同的自然光条件、道路曲率水平、是否有交通信号以及道路有哪些车道和车道数;分别是。

最后,大多数数字特征代表指示碰撞中涉及的物体数量的计数器。

在理解了每个特性代表什么之后,我们需要探究它们各自的值,以理解它们的分布,以及它们的定义是否有任何不一致之处。

top left: distribution of crashes by region; top right: distribution by crash type (multiVehicle); bottom left: distribution by road curvature: bottom right: distribution by junction type

对于每个特性,我们需要考虑值不一致和/或缺失的情况。这导致要么输入缺失值,要么丢弃特定样本,甚至完全丢弃某个特性——详细信息可在 GitHub 上的 EDA 笔记本中找到。在对每个分类和数字特征做了这些之后,我们最终放弃了 22 个与我们的问题无关的特征;或者由于太多缺失/不一致的值,并且没有明确的方法来估算它们。此外,我们还丢弃了一些样本,这些样本的某些特性的值不一致,而这些特性的行为与预期的不同。

无论如何,我们从这一步中学到的最重要的事情是,对于我们的目标变量来说存在着巨大的类别不平衡:

假定非伤害性碰撞是最常见的,并且随着碰撞严重性的增加,做出良好预测的重要性也增加;我们需要解决这个问题,如果我们希望产生一个良好的运作模式。为此,我们将求助于欠采样和过采样技术,这将在模型构建一节中介绍。

除了这一点,数据集没有呈现任何特定的趋势或模式,让我们能够直观地了解哪些特征最具预测能力。

Distribution for eight different feature. All of them behave similarly, where the only similarity they share is how they behave with regard to the target variable.

既然我们已经单独研究了每个特性,我们需要检查一对特性之间可能的相关性。由于大多数特征是绝对的,我们将通过 Chi2 独立性检验来实现。我们采用 p 值来测试每一对特征,并考虑 0.05 阈值的 假设的独立性。结果汇总在下图中,其中红色表示给定特征对之间的相关性,绿色表示独立性:

我们可以看到,每个功能都依赖于几乎所有其他功能。使得由于相关性而几乎不可能移除它们中的任何一个,因为它们都携带有价值的信息。

因此,我们决定保留所有剩余的功能。

主成分分析降维

在完成初始探索之后,我们可以尝试通过应用 PCA 来获得新的特征,以原始特征的线性组合的形式揭示可能的潜在特征,这些潜在特征可能证明是比原始特征更好(和更简单)的预测器。

然而,在用 10 个主成分应用 PCA 之后,我们得到了一个在类之间不可分的数据集。以下是前两个 PC 的每个碰撞严重度的分布情况,这两个 PC 占数据可变性的 97%以上:

如您所见,这四个类的分布非常相似。此外,这些课程相互重叠。以至于在一个图表中包含这四个类,除了几个清晰的点之外,您无法区分它们。

此外,即使在对数据进行最小最大缩放后,结果甚至更糟:

这在某种程度上是可以理解的;考虑到具有许多分类特征的数据集的维数减少往往比具有更多数值特征的数据集更棘手。

这在一定程度上是因为我们已经通过一个热编码过程运行了数据集。这将原始样本矩阵变成了本质上稀疏的另一个样本矩阵。不仅如此,这个稀疏矩阵大部分是二进制的(除了计数器和很少的连续特征);这意味着不是 0 的条目或单元格实际上是 1 。所有这些细节不仅影响应用 PCA 的结果,而且影响分类器本身的开发和实现。例如,如果我们要选择一种依赖于使用某种距离定义的算法,比如 L1(闵可夫斯基)、L2(欧几里得)或 L 无穷(切比雪夫或曼哈顿),我们可能会面临一些问题。

模型结构

正如我们刚刚提到的,数据集中的大多数要素都是分类的。同样,也不清楚哪些是最有意义的或者与分类任务相关的。因此,我们将关注决策树作为基础(和弱)学习器,并训练两个集成模型;一个用于装袋,一个用于增压。具体来说,我们将训练和优化随机森林和 AdaBoost GBM。这将为我们提供两种模型,能够处理刚才提到的两个棘手问题。

对于多类分类问题,这两种算法是很好的选择。然而,随机森林对类别不平衡是敏感的,而 AdaBoost 对噪声和异常值是敏感的。所有这些特殊性都很重要,我们将通过对数据集的三种变化训练这两个模型来解决它们:原始(完整)数据集、欠采样变化和过采样变化。对于目标变量中的每个类,欠采样和过采样变化将具有相同数量的样本。如何获得这些变化的详细信息可在 GitHub repo 的最终报告和笔记本中找到。

标杆管理

为了评估训练模型的性能,我们将使用两个参考值。第一个是专门为我们的问题训练的人工神经网络的性能。Sharaf alk heder 2016 年发表的这篇论文提供了详细信息;马德哈尔·塔姆奈和萨拉赫·塔姆奈:

利用人工神经网络预测交通事故的严重程度

论文摘要描述了一个最终的人工神经网络,其测试精度为 74.6%。

第二个参考将是一个基本的朴素贝叶斯分类器,用作我们集合模型的基线。作为参考,我们将使用所有班级的平均 F1 分数以及班级级别的得分值

基线-朴素贝叶斯分类器

在对每个变化训练 NB 分类器之后,我们得到将用于评估集合模型的以下性能值:

Averaged scores across classes

Class level scores

现在,对于所选的两种算法(RF 和 AdaBoost)。我们遵循了相同的流程:

  1. 以 75/25 的训练/测试比率分割数据集。
  2. 为数据集的每个变体训练一个基线模型(使用默认参数值)。这一步骤的结果是原始变化的一个训练模型;一个用于欠采样变异;一个用于过采样变化。
  3. 分析基线模型的性能指标,并选择性能最佳的模型和变体。在这一步中,我们考虑了准确性;所有目标类别的平均精确度、召回率和 F1 分数;和类级别的相同指标。这样做是因为,虽然我们想获得一个很高的 F1 分数,但我们处于一个多职业的环境中,因此,我们希望分数能代表所有职业。此外,考虑到阶级分布的不均衡性,这变得更加重要。
  4. 使用从最佳性能基线模型的特征导出的参数网格,使用最佳性能变化执行网格搜索。该步骤的结果是基于来自 3 重交叉验证的平均 F1 分数的最佳估计值。

随机森林

基线模型

首先,我们给出基线模型的结果,即所有默认参数。当然,分数对应于每个变体的测试集。

射频基线的准确度和平均 F1 分如下:

Performance of RF baseline model on all variations of the dataset.

Class level scores

正如我们所看到的,最佳精度是在原始变量紧跟过采样变量的情况下获得的。然而,最好的 F1 分数是通过过采样变化获得的。

此外,通过查看类级别的性能指标,我们清楚地看到原始变体的平均 F1 分数主要是由于类 *N、*的分数,而其他类的分数要低得多。另一方面,过采样变化的 F1 分数是由类级别的 F1 分数生成的,这些 F1 分数彼此之间更加平衡。因此,过采样变异的 F1 分数 0.6879 更能代表类级别的情况。

此外,对于过采样变异中的每个类别,F1 分数证明是精确度和召回率之间的非常好的平衡。所有这些细节使得过采样变化成为执行网格搜索的最佳候选。

网格搜索

接下来,我们呈现对参数最大深度n 估计量最小样本分割做网格的结果;以及它们相应的 F1 分数。在这里,分数是三重交叉验证过程的平均值。

得到的最佳估计器是用参数 *max_depth=70、*n _ estimates = 200 和 min_samples_split=2 训练的估计器。

作为一个额外的见解,有趣的是注意到,对于每个被考虑的 n_estimatormax_depth ,最高分是针对 min_samples_split=2 的。通过观察 viz 上的彩色条纹,这一点变得很明显。有人可能会说,如果我们只考虑这三个参数,那么提高性能的最佳方式就是在森林中增加更多的树。

此外,当我们使用最佳估计量对测试集进行预测时,我们得到的准确度为 0.7227,F1 值为 0.7231。其高于它们相应的训练值。

ADA 增强

同样,首先,我们呈现基线模型的结果。

Averaged scores

Class level scores

在这种情况下,最佳准确度和平均 F1 分数都是用原始变异获得的。然而,与 RF 一样,这主要是由类别 N 的分数驱动的。由于我们希望有一个平均代表每个类的分数,所以我们不能选择这个变量。相反,我们将选择过采样变化,虽然其值低得多,但其跨类行为与 RF 非常相似。

网格搜索

对于该算法,我们给出了具有参数 n_estimatorslearning_rate 的网格搜索的结果。

在这种情况下,有趣的部分来自于注意到对于每一个 n_estimators 的值,最好的测试分数是以 1 的学习率获得的。这在某种程度上是有道理的。算法本身已经为正确和错误分类的样本分配了权重,以便训练下一个树桩,从而改善前一个树桩的错误分类。

对于这个最佳估计量,测试集上的准确度是 0.6089,平均 F1 分数是 0.6058。

随机森林和 AdaBoost 比较

最后,在通过网格搜索优化每个模型之后,我们可以在它们之间以及与基准进行比较。

由于我们已经使用过采样变化训练了这两种算法,以克服类的不平衡,因此我们仅给出该变化的性能指标:

对于这两个指标,执行网格搜索后,性能最好的模型是随机森林。在某种程度上,这是意料之中的。至少事实上,在这种情况下,通过网格搜索,最佳执行模型将是一个优化的模型。

但也许最有趣的是两种算法的不同方法。

虽然 AdaBoost 在每一步都试图改善由基于单个特征进行预测的前一个树桩的集合所产生的错误分类,但随机森林是一种确定性方法,它通过找到在分割后产生最大杂质减少的分割来生长树。

通过这样做,随机森林开发出非常精确但过度拟合的树。然而,通过添加许多树,每个树都有一个样本包,并在每次分割时引导特征,它克服了单个树的过度拟合,创建了一个非常强大的模型。

总体准确度分数仅为 0.72 这一事实表明,可用数据缺乏可预测的能力来使这一指标超过我们为参考人工神经网络选择的 74.6%准确度的第一个基准。

Tableau 工作手册有几个例子来支持这个结论。具体来说,随着网格搜索的进行,性能的增加逐渐减少(边际);这表明利用现有数据,搜索和模型只能完成这么多。

结论和可能的改进

RF 只能产生 0.72 的准确度和 0.72 的 F1 分数。虽然 F1 分数在各个类别之间是平衡的——这意味着每个类别的 F1 分数与平均分数具有相似的值——但整体性能低于我们在项目开始时选择的人工神经网络基准。这使得我们的模型相关,但几乎不可用。

尽管如此,仍有很大的改进余地。例如,考虑到数据集的形状和形式,其他一些被证明有用的算法有 SVM、XGBoost 和 LGMB。这些也可以合并,包括随机森林。

我们还可以为每个类训练一个二进制分类器,以便有一个更加定制的一对一方法。还可以尝试其他评估方法,如 AUC/ROC 和 Precision/Recall 曲线。在这种情况下,我们可以为最终的分类器实现一个表决器。我们还可以对每一类的预测概率进行更深入的分析。有助于更好地理解每个类别最具代表性的特征。

与此同时,我们可以通过其他维度缩减技术和无监督学习算法来探索特征选择/工程的途径,这些技术和算法可以帮助发现数据中的隐藏结构。

对于数据集的不平衡性质,一些成本敏感性算法可能非常有用。

最后但同样重要的是,我们可以尝试其他具有其他优点和缺点的库。例如 H2O,它可以处理分类特征,并用于并行计算,这将有助于模型的总训练时间。允许更长的训练时间和更彻底的网格搜索。

总而言之,如果在这一点上不明显,每个机器学习项目的指导北应该是所谓的商业案例;虽然它显然不属于商业范畴,但这个想法仍然成立。业务案例对什么是有意义的,什么是没有意义的有最终决定权:对 2%的性能提升是否值得在截止日期后额外花费 10%的时间和 5%的额外成本,这两者对组织的其他领域和团队来说可能都是合理的。

最终,没有完美的解决方案,只有对预期目的足够好的解决方案。然而,随着研究结果被证明越来越有用,并提供了一个关于如何改进自己的反馈回路,这一目的可以——在许多情况下也应该——变得越来越复杂。

用 Python 预测登革热:看天气

原文:https://towardsdatascience.com/predicting-dengue-fever-with-python-look-at-the-weather-8945b615301f?source=collection_archive---------6-----------------------

步骤 Pandas、matplotlib 和 Python 中的特性探索

驱动数据公司目前正在举办一场竞赛,预测秘鲁伊基托斯和波多黎各圣胡安的登革热病例。我在我之前的职位中探究了每周的案件量。在这篇文章中,我将探讨竞争对手提供的特性。

功能

天气天气天气。所有提供的预测病例数的变量都是基于天气。这 20 项功能分为:

  • 温度
  • 湿度
  • 降雨
  • 植被水平

我的第一步,总是,是看哪些特征彼此相关,哪些特征与目标相关。Seaborn 的热图功能有助于可视化这些相关性。在这种情况下,我对所有相关值进行平方,因为我不关心正相关或负相关,只关心相关的强度。越接近 1,相关性越强。

Correlation Heatmap for Iquitos (left) and San Juan (right)

圣胡安和伊基托斯具有不同的要素关系集。NDVI 水平在伊基托斯高度相关,但在圣胡安不太相关。圣胡安的温度特征会一起移动,但伊基托斯不会。这再次表明每个城市需要不同的模式。

温度、降雨量和湿度

蚊子需要水和合适的温度才能茁壮成长。我的假设是:更多的雨和热=更多的蚊子。下面的图表解释了这些特征平均来说是如何随时间变化的。

我将所有的天气特征标准化,使它们保持在相同的尺度上。例如,在波多黎各的圣胡安,大多数特征都在 0 左右。这意味着它们接近整个数据集的平均温度。值为 1 或-1 表示变量高于或低于平均值 1 个标准偏差。像这样标准化可以让我们比较不同尺度上变量的变化(温度变化 1 度和降雨量增加 1 英寸具有完全不同的意义)。

绘制所有特征的目的是看它们是否一起移动。看precipitation_amt_mm是否每周都在变化并不重要,重要的是看它是否与其他特征同步变化。

圣胡安的天气变化比秘鲁的伊基托斯更为紧密。特征之间的变化,尤其是在基于时间的分析中,对于具有更大的预测能力是重要的。但这也可能导致更多的噪音。

归一化差异植被指数

美国国家海洋和大气管理局(NOAA)拍摄各个城市的卫星图像,并确定该地区的有机增长数量。该级别被归一化为归一化差异植被(NDVI),并提供给每个城市的四个象限。关于 NDVI 是如何计算的更多信息,请点击这里。

Normalized Difference Vegetation Index for Iquitos, Peru (left) and San Juan, Puerto Rico (right)

第一,这个数据是有噪音的。每张图片的上半部分显示了每周的观察结果。取一年中每周的平均值,我们可以得出圣胡安和伊基托斯植被水平的年度趋势。随着时间的推移,伊基托斯的趋势比圣胡安强得多。此外,所有四个象限在伊基托斯总是几乎相同。圣胡安南部象限的 NDVI 分数几乎总是低于北部象限。

结论

建模将向我们展示哪些特征以及特征的哪些组合将是病例数量的良好预测器。然而,重要的是要记住,并不是当前的天气决定了蚊子的数量,从而决定了登革热病例的数量。之前的几周和几个月为蚊子的繁殖提供了潜伏期。

下一篇文章将探讨如何确定月趋势(不考虑天气特征)。之后,我将描述使用历史天气预测当前登革热病例数量的方法。

密码

我的 GitHub repo here 上有 Jupyter 笔记本,上面有我的可视化 python 代码。请随意阅读我未来的帖子。

利用季节性 ARIMAX 模型和气象数据预测登革热传播

原文:https://towardsdatascience.com/predicting-dengue-spread-using-seasonal-arimax-model-on-meteorology-data-3f35979ec5d?source=collection_archive---------6-----------------------

在过去的几十年中,登革热病毒已经在世界的亚热带地区传播,严重形式的登革热的数量增加,例如严重出血、低血压,甚至死亡。由于疾病由蚊子传播,登革热的传播与温度和降水等气象变量有关。在这篇博文中,我将回顾一下我是如何应对邓艾竞赛的论文和代码可以在我的 github 上找到!

这是游戏计划:

  1. 数据分割
  2. 描述性分析和数据可视化
  3. 处理缺失值
  4. 模型诊断
  5. 模型形成
  6. 预测

数据分割

邓艾竞赛数据集本质上是一个杂乱的数据集,包含两个不同的城市和两个不同的时间框架。我根据两个城市将数据集分成两个小数据集:圣胡安和伊基托斯。从两个数据集中,我将每个数据集分为训练集和验证集,以便在选择最佳模型在最终测试集上执行之前测试不同的模型。

Figure 1: Data Split

描述性分析和数据可视化

圣胡安和伊基托斯的数据处理非常相似,所以我在这一节只展示圣胡安的图表。伊基托斯的图表将在我的论文中提供。

每个数据集包含 25 个变量,包括气象和地理变量。在此查看每个变量的详细信息。

Figure 2: Descriptive Analysis of San Juan

相关图将有助于诊断两个变量之间是否存在任何线性关系。我们可以看到,这些变量中没有一个与总病例数**(图 3)** 高度相关。然而,如果我们包括 2 个以上的变量并运行多元线性回归,每个预测因子的大小可能会改变。

Figure 3: Correlation Plot of San Juan

Figure 4: Time Series Plot of Total Cases of San Juan

Figure 5: Scatter Plots of Total Cases and Climate Variables of San Juan

时间序列图表明数据中可能存在季节性,因为每年夏季前后总病例数达到高峰。两个散点图也表明了总病例数和两个气候变量之间可能的线性关系。(温度和湿度)

Figure 6: Time Series Plot of Total Cases and Climate Variables of San Juan

查看总例数和温度以及总例数和湿度的双时间序列图,我们可以看到有时例数和气候值一起上下移动;有时天气变量首先达到峰值或直线下降,然后总病例数在 3 -4 周后上下波动。更有趣的是,登革热症状通常在被受感染的蚊子叮咬后 4 至 7 天开始出现。蚊子在 70 华氏度时可能需要 14 天完成其生命周期,而在 80 华氏度时只需要 10 天。因此,在温度、降雨量或湿度上下波动后,平均需要 3-4 周才能报告病例。

描述性分析和数据可视化提出了一个具有额外预测变量的时间序列模型,并且可能有一些预测变量的先前滞后。

处理缺失值

我通过使用 R 中的最后一次观察结转方法来处理缺失数据,这基本上是用之前最近的非 NA 替换每个 NA。这里我假设本周的天气与上周的天气不会有太大的不同。

*# build a function to impute data with the most recent that is non missing*
  na.locf.data.frame <- 
    **function**(object, **...**) replace(object, TRUE, lapply(object, na.locf, **...**))

  *#fill in NAs - SJ*
  sjdata.train.imputed <- na.locf.data.frame(sjdata.train)

  *#fill in NAs - IQ*
  iqdata.train.imputed <- na.locf.data.frame(iqdata.train)

模型诊断

一个增强的 Dickey-Fuller 检验表明时间序列数据集是平稳的。该数据集具有复杂的季节性,每周数据点(频率= 52.18)。ETS、分解等方法大多要求季节周期为整数。即使我们把它四舍五入到 52,大多数方法也不会有效地处理这么大的季节周期。一种可能的方法是通过在 ARIMA 模型中包括傅立叶项来使用动态谐波回归模型。

Figure 7: ACF and PACF Plots of Total Cases of San Juan Time Series

接下来,为了挑选 MA 和 AR 术语,我首先检查了早期滞后(1,2,3,…)来判断非季节性术语。在低滞后时,ACF 中的这些峰值表示非季节性 MA 术语。此外,PACF 在低滞后时的峰值表明可能存在非季节性 AR 项。

模型形成

通过经验审查和数据诊断,我决定尝试 3 种模型:SARIMA、SARIMAX 和神经网络。我从一个只有全部病例的基本而简单的季节性 ARIMA 开始,然后我在模型中添加了更多的预测因子,如温度、湿度、降雨量。最后,我用 r 中的 NNETAR 包建立了神经网络模型(多层前馈网络)。这里我将只报告建立最佳模型的过程,即季节性 ARIMAX。

季节性 ARIMAX

在研究了影响蚊子繁殖的因素后,我使用 xreg 参数将这些变量添加到季节性 ARIMA 中:

  • 降水量 _ 金额 _ 毫米
  • 再分析露点温度 k
  • 再分析 _ 相对湿度 _ 百分比
  • 车站平均温度 c
  • 车站 _ 昼夜 _ 温度 _rng_c
  • 车站最高温度 c
  • 车站最低温度 c

基本上,如果你在一个热带国家长大,你可能知道蚊子的生命周期包括在水中和空气中的四个不同的阶段。因此,降水、温度和湿度在加速蚊子数量方面起着重要作用。请参考此链接了解更多信息。

有时,包含在回归模型中的预测因子的影响不是简单而直接的。例如,高温和高降雨量可能在几周之后的一段时间内影响所有病例。我运行了 CCF(交叉相关函数),以查看预测因子的任何先前滞后是否与总病例的当前滞后高度相关。似乎前 4 周的露水温度可能与当前的病例数正相关。

Figure 8: CCF Plots of Total Cases and Dew Temperature of San Juan Time Series

ARIMA 模型的选择是使用赤池的信息标准(AIC)进行的。在所有测试的模型中,a SARIMAX (3,0,2)(0,0,1)[52]是最适合圣胡安市的模型,而 ARIMAX (0,1,2)的季节傅立叶项 K = 1 是伊基托斯市的最佳模型。

在 ARIMA 和 NNET 之间的最终选择基于使用 MAE 作为主要参数的样本内交叉验证。

预测

这是两个城市的预测图。我综合了圣胡安和伊基托斯总病例的预测,并将结果提交给数据驱动网站。我 MAE 得了 25.6587,排名 674/4392。

Figure 9: Forecasted Values of Total Cases of San Juan and Iquitos

最终的模型有一些缺点,可以在将来解决。首先,我完全忽略了“ndvi”(地理变量和卫星植被指数),而这些变量可能对疾病的爆发很重要。然而,为了包括这些变量,我需要做更多的研究,以更好地理解它们是什么、为什么以及如何重要。其次,该模型没有完全捕捉到导致登革热传播的所有因素。更多与这两个城市的基础设施和医疗保健系统相关的变量应该包括在模型中。最后,可以使用多季节周期模型来显示周、月和年的不同季节模式,因为当前模型仅捕获每周的季节性。

预测 Airbnb 新用户的目的地国家

原文:https://towardsdatascience.com/predicting-destination-countries-for-new-users-of-airbnb-eb0d7db7579f?source=collection_archive---------7-----------------------

我在 3 年前发现了 Airbnb 在 Kaggle 上发布的这个有趣的挑战。但是,让您参与刺激的数据挑战永远不会太晚!:)

这个 Kaggle 挑战提出了一个预测哪个国家将成为新用户预订目的地的问题。为了这个挑战,我们将使用 Airbnb 提供的三个数据集。

  1. 训练集
  2. 测试设备
  3. 会话数据

让我们了解一下用户资料在训练和测试数据集中的样子。

描述每个用户的 16 个特征如下

  1. id:用户 id
  2. date_account_created:帐户创建日期
  3. timestamp_first_active:第一个活动的时间戳,注意它可以早于 date_account_created 或 date_first_booking,因为用户可以在注册之前进行搜索
  4. date_first_booking:首次预订的日期
  5. 性别
  6. 年龄
  7. 注册方法
  8. 注册流:用户注册的页面
  9. 语言:国际语言偏好
  10. affiliate_channel:什么样的付费营销
  11. affiliate_provider:营销的地方,如谷歌,craigslist,其他
  12. first_affiliate_tracked:用户在注册之前互动的第一个营销是什么
  13. 注册应用程序
  14. 第一设备类型
  15. 第一个浏览器
  16. country_destination:这是我们要预测的目标变量

类似地,有 6 个特征来描述用户的每个 web 会话,如下所示:

  1. user_id:与 users 表中的列' id '连接
  2. 行为
  3. 动作类型
  4. 行动 _ 详细信息
  5. 设备类型
  6. secs _ elapsed

我把对这个挑战的分析分成了两部分—

一.探索性分析

二。预测建模

让我们首先开始探索数据集。

一.探索性分析

# Importing the necessary libraries
import pandas as pd
import numpy as np
import seaborn as sns
import matplotlib.pyplot as plt
%matplotlib inline
import warnings
warnings.filterwarnings("ignore")

让我们现在加载数据。

train_users = pd.read_csv("train_users_2.csv")
test_users = pd.read_csv("test_users.csv")print("There were", train_users.shape[0], "users in the training set and", test_users.shape[0], "users in the test set.") print("In total there were",train_users.shape[0] + test_users.shape[0], "users in total." )

现在,我们将探索训练集和测试集中的所有用户。

df = pd.concat((train_users, test_users), axis = 0, ignore_index = True, sort = True)

检查空值。

display(df.isnull().sum())

我们看到“年龄”、“国家/地区 _ 目的地”、“日期 _ 首次预订”、“首次会员 _ 追踪”列中有空值。

我们尝试检查每一列中的唯一值,以确定是否有任何丢失的数据。我们发现“性别”和“第一浏览器”列中有未知数。

df.gender.unique()

df.first_browser.unique()

我们用 NaNs 替换 unknowns,并删除列“date_first_booking ”,因为它在我们的测试集中没有任何值。

df.gender.replace("-unknown-", np.nan, inplace=True)
df.first_browser.replace("-unknown-", np.nan, inplace=True)
df.drop("date_first_booking", axis = 1, inplace=True)

用户年龄

现在让我们检查年龄的统计摘要,看看是否有任何明显的异常。

df.age.describe()

最大年龄是 2014,这是不可能的。看起来用户无意中填写了年份而不是年龄。还有,最小年龄 1 看起来很荒谬。

df.loc[df['age']>1000]['age'].describe()

df.loc[df['age']<18]['age'].describe()

我们纠正错误填写的年龄,然后设置年龄限制(18-下限和 95-上限)。

df_with_year = df['age'] > 1000
df.loc[df_with_year, 'age'] = 2015 - df.loc[df_with_year, 'age']
df.loc[df_with_year, 'age'].describe()

df.loc[df.age > 95, 'age'] = np.nan
df.loc[df.age < 18, 'age'] = np.nan

可视化用户的年龄。

plt.figure(figsize=(12,6))
sns.distplot(df.age.dropna(), rug=True)
plt.show()

Fig.1: Plot visualizing the age bracket of the users

正如我们在图 1 中看到的,大多数用户群都在 20 到 40 岁之间。

用户性别

plt.figure(figsize=(12,6))
sns.countplot(x='gender', data=df)
plt.ylabel('Number of users')
plt.title('Users gender distribution')
plt.show()

Fig.2: Plot visualizing gender distribution of the users

正如我们在图 2 中看到的,男性和女性用户之间没有显著差异。

旅游目的地

这是我们预测问题的目标变量。

plt.figure(figsize=(12,6))
sns.countplot(x='country_destination', data=df)
plt.xlabel('Destination Country')
plt.ylabel('Number of users')
plt.show()

Fig.3: Plot showing popular destinations among users

我们在图 3 中看到,近 60%的用户最终没有预订 NDF 代表的任何旅行。考虑到这个问题中的用户群来自美国,大多数用户预订了美国的目的地(约 30%)。因此,我的推断是,美国旅行者倾向于在我们自己内部旅行。

我们现在将只分析那些至少进行了一次预订的用户。

plt.figure(figsize=(12,6))
df_without_NDF = df[df['country_destination']!='NDF']
sns.boxplot(y='age' , x='country_destination',data=df_without_NDF)
plt.xlabel('Destination Country')
plt.ylabel('Age of users')
plt.title('Country destination vs. age')
plt.show()

Fig.4: Plot showing choice of destination countries varies across ages

图 4 示出了在预订到图表中显示的目的地的旅行的用户中没有显著的年龄差异。然而,预订去英国旅行的用户似乎比预订去西班牙和荷兰旅行的用户年龄更大。

plt.figure(figsize=(12,6))
sns.countplot(x='signup_method', data = df_without_NDF)
plt.xlabel('Signup Method')
plt.ylabel('Number of users')
plt.title('Users sign up method distribution')
plt.show()

Fig.5: Plot showing sign up method distribution

图 5 显示,在至少预订过一次的所有用户中,近 70%的人使用基本方法(电子邮件)在 Airbnb 注册。

plt.figure(figsize=(12,6))
sns.countplot(x='country_destination', data = df_without_NDF, hue = 'signup_method')
plt.xlabel('Destination Country')
plt.ylabel('Number of users')
plt.title('Users sign up method vs. destinations')
plt.legend(loc='upper right')
plt.show()

Fig.6: Plot showing distribution of sign-up methods vs. destinations

图 6 告诉我们,在至少预订过一次的用户中,无论预订的目的地是哪个国家,大多数人都使用电子邮件的方式注册 Airbnb。

plt.figure(figsize=(12,6))
sns.countplot(x='signup_app', data=df_without_NDF)
plt.xlabel('Signup app')
plt.ylabel('Number of users')
plt.title('Signup app distribution')
plt.show()

Fig.7: Plt showing signup app distribution

在所有预订者中,大多数人都是使用 Airbnb 的网站注册的。接下来,大多数用户使用 iOS 注册(图 7)。

plt.figure(figsize=(12,6))
sns.countplot(x='country_destination', data=df_without_NDF, hue='signup_app')
plt.xlabel('Destination Country')
plt.ylabel('Number of users')
plt.title('Destination country based on signup app')
plt.legend(loc = 'upper right')
plt.show()

Fig.8: Plot showing distribution of destination countries based on signup app

我们看到,美国用户在 Airbnb 上注册时使用了各种各样的应用程序。在其他国家,用户似乎更喜欢只在 Airbnb 的网站上注册(图 8)。

接纳

plt.figure(figsize=(12,6))
sns.countplot(x='affiliate_channel', data=df_without_NDF)
plt.xlabel('Affiliate channel')
plt.ylabel('Number of users')
plt.title('Affiliate channel distribution')
plt.show()

Fig.9: Plot showing distribtution of affiliate channels

我们看到,近 70%的用户直接来到 Airbnb 的网站,没有任何附属机构的参与(图 9)。

plt.figure(figsize=(18,6))
sns.countplot(x='first_device_type', data=df_without_NDF)
plt.xlabel('First device type')
plt.ylabel('Number of users')
plt.title('First device type distribution')
plt.show()

Fig.10: Plot showing distribution of first device type used by users

从图 10 来看,用户首次访问 Airbnb 网站时最常用的设备似乎是 Mac 桌面(40%),其次是 Windows 桌面(30%)。

plt.figure(figsize=(18,6))
sns.countplot(x='country_destination', data=df_without_NDF, hue='first_device_type')
plt.ylabel('Number of users')
plt.title('First device type vs. country destination')
plt.legend(loc = 'upper right')
plt.show()

Fig.11: Plot showing distribution of first device type vs. country destination

从图 11 中可以看出,无论预订的目的地是哪个国家,Mac Desktop 都是用户访问 Airbnb 网站的首选设备。这似乎是美国最高的。紧随其后的是 Windows 桌面。

df_without_NDF_US = df_without_NDF[df_without_NDF['country_destination']!='US']
plt.figure(figsize=(18,6))
sns.countplot(x='country_destination', data=df_without_NDF_US, hue='first_device_type')
plt.ylabel('Number of users')
plt.title('First device type vs. country destination without the US')
plt.legend(loc = 'upper right')
plt.show()

Fig.12: Plot showing distribution of first device type vs. destinations (excluding US)

在美国以外,苹果设备似乎比 Windows 设备更受欢迎(图 12)。

plt.figure(figsize=(20,6))
sns.countplot(x='first_browser', data=df_without_NDF)
plt.xlabel('First browser')
plt.ylabel('Number of users')
plt.title('First browser distribution')
plt.xticks(rotation=90)
plt.show()

Fig.13: Plot showing distribution of first browsers used by users

正如预期的那样,30%的预订者使用 Chrome 浏览器访问 Airbnb 网站。接下来最受欢迎的似乎是 Safari 浏览器(图 13)。

用户的首选语言

plt.figure(figsize=(12,6))
sns.countplot(x='language', data=df_without_NDF)
plt.xlabel('language')
plt.ylabel('Number of users')
plt.title('Users language distribution')
plt.show()

Fig.14: Plot showing user language distribution

几乎所有用户的语言偏好都是英语。这是合理的,因为我们的人口问题来自我们。

日期

为了直观地显示预订如何随月份和年份而变化,让我们首先将日期列转换为 datetime 类型。

df_without_NDF['date_account_created'] = pd.to_datetime(df_without_NDF['date_account_created'])
df_without_NDF['timestamp_first_active'] = pd.to_datetime((df_without_NDF.timestamp_first_active)//1000000, format='%Y%m%d')
plt.figure(figsize=(12,6))
df_without_NDF.date_account_created.value_counts().plot(kind='line', linewidth=1.2)
plt.xlabel('Date')
plt.title('New account created over time')
plt.show()

Fig.15: Plot showing trend of user account creation

2014 年后,账户创建量将大幅增加。Airbnb 在 2014 年后突飞猛进(图 15)。

#Creating a separate dataframe for the year 2013 to analyse it further.
df_2013 = df_without_NDF[df_without_NDF['timestamp_first_active'] > pd.to_datetime(20130101, format='%Y%m%d')]
df_2013 = df_2013[df_2013['timestamp_first_active'] < pd.to_datetime(20140101, format='%Y%m%d')]plt.figure(figsize=(12,6))
df_2013.timestamp_first_active.value_counts().plot(kind='line', linewidth=2)
plt.xlabel('Date')
plt.title('First active date 2013')
plt.show()

Fig.16: Plot showing trend of first activity of users in 2013

如果我们看到用户每月的活跃程度,那么高峰月份是 7 月、8 月和 10 月。另一方面,最不活跃的月份是 12 月(图 16)。

用户会话数据探索性分析

正在加载会话数据。

sessions = pd.read_csv("sessions.csv")print("There were", len(sessions.user_id.unique()),"unique user ids in the sessions data.")

检查空值。

display(sessions.isnull().sum())

检查未知数。

sessions.action_type.unique()

我们看到“action_type”列中有 nan 和 unknown,因此我们将所有 unknown 转换为 nan。

sessions.action_type.replace('-unknown-', np.nan, inplace=True)sessions.action.value_counts().head(10)

sessions.action_type.value_counts().head(10)

sessions.action_detail.value_counts().head(10)

plt.figure(figsize=(18,6))
sns.countplot(x='device_type', data=sessions)
plt.xlabel('Device type')
plt.ylabel('Number of sessions')
plt.title('Device type distribution')
plt.xticks(rotation=90)
plt.show()

Fig.17: Plot showing device type distribution

正如我们在更早的时候研究用户数据时发现的那样,访问 Airbnb 最流行的设备似乎是 Mac Desktop。现在让我们来看看至少预订了一次的用户的会话行为(图 17)。

session_booked = pd.merge(df_without_NDF, sessions, how = 'left', left_on = 'id', right_on = 'user_id')#Let us see what all columns we have for session_booked
session_booked.columns

让我们来看看预订者通常会做的 5 大行为。

session_booked.action.value_counts().head(5)

二。预测建模

#Importing necessary libraries
import pandas as pd
import numpy as np
import seaborn as sns
import matplotlib.pyplot as plt

加载数据集并在此过程中进行一些数据预处理。

train_users = pd.read_csv('train_users_2.csv')
test_users = pd.read_csv('test_users.csv')
df = pd.concat((train_users, test_users), axis=0, ignore_index=True)
df.drop('date_first_booking', axis=1, inplace=True)

特色工程

df['date_account_created'] = pd.to_datetime(df['date_account_created'])df['timestamp_first_active'] = pd.to_datetime((df.timestamp_first_active // 1000000), format='%Y%m%d')df['weekday_account_created'] = df.date_account_created.dt.weekday_name
df['day_account_created'] = df.date_account_created.dt.day
df['month_account_created'] = df.date_account_created.dt.month
df['year_account_created'] = df.date_account_created.dt.yeardf['weekday_first_active'] = df.timestamp_first_active.dt.weekday_name
df['day_first_active'] = df.timestamp_first_active.dt.day
df['month_first_active'] = df.timestamp_first_active.dt.month
df['year_first_active'] = df.timestamp_first_active.dt.year

计算时间滞后变量。

df['time_lag'] = (df['date_account_created'] - df['timestamp_first_active'])
df['time_lag'] = df['time_lag'].astype(pd.Timedelta).apply(lambda l: l.days)df.drop( ['date_account_created', 'timestamp_first_active'], axis=1, inplace=True)

让我们用-1 来代替年龄一栏中的 NaNs。

df['age'].fillna(-1, inplace=True)

让我们按 user_id 分组,并计算每个用户的动作数量、动作类型和动作细节。

#First we rename the column user_id as just id to match the train and test columnssessions.rename(columns = {'user_id': 'id'}, inplace=True)action_count = sessions.groupby(['id', 'action'])['secs_elapsed'].agg(len).unstack()
action_type_count = sessions.groupby(['id', 'action_type'])['secs_elapsed'].agg(len).unstack()
action_detail_count = sessions.groupby(['id', 'action_detail'])['secs_elapsed'].agg(len).unstack()
device_type_sum = sessions.groupby(['id', 'device_type'])['secs_elapsed'].agg(sum).unstack()sessions_data = pd.concat([action_count, action_type_count, action_detail_count, device_type_sum],axis=1)
sessions_data.columns = sessions_data.columns.map(lambda x: str(x) + '_count')# Most used device
sessions_data['most_used_device'] = sessions.groupby('id')['device_type'].max()print('There were', sessions.shape[0], 'recorded sessions in which there were', sessions.id.nunique(), 'unique users.')

secs_elapsed = sessions.groupby('id')['secs_elapsed']secs_elapsed = secs_elapsed.agg(
    {
        'secs_elapsed_sum': np.sum,
        'secs_elapsed_mean': np.mean,
        'secs_elapsed_min': np.min,
        'secs_elapsed_max': np.max,
        'secs_elapsed_median': np.median,
        'secs_elapsed_std': np.std,
        'secs_elapsed_var': np.var,
        'day_pauses': lambda x: (x > 86400).sum(),
        'long_pauses': lambda x: (x > 300000).sum(),
        'short_pauses': lambda x: (x < 3600).sum(),
        'session_length' : np.count_nonzero
    }
)
secs_elapsed.reset_index(inplace=True)
sessions_secs_elapsed = pd.merge(sessions_data, secs_elapsed, on='id', how='left')
df = pd.merge(df, sessions_secs_elapsed, on='id', how = 'left')print('There are', df.id.nunique(), 'users from the entire user data set that have session information.')

#Encoding the categorical features
categorical_features = ['gender', 'signup_method', 'signup_flow', 'language','affiliate_channel', 'affiliate_provider', 'first_affiliate_tracked', 'signup_app', 'first_device_type', 'first_browser', 'most_used_device', 'weekday_account_created', 'weekday_first_active']df = pd.get_dummies(df, columns=categorical_features)df.set_index('id', inplace=True)

分裂训练和测试

#Creating train dataset
train_df = df.loc[train_users['id']]train_df.reset_index(inplace=True)
train_df.fillna(-1, inplace=True)#Creating target variable for the train dataset
y_train = train_df['country_destination']train_df.drop(['country_destination', 'id'], axis=1, inplace=True)from sklearn.preprocessing import LabelEncoder
label_encoder = LabelEncoder()
encoded_y_train = label_encoder.fit_transform(y_train) #Transforming the target variable using labels#We see that the destination countries have been successfully encoded now
encoded_y_train

#Creating test set
test_df = df.loc[test_users['id']].drop('country_destination', axis=1)
test_df.reset_index(inplace=True)id_test = test_df['id']
test_df.drop('id', axis=1, inplace=True)

从训练和测试中移除副本(如果有)。

duplicate_columns = train_df.columns[train_df.columns.duplicated()]duplicate_columns

我们发现有重复的,因此我们删除它们。

#Removing the duplicates 
train_df = train_df.loc[:,~train_df.columns.duplicated()]

类似地,处理测试集中的重复项。

test_df.columns[test_df.columns.duplicated()]

test_df = test_df.loc[:,~test_df.columns.duplicated()]

训练模型并进行预测

对于给定的预测问题,我们使用 XGBoost 模型。

import xgboost as xgb
xg_train = xgb.DMatrix(train_df, label=encoded_y_train)#Specifying the hyperparameters
params = {'max_depth': 10,
    'learning_rate': 1,
    'n_estimators': 5,
    'objective': 'multi:softprob',
    'num_class': 12,
    'gamma': 0,
    'min_child_weight': 1,
    'max_delta_step': 0,
    'subsample': 1,
    'colsample_bytree': 1,
    'colsample_bylevel': 1,
    'reg_alpha': 0,
    'reg_lambda': 1,
    'scale_pos_weight': 1,
    'base_score': 0.5,
    'missing': None,
    'nthread': 4,
    'seed': 42
          }num_boost_round = 5print("Train a XGBoost model")
gbm = xgb.train(params, xg_train, num_boost_round)

对测试集进行预测

y_pred = gbm.predict(xgb.DMatrix(test_df))

为每个用户 id 选择前 5 个目的地。

ids = []  #list of ids
cts = []  #list of countries
for i in range(len(id_test)):
    idx = id_test[i]
    ids += [idx] * 5
    cts += label_encoder.inverse_transform(np.argsort(y_pred[i])[::-1])[:5].tolist()

创建一个包含用户及其五大目的地国家的数据框架。

predict = pd.DataFrame(np.column_stack((ids, cts)), columns=['id', 'country'])

创建最终预测 csv。

predict.to_csv('prediction.csv',index=False)

我们已经成功预测了 Airbnb 新用户的目的地国家!

下一步:

  1. 由于我们知道哪些目的地国家更受用户欢迎,Airbnb 可以实施有针对性的营销。这意味着,将这些特定国家的营销策略集中于上述练习中确定的用户。
  2. Airbnb 可以提前计划他们应该更多地搜寻哪些国家,以获得住宿提供商的支持,因为他们可以清楚地看到用户访问这些国家的倾向。
  3. 根据特定用户对目的地国家的选择,Airbnb 可能会想到类似的目的地国家(在气候、地形、娱乐选择等方面)。)作为其他可行的旅行选项提供给用户。
  4. 该分析提供了关于用户简档看起来如何的广泛想法。Airbnb 利用这一优势来试验新的营销策略,或者头脑风暴未来几年的需求变化。

如果你喜欢看我的分析,一定要给我掌声!:)

源代码托管在 GitHub 上。

预测员工流动率

原文:https://towardsdatascience.com/predicting-employee-turnover-7ab2b9ecf47e?source=collection_archive---------1-----------------------

介绍

员工流动率是指离开一个组织并被新员工取代的员工的百分比。对组织来说,这是非常昂贵的,费用包括但不限于:离职、空缺、招聘、培训和替换。平均来说,组织投资四周到三个月来培训新员工。如果新员工在第一年就决定离开,这项投资对公司来说将是一项损失。此外,由于定期更换的客户代表和/或的顾问,咨询公司等组织的客户满意度会下降,这将导致失去客户。

在本帖中,我们将研究来自 kaggle 的模拟人力资源数据,以构建一个分类器,帮助我们预测在给定某些属性的情况下,哪种员工更有可能离职。这种分类器将有助于组织预测雇员流动,并积极主动地帮助解决这种代价高昂的问题。我们将限制自己使用最常见的分类器:随机森林,梯度推进树,K-最近邻,逻辑回归和支持向量机。

数据有 14999 个例子(样本)。下面是每一种的功能和定义:

  • satisfaction_level:满意度{ 0–1 }。
  • last_evaluationTime:自上次绩效评估以来的时间(以年为单位)。
  • number_project:工作时完成的项目数。
  • average_montly_hours:工作场所每月平均工作时间。
  • time_spend_company:在公司工作的年数。
  • Work_accident:员工是否发生了工作场所事故。
  • left:员工是否离开了工作场所{0,1}。
  • promotion_last_5years:员工在过去五年中是否获得晋升。
  • 销售:员工工作的部门。
  • 工资:工资的相对水平{低、中、高}。

创建这篇文章的源代码可以在这里找到。

数据预处理

让我们看一下数据(检查是否有缺失值以及每个要素的数据类型):

Data oveview

因为没有缺失值,所以我们不必做任何插补。但是,需要一些数据预处理:

  1. 销售功能名称改为部门
  2. 薪金转换为有序分类特征,因为在低、中、高之间有内在的顺序。
  3. 部门特征创建虚拟特征,并删除第一个特征,以避免某些学习算法可能遇到的线性依赖性。

数据现在可以用于建模了。最终的特征数量现在是 17 个。

建模

让我们先来看看每一类的比例,看看我们处理的是平衡的还是不平衡的数据,因为每一类都有自己的一套工具在拟合分类器时使用。

Class counts

如图所示,我们有一个不平衡的数据集。因此,当我们在这样的数据集上拟合分类器时,在比较诸如 f1-scoreAUC(ROC 曲线下面积)等模型时,我们应该使用准确性以外的度量。此外,类不平衡通过隐式学习基于数据集中的多数类优化预测的模型,使决策规则偏向多数类,从而影响训练期间的学习算法。有三种方法可以处理这个问题:

  1. 对少数群体的错误预测给予更大的惩罚。
  2. 对少数类进行上采样或对多数类进行下采样。
  3. 生成合成训练示例。

尽管如此,没有明确的指南或最佳实践来处理这种情况。因此,我们必须尝试所有这些方法,看看哪种方法最适合手头的问题。我们将限制自己使用前两个,即,在分类器中使用class_weight为来自少数类的错误预测分配更大的惩罚,这允许我们这样做,并评估对训练数据的上采样/下采样,以查看哪一个给出更高的性能。

首先,使用 80/20 拆分将数据拆分为训练集和测试集;80%的数据将用于训练模型,20%用于测试模型的性能。第二,对少数类进行上采样,对多数类进行下采样。对于这个数据集,正类是少数类,负类是多数类。

原始形状:(11999,17) (11999,)
上采样形状:(18284,17) (18284,)
下采样形状:(5714,17) (5714,)

我认为我们不需要应用 PCA 之类的降维方法,因为:1)我们想知道每个特征在决定谁会离开与谁不会离开(推断)中的重要性。2)数据集的维数适当(17 个特征)。然而,很高兴看到需要多少主成分来解释数据中 90%、95%和 99%的变化。

PCA

看起来它需要 14、15 和 16 个主成分来分别捕捉数据中 90%、95%和 99%的变化。换句话说,这意味着数据已经在一个良好的空间中,因为特征值彼此非常接近,并进一步证明我们不需要压缩数据。

我们在构建分类器时将遵循的方法如下:

  1. 使用 scikit-learn 的make_pipeline构建一个处理所有步骤的管道,该管道有两个步骤:

I .将数据标准化,以加快收敛速度,并使所有特征具有相同的比例。

二。我们想要用来拟合模型的分类器(estimator)。

2.使用GridSearchCV通过 10 重交叉验证调整超参数。我们可以使用更快的RandomizedSearchCV,尤其是如果我们有两个以上的超参数,并且每个超参数的范围都很大时,它可能会优于GridSearchCV;然而,GridSearchCV将工作得很好,因为我们只有两个超参数和下降范围。

3.使用训练数据拟合模型。

4.使用测试数据为最佳估计量绘制混淆矩阵和 ROC 曲线。

随机森林、梯度推进树、K 近邻、逻辑回归和支持向量机重复上述步骤。接下来,选择交叉验证 f1 值最高的分类器。注意:一些超参数范围将由论文将机器学习应用于生物信息学问题的数据驱动建议指导。

随机森林

首先,我们将从使用未采样、上采样和下采样数据拟合随机森林分类器开始。其次,我们将使用交叉验证(CV) f1 得分评估每种方法,并选择 CV f1 得分最高的方法。最后,我们将使用该方法来拟合其余的分类器。

我们将调整的唯一超参数是:

  • max_feature:每次分割随机考虑多少个特征。这将有助于避免在每次分割时挑选很少的强特征,并让其他特征有机会做出贡献。因此,预测的相关性将会降低,每棵树的方差将会减少。
  • min_samples_leaf:每次拆分要有多少个实例才能成为最终叶节点。

随机森林是一个集合模型,有多棵树(n_estimators)。最终预测将是所有估计者预测的加权平均值(回归)或模式(分类)。注意:大量的树不会导致过度拟合。

Random Forest hyperparameter tuning results

上采样产生了最高的 CV f1 值,为 99.8%。因此,我们将使用上采样数据来拟合其余的分类器。新数据现在有 18,284 个例子:50%属于积极类,50%属于消极类。

让我们使用上面调整的最佳超参数,用向上采样的数据重新调整随机森林,并使用测试数据绘制混淆矩阵和 ROC 曲线。

Random Forest

梯度推进树

梯度增强树与随机森林相同,除了:

  • 它从小树开始,并通过考虑成年树的残差从成年树开始学习。
  • 更多的树会导致过度拟合;与随机森林相对。

因此,我们可以把每一棵树都看作一个弱学习者。除了max_featuresn_estimators之外,我们要调整的另外两个超参数是:

  • learning_rate:速率树学习,越慢越好。
  • max_depth:每次树生长时的分裂次数,限制了每棵树的节点数。

让我们使用测试数据拟合 GB 分类器并绘制混淆矩阵和 ROC 曲线。

Gradient Boosting Trees hyperparameter tuning results

Gradient Boosting Trees

k-最近邻

KNN 被称为懒惰学习算法,因为它不学习也不适合任何参数。它从训练数据中提取最接近我们感兴趣的点的n_neighbors点来预测它的类别,并将邻近点的类别的模式(多数投票)作为它的类别。我们要调整的两个超参数是:

  • n_neighbors:用于预测的邻居数量。
  • weights:根据以下条件为邻居分配多少权重:
  • “均匀”:所有相邻点的权重相同。
  • “距离”:使用预测中使用的每个相邻点的欧几里德距离的倒数。

让我们拟合 KNN 分类器,并绘制混淆矩阵和 ROC 曲线。

K-Nearest Neighbors hyperparameter tuning results

K-Nearest Neighbors

逻辑回归

对于逻辑回归,我们将调整三个超参数:

  • penalty:正则化类型,L2 或 L1 正则化。
  • C:参数λ正则化的反面。C 越高,正则化程度越低。我们将使用覆盖非正则化到完全正则化之间的整个范围的值,其中模型是示例标签的模式。
  • fit_intercept:是否包含拦截。

我们不会使用任何非线性,如多项式特征。

Logistic Regression hyperparameter tuning results

Logistic Regression

支持向量机(SVM)

SVM 调整其超参数的计算成本非常高,原因有二:

  1. 对于大数据集,它变得非常慢。
  2. 它有大量的超参数需要优化,这需要在 CPU 上花费很长时间来优化。

因此,我们将使用我们之前提到的论文中推荐的超参数值,该论文显示在 Penn Machine Learning Benchmark 165 数据集上产生最佳性能。我们通常希望调整的超参数有:

  • Cgammakerneldegreecoef0

10 倍 CV f1 分为:96.38%

Support Vector Machine

结论

最后,让我们打印出到目前为止我们训练的所有分类器的测试准确率,并绘制 ROC 曲线。然后我们将挑选 ROC 曲线下面积最大的分类器。

Comparing ROC curves for all classifiers

尽管随机森林和梯度增强树具有几乎相等的 AUC,但随机森林具有更高的准确率和 f1 值,分别为 99.27%和 99.44%。因此,我们有把握地说,随机森林优于其余的分类器。让我们看看随机森林分类器的特征重要性。

Random Forest feature importance

看起来最重要的五个特征是:

  • 满意度 _ 级别
  • 时间 _ 花费 _ 公司
  • 平均每月小时数
  • 数字 _ 项目
  • lats _ 评估

带回家的信息如下:

  • 在处理不平衡类时,精度不是模型评估的好方法。AUC 和 f1 分数是我们可以使用的指标示例。
  • 上采样/下采样、数据合成和使用平衡的类权重是尝试提高不平衡类数据集的分类器精度的好策略。
  • GridSearchCV帮助调整每个学习算法的超参数。RandomizedSearchCV更快,可能会超过GridSearchCV,尤其是当我们有两个以上的超参数需要优化时。
  • 主成分分析(PCA)并不总是被推荐,特别是如果数据在一个好的特征空间中,并且它们的特征值彼此非常接近。
  • 正如所料,在大多数情况下,集成模型优于其他学习算法。

原载于 2017 年 12 月 11 日imaddabbura . github . io

预测未来农药样品结果,促进智能农药使用

原文:https://towardsdatascience.com/predicting-future-pesticide-sample-results-to-promote-intelligent-pesticide-use-66badaa0baa1?source=collection_archive---------2-----------------------

DeepFarm 概述

DeepFarm 是一家科技初创公司,正在寻求将深度学习应用于精准农业,以获得可操作的见解。这些见解将来自广泛的领域,包括水和能源使用、杂草控制、运营成本以及我们今天的主题——农药使用。在更大的范围内,DeepFarm 正在寻求发展成为一个端到端的系统,负责自动收集、处理、可视化和实现数据驱动的结果。

问题陈述

建立一个分类器,能够最好地预测给定食品样品中农药残留的实验室结果,以促进高效和安全的农药使用。

项目目标

在完成手头的问题时,我还想测试这个特定数据集的各种算法(传统的和高级的)的准确性和效率,并比较每个算法的业务用例。

数据

该项目使用的数据由美国农业部(USDA)采购,作为其农药数据计划的一部分,并发布到 Kaggle(链接如下)。该数据库(仅 2015 年,2013–2014 年也可用)包括约 230 万份实验室样本,总数据量为 89MB。我们的分类器的基线是 98.31%,因为所有样品中只有 1.69%被归类为农药残留超过可接受的阈值。尽管改善的幅度很小,但 1.69%的结果是大约 40,000 个样本超过了农药的可接受阈值,可能会对消费者造成健康后果。对这一基线的任何改进都会导致成百上千的样本被正确识别。

数据链接:https://www . ka ggle . com/usdeptofag/pesticide-DATA-program-2015

型号选择

对于传统模型,我选择使用逻辑回归和随机森林。这些代表了传统模型谱的极端,并将为与高级深度学习模型进行比较提供完整的基础。对于深度学习 3 层模型,我在隐藏层使用了 1024 个节点,dropout 为 0.5,ReLU 激活。

实施

逻辑回归和随机森林模型都使用 SciKit-Learn,神经网络是使用 TensorFlow 后端和 Keras 前端包装器构建的。

结果

正如我们从下面的幻灯片中看到的,随着模型复杂性的增加,准确性也在增加。然而,这种准确性是以时间为代价的,这一因素应由利益相关者根据具体情况进行评估。逻辑回归模型是我们的模型中最简单的,同时表现得相当好,并提供了最易于人类阅读的输出和对系数的访问。随机森林增加了额外的复杂性,输出只有树,但有增加我们的模型准确性的优势。我们的前馈神经网络与我们的随机森林具有相同的精度,但是我相信随着额外的数据和处理能力,这个结果可以增加到甚至更精确。

Model Results

从枪支法预测枪支死亡率:生命与自由之间的平衡是可以衡量的

原文:https://towardsdatascience.com/predicting-gun-death-rate-from-gun-laws-d96041c14198?source=collection_archive---------6-----------------------

当美国政府成立时,生命、自由和追求幸福被视为天赋人权。美国枪支法平衡了限制个人自由和保护个人生命。

以下是无可争议的:1。枪支法限制个人自由。枪支法拯救生命。没有理由浪费精力争论这些事实。相反,问题是,美国人将选择在哪里找到生命和自由之间的平衡,因为这是一个选择。

All data, code, and notes to replicate this analysis can be found on my GitHub repo

撇开游说者对枪支政策或枪支政策对犯罪的影响不谈,各州已经选择通过枪支法,这些法律代表了生命与自由连续统一体中的一系列观点。这里总结的分析不是一种观点,而是对一组复杂的相互作用的、可测量的因素和结果的描述,使用数学算法进行梳理。(按州和年份分类的枪支死亡率和枪支法计数)……中的数字..数字(增加或减少预测死亡率的枪支法律类别以及增加或减少多少)。

结果是一个横向树,描绘了预测的平均年枪支死亡率,这取决于它们在一个类别中拥有的法律数量。树中的每一个分割线都显示了一些法律子类如何增加或减少与枪支相关的死亡人数。从树的左侧开始,每 100,000 名州居民的平均枪支死亡率预测为 11.2,但对于在允许类别内有 4-8 项法律的州,它下降到 7.3。对于有 0-3 个许可法的州,比率增加到 12.7…等等。

特别及时的是年龄限制是否重要的问题。在某些情况下,有更多年龄限制的州(如州枪支法律项目码本所定义的)预计死亡率会低得多。具体来说,在有更多许可法但没有指纹法的州,通过实施更多年龄限制,死亡率预计将减半(4.3 比 9.7,最右边从上往下数第二和第三个框)。

数据:

波斯顿大学州枪支法律项目维护着一个数据库,其中记录了 1991 年至 2017 年间 133 个州枪支法律条款的状况,根据对枪支暴力的预期影响,由他们的法律研究团队分为 14 个类别和 49 个子类别。这是一个公开可用的资源,你也可以通过他们的交互式地图图表进行探索。我下载了他们按州和年份划分的有无枪支法律条款的数据集。

疾控中心的基本死因数据库按地区和年份对死亡证明死因进行了细分。我下载了每个州/年每 100,000 居民的原始死亡率,火器是死亡原因。这包括任何因枪支造成的死亡,无论是否意外,是否自残,是否与犯罪有关,但没有关于枪支类型、性别、年龄或情况的数据。

正如州枪支法项目警告的那样,由于枪支法本身不太可能是枪支死亡率的唯一决定因素,我进行了同样的分析,包括每个州/年的失业率,然后是每个州/年的加权人口密度,这两者都没有显著改变结果。在重复分析中,可能有其他因素(按州/年)可以提供信息,例如与枪支法更多或更少的州的接近程度。

总结平衡自由与生活的量化效果:

基于递归分割和回归树(RPART)分析,发现 49 个枪支法子类中的 10 个显著预测了州枪支死亡率的下降与上升,平均误差率为每 100,000 人 1.76 例死亡。预测的年平均死亡率是 11.2。从那里树分成两部分:上部和下部。

上半部分显示,在拥有 4-8 项许可法律(由州枪支法律项目码本定义)的州,该比率从 11.2 降至 7.3。其中,也有指纹法的州的比率预计会下降到 4.8;否则就涨到 9.0 了。如果没有指纹法,在 6-7 个年龄限制法的情况下,预测的比率从 9.0 下降到 4.3,但在 0-5 个年龄限制法的情况下,预测的比率增加到 9.7。

该树的下半部分从拥有 0-3 项许可法律的州开始,平均每年预计枪支死亡率为 12.7。对于有 2-8 个存储法则的州,这个比率可以降低到 9.5,否则,这个比率会增加到 13.3。预计在暴力轻罪子类别中有 1-3 项(任何)法律的州,这一数字将从 13.3 降至 10.6;如果没有,预测的比率将增加到 14.0。

再向右下方移动,在 2-3 个枪支贩运法律之间,这些州的预测比率从 14.0 下降到 10.8,但是对于 0-1 个枪支贩运法律的州,预测比率增加到 14.7。在家庭暴力限制令子类别中保留 4-11 项法律会将预测比率从 14.7 一直降低到 9.1,但如果这些州有 0-3 项这样的法律,比率会增加到 15.2。如果先占权子类别中有 2-3 项法律,这些州的预测比率将从 15.2 下降到 11.4,但如果有 0-1 项法律,预测比率将上升到 15.3。如果这些州在背景调查子类别中有 2-4 项法律,这一比率预计会稍微降低到 15.1,但如果有 0-1 项这样的法律,这一比率会上升到 17.6。对于那些有大量背景调查法律的州,预测的枪支死亡率在有 1-3 个(任何)经销商许可子类别法律的情况下从 15.1 下降到 13.6,在没有法律的情况下上升到 15.5。

以上三段是信息图存在的理由。向上滚动并查看树可能会更好。或者可以这样压缩:1 .枪支法限制个人自由。枪支法拯救生命。

感谢您的阅读。

我欢迎建设性的反馈。“鼓掌”表示赞同,在 FB、Twitter、Linkedin、Reddit 或任何地方分享,或者如果你有具体的回应或问题,请在这里给我发消息。我也有兴趣听听你想在未来的帖子中涉及哪些主题。如果您想要用于数据争论、特性工程和分析的数据和 R 代码,请派生或下载我的关联 GitHub 资源库。如果有人在添加可能影响结果的额外州/年变量后重复分析,那就太好了。如果有,请告诉我。

阅读更多关于我的作品【jenny-listman.netlify.com】。欢迎随时通过 Twitter@ jblistmanLinkedIn联系我。

数据和分析说明:

  1. 复制这一分析的所有数据、代码和注释都可以在我的 GitHub repo 上找到。去吧!
  2. 从州枪支项目下载了 1991 年至 2017 年美国各州 133 项枪支法律的存在或不存在:https://www.statefirearmlaws.org/table.html
  3. 法律的代码本及其类别、子类和解释可从国家火器法律项目的网站上下载:https://www.statefirearmlaws.org/download-codebook.html
  4. 美国疾病预防控制中心按州/年分列的死因火器数据下载自:https://wonder.cdc.gov/ucd-icd10.html使用过滤标准:州、年、受伤原因=火器。或者从我的 GitHub repo 下载吧。
  5. 使用 R 统计计算语言中的 rpart 包,输入变量包括由州枪支法项目编码的 49 个子类别中每一个子类别每年的法律总数,输出变量是每年每个州的年度原始枪支死亡率。输入变量被缩放,因为法律类别的大小变化很大。数据被分成训练集和测试集。通常,这是通过随机选择 20%的数据作为测试集,80%的数据作为训练集来完成的。然而,对于这个数据集,很可能存在给定年份的跨州相关性和给定年份的跨年相关性,或者每个小范围年份内的年间相关性。因此,数据集按奇数年或偶数年分成两组,每一组都按州进行了平衡,并消除了年初/近年的偏差。用典型的 20/80 随机分割完成的重复分析给出了令人难以置信的相似结果。
  6. 虽然我最终没有使用每年每个州的失业率或加权人口密度,但在我的 GitHub repo 中有数据集。我花时间获取它们,并把它们整理成整齐的格式,其他人可能会想要使用它们。2016 年各州失业数据来自美国劳工部,劳工统计局。截至 2015 年的失业率数据来自爱荷华州立大学,爱荷华社区指标计划下的“附加数据:下载 Excel 中的历史年度系列(1980-当前)”。他们已经汇编了美国劳工部那几年的数据,所以我不必这么做。加权人口密度数据是利用丹·戈尔茨坦在《决策科学新闻》的这篇文章中的代码获得的。

用机器学习预测视频游戏点击率

原文:https://towardsdatascience.com/predicting-hit-video-games-with-ml-1341bd9b86b0?source=collection_archive---------1-----------------------

Original image: http://kotaku.com

在这个项目中,我分析了 8K 视频游戏的销售数据,确定了与点击率(销量超过 100 万台的游戏)最相关的变量,并实现了一个预测模型来区分赢家和输家。奖金:2016 年有哪些游戏还能成为热门?

1.数据探索和分析

中值销售额(百万单位)与评论家得分

以下四幅热图显示了游戏销售如何根据评论家的评分而变化,这些评分分为六个评分组。此外,每个热图还根据以下特征之一进一步细分数据:流派、开发者、发行商和平台(按外观顺序)。

在每个热图下,我们确定了游戏销售最好的类别。这是为好的好的、好的游戏而做的,这些游戏分别由得分在 70、80 和 90 分的游戏定义。

  • 最畅销的游戏类型:赛车、动作
  • **好的*游戏卖得最好的流派:***平台、动作/射击
  • **流派哪里好的游戏卖得最好:**格斗,杂项

  • 谁的游戏卖得最好:任天堂,艺电
  • **开发商谁的游戏卖得最好:**任天堂,Namco
  • 谁的游戏卖得最好?

解读:在 伟大的 得分栏(最后),任天堂每场游戏的中值销售额(以百万台计)最高,为 460 万台。有趣的是,任天堂在 好的 好的 得分栏中也拥有最高的每场游戏中值销售额。

  • **销售优秀游戏最好的发行商:**微软游戏工作室,华纳兄弟互动娱乐公司
  • **卖游戏最好的发行商:**任天堂/华纳兄弟互动娱乐
  • **卖 okay 游戏最好的发行商:**任天堂,微软游戏工作室

  • 伟大的游戏卖得最好的平台: PS,X360
  • 好游戏卖得最好的平台: PS3,XOne
  • 游戏卖得最好的平台: PS3,X360

有趣的是,整个 PlayStation 产品线中的游戏销售似乎对高评论家分数非常敏感,特别是当中等分数范围的销售看起来与其他主机相当时(或至少表现出较窄的差距)。

数据集中的最高值

(按平台、开发商、发行商和流派)

数据集中游戏最多的平台

  1. PS2
  2. PS3

数据集中游戏最多的开发商:

  1. 育碧
  2. 艺电体育
  3. EA 加拿大

数据集中游戏最多的发行商:

  1. 电子艺术
  2. 动视
  3. 纳木错万代运动会

数据集中游戏最多的流派:

  1. 行动
  2. 运动
  3. 混杂的

数据集相关性

(用于数值和分类变量)

最强相关性:

  • **评论家评分与全球销售额之比 😗* 我们将在接下来的两个部分中进一步探讨这一点。
  • **发布到平台的年份 😗* 这很有意义,因为新平台会定期发布。

注意:分类栏(平台、流派、发行商)按照游戏数量的顺序转换为数字,如前一节所示。他们与全球销售的轻微负相关可以解释为“ID 号越高,则[平台、流派、发行商]越小,因此销售数字也就略低”。

评论家得分与全球销售额

(针对数据集中的所有年份)

有点乱,对吧?

我们将继续使用垃圾箱来更好地感受这种关系…

For years ≥ 2014

这种关系现在看起来清晰多了。有趣的是,斜率在 80 年代变得更陡。似乎一旦一个视频游戏获得了很高的批评分数,每增加一分都会产生更大的影响。例如,在 2014 年至 2016 年的子集里,评论家分数增加 8 分,似乎对 65 分起的销售额有大约 25 万英镑的积极影响,但对 77 分起的销售额有大约 100 万英镑的积极影响。 去大了还是回家吧?

将销量超过 100 万台的产品定义为热门产品

这将是我们预测模型中的目标,在这里我们将预测一个游戏是否会成功。目标是二进制的:如果命中则为 1,否则为 0。

以下是使用 5%样本的评论家分数和 VG 点击率之间的关系:

正如所料,点击率似乎大多出现在高评论分数附近,而非点击率在分数上可能有所不同,但在高分范围内开始失去存在(正如 70 年代附近的变陡回归曲线所解释的)。

2.预测模型

(用于预测给定游戏达到 100 万台或更高销量的可能性,称为“热门”游戏。分类方法被应用于从非命中中分离命中。)

生成特征和训练/测试分割

用 RFC 和 LR 测试预测精度

分级功能性能

**Feature ranking (top 10):**1\.  **Critic_Score** (0.323090)
2\.  **Year_of_Release** (0.158740)
3\.  **Publisher_Nintendo** (0.030405)
4\.  **Genre_Action** (0.024856)
5\.  **Publisher_Activision** (0.018035)
6\.  **Genre_Sports** (0.016918)
7\.  **Publisher_Electronic** Arts (0.016917)
8\.  **Genre_Shooter** (0.015722)
9\.  **Platform_PS3** (0.015634)
10\. **Publisher_Ubisoft** (0.014164)

3.2016 年哪些电子游戏还能成为热门?

最有可能成为热门的视频游戏:

最不可能成为热门的视频游戏:

Kaggle 笔记本(Python)可以在这里找到并随时在TwitterLinkedIn上找我。

如果你喜欢读这篇文章,如果你点击“推荐”按钮和/或分享它,我会很感激。

预测爱荷华州埃姆斯的房价

原文:https://towardsdatascience.com/predicting-home-prices-in-ames-iowa-3a247e6c9639?source=collection_archive---------5-----------------------

回归、正则化、残差和特征选择

Kaggle 最近在爱荷华州的 Ames 举办了一场旨在预测房价的比赛。你可以在这里了解更多信息。

在我的分析中,我避开了卡格尔关于预测销售价格的问题。相反,我想确定哪些功能最能增加房屋价值。这些数据包括地块大小、地块形状、邻居和其他你无法改变的房子特征。后半部分是关于某些方面的质量和状况。这些质量变量反映了房子中你可以在出售前翻新的部分(车库、厨房、整体)。

我问自己:房子的哪一部分可以改进,从而最大程度地提高价格?

我把这个问题分成三个部分:

  1. 固定的特征,如地段大小、房子的平方英尺和邻居,能在多大程度上解释销售价格。
  2. 在剩下的误差中,包含测量翻新的特征能解释多少呢?
  3. 在这些质量特征中,哪一个最能解释错误,哪一个最能提高销售价格?

这个分析的所有代码都可以在我的 GitHub repo 中找到

探索性数据分析

和所有好的项目一样,我探索了数据的特性。首先,销售价格。

该分布不完全是正态分布,但对于我们的模型来说,它足够接近了。与左侧相比,尾部继续向右侧延伸(显然不会有售价低于 0 美元的房屋)。这些高销售价格异常值将会在以后的分析中引起问题。

街区的平均价格显示了从上到下的明显差异。作为一个固定的模型,这是第一个模型中最重要的特征之一。

固定特征模型

使用线性回归,我发现固定特征解释了销售价格变化的 82%。不算太坏。然而,绘制实际销售价格与预测销售价格的对比图显示,非常昂贵的房屋的销售价格一贯高估。

这里的残差是实际价格和预测价格之间的差额。残差越大,模型就离正确预测越远。这里使用的线性模型试图减少所有数据点的残差。

再往深里看,也许我们并不需要所有这些功能。有可能其中一些只是噪音。

正则化是一种减少或消除不重要特征的影响并向模型中添加小误差项的方法。我执行了一个套索正则化方法,发现 10 个最有影响力的特征中有 7 个是邻域变量(每个邻域都有一个虚拟变量)。

在所有特征中,“邻居”是不可能改变的。对于我的第二个模型,我研究了翻新如何进一步解释销售价格

翻新模型

对于第二个模型,我包含了所有可以通过家庭装修来修复的特性。仅用这些模型,我发现它们解释了 74%的销售价格。同样,规则化表明虚拟变量“屋顶材料”和“厨房质量”变量解释了最大的差异。

然而,仔细观察“屋顶材料”的价值计数显示,只有 6 个家庭有木瓦,使得这个变量在最终分析中没有用,因为很少有家庭有木瓦。“厨房质量”值更多地分布在一般、典型/一般、良好和优秀之间。

组合模型

要了解“厨房质量”如何解释固定特征模型的误差,只需将该变量代入即可。模型的 R 平方从 0.82 增加到 0.85。换句话说,“厨房质量”解释了基于固定特征的模型中 19%的误差。

结论

“厨房质量”变量的贝塔系数(又名系数)显示了翻新会增加多少销售价格。与普通厨房相比,提升一个质量等级将会提高售价:

  • 优秀:65,884.53 美元
  • 好:17898.30 美元
  • 典型/平均 1,878.90 美元

当然,这个项目没有考虑装修的成本。如果你能以低于上面列出的价格升级一个不错的厨房,你会在销售谈判中得到更多。

欢迎评论和提问。所有代码和一些 powerpoint 幻灯片都可以在我的 GutHub repo 这里获得。

预测医院病床的可用性(部分。1)

原文:https://towardsdatascience.com/predicting-hospital-bed-availability-part-1-81d75649a18c?source=collection_archive---------5-----------------------

“MacBook Pro near black stethoscope and brown clipboard” by rawpixel on Unsplash

我们是塞利姆·阿姆鲁尼和 T2,目前是哥伦比亚大学运筹学的学生。如果您有任何问题,请随时通过电子邮件(塞利姆 / 蒂博)或我们的 LinkedIn ( 塞利姆·阿姆鲁尼 / 蒂博·杜普雷)账户与我们联系。

在这个 Medium 系列中,我们将于 2018 年夏天在 NYU 朗格健康展示我们作为研究实习生的工作。

本文(部分。1)将着重于问题的一般陈述和医院流程的描述。

部分。2 将关注用于预测医院入住率的模型。所以,这里我们进入项目的核心!

实习概述

“预测未来 72 小时内医院床位的可用性…”

医院病床占用率的容量规划、预测和优化是一个热门领域。目标提升操作流程提高效率****保健行业。一些医院,如辛辛那提儿童医院和耶鲁纽黑文医院,由于容量规划已经改善了他们的运营系统。****

作为世界大城市纽约的一家医院,纽约医疗中心经历了几次床位短缺。这些情况非常烦人这就是为什么提前预测床位占用然后使用这些预测优化患者安置是一个有趣且有用的问题。****

我们的目标是预测未来 72 小时(每天)的床位可用性。
随着数据的到来,模型必须重新校准:我们不知道今天会发生什么,但明天我们就会知道发生了什么,所以模型必须不断地用更新的数据重新拟合它的预测。****

综合换乘中心

“white airplane in sky above body of water” by kazuend on Unsplash

“医院控制塔”

综合转运中心 (CTC)是一个由十几个成员组成的团队,管理 整个 NYU 朗格健康的所有患者流动活动。它与领导和员工以及跨学科团队合作,管理 NYU 朗格健康中心内部和内部的转移。
CTC 比作医院的
【控制塔】。这个团队每天都在做着一项惊人的工作,以确保 NYU 所有床位设施的完善 管理。****

医院组织

Tisch Hospital

NYU 兰贡拥有 200 个地点,其中 6 个护理住院病人。本项目的范围仅限于的 3 个住院单位: Tisch 医院、 Kimmel 馆&hassen feld儿童医院。
在进一步深入之前,我们首先需要定义一个
护理单元(NU)** 。阿奴是医院的一个**物理细分。每个 NU 对应一个护士台。****

我们的项目粒度处于 NU 级别:我们需要预测每个 NU 内的可用性。

项目范围统计在 562 床位左右,分布在 21 个 NU 中,每个 NU 又根据护理级别的不同细分为 3 级:(从最低到最高)急性,阶梯式&重症监护。因此,患者可以根据他们的服务和他们需要的护理级别进行分配。通常,有三至四个 NUs 可用,安置旨在提高医院的运作效率。

医院病人流量

为了预测床位需求,重要的是了解医院的患者流量**。首先我们需要创建一个简单的方案来了解某个患者可以处于哪种状态。这个方案可以很容易地用数学建模,并用历史数据进行调整。**

下图说明了我们为研究选择的医院的简化机制。真实的图表更复杂,但在我们的项目范围内,所引起的变化可以忽略不计。

Diagram of the patients flow

入口两种 种****患者:预约(在医院预约的,主要是手术)和非预约**(主要是急诊)。这些病人在医院员工看过之后,可以占用一张病床,也可以不占用一张病床,成为住院病人,直到出院。由于该项目的目标是预测床位的可用性,没有占用床位的患者不在考虑范围内。******

为了估计未来床位的可用性,我们需要区分以下情况:

  • 当前住院患者:我们可以访问住院患者的当前快照,基于此数据,我们希望为每位住院患者分配特定的住院时间(LoS)。
  • 即将安排的:我们可以查看下一次手术的时间表。我们有一些关于这些“预定”病人的信息。根据该时间表,我们将尝试调整预定住院病人的数量,并为他们分配一个服务点。
  • 即将到来的计划外的:这些病人天生就是随机的。根据历史数据,我们将尝试对急诊室即将到来的患者进行抽样调查。通过这些模拟,我们希望调整非预定住院病人的数量,并为他们分配一个服务点。

模型框架

投入

使用了四个数据集来源:

  • 当前普查:是拉出来的那一刻医院所有住院病人的快照。
  • 流量:这是最近两个月流量的数据集,对历史数据进行统计很有用。
  • 或时间表:这是一个时间表,我们可以访问 15 天内即将到来的手术,我们可以访问护理强度、药物类型和手术时间。NU 尚未分配。
  • 安置矩阵:这是一个由 CTC 团队经常更新的矩阵,将特定类型的药物和护理级别与 NU 相关联。

输出

输出是小的表格用于每个护理单元分成三个 不同的 来源:“预定的”、“非预定的”和“当前住院病人”,可以很容易地汇总。表格的列分隔六个时隙。每个时间段代表 12 个小时(主要是上午和下午)。时间线从今天凌晨 0:00 开始,到明天中午 12:00 结束。表格中的行分隔了每个时间段 NU 中的入院、出院和患者总数(来自所考虑的来源)。

Example of an output for the unit xxx, sourced with the unscheduled patients (the name of the unit is masked for non-disclosure agreement)

汇总三个来源

为了有一个特定 NU 的接下来 72 小时的预测,忽略来源,我们只需对来自三个来源的求和。如果我们想要完整位置(Tisch 医院、Kimmel Pavillon 或 Hassenfeld 儿童医院)的预测,我们只需对相应 NU 的表求和。****

结论

瞧啊。在第一部分中,您有机会了解了医院、CTC 组织和管理以及对我们模型的介绍。在接下来的文章中,我们将更深入地研究模型的每个部分,使用单词距离使程序对人类输入具有鲁棒性,模拟未安排的患者,构建图形用户界面以及我们改进工具的思考。

请跟随我们并保持关注…

预测医院病床的可用性(部分。2)

原文:https://towardsdatascience.com/predicting-hospital-bed-availability-part-2-4ebf1c037df1?source=collection_archive---------5-----------------------

“woman showing man laptop” by rawpixel on Unsplash

我们是塞利姆·阿姆鲁尼和 T2,目前是哥伦比亚大学运筹学的学生。如果您有任何问题,请随时通过电子邮件(塞利姆 / 蒂博)或我们的 LinkedIn ( 塞利姆·阿姆鲁尼 / 蒂博·杜普雷)账户与我们联系。

在这个 Medium 系列中,我们将于 2018 年夏天在 NYU 朗格健康展示我们作为研究实习生的工作。

部分。1 是关于问题的一般陈述和医院流程的描述。

本文(部分。2)将集中于用于预测医院占用率的模型。所以,这里我们进入项目的核心!

住院病人模型

初步的

住院病人已经进入 NYU 朗格医疗机构。正如他们已经承认的那样,唯一的目标预测他们的出院日期。然后,通过合计每个 NU 内的出院人数,我们可以检索 NU 内的患者人数。

每天预测患者的剩余 LoS 是多少

可以实施两种方法来预测患者的出院情况。首先,我们可以尝试直接预测患者入院时的损失(例如:3 天、4 天……)。然而,患者的出院是非常不可预测的,并且估计的出院日期在患者护理过程中会改变几次。事实上,患者的身体反应是不确定的,没有人确切知道患者将停留多久,未来的治疗将是什么,等等。因此,第二种方法是每天预测患者的剩余 LoS** 是什么。这是我们采取的方法。**

同样,预测****排放日期既可以看作是回归也可以看作是分类问题。

由于 CTC 团队要求的粒度,我们选择了分类方法。

回归问题中,目标是预测在医院的正确剩余时间量。然而,由于 CTC 团队要求的粒度,我们选择了分类方法。事实上,从运营的角度来看,重要的是了解医院每天的入住情况,但他们并不关心出院的确切时间。在与团队进行了几次审查后,除了当天,我们意识到他们需要知道的一个重要信息放电是否会在中午(下午 12:00)之前发生。事实上,在中午之前知道一张床是否是排放物** (DBN)使得团队能够在下午直接重新确定这张床的属性。这样,就不会出现病人在夜间入住的床位不足的情况。这就是为什么我们把回归问题变成了分类问题。我们将时间分成 7 个 12 小时的时间段,从**“0–12 小时”“+72 小时”。例如,如果患者属于“24–36h”类别,这意味着他的剩余 LoS 在 24 到 36 小时之间。这样,预测医院住院人数的问题就变成了一个监督七类分类问题**。**

使用的功能

用于这项任务的数据集是当前的人口普查。这是医院的快照,有大约 200 个特征。但是,由于过去数据中未来数据的数据泄漏(患者的过去数据被最后的条目覆盖),我们无法使用这些功能。有希望的是,在与 it 团队的几次会议后,由于他们惊人的工作,我们开始每天四次捕获和存储当前的人口普查数据集。因此,我们希望能够在今后的工作中尝试和检验我们的方法。

乍一看,因为我们无法访问历史数据,所以我们只能为我们的住院病人模型使用一个特性:医生给出的估计出院数据。事实上,医生在其每日患者巡视期间更新患者的估计出院日期。

数据的处理

给定医生估计的出院日期和当前时间,我们可以计算患者的剩余住院时间。然后,知道了病人将停留的剩余时间,我们可以将每个病人归属于它所属的类别。最后一步是在每个 NU 内计算属于每个类别的患者数量,以便了解出院人数。

结果

Scatter Plot of the Actual vs. Expected Remaining LoS

实际剩余 LoS 与预期剩余 LoS 的散点图显示了医生预测的**低效率。**基于这种观察,我们试图开发一种监督学习分类算法。

预定模型

放置矩阵

安置矩阵为 NU 指定一种医疗类型和一个护理级别。

First rows of the Placement Matrix (details have been blurred for non-disclosure agreement)

我们可以看到在某些情况下有 NU ( 1),2) …)的列表。这描述了 NU 填充的顺序,如果“1”已满,则将患者放在“2”中,以此类推。我们还可以观察到,有时根据外科医生的团队或一天的类型(工作日、周末或假日),位置会发生变化。

我们必须解读原始文本…

格式不是以为是机器使用而是被人类雇员使用。我们不得不解读原始文本。有时,同一 NU 的名称会有些不同。我们需要找到一种方法来解决这些困难,我们不能为特定的布局矩阵编码一个简单的映射。事实上,布局矩阵经常变化,我们需要执行一个算法 对这些变化具有鲁棒性。

…使用单词距离…将 ch1 转换为 ch2 所需的最少数量的基本运算

我们决定列出 NU 的未更改名称,然后使用单词距离将放置矩阵建议的 NU 与列表中距离最小的 NU 相关联。为此,我们使用了以下距离:设 ch1ch2 为两个字符链。 ch1ch2 标注为 D(ch1,ch2) 的距离是ch1 转换为 ch2 所需的ch1 的最小基本运算次数。有三种基本操作:****

  • 互换两个角色(1)(例如:狗→上帝)
  • 插入一个字符(2)(例如:上帝→黄金)
  • 删除一个字符(3)(例如:黄金→旧)

例如D(“”、“手套”)= 5:

How to calculate the distance between ”dog” and “glove”

这个距离的灵感来自于著名的莱文斯坦距离。我们增加了操作互换。在我们的例子中,字符链实际上是句子。如果两个句子中的单词相似但顺序不同,则互换具有灵活性。我们可以注意到距离验证了距离的最广泛的数学定义:

Definition of a distance

结果非常令人满意,没有一个 NU 的名字被错误地映射。

承认

一旦我们能够正确处理位置矩阵,承认是简单的。我们选择了这样的假设,即患者 在其手术之后的时间段进入 他的 NU。我们做这个选择是为了考虑手术的长度和在 PACU 的时间。例如,如果患者被安排在明天下午,因此在时间段“36-48 小时”,我们将假设他将在时间段“48-60 小时”到达他的 NU。

排放

由于我们还没有关于该患者的任何其他信息(他还没有住院),我们不能以令人满意的准确性影响他。根据他的《怒》,我们可以根据史料
下图给出了每个单位患者的平均损失:

The average LoS for each unit (details have been blurred for non-disclosure agreement)

非计划模型

对于计划外的患者,我们需要使用历史数据对急诊室中的到达者进行采样。

承认

原理很简单,在关于病人出院的数据中,我们可以推导出每天的平均到达人数,考虑到一周中的某一天- 季节性。下图给出了这种特殊季节性的精确值。由于一年中的一段时间(有一些高峰,尤其是在夏季或冬季)造成的季节性应该被直接考虑在内。事实上,我们只考虑了过去两个月的出院数据。因此统计使得只考虑当年的当前 期间

Day-of-the-week-seasonality for the unscheduled arrivals

我们需要模拟今天、明天和后天

一旦我们对这些天进行了统计,我们就知道今天、明天和后天我们需要模拟多少计划外的患者。我们甚至更精确:我们考虑是上午还是下午来正确地填充我们的时间段。
然后,如果我们知道我们必须对特定时间段内的" n "非预定到达进行采样,我们也可以分配给这个" n "不同的患者和 NU。我们利用历史数据完成了这项任务,下图说明了非计划到达的 NU 份额。基于这种分布,我们可以很容易地对计划外患者进行抽样(这只是一种多项分布)。我们使用这个模型来填充急诊室到达的输入。

The distribution of the NU concerning the unscheduled arrivals (details have been blurred for non-disclosure agreement)

排放

正如我们对预约患者所做的那样,我们对非预约患者的 LoS 进行了抽样。然后我们可以推导出不定期到达的出院日期。

现在,CTC 团队已经将软件全部设置好了…

Graphic interface we made in order to facilitate the use for non-technical people

结论

瞧啊。在第二部分中,您有机会深入了解我们为项目构建的模型。在接下来的文章中,我们将进入更奇妙、更吸引人的数学领域来改进这个模型。

请跟随我们并保持关注…

入院时预测住院时间

原文:https://towardsdatascience.com/predicting-hospital-length-of-stay-at-time-of-admission-55dfdfe69598?source=collection_archive---------4-----------------------

探索一个重要的医疗保健绩效指标

Photo by Hush Naidoo on Unsplash

项目概述

预测分析是医疗保健领域日益重要的工具,因为现代机器学习(ML)方法可以使用大量可用数据来预测患者的个体结果。例如,ML 预测可以帮助医疗保健提供者确定疾病的可能性,帮助诊断,推荐治疗方法,以及预测未来健康。在这个项目中,我选择关注医疗保健的物流指标,医院住院时间 (LOS)。LOS 定义为入院到出院之间的时间,以天为单位。

美国医疗系统每年至少花费3775 亿美元,最近的医疗保险立法规范了手术费用的支付,不管病人在医院呆了多少天。这激励医院在入院时识别具有高 LOS 风险的患者。一旦确定,具有高 LOS 风险的患者可以优化他们的治疗计划,以最小化 LOS 并降低获得医院获得性疾病(如葡萄球菌感染)的机会。另一个好处是事先了解 LOS 可以帮助后勤工作,如房间和床位分配计划。

问题陈述

这个项目的目标是建立一个模型,预测每个病人入院时的住院时间。

我最初的想法是,使用随机森林或梯度树增强集成方法会产生最好的结果。其原因是集成方法结合了多种学习算法,以获得比单一算法更好的预测性能,并经常用于 Kaggle 竞赛。然而,第一步是找到合适的数据集。

作为寻找数据的起点,我的直觉是,数据集应该理想地包括诸如患者的诊断类别(例如,心脏病、分娩、受伤/中毒等)的特征。)、年龄、性别、婚姻状况和种族。在搜索了一个有用的医疗数据库后,我最终选择了 MIT MIMIC-III 数据库,因为它拥有大量的信息。模拟描述如下:

MIMIC 是由麻省理工学院计算生理学实验室开发的一个公开可用的数据集,包含与大约 40,000 名重症监护患者相关的去身份健康数据。它包括人口统计,生命体征,实验室检查,药物治疗,等等。

顺便提一下,进入 MIMIC 需要参加的研究道德与合规培训课程,并填写的研究申请表。我发现的唯一明显的缺点是数据库不包括儿科信息(2-13 岁)。

为了预测医院服务水平,需要将模拟数据分为因变量(在本例中为住院时间)和自变量(特征),作为模型的输入。由于 LOS 不是一个分类变量,而是一个连续变量(以天为单位),因此将使用回归模型进行预测。很可能(事实证明是这样的)数据需要大量的清理和特征工程,才能与学习模型兼容。对于这个项目,我使用了 Python 的 Pandasscikit-learn 库。

韵律学

该项目的预期结果是开发一个模型,该模型在预测医院损失方面优于中位数和平均损失的行业标准。中值损失简单来说就是过去入院的中值损失。类似地,医疗保健中第二个常用的指标是平均值,或平均 LOS。为了衡量性能,我将使用均方根误差(RMSE)将预测模型与中值和平均 LOS 进行比较。RMSE 是一种常用的度量模型预测值和观测值之间差异的方法,分数越低表示精确度越高。例如,一个完美的预测模型的 RMSE 应该为 0。这项工作的 RMSE 方程如下所示,其中(n)是住院记录的数量,(y-hat)是预测的服务水平,(y)是实际的服务水平。

最终目标是开发一种预测模型,该模型的 RMSE 低于平均模型或中值模型。

有许多回归模型可用于预测 LOS。为了确定这项工作的最佳回归模型(将被评估的模型子集),将使用 R2 (R 平方)评分。R2 是对模型拟合度的度量。换句话说,它是因变量中方差的比例,可以从自变量中预测出来。R2 定义为以下等式,其中( y_i )是观察数据点,( ŷ )是观察数据的平均值,( f_i )是预测模型值。

最佳可能的 R2 分数是 1.0,负值意味着它比常数模型差,在这种情况下是平均值或中值。

数据探索和特征工程

在多次重复查看 MIMIC 数据库中各种表格的内容后,我最终选择了以下表格,并使用 Pandas 将它们加载到 DataFrames 中: *ADMISSIONS.csv、PATIENTS.csv、DIAGNOSES _ ICD.csv、*和 ICUSTAYS.csv.

入院表给出了 SUBJECT_ID(唯一的患者标识符)、HADM_ID(住院 ID)、ADMITTIME(入院日期/时间)、DISCHTIME(出院时间)、DEATHTIME 等信息。该表有 58,976 个入院事件和 46,520 个不同的患者,这似乎是进行预测模型研究的合理数据量。首先,我通过获取每一行的入院和出院时间之间的差异创建了一个住院时间列。我选择删除有负损失的行,因为这些是患者在入院前死亡的情况。此外,我发现 9.8%的入院事件导致了死亡,因此我删除了这些事件,因为它们不包含在典型的 LOS 指标中。就天数而言,服务水平的分布是右偏的,中位数为 10.13 天,中位数为 6.56 天,最大值为 295 天。

对于录取种族栏,有 30 多个类别可以很容易地减少到下面显示的五个。有趣的是,亚洲类别具有最低的数据集中位数 LOS。

对于宗教,我把名单缩减为三类得不到(录取 13%】宗教(录取 66%),或者不指定(录取 20%)。无法获得的组具有最低的中值 LOS。

入院人数减少到四类:急症、新生儿、急诊、择期新生儿的平均 LOS 最低,而紧急护理类别的平均 LOS 最高。选择性招生有一个更紧密的分布,有利于较低的损失,这是有道理的,因为这种情况的严重性通常是时间不太关键。

这个数据集有一个有趣的见解,表明自费(通常意味着免费)入院比其他保险类别的 LOS 短得多。医疗保险和医疗补助占据最高的中位 LOS 位置,这可能与这些系统中患者的年龄有关。

患者表提供了不确定的出生日期和性别信息。因为模拟数据集不提供真实的出生日期来保护患者的身份,所以我需要使用以下解码器来设计年龄特征:患者的年龄由他们出生的“出生日期”和他们第一次入院的日期之间的差异给出。考虑到这一点,我合并了患者入院数据帧,并使用 pandas‘group by’来提取每个患者的首次入院时间。

df[['SUBJECT_ID ',' ADMITTIME']]。groupby('SUBJECT_ID ')。最小()。重置索引()

在计算了出院时间和第一次入院时间之间的差异后,我可以看看患者的年龄分布。需要注意的是,89 岁以上的患者在 MIMIC 中被归入同一年龄组。

尽管新生儿患者数据包含在模拟数据集中,但儿科年龄不包含在内。为了给年龄分布图增加一个维度,我观察了 LOS 与年龄的关系。该图突出了新生儿和> 89 岁老人的模拟组,其中从 20 岁到 80 岁的住院人数不断增加。由于年龄极值的数据分布类似离散,我决定将所有年龄转换成类别新生儿、年轻成人、中年、老年人,以便在预测模型中使用。

诊断 _ICD 表在特征工程方面提供了最大的挑战。该表由患者和入院 id 以及 ICD9 代码组成,描述如下(来源):

国际疾病分类,临床修改(ICD-9-CM)是由美国国家卫生统计中心(NCHS)创建的改编,用于分配与美国住院病人、门诊病人和医生办公室使用相关的诊断和程序代码。

我本可以为每个代码创建虚拟变量,但是在这种情况下没有意义。在模拟数据集中使用了 6,984 个独特的代码,对患者进行了 651,047 次 ICD-9 诊断,因为大多数患者被诊断患有不止一种疾病。查看表格,您可以看到 ICD9_CODE 列代码采用了可变字符长度的方法。

经过一番调查,我发现真正的代码语法是三位数字后跟一组子类别的小数。例如,第一行的代码是 403.01,属于循环系统的疾病范围,而. 01 值进一步指定了高血压慢性肾脏及相关疾病*。此外,我注意到 ICD-9 有 17 个主要类别,所以我决定将每个入场的唯一代码分类到这些类别中。我的推理是,将 ICD-9 代码从 6984 个减少到 17 个会使 ML 模型更容易理解。此外,我不希望任何 ICD-9 代码只有一个单一的损失目标行,因为这将使培训/测试复杂化。最后,我将排序 ICD-9 代码转换为入院-ICD9 矩阵,对每个入院的诊断进行分组,并将新列与 HADM_ID(入院 ID)上的主入院数据帧合并。您可以看到每一行(入院)都包含多个诊断,这是应该的。*

Part of the admission-ICD9 category matrix

查看每个 ICD-9 超级类别的中值 LOS,可以看到妊娠皮肤诊断代码组之间令人印象深刻的差异。正如后面将要显示的,诊断类别是预测 LOS 的最重要的特征。

数据预处理

即使在完成了 age 和 ICD-9 的特征工程之后,在将数据用于预测模型之前,仍有一些遗留问题需要整理。首先,我确保没有导致死亡的入院是被清理数据集的一部分。我删除了所有未使用的列,并验证了数据中不存在 nan。对于入院类型保险类型、宗教、种族、年龄、婚姻状况列,我执行了 Pandas get_dummies 命令,将这些分类变量转换成虚拟变量/指示变量。最终的数据帧大小产生 48 个特征列和 1 个目标列,条目计数为 53,104。

预测模型

为了实现预测模型,我使用 sci kit-learntrain _ test _ split函数将 LOS 目标变量和特征以 80:20 的比例分成训练集和测试集。

X_train,X_test,y_train,y _ test = train _ test _ split(features,
LOS,test_size = .20)

使用训练集,我使用默认设置拟合了五个不同的回归模型(来自 scikit-learn 库),然后比较了测试集上的 R2 分数。GradientBoostingRegressor 以大约 37%的 R2 分数赢得了测试集,所以我决定专注于改进这个特定的模型。由于 RandomForestRegressor 过去的成功,我尝试了该模型的参数,但从未超过 GradientBoostingRegressor 的分数。

为了改进 GradientBoostingRegressor 模型,我使用了 scikit-learn 的 GridSearchCV 函数来测试各种参数排列,如 n_estimatorsmax_depthloss 。GridSearchCV 的最佳估计结果是 n_estimators =200, max_depth =4,以及 loss =ls。这导致了一个小的改进,测试集的 R2 分数大约为 39%。

结果

在查看 RMSE 基准之前,我想调查在使用梯度推进回归模型预测住院时间时,什么特征是最重要的。与产前问题相关的诊断具有最高的特征重要性系数,其次是呼吸伤害。正如我前面提到的,ICD-9 诊断类别是迄今为止最重要的特征。事实上,在前 20 大特色中,只有急诊入院类型、性别医疗补助保险显示出诊断组之外的重要性。

在指标部分,我说明了 RMSE 将用于比较预测模型与行业标准的平均和中值 LOS 指标。与常数平均值或中值模型相比,梯度推进模型 RMSE 要好 24%以上(百分比差异)。

虽然 RMSE 的趋势很有希望,但我也想从其他一些角度来评估这个模型。下图取自测试集中的前 20 个录取,并直接比较实际、预测(梯度推进模型)、平均值和中值 LOS 值。这给出了预测模型的更复杂的情况;在某些情况下,它预测得很好,但在其他情况下就不那么好了。然而,基于 RMSE 评分,预测模型通常仍将比使用中值或平均 LOS 更准确。

我想看这个模型的最后一种方式是,绘制测试集中准确预测的比例与允许误差的比例。其他研究将一个 LOS 预测视为正确如果它落在一定的误差范围内。因此,随着误差容限的增加,所有模型的准确预测的比例也应该增加。梯度推进预测模型在高达 50%的误差范围内比其他常数模型表现得更好。

结论

MIMIC 数据库提供了与医疗入院相关的惊人的深度和细节,这使我能够创建一个医院住院时间预测模型,该模型考虑了许多有趣的输入特征。这项工作最令人惊讶的方面是,在预测住院时间时,患者的 ICD-9 诊断如何发挥比年龄更重要的作用。到目前为止,这个项目最具挑战性的方面是将 ICD-9 诊断转化为更实用和更易解释的超级范畴的特征工程。然而,这也是未来改进的最明显的领域。鉴于诊断具有如此强的特征重要性,对主要的 ICD-9 分类进行额外的细分是否会产生更好的预测模型是值得评估的。我的理论是,只要数据集中有足够的入院记录来支持合理的诊断模型训练,通过这种优化,预测模型将变得更准确(更低的 RMSE)。

这个项目的 GitHub 库可以从这里获得一个 Jupyter 笔记本,它详细描述了这篇文章中探索的所有部分。

MIMIC-III,一个免费的重症监护数据库。Johnson AEW,Pollard TJ,Shen L,Lehman L,Feng M,Ghassemi M,Moody B,Szolovits P,LA 和 Mark RG。科学数据(2016)。DOI:10.1038/sdata . 2016.35。来自:http://www.nature.com/articles/sdata201635

使用 Scikit-Learn 使用机器学习预测糖尿病患者的再入院

原文:https://towardsdatascience.com/predicting-hospital-readmission-for-patients-with-diabetes-using-scikit-learn-a2e359b15f0?source=collection_archive---------4-----------------------

让我们使用机器学习来识别有再次入院风险的患者!

介绍

随着医疗保健系统转向基于价值的护理,CMS 创建了许多项目来提高患者的护理质量。其中一个项目叫做“减少医院再入院项目”( HRRP ),该项目减少对再入院率高于平均水平的医院的报销。对于那些目前在该计划下受到处罚的医院,一个解决方案是制定干预措施,为再入院风险增加的患者提供额外的帮助。但是我们如何识别这些病人呢?我们可以使用数据科学中的预测模型来帮助确定患者的优先顺序。

一个住院和再住院风险增加的患者群体是糖尿病患者。在美国,糖尿病是一种影响大约十分之一患者的医学疾病。根据奥斯特林等人的研究,糖尿病患者住院的几率几乎是普通人群的两倍(奥斯特林等人 2017 )。因此,在本文中,我将重点预测糖尿病患者的再入院。

在这个项目中,我将演示如何使用以下步骤在 Python 中建立一个预测再入院的模型

  • 数据探索
  • 特征工程
  • 构建培训/验证/测试样本
  • 型号选择
  • 模型评估

你可以跟随我的 github(【https://github.com/andrewwlong/diabetes_readmission】)上提供的 Jupyter 笔记本。

项目定义

预测糖尿病患者是否会在 30 天内再次入院。

数据探索

这个项目中使用的数据最初来自 UCI 机器学习知识库(链接)。该数据包括 1999 年至 2008 年间美国 130 家医院超过 100000 例住院的糖尿病患者。

在这个项目中,我们将利用 Python 来构建预测模型。让我们从加载数据和研究一些列开始。

简而言之,浏览数据列,我们可以看到有一些标识列、一些数字列和一些分类(自由文本)列。下面将更详细地描述这些列。

有些缺失的数据用问号(?).我们将在特性工程部分处理这个问题。

这里最重要的一栏是readmitted,它告诉我们患者是在 30 天内住院、超过 30 天还是没有再次入院。

另一个重要的列是discharge_disposition_id,它告诉我们病人住院后去了哪里。如果我们查看 UCI 提供的 IDs_mapping.csv,我们可以看到 11,13,14,19,20,21 与死亡或临终关怀有关。我们应该从预测模型中移除这些样本,因为它们不能被重新接纳。

现在让我们为二元分类定义一个输出变量。在这里,我们将尝试预测患者是否有可能在出院后 30 天内再次入院。

让我们定义一个函数来计算 30 天内再次入院人口的患病率。

大约 11%的人口再次住院。这代表了一个不平衡的分类问题,所以我们将在下面解决这个问题。

从对列的进一步分析中,我们可以看到分类(非数字)和数字数据的混合。有几件事需要指出,

  • encounter_id 和 patient_nbr:这些只是标识符,不是有用的变量
  • 年龄和体重:在这个数据集中是分类的
  • 入院 _ 类型 _id,出院 _ 处置 _id,入院 _ 来源 _id:在这里是数字,但都是 id(见 IDs_mapping)。它们应该被认为是绝对的。
  • examide 和 citoglipton 只有 1 个值,所以我们不会使用这些变量
  • diag1、diag2、diag3 是分类的,有很多值。我们将不会使用这些作为这个项目的一部分,但你可以分组这些 ICD 代码,以减少维度。我们将使用 number _ diagnoses 来获取一些信息。
  • medical _ speciality 有许多分类变量,因此我们在制作特征时应该考虑这一点。

特征工程

在本节中,我们将为预测模型创建特征。对于每个部分,我们将向数据帧添加新的变量,然后跟踪我们希望使用数据帧的哪些列作为预测模型特征的一部分。我们将把这一部分分解成数字特征、分类特征和额外特征。

在这个数据集中,缺失的数字被打上了问号。让我们用一个 nan 表示来代替它。

数字特征

最容易使用的特征类型是数字特征。这些特征不需要任何修改。我们将使用的数字列如下所示

让我们检查一下数字数据中是否有缺失值。

分类特征

我们要创建的下一类特征是分类变量。分类变量是非数字数据,如种族和性别。要将这些非数字数据转换为变量,最简单的方法是使用一种称为 one-hot encoding 的技术,下面将对此进行解释。

我们将处理的第一组分类数据是这些列:

在我们的分类特征中,racepayer_codemedical_specialty有缺失数据。由于这些是分类数据,最好的办法是使用“fillna”函数为 unknown 添加另一个分类类型。。

注意medical_specialty 没有包含在上面的列表中,因为我们需要多做一个处理步骤。在我们开始一键编码之前,让我们先研究一下医学专业。

我们可以看到,其中大多数是未知的,而且数量下降得相当快。我们不想增加 73 个新变量,因为其中一些只有很少的样本。作为替代,我们可以创建一个只有 11 个选项的新变量(前 10 个专业,然后是另一个类别)。显然,还有其他的分桶选项,但这是减少可能类别数量的最简单的方法之一。

为了将我们的分类特征转换成数字,我们将使用一种称为一次性编码的技术。在一次性编码中,您为该列中的每个唯一值创建一个新列。如果样本具有唯一值,则该列的值为 1,否则为 0。例如,对于列 race,我们将创建新列(“race_Caucasian”、“race_AfricanAmerican”等)。如果患者的种族是高加索人,则患者在“种族 _ 高加索人”栏下得到 1,在其余种族栏下得到 0。要创建这些一次性编码列,我们可以使用 pandas 提供的get_dummies功能。

现在的问题是,如果我们为每个唯一值创建一列,我们就有了相关的列。换句话说,一列中的值可以通过查看其余列计算出来。例如,如果样本不是非洲裔美国人、亚洲人、加拿大人、西班牙人或其他人,那么它必须是 UNK 人。为了处理这个问题,我们可以使用drop_first选项,它将删除每一列的第一个分类值。

get_dummies 功能不适用于数字数据。为了欺骗get_dummies,我们可以将 3 个 ID 类型的数字数据转换成字符串,然后它将正常工作。

现在我们准备好制作我们所有的分类特征

要将独热编码列添加到数据帧中,我们可以使用concat 函数。确保使用 axis = 1 来表示添加列。

让我们保存分类数据的列名来跟踪它们。

额外功能

我们想要制作的最后两个专栏是ageweight。通常,您会认为这些是数字数据,但它们在该数据集中是分类的,如下所示。

一种选择是创建如上所示的分类数据。由于这些值有一个自然的顺序,将它们转换成有序的数字数据可能更有意义。另一个例子,当你想这样做的时候,可能是 t 恤的尺寸(小号,中号,大号)。先说年龄。

让我们将这些映射到 0 到 90 乘 10s 的数值数据。

现在我们来看看重量。请注意,此功能不经常填写。

让我们创建一个变量来表示是否填写了权重,而不是像上面那样创建一个序数特征。不管值是多少,变量的存在都可能是预测性的。

让我们也跟踪这些额外的列。

特征工程:概述

通过这个过程,我们为机器学习模型创建了 143 个特征。这些功能的细分如下

  • 8 个数字特征
  • 133 个分类特征
  • 2 个额外功能

让我们创建一个只有特性和OUTPUT_LABEL的新数据帧。

构建培训/验证/测试样本

到目前为止,我们已经研究了我们的数据,并根据分类数据创建了特征。现在是我们拆分数据的时候了。分割数据背后的想法是,这样你就可以衡量你的模型在看不见的数据上做得有多好。我们分成三个部分:
—训练样本:这些样本用于训练模型
—验证样本:这些样本来自训练数据,用于决定如何改进模型
—测试样本:这些样本来自所有决策,用于衡量模型

的综合性能。在这个项目中,我们将分成 70%的训练、15%的验证和 15%的测试。

我喜欢做的第一件事是使用sample打乱样本,以防出现某种顺序(例如,所有阳性样本都在顶部)。这里的n是样品的数量。random_state只是被指定,所以该项目是可复制的。在你自己的项目中,你不一定需要random_state

我们可以再次使用sample提取 30%的数据(使用frac)用于验证/测试分割。重要的是,验证和测试来自相似的发行版,这种技术是实现这一点的一种方式。

现在使用 50%的分数分为测试和验证。

注意.drop只是删除了df_test中的行,以获取不属于样本的行。我们可以用同样的方法获得训练数据。

在这一点上,让我们检查一下 30 天内住院的组的百分比。这就是所谓的流行。理想情况下,这三组人群的患病率相似。

每个群体的患病率大致相同。

此时,您可能会说,将训练数据放入预测模型中,然后查看结果。然而,如果我们这样做,我们可能会得到一个 89%准确的模型。太好了!干得好!但是,等等,我们从来没有捕捉到任何重新接纳(回忆= 0%)。怎么会这样?

现在的情况是,我们有一个不平衡的数据集,其中负样本比正样本多得多,因此模型可能会将所有样本都指定为负样本。

通常情况下,最好以某种方式平衡数据,给积极的一面更多的权重。通常使用 3 种策略

  • 对更占优势的类别进行二次抽样:使用底片的随机子集
  • 对不平衡类进行过采样:多次使用相同的正样本
  • 创建合成阳性数据

通常,如果只有少数几个阳性病例,您会希望使用后两种方法。因为我们有几千个阳性病例,所以让我们使用子样本方法。这里,我们将创建一个 50%正面和 50%负面的平衡训练数据集。也可以玩玩这个比例,看能不能得到一个提升。

大多数机器学习包喜欢使用输入矩阵 X 和输出向量 y,所以让我们创建它们:

当变量大小不同时(0–100,vs 0–1000000),一些机器学习模型会有问题。为了解决这个问题,我们可以扩展数据。在这里,我们将使用 scikit-learn 的标准定标器,该定标器去除了平均值并按单位方差进行定标。在这里,我将使用所有的训练数据创建一个缩放器,但如果你愿意,你也可以使用平衡的。

我们将需要这个 scaler 来处理测试数据,所以让我们使用一个名为pickle的包来保存它。

现在我们可以转换我们的数据矩阵

我们还不会转换测试矩阵,所以在完成模型选择之前,我们不会考虑性能。

型号选择

哇!为模特做准备有这么多工作。在数据科学中,这总是正确的。您花费 80–90%的时间清理和准备数据。

在本节中,我们将训练一些机器学习模型,并使用一些技术来优化它们。然后,我们将根据验证集的性能选择最佳模型。

我们将利用以下函数来评估模型的性能。关于这些性能指标的讨论,请参阅我以前的文章

因为我们平衡了训练数据,所以让我们将阈值设置为 0.5,以将预测样本标记为阳性。

模型选择:基线模型

在本节中,我们将首先使用默认超参数比较以下 7 个机器学习模型的性能:

  • k-最近邻
  • 逻辑回归
  • 随机梯度下降
  • 朴素贝叶斯
  • 决策图表
  • 随机森林
  • 梯度推进分类器

k 最近邻(KNN)

KNN 是最简单的机器学习模型之一。对于给定的样本点,该模型查看 K 个最接近的数据点,并通过计算阳性标签的数量除以 K 来确定概率。该模型易于实施和理解,但缺点是对 K 敏感,如果训练样本的数量很大,则需要很长时间来评估。我们可以使用 scikit-learn 中的以下代码来拟合 KNN。

我们可以用下面的代码来评估性能

为简洁起见,我们将从剩余模型中排除评估,仅显示以下汇总结果。

逻辑回归

逻辑回归是一种传统的机器学习模型,适合正负样本之间的线性决策边界。这个线性函数然后通过一个 sigmoid 函数来计算正类的概率。当要素可以线性分离时,逻辑回归是一个很好的模型。逻辑回归的一个优势是模型是可解释的,即我们知道哪些特征对于预测积极或消极是重要的。需要考虑的一点是,建模对特征的缩放很敏感,所以这就是我们缩放上述特征的原因。我们可以使用 scikit-learn 中的以下代码来拟合逻辑回归。

随机梯度下降

随机梯度下降类似于逻辑回归。这两种方法都使用梯度下降来优化线性函数的系数。在逻辑回归中,每次迭代都使用所有数据样本,而在随机梯度下降中,只使用一小批样本。这允许随机梯度下降来加速训练。我们可以使用 scikit-learn 中的以下代码来拟合随机梯度下降。

朴素贝叶斯

朴素贝叶斯是机器学习中偶尔使用的另一种模型。在朴素贝叶斯中,我们利用贝叶斯规则来计算概率。这个模型的“幼稚”之处在于它假设所有的特性都是独立的(事实通常不是这样)。这对于自然语言处理模型来说效果很好,但是不管怎样,让我们在这里尝试一下。我们可以用下面的代码来拟合朴素贝叶斯。

决策图表

另一类流行的机器学习模型是基于树的方法。最简单的基于树的方法被称为决策树。本质上,在树形方法中,你利用游戏 20 问题背后的方法论来继续划分你的样本。在每个问题中,您询问样本是否有大于某个阈值的特定变量,然后分割样本。最终预测则是树的最后一片叶子(最终分裂)中阳性样本的分数。这种方法背后的机器学习是要找出在每次分裂时使用哪个变量和哪个阈值。基于树的方法的一个优点是,它们没有关于数据结构的假设,并且如果给定足够的树深度,能够拾取非线性效应。我们可以使用下面的代码来拟合决策树。

随机森林

决策树的一个缺点是,通过记忆训练数据,它们很容易过度拟合。因此,随机森林被创建来减少过度适应。在随机森林模型中,会创建多棵树,并对结果进行汇总。通过使用一组随机样本和每棵树中随机数量的特征,对森林中的树进行去相关。在大多数情况下,随机森林比决策树工作得更好,因为它们更容易归纳。为了适应随机森林,我们可以使用下面的代码。

梯度推进分类器

另一种改进决策树的方法是使用一种叫做 boosting 的技术。在这种方法中,您创建了一组浅树,试图改善先前训练的树的错误。一种使用这种技术与梯度下降算法(以控制学习速率)相结合的模型被称为梯度提升分类器。为了拟合梯度提升分类器,我们可以使用下面的代码。

基线模型分析

让我们用所有基线模型的结果制作一个数据框架,并用一个名为seaborn的包来绘制结果。在这个项目中,我们将利用 ROC 曲线下面积(AUC)来评估最佳模型。对于挑选最佳模型来说,这是一个很好的数据科学性能指标,因为它捕捉了真阳性和假阳性之间的权衡,并且不需要选择阈值。

正如我们所看到的,大多数模型(除了朴素贝叶斯)在验证集上具有相似的性能。正如训练和验证之间的落差所指出的,存在一些过度拟合。让我们看看是否可以使用更多的技术来提高这种性能。

模型选择:学习曲线

我们可以通过绘制学习曲线来诊断模型的表现。在本节中,我们将利用来自 scikit-learn 的网站的学习曲线代码,对绘制 AUC 而不是精确度做了一点小小的改变。

在随机森林的情况下,我们可以看到训练和验证分数相似,但它们的 AUC 分数都很低。这被称为高偏差,是不适应的标志。

根据学习曲线,我们可以采用一些策略来改进模型

高偏差:
-增加新特性
-增加模型复杂度
-减少正则化
-改变模型架构

高方差:
-添加更多样本
-添加正则化
-减少特征数量
-降低模型复杂度
-添加更好的特征
-改变模型架构

这些策略的灵感来自吴恩达的 Coursera class 转述这里的和吴恩达的机器学习向往教材

模型选择:特征重要性

改进模型的一个途径是了解哪些特性对模型是重要的。这通常只能在更简单的模型中进行研究,如逻辑回归或随机森林。这种分析可以在几个方面有所帮助:

—激发新的特性想法→有助于高偏差和高方差
—获得用于减少特性的顶级特性列表→有助于高方差
—指出管道中的错误→有助于模型的健壮性

我们可以使用下面的逻辑回归来获得特征重要性

我们可以查看前 50 个正系数和前 50 个负系数来获得一些见解。

查看这些图后,您可能会受到启发,获得一些与最重要的功能相关的新数据。例如,在这两个模型中,最重要的特征是number_inpatient,它是去年住院病人的就诊次数。这意味着,如果患者在去年去过医院,他们更有可能再次住院。这可能会激发你获得(如果你有的话)更多关于他们之前录取的数据。另一个例子是discharge_disposition_id_22,用于患者出院到康复机构的情况。对你的公司来说,你可以研究出院到康复机构的规则,并添加与这些规则相关的功能。因为大多数数据分析师/数据科学家不具备深厚的领域知识。我可能会把其中的一些特征带给其他专家(如医生),并询问他们关于药物的问题。

在高方差的情况下,一种策略是减少变量的数量以最小化过度拟合。在此分析之后,您可以使用前 N 个积极和消极特征或前 N 个重要的随机森林特征。您可能需要调整 N,以便您的性能不会急剧下降。例如,只使用顶级特性可能会大大降低性能。另一种可以用来减少变量数量的策略叫做 PCA(主成分分析)。scikit 中也实现了这一点——感兴趣的话可以学习一下。

我想提到的最后一点是,特性重要性图也可能指出您的预测模型中的错误。也许,你在清理过程中有一些数据泄露。数据泄露可以被认为是在训练中偶然包含了某种东西,从而允许机器学习算法进行人工作弊的过程。例如,我根据医生的出院记录建立了一个模型(见 TDS 文章此处)。当我对最重要的词进行同样的分析时,我发现预测某人不会被重新录取的第一个词是“过期”。这让我意识到自己犯了一个错误,忘记排除当前医院就诊中死亡的患者。从我的错误中吸取教训,我排除了与死亡/临终关怀相关的出院代码。合并数据集时也会发生类似的情况。也许当您合并数据集时,其中一个类的某些变量以 nan 结束。上面的分析将帮助你抓住其中的一些情况。

模型选择:超参数调整

我们应该研究的下一件事是超参数调整。超参数调整本质上是您在建立机器学习模型时做出的设计决策。例如,你的随机森林的最大深度是多少?这些超参数中的每一个都可以被优化以改进模型。

在本节中,我们将只优化随机梯度下降、随机森林和梯度增强分类器的超参数。我们不会优化 KNN,因为它需要一段时间来训练。我们不会优化逻辑回归,因为它的表现类似于随机梯度下降。我们不会优化决策树,因为它们往往会过度拟合,性能不如随机森林和梯度推进分类器。

超参数调整的一种技术称为网格搜索,在网格搜索中,您可以在一个值网格上测试所有可能的组合。这是非常计算密集型的。另一种选择是随机测试它们的排列。scikit-learn 中也实现了这种称为随机搜索的技术。这一部分的大部分内容是基于威廉·科尔森的博客文章。我强烈建议跟随他走向数据科学。他写高质量的文章。

让我们在一些随机森林超参数上创建一个网格。

要使用 RandomizedSearchCV 函数,我们需要对一组超参数进行评分或评估。这里我们将使用 AUC。

RandomizedSearchCV的三个重要参数是

  • 得分=用于挑选最佳模型的评估指标
  • n_iter =不同组合的数量
  • cv =交叉验证分裂的数量

增加最后两项会增加运行时间,但会减少过度拟合的机会。请注意,变量的数量和网格大小也会影响运行时间。交叉验证是一种多次拆分数据以获得更好的性能指标评估的技术。为了这个项目的目的,我们将限制到 2 CV,以减少时间。

我们可以用下面的代码来适应我们的随机搜索随机森林。

让我们分析一下最佳模型相对于基线模型的性能。

类似地,我们可以优化随机梯度下降和梯度提升分类器的性能。

我们可以汇总结果,并与验证集上的基线模型进行比较。

我们可以看到,超参数调整改进了模型,但不是很多。这很可能是因为我们有一个高偏差的情况。如果我们有高的方差,更多的改进将被期待。

模型选择:最佳分类器

这里,我们将选择梯度推进分类器,因为它在验证集上具有最佳 AUC。您不会希望每次运行新的预测时都训练您的最佳分类器。因此,我们需要保存分类器。我们将使用包pickle

模型评估

现在我们已经选择了我们的最佳模型(优化的梯度推进分类器)。让我们评估一下测试集的性能。

最终评价如表所示

我们还可以为 3 个数据集创建 ROC 曲线,如下所示

结论

通过这个项目,我们创建了一个机器学习模型,能够预测 30 天内再次入院风险最高的糖尿病患者。最佳模型是具有优化超参数的梯度推进分类器。该模型能够捕捉到 58%的再入院率,比随机选择患者要好 1.5 倍。总的来说,我相信许多医疗保健数据科学家正在研究医院再入院的预测模型。如果你是这种情况,我很乐意与你联系(在 Linkedin )并分享经验。欢迎在下面的评论中留下任何反馈或问题。

参考

奥斯特林、威科夫、恰尔科夫斯基、派、崔、巴尔、吉安昌达尼(2017)。临床糖尿病和内分泌学中的“糖尿病和 30 天再入院率之间的关系”。3:1

使用用户搜索参数预测酒店预订

原文:https://towardsdatascience.com/predicting-hotel-bookings-with-user-search-parameters-8c570ab24805?source=collection_archive---------7-----------------------

Photo credit: Pixabay

一家酒店市场数据和基准公司 STR 和谷歌发布了一份报告显示,跟踪酒店搜索结果可以对酒店预订量进行可靠的估计。因此,我们今天的目标是尝试建立一个机器学习模型,根据用户的搜索和与该用户事件相关的其他属性来预测用户事件的结果(预订或只是点击)。

数据

数据是公开的,可以从 Kaggle 下载。我们只使用训练集。下表提供了数据集的模式。

Figure 1

import datetime
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
%matplotlib inlinefrom sklearn.ensemble import RandomForestClassifier
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.decomposition import PCA
from sklearn.metrics import classification_report
from sklearn.metrics import confusion_matrix  
from sklearn.metrics import accuracy_scoredf = pd.read_csv('train.csv.gz', sep=',').dropna()
df = df.sample(frac=0.01, random_state=99)

为了能够在本地处理,我们将使用 1%的数据。之后我们还有大量的 241179 条记录。

df.shape

(241179,24)

count_classes = pd.value_counts(df['is_booking'], sort = True).sort_index()
count_classes.plot(kind = 'bar')
plt.title("Booking or Not booking")
plt.xlabel("Class")
plt.ylabel("Frequency")

Figure 2

很明显我们的数据很不平衡。我们将不得不处理它。

特征工程

该过程包括创建新列,如年、月、计划时间和酒店住宿。然后移除我们不再需要的柱子。

df["date_time"] = pd.to_datetime(df["date_time"]) 
df["year"] = df["date_time"].dt.year  
df["month"] = df["date_time"].dt.monthdf['srch_ci']=pd.to_datetime(df['srch_ci'],infer_datetime_format = True,errors='coerce')
df['srch_co']=pd.to_datetime(df['srch_co'],infer_datetime_format = True,errors='coerce')df['plan_time'] = ((df['srch_ci']-df['date_time'])/np.timedelta64(1,'D')).astype(float)
df['hotel_nights']=((df['srch_co']-df['srch_ci'])/np.timedelta64(1,'D')).astype(float)cols_to_drop = ['date_time', 'srch_ci', 'srch_co', 'user_id']
df.drop(cols_to_drop, axis=1, inplace=True)

使用热图绘制关联矩阵,以探索特征之间的关联。

correlation = df.corr()
plt.figure(figsize=(18, 18))
sns.heatmap(correlation, vmax=1, square=True,annot=True,cmap='viridis')plt.title('Correlation between different fearures')

Figure 3

我们看不到任何两个变量有非常密切的关联。

不平衡数据的处理

我将使用欠采样方法来创建重采样数据帧。

booking_indices = df[df.is_booking == 1].index
random_indices = np.random.choice(booking_indices, len(df.loc[df.is_booking == 1]), replace=False)
booking_sample = df.loc[random_indices]not_booking = df[df.is_booking == 0].index
random_indices = np.random.choice(not_booking, sum(df['is_booking']), replace=False)
not_booking_sample = df.loc[random_indices]df_new = pd.concat([not_booking_sample, booking_sample], axis=0)print("Percentage of not booking clicks: ", len(df_new[df_new.is_booking == 0])/len(df_new))
print("Percentage of booking clicks: ", len(df_new[df_new.is_booking == 1])/len(df_new))
print("Total number of records in resampled data: ", len(df_new))

Figure 4

混洗重新采样的数据帧

df_new = df_new.sample(frac=1).reset_index(drop=True)

为新数据帧分配特征和标签

X = df_new.loc[:, df_new.columns != 'is_booking']
y = df_new.loc[:, df_new.columns == 'is_booking']

PCA

主成分分析(PCA)是一种统计技术,通过选择捕捉关于数据集的最大信息的最重要特征,将高维数据转换为低维数据。我们希望主成分分析能帮助我们找出方差最大的成分。

标准化数据集

scaler = StandardScaler()
X=scaler.fit_transform(X)
X

Figure 5

应用五氯苯甲醚。我们的数据中有 23 个特征

pca = PCA(n_components=23)
pca.fit(X)

Figure 6

计算特征值

var=np.cumsum(np.round(pca.explained_variance_ratio_, decimals=3)*100)
var

Figure 7

在上面的数组中,我们看到第一个特征解释了数据集内 9.6%的方差,而前两个特征解释了 17.8%,依此类推。如果我们使用所有的特征,我们就可以获得数据集中 100%的方差,因此我们可以通过实现一个额外的特征来获得一些方差。没有任何突出的特征。

分类选择

plt.ylabel('% Variance Explained')
plt.xlabel('# of Features')
plt.title('PCA Analysis')
plt.style.context('seaborn-whitegrid')plt.plot(var)

Figure 8

根据上面的图,很明显我们应该保留所有的 23 个特征。

训练、预测和绩效评估

随机森林分类器

X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=1)pca = PCA()  
X_train = pca.fit_transform(X_train)  
X_test = pca.transform(X_test)classifier = RandomForestClassifier(max_depth=2, random_state=0)  
classifier.fit(X_train, y_train)y_pred = classifier.predict(X_test)cm = confusion_matrix(y_test, y_pred)  
print(cm)  
print('Accuracy', accuracy_score(y_test, y_pred))

Figure 9

逻辑回归

from sklearn.linear_model import LogisticRegression
from sklearn.pipeline import PipelineX_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=1)
pca = PCA(n_components=23)
logReg = LogisticRegression()pipe = Pipeline([('pca', pca), ('logistic', logReg)])
pipe.fit(X_train, y_train)
y_pred = pipe.predict(X_test)cm = confusion_matrix(y_test, y_pred)  
print(cm)  
print('Accuracy', accuracy_score(y_test, y_pred))

Figure 10

我们可以通过彻底的网格搜索将结果提高到 70%。但是在本地运行需要很长时间。我不会在这里尝试。

正如你所看到的,从我们现有的数据来预测酒店预订并不是一件容易的事情。我们需要更多的功能,如平均每日房价,用户以前的预订历史,是否有特别促销,酒店在线评论等等。

机器学习前的数据收集入门!

源代码可以在 Github 上找到。享受这周剩下的时光吧!

使用高级回归技术预测房价

原文:https://towardsdatascience.com/predicting-housing-prices-using-advanced-regression-techniques-8dba539f9abe?source=collection_archive---------1-----------------------

我最近在 General Assembly 完成了数据科学沉浸式计划,这是一个为期 12 周的培训计划,旨在深入了解数据科学世界,重点提高从大型数据集分析、预测和传达数据驱动的事实的技能。在接下来的几周里,我将分享我在课程中参与的项目,借此机会回顾我的工作,并与那些希望进入该领域的人分享我的经验。

任务

这个项目的目标是使用 EDA、可视化、数据清理、预处理和线性模型来预测给定房屋特征的房屋价格,并解释您的线性模型以找出哪些特征为房屋增值。数据最初取自 Kaggle。

来自 Kaggle:

让购房者描述他们梦想中的房子,他们可能不会从地下室天花板的高度或靠近东西向铁路开始。但是这个游乐场竞赛的数据集证明,影响价格谈判的远不止卧室的数量或白色尖桩栅栏。

有 79 个解释变量描述了(几乎)爱荷华州埃姆斯住宅的各个方面,这场比赛要求你预测每栋房屋的最终价格。

背景

Ames Housing 数据集由 Dean De Cock 编制,用于数据科学教育。对于寻找经常被引用的波士顿住房数据集的现代化和扩展版本的数据科学家来说,这是一个令人难以置信的替代方案。

探索性数据分析

与任何数据练习一样,我们从一些探索性的数据分析开始。

数字变量

有 36 个相关的数字特征。MSSubClass“确定销售中涉及的住宅类型”,编码为数字,但实际上是一个分类变量。

共有 36 个数字特征,属于以下类型:

  • 平方英尺:表示某些特征的平方英尺,即1stFlrSF(首层平方英尺)和GarageArea(以平方英尺为单位的车库大小)。
  • 时间:与时间相关的变量,如房屋何时建造或出售。
  • 房间和元素:表示元素的数据,如“有多少个浴室?”
  • 条件和质量:主观变量从 1 到 10。

大多数与公寓实际物理空间相关的变量都是正偏的——这是有道理的,因为除了非常富有的人,人们往往住在更小的房子/公寓里。

销售价格也有类似的正偏态分布——我假设与公寓实际尺寸相关的变量对销售价格有很大的影响。

Histograms of all relevant numeric variables.

许多功能与销售价格没有很大关系,例如“销售年份”。然而,一些变量,如整体质量和地段面积与销售价格高度相关。

Scatter plots of numerical variables vs. sale price

分类变量

与数字特征类似,还有一系列分类特征。虽然许多看起来销售价格随类别而变化,但也有许多并非如此。让我们确定几个影响价值的特征。一些因素包括是否有中央空调、邻居、外部质量和分区。

在不同的类别中,也有价格相差不大的特点,包括屋顶风格和土地坡度。

Bar charts of all categorical variables vs. sale price

过程

对数据有了更好的理解后,我们现在能够浏览并对数据进行一些分析。

预处理

为了在数据上运行我们的模型,我必须转换许多变量。采取了以下预处理步骤:

  • 去除异常值:采用 1.5 * IQR 去除异常值的经典 Tukey 方法去除了太多的数据。因此,我删除了 3 * IQR 之外的值。
  • 填充 NaN 值:许多变量都有需要处理的 NaN 值。这些值是根据最有意义的内容填充的。例如,Alley的 NaN 值用一个字符串填充(“No Alley”),而GarageYrBuilt的 NaN 值用中间值填充,以防止数据失真。
  • 为分类变量创建虚拟变量。
  • 将数据分为训练集和测试集
  • 缩放数据

模型

是时候建立一些模型了!我们首先使用线性回归模型对缩放数据和非缩放数据创建了一些基准。然后,我们使用三个正则化线性回归模型准备了一系列拟合。我们适合的模型有:

  • 原始数据的简单岭回归
  • 针对原始数据的简单套索回归
  • 原始数据的简单弹性网络回归
  • 针对定标数据的简单岭回归
  • 针对缩放数据的简单套索回归
  • 针对缩放数据的简单弹性网络回归

然后,我们为每个正则化的线性模型导入交叉验证模型。

结果和结论

我们表现最佳的车型是:

Top performing models. Score is the R2 score of each test.

结论

用粘土瓦给房子盖屋顶去除了大部分价值。有趣的是,靠近公园或其他户外设施也会降低房子的价值。另一方面,也有一些社区增加了价值。这种情况下最有价值的特征是GrLivArea

正则化模型在该数据集上表现良好。关于偏差/方差权衡的说明:根据高斯-马尔可夫定理,普通最小二乘法(OLS)拟合的模型是所有可能估计量中偏差最小的估计量。换句话说,它比所有可能的模型都更符合它所看到的数据。

然而,对于它没有见过的数据,它不一定表现得很好。正则化模型通过限制贝塔的大小来惩罚模型的复杂性。其结果是,该模型比 OLS 模型引入了更多的偏差,但在统计上变得更加稳定和不变。换句话说,它防止我们过度拟合,并且能够更好地推广到新数据。

预测爱荷华州的酒类销售

原文:https://towardsdatascience.com/predicting-iowa-liquor-sales-787f5d471edb?source=collection_archive---------3-----------------------

爱荷华州在其网站上提供了许多数据集,其中一个包含了该州从 2015 年 1 月到 2016 年 3 月所有酒类商店的交易。有了这些信息,我的目标是分析数据并建立一个线性回归模型来预测 2016 年剩余时间的销售额。为了更好地理解数据,每一行或每一个观察都描述了某一天某一特定商店销售了多少单位的某种商品。还包括附加信息,例如商店编号、城市、邮政编码和商店所在的县、商品描述、商品的酒类、瓶子的大小、售出的瓶子数量、瓶子的零售价格、收入等。

在提供的数据集中有很多缺失的数据,所以我寻找处理这些缺失值的方法。其中大多数都在 county 列中,所以我根据在其他观察中找到的所有唯一的市县对,通过将城市映射到相应的县,为这些观察分配了正确的县。我发现了解每个商店属于哪个县很有价值,因为按县划分销售额是汇总数据的好方法。在进一步分析数据后,我注意到销售数字有很大的季节性。

上图直观地展示了 2015 年整个州的酒类销售额逐月大幅波动的情况。就这一点对预测 2016 年销售的价值而言,可以有把握地假设 2016 年的销售将遵循类似的趋势。因此,我决定预测 2016 年最后三个季度销售额的最佳方法是建立一个模型,描述 2015 年第一季度销售额和 2016 年第一季度销售额之间的关系,然后使用 2015 年第二至第四季度的销售额来预测 2016 年第二至第四季度的销售额。从那时起,我必须决定是要对每个商店还是每个县进行销售预测。

我绘制了 2015 年第一季度销售额与 2015 年第一季度销售额在商店和县两个层面的对比图。正如您从上面的回归图中看到的,两个时间段的县销售额密切相关,而商店级别的销售数字则有很大的差异。此外,在研究数据时,我注意到在整个 15 个月中有许多商店关闭和开业,这可能会提供不准确的预测。因此,我使用按县汇总的销售数字来构建我的模型。为了详细说明该模型到底在做什么,计算机开发了一个等式来表示 2015 年第一季度销售额和 2016 年第一季度销售额之间的关系。然后,为了进行预测,我们输入每个县第 2-4 季度的销售额,模型使用它开发的公式返回每个县 2016 年的预测。

我将数据分为一个训练集和一个测试集,并能够仅使用训练集成功构建一个线性回归模型,该训练集占县销售数据集的 70%。该模型的结果预测 2016 年全年总销售额将增长约 3.62%,这是有道理的,因为我们看到 2015 年至 2016 年第 1 季度的销售额有所增长。当在测试集上测试时,该模型获得了 0.9938 的准确度分数。这个数字代表实际值和预测值之间的均方误差或 R 平方值。一个完美的模型应该有 1 分,所以我的模型表现得非常好!

我对我的模型的结果非常满意。我考虑过不仅仅使用销售数字来生成预测,例如总售出升数或总售出瓶数,但是由于这些特性与销售高度相关,我决定不使用它们以避免多重共线性。还有,我做了一个假设,销量是未来销量最好的预测指标!

预测贷款偿还

原文:https://towardsdatascience.com/predicting-loan-repayment-5df4e0023e92?source=collection_archive---------3-----------------------

介绍

借贷行业最关键的两个问题是:1)借款人的风险有多大?2)考虑到借款人的风险,我们是否应该借给他/她?第一个问题的答案决定了借款人的利率。利率衡量借款人的风险,即借款人风险越大,利率越高。考虑到利率,我们可以确定借款人是否有资格获得贷款。

投资者(贷款人)向借款人提供贷款,以换取带息还款的承诺。这意味着只有当借款人还清贷款时,贷款人才能获利(利息)。但是,如果他/她不偿还贷款,那么贷款人就赔钱了。

我们将使用来自 LendingClub.com 的公开数据。该数据涵盖了 2007 年 5 月至 2010 年 2 月期间该平台资助的 9,578 笔贷款。我们为每个借款人提供利率。因此,我们将通过预测借款人是否会在到期日偿还贷款来间接回答第二个问题。通过这个练习,我们将阐述三个建模概念:

  • 如何处理丢失的值。
  • 用于不平衡分类问题的技术。
  • 说明如何使用两种方法建立一个集合模型:混合和堆叠,这很可能会提高我们的性能。

以下是数据集中每个特征的简短描述:

  • credit_policy :如果客户符合 LendingClub.com 的信用核保标准,则为 1,否则为 0。
  • 用途:借款用途,如:信用卡、债务合并等。
  • int_rate :贷款的利率(比例)。
  • 分期付款:如果贷款有资金,借款人所欠的每月分期付款($)。
  • log_annual_inc :借款人年收入的自然对数。
  • dti :借款人的债务收入比。
  • fico :借款人的 fico 信用评分。
  • days_with_cr_line :借款人拥有信用额度的天数。
  • 循环余额:借款人的循环余额。
  • revolu _ util:借款人的循环额度使用率。
  • inq_last_6mths :借款人最近 6 个月被债权人查询的次数。
  • de inq _ 2 yers:在过去的 2 年中,借款人逾期还款超过 30 天的次数。
  • pub_rec :借款人的贬损公开记录数。
  • not _ fully _ payed:表示贷款是否没有全部偿还(借款人违约或借款人被认为不可能偿还)。

让我们加载数据并检查:

  • 每个特征的数据类型
  • 如果我们有缺失的值
  • 如果我们有不平衡的数据

创建这个帖子的源代码可以在这里找到。

Figure 1: Data types/missing values

Figure 2: Class counts

Positive examples = 1533
Negative examples = 8045
Proportion of positive to negative examples = 19.06%

看起来我们只有一个分类特征(“目的”)。此外,六个要素有缺失值(标注中没有缺失值)。此外,数据集如预期的那样非常不平衡,正面例子(“未全额支付”)只有 19%。在下一节中,我们将在概述集成方法之后解释如何处理所有这些方法。

建模

集成方法可以定义为将几个不同的模型(基础学习器)组合成最终模型(元学习器)以减少泛化误差。它依赖于这样一个假设,即每个模型都将着眼于数据的不同方面,从而获取部分事实。将独立训练的表现良好的模型组合起来,将比单个模型捕捉到更多的事实。因此,这将导致更准确的预测和更低的泛化误差。

  • 当我们添加更多的模型时,集合模型的性能几乎总是得到改善。
  • 尝试组合尽可能不同的模型。这将降低模型之间的相关性,这将提高集合模型的性能,从而显著优于最佳模型。在所有模型完全相关的最坏情况下,集成将具有与最佳模型相同的性能,如果一些模型非常差,有时甚至更低。因此,选择尽可能好的模型。

Different 集合方法以 different 方式构建模型的集合。以下是最常见的方法:

  • 混合:平均所有模型的预测。
  • 打包:在不同的数据集上建立不同的模型,然后从所有模型中获得多数票。给定原始数据集,我们使用替换进行采样,以获得与原始数据集相同的大小。因此,每个数据集平均将包括 2/3 的原始数据,其余 1/3 将是重复的。由于每个模型都将建立在不同的数据集上,因此可以将其视为不同的模型。随机森林通过减少每次分割时挑选强特征的可能性来改进默认的装袋树。换句话说,它将每次分割时可用的特征数量从 n 个特征减少到例如 n/2log(n) 个特征。这将减少相关性–>减少方差。
  • 推进:按顺序构建模型。这意味着每个模型都要学习前一个模型的残差。输出将是由学习率λ加权的每个单个模型的所有输出。它通过从先前树(模型)的残差中顺序学习来减少由 bagging 导致的偏差。
  • 堆叠:构建被称为基础学习者的 k 模型。然后将模型拟合到基础学习器的输出,以预测最终输出。

由于我们将使用随机 Fores (bagging)和梯度推进(Boosting)分类器作为集成模型中的基础学习器,因此我们将仅说明平均和堆叠集成方法。因此,建模部件将由三部分组成:

  • 应对价值观缺失的策略。
  • 处理不平衡数据集的策略。
  • 建立集合模型。

在继续之前,以下数据预处理步骤将适用于所有模型:

  1. 从特性“目的”创建虚拟变量,因为它是名义(非序数)分类变量。这也是一个很好的做法,放弃第一个,以避免产生的特征之间的线性依赖,因为一些算法可能会与这个问题作斗争。
  2. 将数据分为训练集(70%)和测试集(30%)。训练集将用于拟合模型,测试集将用于评估最佳模型,以获得泛化误差的估计。我们将使用 10 重交叉验证,而不是设置验证来调整超参数和评估不同的模型,因为这是对泛化误差更可靠的估计。
  3. 将数据标准化。我们将使用RobustScaler,这样标准化将更少受到异常值的影响,即更健壮。它将数据集中在中间值周围,并使用四分位距(IQR) 对其进行缩放。这一步将作为转换器包含在每个模型的管道中,因此我们不会单独进行。
# Create dummy variables from the feature purpose
df = pd.get_dummies(df, columns=["purpose"], drop_first=True)

应对价值观缺失的策略

现实世界的数据集几乎总是有缺失值。例如,这可能是由于用户没有填写表单的某些部分,或者在将数据发送给您之前收集和清理数据时发生了一些转换。有时缺失值是有信息的,并不是随机生成的。因此,添加二进制要素来检查每个有缺失值的要素的每一行中是否有缺失值是一种很好的做法。在我们的例子中,六个特征有缺失值,所以我们将添加六个二进制特征,每个特征一个。例如,“log_annual_inc”要素缺少值,因此我们将添加一个采用值∈ {0,1}的要素“is_log_annual_inc_missing”。好的一面是缺失值只存在于预测值中,而不存在于标注中。以下是处理缺失值的一些最常见的策略:

  • 只需删除所有缺少值的示例。如果缺失值与数据集的大小相比非常小,并且缺失值是随机的,则通常会这样做。换句话说,添加的二进制特征并没有改进模型。这种策略的一个缺点是,当测试数据在预测中有缺失值时,模型会抛出错误。
  • 分别使用每个要素的平均值估算缺失值。
  • 分别使用每个要素的中值来估算缺失值。
  • 使用链式方程多元插补(小鼠)。鼠标的主要缺点是我们不能在 sklearn 管道中将其用作转换器,并且在输入缺失值时需要使用完整的数据集。这意味着会有数据泄露的风险,因为我们同时使用训练集和测试集来估算缺失值。以下步骤解释了鼠标的工作原理:
  1. 第一步:分别使用每个特征的平均值来估算缺失值。

2.第二步:对于每个具有缺失值的特征,我们将所有其他特征作为预测值(包括具有缺失值的特征),并尝试使用例如线性回归来预测该特征的值。预测值将替换该要素的旧值。我们对所有具有缺失值的要素都执行此操作,即每个要素将被用作一次目标变量来预测其值,其余时间用作预测其他要素值的预测值。因此,一旦我们运行模型$k$次来预测具有缺失值的$k$要素,就会完成一次完整的循环(迭代)。对于我们的数据集,每次迭代将运行 6 次线性回归来预测 6 个特征。

3.第三步:重复第二步,直到预测之间没有太大的变化。

  • 使用 K-最近邻估算缺失值。我们计算数据集中所有示例(不包括缺失值)之间的距离,并取每个缺失值的 k 个最近邻的平均值。sklearn 中还没有实现它,计算它的效率很低,因为我们必须遍历所有的例子来计算距离。因此,我们将在本文中跳过这一策略。

为了评估每种策略,我们将使用随机森林分类器,其超参数值由数据驱动建议指导,用于将机器学习应用于生物信息学问题

让我们首先为缺失值创建二元要素,然后为上面讨论的每个策略准备数据。接下来,我们将使用训练数据计算所有模型的 10 重交叉验证 AUC 分数。

Original data shapes: ((7662, 24), (1916, 24))
After dropping NAs: ((7611, 18), (1905, 18))
MICE data shapes: ((7662, 24), (1916, 24))Baseline model's average AUC: 0.651 
Mean imputation model's average AUC: 0.651
Median imputation model's average AUC: 0.651
MICE imputation model's average AUC: 0.656

让我们绘制特征重要性图,以检查添加的二元特征是否为模型添加了任何东西。

Figure 3: Random Forest feature importance

在 10 倍交叉验证 AUC 分数的指导下,看起来所有策略都有可比较的结果,缺失值是随机产生的。此外,当绘制来自随机森林分类器的特征重要性时,添加的六个二元特征没有显示出重要性。因此,可以安全地丢弃这些特征,并在管道中使用中值插补方法作为转换器。

# Drop generated binary features
X_train = X_train[:, :-6]
X_test = X_test[:, :-6]

处理不平衡数据集的策略

大多数现实应用中的分类问题都有不平衡的数据集。换句话说,正面例子(少数阶级)比负面例子(多数阶级)少得多。我们可以看到,在垃圾邮件检测,广告点击,贷款审批等。在我们的例子中,正面例子(没有完全付款的人)只占全部例子的 19%。因此,对于不同的模型,准确度不再是性能的良好度量,因为如果我们简单地预测所有的例子都属于负类,我们达到 81%的准确度。不平衡数据集的更好指标是AUC(ROC 曲线下的面积)和 f1 分数。但是,这还不够,因为类不平衡会在训练期间影响学习算法,通过隐式学习基于数据集中的多数类优化预测的模型,使决策规则偏向多数类。因此,我们将探索不同的方法来克服阶级不平衡的问题。

  • 欠采样:通过使正例数和反例数相等,对有或无替换的多数类进行欠采样。欠采样的缺点之一是它忽略了很大一部分具有有价值信息的训练数据。在我们的例子中,它将丢失大约 6500 个例子。但是,训练起来很快。
  • 过采样:通过使正例与反例的数量相等,用或 w/o 替换对少数类进行过采样。我们将使用这种策略从训练数据集中添加大约 6500 个样本。这比欠采样的计算量大得多。此外,由于重复的例子,它更适合修剪。
  • EasyEnsemble:从多数类中采样几个子集,在每个采样数据的基础上构建一个分类器,并组合所有分类器的输出。更多细节可以在这里找到。
  • 合成少数过采样技术(SMOTE):它对少数类进行过采样,但使用合成样本。它在特征空间而不是数据空间上操作。它是这样工作的:
  1. 计算所有少数样本的 k-最近邻。
  2. 随机选择 1-k 之间的数字
  3. 对于每个功能:

a.计算少数样本与其随机选择的相邻样本之间的差异(来自上一步)。

b.将差值乘以 0 到 1 之间的随机数。

c.将获得的特征添加到合成的样本属性中。

4.重复以上步骤,直到我们得到所需的合成样本数。更多信息可以在这里找到。

还有其他一些方法,比如EditedNearestNeighborsCondensedNearestNeighbors,我们不会在这篇文章中讨论,而且在实践中也很少用到。

在大多数应用中,错误分类少数类(假阴性)比错误分类多数类(假阳性)的代价要大得多。在贷款的情况下,向更有可能无法全额还贷的高风险借款人贷款而损失资金,比错过向值得信任的借款人(风险较低)贷款的机会要昂贵得多。因此,我们可以使用class_weight来改变损失函数中误分类正例的权重。此外,我们可以使用不同的分界点将示例分配给各个类。默认情况下,0.5 是截止值;然而,在贷款等应用中,我们更经常看到截止值小于 0.5。注意,改变缺省值 0.5 会降低整体准确性,但是可以提高预测正/负样本的准确性。

我们将使用我们在缺失值部分中使用的相同的随机森林分类器,评估上述所有方法以及没有重采样的原始模型作为基线模型。

Original model's average AUC: 0.652 
Under-sampled model's average AUC: 0.656 
Over-sampled model's average AUC: 0.651 
EasyEnsemble model's average AUC: 0.665 
SMOTE model's average AUC: 0.641

EasyEnsemble 方法具有最高的 10 倍 CV,平均 AUC = 0.665。

构建集合模型

我们将使用三种不同的模型作为基础学习者来构建集合模型:

  • 梯度推进
  • 支持向量分类器
  • 随机森林

集合模型将使用两种不同的方法构建:

  • 混合(平均)集合模型。使基础学习者适应训练数据,然后在测试时,对所有基础学习者生成的预测进行平均。使用来自 sk 的 VotingClassifier 了解:
  1. 使所有基础学习者适应训练数据
  2. 在测试时,使用所有基础学习者来预测测试数据,然后取所有预测的平均值。
  • 堆叠集成模型:使基础学习者适合训练数据。接下来,使用那些经过训练的基础学习者来生成元学习者使用的预测(元特征)(假设我们只有一层基础学习者)。有几种不同的训练堆叠集合模型的方法:
  1. 使基础学习者适应所有训练数据,然后使用用于适应这些学习者的相同训练数据来生成预测。这种方法对过拟合更为有效,因为元学习者会给记忆训练数据更好的基础学习者更多的权重,即元学习者不会产生好的结果,并且会过拟合。
  2. 将训练数据分成 2 到 3 个不同的部分,用于训练、验证和生成预测。这是一种次优的方法,因为保留的集合通常具有较高的方差,不同的分割会产生不同的结果,并且学习算法需要训练的数据较少。
  3. 使用 k 倍交叉验证,将数据分成 k 倍。我们将基础学习者拟合到(k -1)折叠,并使用拟合的模型来生成保持折叠的预测。我们重复该过程,直到我们生成所有 k 倍的预测。完成后,让基础学员适应完整的培训数据。这种方法更可靠,并且给记忆数据的模型更小的权重。因此,它可以更好地概括未来的数据。

我们将使用逻辑回归作为堆叠模型的元学习器。注意,我们可以使用 k-folds 交叉验证来验证和调整元学习者的超参数。我们不会调整任何基础学习者或元学习者的超参数;然而,我们将使用宾夕法尼亚州基准测试论文推荐的一些值。此外,我们不会在训练中使用 EasyEnsemble,因为经过一些实验后,它不会将 Ensemble 模型的 AUC 平均提高超过 2%,并且它在计算上非常昂贵。在实践中,如果模型在计算上变得更加复杂,我们有时愿意放弃小的改进。因此,我们将使用RandomUnderSampler。此外,我们将估算缺失值并预先标准化数据,以便缩短集合模型的代码并允许避免使用Pipeline。此外,我们将使用测试数据绘制 ROC 和 PR 曲线,并评估所有模型的性能。

Figure 4: ROC and PR curves

从上面的图表可以看出,堆叠系综模型并没有提高性能。一个主要原因是基础学习者高度相关,尤其是随机森林梯度增强(参见下面的相关矩阵)。

# Plot the correlation between base learners probs_df = pd.DataFrame(meta_features, columns=["xgb", "svm", "rf"]) corrmat(probs_df.corr(), inflate=True);

Figure 5: Correlation matrix

此外,对于假阴性比假阳性昂贵得多的分类问题,我们可能希望有一个高召回率而不是高精确度的模型。下面是混淆矩阵:

Figure 6: Confusion matrix

让我们最后检查部分依赖图,看看最重要的特征是什么,以及它们与借款人是否最有可能在数据成熟前全额支付贷款的关系。为了便于阅读,我们将只列出前 8 个特征。请注意,部分图基于梯度推进模型。

Figure 7: Partial dependence plots

正如我们所料,年收入较低和 FICO 分数较低的借款人不太可能全额偿还贷款;然而,利率较低(风险较高)和分期付款较少的借款人更有可能全额支付贷款。

结论

现实世界中的大多数分类问题都是不平衡的。此外,几乎所有数据集都有缺失值。在这篇文章中,我们讨论了处理缺失值和不平衡数据集的策略。我们还探索了在 sklearn 中构建合奏的不同方式。以下是一些要点:

  • 对于在任何情况下使用哪种算法,没有明确的指南。适用于某些数据集的方法不一定适用于其他数据集。因此,总是使用交叉验证来评估方法,以获得可靠的估计。
  • 有时我们可能愿意放弃对模型的一些改进,如果这会增加复杂性,远远超过对评估度量改进的百分比变化。
  • 在一些分类问题中,假阴性假阳性要昂贵得多。因此,我们可以减少分界点,以减少假阴性。
  • 当构建集成模型时,尝试使用尽可能不同的好模型来减少基础学习者之间的相关性。我们可以通过添加密集神经网络和一些其他类型的基本学习器以及向堆叠模型添加更多层来增强我们的堆叠集成模型。
  • EasyEnsemble 通常比任何其他重采样方法执行得更好。
  • 缺失值有时会给模型添加比我们预期更多的信息。一种捕获方法是为每个具有缺失值的要素添加二进制要素,以检查每个示例是否缺失。

原载于 2018 年 3 月 15 日imaddabbura . github . io

用机器学习预测逻辑的歌词

原文:https://towardsdatascience.com/predicting-logics-lyrics-with-machine-learning-9e42aff63730?source=collection_archive---------2-----------------------

从中学开始,当我第一次听到他的歌曲“我所做的一切”时,逻辑就对我的生活产生了显著的影响。这首歌所属的混音带,年轻的辛纳特拉,单枪匹马地让我成为了各种形式的嘻哈音乐的粉丝,向我介绍了我以前从未想过要听的新旧风格。我可以把那个项目中的每一首歌都与初中和高中时的一种特殊感觉或时刻联系起来,无论那是一段无比快乐的时光还是可怕的悲伤。因此,我从来没有遇到过我不喜欢的诗歌或歌曲,所以当我在 5 月份参加的数据科学课上被分配到这个项目时,我立即知道我应该关注哪个音乐家。

与我得到的任何其他编码实验室相比,这个实验室对我来说是最有趣和令人兴奋的,所以我认为写它会很有趣!我将遍历我编写的 Python 代码,然后讨论这个实现的一些优点和缺点,以及将来如何改进它。当然,还要特别感谢加州理工大学分校的 Dennis Sun 教授,感谢他提供了出色的解决方案和帮助,并为探索数据科学分配了如此出色的实验室!

不过,在我们开始之前,明智的做法是 访问此网页快速了解马尔可夫链及其工作原理——这对理解如何处理这个问题至关重要。简单来说,如果我们将天气建模为马尔可夫链,预测明天的天气将只取决于今天的条件。

构建算法

这个实现的关键是创建一个二元模型 马尔可夫链来表示英语。更具体地说,我们的链将是一个 dictionary 对象,其中每个键都是一个惟一的元组,由一个单词及其后面的单词组成。使用二元模型而不是单个单词(unigrams)允许我们提高生成的行的准确性和可读性,因为它定义了我们的模型,使得句子中的下一个单词是基于前两个单词预测的,而不仅仅是前一个单词(稍后有更多细节)。

获取数据

真正的第一步是收集我们将要分析的所有歌词。为了做到这一点,我在网上搜集了 Logic 每首歌的歌词链接,然后浏览每个链接,收集所有相关的文本。最终结果是一个列表,其中每个元素都是一个字符串,包含一首歌的所有歌词。

Web scraping Logic’s lyrics.

每个网页的 URL 只在尾部的页码上有所不同,所以我可以轻松地使用第一个for循环遍历两个页面。我制作的soup变量是来自[BeautifulSoup](https://www.crummy.com/software/BeautifulSoup/bs4/doc/)库的一个对象;它使得从网站上解析和提取数据变得异常简单。在requests库的帮助下,我能够将每个网页的完整 HTML 代码传递给soup。页面上的第一个表格包含了我们需要的所有链接,以便获得每首逻辑歌曲的歌词,所以我使用了另一个for循环来遍历表格中的每一行;因为 HTML 中的超链接由ahref标记表示,所以我能够搜索这些标记来找到每个链接并将其附加到一个links列表中。下一组for循环用于迭代我刚刚获得的每一个links,以获取每首歌曲中的每一段文本,最终让我将每一组song_text添加到一个综合的lyrics列表中。我不得不使用time.sleep函数来确保我不会因为太快发出大量请求而被阻止或禁止。

创建链

终于到了挖掘并开始构建我们的马尔可夫链的时候了。我们编写了一个函数,它遍历 Logic 的所有歌词中的每个单词,以便通过检查两个单词的每个序列并创建每个序列后面的所有单词的列表来生成模型。为了更有效、更实用的遍历,我们使用"<START>""<END>""<N>"标签分别表示歌曲的开始、结束和换行符。

Training our Markov Chain.

这个train_markov_chain函数接收我们之前创建的lyrics列表。我们用键(None, "<START>")初始化我们的chain来标记一首歌曲的开始。你可能已经猜到了,我们从None关键词开始,因为在一首歌的第一个词之前没有任何词。遍历每首歌曲,我们用自定义标签替换歌曲文本中的所有换行符,然后创建一个last_2变量来跟踪迭代过程中遇到的当前/最近的键。然后,for歌曲歌词中的每一个word,我们通过将word连接到当前调来将它插入到我们的链中,然后更新当前调以反映我们正在移动到下一个word的事实。如果这个新键在链中还不存在,我们可以简单地用一个空列表来创建它,以反映它以前没有被见过的事实。一旦歌曲中的最后一首word被处理完,我们就加上一个“<END>”标签,然后继续我们集合中的下一首歌曲。

预测歌词

一旦我们构建并返回了表示马尔可夫链的字典,我们就可以进入算法的最后一部分:生成预测的歌词。从(None, "<START>")键(我们链中的第一个键)开始,我们随机抽样列表中与该键相关的一个单词,然后移动我们当前正在检查的键,以说明我们刚刚抽样的单词。我们继续这个过程,直到最后遇到"<END>"标签。

Predicting new Logic lyrics.

因此,在将所有这些代码放在一起之后,我们可以print(generate_new_lyrics(chain))在控制台中显示我们预测的歌词。如果你想自己运行所有这些代码,你可以查看我的 GitHub 库来访问 Python 文件和 Jupyter 笔记本。

然而,需要注意的是,因为我使用简单的随机抽样来创建新的歌词,所以我也随机选择了我实际接收到的输出。有少数情况下,我收到的输出少于一行,甚至只有一个单词,但大多数时候,算法打印出了大量的预测歌词。尽管如此,在搜索了我从该算法的多次运行中收到的输出后,我得到了一些非常好的歌词,从原始的妙语到彻头彻尾的滑稽讽刺。下面你会发现我最喜欢的几个,我相信所有这些都非常符合 Logic 的风格(除了一些有趣和/或怪异的,我觉得有义务包括在内)。

“在她爱抽烟的日子里,是的,她渐渐消失了”

“所以我对这种景象直喘粗气,黑夜是我的分工”

“我会告诉他们如何行动,我会站起来,然后在后面”

"赞美黑耶稣,现在他们叫警察了,看在我是道具的份上"

“我很清楚他生来就有热量,岩石比混凝土更坚固”

“宝贝女儿我能找到人性吗?”

“把我的一切都丢到街上,更别说热了”

"这位先生最好知道联邦调查局在窃听"

"我的生活不属于我,我需要你来拯救我"

“每个人都在寻找街道,更不用说热”

"我会一直说唱你们所有人?我离开是有原因的

“哦,我的,我的,我的,感觉这邪恶的氛围”

“但我乘公共汽车离开我的问题,上帝帮助我解决它们”

"现在我祈祷有人来拯救我,不管你相信什么是对的"

“你会失去一切,就像一个该死的国王”

“卒往往在没有拨号音的情况下继续”

“是啊,知道吗?我会让死去的总统代表我

"我所过的生活,只是一个门面"

"她不想再哭了,穷困潦倒,不知天高地厚"

“我看到自己在卢浮宫,我知道我的心在捉弄我”

"我觉得我在扼杀我的梦想,生命在消逝"

“为什么没人想说我会说唱”

"就像魔术师在路边胡言乱语"

"我工作室里的朋友,我在公路上漫步"

“这说唱是另一天,另一本书”

“我见过好人,他们能像其他人一样下雨”

"我知道从哪里开始杀人"

"哟,我会保留所有这些新的剩余残渣"

“相信我,女孩,我不会生气,如果你听到不同的人说谎”

"人们认为他们和他一样高,他们还没准备好喝更多的酒"

"任何和我一起骑车的人现在都想这样"

分析我们的结果:优势和劣势

通过观察我们的 bigram 实现和 unigram 实现的许多输出,我们可以得出一些重要的结论:

  1. 我们模型的预测是准确的,但经常被重复利用。值得注意的是,我们预测的许多台词与 Logic 实际编写的台词几乎相同,即一首诗/歌中的半句台词与另一首诗/歌中的半句台词相结合。这是可以预料的,因为使用二元模型在预测的单词中产生较少的可变性,这是由于基于前两个单词而不是最近的一个单词进行预测,导致来自相同逻辑歌词的三个或更多单词的序列。简单地说,用双字代替单个单词增加了可读性和与逻辑风格的相似性,但降低了创造性。
  2. ***我们的型号速度较慢,产出较少。*unigram 模型运行速度更快,因为表示其马尔可夫链的 dictionary 对象的键要少得多。我们的模型有更多的键,因为它必须处理两个单词的元组。此外,正如我前面提到的,有时我收到的输出很少甚至没有,而且通常比我从 unigram 实现中收到的要少。这可以归因于当前两个单词的基础上,下一个单词的可能性较少。

那么,我们该何去何从呢?我们强调了实施的优势和劣势;我们如何减轻这些缺点并使我们的模型变得更好?识别限制我们建立的模型的中心马尔可夫假设是发现优秀设计的关键。

找到更好的方法

用马尔可夫链对情况建模需要假设情况本身满足一个关键陈述:对下一个状态的预测只取决于当前状态的状态,而不是情况历史的其余部分。例如,使用马尔可夫链预测明天的天气需要得出这样的结论,即过去两周或更长时间的天气对明天的情况没有影响——我想我们都同意这听起来很牵强。因此,即使使用二元模型帮助我们降低了模型中这一假设的重要性,它的影响仍然普遍存在,削弱了我们的结果。我们需要找到一种替代模型的方法,至少可以减少假设。

一个递归神经网络是我们可以使用的替代的一个例子。虽然我不会在这里详细介绍 rnn,主要是因为我自己仍然只是对它们进行了初步的了解,但我将提供一些简要的说明。rnn 的两个关键特征是,它们不假设所有输入都是相互独立的,并且它们能够保存它们所处理的内容的历史,这两个特征对于改进我们的模型都是必要的。关于 rnn 如何工作以及如何实现它们的更多信息,请查看维基百科页面以及本教程;我将从这两者中学习,最终更新我的代码以获得更好的预测。

如果你已经做到了这一步,感谢你阅读并一瞥我对机器学习日益增长的兴趣!数据科学作为一个整体已经有如此多的迷人和创造性的应用。随着我在更多项目中的工作和作为一名开发人员的不断进步,我期待着进一步探索许多细微差别和错综复杂的细节。毕竟,正如罗辑曾经写的(以及他之前的保罗·布兰特),当月球上有脚印时,天空怎么可能是极限?

Philadelphia, June 2013

特别感谢我的姐姐 Kelsi Kamin 在我写这篇文章的时候给了我动力和建设性的反馈!

预测 MLB 比赛的上座率

原文:https://towardsdatascience.com/predicting-mlb-game-attendance-c36cdc1b8de6?source=collection_archive---------5-----------------------

Minute Maid Park, Houston, TX

每支 MLB 球队在大约六个月的时间里每个赛季打 162 场比赛,这意味着在整个赛季中,我们很可能会看到球迷的上座率有相当大的差异。我决定看看历史比赛数据,看看哪些因素可能在球迷投票率中发挥作用,然后根据我的发现建立一个模型来预测给定比赛的上座率。当试图想象什么会影响出席率时,我想到了一些事情。第一个对我来说很明显,那就是谁在比赛,但更具体地说,主队是谁。不同的球迷群体有不同的倾向,这意味着这些球队的上座率将有不同的分布。除此之外,我还想象了许多其他因素对上座率的影响,比如球队在和谁比赛,球队在那个赛季表现如何,他们比赛的体育场的容量,一年中的时间,以及比赛在一周中的哪一天进行。

我通过刮 baseball-reference.com 收集了 1990 年到 2016 年所有 MLB 游戏的游戏数据。棒球参考有很多关于每场比赛的重要信息,例如球队在赛季中该点的记录,以及他们的连胜记录,分区排名,他们落后多少场比赛,是晚上的比赛还是白天的比赛等等。在收集数据时,我设计了一些我认为可能与出勤率相关的特征,例如球队的总体胜率、他们十场比赛的胜率、球队每场比赛的平均得分次数,以及过去五场比赛中允许的平均得分次数。Baseball-reference.com 也有每个球队的赛季总结数据,其中有有趣的信息,如该赛季球队的经理,球队的最佳球员(通过战争衡量),以及球队球员的平均年龄(按击球手和投手细分)。

当我探索数字变量时,不出所料,我发现一个团队的表现与出勤率直接相关。这些变量包括胜率、比赛场次和分区排名,虽然它们显示出是球迷投票率的预测因素,但上座率仍有很大的差异,如上图所示。查看分类变量,一年中的时间和一周中的日期显示了粉丝出席率的不同分布。正如你在下图中看到的,游戏通常在周末和夏季更受欢迎,这并不令人吃惊。

我分析了赛季总结数据,看看是否有其他变量对出勤率有影响,我对我的发现感到非常惊讶。数据显示,球队击球手/投手的平均年龄与出勤率之间有很强的正相关关系。因此,随着球队击球手平均年龄的增加,每年的出勤率也会增加。我们可以想象一下,如果一支球队由已经在联盟呆了很长时间的球员组成,或者更好的是,在那个特定的球队呆了很长时间,那么球迷可能会喜欢那些球员,这可能会鼓励他们去看更多的比赛。平均年龄也与胜率正相关,这可能是另一个解释。

有了这些知识,我继续构建模型来预测出席率。我决定包括我所有的变量,我建立了一个随机森林回归模型,以及一个梯度推进回归模型。最终,梯度推进模型表现最佳,实现了 0.833 的 R 平方值,这表示实际出席值与拟合的回归线有多接近。下面是我的模型的特征重要性的视觉效果——是粉丝出席率的最大预测因素的前 15 个变量。与球队表现相关的变量,不出所料地出现在这里,比如每场比赛的得分,胜率,以及比赛的回报。总场次代表了一个球队赛季进行到什么程度。令我惊讶的是,团队变量并没有比原来更强的预测力。

Feature Importances

总之,我对我的结果感到满意,并发现这个项目非常有趣。我认为,如果建模过程是为每个团队单独完成的,它可以产生更准确的结果。至于将这些结果应用到现实世界的场景中,我相信一个团队可能会发现这些预测对于制定有效的营销或促销策略非常有用。我做了一些关于比较 MLB 粉丝基础的进一步分析,但是我必须把它留到我的下一篇文章中。

和往常一样,为了让我的分析更深入,这里有一个到我的 jupyter 笔记本的链接。我希望你喜欢这篇文章!

在 TensorFlow 中使用深度学习预测分子活性

原文:https://towardsdatascience.com/predicting-molecular-activity-using-deep-learning-in-tensorflow-f55b6f8457f9?source=collection_archive---------1-----------------------

我在 STEM 领域有丰富的背景,在过去几年里,我看到了使用机器学习来解决具有挑战性的科学问题的热潮。但是,无论是 STEM 领域还是机器学习领域,都比较难有精深的知识。例如,如果你是一名材料科学家或生物化学家,你可能会花大部分时间思考如何设计实验和如何收集数据。你听到现在每个人都在谈论机器学习,觉得它真的很酷。但是,你并不知道以你的理科背景,如何潜入这个新兴的领域。这篇文章来了。它将提供一个全面的演示,通过 TensorFlow 库使用深度学习来解决默克分子活性 Kaggle 挑战

1。 问题描述

预测新化合物的活性是制药公司在开发新药时遇到的真正挑战。在药物发现过程中,标准的做法是扫描一个大的化合物库,以测试它们对预期靶分子和外周非靶分子的生物活性。希望化合物具有高度特异性,以便具有高效能并使副作用最小化,也就是说,它应该对靶分子具有高活性,而对非靶分子表现出低活性或无活性。这个过程可能非常耗时且昂贵。因此,希望定量预测化合物与靶分子和非靶分子之间的这种生物活性。这种预测可以帮助确定实验的优先次序,减少需要进行的实验工作。事实上,这种预测被称为定量结构-活性关系(QSAR) ,在制药行业中非常常用。

QSAR 方法具有以下特点:

1)制药环境中的数据集通常包含大量化合物。例如,在这次默克数据挑战中,每个目标都针对 20,000 多种化合物进行了测试。

2)每种化合物通常由一系列特征或指纹描述符来表示。这些指纹通常描述分子的内容、化学和分子拓扑,并由特征向量编码。例如,内容和化学可以包括碳和氮原子的数量、氢键供体和受体、电荷、极性和非极性原子以及官能团(酮、羧酸等)的描述符。拓扑包括特定半径内哪些原子与哪些其他原子键合(即分子图的子图)。Kaggle 上描述的 Merck challenge 没有给出所使用的特定指纹,只有作为原始数据的特征向量。

3)每组化合物可能涉及总数数千个指纹描述符。因此,描述每个化合物的向量是稀疏的,只有一小部分是非零的。

4)这些描述符并不都是独立的。根据化合物的结构,不同的描述符之间可能存在很强的相关性。

2。 客观&数据

本次默克数据挑战的目标是,根据化合物化学结构产生的数字描述符,确定预测化合物针对特定分子的生物活性的最佳统计技术。

默克公司提供的数据基于 15 种目标分子和每个目标的 10,000 多种化合物。对于每个目标分子,每一行数据对应于一种化合物,并包含从该化合物的化学结构衍生的描述符。目标分子和每种化合物之间的活性在训练数据中提供,并且是测试数据中预测的目标。

3。 评估指标

将使用 15 个数据集的平均相关系数 R^2 来评估活动预测。对于每个数据集,

其中 x 为已知活性, x 为已知活性的平均值, y 为预测活性, y 为预测活性的平均值, Ns 为数据集 s 中的分子数。

4。 方法和解决方案

鉴于目标变量 activity 是连续的,每个数据集包含数万个条目,这是一个回归问题,我将使用 Python 中的 TensorFlow 库构建一个神经网络(NN)来进行预测。在这项工作中,成本函数被定义为均方误差或 MSE。

以下是本工作中所考虑因素的总结:

4.1 每个目标分子或所有目标分子的一个模型

理论上,合并所有 15 个分子的数据并训练通用模型将是理想的,因为将使用大得多的训练数据,并且模型可能表现得更好。然而,在这个特殊的问题中,这 15 个目标分子在结构和活性上可能彼此非常不同。因此,一个靶分子的数据如何对另一个分子的训练模型有用,这不是直接直观的。考虑到计算能力的限制,每个目标分子的一个模型可能是优选的。或者,我们可以训练一个好的模型,并将其应用于所有 15 个数据集。 作为展示,在这项工作中,只训练和优化第一个目标分子的模型。

4.2 数据预处理

4.2.1 目标

训练数据具有 37k 个条目,其中超过 20k 个具有相同的活动值 4.30,其余的在 4.30 和 8.5 之间(图 1)。

Figure 1. Histogram of activity values in the training data for molecule 1.

这是因为在数据收集过程中设置了一个阈值。例如,由于实验限制,任何低于 4.30 的数据都不会被收集或映射到 4.30。因此,大部分目标数据被截断,并且 NN 可能存在预测输出为单个值的问题。尝试以下预处理步骤:

1)没有预处理

2)删除目标值为 4.30 的所有条目

3)随机移除所有条目的 90%,目标值为 4.30

其中,1)似乎给出了最高和最一致的 R^2 值,可能与将最大量的输入数据输入到神经网络有关(图 2)。因此,不对目标 y 进行预处理。然而,优化器显然在数据集上遇到了困难,我将在 4.3.5 节中谈到这一点。

Figure 2. R^2 value for 8 runs of the same neural network with the full training dataset or partial dataset with all entries with a target value of 4.30 removed.

4.2.2 特征数量

每个条目有 9491 个特征,并且大多数特征向量有大量的零。尝试以下预处理步骤,以便移除琐碎信息并加速模型的训练过程:

1)没有预处理

2)过滤掉方差低于阈值的特征。例如,5e-4 的阈值将移除 3.31%的特征。

3)使用主维度减少(PCA)来减少维度(例如,减少到 6000 而不是 9491 个特征)

结果是 1)和 2)给出了可比较的 R2,而 3)给出了较低的 R2 值。因此,在以下结果中,不会对特征进行预处理。

4.2.3 描述符

所有描述符都是非负整数。描述符转换的选项有:

1)无转换

2)对数变换,即 y = log(x + 1)

3)二元变换,即如果 x > 0,y = 1,否则 y = 0。

图 3 示出了对于上述三个不同的处理步骤,成本函数如何随着时期数而变化。很明显,描述符 x 的二进制或对数变换将把成本函数降低到 0.2 以下,并且随着历元数的增加振荡更少。值得一提的是,高于 0.2 的成本函数通常意味着 R^2 接近于 0。

Figure 3. Change of cost function with increasing epoch number for three different x preprocessing.

使用描述符 x 的对数和二进制变换来获得可比较的 R^2 值(大约 0.6)。因此,描述符 x 的对数变换用于训练过程的剩余部分。

4.3 神经网络的参数

4.3.1 神经网络的架构

每个神经网络至少有三层:输入、隐藏和输出。对于输入,只有一个输入层,其神经元数量由训练集的形状唯一确定。对于这个问题中的回归,神经网络只有一个输出层,并且只有一个节点和一次函数作为它的激活函数。

确定隐藏层的数量至关重要。虽然一个隐藏层对于大多数问题是好的,但是具有一个隐藏层的 NN 给出大约为 0 的 R2 值或无意义的值 NAN,因为所有预测的目标值完全相同。在不优化超参数的情况下,将隐藏层的数量增加到两个可以得到大约 0.56 的 R2。因此,优选具有两个隐藏层的 NN。

至于每个隐藏层中神经元的数量,最常见的经验法则是“隐藏层的最佳大小通常介于输入层的大小和输出层的大小之间”。图 4 在多次训练试验中比较了在隐藏层中具有不同节点数的 4 个不同 NN 的 R2 值。在第一和第二隐层中分别具有 5 和 2 个节点的神经网络与其他三个具有更多节点的神经网络具有相似的最大 R2 值(~ 0.6),但是它有三次试验具有低得多的 R2,这表明具有少量节点的神经网络的不稳定性。在第一和第二隐藏层中具有 50 和 25 个节点的 NN 在 8 次试验中显示出最一致的结果,平均 R2 为 0.568,标准偏差为 0.027。第一和第二隐层节点数分别为 100 和 50 的最大 NN 在 8 次试验中也表现出不一致性,1 次无意义 R2 和 1 次 R2 接近 0。这可能是因为 300 个历元不足以让较大的 NN 持续达到其全局最小值。事实上,神经网络越大,它需要运行的时期就越多,以获得持续的像样的 R^2.理想情况下,我们希望在计算能力允许的情况下运行一个神经网络,直到我们看到优化器收敛到一个解。

Figure 4. R^2 value in different trials for NN with 2 hidden layers and different node numbers ((5, 2), (10, 5), (50, 25), (100, 50) for the first and second hidden layer respectively.) 300 epochs are run for each NN.

4.3.2 激活功能

激活函数的实际作用是使神经网络能够模拟复杂的非线性函数。如果没有非线性激活函数,神经网络将等同于线性函数。在这个特殊的问题中,ReLu 和 Sigmoid 被尝试作为激活函数。ReLu 比 Sigmoid 性能更好,用于所有隐藏层。当使用 Sigmoid 激活函数时,成本函数确实不收敛。这可能是因为 Sigmoid 激活函数将所有输出限制在 0 和 1 之间,从而抑制了 NN 对该特定问题的训练能力。

线性激活用于输出层,这是为回归问题训练 NN 的常见做法。

4.3.3 学习率

神经网络的输出对梯度下降的初始学习速率非常敏感。我以 0.05 的学习率开始,并注意到成本函数要么发散,要么迅速超过最大浮点数,给出 NaN。降低学习率会降低成本函数,然而,成本函数容易陷入局部最小值(例如,24.085、22.220、14.683)。只有当学习率下降到 0.001 时,我才开始看到超过 0.1 的成本和 R^2 值的一致输出。因此,学习率保持在 0.001。

4.3.4 权重和偏差

考虑到成本函数很容易陷入局部最小值,从优化的权重和偏差开始也很重要。我们优化的权重和偏差是来自截断正态分布的随机值,平均值为 0,标准差为 1。[-2,2]之外的值将被删除并重新选取—这一步对于获得一致的结果非常重要。

4.3.5 优化器

Adam 优化器被证明是最好的优化器。最初使用的是随机梯度下降,但是大多数时候成本函数会陷入局部最小值(例如 0.45)。降低学习率和增加动力并没有多大帮助。在将优化器切换到 Adam(自适应矩估计)优化器之后,成本函数开始下降到小于 1,并且收敛。Adam optimizer 为每个参数计算自适应学习率,并保持过去梯度的指数衰减平均值。它通常是输入数据为稀疏矩阵的神经网络的首选优化器。

然而,代价函数(MSE)仍然会陷入局部最小值。例如,图 5 示出了成本函数和 R2 值随着具有两个隐藏层(分别具有 1000 和 500 个节点)的神经网络的时期数的增加而变化。在时期 865,成本从低于 0.2 到高于 0.4 进行了一个小跳跃,进入一个尖锐的局部极小值,并且再也没有恢复。R2 后来真的很糟糕,而在公元 865 年之前它要好得多。成本函数前景可能包含许多非常尖锐的局部最小值,因为我们经常看到训练试验在 R^2 差的情况下被困在 0.4-0.5 MSE 左右(参见图 4 中的一些示例)。这种跳跃现象在所有模拟中都是随机发生的,很难控制。因此,对于每个优化的模型,我通常会运行多次,以获得一致的结果。

Figure 5. Change of cost function and R^2 value with epoch number. The NN has 2 hidden layers with 1000 and 500 nodes respectively. All other parameters of the NN is optimized as shown in this report.

4.3.6 辍学

在神经网络中,放弃是防止过度拟合的常用策略。优化结果是在隐藏层中随机丢弃 25%的神经节点而在输出层中没有丢弃的情况下实现的。

5。 总结

总之,给出最高 R^2 值的优化神经网络具有以下特征:

  • 所有训练数据和所有描述符都是在没有任何过滤过程的情况下使用的。
  • 描述符 x 的对数变换和目标 y 的无预处理。
  • 神经网络有两个隐藏层。第一和第二隐藏层分别具有 50 和 25 个神经元。
  • ReLu 用作所有隐藏层的激活功能。线性激活函数用于输出层。
  • 学习率保持在 0.001。
  • 权重和偏差是截断正态分布的随机值,平均值为 0,标准差为 1。[-2,2]之外的值将被删除并重新选取。
  • 使用了 Adam 优化器。
  • 所有隐藏层使用 25%的丢失率,输出层不使用丢失率。
  • 批量大小为 300,纪元编号为 900。

测试数据(从训练数据中分离出 20%)的最高 R2 值是 0.568 +/- 0.027。Kaggle 领导委员会显示,所有 15 个分子的最高平均 R2 分数为 0.494。与那个结果相比,从神经网络得到的 R^2 值是适当的和令人满意的。

请查看这个 GitHub 库,获取所有代码和补充信息。如果您有任何问题,请随时留言或联系我。

预测莫斯科房价

原文:https://towardsdatascience.com/predicting-moscow-home-prices-5b1e82438214?source=collection_archive---------2-----------------------

俄罗斯最大的银行俄罗斯储蓄银行(Sberbank)强调,需要准确预测房价,以便投资者、购房者和开发商在签署租约或进行投资时能够更加放心。在 2014 年欧盟、美国、加拿大和澳大利亚实施制裁后,他们对预测分析的呼吁尤其合理。此后,俄罗斯卢布大幅下跌,金融危机仍在持续。这给严格根据家庭特征进行预测带来了挑战,因此 Sberbank 纳入了大量宏观经济数据。现在,让我们深入研究数据。

作为我的 EDA 的一部分,在每个都有 293 个变量的训练和测试数据集中,几个问题立即变得明显。就缺失数据而言,我可以生成一个条形图,其中包括每个特性缺失数据的百分比。51 个要素缺少值。百分比最高的是每区医院床位、建造年份、最大楼层和材料。

在深入了解 EDA 之前,我还应该注意,训练数据得出的平均房价是₽ 7,123,035.00,标准差是₽ 4,708,111。

我确实遇到了一些数据质量问题。有一年被列为 2005 年至 2009 年,所以我把它改为 2007 年的中间值。我以为 4965 年应该是 1965 年。有一个称为 condition 的分类值,它是不言自明的,从 1 到 4 对属性进行评级(1 是最差的,4 是最好的)。有一个值是 33,所以我把它改成了 3。

在生成室内功能热图后,全平方米、生活平方米和地板对价格的影响最大,其中每个都以平方米为单位,而生活平方米是不包括阳台、门廊等的总平方米。在 37 例中,生活平方英尺大于全平方英尺。面积和价格之间的相关性如下所示(离群值省略)。

当我查看房价中值时,发现 2015 年早期出现了显著的繁荣。对我来说,这似乎没有意义,需要一些背景研究。显然,莫斯科的房地产价格与世界商品市场上的石油直接相关。因此,销售增长在 2015 年停止,市场走向破产。见下文。

就何时购买而言,房价往往在 3 月和 5 月最高,11 月最低。

很明显,条件等级为 4 的房子卖得最多。

现在让我们按楼层来看房价。

存在适度的正相关。

还有一个功能叫做 max floor。我观察了一下,看看建筑的高度是否会影响价格,但影响并不明显。我注意到的是有超过 1000 个错误,其中单元的楼层大于最大楼层。奇怪!

接下来是一些人口统计数据——我查看了人口密度,看看房价是否随着人口密度的增加而上涨(确实如此),以及哪些地区的交易最频繁

现在让我们来看看是否靠近一所大学、一个体育目标(从体育场到篮球场等不同的事物)或克里姆林宫很重要。

作为我的 EDA 的最后一个组成部分,我想看看基础设施的特性。水处理的邻近性是唯一一个对价格有轻微积极影响的特征,这意味着你离得越远,你的房屋价值就越高。这是一张热图。

在看了所有的数据后,我决定进行一些特征工程。我通过从建造日期中减去年份创造了“建造年代”。我想看看一些定量指标,比如居住面积与总面积的比率,以及厨房面积与总面积的比率。接下来,我想看看大楼的楼层数与大楼的楼层数之比。最后我想看看这个单元离顶楼有几层。

我使用 RSME 作为评估指标运行 XG Boost。这给了我每一个属性的预测。下面你可以看到原分布两套并列。(请记住,科学符号使测试价格分布看起来比实际小得多)

测试价格分布

预测分布

预测 MS 入院

原文:https://towardsdatascience.com/predicting-ms-admission-afbad9c5c599?source=collection_archive---------3-----------------------

Credits: Pexels

快到录取季节了,我有几个朋友正处于恐慌状态,等待他们申请的大学的电话。这让我想到——我们如何预测一个学生是否会被录取?选择的参数是什么?可以用数学表达吗?所有这些问题开始出现,所以我决定解决这个问题,并帮助我的朋友平静他的神经。
(这是我写的第一个技术教程,所以请对我宽容些)。

为了解决这个问题,我将带你通过我称之为
“数据科学管道”。给定任何问题陈述,遵循这条管道,这样你的方法就结构化了。

  1. 定义问题-

写下问题陈述,理解你试图解决的问题。在这种情况下,我们的目标是预测学生是否会被录取。这意味着,这是一个二元分类问题。

2。生成您自己的假设-

接下来,列出你认为会影响我们目标的所有事情,即。列出与我们的目标特性相关的所有可能的特性。
在我们的案例中,我们被问到这个问题— 影响学生录取的因素有哪些? 拿一张纸,写下自己的假设。我花了一些时间,想出了以下特点

  • GRE 成绩
    -托福成绩
    -目的陈述(SOP)
    -推荐信(LOR)
    -学习成绩(GPA)
    -课外活动(体育、奥数等..)
    -杰出成就
    -项目和研究
    确保你写下至少 10-20 个问题陈述。这有助于我们更深入地理解我们试图解决的问题,并促使我们超越现有的数据集进行思考。

3。获取数据集-

下一步是获取数据。我们使用加州大学洛杉矶分校的假设数据进行研究生招生。你可以点击下载数据集。现在你可以用给定的数据集来映射你的假设。查看可以添加或修改多少要素来提高数据集的质量。将每个特征识别为
(a)连续变量或(b)分类变量

(Source: Stack Exchange)

4。数据清理-

大多数时候,数据集会有很多异常,比如缺失值、异常值等等。在进入下一步之前,一定要对数据进行预处理。
--缺失值处理: 您可以使用均值插补(对于连续变量)或模式插补(对于分类变量)

  • 异常值处理: 异常值异常值是随机样本中与其他值存在异常距离的观察值。

有四种方法来处理它——删除观察值、估算、创建箱和分别处理。
--特征工程:-组合、添加、删除、分割、缩放特征以增加模型的精度

5。探索性数据分析(EDA) -

现在是我们动手的时候了。让我们探索数据并理解给定的特征。
该数据集有一个名为admit的二元响应(结果,相关)变量。有三个预测变量:gregparank。我们将变量gregpa视为连续变量。变量rank取值 1 到 4。排名 1 的机构声望最高,排名 4 的机构声望最低。

EDA 帮助我们清楚地了解我们的功能。它还帮助我们捕捉数据点的任何趋势或季节性。
在我们的案例中,我们可以看到 GRE 分数和 GPA 越高,被录取的机会就越大。

6。
预测建模-这是一个二元分类问题。输出只有两种可能,要么是(1) 要么否(0)。有很多分类算法,那么我们如何知道哪一个是最好的呢?我们没有。这是需要经验和专业知识的。不过,别担心,我们还有工作要做。我们可以将多种算法应用到我们的数据点上,然后评估模型。这样我们可以选择误差最小的最佳模型。首先,让我们导入所有必要的库

from matplotlib import pyplot
from sklearn.model_selection import train_test_split
from sklearn.metrics import classification_report
from sklearn.metrics import confusion_matrix
from sklearn.metrics import accuracy_score
from sklearn.model_selection import KFold
from sklearn.model_selection import cross_val_score
from sklearn.linear_model import LogisticRegression
from sklearn.tree import DecisionTreeClassifier
from sklearn.neighbors import KNeighborsClassifier
from sklearn.ensemble import RandomForestClassifier
from sklearn.discriminant_analysis import LinearDiscriminantAnalysis
from sklearn.naive_bayes import GaussianNB
from sklearn.svm import SVC

我们将使用交叉验证作为评估指标,我们将把数据集分为训练和测试两部分。

**#Step 1: Convert Dataframe into matrix**
dataArray = dataset.values**#Step 2: Splitting Input features & Output Variabl**es
X = dataArray[:,1:4]
y = dataArray[:,0:1]**#Step 3: Splitting training & testing**
validation_size = 0.10
seed = 9
X_train, X_test, Y_train, Y_test = train_test_split(X,y,test_size=validation_size, random_state = seed)print(X_train.shape)
print(X_test.shape)
print(Y_train.shape)
print(Y_test.shape)

接下来,我们将对我们的训练数据应用以下机器学习算法
-逻辑回归(LR)
-线性判别分析(LDA)

  • K 最近邻(KNN)
    -决策树(CART)
    -随机森林(RF)
    -高斯朴素贝叶斯(NB)
    -支持向量机(SVM)
    初始化最大数量的特征和数量的树。
num_trees = 200
max_features = 3
models = []
models.append(('LR', LogisticRegression()))
models.append(('LDA', LinearDiscriminantAnalysis()))
models.append(('KNN', KNeighborsClassifier()))
models.append(('CART', DecisionTreeClassifier()))
models.append(('RF', RandomForestClassifier(n_estimators=num_trees, max_features=max_features)))
models.append(('NB', GaussianNB()))
models.append(('SVM', SVC()))**#Fit Models and Evaulate**results = []
names = []
scoring = 'accuracy'**#Cross Validation**
for name, model in models:
 kfold = KFold(n_splits = 10, random_state=7)
 cv_results = cross_val_score(model, X_train, Y_train, cv=kfold, scoring = scoring)
 results.append(cv_results)
 names.append(name)
 msg = "%s: %f (%f)" % (name,cv_results.mean(), cv_results.std())
 print(msg)

我们在这里所做的是在我们的数据点上运行所有 7 种算法,并尝试对其进行评估。如你所见,LR 和 LDA 表现最好。我们也可以实现一个比较图

现在,我们已经将 ML 算法应用到我们的数据集上。接下来,我们必须使用最佳算法创建一个预测模型。
为了简单起见,我打算选 LR。

**#Step 1 - Create prediction model**
model = LogisticRegression()**#Step 2 - Fit model**
model.fit(X_train, Y_train)**#Step 3 - Predictions** 
predictions = model.predict(X_test)**#Step 4 - Check Accuracy**
print("Model --- LogisticRegression")
print("Accuracy: {} ".format(accuracy_score(Y_test,predictions) * 100))
print(classification_report(Y_test, predictions))

我喜欢制造情节。所以让我们再做一个;)

**#plotting confusion matrix on heatmap**
cm = confusion_matrix(Y_test, predictions)
sns.heatmap(cm, annot=True, xticklabels=['reject','admit'], yticklabels=['reject','admit'])
plt.figure(figsize=(3,3))
plt.show()

恭喜你!您制作了我们自己的预测模型,准确率为 77.5
(对初学者来说一点也不差)
您可以尝试通过安装不同的分类算法或进行一点点特征工程来提高这个分数。
最好的方法是使用集成方法,但那是其他教程的内容。

但是等等…
我们怎么知道这行得通呢?
是的,完全正确吗?我们已经走了这么远,怎么能不让我们的模型做出一些预测呢!

**#Making predictions on some new data
#Like a boss**
new_data = [(720,4,1), (300,2,3) , (400,3,4) ]**#Convert to numpy array**
new_array = np.asarray(new_data)**#Output Labels**
labels=["reject","admit"]**#Let's make some kickass predictions**
prediction=model.predict(new_array)#G**et number of test cases used**
no_of_test_cases, cols = new_array.shapefor i in range(no_of_test_cases):
 print("Status of Student with GRE scores = {}, GPA grade = {}, Rank = {} will be ----- {}".format(new_data[i][0],new_data[i][1],new_data[i][2], labels[int(prediction[i])]))

仅此而已。我们自己的预测模型可以决定你朋友的未来(事实上不可以)
但是我们的模型绝对可以预测他/她是否会被录取!

DSW 背后的动机

我从一年前开始学习和研究数据科学。在此期间,我做了大量的问题陈述。但问题是,有时数据集非常有趣,但有时却不是。你必须关心你试图解决的问题,只有这样你才能做好工作。

所以找一个你想解决的问题,用数据来解决它。

你可以在 Github 上找到本教程的代码

我将每周写下一些很棒的教程,所以如果你是那种只能通过做来学习的人,请在这里关注我的 出版物。

也可以在 LinkedIn 上联系。

我希望你有一个富有成效的一周。

在那之前,继续 hustling!

预测 NBA 胜率

原文:https://towardsdatascience.com/predicting-nba-winning-percentage-in-upcoming-season-using-linear-regression-f8687d9c0418?source=collection_archive---------5-----------------------

我们在 Metis 的第二个项目叫做 Project Luther,它是关于网络抓取和线性回归的。

我是一个超级篮球迷,所以我立即想办法把这项运动和这个项目结合起来。经过几个小时的头脑风暴后,我决定尝试创建一个模型,在赛季开始前预测某个 NBA 球队的胜率。我的目标是尝试采用这种模式,看看是否有人可以利用它通过赌博赚钱。

数据采集和初始步骤

我想使用前几个赛季的球队统计数据和任何其他在赛季开始时可以得到的球队信息。我决定从网站 basketball-reference 获取我的统计数据和信息。这个网站有过去几十年每一季的大量统计数据。我最终获得了大约 40 年的各种统计数据,包括整体球队统计数据、教练信息和球员信息。我用 BeautifulSoup 从网站上搜集了这些信息。

一旦我有了一个熊猫数据框架中的数据,我立即分离出一部分数据用于最终测试。我选择搁置 2018 赛季,因为我想把我对那一年的预测与赌博数据结合起来。然后,我运行一个基线线性模型来获得一个起点。我选择的特征是上一个赛季的平均胜率,因为我觉得这可以很好地预测下一个赛季的成功。

微调我的模型

我的下一步是尝试运行我所有的功能在一起。这稍微增加了我的 R 值,但是我的模型现在有超过 30 个特征。我开始删除那些似乎无法改善我的模型的功能。事实证明,有相当多的功能,我可以删除,而不会降低我的 R 值非常多。

在缩小了我的特征列表后,我尝试添加多项式项,看看是否可以改进我的模型。大多数情况下没有,但有两个特定的多项式要素略微增加了 R。在我的要素工程中,我使用套索交叉验证来测试我的模型,并继续移除不需要的要素。

最终模型

最终,我的最终模型包含了套索正则化,并包含了球员的平均年龄、胜率、得分数、回归球员数和盖帽数等特征。

Metrics for final model

R 没有我希望的那么高,但是考虑到这个问题,这可能是可以预期的。均方根误差乍一看很棒,直到你记得我预测的是一个百分比。RMSE 相当于一个赛季 82 场比赛中的 9 场,这是相当可变的。该模型最重要的特征是胜算和玩家的平均年龄,这并不奇怪。

将模型应用于赌博

我的下一个问题是,这种模式可以用来赌博赢钱吗?我从一个赌博网站刮来了超额/欠额赌注。如果你不熟悉体育博彩,我将简要解释过度/不足投注。维加斯给每支球队在即将到来的赛季中的预期胜场数,然后你打赌这支球队会赢更多的比赛(多)或赢更少的比赛(少)。如果你最终是正确的,你就赢了。

我最初根据赌博信息测试了我对所有球队的预测,只有 50%是正确的,就像掷硬币一样。有趣的是,如果我只关注我的模型预测非常接近拉斯维加斯超额/不足数的八支球队,我的正确率为 87.5%。这看起来很棒,但在相信这个数字不是偶然之前,我想在其他年份进行测试。

模型错在哪里?

由于我的模型不擅长预测,我决定看看是否有具体的原因。下面的残差图表明,我的模型在实际胜率较低时预测过度,在实际胜率较高时预测不足。

我挑选了几个我的模型预测非常错误的例子,并发现有一致的原因。下表显示了球队,年份,我的预测和实际胜率的差异,以及我的预测如此错误的原因。

Examples of when model prediction was very different from actual winning percentage

总的来说,当我的模型严重高估时,球队因为某种原因失去了最好的球员。当我的模型严重低估时,球队在休赛期增加了最好的球员。虽然我的模型考虑了回归球员的数量,但它没有区分超级明星和替补球员。我相信如果我整合了这些信息,我的模型会是一个更好的预测器。

预测自行车共享用户的数量

原文:https://towardsdatascience.com/predicting-no-of-bike-share-users-machine-learning-data-visualization-project-using-r-71bc1b9a7495?source=collection_archive---------2-----------------------

用监督机器学习解决的经典回归问题

背景

这个项目始于我为机器学习课程( EE 660 )所做的最后一个班级项目。随着我对机器学习(ML)概念和实践的理解变得成熟,我彻底更新了它,并在这个过程中将代码从 Matlab 转移到 R 中。我使用的 R 脚本、数据集和图片都可以在我的 Github 上公开获取。事不宜迟,让我们开始吧。

Photo by Kelly Sikkema on Unsplash

定义问题和项目目标

自行车共享系统 是一项服务,用户可以付费或免费短期租赁/使用可供共享使用的自行车。目前,全世界有超过 500 个自行车共享项目。此类系统通常旨在通过在城市地区提供免费/负担得起的自行车短途出行,而不是机动车,来减少拥堵、噪音和空气污染。对于这样的系统,任何一天的用户数量都可能有很大的变化。预测每小时用户数量的能力可以允许监管这些系统的实体(企业/政府)以更高效和成本有效的方式管理它们。我们的目标是使用和优化机器学习模型,这些模型能够有效地**预测在任何给定的 1 小时时间段内将使用的共乘自行车的数量,**使用关于该时间/天的可用信息。

使用的数据集

我们使用的数据集来自加州大学欧文分校的机器学习库。数据集编制者使用了华盛顿首都自行车共享系统 2011 年和 2012 年两年历史日志中的部分信息。该信息可公开获得。编译器每小时和每天汇总数据(供任何有兴趣深入研究的人使用)。接下来,他们从这里提取并添加所有相应的天气和季节信息

我们的数据集是一个 csv 文件(可在 my Github 上获得),包含 731 天中 17,379 个小时的信息,每个小时有 16 个特征(信息类别)。其特点是:

  1. 记录索引
  2. 日期
  3. 季节(1:春天,2:夏天,3:秋天,4:冬天)
  4. 年份(0: 2011,1:2012)
  5. 月份(1 至 12)
  6. 小时(0 到 23)
  7. 节假日:当天是否为节假日
  8. 工作日:一周中的某一天
  9. 工作日:如果一天既不是周末也不是节假日,则值为 1。否则为 0
  10. 天气情况:
    — 1:晴,少云,局部多云,局部多云
    — 2:雾+多云,雾+碎云,雾+少云,雾
    — 3:小雪,小雨+雷雨+散云,小雨+散云
    — 4:大雨+冰盘+雷雨+雾,雪+雾
  11. 以摄氏度为单位的归一化温度。数值分为 41(最大值)
  12. 归一化的感觉温度,以摄氏度为单位。数值分为 50(最大值)
  13. 归一化湿度。这些值分为 100(最大值)
  14. 归一化风速。这些值被分为 67(最大值)
  15. 临时用户计数
  16. 注册用户数
  17. 租赁自行车总数,包括休闲自行车和注册自行车

从一开始看,数据点远远超过特征的数量,这使得这是一个“瘦”数据集,被认为是 ML 的理想选择。

探索性数据分析

在开始用算法处理数据集之前,直观地探索它总是一个好主意。本项目我们将使用。使用 ggplot2gg extra包,我们可以快速绘制一些图表来研究可用功能如何影响自行车使用计数。现在我们来看一些图表。

Scatter plot- Adjusted Temperature vs Usage

Scatter plot- Temperature vs Usage

从上面的散点图可以看出,在大部分温度范围内,使用温度和调整温度之间存在正相关关系,线性拟合与最佳拟合曲线相差不远。这在直觉上应该是有意义的,因为人们不太可能在寒冷的天气骑车外出。对于最高温度,这似乎是数据的一个小的子集,在这条曲线上有一个下降。同样,这应该是有意义的,因为当外面太热时,用户也可能不愿意骑自行车。

Scatter plot- Humidity vs Usage

湿度和使用率之间似乎存在负相关,线性拟合非常接近所有数据的最佳曲线拟合(排除一些湿度非常低的异常值)。这可以用 DC 华盛顿州的气候来解释,那里的气候是出了名的潮湿。较高的湿度与较高的降雨机会相关。我们还可以假设,由于高湿度而增加的排汗会阻止人们在户外骑自行车。基于目前为止的想象,我们假设天气状况会影响自行车的使用,降雨会阻碍自行车的使用,这并不是不合理的。我们下面的图表在一定程度上支持了这个假设。从直方图(在 x 轴上)中注意到,晴天(天气等级 1)比阴天或雨天(天气等级 2 或 3)多得多。

Scatter plot- Weather Situation vs Usage

Scatter plot- Wind Speed vs Usage

然而,查看风速数据并不能给我们一个关于它如何影响使用的清晰解释。这两个因素之间的相关性充其量是微弱的。下面是到目前为止讨论的所有连续变量的相关矩阵,它为我们观察到的趋势增加了一些数字。

****注意:有趣的是,临时使用计数与连续变量更相关,并且与我们之前的假设更一致。如果我们想一想,这是有道理的,因为使用自行车上下班的注册用户不太可能受到不舒服的天气条件的影响。我们可以得出这样的结论:分别预测这两个计数,然后将计数相加得到总计数,这样更有意义。然而,当我尝试这样做时,我发现最终的预测不如我们简单地预测总计数得到的准确。因此,对于项目的其余部分,我们将忽略注册的和临时的计数,只将总计数作为输出。如果你愿意,你可以在我的 Github 上访问数据集和我的代码,并尝试包含这些变量,看看你是否能找到更好的结果。继续下一点。让我们来看看时间和日期是如何影响使用的。

从时间的影响来看,使用率最低的似乎是深夜(凌晨 4-5 点之间最低),高峰是上午 8-9 点和下午 5-7 点,这是 DC 的高峰时段。这种拟合远远不是线性的。但是,通过一些简单的数据操作(下一节将详细介绍),我们可以根据到凌晨 4 点的时间距离来表示使用率,并找到某种程度上的线性拟合(见下文)。
注意:具有线性预测结果的特征是理想的,因为它减少了对复杂的非线性 ML 算法的需要。

在月份与使用情况图(如下)中也可以观察到类似的趋势,在夏季较温暖的月份使用率明显较高,而在一月份使用率最低。通过类似于上一个图的一些操作,该数据也可以用于表示基于到一月份的时间距离的使用情况。然而,这种相关性没有被操纵的时间图那么强。

********

最后,查看“年份”变量(如下),可以看到使用率从第 1 年到第 2 年上升,这可能表明该系统越来越受欢迎。使用此变量时需要注意的一个重要事项是,尽管它在提供的年份范围(2011-12 年)内进行预测时可能有用,但该算法必须进行大量外推才能预测它对未来日期(2018 年及以后)的影响,这可能会使此变量成为不同时间段的不太可靠的预测器。

预处理:数据清理&特征工程

对于任何 ML 项目,预处理数据都是至关重要的一步。该过程通常是广泛遵循的预处理实践的积累,以及根据模型设计人员的判断对数据进行的特定案例调整。如果数据争论不正确或不充分,它可能导致训练不当的 ML 算法提供不准确或(充其量)次优的结果。古老的谚语“垃圾进来,垃圾出去”在这里很适用。这个过程的一个重要部分是特征工程,它包括将可用的数据特征转化为更有用的变量,帮助我们预测结果。让我们走一遍我们正在采取的步骤:

  1. 使用先验知识来删除不添加重要信息的特征,在这种情况下,这只是“索引”特征。
  2. 从日期中提取星期数。在所提供的格式中,日期本身不是我们的算法可以处理的。但是,从这个日期开始,我们可以提取周数(对于特定的年份)并使用该变量作为使用计数的预测值。
  3. 一个热编码,这是将非二进制分类特征(月、周数、小时、天气状况、季节、工作日)分割成多个二进制子特征的过程,其中每个子特征指示原始特征的某个类别是否为真(1 或 0)。如果可能的话,在不使数据集变得“胖”的情况下,最好将每个多分类特征分成多个二进制特征。由于我们有一个包含 17,000 多个数据点的大规模数据集,我们可以扩展这些功能,并且仍然有一个“瘦”数据集,这样我们就不会有过度拟合的风险。请注意,这确实显著增加了我们的数据集的维数,并增加了我们的计算时间,其系数大于 5X。由于我们在这个项目中只使用非复杂的回归算法,我们可以增加计算的复杂性,以提高预测的准确性。
  4. 修改循环变量值以表示距单个时间点的时间距离。正如我们在数据可视化部分看到的,对于循环变量(月/周-数字/小时),试图找到变化值的精确线性模式可能很困难。尽管第 1 周中的数据点在时间上非常接近第 53 周中的数据点,但是与第 53 周相比,第 1 周的最佳线性模型拟合在第 1 周中可能具有非常不同的值。我们通过更改这些值来表示与固定时间点的时间距离来解决这个问题。根据我们在探索性数据分析部分的发现,将基本时间点设置在最少使用时间是合理的。因此,我们使用的时间距离是从凌晨 4 点开始计算小时,从一月中旬开始计算星期和月份。

说明时间序列的随机性

到目前为止,我们一直在处理时间序列数据的确定性方面。对于那些需要复习的人来说,确定性系统是一个在系统未来状态的发展中不涉及随机性的系统。换句话说,确定性模型总是从给定的起始条件或初始状态产生相同的输出。另一方面,如果一个系统是随机的,这个系统的一个或多个部分也具有随机性。我们观察到的大多数时间序列数据通常最好用确定性和随机成分的组合来建模。到目前为止,我们一直在处理我们的模型的确定性方面。现在让我们来看看建模的随机性。

将一个自回归模型整合到我们的特征中是一种解决系统中随机性的简单方法。这是基于这样一个假设,即任何给定小时的用户数取决于之前特定小时数的用户数。这种假设在时间序列数据中通常是有效的。

Ex:Y(t)= B0+B1 * Y(t-1)+B2 * Y(t-2)+**

然而,为我们的模型选择正确数量的滞后值是很重要的。自相关是指一个时间序列中的观测值相互关联的方式,通过当前观测值(Yt)与当前观测值之前的 p 个观测值(Y(t-p))之间的简单相关性来衡量。R 中的自相关函数(ACF)告诉我们当前值和滞后值之间的自相关,并允许我们决定在模型中包含多少滞后值。

ACF results on the count per hour

不出所料,在一小时内的用户数和之前的 2 个滞后值之间确实存在强正相关,在一小时内的用户数和第 3 个滞后值之间存在中等正相关。因此,我们将 3 个滞后值添加到我们的数据集,作为新特征

我们最终用 117 个特征17,377 个数据点中预测每小时自行车使用量

应用机器学习算法

对于这个项目,我们将使用两个比较著名的回归算法:最大似然估计最大后验概率。对于线性回归,我们感兴趣的是找到最佳的参数/权重, w ,使得给定我们的特征,X ,我们的预测结果,Y _ predict = Xw,尽可能接近真实结果, Y_test***

关于构造训练+测试集的注意事项: 在大多数回归问题中,当我们在查看横截面数据时,我们会在选择训练和测试集之前随机化数据点的顺序。然而,当我们处理时间序列数据时,我们必须进行时序检验,因为时间序列排序很重要。我们不能在我们的数据中间切出一块作为测试集,并在这部分之前和之后的数据上进行训练。我们需要在一组比测试数据更老的数据上进行训练。

R 和 Python 中的包允许我们用两三行代码方便地应用 ML 算法。虽然这种方法有其优势,但我认为理解 ML 算法背后的基本统计和概率概念也很重要,以便更好地理解我们的结果。与神经网络等更复杂的模型不同,我们将使用的算法更容易理解和解释。因此,我将非常简要地介绍一下他们每个人正在做什么,如果你愿意,你可以查看我在 Github 上的注释代码,一步一步地了解我们正在做什么。

1)最大似然估计

最大似然估计 (MLE)用于估计概率分布设置中的某个变量。假设我们有一个似然函数, P(D|w) 。这是拥有我们整个数据集的可能性, D ,给定某个符合数据集特征的 wX ,到数据集结果, y 。当我们对 w 进行 MLE 时,我们试图推断的参数是:
w _ MLE
=argmax w
P(D | w)
******

换句话说,我们要找到最大化可能性的 wP(D|w)。 从这里开始,我们可以做一点线性代数,想出一个我们需要的 成本/损失函数 ,以便计算出最佳权重,然后使用导数最小化这个函数(回忆微积分)来寻找最佳权重。有了几个基本假设,我们可以使用下面公式中总结的一种叫做 普通最小二乘法(OLS) 的方法找到最佳参数/权重:

Ordinary Least Squares formula

使用 OLS,我们在称为训练集的数据子集上找到最佳参数。然后,我们在不同的独立数据子集上测试这些参数,称为测试集,以查看我们的预测 yMLE 与实际输出 yTest 相比如何。****

我在这里有意加快了数学步骤,因为:a)有免费的在线资源比我更深入地解释了这些方法,b)在本文中,我们更关注这些算法的应用,而不是它们如何工作背后的统计数据。请注意,您需要对微积分、线性代数和概率分布有扎实的理解,才能彻底理解 MLE 或 MAP。

2)最大后验概率

除了 MLE,我们还将尝试另一种叫做最大后验概率(MAP) 的方法。地图由贝叶斯统计得出,贝叶斯统计是一个基于贝叶斯定理的统计领域:

与基于频率统计的 MLE 不同,MAP 基于这样一种观点,即假设我们对分布有一些有用的先验知识。顾名思义,这适用于后验分布,而不仅仅是可能性。从上面的公式中,我们可以导出由以下公式定义的后验分布:

P(w | D)=(P(D | w) P(w))/P(D)*

假设 P(D) 或者我们的数据集的分布保持不变,我们可以得出结论:

P(w | D)P(D | w) P(w)*

第一部分, P(D|w) ,就是我们之前处理过的可能性项。并且我们假设 P(w) 遵循高斯分布,使得:

weights/parameters are assumed to follow a Gaussian distribution

由于我们实际上没有任何关于权重的先验信息,我们不知道权重分布应该遵循什么样的 m_w (均值)或τ平方(方差)。因此,我们使用嵌套的 for 循环来尝试这些术语的值的一千种不同组合,以在我们的验证集上测试我们的算法。验证集最好定义为训练集的子集,用于在最终测试集上测试参数之前微调参数。遵循我们为 MLE 概述的线性代数、微积分和概率步骤,我们发现每个训练集的由以下公式计算:****

在对验证集的参数进行微调后,我们使用测试集特征上的这些参数来预测地图结果,并将这些预测与 yTest 值进行比较。

评估结果和模型的性能

Scatter plot of MLE predictions for y VS real yTest values

Scatter plot of MAP predictions for y VS real yTest values

汇总统计评测:
MLE
运行时间:0.70 秒
中值预测误差:27.05
平均预测误差:56.53
R 平方值:0.65

运行时间:258.36 秒
中值预测误差:27.93
平均预测误差:57.85
R 平方值:0.63

一个有用的方法是将我们的模型的性能与天真的预测进行比较。简单预测是一种估计技术,其中上一期的值用作本期的预测,没有任何试图建立因果关系的调整。

朴素预测模型 中位预测误差:37
平均预测误差:69.9
R 平方值:0.65

Examining how MLE, MAP and Naive Forecast predictions vary from the real data using a sub-set of the Test data

讨论

从上面的图和值可以看出,MAP 和 MLE 给出了非常相似的结果,正如我们在没有任何关于我们试图导出的目标函数的先验信息的情况下使用 MAP 时所预期的那样。我们发现我们的预测误差中值约为 27,预测误差平均值约为 57。这明显优于朴素预测模型,朴素预测模型的中值预测误差为 37,平均预测误差为 69.9。请注意,用户计数的总体范围是从 0 到几乎 800。

两个模型和原始预测的 R 平方值约为 0.63-0.65。因此,当看这个指标时,我们的模型并不比天真的预测表现得更好。穿过散点图的最佳拟合线非常接近理想值,即穿过原点的梯度为 1 的线。请注意,我们的预测没有一个小于零,因为我们假设使用计数遵循泊松分布,并且我们使用了泊松回归模型。

进一步研究一下,让我们看看我们的测试数据的一个子集,它只有 100 个数据点。我们看到,当总使用计数较低时,MAP 和 MLE 都可以很好地预测用户计数,但当使用计数超过 450 时,就不那么好了。这些点导致具有大误差的异常值,这解释了为什么我们的平均误差比中值误差大得多。

考虑到我们的中值和均值误差比天真的预测低得多,我们可以得出结论,我们已经创建了预测每小时自行车共享用户数量的有效模型。当然还有进一步改进的空间,尤其是在用户数量较高的时段。因此,如果您对如何改进这些模型有任何建议,请随时告诉我。我们在这里的工作到此结束。感谢您的阅读。

如果你已经做到了这一步,我希望你能像我喜欢写这篇文章一样喜欢读这篇文章。我也希望你比以前更了解探索性的数据分析和机器学习。如果你认为这对你认识的人来说是有趣或有教育意义的,请与他们分享。如果你喜欢这篇文章,有什么想和我分享的,请随时评论或通过电子邮件联系我,地址是 nadir.nibras@gmail.com 或 https://www.linkedin.com/in/nadirnibras/[](https://www.linkedin.com/in/nadirnibras/)**。我致力于改进我的方法、分析或数据集,所以如果你有任何建议,请告诉我。如果你想关注我在数据科学方面的更多工作,请在 Medium 和 Linkedin 上关注我。
如果你是数据科学或其在理解世界中的应用的粉丝,请联系我。和其他统计爱好者聊天总是很有趣,我很乐意在项目上合作:)
**

预测美国各县的用药过量死亡率

原文:https://towardsdatascience.com/predicting-overdose-mortality-per-us-county-8ec0871004a7?source=collection_archive---------11-----------------------

背景和动机

阿片类药物的流行已经成为这一代美国人的主要公共健康灾难之一。类似于烟草/吸烟或艾滋病毒/艾滋病对前几代人的影响,阿片类药物的流行似乎是这个时代的决定性公共健康危机。我想看看是否有可能建立一个模型来预测一个县一个县的阿片类药物相关死亡率,因为这种类型的模型可能会让我们深入了解在哪里以及如何进行干预。

我怀疑,美国受危机影响最大的地区的相当大的差异可能可以用人口或经济因素来解释,但我实际上更好奇的是,其他更容易修改的预测因素是否会变得重要。例如,常见的说法是,阿片类药物危机始于 20 世纪 90 年代医生开始更自由地开阿片类止痛药,部分原因是制药公司向医生保证这些止痛药成瘾性低,副作用少,但这两者都不是事实。但是阿片类药物处方率仍然是阿片类药物过量死亡的主要驱动因素吗?还是有其他变量是更强的预测因素,例如,海洛因或芬太尼等非法阿片类药物的量可能是更强的预测因素?

设计

该项目的目标是使用多元线性回归模型预测定量目标变量。该项目的设计相当简单:确定一个适当的目标变量,然后找到公开可用的数据集,这些数据集将提供我认为有用和适当的预测信息。然后,我计划使用这些独立变量/预测因子建立一个多元线性回归模型,然后进行特征选择,以查看哪些预测因子是最重要的。最后,我在维持测试数据集上测试了该模型,以查看该模型的性能如何。

数据

在探索了 CDC 对他们公共数据库的描述后,我决定使用 CDC WONDER 数据库来刮取我的目标变量,即 2016 年每个县因药物过量而导致的粗死亡率。关于使用这个作为目标变量的决定的一些评论:我最初想预测每个州的死亡率,但那只会给我 50 个记录。CDC MCD(多种死亡原因)数据库实际上允许您查询具体由于阿片类药物过量导致的死亡(您甚至可以更具体,例如查询由于海洛因、阿片类镇痛剂和其他类型的阿片类药物导致的死亡数量),但对于个别类别来说,数字变得如此之小,以至于更容易获得由于药物过量导致的总体死亡率的实际数字,而无需指定药物类型。这是因为当每个县的总死亡人数在 10-20 之间时,CDC 会给你死亡人数,但不会计算粗略或经年龄调整的死亡率,因为他们声称这个小数字导致“不可靠”的统计数据。如果总死亡人数在 0-9 之间,那么他们根本不会给出一个数字,而是会声明结果是“被抑制的”,因为在一个小县的少量死亡人数,可能会识别出个别患者。

因此,最容易获得每个县因药物过量而导致的粗死亡率数据,可用的最新数据集是 2016 年。从统计学上来说,比较年龄调整死亡率会更准确,但 CDC 没有提供任何县的年龄调整死亡率,因为它给出了“不可靠”的结果(10-20 岁之间的总死亡人数),而且没有每个年龄段死亡人数的具体细分,我无法直接计算年龄调整死亡率。看起来确实有间接计算年龄调整死亡率的方法,但我决定继续使用粗略死亡率,然后使用每个县的中位年龄作为预测值,作为一种粗略的方法来说明这一点。这意味着即使美国有大约 3000 个县,因为我最终有 1000 个记录(没错!)实际上可以计算出这些县的粗略死亡率。

Overdose-related crude mortality rate per 100,000 in 2016

就我的自变量而言,大致来说,它们分为 4 类:

人口统计学的

  • 白种人百分比
  • %高中毕业或以上(指至少高中毕业的人的百分比)
  • 年龄中值

经济的

  • 家庭收入中位数
  • 贫困百分比
  • 失业率%

医学的

  • 该州的 PDMP 年龄(处方药监控计划)
  • 每 100 人阿片类药物处方率

地理学的

  • 美国人口普查地区部

人口和经济数据都是使用美国人口普查 API 查询 ACS(美国社区调查)5 年 2016 数据集获得的。确定要查询哪个美国人口普查数据集,然后确定如何构建查询,这无疑是一个学习过程。美国人口普查提供了如此多的信息,看起来似乎有可能获得你想要的精确、具体记录的极其细粒度的查询,但缺点是,一开始弄清楚如何提取甚至简单的数据是相当困难的!无论如何,在查看了我的预测值的配对图后,我意识到我得到的经济数据彼此之间具有相对较高的相关性,例如%贫困和%失业,尽管它们测量的不是完全相同的东西,但它们显然彼此相关。我认为这可能是导致共线性的一个大问题,但回想起来,我认为拥有所有这些变量实际上是没问题的——当我到达结果部分时,我将讨论我认为设计一个结合经济信息的变量可能对构建更好的模型更有用。

每 100 人的阿片类药物处方率来自 CDC,CDC 向提供了过去十多年来每个县每 100 人的年度阿片类药物处方率。一些数字令人瞠目结舌;在弗吉尼亚州诺顿县,2014 年每 100 人有 563 份阿片类药物处方。没错,那个县的人均阿片类药物处方超过 5 张!许多县的数字没有提供,所以我最后用该州的平均比率来代表这些数字。我加载了 2014 年、2015 年和 2016 年每个县的处方率,当查看相关矩阵时,2014 年的处方率与死亡率具有最强的原始相关性,因此我最终使用 2014 年的阿片类药物处方率而不是其他年份作为我的预测器。由于每年的处方率非常相似,因此没有必要包括所有 3 年。

Opioid prescription rate per 100 people in 2014

处方药监控计划是州级计划(密苏里州除外!)收集和监测关于某些药物处方的信息,特别是阿片类药物和苯二氮卓类药物。不同的州在不同的年份实施了 PDMPs,在 2000 年代,许多州开始实施电子 PDMPs,以便医生、药剂师和其他机构可以访问这些数据。从处方提供者和药剂师的角度来看,PDMP 的主要目标之一是防止患者“逛医生”和去多个提供者那里收集大量阿片类药物或苯并咪唑类药物的处方。如果 PDMPs 真的对减少阿片类药物过量处方有很强的作用,那么希望这可以转化为较低的阿片类药物过量死亡率,因此人们可以假设,总的来说,在有较老的 PDMPs 的州,过量死亡率会较低。

最后,我认为地理区域也可能是粗死亡率的一个有用的预测指标,因为这个国家的一些地区比其他地区受到的打击更大。人们可能会争论如何细化,例如时区、区域、部门,甚至是州与州之间的划分(尽管对于州来说,问题在于州与州之间的大小差异很大)。我最终使用了美国人口普查的地区划分,因为这似乎是宏观/微观之间的一个很好的折衷,因为有 10 个地区。这最终被编码为伪变量,为了避免伪陷阱,我删除了“新英格兰”区域的伪变量。

算法

我们被分配使用的模型是多元线性回归模型。这可以使用 sklearn 或 statsmodels 直接实现,尽管 statsmodels 提供了更多关于模型的信息。考虑到所有的预测因素,我认为 R 平方在 0.3 左右。Damien 然后帮助我使用 sklearn 的多项式特性转换预测因子,以生成二次组合,然后将预测因子的数量从 16 个(8 个定量预测因子,8 个虚拟变量)增加到 53 个,包括定量预测因子的所有交互项。这将整个数据集的 R 平方增加到大约 0.43,这清楚地表明相互作用项确实提供了信息。

下一步是执行特征选择。我最后尝试了两种方法,带交叉验证的后向淘汰法,在每一轮中,每个交叉投票选择一个系数 p 值最高的变量,然后我去掉投票最多的变量。我选择的最终模型是平均验证误差最小的模型。我尝试的另一个策略是使用 sklearn 的 LassoCV 进行特征选择;我再次选择了验证误差最小的套索模型。

有趣的是,LassoCV 和逆向排除法都选择“年龄”作为最重要的预测因子,但之后的四个最重要的预测因子是不同的。此外,逆向排除法选择了几个相当重要的虚拟变量,而 lasso 仍然将它们包括在最终模型中,但它们不那么重要了。他们都给出了相似的 R2 值,大约 0.41 到 0.42,以及大约相同的验证 MSE,0.17 到 0.18。两个模型的最终维持测试数据集的测试 MSE 也大致相同;对于逆向淘汰模型,它是 0.181,对于套索模型,它是 0.184。

工具

为了获得预测值和目标变量数据,我对没有提供 API 的变量使用了 Selenium 和 BeautifulSoup,然后对他们的数据使用了美国人口普查 API。清理数据是在熊猫身上完成的,为了进行分析,我使用了 sklearn 和 statsmodels。

结果

我查看了两个模型中值最大的前 5 个正系数。如下图所示,它们非常相似。反向消除包括组合系数“家庭收入中位数 x 阿片类药物处方率”,而 lasso 包括“%贫困”,但除此之外,它们共有 4 个共同的系数。不出所料,阿片类药物的处方率是前五个积极的预测因素之一,尽管我没有包括任何关于非法药物使用的数据,如海洛因、芬太尼等。我不清楚非法药物使用或处方药是否是过量死亡的更强预测因素。我确实认为组合预测很有趣。家庭收入中值乘以失业率是一个强有力的正预测因子,比任何一个单独的特征都强,这有点奇怪,因为你会认为如果家庭收入中值上升,失业率就会下降,它们会相互抵消。但这可能不是一个真实的假设,因为如果有收入不平等程度高的县,富人变得更富,家庭收入中位数可能会上升(特别是在有收入的家庭),但失业率也可能上升,因为社会经济光谱相反一端的人也可能同时失业。

我还在完整的数据集上重新调整了向后消除,然后将残差映射到 choropleth 图。我想看看这个模型是否有高估或低估粗死亡率的地理模式。上面的 choropleth 地图是使用 GeoPandas 创建的,geo pandas 是一个为处理空间和地理数据而构建的模块,并带有绘图方法以允许制图。然而,有另一个叫做 follow 的库,它允许你创建交互式地图,并把它们保存为 html 页面,所以我用 follow 创建了一个剩余地图。不幸的是,我不能将互动地图嵌入到一个中等帖子中,但如果你感兴趣,链接是这里。粉红色表示模型高估了该县的用药过量死亡率,而绿色表示模型低估了死亡率;颜色越深,残差越大。

在查看残差数据框架并按残差大小排序后,我可以看到具有最大正残差(意味着模型对真实粗死亡率的低估最严重)的县是马里兰州的巴尔的摩市。负残差最大的县(意味着模型的高估程度最差)是纽约州的萨拉托加县。

如你所见,该模型低估了巴尔的摩的真实过量死亡率 64 人/100K!在萨拉托加县,它被高估了一个较小的数量级,但我认为查看这两个异常值的每个要素的值是很有趣的,因为我认为它提供了一些关于为什么模型对这些县不太适用的见解。首先,我没有意识到美国人口普查局认为巴尔的摩市是自己的县,但它显然是这样的,与该国其他地区相比,巴尔的摩的白人人口比例非常低,请记住,白人比例在向后排除和 lasso 线性回归模型中是第二或第三重要的预测因素。2016 年贫困率为 18.3%,而全国贫困率为 12.7%。最后,巴尔的摩的中位年龄低于全国的中位年龄 38 岁,而且由于年龄是两个模型中最重要的预测因素,这也可能导致模型低估了用药过量的死亡率。

对于萨拉托加县,高中或更高学历的比例显然相当高,达到 94%。同样,失业率%和贫困率%都是全国平均水平;就贫困率而言,你可以看到它比 12.7%的全国贫困率低很多。

我认为,观察这些异常值告诉我,我的模型缺少某种整体经济福祉/繁荣或整体生活质量衡量指标,这可能没有在二次多项式回归的交互项中得到充分体现。巴尔的摩因其高犯罪率而臭名昭著,我认为非法阿片类药物肯定有可能是过量死亡的驱动因素,但该模型无法使用,因为我没有包括任何数据来源。在光谱的另一端,在查找了一些关于萨拉托加县的信息后,它显然是纽约州北部“技术谷”的中心,有大量的国际高科技和电子公司在那里设有校区,这也可以解释它的高教育率和低贫困率和失业率。创建包含更多经济变量(例如教育率 x 贫困率 x 失业率)的交互项可能会为模型带来更大的预测能力。

通过查看残差图,我注意到的另一件事是,该模型似乎倾向于低估城市县(或至少包括主要城市的县)的死亡率,而高估了非城市县的死亡率。我确实考虑过将美国人口普查的 2013 年城市/农村分类纳入我的模型,但人口普查提供的数据并不是哪些县是“城市”和哪些县是“农村”的一对一映射,当我想到这一点时,已经接近这个项目的截止日期,并且需要花费太长时间来弄清楚如何对信息进行编码。

结论

我从这一分析中得出的总体结论是,使用我选择的预测因子来解释用药过量死亡率的一些差异是可能的,但我制作的模型肯定不能解释所有的差异。模型的学习曲线表明,它们处于高偏差状态,我仍然对数据拟合不足,需要更多的特征。同样,我认为找到能提供不同国家非法阿片类药物流动信息的数据源将是有用的,我认为特征工程提出一个更全面的变量来捕捉整体生活质量或经济繁荣将是有用的。此外,该模型在城市和农村的表现之间似乎确实存在差异,因此添加这一功能也可能会增加该模型的预测能力。

我的大多数预测因素是经济或人口数据,但如果我要扩展模型,我认为真正有趣的是使用不同的公共卫生干预措施作为下一年过量死亡率的预测变量,看看这些干预措施的存在与否(或年龄)是否是死亡率的强负预测因素。许多州和县正在尝试不同的干预措施,例如发布纳洛酮命令,使用“活体控制法庭”,开设美沙酮诊所等。我试图通过在我的模型中使用 PDMP 的年龄来做到这一点,但它不是一个强有力的预测器。我认为这方面的一个问题是,我获得信息的 PDMP 网站给出了任何 PDMP 开始的年份,但提供商和药剂师可以实时查询的电子 PDM 直到 2000 年才真正开始,因此 PDM 可能至少在那之前无法影响向公众发布的阿片类药物的实际数量。因此,可能有必要进行更多的研究,为 PDMPs 找到一个更好的功能,而不仅仅是程序的年龄,例如,找出电子 PDMP 首次实施的年份,或者甚至获得一些可以表明每个 PDMP 使用了多少的方法。

最后,另一件有趣的事情是阿片类药物危机是如何随着时间的推移而演变的。我认为随着时间的推移,随着不同的驱动程序接管,不同的功能变得或多或少重要是完全可能的。为了进行这种分析,有必要为每一年建立不同的模型,并计算出一些预测因子的适当时滞;例如,长期纳洛酮命令的存在可能对一个县 1 或 2 年内的死亡率具有强烈的负相关性,但不一定是命令发布的那一年。在这个问题上肯定还有很多工作要做!

预测用户评论的极性

原文:https://towardsdatascience.com/predicting-polarity-of-user-reviews-8774c2a83dd3?source=collection_archive---------8-----------------------

credits - freepick

*“自动化应用于高效的运作将会放大效率”——*比尔·盖茨

根据客户互动和在线评论管理软件 Podium 对 2005 名美国消费者的调查, 93%的消费者表示在线评论对他们的购买决定有影响

这意味着,对于任何大批量的买卖业务来说,拥有一个强大的系统来对用户评论进行分类是至关重要的,因为评论是一种形式的社会证明。为了在规模上准确地实现这一点(同时考虑时间和成本节约),添加自动化是有意义的。

在这篇博客文章中,我已经写了我们如何在内部使用哪些机器学习技术来创建这样一个自动化层的第一个版本。

问题

每天,电子商务网站都有数百万的产品列表上传到他们的平台上。这一数据变得更加复杂,因为成百上千的消费者最终会为几乎所有的商品写评论。

但是这个数据是有用的,因为评论被用来创建平均分数来评价产品。
现在,手动对用户评论进行分类既费钱又耗时。这也是为什么在小队,我们正在努力使给用户评论分配极性的过程自动化。目标是预测任何评论的极性,如正面、负面或中性/建议。

自动化情感分析的业务影响

通过包含一个简单的模型,该模型可以根据与评论相关的用户情绪自动对评论进行分类,它可以极大地帮助企业节省通常用于处理内部人工评论团队或外部 BPO 高管团队的成本。事实上,这样的模型实际上帮助团队变得更有生产力,因为现在他们只处理异常,而不是做端到端的猴子工作。

此外,评论的极性可以帮助准确地对产品评级,从而帮助新的在线消费者基于其他用户的喜欢/不喜欢推荐来过滤产品。

从数据集统计开始

我们通过收集各种产品的评论准备了一个用户评论数据集,并使用 Squad 的人在回路中的工作流来标记它们。我们在图 1 中可以看到,正面评价 42.04%,负面评价 45.02%,建议评价 12.94%。数据非常不准确,我们能提供建议的样本非常少。

Figure 1: The distribution of Positive, Negative and Suggestion reviews.

我们实验的不同机器学习管道

这就是机器学习的有趣之处。

通过删除所有重复条目和空白回答对数据进行预处理。然后,对于每个评论,计算 Tf-Idf(术语频率-逆文档频率)特征:

  • sublinear_df 设置为 True 以使用对数形式的频率
  • min_df 是一个单词必须出现在文档中才能保留的最小比例
  • stop_words 设置为*【英语】删除所有常用代词(【a】【the】*、…)以减少噪声特征的数量

Figure 2: Code snippet to build a Tf-Idf model.

然后,这些数据被分成 70-30 的比例,70%的数据用于训练,30%的数据用于测试我们的模型。有三种目标类别:积极、消极和建议。

我们尝试了两条管道:

**一、管道 1 — Tf-Idf + SVM(支持向量机)

*答:*使用 GridSearchCV 和各种参数进行了交叉验证,如图 3 所示。

B. 在 1.8Ghz 英特尔酷睿 I5 处理器(MacBook Air)和 8GB RAM 上训练这个模型大约需要一个小时。

Figure 3: Hyperparameters to select the best model.

**二世。管道 2 — Tf-Idf + NN(神经网络)

A. 我们做了一个定制的单层神经网络。其架构如下所述。

Figure 4: Code snippet to build a neural network.

B. 模型检查指针用于在每个历元之后保存最佳模型,早期停止用于在验证损失停止改善时停止训练模型。

Figure 5: Callbacks used while training.

C. 在我在 Pipeline 1 中使用的同一台 MacBook Air 机器上训练这个模型花了大约 20 分钟。

比较和结果

使用神经网络的第二种技术给出了相对更好的结果。我们评估了模型在某个置信阈值上的性能,即所有三个类别(负面、正面和建议)中发生的最大概率应该高于该值。置信度小于该阈值的样本被认为是不明确的,然后由 HIL 小队(回路中的人)系统验证。因此,自动化表示不需要人工验证的样本比例。

管道 1 (Tf-Idf + SVM)在 0.9 置信阈值下的结果:

管道 2 (Tf-Idf + NN)在置信度阈值为 0.9 时的结果:

结论

我们开发了一个用户评论分类模型。积极班和消极班的成绩略好于暗示班。从一般的观察中,可以得出这样的结论:暗示样本有时与阳性混淆,有时与阴性混淆。

建议类的性能可以通过进一步增加 Tf-Idf 特征向量的大小来提高;为每个类别制作 Tf-Idf 矢量器,并通过来自每个矢量器的每次检查,连接特征,然后训练分类器。

下一步是什么?

我们目前正在研究短文本增强技术,以增加用户评论数据集中倾斜类的比例,从而提高我们模型的准确性。此外,我们还在进行研究,通过使用基于方面的情感分析等技术来发现用户对产品特定功能的情感。

在我的下一篇文章中,我将写另一个用例,我们目前正在为我们的一个企业客户工作。在此之前,请查看—班参加乔尔考试

预测流行的纽约时报文章—质量评分算法

原文:https://towardsdatascience.com/predicting-popular-ny-times-articles-quality-score-algorithms-8ab4af6a830b?source=collection_archive---------5-----------------------

为什么有人会关心《纽约时报》的博客文章有多受欢迎?我认为你应该关心,因为你的领域有可转移的知识——如何监控你的库存质量。例如,我认为脸书的“库存”就是用户的帖子。你可能会喜欢看你最好的朋友的蜜月照片;你的前搭档就没这么多了。向用户提供低质量的库存会让脸书付出与实体店同样高昂的代价。

背景:我参加了在 edX 上举办的一个优秀的 MITx 课程 Analytics Edge,当时我正在研究这个数据集。我是 MOOCs(大规模开放在线课程)的超级粉丝,自 2014 年夏天以来,我一直在 edX 和 Coursera 上注册一门或多门课程。我非常尊重学习过程,并且不会发布代码和数据

重建这个数据集是非常可能的,只需订阅纽约时报的费用。原始数据包括 2014 年初发表的 6500 篇文章,如果每篇文章收到 25 条以上的评论,这些文章就会被标记为受欢迎。这项任务是预测 2014 年秋季会流行的文章。提供了文章的发表日期、章节、标题和摘要。让我们从一些可视化的描述性分析开始,看看我们是否能做出任何推论。

首先,分离出受欢迎的文章并检查出版时间。

Popular NY Times Blog Articles by The Day of Week

一周内发表的文章似乎比周末发表的文章更受欢迎。这是术语影响的一个很好的例子。“受欢迎”是通过用户评论的数量来衡量的;这并不一定意味着纽约时报在周末的收视率会下降。

让我们更进一步,检查文章发布的时间。

Number of Popular Articles by the Hour of the Day of Posting

中午前后是热门文章发表的高峰,3 小时后的下午 3 点是另一个高峰。这可能是因为西海岸的作者发表文章的时间周期与他们东海岸的同事相似。或许这些文章的发表是为了配合各海岸工人的午休时间?

好的,那么文章发表的部分呢?

Popularity of Articles by Posted Section

一般来说,文章受欢迎的可能性是不受欢迎的 5 倍。然而,我们看到两个突出类别的文章更有可能受欢迎(即。其中绿色条比红色条长)。观点、健康和纵横字谜/游戏部分在用户中的受欢迎程度超出预期。

最后,我们来看一下文章内容。我生成了 6500 篇文章中使用最多的 100 个单词的单词云。

100 Most Popular Words in NY Times Blog Articles

你会注意到一些有政治倾向的词,比如奥巴马,共和党,民主党。直觉上,这是有道理的,因为 2014 年是美国中期选举年

从这四张图表中我们可以推断出什么?如果你写了一篇关于奥巴马医疗保健法的博客,并在美国东部时间周一中午 12 点发表,你的评论区会火起来。

这些都是描述性的,而不是预测性的分析。预测未来几个月哪些文章会流行呢?

好问题。我将在本周晚些时候的后续文章中讨论这个问题。

预测《纽约时报》评论的受欢迎程度(上)

原文:https://towardsdatascience.com/predicting-popularity-of-the-new-york-times-comments-part-1-d32f26261f6f?source=collection_archive---------7-----------------------

大家好!我刚刚完成了多伦多瑞尔森大学 大数据认证的顶点项目 。这个项目很有挑战性,但是需要大量的学习。我花了近一个月的时间,从头到尾完成了它,并准备了报告。请按照我的 GitHub 上详细的分步 R 码。

第 1 部分将讨论问题陈述,并向您介绍数据集和不同的可视化方法,以便更好地理解数据。第 2 部分将更多地讨论预测建模,使用自然语言处理的文本到向量框架。

介绍

《纽约时报》(NYT)拥有庞大的读者群,在塑造公众舆论和对时事的看法以及设定公共话语基调方面发挥着重要作用,尤其是在美国。NYT 的文章评论区非常活跃,能够洞察读者对文章主题的看法。每条评论都可以收到其他读者的推荐。

NYT 版主面临的挑战

  • 高达每篇文章 700 条评论NYT 版主一天内人工审核~ 12000 条评论。
  • 版主需要根据预测的相关性和受欢迎程度,更快地做出筛选和分类评论的决定。
  • 找到一种更简单的方法来分组相似的评论,并在读者中保持有用的对话。

Number of popular comments per article by News Desk

关键研究课题

  • 广泛分析 NYT 的文章和评论
  • 读者评论的流行度预测

方法

***** 这个项目的分步代码可以在我的** NYT NLP 顶点 GitHub 资源库中找到。*

步骤 1:数据收集

NYT 文章数据集:

  • 数据集由九个部分组成。2017 年 1 月至 5 月和 2018 年 1 月至 4 月发表的文章的 csv 文件(可在网上获得,也可以使用 NYT API 抓取)。
  • 共有 9335 篇不同的文章,包含 15 个变量。

NYT 评论数据集:

  • 还有另外一组九个。包含对这些文章的评论集合的 csv 文件(可以在网上找到,也可以使用 NYT API 抓取)。
  • 总计 2,176,364 条评论,包含 34 个变量。

** 项目中使用的所有数据文件都可以在这里找到

步骤 2:数据清理和预处理

限制和减少

  • 由于庞大的数据量和有限的计算资源,我决定将数据集限制在 14 个可用新闻服务台中的前 6 名。
  • 我将某些“角色”特征转换为“因素”
  • 我更改了一些特性的数据类型,尤其是将 UNIX 时间戳格式更改为 POSIXct。
  • 我删除了分析不需要的特征。

Number of articles published per News Desk

Volume of comments per News Desk

步骤 3:情感倾向得分和计算

组织和清理文本:

  • 使用 unnest_tokens 函数处理评论、摘录和文章标题中的文本。
  • 在新数据帧的每一行中,文本主体被分割成记号(单个单词)。
  • 我去掉了标点符号,把记号转换成小写。

语义取向分数确定:

  • 使用基于词典的方法来区分文本取向和单词的语义取向。
  • 适当的词典( BING )是从 r。
  • 我用 BING 给每个标题、文章片段和文章评论分配了一个情感分数。
  • 基于情感得分,每个标题、片段和评论被分为三个情感类别:负面、正面或中性。

步骤 4:提取和分析特征

除了数据中已经存在的变量之外,还衍生了一些其他特征:

  • 针对每篇文章标题、摘录和评论正文的合计情感得分 (负面、正面、中性)
  • 每条评论的总字数
  • 每条评论的总字数
  • 平均每句话字数 每个评论
  • 时间特征: 添加评论的时间与文章发表日期/时间的时间差
  • 星期几 添加注释时
  • 添加注释的时间

将建议转换为二进制变量:

此外,为了使用分类方法构建预测模型(如我的下一篇文章中所讨论的),目标变量“建议”(数字)被转换为可能值为 0 或 1 的二进制变量。

流行与非流行变量是从转换前的推荐变量的五个数字的汇总统计中得出的。其总体中值为 4;因此任何有< =3 张赞成票的评论都被标记为非热门**。**

0 = Non-Popular, 1 = Popular

The final data frame with 26 selected features

步骤 5:数据探索和可视化

在建立任何模型时,我们需要了解预测因素和响应变量之间的相关性。下面的可视化提供了对我的数据更好的理解,也研究了不同变量之间的关系。

Frequency of articles based on sentiment: positive, neutral or negative

Do certain words in article headlines elicit more comments?

Comment popularity across the top six News Desks

Correlation between number of comments and article word counts

Correlation between comment popularity and article sentiments

Correlation between comments and temporal features

Most commonly used words in comments

文本特征与评论流行度的相关性探究

进行 Anova 测试以确定响应变量和数值预测值之间相关性的统计显著性。对于所有三个预测因子,相关性在统计上是T5t,如下所示。

Number of words per sentence in comments vs. comment popularity

Number of sentences in comments vs. comment popularity

Article-comment time gap vs. comment popularity

数据探索摘要

  • NYT 最受欢迎的新闻台是专栏**、国内国外华盛顿商业社论。版主在审核读者添加的评论时,可以专注于这些类别。**
  • 在 2017 年和 2018 年,文章倾向于负面情绪多于正面情绪。这可以与美国和世界普遍的政治局势联系起来。
  • 对于评论最多的文章以及这些评论中最常用的词,前 25 个术语相似,包括特朗普**、俄罗斯难民健康秘密。**
  • 根据评论热度分布,全国性文章是读者阅读和喜欢最多的文章**。这可以归因于美国在 2017-2018 年期间发生的政治变化。**
  • 大多数评论是在上午和下午发表的。
  • 周二周四周五是评论最活跃的日子,而最不活跃的日子是周末。
  • 评论的受欢迎程度和一些衍生特征之间有很强的相关性:评论中每句话的平均字数,评论中的平均句子数,以及文章和评论发表之间的平均时间间隔。这意味着这些特征可以用来预测评论流行度。

结论

由于许多预测因素和反应变量之间没有很强的相关性,我选择了一种不同的方法来处理这个问题,我将在下一篇博客中讨论这个问题。

你对四张赞成票成为受欢迎程度的分界点有何看法?你认为提高或降低阈值会如何影响结果?请在评论区告诉我你的想法,并继续关注第 2 部分:-)

(首发@www.datacritics.com)

使用 EA 球员评分和 Tensorflow 预测足球比赛

原文:https://towardsdatascience.com/predicting-premier-league-odds-from-ea-player-bfdb52597392?source=collection_archive---------3-----------------------

Photo by Mario Klassen on Unsplash

快速警告

因为我用顶峰体育的收盘赔率作为我的目标,你可以说我只是在建模。然而,假设是到比赛开始的时候,Pinnacle 的线会移动足够多,因为人们打赌赔率应该非常接近真实的概率。有点像群体智慧效应。这是否是一个好的假设…?我要说的是,它不仅效果很好,而且达到了我希望的效果,我将在后面解释。

这个想法

去年我开发了一个预期目标(xG)模型——只是为了好玩和做一些 Python 编程。这在很大程度上受到了两个人的启发,他们是我在推特上关注的迈克尔·凯利特德·克努特森。在我看来,xG 绝对是梦幻般的。如果你想知道更多的细节,你应该看看迈克尔的推特。然而,和所有的足球分析方法一样,它也有缺点。迈克尔又一次更深入地探讨了这些问题,但我将快速地列出它们,让大家了解为什么我决定做一些不同的事情。首先,它没有考虑参与游戏的玩家。例如,如果埃登·阿扎尔在切尔西缺阵(一个令人悲伤的事实),你显然会期望切尔西的 xG 会更低,然而没有真正的方法来解释这一点。其次,在赛季开始时,当新球员到来时,xG 无法衡量这个新球员会对球队产生什么样的影响。最后,我还没有看到一个 xG 模型可以很好地适用于所有的五大联盟(这是我还没有尝试用我的模型做的事情,但它是我在某个时候要实现的一个扩展)。

我的 xG 模型也很晚才问世——它已经问世 4、5 年了,所以我的模型不是以前没有人做过的东西。我想尝试创造一些东西,a)可以预测足球比赛的结果,b)我以前从未见过,c)使用某种形式的球员数据。我可能大错特错,但我还没有看到很多人将神经网络应用于足球问题的例子。因此,考虑到以上所有因素,我决定在 Tensorflow 中写点东西,尝试根据一个球队的首发 11 人预测足球比赛的结果。

数据

最明显的玩家评级系统是 EA Sport 的 FIFA 游戏。它们每年都会更新,它们独立于联盟之外,而且它们足够准确(以至于我从来没有听到有人这样谈论它们)。我只使用了整体评分,但可能是其他评分的组合(防守,进攻等。)可能效果更好。我收集了过去 5 年来自 https://www.fifaindex.com/的[的英超终极团队评分。我还需要知道哪些玩家开始了哪些游戏。对于这一点,【http://www.betstudy.com/】的](https://www.fifaindex.com/)[是一个伟大的资源。它提供了过去 5 年英超联赛中所有比赛的 11 名首发球员的姓名、号码和国籍。来自 fifaindex 的名字与在 betstudy 上看到的名字并不完全匹配,所以我使用了名字、号码、球队和国籍的组合来匹配球员。一旦匹配完成,我有 22 个评分(11 个主场球员和 11 个客场球员),在过去 5 年的英超联赛中的每场比赛都在 50 到 100 之间。这是一个好的开始。](http://www.betstudy.com/)

What a vector would look like for a Chelsea line-up of Courtois; Moses, Rudiger, Alonso, Christensen, Azpilicueta; Fabregas, Kante; Hazard, Morata, Willian.

然而,仅仅使用这 22 个数字就意味着我们失去了潜在的重要信息。当糟糕的球队对阵优秀的球队时,他们往往会通过启动更多的防守球员来停止比赛——我希望我的模型能够考虑到这种变化。因此,我选择用一个大小为 18 的向量来模拟每个从 11 开始的值。在每个 18 维向量中,第一个分量是对守门员的评分,接下来的六个分量是对后卫的评分——如果只有四名后卫,其中两个分量为零。我在上面加了一张图,试图帮助想象这个 18 维向量在给定切尔西阵容的情况下会是什么样子。根据同样的方法,中场球员有七个组成部分,前锋有四个组成部分。输入的这种结构应该允许从地层中得出一些推论。例如,如果有六名防守球员在比赛,很可能这支球队正在寻找停巴士的机会,因此应该相应地计算赔率。基本上,团队的形成改变了向量的哪些分量被保留为 0,并允许神经网络从中进行推断。此外,当我们将这些数据传递给神经网络时,我们会将它们作为一个大型的 36 维向量进行传递——主队占据前 18 维,客场队占据最后 18 维。通过使用这种结构,网络也可以占据主场优势。

最后,模型的输出将是匹配的 1X2 赔率。我使用了顶尖体育赔率,这些赔率是由 http://www.football-data.co.uk/ T2 的约瑟夫·布赫达尔多年来收集的。

具有训练和验证损失的模型

The neural network architecture. Drawn using http://alexlenail.me/NN-SVG/index.html

收集并格式化所有数据后,必须确定网络的“内部”结构。我最初在 2013-2014、2014-2015、2015-2016 和 2016-2017 英超赛季训练该模型,以便我可以在 2017-2018 赛季回测它。在 1540 个游戏中,我保留了 50 个作为验证集。然后我训练这个模型,使用退出提前停止使用多种不同的网络结构。实现最小验证误差的是具有两个隐藏层的网络,第一层具有 16 个节点,第二层具有 8 个节点。训练集和验证集的误差图如下所示,垂直线表示提前停止。我不会过多地讨论神经网络的细节,但如果有人对此感兴趣,可以在 GitHub(底部的链接)上找到所有代码。一旦我对模型进行了回溯测试(我在下面展示了回溯测试的一些结果),我就对包括 2017-2018 赛季在内的所有数据重新训练了网络,为今年做好了准备。

A plot to show the training and validation losses (y-axis) against the number of iterations (x-axis). The vertical line represents the early stopping

回溯测试

为了进行回溯测试,我从一个 100 人的虚拟银行开始,并使用凯利标准来确定股份大小。我没有下赔率大于 3.2 的赌注,也没有下根据模型期望值小于 2%的赌注。在 2017-2018 赛季,该模型实现了 11%的投资回报率。这好得离谱好。我多次重新运行它,多次重新训练该模型,并不断得出相同的结果。所以我也深入研究了这些数字:

  • 我赢了 50%的赌注
  • 巅峰时期的平均赔率是 2.37
  • 平均预测赔率为 2.01
  • 赌注的平均价值为 7.23%,最高为 21.3%

这么大的投资回报率肯定是偶然的,但上面的观察似乎很有希望,总的来说,该模型将会盈利。我在我的资金下面绘制了一段时间的情况,以及赌注大小,如果有人特别感兴趣,我可以分享更多关于实际赌注的信息。

A plot to show the bank and stake sizes (y-axis) against the number of bets (x-axis).

2018/19 赛季

鉴于回溯测试的良好结果,我重新培训了包括 2017-2018 赛季在内的模型。使用这个新模型,我可以模拟整个赛季,但有几个注意事项。首先,我必须猜测每支球队最有可能的阵容(这很好,但这些显然会在整个赛季中发生变化)。其次,我不得不使用 2017-2018 年 EA 球员评级,这不是一个大问题,但有像萨拉赫这样的球员,他们的评级肯定会在 FIFA 19 中发生变化-我会用新的评级更新这个模拟,并在 FIFA 19 出来时重新运行模拟。此外,转会窗口仍然开放,这是有问题的,因为它看起来几乎肯定会有一些球员离开-像危险。无论如何,带着这个想法,我运行了这个赛季 100 万次(在我的笔记本电脑上大约需要 8 分钟),并计算了平均积分、胜败和平局。然后,我计算了 1,000,000 个赛季中球队获得第一名、前 4 名和降级区的百分比。成绩在下面,看起来符合人们的普遍预期。

Predicted Premier League table averaged over 1,000,000 simulated seasons

进一步来说,我可以开始和团队混在一起。举个例子,假设哈扎德离开了,切尔西改打威利安。与哈扎德的 91 分相比,威利安的得分为 84 分。在模拟赛季中交换这一点,切尔西会下降大约 4 分!我们可以对曼联做同样的事情,把德基换成罗梅罗,他们平均下降 3 分。这些积分差异肯定与你的预期有关——没有哈扎德的切尔西是一支更差的球队,没有德基的曼联更差。(我还没有重新运行这个,包括利物浦所有的新签约——但这是我接下来要做的事情)。

总的来说,我对这种工作方式非常满意。这显然不是模拟足球比赛的完美方式。有很多因素需要考虑——教练、天气、疲劳、赛季末和赛季初等等。这个模型不可能捕捉到潜在的分布。然而,这很有趣,事实上像切尔西这样的球队在你拿走他们的明星球员后会丢分,这表明这实际上是按计划进行的。下一步肯定是看利物浦的预测如何变化,当我加入他们的新球员时。然后我想让它设置为自动使用 Smarkets API,并自动下注。最后,当我大学毕业时,我想在过去的 5 个赛季里,在所有 5 个欧洲顶级联赛中训练它,看看我是否能够产生一个“适合所有人的模式”。这也将允许我在世界杯和欧锦赛上使用这个模型——这将非常有趣。

编辑:我做了一个快捷的网络应用,如果你想自己尝试一下的话——https://pl-predictor-tensorflow.herokuapp.com

如果你在推特之外的地方发现了这个-https://twitter.com/BradleyGrantham

如果有人对实际代码感兴趣,这些都在 GitHub 上-【https://github.com/BradleyGrantham/fifa-stats-scraper

使用神经网络预测概率分布

原文:https://towardsdatascience.com/predicting-probability-distributions-using-neural-networks-abef7db10eac?source=collection_archive---------10-----------------------

本帖原载于 Taboola 的工程博客

如果你最近一直在关注我们的科技博客,你可能已经注意到我们正在使用一种特殊类型的神经网络,称为混合密度网络(MDN)。MDN 不仅预测目标的期望值,还预测潜在的概率分布。

这篇博文将关注如何使用 Tensorflow 从头开始实现这样一个模型,包括解释、图表和一个包含全部源代码的 Jupyter 笔记本

什么是 MDN,为什么它们有用?

现实生活中的数据是嘈杂的。虽然相当恼人,但这种噪音是有意义的,因为它提供了数据来源的更广泛的视角。根据输入的不同,目标值可能有不同程度的噪声,这可能会对我们对数据的理解产生重大影响。

这个用一个例子更好解释。假设以下二次函数:

给定 x 作为输入,我们有一个确定的输出 f(x) 。现在,让我们把这个函数变成一个更有趣(也更真实)的函数:我们将在 f(x) 中加入一些正态分布的噪声。这种噪音会随着 x 的增加而增加。我们将称新函数为 g(x) ,形式上等于g(x)= f(x)+𝜺(x),其中𝜺 (x) 为正态随机变量。

让我们针对不同的 x 值对 g(x) 进行采样:

紫色线代表无噪声函数 f(x) ,我们可以很容易地看到添加噪声的增加。让我们检查一下 x = 1x = 5 的情况。对于这两个值, f(x) = 4,so 4 是 g(x) 可以取的合理值。4.5 对于 g(x) 也是一个合理的预测吗?答案显然是否定的。虽然 4.5 似乎是 x = 5 的合理值,但当 x = 1 时,我们不能接受它作为 g(x)的有效值。如果我们的模型只是简单地学习预测y’(x)= f(x),这些有价值的信息就会丢失。这里我们真正需要的是一个能够预测*y’(x)= g(x)*的模型。这正是 MDN 所做的。

MDN 的概念是由 Christopher Bishop 在 1994 年发明的。他的原始论文很好地解释了这个概念,但它可以追溯到史前时代,当时神经网络不像今天这样普遍。因此,它缺少实际实现的部分。这正是我们现在要做的。

我们开始吧

让我们从一个简单的神经网络开始,它只从有噪声的数据集中学习 f(x) 。我们将使用 3 个隐藏的密集层,每个层有 12 个节点,如下所示:

我们将使用均方差作为损失函数。让我们在 Tensorflow 中对此进行编码:

x = tf.placeholder(name='x',shape=(None,1),dtype=tf.float32)
layer = x
for _ in range(3):
   layer = tf.layers.dense(inputs=layer, units=12, activation=tf.nn.tanh)
output = tf.layers.dense(inputs=layer, units=1)

训练后,输出如下所示:

我们看到网络成功地学习了 f(x) 。现在缺少的只是对噪声的估计。让我们修改网络来获得这条额外的信息。

走向 MDN

我们将继续使用我们刚刚设计的相同网络,但我们将改变两件事:

  1. 输出层将有两个节点,而不是一个,我们将这些节点命名为 musigma
  2. 我们将使用不同的损失函数

现在我们的网络看起来像这样:

我们来编码一下:

x = tf.placeholder(name='x',shape=(None,1),dtype=tf.float32)
layer = x
for _ in range(3):
   layer = tf.layers.dense(inputs=layer, units=12, activation=tf.nn.tanh)
mu = tf.layers.dense(inputs=layer, units=1)
sigma = tf.layers.dense(inputs=layer, units=1,activation=lambda x: tf.nn.elu(x) + 1)

让我们花一点时间来理解 sigma 的激活函数——记住,根据定义,任何分布的标准差都是非负数。指数线性单位 (ELU),定义为:

产出 -1 作为其最低值,因此 ELU+1 将总是非负的。一定要去 ELU 吗?不,任何总是产生非负输出的函数都可以,例如 sigma 的绝对值。ELU 似乎做得更好。

接下来,我们需要调整我们的损失函数。让我们试着去理解我们现在到底在寻找什么。我们的新输出层为我们提供了正态分布的参数。这种分布应该能够描述采样产生的数据 g(x) 。我们如何衡量它?例如,我们可以从输出中创建一个正态分布,并最大化从中抽取目标值的概率。从数学上来说,我们希望最大化整个数据集的正态分布的概率密度函数(PDF)的值。同样,我们可以最小化 PDF 的负对数:

我们可以看到损失函数对于𝜇和𝝈.都是可微的您会惊讶于编码是多么容易:

dist = tf.distributions.Normal(loc=mu, scale=sigma)
loss = tf.reduce_mean(-dist.log_prob(y))

仅此而已。在训练模型之后,我们可以看到它确实在 g(x) 上拾取:

在上面的图中,蓝色的线和点代表用于生成数据的实际标准偏差和平均值,而红色的线和点代表由网络预测的不可见的 x 值的相同值。大获成功!

后续步骤

我们已经了解了如何预测简单的正态分布——但不用说,MDN 可以更通用——我们可以预测完全不同的分布,甚至几种不同分布的组合。您需要做的就是确保分布变量的每个参数都有一个输出节点,并验证分布的 PDF 是可微分的。

我只能鼓励你尝试和预测更复杂的分布——使用本文附带的笔记本,修改代码,或者在现实生活数据中尝试你的新技能!愿机会永远对你有利。

用深度学习预测职业棋手的棋步

原文:https://towardsdatascience.com/predicting-professional-players-chess-moves-with-deep-learning-9de6e305109e?source=collection_archive---------9-----------------------

Source: Pexels

所以我不擅长下棋。

我爸爸在我小的时候教我,但我想他是那种总是让孩子赢的爸爸。为了弥补这个世界上最受欢迎的游戏之一的技能缺乏,我做了任何数据科学爱好者都会做的事情:建立一个人工智能来击败我无法击败的人。不幸的是,它远不如 AlphaZero(甚至不如普通玩家)。但我想看看象棋引擎在没有强化学习的情况下如何运行,以及如何在网络上部署深度学习模型。

在这里对战吧!

获取数据

FICS 有一个数据库,里面有 3 亿个游戏,每个人下的棋,结果,以及参与者的评分。我下载了 2012 年所有至少有一个玩家 2000 ELO 以上的游戏。总共进行了大约 97000 场游戏,移动了 730 万次。获胜分布是:43000 个白色获胜,40000 个黑色获胜,14000 个平局。

极大极小

为了理解如何制作深度学习象棋人工智能,我必须首先理解传统象棋人工智能是如何编程的。进来的是极小极大。Minimax 是“最小化最大损失”的缩写,是博弈论中决定零和博弈应该如何进行的概念。

Minimax 通常与两个玩家一起使用,其中一个玩家是最大化者,另一个玩家是最小化者。代理人,或者任何使用这种算法获胜的人都认为他们是最大化者,而对手是最小化者。该算法还要求有一个董事会评估功能,这是一个谁是赢家的数字措施。这个数字介于-∞和∞之间。最大化者希望最大化这个值,而最小化者希望最小化这个值。这意味着当你,最大化者,面临两个移动之间的十字路口时,你会选择给你更高评价的那个,而最小化者会做相反的事情。这个游戏是在假设两个玩家都处于最佳状态并且没有人犯错的情况下进行的。

Source: GlobalSoftwareSupport

以上面的 GIF 为例。你,最大化者(圆圈),有三个动作可以选择(从顶部开始)。你应该选择的移动直接取决于你的对手(方块)在移动后选择的移动。但是你的对手选择的移动直接取决于你在移动到移动后选择的移动,以此类推直到游戏结束。一直玩到游戏结束会消耗大量的计算资源和时间,所以你选择一个深度,在上面的例子中,是 2。如果最小化点(最左边的方块)选择向左移动,你有-1 和 1 可以选择。你选择 1 是因为它会给你最高分。如果极小值选择正确的移动,你选择 0,因为那更高。现在轮到最小化者了,他们选择 0,因为那更低。这出戏会一直演下去,直到所有的棋都走完了,或者你没有思考的时间了。对于我的象棋引擎,引擎假设白色是最大值,而黑色是最小值。如果引擎是白色的,算法决定哪个分支将给出最高的最低分,假设人类每次都选择最低分,反之亦然。为了获得更好的性能,该算法还可以与另一种算法结合使用: alpha-beta 剪枝。Alpha-beta 剪枝应用一个截断系统来决定是否应该向下搜索一个分支。

深度学习架构

我的研究始于 Erik Bernhardsson 关于象棋深度学习的伟大文章。他讲述了他如何采用传统方法让人工智能下棋,并将其转化为使用神经网络作为引擎。

第一步是将棋盘转换成输入层的数字形式。我借用了 Erik Bernhardsson 的编码策略,将棋盘与每个方格中的棋子进行热编码。这总共是一个 768 元素的数组(8 x 8 x 12,因为有 12 个元素)。

Bernhardsson 选择将输出层设为 1 表示白棋胜,设为-1 表示黑棋胜,设为 0 表示和棋胜。他认为游戏中的每个棋盘位置都与结果有关。每一个单独的位置都被训练成如果黑棋赢了就“偏向黑棋”,如果白棋赢了就“偏向白棋”。这允许网络返回一个介于-1 和 1 之间的值,这将告诉你该位置更有可能导致白棋获胜,还是黑棋获胜。

我想用一个稍微不同的评估函数来处理这个问题。网络能不能看不出是白棋还是黑棋赢了,但能看到哪一步棋会赢?首先,我尝试将 768 元件电路板表示成输出,其中一个位置是输入,下一个位置是输出。当然,这没有成功,因为这将它变成了一个多分类问题。这为引擎正确选择合法移动提供了太多的错误,因为输出层中的所有 768 个元素都可能是 1 或 0。所以我查阅了 Barak Oshri 和 Nishith Khandwala 的斯坦福论文使用卷积神经网络预测国际象棋中的棋步,看看他们是如何解决这个问题的。他们训练了 7 个神经网络,其中一个网络是棋子选择网络。这个网络决定了哪个方块最有可能被移走。其他六个网络是专门为每一件作品类型,并会决定一个特定的作品应该移动到哪里。如果棋子选择器选择了一个有棋子的方格,只有棋子神经网络会用最有可能移动到的方格作出响应。

我借鉴了他们两人的想法,做了两个卷积神经网络。第一个是从网络移动的*,它将接受 768 元素数组表示,并输出 pro 从哪个方块(在方块 0 和方块 63 之间)移动。第二个网络:移动到网络,将做同样的事情,除了输出层将是 pro 移动到的地方。我没有考虑谁赢了,因为我假设不管最终结果如何,训练数据中的所有移动都是相对最优的。*

我选择的架构是两个 128 卷积层和 2x2 滤波器,后面是两个 1024 神经元全连接层。我没有应用任何池,因为池提供了位置不变性。图片左上角的猫就像图片右下角的猫一样。然而,对于国际象棋来说,王卒的价值与车卒的价值是完全不同的。我对隐藏层的激活函数是 RELU,而我对最后一层应用了 softmax,所以我基本上得到了一个概率分布,所有方块的概率总和为 100%。

我的训练数据是训练集的 600 万个位置,剩余的 130 万个位置用于验证集。训练结束时,我从网络得到的移动的验证准确率为 34.8%,从移动到网络的验证准确率为 27.7%。这并不意味着 70%的时间它没有学会合法的动作,这只是意味着 AI 没有做出与验证数据中的职业球员相同的动作。相比之下,Oshri 和 Khandwala 的网络平均验证准确率为 37%。

将深度学习与极小极大相结合

因为这现在是一个分类问题,其中输出可以是 64 个类中的一个,这留下了很多出错的空间。训练数据(来自高水平玩家的游戏)的一个警告是,优秀的玩家很少能玩到将死。他们知道自己什么时候输了,通常不需要看完整场比赛。这种平衡数据的缺乏使得网络在接近尾声时严重混乱。它会选择要移动的车,并尝试对角移动它。该网络甚至会试图指挥反对派的作品,如果它是失败的(厚脸皮!).

为了解决这个问题,我按照概率对输出进行了排序。然后,我使用 python-chess 库获得了一个给定位置的所有合法移动的列表,并选择了具有最高合成概率的合法移动。最后,我应用了一个预测得分公式,对选择可能性较小的移动进行惩罚:400-(所选移动的指数之和)。合法移动在列表中的位置越靠后,它的预测得分就越低。例如,如果从网络移动的的第一个索引(索引 0)与从移动到网络的第一个索引相结合是合法的,那么预测得分是 400-(0+0),这是最高可能得分:400。

我选择了 400 作为最大的预测分数,在和材料分数一起玩了这个数字之后。材料分数是一个数字,它会告诉你所做的移动是否会抓住一个棋子。根据捕捉到的棋子,这步棋的总得分会提高。我选择的材料值如下:

卒:10,骑士:500,主教:500,车:900,皇后:5000,国王:50000。

这尤其有助于结束游戏。在将死棋是第二个最有可能合法的棋步并且预测得分较低的情况下,国王的物质价值会超过它。棋子的分数如此之低,是因为网络在游戏初期考虑得很好,如果是战略行动,它会选择棋子。

然后,我将这些分数组合起来,返回给定任何潜在移动的棋盘评估。我通过深度为 3 的最小最大算法(带有 alpha-beta 修剪)输入这个,得到了一个有效的象棋引擎,它被将死了!

使用 Flask 和 Heroku 部署

我使用了 Youtube 上的 Bluefever 软件指南,展示了如何制作一个 javascript 象棋 UI,并通过向 flask 服务器发出 AJAX 请求来路由我的引擎。我使用 Heroku 将 python 脚本部署到 web 上,并将其连接到我的自定义域:【Sayonb.com。

结论

即使引擎的表现不如我希望的那样好,但我学到了很多关于 AI 的基础,将机器学习模型部署到 web,以及为什么 AlphaZero 不单独使用卷积神经网络来玩!

可以通过以下方式进行可能的改进:

  • 利用二元模型 LSTM 将从移出的和从移至网络组合成一个时间序列。这可能有助于将从移出的和从移至决策放在一起,因为目前每个决策都是独立进行的。**
  • 通过增加获取材料的位置来改进材料评估(在棋盘中心获取棋子比在边上获取更有利)
  • 在使用神经网络预测分数和材料分数之间切换,而不是在每个节点都使用两者。这可以允许更高的最小最大搜索深度。
  • 考虑边缘情况,例如:减少孤立自己棋子的可能性,增加将骑士放在棋盘中心附近的可能性

看看代码,或者在 GitHub repo 用自己的训练数据自己训练一个新的网络!

如果您有任何批评或担忧,您可以通过 LinkedIn 或我的个人网站联系我。

用机器学习预测 Reddit 评论投票数

原文:https://towardsdatascience.com/predicting-reddit-comment-karma-a8f570b544fc?source=collection_archive---------19-----------------------

在本文中,我们将使用 Python 和 scikit-learn 包来预测 Reddit 上一条评论的投票数。我们拟合了各种回归模型,并使用以下指标比较了它们的性能:

  • r 来衡量拟合优度
  • 测试集上测量精确度的平均绝对误差(MAE)和均方根误差(RMSE)。

这篇文章基于来自这个 Github 库的工作。代码可以在这个笔记本里找到。

背景

Reddit 是一个流行的社交媒体网站。在这个网站上,用户在各种子主题中发布主题,如下图所示。

A thread in the “AskReddit” subreddit

用户可以对主题或其他评论进行评论。他们还可以给其他线程和评论投赞成票反对票

我们的目标是预测评论将获得的支持票数。

数据

该数据是一个 pickle 文件,包含发生在 2015 年 5 月的 1,205,039 行(评论),存放在 google drive 上,可以使用此链接下载。

下面列出了将用于建模的目标变量和相关特征。它们可以分为几类。

目标变量

  • 得分:评论的投票数

评论级别功能

  • 镀金:评论上镀金标签(高级赞)的数量
  • 区分:页面上的用户类型。“版主”、“管理员”或“用户”
  • 争议性:一个布尔值,表示(1)或(0)评论是否有争议(热门评论的支持票数与反对票数接近)
  • over_18 :线是否被标记为 NSFW
  • time_lapse :评论和线程上第一条评论之间的时间,以秒为单位
  • 小时评论:发布了一天中的小时评论
  • 工作日:星期几发表评论
  • is_flair :评论是否有 flair 文本(https://www . Reddit . com/r/help/comments/3 tbuml/whats _ a _ flair/)
  • is_flair_css :是否有注释 flair 的 css 类
  • 深度:线程中注释的深度(注释拥有的父注释数)
  • no_of_linked_sr: 注释中提到的子条目数
  • **链接网址数量:**评论中链接的网址数量
  • 主观性:“我”的实例数
  • is_edited : 评论是否被编辑
  • 被引用:评论是否引用另一个评论
  • no_quoted :评论中引用的次数
  • senti_neg :负面情绪得分
  • senti_neu :中性情绪得分
  • senti_pos :正面情绪得分
  • senti_comp :复合情绪得分
  • 字数:评论的字数

父级功能

  • time_since_parent :注释和父注释之间的时间,以秒为单位
  • parent_score: 父评论的分数(如果评论没有父,则为 NaN)
  • parent_cos_angle :注释与其父注释的嵌入之间的余弦相似度(https://nlp.stanford.edu/projects/glove/)

注释树根功能

  • is_root :评论是否为根
  • time _ since _ comment _ tree _ root:评论和评论树根之间的时间(秒)
  • 评论树根得分:评论树根得分

线程级功能

  • link_score :在线评论的 upvotes 开启
  • upvote_ratio :帖子评论上的所有投票中,upvotes 的百分比为 on
  • link_ups :线程上的投票数
  • time_since_link :线程创建以来的时间(秒)
  • no_past_comments :发表评论前帖子上的评论数
  • score_till_now :该评论发布时的帖子得分
  • title_cos_angle :注释与其线程标题嵌入之间的余弦相似度
  • is_selftext :线程是否有 selftext

设置

让我们加载我们需要的所有库。

**import** **pandas** **as** **pd
import** **numpy** **as** **np
import** **matplotlib.pyplot** **as** **plt
import** **seaborn** **as** **sns****from** **sklearn.metrics** **import** mean_squared_error, r2_score, mean_absolute_error
**from** **sklearn.model_selection** **import** train_test_split
**from** **sklearn.preprocessing** **import** LabelBinarizer**from** **sklearn.dummy** **import** DummyRegressor
**from** **sklearn.linear_model** **import** LinearRegression
**from** **sklearn.linear_model** **import** LassoCV
**from** **sklearn.linear_model** **import** RidgeCV
**from** **sklearn.linear_model** **import** ElasticNetCV
**from** **sklearn.neighbors** **import** KNeighborsRegressor
**from** **sklearn.tree** **import** DecisionTreeRegressor
**from** **sklearn.ensemble** **import** RandomForestRegressor
**from** **sklearn.ensemble** **import** GradientBoostingRegressor**import** **warnings** warnings.filterwarnings('ignore')

我们还定义了一些与模型交互的函数。

**def** model_diagnostics(model, pr=True):
    """
    Returns and prints the R-squared, RMSE and the MAE for a trained model
    """
    y_predicted = model.predict(X_test)
    r2 = r2_score(y_test, y_predicted)
    mse = mean_squared_error(y_test, y_predicted)
    mae = mean_absolute_error(y_test, y_predicted)
    if pr:
        print(f"R-Sq: **{r2:.4}**")
        print(f"RMSE: {np.sqrt(mse)}")
        print(f"MAE: **{mae}**")

    **return** [r2,np.sqrt(mse),mae]**def** plot_residuals(y_test, y_predicted):
    """"
    Plots the distribution for actual and predicted values of the target variable. Also plots the distribution for the residuals
    """
    fig, (ax0, ax1) = plt.subplots(nrows=1, ncols=2, sharey=**True**)
    sns.distplot(y_test, ax=ax0, kde = **False**)
    ax0.set(xlabel='Test scores')
    sns.distplot(y_predicted, ax=ax1, kde = **False**)
    ax1.set(xlabel="Predicted scores")
    plt.show()
    fig, ax2 = plt.subplots()
    sns.distplot((y_test-y_predicted), ax = ax2,kde = **False**)
    ax2.set(xlabel="Residuals")
    plt.show()**def** y_test_vs_y_predicted(y_test,y_predicted):
    """
    Produces a scatter plot for the actual and predicted values of the target variable
    """
    fig, ax = plt.subplots()
    ax.scatter(y_test, y_predicted)
    ax.set_xlabel("Test Scores")
    ax.set_ylim([-75, 1400])
    ax.set_ylabel("Predicted Scores")
    plt.show()**def** get_feature_importance(model):
    """
    For fitted tree based models, get_feature_importance can be used to get the feature importance as a tidy output
    """
    X_non_text = pd.get_dummies(df[cat_cols])
    features = numeric_cols + bool_cols + list(X_non_text.columns)
    feature_importance = dict(zip(features, model.feature_importances_))
    **for** name, importance **in** sorted(feature_importance.items(), key=**lambda** x: x[1], reverse=**True**):
        print(f"**{name:<30}**: **{importance:>6.2%}**")
        print(f"**\n**Total importance: {sum(feature_importance.values()):.2%}")
    **return** feature_importance

读入数据

df = pd.read_pickle('reddit_comments.pkl')

处理缺失值

数据有一些缺失值,通过插补或删除观察值来处理。以下各列中出现缺失值,原因如下:

  • parent_score :一些评论没有父评论(估算)
  • comment_tree_root_scoretime _ since _ comment _ tree _ root:一些评论是评论树的根(估算)
  • parent_cosine,parent_euc,title_cosine,title_euc :部分评论缺少有手套单词嵌入的单词(dropped)。此外,一些评论没有父项(parent_cosine,parent_title imputed)
df = df[~df.title_cosine.isna()] # drop where parent/title_cosine is NaNparent_scrore_impute = df.parent_score.mode()[0] # impute with mode of parent_score column
comment_tree_root_score_impute = df.comment_tree_root_score.mode()[0] # impute with mode of comment_tree_root_score column
time_since_comment_tree_root_impute = df.time_since_comment_tree_root.mode()[0] # impute with mode of time_since_comment_tree_root column
parent_cosine_impute = 0
parent_euc_impute = 0
df.loc[df.parent_score.isna(), 'parent_score'] = parent_scrore_impute
df.loc[df.comment_tree_root_score.isna(), 'comment_tree_root_score'] = comment_tree_root_score_impute
df.loc[df.time_since_comment_tree_root.isna(), 'time_since_comment_tree_root'] = time_since_comment_tree_root_impute
df.loc[df.parent_cosine.isna(), 'parent_cosine'] = parent_cosine_impute
df.loc[df.parent_euc.isna(), 'parent_euc'] = parent_euc_impute

选择变量

在下一步中,我们定义在训练模型时使用哪些变量。我们为布尔变量、多类别变量和数字变量制作了一个列表。

bool_cols = ['over_18', 'is_edited', 'is_quoted', 'is_selftext']cat_cols = ['subreddit', 'distinguished', 'is_flair', 'is_flair_css','hour_of_comment', 'weekday']

numeric_cols = ['gilded', 'controversiality', 'upvote_ratio','time_since_link',
                'depth', 'no_of_linked_sr', 'no_of_linked_urls', 'parent_score',
                'comment_tree_root_score', 'time_since_comment_tree_root',
                'subjectivity', 'senti_neg', 'senti_pos', 'senti_neu',
                'senti_comp', 'no_quoted', 'time_since_parent', 'word_counts',
                'no_of_past_comments', 'parent_cosine','parent_euc',
                'title_cosine', 'title_euc', 'no_quoted','link_score']

使用我们的变量列表,我们可以为建模准备数据。下面的步骤使用 scikit-learn 的LabelBinarizer从分类列中生成虚拟变量,然后组合所有变量。

lb = LabelBinarizer()
cat = [lb.fit_transform(df[col]) **for** col **in** cat_cols]
bol = [df[col].astype('int') **for** col **in** bool_cols]
t = df.loc[:, numeric_cols].values
final = [t] + bol + cat
y = df.score.values
x = np.column_stack(tuple(final))

我们使用 80–20 的比例将数据分成训练集和测试集。

X_train, X_test, y_train, y_test = train_test_split(x, y, test_size=0.2, random_state=10)

建模

在本节中,我们使用 scikit-learn 来拟合 Reddit 数据上的模型。我们从基线模型开始,然后尝试用套索、岭和弹性网回归来改进结果。此外,我们尝试了 K 近邻、决策树、随机森林和梯度推进回归。

首先,让我们定义一个字典来存储模型诊断的结果。

model_performance_dict = dict()

线性回归模型

基线模型

我们用一个简单的模型来建立一个基线。这个模型总是预测平均票数。

baseline = DummyRegressor(strategy='mean')
baseline.fit(X_train,y_train)
model_performance_dict["Baseline"] = model_diagnostics(baseline)

线性回归

linear = LinearRegression()
linear.fit(X_train,y_train)
model_performance_dict["Linear Regression"] = model_diagnostics(linear)

套索回归

lasso = LassoCV(cv=30).fit(X_train, y_train)
model_performance_dict["Lasso Regression"] = model_diagnostics(lasso)

岭回归

ridge = RidgeCV(cv=10).fit(X_train, y_train)
model_performance_dict["Ridge Regression"] = model_diagnostics(ridge)

弹性网回归

elastic_net = ElasticNetCV(cv = 30).fit(X_train, y_train)
model_performance_dict["Elastic Net Regression"] = model_diagnostics(elastic_net)

非线性回归模型

K 近邻回归

knr = KNeighborsRegressor()
knr.fit(X_train, y_train)
model_performance_dict["KNN Regression"] = model_diagnostics(knr)

决策树回归

dt = DecisionTreeRegressor(min_samples_split=45, min_samples_leaf=45, random_state = 10)
dt.fit(X_train, y_train)
model_performance_dict["Decision Tree"] = model_diagnostics(dt)

随机森林回归

rf = RandomForestRegressor(n_jobs=-1, n_estimators=70, min_samples_leaf=10, random_state = 10)
rf.fit(X_train, y_train)
model_performance_dict["Random Forest"] = model_diagnostics(rf)

梯度推进回归

gbr = GradientBoostingRegressor(n_estimators=70, max_depth=5)
gbr.fit(X_train, y_train)
model_performance_dict["Gradient Boosting Regression"] = model_diagnostics(gbr)

模型比较

我们基于三个指标来比较这些模型:R、MAE 和 RMSE。为此,我们定义了下面的函数。

**def** model_comparison(model_performance_dict, sort_by = 'RMSE', metric = 'RMSE'):

    Rsq_list = []
    RMSE_list = []
    MAE_list = []
    **for** key **in** model_performance_dict.keys():
        Rsq_list.append(model_performance_dict[key][0])
        RMSE_list.append(model_performance_dict[key][1])
        MAE_list.append(model_performance_dict[key][2])

    props = pd.DataFrame([])

    props["R-squared"] = Rsq_list
    props["RMSE"] = RMSE_list
    props["MAE"] = MAE_list
    props.index = model_performance_dict.keys()
    props = props.sort_values(by = sort_by)

    fig, ax = plt.subplots(figsize = (12,6))

    ax.bar(props.index, props[metric], color="blue")
    plt.title(metric)
    plt.xlabel('Model')
    plt.xticks(rotation = 45)
    plt.ylabel(metric)

让我们使用这个函数来比较基于每个指标的模型。

model_comparison(model_performance_dict, sort_by = 'R-squared', metric = 'R-squared')

model_comparison(model_performance_dict, sort_by = 'R-squared', metric = 'MAE')

model_comparison(model_performance_dict, sort_by = 'R-squared', metric = 'RMSE')

解释结果

考虑到性能和训练时间,随机森林模型是一个合理的选择。平均绝对误差约为 9.7,这意味着平均而言,模型估计误差约为 9.7。让我们看一些图,了解更多关于模型性能的信息。

y_predicted = rf.predict(X_test)
plot_residuals(y_test,y_predicted)

比较测试分数和预测分数的直方图,我们注意到,当目标变量较小时,模型往往会高估目标变量。此外,模型从不预测目标变量会远大于 2000。在目标变量较大的少数情况下,结果似乎有偏差。大多数意见只有少量的支持票,但 model 预计这些意见会得到更多的支持票。然而,当评论有极端数量的支持票时,模型会低估它。

残差的这种分布表明,合乎逻辑的下一步是探索堆叠模型的结果。堆叠是一种集合技术(如随机森林、梯度推进等。)这通常可以提高性能。我们将首先拟合一个分类器来预测向上投票的数量(具有像“少”、“一些”、“许多”这样的类),并且结果将被用作回归模型中的附加预测器。这种方法有可能减少错误并提高拟合度,因为除了我们的原始信息之外,回归模型还会有关于评论数量的提示,以帮助它进行预测。

基于树的模型也允许我们量化他们使用的特性的重要性。

rf_importances = get_feature_importance(rf)

最不重要的特征是不同子数据的指示变量。由于该数据仅包括五个最受欢迎且相当普通的子主题(食品、世界新闻、电影、科学和游戏)的评论,我们不认为这些功能非常重要。此外,还有许多不太重要或不重要的评论。这些特征可以被移除。这有助于避免过度拟合,并减少训练模型所需的时间。

五个最重要的特性是描述评论所在线程或评论父线程的特性。我们可能会预料到这一点,因为受欢迎和有趋势的内容会显示给更多的用户,所以接近有很多支持票的内容的评论也更有可能获得很多支持票。

还需要注意的是,许多非常重要的特性都缺少值。因此,对缺失值的处理方式进行更深入的分析可以提高模型的性能(例如,当我们删除评论树根时,parent score 是最重要的特性,大约占 25%)。使用平均值、中值的插值或使用简单线性回归的预测也值得测试。

结论

在本文中,我们概述了一个使用 scikit-learn python 库预测 Reddit 评论投票的机器学习工作流。我们比较了线性和非线性回归模型的性能,发现随机森林回归是最佳选择。

在快速检查了这个模型的残差之后,我们看到了许多改进的空间。该项目的下一步可能包括:

  • 使用较少的特征拟合模型,并将它们的性能与原始模型进行比较
  • 分析缺失值及其对模型性能的影响
  • 堆叠模型以提高性能

本文基于一个项目,该项目最初由 Adam Reevesman、Gokul Krishna Guruswamy、乐海、Maximillian Alfaro 和 Prakhar Agrawal 在旧金山大学数据科学硕士的机器学习入门课程中完成。相关的工作可以在这个 Github 仓库中找到,本文的代码可以在这个笔记本中找到。

我将很高兴收到以上任何反馈。在 areevesman@gmail.com,你可以通过 LinkedIn 或者电子邮件找到我。

用人口普查收入数据预测学校表现

原文:https://towardsdatascience.com/predicting-school-performance-with-census-income-data-ad3d8792ac97?source=collection_archive---------10-----------------------

Source: Pixabay

我小时候,我们家经常搬家。出于这个原因,我的父母一直在考虑找一个合适的社区居住。有几个因素影响了这个决定,但对于忧心忡忡的父母来说,有一个主导因素:一所好学校。

弗雷泽研究所是一家加拿大研究和教育机构,每年发布加拿大学校排名。这些评级是基于安大略省标准化评估 EQAO 的平均表现。

在这个数据科学项目中,我们将根据收入、位置、学校董事会以及学校是小学还是中学来分析多伦多的学校表现数据。在那之后,我们将看看我们是否可以预测 2017 年这些学校的评级。

获取学校评级数据

为了获得安大略省学校的评级,我们可以下载弗雷泽研究所发布的 pdf,然后将相关页面复制并粘贴到一个文本文件中,这样我们就可以使用 python 轻松地逐行扫描。小学和中学以单独的 pdf 格式给出,因此我们最终得到两个文本文件,其中共有 3810 所学校,格式如下:

Ajax [Public] Ajax OSSLT count: 363
ESL (%): 4.7 Special needs (%): 21.8
Actual rating vs predicted based 2016–17 Last 5 Years
on parents’ avg. inc. of $ n/a: n/a Rank: 596/747 n/a
Academic Performance 2013 2014 2015 2016 2017 Trend
Avg. level Gr 9 Math (Acad) 2.7 2.6 n/a 2.8 2.6 n/a
Avg. level Gr 9 Math (Apld) 1.8 1.8 n/a 1.9 1.9 n/a
OSSLT passed (%)-FTE 81.1 80.5 n/a 76.7 75.4 n/a
OSSLT passed (%)-PE 51.3 49.3 n/a 49.0 37.3 n/a
Tests below standard (%) 31.9 34.4 n/a 31.2 34.4 n/a
Gender gap (level)-Math M 0.1 M 0.1 n/a F 0.2 F 0.1 n/a
Gender gap OSSLT F 8.4 F 5.2 n/a F 14.1 F 20.2 n/a
Gr 9 tests not written (%) 0.7 1.5 n/a 0.0 0.7 n/a
Overall rating out of 10 5.5 5.0 n/a 5.4 4.7 n/a

第一行显示学校名称、学校所在的城市以及参加测试的学生人数。与我们最相关的最后一行显示了学校的评分(满分 10 分)。

我们可以将这些信息与来自多伦多数据目录的学校位置数据库联系起来。数据库为我们提供了以下信息:

  • 学校名称
  • 学校董事会(天主教、公立或私立)
  • 位置(地址、纬度、经度和自治市)
  • 政府特定标识符

使用 Python,我们可以编写一个脚本来解析这个文本文件,提取评级,并将这些评级作为列添加到多伦多学校数据库中。这样做只是将正则表达式应用到正确的行上。

import pandas as pdfile = 'Elementary Schools 2017.txt'
file2 = 'Secondary Schools 2017.txt'
years = [2013, 2014, 2015, 2016, 2017]
df = pd.read_excel('SCHOOL.xlsx')with open(file) as f:
    for line in f:
        if '[' in line:
            city = re.search('] (.*?) ', line).group(1)
            if city == 'Toronto':
                school_is_in_toronto = True
                school_name = re.search('(.*) \[', line)
                school_name = school_name.group(1).upper()
        if 'Overall' in line:
            if school_is_in_toronto:
                ratings = re.search('10 (.*)', line).group(1)
                ratings = ratings.split()[0:-1] row = df['NAME'].str.startswith(school_name) if file == 'Elementary Schools 2017.txt':
                    df.loc[row, 'SCHOOL_TYPE'] = 'ELEMENTARY'
                else:
                    df.loc[row, 'SCHOOL_TYPE'] = 'SECONDARY' for i in range(len(ratings)):
                    column = str(years[i]) + ' RATING'
                    df.loc[row, column] = ratings[i]school_is_in_toronto = False

我们首先浏览文件,找到有方括号的行(唯一有方括号的行是有学校名称和城市信息的行)。接下来,我们检查城市是否在多伦多,如果是,我们存储学校的名称。在代码的第二部分,我们检查单词“总体”(只出现在最后一行)并提取评级。使用我们从文本文件中记录的学校名称,我们使用“name”列将其与多伦多学校数据库进行匹配。因为小学和中学存储在两个文本文件中,所以我们也可以添加这个特性。最后,我们添加了 5 列,代表每年的评级。

获取收入数据

告诉我们一个地区的家庭收入中值的分类普查数据可以很容易地从人口普查地图的 API 中下载。但是,普查地点数据是按传播区域 (DA)排序的。要将 DA 转换成地理位置,我们可以下载 StatsCan 提供的文件,它告诉我们加拿大每个传播区域的中心纬度和经度。

在合并了熊猫的两个文件和收集了多伦多的数据后,我们现在有了一个包含 3676 个传播区域的表格,包括它们的经度和纬度,以及它们的家庭收入中值。

income_at_latlongs_df = pd.merge(cnsmpr_df, statscan_df, 
                                 how='inner',on=['DA_ID'])
print(income_at_latlongs_df.head())

为了将收入信息与评级信息联系起来,我们可以找到与每所学校距离最小的 DA,并假设它是该邻域的中值收入。

为了实现这一点,我们可以使用库 GeoPy( pip install geopy)来寻找 vincenty 距离(球面上两点之间的距离)。

from geopy.distance import vincentyincomes = []
for school_coordinate in school_coordinates:
    minimum_distance = 9999
    for i, DA_coordinate in enumerate(DA_coordinates):
        distance = vincenty(school_coordinate, DA_coordinate)
        if distance < minimum_distance:
            minimum_distance = distance
            row = income_table.index[i] income_for_school_area = float(income_at_latlongs_df.loc
                                   [row, 'Median_Household_Income'])
    incomes.append(income_for_school_area)df['INCOME'] = incomes

将这些收入添加到学校位置数据框架后,我们现在有了完整的数据。

数据可视化

首先,我们可以使用图书馆 gmplot ( pip install gmplot)制作一个散点图,显示每个学校的位置。

该图显示,多伦多中部和东北部的学校评级较高(较亮的点表示评级较高)。通过查阅由人口普查局提供的收入热图,我们可以看到有可能存在相关性。

我们来看看多伦多给出的评分分布。

from statistics import stdev, mean
import matplotlib.pyplot as plt
import seaborn as sns
sns.set(color_codes=True)ratings = df['2017 RATING']sns.distplot(ratings)
plt.title('Distribution of 2017 Ratings in Toronto')
plt.xlabel('School Rating Out of 10')
plt.ylabel('Proportion of Schools')
plt.show()print(mean(ratings), stdev(ratings))

数据大致呈正态分布,均值为 6.35,标准差为 1.73。

既然小学和中学的数据我们都有,那就来看看两种类型的区别吧。

fig = sns.boxplot(x=df['SCHOOL_TYPE'], y=ratings)
plt.title('Distribution of 2017 Ratings by School Type')
plt.xlabel('School Type')
plt.ylabel('School Rating Out of 10')
labels = ['Secondary', 'Elementary']
fig.set_xticklabels(labels)
plt.show()

在这里我们看到,小学的评级通常高于中学。

同样,也可以绘制每个学校董事会评级的箱线图。

不出所料,私立学校排名最高,而公立和天主教学校排名相近。

我们也可以做一个多伦多每个自治市的收视率箱线图。

除了约克市的四分位间距低于其他城市外,其他城市的评级似乎相似。稍后,我们可以测试这种差异在统计上是否显著。

为了恰当地将学校的评级形象化为居民年收入中值的函数,我们应该将收入以 2 万美元为间隔放入垃圾箱。

highest_bin = 200000
num_bins = 10
intervals = highest_bin / num_bins
values = []
column = 'INCOME'
for _, row in df.iterrows():
    bin = row[column]/intervals
    bin = min(bin, num_bins)
    bin = (math.floor(bin))
    values.append(bin)df[column+'_BINS'] = values

绘制数据的箱线图得出:

这张图暗示了在一个街区的中值收入和离那个街区最近的学校的评级之间有某种关联。

统计显著性

即使我们在上面的方框图中直观地看到了差异,这也不足以证明这种差异不仅仅是偶然的。我们必须证明这种差异具有统计学意义。为了找到统计意义,我们可以进行单向方差分析。通过方差分析,我们陈述了零假设,即类别中的样本是从具有相同均值的总体中抽取的。例如,对于学校董事会列,我们假设 _catholic = _public = _private。另一个假设是,样本是从拥有不同均值的人群中抽取的,因此会受到他们所属群体的影响。

from scipy import statscolumns_to_analyze = ['MUN', 'SCHOOL_BOARD', 'SCHOOL_TYPE']
for column in columns_to_analyze:
    grouped_dfs = []
    for group in df.groupby(column).groups:
        grouped_df = df.groupby(column).get_group(group)
        grouped_df = grouped_df.reset_index()['2017 RATING']
        grouped_dfs.append(list(grouped_df.dropna()))
    F, p = stats.f_oneway(*grouped_dfs)
    print(f'{column}: {p: 0.2e}')MUN: 3.70e-05
SCHOOL_BOARD: 9.25e-07
SCHOOL_TYPE: 1.33e-05

每一列的方差分析给出了远低于 0.05 的 p 值,因此我们可以说差异具有统计学意义。我们拒绝每列的零假设,即各组的总体均值相同。

特征工程

我们可以使用回归技术来看看学校的评级是否可以使用我们创建的特征来预测。

但是,在我们将特征放入模型之前,必须填充缺失值,并且所有特征必须被热编码。为了处理缺失值,我们用已收集的评分平均值替换任何缺失值。我们应该确保平均值中不包括 2017 年的评级,因为这是我们试图预测的值。我们可以在遍历前面的文本文件时填充缺失的值。

def fill_missing_values(ratings_with_na):ratings_with_na = [np.nan if rating == 'n/a' 
                              else float(rating) 
                              for rating in ratings_with_na]if all([rating == 'n/a' for rating in ratings_with_na[0:-1]]):
            return ratings_with_namean_rating = round(np.nanmean(ratings_with_na[0:-1]), 1)filled_missing_values = []
    for rating in ratings_with_na:
        if rating in [np.nan]:
            filled_missing_values.append(mean_rating)
        else:
            filled_missing_values.append(rating)return filled_missing_values

该函数采用一个包含 5 个评级的列表,并将所有“不适用”的评级转换为 np.nan,因此我们可以应用 np.nanmean()来计算平均值。然后,我们检查前 4 个评分是否缺失,如果缺失,我们将返回包含缺失值的列表(稍后我们将删除这些行,因为它们非常少)。最后,我们找到 2013-2016 年间的平均评级,并返回一个没有缺失值的新评级列表。

为了对每个分类值进行热编码,我们可以使用 pd.get_dummies(),它将每个分类值转换成多个列。根据数据点是否属于该类别,每列的值可能为 0 或 1。

ordinal_columns = df[['INCOME_BINS', '2013 RATING', '2014 RATING',
                      '2015 RATING', '2016 RATING', '2017 RATING']]
categorical_columns = ['MUN', 'SCHOOL_TYPE', 'SCHOOL_BOARD']
categorical_columns = pd.get_dummies(df[categorical_columns])
ohe_df = pd.concat([categorical_columns, ordinal_columns], axis=1)

包含重命名列的新数据框架如下所示。

既然所有缺失值都已填充,分类列也已热编码,现在让我们绘制皮尔逊相关矩阵,找出我们应该使用的特征。

from matplotlib.colors import LinearSegmentedColormapcorr_sorted = abs(ohe_df.corr()['2017 Rating']).sort_values()
sorted_df = ohe_df[list(corr_sorted.index)]
corr = round(sorted_df.corr(), 2)min_color = 'white'
max_color = (0.03137254, 0.18823529411, 0.41960784313, 1)
cmap = LinearSegmentedColormap.from_list("", [max_color,
                                              min_color,
                                              max_color])
fig = sns.heatmap(corr, annot=True, cmap=cmap,
                  xticklabels=corr.columns.values,
                  yticklabels=corr.columns.values,
                  cbar=False)
plt.xticks(rotation=0)
fig.xaxis.set_tick_params(labelsize=8)
fig.yaxis.set_tick_params(labelsize=8)plt.show()

对相关矩阵进行排序,颜色相对于 0 对称绘制,因此我们可以看到 0.19 的相关性与-0.19 的相关性一样显著。正如假设的那样,每年的学校评级与其他年份的评级密切相关,而收入和私立学校的地位与评级有一定的相关性。

预言;预测;预告

首先,我们必须建立指标来评估我们的模型是否有效。在测量回归性能时,我们将使用平均绝对误差和均方根误差。为了衡量我们的机器学习模型是否值得努力,我们将创建一个基线。例如,如果我们每次都预测平均值,并获得比任何机器学习模型更低的均方误差/平均绝对误差,那么我们的模型实际上是无用的。如果我们每次只预测平均评分(6.35),以下是衡量标准。

y_predicted = mean(df_y)
rmse = (mean((y_predicted - df_y)**2))**0.5
mae = mean(abs(y_predicted - df_y))
print(f'RMSE: {rmse: 0.4f}, MAE: {mae: 0.4f}')RMSE:  1.7311, MAE:  1.3864

如果我们对所有情况的预测值都是 6.35,那么平均来说,预测值将与真实值相差约 1.39 个点。

现在,我们可以设置模型来预测 2017 年给出的评分!为了了解在没有往年信息的情况下能否预测 2017 年的评级,我们将使用学校类型、学校董事会、自治市和收入特征。下面是随机森林、梯度推进、线性回归和留一交叉验证的支持向量机的设置代码。

from sklearn.model_selection import cross_validate, LeaveOneOut
from sklearn.ensemble import RandomForestRegressor, 
     GradientBoostingRegressor
from sklearn.linear_model import LinearRegression
from sklearn.svm import SVRdef LOOCV(ohe_df, use_previous_years=False):
    models = {
     'RFR': RandomForestRegressor(n_estimators=50, random_state=0),
     'GBR': GradientBoostingRegressor(max_depth=1, random_state=0),
     'LIR': LinearRegression(),
     'SVR': SVR(kernel='linear')
    }
    if use_previous_years is False:
        ordinal_columns = df[['INCOME_BINS', '2017 RATING']]
        ohe_df = pd.concat([categorical_columns,
        ordinal_columns], axis=1) df_x = ohe_df.iloc[:, :-1]
    df_y = ohe_df.iloc[:, -1] scoring = ['neg_mean_squared_error', 'neg_mean_absolute_error']
    loo = LeaveOneOut.get_n_splits(df_x, df_y) for name, model in models.items():
        scores = cross_validate(model, df_x, df_y, cv=loo,
                                scoring=scoring)
        rmse = (-1*mean(scores['test_neg_mean_squared_error']))**0.5
        mae = -1*mean(scores['test_neg_mean_absolute_error'])
        print(f'{name} RMSE: {rmse: 0.4f}, MAE: {mae: 0.4f}')LOOCV(ohe_df)RFR RMSE:  1.6488, MAE:  1.2841
GBR RMSE:  1.5320, MAE:  1.2210
LIR RMSE:  1.5255, MAE:  1.2210
SVR RMSE:  1.5447, MAE:  1.2354

我们可以看到,线性回归的平均绝对误差为 1.22,RMSE 为 1.5255。这是不坏的表现,因为这意味着我们的预测平均在真实值的 1.22 点以内,这比我们每次预测平均值要好 0.16 点或 12%。

为了获得更多的信息,我们来看看与往年的信息有哪些误差。

LOOCV(models, df_x, df_y, use_previous_years=True)RFR RMSE:  1.0381, MAE:  0.7906
GBR RMSE:  0.9796, MAE:  0.7443
LIR RMSE:  0.9513, MAE:  0.7215
SVR RMSE:  0.9520, MAE:  0.7200

SVM 和线性回归这次效果最好,平均绝对误差为 0.72,比我们每次预测平均值的结果好 0.76 点或 48%!

结论

在本文中,我们汇总了来自多伦多数据目录、StatsCan 和弗雷泽研究所的数据。在数据被转换成可用的形式后,它被用来可视化一所学校的评级(满分为 10 分)与各种特征(如学校董事会和中等邻里收入)之间的相关性。发现有相关性,有了这些信息就有可能预测一个学校的评级平均 1.22 分。

数据从质量上说的是众所周知的:贫困可以预测许多特征,而教育是一个非常重要的特征。

接下来的步骤可能包括:

  • 将其他城市纳入数据
  • 利用学校雇用的教师的信息
  • 获取除收入以外的家庭人口统计数据,看看它如何影响学校的表现

文章中使用的所有代码都可以在我的 GitHub 上找到。如果你对这篇文章有任何反馈或批评,你可以通过 LinkedIn 联系我。

预测亚马逊产品评论的评分

原文:https://towardsdatascience.com/predicting-sentiment-of-amazon-product-reviews-6370f466fa73?source=collection_archive---------1-----------------------

分类器算法

介绍

在机器学习中,分类用于根据包含类别事先已知的观察值的训练数据集,将新观察值分类到特定的集合/类别中。最常见的例子是电子邮件的“垃圾邮件”或“非垃圾邮件”类别。在电子商务中,可以使用分类器算法来基于单词对评论的情感进行分类。语言中的特定单词根据它们的积极或消极情绪被预先分类。

分类是监督学习的一个实例。训练集已正确识别观察值。分类器算法用于基于与训练数据集的相似性和/或距离从未分类的无监督数据中创建聚类/集合。

分析背后的统计数据

在简单分类器模型中,正和负数据点的简单计数将定义总体正或负集合。这就有问题了。例如,在句子中的单词的情况下,“Great”和“Good”都是肯定词。但是“很棒”比“好”的影响更大。我们需要训练我们的模型来衡量确定的数据点。

分类器模型边界可以是将“阳性”和“阴性”结果分开的简单线,也可以是将多个组分开的更复杂的超平面。

可以使用模型的误差或准确度以及“假阳性”和“假阴性”来观察模型的有效性。

使用的工具

  1. 计算机编程语言
  2. GraphLab
  3. s 帧(类似于熊猫数据帧)

数据加载

我们准备对亚马逊产品评论进行分类,了解正面或负面评论。亚马逊有 5 星评级。我们将用它来比较我们的预测。

*> product_reviews=graphlab.SFrame(‘amazon_baby.gl/’)**> product_reviews.head()*

*> product_reviews.show()*

创建一个单词字典,将使用我的模型进行分类。

*> product_reviews[‘wordcount’] = graphlab.text_analytics.count_words(product_reviews[‘review’])*

选择一个特定的产品来预测评论的情绪。Vulli Shopie 是一款适合婴儿长牙的长颈鹿玩具。过滤产品的所有评论。

*> vs_reviews = product_reviews[product_reviews[‘name’]==’Vulli Sophie the Giraffe Teether’]**> vs_reviews[‘rating’].show(view=’Categorical’)*

使用分类器模型的数据分析

过滤掉中间等级为 3 的。高于 4 的评级意味着它是正面评级。

*> product_reviews = product_reviews[product_reviews[‘rating’] !=3]**> product_reviews[‘binrating’] = product_reviews[‘rating’] >= 4*

创建培训和测试数据集。

*> train_data, test_data = product_reviews.random_split(0.8, seed=0)*

构建一个情感分类器来识别评论是正面的还是负面的情感。逻辑分类器模型将使用来自训练数据的单词(单词计数列)和评级(binrating)来开发预测目标(binrating)的模型。

*> sentiment_model = graphlab.logistic_classifier.create (train_data,* *target=’binrating’,* *features=[‘wordcount’],* *validation_set=test_data)*

评估测试数据的模型,并使用 ROC(受试者工作特性)曲线显示。

*> sentiment_model.evaluate(test_data, metric=’roc_curve’)*

结果

*> sentiment_model.show(view=’Evaluation’)*

91%的准确率就不错了。

使用我们建立的模型,预测 Vullie Sophie 长颈鹿玩具的每个评论情绪。

*> vs_reviews[‘predicted_sentiment_by_model’]=
sentiment_model.predict(vs_reviews, output_type=’probability’)*

我们的模式运行得非常好。对于更高数量的情感(接近 1),我们可以观察到亚马逊产品星级为 5。

我们可以根据模型预测的情绪来查看最积极和最消极的评论。

*> vs_reviews=vs_reviews.sort(‘predicted_sentiment_by_model’, ascending=False)**> vs_reviews[0][‘review’]*

苏菲,哦,苏菲,你的时候到了。我的孙女,维奥莱特 5 个月大,开始长牙了。小索菲给瓦奥莱特带来了多大的快乐。索菲是由非常柔韧的橡胶制成的,结实但不坚韧。对瓦奥莱特来说,把索菲扭成前所未闻的姿势,让她把索菲送进嘴里是相当容易的。小鼻子和小蹄子完全适合小嘴巴,流口水是有目的的。索菲身上的油漆是食品级的。苏菲 1961 年出生于法国。制造商想知道为什么没有婴儿用品,于是在圣索菲节用最好的不含邻苯二甲酸盐的橡胶制作了索菲,这个名字就这样诞生了。从那时起,数以百万计的苏菲出现在这个世界上。她很柔软,婴儿的小手很容易抓住。紫罗兰特别喜欢苏菲那凹凸不平的头和角。苏菲的脖子很长,很容易抓住和扭动。她有可爱的,相当大的斑点,吸引了紫罗兰的注意。索菲有快乐的小吱吱声,带来了紫高兴的尖叫。她能让苏菲吱吱叫,这带来了很多快乐。索菲光滑的皮肤抚慰着维奥莱特的小牙龈。索菲有 7 英寸高,是婴儿抱和爱的正确尺寸。众所周知,婴儿抓到的第一件东西是放进嘴里的——拥有一个能刺激所有感官并有助于解决出牙问题的玩具是多么美妙。苏菲很小,可以放进任何尺寸的口袋或包里。索菲是从几个月到一岁婴儿的最佳选择。听到发现索菲不可抗拒的婴儿发出的咯咯笑声是多么美妙啊。苏菲万岁!强烈推荐。pris rob 12–11–09 "

最负面的评论。

*> vs_reviews[-1][‘review’] # most negative*

“我的儿子(现在 2.5 岁)喜欢他的索菲,我每次去参加婴儿送礼会都会买一个。现在,我的女儿(6 个月)就在今天差点被它呛到,我再也不会给她吃了。如果我不在听得见的范围内,那可能是致命的。她发出的奇怪声音引起了我的注意,当我走到她面前,发现她弯曲的前腿被塞进了她的喉咙,她的脸变成了紫色/蓝色时,我慌了。我把它拉出来,她在尖叫前吐了整个地毯。真不敢相信我对这个玩具的看法怎么就从必须要变成不能用了。请不要忽视任何关于窒息危险的评论,它们并没有过分夸张!”

用 Python 中的随机森林分类器预测恒星、星系和类星体

原文:https://towardsdatascience.com/predicting-stars-galaxies-quasars-with-random-forest-classifiers-in-python-edb127878e43?source=collection_archive---------10-----------------------

来自斯隆数字巡天数据集的见解

The SDSS website banner!

最近,在我寻找有趣(物理学相关)数据集的过程中,我偶然发现了 Kaggle 上的斯隆数字巡天(SDSS)数据集,以及 Faraz Rahman 的辉煌 Kaggle 内核,它使用 R 中的支持向量机预测了不同类型的天文物体(恒星、星系和类星体)。然而,由于 R 带回了一些可怕的记忆训练 SVM 需要大量的计算工作,我决定使用 sci 来尝试一下这个分类问题

数据概述

标签

那么恒星、星系和类星体到底是什么?如果你在开始这个项目之前问我,我可能无法回答(真为我感到羞耻)。幸运的是,法拉兹的笔记本简明扼要地总结了它们是什么:

  • 一个 星系 是一个由恒星、恒星残骸、星际气体、尘埃和暗物质组成的引力束缚系统。星系根据它们的视觉形态分为椭圆形、螺旋形和不规则形。许多星系被认为在其活动中心有超大质量黑洞。
  • 恒星 是一种天文物体,由一个发光的等离子球体组成,通过自身重力聚集在一起。离地球最近的恒星是太阳。
  • 一颗 类星体 又称准恒星天体,是一颗极其明亮的活动星系核(AGN)。类星体辐射的能量是巨大的。最强大的类星体的亮度超过 1041 瓦,是普通大星系如银河系的数千倍。

安德鲁·邦克教授关于恒星和星系(S26) 的短选项课程的页面也是一个很好的资源。

特征

细节的细节可以在 Kaggle 数据集概述上找到。更重要的功能总结如下:

  • ra,dec —分别为赤经和赤纬
  • u,g,r,I,z-过滤波段(又称光度系统或天文星等)
  • 运行、重新运行、camcol、字段—图像中字段的描述符(即 2048 x 1489 像素)
  • 红移——由于天文物体的运动,波长增加
  • 车牌——车牌号码
  • mjd —修正儒略历观测日期
  • 光纤 id —光纤 id

探索性分析

这里的分析遵循了法拉兹的分析。我会让观想自己说话。

加载库和数据

*import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
%matplotlib inlinedf = pd.read_csv("skyserver.csv")*

数据描述

自然,我从df.head()df.describe()df.info()开始。df.info()的输出如下所示:

*<class 'pandas.core.frame.DataFrame'>
RangeIndex: 10000 entries, 0 to 9999
Data columns (total 18 columns):
objid        10000 non-null float64
ra           10000 non-null float64
dec          10000 non-null float64
u            10000 non-null float64
g            10000 non-null float64
r            10000 non-null float64
i            10000 non-null float64
z            10000 non-null float64
run          10000 non-null int64
rerun        10000 non-null int64
camcol       10000 non-null int64
field        10000 non-null int64
specobjid    10000 non-null float64
class        10000 non-null object
redshift     10000 non-null float64
plate        10000 non-null int64
mjd          10000 non-null int64
fiberid      10000 non-null int64
dtypes: float64(10), int64(7), object(1)
memory usage: 1.4+ MB*

没有一个条目是 NaN,这是维护良好的数据集所期望的。清洁不是必须的。

唯一条目

nunique()方法返回包含每列唯一条目数量的 Series 对象。

*df.nunique().to_frame().transpose()*

每个天文实体的出现

然后我在班级栏上运行了value_counts()

*occurrences = df['class'].value_counts().to_frame().rename(index=str, columns={'class': 'Occurrences'})occurrences*

我们看到大多数条目不是星系就是恒星。只有 8.5%的条目被归类为类星体。

密度分布图

使用核密度估计(kde),我绘制了各种特征的(平滑)密度分布。

*featuredf = df.drop(['class','objid'], axis=1)
featurecols = list(featuredf)
astrObjs = df['class'].unique()colours = ['indigo', '#FF69B4', 'cyan']plt.figure(figsize=(15,10))
for i in range(len(featurecols)):
    plt.subplot(4, 4, i+1)
    for j in range(len(astrObjs)):
        sns.distplot(df[df['class']==astrObjs[j]][featurecols[i]], hist = False, kde = True, color = colours[j], kde_kws = {'shade': True, 'linewidth': 3}, label = astrObjs[j])
    plt.legend()
    plt.title('Density Plot')
    plt.xlabel(featurecols[i])
    plt.ylabel('Density')
plt.tight_layout()*

还为每个类别绘制了滤波器频带密度。

*filterbands = pd.concat([df.iloc[:,3:8], df['class']],axis=1)plt.figure(figsize=(15,5))
plt.suptitle('Density Plots')
sns.set_style("ticks")
for i in range(len(astrObjs)):
    plt.subplot(1, 3, i+1)
    for j in range(len(featurecols2)):
        sns.distplot(df[df['class']==astrObjs[i]][featurecols2[j]], hist = False, kde = True, kde_kws = {'shade': True, 'linewidth': 3}, label = featurecols2[j])
    plt.legend()
    plt.xlabel(astrObjs[i])
    plt.ylabel('Density')
plt.tight_layout()*

附加可视化

为了完整起见,我包括一个 3D 图,与原始笔记本相同。最初的意图似乎是确定 SVM 的线性核是否有效(如果我错了,请纠正我)。底部有很多群集,我取了红移的对数(忽略误差)以使可视化更清晰。

*from mpl_toolkits.mplot3d import Axes3Dfig = plt.figure(figsize=(5,5))
ax = Axes3D(fig)for obj in astrObjs:
    luminous = df[df['class'] == obj]
    ax.scatter(luminous['ra'], luminous['dec'], np.log10(luminous['redshift']))ax.set_xlabel('ra')
ax.set_ylabel('dec')
ax.set_zlabel('log redshift')ax.view_init(elev = 0, azim=45)plt.show()*

构建随机森林分类器

训练集和测试集分离

传统的列车测试分割可以通过以下方式完成:

*from sklearn.model_selection import train_test_split
from sklearn.ensemble import RandomForestClassifierx_train, x_test, y_train, y_test = train_test_split(features, labels, test_size=0.3, random_state=123, stratify=labels)clf = RandomForestClassifier()*

训练复杂性

当我最初试图用sklearn.svm.linearSVC训练我的数据时,我的笔记本电脑开始严重过热。训练时间复杂度一般在 O(mn)到 O(mn)之间,其中 m 是特征数,n 是观测数,如 Jessica Mick 此处所解释。另一方面,growing CART(分类和回归树)的训练复杂度为 O(mn logn)和 O(mn),这里的解释为(随机森林是 CART 的系综)。由于时间、耐心和手头的咖啡有限,我决定换成随机森林模型。

事后看来,我可以做的一件事是将我的数据缩放到[-1,1]来加速 SVM(甚至随机森林),正如 Shelby Matlock 在同一篇文章中提到的。这样我也能得到更稳定的预测结果。

*from sklearn.preprocessing import MinMaxScaler
scaling = MinMaxScaler(feature_range=(-1,1)).fit(x_train)
x_train_scaled = scaling.transform(x_train)
x_test_scaled = scaling.transform(x_test)*

超参数优化

对于超参数调谐,我发现这个这个相当方便。我们首先实例化一个随机森林,并查看可用超参数的默认值。美化打印get_params()方法:

*from pprint import pprint
pprint(clf.get_params())*

这给出了:

*{'bootstrap': True,
 'class_weight': None,
 'criterion': 'gini',
 'max_depth': None,
 'max_features': 'auto',
 'max_leaf_nodes': None,
 'min_impurity_decrease': 0.0,
 'min_impurity_split': None,
 'min_samples_leaf': 1,
 'min_samples_split': 2,
 'min_weight_fraction_leaf': 0.0,
 'n_estimators': 10,
 'n_jobs': None,
 'oob_score': False,
 'random_state': None,
 'verbose': 0,
 'warm_start': False}*

我决定关注的超参数是:

  • n_estimators(森林中的树木数量)
  • max_features (max。节点分割中使用的特征数量,通常为。<数据集中的特征数量)
  • max_depth(最大。每个决策树中的层数)
  • min_samples_split(敏。分割节点之前节点中的数据点数)
  • min_samples_leaf(最小。节点中允许的数据点数)
  • criterion(用于确定决策树停止标准的度量)

使用随机搜索进行调整

为了缩小搜索范围,我首先进行了随机搜索交叉验证。在这里,我使用 k = 10 倍交叉验证(cv=10)、跨越 100 个不同组合(n_iter=100)并同时使用所有可用内核(n_jobs=-1)来执行参数的随机搜索。随机搜索随机选择特征的组合,而不是遍历每个可能的组合。更高的n_itercv分别导致更多的组合和更小的过拟合可能性。

*from sklearn.model_selection import RandomizedSearchCVhyperparameters = {'max_features':[None, 'auto', 'sqrt', 'log2'],
                   'max_depth':[None, 1, 5, 10, 15, 20],
                   'min_samples_leaf': [1, 2, 4],
                   'min_samples_split': [2, 5, 10],
                   'n_estimators': [int(x) for x in np.linspace(start = 10, stop = 100, num = 10)],
                   'criterion': ['gini', 'entropy']}rf_random = RandomizedSearchCV(clf, hyperparameters, n_iter = 100, cv = 10, verbose=2, random_state=123, n_jobs = -1)rf_random.fit(x_train, y_train)*

一大堆东西出现了。为了获得最佳参数,我调用了:

*rf_random.best_params_*

这给出了:

*{'n_estimators': 100,
 'min_samples_split': 5,
 'min_samples_leaf': 2,
 'max_features': None,
 'max_depth': 15,
 'criterion': 'entropy'}*

使用网格搜索进行调整

我现在可以指定更小范围的超参数来关注。GridSearchCV 非常适合超参数的微调。

*from sklearn.model_selection import GridSearchCVhyperparameters = {'max_features':[None],
                   'max_depth':[14, 15, 16],
                   'min_samples_leaf': [1, 2, 3],
                   'min_samples_split': [4, 5, 6],
                   'n_estimators': [90, 100, 110],
                   'criterion': ['entropy']}rf_grid = GridSearchCV(clf, hyperparameters, cv = 10, n_jobs = -1, verbose = 2)
rf_grid.fit(x_train, y_train)*

这花了我大约 50 分钟。我打了电话:

*rf_grid.best_params_*

这返回了:

*{'criterion': 'entropy',
 'max_depth': 14,
 'max_features': None,
 'min_samples_leaf': 2,
 'min_samples_split': 5,
 'n_estimators': 100}*

训练分类器

我最后用最佳超参数更新了分类器。

*clf.set_params(criterion = 'entropy', max_features = None, max_depth = 14, min_samples_leaf = 2, min_samples_split = 5, n_estimators = 100)*

测试和评估

然后,我在测试集上测试了更新后的分类器,并根据几个指标对其进行了评估。

准确性得分和 F1 得分

注意,accuracy_score是指校正预测的分数,f1_score是精度(分类器不将阴性样本标记为阳性的能力)和召回率(分类器找到所有阳性样本的能力)的加权平均值。scikit-learn 文档最好地解释了这些概念:

Formula for accuracy_score

**

Formula for f1_score, where beta=1

sklearn.metrics有这些现成的。列表f1_score中分数的顺序对应于类的编码方式,这可以通过使用分类器的.classes_属性来访问。

*from sklearn.metrics import accuracy_score, f1_scoresortedlabels = clf.classes_
accscore = accuracy_score(y_test, y_pred)
f1score = f1_score(y_test, y_pred, average = None)print(accscore)
for i in range:
    print((sortedlabels[i],f1score[i]), end=" ")*

这将返回非常令人满意的分数。

*0.99
('GALAXY', 0.9900265957446809) ('QSO', 0.9596774193548387) ('STAR', 0.9959935897435898)*

混淆矩阵

A 混淆矩阵 C 有矩阵元素 C_(i,j)对应于已知在 I 组但预测在 j 组的观测值的数量,换句话说,对角线元素代表正确的预测,而非对角线元素代表错误标记。我们的目标是得到混淆矩阵的大对角线值 C(I,I)。

我们看一下分类报告和混淆矩阵。

*from sklearn.metrics import classification_report, confusion_matrixcm = confusion_matrix(y_test, y_pred, sortedlabels)print(classification_report(y_test, y_pred))
print(cm)*

这将返回:

*precision    recall  f1-score   support

      GALAXY       0.98      0.99      0.98      1499
         QSO       0.95      0.89      0.92       255
        STAR       0.99      1.00      1.00      1246

   micro avg       0.98      0.98      0.98      3000
   macro avg       0.97      0.96      0.97      3000
weighted avg       0.98      0.98      0.98      3000

[[1481   11    7]
 [  29  226    0]
 [   1    1 1244]]*

可视化混淆矩阵

我一般觉得有用(而且好看!)来绘制混淆矩阵。在我选择的 seaborn 调色板中,较深的颜色意味着更多的条目。

*cm = pd.DataFrame(cm, index=sortedlabels, columns=sortedlabels)sns.set(font_scale=1.2)
sns.heatmap(cm, linewidths=0.5, cmap=sns.light_palette((1, 0.2, 0.6),n_colors=10000), annot=True)
plt.xlabel('Predicted')
plt.ylabel('True')*

如果你有反馈/建设性的批评,请在下面随意评论!

用 Python 预测股票价格

原文:https://towardsdatascience.com/predicting-stock-prices-with-python-ec1d0c9bece1?source=collection_archive---------3-----------------------

用 100 行代码

投资股票市场过去需要大量资金和经纪人,经纪人会从你的收入中提成。然后 Robinhood 颠覆了这个行业,让你只需投资 1 美元,完全避开经纪人。Robinhood 和类似的应用向任何拥有联网设备的人开放了投资,并让非投资者有机会从最新的科技初创企业中获利。

“space gray iPhone X turned on” by rawpixel on Unsplash

然而,让我们这些不是经济学家或会计师的人自由投资“最热门”或“趋势”股票并不总是最好的财务决策。

成千上万的公司使用软件来预测股票市场的走势,以帮助他们的投资决策。普通的罗宾汉用户没有这个功能。原始预测算法,如时间序列线性回归,可以通过利用 python 包如 scikit-learniexfinance来进行时间序列预测。

这个程序将从网上抓取给定数量的股票,预测它们在一定天数内的价格,并向用户发送短信,通知他们可能适合查看和投资的股票。

设置

为了创建一个程序来预测股票在一定天数内的价值,我们需要使用一些非常有用的 python 包。您需要安装以下软件包:

  1. y
  2. sklearn
  3. exfinance

如果您还没有这些包,您可以通过pip install PACKAGE或者通过克隆 git 库来安装它们。

下面是一个用 pip 安装 numpy 的例子

pip install numpy

用 git

git clone [https://github.com/numpy/numpy](https://github.com/numpy/numpy)
cd numpy
python setup.py install

现在打开您最喜欢的文本编辑器,创建一个新的 python 文件。从导入以下包开始

import numpy as np
from datetime import datetime
import smtplib
import time
from selenium import webdriver#For Prediction
from sklearn.linear_model import LinearRegression
from sklearn import preprocessing, cross_validation, svm#For Stock Data
from iexfinance import Stock
from iexfinance import get_historical_data

注意:python 附带了 datetime、time 和 smtplib 包

为了清理雅虎股票筛选程序,你还需要安装 Chromedriver 来正确使用 Selenium。在这里可以找到

获得股票

使用 Selenium 包,我们可以从雅虎股票筛选程序中筛选股票的代码缩写。

首先,创建一个带有参数n的函数getStocks,其中 n 是我们希望检索的股票数量。

def getStocks(n):

在函数中创建你的 chrome 驱动程序,然后使用driver.get(url)来检索你想要的网页。我们将导航至https://finance . Yahoo . com/screener/predefined/aggressive _ small _ caps?offset=0 & count=202 这将显示 200 只列在“激进小型股”类别中的股票。如果你去 https://finance.yahoo.com/screener,你会看到雅虎提供的所有筛选类别的列表。然后,您可以根据自己的喜好更改 URL。

#Navigating to the Yahoo stock screenerdriver = webdriver.Chrome(‘**PATH TO CHROME DRIVER**’)url = “https://finance.yahoo.com/screener/predefined/aggressive_small_caps?offset=0&count=202"driver.get(url)

确保将下载 chromedriver 的路径添加到粗体代码所在的位置。

您现在需要创建一个列表来保存 ticker 值stock_list = []

接下来,我们需要找到 ticker 元素的 XPath,以便能够抓取它们。转到 screener URL 并在您的 web 浏览器中打开开发者工具(Command+Option+I/Control+Shift+IF12 for Windows)。

单击“选择元素”按钮

单击股票并检查其属性

最后,复制第一个 ticker 的 XPath,HTML 元素应该如下所示

<a href=”/quote/RAD?p=RAD” title=”Rite Aid Corporation” class=”Fw(b)” data-reactid=”79">RAD</a>

XPath 应该看起来像这样

//*[[@id](http://twitter.com/id)=”scr-res-table”]/div[2]/table/tbody/tr[**1**]/td[1]/a

如果您检查第一个下面的 ticker 属性,您会注意到 XPath 完全相同,除了上面代码中加粗的 1 对于每个 ticker 增加 1。所以第 57 个 ticker XPath 值是

//*[[@id](http://twitter.com/id)=”scr-res-table”]/div[2]/table/tbody/tr[**57**]/td[1]/a

这对我们帮助很大。我们可以简单地创建一个for循环,每次运行时递增该值,并将跑马灯的值存储到我们的stock_list中。

stock_list = []
n += 1for i in range(1, n):
  ticker = driver.find_element_by_xpath(‘//*[@id = “scr-res-table”]/div[2]/table/tbody/tr[‘ + str(i) +          ‘]/td[1]/a’)stock_list.append(ticker.text)

n是我们的函数getStocks(n)将检索的股票数量。我们必须增加 1,因为 Python 是 0 索引的。然后我们使用值i 来修改每个 ticker 属性的 XPath。

使用driver.quit()退出网络浏览器。我们现在有了所有的股票价格,并准备好预测股票。

我们将创建一个函数来预测下一节中的股票,但现在我们可以创建另一个for循环来遍历列表中的所有股票值,并预测每个股票的价格。

#Using the stock list to predict the future price of the stock a specificed amount of daysfor i in stock_list:
  try:
    predictData(i, 5)
  except:
    print("Stock: " + i + " was not predicted")

用 try 和 except 块处理代码(以防我们的股票包不能识别股票代码值)。

预测股票

创建一个新函数predictData,它采用参数stockdays(其中 days 是我们希望预测未来股票的天数)。从 2017 年 1 月 1 日到现在,我们将使用大约 2 年的数据进行预测(尽管您可以使用任何您想要的数据)。设置start = datetime(2017, 1, 1)end = datetime.now()。然后使用 iexfinance 函数获取给定股票df = get_historical_data(stock, start=start, end=end, output_format=’pandas’)的历史数据。

然后将历史数据导出到一个. csv 文件,为预测创建一个新的虚拟列,并设置forecast_time = int(days)

start = datetime(2017, 1, 1)
end = datetime.now()#Outputting the Historical data into a .csv for later use
df = get_historical_data(stock, start=start, end=end,     output_format='pandas')csv_name = ('Exports/' + stock + '_Export.csv')
df.to_csv(csv_name)
df['prediction'] = df['close'].shift(-1)
df.dropna(inplace=True)
forecast_time = int(days)

使用 numpy 操作数组,然后预处理这些值,并创建 X 和 Y 训练和测试值。对于这个预测,我们将使用 test_size 的0.5,这个值给了我最准确的结果。

X = np.array(df.drop(['prediction'], 1))
Y = np.array(df['prediction'])
X = preprocessing.scale(X)
X_prediction = X[-forecast_time:]X_train, X_test, Y_train, Y_test =         cross_validation.train_test_split(X, Y, test_size=0.5)

最后,对数据进行线性回归。创建变量clf = LinearRegression(),拟合 X 和 Y 训练数据,并将 X 值预测存储在变量prediction中。

#Performing the Regression on the training dataclf = LinearRegression()
clf.fit(X_train, Y_train)
prediction = (clf.predict(X_prediction))

在下一节中,我们将定义通过 SMS 发送股票预测的函数sendMessage。在predictData函数中添加一个if语句,该语句存储一个字符串作为输出,并调用sendMessage函数,向其传递参数output

变量output可以包含您认为有用的任何信息。我让它告诉我股票名称,1 天预测和 5 天预测。

#Sending the SMS if the predicted price of the stock is at least 1 greater than the previous closing pricelast_row = df.tail(1)
if (float(prediction[4]) > (float(last_row['close']))):output = ("\n\nStock:" + str(stock) + "\nPrior Close:\n" +         str(last_row['close']) + "\n\nPrediction in 1 Day: " + str(prediction[0]) + "\nPrediction in 5 Days: " + str(prediction[4]))sendMessage(output)

发送消息

创建一个将output作为参数的函数sendMessage。要发送短信,我们将使用smtplib包,这样我们就可以通过电子邮件发送短信。

将您的电子邮件用户名、密码和接收号码存储为变量。我的手机运营商是威瑞森,所以我用的是@vtext 域名。多亏了这个网站,这里有一些受欢迎的电话公司的分机号码。

  • number@txt.att.net(手机短信),number@mms.att.net(彩信)
  • T-Mobile: number@tmomail.net(短信和彩信)
  • number@vtext.com(手机短信),number@vzwpix.com(彩信)
  • sprint:number @ messaging . sprint PCs . com(短信),number@pm.sprint.com(彩信)
  • 维珍手机:number@vmobl.com(短信),number@vmpix.com(彩信)
def sendMessage(output):username = "EMAIL"
  password = "PASSWORD"
  vtext = "PHONENUMBER@vtext.com"

使用以下行发送带有正确消息的 SMS

message = output
msg = """From: %s To: %s %s""" % (username, vtext, message)server = smtplib.SMTP('smtp.gmail.com', 587)
server.starttls()
server.login(username, password)
server.sendmail(username, vtext, msg)
server.quit()

运行程序

最后,创建一个 main 方法来运行程序。我们将把预测的股票数量设置为 200。

if __name__ == '__main__':
  getStocks(200)

结论

仅在 10 只股票上运行预测,实际 1 日价格和 1 日预测价格之间的平均百分比误差为 9.02% ,其中 5 日百分比误差是令人惊讶的 5.90% 。这意味着,平均而言,5 天的预测仅比实际价格低0.14 美元

这些结果可以归因于样本量小,但无论如何,它们都是有希望的,可以在你投资股票时提供很大的帮助。

查看 Github 上的完整源代码

[## 使用 Tweepy 在 Python 中创建一个 Twitter 机器人

Twitter 大约有 15%是由机器人组成的,我想尝试一下。我谷歌了如何创建一个推特机器人…

medium.freecodecamp.org](https://medium.freecodecamp.org/creating-a-twitter-bot-in-python-with-tweepy-ac524157a607) [## 推特数据分析

在使用 Tweepy 和 Python 以及这段代码创建了免费的 Wtr bot 之后,我想用一种方式来看看 Twitter 用户是如何…

medium.co](https://medium.com/@lucaskohorst/twitter-data-analysis-d5fb7d42ebc7) [## Python 中的新闻倾向性排名

我最近在《华盛顿邮报》上读到一篇文章,题为“根据……从自由派到保守派对媒体进行排名。”

towardsdatascience.com](/ranking-news-bias-in-python-e9bb5d1ba93f)

Kaggle 内核:预测学生的成绩

原文:https://towardsdatascience.com/predicting-students-grades-on-kaggle-fd6ac9b1bfb9?source=collection_archive---------7-----------------------

教育数据挖掘是指将数据挖掘应用于教育数据集。在大多数情况下,EDM 类似于普通的数据挖掘。然而,我们应该考虑教育数据集的具体特征。数据通常有多个层次。此外,许多研究是在一个机构进行的,这使得大多数研究不太容易概括。如果你想了解更多关于 EDM 的内容,你可以看看 Romero 和 Ventura 的论文。两位作者都撰写了关于该主题的多个文献综述,这些综述提供了该领域随时间推移的发展的清晰视图。EDM 中与预测相关的重要主题有:预测注册人数、预测学生表现和预测流失。

在 Kaggle 上,我发现了这个学生成绩的数据集。在分析中,我观察了各种可视化效果,并比较了基于树的机器学习算法对学生成绩的预测。尽管数据集很小,但我们能够达到几乎 82%的准确率。根据想象,女性在这项测试中的得分似乎比男性高。在线环境中被访问资源的数量是最终成绩最重要的预测因素。

您可以通过点击链接查看 Kaggle 笔记本,也可以点击下面的静态笔记本。

预测坦桑尼亚水泵的运行状况

原文:https://towardsdatascience.com/predicting-the-functional-status-of-pumps-in-tanzania-355c9269d0c2?source=collection_archive---------1-----------------------

水是生命和环境的基础;它在经济和社会发展活动中发挥着核心作用。水涉及人类生活的所有领域,包括:家庭、牲畜、渔业、野生动物、工业和能源、娱乐和其他社会经济活动。它通过加强粮食安全、家庭卫生和环境,在减贫方面发挥着关键作用。安全和清洁的水的供应提高了生活水平,而水的不足造成了严重的健康风险,并导致生活水平和预期寿命的下降。

坦桑尼亚的主要淡水来源包括:湖泊、河流、小溪、水坝和地下水。然而,这些并没有在全国范围内得到很好的分配。一些地区既缺乏地表水资源,也缺乏地下水资源。

人口增长和城市化对可用水的数量和质量造成严重压力。当前和未来人类生活和环境的可持续性主要取决于适当的水资源管理。

Image Courtesy: flickr user christophercjensen

首先分析坦桑尼亚现有供水点的功能状态。在此分析中,我们将研究坦桑尼亚水泵的数据集,以预测供水点的运行状况。这给了我们分析的灵感。

通过预测功能正常但需要维修的水泵,降低了坦桑尼亚水利部的总成本。这可以改善水泵的维护操作,并确保坦桑尼亚各地的社区都能获得清洁的饮用水。

首先,让我们看看现有的数据。

训练集值 —训练集的独立变量。'https://S3 . amazonaws . com/driven data/data/7/public/4910797 b-ee55-40a 7-8668-10 EFD 5 C1 b 960 . CSV'

训练集标签 —训练集值中每一行的因变量(status_group)。'https://S3 . amazonaws . com/driven data/data/7/public/0 BF 8 BC 6 e-30d 0-4c 50-956 a-603 fc 693d 966 . CSV'

导入数据

training_values = pd.read_csv('[https://s3.amazonaws.com/drivendata/data/7/public/4910797b-ee55-40a7-8668-10efd5c1b960.csv](https://s3.amazonaws.com/drivendata/data/7/public/4910797b-ee55-40a7-8668-10efd5c1b960.csv)', encoding = 'iso-8859-1')training_lables = pd.read_csv('[https://s3.amazonaws.com/drivendata/data/7/public/0bf8bc6e-30d0-4c50-956a-603fc693d966.csv](https://s3.amazonaws.com/drivendata/data/7/public/0bf8bc6e-30d0-4c50-956a-603fc693d966.csv)', encoding = 'iso-8859-1')

数据集中的要素

list(training_values.columns.values)

我们有 40 个预测变量。在数据集中的 40 个特征中,我们有 31 个分类变量、7 个数值变量和 2 个日期变量。

['id', 'amount_tsh', 'date_recorded', 'funder', 'gps_height', 'installer', 'longitude', 'latitude', 'wpt_name', 'num_private',
'basin', 'subvillage', 'region', 'region_code', 'district_code',
'lga', 'ward', 'population', 'public_meeting', 'recorded_by',
'scheme_management', 'scheme_name', 'permit', 'construction_year',
'extraction_type', 'extraction_type_group', 'extraction_type_class',
'management', 'management_group', 'payment', 'payment_type',
'water_quality', 'quality_group', 'quantity', 'quantity_group',
'source', 'source_type', 'source_class', 'waterpoint_type',
'waterpoint_type_group']

水泵是这三种类型中的任何一种

  1. 功能性的,
  2. 不起作用,或
  3. 功能正常但需要修理。
training_lables.head(5)

现在,让我们检查 status_group 中泵的每种功能类型的计数,以便了解泵状态的功能场景。

training_lables.status_group.value_counts()functional                 32259
non functional             22824
functional needs repair     4317
Name: status_group, dtype: int64

根据上述结果,我们可以说,有 54.31%的功能泵、38.42%的非功能泵和 7.27%的功能泵需要修理。

根据上面的数字,我们可以粗略估计,如果我们从数据中随机抽取一个泵作为功能泵,有 54.31%的可能性。

删除具有相似数据表示的特征

(提取类型,提取类型组,提取类型类),(付款,付款类型),
(水质,质量组),(水源,水源类),(子村,区域,区域代码,地区代码,lga,ward),以及(水点类型,水点类型组)的特征组都包含不同粒度的数据的相似表示。因此,在训练过程中,我们冒着过度拟合数据的风险,在我们的分析中包括所有的特征,这些特征可以被丢弃。

  • 可以删除 id,因为它对于每个实例都是唯一的。
  • num_private 大约 99%为零

数据清理和分析

从数据来看,一些基于人类直觉的特征似乎是有区别的。amount_tsh(供水点可用的水量)、gps_height、basin、installer、population、scheme_management、施工年份、抽水类型、管理组、水质、付款类型、水源和供水点类型看起来对识别水泵状态非常重要。

我们的特征中有空值,需要更新以更好地训练我们的模型。

在清除空值的过程中,我们发现一些特征具有很高的 arity。因此,对于具有高 arity 的特征,让我们基于频率保留前 10 个值,并将所有剩余的值分配给第 11 个合成值作为“其他”。

将全部数据分成 10 组后,我们创建了一个数据透视表,将数据分组到子组中,该子组包含特定特性的每个合成值在每个条件下的泵数量,我们还创建了一个热图,以图形方式查看数据。例如,查看名为 basin 的特征,其实例广泛分布在所有类别中(这可能对我们的模型有影响)。

piv_df= training_df[['basin','status_group','status_values']]
piv_table = piv_df.pivot_table(index='basin',
                           columns='status_group', aggfunc='count')
piv_table

Heat Map constructed using the Pivot table created in the previous step

在丢弃不需要的特征并清理数据集后,我们剩下 20 个特征可用于训练我们的模型。我们将用于培训的功能有:

['amount_tsh', 'days_since_recorded', 'funder', 'gps_height',
 'installer', 'basin', 'subvillage', 'population', 'public_meeting',
 'scheme_management', 'scheme_name', 'permit', 'construction_year',
 'extraction_type', 'payment_type', 'water_quality',   
 'quantity_group', 'source_type', 'source_class', 'waterpoint_type',
 'waterpoint_type_group']

为分类器获取数据的一种常见方法是将可用数据分成两个集合,一个训练集和一个测试集。分类模型建立在训练集上,并应用于测试集。测试集从未被模型看到过,因此当模型应用于看不见的数据时,最终的性能将是一个很好的指导。

通常,选择的比例是 70%用于训练集,30%用于测试。这个想法是,更多的训练数据是一件好事,因为它使分类模型更好,而更多的测试数据使误差估计更准确。

X_train, X_test, y_train, y_test = sklearn.model_selection.train_test_split(training, test, test_size = 0.3, random_state = 0) 

对于分类,我们将使用集成方法,集成学习使用几种用不同学习算法构建的机器学习模型来提高预测的准确性。它基本上是对几个模型的预测进行平均,从而得到一个更好的预测。我将在这个分析中使用的一些集成方法是随机森林,额外树和梯度推进。

我们将尝试不同的方法,选择最适合我们数据的方法。

随机森林分类器

rfc = sklearn.ensemble.RandomForestClassifier(n_estimators=1000, 
                                               min_samples_split=6,
                                               criterion='gini', 
                                               max_features='auto',
                                               oob_score=True,
                                               random_state=1,
                                               n_jobs=-1)

决策树:

dtc = DecisionTreeClassifier(criterion='gini',
                             max_depth = 10,
                             max_features = 'auto',
                             random_state = 1,
                             splitter = 'best')

额外的树分类器:

ETC = ExtraTreesClassifier(n_estimators=1000, min_samples_split=10)

梯度增强:

param_grid = {'learning_rate': [0.075,0.07],
               'max_depth': [6,7],
               'min_samples_leaf': [7,8],
               'max_features': [1.0],
               'n_estimators':[100, 200]}gbc = GridSearchCV(estimator=GradientBoostingClassifier(),
                                 param_grid=param_grid,
                                 n_jobs=-1)

每个分类器的验证分数如下。

对于每个分类器,我们构建了混淆矩阵来检查每个值中的真阳性和假阳性。让我们显示在随机森林分类器和额外树分类器的情况下表现良好的分类器的混淆矩阵。

随机森林分类器的混淆矩阵

额外树分类器的混淆矩阵

综合考虑训练数据集和测试数据集的准确率、F-1、查准率和查全率,随机森林分类器表现良好,根据以上证据,我们可以选择随机森林作为我们的分类模型。

当我们选择模型时,让我们检查每个特性的重要性,看看哪些特性影响了我们的模型。

['amount_tsh', 'days_since_recorded', 'funder', 'gps_height', 
 'installer', 'basin', 'subvillage', 'population', 'public_meeting',   
 'scheme_management', 'scheme_name', 'permit', 'construction_year', 
 'extraction_type', 'payment_type', 'water_quality',   
 'quantity_group', 'source_type', 'source_class', 'waterpoint_type', 
 'waterpoint_type_group']

在所有特性中,数量组、子村庄和 gps 高度似乎是最重要的。通过观察特征的重要性,我们还可以推断出水泵的面积和特定区域的可用水量将对水泵的功能状态产生更大的影响。

最终结果:

分析让我们相信数据集很难分类。对分类进行优先排序,以确定需要维修的泵。一个标准泵的价格从 100 美元到 2000 美元不等。安装这种泵需要钻井,费用可能在 1000 美元到 3000 美元之间。另一方面,维护水泵只需要花费几十美元,这可以帮助坦桑尼亚的水行业获得数百万美元。

未来工作:

  1. 我们可以从外部来源收集准确的人口数据,并将其添加到我们的数据集中,并检查特定区域的人口是否影响泵的功能状态,这可以帮助他们预测该区域并在该区域采取更多措施。
  2. 我们可以通过使用历史数据来确定水泵的寿命,这可以帮助坦桑尼亚水利部在水泵无法使用之前对其进行维修。
  3. 为了提高预测的性能和执行速度,我们可以使用极限梯度提升方法,在 python 中我们可以使用 XGBoost 库来处理它。

项目地点:

T3【https://github.com/ksdkalluri/identifying_faulty_pumps】T5

预测泰坦尼克号乘客的生存

原文:https://towardsdatascience.com/predicting-the-survival-of-titanic-passengers-30870ccc7e8?source=collection_archive---------1-----------------------

在这篇博文中,我将介绍在著名的 Titanic 数据集上创建机器学习模型的整个过程,这个数据集被世界各地的许多人使用。它提供了泰坦尼克号上乘客的命运信息,按照经济地位(阶级)、性别、年龄和存活率进行汇总。

我最初在 kaggle.com 上写这篇文章,作为“泰坦尼克号:从灾难中学习的机器”竞赛的一部分。在这个挑战中,我们被要求预测泰坦尼克号上的一名乘客是否会生还。

皇家邮轮泰坦尼克号

皇家邮轮泰坦尼克号是一艘英国客轮,1912 年 4 月 15 日凌晨在从南安普敦到纽约市的处女航中与冰山相撞后沉没在北大西洋。据估计,船上有 2224 名乘客和船员,超过 1500 人死亡,这是现代史上最致命的和平时期商业海上灾难之一。皇家邮轮泰坦尼克号是当时最大的水上船只,也是白星航运公司运营的三艘奥运级远洋客轮中的第二艘。泰坦尼克号由贝尔法斯特的哈兰和沃尔夫造船厂建造。她的建筑师托马斯·安德鲁斯死于这场灾难。

导入库

*# linear algebra*
**import** **numpy** **as** **np** 

*# data processing*
**import** **pandas** **as** **pd** 

*# data visualization*
**import** **seaborn** **as** **sns**
%matplotlib inline
**from** **matplotlib** **import** pyplot **as** plt
**from** **matplotlib** **import** style

*# Algorithms*
**from** **sklearn** **import** linear_model
**from** **sklearn.linear_model** **import** LogisticRegression
**from** **sklearn.ensemble** **import** RandomForestClassifier
**from** **sklearn.linear_model** **import** Perceptron
**from** **sklearn.linear_model** **import** SGDClassifier
**from** **sklearn.tree** **import** DecisionTreeClassifier
**from** **sklearn.neighbors** **import** KNeighborsClassifier
**from** **sklearn.svm** **import** SVC, LinearSVC
**from** **sklearn.naive_bayes** **import** GaussianNB

获取数据

test_df = pd.read_csv("test.csv")
train_df = pd.read_csv("train.csv")

数据探索/分析

train_df.info()

训练集有 891 个样本,11 个特征+目标变量(存活)。其中 2 个特性是浮点数,5 个是整数,5 个是对象。下面我列出了这些特性并做了简短的描述:

survival:    Survival 
PassengerId: Unique Id of a passenger. 
pclass:    Ticket class     
sex:    Sex     
Age:    Age in years     
sibsp:    # of siblings / spouses aboard the Titanic     
parch:    # of parents / children aboard the Titanic     
ticket:    Ticket number     
fare:    Passenger fare     
cabin:    Cabin number     
embarked:    Port of Embarkationtrain_df.describe()

从上面我们可以看到 38%的训练组成员在泰坦尼克号中幸存。我们还可以看到乘客年龄从 0.4 岁到 80 岁不等。除此之外,我们已经可以检测到一些包含缺失值的特征,比如“年龄”特征。

train_df.head(8)

从上表中,我们可以注意到一些事情。首先,我们需要稍后将大量特征转换为数字特征,以便机器学习算法可以处理它们。此外,我们可以看到特性具有非常不同的范围,我们需要将其转换成大致相同的比例。我们还可以发现更多的包含缺失值(NaN =非数字)的特性,我们需要处理这些特性。

让我们更详细地看看实际上缺少什么数据:

total = train_df.isnull().sum().sort_values(ascending=**False**)
percent_1 = train_df.isnull().sum()/train_df.isnull().count()*100
percent_2 = (round(percent_1, 1)).sort_values(ascending=**False**)
missing_data = pd.concat([total, percent_2], axis=1, keys=['Total', '%'])
missing_data.head(5)

已装载特征只有两个缺失值,可以很容易地填充。处理“年龄”特性要复杂得多,它缺少 177 个值。“小屋”功能需要进一步调查,但看起来我们可能要从数据集中删除它,因为它的 77 %丢失了。

train_df.columns.values

上面你可以看到 11 个特征+目标变量(幸存)。哪些特征有助于提高存活率?

对我来说,如果除了“乘客 Id”、“车票”和“姓名”之外的一切都与高存活率相关联,那就说得通了。

1。年龄性别:

survived = 'survived'
not_survived = 'not survived'
fig, axes = plt.subplots(nrows=1, ncols=2,figsize=(10, 4))
women = train_df[train_df['Sex']=='female']
men = train_df[train_df['Sex']=='male']
ax = sns.distplot(women[women['Survived']==1].Age.dropna(), bins=18, label = survived, ax = axes[0], kde =**False**)
ax = sns.distplot(women[women['Survived']==0].Age.dropna(), bins=40, label = not_survived, ax = axes[0], kde =**False**)
ax.legend()
ax.set_title('Female')
ax = sns.distplot(men[men['Survived']==1].Age.dropna(), bins=18, label = survived, ax = axes[1], kde = **False**)
ax = sns.distplot(men[men['Survived']==0].Age.dropna(), bins=40, label = not_survived, ax = axes[1], kde = **False**)
ax.legend()
_ = ax.set_title('Male')

你可以看到男性在 18 岁到 30 岁之间存活的概率很大,女性也是一点点但不完全对。对于 14 至 40 岁的女性来说,存活的几率更高。

对于男性来说,在 5 岁到 18 岁之间存活的概率非常低,但对于女性来说并非如此。另一件要注意的事情是,婴儿也有更高的存活率。

由于似乎有特定的年龄,这增加了生存的几率,并且因为我希望每个特征都大致在相同的范围内,我将稍后创建年龄组。

3。登船,Pclass 和 Sex:

FacetGrid = sns.FacetGrid(train_df, row='Embarked', size=4.5, aspect=1.6)
FacetGrid.map(sns.pointplot, 'Pclass', 'Survived', 'Sex', palette=**None**,  order=**None**, hue_order=**None** )
FacetGrid.add_legend()

上船似乎与生存相关,取决于性别。

Q 端口和 S 端口的女性生存几率更高。反之亦然,如果他们在港口 C。男人有很高的生存概率,如果他们在港口 C,但低概率,如果他们在港口 Q 或 s。

Pclass 似乎也与存活率相关。我们将在下面生成另一个图。

4。Pclass:

sns.barplot(x='Pclass', y='Survived', data=train_df)

这里我们清楚地看到,Pclass 增加了一个人的生存机会,特别是如果这个人在 1 类。我们将在下面创建另一个 pclass 图。

grid = sns.FacetGrid(train_df, col='Survived', row='Pclass', size=2.2, aspect=1.6)
grid.map(plt.hist, 'Age', alpha=.5, bins=20)
grid.add_legend();

上面的图证实了我们对 pclass 1 的假设,但我们也可以发现 pclass 3 中的人很有可能无法存活。

5。SibSp 和 Parch:

SibSp 和 Parch 作为一个组合特征更有意义,它显示了一个人在泰坦尼克号上的亲属总数。我将在下面创建它,也是一个如果有人不孤单时播种的特征。

data = [train_df, test_df]
**for** dataset **in** data:
    dataset['relatives'] = dataset['SibSp'] + dataset['Parch']
    dataset.loc[dataset['relatives'] > 0, 'not_alone'] = 0
    dataset.loc[dataset['relatives'] == 0, 'not_alone'] = 1
    dataset['not_alone'] = dataset['not_alone'].astype(int)train_df['not_alone'].value_counts()

axes = sns.factorplot('relatives','Survived', 
                      data=train_df, aspect = 2.5, )

在这里我们可以看到,你有 1 到 3 个亲属的存活概率很高,但如果你的亲属少于 1 个或多于 3 个,存活概率就较低(除了一些有 6 个亲属的情况)。

数据预处理

首先,我将从训练集中删除“PassengerId ”,因为它对一个人的生存概率没有贡献。我不会把它从测试集中删除,因为提交时需要它。

train_df = train_df.drop(['PassengerId'], axis=1)

缺失数据:

小屋: 提醒一下,我们要处理小屋(687)、登船(2)和年龄(177)。首先我想,我们必须删除“小屋”变量,但后来我发现了一些有趣的东西。一个舱号看起来像‘C123’,字母指的是甲板。因此,我们将提取这些并创建一个新的功能,其中包含一个人的甲板。我们将把这个特征转换成一个数字变量。缺少的值将被转换为零。在下面的图片中,你可以看到泰坦尼克号的实际甲板,从 A 到 g。

**import** **re**
deck = {"A": 1, "B": 2, "C": 3, "D": 4, "E": 5, "F": 6, "G": 7, "U": 8}
data = [train_df, test_df]

**for** dataset **in** data:
    dataset['Cabin'] = dataset['Cabin'].fillna("U0")
    dataset['Deck'] = dataset['Cabin'].map(**lambda** x: re.compile("([a-zA-Z]+)").search(x).group())
    dataset['Deck'] = dataset['Deck'].map(deck)
    dataset['Deck'] = dataset['Deck'].fillna(0)
    dataset['Deck'] = dataset['Deck'].astype(int)*# we can now drop the cabin feature*
train_df = train_df.drop(['Cabin'], axis=1)
test_df = test_df.drop(['Cabin'], axis=1)

Age: 现在我们可以解决 Age 特性缺少值的问题。我将创建一个包含随机数的数组,这些随机数是根据平均年龄值计算的,与标准偏差和 is_null 有关。

data = [train_df, test_df]

**for** dataset **in** data:
    mean = train_df["Age"].mean()
    std = test_df["Age"].std()
    is_null = dataset["Age"].isnull().sum()
    *# compute random numbers between the mean, std and is_null*
    rand_age = np.random.randint(mean - std, mean + std, size = is_null)
    *# fill NaN values in Age column with random values generated*
    age_slice = dataset["Age"].copy()
    age_slice[np.isnan(age_slice)] = rand_age
    dataset["Age"] = age_slice
    dataset["Age"] = train_df["Age"].astype(int)train_df["Age"].isnull().sum()

着手进行:

由于已装载特征只有两个缺失值,我们将只使用最常见的值来填充它们。

train_df['Embarked'].describe()

common_value = 'S'
data = [train_df, test_df]

**for** dataset **in** data:
    dataset['Embarked'] = dataset['Embarked'].fillna(common_value)

转换功能:

train_df.info()

上面你可以看到“票价”是一个浮动,我们必须处理 4 个分类特征:姓名、性别、车票和上船。让我们一个接一个地调查和转换。

Fare: 使用 pandas 提供的函数“astype()”将“Fare”从 float 转换为 int64:

data = [train_df, test_df]

**for** dataset **in** data:
    dataset['Fare'] = dataset['Fare'].fillna(0)
    dataset['Fare'] = dataset['Fare'].astype(int)

Name: 我们将使用 Name 特性从名称中提取标题,这样我们就可以从中构建一个新的特性。

data = [train_df, test_df]
titles = {"Mr": 1, "Miss": 2, "Mrs": 3, "Master": 4, "Rare": 5}

**for** dataset **in** data:
    *# extract titles*
    dataset['Title'] = dataset.Name.str.extract(' ([A-Za-z]+)\.', expand=**False**)
    *# replace titles with a more common title or as Rare*
    dataset['Title'] = dataset['Title'].replace(['Lady', 'Countess','Capt', 'Col','Don', 'Dr',\
                                            'Major', 'Rev', 'Sir', 'Jonkheer', 'Dona'], 'Rare')
    dataset['Title'] = dataset['Title'].replace('Mlle', 'Miss')
    dataset['Title'] = dataset['Title'].replace('Ms', 'Miss')
    dataset['Title'] = dataset['Title'].replace('Mme', 'Mrs')
    *# convert titles into numbers*
    dataset['Title'] = dataset['Title'].map(titles)
    *# filling NaN with 0, to get safe*
    dataset['Title'] = dataset['Title'].fillna(0)train_df = train_df.drop(['Name'], axis=1)
test_df = test_df.drop(['Name'], axis=1)

性别: 将‘性别’特征转换为数值。

genders = {"male": 0, "female": 1}
data = [train_df, test_df]

**for** dataset **in** data:
    dataset['Sex'] = dataset['Sex'].map(genders)

票:

train_df['Ticket'].describe()

由于门票属性有 681 个独特的门票,这将是一个有点棘手的转换成有用的类别。所以我们将把它从数据集中删除。

train_df = train_df.drop(['Ticket'], axis=1)
test_df = test_df.drop(['Ticket'], axis=1)

已装船: 将‘已装船’特征转换成数值。

ports = {"S": 0, "C": 1, "Q": 2}
data = [train_df, test_df]

**for** dataset **in** data:
    dataset['Embarked'] = dataset['Embarked'].map(ports)

创建类别:

我们现在将在以下功能中创建类别:

年龄: 现在我们需要转换‘年龄’特性。首先我们将把它从浮点数转换成整数。然后,我们将创建新的“年龄组”变量,将每个年龄分为一组。请注意,关注如何组成这些组是很重要的,因为您不希望 80%的数据归入组 1。

data = [train_df, test_df]
**for** dataset **in** data:
    dataset['Age'] = dataset['Age'].astype(int)
    dataset.loc[ dataset['Age'] <= 11, 'Age'] = 0
    dataset.loc[(dataset['Age'] > 11) & (dataset['Age'] <= 18), 'Age'] = 1
    dataset.loc[(dataset['Age'] > 18) & (dataset['Age'] <= 22), 'Age'] = 2
    dataset.loc[(dataset['Age'] > 22) & (dataset['Age'] <= 27), 'Age'] = 3
    dataset.loc[(dataset['Age'] > 27) & (dataset['Age'] <= 33), 'Age'] = 4
    dataset.loc[(dataset['Age'] > 33) & (dataset['Age'] <= 40), 'Age'] = 5
    dataset.loc[(dataset['Age'] > 40) & (dataset['Age'] <= 66), 'Age'] = 6
    dataset.loc[ dataset['Age'] > 66, 'Age'] = 6
 *# let's see how it's distributed* train_df['Age'].value_counts()

Fare: 对于‘Fare’特性,我们需要做与‘Age’特性相同的事情。但这并不容易,因为如果我们将票价值的范围分成几个同样大的类别,80%的值将属于第一类。幸运的是,我们可以使用 sklearn 的“qcut()”函数,我们可以使用它来查看我们如何形成类别。

train_df.head(10)

data = [train_df, test_df]

**for** dataset **in** data:
    dataset.loc[ dataset['Fare'] <= 7.91, 'Fare'] = 0
    dataset.loc[(dataset['Fare'] > 7.91) & (dataset['Fare'] <= 14.454), 'Fare'] = 1
    dataset.loc[(dataset['Fare'] > 14.454) & (dataset['Fare'] <= 31), 'Fare']   = 2
    dataset.loc[(dataset['Fare'] > 31) & (dataset['Fare'] <= 99), 'Fare']   = 3
    dataset.loc[(dataset['Fare'] > 99) & (dataset['Fare'] <= 250), 'Fare']   = 4
    dataset.loc[ dataset['Fare'] > 250, 'Fare'] = 5
    dataset['Fare'] = dataset['Fare'].astype(int)

创建新功能

我将向数据集中添加两个新要素,这两个新要素是从其他要素中计算出来的。

1。时代时代班

data = [train_df, test_df]
**for** dataset **in** data:
    dataset['Age_Class']= dataset['Age']* dataset['Pclass']

2。每人票价

**for** dataset **in** data:
    dataset['Fare_Per_Person'] = dataset['Fare']/(dataset['relatives']+1)
    dataset['Fare_Per_Person'] = dataset['Fare_Per_Person'].astype(int)*# Let's take a last look at the training set, before we start training the models.*
train_df.head(10)

构建机器学习模型

现在我们将训练几个机器学习模型,并比较它们的结果。请注意,因为数据集没有为它们的测试集提供标签,所以我们需要使用训练集的预测来相互比较算法。稍后,我们将使用交叉验证。

X_train = train_df.drop("Survived", axis=1)
Y_train = train_df["Survived"]
X_test  = test_df.drop("PassengerId", axis=1).copy()

随机梯度下降(SGD):

sgd = linear_model.SGDClassifier(max_iter=5, tol=**None**)
sgd.fit(X_train, Y_train)
Y_pred = sgd.predict(X_test)

sgd.score(X_train, Y_train)

acc_sgd = round(sgd.score(X_train, Y_train) * 100, 2)

随机森林:

random_forest = RandomForestClassifier(n_estimators=100)
random_forest.fit(X_train, Y_train)

Y_prediction = random_forest.predict(X_test)

random_forest.score(X_train, Y_train)
acc_random_forest = round(random_forest.score(X_train, Y_train) * 100, 2)

逻辑回归:

logreg = LogisticRegression()
logreg.fit(X_train, Y_train)

Y_pred = logreg.predict(X_test)

acc_log = round(logreg.score(X_train, Y_train) * 100, 2)

K 最近邻:

*# KNN* knn = KNeighborsClassifier(n_neighbors = 3) knn.fit(X_train, Y_train)  Y_pred = knn.predict(X_test)  acc_knn = round(knn.score(X_train, Y_train) * 100, 2)

高斯朴素贝叶斯:

gaussian = GaussianNB() gaussian.fit(X_train, Y_train)  Y_pred = gaussian.predict(X_test)  acc_gaussian = round(gaussian.score(X_train, Y_train) * 100, 2)

感知器:

perceptron = Perceptron(max_iter=5)
perceptron.fit(X_train, Y_train)

Y_pred = perceptron.predict(X_test)

acc_perceptron = round(perceptron.score(X_train, Y_train) * 100, 2)

线性支持向量机:

linear_svc = LinearSVC()
linear_svc.fit(X_train, Y_train)

Y_pred = linear_svc.predict(X_test)

acc_linear_svc = round(linear_svc.score(X_train, Y_train) * 100, 2)

决策树

decision_tree = DecisionTreeClassifier() decision_tree.fit(X_train, Y_train)  Y_pred = decision_tree.predict(X_test)  acc_decision_tree = round(decision_tree.score(X_train, Y_train) * 100, 2)

哪个是最好的型号?

results = pd.DataFrame({
    'Model': ['Support Vector Machines', 'KNN', 'Logistic Regression', 
              'Random Forest', 'Naive Bayes', 'Perceptron', 
              'Stochastic Gradient Decent', 
              'Decision Tree'],
    'Score': [acc_linear_svc, acc_knn, acc_log, 
              acc_random_forest, acc_gaussian, acc_perceptron, 
              acc_sgd, acc_decision_tree]})
result_df = results.sort_values(by='Score', ascending=**False**)
result_df = result_df.set_index('Score')
result_df.head(9)

正如我们所看到的,随机森林分类器放在第一位。但是首先,让我们检查一下,当我们使用交叉验证时,random-forest 是如何执行的。

k 倍交叉验证:

K-Fold 交叉验证将训练数据随机分成称为折叠的 K 个子集**。假设我们将数据分成 4 份(K = 4)。我们的随机森林模型将被训练和评估 4 次,每次使用不同的折叠进行评估,而它将在剩余的 3 个折叠上被训练。**

下图显示了这个过程,使用了 4 次折叠(K = 4)。每行代表一个培训+评估过程。在第一行中,模型 get 在第一、第二和第三子集上被训练,并且在第四子集上被评估。在第二行中,模型 get 在第二、第三和第四个子集上训练,并在第一个子集上评估。K-Fold 交叉验证重复这个过程,直到每个折叠作为一个评估折叠进行一次。

我们的 K-Fold 交叉验证示例的结果将是包含 4 个不同分数的数组。然后我们需要计算这些分数的平均值和标准差。

下面的代码对我们的随机森林模型执行 K-Fold 交叉验证,使用 10 个折叠(K = 10)。因此,它输出一个有 10 个不同分数的数组。

**from** **sklearn.model_selection** **import** cross_val_score
rf = RandomForestClassifier(n_estimators=100)
scores = cross_val_score(rf, X_train, Y_train, cv=10, scoring = "accuracy")print("Scores:", scores)
print("Mean:", scores.mean())
print("Standard Deviation:", scores.std())

这看起来比以前真实多了。我们的模型平均准确率为 82%,标准偏差为 4 %。标准差告诉我们,估计值有多精确。

这意味着在我们的例子中,我们的模型的精度可以相差 + — 4%。

我认为准确性仍然很好,因为随机森林是一个易于使用的模型,我们将在下一节中尝试进一步提高它的性能。

随机森林

什么是随机森林?

随机森林是一种监督学习算法。就像你已经从它的名字中看到的,它创造了一个森林,使它变得随机。它构建的“森林”是决策树的集合,大部分时间是用“打包”方法训练的。bagging 方法的一般思想是学习模型的组合增加了整体结果。

用简单的话来说:随机森林构建多个决策树,将它们合并在一起,得到一个更加准确稳定的预测。

随机森林的一个很大的优点是,它可以用于分类和回归问题,这构成了当前机器学习系统的大多数。除了少数例外,随机森林分类器具有决策树分类器的所有超参数以及 bagging 分类器的所有超参数,以控制整体本身。

随机森林算法在生长树时给模型带来了额外的随机性。它不是在分割节点时搜索最佳特征,而是在随机特征子集中搜索最佳特征。这个过程产生了广泛的多样性,这通常会产生一个更好的模型。因此,当您在随机森林中种植树时,只考虑要素的随机子集来分割节点。您甚至可以通过在每个特征的基础上使用随机阈值,而不是像普通决策树那样搜索最佳阈值,来使树更加随机。

下面你可以看到有两棵树的随机森林的样子:

特征重要性

随机森林的另一个优点是,它使得测量每个特征的相对重要性变得非常容易。Sklearn 通过查看使用该特征的树节点平均减少杂质的程度(跨越森林中的所有树)来测量特征的重要性。它会在训练后自动计算每个特征的分数,并对结果进行缩放,使所有重要度之和等于 1。我们将在下面讨论这个问题:

importances = pd.DataFrame({'feature':X_train.columns,'importance':np.round(random_forest.feature_importances_,3)})
importances = importances.sort_values('importance',ascending=**False**).set_index('feature')importances.head(15)

importances.plot.bar()

结论:

not_alone 和 Parch 在我们的随机森林分类器预测过程中不起重要作用。因此,我将把它们从数据集中删除,并再次训练分类器。我们也可以删除更多或更少的特性,但是这需要更详细地研究特性对我们模型的影响。但是我觉得只单独取出炒一下就可以了。

train_df  = train_df.drop("not_alone", axis=1)
test_df  = test_df.drop("not_alone", axis=1)

train_df  = train_df.drop("Parch", axis=1)
test_df  = test_df.drop("Parch", axis=1)

再次训练随机森林:

*# Random Forest*

random_forest = RandomForestClassifier(n_estimators=100, oob_score = **True**)
random_forest.fit(X_train, Y_train)
Y_prediction = random_forest.predict(X_test)

random_forest.score(X_train, Y_train)

acc_random_forest = round(random_forest.score(X_train, Y_train) * 100, 2)
print(round(acc_random_forest,2,), "%")

92.82%

我们的随机森林模型预测和以前一样好。一般来说,你拥有的功能越多,你的模型就越有可能过度拟合,反之亦然。但我认为我们的数据目前看起来不错,没有太多特征。

还有另一种方法来评估随机森林分类器,这可能比我们之前使用的分数更准确。我说的是出袋样本估计泛化精度。我不会在这里详细介绍它是如何工作的。只需注意,使用与训练集大小相同的测试集,可以获得非常准确的估计。因此,使用袋外误差估计消除了对预留测试集的需要。

print("oob score:", round(random_forest.oob_score_, 4)*100, "%")

oob 分数:81.82 %

现在我们可以开始调整随机森林的超参数了。

超参数调谐

下面您可以看到参数标准的超参数调整代码,min_samples_leaf、min_samples_split 和 n_estimators。

我将这段代码放在 markdown 单元格中,而不是 code 单元格中,因为运行它需要很长时间。在它的正下方,我放了一个 gridsearch 输出的截图。

param_grid = { "criterion" : ["gini", "entropy"], "min_samples_leaf" : [1, 5, 10, 25, 50, 70], "min_samples_split" : [2, 4, 10, 12, 16, 18, 25, 35], "n_estimators": [100, 400, 700, 1000, 1500]}from sklearn.model_selection import GridSearchCV, cross_val_scorerf = RandomForestClassifier(n_estimators=100, max_features='auto', oob_score=True, random_state=1, n_jobs=-1)clf = GridSearchCV(estimator=rf, param_grid=param_grid, n_jobs=-1)clf.fit(X_train, Y_train)clf.best*params*

测试新参数:

*# Random Forest*
random_forest = RandomForestClassifier(criterion = "gini", 
                                       min_samples_leaf = 1, 
                                       min_samples_split = 10,   
                                       n_estimators=100, 
                                       max_features='auto', 
                                       oob_score=**True**, 
                                       random_state=1, 
                                       n_jobs=-1)

random_forest.fit(X_train, Y_train)
Y_prediction = random_forest.predict(X_test)

random_forest.score(X_train, Y_train)

print("oob score:", round(random_forest.oob_score_, 4)*100, "%")

oob 分数:83.05 %

现在我们有了一个合适的模型,我们可以开始以更准确的方式评估它的性能。以前我们只使用准确性和 oob 分数,这只是准确性的另一种形式。问题是,评估一个分类模型比评估一个回归模型更复杂。我们将在下一节中讨论这一点。

进一步评估

混淆矩阵:

**from** **sklearn.model_selection** **import** cross_val_predict
**from** **sklearn.metrics** **import** confusion_matrix
predictions = cross_val_predict(random_forest, X_train, Y_train, cv=3)
confusion_matrix(Y_train, predictions)

第一行是关于未幸存的预测: 493 名乘客被正确分类为未幸存(称为真阴性) 56 名乘客被错误分类为未幸存(假阳性)。

第二行是关于幸存预测: 93 名乘客被错误地分类为幸存(假阴性),而 249 名乘客被正确地分类为幸存(真阳性)。

混淆矩阵给了你很多关于你的模型表现如何的信息,但是有一种方法可以得到更多,比如计算分类器的精度。

精确度和召回率:

**from** **sklearn.metrics** **import** precision_score, recall_score

print("Precision:", precision_score(Y_train, predictions))
print("Recall:",recall_score(Y_train, predictions))

精度:0.801948051948
召回:0.8000000001

我们的模型预测 81%的时间,一个乘客生存正确(精度)。这份回忆告诉我们,它预测了 73 %的幸存者。

f 分数

你可以把精确度和召回率结合成一个分数,叫做 F 分数。F 分数是用精确度和召回率的调和平均值来计算的。请注意,它将更多的权重分配给低值。因此,如果召回率和精确度都很高,分类器将只获得高 F 值。

**from** **sklearn.metrics** **import** f1_score
f1_score(Y_train, predictions)

0.7599999999999

好了,77 %的 F 分。分数没有那么高,因为我们的召回率是 73%。但不幸的是,F-score 并不完美,因为它倾向于具有相似精度和召回率的分类器。这是一个问题,因为你有时想要高精度,有时想要高召回率。事实是,精确度的增加,有时会导致回忆的减少,反之亦然(取决于阈值)。这被称为精确度/召回率的权衡。我们将在下一节讨论这一点。

精确召回曲线

对于随机森林算法必须分类的每个人,它基于函数计算概率,并将该人分类为幸存(当分数大于阈值时)或未幸存(当分数小于阈值时)。这就是为什么门槛很重要。

我们将使用 matplotlib 绘制精度和召回与阈值的关系:

**from** **sklearn.metrics** **import** precision_recall_curve

*# getting the probabilities of our predictions*
y_scores = random_forest.predict_proba(X_train)
y_scores = y_scores[:,1]

precision, recall, threshold = precision_recall_curve(Y_train, y_scores)**def** plot_precision_and_recall(precision, recall, threshold):
    plt.plot(threshold, precision[:-1], "r-", label="precision", linewidth=5)
    plt.plot(threshold, recall[:-1], "b", label="recall", linewidth=5)
    plt.xlabel("threshold", fontsize=19)
    plt.legend(loc="upper right", fontsize=19)
    plt.ylim([0, 1])

plt.figure(figsize=(14, 7))
plot_precision_and_recall(precision, recall, threshold)
plt.show()

从上图可以清楚地看到,召回率正在迅速下降,大约在 85%左右。因此,在此之前,您可能希望选择精度/召回率之间的权衡——可能在 75 %左右。

您现在可以选择一个阈值,为您当前的机器学习问题提供最佳的精确度/召回率权衡。例如,如果您想要 80%的精度,您可以很容易地查看这些图,并看到您将需要 0.4 左右的阈值。然后你就可以用这个阈值训练一个模型,并得到你想要的精确度。

另一种方法是将精确度和召回率相互对比:

**def** plot_precision_vs_recall(precision, recall):
    plt.plot(recall, precision, "g--", linewidth=2.5)
    plt.ylabel("recall", fontsize=19)
    plt.xlabel("precision", fontsize=19)
    plt.axis([0, 1.5, 0, 1.5])

plt.figure(figsize=(14, 7))
plot_precision_vs_recall(precision, recall)
plt.show()

ROC AUC 曲线

ROC AUC 曲线提供了评估和比较二元分类器的另一种方法。该曲线绘制了真阳性率(也称为召回率)对假阳性率(错误分类的阴性实例的比率),而不是绘制了精度对召回率。

**from** **sklearn.metrics** **import** roc_curve
*# compute true positive rate and false positive rate*
false_positive_rate, true_positive_rate, thresholds = roc_curve(Y_train, y_scores)*# plotting them against each other*
**def** plot_roc_curve(false_positive_rate, true_positive_rate, label=**None**):
    plt.plot(false_positive_rate, true_positive_rate, linewidth=2, label=label)
    plt.plot([0, 1], [0, 1], 'r', linewidth=4)
    plt.axis([0, 1, 0, 1])
    plt.xlabel('False Positive Rate (FPR)', fontsize=16)
    plt.ylabel('True Positive Rate (TPR)', fontsize=16)

plt.figure(figsize=(14, 7))
plot_roc_curve(false_positive_rate, true_positive_rate)
plt.show()

中间的红线代表一个纯粹随机的分类器(例如抛硬币),因此你的分类器应该尽可能远离它。我们的随机森林模型似乎做得很好。

当然,我们在这里也有一个权衡,因为分类器产生的假阳性越多,真阳性率就越高。

ROC AUC 得分

ROC AUC 得分是 ROC AUC 曲线的相应得分。它只是通过测量曲线下的面积来计算,该面积称为 AUC。

100%正确的分类器的 ROC AUC 得分为 1,完全随机的分类器的得分为 0.5。

**from** **sklearn.metrics** **import** roc_auc_score
r_a_score = roc_auc_score(Y_train, y_scores)
print("ROC-AUC-Score:", r_a_score)

ROC_AUC_SCORE: 0.945067587

不错!我认为这个分数足以将测试集的预测提交给 Kaggle 排行榜。

摘要

我们从数据探索开始,对数据集有所了解,检查缺失的数据,了解哪些特征是重要的。在这个过程中,我们使用 seaborn 和 matplotlib 来做可视化。在数据预处理部分,我们计算缺失值,将特征转换为数值,将值分组并创建一些新特征。之后,我们开始训练 8 个不同的机器学习模型,选择其中一个(随机森林)并对其进行交叉验证。然后我们讨论了随机森林是如何工作的,看看它对不同特性的重要性,并通过优化它的超参数值来调整它的性能。最后,我们查看了它的混淆矩阵,并计算了模型的精度、召回率和 f 值。

下面您可以看到“train_df”数据帧的前后图片:

当然,仍有改进的空间,如通过相互比较和绘制特征并识别和去除有噪声的特征,进行更广泛的特征工程。另一个可以改善 kaggle 排行榜整体结果的事情是对几个机器学习模型进行更广泛的超参数调整。你也可以做一些整体学习。

基于范围预测任务持续时间

原文:https://towardsdatascience.com/predicting-the-task-duration-based-on-a-range-a345b83fab58?source=collection_archive---------16-----------------------

使用机器学习进行项目评估。

之前的条目之一中,我们已经建立了一个统计模型,用于根据估计预测实际项目时间和成本。我们讨论过,我们可以将评估(敏捷项目和瀑布项目)拟合到对数正态分布,这保证了积极的支持。正如我们在另一篇文章的中所讨论的那样,使用统计方法进行估算使我们能够给出具有所需置信水平的预测,并预测货币收益、成本和风险。

我被问到的一件事是,当一个估计值被作为一个范围给出时,这个模型如何推广。事实上,这是每个人都教导我们的:不要给出一个单一的数字,而是范围。一种方法是继续使用我们的统计模型,并在中间输入一个数字,即两个值的平均值。

这样,该模型无需修改即可使用。

这种方法有两个问题:

  1. 取一个高低的平均值是任意的。它将给出的信息减少了一半。最好有一个算法来学习我们需要在低边界和高边界之间的区间内的什么地方设置变量 x
  2. 通过给我们一系列的数据,开发者试图向我们传达一个非常重要的信息:评估的不确定性程度。正确的模型应该使用这些信息。

为了简化过程,我们将对所有的估计值和实际值取自然对数。由于我们使用对数正态分布对估计值建模,我们的新变量ylh将分别是实际天数、低估计值和高估计值的对数。在这种情况下我们可以使用正态分布!我们将使用线性回归对y建模:

θhθl 相等的情况下,我们会遇到与之前讨论的完全相同的问题

在这种情况下,单个数据的似然函数可以写成如下形式(在之后)。

如前所述,通过给出一个范围,开发人员希望向我们传达评估的不确定性。我们应该将这种不确定性包括在我们对 σ 的估计中。直观上,范围与标准偏差成比例,我们可以通过将 σ 建模为:

如果我们也使用精度参数 τ 代替 σ 0:

那么我们的可能性函数将是:

τθ 的先验传统上分别为伽玛分布和正态分布;

这里 αβλ 为超参数。

ζ 选择先验比较困难。对于我们选择的这种似然函数,没有共轭先验存在。现在我们可以选择正态分布。这种分布的零均值意味着我们先验地不信任范围(我们知道许多顾问的范围总是 20%并且不传达任何信息)。先验分布的高均值意味着我们更加关注估计的不确定性程度。

为简单起见,我们将平均值设为零。

负对数后验函数为:

在这个博客里我会找到参数,对应最大后验概率。为了避免在微分中出错,我们将使用张量流。我们将按照这个例子来构建我们的代码

import numpy as np
import pandas as pd
import tensorflow as tf

此处的数据代表预计和实际天数。我们看到开发人员喜欢在他的预算中增加 25%作为缓冲。然而,对于一些故事,他增加了更多的缓冲,也许是为了表明更多的不确定性。

seed=1389
tf.reset_default_graph()
task_data = pd.DataFrame({'low':[4,14,4,3,4,3,4,9,6,27,20,23,11],
                          'high':[5,18,5,4,5,7,5,10,8,30,25,29,14],
                          'actual':[17,8,5,3,5,4,9,9,4,27,16,15,7,]})%matplotlib inline
import matplotlib.pyplot as plt
import seaborn as sns
fig, ax = plt.subplots(figsize=(11.7, 8.27))
task_data['story_id'] = task_data.index
data_for_plot = pd.melt(task_data, id_vars="story_id", var_name="type", value_name="days")
task_data.drop(columns=['story_id'], inplace=True)
sns.barplot(x='story_id', y='days', hue='type', data=data_for_plot,ax=ax);

定义变量时,我们用 τ 代替另一个变量 ρ :

这是为了避免优化器选择负的 τ

#Taking the log of data
log_data = np.log(task_data.values)
N = log_data.shape[0]#Defining variables
theta_h = tf.Variable(name='theta_h', initial_value=0.5)
theta_l = tf.Variable(name='theta_l', initial_value=0.5)
zeta = tf.Variable(name='zeta', initial_value=0.01)
rho = tf.Variable(name='rho', initial_value=0.01)

由于不想调太多超参数,我们就把 αβ 设为一。两个 λ 参数都作为正则化参数,所以我们必须调整它们

#Set the hyperparameters
alpha = tf.constant(name='alpha', value=1.0)
beta = tf.constant(name='beta', value=1.0)
lambda1 = tf.constant(name='lambda1', value=1e-4)
lambda2 = tf.constant(name='lambda2', value=1e-4)def loss(l, h, y):
    return tf.log(1+zeta**2*(h-l)) + \
        rho**2/2/(1+zeta**2*(h-l))**2 * (y - theta_l*l - theta_h*h)**2cummulative_loss = tf.reduce_sum(list(np.apply_along_axis(lambda x: loss(*x), axis=1, arr=log_data )))
cost = cummulative_loss - (N+1-2*alpha)/2*tf.log(rho**2) + beta*rho**2 + \
rho**2*lambda1/2*(theta_h**2+theta_l**2) + rho**2*lambda2/2*zeta**2learning_rate = 1e-4
optimizer = tf.train.AdamOptimizer(learning_rate)
train_op = optimizer.minimize(cost)import math
init = tf.global_variables_initializer()
n_epochs = int(1e5) with tf.Session() as sess:
    sess.run(init) for epoch in range(n_epochs):
        if epoch % 1e4 == 0:
            print("Epoch", epoch, "Cost =", cost.eval())
            print(f'Parameters: {theta_l.eval()}, {theta_h.eval()}, {rho.eval()}, {zeta.eval()}')
        sess.run(train_op)
    best_theta_l = theta_l.eval()
    best_theta_h = theta_h.eval()
    best_sigma = 1/math.sqrt(rho.eval())Epoch 0 Cost = 55.26268
Parameters: 0.5, 0.5, 0.009999999776482582, 0.009999999776482582
Epoch 10000 Cost = 6.5892615
Parameters: 0.24855799973011017, 0.6630115509033203, 0.6332486271858215, 1.1534561276317736e-35
Epoch 20000 Cost = 1.39517
Parameters: 0.2485545128583908, 0.6630078554153442, 1.3754394054412842, 1.1534561276317736e-35
Epoch 30000 Cost = 1.3396643
Parameters: 0.24855604767799377, 0.6630094647407532, 1.4745615720748901, 1.1534561276317736e-35
Epoch 40000 Cost = 1.3396641
Parameters: 0.24855272471904755, 0.6630063056945801, 1.4745622873306274, 1.1534561276317736e-35
Epoch 50000 Cost = 1.3396646
Parameters: 0.2485586702823639, 0.6630119681358337, 1.4745632410049438, 1.1534561276317736e-35
Epoch 60000 Cost = 1.3396648
Parameters: 0.2485581487417221, 0.6630115509033203, 1.4745649099349976, 1.1534561276317736e-35
Epoch 70000 Cost = 1.3396643
Parameters: 0.2485586702823639, 0.6630122065544128, 1.4745644330978394, 1.1534561276317736e-35
Epoch 80000 Cost = 1.3396643
Parameters: 0.24855820834636688, 0.6630116701126099, 1.4745631217956543, 1.1534561276317736e-35
Epoch 90000 Cost = 1.3396646
Parameters: 0.248562291264534, 0.663015604019165, 1.474563717842102, 1.1534561276317736e-35

这里有意思的是 ζ 为零。这意味着我们不能相信开发者给我们的不确定性估计。这也意味着我们可以只使用由学习参数 θlθh 指定的平均值周围的对数正态分布。比方说,同一个开发人员估计一项新任务需要 10-15 天。代入我们看到的公式:

mu = best_theta_l*math.log(10)+best_theta_h*math.log(15)
most_likely_prediction = math.exp(mu)    
most_likely_prediction10.67385532327305

我们还可以通过将这些值直接代入对数正态分布来获得 95%的置信度:

from scipy.stats import lognorm
distribution = lognorm(s=best_sigma, scale=most_likely_prediction, loc=0)
print(f'95% confidence: {distribution.ppf(0.95)}')95% confidence: 41.3614192940211

如我们所见,如果我们想要 95%的置信度,我们必须给出 41 天的估计,而不是 50%置信度的 11 天。如果你看到开发人员在过去没有很好地完成任务评估,这就很容易解释了。

您可以从 github 访问笔记本。

预测风险投资的前景

原文:https://towardsdatascience.com/predicting-the-venture-capital-landscape-4e3496f8b92f?source=collection_archive---------1-----------------------

“Nearly every top Silicon Valley company has been the beneficiary of early funding from firms on Sand Hill Road.”

介绍

市场将走向何方?资金会放缓还是会激增?哪些行业正在崛起或陷入困境?

生活在旧金山,初创企业会淡出人们的讨论,也会活跃起来,就像它们在新闻和市场上一样。作为湾区的大多数居民,我搬到这里是为了实现梦想,成为硅谷崛起的变革浪潮中的一员。从我早期对创业公司的迷恋,我感到有动力更好地了解创业公司,并从资金开始。

行动纲要

通过使用机器学习,我能够相对自信地预测整个风险资本市场的趋势以及哪些领域最有前途。利用 2013 年的 Crunchbase 数据,我能够预测 2014 年初的资金数额。此外,我预测当时最有希望的行业是生物技术,最差的行业是社会服务。如果给定 Crunchbase 当前的专有数据,我可以很容易地预测 2017 年剩余时间的资金。

数据收集

Crunchbase 保存了关于初创公司的信息,包括这些公司何时得到了资助,由谁资助,属于哪个行业,以及创始人有什么样的公司背景。Crunchbase 始于 2007 年,由用户贡献的内容运营,这些内容在被列入网站之前会经过审查。Crunchbase 以 MySQL 格式免费提供他们的一些数据,提供他们所有的信息,直到 2013 年底。为了获得访问权,一个人必须注册成为研究员。然而,一个人必须注册成为一家企业,并每年支付大约 6000 美元来访问他们当前的数据。因此,我的研究范围将是免费获取的信息,以收集过去的见解,如果有最新的数据,这些见解可以很容易地复制。

数据本身

非常方便的是,我能够在 11 个文件中通过一系列 MySQL 查询轻松地提取和研究数据。在对所有文件进行了大量研究之后,我使用了一些连接来处理一个数据集:funding。有一次,在一个数据帧中,我重新组织了结构,把它放入一个时间序列中。所以我的变量是 2005-2013 年的月度时间序列数据。

Crunchbase began in 2007 and has a significant amount of information for 2005 and onward.

我限制范围的选择是基于观察每年独特投资数量的直方图。值得注意的是,用户可以贡献过去的信息,这个直方图有目的地缩小,因为投资条目可以追溯到 20 世纪 70 年代。

Y Combinator, Techstars and SV Angel are the top three. Andreessen Horowitz rests in the middle with 76 commitments.

SV Angel, First Round Capital and Sequoia Capital. Although not shown, Sequoia Capital leads for the most number of commitments for Series B and in third for Series C.

以上两个图表显示了所有投资者至少有 50 个承诺。顶级投资者因融资阶段而异。Y Combinator 在种子期融资方面领先,而 SV Angel 在首轮融资中排名第一,在种子期融资中排名第三。

型号选择

我想从两个角度来看初创企业的状况。一个视角是观察整个创业市场的表现,另一个视角是进一步观察行业水平。

整体市场(ARMA)

“市场观点”分析了从 2005 年初到 2013 年底每个月的融资总额。由于这是一个简单的时间序列,我认为自回归-移动平均(ARMA)模型将是合适的。ARMA 结合了两个模型,其中每个值都根据其过去的值进行回归,并将以前的误差项作为输入,并根据与以前预测的偏差来预测下一个值。误差项是预测值和实际值之间的差异。ARMA 模型是分析时间序列数据的标准工具。

Total Funding as reported from Crunchbase. The blue line is the monthly raw data in billions of inflation-adjusted USD and the red line shows the market trend (or the annual average).

该图显示了 2009 年前后融资额的下降,这在大萧条时期是有道理的。然后,资金稳步增加,直至 2013 年底。

即使我每个月都有资金,建立 ARMA 模型的第一步是诱导平稳性。将数据转换为平稳时间序列背后的理论是通过与相关时间进行差分来合并数据的内在相关结构。也就是说,一次资金稍微依赖去年,稍微依赖上月。( 2

Each point is the difference while taking into account last month’s change (t-1) and last year’s change (t-12) and last year’s last month change (t-13) for each time (t).

上图是一个平稳的时间序列,能够模拟和预测未来的资金。该序列的平均值非常接近于零,并且大多具有恒定的方差,这是平稳性的两个要求。所示的两次跳跃将限制我的预测的可信度,然而在给定稍微麻烦的数据的情况下,预测仍然是可能的。在我讨论整体市场的结果之前,我们先来关注一下板块层面。

个别部门(LSTM)

Crunchbase 有 42 个预定义的行业标签(如硬件、旅游、体育)。为了保持一致性,我将每个行业放入 2005 年至 2013 年的时间序列中。对于这种类型的数据,我认为长短期记忆(LSTM)递归神经网络(RNN)会工作得很好。LSTM 是专门为长时间“记忆”信息而设计的。一个简单的 RNN 接受一个输入,并通过一组权重(一个层)创建一个输出,同时还通过这些输入进行循环,然后更新权重。除了图层有四个相互关联的更新之外,LSTM 的操作方式与此相同。这四个中最重要的部分是遗忘之门,过去的信息要么被保留,要么被丢弃。另外三个交互创建输入的过滤版本作为输出。( 3 这整个过程是一个历元,其中训练数据在一个迭代周期内更新权重。

Trends of the biotech, the software and the finance industry. The finance sector shows significant increase after the financial crisis signaling increased skepticism of current financial institutions.

2009 年后,软件行业的融资出现下滑,而 2010 年后,金融行业的融资大幅增加。生物技术在这整个时期增长了三倍。对所有这些不同的扇区使用 LSTM 的一个很大的优点是,由于神经网络可以学习数据的潜在依赖性,因此不需要进行差分。

结果

对于整个市场来说,我最好的 ARMA 模型的 R 平方统计值是 0.452。R 平方统计值的范围从 0 到 1,表示模型捕捉到的数据方差。ARMA 模型做了下降的工作,但似乎不能完全解释两个方向的大峰值。它似乎捕捉到了某种形式的跳跃,但在预测上保持保守。

就单个行业而言,我的 LSTM 模型在训练数据和测试数据上的 R 平方值分别为 0.604 和 0.382。训练集由 2005 年到 2012 年组成,测试集是 2013 年的全部。两张图中的蓝线分别是测试集的 R 平方统计值和损失函数值。损失函数应最小化,因为这是预测值和实际值之间偏差的度量。R 平方(r2)图显示了 LSTM 模型如何快速学习,然后在大约 400 个历元处稳定下来,并略有改善。“损失”图显示了训练集和测试集如何收敛。

For both graphs, the x-axis is the number of epochs.

R 平方的红色十字准线显示了我的模型在哪里以及在什么值下性能最好。我可以运行这个模型更多的时期;但是,测试集开始增加其方差,表明模型开始过度拟合训练数据,因此不会很好地推广到预测。

解释

整体市场在 2012 年后稳步增长,我的模型预测这种情况将持续到 2014 年初。根据 Crunchbase 的数据,初创企业已经从 2008 年的金融危机中迅速复苏。

预计数亿美元将流入生物技术、清洁技术、软件、企业、电子商务、移动和医疗部门。生物技术、清洁技术和医疗尤其令人感兴趣,因为它们在这段时间内增长最快。软件、企业、电子商务和移动是资金最多、资金流最可靠的行业。

另一方面,公共关系、非营利、法律、地方和政府部门是最没有前途的部门,预计所有这些部门每月基本上都没有资金。围绕这些部门的共同线索是,它们属于一个更大的社会服务类别。然而,这是否意味着创新在这里是不可能的?我坚信这些行业不需要更多的创新;然而,这些行业的盈利能力可能很低。

结论

2012 年后,随着资金的稳定流入,市场保持了增长。在此期间,生物技术部门成为最有前途的部门,而社会服务部门缺乏创新的代表性。

接下来,我打算将我的关注点进一步缩小到个别公司及其投资者,以更好地理解创业精神,并衡量某些投资者是否对结果有重大影响。最重要的是,我计划体验一下企业家的生活,了解市场动向对一个人的公司有重大价值。

用机器学习预测 NCAA 锦标赛的冷门

原文:https://towardsdatascience.com/predicting-upsets-in-the-ncaa-tournament-with-machine-learning-816fecf41f01?source=collection_archive---------4-----------------------

更新:看看这个的后续,我在这里讨论了 3 个额外的不安信号。

疯狂即将来临!一年一度的男子大学篮球锦标赛将于 3 月 15 日开始,很快数百万球迷将填写他们的括号。

对我们大多数人来说,冷门是锦标赛中最精彩的部分。在体育运动中,很少有球迷的经历能比得上看到实时爆冷的兴奋感,以及处于劣势的球队赢得胜利时的纯粹喜悦:

唯一比看着疯狂的冷门下跌更好的事情是把冷门选秀权钉在你的支架上。说起来容易做起来难:在最近的一次全国在线括号比赛中,平均只有 19%的括号选择了不满意。冷门还会让一些种子选手提前回家。例证:2016 年 62%的 ESPN 挑战赛排名密歇根州立大学进入了四强,斯巴达队获得了第二多的冠军。但疯狂随之而来:汤姆伊佐的球队在第一轮就被拥有 15 个种子的田纳西中部州立大学淘汰了。

正确挑选冷门可以区分你的括号,给你一个竞争优势。我试图通过使用数据和机器学习来预测 NCAA 锦标赛中的冷门,从而战胜困难。

使用团队种子定义意外事件

每年,64 个符合条件的团队被分成四组,每组 16 个(“地区”),每个团队都被分配一个“种子”,排名从 1(最好)到 16(最差),就像 2016 年的中西部地区一样。一个队在几乎每场比赛中都有技术优势,但人们不会对 9 号种子击败 8 号种子,甚至 10 号种子击败 7 号种子感到震惊。这些比赛基本上都是“胜负难分”的。我对预测更令人震惊和意想不到的沮丧感兴趣。

我把一场失利定义为一个比对手低至少 4 位的种子队的胜利,比如 1 号种子输给 5 号种子或更低,2 号种子输给 6 号种子或更低,等等。因为锦标赛每年都使用相同的结构,所以种子赛是一种快速、简单的方法来识别和研究冷门。

数据准备和探索

数据

我获得了自 2003 年以来每支锦标赛球队在常规赛和锦标赛中球队和球员表现的数据。该数据包括 584 场有“潜在冷门”的锦标赛,这意味着这些球队的种子差距至少为 4。

特征工程

我为每个团队创建了一个包含 82 个特征的数据集,包括整个赛季的团队表现、团队效率指标、教练比武经验/成功以及团队旅行。因为目标是预测,所有特征都是在每场锦标赛游戏的之前可用的特征。然后,我做了一些数据探索,以确定可能预测冷门的趋势。

冷门和种子比赛

下面的图表显示了每年的冷门次数,以及每年的平均值。不要疯狂地挑太多的冷门;平均每年只有 9 起。

On average only 9 upsets occur in each tournament

哪些比赛最有可能导致冷门?事实证明,在第 1 轮和第 2 轮中出现的 14 个常见种子配对占所有“潜在冷门”游戏的 85%。下面显示了这些比赛,以及它们的“冷门率”(导致冷门的比赛比例)的热图。

Heat map of upset rates for the most common seed pairings

该图基于种子匹配确定了一些好的不规则候选:

  • 在第一轮中,关注 12 对 5 和 11 对 6。12 号种子选手和 11 号种子选手赢得这些比赛的几率约为 40%。
  • 如果你觉得大胆,在第一轮中拿一个 13 号种子胜过一个 4 号种子。13 号种子队赢得了 20%的比赛。
  • 2 粒种子很少在第一轮中失败(7%),但在第二轮中,他们令人惊讶地容易被 7 粒种子(33%)和 10 粒种子(37%)打乱。
  • 这些 10 粒种子和 7 粒种子比 8 粒种子和 9 粒种子更适合 16 粒种子,后者很少在第二轮中击败 1 粒种子(12-13%)。
  • 考虑在甜蜜的 16 强中放一个 11 号种子:在第二轮中,11 号种子赢得了三分之一的比赛。

发现灰姑娘和后进生

除了种子赛,赢的失败者和输的热门有什么特征?

团队效率边际

从肯·波默罗伊优秀的高级篮球分析网站,一个球队的调整后的效率边际是一个单一的数字,它表明了比赛的整体实力。本质上,它代表了在给定 100 分的情况下,一个球队相对于一个普通对手的预期胜率。下面我画出了我的数据集中每场比赛的失败者和最受欢迎者的效率边际,数据点显示了比赛是否导致了冷门。

Upsets involve underdogs with higher efficiency and favorites with lower efficiency

大多数冷门都发生在差幅超过 10 的劣势方对差幅低于 25 的热门方的时候。事实上,符合这些标准的游戏有 35%的时间会导致不愉快,而不符合这些标准的游戏只有 13%。作为挑选冷门的简单经验法则,你当然可以做得更糟!

赚取额外的财富——篮板和失误

在篮球比赛中,球队在投篮不中或得分后交换控球权,但球队也可以通过反弹自己的失误(产生额外的投篮机会)和迫使失误(夺走对手的机会)来获得“额外”的控球权。为了计算“进攻篮板和失误率”,我计算了整个赛季中每支球队平均每场比赛的进攻篮板和失误优势。

Winning underdogs have better offensive rebounding and turnover margins

在左边,我显示了在非冷门(左)和冷门(右)比赛中的冷门选手和热门选手的平均差距。

在没有冷门的情况下,热门比冷门有更高的利润,但是在冷门的情况下,情况正好相反。如果处于劣势的一方比他们的对手更擅长获得进攻篮板和失误,那么这场比赛就是一场逆转。

用于镦粗预测的机器学习

与其逐个检查 82 个特征,不如让算法发挥作用。我将游戏分成训练集(80%)和测试集(20%),并训练每个算法进行预测。

训练分类算法

我将冷门预测作为一个分类问题,目标是将每场比赛归类为“冷门”与否。我选择了 5 种分类算法进行训练:

  • 逻辑回归
  • 神经网络
  • 支持向量机
  • 随机森林
  • 梯度树提升分类器

使用 python 的 scikit-learn 包,我使每个算法适合训练数据,并使用 5 重交叉验证来调整模型超参数(影响模型拟合的设置)。为了确定每个算法的最佳设置,我使用了交叉验证 F1 分数。这里, F1 分数是扰乱精度(最小化不正确的扰乱预测)和召回(预测大多数实际扰乱)的平衡。关于 F1 的更多信息,请参见此处

我也应该承认冷门在这些数据中是“不平衡”的,只有 22%的游戏是冷门。这些算法通常最适用于接近对半分割的示例。不涉及太多细节,我会注意到训练数据被重采样以在扰乱和非扰乱之间创建平衡(在这里阅读关于不平衡数据和重采样的更多信息)。

测试模型性能

对于每种算法,在保留的测试集上评估来自训练的最佳模型。5 个模型的 ROC 曲线如下所示:

该图显示,对于每个分类器,随着真阳性率的增加,假阳性率也增加。大多数分类问题都是如此;随着更多的真实情况被预测,更多的虚假情况也被预测。我还注意到,这些算法在 ROC 曲线的不同点上最大化了真正的阳性率,因此将它们组合在一起可能会产生更好的结果。

“未来”对决分类

为了评估一个更“真实世界的场景”,我想预测单个锦标赛的冷门。我使用逻辑回归模型预测了 2017 年的 42 场潜在冷门比赛,这些比赛是我在之前的训练和测试中推出的。

Matrix showing prediction results for 2017

该矩阵将预测细分为正确的非镦粗(左上)、正确的镦粗预测(右下)、不正确的非镦粗预测(左下)和不正确的镦粗预测(右上)。

该模型预测了 2017 年的 15 次颠覆。在 2017 年的 10 次实际冷门中,有 8 次被模型识别出来,但模型也做出了 7 次“假阳性”的冷门预测。该模型在预测冷门时有点过于激进,但对于这些难以预测的游戏来说,它仍然是正确的。

更仔细地观察预测,可以更深入地了解模型在哪些方面表现良好,以及在哪些方面需要改进:

Upset predictions are most accurate for Round 1

模型真的很擅长预测第一轮,23/24 场比赛预测正确。对于所有其他回合,该模型去 10/18。我希望模型在整个比赛中更加精确,但第一轮也是最令人失望的时候。大多数括号池玩家可以通过在第一轮中采取模型预测的冷门来获得优势。我还计算出,在这些令人沮丧的预测上下注,将获得 21%的净回报。

结论

我有几个改进模型预测的想法,包括添加更多的数据来创建更多的特征,对团队最近的表现进行加权,以及尝试其他算法或算法组合。我还想尝试对比赛分数而不是最终结果进行建模,并研究其他 NCAA 锦标赛预测问题,如识别被高估的球队提前回家的特征,以及“灰姑娘”失败者准备深入锦标赛的特征。

我将在 Twitter 上宣布未来的工作,所以如果你喜欢,请给我一个关注

预测维基百科的网络流量

原文:https://towardsdatascience.com/predicting-web-traffic-on-wikipedia-44004d6b152e?source=collection_archive---------4-----------------------

现场 Kaggle 比赛

这是我在 Kaggle 上参加 WTF 比赛的文档,这是网络流量预测的简称!一个月不稳定的管道建设,一些令人沮丧的周末,40 次提交和 22 次提交后,我仍然没有达到我的期望。虽然学到了很多,但这份报告是试图组织学习。

也就是说,一个警告——这个博客会稍微有点技术性:)

这是一场现场比赛,由 Kaggle 主办,由 Google 发布 145K 维基百科页面的网络流量将在 2017 年 9 月至 11 月期间进行预测,这意味着,我们提交的准确性将实时计算——取决于未来如何发展!训练数据由过去两年中维基页面上每天的查看次数组成。

听起来像一个非常标准的时间序列问题,对吗?大错特错。

我的方法——Github

在我的脑海中有一个面向 xgboost 的策略并不总是很好,这个竞争让我离开了我的舒适区!很自然地,我查阅了关于 ARIMA 模型表现的讨论/内核——显然,自回归模型不能很好地推广到目标变量的未知范围(这是我们问题中非常可能出现的情况)。

一对夫妇的方法脱颖而出:

  • 将时间序列问题建模为回归问题,每个页面-日期对被视为一行。
  • 使用脸书的预言家,他们的新预测工具。

在一些顶级 kagglers 的建议下,我决定采用回归模型——将基于时间序列的数据框架融合到传统的每行页面日期特征数据框架中。运行 xgb,并在类似熔化的测试数据帧上进行预测。

特征工程

总体平均值/中值 —一个简单的常量提交,包含过去 8 周的平均值/中值,在第一阶段很难被超越。包括在内。

滚动方式和滚动中间值——这些是我想到的一些最明显的特性,然而它们实现起来并不简单。我同意,在预测今天的流量时,过去 7 天的滚动平均值将是一个重要的特征,但挑战是要求我们预测未来三个月的流量数据。

当当前日期是 9 月 14 日时,如何找到 11 月 1 日的周滚动平均值?

因此,像滚动平均这样的功能在验证中表现非常好,但在公共排行榜上却不是这样。最后,我继续使用过去 30 天和 60 天的滚动平均值和中间值。对于我无法计算这些特征的日期,我继续使用时间序列中最后一个可用的计算特征的代理。

后来,我包括了更多的功能,如滚动标准开发,滚动最小/最大等。

基于工作日的平均值/中值 —这些特性被证明是最重要的特性之一!很明显,很多维基百科的点击是工作日/周末相关的——我试图通过过去六个月的工作日累计平均值和中值来捕捉这一点。

语言和来源——我试图整合来自页面语言或来源(爬虫、蜘蛛等)的统计数据,但这些并没有让我在一个普通的 xgboost 上得到提升。为了简单起见,把它们去掉了。

最后一天的访问——像最后一天的访问这样的特性在进行验证运行时非常有用。测试数据并非如此,因为竞争是实时的。我必须提交对未来两个月所有页面的预测——显然,使用最后一天的访问量是愚蠢的!

流水线作业

构建一个抽象的模块化管道占用了我大部分的带宽!我必须将宽格式的数据帧转换成长格式的数据帧,并对每个页面-日期对进行滚动统计。计算每个滚动统计的函数有可选参数,如“last _ n _ days”——30 天的滚动平均值,以及“rows _ to _ consider”——我们希望返回多少个日期。

在大量阅读内核和论坛之后,我坚持许多顶级 kagglers 的策略:

  • 在所有页面上训练一个 Xgboost 模型。这将帮助我们确定整个维基百科的总体趋势。
  • 在网页的所有未来日期上测试模型。

另一种方法是在每个页面上单独训练一个 xgboost,使算法个性化。这非常耗时,并且可能无法很好地推广。

型号

XGBoost 是爱,XGBoost 是命!

我继续与香草 xgb,再一次。首先,xgboost 在几个月的讨论中得到了很好的反馈。这是我第一次使用自定义损失函数( SMAPE )作为 xgboost 参数(feval),这是一个有争议的损失函数选择——不可微且不对称!

我面临的一个主要问题是,基于树的模型不能很好地推广到未知的范围,在我添加更多功能之前,与 xgboost 的常量预测斗争了一段时间!解决这个问题的方法是将目标变量的差异视为目标变量,从而限制范围。这需要以类似的方式改变特性,我没有走这条路。

挑战&失误

  • XGBoost 不能很好地推广到未知范围,如前所述。
  • 由于我将数据帧分解为长格式,如果我只考虑最近六个月的数据,那么行数达到了 2600 万!这是其中的一个权衡,放弃旧数据而不是 RAM 限制。
  • 正如我前面提到的,在测试数据集中计算未来几天的滚动统计是不可能的。我试着把它们设为 NA,但这大大夸大了预测(因为模型在训练中没有看到 NA)。最后,我坚持向前填充滚动统计数据。
  • 建了一个复杂的管道,调试简直是一场噩梦!我还是想不出更简单的方法,权衡:)
  • 我的 noob 错误——将数据帧的浅层副本视为深层副本。我怎么也想不出这个 bug!

学习成果&结论

我从这次比赛中得到的主要收获是:

  • 花更多的时间在 kaggle 讨论上,并且经常参与。这将建立一个循环——工作、讨论。讨论,工作。
  • 应该从一开始就抽象我的功能。重构一点都不好玩!
  • 我想我已经刷爆了我的功能,现在要看看别人提交的内容了!
  • 既然我擅长流水线和特性工程,我应该更加关注模型调优和集成。
  • 不要害怕时间序列问题。在一天结束时,它的好 ol '回归!

总的来说,这是一场有趣的比赛——现在想起来,可能更令人沮丧而不是有趣!学到了很多,对我将来的比赛很有帮助。

到下一个:)

这篇文章最初发表在我的 博客 上。每周一篇博客

预测工程:如何设置你的机器学习问题

原文:https://towardsdatascience.com/prediction-engineering-how-to-set-up-your-machine-learning-problem-b3b8f622683b?source=collection_archive---------2-----------------------

用机器学习解决问题的第一步的解释和实现

这是关于我们如何在功能实验室进行机器学习的四部分系列中的第二部分。这套物品是:

  1. 概述:机器学习的通用框架
  2. 预测工程(本文)
  3. 特征工程:机器学习的动力
  4. 建模:教授算法进行预测

这些文章将涵盖应用于预测客户流失的概念和完整实现。project Jupyter 笔记本在 GitHub 上都有。(完全披露:我在 Feature Labs 工作,这是一家初创公司开发工具,包括 Featuretools ,用于解决机器学习的问题。这里记录的所有工作都是用开源工具和数据完成的。)

预测工程概念

当在机器学习任务中使用真实世界的数据时,*我们定义问题,这意味着我们必须开发自己的标签——*我们想要预测的历史示例——来训练监督模型。制作我们自己的标签的想法最初可能对数据科学家(包括我自己)来说是陌生的,他们从 Kaggle 竞赛或教科书数据集开始,其中已经包含了答案。

预测工程背后的概念——制作标签来训练有监督的机器学习模型——并不新鲜。然而,它目前还不是一个标准化的流程,而是由数据科学家在按需完成。这意味着,对于每一个新问题,即使是相同的数据集,也必须开发一个新的脚本来完成这项任务,导致解决方案无法适应不同的预测问题。

更好的解决方案是编写能够灵活改变业务参数的函数,允许我们为许多问题快速生成标签。这是数据科学可以从软件工程中学到的一个领域:解决方案应该是可重用的,并接受不断变化的输入。在本文中,我们将看到如何实现一种可重用的方法来解决机器学习问题的第一步——预测工程。

预测工程的过程

预测工程既需要从业务的角度得到指导,以找出要解决的正确问题,也需要从数据科学家的角度得到指导,以确定如何将业务需求转化为机器学习问题。预测工程的输入是定义业务需求预测问题的参数,以及寻找我们想要预测的例子的历史数据集

Process of prediction engineering.

预测工程的输出是一个标签时间表:一组标签,其中包含从过去数据中获得的负面和正面示例,以及相关的截止时间,指示我们何时必须停止使用数据来为该标签创建特征(稍后将详细介绍)。

对于我们将在本系列中完成的用例——客户流失——我们将业务问题定义为通过降低流失率来增加每月活跃用户。机器学习问题是建立一个模型,利用历史数据预测哪些客户会流失。这项任务的第一步是制作一组过去客户流失案例的标签。

构成客户流失的参数以及我们希望进行预测的频率将根据业务需求而有所不同,但在本例中,假设我们希望在每个月的第一天进行预测,客户将在预测后的一个月内流失。流失将被定义为超过 31 天没有活跃会员。

重要的是要记住,这只是与一个业务问题相对应的客户流失的一种定义。当我们编写函数来制作标签时,它们应该接受参数,这样它们就可以快速地改变为不同的预测问题。

我们预测工程的目标是如下的标签时间表:

Example of label times table

根据历史数据,这些标签对应于客户是否有过交易。每个客户都被多次用作训练示例,因为他们有几个月的数据。即使我们没有多次使用客户,因为这是一个与时间相关的问题,我们也要正确地实现截止时间的概念。

截止时间:如何确保要素有效

没有截止时间标签就不完整,截止时间代表当我们不得不停止使用数据为标签制作特征时。因为我们在每个月的第一天预测客户流失,我们不能使用第一个之后的任何数据来制作那个标签的特征。因此,我们的截止时间都在每月的第一天,如上面的标签时间表所示。

每个标签的所有特征必须使用该时间之前的数据,以防止数据泄露的问题。截止时间是对时间序列问题建立成功解决方案的关键部分,许多公司没有考虑到这一点。使用无效数据来制作特性会导致模型在开发中表现良好,但在部署中失败。

想象一下,我们没有将我们的特征限制在每个标签的月 1 日之前发生的数据上。我们的模型会计算出在该月有付费交易的客户不可能在该月有交易,因此会记录较高的指标。然而,当需要部署模型并对未来一个月进行预测时,我们无法访问未来的交易,我们的模型将表现不佳。这就像一个学生在家庭作业上做得很好,因为她有答案,但在考试中却没有相同的信息。

客户流失数据集

现在我们有了概念,让我们来研究一下细节。 KKBOX 是亚洲领先的音乐流媒体服务,为超过 1000 万会员提供免费和按月付费的订阅选项。KKBOX 提供了一个数据集用于预测客户流失。有 3 个略超过 30 GB 的数据表,由下面的模式表示:

Relational diagram of data.

这三个表格包括:

  • 客户:背景信息,如年龄和城市(msno 是客户 id):

  • 交易:每个客户每次付款的交易数据:

  • 活动日志:客户倾听行为的日志:

这是订阅业务的典型数据集,是结构化关系数据的一个示例:行中的观察值、列中的特性以及通过主键和外键连接在一起的表:客户 id。

查找历史标签

使预测工程适应不同问题的关键是遵循从数据集中提取训练标签的可重复过程。概括来说,这一点概括如下:

  1. 根据关键业务参数定义正面和负面标签
  2. 搜索过去的数据,寻找正面和负面的例子
  3. 制作一个截止时间表,并将每个截止时间与一个标签相关联

对于客户流失,参数是

  • 预测日期(截止时间):我们做出预测的时间点,也是我们停止使用数据为标签制作特征的时间点
  • 用户被视为流失前没有订阅的天数
  • 提前期:我们希望预测的未来天数或月数
  • 预测窗口:我们想要预测的时间段

下图显示了每一个概念,同时用我们将要研究的问题定义来填充细节。

Parameters defining the customer churn prediction problem.

在这种情况下,客户在一月份已经有 30 多天没有订阅了。因为我们的提前期是一个月,预测窗口也是一个月,所以流失的标签与 12 月 1 日的截止时间相关联。对于这个问题,我们因此教导我们的模型提前一个月预测客户流失*,以给客户满意度团队足够的时间与客户接触。*

对于一个给定的数据集,我们可以从中做出无数的预测问题。我们可能希望预测不同日期或频率的流失,例如每两周一次,提前两个月,或者将流失定义为没有活动成员的较短持续时间。此外,我们可以用这个数据集解决其他与流失无关的问题:预测客户下个月会听多少首歌;预测客户群的增长率;或者,根据聆听习惯将客户划分为不同的群体,以定制更加个性化的体验。

当我们开发用于创建标签的函数时,我们将输入作为参数,这样我们就可以从数据集中快速生成多组标签。

如果我们开发一个拥有参数而不是硬编码值的管道,我们可以很快地采用它来解决不同的问题。当我们想要改变客户流失的定义时,我们需要做的就是改变管道的参数输入并重新运行它。

标签实施

为了制作标签,我们开发了 2 个功能(全部代码在笔记本中):

label_customer(customer_transactions, prediction_date = "first of month", days_to_churn = 31, lead_time = "1 month", prediction_window = "1 month") make_labels(all_transactions, prediction_date = "first of month", days_to_churn = 31, lead_time = "1 month", prediction_window = "1 month")

label_customer函数接收客户的交易和指定的参数,并返回一个标签时间表。该表包含一组预测时间(截止时间)和对应于单个客户的每个截止时间的预测窗口中的标签。

例如,我们的客户标签如下所示:

Label times for one customer.

然后,make_labels函数接收所有客户的交易和参数,并返回一个表,其中包含每个客户的截止时间和标签。

后续步骤

当正确实现时,预测工程的最终结果是一个可以通过改变输入参数为多个预测问题创建标签时间的函数。这些标注时间(截止时间和关联标注)是下一阶段的输入,在该阶段中,我们为每个标注创建要素。本系列的下一篇文章描述了特征工程如何工作。

结论

我们还没有发明预测工程的过程,只是给它起了个名字,并为管道中的第一部分定义了一个可重用的方法。

预测工程的过程分为三个步骤:

  1. 确定可以用可用数据解决的业务需求
  2. 将业务需求转化为有监督的机器学习问题
  3. 根据历史数据创建标注时间

获得正确的预测工程至关重要,需要业务和数据科学两方面的投入。通过编写预测工程的代码来接受不同的参数,如果我们公司的需求发生变化,我们可以快速地改变预测问题。

更一般地说,我们解决机器学习问题的方法在标准化每个输入和输出的同时,将流水线的不同部分分段。正如我们将看到的,最终结果是我们可以在预测工程阶段快速改变预测问题,而不需要重写后续步骤。在本文中,我们已经开发了一个框架的第一步,该框架可用于解决机器学习的许多问题。

如果构建有意义的、高性能的预测模型是你所关心的事情,那么请通过功能实验室与我们联系。虽然这个项目是用开源的 Featuretools 完成的,但商业产品为创建机器学习解决方案提供了额外的工具和支持。

自动驾驶汽车中的预测——你需要知道的一切

原文:https://towardsdatascience.com/prediction-in-autonomous-vehicle-all-you-need-to-know-d8811795fcdc?source=collection_archive---------7-----------------------

想象一个场景,你在一条双车道的路上驾驶一辆车,向前行驶,你想右转,但是第二车道上有一辆车从相反的方向驶来,现在你会怎么做?

自动驾驶汽车的预测是关于我们的自动驾驶汽车如何预测另一辆汽车的轨迹或路径,并采取行动避免碰撞。

我是 Udacity 自动驾驶汽车纳米学位项目的第三期学生,在这里我将分享我在预测方面的知识,这是自动驾驶汽车轨迹规划的一个重要部分。

这是怎么做到的?

预测的输入来自传感器融合和定位。传感器融合就是结合来自多个传感器(如雷达、激光雷达等)的数据(使用卡尔曼滤波器)。)让我们的汽车了解它的环境,而汽车使用定位来精确地知道它在哪里。

一旦我们有了输入,就可以通过以下方法来预测车辆的轨迹:

1.基于模型的方法

2.数据驱动方法

这些方法可以单独使用,也可以混合使用,以做出更好的预测。

让我们一次看一种方法

1。基于模型的方法:

这种方法识别车辆的常见行为(变道、左转、右转、确定最大转弯速度等。) .

在这种方法中,我们为车辆可能行驶的每个可能轨迹创建一个模型,并将其与汽车的行为一起发送给多模态估计算法 (现在假设它是一个黑盒)。该算法将概率分配给轨迹模型,最终选择概率最高的模型。

Modal Based Approach

在我们深入研究基于模型的方法之前,让我们先来看看 Frenet 坐标系。

弗雷诺坐标系

在 FCS 中,我们使用s’d’符号来确定物体的位置,其中s’是道路上的距离,而 d 确定距离车道中心的距离,这与我们使用 x,y 坐标来表示道路上的位置的笛卡尔坐标系不同。FCS 是表示道路上物体位置的更好的方法,因为使用笛卡尔坐标实现曲线道路的方程会困难得多。

基于模型的方法中使用的步骤:

Steps used in Model Based Approach

*第一步:*确定汽车的共同行为

步骤 2: 为每个被识别的行为创建过程模型

*第三步:*计算每个过程模型的概率

让我们通过一个简单的例子来理解每个步骤:

Image Source: Udacity Nano Degree Program

假设我们的自动驾驶汽车(绿色汽车)必须在高速公路上行驶。为此,它必须预测蓝色汽车的行为。

第一步:

蓝色汽车的行为如下:

  • 它会忽略我们
  • 它会减速,让我们的车先行,这是一个礼貌的司机
  • 它会加速并超过我们的车
  • 它会变道并以同样的速度继续行驶

等等..

我们必须用数学描述来描述这些行为。为此,我们将转到步骤 2。

第二步:

过程模型为确定的行为提供了数学描述。

这些模型的复杂程度可以从非常简单的数学描述到非常复杂的数学描述不等

  • 请注意,流程模型数量取决于所识别行为的数量。它可能随着行为的数量而变化。

预测状态 x 在时间 k 的过程模型的一般状态形式如下:

state vector

第三步:

在这一步中,我们将通过为每个行为创建的流程模型分配概率,来确定汽车中的驾驶员将执行什么操作。这是通过多模态估计算法完成的。该算法最简单的方法是自主多模态(AMM)算法。

自主多模态(AMM)算法。

在 AMM,我们首先观察车辆在时间 k-1 和时间 k 的状态

然后,我们计算 k-1 时刻的流程模型,并得到 k 时刻的预期状态。

然后将比较期望状态和观察状态的可能性。并使用以下公式获得模型在时间 k 的概率:

模型(I)在时间 k 的概率

其中:

M: 多个不同的流程模型

U: 模型的概率。

L: 模型的观测的可能性

k: 时间戳

最后选择概率最高的模型。

2。数据驱动方法

在数据驱动方法中,我们将采用一个黑盒,并使用大量训练数据对其进行训练。一旦它得到训练,我们将符合观察到的行为,并得到预测。

这有助于确定车辆的具体模式,否则可能会被遗漏。

数据驱动方法分两个阶段完成:

  1. 离线培训(模型培训)
  2. 在线预测(使用模型预测轨迹)

Data Based Approach

离线培训

数据驱动方法中使用的步骤:

*第一步:*获取大量轨迹数据

*第二步:*清除数据

步骤 3: 选择一个度量来执行相似性

步骤 4: 使用机器学习算法执行轨迹的无监督聚类,如谱聚类凝聚聚类

步骤 5 :为每个集群定义一个轨迹模式

按照这些步骤,我们将得到模式和轨迹群

在线预测

步骤 1: 观察车辆局部轨迹

第二步:将它与原型轨迹进行比较

*第三步:*预测轨迹

重复在线预测步骤,直到我们找到原型轨迹之一与车辆轨迹相似的最大可能性。

所以到现在为止,你们一定对预测轨迹的两种不同方法有很好的理解。

混合方法

所以现在的问题是使用哪种方法..?

为什么不利用这两种方法的优点呢?这就是混合方法发挥作用的地方。:)

Hybrid Approach

为了实现混合方法,我们将用机器学习代替基于运动的方法的多重运动估计器。为此,我们需要一个分类器。一个这样的分类器是朴素贝叶斯分类器

朴素贝叶斯分类器:

处理连续数据时的一个典型假设是,与每个类相关联的连续值按照高斯分布分布。

例如,假设训练数据包含一个连续属性 x。我们首先按类对该数据进行分段,然后计算每个类的平均值和标准偏差。假设我们有类的第 k 段,即 x 的 C_k,u_k 是平均值,_ square _ k 是标准偏差,那么给定一个类 C_k,v 的概率分布可以通过将 v 代入方程来计算

这就是我们需要知道的关于我们的自动驾驶车辆如何预测其他车辆的轨迹。请记住,在这篇博客中,我们已经通过一次一个对象的方式介绍了预测,而在现实世界的场景中,可能会有许多对象必须同时进行预测,这使得预测过程更加复杂。幸运的是,我们到目前为止所学的知识可以很好地预测公路上车辆的轨迹。

你可以通过阅读这篇关于 T2 多模型算法的论文来了解更多关于预测的知识,作者是 T4 的瑞安·r·皮特里·维斯林·p·吉尔科夫·x·李蓉。

如有任何疑问,请通过 LinkedIn联系我或写下私人笔记。

预测分析、区块链、大数据人工智能和机器学习是塑造新商业世界的技术。

原文:https://towardsdatascience.com/predictive-analytics-blockchain-big-data-ai-and-machine-learning-are-the-technologies-shaping-the-41b2069a70af?source=collection_archive---------1-----------------------

世界开展业务的方式正在快速变化,世界已经从传统的广告、营销和销售时代跃升到几乎每个数字数据都具有强大媒体元素的时代,包括枯燥的办公生产力工具。今天最重要的成分是数据,而在谁控制了世界上大多数数据的竞赛中,GAFAs(谷歌、亚马逊、脸书和苹果)及其同类似乎已经获胜。与此同时,关于谁将最大限度地利用世界以惊人的速度产生的庞大数据,仍存在一场巨大的权力斗争。在目前的情况下,比拥有这些数据更重要的是能够释放这些数据的潜力。实时数据分析甚至可以预测未来的结果和趋势,即使只有几分钟的时间,也可能是一个与众不同的因素,这是大多数企业正在运营和将要运营的方式。

目前,不同类型的企业使用预测分析,如金融服务,这是他们的主要生命力。电子商务商店和在线视频流媒体服务等其他业务已经享受到了预测分析的甜蜜力量。
预测分析是一种现代营销工具。如果不能从大量数据中翻译出重要的意义,预测就会变得困难。

有趣的是,许多软件公司开始想出有趣的方法来让这些技术变得有趣,让它们变得非常互动和用户友好,这正在改变我们销售、做生意甚至塑造品牌的方式。

大数据技术是与拥有无限数据集和信息的大多数企业相关的新现象。数据可以很容易地生成,当事情进展顺利时,它们可以以量子速率增长,如果组织不当,很快就会变得一团糟。然而,由于数据增长,有趣而美丽的解决方案不断涌现,迫使科学家们提出更出色的算法;企业家更具突破性的解决方案。随着数据创建和消费的增长,这只能表明未来会有更多的数据演变。

区块链是支撑比特币的底层技术。最近,它已经分别成为网络安全、IOT、数字总账和其他数据技术的前沿。大量的研究和投资投入到区块链技术的发展中,因为它提供了巨大的潜力和无数的应用。好消息是,区块链距离成为大规模营销工具还有几年时间。许多人也认为区块链是自互联网发明以来最重要的技术突破,在未来几年,它将成为许多企业的重要组成部分。

人工智能和机器学习听起来相当超前和怪异,但它是所有看到机器人如何以病毒方式接管网络空间的人中最友好的。这项技术的威力毋庸置疑。人工智能正在获得实际应用,并变得与日常生活活动密不可分,在银行、卫生、交通国防等几乎所有部门都有关联。随着各种各样几乎无穷无尽的人工智能应用的出现,我们无疑正处于自动化世界的黎明。

因此,无论是区块链、大数据、预测分析、人工智能还是机器学习,这些技术都有如此多的共同点,因为它们都依赖于其他技术来获得有效的解决方案。对于大多数人来说,当你听到这些术语时,脑海中浮现的是机器人或先进技术,“是的,它们非常先进”,但应该浮现的是这项技术在所有商业领域的变革力量,如营销、销售、客户服务、增长黑客等。鉴于人工智能对人类的明显好处,我们必须考虑人工智能的任何解决方案。从最近的趋势来看,很容易理解为什么人类会因为方便而更多地与采用 AI 解决方案的企业互动。

商业竞争越来越激烈,技术含量越来越高,因此新一代的销售人员能够借助技术进行有效的销售。

对未来的模糊看法胜过完全的黑暗。既然几乎所有的电子设备都变得智能了,为什么企业不能呢?我对智能企业的定义是能够提供智能服务,这可以转化为指数增长。

营销预测分析:它能做什么,为什么你应该使用它

原文:https://towardsdatascience.com/predictive-analytics-for-marketing-what-it-can-do-and-why-you-should-be-using-it-afdbde131b36?source=collection_archive---------6-----------------------

Photo by Jamie Templeton on Unsplash

预测智能并不新鲜。事实上,几年来,企业已经使用先进的分析工具来检测欺诈、评估风险,甚至预测飞机的维护需求,以减少航班延误。

然而,理解预测分析的结果并将数据转化为洞察力并不总是容易的,通常需要高级技能。由于有限的计算能力和难以访问的复杂软件,预测技术从未成为主流营销策略。

直到现在。

今天,人工智能驱动的(AI 驱动的)营销工具——聊天机器人、内容策展人、动态定价模型等。—易于访问且价格合理,为更多企业创造了从世界一流的分析中获益的机会,即使是在预算有限的情况下。

强大、先进、预测性的分析是“时尚”,精明的营销人员不仅回顾数字,还展望未来。让我们探讨一下营销预测分析——它是什么,它能做什么,以及为什么您应该使用它。

什么是营销预测分析?

根据 SAS 的说法,预测分析是“基于历史数据,使用数据、统计算法和机器学习技术来识别未来结果的可能性。我们的目标是超越对已经发生的事情的了解,提供对未来将会发生的事情的最佳评估。”

Salesforce 解释了营销联系:“预测营销使用数据科学来准确预测哪些营销行动和策略最有可能成功。简而言之,预测智能推动营销决策。”

听起来不错。那么,预测分析如何为您的营销决策增加更多洞察力和清晰度呢?

大数据分析如何帮助企业实现价值?

着眼于未来的企业意识到,他们想知道的不仅仅是过去发生的事情;他们想用他们的数据来预测未来。预测分析通过帮助您更好地了解关系以做出更明智的决策,使您已经拥有的当前和历史数据更有价值。

如今,“91%的顶级营销人员要么完全致力于,要么已经在实施预测营销。”这是他们正在做的。

他们更准确地预测客户行为。 对于营销人员来说,客户情报就是游戏的名字。你越了解你的客户——他们想要什么,他们什么时候想要,如何想要——就越容易在正确的时间通过正确的渠道向他们传达正确的信息。

使用由机器学习和人工智能指导的预测技术,预测建模通过识别数据中变量之间的模式和相似性来帮助评估未来的客户行为。例如,回归分析确定客户过去购买行为之间的相关性,以确定未来购买的可能性。

预测模型还可以帮助你根除有可能失去的不满意客户,以及识别可能准备购买的兴奋客户。通过预测模型运行客户数据可以帮助您更好地预测行为,从而更好地制定营销策略。

他们正在识别并优先考虑合格的销售线索。 不合格的潜在客户——那些没有购买意愿的客户——最终会耗费公司的时间和金钱。借助预测分析,一种算法可以根据已知潜在客户和客户采取行动的可能性对其进行优先排序,从而帮助确定潜在客户。识别模型发现与现有买家有相似之处的潜在客户,最大化新销售的机会。

更好的是,来自预测分析的见解可以帮助您的销售团队专注于培养您最有利可图的客户。找到最有潜力的潜在客户,你就能给你的销售团队提供有价值的见解,让他们知道下一个该和谁谈,哪些潜在客户最有可能达成交易。

如果您的企业资金有限,预测分析是一个强大的工具,有助于确保在正确的时间使用正确的资源,同时预测最有可能购买的高价值客户,以优化营销支出。

他们正在钉个性化的消息。 个性化事项。然而,当涉及到为客户提供定制信息时,品牌却举步维艰。要么他们没有准确的数据,要么他们没有足够的数据,要么他们就是不能足够快地获得洞察力。

对其他人来说,个性化做得好的回报是超出预期的非凡客户体验。然而,个性化的手动方法是不可持续的,企业正在转向机器学习和预测技术作为下一个逻辑步骤。

预测分析推动个性化信息的自动细分,这意味着您可以在追加销售、交叉销售或推荐产品时更好地瞄准特定群体或个人,以独特的实时共鸣信息接触客户。

为什么预测分析对您很重要?

今天,数据是新的石油,企业正在“在存储和基础设施上的支出估计为 360 亿美元”——这一数字预计到 2020 年将翻一番。随着更多的数据、改进的计算能力和对供应商工具的轻松访问,用于营销的预测分析不仅是智能的,而且是业务的必要条件!

预测模型可以根据过去的营销活动预测营销绩效,发现改进的机会,以便您可以更好地了解客户的行为,提供更有意义的内容,并创建令人惊叹的定制体验。

好消息是什么?部署预测分析解决方案既不复杂,也不需要单独在内部完成。事实上,无论是大公司还是小公司,都有大量令人惊叹的解决方案可供选择——甚至对于在分析方面缺乏成熟度的企业也是如此。

Blue Fountain Media 的业务开发副总裁 Brian Byer 有一些的至理名言要与大家分享:“使用正确的工具,使您能够利用数据……比试图将解决方案逆向工程到传统技术堆栈中要容易得多。计划取得成功,这将使整合预测分析和其他新技术变得更加容易。”

总之

随着技术格局的快速变化,成功的公司将使他们的团队能够使用技术优先的解决方案来更好地服务于他们的客户。他们将采用新工具,在采用新技术时避免分析瘫痪,并将变化作为新的机遇进行规划。敏捷商业方法着眼于未来,是 2019 年及以后取得成功的必备条件。

准确而及时的商业智能将是未来的一大优势。虽然使用预测分析的原因有很多,但最有说服力的也是最简单的:超越学习发生了什么及其原因,发现对未来的见解,你今天就能更好地服务于你的客户。

基于机器学习的制造业预测性和规范性维护

原文:https://towardsdatascience.com/predictive-and-prescriptive-maintenance-for-manufacturing-industry-with-machine-learning-2078afa76bfb?source=collection_archive---------7-----------------------

利用机器学习监控机器健康状况并优化制造产量

作者:帕萨·德卡和罗希特·米塔尔

今天的人工智能(AI)趋势和制造业自动化水平的提高允许企业通过数据驱动的见解灵活地连接资产和提高生产率,这在以前是不可能的。随着制造业越来越多地采用自动化,处理维护问题所需的响应速度将会越来越快,从经济角度来看什么是最佳选择的自动化决策也变得越来越复杂。

规定性维护:

规范维护是一种范式转变,它促进从严格依赖计划事件转向能够从实际事件中采取实时行动。规范维护利用高级软件来确定识别点,以明确诊断根本原因问题,然后指示精确而及时的措施,以便及时改变结果。工业企业正在使用规定的维护和分析软件来减少或消除计划外停机时间,并最大限度地提高盈利能力和设备可靠性。人工智能支持的说明性维护的独特之处在于,它不仅仅预测即将发生的故障,而是努力通过分析产生以结果为中心的运营和维护建议。

提高生产力:

生产率是制造商追求的三个基本要素之一,另外两个是成本和质量。今天,估计有价值 5000 亿美元的机床在帮助企业管理他们的工业设备。然而,现代公司正在寻求超越预防性维护,以实现规范的维护系统。例如,减少停机时间对于工业设备和机器来说非常重要,有助于提高生产率和设备的整体运行效率。OEE 黄金标准仅为 80%左右。事实证明,如果没有人工或成本高昂的流程,很难超越这些效率水平。

数字核心:

实施规定维护和分析的一个关键方面是纳入下一代数字核心技术,包括人工智能、机器学习、物联网连接、协作和高级分析。这些工具必须灵活、可扩展,并且易于集成到遗留的 IT 基础设施中。它们允许组织将来自后台系统的业务流程和事务数据与来自各种来源的大量结构化和非结构化数据集成在一起。然后,高级分析可以跨数字核心及时嵌入数据,使组织能够获得新的见解,如预测结果或提出新的行动。

工业化人工智能:

人工智能元素需要在确定的基础上嵌入并同步到整个数字核心的数据中,使公司能够获得新的见解,例如预测结果和自动采取行动以确保优化结果。

高级分析:

AI/ML 系统是规定维护平台的大脑。生产机器的 ML 模型被设计用来检测生产过程中的异常行为。训练数据有助于为单个配方步骤或特定设备类型开发特定模型。通过在一些连续的基础上确定数据点是否落在这些界限之外,及时的检测和规定被完成,它被标记为异常并被报告。培训新模型和按需部署的能力是关键。通过这样做,模型能够随着时间的推移不断学习和适应

虚拟协作:

大量数据的可视化对于支持管理分析和快速决策至关重要,以便进行持续监控和说明性维护和分析。可视化工具必须综合多维的、通常是融合的数据和信息,以便支持评估、规划和预测。该工具需要是开放的、动态的、实时的,并对所有参与者可用,以便能够与所有参与者协作,在不同的抽象和网络连接级别访问数据。

案例分析

为了保持我们工作的机密性,我们在下面呈现一个抽象的用例:

问题陈述:

我们的组件制造经历了多个连续的步骤。我们的制造组件由多个移动部件组成,最显著的是运动平台和致动器。最难以捉摸的产量问题之一是随着时间的推移随机发生的间歇性电机故障。就时间、频率、组件、配方等而言,故障发生没有可识别的一致性。它们只是随机出现。关闭设备进行铁测试,直到人们能够幸运地捕捉到现场故障事件,这通常非常耗时,并对我们工厂的生产能力产生负面影响。另一方面,如果设备保持在线,则继续间歇性地制造故障产品,浪费下游工厂产能、耗材、劳动力和高额收入损失。我们以前依赖基于条件的手动监控解决方案和预防性维护计划,这限制了我们提高产量和生产率的能力。预测性和说明性维护最近已在重型制造业中采用。例如用于燃气轮机、真空泵、飞机发动机等的预测性维护。这些预测性维护解决方案在本质上是高度定制的,基于机器及其操作、领域等。此外,这些情况下使用的传感器适用于大型和重型机器,并针对大幅度的速度、加速度、旋转和倾斜进行调整。与重型机械行业的流程相比,我们的制造流程非常不同。不仅我们的制造领域和流程不同,而且数据采集的传感器要求也不同。在我们的组件制造中使用的电机尺寸小,它们的运动范围更短,不那么突然,以便处理精密和小型光学组件。目前可用的现成 IOT 传感器(用于重型制造业的运动检测)不适合我们的组件制造,因为它们体积太大,无法安装,或者不够精确和灵敏。例如,导致过度振动的运动可能会导致现有传感器无法检测到微小部件的未对准。

我们的解决方案:

我们通过广泛的解决方案需求文档提出了解决方案,详细说明了技术设计规格,如性能、可扩展性、模块化、安全性、高可用性、连接性、灵活的应用程序编程接口、CPU/内存/网络/硬盘使用规格、互操作性、可配置性、可靠性、可用性、延迟、ML / AI 算法、数据库性能、可视化、可扩展性、传感器要求。

例如:

我们与一家供应商合作,该供应商拥有满足我们所有解决方案设计规格的专业知识。通过与供应商合作,我们开发了一个预测性维护框架,该框架利用定制的机器学习技术、软件工程原理以及基于外形、功率和通信协议等选择的适当传感器。对我们的组件制造更加精确。总的来说,预测性维护框架能够执行实时检测、可视化、警报创建以及针对我们制造流程不同阶段的修复建议。这种独特的系统还使用最先进的机器学习技术和软件工程原理来抢先和自主地预测、检测、创建警报,并建议在组件制造过程中修复异常振动。该系统在制造过程的任何实际中断发生之前提醒个人并推荐修正估计。这使得我们能够对组件制造流程进行预测性和规范性的定期维护,减少突发和计划外的停机/中断,并优化我们的工厂产能、耗材、劳动力和成本。AI/ML 的平台集成是一个时间感知运行时系统和灵活的创作工具,可以更好地预测工艺和设备问题,并对我们的设备组件进行精确维护,避免突然和计划外的停机时间/避免间歇性故障制造,最大限度地减少收入损失。

我们实现的主要收益:

产量增加

提高工人生产力

减少计划外停机时间

优化盈利能力

快速实施

快速可扩展性

最大似然算法概述:

什么是异常检测:

异常检测是关于发现模式(如离群值、异常、异常等)。)偏离数据集内的预期行为,因此它可以类似于噪声去除或新奇检测。检测到异常的模式实际上是感兴趣的,噪声检测可能略有不同,因为噪声检测的唯一目的是去除那些噪声。与大多数数据科学项目一样,异常检测的最终目标不仅仅是算法或工作模型。相反,它是关于异常/异常值所提供的洞察力的价值,即防止设备损坏所节省的业务资金。在制造领域,我们希望在异常检测实际损坏设备之前,利用异常检测主动实现预测性和规范性维护。这将预警并实现“定期维护”,避免通常会导致严重收入损失的突然停机

有人监督与无人监督:

有两种用于构建异常检测系统的主要架构:

监督异常检测—如果我们已经标记了数据集,并且知道每个数据点是否正常,就可以使用监督异常检测

无监督异常检测—数据集未标记,即每个数据点是否异常不可靠或未知

我们的 ML 管道:

我们最先进的 ML 软件框架从战略性地放置在我们制造装配各部分的传感器中执行实时传感器数据采集。所有这些都是实时的,我们的软件框架从采集的传感器信号中执行统计特征提取,导出主成分,并使用监督和非监督学习技术检测异常聚类(数据点),对传感器信号以及置信区间保护带执行时序抢先预测,并检测极端振动。以下是一个概述:

检测各种聚类的样本无监督算法:

均值漂移聚类旨在发现数据点的平滑密度中的聚类。这是一种基于质心的算法;它首先将每个数据点视为一个聚类中心。根据所提供的带宽参数,每个数据点构建一个假想的感兴趣的球体。然后,它使用球体中数据点的平均值更新球体的质心,然后围绕新平均值(新质心)构建新的感兴趣球体,然后再次使用该区域中数据点的平均值更新质心。这个过程反复进行,直到它收敛,直到质心不再移动。随后是过滤后处理阶段,以消除近似重复,从而形成最终的质心集。球体中汇聚到同一个质心的数据点被视为同一个聚类的成员

每种技术的最佳聚类数是通过优化轮廓系数来实现的。使用每个样本的平均组内距离(a)和平均最近组距离(b)计算轮廓系数。样本的轮廓系数为(b — a) / max (a,b)。为了澄清,b 是样本和该样本不属于的最近聚类之间的距离。最好的值是 1,最差的值是-1。接近 0 的值表示重叠的簇。负值通常表示样本被分配到错误的聚类,因为不同的聚类更相似

下图中,均值漂移聚类检测到我们的一个制造装配组件的各种振动阶段:

我们的软件架构:

我们有一个灵活的软件架构,可在边缘提供全部功能,并根据数据/ ML 计算需求等按需切换到基于混合边缘云的架构。我们的框架还提供了一个灵活的 API 来根据需要更新我们的 ML 模型。以下是我们的示例高级软件架构与树莓馅饼边缘计算机。我们利用了开放技术,如 MQTT(基于实时订阅的消息协议)、Influx db(用于实时分析的开源时间序列数据库)和 Grafana(用于实时可视化)

由于从实时数据处理到最大似然训练/预测的各种计算限制,我们采用了一种灵活的软件架构,可以无缝切换到混合形式。Edge-cloud 框架在滚动窗口中将数据持续归档到云中的历史归档数据库中,例如,在云数据库中维护到当前日期为止一周或一个月的历史数据,要归档的数据量可以根据使用情况而变化。该框架具有基于规则的模型健康监控系统,该系统定期(以及按需)检查 ML 模型的性能统计数据——性能统计数据可以基于但不限于用例的性质、ML 算法的性质等而变化。如果模型性能统计低于阈值(例如 f1 分数、受监督学习者的 R 平方、无监督学习者的轮廓系数等。这可以基于用例、算法等而变化。),一旦满足阈值标准,该框架触发 ML 训练管道(在线)并部署新训练的模型。以下是我们的混合架构示例:

规定性维护实时可视化平台:

我们构建了一个最先进、易于使用的智能监控平台,用于规范维护。操作人员可以监控异常情况,深入分析根本原因,并接收智能建议,以实时修复制造过程中的故障情况。基于 ML 的智能建议基于异常行为、传感器位置、传感器数据、发生时间、设备类型/属性等。有了这个平台,操作员还可以轻松查看和监控 CPU、内存、网络使用情况等。在各种制造装配服务器上。我们的可视化平台还提供自定义日期范围的回看选项。基于需求并使用回顾选项,模型健康监控系统可以指示异常检测算法在云中使用存档的历史来重新训练自身,以更好地预测未来。

总结&结论:

我们开发了一个基于机器学习的端到端可扩展、安全、模块化、可扩展、可互操作、可配置的规范维护平台。借助该平台,我们实现了组件制造流程产量的大幅提升。我们积极主动地检测故障,为我们的组件制造装配提出修复建议,从而大幅减少计划外停机时间和工厂产能、耗材、劳动力和运营成本。异常检测科学是不断变化的。我们的平台提供的灵活的 ML API 使我们能够根据需要更新我们的异常检测算法。

参考文献:

http://mqtt.org/

【https://www.influxdata.com/

https://grafana.com/

http://ranger.uta.edu/~chqding/papers/KmeansPCA1.pdf

https://scikit-learn.org/stable/

预测性员工流动分析第一部分

原文:https://towardsdatascience.com/predictive-employee-turnover-analytics-b3d89526a06c?source=collection_archive---------0-----------------------

Kaggle 上有一个名为人力资源分析的新数据集。(【https://www.kaggle.com/ludobenistant/hr-analytics)这可能是一个探索不同机器学习工具的好机会,看看它们在预测二元变量的能力方面有何不同。更重要的是,这是一个公司迟早会遇到的真实情况。把它作为一个真实的商业分析案例会很有见地。在 Tableau 的帮助下,很容易快速而深入地查看数据集,它可以进一步帮助我决定在以后的学习中使用哪些机器学习工具。第一次做,从机器学习开始,到 Tableau 结束。然而,理想的过程是以非常直接和直观的方式查看原始数据。所以我真的应该从 Tableau 开始,然后去统计。

对数据的快速浏览

好的,我们开始吧。整个数据集包含 14999 行和 10 列。“左”列是我们知道雇员是否已经离开的地方。除“销售”之外的所有其他栏目都直接或间接与员工的选择有关。从“销售”我们知道一个雇员属于哪个部门。

A first look at the data

我选择计算他们的相关矩阵作为第一步。在 R 和 Excel 中很容易做到这一点,这给人一种它们之间如何相互关联第一印象。因为我知道它们实际上是相互关联的,所以将它们全部包含在分析中是安全的。

Correlation matrix

用黄色突出显示的行包含与响应相关联的相关性。尽管一些数字非常小,低至 0.006567,但在统计上仍然是显著的。我将在这里省略卡方检验。下一步我会去 Tableau 看看故事背后有没有商业本能。

谁要离开公司?

Fraction of leaving in each department

这张图表让观众大致了解了这家公司的情况以及营业额的来源。深蓝色部分代表周转率,用数字记为 1,否则记为 0。总更替率为 0.238,各部门之间的比率与整体比率非常接近。销售、技术和支持是三个最大的部门,大部分人员流动都发生在那里。

主观感受和客观表现如何决定选择

我们将研究个人满意度和员工评价如何影响离职选择。

x 轴表示满意度,y 轴表示绩效。灰色圆点代表较小的周转率,红色越多,周转率越高。请注意,在此图中有三个红色的主要集群。第一个在左上角。它包含高绩效和不太满意的人。广义来说,满意度低于 0.11 的人离职的可能性很大。还要注意,当满意度低于 0.11 时,很少有人工作出色。这一群人在我的警报系统中被标记为“极有可能离开”,HR 可以用它来识别那些考虑明天不再回来的人。第二个星团在中部偏左的某个地方。他们的满意度介于 0.36 和 0.46 之间,评价介于 0.45 和 0.57 之间。很难找到一个理由来证明他们的动机。他们似乎无法与他们的邻居区分开来。另一件要注意的事情是,这个区域的点变得非常密集。这个问题需要进一步调查,因为我不知道它为什么会发生。从数据中得到的唯一线索是,这里的点变得更密集,但在它右边延伸到右上角的另一个更密集的部分没有显示出类似的模式。在这个大而密集的区域,有一个部分比它的周围有更高的周转概率。为什么即使他们对工作非常满意,他们也很努力,但他们还是想离开?尽管他们不像右边的人那样“完全”满意,但他们也不像左边的人。他们当然表现得很好,但是这个事实如何让他们的离开成真呢?也许这两个指标并不能完美地解释失误者的行为。我可能忽略了一个更大的画面。另一个要问的问题是为什么要有集群?我可以理解低满意度产生了离开的动力。但是当有一群人不如一个人满足和努力的时候,为什么他更倾向于离开?这不是一个容易回答的问题,所以我将把它留在这里。我会试着去不同的部门看看,以便对公司有更详细的了解。由于与上面的整体图相似的图表显示了不同的部门,我将只显示人力资源部门。

上图在很大程度上复制了这一模式。令人惊讶的是,在不同的部门,人们至少在离职方面有着相似的动机。有没有可能 it 或技术部门比销售和管理部门更喜欢久坐,因此他们的心态和看待彼此的方式会有所不同?数据没有告诉我们这一点。既然这是模拟数据,也许本身就有偏差。或者,可能有一些东西长期以来对人们隐藏着。使用数据的目的实际上是让我们能够发现未被充分重视的秘密。

工资和工作量如何影响选择

工作并获得报酬。这是一枚硬币的两面。是时候从这个角度看了。

由圆圈组成的三个长图形包含从低到高的工资信息。在每个图形上,绿色圆圈越多,换手率越高,圆圈越大,总换手率越高。每个圆圈代表一群每月工作相同时间的人。

首先,我们将讨论公司层面。每幅图都有两个讨论,一个是关于营业额的可能性,另一个是关于营业额的数量。

可能性。在低工资水平上,处于两端的人很可能会离开,这意味着工作过度或工作不足、收入微薄的人辞职的频率更高。在极端情况下,当人们疯狂地长时间工作(超过 290 小时/月)时,离职率可以达到 100%。当工资提高到中等水平时,同一批人也更倾向于离开。但这一次,与收入较低的同行相比,收入较低的人不太可能离开。然而,有一点需要注意,那些仍然长时间疯狂工作的人几乎肯定会离开公司。随着薪水越来越高,辞职的人越来越少,但还是可以看到同样的模式。

。收入较低的人有助于提高员工流动率,部分原因是薪资结构应该像金字塔一样。

接下来我会下到部门级别。会计是第一个上来的。

这张图看起来很“绿色”,与公司图不同。只要有人离开,这个圈子的可能性就很大。中等收入的人辞职很多,而且几乎可以肯定。然后是 HR 部门。

另一个“绿色”和独特的图形。然后就来了。

一个更加丰富多彩但仍然不同的画面。在低工资水平下,只要员工工作不到一定的时间,就有可能辞职。但是当那个人挣得更多的时候,除非他/她疯狂地过度工作或者无所事事,辞职是不可能发生的。接下来是管理。

描述正在发生的事情是一件容易的事情,但是请注意不同之处。下一步,我想展示三张图来展示数据分析的一个非常重要和普遍的部分。

这三个部分依次是销售、支持和技术。它们看起来与上面的图表非常不同,但与公司级图表相似。这解释了为什么上面的图看起来不同,它们受到这三个的影响。请记住,在开始时我说过这三个部门是公司中最大的三个部门,当然它们在很大程度上决定了公司级图表的外观。如果我不深入研究,这个部门特有的模式将永远不会被发掘出来。数据分析器永远不会遗漏细节。

接下来的部分将集中讨论晋升如何影响离职的选择。首先是图表:

不辞职的决定与高达 2.6%的晋升可能性有关,而明显辞职的那组人的晋升可能性不到 0.6%。使用统计数据,我可以告诉如果保证金是显着的,我不会在这里这样做。上图只显示了相关关系,而不是因果关系。我没有忘记在部门一级做我的研究,但我不会在这里展示它。IT 和营销在这方面有很大的不同。

我也研究过工伤事故在这里扮演的角色,但我不会在本文中说明,因为它可以比作晋升。

使用 Tableau 进行了大量的预先研究,以找出营业额数据中隐藏的秘密。就我个人而言,我学到了很多关于如何使用 Tableau 的知识,至少在两个方面,它确实不同于简单地使用统计数据来做研究。第一,当我经常分解数据集时,Tableau 功能更强大,使用起来更快捷。很容易立即切换、添加、更改内容。第二,Tableau 以一种耸人听闻的方式将数据与我联系起来。有时候看起来挺可爱的。

在接下来的第二部分,我将使用 logit 回归,KNN 和决策树来建立一个更科学的设置,我应该如何看待数据。

具有人工智能和决策优化的预测性维修计划

原文:https://towardsdatascience.com/predictive-maintenance-scheduling-with-ibm-data-science-experience-and-decision-optimization-25bc5f1b1b99?source=collection_archive---------4-----------------------

如何通过在准确的时间安排维护来保持您的资产健康并降低维修成本

Photo by Jacek Dylag on Unsplash

什么是预测性维护?

计划外维护是许多资产密集型行业(如制造业、石油和天然气业以及运输业)的一个关键问题。由于长时间的生产停工期,成本可能非常高。它们不仅导致高度紧急的维修和新机器和零件的投资,而且意外的生产损失可能影响供应商的义务并迫使公司从其竞争对手那里购买产品,从而导致巨大的意外成本。根据 Automation.com(2016),每年因计划外维修造成的损失高达 200 亿美元。

预测性维护使用预测性分析和机器学习(ML)来确定机器的寿命以及机器在某一天发生故障的可能性。其理念是在设备出现故障之前,而不是在实际需要之前,利用这些信息来安排维护,从而避免与维修和生产损失相关的不必要成本(图 1)。根据行业的不同,资产的类型可以有所不同,从汽车和卡车到风力涡轮机、起重机和石油平台。

Figure 1: Predicting likelihood of failure helps determine the optimal time for machine maintenance

值得注意的是,与预防性维护相比,预测性维护具有真正的优势,预防性维护使用固定的更换和维修周期,通常基于供应商的规格。后者没有考虑机器的实际状态或机器运行的特定环境,例如生产水平或其他运行条件。因此,预防性维护通常是不准确的,并且由于修理计划太晚或太早而导致过高的成本。另一方面,预测性维护可以考虑历史数据,以便更准确地预测故障的可能性。

为什么预测故障是关键,但不足以解决维护计划的挑战?

机器学习模型可以考虑所有可用的信息,例如传感器数据、历史任务和订单、过去的故障历史和维护历史。因此,它可以根据每台机器的具体特征帮助确定最佳维护日(图 2)。

Figure 2: Predicting optimal maintenance day using ML (one machine at a time)

当我们一次考虑一台机器并且没有冲突优先级时,这种方法非常有效。然而,一旦我们开始引入一些复杂性、依赖性和有限的资源,确定最优的时间表就变得更加具有挑战性。例如,如果计划产量恰好在我们预测维护最佳的那一天达到最高(图 3),该怎么办?在这种情况下,提前一天安排维修可能会降低成本,因为这样我们可以避免高峰生产损失。

Figure 3: An “optimal” maintenance day may not be optimal if scheduled production numbers are high

更重要的是,我们如何处理有限的资源?如果我们的 ML 模型预测第 3 天是三台机器的最优维修日(图 4),但是只有两个维修组可用,我们该怎么办?

Figure 4: “Optimal” predicted maintenance day for each machine may not be feasible due to limited resources

决策优化有什么帮助(分三步)?

虽然机器学习可以考虑所有可用的数据和过去的历史来预测给定机器发生故障的可能性,但决策优化(DO)可以更进一步,生成一个对一组机器而言是最优的调度,该调度受到有限资源(例如,维护人员可用性)其他约束和依赖性(生产计划和维修成本)和优化指标(最小化总成本,最大化客户满意度/满足计划生产,最小化后期维护)它不仅为我们提供了有价值的见解,而且还生成了一个可操作的时间表或计划(图 5)。

Figure 5: Combining the Power of Machine Learning & Decision Optimization for Maintenance Scheduling

与任何业务解决方案一样,仅仅创建一个模型是不够的。我们的最终目标应该是在业务用户和决策者手中交付一个解决方案。无论使用什么技术都是如此,方法也是相似的。在这里,作为一个例子,我们概述了 IBM Cloud Pak for Data (CPD),即 IBM 数据和人工智能平台,如何用于构建预测性维护计划解决方案。关键步骤如下(图 6):

Figure 6: Decision Optimization application development and deployment using IBM Cloud Pak for Data

步骤 0 :收集所有需要的数据,包括机器和故障率的历史信息。构建并部署一个机器学习模型来预测某一天发生故障的可能性。在 IBM Cloud Pak for Data 中,这可以通过多种方式完成,包括使用 AutoAI 自动选择和调整最佳模型,使用 scikit-learn 等开源包的 Python 或 R 中的模型,或者使用 SPSS Modeler 的图形用户界面。一旦模型被训练、验证和测试,它就可以被部署为在线模型,使用 REST APIs 进行访问。剩下的步骤集中在实现和部署优化模型和 web 应用程序上:

  1. 建立一个 DO 模型来安排维护。在 IBM Cloud Pak for Data 中,这可以使用 CPLEX Python API 来完成。DO 模型的输入将包括 ML 模型的输出,即机器故障预测。
  2. 配置可视化仪表板并执行假设分析,即并排创建和比较不同的场景。在 IBM Cloud Pak for Data 中,这可以使用决策优化仪表盘轻松完成,在仪表盘中,您可以通过更改输入、重新运行模型和可视化输出来创建和比较不同的场景。准备好之后,与业务用户共享仪表板,以获得关于模型和场景演示的反馈。
  3. 一旦业务用户有机会查看仪表板和测试场景,就可以通过 REST API 将优化模型部署为可执行的在线模型。现在,您可以简单地构建和部署一个 web 应用程序(例如 Node.js ),或者在现有的应用程序中嵌入服务,并通过访问 ML 和 DO 在线模型来生成您的维护计划。

让我们更详细地看一下前三个步骤。

步骤 1:建模业务需求

决策优化模型的关键要素是优化指标、约束和决策变量。

优化指标定义了我们优化的目标(最小化/最大化)。在预测性维护的情况下,这些指标可以是以下任何一个或组合:

  • 最小化成本(维护、劳动力)
  • 最大限度减少后期维护
  • 最大化生产
  • 最大限度提高客户满意度

优化模型需要考虑许多约束条件,包括:

  • 机器故障的预测可能性(ML 模型的输出)
  • 维护对生产的影响(我们可能希望避免在计划生产水平最高的日子进行维护)
  • 维护人员的可用性
  • 机器特性(维修成本、剩余部件寿命成本等)。)

最后,需要做出的决策(建模为决策变量)决定了每台机器计划维护的日期/时间。这些值不是我们输入数据的一部分,而是由优化引擎作为解决方案的一部分自动确定。

第二步:形象化并并排比较场景

决策优化仪表板显示我们 DO 模型的输入和输出。“输入”选项卡可能如下所示:

DO for Cloud Pak for Data Dashboard — scenario inputs

在这里,我们可以看到一些关于机器及其特性、每日计划生产水平、预测故障(ML 模型的输出)和维护成本的数据。特别令人感兴趣的是预测故障图,它可以提供一些线索,说明何时安排维护是有意义的。假设我们想使用一种启发式方法,并计划“就在它变得太红之前”,这意味着机器很可能发生故障的前一天。我们将此视为我们的“手动”场景,并将维护事件定义如下(勾号表示维护事件):

Using a heuristic to determine the optimal maintenance day for each machine

我们还定义了一个没有固定维护事件的“优化”场景,并让优化引擎自动确定时间表。解决这两个方案后,我们可以在仪表板的多方案选项卡中并排比较解决方案:

DO for Cloud Pak for Data Dashboard — compare manual vs optimized scenarios side-by-side

显然,优化的方案导致更低的总成本和更少的生产短缺。查看维护时间表,很容易发现最佳维护日期并不明显,因为在某些情况下,最好提前几天安排维护,而在其他情况下,甚至推迟一天(机器 6)。优化方案还更好地利用了资源——与“手动”方案中的两个维护组相比,只需要一个维护组。优化的好处显而易见,即使是在一个非常小的问题上(6 台机器,15 天,和少量的约束)。想象一下,当一个问题很大时(成百上千的机器和大量的约束条件),找到一个好的解决方案会有多难!

步骤 3:部署模型并将它们嵌入到您的应用程序中

一旦模型准备好,经过测试,业务决策者已经审查了场景,就可以在线部署了,剩下要做的就是开发和部署我们的 web 应用程序。我们的演示是使用简单的 Node.js 应用程序实现的。

如果需要,机器、生产水平和维护成本的最新数据将加载到单独的数据选项卡中以供参考:

在主“维护计划”选项卡下,我们连接到 ML 可执行服务以获得预测。每条曲线的顶部告诉我们每台机器最有可能出现故障的时间:

Connect to the executable ML service and obtain failure predictions

我们现在已经准备好调用优化服务,并通过单击按钮生成最佳维护计划*:*

Connect to the online DO model and obtain the optimal maintenance schedule in one click!

现在我们已经获得了最佳维护计划,我们可以通过创建新的场景并指定事件来轻松地手动修复一些维护事件(相当于上面讨论的 Cloud Pak for Data DO 控制面板中的“手动”场景):

再次求解该场景并将结果与原始结果进行比较,证实了最优解优于手动解(成本为 2,279 美元对 2,471 美元):

Solving the Manual scenario (using a simple heuristic to schedule maintenance) and comparing the results

当然,这只是一个使用 IBM Cloud Pak 实现数据、决策优化和 Node.js 的演示的简单示例。至于您可以做什么以及如何在自己的应用程序中呈现信息,可能性是无限的。

摘要

预测性维护计划是许多资产密集型行业的关键领域。创建最佳维护计划是一个具有挑战性的问题,最好使用机器学习和决策优化的组合能力来解决。虽然机器学习可以考虑所有可用的数据和过去的历史,以预测每台机器发生故障的可能性,但决策优化可以更进一步,根据有限的资源、其他约束和依赖性以及优化指标,生成对一组机器而言最优的时间表。优化不仅能提供有价值的见解,还能生成可行的时间表或计划。**

使用良好的预测性维护解决方案的好处是巨大的,包括但不限于:

  • 更低的成本和更高的客户满意度
  • 减少规划/调度时间和工作量
  • 提高资产的可靠性和可用性
  • 提高单个资产的运营效率

根据世界经济论坛和埃森哲的研究,预测性维护解决方案的商业价值是:

  • -12%的调度成本
  • -30%的维护费用
  • -70%的非计划停机时间

如果您的公司正在寻找更好的方法来优化维护计划或解决其他预测和优化挑战,请不要犹豫,寻求帮助。IBM 数据科学精英团队的使命是帮助我们的客户在数据科学之旅中取得成功,作为这一使命的一部分,我们免费提供初始客户服务。我们很高兴在数据科学/人工智能相关项目上与您合作。更多信息请参考https://www . IBM . com/analytics/global elite/IBM-analytics-data-science-elite-team

如果你对更多的技术细节感兴趣,请继续关注这篇博客的后续文章。在下一篇文章中,我们将揭开 ML 和 DO 模型的面纱,探索一些真正的魔法!

附加链接

[## 预测性维护在工业自动化中的重要性

“每年因计划外停机造成的损失高达 200 亿英镑”(Automation.com,2016)。使用预测的有效方法…

www.linkedin.com](https://www.linkedin.com/pulse/importance-predictive-maintenance-within-industrial-dani%C3%ABl-visser/) [## 付费项目:制造商如何实现顶级绩效

今天的工业组织承受着巨大的压力,不仅要保持竞争力,还要建立…

partners.wsj.com](https://partners.wsj.com/emerson/unlocking-performance/how-manufacturers-can-achieve-top-quartile-performance/) [## IBM 分析数据科学精英团队| IBM

编辑描述

www.ibm.com](https://www.ibm.com/analytics/globalelite/ibm-analytics-data-science-elite-team) [## IBM Cloud Pak for Data -概述

IBM Cloud Pak for Data 是一个数据平台,它统一并简化了数据的收集、组织和分析

www.ibm.com](https://www.ibm.com/products/cloud-pak-for-data) [## 智能维护加速器

查看所选文档的详细信息

community.ibm.com](https://community.ibm.com/community/user/cloudpakfordata/viewdocument/intelligent-maintenance-prediction?CommunityKey=c0c16ff2-10ef-4b50-ae4c-57d769937235&tab=librarydocuments)

爱荷华州白酒销售数据的预测模型

原文:https://towardsdatascience.com/predictive-modeling-with-iowa-state-liquor-sales-data-e45342081b83?source=collection_archive---------2-----------------------

你好朋友们,

最近,我的任务是利用爱荷华州的大量酒类销售数据建立一个预测模型。

作为一个简短的背景,爱荷华州是一个酒精饮料控制州,这意味着该州在全州范围内保持着对酒类批发的垄断。实际上,私人零售商必须从州政府那里购买酒,然后才能卖给个人消费者。你可以在爱荷华酒精饮料部门的维基页面上了解更多。

The majestic Iowa flag

出于这个项目的目的,我利用了爱荷华州白酒销售数据的子集,这些数据可以在爱荷华州的州托管的开放数据门户上找到。虽然门户网站包含 2012 年以来的酒类销售,但我使用的数据集包含了 2015 年全年和 2016 年第一季度(1-3 月)的单个酒类销售。该项目的目标是使用 2015 年的销售数据建立一个模型,该模型可以根据 Q1 2016 年的数据预测 2016 年的总销售额。我使用 Python 中的 Pandas 库分析了数据。

简而言之,该数据集包含超过 270 万行数据。每项观察包含的信息包括:

  • 购买日期(年/月/日)
  • 进行购买的供应商的详细信息(例如,指定的商店编号、县和城市详细信息);
  • 购买的酒的类型和品牌(例如,杰克丹尼尔的田纳西威士忌);
  • 瓶子尺寸(例如 750 毫升)和购买的瓶子数量;
  • 总销售额,包括国家和每瓶零售成本;和
  • 出售的酒的总体积,单位为升和加仑

A snapshot of select columns in the original dataset. There are many additional data columns not pictured here.

初始数据清理和探索性分析

最初的数据清理和探索性分析包括以下步骤。

常规数据清理:

  • 提高列名的清晰度,根据需要转换数据类型。
  • 删除重复行
  • 用真空值替换字符串“nan”值
  • 对于成对的列(category_ID 和 category_name),如果一个列值没有相邻的对,我就填充它,如果可以的话,否则就把它改为 null

确保正确的计算:

  • 确保瓶子尺寸(例如 750 毫升)x 售出的瓶子=售出的体积升数
  • 确保瓶子的零售价值 x 售出的瓶子=销售额
  • 我没有发现数学上的问题,但是检查一下还是很好的

准备模型构建

我知道,如果我能把大部分数据分成更简单的类别,分析会容易得多。因此,我创建了几个新的专栏,从长远来看,这会让我的生活变得更加轻松。

例如,我创建了一个列,将日期条目折叠到它们发生的季度和年份:

(我将我的数据帧命名为爱荷华酒精的 i_a)

#Generating column for quarter-year
i_a[“Quarter_Year”] = “-”i_a.ix[(i_a.Date > ‘2014–12–31’) & (i_a.Date < ‘2015–04–01’), “Quarter_Year”] = “Q1_2015”
i_a.ix[(i_a.Date > ‘2015–03–31’) & (i_a.Date < ‘2015–07–01’), “Quarter_Year”] = “Q2_2015”
i_a.ix[(i_a.Date > ‘2015–06–30’) & (i_a.Date < ‘2015–10–01’), “Quarter_Year”] = “Q3_2015”
i_a.ix[(i_a.Date > ‘2015–09–30’) & (i_a.Date < ‘2016–01–01’), “Quarter_Year”] = “Q4_2015”
i_a.ix[(i_a.Date > ‘2015–12–31’) & (i_a.Date < ‘2016–04–01’), “Quarter_Year”] = “Q1_2016”

我还创建了单独的列来计算每笔交易的总零售成本和州的总成本,以了解该州从其酒类销售中获得了多少利润。

当检查某些类别和 2015 年总销售额之间的关联时,我可以看到与其他不太受欢迎的选项相比,某些项目占总销售额的很大一部分。

例如,有 30 多种不同的瓶子尺寸(体积/毫升)。然而,绝大多数售出的瓶子要么是 750 毫升、1000 毫升,要么是 1750 毫升。为了使进一步的分析和模型构建更容易,我创建了一个列来指示所购买的酒的瓶子大小是 750 毫升、1000 毫升、1750 毫升还是其他。

i_a[“Consolidated_Bottle_ml”] = “”#After examining data, it made sense to consolidate bottle sizes into 750ml, 1000ml, 1750ml, and all others
i_a.ix[i_a.Bottle_Volume_ml == 750, “Consolidated_Bottle_ml”] = “750ml”
i_a.ix[i_a.Bottle_Volume_ml == 1000, “Consolidated_Bottle_ml”] = “1000ml”
i_a.ix[i_a.Bottle_Volume_ml == 1750, “Consolidated_Bottle_ml”] = “1750ml”
i_a.ix[i_a.Consolidated_Bottle_ml == “”, “Consolidated_Bottle_ml”] = “Other_ml”

当绘制与这些类别相关的相对总销售额时,可以清楚地看到这些瓶子尺寸在所有其他产品中的主导地位:

同样,我注意到酒类的大趋势表明,许多购买的要么是各种威士忌,要么是伏特加。为了解析这些,我对类别字符串进行了文本搜索,以表明所购买的酒是某种威士忌、伏特加还是其他什么:

#Creating “Is_” columns as booleans for each type in the list above
#After further analysis, only whiskey and vodka seem to warrant their own categories, with everything else in “Other”i_a[“Is_WHISK”] = i_a[‘Alcohol_Category_Name’].str.contains(“WHISK”)
i_a[“Is_VODKA”] = i_a[‘Alcohol_Category_Name’].str.contains(“VODKA”)#Creating new column to identify consolidated alcohol typei_a[“Consolidated_Category”] = “”#Assigning values as either Whiskey, Vodka, or Non-Whiskey-Vodka, depending on true values in "Is_" columns. If the category is neither whiskey, nor vodka, or is null, assigning it to this other category.i_a.ix[i_a.Is_WHISK == True, “Consolidated_Category”] = “WHISKEY”
i_a.ix[i_a.Is_VODKA == True, “Consolidated_Category”] = “VODKA”

i_a.ix[((i_a.Is_WHISK == False) & (i_a.Is_VODKA == False)) | (i_a.Alcohol_Category_Name.isnull()), “Consolidated_Category”] = “NON-WHISKEY-VODKA”

同样,你会注意到与所有其他烈性酒相比,威士忌和伏特加这两种酒是多么突出:

既然我可以看到大部分销售收入的分组,我觉得我有足够的信息来开始构建一个模型

转换数据集

为了构建我的模型,我知道我需要仅使用一个季度的销售数据来预测全年的销售。

为此,我想转换我的数据集,按商店编号对数据进行分组,然后构建一个模型,根据一个季度的数据预测每个商店的年总销售额。

我知道我希望将预测变量的数量保持在最小,所以我希望选择那些看起来能解释总销售额中最大差异的变量。

具体来说,我想根据与四个变量相关的 Q1 2015 年销售额来预测年总销售额:750 毫升瓶、1000 毫升瓶、1750 毫升瓶,以及非威士忌/非伏特加酒的购买量。

为了在 pandas 中实现这一点,我使用 groupby 语句创建了一系列独立的数据帧,然后将这些不同的数据帧连接在一起,以创建我的最终建模集。

我用多个变量分组,用“.unstack()"函数有助于将每个感兴趣的变量存储为自己的列,而不是分层嵌套结果。在开始这个过程之前,我还创建了一个单独的日期框架,仅包含 2015 年的数据(i_a_2015)。

(有几个额外的变量我没有包括在我的最终模型中,它们最初是为了好奇而添加的。)

#Use the data from 2015 to make a linear model using as many variables as you find useful to predict the yearly sales of all stores.#We don’t want to use ALL of the data from the variables of interest — we only want about 1/4 of it (as we’ll only have a quarter’s worth of data from 2016 when generating predictions for all of 2016.)#create dataframe grouped by store for 2015 that will be used for building regression model#We DO still keep ALL of the sales data from 2015 as the target variable, as we want to predict the final 2016 totals
#for all storesstore_sales_2015 = pd.DataFrame(i_a_2015.groupby(“Store_Number”).Sale_Dollars.sum())store_sales_2015.rename(columns={‘Sale_Dollars’:’Sale_Dollars_Total_2015'}, inplace=True) #Drawing out bottles_sold; keeping Q1 data and dropping Q2:Q4add_Q1_bottle_sold = pd.DataFrame(i_a_2015.groupby([“Store_Number”, “Quarter_Year”]).Bottles_Sold.sum().unstack())#alter Q1_2015 column name for easier interpretabilityadd_Q1_bottle_sold.rename(columns={‘Q1_2015’:’Bottles_Sold_Q1_2015'}, inplace=True)add_Q1_bottle_sold.drop([‘Q2_2015’, “Q3_2015”, “Q4_2015”], axis=1, inplace=True)#Finding the “mode” of the stores’ counties, which will be the only item associated with each storeadd_store_county = pd.DataFrame(i_a_2015.groupby(“Store_Number”).County.agg(lambda x:x.value_counts().index[0]))#Creating df of only Q1_2015 to make extracting of bottle sizes and other multi-variable columns easieri_a_Q1_2015 = i_a[i_a[“Quarter_Year”] == “Q1_2015”]#Drawing out bottles_sizes sales volume for 750ml, 1000ml, 1750ml, and other_ml for Q1_2015;add_Q1_bottle_sizes = pd.DataFrame(i_a_Q1_2015.groupby([“Store_Number”, “Consolidated_Bottle_ml”]).Sale_Dollars.sum().unstack())add_Q1_bottle_sizes.rename(columns={‘1000ml’:’1000ml_Sales_Q1_2015', ‘1750ml’:’1750ml_Sales_Q1_2015',’750ml’:’750ml_Sales_Q1_2015',’Other_ml’:’Other_ml_Sales_Q1_2015'}, inplace=True)#Drawing out consolidated_category sales volume for whiskey, vodka, and others for Q1_2015;add_Q1_consolidated_category = pd.DataFrame(i_a_Q1_2015.groupby([“Store_Number”, “Consolidated_Category”]).Sale_Dollars.sum().unstack())add_Q1_consolidated_category.rename(columns={‘NON-WHISKEY-VODKA’:’NON-WHISKEY-VODKA_Sales_Q1_2015', ‘VODKA’:’VODKA_Sales_Q1_2015',’WHISKEY’:’WHISKEY_Sales_Q1_2015'}, inplace=True) #saves changes#drawing out total Q1 sales from initial i_a_2015 df, dropping Q2, Q3, and Q4add_Q1_total_sales = pd.DataFrame(i_a_2015.groupby([“Store_Number”, “Quarter_Year”]).Sale_Dollars.sum().unstack())add_Q1_total_sales.rename(columns={‘Q1_2015’:’Q1_2015_total_sales’}, inplace=True) #saves changes add_Q1_total_sales.drop([‘Q2_2015’, “Q3_2015”, “Q4_2015”], axis=1, inplace=True)#creating final dataframe for modeling by concatenating all other dfsmodel_df = pd.concat([store_sales_2015, add_Q1_bottle_sold, add_store_county, add_Q1_bottle_sizes, 
 add_Q1_consolidated_category, add_Q1_total_sales], axis=1)#there are some NaN values where stores didn’t buy certain bottle sizes or liquor types — convert to zerosmodel_df.fillna(value=0, inplace=True)

完成所有这些后,我们有了 2015 年总销售额的数据框架,并选择了可用于预测的 Q1 销售变量。让我们快速浏览一下:

A snapshot of our dataframe used for modeling. The Index column on the far left is each store’s assigned number. Not all columns are pictured here.

检查我感兴趣的变量的关联热图,我可以看到这些变量之间有中等强度的关联,这并不完全令人惊讶(特别是考虑到非威士忌/非伏特加酒将固有地与瓶子大小重叠)。

构建预测模型

为了训练和测试我的模型,我对 2015 年的模型集进行了 70:30 的训练测试分割。这意味着我可以使用建模数据框架中 70%的数据来拟合我的模型,然后用拟合模型时没有使用的剩余 30%的数据来测试我的模型的准确性。

在下面的代码中:

X =仅使用上述热图中列出的变量的存储数据对数据框架进行建模

y =仅包含 2015 年商店总销售额的数据框架

from sklearn import linear_model
from sklearn.model_selection import train_test_split#Conducting 70:30 train-test split for purposes of building and testing model. Set random state = 1 for reproducibility.X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=1)#instantiate linear model for ease of coding belowlm = linear_model.LinearRegression() #generate fit of model base on training set
#fit method expects two arguments of x’s and y’smodel = lm.fit(X_train, y_train) #generate predicted values of y_test from X_test based off of training setpredictions = lm.predict(X_test)#plotting predicted ys against y values in test set plt.scatter(y_test, predictions) 
plt.xlabel(“True 2015 Total Sales”)
plt.ylabel(“Predicted 2015 Total Sales”)

得到的模型的 R =.956,这意味着该模型解释了商场 2015 年年度销售额中约 95.6%的差异,这是根据我选择的变量中的 Q1 销售数据得出的。这是预测值与实际值的对比图:

我用交叉验证和正则化方法进一步检查了这个模型,但是这篇博文已经够长了,而且他们没有给已经不存在的模型增加太多东西。

对 2016 年进行预测

最后一步,是为我现有的 2016 年 Q1 再现一个类似的建模数据框架(按商店分类的信息),然后为每个商店的 2016 年总销售额生成预测。我使用了与上面巨大代码块非常相似的代码来生成 2016 预测集。

生成预测后,我将预测(LM_Predictions)附加到每个商店的行中,如下所示:

最终结果

我建立的线性模型预测 2016 年白酒总销售额为 2.92 亿美元,比 2015 年(2.84 亿美元)增长 3%。

其中,该州 2015 年的利润占总销售额的 33%(9500 万美元),该州 2016 年的预计利润为 9800 万美元。很酷,东西!

世界各地的饮料偏好

原文:https://towardsdatascience.com/preferences-of-drinks-around-the-world-36f37de0394?source=collection_archive---------2-----------------------

在啤酒、烈酒和葡萄酒消费方面,一些国家比其他国家更相似吗?

我使用了一个来自世卫组织的包含年度酒精消费量的数据集,对它应用了层次聚类,并将树分成 6 个聚类。结果很有趣。

地理位置相近的国家有相似的饮酒习惯,比如我们可以看到俄罗斯、白俄罗斯、斯洛伐克在一个群中,瑞士和卢森堡在一个群中,比利时、荷兰、奥地利在一个群中。潜在文化相似的国家也靠得很近,比如巴布亚新几内亚和密克罗尼西亚。

这是我的# 100 day 项目的第四天。完整代码在 github 上。

准备现场数据科学面试

原文:https://towardsdatascience.com/preparing-for-in-person-data-science-interviews-some-thoughts-5e2677ee30d9?source=collection_archive---------7-----------------------

从我的经历中得到的一些建议

Edited from: https://lifehacker.com/5975338/top-10-tips-for-acing-your-next-job-interview

我最近偶然看到Kristen ke hrer2018 年 4 月的文章“如何在数据科学面试中胜出”,这让我反思了自己的数据科学工作准备,以及几个月前与也在寻找类似工作的朋友们的讨论。这篇文章总结了我准备数据科学家面试的笔记。

免责声明:我和我的朋友都有博士学位和 2-3 年的学术经验背景,他们主要寻找自然语言处理方面的工作。因此,虽然我要写的大部分内容是通用的,希望对每个人都有用,但有些部分可能是特定于那个背景的。

一般来说,数据科学家职位的现场面试包括会见几个人:

  • 不同经验水平的数据科学家同事
  • 软件工程师、数据工程师等
  • 数据科学经理和任何其他人员(例如,在初创公司中,这可能涉及 CTO 或 CEO)。

根据公司的不同,这通常需要大约半天的面试时间。除了这些,你还可能被要求做一个演讲/报告,这取决于你的角色。我只在申请以研究为重点的职位时做演讲——所以,在这篇文章中我不会深入探讨。

当我知道我要申请数据科学家的职位时,我开始了一个实时文档,添加了我在网上找到的问题,并做了自己的分类。虽然这种分类可能并不适用于所有人,但以下是我使用的分类:

  • 与简历/过去工作相关的问题
  • 编程和软件工程问题
  • 机器学习/深度学习/NLP:概念问题
  • 问题解决问题(大多与公司领域相关)
  • 统计问题
  • 行为问题
  • 工作文化相关问题
  • 我们可以/应该问面试官的问题

我浏览了各种网站,并开始在相应的部分列出我在 live 文档中发现的所有问题。虽然我没有准备好每个问题的答案,但只要一有时间,我就会试着给每个问题添加评论。在每次面试之前,我都会通读这份文件,如果我发现任何我认为与面试特别相关的未回答的问题,我会添加一个答案。每次面试后,如果我面对一个新问题,如果回家后我还记得,我会把它添加到我的文档的适当部分。像这样,那份文件现在已经增长到 30 多页了![本来真的应该更长,但我意识到我忘记了大多数被问到的问题!]

让我逐一讨论每一类问题:

简历和过往工作相关问题:

这些通常以“告诉我关于你自己的情况”开始,有时可能会有一些具体的问题,如:“你在 X 公司做什么?”、“你做 Y 用的什么库?”等等。在我看来,解决这些问题的最佳方式是:

  • 练习持续 1-1.5 分钟的“自我介绍”
  • 彻底检查你的简历
  • 快速浏览您的公开资料(LinkedIn、Medium、Github 等)

与编程和软件工程实践相关的问题:

这些主要是工程师会问的问题,在某种程度上,也是你未来的同事数据科学家会问的问题。 一般都是做一些白板编码,讲一些典型的问题解决方法和算法等。当我说软件工程实践时,我指的是代码和模型版本控制、软件测试、代码审查等。以下是我为准备这类问题而做的一些事情:

  • 在 HackerRank 上练习编码几天,每天 30-60 分钟 ,浏览 Gayle Laakmann McDowell 的《破解编码面试》。我在一所美国大学做全职助理教授,一大早我抽不出一个小时以上的时间。但是如果你完全生疏了,如果可以的话,多花点时间是有用的。
  • 对于软件工程实践,由于我不是在面试一个传统的软件工程师职位,我没有花很多时间,除了列出几个问题,如果我是面试官 (例如,我什么时候使用笔记本?我在 Python 中使用类吗?如何对数据和模型进行版本控制?我如何看待数据科学的软件测试?等等。)

ML/DL/NLP:概念性问题

这些是团队中的数据科学家可能会问你的问题 。经理也可能会问这些问题来衡量你是否知道你在说什么,以及你是否能传达你所知道的。这里的 NLP 是因为我申请了这些工作,我有那方面的研究背景。但是,申请图像处理工作的人可能会有相关的问题。对于这些问题,我:

  • 浏览典型的教科书内容,例如,这些学科的所有入门课程中教授的算法
  • 最近的会议论文和博客文章,以了解最近的发展
  • 重温了我以前为其他项目编写的一些代码,其中涉及到应用这些概念。

问题解决问题

这些都是与公司领域相关的问题。目标是看你是否能把概念上的知识应用到一个具体的问题上。 在我的采访中,这些问题通常来自一位经理,尽管有时,一位资深数据科学家也会问这些

一个例子可能是这样的:“我们是一个电子商务网站,我们有这个问题的假评论和假用户资料。你将如何运用你的 NLP 和 ML 知识来解决这个问题?”。根据你的回答,会有很多后续问题,比如:“你需要什么样的数据?你将如何得到它?需要什么清洁?处理此文本时,您可能会遇到什么潜在问题?”等等。

以下是我对这类问题的回答:

  • 我经常看一些博客,比如的人工智能面试,在那里他们会发布一些公司特有的面试问题,这些问题集中在该公司做了什么。
  • 除此之外,我还试图预测该公司领域的潜在问题,并对此有一些想法。例如,如果我们正在寻找,比方说,像 LinkedIn 这样的公司,一些潜在的 NLP 问题场景是什么?—从个人资料/工作描述中提取信息,向用户提供建议,显示与某个主题相关的不同帖子(例如,“人们现在在谈论什么?特征)等等。

统计问题

这些问题是关于一般的统计方法,他们的假设和东西。 这些通常来自数据科学家团队。 因为我没有统计学学位,所以我只关注基本问题(例如,线性回归的假设、1 型与 2 型误差、假设检验等)。有很多关于这些的在线资源,我尽可能多地梳理了这些资源,并在我的文档中列出了这些独特的问题,以及我在哪里知道它们或在网上找到它们的答案。

行为问题

行为问题主要侧重于了解我们对工作场所不同场景的反应,以及了解你的总体态度。根据我的经验,这些来自经理,以及团队/公司中的其他高级管理人员。

Gayle Laakmann McDowell 的书(包括《编码》和《产品经理》)列出了一堆行为问题。我发现这些非常详尽。另外,我还从网上搜集了一堆问题。比如“告诉我你做过的最具挑战性的项目”,“你将如何处理与老板的冲突”等等。,我们显然不会对所有这样的场景都有答案,但我试图从以前的工作经历中为尽可能多的问题准备具体的例子,以便到时候我可以根据快速回忆说话,而不是匆忙思考。虽然我的许多答案来自以前的专业经验,但也有一些来自学生时代和其他自愿(非技术)的经验。

文化契合度问题:

这些通常是任何一个面试官都会问你的问题 ,以评估你是否适合他们的团队,是否会成为一个好同事。我归类为文化适应问题的内容包括:

  • 你如何与现场发生的事情保持联系?
  • 你最近用过哪些工具包/库?
  • 你最喜欢的算法是什么?
  • 举一些数据科学中“最佳实践”的例子
  • 你喜欢在小团队还是大团队工作还是自己一个人?

等等。再次,我从网上资源整理了很多问题,也加入了我作为面试官会问的问题。

问面试官的问题:

我认为面试是一个相互评估的过程。面试官在评估你的同时,你也在评估他们是否是聪明友好的同事,你是否能在那个职位上成长,以及公司的文化是否适合你。所以,我总是花时间思考该问我遇到的每个人什么。我也试着从招聘经理那里了解我到底会遇到谁,并尽可能在网上查找他们。

这些和之前的有一些共同的问题。例如,作为一名受访者,我还想了解上述文化适应问题。除此之外,我还想知道团队的长期愿景,人们现在正在做的项目,他们使用什么语言/平台,他们喜欢自己工作中的什么等等。对于经理和其他人,我也想知道我是否被派去参加会议,是否能请几天假去做与公司利益相关的个人项目等等。

我作为面试官问的问题

虽然我没有花很多时间,但我确实参加了数据科学家职位的面试。我没有问所有这些问题,但考虑到我是一名数据科学家,并且我过去有一点工程和研究背景,我的问题主要有四种:

  • 技术问题:比如关于一些 NLP/ML/DL 算法及其用例。我没有问任何编程问题,因为这通常会出现在在线测试或另一位面试官的提问中。
  • 解决问题:比如“你将如何为中型文章设计一个自动标记系统?”
  • 关于简历/过去的工作、流程和实践的问题:例如,“你实践团队数据科学流程吗?”,“你为其他数据科学家做代码评审吗?”,“在 X 公司,你用了哪些库?”等等。
  • 工作文化问题:例如,“你关注什么时事通讯/博客来保持与最新发展的联系?”

这是一个相当长的帖子,所有这些都不是在一两天内完成的。我的问题文档是在几个月的时间里建立起来的,如果我发现一些有趣的东西,我会偶尔更新它。就像我之前提到的,并不是所有这些都与每个人相关,但我希望每个人都能从中受益。我不是说这是唯一的办法,但准备这份文件对我来说真的很有用。当然,我还得补充一点:准备问题和答案只是故事的一部分。 在面试中练习和保证恰当的沟通同样重要!毕竟,我们没有一生的时间去打动面试官! 感谢阅读!

准备您的数据科学简历和投资组合

原文:https://towardsdatascience.com/preparing-your-data-science-resume-portfolio-22af6bada8b9?source=collection_archive---------2-----------------------

在过去的几年里,我会见了许多雇主,并进行了培训项目的面试。通过对话和面试并看到最终结果,我想我会分享更多关于如何准备你的简历,甚至是数据科学职位的面试。大部分提示都是给那些想进入数据科学行业并有“绿色”背景的人的。我不能保证结果,但我希望它可以帮助那些对数据科学充满热情的人。给出的提示是给那些对 it 充满热情的人的,因为这需要很多努力。

项目

标题本身就说明了问题,但让我借此机会进一步解释一下。经常有人问我“我能把我的学校项目作为项目组合的一部分吗?”如果要展示他们的学校项目,我有一些想法。

首先,这些学校项目中的大部分是有指导的(希望如此)并且是团队合作的。区分项目的哪一部分由谁来完成是非常具有挑战性的。我只能推断的是,基于项目的结果,团队是功能性的还是功能性的。

展示的最佳项目是在课程之外,在一个人的空闲时间完成的,因为它表明这个人对数据科学充满热情,并且愿意将他们的空闲时间花在这上面。我也可以把项目中所做的一切归功于受访者。但那是在我问了几个关于这个项目的问题以确定它之后。

使用关键词(如使用的机器学习模型、模型训练过程等)来解释项目,但要准备好解释这些关键词,尤其是在技术面试的时候。我倾向于要求受访者解释这些关键词,并且解释必须达到外行人能够理解的水平。嗯,如果一个人不能向门外汉解释它,这意味着他仍然不能完全理解它,对吗?

团队工作

如果一个人要从事数据科学甚至人工智能的工作,能够在团队中工作是非常重要的,不管他是领导还是团队成员。因此,展示任何团队项目以及取得的影响是很重要的,最好量化影响,这样面试官就可以建立一个良好的心理印象。这种影响会给我一些信息,让我知道受访者是否能在团队中工作。我还倾向于要求受访者分享他们在至少一个项目中的更多经验,以确定他/她是否能在团队中工作。

数学&统计背景

我喜欢被采访者对数学和统计学水平的良好把握。可以从他们使用的模块等级、项目、工具来推断。

模块等级确实有助于确定水平。我通常会查看整个数学模块组合,作为一个整体来确定数学和统计背景的水平。我确实会给那些成绩平平的人机会,但我肯定会问受访者为什么成绩平平。我确实会问受访者他们喜欢和不喜欢数学和统计学的什么,以确定他/她是否能够处理数据科学和人工智能所需的数学。

项目和工具确实有助于推断数学背景。这是通过他们使用的机器学习模型,他们如何实现它以及他们为什么以特定的方式实现它来看的。我可能会问他们在这些项目中面临的挑战是什么,选择特定解决方案的原因是什么,以及尽可能与背后的数学知识有关。

编程

如果可能的话,展示所有编写的代码,尤其是为数据科学项目编写的代码。否则欢迎其他语言,不一定一定是数据科学中常用的那些语言(R,Python,Scala)。

确保它是有据可查的。良好记录的意思是对代码做了什么,为什么需要以这种方式编写代码,为什么要实现代码等有很好的描述。主要目的是让采访者了解采访者在编写代码和从项目中获得洞察力时所经历的思维过程(这是我关于如何改进它的博文)。为了使数据科学具有可再现性、解释性和可说明性,文档非常重要。展示思考过程对于面试官来说是一个非常重要的考虑因素,以决定给予新员工多大的自主权来从项目中获得有意义的结果。

因此,记录良好的代码非常重要,因为它可以表明潜在雇员的知识、技能和思维水平。

结论

以上几点是我在参加培训项目面试和与许多雇主交谈时收集到的。我希望分享的几点能帮助你构建一份对潜在雇主更具“吸引力”的简历,并为可能出现的面试问题做好充分准备。

我还要推荐下面这篇文章,“如何从零开始构建数据科学投资组合”。

祝您的数据科学学习之旅愉快,请务必访问我的其他博客文章LinkedIn 个人资料

**补充说明:**作为我 2020 年新年计划的一部分,我已经建立了自己的网站,最新消息请访问这里。感谢支持!

物联网数据预处理:线性重采样

原文:https://towardsdatascience.com/preprocessing-iot-data-linear-resampling-dde750910531?source=collection_archive---------1-----------------------

处理间隔不均匀的时间序列数据

在本文中,我将介绍我们认为在分析来自物联网(IoT)的时间序列数据时最重要的预处理步骤:线性重采样。我将描述对物联网传感器数据进行重采样所面临的挑战,并介绍我们为解决这些挑战而设计的简单解决方案。

不规则物联网时间序列数据

在物联网(IoT)中,传感器和其他连接设备收集数据。这些数据被发送到云端,以便进行处理、分析或建模,从而构建智能应用。

因为物联网设备通常不会定期发出数据,所以物联网时间序列数据在采样率方面非常不规则,无论是在设备内部还是在设备之间。这使得处理和分析变得麻烦,尤其是当来自多个传感器的数据被组合在一起分析时。

因此,重采样不规则和不均匀间隔的时间序列数据到一致和规则的频率是物联网中至关重要的预处理步骤,可以极大地促进数据的连续处理。

在总部位于柏林的风险建筑商 WATTx ,我们专注于深度技术,包括物联网。在我们最近的一个项目中,我们在一栋安装了数百个传感器的建筑中建造了一个能源优化原型。这些传感器收集关于温度、湿度、亮度和运动的信息。下面,您可以看到一张展示该设置的平面图:

Smart Office IoT setup

通过分析来自办公室这些传感器的数据,我们发现了一个特别有趣的现象:

Clusters of averaged daily temperature curves

该图显示了平均温度曲线簇,并显示了大量房间在夜间和白天都出现过热,这表明 HVAC 系统的使用不理想,因此浪费了能量。

使用熊猫进行重采样

在运行与上面类似的分析之前,一个关键的预处理步骤是将不规则的时间序列数据转换为规则的频率,在所有传感器上保持一致。通过这样做,我们消除了在后面的分析过程中必须处理不规则和不一致的跨传感器时间戳的痛苦。

在 WATTx,我们大量使用 Python 及其数据科学堆栈,因此这个过程的自然选择是使用来自 pandas[resample](https://pandas.pydata.org/pandas-docs/stable/generated/pandas.DataFrame.resample.html)功能。

让我们来看一个简单的模拟温度曲线示例,数据点间距不均匀:

现在,假设我们想要使用平均值作为聚合函数和线性插值,以 50 分钟(任意选择)的频率对此温度曲线进行重新采样:

pd.resample(tseries, '50min', 'mean').interpolate()

如上所述,重新采样后的时间序列与原始数据并不完全匹配,但显示出相当大的偏移。这主要是因为 pandas 的重采样功能是一个按时间分组的操作,这使得它非常容易受到原始数据的精确采样和期望目标频率的影响。

物联网的两步重采样过程

为了克服这些不一致性,我们提出了一种解决方案,可以解决我们所有需要线性插值的物联网传感器的这个问题。

该解决方案由两步重采样过程组成,其中我们 (1)首先使用均值作为聚合函数和线性插值将原始时间序列向上采样到高频(例如 1 分钟或 1 秒,取决于初始数据的分辨率),然后使用简单的正向填充聚合将序列向下采样到所需的目标频率。

应用于上面的示例曲线,代码如下所示:

tmp = pd.resample(tseries, '1min', 'mean').interpolate()
resampled = pd.resample(tmp, '50min', 'ffill')

让我们来看看结果:

显然,这种两步重采样过程的结果曲线与底层数据的匹配程度更高,并且在我们所有需要线性重采样的物联网传感器中都是如此。

增强稳健性:处理缺失数据

当对物联网传感器数据进行重采样时,我们希望考虑的另一种情况是时间序列中缺失数据的大缺口。例如,传感器离线几个小时就是这种情况。

以下是一个模拟温度曲线的示例,显示了传感器在夜间(大约从晚上 10 点到早上 6 点)离线的几个小时间隔:

如果我们对这个时间序列进行重新采样,得到的数据点如下所示:

显然,重采样的数据与大块数据丢失期间的基本真实温度曲线不匹配。为了涵盖这种情况,我们引入了一个附加参数,该参数规定了缺失数据的最大间隙应该是多大,以便进行插值。如果差距超过这个指定的阈值(我们发现在大多数情况下,1 小时左右是一个好的选择),数据点不会被插值,而是作为 *NaN(不是数字)*值返回。

应用这个额外的功能,我们得到了我们想要的结果;在无数据传输期间,定期采样的数据为空值:

摘要

在这篇博文中,我们展示了对不规则物联网时间序列数据进行重采样的挑战,以及我们为克服这些挑战而设计的简单解决方案。我们简单的物联网传感器数据重采样解决方案的代码可在 GitHub gist 的中找到。

这篇博文的内容是我在 PyData Berlin 2017 演讲的一部分,幻灯片可以在这里找到。

要了解我们在 WATTx 工作的更多令人兴奋的内容,请查看我们的博客和Statice——我目前正在从事的项目,我们在其中开发技术以实现隐私保护数据科学。

预处理大型数据集:50 万多个实例的在线零售数据

原文:https://towardsdatascience.com/preprocessing-large-datasets-online-retail-data-with-500k-instances-3f24141f511?source=collection_archive---------12-----------------------

几个月前,我有机会参与一个拥有超过 500,00 0 行的庞大数据集的项目!老实说,这是我第一次不得不处理数量惊人的数据,但我认为玩它并探索新的数据挖掘技术会很有趣。在这篇文章中,我将解释我是如何处理这个问题的,并最终得到了一个干净的、便于使用的数据集。还提供了 R 代码。

正在讨论的数据集在 UCI 机器学习库这里可用。这是一个交易数据集,包含 2010 年 1 月 12 日和 2011 年 9 月 12 日之间英国注册的无店铺在线零售的所有交易。该公司主要销售独特的全场合礼品;这家公司的许多客户都是批发商。属性信息可以在提供的链接中找到。我的最终目标是对这些数据进行购物篮分析,并找出关联规则。然而,第一步是清理数据。

我将数据集保存为一个. csv 文件,并简要查看了所有行。我意识到,由于维度问题,我可能无法注意到最重要的模式和细节。然而,我注意到一些单元格是空的,那些是丢失的值。为了方便起见,它们被重新编码为 NA。我还发现了丢失的值在哪里,以及有多少。

dataset = read.csv("OnlineRetail.csv", na.strings = c("","NA"))attach(dataset)#checking if there any missing values, where are they missing, and how many of them are missingany(is.na(dataset))[1] **TRUE**apply(dataset, 2, function(x) any(is.na(x)))InvoiceNo StockCode Description Quantity InvoiceDate UnitPrice CustomerID Country**FALSE** **FALSE** **TRUE** **FALSE** **FALSE** **FALSE** **TRUE** **FALSE**sum(is.na(CustomerID))[1] 135080sum(is.na(Description))[1] 1454

InvoiceNo 为整数类型;但是,最好是字符类型,这样我们就可以应用字符串函数。在 InvoiceNoDescription 中的 trim 功能都删除了前导和尾随空格。

dataset$InvoiceNo = as.character(InvoiceNo)
trim = function (x) gsub("^\\s+|\\s+$", "", x)
dataset$InvoiceNo = trim(InvoiceNo)
dataset$Description = trim(as.character(Description))

以 C 开头的发票号码实际上是取消的,所以我们可能想去掉它们。我引入了一个名为 is_C 的函数,它检查一个字符串是否以 C 开头。我们对原始数据进行子集化,得到 dataset2 (没有取消)和 dataset3 (没有空的项目描述)。我们可以看到原始数据集有 541 909 个观察值,现在我们在数据集 3 中有 531 167 个观察值。我们刚刚剔除了将近 10 000 个无用的观察值。

is_C = function (x) startsWith(x,"C")
dataset2 = dataset[which(!is_C(dataset$InvoiceNo)),] #subsetting
dataset3 = subset(dataset2,!is.na(dataset2$Description)) #subsetting

接下来,我又看了一遍这些行,发现许多项目描述没有任何意义。例如,我看到了像“?”这样的符号以及损坏、砸碎、丢失等词语。扔掉这些不需要的东西是个好主意。我想出了一系列有趣的流行语:

buzzwords = c("WRONG","LOST", "CRUSHED", "SMASHED", "DAMAGED", "FOUND", "THROWN", "MISSING", "AWAY", "\\?", "CHECK", "POSTAGE", "MANUAL", "CHARGES", "AMAZON", "FEE", "FAULT", "SALES", "ADJUST", "COUNTED", "LABEL", "INCORRECT", "SOLD", "BROKEN", "BARCODE", "CRACKED", "RETURNED", "MAILOUT", "DELIVERY", "MIX UP", "MOULDY", "PUT ASIDE", "ERROR", "DESTROYED", "RUSTY")

如果任何项目包含这些单词中的一个,它将被删除。以下功能是不合需要的测试一个项目是否“不合需要”。

library(stringr)   #function str_detectisUndesirable = function(x){c = **FALSE**   #assume that the string is undesirable (FALSE), and perhaps switch to desirable (TRUE)for (i **in** 1:(length(buzzwords))){
  c = c || ifelse(str_detect(toupper(x),buzzwords[i]),**TRUE**,**FALSE**)
}#now we know whether or not the string is undesirablereturn(c)}

现在我们可以子集化 dataset3 使得数量大于 0(否则没有意义),项目名称为“合意”。我们得到数据集 4 ,最后得到数据集 5InvoiceDate 被转换为 POSIXct 对象,订单的确切时间被排除。描述列被分解。

dataset4 = subset(dataset3, dataset3$Quantity > 0)dataset5 = dataset4[which(!isUndesirable2(as.character(dataset4$Description))),]Time = format(as.POSIXct(strptime(dataset5$InvoiceDate,"%Y-%m-%d %H:%M",tz="")) ,format = "%H:%M:%S")dataset5$InvoiceDate = as.Date(dataset5$InvoiceDate)
dataset5$Description = as.factor(dataset5$Description)

就是这样!现在我们有了包含 530 653 个观察值的数据集 5 ,准备用于购物篮分析。请注意,该数据集在 CustomerID 列中仍然有缺失值。然而,这无关紧要,我们为什么要关心客户的 ID 呢?发票号对于发现关联规则和进一步分析更为重要。然而,如果我们想在另一个分析中使用这个数据,我们可以用不同的方式对它进行预处理。

完整的 R 代码,请访问我的 GitHub 简介。

使用 sklearn 进行预处理:完整而全面的指南

原文:https://towardsdatascience.com/preprocessing-with-sklearn-a-complete-and-comprehensive-guide-670cb98fcfb9?source=collection_archive---------0-----------------------

对于有抱负的数据科学家来说,有时可能很难在预处理技术的森林中找到出路。 Sklearn 它的预处理库形成了一个坚实的基础,指导您完成数据科学管道中的这项重要任务。虽然 Sklearn 有相当可靠的文档,但它经常忽略不同概念之间的流线和直觉。

本文旨在成为一个关于使用 sklearn v0.20.0 进行预处理的完整指南。它包含了 sklearn 中可用的所有实用函数和 transformer 类,并补充了其他常用库中的一些有用函数。最重要的是,文章是按照一个逻辑顺序来组织的,这个逻辑顺序代表了执行所讨论的转换的顺序。

将处理以下主题:

  • 缺少值
  • 多项式特征
  • 分类特征
  • 数字特征
  • 自定义转换
  • 特征缩放
  • 正常化

注意,第三步和第四步可以互换执行,因为这些转换应该彼此独立地执行。

缺少值

处理缺失值是一项重要的预处理任务,如果处理不当,可能会严重影响模型的质量。在处理缺失值时,应该提出几个问题:

我是否有缺失的值?它们在数据中是如何表达的?我应该扣留缺失值的样本吗?或者我应该换掉它们?如果是,应该用哪些值替换?

在开始处理缺失值之前,重要的是识别缺失值并知道它们被哪个值替代。通过将元数据信息与探索性分析相结合,您应该能够发现这一点。

一旦您对丢失的数据有了更多的了解,您就必须决定是否要保留带有丢失数据的条目。根据 Chris Albon ( 机器学习与 Python 食谱)的说法,这个决定应该部分取决于随机缺失值的程度

如果它们是完全随机的,它们不会给出任何额外的信息,可以省略。另一方面,如果它们不是随机的,值丢失的事实本身就是信息,可以表示为额外的二进制特征。

还要记住,因为缺少一个值而删除整个观察可能是一个糟糕的决定,会导致信息丢失。就像保留一整行缺失值,因为它有一个有意义的缺失值,这可能不是您的最佳选择。

让我们使用 sklearn 的 MissingIndicator 通过一些编码示例来实现这个理论。为了给我们的代码赋予一些意义,我们将创建一个非常小的数据集,包含三个特性和五个样本。数据包含明显的缺失值,表示为非数字999

import numpy as np
import pandas as pdX = pd.DataFrame(
    np.array([5,7,8, np.NaN, np.NaN, np.NaN, -5,
              0,25,999,1,-1, np.NaN, 0, np.NaN])\
              .reshape((5,3)))X.columns = ['f1', 'f2', 'f3'] #feature 1, feature 2, feature 3

Data set with three features and five samples

快速浏览一下数据,这样您就知道丢失的值在哪里。使用 pandas 的 dropna 函数,可以从数据中删除包含大量无意义缺失值的行或列。让我们来看看最重要的参数:

  • : 0 为行,1 为列
  • tresh :非 NaN 的不删除一行或一列的数目
  • 就地:更新框架

我们通过删除所有只有缺少值的行( =0)来更新数据集。注意,在这种情况下,除了将 tresh 设置为 1,您还可以将 how 参数设置为*‘all’*。结果,我们的第二个样本被丢弃,因为它只包含丢失的值。请注意,为了方便起见,我们重置了索引并删除了旧的索引列。

X.dropna(axis=0, thresh=1, inplace=True)X.reset_index(inplace=True)X.drop(['index'], axis=1, inplace=True)

让我们创建一些额外的布尔特征,告诉我们样本是否缺少某个特征的值。首先从 sklearn.impute 导入 MissingIndicator (注意需要版本 0.20.0 )(用'conda update sci kit-learn'更新)。

不幸的是,缺失指示器不支持多种类型的缺失值(参见 Stackoverflow 上的这个问题)。因此,我们必须将数据帧中的 999 值转换为 NaN 值。接下来,我们创建、拟合并转换一个 MissingIndicator 对象,该对象将检测数据中的所有 NaN 的

从这个指示符,我们可以创建一个新的数据帧,用布尔值表示一个实例是否缺少某个特性的值。但是为什么我们只有两个新专栏,而我们有三个原始功能?删除第二个样本后, f2 不再有缺失值。如果缺失指示器没有检测到特征中的任何缺失值,它不会从该特征创建一个新特征。

我们稍后会将这个新特性添加到我们的原始数据中,现在我们可以将它们存储在指示器变量中。

from sklearn.impute import MissingIndicatorX.replace({999.0 : np.NaN}, inplace=True)indicator = MissingIndicator(missing_values=np.NaN)indicator = indicator.fit_transform(X)indicator = pd.DataFrame(indicator, columns=['m1', 'm3'])

在决定保留(一些)缺失值并创建缺失值指示器后,下一个问题是是否应该替换缺失值。当缺失值被表示为而不是数字 ( np)时,大多数学习算法表现不佳。NaN )并且需要某种形式的缺失值插补。要知道有些库和算法,比如 XGBoost可以处理缺失值,通过学习自动估算这些值。

输入值

为了用通用策略填充缺失值,sklearn 提供了一个简单估算器。四个主要策略是均值最频繁中值常量(不要忘记设置填充值参数 ) 。在下面的例子中,我们用特征的平均值估算数据框架 X 的缺失值。

from sklearn.impute import SimpleImputerimp = SimpleImputer(missing_values=np.nan, strategy='mean')imp.fit_transform(X)

注意,返回的值被放入一个 Numpy 数组,我们丢失了所有的元信息。由于所有这些策略都可以在 pandas 中模仿,我们将使用 pandas fillna 方法来估算缺失值。对于表示的‘T28’,我们可以使用下面的代码。这个 pandas 实现还提供了向前填充( ffill )或向后填充(bfil)的选项,这在处理时间序列时非常方便。

X.fillna(X.mean(), inplace=True)

其他常用的估算缺失数据的方法是用 k 近邻 (KNN) 算法对数据进行聚类,或者使用各种插值方法对值进行插值。这两种技术都没有在 sklearn 的预处理库中实现,这里就不讨论了。

多项式特征

创建多项式要素是一种简单而常用的要素工程方法,它通过组合要素来增加数字输入数据的复杂性。

当我们想要包含特征和目标之间存在非线性关系的概念时,通常会创建多项式特征**。它们主要用于增加几乎没有特征的线性模型的复杂性,或者当我们怀疑一个特征的效果依赖于另一个特征时。**

在处理缺失值之前,您需要决定是否要使用多项式要素。例如,如果您将所有缺少的值替换为 0,则使用此功能的所有叉积都将为 0。此外,如果不替换丢失的值( NaN ),创建多项式特征将在 fit_transform 阶段产生值错误,因为输入应该是有限的。

在这方面,用中值或平均值代替缺失值似乎是一个合理的选择。由于我对此并不完全确定,也找不到任何一致的信息,我在数据科学 StackExchange 上问了这个问题。

Sklearn 提供了一个多项式特征类来从头创建多项式特征。次数参数决定多项式的最大次数。例如,当设置为 2 且 X=x1,x2 时,创建的特征将为 1,x1,x2,x1,x1x2 和 x2。 interaction_only 参数让函数知道我们只需要交互特性,即 1、x1、x2 和 x1x2。

这里,我们创建了三次多项式特征,也是唯一的交互特征。结果我们得到四个新特征: f1.f2f1.f3f2.f3f1.f2.f3 。请注意,我们的原始特征也包含在输出中,并且我们会切掉新特征,以便稍后添加到我们的数据中。

from sklearn.preprocessing import PolynomialFeaturespoly = PolynomialFeatures(degree=3, interaction_only=True)polynomials = pd.DataFrame(poly\
                           .fit_transform(X), 
                           columns=['0','1','2','3', 
                                    'p1', 'p2', 'p3', 'p4'])\
                                        [['p1', 'p2', 'p3', 'p4']]

正如任何其他形式的特征工程一样,在进行任何特征缩放之前,创建多项式特征是很重要的。

现在,让我们用 pandas concat 方法将新的缺失指标特征和多项式特征连接到我们的数据中。

X = pd.concat([X, indicator, polynomials], axis=1)

Dataframe with original features (f), missing value indicators (m) and polynomial features (p)

分类特征

分类数据的筛选是数据预处理过程中的另一个重要过程。不幸的是, sklearn 的机器学习库不支持处理分类数据。即使对于基于树的模型,也有必要将分类特征转换成数字表示

在开始转换数据之前,确定您正在处理的要素是否是有序的(相对于名义的)非常重要。有序特征最好描述为具有自然有序类别的特征,类别之间的距离未知

一旦你知道你正在处理什么类型的分类数据,你就可以选择一个合适的转换工具。在 sklearn 中,将有一个用于序数数据的 OrdinalEncoder ,以及一个用于名义数据的 OneHotEncoder

让我们考虑一个简单的例子来演示这两个类是如何工作的。创建一个具有五个条目和三个特征的数据框架:性别血型教育程度

X = pd.DataFrame(
    np.array(['M', 'O-', 'medium',
             'M', 'O-', 'high',
              'F', 'O+', 'high',
              'F', 'AB', 'low',
              'F', 'B+', np.NaN])
              .reshape((5,3)))X.columns = ['sex', 'blood_type', 'edu_level']

查看数据框架,您应该注意到教育水平是唯一的顺序特征(可以排序,类别之间的距离未知)。我们将从用 OrdinalEncoder 类编码这个特性开始。导入该类并创建一个新实例。然后通过将该特征拟合并转换到编码器来更新教育水平特征。结果应该如下所示。

from sklearn.preprocessing import OrdinalEncoderencoder = OrdinalEncoder()X.edu_level = encoder.fit_transform(X.edu_level.values.reshape(-1, 1))

注意这里我们有一个相当烦人的问题:我们丢失的值被编码成一个单独的类(3.0) 。仔细阅读文档可以发现,这个问题还没有解决方案。一个好的迹象是, sklearn 开发者正在讨论实现一个合适的解决方案的可能性。

另一个问题是我们的数据顺序没有得到尊重。幸运的是,这可以通过将特性的唯一值的有序列表传递给类别参数来解决。

encoder = OrdinalEncoder(categories=['low', 'medium', 'high'])

要解决第一个问题,我们必须求助于熊猫。因式分解方法提供了一种替代方法,可以处理缺失值并尊重我们的值的顺序。第一步是将特征转换为有序熊猫分类。传递一个类别列表(包括缺失值的类别)并将有序参数设置为

cat = pd.Categorical(X.edu_level, 
                     categories=['missing', 'low', 
                                 'medium', 'high'], 
                     ordered=True)

缺失类别替换缺失值。

cat.fillna('missing')

然后,将分类参数设置为分类进行因式分解,并将输出分配给教育水平特征。

labels, unique = pd.factorize(cat, sort=True)X.edu_level = labels

这一次的结果更令人满意,因为数据是数值型的,仍然是有序的,缺失值被替换为 0。请注意,用最小值替换缺失值可能并不总是最佳选择。其他选项是将其放在最常见的类别中,或者在特征分类时将其放在中间值的类别中

现在让我们转向另外两个,名义特征。请记住,我们不能用数字来代替这些特征,因为这意味着这些特征是有顺序的,这在性别或血型的情况下是不正确的。

最流行的标称特征编码方式是一次热编码。本质上,具有 n 个类别的每个分类特征被转换成 n 个二元特征

让我们看一下我们的例子,把事情弄清楚。首先导入 OneHotEncoder 类,并创建一个新实例,将输出数据类型设置为 integer。这不会改变我们的数据将如何被解释,但会提高我们输出的可读性。

然后,拟合并转换我们的两个名义范畴。这个转换的输出将是一个稀疏矩阵,这意味着我们必须将矩阵转换成一个数组()。toarray() )才能将其倒入数据帧中。当初始化一个新的类实例时,可以通过将稀疏参数设置为来省略这个步骤。分配列名,输出就可以添加到其他数据中了( edu_level 特性)。

from sklearn.preprocessing import OneHotEncoderonehot = OneHotEncoder(dtype=np.int, sparse=True)nominals = pd.DataFrame(
    onehot.fit_transform(X[['sex', 'blood_type']])\
    .toarray(),
    columns=['F', 'M', 'AB', 'B+','O+', 'O-'])nominals['edu_level'] = X.edu_level 

将输出(名词)与我们的原始数据进行比较,以确保一切都以正确的方式进行。

Encoded data versus original data

因为我们的数据中没有丢失值,所以说明如何用onehotencode处理丢失值是很重要的。丢失的值可以很容易地作为一个额外的特性来处理。注意,要做到这一点,您需要首先用一个任意值替换丢失的值(例如,‘missing’)如果您另一方面想忽略丢失的值并创建一个全为零的实例( False ),您只需将 OneHotEncoderhandle _ unknown参数设置为 ignore

数字特征

就像分类数据可以被编码一样,数字特征可以被“解码”成分类特征。最常见的两种方法是离散化二值化

[数]离散化

离散化,也称为量化或宁滨,将连续特征分成预先指定数量的类别(箱),从而使数据离散。

离散化的主要目标之一是显著地减少连续属性的离散区间的数量。因此,为什么这种转换可以提高基于树的模型的性能。

Sklearn 提供了一个 KBinsDiscretizer 类来处理这个问题。您唯一需要指定的是每个特征的面元数量(n _ 面元)以及如何对这些面元进行编码(序数一个热点一个热点密集)。可选的策略参数可以设置为三个值:

  • 统一,其中每个特征中的所有箱具有相同的宽度。
  • *分位数(*默认),其中每个特征中的所有条柱具有相同的点数。
  • k 均值,其中每个箱中的所有值都具有相同的 1D k 均值聚类的最近中心。

小心选择策略参数很重要。例如,使用统一策略对异常值非常敏感,会使您最终得到只有几个数据点的条柱,即异常值。

让我们转向我们的例子来进行一些澄清。导入 KBinsDiscretizer 类并创建一个新实例,该实例具有三个 bin、序号编码和统一策略(所有 bin 都具有相同的宽度)。然后,拟合并转换我们所有原始的、缺失的指标和多项式数据。

from sklearn.preprocessing import KBinsDiscretizerdisc = KBinsDiscretizer(n_bins=3, encode='uniform', 
                        strategy='uniform')disc.fit_transform(X)

如果输出对您没有意义,调用离散化器(圆盘)上的 bin_edges_ 属性,看看这些面元是如何划分的。然后尝试另一种策略,并查看面元边缘如何相应地变化。

Discretized output

二值化

特征二值化是对数字特征进行阈值处理以获得布尔值的过程。或者换句话说,基于阈值给每个样本分配一个布尔值()。注意,二进制化是二进制离散化的极端形式。

总的来说,二值化作为一种特征工程技术是有用的,用于创建新的特征来表示有意义的东西。就像上面提到的缺失指示器用来标记有意义的缺失值。

sklearn 中的二进制化器类以非常直观的方式实现二进制化。您需要指定的唯一参数是阈值复制。所有低于或等于阈值的值被替换为 0,高于阈值的值被替换为 1。如果复印设置为,则执行原位二值化,否则进行复印。

考虑我们示例中的特征 3 ( f3 ),让我们创建一个额外的二元特征,对于正值使用,对于负值使用。导入二进制化器类,创建一个阈值设置为零的新实例,并复制到 True 。然后,将二进制化器安装并转换到*特征 3。*输出是一个带有布尔值的新数组。

from sklearn.preprocessing import Binarizerbinarizer = Binarizer(threshold=0, copy=True)binarizer.fit_transform(X.f3.values.reshape(-1, 1))

定制变压器

如果您想将现有的函数转换成转换器,以帮助数据清理或处理,您可以使用 FunctionTransformer 从任意函数实现转换器。如果你正在使用 sklearn 中的管道,这个类可能会很有用,但是可以很容易地通过将 lambda 函数应用到你想要转换的特征来替换(如下所示)。

from sklearn.preprocessing import FunctionTransformertransformer = FunctionTransformer(np.log1p, validate=True)transformer.fit_transform(X.f2.values.reshape(-1, 1)) #same outputX.f2.apply(lambda x : np.log1p(x)) #same output

特征缩放

预处理管道中的下一个逻辑步骤是缩放我们的特征。在应用任何缩放变换之前,将你的数据分成一个训练集和一个测试集是非常重要的。如果您之前就开始缩放,您的训练(和测试)数据可能会围绕一个平均值(见下文)进行缩放,而这个平均值实际上并不是训练或测试数据的平均值,从而忽略了您最初缩放的全部原因。

标准化

标准化是一种转换,通过移除每个特征的平均值来集中数据,然后通过将(非恒定)特征除以它们的标准偏差来缩放数据。标准化数据后,平均值为零,标准偏差为一。

标准化可以极大地提高模型的性能。例如,学习算法的目标函数中使用的许多元素(如支持向量机的 RBF 核或线性模型的 l1 和 l2 正则化子)假设所有特征都以零为中心,并且具有相同顺序的方差。如果某个特征的方差比其他特征的方差大几个数量级,那么它可能会主导目标函数,使估计器无法像预期的那样正确地从其他特征中学习。

根据你的需求和数据,sklearn 提供了一堆定标器:标准定标器最小最大定标器最大最小定标器鲁棒定标器

标准缩放器

Sklearn 它的主定标器 StandardScaler 使用一个严格的标准化定义来标准化数据。它通过使用以下公式纯粹地将数据居中,其中 u 是平均值, s 是标准偏差。

x _ scaled =(x-u)/s

让我们看看我们的例子,看看这在实践中。在我们开始编码之前,我们应该记住我们的第四个实例的值是缺失的,我们用平均值代替了它。如果我们在上面的公式中输入平均值,标准化后的结果应该为零。我们来测试一下。

导入 StandardScaler 类并创建一个新实例。请注意,对于稀疏矩阵,您可以将 with_mean 参数设置为 False 以避免数值集中在零附近。然后,将定标器安装并转换至特征 3

from sklearn.preprocessing import StandardScalerscaler = StandardScaler()scaler.fit_transform(X.f3.values.reshape(-1, 1))

不出所料,第四个实例的值为零。

Ouput of standard scaling feature 3

最小最大缩放器

最小最大缩放器通过将每个特征缩放到给定范围来变换特征。该范围可以通过指定特征范围参数来设置(默认为 (0,1) )。此缩放器更适合非高斯分布或标准偏差非常小的情况。然而,它对异常值很敏感,所以如果数据中有异常值,你可能需要考虑另一个缩放器。

x _ scaled =(x-min(x))/(max(x)-min(x))

导入和使用最小最大缩放器的工作方式与标准缩放器完全相同——就像下面所有的缩放器一样。唯一的区别在于启动新实例时的参数。

这里我们将特征 3 ( f3 )缩放到-3 和 3 之间的比例。正如所料,我们的最大值( 25 )被转换为 3,最小值(- 1 )被转换为-3。所有其他值在这些值之间线性缩放。

from sklearn.preprocessing import MinMaxScalerscaler = MinMaxScaler(feature_range=(-3,3))scaler.fit_transform(X.f3.values.reshape(-1, 1))

Feature 3 before and after applying the MinMaxScaler

MaxAbs 定标器

maxabscaler的工作方式与 MinMaxScaler 非常相似,但会根据绝对最大值自动将数据缩放至 [-1,1] 范围。该缩放器用于已经以零为中心的数据或稀疏数据。它不会移动/居中数据,因此不会破坏任何稀疏性。

x_scaled = x / max(abs(x))

让我们再次使用maxabscaler特性 3 进行转换,并将输出与原始数据进行比较。

from sklearn.preprocessing import MaxAbsScalerscaler = MaxAbsScaler()scaler.fit_transform(X.f3.values.reshape(-1, 1))

Feature 3 before and after applying the MaxAbsScaler

鲁棒定标器

如果您的数据包含许多异常值**,使用数据的平均值和标准偏差进行缩放可能不会很好。在这些情况下,您可以使用鲁棒定标器移除中间值,并根据分位数范围缩放数据。文档中没有规定鲁棒定标器的确切公式。如果你想要完整的细节,你可以随时查看源代码。**

默认情况下,缩放器使用四分位数范围(IQR),即第一个四分位数和第三个四分位数之间的范围。当启动鲁棒定标器的新实例时,可以通过指定 quantile_range 参数来手动设置分位数范围。这里,我们使用从 10%90% 的分位数范围来变换特征 3

from sklearn.preprocessing import RobustScalerrobust = RobustScaler(quantile_range = (0.1,0.9))robust.fit_transform(X.f3.values.reshape(-1, 1))

正常化

归一化是指将单个样本缩放至单位范数的过程。基本上,当算法根据数据点之间形成的加权关系进行预测时,您需要对数据进行规范化。将输入缩放到单位规范是文本分类或聚类的常见操作。

缩放(例如标准化)和规格化之间的一个关键区别是规格化是一个行操作**,而缩放是一个列操作。**

虽然有许多其他方法来归一化数据,但是 sklearn 提供了三个范数(与单个值进行比较的值): l1l2max 。创建规格化器类的新实例时,可以在规格化参数下指定所需的规格化。

下面,可用范数的公式将在 Python 代码中讨论和实现——结果是数据集 X 中每个样本的分母列表。

马克斯

最大值范数使用绝对最大值,对样本的作用与最大值缩放器对特征的作用相同。

x_normalized = x / max(x)

norm_max = 
list(**max**(list(abs(i) for i in X.iloc[r])) for r in range(len(X)))

l1 '

l1 范数使用所有值的总和作为,因此给予所有参数相等的惩罚,加强稀疏性。

X _ 规格化= x / sum(X)

norm_l1 = 
list(**sum**(list(abs(i) for i in X.iloc[r])) for r in range(len(X)))

l2 '

l2 范数使用所有平方值之和的平方根。这创建了平滑和旋转不变性。一些模型,如 PCA,假设旋转不变性,因此 l2 将执行得更好。

X _ normalized = X/sqrt(sum((I * * 2)for I in X))

norm_l2 = 
list(math.sqrt(sum(list((i**2) for i in X.iloc[r]))) 
 for r in range(len(X)))

——请随时在评论中或私信中告诉我任何不一致或错误。—

来源

** [## 4.3.预处理数据-sci kit-学习 0.20.1 文档

例如,学习算法的目标函数中使用的许多元素(如支持向量机的 RBF 核…

scikit-learn.org](https://scikit-learn.org/stable/modules/preprocessing.html#preprocessing) [## 规范化数据-人工智能系列的第一部分

swaathi.com](https://swaathi.com/2017/04/29/normalizing-data/) [## 人工智能神经网络常见问题,第 2 部分,共 7 部分:学习部分——我是否应该标准化/规范化/重新调整

人工智能神经网络常见问题,第 2 部分,共 7 部分:学习部分——我是否应该标准化/规范化/重新调整

人工智能神经网络常见问题,第 2 部分,共 7 部分:学习部分——我应该标准化/规范化/重标 thewww.faqs.org 吗](http://www.faqs.org/faqs/ai-faq/neural-nets/part2/section-16.html) [## 使用 Python 的机器学习食谱

量化数据是对某些东西的度量——无论是班级规模、月销售额还是学生成绩。自然的方式…

www.oreilly.com](https://www.oreilly.com/library/view/machine-learning-with/9781491989371/ch04.html) [## 如何使用 Scikit-Learn 为 Python 中的机器学习准备数据

许多机器学习算法会对你的数据做出假设。在…中准备数据通常是一个非常好的主意

machinelearningmastery.com](https://machinelearningmastery.com/prepare-data-machine-learning-python-scikit-learn/) [## 标准化还是常态化?Python 中的示例

一个常见的误解是,什么是标准化数据以及何时标准化数据与标准化日期之间的区别。

medium.com](https://medium.com/@rrfd/standardize-or-normalize-examples-in-python-e3f174b65dfc) [## 使用 scikit-learn 扩展功能

在这篇文章中,我们探索了 scikit-learn 中实现的 3 种特征缩放方法:标准缩放器假设…

benalexkeen.com](http://benalexkeen.com/feature-scaling-with-scikit-learn/)**

用数据保护我们更好的立法者

原文:https://towardsdatascience.com/preserving-our-better-legislators-with-data-3726232f86f6?source=collection_archive---------6-----------------------

你有最喜欢的国会议员吗?在一个支持率非常低的机构中,人们倾向于喜欢他们当地的联邦立法代表。我的情况也不例外;我也开始钦佩我在当地的代表,Ileana Ros-Lehtinen。

除了地区问题,她在拉丁美洲问题上的立法记录给我留下了特别深刻的印象。作为第一位当选国会议员的拉美裔女性,她对外交政策产生了兴趣,并加入了美国众议院外交事务委员会。她作为被卡斯特罗驱逐出古巴的古巴人的背景影响了她的问题观点,但这从未妨碍她在支持拉丁美洲的和平与民主方面有着完美的记录。作为一名哥伦比亚人,我注意到她在 90 年代末帮助控制国家的努力。后来,在国会山工作时,我目睹了她争取国会支持反对委内瑞拉萌芽中的查韦斯/马杜罗独裁政权。类似的行动发现在联邦记录尼加拉瓜,厄瓜多尔等。

众议员 Ros-Lehtinen 将在国会本届会议后退休。作为一个国家,我们将非常怀念她在政治舞台上充满激情的声音和合群的个性。更重要的是,这留下了一个问题:她的追随者会如何看待她的遗产。在这篇文章中,我将利用数据科学为维护她的理想贡献我的一粒沙子。

This is retiring member Ileana Ros-Lehtinen. She has an even happier aura in person.

该项目旨在预测一名长期任职的国会议员退休后将如何投票表决未来的立法。通过使用她在过去 4 届国会会议期间在委员会中发起的法案,我将创建一个预测模型,该模型将输出一个逻辑答案,即在给定文本的情况下,众议员 Ros-Lehtinen 是否会对法案进行投票。

为了利用文本作为特征,我对账单文本执行了计数矢量化以提取特征。这一过程需要做出许多关键决策,例如对计数矢量化结果进行词汇化时丢失的上下文,以及除 NLTK 的“英语”集合中的标准之外的停用词的选择。在适当的时候,我们将法案中的标准语言和法案文本中更具程序性的语言纳入到停用字词阈值中。

计数矢量化的结果数据框将使用 XGBoost 和 Logislitc 回归进行建模,目的是在信号太弱时使用增强方法。

数据字典和清理

这些数据主要是从他们现在已经废弃的(至少是数据部门)阳光基金会美国政府出版办公室ProPublica 收集的。

我从阳光基金会刮出了一份从 2009 年到现在提交给美国众议院外交事务委员会(委员会)的所有法案的清单。在 scrape 中,我保留了几个有助于识别账单的变量,包括计数矢量化的潜在目标,比如账单标题和昵称。

使用账单标识信息,我构建了第二个 scraper,它将迭代第一个 scraper 以获取账单信息,从而从 GPO 下载账单文本。

最后,我使用来自阳光基金会的委员会特定法案的信息来解析 ProPublica 的法案记录。从那里我收集了众议员 Ileana Ros-Lehtinen 赞助或共同赞助的条目。我选择了赞助而不是投票,因为赞助比投票更常见,因为少量的提案会得到投票的考虑。这也表明了个人对拟议立法的语言和内容的更多承诺。

获取必要的数据后,接下来的步骤是为计数矢量化做准备。该法案的文本有很多格式,以纠正空白,并选择该法案的最有用和独特的部分。在运行计数矢量器之前,数据被分离出来,只包含文本和 Ros-Lehtinen 的投票记录。

此时,我执行了一次训练、测试分割,并继续进行数据的计数矢量化。

下图只是字数统计;我分享是因为我觉得很有趣,最常见的话基本上是告诉国务卿该做什么。

Keeping SoS busy

特征和模型选择

鉴于项目的范围和我收集的数据,我选择了以下特征来构建模型。

主要特征是应用于账单文本语料库的词汇化计数 Verctorization 的结果。所使用的案文正文被删除了法案的序言(包括提案国和共同提案国,以及将法案提交委员会的程序),以及诸如符号和章节编号等非文字部分。除了计数矢量化之外,我还使用虚拟变量来表示条目是哪种法规(HR、HRES、S 等。).

当然,回应变量是众议员罗斯-莱蒂宁的一个衡量标准。然而,考虑到提交给委员会的法案和正在进行表决的法案之间的交集非常少,我不得不使用一个不同的参数。为此,我选择提案或共同提案一项法案。因此,响应类的数量上升到数据的大约 15%。使用这个标准还可以防止我错过以语音投票形式出现的数据点。口头投票在普遍认可的立法中很常见,反对党有义务要求投赞成票和反对票,以便将这些投票立场纳入联邦登记册。

为了解决班级失衡问题,我所做的最积极的决定是增加我的积极回应,以匹配我的消极回应。我通过替换重采样和设置参数来实现这一点,这样每个类平均分为 2150 个条目。在使用这个数据集构建模型之后,我将恢复到最初的数据集,并在模型中运行它。基于此的报告将是我的模型评分的一部分。

A reminded of how, and in which order, to deal with highly unbalanced classes, courtesy of the one and only Chris Albon. If his website is not among your most visited, make it a thing.

有了我的数据和响应变量,我建立了几个分类模型,看看哪种算法最能突出我的响应变量。

结果

即使有模型和矢量器组合的排列数,模型也难以获得高于 60%的 AUC 分数。使用计数矢量器、TFIDF 矢量器以及 KNeighbors、逻辑回归、Bernoulli 朴素贝叶斯、多项式朴素贝叶斯、XGBoost 和 Random Forest 模型,我寻找可能的最佳评分模型。准确性总是很高,但是根据混淆矩阵和 AUC 评分,模型不断将结果偏向非常低的阳性预测数。

经过上述的上采样后,我的模型的结果得到了改善。当我在 upsampled-made 模型中传递原始数据时,我发现**精确度和计算效率的最佳平衡是对 TF-IDF 矢量化文本运行逻辑回归。**XGBoost 模型的结果也显示了类似于逻辑回归的前景,但不足以证明其缓慢的表现。

所选逻辑回归模型的最终交叉验证准确度和 AUC 度量为 82%准确度和. 69% AUC。我感到矛盾,因为这略低于我所声明的达到. 70 AUC 分数的目标,但精度远远高于我的原始目标,我觉得概念证明已经实现,并需要使用更合适的自然语言处理工具进行进一步开发。

A model feature importance; for those who are curious about which terms mattered most.

估价

在投票行为并不总是被记录的议会系统中,预测投票行为的任务是棘手的。此外,立法通常由工作人员以历史悠久的方式构建,因此减少了文本矢量器在预测投票成员的感受或风格方面的影响。然而,我确实相信,在对文本的分析中,有足够的信号表明他们将支持什么样的立法。

在具体参考我的结果和评估我的实验时,我对我的目标变量中的积极响应的低召回值感到担忧。该模型对比尔赞助回忆的得分为 0.45,这确实给我的结果和断言蒙上了一层阴影,但我相信其他 NLP 工具将有助于纠正这一错误。

Final results of my original data when applied to the models made with upsampled dataset. The model was a logistic regression with a TF-IDF vectorization.

随后的分析将加深对基于立法文本的投票行为的理解,该分析将运行无监督学习算法,例如 LDA。将这个项目的模型和 LDA 部署为一个集成系统是不可能的,但它将深化主题专业知识,并为未来的模型开发提供见解。

最后的想法

我将继续致力于这个项目,以更好地预测投票/赞助行为。我还有本届国会会议的剩余时间来进一步测试这个模型;更确切地说是拉丁美洲的钞票,这也是这个项目最初的预期。我还将制作一个针对具体问题划分的法案子集,看看我的模型在某些子集上是否更好。

从文本分析的角度看媒体吹风会:川普总统与中国***的会晤

原文:https://towardsdatascience.com/press-briefing-through-the-lens-of-text-analytics-president-trumps-meetings-with-president-xi-of-a0d8eabe0f08?source=collection_archive---------5-----------------------

特朗普总统和中国总理 Xi 上周在美国的会晤是全世界关注和报道的最重要事件之一。会后,白宫博客发布了秘书们关于这次会议的简报,可以在这个公共领域找到。

首先,当你阅读时,我觉得新闻发布会是一个相当长的内容,因为峰会的复杂性和重要性。其次,一些关键的含义可能隐藏到普通人的眼睛和头脑才能理解。所以,这里有一个基于文本分析的方法,我用它来从简报中理解会议的重要性。

进场:

我首先将新闻简报的内容(不包括问题)分成三个部分,这三个部分可以提供过去、现在和未来的线索。然后,我查看具体的上下文,如找到重要的单词、语言风格、情感等,以获得更好的理解。

在这篇文章中,我将只涉及我观察到的现在和未来的相关方面。整个发现和观察对我来说花了大约 30 分钟,使用了我在公司建立的技术框架,并基于我从经验中使用的特定技术。

文本分析

文本发现到现在的语境

*正如在座各位所知,今天显然是一个完美的天气,这对夫妇来说是一个很好的机会,可以真正了解彼此,享受,一起用餐,并就重要问题开展工作。
*当然,我们在这里有代表,他们也能够为我们未来的许多工作建立重要的关系。我想我真正想让你了解的是,两位领导人之间的气氛和化学反应是积极的。
*因此,我认为我们所有人都对本次峰会的成果感到非常满意,因为它为未来奠定了非常有建设性的基调。
*双方注意到了朝鲜武器计划威胁的紧迫性,重申了
*我认为,从他们的角度来看,他们都认为朝鲜核能力的发展已经到了非常严重的阶段。但是为了实现这一点,朝鲜的姿态必须改变,才有对话或讨论的基础。

文本发现到未来语境

*我会先说总统非常高兴在 Mar-a-Lago 主持这两天。正如在座的各位所知,今天显然是一个完美的天气,这对总统和他们的妻子来说是一个很好的机会,可以真正了解彼此,享受,一起用餐,并就重要问题开展工作。
*我可以告诉你,交流是非常坦率的。两国总统回顾了双边关系的现状,并指出共同努力取得有益于两国公民的积极成果的重要性。
*总统强调了采取具体措施为美国工人创造公平竞争环境的必要性,反复强调了互惠市场准入的必要性。
*没有讨论过解决这个问题的一揽子安排。他们讨论了给两国带来的挑战,但是我们有一个真正的承诺,那就是共同努力,看看这个问题是否能以和平的方式解决。
*但为了实现这一目标,朝鲜必须改变姿态,才有对话或讨论的基础。
*川普向***表示,他欢迎***和中国关于我们可以采取的其他行动的任何想法,我们很高兴与他们合作,但我们知道这对他们造成了独特的问题和挑战,如果这是我们无法协调的事情,我们将准备好规划我们自己的道路。他们致力于朝鲜半岛无核化,并致力于全面执行联合国安理会决议。

接下来,参照会议的当前语境,让我们看看动作动词、语境词、语言风格、情绪和情感

动作动词(现在&未来语境)

  • 现在动作动词单词**‘Have’指向朝鲜(对象)的武器和姿势的拥有,单词‘Think’**指向表达对峰会的看法或印象。所以,从主观上来说,这表明当前峰会的背景与朝鲜有关,反映了对峰会/其目标的看法。
  • 接下来,与将来动作动词相关的语境词指向 【变化】 朝鲜现在的姿态中预期的方面、**【解决】朝鲜问题。为美国工人创造一个' '平等' '的竞争环境, 【采取】 基于双方想法的行动,以及【产生】**共同努力的积极成果..

所以现在到未来的语境从**‘思考’的世界转移到‘表演’**

在当前和未来方面发现的重要术语:

下面显示了我应用算法从过去和未来时态文本内容中发现重要术语而生成的单词云。单词的大小表示在上下文中与其他单词的相对重要性。

  • 目前的背景表明了朝鲜姿态的重要性,以及通过此次会议解决除峰会环境问题之外的其他问题的大好机会。
  • 未来的背景很有趣。它指出,与中国合作的经济、市场方面/增长与通过联合国安理会决议实现朝鲜半岛无核化同等重要。

简报的语言风格和情感基调

  1. 当前上下文

语言风格:理性(83%)和自信(90%)
**情感基调:**喜悦(58%)、厌恶(50%)显著
*语言的这种高度逻辑推理和确定性取向,表明简报中的事实和确信的可能性较高。然后,积极和消极情绪的存在都有快乐的阴影,以及对与朝鲜方面有关的东西的厌恶和反感。快乐是拥抱机会,厌恶是摆脱或驱逐武器场景。

2。未来背景

语言风格:理性(64%)。肯定的或试探性的感觉——:不存在
**情绪基调:**喜悦(59%)、悲伤(53%)是显著的
*逻辑推理表明陈述中的分析取向,而不是含糊或猜测的工作类陈述。那么积极情绪和消极情绪的存在就有快乐和悲伤的阴影。(具有相反极性的情感)。快乐意味着通过联合关系活动实现或获得利益的机会,而悲伤则是需要“做出改变”才能变得快乐的方面的指示器。悲伤是一种长期的情绪,而愤怒或厌恶则有短期的倾向。因此,这种情绪为可能必须做出的重大改变/行动提供了线索,以实现长期目标(参考上面的词语云:互惠市场行动、双边关系、遵守安全理事会决议)

摘要

文本分析有助于为这样的新闻简报文档带来不同的视角,并获得更好的见解。关于内容的分析,

  • 从简报中发现的当前背景为峰会有关两国合作和朝鲜问题的**“思考/焦点”**方面提供了线索。
  • 发现的未来背景为与市场/经济增长相关的**【行动要点】**提供线索,期望改变朝鲜半岛的安全局势,并致力于双边关系。

更新:4 月 11 日- 今天看到这条新闻很有趣中国将派遣 15 万军队应对可能出现的情况。

声明:
此处提及的观点均为本人观点。
本文使用的数据来自公共领域的可用信息。但对其准确性、完整性、及时性或正确性不做任何明示或暗示的陈述或保证。我不对任何错误或不准确负责,不管是什么原因造成的。(读者)。

用 Python 假装了解 NBA

原文:https://towardsdatascience.com/pretending-to-know-about-the-nba-using-python-699177a58685?source=collection_archive---------11-----------------------

如何在不剥夺睡眠的情况下跟踪每年 1300 场 NBA 比赛?在NBA . papiotis . info查看结果,如果你对背景故事感到好奇,请继续阅读。

我从来都不是一个喜欢运动的人。正如大多数认识我的人可能猜到的那样,我更喜欢坐在电脑前,试图解决一些(自己造成的)编程难题,或者玩视频游戏。事实上,我作为一个“体育迷”的第一次经历是关注 DOTA2 电子竞技,也就是说,看人们玩电子游戏比我玩得好得多。

The Greek Freak casually flying over a 1.98m man.

然而,在 2018 年初,我的注意力被篮球神童扬尼斯·阿德托昆博(又名希腊怪胎)所吸引。对于那些不了解他的人来说,詹尼斯是一名尼日利亚血统的希腊篮球运动员,23 岁的他正在 NBA 掀起巨大的涟漪。詹尼斯在雅典艰难的条件下(轻松地说)成长,进入 NBA,并以其令人难以置信的运动能力成为联盟中最好的球员之一,不断给球迷和分析师带来惊喜,这真的激励我去了解更多关于他的进步。

当然,这意味着我必须了解 NBA 是如何运作的,更重要的是,找到一种方法来跟踪每个赛季大约 1300 场比赛。让我们暂时记住这个数字: 1300。火柴。这还没有考虑到这样一个事实,对于生活在西欧的人来说,大多数比赛都在 02:00 到 04:00 之间开始——这不是一个理想的场景,除非你是一个失眠症患者。

所以,我找到了一个新的标题:一个简单、容易理解的 NBA 比赛摘要,人们可以简单地浏览一下,并立即感受到比赛的进展。

外面有什么

在深入研究原型制作之前,我想先了解一下已经可用的东西——还有什么比直接找到来源更好的方法呢:NBA 自己的统计页面

Thanks NBA, I totally understand all of these.

现在,让我澄清一下:我很感谢 NBA 统计页面。它本质上是一个开放的海量数据存储库,任何人都可以通过各种方式进行咨询,以获得关于这个季节的深入信息。但是你知道 NBA 的统计页面有什么不好吗?

新人。

NBA 统计页面充斥着带有神秘缩写名称的统计数据,对于新人来说,这根本不是一个了解昨晚比赛的好地方。甚至每场比赛的盒子分数(结果总结)也向你显示了最终分数,每个季度末的分数,然后是一系列我的 NBA 新手大脑无法处理的数字和字母。

Me trying to understand the stats page for a single match.

当然,最后的分数可以告诉你谁赢了,但是每天有 5-10 场比赛,那只是一个数字。它不会告诉你这场比赛是否有趣到足以让你去看视频集锦或者看完整场比赛;它没有传达很酷的故事情节,比如一个队在整场比赛落后后在最后一分钟获胜。

浏览了一下,我发现了一些更好的选择,如爆米花机的 GameFlow 或 basketball-reference.com 的。这些更受欢迎,传达了游戏进展的感觉,但仍然充满了我无法理解的统计数据,在我看来,有点刺眼。

Popcorn Machine’s GameFlow: much better, but still too ‘stats-y’ for my taste.

因此,基于我自己的需求和对当前产品的想法,我开始为我想做的东西确定一些要求:

  • **简单。**没有统计数据,没有深入的信息。反正我是不会理解的(至少在那一点上不会)!如果有人想找到详细的统计数据,已经有很多很好的选择。
  • 目测。只要看一眼摘要就能知道比赛中发生了什么。此外,最终结果应该是光滑和悦目的,因为这个想法是每天检查多个摘要。
  • 互动。由于把可视化做得太简单,我冒了让它变得肤浅和无趣的风险。交互性可以让我为用户增加一些额外的奖励,而不用一开始就把它推到他们面前。

我做了什么

最终结果可在 nba.papiotis.info 获得。它看起来是这样的:

Example visualization for a match. The difference in score is plotted as a line along time, with markers for each successful shot. The color of the line and markers change according to which team is ahead at any given moment.

你可以从日历中选择一个日期,下拉菜单会列出该日期的所有 NBA 比赛**。选择一个匹配项会在下面显示出来。为了方便起见,当您第一次打开页面时,会自动选择最近的匹配项,这样就可以很容易地快速查看最新的匹配项,如果您想赶上进度,还可以返回旧的匹配项。**

可视化本身是一条线代表两队之间的比分差异,每一次成功射门都有标记。我决定使用分数差,因为这样很容易看出谁领先,以及领先多少。这样,一条在整场比赛中始终高于零的线显示了一场一边倒的比赛,主队在整场比赛中占据主导地位;相反,一条不断在零附近振荡的线表明比赛很接近,两队都没有取得绝对领先。为了避免混淆图的哪一侧对应于哪支球队,每支球队的标志都显示在图的右侧。

An eventful first period in the Timberwolves vs. Pacers match from 22/10/2018.

线和标记的颜色会随着时间的推移而变化,这取决于哪支球队领先,通过查看可视化标题,您可以快速看出哪种颜色对应于哪支球队——在左侧的示例中,明尼苏达森林狼队主场迎战印第安纳步行者队。看看这条线的颜色是如何渐变的,从蓝色(森林狼领先),到绿色(比分扳平),最后是黄色(步行者领先)。

如前所述,你可以看到圆形标记,表示每一个成功的拍摄。将鼠标悬停在这些标记上方会给出每个事件的简短描述,如下图所示:

Details about each successful shot are revealed by hovering over with the mouse.

悬停文本为您提供有关当前比分的信息,以及由 NBA API 自动生成的简短文本描述,例如:

格兰特 24 英尺 3 分跳投(8 分)(威斯布鲁克东部时间 4 分)

这告诉我们的是,三分跳投 距离 24 英尺远 把他的 总得分提高到了 8 。他是由助攻 的,包括这个传球在内,到目前为止在比赛中已经给了 4 次助攻 。**

简短的描述有助于快速获得所有必要的信息,而不必像上面的解释性句子那样阅读完整的句子,但它有点枯燥。来点赏心悦目的东西让事情变得更愉快怎么样?

到目前为止,您可能已经注意到,虽然所有的乐谱标记都是圆形的,但其中一些标记填充了颜色,而另一些标记是空的。这是因为点击满标记显示该特定镜头的视频高亮**!**

Clicking on a marker shows a video highlight, as well as a more-human readable description of that play.

**不幸的是,NBA 不会为每一个镜头提供精彩镜头,但平均来说,大约 60%的镜头都伴随着视频精彩镜头。此外,我还解析了短格式的文本描述,并将其转换为更容易阅读的句子,例如: X 在 y 的帮助下完成了转身跳投。这样您可以两全其美:悬停时的快速编码描述,以及点击时对该事件的更丰富的描述。

仅此而已!比赛每小时自动更新一次,当前可用的可视化比赛可以追溯到 2017-2018 赛季初。

我很乐意看到这对其他人有用,所以去 http://nba.papiotis.info/的[开始你的 NBA 吧!](http://nba.papiotis.info/)

可以添加一些很酷的额外功能

虽然快速赶上 NBA 比赛的基本目的已经包含在上面了,但是我不能停止想一些额外的东西&我可能会添加的新功能。以下是我目前为止的一些想法:

  1. 自动集锦卷
    因为我已经有了一个及时订购的视频集锦列表,所以很容易添加一个“显示所有集锦”按钮,一个接一个地播放它们,以创建一个即兴的比赛集锦卷。
  2. 按关键词过滤事件
    如果我能输入“Antetokounmpo dunk”或“Curry 3PT”就能看到詹尼斯扣篮或斯蒂芬·库里投进三分的所有瞬间,岂不是很酷?
  3. **分享比赛和/或集锦
    有时我想分享一场特定的比赛,因为可视化真实地传达了它是如何来回的。或者,浏览视频集锦,看到一些只是很脏,需要分享的东西。我可以分享视频文件本身的链接,但是如果在 URL 栏中有一个显示页面当前状态的代码(比如/m = match id&h = highlight id)就更酷了,它可以立即被复制和分享。

当然,在我实际实现这些之前,它们都是科幻小说——也就是娱乐性的!所以,请在下面的评论中提出你想要的任何建议(或者给我发电子邮件),我们可以一起构思出最酷的 NBA 视觉化东西(但不保证会实现)。

**感谢阅读,

笔记

  1. 在美国体育运动中,传统上客场球队的名字排在第一位,主场球队的名字排在第二位,而在欧洲体育运动中,通常情况正好相反。在意识到这个小怪癖之前,我就开始以欧洲风格开发一切东西,并决定保持这种方式。
  2. 和大多数体育联赛一样,每支球队的特点是多达三种颜色**(主场、客场、替补);为了创造一个漂亮、突出的配色方案,我用 CIE94 公式为客队选择与主队主色最不一样的颜色。**

额外阅读:实现细节

还在读书?酷毙了。这里有一些关于技术部分的细节,以防你好奇。

我毫不怀疑,从一开始,这需要一个基于浏览器的原型。基于不断更新的在线数据的交互式可视化几乎注定要存在于浏览器中;智能手机应用程序是一个不错的选择,但这意味着一些样板文件和部署问题,我并不急于接受。另外,我想在大屏幕上欣赏这个。

现在,有很多开发环境可以开发基于浏览器的软件,但是 Python 几年来一直是我的个人爱好(对 @chaosct 大声喊出来,因为它把我推向了那个方向)。Python 使得在 Jupyter 笔记本中立即开始原型化和尝试不同的东西变得很容易,并且将原型的好的部分转移到部署就绪的解决方案中从来都不是一件痛苦的事情。几乎所有的东西都有记录良好且持续支持的库,还有一个很棒的开发者社区,他们乐于以可重用的方式分享他们的创作。

在用 Matplotlib 的交互模式和散景进行了一些快速研究和测试后,我最终决定使用 plot.ly 来创建可视化效果。大量的文档、示例及其绝对令人惊叹的姐妹框架 Dash 意味着我可以在一个生产就绪的 web 框架内创建强大的交互式可视化,该框架与我的所有其他 Python 代码配合良好,可以抓取、清理和检索匹配数据。

这就把我们带到了下一点:获取数据。NBA 提供了一个 RESTful API,包含每场比赛的统计数据,虽然数据丰富,但几乎没有文档。事实上,现存的少量文档是由与 NBA 无关的其他开发者提供的。我很幸运地发现了 nba_py,一个整洁的 NBA stats API 的小 python 包装器,它为 API 端点提供了一点文档,并与 Pandas 集成,这使得清理和组织数据变得轻而易举。

最大的挑战之一是 NBA 统计 API 在收集了几场比赛的数据后封锁了我的 IP 。NBA 禁止 IP 的方式是简单地让请求无限期挂起,这比得到 403 错误或类似的错误更令人讨厌——这样我就知道我被 IP 阻止了,而不是花大量时间调试,最终发现 NBA 对我冷淡。

除了在家里屏蔽我的个人 IP(没错,我自己不能访问 stats.nba.com),NBA stats API 还会自动屏蔽来自 AWS 或 GCP 等已知提供商的任何 IP。这是一个大问题——我应该在哪里主持这个东西,这样 NBA 就不会阻止它了?如果我把它放在某个地方,只刮了几根火柴就被屏蔽了呢?

最后,我用 Python 编写了一个代理旋转器,这样每个发送到 NBA stats API 的请求都来自不同的 IP。为了避免再次被封锁,我不会透露太多关于具体细节的信息,但如果你很好奇,可以在这里查看这类事情的演练:https://www . screphero . com/how-to-rotate-proxy-and-IP-addresses-using-python-3/

整个 shebang 托管在 Python Anywhere 上,使用起来超级简单,总体来说是一次非常愉快的体验。这项服务很便宜,设置只花了我 10 分钟,在少数情况下,我需要一些客户支持,他们反应很快,很友好。100%推荐!

这大概是对技术栈的总结。如果你对体育数据可视化感兴趣,我推荐 Perin 等人的这篇优秀的综述。

防止深度神经网络过拟合

原文:https://towardsdatascience.com/preventing-deep-neural-network-from-overfitting-953458db800a?source=collection_archive---------0-----------------------

神经网络的秘密第二部分

Source

由于拥有大量的参数(数千个,有时甚至数百万个),神经网络有很大的自由度,可以适应各种复杂的数据集。这种独特的能力使他们能够接管许多在“传统”机器学习时代难以取得任何进展的领域,如图像识别、物体检测或自然语言处理。然而,有时他们最大的优势变成了潜在的弱点。对我们模型的学习过程缺乏控制可能会导致过度拟合的情况,当我们的神经网络与训练集如此接近,以至于很难对新数据进行归纳和预测。理解这个问题的根源和防止它发生的方法,是成功设计神经网络的关键。

**注:**本文是“神经网络的奥秘”系列的第二部分,如果你还没有机会,请阅读的开篇文章。在我的 GitHub 上可以找到用于创建本文中使用的可视化效果的源代码。

你怎么知道你的神经网络过度拟合?

培训、开发和测试设备

在实践中,检测我们的模型是否过度拟合是困难的。我们训练过的模型已经投入生产,然后我们开始意识到有问题,这种情况并不罕见。事实上,只有面对新的数据,你才能确保一切正常运行。然而,在训练过程中,我们应该尽可能地再现真实情况。**出于这个原因,将我们的数据集分成三个部分是一个很好的做法——训练集、开发集(也称为交叉验证或保留)和测试集。**我们的模型通过只看到第一部分来学习。Hold-out 用于跟踪我们的进度,并得出优化模型的结论。同时,我们在训练过程的最后使用测试集来评估我们的模型的性能。使用全新的数据可以让我们对我们的算法有多好有一个公正的看法。

Figure 1. Recommended method of dividing the data set.

确保您的交叉验证和测试集来自相同的分布,以及它们准确地反映了我们期望在未来收到的数据,这一点非常重要。只有这样,我们才能确信我们在学习过程中做出的决策会让我们更接近更好的解决方案。我知道你在想什么…“我应该如何划分我的数据集?”直到最近,最常推荐的拆分之一是 60/20/20,但在大数据时代,当我们的数据集可以计算数百万个条目时,那些固定的比例不再合适。简而言之,一切都取决于我们所处理的数据集的大小。如果我们有数百万个条目可供我们使用,那么将它们以 98/1/1 的比例划分可能会更好。我们的开发和测试集应该足够大,以使我们对模型的性能充满信心。根据数据集大小划分数据集的推荐方法如图 1 所示。

偏差和方差

T 感谢我们对数据的适当准备,我们给了自己评估模型性能的工具。然而,在我们开始得出任何结论之前,我们应该熟悉两个新概念——偏差和方差。为了让我们更好地理解这个有些多么复杂的问题,我们将用一个简单的例子,希望能让我们发展出一种有价值的直觉。我们的数据集由位于二维空间的两类点组成,如图 2 所示。

Figure 2. Visualization of the data set.

由于这是一个简单的演示,这次我们将跳过测试集,只使用训练集和交叉验证集。接下来,我们将准备三个模型:第一个是简单的线性回归,另外两个是由几个紧密连接的层构建的神经网络。如下图 3 所示。我们可以看到使用这些模型定义的分类界限。右上角的第一个模型非常简单,因此具有较高的偏向性,即它无法找到特征和结果之间的所有重要联系。这是可以理解的-我们的数据集有很多噪音,因此简单的线性回归不能有效地处理它。神经网络的表现要好得多,但第一个(显示在左下角)与数据拟合得太过紧密,这使得它在坚持集上的表现明显更差。这意味着它具有很高的方差——它符合噪声,而不符合预期输出。在上一个模型中,这种不良影响通过使用规范化得到了缓解。

Figure 3. Classification boundaries created by: top right corner — linear regression; bottom left corner — neural network; bottom right corner — neural network with regularisation

我知道,我知道……我举的例子很简单——我们只有两个特性,任何时候我们都可以创建一个图表,直观地检查我们模型的行为。当我们在多维空间中操作,数据集包含,比如说,几十个特征,该怎么办?**然后,我们比较使用训练集和交叉验证集计算的误差值。**当然,我们应该追求的最佳情况是这两个集合的低错误率。主要问题是定义什么是低错误率——在某些情况下,它可以是 1%,而在其他情况下,它可以高达 10%或更多。在训练神经网络时,建立一个基准来比较我们模型的性能是很有帮助的。这通常是人类执行这项任务的效率水平。然后,我们试图确保我们的算法在训练期间具有接近我们参考水平的误差。如果我们已经实现了这个目标,但是当我们在坚持集上验证它时,错误率显著增加,这可能意味着我们过度拟合(高方差)。另一方面,如果我们的模型在训练集和交叉验证上表现不佳,它可能太弱,有很高的偏差。当然,这个问题要复杂得多,范围也很广,可以作为单独一篇文章的主题,但是这些基本信息应该足以理解下面的分析。

防止过度拟合的方法

介绍

T 当我们的神经网络具有高方差时,这里有许多方法可以帮助我们。其中的一些,比如获取更多的数据,是相当通用的,每次都能很好的工作。其他的,比如正规化,需要很多技巧和经验。对我们的神经网络施加太多的限制可能会损害它有效学习的能力。现在让我们来看看一些最流行的减少过度拟合的方法,并讨论它们起作用的原因。

L1 和 L2 正规化

O 当我们需要减少过度拟合时,我们应该尝试的第一个方法是规范化。它涉及到在损失函数中增加一个额外的元素,这惩罚了我们的模型过于复杂,或者简单地说,在权重矩阵中使用了过高的值。这样我们试图限制它的灵活性,但也鼓励它基于多种特性构建解决方案。这种方法的两个流行版本是 L1 最小绝对偏差(LAD)和 L2 最小平方误差(LS)。下面给出了描述这些正则化的方程。

在大多数情况下,使用 L1 是更可取的,因为它将不太重要的特征的权重值降低到零,通常从计算中完全消除它们。在某种程度上,它是自动选择特性的内置机制。此外,L2 在含有大量异常值的数据集上表现不佳。值平方的使用导致模型以更受欢迎的示例为代价最小化离群值的影响。

现在让我们看看我们在偏差和方差的例子中使用的两个神经网络。其中一个,正如我前面提到的,我使用正则化来消除过度拟合。我发现这是一个有趣的想法,在三维空间中可视化权重矩阵,并比较正则化和非正则化模型之间获得的结果。我还使用正则化对许多模型进行了模拟,改变了 λ 值,以验证其对权重矩阵中包含的值的影响。(老实说,我这么做也是因为我觉得它看起来超级酷,我不想让你睡着。)矩阵行和列索引对应于水平轴值,权重被解释为垂直坐标。

Figure 4. Visualization of weighing matrix for models without and with regularization.

λ因子及其影响

在之前提到的 L1 和 L2 两个版本的正则化公式中,我引入了超参数λ——也称为**正则化率。**在选择其值时,我们试图在模型的简单性和使其适合训练数据之间找到平衡点。增加 λ 值也会增加正则化效果。在图 4 中。我们可以立即注意到,没有调节的模型和具有非常低的 λ 系数值的模型所获得的平面是非常“湍流”的。有许多具有重要值的峰值。在应用具有较高超参数值的 L2 正则化之后,图形变平。最后,我们可以看到,将 lambda 值设置为 0.1 或 1 左右会导致模型中权重值的急剧下降。我鼓励您检查用于创建这些可视化的源代码。

拒绝传统社会的人

另一种非常流行的神经网络正则化方法是放弃。这个想法其实很简单——我们神经网络的每一个单元(除了属于输出层的单元)都被赋予了在计算中被暂时忽略的概率 p 。超参数 p 被称为辍学率,通常其默认值被设置为 0.5。然后,在每次迭代中,我们根据分配的概率随机选择我们丢弃的神经元。结果,每次我们用一个更小的神经网络工作。下面的可视化显示了一个神经网络遭受辍学的例子。我们可以看到在每次迭代中,第二层和第四层的随机神经元是如何被去激活的。

Figure 5: Visualization of a dropout.

这种方法的有效性是相当令人惊讶和违反直觉的。毕竟,在现实世界中,如果工厂的经理每天随机挑选员工并让他们回家,工厂的生产率就不会提高。让我们从单个神经元的角度来看这个问题。由于在每次迭代中,任何输入值都可能被随机消除,神经元试图平衡风险,而不是偏向任何特征。结果,权重矩阵中的值变得更加均匀分布。该模型希望避免这样的情况,即它提出的解决方案不再有意义,因为它不再有来自非活动特性的信息。

提前停止

下图显示了在学习过程的后续迭代中,在测试和交叉验证集上计算的准确度值的变化。我们马上看到,我们最终得到的模型并不是我们可能创造的最好的。老实说,这比我们经历了 150 个时代还要糟糕得多。为什么不在模型开始过拟合之前中断学习过程?这一观察启发了一种流行的过拟合减少方法,即早期停止。

Figure 6. Change of accuracy values in subsequent epochs during neural network learning.

在实践中,每隔几个迭代就对我们的模型进行采样,并检查它与我们的验证集的工作情况,这是非常方便的。每一个比之前所有模型表现更好的模型都会被保存。我们还设置了一个限制,即没有进展被记录的最大迭代次数。超过该值时,学习停止。尽管早期停止可以显著提高我们模型的性能,但在实践中,它的应用会使我们模型的优化过程变得非常复杂。简直很难和其他常规技术结合。

结论

认识到我们的神经网络过度拟合的能力以及我们可以用来防止这种情况发生的解决方案的知识是最基本的。然而,这些都是非常广泛的主题,不可能在一篇文章中描述得足够详细。因此,我的目标是提供基本的直觉,让人们了解诸如正规化或辍学这样的把戏实际上是如何运作的。这些话题对我来说很难理解,我希望我帮助你解决了它们。如果你喜欢这篇文章,请在 TwitterMedium 上关注我,并在 GitHubKaggle 上查看我正在进行的其他项目。保持好奇!

防止机器学习偏差

原文:https://towardsdatascience.com/preventing-machine-learning-bias-d01adfe9f1fa?source=collection_archive---------5-----------------------

机器学习算法越来越多地用于围绕评估员工绩效和流动率、识别和防止累犯以及评估工作适用性做出决策。这些算法的规模很小,有时在充满高质量研究和工具的环境中开发起来也很小。不幸的是,这些算法没有阻止和自动化的一件事是,如何以一种不会导致偏见和负面自我强化循环的方式来构建你的数据和训练管道。这篇文章将涵盖使用偏差感知而不是盲目方法忠实消除算法偏差的解决方案。

Photo by moren hsu on Unsplash

为什么防止偏见很重要

来自算法的预测通常不会在真空中使用。相反,它们被用来驱动决策和优化某些结果。如果你处理的数据有一些固有的偏差,模型不仅会学习这些偏差,而且最终会放大它们。有了有偏见的数据,模型的结果将以自我实现的预言而告终,这在许多情况下会导致灾难性的后果。我不认为我能对人工智能中的道德话题给出足够的报道,因为我想提供更多实用的解决方案,告诉人们如何设计他们的训练管道,使其对偏见更加鲁棒。相反,我强烈推荐阅读来自 fast.ai 的 Rachel Thomas 的人工智能伦理资源,以获得关于该主题的更详细的讨论。

盲算法

从算法中移除偏差的最常见方法是显式移除与偏差相关的变量。例如,如果您想预测某个职位应该雇用谁,您可以包括相关的输入,如申请人拥有的技能和经验,并排除不相关的信息,如性别、种族和年龄。这种方法的问题在于它不起作用。您想要包含的一些变量会受到潜在输入的影响。换句话说,你不能一边说“让我们把种族从模型中排除”一边又包括另外二十个有助于编码某人种族的变量。我将提供两个像这样盲目的方法失败的例子。

亚马逊招聘

最近路透社报道亚马逊一直在试图开发一种工具来自动化简历筛选和招聘。这个项目不得不被取消,因为它显示出对女性的严重偏见。我相当肯定,从事该模型工作的工程师没有使用任何明确的变量来识别某人的性别。尽管如此,要消除该模型识别与性别相关的其他潜在变量的能力,并且不歧视简历中包含“女子象棋俱乐部队长”的求职申请,是一项挑战。换句话说,如果数据有偏差(在这种情况下很有可能出现这种情况),当给定一组大而全面的特征时,模型会找到一种方法来对该信息进行编码。

预测累犯

两年前,Pro Publica 为提供了一个很好的分析软件,用于预测累犯率。他们发现,嵌入该软件的模型在非裔美国人中的假阳性率比白人高得多。开发该软件的公司指出,他们用来评估一个人再犯风险的 137 个问题中没有一个将种族作为输入。尽管如此,如果你看一下问卷,不需要太多的洞察力就能注意到一些主题可能与种族相关,并在判断申请人的风险时鼓励偏见。例如,当你问某人他们的父母是否在成长过程中被分开,你是在间接地编码他们的种族。al,2015,来理解不同种族的离婚率有多么惊人的不同。这又是一个盲目的方法不起作用的例子,因为没有考虑到潜在的变量。

偏差感知算法

我建议我们反其道而行之,而不是去除与有偏见的结果直接相关的变量。换句话说,为了知道你的数据中存在多少偏差,你需要让你的模型正确地测量它,然后减去偏差对结果的影响。我将通过一个人为的模拟来检验这种技术的有效性。

我们的模拟数据将包含以下特征:性别(我们将关注大多数性别:男性和女性)、经验年限和职业(我们将关注两种职业,软件工程和咨询)。我们的目标是预测给定这些特征的人我们应该支付多少薪水。

我们的数据将具有以下关系:

  • 总的来说,工作年限和薪水之间有明显的正相关关系
  • 相对于做软件工程师来说,做顾问会让你赚更多的钱
  • 身为男性会比身为女性赚更多的钱
  • 我们要考虑几个关键的相互作用。在咨询行业,男性和女性的起薪相同,但男性的工资增长高于女性。换句话说,对于每一年的工作经验(或每一次晋升),男性的工资预期会增加
  • 在软件工程领域,女性从低端起步,然后必须经历一段时间的追赶

你可以在下面找到上面描述的所有关系。

请注意,我们有目的地创建一个“看起来”真实的场景,并描述不同层次的交互,因为我想展示偏见意识方法在推广到具有数百个变量和多层复杂性的问题时的优势。

为了消除数据中偏见的影响,我们需要建立一个忠实代表性别偏见的模型。在下面的代码中,我们有一个非常简单的训练管道来完成这个任务。

下面你可以在测试集上找到模型预测。正如你所看到的,这个模型概括得非常好,并且设法捕捉到了数据中所有的主要影响和相互作用。

接下来,我将提取特定于预测的相互作用,以消除它们的影响。在这种情况下,我使用的是 XGBoost ,它已经实现了Shapley Additive explain方法,这是一种在单个预测级别提取特征贡献的一致、快速和确定的方法。这个方法在其他流行的 boosting 库中已经可用,比如 CatBoost 和 LightGBM。如果你的预测中不存在决定论的问题,你也可以使用时间,或者如果你使用其他类型的算法,如 L1 或 L2 线性回归导数,从手工编码的交互中提取权重。

“交互”对象将包含一个 numpy 形状数组(n_samples,n_features + 1,n_features + 1),其中包括所有主要效果、交互和截距。下面是测试集中第一次观察时该数组的样子:

Note that the numbers look small because the outcome was log-transformed before training.

接下来,我们简单地取消所有由性别变量驱动的影响。

然后,我们可以计算我们的预测,并绘制它们。我们可以立即看到,任何偏见的迹象都被完全消除了,该模型忠实地捕捉到了由多年的就业和职业道路所驱动的变化。

感知偏差的建模方法可以应用于其他类型的输入数据:文本、图像、声音。如果您使用依赖于实体嵌入的 NLP 模型,您可以显式地编码更敏感的概念,并跟踪与这些概念相关的嵌入如何与其他嵌入交互。请注意,谷歌似乎也使用了类似的方法。

结论

我想从一开始就指出,毫无疑问,这种方法会导致验证数据的模型性能下降。在我们设计的例子中,对于编码偏差的预测,RMSPE 是 12%,对于去除性别因素的预测,是 14%。尽管如此,在许多情况下,这种性能下降是可以接受的,也是受到鼓励的。毕竟,你的模型的目的不仅仅是做出好的预测,而且还能让你找到利用杠杆的方法,比如修改你网站上的用户行为,或者在诊断疾病时防止有害的事情发生。因此,如果你想建立一个不受数据偏见影响的模型,让模型首先测量偏见的数量,然后将所有偏见因素重置为零是不会错的。

价格弹性:首先是数据理解和数据探索!

原文:https://towardsdatascience.com/price-elasticity-data-understanding-and-data-exploration-first-of-all-ae4661da2ecb?source=collection_archive---------2-----------------------

在我之前的一篇文章中,我描述了如何使用最常用的指标和图表来评估回归。我举了一个关于价格弹性建模的实验为例,在用残差图分析模型后,发现测试数据集在 9 月 1 日之后出现了问题:

fig. 1 — The calendar_date variable vs residuals plot shows that something strange happens after the 1st of September (by the author)

本文将展示 R 中用于更好的数据探索的工具,展示为高性能预测建模准备数据的好方法。这也是试图解释之前出现的问题的唯一方法。

如果你想从数据集开始而不使用上面建议的实验,你可以在这里得到它们

千万不要照原样把所有的都放进锅里

打开Azure Machine Learning Studio中的价格弹性实验,我们可以看到,在三个不同数据集之间的连接之后,在所有数据转移到建模阶段之前,只有很少的基本数据转换:

fig.2 — Join and Transformation phases in the price elasticity experiment (by the author)

看起来数据还没有被很好的分析和理解,因为这个实验只是为了演示。但是,一般来说,对预测模型中使用的数据有信心是很重要的,因为,正如 Techopedia 在其“数据预处理”一节中所说:

真实世界的数据通常是不完整的不一致的,和/或在某些行为或趋势中缺少,并且很可能包含许多错误

一般来说,几乎所有信息系统的问题都是“垃圾进,垃圾出”。如前所述,由于数据集可能包含大量潜在陷阱,在机器学习实验的任何建模阶段之前,必须应用详细的数据探索

数据背后是什么

用作实验起点的三个数据集来自一家汉堡咖啡馆进入中国微软大楼的交易。成本压力使得有必要重新审视超额价格。对微软来说,了解商店对汉堡的需求对价格上涨的反应是很重要的。换句话说,为了知道价格可以提高多少,了解商店里汉堡的*(需求)价格弹性*是很重要的。事实上,价格弹性是一种产品的价格影响其需求的程度。

fig. 3 — Price elasticity of demand (by the author)

从上图可以清楚的看到,如果价格定在 3.000 美元,卖出的产品是 400 万;相反,如果价格增加到 4.000 美元,售出的产品只有 200 万。

根据其斜率,需求曲线可以是弹性非弹性

fig. 4 — Elastic and inelastic demand curve

在左图中的弹性需求下,如果价格从 50 便士增加到 60 便士,大量物品的数量减少(这对于卖方是最坏的情况,对于买方是最好的情况);相反,如果需求是无弹性的,如右图所示,将价格提高 40%将导致数量的小幅减少(在这种情况下,卖方可以在价格上做文章,因为买方需要该商品)。

fig. 5 — Buyer behavior in case of a good that follows an inelastic demand and that undergoes an increase in price (from https://bit.ly/3OtlIZo)

现在,回归只有两个变量价格数量的需求曲线非常简单。当涉及到更多的变量时,它就变得更加复杂了(比如和其他产品一起卖汉堡)。由于机器学习,我们将收集所有需要的信息,以了解在不导致收入大幅下降的情况下价格可以提高多少。

数据探索拯救世界

要做的第一件事是努力让最好地理解数据。这是通过使用一些特定的统计工具来探索它而获得的。

全面的数据探索指南超出了本文的范围。一个非常好的由分析 Vidhya 可以在这里找到。从本指南中,我们可以了解获得合理数据感受的步骤:

  1. 变量识别
  2. 单变量分析
  3. 双变量分析
  4. 缺失值处理
  5. 异常值处理
  6. 变量变换
  7. 变量/特征创建

让我们从第一步开始。

变量识别

有三组数据需要分析。让我们看看每一个中包含的变量。

“咖啡馆-交易-商店 1”数据集

组成这个数据集的变量可以直接在 Azure Machine Learning Studio 中进行分析(从数据集的输出 pin 中单击“Visualize”),它们就是下图中显示的那些变量。

fig. 6 — Variables in the “Cafè — Transaction — Store 1” data set (by the author)

每一行都是一个聚合事务,它对 SELL_ID 标识的特定产品在特定一天的销售量进行求和。假设那天那个产品的价格不会变化。

详细来说:

  • STORE :分类变量,在本例中只包含标识商店 1 的值“1”
  • CALENDAR_DATE :日期/时间变量,时间总是设置为上午 00:00
  • 价格:数字变量,与 SELL_ID 标识的产品价格相关联
  • QUANTITY :一个数字变量,与销售的产品数量相关联,由 SELL_ID 标识
  • SELL_ID :分类变量,所售产品的标识符
  • SELL_CATEGORY :分类变量,所售产品的类别

“咖啡馆——出售元数据”数据集

这是这个数据集的变量。

fig. 7 — Variables in the “Cafè — Sell Meta Data” data set (by the author)

详细来说:

  • SELL_ID :与之前数据集中显示的已售出产品的标识符相同
  • SELL_CATEGORY :上一个数据集中显示的已销售产品的同一类别。看图现在很清楚,类别“0”标识单个产品;类别“2”标识组合
  • ITEM_ID :分类变量,产品中包含的项目的标识符
  • ITEM_NAME :分类变量,标识项目的名称

正如上图中突出显示的,同一个 SELL_ID 的多个实例与不同的 ITEM _ IDs 相对应,这使我们认为 SELL_ID 是产品的标识符,可以是单个项目,也可以是项目的组合*。例如,SELL_ID = 2053 的组合是由汉堡、可乐和咖啡组成的。SELL_ID 为 1070、3028、3055 和 3067 的产品是单一商品。*

“日期信息”数据集

这个数据集包含带有一些外部数据的日历信息。

fig. 8 — Variables in the “DateInfo” data set (by the author)

详细来说:

  • CALENDAR_DATE :日期/时间变量,表示日历的日期
  • :数字型变量,表示对应 CALENDAR_DATE 的年份
  • 假日:分类变量,表示对应的 CALENDAR_DATE 是否为假日
  • IS_WEEKEND :分类变量,表示对应的 CALENDAR_DATE 是否为周末
  • IS_SCHOOLBREAK :分类变量,表示对应的 CALENDAR_DATE 是否为学校放假
  • AVERAGE_TEMPERATURE :数值型变量,表示对应 CALENDAR_DATE 日的平均华氏温度
  • IS_OUTDOOR :分类变量,我不知道它的意思。它可能是一个标志,指示温度是在室外测得的(值 1)还是在建筑物内测得的(值 0),因为它是外部数据信息的一部分,并且接近 AVERAGE_TEMPERATURE 变量

将所有数据集连接在一起

其中一些变量可以被操纵,然后作为一个独特的数据集加入,用作我们机器学习实验的来源。这里要执行的操作:

fig. 9 — Operations to perform in order to have a unique data set (by the author)

因为事务数据包含 SELL_ID 变量作为引用,所以我需要将 SELL_ID 产品的所有元数据信息放在一行中,以便与它连接。因此,我们必须将数据集从长格式转换为宽格式。这可以通过旋转“销售元数据”信息来获得。

fig. 10 — Pivoting of a data set from a long format to a wide one (by the author)

这个任务在下面简单(并且相当神秘)的 R 代码片段中实现,进入图 9 中的执行 R 脚本模块:

关于此功能的任何细节,请参考此链接。真诚地说,我更喜欢用整洁的方式来做同样的转换,只是稍微多了一点罗嗦,但是可以理解:

在“通过 SELL_ID 加入”模块中,有一些变量需要过滤掉。

fig. 11 — Variables to filter out from the first Join Data module (by the author)

变量 STORE 和 BURGER 是零方差预测器(它们的值总是 1),所以它们不会带来任何有意义的信号。然后,由于数据集模块中的选择列,这些变量被删除。SELL_ID 变量是一个产品标识符,一个标识交易中售出的产品的标签。因为它是一个 ID,所以很容易想到将其从数据集中删除,但是我们保留它,因为它可能对将价格和数量与售出的产品相关联很重要。来自事务的 SELL_CATEGORY 变量也被保留下来(在最初的实验中,这个变量被过滤掉了)。输出如下所示:**

fig. 12 — Variables kept after the Select Columns in Dataset module (by the author)

然后,所有关于日期和外部因素的信息通过 CALENDAR_DATE 变量连接到“Join by SELL_ID”数据集,最终结果如下:

fig. 13 — Final data set after the Join Phase (by the author)

生成的数据集可以 CSV 格式在此处下载。如果您没有 Azure Machine Learning Studio 帐户,可以使用该文件进行以下分析。

单变量分析

一旦我们准备好了输入数据集,就必须探究其中的每一个变量。根据变量的性质,需要不同的统计方法(集中趋势、离差度量)和图表来完成这项工作。最后,对于数据科学家来说,这项工作总是重复的。既然我们不喜欢猴子工作*,微软的一个伟大的开源工具来拯救我们: 交互式数据探索性分析和报告 ( IDEAR ) 。该工具提供了三个版本,分别适用于以下平台:*

  • 微软机器学习 R 服务器
  • 计算机编程语言
  • 稀有

在这篇文章中,我使用的是 R 的版本。特别是,我将它与 RStudio 中的 R 3.4.3 一起使用(到目前为止,IDEAR 在 R ≥3.5.0 上有一些问题)。关于如何安装和使用它的完整说明在这里

首先,我们需要以 CSV 格式导出连接的数据集。这要归功于转换为 CSV* 模块:*

fig. 14 — Export the joined data set to CSV (by the author)

然后,根据指令中提到的 IDEAR 约定,有必要编写一个包含 CSV 文件中变量的元数据信息的 yaml 文件。 yaml 文件的内容如下:

打开 Run-IDEAR 后。R 文件并执行后,会提示一个对话框要求点击确定继续(有时会出现对话框图标,但对话框本身仍隐藏在后台;点击图标即可)。然后打开刚刚在打开对话框中创建的 yaml 文件,游戏就完成了:一个神奇闪亮的应用程序会出现,上面有我们需要的所有统计数据。

fig. 15 — IDEAR Data Quality Report (by the author)

由于我们已经在 yaml 文件中将 CALENDAR_DATE 变量定义为日期/时间,IDEAR 已经自动生成了其他日期/时间组件(年、月、周、日、星期日),并在它们的名称后添加了“ autogen_ < var > ”后缀。这些新变量将帮助我们在多变量分析中获得更好的洞察力。

在“数据总结”部分(包含变量、变量类型和值的信息)之后,是“深入研究每个变量”部分,我们可以在这里进行单变量分析。

分析目标变量

首先,“每个变量的更详细的统计数据”小节让我们快速浏览每个变量的一些基本统计数据。

然后“可视化目标变量”小节包含四个图,帮助理解目标变量(在我们的例子中是数量)的行为。

fig. 16 — Behavior of target variable (by the author)

由于分布的右偏性,数量变量似乎是双峰的(在密度图中有两个主要的隆起),并且对于高值(查看箱线图)几乎没有异常值。

分析数字变量

由于“可视化数字变量”小节,可以研究所有的数字变量:价格、数量(刚刚分析的)和平均温度。

fig. 17 — Behavior of the PRICE variable (by the author)

价格变量似乎也是双峰的,只是有点向右倾斜。箱线图显示没有异常值。

平均温度也是双峰的。这一次,分布有点左倾

fig. 18 — Behavior of the AVERAGE_TEMPERATURE variable (by the author)

稍后,我们将对这些变量进行一些转换,以便尽可能地调整它们的偏斜度,试图在不消除异常值的情况下减轻它们的影响。

分析分类变量

感谢“可视化分类变量”小节,我们也可以探索分类变量。CALENDAR_DATE 中自动生成的变量也是分类变量。例如,有趣的是看到交易数量在一年的最后一个季度下降。

fig. 19 — Exploration of the CALENDAR_DATE_autogen-month variable (by the author)

查看 SELL_ID 分类变量,我们有以下图表:

fig. 20 — Exploration of the SELL_ID variable (by the author)

只卖四种产品(单个汉堡,1070;汉堡+可乐套餐,2051;汉堡+柠檬水套餐,2052;汉堡+可乐+咖啡组合,2053)。奇怪的是,所有这些产品的销售数量完全相同。可能是交易的数据集已经衍生出一个更完整的数据集。

多变量分析

当探索两个变量的相互作用时,事情变得有趣了。

等级变量

首先,IDEAR 为我们提供了“等级变量”小节,这有助于理解哪些变量与所选变量的关联最强。不同的度量标准分别用于分类变量和数值变量。

选择 6 作为与数量相关的顶级分类变量的数量后,结果如下:

fig. 21 — Strength of association between variables in the data set (by the author)

x 轴上的变量标签被截断了一点。为了清楚起见,接下来是排序为最强相关的第一个的数字和分类变量的列表。

数值变量

  1. 价格
  2. 温度

分类变量

  1. 出售标识
  2. 销售 _ 类别
  3. 柠檬汁
  4. 焦炭
  5. 日历日期自动生成日
  6. 是周末

有趣的是注意到 SELL_ID 和 SELL_CATEGORY 变量的强度,它们意外地没有包括在原始实验的训练数据集中。此外,星期几(从 1 到 7)与目标变量之间的关联是一个意想不到的发现。

两个分类变量之间的相互作用

IDEAR 使用马赛克图来比较两个分类变量。乍一看,对于不了解一些统计概念的人来说,这可能有点令人困惑。例如,下面是变量 SELL_CATEGORY 和 COKE 的镶嵌图:

fig. 22 — Mosaic plot for SELL_CATEGORY vs COKE (by the author)

由于这个图,我们可以说组合产品(SELL_CATEGORY = 2)几乎总是包含可乐(COKE = 1)。事实上,不含可乐(可乐= 0)的组合产品(SELL_CATEGORY = 2)与它们之间独立的情况(红色)相比,较少出现在交易中。与此同时,可以肯定地说,单一产品(SELL_CATEGORY = 0)不含可乐。

关于如何绘制镶嵌图的更详细的解释,请参考本帖

两个数值变量之间的相互作用

比较两个数值变量最常用的图是散点图*。比较 IDEAR 中的价格和数量变量很有意思:*

fig. 23 — Scatter plot for PRICE vs QUANTITY (by the author)

有两条线可以帮助您查看变量之间的任何关系:红色的简单回归模型线(线性模型, lm ),以及蓝色的 局部加权散点图平滑 (LOWESS)线。前者是一种参数方法来拟合曲线(您预先假设数据符合某种类型的分布),而后者是一种非参数策略,试图找到最佳拟合曲线,而不假设数据必须符合某种分布形状。

图上显示的相关值是两个变量之间的皮尔逊相关

对于等于或大于 14 美元的价格,数量似乎有不同的表现。可能有另一个变量使这种情况发生。我们稍后会对此进行调查。

如果我们想研究价格和数量相对于平均温度的行为,我们会发现没有特别的关联:

fig. 24 — Scatter plot for AVERAGE_TEMPERATURE vs PRICE (by the author)

fig. 25 — Scatter plot for AVERAGE_TEMPERATURE vs QUANTITY (by the author)

数值变量之间的相关性

IDEAR 中的这一部分允许根据 Pearson、Kendall 和 Spearman 计算两个数值变量之间的相关性。可以为绘图选择几种配置(顺序、形状、布局)。

与标准皮尔逊相关相比,肯德尔的τ 对极端观测值和非线性更加稳健。让我们看看 AVERAGE_TEMPERATURE 变量是否以非线性方式与其他数值变量相关联:

fig. 26 — Kendall’s correlation for numeric variables (by the author)

平均气温和价格之间出现了意想不到的小联系。有数量的可以忽略不计。

数字变量和分类变量之间的相互作用

IDEAR 通过箱线图可视化数字和分类变量之间的关联。这是检查数值变量的分布在分类变量的不同级别是否有显著差异的常用方法。同时,检验了零假设*,即数值变量在分类变量的不同级别上具有相同的平均值。进行两个变量之间的单向方差分析( ANOVA )。在 ANOVA 测试中由 F 值返回的 p 值帮助我们接受(箱线图的平均值具有相同的值)或拒绝(箱线图的平均值具有不同的值)零假设。*

例如,让我们检查价格变量分布是否在 SELL_ID 变量(销售产品标识符)的不同级别有所不同:

fig. 27 — Interaction between PRICE and SELL_ID (by the author)

从上图中可以清楚地看到,单个汉堡(SELL_ID = 1070)决定了价格的净增长(零假设被拒绝)。出现了一些值得关注的异常值。

数量分布也随着 SELL_ID 级别的不同而显著变化:

fig. 28 — Interaction between QUANTITY and SELL_ID (by the author)

从上图可以看出,汉堡+可乐组合产品(SELL_ID = 2051)出现了一些明显的异常值。

当分析 SELL_CATEGORY 和 COKE 变量与价格的关系时,发现了其他有趣的异常值:

fig. 29 — Interaction between PRICE and SELL_ID (by the author)

fig. 30 — Interaction between PRICE and COKE (by the author)

缺失值处理

我们的数据集很幸运:我们没有缺失值,正如您在 IDEAR 的“检查数据质量”部分看到的,选择了所有 18 个变量进行分析:

fig. 31 — Missing values analysis (by the author)

这个情节是对 r 中 levelplot() 的巧妙运用,作为类似的例子,看看这个链接

异常值处理

从单变量分析中我们发现,单个变量没有如此明显的异常值。在多变量分析中,当比较数值变量和分类变量时,情况会发生变化。

从图 27 中,我们看到有单个汉堡(SELL_ID = 1070)以低于 14 美元出售的交易。让我们更深入地了解这个案例。您会在代码中找到注释。

我们很幸运地发现了一个数据问题,只是检查异常值。移除错误的交易行我们也移除了之前显示的所有极端异常值。所以,我们刚刚一石多鸟!

变量变换

有时变量分布中的异常值并不是错误的度量,它们可能是变量本身固有的性质,尤其是当变量偏斜时。从分布中删除这些值会删除对成功预测建模有用的信息。因此,最好转换变量以减轻偏斜度,尝试使其分布更接近正态分布。减少非正态性通常也会减少非线性,即使变换后的分布不完全正态,它通常也是对称的。

当分布是右偏的时,通常使用 对数变换。但是如果是左倾呢?幸运的是,有一种转换非正态分布的通用方法:Box-Cox 转换。它将仅应用于价格和数量,因为 AVERAGE_TEMPERATURE 已经是对称的(对其进行 Box-Cox 变换不会改变其分布,因为它不能在正常情况下进行变换)。

var_distribution 函数为我们提供了四个图,与“可视化数字变量”部分中的 IDEAR 用法相同(只需按“导出”将代码导入price-elasticity-joined . log . r文件,并声明为 YAML 文件)。

boxcox_transf 函数返回一个列表,其中包含转换后的数据和由 Box-Cox 转换计算出的 lambda 值。

下面是原始价格变量和 Box-Cox 转换变量(T-PRICE)的曲线图。

fig. 32 — Distribution plots for PRICE and transformed PRICE (T-PRICE) (by the author)

如您所见,转换后的密度图显示出更加对称的曲线,转换后的 Q-Q 图更接近法线。用于转换价格变量的 lambda 值为-1.1。

这是数量变量的相同曲线。

fig. 33 — Distribution plots for QUANTITY and transformed PRICE (T-QUANTITY) (by the author)

用于转换数量变量的λ值为-0.1。在这种情况下,正如您从 T-QUANTITY 箱线图中看到的,由于转换,异常值已经消失,而没有被移除。

变量创建

这是数据科学项目中最具创造性的阶段,也被称为特性工程*。三言两语(来自这篇博文):*

这是使用数据的领域知识来创建使机器学习算法工作的特征的过程。如果特征工程做得正确,它可以通过从原始数据中创建有助于促进机器学习过程的特征来提高机器学习算法的预测能力。特征工程是一门艺术。

新的日期/时间变量

特征工程的第一个例子是从一个日期变量创建多个变量。正如我们在本文开头看到的,IDEAR 会自动为我们进行这种转换,以便更好地分析我们的数据集。

提取一个新的变量来表示从我们在数据集中找到的第一天开始的天数也是很有用的。通常,日期/时间变量是循环的(例如,月份数从 1 到 12;天数从 1 到 31)。机器学习算法不会考虑变量的周期性。因此,表示时间流逝的天数计数器是一个很好的添加变量,因为它可以帮助算法捕捉自活动开始以来的任何销售增长。

这里是从 CALENDAR_DATE 变量中提取这些变量的 R 代码(它是由 read_csv 函数在日期列中自动解析的)。

新分类变量

让我们来看看这个情节:

fig. 34 — Interaction between QUANTITY and HOLIDAY (by the author)

似乎在工作日(HOLIDAY = "NULL ")的销售量要比节假日期间大得多。因此,一个名为 IS_HOLIDAY 的新虚拟变量(1,如果事务发生在节假日;否则为 0)可能有助于机器学习算法以更好的方式执行。

还有一些 factor 列必须转换成 one-hot 编码变量 (如您所见,我们的数据集中已经有了其中的一些:咖啡、柠檬水、…)。独热编码变量(或虚拟变量)是数值变量,因为它们代表存在(1)或不存在(0)的特征。在我们的分析中,它们经常被转换成分类变量,以便于图形化表示。在 R 中,由于使用了 model.matix 函数,可以实现一键编码变量。

(在这里你可以找到原因“-1”)

新的数值变量

在组合产品中有一个商品数量的变量可能是决定价格变化的一个重要特征。因此,就在“长格式到宽格式”执行脚本模块之后,您可以在图 2 中看到,数据集是图 10 中的数据集。这里可以添加变量 NO_ITEMS,定义如下:

清理数据后的进一步分析

假期分析

在删除假日列之前,如前面代码中所述,检查每个假日在我们每年的数据集中是如何表示的是很有趣的。怎么做呢? 海盗团 前来救援。在使用这个图之前,为了更好的可视化表示,我们将添加一个新变量(HOLIDAY_ABBR ),每个假日都有缩写标签。

fig. 35 — Pirateplot for QUANTITY versus SELL_ID and YEAR (by the author)

如你所见,某一年缺少一些假期:

  • **2015 年中秋节不见了
  • **2015 年国庆节不见了
  • 2012 年、2013 年和 2014 年没有二战庆典(第二次世界大战结束)

很容易证明 2015 年没有前两个假期是合理的。我们在数据集中登记的交易的最大日期是 2015 年 9 月 10 日。所以这些假期比最大日期晚。

在 2015 年之前的几年里,二战庆祝活动不见了。由于数据集是由微软中国的一家汉堡店的交易产生的,我在网上搜索了一下,发现了这个帖子。似乎中国决定从 2015 年开始庆祝二战的结束。因此,2015 年之前的年份缺乏的原因得到了解释。

SELL_ID 对需求曲线的影响

我们想知道汉堡的销售是否遵循线性需求。在图 23 中,我们假设有另一个变量打破了数量和价格之间的线性关系。让我们深入分析来回答这个问题。

要考虑的第三个变量是 SELL_ID(一个分类变量)。假设不同的产品以不同的价格和数量出售是合理的。从图 23 中可以明显看出,价格为 14 美元或更高的产品会出现不同的行为。让我们考虑一个新变量 IS_PRICE_HIGH,如果价格为 14 美元或更多,则设置为 1,否则为 0。因此,现在我们需要绘制一个数字变量(数量)和两个分类变量(SELL_ID 和 IS_PRICE_HIGH)。海盗团会再次帮助我们。

fig. 36 — Pirateplot for QUANTITY versus SELL_ID and IS_PRICE_HIGH (by the author)

查看该图,只有 SELL_ID 1070 出现在 IS_PRICE_HIGH 区域中,对应于等于或大于$14 的价格,并且平均值周围的推断带不重叠,这似乎证实了由 SELL_ID 标识的每个产品都以 9%置信度的平均数量销售,并且高价格标识特定的 SELL_ID。

如果我们绘制每个 SELL_ID 的价格分布图,每个 SELL_ID 的价格也非常不同。

fig. 37 — Pirateplot for PRICE versus SELL_ID (by the author)

SELL _ IDs 2052 和 2053 的平均置信水平是重叠的,所以它们在价格上很难区分。

让我们看看每个 SELL_ID 的需求曲线是如何表现的。

fig. 38 — Scatter plots between PRICE and QUANTITY for each SELL_ID value (by the author)

看起来我们实际上可以用线性回归来塑造需求曲线。

结论

在没有首先仔细分析输入数据集的情况下,面对一个机器学习问题是完全错误的。数据必须得到真正的理解和恰当的“处理”,这样它才能显示所有的洞察力。只有在完全理解数据之后,数据科学家才能转换和创建新的变量,这些变量对于机器学习算法的良好运行非常有用。

在这篇文章中,我们加深了对汉堡咖啡馆交易数据集的了解。在下一篇文章中,我们将应用这些知识在 Azure Machine Learning Studio 中实现一个新的机器学习模型,我们将检查:

  • 这些表现比上一篇中的表现要好
  • 残差图相对于 CALENDAR_DATE(参见本文的前言)中出现的问题在应用于数据集的转换后是否得到解决

云定价

原文:https://towardsdatascience.com/pricing-on-the-cloud-9a2d3f61b67f?source=collection_archive---------7-----------------------

Photo by C Dustin on Unsplash

1.介绍

云计算是在线提供计算资源作为服务的重要实践。此外,根据牛津在线词典的定义,它是*“使用互联网上托管的远程服务器网络来存储、管理和处理数据的实践,而不是本地服务器或个人计算机”* [18]。

云上提供多种类型的服务:基础设施即服务(IaaS)、平台即服务(PaaS)、软件即服务(IaaS)、存储即服务(STaaS)、安全即服务(SECaaS)、测试环境即服务(TEaaS)等等。

云计算提供商的目标是最大化其收入,而客户的目标是以可接受的价格获得良好的服务质量。因此,满足双方需要一个最优的定价方法。

本报告主要基于以下研究论文:

  • “云计算中的定价方案:综述”,2017 年出版 [1]
  • 《云计算中的定价方案:概述》,2016 年出版 [3]
  • 《云计算定价模式:调查》,2013 年出版[2]

我将尝试对所有列出的定价模型给出一个更全面的观点,比较它们,并显示每个模型的一些优点和缺点。此外,我将简要讨论这三篇论文的内容,并给出建议。

2.云定价

当谈论云定价时,需要考虑许多因素,首先是服务提供商的目标是实现利润最大化,而客户正在寻求更低价格、更高质量的服务。其次,在云上销售服务竞争非常激烈,因为有大量的提供商在销售相同的服务。此外,价格还受到以下因素的影响:

  • 租赁期,可视为供应商和客户之间的合同时间。
  • 资源的初始成本
  • 折旧率,意味着这些资源被使用了多少次
  • 服务质量
  • 资源的年龄
  • 维护费用

3.定价模型

云上使用的定价模型有很多,从变化周期的角度可以分为两大类:固定的和动态的。

3.1.固定定价模型

固定定价模型也称为静态定价模型,因为价格长期稳定。云上最著名的服务提供商如 Google、Amazon Web Services、Oracle、Azure 等都使用固定的定价模式。

固定价格使用户意识到做生意和消耗资源的成本。然而,另一方面,这种定价方式对顾客来说是不公平的,因为他们可能会多付或少付他们的需求。另外,它不受需求的影响。

有许多固定的定价方式,如“按使用付费”、订阅、价目表……在这一部分,我将简要介绍这些定价模式:

3.1.1.按使用付费模式

在这种模式下,用户只需为他们使用的东西付费。顾客根据他在特定服务上花费的时间或数量付费。如表 1 和表 2 所示的亚马逊网络服务(AWS) [13]、Salesforce [19]使用这种模型。

Table 1 — Amazon S3 storage pricing

Table 2 — Salesforce Cloud pricing

3.1.2.签署

在这种模式下,用户需要定期付费,以在线服务的形式访问软件,从而从服务中获利。客户订购使用预先选择固定和长期服务单位组合,通常是每月和每年。

Dropbox[16]——如表 3 所示——使用这种模型。

Table 3 — Dropbox pricing

3.1.3.混合物

该模型是按使用付费和订阅定价模型的组合,在该模型中,所有服务价格都使用订阅模型来设置,但是当超过使用限制时,则使用按使用付费定价。

谷歌应用引擎[12]使用这个模型,如表 4 所示。

Table 4 — Google app engine pricing

3.1.4.为资源付费

在这种模式中,客户为使用的资源付费。微软 Azure 在基础设施即服务定价中使用该模型,如表 5 所示[14]。

Table 5 — Windows Azure IaaS pricing

3.1.5.价格表

在这个模型中,服务提供商在一个表格/列表中列出所有价格及其详细信息。此外,它可以作为文档(PDF)下载。Oracle [15]使用了这个模型,如图 1 所示。

Figure 1 — Oracle products price Lists

3.2.动态定价

动态定价模型也称为实时定价,这些模型非常灵活,它们可以被认为是一个函数的结果,该函数将成本、时间和其他参数(如位置、用户感知价值等)作为参数。

在动态定价中,只要有请求,就根据定价机制计算价格。与固定价格相比,反映实时供需关系的动态定价代表了一种更有前途的收费策略,可以更好地利用用户支付潜力,从而为云提供商带来更大的利润收益。

例如,亚马逊每 10 分钟改变一次价格,百思买和沃尔玛每个月改变价格超过 50000 次。

有许多动态定价模型,如:

  • 以成本为基础的模式,将利润与成本水平相结合。
  • 基于价值,考虑用户感知价值的基础
  • 基于竞争,考虑竞争对手的服务价格
  • 以客户为基础,考虑客户愿意支付的价格。
  • 基于位置,根据客户位置设定价格。

3.3.固定定价与动态定价

在表 6 中,列出了固定定价和动态定价的主要区别[1]。

Table 6 — Fixed pricing VS dynamic pricing

3.4.几种定价模型的比较

在表 7 中,列出了所有定价模型及其优缺点[1]。

Table 7 — Pricing Models Comparison

4.讨论和结论

我们正在总结的三篇论文讨论了动态定价,它们将使收入最大化,并且对客户和提供商更加公平。然而,客户无法预测动态定价模型,而且大多数情况下,客户无法接受动态定价模型,尤其是在谈到云计算服务时。为此,云服务提供商不使用动态定价;亚马逊、全球速卖通、沃尔玛等在线零售商使用它们。

然而,有许多供应商正在使用带有一些动态性的固定价格;可以称之为混合定价。因此,价格在很长一段时间内是静态的,但它会受到资源成本以外的其他参数的影响,如位置、客户、竞争和其他因素。

如图 2、3、4 所示,微软认证价格是固定的,但随着地点或客户类型的变化而变化[17]。

Figure 2 — MCSA exam price in Lebanon on December 2017

Figure 3 — MCSA exam price in United States on December 2017

Figure 4 — MCSA exam price will decrease for students

但是,在这种混合方法中,固定定价的主要缺点仍然存在,因此客户可能会多付或少付资源的费用。为此,我们建议在分析每个定价模型中使用的参数的基础上设计预测分析模型,以帮助客户更好地了解价格变化。

此外,即使找到了预测分析模型,有一点我们不能忘记的是,服务提供商是选择定价模型的人,因此所使用的定价模型总是偏向服务提供商。这增加了建立国际定价标准的需要,以便在顾客的权利和销售者的目标之间进行协调。

5.参考

  • [1] A Soni 和 M Hasan,“云计算中的定价方案:综述”,《国际高级计算机研究杂志》,第 7 卷,2017 年 2 月 20 日
  • [2]M . Al-Roomi、S . Al-Ebrahim、S . Buqrais 和 I Ahmad,“云计算定价模型:调查”,《国际网格和分布式计算杂志》第 6 卷,2013 年 6 月 5 日
  • [3]A . Mazrekaj 和 I Shabani 和 B Sejdiu,“云计算中的定价方案:概述”,《国际高级计算机科学与应用杂志》,第 7 卷,2016 年
  • [4] C. D. Patel 和 A. J. Shah,数据中心规划、开发和运营的成本模型,惠普技术报告-HPL-2005–107(r . 1),2005 年。
  • [5] Pal,r .和 Hui,p,《云服务市场的经济模型:定价和容量规划》。理论计算机科学 496,113–124,七月。2013.
  • [6]王文伟,张平,T. Lan 和 V. Aggarwal,具有单个作业截止期的数据中心净利润优化,Proc .信息会议。科学与系统 2012。
  • [7] C. S. Yeoa,S. Venugopalb,X. Chua 和 R. Buyyaa,公用计算服务的自主计量定价,下一代计算机系统。,第 26 卷,第 8 期,2010 年。
  • [8] M .马西亚斯和 j .吉塔特,云计算市场定价的基因模型,Proc .第 26 届交响乐。应用计算,2011 年。
  • [9] H. Li,J. Liu 和 G. Tang,云计算资源的定价算法,Proc .里面的网络计算与信息会议。安全,2011 年。
  • [10] B. Sharma,R. K. Thulasiram,P. Thulasiraman,S. K. Garg 和 R. Buyya,《云计算商品定价:一种新的金融经济模型》, Proc .IEEE/ACM Int。症状。关于集群、云和网格计算,2012 年。
  • [11]卢米先生。Al-Ebrahim,S. Buqrais 和 I. Ahmad,《云计算定价模型:调查》,《国际网格和分布式计算杂志》第 6 卷第 5 期,第 93–106 页,2013 年。
  • [12]谷歌应用引擎,https://cloud.google.com/appengine/,最近一次访问是在 2015 年 11 月 12 日。
  • [13]http://aws.amazon.com/,亚马逊网络服务最近一次访问时间为 2015 年 10 月 12 日。
  • [14]微软 Azure 网站,https://Azure . Microsoft . com/en-us/pricing/details/cloud-services/,最后访问时间:2017 年 12 月 5 日
  • [15]甲骨文公司网站,http://www . Oracle . com/us/corporate/pricing/price-lists/index . html,最后访问时间:2017 年 12 月 5 日
  • [16] Dropbox 网站,https://www.dropbox.com/business/pricing,最近访问时间:2017 年 12 月 5 日
  • [17]微软网站,https://www . Microsoft . com/en-us/learning/mcsa-windows-server-2016-certification . aspx,最后访问时间:2017 年 12 月 5 日
  • [18]牛津在线词典
  • [19]销售团队网站,https://www.salesforec.com,最近访问时间:2015 年 10 月 12 日

主成分分析-简介

原文:https://towardsdatascience.com/principal-component-analysis-intro-61f236064b38?source=collection_archive---------0-----------------------

可变缩减技术

变数太多?你应该使用所有可能的变量来生成模型吗?

为了处理“维数灾难”并避免高维空间中的过拟合等问题,使用了主成分分析等方法。

PCA 是一种通过从大量数据中提取重要变量来减少数据中变量数量的方法。它减少了数据的维度,目的是保留尽可能多的信息。换句话说,这种方法将高度相关的变量组合在一起,形成一个较小数量的人工变量集,称为“主成分”,它解释了数据中的大多数差异。

让我们深入了解 PCA 是如何在幕后实现的。

开始 通过从每个数据点中减去平均值来标准化预测值。对预测值进行归一化非常重要,因为原始预测值可能处于不同的等级,并且可能对方差产生显著影响。结果如表 2 所示,平均值为零。

Normalized Data

接下来,计算数据的协方差矩阵,该矩阵将测量两个预测器如何一起移动。它是在两个预测值之间测量的,但如果您有三维数据(x,x1,x2),则测量 x x1,x x2,x1 x2 之间的协方差。供参考的协方差公式为:

在我们的例子中,协方差矩阵如下所示:

Covariance Matrix

现在,计算上述矩阵的特征值和特征向量。这有助于发现数据中的潜在模式。在我们的例子中,它大约是:

Eigen Value and Vector

我们快到了:)。执行重定向。为了将数据转换成新的轴,将原始数据乘以特征向量,这表示新轴的方向。请注意,您可以选择省略较小的特征向量,或者两者都使用。此外,根据哪一组占了 95%或更多差异,决定保留多少组特性。

**最后,**从上述步骤中计算出的分数可被绘制出来,并输入预测模型。绘图让我们感觉到两个变量有多接近/高度相关。我们没有使用原始数据来绘制 X 和 Y 轴(这并不能告诉我们点与点之间的关系),而是绘制转换后的数据(使用特征向量),这些数据可以发现模式并显示点之间的关系。

尾注:很容易将 PCA因子分析混淆,但这两种方法在概念上是有区别的。我将在下一篇文章中详细介绍因子分析以及它与 PCA 的不同之处..敬请关注。

Tensorflow 中带交互代码的主成分分析网络

原文:https://towardsdatascience.com/principal-component-analysis-network-in-tensorflow-with-interactive-code-7be543047704?source=collection_archive---------10-----------------------

GIF from this website

主成分分析池层的自然延伸将是在该层之外制作一个完整的神经网络。我想知道这是否可能,以及它在 MNIST 数据上的表现是好是坏。

主成分分析池层

Image from this website

对于不熟悉 PCAP 的人,请先阅读这篇博客。基本思想是合并层,如最大或平均合并操作执行维数减少,不仅节省计算能力,而且作为正则化。 PCA 是一种降维技术,将相关变量转换成一组线性不相关变量的值,称为主成分。我们可以利用这个操作来做与最大/平均池类似的工作。

由大多数池层组成的网络

Image from this website

现在我知道你在想什么了,在执行分类的时候有一个只由池层组成的网络是没有意义的。你是完全正确的!它没有!但我只是想试着玩玩。

数据集/网络架构

蓝色矩形 → PCAP 或最大池层
绿色矩形 →卷积层增加通道尺寸+ 全局平均池操作

网络本身非常简单,只有四个池层和一个卷积层来增加信道大小。然而,为了使尺寸匹配,我们将把每个图像下采样为 16*16 的尺寸。因此张量的形状是…

【批量,16,16,1】→【批量,8,8,1】→【批量,4,4,1】→
【批量,2,2,1】→【批量,1,1,1】→【批量,1,1,10】→
【批量,10】

并且我们可以像任何其他网络一样使用软最大层来执行分类。

结果:主成分网络

如上所述,训练准确率停滞在 18 %,这是可怕的 LOL。但我怀疑网络从一开始就没有足够的学习能力,这是它能做到的最好的。然而,我想看看每个 PCAP 层如何转换图像。

Generated Image when input is 7

Generated Image when input is 2

Generated Image when input is 1

左上图 →原始输入
右上图 →第一层后
左下图 →第二层后
右下图 →第四层后

我们可以观察到的一个明显的模式是亮度的变化。例如,如果左上像素在第二层中是白色的,则该像素在下一层中将变为黑色。目前,我不能 100%确定为什么会发生这种情况,但随着更多的研究,我希望知道确切的原因。

结果:最大共享网络

如上所述,当我们用 max pooling 操作替换所有 PCAP 层时,我们可以观察到训练图像的精度停滞在 14%左右,这证实了网络从一开始就没有足够的学习能力。

Generated Image when input is 7

Generated Image when input is 2

Generated Image when input is 1

左上图像 →原始输入
右上图像 →第一层后
左下图像 →第二层后
右下图像 →第四层后

与 PCAP 相反,使用最大池,我们可以清楚地观察到具有最高亮度的像素移动到下一层。这是意料之中的,因为这就是最大池的作用。

交互代码

对于 Google Colab,你需要一个 Google 帐户来查看代码,而且你不能在 Google Colab 中运行只读脚本,所以在你的操场上复制一份。最后,我永远不会请求允许访问你在 Google Drive 上的文件,仅供参考。编码快乐!

要使用 PCAP 访问网络,请点击这里。
要使用最大池访问网络,请单击此处

最后的话

我从一开始就没有对这个网络抱太大希望,但我希望在训练/测试图像上至少有 30%的准确率。

如果发现任何错误,请发电子邮件到 jae.duk.seo@gmail.com 给我,如果你希望看到我所有写作的列表,请在这里查看我的网站。

同时,在我的 twitter 上关注我这里,访问我的网站,或者我的 Youtube 频道了解更多内容。我还实现了广残网,请点击这里查看博文 t。

参考

  1. 50000 有 28 个因子。(2018).Factornumber.com。检索于 2018 年 6 月 3 日,来自http://factornumber.com/?page=50000
  2. 终端?,H. (2018)。如何在终端中重命名文件?。问 Ubuntu。检索于 2018 年 6 月 3 日,来自https://askubuntu . com/questions/280768/how-to-rename-a-file-in-terminal
  3. 中学 _y,H. (2018)。用 Seaborn + Pandas 带 secondary_y. Stack 溢出出图时如何去掉网格线?检索于 2018 年 6 月 3 日,来自https://stack overflow . com/questions/26868304/how-to-ride-of-grid-lines-when-plotting-with-seaborn-pandas-with-secondary
  4. [复本],H. (2018)。如何在 Matplotlib (python)中隐藏轴和网格线?堆栈溢出。检索于 2018 年 6 月 3 日,来自https://stack overflow . com/questions/45148704/how-to-hide-axes-and-gridlines-in-matplotlib-python
  5. MNIST 手写数字数据库,Yann LeCun,Corinna Cortes 和 Chris Burges。(2018).Yann.lecun.com。检索于 2018 年 6 月 3 日,来自http://yann.lecun.com/exdb/mnist/
  6. TensorFlow?,W. (2018)。TensorFlow 中最大汇集 2D 层的输出张量是什么?。堆栈溢出。检索于 2018 年 6 月 3 日,来自https://stack overflow . com/questions/43453712/what-is-output-tensor-of-max-pooling-2d-layer-in-tensor flow
  7. 主成分分析。(2018).En.wikipedia.org。检索于 2018 年 6 月 3 日,来自https://en.wikipedia.org/wiki/Principal_component_analysis
  8. 桑托斯大学(2018)。混合层人工智能。Leonardo araujosantos . git books . io . 2018 年 6 月 3 日检索,来自https://Leonardo araujosantos . git books . io/artificial-intelligence/content/pooling _ layer . html
  9. [ ICLR 2015 ]追求简单:具有交互码的全卷积网。(2018).走向数据科学。检索于 2018 年 6 月 3 日,来自https://towards data science . com/iclr-2015-力争简单-所有卷积-网络-交互-代码-手册-b4976e206760

Tensorflow 中的主成分分析池与交互代码[PCAP]

原文:https://towardsdatascience.com/principal-component-analysis-pooling-in-tensorflow-with-interactive-code-pcap-c621c7d927ed?source=collection_archive---------10-----------------------

其思想很简单,卷积神经网络中的最大/平均池操作用于降低输入的维数。虽然引入了更复杂的池操作,如 Max-Avg (Mix) Pooling 操作,但我想知道我们是否可以用主成分分析(PCA) 做同样的事情。

PCA 概述及简单教程

上面的论文在解释什么是 PCA 方面做了大量的工作,并且给出了使用哪种数学的简单例子。这将是一个好主意,先浏览 pdf 文件,然后再继续阅读。

PCA /单值分解

Image from this website

红框 →我们将如何在 Tensorflow 中执行 PCA

这篇博文很好地解释了我们如何使用单值分解来执行 PCA。谢天谢地 Tensorflow 已经有了 tf.svd() 操作来执行单值分解。

Video from this website

我个人不得不观看/阅读额外的材料来具体理解什么是单值分解,并且我已经链接了我在上面观看的视频。(这个 Quora 帖子和这个 medium 帖子也是一个很好的阅读来源。)

(愚蠢的)主成分分析池背后的想法

Image from this video

红框 →原矩阵
蓝框 →左奇异向量
紫框 →奇异值(对角矩阵)
绿框 →右奇异向量

我试图尽可能简单地理解难懂的概念,所以这里是我的简单(非常愚蠢的)SVD 版本。假设我们有一个蛋糕叫做 A,谢天谢地这个蛋糕 A 只由两种成分组成。牛奶 M 和糖 s 所以 A = M + S。

然而,这里的诀窍是知道我们制作原始蛋糕 A 所需的牛奶和糖的确切组合。假设我们需要 30 升牛奶和 50 毫克糖来正确制作蛋糕 A,这意味着我们也需要在某个地方获得该信息。

这样做的好处是,我们不必随身携带蛋糕(这需要大量的存储空间),我们可以简单地携带牛奶、糖和说明书(告诉我们需要多少比例的牛奶和糖),作为一种更紧凑的形式。这是我对奇异值分解的理解,从这里我们可以转到主成分分析。

Image from this [website](http://Li, E. (2018). PCA With Tensorflow. Abracadabra. Retrieved 25 May 2018, from https://ewanlee.github.io/2018/01/17/PCA-With-Tensorflow/)

如上面在 PCA 中所看到的,我们丢弃右奇异向量并修改奇异值矩阵的维数,以便降低维数。我们可以利用这一点,使我们的 PCA 充当池操作。

例如,假设我们有一批 881 的张量格式的 200 幅图像,我们可以将它写成(200,8,8,1)。但我们已经知道,我们可以对图像进行矢量化,将张量整形为(200,881) = (200,64)。现在,如果我们执行 PCA 以将维度从 64 降低到 16,我们可以将其重塑回 3D 图像,使张量变成(200,4,4,1)。因此得到的张量具有与执行平均汇集操作相同的维数。

奇异矩阵的指数加权移动平均值/α,β

红框→ 在训练期间更新移动奇异矩阵(sigma ),但是在测试期间,我们将使用移动平均 sigma 值来执行维度缩减。

我们需要注意的一个小细节是奇异矩阵的指数加权移动平均。就像我们执行批量标准化一样,我们在训练期间跟踪平均值和标准差的权重。在测试期间,我们不使用数据的平均值/标准值,而是使用移动平均值。

因为我们希望模型的预测只依赖于测试阶段的给定测试数据。因此,我们将使用奇异矩阵的移动加权平均值,而不是使用测试数据中的奇异矩阵。(如果有人想了解更多关于批量标准化的信息,请点击这里。)

Original Image from the paper

如上所述,在批量标准化中,我们将标准化数据乘以α,并添加β项。我将遵循这个想法,也给我们的 PCAP 层一些能力来取消 PCA 操作,如下所示。

红框 →将α和β项添加到整形后的 PCA 中

网络架构

黑盒 →卷积层
黄盒 →卷积+批量归一化
绿盒 →平均池层
红盒 →主成分分析池层
粉盒 →全局平均池和 Softmax

我们将要使用的基本网络是全卷积网络,如上所示(浅蓝色方框),整个网络主要分为三个不同的部分。

结果

左图 →随时间变化的训练精度/随时间变化的成本
右图 →随时间变化的测试精度/随时间变化的成本

令人惊讶的是,该模型正在学习如何使用 PCA 池层对 MNIST 图像进行分类。尽管我们需要注意这样一个事实,它几乎没有达到 50%的准确率。(都在测试/训练图像上)。

第 21 个纪元后的最终精度为 53%。

交互代码

对于 Google Colab,你需要一个 Google 帐户来查看代码,而且你不能在 Google Colab 中运行只读脚本,所以在你的操场上复制一份。最后,我永远不会请求允许访问你在 Google Drive 上的文件,仅供参考。编码快乐!同样为了透明,我在训练期间上传了所有的日志。

要访问代码以及培训日志,请点击此处。

最后的话

最终结果非常有趣,因为该模型实际上能够学习如何对 MNIST 图像进行分类。我很高兴地知道,在网络中插入更复杂的操作(如 PCA)是可能的。(带端到端培训)最后,顺便提一下,如果有人有兴趣学习更多关于线性代数的知识,请观看下面的视频系列。( 3Blue1Brown 是一个产出高质量内容的土豆/数学家)

Video From this website

如果发现任何错误,请发电子邮件到 jae.duk.seo@gmail.com 给我,如果你希望看到我所有写作的列表,请在这里查看我的网站。

同时,在我的 twitter 上关注我这里,访问我的网站,或者我的 Youtube 频道了解更多内容。我还实现了广残网,请点击这里查看博文 t。

参考

  1. 李,E. (2018)。张量流 PCA。胡言乱语。检索于 2018 年 5 月 25 日,来自https://ewanlee.github.io/2018/01/17/PCA-With-Tensorflow/
  2. tf.set_random_seed | TensorFlow。(2018).张量流。检索于 2018 年 5 月 25 日,来自https://www . tensor flow . org/API _ docs/python/TF/set _ random _ seed
  3. Iris 数据集-sci kit-学习 0.19.1 文档。(2018).Scikit-learn.org。检索于 2018 年 5 月 25 日,来自http://sci kit-learn . org/stable/auto _ examples/datasets/plot _ iris _ dataset . html
  4. tf.cumsum | TensorFlow。(2018).张量流。检索于 2018 年 5 月 25 日,来自https://www.tensorflow.org/api_docs/python/tf/cumsum
  5. 输入,T. (2018)。Tensorflow:使用 tf.slice 拆分输入。堆栈溢出。检索于 2018 年 5 月 25 日,来自https://stack overflow . com/questions/39054414/tensor flow-using-TF-slice-to-split-the-input
  6. 李,c,,p .,,涂,Z. (2015)。卷积神经网络中的一般化池函数:混合、门控和树。Arxiv.org。检索于 2018 年 5 月 26 日,来自https://arxiv.org/abs/1509.08985
  7. 主成分分析。(2018).En.wikipedia.org。检索于 2018 年 5 月 26 日,来自https://en.wikipedia.org/wiki/Principal_component_analysis
  8. (2018).cs . otago . AC . NZ . 2018 年 5 月 26 日检索,来自http://www . cs . otago . AC . NZ/cosc 453/student _ tutorials/principal _ components . pdf
  9. 李,E. (2018)。张量流 PCA。胡言乱语。检索于 2018 年 5 月 25 日,来自https://ewanlee.github.io/2018/01/17/PCA-With-Tensorflow/
  10. 奇异值分解。(2018).En.wikipedia.org。检索于 2018 年 5 月 26 日,来自 https://en.wikipedia.org/wiki/Singular-value_decomposition
  11. tf.svd |张量流。(2018).张量流。检索于 2018 年 5 月 26 日,来自 https://www.tensorflow.org/api_docs/python/tf/svd
  12. 线性代数预习精华。(2018).YouTube。检索于 2018 年 5 月 26 日,来自https://www.youtube.com/watch?v=kjBOesZCoqc&list = plzhqobowt qd D3 mizm 2 xvfitgf 8 he _ ab
  13. [在线]可从以下网址获取:https://www . quora . com/What-is-an-intuitive-explain-of-singular-value-decomposition-SVD【2018 年 5 月 26 日获取】。
  14. 对 Tensorflow 中使用交互式代码进行批处理规范化有了更深入的理解。(2018).中等。检索于 2018 年 5 月 26 日,来自https://medium . com/@ SeoJaeDuk/deeper-understanding-of-batch-normalization-with-interactive-code-in-tensor flow-manual-back-1d50d 6903 d35
  15. [在线]可从以下网址获取:https://www . quora . com/What-is-an-intuitive-explain-of-singular-value-decomposition-SVD【2018 年 5 月 26 日获取】。
  16. 奇异值分解教程:应用,例子,练习。(2017).统计和机器人。检索于 2018 年 5 月 26 日,来自https://blog . statsbot . co/singular-value-decomposition-tutorial-52c 695315254
  17. (2018).Arxiv.org。检索于 2018 年 5 月 26 日,来自https://arxiv.org/pdf/1502.03167v3.pdf
  18. [ ICLR 2015 ]追求简单:具有交互码的全卷积网。(2018).走向数据科学。检索于 2018 年 5 月 26 日,来自https://towards data science . com/iclr-2015-努力简化-所有卷积网-交互式代码-手册-b4976e206760
posted @ 2024-10-13 15:17  绝不原创的飞龙  阅读(10)  评论(0编辑  收藏  举报