TowardsDataScience-博客中文翻译-2016-2018-二十-
TowardsDataScience 博客中文翻译 2016~2018(二十)
原文:TowardsDataScience Blog
协议:CC BY-NC-SA 4.0
如何用 VS 代码和 Jupyter 笔记本改善你的工作流程💘
原文:https://towardsdatascience.com/how-to-improve-your-workflow-with-vs-code-and-jupyter-notebook-f96777f8f1bd?source=collection_archive---------2-----------------------
我喜欢 VS 代码,也喜欢 Jupyter 笔记本😍。两人都擅长自己的世界。但是为了改进我的工作流程,我必须在他们的世界之间建立一座桥梁。
数据科学家喜欢 Jupyter 笔记本。它们是创建可重复实验的最佳选择。Visual Studio 代码将经典的轻量级文本编辑器的易用性与更强大的 IDE 类型的功能结合在一起,只需要很少的配置。它附带了许多令人敬畏的扩展,使它成为常规使用的一个非常强大的工具。
不幸的是,每次查看 IPython 文档时,您都必须运行 Jupyter 实例并在浏览器中打开笔记本。如果我们在 VS 代码中打开一个 IPython 笔记本,我们只能看到一个 JSON 文档,而看不到漂亮的渲染文档。
我的工作流程包括在 Jupyter 笔记本上做原型和实验,然后用 VS 代码创建一个独立的 Python 脚本。Python 代码的 Git 版本简化了我的工作流程。
让我有点失望的是,即使是为了查看预览,我也必须启动一个 Jupyter 实例,并打开我的 RAM hungry Chrome 浏览器。😃
所以我决定不运行 Jupyter 实例来解决这个预览笔记本的小问题。为了更进一步,我决定在 VS 代码中实现。
结果是 nbpreviewer,一个 VS 代码扩展,帮助你在 VS 代码中预览渲染 Jupyter notebook。你甚至可以用 VS 代码与交互式图形可视化进行交互。
在这里尝试一下
[## VS 代码 Jupyter 笔记本预览器- Visual Studio 市场
这是一个易于使用的扩展,用于在 VS 代码中预览 Jupyter 笔记本
marketplace.visualstudio.com](https://marketplace.visualstudio.com/items?itemName=jithurjacob.nbpreviewer)
演示
Playing with plotly 3D visualization within VS Code
Bridging two worlds 😃
如果您对扩展的源代码感兴趣,请访问我的 GitHub 库。请关注我的下一篇博文,了解我是如何创建扩展的,以及您如何轻松地创建自己的扩展。
[## jithurjacob/vscode-nbpreviewer
一个 VS 代码扩展,用于预览 Jupyter 笔记本
github.com](https://github.com/jithurjacob/vscode-nbpreviewer)
记得给本帖一些💚如果你喜欢的话。关注我了解更多内容:)
改善神经网络的性能
原文:https://towardsdatascience.com/how-to-increase-the-accuracy-of-a-neural-network-9f5d1c6f407d?source=collection_archive---------2-----------------------
神经网络是机器学习算法,提供许多用例的准确性状态。但是,很多时候,我们正在构建的网络的准确性可能不令人满意,或者可能不会让我们在数据科学竞赛的排行榜上名列前茅。因此,我们一直在寻找更好的方法来提高我们模型的性能。有许多技术可以帮助我们实现这一目标。跟着去了解他们,建立你自己精确的神经网络。
检查是否过度配合
确保您的神经网络在测试数据上表现良好的第一步是验证您的神经网络没有过度拟合。好了,打住,什么叫过度拟合?当您的模型开始记忆来自训练数据的值而不是从中学习时,就会发生过度拟合。因此,当您的模型遇到一个它以前没有见过的数据时,它无法对它们执行良好的操作。为了让你更好的理解,我们来看一个类比。我们都会有一个擅长记忆的同学,假设数学考试即将来临。你和你擅长记忆的朋友从课本开始学习。你的朋友继续记忆教科书上的每一个公式、问题和答案,但另一方面,你比他更聪明,所以你决定依靠直觉解决问题,并学习这些公式是如何发挥作用的。考试日到了,如果试卷中的问题直接取自教科书,那么你可以期待你的记忆朋友在这方面做得更好,但是,如果问题是涉及运用直觉的新问题,你在考试中做得更好,而你的记忆朋友却悲惨地失败了。
如何识别自己的模型是否过度拟合?你可以交叉检查训练的准确性和测试的准确性。如果训练精度比测试精度高得多,那么你可以假定你的模型已经过度拟合了。您也可以在图表上绘制预测点来验证。有一些避免过度拟合的技巧:
- 数据规范化(L1 或 L2)。
- 中断——随机中断神经元之间的连接,迫使网络寻找新的路径并进行归纳。
- 早期停止—加速神经网络的训练,从而减少测试集中的错误。
超参数调谐
超参数是您必须对网络进行初始化的值,这些值不能在训练时被网络学习到。E.x:在卷积神经网络中,一些超参数是内核大小、神经网络的层数、激活函数、损失函数、使用的优化器(梯度下降,RMSprop)、批量大小、要训练的时期数等。
每个神经网络将有其最佳的超参数集,这将导致最大的准确性。您可能会问,“有这么多的超参数,我如何为每一个选择使用什么?”不幸的是,没有直接的方法来确定每个神经网络的最佳超参数集,因此它主要是通过反复试验获得的。但是,下面提到了一些超参数的最佳实践,
- 学习率——选择一个最佳的学习率是很重要的,因为它决定了你的网络是否收敛到全局最小值。选择一个高的学习率几乎不会让你达到全局最小值,因为你很有可能超过它。因此,你总是在全局极小值附近但从不收敛于它。选择小的学习速率可以帮助神经网络收敛到全局最小值,但是这需要大量的时间。所以,你要对网络进行更长时间的训练。小的学习率也使网络容易陷入局部最小值。即网络将收敛到局部最小值,并且由于小的学习速率而不能摆脱它。因此,在设定学习率时,你必须小心。
- 网络架构——没有一个标准的架构能在所有的测试案例中给你高的准确性。你必须进行实验,尝试不同的架构,从结果中获得推论,然后再试一次。我建议的一个想法是使用经过验证的架构,而不是构建自己的架构。对于图像识别任务,你有 VGG 网,Resnet,谷歌的 Inception 网络等。这些都是开源的,并且已经被证明是高度准确的,因此,你可以复制它们的架构,并根据你的目的进行调整。
- 优化器和损失函数——有无数的选项可供你选择。事实上,如果有必要的话,你甚至可以定义你自己的损失函数。但常用的优化器有 RMSprop、随机梯度下降和 Adam。这些优化器似乎适用于大多数用例。如果你的用例是分类任务,常用的损失函数是分类交叉熵。如果您正在执行回归任务,均方误差是常用的损失函数。请随意试验这些优化器的超参数,以及不同的优化器和损失函数。
- 批量大小和时期数量——同样,没有适用于所有用例的批量大小和时期的标准值。你必须尝试不同的方法。在一般实践中,批处理大小值被设置为 8、16、32…历元的数量取决于开发人员的偏好和他/她拥有的计算能力。
ReLU Activation Funciton
- 激活函数—激活函数将非线性函数输入映射到输出。激活函数非常重要,选择正确的激活函数有助于模型更好地学习。如今,校正线性单元(ReLU)是最广泛使用的激活函数,因为它解决了消失梯度的问题。早期的 Sigmoid 和 Tanh 是使用最广泛的激活函数。但是,它们遇到了梯度消失的问题,即,在反向传播期间,当它们到达开始层时,梯度的值减小。这阻止了神经网络随着层数的增加而变得更大。ReLU 能够克服这个问题,因此允许神经网络具有较大的规模。
算法集成
如果单个神经网络不像您希望的那样准确,您可以创建一个神经网络集合,并结合它们的预测能力。您可以选择不同的神经网络架构,在数据的不同部分对它们进行训练,然后集成它们,利用它们的集体预测能力来获得测试数据的高准确性。假设,你正在构建一个猫和狗的分类器,0-猫和 1-狗。当组合不同的猫和狗分类器时,基于个体分类器之间的皮尔逊相关性,集成算法的准确度增加。让我们看一个例子,取 3 个模型并测量它们各自的准确度。
Ground Truth: 1111111111
Classifier 1: 1111111100 = 80% accuracy
Classifier 2: 1111111100 = 80% accuracy
Classifier 3: 1011111100 = 70% accuracy
三个模型的皮尔逊相关系数都很高。因此,将它们组合在一起并不能提高精度。如果我们使用多数投票将上述三个模型集成,我们会得到以下结果。
Ensemble Result: 1111111100 = 80% accuracy
现在,让我们来看三个模型,它们的输出之间具有非常低的皮尔逊相关性。
Ground Truth: 1111111111
Classifier 1: 1111111100 = 80% accuracy
Classifier 2: 0111011101 = 70% accuracy
Classifier 3: 1000101111 = 60% accuracy
当我们集成这三个弱学习者时,我们得到以下结果。
Ensemble Result: 1111111101 = 90% accuracy
正如你在上面看到的,具有低皮尔逊相关性的弱学习者的集合能够胜过它们之间具有高皮尔逊相关性的集合。
缺乏数据
在执行了上述所有技术之后,如果您的模型在测试数据集中仍然表现不佳,这可能是由于缺少训练数据。在许多用例中,可用的训练数据量是有限的。如果你不能收集更多的数据,那么你可以求助于数据扩充技术。
Data Augmentation Techniques
如果您正在处理图像数据集,可以通过剪切图像、翻转图像、随机裁剪图像等方式将新图像添加到训练数据中。这可以为神经网络训练提供不同的例子。
结论
这些技术被认为是最佳实践,在提高模型学习特征的能力方面通常是有效的。这似乎是一篇很长的帖子,谢谢你通读,如果这些技巧对你有用,请告诉我:)
如何使用 Cmake 从源代码构建和安装 OpenCV 和额外的模块,并配置您的 Pycharm IDE
原文:https://towardsdatascience.com/how-to-install-opencv-and-extra-modules-from-source-using-cmake-and-then-set-it-up-in-your-pycharm-7e6ae25dbac5?source=collection_archive---------1-----------------------
OpenCV(开源计算机视觉)是一个非常强大的图像处理和机器学习任务库,它还支持 Tensorflow、Torch/Pytorch 和 Caffe。这个库是跨平台的,你可以在 CPU 的支持下 pip 安装它(如果你使用 Python 的话)。或者,举例来说,如果您想在 GPU 支持下使用它,您可以从源代码构建它,这更复杂。本文介绍了在 Linux Ubuntu 机器上从源代码构建 OpenCV 的过程。
特别是,本文解释了如何:
- 使用 Cmake GUI 从源代码安装 OpenCV master 和 OpenCV contrib 文件
- 在 Cmake 中构建时,通过适当地选择/取消选择,仅选择您想要的 OpenCV contrib 模块
- 配置您的 Pycharm IDE 以识别生成的 OpenCV 安装
几个月前(2018 年 5 月),我决定使用 Cmake 从头构建 openCV,因为我希望 OpenCV 在我的本地机器上有 Nvidia GPU 支持,而不是只在 CPU 上运行 OpenCV。我第一次安装 openCV 是在 5 月份,从 github 资源库下载,网址是:
[## opencv/opencv
开源计算机视觉库。在 GitHub 上创建一个帐户,为 opencv/opencv 开发做贡献。
github.com](https://github.com/opencv/opencv)
下载完成后,我用 Cmake 安装了 openCV。我当时没有意识到的是,由于没有将“opencv_contrib”作为 Cmake 安装的一部分,我错过了多少 openCV 的功能。这些是 OpenCV 的附加模块。
[## opencv/opencv_contrib
OpenCV 额外模块的存储库。通过在…上创建帐户,为 opencv/opencv_contrib 开发做出贡献
github.com](https://github.com/opencv/opencv_contrib)
当时我还不知道 openCV contrib(T1 ),并认为安装 openCV 本身会给我提供 openCV 必须提供的几乎所有功能。那么,从源代码来看,标准的“openCV”安装缺少哪种模块呢?比如 openCV 的 TrackerMedianFlow(openCV 中的对象跟踪器之一)。如果你从头开始制作 openCV,没有 opencv_contrib 文件,这个对象跟踪器不包括在内。这个跟踪器甚至包含在带 CPU 支持的 openCV 的标准 pip 安装中。如果您感兴趣,这里解释了可用的 OpenCV 跟踪器:
[## OpenCV:OpenCV 跟踪器简介
在本教程中,您可以选择视频或图像列表作为程序输入。如帮助中所写,您…
www.docs.opencv.org](https://www.docs.opencv.org/3.1.0/d2/d0a/tutorial_introduction_to_tracker.html)
因此,本文解释了我使用 Cmake 重新安装 OpenCV 的过程,但是这次选择了我需要的额外的 openCV 功能,可以从 opencv_contrib 库获得。安装过程有几个“陷阱”(这当然让我);我已经解释了这些是如何绊倒我的,以及我是如何解决它们的。
请注意,我正在描述 OpenCV 的 Cmake 过程,我的机器上已经安装了一些东西,下一段将详细介绍。
我的系统规格和我已经安装的内容:
- 我的操作系统: Linux Ubuntu 16.04 LTS
- Nvidia GPU: GeForce GTX 1050,驱动程序版本:384.130(你可以在电脑上打开一个终端,输入
nvidia-smi
来检查这一点 - 从源代码构建应用程序: CMake 3.5.1 (在 Linux 上可以通过打开计算机上的终端并键入
sudo apt-get install cmake)
来安装)。 - CUDA 9.0
这篇文章中的步骤概述如下:
- 从 github 克隆最新的 openCV master 和 openCV contrib 模块
- 在 Cmake GUI 中,配置,然后在您创建的新“build”文件夹中生成新的构建文件
- 在您的终端中,导航到“build”文件夹,然后运行“make”和“install”命令。“make”命令将花费相当长的时间,并且可能会产生错误(将在下面讨论)。
- 检查这个进程在哪里安装了在 Cmake 进程中创建的 cv2.xxx.so 文件(如果需要的话,用符号链接)
- 在 Python 控制台中检查 openCV 是否已经安装,以及它是否被 Python 识别
- 在 Pycharm 中配置 openCV,以便 Pycharm IDE 识别新安装的 OpenCV 包并检查结果。
使用 Cmake 从源代码下载文件并进行编译的更多详细步骤
步骤 1 : 将主 openCV 文件(opencv_master)和附加模块(opencv_contrib)从 Github 下载/克隆到您的电脑上
图 1 显示了从 Github 下载的 opencv_master 文件夹。下载或克隆主要 openCV 文件后,我创建了一个名为“ build ”的新(空)文件夹。Cmake 将在这里为您的新构建创建文件。
Fig 1: Downloaded opencv-master folder with new empty ‘build’ folder I created inside
步骤 2:在 Cmake GUI 中,“配置”然后在您创建的新“构建”文件夹中“生成”新的构建文件
通过在 bash 终端的$符号后键入以下命令,打开 Cmake GUI:
$ cmake-gui
这将打开一个 Cmake GUI 窗口,如图 2 所示。在 Cmake GUI 中,您会注意到,在从 Github 下载资源库时,我已经将 opencv-master 文件放在我的计算机上名为“…/opencv-master”的文件夹中,然后在 GUI 中,我在“Where are the source code”选项中指向它。如步骤 1 所述,在 opencv-master 文件中,我创建了一个名为“build”的新的空子文件夹。这个构建文件夹是二进制文件将要构建的地方,文件路径设置“在哪里构建二进制文件”指向这个空文件夹。关于 Cmake 的伟大之处在于,如果你完全塞住了你的构建过程(在我弄清楚我在做什么之前,我做了令人沮丧的大量工作…)然后,在再次开始构建过程之前,您应该删除构建文件夹的内容。
Fig 2: Cmake GUI example building opencv-master
在 Cmake GUI 中运行配置命令
按下'配置'(图 2 左侧的按钮)。运行 configure 将填充构建文件的内容,该文件到目前为止是空的。首次配置时,这将提示您为交叉编译指定工具链。我选择了原生工具链。当这个过程完成时——这并不需要很长时间——您应该在窗口中得到一条消息,说“配置完成”。
将 OpenCV Contrib 中的额外模块添加到您的 OpenCV 构建中
按下 GUI 上的'配置',然后浏览参数并查找“OPENCV_EXTRA_MODULES_PATH”。浏览参数,寻找名为 OPENCV_EXTRA_MODULES_PATH 的形式;使用搜索表单快速关注它。单击“advanced ”(高级)复选框(分别显示在图 2 和图 3 的右上方),通过勾选或取消勾选相应的复选框,搜索您特别希望包括或排除的模块。
Fig 3: Searching for, selecting and deselecting additional openCV modules (e.g. opencv_face)
在 Cmake GUI 中运行“生成”命令
配置完成后,按下'生成'(见图 3),同样应出现“生成完成”。
步骤 3:在您的终端中,导航到“build”文件夹,运行“make ”,然后运行“install”命令。
在 bash 终端中使用以下命令导航到构建文件夹(这里的示例显示了导航到我的构建文件夹,因此相应地修改您的路径):
$ cd /home/joanne/opencv-master/build
然后在命令行中输入 cmake 命令:
$ cmake .
过了一会儿,这将产生一条消息(如图 4 所示):
" —配置完成—生成完成
—构建文件已写入:/home/Joanne/opencv-master/Build"
(根据您将构建文件写入的位置,此消息会有所不同)。
Fig 4: Running the cmake command in your build folder
接下来,在命令行上,键入:
$ make -j8
请注意,数字“8”指的是您拥有的 CPU 内核的数量(您在这里的数量可能不同)。那个-j[8]标志是并行的,因此可以加速构建。正是这个“制作”过程需要时间(大约 2 个小时),而且对我来说,会产生一些错误。当您的“make”过程成功完成时,通过以下命令在您的终端中再次执行最后的安装步骤:
$ sudo make install
注意,使用这些“make”和“install”命令,您可能不需要在它们前面包含“sudo”来获得 Linux 上的必要权限。我发现我的机器需要这个。2018 年 5 月,我已经在我的机器上安装了来自我的原始 openCV 版本的 OpenCV。运行' sudo make install 命令成功覆盖了原始安装。
抓到你了!对您的 Cmake 构建进行故障排除
Trip hazard 1 : 确保你的 openCV 和 openCV_contrib 代码同步,在同一天 下载
正如我在本文开头提到的,我最初是在 2018 年 5 月下载并构建 openCV 的。因为当时我没有包含 openCV_contrib 模块,所以我不得不重新构建 openCV,这一次包含了 openCV_contrib 模块 和 。
我在 2018 年 8 月下载了 openCV_contrib 代码,但最初尝试结合我在 2018 年 5 月下载的 openCV 代码在 Cmake 中构建。这三个月的差异足以使 openCV 主代码库和 openCV_contrib 模块之间出现不兼容。结果,当 make 进程试图构建 contrib 模块时,我的构建在' make -j8 '阶段总是失败。这导致整个 openCV 'cmake '构建过程失败。例如,模块“生物感应失败,如图 5 所示。最初,当我遇到这样的故障时,我通过 GUI 排除了那些额外的模块,并再次运行了重建过程。然而,经过几次尝试后,很明显有许多模块以这种方式失败了,我意识到问题的根源是主要的 openCV 代码来自 2018 年 5 月,与最近的 contrib 模块不兼容。因此,我不得不下载 2018 年 8 月的 openCV 代码,并将其用于我的 Cmake 构建,以确保与 2018 年 8 月的 contrib 模块兼容。
Fig 5: Contrib module ‘bioinspired’ failing as a result of incompatibility between main OpenCV code version and the OpenCV contrib modules
跳闸危险 2:可能有奇怪的 openCV_contrib 模块就是不工作
即使您已经确保在同一天从代码库构建 openCV 和 openCV_contrib,也可能有奇怪的 openCV_contrib 模块会失败。 contrib 模块本质上更具实验性,因此还没有成为标准的 openCV 版本。
我发现只有一个 openCV 模块不管我做什么都不工作,并导致我的整个构建失败,这就是“ xfeatures2d ”。图 5 显示了这个附加模块的失败,它使得整个构建陷入停顿。
Fig 6: Build failure due to the xfeatures2d openCV_contrib module
事实证明,我不需要额外的“ xfeatures2d ”模块。我使用 Cmake GUI 从构建中排除这个模块(参见在步骤 2 中从 OpenCV Contrib 中添加额外的模块到 OpenCV 构建中),然后使用上面的步骤重新构建
跳闸危险 3 : 从源代码重建时,删除“构建”文件的内容
如上所述,如果您不得不多次从源代码构建,在 Cmake GUI 中再次运行配置和生成命令之前,按“生成”会确保您删除了构建文件的内容(留下一个空的构建文件)。
第 4 步:查看该进程在何处安装了 openCV”。所以“在 Cmake 过程中创建的文件
假设你的库已经安装成功,你应该可以找到你的' cv2.xxx.so '文件。在我的例子中,文件是“cv2 . cpython-35m-x86 _ 64-Linux-GNU . so”安装在“/usr/local/lib/python 3.5/dist-packages”中。我的另一个"。所以与 openCV 相关的文件位于“”/usr/local/lib”路径下,如图 7 所示。
Fig 7: The location of my openCV .so files
第 5 步:在 Python 控制台中检查 openCV 是否已经安装,以及它是否被 Python 3 识别
当我使用 Pycharm 进行 Python 开发时,我使用 Pycharm 中的 console 选项卡来检查 OpenCV 的安装。如图 10 所示,输出显示了到的完整路径。所以归档吧。
Fig 10. Checking the installation path of OpenCV using the python console tab in Pycharm
步骤 6:在 Pycharm 中配置 openCV,确保 Pycharm IDE 能够识别新安装的 OpenCV 包
尽管 Pycharm 中的 Python 控制台可以识别 openCV(如图 10 所示),但是第 6 步可以确保 Pycharm IDE 能够识别新安装的 openCV 包。在主菜单中,如果您选择 File -> Settings(或 Settings for new projects),那么这将显示项目解释器,如图 11 所示。
Fig 11. Project Interpreter selected (note ‘cog’ symbol in top right shown by pointer)
在图 11 中窗口的右上方,有一个 cog 图标,如果你点击它,会给你“添加”或“显示所有”项目解释器的选项。选择“显示全部”会打开一个新窗口,显示所有可用的项目解释器(我在这里稍微编辑了一下)。
Fig. 12: Path addition in Pycharm IDE
对于给定的解释器,您可以添加路径。当你点击图 12 右手边的按钮时(当你悬停在上面时,显示“显示所选解释器的路径”),一个名为“解释器路径”的新窗口打开(图 12)。在该窗口中,可以通过按“+”号添加新路径。我在图 12 中添加了一个新路径,名为“ /usr/local/lib ”。我发现这对于 Pycharm IDE 识别我新安装的 OpenCV 是必要的。
Fig.12: Adding a new interpreter path in the Pycharm Integrated Development Environment
要测试 Pycharm IDE 是否识别新的 OpenCV 安装,您可以尝试在 IDE 中创建一个新的 python 文件。尝试主 OpenCV 构建中缺少的“TrackerMedianFlow”现在是可用的,如图 13 所示。
Fig. 13: Checking import of OpenCV and additional modules e.g. TrackerMedianFlow
就是这样!OpenCV(在我的例子中有 GPU 支持)现在已经从源代码安装好了,可以在 Python 控制台或 Pycharm IDE 中使用。
如何整合 Google Sheets 和 Jupyter 笔记本
原文:https://towardsdatascience.com/how-to-integrate-google-sheets-and-jupyter-notebooks-c469309aacea?source=collection_archive---------2-----------------------
Jupyter 笔记本的功能非常强大。与 Google Sheets 或 Microsoft Excel 不同,它们可以轻松处理大量数据。只需几行代码,您就可以执行复杂的统计操作或操纵数据。你可以运行复杂的 for-loops 来创建蒙特卡洛模拟,而不需要像水晶球这样昂贵的附加组件。
但是有时您需要将这种强大的功能与简单且几乎普遍理解的电子表格 UI 结合起来。
例如,您可能想在一个小数据集上练习您的 Python 代码,您可以在 Google Sheets 中轻松直观地操作它。或者你可能需要将复杂分析的结果输出到电子表格中,以便你的非编码人员 CEO 或客户能够阅读和理解。或者,您可能会发现在电子表格中做一些简单的数据工作更容易,而在 Python 中只做最复杂的部分。
我曾经在 Google Sheets 中完成我的电子表格工作,下载一个 CSV 文件,将 CSV 文件数据拉入 Jupyter,处理我的数据,导出另一个 CSV 文件,然后将其上传回 Google Sheets。对每次调试或新的数据迭代进行清洗和重复。呸。
但后来我意识到,谷歌提供了一个 API,可以将工作表连接到你能想到的任何第三方应用,包括 Jupyter 笔记本。在修补了一会儿之后,我想出了如何轻松地将最新的数据从我的 Google Sheets 导入 Jupyter,并将数据从 Jupyter 输出回 Google Sheets。
这需要一点一次性设置。但是,如果您发现自己在工作表和 Jupyter 之间来回切换,或者偶尔想念电子表格的易用性,或者需要从 Jupyter 快速更新工作表中的数据,那么本教程就是为您准备的。
注意:我使用的是 Python 2.7.14 和 Anaconda 4 . 3 . 30 版本。你可以在这里看到我的完整环境,在这里看到我在第 2 部分中使用的完整示例笔记本。
订阅我的简讯
第一部分——创建你的谷歌开发者证书
在将我们的 Jupyter 笔记本连接到我们的 google sheets 之前,我们首先必须创建允许访问我们的 google Drive 的 Google 开发人员凭据。这一部分有点长也有点难,但是你只需要对所有的笔记本和纸张做一次。
创建一个 Google 开发者项目
进入谷歌开发者控制台。
点击创建项目。
输入一个项目名称——我只为我所有的笔记本使用一个项目,而不是为每个项目创建一个新项目,所以我将我的项目命名为“Jupyter 和 Google Sheets”。如果愿意,您还可以重命名项目 ID。
点击创建。
启用 Google Drive API
创建项目后,Google 会带你回到开发者控制台。我必须刷新页面才能看到我的新项目。单击您的新项目。
点击左侧的汉堡菜单,进入 API & Services 仪表盘,选择API&Services>仪表盘。
点击 Google Drive API 。
点击启用。
好吧。现在我们已经创建了我们的 Google Drive 项目。让我们获得使用它的凭证。
创建凭据以使用 Google Drive API
启用 Google Drive API 后,Google 应该会带您进入项目的 Google Drive API 控制台。
点击创建凭证。
选择其他用户界面中的“您将从哪里调用 API?”。
选择用户数据用于“您将访问哪些数据?”然后点击我需要什么凭证?。
输入名称并点击创建客户端 ID 。
选择您的电子邮件地址,输入产品名称,然后单击继续。
下载您的凭证,并将其保存到您打算创建 Jupyter 笔记本的文件夹中。
创建服务帐户凭据
设置凭据的最后一步是创建服务帐户凭据,这样我们就可以将我们的客户端(我们刚刚创建的)连接到我们实际的个人 Google Drive。
返回凭证仪表板,创建一个服务帐户密钥。
选择新建服务账户,将服务账户名称设置为 Google Sheets ,将角色设置为服务账户用户,将密钥类型保留为 JSON ,点击创建。
将 JSON 文件保存到您打算创建 Jupyter 笔记本的文件夹中(确保文件名中没有像这样的空格)。
好吧。咻。我们有我们的谷歌开发人员证书,有权访问我们的谷歌驱动器,因此谷歌表。
第二部分—将 Jupyter 连接到 Google Sheets
现在让我们将 Jupyter 笔记本连接到 Google Sheet。
使用 conda install 和 pip 安装所需的软件包。
conda install pandas jupyter pip install gspread oauth2client df2gspread
上面所有的工作你只需要做一次。从现在开始,将数据从 Google Sheet 放入 Jupyter 笔记本变得很容易,反之亦然。
首先,你需要一张谷歌表。这可以是任何工作表。我们将使用我的美国首席执行官文章中的候选人得分数据。
要允许您的 Jupyter 笔记本访问 Google 表单,您需要与您在第一部分中创建的 Google 开发者凭证共享该表单。为此,请在 Jupyter 或文本编辑器中打开服务帐户凭据文件。
复制 client_email 属性。
回到你的谷歌表单,点击分享。
将 client_email 粘贴到人物框中,点击发送。
您需要对任何想要放入 Jupyter 笔记本的工作表重复上述步骤。
将谷歌工作表数据放入 Jupyter 笔记本
打开或创建 Jupyter 笔记本。我的笔记本的完整版本可以在这里找到。
导入库
import pandas as pd import gspread from oauth2client.service_account import ServiceAccountCredentials
连接到您的服务帐户
scope = ['https://spreadsheets.google.com/feeds'] credentials = ServiceAccountCredentials.from_json_keyfile_name('./<YOUR CREDENTIALS FILENAME>.json', scope) gc = gspread.authorize(credentials)
将谷歌电子表格中的数据导入 Jupyter
在电子表格的 url 中找到您想要导入的电子表格的 Google Sheet key ,如下所示。
复制密钥并将其粘贴到以下代码中。
spreadsheet_key = '1f0OwtmuTk1fTdhnn4tuvVcPCZjdb00D79dWw4RFhYs0' book = gc.open_by_key(spreadsheet_key) worksheet = book.worksheet("Candidate Data") table = worksheet.get_all_values()
输入要导入到上述代码中的工作表的名称。
如果您运行代码,您会看到表变量现在有了来自 Google 工作表的行,如下所示。
将工作表数据转换成熊猫数据框架
现在我们已经在 Jupyter 笔记本中有了工作表数据,我们想要将包含在表变量中的数据转换成一个干净的 pandas 数据框架,以便于操作。
##Convert table data into a dataframe df = pd.DataFrame(table[1:], columns=table[0]) ##Only keep columns we need df = df[['Order', 'Candidate', 'Position', 'Start Date', 'End Date', 'Years of Experience', 'Points']] ##Convert number strings to floats and ints df = df.apply(pd.to_numeric, errors='ignore') ##Convert date strings to datetime format df['End Date'] = pd.to_datetime(df['End Date'],infer_datetime_format=True) df['Start Date'] = pd.to_datetime(df['Start Date'],infer_datetime_format=True) df.head()
还有瓦拉!你已经将你的谷歌表单数据转换成了一个漂亮、干净的熊猫数据框架。如果您更改了工作表中的数据,并希望更新数据框架,只需重新运行以下所有代码:
book = gc.open_by_key(spreadsheet_key)
前进。
从 Jupyter 笔记本推送到 Google Sheet
我们还可以将 Jupyter 笔记本中的数据发送回 Google Sheet。
首先,让我们处理数据。数据帧的 groupby 功能很难在一个工作表中复制,所以我们就这么做吧。
candidate_groups = df.groupby('Candidate') scores_df = candidate_groups.sum() scores_df['Order'] = candidate_groups.first() scores_df.head()
这将创建一个新的分数数据框架,如下所示…
要将这些数据输出到名为“Jupyter Manipulated Data”的工作表下的同一个 Google 工作表中,只需运行以下代码。
from df2gspread import df2gspread as d2g wks_name = 'Jupyter Manipulated Data' d2g.upload(scores_df, spreadsheet_key, wks_name, credentials=credentials, row_names=True)
然后嘣。谷歌表用我们的 Jupyter 数据更新…
现在,在 Google Sheets 和 Jupyter notebook 之间来回推送数据简直易如反掌。我每天都在使用它,并不断为它寻找新的功能和工作流程。我希望你会和我一样觉得它很有用。
获取更多科技小技巧, 订阅我的简讯 !
原载于www.countingcalculi.com。
如何组织你的研究项目:文件夹结构
原文:https://towardsdatascience.com/how-to-keep-your-research-projects-organized-part-1-folder-structure-10bd56034d3a?source=collection_archive---------2-----------------------
一个文件夹结构,带有在线工具,让你的研究项目有条不紊。
所有的研究人员都知道以一种清晰而有条理的方式发表论文的重要性。然而,对于我们在研究项目的后端(即代码和数据层)组织和维护代码和数据的方式,情况往往就不一样了。项目的这一部分通常是不可见的,当截止日期临近时,保持项目有序的良好意图往往是最先飞出窗外的事情之一。虽然可以理解,但我认为这是一个有很大改进空间的领域。我们花了大部分时间与项目的这一部分互动,如果我们保持它的整洁和有组织性,我们可以节省很多时间和挫折!
在这一系列文章中,我将描述和分享一些我多年来复制、改编和开发的最佳实践,以保持我的研究和编码项目有条理。诚然,我没有比任何人更多的资格来谈论这个话题。然而,我认为缺少面向易于使用和实现,同时仍然有效地保持事物有序的最佳实践。因此,本系列文章旨在为这种最佳实践提供一个起点。我希望这是一个社区驱动的努力,所以如果你有额外的提示或建议,请通过评论或给我发电子邮件来分享,以便我可以整合和添加它们!
第一部分:文件夹结构
我想开始的第一个主题是文件和文件夹的组织。从正确的文件夹结构开始项目,甚至在编写第一行代码之前,可以提供一种简单且相对不引人注目的方式来保持有序。Matthew Gentzkow 和 Jesse Shapiro 的指南是一个很好的起点,该指南名为“社会科学的代码和数据:从业者指南”。它们描述了各种核心“规则”,值得一读。然而,他们的实际建议,至少对我来说,从来没有真正解决过我的组织问题。但这是一个很好的起点!基于他们的基本原则,我开发了一个适应版本的目录结构,它更加全面,同时仍然保持直观和易于使用。下图用图形表示了这一点:
这种文件夹结构背后的主要思想是,您有一个顶层项目文件夹,它包含 4 个子文件夹:0 _ 数据、1 _ 代码、2 _ 管道和3 _ 输出。我将在下面更详细地描述每个文件夹:
0_data 包含从外部来源检索或手动创建的所有输入数据。例如,这包括从数据库(如 Compustat)下载的数据,但也包括包含您手动分类的数据的 Excel 表。这里的核心原则是该文件夹中的任何内容都不应该被修改。此文件夹中的数据应该与您检索或手动创建的方式保持一致。
1_code 包含你所有的代码文件。这包括例如 Python、Stata、R 或 SAS(或其组合)的代码文件。此外,我建议以数字开头来命名代码文件,以表示执行的顺序。这使得文件应该以什么样的顺序执行变得显而易见(您还可以在. bat /中进一步形式化)。sh 文件,如果你想的话)。
2_pipeline 为 1_code 文件夹中包含的每个代码文件包含一个单独的子文件夹,它们根据名称(减去文件扩展名)进行对应。这意味着,例如, 1_code 中的代码文件“0_load_data.ipynb”将在 2_pipeline 文件夹中有一个名为“0_load_data”的子文件夹。主要思想是,由代码文件生成的所有输出最终都在它们对应的管道文件夹中。这使得理解数据如何在代码文件之间流动变得非常容易,因为数据位置指示了它是在哪里生成的。为了进一步组织生成的输出,我建议在每个子文件夹中包含以下文件夹: out 、 store 和 tmp 。
2_pipeline - > 子文件夹 - > out 包含您保存的文件,以便在将来的代码文件中加载它们。这些通常是当前代码文件的“最终产品”。
2_pipeline - > 子文件夹 - > store 包含您保存的打算加载到当前代码文件中的文件。例如,在需要一段时间来运行部分代码的情况下,可以使用这种方法,以避免每次需要间歇地将生成数据的进度保存到 store 文件夹时都必须重新运行这些部分。
2_pipeline - > 子文件夹 - > tmp 包含您出于检查目的或其他临时原因而保存的文件。基本原则是你不必担心 tmp 文件夹中的任何东西会被删除,因为它只是一个临时的目的。
3_output 包含任何要进入纸张的最终输出文件。这包括表格和图表等文件。
还有几个额外的原则值得一提:
- 您应该只从 0_data 文件夹或 2_pipeline 子文件夹中的 out 文件夹中加载数据。
- 您应该只从属于代码文件的 out 文件夹中加载数据,这些代码文件在您正在处理的当前代码文件之前执行。例如,当您在代码文件“ 2_process_data ”中工作时,千万不要从“ 5_run_analysis ”的 out 文件夹中加载数据。这是为了保证代码文件能够按顺序执行。
- 务必将工作目录设置为顶级项目文件夹。这使您能够使用相对路径来引用各种文件夹,从而使整个项目文件夹可移植。换句话说,使用相对路径,您可以将项目文件夹复制到另一台计算机,只要工作目录设置为顶级项目文件夹,所有代码都将正常工作。
- 我通常会将 0_data 、 1_code 、 2_pipeline 、 3_data 文件夹放在一个名为“experimental”的父文件夹中,并创建其他几个父文件夹,如:“administrative”、“explorative”和“paper”。通过这种方式,我也可以把我所有的其他文件,比如那些写论文的文件,组织好。
如果遵循这种文件夹结构,任何人都应该能够很容易地分辨出原始数据是什么,代码应该如何执行,以及数据如何在不同的代码文件之间流动。这不仅对试图使用或复制您的代码的其他人有益,而且当您在一段时间没有使用代码之后需要与代码进行交互时,这也是一个巨大的时间节省器。
但是等等,还有!
正如我前面提到的,从研究项目一开始就使用这样的文件夹结构是很重要的。然而,我完全理解,在热情地开始一个新的研究项目的过程中,不得不处理所有这些文件夹的创建是不太吸引人的。幸运的是,我为这个问题创建了一个解决方案!使用我的在线工具,在选择一些基本选项后,您可以简单地下载一个 zip 文件,其中已经为您设置了整个目录结构。只需将该文件夹解压缩到所需的位置,就可以开始了!
https://www.tiesdekok.com/folder-structure-generator/
我还包含了 Python 的入门模板(都是。py 文件和笔记本)、Stata 和 R 代码,用于将工作目录更改为项目文件夹并创建管道文件夹。你所需要做的就是将你需要的模板文件复制到 1_code 文件夹中,并将其重命名为你想要对该文件执行的任何操作。然后,如果您在代码文件中修改 NAME 参数(如果您使用 Stata / R 还有 PROJECT_DIR 参数)并运行代码,它将自动检查相应的管道文件夹是否存在,如果不存在,则为您生成它。它还提供了一个特定于该代码文件夹的“管道”变量,以便您在保存文件时可以轻松地引用它。每个模板文件还包含如何加载和保存数据的参考示例,例如:
我希望这是一个有趣的阅读,如果你有意见,评论,或建议,请让我知道评论下面或给我发电子邮件!
如何在你梦想的公司找到一份数据科学家的工作——我的 Airbnb 之旅
原文:https://towardsdatascience.com/how-to-land-a-data-scientist-job-at-your-dream-company-my-journey-to-airbnb-f6a1e99892e8?source=collection_archive---------0-----------------------
流程、提示和一些资源
Photo by Kalen Emsley on Unsplash
我写这篇博客的原因
我一个月前刚开始在 Airbnb 的新工作,是一名数据科学家,我仍然觉得我在这里太幸运了。没人知道我有多想加入这家公司——我的办公桌前贴着 Airbnb 办公室的照片;我把我的 iPhone 壁纸设置成我站在 Airbnb 标志前的照片;我四次申请 Airbnb 的职位,但最后一次才收到招聘人员的回复…
以前别人问我“你最想去哪家公司工作?”我不敢说“Airbnb”,因为当我这么说的时候,他们回答我,“你知道有多少人想在那里工作吗?他们中有多少人最终被录取了?加油,现实一点。”
结果证明,没有什么是不可能的。由于我的许多朋友让我分享我的求职经历,我认为把它写下来并与人分享可能会有帮助。
一些数据……
概述我的求职过程:
- 应用:475
- 电话采访:50 次
- 完成数据科学带回家的挑战:9
- 现场面试:8 次
- 优惠:2
- 花费的时间:6 个月
正如你可能从数据中看到的,我不是一个强有力的候选人,因为,否则,我只会申请几个职位并收到一堆邀请。是的,我曾经超级弱;我曾经是那种浪费面试官时间的考生。但是“几个月前你是谁并不重要,重要的是你正在成为什么样的人。”
数据科学家工作少走的路
稍微介绍一下我的背景,我在国内某大学获得了经济学学士学位,在伊利诺伊大学香槟分校获得了工商管理硕士学位。毕业后,我做了两年的数据分析师,其中 7 个月在谷歌做合同工,另外 1 年 4 个月在一家初创公司。我的工作主要是编写 SQL 查询,构建仪表板,并给出数据驱动的建议。
在意识到我没有像预期的那样学习和成长后,我辞去了工作,申请了激励数据科学沉浸计划,这是一个在旧金山为期 12 周的训练营。我 4 次都没能通过统计面试进入新兵训练营,在第五次参加统计面试后被录取了。
galilet 教授的内容侧重于 Python 和机器学习,并且他们假设你已经有很强的统计学基础。不出所料,一开始我很纠结,因为我对编程了解不多,对统计也不太强。我别无选择,只能努力工作。在镀锌期间,我没有休息,没有娱乐,没有约会,除了每天超过 12 个小时的学习,什么都没有。后来,我对这些课程更加适应了。
然而,当我第一次开始找工作时,我仍然在面试中让自己尴尬了无数次。因为我和真正的数据科学家之间的差距是如此之大,即使我很努力,12 周的研究也远远不足以实现职业转型。于是我申请,面试,失败,再申请,再面试,再失败。好的一面是,每次我都能学到新的东西,变得更强一点。
2018 年 3 月,我辞去上一份工作,已经失业快一年了。我的银行账户上只有 600 美元,我不知道如何支付下个月的房租。更糟糕的是,如果我在 2018 年 4 月底之前找不到工作,我就必须离开美国,因为我的签证将到期。
幸运的是,经过这么多的练习和重复,我已经从一个不知道如何恰当地介绍自己,不记得拉索和里奇中哪一个是 L1,对编程算法一无所知的人,成长为一个知道自己已经准备好得到自己想要的东西的人。
当我进入 Airbnb 的最后一轮面试时,我手里拿着一份数据科学家的聘书;因此,我一点也不紧张。我最后面试的目标是做最好的自己,不留遗憾。这次面试是我经历过的最好的一次。他们给了我这份工作,所有的努力和不眠之夜都得到了回报。
Photo by Jackson Hendry on Unsplash
我很乐意分享的小贴士
- 知道你想要什么,设定你的目标,努力实现这个目标,永远不要退而求其次。
- 成长心态,这真的很重要(如果你没听说过这个成长心态动画视频)。不要说“我不擅长编码”,“我不擅长统计”。不是天赋的问题。不要用“天赋”来形容别人,作为自己懒惰的借口。你需要的是用正确的方法去学习,多练习几次,直到你很好。
- 记下你被问到的所有面试问题,尤其是那些你没有回答的问题。你可以再次失败,但不要在同一个地方失败。你应该一直学习和提高。
- 如果可能的话,和其他人讨论你不懂的问题。我真的很感谢我的同学和指导老师的帮助,每个人都非常支持并愿意互相帮助。
- 去当地的数据科学聚会,加入数据科学学习小组,与行业内的人联系,当你试图在 LinkedIn 上与陌生人联系时,发送一封个性化的短信……尽可能地扩展你的网络,你不知道哪一封会为你打开一扇门。
- 有时候,结果是运气和准备的结合,你只是这次运气不好。不要总是把失败归因于自己不够好。
如果我可以重新开始找工作,我会有什么不同的做法
- 不要在求职之初就去面试你想去的公司,除非你认为自己已经准备好去应聘了。
我从采访优步开始了我的求职过程,我对那个决定深感后悔。我搞砸了,以至于不能在优步获得其他团队的面试机会。大多数人将主要的科技公司视为梦想中的公司;但是,这些公司大多有一个严格的规定,如果你失败了一次,6 个月或 1 年内不能再参加面试。因此,你要确保在去这些公司面试之前做好准备。
- 缩小你想做的工作类型,以及不适合你的工作类型,这会节省你很多时间。
如果你曾经看过数据科学家的招聘信息,你就会知道责任有多广。有从事自然语言处理、计算机视觉、深度学习的数据科学家,也有从事 A/B 测试、产品分析的数据科学家。确定什么样的工作适合你,什么不适合,这将帮助你节省大量准备面试的时间。
就我而言,我跳过了所有要求博士学位和深度学习、计算机视觉等知识的招聘信息。但是我还有太多的领域需要学习和准备。下面是我在找工作时使用的资源的总结。记住,有太多的资源你可以用来学习,你可能会花很多时间只是搜索材料,请有所选择,并确保你充分利用它们。
数据科学面试准备资源
统计数据
- 可汗学院:非常好的学习基本概念。
- 数据科学家实用统计学:不错的一个,非常实用,强烈推荐。
- 杜克大学在 Coursera 上开设的统计学课程(以 R 语言授课)
概率问题
- brilliant.org:我在准备采访时购买了他们的会员资格,我发现这是脸书现场采访准备指南的推荐资料之一。
A/B 测试
- Google 的 Udacity A/B 测试课程:我看了两遍,写了这个课程的总结。
- 微软的 KDD 论文和幻灯片:A/B 测试是数据科学面试中常见的问题,但之前没有多少业外人士做过 A/B 测试,所以当我试图了解实验设计时,我搜索并阅读了约 15 篇论文。
- Exp 平台上的幻灯片和视频
- 公司科技博客,如 Airbnb 数据科学博客
机器学习
- 吴恩达在 Coursera 上发布的斯坦福大学机器学习课程
- 统计学习介绍:在 R 中的应用:我们在 galilep 使用的教科书之一
- 行动中的机器学习:我们在 galile 使用的另一本教科书
- 密歇根大学在 Coursera 上发布的 Python 专业应用数据科学
基本编程算法
- HackerRank :更加入门级的友好
- 从简单到中等水平的问题
- 破解编码面试:189 个编程问题及解答(Java 编写)
Python 数据操作(Pandas,Numpy)
- 数据营
- 提示:通过解决公司的带回家的挑战,我极大地改进了 Python 数据操作。实践是最好的学习方法。
稀有
- 抱歉,我不太用 R。通常在面试中,你可以使用 R 或 Python。
结构化查询语言
- Mode Analytics SQL 教程:我对 SQL 相当熟悉,但我还是会在每次 SQL 面试前浏览一遍,尤其是高级部分,以防万一。
产品意识/商业理解
- 恰当的例子
- 破解 PM 访谈
- 解码并征服
一般面试问题
- 琳达·雷尼尔的 Youtube 频道:对一般的面试问题很有帮助。你也可以搜索其他视频来了解如何回答特定的面试问题。
其他资源
- 公司科技博客: Airbnb ,优步, LinkedIn ,网飞, Lyft , Pinterest , Stitch Fix , Quora , Yelp …应有尽有。学习的绝佳资源。
- 在技术面试前从 Glassdoor 收集公司的面试问题。
离别的思念
找工作只是我们人生旅程中的一段插曲。但是从长远来看,我们在这个过程中所表现出的勇气、激情和毅力将使我们受益。就我个人而言,我深深地相信下面的引用,并将永远继续相信它。希望它能像激励我一样激励你:
永远不要让别人告诉你,你做不到。如果你有梦想,就要捍卫它。人们自己做不到一些事情,他们想告诉你你也做不到。你想要什么,就去得到它。句号。” —海蓓娜斯的追求
Photo by Denys Nevozhai on Unsplash
如果你破产了,如何学习数据科学
原文:https://towardsdatascience.com/how-to-learn-data-science-if-youre-broke-7ecc408b53c7?source=collection_archive---------1-----------------------
去年,我自学了数据科学。我从数百个网上资源中学习,每天学习 6-8 个小时。同时在一家托儿所拿最低工资。
我的目标是开始一项我热爱的事业,尽管我缺乏资金。
因为这个选择,我在过去的几个月里完成了很多。我发布了我自己的网站,发表在一个主要的在线数据科学出版物上,并获得了一个竞争性计算机科学研究生项目的奖学金。
在下面的文章中,我给出了指导方针和建议,以便您可以制定自己的数据科学课程。我希望给别人工具,让他们开始自己的教育之旅。因此,他们可以开始在数据科学领域从事更有激情的职业。
快速笔记
当我说“数据科学”时,我指的是将数据转化为现实世界行动的工具集合。这些包括机器学习、数据库技术、统计学、编程和特定领域技术。
开始你的旅程的一些资源。
互联网是一个混乱的烂摊子。从中学习常常感觉像从消防水管的有趣一端喝水。
source
有更简单的替代方法可以帮你整理混乱的局面。
像 Dataquest 、 DataCamp 和 Udacity 这样的网站都可以教你数据科学技能。每个人都创建了一个教育计划,引导你从一个话题到另一个话题。每一个都不需要你做什么课程规划。
问题?它们花费太多,它们没有教你如何在工作环境中应用概念,它们阻止你探索自己的兴趣和激情。
还有一些免费的选择,比如 edX 和 coursera,它们提供深入特定主题的一次性课程。如果你从视频或课堂环境中学得很好,这些都是学习数据科学的绝佳方式。
Free Online Education Platforms
查看此网站,获取可用的数据科学课程列表。你也可以使用一些免费的课程。查看大卫·文丘里的帖子,或者开源 DS Masters (一个更传统的教育计划)。
如果你读书学得好,就看看数据科学从零开始这本书。这本教材是一个完整的学习计划,可以用在线资源补充。你可以在网上找到这本书的全文,或者从亚马逊网站(27 美元)得到一本纸质书。
这些只是为数据科学提供详细学习途径的免费资源中的一部分。还有很多。
为了更好地理解你在教育之旅中需要获得的技能,在下一节中,我将详细介绍一个更广泛的课程指南。这是高层次的,而不仅仅是一个课程或书籍的清单。
课程指南
Data Science Curriculum Guideline
Python 编程
编程是数据科学家的一项基本技能。熟悉 Python 的语法。了解如何以多种不同方式运行 python 程序。(Jupyter 笔记本 vs 命令行 vs IDE)
我花了大约一个月的时间复习了 Python 文档、Python 搭便车指南,以及 CodeSignal 上的编码挑战。
提示:留心程序员常用的解决问题的技巧。(读作“算法”)
统计学&线性代数
机器学习和数据分析的先决条件。如果你已经有了一个坚实的理解,花一两周时间温习关键概念。
特别关注描述性统计数据。能够理解一个数据集是一项价值连城的技能。
Numpy,熊猫,& Matplotlib
了解如何加载、操作和可视化数据。掌握这些库对你的个人项目至关重要。
快速提示:不要觉得你必须记住每一个方法或函数的名字,这需要练习。如果你忘记了,谷歌一下。
查看熊猫文档、 Numpy 文档和 Matplotlib 教程。有更好的资源,但这些是我用的。
记住,你学习这些库的唯一方法就是使用它们!
机器学习
学习机器学习算法的理论和应用。然后将您学到的概念应用到您关心的真实世界的数据中。
大多数初学者从使用来自 UCI ML 知识库的玩具数据集开始。摆弄数据,浏览指导式 ML 教程。
Scikit-learn 文档中有关于常用算法应用的优秀教程。我还发现这个播客是 ML 理论背后的一个伟大的(免费的)教育资源。你可以在上下班的路上或者健身的时候听。
生产系统
获得一份工作意味着能够获得真实世界的数据并将其转化为行动。
要做到这一点,你需要学习如何使用企业的计算资源来获取、转换和处理数据。
Amazon Web Services, Google Cloud, Microsoft Azure
这是数据科学课程中教授最少的部分。主要是因为你使用的具体工具取决于你要从事的行业。
然而,数据库操作是一项必需的技能。你可以在 ModeAnalytics 或 Codecademy 上学习如何用代码操作数据库。你也可以(便宜地)在 DigitalOcean 上实现自己的数据库。
另一个(经常)需要的技能是 版本控制 。你可以通过创建一个 GitHub 账户并使用命令行每天提交你的代码来轻松获得这项技能。
当考虑学习其他什么技术时,重要的是要考虑你的兴趣和激情。例如,如果你对 web 开发感兴趣,那么就去看看这个行业的公司所使用的工具。
执行课程的建议。
by Ugur Akdemir on Unsplash
1.概念会比你学习的速度更快。
有成千上万的网页和论坛解释常用数据科学工具的使用。正因为如此,在网上学习时很容易偏离主题。
当你开始研究一个课题时,你需要牢记你的目标。如果你不这样做,你就有被任何吸引你眼球的链接所吸引的风险。
解决方案,获得一个好的存储系统来保存有趣的网络资源。这样你就可以把材料留到以后,然后把注意力集中在与你当前相关的话题上。
My current Chrome Bookmarks Bar
如果你做对了,你就可以制定一个有序的学习路径,告诉你应该关注什么。你也会学得更快,避免分心。
警告,随着你探索自己感兴趣的新话题,你的阅读清单将很快增长到数百个。别担心,这引出了我的第二条建议。
2.不要有压力。这是一场马拉松,不是短跑。
拥有一个自我驱动的教育经常感觉就像试图阅读一个永无止境的知识图书馆。
如果你想在数据科学领域取得成功,你需要将你的教育视为一个终生的过程。
只要记住,学习的过程就是它自己的回报。
在你的教育之旅中,你将探索自己的兴趣,发现更多驱动你前进的动力。你对自己了解得越多,你从学习中获得的乐趣就越多。
3.学习->应用->重复
不要满足于仅仅学习一个概念,然后再去做下一件事。学习的过程不会停止,直到你能把一个概念应用到现实世界中。
by Allef Vinicius on Unsplash
不是每个概念都需要在你的投资组合中有一个专门的项目。但重要的是要脚踏实地,记住你正在学习,这样你才能对世界产生影响。
4.建立一个投资组合,这表明其他人可以信任你。
归根结底,怀疑是你在学习数据科学时将面临的最大逆境之一。
这可能来自别人,也可能来自自己。
你的作品集是你向世界展示你有能力并且对自己的技能有信心的方式。
因此,建立投资组合是你在学习数据科学时可以做的最重要的事情。一份好的投资组合可以让你找到一份工作,让你成为一名更自信的数据科学家。
在你的文件夹中装满你引以为豪的项目。
你是从零开始构建自己的 web 应用程序的吗?是自己做的 IMDB 数据库吗?你写过有趣的医疗保健数据分析吗?
把它放在你的文件夹里。
只要确保文章可读,代码被很好地记录,并且投资组合本身看起来不错。
https://harrisonjansma.com/archive
这是我的作品集。发布您的作品集的一个更简单的方法是创建一个 GitHub 资源库,其中包含一个很棒的 ReadMe(摘要页面)以及相关的项目文件。
这是一个美观又简单的 GitHub 文件夹。对于更高级的投资组合,请查看 GitHub-IO 来托管您自己的免费网站。(举例)
5.数据科学+ _______ =充满激情的职业
填空。
数据科学是一套旨在改变世界的工具。一些数据科学家构建计算机视觉系统来诊断医学图像,其他人遍历数十亿个数据条目来发现网站用户偏好的模式。
数据科学的应用是无穷无尽的,这就是为什么找到让你兴奋的应用是很重要的。
如果你找到了自己感兴趣的话题,你会更愿意投入工作去完成一个伟大的项目。这引出了本文中我最喜欢的一条建议。
当你在学习时,睁大眼睛寻找让你兴奋的项目或想法。
Stefan Steinbauer on Unsplash
一旦你花了时间学习,试着把这些点联系起来。找到让你着迷的项目之间的相似之处。然后花些时间研究从事这类项目的行业。
一旦你找到一个你热爱的行业,就把获得该行业所需的技能和专业技术作为你的目标。
如果你能做到这一点,你将会把你对学习的努力和奉献变成一份充满激情和成功的事业。
结论
如果你喜欢探索这个世界。如果你对人工智能着迷。那么无论你的情况如何,你都可以闯入数据科学行业。
这并不容易。
为了激励你自己的教育,你需要毅力和纪律。但是如果你是那种能推动自己进步的人,你完全有能力自己掌握这些技能。
毕竟,这就是作为一名数据科学家的意义所在。好奇心强,自我驱动,对寻找答案充满热情。
想要更多高质量的数据科学文章,关注我。👍
保持学习数据科学的动力。
原文:https://towardsdatascience.com/how-to-learn-data-science-staying-motivated-8665ed649687?source=collection_archive---------5-----------------------
关于如何在你的教育之旅中保持一致的建议。
Photo by Victoria Heath on Unsplash
在过去的几周里,我暂停了写作,专注于申请实习。但是当我今天开车去上课的时候,一个问题开始困扰我。
互联网上有这么多可供我们使用的资源,为什么我们很难保持学习数据科学的动力呢?
在过去的一年里,我不得不非常努力地保持学习数据科学的动力。我完全用(免费)网络资源制作了自己的课程,每天,不管我的动机如何,我都会留出至少四个小时来拓展我的技能。
这种追求祝福了我的人生,很多都是从奋斗中得来的。就在过去的六个月里,我建立了我的投资组合网站,并创建了一些非常惊人的数据科学项目(分析了 140 万个媒体故事)。
然而,去年也经历了非常艰难的日子。那些日子里,尽管我已经取得了很大的成就,但我仍在努力奋斗,几乎要放弃。
根据我的经验,无论你走哪条通往数据科学的道路,你都将面临可能会扼杀你动力的挑战。你会承担一些可能让你觉得自己渺小无力的任务,或者是在你耳边低语“这太难了。你应该放弃”。
但你不必一个人去。在这篇文章中,我将描述一些可能威胁你学习数据科学动机的陷阱。我希望通过意识到这些障碍,你在数据科学领域的职业道路会比我更容易。让我们开始吧。
在开始之前,确保数据科学是合适的。
Photo by Glenn Carstens-Peters on Unsplash
数据科学是一份性感的工作。薪水很高,工作很有趣,头衔也带来了巨大的声望。因此,许多人想成为数据科学家。
不幸的是,即使你对数据科学充满热情,并且能把工作做得非常好,你也不能强迫自己热爱这个过程。这给有抱负的数据科学家带来了一些令人不安的建议。
你可以对数据科学着迷,但如果你讨厌日复一日的任务和随之而来的感觉,那就很难保持你的动力。
对于大多数刚开始学习的人来说,你可能需要几个月的时间才能真正进入教育的“实践”阶段。(在那里你实际上建立了全面的数据科学项目。)在这一点上,意识到你讨厌这个过程对你个人来说是一个沉重的打击。为了省去你的麻烦,我整理了一份数据科学家面临的一些常见挫折的清单。
如果你选择从事数据科学领域的职业,以下是你需要适应的一些任务和感受:
感受:
- 学不完的感觉。
- 力不从心/不知所措的感觉。
- 失败了很多很多次才获得一次成功的感觉。
- 那种你花了几周时间做的事情失败或被忽视的感觉。
任务:
- 自学一门你一无所知的技能。
- 花几十个小时来回答一个看似简单的问题。
- 将自己与(表面上)更成功的人进行比较。
- 与不了解(或不关心)数据科学的人交流。
- 做 95%准备,5%执行的工作。
- 做很多不“性感”的工作。(数据库工作、数据管理等)
- 编码…大量编码。
我的建议是:在你跳下去之前做好你的研究。
数据科学是一个令人敬畏的职业,但随之而来的肯定是一些严重的挫折。
对于有抱负的数据科学家,我鼓励你在投身数据科学事业之前,了解更多关于普通数据科学家所做的工具和任务的知识(本文、此视频)。
开始的时候,做一点点研究将会大大增加你完成教育之旅的机会。
学会如何应对焦虑。
当你开始研究如何成为一名数据科学家时,你会发现一个关于这个职业的不幸事实。也就是说,成为一名数据科学家需要广泛而深入的工具、技术和技能知识。所有这些都让成为数据科学家的前景变得非常可怕。
你可能会开始问这样的问题:我必须回学校拿个博士学位吗?没有工作经验的我如何获得这些技能?我有能力学会所有这些吗?
Photo by Nathan Dumlao on Unsplash
当你踏上通往数据科学的旅程时,你会感到很多焦虑和压力。这是完全正常的反应,每个处于你的处境的人都会有同样的感觉。
要知道,在你教育旅程开始的这段时间对你的长期成功绝对至关重要。你在最初几周采取的行动将决定你为自己树立什么样的习惯,结果将决定你如何应对整个旅程中压力和焦虑的负面影响。
如果你能从一开始就找到应对压力和焦虑的健康方法,随着时间的推移,你的信心和动力将变得不可动摇。
然而,这里有一个需要解决的危险。在这段时间里,避免用不健康的方式应对负面压力是绝对重要的。
不幸的是,健康和不健康在很大程度上取决于你是谁。但在我自己的旅程中,我已经认识到一些不健康的应对机制,它们在过去损害了我的动力。
这里有一些你应该避免的处理压力的不健康方式。
避免不知所措:购买全包课程或教材。
这一次真的让我栽了大跟头。每当我开始对我需要学习的大量东西感到不知所措时,我就有一种强烈的冲动,想放弃自学,去购买别人的教案。
如果我最终真的买了包罗万象的课程或教材,学习就开始感觉像是别人交给我的苦差事。更糟糕的是,因为我没有努力去计划我需要学习什么,我变得和我为什么要学习一个特殊的技能或概念脱节了。结果呢?每当我购买在线课程时,我快速学习的动力就消失了。
为什么要避免这种情况:即使你可以从别人的课程中学到很多东西,我仍然建议不要这样做。为什么?因为在你迈向数据科学的旅程中,最重要的技能是能够自学。
自学是识别你的技能组合中的漏洞,研究新技术来缩小差距,并制定可行的计划来获得该技能的过程。如果你在旅途中仅仅依靠手把手的课程,你在这个过程中的经验会少得多。
随着时间的推移,这真的很糟糕。当你真正得到这份工作时,你可能会面临一个非常独特的、特定领域的、你几乎没有经验的问题。如果没有一个 MOOC 或教科书可以教你所需的技能,你将会非常艰难。
避免压力:推迟,或者指定一天来学习。
在旅程开始时,你可能犯的最大错误就是推迟学习。如果你觉得自己太忙也没关系,如果你想在旅途中获得成功,你需要每天留出时间来学习。
如果你不每天练习和学习,你的动力会很快消失,你将不可避免地对一个潜在的令人满意的职业失去兴趣。
为什么要避免这些:追求数据科学是一场马拉松,而不是短跑。这项工作所需的技能是如此的多样化,只有通过长时间的不懈努力才能获得。如果你试图在短时间内学习,你最终会耗尽你自己,熄灭你继续下去的动力。
更糟糕的是,如果你把学习推迟到你觉得有时间的时候,你可能永远也不会开始你的旅程。而且,如果你这样做了,你就会在你的头脑中形成这样一种观念:学习是你在时间允许的情况下做的事情。在数据科学中,这种心态是职业生涯的快速终结。
我的建议是:尽早养成健康的习惯。
无论你是全职工作,想做一个职业支点,还是正在读大学,想走一条让你兴奋的职业道路;无论哪种方式,你都需要找到让你克服压力的健康习惯。
几个你可以从一开始就养成的健康习惯:
- 每天留出时间学习新东西。
- 尝试加入数据科学社区。你会惊讶有多少人会认同你的焦虑感。
- 如果你因为学习而感到疲惫和焦虑,那就休息一段时间,用你最近学到的东西建立一个项目。这是一个减压的好方法,可以让你重新认识到你为什么要学习。
学会如何应对不知所措。
当你真正开始学习数据科学技能时,你会注意到有很多事情需要关注。此时此刻,我可能会列出未来 6 个月内我想获得的 8-12 项技能。
不幸的是,这不仅仅是我。在您迈向数据科学的旅程中,拥有一长串您想要学习或实践的技能将是每天的现实。只要看看 Swami Chandrasekaran 的数据科学路线图,你就会明白我在说什么。
Swami Chandrasekaran
当我第一次看到这个路线图时,我的直觉反应是被这个清单的庞大所淹没。一个人怎么可能指望自己学会所有这些?到目前为止,我所学到的只是列表中的一小部分,我真的取得了任何进步吗?
不幸的是,这种不知所措的感觉将伴随你走向数据科学的旅程。
有一天,你可能会觉得你已经掌握了一个概念/技能,只是意识到有五个新的东西需要添加到你的学习清单中。随着时间的推移,随着你需要学习的技术变得更新更复杂,这个问题只会变得更糟。
如果你没有想出一个计划来处理这种不知所措的感觉,有两件事会发生在你身上。
首先,你会开始对你需要掌握的技能的广度感到非常焦虑。如果这种感觉继续恶化,你会发现越来越难专注于一件事。结果,你可能会花几个月的时间在技能之间摇摆不定,拼命想一次学会所有技能,最后当你没有掌握任何一项技能时,你会感到沮丧。
第二,你会开始因为你需要学习的技能数量而感到压力。这样下去,你学习的动力就岌岌可危了。过去的每一天都会让你更加沮丧,因为你会将已经取得的进步与尚未完成的艰巨任务进行比较。在某些时候,你会开始相信你迄今为止取得的任何进展都是毫无价值的,成为一名数据科学家的任务是不可能的。
如果允许这两种感觉中的任何一种在你的头脑中增加重量,它们将慢慢粉碎你学习数据科学的动力。但是不要担心,这些负担可以通过深思熟虑的计划和战略重点在早期得到解决。
我的建议是:保持条理,保持短视。
数据科学本质上是一个广阔的领域,掌握如此多样的技能的唯一方法是一点一点地学习,一次学习一项技能。不管你选择如何从事数据科学,你都需要制定某种线性的、有组织的学习计划。这将有助于您通过一次专注于一项技能来应对数据科学技能集的广度。
如果你想建立自己的课程,你可以选择像 Swami 那样建立一个端到端的路线图。然而,你可能会开始对清单的深度感到不知所措。
这就是有点近视真正有帮助的地方。
根据我的经验,处理不知所措的感觉的最好方法是设定短期目标,将你的注意力集中在最重要的技能上。我的原则是,在任何时候,我都应该有一个清单,上面列有我下个月应该掌握的三项最重要的技能。
整个月我的注意力都集中在学习这三项技能上,我取得的任何进步都让人觉得非常充实和值得。当我觉得自己在进步时,激励自己每天学习就变得容易多了。在月末,我会重新评估我的技能,并尝试确定我应该关注的三个更有价值的技能。
如果你想自己做这件事,只需做以下几件事。问问你自己,“根据我现在所学的,接下来我需要的三个最重要的技能是什么?”把它们写下来,然后坚持到下一步去学习。
如果你想知道从哪里开始,或者你应该以什么顺序学习数据科学技能,请查看下面链接的我以前的帖子。在这个故事中,我给出了指导方针和建议,以便您可以执行自己的数据科学课程。
[## 如果你破产了,如何学习数据科学
去年,我自学了数据科学。我从数百个在线资源中学习,学习了 6-8 个小时…
towardsdatascience.com](/how-to-learn-data-science-if-youre-broke-7ecc408b53c7)
结论
归根结底,我们学习数据科学的动力是我们拥有的最宝贵的资源。如果我们要持续地掌握我们的手艺,我们需要保护我们的动机,使其免受威胁消灭它的挑战。
具体来说,我们需要对焦虑或不知所措的感觉保持警惕。这些负担可以通过健康的学习习惯以及有组织和有意识的专注来解决。
如果你可以保护和培养你学习数据科学的动机,那么没有什么可以阻挡你。你将拥有不可动摇的决心,推动你成为尽可能最好的数据科学家。
保持热情。保持动力。感谢阅读。
想要更多高质量的数据科学文章就关注我吧。👍
如何在 6 个月内学会深度学习
原文:https://towardsdatascience.com/how-to-learn-deep-learning-in-6-months-e45e40ef7d48?source=collection_archive---------2-----------------------
在大约 6 个月的时间里,很有可能学习、跟随和贡献深度学习的艺术作品。本文详细介绍了实现这一目标的步骤。
先决条件
-你愿意在接下来的 6 个月里每周花 10-20 个小时
-你有一些编程技能。一路上捡 Python 应该很舒服。和云。(假设没有 Python 和云背景)。
-过去的一些数学教育(代数、几何等)。
-接入互联网和电脑。
第一步
我们通过开车来学习开车。而不是通过学习离合器和内燃机的工作原理。至少最初没有。在学习深度学习时,我们会遵循同样的自上而下的方法。
做 fast.ai 课程— 程序员实用深度学习—第一部分。这需要大约 4-6 周的努力。本课程有一节课是关于在云上运行代码的。谷歌联合实验室有免费的 GPU 访问。从那个开始。其他选项包括 Paperspace 、 AWS 、 GCP 、 Crestle 和 Floydhub 。所有这些都很棒。不要开始建造你自己的机器。至少现在还没有。
第二步
这是了解一些基本知识的时候了。学习微积分和线性代数。
对于微积分,微积分大图提供了很好的概述。
对于线性代数,Gilbert Strang 在开放课件上的麻省理工课程很惊艳。
一旦做完以上两条,再看深度学习的矩阵演算。
第三步
现在是了解深度学习的自下而上方法的时候了。在 Coursera 上完成深度学习专业的全部 5 门课程。你需要付费来给作业评分。但是这种努力是值得的。理想情况下,考虑到你目前为止所获得的背景知识,你应该能够每周完成一门课程。
第四步
“只工作不玩耍,聪明的孩子也变傻”
做一个顶点项目。这是你深入研究深度学习库(例如:Tensorflow、PyTorch、MXNet)并为你喜欢的问题从头实现一个架构的时候。
前三步是了解如何以及在哪里使用深度学习,并获得坚实的基础。这一步是关于从零开始实现一个项目,并在工具的基础上发展一个强大的基础。
第五步
现在快去做ai 的 part II 课程——程序员前沿深度学习。这涵盖了更高级的主题,你将学会阅读最新的研究论文,并从中理解。
每个步骤大约需要 4-6 周的时间。在你开始学习的大约 26 周内,如果你虔诚地遵循以上所有内容,你将在深度学习方面有一个坚实的基础。
接下来去哪里?
参加斯坦福大学的 CS231n 和 CS224d 课程。这两个课程分别对视觉和 NLP 有很大的深度。他们涵盖最新的艺术水平,阅读深度学习书籍。这会巩固你的理解。
快乐深度学习。创造每一天。
如何在低内存上处理 BigData 文件?
原文:https://towardsdatascience.com/how-to-learn-from-bigdata-files-on-low-memory-incremental-learning-d377282d38ff?source=collection_archive---------6-----------------------
关于如何使用 Pandas/Dask 在 Python 中处理大数据文件的演练
Photo by Ruffa Jane Reyes on Unsplash
这是我在Tackle
类别的帖子中的一个,可以在我的 github repo 这里找到。
(Edit-31/01/2019) — 为 BigData 添加了 dask.distributed.LocalCluster 的信息
(Edit-12/4/2019)——添加了关于数据集大小缩减和文件类型使用的新章节【尚未完成,但您仍可从中获得应用思路。]
索引
- 简介
- 列记忆还原(pd。Series.astype()) [:未完成]
- 文件类型(减少内存使用) [:未完成]
- 数据探索
- 预处理
- 增量学习(熊猫)
- Dask(探索+准备+拟合预测)
- 延伸阅读
- 参考文献
***NOTE:*** This post goes along with ***Jupyter Notebook*** available in my Repo on Github:[[HowToHandleBigData](https://nbviewer.jupyter.org/github/PuneetGrov3r/MediumPosts/blob/master/Tackle/BigData-IncrementalLearningAndDask.ipynb)] (with dummy data)
and
Kaggle:[[HowToHandleBigData](https://www.kaggle.com/puneetgrover/learn-from-bigdata-files-on-low-memory)] (with Kaggle [competition](https://www.kaggle.com/c/ga-customer-revenue-prediction) data)
1.简介 ^
随着数据量呈指数级增长,我们无法在电脑内存中容纳我们的数据,甚至我们的模型。我们都买不起高端组装台式机。
例如,最近的 kaggle 竞赛的数据集无法容纳在 kaggle 内核或 Colab 的 17GB 内存中。它有将近 200 万行,最重要的是,一些列有非常大的 JSON 数据作为字符串。我们应该如何解决这个问题?我们可以向谁求助呢?
增量学习和/或 Dask 来拯救!
你可能已经知道神经网络本质上是增量学习器,所以我们可以在那里解决这个问题。许多sklearn
的模型提供了一种叫做partial_fit
的方法,使用它我们可以批量建模。一些像XGBoost
和LightGBM
这样的 Boosting 库提供了一种渐进学习的方式来处理大数据。
在这里,我们将研究一些 Boosting 算法提供的增量解决方案。然后我们将在同一个数据集上使用Dask
,并使用其模型进行预测。
2.列存储缩减
^
Photo by Lisa H on Unsplash
# I don't know who the original author of this function is,
# but you can use this function to **reduce memory**
# **consumption** **by** **60-70%!****def** *reduce_mem_usage*(df):
"""
iterate through all the columns of a dataframe and
modify the data type to reduce memory usage.
"""
start_mem = df.memory_usage().sum() / 1024**2
**print**(('Memory usage of dataframe is {:.2f}'
'MB').format(start_mem))
**for** col in df.columns:
col_type = df[col].dtype
**if** col_type != object:
c_min = df[col].min()
c_max = df[col].max()
**if** str(col_type)[:3] == 'int'**:**
**if** c_min > np.iinfo(np.int8).min and c_max <\
np.iinfo(np.int8).max:
df[col] = df[col].astype(np.int8)
**elif** c_min > np.iinfo(np.int16).min and c_max <\
np.iinfo(np.int16).max:
df[col] = df[col].astype(np.int16)
**elif** c_min > np.iinfo(np.int32).min and c_max <\
np.iinfo(np.int32).max:
df[col] = df[col].astype(np.int32)
**elif** c_min > np.iinfo(np.int64).min and c_max <\
np.iinfo(np.int64).max:
df[col] = df[col].astype(np.int64)
**else**:
**if** c_min > np.finfo(np.float16).min and c_max <\
np.finfo(np.float16).max:
df[col] = df[col].astype(np.float16)
**elif** c_min > np.finfo(np.float32).min and c_max <\
np.finfo(np.float32).max:
df[col] = df[col].astype(np.float32)
**else**:
df[col] = df[col].astype(np.float64)
**else**:
df[col] = df[col].astype('category') end_mem = df.memory_usage().sum() / 1024**2
**print**(('Memory usage after optimization is: {:.2f}'
'MB').format(end_mem))
**print**('Decreased by {:.1f}%'.format(100 * (start_mem - end_mem)
/ start_mem))
**return** df
坦克
3.文件类型
^
Photo by Kelly Sikkema on Unsplash
HDF5、拼花地板等。
注:如果你不想落入这一节,你可以只看 HDF5。这应该足够了。转到下一部分。
分层数据格式—维基百科 (HDF5)
阿帕奇拼花地板
Hadoop 文件格式:它不再仅仅是 CSV——Kevin Haas(不要在阅读 Hadoop 后被吓跑,您可以只使用 Parquet 格式并通过使用pd.DataFrame.to_parquet
和pd.DataFrame.read_parquet
方法。)
还有,如果你有兴趣: Parquet vs Avro 【无论如何我都会推荐你去看。]
坦克
4.数据探索 ^
Photo by Panos Sakalakis on Unsplash
首先,我们将通过使用以下命令查看前几行来了解我们的数据是什么样子的:
part = pd.read_csv("train.csv.zip", nrows=10)
part.head()
通过这个,你将有关于不同的列是如何构成的,如何处理每个列等的基本信息。列出不同类型的栏目,如numerical_columns
、obj_columns
、dictionary_columns
等。它将保存所有相应的列。
现在,为了研究数据,我们将像这样逐列进行:
**#** For dictionary columns you can do:# 'idx' is index of corresponding column in DataFrame.
# You can find it by using np.where(col==df.columns)for col in dictionary_columns:
df = pd.read_csv("train.csv.zip", usecols = [idx], converters={col: json.loads})
column_as_df = json_normalize(df[col])
# ... plot each column ...
# ... check if you want to drop any column ...
您可以将所有列名作为键的字典和应用于它的方法保存在一个列表中,作为该列的管道。你也可以把你的字典保存起来,以备将来使用:
with open("preprocessing_pipeline.pickle", "wb") as fle:
pickle.dump(preprocessing_pipeline, fle)
如果其中一列对您的内存来说太大,实际上我上面提到的 kaggle 竞赛中的一行就是这种情况。你甚至可以逐步打开一列,并可以做一些基本的事情,如计算平均值,标准差等。手动。或者你也可以用Dask
来代替它,用和pandas
几乎一样的 API 来计算它们。参见最后一节Dask
。
5.预处理 ^
Photo by rawpixel on Unsplash
对于预处理数据,我们将使用我们之前创建的字典,它包含关于我们希望保留哪些列(作为键)以及对每列应用什么方法(作为值)的信息,以创建一个方法。
在增量学习过程中,每一批数据都会调用这个方法。
现在这里要注意的一件事是我们安装了方法(比如 LabelEncoder 的、scalar的等等。)在探索整个数据列的过程中,我们将在这里的每个增量步骤中使用它来转换数据。因为,在每一批中,可能会有一些数据丢失,如果我们使用了不同的标签编码器、标量等。对于每一批,这些方法不会给出相同类别的相同结果。这就是为什么我们在探索过程中已经安装了整个列。
以下是预处理数据的方法:
def preprocess(df):
df.reset_index(drop=True, inplace=True)
# For dict columns:
for col in dict_columns:
col_df = json_normalize(df[col])
# json.loads during pd.read_csv to convert string to dict.
col_df.columns = [f"{col}.{subcolumn}" for subcolumn in col_df.columns]
# Select all columns which we selected before.
selected_columns = [c for c in dictionary.keys() if c in col_df.columns()]
to_drop = [c for c in col_df.columns if not in selected_columns]
# Drop all previously unselected columns.
col_df = col_df.drop(to_drop, axis=1)
df = df.drop(col, axis=1).merge(col_df, right_index=True, left_index=True)
# And so on...
# And then apply all Scalars, LabelEncoder's to all columns selected...
return df
6.增量学习 ^
Photo by Bruno Nascimento on Unsplash
要使用pandas
增量读取数据文件,您必须使用一个参数chunksize
,该参数指定一次要读/写的行数。
incremental_dataframe = pd.read_csv("train.csv",
chunksize=100000) **#** Number of lines to read.# This method will return a sequential file reader (TextFileReader)
# reading 'chunksize' lines every time. To read file from
# starting again, you will have to call this method again.
然后你可以使用XGBoost
或LightGBM
对你的数据进行增量训练。对于LightGBM
,你必须向它的.train
方法传递一个参数keep_training_booster=True
,向XGBoost
的.train
方法传递三个参数。
**#** First one necessary for incremental learning:
lgb_params = {
'keep_training_booster': True,
'objective': 'regression',
'verbosity': 100,
}**#** First three are for incremental learning:
xgb_params = {
'update':'refresh',
'process_type': 'update',
'refresh_leaf': True,
'silent': False,
}
在每一步中,我们将保存我们的估计值,然后在下一步中将其作为参数传递。
**#** For saving regressor for next use.
lgb_estimator = None
xgb_estimator = Nonefor df in incremental_dataframe:
df = preprocess(df)
xtrain, ytrain, xvalid, yvalid = # Split data as you like
lgb_estimator = lgb.train(lgb_params,
**#** Pass partially trained model:
init_model=lgb_estimator,
train_set=lgb.Dataset(xtrain, ytrain),
valid_sets=lgb.Dataset(xvalid, yvalid),
num_boost_round=10)
xgb_model = xgb.train(xgb_params,
dtrain=xgb.DMatrix(xtrain, ytrain),
evals=(xgb.DMatrix(xvalid, yvalid),"Valid"),
**#** Pass partially trained model:
xgb_model = xgb_estimator)
del df, xtrain, ytrain, xvalid, yvalid
gc.collect()
CatBoost
的增量学习法正在进行中。
为了加快速度,如果您的块仍然足够大,您可以使用Python
的multiprocessing
库函数来并行化您的预处理方法,如下所示:
n_jobs = 4
for df in incremental_dataframe:
p = Pool(n_jobs)
f_ = p.map(preprocess, np.array_split(df, n_jobs))
f_ = pd.concat(f_, axis=0, ignore_index=True)
p.close()
p.join()
# And then your model training ...
关于Python
中并行编程的介绍,请在这里阅读我的帖子。
7.达斯克 ^
Photo by Nick Fewings on Unsplash
Dask 有助于以顺序并行的方式利用大数据资源。
关于Dask
的介绍,请在这里阅读我的帖子。
您可以在这里以类似的方式应用来自pandas
API 的函数。您可以检查是否有这样的空值:
df.isnull().sum().compute()
要缩放列,可以将它们转换为数组,并以类似的方式使用其 Scaler 函数:
rsc = dask_ml.preprocessing.RobustScaler()
result = rsc.fit_transform(X[:,i].reshape(-1, 1)) # for ith column
处理 JSON 或任何其他半结构化数据,如日志文件等。你可以使用Dask
的Bag
容器提供的函数。
df[key] = df[dict_col].to_bag().pluck(key).to_dataframe().iloc[:,0]
在预处理之后,你可以使用Dask
的一个模型来训练你的数据。
完整代码请阅读 Jupyter 笔记本中的Dask
部分,点击这里。
**Note:** You should only use Dask in case of Big Data, where it is not able to fit in your memory. Otherwise in-memory learning with pandas and sklearn will be lot faster.**Note: (Local Cluster)**
You can perform almost any BigData related query/tasks with the help of LocalCluster. You can, specifically, use 'memory_limit' parameter to constrict Dask's memory usage to a specific amount.
Also, at times you might notice that **Dask** is exceeding memory use, even though it is dividing tasks. It could be happening to you because of the function you are trying to use on your **dataset** wants most of your data for processing, and multiprocessing can make things worse as all workers might try to copy **dataset** to memory. This can happen in aggregating cases.In these cases you can use **Dask.distributed.LocalCluster** parameters and pass them to **Client**() to make a **LocalCluster** using cores of your Local machines.**from** dask.distributed **import** Client, LocalCluster
client = **Client**(n_workers=1, threads_per_worker=1, processes=False,
memory_limit='25GB', scheduler_port=0,
silence_logs=False, diagnostics_port=0)
client'scheduler_port=0' and 'diagnostics_port=0' will choose random port number for this particular client. With 'processes=False' **dask**'s client won't copy dataset, which would have happened for every process you might have made.
You can tune your client as per your needs or limitations, and for more info you can look into parameters of **LocalCluster.** You can also use multiple clients on same machine at different ports.
8.延伸阅读 ^
- https://www . ka ggle . com/mlisovyi/bigdata-dask-pandas-flat-JSON-trim-data-upd
- https://github . com/dmlc/xgboost/issues/3055 # issue comment-359505122
- https://www . ka ggle . com/ogrellier/create-extracted-JSON-fields-dataset
- https://github . com/Microsoft/light GBM/blob/master/examples/python-guide/advanced _ example . py
- 将数据帧内存大小减少约 65% | Kaggle
- 机器学习处理大数据文件的 7 种方法——机器学习掌握
9.参考文献 ^
- https://www . ka ggle . com/mlisovyi/bigdata-dask-pandas-flat-JSON-trim-data-upd
- https://www . ka ggle . com/ogrellier/create-extracted-JSON-fields-dataset
- https://gist . github . com/goraj/6 df 8 f 22 a 49534 e 042804 a 299d 81 bf2d 6
- https://github.com/dmlc/xgboost/issues/3055
- https://github.com/catboost/catboost/issues/464
- https://github.com/Microsoft/LightGBM/issues/987
- https://gist . github . com/ylogx/53 fef 94 cc 61d 6a 3 e 9 B3 EB 900482 f 41 e 0
Suggestions and reviews are welcome.
Thank you for reading!
签名:
如何学习新的东西
原文:https://towardsdatascience.com/how-to-learn-something-new-27b950f16f33?source=collection_archive---------2-----------------------
最初发表于【lemjosh.tumblr.com】。
图片来源:
世界在变化,速度之快超乎任何人的想象。许多许多年前是我们生活一部分的东西已经不在这里了,许多今天是我们生活一部分的东西在不久的将来会成为收藏品。对于每一项最新的技术,大约两年后总会有更好的或完全的替代品。有的变化快,有的变化慢,但都是变化的。二十年前,谁会想到我们会拥有像今天这样的 3D 相机、增强现实和超高速通信技术?
因此,我们需要在当今世界保持相关性的一个非常重要的技能是能够快速学习新事物。
去年的这个时候,我正准备在一个我一无所知的领域开始攻读博士学位。我有机械工程的背景,但是我知道我的博士研究需要很多我还不知道的知识。所以从那以后,我一直在积极地学习新的东西。
因此,我写这篇文章,不是作为一个知道的人,而是作为一个正在知道的人。我的学习经历充满了失望,但是最终知道你学到了什么的喜悦超过了这个过程。
在过去的一年里,我一直在学习如何说一种新的语言——日语,关于 Python 和 C++编程、机器学习、计算机视觉、机器人和人工智能。我必须说这是充满挑战但又令人愉快的一年。以下是有助于保持学习和提高的想法。
1。培养对你所学的东西的兴趣。学习并不容易,需要付出很多努力和精力,也相当容易累垮。然而,你的兴趣有助于缓解耗费如此多精力和精力的感觉。我演奏萨克斯管和钢琴的水平令人羡慕,所以我有很多想学习简单乐器的人的问题,我总是告诉他们的一件事是,没有一种乐器是简单的,无论它看起来多么简单,而且有时你会卡住,看起来你不会变得更好。然而,在那些时候,是你对所学内容的兴趣帮助你度过难关。
2。花时间。这可能是学习任何东西的唯一最重要的因素。你必须花时间在你所学的东西上。我不能过分强调这一点。这是任何领域最优秀的人的一个共同点,他们花费大量的时间来磨练自己的技能。你花的时间越多,你就变得越好。就这么简单!
3。要知道学习是一个循环。从我开始研究开始,我就意识到了这个循环;我对某个东西没有概念,我开始学习它,我通常在第一次读到一个新主题时不理解,我又读了一遍,现在我有了更好的理解,我又看了一遍,现在我抓住了它,然后我继续下一件事,重复这个过程。有时候,在我继续前进之前,我会多次重复“走过去”这一步。这有助于我永远不会真正卡住。我重复这个循环越多,我就变得越好。然而,这可能需要很长时间。你可以称之为经验。
4。有时候分心是好事。目前,我平均每周工作 80 个小时,其中大部分时间都在研究一些新东西,这有时真的很烦人。但是,我会放一天假冷静一下,做点别的事情。演奏音乐,去教堂做礼拜,只是睡觉和听音乐,观光,看电影,等等。底线是,我通过做一些完全不同的事情来让自己恢复精神,这不一定是学习。我相信它有助于我保持精力充沛和精神饱满。
在我的一生中,我已经能够亲自学习两种乐器(达到中级熟练程度,没有乐理经验。是的,我玩听觉)、音乐制作(我有一张音乐专辑)、平面设计、视频编辑和 flash 动画、3D 绘图、建模和动画、丝网印刷、第三语言和计算机编程。我还想学更多,也许是第四语言和网页设计。你可以叫我多面手。哈哈!
我认为我喜欢学习新的东西,这给了我信心,我将继续在这个快速变化的世界中发挥作用。
如果你和我一样喜欢这篇文章,喜欢学习,请在评论中分享你的经历或建议。我也可以向你学习。😃
如何成为一名数据科学家(第 1 部分)
原文:https://towardsdatascience.com/how-to-level-up-as-a-data-scientist-part-1-9ea6a775f239?source=collection_archive---------4-----------------------
第 1 部分:表桩
不久前,我写了一篇文章,将方法论作为虚荣的衡量标准。我想表达的观点是,方法是一种手段,而不是目的——学习它们可能是令人愉快的,但作为数据科学家,我们通过解决有价值的问题来谋生。因此,当你考虑技能培养时,你应该专注于那些你需要推动价值的技能。在思考这篇文章时,我意识到做出这样的声明很容易,但很难执行,特别是如果一个人处于职业生涯的早期,还没有建立起许多代表,所以我决定写一篇(一组)附带的文章,提供更多可操作的建议。我的目标是留给你们两样东西:
- 首先,要理解超越(明显的)技术工具的核心技能,这些技能造就了一名优秀的数据科学家
- 其次,你可以采取一些具体的步骤来发展或提高这些技能。
这很长,所以我决定把它分成几个部分。在这篇文章中,我将讨论牌桌赌注——你在牌桌上获得一席之地所需的技能,如果你还没有这些技能,你应该首先学习。在随后的文章中,我将涵盖 3 个领域,在这 3 个领域中,强有力的从业者表现出色,并且可以做一些具体的事情来建立这些技能。
桌面木桩
桌桩是基础,其他所有东西都位于其上。它们代表了数据科学家用来为公司创造价值的核心技能。
SQL
不管是好是坏,SQL 是处理数据的通用语言。大多数技术产品都有 sql 数据库支持,甚至那些没有内置 SQL 风格的产品也是如此(例如 Hadoop 的 Hive)。无论如何,由于您要处理的大多数问题的起点都是“获取数据”,而数据通常存储在 SQL 存储中,因此您需要成为这方面的专家。幸运的是,这方面有很多免费资源。我最喜欢的是 Mode 的 SQL 学校。
随机变量和条件概率
这是你将使用的主要数学工具,因为它最适合回答诸如“这个东西比那个东西好吗?”或者“我们刚刚做的事情成功了吗?”。大多数人为了在这些问题上取得进展而匆忙采用统计数据。根据我的经验,统计方法有太多的假设,它们在现实世界的问题中往往是非常无用的(一些可以映射到二项式的简单情况是例外),我在大约 10 年的时间里没有真正信任过统计测试的结果。但它们背后的东西——随机变量和产生它们的概率规则——真的很有用,因为你可以用它们来明确你的假设,并运行场景来计算你在数据中的结果实际上有多大可能。所以我建议你在这方面打下坚实的基础,你可以从任何好的教科书或这些卡恩学院的课程中获得关于概率和随机变量的知识。
Python 或基于 R 的机器学习和随机建模基础
ML 和随机建模是数据科学家和分析师之间的第一次分离,因为它们是支持规模的工具。我说的“基础”是指,知道有哪些方法可用(例如,树与回归和深度模型),它们的目的是什么(例如,分类与项目),它们如何在高层次上工作(例如,损失最小化、正则化等)。),哪些库实现了它们,如何让那些库产生一个结果,以及如何验证它(例如,AUROC,precision vs. recall,等等)。).
我推荐“从头开始的数据科学”,它贯穿了最常见算法的 python 实现,从基本原理开始。无论你选择什么,确保你使用的是 Python 或者 R,而不是你必须付费的东西(比如 SAS)或者不是代码的东西(比如基于 GUI 的工具,比如 RapidMiner)。这是因为:
- 免费工具正在胜出。并且免费。就像你不用付钱一样。如果你愿意的话,你可以把钱用在其他事情上,比如咖啡或啤酒。
- 证据表明代码是软件的最佳抽象。你的目标是能够用软件实现你的解决方案,因为这给了你最大的优势(同时也是作为数据人员最好的职业前景)。
这一步还让你接触到数据栈(python 中的 pandas、numpy、matplotlib、R 中的 dplyr 等),这将有助于你向价值链的上游移动。(作为旁注,我个人在这一步开始提倡 Python 而不是 R。这是因为 Python 为生产环境提供了一条更干净的路径,并且是一种功能齐全的编程语言,也适合于软件开发。由于这一点,Python 正在迅速获得市场份额。在 R 中,您可以是多产的和有价值的,但是要真正扩展 Python 是一个更好的选择。我们稍后将回到这一点。)
以上三方面的专业知识会让你在谈判桌上占有一席之地。它们构成了使您有资格成为替代级数据科学家的核心技能。如果你只有 1 和 2,作为一个分析师,你可以创造很多价值,但是你被阻止了。如果你只有 1 和 3,你基本上是一个技术人员,你的结果不会被信任。如果你只有 2 个和 3 个,你基本上是一个研究员,因为数据需要交给你,你的迭代周期会太慢。所以,如果你错过了以上三件事情中的任何一件,先从这些开始。
所以,一旦你在赌桌上下注,下一步是什么?假设你已经在你的第一份工作上工作了几年,正进入职业生涯中期。你做了一些有趣的工作,有一些胜利,也有一些失败。你准备好升级了。要成为一名高级贡献者,你必须做些什么?在我看来,你应该多做三件事:
- 发展系统思维。
- 拓展你的创意产生平台。
- 多元化和规模化你的分销机制。
我将在后续的文章中详细介绍这些内容。
(想在职业生涯中更上一层楼?在 建立你的技能世界贝叶斯 )
如何成为一名数据科学家(第二部分)
原文:https://towardsdatascience.com/how-to-level-up-as-a-data-scientist-part-2-92eb65aaf1c5?source=collection_archive---------3-----------------------
在本系列的第 1 部分中,我确定了三个我认为是数据科学家基本技能的领域:SQL、随机变量/条件概率和 R 或 Python 中的 ML 基础。了解这些领域可以让你在谈判桌上获得一席之地,并让你处于可以开始增值的位置。以此为起点,我们准备进入下一步,解决如何升级的问题。我要解决的第一类问题是开发系统思维。
系统: 一组相互联系的事物或部分形成一个复杂的整体,特别是。作为机械装置或互联网络的一部分一起工作的一组事物。
为什么培养系统思维很重要?因为数据不是在真空中产生的。相反,它是由现实世界中正在运行(或被运行)的系统产生的——一个用于搜索互联网的 web 应用程序,一个用于与朋友联系的消息服务,一个用于购买任何你想要的东西的电子商务网站。每种方法产生的数据都是不同的,因为人们在使用每种方法时都试图实现不同的目标。理解一个系统及其相关的背景会引导你找到有用的问题,推动你的实验以验证答案,并能帮助你设计衡量标准来揭示你是否真正成功地实现了你的目标(以及揭示你何时在自欺欺人)。例如,上面列出的每个应用程序的行动要求是不同的。在搜索应用程序中,它是搜索按钮;在消息应用程序中,它是发送按钮;在电子商务应用程序中,它是购买按钮。行动呼吁应该是大还是小?答案十有八九取决于制度。对于搜索或电子商务,我们可能希望它很大,因为我们希望尽可能简单的行动。对于信息服务,我们可能希望它小一点,因为否则它可能会占用太多的屏幕空间,使写信息变得很烦人,这将减少我们产品的使用。因此,如果我们进行一项实验,并生成关于按钮大小与动作的数据,而不考虑我们所处的环境(搜索/电子商务与消息传递),我们什么也学不到。我们的数据没有上下文是没有用的,而上下文来自于生成它的系统。换句话说,理解数据背后的系统有助于你定义什么是“好的”。没有它,你只有数字——没有任何意义的值,你的结论在最好的情况下是没有信息的,在最坏的情况下是无意义的。鉴于此,一个人如何发展系统思维?没有什么比重复更能让你做得更好了,所以我将在下面列出一些练习。目标是让你思考数据是如何存在的,你能从数据中学到什么,以及(最终)你如何利用数据获取价值。我提倡一个三步走的过程:
- 通过玩具模型培养对周围世界的理解。这将帮助您了解系统。
- 通过建立评估模型的量化框架来培养产品意识。这将帮助您识别系统中的价值层。
- 发展观点,做出预测,并让自己对它们负责。这将帮助你确保你在做(1)和(2)时发展的直觉是正确的。
第一步:通过玩具模型来了解你周围的世界
系统思考的第一步是开始注意并试图理解你周围世界的系统。玩具模型是一个很好的工具。对于那些不熟悉的人:
A 玩具模型 是一个刻意简化的模型,去掉了许多细节,以便可以用来简洁地解释一个机构。
它们在物理学中大量用于围绕一个问题建立直觉。通过建立一个你感兴趣的现象的简化版本,你可以学到很多关于它是如何工作的,甚至可以做出有意义的预测。在放射性衰变中有一个很好的例子,当不稳定的原子自发分裂成更轻的元素,同时以辐射的形式释放能量。为了充分描述这个过程,你需要量子力学和量子场论,如果你想精确计算一组特定原子的衰变率和它们释放的能量。然而,第一批研究这个问题的物理学家没有这些可用的工具,他们需要想出更简单的方法。为此,他们建造了一个玩具模型。
- 他们推断,放射性衰变是一种罕见的事件,因为给定原子在两个特定时间点之间衰变的概率非常低。如果不是这样,我们在地球上观察到的每一种元素都已经衰变到稳定状态,我们永远也不会测量到任何辐射。
- 这意味着泊松统计支配的过程,它包含一个单一的参数:事件率或过程的半衰期。该参数必须包含整个流程的高级描述,因为没有其他信息可用。
- 这样他们就有了可以测量的东西:使用辐射探测器,如盖革计数器,在规定的短时间内重复测量击中的次数。从那里可以相对简单地验证计数确实遵循泊松分布,并提取速率参数和半衰期。
这可能看起来很琐碎,但事实证明,这种简单的方法,一旦得到验证,最终成为碳年代测定等方法的基础。这个玩具模型无法解释衰变过程的所有细节,但能够给出一些对地球年龄的最初精确估计!
- 棒球中的 Sabermetrics ,它将每一次互动建模为一个独立的事件,具有特定结果的给定概率(如击球、保送、出局、跑动等)。),并将每个结果与获胜概率的边际增长联系起来。这就产生了,除了别的以外,保送等同于单打,因为两者都导致非出局事件和一垒上的球员。
- 有效市场假说,该假说认为股票市场的参与者可以获得完美信息。这就产生了这样一种观点,即市场通常是一起运动的,因此股票的价格变化在任何给定时刻都很可能是随机的。
- PageRank ,该模型将浏览网页建模为有条件的随机浏览网页,在这种情况下,冲浪者只能访问与他们所在的前一个页面相链接的页面。根据这个模型,我们发现链接最多的页面占据了浏览时间,这意味着它们是给定主题最重要的来源。
这些例子中没有一个在它们试图建模的过程方面是严格准确的,但是都产生了有用的见解。其中的每一个都是通过考虑生成数据的系统可能会是什么样子,并努力理解其含义而构建的。那么你是如何学会这个的呢?我建议的练习是:
- 找到你感兴趣的东西。
- 假设那件事背后的基本原则。
- 对你在(2)中发现的含义进行推理。
- 用数据验证。
- 重复!
我想举一些例子来帮助你开始:
- 运用项目反应理论理解篮球犯规
- 利用马尔可夫模型进行营销的多渠道归因
- 使用统计力学来模拟股票价格
这样做的次数足够多,你会发现自己分解了遇到的每一个过程,并在比其他人少得多的信息下对事物如何工作有了深刻的理解。但你也会发现这只是一部分。玩具模型将帮助你弄清楚事物是如何工作的,但你可能会开始怀疑这些东西是否应该存在——它们是否正在产生有价值的结果。这就把我们带到了第二步。
第二步:通过建立评估模型的量化框架来培养产品意识
一旦你真正擅长构建玩具模型,你将能够观察任何过程,并能够构建一个描述该过程如何生成数据的模型。然而,它不会告诉你任何关于所述过程的效用。这个过程会产生有用的结果吗?这个结果值多少钱?结果是否证明了成本的合理性?这个过程应该发生吗?要回答这些问题,你必须学会对产生的价值进行推理,而不仅仅是产生的结果。事实上,我上面列出的所有玩具模型都有一个关键的价值金块,这是洞察力的一部分,可以直接转化为有用的收获。
- sabermetrics 的保送等同于单打的结果意味着它们应该由市场来定价-保送率高的球员应该和那些击球率高但主要击中单打的球员赚得一样多。
- 有效市场假说产生了“买入市场”策略,而不是选股或积极投资。
- PageRank 作为 web 搜索的基础,利用了这样一个事实,即在确定网页重要性时,网页之间的连接比它们的内容更能提供信息,这极大地增加了搜索相关性,减少了垃圾邮件。
你可以很清楚地看到,这些玩具模型中的每一个都指向一个非常值得解决的问题,影响了数百万人,产生了数千亿美元的实际价值。任何致力于解决这些问题的人显然都在做正确的事情。他们是怎么知道的?你通常会发现这种选择正确工作的技巧在技术圈被称为“产品意识”,这基本上是一种识别哪些问题值得解决以及这些问题的哪些解决方案最有价值的艺术。
擅长这个包括为你正在探索的任何模型、产品或流程开发一个评估框架,其中心是围绕优化的核心指标。
- 对于 sabermetrics,核心指标是每场胜利的美元数,因为棒球队的目标是利用他们的资源(工资)赢得比赛。事实证明,市场高估了安打,低估了保送,这种低效率被一些小型市场团队用来与那些预算较大的团队有效竞争。并最终被一个大型市场团队(波士顿红袜队)用来赢得冠军。
- 对于有效市场假说来说,核心指标是财富的增长百分比——在一段时间结束时,你的财富比开始时多了多少。这让投资者转向低负荷共同基金和 ETF,它们在过去 10 年中作为一种资产类别的表现优于对冲基金(特别是在计入费用后)。
- 对于 PageRank,核心指标是每次点击的搜索次数(我们希望这个值很低,这意味着最好的结果可以很快找到)。PageRank 通过返回最相关的结果对此进行了优化。这使得网络成为一个有用的地方,当然,也形成了有史以来最大的科技公司之一的支柱。
我提倡学习这样做的以下过程:
- 选择一个你喜欢使用和熟悉的产品或服务。
- 建立一个玩具模型,描述产品如何工作——谁是它的用户,他们如何找到产品,他们如何转换,他们如何参与。
- 添加一个描述公司如何产生成本和收入的框架——获取渠道、运营成本和货币化。
- 选择一个你喜欢的特性,用你的模型和框架来计算他们从中获得了多少。对他们是否应该拥有该功能有一个看法,或者你需要什么信息来做这个决定。
- 对于额外的积分,用一个他们还没有的新功能做同样的事情。
- 重复!
这里有几个我非常喜欢的例子,应该可以帮助你开始:
- 在 Airbnb 的相关性
- 流媒体音乐的货币化(如 Pandora 或 Spotify)
- 围绕电动滑板车共享的单位经济学(如 Bird 或 Lime)
将这个过程运行几次,特别是如果你将步骤(1)和(2)结合起来,可以增强你的产品开发能力。这是很好的准备工作,但不会让你一路走到那一步。这里缺少了一个关键的部分:你怎么知道你是对的?或者,换句话说,你怎么知道你已经变得擅长这个了?
第三步:发展观点,做出预测,并让自己对它们负责
这就把我们带到了步骤(3),开始做预测,最好是在游戏中有一些皮肤。反复经历步骤(1)和(2)会让你对任何事情都有看法。但是目标不仅仅是拥有观点,而是拥有好的观点。实现这一点的唯一方法是添加一个反馈机制。这意味着写下你的观点,用它们做出并跟踪预测,并对自己的观点负责。责任感真的很重要——没有它,你会记住你的成功,忘记你的失败,你不会进步。最终,你会用这个过程为你自己(比如在哪里工作)和你的公司(比如在哪里投资)做出真正困难的决定,所以你真的希望它能产生好的结果。
人们用来赚大钱的观点的例子:
- 在亚马逊无利可图的时候投资它,但却产生了大量的自由现金流。
- 在雅虎和 AltaVista 明显赢得市场的时候建立另一个搜索引擎。
- 在 2008 年崩盘后立即购买房地产或股票。
- 当允许陌生人睡在你家是一个疯狂的想法时,你就投资了 AirBNB。
你希望你的观点和相关的预测和这些一样好,而责任是实现这一点的关键。一些低风险的问责方式:
- 通过博客、推文或新信公开你的观点和预测。(体育分析社区通常走这条路。)
- 基于你的一个观点开始一个副业项目,在那里你创造用户和/或收入。
- 通过投资来支持你的观点。
我记录下我所有的观点和我用这些观点做出的预测,并试着把一些事情放在后面,这样如果我错了,它会很痛(但不会太痛)。
有几个我是对的(至少到目前为止):
- 亚马逊和苹果(大约 2004 年)
- 比特币
- 湾区房地产邮报 2008
我错过了一些:
- 微软和谷歌
- 以太坊
- Fitbit
我的观点并不总是正确的,但随着时间的推移,我的观点越来越接近正确。但是随着时间的推移,在游戏中有一些责任感和皮肤无疑让我变得更好。由此产生的自信让我在做高风险决策时更加有效。
关键是这最后一步结束了循环——通过强制执行责任反馈步骤,你将了解你是否成功地理解了系统并从中提取了价值。
包扎
如果你做完这些练习,你就会知道如何去做
- 识别现实世界中的系统,并通过玩具模型进行分析。
- 应用产品意识,通过在你的模型上分层定量评估框架,发现那些系统中哪些代表真正的机会。和
- 对你在(1)和(2)中得出的观点和预测负责,以确保你确实产生了好的观点和预测。
到了这里,你就开始为自己增压,准备好在一个非常高的水平上为企业或产品的发展做出贡献。你将为下一步做好准备,学习如何产生你自己的好想法,并让这些创意源源不断。我称之为扩展你的想法产生平台,我们将在第三部分中讨论。
(希望提升你的职业生涯?在 建立你的技能世界贝叶斯 )
如何利用人工智能预测(并防止)客户流失
原文:https://towardsdatascience.com/how-to-leverage-ai-to-predict-and-prevent-customer-churn-f84d653a76fb?source=collection_archive---------6-----------------------
对于任何数字或在线业务来说,赢得客户只是战斗的一半。这也是为了吸引并最终留住客户,以取得长期成功。解决客户流失问题一直是品牌和开发在线用户体验的产品团队面临的最大挑战之一。对大多数人来说,每月 5%的流失率听起来没什么大不了的,但是每年复合计算,你可能会失去将近一半的客户!也就是说,你需要非常努力地工作,才能让你的企业保持目前的规模,而不是萎缩。
没有什么比在众所周知的仓鼠轮上“奔跑”时烧掉你辛苦赚来的资本更糟糕的了
…换句话说,努力工作却一事无成。当你有 5%的流失率时,很难想象会有什么增长,你需要稳定下来,保持运转。是时候我们停止猜测客户流失的原因,开始利用一些新的方法来解决这个问题了。
获得一个新客户的成本通常是留住一个现有客户的 5 到 25 倍,这使得最大限度地减少客户流失对任何企业都至关重要。这就是为什么产品经理采取积极主动的方法来留住用户,以最大限度地降低获取成本,并增加长期大规模采用的机会是如此重要。但是任何产品经理都知道,他们将会遇到严重的障碍,从而影响产品的采用和保留。
问题是,大多数经理传统上采取追溯的方法来解决客户流失。他们会进行调整、变化和调整,然后追溯过去,并对这些变化是否有效进行事后分析。然而,随着人工智能(AI)应用的最新进展,产品经理现在能够更好地预测客户流失,并采取积极措施防止客户流失。
追溯方法的问题是
你已经创建了一个看起来功能良好的产品或应用程序,拥有流畅的用户体验,并在用户获取方面取得了一些初步成功。但过了一段时间,用户开始减少,客户流失,你不太清楚为什么。为了减少流失,设计师、开发人员和产品经理会尝试各种策略来解决这个问题。他们可能会改变颜色,调整字体,移动付费墙,或改变用户界面(UI),然后等待 2-3 周来衡量营业额是否有所改善。根据几周前的保留基准,他们将尝试找出是哪项或哪些更改产生了影响。是一个变化,几个变化,还是变化的总和?
这种循环的中断会扼杀与改进 UX 相关的所有部门的工作流程、生产力和整体效率。这种一次测试一个或两个变更、衡量成功、选择最佳选项,然后进行下一步的 A/B 方法是缓慢、繁琐和低效的。更糟糕的是,即使考虑这样做是正确的,你也需要一次实现一个改变,这可能比你的业务跑道花费更多的时间。
简而言之,这是一种落后的方法,分割了 UX 改进过程,并且经常解决客户流失的根本原因太少,太晚。
人工智能如何主动解决客户流失问题
我们的数据科学家团队已经开发出一种更好、更快、更有效的方法来解决客户流失问题,这种方法利用了机器学习的新进展。我们方法的真正秘诀是以预测的方式利用人工智能。你越能预测客户流失,你就能越好地预防它。通过机器学习模型,你可以了解是什么导致了客户流失。产品经理、开发人员、设计人员和高管都免于猜谜游戏。
预言;预测;预告
第一步是探索阶段,在这个阶段,你要深入研究数据。与点击流或购买数据不同,利用机器学习可以让你筛选大量数据,而不仅仅是一小部分。例如,如果您有一个 100 名用户的列表,按照流失可能性从上到下排列,您可以分析聚类以查看哪些类型的人似乎出现在“极有可能流失”桶中。通过揭示客户的年龄、性别、收入、活动和客户来源等个人资料属性,您将能够更好地预测哪些类型的客户可能会流失(哪些不会)。
诊断
机器学习可以带你分析数据,以便分析师能够帮助业务团队了解谁可能会流失,并在用户界面上提出预防性的变化。通过行为分析工具,您可以根据任何属性(行为、支出水平、年龄或群体)对用户进行细分,并采取适当的行动。诊断步骤也是至关重要的,因为你可以量化风险,纠正过程,并采取措施防止未来发生人员流动。
利用人工智能的行动步骤
现在,你已经有效地利用人工智能来开发预测模型,以预测哪些类型的客户很可能流失,下面是一些你可以采取的具体行动,以防止在你的业务或产品的生命周期内流失:
- 干预 —防止客户流失的最佳方法之一是对可能流失的客户档案的客户生命周期进行干预。通过向用户和您的内部团队发出警报,您可以集中精力采取措施留住重要客户甚至特定的个人。
- 收购 —客户流失并不总是基于个人资料元素来预测。它还取决于收购渠道(谷歌广告词、社交媒体、内容营销、合作伙伴推荐等)。).基于你的预测分析,你可以只锁定那些拥有最佳留存率和 LTV 的最有利可图的用户,当然,也可以针对这些特定的客户微调你的产品。
- 体验 —颜色、字体、用户流量和体验的其他部分都是最终影响客户流失的因素。有了人工智能和行为分析,你现在有工具知道在哪里集中精力调整用户体验。
底线是客户流失不能再追溯解决了。如果公司、品牌和产品经理想要有意义地降低流失率,他们需要采取主动的方法。通过利用人工智能生成数据驱动的预测策略,公司可以不再猜测将精力集中在哪里,以实现更健康的 SaaS 业务,甚至获得竞争优势。
如何与数据科学撒谎
原文:https://towardsdatascience.com/how-to-lie-with-data-science-5090f3891d9c?source=collection_archive---------6-----------------------
最近,我读了达雷尔·赫夫写的《如何用统计撒谎》一书。这本书谈到了如何利用统计数据让人们得出错误的结论。我发现这是一个令人兴奋的话题,我认为它与数据科学非常相关。这就是为什么我要把“数据科学”版书中的例子展示出来。其中一些是书中的,其他的是我看到的可能发生在现实生活数据科学中的例子。
这篇文章实际上并不是关于如何用数据科学撒谎。相反,它是关于我们如何可能因为没有对管道不同部分的细节给予足够的关注而被愚弄。
图表
把自己想象成某个公司的新数据科学家。这家公司已经有一个数据科学团队,他们建立一个模型来预测一些重要的事情。您是一位非常有才华的数据科学家,仅仅一个月后,您就能够将他们的模型准确性提高 3%。难以置信!你想向某人展示你的进步,所以你准备了这张图表:
现在,这看起来不错,但不是很令人印象深刻,你想留下深刻的印象,所以你能做什么(除了进一步改进你的模型)?为了更好地展示同样的数据,你需要做的只是稍微改变一下图表。你需要让它专注于改变。所有这些低于 80%或高于 85%的数字都没有“真正的”需求。所以它看起来像这样:
看起来你的模型比旧的要好四倍!当然,聪明的读者会明白到底发生了什么,但这个图表看起来令人印象深刻,许多人会记住这个巨大的差距,而不是确切的数字。
随着时间的推移,我们可以用过程做同样的事情。假设你和你的团队在研究某个模型,最近几周你有了突破,所以你的模型性能提高了 2%,非常好。看起来是这样的:
很难看出变化,实际数字是。同样,也许 2%是一个显著的进步,但在这张图表中,它看起来并不那么好。所以让我们像以前一样改变它:
同样,这些数字是相同的,但是这张图看起来比上一张好得多。
测量值
通常,初级数据科学家并没有足够重视使用什么度量标准来度量他们的模型性能。这可能会导致使用一些默认的、大多数时候是错误的度量标准。以准确性为例,在现实生活中(在大多数情况下),这是一个非常糟糕的指标。这是因为现实生活中的大多数问题,数据都是不平衡的。考虑一个预测泰坦尼克号幸存者的模型,这是一个非常受欢迎的 Kaggle 教程。如果我告诉你我建立了一个 61%准确率的模型。好吃吗?很难说。我们没有任何可以与之比较的东西(稍后会详细介绍)。听起来还行。这可能比什么都没有好得多,对吗?让我展示一下我到底做了什么:
predicted = np.zeros(len(test_df))
print accuracy_score(predicted, test_df['Survived'])
没错,我所做的就是预测所有实例的“零”(或“否”)。我能得到这个准确率(61%)仅仅是因为活下来的人比没活下来的人少。还有更极端的情况,数据非常不平衡,在那些情况下,甚至 99%的准确率可能什么都不是。这种极端不平衡数据的一个例子是当我们想要正确地分类一些罕见的疾病时。如果只有 1%的人患有这种疾病,那么每次预测“不”,就会给我们 99%的准确率!
这不仅关系到准确性。当我们阅读一些研究/试验/论文的结果时(或者万一我们发表了我们的结果),我们需要确保所使用的度量标准适合它试图测量的问题。
关于测量,我们需要做的另一件重要的事情是了解结果的好坏。即使我们使用了正确的衡量标准,有时也很难知道它们的好坏。90%的精度对于一个问题来说可能是极好的,但对于其他问题来说则非常糟糕。这就是为什么一个好的实践是创建一个基准。创建一个非常简单的(甚至是随机的)模型,并将其与你/他人的结果进行比较。对于泰坦尼克号问题,我们已经知道,仅仅对每个人说“不”就会给我们 61%的准确率,所以当某个算法给我们 70%的时候,我们可以说这个算法贡献了一些东西,但很可能它可以做得更好。
泄密
我想谈谈我在数据科学历史中遇到的 3 种漏洞。特征工程/选择泄漏、从属数据泄漏和不可用数据泄漏。
特征工程/选择泄漏:
在大多数情况下,我们需要对我们的数据做一些预处理和/或特征工程,然后再将它推入一些分类器。很多时候使用一些类(Transformer)很容易做到这一点,这里有一个sklearn
例子:
X, y = get_some_data()X = SomeFeaturesTransformer().fit_transform(X)X_train, X_test, y_train, y_test = train_test_split(X, y)classifier = SomeClassifier().fit(X_train, y_train)
对于那些不熟悉sklearn
或python
的人来说:在第一行,我用一些方法得到我的数据。然后我使用SomeFeaturesTransformer
类从数据中提取特征。然后,我将数据分为训练和测试,最后训练我的分类器。
你看到这里的漏洞了吗?大多数时候,特征提取/选择是模型的一部分,所以通过在分割之前执行这个步骤,我在测试集上训练我的模型的一部分!一个简单的例子是当我们想要使用一些关于我们特征的统计数据时。例如,我们的特征之一可能是偏离平均值。假设我们有房屋大小-价格预测,我们想使用当前房屋大小与平均房屋大小的差异作为一个特征。通过计算整个数据(而不仅仅是训练集)的平均值,我们将测试集的信息引入到我们的模型中!(数据的平均值是模型的一部分)。在这种情况下,我们可能会在我们的测试集上获得出色的结果,但是当我们在生产中使用这个模型时,它会产生不同/更差的结果。
我们的模型不仅仅是管道末端的分类器。我们需要确保模型的任何部分都不能访问关于测试集的任何信息。
从属数据泄漏:
在我的论文工作中,我建立了一个系统,试图将话语录音分为典型和非典型语音。我有 30 个参与者,15 个句子,每个重复 4 次。所以总共 30154=1800 次录音。这是非常少的数据,所以我想做交叉验证来评估我的算法,而不是仅仅将其分为训练和测试。然而,我需要非常小心,即使没有交叉验证,当我随机选择我的数据的某个百分比作为测试集时,我将(很可能)获得测试集中所有参与者的记录!这意味着我的模型是在将要测试的参与者身上训练的!当然,我的结果会很棒,但我的模型将学会识别不同参与者的不同声音,而不是典型或非典型的讲话!我会得到高分,但实际上,我的模型没什么价值。
正确的方法是在参与者级别拆分数据(或进行交叉验证),即使用 5 名参与者作为测试集,另外 25 名参与者作为训练集。
这种类型的相关数据可能出现在不同的数据集中。另一个例子是当我们试图在工作和候选人之间创建一个匹配算法。我们不想向我们的模型显示将出现在测试集中的作业。我们需要确保模型的所有部分都不会看到来自测试集的任何数据。
不可用数据泄漏:
这是很常见的一个。有时,我们的数据中有一些列在将来对我们来说是不可用的。这里有一个简单的例子:我们想预测用户对我们网站上产品的满意度。我们获得了大量的历史数据,因此我们利用这些数据建立了模型。我们有一个名为 User Satisfaction
的字段,它是我们的目标变量。我们取得了优异的成绩,我们很高兴。然而,当我们在生产中使用我们的模型时,它预测绝对没有意义。原来除了一般的用户满意度,用户提供的其他领域。像用户是否对交付、运输、客户支持等满意的字段。这些字段在预测时间中对我们不可用,并且与一般用户满意度非常相关(并且具有预测性)。我们的模型使用它们来预测总体满意度,并且做得非常好,但是当这些字段不可用时(并且我们估算它们),该模型不必做出太多贡献。
机会/运气
让我们回到典型-非典型言语问题。正如我所说的,只有 30 名参与者,所以如果我做一个简单的 20%-80%的训练测试分割,我将只有 6 名参与者进行测试。六个参与者非常少。我可能会碰巧对其中的 5 个进行正确的分类。我甚至可以正确地将它们分类,只是因为我很幸运。这将给我 100%的准确性!(或者在只有 5 个正确的情况下为 83%)。它可能看起来很棒,当我发布我的结果时,它会看起来非常令人印象深刻,但事实是这个分数并不重要(甚至不真实)。
如果我们假设有 50%的人有非典型的言论,那么仅仅通过随机猜测,我就有 50%的机会是正确的,这意味着如果我试图猜测 6 名参与者,我会将他们全部正确分类 0.5⁶=0.01 (1%)次。也就是说,100 个随机模型中有 1 个会有 100%的准确率!(100 个中有 3 个会有 83%的准确率)。
这里正确的方法是“留下一个交叉验证”,将所有的参与者作为一个测试。
人类
将学习算法比作人类是非常诱人的。这在很多医学领域都很常见。但是,对比人类和机器,一点都不琐碎。假设我们有一种算法可以诊断一种罕见的疾病。我们已经看到,对于不平衡的数据,使用准确性作为度量并不是一个好主意。在这种情况下,如果我们使用精确度和召回率来进行模型评估和比较,可能会好得多。我们可以使用某个医生的精确度和召回率,并将其与我们的算法进行比较。然而,在精确度和召回率之间总是有一个权衡,我们并不总是清楚我们更想要什么,高精确度还是高召回率。如果我们的算法得到 60%的准确率和 80%的召回率,医生得到 40%的准确率和 100%的召回率,谁更胜一筹?我们可以说精度更高,因此我们的算法“比人更好”。此外,作为一种算法,我们可以控制这种权衡,我们需要做的只是改变我们的分类阈值,我们可以将精度(或召回)设置为我们希望的点(并看看召回会发生什么)。因此,更好的选择是使用 ROC AUC 得分或“平均精度”进行模型评估。这些指标考虑了精确度-召回率的权衡,并提供了关于我们的模型如何“预测”的更好的指标。人类没有 ROC AUCs,也没有“平均精度”。我们无法在任何一个医生身上控制(大多数情况下)这个门槛。有不同的技术可以为一组人类决策者提供精确回忆曲线,但这些技术几乎从未使用过。关于这一点,这里有一个很棒而且更详细的帖子:
[## 机器真的会打败医生吗?ROC 曲线和绩效指标
医学领域的深度学习研究目前有点像狂野的西部;有时你会找到金子,有时会找到…
lukeoakdenrayner.wordpress.com](https://lukeoakdenrayner.wordpress.com/2017/12/06/do-machines-actually-beat-doctors-roc-curves-and-performance-metrics/)
结论
在这篇文章中,我展示了当我们试图发布一些算法结果或解释其他结果时可能出现的不同陷阱。我认为从中得出的主要观点是“当它看起来好得难以置信时,它很可能是真的”。当我们的模型(或其他模型)看起来出奇的好时,我们必须确保我们的管道中的所有步骤都是正确的。
如何使用 Python、Geopandas 和 Matplotlib 制作 gif 地图
原文:https://towardsdatascience.com/how-to-make-a-gif-map-using-python-geopandas-and-matplotlib-cd8827cefbc8?source=collection_archive---------5-----------------------
不需要 Photoshop:只使用 Python 和命令行制作动画图表。
更新:我增加了一个归一化功能来保持每张地图的彩条图例范围相同。下面和 Github 上的 Jupyter 笔记本中的代码已更新。请看下面关于怪异渲染的注释。
作为一种语言,Python 非常灵活。这使得有时仅用几行代码就可以实现许多不同的可视化。但是现在有了这么多不同的图表网站和软件,为什么还要写代码呢?难道我们就不能用 GUI 上传一个 csv 文件,调整范围,点击导出 png 然后收工吗?
是的。你当然可以。有时,如果您需要快速、一次性的图表或地图,这是最佳选择。但是当你需要制作大量的地图——大量的地图时,使用 Python 的真正力量就发挥出来了。
在本教程中,我将在之前的文章的基础上,讲述如何使用 Geopandas 和 Matplotlib 制作 choropleth 地图。我们将以此为起点,所以如果你想赶上进度,请在这里查看帖子或在 Github 上查看我的 Jupyter 笔记本。
这次我将介绍如何创建一个动画 gif choropleth 来显示地理数据(因为它是一张地图)和随时间的变化。最重要的是,本教程将从头到尾只使用 Python 和一些命令行工具。无需在 Photoshop 中寻找正确的菜单/下拉菜单/窗口。
正如我在之前的教程中提到的,这可能不是所有用例的最佳工作流。但是如果速度、再现性和一致性是你优先考虑的,我认为这是一个好办法。
为什么是 gif 图?
在过去的几年里,gif 图表似乎在社交媒体上变得非常流行。《金融时报》和《经济学人》等出版商花了更多时间来简化和完善他们的数据,即在 Twitter 和 Instagram 等平台上获得更多参与的格式。也许更重要的是,gif 图表允许在静态图表所显示的基础上有一个新的故事层。
这有几种不同的用法:
- 通过注释或突出显示引导用户浏览同一图表中最重要的点
- 通过比较显示两个不同的图表
- 显示相同的图表随时间的变化(这是我将要介绍的内容)
这个列表并不详尽,用例还在继续扩展。总之:移动图表既酷又有用(如果使用正确的话)。
让我们开始映射。
如何制作 gif 图
不必重述之前教程的每一个步骤,以下是你应该开始的:
- 在 shapefile 中加载
- 加载 csv 格式的数据以进行可视化
- 连接两个数据框
- 绘制地图并开始设计风格。
现在,我们将使用 Python 中 for()循环的强大功能,使用多个不同的列生成相同的地图。因为我们想显示随时间的变化,我们需要确保我们的数据包含多年的变量。为了便于标记,让我们确保数据的每个列标题都是一个年份数字。
为了遍历列,我们需要一个字符串列表来调用每一列的名称。让我们创建一个包含每列年份的列表变量(格式化为字符串)。让我们也设置一个输出路径,这样我们所有的地图都保存到一个文件夹中。
*# save all the maps in the charts folder*
output_path = 'charts/maps'
*# counter for the for loop*
i = 0
*# list of years (which are the column names at the moment)*
list_of_years = ['200807','200907','201007','201107','201207','201307','201407','201507','201607']
最后,在创建映射之前,我们希望为 vmin 和 max 值设置一个一致的全局变量。这设置了颜色范围的值。如果没有预先设置,Matplotlib 将在每次 for 循环迭代时更改 choropleth 的范围,因此很难看到值是如何随时间增加或减少的。
*# set the min and max range for the choropleth map*
vmin, vmax = 200, 1200
编写 for 循环
一旦开始使用它们,for()循环就相当简单了。for()循环的语法是这样的:
- 对于 list_of_years 列表中的每一年,运行以下代码。
- 当列表中的所有年份都完成了代码时,停止循环。
以下是使用上一教程中底图要点的代码:
*# start the for loop to create one map per year*
**for** year **in** list_of_years:
*# create map,* UDPATE: added plt.Normalize to keep the legend range the same for all maps
fig = merged1.plot(column=year, cmap='Blues', figsize=(10,10), linewidth=0.8, edgecolor='0.8', vmin=vmin, vmax=vmax,
legend=True, norm=plt.Normalize(vmin=vmin, vmax=vmax))
*# remove axis of chart*
fig.axis('off')
*# add a title*
fig.set_title('Violent crimes in London', \
fontdict={'fontsize': '25',
'fontweight' : '3'})
*# this will save the figure as a high-res png in the output path. you can also save as svg if you prefer.*
filepath = os.path.join(output_path, only_year+'_violence.jpg')
chart = fig.get_figure()
chart.savefig(filepath, dpi=300)
如果您运行这段代码并打开刚才设置的输出路径文件夹,您应该会看到许多地图,每张地图都有略微不同的阴影,代表不同年份的数据。但是这可能会让浏览者感到困惑:一旦地图动画化,他们怎么知道年的增量呢?
我们可以在底部设置一个简单的日期范围(2007–2015),但是 for()循环给了我们一个更好的解决方案。因为我们已经将每一列的年份作为字符串保存在变量中,所以我们可以为每个地图添加不同的注释(对应于数据的年份)。
根据我们的 for()循环,变量“year”将是 for 循环每次运行时的列 year。使用这个逻辑,我们可以插入“year”作为 fig.annotate()参数的变量。
现在,每次 for 循环运行时,不同的年份将作为注释插入到地图上。使用相同的逻辑,我们也可以设置文件名以每年开始,这样就很容易找到每年对应的地图。在 for()循环中添加这段代码将会添加一个 year 注释。
*# create an annotation for the year by grabbing the first 4 digits*
only_year = year[:4] *# position the annotation to the bottom left*
fig.annotate(only_year,
xy=(0.1, .225), xycoords='figure fraction',
horizontalalignment='left', verticalalignment='top',
fontsize=35)
重新运行代码,您的地图应该会被新的地图所替换,每个地图的左下角都有一个年份注释。如果你从上到下浏览地图,你可以开始对你的 gif 有个大概的了解。
制作 gif
对于最后一步(gif 制作),我们将离开 Python 并打开终端(或您使用的任何命令行编辑器)。导航到您在终端中保存所有文件的目录。
遗憾的是,我找不到让 ImageMagick 将我的 png 地图批量转换成 jpg 格式的方法。我似乎无法让 matplotlib 将我的图表保存为。jpg(得到一个在这个堆栈溢出线程上描述的错误)。所以我找到了一个变通方法,使用一个叫做 sips 的 Mac 程序(教程和讲解者在这里)。但本质上,它是一个命令行工具来批量转换文件。对于非 Mac 用户,我相信也有类似的解决方案!
将这段代码复制/粘贴到您的终端上,将所有的 png 文件转换成 jpg 文件。
for i in *.png; do sips -s format jpeg -s formatOptions 70 "${i}" --out "${i%png}jpg"; done
有许多方法可以制作 gif,但我使用 ImageMagick 有几个原因:
- 安装和设置相对容易
- 它允许您在一行代码中设置过渡时间、裁剪大小和文件格式
- 它超级快
ImageMagick 的文档非常全面。如果你还没有安装它,看看他们的安装和文档页面。
要检查是否正确安装了 ImageMagick:
- 在终端中,键入:
convert -version
2.如果已经安装了 ImageMagick,将显示带有版本和版权声明的消息。一旦您在系统上安装了 ImageMagick,请导航到包含我们刚刚制作的所有地图的目录。现在我们需要运行一行代码来创建 gif。简而言之,它是这样做的:
- 转换:获取所有这些文件并进行更改
- -delay 60 :设置进入下一幅图像之前每幅图像之间经过的时间
- -循环 0 :设置无限循环
- <插入所有将被转换的文件名>
- my_map.gif
下面是在终端中使用的代码:
convert -delay 60 -loop 0 2008_violence.jpg 2009_violence.jpg 2010_violence.jpg 2011_violence.jpg 2012_violence.jpg 2013_violence.jpg 2014_violence.jpg 2015_violence.jpg 2016_violence.jpg new_map_normal.gif
现在检查您创建的新文件“new_map_normal.gif ”,您应该会看到类似这样的内容:
The gif above still renders as changing color range here on Medium, but the code outputs the correct file and the legend is correct when you view the file on other sites ¯_(ツ)_/¯. Download it and view in a different programme to see for yourself (and anyone who knows why this might be, let me know!).
就是这样!我们有一张 gif 图。
当然,现在这开始提出一系列新的问题:为什么近年来颜色变深了?暴力犯罪显著上升了吗?这种格式的 Gif 地图的局限性在于很难看清每个行政区背后的实际数字。
为此,更复杂的组合图可能比在右边包含一个图例更有用(下一次要处理的图例!).然而,作为一种揭示数据背后的故事的方法,使用 gif 地图可以成为更深入分析的一个很好的切入点。另外,你可以把任何一种有时间序列数据的图表转换成 gif 图表——我选择地图是因为它们很酷。
和往常一样,你可以在 Github 上找到复制本教程所需的所有代码(Jupyter 笔记本、shapefiles 和数据)。如果你有任何问题,在推特上找我。
感谢阅读!我还出版了一份关于数据可视化、数据科学和技术交叉的每周时事通讯。每一版都包含可供阅读的文章、可供探索的可视化内容、可供分析的数据集以及更多可供学习的教程。你可以在这里 报名。
如何制作人们会真正使用的仪表板
原文:https://towardsdatascience.com/how-to-make-dashboards-that-people-will-actually-use-16c6ec35334a?source=collection_archive---------8-----------------------
当今的组织在构建仪表板上花费了大量的金钱和时间。“只要我们有一个令人眼花缭乱的仪表板,我们最终将成为数据驱动的,”他们承诺——但这与事实相去甚远。根据 Logix 的一份 2017 年报告,实际上,只有 45%能够使用 BI 工具的人报告说他们实际上在使用它们。他们提到的最常见的挑战是,仪表盘太难使用了。
不同的人做不同的决定。如果您想要构建仪表板来帮助他们做出更好的决策,您首先必须了解他们如何以及为什么做出这些决策。你可以坐在一个数据宝库上,做出最精美的图表,但如果你不能从噪音中过滤出数据,并以正确的方式呈现正确的数据,那就没有意义了。
在 SocialCops,我们积极尝试避免这种“令人眼花缭乱的仪表板”陷阱。我们的核心价值观之一是“问题第一,解决方案第二”将这转化为现实的一种方式是,我们将 80%的时间集中在解决问题上,然后用 20%的时间设计解决方案(通常是一个仪表板)。我们花在问题陈述上的时间越多,花在实现上的时间就越少,实现就变得越有效。
作为一个在遇到问题时总是跳出来执行的人,这与我一生所知道的事情是如此的违背直觉。但是我为儿童投资基金基金会(CIFF)做的一个项目完全改变了我的想法。随着项目的进行,在处理数据或构建仪表板之前,弄清楚用户和他们正在做的决定是如此重要,这一点变得很明显。
在这篇文章中,我将使用 CIFF 的故事,通过 8 个步骤来讲述我们在如何构建用户会真正使用和喜欢的仪表盘方面的学习。
第一步:文献综述:不仅仅是学术界
绕过文献综述似乎很诱人,但它对构建一个伟大的仪表板至关重要。在进行用户访谈之前,不能跳过作业。文献综述奠定了坚实的基础,有助于你更深入地理解问题陈述。
CIFF 是一个捐助组织,致力于改善发展中国家弱势儿童和青少年的生活。他们在拉贾斯坦邦开展了几个以儿童为中心的项目。他们向我们提出了一个非常有趣的问题陈述——建立一个仪表板,帮助他们深入评估他们的儿童福利项目的实际影响。
当然,我们知道儿童福利,但它实际上意味着什么呢?它是如何定义的?为了给仪表板打下良好的基础,我们广泛查阅了儿童福利文献,使用了我们能找到的所有相关资料——研究论文、期刊和书籍。在此过程中,我们首先做了以下工作:
- 为儿童定义的年龄段(例如,0-1 岁为婴儿,1-5 岁为儿童)
- 为本项目定义了“儿童福利”的范围和目标
- 概述了儿童福利部门,如教育、卫生、营养和犯罪
- 确定了我们指数的焦点群体——易受伤害和需要立即关注的儿童。
我们还研究了印度和全球的儿童相关指数。这些指数向我们展示了在全球范围内被追踪的重要指标。这也给了我们一些有趣的见解。
Screenshot highlighting the table of contents from our research report for CIFF
例如,一个国家的指数中使用的指标类型因该国的发达程度而异。在像美国这样高度发达的国家,儿童福利指数可能倾向于高等教育、社会保障和教育歧视等指标;而在印度,指标更侧重于消除营养不良、提供高中教育和学校适当的卫生设施。
第二步:总是从用户开始
最好的仪表板始于真正使用它们的人。确定不同的用户组,他们需要解决的问题,以及他们需要从仪表板中得到什么。最好的方法是实地考察和亲自采访;但是,如果这是不可能的,呼吁帮助。
我们的下一步是了解仪表板的用户,他们关心什么,什么信息和见解对他们很重要。于是我们出发去拉贾斯坦邦的首府“粉红之城”实地考察。
由于并非所有用户都有相同的行为或目标,因此必须分析每个用户的个性、角色和职责。我们采访了斋浦尔的不同用户组,然后根据他们需要使用仪表板做出的决策绘制了用户组。举个例子,
- 和 首席秘书对拉贾斯坦邦儿童福利的总体状况感兴趣,并将其表现与其他邦进行比较。因此,对他们来说,仪表板需要帮助通知和推动他们的政策和战略。
- 项目 和 方案主管需要跟踪他们项目的进度和成果。因此仪表板需要指出他们各自项目中的具体瓶颈,并帮助他们影响实际活动。
- ****CIFF 和他们的非政府组织伙伴热衷于了解他们在与儿童相关的部门中应该针对的关键优先事项。这将有助于他们资助和设计满足这些优先事项及其触发因素的干预措施。
第三步:首先是问题,而不是数据
从你的仪表板需要回答的问题开始。从关于问题的宽泛问题转移到可操作问题的综合列表,这将为您指出解决方案。这些问题将是你仪表板的核心。
我们没有查看 CIFF 的数据,也没有弄清楚如何展示这些数据,而是接下来查看了 CIFF 的需求(在用户访谈中公布)。CIFF 需要回答什么问题来衡量它的影响?我们回到绘图板,从非常基本的问题开始:“项目在实现其结果方面有多成功?”,“节目的覆盖范围是什么?与印度相比,拉贾斯坦邦的表现如何?“,等等。
然而,我们并没有就此止步。这些问题将有助于 CIFF 了解他们做得如何,但不是他们下一步该做什么。为了使我们的解决方案更加面向行动,我们更进一步:“什么是最脆弱的儿童群体?”,“它们位于哪里?”、“这些领域需要哪些项目和干预措施?”“对他们来说,哪些干预措施最成功?”、“现在的节目在哪里破?”、什么外围因素在起作用等等。
A screenshot from our dashboard mockup for CIFF that is helping them track various programs and interventions
在这个练习的最后,我们都同意回答这些问题将使每个仪表板用户具备他们需要的洞察力,以了解哪些程序执行得不好,暴露关键的瓶颈,并显示潜在的后续步骤。
第四步:关注北极星指标
将一系列问题整合成一组核心指标或指标,这些指标或指标能让您一目了然地从较高层面了解他们的行业或问题。这有助于用户关注真正重要的东西,而不是被一大堆指标和图表分散注意力。
下一步是找出如何回答这些问题,并以数据驱动的方式揭示实际情况。挑战——儿童福利是一个非常复杂的课题。它包含无数的政策、法律和部门,以及一系列复杂的利益攸关方(政府部门和部委、慈善机构、国家和国际机构等等)。
挑战不仅限于涉及多个不同的利益攸关方。另一个挑战是,我们想要回答的问题不能用一组简单的指标来解释,因为我们的利益相关者以不同的方式理解和衡量它们。此外,儿童福利绝不简单,所以每个问题都不可避免地涉及多个部门。为了解决这一复杂性并将这些问题和部门整合在一起,我们创建了单独的部门指数——每个影响儿童福利的部门一个指数,如教育和营养。然后我们将这些指数合并成一个单一的指数,拉贾斯坦邦的 C 儿童福利指数,它将作为我们单一的、统一的北极星指标。
这一指数将通过把所有部门和发展伙伴的数据整合到一个平台上来创建。因此,它将自动考虑不同项目的不同“定义措施”,并以清晰、简洁的方式呈现它们。这将有助于用户理解拼图中他们自己的部分,并描绘出这些部分是如何与拉贾斯坦邦儿童福利的大图景联系在一起的。
步骤 5:故事板用户将如何做决定
抓住每个用户群,专注于他们需要做出的决定,并为可视化或屏幕创建一个布局,展示他们需要的准确洞察力。逐个用户组地查看,以确保您的仪表板能够满足每个用户的特定需求。在白板或纸上画一个粗略的草图会有很大帮助。
接下来,我们需要为仪表板创建“决策流”,或者用户如何导航仪表板以做出决策。我们的用户研究在我们用故事板列出用户需要做出的决定时派上了用场。在头脑风暴时,我们意识到这三类用户需要三种不同类型的屏幕。
Different screens help users navigate better on the dashboard and make to better decisions
让我举几个例子来说明这到底意味着什么:
- 教育部长需要跟踪拉贾斯坦邦教育部门的整体表现。对于像他这样的用户,我们设计了一个带有行业指数的概览屏幕,以及地理位置和关键指标的表现。****
- NHM (国家健康使命)的儿童健康** 项目主管会被 aanganwadi 中心注册人数的下降所激励,所以他需要找出原因并解决任何障碍。对于这组用户,我们设计了测量项目输出(或成果)的屏幕,以及成功获得这些输出所需的输入。**
- 如果 CIFF 及其伙伴组织了解到导致儿童辍学的因素(例如,童婚、针对儿童的犯罪、疾病等。),他们可以通过他们的项目和投资来解决这些问题。对于他们,我们设计了包含主要 KPI 及其触发指标的屏幕,以显示指标在不同领域之间的关系。
当我们创建这些设计时,我们从用户那里得到了关于定义、数据集等的反馈。定期反馈有助于我们确保仪表板满足他们的需求和要求。我们采纳了他们的建议,并着手解决他们指出的任何问题——这确实为我们节省了大量时间。
第六步:找到可用的数据,以及它的样子
数据范围界定可能很乏味,但知道哪些数据可用以及数据看起来像什么是很重要的。深入研究所有可能的数据系统的结构和指标,以确定最终指标。(如果数据集本身不可用,您可以通过查看用于收集数据的表单来了解它们。)
下一个任务是检查这个仪表板有哪些数据可用。拉贾斯坦邦的政府数据比其他许多邦更先进。然而,它的所有数据系统都存在于私有的筒仓中——没有集成或挂钩使这些数据系统能够相互通信。
我们知道我们必须将这些数据集和系统整合在一起,所以我们首先必须从里到外了解它们。这意味着找到不同政府部门、行业、项目和计划的所有相关数据集。
我们研究了我们发现的每个数据集的特征,例如来源(例如政府机构、民间社会、智库)、数据类型(例如管理信息系统、报告、调查)和格式(例如 Excel、CSV、PDF)。这有助于我们全面了解可用的数据集及其元数据。然后,我们一个接一个地深入研究数据集,了解它们的指标和变量。我们关注他们的粒度(州、地区、街区、村庄、受益人等)。)、分类(按性别、年龄、种姓、地区等)。),以及可用年份连同周期(数据更新的频率)。
创建指数的最大挑战是指数中的指标需要保持一致。如果它们来自不同的数据源,这可能会很棘手。例如,它们需要(1)以必要的粒度出现,(2)在相同的时间段内被记录,以及(3)都被一致地定义。因此,我们做了一些基本的数据清理,以处理缺失值和异常值或方差。
为了完成数据范围界定,我们开始了第二个研究阶段。我们审查了计划和项目目标,最终确定了投入和产出指标清单。此外,我们还进行了实践研究,以制定儿童福利关键绩效指标及其相关指标。
第 7 步:完善北极星指标的方法
下一步是最终确定仪表盘北极星指标的方法。这是应该咨询数据科学家和统计学家的地方。它们可以帮助您了解如何构建一个强大的指数,以及您可以对这些指数进行哪些其他分析。
现在我们已经知道了哪些数据集和指标可用,我们可以为儿童福利指数创建最终的方法。建立一个索引包括创建一个指标列表,并以数学逻辑的方式将它们组合起来。
我们精心挑选了最重要的指标,并对其进行标准化。我们首先给予所有指标同等的权重,因为我们认为所有涉及儿童福利的部门都同样重要。但是,我们计划通过咨询行业专家并使用主成分分析和奇异值分解等统计方法进行降维,来提高这些权重。
我们还通过按性别、年龄、种姓和地区等分层因素对指数进行分解,从而完善了指数。我们还建议跨时间计算该指数,以便用户能够了解不同地区的儿童福利如何逐年变化。
第 8 步:为用户反馈和设计迭代构建一个原型
One of the rough layouts for the visualization of the dashboard before we built the Powerpoint mocks and Invision prototypes
你不需要一个最终的仪表盘来查看你的用户怎么想。即使是一个简单的原型也是在用户反馈和设计迭代之间启动反馈循环的好方法。像 Invision 甚至交互式 PPT 这样的平台就足够了。
一旦我们有了故事板的草图,我们就开始着手创建模型,这是一个实际仪表板外观和功能的表示或原型。然后,我们将原型带给 CIFF 和其他利益相关者,并要求他们使用它。这有助于我们深入了解他们是否能够利用仪表板上的见解做出决定。
这个过程也非常有用,因为它让用户对问题感兴趣,并鼓励他们分享一些非常有价值的反馈。换句话说,模型就像一个底座,帮助他们获得清晰。这些反馈循环一直持续到每个人都确信仪表板是正确的。
这个过程值得花时间吗?
显然,这个仪表板范围和设计过程需要时间。我们需要 8 个步骤来提出以用户为中心的设计,这还没有考虑到未来的数据处理、清理和标准化,建立数据管道,或建立实际的仪表板。
那么这个过程值得吗?我们认为是。
看着数据,找出最好的指标,并以最漂亮的方式将它们可视化,这很诱人,但往往只会导致一个令人眼花缭乱的仪表板,每年只使用一次或两次。相反,瞄准将使用仪表板的人和它最终需要驱动的决策可以帮助你建立一个你的用户永远不会放下的仪表板。
在我们的例子中,这非常重要,因为仪表板本身非常重要。通过这个仪表板,CIFF 和他们的合作伙伴将能够跟踪他们的投资是如何帮助遏制儿童死亡率和营养不良的;政府官员将能够追踪像宝山和 RJJSY 这样的计划是如何帮助抑制婴儿死亡率和产妇死亡率的;项目主管将能够追踪哪些因素导致了小学教育质量的飙升。如果这个仪表板不容易理解和使用,CIFF 和他们所有的利益相关者将会浪费大量的时间和金钱,而不会更接近他们需要的答案。
A screenshot of from our dashboard mockup that will help CIFF partners identify and address problems based on their projects and investments
此外,我们发现,广泛的范围界定和设计流程有助于我们预见并预防在我们实际创建仪表板时会出现的挑战。例如,广泛的数据范围有助于我们了解最终的仪表板可以包含什么,不可以包含什么。DISE(印度最大的教育数据集)中的大多数指标都有很多分类,但这些分类在其他数据集中是不可用的。如果没有数据范围,我们可能会以不一致的指标或糟糕的索引而告终。
因此,这一范围界定过程有助于我们为这些挑战做好准备,并在它们脱离我们的仪表板之前找出解决它们的方法。这也有助于我们让利益相关者意识到这些挑战,以便他们准备好并愿意在需要时提供额外的帮助或资源。
有兴趣了解更多关于如何确定范围和设计优秀仪表板的信息吗?这里有一些关于设计思维的资源可以帮助你开始:
- https://www . interaction-design . org/literature/topics/design-thinking
- https://medium . com/Wharton-innovation-design/what-is-design-thinking-反正-c59428031331
- https://www.ideou.com/pages/design-thinking
- https://dschool . Stanford . edu/resources-collections/a-virtual-crash-course-in-design-thinking
- http://www.creativeconfidence.com/tools
祝您构建自己的直观、用户友好的仪表板好运!
嘿伙计们,快速个人更新!我们在 Locale.ai 推出了我们的产品,希望您能试用并分享您的反馈。报名链接此处为。
如何像老板一样做出数据驱动的决策
原文:https://towardsdatascience.com/how-to-make-data-driven-decisions-like-a-boss-fffc088470da?source=collection_archive---------5-----------------------
理论上,理论和实践没有区别。但实际上是有的。― 瑜伽熊
决策可能很难。你每天需要做的决定多得令人不知所措。研究表明,我们一天中做的决定越多,我们做决定的能力就越差(决策疲劳)。有时你会做出非常非常艰难的决定,在这种疲劳中,你很难选择一个选项而不是另一个选项,即使使用了你所拥有的所有数据。
决策理论是逻辑、博弈论和概率的结合,旨在将决策形式化为您更容易解决的结构化问题。很好,但是你为什么要在乎?因为它提供了许多通用的框架和工具,您可以使用它们来确保决策方法的一致性。你越善于使用这些框架和工具,你就越能更好地做决策——你就越不容易被淹没和成为决策疲劳的受害者。
决策理论是一个很大的领域,所以我们将只涵盖你需要开始的基础知识。具体来说,我们将涵盖:
- 什么是决策?(决策模型)
- 可能的结果是什么?(期望值分析)
- 结构化决策(决策树)
- 模拟决策(蒙特卡洛模拟)
让我们从建模决策开始,使它们更容易评估。
离群值 监控您的业务数据,并在发生意外变化时通知您。我们帮助营销/发展&产品团队从他们的业务数据中获取更多价值。 今天安排试玩。
- Outlier 是 Strata+Hadoop World 2017 观众奖得主。
决策模型
可视化决策
什么是决策?简而言之,这是在许多不同的选项中做出选择,每一个选项都会导致某种预期的结果。你可以用我称之为决策模型的东西来想象一个决策,它实际上只是流程图。您可能在过去使用过流程图来捕捉流程,这正是我们决策过程所需要的!例如,下面是一个非常通用的决策模型:
A simple flow diagram describing decisions
决策模型帮助您获取做出最佳决策所需的所有信息:
- 列举所有可能的选择。
- 理解每个选择的结果。
- 对最终结果的理解。
决策模型使得这三者都很容易可视化。例如,假设我们需要决定是否应该为我们的销售团队再雇用一名销售人员。如果我们雇佣销售人员,短期内会花费一些钱(工资),但可能会在 6 个月内带来更多的销售。该决定可能如下所示:
A hypothetical flow evaluating the hire of a sales person
如你所见,决策模型只是一种简单的方法,通过强迫你写下来来确保你理解所有的选择和决策结果。你不会对每个决定都这样做,但对最重要的决定来说,这是一个重要的工具。
接下来,我们将讨论当存在不确定性时如何理解结果,这在现实生活中几乎总是如此!
期望值分析
了解成果
在昨天讨论决策模型时,我们分解了如何考虑决策和可供选择的选项。在许多方面,比你的选择更重要的是这些选择的最终结果。
例如,让我们说你正试图决定你是否应该买一张彩票。我们可以对决策建模如下:
Flow diagram for expected value analysis
看那里的决定,显然我们应该买票!然而,我们没有捕捉到的是,获胜的概率并不是 100%。事实上,对于大多数彩票来说,中奖的概率非常小。让我们假设赢得彩票的概率是 1 . 75 亿分之一(强力球的典型概率)。那么,我们如何衡量这一潜在结果的价值呢?
期望值是评估受概率(也称为随机变量)影响的结果的一种方式。期望值允许您在量化事件时考虑事件的可能性,并将其与其他不同概率的事件进行比较。
要计算期望值,您需要将事件的概率乘以事件的值。在这种情况下,我们将中奖金额(1 亿美元)乘以中奖概率:
简单来说,中奖的回报是巨大的,但中奖的机会是微乎其微的,所以买票的预期价值只有 57 美分。
现在,我们可以在决策模型中使用它来明确决策:
现在选择很清楚,我们不买票并节省 1 美元比买票损失 0.43 美元要好得多!这就是期望值的力量,在比较选项时,它们允许我们快速而容易地计算概率。
当然,大多数决策将包括许多不同的概率。接下来,我们将讨论多阶段决策,其中一个决策可能导致许多其他决策,并将我们迄今为止讨论的内容汇集在一起,以做出一些实际的决策!
决策树
在生活或商业中,很少有决策是独立的。一个决定导致更多的决定,反过来又导致更多的决定。当你做决定的时候,如果你要做一个最优的选择,你需要考虑那些后来的决定。
决策树是我们之前讨论的决策模型的扩展,它允许您理解相互关联的决策的关系和最终结果。决策模型和决策树的唯一区别在于,在决策树中,一个选择的结果可以是另一个决策!
举个例子,让我们回顾一下我们是否要雇佣一名销售人员的决定。不要把它想成是雇用销售人员的决定,让我们把它想成是现在还是以后雇用销售人员的决定。这将决策变成一棵树,如下图所示:
Taking the decision tree to the next level with dependencies
如果我们现在决定不雇佣销售人员,我们可以选择以后雇佣他们。这既有成本也有收益,现在您已经绘制了决策树,可以开始分析了。
这个简单的例子体现了现实世界决策的许多特征,以及您在构建决策树时应该考虑的事情:
- 仅仅因为有大量的决策,就可能只有少量的可能结果。在许多真实世界的情况下,任何决策都只有几种可能的结果,这可以大大简化你的过程。通过从首选结果开始回溯,您可以确定最有可能帮助您实现目标的决策路径。
- 根据我们在第一个决定中所做的选择,其他各种决定要么可用,要么丢失。这是做决定时要考虑的一个重要因素,因为一些选择可能会在未来保留更多选择,从而增加你未来决策的灵活性。
- 你的决策树的许多分支也将引入不确定性,因为一些决策和结果将依赖于某些概率。在这里,使用期望值是非常强大的,因为您可以计算一个选择的期望值,即使真实的结果是删除了许多决策!
你的决策树越大,就越难处理它可能引入的越来越多的概率。明天,我们将回顾一个有用的工具,来减少这种复杂性,并使这些决定变得稍微容易一些。
模拟决策
赌博可以变好
即使使用了我们本周讨论的工具,仍然很难做出艰难的决定。如果你的决策树有很多不确定性,或者你的期望值很难预测,即使这些框架也没什么帮助。
好消息是你可以作弊!在你真正做出决定之前,你可以把同一个决定重复上千次,看看结果如何。这个过程被称为蒙特卡罗模拟,它使用软件来模拟多次做出相同的决定,并使用您提供的概率来确定结果。通过研究这么多测试的结果,你可以了解最有可能的结果,并将其作为你决策的一部分。
例如,让我们回到是否购买彩票的决定。请记住,门票价格为 1 美元,中奖奖金为 1 亿美元,但中奖几率仅为 1.75 亿分之一。如果同一张彩票也有 1/20 的机会赢得 5 美元,1/50 的机会赢得 20 美元呢?那我们怎么做决定呢?
对于这个简单的例子,我们可以直接计算期望值,但为了好玩,我进行了蒙特卡洛模拟,结果如下:
我进行了 500 次模拟,其中 467 次我一无所获,5 次 15 美元,20 次 16 美元,可悲的是,1 亿美元 0 次。平均结果是赢得 0.79 美元——仍然低于票价!
然而,考虑 500 次模拟中涉及的概率可能不足以得到一致的结果。与任何概率模拟一样,运行的次数越多,结果的分布就越能反映真实的概率,所以要尽可能多运行几次。我再次运行同样的模拟 500 次,得到的平均值是 0.54 美元,这是非常不同的!这凸显了这种方法的危险,因为结果中有太多的可变性,所以你需要使用结果作为指导,而不是事实。
回顾:我们已经讲述了决策理论的基础,包括如何可视化决策,以确保您捕捉所有可能的选择和结果(决策模型和树),并考虑结果中的不确定性(期望值)。我希望这能给你一个开始,用一种系统的方式来处理你的决定,这将帮助你做出更好的决定!
离群值 监控您的业务数据,并在发生意外变化时通知您。我们帮助营销/发展&产品团队从他们的业务数据中获取更多价值。 今天安排试玩。
- Outlier 是 Strata+Hadoop World 2017 观众奖得主。
如何利用上下文土匪做出数据驱动的决策
原文:https://towardsdatascience.com/how-to-make-data-driven-decisions-with-contextual-bandits-the-case-for-bayesian-inference-cc2f2913ebec?source=collection_archive---------8-----------------------
贝叶斯推理的案例
2018 年,几乎每个行业都面临着巨大的压力,要做出数据驱动的决策。在强大的机器学习算法时代,这不仅仅是一个好主意;这是生存。
但是我们如何应用“预测分析”来做决策呢?那么,如果我们可以预测客户流失或转换的可能性呢?一个好的预测真的能给你的组织带来价值吗?
数据科学是时候成长了
监督学习创造了奇迹,但它从根本上说是有限的。决策的直接优化——最广泛地说,强化学习(RL)领域— 对于大联盟来说已经足够成熟了。
我们已经看到了 RL 的一些巨大突破,但是一个可靠的通用解决方案仍然缺乏。
众所周知并且有效解决了的是 RL 的特殊情况,称为上下文强盗问题。
什么是语境土匪?很像 RL;你有一系列的决定要做,任务是学习最佳的选择来优化一些奖励。唯一的区别是上下文强盗公式没有状态。
约翰·舒尔曼是 OpenAI 深度增强现实领域的领先研究人员,他在2017 年的演讲中对任何希望在实际环境中应用深度增强现实的人的直接建议是将其作为一个上下文相关的土匪问题。
“通常你可以把(你的问题)近似为一个没有国家的背景强盗问题。对背景强盗问题有了更好的理论理解。”约翰·舒尔曼,OpenAI
深度语境强盗来了——而且效果很好
也许被关于深度学习的头条新闻掩盖了,背景强盗问题研究的最新进展在很大程度上被忽视了。deep RL 中有一些令人惊讶的结果,它是优秀的 clickbait,但在野外,我们数据科学家有职业责任关注相关研究。
尤为重要的是 2018 谷歌大脑论文深度贝叶斯土匪对决。这篇论文算不上创新,但却是一个里程碑。作者们看了一些最近最有希望的解决方案,并在各种不同的任务上对它们进行了比较。
主要外卖?这些方法中的大多数都能很好地解决各种各样的问题。
探索与利用
所有的 RL 问题都面临一个基本的悖论:我们是尝试新事物来寻找更好的解决方案,还是简单地重复我们知道行之有效的行为?这个经典难题被称为探索/利用权衡。
大多数关于上下文强盗的研究都集中在用一般的方法解决这个难题上。每个问题都不一样;我们能创造出一种在任何地方都适用的算法吗?
一个简单有效的解决方案被称为ε贪婪策略。ε是超参数;当ε= 0.01 时,我们利用 99%的时间,探索 1%的时间。这个简单有效。我们只需要选择一个运行良好的 epsilon,我们可以找到一个解决方案,同时最大限度地提高性能。
epsilon-greedy 的问题是它需要调优。我们是从高ε开始,然后随着时间降低它吗?我们要选择一个 epsilon 并把它留下吗?
在这里摆弄的真正风险是,当我们调整时,由于次优决策,真正的钱正在损失。
汤普森取样
真正的解决方案是找到一种算法,自我调节探索利用问题。事实证明,贝叶斯公式给了我们一个可靠的方法来做到这一点。
汤普森取样是一个可以追溯到 1933 年的想法。它给了我们一种聪明探索的方式。汤普森抽样的主要思想是:
"当有疑问时:探索!"—迈克尔·克莱尔,试图解释汤普森抽样。
使用 Thompson 采样可以很容易地解决更简单的情况,即所谓的多臂强盗问题。
这个想法很简单:利用我们对每个行动背后的预期回报分布的先验理解,让我们抽取样本并选择 argmax 作为我们选择的行动。这就是汤普森抽样政策:既贪婪又随机。
这个策略的结果是深远的:当我们的模型对一个决定有信心时,它会不断重复那个行为。当它不太自信时,它会探索可能性更高的其他选项。
对多臂土匪很管用。棘手的部分是将它应用到上下文案例中。
汤普森抽样的贝叶斯回归
当我们将背景引入多臂强盗问题时,我们不再能够简单地学习每一个动作的奖励分配。我们需要根据一组特性或者一个环境来决定这个分布。
贝叶斯线性回归为我们提供了一个很好的方法。贝叶斯线性回归不是简单地拟合一个线性回归模型,而是允许我们在预测中加入不确定性。更具体地说,它允许我们将某些结果(比如说,我们的报酬)的预期分布取决于一些特征。这种分布可以从采样,打开了在上下文土匪情况下汤普森采样的大门。
Bayesian regression reward optimization — Maximum Reward is the known-best policy, and cumulative reward is the trained policy. Bayesian LR + Thompson Sampling implicitly optimizes explore-exploit behavior. (Each decision and timestep is the x-axis.)
非线性函数呢?
线性模型是有效的,但是限于给定独立特征的近似线性信号。如果我们需要对非线性函数建模呢?
一种完全有效的方法是从我们的原始特征中设计出一组大致独立的特征。你能做到的。
但是特征工程是老派的。2018 年,我们有神经网络来为我们做这件事。
进入深度学习
2018 年上下文土匪摊牌论文探索了贝叶斯线性回归解决方案的巧妙适应。简称为神经线性算法,谷歌大脑研究人员应用神经网络来学习一组特征,以馈入贝叶斯线性回归模型。
结果呢?一个在各种任务中表现卓越的模型。这很简单,计算效率高,而且证据就在布丁里。
“…根据对深度网络最后一层提供的表示进行贝叶斯线性回归来做出决策,提供了一种可靠且易于调整的方法。”——Riquelme 等人,谷歌大脑
你可以应用最先进的研究
这种算法是普遍适用的,本质上是简单的。研究人员甚至开源了他们的代码供公众使用。
但直接应用前沿研究可能会令人生畏。
我在 Launchpad 主持一个数据科学家培训会议。AI ,作为培养数据科学人才进入该领域的国际活动的一部分。
教授梯度推进和随机森林很容易,因为开源软件非常用户友好。初露头角的数据科学家只需要导入一些类,她就可以立即开始实验。
因此,当我站在一群受训的数据科学家面前,向他们讲授深层贝叶斯语境强盗时,他们迫不及待地想要尝试。
唯一的问题?他们不能直接从 scitkit-learn 导入。唯一可用的选择,从零开始手工编码实现,当你有最后期限来满足时,并不总是可行的。
太空盗匪诞生
我决定把谷歌大脑的开源代码打包,这样我的学员就可以使用它了。
我没有野心;我从 Tensorflow 开源代码中取出最简单的模型(贝叶斯线性)和最好的模型(神经线性),优化后用于规模化使用,上传到 PyPI 。
它只需要一个名字。我有很多想法,但我对天文学的热爱和“太空强盗”这个愚蠢的名字吸引了我。 太空盗匪 诞生。
目前的版本是 v0.0.9,是一个 alpha 版本,但是它可以工作。一个玩具问题表明,图书馆的模型可以在线学习,也可以从历史数据中学习。
这是 Google Brain 的贝叶斯方法的另一个优势:学习不需要直接获取决策政策。这意味着来自任意活动的记录可以用于优化。
Space Bandits is able to learn a “soft” decision boundary with Thompson sampling and a Bayesian linear model — only observing rewards given actions
关于报酬设计的一个注记
“我已经开始把 deep RL 想象成一个恶魔,它故意曲解你的奖励,并积极地寻找最懒惰的可能的局部最优解。”— Alex Irpan ,Google,深度强化学习还没起作用
亚历克斯可能说得最好,但任何有机器学习经验的人都不应该对此感到惊讶。
RL 算法,包括上下文土匪,不容易推广。他们只有在别无选择时才会这么做。
在受监督的环境中,这种想法表现为过度适应。当简单地记忆训练数据是一种选择时,为什么要一般化呢?
同样的问题在 RL 里就不那么清楚了。当你的模型找到优化奖励的方法时,是否过度拟合?只有当你的奖励函数有缺陷的时候才会这样。
这一块应该不难,不要想多了。在现实生活中,奖励(通常)是金钱。如果你的模型找到了优化回报的“窍门”,只要回报是利润,你就应该高兴。
A Space Bandits Neural Linear model learns nonlinear decision boundaries. Thompson sampling encourages more exploration closer to “true” decision boundaries, and optimal choices in regions with higher certainty.
部署深度贝叶斯上下文盗匪模型
你没有借口了。该算法已被证明在实践中对广泛的问题有效。您可以通过基于前沿研究的决策优化给同事留下深刻印象。也许最好的是,你可以 pip 安装一个 python 包为你做所有的艰苦工作。
你还在等什么?
如何让设备变得智能
原文:https://towardsdatascience.com/how-to-make-devices-smart-10dff00c2a8c?source=collection_archive---------6-----------------------
使用机器学习算法,亚马逊 Alexa 和 DeviceHive
在一切都趋于智能的时代,仍然有设备和遗留设备保持不变。他们很好地履行了自己的职责,但如果他们能做得更多呢?
我们考虑了一个简单的电梯连接到由新功能和服务支持的互联网的场景。人们每天都使用电梯。所以,让我们让它更安全、更智能、更可靠。
应用支持
开发新功能总是要花相当多的时间。但是如果你可以通过安装一个新的应用程序把它添加到你的设备上呢?
我们将集成服务打包到 Canonical 的 snap 包中。其架构允许任何开发者创建自己的品牌应用商店,并上传快照进行分发。
一旦设备支持应用程序,它就成为 snap 生态系统的一部分,为该平台提供了大量解决方案。这项技术允许在不改变设备主要功能的情况下向设备添加新的服务。整个演示旨在展示如何轻松完成。
更安全的
为了提高安全性,让电梯更安全,我们使用了机器学习算法。这些算法允许我们跟踪攻击行为、武器、衣服、情绪、健康状况等。
Ski-mask detection
通常入侵者在实施抢劫/袭击前会试图隐藏自己的脸。我们以这一事实为出发点,训练机器学习算法来识别人们身上的面具,但不对仅仅持有面具的人做出反应。
一旦检测到滑雪面罩,系统就会触发警报,发送短信,并呼叫安全官员。此外,理论上它可以锁定电梯门,直到警察到来。
来自电梯摄像机的视频流使用 TensorFlow 模型进行分析,该模型被训练来识别滑雪面罩。在肯定识别的情况下,发生警报。
- 对 RestComm 电话服务器的 API 调用被调用——这触发了预先配置的动作(比如发送文本消息或打电话);在调用时,它也可以提供一些信息。
- 警报声响起——为了让这成为可能,我们用定制的 DeviceHive 固件刷新了 ESP8266 芯片。
Solution architecture
聪明的
在上一篇文章中,我们讨论了如何将任何基于 Linux 的设备转变为 Amazon Echo 设备。我们在这里也实现了它,为了演示实际的解决方案,我们将 Alexa 与 DeviceHive 集成在一起。
[## 如何将 Alexa 添加到树莓派中
或者任何 Linux 设备
medium.com](https://medium.com/iotforall/how-to-add-alexa-to-a-raspberry-pi-6cedfe15662e)
我们使用 DeviceHive 云解决方案来控制一个 LED 灯条,用于语音命令的可视化演示。主要的挑战是开发一个可以在多种电路板上运行的语音激活解决方案。Ubuntu 为这些主板提供支持,包括 x64 和 ARM 主板,如 Raspberry Pi。
对 Alexa 的每个请求都必须由人类语言触发。因此,我们添加了一个本地语音识别算法来检测' Alexa '关键字。一旦它听到这个关键词,它就会记录声音,直到语音停止,并将其发送到亚马逊 Alexa 云服务。
为了获得广泛的硬件支持,我们开发了一个基于 Amazon Alexa API 的包。然后,我们将这个应用程序打包到一个规范的 snap 包中,以提供简单的设置和事务性更新。
我们使用 WS2812B LED 灯条作为视觉设备,通过 DeviceHive 固件连接到 ESP8266 芯片。该固件提供与 DeviceHive 服务器的连接,还支持 LED 灯条设备,并提供控制它们的命令。因此,我们完全可以通过从 Alexa Skills 应用程序发送不同的命令来控制 LED 灯条。
Alexa integration architecture diagram
我们创建了一个语音控制电梯系统,led 灯带上的灯代表建筑楼层。
此外,该系统被编程为播放关于在所选楼层可以找到的位置的广告。它还可以回答诸如“这栋楼里最好的餐厅在哪里?”
可靠的
我们通过其 RESTful API 将演示与 Salesforce 物联网云集成,以记录使用统计数据并分析收集的数据。这可用于构建预测性/预防性维护解决方案。
利益
我们开发了一个与现代服务和技术相集成的复杂解决方案,为用户和客户增加了新的价值:
- 语音识别使语音命令成为物联网生态系统的一部分。该解决方案使用基于 web 的服务,这使得它可以扩展到更大的系统,并且可以轻松地从一个硬件平台迁移到另一个硬件平台。
- 利用机器学习方法可以提高安全性。
- 云技术使公司更具创新性,更快地开发商业模式,并在定制解决方案中使用众所周知的高质量产品。
- Salesforce 物联网云集成可记录和分析使用数据。
- 作为应用程序添加新特性和功能的能力。
技术
技术栈包括:亚马逊 Web 服务、亚马逊 Alexa、DeviceHive 云服务、DeviceHive 固件、Linux、Python、C、Ubuntu Snaps、Snapcraft、Java、JavaScript、TensorFlow、Restcomm。
由 DataArt 物联网负责人伊洛宁撰写。
如何让 Goodreads.com 跻身 400 强?
原文:https://towardsdatascience.com/how-to-make-goodreads-com-top-400-list-8e3a26e509bf?source=collection_archive---------2-----------------------
我是一个书虫。我一个月读 3-4 本书(仅限非小说类书籍), 80%的句子以“我在某处读到过……”开头
我对书籍的兴趣促使我创办了全球最大的读者和书籍推荐网站goodreads.com,亚马逊于 2013 年收购了该网站。
这个项目的目标是分析 goodreads.com 的前 400 本书的共同特征,并根据书评预测一本书的成功。
刮 Goodreads.com
我从“有史以来最好的书”列表中刮出了这些书。为了获取我的分析所需的所有信息,我必须抓取三个不同的页面模板。
下面是一个页面模板的例子,它列出了我的分析所需的一些元素(用橙色突出显示)。
分析
我将我的分析分为三个部分,每个部分由一组问题引导:
- 写作:
- 哪种流派在 400 强榜单中最具代表性?
- 有最佳页数吗?
- 出版
- 出版年份重要吗?
- 预测
- 评论的数量是成功的预测因素吗?
- 哪些词,在哪个频率下,可以预测成功?
前两部分的目的是在作者写书之前为他/她提供指导,而最后一部分的目的是预测一本书出版后的成功。
我使用 Python 进行分析,使用 Python 的散景包进行可视化。
1-写作
哪种流派在 400 强榜单中最具代表性?
小说、经典和奇幻是 400 强榜单中最具代表性的类型。请注意,由于一本书可能被归类到多个流派下,因此这些流派之间可能会有重叠。
上面的直方图提出了几个问题:
- 各流派在 400 强榜单中的分布情况如何?比如,小说类书籍主要在前 100 名还是在前 400 名榜单的底部?
- 如果一本书的体裁是小说、幻想或经典,它更有可能进入前 400 名吗?如果这三种类型在 Goodreads.com 有很高的代表性呢?人们应该预料到一个流派进入前 400 名的可能性与该流派在所有 Goodreads.com 书籍中的流行程度成正比。
400 强榜单内各流派分布
下面的热图回答了第一个问题:它按排名类别显示了前 16 个流派的分布(例如,前 100、前 200 等。).颜色描述了书籍的数量。
一个有趣的发现:文学体裁不属于三大体裁。然而,它在 100 强名单中占有很高的比例。
引入另一个数据集:我们的控制列表
如上所述,如果我们不能把它和最差的 400 个榜单进行比较,那么前 400 个榜单就毫无意义。可惜没有这样的名单…
在没有“史上最差书籍”榜单的情况下,我随机抽取了 1 万本关于 goodreads.com 的书籍,作为我的“对照”榜单。
免责声明:我后来才知道,goodreads.com 上的确有最差书籍排行榜。
下面的直方图比较了控制列表和最佳书籍列表之间的流派分布。
一个有趣的发现:虽然经典作品在 goodreads.com 上的代表性不足,但它在 400 强榜单中却占有很高的比例,这表明读者更有可能投票支持经典作品。
另一方面,小说、幻想和青少年体裁在 goodreads.com 书籍中占有相当大的比例。它们进入前 400 名的可能性高于像古典文学这样代表性不足的流派。
有最佳页数吗?
简而言之,答案是否定的。如下图所示,对照名单和前 400 名名单之间也有类似的趋势。页面数量不是成功的预测因素。
2-发布
出版年份有关系吗?
对于这一部分,我查看了每年排名前 400 的书籍的分布,并调查了一个可能的关联:
- 每年出版的平均页数
- 每年售出的图书总数
总计数与平均页数(按出版年份)
排名前 400 的书籍中有很大一部分是在 2003 年至 2006 年间出版的。尽管平均出版页数的一些峰值与排名前 400 的书籍数量的峰值一致,但这两个变量之间没有相关性。
有趣的是,控制列表(下图)的趋势与前 400 名列表的趋势不同。尽管很多书是在 2010 年后出版的,但它们在 400 强榜单中的代表性不足。
对于那些对细节感兴趣的人来说,下面是 2003 年、2004 年和 2006 年十大畅销书的名单。
售出图书数量与前 400 名图书数量之比
每年前 400 的图书分布和当年的图书销量有关联吗?如下图所示,情况似乎并非如此。
然而,数据集是有偏差的(如下所述),所以对结果不能全信。
我使用了来自美国人口普查局的数据集,该数据集提供了每年售出的图书数量。该数据集仅包括 1992 年至 2014 年美国书店销售的图书数量。换句话说:
- 样本量有限(23 年)。
- 网上销售没有被计算在内,我们预计这意味着本世纪的大量图书销售没有被计算在内。不幸的是,由于没有网上图书销售的官方记录,实际数字无法核实。
- 它没有报告售出的独特书籍的数量,这意味着我们一年可以卖出 1000 本全部是哈利波特系列的书。
3-预测
评论的数量是成功的预测因素吗?
评论的数量是排名前 400 的指标。我们看到一个明显的趋势,前 100 本书比前 100-200 本书收到的评论更多,而前 100-200 本书收到的评论又比前 200-300 本书多,等等。
是否应该得出评论越多越好的结论?或者说评论数量和评分之间的关系是一条最好和最差的书获得更多评论的倒钟形曲线?毕竟,一本普通的书不会引发强烈的情绪(无论是积极的还是消极的);只有最好的和最差的才知道。
控制列表没有证实倒钟形曲线的假设。相反,五星的书得到的评论比四星的书少,而一两星的书几乎得不到任何评论。
哪些词,在哪个频率下,可以预测成功?
我使用 AFINN 字典开始对评论专栏进行情感分析。
AFINN 方法的输出是一个浮动变量(AFINN 分数),如果大于零,则表示正面情绪,小于零,则表示负面情绪。刻度范围从-5 到+5。
首先测试控制列表上的 AFINN 方法
需要高水平的粒度来识别哪些单词可以预测一本书在 Top 400 列表中的排名。在将 AFINN 方法应用于前 400 名名单之前,我在一个更广泛的名单上检查了它的可靠性,即控制名单。
AFINN 词典似乎是一个很好的成功预测器(如上图所示)。下一步是看它是否能帮助区分前 100 名和前 300 名的书…
不幸的是,如下图所示, AFINN 词典的粒度不足以预测“有史以来最好的书”名单中的排名(根据定义,所有的书都是成功的)。
下面的散点图提供了与箱线图相同的见解,只是我使用了连续变量(得分)而不是离散变量(排名类别),并通过颜色区分了排名类别。
在上面的散点图中,分数没有下降到-1.5 以下,这是有意义的,因为我们不希望“有史以来最好的”书籍有很高的负面情绪分数(即-3,-4 或-5)。然而仍然有少量的预测误差;一些排名前 100 的书有负面情绪得分。
我的情感分析需要一些微调:
- 我没有查看书评的总得分,而是分析了书评中的每个单词,以了解的 AFINN 得分和频率如何预测一本书的排名。
- 我还查看了另一个库, Vader 词典,它提供了更多的粒度。
观察单个的正面和负面词汇,以及它们如何影响一本书的排名
如下图所示,一个单词的出现频率和 goodreads 平均得分之间没有相关性。
有趣的是,一些 AFINN 得分较低的词在成功书籍的评论中出现得相当频繁。这是因为 AFINN 词典是用 unigram 特征构建的,其中忽略了语法甚至单词的顺序,这意味着句子“我不喜欢”中的“喜欢”将被正面解释。
查看另一个库——Vader lexicon——以帮助更好地预测分数
我对 AFINN 词典不太满意,决定看看 Vader 词典。它的算法似乎更精细,因为它输出 4 类情感:
- 阴性:阴性
- neu:中性
- 位置:正
- 复合:复合(即,通过将评论中每个词的化合价分数相加来计算的总分数,根据 Vader 规则进行调整,然后标准化为-1(最极端的负面)和+1(最极端的正面)之间的分数)
我使用配对图来分析以下各项之间的相关性:
- Vader 正分数(pos)和 goodreads 分数
- 维德负分数(neg)和古德里德分数
- 维德复合得分(复合)和古德里德得分
pearson's r 值为 0.5 或更高的图表显示相关性,为绿色。Pearson r 的范围从-1 到 1,其中:
- r 为-1 表示变量之间完全负线性关系,
- r 为 0 表示变量之间没有线性关系,以及
- r 为 1 表示变量之间完全正线性关系。
Vader 中性和阳性分数之间存在负相关,这是有意义的:分数毕竟来自同一个词典。然而,Vader 正负分数之间没有相关性,这令人惊讶。
最后,我感兴趣的变量之间没有关联(例如,Vader 正、负、复合分数与 goodreads 分数)。
会有,应该会有,可能会有
我的分析表明,经典类的书更有可能进入前 400 名榜单。
虽然排名前 400 位的书籍大多平均有 300 页,但没有明确的模式表明出版年份或页数。
评论的数量是成功的一个很好的预测指标:越多越好。然而,这无助于区分四星和五星的书籍。也就是说,五星级的书可能比四星级的书卖得好,这不是我分析的一部分。
最后,情感分析部分在预测一本书在排行榜前 400 名中的成功是不成功的。AFINN 和 Vader 方法帮助预测了 goodreads.com 获得高分的可能性。然而一旦一本书进入前 400 名榜单,并且需要高水平的粒度来将其与其他成功的书籍区分开来并预测其排名,这两种方法就不可靠了。
如果给我更多的时间和数据,下面是我可以、将要和应该完成的分析的快速列表:
- 更多关于用户写评论的数据:我希望这些评论包括写评论的人的人口统计数据,以回答一些问题,例如:来自特定城市、特定年龄组或性别的人在评论时更无情吗?
- 使用单文法与 n 文法:情感分析是用单文法特征构建的。这意味着整个文本被分割成单个单词,使单词脱离了上下文,从而降低了检测评论情感的准确性。n-gram 越长(n 越高),需要处理的上下文就越多。我希望我已经知道了基于 n-grams 的词典或者 R 中的 Syuzhet 包,这将我带到下一个要点。
- 使用 R :总的来说,我觉得对于情感分析部分,R 可能是一种更好的语言。事实上,我开始用 R 编写代码,并为这一部分用 Python 翻译了我的代码。
- 每本书的评论数量有限:我只抓取了一本书的前 30 篇评论,这确实限制了情感分析,并且可能会引入一些偏见(尽管第一篇评论是随机显示的,并且没有按照新近度排序)。
- 更多见解:我希望我的分析更有成果,尤其是情感分析部分。
如何使用 gif 制作有趣的 Tableau 仪表盘
原文:https://towardsdatascience.com/how-to-make-interesting-tableau-dashboards-using-gifs-182eab5fe354?source=collection_archive---------6-----------------------
可视化可以对我们如何感知不同的事物产生巨大的影响,尤其是数据。将数据以结构化方式排列成表格格式远比非结构化数据好得多;以图表的形式用图形表示数据也比以表格的形式表示数据要好。随着可视化程度的提高,我们对数据及其呈现环境的理解也在提高。
我们举个例子,自己验证一下上面的说法。
试着阅读上面的表格并理解它的意思。
好吧,我来帮你。
因此,该表提供了人均互联网和移动电话使用量的逐年变化趋势。总体趋势是积极的,互联网和移动电话的人均使用量逐年增加。然而,为了更进一步理解这些年来的相对增长,我们必须在分析之前做一些计算并得到一些数字。然而,如果我们以一种更好的视觉格式呈现上述数字,比如说条形图或折线图,那么它可能有助于我们的目的。我们将能够看到这些数字多年来的总体变化,并进一步看到这些年来的相对增长。让我们看看下面的图表,看看有什么不同。
柱状图为我们提供了人均手机使用数据,而折线图为我们提供了人均互联网使用数据。我可以毫不避讳地说,上图的视觉吸引力比表格中的简单数字好无数倍。上图为我们提供了多方面的见解,其中一些观点如下:
- 人均移动电话使用量和人均互联网使用量的总体增长
- 2009 年至 2012 年期间,人均移动电话使用率增长不多;尽管人均互联网使用率几乎一直呈线性增长
- 人均互联网使用率的增长率远远低于人均移动电话使用率的增长率——这可以从每年的折线图与条形图的位置推断出来。2000 年,线很接近杠顶;而在 2012 年,这条线几乎位于酒吧的中心。
从上面的图表中可以得出许多其他的见解。这就是数据可视化的力量。它的互动性和动态性越强,就越有利于用户从中获得洞察力。
上面两个图表是在 Tableau 中创建的,Tableau 是市场上最先进的数据可视化工具之一。Tableau 帮助我们用简单的拖放方法创建强大的交互式可视化。使用 Tableau,我们将尝试通过将静态图表转换为更具交互性的形式,即通过将它们转换为 gif,将我们的可视化提升到一个新的水平。通过一个简单的播放按钮,用户可以看到所有的条形图和折线图根据时间线移动。我们将举几个例子,了解如何在 Tableau 中创建 gif。
我们将使用标准的 Tableau World Indicators 内置仪表盘作为示例。首先,我们将使用互联网和手机的人均使用数据,并了解如何创建一个 GIF,看看它提供的影响。我们在图 1 和图 2 中看到了两种不同形式的相同数据。要以 GIF 格式显示图表,首先按照标准说明以所需格式创建图表。标准图表可能如下图所示。
现在,要将标准图像转换成 GIF,你所要做的就是将 Year 字段移动到左上角的 Pages shelf。完成后,你会在右边看到一个页面卡片,上面有一个“播放”按钮。只要点击播放按钮,你就可以制作一个 GIF 了。请看下图中的 pages 卡片。
因为,Tableau 的当前版本不提供下载 gif 的灵活性,你将不得不使用第三方工具来录制屏幕。
现在让我们将上面的图片分成三个部分(在不同的年份点),并了解整个 GIF 是如何演变的。
上图是 GIF 的第一步(年份= 2000)。让我们看看 2005 年的第二步。
接下来,我们来看一下 Year = 2011 时的图像。
当你按下播放按钮时,图像会一次移动一年。使用右侧的 pages 卡,您可以选择不同的选项,如过渡速度和特定年份。如果您点击“显示历史”旁边的小箭头,将出现如下所示的弹出窗口。使用这个弹出窗口,你可以改变颜色,褪色的酒吧等。
此外,如果您不想在图表随年份移动时保留以前的条形,您可以选择“突出显示”选项,而不是“全部”,结果如下所示。
现在,让我们看另一个例子,看看 gif 如何有助于在区域地图上提供一段时间内的指标趋势。我们将使用 Tableau 的内置仪表板——世界指标,但这一次我们将使用不同的数据集——健康指标。
我们将首先为非洲不同国家的平均出生率创建一个静态区域热图。图表如下所示:
现在,将 Year 字段移动到 Pages 窗格,点击 play 按钮,观察不同国家的颜色变化。你会观察到,不同国家的颜色随着平均出生率的变化而变化。阿尔及利亚的情况明显不同。
在 2000 年,阿尔及利亚是金黄色的,这表明平均出生率接近 1.1%(看上图中的梯度比例);而在 2012 年,阿尔及利亚的颜色变成了浅绿色,表明平均出生率逐年提高。
然后,Tableau 表可以移动到任何 Tableau 仪表板,并在演示文稿中使用。这是 Tableau 提供的一个非常强大的功能,它可以帮助我们以一种非常吸引人和交互的方式呈现数据。
尽管 gif 在创建吸引人的可视化效果方面非常有用,但在使用时还是要小心。它们应该主要用于当你想要呈现一段时间内的变化趋势时,例如:一个国家多年来的 GDP 变化。另一个例子是,如果您想要比较两个或更多国家/地区之间的一个指标,并查看多年来的变化趋势。我们可以在更多的领域看到这种 gif 的应用,你能想到吗?在 Tableau 中创建 gif 时,我们很高兴听到您的观点和经验。
作者简介:
本文由 Perceptive Analytics 供稿。Saneesh Veetil、Sinna Muthiah Meiyappan 和 Chaitanya Sagar 对本文有贡献。
Perceptive Analytics 为电子商务、零售、医疗保健和制药行业提供 Tableau 咨询、数据分析、商业智能和报告服务。我们的客户包括美国和印度的财富 500 强和纽约证券交易所上市公司。
如何利用机器学习来理解社交媒体
原文:https://towardsdatascience.com/how-to-make-sense-of-social-media-using-machine-learning-8a3db1506d03?source=collection_archive---------3-----------------------
社交媒体最初是为个人提供的环境,但品牌很快注意到了个人互动的机会。目前,顶级社交媒体平台也是相关的营销渠道,有时会完全取代电视广告或传单等传统选择。每秒钟,脸书上出现 330 万条新帖子,推特上出现近 50 万条。如果你想记录你的品牌被提及的所有次数,该怎么办?
为了利用社交媒体的力量,创建一个营销计划并相应地分配预算。品牌希望对自己行为的影响、客户的偏好甚至负面评价有清晰的认识。然而,鉴于信息量如此之大,手动操作是不可能的。
克服信息过载
进入机器学习(ML) ,这是一系列算法,使计算机能够识别数据中的模式,并将其分类成簇。这非常适合非结构化数据,因为社交媒体帖子不遵循任何规则。它通常是文本、图像、声音和视频的混合。
这种分析的结果可以给出关于所选用户的可操作的见解。自然语言处理提供了关于社交媒体帖子作者的年龄、性别、位置和偏好的有价值的线索。来自 NLP API 的数据可以帮助基于真实世界的数据而不是统计或有根据的猜测进行客户细分。
为什么要使用机器学习
在社交媒体分析中部署 ML 有几个原因,这是由大数据的 3 比(数量、速度和多样性)决定的。
可攀登的
社交媒体活动的庞大数量需要自动化工具来处理处理活动。即使有专门的社交媒体团队,也不可能跟踪所有渠道和品牌提及。相反,网络抓取工具收集所有可能与品牌相关的帖子,将它们放入一个数据湖中,然后输入到算法中,将它们分割成相关的部分。
文本与语境
搜集阶段依赖于一个关键词,如品牌或产品名称。对于专门的活动,可以使用标签进行搜索,但这仅仅是开始。与为结构化数据设计的简单统计工具相比,使用大数据我们可以实现更多。这些只是统计关键词在对话中出现的次数,并增加更多的过滤级别,如地理位置和性别,而现在我们可以创建图表来显示现有的链接并给出意义。更重要的是不仅要分析焦点词(文本),还要分析它所处的语境。通过 NLP 支持的情感分析,公司可以了解客户对产品的满意程度,以及与积极和消极感觉相关的词语。这类似于人类通过语调相互理解的方式,或者朋友通过即时消息交流的方式。
相关性和权威性
在社交媒体中,识别影响者非常重要,无论他们是个人还是机构,因为他们是网络中的中心节点,与他们建立合作关系可以创造出促进营销的病毒式内容。
斯坦福的一篇文章解释了如何追溯链接,查看每条信息的来源,甚至使用图表跟踪最初帖子的变化。最相关的条目有许多引用,而具有最高权限的内容生成者始终如一地创建相关帖子。
说他们的语言
就在十年前,市场调研是通过调查和焦点小组完成的。机器学习不仅提高了答案的准确性、速度和可靠性,而且它可以结合不同组的预先存在的信息来回答新问题。这有助于在初始测试后缩小选择范围或创建新的行动路线,从而迭代地做出决定。
通过查看社交媒体洞察,营销人员可以了解客户使用产品的新方式,他们购买产品时的感受,甚至新的商业机会。
以前的客户细分技术无法创建用户角色,但现在通过聚类,公司不仅可以发现他们的典型客户是二十出头、受过大学教育和生态学家,而且他们还可以生成听起来像她自己的帖子,达到非常个性化的目标营销水平。
说到语言,由于机器学习算法只是使用了聚类,因此可以用来分析不同的语言,而无需修改底层命令。此外,这些工具非常适合社交媒体分析,在这种环境下,用户有时会混合使用多种语言,尤其是在非英语母语的情况下。例如,文本可以用用户的母语书写,有表情符号,这是通用和流行的英语标签,创建与全球用户联系的更丰富的信息。
电脑不理解
重要的是要明白,计算机处理信息的方式与人类不同,尽管这是人工智能的最终目标。目前,
他们只是创造规则并应用它们,给人以推理的印象。然而,这并不是反对使用机器学习的理由,只是提醒一个程序的能力和一种设定现实预期的方法。
这种限制的可能缺点是,在校准阶段,分析社交媒体帖子需要特别注意,特别是关于元通信,如表情符号和使用讽刺和挖苦。虽然人类可以更容易地发现这一点,但机器可能会将这样的帖子分类到错误的垃圾箱中,并忽略不满意的客户。
从用户到影响者
在社交媒体出现之前,能够影响他人的人数是有限的,通常由电影明星、运动员、医生或专家等高调、高知名度的个人组成。内容创作也仅限于出版社和媒体渠道。通过智能手机民主化,我们每个人都是内容创造者,成为影响者的门槛降低了,因此任何人都可以创建帐户并发表自己的想法。在这种去监管化的环境下,企业不再能控制自己的形象。现在,他们只能观看表演,并确定导致积极市场刺激的行为来鼓励他们。
如何使用 parfit 使 SGD 分类器的性能与逻辑回归一样好
原文:https://towardsdatascience.com/how-to-make-sgd-classifier-perform-as-well-as-logistic-regression-using-parfit-cc10bca2d3c4?source=collection_archive---------1-----------------------
对于大型数据集,使用 parfit 优化的超参数,我们可以在 LogisticRegression 所用时间的第三分之一内获得与 SGDClassifier 相当的性能。
什么是 SGD 量词?
SGD 分类器使用随机梯度下降实现正则化的线性模型。
那么,什么是随机梯度下降?
随机梯度下降在改变权重时仅考虑 1 个随机点,不同于考虑整个训练数据的梯度下降。因此,在处理大型数据集时,随机梯度下降比梯度下降快得多。Quora 上有一个很好的回答,详细解释了梯度下降和随机梯度下降的区别。
我们已经有了逻辑回归,为什么还要关心 SGD 分类器?
默认情况下,逻辑回归使用梯度下降,因此在较大的数据集上使用 SGD 分类器会更好。你可能想要使用 SGD 分类器的另一个原因是,如果你不能在 RAM 中保存数据集,逻辑回归,在其普通的 sklearn 形式下,将不会工作,但 SGD 仍然会工作。
我们如何让 SGD 分类器表现得和逻辑回归一样好?
默认情况下,SGD 分类器的性能不如逻辑回归。它需要一些超参数调整来完成。
使用par fit:进行超参数优化
Parfit 是一个新的软件包,由我的同事和旧金山大学的 MSAN 学生 Jason Carpenter 编写。该软件包(使用并行处理)允许用户在模型上执行详尽的网格搜索,这使用户能够灵活地指定验证集、评分标准,并可以选择在输入的超参数网格上绘制分数。你可以在媒体上的这篇文章中读到更多关于这个包的信息。
您可能希望使用 parfit 的一个关键原因是,它为您提供了在单独的验证集上评估指标的灵活性,而不像 GridSearchCV 那样使用交叉验证。交叉验证并不是在所有情况下都是好主意。您可能不想使用交叉验证的一个原因是当数据中有时间成分时。例如,在这种情况下,您可能希望使用最近 20%的观察值创建一个验证集。fast.ai 的 Rachel Thomas 写了一篇非常好的博文,关于如何(以及为什么)创建一个好的验证集。
在本文中,我将把验证集的性能作为“模型表现如何”的指标。这里的度量是' sklearn.metrics.roc_auc_score '。
Logistic 回归拟合:
在这里,我们将使用带有“l2”惩罚的逻辑回归作为我们的基准。对于逻辑回归,我们将调整 1 个超参数 c。
C = 1/λ,其中λ是正则化参数。C 值越小,正则化越强。由于 parfit 并行拟合模型,所以我们可以为 C 提供大范围的参数,而不必太担心寻找最佳模型的开销。
如何使用 parfit:
bestFit 接受以下参数:
- 模型:在我们的例子中,输入模型是逻辑回归。请注意,该函数只接受类作为输入,而不接受它的对象。
- paramGrid :运行模型的超参数的参数网格对象
- X_train , y_train , X_val , y_val :训练和验证集
- 公制:评估你的模型的公制。
- bestScore :返回通过“max”时的最高分。
它不仅返回最佳模型及其最佳分数,还返回所有模型及其所有分数。
Hyper Parameter Optimisation for Logistic Regression using parfit
输出:
后勤部门花了大约 26 分钟找到最佳模型。这么长的持续时间是为什么使用 SGDClassifier 而不是 LogisticRegression 是个好主意的主要原因之一。对于 C = 0.0001,我们得到的最好的 roc_auc_score 是 0.712。
让我们看看我们的最佳模型 roc_curve:
Code to plot ROC curve
AUC curve for Logistic Regression’s best model
SGD 分类器上的部分匹配:
与逻辑回归相同,我们将对 SGD 分类器使用“l2”惩罚。这里需要注意的一个重要的超参数是 n_iter。sklearn 文档中的“n_iter”定义为
通过训练数据的次数(也称为时期)。”
sklearn 中的 n_iter 默认为 None。我们在这里将其设置为足够大的值(1000)。最近添加的 n_iter 的一个替代参数是 max_iter。同样的建议应该适用于 max_iter。
阿尔法超参数有双重用途。它既是一个正则化参数,也是默认时间表下的初始学习率。这意味着,除了正则化逻辑回归系数之外,模型的输出还取决于α和拟合程序执行的历元数(n_iter)之间的相互作用。具体来说,当α变得非常小时,必须增加 n_iter 来补偿缓慢的学习速率。这就是为什么当搜索大范围的α时,指定足够大的 n_iter 更安全(但是更慢),例如 1000。
Hyper Parameter Optimisation for SGD Classifier using parfit
输出:
请注意,SGD 分类器只花了 8 分钟就找到了最佳模型,而逻辑回归花了 26 分钟才找到最佳模型。此外,我们在 n_iter = 1000 时运行 SGD 分类器。SGD 分类器在α = 0.1 时给出最佳模型。最佳模型的 roc_auc_score 为 0.712,这与我们从逻辑回归得到的结果相似,精确到小数点后第三位。
现在,让我们看看最佳模型上的 AUC 曲线。
AUC curve for SGD Classifier’s best model
我们可以看到 AUC 曲线类似于我们在逻辑回归中观察到的曲线。
摘要
就像这样,通过使用 parfit 进行超参数优化,我们能够找到一个 SGD 分类器,它的性能与逻辑回归一样好,但只需要三分之一的时间就可以找到最佳模型。
对于足够大的数据集,最好实现 SGD 分类器而不是 Logistic 分类器,以便在更短的时间内产生相似的结果。
生物: 我目前正在旧金山大学攻读分析(数据科学)硕士学位,并在 Manifold.ai 实习。此前,我曾在惠普企业云部门担任软件存储工程师。
领英:https://www.linkedin.com/in/vpatlolla/
如何让技术资料简洁美观
原文:https://towardsdatascience.com/how-to-make-technical-data-simple-and-beautiful-4724038bb74d?source=collection_archive---------10-----------------------
数据是任何演示或报告的支撑。它提供了真实的片断,这些片断共同构成了一幅精确的图像。
没有数据,营销人员会根据假设和推测来创建他们的活动,而不是确切地知道他们的客户想要什么。更不用说工程师从一开始就只会建造危险的建筑。甚至消费者也需要数据来知道如何相应地使用他们的新产品。
尽管技术数据无处不在,但它仍被视为冰冷而平淡。以下是一些关于如何通过内容和设计简单而漂亮地传达技术信息的技巧。
相关:关于如何通过数据可视化吸引注意力的专家提示
技术数据需要可视化升级
有四种学习方式,分别是视觉、听觉、读写和动觉。这意味着我们都以不同的方式理解信息。人们通常有一种主导风格,但他们也需要其他三种风格来吸收新内容的复杂图像。
可视化数据可以结合几乎所有的学习风格,以获得一个全面的方案。T2 1998 年的一项研究发现,人对图像的记忆能力比文字更强。这是因为人们应该一次读一行。另一方面,只要看一眼就能理解图像。作家需要整个页面来描述一个场景。然而,一幅图像可以同时包含所有细节。
视觉数据不仅仅是图像。它是关于找到一种方法来连接两个在文本中看起来不相关的元素。一旦信息被清楚地分类,视觉元素就可以进来表示内容。一旦他们每个人都有了自己的形式,与他们一起工作就很容易了。
数据解释器可以创建真实的场景,并使用地理定位来找到两个看似陌生的元素之间的联系。地理方位将使你能够找到两点之间的联系,就像人们在几何学中所做的那样。文本不能给你一个空间的解释,数据可以隐藏在背景后面。
例如,架构师使用数据可视化为每个真实元素分配一个可视化的解释。他们画了一条线来代替“墙”这个词。他们没有用“窗户”这个词,而是在墙上画了第二条线。每个元素在设计领域都有自己的诠释,并成为一种符号。
通过将复杂的图像简化为简单的线和点,建筑师可以很容易地发现某些联系。因此,建筑师的工作不仅需要设计技能,还需要广泛的解决问题的能力,我们都知道建筑师的收入。
如何交流技术信息
人们通过同化来学习。我们把一个完全未知的概念放在它在这个世界上的正确位置。我们需要理解它的意义以及它与我们已知的事物和概念的关系。例如,当我们学习一门新的语言时,我们将每个单词与现实中的物体或现象同化。
我们的课程越简洁明了,我们学得就越快。我们的人性要求我们在未知背后找到一个逻辑或理由。因此,史前时代把打雷或下雨之类的奇怪自然现象的原因,找到了神的力量。我们都知道这些影响的背后是科学,我们也知道了它与天气的联系。
因此,为了创建易于理解的技术数据表示,我们需要结构。新信息必须符合逻辑。如果没有这个组织,就只会有一些随机的数字和短语。
为了简化,您的技术数据需要组织。人们需要一个逻辑的开头、中间和结尾来理解和掌握新的概念。因此,任何清晰的视觉数据都应该尊重五个逻辑结构之一:
- 位置;
- 字母表;
- 年表;
- 类别;
- 等级制度。
如果没有这些结构,将会有大量紧凑的无限数据。这个世界运行在复杂的规则和方程上,一个人的一生不足以掌握所有的规则和方程。
但是人们不需要知道所有的事情。通过在逻辑结构中构建一个精确的主题,你向他们感兴趣的主题传递了意义。
如何化简单为有效
简单性和结构本身不足以支持有效的视觉数据。他们需要一个共同目标的帮助。报告的目的是什么?数据为什么问题提供了解决方案?因此,任何技术内容都应致力于以下一个或几个功能:
- 以可视结构显示数据;
- 把平面设计仅仅作为达到目的的一种手段,以及理解数据实质的一种手段;
- 避免在普通文本中不恰当的短语组合后出现的曲解;当你使用数据而不是文本时,你回避了可能导致多种解释的单词的上下文性质;
- 提供大量与图形主题相关的重要数字;
- 为大型数据集提供清晰度;
- 使用户能够在图形或数字元素之间进行比较;
- 激活几个层次的概述,从一个领域的广泛描述到深入的部分;
- 尊重以下简明目的之一:
- 装饰(用令人愉快的设计来组织数据,使其更容易消化);
- 制表(将数据分类成表格形式);
- 描述(概述数据的背景和来源)或探索(根据收集的数据形成分析的行为;
- 将统计数据和文字描述整合到图形中。
数据可视化的类型
既然我们已经介绍了简单性在交流技术信息中的重要性,那么是时候将数据可视化集成到设计精美的图形中了。有许多方法可以赋予数据视觉元素和意义。下面是一个复杂的可视化类型列表,可以用逻辑和精确的图形来组织数据。
1.1D/线性
这种一维结构可以由我们所知道的物品清单来定义。虽然这是最常用的视觉类型,但它确实缺乏深度。观看者无法执行逻辑关联,其项目之间的联系隐藏在多维主体的缺失之后。
2.2D /平面
这是一种综合类型的图形,依赖于地理解释。它的主要目的是综合描述真实区域(如国家、城市或社区)的数据。有几种方法可以释放平面可视化的潜力,甚至可以产生交互式地图。
- 这是一张以颜色或图案分类的地图。它的目标是提供一个总体视图,显示某个特征(如人口密度)在不同地区之间的差异。
- 图表:这种类型的地图用土地面积或距离代替某些变量。例如,可以改变地区的大小,以显示与其他地区相比有多少公民。
- 点分布图:这种地图表示使用点来表示特定区域内特定因素的存在。一个点代表数据记录的现象的位置。因此,观察某一代理人在整个国家的影响是很方便的。
- 比例符号图:与图表样式一样,比例符号的任务是在地图上的精确位置显示现象的正确表示。这些符号可以根据它们的数量改变它们的大小。
- 等高线图:这是一种用不同函数的曲线来表示数据的地图。
3.三维/立体
这种类型的可视化为提供了广泛的方法来表示三维记录的数据,三维是长度、宽度和高度。
这是完美的可视化风格,使观众能够理解空间中的联系。很容易找到独特的角度和数据元素的组合,否则在 2D 或 1D 的表现中看不到。
4.暂时的
- 时间线:时间线尊重年代规律。数据的逻辑发展尊重时间线,使观众能够理解数据的演变。
- 时间序列:这是一个可视化列表,其中数据元素在时间或空间维度上接收它们自己的点。通过将它们之间的点按时间顺序连接起来,你就获得了一个描绘某个领域起伏的图形。基于时间序列,专家有足够的数据来准确预测该领域的未来。
- 甘特图:其实就是一个关注项目进度的条形图。有一个预先确定的时间段,在该时间段中,由图形表示的工作活动出现在它们发生的精确时刻。甘特图用于记录项目管理的有效性以及其他有用的功能。
- 流图:流图有一个中轴,通常是时间线。在这个轴上流动的是某个领域中记录的一些变量。最受欢迎的流图之一是《纽约时报》制作的,用来比较电影票房收入。
- 桑基图:数据用箭头表示,根据其影响程度改变大小。
- 冲积图:这种可视化技术以时间轴为轴,用水平线根据一个系统的发展历史来改变它们的轨迹。
5.多维的
最复杂的数据可视化提供了最全面的解决方案。很难在多维领域保持相关性。然而,最终结果将把复杂的结构变成简单的图形。
从这里开始,将它们之间的元素联系起来并理解它们如何作为一个整体一起工作就变得非常简单了。
- 饼状图:这是一个圆形,有多个切片。每一段代表一个变量。该图简化了几个数值因子之间的定量比例。
- 直方图:描述了概率分布的估计。有两个轴通常代表时间和数量。
- 标签云:用于突出关键词元数据。这些单位随机显示。它们的规模越大,就越重要。
- 泡泡云:酷似标签云。然而,在这种情况下,每个术语都有自己的气泡。但它们的重要性仍由泡沫的大小来衡量。
- 树形图:遵循层次规则。每个元素接收自己的矩形,矩形可以有自己的更小的矩形作为子分支。在树状图中,创作者可以使用颜色来标记几个分支之间的某种相似之处。矩形的大小象征着它的尺寸或相对于其他的成功。
- 散点图:使用笛卡儿坐标,根据变量的值将它们放置在正确的位置。最终结果看起来像是代表数据的图形表示的点的集合。
- 面积图:表示定量数据的逼真图形。使用这种类型,您可以比较几个折线图来衡量它们之间的差异。商务人士用它们来记录某个领域最流行的趋势。
- 热图:这是一个矩阵,其中的变量有特定的颜色。颜色编码很精确。例如,红色表示高活动,而黄色表示较低的记录。
- 平行坐标:这种可视化技术采用高维几何,通过依赖于几条垂直线的平行线来表示数据。人们将它们用于空中交通管制、数据挖掘、计算机视觉和优化。
总而言之,技术数据的有效性取决于简单性和可视化表示。简单意味着以某种方式组织数据,使其服务于一个单一的目标。
美感和视觉表现对鼓励观众理解数字和其他记录所描述的系统至关重要。一旦用户接受了某个主题的教育,数据就完全达到了目的。
轮到你了
如果你想知道是否需要高级专业知识——甚至是数据科学学位——来创建这些类型的数据可视化,也有大量针对初学者的易于使用的信息设计工具可以帮助你在几分钟内创建交互式图表、图形和信息图。
您可以尝试的一个选项是 Visme,这是一个一体化的可视化内容创建工具。 点击这里 免费试用。
如果你有任何关于如何向非技术受众传达技术信息的信息设计技巧和建议,请在下面的评论区给我们留言。
本帖 原版 最早出现在 Visme 的 视觉学习中心 。
如何用 Python 制作 Windows 10 吐司通知
原文:https://towardsdatascience.com/how-to-make-windows-10-toast-notifications-with-python-fb3c27ae45b9?source=collection_archive---------1-----------------------
Sample Toast Notification
Python!!那是什么?
Python 是一门漂亮的编程语言。它拥有你可能需要的一切。它有一个易于使用的软件包管理器,可以帮助我们建立网络应用程序,桌面应用程序,网络应用程序和基于数据的应用程序。
如果你正在寻找 2018 年学习 Python 的理由,请阅读这篇 Stack Overflow 博文。
[## Python |堆栈溢出的惊人增长
我们最近探讨了富裕国家(被世界银行定义为高收入的国家)如何倾向于访问不同的…
stackoverflow.blog](https://stackoverflow.blog/2017/09/06/incredible-growth-python/)
win10toast
作为一名机器学习工程师,我在开源社区消费了很多才华横溢的人构建的包。我很高兴能回馈给这个了不起的社区一个小包裹。
在我的工作中,我习惯于运行需要几个小时的神经网络,所以我会一边看电影一边等它结束。我想有一种简单的方法在脚本运行结束时得到通知,而不是打断我的电影并检查进度。所以我创建了一个包来给我发送 Toast 通知😃
如何入门?
该软件包已经在 Pypi 中发布,可以很容易地与 pip 一起安装。
pip install win10toast
一旦安装完成,你可以尝试一个简单的通知。
from win10toast import ToastNotifier
toaster = ToastNotifier()
toaster.show_toast("Sample Notification","Python is awesome!!!")
有关高级使用说明,请参考文档。
如果你喜欢这个包,或者对扩展的源代码感兴趣,请访问我的 GitHub 库。
[## jithurjacob/Windows-10-Toast-通知
显示 Windows 10 Toast 通知的 Python 库
github.com](https://github.com/jithurjacob/Windows-10-Toast-Notifications)
记得给本帖一些👏如果你喜欢的话。关注我了解更多内容:)
我以前的帖子
[## 如何用 VS 代码和 Jupyter 笔记本改善你的工作流程
增强您的数据科学工作流程。Jupyter 笔记本+ VS 代码=💘
towardsdatascience.com](/how-to-improve-your-workflow-with-vs-code-and-jupyter-notebook-f96777f8f1bd)
如何让你的软件开发体验…没有痛苦…
原文:https://towardsdatascience.com/how-to-make-your-software-development-experience-painless-2591ebcc69b6?source=collection_archive---------4-----------------------
在各种形式的组织中工作(从面向大型软件开发的小型初创企业到学术实验室),我注意到人们倾向于让自己的生活比实际需要的更艰难。因此,我将利用这篇文章来解释如何让你的软件开发经历不那么痛苦。
作业调度器
如果它简单、乏味且令人讨厌地重复,那么你可以自动完成它。如果你是一个 Unix 用户(像大多数程序员一样…我讨厌 Windows…),你将可以访问 cron 作业。cron 软件实用程序是一个基于时间的作业调度程序,在类似 Unix 的计算机操作系统中。建立和维护软件环境的人使用 cron 来安排作业在固定的时间、日期或间隔定期运行。学习 Unix crontab 命令。
自动化测试
如果你一个人或者团队中的多个成员独立地开发同一个代码库,很可能有人会在代码中引入某种形式的 bug。通常的程序是花几个小时追踪整个代码中的微小错误,同时以胎儿的姿势哭泣(如果你还没有哭够,那么你可能不是一个真正的程序员)。就自动化测试而言,有很多选择。单元测试非常普遍。JUnit 面向 Java 用户,而非 ittest 库面向 Python 开发者。然而,在将代码投入生产之前,有些人可能会忘记在团队中正确运行单元测试。为了避免这样的灾难,自动化测试是很重要的。虽然你可以使用 crontab 来运行自动化测试,但我会推荐使用更专业的工具,比如 Jenkins 。Jenkins 允许你安排测试,从版本控制库中挑选特定的分支,如果有问题就发邮件给你,如果你想用沙箱保护你的测试,甚至可以旋转容器图像。
集装箱
沙盒是编码的重要组成部分。这可能涉及到为各种应用程序提供不同的环境。它可以简单地将生产环境复制到开发中。这甚至意味着拥有多个不同软件版本的生产环境,以迎合更大的客户群。如果您想到的最佳方法是使用带有虚拟箱的虚拟机,我相信您已经注意到,您要么需要使用完全相同的虚拟机进行多轮测试(糟糕的 DevOps 卫生状况),要么为每次测试重新创建一个干净的虚拟机(根据您的需要,这可能需要近一个小时)。一种更简单的替代方法是在虚拟机上使用容器而不是完整容器。容器只是一个 unix 进程或线程,看起来、闻起来和感觉起来都像 VM。它的优势在于低功耗和低内存消耗(这意味着你可以在几分钟内随意启动或关闭它)。流行的容器化技术包括 Docker (如果你希望只使用一个容器)或 Kubernetes (如果你喜欢为多服务器工作流编排多个容器)。
版本控制
想象一下将您的代码推向生产。而且很管用!完美。没有抱怨。随着时间的推移,您会不断添加新功能并开发它。然而,这些特性中的一个给你的代码引入了一个错误,严重扰乱了生产应用程序。您希望您的许多单元测试中的一个能够发现它。然而,仅仅因为一些东西通过了你所有的测试并不意味着它没有错误。这只是意味着它通过了当前编写的所有测试。因为这是生产级代码,所以你没有时间去调试。时间就是金钱,你有愤怒的客户。回到代码工作的时候不是很简单吗???这就是版本控制的用武之地。在敏捷风格的代码开发中,产品在一个不确定的时间周期内保持零碎的开发。对于这样的应用程序,某种形式的版本控制将非常有用。我个人喜欢 Git ,但是 SVN 用户依然存在。Git 可以在所有形式的平台上工作,如 GitHub 、 GitLab 和 BitBucket (每种平台都有自己独特的优缺点)。如果你已经熟悉了 git,可以考虑在 Atlassian 上学习更高级的 Git 教程。我推荐查找的一个高级特性是 Git 子模块,在这里您可以存储多个独立 Git 存储库的特定提交散列,以确保您可以访问一组稳定的依赖项。
设计模式和代码味道
当人们开始自学程序员时,很多时候我们想的是创建一个简单的应用程序。成功了,完美!下一个受害者!然而,一旦我们试图扩大规模,各种各样的随机问题就开始出现。糟糕的编码实践,缺乏文档和紧密耦合。为了开发一个更加灵活、可重用和可维护的代码库,理解设计模式和代码味道的基础是很重要的。我强烈推荐阅读的一本书是由 Erich Gamma、Richard Helm、Ralph Johnson 和 John Vlissides 撰写的《设计模式:可重用面向对象软件的元素》。SourceMaking.com 的也是一个非常好的参考网站,提供了 Python、Java 和 c 语言的例子。我已经在以前的博客中提到过一些例子:软件开发设计原则
评论
最后,防止软件开发过程失控的最显而易见的方法是拥有某种程度的文档。虽然拥有多个包含每个微小功能的详细文档并随着代码的发展而更新它们的 pdf 文件是很好的,但这很可能是不实际的。在高节奏和高压力的软件开发环境中,即使是最自律的开发人员也会面临某种程度的不幸。记录代码的最佳方式是在脚本中添加注释。当人们开发脚本时,评论会发生变化。不同的编程语言有特殊的注释规则。作为一名 Python 程序员,我非常依赖 PEP8 。评论很重要的一点是,它应该是显而易见的。如果你需要大量的注释来解释一段简单的代码,很可能你的代码写得不好(一种很常见的代码味道)。把评论当成讲笑话。如果需要解释,不会让任何人发笑。
如何掌握新技能
原文:https://towardsdatascience.com/how-to-master-new-skills-656d42d0e09c?source=collection_archive---------4-----------------------
为什么尽量避免电子表格是学习数据科学的最佳方式
学习新技能的最好方法是用它来解决问题。在我以前作为一名航空航天工程学生的生活中,我花了几个小时在 Excel 中编写复杂的公式来做从设计机翼到计算航天器再入角度的一切事情。经过几个小时的努力,我会用平淡无奇的 Excel 图表来展示结果,这些图表主宰了许多幻灯片。确信这不是一个最佳的工作流程,我决定学习 Python,一种常见的编码语言,仅仅是为了避免把我醒着的时间都花在 Excel 上。
在 Al Sweigart 的 的帮助下,用 Python 自动处理枯燥的东西,我学会了足够多的语言,将我在 Excel 中花费的时间减少了 90%。我没有记忆基础知识,而是专注于有效地解决航空航天问题。我很快就完成了作业,当我在课堂上展示 Python 图形时,有人问我使用了哪种神奇的技术。甚至不用尝试,我就获得了一个能把混乱的电子表格转换成清晰图像的人的名声。
The difference between data (left) and knowledge (right)
具有讽刺意味的是,只有当我达到我所在领域的顶峰时,我才决定转向数据科学。当我在美国国家航空航天局做航天工程师实习生时,我周围都是这个国家最聪明的人。然而,这些人的才华受到了严重限制,因为他们最终花了大部分时间钻研现代数据的诅咒:Excel 电子表格。这些人致力于扩展人类对宇宙的知识,实际上是在电子表格中做火箭科学!就在那一刻,我意识到,作为一名帮助人们从数据中理解事物的数据科学家,我会比作为一名航空航天工程师产生更大的影响。
尽管我当时正在执行一项任务,将一颗卫星送入太空(近地小行星侦察任务),但我对这项工作感到沮丧,因为它主要涉及数小时的翻阅数字。通常,这些电子表格已经使用多年,人们相信这些数字,尽管不能理解这些公式。我最终放弃了试图理解电子表格,而是开始使用我所知道的一点点 Python 来自动计算。基于我在学校试图逃离电子表格时获得的有限知识,并使用我从 Stack Overflow 复制和粘贴的一些代码,我能够提高我的工作效率和质量。
Not pictured: the millions of lines of Excel behind the ISS
我试探性地向同事们提到有一种更好的方法来完成他们的工作。尽管他们持怀疑态度,但他们已经看到了我的成果,并愿意倾听。在向他们展示了一些我编写简单代码来代替手工编辑电子表格的例子后,他们开始接受这个想法。起初,我为他们编写脚本,这是一项我很乐意承担的任务,因为几行代码就大大减少了我的工作量,但最终他们能够开始编写自己的脚本了。(虽然我确实说服了他们写代码,但几乎都是用 Matlab 甚至 Fortran。有些事情你就是改变不了!)在几周的时间里,我从一名卑微的实习生变成了我所在部门的首席数据顾问。
这个真实的应用程序说明了两个关键点:
- 新技能是从解决问题中学习的,而不是从理论中学习的
- 不需要多少知识就能达到有用的结果
与传统的教育模式相反,我们首先开发应用,然后形成理论,而不是相反。内燃机是历史上最有影响力的技术之一,它是由工程师而不是理论家几十年的修补成果。只有在发动机被发明出来之后,发动机工作原理的理论才变得清晰起来。我学习编程和数据科学不是靠记忆数据结构和公式的细节,而是靠写代码解决问题。一路上,我学到了很多本可以在书上读到的基础知识。现在当我学习一种新的机器学习方法时,我会直接将其用于真实数据,而不是研究公式。通过实际操作而不是在页面上看到模型,我可以更好地理解模型是如何工作的。
Theory vs Application. Only one actually flies.
人们通常认为他们需要成为某个领域的专家才能做出贡献。这使得他们甚至无法开始学习一项新技术,因为他们认为这项技术需要几年才能派上用场。我在 NASA 的经历为这种误解提供了一个反例。数量有限的正确知识,在这种情况下是数据科学,可能非常有影响力。我没有等到对编码了如指掌,而是应用了我所知道的,并取得了有益的结果。
罗马不是一天建成的,这句老话意味着大型项目需要多年的努力。然而,这里有一个更重要的信息:一个完整的城市不需要在有用之前就建成。即使只有几户人家,一个城市仍然有它的用途。半个罗马比没有罗马好,正如有些知识比没有知识好。每一栋新房子或每一个额外的知识都会在积极的反馈循环中激发更多的成长。关键是在学习过程中不断解决问题,而不是等到掌握了一门学科才使用!
这些想法应该鼓励任何想学习新技能或转换领域的人。如果你认为学习一门技术需要太长时间,或者你对基础感到厌烦,不要担心!简单的东西是乏味的,你最好通过解决问题和学习过程中的基本原理来学习。此外,意识到你可以用有限的正确知识获得有用的结果。解决一些基本问题,并在复杂性增加时根据需要提高技能。
因为我们已经使用了一个陈词滥调,这里有另一个:“种树的最佳时间是 20 年前。第二好的时间是今天。”不要后悔在学校时没有学习编程——或者任何技能——而是想想你将来想知道什么!找出你(或你的同事)需要解决的问题,并开始学习。现在回过头来看,我的数据科学之路并不是一帆风顺的规划出来的,而是通过解决问题,稳步获取工具而进化出来的。现在是自学的最好时机,扩展你技能的最好方法就是开始解决问题!
一如既往,我欢迎反馈和建设性的批评。可以通过 Twitter @koehrsen_will 找到我。
我要感谢 Taylor Koehrsen (PharmD no less!)对她的编辑帮助。
如何从 tf.contrib.learn 估计器过渡到核心 Tensorflow tf?估计量
原文:https://towardsdatascience.com/how-to-move-from-tf-contrib-learn-estimator-to-core-tensorflow-tf-estimator-af07b2d21f34?source=collection_archive---------4-----------------------
我有一堆使用“原始”估计器 API 构建的机器学习模型,在 tf.contrib.learn 中的那个。在 Tensorflow 1.2 中,它的一部分被移到了 core,在 Tensorflow 1.4 中,我需要的剩余部分最终到达了 core Tensorflow。所以,是时候开始迁移到核心评估 API 了。
当 Tensorflow 团队将代码从 contrib 转移到 core 时,他们趁机清理 API。另一种方法是在 contrib 接受之前对所有东西进行昂贵的代码审查,而不仅仅是证明有用的东西。那会减缓创新…
在任何情况下,如果我们发现 contrib 中的一个实验包是有用的,我们应该准备好花一点时间和精力将我们的代码迁移到核心。这通常不仅仅是将包名(例如)从 tf.contrib.learn.Estimator 改为 tf。估计者又收工了。
让我们分四个部分来看看从 tf.contrib.learn 到 tf.estimator 的过程:
- 如果您正在将一个固定的估计器(例如,tf.contrib.learn.DNNClassifier)移动到 tf。估计器. dnn 分类器)
- 如果您正在移动一个定制的估计器(例如,如果您做了一些类似于我在文本卷积或时间序列预测上的博文,因此需要从 tf.contrib.Estimator(model_fn)更改为 tf。估计器(model_fn)。
- 如何从代码中移除 tf.contrib.learn.Experiment 和 learn_runner?
- 对您的云 ML 引擎脚本的更改
没有变化就不可能有进步
哇哦。变化真大!考虑到这里的巨大变化,你将来使用 contrib 中的类的可能性有多大?你是否认为你宁愿等待尘埃落定,并在它们进入核心后使用它们?
当然,如果你想要一个稳定的 API,你应该坚持使用核心 Tensorflow 中的东西。但是我想你和我一样,相信萧伯纳的格言:不改变就不可能进步,你决定使用 contrib,因为你知道你将来必须做出一些改变。
不过,一切都完了,是时候付出代价了!让我们一个一个地看一下这些变化。
如何移动固定估计量
对固定估计量的更改主要涉及特性列。走这几行:
import tensorflow.contrib.layers as layers
is_male = layers.sparse_column_with_keys('is_male',
keys=['True', 'False'])
age = layers.real_valued_column('mother_age')b_age = layers.bucketized_column(age, np.arange(15,45,1).tolist())crossed = layers.crossed_column([b_age, ...], 200)
embed = layers.embedding_column(crossed, 3)
功能列包和方法名称已更改。以下是替代产品的外观:
import tensorflow.feature_column as fc
is_male = fc.categorical_column_with_vocabulary_list('is_male',
['True', 'False'])
age = fc.numeric_column('mother_age')b_age = fc.bucketized_column(age,
boundaries=np.arange(15,45,1).tolist())crossed = fc.crossed_column([b_age, ...],
hash_bucket_size=200)
embed = fc.embedding_column(crossed, 3)
在不熟悉这些术语的情况下,关于特性列的 Tensorflow 文档非常有用。改变后的方法名(分类的代替了稀疏的,数字的代替了实数的)得到了字段的特征而不是它们的表示,新的 API 有了更多的灵活性。
一旦您有了特性列,创建评估器仍然是一样的。例如,改变,
tf.contrib.learn.DNNLinearCombinedRegressor
收件人:
tf.estimator.DNNLinearCombinedRegressor
你完了。
但是,您还应该收紧您的服务输入 fn(例如,Tensorflow 将使用这个函数来解析接收到的 JSON,并将其输入到您的模型中)。你可能会有这样的想法:
return tf.contrib.learn.utils.input_fn_utils.InputFnOps(
features,
None,
feature_placeholders)
现在,它将变成:
return tf.estimator.export.ServingInputReceiver(
features,
feature_placeholders)
实际上,没有人需要的第二个参数已经去了它的休息处。
如何移动自定义评估员
在向核心迁移的过程中,定制估算器变得更加灵活和强大。
在您的自定义估算器中,您曾经有一个这样定义的模型函数:
def cnn_model(features, target, mode):
# stuff ... return tf.contrib.learn.ModelFnOps(
mode=mode,
predictions=predictions_dict,
loss=loss,
train_op=train_op)
这现在变成了:
def cnn_model(features, labels, mode, params):
# STUFF if mode == tf.estimator.ModeKeys.TRAIN or mode == tf.estimator.ModeKeys.EVAL:
eval_metrics = {'acc': tf.metrics.accuracy(tf.argmax(logits,1), labels)}
else:
eval_metrics = None return tf.estimator.EstimatorSpec(
mode=mode,
predictions=predictions_dict,
loss=loss,
train_op=train_op,
eval_metric_ops=eval_metrics,
export_outputs={'classes': tf.estimator.export.PredictOutput(predictions_dict)}
)
让我们打开它。这些是关键的变化:
- 请注意,您现在获得了一个额外的参数。您可以使用它向您的模型传递一个额外的字典。当您使用 Cloud ML 引擎并且想要超参数调整模型参数时,这非常方便。稍后会有更多内容。
- 以前是 TF . contrib . learn . mode keys . train 之类的模式现在是 tf.estimator.ModeKeys.TRAIN,这里没什么大不了的。它们映射到的数字还是一样的,所以即使你不改变代码,也不会发生什么疯狂的事情。但是最好清理一下,用核心包。
- 你现在返回一个 tf.estimator.EstimatorSpec,而不是返回一个 tf.contrib.learn.ModelFnOps,但是 EstimatorSpec 有一些新的功能。具体来说,您现在可以指定要评估的指标列表。EstimatorSpec 还提供了导出预测字典的不同部分的能力。
模型函数本身被传递到一个估计器中,如下所示:
tf.contrib.learn.Estimator(model_fn=cnn_model,
model_dir=output_dir),
相反,您将像这样传递它:
training_config=tf.estimator.RunConfig(save_checkpoints_steps=1000)
hparams = parser.parse_args().__dict__tf.estimator.Estimator(model_fn=cnn_model,
model_dir=output_dir,
config=training_config,
params=hparams),
请注意,我将命令行参数作为 params 传入。这就是上面 cnn_model()的第四个参数——在 Cloud ML Engine 中,这个传递允许我对模型进行超参数调整。
摆脱实验
实验,原谅我的双关语,是一个失败的实验。替换核心 Tensorflow 功能是使用 tf。Estimator.train_and_evaluate()。
您可能有这样的设置:
def make_experiment_fn(output_dir):
def experiment_fn(output_dir):
wide, deep = get_wide_deep()
return tf.contrib.learn.Experiment(
estimator,
train_input_fn=read_dataset('train'),
eval_input_fn=read_dataset('eval'),
eval_metrics={
'rmse': tf.contrib.learn.MetricSpec(
metric_fn=metrics.streaming_root_mean_squared_error
)
},
train_input_fn=read_dataset('train', PATTERN),
eval_input_fn=read_dataset('eval', PATTERN),
export_strategies=[saved_model_export_utils.make_export_strategy(
serving_input_fn,
default_output_alternative_key=None,
exports_to_keep=1
)],
train_steps=TRAIN_STEPS
)
return experiment_fnlearn_runner.run(make_experiment_fn, output_dir)
这将变成:
train_spec=tf.estimator.TrainSpec(
input_fn=read_dataset('train', PATTERN),
max_steps=TRAIN_STEPS)
exporter = tf.estimator.LatestExporter('exporter',serving_input_fn)
eval_spec=tf.estimator.EvalSpec(
input_fn=read_dataset('eval', PATTERN),
steps=None,
exporters=exporter)
tf.estimator.train_and_evaluate(estimator, train_spec, eval_spec)
本质上,以前调用 learn_runner.run()的地方,现在调用 TF . estimator . train _ and _ evaluate()。您向它传递了 estimator 和 train_spec,它们封装了有关您的训练数据的细节,还传递了 eval_spec,它们对您的评估数据执行相同的操作。导出发生在评估期间,因此您在那里指定您的导出器(LatestExporter 或 FinalExporter)。
请注意,在实验中,您曾经指定 eval_metrics,但是它已经被移到 EstimatorSpec 中(参见上一节,关于定制估计器)。我不清楚如果你使用一个固定的评估器,你如何获得额外的评估指标…幸运的是,我还没有遇到这种需求。
对您的云 ML 引擎脚本的更改
你必须对你的开发环境做什么改变?
嗯,云数据实验室现在带有 Tensorflow 1.4,所以只需启动一个新的实例,并在其中运行您的笔记本电脑。不需要其他更改。
在提交培训作业的 gcloud 命令中,指定 runtime _ version 1.4 而不是 1.2。所以改变:
gcloud ml-engine jobs submit training $JOBNAME \
...
--runtime-version 1.2 \
...
收件人:
gcloud ml-engine jobs submit training $JOBNAME \
...
--runtime-version 1.4 \
...
contrib 中的 saved_model_export_utils 用于将导出的模型写入名为 Servo 的目录中。嗯,Servo 是构建 Tensorflow 服务的 Google 项目的内部项目代号…该目录现在被称为“exporter”而不是“Servo”。据推测,这是为了防止另一个团队出现并构建更好的东西。因此,如果你有一个脚本:
MODEL_LOCATION=$(gsutil ls gs://${BUCKET}/babyweight/trained_model/export/Servo/ | tail -1)
您将把它改为:
MODEL_LOCATION=$(gsutil ls gs://${BUCKET}/babyweight/trained_model/export/exporter/ | tail -1)
当您部署模型时,请确保指定 Tensorflow 运行时版本:
gcloud ml-engine versions create ${MODEL_VERSION} --model ${MODEL_NAME} --origin ${MODEL_LOCATION} --runtime-version 1.4
其他一切都保持不变。
编码快乐!
如何归一化 TensorFlow 中的特征
原文:https://towardsdatascience.com/how-to-normalize-features-in-tensorflow-5b7b0e3a4177?source=collection_archive---------3-----------------------
Photo by Karsten Würth (@inf1783) on Unsplash
TL;DR 使用 *tf.estimator*
时,使用 *tf.feature_column.numeric_feature*
中的 *normalizer_fn*
参数,使用相同的参数(均值、标准差等)进行归一化。)进行培训、评估和服务。
def zscore(col):
mean = 3.04
std = 1.2
return (col — mean)/stdfeature_name = ‘total_bedrooms’
normalized_feature = tf.feature_column.numeric_column(
feature_name,
normalizer_fn=zscore)
归一化为
神经网络激活通常喜欢它们的输入被标准化。将网络中节点的输入标准化有助于防止所谓的消失(和爆炸)梯度。批量规范化是最全面的规范化方法,但是它会产生额外的成本,并且对于您的问题来说可能是多余的。因此,您可能只想规范化您的输入。
使用tf.estimator
API(这是构建 TensorFlow 模型最简单的方法)时,有两种规范化输入的方法:在input_fn
内部和创建feature_column
时。我将向您展示一个执行阶梯的示例,然后我将向您展示如何使用 ML 引擎训练多个模型。
样板代码:使用 normalizer_fn
参数进行规范化
查看这款笔记本的完整工作示例。
规范化 input_fn 中的允许更大的灵活性(您也可以在这里执行特征工程),但是我发现将normalizer_fn
与tf.feature_column.numeric_column
一起使用更优雅。下面是一个基本的例子:
*def zscore(col):
mean = 3.04
std = 1.2
return (col — mean)/std**feature_name = ‘total_bedrooms’
normalized_feature = tf.feature_column.numeric_column(
feature_name,
normalizer_fn=zscore)*
下面,我将展示一个端到端的例子,以获取规范化参数,然后规范化我的数据集中的所有数值列。
您应该提前计算训练集的规范化参数。在本例中,我使用 Pandas 来获取每个数字列的平均值和标准差:
或者, TensorFlow Transform 提供了一种标准化输入的可扩展方法,特别适用于大型数据集。查看这里的中的例子。
运行上面的代码后,我们返回每一列的参数:
{‘households’: {‘mean’: 501.34073416222617, ‘std’: 382.81658748493305},
‘housing_median_age’: {‘mean’: 28.5441089402013, ‘std’: 12.610144469735635},
‘median_income’: {‘mean’: 3.8814239564831365, ‘std’: 1.9061255708184284},
‘population’: {‘mean’: 1428.941163410302, ‘std’: 1150.5106244960523},
‘total_bedrooms’: {‘mean’: 539.6057578448787, ‘std’: 418.76075045523334},
‘total_rooms’: {‘mean’: 2642.2929988158676, ‘std’: 2162.649970020439}}
现在,您可以使用上面计算的训练平均值和标准偏差来创建特征列。
NUMERIC_FEATURES = [‘housing_median_age’, ‘total_rooms’, ‘total_bedrooms’, ‘population’, ‘households’, ‘median_income’]feature_columns = create_feature_cols(NUMERIC_FEATURES, use_normalization=True)
最后,您可以使用特性列构建评估器:
model = tf.estimator.DNNRegressor(hidden_units=[10,4],
model_dir = outdir,
feature_columns = feature_columns)
使用 ML 引擎在云中训练多个模型
归一化是一个超参数,在实践中,评估不同的归一化方案将是有用的。例如,您可能想尝试训练一个模型,只对您的要素进行归一化,并将其与使用批量归一化对隐藏图层的输入进行归一化进行比较。
您可以使用云 ML 引擎并行启动多个实验。这对于较大的数据集尤其有价值,在这种情况下,您希望利用云来扩展模型训练。使用 ML 引擎训练,需要将模型代码打包,创建 task.py 和 model.py 模型文件。参见回购的示例。
最佳实践是首先在本地测试模型包,以确保没有语法或语义错误:
OUTPUT_DIR=’trained_model’
export PYTHONPATH=${PYTHONPATH}:${PWD}/model_code
python -m trainer.task — outdir $OUTPUT_DIR — normalize_input 1
之后,您可以使用“g cloud ML-引擎作业提交培训”向 ML 引擎提交作业:
JOBNAME=my_ml_job_$(date -u +%y%m%d_%H%M%S)
REGION=’us-central1'
BUCKET=’gs://crawles-sandbox’
OUTPUT_DIR=$BUCKET/’housing_trained_model’
PACKAGE_PATH=$PWD/model_code/trainergcloud ml-engine jobs submit training $JOBNAME \
-- package-path=$PACKAGE_PATH \
-- module-name=trainer.task \
-- region=$REGION \
--staging-bucket=$BUCKET\
-- scale-tier=BASIC \
-- runtime-version=1.8 \
-- \
-- outdir=$OUTPUT_DIR\
-- normalize_input=0
在我的例子中,我在训练时计算和不计算特征的 z 值:
正如预期的那样,规范化输入提高了最终模型的性能。
就是这样!如果你觉得这篇文章有帮助,请给它一个掌声,这样其他人就可以找到它。
其他资源
- 使用 input_fn 归一化
- 使用 tf.keras 进行批量标准化
- 标准分数 (z 分数)
- 回购本帖子中的代码
如何不撞毁昂贵的圣诞无人机
原文:https://towardsdatascience.com/how-to-not-crash-that-expensive-christmas-drone-ad45259021ce?source=collection_archive---------0-----------------------
什么玩具可以教你
© Jason Peterson
认为你的新 DJI Phantom 4、Mavic 或其他昂贵的无人机由于其广泛的传感器包而不可摧毁?它有 GPS 加 GLONASS(俄罗斯 GPS) 加视觉定位,我听你说的。
是的。然而,人们总是坠毁这些高端无人机,产生各种各样的坠毁色情。下面是一个 3000 美元的 DJI 激励崩溃,都是由湿件故障引起的很好的蒙太奇。
如果你对相机感兴趣,你很容易将无人机简单地视为飞行相机,并迷恋相机部分(你必须拥有最好的),而轻视飞行部分(这有多难?).
但是多翼无人机是令人不安的装置。他们移动得很快,而且不总是朝着你想要的方向。
很容易慌,做错事。当你这样做时,尽管无人机控制器感觉很像视频游戏控制器,但你现在推动的是物质,而不是像素,物质对物质的碰撞往往是混乱的,昂贵的,并且对软弱和爱打官司的人有害。
进行一些廉价的练习
相信我。你需要练习。但是为什么要在你 1000 美元的无人机上练习呢?有这么多有趣的、廉价的、飞行原理相似的无人机。开始便宜,甚至继续廉价飞行时,尝试新的举措。
在法拉利上试用之前,请先在搅拌器上试用。
我已经在曼谷花了几周时间做这件事,等待我昂贵的无人机送货。我从零飞行经验到基本熟练的全手动飞行,在这个过程中,我把一架无人机沉入了湄南河——令人印象深刻的是,它一直闪烁着红色和绿色的光——然后把另一架放进了游泳池——它在干燥 36 个小时后奇迹般地复活了。
崩溃没有让我开心,但也没有让我付出太多。我从他们身上学到了很多。
在你毁掉昂贵的圣诞无人机之前,给你一些建议。
1.买个玩具级的练习用四轴飞行器,带高度保持。
这将是你的打手。
高度保持功能确保你的练习无人机在你起飞后会自动悬停(多亏了里面的一个小气压计——不需要复杂的卫星)。
如果你上升或下降,通过应用或多或少的油门,它将保持新的高度。
这让你几乎忘记了垂直运动,而专注于水平运动,这本身就有点棘手,因为你必须将左杆的偏航与右杆的倾斜结合起来,才能完成一个优雅的转弯。
玩具世界中有许多高空无人机可供选择,但司马 X5HW-I(约 60 美元)被誉为最容易飞行的无人机之一。
(飞行一段时间后,你也不需要保持高度——你将掌握悬停所需的油门的细微调整——但把这个挑战留到以后。)
2.买些电池和备用道具。
这些廉价的无人机每次充电飞行不会超过 8 或 10 分钟,所以你希望能够在野外更换电池,以便获得更多的练习时间。
顺便订购一些额外的道具,因为它们很容易损坏或丢失。
3.在安全的地方练习。
去一个开放的地方练习。不要认为你可以在你家附近的街道上飞来飞去,那里有电线,孩子们在踢足球,停着昂贵的汽车。
一旦到了那里,你想逐渐掌握如何平稳起飞和降落;悬停;来回和左右移动;并在保持四轮车前侧向前的同时进行倾斜转弯(考虑到对称的形状,这很棘手)。
制作平滑的、正面第一的数字 8,甚至跑道椭圆,并不像你想象的那么简单。
你还希望能够让无人机回到你身边,即使你不确定它的方向,因为它太远了,看不清楚。
四轴飞行器 101 YouTube 频道这里有很好的飞行课,涵盖了以上大部分内容。
4.开始思考如何取景拍摄。
没有什么好的说法:这个价位的相机会很烂。没有万向架,视频看起来很糟糕——分辨率低,不稳定,充满果冻效果——但无论如何都要记录下来,因为结果会给你如何最好地创作无人机镜头的想法。你会看到,就像在陆地上一样,你需要努力获得缓慢而流畅的动作。
当你准备好昂贵的无人机上的万向节控制时,你的拍摄将会更好。
5.如果你弄坏了,就修好它。
它是一个玩具。但是它不必是一次性的。
当你撞毁你的练习无人机时,你不太可能损坏主板,你可能会损坏的所有部件——机身、道具,甚至马达——都很容易在网上买到,而且很便宜。
我设法更换了我的 Cheerson nano 无人机中的一个花生大小的马达(如上图)。这项工作确实需要焊接,但在其他方面非常简单,20 分钟的修理。
YouTube 上有一个视频,可以让你对一架普通无人机进行几乎所有的修理。
做了这些事情,你就会成为一个更自信、更称职的昂贵无人机飞行员。相比之下,它的先进功能将使它看起来非常容易飞行。但是当软件或硬件出现故障时,这是不可避免的,你会为所有这些廉价的练习感到高兴。
如何不涉足数据科学
原文:https://towardsdatascience.com/how-to-not-get-into-data-science-7b06a9947907?source=collection_archive---------9-----------------------
“我如何进入数据科学/人工智能领域?”
我有坏消息要告诉你。你不会的。好吧,说真的。我最近在 LinkedIn 上收到了许多被问到这个问题的消息,我想成批回复它们,而不是所有这些小批量(双关语)。
我明白了。我们生活在一个信息过载的世界。我并不是说在这个特定的时刻很容易找到你需要的必要信息。但是你会发现(并发展)其他更有价值的东西:自己做研究的技能。
作为一名计算机科学家,我很自然会去谷歌搜索所有我需要的信息和解决方案。由于许多试图进入数据科学的人来自不同的背景(我认为这是这个领域最美好的事情),这可能不是那么明显。
是的,这会花费你更多的时间。至少一开始是这样。这需要你付出巨大的努力和创造力。但是说实话,你想要的工作不会有太大的不同。
“但是已经在这个领域工作的人更有经验,能够告诉我该怎么做。”
你完全正确。我不是说不要问别人。但是想想你会问他们什么。在我的情况下,我告诉每个人去参加六门课程:
- https://www.coursera.org/learn/machine-learning 的机器学习教程()
- Deeplearning.ai 的 5 门课程深度学习专业化(https://www.coursera.org/specializations/deep-learning)
在你成功地学习了这些课程之后,你就拥有了在数据科学/人工智能领域从事职业的所有必要技能。但我有什么资格这么说。我的 LinkedIn 个人资料上列出了 20 多门课程。我意识到的一件事是,随着课程数量的增加,存在收益递减规律。在某一点上,你不得不离开那个舒适的球场环境,弄脏你的手。所以最好尽快这么做。严酷的事实是,在一个你自己从头开始完成的项目中(也可能是一个 Kaggle 项目),你学到的东西比你参加另外 50 门课程学到的东西要多。
关于从别人那里获得建议
回到我在这一段开始的观点:如果你问别人,他们可能会回答并建议你可以选择什么课程。他们会这么告诉所有人。关键是你想脱颖而出。
如果你走出去,找到自己的资源,你可能会找到黄金,找到一篇文章或课程,完全符合你的需求。或者你会花几个小时去寻找,却找不到任何有用的东西(经常发生)。但通过这样做,你学会了如何判断和分析资源。你对互联网上的大量信息开发了自己的过滤器。
如果没有帮助,去问问别人。但是要用深思熟虑的方式去做。你不会通过说“嘿”或“你能建议我选什么课程吗?”来得到别人的建议。对你联系的那个人来说,这听起来像是“我太懒了,不想自己做研究,我看到你在这个领域工作。你能帮我吗?”。
就我而言,如果有人试图在更私人的层面上联系,我更有可能与他取得联系。告诉我你是谁,做什么的。为什么联系我而不是别人?你想达到什么目标,我怎样才能帮助你实现这个目标?本质上,这些都是人际交往技能。如果你不是最好的,戴尔·卡耐基会带你去→https://amzn.to/2Nz6fbr。
总结一下,我们生活在一个有太多信息需要处理的世界。唯一能让你与众不同并给你最大竞争优势的是发展你的研究技能。这也为你的长期发展做好了准备。我们的世界瞬息万变,你必须适应新的环境和工作场景。如今,取得成功意味着能够在比特和字节的丛林中爬行,找到问题的解决方案。这适用于数据科学、人工智能和当今时代的所有其他领域。
*免责声明:我不会因为推广他们的课程而获得报酬。我已经完成了。他们是最棒的。句号。
如何像一个适当的增长团队一样优化广告支出,并举例说明
原文:https://towardsdatascience.com/how-to-optimize-ad-spend-like-a-proper-growth-team-with-examples-4e57d9ed61e3?source=collection_archive---------1-----------------------
在线营销已经成为利用数据发展业务的一个非常强大的工具。您可以在几十个广告网络和平台上运行数百(或数千)个不同的广告活动,针对非常特定类型的潜在客户,并衡量活动绩效的各个方面。
面临的挑战是如何优化您的在线营销支出,以获得最大收益!在成千上万的活动中,哪些表现良好?哪些花费你太多,你应该一起停止它们?哪些广告吸引了那些会成为你最忠实顾客的顾客?
这些问题的答案每天(甚至每小时)都在变化。由于在线广告竞争如此激烈,接触客户的成本不断变化,你需要能够每天优化你的营销,以确保你的回报最大化。所有这些活动产生的数据可能会令人不知所措,并且很难知道从哪里开始。
在这篇文章中,我们将介绍如何使用我们在过去几个月中介绍的许多数据技术来优化您的广告活动。具体来说,我们将涵盖:
- 第 1 部分 —绩效基准测试
- 第二部分 —异常检测
- 第三部分 —客户价值预测
- 第四部分 —自动化
在你开始优化之前,我们将从讨论如何确定你今天做得有多好开始。
异常值 监控您的业务数据,并在发生意外变化时通知您。 我们帮助营销/增长&产品团队从他们的业务数据中获取更多价值。 今天安排一个试玩 。
第一部分。标杆广告绩效
理解你的基线表现是提高它的第一步。如果你现在不知道什么是正常的,你怎么能识别异常的表现呢?
有几种类型的在线广告活动,但我们将使用每次点击费用( CPC )活动作为一个例子。在这些活动中,只有当用户点击你的广告时(而不是当他们看到广告时),你才需要付费。与大多数广告一样,实际的每次点击成本会随着广告需求的变化而不断变化。以下是一周内 CPC 活动的示例数据:
A typical ad spend performance table
哇,这么多数据。我们从哪里开始?
我们的第一步是确定该活动的典型特征,以便我们可以轻松评估其表现,并将其表现与您每天开展的大量其他活动进行比较。虽然使用价格(CPC)很有吸引力,但它可能是一种误导性的活动衡量方法,因为最低成本的活动可能不会产生吸引或转化的用户。你需要的是一个结合成本和绩效的指标,这样你就可以通过投资回报来衡量一个活动。
在这个简单的例子中,我没有实际的用户行为数据,比如与每次点击相关的订单值,所以我需要找出一个不同的指标。跳出率是访问网站的用户只看了一页就离开的百分比,因此反过来,(1-跳出率)是访问了至少两页并因此更加投入的用户的百分比。如果我用价格 CPC 衡量参与度,我可以创建一个有用的营销活动价值指标:
有了价值指标,我们现在可以对示例活动进行基准测试。我们七天活动中每一天的价值如下:
鉴于我们 7 天的数据,我们需要选择一个统计数据来捕捉这一时期的活动性质,并成为我们的基准。正如我们前面提到的,如果数据不符合正态分布,使用平均值是危险的,而且我们没有办法知道它是否符合正态分布。相反,我们可以使用中位数,并更有信心,我们没有误导自己!
中值是 0.58,这是我们此次活动的基准。我们可以根据未来天数是高于还是低于该基准来评估该活动的未来天数。我们还可以使用基准比较我们所有的活动,看看在我们选择的时间段内,哪些活动表现得更好或更差。您还应该考虑跨多个时间段进行基准测试,因为性能可能会因周、月或年而异。
重要的是不要在真空中思考您的活动,因此您还应该计算您开展的所有活动的全球基准。借助全球基准和每个营销活动的单独基准,您可以轻松发现哪些营销活动超出或低于预期绩效,并做出相应的调整。
第二部分。异常检测
现在,您已经有了广告性能基准,您可以开始识别性能何时以意想不到的方式发生变化。这就是所谓的异常检测,它可以帮助你快速地从一堆数据中筛选出你需要分析的少数东西。
正如我们昨天所讨论的,最明显的方法是采用全球基准,并将低于该基准的任何活动标记为表现不佳。然而,我们的基准测试依赖于将几天的时间聚合在一起,这可能会丢失有价值的信息。如果一个活动在周一和周二表现很好,但在一周的其他时间表现很差,该怎么办?
我们将不再依赖我们的检测基准,而是将它们作为更复杂方法的一个组成部分。下图显示了七天营销活动的价值指标,以及我们用来总结它的每日基准(0.58,以绿色显示)。
如您所见,该基准有助于了解哪些天高于和低于正常水平,但仍不完全清楚哪些天是真正异常的。
我们可以通过添加一个高于或低于预期偏差范围的区间来扩展基准。我们预计我们的指标每天都会发生变化,因此,根据之前在这些活动中的经验,我们可能会预计,高于或低于基准 15%仍在预期绩效范围内。这反过来又给了我们一个预期的范围,我们可以绘制如下图:
如您所见,这种新的间隔方法使第 2 天明显超出预期行为,并将其归类为需要调查的异常。一旦建立了预期值范围,您就可以通过将每日值指标与预期范围进行比较,轻松监控所有活动的异常情况。
请注意,简单地选择高于或低于基准的值范围(在本例中为 15%)并不能捕捉到您的活动在一周内可能发生的典型变化。您可能希望使用更高级的技术,如 ARIMA 建模,来创建一个反映数据中每周和每月自然周期的预期范围。
第三部分。客户价值预测
优化广告活动时,准确了解客户对你的价值是很重要的,这样你就知道你获得他们的花费不会超过他们给你带来的好处。你越了解客户的价值,你就越能优化广告支出。
本周早些时候,因为我没有用户数据,我创建了一个基于每次点击费和跳出率的价值指标:
虽然这捕捉到了一个活动相对于另一个活动的相对价值,但它并没有告诉我们,我们为获得流量而支付的价格是高于还是低于这些用户的预期收入。如果你使用这个指标优化你的广告,你可能会在你获得的每个用户上赔钱!
理想情况下,我们会选择一个价值函数,将客户产生的收入与获得客户的成本联系起来:
收入的一个衡量标准是客户的终身价值,或 LTV,这是我们在获得这些用户后期望从他们那里获得的总收入。正如我们前面所讨论的,成本可以用 CPC 来表示。从 LTV 中减去每次点击费用,这个指标就是我们从客户那里赚的钱比我们为让他们点击而支付的钱多多少。我们仍然可以使用这一指标来比较营销活动、检测异常情况并进行优化,但现在我们可以肯定,只要价值指标为正,我们从营销活动中获得的收益就会超过其成本。
在电子商务等一些业务中,LTV 可能只是用户通过广告点击访问网站后购买的总金额。在其他情况下,如订阅业务,它可能是 12 个月订阅的价值。无论你的业务是什么,你能更有效地衡量 LTV,你就能更好地制定价值指标,优化你的广告。
就像生活中的所有事情一样,没有完美的标准。用户在买东西之前可能会点击几个不同的广告,这使得成本的计算很难进行。你应该考虑到无论你用什么方法都不是完美的。
第四部分。自动化
虽然我们介绍的技术非常强大,但是如果每天使用这些技术需要花费太多的时间和精力,那么它们就没有用。您需要自动化来为您处理大部分工作!
好消息是有很多选择可以帮助你:
- 需求方平台 会自动优化你在多个不同渠道的广告支出。他们将进行我们本周讨论的许多计算,并为您调整支出,确保最佳支出。它们通常只在实时竞价平台(也称为程序化广告购买)上起作用,因此可能不适用于你的所有广告,但它们是一个很好的起点。
- 广告归属产品 会自动跟踪你的广告价值指标,考虑到用户在成为客户之前可能会看到许多不同的广告(在不同的平台上)。这使得您的价值指标计算更容易,并将您的绩效收集在一个地方。
- 异常检测 产品会在您的任何活动数据出现异常时通知您,让您在必要时采取措施。它们通常与其他类型的工具结合使用,以确保您始终知道何时会发生重大变化。
如果你使用自动化,警惕盲目信任他们的优化方法。正如您在本周所看到的,优化可能需要针对您的业务做出许多决策,而这在一个一刀切的产品中是不可能的。只要有可能,自己审核绩效,以确保你真正充分利用了你的支出。
回顾:优化广告活动是确保营销支出有效的关键一步。您可以使用自动化平台来完成,也可以使用我们在此为您展示的流程自己完成。这是一个有价值的项目,因为优化的广告策略在任何市场都是一个强大的优势。
out lier监控您的业务数据,并在发生意外变化时通知您。 我们帮助营销/增长&产品团队从他们的业务数据中获取更多价值。 今天安排一个试玩 。
如何优化机器学习模型的超参数
原文:https://towardsdatascience.com/how-to-optimize-hyperparameters-of-machine-learning-models-98baec703593?source=collection_archive---------9-----------------------
Photo by Todd Quackenbush on Unsplash
寻找超参数的最佳组合是许多机器学习应用的核心。在这篇文章中,我将给你一个简要的概述和三个主要方法的示例。
在我最近的一个项目中,我发现自己处于一个太熟悉的情况。我获得了一组漂亮的数据。我完成了数据清理和特征工程的第一次迭代。最后,我准备好释放我们作为数据科学家向世界承诺的所有潜力。经过几次初步实验后,我们选定了梯度推进算法。但是,如何找到超参数的最佳配置呢?这就是这篇博文的内容。
在这篇文章中,我将带你看一个基本的例子,并对它应用三种不同的方法。我的目标是为你提供一个坚实的直觉,作为进一步调查的基础。如果你想做一些自己的实验,或者如果你需要一个地方开始你的优化之旅,所有的细节和必要的代码都可以作为一个 Jupyter 笔记本获得。
如何预测成功的众筹项目?
我的一个朋友正在准备一个 Kickstarter 活动,所以我决定用这个地区作为这篇文章的例子。多亏了米卡埃尔·穆莱,在 Kaggle 上有一个精彩的数据集。我抽样了 1000 个项目,其中大约 36%是成功的。我的目标是根据以下信息预测活动是否成功:
- 项目的类别(一般和更具体),例如“电影”或“书籍”。
- 项目来源国(美国占 77%)。
- 以美元为单位的筹资目标。幸运的是,这个转换已经包含在数据集中了。
我将类别和国家转换成虚拟变量,所以最终大约有 200 个可用的特性。
免责声明 1: 我说明性地使用数据,而不是你在实际应用中应该如何处理它。对于这个帖子,我采用了数据,并将其视为干净可靠的。我也没有任何特征工程等。
和项目类似,我用的是梯度提升算法(这里是 sklearn 的gradientboostingclassifier)。这组算法有许多超参数,但我专注于其中的两个以保持简洁明了:学习速率和特征的数量。
学习率调整算法更新的速度。如果太高,算法会快速跳转,可能会错过最佳解决方案。如果太低,算法可能需要很长时间才能最终稳定下来。诚然,这是一个粗略的总结,但希望表明,找到最佳点是至关重要的。
特征的数量决定了底层关系允许有多复杂。太复杂会导致过度拟合。另一方面,缺乏复杂性阻止了算法检测特征和目标之间的有用关系。
总之,我们已经准备好了数据集,确定了算法,并决定了我们想要优化的两个超参数。现在怎么办?在我们回到玩具的例子之前,让我们考虑三个选择。
选项 1:尝试所有组合
我们生活在一个计算能力无限的时代,对吗?如果这是真的,让我们尝试所有可能的配置,在测试集上比较它们的性能,并选择最佳配置。这就是网格搜索建立的目的。这种方法并不意味着精确或高效;这是一把猎枪。如果您有一组参数的完美组合可以隐藏的地方,网格搜索会瞄准所有这些地方并返回最佳选择。
让我们假设我定义了五个不同的学习率,以及五个不同的模型允许使用的最大特征数的值。然后,grid search 训练 25 个(5 * 5)不同的模型,评估所有模型,并返回在我选择的度量中得分最高的超参数配置。到目前为止一切顺利。
然而,正如您已经预料到的,这种方法的运行时间可能会很长。如果要检查三个超参数的十个不同值,网格搜索需要计算 10 * 10 * 10,也就是 1000(!)模特。让我们添加 3 重交叉验证,我们需要训练 3000 个模型!虽然对于网格搜索何时不再可行没有客观的阈值,但是这种方法的缺点是显而易见的。
选项 2:尝试尽可能多的组合
我不确定这是否会随着量子计算而改变,但目前,我必须在有限的计算能力下工作。因此,我无法测试所有可能的超参数组合。相反,我想尽可能多地测试它们,我将使用随机搜索来完成这项工作。由于我不知道最佳配置,所以这种方法随机选择一组组合并测试它们。
与网格搜索相比,有两个主要优势:
- 我可以定义迭代次数,即搜索算法测试的可能组合的数量。通过这样做,我可以决定我可用的计算预算。也许它很小,因为下一次结果的展示就要开始了。也许我的预算很重要,因为我周末离开,同时可以让我的机器保持运转。关键是,我现在控制了局面。
- 由于组合的选择是随机的,所以我可以使用分布来代替固定的一组值。对于网格搜索,我需要定义一组不同的最大特征,例如[1,10,30,50]。在随机搜索中,我可以定义特征的最大数量必须在 1 到 50 之间,并且中间的每个整数的概率相等。
这两点都改进了网格搜索。然而,让我们来解决房间里的大象:如果组合的选择是随机的,我找到最佳模型(或者至少是合理接近它的模型)的可能性有多大?好在答案是:很有可能。明确地说:如果我的网格包括 1000 种组合,而我只随机选择了其中的 10 种,我就有麻烦了。然而,一篇研究论文显示,如果网格中 5%的组合导致最佳结果,60 次随机搜索迭代足以有超过 95%的把握找到这些点中的一个(参见此处获得实际论文,以及此处获得额外解释)。
要点:网格搜索是有时间/资源和非理性高度风险厌恶的人可能会尝试的。然而,随机搜索是所有实际数据科学问题的首选算法。
如果你和我一样,你还是不满足。原因是这个词随机化了。现在有很多关于人工智能的讨论,因此必须有一种更智能的方法来选择超参数组合。如果我们使用一种算法来学习看哪里,那不是很好吗?
选项 3:尝试最有希望的组合
我坚持我对每个超参数的可能值范围的想法。然而,这一次,该算法不会测试所有的组合(网格搜索)或随机选择其中的一些组合(随机搜索),而是反复重新评估下一步在哪里寻找。从概念上讲,我们现在正在进入知情搜索的领域。
免责声明 2 :我在这里讨论贝叶斯优化,但是,尽管这是一个流行的选择,它只是一个有根据的搜索算法的例子。在我看来,这是最容易从概念上理解的,但这并不意味着它一定是最好的选择。有关方法和实现的更多细节,请查看此处的和此处的和。
要理解这个想法,请跟着我看一个基本的例子。假设我用随机选择的超参数值计算了第一个模型。其准确率为 67%。现在我用另一组超参数计算一个模型,它产生的准确率只有 64%。贝叶斯方法降低了为第二模型选择的值是最优解的一部分的概率。现在,它使用更新的概率为每个超参数选择一组新值,查看它是提高还是降低了模型的质量,并更新概率。换句话说,该算法更有可能为下一轮选择与较高模型性能相关的值,而不是那些不太有效的替代值。
关注更新概率的概念是至关重要的。有希望的值更有可能被选中,但仍有一些随机性。这个过程确保算法对新的可能性保持开放。如果想深入挖掘这个问题,谷歌“探索 vs 剥削”。
那么这些 Kickstarter 活动呢?
在我回到我的玩具例子之前,这里是关于三个选项的最关键点:
- 网格搜索是一种强力方法,它测试超参数的所有组合,以找到最佳模型。它的运行时随着要测试的值(及其组合)的数量而爆炸。
- 随机搜索通过将自己限制在限定数量的组合中进行尝试来减少运行时间。因为这种方法可能找到接近最佳的解决方案,所以比网格搜索更可取。
- 知情搜索(贝叶斯优化作为其实现之一)通过反复重新评估寻找最佳位置增加了一些额外的开销。这种开销可以通过更有效的搜索来平衡。这种方法经常出现在 Kaggle 比赛中是有原因的。
现在,让我们看看 Kickstarter 项目(再次,见这里一个 Jupyter 笔记本)。如上所述,我只调整学习率(在 0.005 和 0.2 之间)和最大特征数(在一个和所有可用特征之间)来对数据训练梯度推进模型。以下是我们三个选项的结果:
- 网格搜索:我使用 numpy 为两个超参数定义了五个均匀间隔的值,总共有 25 个组合要测试。达到 0.626 的 AUC 分数花费了大约 8 秒。
- 随机搜索:这次我用了一个 scipy 函数,让特征数量的选择更加灵活。一个特征和所有特征之间的所有值被选择的可能性是相等的。为了增加难度,我只允许 12 次迭代。大约 4 秒后得到的 AUC 分数为 0.617。比网格搜索略差。
- Informed Search:hyperopt提供了一些非常有用的函数来模拟超参数的分布。对于学习率,我使用了一个使较小值比大值更有可能的分布。我决定用 25 次迭代。在大约 7 秒之后,该模型获得了 0.635 的 AUC 分数。
我想说清楚:这是一个用于说明目的的玩具示例。请按照我在这篇博文中提供的链接进行比较和评估。尽管如此,我希望这篇介绍能在两个方面帮助你。首先,让您可以方便地访问主题和一些可以在项目中使用的代码片段。第二,激励你更深入地挖掘超参数优化的主题。
感谢阅读!如果您有任何反馈或想告诉我您在超参数优化方面的体验,我很高兴收到您的来信!你可以在推特和领英上找到我。让我们继续学习吧!
如何在数据科学竞赛中胜出——洞察力、技巧和策略
原文:https://towardsdatascience.com/how-to-out-compete-on-a-data-science-competition-insights-techniques-and-tactics-95a0545041d5?source=collection_archive---------4-----------------------
Random Forest Visualization of the Competition Data Set
过去两天,我花了相当多的空闲时间在当前的数据科学竞赛上。在 Vidhya 的一个贷款预测问题。是的,睡眠比平时少了,但是学习是值得的。
让我来分享一下我的经验和这类比赛的主要发现,以及成功的秘诀。
首先:数据科学竞赛是为了好玩,加强你的数据科学和机器学习技能。
所以——选择一个你最喜欢的比赛和数据集,而不是承诺最高奖金的那个。
浏览您的数据。密集!
不深入研究数据细节,我们就无法提出(&回答)正确的问题——这是成功的数据科学的关键先决条件。
在我们的例子中,提供的训练集如下所示:
Loan_Status 是我们将针对其进行训练的标签。
对数据的初步分析
pandas 库的 describe()特性非常方便。它将一目了然地展示连续变量的一些指标。我们可以清楚地看到,数据相当少,只有 614 个样本。因此每个样本对最终模型的贡献相对较高。
信用记录显然是最重要的特征之一。没有信用记录的申请人很有可能被拒绝——92%——然后是有信用记录的申请人(只有 20%被拒绝)
了解这一点很重要,尤其是在处理缺失值时。我们的训练集中的 50 个条目和测试集中的 29 个条目对于信用历史没有价值。考虑到数据的小规模,这是我们需要处理的大量数据。
其他重要特征是财产面积、教育和婚姻状况:
Orange 提供了一种很好的方式来可视化三维向量空间中预测值的重要性:
Feature Importance visualized in a 3d vector space
财务状况当然也是申请贷款的一个重要标准:
由于银行总是将一个家庭作为一个整体来考虑,所以提供一个新的特征是有意义的,它将包括申请人和共同申请人的总收入。以及人均收入分割(基于数据集上的受抚养人人数)
填补空白-缺失值处理
一个非常常见且有时很好的策略是跳过/删除缺少值的数据条目。尤其是当数据集的大小非常大而缺失值的数量相对较小时。两者都在这里不是这样的。
所以我们需要想出一个解决方案。有不同的方法到达那里。对于数值,可以应用线性回归并基于它预测缺失值。
k-NN 方法:由于我们缺少数值和分类值,我决定用 k-NN 算法来解决这个问题。想法是检测具有丢失值的每个数据项的 k 个最近邻居。
对于数值,我们将计算 k-邻居的平均值,对于分类值,计算具有最高众数值的平均值。我决定使用 k=7(是一个奇数,代表大约。1%的数据)。这样,我就能够用合理的价值观来填补所有缺失的价值观缺口。
添加有意义的信息—特征工程
我们已经围绕收入指标引入了一些新功能。类似的策略可以应用于预测值 LoanAmount 和 Loan_Amount_Term,我们可以计算每个期限的贷款金额(每月贷款支付率):
当然,像随机森林或神经网络这样的算法将能够从数据中提取这个值。公开这类特征只是让它们显而易见,从而赋予它们更高的权重。
记住房产的面积是一个决定性的预测因素,一个有价值的新特征可能是区分在郊区有孩子的家庭(假设他们更有可能获得贷款)和其他家庭(有房子的家庭)
检测异常值
另一个有价值的方法是计算每期贷款金额与每月收入的比率:
这样做我们可以发现几个异常值(月贷款利率>月收入的 100%),并可以更仔细地观察它们。离群值是一个严肃的话题,因为它们扭曲了你的度量标准(特别是。平均值对异常值非常敏感),这将对您的模型准确性产生负面影响。
特征选择-哪些贡献最大?
特征选择在数据挖掘过程中起着关键作用。您可以通过对数据应用基于树的算法(例如决策树、随机森林)或使用类似于 Rlief 的算法来验证哪些功能的成本最低:
这是一个很好的指标,表明我们引入的额外功能得分很高,并且优于一些给定的功能。这项工作是值得的。
现在让我们建立模型。
这里我们面临的问题是一个二元分类问题。我们可以应用不同的监督训练算法,如逻辑回归、神经网络、SVM、基于树的模型等。
由于数据集相对较小,我决定采用多个随机森林模型的集合,这些模型由逻辑回归模型聚合而成。训练结果通过 K 倍(k=20)交叉验证进行验证,在训练集上的最终分类准确度分数为 0.810(竞赛的获胜分数为 0.8206278027,这非常接近,但仍然是显著的差异)
结论:
制作新特征、填补缺失的值缺口、处理异常值、特征选择——这是每个数据挖掘过程(也称为探索性数据分析——EDA)的核心步骤。它不是线性的,而是一个高度迭代的过程。
因此,重要的是建立一个处理管道(例如在 Jupyter、RStudio 或可视化工具中,如 RampidMiner 、 Knime 或 Orange ),并能够随时重复和调整其中的每一步。
最后——即使我们没有登上排行榜的首位(但对于两天的努力来说已经很接近了),这仍然是一场胜利。新见解、有价值的技术和策略的胜利。
让我知道你是否喜欢这篇文章,点击掌声按钮和/或在下面留下评论。我很感激。
PS:想接触一下?在 LinkedIn 上找到我:
[## Christo Zonnev -数据科学副总裁-凯捷发明| LinkedIn
查看 Christo Zonnev 在世界上最大的职业社区 LinkedIn 上的个人资料。Christo 列出了 7 项工作…
www.linkedin.com](https://www.linkedin.com/in/christo-zonnev/)
或者在推特上关注我
如何在 Excel 中不写代码进行情感分析?
原文:https://towardsdatascience.com/how-to-perform-sentiment-analysis-in-excel-without-writing-code-8a9e66115447?source=collection_archive---------5-----------------------
我们最近发布了一个新版本的 Excel 加载项,它让您无需编写一行代码,就可以在舒适的电子表格中执行最先进的文本分析功能。该插件已被不同行业的用户广泛接受,如市场研究、软件、消费品、教育等。解决各种用例。
情绪分析是我们 Excel 插件中使用最多的功能,紧随其后的是情绪检测。我们的许多用户使用 Excel 中的情感分析来快速准确地分析开放式调查的回复、围绕其产品/服务的在线聊天,或者分析来自电子商务网站的产品评论。
在这篇博文中,我们将讨论如何使用 Excel 插件中的情感分析功能对任何类型的内容进行文本分析。
首先,我们将向您简要介绍驱动我们情感引擎的底层技术。
我们的情感分析“模型”使用长短期记忆(LSTM)算法将文本 blob 的情感分为积极和消极。LSTMs 将句子建模为基于上下文的遗忘-记忆决策链。它接受了来自不同社交媒体网站和新闻文章的用户生成内容的训练,以处理随意和正式的语言。作为我们的企业产品的一部分,我们还在不同客户的定制数据集上训练了这种算法。
在 Excel 插件中使用情感分析
首先,你需要注册一个 ParallelDots 账户(如果你还没有的话),下载并在你的电脑上安装 Excel 插件。安装后,按照以下步骤在 Excel 中使用情绪分析:
- 登录到您的 ParallelDots Excel 加载项帐户:输入您的登录凭据以激活加载项的功能。
- 使用 excel 插件情感分析功能:
使用函数parallel dots _ perspective可以分析任何文本内容,并反过来获得附加到文本的情感。考虑下面的例子,其中文本句子“团队整体表现良好”正在使用 paralleldots _ 情操分析。如下图 GIF 所示:
如果您需要知道上面讨论的 parallel dots _ invision 函数返回的情感标签的概率,您可以通过调用 parallel dots _ invision <sentiment_label> probability 函数来实现,其中 invision _ lable 可以是中性的、正的或负的。</sentiment_label>
情绪分析以快速有效的方式衡量用户的情绪,并据此采取适当的行动。通常,这是做出数据驱动的决策以改进产品或服务之旅的第一步。您应该将它与关键字提取功能结合使用,以找到对您的数据的整体情感有贡献的关键因素。
你可以在这里阅读更多关于 Excel 插件的使用案例。
我们希望这篇文章能帮助你在 excel 中使用 ParallelDots 插件进行情感分析,并开始你的文本分析之旅。如有任何疑问或反馈,请通过 support@paralleldots.com写信给我们。
如果你还没有下载插件,请从这里免费下载。
我们希望你喜欢这篇文章。请注册一个免费的 ParallelDots 账户,开始你的 AI 之旅。你也可以在这里查看 PrallelDots AI API的演示。
此处阅读原文。
如何在 R 中播放星球大战等曲子
原文:https://towardsdatascience.com/how-to-play-star-wars-and-other-tunes-in-r-5e837e8b71e4?source=collection_archive---------2-----------------------
Photo by Liam Tucker on Unsplash
有时我的研发过程需要很长时间,我不能坐在电脑前看着它全部完成。我认为在我的脚本结尾选择一些胜利的曲调会很酷,这样当过程成功执行时,我可以听到一些告诉我一切顺利的东西。
所以我研究了 R 中的audio
包,它允许你通过与机器上基于样本的音频设备接口来创建和播放声音,并将其保存为 wave 文件。文本和数字的字符串可以被处理成频率值,然后与音符长度的数据结合成正弦波。这将产生一个整洁小曲子,可以在你的休息时间或任何媒体设备上播放。
写星球大战主题
让我们从加载必要的包开始:
library(dplyr)
library(audio)
让我们也定义一个八度音程中音符的值。为此,你需要用半音来思考,考虑到降半音和升半音,这将在后面定义:
notes <- c(A = 0, B = 2, C = 3, D = 5, E = 7, F = 8, G = 10)
现在让我们为星球大战主题写笔记,忽略每个笔记的长度。如果你能读懂乐谱,你就能做到这一点。你可以用任何你想要的方式组织它,用一个字符向量的格式,因为我们稍后会清理它。我决定为每个小节写一个字符串,字符串中的音符用空格隔开。
我们稍后将设置代码,将符号#
理解为升半音,将b
理解为降半音,以使音乐人更直观。
我们需要在音乐中分离八度音阶。稍后我将设置我的代码来解释一个普通的音符,例如A
在第四个八度音阶中,任何其他的八度音阶都通过在音符后面加上八度音阶编号来表示(例如A5
或B3
pitch <- paste("D D D",
"G D5",
"C5 B A G5 D5",
"C5 B A G5 D5",
"C5 B C5 A D D D",
"G D5",
"C5 B A G5 D5",
"C5 B A G5 D5",
"C5 B C5 A D D",
"E E C5 B A G",
"G A B A E F# D D",
"E E C5 B A G",
"D5 A D D",
"E E C5 B A G",
"G A B A E F# D5 D5",
"G5 F5 D#5 D5 C5 A# A G",
"D5 D D D",
"G D5",
"C5 B A G5 D5",
"C5 B A G5 D5",
"C5 B C5 A D D D",
"G D5",
"C5 B A G5 D5",
"G5 F5 D#5 Bb5 A5",
"G5 G G G G")
然后你可以用音符的长度写一个数字向量,一拍用数字1
表示。为了使我的符号清晰,我尽量保持每个小节一行。
duration <- c(0.33, 0.33, 0.33,
2, 2,
0.33, 0.33, 0.33, 2, 1,
0.33, 0.33, 0.33, 2, 1,
0.33, 0.33, 0.33, 2, 0.33, 0.33, 0.33,
2, 2,
0.33, 0.33, 0.33, 2, 1,
0.33, 0.33, 0.33, 2, 1,
0.33, 0.33, 0.33, 2, 0.75, 0.25,
1.5, 0.5, 0.5, 0.5, 0.5, 0.5,
0.33, 0.33, 0.33, 0.75, 0.25, 1, 0.75, 0.25,
1.5, 0.5, 0.5, 0.5, 0.5, 0.5,
1, 2, 0.75, 0.25,
1.5, 0.5, 0.5, 0.5, 0.5, 0.5,
0.33, 0.33, 0.33, 0.75, 0.25, 1, 0.75, 0.25,
0.75, 0.25, 0.75, 0.25, 0.75, 0.25, 0.75, 0.25,
3, 0.33, 0.33, 0.33,
2, 2,
0.33, 0.33, 0.33, 2, 1,
0.33, 0.33, 0.33, 2, 1,
0.33, 0.33, 0.33, 2, 0.33, 0.33, 0.33,
2, 2,
0.33, 0.33, 0.33, 2, 1,
0.33, 0.33, 0.33, 2, 1,
1, 0.33, 0.33, 0.33, 1)
现在我们有了所有需要的原材料。
将音符转换成正弦波的频率
首先,我们将音高和音长向量转换成一个数据帧,其中每个音符都是一个具有音高和音长的元素。在星球大战主题的情况下,总共有 126 个音符。
starwars <- data_frame(pitch = strsplit(pitch, " ")[[1]],
duration = duration)
现在,我们将扩展该数据框架,以包括一些新列:
octave
它从pitch
符号中提取音符要在哪个八度音阶中演奏note
从我们的原始notes
向量中提取原始音符值,然后针对升半音、降半音和八度音程变量进行调整freq
将note
转换成以 Mhz 为单位的频率
starwars <-
starwars %>%
mutate(octave = substring(pitch, nchar(pitch)) %>%
{suppressWarnings(as.numeric(.))} %>%
ifelse(is.na(.), 4, .),
note = notes[substr(pitch, 1, 1)],
note = note + grepl("#", pitch) -
grepl("b", pitch) + octave * 12 +
12 * (note < 3),
freq = 2 ^ ((note - 60) / 12) * 440)
我们现在将定义一个将音符和音长转换成正弦波的函数。为此,我们将以每分钟的节拍数和采样率(通常为 44.1Khz)来设置速度:
tempo <- 150
sample_rate <- 44100make_sine <- function(freq, duration) {
wave <- sin(seq(0, duration / tempo * 60, 1 / sample_rate) *
freq * 2 * pi)
fade <- seq(0, 1, 50 / sample_rate)
wave * c(fade, rep(1, length(wave) - 2 * length(fade)), rev(fade))
}
最后,我们只需将该函数应用于starwars
数据帧中的freq
和duration
列,然后简单地弹奏曲子。
starwars_wave <-
mapply(make_sine, starwars$freq, starwars$duration) %>%
do.call("c", .)audio::play(starwars_wave)
您也可以将乐曲保存为一个.wav
文件,以便随时使用
audio::save.wave(starwars_wave, "starwars.wav")
你需要的所有代码都在这里供你尝试,但是这里有 GitHub 中的代码链接,如果你想拿出来和其他曲子一起玩的话。您可以随意将自己的音乐放回单独的 R 文件中的同一个 GitHub repo 中,以便他人欣赏。
最初我是一名纯粹的数学家,后来我成为了一名心理计量学家和数据科学家。我热衷于将所有这些学科的严谨性应用到复杂的人的问题上。我也是一个编码极客和日本 RPG 的超级粉丝。在LinkedIn或Twitter上找我。
如何用 Anaconda 和 Jupyter 笔记本绘制地震活动图
原文:https://towardsdatascience.com/how-to-plot-seismic-activity-with-anaconda-and-jupyter-notebooks-7ed23ce9aa5?source=collection_archive---------8-----------------------
Demo of our end product
在这个活动中,我们将使用 Anaconda 作为我们的分发平台。要开始使用 Anaconda,从 Anaconda 下载发行版,根据您的操作系统说明进行安装,通过单击左下角的 create 按钮创建一个新环境,然后搜索、选择并安装以下包[matplotlib、basemap、pillow、pandas]
接下来,转到 Anaconda Navigator 的主页,确保左上角的下拉菜单选择了您新创建的环境,并安装 Jupyter Notebook。
Homepage of your selected environment
如果您已经安装了 Anaconda,请确保您已将 Matplotlib 更新到版本 3.0.2,或降级到版本 3.0.0,3.0.1 在使用设置属性时引入了底图错误。plot(),我们稍后会用到它。参考 github 问题这里了解更多信息。如果你不确定如何更新 conda 和它的包,请看这个堆栈溢出帖子,尽管如果在阅读时发行版没有更新,你可能不得不求助于 pip。(截至 2018 年 11 月 17 日尚未发布)
# open your environment with cmd prompt/shell
pip install matplotlib --upgrade# conda version will still display what it's distro is set to
# feel free to check your version
import matplotlib
print(matplotlib.__version__)
很好,现在在左侧菜单中选择“环境”,您会在新创建的环境中看到一个图标,您会看到几个选项,您想要的是“用 Jupyter 笔记本打开”
Menu for launching environment
继续运行它,一个新的窗口将在你的默认浏览器中打开,列出你的根目录。浏览您的文件夹,选择一个位置来存储您的 Jupyter 笔记本,然后单击文件夹上方菜单上的“新建”按钮创建一个新笔记本。如果您正确地遵循了说明,您应该会看到类似这样的内容。
Newly created notebook
太棒了,你已经做了你的第一个笔记本。现在我们可以开始玩了!请打开笔记本。你将得到一个交互式 shell,如果你不熟悉的话,我鼓励你使用 Jupyter Notebook 来阅读。
首先,我们将创建一个基本的彩色正交地图。有关所有支持的投影列表,请参见此处的。
# import dependencies
# note that Basemap will be supported until 2020 only
from mpl_toolkits.basemap import Basemap
import matplotlib.pyplot as plt
import numpy as np# make sure to set your plot size before you start rendering to screen
plt.figure(figsize=(8, 8))# by default, only crude and low resolutions are installed, if you wanted
# higher fidelity images, refer to the documentation.default_map = Basemap(projection='ortho', lat_0=45, lon_0=-105,
resolution='l', area_thresh=1000.0)default_map.drawcoastlines()
default_map.drawcountries()
# matplotlib provides color creation
default_map.fillcontinents(color='navajowhite')
default_map.drawmapboundary()plt.show()
Default Map
接下来,让我们通过在 plt.show()前添加以下代码来添加经纬线
default_map.drawmeridians(np.arange(0, 360, 30))
default_map.drawparallels(np.arange(-90, 90, 30))
Longitude and Latitude added
这开始看起来挺帅的!可悲的是,尽管它很漂亮,但它可能不是观察全球地震活动的最佳预测。我鼓励你在这一点上玩投影,看看你喜欢哪一个!至于我自己,我选择了锤子投影,并根据自己的喜好调整了纬度/经度值。
# change to hammer projection, fix lat/long
# import dependencies
# note that Basemap will be supported until 2020 only
from mpl_toolkits.basemap import Basemap
import matplotlib.pyplot as plt
import numpy as np# make sure to set your plot size before you start rendering to screen
plt.figure(figsize=(18, 18))# by default, only crude and low resolutions are installed, if you wanted
# higher fidelity images, refer to the documentation.default_map = Basemap(projection='hammer', lat_0=0, lon_0=-100,
resolution='l', area_thresh=1000.0)default_map.drawcoastlines()
default_map.drawcountries()
# matplotlib provides color creation
default_map.fillcontinents(color='navajowhite')
default_map.drawmapboundary()default_map.drawmeridians(np.arange(0, 360, 30))
default_map.drawparallels(np.arange(-90, 90, 30))plt.show()
Hammer projection with longitude/latitude lines
我知道你现在在想什么!"看,妈妈,从这里我能看见我的房子."那么,我们为什么不试着放大我们自己的地理区域,仔细看看。最简单的方法是将您的投影类型更改为“墨卡托投影”,它支持缩放。我在网上查找我的经度,纬度坐标,并向外调整以获得更清晰的图像。如果您希望放大后的地图具有更高的分辨率,也可以安装 Anaconda 的 basemap-data-hires。
对于下一步,我大胆地将 merc 投影仪放入一个接受两个整数的函数中,以创建一个区域地图生成器。现在,如果您超出纬度/经度限制,可能会出现一些问题,但是您可以轻松地调整输入来解决这个问题。这是没有异常处理的快速而肮脏的代码。
# what if we want to look at a specific area of the world?from mpl_toolkits.basemap import Basemap
import matplotlib.pyplot as plt
import numpy as npdef create_merc(lat, long):
plt.figure(figsize=(10, 10))# make sure the value of resolution is a lowercase L,
# for 'low', not a numeral 1
my_map = Basemap(projection='merc', lat_0=(lat-20), lon_0=(long+15),
resolution = 'h', area_thresh = .1,
# lower left hand corner longitude, lat
# upper right hand corner long, lat
llcrnrlon=(long-10), llcrnrlat=(lat-10),
urcrnrlon=(long+10), urcrnrlat=(lat+10))my_map.drawcoastlines()
my_map.drawcountries()
my_map.fillcontinents(color='navajowhite', lake_color='paleturquoise')
my_map.drawmapboundary()my_map.drawmeridians(np.arange(0, 360, 30))
my_map.drawparallels(np.arange(-90, 90, 30))plt.show()create_merc(39, -76)
You might recognize these iconic US lakes.
哇哦。我们能不能感谢这些库所付出的努力,让我们在几个小时内通读文档就能做出这样的东西?(不可否认,我花了更多的时间来克服一些错误)
好吧,继续!让我们试着画出具体的坐标。比如我现在住的地方。
# plot the initial coordinate input
x, y = merc_map(long, lat)
merc_map.plot(x, y, 'go', markersize=12)plt.show()
A nice big green dot
好的,我们已经证明了我们可以绘制图形。但是我们可能需要多个,所以让我们从函数输入中删除赋值,并使用一个容器来存储我们需要的内容(记住,我们希望读入数据并存储它以便以后绘制),让我们继续为我们的图添加一些标签。这里的想法和坐标一样!我们先手动测试一下。(和你真正的一点点偷懒)
# what if we want to look at a specific area of the world?from mpl_toolkits.basemap import Basemap
import matplotlib
import matplotlib.pyplot as plt
import numpy as npdef create_merc(lat, long):
plt.figure(figsize=(10, 10), dpi=100)
# increase font size
matplotlib.rcParams.update({'font.size': 16})# make sure the value of resolution is a lowercase L,
# for 'low', not a numeral 1
merc_map = Basemap(projection='merc', lat_0=(lat-20), lon_0= (long+15),
resolution = 'h', area_thresh = .1,
# lower left hand corner longitude, lat
# upper right hand corner long, lat
llcrnrlon=(long-10), llcrnrlat=(lat-10),
urcrnrlon=(long+10), urcrnrlat=(lat+10))
longs = [-77, -74]
lats = [39, 40]
x, y = merc_map(longs, lats)
merc_map.plot(x, y, 'go', markersize=8)
locations = ['Columbia, MD', 'New York City']
for label, xc, yc in zip(locations, x, y):
plt.text(xc-100000, yc+55000, label, color='teal')
merc_map.drawcoastlines(color='grey', linestyle=':')
merc_map.drawrivers(linewidth=0.3, color="cornflowerblue")
merc_map.fillcontinents(color='navajowhite', lake_color='paleturquoise')
merc_map.drawcountries()
merc_map.drawmapboundary() merc_map.drawmeridians(np.arange(0, 360, 30))
merc_map.drawparallels(np.arange(-90, 90, 30))
plt.show()create_merc(39, -77)
现在我们已经探索了映射、绘图和注释,让我们开始引入一些数据。出于本教程的目的,我已经将地震数据下载为 CSV 格式,并将其存放在 github 上,供您以其 raw 格式访问。
继续将原始数据加载到 pandas 中,并开始研究数据。我们实际上想要绘制地震活动的是它的地理位置,所以检查纬度和经度列中是否有任何缺失的值。
import pandas as pd
seismic_activity_30_days = pd.read_csv('[https://raw.githubusercontent.com/edwardauron/working_data/master/all_week.csv'](https://raw.githubusercontent.com/edwardauron/working_data/master/all_week.csv'))seismic_activity_30_days.head()print(seismic_activity_30_days['latitude'].isnull().values.any())
print(seismic_activity_30_days['longitude'].isnull().values.any())False
False
太好了,没有丢失 lat 或 long 数据,所以我们可以跳过清理,直接将列中的数据放到我们函数中先前定义的列表中。我们重用先前函数中的现有代码来获取一个数据帧,并添加一些方法来处理它。
def create_hammer(df):
plt.figure(figsize=(10, 10), dpi=100)
# increase font size
matplotlib.rcParams.update({'font.size': 16})# make sure the value of resolution is a lowercase L,
# for 'low', not a numeral 1
merc_map = Basemap(projection='hammer', lat_0=0, lon_0=-130,
resolution = 'l', area_thresh = 1000)
working_df = df
longs = working_df['longitude'].tolist()
lats = working_df['latitude'].tolist()
x, y = merc_map(longs, lats)
merc_map.plot(x, y, marker='o', color='lavenderblush', markersize=4)
merc_map.drawcoastlines(color='grey', linestyle=':')
merc_map.drawrivers(linewidth=0.3, color="cornflowerblue")
merc_map.fillcontinents(color='navajowhite', lake_color='paleturquoise')
merc_map.drawcountries()
merc_map.drawstates(linewidth=0.3, color='saddlebrown')
merc_map.drawmapboundary()merc_map.drawmeridians(np.arange(0, 360, 30))
merc_map.drawparallels(np.arange(-90, 90, 30))
plt.show()create_hammer(seismic_activity_30_days)
如果你跟着做,你会注意到这造成了一片混乱。
Yikes!
我们需要单独绘制所有这些点,而不是一次绘制所有这些点。是的,是时候来个for
循环了。事实证明“淡紫色”并不是最容易看到的颜色!
def create_hammer(df):
plt.figure(figsize=(10, 10), dpi=100)
# increase font size
matplotlib.rcParams.update({'font.size': 16})# make sure the value of resolution is a lowercase L,
# for 'low', not a numeral 1
hammer_map = Basemap(projection='hammer', lat_0=0, lon_0=-130,
resolution = 'l', area_thresh = 1000)
working_df = df
longs = working_df['longitude'].tolist()
lats = working_df['latitude'].tolist()
min_marker_size = 2.5
for longitude, latitude in zip(longs, lats):
x, y = hammer_map(longitude, latitude)
marker_size = min_marker_size
hammer_map.plot(x, y, marker='o', color='maroon', markersize=marker_size)
hammer_map.drawcoastlines(color='grey', linestyle=':')
hammer_map.drawrivers(linewidth=0.3, color="cornflowerblue")
hammer_map.fillcontinents(color='navajowhite', lake_color='paleturquoise')
hammer_map.drawcountries()
hammer_map.drawstates(linewidth=0.3, color='saddlebrown')
hammer_map.drawmapboundary()hammer_map.drawmeridians(np.arange(0, 360, 30))
hammer_map.drawparallels(np.arange(-90, 90, 30))
plt.show()
这才像话!
我们还需要做最后一件事。你能猜到吗?我们需要一种方法来区分这些情节点!你能在数据框中找到对我们有帮助的列吗?我们应该将该列映射到哪种表达式?在查看我的解决方案之前,请随意探索并提出想法。
嗯,这是我的成品。它仍然需要一些提炼,就像一个传说。但是我继续添加了一个格式化的标题,以及一些玩弄绘制的圆圈大小。它可以使用一些悬停事件,我计划添加一个选项来放大和投影用户指定的区域与墨卡托投影,但我对我在这里感到满意。暂时如此。
# plotting seismic activityfrom mpl_toolkits.basemap import Basemap
import matplotlib
import matplotlib.pyplot as plt
import numpy as np
import pandas as pddef create_hammer(df):
plt.figure(figsize=(18, 12), dpi=100)
# increase font size
matplotlib.rcParams.update({'font.size': 16})# make sure the value of resolution is a lowercase L,
# for 'low', not a numeral 1
hammer_map = Basemap(projection='hammer', lat_0=0, lon_0=-130,
resolution = 'l', area_thresh = 1000)
working_df = df
# generate data for plotting from our df
longs = working_df['longitude'].tolist()
lats = working_df['latitude'].tolist()
mags = working_df['mag'].tolist()
# handle dates for title
start = working_df.time.iloc[0]
end = working_df.time.iloc[1825]
min_marker_size = 2.5
for longitude, latitude, magnitude in zip(longs, lats, mags):
x, y = hammer_map(longitude, latitude)
marker_size = min_marker_size * magnitude\
if magnitude < 3.0:
hammer_map.plot(x, y, marker='o', color='maroon', markersize=marker_size)
elif magnitude < 5.0:
hammer_map.plot(x, y, marker='o', color='slateblue', markersize=marker_size)
else:
hammer_map.plot(x, y, marker='o', color='goldenrod', markersize=marker_size)
hammer_map.drawcoastlines(color='grey', linestyle=':')
hammer_map.drawrivers(linewidth=0.3, color="cornflowerblue")
hammer_map.fillcontinents(color='navajowhite', lake_color='paleturquoise')
hammer_map.drawcountries()
hammer_map.drawstates(linewidth=0.3, color='saddlebrown')
hammer_map.drawmapboundary()hammer_map.drawmeridians(np.arange(0, 360, 30))
hammer_map.drawparallels(np.arange(-90, 90, 30))
title = "Seismic activity with Magnitudes more than 1.0\n"
# string manipulation, list slicing
title += "%s through %s" % (start[:10], end[:10])
plt.title(title)
plt.show()create_hammer(seismic_activity_30_days)
如何如厕训练暹罗网络
原文:https://towardsdatascience.com/how-to-potty-train-a-siamese-network-3df6ca5e44da?source=collection_archive---------4-----------------------
是时候对我的一次性学习方法进行更新了,我使用了一个基于 LSTM 的深度神经网络,我们开发该网络是为了通过流量分析来识别电信网络故障。当我们将机器升级到最新的 TensorFlow 和 Keras 时,许多小细节都必须更改。仅此一项就引入了一些新的行为……同时我们获得了新例子的新数据,并发现了我们模型的一些问题。我不打算介绍所有的变化,但一些主要的变化以及一些有趣的发现。这感觉很像 potty 训练一只猫…如果你是这个系列的新手,你可以参考我以前的帖子:“电信网络会梦到暹罗记忆吗?、暹罗梦是什么做成的…
首先,Keras 中的批量规范化现在在我的黑魔法列表中😊。我将不得不更多地挖掘它是如何实现的,尤其是火车时间和预测时间之间的差异。很长一段时间,我一直在想为什么我得到了极好的训练损失和差的验证损失,直到我删除了输入层上的批处理规范化。所以,有些东西需要研究。
其次,我介绍了用于训练和验证数据的数据生成器。对于必须提供大量相似和不相似线对的连体网络方法,使用生成器在某些时候是必须掌握的!一旦掌握了要领,就相当方便了。我发现 Shervine Amidi 的博客:“一个关于如何使用 Keras 的数据生成器的详细示例”是一个很好的解释示例。我将把它推荐给任何学习 Keras 数据生成器的人。
在这个过程中,我发现我的 triplet_loss 函数(如前一篇文章所示)是有缺陷的…因为我用 Keras concatenate 打包基本神经网络输出的方式,我必须显式地指定范围。此外,我痛苦地了解到,Keras 中的损失函数传递的是一小批 y_true/y_pred 值,而不是单个值。嗯,这一点乍一看对我来说并不清楚…我还利用这个机会修改了逻辑,使用了更多的 Keras 方法而不是 TensorFlow(微妙的变化)。下面是新的损失函数。
第四个有趣的事情是,当我调试所有这些问题时,我觉得需要更好地可视化结果,而不是简单地查看预测值。我将输出向量空间从 10 维减少到 3 维,因为我现在没有太多不同的例子,所以 3D 应该足以将它们分开。此外,我更改了输出图层,使用 sigmoid 激活函数将输出空间限制在[0,1]范围内。这些变化反过来使我能够在变换的空间中查看预测点的位置,例如,交通模式现在对应于该输出空间中的 3D 位置。
下面我制作了一个视频,展示了这种投射是如何通过训练而演变的。最初,当神经网络用随机值初始化时,输出点在中心混杂在一起。但是很快我们看到它们被分开了,各自占据了空间的一角。当然,当神经网络试图找到一个更好的解决方案时,会有很多来回跳动,但我们可以看到,我们可以找到一个最佳点,在那里不同的流量模式可以很好地分开。顺便提一下,我们在这里看到了三种不同的流量模式。绿色表示正常流量,两种不同的错误情况,一种是红色表示所有流量都被阻塞,另一种是橙色表示我们达到了通信链路的容量极限。
现在,在从我们的测试平台获取更多数据的同时,我们正在尝试使用不同的损失函数来分离流量。我的一个同事刚刚发布了一个不同损失函数的比较:“无损三重损失”。我也可能尝试一些不同的损失函数,并展示我的发现。
我希望这表明,使用暹罗网络的一次性学习可以用于人脸识别以外的其他目的。在这种情况下,我们成功地将其用于信令流量分类和故障检测。
原载于 2018 年 2 月 13 日【thelonenutblog.wordpress.com。
封面照片由Jan-MallanderatPixabay。
在爱荷华州艾姆斯市买房,人们愿意支付什么
原文:https://towardsdatascience.com/how-to-predict-housing-prices-in-ames-iowa-991c35a4743?source=collection_archive---------16-----------------------
这可能是 Kaggle 上最受欢迎的测试你的第一个机器学习模型的比赛之一。你可以下载一个包含埃姆斯市房屋特征和价格信息的大型数据集,并使用它来建立一个可以预测同一城市房屋价格的机器学习模型!
为了构建这个模型,我使用了 Python,包括 Pandas、Numpy 和 Scikit-learn 库,以及用于绘图的 Seaborn 和 Matplotlib。
这个数据集有 2000 多行和大约 80 列,但并不是所有的都被填充了:第一个问题是大量丢失的数据!
有些人可能只是决定删除带有空单元格的行,或者如果缺少的值数量很大,甚至考虑删除整列。我决定不丢弃任何东西,而是试图理解数据集,并用有意义的东西填充空白点。例如,对于地块临街面,我决定使用相同街区内房屋的平均值来填充空白单元格
train['Lot Frontage'] = train.groupby('Neighborhood')['Lot Frontage'] = train.groupby('Neighborhood')['Lot Frontage'].transform(lambda x: fillna(x.mean())
其他分类单元格可能会填充模式值(通过使用上述相同的代码块并用mode()
替换mean()
),或者在有意义的地方填充 0s ,或者在某些分类列中填充 N/A 。
填完空单元格,就该来点 EDA 了!从这个数据集中可以观察到一些有趣的见解。
夏季,尤其是六月和七月的销售高峰。我对埃姆斯的天气不太熟悉,但我认为当外面天气温暖宜人时,人们会比在寒冷的月份里更容易搬到一个新地方。
另一件有趣的事情是社区是如何分布的(例如,它们有多受欢迎),以初步了解这是否是一个在最终确定房价时最终很重要的变量。
It appears that North Ames is the most popular by far, followed by College Creek and Old Town.
另一件值得关注的事情是目标变量的分布,在本例中是销售价格,因为这对构建回归模型的最终目的是有用的。分布是正偏的,这并不理想,因为它违反了线性回归所基于的正态假设,但这仍然是我们可以解决的问题。
是时候做模特了!但在直接切入之前,我试图将尽可能多的分类变量转换成数值,这样我的算法在计算上就可以尽可能简单。一些分类变量描述了一种质量(通常从差到优),在这种情况下,很容易用数字替换这些等级,即差对应 1,一般对应 2,依此类推……
所以我只定义了一个字典,类似cat_dict = {'Po':1, 'Fa':2, 'TA':3, 'Gd':4, 'Ex':5}
的东西,并把它传递到[.replace()](https://pandas.pydata.org/pandas-docs/stable/generated/pandas.Series.replace.html)
方法中,应用到相应的列中!在这之后,您可能会认为您已经完成了分类列的映射,但可能还没有!有趣的是,这些并不是唯一可以转换成数字的变量:例如,如果您看一下 MS 分区,这些值与销售价格相比是有序的,那么为什么不把它们也转换成数字呢?换句话说,像对待 FV 等于优和 A 或 I 等于差、一样对待他们,并相应地将所有区域排在中间。
This concept can be applied to a LOT of categorical variables: check out also Lot Shape, Lot Configuration, Masonry Type and so on.
剔除几个异常值,剔除剩余的分类变量,剔除所有相关系数销售价格低于 5%的预测因子后,真的是时候建模了!
别忘了训练/测试分裂!你想把你的模型放在训练集上,然后检查它在看不见的数据上的表现,也就是你的测试集。在处理大量的训练和测试数据时,该过程还可以帮助您防止过度拟合,并理解模型的偏差/方差权衡。我最终选择了 80/20 的比例,但 90/10 的表现还不错。
现在应该用什么型号?我给你一个提示:我尝试了经典的线性回归和岭,但最终选择了套索,因为它的表现要好得多。套索回归在这种情况下也非常有用,因为你有大量的变量要开始:这种方法特别激烈,可以帮助你更快地摆脱不太重要的预测因素!别忘了,Lasso 会要求你缩放你的数据(只有预测值,没有目标值!)所以惩罚因子在所有变量中可以是“公平”的。
这种方法的缺点是“选择”最佳超参数α。你不必真的突然选择它,最有可能的是你必须写一个算法为你做这件事。我刚学了[GridSearchCV](http://scikit-learn.org/stable/modules/generated/sklearn.model_selection.GridSearchCV.html)
这就是我用的!由于我不知道这个α的范围,也不想让我的笔记本电脑陷入几个小时的迭代中,我把研究分成了两部分:首先,我研究了一个范围更广的数字,这些数字的间隔相当大。一旦我找到了第一个最佳值,我就将研究进一步细分,在第一个最佳值周围划分成一个更密集的区间。我很惊讶,因为这只花了几分钟的迭代时间!那些不熟悉 GridSearch 的人可能不知道我在说什么,也因为我的解释不全面,但这是一个相当复杂的步骤,需要一篇博文,也许我会写一篇。或者,您可以使用[LassoCV](http://scikit-learn.org/stable/modules/generated/sklearn.linear_model.LassoCV.html)
来找到您的最佳参数:它没有那么强大,但仍然适合这个目的。
一旦您找到您的超参数,您就可以实例化并拟合您的模型了!我的套索回归让我从最初的 179 个参数中去掉了 83 个,非常棒!此外,有趣的是,我的获胜特征是我自己设计的!在初始数据集中,有 4 列关于平方英尺的数据:一楼、二楼、地上(一楼和二楼的总和)和地下室。我删除了所有这些列,并创建了一个新的列:总平方英尺数等于地面面积加上地下室面积的,这最终成为确定埃姆斯一所房子最终价格的最重要的特征!
Absolute values of the top 20 predictors of Lasso regression.
在第二名和第三名我们分别找到了总体质量和年造,这很有意义。当然,并不是所有的顶级预测都是积极的:一些其他变量也可能非常强烈地降低房价。第四,事实上,我们可以看到一个未完工的地下室的面积和房子的价格是负相关的。如果说我从这个项目中学到了什么,那就是埃姆斯的人们真的很喜欢他们的地下室和车库!
最后,我的第一个模型完成了,我的训练集和测试集的交叉验证分数分别为 90.2%和 88.6%,非常好!事实上,训练分数比测试分数略高,这意味着模型稍微有些过拟合,所以对于未来的发展,我会考虑放弃更多的变量,或者在训练/测试比率上多下一点功夫。我还将实现一些多项式特性,并尝试对数转换正偏差的变量(使与目标的关系“更加线性”),看看结果如何!
如何用 Python 和递归神经网络预测严重堵车?
原文:https://towardsdatascience.com/how-to-predict-severe-traffic-jams-with-python-and-recurrent-neural-networks-e53b6d411e8d?source=collection_archive---------9-----------------------
利用 Python 和 Keras 实现序列模型在交通事件 Waze 开放数据挖掘中的应用。
在本教程中,我将向您展示如何使用 RNN 深度学习模型从事件报告的 Waze 交通开放数据中发现模式,并预测严重的交通堵塞是否会很快发生。干预是可以有效取出的。
竞争
2018 年 12 月 1 日,我在德克萨斯州弗里斯科的 UNT 灵感公园参加了一场黑客马拉松编程比赛。黑客马拉松被称为“HackNTX”。
黑客马拉松从早上 8 点开始,到晚上 9 点结束。参与者可以自由地吃零食和水果,在院子里散步,呼吸新鲜空气,晒晒太阳。此外,人们可以自由地交谈、讨论和组建团队(每个团队不超过 5 人)。
主持人向参赛者提供了各种开放数据集,以及一些预定义的演示问题。你可以选择自己的新问题,在竞赛中解决。
Waze 数据是提供的数据集之一。
在国内,我从来不用 Waze App 导航。对我来说是新的。
我谷歌了一下,发现了 Waze 的特征。它不仅可以为用户提供普通的导航功能,还可以让用户报告交通事件,以便其他用户可以相应地调整他们的路线。
对我来说,最重要的特点是,当你被困在交通堵塞时,你可以准确地知道前面发生了什么,如道路施工,或车祸。在这种情况下,你将能够有一个更好的估计,冷静下来。这对你的健康有好处。
从几年前开始,Waze 与政府合作,开始共享数据。对于政府来说,他们可以从即时的交通状况报告中受益,并及时对事件做出响应。对于 Waze 平台来说,它可以整合政府开放的数据,如道路规划,以改善其路由功能,让用户更快乐。
HackNTX 的主办方提供的 Waze 数据是关于 DFW 地区从 11 月 1 日到 11 月 29 日的交通事件。
原始数据为 TSV 格式,总大小约为 300 兆字节。
每行代表一个事件报告,包含坐标和时间戳。
在探索性数据分析阶段,我根据数据进行了几次可视化。
第一次听说 QGIS,软件很强大。谢谢杰西教我如何使用它!
在上面的截图中,你可以看到每个点代表一个事件。他们人太多了!
由于我对 QGIS 不太熟悉,Jesse 在下午早些时候离开了比赛,我不得不回去使用 Python 进行详细的可视化。
上图是用 Python 的 Geopandas 包制作的。它显示了三种不同类型的交通事件,即交通堵塞(红色)、事故(黄色)和“路肩停车”(蓝色)。请注意,它们仅从数据集中的前 3000 行中提取。
正如你可能已经发现的,红点的数量(意味着交通堵塞)是巨大的。交通堵塞确实是一个大问题。
我从数据中提取了所有独特的事件类型,得到了以下列表:
我们可能知道,交通堵塞可以分为几个不同的级别。最严重的是“大塞车”和“大塞车”。
我把这两类事件合并成一个集合 a .而其他事件可以看作是集合 b。
对于集合 A 中的每个事件,我回溯 30 分钟,并将同一条路上报告的每个事件累积到一个序列中。总共有 987 个。然而,其中一些是空列表,意味着在严重堵塞之前没有任何报告,而且它发生得非常突然。对于这种堵车,没人能预测,所以我决定去掉,保留了 861 个非空序列。
类似地,我通过回溯来自集合 b 的事件随机提取了 861 个非空序列。注意这些序列没有导致严重的交通堵塞。
现在我们已经得到了作为输入数据的序列,我们将从集合 A 生成的序列标记为 1,而其他的标记为 0。
我们的研究问题是,能不能用一个模型对这些序列数据进行分类?
结果证明是成功的。我们获得了一等奖!
我们的团队,昵称为“守望饺子”,由来自武汉大学的访问博士生王春英和我组成,代表实验室。我们每个人都得到了 100 美元。看我们多开心啊!
HackNTX 的网站很快就对黑客马拉松比赛进行了报道。这里是环节。
几天后,UNT 也向报告了这个消息。
对我来说,获得一等奖几乎完全是运气。然而,我认为该模型具有潜在的实用价值。
在本文的后面部分,我将尝试向您展示如何使用 Python 和 Keras 实现 RNN 模型来对 Waze 事件序列进行分类。
环境
要做深度学习,你需要 GPU 或者 TPU,否则你的笔记本电脑会被折磨。我带着没有风扇的 Macbook 去参加比赛,我没有办法用它来训练深度神经网络。
我用了谷歌 Colab。这很酷,谷歌人很慷慨,为用户提供免费的 GPU 和 TPU。
请先下载安装 Google Chrome,然后点击这个链接,安装一个名为 Colaboratory 的插件。
你会在 Chrome 的扩展栏中看到它的黄色图标。
我已经把这个教程的所有代码和数据上传到了这个 github repo 上。
请点击上面的链接,并点击demo.ipynb
。
现在你可以点击 Colaboratory 的图标,Chrome 会自动为你打开 Google Colab,将这个 ipynb 文件加载进去。
点击上面截图中我用红色圈出的“复制到驱动器”按钮,Google 会在你的 Google Drive 上为你创建一份 Jupyter 笔记本文件的副本。
进入“运行时”菜单,点击“更改运行时类型”。
仔细检查选项是否设置如下:
保存,然后就万事俱备了。
要运行一段代码,只需点击左侧的运行按钮。
让我们一步一步来,我会给你必要的解释。
密码
我们需要加载 Pandas 包来处理表格数据。
import pandas as pd
我们将需要另一个包来加载预处理阶段保存的数据。它叫泡菜。
import pickle
它可以将单个或多个 Python 数据保存到外部文件中。当您将它加载回程序中时,它会将数据恢复为保存时的状态。在这种情况下,它比用 CSV 文件交换数据更容易、更高效。
让我们克隆本教程的 github repo,并将数据放入 Google Colab workspace。
!git clone [https://github.com/wshuyi/demo_traffic_jam_prediction.git](https://github.com/wshuyi/demo_traffic_jam_prediction.git)
数据没那么大,不一会就下载完了。
Cloning into 'demo_traffic_jam_prediction'...
remote: Enumerating objects: 6, done.[K
remote: Counting objects: 100% (6/6), done.[K
remote: Compressing objects: 100% (4/4), done.[K
remote: Total 6 (delta 0), reused 3 (delta 0), pack-reused 0[K
Unpacking objects: 100% (6/6), done.
让我们告诉 Jupyter 笔记本数据文件夹的路径。
from pathlib import Path
data_dir = Path('demo_traffic_jam_prediction')
我们将打开数据文件并用 pickle 加载两个不同的数据变量。
with open(data_dir / 'data.pickle', 'rb') as f:
[event_dict, df] = pickle.load(f)
首先,让我们看看名为event_dict
的事件字典:
event_dict
以下是所有的事件类型。
{1: 'road closed due to construction',
2: 'traffic jam',
3: 'stopped car on the shoulder',
4: 'road closed',
5: 'other',
6: 'object on roadway',
7: 'major event',
8: 'pothole',
9: 'traffic heavier than normal',
10: 'road construction',
11: 'fog',
12: 'accident',
13: 'slowdown',
14: 'stopped car',
15: 'small traffic jam',
16: 'stopped traffic',
17: 'heavy traffic',
18: 'minor accident',
19: 'medium traffic jam',
20: 'malfunctioning traffic light',
21: 'missing sign on the shoulder',
22: 'animal on the shoulder',
23: 'animal struck',
24: 'large traffic jam',
25: 'hazard on the shoulder',
26: 'hazard on road',
27: 'ice on roadway',
28: 'weather hazard',
29: 'flooding',
30: 'road closed due to hazard',
31: 'hail',
32: 'huge traffic jam'}
然后,让我们看看数据帧中的df
是什么。
这是一张相当长的桌子。让我们只显示前 10 行。
df.head(10)
在每一行中,都有一个相应的标签,显示数据序列之后是否有严重的交通堵塞事件。
然后我们会让熊猫给我们展示最后 10 排。
df.tail(10)
现在我们已经正确地加载了数据,我们将看到哪一行包含最长的序列。
我们将使用来自 Pandas 的一个名为idxmax()
的函数,它将帮助我们获得最大值的索引。
max_len_event_id = df.events.apply(len).idxmax()
max_len_event_id
结果如下:
105
让我们深入了解这一行的顺序:
max_len_event = df.iloc[max_len_event_id]
max_len_event.events
结果是一个相当长的列表。
['stopped car on the shoulder',
'heavy traffic',
'heavy traffic',
'heavy traffic',
'slowdown',
'stopped traffic',
'heavy traffic',
'heavy traffic',
'heavy traffic',
'heavy traffic',
'traffic heavier than normal',
'stopped car on the shoulder',
'traffic jam',
'heavy traffic',
'stopped traffic',
'stopped traffic',
'stopped traffic',
'heavy traffic',
'traffic jam',
'stopped car on the shoulder',
'stopped traffic',
'stopped traffic',
'stopped traffic',
'heavy traffic',
'traffic heavier than normal',
'traffic heavier than normal',
'traffic heavier than normal',
'traffic heavier than normal',
'heavy traffic',
'stopped traffic',
'traffic heavier than normal',
'pothole',
'stopped car on the shoulder',
'traffic jam',
'slowdown',
'stopped traffic',
'heavy traffic',
'traffic heavier than normal',
'traffic jam',
'traffic jam',
'stopped car on the shoulder',
'major event',
'traffic jam',
'traffic jam',
'stopped traffic',
'heavy traffic',
'traffic heavier than normal',
'stopped car on the shoulder',
'slowdown',
'heavy traffic',
'heavy traffic',
'stopped car on the shoulder',
'traffic jam',
'slowdown',
'slowdown',
'heavy traffic',
'stopped car on the shoulder',
'heavy traffic',
'minor accident',
'stopped car on the shoulder',
'heavy traffic',
'stopped car on the shoulder',
'heavy traffic',
'stopped traffic',
'heavy traffic',
'traffic heavier than normal',
'heavy traffic',
'stopped car on the shoulder',
'traffic heavier than normal',
'stopped traffic',
'heavy traffic',
'heavy traffic',
'heavy traffic',
'stopped car on the shoulder',
'slowdown',
'stopped traffic',
'heavy traffic',
'stopped car on the shoulder',
'traffic heavier than normal',
'heavy traffic',
'minor accident',
'major event',
'stopped car on the shoulder',
'stopped car on the shoulder']
如果你仔细检查序列,你会注意到这条路上有严重交通堵塞的迹象。然而,你需要让机器获得“感觉”并自动对序列进行分类。
最长的序列有多长?
maxlen = len(max_len_event.events)
maxlen
下面是答案:
84
哇!这是一个长长的事件列表!
电脑不擅长读取事件名称。让我们试着把名字转换成数字,这样计算机就能更好地处理这个问题。
为了有效地做到这一点,我们需要反转之前加载的字典。即尝试将“索引:事件类型”格式转换为“事件类型:索引”。
reversed_dict = {}
for k, v in event_dict.items():
reversed_dict[v] = k
让我们检查一下翻过来的字典。
reversed_dict
这是结果。
{'accident': 12,
'animal on the shoulder': 22,
'animal struck': 23,
'flooding': 29,
'fog': 11,
'hail': 31,
'hazard on road': 26,
'hazard on the shoulder': 25,
'heavy traffic': 17,
'huge traffic jam': 32,
'ice on roadway': 27,
'large traffic jam': 24,
'major event': 7,
'malfunctioning traffic light': 20,
'medium traffic jam': 19,
'minor accident': 18,
'missing sign on the shoulder': 21,
'object on roadway': 6,
'other': 5,
'pothole': 8,
'road closed': 4,
'road closed due to construction': 1,
'road closed due to hazard': 30,
'road construction': 10,
'slowdown': 13,
'small traffic jam': 15,
'stopped car': 14,
'stopped car on the shoulder': 3,
'stopped traffic': 16,
'traffic heavier than normal': 9,
'traffic jam': 2,
'weather hazard': 28}
我们成功了。
现在我们需要构造一个函数,来转换事件列表,并返回给我们一个数字列表。
def map_event_list_to_idxs(event_list):
list_idxs = []
for event in (event_list):
idx = reversed_dict[event]
list_idxs.append(idx)
return list_idxs
让我们试试最长列表中的函数。
map_event_list_to_idxs(max_len_event.events)
结果是:
[3,
17,
17,
17,
13,
16,
17,
17,
17,
17,
9,
3,
2,
17,
16,
16,
16,
17,
2,
3,
16,
16,
16,
17,
9,
9,
9,
9,
17,
16,
9,
8,
3,
2,
13,
16,
17,
9,
2,
2,
3,
7,
2,
2,
16,
17,
9,
3,
13,
17,
17,
3,
2,
13,
13,
17,
3,
17,
18,
3,
17,
3,
17,
16,
17,
9,
17,
3,
9,
16,
17,
17,
17,
3,
13,
16,
17,
3,
9,
17,
18,
7,
3,
3]
现在我们从 Keras 加载 numpy 和一些实用函数。
import numpy as np
from keras.utils import to_categorical
from keras.preprocessing.sequence import pad_sequences
我们需要弄清楚我们有多少不同的事件类型。
len(event_dict)
结果如下:
32
让我们把所有的事件顺序转换成数字列表。
df.events.apply(map_event_list_to_idxs)
结果是:
0 [9, 17, 18, 14, 13, 17, 3, 13, 16, 3, 17, 17, ...
1 [2, 10, 3]
2 [2]
3 [2]
4 [2, 2, 2, 2, 2, 2, 2, 9]
5 [3, 2, 17]
6 [3, 2, 17]
7 [2, 15, 2, 17, 2, 2, 13, 17, 2]
8 [17, 2, 2, 16, 17, 2]
9 [17, 2, 2, 16, 17, 2]
10 [17, 16, 17, 2, 17, 3, 17, 17, 16, 17, 16, 18,...
11 [17]
12 [17]
13 [24, 24]
14 [24, 2, 24, 24, 2]
15 [24, 2, 24, 24, 2]
16 [2, 10, 2, 2, 2, 18, 16, 16, 7, 2, 16, 2, 2, 9...
17 [2, 10, 2, 2, 2, 18, 16, 16, 7, 2, 16, 2, 2, 9...
18 [24, 24, 24, 16, 2, 16]
19 [24, 24, 24, 16, 2, 16]
20 [2, 2]
21 [2, 16, 2]
22 [2, 16, 2]
23 [2, 2]
24 [2, 2]
25 [24, 24]
26 [2, 2]
27 [2, 2, 2, 17]
28 [2, 19, 2]
29 [24]
...
831 [9, 9, 9, 2, 9, 9, 17, 2, 9, 17]
832 [3, 3, 3]
833 [2, 9, 2, 17, 17, 2]
834 [3, 3, 17, 3, 13, 3, 3, 23, 9, 3, 3, 25, 3, 3]
835 [3, 17, 9, 14, 9, 17, 14, 9, 2, 9, 3, 2, 2, 17]
836 [2]
837 [17, 2, 16, 3, 9, 17, 17, 17, 13, 17, 9, 17]
838 [13, 17, 17, 3, 3, 16, 17, 16, 17, 16, 3, 9, 1...
839 [2]
840 [3]
841 [2]
842 [17, 17, 17, 3, 17, 23, 16, 17, 17, 3, 2, 13, ...
843 [3, 3]
844 [2]
845 [2, 17, 2, 2, 2, 2, 2, 17, 2, 2]
846 [7, 17, 3, 18, 17]
847 [3, 3, 3]
848 [2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, ...
849 [2, 2]
850 [2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 13, 3, 2]
851 [2, 2, 2]
852 [16, 2, 16]
853 [3, 16, 5, 3, 17, 3, 16, 9, 3, 2, 17]
854 [16]
855 [3, 3, 3, 3, 3, 3, 3, 3, 2, 13, 3, 6, 3, 6, 3,...
856 [17, 17, 17, 2, 3, 2, 2, 2, 2, 2]
857 [2, 2]
858 [2, 2, 9, 17, 2, 2]
859 [17, 3, 2, 2, 2, 2, 2, 2]
860 [17, 3, 3, 17, 3, 17, 2, 3, 18, 14, 3, 3, 16, ...
Name: events, Length: 1722, dtype: object
作为人类,我们很难识别每个数字所代表的意义。但是,对于计算机来说,就容易多了。
我们将结果列表命名为sequences
,显示前五行。
sequences = df.events.apply(map_event_list_to_idxs).tolist()
sequences[:5]
结果如下:
[[9,
17,
18,
14,
13,
17,
3,
13,
16,
3,
17,
17,
16,
3,
16,
17,
9,
17,
2,
17,
2,
7,
16,
17,
17,
17,
17,
13,
5,
17,
9,
9,
16,
16,
3],
[2, 10, 3],
[2],
[2],
[2, 2, 2, 2, 2, 2, 2, 9]]
注意第一行比后面几行长得多。
然而,要对数据应用序列模型,我们需要确保所有输入序列共享相同的长度。因此,我们使用最长序列的长度作为最大长度,并从开始用 0 填充其他较短的序列。
data = pad_sequences(sequences, maxlen=maxlen)
data
以下是填充序列:
array([[ 0, 0, 0, ..., 16, 16, 3],
[ 0, 0, 0, ..., 2, 10, 3],
[ 0, 0, 0, ..., 0, 0, 2],
...,
[ 0, 0, 0, ..., 17, 2, 2],
[ 0, 0, 0, ..., 2, 2, 2],
[ 0, 0, 0, ..., 3, 3, 2]], dtype=int32)
现在所有的序列都有相同的长度。
我们需要获取标签列,并将其保存到一个名为labels
的变量中。
labels = np.array(df.label)
因为我们需要使用几个随机函数,为了保持您的运行结果与我的相同,我们将随机种子值指定为 12。
np.random.seed(12)
当您完成代码的第一次运行时,可以随意修改它。
我们把这些序列和它们相应的标签混在一起。
indices = np.arange(data.shape[0])
np.random.shuffle(indices)
data = data[indices]
labels = labels[indices]
训练集将包含 80%的数据,而另外 20%将进入验证集。
training_samples = int(len(indices) * .8)
validation_samples = len(indices) - training_samples
下面的代码将数据与标签一起分为定型集和验证集。
X_train = data[:training_samples]
y_train = labels[:training_samples]
X_valid = data[training_samples: training_samples + validation_samples]
y_valid = labels[training_samples: training_samples + validation_samples]
让我们展示训练数据的内容:
X_train
这是结果。
array([[ 0, 0, 0, ..., 15, 15, 3],
[ 0, 0, 0, ..., 0, 2, 2],
[ 0, 0, 0, ..., 0, 0, 16],
...,
[ 0, 0, 0, ..., 2, 15, 16],
[ 0, 0, 0, ..., 2, 2, 2],
[ 0, 0, 0, ..., 0, 0, 2]], dtype=int32)
请注意,当我们用 0 填充序列作为填充值时,现在我们有 33 个事件类型,而不是 32 个。
因此事件类型的数量将被设置为 33。
num_events = len(event_dict) + 1
如果我们简单地把数字放入分类模型,它会把每个数字看作一个连续的值。然而,事实并非如此。因此,我们将让数字通过一个嵌入层,并将每个数字(代表某种类型的事件)转换为一个向量。每个向量将包含 20 个标量。
embedding_dim = 20
初始嵌入矩阵将随机生成。
embedding_matrix = np.random.rand(num_events, embedding_dim)
最后,我们现在可以建立一个模型。
我们使用 Keras 中的顺序模型,一层一层地放置不同的层,就像我们玩乐高一样。
第一层是嵌入层,然后是 LSTM 层,最后一层是稠密层,其激活函数是 sigmoid,进行二值分类。
from keras.models import Sequential
from keras.layers import Embedding, Flatten, Dense, LSTM
units = 32
model = Sequential()
model.add(Embedding(num_events, embedding_dim))
model.add(LSTM(units))
model.add(Dense(1, activation='sigmoid'))
如果你对 Keras 不熟悉,推荐你读一读 Keras 的创建者 Franç ois Chollet 的《用 Python 进行深度学习》。
下一步是处理嵌入层中的参数。目前,我们只是加载随机生成的初始嵌入矩阵,不会让训练过程改变嵌入层的权重。
model.layers[0].set_weights([embedding_matrix])
model.layers[0].trainable = False
然后,我们训练模型,并将模型保存到 h5 文件中。
model.compile(optimizer='rmsprop',
loss='binary_crossentropy',
metrics=['acc'])
history = model.fit(X_train, y_train,
epochs=50,
batch_size=32,
validation_data=(X_valid, y_valid))
model.save("mymodel_embedding_untrainable.h5")
在 TPU 的大力支持下,训练速度相当快。
模型训练完成后,让我们用 matplotlib 可视化精度和损耗的曲线。
import matplotlib.pyplot as plt
acc = history.history['acc']
val_acc = history.history['val_acc']
loss = history.history['loss']
val_loss = history.history['val_loss']
epochs = range(1, len(acc) + 1)
plt.plot(epochs, acc, 'bo', label='Training acc')
plt.plot(epochs, val_acc, 'b', label='Validation acc')
plt.title('Training and validation accuracy')
plt.legend()
plt.figure()
plt.plot(epochs, loss, 'bo', label='Training loss')
plt.plot(epochs, val_loss, 'b', label='Validation loss')
plt.title('Training and validation loss')
plt.legend()
plt.show()
这是精确度曲线。
如你所见,还不错。如果我们使用虚拟模型来预测标签为 0 的所有内容(或所有内容为 1),精确度将保持在 0.50。很明显,我们的模型捕捉到了一些模式,并且比虚拟模型表现得更好。
但是,它很不稳定。
然后让我们看看损失曲线。
你可能会发现,这并不好。当训练损失下降时,验证集的损失上升,并且没有明显的收敛趋势。
更重要的是找出原因。
注意,我们使用了一个随机初始化的嵌入矩阵,它在训练阶段保持不变。这可能会给我们带来麻烦。
下一步,我们可以做一个实验来训练和调整嵌入层。
from keras.models import Sequential
from keras.layers import Embedding, Flatten, Dense, LSTM
units = 32
model = Sequential()
model.add(Embedding(num_events, embedding_dim))
model.add(LSTM(units))
model.add(Dense(1, activation='sigmoid'))
代码中唯一不同的是,参数trainable
被设置为True
。
model.layers[0].set_weights([embedding_matrix])
model.layers[0].trainable = True
让我们编译这个模型,再运行一遍。
model.compile(optimizer='rmsprop',
loss='binary_crossentropy',
metrics=['acc'])
history = model.fit(X_train, y_train,
epochs=50,
batch_size=32,
validation_data=(X_valid, y_valid))
model.save("mymodel_embedding_trainable.h5")
我们还绘制了精度曲线和损耗曲线。
import matplotlib.pyplot as plt
acc = history.history['acc']
val_acc = history.history['val_acc']
loss = history.history['loss']
val_loss = history.history['val_loss']
epochs = range(1, len(acc) + 1)
plt.plot(epochs, acc, 'bo', label='Training acc')
plt.plot(epochs, val_acc, 'b', label='Validation acc')
plt.title('Training and validation accuracy')
plt.legend()
plt.figure()
plt.plot(epochs, loss, 'bo', label='Training loss')
plt.plot(epochs, val_loss, 'b', label='Validation loss')
plt.title('Training and validation loss')
plt.legend()
plt.show()
准确度曲线如下所示。
如你所见,情况有所好转。验证准确度曲线波动下降,验证准确度高于 0.75。
这种模式在某种程度上更有价值。
但是,我们不应该这么快就下结论。如果你观察亏损曲线,你就不会这么乐观了。
从中途开始,不同盘的损失趋势走向不同的方向。
这是一种过度拟合的暗示。
过度拟合总是表明训练数据对于复杂模型来说是不够的。
你可以为训练增加更多的数据,或者降低复杂度。
第一种方法现在不太适用,因为我们只有 11 月份 29 天的数据集。
然而,要降低模型的复杂性,可以通过 Dropout 轻松实现。
当你使用 Dropout 时,模型会随机选取一定比例(你说了算)的神经元,在训练阶段将它们的权重设置为零,这样就可以将它们视为从网络中“移除”,复杂度变低了。
注意在验证阶段,模型将使用所有神经元,没有任何遗漏。
我们将添加两个与辍学相关的参数。为此,我们在定义 LSTM 层时使用dropout=0.2, recurrent_dropout=0.2
。
from keras.models import Sequential
from keras.layers import Embedding, Flatten, Dense, LSTM
units = 32
model = Sequential()
model.add(Embedding(num_events, embedding_dim))
model.add(LSTM(units, dropout=0.2, recurrent_dropout=0.2))
model.add(Dense(1, activation='sigmoid'))
我们将保持嵌入层的参数trainable
为True
。
model.layers[0].set_weights([embedding_matrix])
model.layers[0].trainable = True
让我们再进行一次训练。
model.compile(optimizer='rmsprop',
loss='binary_crossentropy',
metrics=['acc'])
history = model.fit(X_train, y_train,
epochs=50,
batch_size=32,
validation_data=(X_valid, y_valid))
model.save("mymodel_embedding_trainable_with_dropout.h5")
可视化部分没有修改。
import matplotlib.pyplot as plt
acc = history.history['acc']
val_acc = history.history['val_acc']
loss = history.history['loss']
val_loss = history.history['val_loss']
epochs = range(1, len(acc) + 1)
plt.plot(epochs, acc, 'bo', label='Training acc')
plt.plot(epochs, val_acc, 'b', label='Validation acc')
plt.title('Training and validation accuracy')
plt.legend()
plt.figure()
plt.plot(epochs, loss, 'bo', label='Training loss')
plt.plot(epochs, val_loss, 'b', label='Validation loss')
plt.title('Training and validation loss')
plt.legend()
plt.show()
从准确度曲线上,你可能看不到什么令人兴奋的东西。
然而,当你观察损失曲线时,你会看到显著的改善。
验证损失曲线更平滑,更接近训练损失的趋势。
过度拟合的问题已经得到了解决,模型现在更加稳定,并且可以推广到看不见的数据。
然后,交通管理部门可以使用该模型,通过事件报告的 Waze 开放数据来预测严重交通堵塞的发生。模型精度的期望值约为 75%。
也许这样一来,由于这些预防措施,一些严重的交通堵塞就不会发生了。
摘要
希望你能从这篇教程中得到以下几点。
- 序列模型,如 RNN 和 LSTM,不仅可以用于文本,也可以用于其他序列数据。
- 您可以在这类任务中使用嵌入层,即使它们没有预先训练的单词嵌入模型,如 word2vec、glove 或 fasttext。确保您设置了嵌入层的权重可训练。
- 你可以尝试用几种不同的方法来克服过度拟合。辍学就是其中之一。在我们的情况下,它是有效的。
希望您现在可以用顺序数据处理自己的分类任务。
快乐深度学习!
我关于深度学习的其他教程:
- 使用 Python 和 fast.ai 的深度学习,第 1 部分:使用预训练模型的图像分类
- 使用 Python 和 fast.ai 的深度学习,第 2 部分:使用迁移学习的 NLP 分类
- Python 深度学习,第 0 部分:在 Google Cloud 上设置 fast . ai 1.0
- 如何用云 GPU 加速你的 Python 深度学习?
如何准备机器学习面试
原文:https://towardsdatascience.com/how-to-prepare-for-machine-learning-interviews-5fac3db58168?source=collection_archive---------8-----------------------
机器学习的机会可能很少,所以当你最终被邀请参加期待已久的机器学习面试时,你希望它能完美进行。让我告诉你怎么做。
这个故事最初出现在上。
寻找机会
机器学习工作没有现成的来源,许多都分布在通用工作公告栏中,包括:
- AngelList(创业公司)
- 的确
- RemoteML(远程位置)
可以说,写你的申请和组织你的简历是完全不同的一件事,所以我们暂时不讨论这个。抓住所有让你感兴趣的机会,不要等一个机会有了反馈再去找下一个,很快你就会找到下一个机会。
初亏
是时候了!你申请已经有几天了,但是一位招聘经理终于联系到你,和你讨论下一步的工作。这已经是第一次给人留下好的第一印象的机会了。
- 在适当的时间范围内回答(< 24 小时)
- 让招聘经理选择适合你的时间和日期
- 巧妙地告诉他们你对这个机会感到高兴/兴奋
这些对你来说可能是显而易见的,但这些事情已经暗示了你对这个机会有多兴奋,如果你是一个有条理的人,以及你如何沟通。有了这些建议,记住一件事:保持微妙。没有理由在经理发出邮件后几秒钟就回复,也没有理由使用一个以上的“!”在你的判决之后。
准备
如前所述,第一次面试主要是看你和公司是否合适的一种方式。在某些情况下,第一次面试可能已经是一个技术筛选,但这并不常见。
在这次面试中,你必须推销自己。让招聘经理尽可能容易地发现你的才能。研究一下这家公司做什么,你能在哪里工作。在某些情况下,公司可能会问你“我们公司的什么让你感到兴奋?”。如果你不知道他们的产品,这可能是一个将军。
- 研究公司做什么
- 看看他们的团队成员是谁
- 自己找出你可能适合的地方
- 看看你的技能和他们的需求是否匹配
- 为你真正想知道的事情准备问题
面试
在许多情况下,这将是一个电话/视频屏幕,所以请确保您在一个安静的空间,有稳定的互联网连接和一个良好的麦克风。对于招聘经理来说,没有什么比缓冲视频流、回声或背景噪音更令人恼火的了。然后面试开始了..
此时,做好自己就好。你已经为技术细节做好了准备,但剩下的就是你自己了。许多公司都想了解你的性格、个性甚至幽默。保持冷静和放松,如果情况合适,暗示你已经准备好的东西。不要违背谈话的自然流程来推销自己,因为这听起来非常做作和不诚实。
在大多数情况下,你也会有时间问问题。一定要事先准备好这些并且只问自己想知道的问题,不要准备自己不关心的填充题。说自己没有任何问题也不丢人。机器学习的好问题可能包括:
- 有多少团队成员?
- 你用什么硬件?
- 你也做数据标签吗?
- ML 工程师必须在某个地方集成他们的模型吗?
追踪
面试结束后,有时发一封电子邮件(可能一天后)来感谢他们的时间,告诉他们你是否喜欢这次面试,这是一个不错的惊喜。这也提醒他们跟进你,也许会有更多的面试。
现在怎么办?
大多数公司的招聘流程包括两次、三次或更多次面试(提示:只有一次面试是一个巨大的危险信号)。这些面试很可能是技术性的,所以如果你知道这家公司是做什么的(例如计算机视觉),而你在这方面有点生疏,一定要复习这些方面的知识。
在很多情况下,如果你通过了第一次面试,并且在机器学习方面有很好的技能,你就不必担心。有时行得通,有时行不通。为了测试你是否有好的技能,你可以试着做一些基本的 ML 面试问题。如果你全部(或至少大部分)答对了,那就出去看看你能做什么!
如何用 Keras 预处理字符级文本
原文:https://towardsdatascience.com/how-to-preprocess-character-level-text-with-keras-349065121089?source=collection_archive---------8-----------------------
你可以在这里找到笔记本
这篇简介的目的是让您了解如何使用 Keras 在字符级预处理文本。文章的其余部分组织如下。
- 加载数据
- 标记器
- 改变词汇
- 要索引的字符
- 填料
- 获取标签
加载数据
首先,我们使用 pandas 加载训练数据。
将第 1 列和第 2 列合并为一个文本。
标记器
将第 1 列保存到texts
,并将所有句子转换为小写。
初始化记号赋予器时,只有两个参数很重要。
char_level=True
:这可以告诉tk.texts_to_sequences()
在字符级处理句子。oov_token='UNK'
:这将在词汇表中添加一个 UNK 令牌。我们可以用tk.oov_token
来称呼它。
在调用tk.fit_on_texts(texts)
之后,tk
类将包含关于训练数据的必要信息。我们可以调用tk.word_index
来查看字典。这里UNK
的索引是word_count+1
。
这是从训练数据中学习到的字符字典。但是如果我们已经有一个角色列表,我们必须改变tk_word_index
。
改变词汇
看到我已经有一个角色列表调用alphabet
,我们基于alphabet
构建一个char_dict
。
我们将为UNK
分配一个新的索引。
要索引的字符
在我们得到正确的词汇后,我们可以用字符索引来表示所有的文本。
这一步非常简单,tk.texts_to_sequences()
会为我们自动完成这个转换。
我们可以看到字符串表示被索引表示所取代。我们列出了前 5 个句子长度。
填料
因为文本有不同的长度,我们必须使所有的文本长度相同,这样 CNN 就可以处理批量数据。
这里我们将最大句子长度设置为 1014。如果文本的长度小于 1014,则该部分的其余部分将被填充为 0。如果文本长度大于 1014,超过 1014 的部分将被截断。因此所有文本将保持相同的长度。
最后,我们将列表转换成 Numpy 数组。
获取标签
首先,我们将train_df
中的第 0 列分配给一个class_list
,这个一维列表包含每个文本的所有标签。但是我们的任务是一个多类任务,所以我们必须把它转换成一个二维数组。这里我们可以使用 Keras 中的to_categorical
方法
至于测试数据集,我们只需要再次执行相同的过程。
摘要
为了方便使用,我将所有代码加在一起。
*# write all code in one cell#========================Load data=========================
import numpy as np
import pandas as pdtrain_data_source = '../data/ag_news_csv/train.csv'
test_data_source = '../data/ag_news_csv/test.csv'train_df = pd.read_csv(train_data_source, header=None)
test_df = pd.read_csv(test_data_source, header=None)# concatenate column 1 and column 2 as one text
for df in [train_df, test_df]:
df[1] = df[1] + df[2]
df = df.drop([2], axis=1)
# convert string to lower case
train_texts = train_df[1].values
train_texts = [s.lower() for s in train_texts]test_texts = test_df[1].values
test_texts = [s.lower() for s in test_texts]#=======================Convert string to index================
from keras.preprocessing.text import Tokenizer
from keras.preprocessing.sequence import pad_sequences# Tokenizer
tk = Tokenizer(num_words=None, char_level=True, oov_token='UNK')
tk.fit_on_texts(train_texts)
# If we already have a character list, then replace the tk.word_index
# If not, just skip below part#-----------------------Skip part start--------------------------
# construct a new vocabulary
alphabet="abcdefghijklmnopqrstuvwxyz0123456789-,;.!?:'\"/\\|_@#$%^&*~`+-=<>()[]{}"
char_dict = {}
for i, char in enumerate(alphabet):
char_dict[char] = i + 1
# Use char_dict to replace the tk.word_index
tk.word_index = char_dict
# Add 'UNK' to the vocabulary
tk.word_index[tk.oov_token] = max(char_dict.values()) + 1
#-----------------------Skip part end----------------------------# Convert string to index
train_sequences = tk.texts_to_sequences(train_texts)
test_texts = tk.texts_to_sequences(test_texts)# Padding
train_data = pad_sequences(train_sequences, maxlen=1014, padding='post')
test_data = pad_sequences(test_texts, maxlen=1014, padding='post')# Convert to numpy array
train_data = np.array(train_data)
test_data = np.array(test_data)#=======================Get classes================
train_classes = train_df[0].values
train_class_list = [x-1 for x in train_classes]test_classes = test_df[0].values
test_class_list = [x-1 for x in test_classes]from keras.utils import to_categorical
train_classes = to_categorical(train_class_list)
test_classes = to_categorical(test_class_list)*
查看我的其他帖子 中等 同 一分类查看 !
GitHub:bramble Xu LinkedIn:徐亮 博客:bramble Xu
如何给一个人工智能项目定价
原文:https://towardsdatascience.com/how-to-price-an-ai-project-f7270cb630a4?source=collection_archive---------2-----------------------
客户多次要求我为大型机器学习(ML)项目提供固定的价格估计。这真的很棘手。需求经常会在项目进行到一半时发生变化,这是由于功能蔓延、开发延误、集成问题、用户接受度和许多其他因素造成的。我建议客户而不是在他们的第一个 ML 项目中对抗需求变更,这与传统的软件开发原则完全相反。机器学习是而不是常规编程。它基本上是应用数据科学,在一个已经拥有非机器学习基础设施的组织中,与一个从头开始的初创公司相比,它的推出非常不同。
Machine Learning consulting is a premium service
未知越大,或者我喜欢称之为需求风险,我就越倾向于按小时计费而不是固定价格。在需求非常紧张的地方,或者我喜欢称之为可执行规范的地方,我越倾向于固定价格。
在之前的一篇文章中,我讨论了如何雇佣一名人工智能顾问,在这篇文章中,我们将研究一个项目是如何定价的。
一位与我们共事的政府代表喜欢将这些坦率的对话称为开放的和服方式。残酷的诚实。让我们现实地考虑一下入场费和每小时的费用。如果是现场演出,我们 2017 年 8 月的标准价格是 250 美元/小时,外加差旅费和每日津贴。考虑到启动合同的努力,包括 NDA、工作说明书和初步讨论,承包商的目标是至少 5K (20 小时)大小的项目。一个低跟进潜力的一小时项目只是一个不成功的项目(例如调试我的代码)。你(客户)也有预算问题,需要考虑内部资源。我们喜欢将尽可能多的低端工作委派给客户的员工,以减少完成项目所需的时间。但是在一天结束的时候,你仍然支付你的员工在这个项目上的工作,并且需要考虑到这一点。你的目标是控制 ML 项目的成本和时间。我们的目标是努力达到我们的时薪,即使是固定价格的项目,并尽可能吸引大项目。
这篇文章的目的是帮助你对你的项目进行高层次的定价。让我们给一个小的虚构项目定价,看看我们最终会在哪里。
客户要求
对于 ML 中的任何项目来说,关键是我们需要设定关于准确度、精确度、召回率、F 分数等的期望。让我们假设客户想要“好”的结果,而不是一个量化的基准。这使得项目更容易定价,因为迭代次数更少。一般来说,人工智能的质量随着数据集的大小而增长。
另一个要考虑的维度是需求质量。许多客户提出了定义不明确的需求,这就是为什么他们不仅需要我们的专家建议,还需要我们对项目定义和解决方案架构的建议。在讨论的最早可能阶段,确定任何被证明不可能实现的需求,或者需要新科学的需求是非常关键的。不开玩笑。有人要求我固定研究项目的价格,而研究的定义是你不知道答案。我们的解决方案很简单。为了固定价格研究,我们提供固定价格的小时数。结果不能保证,但至少燃烧速度得到控制。在那些项目中,我们的目标是尽早交付结果,以激励进一步的发展。
我们将在本文中定价的假想项目是一个文档分类系统,它使金融机构中的 BI 分析师能够转储文档(PDF、Word 等。)并用许多不同的方法按语义和句法相似性对它们进行排序。客户感兴趣的是文档之间的相似性,以及每个文档和搜索框的关键字内容之间的相似性,以及文档和用户粘贴的文本段落之间的相似性。对于分析师来说,这是一个普通的任务,并不是一个超级新颖的 ML 项目,但它给了我们一些我们可以轻松定价的东西。让我们定义客户端没有 ML 服务器。要排序的数据不是敏感的内部数据,因此可以安全地运送到 AWS 以外的地方,供 ML 系统进行消化和呈现。正如我在之前的文章中所讨论的,一些公司由于各种原因在使用公共云数据时遇到了困难。
让我们计划一下这个事情,然后估计一个价格。
规划
第一步:打好基础
我们现在知道该项目将存在于 AWS 中,并将使用一个或多个从现有 AMI 中派生出来的 p2/p8 实例。假设在与客户的交谈中,定制的弹性搜索功能不能满足这些分析师的需求,而的常规搜索功能也是必要的,但还不够,我们决定建立一个 ML 和现有文档搜索工具的混合模型。该系统将需要 tensorflow、word2vec、doc2vec、keras、elasticsearch 和 Flask 来像 elasticsearch 一样公开这组特性。我们将需要一个用于 AngularJS GUI 的 PHP 服务器(如果是一个小规模项目,甚至可能在同一个实例上)。我们决定不使用 NLTK,因为 elasticsearch 包含了我们会从这个包中用到的所有东西。Jupyter notebook 是一个很好的想法,这样,将拥有这个项目的开发人员可以轻松安全地在服务器上运行代码,而且我们也可以轻松地重用 github 示例中的代码。这是双赢。我们还需要知道客户需求对应于这样的工具:
文档相似度+文档到段落相似度= word2vec 和 doc2vec,还有 CNN 的一些 Keras 型号+word2vec 。仅供参考这只是我们可以根据自己的需要开始和塑造的众多例子中的一个。
文档关键字搜索和其他搜索功能=弹性搜索
重用模型节省了时间和金钱。我们可能会使用预先训练的谷歌新闻 word2vec 模型,或者可能是手套模型。基本上,我们的计划是使用一些现成的代码。
Word2vec 不对保存的模型进行迁移学习,因此预先训练的模型可能不能很好地代表定制模型的表现。我们建议客户,他们同意这个计划。
elasticsearch 有很多客户不知道的很酷的 API,所以除了开发工作之外,我们还为客户的员工安排了一些培训。
这就是高水平。
第二步:优先考虑早期结果
所以我们想给这个项目定价。让我们决定对公司来说最紧急的优先事项是什么,并为第一阶段的开发定价。为什么在我们第一次约会之前就决定我们婚姻的条款?我的理念是从第一天开始就给出现实的价格,并保持初始阶段的简短,以便客户可以很快看到并感受到结果。该项目是关于句子,段落和整个文档的语义相似性。让我们启动系统,向客户展示他们不能下架的功能。客户同意我们将提供 2 个实例。我们称之为“web 1”的一个服务器是 RESTful LEMP web 服务器,它将包含我们的 Angular 代码、文件转储,稍后它还将托管 elasticsearch 代码。这个实例上没有 GPU,但它将有一个大块存储附件来保存所有文件。我们称之为“ML1”的另一个服务器将保存 ML 系统。ML 服务器将接受来自 web 服务器的作业,并将存储将被成批转储回 web 服务器的响应。ML1 将是一个高内存的 p2 实例,因为它将受到大量 GPU 作业的冲击,但也有很高的内存需求。这是因为像我们将在 word2vec/gloVe 中使用的单词嵌入模型比计算密集型更占用内存。
在第一阶段,我们没有捕捉主题建模,也没有考虑整个弹性搜索模块和培训。在与客户的交谈中,我们也推动文档相关性回归。这些项目可以随时进入第二阶段。现在客户希望看到奇迹发生。
接下来我们把项目票扔进 JIRA。
专注于文档分类,我们估计 AWS 实例供应需要 10 个小时,证书安装(PKKs、SSL、OTP 等)需要另外 5 个小时。).这 15 个小时包括工具安装。我们在报价中增加了 3 个小时的知识传授时间,以确保客户了解系统的工作原理。现在我们有了一个工作的双实例系统。让我们来设置 ML 和 GUI。不需要负载平衡器、地理分布等。我们保持简单。
我们估计 10 个小时的 GUI 开发,包括文件转储和结果的介绍。我们决定使用 tensorboard 来显示文档聚类,并在单独的 GUI 中使用一个角度表来排列结果。此阶段通过 HTACCESS 密码进行身份验证。在第 2 阶段,我们可以使用 Oauth 2.0 登录,这样分析师就可以使用他们的工作帐户登录系统。
所以现在我们是 25 小时。我们继续吧。
核心 ML 的配置和部署不会超过 10 个小时。这种需求与 ML 工具的现有能力非常匹配。这段时间包括一个小时的客户演示,向他们展示整个系统如何工作。
第三步:考虑滑移
经验法则是,当试图估算项目价格或持续时间时,估计一个因子π。让我们把圆周率截成 3。所以滑点最多可以达到 353(2/3) = 35*2 = 70 小时。
定价
服务器设置: 15 小时
界面设置: 10 小时
ML 开发: 10 小时
延迟:长达 70 小时
因此,我们估计第一阶段的工作需要 35 到 105 个小时,或8,750 到 26,250 美元。为了控制成本,我会详细介绍客户可以采取的避免延误的步骤,包括提前规划网络访问(防火墙、端口、证书等)。).这是那种我会在 10K 提供定价的项目,因为滑点的风险很低。
如果我们指定第二和第三阶段,我希望他们每个人都会来到 10K,项目总成本为 30K。这些阶段大约每 4 周发布一次。也许会更快,因为这个项目比一般项目要简单得多。只有在项目被指定为工作说明书的这一点上,客户才真正签署合同。
当我们结束项目时,我们试图向客户追加销售更多的 ML 解决方案,这可以为客户增加超出初始项目的价值。这使我们在第 4 阶段及以后的比赛中保持领先。
结论
当谈到项目定价时,希望这对你来说是一个真正深入了解人工智能顾问的想法的机会。如果你喜欢这篇文章,那么请推荐它,分享它,或者给它一些爱(❤).
编码快乐!
-丹尼尔
丹尼尔@lemay.ai ←打个招呼。
LEMAY . AI
1(855)LEMAY-AI
您可能喜欢的其他文章:
- 人工智能和不良数据
- 人工智能:超参数
- 人工智能:让你的用户给你的数据贴上标签
如何恰当地用数据讲述一个故事——以及要避免的常见陷阱。
原文:https://towardsdatascience.com/how-to-properly-tell-a-story-with-data-and-common-pitfalls-to-avoid-317d8817e0c9?source=collection_archive---------1-----------------------
使用数据最重要的一个方面,但最不受重视的是如何传达数据告诉你的信息。即使你每天都遵循我们关于数据驱动的所有建议,如果你传达你的见解很差或者误导了观众,这可能比根本不使用数据更糟糕。
历史上一些最糟糕的商业决策都是由数据驱动的!当百事可乐的崛起威胁到可口可乐在软饮料领域的主导地位时,可口可乐采取了数据驱动的方法来解决这个问题。他们配制了新的可口可乐,并在全国范围内的口味测试中发现,它轻而易举地击败了百事可乐。有了确凿的数据,该公司把他们的未来押在了新可乐上。
不幸的是,新可乐的部分故事被遗漏了。新可乐非常甜,所以它很容易赢得品尝测试,顾客只喝一小口,但喝满一杯或一瓶就不喜欢了。此外,测试人员未能衡量消费者对旧口味可乐的情感依恋,他们是伴随着旧口味可乐长大的。如果没有测试数据的背景,决策者就会忽略消费者不喜欢新可乐的事实。在一次灾难性的推出后,公司不得不绝望地回到最初的模式。[1]
在这篇文章中,我将展示讲故事如何影响人们以不同的方式看待相同的数据。我们将以三种不同的方式讲述一组数据的故事,这意味着三种不同的结论。下面是我们将使用的数据,这是一家拥有四种产品的公司的月收入数据:
从原始数据中无法得出明显的结论,我们需要做数据专家的工作,探索数据,讲述隐藏的故事。关于这些数据,我们会讲述哪些故事?具体来说,我们将涵盖:
- 第一部分——谎言的故事
- 第二部——误导人的故事
- 第三部——告知的故事
- 第四部分 —一般讲故事
离群值 监控您的业务数据,并在发生意外变化时通知您。我们帮助营销/发展&产品团队从他们的业务数据中获取更多价值。今天安排一次演示。
- Outlier 是 Strata+Hadoop World 2017 观众奖得主。
第一部分。谎言的故事
首先,我要告诉你一个关于我们的数据(上面提供的)的故事,这是一个故意撒谎的好消息。
收入增长迅速,12 月份比 11 月份大幅增加。您可以在下面的收入图表中看到这一点:
这一增长得益于产品 D 收入的 1,150%的跃升!如果这一趋势持续下去,我们预计 1 月份的总收入将首次超过 10 万美元。对于公司来说,这是一个激动人心的时刻,这种增长是我去年 6 月所做战略决策的直接结果。
这个故事为什么好?
不是,是骗人的。
为什么这个故事不好?
我在数据故事中使用了一些非常常见的技巧来欺骗你去读更多的东西。具体来说:
- 操纵音阶。查看图表时,您习惯于比较条形的大小来确定相对大小。通过让 y 轴从一个任意值开始,而不是从零开始,我改变了相对大小,使它看起来好像在没有增长的地方有显著的增长。
- 樱桃采摘。我只选择了几个数据点来说明我的情况(产品 D 的增长率),而没有考虑数据的全部广度及其真正传达的内容。
- 下结论。尽管没有明确的逻辑依据,我还是根据数据得出了结论。为什么我去年 6 月做出的决定会影响 12 月的收入?
在这种情况下,我是恶意的,故意撒谎。
第二部分。误导人的故事
接下来,我要告诉你一个关于我们的数据的故事,这个故事是真实的,但却具有误导性:
总的来说,所有产品的收入相当平均。产品 D 的收入在 12 月份出现了一个明显的例外,环比增长超过 1000%。
然而,单一产品的收入支配着所有其他产品——产品 C 占总收入的 50%以上。这意味着产品 C 的收入大于其他三种产品的总和。
这个故事为什么好?
这个故事是真的,这是一个好的开始。通过在第一个图表中使用相对标度,产品 D 的显著偏差变得非常清楚。这个故事试图通过对产品构成的一些洞察来分解整体趋势,但没有成功。
为什么这个故事不好?
这是非常误导人的。我在交流数据时犯了一些常见的错误,这让作为观众的你很容易得出不准确的结论。
- 缺乏清晰度。我还没有标记我的图表或我的讨论中的坐标轴!在第一个图表中,y 轴是增长率,而饼图是 12 月的收入。然而,因为你没有办法知道你可以得出各种不同的结论。
- 混乱的图表。这两个图表会切换哪些颜色代表哪些产品。黄色代表第一个图表中的产品 D,第二个图表中的产品 C!如果你快速阅读这篇文章,你可能会认为快速增长的产品是最大的,这是不正确的。
- 没有上下文。我提到产品 D 增长超过 1000%,但不是绝对值是多少!例如,从 1 美元增长 1000%是 11 美元,变化 10 美元,但从 100 美元增长 1000%是 1100 美元,变化 1000 美元。避免在没有提供适当上下文的情况下使用相对度量。
最后,我使用了一个饼状图,很多数据可视化的人认为这是一个的大错误。
第三部分。精彩故事
让我们最终讲述我们数据的真实故事,并以此强调过去两个故事的糟糕程度。
总体而言,过去一年的收入呈下降趋势(虚线)。夏季有一个明显的峰值,春季和秋季有所下降,根据前几年的数据,预期范围(绿色条)加强了这一季节性趋势。下面是显示这一趋势的总收入图表:
正如你所看到的,四月和五月是这一趋势中稍微反常的月份,但是总的来说收入模式是非常一致的。
隐藏在这一整体趋势下的是收入构成的转变。产品 A 在这一年中一直在下降,而产品 C 一直在上升。12 月,产品 C 的收入大幅增长,这是第一个月产品 C 的收入高于产品 a。
如果这种趋势持续下去,我们可以预期下一年的收入会增加。
这个故事为什么好?
这个故事遵循了许多数据叙事的最佳实践:
- 先说大图。将您所有的数据通信放在一个更大的框架内。在这种情况下,故事首先陈述了总收入呈下降趋势,看起来是季节性的。
- 显示上下文。通过在第一张图中突出整体营收的预期区间和线性趋势,更容易把握隐藏在数据中的更大格局。这些视觉引导是解释原始数据的重要背景。
- 突出重要驱动因素。通过识别总收入的两个重要驱动因素(产品 A 和 C)并描述它们之间的关系,隐藏在顶部图表中的洞察力变得清晰。这与挑选樱桃数据不同,因为我们强调的是数据中有意义和重要的驱动因素。
最重要的是,在这种情况下,我让数据来讲述故事,而不是试图用数据来讲述故事。这是很重要的一点,因为如果你试图让你的数据符合一个现有的故事,你将无法讲述整个故事。
为什么这个故事不好?
不是,虽然我可以说得更详细些。总的来说,我很满意。
像大多数诚实和直接的数据故事一样,结论远不如我们撒谎或误导时那么清晰。这是因为真实世界的数据很少给我们一个单一的、清晰的信息。你需要依靠你的专业知识和听众的判断来得出结论。
第四部分。一般讲故事
我们回顾了好故事和坏故事,都是关于相同的数据。由于您将讲述关于您自己的数据的故事,因此让我们回顾一下围绕传达您自己的数据见解的最佳实践。
做…
- 先说大图。将您所有的数据通信放在一个更大的框架内。这让你的听众更容易理解,给你的故事一个强有力的开始。
- 显示上下文。你提供的语境越多,无论是视觉上的还是语言上的,你的听众就越不可能得出错误的结论。
- 突出隐藏的见解。您的数据中许多最重要的见解都隐藏在表面之下。突出这些,并将它们与总体指标进行对比,以形成一个强有力的故事。
不要…
- 操纵标尺。明确数据的刻度和单位,厌倦多轴图表。与其让观众产生误解,不如就图表的背景进行过多的交流。
- 樱桃采摘数据。在你的沟通中包括全面的数据,而不仅仅是有助于你的案例的数据点。
- 不一致。在你的故事中,所有的陈述和可视化都使用相同的颜色、标签和惯例。这样做可以为您的数据创建一种自然语言,一种您的受众可以学习的语言。
- 谎言。说真的,就是不要。
总的来说,让数据来讲故事。避免试图使用数据来证明现有的决策或讲述现有的故事,因为这些途径注定会导致错误和失误。如果你让数据引导你,故事会自己告诉你。
离群值 监控您的业务数据,并在发生意外变化时通知您。我们帮助营销/发展&产品团队从他们的业务数据中获取更多价值。安排今天的演示。
- Outlier 是 Strata+Hadoop World 2017 观众奖得主。
[1]如果你想了解更多,Snopes 对新的可口可乐灾难有一个很好的分析。
如何把完全交互式的、可运行的代码放到一篇中等的文章中
原文:https://towardsdatascience.com/how-to-put-fully-interactive-runnable-code-in-a-medium-post-3dce6bdf4895?source=collection_archive---------10-----------------------
(Source)
代码应该是交互式的。
- 前往回复
- 用你最喜欢的语言写一些代码。
- 复制并粘贴你的回复到一个中等职位的网址。
- 发布帖子,使代码具有交互性。
Interactive code. In a Medium article! (from repl.it).
请随意使用上面的代码。这是一个简单的例子,但是您可以为读者创建复杂的脚本以在多种语言中运行。
笔记
- 代码只有在发布后才是完全交互的
- 您可以添加包、数据文件,或者在您的 repl 中包含多个脚本
- 这在手机上确实有效,尽管并不完美
- 每次重新加载页面时,都会安装软件包
除了在文章中嵌入代码,repl.it 还有一个很棒的论坛和互动练习来学习编码。
我欢迎评论、反馈或建设性的批评,可以通过 Twitter @koehrsen_will 联系。
如何(快速)建立 Tensorflow 培训渠道
原文:https://towardsdatascience.com/how-to-quickly-build-a-tensorflow-training-pipeline-15e9ae4d78a0?source=collection_archive---------4-----------------------
如何在 Tensorflow 中建立一个高效的培训和管道,而不会在树林中迷路
Tensorflow 很棒。真的,你可以做任何你能想到的事情。你可以用它来打造真正的酷产品。然而,Tensorflow 的代码示例通常倾向于掩盖如何将数据输入到您的模型中:它们有时会天真地认为其他人已经为您做了艰苦的工作并将数据序列化为 Tensorflow 的原生格式,或者展示不合理的缓慢方法,这些方法会使 GPU 以低得惊人的性能闲置。此外,代码通常非常粗糙,难以遵循。因此,我认为展示一个小的、自包含的例子可能是有用的,这个例子在一个重要的例子上处理训练和有效的数据管道。
向张量流模型提供数据的 3 种方法:如何正确获取数据?
There are three paths to enlightenment. Or at least to feeding Tensorflow models with data.
在典型的 Tensorflow 中,有许多方法可以设置数据管道。本指南将快速列出前 3 项,并向您展示如何使用折衷方案,获得易于编码且对于 80%的用例来说速度惊人的解决方案。
一般来说,有三种方法可以将数据输入到模型中:
- 使用
feed_dict
命令,使用输入数组覆盖输入张量。这种方法在在线教程中有广泛介绍,但是由于一系列原因,它的缺点是非常慢。最值得注意的是,要使用feed_dict
,你必须在 python 中将数据加载到内存中,这已经否定了多线程的可能性,因为 python 有一个丑陋的怪兽,叫做全局 interperer 锁(又名 GIL )。使用feed_dict
在其他教程中有广泛介绍,在某些情况下是一个很好的解决方案。然而,一旦你试图利用高容量的 GPU,你会发现你正在尽力利用它的 30%的计算能力! - 使用 Tensorflow
TfRecords
。我觉得在这里我可以大胆地说,卷入这场混乱十有八九是个坏主意。从 python 中序列化记录既缓慢又痛苦,反序列化它们(即读入 tensorflow)同样容易出错,需要大量编码。你可以在这里阅读如何使用它们。 - 使用 tensorflow 的
tf.data.Dataset
对象。现在,这是一个很好的方法,但有太多不同的方法来使用它,Tensorflow 的文档在构建重要的数据管道方面并没有真正的帮助。这就是本指南的用武之地。
让我们看看现实生活中的用例,并建立一个复杂的数据管道,在一台具有潜在高容量 GPU 的机器上以惊人的速度进行训练。
我们的模型:基本的人脸识别
所以我们来处理一个具体的例子。假设我们的目标是建立一个人脸识别模型。模型的输入是 2 张图片,如果是同一个人,输出是 1,否则是 0。让我们看看一个超级天真的张量流模型如何完成这项任务
好吧,所以这个模型不会赢得任何历史上最佳人脸识别的奖项。我们只是取两幅图像之间的差异,通过标准的 conv-雷鲁-马克斯普尔神经网络输入这个差异图。如果这对你来说是胡言乱语,不要担心:这不是一个比较图像的好方法。请相信我的话,它至少在某种程度上能够识别同一个人的照片。模型现在需要的只是数据——这就是我们有趣的小帖子的重点。
那么我们的数据是什么样的呢?
数据
一个经典的(微小的)人脸识别数据集叫做标签为 野外人脸,你可以在这里 下载。数据很简单:你有一堆文件夹,每个文件夹都包含同一个人的照片,就像这样:
/lfw
/lfw/Dalai_Lama/Dalai_Lama_0001.jpg
/lfw/Dalai_Lama/Dalai_Lama_0002.jpg
...
/lfw/George_HW_Bush/George_HW_Bush_0001.jpg
/lfw/George_HW_Bush/George_HW_Bush_0002.jpg
...
我们可以做的一件事是生成所有可以想象的配对,缓存它们,并将其提供给模型。那会很高,会占用我们所有的内存,因为这里有 18,984 张照片,18,894 的平方是……很多。
因此,让我们构建一个非常轻量级的 pythonic 函数,它生成一对照片,并指示它们是否是同一个人——并在每次迭代中随机抽取另一对照片。
哇哦。但是我不是说过 python 对于一个数据管道来说太慢了吗?答案是肯定的,python 很慢,但是在随机抽字符串和喂它的时候,就足够爽快了。重要的是,所有的重担:阅读。jpg 图像,调整它们的大小,对它们进行批处理,对它们进行排队等等——这些都是在 pure Tensorflow 中完成的。
张量流数据集管道
所以现在我们只剩下在 Tensorflow 中构建数据管道了!事不宜迟:
所以基本上我们从 pythonic 生成器输出(3 个字符串)的字典开始。让我们来分析一下这里发生了什么:
- 让我们知道它将由我们的 pythonic 发电机提供能量。这一行根本没有评估我们的 pythonic 生成器!它只是建立了一个计划,每当我们的数据集渴望更多的输入,它将从生成器中获取它。
这就是为什么我们需要煞费苦心地指定生成器将要生成的输出的类型。在我们的例子中,image1 和 image2 都是图像文件的字符串,label 是一个布尔值,表示是否是同一个人。 map
操作:这是我们设置所有必要任务的地方,从生成器输入(文件名)到我们实际上想要馈送给模型的内容(加载和调整大小的图像)。_read_image_and_resize()
会处理好的。batch
operation 是一个方便的功能,它可以将图像批处理成具有一致数量元素的包。这在训练中非常有用,因为我们通常希望一次处理多个输入。请注意,如果我们从[128,128,3]维的图像开始,在该批之后,我们将得到[10,128,128,3],在本例中,10 是批大小。prefetch
operation 让 Tensorflow 做簿记工作,包括设置队列,以便数据管道继续读取数据并对数据进行排队,直到 N 批数据全部加载并准备就绪。在这种情况下,我选择了 5,并且通常发现数字 1-5 通常足以充分利用 GPU 的能力,而不会不必要地增加机器的内存消耗。
就是这样!
现在一切都设置好了,简单地实例化一个会话并调用session.run(element)
将自动获得img1_resized
、img2_resized
和label
的实际值。如果我们点击session.run(opt_step)
,那么一个新的数据将通过管道执行一个优化步骤。这里有一个很小的脚本,用于获取一个数据元素,并执行 100 个训练步骤来查看它是否全部工作
当你只把乔治·布什和达丨赖喇嘛作为类别时,这个模型收敛得相当快。下面是这次模拟运行的结果:
/Users/urimerhav/venv3_6/bin/python /Users/urimerhav/Code/tflow-dataset/recognizer/train.py
{'person1': 'resources/lfw/Dalai_Lama/Dalai_Lama_0002.jpg', 'person2': 'resources/lfw/George_HW_Bush/George_HW_Bush_0006.jpg', 'same_person': False}
{'person1': 'resources/lfw/Dalai_Lama/Dalai_Lama_0002.jpg', 'person2': 'resources/lfw/George_HW_Bush/George_HW_Bush_0011.jpg', 'same_person': False}
step 0 log-loss 6.541984558105469
step 1 log-loss 11.30261516571045
...
step 98 log-loss 0.11421843618154526
step 99 log-loss 0.09954185783863068
Process finished with exit code 0
我希望这本指南对你有用。github 上有完整的(微小的)代码回购。你觉得合适就随便用吧!
示例 2 —从产品图片中移除背景
稍后我可能会写一篇更详细的博文,但我应该注意到我最近的数据培训管道,我很喜欢我作为副业项目建立的一个名为 Pro Product Pix 的小型概念验证网站。这个概念很简单:电子卖家需要拍摄产品的照片,然后必须做一项费力的任务,即去除背景像素(这相当繁琐!).为什么不自动这么做呢?
但是获得有背景和没有背景的产品的标签图像是非常棘手的。所以:数据生成器来拯救!以下是我最后做的事情:
- 在只有一个物体存在的公共领域搜索图像(实际上有很多这样的东西——透明的 png 文件到处都是)
- 在 Bing 图片中搜索一些普通的背景模板,如“地毯”或“墙”
- 建立一个生成器,生成成对的背景文件路径+对象文件路径,将它们融合在一起。
- 让模型猜测哪些像素属于背景,哪些属于物体(以及一堆其他东西,但那是另一篇文章)。
总之,我们有很多这样的背景:
Bunch of backgrounds
我们把它们和没有背景的产品照片融合在一起
Random product photos
这里有一堆小问题要解决。对于 exmaple,背景通常比产品照片大得多,所以我们需要将背景照片裁剪到产品尺寸,然后将两张照片合并。整个管道有点复杂,因为它不是在编写教程的时候考虑的,但是我会把重点片段放在这里。我们有一个生成背景路径+产品路径的生成器
我们将背景加载为 rgb 图像,对象 png 实际上既有 rgb 图像,也有我们所说的透明贴图(我们称之为 object_pixels:它告诉我们哪些像素属于背景,哪些属于对象)。然后在我们的 dataset.map 操作中,我们随机裁剪一块背景,并将其与前景混合。
有时候,结果非常好。这里有一张我比较喜欢的之前/之后的照片,尽管它仍然不是 100%完美的:
我希望有一天我会找到时间写更多关于实际使用的模型。你可以在网站[这里](http://proproductpix.org)玩这个模型,但是要预先警告——这基本上只适用于类似真实产品照片的图片。其他的,都是垃圾进——垃圾出!
最初发布在霍斯科技博客(那是我的 ML 咨询公司)
如何用 Python 快速测试几十个深度学习模型
原文:https://towardsdatascience.com/how-to-rapidly-test-dozens-of-deep-learning-models-in-python-cb839b518531?source=collection_archive---------4-----------------------
让我们开发一个神经网络装配线,使我们能够轻松地试验众多的模型配置。
Assembly Line of Neural Networks (Source: all_is_magic on Shutterstock & Author)
优化机器学习(ML)模型不是一门精确的科学。最佳模型架构、优化算法和超参数设置取决于您正在处理的数据。因此,能够快速测试几种模型配置对于最大化生产率和推动 ML 项目的进展是必不可少的。在本文中,我们将创建一个易于使用的界面,允许您这样做,类似于 ML 模型的装配线。
深度学习模型由一组超参数管理,我们可以创建对这些超参数进行归纳的函数,并建立临时模型。以下是控制神经网络的主要超参数:
- 隐藏层数
- 每层神经元的数量
- 激活功能
- 最优化算法
- 学习率
- 正则化技术
- 正则化超参数
我们可以将这些打包成一个哈希表:
model_info = {}
model_info['Hidden layers'] = [100] * 6
model_info['Input size'] = og_one_hot.shape[1] - 1
model_info['Activations'] = ['relu'] * 6
model_info['Optimization'] = 'adadelta'
model_info["Learning rate"] = .005
model_info["Batch size"] = 32
model_info["Preprocessing"] = 'Standard'
model_info["Lambda"] = 0
model_2['Regularization'] = 'l2'
model_2['Reg param'] = 0.0005
在我们开始试验各种模型架构之前,让我们将数据可视化,看看我们在做什么。虽然标准缩放是事实上的预处理方法,但我使用了各种预处理策略来可视化数据。我使用主成分分析和 t-SNE 来降低每种预处理方法的数据维数。以下是看起来最容易分离的数据可视化:
Source: Author
然后,我们可以定义一个函数,在给定超参数哈希表的情况下,该函数将构建和编译一个神经网络:
既然我们有了一种快速、灵活的构建和编译神经网络的方法,我们就可以快速测试一些基线模型。这使我们能够快速推断出哪些超参数似乎工作得最好:
使用上面的函数,在用五重交叉验证评估了十几个模型架构之后,我发现需要更深更宽的架构来获得数据的高性能。这很可能是由于我们数据的非线性结构。下图说明了收益递减。将每层中隐藏单元的数量从 15 个增加到 120 个,可以显著提高训练数据的性能,但实际上对测试数据没有任何影响。这是模型过度拟合的迹象,即训练集的性能不能概括测试数据。
旁白:如果你不熟悉 k-fold 交叉验证,这是一种模型评估技术,涉及到将数据分成 K 个不相交的分区。这些分区中的一个用作测试集,其余的用作训练集。然后我们遍历每个折叠,这样每个分区都有一个回合作为测试集。执行 k-fold 交叉验证使我们能够获得模型性能的可靠评估。
Source: Author
K-fold 交叉验证是一种评估模型性能的稳健方法,但需要注意的是,获得这些结果的计算成本很高。我们可以将数据分成训练和测试集,以在优化超参数的同时得出更快的启发,并在每个时期后保存模型,以便它们在训练后可检索。 Tensorboard 回调也可用于检查模型是如何被训练的:
一旦我们了解了哪些超参数设置工作良好,我们就可以获得更可靠的性能评估。
网格搜索不是行业中超参数优化的首选方法。相反,一种被称为由粗到细的方法被更频繁地采用。在由粗到细的方法中,我们从大范围的超参数开始,然后专注于最有效的参数设置。然后,我们从想要试验的狭窄范围的值中随机抽样超参数设置。既然我们有了动态实例化深度神经网络的方法,我们可以快速迭代众多模型配置:
旁白:当从你的终端调用 Tensorboard 日志目录时,你不能在文件路径中有空格。在 Windows 上,日志目录中的空格会阻止 Tensorboard 正确加载数据。
上面的代码还将每个模型的重要指标(例如 ROC 曲线下的面积)保存到一个 CSV 文件中,以便我们可以轻松地比较和对比哪些超参数会导致性能变化。
一旦我们对哪些超参数值工作良好有了更好的了解,我们就可以开始在这个值范围内优化模型。下面的函数生成一个随机化的神经网络。然后,我们可以使用该函数在我们缩小的值范围内试验各种随机超参数设置:
在本文中,我们学习了如何快速试验众多的模型架构和超参数设置。如果你喜欢这篇文章或学到了新的东西,请随时关注我或留下掌声。再次感谢!
源代码:此处
警告:
我在代码中发现了一个 bug,可能是 Tensorboard Keras 回调或者 build_nn()函数导致的。这不是一个主要问题,但我想和你讨论这个问题。问题是,在测试一系列神经网络时,会将多个图形写入 Tensorboard 日志文件。例如,当我们运行上面的“模型实验”代码时,我们得到了 model_1 的图形可视化:
Erroneous Graph (Source: Author)
正如您所看到的,这里有两个不同的图形:一个对应于 model_0(左),一个对应于 model_1(右)。model_0 的图形不会发生这种情况,因为它是在 model_1 之前训练的:
Visualizing model_0 Architecture via Tensorboard (Source: Author)
然而,如果我们在训练之后加载 model_1,我们可以看到,对于我们传递给 build_nn()的哈希表,该架构是正确的:
print("Model 1")
saved_model = load_model(FILE_PATH)
print(saved_model.summary())Model 1
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
dense_8 (Dense) (None, 110) 10120
_________________________________________________________________
activation_8 (Activation) (None, 110) 0
_________________________________________________________________
dense_9 (Dense) (None, 110) 12210
_________________________________________________________________
activation_9 (Activation) (None, 110) 0
_________________________________________________________________
dense_10 (Dense) (None, 110) 12210
_________________________________________________________________
activation_10 (Activation) (None, 110) 0
_________________________________________________________________
dense_11 (Dense) (None, 1) 111
_________________________________________________________________
activation_11 (Activation) (None, 1) 0
=================================================================
Total params: 34,651
Trainable params: 34,651
Non-trainable params: 0
_________________________________________________________________
这表明使用该代码获得准确的评估没有潜在的问题,但是它不允许我们可视化管道中的模型。如果您有任何见解、建议或知道为什么会出现这种情况,请随时修改代码或告诉我。我想继续研究这个问题,但作为一名有三份兼职工作的全日制学生,我无法做到这一点。再次感谢阅读!
如何降低电子商务结账阶段的废弃率——A/B 测试电子支付方式
原文:https://towardsdatascience.com/how-to-reduce-abandonment-rate-during-the-e-commerce-checkout-stage-a-b-testing-e-payment-methods-8818506a353c?source=collection_archive---------7-----------------------
If SpaceX A/B Tests their Rockets, shouldn’t you at least A/B Test your Checkout Page?
随着电子商务公司不断寻找新的方法来提高他们的转化率,他们中的大多数人仍然不得不应对高比例的购物者放弃结账阶段的最后一步。即使顾客输入了个人信息,选择了送货方式,20-30%的顾客仍然会放弃付款页面。这就给我们带来了挑战:如何降低结账阶段的弃用率?
我花了几年时间,帮助世界上一些最大的电子商务商家,我相信一个更明显的答案在于 A/B 测试电子支付选项,以确定最高的转换组合。
电子支付系统如何工作
电子支付系统可以分为三种类型,基于信用,替代和数字钱包。
基于信用的电子支付系统使用信用卡/借记卡/预付卡接受和处理来自发卡机构的支付,如万事达、维萨、美国运通、 Discover/Diners 和银联。使用四方模型或三方模型,其中涉及发行者(向购物者提供信用卡/借记卡/预付卡)、收单方(以商家的方式处理交易)、商家(与网关集成以接受交易)和购物者(向商家发起支付)。
可供选择的电子支付系统有多种实施方式,但几乎都使用由第三方处理机构促成的直接银行转账,例如荷兰的 iDeal 和比利时的 Bancontact 。第三方处理器提供一方面与网关集成,另一方面与银行环境集成的技术,以启动从购物者到商家的资金转移。
数字钱包电子支付系统是像 PayPal 、谷歌钱包和 Apple Pay 这样的服务,它们作为中介接受和处理支付,并从转入账户或关联信用卡或银行账户的资金中进行内部贷记。与替代电子支付系统类似,数字钱包为网关提供 API 以集成其钱包或直接为商家提供集成选项。
哪种电子支付系统最常用?
根据国家的不同,零售中采用基于信用卡或借记卡的支付方式对所使用的电子支付系统有很大的影响。美国和英国的信用卡使用率很高,这导致大多数商家提供基于信用的电子支付方式。虽然荷兰和比利时等国家更喜欢使用借记卡,但这导致银行合作开发 iDeal 和 Bancontact 等替代支付选项,以防止万事达卡和 Visa 抢占更多市场份额。
导致采用电子支付系统的其他几个因素是安全性和易用性。这导致电子商务公司不得不提供多种支付方式。像 AirBnB、Amazon 和 Zalando 这样的公司都是以基于信用的电子支付系统起家的,但是随着他们的成长,电子支付方式已经适应了消费者的偏好。例如,AirBnB 接受信用卡、借记卡和预付卡,但在特定国家也接受 PayPal,在中国只接受支付宝,在意大利接受 Postepay ,在德国接受 Sofort ,在荷兰接受 iDeal,在印度接受 PayU ,在巴西接受 Boleto Bancário、 Hipercard 、 Elo 和 Aura。
A/B 测试电子支付选项
通过实施 A/B 测试,商家能够测试电子支付选项的不同组合。在任何 A/B 测试中,都有可以测试的变量。通过与世界各地的商家合作,我分析了我认为在 A/B 测试电子支付选项中最重要的变量。
如前所述,国家是电子支付方式可用性和接受度的重要组成部分。另一个变量是购买商品或服务时使用的 D 设备类型,无论是台式机、平板电脑还是手机。对于具有结账功能的应用程序,平台是另一个可以用于测试的变量,可以是 iOS (15%的市场份额),Android (85%的市场份额)。
测试电子支付方式背后的数学原理
要确定添加额外的电子支付方式是否会对转换率产生影响,可以实施 A/B 测试。为了确定哪个版本是赢家,Z 测试可以计算 B 版本是否明显优于控制版本。
根据您的交易量,我建议您尝试达到 95%的置信度。
95%区间估计的公式如下:
在哪里
- p(hat) =我们的点估计
- 1.96 =对应于 95%显著性的正常曲线 Z 值估计值
- n =我们的样本量
这可以解释为有 95%的把握皮肤上的转化率介于:
95%的置信水平告诉我们,如果测试重复多次,并且计算了每次测试的置信区间,则 95%的置信区间将包含真实的转化率。前面处理的是单个样本。在 A/B 测试中,重点在于比较多个样本。为了凭经验确定在 A/B 测试中观察到的两个转化率之间的差异是否足够大,从而可以合理地归因于 A 和 B 之间的经验差异,而不是因为采样误差,必须计算两个比例的 Z 统计量。
如果给定的指标是一个百分比或一个比例,则测试统计由下式给出:
在其最基本的形式中,它可以被认为是被称为标准误差的总体变化的量度,可以通过下式计算:
对于两个比例,通过合并所有值,计算合并比例,然后根据两个样本大小进行归一化,可以获得标准误差。如果 X A 是第一个样本中转换的人数,第二个样本中转换的人数,则综合转换率由下式给出:
在计算检验统计量(Z)时,采取以下步骤:
基于这个测试统计,我们观察到的差异是由于随机机会的概率可以计算出来。该值称为 p 值,是某一点之前或之后标准正态(Z)分布下方的区域。如果 Z 值为负,则计算到该点为止的值,并乘以 2。如果 Z 值为正,则在该点之后计算该值,然后乘以 2。乘以 2 是所谓的双尾检验的应用。
对商家有什么好处
A/B 测试电子支付选项有很多好处
- 通过 A/B 测试电子支付选项,商家可以消除猜测工作,为客户提供正确的电子支付方式组合,并在此过程中降低支付页面的放弃率。
- 降低获客成本 :通过在结账流程的关键阶段降低弃购率,这直接提高了转化率。虽然获得客户的成本相同,但购买量降低了平均获得客户的成本。
- 更高的利润 :更低的废弃率等于更高的交谈率,这导致销售商品的收入和成本增加,但在相同的管理费用和广告成本下,这导致更高的利润。
随着购物者越来越习惯于在网上购买商品和服务,他们首选的支付方式可能会因国家而异。通过使用 A/B 测试,商家可以测试并找到每个国家和设备的电子支付选项的正确组合。通过降低结账过程中最关键部分的废弃率,商家将能够降低他们的客户获取成本并增加利润。
感谢阅读;),如果你喜欢它,请点击下面的掌声按钮,这对我意义重大,也有助于其他人了解这个故事。通过在 Twitter、Linkedin 和 Twitter 上联系,让我知道你的想法。或者留下回应。
如何用基本的数据科学技术减少营销膨胀
原文:https://towardsdatascience.com/how-to-reduce-marketing-bloat-with-basic-data-science-techniques-fa9fd9dee787?source=collection_archive---------9-----------------------
在不损失客户的情况下减少营销支出
势头是营销策略中一个非常强大的因素。公司利用多年的经验来完善演示、流程和内容,以吸引新客户并让现有客户满意。
但是势头也会导致膨胀。随着组织推动自身前进,动力随着以新方式吸引客户的额外策略而增长。就像滚落山坡的雪球越滚越大,通信接触点越来越多。最终,营销势头有了自己的生命,从客户的角度来看,他们看到了大量的信息,这使他们更有可能忽略这一切。
人们退订邮件列表的首要原因是:“我收到太多邮件了。”第二个原因:“电子邮件与我无关。”—2016 年 12 月 MarketingSherpa“客户满意度调查研究”
势头不仅导致量上的膨胀,也导致目的上的膨胀。相比有针对性的信息传递,动量策略更倾向于对多个客户群有效的策略。即使每个营销人员都知道理论上专注是至关重要的,但在实践中却很难实现。
“能够个性化网络体验的营销人员看到销售额增加了 20%……但大多数人不知道如何去做。”— 经济咨询/货币化
求解雪崩的动量并不容易。你如何在不危及你辛辛苦苦创造的成功的情况下撤回战术?当通用的遗留方法看起来足够有效时,您如何将策略与受众群体相匹配?
有答案,使用已建立的机器学习方法,世界上最大的品牌每天都在做。对于较小的组织来说,这项任务似乎更加艰巨。值得努力吗?答案很简单:如果你能节省 50%的营销成本,但能取得更好的效果,你会这么做吗?
减少营销膨胀的两步法
第一步:通过随机对照实验消除浪费
有时,为了做出高效的决策,有必要抛开一些你对客户的了解。随机对照实验通常与临床试验相关,在市场营销中同样有效。类似于 A/B 测试,随机控制实验使得测试现有营销策略对无所作为的影响成为可能。关键是控制两组都暴露的因素,并随机选择测试组(而不是基于分段)。随机化可以让你考虑选择偏差,如果进行得正确,实验可以告诉你你在哪里花了不必要的钱。
如何进行随机对照营销实验
- 选择一个变量进行测试:哪种策略可能是多余的?还是很贵?
- 选择相关受众:要考一段还是多段?
- 最终确定假设:你想测试什么理论?例如,“取消我们的客户简讯不会影响客户保留率。”或者“这个新的和改进的策略将增加 10%的转化率。”
- 说明破坏性因素:哪些因素会破坏实验?例如,重叠策略可能会触发误报。
- 完成实验流程:确保因果关系尽可能清晰,并有清晰的协议和结果跟踪。
- 初步研究:用随机划分的试验组和对照组进行一个小实验,使风险最小化。
- R evise 流程:将您在试点研究中学到的东西应用到修订后的流程中。
- 扩大实验:对更大的受众重复实验。
- 分析结果:寻找哪些符合你的假设,哪些不符合。
关于随机对照实验的一个很好的概述,见 Amy Gallow 在哈佛商业评论上的精彩文章。
第二步:使用预测分析最大化收益
预测分析的最佳用途之一是决定不向谁营销。换句话说,你可以使用预测分析来创建一个规模更小、成本更低、转化率更高的营销活动。使用二元逻辑回归等基本预测方法或随机森林决策树等更高级的技术,您可以创建一个预测模型,该模型使用历史数据来确定您的客户群中谁最有可能在未来对给定的营销策略做出反应。
通过对积极响应的可能性进行评分,您可以将营销活动集中在最高收益目标上。例如,你可以决定只针对列表中得分最高的 20%的部分,如果你针对所有人,仍然可以获得 80%的最佳结果。这种方法在像直邮这样的高成本策略中特别有效,但在电子邮件过载的危险不断增加的电子邮件营销中也同样适用。
在不损失客户的情况下减少营销膨胀并不难——只需要一个考虑到迭代改进的深思熟虑的实验过程。当然,还有挑战现状的欲望。
原载于【www.deducive.com】。
如何在云中运行定制的 Tensorflow 培训
原文:https://towardsdatascience.com/how-to-run-customized-tensorflow-training-in-the-cloud-d0c142e3cfb5?source=collection_archive---------9-----------------------
您的 Tensorflow 代码在本地运行。现在,您希望在生产环境中设置它,以获得所有额外的 GPU 功能。有两种选择。比较流行的两个托管 ML 云平台是 Google Cloud ML Engine 和 AWS Sage Maker。它们让您快速部署您的模型并训练它们。但是,您可能想要构建一个更加定制化的解决方案。为此,您可以使用 AWS 批次。
为什么 AWS 批量?
这里的主要思想是尽可能降低成本,同时仍然利用 GPU 的能力。持续运行 GPU 实例会产生巨大的成本。AWS batch 使用一个作业队列,并根据作业需求扩展实例。因此,如果没有作业,就没有正在运行的实例。通过使用点实例,您可以进一步降低运行培训工作的成本。
先决条件:
- AWS 账户:https://aws.amazon.com/console。
- 用于部署的 AWS 命令行:https://aws.amazon.com/cli/。
- https://docs.docker.com/install/。
构建 Docker 映像
AWS 批处理需要一个 docker 映像,您的 Tensorflow 训练代码将在其中运行。Dockerfile 文件如下。
- 安装所需的相关 cuda 基础映像和库,从这里获取https://github . com/tensor flow/tensor flow/blob/master/tensor flow/tools/docker/docker file . GPU(版本可能会有所不同)。
- 复制您的代码使用的 Pipfile 并将其安装在映像上。Pipfile 也应该包含 Tensorflow 版本。
- 设置相关的环境变量。
- 复制获取并运行脚本,该脚本将在 s3 上获取一个 shell 脚本(稍后将详细介绍)来处理 Tensorflow 代码的运行(也驻留在 S3 上)。
$RUN_SCRIPT 参数将作为环境变量传递给 AWS 批处理作业。
接下来,构建映像并将其推送到 docker 存储库,以便批处理作业可以访问它。
> docker build -t $DOCKER_IMAGE_TAG aws_batch_image
> docker push $DOCKER_IMAGE_TAG
aws_batch_image 是一个包含 docker 文件以及获取和运行脚本的文件夹。
建立 AMI
Tensorflow 依赖于特定的 NVIDIA 驱动程序和软件包来运行。你可以使用 AWS Deeplearning AMI ,它附带了一组预装的驱动程序,或者你也可以自己构建一个。我将通过各种步骤来构建您的自定义 Tensorflow AMI。
创建一个 GPU 基础 AMI
从 Amazon EC2 仪表板创建 Amazon Linux AMI。我们将使用带有 16GB 通用 SSD 卷存储的 p2.xlarge 实例。确保生成一个定制的密钥对,您可以用它来 SSH 到实例中。
安装 NVIDIA 驱动
首先使用以下命令将 ssh 连接到您的实例。
> ssh -i custom-key-pair.pem ec2-user@<Public DNS>
运行以下命令。
# Update package cache and get package updates
> sudo yum update -y# Installs gcc compiler and kernel header package
> sudo yum install -y gcc kernel-devel-$(uname -r)
接下来,我们需要安装基于 Tensorflow 版本的 NVIDIA 驱动程序。P2 实例包含特斯拉 K-80 GPU 的。我们将使用与 CUDA Toolkit 8.0 兼容的 Tensorflow 1.3。你可以使用这个链接帮助找到兼容的驱动程序http://www.nvidia.com/Download/Find.aspx。我们将使用版本 367.106。
下载驱动程序安装文件。
> wget http://us.download.nvidia.com/XFree86/Linux-x86_64/367.106/NVIDIA-Linux-x86_64-367.106.run
运行安装文件,然后重新启动。
> sudo /bin/bash ./NVIDIA-Linux-x86_64-367.106.runVerifying archive integrity... OKUncompressing NVIDIA Accelerated Graphics Driver for Linux-x86_64 367.106............................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................> sudo reboot
SSH 到您的实例中,并运行以下命令来测试驱动程序是否安装正确。
> nvidia-smi -q | head==============NVSMI LOG==============Timestamp : Tue Apr 10 11:01:04 2018Driver Version : 367.106Attached GPUs : 1GPU 0000:00:1E.0Product Name : Tesla K80Product Brand : Tesla
如果您选择的驱动程序不起作用,请尝试使用不同的版本。
配置 nvidia-docker
NVIDIA Docker RPM 安装将 NVIDIA 驱动程序复制到 AWS 批处理作业中 Docker 容器的正确位置所需的组件。
用以下内容创建一个 bash 脚本文件。
运行该脚本,验证您可以运行 docker 容器,并使用以下命令访问已安装的驱动程序。
> ./configure_nvidia_gpu.sh> sudo docker run --privileged -v /var/lib/nvidia-docker/volumes/nvidia_driver/latest:/usr/local/nvidia nvidia/cuda:8.0-cudnn6-devel nvidia-smi
您应该得到类似于下面的输出。
删除实例上的 docker 容器和映像,以减小 AMI 的大小。
> sudo docker rm $(sudo docker ps -aq)
> sudo docker rmi $(sudo docker images -q)
从实例中创建 AMI
- 首先,创建图像的快照。可以参考这里https://docs . AWS . Amazon . com/AWS C2/latest/user guide/EBS-creating-snapshot . html。
- 从 EC2 仪表板中选择您的实例,并选择操作、图像、创建图像。
- 如下填写字段(我已经将快照 ID 和实例 Id 变白)。
4.单击创建图像。
您的 ami 现在应该显示在 AMIs 部分。状态变为可用可能需要一段时间。
设置 AWS 批
先决条件
- 创建 AWS 批处理服务角色。参考这里的获取信息。
- 创建一个 ecsInstanceRole。参考此处的获取信息。
- 创建一个 EC2SpotFleetRole。参考此处获取信息。
- 创建一个 EC2 密钥对。参考此处获取信息。
- 创建一个 EC2ContainerServiceTask 角色,并为其附加一个 AmazonS3FullAccess 策略。
AWS 批处理可以通过 GUI 或命令行设置。我们将通过命令行完成设置过程。如果你想通过图形用户界面来设置它,请遵循这里的教程并填写下面给出的信息。
创建计算环境
创建一个 JSON 文件来指定计算环境的各种属性。
类型:我们选择 managed,因为我们希望 AWS Batch 负责调度和管理资源。
状态:表示您现在是否想要激活。我们将其设置为 enabled。
计算资源:
- 类型:现场实例或按需实例。选择 spot 实例以降低成本。
- 这是你在上面创建的舰队角色的 arn。
提示:您可以使用 cli 获取您的角色的 arn,如下所示。
> aws iam get-role --role-name aws-batch-spot-fleet-role --query 'Role.Arn' --output text
- minvCpus :不管作业需求如何,要维护的虚拟 CPU 的最小数量。为了节省成本,我们将其设置为零。
- maxvCpus :我们希望作业运行的虚拟 CPU 的最大数量。
- desiredvCpus :计算环境在启动时应该拥有的虚拟 CPU 的数量。随着需求的增加或减少,AWS 批次的数量将在最大值和最小值之间进行调整。
- 实例类型:要启动的 EC2 实例的类型。我们将把它设置为 p2.xlarge(我们用来创建 AMI 的同一个实例)。
- bidPercentage :实例启动前,现货实例价格与该实例类型的按需价格相比必须达到的最大百分比。
- 子网:要在其中运行批处理实例的虚拟私有云(VPC)子网。
提示:您可以从 cli 查询您的子网 id,如下所示:
> aws ec2 describe-subnets
- security groupid:您希望应用到您的实例的安全组的标识符,例如 SSH 访问。
提示:您可以从 cli 查询您的安全组 id,如下所示。
> aws ec2 describe-security-groups
- ec2KeyPair: 用于 SSH 进入实例。将其设置为您在上面创建的值。
- instanceRole :将其设置为您在上面创建的角色的名称。
serviceRole: 将其设置为您在上面创建的角色的名称。
运行以下命令创建计算环境。
> aws batch create-compute-environment --cli-input-json file://<path_to_json_file>/compute_environment_spec.json
您应该会得到类似下面的输出。
创建作业队列
创建一个 JSON 文件来指定作业队列参数。
jobQueueName: 作业队列的名称。
状态:表示您希望它现在激活。我们将其设置为 enabled。
优先级:当与相同的计算环境相关联时,优先级参数具有较高整数值的作业队列首先被评估。我们使用单独的计算环境进行培训,因此我们只将其设置为 1。
计算环境清单:
- 顺序:作业调度器使用该参数来确定哪个计算环境应该执行给定的作业。
- 计算环境:计算环境的名称。
运行以下命令创建作业队列。
> aws batch create-job-queue --cli-input-json file://<path_to_json_file>/job_queue_spec.json
输出应该如下所示。
登记工作定义
创建一个 JSON 文件来指定作业定义参数。
作业定义名称:作业定义的名称。
类型:作业的类型。目前只支持容器类型。
容器属性:
- 图片:你上面创建的 docker 图片的标签。
- vcpu:工作所需的 vcpu 数量。
- 内存:作业所需的内存。
- jobRoleArn: 您在上面创建的 EC2ContainerServiceTask 角色的 Arn。
- 卷:传递给 docker 守护进程的卷。
- 主机:数据卷在容器上的位置。我们将把它指向我们在 AMI 上安装的 NVIDIA 驱动程序。
- 名称:卷的名称。
- 挂载点:容器中卷的挂载点。
- containerPath: 容器上装载主机卷的路径。
- sourceVolume: 上面提到的源卷的名称。
- privileged: 这赋予容器在主机容器实例上的根特权。
- 重试策略:重试失败作业的策略。
- 尝试次数:运行作业的尝试次数。我们将它设置为 1,这表示如果失败就不会重试。
使用以下命令创建作业定义。
> aws batch register-job-definition --cli-input-json file://<path_to_json_file>/job_definition_spec.json
输出应该如下所示。
设置代码
- 在 Tensorflow 代码文件夹中创建运行脚本,如下所示
$ SCRIPT _ DIR:S3 目录路径,包含运行培训的所有脚本。
$MODEL_DIR:存储检查点的 s3 目录路径。
$EXPORT_PATH:保存训练好的模型的 s3 目录路径。
$TRAINING_DATA:包含训练数据的 CSV 的 s3 路径。
$TEST_DATA:包含测试数据的 CSV 的 s3 路径。
批处理作业将通过环境变量传递这些变量的值。
2.将您的 Tensorflow 代码、训练数据和测试数据上传到 s3 中的文件夹。(样本训练代码和数据可参考 https://github.com/vigbk/tensorflow-ami-example的
运行批处理作业
创建以下 JSON 来指定批处理作业参数
按如下方式运行批处理作业。
aws batch submit-job --cli-input-json file://<path_to_json_file>/batch_job_spec.json
作业输出应该如下所示。
您可以通过 Amazon CloudWatch 控制台查看您的作业日志,或者使用以下命令从 cli 获取它
> aws logs get-log-events --log-group-name /aws/batch/job --log-stream-name TrainModel/default/876da822-4198-45f2-a252-6cea32512ea8--query events[*].message --limit 100
这就是所有的人…
有许多即插即用的解决方案可以在云中使用 Tensorflow 管理培训,但我希望这篇文章能够让您了解如何定制 Tensorflow 培训,从而在不牺牲性能的情况下降低成本。
如果你喜欢这篇文章,请随意点击“鼓掌”按钮👏帮助其他人找到它。
参考文献:-
- https://docs . AWS . Amazon . com/batch/latest/user guide/batch-GPU-ami . html
- https://docs . AWS . Amazon . com/AWS C2/latest/user guide/install-NVIDIA-driver . html
我是啰嗦的项目维护者之一,这是一个数据转换库。帮助我们在 GitHub 上宣传这个项目:https://github.com/productml/blurr
如何在亚马逊云上或没有监视器的情况下运行 Unity
原文:https://towardsdatascience.com/how-to-run-unity-on-amazon-cloud-or-without-monitor-3c10ce022639?source=collection_archive---------1-----------------------
经过几天的咒骂和诅咒,我设法让我的 Unity 应用程序在一台“无头”Linux 机器上运行和渲染,这台机器没有物理显示器。最终甚至在亚马逊云上!
最后,所有的问题都是由于 Unity 的而不是,而是配置操作系统和驱动程序的问题。一旦我设法让 OpenGL 样本 glxgears 在没有监视器的情况下运行,Unity 也能运行。
TL;DR: 给我准备好使用使用 GPU 的亚马逊磁盘镜像。
为什么有人想在没有显示器的情况下运行 Unity 应用程序?
如果你正在与机器学习合作— 教学代理通过查看像素来玩 Unity 游戏或在 Udacity 自动驾驶汽车模拟器中驾驶。如果你用合成图像来扩充训练集,或者简单地为你的电影渲染大量的帧,你可能想要在远程服务器上运行,在云中运行,或者至少在你自己的桌面上隐藏烦人的窗口。
你仍然需要渲染循环运行和 GPU 工作,所以通常的方法来运行 Unity 作为一个服务器是行不通的。
Linux 来拯救我们了!
在没有显示器的服务器上运行带有图形的 Unity 应用程序
假设你有 Linux box(我在 Ubuntu14.04) 上测试过)并且已经安装了 NVIDIA 驱动程序并且可以工作。
剩下的工作非常简单——配置虚拟显示器,运行 X 服务器,并确保在与 X 相同的显示器上启动应用程序:
在本地机器上运行 Unity 应用程序
当您的 DeepQ 代理正在学习时,隐藏烦人的窗口很有用。
安装虚拟和虚拟。xduminum 将在屏幕外创建新的虚拟显示,VirtualGL 将捕获传入的 OpenGL 调用,并在真实的 GPU 上执行它们。参见说明:
在亚马逊云上运行带有图形的 Unity 应用程序!
现在最有趣和最有价值的部分——在亚马逊弹性计算云(亚马逊 EC2) 上运行 Unity。
亚马逊提供了几个 GPU 选项:旧的 g2 实例和更快的 p2 实例。到目前为止,我在使用 Ubuntu 14.04 的 g2.2xlarge 单 GPU 实例上测试了以下内容。
最复杂的部分是找到正确的 NVIDIA 驱动程序,可以支持云上的 GPU。到目前为止,我发现 367.57 和 340.46 正在使用位于 g2 实例内部的 GRID K520 GPU。然而,安装程序有一个问题——它忘记将总线 ID 添加到配置中——需要手动修补文件。
你需要禁用 Ubuntu 自带的新驱动程序。他们对可怜的 K520 没有任何好处。
除此之外——构建并安装 X 服务器,设置虚拟显示并启动 X。
您的应用程序应该准备好在与 x 相同的显示器上启动。
如果你想知道更多关于 NVIDIA 驱动安装的细节,请关注:https://askubuntu . com/questions/429596/how-to-choose-the-VGA-when-setting-the-x-server/534622 # 534622
准备使用亚马逊启动映像
如果你不能被上面的步骤所困扰,那也没关系。我为你创建了可以在 Amazon 上运行 Unity 或任何其他 OpenGL 应用程序的引导磁盘映像(AMI)。
图片包含 Ubuntu 14.04,NVIDIA 驱动 367.57。在启动时,它用虚拟显示器启动 X 服务器。当然,所有的 OpenGL 调用都将在 GPU 上执行。
图像名为: Ubuntu 14.04,带有针对 GPU 加速 OpenGL 的虚拟显示设置,可在以下位置获得: us-west-1 、 us-west-2 和 us-east 。
要在亚马逊云上找到它,只需在 AMI 搜索栏中键入“ Ubuntu GPU ”或使用链接:https://console.aws.amazon.com/ec2/v2/home?region = us-west-1 # LaunchInstanceWizard:ami = ami-921 C40 f 2
PS: 出于测试目的,你可以下载我的小 Unity app,它会渲染一些盒子,抓取截图并写入磁盘:【https://www.dropbox.com/s/abycjktjzmkrmb4/auto.zip?dl=0】
如何破坏你的第一个生产模型?
原文:https://towardsdatascience.com/how-to-sabotage-your-first-production-model-54abb1a7f569?source=collection_archive---------1-----------------------
我听过很多关于生产中数据科学的恐怖故事。细节很重要,有两个潜在的危险直到为时已晚才显现出来。
Source: unsplash.com
Jason Bell 提供了数据科学模型如何在“数据科学最忽略的东西”中失败的很好的例子。
在这些例子中有两个主要的失败。一是问错了问题。另一个是使用了错误的评估程序。可惜这些技巧很难掌握,有很多微妙的层次。
问错误的问题
Jason Bell 指出,我们需要思考我们认为什么是胜利。"谷歌的广告活动会带来销售线索吗?"vs .“谷歌广告活动是否带来了销售线索,从而增加了销售额?”
谷歌“亚马逊
”,第一个广告通常是亚马逊。算法做的好吗?我不这么认为。在这种情况下,人们不会受到广告的影响,但他们仍然会点击它。这是最糟糕的!
有许多创造性的方法来问错误的问题,但是我将直接跳到一个解决方案。
当我们建立一个模型时,我们应该考虑如何使用我们的结果。一个成功的模型将提供信息或做出决定。这一决定可以说是一种干预或政策选择。从这个角度来说,借用节目评测的一些思路是有意义的。
项目评估着眼于项目和政策的效率和效果。该规程要求我们提出以下问题:
- 我们的模型所提供的干预是否有必要?
- 我们是否对干预将如何影响下游结果以及上游情景如何影响干预有了可行的理解?
- 干预的实施是否会反映我们心中的设计?
- 我们如何衡量干预是否成功?我们看到的是正确的结果吗?
- 干预的好处是否证明实施所需的成本是合理的?
一般来说,一个完整的项目评估是一个漫长的考验。然而,简单地询问这些问题并与最终用户交流将会避免许多概念性错误。
使用错误的评估程序
模型评估背后的直觉非常简单。我们希望根据其在生产条件下的表现来选择最佳型号。如果我们不能在生产中测试,我们最多只能模拟生产条件。我们将我们的数据分成训练数据和测试数据,以基于过去的数据来模拟未来的条件(参见交叉验证)。
做好这一点非常困难。选择合适的评估指标和无偏见的数据样本需要仔细关注。
错误的评估指标
选择错误的评估指标是一个常见的问题,与问错误的问题有关。这不是一个困难的选择,我们只需要仔细考虑结果变量和用例。当我们解决了错误的问题时,花哨的模型和 rockstar 编程并不重要。
我不禁想起了史蒂夫·斯基纳的《算法设计》手册中的“如何设计算法”一章。
我真的理解这个问题吗?
(a)投入具体包括什么?
(b)确切的预期结果或产出是什么?
(c)我能否构建一个足够小的输入示例,以便手动解决?当我试图解决它时会发生什么?
(d)我总能找到最佳答案对我的应用程序有多重要?我能满足于接近最优的答案吗?
(e)我的典型问题有多大?
(f)速度对我的应用程序有多重要?
(g)我可以在实施上投入多少时间和精力?
取样偏差
机器学习模型只有在它们被训练的环境与它们被使用的环境相同时才起作用。上下文只是意味着我们的训练数据代表了我们的生产数据。如果我们的训练数据不符合我们的用例,我们就有一个采样偏差问题。换句话说,我们收集了错误的训练数据。
采样偏差是无声的。它在数据收集、数据清理、特征工程和决策制定过程中悄悄潜入。
数据采集
在数据收集过程中,我们必须处理有限的数据,可能会选择与生产条件不匹配的样品。例如,我们可能会无意中使用现有的客户数据来预测新客户的行为。
不幸的是,存在一种选择偏差效应,某些类型的人成为现有客户,并意味着新客户的行为会有所不同。我们从现有客户那里学到的经验,对新客户来说只有很小的机会。
数据清理
在数据清理期间删除有问题的行来提高模型的性能是很诱人的。想象一下,将客户评论分为正面和负面情绪,有些评论太短,无法做任何有用的事情。
如果我们从测试数据和训练数据中删除所有非常短的评论,那么由于模糊性的减少,我们的模型很有可能会做得更好。然而,在生产系统中,我们将不得不处理简短的评论,我们的模型针对错误的上下文进行了优化。
让简短评论成为特例本身并没有什么错,但是我们的评估程序应该反映这种变化。开箱即用的评估程序会夸大我们模型的准确性。
特色工程
在特征工程和 ETL 过程中,我们经常想要生成数据的集合,比如均值、中位数等。需要为训练和测试数据分别生成这些聚合。
如果我们或其他人对整个数据集进行平均,那么我们会在测试过程中暴露训练数据中有关“未来”的信息。其结果是,我们会夸大我们的模型的有效性。即使训练和测试数据中的平均值几乎相同,这也是一个问题。
决策
决策给模型构建增加了一个奇怪的转折。当基于我们的模型做出决策时,它可能会影响我们建模的结果或我们使用的功能。在生产中评估我们的模型变得困难,并且在我们使用的数据中引入了抽样偏差。
当我们重用一个模型时,这就成了一个问题。我们在特征变量和结果变量之间引入反馈效应。
想象一下,一所大学决定为可能不及格的学生实施预警系统。根据学生过去的课程,我们会在注册时发出警告,以阻止学生注册,如果他们可能会失败。让我们假设识别学生的模型做得非常好。
第一学期,这种模式发挥了作用,提高了课程的通过率。更令人鼓舞的是,那些对自己有把握的学生忽略了警告,并经常成功地上了课。那些对自己没有信心的学生没有选修这门课,从而避免了不及格。
当我们再次尝试应用我们的模型时会发生什么?
如果我们使用旧模式,我们的信息可能会过时。它也从未见过无视警告系统的学生。他们是否与之前的学生群体有足够的差异,从而导致不准确?
如果我们训练一个新的模型呢?因为新的通过率更高,所以肯定会有不同的结果。背景也发生了变化,因为关注预警系统的学生不再反映在数据中。
不要放松警惕
如果您有幸拥有一个将用于生产的模型,请花一点时间考虑这些问题。它们不是复杂的想法,但却经常被忽视。大多数问题会在您处理数据时出现,但只有在有人尝试使用您的模型后才会出现。
如果您觉得这很有帮助,请推荐并分享,点击💚这样其他人就能看到了。
如何用机器学习节省 HR 的时间
原文:https://towardsdatascience.com/how-to-save-hrs-time-with-machine-learning-b6f2226b789d?source=collection_archive---------2-----------------------
上周末,我参加了 WNS 分析向导 2018 ,机器学习在线黑客马拉松。在 72 小时内,1000 多名参与者解决了 WNS 分析公司的一个任务。在这篇文章中,我将描述一种技术方法,它帮助我在这次活动中获得了第四名,并给你一些关于我的解决方案的商业价值的想法。
挑战简介
在这场竞争中,我们的客户是大型跨国公司 WNS 分析公司。他们想让我们找到合适的人选来升职。目前,这一过程包括几个步骤:
- 他们首先根据推荐和过去的表现确定一组员工;
- 被选中的员工将接受每个垂直行业单独的培训和评估计划。这些计划基于每个垂直行业所需的技能;
- 在计划结束时,根据各种因素,如培训绩效、KPI 完成情况(仅考虑 KPI 完成率高于 60%的员工)等。,一名员工获得晋升。
The pipeline of a promotion process
正如你可能猜到的,整个过程需要很多时间。加快速度的一个方法是在检查点确定合适的候选人,这样公司可以节省时间和金钱。我们将使用数据驱动的方法来预测候选人是否会被提升。我们的预测将基于员工从提名晋升到关卡的表现以及人口统计特征的数量。
竞赛问题被公式化为一个二元分类任务,评价指标是 F1 得分。训练集包括 54808 个样本,测试集包括 23490 个样本。只有 8.5%的员工被推荐晋升。
Dataset features explanation
验证策略
验证策略在所有数据驱动的任务中至关重要,尤其是在竞赛中。在比赛开始时,我假设测试数据来自不同的分布,然后是训练数据。如果训练/测试分割是由某个时间变量完成的,而组织者并没有提供该时间变量,则可能会出现这种情况。在这种情况下,StratifiedKFold
进行的简单验证得出的分数可能会高估我们的真实分数和在排行榜上的预期位置。
我决定根据属于测试集的可能性,将训练数据集分成若干部分。这是一种简单而强大的技术,用于处理训练/测试零件中的不同分布。这种方法的思想很简单:在解决任何机器学习任务之前,我们计算每个训练样本出现在测试集中的可能性。它允许我们:
- 确定明显区分训练数据集和测试数据集的特征。这些特征经常导致过度拟合(即它们是无用的),我们可能会丢弃它们以增加模型的分数。此外,我们可能会从这些特性的本质中获得一些见解;
- 确定与测试示例非常相似的训练样本(即“异常值”)。我们可以照亮这些样本,在训练期间给它们较低的权重,或者在训练和验证期间给它们较低的权重。根据我的经验,它总是在验证和排行榜上增加一个分数;
- 进行更好的验证。我们希望我们的验证折叠具有与测试集完全相同的分布(这正是验证的理念)。通过在折叠中随机分割训练,我们可能会在这样一种情况下结束,其中几个折叠由与测试集相似的例子组成。我们不能依赖这种分裂的分数,因此我们的验证是无用的。通过作为测试集的一部分的相似性进行划分可以帮助我们克服这个问题。
为了执行这项技术,我添加了一个新的特性:is_test
,它等于训练部分的0
和测试部分的1
。我将两个数据集结合在一起,预测了新的目标— is_test
。
import pandas as pd
import numpy as np
from scipy.stats import rankdata
from [sklearn.model_selection](http://scikit-learn.org/stable/modules/classes.html#module-sklearn.model_selection) import cross_val_predicttrain['is_test'] = 0
test['is_test'] = 1
train_examples = train.shape[0]
train = train.drop('is_promoted', axis=1)
data = pd.concat([train, test], axis=0).reset_index(drop=True)data_x = data.drop('is_test', axis=1)
data_y = data['is_test']is_test_probs = cros_val_predict(some_ml_model, data_x, data_y, method='predict_proba')[:train_examples]train['is_test'] = rankdata(is_test_probs)
bins = np.histogram(train['is_test'])[1][:-1]
train['is_test_bins'] = np.digitize(train['is_test'], bins)# use 'is_test_bins' as stratification
然而,这种方法在这次比赛中并没有帮助我。该任务的 AUC 分数约为 0.51,这清楚地表明分类器不能区分训练和测试部分(测试数据类似于训练数据)。我决定用 11 折的StratifiedKFold
来代替。
预处理和特征工程
我用一个新的类别missing
填充了education
和previous_year_rating
中缺失的值。所有其他要素都没有缺失值和异常值,该数据集使用起来非常舒适。
我添加了一些特征,作为分类特征和与员工年龄相关的特征的组合,它们略微增加了分数:
train['work_fraction'] = train['length_of_service'] / train['age']
test['work_fraction'] = test['length_of_service'] / test['age']train['start_year'] = train['age'] - train['length_of_service']
test['start_year'] = test['age'] - test['length_of_service']
此外,我注意到avg_training_score
是分类器的一个重要特性,所以我创建了一堆带有分类特性和avg_training_score
的组合。例如,新特性avg_training_score_scaled_mean_department_region
是avg_mean_score
除以特定地区和部门的平均分数的结果。从下图中可以清楚地看到,这种类型的归一化对于分类器来说是一个很好的特性。一个人的分数高于所在部门的平均水平,就有更大的机会得到提升。
The distributions of avg_training_score
for a positive and negative target are presented on left figure. The distributions of avg_training_score divided on the mean scores of each department_region
are presented on the right figure
为了使我的模型多样化,我使用了几种方法来处理分类特征:标签编码、一键编码和均值编码。均值编码通常会增加具有多层次分类特征的任务的得分。但另一方面,平均值编码的不正确使用可能会损害分数(见下图)。均值编码的正确方法是将数据集分成几个折叠,并在每个折叠内分别执行均值编码。
Results of playground experiments with Click-Through Rate Prediction dataset and mean encoding (LogLoss metrics). The wrong approach to mean encoding will gradually increase CV score, but dramatically decrease leaderboard score
训练有素的模特
我在 11 个折叠(总共 55 个模型)上用不同的预处理策略训练了 3 个 CatBoost 和 2 个 LightGBM:
- CatBoost — 1
旧功能+标签编码 - CatBoost — 2
旧功能+新功能+标签编码 - CatBoost — 3
旧功能+新功能+平均编码 - LightGBM — 1
旧功能+新功能+ MeanEncoding - LightGBM — 2
旧功能+新功能+ OHE
对于每个模型,我在StratifiedKFold
中对不同的模型使用了不同的种子(只要我不打算堆叠,那就可以了)。对于每个折叠,我根据折叠的 F1 分数来确定最佳阈值。最后的预测是 55 个模型的主要投票。最佳单个模型的交叉验证 F1 得分为 0.5310,最终模型为 0.5332,私人得分为 0.5318(公共排行榜第 20 位,私人排行榜第 4 位)。永远相信你的简历!
Row-wise normalized confusion matrix of the best submit, F1 score is equal to 0.5432
总结
我们如何解释这场比赛的结果?我认为有很大的改进余地。首先,我认为问题的焦点应该从“谁应该被提升?”到“员工必须做些什么才能获得晋升?”。在我看来,机器学习工具应该为一个人指明道路,这样他就会有清晰的理解和动力在工作中取得成功。一个小小的焦点改变会让一切变得不同。
第二,在我看来,即使是最好的模型,分数结果也是相当差的。如果它的性能比人更好,这可能是有用的,但 WNS 分析公司可能会考虑在决策过程中添加更多数据。我说的是增加更多与促销过程无关的功能,而是在促销过程开始之前,增加与员工工作相关的 KPI。
最后,我为这次比赛的结果感到高兴。对我来说,这是一场很好的比赛。在这次竞赛中,我已经在真实世界的数据集上测试了几个想法;设置半自动管道进行混合和堆叠;处理数据,并完成了一些明显的特征工程以外的工作。
更别说很好玩了:)
如何扩展您的机器学习管道
原文:https://towardsdatascience.com/how-to-scale-your-machine-learning-pipeline-dc820bb9460c?source=collection_archive---------5-----------------------
使用 Luigi、Docker 和 Kubernetes 并行化和分发您的 Python 机器学习管道
kurzgesagt.org
本文介绍了将您的机器学习应用程序从简单的 Python 程序转变为运行在集群上的可伸缩管道的最简单方法。
查看 Github 库中现成的示例代码。
您将学到的内容:
- 如何使用
[luigi](http://luigi.readthedocs.io/)
管理任务 - 如何用
[click](http://click.pocoo.org/6/)
轻松创建 python 脚本的命令行界面 - 如何在多个 Docker 容器中运行管道
- 如何在您的机器上部署小型集群
- 如何在集群上运行应用程序
不要计算两次——Luigify 你的管道
您的应用程序中的一些函数可能非常耗时,并且会返回大量输出,因此,如果您的管道在运行过程中出现故障,无论出于什么原因,修复一个小错误并重新运行所有内容都将花费您大量的时间和精力。
让我们做点什么吧。
假设您的管道需要做以下事情:
- 获取最近 10 天的数据;
- 转换数据;
- 用两种不同的模型做预测。
您可以像这样编写工作流:
但是这段代码很容易出错,比如在下载数据时可能发生的错误——一个网络错误,您所做的所有工作都会丢失。此外,如果您今天下载了最近十天的数据,并计划明天再次运行相同的管道,再次下载 90%的必要数据没有多大意义。
那么如何才能避免同样的事情做两次呢?
当然,您可以想出如何保存和重用中间结果的想法,但是没有必要自己编写代码。
我推荐使用[luigi](http://luigi.readthedocs.io/)
套装。它让您可以轻松地将代码划分为单独的数据处理单元——称为任务——每个单元都有具体的需求和输出。
您的任务之一可能如下所示:
从这个片段中,我们可以看到:
- 任务名称为
TransformData
; - 任务有一个参数,即
date
; - 这取决于
FetchData
类的十个任务,前十天各一个; - 它将其输出保存在一个以
date
参数命名的 CSV 文件中。
下面我给出了一个完整的虚拟管道的例子。花点时间分析任务的依赖关系是如何创建逻辑管道的:
现在,当您尝试运行MakePredictions
任务时,Luigi 将确保所有上游任务都提前运行。尝试用pip install luigi
安装 Luigi,将上面的例子保存在task-dummy.py
中,然后运行这个命令:
PYTHONPATH=. luigi --module task-dummy MakePredictions --date 2018-01-01 --local-scheduler
此外,当输出已经存在时,Luigi 不会运行任何任务。尝试再次运行相同的命令——Luigi 将报告给定日期的MakePredictions
已经完成。
在这里你可以找到另一个帮助你开始学习 Luigi 的好例子。
免费并行— Luigi workers
我可以同时运行多个任务吗?
是的,你可以!Luigi 提供了开箱即用的功能。例如,只需在命令中添加
--workers 4
,就可以让 Luigi 同时运行四个任务。
让我们利用这个机会来介绍一下 Luigi 的图形界面。
打开第二个终端并运行以下命令:
luigid
这将启动一个所谓的中央 Luigi 调度器,它监听默认端口 8082。你可以在你的浏览器上查看它漂亮的仪表盘: http://localhost:8082 。
现在回到第一个终端——您可以再次运行 Luigi 命令,这一次不带--local-scheduler
参数(不要忘记删除您已经创建的文件,或者选择另一个日期来查看任务的执行情况)。如果需要并行,在命令中添加--workers 4
。刷新仪表板页面后,您应该会看到一个计划任务列表。点击MakePredictions
任务旁边的树图标,查看它所有的依赖项(是不是很漂亮?):
大规模并行—迁移到集群
现在我们开始认真起来——如果一台机器不足以让您并行运行任务,您可以将您的管道提升到下一个级别,并将其部署在集群上。我会引导你完成所有必要的步骤。
在前面的示例中,所有文件都保存在执行任务的同一台计算机上。
那么,如何在集群中的多台机器之间共享文件呢?
这个问题有很多答案,但我们将专注于其中一种可能的方式——使用亚马逊的 S3。
AWS S3 是一个简单的存储服务。它可以让你把你的文件存储在云端。你将文件保存在s3://bucket/data/file.csv
下,而不是/home/user/data/file.csv
。Python 提供了一些工具,可以轻松地从本地存储切换到 S3。
为了简化本教程,如果你想遵循下面的说明,我需要你 建立一个免费的 AWS 试用帐户 你将使用它来存储你的文件。你可以在这里做而且一年内完全免费。如果你不再需要它,你可以选择退出。
创建账户后,到 这里 创建一个桶。把一个桶想象成硬盘上的一个分区。
为了从 S3 读取和写入数据,我们将使用luigi.contrib.s3.S3Target
类。您可以通过简单地添加一个适当的导入并替换任务定义中的LocalTarget
来修改这个虚拟示例,正如我在这里所做的:
你还需要删除所有的self.output().makedirs()
来电,因为你不需要在 S3 上创建文件夹。
要使用 Luigi 的 S3 功能,您必须pip install boto3
。
您还需要为 S3 认证提供您的应用程序凭证。让我们使用最简单的方法:您可以在站点上创建一个新的访问密钥。您将获得一个访问密钥 ID 和一个秘密访问密钥——分别保存在环境变量AWS_ACCESS_KEY_ID
和AWS_SECRET_ACCESS_KEY
中。
现在,您的应用程序应该能够读写 AWS S3 的数据。通过再次运行管道来尝试一下。
将您的管道容器化,放在一个集群上
可悲的是,你不能把你的 Python 代码放在一个集群上,然后直接执行它。但是,您可以在某个容器中运行某个命令。
我将向您展示如何重构您的管道,以便在单独的 Docker 容器中运行每个任务。
将您的任务转化为迷你程序—通过点击添加一个简单的 CLI
在容器中运行任务的第一步是让它们可以从命令行运行。
用 Python 写 CLI 最快的方法是什么?
回答:点击。Click 是一个非常棒的软件包,它使得创建命令行界面变得非常容易。
让我们回到TransformData
任务的例子(不是虚拟的)。它的run()
方法调用两个函数,即transform_data
和save_result
。假设这些函数是在名为transform.py
的文件中定义的:
现在让我们从命令行运行这些功能:
这里,我们定义了一个函数(cli
),当我们从命令行运行这个脚本时会调用这个函数。我们指定第一个参数将是一个输出路径,所有进一步的参数将组成一个输入路径元组。运行pip install click
之后,我们可以从命令行调用数据转换:
*python transform.py s3://your-bucket/output.csv input1.csv input2.csv*
为了方便起见,我们把我们的项目叫做tac
(为什么不重要)。如果您将setup.py
添加到项目中,并将pip install
添加到项目中(查看示例项目以了解项目应该如何构建,并且不要忘记将__init__.py
添加到包目录中),您应该能够运行您的脚本:
*python -m tac.transform s3://your-bucket/output.csv input1.csv input2.csv*
让东西变得可移植——在容器中运行任务
现在的问题是:
如何轻松创建一个 Docker 容器来运行我的命令?
嗯,那很简单。
首先,在项目根目录下创建一个requirements.txt
文件。您将需要以下软件包:
*click
luigi
boto3
pykube # we'll talk about this one later*
现在,在项目根目录下创建一个Dockerfile
,并将它放入:
*FROM python
COPY requirements.txt /requirements.txt
RUN pip install -r /requirements.txt
COPY . /tac
RUN pip install /tac
ARG AWS_ACCESS_KEY_ID
ENV AWS_ACCESS_KEY_ID=${AWS_ACCESS_KEY_ID}
ARG AWS_SECRET_ACCESS_KEY
ENV AWS_SECRET_ACCESS_KEY=${AWS_SECRET_ACCESS_KEY}*
让我们来分解一下:
FROM python
给我们一个安装了 python 的基础映像。COPY requirements.txt /requirements.txt
和RUN pip install -r /requirements.txt
安装所有需要的软件包。COPY . /tac
和RUN pip install /tac
安装我们的项目。- 最后四行将让我们在构建时在映像中设置 AWS 凭证(这不是一个好的做法,但让我们保持本教程简单)。
现在,您可以通过从项目根目录执行来构建包含项目的 Docker 映像(假设您在 env 变量中仍有 AWS 凭证):
*docker build -t tac-example:v1 . --build-arg AWS_ACCESS_KEY_ID=$AWS_ACCESS_KEY_ID --build-arg AWS_SECRET_ACCESS_KEY=$AWS_SECRET_ACCESS_KEY*
因此,您刚刚构建了一个标记为tac-example:v1
的 Docker 映像。让我们看看它是否有效:
*docker run tac-example:v1 python -m tac.transform s3://your-bucket/docker-output.csv input1.csv input2.csv*
这应该会在您的 S3 存储桶中保存一个docker-output.csv
文件。
与集群对话—准备要在 Kubernetes 中运行的任务
如果您想在一个集群中运行所有或者部分管道任务,Luigi 提供了一个解决方案。
看一看uigi.contrib.kubernetes.KubernetesJobTask
。
长话短说,Kubernetes 是一个可以管理集群的系统。如果你想和一个集群互动,可以和 Kubernetes 交流。
要在集群中运行一段代码,您需要向 Kubernetes 提供以下信息:
- 应该用于创建容器的图像;
- 应为容器指定的名称;
- 应该在容器中执行的命令。
让我们修改来自虚拟管道的旧任务TransformData
,以符合这些需求。
- 首先,将基类更改为“KubernetesJobTask”:
*from luigi.contrib.kubernetes import KubernetesJobTask
class TransformData(KubernetesJobTask):
date = luigi.DateParameter()*
- 给它起个名字:
*@property
def name(self):
return 'transform-data'*
- 定义应该运行的命令:
*@property
def cmd(self):
command = ['python', '-m', 'tac.transform',
self.output().path]
command += [item.path for item in self.input()]
return command*
- 提供要传递给 Kubernetes 的信息:
*@property
def spec_schema(self):
return {
"containers": [{
"name": self.name,
"image": 'tac-example:v1',
"command": self.cmd
}],
}*
- 删除
run()
方法,因为它是由KubernetesJobTask
实现的。 - 此外,运行
pip install pykube
,因为这是KubernetesJobTask
的要求。
您应该会得到类似于您在示例项目中看到的东西。
但是在连接到集群之前,我们无法运行它。继续读。
家居集群— Kubernetes 和 Minikube
如何在不访问集群的情况下在集群中运行管道?
最酷的是,你实际上可以在你的笔记本电脑上运行一个真实集群的迷你版本!
你可以用 Minikube 来做这件事。Minikube 在您计算机上的虚拟机内运行单节点(单机)集群。
现在花点时间安装 Minikube。你可以在这里找到说明。你需要这些说明中提到的所有部件。
安装后,您应该能够运行
*minikube start*
启动您的本地集群。耐心点,因为这可能需要一段时间,尤其是当你第一次做的时候。验证您的群集正在运行
*kubectl cluster-info*
您应该会看到类似如下的内容:
*Kubernetes master is running at https://192.168.99.100:8443
KubeDNS is running at https://192.168.99.100:8443/api/v1/...*
如果一切正常,您应该能够访问 Kubernetes 的仪表板,其中显示了您的集群的当前状态:
*minikube dashboard*
将会打开一个新的浏览器选项卡,并向您显示以下内容:
由于集群运行在一个单独的(虚拟)机器上,它不能访问您的 Docker 映像(因为您没有将它推送到任何在线注册表)。我们将使用一个小技巧来克服这一点。
以下命令会将您当前的控制台会话设置为不使用本地 docker 引擎,而是使用集群虚拟机的 Docker 引擎来执行 Docker 命令:
*eval $(minikube docker-env)*
现在你需要做的就是再次调用docker build
命令。这一次,您的映像将构建在虚拟机内部:
*docker build -t tac-example:v1 . --build-arg AWS_ACCESS_KEY_ID=$AWS_ACCESS_KEY_ID --build-arg AWS_SECRET_ACCESS_KEY=$AWS_SECRET_ACCESS_KEY*
关键时刻到了。
我们将在刚刚配置的集群中执行管道。
如果一切顺利,只需调用 Luigi 命令就足够了。Minikube 已经设置了适当的配置,所以KubernetesJobTask
知道目标 Kubernetes 在哪里运行。
所以试着从task-dummy.py
所在的目录执行这个命令:
*PYTHONPATH=. luigi --module task-dummy MakePredictions --date 2018-01-01*
并观察您的TransformTask
作业如何在集群中运行:
尾注
- 如果
KubernetesJobTask
报告如下消息:No pod scheduled by transform-data-20180716075521-bc4f349a74f44ddf
并且无法运行,这可能是 Luigi 错误,而不是您的错。检查仪表板,查看transform-data-…
Pod 是否处于状态Terminated:Completed
。如果是这样,那么任务实际上已经完成,再次运行管道应该可以解决问题。 - 考虑一下 Google Kubernetes 引擎如何构建一个真正的集群。
- 当使用谷歌的集群时,考虑从 AWS S3 切换到谷歌云存储,以显著加快数据访问速度。这个模块应该会有帮助。
- 阅读更多关于使用 Dask 和 Kubernetes 加速管道的信息。
原载于www.datarevenue.com。
如何使用 Python 和 ScraPy 蜘蛛抓取网页
原文:https://towardsdatascience.com/how-to-scrape-the-web-using-python-with-scrapy-spiders-e2328ac4526?source=collection_archive---------2-----------------------
Each of those hairs scrapes. Source: Pixabay
有时候 Kaggle 还不够,还需要自己生成数据集。
也许你需要你正在训练的这个疯狂的卷积神经网络的蜘蛛图片,或者也许你为了,嗯,科学的目的想要刮 NSFW 子网格。不管你的理由是什么,浏览网页可以给你带来非常有趣的数据,并帮助你汇编令人惊叹的数据集。
在本文中,我们将使用 ScraPy 来抓取 Reddit 子编辑并获取图片。
有些人会告诉我使用 Reddit 的 API 是一种更实用的获取数据的方法,这绝对是真的。确实如此,我可能很快会写一篇关于它的文章。
但是只要我们做得很少,并且不要让 Reddit 繁忙的服务器超负荷工作,应该没问题。所以请记住,本教程仅用于教育目的,如果你需要 Reddit 的数据,你应该使用官方渠道,比如他们的牛逼 API 。
那么,我们如何着手清理网站呢?让我们从头开始。
检查机器人. txt
首先我们将进入 reddit.com/robots.txt。对于一个站点来说,习惯上是让他们的 robots.txt 文件可以从他们的主域访问。它遵循以下格式:
User-agent: <pattern>
Disallow: <patterns>
其中 U ser-agent 描述一种设备类型(我们属于,通配符模式),而 Disallow 指向一个我们无法抓取的 url 模式列表。
我在那里没有看到/r/,所以我觉得刮一个 subreddit 的主页也可以。出于礼节,我仍然建议你在任何严肃的项目中使用 API。
不尊重一个网站的 robots.txt 文件可能会有法律后果,但这主要只是让你看起来像一个卑鄙的人,我们不希望这样。
建立我们的项目。
为了用 Python 抓取网站,我们将使用 ScraPy,它是主要的抓取框架。有些人喜欢美丽的声音,但我觉得 ScraPy 更有活力。
ScraPy 的基本抓取单元叫做蜘蛛,,我们将通过创建一个空蜘蛛来开始这个程序。
因此,首先,我们将安装 ScraPy:
pip install --user scrapy
然后我们将开始一个零碎的项目:
scrapy startproject project_name
您可以在此输入任何内容,而不是项目名称。该命令将创建一个目录,其中包含许多文件和 python 脚本。
现在,对于我们的最后一个初始化命令,我们将创建我们的第一个蜘蛛。为此,我们将运行 scrapy 的 genspider 命令,该命令将一个蜘蛛的名称和一个域 url 作为其参数。我会给我的取名为小猫捕手(小心:剧透)和爬行reddit.com/r/cats。
scrapy genspider kitten_getter reddit.com/r/cats
现在我们只进入/spider目录,不关注其余部分。和往常一样,我在GitHub 项目中发布了我的代码。
搭建我们的第一只蜘蛛
在蜘蛛目录中,我们将打开名为 kitten_getter.py 的文件并粘贴以下代码:
这里发生了什么事?嗯,每个蜘蛛需要三样东西:一个解析方法,一个开始请求方法,和一个名称。
- 每当我们从控制台启动蜘蛛时,都会使用蜘蛛的名称和。
- 从控制台运行 spider 将使其从 start_requests 例程启动。
- 我们让例程在 URL 列表上执行 http 请求,并在它们的 http 响应上调用我们的解析方法。
为了运行它,我们所要做的就是在项目的目录中打开我们的终端并运行:
scrapy crawl kitten_getter
释放你的蜘蛛!让他们漫游网络,攫取宝贵的数据。
如果您运行该命令,它将运行我们刚刚编写的蜘蛛,因此它将发出请求,获取我们提供的 url_list 中第一个 url 的 HTML,并按照我们要求的方式解析它。在这种情况下,我们所做的就是将整个响应直接写入一个名为“kitten_response0”的文件中(大小约为 140Kb)。
如果你打开它,你会看到它只是我们刮的网站的 HTML 代码。这对我们的下一个目标很有用。
识别模式
如果你去链接reddit.com/r/cats寻找小猫图片,你会注意到有两种帖子。
- 点击链接到评论区的文章。
- 直接指向 pic 的帖子
我们还注意到,我们无法在不违反 robots.txt、的情况下找到任何与reddit.com/r//comments/**匹配的内容,因此从帖子中提取图片是错误的。然而,如果图片直接链接到 subreddit 的主页,我们可以获得图片的 URL。我们看到那些链接总是在一个<>标签中的 href 属性,所以我们要做的是调用响应对象的 xpath 方法来获得它们。
xPath 是一种在网站的 HTML 树中移动并获取其中一些元素的方法。Scrapy 还为我们提供了 css 方法,它允许一种不同的索引和标记元素的方式。我个人发现在浏览器中右键单击一个元素,点击 inspect,然后 copy xpath 是一种快速的开始方式,然后我只是稍微摆弄一下输出。
在这个特殊的例子中,因为我们需要的只是每个<>元素的 href 值,我们将调用
response.xpath(‘//a/@href’)
这将为每个 href 值(ScraPy 库中的一个对象)返回一个迭代器。然后,我们通过调用 extract 方法提取该值的字符串形式,并通过查看它是否以'结尾来检查它是否实际上是一个到图像的链接。png '或'。jpg。
下面是整个改进的解析方法,它现在还创建了一个 html 文件来显示所有图像,而无需下载它们:
因此,我们让我们的蜘蛛再次爬行,输出应该是这样的:
Crawled (200) <GET [https://www.reddit.com/r/cats/](https://www.reddit.com/r/cats/)> (referer: None)
[https://i.imgur.com/Au0aqkj.jpg](https://i.imgur.com/Au0aqkj.jpg)
[https://i.imgur.com/Xw90WFo.jpg](https://i.imgur.com/Xw90WFo.jpg)
[https://i.imgur.com/fOINLvP.jpg](https://i.imgur.com/fOINLvP.jpg)
其中每个链接都是一只可爱小猫的图片。作为奖励,文件kittens.html应该洋溢着可爱。
就是这样!您已经成功抓取了您的第一个网站!
保存图像
假设我们想下载图片,而不是制作一个 HTML 文件。然后我们要做的是导入 Python 的请求库,以及 unicodedata 库。请求将完成这项繁重的工作,但是我们需要 unicodedata ,因为提取的字符串默认为 unicode ,而请求需要 ASCII 码。
现在,我们将传递我们的 scrapy,而不是解析方法。请求函数将下面的函数作为回调参数:
它所做的只是下载一张图片,并将其保存为 JPG。它还自动增加存储在蜘蛛中的索引属性,为每张图片命名。
到处玩:交互式 shell
ScraPy 为我们提供了一个交互式的 shell,在这里我们可以尝试不同的命令、表达式和 xpaths。这是一种比用 crawl 命令一遍又一遍地运行整个程序更有效的迭代和调试蜘蛛的方式。要启动 shell,我们只需运行以下命令:
scrapy shell ‘http://reddit.com/r/cats’
当然,这个网址可以用其他任何网址代替。
伸出我们的蜘蛛
如果我们想得到更多的图像,我们可以让 download_pictures 方法调用 scrapy。请求下一页的 URL 上的,可以从“下一页”按钮的 href 属性中获得。我们还可以让蜘蛛将 subreddit 作为参数,或者更改下载的文件扩展名。
总而言之,最好的解决方案通常是最简单的,所以使用 Reddit 的 API 会让我们省去很多麻烦。
我希望你现在能够制作自己的蜘蛛,并获得自己的数据。请告诉我您是否觉得这很有用,以及您认为使用此工具可以生成什么样的好数据集—越有创意越好。
最后,还有一本我喜欢的奥莱利的书。当我开始我的数据科学之旅时,我发现它非常有用,它让我接触到了一个不同的、更容易使用(尽管不太灵活)的 Web 抓取框架。用 Python 叫做从零开始的数据科学,大概也是我得到这份工作的一半原因。如果你读到这里,你可能会喜欢它!
关注我,获取更多 Python 教程、技巧和诀窍!
你可以在我的 个人网站 中看到我正在做的事情以及我最近的文章和笔记。
如何为 SparkSQL 设置经济高效的 AWS EMR 集群和 Jupyter 笔记本电脑(2020 年 11 月更新)
原文:https://towardsdatascience.com/how-to-set-up-a-cost-effective-aws-emr-cluster-and-jupyter-notebooks-for-sparksql-552360ffd4bc?source=collection_archive---------8-----------------------
高级数据科学技能
Photo by Myriam Jessier on Unsplash
这是一篇基于我个人工作笔记的生活类文章。随着时间的推移,AWS 界面和选项发生了很大的变化,所以我会在空闲时间不断更新本文。
我在一家国际信息服务公司工作,处理来自各个领域的数百个数据源,因此本文的主题对我和许多其他人来说都很重要。不要浪费时间处理我已经有的问题!
入门指南
创建 EMR 集群有三种主要方式:
- 从头开始创建一个,这在本文中有详细介绍。
- 克隆现有的 EMR 集群。如果您正在克隆其他人的集群,您只需更改集群名称、指定您的 RSA 密钥、启用集群自动缩放并更改集群标签(即
*creator*
、*product*
等)。一些公司使用标签来自动应用规则到你的集群,像闲置 X 分钟自动终止,S3 数据访问权限和会计/预算。)您要克隆的集群不必当前处于活动或运行状态,即它可以处于terminated
或running
状态。我喜欢使用如下的命名分类法,因为它具有足够的描述性和唯一性,我可以在以后的克隆中找到:
project-name_myuseridANYOUNG_DDMM_spark.
一旦你创建了一个特定于你的项目类型的集群,这个过程在将来会更加简单,因为你不需要改变你的集群标签,只需要偶尔改变你的集群名称。 - 使用 AWS CLI。这是最快最有效的方法。但是,这也是最先进的方法,并且配置最适合您项目的参数的前期成本很高。对于本文的读者来说,我只在尝试了前两种方法后才推荐这种方法。
步骤 0:创建 EMR 集群
选择右上方的区域。区域影响成本和延迟,这与实时应用相关。点击Create cluster
按钮。
Image source: author, taken Nov. 2020.
步骤 1:软件配置
点击"Go to advanced Options."
Image source: author, taken Nov. 2020.
选择如下所示的配置,然后单击下一步。
I recommend installing more software than you need if: 1. you work on a variety projects 2. you want a one-size-fits-most cluster to clone in the future. Image source: author, taken Nov. 2020.
Image source: author. Taken Nov. 2020.
如果您打算在笔记本中安装 Python/Scala 包和 SQL 函数,请确保选择的Release
是emr-5.30.0
。有些包,尤其是实现新算法的包,不能通过带有!pip install
或pypi
的笔记本安装在集群的所有节点上。在撰写本文时,无论是我还是多个企业 AWS 技术支持成员(国外和美国都有,如果这对你很重要的话)都无法在任何更高版本的emr
上安装包,尽管进行了数周的试验。坦率地说,我在使用 emr-5.30.0 版本时没有遇到任何问题,尽管目前有这么多更新的版本。
Software configuration that I recommend for a one-size-fits-most cluster. Image source: author, taken Nov. 2020.
默认情况下,选择并安装 Hadoop、Hive 和 Ganglia 应用程序。你将不得不添加火花和其他你可能需要的。安装比您需要的更多的软件的后果是,集群将需要更长的启动时间,但在大多数情况下,额外的等待时间可以忽略不计。
一个可选步骤优化您的集群以读取存储在 S3 的 Parquet 格式的文件,在 PySpark 数据框中处理它们,并防止在尝试从 Jupyter 笔记本中长时间运行 Spark 作业时出现常见错误。完成上述任务的代码,
Image source: author, taken Nov. 2020.
编辑软件设置,进入配置,添加以下 JSON 代码:
[{"classification":"spark","properties":{"maximizeResourceAllocation":"true"}},{"classification":"spark-defaults","properties":{"spark.network.timeout":"1500"}},{"classification":"hdfs-site","properties":{"dfs.replication":"2"}},{"classification":"livy-conf","properties":{"livy.server.session.timeout":"10h"}},{"classification":"emrfs-site","properties":{"fs.s3.maxConnections":"100"}}]
解释:
"maximizeResourceAllocation":"true" -- Configures your executors to utilize the maximum resources possible on each node in a cluster. This EMR-specific option calculates the maximum compute and memory resources available for an executor on an instance in the core instance group. It then sets the corresponding spark-defaults settings based on this information. [[reference](https://docs.aws.amazon.com/emr/latest/ReleaseGuide/emr-spark-configure.html#emr-spark-maximizeresourceallocation)]"livy.server.session.timeout":"10h" -- addresses errors from long-running Spark tasks in a Jupyter/EMR notebook that die after an hour of execution:
An error was encountered:
Invalid status code '400' from https://xxx.xx.x.xxx:18888/sessions/0/statements/20 with error payload: "requirement failed: Session isn't active." [[reference](https://stackoverflow.com/questions/54220381/how-to-set-livy-server-session-timeout-on-emr-cluster-boostrap)]"fs.s3.maxConnections":"100" -- addresses the “Timeout waiting for connection from pool” error [[reference](https://aws.amazon.com/premiumsupport/knowledge-center/emr-timeout-connection-wait/)]
步骤 2:硬件配置
选择内部 AWS 工程团队指定的网络和子网,或者保留默认设置。
对于 Spark 作业,建议申请以下实例数量和类型:
1 个主节点实例、
1 个核心节点实例、
1 个任务节点实例各 1-3 种不同类型,即r4.2xlarge
、r5.2xlarge
、r5.4xlarge
等。
Image source: author, taken Nov. 2020.
对于任务节点,选择现货定价,选择按需作为最高价格。我们愿意为主节点和核心节点支付“按需”价格,因为主节点总是需要对我们连续可用,而任务节点可以基于市场定价(“现货”定价)来来去去。
Image source: author, taken Nov. 2020.
在我上面的截图中,我显示按需价格是每实例小时 0.192 美元;相同实例类型、地区和日期的现货价格显示在左侧:0.040 美元/实例小时。按需定价几乎贵了 5 倍!
我推荐固定数量的实例的原因是因为我们正在构建一个自动伸缩的集群:实例的数量将根据您的工作的计算压力和您指定的自动伸缩规则而增加或减少。
在实施自动扩展规则之前,为每个 EBS 卷实例将核心和任务节点的 EBS 存储类型调整到至少 500 GB 的吞吐量优化 HDD (ST1) 。您还可以为每个“ EBS 卷实例”增加“实例的数量一般来说,我有两个卷实例,每个实例有 500 GB,核心总共有 1000 GB。如果您正在处理大数据,请添加更多实例/内存。主节点不需要 EBS 存储。
当在 S3 使用 Spark 时,中间数据被写入磁盘临时本地存储,而不是在 HDFS,因此当处理大型数据集时,为实例提供更多存储是有用的。我们选择 500 GB 的硬盘驱动器(HDD)而不是固态驱动器(SSD)上的 32 GB 存储,因为写入速度的瓶颈将是互联网速度而不是 HDD 写入速度,并且 HDD 更便宜。
步骤 2*:集群扩展(2020 年 7 月发布)
这对我来说是最重要的一步,也是 AWS 在 2020 年 7 月 7 日发布了 EMR 管理的自动缩放功能后最简单的一步。这曾经是一个非常痛苦、耗时的过程,但现在变得非常容易。自动缩放是这样完成的:
选中Enable Cluster Scaling
并使用默认Use EMR-managed scaling.
主节点不可伸缩,因此这只影响核心和任务节点。
根据我正在做的事情,我喜欢将核心和任务节点的最小数量保持在 1 到 3 之间。1 如果我正在试验一个新项目,3 如果我想安全行事,保证在关键任务的最后期限内不会出现任何问题。
- 简单来说:核心节点是数据存储,任务节点是计算。处理更大的数据?允许更多的核心节点以避免内存问题(进一步阅读: AWS 文档)
- 将最大节点数设置为一个较大但合理的数值。我根据自己的项目选择 250 到 1000 之间的一个数字。在理论和实践中,最大数量的节点只会在需要的时候被征用。但是,从理论上讲,用户错误和/或未知的未知因素也有可能导致您的集群占用大量接近无穷大的节点。一个合理的数字是一个防止预算超支的数字,并允许对你的最大燃烧速度进行一些控制。在三年多的时间里,我经常在 AWS 上处理数十 Pb 的数据,最大节点数不超过 1000 个,没有出现任何问题。
- 将按需限制设置为 0。我们不想为节点支付按需价格,因为它们比现货价格高 5 倍!我将随时以现货价格(每实例小时 0.040 美元)购买一个 m5.xlarge 节点,而不是以按需价格(每实例小时 0.100 美元)购买一个 m4.large 节点!(注意,这是指定多个实例类型允许您“套利”AWS 节点投标系统的地方,因为您可以以更低的采购成本获得更大的能力)。
- 将最大核心节点设置为接近但不等于最大值的高值。在下面的例子中,我将其设置为 200,最多 250 个节点。我这样做是为了让我的集群可以自由地分配我的节点;如果我需要的核心节点比任务节点多,那就给我弄来。
Image source: author, taken Nov. 2020.
步骤 3:常规集群设置
下面的要点后面提供了截图示例。
- 描述性地命名集群。这使您能够记住它的用途以及您仅通过查看名称就能设置的一些参数。我喜欢使用如下所示的集群命名分类法,因为它具有足够的描述性和唯一性,便于我日后进行克隆:
project-name_myuseridANYOUNG_DDMM_spark.
- 始终启用记录和调试。您需要同时启用这两个功能,以便对错误进行故障排除,或者在 AWS 技术支持下进行调试。
- 填写标签中的标签,以帮助跟踪贵公司工程团队指定的使用情况、预算和自动化集群策略。下面是标签示例:
创建者:输入你的名字或其他一些唯一的标识符。
项目:一个详细描述你正在进行的项目的有用名称。
部门:【数据科学 R & D、数据科学分析、其他】
环境:【开发、测试、生产】
克隆此群集时会复制这些设置,因此如果您要克隆其他人的群集,请根据需要进行更改。如果您正在克隆您自己的旧集群,您可能不需要做太多改变!
Image source: author, taken Nov. 2020.
步骤 3*:引导安装脚本
您需要一个引导脚本来在 EMR 集群的所有节点上安装软件包。以下是实现这一点的步骤:
- 用以下内容创建一个
.sh
文件并保存在 S3:
Author’s code
#!/bin/bash -xesudo pip install \
pandas \
numpy \
xgboost \
scikit-learn \
nbextensions
2.指定引导操作脚本 S3 位置:
Image source: author, taken Nov. 2020.
步骤 4:安全设置
如果您在大型企业环境中工作,您可能需要指定这些设置。选择您的 EC2 密钥对和 EC2 实例角色。我将撰写另一篇文章,介绍如何创建 EC2 密钥对,允许登录主节点进行故障排除/测试。下面的截图是一个虚拟的 AWS 帐户,所以我没有创建 EC2 密钥对,因此警告说不能 SSH 到它。
Image source: author, taken Nov. 2020.
步骤 5:创建后监视集群
点击创建集群后,仪表盘页面显示状态为开始,设置完成后变为【等待】。
请注意,您可以对正在运行的 EMR 集群进行动态调整。例如,您可以通过克隆一个“step”脚本并在 S3 将输入文件更改为新上传或修改的.sh
脚本来安装软件。
第六步:使用电子病历笔记本(2018 年 11 月发布)
命名并配置您的笔记本。将其附加到您创建的 EMR 集群。即使在 EMR 集群终止后,笔记本仍然存在。EMR 笔记本很好,因为您可以通过浏览器连接,每个包含 PySpark 代码的单元格在执行后都有其作业进度跟踪。
关于作者
安德鲁·杨是 Neustar 的 R&D 数据科学家经理。例如,Neustar 是一家信息服务公司,从航空、银行、政府、营销、社交媒体和电信等领域的数百家公司获取结构化和非结构化的文本和图片数据。Neustar 将这些数据成分结合起来,然后向企业客户出售具有附加值的成品,用于咨询、网络安全、欺诈检测和营销等目的。在这种情况下,Young 先生是 R&D 一个小型数据科学团队的实践型首席架构师,负责构建、优化和维护一个为所有产品和服务提供信息的系统,该系统为 Neustar 带来了超过 10 亿美元的年收入。(在 LinkedIn上关注他,了解数据科学的最新趋势!)
更多热门文章:
- 隔离森林是目前最好的大数据异常检测算法
- 高效数据科学家必备的演示工具
过时的说明(备案)
由于 AWS Engineering 于 2020 年 7 月 7 日发布,以下说明已过时:引入 Amazon EMR 托管扩展—自动调整集群大小以降低成本
接下来,定义自动扩展策略。对于核心节点,将最大实例数设置为 100(或其他合理的值),将最小实例数设置为 1。选中规则中默认的横向扩展和比例的复选框,因为它们性能良好。对于任务节点类型,将最大实例数设置为 50,最小实例数设置为 0。检查规则中默认横向扩展和比例的复选框,因为它们执行良好。如果由于某种原因默认规则不可见,请手动添加它们。有两个横向扩展规则:
- “rule1”:如果YARNMemoryAvailablePercentage比 15 小 1 五分钟,冷却时间 300 秒,则增加 1 实例。
- “规则 2”:如果 ContainerPendingRatio 大于 0.750.75持续 1 五分钟,冷却时间为 300 秒,则添加 1 实例。
在标尺中增加一个标尺:
- “rule1t”:如果YARNMemoryAvailablePercentage大于 75 持续 1 五分钟,冷却时间为 300 秒,则终止 1 实例。
任何横向扩展规则都不能与任何纵向扩展规则同名。注意,最大实例数在技术上是任意的,但是为了安全起见,不要给出一个荒谬的数字。大致来说,运行 10 小时的 10 节点集群的成本与运行 1 小时的 100 节点集群的成本相同,因此最好在需要时征用所需的节点。
如何用 Keras/Theano 在 AWS 上搭建深度学习环境
原文:https://towardsdatascience.com/how-to-set-up-a-deep-learning-environment-on-aws-with-keras-theano-b0f39e3d861c?source=collection_archive---------0-----------------------
更新:2017 年 5 月 19 日——在这篇文章中,我将一步一步地解释如何建立一个运行在亚马逊的 EC2 GPU 实例上的深度学习环境,使用:
- 图片:ami-b 03 ffedf(Ubuntu Server 16.04 LTS(HVM),SSD 卷类型)
- 区域:欧盟中部-1(欧盟法兰克福)
- 实例类型:g2.2xlarge
- 存储:30 GB(建议至少 20gb 以上)
软件:
- CUDA 8.0 / cuDNN 5.0
- 带 Python 3 的 Anaconda 4.20】
- Keras / Theano
1。创建一个新的 EC2 GPU 实例
Select the Ubuntu Server 16.04 LTS AMI.
Take the g2.2xlarge GPU Instance. Alternatively, you could also take the g2.8xlarge if you need more computing power.
Change the standard storage size to 30 GB.
Launch the cluster and assign an EC2 key pair.
2。在 GPU 实例上安装 CUDA/cud nn
NVIDIA 驱动程序
更新图形驱动程序:
$ sudo add-apt-repository ppa:graphics-drivers/ppa -y
$ sudo apt-get update
$ sudo apt-get install -y nvidia-375 nvidia-settings
CUDA
SSH 到 EC2 GPU 实例:
$ ssh -i ~/folder_key_pair/key_pair.pem ubuntu@public_dns_ec2
首先下载 CUDA 8.0 到你的$HOME 文件夹( /home/ubuntu ):
$ wget [https://developer.nvidia.com/compute/cuda/8.0/Prod2/local_installers/cuda-repo-ubuntu1604-8-0-local-ga2_8.0.61-1_amd64-deb](https://developer.nvidia.com/compute/cuda/8.0/Prod2/local_installers/cuda-repo-ubuntu1604-8-0-local-ga2_8.0.61-1_amd64-deb)
安装 CUDA:
$ sudo dpkg -i cuda-repo-ubuntu1604-8-0-local_8.0.44-1_amd64-deb
$ sudo apt-get update
$ sudo apt-get install -y cuda nvidia-cuda-toolkit
检查所有安装是否正确:
$ nvidia-smi
$ nvcc --version
cuDNN
接下来,在 NVIDIA 的加速计算开发者计划上注册一个帐户,并将 cuDNN 5.0 下载到您的本地机器上:
Select cuDNN v5 Library for Linux
将 TAR 归档文件 SCP 到 EC2 GPU 实例:
$ scp -i ~/folder_key_pair/key_pair.pem ~/folder_tar_file/cudnn-8.0-linux-x64-v5.0-ga.tgz ubuntu@public_dns_ec2:/home/ubuntu/
SSH 到 EC2 GPU 实例并解压缩文件:
$ tar -zxvf cudnn-8.0-linux-x64-v5.0-ga.tgz
最后,打开。巴沙尔然后加上这个:
export LD_LIBRARY_PATH=/home/ubuntu/cuda/lib64:$LD_LIBRARY_PATHexport CPATH=/home/ubuntu/cuda/include:$CPATHexport LIBRARY_PATH=/home/ubuntu/cuda/lib64:$LD_LIBRARY_PATH
重新装上。巴沙尔:
$ source ~/.bashrc
3。安装 Keras 和 Theano
在 EC2 实例上下载 Anaconda 并安装它:
$ wget [https://repo.continuum.io/archive/Anaconda3-4.2.0-Linux-x86_64.sh](https://repo.continuum.io/archive/Anaconda3-4.2.0-Linux-x86_64.sh)$ bash Anaconda3-4.2.0-Linux-x86_64.sh
注意:重新加载您的 bash 概要文件(源代码。bashrc)以便激活 Anaconda。
最后,安装 Keras 和 Theano:
$ pip install --upgrade --no-deps git+git://github.com/Theano/Theano.git$ pip install keras
注意:确保在 Keras 中将 Theano 用作后端。如果没有,您需要在 Keras 配置中更改它。keras/keras.json),通常在 python 中第一次导入后创建。
1 {
2 "backend": "theano",
3 "epsilon": 1e-07,
4 "floatx": "float32",
5 "image_dim_ordering": "th"
6 }
4。测试您的环境:
现在你可以走了!通常,我倾向于用一个简单的脚本来测试我的环境,看看是否一切都像预期的那样工作。
以下是一个用于训练 MNIST 数据集的简单 MLP 网络:
通过调用以下命令运行脚本:
$ THEANO_FLAGS=floatX=float32,device=gpu0,lib.cnmem=0.8,nvcc.flags=-D_FORCE_INLINES,dnn.enabled=True python mnist_gpu_test_script.py
或者,您可以在的 no 配置文件(中指定设置。theanorc ):
[global]floatX = float32device = gpu[lib]cnmem = 0.8[dnn]enabled = true[nvcc]flags = -D_FORCE_INLINES
注意:标志“nvcc.flags=-D_FORCE_INLINES”对于 Ubuntu 16.04 非常重要,因为 CUDA 8.0 似乎不支持默认的 gcc 版本(5.4.0)(参见 Ubuntu 16.04 和 CUDAglibc 2.23)的修复)。目前这是一个棘手的问题。或者,您也可以通过使用 update-alternatives 将 CUDA 链接到一个较旧的 gcc 版本(参见* 此处 )。*
最终,这里是输出:
We can see that cuDNN is enabled (cuDNN 5005).
注意:监视 NVIDIA 的系统管理界面以查看是否有一些活动也很有趣,例如内存使用、运行进程和 GPU 利用率。
*$ watch -n1 nvidia-smi*
结论/展望
在这篇博文中,我一步一步地描述了如何在 AWS 上建立深度学习环境。如果有不清楚的地方,请通过 twitter @datitran 联系我,或者关注我。在下一篇文章中,我将关注如何通过使用 docker 来自动化上面解释的那些步骤,从而极大地加快设置过程。
如何为深度学习设置一个强大且经济高效的 GPU 服务器
原文:https://towardsdatascience.com/how-to-set-up-a-powerful-and-cost-efficient-gpu-server-for-deep-learning-aa1de0d4ea56?source=collection_archive---------2-----------------------
Looking for GPU computational power for deep learning experimentations?
使用 Paperspace 和 fast.ai
语境
如果你打算开始你的深度学习之旅,并成为令人兴奋的深度学习实践者社区的一部分,你肯定需要设置一个 GPU 服务器。
在这篇文章中,我将介绍 Paperspace ,一个非常适合深度学习活动(以及其他)的虚拟机云提供商。尽管存在其他几种替代方案(亚马逊网络服务、谷歌云平台、微软 Azure 、 Crestle 、…)、,但我发现paper space使用起来非常方便,而且功能强大,性价比高。
I quickly adopted Paperspace as my perfect deep learning platform.
Paperspace 提供了一个现成的 fast.ai 模板。 fast.ai 是一个构建在 PyTorch 之上的超级便捷的深度学习框架,由杰瑞米·霍华德和瑞秋托马斯开发并教授;你肯定会想在某个时候尝试一下。
让我们来配置你的深度学习环境吧!
关于定价
Paperspace 提供有吸引力的定价选项。你确实可以以不到 40 美元的价格获得一台功能强大的机器,预计每月使用 40 小时。定价可详述如下:
- 一个公共 IP 地址每月 3$
- 250 GB 硬盘(存储)每月 7 美元
- 0.65 美元/小时对于一台 NVidia Quadro P5000 机器(RAM 30GB8 个 CPU,8GB GPU)
我上面提到的替代方案在我看来既不便宜也不简单。
注意:学习深度学习的另一个好方法(这也是我真心推荐的!)是跟随deep learning . ai的专精由吴恩达。这种在线课程(mooc)由 5 门课程组成(每门课程约 1 个月),每月 49 美元。稍微贵一点,但是仍然值得投资,因为 Andrew 也是一个很好的老师。
步骤 1:创建图纸空间帐户
如果你打算使用这项服务,这是非常明显的一步!您需要提供有效的电子邮件地址作为标识符,以及密码。
Enter valid email address + password to create your account.
一旦完成,你就可以在几分钟内创建你的深度学习 gpu 服务器。
步骤 2:创建一台机器
- 从https://www.paperspace.com/console/machines,点击‘新机器’按钮
You GPU server is only a few clicks away from this screen.
- 选择一个地区(选择离你最近的一个)
For some regions, you might have to provide some justification on your planned usage, in order to reduce fraud and enable Paperspace to prioritize requests. In such a case expect ~2 days for the investigation to take place.
- 为您的机器选择一个模板
Paperspace 提供多种模板供您使用。我推荐使用 fast.ai 模板。Paperspace 的 fast.ai 模板是云中的一个全功能 Linux (Ubuntu 16.04) 实例,专为启动和运行非常受欢迎的 Fast.ai 在线 MOOC 而构建,名为“程序员实用深度学习”。该模板旨在为交互式开发提供一个全功能的机器学习环境。
该模板包括英伟达用于使用 GPU 运行机器学习程序的库,以及各种用于 ML 开发的库(Anaconda Python 发行版、Jupyter notebook、fast.ai 框架……)。
fast.ai is a popular template that will definitively make your life easier!
- 选择机器的计算能力
Available options might evolve over time. P4000 and P5000 will give you sufficient resources to build world-class classifiers and become a serious Kaggle competitor.
- 根据您的需求选择存储空间,从 50GB 到 2000GB 不等
Note that you can upgrade to a higher storage any time.
- 选择选项 -您需要一个公共 IP 地址来访问 jupyter 笔记本电脑
Turn ON Public IP
(cost is $3/month
) | Turn OFF Auto Snapshot
(to save money on doing back-ups)
- 添加您的信用卡信息并继续付款
- 创建您的纸张空间框
由于高需求,您的请求可能需要几个小时才能完成。完成后,您将收到一封主题为“您的新 Paperspace Linux 机器准备就绪”的电子邮件,其中包含一个临时密码,可通过 ssh 登录到您的新机器。
步骤 3:连接到您的机器
- 点击‘开始’按钮来启动你的机器
Screenshot from Paperspace home > Machines > Machine id.
- 打开机器。您将被重定向到一个基于 web 的命令行界面,但是您可以随意使用任何其他界面( Cygwin ,…)
Click the ‘open’ button once machine is ready.
- 将确认邮件中的密码复制粘贴到终端中:Windows: Ctrl + Shft + v. Mac: Cmd + v
And here you are!
第四步:不要忘记关闭你的机器!
每当您停止工作时,点击“关机”按钮,以防止您每月的账单无谓地增加!
Tip: Paperspace let you choose to automatically shut down your machine at: 1h, 8h, 1d, 1w.
结论
请随意评论和分享您自己对 Paperspace 或任何其他提供商的体验。感谢阅读,快乐深度学习!
来源
- fast.ai 学生笔记
- Paperspace 网站
- fast.ai 网站
如何在 AWS GPU 实例上设置深度学习环境
原文:https://towardsdatascience.com/how-to-set-up-deep-learning-machine-on-aws-gpu-instance-3bb18b0a2579?source=collection_archive---------3-----------------------
设定我们的目标
目标是学习如何在 Amazon 的 AWS GPU 实例上建立一个机器学习环境,通过使用 docker 容器,该环境可以很容易地复制并用于其他问题。
设置环境
第一步是在亚马逊的网络服务上建立一个虚拟机。为此,我们需要选择正确的硬件和软件包来构建深度学习模型。深度学习模型消耗大量计算能力,对非常大的矩阵进行矩阵运算。AWS 上有两个硬件选项。仅限 CPU 或 GPU。GPU 代表图形处理单元。CPU 和 GPU 架构的主要区别在于,GPU 是并行处理器,但更加专业化。相反,CPU 是通用计算架构,在并行计算上做不好。Amazon 允许您为繁重的计算建立一个带有专用 GPU 核心的虚拟机。当然,这增加了一点你的成本,但是如果你考虑到你节省的时间,这是一个很好的交易。
或者,如果你真的想认真对待这个问题,那么我建议你在家里用 nvidia GPUs 构建自己的系统。
下面是我们在 AWS 上设置 GPU 实例所需的步骤:
- 启动实例
- 选择 ubuntu 16.04
- 选择 g2.xlarge — 8 个 vCPU、15Gb RAM、60GB 启动 SSD、1 个 GPU K520
- 选择可用性区域
- 防止意外终止
- 添加存储— 120 GB
- 添加标签,如名称和环境…
- 选择安全组
- 启动并选择键
连接到实例
导航到存储 SSH 密钥的目录,使用下面的命令在终端中连接到您的实例
ssh -i “your_ssh_key.pem” ubuntu@*[your instance public IP address]*
安装 NVIDIA 驱动程序
ref:https://medium . com/forward-data-science/how-to-set-up-a-deep-learning-environment-on-AWS-with-keras-the ano-b 0f 39 e 3d 861 c
sudo apt-get updatesudo apt-get upgrade
要领
sudo apt-get install openjdk-8-jdk git python-dev python3-dev python-numpy python3-numpy build-essential python-pip python3-pip python3-venv swig python3-wheel libcurl3-devsudo apt-get install -y gcc g++ gfortran git linux-image-generic linux-headers-generic linux-source linux-image-extra-virtual libopenblas-dev
NVIDIA 驱动程序
sudo add-apt-repository ppa:graphics-drivers/ppa -ysudo apt-get updatesudo apt-get install -y nvidia-375 nvidia-settings
安装 CUDA 8 库
wget [https://developer.nvidia.com/compute/cuda/8.0/Prod2/local_installers/cuda-repo-ubuntu1604-8-0-local-ga2_8.0.61-1_amd64-deb](https://developer.nvidia.com/compute/cuda/8.0/Prod2/local_installers/cuda-repo-ubuntu1604-8-0-local-ga2_8.0.61-1_amd64-deb)sudo dpkg -i cuda-repo-ubuntu1604-8-0-local-ga2_8.0.61-1_amd64-debsudo apt-get updatesudo apt-get install cudanvidia-smi
为 nvidia GPU 机器设置 docker 引擎(nvidia-docker)
参考:https://docs.docker.com/engine/installation/linux/ubuntu
添加 docker 引擎库
sudo apt-get updatesudo apt-get install \ apt-transport-https \ ca-certificates \ curl \ software-properties-commoncurl -fsSL [https://download.docker.com/linux/ubuntu/gpg](https://download.docker.com/linux/ubuntu/gpg) | sudo apt-key add -sudo apt-key fingerprint 0EBFCD88sudo add-apt-repository \ “deb [arch=amd64] [https://download.docker.com/linux/ubuntu](https://download.docker.com/linux/ubuntu) \ $(lsb_release -cs) \ stable”
安装 docker 引擎 ce
sudo apt-get updatesudo apt-get install docker-cesudo docker run hello-worldsudo usermod -aG docker $USER
安装 nvidia-docker
# Install nvidia-docker and nvidia-docker-pluginwget -P /tmp [https://github.com/NVIDIA/nvidia-docker/releases/download/v1.0.1/nvidia-docker_1.0.1-1_amd64.deb](https://github.com/NVIDIA/nvidia-docker/releases/download/v1.0.1/nvidia-docker_1.0.1-1_amd64.deb)sudo dpkg -i /tmp/nvidia-docker*.deb && rm /tmp/nvidia-docker*.deb# Test if docker is using nvidia GPUsnvidia-docker run — rm nvidia/cuda nvidia-smi
用 jupyter 笔记本、tensorflow 和机器学习库建立 docker 容器
为 gpu 拉张量流 docker 图像
docker pull tensorflow/tensorflow:latest-gpu-py3
用 tensorflow 为 gpu 创建 docker 容器
nvidia-docker run -it -name planet -p 8888:8888 tensorflow/tensorflow:latest-gpu-py3 bash
码头集装箱内
奠定基础
apt-get updateapt-get install sudosudo apt-get updatesudo apt-get install gitsudo apt-get install nano #or your choice of editor
设置 Python 环境
首先让我们看看我们需要什么,我们有什么。我们需要:
Python 3.5,PIP3 9.0.1,带 Python 3.5 内核的 jupyter 笔记本,tensorflow 1.1,带 tensorflow 后端的 keras,还有这些 librarise: cv2 (OpenCV),sys,os,gc,numpy,pandas,seaborn,matplotlib,scikit-learn (sklearn),scipy,itertools,subprocess,six,skimage,IPython.display,tqdm,多重处理,concurrent.futures
运行 ipython 并导入下面的库,以确保一切正常。这些库的大部分已经安装在 tensorflow docker 映像中。但是,其中一些可能不包括在内。
import sysimport osimport gcimport numpyimport pandasimport seabornimport matplotlibimport sklearnimport scipyimport itertoolsimport subprocessimport siximport skimageimport IPython.displayimport tensorflowimport kerasimport tqdmimport multiprocessingimport concurrent.futuresimport cv2
安装缺失的库
pip3 install seabornpip3 install scikit-imagepip3 install keraspip3 install tqdmpip3 install opencv-python
从这个容器创建一个新的图像,并将其命名为 keras-tf
docker commit amazon keras-tf:latest
如何为您的组织设置数据科学职能
原文:https://towardsdatascience.com/how-to-setup-a-data-science-function-for-your-organisation-9d247e605202?source=collection_archive---------3-----------------------
本文将提供在 3 种类型的组织中建立数据科学职能的有效方法的高级理解:(1)初创公司,(2)中型组织,以及(3)大型组织。
M ost 公司已经意识到,为了在各自的市场中保持竞争力,他们需要数据科学能力。在某些情况下,来自组织内数据科学(DS)团队的产品和见解正日益成为他们的主要竞争优势。
然而,很少有公司做对了这一点。
组织需要的东西和数据科学家想要研究的东西之间的脱节与双方的优先事项有关。
大多数公司都有很多“易得之果”(数据清理、简单查询等)。)不需要复杂的数据科学模型来解决。然而,大多数数据科学家希望解决业务中最复杂的问题。
组织需要清楚地传达为什么这些唾手可得的成果能迅速为组织增加价值,数据科学家需要明白,解决这些问题将让他们了解业务。一旦他们了解了业务,数据科学家就可以在组织数据科学能力的成熟过程中发挥重要作用。
为了做好这件事,需要做两件事:
Source: Monica Rogati’s article on “The AI Hierarchy of Needs”
(I)了解“数据科学需求层次”
https://hacker noon . com/the-ai-hierarchy-of-needs-18f 111 FCC 007
(ii)如何根据组织的规模组建团队。
1。创业公司:
在大多数初创公司中,资源(时间、资源和员工数量)是有限的,同时,你的 DS 团队必须(1)负责建立整个数据基础设施,以及(2)生成引导组织朝着正确方向前进所需的关键见解。
由于这两个原因,创业公司中最有效的 DS 团队有成对的数据科学家和数据工程师一起工作。这使得两种技能都能发挥各自的优势,推动数据产品和见解向前发展。
2.中型组织
在中型公司中,可以用来创建数据产品和见解的资源不那么稀缺。这意味着他们可以将数据科学家和数据工程师分开。在某些情况下,一个中等规模的公司也可能有软件工程师来负责数据收集和数据获取。
这允许基于技能组合的更多的分离。
这里的关键要点是,数据工程师和数据科学家可以专注于分析和指标,这些分析和指标可以有效地告诉企业他们的产品或服务表现如何,同时还可以拓展开发新的复杂模型的范围。
3.大型组织
当公司变得足够大时,他们开始在员工身上花钱。这样做有两个好处:(1)员工不必担心他们领域之外的事情,以及(2)员工可以专注于他们最擅长的事情,很少分心。
与中型组织类似,在大型组织中,软件工程师负责仪表、日志等。数据工程师专注于数据管道的架构。
现在,不同类型的数据科学家之间出现了分化。
- 数据科学,分析工程师
这些数据科学家专注于:
(i)获取大型数据集,并将它们转化为具体的结论和可操作的见解。
(ii)向不同的受众传达复杂的主题。
(iii)创造性地思考,发现新的机会,将组织引向正确的方向。 - 数据科学,机器学习工程师
这些数据科学家专注于:
(i)开发高度可扩展的工具,利用基于规则的模型。
(ii)建议、收集和综合需求,以创建有效的路线图。
(iii)与工程团队合作编写可交付成果。
(iii)采用标准的机器学习方法,最好地利用现代并行环境。
在数据科学家的动机和组织表示希望数据科学家加入他们的意思之间,仍然很难弥合差距。
双方都要思考数据科学的需求层次,以及如何最好地实施配对,让个人发挥他们的优势,这将为数据科学团队带来最佳结果。
在我的下一篇文章中,我将讨论产品设计师和数据科学家如何合作开发高效的产品。
如何为机器学习设置 Python 环境
原文:https://towardsdatascience.com/how-to-setup-a-python-environment-for-machine-learning-354d6c29a264?source=collection_archive---------8-----------------------
想获得灵感?快来加入我的 超级行情快讯 。😎
为机器学习设置 Python 环境可能是一项棘手的任务。如果你以前从未设置过这样的东西,你可能会花几个小时摆弄不同的命令,试图让它工作。但我们只想直接去 ML!
在本教程中,您将学习如何建立一个稳定的 Python 机器学习开发环境。您将能够直接进入 ML,再也不用担心安装包了。
(1)设置 Python 3 和 Pip
第一步是安装 pip,这是一个 Python 包管理器:
sudo apt-get install python3-pip
使用 pip,我们将能够用一个简单的pip install *your_package*
安装在 Python 包索引 中索引的任何 Python 包。你很快就会看到我们如何用它来建立我们的虚拟环境。
接下来,当从命令行运行pip
或python
命令时,我们将 Python 3 设置为默认。这使得使用 Python 3 更加容易和方便。如果我们不这样做,那么如果我们想使用 Python 3,我们每次都必须记住键入pip3
和python3
!
为了强制 Python 3 成为默认版本,我们将修改~/.bashrc
文件。从命令行执行以下命令来查看该文件:
nano ~/.bashrc
向下滚动到 #更多 ls 别名部分,并添加以下行:
alias python='python3'
保存文件并重新加载您的更改:
source ~/.bashrc
嘣!Python 3 现在是您的默认 Python 了!你可以在命令行上用简单的python *your_program*
来运行它。
(2)创建虚拟环境
现在我们将建立一个虚拟环境。在那里,我们将安装机器学习所需的所有 python 包。
我们使用虚拟环境来分离我们的编码设置。想象一下,如果你想在你的电脑上做两个不同的项目,需要不同版本的不同库。将它们都放在同一个工作环境中可能会很麻烦,并且您可能会遇到库版本冲突的问题。你的项目 1 的 ML 代码需要 1.0 版本的numpy
,但是项目 2 需要 1.15 版本。呀!
虚拟环境允许我们隔离工作区域,以避免这些冲突。
首先,安装相关的软件包:
sudo pip install virtualenv virtualenvwrapper
一旦我们安装了 virtualenv 和 virtualenvwrapper,我们将再次需要编辑我们的~/.bashrc
文件。将这三行放在底部,保存它。
export WORKON_HOME=$HOME/.virtualenvs
export VIRTUALENVWRAPPER_PYTHON=/usr/bin/python3
source /usr/local/bin/virtualenvwrapper.sh
保存文件并重新加载您的更改:
source ~/.bashrc
太好了!现在我们终于可以像这样创建我们的虚拟环境了:
mkvirtualenv ml
我们刚刚创建了一个名为ml
的虚拟环境。要输入,请执行以下操作:
workon ml
不错!你在ml
虚拟环境中进行的任何库安装都将被隔离在那里,不会与任何其他环境冲突!因此,无论何时你希望运行依赖于安装在ml
环境中的库的代码,首先用workon
命令进入,然后正常运行你的代码。
如果您需要退出 virtualenv,请运行以下命令:
deactivate
(3)安装机器学习库
现在我们可以安装我们的 ML 库了!我们将使用最常用的方法:
- numpy: 用于任何矩阵工作,尤其是数学运算
- 科学技术计算
- pandas: 数据处理、操作和分析
- matplotlib: 数据可视化
- scikit learn: 机器学习
这里有一个简单的技巧,可以快速安装所有这些库!创建一个requirements.txt
文件,列出您希望安装的所有软件包,如下所示:
numpy
scipy
pandas
matplotlib
scikit-learn
完成后,只需执行以下命令:
pip install -r requirements.txt
瞧啊。Pip 将继续安装文件中列出的所有软件包。
恭喜你,你的环境已经设置好了,你可以开始机器学习了!
喜欢学习?
在推特上关注我,我会在这里发布所有最新最棒的人工智能、技术和科学!也在 LinkedIn 上与我联系!
如何设置 JupyterLab 项目环境
原文:https://towardsdatascience.com/how-to-setup-your-jupyterlab-project-environment-74909dade29b?source=collection_archive---------1-----------------------
在一分钟内创建和定制您的容器化和脚本控制的 JupyterLab 项目环境。
本文是本书的一部分: 用 Python 实践量子机器学习。
在这里免费获得前三章。
TL;博士:
JupyterLab-Configuration 让您轻松创建您的 JupyterLab 配置,它在容器中运行 JupyterLab,并使用脚本自动完成整个设置。容器是一个独立的环境,它封装了您在其中安装的库,而不会影响您的主机。脚本自动执行您通常需要手动运行的所有命令。因为您可以查看和编辑脚本,所以您可以随时完全控制您的配置。
在本帖中,您将看到这个 JupyterLab 配置是如何工作的,以及如何定制它来满足您的需求。
我是一名数据科学家,不是 DevOps 工程师
该死的吉姆。我是数据科学家,不是 DevOps 工程师
数据科学家的要求清单非常长。它包含数学和统计,编程和数据库,通信和可视化,领域知识,等等。
“求求你,不要把 DevOps 加到名单里,”你觉得呢?好吧!你觉得这些过程怎么样?
创建您的 JupyterLab 配置:
- JupyterLab-Configuration 让你轻松创建你的定制配置
- 下载并解压缩您的配置
- 根据您的需求进行定制(可选)
下图显示了运行中的 JupyterLab 配置。通过两个简单的步骤使用它:
- 执行
sh {path_to_your_project}/run.sh
- 在浏览器中打开
localhost:8888
Using the JupyterLab configuration
如果我对这种配置的工作原理感兴趣呢?解释它需要多少时间?
当然,几个小时,先生。但是你没有几个小时,所以我会在几分钟内为你做。
这篇文章的剩余部分从概念上给你一个 JupyterLab 配置如何工作的概述。它解释了构造块,并使您能够根据自己的需求定制配置,例如
- 添加软件包
- 添加您自己的 Python 模块
- 定制 Jupyter 笔记本服务器
我为什么需要一个 JupyterLab 配置?
2018 年,Project Jupyter 推出了 JupyterLab——一个用于处理笔记本、代码和数据的交互式开发环境。JupyterLab 完全支持 Jupyter 笔记本,使您能够在选项卡式工作区中与笔记本一起使用文本编辑器、终端、数据文件查看器和其他自定义组件。
如果您运行的是基于 Unix 的操作系统(macOS 或 Linux),那么您可以使用两个简单的命令来安装和启动 JupyterLab:
python -m pip install jupyterlab
jupyter lab
但是等等!JupyterLab 的手动设置如此简单,乍看之下可能无法满足您在数据科学项目中需要做的所有事情。您可能还需要:
- Jupyter 内核(例如 bash、Javascript、R 等等)
- 文件转换器(如 Pandoc、Markdown 等)
- 库(例如 NumPy、SciPy、TensorFlow、PyTorch 等)
- 支持软件(Git、NbSphinx 等)
将这些依赖项直接安装在您的计算机上并不是一个好主意,因为您将很难确保保持您的计算机干净。
- 如果您有不同的项目需要不同版本的库会怎样?你会在每次切换项目时卸载旧版本并安装正确的版本吗?
- 如果你不再需要一个库,该怎么办?如果你发现你还需要它,你会马上把它移除并重新安装吗?或者您会等到忘记删除这个库吗?
手动安装这些依赖项也不是一个好主意。你将无法控制你安装的所有东西。
- 如果你想在另一台电脑上完成这个项目,该怎么办?重新建立项目需要多少时间和工作量?
- 如果有人问你要你正在使用的所有第三方库怎么办?在您安装在主机上的所有库当中,您如何识别您在本项目中使用的库?
集装箱式结构
容器是独立于主机的虚拟环境。它创建了自己的运行时环境,可以适应您特定的项目需求。它只以特定的方式与宿主互动。对容器的任何更改都不会影响您的主机,反之亦然。 Docker 是用于项目环境虚拟化的最著名和最广泛使用的平台之一。
下图描述了包含两个步骤的 Docker 过程:(1)从 Docker 文件构建一个映像,以及(2)在容器中运行该映像。
The Docker process
我们的配置在run.sh
-脚本中自动化了这个过程。这是一个运行在主机上的 shell 脚本(sh
或bash
)。同样,这个脚本是您开始 JupyterLab 项目的切入点。只需打开一个终端并运行:
sh {path_to_your_project}/run.sh
Docker 文件是告诉 Docker 如何在容器内配置系统的脚本。在docker build
步骤中,Docker 创建了该系统的映像。映像是一个可执行包,其中包含运行应用程序所需的一切—代码、运行时环境、库、环境变量和配置文件。
虽然 Docker 支持从头开始构建系统,但最佳实践是从现有映像开始,例如包含操作系统甚至完整配置的映像。
配置从一个现有图像开始。你可以在这个 GitHub-Repository 中找到相应的 Dockerfile。此映像包含以下软件和库:
- Ubuntu 18.04
- Python 3.7.0
- 点
- 朱庇特和朱庇特实验室
- Bash 和 Jupyter Bash-Kernel
- 文档(pdf)工具(
pandoc
、texlive-xetex
) - 构建工具(例如,
build-essential
、python3-setuptools
、checkinstall
) - 通讯工具(
openssl
、wget
、requests
、curl
) - 各种 Python 开发库
如果你需要更多的软件库,那么 Dockerfile 就是你要去的地方。只需在FROM
语句后添加一个新行。这一新行需要以RUN
开始,并包含您可能想要执行的任何 shell 命令,通常类似于apt-get install
或pip install
。例如,您可以使用以下语句使用pip
安装一些主要的数据科学包:
RUN pip install numpy
RUN pip install scipy
RUN pip install pandas
Dockerfile 中的更改在build
步骤中生效。如果您已经启动了容器,您需要停止它(例如在您的终端中使用 ctrl+c)并重新启动它(sh {path_to_your_project}/run.sh
)。编辑 docker 文件时,build
步骤可能需要一些时间。Docker 试图重用现有的图像,当你没有改变任何东西时,它在随后的启动中非常快。
如果您从 Docker 文件中删除命令并重新运行run.sh
-脚本,Docker 会创建一个新的系统映像。您不需要从系统中卸载任何东西。因为被删除的命令从来就不是这个结果系统的一部分。这使您的配置始终保持干净。您可以实验性地安装库,而不必担心。如果你不需要它们,就去掉它们。您将得到一个从未安装它们的系统映像。
下图描述了 Dockerfile 如何配置系统:它按照其RUN
-命令中指定的方式安装软件。
The Dockerfile specifies the configuration of the system
命令在一个容器中执行这个图像。此外,它定义了在容器内运行的系统如何连接到外部世界,即主机。
有两种主要的连接类型:卷和端口。卷是主机上的目录和容器中的目录之间的链接。这些目录是同步的,即主机目录中的任何变化都会影响容器中的目录,反之亦然。端口映射让 Docker 将对主机端口的任何请求(例如 HTTP 请求)转发到容器的映射端口。
下图描述了我们到目前为止的配置。run.sh
-脚本负责 Docker build
和run
步骤。一旦您执行该脚本,它将创建一个运行容器,通过文件系统卷和端口映射与您的主机连接。
The run.sh script automates the Docker process
文件系统
当您从 Git-Hub-Repository 下载文件时,您将在.zip
文件中获得以下文件结构:
{path_to_your_project}/
├─ config/
│ ├─ {projectname}.Dockerfile
│ ├─ jupyter_notebook_configuration.py
│ └─ run_jupyter.sh
├─ libs/
│ └─ nbimport.py
├─ notebooks/
│ └─ …
└─ run.sh
- 文件夹包含 JupyterLab 项目的配置文件。这些文件配置 Docker 容器,安装软件包,并配置 JupyterLab 环境。
libs
-文件夹包含软件库,这些软件库不是作为软件包安装的,而是作为文件添加的,例如您在其他项目中自己编写的 Python 模块。- 文件夹是我们放笔记本的目录。
在 Dockerfile 文件中,我们设置指向这些目录的环境变量。因为配置中的脚本使用了这些环境变量,所以如果愿意,您可以编辑它们。只要确保变量中的路径与实际路径匹配即可。
ENV MAIN_PATH=/usr/local/bin/{projectname}
ENV LIBS_PATH=${MAIN_PATH}/libs
ENV CONFIG_PATH=${MAIN_PATH}/config
ENV NOTEBOOK_PATH=${MAIN_PATH}/notebooks
在配置中,我们将当前工作目录({path_to_your_project}
)映射到容器中的${MAIN_PATH}
-文件夹。因此,您放入该目录的任何文件在您的 JupyterLab 项目中都是可用的。反之亦然,您在 JupyterLab 中添加或更改的任何文件(例如 Jupyter 笔记本)都会出现在您的主机上。
此外,在 Dockerfile 的EXPOSE
命令中,我们指定配置提供 JupyterLab 端口8888
。容器内的这个端口被映射到您的主机计算机的端口。
下图描述了容器如何将其文件系统和端口连接到主机。
Connect the file system and the port
特定于 JupyterLab 的配置
我们 docker 文件中的最后一个命令是CMD
-命令。它告诉 Docker 无论何时启动容器都要执行这条指令。在配置中,我们执行run_jupyter.sh
-脚本。这个脚本允许我们做一些最后的准备,比如:
- 将
jupyter_notebook_configuration.py
文件放在 JupyterLab 期望的位置 - 配置一个定制的 Jupyter-Kernel 来自动加载
nbimport.py
Python 模块
jupyter_notebook_configuration.py
可让您配置 Jupyter 笔记本电脑服务器,例如设置用于网络认证的密码。可用选项列表可在这里找到。
定制 Python 内核将${LIBS_PATH}
添加到您的 Python sys.path
中。这允许您从${LIBS_PATH}
-文件夹中导入任何 Python 模块,例如import libs.nbimport
。此nbimport.py
-模块进一步使您能够导入位于${NOTEBOOK_PATH}
-文件夹中的笔记本。每当你用 Python 内核启动 Jupyter 笔记本时,系统会自动为你做这些事情。
最后,run_jupyter.sh
-脚本启动 JupyterLab。您现在可以在浏览器中打开localhost:8888
,其中8888
是您指定的端口。
下图描述了完整的 JupyterLab 配置。
The complete JupyterLab configuration
摘要
JupyterLab-Configurator 可让您轻松创建自定义配置。这个 JupyterLab-Configuration 在容器中运行 JupyterLab。它将 JupyterLab 运行的环境与主机环境分开。因此,您可以更改 JupyterLab 环境(例如,卸载/安装软件包),而不会影响您的主机或任何其他项目。
这个JupyterLab-Configuration使用脚本自动完成整个设置。这些脚本:
- 使您能够使用单个命令(例如
sh run.sh
)运行 JupyterLab - 使您的项目可移植:只需将目录移动或复制到另一台主机上
- 揭示您的配置的一部分,并允许您查看和编辑您的配置
- 让您的配置成为您的源代码的一部分。您可以像对代码进行版本控制一样对它们进行版本控制
GitHub-repository提供了完整的源代码。
使用 JupyterLab 配置非常简单:
- 执行
sh {path_to_your_project}/run.sh
- 在浏览器中打开
localhost:8888
Using the JupyterLab configuration
注 :运行 Docker 容器的能力是这个 JupyterLab-Configuration 对主机的唯一要求。Docker 在 Windows 上可用,并且最近获得了运行基于 Linux 的容器的能力。因此,Jupyterlab 没有理由不在 Windows 上运行。如果你想尝试一下,你需要运行 Docker,并将run.sh
的docker build
和docker run
命令移动到一个可以在 Windows 上执行的.cmd
文件中。
如何为您的数据产品缩小 NumPy、SciPy、Pandas 和 Matplotlib
原文:https://towardsdatascience.com/how-to-shrink-numpy-scipy-pandas-and-matplotlib-for-your-data-product-4ec8d7e86ee4?source=collection_archive---------6-----------------------
如果你是一名在微服务框架中部署数据产品的数据科学家或 Python 开发人员,你很有可能需要利用 NumPy、SciPy、Pandas 或 Matplotlib 的公共科学生态系统模块。微服务中的“微”,建议你应该保持组件尽可能的小。然而,当通过 PIP 安装时,这四个模块非常庞大!
让我们探索为什么 NumPy,SciPy,Pandas,Matplotlib 在通过 PIP 安装时如此庞大,并设计一个关于如何在微服务框架内优化您的数据产品的策略(使用源代码)。
Python Scientific Modules
我参与的大多数数据产品都是通过 Docker 部署的,所以本文将使用该框架。与微服务框架的“微”保持一致,第一个 Docker 最佳实践围绕着保持你的图像尺寸小。如果你对缩小 Docker 图片尺寸的最佳实践感兴趣,在 Medium 上有很多帖子。这篇文章将完全专注于减少 NumPy、SciPy、Pandas 和 Matplotlib 消耗的磁盘大小。
只使用预编译的二进制文件?
关于 NumPy、SciPy、Pandas 和 Matplotlib,你可以在互联网上读到的一般建议是通过你的 linux 包管理器(即 apt-get install -y python-numpy)来安装它们。然而,在实践中,那些包管理人员经常在官方发布的版本后面跟踪多个版本。如果您的数据产品需要这些模块的一个特定版本,这根本就行不通。
Just trust the package manager?
Anaconda 发行版用比 PIP 更少的内存完成了编译这些库的工作,那么为什么不直接使用 Python 发行版呢?根据我的经验,如果您已经处于需要特定版本的 NumPy、SciPy、Pandas 或 Matplotlib 的状态,那么您很可能还需要来自其他软件包的特定版本。不幸的消息是,那些其他的包可能不会存在于 Conda 库中。所以简单地使用 Anaconda 或 miniconda ,并引用 conda 存储库不会满足您的需求。更不用说您的 Docker 映像中不需要的 Anaconda 的额外膨胀。记住,我们想让事情尽可能的小。
码头工人历史
要查看构建 Docker 映像时运行的命令的逐层影响,历史命令非常有用:
$ docker history shrink_linalgIMAGE CREATED CREATED BY SIZE COMMENT435802ee0f42 About a minute ago /bin/sh -c buildDeps='build-essential gcc gf… 508MB
在上面的示例中,我们可以看到一个层产生了 508MB ,而我们在该层中所做的只是使用以下命令安装 NumPy、SciPy、Pandas 和 Matplotlib:
pip install numpy==1.15.1 pandas==0.23.4 scipy==1.1.0 matplotlib==3.0.0
我们还可以使用 du 命令查看映像中消耗的详细包磁盘空间:
$ docker run shrink_linalg /bin/bash -c "du -sh /usr/local/lib/python3.6/site-packages/* | sort -h"...
31M /usr/local/lib/python3.6/site-packages/matplotlib
35M /usr/local/lib/python3.6/site-packages/numpy
96M /usr/local/lib/python3.6/site-packages/pandas
134M /usr/local/lib/python3.6/site-packages/scipy
这些模块是巨大的!你可能会说这些模块的功能需要那么大的磁盘空间。但是它们不需要这么大。我们可以删除很大一部分(高达 60% )不必要的磁盘空间,而不会影响模块本身的性能!
爆破优化
NumPy 和 SciPy 的优势之一是对线性代数方法进行了优化。为此,有许多 LinAlg 优化器。在这篇文章中,我们只是使用了 OpenBLAS 。但是我们需要验证是否安装了 NumPy 和 SciPy 来利用这个库。
$ docker run shrink_linalg /bin/bash -c "python -c 'import numpy as np; np.__config__.show();'"...
openblas_info:
libraries = ['openblas', 'openblas']
library_dirs = ['/usr/lib']
language = c
define_macros = [('HAVE_CBLAS', None)]
...
这里重要的是让 OpenBLAS 被识别并映射到正确的目录。这将使 NumPy 和 SciPy 能够利用该库中的 LinAlg 优化。
PIP 安装选项
当在 Docker 容器中通过 PIP 安装时,保留缓存是没有意义的。让我们添加一些标志来指示 PIP 如何工作。
- — no-cache-dir
PIP 使用缓存来防止重复的 HTTP 请求,以便在安装到本地系统之前从存储库中提取模块。当在 Docker 映像中运行时,没有必要保留这个缓存,所以用这个标志禁用它。 - —编译
将 Python 源文件编译成字节码。在 Docker 映像中运行时,不太可能需要调试成熟的已安装模块(如 NumPy、SciPy、Pandas 或 Matplotlib)。 - — global-option=build_ext
为了通知 C 编译器我们想要在编译和链接期间添加额外的标志,我们需要设置这些额外的“全局选项”标志。
c 编译器标志
Python 有一个名为 Cython 的 C-Extension 包装器,它使开发人员能够以类似 Python 的语法编写 C 代码。这样做的好处是,它允许对 C 语言进行大量的优化,同时也便于编写 Python。NumPy,SciPy 和 Pandas 大量利用 Cython!Matplotlib 似乎也包含一些 Cython,但程度要小得多。
这些编译器标志被传递给安装在 docker 文件中的 GNU 编译器。开门见山地说,我们只打算调查其中的一小部分:
- 禁用调试语句 ( -g0 )
因为我们将数据产品粘贴到 Docker 映像中,所以我们不太可能对来自 NumPy、SciPy、Pandas 或 Matplotlib 的 Cython 代码进行任何实时调试。 - 移除符号文件 ( -Wl,— strip-all )
如果我们永远不会在 Docker 映像中调试这些包的构建,那么保留调试所需的符号文件也没有意义。 - 针对几乎所有支持的优化进行优化,这些优化不涉及空间速度权衡 ( -O2 )或针对磁盘空间的优化 ( -Os )
这些优化标志面临的挑战是,虽然它可以增加/减少磁盘大小,但它也会操纵编译后的二进制文件的运行时性能!如果没有明确测试它对我们的数据产品的影响,这些可能是有风险的(但同时,它们是非常有效的)。 - 头文件的位置(-I/usr/include:/usr/local/include)
明确告诉 GCC 在哪里可以找到编译 Cython 模块所需的头文件。 - 库文件的位置(-L/usr/lib:/usr/local/lib)
明确告诉 GCC 在哪里可以找到编译 Cython 模块所需的库文件。
但是在通过 PIP 安装期间设置这些 CFLAG 有什么影响呢?
缺少调试信息可能会使有经验的开发人员提高警惕,但是如果您以后真的需要它们,您总是可以使用标志重新构建 Docker 映像,以再现任何发生的 stacktrace 或 core dump。更大的问题是不可重现的异常..没有符号文件是无法诊断的。但是,没有人会以码头工人的形象这样做。
带 CFLAG 比较的 PIP
Disk consumption inside Docker image
采取最佳优化 CFLAG 策略,您可以将 Docker 映像的磁盘占用空间减少 60% !
对于我的数据产品,我只是删除了 debug/符号,并且不执行任何额外的优化。如果你想知道其他人是如何执行类似的 CFLAG 优化的,请查看官方的 Anaconda 食谱,包括 NumPy 、 SciPy 、 Pandas 和 Matplotlib 。这些都是针对 Python 的 Anaconda 发行版进行优化的,可能与您的特定 Docker 数据产品部署相关,也可能不相关。
单元测试
仅仅因为我们能够收缩每个模块的编译二进制文件,我们就应该进行健全性检查,以验证我们使用的 C 编译器标志没有影响这些模块的性能。
所有这些包都利用了 pytest 模块,我们没有将它安装在 Docker 映像中,因为它在生产中没有提供任何价值。我们可以安装它并从内部执行测试,尽管:
- 我们的 Docker 映像中的 NumPy 测试:
$ docker run shrink_linalg /bin/bash -c "pip install pytest; python -c \"import numpy; numpy.test('full');\""4675 passed ... in 201.90 seconds
- Docker 映像内部的 SciPy 测试:
$ docker run shrink_linalg /bin/bash -c "pip install pytest; python -c \"import scipy; scipy.test('full');\""13410 passed ... in 781.44 seconds
- 我们 Docker 图片中的熊猫测试:
$ docker run shrink_linalg /bin/bash -c "pip install pytest; python -c \"import pandas; pandas.test();\""22350 passed ... in 439.35 seconds
有相当多的测试被跳过,而被 x 失败,这取决于您的数据产品和/或安装的版本,这些都是可以预料到的,或者您可能需要进一步研究。在大多数情况下,如果不是严重的失败,很可能可以继续。
希望当您的数据产品需要 NumPy、SciPy、panases 或 Matplotlib 时,这将有助于引导您使用更小的 Docker 图像!我鼓励您尝试其他 CFLAG,并测试磁盘空间和单元测试性能。
源代码
如何解决最后一公里物流难题?
原文:https://towardsdatascience.com/how-to-solve-the-last-mile-logistics-conundrum-2ced70f5f7f3?source=collection_archive---------13-----------------------
电子商务的兴起和消费者对快速送货的期望给物流公司带来了前所未有的压力,要求他们消除最后一公里物流中的摩擦和低效。“最后一英里”通常是指从运输中心(如仓库)到最终交付目的地(如您的家)的货物交付。对物流公司来说,这最后一段是最昂贵的,占运输成本的近 28%。
我们都听说过这样的轶事:送货不准时、包裹被损坏、错过送货和包裹失窃。最后一公里物流在当天送达的世界中更加重要,并给物流提供商带来越来越大的压力。巨大的挑战包括改善基础设施、确保透明度以及通过智能车辆路线将成本降至最低。在这篇文章中,我们将研究一些算法,看看它们如何应用于现实生活中的实际情况,以最小化最后一英里的成本。在一个依赖高销量和低利润的行业,优化最后一英里将直接带来高利润和满意的客户。
旅行推销员和 NP 难题
计算机科学中最著名的问题之一是旅行推销员问题。这个问题构成了物流世界中车辆路径的基础。给定一组点,我们如何找到从起点到终点的最短路径,其中我们访问每个点恰好一次?
Travelling salesman problem
求解旅行商是一个 NP-hard 问题,也就是说没有‘快速’解(快速是指多项式时间算法)。一个精确的算法将包括找到所有的路由排列和组合,并比较每一个来提取最短的路由。“Held-Karp”算法可用于求解旅行推销员问题的精确解,利用子路径并使用动态编程技术。即使这样,这样的算法也只能在合理的时间内解决少量的点。点数的任何增加都会导致计算时间的指数增长。因此,在实际应用中,我们使用近似算法的组合来逼近最佳路径,误差在最佳精确解的 1%以内。
车辆路径问题
最后一英里物流的成本最小化本质上是一个车辆路径问题。车辆路径问题概括了前面提到的旅行推销员问题,并处理寻找一组路径或路线,以最小化成本。问题域可能涉及许多车辆、数百个交货地点和一组仓库地点。车辆路线算法的目标包括但不限于以下内容:
- 为每辆车寻找最短的路径,或最短的行驶时间以节省燃料费用
- 每辆车的容量可能有限,因此目标是使用最少的车辆覆盖所有路线
- 交付需要在特定的时间窗口内发生,我们需要在特定的时间范围内安排路径
- 交货从仓库开始,必须返回仓库
克拉克·赖特储蓄算法
Clarke 和 Wright 节约算法在车辆路径问题的近似解方面非常流行。该算法的决策变量是要使用的车辆数量。该算法的基本思想是,如果两条路线可以可行地合并并产生距离节省,那么我们就选择合并的路径。该算法的工作原理如下:
- 通过将每辆车分配给客户或位置,创建一个初步可行的解决方案
- 对于所有的位置对,我们在连接它们时计算节省,并且我们将节省列表按降序排列
- 我们从节省列表的顶部选取每个子路径,如果没有超过最大车辆容量,则加入其他子路径
- 我们重复上一步,直到考虑了整个节省列表,或者容量限制不允许更多的子路径合并。
最终结果将是在不超出车辆容量的情况下,为最小车辆集分配一定数量的路径或循环,并且每个位置只被访问一次。
蚁群优化算法
蚁群算法大致基于蚂蚁寻找食物的行为。起初,一群蚂蚁会漫无目的地游荡,当一只蚂蚁找到食物时,它会走回蚁群,留下信息素或标记供其他蚂蚁跟随。随着越来越多的蚂蚁追踪这些标记,信息素的踪迹变得越来越突出。更短的路径意味着蚂蚁会更频繁地在上面行走,从而产生更强的信息素踪迹。这个原理可以用来逼近最佳路径。
谷歌或工具
我们如何构建一个软件应用程序来解决车辆路径问题,并利用广泛的优化算法?原来我们可以使用 Google 或者-tools 包来解决我们最后一英里的物流问题。
在我们的示例问题域中,我们将在悉尼市中心附近生成多个装货地点和一个仓库。然后,我们的车辆将从仓库出发,访问这些地点,并装载一些具有一定重量的货物。在我们的问题中,我们将每辆车的载重量限制在 15 公斤,我们的车队最多有 10 辆卡车。
The green marker signifies the home depot, our fleet of trucks must visit the 16 locations on this map.
这个项目将包括一个简单的 Django 后端服务器和一个用 React.js 构建的前端。第一个端点简单地生成一些地址,第二个端点在 Google 或-tools 中运行有容量限制的车辆路径算法。我们选择使用上述节约算法,该算法以其相对较快的计算时间而闻名。这种算法的输入包括使用 Google distance matrix API 计算的距离矩阵,其他参数包括每个给定位置的重量需求列表(随机生成)和许多约束条件,包括车辆的最大数量和每辆车的最大容量。
对于前端,我们只需使用谷歌地图 javascript 库来呈现位置和路线。我们只需在地图上标出送货地点,然后用彩色编码折线显示计算出的路线。我们还可以看到每辆车的路线和它们在每个位置的容量。随着我们给这个问题增加越来越多的问题,只有我们也增加车队的规模,才能产生一个解决方案。例如,如果我们将车队限制为 3 辆车,我们将无法为 20 多个地点提供载重量为 15 公斤的最佳路线。
Optimal vehicle routes plotted using Polylines using Google Maps Javascript Library
这个项目的代码可以在这里和这里找到。
聚类增强
在上面的例子中,我们展示了我们可以使用 Google 或-tools 为我们的车队计算一组优化的路线。然而,随着递送点数量的增加,计算时间变得不合理地长。在现实世界的交付示例中,我们可能要处理数百个交付位置和多个仓库位置。在这种情况下,使用聚类算法将地理上相似的点分组在一起,然后将有容量限制的车辆路线算法应用于每个聚类是合适的。 DBSCAN 聚类算法将适合这样的任务,DBSCAN 算法是一种基于密度的聚类技术,它将紧密堆积的邻居分组在一起,这可以大大加快我们在 Google OR-tools 套件中实现算法的速度。
未来应用
正如我们所看到的,解决车辆路径问题和找到最佳路线将是任何最后一英里物流运营降低成本和增加利润的关键。几项关键的技术开发目前正在进行中,以将最后一英里物流提升到一个新的水平,并确保满足消费者对当天交付等服务的高期望。我们开始看到一些公司在测试自动地面车辆和无人驾驶送货机。这些技术有可能进一步降低运输成本,并将服务范围扩大到农村地区。
如何借助热图发现数据泄漏(在您的笔记本电脑上!)
原文:https://towardsdatascience.com/how-to-spot-data-leakage-thanks-to-heat-maps-81a25f5331eb?source=collection_archive---------15-----------------------
如何确保你的模型真正学到你认为它学到的东西的指南!
Last Convolution Layer Heat Map for two training samples. (Be patient, this animated GIF could take some time to load…)
生成以下图片所需的数据集和源代码可在GitHub 资源库中找到。本文所有内容都可以在配有 1 Go 内存 GPU 的笔记本电脑上重现。
在本文中,您将了解到:
- 如何在图像分类任务中发现数据泄露,以及
- 如何修复(对于这个给定的图像分类任务)。
问题是
想象一下,玛姬·辛普森委托给你一项任务:她想让你做一个算法来区分巴特和荷马。
因为她爱她的丈夫和儿子,她给了你 66 张代表他们的照片在家庭住宅前。(上一句的粗体部分很重要。)
以下是该数据集的摘录。
Pictures Marge gave you
作为一名实验过的数据科学家,你选择使用你最喜欢的预先训练好的图像识别深度神经网络:比如说 VGG16 。
(2014 年获得大型视觉识别挑战赛。)
但是,因为感兴趣的部分(Bart 或 Homer)表示图像中的一个小区域,所以您选择用单个卷积层和一个全局平均池层替换结束的完全连接的层,如下图所示:
Model used for Bart vs. Homer classification (based on VGG16). The only trainable layer is in red.
对于那些想知道的人来说,全球平均池是一种复杂的说法……“平均”。我们稍后会更详细地解释它。
如上所述,对于我们的识别任务,您将只训练最后一个卷积层。
将给定数据集拆分为训练集和验证集后,您训练了最后一个卷积层。
学习曲线是好的:低训练和验证损失意味着你有好的表现,没有过度拟合。您甚至在训练和验证集上获得了 100%的准确率。
恭喜你!
Learning curves
现在是时候在生产中使用您的模型了!
然而,在生产中,巴特和荷马可能在世界的任何地方,包括在斯普林菲尔德核电站前,如下所示:
Ground truth: Bart — Predicted label: Bart ==> OK!
Ground truth: Homer — Predicted label: Homer ==> OK!
对于之前的这 4 张图片,您的模型 100%地预测了好标签(上面的图片预测为 Bart,下面的图片预测为 Homer)。
干得好,玛吉会高兴的!
但是现在让我们在一个稍微不同的数据集上训练您的模型:
- 因为荷马花费大量时间在工作上,所以玛吉给你的所有照片都代表了荷马在核电站前的样子。
- 因为巴特是个孩子,一直在玩,所以玛吉给你的所有照片都代表巴特在家庭住宅前。
下面是这个新数据集的摘录。
The new dataset. Notice that in this dataset, Bart is always in front of the house, and Homer is always in front of the power plant.
像第一次一样,在将给定的数据集分成训练集和验证集之后,您训练了模型的最后一个卷积层。
学习曲线 超级 好:你只用一个历元就达到了 100%的准确率!
提示:这好得令人难以置信。
Learning curves
与之前的训练集一样,现在是时候在生产中使用您的模型了!
让我们看看你的模型有多好,巴特在核电站前面,荷马在家庭住宅前面。
请注意,在训练集中,Bart 在房子前面,Homer 在植物前面。在“生产”中,我们测试了相反的情况:巴特在工厂前面,荷马在房子前面。
Ground truth: Bart — Predicted label: Homer ==> NOT OK at ALL!
Ground truth: Homer — Predicted label: Bart ==> NOT OK at ALL!
哎哟…你的模型总是预测错误的标签。所以我们总结一下:
- 训练集上的损失和准确性->好。
- 验证集上的损失和准确性->好。
- 生产中的模型预测->坏。
发生了什么事?
回答:你的模型被数据泄露感染。
为了学习,模型使用了一些本不该使用的功能。
如何发现数据泄露
首先让我们来看看你的模型的最后一部分 :
想法是在原始图片上叠加最后一个卷积层的输出。该层输出是 2 个 22×40 的矩阵。第一个矩阵表示用于 Bart 预测的激活,第二个矩阵表示用于 Homer 预测的激活。
当然,因为这些矩阵的形状都是 22x40,所以在将它们叠加到原来的 360x640 之前,您必须将它们放大。
让我们用验证集的 4 张图片来做这件事:
在左栏,你有“Bart”最后一个卷积层的输出,在右栏是“Homer”的输出。
色码:蓝色为低输出(接近 0),红色为高输出。
Extract of validation set with heat maps corresponding to the last convolution layer output
看起来你的模型根本没有使用 Bart 和 Homer 来完成分类任务,而是使用了背景来学习!
为了确定这个假设,让我们显示没有巴特和荷马的图片的最后一个卷积层的输出!
Last convolution layer for background only
看来我们的假设是对的。添加/删除 Bart & Homer 对分类模型没有太大影响…
让我们回到我们的第一个模型上几秒钟,这个模型是用 Bart & Homer only 在房子前面的图片训练的,让我们显示一些验证示例的最后卷积层的输出:
Extract of validation set with heat maps corresponding to last convolution layer output, for the model trained with Bart only in front of the house and with Homer only in front of the power plant
在这种情况下,我们现在能够理解为什么这个模型预测了好标签:因为它实际上使用了 Bart & Homer 来预测产量!
解决方案
如何修复 Bart 总是在房子前面,Homer 总是在植物前面的训练集的数据泄露问题?我们有几个选择:
- 最常见的一种是通过使用边界框来修改模型。但是…那很无聊:你必须一个接一个地注释每个训练样本。
- 一个更简单的解决方案是将我们的 2 类分类问题(Bart & Homer)转化为 3 类分类问题(Bart、Homer 和背景)。
第一个类将包含巴特的图片(在房子前面),第二个类将包含荷马的图片(在发电厂前面),第三个类将只包含 2 张图片:一张房子的图片和一张发电厂的图片(上面没有任何人)。
还有……就这些了!
下面是这个 3 级训练模型的学习曲线。这些曲线看起来“更正常”。
Learning curves for the 3-classes trained model
下面是一些验证示例的最后一个卷积层的输出:
Extract of validation set with heat maps corresponding to the last convolution layer output, for the 3-classes trained model
您的模型现在在生产中也运行良好。
现在你知道了: 如何在一个图像分类任务上发现数据泄漏,以及如何为我们的 Bart vs. Homer 分类任务修复它。
生成上述图像所需的数据集和源代码可在GitHub 资源库中找到。
如何从 Kaldi 和语音识别开始
原文:https://towardsdatascience.com/how-to-start-with-kaldi-and-speech-recognition-a9b7670ffff6?source=collection_archive---------2-----------------------
实现最先进的语音识别系统的最佳方式
Today Speech recognition is used mainly for Human-Computer Interactions (Photo by Headway on Unsplash)
卡尔迪是什么?
Kaldi 是一个开源工具包,用于处理语音数据。它被用于与语音相关的应用,主要用于语音识别,但也用于其他任务——如说话人识别和说话人日记化。这个工具包已经很老了(大约 7 年了),但是仍然在不断更新,并由一个相当大的社区进一步开发。Kaldi 在学术界(2015 年被引用 400 多次)和工业界都被广泛采用。
Kaldi 主要是用 C/C++编写的,但是工具包包装了 Bash 和 Python 脚本。对于基本用法,这种包装避免了深入源代码的需要。在过去的 5 个月里,我了解了这个工具包并学会了如何使用它。这篇文章的目标是引导你完成这个过程,并给你对我帮助最大的材料。把它看作一条捷径。
Kaldi simplified view (As to 2011). for basic usage you only need the Scripts.
本文将包括对 Kaldi 中语音识别模型的训练过程的一般理解,以及该过程的一些理论方面。
本文不包括代码片段和实践中做这些事情的实际方法。关于这一点,你可以阅读《卡尔迪傻瓜指南》或其他在线资料。
卡尔迪的三个部分
预处理和特征提取
如今,大多数处理音频数据的模型都使用基于像素的数据表示。当您想要提取这样的表示时,您通常会希望使用有利于以下两点的特征:
- 识别人类说话的声音
- 丢弃任何不必要的噪声。
多年来有几次尝试使那些功能和今天的在业界得到广泛应用。
An Example of MFCC. The Y Axis represents features and the X axis represents time.
MFCC 代表梅尔频率倒谱系数,自从戴维斯和梅尔斯坦在 80 年代发明以来,它几乎已经成为行业标准。在这篇令人惊叹的可读文章中,你可以获得关于 MFCCs 的更好的理论解释。对于基本的用法,你需要知道的是 MFCCs 只考虑我们的耳朵最容易听到的声音。**
在 Kaldi 中,我们使用了另外两个特性:
- cmvn用于更好的规范 MFCC
- I-Vectors (值得自己写一篇文章),用于更好地理解域内的方差。例如,创建依赖于说话者的表示。I 向量基于 JFA(联合因子分析)的相同思想,但是更适合于理解通道和说话者的变化。I-Vectors 背后的数学原理在这里和这里有清晰的描述。
The Process of using I-Vectors as described in Dehak, N., & Shum,**S.** (2011) In Practice: It’s complicated****
为了对这些概念有一个基本的了解,请记住以下几点:
- MFCC 和 CMVN 用于表示每个音频话语的内容。****
- I 向量用于表示每个音频话语或说话者的风格。****
模型
Kaldi 后面的矩阵数学是用 BLAS 和 LAPACK 实现的(用 Fortran 写的!),或者基于 CUDA 的替代 GPU 实现。由于使用了如此低级的包,Kaldi 在执行这些任务时效率很高。
Kaldi 的模型可以分为两个主要部分:
第一部分是声学模型,它曾经是一个 GMM 但现在被深度神经网络疯狂取代。该模型将把我们创建的音频特征转录成一些依赖于上下文的音素(在 Kaldi 方言中,我们称它们为“pdf-id”,并用数字表示它们)。
The Acoustic model, generalized. On top you can see IPA phoneme representation.
第二部分是解码图,它获取音素并将其转换成点阵。网格是可能用于特定音频部分的备选单词序列的表示。这通常是您希望在语音识别系统中得到的输出。解码图考虑了你的数据的语法,以及相邻特定单词的分布和概率( n-grams )。
A representation of lattice — The words and the probabilities of each word
解码图本质上是一个 WFST ,我强烈鼓励任何想要专业化的人彻底学习这个主题。最简单的方法就是通过那些视频和这篇经典文章。理解了这两点之后,你就可以更容易地理解解码图的工作方式了。这种不同 wfst 的组合在 Kaldi 项目中被命名为“HCLG.fst 文件”,它基于 open-fst 框架。
A simple representation of a WFST taken from “Springer Handbook on Speech Processing and Speech Communication”. Each connection is labeled: Input:Output/Weighted likelihood
值得注意的是:这是模型工作方式的简化。关于用决策树连接两个模型,以及你表示音素的方式,实际上有很多细节,但是这种简化可以帮助你掌握这个过程。
你可以在描述 Kaldi 的原始文章中深入了解整个架构,特别是在这个惊人的博客中了解解码图。
培训过程
一般来说,这是最棘手的部分。在 Kaldi 中,你需要按照一个真正特定的顺序排列你转录的音频数据,这个顺序在文档中有详细描述。
对数据进行排序后,您需要将每个单词表示为创建它们的音素。这种表示将被命名为“字典”,它将确定声学模型的输出。这是这种字典的一个例子:
八-> ey t
五- > f ay v
四- > f ao r
九- > n ay n
当你手头有了这两样东西,你就可以开始训练你的模型了。你可以使用的不同训练步骤在卡尔迪方言中被命名为“食谱”。最广泛使用的配方是 WSJ 配方,你可以查看 run bash 脚本来更好地理解这个配方。
在大多数食谱中,我们从用 GMM 将音素排列成声音开始。这个基本步骤(名为“比对”)帮助我们确定我们希望我们的 DNN 稍后吐出的序列是什么。
The general process of training a Kaldi model. The Input is the transcribed data and the output are the lattices.
校准后,我们将创建 DNN,它将形成声学模型,我们将训练它以匹配校准输出。创建声学模型后,我们可以训练 WFST 将 DNN 输出转换为所需的网格。
“哇,太酷了!接下来我能做什么?”
- 试试看。
- 阅读更多
如何尝试
下载这个免费口语数字数据集,试着用它来训练卡尔迪吧!你也许应该试着模糊地跟随这个。你也可以只使用上面提到的多种不同食谱中的一种。
如果你成功了,试着获取更多的数据。如果你失败了,试着在卡尔迪帮助小组中提问。
在哪里阅读更多内容
我无法强调这个 121 张幻灯片的演示对我的帮助有多大,它主要基于一系列的讲座。另一个很好的来源是约什·梅尔的网站。你可以在我的Github-Kaldi-awesome-list中找到这些链接和更多。
试着通读论坛,试着更深入地挖掘代码,试着阅读更多的文章,我很确定你会从中得到一些乐趣。😃
如果您有任何问题,请在此自由提问或通过我的电子邮件联系我,并在 Twitter 或 Linkedin 上自由关注我。
如何在没有实体数据挖掘的情况下保持在线竞争力
原文:https://towardsdatascience.com/how-to-stay-competitive-online-without-brick-and-mortar-data-mining-ee14633d0da5?source=collection_archive---------11-----------------------
对零售商来说,唯一比销售更有价值的是潜在买家的信息。网上零售商可以使用大量的先进工具。然而,许多电子商务品牌已经开始了解通过店内互动收集客户数据的价值。随着亚马逊最近宣布收购全食超市(Whole Foods),以及 Fabletics 等品牌在实体店获得成功,人们越来越清楚地看到,线下品牌建设可能是成功实现在线销售的主要影响因素。
今年电子商务行业预计将在增长 10%左右,但仍仅占零售行业的 10% 多一点。鉴于近 90%的购物仍在店内进行,大型公司和品牌探索实体空间也就不足为奇了。对于凯特·哈德森的电子商务运动服装品牌 Fabletics ,最成功的市场是实体店。通过实体店中的客户交互收集的数据对于他们的店面来说是无价的信息。开一家店面是一项成本高昂的操作,但从数据的角度来看,店内收集的信息和研究是无价的。
今年早些时候,Casper 与 Target 签订了一份大合同,在店内销售他们的产品。即使有 100 天的免费试用,这个床垫品牌也看到了给予顾客触感体验的价值。此外,他们能够更好地了解他们的目标市场,以及什么类型的人在购买床垫时会考虑他们的品牌。
实体店给购物者一种品牌体验,更容易引导购买。商店员工可以提出具体问题,更准确地将个性、喜好和欲望与购买决策联系起来。StubHub 正为此在时代广场开设一家旗舰店,并计划将该空间作为路人查找该地区活动的资源。
随着所有这些大型电子商务品牌转向线下收集数据和改善客户体验,这对小卖家意味着什么? Etsy 的手工艺者、易贝的节俭者和 Bonanza 的小企业会在网上保持竞争力吗?对于行业领导者来说,挖砖是一个有价值的工具,所以小卖家必须找到独特的方法来吸引更多的顾客。
即使没有投资实体数据挖掘的资源,也有办法了解一个市场。以下是小型在线企业拓展业务的几种方式:
- 尝试跨市场销售:如果你只在一个平台上销售,尝试在其他平台上列出你的商品。亚马逊拥有最多的购物者,但你的商品也可能属于 Etsy 购物者寻找的特定商品。Bonanza 提供了一些导入工具,可以让你快捷方便地列出你的商品,此外,它们还可以让你选择在谷歌购物中为你的商品做广告。
- 使用营销工具:通过电子邮件营销和特别优惠券吸引买家和浏览者。Bonanza 的客户营销工具让直接向过去的买家发送报价变得没有痛苦。 Shopify 为卖家提供选项,在他们的网站上创建带有 flash 销售和优惠的屏幕弹出窗口。
- 打造策划品牌体验:在每批货中包含一点额外的东西。你能提供一个小样品吗?包括一些让买家试用的东西,鼓励他们购买不同的产品。包括品牌包装、个性化说明或特殊优惠券代码是赢得买家的另一个好方法。
- 有机会就下线:还记得 80 年代的特百惠派对吗?谁说你不能与朋友、家人和邻居一起举办派对来展示你的物品。只要有可能,就在当地的工艺品交易会上预定一张桌子,倾听顾客的反馈,以不断提升你的品牌。
- 使用社交媒体:像脸书和 Instagram 这样的平台是讲述你的品牌故事的有效途径。你只需花 5 美元就可以购买广告,到达特定的市场,并获得关于你在与谁打交道的详细分析。
如何构建高绩效分析团队
原文:https://towardsdatascience.com/how-to-structure-a-high-performance-analytics-team-f564c92a1aaa?source=collection_archive---------3-----------------------
分析对于公司的成功和在竞争中获得竞争优势至关重要。我郑重声明,组建分析团队没有完美的方式。如今,团队的结构有多种方式,另外,如果你在谷歌上搜索,你会发现一些不同的结构正在被使用。我将在这篇文章中强调的是我认为组建团队的最佳方式。
企业可以做的最重要的事情是询问他们为什么需要分析。此外,对不同类型的分析技术有很好的理解将有助于你确定团队中需要谁。
分析学被定义为、对数据或统计的系统化计算分析。
分析是的保护伞——数据可视化(仪表盘)、EDA、机器学习、AI 等。
核心分析/数据挖掘方法
- 描述性——已经发生和正在发生什么?
- 规范性—为给定的问题找到最佳的行动方案
- 探索性—我的数据中存在哪些金块?
- 预测—未来会发生什么
谁构成了分析团队的核心?
- 数据分析师
- 数据工程师
- 数据科学家
这些角色是做什么的?
数据分析师
- 多面手,能够适应多种角色和团队,帮助他人做出数据驱动的决策
- 数据分析师通过获取数据、使用数据回答问题以及交流结果来帮助做出业务决策,从而实现价值
数据科学家
- 应用统计学和构建机器学习模型的专业知识进行预测并回答关键业务问题的专家
- 拥有数据分析师所具备的所有技能,但在这些技能方面会更有深度和专业知识
- 利用监督和非监督机器学习模型发现数据中隐藏的见解
数据工程师
- 构建并优化允许数据科学家和分析师开展工作的系统。确保数据被正确接收、转换、存储,并可供其他用户访问
- 更倾向于软件开发技能
根据您在分析之旅中所处的位置,以下是我的建议——爬之前必须先走
刚刚进入分析领域?
- 数据工程师和数据分析师
- 重要的是要有一个团队,可以建立你的数据连接,数据仓库,了解你的数据。团队中没有必要有数据科学家。您将为无法利用的技能组合买单,最终可能会让数据科学家对主要进行描述性分析感到沮丧。数据科学家是需要不断挑战的好奇生物。
已经在分析领域工作了一段时间,对您的数据有了很好的了解,想要转向高级分析吗?
- 数据工程师、数据分析师和数据科学家
- 现在是进入预测和说明性分析的正确时机,是雇用一两名数据科学家的时候了。
一旦团队扩展过了这最后一个阶段,雇佣一个项目经理来帮助推动分析团队的计划是有意义的。一旦你有一个 15 人以上的团队,这应该会发生
分析经理
谁应该管理分析团队?分析经理(也称为分析主管,或数据分析经理)如果团队只有 2 个人,这没有多大意义。然而,如果你有一个 3 人以上的团队,你需要一个经理。
分析经理的主要职责是-
- 管理数据仓库和 ETL 解决方案
- 根据最佳投资回报率对项目进行优先排序(经理必须具备丰富的领域知识,并对业务核心目标有深刻的理解)
- 保护数据分析师免受报告和可视化请求的轰炸
- 确保团队拥有完成项目所需的所有工具
- 影响业务成为数据驱动的文化
- 鼓励自助服务分析
- 为预测性和规范性分析项目提供指导
- 指导团队并为其提供持续的教育机会,以保持对其角色的掌控
分析总监
在某些情况下,根据组织的规模,可以有如下结构。
分析总监>分析经理和数据科学经理
- 分析总监管理分析和数据科学经理
- 分析经理将监督数据工程师和数据分析师,侧重于探索性和描述性分析。
- 数据科学经理将监督数据科学家,重点关注预测和说明性分析。
如果你有一个敏捷分析团队,你也可以有一个有团队领导的分析主管,但不一定是经理。我个人更喜欢敏捷团队有领导,有一个主管监督整个团队。
正如我在文章开头提到的,构建分析团队没有完美的方法,在我看来,这只是最具成本效益、最合理的解决方案。
请在评论区留下任何评论或反馈。
如何构建机器学习项目
原文:https://towardsdatascience.com/how-to-structure-machine-learning-projects-f6abec2340bd?source=collection_archive---------10-----------------------
让机器学习算法发挥作用
这篇文章不是要告诉你学习什么机器学习算法,并向你解释模型的本质。
如果你正在寻找这些材料,我强烈建议你查阅我以前的文章了解如何选择在线课程,选择哪些在线课程以及阅读哪些书籍以深入了解。
事实上,这篇文章将向您展示如何让 真正地 让机器学习算法为您的项目工作,以及如何构建它们,否则您会花费不必要的长时间在错误的方向上优化您的模型。
机器学习向往由吴恩达
不管你是数据科学的初学者还是专家,你都有可能(我是说 99%)听说过他的名字。
(Source)
他在 Coursera 上最著名的课程— 机器学习对世界各地的许多学生来说都是一笔财富。我一直很着迷于他将复杂的概念分解成更简单的信息进行学习的能力,尤其是对于机器学习的初学者。
他还写了一本书——《机器学习的向往》,为那些对机器学习感兴趣的人提供了实用指南。
而且是免费的!
点击这里一旦你注册了邮件列表,你将会收到每一章的草稿。
更新:
****如果你无法看到链接或注册邮件列表以获得草稿,请从我的 Google Drive 获得免费副本:https://Drive . Google . com/file/d/1 q 81 nayn 8 wy 8-byyxsxpziotkza 6974 x/view?usp =分享
外面有那么多机器学习的书。为什么是这本书?
(Source)
举个例子,说你要建立一个图像分类不同类别的神经网络。****
然而,你的神经网络的精确度不够好,你的团队需要在一个期限内达到期望的精确度。
压力很大。因此,您和您的团队开始集思广益,寻找改进模型的方法。例如:
- 获取更多培训数据
- 收集更多样化的训练数据:不同类别的具有不同设置和背景的图像
- 增加模型的复杂性:更多的单元,隐藏的层
- 不断调整模型参数以获得最佳设置
- 降低算法的学习速度(需要更长的时间)
- 尝试将正则化添加到模型中
- …
****好消息是:如果您选择了正确的方向,您的模型将能够在时间框架内满足所需的精度(甚至更高)。
****坏消息是:如果你选择了错误的方向,你可能会浪费几个月(甚至几年)的开发时间,最终意识到你做了一个错误的决定。不太好。
有的技术 AI 课会给你一锤子;这本书教你如何使用锤子。
—吴恩达
你如何充分利用这个模型并获得最佳结果?
你看。学会如何在一开始就为你的团队制定战略决策设定方向是非常重要的,这通常需要多年的经验。
因此,这本书旨在通过优先考虑最有前途的方向、诊断复杂的机器学习系统中的错误、提高团队的生产力等等,使机器学习算法为您的项目和公司服务。
这本书的预览
1。设置开发和测试集
- ****训练集——你在上面运行你的学习算法。
- Dev(开发)set —您可以使用它来调整参数、选择特性,以及做出其他关于学习算法的决定。有时也称为保留交叉验证集。
- 测试集 —用于评估算法的性能,但不决定使用什么学习算法或参数。
- 本章向读者展示了开发和测试集应该使用什么样的数据分布,要使用的开发/测试集的大小,以及要优化的指标等。
2。基本误差分析
- 在错误分析期间并行评估多个想法
- 清理贴错标签的开发和测试集示例
- 眼球和黑盒 dev 集应该有多大?
- 本章向读者展示了如何快速构建第一个简单的机器学习系统,然后通过错误分析进行迭代,以找到最佳线索,为时间投资提供最有希望的方向。
3。偏差和方差
- 偏差与方差权衡
- 减少偏差和方差的技术
- 这一章以非常清晰和简洁的方式解释了偏差和方差。它强调了识别模型欠拟合和过拟合的重要性。此外,它教读者一些有用的技术,以减少偏见和方差。
4。学习曲线
- 绘制训练误差和学习曲线
- 解释学习曲线:高偏差
- 解释学习曲线:其他案例
- 本章解释了为什么学习曲线对于理解模型的性能如此重要,以及如何使用学习曲线根据期望的性能水平做出决策。
5。对比人类水平的表现
6。不同发行版的培训和测试
7。调试推理算法
8。端到端深度学习
9。零件误差分析
最后的想法
(Source)
所以你现在可能想知道:为什么上面的其余章节是空的?
答案是我还在读这本书的过程中。肯定会很快看完的!😃
老实说,在读完这本书的前四章后,我已经学到了很多,并且发现了一些有用的技巧,否则我不会意识到的!
最重要的是,这本书不是技术性的,每一节只有 1-2 页。
感谢您的阅读。我希望通过展示我从这本书里得到的东西,能让你对这本书有一个简要的概述,以及你如何能从中受益。
最终,这本书的实用性将教会你如何构建你的机器学习项目,并让你的模型为你、你的团队和公司服务。
一如既往,如果您有任何问题或意见,请随时在下面留下您的反馈,或者您可以随时通过 LinkedIn 联系我。在那之前,下一篇文章再见!😄
关于作者
Admond Lee 目前是东南亚排名第一的商业银行 API 平台Staq—的联合创始人/首席技术官。
想要获得免费的每周数据科学和创业见解吗?
加入 Admond 的电子邮件时事通讯——Hustle Hub,每周他都会在这里分享可行的数据科学职业建议、错误&以及从创建他的初创公司 Staq 中学到的东西。
你可以在 LinkedIn 、 Medium 、 Twitter 、脸书上和他联系。
** [## 阿德蒙德·李
让每个人都能接触到数据科学。Admond 正在通过先进的社交分析和机器学习,利用可操作的见解帮助公司和数字营销机构实现营销投资回报。
www.admondlee.com](https://www.admondlee.com/)**
如何利用人工智能:你准备好跳跃的 4 个迹象
原文:https://towardsdatascience.com/how-to-take-advantage-of-ai-4-signs-youre-ready-to-make-the-jump-95660ded56c0?source=collection_archive---------12-----------------------
预测营销活动是寻求获得新客户并最大化现有客户终身价值的营销人员的下一个前沿领域。为什么?人工智能驱动的活动识别最有可能购买和再次购买的客户,然后推荐有针对性的促销活动和产品。这是你每天都会遇到的技术,无论是在亚马逊购物还是浏览网飞。由于支持这些平台的机器学习技术,所有那些你离不开的个性化推荐都是可能的。现在,多亏了云计算,预测营销正在走向真正的大众化。曾经只有大型企业才能实现的昂贵提议,现在已经成为主流。在许多方面,预测营销已经从一种奢侈品变成了必需品,每个组织都需要它来生存和保持竞争力。
幸运的是,这些先进技术的准入门槛比以往任何时候都低,每个组织都应该能够利用预测分析技术。尽管如此,有些人比其他人更适合。
您如何知道自己是否准备好利用预测营销技术?以下四个指标表明,是时候迈出这一大步了:
1.数据准备度:你的数据比较干净;数据字典可用;组织内明确定义了数据所有权;
预测是基于机器学习的。机器是可以处理大量数据、发现隐藏模式和识别成功故事的计算机软件。为了使这些输出准确,输入必须干净。如果您已经有了一个包含干净(标准化)数据的数据仓库或某种数据存储库,那么您已经有了一个良好的开端。
明确定义团队内部的数据所有权也很重要。不可避免地,会有一些与数据相关的清理工作要做。数据所有者负责做出与数据相关的决策,并持续努力确保数据保持干净和可访问。
2.现有基线:你衡量你的活动表现和投资回报;你细分(或计划细分)你的客户群
衡量机器学习产生的预测的有效性的能力至关重要。你如何知道使用预测是否比当前的方法更好?如果你已经在衡量你的营销活动的表现,那太好了。否则,您应该努力建立方法来衡量您现有方法的成功。这将帮助你调整你的活动和营销方法,以确保最大的投资回报率。
3.客户之旅:您从客户之旅中的大多数接触点获取数据
机器学习是通过处理数据来理解因果关系。你提供给机器的数据点越多,它就越能更好地理解顾客购买或放弃购物车的原因。你应该设法捕捉所有的客户接触点和互动,从网站访问到呼叫中心互动、对外营销活动、销售历史、退货、调查等。收集这些信息将有助于您识别客户旅程中的关键差距,从而使您能够相应地修改您的活动和营销实践。
4.数据驱动的文化:组织文化鼓励数据驱动的决策
即使是最准确的预测,在被组织决策者接受之前也是毫无意义的。有时,预测建议可能是违反直觉的。但你总能理解为什么机器会推荐一个特定的行动方案。如果你计划实施机器学习,拥有一个鼓励数据驱动决策的数据驱动文化是绝对必要的,更不用说管理一个成功的预测营销活动了。
您的组织符合上述标准吗?如果答案是肯定的,那么是时候用人工智能驱动的方法来提高你的营销力度了。
感谢您阅读帖子。
有问题吗?我们很乐意帮忙。在 info@vectorscient.com 取得联系
作者简介 : Suresh Chaganti, VectorScient 的联合创始人&战略顾问。Suresh 专门研究大数据,并将其应用于解决现实世界的商业问题。他在跨各种行业垂直领域设计 B2B 和 B2C 应用程序方面拥有 20 年的经验。在 linkedin 上与 suresh 联系
如何利用预测分析和人工智能应对大型银行
原文:https://towardsdatascience.com/how-to-take-on-the-megabanks-with-predictive-analytics-and-ai-eff3c849fcc0?source=collection_archive---------5-----------------------
无论您是地区银行、社区银行还是信用合作社,管理您的数据基础架构都是一项艰巨的工作。利润率很低,运行遗留系统需要时刻保持警惕。找到时间和资源来利用人工智能的进步并不容易。围绕大数据有太多的噪音,很难区分营销术语在哪里结束,现实在哪里开始,因此获得组织的认可可能是一个巨大的挑战。
但是小银行别无选择。事关生死存亡。全国性银行正在赢得下一代客户,大数据是一大优势。
“银行真的不再能够选择是否进入分析领域……现在,客户互动正在向所有人群的数字空间转移,不再需要更多的人际互动。分析是你希望个性化和影响有利结果的唯一途径。”——美国律师协会银行期刊, 大数据和预测分析:的确是一件大事
然而,对各种规模的银行来说,都有好消息。执行预测建模等高级分析项目所需的工具比以往任何时候都更加容易获得和灵活。这意味着银行可以将他们的分析预算用于最重要的地方,避免将资金投入到没有价值的系统中。他们可以独立完成,也可以在有针对性的项目中与专业顾问合作。
数据科学:参与规则
我们为参与高级分析项目的地区银行和信用合作社推荐五条原则:
- 定义明确的目标。根据 Gartner 的调查,55%的大数据项目从未完成。问题不在于努力或数据质量。相反,最大的挑战是设定与可证明的价值相关的明确目标。
- 采取渐进的方法。没有必要在员工和软件上进行大量投资。事实上,如果你一次只关注一个机会,你会得到更好的结果。然后利用你所学到的,并在此基础上发展。
- 像科学家一样思考。假设,实验,学习,重复。一种演绎的科学方法会让你保持专注,并提供你可以依赖的结果。
- 围绕客户需求确定询问的优先顺序。客户承诺已经让小型银行从全国性银行中脱颖而出。利用你的优势。
- 做好准备迎接惊喜。结构合理且客观的分析调查将克服确认偏差,揭示您可能没有预料到的见解。
“即使银行决定只能花很少的钱,那也比什么都不做要好。”——美国银行家,为什么小银行需要大数据
面向小型银行的下一级分析
社区银行已经非常了解如何使用数据,无论是用于业务分析、细分还是风险管理。人工智能的进步使另一个层面的洞察力成为可能,使个人客户层面的预测比以往任何时候都更有用。
- 预测客户需要什么。产品交叉销售对银行来说并不新鲜。但是现在通过行为分析,预测顾客真正需要什么,并提供给顾客是可能的。
- 打造更好的在线体验。无论是优化您的网站体验,还是最大限度地提高网上银行的效率,现在比以往任何时候都更容易收集能够产生影响的精细数据。
- 整合数据源,揭示完整的客户旅程。连接 CRM、联络中心和 web 数据源可以让您全面了解客户体验,从而识别优势和劣势。
- 确定哪些客户可能会离开。客户行为分析可以帮助您预测和应对潜在的客户维系挑战。
- 懂地理。通过位置追踪互动可以告诉你很多关于你的客户在哪里做生意——以及你需要在哪里。
“国家银行现在赢得了绝大部分初级支票购买者,尤其是千禧一代。然而,国民银行的千禧一代也更愿意更换银行,这为其他银行创造了一个机会,这些银行可以了解并瞄准该细分市场的最佳部分,然后优先考虑必要的数字、营销和其他投资。”— Novantas, 2016 年全渠道购物者调查
小银行成功的关键是为使用大数据和人工智能设定明确的目标。但是要做好准备,足够灵活地去数据带你去的地方。
想了解更多关于数据科学增量方法如何在您的组织中发挥作用的信息吗?在 hello@deducive.com 给我们写封短信。
此文原载于Deducive.com。
如何与客户交谈以获得更好的结果
原文:https://towardsdatascience.com/how-to-talk-to-customers-to-get-better-results-5fcae25c5f0c?source=collection_archive---------0-----------------------
他们可能不懂数据科学,但他们可以教你很多东西。
本文摘自 像数据科学家一样思考 。
数据科学领域的每个项目都有一个客户。有时,客户是付钱给你或你的企业来做项目的人,例如,客户或合同代理。在学术界,客户可能是要求您分析其数据的实验室科学家。有时客户是你、你的老板或另一位同事。无论客户是谁,他们都希望从你这个负责项目的数据科学家那里得到一些东西。
通常,这些期望与以下方面有关:
- 需要回答的问题或需要解决的问题;
- 有形的最终产品,如报告或软件应用程序;或者,
- 先前研究或相关项目和产品的总结
期望可以来自任何地方。一些是希望和梦想,另一些来自类似项目的经验或知识。然而,关于期望的典型讨论可以归结为两个方面:客户想要什么,数据科学家认为什么是可能的。这可以被描述为愿望与实用主义,客户描述他们的愿望,数据科学家根据表面的可行性批准、拒绝或限定每一个。另一方面,如果你愿意把自己这个数据科学家想象成一个精灵,一个愿望的授予者,你不会是第一个这样做的人!
解决愿望和实用主义
至于客户的愿望,他们可以从完全合理到完全古怪,这是可以的。很多商业发展和硬科学都是由直觉驱动的。也就是说,首席执行官、生物学家、营销人员和物理学家都利用他们的经验和知识来发展关于世界如何运转的理论。其中一些理论有可靠的数据和分析支持,但其他更多的来自直觉,这基本上是一个人在他们的领域广泛工作时开发的概念框架。很多领域和数据科学的一个显著区别是,在数据科学中,如果一个客户有一个愿望,即使是一个有经验的数据科学家也不一定知道是否可能。软件工程师通常知道软件工具能够执行什么任务,生物学家或多或少知道实验室能做什么,但尚未看到或使用过相关数据的数据科学家面临着大量的不确定性,主要是关于哪些具体数据可用以及它能为回答任何给定问题提供多少证据。同样,不确定性是数据科学过程中的一个主要因素,在与客户谈论他们的愿望时,应该首先考虑这一点。
例如,在我与生物学家和基因表达数据打交道的几年中,我开始形成自己的概念,即 RNA 是如何从 DNA 翻译而来的,RNA 链是如何在细胞中漂浮并与其他分子相互作用的。我是一个视觉型的人,所以我经常发现自己在想象一条由数百或数千个核苷酸组成的 RNA 链,每个核苷酸看起来就像四个字母中的一个,代表一个碱基化合物(A、C、G 或 T;为了方便起见,我用“T”代替“U”),整个链看起来像一条长而柔韧的链——这个句子只对细胞内的机器有意义。由于 RNA 及其核苷酸的化学性质,互补序列喜欢彼此结合;a 喜欢与 T 结合,C 喜欢与 g 结合。因此,当两条 RNA 链包含接近互补的序列时,它们很可能会彼此粘在一起。如果一条 RNA 链足够灵活并含有互补的序列,它也可能折叠并粘在自身上。这是一个概念框架,我在很多场合下用它来猜测当一堆 RNA 在细胞中漂浮时会发生什么。
因此,当我开始处理微小 RNA 数据时,我意识到微小 RNA 大约 20 个核苷酸的短序列——可能会与遗传 mRNA 序列的一部分(即直接从对应于特定基因的 DNA 链翻译的 RNA,通常要长得多)结合,并抑制其他分子与该基因的 mRNA 相互作用,从而有效地使该基因序列变得无用。对我来说,一点 RNA 可以粘在一段遗传 RNA 上,并最终阻止另一个分子粘在同一段上,这在概念上是有意义的。这一概念得到了科学期刊文章和确凿数据的支持,这些数据表明,如果 microRNA 和基因 mRNA 具有互补序列,它们可以抑制基因 mRNA 的表达或功能。
然而,与我一起工作的一位生物学教授有一个更加微妙的概念框架,描述了他如何看待这个基因、微小 RNA 和 mRNA 的系统。特别是,他几十年来一直在研究普通小鼠小家鼠的生物学,可以列出任何数量的显著基因、它们的功能、相关基因以及物理系统和特征,如果开始做“敲除”这些基因的实验,这些基因就会受到明显的影响。因为教授比我更了解老鼠的遗传学,而且因为他不可能和我分享他所有的知识,所以在花太多时间研究一个项目的任何方面之前,讨论这个项目的目标和期望对我们来说是非常重要的。没有他的投入,我基本上只能猜测生物学相关的目标是什么。如果我错了(这很有可能),工作就白费了。例如,某些特定的微小 RNA 已经得到了很好的研究,并且已知它们在细胞内完成非常基本的功能,甚至更多。如果该项目的目标之一是发现很少研究的微小 RNA 的新功能,我们可能会想从分析中排除某些微小 RNA 家族。如果我们不把它们排除在外,它们很可能只会给细胞内已经非常嘈杂的基因对话增添噪音。这仅仅是教授知道的许多重要事情中的一件,而我却不知道。因此,在认真开始任何项目之前,对目标、期望和注意事项进行冗长的讨论是必要的。
从广义(如果简单的话)来说,当且仅当客户对结果满意时,项目才被认为是成功的。当然,这一准则也有例外,但无论如何,在数据科学项目的每一步中始终牢记期望和目标是非常重要的。不幸的是,根据我自己的经验,在项目的开始阶段,期望通常是不清楚或者不明显的,或者不容易简明地表达出来。因此,我决定采用一些实践来帮助我找出合理的目标,这些目标可以指导我完成涉及数据科学的项目的每一步。
客户很可能不是数据科学家
关于客户期望的一件有趣的事情是,他们可能不合适。这并不总是——甚至通常也不是——客户的错,因为数据科学解决的问题本质上是复杂的,如果客户完全了解他们自己的问题,他们可能就不需要数据科学家来帮助他们了。因此,当客户的语言或理解不清楚时,我总是放他们一马,我认为设定期望和目标的过程是一个联合练习,可以说类似于冲突解决或关系治疗。
您,数据科学家,和客户都有成功完成项目的共同兴趣,但是你们两个可能有不同的具体动机,不同的技能,最重要的是,不同的观点。即使你自己是客户,你也可以把自己想象成分成两半,一部分(数据科学家)专注于获得结果,另一部分(客户)专注于使用这些结果做一些“真正的”事情,或者项目本身之外的事情。通过这种方式,数据科学的项目从寻找两种性格、两种观点之间的一致开始,如果它们不冲突,至少是完全不同的。
虽然严格来说,您和客户之间没有冲突,但有时看起来是这样的,因为你们都在朝着一组既可实现(对数据科学家而言)又有帮助(对客户而言)的目标混日子。而且,就像在解决冲突和关系治疗中一样,也涉及到感情。这些感觉可能是意识形态的,受个人经历、偏好或观点的驱使,对另一方来说可能没有意义。因此,一点耐心和理解,而不需要太多的判断,对你们双方都非常有益,更重要的是,对项目也非常有益。
问非常具体的问题来揭露事实,而不是发表意见
当客户描述关于您要研究的系统的理论或假设时,他们几乎肯定会表达事实和观点的混合,区分这两者通常很重要。例如,在一项关于小鼠癌症发展的研究中,前述生物学教授告诉我,“众所周知,哪些基因与癌症有关,而这项研究只关注那些基因,以及抑制它们的微小 RNA。”人们可能会试图从表面上接受这种说法,并只分析癌症相关基因的数据,但这可能是一个错误,因为这种说法有些模糊。原则上,还不清楚是否其他可能与癌症无关的基因在实验引发的复杂反应中起辅助作用,或者是否众所周知并证明癌症相关基因的表达完全独立于其他基因。在前一种情况下,忽略与非癌症相关基因相对应的数据不是一个好主意,而在后一种情况下,这可能是一个好主意。不解决这个问题,就不清楚哪一个是合适的选择。所以,问很重要。
同样重要的是,问题本身要以客户能够理解的方式表述。例如,问“我应该忽略来自与癌症无关的基因的数据吗?”是不明智的这是一个关于数据科学实践的问题,属于你的领域,而不是生物学家的。相反,你应该问类似于“你有任何证据证明癌症相关基因的表达是独立于其他基因的吗?”这是一个关于生物学的问题,希望生物学教授能够理解。
在他的回答中,区分他所想的和他所知的是很重要的。如果教授只是认为这些基因的表达是独立于其他基因的,那么在整个项目过程中,这肯定是要记住的事情,但你不应该根据它做出任何非常重要的决定——比如忽略某些数据。另一方面,如果教授可以引用科学研究来支持他的观点,那么利用这个事实来做决定是绝对明智的。
在任何项目中,作为数据科学家,你是统计学和软件工具方面的专家,但是主要的主题专家通常是其他人,就像涉及生物学教授的情况一样。在向这位主题专家学习的过程中,你应该提出一些问题,这些问题不仅能让你对所研究的系统是如何工作的有一些直观的感觉,还能试图将事实与观点和直觉分开。基于事实的实际决策总是一个好主意,但是基于观点的决策可能是危险的。“信任,但要确认”这句格言在这里很合适。如果我忽略了数据集中的任何基因,我很可能错过了癌症实验中各种类型的 RNA 之间发生的复杂相互作用的一个关键方面。事实证明,癌症是一种非常复杂的疾病,不仅在医学层面,在基因层面也是如此。
提示交付物:猜测并检查
您的客户可能不了解数据科学及其用途。问他们,“你希望在最终报告中出现什么?”或者“这个分析应用程序应该做什么?”很容易导致“我不知道”,或者更糟,一个没有实际意义的建议。数据科学不是他们的专业领域,他们可能没有完全意识到软件和数据的可能性和局限性。因此,通常最好用一系列建议来解决最终产品的问题,然后注意顾客的反应。
我最喜欢问客户的一个问题是,“你能给我一个你可能希望在最终报告中看到的句子的例子吗?”我可能会得到这样的回答,“我想看看:‘微小 RNA-X 似乎能显著抑制 Y 基因’;”或者“基因 Y 和基因 Z 似乎在所有测试样本中表达水平相同。”诸如此类的回答为构思最终产品的格式提供了一个很好的起点。如果客户能给你这样的种子想法,你可以扩展它们,提出最终产品的建议。你可能会问,“如果我给你一张特定微 RNA 和基因 mRNAs 之间最强相互作用的表格会怎么样?”客户可能会说这很有价值,也可能不会。
然而,最有可能的是,客户会做出不太明确的陈述,例如,“我想知道哪些微小 RNA 在癌症发展中是重要的。”当然,如果我们希望成功地完成这个项目,我们需要澄清这一点。生物学意义上的“重要”是什么意思?这种重要性如何体现在现有的数据中?在继续之前得到这些问题的答案是很重要的;如果你不知道微小 RNA 的重要性如何在数据中体现出来,你怎么知道你什么时候找到了它?
我和许多其他人犯的一个错误是将相关性和重要性混为一谈。一些人谈到了相关性和因果性的混淆,一个例子是:戴头盔的骑车人比不戴头盔的骑车人卷入事故的比例更高;头盔引发事故的结论可能很诱人,但这可能是错误的。头盔与事故的相关性并不意味着头盔导致事故;也不是说事故[直接]导致头盔。事实上,在更繁忙、更危险的道路上骑自行车的人更有可能戴头盔,也更有可能发生事故。本质上,在更危险的道路上骑车会导致这两种情况。在头盔和事故的问题上,尽管存在相关性,但没有直接的因果关系。反过来,因果关系仅仅是相关性可能很重要的一个例子。如果你正在对头盔的使用和事故率进行研究,那么这种相关性可能是显著的,即使它并不意味着因果关系。应该强调的是,重要性,正如我所使用的术语,是由项目的目标决定的。头盔-事故相关性的知识可以导致考虑(和建模)作为项目一部分的每条道路上的交通和危险水平。相关性也不能保证显著性。我相当肯定更多的骑自行车事故发生在晴天,但这是因为更多的骑自行车的人在晴天上路,而不是因为任何其他重要的关系(当然,除非下雨)。我现在还不清楚如何利用这些信息来实现我的目标,所以我不会花太多时间去探索它。在这种特殊情况下,这种相关性似乎没有任何意义。
在基因/RNA 表达实验中,通常在 10-20 个生物样品中测量了数千个 RNA 序列。这种变量(每个 RNA 序列的表达水平)远多于数据点(样本)的分析被称为“高维”或通常“欠确定”,因为变量太多,其中一些只是随机相关,如果说它们在真正的生物学意义上是真正相关的,那将是荒谬的。如果你向生物学教授提交一份强相关性的列表,他会立即发现你报告的一些相关性不重要,或者更糟的是,与已有的研究相反,你将不得不回去做更多的分析。
基于知识而不是愿望来重复你的想法
正如在你所掌握的领域知识中,把事实和观点分开是重要的一样,避免让过度乐观使你对障碍和困难视而不见也是重要的。我早就说过,优秀数据科学家的一项无价技能是预见潜在困难并为其开路的能力。
在当今的软件行业中,在分析能力还处于开发阶段时就对其进行断言是很流行的。我了解到,这是一种推销策略,似乎经常是必要的,尤其是对于年轻的初创企业,以便在竞争激烈的行业中取得成功。当有人积极销售一款分析软件时,我总是感到紧张,我说我认为我可以开发这款软件,但考虑到我们现有数据的一些限制,我不能 100%肯定它会按计划工作。因此,当我做出如此大胆的声明时,我会尽可能地将它们保持在我几乎肯定能做到的事情范围内,如果我做不到,我会尝试制定一个备用计划,不涉及原计划中最棘手的部分。
假设您想要开发一个总结新闻文章的应用程序。你需要创建一个算法,可以解析文章中的句子和段落,并提取主要思想。有可能编写一个算法来做到这一点,但尚不清楚它的性能如何。对于大多数文章来说,摘要在某种意义上可能是成功的,但 51%的成功和 99%的成功之间有很大的区别,至少在你建立了第一个版本之前,你不会知道你的特定算法属于那个范围。盲目销售和狂热开发这种算法可能看起来是最好的主意;努力就会有回报,对吧?也许吧。这项任务很难。完全有可能的是,尽管你尽了最大努力,但你永远不会获得超过 75%的成功,从商业角度来看,这可能还不够好。那你会怎么做?你会放弃并关闭商店吗?只有在这次失败后,你才开始寻找替代方案吗?
一个优秀的数据科学家甚至在开始之前就知道任务有多难。句子和段落是复杂的随机变量,通常看起来是专门设计来挫败你可能扔给它的任何算法的。在失败的情况下,我总是回到“首要原则”,在某种意义上:我试图解决什么问题?除了总结,最终目标是什么?
如果最终目标是建立一个让阅读新闻更有效率的产品,也许有另一种方法来解决新闻读者效率低下的问题。或许把相似的文章聚合在一起呈现给读者更容易。或许可以通过更友好的设计或整合社交媒体来设计更好的新闻阅读器。
没有人想宣布失败,但数据科学是一个有风险的行业,假装失败从来没有发生本身就是一个失败。解决问题总是有多种方法,制定一个承认障碍和失败可能性的计划可以让你在前进的道路上从微小的成功中获得价值,即使主要目标没有实现。
一个更大的错误是忽略失败的可能性以及测试和评估应用程序性能的需要。如果你认为产品工作得近乎完美,但事实并非如此,那么将产品交付给客户可能是一个巨大的错误。你能想象如果你开始销售一个未经测试的应用程序,该应用程序本应该对新闻文章进行摘要,但是很快你的用户就开始抱怨摘要完全错误吗?不仅应用程序会失败,而且你和你的公司可能会因为软件不工作而名声大噪。
要了解更多信息,请下载免费的第一章 像数据科学家 一样思考,并查看此 幻灯片演示 获取折扣代码。
Brian Godsey 博士,是一位数学家、企业家、投资人和数据科学家,他的著作 像数据科学家一样思考 现已面世。——【briangodsey.com】
如果你喜欢这个,请点击💚下面。
*[## (我喜欢你)叫我大数据
恶名昭彰的 IDE 人群的滑稽嘻哈联合
medium.com](https://medium.com/@briangodsey/i-love-it-when-you-call-me-big-data-2e4b89e84740)* *[## 不确定性意识:数据科学的一个优点
脸书最近在趋势分析上的失态再次表明,好的数据科学取决于承认你不知道
medium.com](https://medium.com/@briangodsey/awareness-of-uncertainty-a-virtue-in-data-science-c6751e7f5a00)*
如何用卷积神经网络教计算机看东西
原文:https://towardsdatascience.com/how-to-teach-a-computer-to-see-with-convolutional-neural-networks-96c120827cd1?source=collection_archive---------11-----------------------
在过去的几年里,计算机视觉领域取得了巨大的进步。卷积神经网络极大地提高了图像识别模型的准确性,并在现实世界中有大量的应用。在本文中,我将介绍它们是如何工作的,一些真实世界的应用程序,以及如何用 Python 和 Keras 编写一个应用程序。
Photo by Amanda Dalbjörn on Unsplash
对我们大多数人来说,看是我们日常生活的一部分。我们用眼睛来寻找我们周围世界的道路。我们用它们来交流和理解。大概不用我说,视力超级重要。这是我们一天中如此重要的一部分。我是说,你能想象,看不见吗?
但是如果我让你解释视觉是如何工作的呢?我们如何理解眼睛解读的东西?嗯,首先你看一些东西,然后…什么?大脑就像一台经过数百万年自然发展的超级复杂的计算机。我们已经非常擅长识别各种模式和物体。
许多技术都是基于自然机制。以相机为例。快门控制光量,类似于我们的瞳孔。相机和眼睛中的镜头聚焦并反转图像。相机和眼睛都有某种方式来感知光线,并将其转换为可以理解的信号。
Photo by Alfonso Reyes on Unsplash
但显然,我们不只是用胳膊和腿移动摄像机。我们目前拥有的相机显然不能完全理解他们在拍什么。如果他们这样做了,那就有点可怕了。对照相机和电脑来说,一张照片只是一串排列的数字。
Digit 8 from MNIST dataset represented as an array. Source.
那么,我们究竟怎样才能创造出能够告诉我们狗是狗还是猫的程序呢?这是我们试图用计算机视觉解决的问题。
这就是神经网络如何帮助我们的!
神经网络如何工作
人工神经网络(ANN)是基于人脑的松散程序。神经网络由许多相连的神经元组成。这些神经网络中的一些可以有数百万个节点和数十亿个连接!
神经元基本上是一种接受输入并返回输出的功能。
Artificial neurons are modeled off biological neurons. Source.
一个神经元本身做不了多少事。但是当你有大量的神经元连接在一起时,乐趣就开始了。不同层次/结构的神经网络让你做很多很酷的事情。
You can get something like this!
每个神经元通常与某种权重相关联。基本上,当一个连接比另一个更重要时。假设我们有一个网络想告诉你图片是不是一个热狗。那么我们会希望包含热狗特征的神经元比普通狗的特征更重要。
神经网络的权重是通过对数据集进行训练来学习的。它将运行许多次,通过关于损失函数的反向传播来改变它的权重。神经网络基本上通过测试数据,做出预测,然后看到它有多错。然后它得到这个分数,让自己变得稍微准确一点。通过这个过程,神经网络可以学习提高其预测的准确性。
我不会在这篇文章中讨论反向传播或损失函数,但是有很多很棒的资源,比如 this 涵盖了这些主题!
卷积神经网络(CNN)是一种特殊的神经网络。当应用于图像数据集时,它们表现得非常好。
卷积神经网络
A diagram of Convolutional Neural Networks. Source.
正如我之前提到的,计算机将图片视为一组数组中的数字。CNN 的不同层将函数应用于这些阵列,以从图像中提取各种特征,并降低图像的复杂性。
让我们来看看在热狗检测器上训练 CNN 的一些步骤。
首先,我们用随机权重初始化 CNN。这基本上意味着网络完全是在猜测。一旦它做出预测,它将检查使用损失函数的错误程度,然后更新其权重,以便下次做出更好的预测。
CNN 包含称为卷积层和池层的层。你可以这样想象卷积层会发生什么。
假设你有一张照片和一个放大镜。把你的放大镜放在图片的左上角,寻找一个特定的特征。记下它是否在那里。慢慢地在图像中移动,重复这个过程。
Visualizing feature extraction in a convolutional layer. Source.
卷积层创建一堆特征图。
对于一个用来描述不同图像如动物或面孔的 CNN 来说。第一卷积层寻找的特征可以是对象的不同边缘。这就像是把图片中不同的边列了一个清单。这个列表然后被传递到另一个卷积层,它做类似的事情,除了它在图像中寻找更大的形状。这可能是动物的一条腿,也可能是脸上的一只眼睛。最终,这些特征被一个全连接的层所接受,该层对图像进行分类。
汇集层也用于卷积层。这需要另一个放大镜,但它不会寻找特征。而是取一个区域的最大值来降低图像的复杂度。
Pooling in a CNN. Source.
这很有用,因为大多数图像都很大。它们有大量的像素,这使得处理器很难处理它们。共享让我们在保留大部分重要信息的同时缩小图像的尺寸。池化还用于防止过度拟合,即当模型变得过于擅长识别我们对其进行训练的数据,而对我们给出的其他示例不太适用时。
An example of overfitting on a linear dataset. [Source.](http://By Ghiles - Own work, CC BY-SA 4.0, https://commons.wikimedia.org/w/index.php?curid=47471056)
如图所示,该图中的数据可以用一条直线来表示。蓝色的模型显然击中了所有的数据点,但如果我们试图让它预测其他东西,它将无法做到。就我们的 CNN 而言,这可能意味着它将对我们训练它的图像超级准确,但无法在其他图像上给我们正确的预测。
最后,我们把 CNN 的结构扁平化成一个超长的特写。我们基本上只是把所有的数据放在一起,这样我们就可以把它传递给一个完全连接的层来进行预测。
为什么神经网络更好?
假设我们没有使用神经网络。我们将如何处理这个问题?假设我们正在尝试编写一个识别猫的程序。我们可以通过寻找特定的形状来表现猫。
Cat shapes from Computer Vision Expert Fei-Fei Li’s TED Talk.
看起来很简单,对吧?但是等一下。不是所有的猫都长这样。如果你有一只伸展开的猫呢?我们需要添加更多的形状。
More cat shapes from Computer Vision Expert Fei-Fei Li’s TED Talk.
至此,应该很清楚告诉计算机寻找某些形状是行不通的。猫有各种形状和大小。这是假设我们只在找猫。如果我们想要一个可以对各种图片进行分类的程序呢?
这就是为什么使用神经网络要好得多。你可以让电脑设定自己的规则。通过使用高度先进的算法,神经网络可以以极高的准确度对图像进行分类。一些模型已经在这项任务中击败了人类!
我们应用计算机视觉的一些很酷的方式
随着算法变得更高效,硬件变得更强大,我们可能能够用更接近科幻小说领域的神经网络来完成任务。但这并不意味着我们现在没有用这项技术做很多很酷的事情!
零售
你可能在新闻里听说过。 亚马逊 Go ,电商巨头的无收银员杂货店。你走进去,拿起一些东西,然后走出来。系统会自动向你收取费用。覆盖在天花板上的摄像头会记录下你拿起的物品。虽然该系统并不完善,而且可能容易受到入店行窃的影响。看到这个想法在未来几年内如何发展将会非常有趣。
自动驾驶汽车
在我看来,自动驾驶汽车是目前正在开发的最酷的东西之一。 Waymo ,最初是谷歌的自动驾驶汽车项目,优步和特斯拉是一些公司目前正在开发可以自行导航道路的车辆。
Waymo 的自动驾驶汽车车队已经行驶了超过 1000 万英里的道路!平均每年旅行约 12000 英里。总共有 800 多年的驾驶经验!
One of Waymo’s self-driving cars. Source.
卫生保健
在医疗保健中,CNN 被用于识别许多不同种类的疾病。通过对癌症或其他医疗状况的某些数据集进行训练,神经网络可以以很高的准确率找出是否有问题!通过让神经网络提取特征并在数据中找到模式,它可以利用我们从未想到过的图片信息!
微软正在开发其InnerEye项目,该项目帮助临床医生使用深度学习和 CNN 分析 3D 放射图像。这有助于医疗从业者提取定量测量值,并有效地计划手术。
用 Keras 创建卷积神经网络
既然我们理解了 CNN 应该如何工作背后的一些直觉。我们可以用 Python 编写的高级 APIKeras在 Python 中创建一个。Keras 将帮助我们编写易于理解和超级可读的代码。
你可以从安装 Anaconda 开始,在命令界面运行conda install keras
。然后你可以使用 Jupyter 笔记本开始用 Python 编程。如果你想在云端运行一切,你也可以使用谷歌的合作实验室。
我们将使用属于 Keras 库的 MNIST 数据集。包含 6 万个训练样本和 1 万个手写数字测试样本。我们开始吧!
The first few training examples in the MNIST dataset.
首先,我们要从 Keras 库中导入我们需要的所有东西。这包括顺序模型,这意味着我们可以通过添加层来轻松构建模型。接下来我们将导入 Conv2D (Convolution2D),MaxPooling2D,Flatten 和 Dense 层。前 3 个是不言自明的,密集层帮助我们建立完全连接的层。
我们将需要 Keras Utils 来帮助我们编码数据以确保它与我们模型的其余部分兼容。这使得数字 9 不会被视为比 1 更好。最后,我们将导入用于训练模型的 MNIST 数据集。
导入数据集后,我们需要将它分成训练数据和测试数据。训练数据就是我们要教给神经网络的东西。测试数据是我们用来衡量准确性的。我们将重塑数据,以匹配 TensorFlow 后端所需的格式。接下来我们将归一化数据,以保持数值范围在 0 到 1 之间。并且对MNIST 标签进行分类编码。
太好了!现在我们可以开始构建我们的模型了。我们将从创建一个序列模型开始,这是一个层的线性堆栈。正如你在下面的代码中看到的,这使得我们向模型中添加更多的层变得非常容易。
在我们建立完模型后,我们将编译它。该模型使用 Adam 优化器,这是一种用于调整权重的梯度下降算法。我们的模型使用的损失函数是分类交叉熵,它告诉我们的模型我们离结果有多远。指标参数用于定义如何评估绩效。它类似于损失函数,但在实际训练过程中不会用到。
我们将在训练台上调整或训练我们的模型。批量大小决定了我们在每次迭代中要考虑多少张图像。历元的数量决定了模型在整个集合中迭代的次数。在一定数量的时代之后,模型将基本上停止改进。
详细值决定了模型是否会告诉我们模型的进度,而验证数据决定了模型如何在每个时期后评估其损失。**
最后,我们将打印出我们的模型有多精确。最终结果应该在 98%到 99%之间
你可以在 my GitHub 上找到完整的代码,或者你可以在 Google Colaboratory 上运行它。
关键要点
- 神经网络松散地基于我们大脑解释信息的方式。
- 卷积神经网络特别适合处理图像。
- 计算机视觉在现实世界中有很多应用。
感谢阅读!如果您喜欢,请:
- 在 LinkedIn上添加我并关注我的媒体,了解我的旅程
- 留下一些反馈或给我发电子邮件(alexjy@yahoo.com)
- 与你的网络分享这篇文章
如何教 AI 玩游戏:深度强化学习
原文:https://towardsdatascience.com/how-to-teach-an-ai-to-play-games-deep-reinforcement-learning-28f9b920440a?source=collection_archive---------0-----------------------
如果你对机器学习感兴趣,并且对它如何应用于游戏或优化感兴趣,那么这篇文章就是为你准备的。我们将看到强化学习和深度强化学习(神经网络+ Q 学习)的基础知识应用于游戏 Snake。让我们开始吧!
与普遍的看法相反,人工智能和游戏并不能和谐相处。这是一个有争议的观点吗?是的,它是,但是我将解释它。人工智能和人工行为是有区别的。我们不希望我们游戏中的代理比玩家更聪明。我们希望他们足够聪明,能够提供乐趣和参与。我们不想挑战我们 ML bot 的极限,就像我们通常在不同行业所做的那样。对手需要是不完美的,模仿一个类似人类的行为。
然而,游戏不仅仅是娱乐。训练一个虚拟代理人超越人类玩家可以教会我们如何在各种不同和令人兴奋的子领域中优化不同的过程。这就是谷歌 DeepMind 用其广受欢迎的 AlphaGo 所做的事情,它击败了历史上最强的围棋选手,打进了一个在当时被认为不可能的进球。在本文中,我们将开发一个人工智能代理,它能够从头开始学习如何玩热门游戏《贪吃蛇》。为了做到这一点,我们在 Tensorflow 和 PyTorch(两个版本都可用,您可以选择您喜欢的一个)之上使用两个 Keras 实现了一个****深度强化学习算法。这种方法包括两个组件之间的交互:环境(游戏本身)和代理(Snake)。代理收集关于其当前状态的信息(我们将在后面看到这意味着什么)并相应地执行动作。环境基于执行的动作奖励或惩罚代理。随着时间的推移,代理学会了什么样的行为能使回报最大化(在我们的例子中,什么样的行为会导致吃掉苹果和避开墙壁)。没有给出关于游戏的规则。最初,Snake 不知道该做什么,并且执行随机的动作。目标是制定一个策略(技术上称为“政策”)来最大化分数——或回报。
我们将看到一个深度 Q 学习算法如何学习玩蛇,在短短 5 分钟的训练中,得分高达 50 分,显示出扎实的策略。可选地,代码显示如何使用贝叶斯优化来优化人工神经网络。这个过程不是必须的,但是我想为高级读者提一下。
关于完整代码,请参考 GitHub 库。下面我将展示学习模块的实现。
游戏
On the left, the AI does not know anything about the game. On the right, the AI is trained and learnt how to play.
这个游戏是用 Pygame 用 python 编写的,Pygame 是一个允许开发相当简单的游戏的库。在左边,代理没有经过训练,也不知道该做什么。右边的游戏指的是训练后的特工(5 分钟左右)。
它是如何工作的?
强化学习是一系列用于控制的算法和技术(如机器人技术、自动驾驶等)..)和决策。这些方法解决了需要表达为马尔可夫决策过程(MDP)的问题。这是什么意思?这意味着我们需要通过一组状态 S(例如,基于蛇的位置的索引)、一组动作 A(例如,上、下、右、左)、一个奖励函数 R(例如,当蛇吃苹果时+10,当蛇碰壁时-10)和可选的描述状态之间转换的转换函数 T 来描述我们的游戏。为了使用强化学习,我们需要使用这四个部分来形式化我们的问题。如果这是令人困惑的,怕不是,几分钟后一切都会明朗。
在我的实现中,我使用了深度 Q 学习,而不是传统的监督机器学习方法。有什么区别?传统的 ML 算法需要用一个输入和一个叫做 target 的“正确答案”来训练。然后,系统将尝试学习如何根据看不见的输入来预测目标。在这个例子中,我们不知道在游戏的每个状态下应该采取的最佳行动(这实际上是我们正在努力学习的!),所以传统的方法不会有效。
在强化学习中,我们有两个主要组件:环境(我们的游戏)和代理(我们的蛇..或者正确的说,驱动我们蛇行动的深层神经网络)。每当代理执行一个动作,环境就给代理一个奖励,奖励可以是正的也可以是负的,这取决于该动作在特定状态下有多好。代理的目标是在给定每一种可能状态的情况下,学习什么样的行为能使奖励最大化。状态状态是代理在每次迭代中从环境中接收到的观察结果。一个状态可以是它的位置,它的速度,或者任何描述环境的变量数组。更严格地说,使用强化学习符号,代理用来做决策的策略被称为策略**。在理论层面上,策略是从状态空间(代理可以接收的所有可能观察的空间)到动作空间(代理可以采取的所有动作的空间,比如上、下、左和右)的映射。最优智能体可以在整个状态空间中进行归纳,从而总是预测最佳的可能行动..甚至对于那些代理人从来没有见过的情况!如果这还不清楚,下一个例子会澄清你的疑惑。为了理解代理如何做决定,我们需要知道什么是 Q 表。Q 表是一个矩阵,它将代理的状态与代理可能采取的行动相关联。表中的值是行动成功的概率(从技术上来说,是对预期累积奖励的一种衡量),根据代理在培训期间获得的奖励进行更新。贪婪策略的一个例子是代理查找表格并选择导致最高分数的动作的策略。****
Representation of a Q-Table
在这个例子中,如果我们处于状态 2,我们可能会选择右,如果我们处于状态 4,我们可能会选择上。Q 表中的值代表从状态 s. 采取行动 a 的累积 预期报酬,换句话说,这些值给我们一个指示,即如果代理从该状态 s 采取行动 a 时它获得的平均报酬。 这个表就是我们之前提到的代理人的策略: 它决定了从每个状态应该采取什么行动来最大化期望报酬。这有什么问题?策略是一个表,因此它只能处理有限的状态空间。换句话说,我们不能有一个无限大的表,有无限个状态。对于我们有很多可能状态的情况,这可能是个问题。
深度 Q 学习通过将表格转换成深度神经网络来增加 Q 学习的潜力,深度神经网络是参数化函数的强大表示。Q 值根据贝尔曼方程更新:
一般来说,该算法工作如下:
- 游戏开始,Q 值随机初始化。
- 代理收集当前状态 s (观察)。
- 代理基于收集的状态执行动作。动作可以是随机的,也可以由神经网络返回。在训练的第一阶段,系统通常选择随机动作来最大化探索。后来,系统越来越依赖它的神经网络。****
- 当人工智能选择并执行动作时,环境给智能体一个奖励。然后,代理到达新状态state’,并根据上述贝尔曼方程更新其 Q 值。此外,对于每一步棋,它存储原始状态、动作、执行该动作后达到的状态、获得的奖励以及游戏是否结束。该数据稍后被采样以训练神经网络。这个操作被称为重放存储器。
- 这最后两个操作重复进行,直到满足某个条件(例如:游戏结束)。
状态
状态是代理发现自己所处的情况的表示。状态也代表神经网络的输入。在我们的例子中,状态是一个包含 11 个布尔变量的数组。它考虑到:
-如果蛇的接近(右,左,直)有立即的危险。
-蛇是否上下左右移动。
-如果食物在上面、下面、左边或右边。
失败
深度神经网络将输出(行动)优化为特定的输入(状态),试图最大化预期的回报。损失函数给出了表示预测与事实相比有多好的值。神经网络的工作是最小化损失,减少真实目标和预测目标之间的差异。在我们的例子中,损失表示为:
报酬
如前所述,人工智能试图最大化预期回报。在我们的例子中,只有当代理吃了食物目标(+10)时,才会给予它积极的奖励。如果蛇撞到墙或者撞到自己,奖励为负(-10)。此外,我们可以对蛇每走一步而不死给予积极的奖励。在这种情况下,Snake 可能会利用这种情况,跑一圈而不是去够食物,因为它每走一步都会得到积极的回报,同时避免撞到墙上的风险。有时,强化学习代理比我们聪明,在我们的策略中呈现出我们没有预料到的缺陷。
深度神经网络
人工智能代理的大脑使用深度学习。在我们的例子中,它由 120 个神经元的 3 个隐藏层组成。学习率不固定,从 0.0005 开始,递减到 0.000005。不同的架构和不同的超参数有助于更快地收敛到最优,以及可能的最高分数。
网络接收状态作为输入,并返回与三个动作相关的三个值作为输出:向左移动、向右移动、直线移动。最后一层使用 Softmax 函数。
学习模块的实施
该计划最重要的部分是深度 Q 学习迭代。在上一节中,解释了高级步骤。在这里你可以看到它是如何实现的(要查看完整代码,请访问 GitHub 库)。编辑:由于我正在扩展这个项目,Github repo 中的实际实现可能会略有不同。概念与下面的实现相同)。
**while not game.crash:
#agent.epsilon is set to give randomness to actions
agent.epsilon = 80 - counter_games
#get old state
state_old = agent.get_state(game, player1, food1)
#perform random actions based on agent.epsilon, or choose the action
if randint(0, 1) < agent.epsilon:
final_move = to_categorical(randint(0, 2), num_classes=3)
else:
# predict action based on the old state
prediction = agent.model.predict(state_old.reshape((1,11)))
final_move = to_categorical(np.argmax(prediction[0]), num_classes=3)[0]
#perform new move and get new state
player1.do_move(final_move, player1.x, player1.y, game, food1, agent)
state_new = agent.get_state(game, player1, food1)
#set treward for the new state
reward = agent.set_reward(player1, game.crash)
#train short memory base on the new action and state
agent.train_short_memory(state_old, final_move, reward, state_new, game.crash)
# store the new data into a long term memory
agent.remember(state_old, final_move, reward, state_new, game.crash)
record = get_record(game.score, record)**
决赛成绩
在实施结束时,人工智能在 20x20 的游戏棋盘上平均得分为 40 分(每吃一个水果奖励一分)。记录是 83 分。
为了可视化学习过程以及深度强化学习方法的有效性,我绘制了分数和玩游戏的数量。正如我们在下图中看到的,在前 50 场比赛中,人工智能得分很低:平均不到 10 分。这是意料之中的:在这一阶段,代理人经常采取随机行动探索棋盘,并在其记忆中存储许多不同的状态、行动和奖励。在过去的 50 场比赛中,代理不再采取随机的行动,而是根据它的神经网络(它的策略)来选择做什么。
在仅仅 150 场比赛中——不到 5 分钟——代理学会了一个可靠的策略,并获得了 45 分!
结论
这个例子展示了一个简单的代理如何在几分钟内用几行代码学会一个进程的机制,在这个例子中是游戏 Snake。我强烈建议深入研究代码并尝试改进结果。一个有趣的升级可能会在每次迭代时通过当前游戏的截图获得。在这种情况下,状态可以是每个像素的 RGB 信息。深度 Q 学习模型可以用双深度 Q 学习算法来代替,以实现更精确的收敛。
如果您有任何问题或建议,请随时留言,我将非常乐意回答。
要引用这篇文章,请参考这个快速 BibTex 推荐:
****@article**{comi2018,
title = "How to Teach an AI to Play Games using Deep Q-Learning",
author = "Comi, Mauro",
journal = "Towards Data Science",
year = "2018",
url = "https://towardsdatascience.com/how-to-teach-an-ai-toplay-games-deep-reinforcement-learning-28f9b920440a"
}**
如果你喜欢这篇文章,我希望你能点击鼓掌按钮👏这样别人可能会偶然发现它。对于任何意见或建议,不要犹豫留下评论!
我是一名研究工程师,热爱机器学习及其无尽的应用。你可以在 maurocomi.com找到更多关于我和我的项目的信息。你也可以在 Linkedin ,在 Twitter 上找到我,或者直接给我发邮件。我总是乐于聊天,或者合作新的令人敬畏的项目。
如果你对这篇文章感兴趣,你可能会喜欢我的其他文章:
- 人工智能遇上艺术:神经传递风格
- 人工智能是种族歧视吗?(及其他关注)
- 计算机图形学中人工智能的 3 大挑战
如何讲故事,用数据编织有凝聚力的叙事
原文:https://towardsdatascience.com/how-to-tell-stories-and-weave-a-cohesive-narrative-with-data-532f33ba60cf?source=collection_archive---------2-----------------------
讲故事是人类最重要的进化优势之一。这是一个大胆的说法,但我相信这是真的。
当古代人围坐在村庄的篝火旁讲故事时,他们正在教其他村民去哪里寻找食物,如何成功捕获猎物,什么草药可以治愈疾病,哪些动物应该避开(以及如何避开!)等必备的生存技能。
这些信息没有在村里的时事通讯或洞壁上的安全海报中分享(嗯…我猜它们有点像早期的海报…但你知道我的意思)。这些课程主要以故事的形式出现。
所以几万年来,这是人类相互学习最重要的东西的方式,因此,这也是我们期望相互学习的方式。
数字让人害怕
每个人都知道如何讲故事。我们都到处编故事。我们知道如何讲笑话,制造悬念,围绕一个奇怪的假期轶事或关于我们孩子的芭蕾课讲一个流畅的故事。
然而,出于某种原因,一旦大多数人不得不交流数字,他们吓坏了。“我讨厌数学!我不知道数字!我有数据要分享…我该怎么办?!?我知道,我会把所有的数字放在一张幻灯片上,然后期待最好的结果。其他人都会想通的……”
这感觉熟悉吗?你并不孤单。在我们的文化中,我们有一种严重的数字恐惧症,这种恐惧症让许多人——尤其是专业沟通者——神经紧张。
但是正如认知行为疗法可以通过直面恐惧来帮助解决各种恐惧症的问题一样,我相信每个人都可以学会以类似的方式交流数据——通过这样做。仅仅是尝试和练习的行为,就能使任何沟通者成为数据沟通者。
最重要的策略之一是从讲故事的角度来看待数据通信。不仅因为讲故事是如此强大,是在许多主题上与许多观众联系的最佳方式,而且因为我们都知道如何做,所以它有助于将令人生畏的数字转化为故事的简单成分。
用数字编织一个故事
将数字转化为叙事的最重要的步骤之一是,像你讲述其他故事一样,概述或讲述你的故事,忽略数据本身,专注于论点的流动。例如,假设你有公司的销售数据,你需要为你的 CEO 做一份报告。你是做什么的?
首先,你要弄清楚 KWYRWTS——我的首字母缩略词,这是有史以来最糟糕的首字母缩略词,但它代表了一个非常重要的思想:知道你真正想说什么。
假设你这个季度的销售数字大幅下降。但你知道主要原因是因为围绕英国退出欧盟公投的争论和随后的通过,你的欧洲办公室的销售额大幅下降。显然这将是你故事的焦点。那是你的 KWYRWTS。也许有两个要点,或者三个要点,但是你必须知道它们到底是什么!
所以你创建一个故事板,并像这样决定叙事流程:
这五个“面板”故事建立了一个流程和逻辑,你可以很容易地围绕它编织一个故事。你知道你以“销售额下降”开始,这可能包括公司销售的概述。你正在建立一些预期,激活你的 CEO 的情绪(希望不是针对你的愤怒——也许他有些焦虑!).
然后,你会通过显示地区数字,暗示一些好消息,将故事转移到缓解焦虑上?或者至少一些可能有助于支持解决方案的信息。接下来,你得到你对问题的假设,这是从地区故事的逻辑构建。然后你进入预测未来阶段,关注近期(下个季度)和长期(明年),这让你以一个快乐的音符结束——对你的数据故事来说,这是一个好莱坞式的结局!
只有当你对自己的故事非常有信心时,你才会担心获得实际的数据,并考虑要展示什么图表,以及如何展示。换句话说,我需要理解数据的要点,以知道要讲什么故事,但我不需要一点实际数据来概述一个令人信服的故事,解释需要解释的内容,并以最大化我对首席执行官的影响的方式呈现信息。
这是一个非常简单的过程,根据大量的内容简单地勾勒出一个基本的线性故事,这是从一堆数字中挤出一个故事的非常有效和非常简单的方法。
对了,隐藏在这里面的,是我观众非常清晰的认识。我知道我虚构的 CEO 不会因为一点坏消息就大发雷霆——我肯定她已经知道了。我也知道她很好奇销售额下降的原因,以及我们是否能对未来做出任何预测。
因此,我将这个故事编织成一种方式,可以很快找到原因,然后进行预测。我也知道她希望坦诚,所以清楚地知道下一季度可能没那么好是很重要的,同时也在最后提供一缕阳光。
如果是另一位老板,我可能会以不同的方式讲述这个故事:
只是不要害怕
你已经知道如何讲故事了。知道你想说什么,尽可能在你的叙述中注入情感、悬念和兴趣,概述你的故事流程,忽略数据直到过程的最后,然后才担心具体包括什么以及如何可视化你的数据。最好的建议?你在用数字讲故事。不要害怕。你在讲一个故事…用数字——它们只是成分!
要了解更多关于数据叙事的信息,只需在 Udemy 上查看课程即可(使用此链接可节省 50%的费用)。
本帖 原版 最早出现在 Visme 的 视觉学习中心 。
如何像数据科学家一样思考组合学
原文:https://towardsdatascience.com/how-to-think-about-combinatorics-like-a-data-scientist-bddbd18eff80?source=collection_archive---------2-----------------------
牢固掌握这些基本概念,以改善您的决策过程并推动您的公司向前发展。
我们最近讨论了决策树、 博弈论和客户角色。对于每个主题,我们都使用了具有少量案例的示例,这样我们就可以向您展示一些有趣但大小可控的内容。上周,我们讨论了如何使用集群来减少您试图解决的问题的规模。本周,我们将更进一步,讨论如何计算你必须开始的案例数。
为此,我们将讨论组合学的数学领域,特别是排列和组合。排列计算结果的数量,而你计算的顺序很重要。另一方面,组合计算结果的数量,而你计算的顺序并不重要。排列和组合都被进一步细分,以考虑您正在选择的选项是否允许重复,即在每次选择后在可用选项集中替换,或者不允许(您将看到这个概念被称为“重复”和“替换”——本周我将使用“替换”)。本周我们将讨论每个场景:
- 置换置换
- 没有替换的排列
- 没有替换的组合
- 替换组合
开始数数吧!
离群值 监控您的业务数据,并在发生意外变化时通知您。我们帮助营销/发展&产品团队从他们的业务数据中获取更多价值。
今天安排一次演示。
- Outlier 是 Strata+Hadoop World 2017 观众奖得主。
置换置换
回到我们讨论博弈论的时候,我们讨论的一个场景是,你的公司(例如,道格的甜点)需要决定是提高价格、降低价格还是保持价格不变。假设你有另外 3 个竞争者(让我们称他们为 A、B 和 C ),他们和你卖同样的产品,他们面临同样的三个决定。此外,根据您过去的经验,您知道您的公司是该领域的领导者,然后其他公司总是以相同的顺序对您的定价决策做出反应,A,B,c。
排列计算结果的数量,而你计算的顺序很重要。另一方面,组合计算结果的数量,而你计算的顺序并不重要。
那么会发生多少种不同的情况呢?我们当然可以用手数出来…
…但随着选项数量的增加,这变得越来越难。这个问题是置换排列的一个例子。让我们从头开始思考结果的数量。道格的甜点首先在 3 个选项中做出选择,然后 A 公司在同样的 3 个选项中做出选择。换句话说,对于道格的甜点可以选择的 3 个选项中的每一个,公司 A 可以选择相同的 3 个选项中的任何一个,这意味着有 3 * 3 = 9 种可能的结果。接下来,B 公司在同样的 3 个选项中做出选择。换句话说,对于我们为道格的甜点和 A 公司计算的 9 个结果中的每一个,B 公司可以选择 3 个选项,这意味着有 9 * 3 = 27 个结果。最后,C 公司在同样的 3 个选项中做出选择。换句话说,对于我们为道格甜点计算的 27 个结果中的每一个,公司 A、公司 B、公司 C 可以选择 3 个选项,这意味着有 27 * 3 = 81 个结果。
你现在可以看到这个模式了——每次做出一个新的选择,我们都要把之前的结果乘以选项的数量。让我们将 n 表示为选项的数量,在本例中 n = 3,k 表示做出选择的次数,在本例中 k = 4。然后,我们可以概括置换的概念:当有 n 个选项被选择 k 次,每次替换选项,有 n^k 不同的结果。在这个例子中,这意味着,3⁴ = 3 * 3 * 3 * 3 = 81。
接下来,我将讨论不允许替换选项的排列场景。
没有替换的排列
这就是当在过程的每一步都有相同的选项时,如何计算排列的方法。现在我来讲讲每个选择只允许做一次的情况下,如何统计结果。
假设你准备推出一款新产品,并试图找出向公众发布的最佳策略。你已经确定了四种不同的营销策略,并正在考虑实施:
- 发送新闻稿并安排新闻媒体的采访
- 开展在线营销活动
- 开展电视/广播营销活动
- 在行业会议上发起并发言
根据您的营销经验,您认为采取这些措施的顺序很重要。换句话说,你认为在发起行业会议并在会议上发言之前进行在线营销活动的结果会与在线营销活动之前举行会议的结果不同。
那么你要考虑多少种不同的结果呢?这是一个没有替换的排列的例子。有四种不同的策略可以考虑,我们将它们表示为 n。当考虑先做什么时,您有四种选择。当考虑下一步做什么时,你只剩下三个选择(因为我们不会做两次同样的营销策略)。当你选择第三步做什么的时候,你还有两个策略。最后,最后做的策略是由你之前的选择决定的,因为只剩下一个选项了。综上所述,你有 4 * 3 * 2 * 1 = 24 种不同的结果需要考虑。
我们刚刚做的整数乘积的计算发生得如此频繁,以至于它有自己特殊的名字和数学符号。它被称为阶乘,用“!”表示在一个数字之后。它的简写意思是,取每个小于或等于该数的整数的乘积。比如 4!= 4 * 3 * 2 * 1 = 24,正是我们上面计算的结果。更一般地说,如果我们要采取所有 n 个营销策略,那么我们必须考虑 n 个!不同的结果。
但是,如果你因为没有时间或预算而无法完成所有的营销策略,该怎么办呢?而是只能选择 4 个选项中的 2 个。让我们把你要做的选择数记为 k,在这个例子中 k = 2。你可以从第一步的 4 个策略和第二步的 3 个策略中选择,但是你就此打住。所以你有 4 * 3 = 12 个结果要考虑。请注意,这个结果与之前的唯一不同之处是 2 * 1 不再出现在公式中。我们可以将公式改写为 4 * 3 * 2 * 1 / 2 * 1 = 4 * 3 = 12(很快就会明白为什么了)。换句话说,我们总共有 n 个!结果,但需要将该值减去我们能够做出的选择数,即(n — k)!
把这两个例子,我们可以写一个,一般公式如何计算置换:n!/ (n — k)!,通常表示为 P(n,k)。在我们讲的第一个例子中,有 4 个选项(n = 4)和 4 个选择(k = 4),所以 4!/ (4–4)!= 4!/ 0!= 24 [1].在第二个例子中,有 4 个选项(n = 4)和 2 个选择(k = 2),所以 4!/ (4–2)!= 4!/ 2!= 12.
既然我们已经知道了如何在顺序很重要的情况下计数,明天,我将讨论顺序无关紧要的组合。
没有替换的组合
当你想到密码时,首先想到的可能是“密码锁”。不幸的是,这实际上是一个非常糟糕的组合的例子!正如我们在过去的几天里谈到的,在排列中,顺序很重要,但在组合中,顺序并不重要。正如你所知道的,你在密码锁中输入数字的顺序非常重要,所以如果我们想要更准确(至少从数学家的角度来看),我们应该将“密码锁”重命名为“排列锁”!
让我们重新考虑一下昨天的例子,您有四个不同的营销活动策略,您正在考虑即将到来的产品发布。在排列的情况下,这些决定的顺序很重要。但是今天,让我们假设你要进行一次大的营销宣传,同时实施所有这些策略。那有多少种不同的结果?简单,一——你同时做所有的事情!
现在让我们假设你想大出风头,但没有预算或时间同时实施这四个策略。相反,你只能做两个。考虑没有替换的组合的最简单的方法是首先计算没有替换的排列的数量,然后用选项可以排序的方式的数量来减少该值。昨天我们计算出,当我有四个选项和两个选择时,有 12 种不同的没有替换的排列。那么,有多少种方法可以让我们做出两种选择,并进行替换呢?我们从昨天就已经知道答案了,是 P(2,2) = 2!/ (2–2)!= 2!= 2 * 1 / 1 = 2.这意味着没有替换的组合数是 12 / 2 = 6。
我们可以把所有这些放在一起形成一个通用的形式,再次表示 n 为选项的数量,k 为选择的数量。我们将今天的结果计算为 P(n,k) / P(k,k)。因为 P(k,k)和 k 是一样的!,我们可以把这个写成 P(n,k) / k!= n!/ (n — k)!* k!,通常表示为 C(n,k)。在我们今天讲的第一个例子中,有 4 个选项(n = 4)和 4 个选择(k = 4),所以 4!/ (4–4)!* 4!= 4!/ 0!* 4!= 1.在第二个例子中,有 4 个选项(n = 4)和 2 个选择(k = 4),所以 4!/ (4–2)!* 2!= 4!/ 2!* 2!= 6.
接下来,我将通过讨论替换组合来结束我们关于组合学的讨论。
替换组合
我们要讨论的最后一种组合是替换组合。这类计数问题的一个例子是在商店购买产品。举个例子,你站在我假设的面包店 Doug 's Desserts 的柜台前,想买四个甜甜圈(即你做出选择的数量,这里 k = 4)。我的面包店出售三种甜甜圈:香草霜甜甜圈、糖衣甜甜圈和果冻馅甜甜圈(即你拥有的选择数量,其中 n = 3)。现在的问题是,考虑到你可以随心所欲地购买每种甜甜圈,你有多少种方法可以从三种选择中购买四种甜甜圈?
类似的逻辑也适用于我在讨论置换时讨论的例子——四家公司各自选择三种产品价格处理方案。在排列的背景下,我们假设选择的顺序很重要。不过,对于组合来说,让我们假设顺序无关紧要。现在的问题是,假设这四家公司都在同一时间定价,他们有多少种不同的定价方式?
在这两个例子中,有 n = 3 个选项可供选择,并且做出 k = 4 次决策,其中每次做出决策时所有选项都可用。
让我们用甜甜圈的例子来思考如何解决这个问题,因为它更容易形象化。想象你在面包店,每种类型的甜甜圈都在自己的托盘上。因此,一个托盘上有一打香草冰淇淋(在表格中用“O”表示),旁边的托盘上有一打果冻,还有一打糖浆放在自己的托盘上。
你喜欢香草霜,也确实喜欢果冻馅的,但是不喜欢蜜饯的,所以你的方案是选一个香草霜,三个果冻馅的。您可以想象购买过程如下。
首先,你站在香草霜甜甜圈托盘前(你看到的托盘是蓝色的)…
然后要一个甜甜圈放在你的包里。然后你移到下一盘甜甜圈,浇上糖浆。
既然你不想要这些甜甜圈,就不要从托盘里拿走。你移动到最后一盘油炸圈饼,果冻填充…
三次要一个甜甜圈。
如果一个旁观者记录了你购买甜甜圈的步骤,它应该是这样的:(1)甜甜圈(2)移到下一个托盘(3)移到下一个托盘(4)甜甜圈(5)甜甜圈(6)甜甜圈。实际选择的甜甜圈并不重要,因为这是一个组合,选择的顺序并不重要。
以这种方式来看购买,无论你选择哪种甜甜圈,你总是会有 4(即,k)“甜甜圈”步骤和 2(即,n-1)“移动到下一个托盘”步骤。这就像说,我们有 k + (n -1),在我们的例子中是 6,选择甜甜圈或移动到下一个托盘的不同选项,我们想选择 k,在我们的例子中是 4,甜甜圈。换句话说,这与没有替换的组合是一样的,但是对我们昨天讨论的公式的输入稍作修改!结果总数为 C(k + (n — 1),k) = (k + (n — 1))!/ (k + (n — 1) — k)!* k!=(k+(n-1))!/ (n — 1)!* k!。从示例中插入我们的值,有 6 个!/ 2!* 4!=你如何选择甜甜圈的 15 个结果(或者公司可以做出定价决定)。
好了,这就是排列和组合。我希望你已经享受了这一周的计算结果,你可能会面临你的业务!
离群值 监控您的业务数据,并在发生意外变化时通知您。我们帮助营销/发展&产品团队从他们的业务数据中获取更多价值。 今天安排试玩。
- Outlier 是 Strata+Hadoop World 2017 观众奖得主。
这是 30 秒后的异常值。
[1] 0!= 1,按照惯例。
[2]一打油炸圈饼并不重要,只要每个托盘上至少有四个——因为这是你要做的选择,我们假设每个选择都有所有选项——逻辑是一样的。
如何在 5 分钟内训练一个机器学习模型
原文:https://towardsdatascience.com/how-to-train-a-machine-learning-model-in-5-minutes-c599fa20e7d5?source=collection_archive---------3-----------------------
关于 Mateverse :我们在 Mate Labs 已经建立了 Mateverse,使每个人都能够建立和训练机器学习模型,而无需编写一行代码。在 Mateverse 上培训模型只需 5 个步骤。如果你想要的只是一个智能解决方案,甚至不需要学习编码技能,更不用说机器学习的概念了。
看看它是如何工作的:
1。 模型命名 —给你的模型起个名字:先给你的模型起个名字,描述你的模型,给你的模型贴上标签。标签是为了让你的模型可以被搜索。
Step 1— Naming your model
2。 数据类型选择 —选择数据类型(Images/Text/CSV):是时候告诉我们你想要训练你的模型的数据类型了。我们支持图片、文字和*。CSV(分类数据)数据类型。选择适当的数据类型,然后单击“下一步”继续下一步。我们还公开了一些数据集,供大家开始使用。 公开数据集 是为了让你知道在 Mateverse 上训练你的模型需要什么类型的数据。
Step 2— Data Type Selection
3。 数据上传 —上传您的数据或从公共数据集中选择:从公共数据集中选择,如珠宝数据集(图像)、性别数据集(图像)、问题或句子数据集(文本)、数字数据集(CSV)或上传您的数据。上传您的数据是一个简单的过程,只需选择您的文件并键入所选文件的标签。
我们举一个图像数据集的例子。图像可以直接上传,也可以压缩成压缩文件上传(不同的标签/类别有不同的压缩文件)。属于一个唯一类别的所有图像都应该在这个压缩文件中。
附:建议:不要压缩文件夹,压缩文件夹的话就不行了。选择文件并直接压缩。
Sample compressed file with images — This is how your compressed file’s data should look like
文本—同样,您可以上传文本(*。txt)文件。下面是一个示例文本文件。每个独特的句子应该是文本文件中的不同行。
Sample Text(.txt) file
CSV——如果你想训练一个模型,不管是分类还是回归(预测),只需上传一个 csv 文件就可以了。一旦你上传了文件,你必须做两件事:
a) 按下“跳过”按钮,跳过您发现对训练所需模型来说多余/不重要的列。
b)在模型训练完成后,选择一个要进行预测的列。
您甚至可以更改列名以供参考。
CSV fIle Upload Preview
附注:尽量避免在文本和 CSV 文件中使用不支持的字符。
4。 为您上传的文件(图像/文本文件)键入类别(标签),点击提交开始上传。等待一段时间,直到我们的 web 应用程序上传所有文件。您可以上传尽可能多类别的图像。您需要至少 2 个标签(类别)来对图像/文本进行分类。我们支持带“*”的文本文件。txt "扩展名。
5。 开始训练:按下按钮,开始训练。现在,Mateverse 的智能后端将开始处理你上传的数据,并为训练做准备。与此同时,它还将开始选择最佳的机器学习/深度学习算法,以最高的精度训练最佳模型。
Step 4: Push the Button to Start Training
6。 开始测试:你的模型训练好了,可以开始测试你刚训练好的模型了。您可以通过 UI 使用它,或者通过 API 集成它(参考文档)。
关于我们的更多信息
在让 Mateverse 成为一个更好的平台方面,我们已经走了很长的路。借助 Mateverse V1.0,我们利用专有技术、复杂管道、大数据支持、自动化数据预处理(使用 ML 模型的缺失值插补、异常值检测和格式化)、自动化超参数优化以及更多功能,让分析师和数据科学家的工作变得更加轻松。
如果你也想在 5 分钟内训练出一个 ML 模型,请在这里填写 。
为了帮助您的企业采用机器学习,而不会浪费您的团队在数据清理和创建有效数据模型方面的时间,您也可以通过电子邮件与我们联系,我们将与您联系。
让我们携起手来。
告诉我们你第一次在 Mateverse 中训练模型的经历。而且我们会分享给所有我们认识的对 AI 和机器学习着迷的人。共建共享。查看 LinkedIn ,了解更多。
如果你有新的建议,请告诉我们。我们的耳朵和眼睛总是为真正令人兴奋的事情而张开。
之前我们分享过。
- 公共数据集:用这些在 Mateverse 上训练机器学习模型。
- Mateverse 公测公告。
- 为什么我们需要机器学习的民主化?
- 一个非常清晰的解释全有线电视新闻网的实施。这些研究人员如何尝试一些非常规的东西,以实现更小但更好的图像识别。
- 我们的愿景。关于人工智能大家都没告诉你的事情
如何训练一个 Tensorflow 人脸对象检测模型
原文:https://towardsdatascience.com/how-to-train-a-tensorflow-face-object-detection-model-3599dcd0c26f?source=collection_archive---------2-----------------------
人工智能使得分析图像成为可能。在这篇博文中,我将着重于用定制的类来训练一个对象检测器。你要做的第一件事是设置。在 Tensorflow 文档中写了如何在本地机器上设置。我们将使用 Tensorflow 对象检测来训练实时对象识别应用程序。训练好的模型在这个库中可用
这是一个翻译的'Train een tensor flow gezi cht object detectie model和Objectherkenning meet de 计算机视觉库 Tensorflow
MS COCO Tensorflow Nürburgring example (own picture)
OpenCV
你可以在 Ubuntu 上的 /usr/local 中自动安装 OpenCV。用下面的脚本。该脚本安装 OpenCV 3.2 并与 Ubuntu 16.04 一起工作。
$ curl -L [https://raw.githubusercontent.com/qdraw/tensorflow-object-detection-tutorial/master/install.opencv.ubuntu.sh](https://raw.githubusercontent.com/qdraw/tensorflow-object-detection-tutorial/master/install.opencv.ubuntu.sh) | bash
在我的 Mac 上,我使用 OpenCV 3.3.0 en Python 2.7.13。我在 OpenCV 3.2 和 3.3 中试过,但是在 Python 3.6 中失败了。然而,在 Ubuntu Linux 上,这种组合确实有效。
$ brew install homebrew/science/opencv
“超薄”和对象检测模块的设置
第一步是克隆 Tensorflow-models 存储库。在本教程中,我们只使用了 slim 和 object_detection 模块。
$ nano .profileexport PYTHONPATH=$PYTHONPATH:/home/dion/models/research:/home/dion/models/research/slim
您还需要编译 protobuf 库
$ protoc object_detection/protos/*.proto --python_out=.
克隆教程存储库并安装依赖项
示例代码可在tensor flow-face-object-detector-tutorial资源库中找到。你可以克隆这个回购。
$ git clone [https://github.com/qdraw/tensorflow-face-object-detector-tutorial.git](https://github.com/qdraw/tensorflow-face-object-detector-tutorial.git)
转到子文件夹:
$ cd tensorflow-face-object-detector-tutorial/
使用 PIP 安装依赖项:我使用 Python 3.6,OpenCV 使用 Python 绑定安装。
$ pip install -r requirements.txt
下载培训和验证数据
香港中文大学有一个庞大的标签图像数据集。较宽的人脸数据集是人脸检测基准数据集。我已经使用了标签来显示边界框。所选文本是面标注。
WIDER example using labelImg (credits: http://mmlab.ie.cuhk.edu.hk/projects/WIDERFace/))
脚本 001_down_data.py 将用于下载 WIDERFace 和SSD _ mobilenet _ v1 _ coco _ 11 _ 06 _ 2017。我将使用预训练模型来加快训练时间。
$ python 001_down_data.py
将 WIDERFace 转换为 Pascal XML
首先,我们需要将数据集转换成 Pascal XML。Tensorflow 和 labelImg 使用不同的格式。图像被下载到 WIDER_train 文件夹中。使用002 _ data-to-Pascal-XML . py我们转换宽面数据并将其复制到不同的子文件夹。我的电脑处理 9263 张图片需要 5 分钟。
$ python 002_data-to-pascal-xml.py
From the dataset WIDERFace and the film Marching Band (2009) with XML and LabelImg interface.
Pascal XML 到 Tensorflow CSV 索引
当数据被转换成 Pascal XML 时,就会创建一个索引。通过训练和验证数据集,我们使用这些文件作为输入来生成 TFRecords。但是,也可以使用 labelImg 之类的工具手动标记图像,并使用此步骤在此创建索引。
$ python 003_xml-to-csv.py
Excel and OS X Finder with list of files
创建 TFRecord 文件
TFRecords 文件是一个很大的二进制文件,可以读取它来训练机器学习模型。在下一步中,Tensorflow 将顺序读取该文件。训练和验证数据将被转换为二进制文件。
训练数据到 TFRecord (847.6 MB)
$ python 004_generate_tfrecord.py --images_path=data/tf_wider_train/images --csv_input=data/tf_wider_train/train.csv --output_path=data/train.record
验证数据到 TFRecord (213.1MB)
$ python 004_generate_tfrecord.py --images_path=data/tf_wider_val/images --csv_input=data/tf_wider_val/val.csv --output_path=data/val.record
设置配置文件
在储存库中,SSD _ mobilenet _ v1 _ face . config是用于训练人工神经网络的配置文件。这个文件基于一个 pet 探测器。
在这种情况下, num_classes 的数量保持为 1,因为只有面部会被识别。
变量 fine_tune_checkpoint 用于指示获取学习的前一模型的路径。这个位置将适合你在这个文件。微调检查点文件用于应用迁移学习。迁移学习是机器学习中的一种方法,专注于将从一个问题获得的知识应用到另一个问题。
在类 train_input_reader 中,与用于训练模型的 TFRecord 文件建立链接。在配置文件中,您需要将其定制到正确的位置。
变量 label_map_path 包含索引 id 和名称。在这个文件中,零被用作占位符,所以我们从 1 开始。
item {
id: 1
name: 'face'
}
对于验证,两个变量很重要。类 eval_config 中的变量 num_examples 用于设置示例的数量。
T5eval _ input _ reader类描述了验证数据的位置。这个位置也有一条小路。
此外,还可以更改学习率、批量和其他设置。目前,我保留了默认设置。
让我们训练;)
现在要开始真正的工作了。计算机将从数据集中学习,并在这里建立一个神经网络。由于我在 CPU 上模拟火车,这将需要几天才能得到一个好的结果。有了强大的 Nvidia 显卡,这是有可能缩短到几个小时。
$ python ~/tensorflow_models/object_detection/train.py --logtostderr --pipeline_config_path=ssd_mobilenet_v1_face.config --train_dir=model_output
Tensorboard 让我们深入了解学习过程。该工具是 Tensorflow 的一部分,是自动安装的。
$ tensorboard --logdir= model_output
Tensorflow Tensorboard TotalLoss
将检查点转换为 protobuf
通过计算机视觉库 Tensorflow 在对象识别中使用该模型。下面的命令提供了模型库和最后一个检查点的位置。文件夹 folder 将包含 freezed _ inference _ graph . Pb。
$ python ~/tensorflow_models/object_detection/export_inference_graph.py \
--input_type image_tensor \
--pipeline_config_path ssd_mobilenet_v1_face.config \
--trained_checkpoint_prefix model_output/model.ckpt-12262 \
--output_directory model/
TL;DR;
中的模型/冻结 _ 推理 _ 图形。github 知识库上的 pb 文件夹是一个人工神经网络的冻结模型。香港中文大学拥有广泛的研究面,该数据集已被用于训练模型。
估价
除了用于训练的数据之外,还有一个评估数据集。基于该评估数据集,可以计算准确度。对于我的模型,我计算了精度(平均精度)。我在 14337 步(epochs)时得到了 83.80%的分数。对于这个过程,Tensorflow 有一个脚本,可以在 Tensorboard 中看到分数。除了培训之外,建议您运行评估流程。
python ~/tensorflow_models/object_detection/eval.py --logtostderr --pipeline_config_path=ssd_mobilenet_v1_face.config --checkpoint_dir=model_output --eval_dir=eval
然后你可以用 Tensorboard 监控这个过程。
tensorboard --logdir=eval --port=6010
冻结模型的结论和使用
训练人脸识别模型已经成为可能。冻结模型model/frozen _ inference _ graph . Pb可以部署在例如具有计算机视觉库 Tensorflow 的对象识别中。
计算机视觉的世界应该让你感兴趣,但是你仍然不知道如何应用它,并且有必要的问题吗?给我发一封电子邮件,然后我们可以一起喝杯咖啡。
Me and a cup of coffee
In this example, 43 faces are recognized. Source image: Ricardo Lago https://www.flickr.com/photos/kruzul/4763629720/
如何在 PyTorch 中训练一个图像分类器,并使用它对单幅图像进行基本推理
原文:https://towardsdatascience.com/how-to-train-an-image-classifier-in-pytorch-and-use-it-to-perform-basic-inference-on-single-images-99465a1e9bf5?source=collection_archive---------2-----------------------
使用自己的图像训练 ResNet 的教程
如果你刚刚开始使用 PyTorch,并且想学习如何做一些基本的图像分类,你可以遵循这个教程。它将介绍如何组织您的训练数据,使用预训练的神经网络来训练您的模型,然后预测其他图像。
为此,我将使用一个由 Google Maps 地图切片组成的数据集,并根据它们包含的地形特征对它们进行分类。我将写另一个关于我如何使用它的故事(简而言之:为了识别无人机飞越或着陆的安全区域)。但是现在,我只想使用一些训练数据来对这些地图分块进行分类。
下面的代码片段来自 Jupyter 笔记本。你可以将它们组合在一起构建你自己的 Python 脚本,或者从 GitHub 下载笔记本。这些笔记本最初是基于 Udacity 的 PyTorch 课程。如果你使用云虚拟机进行深度学习开发,并且不知道如何远程打开笔记本,请查看我的教程。
组织你的训练数据集
PyTorch 希望数据按文件夹组织,每个类一个文件夹。大多数其他 PyTorch 教程和示例希望您进一步组织它,在顶部有一个 training and validation 文件夹,然后在其中有 class 文件夹。但我认为这非常麻烦,必须从每个类中挑选一定数量的图像,并将它们从训练文件夹移动到验证文件夹。因为大多数人会选择一组连续的文件,所以在选择时可能会有很多偏差。
因此,有一种更好的方法可以将数据集动态拆分为训练集和测试集,就像 Python 开发人员习惯的 SKLearn 一样。但是首先,让我们导入模块:
%matplotlib inline
%config InlineBackend.figure_format = 'retina'
import matplotlib.pyplot as pltimport numpy as np
import torch
from torch import nn
from torch import optim
import torch.nn.functional as F
from torchvision import datasets, transforms, models
接下来,我们将定义训练/验证数据集加载器,使用 SubsetRandomSampler 进行拆分:
data_dir = '/data/train'def load_split_train_test(datadir, valid_size = .2):
train_transforms = transforms.Compose([transforms.Resize(224),
transforms.ToTensor(),
]) test_transforms = transforms.Compose([transforms.Resize(224),
transforms.ToTensor(),
]) train_data = datasets.ImageFolder(datadir,
transform=train_transforms)
test_data = datasets.ImageFolder(datadir,
transform=test_transforms) num_train = len(train_data)
indices = list(range(num_train))
split = int(np.floor(valid_size * num_train))
np.random.shuffle(indices)
from torch.utils.data.sampler import SubsetRandomSampler
train_idx, test_idx = indices[split:], indices[:split]
train_sampler = SubsetRandomSampler(train_idx)
test_sampler = SubsetRandomSampler(test_idx)
trainloader = torch.utils.data.DataLoader(train_data,
sampler=train_sampler, batch_size=64)
testloader = torch.utils.data.DataLoader(test_data,
sampler=test_sampler, batch_size=64)
return trainloader, testloadertrainloader, testloader = load_split_train_test(data_dir, .2)
print(trainloader.dataset.classes)
接下来我们来确定我们有没有 GPU。我假设如果你这样做,你有一个 GPU 驱动的机器,否则代码将至少慢 10 倍。但是概括和检查 GPU 的可用性是一个好主意。
我们还将加载一个预训练模型。对于这个例子,我选择了 ResNet 50:
device = torch.device("cuda" if torch.cuda.is_available()
else "cpu")
model = models.resnet50(pretrained=True)
print(model)
打印模型将向您展示 ResNet 模型的层架构。这可能超出了你我的理解范围,但看看这些深藏的层里面是什么仍然很有趣。
选择哪种模型取决于您,并且可能会根据您的特定数据集而有所不同。这里列出了所有的 PyTorch 型号 。
现在我们进入了深层神经网络的有趣部分。首先,我们必须冻结预训练的层,这样我们就不会在训练过程中反向穿透它们。然后,我们重新定义最终的完全连接的层,我们将使用我们的图像进行训练。我们还创建了标准(损失函数)并选择了优化器(在这种情况下是 Adam)和学习率。
for param in model.parameters():
param.requires_grad = False
model.fc = nn.Sequential(nn.Linear(2048, 512),
nn.ReLU(),
nn.Dropout(0.2),
nn.Linear(512, 10),
nn.LogSoftmax(dim=1))
criterion = nn.NLLLoss()
optimizer = optim.Adam(model.fc.parameters(), lr=0.003)
model.to(device)
现在最后,让我们训练我们的模型!在这个例子中只有一个纪元,但是在大多数情况下你需要更多。从代码来看,基本过程非常直观:加载成批图像并进行前馈循环。然后计算损失函数,并使用优化器在反向传播中应用梯度下降。
PyTorch 就是这么简单。下面的大部分代码用于显示每 10 个批次的损失和计算准确度,因此您可以在训练过程中获得更新。在验证过程中,不要忘记将模型设置为 eval()模式,完成后再返回到 train()。
epochs = 1
steps = 0
running_loss = 0
print_every = 10
train_losses, test_losses = [], []for epoch in range(epochs):
for inputs, labels in trainloader:
steps += 1
inputs, labels = inputs.to(device), labels.to(device)
optimizer.zero_grad()
logps = model.forward(inputs)
loss = criterion(logps, labels)
loss.backward()
optimizer.step()
running_loss += loss.item()
if steps % print_every == 0:
test_loss = 0
accuracy = 0
model.eval()
with torch.no_grad():
for inputs, labels in testloader:
inputs, labels = inputs.to(device),
labels.to(device)
logps = model.forward(inputs)
batch_loss = criterion(logps, labels)
test_loss += batch_loss.item()
ps = torch.exp(logps)
top_p, top_class = ps.topk(1, dim=1)
equals =
top_class == labels.view(*top_class.shape)
accuracy +=
torch.mean(equals.type(torch.FloatTensor)).item()
train_losses.append(running_loss/len(trainloader))
test_losses.append(test_loss/len(testloader))
print(f"Epoch {epoch+1}/{epochs}.. "
f"Train loss: {running_loss/print_every:.3f}.. "
f"Test loss: {test_loss/len(testloader):.3f}.. "
f"Test accuracy: {accuracy/len(testloader):.3f}")
running_loss = 0
model.train()
torch.save(model, 'aerialmodel.pth')
然后…在您等待几分钟(或更长时间,取决于数据集的大小和历元数)后,训练完成,模型被保存以供以后的预测使用!
现在还有一件事你可以做,那就是绘制训练和验证损失图:
plt.plot(train_losses, label='Training loss')
plt.plot(test_losses, label='Validation loss')
plt.legend(frameon=False)
plt.show()
如您所见,在我的一个时期的特定示例中,验证损失(这是我们感兴趣的)在第一个时期结束时趋于平缓,甚至开始上升趋势,因此 1 个时期可能就足够了。培训损失,正如预期的那样,非常低。
现在进入第二部分。因此,您训练了您的模型,保存了它,并需要在应用程序中使用它。为此,您需要能够对图像进行简单的推断。您也可以在我们的资源库中找到这款演示笔记本。我们导入与培训笔记本中相同的模块,然后再次定义转换。我只再次声明图像文件夹,这样我就可以使用其中的一些示例:
data_dir = '/datadrive/FastAI/data/aerial_photos/train'test_transforms = transforms.Compose([transforms.Resize(224),
transforms.ToTensor(),
])
然后,我们再次检查 GPU 可用性,加载模型并将其置于评估模式(因此参数不会改变):
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
model=torch.load('aerialmodel.pth')
model.eval()
预测特定图像的类别的函数非常简单。注意,它需要一个枕头图像,而不是一个文件路径。
def predict_image(image):
image_tensor = test_transforms(image).float()
image_tensor = image_tensor.unsqueeze_(0)
input = Variable(image_tensor)
input = input.to(device)
output = model(input)
index = output.data.cpu().numpy().argmax()
return index
现在为了更容易测试,我还创建了一个函数,它将从数据集文件夹中随机选取一些图像:
def get_random_images(num):
data = datasets.ImageFolder(data_dir, transform=test_transforms)
classes = data.classes
indices = list(range(len(data)))
np.random.shuffle(indices)
idx = indices[:num]
from torch.utils.data.sampler import SubsetRandomSampler
sampler = SubsetRandomSampler(idx)
loader = torch.utils.data.DataLoader(data,
sampler=sampler, batch_size=num)
dataiter = iter(loader)
images, labels = dataiter.next()
return images, labels
最后,为了演示预测功能,我获取随机图像样本,预测它们并显示结果:
to_pil = transforms.ToPILImage()
images, labels = get_random_images(5)
fig=plt.figure(figsize=(10,10))
for ii in range(len(images)):
image = to_pil(images[ii])
index = predict_image(image)
sub = fig.add_subplot(1, len(images), ii+1)
res = int(labels[ii]) == index
sub.set_title(str(classes[index]) + ":" + str(res))
plt.axis('off')
plt.imshow(image)
plt.show()
这里有一个在谷歌地图上预测的例子。标签是预测的类,我也显示它是否是一个正确的预测。
差不多就是这样了。继续在您的数据集上尝试。只要您正确地组织了您的图像,这段代码应该可以正常工作。很快我会有更多关于你可以用神经网络和 PyTorch 做的其他酷事情的故事。
克里斯·福塔什(Chris Fotache)是一名人工智能研究员,他在新泽西的 CYNET.ai 工作。他涵盖了与我们生活中的人工智能、Python 编程、机器学习、计算机视觉、自然语言处理等相关的主题。
如何仅使用 SQL 来训练和预测回归和分类 ML 模型—使用 BigQuery ML
原文:https://towardsdatascience.com/how-to-train-and-predict-regression-and-classification-ml-models-using-only-sql-using-bigquery-ml-f219b180b947?source=collection_archive---------3-----------------------
在我的书(Google 云平台上的数据科学)中,我讲述了一个航班延误预测问题,并展示了如何使用包括 Spark Mlib 和 TensorFlow 在内的各种工具来解决这个问题。既然已经宣布了 BigQuery ML,我想我应该展示如何使用 BQ ML 预测航班延误。
Predict whether this flight will arrive late. Using only SQL.
毫无疑问,您仍然需要收集数据、探索数据、清理数据并丰富数据。基本上所有我在第 1-9 章做的事情。在第十章,我用了 TensorFlow。在本文中,我将使用 BQML。
创建回归模型
下面是一个创建模型的 BigQuery 查询:
#standardsql
CREATE OR REPLACE MODEL flights.arrdelayOPTIONS
(model_type='linear_reg', input_label_cols=['arr_delay']) ASSELECT
arr_delay,
carrier,
origin,
dest,
dep_delay,
taxi_out,
distance
FROM
`cloud-training-demos.flights.tzcorr`
WHERE
arr_delay IS NOT NULL
请注意:
- 它从创建模型开始,模型的名称看起来就像一个表名。注意:“flights”是用于存储结果模型的数据集的名称,因此,您需要在运行查询之前创建一个空数据集。
- 这些选项指定了算法,在本例中是线性回归算法,标签为 arr_delay
- 本质上,我在 SELECT 中引入了预测变量和标签变量
大约 10 分钟后,模型被训练,并且评估结果已经为每个迭代填充:
这里的损失是均方误差,因此模型收敛于迭代#6,RMSE 约为 sqrt(97) = 10 分钟。
使用模型预测
训练模型的目的是用它来预测。您可以使用 SQL 语句进行模型预测:
#standardsql
SELECT * FROM ML.PREDICT(MODEL flights.arrdelay,
(
SELECT
carrier,
origin,
dest,
dep_delay,
taxi_out,
distance,
arr_delay AS actual_arr_delay
FROM
`cloud-training-demos.flights.tzcorr`
WHERE
arr_delay IS NOT NULL
LIMIT 10))
这导致:
如你所见,因为我们训练了模型来预测一个叫做“arr_delay”的变量,ML。PREDICT 创建一个名为 predicted_arr_delay 的结果列。在本例中,我从原始表中提取 10 行,并预测这些航班的到达延迟。
创建分类模型
在书中,我实际上并没有试图预测到达延迟。相反,我预测航班晚点超过 15 分钟的概率。这是一个分类问题,您可以通过稍微更改训练查询来做到这一点:
#standardsql
CREATE OR REPLACE MODEL flights.ontime
OPTIONS
(model_type='logistic_reg', input_label_cols=['on_time']) ASSELECT
IF(arr_delay < 15, 1, 0) AS on_time,
carrier,
origin,
dest,
dep_delay,
taxi_out,
distance
FROM
`cloud-training-demos.flights.tzcorr`
WHERE
arr_delay IS NOT NULL
下面是评测结果:
预测的一个例子是:
评估模型
可以在独立的数据集上评估模型。我手边没有,所以我将只向您展示如何在模型训练的同一数据集上运行评估:
#standardsql
SELECT * FROM ML.EVALUATE(MODEL flights.ontime,
(
SELECT
IF(arr_delay < 15, 1, 0) AS on_time,
carrier,
origin,
dest,
dep_delay,
taxi_out,
distance
FROM
`cloud-training-demos.flights.tzcorr`
WHERE
arr_delay IS NOT NULL
))
结果是:
BQML 真的很简单,真的很强大。尽情享受吧!
如何在 5 分钟内训练自定义图像分类器
原文:https://towardsdatascience.com/how-to-train-custom-image-classifier-in-5-minutes-4efa61255fc7?source=collection_archive---------2-----------------------
使用 Vize 分类器 API 识别图像
今天我将展示如何使用 Vize.ai —自定义图像分类 API 来设置和测试自定义图像分类引擎。我们将准备数据集,上传图像,训练分类器,并在 web 界面中测试我们的分类器。我们不需要编码经验,除非我们想在我们的项目中建立 API。让我们现在开始。
准备数据集
我们希望分类器识别人的性别。首先,我们需要每只雄性和雌性的 20 张图片。让我们用谷歌搜索“男人”和“女人”,并分别保存 20 张照片。在这里你可以下载我的数据集。我尽量避免时尚图片和模特,所以我的数据集是普通人图片。我还搜索了不同的文化类型和肤色,因此我的数据集尽可能多样化。我只用了正面图像。
Male and female images in dataset
将数据集上传到 Vize
我们需要在vize . ai上创建一个帐户。访问主页,然后点击“免费开始”,并使用 Google 或 GitHub 帐户登录。我们准备创建一个新任务。一个任务是分类引擎(卷积网络模型),它让我们对图像进行分类。
Homepage, signup page, task dashboard
我们点击“新任务”按钮,填写我们的分类器名称“男性或女性分类器”。我们要增加两类【男】****【女】。我们可以随时添加和删除类别。点击“创建”进入图像上传。
Name your task and create categories to sort
现在,我们将点击“直接上传”将图片上传到我们的两个类别中。我们可以在下面的图片上看到上传的 22 和 21 张图片。我们可以使用“编辑”按钮来显示图像,并将它们从一个类别移动到另一个类别。要删除一些图像,将它们移动到新的“删除”类别,并删除该类别。我们现在不需要这些。让我们点击右上角的“复习训练”。
Images uploaded into categories
训练分类器
在这一步,我们可以回顾我们的类别。我们准备点击【开始训练】按钮。
Start custom classifier training
一项任务正在训练中。根据图像的数量,可能需要一至五个小时。Vize 使用迁移学习和一组微调的模型架构,以在每项任务上达到尽可能最佳的准确性。现在是喝咖啡的时候了,等待训练结束。
Classifier training finished
测试分类器
我们的模型准备好了!我们在 43 张图像数据集上达到了 93%的准确率。我们现在可以使用预览来测试它。我们将点击“部署和预览”,然后点击“预览我的任务”。 在我们的数据集“test”文件夹中,我们可以找到一些测试图像来测试我们的分类器。
Preview trained task — test classification
摘要
我们使用 Vize web 界面训练和测试了我们的分类器。这是构建图像分类引擎最简单的方法。我们达到了 93%的准确率,随着上传更多的图像,我们可以将准确率提高到 100%。是时候尝试图像分类带来的巨大可能性了。在开发者文档中,我们还可以找到将 REST API 实现到我们的应用中的示例代码。
使用视觉 AI 可以构建什么样的应用?在评论中让我知道你的想法。
如何在 AWS 上使用 GPU 训练自定义单词嵌入
原文:https://towardsdatascience.com/how-to-train-custom-word-embeddings-using-gpu-on-aws-f62727a1e3f6?source=collection_archive---------2-----------------------
语言很重要。人类用文字交流,文字承载着意义。我们能训练机器也学习意义吗?这篇博客的主题是我们如何训练机器使用单词嵌入来学习单词的意思。在我浏览堆栈溢出、EC2 文档和博客的过程中,我将记下某人在 AWS 的 GPU 上使用 TensorFlow 训练单词嵌入的步骤。但是在介绍这些步骤之前,让我们先简要了解一下为什么我们需要单词嵌入。
Language is all around us — can we make a machine learn meaning?
通常,在大多数自然语言处理任务中,单词被转换成一键向量,其中每个单词在向量中获得唯一的索引。因此,在苹果、桔子和果汁这三个单词的词汇表中,我们可以用[1 0 0]、[0 1 0]和[0 0 1]来表示这三个单词。对于小型语言任务,这些向量非常有用。然而,其中有两个主要缺点:
a)对于具有 n 个字的训练数据,我们将需要 n 个维度向量。所以你可以想象 1000000 维向量非常大,并且非常稀疏。
b)one-hot vectors 中没有上下文的意义——每个单词都是完全唯一的。因此,如果一个模特已经学会了“苹果汁”,它就不能转移对填充“桔子 __”的学习。单词嵌入遵循的原则是“你将一个单词由它所保持的公司”,因此我们在单词嵌入向量中的每个维度都可以表示一个“特征”,如食物或性别或资本等等——如下所示:
Visualizing Word Embeddings (from a class by Andrew Ng)
训练有素的单词嵌入可以用于翻译、文本摘要、情感分析和类比任务,例如男人>女人、国王>王后。word 2 vec和 Glove 是两个流行的预训练单词嵌入,可以作为开源软件获得——它们对于开始一般的语言任务非常强大。但是,在本教程中,我们将学习如何在特定领域为我们自己的自定义数据构建 word 嵌入。我正致力于为电子数据,如微处理器、电容器、ram、电源等构建字嵌入。
因此,让我们开始制作单词嵌入的旅程,我们将在 AWS GPU 上进行训练!
- ****选择 P2 或 P3 实例类型T3 首先,您需要选择一个 EC2 实例类型。最近 AWS 在 EC2 上发布了 p3 实例,但是它们的价格大约是每小时 3 美元,这是一笔不小的数目。所以我将继续使用 p2 实例,它可能没有那么快,但是更便宜(大约每小时 1 美元)。这篇博客进行了更详细的比较。一旦你选择了 p2 实例,你可能需要在你的帐户上请求一个限制增加来得到使用他们。
- 建立深度学习 AMI 和安全组 如果您正在构建自己的 GPU 硬件,您需要自己设置 CUDA 驱动程序,但是在 AWS 上使用 EC2 实例为我们提供了使用预构建 AMI 或 Amazon 机器映像的优势。我选择了深度学习 AMI,带源代码(CUDA 8,Ubuntu)。
更新(2018 年 6 月):最新的 TensorFlow 库与 CUDA 8 不太兼容,请使用支持 CUDA 9 的 AMI 比如这个这个。
如果我们想在 EC2 实例中使用 Jupyter notebook,我们需要更改安全组,以允许从端口 8888 访问 EC2。这可以通过创建一个新的安全组和使用自定义 TCP 规则和端口范围作为 8888** 和在源选择**任何地方来完成。现在您可以启动实例了。接下来,创建一个新的密钥对,并将其保存在本地计算机上。当我丢失这个的时候,我不得不再次做这些步骤。pem 文件,所以请确保它在一个安全的地方!使用chmod 400 YourPEMFile.pem
将读写权限更改为只读。接下来,通过右键单击实例实例状态> Start 来启动您的 GPU。****
3.登录并在 EC2 实例上设置 Conda 环境** 您可以通过ssh -i path/YourPEMFile.pem ubuntu@X.X.X.X
登录到您的 GPU,其中X.X.X.X
代表您的 GPU 的公共 IP,path/YourPEMFile.pem
是您在上一步中创建的.pem
文件的路径。一旦您登录到 EC2 实例,您就可以设置自己的 Conda 环境。你为什么需要它?我们来看看这个的回答,它讨论了康达如何优于 virtualenv。键入conda -V
会导致一个错误,因为路径变量还没有设置好。我们需要转到.bash_profile
并添加路径。**
下面是让 **conda**
在新 EC2 实例
上工作的步骤 a .通过vim ~/.bash_profile
和
创建或编辑文件 b .添加export PATH=”/home/ubuntu/src/anaconda2/bin:$PATH”
路径指定包含可执行程序的目录,无需知道命令行上的完整路径即可启动这些程序。运行source ~/.bash_profile
来获取这个文件。你现在可以运行conda -V
并且不会看到错误。
e .通过conda create -n embeddings python=3
创建一个新环境这将使用最新版本的 Python 3 创建一个新的 conda 环境。
f .运行source activate embeddings
启动 conda 环境。****
4.安装 Tensorflow-GPU、Jupyter notebook 等软件包** 设置并激活 conda 环境后,现在可以安装 Tensorflow 等软件包了。
a)我们可以使用pip install tensorflow-gpu jupyter notebook nltk scikit-learn pandas
来安装所有必要的包来完成 word 嵌入的工作。我们需要使用tensorflow-gpu
而不是tensorflow
,因为前者已经过优化,适合在 GPU 中使用。所有这些要求都可以用pip freeze > requirements.txt
保存到一个文件中**
b)我们现在可以使用jupyter notebook --ip=0.0.0.0 --no-browser
转到X.X.X.X:8888/?token=<TOKEN>
来启动 jupyter 笔记本,其中X.X.X.X
是 EC2 机器的 IP 地址,<TOKEN>
是我们运行上面的命令时出现的令牌。
c)运行以下代码检查 TensorFlow 版本,并查看 TensorFlow 是否在 GPU 上正确运行。
import tensorflow as tf
print('TensorFlow Version: {}'.format(tf.__version__))
print('Default GPU Device: {}'.format(tf.test.gpu_device_name()))
我得到的输出是:
TensorFlow Version: 1.3.0 Default GPU Device: /gpu:0
为了绝对确定 GPU 确实被使用,运行
sess = tf.Session(config=tf.ConfigProto(log_device_placement=True))
,你应该会看到以/gpu:0
结尾的东西,这也是官方文档所建议的。这帮助我最近在设置实际使用 GPU。
5.建立用于训练单词嵌入的文本语料库** 你可以使用 IMDB 或维基百科数据集,但由于本博客的目标是通过自定义单词嵌入,我们将建立自己的语料库。如果你有很多文本文件,那么你可以一个一个地阅读它们,并建立语料库。在这里,我假设你有 PDF 文件,这是有点难以处理。为此,我使用了库PyPDF2
。我使用的代码是:**
import PyPDF2def read_pdf(fname):
pdfFileObj = open(fname, 'rb')
pdfReader = PyPDF2.PdfFileReader(pdfFileObj)
print("TOTAL PAGES in file", pdfReader.numPages)
pageObj = pdfReader.getPage(0)
text = pageObj.extractText()
return ' '.join(text.split())
我在本地存储的一堆 PDF 文件上运行了上面的代码。我将上述函数返回的字符串连接起来,并写入一个文本文件。我们的文本语料库准备好了!
6。预处理文本并创建查找表 现在,让我们预处理文本,为训练单词嵌入做好准备。在自然语言处理中,在运行分类器或算法之前,通常的做法是将所有单词小写,并进行一些停用词移除。我们将使用库re
(Python 中的正则表达式库)来执行其中的一些任务。
text = text.lower()
text = text.replace('.', ' __PERIOD__ ')
text = text.replace('-', ' ')
# Remove ' and full stops and brackets
text = re.sub(r'[{}()\']', '', text)
# Replace commas, dashes, colons and @ with spaces
text = re.sub(r'[;,:-@#]', ' ', text)
我们可以根据需要做更多的预处理,比如把缩写改成全称,用__NUMBER__
token 代替数字等等。上图中,我把句号改成了一个__PERIOD__
,它可以作为训练的标志。理解句子中单词上下文的动态变化是很重要的,而__PERIOD__
将帮助我们做到这一点。
接下来,让我们创建两个散列表,我们可以使用它们从索引>词汇以及词汇>索引中查找词汇。
下面的代码可以做到这一点:
word_counts = Counter(words)
sorted_vocab = sorted(word_counts, key=word_counts.get, reverse=True)
int_to_vocab = {ii: word for ii, word in enumerate(sorted_vocab)}
vocab_to_int = {word: ii for ii, word in int_to_vocab.items()}
7.执行二次采样** 经常出现的单词,如“the”、“is”等,对于为附近的单词提供上下文来说不是很有用。如果我们删除所有这些信息,我们就有效地删除了他们提供的任何信息。Mikolov 等人提出的一种更好的方法是删除一些单词,以消除数据中的一些噪声。对于训练集中的每个单词,我们以概率丢弃它:**
Probability to discard words to reduce noise
其中 t 是阈值参数,f(w)是单词 w 的频率。
8.创建张量流图****
我总是很难想象单词嵌入和数学是如何工作的。我发现吴恩达的解释在理解数学方面非常有用,下面是我们试图用 TensorFlow 做的工作流程(假设一个单词向量有 300 个维度,词汇表有 100,000 个独特的单词):
The 3 steps in training word embeddings — we only care about embedding matrix
输入的单词作为一个热点向量传递到一个隐藏的线性单元层。这些然后被连接到用于预测上下文单词的软最大层。换句话说,给定每个单词,我们将尝试最小化预测邻居或上下文单词的损失。我们最终可以扔掉 soft-max 层权重,只使用我们构建的单词向量的嵌入矩阵——这些单词向量是单词的低维表示,同时保留了上下文!
Chris McCormick 的博客是下图的灵感来源,该图是上图的另一个视图:
Visualizing the neural network of word embeddings
TensorFlow 使用数据流图来计算深度学习操作,我们需要首先定义图,然后在一个会话中在这个图上运行我们的数据。
让我们浏览一下这段代码:
import tensorflow as tf
train_graph = tf.Graph() # Placeholders for our training data
with train_graph.as_default():
inputs = tf.placeholder(tf.int32, [None], name='inputs')
labels = tf.placeholder(tf.int32, [None, None], name='labels')n_vocab = len(int_to_vocab)
n_embedding = 300 # Number of embedding features# Embedding matrix that we care about
with train_graph.as_default():
embedding = tf.Variable(tf.random_uniform((n_vocab, n_embedding), -1, 1))
word_vector = tf.nn.embedding_lookup(embedding, inputs)
首先我们定义图中的placeholders
的inputs
和labels
。接下来,我们使用Variable
来定义我们想要训练的内容。这个讨论对他们的区别很好。我们使用一个feed_dict
将值输入到占位符中。我们的total vocabulary size x number of embedding dimensions
给出了我们需要训练的总重量。
接下来,我们可以定义 softmax 权重和偏差:
# Softmax layer that we use for training but don't care about
with train_graph.as_default():
softmax_w = tf.Variable(tf.truncated_normal((n_vocab, n_embedding), stddev=0.1))
softmax_b = tf.Variable(tf.zeros(n_vocab))
9。负采样和损失函数 我们准备了一组单词和上下文单词,它们是正示例。但是我们也会添加一些单词和非上下文单词。这些将作为反面的例子。所以orange juice
是正面例子,但orange book
和orange king
也是反面例子。这使得向量的学习更好。对于每个正面的例子,我们可以选择 2 到 20 个反面的例子。这被称为负采样,TensorFlow 为此提供了一个函数[tf.nn.sampled_softmax_loss](https://www.tensorflow.org/api_docs/python/tf/nn/sampled_softmax_loss)
!
我们已经写好了整个图表,我们需要写损失函数是什么,以及如何优化权重。
with train_graph.as_default():
loss = tf.nn.sampled_softmax_loss(softmax_w, softmax_b,
labels, word_vector,
n_sampled, n_vocab)
cost = tf.reduce_mean(loss)
optimizer = tf.train.AdamOptimizer().minimize(cost)
10。运行 TensorFlow 会话来训练单词嵌入 写出图形和损失函数以及优化器后,我们可以编写 TensorFlow 会话来训练单词嵌入。
**with** tf.Session(graph=train_graph) **as** sess:
loss = 0
sess.run(tf.global_variables_initializer())
**for** e **in** range(1, 11): # Run for 10 epochs
batches = get_batches(train_words, batch_size, window_size)
**for** x, y **in** batches:
train_loss, _ = sess.run([cost, optimizer], feed_dict= {inputs: x, labels: np.array(y)[:, **None**]})
loss += train_loss
get_batches
此处未显示函数,但它在笔记本中(在参考文献中)——它批量返回特征和类的生成器。上述步骤在 CPU 上可能需要很长时间,但在 p2.x 实例上运行起来相当快。我能够在几分钟内运行 10 个纪元来训练 100k 单词的单词大小。我们可以使用我们学过的embedding
来绘制 T-SNE 图,以形象化地展示上下文是如何被学习的。请注意,T-SNE 图将把我们的 300D 数据缩减到 2D,因此一些上下文将会丢失,但是它保留了许多关于上下文的信息。
from sklearn.manifold import TSNE
tsne = TSNE()
embed_tsne = tsne.fit_transform(embedding[:viz_words, :])
fig, ax = plt.subplots(figsize=(14, 14))
**for** idx **in** range(viz_words):
plt.scatter(*embed_tsne[idx, :], color='steelblue')
plt.annotate(int_to_vocab[idx], (embed_tsne[idx, 0], embed_tsne[idx, 1]), alpha=0.7)
我们还可以使用主成分分析来可视化单词之间的关系,我们预计会发现如下关系:
Visualizing word vectors using PCA from the original Mikolov paper
这使得单词嵌入非常有趣!如果你在一家电子商务公司工作,如果你能开始识别battery size
和battery capacity
是否是同一件事,这可能会对用户产生巨大的影响,或者如果你在一个酒店预订网站,发现hotel
和motel
相似可能会产生巨大的影响!因此,在涉及语言的情况下,单词嵌入在改善用户体验方面非常有效。
我也觉得这个话题挺有意思的。我喜欢写作和语言,也喜欢数学和机器学习。词向量在某种程度上是这两个世界之间的桥梁。我刚刚完成了一个关于文本分类的大项目,接下来我会更多地研究这些与单词向量相关的想法!
祝你好运~
我正在创建一个类似主题的新课程,名为
“查询理解技术概述”。
本课程将涵盖信息检索技术、文本挖掘、查询理解技巧和诀窍、提高精确度、召回率和用户点击量的方法。有兴趣的请在这里报名!这种兴趣展示将允许我优先考虑和建立课程。
My new course: Overview of Query Understanding Techniques
如果你有任何问题,给我的 LinkedIn 个人资料留言或者给我发电子邮件到 sanket@omnilence.com。感谢阅读!
参考文献:
a) 吴恩达关于单词嵌入的课程。斯坦福大学 CS224n 曼宁教授的讲座。c)uda city 的深度学习纳米度。
d)我在 Github 上的字矢量笔记本。
如何使用 Spotty 在 AWS Spot 实例上训练深度学习模型?
原文:https://towardsdatascience.com/how-to-train-deep-learning-models-on-aws-spot-instances-using-spotty-8d9e0543d365?source=collection_archive---------5-----------------------
Spotty 是一个工具,它极大地简化了 AWS 上深度学习模型的训练。
你为什么会❤️这个工具?
- 它使得在 AWS GPU 实例上的培训就像在本地计算机上的培训一样简单
- 它自动管理所有必要的 AWS 资源,包括 ami、卷、快照和 SSH 密钥
- 它使得每个人都可以通过几个命令在 AWS 上训练你的模型
- 它使用 tmux 轻松地将远程进程从 SSH 会话中分离出来
- 通过使用 AWS Spot 实例,它可以为您节省高达 70%的成本
为了展示它是如何工作的,让我们采用一些非平凡的模型,并尝试训练它。我选择了 Tacotron 2 的一个实现。这是谷歌的语音合成系统。
将 Tacotron 2 的存储库克隆到您的计算机上:
git clone https://github.com/Rayhane-mamah/Tacotron-2.git
Docker 图像
码头集装箱内参差不齐的火车模型。因此,我们需要找到一个满足模型需求的公开可用的 Docker 映像,或者用适当的环境创建一个新的 Docker 文件。
Tacotron 的这个实现使用 Python 3 和 TensorFlow,所以我们可以使用 Docker Hub 的官方 Tensorflow 图像。但是这个图像并不满足“requirements.txt”文件中的所有要求。所以我们需要扩展映像,并在其上安装所有必要的库。
将“requirements.txt”文件复制到“docker/requirements-spotty.txt”文件中,并创建包含以下内容的docker/Dockerfile.spotty
文件:
这里我们扩展了原始的 TensorFlow 映像,并安装了所有其他需求。当您启动实例时,将自动构建此映像。
参差不齐的配置文件
一旦我们有了 docker 文件,我们就可以编写一个参差不齐的配置文件了。在项目的根目录下创建一个spotty.yaml
文件。
在这里你可以找到这个文件的全部内容。它由 4 个部分组成:项目、容器、实例、和脚本。我们一个一个来看。
第一部分:项目
此部分包含以下参数:
**name**
: 项目名称。该名称将用于 Spotty 为此项目创建的所有 AWS 资源的名称中。例如,它将用作 EBS 卷的前缀,或者用在帮助将项目代码与实例同步的 S3 存储桶的名称中。**syncFilters**
: 同步过滤器。这些过滤器将用于在将项目代码与正在运行的实例同步时跳过一些目录或文件。在上面的例子中,我们忽略了 PyCharm 配置、Git 文件、Python 缓存文件和训练数据。在幕后,Spotty 通过“aws s3 sync”命令使用这些过滤器,因此您可以在这里获得更多关于它们的信息:使用排除和包含过滤器。
第二部分:集装箱
本节描述了项目的 Docker 容器:
**projectDir**
: 容器内的一个目录,一旦实例启动,本地项目将被同步到这个目录。确保它是卷装载路径的子目录(见下文)或者与卷装载路径完全匹配,否则,一旦实例停止,对项目代码的所有远程更改都将丢失。**volumeMounts**
: 定义 EBS 卷应该挂载到的容器内的目录。EBS 卷本身将在配置文件的instances
部分描述。该列表的每个元素描述一个挂载点,其中name
参数应该与来自instance
部分的相应 EBS 卷相匹配(见下文),而mountPath
参数指定一个卷在容器中的目录。**file**
:我们之前创建的 Dockerfile 文件的路径。一旦实例启动,Docker 映像将自动构建。作为一种替代方法,您可以在本地构建映像,并将其推送到 Docker Hub ,然后您可以使用**image**
参数而不是**file**
参数直接指定映像的名称。**ports**
:实例应该公开的端口。在上面的例子中,我们打开了 2 个端口:6006 用于 TensorBoard,8888 用于 Jupyter Notebook。
在文档中阅读更多关于其他容器参数的信息。
第 3 节:实例
本节描述了实例及其参数的列表。每个实例包含以下参数:
**name**
:实例名称。该名称将用于专门为此实例创建的 AWS 资源的名称中。例如,EBS 卷和 EC2 实例本身。此外,如果在配置文件中有多个实例,这个名称也可以用在 Spotty 命令中。例如,spotty start i1
。**provider**
:实例的云提供商。目前,Spotty 只支持“ aws ”提供商(亚马逊网络服务),但在不久的将来也会支持谷歌云平台。**parameters**
:实例的参数。它们特定于云提供商。请参见下面的 AWS 实例参数。
AWS 实例参数:
**region**
:应该启动 Spot 实例的 AWS 区域。**instanceType**
:EC2 实例的类型。点击阅读更多关于 AWS GPU 实例的信息。**volumes**
:应该附加到实例的 EBS 卷列表。要将一个卷附加到容器的文件系统,参数name
应该匹配来自container
部分的一个volumeMounts
名称。请参见下面对 EBS 卷参数的描述。**dockerDataRoot**
:使用此参数,我们可以更改 Docker 存储所有图像(包括我们构建的图像)的目录。在上面的示例中,我们确保它是连接的 EBS 卷上的一个目录。所以下一次不会再重建图像,而只是从 Docker 缓存中加载。
EBS 音量参数:
**size**
:卷的大小,以 GB 为单位。**deletionPolicy**
:使用spotty stop
命令停止实例后,如何处理卷。可能的值包括:" create_snapshot " (默认), update_snapshot ", retain , delete "。在文档中阅读更多信息:卷和删除策略。**mountDir**
:将在实例上安装卷的目录。默认情况下,它将被装载到“/mnt/ < ebs_volume_name >”目录中。在上面的例子中,我们需要为“docker”卷显式指定这个目录,因为我们在dockerDataRoot
参数中重用了这个值。
在文档中阅读更多关于其他 AWS 实例参数的信息。
第 4 部分:脚本
脚本是可选的,但是非常有用。可以使用以下命令在实例上运行它们:
spotty run <SCRIPT_NAME>
对于这个项目,我们创建了 4 个脚本:
- 预处理:下载数据集并为训练做准备。
- 训练:开始训练,
- tensorboard :在 6006 端口运行 tensorboard,
- jupyter :启动端口 8888 上的 jupyter 笔记本服务器。
就是这样!该模型已准备好在 AWS 上接受训练。
参差不齐的安装
要求
- Python ≥3.5
- 安装和配置 AWS CLI(参见安装 AWS 命令行界面)
装置
使用 pip 安装 Spotty:
pip install -U spotty
模特培训
1。使用 Docker 容器启动 Spot 实例:
spotty start
一旦实例启动并运行,您将看到它的 IP 地址。以后用它打开 TensorBoard 和 Jupyter 笔记本。
2。下载并预处理 Tacotron 模型的数据。我们在配置文件中已经有了一个自定义脚本来完成这个任务,只需运行:
spotty run preprocess
数据处理完毕后,使用**Ctrl + b**
,然后使用**x**
组合键关闭 tmux 面板。
3。预处理完成后,训练模型。运行“训练”脚本:
spotty run train
您可以使用**Ctrl + b**
,然后使用**d**
组合键来分离这个 SSH 会话。训练过程不会中断。要重新连接该会话,只需再次运行spotty run train
命令。
张量板
使用“TensorBoard”脚本启动 tensorboard:
spotty run tensorboard
TensorBoard 将在端口 6006 上运行。您可以使用**Ctrl + b**
键和**d**
组合键分离 SSH 会话,TensorBoard 仍将运行。
Jupyter 笔记本
您也可以使用“Jupyter”脚本启动 Jupyter Notebook:
spotty run jupyter
Jupyter 笔记本将在 8888 端口上运行。使用将在命令输出中看到的实例 IP 地址和令牌打开它。
下载检查点
如果您需要将检查点或任何其他文件从正在运行的实例下载到您的本地机器,只需使用download
命令:
spotty download -f 'logs-Tacotron-2/taco_pretrained/*'
SSH 连接
要通过 SSH 连接到正在运行的 Docker 容器,请使用以下命令:
spotty ssh
它使用一个 tmux 会话,因此您可以使用**Ctrl + b**
然后使用**d**
组合键来分离它,并在以后再次使用spotty ssh
命令来附加该会话。
完成后,不要忘记停止实例!使用以下命令:
spotty stop
在上面的示例中,我们对卷使用了“保留”删除策略,因此 Spotty 将只终止实例,而不会触及卷。但是,如果我们使用“创建快照”或“更新快照”删除策略,它可以自动创建快照。
结论
使用 Spotty 是在 AWS Spot 实例上训练深度学习模型的一种便捷方式。它不仅可以为您节省高达 70%的成本,还可以节省大量为您的型号和笔记本电脑设置环境的时间。一旦你的模型有了一个参差不齐的配置,每个人都可以用几个命令来训练它。
如果你喜欢这篇文章,请在 GitHub 上启动 项目,点击👏按钮,并与您的朋友分享这篇文章。
如何使用云 ML 引擎在云端训练机器学习模型
原文:https://towardsdatascience.com/how-to-train-machine-learning-models-in-the-cloud-using-cloud-ml-engine-3f0d935294b3?source=collection_archive---------1-----------------------
以及如何使用 docopt 包巧妙地编写一个task.py
在云中训练 ML 模型很有意义。为什么?在许多原因中,它允许你用大量的计算训练大量的数据,并且可能并行训练许多模型。加上也不难做!在 Google 云平台上,可以使用 Cloud ML Engine 在 TensorFlow 和其他 Python ML 库中(如 scikit-learn)训练机器学习模型,而无需管理任何基础设施。为了做到这一点,你需要将你的代码放入一个 Python 包中(即添加setup.py
和__init__.py
文件)。此外,将您的代码组织成一个model.py
和task.py
是一个最佳实践。在这篇博文中,我将带你一步一步地了解这涉及到什么。
Submitting a job to ML Engine. The file *task.py*
is the file actually executed by ML Engine and it references the model logic located in *model.py*
.
**task.py**
文件****
作为一名教师,我看到学生,尤其是那些刚接触 Python 的学生,最先遇到的事情之一就是创建一个task.py
文件。虽然这在技术上是可选的(见下文),但强烈推荐,因为它允许你将超参数从模型逻辑中分离出来(位于model.py
)。它通常是由 ML 引擎调用的实际文件,其目的有两个:
- 读取和解析模型参数,如训练数据和输出模型的位置、隐藏层数、批量大小等。
- 用所述参数调用位于
model.py
中的模型训练逻辑
An example task.py file that parses command line arguments for training data location, batch size, hidden units, and the output location of the final model.
有许多不同的方法可以编写一个task.py
文件——你甚至可以给它起不同的名字。事实上task.py
和model.py
约定仅仅是一个约定。我们本来可以称之为task.py
aReallyCoolArgument_parser.py
和model.py
very_deeeep_model.py
。
我们甚至可以将这两个实体合并到一个文件中,进行参数解析和训练模型。只要你把你的代码安排到一个 Python 包中(即它必须包含 setup.py
和__init__.py
),ML 引擎就不会在意。但是,坚持在一个 trainer 文件夹中命名为task.py
和model.py
的两个文件的惯例(更多细节在下面),这两个文件分别存放您的参数解析和模型逻辑。
查看云 ML 示例和云 ML 培训报告,了解使用云 ML 引擎的完整示例以及model.py
和task.py
文件的示例。
使用 docopt 编写干净 **task.py**
文件
尽管许多人使用 argparse,这是用于解析命令行参数的标准 Python 库,但我更喜欢使用 docopt 包来编写我的task.py
文件。为什么?因为这是写一个记载 task.py
最简洁的方法。事实上,几乎你唯一需要写的就是你的程序的使用信息(即帮助信息),而 docopt 会处理剩下的事情。基于您在模块的 doc 字符串中编写的用法消息(Python 将调用这个__doc__
),您调用docopt(__doc__)
,它根据您在 doc 字符串中指定的格式为您生成一个参数解析器。以下是上面使用 docopt 的示例:
很不错,对吧?让我来分解一下。第一块代码是您的task.py
的用法。如果您不带参数调用它或者错误地调用task.py
,这将显示给用户。
第arguments = docopt(__doc__)
行从帮助字符串中解析用法模式(“用法:…”)和选项描述(以破折号“-”开头的行),并确保程序调用与用法模式匹配。
最后一部分将这些参数分配给model.py
变量,然后执行训练和评估。
让我们运行一个任务。记住task.py
是称为 Python 包的文件家族的一部分。在实践中,您将花大部分时间编写model.py
文件,花一点时间创建task.py file
,其余的基本上是样板文件。
training_example # root directory
setup.py # says how to install your package
trainer # package name, “trainer” is convention
model.py
task.py
__init__.py # Python convention indicating this is a package
因为我们使用的是 docopt,它不是标准库的一部分,我们必须将它添加到setup.py
,所以我们在setup.py
中插入了一个额外的行:
这将告诉 Cloud ML Engine 在我们向云提交作业时通过运行pip install docopt
来安装 docopt。
最后,一旦我们有了以上结构的文件,我们就可以向 ML 引擎提交一个作业。在我们这样做之前,让我们首先使用python -m
和ml-engine local predict
在本地测试我们的包。这两个步骤虽然是可选的,但可以帮助您在提交到云之前调试和测试包的功能。你通常在一个很小的数据集或非常有限的训练步骤上这样做。
Before you train on the cloud, test your package locally to make sure there are no syntactic or semantic errors.
一旦我们在本地测试了我们的模型,我们将使用gcloud ml-engine jobs submit training
向 ML 引擎提交我们的作业
这两行与我们的讨论相关:
— package-path=$(pwd)/my_model_package/trainer \
— module-name trainer.task
第一行表示我们包名的位置,我们总是称之为trainer
(一个约定)。第二行表示,在培训师包中,我们将调用培训师包中的任务模块(task.py
)。
结论
通过构建task.py
,我们可以将超参数作为命令行参数来处理,这允许我们将模型逻辑从超参数中分离出来。一个重要的好处是,这使我们能够使用不同的参数轻松地并行启动多个作业,以确定最佳超参数集(我们甚至可以使用内置的超参数调整服务!).最后,docopt 包根据用户编写的用法字符串自动为我们的task.py
文件生成一个解析器。
就是这样!我希望这能清楚地说明如何提交一个 ML 引擎作业并构建一个task.py
。如果你觉得这很有帮助,请留下你的掌声,让其他人也能发现。
附加资源
- 谷歌云 ML 样本
- 谷歌云机器学习培训
- 云 ML 引擎文档
- docopt 文档
- 封装一个 Python 模块
如何用优化器更快的训练神经网络?
原文:https://towardsdatascience.com/how-to-train-neural-network-faster-with-optimizers-d297730b3713?source=collection_archive---------6-----------------------
神经网络的秘密第四部分
当我在写最后一篇文章时,我有机会只用 Numpy 创建自己的神经网络。这是一项非常具有挑战性的任务,但同时它极大地拓宽了我对神经网络内部发生的过程的理解。其中,这次经历让我真正意识到有多少因素影响神经网络的性能。所选的架构、适当的超参数值,甚至参数的正确初始化,只是其中的一部分...然而,这一次,我们将关注对学习过程速度有巨大影响的决策,以及获得的预测的准确性——优化策略的选择。我们将深入了解许多流行的优化器,研究它们是如何工作的,并将它们相互比较。
注意:由于我想涵盖的内容范围相当广,所以我决定不在本文中包含任何代码片段。但是请记住,像往常一样,您可以在 GitHub 上找到所有用于创建可视化效果的代码。我还准备了一些笔记本,可以让你更好地理解讨论的问题。
机器学习算法的优化
O 优化是一个寻找使我们的功能最小化或最大化的参数的过程。当我们训练机器学习模型时,我们通常使用间接优化。我们选择某种度量标准,如准确度、精确度或召回率,这表明我们的模型解决给定问题的效果如何。然而,我们正在优化一个不同的成本函数 J(θ) ,并希望最小化其值将改善我们关心的度量。当然,成本函数的选择通常与我们要解决的特定问题有关。本质上,它是故意设计来表明我们离理想的解决方案有多远。可以想象,这个话题相当复杂,是一篇单独文章的绝佳话题。
Figure 1. Examples of points which are a problem for optimization algorithms.
一路上的陷阱
然而事实证明,找到非凸成本函数的最小值通常并不容易,我们必须使用高级优化策略来定位它们。如果你学过微分学,你肯定知道局部最小值的概念——这是我们的优化器可能陷入的一些最大的陷阱。对于那些还没有接触过数学中这一奇妙部分的人,我只能说,这些是函数取最小值的点,但只是在给定的区域内。上图的左侧显示了这种情况的一个示例。我们可以清楚地看到,优化器定位的点并不是整体最优解。
克服所谓的鞍点通常被认为更具挑战性。这些是平台,其中成本函数值几乎是恒定的。这种情况显示在同一图的右侧。在这些点上,所有方向上的梯度几乎为零,使得不可能逃脱。
有时,特别是在多层网络的情况下,我们可能不得不处理成本函数非常陡峭的区域。在这些地方,渐变的值急剧增加——爆炸渐变——这导致采取巨大的步骤,经常破坏整个先前的优化。然而,这个问题可以通过渐变裁剪轻松避免——定义最大允许渐变值。
梯度下降
在我们了解更高级的算法之前,让我们先来看看一些基本策略。可能最直接的方法之一就是简单地沿着与梯度相反的方向前进。这种策略可以用下面的等式来描述。
其中,α是一个称为学习率的超参数,它转化为我们在每次迭代中将要采取的步长。它的选择在一定程度上表达了学习速度和可以获得的结果的准确性之间的折衷。选择太小的步长会导致繁琐的计算,并且需要执行更多的迭代。然而,另一方面,选择太高的值会有效地阻止我们找到最小值。这种情况如图 2 所示——我们可以看到在随后的迭代中,我们如何来回跳动,无法稳定下来。同时,模型中适当的步骤被定义,几乎立即找到最小值。
Figure 2. Visualization of gradient descent behavior for small and large learning rate values. In order to avoid obscuring the image, only the last ten steps are visible at any time.
此外,该算法易受先前描述的鞍点问题的影响。由于在随后的迭代中执行的校正的大小与计算的梯度成比例,我们将无法逃离平台。
最后,最重要的是,该算法是无效的——它需要在每次迭代中使用整个训练集。这意味着,在每个时期,我们必须查看所有示例,以便执行下一个优化步骤。当训练集由几千个例子组成时,这可能不是问题,但正如我在我的一篇文章中提到的那样——当神经网络拥有数百万条记录时,它们工作得最好。在这种情况下,很难想象在每次迭代中我们都使用整个集合。这会浪费时间和计算机内存。所有这些因素导致梯度下降,以其最纯粹的形式,在大多数情况下不起作用。
小批量梯度下降
Figure 3. Comparison of gradient descent and mini-batch gradient descent.
L et 首先尝试解决上一章提到的最后一个问题——效率低下。虽然矢量化允许我们通过一次处理许多训练示例来加速计算,但当数据集有数百万条记录时,整个过程仍然需要很长时间才能完成。。让我们尝试使用一个相当简单的解决方案——将整个数据集划分为更小的批次,并在后续迭代中使用它们进行训练。我们的新策略已经在上面的动画中形象化了。想象一下,画在左边的等高线象征着我们想要优化的成本函数。我们可以看到,由于我们需要处理的数据量更少,我们的新算法做出决策的速度更快。再来关注一下对比车型在运动上的对比。梯度下降采取罕见的,相对较大的步骤,几乎没有噪音。另一方面,批量梯度下降需要更多的步骤,但是由于分析数据集中可能的多样性,我们有更多的噪音。甚至有可能在一次迭代中,我们会朝着与预期相反的方向前进。然而,平均来说,我们向最小值移动。
Figure 4. Splitting the dataset into batchs.
我知道你在想什么…如何选择批量?正如深度学习中经常出现的情况一样,答案不是确定的,取决于具体的情况。如果我们批处理的大小等于整个数据集,那么我们本质上是在处理一个普通的梯度下降。另一方面,如果大小为 1,那么在每次迭代中,我们只使用数据集中的一个例子,因此失去了矢量化的好处。这种方法有时是合理的,使用它的策略的一个例子是随机梯度下降。这是通过选择随机数据集记录并在后续迭代中将其用作训练集来完成的。然而,如果我们决定使用小批量,我们通常选择一个中间值—通常从 64 到 512 个示例中选择。
指数加权平均值
T 他的想法被用在很多领域,比如统计学、经济学甚至深度学习。许多先进的神经网络优化算法使用这个概念,因为它允许我们继续优化,即使在给定点计算的梯度为零。让我们花一些时间来理解这个算法。作为一个例子,我们将使用去年最大的科技公司的股票价值。
Figure 5. Visualization showing Exponentially weighted averages calculated for different β values.
EWA 本质上是平均许多以前的值,以便独立于局部波动,专注于整体趋势。它的值是使用上面显示的递归公式计算的,其中β是用于控制要平均的值的范围的参数。我们可以说,在随后的迭代中,我们考虑了 1/(1 - β)个例子。对于较大的β值,我们得到的图形要平滑得多,因为我们对许多记录进行了平均。另一方面,我们的图表越来越向右移动,因为当我们在很长一段时间内平均时,EWA 适应新趋势的速度更慢。这可以从图 5 中看出,我们在图 5 中展示了收盘时的实际股票价值,以及 4 个显示为不同 beta 参数计算的指数加权平均值的图表。
动量梯度下降
这种策略利用指数加权平均值来避免成本函数的梯度接近于零的点的麻烦。简而言之,我们允许我们的算法获得动量,这样即使局部梯度为零,我们仍然依靠先前计算的值向前移动。由于这个原因,它几乎总是比纯梯度下降更好的选择。
像往常一样,我们使用反向传播来计算网络每层的 dW 和 db 的值。然而,这次不是直接使用计算的梯度来更新我们的 NN 参数值,而是首先计算 VdW 和 Vdb 的中间值。这些值实际上是成本函数关于单个参数的导数的 EWA。最后,我们将在梯度下降中使用 VdW 和 Vdb 。整个过程可以用下面的等式来描述。还值得注意的是,该方法的实现需要存储迭代之间的 EWA 值。您可以在我的存储库上的一个笔记本中看到详细信息。
Figure 6. Gradient descent with momentum.
现在,让我们尝试对 EWA 对我们的模型行为的影响有一个直观的认识。再一次,让我们想象下面画的等高线象征着我们优化的成本函数。上面的可视化显示了标准梯度下降和带有动量的 GD 之间的比较。我们可以看到,成本函数的图形形状迫使采用非常缓慢的优化方式。就像在股票市场价格的例子中一样,指数加权平均值的使用让我们关注领先的趋势而不是噪音。指示最小值的分量被放大,导致振荡的分量被慢慢消除。此外,如果我们在后续更新中获得指向相似方向的梯度,学习率将会提高。这导致更快的收敛和减少的振荡。然而,这种方法有一个缺点—当您接近最小值时,动量值会增加,并可能变得如此之大,以至于算法将无法在正确的位置停止。
RMSProp
另一种提高梯度下降性能的方法是应用 RMSProp 策略——均方根传播,这是最常用的优化器之一。这是另一种使用指数加权平均值的算法。此外,它是自适应的——它允许对模型的每个参数的学习速率进行单独调整。后续参数值基于为特定参数计算的先前梯度值。
使用图 6 中的例子。和上面的等式,让我们考虑这个策略背后的逻辑。根据名称,在每次迭代中,我们计算关于相应参数的成本函数的导数的逐元素平方。此外,我们使用 EWA 来平均最近迭代中获得的值。最后,在我们更新网络参数值之前,相应的梯度分量除以平方和的平方根。这意味着对于梯度大的参数,学习速率降低得更快,而对于梯度小的参数,学习速率降低得更慢。这样,我们的算法减少了振荡,并防止噪声控制信号。为了避免被零除(数值稳定性),我们还为分母增加了一个非常小的值,在引用的公式中标记为ɛ.
我必须承认,在写这篇文章的时候,我有两个惊叹的时刻——我被我分析的优化器之间的质量飞跃震惊了。第一个是当我看到标准梯度下降和小批量之间的训练时间的差异。第二,当我将 RMSprop 与我们目前所见的一切进行比较时。然而,这种方法也有缺点。随着上述方程的分母在每次迭代中增加,我们的学习速率变小。因此,这可能会导致我们的模型完全停止。
Figure 7. Optimizers comparison.
圣经》和《古兰经》传统中)亚当(人类第一人的名字
L 快速但同样重要的是,让我告诉你关于自适应矩估计。与 RMSProp 一样,这是一种在广泛的应用中运行良好的算法。它利用了 RMSProp 的最大优点,并将它们与动量优化的思想相结合。结果是一个允许快速有效优化的策略。上图显示了讨论得很好的优化器如何处理函数中困难部分的优化。你可以立即看到亚当在这种情况下做得很好。
不幸的是,随着我们方法的有效性增加,计算的复杂性也增加了。是真的…以上,我写了十个矩阵方程,描述优化过程的单次迭代。根据经验,我知道你们中的一些人——尤其是那些不太熟悉数学家的人——现在会心情沉重。别担心!请注意,这里没有什么新内容。这些等式与之前为 momentum 和 RMSProp 优化器编写的等式相同。这一次我们将简单地同时使用这两种想法。
结论
我希望我已经设法以透明的方式解释了这些难题。这篇文章让我明白了选择正确的优化器有多重要。理解这些算法可以有意识地使用它们,理解单个超参数的变化如何影响整个模型的性能。
如果你设法来到这里,恭喜你。这当然不是最容易的阅读。如果你喜欢这篇文章,请在 Twitter 和 Medium 上关注我,并在 GitHub 和 Kaggle 上查看我正在进行的其他项目。本文是“神经网络的奥秘”系列的第四部分,如果你还没有机会,请阅读其他文章。如果你对接下来的帖子有什么有趣的想法,请写在评论里。保持好奇!
如何训练你的模型(大大加快)
原文:https://towardsdatascience.com/how-to-train-your-model-dramatically-faster-9ad063f0f718?source=collection_archive---------6-----------------------
学习使用迁移学习,用 Python 编码的例子。
我在Unbox Research——Tyler ney lon的新 ML 研发工作室担任机器学习工程师。我刚刚完成了一个项目,为一个客户实现了一个定制的图像分类器 iOS 应用程序——在这种情况下,迁移学习是一个强大的工具。
迁移学习是一种有效地、部分地重新训练神经网络的技术。为此,我们重用先前构建的模型架构和大部分学习到的权重,然后使用标准训练方法来学习剩余的、未重用的参数。
迁移学习 vs 非迁移学习
Figure 1: Model architecture for a standard neural network model, with green color indicating the training of all weights and biases.
经过充分训练的神经网络在初始层中获取输入值,然后顺序地将该信息向前馈送(同时对其进行转换),直到关键的是,某个倒数第二层已经构建了可以更容易地转换为最终输出的输入的高级表示。该模型的完整训练包括在每个连接中使用的权重和偏差项的优化,用绿色标记。
倒数第二层被称为瓶颈层**层。瓶颈层将回归模型中的值或分类模型中的 softmax 概率推送到我们的最终网络层。
Figure 2: Model architecture for a transfer-learning neural network model, with red color indicating fixed weights and biases, and green color indicating the training of just the final layer’s weights and biases.
在迁移学习中,我们从整个网络的预训练权重开始。然后,我们将权重固定到最后一层,并让该层中的权重随着我们对新数据的训练而变化。如图所示,我们保持红色连接不变,现在只重新训练最后一层绿色连接。
传输效率
迁移学习有两大好处:
- 对新数据的训练比从头开始更快。
- 如果我们从零开始,我们通常可以用比我们需要的更少的训练数据来解决问题。
Figure 3: A high level overview of the InceptionV3 model, which we use to demonstrate a transfer learning example. The fancy flowchart nature of the image has to do with Inception being a convolutional neural net.
在这里,我们考虑迁移学习为什么如此有效。
通过只重新训练我们的最后一层,我们正在执行一个计算成本低得多的优化(学习数百或数千个参数,而不是数百万个)。
这与像 Inception v3 这样的开源模型形成了鲜明对比,后者包含 2500 万个参数,并使用一流的硬件进行了训练。因此,这些网络具有非常合适的参数和瓶颈层,具有高度优化的输入数据表示。虽然您可能会发现很难用自己有限的计算和数据资源从头开始训练一个高性能的模型,但您可以使用迁移学习来利用他人的工作,并强制倍增您的性能。
样本代码
让我们看一些 Python 代码,稍微深入一些(但不要太深入——不要在那里迷路!).
首先,我们需要从一个预训练模型开始。Keras 有一堆预训练的模型;我们将使用 InceptionV3 模型。
*# Keras and TensorFlow must be (pip) installed.
from keras.applications import InceptionV3
from keras.models import Model*
InceptionV3 已经在 ImageNet 数据上进行了训练,该数据包含 1000 个不同的对象,其中许多我觉得非常古怪。例如,924 类是guacamole
。
Figure 4: mmm….
事实上,预训练的概念 3 承认这一点。
preds = InceptionV3().predict(guacamole_img)
返回一个 1000 维的数组(其中guacamole_img
是一个 224x224x3 维的 np 数组)。
preds.max()
返回 0.99999,而preds.argmax(-1)
返回指数 924——盗梦空间模型非常确定这个鳄梨色拉酱就是那个!(例如,我们预测guacamole_img
是 99.999%置信度的 Imagenet 图像#924。这里有一个可复制的代码的链接。
既然我们知道 InceptionV3 至少可以确认我当前吃的是什么,那么让我们看看是否可以使用底层数据表示来重新训练和学习一个新的分类方案。
如上所述,我们希望冻结模型的前n-1
层,只重新训练最后一层。
下面,我们加载预训练模型;然后,我们使用 TensorFlow 的.get_layer()
方法从原始模型中获取输入和倒数第二个(瓶颈)层名称,并使用这两个层作为输入和输出来构建新模型。
*original_model = InceptionV3()
bottleneck_input = original_model.get_layer(index=0).input
bottleneck_output = original_model.get_layer(index=-2).output
bottleneck_model = Model(inputs=bottleneck_input, outputs=bottleneck_output)*
这里,我们从初始模型的第一层(index = 0)获得输入。如果我们print(model.get_layer(index=0).input)
,我们会看到Tensor("input_1:0", shape=(?,?,?,3), dtype=float32)
——这表明我们的模型期望一些不确定数量的图像作为输入,具有未指定的高度和宽度,具有 3 个 RBG 通道。这也是我们希望作为瓶颈层输入的内容。
我们将Tensor("avg_pool/Mean:0",shape=(?, 2048), dtype=float32)
视为瓶颈的输出,我们通过引用倒数第二个模型层来访问它。在这种情况下,Inception 模型已经学习了任何图像输入的 2048 维表示,其中我们可以认为这些 2048 维表示对于分类来说必不可少的图像的关键组成部分。
最后,我们用原始图像输入和瓶颈层输出实例化一个新模型:Model(inputs=bottleneck_input, outputs=bottleneck_output).
接下来,我们需要将预训练模型中的每一层设置为不可训练的——本质上,我们冻结了这些层的权重和偏差,并保留了已经通过 Inception 原始、费力的训练学习到的信息。
*for layer in bottleneck_model.layers:
layer.trainable = False*
现在,我们制作一个新的Sequential()
模型,从我们之前的构建模块开始,然后做一个小的添加。
*new_model = Sequential()
new_model.add(bottleneck_model)
new_model.add(Dense(2, activation=‘softmax’, input_dim=2048))*
上面的代码用于构建一个复合模型,该模型将我们的初始架构与一个包含两个节点的最终层相结合。我们使用 2,因为我们要重新训练一个新的模型来学习区分猫和狗——所以我们只有 2 个图像类。用你希望分类的类别来代替它。
如前所述,瓶颈输出的大小是 2048,所以这是我们对Dense
层的 input_dim。最后,我们插入一个 softmax 激活,以确保我们的图像类输出可以被解释为概率。
我在这篇文章的最后附上了整个网络的一个非常高的网络布局图——一定要看看!。
最后,我们只需要几个标准的张量流步骤:
*# For a binary classification problem
new_model.compile(optimizer='rmsprop',
loss='binary_crossentropy',
metrics=['accuracy'])one_hot_labels = keras.utils.to_categorical(labels, num_classes=2)new_model.fit(processed_imgs_array,
one_hot_labels,
epochs=2,
batch_size=32)*
这里,processed_ims_array
是一个大小为(number_images_in_training_set, 224, 224, 3)
的数组,labels
是地面真实图像类的 Python 列表。这些标量对应于训练数据中的图像类别。num_classes=2
,所以labels
只是一个包含 0 和 1 的长度number_of_images_in_training_set
的列表。
最后,当我们在我们的第一个猫训练图像上运行这个模型时(使用 Tensorflow 非常方便的内置双线性 重缩放函数):
Figure 6: A cute cat…is good for you!
该模型以 94%的置信度预测cat
。考虑到我只使用了 20 张训练图像,并且只训练了 2 个时期,这已经很不错了!
外卖
通过利用预先构建的模型架构和预先学习的权重,迁移学习允许您使用学习到的给定数据结构的高级表示,并将其应用于您自己的新训练数据。
概括地说,使用迁移学习需要 3 个要素:
- 预训练模型
- 相似的训练数据-您需要输入与预训练模型的输入“足够相似”。足够相似意味着输入必须是相同的格式(如输入张量的形状、数据类型……)和相似的解释。例如,如果您使用一个为图像分类而预先训练的模型,图像将作为输入!然而,一些聪明的人将格式的音频通过一个预先训练的图像分类器运行,得到了一些很酷的结果。一如既往,财富偏爱有创造力的人。
- 培训标签
查看完整的工作示例点击查看使用本地文件的迁移学习演示。
如果你有任何问题/发现这个有价值,请在下面留下评论和掌声。如果你有任何想要讨论的机器学习项目,请随时联系我!will@unboxresearch.com。
对于纽约市的读者,我们将于 2019 年 1 月举办一场关于 TensorFlow 的研讨会— 在这里 获取门票。
附录:
用 Netron 创建的我们网络的完整图形表示。你不庆幸我们不用完全构建自己吗?!
**
如何用 Keras 和 Apache Spark 并行训练你的神经网络
原文:https://towardsdatascience.com/how-to-train-your-neural-networks-in-parallel-with-keras-and-apache-spark-ea8a3f48cae6?source=collection_archive---------5-----------------------
Github 链接到项目
“Time-lapse photography of spark (not the kind we address) from a firecracker” Photo by Ethan Hoover on Unsplash
作为一名数据科学家,你肯定遇到过“Apache Spark”一词被抛出的冷场讨论,通常后面是“computational clusters”、“JVM”等其他词,有时还有“你有没有再次尝试重启内核?”。你知道,只是标准的行业术语。理想情况下,您可能至少知道 Spark 与扩展您的数据科学项目有关。或者,通过管理海量数据并从中产生任何可操作的见解的第一手经验,您可能特别了解 SystemML 的强大威力。所以让我们开始吧!
Apache Spark 上的集群计算
在大多数真实世界的机器学习候选场景中,数据本身是从物联网传感器或多媒体平台实时生成的,并使用从 HDFS、ObjectStore、NoSQL 或 SQL 数据库等云解决方案以适当的格式存储。对于许多用例来说,在本地节点(Java 虚拟机在本地节点上运行 iPython 笔记本)提供的有限资源上运行您的分析工作流可能无法满足要求。快速、健壮和可靠的机器学习工作流可以利用大型计算集群,而无需费力地编辑代码并使其适应并行处理。你怎么问?这就是著名的 Hadoop 分布式文件系统的秘方,它可以让你将所有磁盘的存储容量合并为一个大型虚拟文件系统。
HDFS 主要做的是将数据分成大小相等的块,并将它们分布在物理磁盘上,同时在这些块上创建一个虚拟视图,以便它可以被视为跨整个集群的单个大文件。该技术的一个主要优势来自于数据局部性的概念。由于 HDFS 跟踪文件各个块的位置,因此可以使用驻留在同一物理工作节点上的 CPU 或 GPU 并行执行计算。在这一点上,你们中的一些人可能会问,为什么要这样做?嗯,这个问题的简单答案可以通过一个小测验来证明:
您有一个很好的计算集群,拥有 256 个节点,每个节点 8 个 CPU,每个 CPU 有 16 个 CPU 内核,每个内核有 4 个超线程。并发运行的并行线程的最大可能数量是多少?
Image retrieved from : https://systemml.apache.org/
这个问题的答案当然是, <在这里打鼓> : 131 072 同时运行并行线程,各自做自己的一部分工作!(= 256 个节点*每个节点 8 个 CPU 每个 CPU 16 个 CPU 核心每个核心 4 个超线程)。因此,通过这种方式,Apache spark 提供了一个开源的分布式通用集群计算框架,它允许你操作数据并并行执行计算。
永远有弹性
ApacheSpark 中的主要数据抽象是古老的弹性 分布式数据集 ( RDD) 。这是一个分布式不可变的集合或列表数据,可以用字符串或双精度值编写,可以使用各种数据存储解决方案伪造,从开源的 MongoDB 数据库到更具排他性的 SQL 和 NoSQL 解决方案。您甚至可以从本地文件系统创建 rdd。创建后,RDD 分布在不同工作节点的主内存中。最后,你会发现 rdd 相当懒。这意味着,只有在执行特定计算确实需要数据时,才会从底层存储系统中读取数据。默认情况下,应用于数据框的任何变换(如删除变量或归一化要素)都不会立即执行。相反,你的选择会被记住,只有当一个动作要求一个结果返回给驱动程序时才会被计算。事实证明,这根本不是一个坏主意,并为即将到来的真正的大规模行动节省了相当多的计算资源。
Apache Spark 的三个杀手级特性使其成为强大的数据科学和机器学习工具:
1.结构化数据检索:Spark SQL
无数的数据科学家、分析师和普通商业智能用户依靠 interactive SQL 查询来探索数据。令人欣慰的是,Spark 很好地意识到了这一点,并附带了用于结构化数据处理的 Spark 模块,称为 Spark SQL。它提供了我们都非常珍视的编程抽象,即数据框架。Spark SQL 还可以充当分布式 SQL 查询引擎,并使未修改的 Hadoop Hive 查询在现有部署和数据上的运行速度提高 100 倍。它还提供了与 Spark 生态系统其余部分的强大集成(例如,将 SQL 查询处理与机器学习集成)。
Spark Open source ecosystem
2.机器学习:MLlib
机器学习已经迅速成为挖掘大数据以获得可操作见解的关键部分。建立在 Spark 之上的 MLlib 是一个可扩展的机器学习库,它提供了高质量的算法和“闪电般”的速度,如果他们说自己做的话(比 MapReduce 快 100 倍)。该库可作为 Spark 应用程序的一部分在 Java、Scala 和 Python 中使用,因此您可以将其包含在完整的工作流中。
它的伟大之处在于,Apache SystemML 为使用大量数据的机器学习提供了一个最佳的工作场所,因为它不仅提供了使用大量定制算法的方法,还允许您使用一些伟大的预实现算法(如梯度提升树、K-最近邻,仅举几例)。更好的是,它与各种著名的深度学习框架(如 Keras 和 Caffe)相接口,我们将在后面看到。
3.流分析:火花流
最后,如今许多应用程序不仅需要处理和分析批量数据,还需要实时处理和分析新数据流。Spark Streaming 运行在 Spark 之上,支持跨流和历史数据的强大交互和分析应用,同时继承了 Spark 的易用性和容错特性。它很容易与各种流行的数据源集成,包括 HDFS、Flume、Kafka 和 Twitter。
有些人可能会说,在这里只命名 3 个特性并不能体现 Apache Spark 的公正。钨加速器和语法执行树等操作特性也非常出色,同样有利于当今忙碌的数据科学家。当然,我可以详细介绍 Apache Spark、Hadoop 分布式文件系统和 mllib 库。可以说是“引擎盖下”的旅行。但是也许下一篇文章。对于本文的目的,我们理解 Apache Spark 的 SystemML 可以在可嵌入、独立和集群模式下运行,支持 Scala、Python 和 Java 中的各种 API,并且是扩展深度学习模型的理想选择就足够了。你怎么问?
用 SystemML 扩展机器学习
进入大数据世界七大奇迹之一的 SystemML。这个灵活的机器学习系统能够自动扩展到 Spark 和 Hadoop 集群。事实上,根据数据大小、稀疏性、计算集群大小以及本地机器的内存配置,SystemML 将决定是编译单节点计划,还是 Hadoop 或 Spark 计划。它附带了一种类似 R 的函数式编程语言,称为声明式机器学习,可以让您实现您喜欢的机器学习算法,或者更好的是,从头设计一个自定义算法。据说 SystemML 有一个低成本的编译器,可以自动生成混合运行时执行计划,这些计划由单个节点和分布式操作组成。它可以在 Apache Spark 上运行,在 Apache Spark 上,它可以自动逐行缩放您的数据,确定您的代码应该在驱动程序上运行还是在 Apache Spark 集群上运行。
在 SystemML 上实现深度学习模型
在 SystemML 中实现深度学习模型有三种不同的方式:
- 使用DML-体神经网络库:这个库允许用户充分利用 DML 语言的灵活性来实现你的神经网络。
- 使用实验性的 Caffe2DML API :这个 API 允许用 Caffe 的 proto 格式表示的模型被导入到 SystemML 中。这个 API 不要求 Caffe 安装在你的 SystemML 上。
-
- 使用实验性的 Keras2DML API :这个 API 允许用 Keras 的 API 表示的模型导入到 SystemML 中。但是,这个 API 要求 Keras 安装在您的驱动程序上。*
SystemML 的开发包括额外的具有 GPU 功能的深度学习,例如导入和运行神经网络架构和用于训练的预训练模型。本文的下一部分将展示如何使用 MLContext API 序列化和训练 Keras 模型。我也鼓励你查看一些由 Apache Spark 发布的关于如何开始使用 DML 的详细教程,并行化诸如自动编码器的算法,并尝试一些不错的旧图像分类。
IBM Watson Studio 上的 Apache Spark
现在,我们将最终使用实验性的 Keras2DML API 来训练我们的 Keras 模型。为了能够执行以下代码,您需要在 IBM cloud 帐户上创建一个免费 tier 帐户,并登录以激活 Watson studio。
(IBM cloud 上的分步 Spark 设置 教程此处 ,IBM cloud 上的 spark 更多信息此处 )。
一旦你有了一个激活星火计划的 Watson studio 账号,你就可以在平台上创建一个 Jupyter 笔记本,选择一个云机配置(CPU 和 RAM 的数量)和一个星火计划,就可以开始了!
沃森工作室附带一个免费的星火计划,包括 2 个星火工作者。虽然这对于现在这样的演示目的来说已经足够了,但是对于真实世界的场景来说,强烈建议购买付费的 Spark 计划。更多的 Spark workers 基本上意味着更多的线程可以并行处理计算,因此更少像僵尸一样在屏幕前等待结果。最后,在我们开始之前,我还将注意到其他替代方案,如深度认知,具有同样有趣的功能和说明性的媒体文章,它们是存在的,并且同样值得探索。
SystemML 上的手写数字识别
啊,MNIST。如此标志性,它可以被认为是机器学习数据集的“hello world”。事实上,它甚至是 Keras 安装自带的六个标准数据集之一。请放心,无论您想到什么算法,从线性分类器到卷积神经网络,都已经在这个数据集上进行了尝试和测试,在过去 20 年的某个时间。都是为了手写数字识别的任务。一些我们人类自己毫不费力就能做到的事情(如此之多,以至于不得不把它作为一项工作来做肯定是非常令人沮丧的)。
事实上,这项任务是相当多的机器学习起源项目的理想候选,因为缺乏当时存在的全面的大型数据集……嗯,任何真正的东西。尽管现在情况已经不同了,互联网上充斥着从鳄梨价格到金星火山的数据集。今天,我们通过扩大我们的手写数字识别项目来纪念 MNIST 的传统。我们通过在计算集群上训练我们的机器学习算法来做到这一点,并有可能大大减少我们的训练时间。
Convolutional neural network on MNIST dataset
1。我们从导入一些库开始:
import keras
from keras.models import Sequential
from keras.layers import Input, Dense, Conv2D
from keras.layers import MaxPooling2D, Dropout,Flatten
from keras import backend as K
from keras.models import Model
import numpy as np
import matplotlib.pyplot as plt
2.加载数据
我们现在可以从 Keras 加载 MNIST 数据集,使用下面的简单代码行。
from keras.datasets import mnist(X_train, y_train), (X_test, y_test) = mnist.load_data()# Expect to see a numpy n-dimentional array of (60000, 28, 28)type(X_train), X_train.shape, type(X_train)
3.塑造您的数据
在这里,我们做一些最适合我们的神经网络重塑。我们将每个 28×28 的图像重新排列成一个 784 像素值的向量。
#Flatten each of our 28 X 28 images to a vector of 1, 784X_train = X_train.reshape(-1, 784)
X_test = X_test.reshape(-1, 784)#Check shape
X_train.shape, X_test.shape
4.标准化您的数据
然后,我们使用 Scikit-Learn 的 MinMaxScaler 来归一化我们的像素数据,其范围通常为 0–255。归一化后,值的范围将从 0 到 1,这大大改善了结果。
from sklearn.preprocessing import MinMaxScalerdef scaleData(data):
scaler = MinMaxScaler(feature_range=(0, 1))
return scaler.fit_transform(data) X_train = scaleData(X_train)
X_test = scaleData(X_test)
5.建立网络
接下来,我们用 Keras 构建我们的网络,定义一个适当的输入形状,然后堆叠一些卷积、最大汇集、密集和丢弃层,如下所示。(一些神经网络基础:确保你的最后一层和你的输出类有相同数量的神经元。因为我们预测的是手写数字,范围从 0 到 9,所以我们有一个由 10 个神经元组成的密集层作为最后一层。)
input_shape = (1,28,28) if K.image_data_format() == 'channels_first' else (28,28, 1)keras_model = Sequential()
keras_model.add(Conv2D(32, kernel_size=(5, 5), activation='relu', input_shape=input_shape, padding='same'))
keras_model.add(MaxPooling2D(pool_size=(2, 2)))
keras_model.add(Conv2D(64, (5, 5), activation='relu', padding='same'))
keras_model.add(MaxPooling2D(pool_size=(2, 2)))
keras_model.add(Flatten())
keras_model.add(Dense(512, activation='relu'))
keras_model.add(Dropout(0.5))
keras_model.add(Dense(10, activation='softmax'))
keras_model.summary()
如果你看到下面这个 Keras 模型的总结,那么到目前为止你都是好的。
5.创建一个 SystemML 模型
使用 Keras2DML 包装器,并将其输入我们新构建的 Keras 网络。这是通过调用 Keras2DML 方法并向其提供您的 spark 会话、Keras 模型、其输入形状和预定义变量来完成的。变量' epoch 表示您的算法在数据上迭代的次数。接下来,我们有' batch_size ',它表示我们的网络将在每个学习批次中看到的训练示例的数量。最后,‘samples’只是对我们训练集中的样本数量进行编码。我们还要求每 10 次迭代显示一次训练结果。
然后,我们在新定义的 SystemML 模型上使用fit参数,并向其传递训练数组和标签来启动我们的训练会话。**
**from systemml.mllearn import Keras2DMLepochs = 5
batch_size = 100
samples = 60000
max_iter = int(epochs*math.ceil(samples/batch_size))sysml_model = Keras2DML(spark, keras_model, input_shape=(1,28,28), weights='weights_dir', batch_size=batch_size, max_iter=max_iter, test_interval=0, display=10) sysml_model.fit(X_train, y_train)**
现在,您应该会在屏幕上看到类似这样的内容:
6.得分时间到了!我们只需在我们训练好的 SystemML 模型上调用 score 参数,就可以做到这一点,就像这样:
**sysml_model.score(X_test, y_test)**
等待 spark 作业执行,然后,瞧!您应该看到您在测试集上的准确性出现。你可以在下面看到,我们取得了 98.76 的成绩,不算太差。
请注意,我们能够通过 SystemML 的 Keras2DML 包装器部署 Keras 模型,该包装器实际上将您的模型序列化为 Caffe 模型,然后将该模型转换为声明性的机器学习脚本。如果您选择用 Keras 来训练相同的 Keras 模型,那么该模型将会受到单个 JVM 的资源的限制,而不会为了并行处理而对代码进行重大调整。整洁,不是吗?你现在可以在本地 GPU 上训练你的神经网络,或者像我们在 Watson studio 上做的那样使用云机器。
虽然在处理方面配备一些本地火力总感觉不错,但没有什么能打败云。你真的可以扩大你的项目,选择合适的机器配置和 spark 计划,而成本只是硬件替代品的一小部分。这是处理不同环境和高度多样化需求的用例的理想选择,从小规模数据可视化到需要实时分析 Pb 级数据的大数据项目。也许你只是试图分析来自你的分布式仓库网络(如沃尔玛)的大量物联网数据。或者也许你到达了亚原子深度,试图确定我们宇宙的结构,就像欧洲粒子物理研究所一样。在这些大不相同的用例中,任何一个都可以从将计算迁移到云中受益,而且很可能已经这样做了。
谢谢你的时间
我希望你觉得这篇文章内容丰富,令人愉快。我真的很喜欢研究这篇文章的内容和编写相关的代码。这里有一个到我的库的链接,里面有的完整代码,以及一个不使用 SystemML 的脚本版本。如果您对所涉及的内容或所提供的源代码有任何问题或反馈,请在评论中告诉我。下次见!
参考
****1。星火入门:https://databricks.com/product/getting-started-guide-2
****2。SystemML 网页:http://systemml.apache.org/
****3。Spark ML 上下文编程指南:https://system ML . Apache . org/docs/0 . 15 . 0/spark-ML context-Programming-guide
4. Keras2DML 指南:https://system ml . Apache . org/docs/1 . 0 . 0/初学者-指南-keras2dml
****5。喀拉斯:https://keras.io/
6。Github 资源库代码:https://gist . github . com/NiloyPurkait/1c 6 c 44 f 329 f 2255 f 5 de 2 b 0d 498 C3 f 238
如何用 TensorFlow 的物体检测器 API 训练自己的物体检测器
原文:https://towardsdatascience.com/how-to-train-your-own-object-detector-with-tensorflows-object-detector-api-bec72ecfe1d9?source=collection_archive---------0-----------------------
这是关于“用 Tensorflow 和 OpenCV 构建实时物体识别应用”的后续帖子,在这里我重点训练自己的类。具体来说,我在自己收集和标记的数据集上训练了自己的浣熊检测器。完整的数据集可在我的 Github repo 上获得。
顺便说一下,这是浣熊探测器在工作:
The Raccoon detector.
想了解详情,还是继续看下去吧!
动机
在我的上一篇帖子之后,许多人要求我写一份指南,介绍他们如何使用 TensorFlow 的新对象检测器 API 用他们自己的数据集训练对象检测器。我找到时间做这件事。在这篇文章中,我将解释训练你自己的探测器的所有必要步骤。特别是,我创建了一个对象检测器,能够识别浣熊,结果相对较好。
搞什么鬼?为什么说浣熊 🐼 ????
没有什么特别😄它们是我最喜欢的动物之一,不知何故它们也是我的邻居!我发誓,浣熊探测器有很多潜在的用途。例如,现在你可以检测到当你不在家时,是否有浣熊在敲你的门。该系统可以向您的手机发送一条推送消息,让您知道有访客。
Full video: https://youtu.be/Bl-QY84hojs
创建数据集
所以我们认真点!我需要做的第一件事是创建自己的数据集:
- Tensorflow 对象检测 API 使用 TFRecord 文件格式,所以最后我们需要将数据集转换成这种文件格式
- 有几个选项可以生成 TFRecord 文件。要么你有一个与 PASCAL VOC 数据集或 Oxford Pet 数据集结构相似的数据集,然后他们有现成的脚本用于这种情况(参见
[create_pascal_tf_record.py](https://github.com/tensorflow/models/blob/master/research/object_detection/create_pascal_tf_record.py)
和[create_pet_tf_record.py](https://github.com/tensorflow/models/blob/master/research/object_detection/create_pet_tf_record.py)
)。如果您没有这些结构中的一个,您需要编写自己的脚本来生成 TFRecords(它们也为这个提供了解释)。这就是我做的! - 要为 API 准备输入文件,您需要考虑两件事。首先,您需要一个编码为 jpeg 或 png 的 RGB 图像,其次,您需要一个图像的边界框列表(
xmin, ymin, xmax, ymax
)和边界框中的对象类别。对我来说,这很简单,因为我只有一门课。 - 我从 Google Images 和 Pixabay 中搜集了 200 张浣熊图片(主要是 jpegs 和一些 png ),确保这些图片在比例、姿势和光照方面有很大的变化。这是我收集的浣熊图像数据集的一个子集:
Subset of the Raccoon image dataset.
- 之后,我用标签手工给它们贴上标签。LabelImg 是一个用 Python 编写的图形图像注释工具,使用 Qt 作为图形界面。它支持 Python 2 和 3,但我用 Python 2 和 Qt4 从源代码中构建了它,因为我用 Python 3 和 Qt5 时遇到了问题。它非常容易使用,注释以 PASCAL VOC 格式保存为 XML 文件,这意味着我也可以使用
[create_pascal_tf_record.py](https://github.com/tensorflow/models/blob/master/research/object_detection/create_pascal_tf_record.py)
脚本,但我没有这样做,因为我想创建自己的脚本。 - 不知何故,LabelImg 在 MAC OSX 上打开 JPEG 有问题,所以我不得不把它们转换成 png,然后再转换回 JPEG。实际上,我可以将它们保存在 png 中,API 也应该支持这一点。我发现的时候已经太晚了。这是我下次要做的。
- 最后,在标记图像之后,我编写了一个脚本,将 XML 文件转换为 csv 文件,然后创建 TFRecords。我用了 160 张图片进行训练(
train.records
),40 张图片进行测试(test.records
)。该脚本也可以在我的回购上获得。
备注:
- 我发现了另一个叫做 FIAT(快速图像数据注释工具)的注释工具,看起来也不错。将来,我可能会尝试这样做。
- 对于命令行上的图像处理,如将多个图像转换成不同的文件格式, ImageMagick 是一个非常好的工具。万一,你没用过,值得一试。
- 通常,创建数据集是最痛苦的部分。我花了 2 个小时来整理这些图片并给它们贴上标签。这只是一堂课。
- 确保图像大小为中等(参见 Google images,了解中等是什么意思)。如果图像太大,您可能会在训练过程中遇到内存不足的错误,尤其是在您没有更改默认批处理大小设置的情况下。
训练模型
在我为 API 创建了所需的输入文件之后,我现在可以训练我的模型了。
对于培训,您需要以下内容:
- 一个物体检测训练管道。他们还在回购上提供了样本配置文件。对于我的训练,我使用
ssd_mobilenet_v1_pets.config
作为基础。我需要将num_classes
调整为 1,并为模型检查点、训练和测试数据文件以及标签地图设置路径(PATH_TO_BE_CONFIGURED
)。至于其他配置,比如学习率、批量大小等等,我使用了它们的默认设置。
注意:data_augmentation_option
非常有趣,如果你的数据集没有太多的可变性,比如不同的比例、姿势等..完整的选项列表可以在这里找到(见PREPROCESSING_FUNCTION_MAP
)。
- 数据集(TFRecord 文件)及其相应的标签映射。如何创建标签地图的例子可以在这里找到。这也是我的标注图,非常简单,因为我只有一个类:
item {
id: 1
name: 'raccoon'
}
注意:你的标签映射应该总是从 id 1 开始,这一点很重要。索引 0 是一个占位符索引(关于这个主题的更多信息,也参见这个讨论)。
- (可选) 预先训练好的模型检查点。建议使用检查点,因为从预先训练的模型开始总是更好,因为从头开始训练可能需要几天才能得到好结果。他们在回购协议上提供了几个模型检查点。在我的例子中,我使用了 ssd_mobilenet_v1_coco 模型,因为模型速度对我来说比准确性更重要。
现在你可以开始训练了:
- 培训可以在本地进行,也可以在云 (AWS、谷歌云等)上进行。).如果你家里有 GPU(至少 2 GB 以上),那么你可以在本地完成,否则我会建议你使用云。就我而言,这次我使用了谷歌云,基本上遵循了他们文档中描述的所有步骤。
- 对于谷歌云,你需要定义一个 YAML 配置文件。还提供了一个样本文件,我基本上只是采用了默认值。
- 还建议在培训期间开始评估工作。然后,您可以通过在本地机器上运行 Tensorboard 来监控培训和评估工作的进程。
tensorboard — logdir=gs://${YOUR_CLOUD_BUCKET}
以下是我的培训和评估工作的结果。总的来说,我用 24 个批量运行了大约一个小时/22k 步,但是我已经在大约 40 分钟内取得了很好的结果。
总损失是这样演变的:
Total loss decreased pretty fast due to the pre-trained model.
因为我只有一个类,所以只看总地图(平均精度)就足够了:
The mAP hit 0.8 at around 20k steps which is quite good.
下面是一个在训练模型时评估一幅图像的示例:
The detected box around the Raccoon got much better over time.
输出模型
- 完成训练后,我将训练好的模型导出到一个文件中(Tensorflow graph proto ),这样我就可以用它进行推理。
- 在我的例子中,我必须将模型检查点从 Google Cloud bucket 复制到我的本地机器上,然后使用提供的脚本来导出模型。型号可以在我的回购上找到,以防万一如果真的要用在生产上;)
奖金:
I applied the trained model on a video that I found on YouTube.
- 如果你看过视频,你会发现并不是每只浣熊都被检测到,或者有一些错误的分类。这是合乎逻辑的,因为我们只在一个小数据集上训练模型。要创建一个更通用、更强大的浣熊检测器,例如,它还能够检测地球上最著名的浣熊,即来自银河护卫队的火箭浣熊,我们只需要更多的数据。这只是目前人工智能的局限性之一!
Most famous raccoon on earth.
结论
我希望你喜欢这篇文章。如果你有,给我一个❤️。希望你现在可以训练你自己的物体探测器。在本文中,我只使用了一个类,因为我懒得标记更多的数据。有一些服务,如crowd Lower、 CrowdAI 或亚马逊的 Mechanical Turk 提供数据标签服务,但这对于本文来说太多了。
我在如此短的训练时间内获得了相当不错的结果,但这是因为检测器只在一个班中训练过。对于更多的职业,总地图不会像我得到的那样好,而且肯定需要更长的训练时间才能得到好的结果。事实上,我还在 Udacity 提供的带注释的驾驶数据集(数据集 1)上训练了一个对象检测器。我花了很长时间来训练一个模型,它能够很好地识别汽车、卡车和行人。在许多其他情况下,即使我使用的模型也过于简单,无法捕捉多个类之间的所有可变性,因此必须使用更复杂的模型。还必须考虑模型速度和模型精度之间的权衡。然而,这是一个不同的故事,实际上可以是另一个独立的文章。
在 Medium Dat Tran 或 twitter @datitran 上关注我,了解我的最新作品。
如何训练你的自动驾驶汽车转向
原文:https://towardsdatascience.com/how-to-train-your-self-driving-car-to-steer-68c3d24bbcb7?source=collection_archive---------1-----------------------
一步一步的指导使用小而有效的神经网络和一点魔法。
神经网络,特别是深度学习研究,最近在计算机视觉领域和计算机科学的其他重要领域取得了许多突破。在许多不同的应用中,目前正在兴起的一项技术是自动驾驶汽车。每个人都听说过他们,所有的大公司似乎都在这个新千年的淘金热中投入巨资。人工智能驱动的汽车可以带你去任何地方,而你的时间,嗯,不开车。在这篇文章中,我将向你展示如何训练一个神经网络,仅使用前方道路的图像来自主驾驶。你可以在这个 Jupyter 笔记本中找到所有的代码,一步一步地解释。你也可以在这里找到更详细的论文。
深度神经网络,尤其是在计算机视觉、物体识别等领域,往往参数很多,有几百万个。这意味着它们的计算量和运行它们的设备的内存都很大。如果你是一个学术实验室或一家大公司,你有你的数据中心和大量的 GPU,这不是一个问题。但是,如果你只有一辆应该实时驾驶的汽车上的嵌入式系统,这可能是一个问题。这就是为什么我将重点放在非常纤薄、快速和高效的特定架构上。我使用的主要模型是SqueezeNet架构。这是一个相当新的模型,它用很少的参数,仅几兆字节的重量,就在对象识别任务上取得了显著的性能。我建议阅读这个故事和代码,它已经非常详细,以进一步理解概念。
我们首先需要的是一个数据集,这是大多数深度学习项目的核心。幸运的是,有几个数据集对我们有用。我们最需要的是在不同环境下(高速公路、城市)驾驶数小时所拍摄的图像。你可以在笔记本里找到一本。有了数据集之后,我们需要对数据进行预处理,以使我们的算法更好地工作。例如,我们当然不能将整个数据集加载到 RAM 中,因此我们需要设计一个生成器,,这是 Python 中一种特别有用的函数,它允许动态加载一小批数据,对其进行预处理,然后将其直接输出到我们的神经网络中。为了帮助网络更好地概括每一种可能的天气和光线条件,我们可以随机修改图像的亮度。此外,我们可以裁剪图像的顶部,因为它主要包含天空和其他对驾驶无用的信息。这有助于使整个计算更快。
NVIDIA model.
在预处理之后,我们可以开始设计我们的网络。为此,我使用了 Keras,使其可读性更好。第一款是 NVIDIA 型号,相当经典的 CNN。在一些卷积层之后,从我们的图像中提取视觉特征,我们有一个展平层,然后是完全连接的层,它输出一个单一的实数值:我们的转向角。你可以在代码中看到网络的细节。
如果你在笔记本电脑上训练这个网络,特别是在没有 GPU 加速的情况下,你可能需要一整天来训练它。(但是努力是值得的。大概吧。)在这个相对较小的训练之后,你可以看到验证损失是如何显著减少的,因此网络确实在学习如何驾驶。
这种架构可以在笔记本电脑上实时工作,大约有 500,000 个参数。但是我们可以做得更好,建立一个更小的网络。这就是 SqueezeNet 出现的原因。这种特殊的架构已经很小了,我通过减少卷积特性的数量进一步缩小了它。这个架构的核心是 Fire 模块,这是一个非常巧妙的过滤器块,可以使用很少的参数提取语义上重要的特征,并且输出很少。您可以在代码中看到网络实现的细节。最终的层也被修改,因为我们的任务是图像空间中的回归,而网络最初是为对象识别而设计的。****
The Fire Module.
使用与之前相同的训练设置,我们可以看到训练是如何更快的,并且在大约 10 个时期之后,网络达到甚至更好的性能。
你可能会说,我们在这里预测的转向角仅仅基于当前帧,而驾驶是一项动态任务,也依赖于先前的帧。这就是为什么我在这里展示的最后一个模型是一个循环模型。我在 SqueezeNet 的第一个密集连接层的输出中添加了一个递归层:网络现在将 5 个连续帧作为输入,然后递归层输出一个单一的实数值,即转向角。令人惊讶的是,这种新架构的性能,即使它更接近人类决定如何驾驶的方式,也不比以前看到的架构更好。因此,无记忆和无状态架构可以很好地驱动,从单个帧计算转向角度,独立于其他帧。****
现在,最后,我们网络运行的一个小视频。剧本是从这个非常酷的资料库中截取的。它显示汽车的实时驾驶,转向完全由网络根据它看到的街道来控制。很好,对吧?
Our self-driving car in action.
我们已经用非常简单的架构和技术训练我们的自动驾驶汽车转向,取得了显著的效果。我希望你已经从这篇文章、代码和论文中学到了一两个技巧。欢迎评论或联系!
如何训练张量流模型
原文:https://towardsdatascience.com/how-to-traine-tensorflow-models-79426dabd304?source=collection_archive---------0-----------------------
使用 GPU
近年来,机器学习领域取得了重大进展。这种进步很大程度上可以归功于图形处理单元(GPU)的使用越来越多,以加速机器学习模型的训练。特别是,额外的计算能力导致了深度学习的普及——使用复杂的多层神经网络来创建模型,能够从大量未标记的训练数据中进行特征检测。
GPU 简介
GPU 非常适合深度学习,因为它们被设计来处理的计算类型恰好与深度学习中遇到的计算类型相同。图像、视频和其他图形都表示为矩阵,因此当您执行任何操作(如放大效果或相机旋转)时,您所做的只是对矩阵应用一些数学变换。
实际上,这意味着与中央处理器(CPU)相比,GPU 更擅长执行矩阵运算和其他几种高级数学转换。这使得深度学习算法在 GPU 上的运行速度比 CPU 快好几倍。学习时间通常可以从几天缩短到几个小时。
机器学习中的 GPU
那么,如何使用 GPU 来完成机器学习任务呢?在这篇文章中,我们将探索一个支持 GPU 的 AWS 实例的设置,以在 Tensorflow 中训练神经网络。
首先,在 AWS 控制面板中创建一个新的 EC2 实例。
我们将使用 Ubuntu Server 16.04 LTS (HVM)作为操作系统,但是这个过程在任何 64 位 Linux 发行版上都应该是相似的。
对于实例类型,选择 g2.2xlarge 这些是通过 NVIDIA GRID GPU 启用的。也有几个这样的 GPU 的实例,但利用一个以上需要额外的设置,这将在本文稍后讨论。
使用您首选的安全设置完成设置。
一旦设置和创建完成,SSH 进入您的实例。
Python 应该已经存在于系统中,所以安装所需的库:
sudo apt-get update
sudo apt-get install python-pip python-dev
接下来,安装启用 GPU 支持的 Tensorflow。最简单的方法是:
pip install tensorflow-gpu
但是,对于某些安装,这可能会失败。如果发生这种情况,还有一个替代方案:
export TF_BINARY_URL=https://storage.googleapis.com/tensorflow/linux/gpu/tensorflow_gpu-0.12.1-cp27-none-linux_x86_64.whl
sudo pip install --upgrade $TF_BINARY_URL
如果在 TF 安装过程中得到一个locale.Error: unsupported locale setting
,请输入:
export LC_ALL=C
然后,重复安装过程。
如果不再出现错误,TF 安装就结束了。然而,为了让 GPU 加速正常工作,我们仍然必须安装 Cuda 工具包和 cuDNN。
首先,让我们安装 Cuda 工具包。
开始之前,请注意安装过程将下载大约 3gb 的数据。
wget "http://developer.download.nvidia.com/compute/cuda/repos/ubuntu1604/x86_64/cuda-repo-ubuntu1604_8.0.44-1_amd64.deb"
sudo dpkg -i cuda-repo-ubuntu1604_8.0.44-1_amd64.deb
sudo apt-get update
sudo apt-get install cuda
安装 CUDA 工具包后,下载 cuDNN Library for Linux (注意,您需要注册加速计算开发者计划)并将其复制到您的 EC2 实例中。
sudo tar -xvf cudnn-8.0-linux-x64-v5.1.tgz -C /usr/local
export PATH=/usr/local/cuda/bin:$PATH
export LD_LIBRARY_PATH="$LD_LIBRARY_PATH:/usr/local/cuda/lib64:/usr/local/cuda/extras/CUPTI/lib64"
export CUDA_HOME=/usr/local/cuda
最后,设置过程已经结束,我们可以测试安装了:
python
>>> import tensorflow as tf
>>> sess = tf.Session()
你应该看到Found device 0 with properties: name: GRID K520
>>> hello_world = tf.constant("Hello, world!")
>>> print sess.run(hello_world)
将显示Hello, world!
>>> print sess.run(tf.constant(123)*tf.constant(456))
56088
是正确答案。
系统现在准备好利用带有 Tensorflow 的 GPU。
对 Tensorflow 代码的更改应该是最小的。如果 TensorFlow 操作同时具有 CPU 和 GPU 实现,则将操作分配给设备时,GPU 设备将优先。
如果您想在自己选择的设备上运行一个特定的操作,而不是使用默认的,您可以使用with tf.device
创建一个设备上下文。这将强制该上下文中的所有操作具有相同的设备分配。
# Creates a graph.
with tf.device('/gpu:0'):
a = tf.constant([1.0, 2.0, 3.0, 4.0, 5.0, 6.0], shape=[2, 3], name='a')
b = tf.constant([1.0, 2.0, 3.0, 4.0, 5.0, 6.0], shape=[3, 2], name='b')
c = tf.matmul(a, b)
# Creates a session with log_device_placement set to True.
sess = tf.Session(config=tf.ConfigProto(log_device_placement=True))
# Runs the op.
print sess.run©
如果您想在多个 GPU 上运行 TensorFlow,可以以多塔的方式构建一个模型,并将每个塔分配给不同的 GPU。例如:
# Creates a graph.
c = []
for d in ['/gpu:2', '/gpu:3']:
with tf.device(d):
a = tf.constant([1.0, 2.0, 3.0, 4.0, 5.0, 6.0], shape=[2, 3])
b = tf.constant([1.0, 2.0, 3.0, 4.0, 5.0, 6.0], shape=[3, 2])
c.append(tf.matmul(a, b))
with tf.device('/cpu:0'):
sum = tf.add_n(c)
# Creates a session with log_device_placement set to True.
sess = tf.Session(config=tf.ConfigProto(log_device_placement=True))
# Runs the op.
print sess.run(sum)
利用 GPU 的优势
出于基准测试的目的,我们将使用卷积神经网络(CNN)来识别图像,这是作为 Tensorflow 教程的一部分提供的。CIFAR-10 分类是机器学习中常见的基准问题。任务是将 RGB 32x32 像素图像分为 10 类。
让我们比较在几种流行的配置上训练该模型的性能:
结果
如结果所示,在这个特定示例中,16 个 CPU 的能力与 1 个 GPU 的能力相当。在撰写本文时,同样的训练时间,使用 GPU 也要便宜 18%。
由data art的高级建筑师尼古拉·哈巴罗夫撰写。
如何用数据可视化改造枯燥乏味的报表
原文:https://towardsdatascience.com/how-to-transform-boring-and-dry-reports-with-data-visualization-81fd908bcc62?source=collection_archive---------6-----------------------
研究表明,帮助当今人们应对信息过载的最基本方法之一是将其可视化。通俗地说,这意味着将其绘制成图表,在地图上绘制,甚至使用数据创建交互式图表。
通过可视化地绘制出数据,不仅可以更容易地消化和理解重要信息,还可以更容易地发现关键模式、重要趋势和令人信服的相关性,否则这些可能很难揭示。一句话:你不仅要明白 发生了什么 发生了什么,还要明白 为什么 。
你想讲什么故事?
在创建图表之前,首先理解 为什么 你需要一个图表是至关重要的。请记住,您正在创建一个可视化工具来帮助人们理解复杂的数据,发现模式,识别趋势,并最终实现目标。
您还必须遵循图表最佳实践。首先,这些数字需要相加,你需要相应地调整你的图表。此外,考虑你想要说明多少变量,你想要显示多少数据点,以及你想要如何缩放你的轴。
以下是可以从最新的数据可视化工具中受益的传统商务智能报告/实践类型:
对于会计部门
费用报告
假设您想要生成一份每月支出报告,比较不同类别的支出数据,如差旅、办公用品等。—甚至跨部门。如何快速、轻松地判断某个特定领域何时会增加支出,从而发现节约的机会?
虽然这种趋势在电子表格中很容易被忽略,但条形图可以将数据可视化。这是一种比较信息的简单方法,因为它一眼就能发现高点和低点。会计部门可以向领导或部门主管提供信息,并立即了解面临的挑战。(当他们的打印费用明显高于另一个部门的技术成本时,谁会对他们过度使用复印机犹豫不决呢?)
财务仪表板
随着越来越多的组织将透明度作为员工参与和保留的一种战略,每月一次的“市政厅”变得越来越普遍,在那里共享关键数据。
虽然这是一项勇敢的努力,但简单地向那些可能不会经常与如此大数量的数据打交道的人展示枯燥的收入/利润/支出数据,只会导致每个人都对此视而不见。更糟糕的是,缺乏理解可能会导致员工在没有问题的地方假设有问题。
Image Source
数据可视化使任何人都可以理解这样的报告,而不管分析的舒适度如何。你可以清楚地展示成功的领域和改进的机会。此外,你可以提出多种观点,让员工明白,虽然利润比上个月有所下降,但实际上比去年同月有所上升。
使用数据可视化软件,您还可以使图表和图形具有交互性和可访问性。您可以创建一个仪表板,供员工随时登录,而不是在每月 30 分钟的会议中显示一组数字。这样,他们可以更好地了解公司的日常表现,以及他们的工作对整体的影响。
对于营销和销售团队来说
参与趋势
又到了一年中的这个时候:你那位对营销持怀疑态度的首席执行官希望你写一份报告,反映你的网站在三个月内的页面浏览量。他希望它与收入相对应,以证明你的参与努力的价值。
在折线图中尝试一下。这是一种连接单个数字数据点的简单方法,可以简单直观地显示趋势,以及它们在一段时间内的对应关系。与收入增长相比,您的网站浏览量、电子邮件参与率或广告点击率之间的关系如何?正相关可能表明这种努力是成功的,可以很快让你买入进一步的投资。
CRM 快照
销售线索挖掘可能是一个支离破碎的过程。你观察漏斗的每一步,衡量参与度和转化率,但很难看到全貌。
数据可视化会有所帮助。映射图表可以显示销售线索的每一步,以便轻松发现和解决潜在的障碍。与此同时,您可以注意到加速领域,即销售线索可能转化的领域,并从这些案例中学习最佳实践。
此外,你可以创建买家旅程。随着您将数据可视化工具与您的 CRM 集成,最常见的购买途径将会出现。利用这些趋势来创建旅程和人物角色,为你的未来战略提供信息。
对于人力资源
学习管理报告
学习管理系统 (LMS)正越来越多地被企业用于从合规培训到入职培训、拓展机会和绩效评估的方方面面。一个使用良好的 LMS 可以是关于您最重要的资产——您的员工——的大量数据。然而,如果你不了解这些数据,或者如果个别经理对他们的直接下属有看法,但领导层缺乏全局观念,这些数据可能会被浪费掉。
使用数据可视化,您可以获得员工进展快照,这将有助于您确定表现最佳的员工(可能准备好升职)以及那些发展停滞或落后的员工。
招聘来源报告
许多组织都有分散的招聘流程,由各个经理负责职位发布和候选人招聘。这种支离破碎的过程可能会导致重新创建车轮,关注那些要么不起作用要么导致候选人不合格的招聘策略。
您可以使用数据可视化创建图表,集中了解招聘流程。例如,创建一个饼图,显示您可能使用的各种媒体(社交媒体、电子邮件、招聘信息板等)的招聘来源。您可以为组织创建一个总体图表,还可以为每个部门创建单独的版本。
利用这些信息,你会很快注意到招聘信息板最适合招聘 IT 人员,而你的营销团队中的大多数人都是直接推荐来的。有了这些数据,你就可以了解哪些领域有助于改善你的候选人库,缩短每个职位的招聘时间。
对于技术团队来说
无论您的组织规模如何,您都有机会使用故障单系统向您的 IT 团队报告问题,确定问题的重要性,并跟踪问题直到解决。这些票务工具通常提供易于理解的门票数量和每张门票花费时间的指标,但这并不能说明太多问题。
讲述故事的是事件级别。这些票都是从哪里来的?哪些设备、产品或用户是最大的罪魁祸首?你的组织越大,就越难注意到这种趋势。当 IT 团队可以制定防火计划时,他们却以救火告终。
使用数据可视化,您可以轻松地注意到事件的最大原因,并主动解决它们,以减少整体票证数量。
争夺领导权
Image Source
投资者和顾问委员会希望不断了解他们所支持的企业。对于业务领导来说,定期向他们传达指标可能是一个挑战,他们已经很忙,很难创建可消化的数据,然后有时间回答问题。
数据可视化工具带来了变化。正如您可以创建仅供员工访问的自定义仪表板一样,您也可以为投资者创建仪表板。使用它以视觉上引人注目的方式展示他们最关心的数据,无需指导即可理解。这样,投资者可以在自己的时间登录来检查进展,而你的季度会议可以用来根据这些数据制定战略,而不是在数字中摸索。
眼见为实
由于我们这个社会的注意力持续下降——8 秒钟——并且因为我们不断暴露在海量信息中,所以快速、直观地传达我们的数据至关重要。
数据可视化使我们能够快速理解信息,并调整不同的变量来观察它们的效果。
一张图片真的抵得上一千个字。作为企业所有者或团队经理,你不能只使用原始数据来教育你的利益相关者。
当您将数据可视化时,人们就更容易消化引人注目的见解,因此您可以全面提高关注度、保留率和参与度。
本帖 原版 最早出现在 Visme 的 视觉学习中心 。
如何调优 BigQuery ML 分类模型以达到期望的精度或召回率
原文:https://towardsdatascience.com/how-to-tune-a-bigquery-ml-classification-model-to-achieve-a-desired-precision-or-recall-e4d40b93016a?source=collection_archive---------15-----------------------
基于 ROC 曲线选择概率阈值
BigQuery 为在大型结构化数据集上训练机器学习模型提供了一种令人难以置信的便捷方式。在之前的一篇文章中,我向您展示了如何训练一个分类模型来预测航班延误。以下是预测航班是否会晚点 15 分钟或更久的 SQL 查询:
CREATE OR REPLACE MODEL flights.delayedOPTIONS (model_type='logistic_reg', input_label_cols=['late'],
data_split_method='custom', data_split_col='is_train_row') ASSELECT
IF(arr_delay < 15, 0, 1) AS late,
carrier,
origin,
dest,
dep_delay,
taxi_out,
distance,
is_train_day = 'True' AS is_train_row
FROM
`cloud-training-demos.flights.tzcorr` as f
JOIN `cloud-training-demos.flights.trainday` as t
USING(FL_DATE)
WHERE
arr_delay IS NOT NULL
这将在名为 flights 的数据集中创建一个名为 delayed 的模型。该模型将使用载体、原点等列。作为模型的输入,并预测航班是否会晚点。地面实况来自美国航班到达延误的历史数据。请注意,我已经按天将数据预拆分为一行是训练数据(is_train_day=True)还是应该用于独立评估(is_train_day=False)。这很重要,因为同一天的航班延误往往高度相关。
当训练完成时,BigQuery 报告训练统计数据,但是我们应该查看保留数据集的评估统计数据(is_train_day=False):
SELECT * from ML.EVALUATE(MODEL flights.delayed,
(
SELECT
IF(arr_delay < 15, 0, 1) AS late,
carrier,
origin,
dest,
dep_delay,
taxi_out,
distance
FROM
`cloud-training-demos.flights.tzcorr` as f
JOIN `cloud-training-demos.flights.trainday` as t
USING(FL_DATE)
WHERE
arr_delay IS NOT NULL
AND is_train_day = 'False'
))
这给了我们:
Evaluation statistics for flight delay model
航班延误数据是一个不平衡的数据集——只有 18%的航班晚点(这是我通过实践发现的):
SELECT
SUM(IF(arr_delay < 15, 0, 1))/COUNT(arr_delay) AS fraction_late
FROM
`cloud-training-demos.flights.tzcorr` as f
JOIN `cloud-training-demos.flights.trainday` as t
USING(FL_DATE)
WHERE
arr_delay IS NOT NULL
AND is_train_day = 'True'
在这样一个不平衡的数据集中,准确性并不那么有用,通常有一个业务目标来满足期望的精度(如果 1 更常见)或召回(如果 0 更常见)。
受试者工作特征曲线
一个分类模型实际上返回的是航班晚点的概率;上表中的评估统计数据是通过将该概率阈值设定为 0.5 来计算的。我们可以改变这个阈值,并在不同的阈值下获得精度和召回率。这被称为 ROC 曲线(这是一个可以追溯到雷达时代的首字母缩写词),我们可以让 BigQuery 使用以下方法生成这条曲线:
SELECT * from ML.ROC_CURVE(MODEL flights.delayed,
(
SELECT
IF(arr_delay < 15, 0, 1) AS late,
carrier,
origin,
dest,
dep_delay,
taxi_out,
distance
FROM
`cloud-training-demos.flights.tzcorr` as f
JOIN `cloud-training-demos.flights.trainday` as t
USING(FL_DATE)
WHERE
arr_delay IS NOT NULL
AND is_train_day = 'True'
))
本质上,它和 ML 是一样的。评估查询,除了您使用 ML。ROC _ CURVE 因为我们要调整阈值,所以我们应该对训练数据进行调整(is_train_day=True)。该表返回 101 行,每个阈值都有一个误报率(1 精度)和召回率。默认情况下,阈值基于对训练数据集的百分位数的计算:
Recall, false positive rate, etc. as the probability threshold of the classification model is changed
我们可以点击 BigQuery UI 中的“Explore in Data Studio”链接,得到一个图(设置 false_positive_rate 为维度,recall 为度量):
ROC curve in Data Studio
更有用的观点是将阈值作为维度,将另外两个统计数据作为维度:
Graph the variation of recall and false_positive_rate by threshold in Data Studio and choose the threshold that gives you a recall close to 70%.
我们可以调整阈值来实现一定的回忆(然后你将生活在你得到的任何精度)。假设我们想要确保识别至少 70%的晚点航班,即我们想要 0.7 的召回率。从上图可以看出,概率阈值需要为 0.335。这意味着我们会错误地将 1%的准点航班识别为晚点。
SQL 中的优化概率阈值
下面是一个查询,它将返回阈值,而无需绘制图形并将鼠标悬停在其上:
WITH roc AS (SELECT * from ML.ROC_CURVE(MODEL flights.delayed,
(
SELECT
IF(arr_delay < 15, 0, 1) AS late,
carrier,
origin,
dest,
dep_delay,
taxi_out,
distance
FROM
`cloud-training-demos.flights.tzcorr` as f
JOIN `cloud-training-demos.flights.trainday` as t
USING(FL_DATE)
WHERE
arr_delay IS NOT NULL
AND is_train_day = 'True'
)))SELECT
threshold, recall, false_positive_rate,
**ABS(recall - 0.7) AS from_desired_recall**
FROM roc
**ORDER BY from_desired_recall ASC**
LIMIT 1
这给了我们获得 0.7 召回所需的阈值:
Choosing the threshold that gives us a recall of 0.7.
Nicely tuned! Photo by Ali Morshedlou on Unsplash
用新的概率阈值进行评估和预测
我们可以(对保留的数据集)进行评估,看看我们是否达到了预期的召回率:
SELECT * from ML.EVALUATE(MODEL flights.delayed,
(
SELECT
IF(arr_delay < 15, 0, 1) AS late,
carrier,
origin,
dest,
dep_delay,
taxi_out,
distance
FROM
`cloud-training-demos.flights.tzcorr` as f
JOIN `cloud-training-demos.flights.trainday` as t
USING(FL_DATE)
WHERE
arr_delay IS NOT NULL
AND is_train_day = 'False'
), **STRUCT(0.3348 AS threshold)**)
这给了我们:
We get the hoped-for recall of 70% on the independent evaluation dataset!
万岁!我们在独立评估数据集上也获得了 70%的召回率,所以看起来我们没有过度拟合。
和 ML 一样。评估,当我们进行最大似然预测时,我们可以指定概率的期望阈值:
SELECT * from ML.PREDICT(MODEL flights.delayed,
(
SELECT
IF(arr_delay < 15, 0, 1) AS late,
carrier,
origin,
dest,
dep_delay,
taxi_out,
distance
FROM
`cloud-training-demos.flights.tzcorr` as f
JOIN `cloud-training-demos.flights.trainday` as t
USING(FL_DATE)
WHERE
arr_delay IS NOT NULL
AND is_train_day = 'False'
LIMIT 10
), **STRUCT(0.3348 AS threshold)**)
尽情享受吧!
如何使用 Core ML 在 iOS 11 上使用机器学习模型
原文:https://towardsdatascience.com/how-to-use-a-machine-learning-model-on-ios-11-using-core-ml-24a9d8654df6?source=collection_archive---------2-----------------------
iOS 11 的发布给开发者带来了很多新功能,比如 ARKit 、 Core NFC 等等。对我来说真正突出的一点是增加了核心 ML 。
Core ML 可以让你将任何机器学习模型集成到你的 iOS 应用中。
在本教程中,我将使用一个预先训练好的深度卷积神经网络来确定一张图片是否包含一只猫或一只狗。这是我在学习 DL 时建立的一个非常简单的模型。
先决条件
要完成本教程,您需要:
- 运行 iOS 11 的设备
- Xcode 9
- 受过训练的模特
获取核心 ML 模型
要将您的模型转换为 Core ML ,您需要安装 Apple 提供的命令行工具。
pip install coremltools
接下来,在与模型相同的文件夹中创建一个 python 文件,并添加下面的代码。 image_input_names 和 is_bgr 告诉转换器我们的输入参数将是一个图像。
注意:如果您的模型不是用 Keras 构建的,或者如果您需要关于可用参数的更多信息,您可以查看 Apple 文档。https://apple . github . io/coremltools/coremltools . converters . html
创建后,执行 python 文件来转换您的模型。
python your_file_name.py
将新模型添加到您的应用中
首先,将模型拖到项目导航器中,将模型添加到 Xcode 项目中。将自动生成一个带有模型名称及其属性的新对象。
您可以通过在 Xcode 中打开它来查看有关模型的信息。在查看 mine 时,我们可以看到模型类型和我们在转换模型时配置的输入/输出。
给你的模型拍照
首先实现本地相机来拍摄照片,为我们的模型提供素材。
在 UIImagePickerController 的委托中,我们将进行预测,并提供一个简单的警告来显示我们模型的输出。预测方法将在稍后实现。
调整照片大小
如果你仔细看了我的模型的描述,你会注意到我的输入图像的大小是 64x64。由于我的模型是用特定大小的图像训练的,我们需要将相机中的照片调整到与它们相同的大小。
将 UIImage 转换为 CVPixelBuffer
遗憾的是 Core ML 不允许我们将 UIImage 直接输入到模型中。而是需要转换成支持的类型CVPixelBuffer。我创建了一个简单的扩展来将 UIImage 转换成 CVPixelBuffer。
做预测
现在是有趣的部分!我们将使用我们之前创建的方法来格式化我们的 UIImage,然后将它提供给我们的模型。一旦格式化,我们简单地调用预测方法来获得我们的预测。
Tada!现在,您应该可以从您的模型中获得预测。
你可以在 Github 上找到完整的项目:https://github.com/francoismarceau29/CoreMLCNNDemo
如果你喜欢这篇文章,请一定留下你的关注,你也可以在 twitter 上联系我。
如何使用人工智能检测非数据科学家的开放式问题
原文:https://towardsdatascience.com/how-to-use-ai-to-detect-open-ended-questions-for-non-datascientists-e2ef02427422?source=collection_archive---------6-----------------------
这是一个快速指南,任何人都可以按照它来训练机器学习模型,以检测文本中的开放式问题。
问开放式问题的能力非常重要,无论你是在产品管理、教育、咨询/治疗、销售还是新闻业。从表面上看,区分开放式问题(“你感觉如何?”)与封闭式问题(“你喜欢你的工作吗?”).
人工智能和机器学习
想到聊天机器人、消息服务和其他与人类互动的机器用例,我清楚地意识到,能够问(或至少能够检测)开放式问题将是重要的。这可以帮助指导学生和教师、辅导员和被辅导者、面试官和被面试者(名单还在继续)在网上和机器互动。
但是现在让我们只关注单一的用例;正在检测问题类型。我做的第一件事是在谷歌上搜索一个合适的问题和答案的数据集,上面有问题类型的标签。幸运的是,我发现了这个非常大的亚马逊问答数据集。
观点问答系统中的歧义性、主观性和分歧观点建模
【孟婷】万,朱利安·麦考利
数据挖掘国际会议(ICDM) ,2016通过客户评论解决复杂主观的产品相关查询
朱利安·麦考利,杨顺清
环球网(WWW) ,2016
下载和了解数据集
数据集被分解为亚马逊产品类别,所以我只是随机选择了一个并下载了它。不幸的是,它本质上是一个文本文件,其中每一行都是一个 JSON 对象,并且格式不正确。
这是机器学习的第一个问题。干净的数据集。
我经历了手动清理这些数据的过程,这实际上意味着运行一个 Python 脚本(幸运的是网站的作者提供了这个脚本)来将文件转换成一个格式正确的 JSON 对象列表。
接下来,我需要更改封闭式问题的问题类型标签,因为在字段名中使用“/”会在以后出现问题。我简单地对“是/否”到“是 _ 否”进行了查找和替换。
Some grammar errors
手动检查这些数据,你会发现它并不完美。不是数据集作者的错,主要是问题作者的错。有大量的语法错误、标点符号问题等。
但是没关系。还是看看能不能得到显著的结果吧。
文本类
我最喜欢的训练机器学习模型的方法是从将数据集转换成文本文件开始,然后将它们放入标签为“开放式”和“yes_no”的文件夹中。这不是唯一的方法,或者可能是最好的/最有效的方法,但是因为我不是一个很好的开发人员,我试图通过使用现有的工具来使事情变得简单。我最喜欢的一个是它的文本类。它使用机器框的分类框使用文件夹中的文本文件构建模型。
为了做到这一点,我编写了这个 Go 代码(请—不要评判)来将 JSONs 转换成文件夹中的文本文件。
训练模型
When you run Classificationbox you can visit localhost on port 8080 to see a console
下一步是挑选你最喜欢的机器学习模型创建工具。我的明明是机盒。下载并运行分类框,然后在你所有文本文件所在的文件夹上运行 Textclass 工具。
它将很快对成千上万个例子进行训练(对我来说不到一分钟),然后经历一个验证过程(它将已知的答案与模型预测的进行核对)。
在我第一次运行时,我得到了84%
的准确度。不惊人,但它绝对有资格作为重要的。80%以上的准确率意味着您正在做一些事情,而这种优化很可能会让您获得更高的准确率。这种优化通常意味着进行更多的数据清理、平衡,或者只是有更多的样本。
我首先进行了平衡数据的步骤,这提高了几个点的准确性,然后我回到源位置,下载了几个数据集添加到第一个数据集。经过两轮添加数据和平衡,我能够获得高达87%
的精度。
Textclass CLI output
在这上面只花了一个小时,我感到非常满意,使用机器学习来检测文本中的开放式问题是完全可行的。我强烈建议大家自己试一试,看看会有什么发现。
如何用 API 做一个深度学习卫星图片库?
原文:https://towardsdatascience.com/how-to-use-api-to-make-a-deep-learning-satellite-image-repository-818a5ae2a5fa?source=collection_archive---------2-----------------------
进行任何深度学习实验的最重要的部分之一是从不同的来源提取或收集数据,以获得真实/接近实际的训练样本。现在,在缺乏已经可用的深度学习研究存储库或 kaggle 数据集的情况下,有时我们可能会在尝试我们在特定用例中学习的方法时遇到障碍。这就是神奇的 API 世界来拯救我们的地方。
什么是 API?
以下是维基百科的内容:
在计算机编程中,应用编程接口(API)是一组用于构建应用软件的子例程定义、协议和工具。一般来说,它是各种软件组件之间的一组明确定义的通信方法。一个好的 API 通过提供所有的构建模块,让开发一个计算机程序变得更加容易,然后由程序员把这些模块组合在一起。API 可以用于基于网络的系统、操作系统、数据库系统、计算机硬件或软件库。API 规范可以有多种形式,但通常包括例程、数据结构、对象类、变量或远程调用的规范。POSIX、Windows API 和 ASPI 是不同形式的 API 的例子。 通常提供 API 的文档以方便使用 。
from -https://shareurcodes.com/blog/creating%20a%20simple%20rest%20api%20in%20php
简而言之:API 是一种接口或协议,它允许用户/开发人员从开发的应用程序(如 web 服务器/web 实用工具等)中提取实用程序,而无需理解底层代码或系统。API 可用于获取数据以及更新数据源中的数据。我们在这里将涉及或使用的是 GET 请求,因为我们对数据源感兴趣。
手里的问题是什么?
现在考虑深度学习的图像分类问题,我需要的是一组卫星图像,这些图像被标记为对应的灾难类型。我瞄准的门户网站是https://earthobservatory.nasa.gov/NaturalHazards/
https://earthobservatory.nasa.gov/NaturalHazards/
现在地球观测站是一个门户网站,将有 100 多张图片,现在我需要搜索一个 API 端点,它允许我获取继续分析所需的图片。API 端点是一个 URL,根据 API 文档中提供的规范,可以查询它来搜索您需要的数据。
在浩如烟海的网络世界里搜索了一下,我找到了 https://eonet.sci.gsfc.nasa.gov/。它是关于自然事件的元数据的储存库。这个存储库支持的 API 有一个很好的端点文档。
下面是大多数 API 文档的样子:
https://eonet.sci.gsfc.nasa.gov/docs/v2.1
现在我需要从表格中了解的是:
1)自然事件跟踪器的 API 端点是https://eonet.sci.gsfc.nasa.gov/api/v2.1/events。这就是我对图像元数据的所有查询,都将通过这个 URL 获得。
2)我可以根据来源、状态、限制、天数来查询存储库
3)示例查询-【https://eonet.sci.gsfc.nasa.gov/api/v2.1/events?limit=5 &天数=20 &来源=InciWeb &状态=未结。这给了我下面的 JSON 结果,关于过去 5 天的自然事件,来自 InciWeb 并且仍然开放。
如何有效地编码和获取信息?
现在我们知道了信息存在于何处,但我们仍然需要找到一种最佳方法来做到这一点:
Step-1 使用 python 中的请求来访问 eonet API 端点并获得所需的 json 响应
import requests
parameters={"limit":1000,"days":5000}
response=requests.get('[https://eonet.sci.gsfc.nasa.gov/api/v2/events?status=closed&source=EO'](https://eonet.sci.gsfc.nasa.gov/api/v2/events?status=closed&source=EO'))
print(response.status_code)
代码应该得到 json 响应,您可以使用任何在线可用的 json 到 csv 转换器将其转换为 csv。从 csv 中过滤出您希望作为训练数据一部分保留的图像 URL
步骤 2 现在,当你有了所有你需要下载图片的图片网址。您可以使用以下代码将图像下载到您的硬盘或虚拟机上。
import csv
import urllib
import lxml.html
import requestsconnection = urllib.urlopen(url)with open('location/urls_to_download_2.csv') as csvfile:
csvrows = csv.reader(csvfile, delimiter=',', quotechar='"')
for row in csvrows:
if 'view.php' in row[0]:
filename = row[1]
url = row[0]
locn=row[2]
print (locn)
是的。现在,您已经具备了图像形式的所有必需数据,可以征服卫星图像的深度学习了。只管去做吧!
tf.keras 和 TensorFlow:批量规范化以更快地训练深度神经网络
原文:https://towardsdatascience.com/how-to-use-batch-normalization-with-tensorflow-and-tf-keras-to-train-deep-neural-networks-faster-60ba4d054b73?source=collection_archive---------5-----------------------
训练深度神经网络可能很耗时。特别是,当网络由于梯度(尤其是早期图层中的梯度)已接近零值而停止更新时,梯度消失会严重阻碍训练。合并 Xavier 权重初始化和 ReLu 激活函数有助于解决消失梯度问题。这些技术也有助于解决相反但密切相关的爆炸梯度问题,即梯度变得非常大,从而阻止模型更新。
也许对付渐变消失和爆炸问题的最有力的工具是批量标准化。批量标准化的工作方式如下:对于给定图层中的每个单元,首先计算 z 得分,然后使用两个经过训练的变量𝛾和𝛽.应用线性变换批量标准化通常在非线性激活函数之前完成(见下图),但是在激活函数之后应用也是有益的。查看这堂课了解更多关于这项技术如何工作的细节。
During backpropagation gradients tend to get smaller at lower layers, slowing down weight updates and thus training. Batch Normalization helps combat the so-called vanishing gradients.
在 TensorFlow 中可以通过三种方式实现批量规范化。使用:
tf.keras.layers.BatchNormalization
tf.layers.batch_normalization
tf.nn.batch_normalization
08/18/2018 更新:dnn classifier和dnn regressor现在有了一个 *batch_norm*
参数,这使得用一个固定的估计器进行批量归一化变得可能和容易。
2019 年 11 月 12 日更新:使用 tf.keras,这变得更加容易,你可以简单地添加一个 *BatchNormalization*
层,而不需要担心 control_dependencies。
tf.keras
模块在 1.4 版本中成为核心 TensorFlow API 的一部分。并且提供了用于构建张量流模型的高级 API 所以我会告诉你如何在 Keras 做到这一点。tf.layers.batch_normalization
函数具有类似的功能,但是 Keras 通常被证明是在 TensorFlow 中编写模型函数的更简单的方法。
Note the training variable in the Batch Normalization function. This is required because Batch Normalization operates differently during training vs. the application stage– during training the z score is computed using the batch mean and variance, while in inference, it’s computed using a mean and variance estimated from the entire training set.
In TensorFlow, Batch Normalization can be implemented as an additional layer using tf.keras.layers.
带有tf.GraphKeys.UPDATE_OPS
的第二个代码块很重要。对于网络中的每个单元,TensorFlow 使用tf.keras.layers.BatchNormalization
不断估计训练数据集中权重的平均值和方差。这些然后被存储在tf.GraphKeys.UPDATE_OPS
变量中。训练后,这些存储的值用于在预测时应用批处理规范化。每个单元的训练集平均值和方差可以通过打印extra_ops
来观察,它包含网络中每个层的列表:
print(extra_ops)[<tf.Tensor ‘batch_normalization/AssignMovingAvg:0’ shape=(500,) dtype=float32_ref>, # layer 1 mean values
<tf.Tensor ‘batch_normalization/AssignMovingAvg_1:0’ shape=(500,) dtype=float32_ref>, # layer 1 variances ...]
虽然在tf.nn
模块中也可以使用批量标准化,但是它需要额外的簿记,因为均值和方差是函数的必需参数。因此,用户必须在批处理级别和训练集级别手动计算均值和方差。因此,它是比tf.keras.layers
或tf.layers
更低的抽象层次;避免tf.nn
实现。
MNIST 上的批处理规范化
下面,我使用 TensorFlow 对突出的 MNIST 数据集应用批量归一化。点击查看代码。MNIST 是一个易于分析的数据集,不需要很多图层就可以实现低分类错误。但是,我们仍然可以建立一个深度网络,观察批处理规范化如何影响收敛。
让我们使用[tf.estimator](https://www.tensorflow.org/get_started/custom_estimators)
API 构建一个定制的评估器。首先,我们建立模型:
定义模型函数后,让我们构建定制的估计器,并训练和评估我们的模型:
让我们测试一下批量标准化如何影响不同深度的模型。在我们将代码打包成 Python 包之后,我们可以使用 Cloud ML Engine 并行启动多个实验:
下图显示了达到 90%测试准确度(一个简单的目标)所需的训练迭代次数(1 次迭代包含 500 个批量),作为网络深度的函数。很明显,批量标准化大大加快了深层网络的训练速度。如果没有批标准化,训练步骤的数量会随着每个后续层的增加而增加,但有了批标准化,训练步骤的数量几乎保持不变。实际上,在更复杂的数据集上,更多的图层是成功的先决条件。
Without Batch Normalization the number of training iterations required to hit 90% accuracy increases with the number of layers, likely due to the vanishing gradient effect.
同样,如下图所示,对于一个有 7 个隐层的全连通网络,没有批量归一化的收敛时间明显变慢。
以上实验利用了常用的 ReLu 激活函数。尽管显然不能避免消失梯度效应,如上所示,ReLu 激活比 sigmoid 或 tanh 激活函数要好得多。sigmoid 激活函数对消失梯度的脆弱性是很容易理解的。在较大幅度(非常正或非常负)值时,sigmoid 函数“饱和”,即 sigmoid 函数的导数接近零。当许多节点饱和时,更新次数减少,网络停止训练。
相同的 7 层网络在使用 sigmoid 激活函数而不使用批量标准化的情况下训练明显较慢。当使用 ReLu 时,通过批处理规范化,网络以相似的迭代次数收敛。
另一方面,其他激活函数,如指数 ReLu 或泄漏 ReLu 函数,可以帮助解决消失梯度问题,因为它们对于正大数和负大数都具有非零导数。
最后,值得注意的是,批量标准化会导致额外的培训时间成本。虽然批量标准化通常减少了达到收敛的训练步骤的数量,但是它带来了额外的时间成本,因为它引入了额外的操作,并且还引入了每个单元两个新的训练参数。
For the MNIST classification problem (using a 1080 GTX GPU), Batch Normalization converges in (top) fewer iterations, however the time per iteration is slower. Ultimately, the Batch Normalization version still converges faster (bottom), but the improvement is less pronounced when incorporating total training time.
将 XLA 和融合批处理规范化(tf.layers.batch_normalization
中的融合参数)合并到一个内核中,可以帮助加速批处理规范化操作。
无论如何,批处理规范化对于加速深度神经网络的训练是一个非常有价值的工具。和训练深度神经网络一样,判断一种方法是否对你的问题有帮助的最好方法就是去尝试!
如何利用企业邮件分析揭示隐藏的明星,确保机会均等!
原文:https://towardsdatascience.com/how-to-use-corporate-e-mail-analysis-to-reveal-hidden-stars-and-ensure-equal-opportunities-90bb77d61a7f?source=collection_archive---------13-----------------------
unsplash.com
组织网络分析和沟通内容分析系列文章
1736 年,莱昂哈德·欧拉写了一篇关于柯尼斯堡七座桥的论文。这篇论文被认为是图论史上的第一篇。最近,图论被用于组织沟通领域,它被称为组织网络分析(ONA),基本上是“谁跟谁”。
在遍布全球的大型组织中,寻找领域专家、话题影响者或有效沟通者是一项挑战。意识到这些挑战,我们开始了探索之旅。
本系列文章的重点是电子邮件分析。简单来说,电子邮件包含:发件人、收件人、时间戳、主题和正文。但是,还有更多的字段可用。例如,MS Outlook 定义了关于字段的更多细节,这开启了一个应用 ONA 和数据科学的机会新世界。TrustSphere 也就主题写了一篇很棒的文章。
从某种意义上说,公司的电子邮件交流代表了同事之间的工作关系——这正是 ONA 的意义所在。通过各种分析,我们希望了解并推进人员培养、人才发现和整体组织沟通改善。我们区分了电子邮件网络和内容,以缓解隐私和道德话题。同样的原则也适用于组织中任何形式的现代交流,无论是即时消息、评论还是反馈系统。
基于电子邮件网络的分析
这种方法不使用电子邮件内容。它只关注电子邮件的“发件人”、“收件人”和“时间戳”字段。给某人发送电子邮件会在网络中创建一个边缘。很明显,仅通过分析“已发送”的电子邮件就可以构建整个组织网络(“已发送”的电子邮件将总是进入某人的收件箱)。在我们的实验数据集中,我们排除了邮件列表和外部电子邮件域,同时保留了 CC 和 BCC 收件人,它们在图中可能具有不同的权重。为简单起见,我们暂时将所有权重相同的电子邮件设为 1。我们的方法基于借用图论的 11 个网络度量,如下所示:
我们提出两个最有趣的观点:
- 内部继任计划
- 如果员工离职怎么办
有关这些见解的技术实现的更多信息,请参见第 2 部分。
此外,我们还结合了各种衡量标准,以建议的形式向员工提供进一步的见解,包括如何改善他们的沟通和协作,以及向谁寻求建议和支持。
我们的建议有助于员工实现他们的潜力,并在您的组织中更加引人注目。
这些是我们已经实施的一些建议,但不是最终建议:
- 为了增加你在组织中的影响力,请联系 <用户> 。
- 改善与 <用户> 的沟通与协作。
- 要提高电子邮件沟通技巧,请联系 <用户> 。
- 改善与您的直接下属 <用户> 的沟通。
假设 <用户> 已经同意被推荐。
以下是这些建议的样子:
有关技术实施和指标组合的更多信息,请参见第 3 部分,其中我们重点介绍前两个推荐器示例。
基于电子邮件内容的分析
电子邮件内容是电子邮件分析的另一个来源,但是它意味着更多的隐私问题。我们不断努力改进我们的概念,以解决与隐私相关的话题。如果你想了解更多,请参阅我们的文章《如何利用趋势发现隐藏的明星并致力于一个完美的项目?《人物分析会让你成为明星》,第四部分。
技术实现请参见第五部分。
最后,使用 ONA 和 NLP 实现类似的电子邮件分析需要尽早解决以下问题:
- 职业道德
- 设计的数据隐私
- 机器学习用例
- 产品管理
- 员工接受度
这些话题密切相关,相互依存。例如,今天,如果隐私问题没有在早期得到解决,就很难获得员工的认可,尤其是那些属于 GDPR 领域的产品。在这方面,我们定义了一种解决隐私和 GDPR 的方法,如下所示:
类似地,除非数据隐私和伦理没有得到很好的考虑和整合,否则产品管理无法开发出好的产品。例如,经理可以使用 ONA 指标来惩罚(甚至解雇)员工,而不是做正确的事情。因此,产品管理必须通过他们的解决方案关注员工的改进和能力,同时最小化误用见解和建议的空间。
成功的 ONA 产品实施取决于组织和员工如何跟进,以及公司文化如何处理这些见解。对于组织来说,理解、计划和实施洞察后阶段和过程是至关重要的——这只有在组织领导层的支持下才能实现。这种支持的主要原因与您的组织如何利用获得的信息有关。整个组织必须有向未来组织发展和转型的意愿和支持,在未来组织中,员工是组织发展的焦点。
本文是 ONA @豪夫系列文章的一部分
- 如何利用企业邮件分析揭示隐藏的明星,确保机会均等(Part 1)
- 基于电子邮件网络的见解的技术概述(第 2 部分)
- 深入探讨基于电子邮件网络的推荐(第 3 部分)
- 如何利用趋势发现隐藏的明星,并致力于一个完美的项目?人物分析会让你成为明星
- 如何实现基于电子邮件内容的分析(第 5 部分)
如何在 TensorFlow 中使用数据集
原文:https://towardsdatascience.com/how-to-use-dataset-in-tensorflow-c758ef9e4428?source=collection_archive---------0-----------------------
我在LinkedIn,快来打个招呼 👋
内置的输入管道。再也不用“feed-dict”了
16/02/2020:我已经换成 PyTorch 😍
29/05/2019:我会把教程更新到 tf 2.0😎(我正在完成我的硕士论文)
2018 年 2 月 6 日更新:添加了第二个完整示例,将 csv 直接读入数据集
2018 年 5 月 25 日更新:添加了第二个完整示例,带有一个 可重新初始化的迭代器
更新至 TensorFlow 1.8
您应该知道,feed-dict
是向 TensorFlow 传递信息的最慢方式,必须避免使用。将数据输入模型的正确方法是使用输入管道来确保 GPU 永远不会等待新的东西进来。
幸运的是,TensorFlow 有一个内置的 API,名为 Dataset ,可以更容易地完成这项任务。在本教程中,我们将了解如何创建输入管道,以及如何高效地将数据输入模型。
本文将解释数据集的基本机制,涵盖最常见的用例。
你可以在这里找到 jupyter 笔记本的所有代码:
https://github . com/FrancescoSaverioZuppichini/tensor flow-Dataset-Tutorial/blob/master/Dataset _ Tutorial . ipynb
一般概述
为了使用数据集,我们需要三个步骤:
- 导入数据。从一些数据创建数据集实例
- 创建一个迭代器。通过使用创建的数据集来制作迭代器实例来遍历数据集
- 消费数据。通过使用创建的迭代器,我们可以从数据集中获取元素,以提供给模型
导入数据
我们首先需要一些数据放入我们的数据集
来自 numpy
这是常见的情况,我们有一个 numpy 数组,我们想把它传递给 tensorflow。
# create a random vector of shape (100,2)
x = np.random.sample((100,2))
# make a dataset from a numpy array
dataset = tf.data.Dataset.from_tensor_slices(x)
我们也可以传递不止一个 numpy 数组,一个经典的例子是当我们将一些数据分成特征和标签时
features, labels = (np.random.sample((100,2)), np.random.sample((100,1)))
dataset = tf.data.Dataset.from_tensor_slices((features,labels))
来自张量
当然,我们可以用一些张量初始化我们的数据集
# using a tensor
dataset = tf.data.Dataset.from_tensor_slices(tf.random_uniform([100, 2]))
从占位符
当我们想要动态地改变数据集中的数据时,这是很有用的,我们将在后面看到如何改变。
x = tf.placeholder(tf.float32, shape=[None,2])
dataset = tf.data.Dataset.from_tensor_slices(x)
来自发电机
我们也可以从生成器初始化一个数据集,当我们有一个不同元素长度的数组(例如一个序列)时,这很有用:
# from generator
sequence = np.array([[[1]],[[2],[3]],[[3],[4],[5]]])def generator():
for el in sequence:
yield eldataset = tf.data.Dataset().batch(1).from_generator(generator,
output_types= tf.int64,
output_shapes=(tf.TensorShape([None, 1])))iter = dataset.make_initializable_iterator()
el = iter.get_next()with tf.Session() as sess:
sess.run(iter.initializer)
print(sess.run(el))
print(sess.run(el))
print(sess.run(el))
输出:
[[1]]
[[2]
[3]]
[[3]
[4]
[5]]
在这种情况下,您还需要指定将用于创建正确张量的数据的类型和形状。
从 csv 文件
您可以直接将 csv 文件读入数据集。例如,我有一个 csv 文件,里面有推文和他们的情绪。
tweets.csv
我现在可以通过调用tf.contrib.data.make_csv_dataset
轻松地从它创建一个Dataset
。请注意,迭代器将创建一个字典,以 key 作为列名,以张量的形式使用正确的行值。
# load a csv
CSV_PATH = './tweets.csv'
dataset = tf.contrib.data.make_csv_dataset(CSV_PATH, batch_size=32)
iter = dataset.make_one_shot_iterator()
next = iter.get_next()
print(next) # next is a dict with key=columns names and value=column data
inputs, labels = next['text'], next['sentiment']with tf.Session() as sess:
sess.run([inputs, labels])
next
在哪里
{'sentiment': <tf.Tensor 'IteratorGetNext_15:0' shape=(?,) dtype=int32>, 'text': <tf.Tensor 'IteratorGetNext_15:1' shape=(?,) dtype=string>}
创建迭代器
我们已经看到了如何创建数据集,但是如何取回我们的数据呢?我们必须使用一个Iterator
,这将使我们能够遍历数据集并检索数据的真实值。有四种类型的迭代器。
- 一针。它可以遍历一次数据集,你不能给它任何值。
- 可初始化:可以动态改变调用它的
initializer
操作,用feed_dict
传递新数据。它基本上是一个可以装满东西的桶。 - 可重新初始化:它可以从不同的
Dataset.
初始化,当你有一个训练数据集需要一些额外的变换,例如 shuffle,和一个测试数据集时非常有用。这就像使用塔式起重机来选择不同的容器。 - Feedable : 可以用迭代器选择使用。按照前面的例子,就像一个塔吊选择用哪个塔吊来选择拿哪个集装箱。在我看来是没用的。
一次性迭代器
这是最简单的迭代器。使用第一个例子
x = np.random.sample((100,2))
# make a dataset from a numpy array
dataset = tf.data.Dataset.from_tensor_slices(x)# create the iterator
iter = dataset.make_one_shot_iterator()
然后你需要调用get_next()
来获取包含你的数据的张量
...
# create the iterator
iter = dataset.make_one_shot_iterator()
el = iter.get_next()
我们可以运行el
来查看它的值
with tf.Session() as sess:
print(sess.run(el)) # output: [ 0.42116176 0.40666069]
可初始化迭代器
如果我们想要构建一个动态数据集,可以在运行时改变数据源,我们可以创建一个带有占位符的数据集。然后我们可以使用通用的feed-dict
机制初始化占位符。这是通过一个可初始化的迭代器完成的。使用上一节中的示例三
# using a placeholder
x = tf.placeholder(tf.float32, shape=[None,2])
dataset = tf.data.Dataset.from_tensor_slices(x)data = np.random.sample((100,2))iter = dataset.make_initializable_iterator() # create the iterator
el = iter.get_next()with tf.Session() as sess:
# feed the placeholder with data
sess.run(iter.initializer, feed_dict={ x: data })
print(sess.run(el)) # output [ 0.52374458 0.71968478]
这次我们叫make_initializable_iterator
。然后,在sess
范围内,我们运行initializer
操作来传递我们的数据,在本例中是一个随机的 numpy 数组。。
想象一下,现在我们有一个训练集和一个测试集,这是一个真实的常见场景:
train_data = (np.random.sample((100,2)), np.random.sample((100,1)))
test_data = (np.array([[1,2]]), np.array([[0]]))
然后,我们将训练模型,然后在测试数据集上评估它,这可以通过在训练后再次初始化迭代器来完成
# initializable iterator to switch between dataset
EPOCHS = 10x, y = tf.placeholder(tf.float32, shape=[None,2]), tf.placeholder(tf.float32, shape=[None,1])
dataset = tf.data.Dataset.from_tensor_slices((x, y))train_data = (np.random.sample((100,2)), np.random.sample((100,1)))
test_data = (np.array([[1,2]]), np.array([[0]]))iter = dataset.make_initializable_iterator()
features, labels = iter.get_next()with tf.Session() as sess:
# initialise iterator with train data
sess.run(iter.initializer, feed_dict={ x: train_data[0], y: train_data[1]})
for _ in range(EPOCHS):
sess.run([features, labels])
# switch to test data
sess.run(iter.initializer, feed_dict={ x: test_data[0], y: test_data[1]})
print(sess.run([features, labels]))
可重新初始化的迭代器
这个概念类似于以前,我们要在数据之间动态切换。但是,我们不是向同一个数据集提供新数据,而是切换数据集。和以前一样,我们希望有一个训练数据集和一个测试数据集
# making fake data using numpy
train_data = (np.random.sample((100,2)), np.random.sample((100,1)))
test_data = (np.random.sample((10,2)), np.random.sample((10,1)))
我们可以创建两个数据集
# create two datasets, one for training and one for test
train_dataset = tf.data.Dataset.from_tensor_slices(train_data)
test_dataset = tf.data.Dataset.from_tensor_slices(test_data)
这就是诀窍,我们创建一个泛型迭代器
# create a iterator of the correct shape and type
iter = tf.data.Iterator.from_structure(train_dataset.output_types,
train_dataset.output_shapes)
然后是两个初始化操作:
# create the initialisation operations
train_init_op = iter.make_initializer(train_dataset)
test_init_op = iter.make_initializer(test_dataset)
我们像以前一样得到下一个元素
features, labels = iter.get_next()
现在,我们可以使用我们的会话直接运行两个初始化操作。综上所述,我们得到:
# Reinitializable iterator to switch between Datasets
EPOCHS = 10
# making fake data using numpy
train_data = (np.random.sample((100,2)), np.random.sample((100,1)))
test_data = (np.random.sample((10,2)), np.random.sample((10,1)))
# create two datasets, one for training and one for test
train_dataset = tf.data.Dataset.from_tensor_slices(train_data)
test_dataset = tf.data.Dataset.from_tensor_slices(test_data)
# create a iterator of the correct shape and type
iter = tf.data.Iterator.from_structure(train_dataset.output_types,
train_dataset.output_shapes)
features, labels = iter.get_next()
# create the initialisation operations
train_init_op = iter.make_initializer(train_dataset)
test_init_op = iter.make_initializer(test_dataset)with tf.Session() as sess:
sess.run(train_init_op) # switch to train dataset
for _ in range(EPOCHS):
sess.run([features, labels])
sess.run(test_init_op) # switch to val dataset
print(sess.run([features, labels]))
可馈送迭代器
这非常类似于reinitializable
迭代器,但是它不是在数据集之间切换,而是在迭代器之间切换。在我们创建了两个数据集之后
train_dataset = tf.data.Dataset.from_tensor_slices((x,y))
test_dataset = tf.data.Dataset.from_tensor_slices((x,y))
一个用于培训,一个用于测试。然后,我们可以创建我们的迭代器,在这种情况下我们使用initializable
迭代器,但是你也可以使用one shot
迭代器
train_iterator = train_dataset.make_initializable_iterator()
test_iterator = test_dataset.make_initializable_iterator()
现在,我们需要定义和handle
,这将是一个可以动态改变的占位符。
handle = tf.placeholder(tf.string, shape=[])
然后,与之前类似,我们使用数据集的形状定义一个泛型迭代器
iter = tf.data.Iterator.from_string_handle(
handle, train_dataset.output_types, train_dataset.output_shapes)
然后,我们得到下一个元素
next_elements = iter.get_next()
为了在迭代器之间切换,我们只需调用next_elemenents
操作,并在 feed_dict 中传递正确的handle
。例如,要从训练集中获取一个元素:
sess.run(next_elements, feed_dict = {handle: train_handle})
如果你正在使用initializable
迭代器,就像我们正在做的那样,记得在开始之前初始化它们
sess.run(train_iterator.initializer, feed_dict={ x: train_data[0], y: train_data[1]})
sess.run(test_iterator.initializer, feed_dict={ x: test_data[0], y: test_data[1]})
综上所述,我们得到:
# feedable iterator to switch between iterators
EPOCHS = 10
# making fake data using numpy
train_data = (np.random.sample((100,2)), np.random.sample((100,1)))
test_data = (np.random.sample((10,2)), np.random.sample((10,1)))
# create placeholder
x, y = tf.placeholder(tf.float32, shape=[None,2]), tf.placeholder(tf.float32, shape=[None,1])
# create two datasets, one for training and one for test
train_dataset = tf.data.Dataset.from_tensor_slices((x,y))
test_dataset = tf.data.Dataset.from_tensor_slices((x,y))
# create the iterators from the dataset
train_iterator = train_dataset.make_initializable_iterator()
test_iterator = test_dataset.make_initializable_iterator()
# same as in the doc [https://www.tensorflow.org/programmers_guide/datasets#creating_an_iterator](https://www.tensorflow.org/programmers_guide/datasets#creating_an_iterator)
handle = tf.placeholder(tf.string, shape=[])
iter = tf.data.Iterator.from_string_handle(
handle, train_dataset.output_types, train_dataset.output_shapes)
next_elements = iter.get_next()with tf.Session() as sess:
train_handle = sess.run(train_iterator.string_handle())
test_handle = sess.run(test_iterator.string_handle())
# initialise iterators.
sess.run(train_iterator.initializer, feed_dict={ x: train_data[0], y: train_data[1]})
sess.run(test_iterator.initializer, feed_dict={ x: test_data[0], y: test_data[1]})
for _ in range(EPOCHS):
x,y = sess.run(next_elements, feed_dict = {handle: train_handle})
print(x, y)
x,y = sess.run(next_elements, feed_dict = {handle: test_handle})
print(x,y)
消费数据
在前面的例子中,我们使用了会话来打印数据集中next
元素的值。
...
next_el = iter.get_next()
...
print(sess.run(next_el)) # will output the current element
为了将数据传递给模型,我们必须传递从get_next()
生成的张量
在下面的代码片段中,我们有一个包含两个 numpy 数组的数据集,使用了第一部分中的相同示例。注意,我们需要将.random.sample
包装在另一个 numpy 数组中,以添加一个维度,我们需要这个维度来批量处理数据
# using two numpy arrays
features, labels = (np.array([np.random.sample((100,2))]),
np.array([np.random.sample((100,1))]))dataset = tf.data.Dataset.from_tensor_slices((features,labels)).repeat().batch(BATCH_SIZE)
然后像往常一样,我们创建一个迭代器
iter = dataset.make_one_shot_iterator()
x, y = iter.get_next()
我们制作一个模型,一个简单的神经网络
# make a simple model
net = tf.layers.dense(x, 8) # pass the first value from iter.get_next() as input
net = tf.layers.dense(net, 8)
prediction = tf.layers.dense(net, 1)loss = tf.losses.mean_squared_error(prediction, y) # pass the second value from iter.get_net() as label
train_op = tf.train.AdamOptimizer().minimize(loss)
我们直接使用来自iter.get_next()
的张量作为第一层的输入,并作为损失函数的标签。包装在一起:
EPOCHS = 10
BATCH_SIZE = 16
# using two numpy arrays
features, labels = (np.array([np.random.sample((100,2))]),
np.array([np.random.sample((100,1))]))dataset = tf.data.Dataset.from_tensor_slices((features,labels)).repeat().batch(BATCH_SIZE)iter = dataset.make_one_shot_iterator()
x, y = iter.get_next()# make a simple model
net = tf.layers.dense(x, 8, activation=tf.tanh) # pass the first value from iter.get_next() as input
net = tf.layers.dense(net, 8, activation=tf.tanh)
prediction = tf.layers.dense(net, 1, activation=tf.tanh)loss = tf.losses.mean_squared_error(prediction, y) # pass the second value from iter.get_net() as label
train_op = tf.train.AdamOptimizer().minimize(loss)with tf.Session() as sess:
sess.run(tf.global_variables_initializer())
for i in range(EPOCHS):
_, loss_value = sess.run([train_op, loss])
print("Iter: {}, Loss: {:.4f}".format(i, loss_value))
输出:
Iter: 0, Loss: 0.1328
Iter: 1, Loss: 0.1312
Iter: 2, Loss: 0.1296
Iter: 3, Loss: 0.1281
Iter: 4, Loss: 0.1267
Iter: 5, Loss: 0.1254
Iter: 6, Loss: 0.1242
Iter: 7, Loss: 0.1231
Iter: 8, Loss: 0.1220
Iter: 9, Loss: 0.1210
有用的东西
一批
通常批处理数据是一件痛苦的事情,有了Dataset
API,我们可以使用方法batch(BATCH_SIZE)
以提供的大小自动批处理数据集。默认值为 1。在下面的例子中,我们使用的批量大小为 4
# BATCHING
BATCH_SIZE = 4
x = np.random.sample((100,2))
# make a dataset from a numpy array
dataset = tf.data.Dataset.from_tensor_slices(x).batch(BATCH_SIZE)iter = dataset.make_one_shot_iterator()
el = iter.get_next()with tf.Session() as sess:
print(sess.run(el))
输出:
[[ 0.65686128 0.99373963]
[ 0.69690451 0.32446826]
[ 0.57148422 0.68688242]
[ 0.20335116 0.82473219]]
重复
使用.repeat()
,我们可以指定数据集迭代的次数。如果没有传递参数,它将永远循环下去,通常最好是永远循环下去,用标准循环直接控制历元数。
洗牌
我们可以通过使用方法shuffle()
来打乱数据集,默认情况下,每个时期都会打乱数据集。
记住:打乱数据集对于避免过度适应非常重要。
我们还可以设置参数buffer_size
,一个固定大小的缓冲区,下一个元素将从其中统一选择。示例:
# BATCHING
BATCH_SIZE = 4
x = np.array([[1],[2],[3],[4]])
# make a dataset from a numpy array
dataset = tf.data.Dataset.from_tensor_slices(x)
dataset = dataset.shuffle(buffer_size=100)
dataset = dataset.batch(BATCH_SIZE)iter = dataset.make_one_shot_iterator()
el = iter.get_next()with tf.Session() as sess:
print(sess.run(el))
首次运行输出:
[[4]
[2]
[3]
[1]]
第二轮输出:
[[3]
[1]
[2]
[4]]
没错。它被洗牌了。如果您愿意,也可以设置seed
参数。
地图
您可以使用map
方法将自定义函数应用于数据集的每个成员。在下面的例子中,我们将每个元素乘以 2:
# MAP
x = np.array([[1],[2],[3],[4]])
# make a dataset from a numpy array
dataset = tf.data.Dataset.from_tensor_slices(x)
dataset = dataset.map(lambda x: x*2)iter = dataset.make_one_shot_iterator()
el = iter.get_next()with tf.Session() as sess:
# this will run forever
for _ in range(len(x)):
print(sess.run(el))
输出:
[2]
[4]
[6]
[8]
完整示例
可初始化的迭代器
在下面的例子中,我们使用批处理来训练一个简单的模型,并且我们使用一个可初始化的迭代器在训练和测试数据集之间切换
# Wrapping all together -> Switch between train and test set using Initializable iterator
EPOCHS = 10
# create a placeholder to dynamically switch between batch sizes
batch_size = tf.placeholder(tf.int64)x, y = tf.placeholder(tf.float32, shape=[None,2]), tf.placeholder(tf.float32, shape=[None,1])
dataset = tf.data.Dataset.from_tensor_slices((x, y)).batch(batch_size).repeat()# using two numpy arrays
train_data = (np.random.sample((100,2)), np.random.sample((100,1)))
test_data = (np.random.sample((20,2)), np.random.sample((20,1)))iter = dataset.make_initializable_iterator()
features, labels = iter.get_next()
# make a simple model
net = tf.layers.dense(features, 8, activation=tf.tanh) # pass the first value from iter.get_next() as input
net = tf.layers.dense(net, 8, activation=tf.tanh)
prediction = tf.layers.dense(net, 1, activation=tf.tanh)loss = tf.losses.mean_squared_error(prediction, labels) # pass the second value from iter.get_net() as label
train_op = tf.train.AdamOptimizer().minimize(loss)with tf.Session() as sess:
sess.run(tf.global_variables_initializer())
# initialise iterator with train data
sess.run(iter.initializer, feed_dict={ x: train_data[0], y: train_data[1], batch_size: BATCH_SIZE})
print('Training...')
for i in range(EPOCHS):
tot_loss = 0
for _ in range(n_batches):
_, loss_value = sess.run([train_op, loss])
tot_loss += loss_value
print("Iter: {}, Loss: {:.4f}".format(i, tot_loss / n_batches))
# initialise iterator with test data
sess.run(iter.initializer, feed_dict={ x: test_data[0], y: test_data[1], batch_size: test_data[0].shape[0]})
print('Test Loss: {:4f}'.format(sess.run(loss)))
注意,我们使用了一个批量大小的占位符,以便在训练后动态切换它
输出
Training...
Iter: 0, Loss: 0.2977
Iter: 1, Loss: 0.2152
Iter: 2, Loss: 0.1787
Iter: 3, Loss: 0.1597
Iter: 4, Loss: 0.1277
Iter: 5, Loss: 0.1334
Iter: 6, Loss: 0.1000
Iter: 7, Loss: 0.1154
Iter: 8, Loss: 0.0989
Iter: 9, Loss: 0.0948
Test Loss: 0.082150
可重新初始化的迭代器
在下面的例子中,我们使用批处理训练一个简单的模型,并且我们使用可重新初始化的迭代器在训练和测试数据集之间切换
# Wrapping all together -> Switch between train and test set using Reinitializable iterator
EPOCHS = 10
# create a placeholder to dynamically switch between batch sizes
batch_size = tf.placeholder(tf.int64)x, y = tf.placeholder(tf.float32, shape=[None,2]), tf.placeholder(tf.float32, shape=[None,1])
train_dataset = tf.data.Dataset.from_tensor_slices((x,y)).batch(batch_size).repeat()
test_dataset = tf.data.Dataset.from_tensor_slices((x,y)).batch(batch_size) # always batch even if you want to one shot it
# using two numpy arrays
train_data = (np.random.sample((100,2)), np.random.sample((100,1)))
test_data = (np.random.sample((20,2)), np.random.sample((20,1)))# create a iterator of the correct shape and type
iter = tf.data.Iterator.from_structure(train_dataset.output_types,
train_dataset.output_shapes)
features, labels = iter.get_next()
# create the initialisation operations
train_init_op = iter.make_initializer(train_dataset)
test_init_op = iter.make_initializer(test_dataset)# make a simple model
net = tf.layers.dense(features, 8, activation=tf.tanh) # pass the first value from iter.get_next() as input
net = tf.layers.dense(net, 8, activation=tf.tanh)
prediction = tf.layers.dense(net, 1, activation=tf.tanh)loss = tf.losses.mean_squared_error(prediction, labels) # pass the second value from iter.get_net() as label
train_op = tf.train.AdamOptimizer().minimize(loss)with tf.Session() as sess:
sess.run(tf.global_variables_initializer())
# initialise iterator with train data
sess.run(train_init_op, feed_dict = {x : train_data[0], y: train_data[1], batch_size: 16})
print('Training...')
for i in range(EPOCHS):
tot_loss = 0
for _ in range(n_batches):
_, loss_value = sess.run([train_op, loss])
tot_loss += loss_value
print("Iter: {}, Loss: {:.4f}".format(i, tot_loss / n_batches))
# initialise iterator with test data
sess.run(test_init_op, feed_dict = {x : test_data[0], y: test_data[1], batch_size:len(test_data[0])})
print('Test Loss: {:4f}'.format(sess.run(loss)))
其他资源
张量流数据集教程:https://www.tensorflow.org/programmers_guide/datasets
数据集文档:
https://www.tensorflow.org/api_docs/python/tf/data/Dataset
结论
Dataset
API 为我们提供了一种快速而健壮的方式来创建优化的输入管道,以训练、评估和测试我们的模型。在本文中,我们已经看到了可以用它们进行的大多数常见操作。
你可以用我为这篇文章做的笔记本作为参考。
感谢您的阅读,
弗朗西斯科·萨维里奥
如何使用深度学习来量化传粉者的行为
原文:https://towardsdatascience.com/how-to-use-deep-learning-to-quantify-pollinator-behavior-i-5fc8000a9bde?source=collection_archive---------7-----------------------
在过去的几年里,关于两个看似不相关的话题的新闻变得相当模糊:蜜蜂和其他授粉者的减少,同时,人工智能和数据科学的增加。读了一些关于授粉和授粉如何工作的研究,我意识到尽管已经知道了很多,但是像所有科学一样,还有更多未知的东西。这引发了我的好奇心,难道没有可能将 AI 用于传粉者的研究吗?在这篇文章中,我解释了一个简单的方法。我写了一些代码,可以在我的 github 上找到。(https://github.com/jnnkl/bees_on_dahlia)。但作为一个引子:我想量化这部电影中花的访问量。
获取数据
要做的第一件事是收集数据。我的目标是做一些便宜的东西,所以我买了我能在当地电子商店找到的最便宜的网络摄像机。去年 9 月,我把它带到一个公园,收集了大约 1.5 个小时的一束大丽花的第二组延时照片。这产生了大约 4500 张图片的数据集。我的目标是使用深度学习方法来计算访问每朵花的传粉者的数量。我决定去监督学习,因为这是最容易的。为此,我需要一个带标签的数据集,为此我使用了前 1500 张图像。也就是说,我确实在有昆虫访客和没有昆虫访客的主花中间剪出了正方形。我做了不同大小的方块,并把每只蜜蜂剪了几次。用这种方法,我收集了 635 张有蜜蜂的花的照片,因为花更经常不被访问,而不是被访问,所以有更多没有昆虫的照片。事实证明,花更经常不被参观,而不是参观。为了使数据集平衡,我使用了相似数量的空花图片。
构建网络
我想构建一个包含两类的分类器 1)有昆虫存在,2)没有昆虫存在。我为此使用了卷积神经网络,因为这对图像识别非常有用。由于数据量不多,我选择了迁移学习。因为 VGG16 是安装在我电脑上的 keras 发行版中最小的网络,所以我使用了它。我使用了 keras 的这篇(https://blog . keras . io/building-powerful-image-classification-models-using-very-little-data . html)博文中讨论的技术。在 VGG16 网络之上,我放了一个小的卷积神经网络,训练这个小网络并保存它。接下来,我把整个网络,使前 15 层不可训练,然后用非常小的训练率训练其余部分,以防止过度拟合。我很快得到了超过 92%的准确率。我很幸运能够访问 GPU 集群来进行培训,否则这将需要相当长的时间。
制作电影
现在我可以对有蜜蜂或没有蜜蜂的正方形图像进行分类,是时候用它来检查我的电影中两种主要花卉的昆虫访客数量了。幸运的是,我在一个无风的日子做了延时记录,所以图像相当稳定。所以我简单地确定了两朵花的位置,取了每张照片的这些部分,通过神经网络运行,得到了一个表格,显示了这两朵花的每张照片上是否有昆虫。由于准确性很高,但不太高,我决定只计算那些昆虫的实例,如果至少有两个昆虫的后续实例,类似地,如果它消失的时间短于一秒钟,那么我将其重新分类为。我在我看的地方画了方框,如果没有昆虫就画红色,如果有昆虫就画绿色。这导致了下面的电影:
量化结果和一些讨论
现在我有了一个很好的可视化,这并不是真正的量化让我们来看一些图。在这个图中,花 1 是左上角的花,花 2 是只能看到一半的大花。
它们表明,较大的花得到更多的访问,访问之间的间隔似乎更小。当然,这个简短的测量并不支持任何关于传粉者行为的严肃主张,但这不是我想要的。这个实验的目标是表明深度学习技术可以帮助研究授粉行为,也是以定量的方式。当然,这也可以用经典的图像分析方法来完成。或许,人们可以相对容易地提出一种算法,自动识别昆虫对这些大丽花的访问。然而,他们并不推广到其他花卉。我检查了这个网络是否也适用于其他花的延时。如果是这样的话,我会很幸运,事实上我不得不得出结论,这个网络只为这些花工作。其他花的结构通常比这种特殊的大丽花更多样化,要建立一个网络来检测所有种类的花上的昆虫实际上是相当棘手的。所以如何为其他花和更多背景获得一个好的昆虫检测网络将是后面帖子的一个话题。
A nice picture of a bumblebee on a Rubus flower.
如何使用 ELMo 词向量进行垃圾邮件分类
原文:https://towardsdatascience.com/how-to-use-elmo-word-vectors-for-spam-classification-1891c0da8f1d?source=collection_archive---------10-----------------------
自然语言处理的 Keras 教程
数据集:https://www . ka ggle . com/UC IML/SMS-spam-collection-dataset/version/1 # _ = _
代码:http://hunterheidenreich . com/blog/elmo-word-vectors-in-keras/
如何使用脸书图形 API 和使用 Python 提取数据!
原文:https://towardsdatascience.com/how-to-use-facebook-graph-api-and-extract-data-using-python-1839e19d6999?source=collection_archive---------0-----------------------
大家好,
这是我关于 Medium.com 的第二篇报道。自从第一个故事以来,我已经从挣扎着写代码变成了有点舒服。我写了一个 Python 代码来提取脸书的公开数据。让我们深入研究一下。
获取接入令牌:
为了能够使用 python 代码从脸书提取数据,您需要在脸书上注册为开发人员,然后拥有一个访问令牌。下面是它的步骤。
- 去 developers.facebook.com 链接,在那里创建一个账户。
- 转到链接developers.facebook.com/tools/explorer。
- 转到右上角的“我的应用程序”下拉菜单,选择“添加新应用程序”。选择显示名称和类别,然后“创建应用 ID”。
- 再次回到同一环节developers.facebook.com/tools/explorer。您将在右上角的“我的应用程序”下方看到“图形应用程序资源管理器”。从“图形 API 浏览器”下拉列表中,选择您的应用程序。
- 然后,选择“获取令牌”。从该下拉列表中,选择“获取用户访问令牌”。从出现的菜单中选择“权限”,然后选择“获取访问令牌”
- 转到链接developers.facebook.com/tools/accesstoken。选择“用户令牌”对应的“调试”。转到“扩展令牌访问”。这将确保您的令牌不会每两小时过期一次。
访问脸书公共数据的 Python 代码:
如果你想收集任何公开的数据,请点击链接https://developers.facebook.com/docs/graph-api。参见https://developers . Facebook . com/docs/graph-API/reference/v 2.7/。从这个文档中,选择您想要从中提取数据的任何字段,如“组”或“页”等。在选择了这些代码之后,去看看代码的例子,然后选择“facebook graph api ”,你会得到如何提取信息的提示。这个博客主要是关于获取事件数据。
首先,导入' urllib3 ',' facebook ',' requests ',如果它们已经可用的话。如果没有,请下载这些库。定义一个变量令牌,并将其值设置为上面得到的“用户访问令牌”。
token= ‘aiufniqaefncqiuhfencioaeusKJBNfljabicnlkjshniuwnscslkjjndfi’
获取事件列表:
现在,要查找任何搜索词“诗歌”的事件信息,并将这些事件的数量限制为 10000 个:
graph = facebook.GraphAPI(access_token=token, version = 2.7)
events = graph.request(‘/search?q=Poetry&type=event&limit=10000’)
这将给出一个在脸书上创建的所有事件的字典,并且其名称中有字符串“诗歌”。要获取事件列表,请执行以下操作:
eventList = events[‘data’]
从上面提取的事件列表中提取事件的所有信息:
通过以下方式获取列表中第一个事件的 EventID
eventid = eventList[1][‘id’]
对于此 EventID,获取所有信息并设置一些变量,这些变量将在以后由以下人员使用:
event1 = graph.get_object(id=eventid,
fields=’attending_count,can_guests_invite,category,cover,declined_count,description,end_time,guest_list_enabled,interested_count,is_canceled,is_page_owned,is_viewer_admin,maybe_count,noreply_count,owner,parent_group,place,ticket_uri,timezone,type,updated_time’)
attenderscount = event1[‘attending_count’]
declinerscount = event1[‘declined_count’]
interestedcount = event1[‘interested_count’]
maybecount = event1[‘maybe_count’]
noreplycount = event1[‘noreply_count’]
获取所有参加活动的人的列表,并将响应转换成 json 格式:
attenders = requests.get(“[https://graph.facebook.com/v2.7/](https://graph.facebook.com/v2.7/)"+eventid+"/attending?access_token="+token+”&limit=”+str(attenderscount)) attenders_json = attenders.json()
获取事件的管理员:
admins = requests.get(“[https://graph.facebook.com/v2.7/](https://graph.facebook.com/v2.7/)"+eventid+"/admins?access_token="+token)admins_json = admins.json()
同样,如果您愿意,您可以提取其他信息,如该活动的照片/视频/提要。
进入https://developers . Facebook . com/docs/graph-API/reference/event/查看文档中的“Edges”部分。见图片
现在,让我们说,你想有一个对这个事件感兴趣的所有人的名单,点击“感兴趣的”绿色单词在这里。这将打开新的一页:
在此选择“图形 API 浏览器”。这将打开新的一页:
在这里,输入事件的 id 来代替{event-id},如下所示:
点击提交。此外,在同一页面上,你会发现下面的'获取代码'选项
选择它以查看代码。在出现的弹出窗口中选择“curl ”,然后在 python 代码中获得相同的输出,用 requests.get 编写它,如上面的示例所示。
希望这对那些开始使用 facebook graph API 的人有所帮助。我将很高兴听到你的建议/问题/反馈。
如果你发现这个博客对你有任何价值,如果你对加密货币感兴趣,如果你很慷慨,考虑发送一些涟漪到以下地址:
目的地标签:5973413
钱包地址:rld inlq 5 cjood 9 wdjy 9 zcdgyck 8 kgevkuj
上面的语句中有太多的如果。只有三个都是真的才发送!加密货币 FTW!
如何使用 flickr api 为深度学习实验收集数据?
原文:https://towardsdatascience.com/how-to-use-flickr-api-to-collect-data-for-deep-learning-experiments-209b55a09628?source=collection_archive---------6-----------------------
一旦你踏上了深度学习的旅程,并通过了基本的玩具示例,如在 MNIST 数据集上对手写数字进行分类,下一个合乎逻辑的步骤就是开始从事自己的定制项目。人们遇到的第一个障碍是他们想要做的定制项目的数据可能不可用。如果你知道如何清理网站,你可以很容易地收集到你想要的图片,但是清理网站有两个陷阱:
1.刮一些网站是不合法也不道德的
2.即使你不关心法律或道德,大规模报废也是具有挑战性的,特别是如果有适当的保护措施来阻止报废的话。
除了废弃网络,还有其他选择。以下是您可以在自己的项目中使用图像数据的资源列表:
1.Yelp 公开了大量的数据,他们公开了 20 万张图片的数据集,你可以点击这里查看https://www.yelp.com/dataset
2.这里也有亚马逊评论数据托管在 http://jmcauley.ucsd.edu/data/amazon/也包括预处理的图像特征
3.此外,还有一些数据集,如学术界非常常用的 MS COCO、Imagenet 和 CIFAR 10。
如果这些数据集似乎也不能满足您的目的,那么您可以使用 flickr 作为您的数据收集来源。Flickr 有一个 api 可以用来收集图片。您可以使用这个 api 通过标签搜索图像。例如,您可以搜索日常物品/地点和建筑物的图像,如灯柱、披萨、教堂等。我能够使用这个 api 轻松地为一个给定的标签获取大约 600 多张图片。我能够创建一个脚本,通过标签获取图像,并存储在计算机上的一个文件夹中,该文件夹以被搜索的标签命名。我创建了两个脚本,一个获取给定标记的 url,并将其存储在 csv 文件中。另一个脚本从 url 文件中读取链接,获取图像并将它们存储在一个文件夹中。
下面是通过标签获取 Url 的脚本代码, flickrGetUrl.py (你可以在这里注册获得密钥和应用程序秘密令牌https://www.flickr.com/services/apps/create/
要使用上面的脚本,您可以在终端中运行以下命令:
python flickrGetUrl.py pizza 500
这将在工作目录中创建一个新文件,其中将有指向 pizza 图像的链接,这将是一个名为 pizza.csv 的. csv 文件。第一个参数是您想要其图像的标记,第二个参数是要尝试的 URL 获取的数量。
第二个文件, get_images.py , 从 url 获取图片并将图片存储在一个文件夹中,下面是它的代码:
要使用第二个文件,请在终端中键入以下内容:
python get_images.py pizza.csv
这将从存储在 pizza.csv 中的 URL 获取图像,并将它们存储在一个名为 pizza 的文件夹中。
这些是一些常见的方法,人们可以通过这些方法获取图像数据来运行深度学习实验。请记住,上面的脚本可能需要一些时间来下载图像,您可以通过向它们添加多处理功能并在多核机器上运行它们来加速这些脚本。
如何使用机器学习进行异常检测和状态监控
原文:https://towardsdatascience.com/how-to-use-machine-learning-for-anomaly-detection-and-condition-monitoring-6742f82900d7?source=collection_archive---------0-----------------------
机器学习和统计分析的具体用例
在本文中,我将介绍机器学习和统计分析的几种不同技术和应用,然后展示如何应用这些方法来解决异常检测和状态监控的特定用例。
数字化转型,数字化,工业 4.0 等。
这些都是你以前可能听说过或读到过的术语。然而,在所有这些时髦词汇的背后,主要目标是利用技术和数据来提高生产率和效率。设备和传感器之间的信息和数据的连接和流动允许大量的可用数据。关键的促成因素是能够使用这些大量的可用数据并实际提取有用的信息,从而有可能降低成本、优化容量并将停机时间降至最低。这就是最近围绕机器学习和数据分析的讨论发挥作用的地方。
异常检测
异常检测(或异常值检测)是对罕见项目、事件或观察结果的识别,这些项目、事件或观察结果因与大多数数据显著不同而引起怀疑。通常,异常数据可能与某种问题或罕见事件有关,例如银行欺诈、医疗问题、结构缺陷、设备故障等。这种联系使得挑选出哪些数据点可以被视为异常变得非常有趣,因为从业务角度来看,识别这些事件通常非常有趣。
这给我们带来了一个关键目标:我们如何识别数据点是正常的还是异常的?在一些简单的情况下,如下图所示,数据可视化可以给我们重要的信息。
Figure 1 : Anomaly detection for two variables
在二维数据( X 和 Y )的情况下,通过位于典型分布之外的数据点直观地识别异常变得非常容易。然而,看右边的图,不可能通过调查当时的一个变量直接识别异常值:X 和 Y 变量的组合使我们能够容易地识别异常值。当我们从两个变量扩大到 10-100 个变量时,事情变得非常复杂,这在异常检测的实际应用中是常见的情况。
连接到状态监控
任何机器,无论是旋转机器(泵、压缩机、燃气轮机或蒸汽轮机等。)或非旋转机器(热交换器、蒸馏塔、阀门等)。)最终会达到健康不佳的地步。该点可能不是实际故障或停机的点,而是设备不再以最佳状态运行的点。这表明可能需要一些维护活动来恢复全部运行潜力。简单来说,识别我们设备的“健康状态”是状态监控的领域。
执行状态监控的最常见方法是查看机器的每个传感器测量值,并对其施加最小和最大值限制。如果当前值在界限内,那么机器是健康的。如果当前值超出界限,则机器不健康,并发出警报。
众所周知,这种强加硬编码警报限值的程序会发送大量错误警报,即针对机器实际健康状态的警报。还有漏报警,即有问题但没有报警的情况。第一个问题不仅浪费时间和精力,而且浪费设备的可用性。第二个问题更为关键,因为它会导致真正的损失,以及相关的维修费用和生产损失。
这两个问题都是由同一个原因引起的:一个复杂设备的健康状况无法根据对每个测量值的分析而可靠地判断出来(正如上一节异常检测中的图 1 所示)。我们必须考虑各种测量的组合来获得情况的真实指示
技术部分:
如果不深入一些更技术性的方面,很难涵盖异常检测的机器学习和统计分析主题。我还是会避免太深入理论背景(但是提供一些链接,可以更详细的描述)。如果您对机器学习和统计分析的实际应用更感兴趣,例如状态监控,请直接跳到“状态监控用例”部分。
方法 1:多元统计分析
使用主成分分析的维数减少:PCA
由于处理高维数据通常具有挑战性,有几种技术可以减少变量的数量(维度缩减)。其中一个主要技术是主成分分析 (PCA),它执行数据到低维空间的线性映射,使得低维表示中数据的方差最大化。在实践中,构建数据的协方差矩阵,并计算该矩阵的特征向量。对应于最大特征值(主成分)的特征向量现在可以用于重构原始数据的方差的大部分。原始的特征空间现在已经减少到由几个特征向量跨越的空间(丢失了一些数据,但是希望保留最重要的方差)。
多元异常检测
正如我们上面提到的,为了在处理一两个变量时识别异常,数据可视化通常是一个很好的起点。然而,当将其扩展到高维数据时(实际应用中经常出现这种情况),这种方法变得越来越困难。幸运的是,多元统计学在这方面发挥了作用。
当处理一组数据点时,它们通常具有某种分布(例如高斯分布)。为了以更定量的方式检测异常,我们首先从数据点计算概率分布 p (x)。然后当一个新的例子 x,进来时,我们将 p (x)与一个阈值 r 进行比较。如果 p (x) < r ,则认为是异常。这是因为正常示例倾向于具有大的 p (x ),而异常示例倾向于具有小的 p (x)
在状态监控的情况下,这是很有趣的,因为异常可以告诉我们一些关于被监控设备的“健康状态”的信息:当设备接近故障或次优操作时,生成的数据通常与来自“健康”设备的数据具有不同的分布。
马哈拉诺比斯距离
如上所述,考虑估计数据点属于分布的概率的问题。我们的第一步是找到样本点的质心或质心。直觉上,问题点离这个质心越近,就越有可能属于集合。然而,我们还需要知道这个集合是分布在一个大的范围还是一个小的范围,这样我们就可以决定一个给定的距离中心的距离是否值得注意。最简单的方法是估计样本点到质心距离的标准偏差。通过将其代入正态分布,我们可以推导出数据点属于同一分布的概率。
上述方法的缺点是,我们假设样本点以球形方式围绕质心分布。如果分布确实是非球形的,例如椭球形,那么我们可以预期测试点属于该集合的概率不仅取决于离质心的距离,还取决于方向。在椭球具有短轴的方向上,测试点必须更近,而在长轴的方向上,测试点可以离中心更远。在数学基础上,可以通过计算样本的协方差矩阵来估计最能代表集合概率分布的椭球。 Mahalanobis 距离 (MD)是测试点距离质心的距离除以椭球体在测试点方向的宽度。
为了使用 MD 将测试点分类为属于 N 个类别之一,首先估计每个类别的协方差矩阵,通常基于已知属于每个类别的样本。在我们的例子中,由于我们只对“正常”与“异常”的分类感兴趣,我们使用只包含正常操作条件的训练数据来计算协方差矩阵。然后,给定一个测试样本,我们计算“正常”类别的 MD,如果距离高于某个阈值,则将测试点分类为“异常”。
注意:MD 的使用意味着可以通过均值和协方差矩阵进行推断——这是正态分布独有的特性。在我们的情况下,这个标准不一定满足,因为输入变量可能不是正态分布的。然而,我们还是试了一下,看看效果如何!
方法 2:人工神经网络
自动编码器网络
第二种方法是基于使用自动编码器神经网络。它基于与上述统计分析相似的原理,但略有不同。
自动编码器是一种人工神经网络,用于以无监督的方式学习高效的数据编码。自动编码器的目的是学习一组数据的表示(编码),通常用于维度缩减。随着缩减侧,学习重构侧,其中自动编码器试图从缩减的编码中生成尽可能接近其原始输入的表示。
在架构上,自动编码器的最简单形式是一个前馈,非递归神经网络,非常类似于许多单层感知器,这使得多层感知器(MLP)——具有一个输入层、一个输出层和一个或多个连接它们的隐藏层——但是输出层具有与输入层相同数量的节点,并且目的是重建它自己的输入。
Figure 2: Autoencoder network
在异常检测和状态监控的背景下,基本思想是使用自动编码器网络将传感器读数“压缩”到一个较低维度的表示,该表示捕获各种变量之间的相关性和相互作用。(基本上与 PCA 模型的原理相同,但是这里我们也允许变量之间的非线性相互作用)。
然后,自动编码器网络根据代表“正常”操作状态的数据进行训练,目标是首先压缩,然后重构输入变量。在降维过程中,网络学习各种变量之间的相互作用,并且应该能够在输出端将它们重构回原始变量。主要思想是,随着被监控设备的退化,这将影响变量之间的相互作用(例如,温度、压力、振动等的变化)。).当这种情况发生时,人们将开始看到输入变量的网络重构中的误差增加。通过监控重建误差,可以得到被监控设备的“健康”的指示,因为该误差将随着设备退化而增加。类似于使用马氏距离的第一种方法,我们这里使用重建误差的概率分布来识别数据点是正常还是异常。
状态监控用例:齿轮轴承故障
在本节中,我将介绍一个使用上述两种不同方法进行状态监控的实际用例。由于我们与客户合作的大部分数据都不是公开可用的,我选择用 NASA 提供的数据来演示这两种方法,这些数据可以在这里下载。
对于此用例,目标是检测发动机上的齿轮轴承退化,并发出警告,允许采取预测措施,以避免齿轮故障(例如,可能是设备的计划维护/修理)。
实验细节和数据准备:
三组数据,每组由四个轴承组成,在恒定负载和运行条件下运行至失效。振动测量信号是在轴承的整个寿命期间为数据集提供的,直到发生故障。失败发生在 1 亿次循环后,外环出现裂纹(参见下载页面的自述文件,了解更多关于实验的信息)。由于设备一直运行到发生故障,前两天运行的数据被用作训练数据,以代表正常和“健康”的设备。然后将轴承故障发生前的数据集的剩余部分用作测试数据,以评估不同方法是否能够在故障发生前检测到轴承退化。
方法 1 : PCA + Mahalanobis 距离
正如在本文的“技术部分”中更详细解释的,第一种方法包括首先执行主成分分析,然后计算马氏距离 (MD)以识别数据点是正常还是异常(设备退化的迹象)。代表“健康”设备的训练数据的 MD 分布如下图所示。
Figure 3: Distribution of Mahalanobis distance for “healthy” equipment
使用“健康”设备的 MD 分布,我们可以定义一个阈值来判断什么是异常。根据上述分布,我们可以将 MD > 3 定义为异常。检测设备退化的这种方法的评估现在包括计算测试集中所有数据点的 MD,并将其与定义的阈值进行比较,以将其标记为异常。
测试数据的模型评估:
使用上述方法,我们计算了轴承失效前的测试数据的 MD,如下图所示。
Figure 4: Predicting bearing failure using approach 1
在上图中,绿点对应于计算的 MD,而红线代表用于标记异常的定义阈值。轴承故障发生在数据集的末端,由黑色虚线表示。这说明第一种建模方法能够在实际故障(MD 超过阈值)前大约 3 天检测到即将到来的设备故障。
我们现在可以使用第二种建模方法进行类似的练习,以评估哪种方法比另一种方法性能更好。
方法 2:人工神经网络
正如在论文的“技术部分”中更详细解释的,第二种方法包括使用自动编码器神经网络来寻找异常(通过网络中增加的重建损失来识别)。类似于第一种方法,我们在这里也使用代表“健康”设备的训练数据的模型输出的分布来检测异常。训练数据的重建损失(平均绝对误差)分布如下图所示:
Figure 5 : Distribution of reconstruction loss for “healthy” equipment.
使用“健康”设备的重建损失分布,我们现在可以定义一个阈值来确定什么是异常。根据上述分布,我们可以将大于 0.25 的损失定义为异常。检测设备退化的方法的评估现在包括计算测试集中所有数据点的重建损失,并将该损失与定义的阈值进行比较,以将其标记为异常。
测试数据的模型评估:
使用上述方法,我们计算了轴承失效前的测试数据的重建损失,如下图所示。
Figure 6: Predicting bearing failure using approach 2
在上图中,蓝点对应于重建损失,而红线代表用于标记异常的定义阈值。轴承故障发生在数据集的末端,由黑色虚线表示。这说明这种建模方法也能够在实际故障(其中重建损失超过阈值)之前大约 3 天检测到即将到来的设备故障。
结果摘要:
如以上关于两种不同异常检测方法的章节所示,两种方法都能够在实际故障发生前几天成功检测到即将发生的设备故障。在现实生活中,这将允许在故障之前采取预测措施(维护/修理),这意味着节约成本以及设备故障对 HSE 方面的潜在重要性。
展望:
随着通过传感器捕获数据的成本降低,以及设备之间的连接性增加,能够从数据中提取有价值的信息变得越来越重要。在大量数据中寻找模式是机器学习和统计学的领域,在我看来,利用隐藏在这些数据中的信息来提高几个不同领域的性能有巨大的可能性。本文中提到的异常检测和状态监控只是许多可能性中的一种。(此处也可用)
在未来,我相信机器学习将会被用在比我们今天所能想象的更多的地方。你认为它会对各个行业产生什么影响?我很想在下面的评论中听到你的想法。
编辑:这篇关于异常检测和状态监控的文章收到了很多反馈。我收到的许多问题涉及技术方面以及如何建立模型等。由于这个原因,我决定写一篇后续文章,详细介绍所有必要的步骤,从预处理数据到构建模型和可视化结果。
如果你有兴趣了解更多与人工智能/机器学习和数据科学相关的主题,你也可以看看我写的其他一些文章。你会发现他们都列在我的中型作者简介,中,你可以在这里找到。
而且,如果你想成为一个媒体会员,免费访问平台上的所有资料,你也可以使用下面我的推荐链接。(注意:如果您使用此链接注册,我也会收到一部分会员费)
* [## 通过我的推荐链接加入媒体- Vegard Flovik
作为一个媒体会员,你的会员费的一部分会给你阅读的作家,你可以完全接触到每一个故事…
medium.com](https://medium.com/@vflovik/membership)
更多来自 Vegard Flovik 媒体:
- 蒙特卡洛方法简介
- 从物理学到数据科学的转变
- 什么是图论,为什么要关心?
- 用于图像分类的深度迁移学习
- 建造一个能读懂你思想的人工智能
- 机器学习:从炒作到现实应用
- 人工智能和大数据隐藏的风险
- 供应链管理的人工智能:预测分析和需求预测
- 如何(不)使用机器学习进行时间序列预测:避免陷阱
- 如何利用机器学习进行生产优化:利用数据提高绩效
- 如何向 AI 系统教授物理?
- 我们能否利用纳米级磁铁构建人工大脑网络?
人工智能研讨会——从宣传到现实应用*
如何利用自然语言处理分析产品评论?
原文:https://towardsdatascience.com/how-to-use-natural-language-processing-to-analyze-product-reviews-17992742393c?source=collection_archive---------5-----------------------
在这篇文章中,我将展示如何使用自然语言处理从产品评论中提取关键词(方面)。这个想法实质上是试图复制亚马逊对评论所做的事情。例如,在下图中,你可以看到亚马逊从给定产品的评论中提取关键词,然后允许用户通过这些关键词搜索评论。
Aspect Based Search in Amazon.in
我将试着复制这些关键词产生的过程,然后这些关键词可以用来做各种各样的任务,从基于方面的搜索到基于方面的情感分析。让我们开始吧。
NLP:这是什么?
在我们开始方面提取的任务之前。我们先来了解一下什么是自然语言处理。
NLP,是让计算机理解人类语言的一种尝试。计算机很容易理解编程语言。但是我们如何确保计算机能够理解人类语言呢?要理解 NLP,我们先来了解一下有哪些重大任务可以归为 NLP 任务。
1.标记化:人类可以阅读和理解语言,因为我们可以很容易地识别给定文档中的单词、句子、段落等。大多数 NLP 框架允许计算机理解文本的哪些部分是单词、句子或段落。
2.词性标注:另一个,语言理解的特点是人类能够识别语言中语法成分的能力。例如,我们可以很容易地在给定的句子中找出哪个词充当动词、名词或代词等。NLP 框架允许计算机识别文本中每个单词的语法功能。
3.依存解析:当我们看任何一个句子时,我们不仅能够识别语法元素,还能够识别这些元素在给定句子中是如何以什么是“主语”和什么是“宾语”的形式相互关联的。我们也理解什么是句子中的名词短语,以及它如何与给定句子中的其他短语和单词相关联。NLP 工具包也有助于完成这项任务。
4.共指解析:人类能够轻松破译代词与句子中不同语法元素的关系。例如在文本中
“莫迪指责反对双重标准。他今天在议会提出了这一指控”
我们知道第二句中的“他”指的是莫迪。使用 NLP 框架,人们可以很容易地建立规则来理解文本中的哪个代词指代哪个名词或者与哪个名词短语相关。
5.命名实体识别:对于我们来说,判断一个句子中的单词是否指人、地点、日期、公司实体等是非常自然的。即使我们以前没有见过一个单词,我们也能够正确地猜出这个单词所指的是哪个实体。例如在下面的句子中:
"协和女神宣布给股东 3000 万美元的股息"
虽然我们可能从未听说过“Concordia”是一家公司,但我们仍然可以从句子的上下文中合理地说它是一个公司实体。NLP 框架还有助于计算机理解给定单词所指的“实体”。
提取关键词(方面)
为了复制 amazon 所做的,我将展示如何提取关键字。我将依靠基于规则的方法,这将利用评论的语法结构。这种方法正常工作的假设是,注释一般是以尊重语法规则的方式编写的。我们将使用的语法规则是:
去掉了常用词的文本中最常用的名词将显示文本中的关键词(方面)
为了在产品评论的语料库上实现这个规则,将需要以下预处理。
- 从语料库中提取单词标记。
- 删除常用词
- 提取所有名词
- 找出前 5 个最常用的名词,这些将是关键词/方面
我使用 spacy 来实现我的 NLP 管道。
下面是我写的函数,用于从关于某个特定产品的评论中提取方面,这个产品是一个非常受欢迎的手机品牌。这些评论是由班加罗尔竖锯学院一个学期项目的学生团队收集的。(https://www.jigsawacademy.com/
现场演示:
这里可以看到一个现场演示http://ec2-18-188-32-93 . us-east-2 . compute . Amazon AWS . com:8051/(这是一个比较小的机器,不要征税太多!!!)
下一步?
一旦你能够从产品评论中识别方面,你可以尝试建立一个基于 方面的搜索 或者甚至可以尝试做一个基于 方面的情感 分析。基于方面的情感分析可以用来找出人们对产品不同特性的感受。例如,人们是否普遍对手机的电池寿命感到满意。你可以把这段代码扩展成这样。
如何利用噪音成为你的优势?
原文:https://towardsdatascience.com/how-to-use-noise-to-your-advantage-5301071d9dc3?source=collection_archive---------3-----------------------
Photo by Jason Rosewell on Unsplash
噪音是工程师的头号敌人。
对科学家来说,随机波动或噪声是不受欢迎的。
虽然通常被认为会降低性能,但它有时可以改善非线性系统中的信息处理。在这篇文章中,我们将看到一些例子,噪音可以被用来作为一种优势。
示例 1
向神经网络中添加噪声
最近的工作表明,通过在训练深度神经网络时允许一些不准确性,不仅可以提高训练性能,而且可以提高模型的准确性。
神经网络能够学习输出函数,该函数可以随着输入的微小变化而剧烈变化。向输入中随机添加噪声就像告诉网络不要在你的精确输入周围改变输出。
通过限制网络中的信息量,我们迫使它学习 输入特征的紧凑表示 。
- 变分自动编码器 (VAE) 给隐藏层添加高斯噪声。
- 这种技术迫使网络在有限的带宽下学习有用的信息。
- 具有随机深度的深度网络 :类似于 dropout 的概念,但在每层级别而不是每单元级别。
示例 2
更好地探索参数噪声
RL 是机器学习的一个区域,假设有一个 代理 位于 环境 中。在每一步,代理采取一个 动作 ,并从环境中接收一个 观察 和 奖励 。
给定一个先前未知的环境,RL 算法通过一个通常涉及大量试错的学习过程来寻求最大化代理的总报酬。
为了理解深度 RL 系统探索中的挑战,想想那些在实验室中花费大量时间却没有产生任何实际应用的研究人员。等价地,RL 代理可以花费大量的资源而不收敛到局部最优。
OpenAI 提出了一种称为参数空间噪声的技术,在每集开始时在模型策略参数中引入噪声。
其他方法集中在所谓的动作-空间-噪声上,它们引入噪声来改变与代理从一个时刻到下一个时刻可能采取的每个动作相关联的可能性。
Action-Space-Noise (left) and Parameter-Space-Noise (right)
“我们发现,向强化学习算法的参数中添加自适应噪声经常会提高性能”——open ai
参数-空间-噪声模型的初步结果证明是很有希望的。这项技术有助于算法更有效地探索它们的环境,从而获得更高的分数和更优雅的行为。更多细节可以在研究论文中找到。
要记住的重要事情是,添加噪声被用作提高强化学习算法的探索性能的优势。
示例 3
从有噪声的标签中学习(弱监督训练)
提高识别率并不像向这些系统投放更多标签图像那么简单。事实上,手动注释大量图像是一个昂贵且耗时的过程。
脸书的研究人员和工程师通过在大量带有标签的公共图像上训练图像识别网络来解决这个问题。
由于人们经常给他们的照片加上标签,这将是一个很好的模型训练数据来源。
脸书开发了新的方法,专门用于使用标签监督进行图像识别实验。这项研究在探索弱监督预培训的限制中有详细描述
在 COCO 对象检测挑战中,已经表明使用 hashtags 进行预训练可以将模型的平均精度提高 2%以上。
“标签可以帮助计算机视觉系统超越一般的分类术语,以识别图像中的特定子类别和附加元素。”——脸书
结论
噪音不应该是我们的敌人!它并不总是一种不必要的干扰,经常可以被用作一种优势,甚至是一种有价值的研究工具。如果有人试图告诉你不同的说法,那么,就给他我们提供的例子…
请继续关注,如果你喜欢这篇文章,请留下👏!
参考
[1]弱监督预训练:https://research . FB . com/publications/exploring-the-limits-of-Weakly-supervised-pre training/
[2]带参数噪声的更好探索:https://blog . open ai . com/Better-Exploration-with-Parameter-Noise/
如何在你的电脑上使用 PySpark
原文:https://towardsdatascience.com/how-to-use-pyspark-on-your-computer-9c7180075617?source=collection_archive---------2-----------------------
我发现对于大多数人来说,在本地机器上开始使用 Apache Spark(这里将重点介绍 PySpark)有点困难。有了这个简单的教程,你会很快到达那里!
https://www.mytectra.com/apache-spark-and-scala-training.html
我假设您知道 Apache Spark 是什么,PySpark 也是什么,但是如果您有问题,请不要介意问我!哦,你可以在这里查看我不久前做的一个快速介绍。
$符号将表示在 shell 中运行(但不要复制该符号)。
在 Jupyter 运行 PySpark
- 安装 Jupyter 笔记本
$ pip install jupyter
2.安装 PySpark
确保您的计算机上安装了 Java 8 或更高版本。当然,你也会需要 Python(我推荐 Anaconda 的> Python 3.5)。
现在访问 Spark 下载页面。选择最新的 Spark 版本,这是一个针对 Hadoop 的预构建包,并直接下载。
如果你想得到蜂巢的支持或者更多有趣的东西,你必须自己建立你的星火分布-> 建立星火。
将其解压缩并移动到/opt 文件夹中:
$ tar -xzf spark-2.3.0-bin-hadoop2.7.tgz
$ mv spark-2.3.0-bin-hadoop2.7 /opt/spark-2.3.0
创建一个符号链接(这将让您拥有多个 spark 版本):
$ ln -s /opt/spark-2.3.0 /opt/spark̀
最后,告诉你的 bash(或 zsh 等。)哪里找火花。为此,通过在~/中添加以下行来配置$PATH 变量。bashrc(或者~/。zshrc)文件:
export SPARK_HOME=/opt/spark
export PATH=$SPARK_HOME/bin:$PATH
现在要在 Jupyter 中运行 PySpark,您需要更新 PySpark 驱动程序环境变量。就把这几行加到你的/。bashrc(或者/。zshrc)文件:
export PYSPARK_DRIVER_PYTHON=jupyter
export PYSPARK_DRIVER_PYTHON_OPTS='notebook'
重启你的终端并启动 PySpark:
$ pyspark
现在,这个命令应该在您的 web 浏览器中启动一个 Jupyter 笔记本。点击“新建”>“笔记本 Python[默认]”,创建一个新的笔记本。瞧,您的计算机中有一个 SparkContext 和 SqlContext(或 Spark > 2.x 的 SparkSession ),可以在笔记本中运行 PySpark(运行一些示例来测试您的环境)。
在您最喜欢的 IDE 上运行 PySpark
有时候你需要一个完整的 IDE 来创建更复杂的代码,PySpark 默认不在 sys.path 上,但这并不意味着它不能作为一个常规库使用。您可以通过在运行时将 PySpark 添加到 sys.path 来解决这个问题。findspark 包会帮你做到这一点。
要安装 findspark,只需输入:
$ pip install findspark
然后在您的 IDE 上(我使用 PyCharm)初始化 PySpark,只需调用:
import findspark
findspark.init()import pyspark
sc = pyspark.SparkContext(appName="myAppName")
仅此而已。很简单,对吧?下面是一个完整的独立应用程序示例,用于在本地测试 PySpark(使用上面解释的 conf):
如果你有什么要补充的,或者只是有问题,请提出来,我会尽力帮助你。
编辑由于贡献巨大:)——————>>
Jupyter 笔记本 Python,Scala,R,Spark,Mesos 栈
Docker 就像一个轻量级的“虚拟机”(Docker 技术上提供的是“映像”和“容器”而不是虚拟机。),就好像您有一台完整的第二台计算机,它有自己的操作系统和文件,就在您的真实计算机中。您可以从您的真实计算机登录到这台机器,并像通过 ssh 登录到另一台远程计算机一样使用它。
[## jupyter/docker-stack
Docker-stacks——Docker 中现成的 Jupyter 应用程序的自以为是的堆栈。
github.com](https://github.com/jupyter/docker-stacks/tree/master/all-spark-notebook)
只需到那里并按照步骤操作,就可以获得 Spark 的完整“容器化”版本(2.3 和 Hadoop 2.7)
基本用途
以下命令启动一个容器,笔记本服务器使用随机生成的身份验证令牌在端口 8888 上侦听 HTTP 连接。
$ docker run -it --rm -p 8888:8888 jupyter/pyspark-notebook
Pip 安装
这种打包目前是试验性的,在未来的版本中可能会改变(尽管我们会尽最大努力保持兼容性)。
Spark 的 Python 打包并不打算取代所有其他用例。Spark 的 Python 打包版本适合与现有集群(无论是 Spark standalone、YARN 还是 Mesos)进行交互,但不包含设置您自己的独立 Spark 集群所需的工具。
要安装它,只需运行:
$ pip install pyspark
最初发布在我的 LinkedIn 上。
如果您想联系我,请务必在 twitter 上关注我:
[## 法维奥·巴斯克斯(@法维奥·巴斯克斯)|推特
Favio Vázquez 的最新推文(@FavioVaz)。数据科学家。物理学家和计算工程师。我有一个…
twitter.com](https://twitter.com/faviovaz)
资源:
- 希卡拉
- 阿帕奇火花
- FindSpark
如何使用 Python 为您的研究计算样本大小
原文:https://towardsdatascience.com/how-to-use-python-to-figure-out-sample-sizes-for-your-study-871f0a76a19c?source=collection_archive---------4-----------------------
数据科学家普遍认为,你 80%的时间花在清理数据上,而 20%的时间花在实际分析上。
在做实证研究时,也有类似的问题:通常,在你进入有趣的部分(即看到和解释结果)之前,有大量的工作要做。
实证研究中一个重要的前期活动是计算出你需要的样本量。这一点至关重要,因为它会显著影响您的研究成本和结果的可靠性。收集太多样本:你浪费了金钱和时间。收集太少:你的结果可能没用。
了解您需要的样本大小取决于您计划使用的统计测试。如果这是一个简单的测试,那么找到想要的样本量只需要将数字代入一个等式。然而,它可以更复杂,在这种情况下,像 Python 这样的编程语言可以使生活变得更容易。在这篇文章中,我将讲述其中一个更困难的案例。
场景是这样的 :你正在研究一项旨在增加进入你商店的女性比例的营销活动(比如,改变招牌)。假设你想知道这一变化是否真的增加了女性走过的比例。你计划在改变标志之前和之后收集数据,并确定是否有差异。您将使用一个 双比例 Z 测试 来比较两个比例。您不确定需要多长时间来收集数据以获得可靠的结果——您首先必须计算出需要多少样本!
两比例 Z 检验概述
确定所需样本量的第一步是了解您将使用的静态测试。比例的双样本 Z 检验确定一个人口比例 p1 是否等于另一个人口比例 p2。在我们的示例中,p1 和 p2 分别是营销变化前后进入商店的女性比例,我们希望了解 p2 是否比 p1 有统计学上的显著增加,即 p2 > p1。
该测试检验零假设:p1 — p2 = 0。我们用来检验这种无效假设的检验统计量是:
其中 p*是两个样本中“成功”(即女性进入商店)的比例。即
Z 近似呈正态分布(即~N(0,1)),因此给定两个比例的 Z 分数,您可以根据正态分布查找其值,以查看该值偶然出现的可能性。
那么如何算出我们需要的样本量呢?这取决于几个因素:
- 信心水平: 我们需要有多大的信心来确保结果不是偶然发生的?对于给定的结果差异,以更高的置信度检测它需要更多的样本。这里的典型选择包括 95%或 99%的置信度,尽管这些只是惯例。
- 我们希望能够检测到的百分比差异 :您希望能够检测到的差异越小,需要的样本就越多。
- 您想要检测差异的概率的绝对值: 这有点复杂,对于我们正在进行的特定测试来说有点独特。事实证明,例如,检测 50%和 51%之间的差异与检测 80%和 81%之间的差异需要不同的样本量。换句话说,所需的样本大小是 p1 的函数,而不仅仅是 p1 — p2。
- 数据结果的分布: 假设您想要比较子组内的比例(在我们的例子中,假设您按年龄组细分女性比例)。这意味着您需要在每个亚组中有足够大的样本来进行统计显著性比较。您通常不知道样本在这些组中的表现如何(对某些组来说,获取样本可能要困难得多)。这里至少有几个选择:I)你可以假设样本在各个子群中均匀分布;ii)你可以进行初步测试(例如,在商店外面坐半天,以获得每个年龄组进入商店的女性的初步比例)。
那么,当有这么多因素在起作用时,你如何计算样本量呢?
用 Python 计算样本大小的可能性
最终,我们想要确定我们能够计算 p1 和 p2 之间的差,当它存在的时候。所以,让我们假设你知道 p1 和 p2 之间存在的“真实”差异。然后,我们可以查看 p1 的各种置信水平和绝对水平的样本大小要求。
我们需要一种计算 Z 的方法,这样我们就可以确定给定的样本大小是否提供了具有统计意义的结果,所以让我们定义一个函数,在给定 p1、p2、n1 和 n2 的情况下返回 Z 值。
然后,我们可以定义一个函数,在给定 p1(之前概率)、p_diff(即 p2-p1)和 alpha(表示 p 值,或 1 减去置信水平)的情况下,返回所需的样本。为简单起见,我们假设 n1 = n2。如果你预先知道 n1 的大小大约是 n2 的四分之一,那么把它合并到函数中就很简单了。然而,您通常事先不知道这一点,在我们的场景中,等样本假设似乎是合理的。
该函数非常简单:它从 1 开始从 n 开始计数,直到 n 足够大,其中统计值足够大的概率(即 p 值)小于α(在这种情况下,我们将拒绝 p1 = p2 的零假设)。该函数使用 scipy 库中可用的正态分布来计算 p 值,并将其与 alpha 进行比较。
我们定义的这些函数提供了确定所需最小样本水平所需的主要工具。
如前所述,需要处理的一个复杂问题是,确定 p1 和 p2 之间差异所需的样本取决于 p1 的绝对水平。所以,我们想回答的第一个问题是“什么样的 p1 需要最大的样本量来确定与 p2 的给定差异?”弄清楚这一点,你就可以计算出任何一个 p1 的样本的下限。如果您用最高要求的样本计算 p1 的样本,您知道它将足够用于任何其他 p1。
假设我们希望能够以 95%的置信度计算出 5%的差异,我们需要找到一个 p1,它给出了我们所需的最大样本。我们首先在 Python 中生成一个要查看的所有 p1 的列表,从 0%到 95%,然后对每个差异使用 sample_required 函数来计算样本。
然后,我们用下面的代码绘制数据。
产生了这个图:
该图清楚地表明,p1 = 50%产生最高的样本量。
使用此信息,假设我们想要计算计算 p1 和 p2 之间的差异所需的样本大小,其中 p2 - p1 介于 2%和 10%之间,置信水平为 95%或 99%。为了确保我们得到足够大的样本,我们知道设置 p1 = 50%。我们首先编写代码来构建要绘制的数据框。
然后,我们编写以下代码,用 Seaborn 绘制数据。
最后的结果是这样的情节:
这显示了对于 95%和 99%的置信水平,检测 2%和 10%之间的概率差异所需的最小样本。因此,例如,在 95%的置信水平下检测 2%的差异需要约 3,500 个样本,即 n1 = n2 = 1,750。因此,在我们的例子中,在营销干预之前,你需要大约 1750 人走进商店,之后需要 1750 人在 95%的置信度下检测 2%的概率差异。
结论
这个例子展示了 Python 是如何成为一个非常有用的工具来执行“封底”计算的,比如对测试所需样本量的估计,在这种情况下,这种确定是不直接的。这些计算可以为你节省大量的时间和金钱,尤其是当你考虑为一个研究项目收集你自己的数据时。
原载于 2018 年 7 月 22 日【www.marknagelberg.com】。要访问我共享的 Anki deck 和 Roam Research notes 知识库,以及关于间隔重复和提高学习效率的技巧和想法的定期更新, 加入“下载马克的大脑”。
如何在 Ubuntu 18.04 上将笔记本电脑 GPU 专用于 TensorFlow?
原文:https://towardsdatascience.com/how-to-use-tensorflow-on-the-gpu-of-your-laptop-with-ubuntu-18-04-554e1d5ea189?source=collection_archive---------7-----------------------
使用 Ubuntu 18.04 将笔记本电脑的 100% GPU 内存专用于 TensorFlow 并非如此简单。在这篇文章中,你会找到一个完整的教程,一步一步地去做。
Output of $ nvidia-smi at the end of this post
这篇文章分为三个部分:
- 检查您的 GPU 是否符合 TensorFlow 标准。
- 在您的笔记本电脑上安装合适的驱动程序,TensorFlow 和所有必需的依赖项,以便在您的 GPU 上训练模型。
- 安装自定义驱动程序以确保只有 TensorFlow 可以使用 GPU 内存。
检查您的 GPU 是否符合 TensorFlow 标准。
走向你的终端,输入:
这段代码将列出所有的 PCI 设备,并过滤 NVIDIA 设备。
在我的例子中,前面命令的结果是:
01:00.0 3D controller: NVIDIA Corporation GM108M [GeForce 940MX] (rev a2)
(我的笔记本电脑是小米笔记本 Air 13”配显卡 NVIDIA GeForce 940MX。)
如果什么都没有出现,对不起,但似乎你没有任何 NVIDIA GPU,所以你将无法使用 TensorFlow 与它(但它仍然有可能与你的 CPU!).
如果出现一条线,那我们走!
在您的笔记本电脑上安装合适的驱动程序,TensorFlow 和所有必需的依赖项,以便在您的 GPU 上训练模型。
安装 NVIDIA 专有驱动程序。
配备 NVIDIA 显卡的现代笔记本电脑通常配备 Optimus 技术。Optimus 技术意味着你的笔记本电脑实际上有 2 个图形芯片:第一个位于主板上,靠近 CPU。第二个在你的 NVIDIA 卡上。默认情况下,在 Ubuntu 18.04 上,不使用 NVIDIA 卡。你必须安装特定的驱动程序才能使用它。
要安装它们,非常简单:
- 转到您的软件&更新应用程序
- 点击标签附加驱动
在我的笔记本电脑上,我有:
我们可以看到没有使用 NVIDIA 二进制驱动。要修复它:
- 点击使用 NVIDIA 二进制驱动,然后点击应用更改
- 完成后,重新启动计算机
重新启动计算机后,打开终端写下:
在我的计算机上,我得到了以下结果:
显示 NVIDIA 显卡正在使用中。
CUDA 9.0 工具包安装
TensorFlow 需要 CUDA 9.0 才能使用你的 GPU。让我们安装它。
你应该不要安装其他版本的 CUDA,因为 TensorFlow 不会接受。
- 进入 CUDA 工具包 9.0 下载页面
- 点击 Linux ,然后点击你的架构(可能是 x86_64 ,然后点击 Ubuntu ,然后点击 17.04 (因为用于 Ubuntu 18.04 的 CUDA 9.0 不可用,但我们会做需要做的事情来让它工作),然后点击然后点击 runfile (local) ,然后点击下载 (不要选择除 runfile(本地)之外的其他安装程序类型,否则我们安装 CUDA 会有一些麻烦)。****
- 在控制台中,运行:
不要忘记“ —覆盖”选项,否则安装程序会抱怨它与 GCC 7.3(Ubuntu 18.04 提供的 GCC 版本)不兼容。
“—覆盖”选项将强制安装程序使用可用的 GCC 版本,这很好。
- 阅读 EULA(如果你想的话),然后按下“ q ,然后写下“接受”。
- 关于问题“您正试图在不支持的配置上安装。您希望继续吗?”回答是 。
- 关于“为 Linux-x86_64 384.81 安装 NVIDIA 加速图形驱动?”回答否(非常重要!).
- 关于的问题“安装 CUDA 9.0 工具包?”回答是 。
- 在问题“输入工具箱位置”上点击进入。
- 关于问题“您希望使用‘sudo’运行安装吗?”回答是然后输入你的密码。
- 关于问题“要不要在/usr/local/cuda 安装一个符号链接?”回答是 。
- 关于问题“安装 CUDA 9.0 样品?”回答没有 。
- 安装完成后,在文件 ~/中添加以下两行。bashrc (或者 to ~/。zshrc 如果使用 ZSH
恭喜你!你刚刚在 Ubuntu 18.04 上安装了 CUDA 9.0 !
NVIDIA cuDNN 安装。
TensorFlow 还需要 NVIDIA cuDNN 来使用你的 GPU。让我们安装它。
- 继续 NVIDIA cuDNN 页面。
- 点击下载 cuDNN 。
- 如果您还没有帐户,请创建一个帐户(这是免费的)。
- 点击与 CUDA 9.0 兼容的最新 cuDNN 版本。
- 点击链接 cuDNN … for Linux 。
- 提取下载的文件。
- 从提取的下载文件中,将 cuda/include 的内容复制(可能需要 root 权限)到 /usr/local/cuda/include 。
- 从提取的下载文件中,复制 cuda/lib64 到 /usr/local/cuda/lib64 的所有 libcudnn.so* 文件(可能需要 root 权限)。
(无需复制)。一个"文件)
恭喜你!你刚刚在 Ubuntu 18.04 上安装了 NVIDIA cuDNN !
TensorFlow 和 TensorFlow GPU 安装。
-
如果 pip 尚未安装,用以下工具安装:
-
安装 TensorFlow 和 TensorFlow GPU
如果只安装 TensorFlow , TensorFlow 会使用 CPU。
TensorFlow 安装 TensorFlow GPU 后才会使用 GPU。
恭喜你!你刚刚在 Ubuntu 18.04 上安装了 TensorFlow 和 TensorFlow GPU !
让我们训练一个 MNIST 模特吧!
- 在一个全新的控制台中,下载以下文件。它包含一个简单的全连接(带有一个隐藏层)网络来识别手写数字。
该脚本将训练 5 个时期(这意味着训练集的每个示例将在训练期间被算法看到 5 次)。
出于某种原因,安装完所有这些东西后,第一次培训的第一个时期相当长(在我的电脑上只有 5 分钟)。也许有一些编译,因为在这段时间里,我的一个 CPU 被完全使用。
训练时间比其他所有训练都更“平常”。
在另一个控制台中,您可以编写:
它会每秒刷新一次 nvidia-smi 的输出。当 Python 脚本运行时,您应该在底部看到一行带有进程名:Python 的内容,并为其分配了一定数量的内存。此外, Volatile GPU-Util 应该显示一个工作的 GPU。
恭喜你!你刚刚在装有 Ubuntu 18.04 的笔记本电脑上,用 TensorFlow 和你的 GPU 训练了你的第一个模型!
不幸的是,正如 $ nvidia-smi 的输出所示,你的 GPU 的大量内存被用于其他事情,而不是训练你的模型。
安装自定义驱动程序以确保只有 TensorFlow 可以使用 GPU 内存。
在这一部分,我们将看到如何将你的 GPU 内存 100%奉献给 TensorFlow 。基本上我们会用 NVIDIA 芯片做 TensorFlow ,其余(包括图形显示)用 Intel 芯片。
下载 NVIDIA 驱动程序安装运行文件。
- 进入 NVIDIA 驱动程序安装页面
- 选择您的显卡(如果您想查看 Linux,请不要忘记点击“显示所有操作系统”)。
- 下载文件。
安装自定义 NVIDIA 驱动程序。
暂时,我们需要关闭 X 服务器,这意味着你将无法访问 Ubuntu 的窗口界面(因此也无法访问这篇文章……)。
因此,请打印、写下或在其他设备上打开这篇文章,比如你的手机。
您还需要您的登录名,因此如果您不知道它,只需在控制台中写入:
-
要关闭 X 服务器,在控制台中写入:
-
重启。
-
输入您的登录名和密码。
-
进入您下载驱动程序的文件夹,然后写下:
这个命令行将安装驱动程序而不处理 X 服务器(所以这个驱动程序不会用于图形显示目的)。
- 关于问题“发行版提供的预装脚本失败!您确定要继续吗?”回答继续安装 。
- 关于问题“警告:不会安装 nvidia-drm 模块。因此,DRM-MMS 将无法与此 NVIDIA 驱动程序安装一起使用。
- 关于问题“你想向 DKMS 注册内核模块源代码吗?这将所有 DKMS 自动建立一个新的模块,il fou 安装一个不同的内核后?”回答是 。
- 关于的问题【安装 NVIDIA 的 32 位兼容库】回答否 。
现在应该开始安装驱动程序了。
如果过了一会儿(比如说 5 分钟),安装程序卡在
构建模块上。(这可能需要一段时间)
然后只需按几次回车。如果多次按下 Enter 没有任何作用,只需打开一个新的终端(例如使用 Ctrl + Alt +F3 )并从行“输入您的登录名和密码”重新执行协议。现在应该可以了。
现在,我们必须告诉 NVIDIA 配置工具打开英特尔图形卡,然后我们必须告诉 NVIDIA 配置工具打开 NVIDIA 图形卡,然后我们必须重新启动。不清楚为什么我们应该这样做,但是如果我们不这样做,我们可能会在下次重新启动时卡在“启动的登录服务”上。然后我们必须重新打开 X 服务器。
这最后四个步骤总结如下:
重启后,
现在应该显示:
正如我们所见,没有进程使用 NVIDIA GPU。
现在,如果我们重新运行 MNIST python 文件(这一次,第一个纪元可能需要几分钟),同样的 NVIDIA SMI 命令应该显示:
我们到了!只有 TensorFlow 使用 GPU 内存!
python 脚本完成后,应再次显示消息“未找到正在运行的进程”。
还有一件事:如果你不小心忘记了步骤
“sudo prime-select Intel/NVIDIA” ,如果在重启过程中你陷入了奇怪的状态“Started log in Service”,那么只需等待 5 分钟以获得登录/密码命令/提示,然后再写一次。
机器学习快乐!
如何使用 TorchText 进行神经机器翻译,加上 hack 使其速度提高 5 倍
原文:https://towardsdatascience.com/how-to-use-torchtext-for-neural-machine-translation-plus-hack-to-make-it-5x-faster-77f3884d95?source=collection_archive---------8-----------------------
处理文本是 NLP 中任何成功项目的第一步,幸运的是,帮助我们的工具正在变得越来越复杂。
对于我的第一个深度学习项目,我构建了一个高功能的英法翻译器,如果没有 TorchText 库,我不可能做到这一点。好吧,也许这是一个有点戏剧性的说法…我至少会被大大减慢。
TorchText 非常方便,因为它允许您快速标记和打包(这些是单词吗?)你的数据。原本需要你自己的功能和大量思考的东西现在只需要几行代码,然后,你就可以构建你的人工智能了,它将接管这个世界(或者只是翻译一种语言什么的,我不知道你在计划什么)。
然而,它也不是没有缺点,在这篇文章中,我们还将探讨它最大的低效率以及如何快速规避它。
因此,现在让我们通过浏览我在越来越多的互联网上找到的一些英语-法语数据来探索如何使用 TorchText。
所有翻译数据的始祖
这是我用来训练我的翻译的数据集。
虽然法语和英语之间有许多小型并行数据集,但我想创建一个尽可能强大的翻译器,于是我选择了 big kah una:the European Parliament Proceedings Parallel Corpus 1996–2011(可从这里下载)。
15 years of EU proceedings makes an enthralling read for our seq2seq model!
这个坏男孩包含了 15 年来来自欧盟程序的评论,总计 2007724 个句子,50265039 个单词。
解压缩可下载文件将产生两个文本文件,可以通过以下方式加载:
europarl_en = open('{YOUR_PATH}/europarl-v7.fr-en.en', encoding='utf-8').read().split('\n')
europarl_fr = open('{YOUR_PATH}/europarl-v7.fr-en.fr', encoding='utf-8').read().split('\n')
这给我们留下了两个 python 句子列表,其中每个句子都是另一个句子的翻译。
使用分词器快速处理文本
我们需要做的第一件事是为每种语言创建一个标记器。这是一个将文本分割成独立单词并给它们分配唯一数字(索引)的功能。当我们讨论嵌入时,这个数字将会发挥作用。
Sentences turned into tokens, which are then given individual indexes
下面的代码展示了如何同时使用 Torchtext 和 Spacy 来标记文本。Spacy 是一个专门构建的库,用于获取各种语言的句子,并将它们拆分成不同的标记(更多信息,请参见此处)。没有 Spacy,Torchtext 默认为一个简单的。拆分(“”)的方法进行标记化。这比 Spacy 的方法要少得多,Spacy 的方法也将像“不”这样的词分成“做”和“不”,等等。
import spacy
import torchtext
from torchtext.data import Field, BucketIterator, TabularDataseten = spacy.load('en')
fr = spacy.load('fr')def tokenize_en(sentence):
return [tok.text for tok in en.tokenizer(sentence)]def tokenize_fr(sentence):
return [tok.text for tok in fr.tokenizer(sentence)]EN_TEXT = Field(tokenize=tokenize_en)FR_TEXT = Field(tokenize=tokenize_fr, init_token = "<sos>", eos_token = "<eos>")
在短短几行代码中,我们创建了两个 field 对象,稍后它们将能够处理/标记我们的文本。
使用 Torchtext TabularDataset 构建迭代器
也许与直觉相反,使用 Torchtext 的最佳方式是将数据转换成电子表格格式,不管数据文件的原始格式是什么。
这要归功于 Torchtext TabularDataset 函数令人难以置信的多功能性,它可以从电子表格格式创建数据集。
因此,首先要将我们的数据转换成一个合适的 CSV 文件,我们使用了一点熊猫的魔法:
import pandas as pdraw_data = {'English' : [line for line in europarl_en], 'French': [line for line in europarl_fr]}df = pd.DataFrame(raw_data, columns=["English", "French"])# remove very long sentences and sentences where translations are
# not of roughly equal lengthdf['eng_len'] = df['English'].str.count(' ')
df['fr_len'] = df['French'].str.count(' ')
df = df.query('fr_len < 80 & eng_len < 80')
df = df.query('fr_len < eng_len * 1.5 & fr_len * 1.5 > eng_len')
我们现在必须创建一个验证集。这一步很关键!例如,seq2seq 上的这个 pytorch 教程没有做到这一点,在我自己构建它并使用验证集后,我发现它过度拟合了。
幸运的是,Sklearn 和 Torchtext 一起让这个过程变得异常简单:
from sklearn.model_selection import train_test_split# create train and validation set
train, val = train_test_split(df, test_size=0.1)train.to_csv("train.csv", index=False)
val.to_csv("val.csv", index=False)
这将创建一个 train 和 validation csv,每个 csv 都有两列(英语、法语),其中每行在“英语”列中包含一个英语句子,在“法语”列中包含其法语翻译。
调用 magic TabularDataset.splits 然后返回一个训练和验证数据集,其中加载了相应的数据,并根据我们前面定义的字段进行了处理(/标记化)。
# associate the text in the 'English' column with the EN_TEXT field, # and 'French' with FR_TEXT
data_fields = [('English', EN_TEXT), ('French', FR_TEXT)]train,val = data.TabularDataset.splits(path='./', train='train.csv', validation='val.csv', format='csv', fields=data_fields)
处理几百万字可能需要一段时间,所以在这里喝杯茶吧…
一旦最终完成,我们可以索引所有的令牌:
FR_TEXT.build_vocab(train, val)
EN_TEXT.build_vocab(train, val)
要查看每个字段中的令牌被分配了哪些数字,反之亦然,我们可以使用 self.vocab.stoi 和 self.vocab.itos…这在以后会很方便。
example input: print(EN_TEXT.vocab.stoi['the'])
example_output: 11example input: print(EN_TEXT.vocab.itos[11])
example_output: 'the'
只需多一行代码,我们就有了一个迭代器…
train_iter = BucketIterator(train, batch_size=20, \
sort_key=lambda x: len(x.French), shuffle=True)
让我们来看一个批次的例子,这样我们就可以看到我们到底用所有这些 Torchtext 魔法做了什么…
在每一批中,句子已经被转置,所以它们是垂直下降的(重要:我们将需要再次转置这些句子以使用转换器)。每个索引代表一个单词,每个列代表一个句子。我们有 10 列,因为 10 是我们指定的 batch_size。
你可能会注意到所有的“1 ”,并想这是哪个极其常见的单词的索引?这个“1”当然不是一个词,而是纯粹的填充。事实上,它太多了(这是我们将在下一节中解决的问题)。
..., sort_key = lambda x: len(x.French), ...
最后,这个排序关键字位决定了如何形成每一批。lambda 函数告诉迭代器尝试查找相同长度的句子(这意味着矩阵中更多的是有用的数据,更少的是填充)。
用这么少的几行代码完成了这么多的工作…我们已经将数据处理成了标记,并得到了一个迭代器,它返回匹配的、成批的法语和英语句子,所有的句子都是填充的,等等。
黑客入侵 TorchText 使其效率大大提高
# code from [http://nlp.seas.harvard.edu/2018/04/03/attention.html](http://nlp.seas.harvard.edu/2018/04/03/attention.html)
# read text after for description of what it doesglobal max_src_in_batch, max_tgt_in_batchdef batch_size_fn(new, count, sofar):
"Keep augmenting batch and calculate total number of tokens + padding."
global max_src_in_batch, max_tgt_in_batch
if count == 1:
max_src_in_batch = 0
max_tgt_in_batch = 0
max_src_in_batch = max(max_src_in_batch, len(new.English))
max_tgt_in_batch = max(max_tgt_in_batch, len(new.French) + 2)
src_elements = count * max_src_in_batch
tgt_elements = count * max_tgt_in_batch
return max(src_elements, tgt_elements)class MyIterator(data.Iterator):
def create_batches(self):
if self.train:
def pool(d, random_shuffler):
for p in data.batch(d, self.batch_size * 100):
p_batch = data.batch(
sorted(p, key=self.sort_key),
self.batch_size, self.batch_size_fn)
for b in random_shuffler(list(p_batch)):
yield b
self.batches = pool(self.data(), self.random_shuffler)
else:
self.batches = []
for b in data.batch(self.data(), self.batch_size,
self.batch_size_fn):
self.batches.append(sorted(b, key=self.sort_key))
虽然 Torchtext 很出色,但它基于 sort_key 的批处理还有一些不足之处。通常,句子的长度根本不一样,你最终会向你的网络中输入大量的填充(正如你在最后一个数字的中看到的所有 1)。
此外,如果您的 RAM 每次迭代可以处理 1500 个令牌,并且您的 batch_size 是 20,那么只有当您的批处理长度为 75 时,您才会利用所有的内存。一个有效的批处理机制将根据序列长度改变批处理大小,以确保每次迭代处理大约 1500 个令牌。
这是通过上面在 Torchtext 上运行的补丁批处理代码实现的。我们现在可以创建一个更有效的迭代器,如下所示:
train_iter = MyIterator(trn, batch_size=1300, device=0,
repeat=False, sort_key= lambda x:
(len(x.English), len(x.French)),
batch_size_fn=batch_size_fn, train=True,
shuffle=True)
准备出发!
现在你有了它,一个迭代器,可以部署在任何神经机器翻译模型上。看我的 github 这里,我在我的变形金刚模型的实现中使用了这个代码,你可以在你自己的数据集上尝试这个最先进的 NMT 模型。
如何使用 Twitter 的 API
原文:https://towardsdatascience.com/how-to-use-twitters-api-c3e25c2ad8fe?source=collection_archive---------2-----------------------
为什么要使用 API?API 代表应用程序编程接口(API ),它们允许您访问仅在服务器上可用的资源。让我们学习如何使用 twitters 的 API。
首先,你需要一个 twitter 账户,并附上你的电话号码作为验证。然后你需要去apps.twitter.com并创建应用程序,这样我们就可以引用 Twitter 为该应用程序生成的相应密钥。这些是我们将在应用程序中用来与 Twitter API 通信的键。
现在进入代码,我们需要安装 python-twitter API 库
!pip install python-twitter
确保你理解 Twitters 的 API 使用规则,如果你不遵守他们的规则,他们会阻止你访问数据。这里有一个链接,链接到他们的一些费率限制【https://dev.twitter.com/rest/public/rate-limiting
现在我们有了我们的应用程序,我们有了与应用程序相关联的键。
按键设置
- 消费者密钥——在你的应用页面“密钥和访问令牌”下找到它
- consumer _ secret——位于“密钥和访问令牌”选项卡中的 consumer_key 下方
- access_token_key —您需要点击“生成令牌”按钮来获取此信息
- access_token_secret —按下“生成令牌”后也可用
我们将在下面的函数中插入这些特定的键
import twitter, re, datetime, pandas as pdclass twitterminer():request_limit = 20
api = False
data = []
twitter_keys = {
'consumer_key': , #add your consumer key
'consumer_secret': , #add your consumer secret key
'access_token_key': , #add your access token key
'access_token_secret': #add your access token secret key
}
def __init__(self, request_limit = 20):
self.request_limit = request_limit
# This sets the twitter API object for use internall within the class
self.set_api()
def set_api(self):
self.api = twitter.Api(
consumer_key = self.twitter_keys['consumer_key'],
consumer_secret = self.twitter_keys['consumer_secret'],
access_token_key = self.twitter_keys['access_token_key'],
access_token_secret = self.twitter_keys['access_token_secret']
)def mine_user_tweets(self, user=" set default user to get data from", mine_retweets=False):statuses = self.api.GetUserTimeline(screen_name=user, count=self.request_limit)
data = []
for item in statuses:mined = {
'tweet_id': item.id,
'handle': item.user.name,
'retweet_count': item.retweet_count,
'text': item.text,
'mined_at': datetime.datetime.now(),
'created_at': item.created_at,
}
data.append(mined)
return data
然后,我们需要实例化我们的类,以便能够使用我们上面的函数。
mine = twitterminer()
让我们使用 API 从唐纳德·特朗普的推特上获取一些推文
# insert handle we like
trump_tweets = miner.mine_user_tweets("realDonaldTrump")
trump_df = pd.DataFrame(trump_tweets)
我们现在已经成功地将来自唐纳德·特朗普推特的推文拉到我们的本地机器上进行分析。祝你收集数据顺利。
如何对机器学习任务进行版本控制— I
原文:https://towardsdatascience.com/how-to-version-control-your-machine-learning-task-cad74dce44c4?source=collection_archive---------0-----------------------
什么是版本控制?
软件配置管理、版本控制的一个组成部分,也称为版本控制或源代码控制、【1】是对文档、计算机程序、大型网站以及其他信息集合的变更管理。变更通常由数字或字母代码标识,称为“修订号”、“修订级别”,或简称为“修订”。例如,一组初始文件是“修订版 1”。当进行第一次更改时,结果集是“修订版 2”,依此类推。每个修订都与一个时间戳和做出更改的人相关联。可以比较、恢复修订,还可以合并某些类型的文件。
为什么要版本控制?
一个重要的问题:为什么我们需要版本控制?我在我的本地计算机/云上做任务,一旦模型准备好,并且只有当我完成测试时,我才在我的服务器上部署它。那么为什么我需要版本控制呢?
现在让我们看一个场景:我在一家像 Botsupply 这样的公司工作,我有客户。我是人工智能的家伙。我使用基于 TF-IDF 的模型进行了问答搜索。我把它部署在我的服务器上。在下一阶段,我对它做了一些更改,在我的虚拟数据上,我的准确性增加了。我把它部署在服务器上了。现在,由于测试数据的复杂性,性能下降了。现在我想回到之前的版本。
一种方法是再次部署之前的版本。第二,或者说更好的解决方案是版本控制并恢复到以前的版本。
Source
如何做版本控制?
- 版本控制最流行的方式之一是 Git 。非常受欢迎,基本上每个人都知道如何使用它。(至少是每个程序员和数据科学家)。
现在,Git 真的很酷,但对于一个数据科学家来说,保持 Git 中所有文件夹的同步是一项艰巨的任务。模型检查点和数据大小占用了所有不必要的空间。因此,一种方法是将所有数据集存储在像亚马逊 S3 这样的云服务器中,并将所有可复制的代码存储在 Git 中,并动态生成模型。看起来是一个不错的选择,但是如果在相同的代码中使用多个数据集,将会造成混乱,如果没有正确地记录,从长远来看,可能会导致数据集的混合。
此外,如果数据变更/升级,并且所有的提交没有被正确地记录,模型可能会丢失上下文。
没有上下文的结果比毒药更致命— 乔瓦尼·托奇,僵尸供应
如果文件不能动态复制,可以选择 git-annex 。
[## git-附件
git-annex 允许用 git 管理文件,而不需要将文件内容签入 git。虽然这看起来有些矛盾…
git-annex.branchable.com](https://git-annex.branchable.com/)
2.第二个选择是在沙盒环境中做所有事情,看看结果,如果不好,就不要将更改提交到生产环境中。 Ipython 笔记本(Jupyter Notebook) 就是这么做的好方法。代码可以在不同的单元中分成更小的片段,然后在每一步都可以看到结果,这使得 Ipython 成为机器学习的最佳编辑器之一。
[## Jupyter 项目
Jupyter 笔记本是一个基于网络的交互式计算平台。该笔记本结合了现场代码,方程式…
jupyter.org](https://jupyter.org/)
3.最好的选择(在我看来)是 数据版本控制或者【DVC】。DVC 在许多方面与 Git 相似(如命令结构),但它也提供对步骤的跟踪、步骤之间的依赖关系、代码和数据文件之间的依赖关系以及所有代码运行参数,因此它结合了对代码和数据库的版本控制。
[## 数据版本控制——让您的数据科学项目具有可复制性和可共享性。
阅读有关 dataversioncontrol 的更多信息。数据科学项目 Git。
dataversioncontrol.com](https://dataversioncontrol.com/)
在现实生活中,很难一次性开发出一个好的机器学习模型。ML 建模是一个迭代过程,跟踪您的步骤、步骤之间的依赖关系、代码和数据文件之间的依赖关系以及所有代码运行参数非常重要。DVC,德米特里·彼得罗夫
什么是 DVC 和使用它的 5 个好理由?
DVC 通过自动构建数据依赖图(DAG)使数据科学项目具有可重复性。你的代码和依赖项可以很容易地被 Git 和数据共享——通过云存储(AWS S3,GCP)在一个单一的 DVC 环境中。
Source
- 它是完全开源的,可以用 pip 的简单命令安装:
**pip install dvc** #pip3 for python3
2.命令类似于 git :
**dvc run python train_model.py data/train_matrix.p data/model.p**
3.它是独立于语言的,机器学习过程可以很容易地转换成任何语言的可重复的 DVC 流水线。
4.DVC 不仅可以将你的工作简化到一个单一的、可复制的环境中,它还可以通过 Git 共享这个环境,包括依赖关系(DAG)——这是一个令人兴奋的协作功能,它提供了在不同的计算机上复制研究结果的能力。
5.数据文件可以由任何云文件共享服务共享,如 AWS S3 或 GCP 存储,因为 DVC 不会将数据文件推送到 Git 存储库。
source
要详细了解 DVC 的安装和使用,请查看下面的博文:
[## 数据版本控制测试版:迭代机器学习
在现实生活中,很难一次性开发出一个好的机器学习模型。ML 建模是一种…
blog.dataversioncontrol.com](https://blog.dataversioncontrol.com/data-version-control-beta-release-iterative-machine-learning-a7faf7c8be67)
阅读 第二部分 以了解 DVC 如何在与numeri合作时帮助我进行版本控制,在那里,数据科学家使用机器学习来做出预测,为 numeri 的对冲基金提供动力。
[## 如何对您的机器学习任务进行版本控制— II
这篇文章是上一篇文章的延续:如何对你的机器学习进行版本控制- I。如果你还没有…
medium.com](https://medium.com/@shridhar743/how-to-version-control-your-machine-learning-task-ii-d37da60ef570)
如何用高斯过程可视化黑盒优化问题
原文:https://towardsdatascience.com/how-to-visualise-black-box-optimization-problems-with-gaussian-processes-a6128f99b09d?source=collection_archive---------11-----------------------
更新:我开了一家科技公司。你可以在这里找到更多
缺乏框优化在机器学习中很常见,因为我们试图优化的过程或模型往往没有可以解析求解的代数模型。此外,在目标函数评估昂贵的某些使用情况下,一般方法包括创建目标函数的更简单的替代模型,该替代模型评估起来更便宜,并且将用于解决优化问题。在以前的一篇文章中,我解释了其中一种方法,贝叶斯优化,它使用高斯过程来逼近目标函数。这篇文章是一个 Python 教程,展示了如何使用贝叶斯优化 APIopta as评估和可视化高斯过程代理。
[## 高斯过程贝叶斯优化背后的直觉
在某些应用中,目标函数是昂贵的或难以评估的。在这些情况下,一般…
towardsdatascience.com](/the-intuitions-behind-bayesian-optimization-with-gaussian-processes-7e00fcc898a0)
在本教程中,我们将使用 OPTaaS 来查找由以下公式定义的 Beale 函数的全局最小值:
装置
OPTaaS 在 PyPi 上,可以直接 pip 安装:
!pip install mindfoundry-optaas-client%matplotlib inline
from matplotlib import pyplot as plt
import numpy as npfrom mindfoundry.optaas.client.client import OPTaaSClient, Goal
from mindfoundry.optaas.client.parameter import FloatParameter
连接到 OPTaaS
为了连接到 OPTaaS,您需要一个 API 密钥。你可以在这里得到一个。
client = OPTaaSClient(OPTaaS_URL, OPTaaS_API_key)
创建任务
要开始优化过程,我们需要定义参数并创建一个任务。
parameters = [
FloatParameter(name='x', minimum=-4.5, maximum=4.5),
FloatParameter(name='y', minimum=-4.5, maximum=4.5),
]initial_configurations = 5task = client.create_task(
title='Beale Optimization',
parameters=parameters,
goal=Goal.min,
initial_configurations=initial_configurations,
)configurations = task.generate_configurations(initial_configurations)
然后,我们需要生成一些初始均匀采样配置(5)来加权高斯过程代理模型。
出于本教程的目的,我们将把优化过程分解成几个步骤,但是在一个典型的场景中,我们将简单地运行总迭代次数的任务。
运行任务 5 次迭代
number_of_iterations = 5for i in range(number_of_iterations):
configuration = configurations[i]
x = configuration.values['x']
y = configuration.values['y']
score = beale_function(x, y)
next_configuration = task.record_result(configuration=configuration, score=score)
configurations.append(next_configuration)
既然我们已经用初始配置对代理模型进行了加权,我们将检索它的值来可视化它。
检索代理
我们将从 OPTaaS 生成的代理模型中请求预测。高斯过程替代模型的预测以它们的均值和方差为特征。
random_configs_values = [{'x': np.random.uniform(-4.5, 4.5),
'y': np.random.uniform(-4.5, 4.5)
} for _ in range(1000)]predictions = task.get_surrogate_predictions(random_configs_values)mean = [p.mean for p in predictions]
var = [p.variance for p in predictions]
我们现在将检索对最初 5 种配置的 Beale 函数的评估:
predictions = task.get_surrogate_predictions(random_configs_values)surrogate_X = [[c['x'], c['y']] for c in random_configs_values]
surrogate_X=np.array(surrogate_X)results = task.get_results(include_configurations=True)evaluations_config_values = [r.configuration.values for r in results]
evaluations_score = [r.score for r in results]
绘制代理
我们现在将重新格式化这些值以绘制它们:
xs = [results[i].configuration.values['x'] for i in range(len(results)) ]
ys = [results[i].configuration.values['y'] for i in range(len(results)) ]
zs=evaluations_scorebeale=np.zeros(len(surrogate_X[:,1]))for i in range(len(surrogate_X[:,1])):
beale[i]=beale_function(surrogate_X[i,0], surrogate_X[i,1])
最后,我们将绘制代理函数与实函数的曲线图,并将曲线图与 OPTaaS 所做的函数求值叠加。
plt.clf()
fig = plt.figure(figsize=(20, 10))
ax3d = fig.add_subplot(1, 2, 1, projection='3d')
ax3d.view_init(15, 45)surface_plot = ax3d.plot_trisurf(surrogate_X[:,0], surrogate_X[:,1], np.array(mean), cmap=plt.get_cmap('coolwarm'), zorder=2, label='Surrogate')
surface_plot.set_alpha(0.28)plt.title('Surrogate after 5 iterations')
ax3d.plot(xs, ys,zs, 'x', label='evaluations')plt.xlabel('x')
plt.ylabel('y')ax3d = fig.add_subplot(1, 2, 2, projection='3d')
ax3d.view_init(15, 45)surface_plot_real = ax3d.plot_trisurf(surrogate_X[:,0], surrogate_X[:,1], true, cmap=plt.get_cmap('coolwarm'), zorder=2, label='real')
surface_plot_real.set_alpha(0.28)plt.title('Real')
ax3d.plot(xs, ys,zs, 'x', label='evaluations')display(plt.gcf())plt.close('all')
哪些输出:
正如我们所看到的,代理在 5 次迭代后看起来不太像真正的函数,但我们希望随着评估次数的增加,随着它对底层函数的了解增加,这种情况会有所改变。
代理人的进化
随着迭代次数的增加,代理很快适应了 Beale 函数的更真实的表示。这些图是用与上面相同的代码生成的。
从不同的角度来看,相同的过程显示了 OPTaaS 性能的演变,并突出了接近最优值的推荐的集中程度:
绘制方差的等值线图
我们也可以尝试用等值线图来显示替代变量的变化。蓝色阴影越深,表示相关预测的不确定性越低。
OPTaaS
如果您有任何问题或想了解更多关于 OPTaaS 的信息,您可以查看以下链接:
教程:https://tutorial . opta as . mind foundry . ai
API 文档:https://opta as . mind foundry . ai
研http://www . robots . ox . AC . uk/~ mosb/projects/project/2009/01/01/bayesopt/
如果你仍然好奇,请随时给我发邮件了解更多信息和 API 密钥:Charles . bre cque @ mind foundry . ai
如何使用 Scikit-Learn 在 Python 中可视化随机森林中的决策树
原文:https://towardsdatascience.com/how-to-visualize-a-decision-tree-from-a-random-forest-in-python-using-scikit-learn-38ad2d75f21c?source=collection_archive---------1-----------------------
有助于理解您的模型的实用程序
下面是完整的代码:只需复制并粘贴到 Jupyter 笔记本或 Python 脚本中,用您的数据替换并运行:
Code to visualize a decision tree and save as png (on GitHub here).
最终结果是一个完整的决策树图像。
Decision Tree for Iris Dataset
代码解释
- 创建一个模型训练并提取:我们可以使用一个单独的决策树,但是因为我经常使用随机森林来建模,所以在这个例子中使用了它。(树与树之间会略有不同!).
from sklearn.ensemble import RandomForestClassifier
model = RandomForestClassifier(n_estimators=10)*# Train*
model.fit(iris.data, iris.target)
*# Extract single tree*
estimator = model.estimators_[5]
2。将树导出为。点文件:这利用了 Scikit-Learn 中的export_graphviz
函数。这里有许多参数控制显示的外观和信息。查看文档了解具体信息。
from sklearn.tree import export_graphviz# Export as dot file
export_graphviz(estimator_limited,
out_file='tree.dot',
feature_names = iris.feature_names,
class_names = iris.target_names,
rounded = True, proportion = False,
precision = 2, filled = True)
3。使用系统命令 : 将 **dot**
转换为 **png**
在 Python 中运行系统命令可以方便地执行简单的任务。这需要安装包含点工具的 graphviz。有关转换的完整选项,请查看文档。
# Convert to png
from subprocess import call
call(['dot', '-Tpng', 'tree.dot', '-o', 'tree.png', '-Gdpi=600'])
4。可视化:最好的可视化出现在 Jupyter 笔记本中。(相当于你可以用matplotlib
来显示图像)。
# Display in jupyter notebook
from IPython.display import Image
Image(filename = 'tree.png')
考虑
有了随机森林,每棵树都将被不同地建造。我使用这些图像来展示决策树(以及随后的随机森林)背后的推理,而不是具体的细节。
当您拥有大量要素时,限制树的最大深度会很有帮助。否则,你最终会得到巨大的树,看起来令人印象深刻,但根本无法解读!这是一个包含 50 个特性的完整示例。
Full decision tree from a real problem (see here).
结论
机器学习仍然受到黑箱问题的困扰,一张图片并不能解决问题!尽管如此,观察单个决策树向我们展示了这种模型(和随机森林)并不是一种无法解释的方法,而是一系列逻辑问题和答案——就像我们在进行预测时形成的一样。请随意为您的数据使用和修改这些代码。
和往常一样,我欢迎反馈、建设性的批评以及倾听您的数据科学项目。可以在推特上找到我 @koehrsen_will
如何可视化分布
原文:https://towardsdatascience.com/how-to-visualize-distributions-2cf2243c7b8e?source=collection_archive---------1-----------------------
Source: https://xkcd.com/539/
您已经将所有必要的数据整理成一种清晰的格式,您已经恰当地执行了一个时髦的统计分析,现在是分析结果的时候了。这就是可视化数据派上用场的地方。信息丰富的数据可视化不仅揭示了新颖的见解,也许你正在和某人约会,但你并不知道,但当你要向老板/客户传达你的发现时,它们真的是非常宝贵的。
这篇文章将专门研究我一次又一次面临的可视化任务。在分析数据的这些年里,我经常发现自己想要比较和对比数字数据的多种分布。这可能很棘手,取决于分布的不同程度,以及分布的大量可能的表示方法(http://www . darkhorsanalytics . com/blog/visualizing-distributions-3)。当比较分布时,我通常有两个目标,或者我想突出它们异常值的差异,或者,通常是它们各自分布的细微差异。也许我想展示用不同标准收集的数据集如何对统计程序做出不同的反应,或者应用统计校正如何改进评分函数。
如果我对比较异常值感兴趣,我倾向于箱线图。箱线图显示数据的总体分布,同时绘制异常值的数据点。这一物理点使得它们的特定值很容易在样品中识别和比较。
让我们忽略数据的实际意义,因为这并不重要。您可以看到分布的分布或多或少是相等的,异常值很容易比较。红色/洋红色分布具有最极端的异常值,后面是我从绿色分布中着色为红色的点。对于这个分析,红色分布已经预先计算过了,我能够通过观察极端异常值来重现他们的数据。然而,红点是一个新奇的观察。
如果你是一个关注绘图轴并了解一些统计数据的人,那么你可能已经意识到我对我的数据集应用了一个统计变换,以便放大分布异常值中的差异。我将我的数字分布转换成一个 z 值。z 得分通过测量数据点偏离样本均值的标准偏差数来转换数据点。
我通常为分布图做的第一个可视化是直方图。你可以在这里看到这是一个可怕的和无信息的方式来看待数据。使用这种方法,不同组之间样本大小的差异使得它们不可比较。它是如此的极端,以至于你再也看不到蓝色的分布。这种可视化在比较甚至看到异常值方面也是失败的。从这个图像中我唯一能得出的结论是红色和绿色的分布有大致相同的意思。
虽然我认为箱线图是这种情况下的最佳选择,但它们看起来非常正式,人们通常不知道如何正确地解释它们(四分位数范围,分布,说什么?).此外,箱线图无法洞察用于创建它们的样本大小。对于不太在意统计的观众来说,带状图更直观,因为他们可以看到所有的数据点。该图还显示了分布的样本量。我喜欢在点上应用抖动和不透明度,让这些图更吸引人。
让我们跳到第二种情况,我们感兴趣的是比较分布的分布。在这里,如果被比较的分布具有相同的样本大小,并且您最多进行 3 次比较,直方图是一个很好的选择。否则,你会得到一个非常繁忙的图,很难看到数据。
在这些情况下,我倾向于没有填充的内核密度图。它不是很漂亮,但是你可以看到和比较分布。在最近的一个项目中,为了克服这一点,我决定在直方图上实现一个旋转,并使用一种叫做阶梯图的变体,效果很好。如果你的图变得笨拙,我建议改变你表示数据的方式。
但是如果你想要全部呢?!在这种情况下,我喜欢使用小提琴情节。我看到这些情节变得越来越受欢迎,还有许多变化,使他们更加强大。它们本质上是箱线图,周围有一个旋转的核密度图。在这里,我绘制了旋转内核密度图内的箱线图。
这就是我现在能给你的。我使用 r 中的 ggplot2 包制作了上面所有的图。我还使用 matplotlib 和 seaborne 在 python 中制作了相当多的图。案例 2 中使用的数据集是使用 R 附带的 airquality 数据集完成的,另一个数据集是我自己为我的硕士论文构建的。
代码可以在这个库中找到。如果你愿意,请随意添加图表,如果你认为有更好的方法来分析分布,请在评论中告诉我!
Pixabay.com
如何使用 Plotly R 可视化多元轨迹置信区间
原文:https://towardsdatascience.com/how-to-visualize-multivariate-trajectory-confidence-intervals-using-plotly-r-da345d084bd6?source=collection_archive---------4-----------------------
Simulated datasets — 3D lines with confidence bands drawn with Plotly R
统计学或机器学习中的任何概率回归方法都会产生一个折线图以及相关的置信区间,通常定义为平均值周围的两个标准差。尽管 Plotly 拥有许多强大的图表工具,可用于绘制二维或三维图表,并可为 2D 折线图绘制误差线或置信区间,但它没有在三维折线图或曲面图中绘制置信区间的选项。
多元挑战
许多有趣的概率回归任务本质上是多元的;例如,跨位置坐标 x 预测时间 t 上的数据值 z。该预测的结果将是表示时间 t 上每个点 x 处的预期值 z 的 3D 表面,以及每个值点处的相关误差的估计。这种类型的表面图在表面拓扑探测中很常见,其中传感器网格在目标空间内的每个网格点捕获数据。在 Plotly 中,该网格将被很好地可视化为跨所有 x,y 坐标的数据值的 3D 表面图,但是 Plotly 不呈现跨该表面的置信边界。
轨迹
通常问题的领域局限于通过目标空间的轨迹,而不是整个领域的完整探索。例如,想象一个火箭轨道,在飞行的每个纬度和经度上都标有发动机温度的测量值。温度数据是在相对于位置的每个点捕获的,但是位置数据是整个子午线空间的子集,仅沿着火箭的轨迹测量。这在建模和可视化时,以图形方式显示为一条穿过温度、高度和经度的 3D 空间中的轨迹的温度线,而不是表面。Plotly 允许我们画出这条轨迹,但它不允许我们轻易地在这条线上画出上下置信区间。我们可以重构计算,以显示温度与高度的关系,如 2D 图,但这样我们会失去空间分辨率,例如,将无法区分火箭向外飞行的方向与向内、向地球飞行的轨迹,在不同的时间穿越相同的高度,这将给我们的回归分析带来问题。
如何绘制三维置信区间
显示的图表是模拟数据的渲染图,代表样本数据在 x,y 平面上的三个轨迹,z 显示每个点的数据值,带显示置信上限和置信下限。直接沿 z 轴向下看,可以看到置信带位于 z 平面内,因为误差是相对于数据值显示的,而观察到的 x 和 y 观察点被假设为是已知的,没有误差。这是回归分析中通常采用的方法,通常假设我们可以精确地获得测量坐标。
Projection down z axis
用于创建这些图的 R 代码使用 Plotly mesh3D 图表类型来构建向上和向下指向的交错三角形的表面,这些三角形链接在一起以在数据值的平面中形成连续的表面。
所描述的方法是完全通用的,并且可以用于创建任何形式的表面,例如在 3D 绘图表面上构造上下边界表面。使用这种方法的唯一限制是表面重叠的复杂性,当在平面图像中渲染时,会使眼睛感到困惑,而不是作为情节动态可视化。
r 代码
*#R code for 3D confidence error intervals*
install.packages("plotly")
library(plotly)
*# Generate Simulated Data Points*
x <- seq(-5,5, .1)
y <- seq(0, 10, .1)
y <- cbind(y, sin(y), cos(y))
*# Generate Simulated Data Values*
z1 = sin(x+y[,1])
z2 = sin((x+y[,1])/2.)
z3 = sin((x+y[,1])/3.)
z <- cbind(z1, z2, z3)*# Generate Simulated Standard Deviations*
sd <- sqrt(abs(z) * .05)
n = length(x)
i = seq(0,n-1)*# Create Plots for each of three simulated trajectories*
p <- plot_ly(type = 'scatter3d')
for (index in 1:3){
p <- add_trace(p, x = x, y = y[,index], z = z[,index], mode = 'lines', line = list(width = 8, color=index))
p <- add_trace(p, type = 'mesh3d',
*# Setup triangle vertices*
x = c(x, x),
y = c(y[,index], y[,index]),
z = c(z[,index] - 2 * sd[,index], z[,index] + 2 * sd[,index]),
*# Create triangles*
i = c(i[1:n - 1], i[1:n - 1]),
j = c(n + i[1:n - 1], n + i[2:n]) ,
k = c(n + i[2:n], i[2:n]),
color = index
)
}
*#END*
如何用 Python 在 4 分钟内完成网页抓取
原文:https://towardsdatascience.com/how-to-web-scrape-with-python-in-4-minutes-bc49186a8460?source=collection_archive---------0-----------------------
Python 网页抓取初学者指南
Photo by Chris Ried on Unsplash
网页抓取
Web 抓取是一种从网站中自动访问和提取大量信息的技术,可以节省大量的时间和精力。在本文中,我们将通过一个简单的例子来演示如何从纽约 MTA 自动下载数百个文件。这是一个伟大的练习网页抓取初学者谁正在寻找了解如何网页抓取。网络抓取可能有点吓人,所以本教程将分解如何进行这个过程。
纽约 MTA 数据
我们将从以下网站下载十字转门数据:
[http://web.mta.info/developers/turnstile.html](http://web.mta.info/developers/turnstile.html)
十字转门的数据从 2010 年 5 月到现在每周都有汇编,所以几百个。网站上有 txt 文件。下面是一些数据的片段。每个日期都是一个链接。txt 文件,您可以下载。
手动右键点击每个链接并保存到你的桌面是很痛苦的。幸运的是,有网络抓取!
关于网页抓取的重要注意事项:
- 通读网站的条款和条件,了解如何合法使用数据。大多数网站禁止你将这些数据用于商业目的。
- 确保下载数据的速度不要太快,因为这可能会破坏网站。您也可能被阻止访问该网站。
检查网站
我们需要做的第一件事是找出在多层 HTML 标签中我们可以在哪里找到我们想要下载的文件的链接。简而言之,网站页面上有大量代码,我们希望找到包含我们数据的相关代码。如果你不熟悉 HTML 标签,参考 W3Schools 教程。理解 HTML 的基础知识对于成功抓取网页是很重要的。
在网站上,右键点击“检查”。这可以让你看到网站背后的原始代码。
一旦你点击“检查”,你应该看到这个控制台弹出。
Console
请注意,在控制台的左上方,有一个箭头符号。
如果您单击这个箭头,然后单击站点本身的一个区域,则该特定项目的代码将在控制台中突出显示。我点击了第一个数据文件,2018 年 9 月 22 日,星期六,控制台以蓝色突出显示了该特定文件的链接。
<a href=”data/nyct/turnstile/turnstile_180922.txt”>Saturday, September 22, 2018</a>
注意所有的。txt 文件在上面一行后面的<a>
标签中。当你做更多的网页抓取时,你会发现<a>
是用于超链接的。
现在我们已经确定了链接的位置,让我们开始编码吧!
Python 代码
我们从导入以下库开始。
import requests
import urllib.request
import time
from bs4 import BeautifulSoup
接下来,我们设置网站的 url,并使用我们的请求库访问该站点。
url = '[http://web.mta.info/developers/turnstile.html'](http://web.mta.info/developers/turnstile.html')
response = requests.get(url)
如果访问成功,您应该会看到以下输出:
接下来,我们用 BeautifulSoup 解析 html,这样我们就可以使用更好的嵌套式 BeautifulSoup 数据结构。如果你有兴趣了解这个库的更多信息,请查看 BeatifulSoup 文档。
soup = BeautifulSoup(response.text, “html.parser”)
我们使用这种方法。findAll 找到我们所有的<a>
标签。
soup.findAll('a')
这段代码给出了每一行带有<a>
标签的代码。我们感兴趣的信息从第 38 行开始,如下所示。也就是说,第一个文本文件位于第 38 行,所以我们想要获取位于下面的其余文本文件。
subset of all tags
接下来,让我们提取我们想要的实际链接。让我们测试第一个链接。
one_a_tag = soup.findAll(‘a’)[38]
link = one_a_tag[‘href’]
这段代码将第一个文本文件“data/nyct/turnstile/turnstile _ 180922 . txt”保存到我们的变量 link 中。下载数据的完整网址其实是‘http://web . MTA . info/developers/data/nyct/turnstile/turnstile _ 180922 . txt’,是我在网站上点击第一个数据文件作为测试发现的。我们可以使用我们的 urllib.request 库将这个文件路径下载到我们的计算机上。我们为 request.urlretrieve 提供两个参数:文件 url 和文件名。对于我的文件,我命名为“turnstile_180922.txt”、“turnstile_180901”等。
download_url = 'http://web.mta.info/developers/'+ link
urllib.request.urlretrieve(download_url,'./'+link[link.find('/turnstile_')+1:])
最后但同样重要的是,我们应该包含这一行代码,这样我们可以暂停我们的代码一秒钟,这样我们就不会向网站发送垃圾请求。这有助于我们避免被标记为垃圾邮件发送者。
time.sleep(1)
现在我们已经了解了如何下载一个文件,让我们试着用 for 循环下载整个数据文件集。下面的代码包含了网络抓取纽约 MTA 十字转门数据的整套代码。
Note that line 19 should be 38 and not 36 due to an updated on the website.
你可以在我的 Github 上找到我的 Jupyter 笔记本。
感谢大家的阅读和快乐的网刮!
如何赢得 70%以上的石头剪刀布比赛
原文:https://towardsdatascience.com/how-to-win-over-70-matches-in-rock-paper-scissors-3e17e67e0dab?source=collection_archive---------7-----------------------
https://www.flickr.com/photos/gozalewis/4565833940
一个流行游戏的初级人工智能方法
你有没有想过算法是怎么下棋的?如何设置围棋程序?为什么 AI bot 能够在你最喜欢的游戏中打败你?你不会在这篇文章中读到它。我将要写的这个游戏更容易玩,也更容易实现。
虽然石头剪子布(RPS)看起来像一个微不足道的游戏,但它实际上涉及到时间模式识别的困难计算问题。这个问题是机器学习、人工智能和数据压缩领域的基础。事实上,它甚至对理解人类智能的工作方式至关重要。
以上文字来自伟大的石头剪刀布编程大赛 页面。它举办了一场自由开放的比赛,每个人都可以提交他/她的游戏算法。代码提交在 Python 2 中,每个人都可以看到。它让每个人都有机会看到最佳解决方案的细节。然而理解它们并不总是容易的。
提交的算法和其他程序打一千回合。这叫比赛。获胜回合数较多的算法获胜。玩家在排行榜上的排名基于通过比赛获得或失去的分数。
让我们实现最简单的播放算法。它总是放摇滚。
注意,在程序中你唯一要做的事情就是给全局输出变量一个 range 值(‘R’,‘P’,‘S’)。你反对算法将其移动分配给输入全局变量。每一轮你都可以看到前一轮的输入。第一轮变量是一个空字符串。
好吧,第一个游戏对于任何从数据中学习的算法来说都是很容易对付的。现在采取相反的方法。
http://dilbert.com/strip/2001-10-25
你认为会怎样?这很容易预测:平均三分之一输,三分之一平,三分之一赢。这个策略让你有 50%的机会赢得每场比赛。为了获得更高的胜率,你必须冒险。只看随机模特比赛有趣吗?不,所以请不要提交完全随机的解决方案。不过我们会在某些情况下使用这个模型。
请注意,您可以离线测试您的模型。从网站下载 rpsrunner.py 即可。你可以发布它们来检查它们做得怎么样,但是没有太多的计算能力。一开始犯了一个错误,贴了一些无意随机的代码。这很容易测试——只需让您的代码处理持续的输入(就像第一个实现的模型一样)。如果它松动了大约 50%,你的模型可能是随机的。
我们要实现的模型是一个离散马尔可夫链。它建立在一个简单的想法上。假设一个进程有两种可能的状态 A 和 e,我们现在在状态 A,我们停留在状态 A 的几率是多少?还有,去 E 州的几率有多大?关于具有两种可能状态的马尔可夫链,这两种概率的总和必须为 1。充分地说,当前状态 e 有两种概率,你可以在下面的图片上看到机制。
https://en.wikipedia.org/wiki/Markov_chain
这里有一个关于马尔可夫模型如何工作的极好的可视化。
我们如何在 RPS 竞赛中使用该模型?一种自然的方法是分析最近一轮的输入和输出,并尝试预测下一个输入。然后采取行动击败它。这个设置表明我们的当前状态是一对,就像“RP”,下一个状态是我们的输出。应该是这样的:
Image by author
下面是实现。我还添加了一个 n_obs 键来保存过去发生的次数。我们将在学习过程中使用它。
衰减参数代表模型的记忆。值 1 意味着模型具有完美的记忆。如果分配一个介于 0 和 1 之间的值,模型将会忘记先前的观察,从而更快地适应对手行为的变化。
作为输入预测,给定最新的输出-输入对,模型选择具有最高概率的移动。
下面你可以找到整个播放程序:
你可以玩算法:
http://www.rpscontest.com/human/5706404883070976
我必须警告你。这种型号在比赛中表现不好。只是太初级了。大部分冒险算法应该可以对抗这种策略。你可以在这个链接下看到它的表现。它只是一个让你在石头剪刀布比赛中开始冒险的地方。你可以修改参数,训练许多模型,选择最好的来玩,创建合奏。这取决于你的想象力。最好的算法赢得大约 80%的匹配。你可以在这里查看我的超 70%算法。你能做得更好吗?
关于 RPS 游戏中贝叶斯推理的说明。当我开始参加竞赛时,我认为最好的解决方案是贝叶斯方案。现在我相信不是贝叶斯问题。你可以评估所有的策略,因为输入和输出是同时的,因此相互独立。它否定了贝叶斯推理最大的优势之一——选择下一个要测试的算法。
你打算参加比赛吗?你有别的方法吗?如果你喜欢这篇文章,请在评论区或拍手告诉我!
Kitsune-ken — a popular Japanese rock–paper–scissors variant. https://en.wikipedia.org/wiki/Rock-paper-scissors
如何赢得数独
原文:https://towardsdatascience.com/how-to-win-sudoku-3a82d05a57d?source=collection_archive---------0-----------------------
Photo by Xan Griffin on Unsplash
了解被称为数独的流行谜题,以及我们如何教计算机自己解决它。
Sudoku (aka 数独)
数独这个名字来自日本,翻译过来就是‘数’(Su)和‘单’(Doku)。然而,虽然这个名字表明了日本的传统,但创造这个谜题的主要功臣是伦纳德·欧拉;一位非常著名的 18 世纪瑞士数学家。从那以后,这个谜题在国际上被广泛采用,甚至在计算机中也是如此。
那么数独怎么玩呢?首先,这个谜题是一个由 81 个方块组成的棋盘(就像井字游戏一样),根据谜题的难度,有许多方块填满了数字,而其余的都是空白的。下面你可以在左边看到一个尚未解决的数独拼图板,在右边看到一个已经解决的相同拼图板。
https://blogs.unimelb.edu.au/sciencecommunication/files/2016/10/sudoku-p14bi6.png
要解决这个难题,你需要用从 1 到 9 的数字填充空白方块。问题是每个方块必须包含一个对该行、列和框唯一的值。这些行、列和框将被称为区域。一行从左到右由九个正方形组成,一列从上到下由九个正方形组成,一个盒子由九个均匀分布在棋盘上的 3x3 盒子之一组成。
Udacity AI Nanodegree Program
现在这个谜题有不同的变体,但我们将只关注最初的。如果你没有玩过数独,那就去试试吧!人们已经玩了几个世纪了,这很有趣(有时令人沮丧)。
解决数独
好了,现在你知道了数独的规则,并且有希望获得一些玩数独的经验,你可能已经注意到了在你寻找解决方法的过程中的一些模式。更有可能的是,你从填一个只能取一个值的方块开始。然后,也许你开始解决其余的方块,通过消除所有可能的值,一个特定的方块不能采取,并选择剩下的一个。可能有几次你不得不记住多个方块的几个值。也许你遇到了两个岔路口,你不得不在两条不同的路径中选择一条来寻找解决方案,其中一条路径要么帮助你解决了难题,要么产生了一个迫使你原路返回的死胡同。
这是对两种常见策略的很好的介绍,称为消除和唯一选择,它要求你列出每个方块可能取的所有值(消除),然后填写只列出一个可能值的方块(唯一选择)。你需要做的就是一遍又一遍地重复这个循环来解决这个难题。不错!
约束传播
现在要教计算机如何做到这一点,我们需要使用一种常见的人工智能方法,称为约束传播。简而言之,这是一种方法,它允许计算机朝着可能的解决方案移动(传播),同时遵循一些空间的规则和每个变量可能使用的值(约束)。在这种情况下,我们的约束是只能包含一个从 1 到 9 的值的正方形,并且每个区域必须是唯一的。
那么,这种方法实际上是怎样的呢?让我们从下面的数独板开始。别担心,这个难题很简单,使用约束传播时对计算机来说甚至更容易。
Udacity AI Nanodegree Program
首先,我们要列出每个方块可能取的所有可能值,这样我们可以缩小可能的选择范围,并发现“已经解决”的方块(即,只有一个可能值的方块)。根据下面的板子,你可以看到所有可能的值都列在了每一个方块上,其中一些只有一个值。
Udacity AI Nanodegree Program
现在要做的显而易见的事情是解决已经缩小到只有一个值的正方形。基于数独的规则,我们可以查看单个区域(行、列和框)来找出每个方块的不同值。这是向下钻取局部约束的过程;在这里是区域。
例如,让我们看看下图中顶部中间的红色方框。你可以看到我们几乎已经解决了这个区域,但还没有完全解决。由于这个方框中的每个方块必须是唯一的,我们知道 2、3、5、6 和 8 都不是未解方块的可能值。然而,我们可以看到,值 1 只可能出现在这个区域的右上角的正方形中,而该区域中的每个未解正方形都包含 4、7 或 9。
Udacity AI Nanodegree Program
这导致我们将 1 赋给那个正方形,因为它是值中的唯一选择,保证它在整个给定区域中是唯一的。接下来,计算机会在所有区域重复做同样的事情,直到找到解决方案。
Udacity AI Nanodegree Program
通过使用约束传播,我们可以教会计算机如何通过关注局部约束来解决几乎任何数独难题。但是你可能从经验中知道,有时候棋盘会达到一种“停滞”状态,在这种状态下,有些方块可以有多种值。也许对于任何特定的未解正方形,可供选择的最少数值是两个或更多!嗯,这将是一个你面对裸体双胞胎的例子,这表明在通往伟大的道路上有多条道路可供选择(解决难题)。让我们一起走向伟大。
搜索
如果在解数独谜题的时候,有一个点是你在一个不完整的解上停滞不前,你知道你在解这个谜题的时候做了一个曾经有效的选择,导致了一个无效的解。这意味着你必须回到你当初做那个选择的地方,做出一个不同的选择。希望你留下了面包屑。
实现一种搜索方法,允许计算机遍历可能导致有效解决方案的多个场景,这正是我们在这里想要的,当面对裸体双胞胎时,我们知道我们有两个选择。当在两个不同的方向之间做出选择时,我们必须扩展到两个不同的可能性世界。这可以使用一棵树来完成,特别是一棵(BST)。
现在,BST 由一个根节点组成,从这个根节点分支出两个方向,这些后续的点本身可以有从它们分支出的两个方向,依此类推。
https://i.stack.imgur.com/9jegh.png
现在把节点 A 想象成一个时间点,我们必须在两个决定中做出选择,最终不是 B 就是 c,在数独中,这和遇到裸体双胞胎(wut?);你必须在两条路径中选择一条,这两条路径可能会也可能不会产生有效的解决方案。
Udacity AI Nanodegree Program
如果你看上面的棋盘,你会注意到一个停滞的数独棋盘,左下角有一个方块,包含数值 8 和 9。既然我们被困在一个不完整的解决方案中,我们必须跃入未知,这意味着选择以一种方式解决难题,并希望它能成功。如果没有,我们知道哪里出了问题,并可以通过回溯和选择另一个选项来纠正我们的错误。
谁知道呢,也许在我们做出 8 或 9 的选择后,我们会遇到另一对裸体双胞胎(嗯…),这将导致另一组可能性,从而在我们的树上出现另一组分支!通过将此建模为 BST,我们可以让计算机使用深度优先搜索遍历这些可能的解决方案,这将最终引导我们找到有效的解决方案。
这是智力吗?
现在计算机不知道有解存在。它只是在时间中前进,四处探索,希望能找到一个。虽然我们人类当然知道一个合适的数独棋盘有一个或多个有效解,但计算机不知道。这意味着它必须通过做出适当的选择来聪明地找到这些解决方案之一,因为解决这个难题所需的时间是未知的,在这种情况下,这被称为 NP 问题。
有些人可能不相信这是智力,但这真的取决于你对智力的定义是什么。它可能不会像 Siri 一样跟我们说话,但它肯定是在解决一个问题,而没有潜在的解决方案(就它所知),也没有我们给它明确的条件语句。在解决数独谜题的情况下,我们只是告诉计算机:“你可以这样做,但不可以这样做。现在解决问题。”然后它就明白了。
彼得·诺维格——一位著名的人工智能研究员——发现了如何应用 BST 的约束传播和深度优先搜索来解决数独难题,并在这里详细讨论了它。他甚至深入研究了代码,以展示教计算机如何做到这一点是如何可能的。
包裹
我们讲述了在解决古老的数独难题时,约束传播与 BST 的深度优先搜索是如何完美结合的,这更好地告诉我们如何教会计算机自己做这件事。如果你有兴趣了解更多关于这个主题的知识,我强烈建议你阅读彼得·诺维格的帖子,在那里他提供了关于代码片段问题的更深入的观点。你也可以看看我为我的 Udacity 人工智能 Nanodegree 写的解决这个问题的代码,你可以在我的 GitHub repo 上找到。
嗨,我是格兰特!我是一名自由开发者和作家。查看我在 https://grantbartel.com 的网站。干杯!
如何编写 Jupyter 笔记本扩展
原文:https://towardsdatascience.com/how-to-write-a-jupyter-notebook-extension-a63f9578a38c?source=collection_archive---------4-----------------------
(Source)
让 Jupyter 笔记本成为你的游乐场
Jupyter 笔记本扩展是简单的附加组件,可以显著提高您在笔记本电脑环境中的工作效率。它们自动执行乏味的任务,如格式化代码或添加功能,如创建目录。虽然有许多现有的扩展,我们也可以编写自己的扩展来扩展 Jupyter 的功能。
在本文中,我们将了解如何编写一个 Jupyter 笔记本扩展,在每个新笔记本的顶部添加一个默认单元格,这在您发现自己要向每个笔记本导入库时非常有用。如果你想了解扩展的背景,那么看看这篇文章。GitHub 上提供了该扩展的完整代码。
默认单元格扩展的最终结果如下所示:
Extension to add a default cell to the top of every notebook.
开始前的注意事项
(如果您还没有 Jupyter 扩展,查看本文或在命令提示符下运行以下代码:pip install jupyter_contrib_nbextensions && jupyter contrib nbextensions install
然后启动一个新的笔记本服务器并导航到扩展选项卡)。
不幸的是,没有太多关于编写自己的扩展的官方文档。我的策略是阅读其他扩展,大量复制和粘贴,并进行试验,直到我弄明白为止。这个栈溢出问答提供了这个扩展的基本代码。
Jupyter 笔记本扩展的结构
任何 Jupyter 笔记本扩展都有 3 个部分(至少):
description.yaml
:Jupyter 读取的配置文件main.js
:扩展本身的 Javascript 代码README.md
:扩展的降价描述
(我们也可以在其他文件或css
中有更多的函数进行造型)。
这 3 个文件应该位于一个目录中,我们称之为default_cell
。这个文件夹需要在jupyter_contrib_extensions
库的nbextensions
子目录中(你用 pip 安装的)。要找到安装了 pip 的库的位置,请运行pip view package
。)
我的jupyter_contrib_extensions
目录是:
/usr/local/lib/python3.6/site-packages/jupyter_contrib_nbextensions/nbextensions
所以文件结构看起来是这样的(如上图nbextensions
):
nbextensions/
default_cell/
- description.yaml
- main.js
- README.md
当您运行jupyter notebook
时,Jupyter 在这个位置查找扩展,并在服务器上的 extensions 选项卡上显示它们:
Jupyter Notebook Extensions tab
当您在开发过程中对扩展文件进行了更改,并且希望在 Jupyter 笔记本中看到效果时,您需要运行命令jupyter contrib nbextensions install
来重写 Jupyter 配置文件。然后,重新启动笔记本服务器以查看您的更改。
详细情况说完了,让我们来看一下我们需要的三个文件。
描述. yaml
YAML (YAML 不是标记语言)是一种人类可读的标准,用于编写配置和头文件。YAML 文件描述了要在扩展选项卡上呈现的 Jupyter 扩展配置器的扩展。
这是一个相当容易的文件复制+粘贴和修改我们的需要。
这将很好地呈现在笔记本的NBExtensions
选项卡上:
兼容性指明了该扩展适用的 Jupyter 版本。我刚刚把它们全部加了进去(3.x — 6.x ),看起来效果不错!
主页. js
这是应用程序的核心,是扩展的实际逻辑所在。Jupyter 笔记本在浏览器中运行,这意味着扩展必须用 Javascript 编写,Javascript 是 web 的语言。
要弄清楚使用什么命令来让笔记本做你想要的事情可能有点困难。一种试验方法是使用 Chrome 开发工具(Windows 上的 cntrl + shift + i)或右键单击> inspect。
开发工具打开后,我们可以使用console
选项卡来运行命令。
Console in Chrome developer tools
尝试在 Jupyter 笔记本中打开开发者工具,使用以Jupyter.notebook.
开头的选项,你输入的任何命令都必须是 Javascript 格式的。这种行为的一个例子可以在下面的剪辑中看到。我打开开发工具,然后运行一些命令来执行单元格,插入一个新的单元格,并选择前一个单元格。
开发 Javascript 代码需要大量这样的实验!这也有助于阅读其他扩展,以确定您需要做什么。
最终的main.js
如下:
代码中最重要的部分是add_cell
函数。
var add_cell = function() {
Jupyter.notebook.
insert_cell_above('code').
// Define default cell here
set_text(`Define default cell here`);
Jupyter.notebook.select_prev();
Jupyter.notebook.execute_cell_and_select_below();
};
这将在当前选中的单元格上方添加一个代码单元格,括号中写有 python 代码(在set_text
调用中)。这是应该定义默认代码单元的地方。然后,该函数执行单元格并选择下面的单元格。
load_ipython_extension
功能首先检查笔记本中的单元格数量。如果只有一个单元格——一个新的笔记本——它调用add_cell
函数,将默认单元格放在笔记本的顶部。
// Run on start
function load_ipython_extension() {// Add a default cell if a new notebook
if (Jupyter.notebook.get_cells().length===1){
add_cell();
}
defaultCellButton();
}
然后运行defaultCellButton
功能,在 Jupyter 笔记本工具栏上放置一个按钮。我们可以使用此按钮在当前选定的单元格上方添加并运行默认单元格。当我们有一个已经启动的笔记本并且我们想要我们的正常导入时,这可能是有用的。
Function of defaultCellButton
我们可以在浏览器中用 Javascript 完成几乎无限多的任务。这只是一个简单的应用程序,但是还有许多更复杂的 Jupyter 扩展(例如变量检查器)演示了更多的功能。我们还可以用 Javascript 编写应用程序,调用 Python 脚本来获得更好的控制。
README.md
一个 readme markdown 文件对任何一个有一点编程经验的人来说都应该是熟悉的。这里是我们解释我们的应用程序做什么以及如何使用它的地方。这显示在“扩展”选项卡上:
README rendered on the extensions tab
(实际的代码很无聊,但为了完整起见,在这里)
Default Cell**=========**Adds and runs a default cell at the top of each new notebook. To change the default cell, edit the `add_cell` function in the `main.js` file. The relevant section is`Jupyter.notebook.insert_cell_above('code', 0).set_text(``)`Set the `text` to whatever you would like.This extension also adds a button to the toolbar allowing you to insert and run the default cell above your current cell. This can be helpful if you open an already started notebook and notice you are missing some common imports.This extension is a work in progress and any help would be appreciated. Feel free to make contributions on GitHub or contact the author (Will Koehrsen) at wjk68@case.edu
一旦有了三个必需的文件,您的扩展就完成了。
要查看扩展的工作情况,请确保default_cell
目录位于正确的位置,运行jupyter contrib nbextensions install
并启动 Jupyter 笔记本服务器。如果您导航到NBExtensions
选项卡,您将能够启用扩展(如果您没有该选项卡,请打开笔记本并编辑> nbextensions 配置)。
Extension enabled
启动新笔记本,查看您的扩展功能:
Default cell jupyter notebook extension
这个扩展不会改变你的生活,但是它可能会节省你几秒钟的时间!
结论
获得计算机知识的部分乐趣是意识到如果你想在计算机上完成某件事,有机会你可以用正确的工具和学习的意愿。这个制作 Jupyter 笔记本扩展的小例子表明,我们不会受到开箱即用产品的限制。我们只需要几行代码来完成我们的目标。
希望这个扩展证明对你有用或者启发你写你自己的。我从扩展中得到了很多用处,并期待看到人们还能开发出什么。一旦你开发了一个扩展,分享它,这样其他人可以惊叹你的代码并从你的努力工作中获益。
一如既往,我欢迎反馈和建设性的批评。可以通过推特 @koehrsen_will 或者通过我的个人网站 willk.online 找到我。
数据科学如何写一个生产级代码?
原文:https://towardsdatascience.com/how-to-write-a-production-level-code-in-data-science-5d87bd75ced?source=collection_archive---------1-----------------------
dreamstime/Scyther5
编写生产级代码的能力是数据科学家角色的抢手技能之一——无论是否明确公布。对于一个从软件工程师转型为数据科学家的人来说,这听起来可能不是一个具有挑战性的任务,因为他们可能已经完善了开发生产级代码的技能,并多次部署到生产中。
本文面向那些刚开始编写生产级代码并对学习它感兴趣的人,如大学应届毕业生或任何进入数据科学领域(或计划转型)的专业人士。对他们来说,编写生产级代码似乎是一项艰巨的任务。
我会给你一些关于如何编写生产级代码并实践它的技巧,你不一定要在数据科学的角色中学习这项技能。
1。保持模块化
这基本上是推荐给任何软件工程师的软件设计技术。这里的想法是根据它的功能将一个大的代码分成小的独立部分(函数)。它有两个部分。
(I)将代码分成较小的部分,每个部分用于执行特定的任务(可能包括子任务)
(ii)基于其可用性将这些功能分组到模块(或 python 文件)中。它还有助于保持组织性和代码的易维护性
第一步是将一个大代码分解成许多具有特定输入(和输入格式)和输出(和输出格式)的简单函数。如前所述,每个函数应该执行一个任务,如清除数据中的异常值、替换错误值、对模型评分、计算均方根误差(RMSE) 等等。试着将这些功能进一步分解为执行子任务,继续下去,直到没有功能可以进一步分解。
低级函数 —不能再分解的最基本的函数。例如,计算数据的 RMSE 或 Z 分数。这些函数中的一些可以广泛用于任何算法或机器学习模型的训练和实现。
中级功能 —使用一个或多个低级功能和/或其他中级功能来执行其任务的功能。例如,清除异常值函数使用计算 Z 值函数来移除异常值,只保留特定范围内的数据,或者使用计算 RMSE 函数的误差函数来获取 RMSE 值。
高级功能 —使用一个或多个中级功能和/或低级功能来执行其任务的功能。例如,使用几个函数的模型训练函数,例如获得随机采样数据的函数、模型评分函数、度量函数等。
最后的步骤是将对多个算法有用的所有低级和中级函数分组到一个 python 文件中(可以作为一个模块导入),并将仅对所考虑的算法有用的所有其他低级和中级函数分组到另一个 python 文件中。所有的高级函数都应该驻留在一个单独的 python 文件中。这个 python 文件规定了算法开发的每个步骤——从组合来自不同来源的数据到最终的机器学习模型。
遵循以上步骤没有硬性规定,但是我强烈建议你从这些步骤开始,然后发展你自己的风格。
2。测井和仪器仪表
记录和仪表(LI)类似于飞机上的黑匣子,记录驾驶舱内发生的所有事情。LI 的主要目的是记录代码执行过程中的有用信息,帮助程序员在出现问题时进行调试,并提高代码的性能(如减少执行时间)。
日志记录和检测有什么区别?
(i)日志记录— 仅记录可操作的信息,如运行时的关键故障,以及结构化数据,如代码本身稍后将使用的中间结果。在开发和测试阶段,可以接受多种日志级别,如调试、信息、警告和错误。然而,在生产过程中要不惜一切代价避免它们。
日志记录应尽量少,仅包含需要人工关注和立即处理的信息。
(ii)检测— 记录日志中遗漏的所有其他信息,这些信息将帮助我们验证代码执行步骤,并在必要时改进性能。在这种情况下,拥有更多的数据总是更好,因此要尽可能多地收集信息。
为了验证代码执行步骤——我们应该记录诸如任务名称、中间结果、经过的步骤等信息。这将有助于我们验证结果,并确认算法遵循了预期的步骤。无效的结果或异常执行的算法可能不会引发在日志记录中会被捕获的严重错误。因此记录这些信息是必要的。
为了提高性能,我们应该记录每个任务/子任务花费的时间和每个变量使用的内存。这将有助于我们改进代码,进行必要的修改,优化代码以运行得更快并限制内存消耗(或者识别 python 中常见的内存泄漏)。
插装应该记录日志中遗漏的所有其他信息,这些信息将帮助我们验证代码执行步骤并致力于性能改进。数据多总比少好。
3。代码优化
代码优化意味着降低时间复杂度(运行时间)和降低空间复杂度(内存使用)。时间/空间复杂度通常表示为 O(x),也称为 Big-O 表示法 其中 x 是时间或空间占用多项式中的主导项。时间复杂度和空间复杂度是衡量 算法效率 的度量。
例如,假设我们有一个嵌套的 for 循环,每个循环的大小为 n ,每次运行大约需要 2 秒,然后是一个简单的 for 循环,每次运行需要 4 秒。那么时间消耗的等式可以写成
耗时~ 2 n +4 n = O(n +n) = O(n)
对于 Big-O 表示,我们应该去掉非主导项(因为它可以忽略不计,因为 n 趋向于 inf )以及系数。系数或比例因子被忽略,因为我们在优化灵活性方面对其控制较少。请注意,绝对耗时中的系数是指循环的数量与每次运行所用时间的乘积,而 O(n +n)中的系数代表循环的数量(1 个双用于循环,1 个单用于循环)。同样,我们应该从等式中去掉低阶项。因此,上述过程的大 O 是 O(n)。
现在,我们的目标是用时间复杂度更低的更好的替代方案替换效率最低的代码部分。比如 O(n)比 O(n)好。代码中最常见的杀手是循环的,最不常见但比循环的更糟糕的是递归函数(O(branch^depth)).尝试用 python 模块或函数替换尽可能多的 for 循环,这些模块或函数通常用可能的 C 代码执行计算进行了大量优化,以实现更短的运行时间。
我强烈推荐你阅读盖尔·麦克道尔的《破解编码采访中关于“大 O”的部分。事实上,试着通读整本书来提高你的编码技能。
4。单元测试
单元测试——根据功能自动化代码测试
您的代码在进入生产之前必须清除多个测试和调试阶段。通常有三个级别—开发、试运行和生产。在一些公司中,在生产之前会有一个模拟生产系统确切环境的阶段。代码应该没有任何明显的问题,并且应该能够在进入生产时处理潜在的异常。
为了能够识别可能出现的不同问题,我们需要针对不同的场景、不同的数据集、不同的边缘和角落情况等来测试我们的代码。每次我们想要测试代码时,手动执行这个过程是低效的,因为每次我们对代码进行重大修改时都会这样。因此,选择包含一组测试用例的单元测试,它可以在我们想要测试代码的任何时候执行。
我们必须添加具有预期结果的不同测试用例来测试我们的代码。单元测试模块逐个检查每个测试用例,并将代码的输出与期望值进行比较。如果没有达到预期的结果,测试就会失败——这是您的代码在部署到产品中时会失败的早期迹象。我们需要调试代码,然后重复这个过程,直到所有的测试用例都被清除。
为了让我们的生活变得简单,python 有一个名为 unittest 的模块来实现单元测试。
5。与生态系统的兼容性
最有可能的是,你的代码不会是一个独立的函数或模块。它将被整合到公司的代码生态系统中,您的代码必须与生态系统的其他部分同步运行,没有任何缺陷/故障。
例如,假设你开发了一个算法来给出推荐。流程通常包括从数据库中获取最近的数据,更新/生成推荐,将其存储在数据库中,该数据库将被前端框架(如网页)读取(使用 API)以向用户显示推荐的项目。简单!它就像一条链条,新的链环应该与前一个和下一个链环锁在一起,否则该过程将失败。同样,每个进程都必须按预期运行。
每个流程都有明确定义的输入和输出需求、预期的响应时间等等。如果当其他模块(从网页)请求更新的建议时,您的代码应该在可接受的时间内以期望的格式返回期望值。如果结果是意想不到的值(当我们在购买电子产品时建议购买牛奶),不希望的格式(以文本而不是图片的形式提出的建议),以及不可接受的时间(没有人等待分钟来获得建议,至少在这些日子里),这意味着代码与系统不同步。
避免这种情况的最好方法是在我们开始开发过程之前与相关团队讨论需求。如果团队不在,仔细阅读代码文档(很可能你会在那里找到很多信息)和代码本身,如果必要的话,理解需求。
6。版本控制
git——一个版本控制系统是最近发生在源代码管理上的最好的事情之一。它跟踪对计算机代码的修改。也许有许多现有的版本控制/跟踪系统,但是与其他任何系统相比,Git 被广泛使用。
这个过程简单来说就是“修改和提交”。我把它过分简化了。这个过程有很多步骤,例如创建一个开发分支,在本地提交更改,从远程提取文件,将文件推送到远程分支,等等,我将留给您自己去探索。
每当我们对代码进行更改时,我们不是用不同的名称保存文件,而是提交更改——这意味着用新的更改覆盖旧的文件,并使用与之链接的键。我们通常在每次提交代码变更时都要写注释。比方说,你不喜欢在最后一次提交中所做的更改,并且想要恢复到以前的版本,使用提交引用键可以很容易地做到这一点。Git 对于代码开发和维护来说是如此强大和有用。
您可能已经理解了为什么这对生产系统很重要,以及为什么必须学习 Git。我们必须总是能够灵活地回到稳定的旧版本,以防新版本意外失败。
7。可读性
你写的代码对其他人来说也应该是容易理解的,至少对你的团队成员来说是这样。此外,如果没有遵循正确的命名约定,即使是对您来说,在编写代码后的几个月内理解自己的代码也是一个挑战。
(一)适当的变量和函数名
变量和函数名应该是不言自明的。当有人阅读你的代码时,应该很容易找到每个变量包含什么,每个函数做什么,至少在某种程度上是这样。
使用一个能清楚说明其功能/作用的长名称,而不是使用诸如 x、y、z 等短名称,是完全可以的。,那都是模糊的。变量名不要超过 30 个字符,函数名不要超过 50–60 个字符。
以前,基于完全过时的 IBM 标准,标准代码宽度是 80 个字符。现在按照 GitHub 的标准,大概是 120 左右。为角色名设置 1/4 的页面宽度限制,我们得到 30,这足够长了,但并没有填满页面。函数名可以稍微长一点,但是也不应该占满整个页面。因此,通过设置 1/2 页宽的限制,我们得到 60。
例如,样本数据中亚洲男性平均年龄的变量可以写成 mean_age_men_Asia 而不是年龄或 x 。类似的论点也适用于函数名。
(二)文档字符串和注释
除了适当的变量名和函数名之外,在任何必要的地方都要有注释和注解,以帮助读者理解代码。
文档字符串 —特定于函数/类/模块。函数定义中的前几行文本,描述函数的角色及其输入和输出。文本应该放在一组 3 个双引号之间。
定义<function_name>:</function_name>
" " " "
返回
注释 —可以放在代码中的任何位置,以告知读者特定部分/行的操作/角色。如果我们给变量和函数起一个合适的名字,注释的需求就会大大减少——代码在很大程度上是不言自明的。
代码审查:
尽管这不是编写产品质量代码的直接步骤,但是您的同行对代码的评审将有助于提高您的编码技能。
没有人能写出完美的计算机代码,除非有人有 10 年以上的经验。总会有改进的余地。我见过有几年编写糟糕代码经验的专业人士,也见过有杰出编程技能的正在攻读学士学位的实习生——你总能找到比你更好的人。这完全取决于一个人投入了多少时间来学习、练习,最重要的是提高这一特殊技能。
我知道比你更好的人总是存在的,但是在你的团队中并不总是可能找到他们,只有他们你才能分享你的代码。也许你是你团队中最棒的。在这种情况下,让团队中的其他人测试你的代码并给出反馈是可以的。即使他们没有你好,有些东西可能会逃过你的眼睛,他们可能会抓住。
当您处于职业生涯的早期阶段时,代码审查尤其重要。这将极大地提高你的编码技能。请按照下面的步骤成功审查您的代码。
(I)在您完成所有开发、测试和调试的代码编写之后。确保你没有遗漏任何愚蠢的错误。然后恳请您的同行进行代码审查。
(ii)将您的代码链接转发给他们。不要让他们一次复习几个剧本。一个接一个地问他们。他们对第一个脚本的评论可能也适用于其他脚本。在发送第二个脚本进行审查之前,请确保将这些更改应用于其他脚本(如果适用)。
(iii)给他们一到两周的时间来阅读和测试你每次迭代的代码。还要提供所有必要的信息来测试您的代码,比如样本输入、限制等等。
㈣与他们每个人会面,听取他们的建议。记住,你不必在你的代码中包含他们所有的建议,根据你自己的判断选择那些你认为会改进代码的建议。
(v)重复,直到你和你的团队满意为止。尝试在最初的几次迭代(最多 3-4 次)中修复或改进您的代码,否则它可能会对您的代码能力产生不好的印象。
希望这篇文章是有帮助的,你喜欢阅读它。
我很乐意阅读您的反馈。
如何用 R 编写整洁的 SQL 查询
原文:https://towardsdatascience.com/how-to-write-tidy-sql-queries-in-r-d6d6b2a3e17?source=collection_archive---------8-----------------------
如今,我们大多数人都必须与数据库进行交互,而 SQL 是目前最常用的语言。然而,在 R 中使用 SQL 可能会很麻烦。如果您的查询很复杂,您必须将它们编码为文本字符串,这很容易出错,并且面临格式方面的挑战。此外,当您想要构建包含变量的 SQL 查询时,您必须进行替换或粘贴,这有点麻烦。
理想情况下,您希望能够使用 tidy 原则处理您的数据库,利用 tidyverse 的奇迹,最好不要先将整个数据库下载到您的会话中。这就是dbplyr
的魔力所在。
dbplyr
充当 SQL 翻译器,允许你使用tidyverse
来处理数据库。所以现在你可以尽情宣泄了。如果你还没有用过这个,我现在就开始用。编写整洁的数据库查询有许多优点。当你过一段时间再回到你的工作时,你可以更容易地理解你的工作,你可以更清楚地评论,并且它也迫使你去思考你的查询的最有效的结构。
在 dbplyr 中工作的基本原则
要在dbplyr
中工作,您需要像在 R 会话中一样设置数据库连接,我们称之为myconn
。您将使用dbplyr::in_schema()
在 R 会话中设置数据库对象。这需要两个参数:第一,您希望在数据库连接中访问的模式,第二,您在该模式中感兴趣的表。下面是一个如何设置的示例:
catdata <- dplyr::tbl(
myconn,
dbplyr::in_schema("ANIMAL_ANALYSTS", "CAT_TABLE")
)
现在catdata
是一个数据库对象。上面的命令连接到数据库并下载关于字段、数据类型等的最少信息。—足以允许操纵对象,而无需物理下载数据。
现在,您可以像操作 r 中的其他表一样操作catdata
。例如:
weight_by_age <- catdata %>%
dplyr::group_by(AGE) %>%
dplyr::summarise(AVG_WT = mean(WT, na.rm = TRUE))
所有这些操作都是通过在后台将您的代码翻译成 SQL,而无需实际下载数据。由于数据下载通常是最耗时的步骤,这允许您在提取数据之前考虑您希望在服务器上完成多少工作。
准备拉数据的时候,用dplyr::collect()
就可以了。这将把后台编译的 SQL 查询发送到数据库并执行它。例如:
weight_by_age %>%
dplyr::rename(`Age of Cat` = AGE,
`Average Weight` = AVG_WT) %>%
dplyr::collect()
dbplyr 中更复杂的 SQL 操作
dbplyr
非常灵活,我还没有发现我不能用dbplyr
重写 tidy 的 SQL 查询。
连接通过在数据库对象上使用dplyr
的连接函数来工作,例如:
fullcatdata <- dplyr::left_join(
catregistrationdetails,
catdata,
by = "SERIAL_NO"
) %>%
dplyr::left_join(
cathealthrecord,
by = "SERIAL_NO"
)
可以使用dplyr::mutate()
将新列添加到数据中,甚至可以用于更复杂的连接。例如,如果您的卡特彼勒序列号在一个表中有“CAT-”开头,但在另一个表中没有:
fullcatdata <- catregistrationdetails %>%
dplyr::mutate(SERIAL_NO = paste0("CAT-", SERIAL_NO)) %>%
dplyr::left_join(catdata, by = "SERIAL_NO")
dbplyr
巧妙地将 R 函数翻译成 SQL 等价物。您可以使用dbplyr::translate_sql()
功能来查看它的功能。例如:
dbplyr::translate_sql(substr(NAME, -3, -1))
<SQL> substr("NAME", -3, 3)
我发现dbplyr
也让我在反应式环境中更容易编码。如果你要建立一个闪亮的应用程序,根据输入计算猫的平均体重input$age
:
weight <- reactive({
catdata %>%
dplyr::filter(AGE == input$age) %>%
dplyr::select(WT) %>%
mean(na.rm = TRUE) %>%
dplyr::collect()
})
这些只是dbplyr
帮助您在 SQL 中更整洁地工作的许多方式中的一部分。我强烈推荐。
关于 *dbplyr*
的更多信息,请点击 这里 。
最初我是一名纯粹的数学家,后来我成为了一名心理计量学家和数据科学家。我热衷于将所有这些学科的严谨性应用到复杂的人的问题上。我也是一个编码极客和日本 RPG 的超级粉丝。在LinkedIn或Twitter上找我。
如何用 Python 写你最喜欢的 R 函数?
原文:https://towardsdatascience.com/how-to-write-your-favorite-r-functions-in-python-11e1e9c29089?source=collection_archive---------4-----------------------
r vs Python——争论仍在继续。与此同时,我们尝试走一条中间道路,创建一个 Python 脚本来模仿方便的 R 风格函数,以便更好、更容易地进行统计!
介绍
数据科学和机器学习的现代大战之一是“Python vs. R”。毫无疑问,这两种语言近年来都取得了巨大的进展,成为数据科学、预测分析和机器学习的首选编程语言。事实上,在 IEEE 最近的一篇文章中,Python 取代 C++成为 2018 年的顶级编程语言,R 也牢牢占据了前 10 名的位置。
然而,这两者之间有一些基本的区别。 R 最初是作为统计分析和数据分析问题的快速原型开发的工具。另一方面,Python 是作为一种通用的现代面向对象语言开发的,与 C++或 Java 一脉相承,但具有更简单的学习曲线和更灵活的风格。因此,R 继续在统计学家、定量生物学家、物理学家和经济学家中非常流行,而 Python 已经慢慢成为日常脚本、自动化、后端 web 开发、分析和通用机器学习框架的首选语言,具有广泛的支持基础和开源开发社区工作。
在 Python 环境下模仿函数式编程?
R的函数式编程特性为用户提供了极其简单紧凑的界面,用于快速计算概率和对数据分析问题进行必要的描述/推断统计。例如,仅仅通过一个简单的函数调用就能回答下面的问题,这不是很好吗?
如何计算一个数据向量的均值/中值/众数?
如何计算服从正态分布的事件的累积概率?如果分布是泊松分布呢?
如何计算一系列数据点的四分位间距?
如何生成几个服从学生 t 分布的随机数?
r 编程环境允许您这样做。
另一方面,Python 脚本能力允许分析师在各种各样的分析管道中使用这些统计数据,具有无限的复杂性和创造性。
为了结合两个世界的优势,我们需要一个简单的基于 Python 的包装器库,它包含了最常用的与概率分布和描述性统计相关的函数,这些函数在 R-style 中定义,这样用户就可以非常快速地调用这些函数,而不必去适当的 Python 统计库,找出所有的方法和参数。
用于最方便的 R 函数的 Python 包装器脚本
我写了一个 Python 脚本,用 Python 定义了简单统计分析中最方便、最广泛使用的 R 函数。导入这个脚本后,您将能够像在 R 编程环境中一样自然地使用这些 R 函数。
该脚本的目标是提供简单的 Python 子程序,模仿 R 风格的统计函数,用于快速计算密度/点估计值、累积分布、分位数,并为各种重要的概率分布生成随机变量。
为了保持 R 风格的精神,没有使用类层次结构,只在这个文件中定义了原始函数,这样用户就可以导入这个 Python 脚本,并在需要时通过一个名字调用来使用所有的函数。
注意,我用 这个词模仿 。在任何情况下,我都不会声称要模仿真正的 R 函数式编程范例,它包含了深层的环境设置以及这些环境和对象之间复杂的相互关系。这个脚本只允许我(我希望无数其他 Python 用户也是)快速启动 Python 程序或 Jupyter 笔记本,导入脚本,并立即开始做简单的描述性统计。这就是目标,不多不少。
或者,您可能在研究生院编写了 R 代码,刚刚开始学习和使用 Python 进行数据分析。您将会很高兴在 Jupyter 笔记本上看到并使用一些众所周知的功能,就像您在 R 环境中使用的方式一样。
不管是什么原因,这都很有趣:-)。
简单的例子
首先,只需导入脚本并开始处理数字列表,就像它们是 r 中的数据向量一样。
**from R_functions import ***
lst=[20,12,16,32,27,65,44,45,22,18]
<more code, more statistics...>
例如,你想从一个矢量数据点中计算出 Tuckey 五个数 summary。你只需要调用一个简单的函数 fivenum 并传递向量。它将在 Numpy 数组中返回五个数字的摘要。
lst=[20,12,16,32,27,65,44,45,22,18]
**fivenum**(lst)
> array([12\. , 18.5, 24.5, 41\. , 65\. ])
或者,你想知道下面这个问题的答案。
假设一台机器每小时平均产出 10 件成品,标准偏差为 2。输出模式遵循近似正态分布。机器在接下来的一个小时内输出至少 7 台但不超过 12 台的概率是多少?
答案基本上是这样的,
使用 pnorm …只需一行代码就能得到答案
**pnorm**(12,10,2)-**pnorm**(7,10,2)
> 0.7745375447996848
或者,下面,
假设你有一枚装了子弹的硬币,每次扔的时候,有 60%的概率正面朝上。你在玩 10 次投掷的游戏。你如何用这枚硬币画出所有可能的中奖概率(从 0 到 10)?
只用几行代码和一个函数 dbinom …,你就可以得到一个漂亮的条形图
probs=[]
import matplotlib.pyplot as plt
for i in range(11):
probs.append(**dbinom**(i,10,0.6))
plt.bar(range(11),height=probs)
plt.grid(True)
plt.show()
概率计算的简单界面
r 为从基本概率分布中快速计算提供了一个极其简化和直观的界面,令人惊叹。界面是这样的…
- d —给出点 x 的密度函数值
- p —给出点 x 的累积值
- q 【分布】—以概率 p 给出分位数函数值
- r —生成一个或多个随机变量
在我们的实现中,我们坚持使用这个接口和相关的参数列表,这样您就可以像在 R 环境中一样执行这些函数。
当前实现的功能
目前,脚本中实现了以下 R 风格的函数用于快速调用。
- 均值、中值、方差、标准差
- 塔基五号总结,IQR
- 矩阵或两个向量之间的协方差
- 以下分布的密度、累积概率、分位数函数和随机变量生成-正态分布、均匀分布、二项式分布、泊松分布、f 分布、学生 t 分布、卡方分布、贝塔分布和伽玛分布。
工作正在进行中…
显然,这是一项正在进行的工作,我计划在这个脚本中添加一些更方便的 R 函数。例如,在 R 中,一行简单的命令lm
就可以让你得到一个普通的最小二乘拟合模型,它是一个带有所有必要的推断统计数据(P 值、标准误差等)的数字数据集。).这是强有力的简洁和紧凑!另一方面,Python 中的标准线性回归问题通常使用 Scikit-learn 来解决,这需要更多的脚本来完成。我计划使用 Python 的 statsmodels 后端整合这个单一函数线性模型拟合特性。
如果你喜欢这个脚本,并在你的工作中找到它的用处,请在我的 GitHub repo 上签名并传播这个消息。
如果您有任何问题或想法要分享,请通过tirthajyoti【AT】Gmail . com联系作者。此外,您可以查看作者的 GitHub 资源库 中其他有趣的 Python、R 或 MATLAB 代码片段和机器学习资源。如果你像我一样对机器学习/数据科学充满热情,请随时在 LinkedIn 上添加我或在 Twitter 上关注我。
如果你喜欢这篇文章,请别忘了留下掌声:-)
追踪应用如何分析你的 GPS 数据:Python 实践教程
原文:https://towardsdatascience.com/how-tracking-apps-analyse-your-gps-data-a-hands-on-tutorial-in-python-756d4db6715d?source=collection_archive---------0-----------------------
如今,运动追踪应用和伴随它们的社交网络无处不在。每个人都想在像 Nike+ Run 或 Strava 这样的应用上做出最大或最快的努力。但是你有没有想过所有这些花哨的统计数据是从哪里来的,或者它们是如何计算出来的?
我们先来解释一下你的手机是如何知道你在哪里的,或者更准确的说,你手机里的 GPS 接收器是如何知道你在哪里的。全球定位系统(GPS)是美国政府拥有的基于卫星的无线电导航系统。
它是一个全球导航卫星系统,向地球上任何地方的 GPS 接收机提供地理位置和时间信息,在那里可以畅通无阻地看到四颗或更多的 GPS 卫星。你的手机接收器的位置通常被转换成纬度,经度和海拔,伴随着一个时间戳,并存储为一个 gpx 文件(更多关于文件格式如下)。
在本教程中,我们将使用 Python 在 Jupyter 笔记本中提取、管理和分析一条路线的 gpx 数据。我们将从把数据从 gpx 文件提取到一个方便的 pandas 数据框架开始。从那里,我们将探索数据,并尝试复制我们最喜欢的运行应用程序的界面为我们提供的统计数据和图表。
获取数据
大多数流行的追踪应用程序允许你下载你的成果作为一个 gpx 文件。在本教程中,我们下载了来自 Strava 的 11 公里跑步记录。gpx-file 是 GPS 交换格式的简称,通常可以通过点击导出获得。下面的截图显示了你可以在哪里下载你的 gpx 文件。你可以在这里下载本文使用的文件。
Export data as gpx-fle
Gpx 是一种 XML 模式,设计为软件应用程序的通用 GPS 数据格式。它可以用来描述路点、轨迹和路线。这也意味着下面的所有代码都可以用于运行任何GPS 数据,只要你考虑到运动的速度和类型。
首先,理解我们的 gpx 文件的结构很重要。在任何文本编辑器(这里是 Notepad ++ )中打开文件后,您应该会得到一个XML-文件,其中包含许多条目,如下所示。注意每个轨迹点由四个值组成:纬度、经度、海拔或海拔和一个时间戳。这四个价值将是我们分析的基础。
加载数据
现在,我们想将 gpx 数据加载到 pandas 数据框架中。没有直接的方法可以做到这一点,所以我们必须使用 gpxpy 库来帮助我们。当我们导入模块时,您可能希望确保您也安装了以下库: matplotlib , datetime , geopy , math , numpy , pandas , haversine 和 plotly (可选)。下载这些库,并确保下面的代码可以成功运行。
import gpxpy
import matplotlib.pyplot as plt
import datetime
from geopy import distance
from math import sqrt, floor
import numpy as np
import pandas as pd
import plotly.plotly as py
import plotly.graph_objs as go
import haversine
将 gpx 数据加载到 Python 中就像以读取模式打开文件并将其解析成一个新变量一样简单。
gpx_file = open('my_run_001.gpx', 'r')
gpx = gpxpy.parse(gpx_file)
看一下这个新对象,注意它是一个由一系列 GPXTrack 对象组成的 GPX 对象。GPXTrack 对象依次存在于一系列 GPXTrackSegment 对象中,这些对象依次存在于 GPXTrackPoints 中。这些点是我们感兴趣的四值数据点。可以通过经度、纬度、高程和时间属性访问。
在使用数据之前,检查数据在这些对象之间是如何划分的很重要。您可以通过检查轨道、段和点列表的长度来完成此操作。
len(gpx.tracks)
len(gpx.tracks[0].segments)
len(gpx.tracks[0].segments[0].points)
在我们的例子中,轨道和片段的长度都是 1。这意味着所有数据都集中在第一个轨迹的第一个段的点属性中。创建一个直接指向数据点列表的新变量是有意义的。
data = gpx.tracks[0].segments[0].points
看看你的起点和终点,确保一切都有意义(即开始时间
## Start Position
start = data[0]
## End Position
finish = data[-1]
一旦你找到了所有的数据,把所有的东西都放进一个数据框就很容易了。只需创建一个空的数据帧,并在将所有数据点添加到数据帧时遍历所有数据点。
df = pd.DataFrame(columns=['lon', 'lat', 'alt', 'time'])for point in data:
df = df.append({'lon': point.longitude, 'lat' : point.latitude, 'alt' : point.elevation, 'time' : point.time}, ignore_index=True)
数据帧的头部应该如下所示:
请注意,数据点之间的时间间隔应该是一秒钟(对于 Strava,您可以在设置中进行更改)。不幸的是,由于连接问题,我的设备无法始终提供 GPS 数据。在这种失败的情况下,数据点被跳过(没有任何种类的错误),应用程序将在下一个时间间隔收集数据。重要的是要记住这一点,以便进一步分析,而不是假设所有点之间的间隔是相同的。
绘制数据
现在我们已经加载了数据,我们可以通过绘制一些基本的图表来开始探索它。最简单的两个是 2d 地图(经度对纬度)和我们在活动中的高度增益(高度对时间)。将这些图与我们应用程序中的图进行比较,我们可以看到,到目前为止,我们做得相当不错。
plt.plot(df['lon'], df['lat'])
plt.plot(df['time'], df['alt'])
如果我们想变得更有趣,我们可以用 plotly 绘制一条数据的交互式 3d 线。虽然这个情节是否给我们的故事增加了任何分析价值还有待商榷,但从另一个角度看你付出的巨大努力总是让人感觉很好。如果你以前没有用过 plotly,别忘了在 plot.ly 上创建一个账户,并在凭证文件中设置你的用户名和 API-key。
_data = [go.Scatter3d(x=df['lon'],
y=df['lat'], z=df['alt'], mode='lines')]py.iplot(_data)
如果你想学习如何在谷歌地图上叠加你的地图,看看这个关于 gmplot 的教程。
转换数据
虽然到目前为止我们做得很好,但我们仍然缺少一些关键价值,如距离和速度。计算这两个似乎不太难,但是有几个陷阱。第一,我们必须考虑两个 LL 点(经度,纬度)之间的距离不是直线,而是球面。
Spherical distance vs Euclidean distance
有两种主要的方法来计算球面上两点之间的距离:哈弗森距离和文森特距离。这两个公式采用不同的方法计算距离,但这超出了本文的范围。你可以在他们的维基百科页面找到更多信息:哈弗辛公式维基和文森提公式维基。
下一个问题是,我们可能要在计算中考虑海拔的增加或减少。最简单的方法是计算球面 2d 距离,然后使用欧几里德公式添加第三维度。下面的公式显示了这最后一步。
distance _ 3d = sqrt(distance _ 2d * * 2+(alt 2—alt 1)* * 2)
现在我们有了所有需要的理论背景,我们可以开始在代码中实现这个公式了。为了方便起见,我们让数据框架保持原样,并像以前一样遍历所有数据点。我们为距离公式的每一个可能的实现创建一个列表(Haversine 或 Vincenty 和 2d 或 3d ),并将每个数据点的总距离添加到列表的末尾。
当我们遍历数据点时,我们还为所有连续数据点之间的高度差、时差和距离差创建了一个列表。
alt_dif = [0]
time_dif = [0]
dist_vin = [0]
dist_hav = [0]
dist_vin_no_alt = [0]
dist_hav_no_alt = [0]
dist_dif_hav_2d = [0]
dist_dif_vin_2d = [0]for index in range(len(data)):
if index == 0:
pass
else:
start = data[index-1]
stop = data[index]
distance_vin_2d = distance.vincenty((start.latitude, start.longitude), (stop.latitude, stop.longitude)).m dist_dif_vin_2d.append(distance_vin_2d)
distance_hav_2d = haversine.haversine((start.latitude, start.longitude), (stop.latitude, stop.longitude))*1000dist_dif_hav_2d.append(distance_hav_2d)
dist_vin_no_alt.append(dist_vin_no_alt[-1] + distance_vin_2d)
dist_hav_no_alt.append(dist_hav_no_alt[-1] + distance_hav_2d)
alt_d = start.elevation - stop.elevation
alt_dif.append(alt_d)
distance_vin_3d = sqrt(distance_vin_2d**2 + (alt_d)**2)
distance_hav_3d = sqrt(distance_hav_2d**2 + (alt_d)**2)
time_delta = (stop.time - start.time).total_seconds()
time_dif.append(time_delta)
dist_vin.append(dist_vin[-1] + distance_vin_3d)
dist_hav.append(dist_hav[-1] + distance_hav_3d)
为了进一步方便,我们可以将数据放入之前创建的 dataframe 中。
df['dis_vin_2d'] = dist_vin_no_alt
df['dist_hav_2d'] = dist_hav_no_alt
df['dis_vin_3d'] = dist_vin
df['dis_hav_3d'] = dist_hav
df['alt_dif'] = alt_dif
df['time_dif'] = time_dif
df['dis_dif_hav_2d'] = dist_dif_hav_2d
df['dis_dif_vin_2d'] = dist_dif_vin_2d
使用下面的 print 命令检查结果。
print('Vincenty 2D : ', dist_vin_no_alt[-1])
print('Haversine 2D : ', dist_hav_no_alt[-1])
print('Vincenty 3D : ', dist_vin[-1])
print('Haversine 3D : ', dist_hav[-1])
print('Total Time : ', floor(sum(time_dif)/60),' min ', int(sum(time_dif)%60),' sec ')
输出应该是这样的。让我们将我们的结果与跑步应用程序显示的统计数据进行比较。
有几件事需要注意。首先,我们所有的总距离计算——尤其是 2d 的——似乎是我们的应用程序为我们计算的距离的一个很好的近似值。其次,总活动时间与我们的计算完全一致,但移动时间似乎不同。
这可能意味着每当两个数据点之间的距离过小时,应用程序就会停止移动时间,但仍然会考虑距离,例如,当我们必须减速并停下来等红绿灯时,这可能是现实的。
在这种情况下,我们的二维计算是正确的,我们可以得出结论,该应用程序没有考虑海拔。app 公司的一篇博文确实证实了这一点。
假设表面平坦,不考虑来自地形的垂直速度。—斯特拉瓦
令人担忧?不完全是。应用程序提出的距离和我们最大的 3d 估计值之间的差异只有 61m (0.55%)。这意味着 100 公里跑(或骑行)的总四舍五入将是大约 600 米。请注意,如果你从事更高强度的活动(山地自行车或徒步旅行),这种差异会增加。
让我们看看是否可以找出 Strava 使用哪个阈值来停止计时器(从而提高我们的平均速度)。要做到这一点,我们需要创建一个新的变量来计算我们每秒米数的运动(而不仅仅是每个数据点的运动,因此我们创建了时间差变量)。让我们为我们的哈弗辛二维距离这样做,因为这是由应用程序提出的距离的最接近的近似值。
df['dist_dif_per_sec'] = df['dis_dif_hav_2d'] / df['time_dif']
有了这个新变量,我们可以迭代一系列阈值,比如说 50 厘米和 1 米之间的阈值,并尝试找出哪个阈值的计时器超时最接近 51 秒。
for treshold in [0.5, 0.6, 0.7, 0.8, 0.9, 1]:
print(treshold, 'm', ' : Time:',
sum(df[df['dist_dif_per_sec'] < treshold]['time_dif']),
' seconds')
你的笔记本应该打印出这样的内容。
因此,我们可以得出结论,如果每秒钟的移动小于 80 厘米,应用程序不会将其视为移动,并停止计时器。这似乎很合理,因为每秒 80 厘米大约是每小时 2.9 公里,这个速度远远低于大多数人他们的步行的速度。
说到速度,我们不妨计算一下每个数据点的速度。首先,我们在数据框架中创建了一个名为 speed 的新列。这个新变量的计算方法是,用以米为单位的行驶距离除以以秒为单位的时间,然后转换为公里/小时。
df['spd'] = (df['dis_dif_hav_2d'] / df['time_dif']) * 3.6
接下来,我们过滤掉每秒移动大于 90 厘米的所有数据(原因见上一节)。
df_with_timeout = df[df['dist_dif_per_sec'] > 0.9]
然后我们计算加权平均速度,并将其转换为每公里分钟秒(跑步者广泛使用的度量标准)。
avg_km_h = (sum((df_with_timeout['spd'] *
df_with_timeout['time_dif'])) /
sum(df_with_timeout['time_dif']))print(floor(60 / avg_km_h), 'minutes',
round(((60 / avg_km_h - floor(60 / avg_km_h))*60), 0),
' seconds')
这导致平均速度为每公里 5 分 3 秒,与我们的应用程序提出的速度完全相同。让我们也画一个我们的速度图。为每秒绘制一个数据点会过于精细,所以我们将为每 10 秒绘制一个平均速度数据点。
因此,创建一个新的变量,将我们的时间差的累积和向下舍入到 10 秒,并根据它绘制聚合速度。
df['time10s'] = list(map(lambda x: round(x, -1)
, np.cumsum(df['time_dif'])))
plt.plot(df.groupby(['time10s']).mean()['spd'])
结果是一个平滑的线图,我们可以看到以千米/小时为单位的速度和以秒为单位的时间。
我们要仔细研究的最后一个指标是仰角增益。根据 apps 文档,累积高度增益是指整个行程中每次高度增益的总和。这意味着我们应该只考虑正的高度增益。
我们可以写一个简单的函数,把它映射到数据帧的高度差栏上。
def positive_only(x):
if x > 0:
return x
else:
return 0pos_only = list(map(positive_only, df['alt_dif']))sum(pos_only)
总和约为 237 米,与我们的应用程序告诉我们的高度(150 米)相差甚远。仔细观察海拔高度的差异,我们可以看到它精确到 10 厘米。
在跑步的情况下,这可能是在人行道上跳上跳下,或者用手里的手机挠头。将数字四舍五入到 1 米是有意义的。我们可以通过在之前的结果上映射一个 lambda 函数来做到这一点。
sum(list(map(lambda x: round(x,0) , pos_only)))
新的结果是 137 米,非常接近应用程序提出的海拔高度。知道了这一点,我们还应该用这些新的高程值重新计算我们的 3d 距离。不用计算,我们知道总距离会下降并接近 2d 距离。这使得不考虑总距离中的高度增益更加合理。
值得思考的事情
我将用一个关于海拔增加的启示来总结这篇文章:在实际跑步过程中,我没有增加任何海拔(除了几个小楼梯)。更有甚者,我的手机就像大多数低端市场的手机一样,没有气压计。
气压计是一种测量大气压力的仪器,尤其用于预测天气和确定海拔高度。但是斯特拉发是如何确定我们的高度的呢?答案是 Strava 的高程底图。
它是使用来自社区的数据创建的。通过从过去上传到 Strava 的任何活动中收集气压高度计测量值(从带有气压计的设备中),他们能够建立一个全球海拔数据库。
目前,底图还不够可靠,也没有覆盖足够多的世界。但是,如果他们能够在未来使其更加可靠,他们可能能够结合 3d 计算和更复杂的海拔增益模型,为所有的运动者提供更准确的统计数据。
下一步是什么?
在本文的后续文章中,我们将可视化在本教程中与另一个热门人物一起获得的所有数据: QlikView 。
—请随时在评论中或私信中向我指出任何不一致或错误。—
Turi 创造的方式正在颠覆机器学习的格局
原文:https://towardsdatascience.com/how-turi-create-is-disrupting-the-machine-learning-landscape-37b562f01eab?source=collection_archive---------5-----------------------
几个月前——1 月 18 日星期四——我在西雅图的第一次聚会上发表了演讲。这是我从芝加哥搬家后的第三天,所以没有浪费时间!
原因?没有什么比苹果开源 Turi Create 的消息更让我关注的了,这是它在 2016 年收购 Turi 的后拥有的机器学习(ML)库。
一句话:Turi Create 是一个 Pythonic 式的机器学习库,非常强大且易于使用,你应该探索它的能力!
首先,我要感谢 Metis 、 BeMyApp 和 Intel 共同赞助此次活动。
这篇文章是 meetup 的总结:我做了什么,观众问了一些相关的问题,一些意外访客的记录,以及我对 Turi Create 未来发展的想法。我还将分享最佳实践、经验教训以及对我未来项目的想法。
Turi Create
我展示的东西
首先,我分享了在准备 GraphLab Create 环境时学到的经验。眼尖的读者可能会注意到,GraphLab Create(以下简称 GC)看起来与 Turi Create(以下简称 TC)是不同的产品;Turi 团队告诉我,这种差异只是表面现象,因为两个包使用相同的核心代码,开源变体(TC)基本上可以做 GC 能做的一切。因此,虽然一些程序项目可能有所不同,但一般用法是非常相似的。
为了深入了解产品是如何发展的,我强烈推荐创始人 Carlos Guestrin 的这个演示。它已经有五年的历史了,但是 Guestrin 触及了早期开发阶段的动机和关注领域。为了了解软件包在“堆栈”中的位置,这里有一个常见的架构:
GC Architecture
值得注意的是,GC 和 TC 都运行在 Python 2 上,环境必须用特定版本的支持库来设置。作为一个挑战,我试图将新的包合并到我的主 anaconda 环境中,但是遇到了版本和依赖地狱。所以,对于第一次来说:
- 确保你有至少 8GB 的内存用于严肃的工作,或者设置在虚拟环境中
- 根据设置说明创建一个新的 conda 环境
- 然后,注册许可证(针对 GC)
- 如果使用 TC,将 repo 克隆到您的机器上
- 尝试入门指南中的一些练习
加载和管理数据与熊猫非常相似:
import graphlab as gl
%matplotlib inline# load data into SFrame
url = '[https://raw.githubusercontent.com/plotly/datasets/master/data.csv](https://raw.githubusercontent.com/plotly/datasets/master/data.csv)['](https://static.turi.com/datasets/millionsong/song_data.csv')df = gl.SFrame.read_csv(url)
从这里,我们可以调用汇总统计数据和一个交互式控制面板,它具有以下功能:
# summary statistics for a column
df['column'].sketch_summary()# show dashboard
df.show()
然后,您将能够快速找到特定的行范围,跟踪更多的汇总统计数据,并构建如下所示的交互式图表:
View large datasets with ease!
Heatmaps with various scaling functions
Line charts with zoom and drag capabilities
建模看起来与 SciKit-Learn 非常相似,但这是一件好事。如果它没坏,不要修理它:
# load housing data and fit a linear model
url = '[https://static.turi.com/datasets/regression/Housing.csv'](https://static.turi.com/datasets/regression/Housing.csv')
x = gl.SFrame.read_csv(url)lm = gl.linear_regression.create(x, target='price')
值得注意的是,GC 会自动创建“样本外”验证集,以跟踪真实的模型性能。有许多巧妙的技巧可以让你更有效地编码,更快地得到结果。然而,GC 预先选择了常见的方法,因此您需要了解文档中的默认参数和假设!
与 SciKit-Learn 相比,一个常见的观众问题与性能有关。如果你仅仅使用 CPU 来拟合模型或者搅动数据,差别很小,并且会归结为代码优化、稍微不同的求解方法等等。然而,如果你有一个高度可并行化的任务,并且运行在 AWS P2 或 P3 实例上,或者你在办公室里有一个强大的 Cuda 设置,我们所说的 TC 会快几个数量级。
这个事实本身就是将你公司的模型转移到 Turi 环境的完美理由。
目前,TC 和 SciKit-Learn 基于 Python 的 ML 库之间的一般比较如下:
Scikit-learn 的优势:
- 开源:Scikit-learn 是一个开源库,有 500 多个贡献者和强大的支持
- 对 Python 3 的支持:Scikit-learn 支持 Python 3,而 Graphlab Create 只与 Python 2 兼容
- 更多算法:与 Graphlab 相比,Scikit-learn 拥有更多算法
Graphlab Create 的优势:
- Graphlab Create 是一款 24/7 全天候支持的商业软件
- 可伸缩性:Scikit-learn 实现只在内存中执行。GraphLab Create 能够扩展到核外,许多多线程实现利用了机器上的多个核。
- GPU 支持:你可以安装带有 GPU 加速的 Graphlab Create,它可以让某些任务的速度快得惊人
最后,在演讲之后,Turi 的三个核心成员——负责 GC 和 TC 的编码和开发——走上前来介绍他们自己!现在,苹果的员工们,我们就产品的未来、外部市场的看法和商业模式进行了深入的交谈。
太神奇了!
也许是好事,我不知道他们一直在看着我…无知是福。
苹果和机器学习
苹果非常认真地建设其机器学习(ML)能力,因为它寻求在利润丰厚的“大数据”领域与谷歌和脸书等其他巨头竞争。然而,苹果的策略却截然不同。作为一个以客户数据隐私为荣的组织,我们的重点是利用苹果对其产品用户的了解来改善总体用户体验,包括:
- Siri 变得更加智能预测你的需求
- Apple Music 利用 ML 帮助您发现令人惊叹的新艺术家
- 来电显示用于拨打您 iPhone 的新号码
- 使用 ML 来预测你的卡路里消耗和一般活动
- 差异化隐私为所有这些服务提供动力
在苹果的定期更新并面向公众的博客上,我们可以看到最新最棒的产品和服务的暗示——以及数据科学是如何实现的。
Turi 如何创造可能进化
TC 已经是 Pandas 和 SciKit-Learn combo 的有力竞争对手,拥有完整的堆栈数据管理和建模能力。它快速而高效,并具有某些功能,如 GPU 加速,这些功能在 SciKit-Learn 中不存在或处于早期阶段。此外,由于该产品是苹果 ML 推广的一个关键方面,我希望看到与框架的深度集成,如 Core ML 、 ARKit 和 HealthKit 。
Turi 与 Tensorflow 等平台有功能重叠,鉴于对神经网络等模型的关注和宣传,这种重叠可能会在深度学习领域增长。事实上,GPU 加速的一个关键价值主张是允许更快地拟合大型数据集上的深度模型。我也希望看到像 Keras 这样的包装器扩展数据科学家修改参数和架构的便利性。
已经有一个快速指南介绍如何将 TC 集成到 iPhone 应用程序中,并通过 App Store 直接向用户部署你的 ML 模型。当前的型号产品包括以下列表,但随着时间的推移,我们应该会看到更多的产品:
- 推荐系统
- 图像分类
- 图像相似度
- 物体探测
- 活动分类器
- 文本分类器
最后,我希望在未来几年看到对主题建模和自然语言处理空间的更深入的推动,特别是随着 Siri 的不断完善。
您企业的下一步
TC 似乎是一个令人惊叹的平台,但真正重要的问题是:
Turi Create 如何让我的业务受益?
- 如果你的企业出售订阅服务,或者软件许可,TC 的广泛的分类模型套件可以决定哪些客户更有可能流失,或者“流失”。然后,您可以激励这些客户续订,或者确定另一种产品是否符合他们的需求。
- 如果你的公司提供许多产品或服务——并且你对你的客户群有所了解——你可以实施 TC 的推荐系统来量化客户的兴趣,并对你营销或提供的新产品进行优先排序。这些模式为亚马逊和易贝的“推荐给你”列表、Spotify 的音乐播放列表管理和 GrubHub 的供应商聚光灯提供了动力。
- 最后,如果您经营一家使用身体传感器收集心脏、大脑或活动指标的医疗企业,TC 的活动分类器可以从加速度计、陀螺仪、恒温器等设备中获取数据。该模型将预测可能发生的锻炼形式、心脏状况或医疗紧急情况。这个应用程序可以扩展到其他领域,如网络安全、工程应用程序或任何从噪声数据中推断模式的领域。
Classifying Activities from Gyroscope Data
我业务的下一步
我想在 TC 环境中重新创建我过去的一些项目,作为一个具有审查基线的真实世界测试。我将把这些代码中的一部分——尤其是我的集合模型——部署到各种 AWS 实例类型中,以便判断哪种架构能给我带来最高的性能。
今年,我专注于将更多的数据科学应用到我的投资和加密货币策略中,TC 是建立神经网络或类似投资组合优化模型的有力竞争者。
最后但同样重要的是,作为 Metis 的数据科学讲师,我将寻找将 TC 纳入我们课程的方法,以便让学生了解。在我的书中,最终的成功是:一名学生构建了一个以 ML 为中心的 iOS 应用程序,并成功地将其部署到拥有超过 10 亿智能手机用户的市场中!
你认为如何开始使用 Turi Create?在下面评论或者在推特和 LinkedIn 上联系我。
威斯敏斯特袭击一小时后推特如何回应
原文:https://towardsdatascience.com/how-twitter-responded-an-hour-after-the-westminster-attacks-bd2823a31195?source=collection_archive---------4-----------------------
3 月 22 日威斯敏斯特袭击的消息像许多恐怖袭击一样传播开来:一名目击者的推文、英国广播公司的现场报道和大量来自直升机的空中视频,同时新闻媒体争相将这些片段拼凑起来。伦敦震惊地看着大本钟成为高度警戒的警戒线中心。但是在他们哀悼之前,许多人只是想知道发生了什么。
就像许多突发新闻事件一样,Twitter 成了了解事件最新进展的最快途径之一。为了更好地了解人们在混乱时期如何使用社交网络,我筛选了 30 分钟内收集的 5 万条推文样本。这些推文是在袭击者开始穿越威斯敏斯特大桥的致命驾驶后一小时发出的。
我发现的是各种情绪的巨大混合体:从团结和众包到伊斯兰教和移民的危险。在运行一些统计分析后,下面的网络图显示,通过映射该时间段内所有带有#Westminster 的推文的转发模式,可以找到八个潜在的社区。
图形上的每种颜色代表与攻击相关的不同推文社区。一个节点可以连接到两种不同的颜色,但颜色是基于它的原始源 tweet。lines 表示由一个帐户发送的原始推文的转发。尽管许多账户在一天中被转发了很多次,但我在分析数据时发现了一些要点。
大多数人想要帮助或显示团结
在数据集中发现的社区中,至少有三个与众包或展示团结有关。@MetpoliceUK 是转发量最大的账户之一,代表了大部分粉色和绿色的节点。这段时间转发量最大的推文来自大都会博物馆,敦促人们对受害者表现出谨慎和尊重。
大都会博物馆还要求人们给他们发送任何关于这次活动的信息。这条推文被广为流传,不管图中是什么社区。
灰色社区代表非新闻账户,通常包含表示关注或声援袭击受害者的推文。然而,这组情绪可能比图中描绘的这一种颜色大得多,因为由于语言的差异,所有法语和西班牙语的推文都被自动分为一个单独的类别。
更大的新闻网络仍然是混乱中最共享的来源
尽管 Twitter 允许任何人传播此类事件的新闻,但像@BBCBreaking 和@AP 这样的大型新闻网络仍然是正在发生的事件的新闻报道的首选来源。以至于这些推文被归类到一个独特的社区。
其他新闻网络也迅速报道了这件事(用橙色表示)。像@DailyMail、@Skynews、@iTVNews、@DailyMirror 和@Telegraph 这样的账户遍布网络中心,成为其他社区发展的基础。
极右的民族主义者抓住机会传播恐惧
哪里有恐惧,哪里就有人愿意煽动恐惧。图表底部用蓝色表示的社区通常可以被描述为表达极右或民族主义情绪。这些推文的严重性和意识形态各不相同。转发量最广的账号有@DefendEvropa、@V_of_Europe 和@Foxnews。
一些推文只是在传播袭击的消息,或者呼吁谨慎。但是其中一些最大的节点(因此当时转发量最大)是带有反伊斯兰情绪的推文。
无论是公开的政治还是对事件的本能反应,蓝色社区中的推文似乎表达了强烈的民族主义意识形态。这些推文在他们的社区中仍然相当孤立,但在某些情况下,会传播到图表的其他部分。
当考虑到两个社区由@MetpoliceUK 推文主导这一事实时,极右翼社区在相关转发量方面排名第二。
尽管这八个社区出现在数据集中,但还需要更多的分析来了解信息是如何随着时间的推移而传播的。然而,作为袭击发生一小时后许多问题仍未得到解答的推特样本,这些数据仍然揭示了一些关于混乱时期信息在推特上如何传播的见解,以及什么类型的账户正在分享它们。
用于分析的工具:
- Python:用于抓取 Twitter
- Excel:用于清理数据
- Gephi:用于创建网络图和运行统计
- Adobe Illustrator:用于创建图形
在此亲自探索 Gephi 图。在这里下载原始数据。所有代码都在 Github 上。
原载于 2017 年 4 月 1 日Benjamin cooley . me。
我们如何建立一种全新的预测分析方法
原文:https://towardsdatascience.com/how-we-build-a-completely-new-way-of-doing-predictive-analytics-4be407420694?source=collection_archive---------9-----------------------
首先,这是当前在数字营销中进行预测分析的主要问题
[## DejaVu |基于人类认知和神经科学的人工智能预测分析| 77Sense.com
加入免费测试版
77sense.com](https://77sense.com/dejavu)
传统的预测分析工具从网站的所有访问中获取总数据,并根据预期结果对数据进行细分。一笔交易。这样,一些数据被遗漏(标记为噪声),以便更深入地挖掘成功的数据(标记为信号)。
然后,对标记的数据进行数据挖掘,以找出与结果正相关或负相关的模式,换句话说,哪些可能导致预期的结果,哪些没有。
这些模式用于创建模型,这是一种数学表示,可以根据以前的数据(训练数据)计算未来的数据。然后,该模型用于预测输入数据的结果,并评估模型的性能。
通常会使用多种模型,以找到最适合数据的模型。
没有问题吧?—这比不做好得多
正确—做这种数据挖掘、建模和预测比不做要好得多。但这根本不是做预测的最佳方式。
为什么?
因为我们建模的数据是人类行为,而人类行为是由人类创造的,人类行为仍然是科学试图解开的东西。30 多年的神经科学文献证明了这一挑战——然而,就在我们进入一个令人兴奋的人工智能和机器学习时代时,神经科学也已经成熟为一个可靠的共识,即是什么让我们人类做出决定(买房子或可乐)
你数据中的每个点都是一个人——试图在你的网站上做一些事情
那么有什么问题呢?
神经科学可以同意的是,选择/决定是由三个因素驱动的——注意力、情绪和记忆。我们所关注的,结合我们的记忆,以及对此的情绪反应,是决策过程中最强的因素。
这三个因素不断更新我们对世界的认知,以及我们正在执行的任务。
通过这些过程获得的数据决定了我们如何看待这个世界。这就是为什么感知会因人而异——更重要的是因时间而异。
所以……大脑是我们为什么做出一个决定而不是另一个决定的答案——或者更准确地说,是注意力、情感和记忆
我们面临的挑战是抛弃看待数据的“旧”方式,提出使用相同数据的新方式,这种方式与屏幕后面的人类大脑中实际发生的事情更加一致。
一个激进的挑战需要一个激进的新方法——所以我们建立了一个神经营销平台来快速测试世界任何地方的数百人(emolab . io)——我们建立了一个系统来简化这些测试的招募(参与者)
长话短说——我们出去测试了来自世界各地的 6500 人,让他们像在家一样浏览网页。我们使用 EmoLab 每秒钟测量他们的注意力、情绪和记忆激活 60 次。
这产生了超过 6 亿个数据点,涉及人类的注意力、情感和记忆在我们控制一切的环境中,我们还能够逆向工程他们的整个经历。
- 通过专有的机器学习方法,将 HTML/Javascript & CSS 转换为单个网页和域的分类,我们保留了网页和域的意图的细节。我们还对与页面相关的 DOM 树层次结构进行了深入分析(检测顶部菜单、左侧导航、过滤器等)
- 我们收集了这个人看向哪里的眼球轨迹,以及随后对这个元素的情绪反应,以及之前元素的连锁反应
- 然后,我们收集了关于鼠标移动和键盘敲击的非常详细的信息,以及用户在普通网站上进行的滚动和其他标准微事件的具体信息。
与情绪反应相关的微事件数据库
这就产生了一个我们称之为微事件指纹的大型数据库——微事件指纹是与特定情绪反应相关的特定类型页面上的特定鼠标移动。
我们还创建了一种实时方法来预测用户在页面上的位置——无需使用网络摄像头或眼球跟踪设备——仅使用鼠标移动细节。
结果是一个我们命名为 SuperSentient 的小 javascript 片段——它纯粹基于鼠标移动来预测用户的注意力和情绪反应。
预测分析不应该是将数据位放入虚拟框中并试图预测用户的购买意愿,而应该是预测意图、动机和内部目标设置,以便我们可以在这方面帮助用户,创造最终的用户体验。
我们对每个会话进行实时预测分析,比以前更快、更可靠、更精确。
[## DejaVu |基于人类认知和神经科学的人工智能预测分析| 77Sense.com
加入免费测试版
77sense.com](https://77sense.com/dejavu)
我们如何在 AWS 基础设施上构建数据科学 Web 应用程序“Route Planner X”
原文:https://towardsdatascience.com/how-we-built-data-science-web-app-route-planner-x-on-aws-infrastructure-71f814247a0c?source=collection_archive---------12-----------------------
如今,找到拥有数百万或数十亿行数据的公司比以往任何时候都容易。然而,问题不在于“如何创建更多的数据”,而在于
如何利用这些庞大的数据?
解决这个问题的一个方法是将数据迁移到数据仓库,这是为分析任务构建的数据库。也就是说,构建数据仓库是一个昂贵且耗时的过程。
诸如 AWS 、 GCP 或 Azure 等公共云的出现为解决这个问题提供了更好的方法。在这篇博客文章中,我将告诉你我们的 5 名毕业生团队如何构建一个端到端的数据科学 web 应用程序来处理 1.5 亿行数据。
什么是「路线规划师 X」?
路线规划师 X 是我们为墨尔本数据马拉松 2018 (澳大利亚最大的数据马拉松活动之一)在 2 个月内构建的应用程序的名称(我们团队的名称是“不是热狗”)。有 400 多名参与者,包括学生和非学生。
我们真的很努力,在提交的最后一天,我们只有 6 个小时来建立演示文稿。最终,这种努力是值得的。我们获得了非学生 Data2App 类别的二等奖。
路线规划器 X 的想法基于构建“等时线地图”的想法,该地图显示了人们在特定时间内从特定点可以行驶多远。
我们将等时图与 PTV(维多利亚公共交通)数据和500 亿郊区火车环线计划结合起来,得出了你可以在上面的视频中看到的故事。
Example isochrone built from PTV transportation feed (Image by author)
关于数据集:Myki 事务数据
Myki card in action. Thank you for the photo from PTV Website (This is the old Myki card, the new one is in black color)
在继续讨论应用背后的技术之前,让我快速浏览一下输入数据是什么。
每年为墨尔本数据马拉松的参与者提供的数据集都是不同的。去年,我们有一个关于药物的非常有趣的数据集。今年,数据集更加有趣。这是关于墨尔本数百万乘客使用的交通工具。
当任何乘客点击闸机上的 Myki 卡进入/离开任何车站时,都会收集这些数据。该数据集涵盖了墨尔本的所有交通类型:火车、电车和公共汽车。
由于墨尔本使用公共交通的每个人都将被记录在这个数据集中,我们在提取见解时获得了很多乐趣,并了解了一些有趣的行为,如许多人在免费电车区旅行时如何点击他们的 Myki 卡。
我相信总共有大约 7.5 亿行数据。然而,80%的数据集发布得太晚,没有多少团队有足够的时间将这些数据投入使用。我们依赖于第一天发布的前 1.5 亿行。
数据已经出来了。关系表的 txt 文件。没有合适的数据字典来告诉我们哪个表和哪个列是哪个。所以我们想出了我们自己版本的表之间的关系:
Database Schema (Note: This may not be the final version of the schema we used since I got this from our team’s early conversation on the Slack chat) (Image by author)
大数据的数据接收
我知道 1.5 亿行对于一些人来说可能听起来像是儿戏。然而,根据我们的团队成员在墨尔本 Datathon 的 Fleep chat(类似于 Slack 的群组聊天室)上发现的情报,许多团队都在努力将数据读入内存。
我们的团队尝试了 3 种方法来读取这个数据集。我们在数据接收上浪费了大量时间(和金钱)。我们尝试了三种方法:
方法 1:笔记本电脑上的 RDBMS
这种方法是在笔记本电脑上安装关系数据库管理系统,如 MySQL 或 PostgreSQL。然后将数据导入到这些 RDBMS 中,以便查询数据。
这是我去年为 2017 年墨尔本数据马拉松做的。如果我没记错的话,大约只有 800 万到 1200 万行数据。我们可以轻松地加载 800 万行数据并即时查询。在我的 Macbook 上,查询过程大约需要 3-4 分钟。这是缓慢的,但仍然可以接受。
然而,对于 1.5 亿行数据,这种方法对于我们探索数据来说效率不高。因此,我们转向了云计算。
方法 2:AWS 云上的 RDBMS(AWS RDS)
云技术赋予了我们梦寐以求的计算资源。但是,我们不能只是启动最大的机器,让它永远开着。正如本大叔(来自蜘蛛侠)曾经说过的“权力越大,责任越大”,AWS 中的权力越大,责任也就越大(要支付大额账单)。
尽管 AWS 赞助了墨尔本 Datathon,并给予每个团队 500 美元的 AWS 积分,但我们仍然超出了限额,因为我们的团队在我们采取下一种方法后忘记了终止数据库。
Pricing table per hour for AWS RDS. We are using the biggest machine for $7.68 per hour. Photo by AWS
我们使用了名为“AWS RDS”(关系数据库服务)的 AWS 服务,它基本上是基于云的 MySQL。查询速度比使用本地机器快,但是我们发现查询时间不够快。一些查询可能需要 30-60 分钟。
由于我们只有周末有时间(每个人都在全职工作),我们需要在我们拥有的短时间内完成工作。那时我们在 AWS 中试验了相当新的服务,叫做 Athena 。
方法 3: AWS Athena —来自文本文件的 SQL 查询引擎
Athena lets you write SQL to query data directly from text files (Image by author)
Athena 是 AWS 服务,让我们可以从存储在 S3 桶(AWS 的云存储,类似于 Dropbox)中的文本文件中查询信息,而不必担心打开/关闭数据库服务器。价格也比 RDS 实惠很多。
Athena 扫描每 TB 数据的成本为 5 美元。这意味着我们可以通过优化查询来扫描更少的数据,从而轻松控制成本。
我们的团队完全转向 Athena 进行分析。这比我们迄今为止尝试的任何其他方法都要快,而且成本只是 RDS 的一小部分。我们还发现了使用 Python 的 boto3 库向 Athena 发送查询的方法。这使得 Athena 的自动化非常简单。
我们想尝试的另一种方法是:BigQuery
在这次比赛中,我们听到了很多使用 BigQuery 的团队的成功故事。下次有机会做 Datathon 时,我们一定会尝试 BigQuery。
在我们进入下一节讨论如何整合之前,我想提一下,我发现墨尔本数据马拉松是一个试验我们以前没有尝试过的新技术的好方法。与没有时间学习新技术的 24-48 小时黑客马拉松不同,墨尔本数据马拉松给了我们两个月的时间。在数据马拉松开始之前,我们没有使用或了解过雅典娜。
Web 应用架构
您可能会从视频中注意到,我们的提交包括 2 个应用程序:第一部分是可视化应用程序,第二部分是路线规划器 X。
可视化应用程序从 AWS 基础设施查询数据集,如下图所示:
Frontend & Backend technologies for visualization part (Image by author)
这里是每项技术的简要描述,请随时提问:)(我可能无法在后端部分给出准确的答案,因为我的工作主要是在前端)
- HTML / CSS —用于页面布局。CSS 用于将页面分成两半。
- LeaftletJS —用于在可视化中绘制交互式 choropleth 地图。这是我们视觉化的主要部分。
- D3。JS —用于在页面右侧绘图。我们还使用了 C3。JS 是 D3 的包装器。
- jQuery —用于管理可视化中的交互。
- API 网关 —用于构建 web API 端点,以便我们的前端可以与后端联系,即使它们不在同一个服务器上
- Lambda + Python —用于调用 Athena 查询数据。然后,结果将通过 API 网关发送回前端。
- 雅典娜 —用于查询存储在 S3 桶中的文本文件。如前所述,雅典娜是超级快,用户不必等待分钟。
- S3 —用于以快速、安全且经济高效的方式存储整个数据集。
注意,我们将前端和后端解耦,以增加系统的灵活性。发生在前端或后端的基础设施的变化永远不会影响到另一方。
对于视频的第二部分,路线规划器应用程序,我们基于 OpenTripPlanner 的 API 服务器构建,它允许我们自定义数据以生成自定义的等时线地图。下图显示了我们使用的技术。
Frontend & Backend technologies for the app part (Image by author)
我们对应用程序部分使用了非常相似的架构。这部分的新组件是:
- VueJS —因为允许用户添加他/她自己的数据点。我们必须使用 VueJS 来帮助管理输入数据。
- OpenTripPlanner — OTP 是使用自定义 GTFS 数据生成路线计划的 Java 客户端。我们使用 PTV·GTFS 的数据以及基于用户输入的合成路线计划,以绘制最终的等时线。
- EC2 —这基本上是云上的虚拟机。我们必须启动 EC2 实例,以便在其上安装 OTP。
墨尔本数据马拉松的主要收获
在今年的墨尔本数据马拉松中,我们学到了很多东西,并有机会尝试新技术。这绝对是一次无价的经历。如果我想分享一些关于这次数据马拉松的事情,这里是我想到的三件事:
要点 1)记得在使用完 AWS 资源后终止它们!!!
在 EC2 或 RDS 等流行的 AWS 服务中,您可以停止或终止实例。不同之处在于:
- 停止不会删除文件,稍后您可以再次启动,但是即使您已经停止,仍然会产生文件存储费用。对于 RDS,停止的实例将在 7 天不活动后自动重新启动。(我们就是这样赔钱的。它自己又开始了,直到一天过去了我们才知道。)
- 终止将从你的实例中完全删除所有文件。这种情况下不会有更多的成本。
请记住,为了阻止账单增加,您必须终止。
2)黑客马拉松/数据马拉松需要多种多样的技能
如果你不是从 ETL 到可视化无所不能的独角兽,这完全没问题。你不必能够端到端地做所有的事情。但是你的团队必须能够端到端地做所有的事情。
组建团队时,确保团队成员拥有不同的技能组合,涵盖各个领域,例如 datathon:数据工程师、数据分析、数据可视化、开发。
把这当成一个学习的机会
得点奖总比没奖好。但我总是专注于为未来的工作学习新技能,而不是专注于奖金。
我相信这些新技能对我的职业生涯会比你获得的奖励更有价值。哦!记得记下你所学到的东西。写博客也是分享和获得反馈的好方法,不管你对某些话题的理解是否正确。
我希望这篇博文对那些想在云上构建 web 应用程序的人有所帮助。如果你更喜欢在内部构建东西,请阅读我今年早些时候发表的【指南】用 React、NodeJS 和 MySQL 构建数据科学 Web 应用程序。
欢迎对任何问题发表评论,或给我发邮件询问 woratana.n@gmail.com 的任何问题。最后但同样重要的是,感谢墨尔本 Datathon 2018 的工作人员,他们是我生命中这件大事的幕后推手。
最初发表于 沃拉纳珀斯 。
我们如何使用 Flask 和 Docker 部署 scikit-learn 模型
原文:https://towardsdatascience.com/how-we-deployed-a-scikit-learn-model-with-flask-and-docker-53c97a6fc1a3?source=collection_archive---------2-----------------------
在我们的上一篇文章中,我们讨论了我们的客户满意度预测模型。我们使用了 AzureML studio 来首次部署这个机器学习模型,以服务于实时预测。在这篇文章中,我们将分享我们如何以及为什么使用 Flask 、 Docker 和 Azure App Service 从 AzureML 迁移到 Python 部署。在此期间,我们还尝试了 Python 的 Azure 功能。此外,我们开源了一个带有 Flask 和 Docker 的示例 Python API,用于机器学习。
在生成我们的第一个客户满意度预测模型之后,我们希望快速、轻松地部署它。AzureML 服务于这个目的,但也表现出一些困难。我们生成的模型是使用 scikit-learn 开发的,但是我们部署到生产环境的模型是使用 AzureML 生成的。因此,参数并不完全相同,我们测量的一些指标也不同。此外,我们有一些数据准备逻辑,由模型训练和实时预测共享,但在代码方面是重复的。最后,我们发现 AzureML GUI 非常慢,因此对用户不太友好。
从上述问题中,我们得出了对第二个预测模型部署架构的以下要求:
- 快速简单的部署
- 在本地环境中培训的相同模型可以部署到生产中
- 在生产和模型培训之间共享数据准备代码
- 轻松的端到端流量控制
- 不是必须的:易于集成到持续部署中(例如 codefresh )
首先,我们尝试在 Python 中使用 Azure Function rest API。设置非常简单,我们很快就能运行 Python 代码。此外,使用 Kudu 也很容易、快速且非常用户友好。虽然它显示了希望,但后来事情变得更加困难:
- 在 Windows 机器上安装机器学习的库更难一些——一些基本的库,如 NumPy 需要特殊处理,然后只是“pip 安装”
- Azure 函数在每个请求上运行所有的导入,在我们的情况下(numpy,scikit-learn,pandas)导入花费了大约 30 秒(更多细节请参见这个问题)——这对我们来说是一个障碍
最后,我们决定尝试部署我们自己的服务器,使用:
- flask:Python 的微型网络框架,非常容易设置
- 码头工人
- Azure 应用服务
我们从中获得了什么:
- 由于我们部署了自己的服务器,我们有了完整的端到端控制——这使得实时 API 和离线模型训练之间的代码共享变得容易
- 使用 Pickle 将离线训练的实际模型部署到生产中
- 由于 Docker 运行在 Linux 虚拟机上,不再有 Windows“pip 安装”的困难
- Docker 使这项服务可以在多个平台上托管——如果 Azure 应用服务出现问题,迁移将非常容易
- 从源代码 git 存储库到 codefresh 的轻松集成——这处理了我们所有的持续部署过程——每次提交到我们的 git 存储库都会将新代码部署到一个辅助服务,该服务可以轻松地转换为我们的主要实时服务
顺便说一下,Azure 对 Docker 的应用服务支持仍处于预览阶段――更多信息可以在这里找到。
想试试吗?
可在此处找到 docker 图像样本
可以在这里找到该架构的代码示例
在下一篇文章中,我们将分享更多关于我们新系统架构的实时性能、将会出现的新问题(总是有问题:-),以及更多关于我们新挑战和新特性的内容。
我们如何在 Kaggle 上发布一个成功的数据集
原文:https://towardsdatascience.com/how-we-published-a-successful-dataset-on-kaggle-2945de537597?source=collection_archive---------13-----------------------
以及它如何帮助传播我们公司的数据成果
大约一年前,我第一次访问了 Kaggle 网站。我被吸引去解决一些基本的机器学习问题(比如泰坦尼克号:灾难中的机器学习)。我发现这也是一个研究其他人的数据集,以及分享你自己的数据的好地方。
那时我在一家大公司工作,公司有非常严格的规章制度。共享任何数据都是不可能的。但这个想法一直萦绕在我的脑海里。过了一段时间,我离开了那家大公司,开始在一家名为 Olist 的中型初创公司工作。我们是巴西市场中最大的百货商店。我们的目录中有超过 20 万种产品,超过 4000 个卖家通过我们的平台销售他们的产品。
在那里,我们有足够的官僚作风来打消我发布数据集的想法。大约五个月前,我第一次在公司内部提出这个想法,但当时它还非常不成熟。提出了一些问题,例如:
- 我们应该发表什么?为什么?
- 有人会使用我们的数据吗?怎么会?
- 还有…如果任何竞争对手使用我们的数据怎么办?
在接下来的几个月里,这个想法不断发展,所有的问题都得到了解答。然后,经过一些开发过程,我们终于准备分享一些数据。大约两个月前我们在 Kaggle 上做过。本文的目的是解释我们是如何发布数据的,并在这个过程中为您提供指导。也许我们甚至鼓励你或你的公司也公布一些数据。
我们发表了什么?为什么?
我们决定发布一个包含订单及其客户评论的数据集。这将允许解决一些分类问题。我们的数据科学团队已经制作了一些模型来对评论进行分类,所以我们很想看看其他人会如何处理同样的问题。
为此,我们决定发布两个数据集:
- 约 4k 订单和评论的分类数据集(仅在版本 5 或更低版本上)。
- 包含 10 万个订单的未分类数据集。
为什么是 100k?嗯……这是一个神奇的数字:比 Kaggle 上大多数公开的数据集都要大。大到足以提供深入的分析和不同的产品类别。
该数据集包含 2016 年至 2018 年巴西多个市场的订单信息。其功能允许从多个维度查看订单:从订单状态、价格、付款和货运表现到客户位置、产品属性,最后是客户撰写的评论。后来,我们还发布了一个地理定位数据集,将巴西邮政编码与纬度/液化天然气坐标联系起来。
点击此处查看数据集最新版本
Our data is publicly available at Kaggle.
我们分享了哪些数据?
首先,我们发布了一个真实的数据集。通过使用我们的数据,可以得出一些关于巴西电子商务的结论。我们希望全面了解我们的数据团队所面临的挑战。所以我们发布尽可能多的信息。我们唯一的限制是:
- 不发布我们的产品目录(如标题,描述和照片)
- 不发布任何客户信息
- 不发布任何合作伙伴信息
考虑到这一点,我们创建了一个包含 30 多个要素的数据集。它允许从多个角度探索订单,如订单履行、产品类别、地理位置、客户满意度,等等。下面我们展示数据是如何构成的。
Our data schema. Multiple tables to allow studying an order from multiple perspectives.
您可能会注意到,它反映了真实的情况,数据存储在多个表和源中。这种结构与 Kaggle 上发布的平均数据集截然不同。
数据集被很好地记录,所有的特征都被解释,并且给出了足够的上下文来让每个人理解数据。我们创建了一个讨论主题,鼓励人们提问,然后用一些非常基本的分析编写了一个入门内核。仅此而已。
我们为什么要发表它?
有几个原因促使我们最初公布这些数据。但现在我们做到了,我们有更多的理由。它们是:
- 为数据社区贡献真实、高质量的数据。我们已经看到它被用于大学课堂。
- 将 Olist 定位为巴西数据科学界的参考。发布数据集后,我们注意到其他公司向我们寻求指导。
- 吸引优秀的候选人加入我们的团队。通过分享数据,更容易产生共鸣并解释我们所做的事情。我们已经联系了一些用公共内核分析我们数据的人。
- 从别人的角度看一些问题。许多人贡献了公共内核,通过阅读它们,我们发现了解决我们正在处理的问题的不同方法。
- 应试者。我们选择过程的第一步是数据集的公开挑战。
- 用葡萄牙语文本填补公共数据库的不足。帮助巴西的 NLP 社区。
- 它还帮助我们将公司定位为领域专家。公开这个数据集就像是一种证明:相信我们,我们知道自己在做什么。
它如何重新定义我们的成功指标?
我们用 Kaggle 上的其他公共数据集作为基准来定义什么是成功的。我们非常谦虚,起初,我们认为有了以下内容,我们就可以说该计划是成功的:
- 两个月内超过 50 次投票(我们有 200 次)
- 超过 500 次下载(我们有 3.4k)
- 超过 5000 次浏览(我们有 24k 次)
- 超过 5 个公共内核(我们有 21 个)
Left: our data being used at a college data science class in Natal/RN (photo by Tyrone Damasceno). Right: Public kernels on Kaggle.
Our data being used at a UCS business class
这也回答了我们的第二个问题:我们的数据被利用了!
如果任何竞争对手使用我们的数据怎么办?
这是一个风险。但是如果他们真的想使用它,即使我们不公开数据,他们也会找到方法。我们的数据集合可能已经在我们出售的商店上公开了。一些例子是:
- 过去四个月的总销售额
- 过去 30 天的平均审核分数
除此之外,我们的整个目录在商店公开出售。只需要构建一个网络爬虫来获取这些数据。产品描述、价格、照片、运费和预计交货时间都可以在我们销售产品的市场上找到。
即使有人通过搜索商店获得了我们的目录数据库,我们也不会让任何人发现销售了哪种产品,您只需要一个匿名的 product_id。不可能将我们的数据集链接到任何产品目录。这些数据已经被匿名化,评论中提到的公司和合作伙伴已经被《权力的游戏》的大公司所取代。我们还以不允许他人对我们当前的业务规模做出任何结论的方式进行了抽样调查。已经采取了这些措施,没有其他理由保留这些数据。
我们做错了什么?
在第一个版本中,我们认为消除数据的复杂性会很好。所以我们试图在一个表中加入尽可能多的信息。随着时间的推移,用户开始要求新的功能,如客户、产品和卖家 id。我们还决定添加更多我们认为重要的功能。
我们保留了原始的数据结构(一个主表),并添加了带有附加信息的其他表。很快我们就增加了许多新功能。整个数据集越来越难看:组合键,没有任何约定的名字和其他乱七八糟的东西。
我们决定在版本 6 中解决这个问题。我们将整个数据集拆分到不同的表中,每个表包含订单的一个方面。现在数据集看起来比以前更复杂,但数据之间的关系更清晰。
如果我们可以在这个问题上给出任何建议,那就是从支持增长和添加更多功能的数据结构开始考虑。因为你的数据用户肯定会要求的。
一句鼓励的话
我们希望看到更多像我们这样的数据集公开发布。到目前为止,我们只有分享数据的好处,似乎不会有任何缺点。
现在我们已经在考虑 ta 将要公开的下一个数据。你呢?有没有你想分享的数据?
如果您有任何问题或疑虑,请联系我们。
我们使用“数据”这个词的方式已经变了,这很危险。
原文:https://towardsdatascience.com/how-we-use-the-word-data-has-changed-and-it-s-dangerous-b7b6278a8e09?source=collection_archive---------5-----------------------
几年前,我正在为即将召开的石油和天然气会议撰写一篇技术论文。经过几周的写作会议,我将论文提交给了内部同行评审。评论通常是相当正面的,一位令人愉快的英国人指出,这篇论文“写得非常好”。就像大多数好事情一样,在自我表扬之后,现在,几年过去了,我已经忘记了这篇论文的大部分细节。然而,有一件神器一直牢牢地盘踞在我的脑海里;奇怪的是,这与论文本身无关,而是同一位先生在同行评议过程中提供的评论。我清楚地记得他在草稿手稿上手写的潦草字迹:
“错了!应该是这些数据是——不是这个数据是!”。
如果你已经到了一定的年龄,或者在科学领域工作过,你可能会很容易发现我的同行评审员在我错误地使用复数单词“数据”时发现的错误。但是,一个小小的语法错误可能会被原谅,实际上可能是一个现代文化现象的微观例子:我们似乎不再知道数据和信息之间的区别,这是危险的。
什么是“数据”,这个词从何而来?无需深究晦涩的词源细节,单词“data”是拉丁语单词“datum”的复数形式,意思是“给定的事物”。它进一步来源于拉丁语动词“dare”,意思是“给予”。本质上,数据是多个观察值;数据是给定的东西。快进到今天,“数据”这个词已经发生了变化,通常被认为是一个复数名词,类似于“雨”或“沙”。由于单独提及雷雨时的每一滴雨水或海滩上的每一粒沙子会很尴尬,所以我们一起提及它们,即“我的鞋子里有很多沙子”,而不是“我的鞋子里有非常多但数量有限的单个沙粒”。尴尬。
在语言学界,关于哪个定义是正确的争论仍在继续。事实上,什么是这个词的正确用法甚至已经在主流媒体上公布,包括《卫报》的这篇文章和讨论流行数据科学网站 FiveThirtyEight 进行的非正式在线投票结果的文章。
不管 logophiles 的感受如何,毫无疑问,在方言中,像“你的数据是错误的”或“数据是 _ _ _ _ _ _ _ _ _ _”这样的话已经变得完全可以接受。更有趣的是,我们可以检查过去大约 100 年的谷歌 N-gram 趋势,并比较这一时期短语“数据是”与“数据是”在书中的流行程度。从下图中可以看出,在这段时间的大部分时间里,“data are”的使用量明显大于其单数对应词“data is ”(这些趋势也适用于其他单/复数修饰语,如 was/was、this/these 等)。).
Google N-Gram Trends — “data are” vs. “data is” (1890–2008)
然而,在 20 世纪 40 年代后期,单数形式的流行开始迅速增加。伴随着这一现象,在 20 世纪 80 年代早期,我们看到复数形式的使用急剧下降。这些趋势一直持续到 2000 年代初,“数据”一词的单数和复数用法几乎达到了对等。粗略的谷歌搜索趋势分析显示,自 2004 年以来,使用单数形式的搜索词的受欢迎程度远远超过了包含复数形式的搜索。不管是好是坏,复数和单数已经成为同义词。数据简单来说就是。
虽然看似细微的语义争论,这个词用法的演变揭示了现代社会的一些有趣的事情。具体来说,自从数字时代开始以来,数据已经成为自身的一个实体,而不是历史定义所暗示的观察结果的集合。计算机的出现已经把“数据”变成了雪的数字等价物——本质上是不可计数的,并且更容易集中引用。这不是德里达启发的解释性语言游戏。相反,这个词从复数形式到单数形式的演变表明,数据的概念已经发生了变化,对我们如何相互交流产生了具体的影响。数据不再是给定的东西,也就是说,我们对世界的观察。现在,数据是一个单一的实体,充满了某种前所未有的媒介和力量:信息的力量。**
数据和信息有着千丝万缕的联系,但并不等同。很少有人比克劳德·香农更能理解这种微妙之处。虽然香农并不是一个家喻户晓的名字,但他在 1948 年发表的开创性论文《交流的数学理论》为一大批现代数字技术奠定了理论框架。在这篇信息论领域的开创性论文中,Shannon 根据数据变化的概率,即观察到个体观测值之间的一些差异的可能性,给出了信息的精确数学定义。抛开数学定义不谈,著名的人类学家格雷戈里·贝特森(部分是因为他与另一位著名的人类学家玛格丽特·米德的婚姻而出名)提出了也许是香农定量定义最简洁的定性体现:“信息是一种差异,这种差异产生了差异”。从根本上来说,信息是对我们周围世界的上下文观察(即数据)进行比较处理的结果。
撇开抽象定义不谈,为什么将数据的概念与信息的概念混为一谈如此危险?想象数据(复数意义)是暴风雪中的一片雪花。雪看起来很美,但当我们把它聚集在一起时,它变得更有趣。我们可以煞费苦心地精确地将雪堆积成一个个独立的砖块,然后一个个垒起来。经过足够仔细的思考,我们可以建造漂亮的圆顶冰屋。从微小的个体事物,我们可以创造出结构。
或者,我们可以放弃这种精确性,匆匆忙忙地把雪打包成小球,这样就非常方便互相投掷了。或者更糟,接受别人准备的过冬弹药,而不考虑我们的供应商的意图。这似乎很快成为默认的工作方式。在任何重大事件后,快速浏览脸书,我们总是发现我们的朋友已经成为社会科学专家,引用令人作呕的研究和统计数据;也许我们曾经因为自己成为那些“专家”之一而感到内疚。打雪仗在过去的冬天可能很有趣,但以这种方式使用数据从根本上来说是具有破坏性的。
在人类历史上,从来没有以如此低的成本获得如此多的数据和信息。然而,数据洪流导致从噪音中提取相关信息极其困难。随后,数据和信息之间的界限变得模糊到被遗忘的程度。除了更新我们的生物硬件来应对洪水,接下来的问题是,我们能做些什么?
如果所有的语义看起来都很迂腐,你可能是正确的——但话说回来,魔鬼不总是在细节中吗?这不仅仅是文字。虽然词源分析和历史可能会说明我们目前的状况,但语法再教育运动肯定不是根本问题的答案。在我看来,有四点是对这种情况的任何补救措施的必要组成部分:
①对教育的热爱和不懈追求。
(2)对被误导的人表现出同情,并坚定地捍卫言论自由(不管我们会觉得某人的观点多么应受谴责)。
(3)相信客观真理确实存在,而且值得去寻找。
(4)认识到有限使我们无法了解一切。充其量,我们是真理的容器,而不是真理的化身。
总之,要真正解决这个问题,我们必须学会理解数据和信息之间的微妙差异——实际上,这相当于我们对世界的观察以及随后我们从中得出的结论——并认识到这是个人义不容辞的责任,要理解什么构成了“造成差异的差异”。作为宇宙中唯一有意识的观察者,我们的独特角色赋予我们一种永恒的责任,那就是守护我们自己的思想。我们继续无视这些微妙之处,后果自负。
我们如何在 Twitter 上使用机器人来获得 1750 倍的廉价参与
原文:https://towardsdatascience.com/how-we-used-bots-on-twitter-to-get-1750x-cheaper-engagement-68f90a6b3f6d?source=collection_archive---------0-----------------------
[## 你好,你能听到我吗?
Adele - Hello - Yarn 是通过引用找到视频剪辑的最佳方式。找到电视节目、电影或音乐中的确切时刻…
www.getyarn.io](https://www.getyarn.io/yarn-clip/c19ed821-8b52-42eb-b8ac-28d2a3a92c01)
开始
我们像任何创业公司一样起步;我们有一个看似不错的想法,一个网站和没有用户。We ' s YARN:通过引用查找电影、电视和音乐视频剪辑的搜索引擎。这些剪辑只有几秒钟长,是由我们的网页抓取和索引过程自动生成的。我们相信人们会使用它们;我们需要一种方式让每个人都知道我们的存在。
[## 事实是,你甚至不知道我们的存在。
量子的安慰(2008)惊悚片-纱是最好的方法来找到视频剪辑的报价。在电视中找到准确的时刻…
www.getyarn.io](http://www.getyarn.io/yarn-clip/2371e6a1-c91c-4882-ba33-4cf87b831472)
获取首批用户
我们对用户获取有了初步的想法。我们最初的努力是联系作家和博客,试图获得故事。当没有人认识你的时候,很难得到媒体的关注,但是我们有一些幸运的突破。公关是一项困难的工作,耗费时间,而且不是我们的核心竞争力。在产品发布之后,很难激起人们的兴趣。最终,我们需要能够更好地扩展的东西;我们只有两个人,公共关系既昂贵又不可预测。
[## 我们需要更多的能量。这就是问题所在。
怪异科学(1985) - Yarn 是通过引用找到视频剪辑的最佳方式。在电视节目、电影或…
www.getyarn.io](http://www.getyarn.io/yarn-clip/eaf0c8eb-90ca-4740-aefd-abb88fe90e03)
社会化媒体
社交媒体似乎比公关更具扩展性。这个想法是,人们会张贴奇谈怪论,其他人会看到它们,并依次学习张贴它们。gif 已经被证实了;奇谈比 gif 更好,因为它们在声音和语气的上下文中与你想说的内容完全吻合。我们通过在 Twitter、脸书、Reddit、Slack 和 Pinterest 等社交媒体上发布奇谈来播种这一努力。我们的朋友张贴了一些,以及喜欢和向上投票的帖子。这种方法的伸缩性更好,但仍然受到朋友数量和时间的限制。
[## 我们人不够多,友好的。
拆迁人(1993) -纱是最好的方式找到视频剪辑的报价。在电视节目、电影中找到确切的时刻…
www.getyarn.io](https://www.getyarn.io/yarn-clip/550d142f-7c4d-4f94-bd07-f9b66386c47a)
推特实验
我们首先利用了我们自己,然后是我们的朋友,我们需要更多。技术自动化有无限延伸的希望。我们在 Twitter 上尝试了三个实验,看看是否有可能使用自动化来提高参与度和认知度。
我们的前提是,因为故事很短,而且与上下文相关,我们会看到更好的参与度,因为即使对一个完全陌生的人来说,它们似乎也更私人。
我们进行了三个实验来测试我们的理论:
- 手动向陌生人发推文
- 用机器人发推文,目标是 @TheEllenShow 和 @JimmyFallon
- 用一个机器人发微博,目标是 @pewdiepie 和他自己的内容
我们针对以下方面进行了优化:
- 围绕一条推文的任何参与度(回复、点赞、转发、视频浏览量、页面浏览量),无论浏览量多少。
- 提高整体参与度。
实验 1:手动推文
一个多月来,我们通过我们的 @yarnspun 账户发出了 400 条推文,尝试了各种技术。我们将推文分为三种类型:普通推文、热门话题推文和对陌生人的回复。制作一条推文大约需要 2-3 分钟;你需要找一个人回复,找一个故事,发一条微博。这个实验总共花了大约 20 个小时:假设 500 美元每小时 25 美元,或者一条推文大约 1.25 美元。
Type Impressions Engagement/tweet Engagement/imp Cost/engagement Tweets 11,239 27.59% 0.33% $0.034
Trending 33,282 69.03% 0.94% $0.004
Replies 46,328 78.95% 2.65% $0.001
实验 1:手动推文结果
- 回复比一般的推文更吸引人。除非你是一个显著的影响者,点回复会得到更多的参与。
- 用一根纱线来强调一点,下面是一个例子:
https://twitter.com/yarnspun/status/743832410740121600
3.有些热门话题很棒,有些很糟糕。热门话题有利于参与,因为人们通常“实时”发布推文,所以你的推文更有可能被看到。但是,你需要有参与度的话题;这本身就是一篇博文。
4.我们针对拥有 100-10,000 名粉丝的个人进行回复。这不是唯一的规则,但是我们发现在这个范围内参与度增加了。
5.人们知道你的追随者;你的粉丝越多,潜在参与度就越高。用户可以将您视为同事或影响者。
6.我们发现在太平洋时间晚上 10:00-凌晨 1:00 之间有更好的参与度。也许人们在晚上寻求陪伴。清晨的推文也会在上班前到达用户。
[## 他们怎么还用手摘呢?
蓝色夏威夷(1961)——Yarn 是通过引用找到视频剪辑的最佳方式。在电视节目、电影或…
www.getyarn.io](https://www.getyarn.io/yarn-clip/2dd3d6ba-52bf-4cef-b236-3fc43359f809)
实验二:推特机器人
我们是一家资源有限的小公司,但拥有无限的创意和技术人才;)我们试图通过创建 twitter 机器人来自动化我们的第一个实验。我们的机器人与吉米·法伦(@jimmyfallon)和艾伦·德杰尼勒斯(@TheEllenShow)的推特互动。机器人监控他们的信息流,发现新的推文。该机器人分析了推文,并使用纱线生成了一个响应。在对机器人进行初始编码后,监控 twitter 账户的设置花费了大约 30 分钟,大致如下:
twitterUtil.createWatcher('yarnds', '[https://www.getyarn.io](https://www.getyarn.io/)', {
skipTweet: false,
useTextMp4: true,
pollTime: 24000,
apiLink: 'statuses/user_timeline',
params: {
screen_name: 'jimmyfallon',
count: 1}
});twitterUtil.createWatcher('yarnds', '[https://www.getyarn.io](https://www.getyarn.io/)', {
skipTweet: false,
useTextMp4: true,
pollTime: 24000,
apiLink: 'statuses/user_timeline',
params: {
screen_name: 'TheEllenShow',
count: 1}
});
我们进行了一个月的实验,回复了 460 条推文。偶尔回应是无意义的;解析一条 tweet,生成回复候选,搜索 YARN,最终选择单个 YARN,每一步都有级联问题。但是,嘿,这是自动的。
以下是一些有趣的回答:
@jimmyfallon
https://twitter.com/yarnds/status/745592676481826816
@TheEllenShow
https://twitter.com/yarnds/status/744227367334215681
实验 2: Tweetbots 结果= 50 倍的改进
Type Impressions Engagement/tweet Engagement/imp Cost/engagement Replies 73,900 60.78% 1.73% $0.000021
自动化肯定是值得的,因为成本很低。尽管我们的最佳手动参与率更高(2.65%对 1.73%),但它更难扩展。我们的机器人可以以更低的成本(设置和监控成本)进行扩展,并使每次项目的成本降低 50 倍。由于一次性的前期安装成本,我们的成本会随着时间的推移而下降。
通过更多的努力,可以产生更好的机器人响应。通过界定内容搜索的范围,这些响应可以更好地针对 Ellen 和 Jimmy 的特定受众。例如,使用节目嘉宾的内容,如塞斯·罗根、弗莱德·阿米森、基特·哈灵顿(本周《今夜秀》的嘉宾)。
[## 这两者结合得相当好。
《权力的游戏》(2011) -第六季第十集- Yarn 是通过引用找到视频剪辑的最佳方法。找到电视节目中的确切时刻…
www.getyarn.io](https://www.getyarn.io/yarn-clip/aa8eb344-3607-4b16-9f09-c3f4f05c5148)
实验三:Pewdiepie 机器人
菲利克斯·谢尔贝格又名派迪派又名@派迪派是 YouTube 上最受欢迎的频道之一,拥有 4500 万订户和超过 100 亿的视频浏览量。
我们试图通过使用他自己的内容来围绕他的 twitter 账户和他的追随者建立互动。我们摄取并分析了大约 50 个视频,大约 9 个小时的视频。我们制作了 11,500 个纱夹。我们的纱线定制网站是:http://pewdiepie.getyarn.io/。Bot 安装花费了 30 分钟:
twitterUtil.createWatcher(‘pewdyarn’,‘[https://pewdiepie.getyarn.io](https://pewdiepie.getyarn.io/)', {
skipTweet: false,
useTextMp4: true,
pollTime: 12000,
apiLink: ‘statuses/user_timeline’,
params: {
screen_name: ‘pewdiepie’,
count: 1}
});
费利克斯大约每天向 580 万粉丝发一条推文,他的推文获得大约 1000 到 5000 次转发。我们配置了一个机器人( @pewdyarn )来跟踪他的流并找到新的推文。该机器人抓取了一条推文,分析了其结构,并使用自己视频中的一个故事做出了回应。这个过程在几毫秒内执行,我们每 12 秒检查一次他的账户。
一个例子是:
[## 去你妈的光明会!
PewDiePie 动机游戏-纱是最好的方式找到视频剪辑的报价。找到电视节目中的确切时刻…
pewdiepie.getyarn.io](http://pewdiepie.getyarn.io/yarn-clip/abe59524-15e0-4371-b7cb-c49089787b22)
我们这样做了一个月,发出了 360 条推文,50 万次展示,1000 次链接点击,768 次赞
https://twitter.com/pewdyarn/status/728885205423919105
Type Impressions Engagement/tweet Engagement/imp Cost/engagement Replies 489,000 97% 8.9% $0.0000006244
实验 3: Pewdiepie Bot = 1,750 倍改进
我们发现,与之前的机器人相比,性能提高了 35 倍,与手动推文相比,性能提高了 1,750 倍。
- 我们太快了,在一些情况下,我们第一个回复了他的推文。许多人认为我们实际上是菲利克斯;许多人认为我们是机器人。
- 这很有效,因为对他自己的观众来说,这是他自己的内容。
- 我们有很多印象,因为这么多人查看他的推文,并且在一个线程的顶部有所帮助。
[## 扩大规模,推出产品,上市,
硅谷(2014) -第二季第二集失控贬值- Yarn 是通过引用找到视频剪辑的最佳方式。找到确切的…
www.getyarn.io](http://www.getyarn.io/yarn-clip/349c6fbd-636d-4c12-89b0-6991c6c10e22)
你该怎么办?
根据上下文回应用户。理想情况下,找到一种方法来制作一条你可以自动化的信息,传达给那些已经在讨论你的信息的人。个性化和情境化的消息传递显著提高了参与度。
使用纱线进行接合。它们可以在脸书和 Twitter 上自动扩展成显卡,以增加帖子的参与度。视觉获得更多关注;视频更多。一根纱线的短尺寸在实时社交平台上非常好用。您的信息更加清晰可见,传达了额外的语气,并且大小完全适合移动带宽。奇谈怪论可以在电子邮件中发送,在空闲时间发送,在 iOS 或 Android 上发送 FB messenger,以及任何你可以链接网址的地方。
在 YARN 我们摄取并分析视频内容,以便在对话中使用。我们很乐意为您的内容或社交活动提供帮助。如有任何问题,请联系我们。
我是杰弗里·克劳斯,@geofree,YARN 的创始人。我们是 Y Combinator 的研究员(F3),致力于让数字对话变得更有趣,更吸引人。
我们如何在 Amino 可视化数据
原文:https://towardsdatascience.com/how-we-visualize-data-at-amino-c38e1ee4ba05?source=collection_archive---------5-----------------------
我们都致力于为医疗保健带来透明度。为了做到这一点,我们把大量复杂的信息变得简单易懂。有效数据可视化的目标没有什么不同,这也是我们在 Amino 如此关注它的原因。
虽然医疗保健和数据科学的交叉是一个令人兴奋的前沿,但有一个大问题:医疗保健已经令人困惑。添加大量的数据,很难理解你在看什么,更不用说收集任何有意义的见解了。世界上的医生和数据科学家有着高度专业化的工作,由于这种极端专业化,他们使用的行话对于那些可以从他们的专业知识中受益最多的人来说往往是不可理解的。
在 Amino,我们认为数据科学家需要知道如何用每个人都能理解的清晰术语解释他们的工作,因为如今,人们越来越多地对自己的医疗保健选择和费用负责。他们需要快速成为专家。这就是数据可视化的用武之地。数据可视化使任何人都可以很容易地从大量复杂信息中快速理解关键见解。
在过去的一年里,我们开发了一个创建有效数据可视化的流程,帮助人们做出更好的医疗保健决策。下面是这个过程的幕后场景——以及我们最喜欢的项目之一是如何从开始到结束变成现实的。
Amino 的数据可视化过程
步骤 0:分析数据
在你可以可视化任何东西之前,你需要一些数据!我们经常被问到,是我们的分析激发了视觉,还是视觉的想法激发了分析。我们发现前者是正确的,最引人注目的视觉效果通常来自我们的数据科学家每天所做的惊人工作。
第一步:编造一个故事
这是这个过程中最重要的部分,也是最容易被忽视的部分。你在说什么呀你想回答的问题是什么?你的数据中的洞察力是什么?你想提出什么论点?你用你的数据在支持或反驳什么立场?读者应该从视觉化中得到什么?预先回答这些类型的问题可以减少你必须修改和编辑的次数,从而在以后的过程中节省你大量的时间。如果你没有太多的故事,或者故事太难,你应该后退一步,重新评估你试图用数据做什么。
第二步:制作原型
绘制您的数据。不要担心它是否漂亮。画出来就好。我非常鼓励在使用软件之前用手绘制草图。如果你最初的情节开始讲述第一步中概述的故事,你就朝着正确的方向前进了。如果不是,那就值得考虑重新架构这个故事。
第三步:提炼
理想情况下,你视觉上的每一个像素都支持你想要讲述的故事。数据可视化先驱爱德华·塔夫特称之为提高“数据-墨水比率”有时,这意味着将单个数据点分成不同的类别,或者完全删除不必要的类别。其他时候,这意味着删除不必要的图例或投影等视觉效果。这也是你需要开始思考审美的地方;简洁的标签、文本和数据点之间充足的间距、便于阅读的正确文本对齐、突出显示数据的不同颜色等等。
第四步:获得反馈并进一步完善
一旦你准备好了草稿,建设性的反馈——尤其是非数据从业者的反馈——可以让你的可视化更加平易近人和易于理解。我试图通过提出以下问题来收集反馈:
“这张图表告诉你什么?”
“哪些元素有助于你理解数据?”
“哪些元素令人困惑?”
如果你在第一个问题上得到的答案不是你在第一步中希望得到的答案,那么就有必要深入研究一下是什么导致了这种误解。有时,所有需要的只是简单地改变一个标题或标签,以向读者重新构建整个想法。
第五步:发表并反思你的工作
你成功了!是时候与世界分享你的想象了。根据我们的经验,如果我们真的很幸运,我们的视频会在媒体上发表,并在社交媒体上分享。我对视觉产生的对话特别感兴趣。如果我们实现了让一个复杂的想法变得清晰易懂的目标,对话就不是关于数据本身,而是从数据中获得的洞察力。
以这条推特为例,它展示了 Amino 关于宫内节育器成本的数据:
如果你读了回复,讨论往往围绕着人们根据自己的经验支付的宫内节育器的费用,而不是数据本身(它是什么,它是如何得出的,等等。).我们对这张特别的图表感到非常自豪。
Amino 的数据可视化指导原则
在整个过程中,我们制定了一些指导原则来保持我们的专注。
了解你的观众。使用每个人都能理解的术语。
只要有可能,我们就避免使用技术术语,并试图用每个人都能理解的简单术语来解释我们的数据。如果我们发现我们必须依靠技术术语来表达一个概念,那么很可能我们还没有把它简化得足够简单。太多时候,技术写作(如研究论文)缺乏对作者发现的简单明了的解释。因此,他们经常被误解——有时是故意欺骗!这在医疗保健和 T2 政治中尤为常见。我们希望成为数据的好管家,防止数据被滥用。
透明、真实、可信。
没有误导的指南或尺度,避免使用专有的“黑箱”方法或措施。我们努力设计每一个图表,让它能够独立存在;独立于特定的内容,如新闻文章或博客文章。你永远不知道你的工作会在哪里结束!
最大化视觉可访问性,尤其是移动屏幕。
我们使用一种对患有常见色盲的人来说容易辨别的配色方案。我们对所有内容都采取“移动优先”的方式,因为大多数美国人通过智能手机和平板电脑阅读新闻。因此,我们优化了我们的数据可视化,使它们可以在移动屏幕上轻松阅读。在实践中,这意味着我们的视觉效果有薄的边界,粗体,和大量的对比。
数据可视化过程如何工作:一个真实的例子
六月,我们发表了一篇关于女性在怀孕期间接受各种超声波检查的数据报道。这是一个与我们在 Amino 的使命紧密相关的主题。我们知道,在怀孕期间,很难弄清楚你需要什么类型的超声波,你需要它们的频率,你应该什么时候得到它们,或者它们要花多少钱。虽然没有“普遍”的怀孕经历,但我们的目标是帮助孕妇理解并想象出预期的基线。
然而,在我们最初的数据探索中,我们发现各种类型的妊娠超声有近 20 种不同的代码。我们如何清晰、简单、有效地表示这些数据?最重要的是,我们如何包装它,让它真正有用?下面是我们如何从初始分析到最终可视化的一步一步的介绍——一个简单易懂的图形,代表了来自 308,000 例怀孕的 200 多万个数据点。
步骤 0:分析数据
在绘制单个数据点之前,我们首先做了大量的分析。在我们对与怀孕相关的超声波索赔的探索中,我们能够通过观察不同类型的超声波何时出现在保险索赔中来跟踪怀孕的阶段。下面是一个例子,一名妇女的怀孕超声波声称什么样子。
Example of one patient’s pregnancy ultrasound claims. This patient likely had twins, which could explain why there are so many TVUs and follow-up scans.
第一步:编造一个故事
在研究这个话题时,我们从女性那里听到的一个典型问题是“我对超声波的体验正常吗?”我们没有在网上找到任何资源来提供每种类型的超声波发生的鸟瞰图,所以我们认为我们可以自己制作。如果我们有数以千计的上述数据的例子,我们可以概括超声波的频率和时间,并向女性提供她们自己的经历有多么相似或不同的感觉。
第二步:制作原型
我最初考虑将这些数据可视化为折线图。x 轴代表时间,而 y 轴代表超声波的数量。每种超声波都有自己的线路:
然而,人们很快发现,用标签或图例来跟踪所有不同类型的代码太困难了。重叠的线条也很难辨认。因此,我们认为热图可能效果更好。
在热图中,在怀孕的每个阶段接收到的超声波数量将通过颜色来表示——颜色越深,在特定时间接收到的超声波越多。这使得超声波的类型被清楚地标记为它们自己的轴。
初稿在电脑上绘制出来了。y 轴是以天为单位的时间,列是各种超声波的代码。
我们立刻看到了一些有趣的模式。一些代码在怀孕早期出现,而另一些则出现得较晚。然而,它仍然非常复杂,可以做很多事情来简化事情——也就是说,你必须是医学编码专家才能理解图表顶部的代码。不理想。
第三步:提炼
是时候改进了。我们有两种主要的方法来简化上面的草案:将代码分组到有清晰标签的类别中,并以四个月为主要界限将时间显示为周而不是天。
翻转图表使其水平放置也更容易阅读。现在,所有文本都是水平的——不需要倾斜头部。
第四步:获得反馈并进一步完善
从我们听到的反馈来看,仍然很难看出每种超声波的“热点”。我们把这归因于太多的颜色。我们减少了不同颜色之间的步数,并增加了每周超声检查次数的下限。
这些调整增加了步骤之间的对比度,并使每种超声波的“热点”更加明显。
Previously, every week with an observed ultrasound was included in the visual, but in the updated version, only weeks with at least 100 ultrasounds were shown.
第五步:发表并反思你的工作
最后一步包括写一个清晰的标题、描述性的副标题、有用的图例和附加的指针。我们喜欢我们的标题稍微带有编辑性,并且尽可能回答“那又怎样?”在图表后面。字幕总是对所呈现的数据进行更技术性的描述。
我们对图例做出的一个有意识的决定是不包括任何数字界限。我们认为,对于读者来说,在任何给定的一周内进行超声波检查的确切次数并没有多大关系——颜色强度的差异足以说明问题。在博文中,我们澄清了灰色条带代表仅观察到 100–200 名患者接受超声检查的几周,而最暗的紫色条带代表 10,000 多名患者的观察结果。
我们很高兴地看到,这个视觉效果,以及我们其余的分析,出现在了一篇由 The Bump 撰写的文章中,这是一个致力于为准父母提供怀孕信息的新闻网站。
一些最后的想法和进一步的阅读
理解越来越多的海量信息是数据科学家和非数据科学家都面临的挑战,而且不仅仅是医疗保健。我们生活在一个充满数据的世界。很多影响我们生活的决定都是在大量信息的情况下做出的,这些信息往往超出了我们的理解范围:我们的新闻提要中显示了什么,我们与谁约会,我们获得的住房贷款利率是多少,或者我们的医疗保险将支付什么费用。有效的数据可视化是朝着让每个人更容易理解这个信息海洋迈出的一小步。
如果您是数据可视化的新手,并且正在寻找灵感、指南和工具,下面是一些重要资源的链接。你也可以在这里查看我们的其他作品。
灵感
- 流动数据
- 布丁
- 结果
- 538
- 守护者视觉效果
- 彭博视觉数据
指导
- 如何使用 R 和 ggplot2 为网站制作高质量的数据可视化效果
- 制作互联网事物,第 1 部分:使用数据(专门针对 Python)
- D3 . js 的搭便车指南
- 设想信息 爱德华·塔夫特
工具
- ggplot2
- matplotlib—Python 的数据可视化
- RStudio —一个流畅的 R 环境,让使用 ggplot2 变得轻而易举
- 闪亮的 —使用 ggplot2 语法为 web 创建交互式图表
- ge phi——强大且可扩展的开源图形可视化软件
- D3.js —信息可视化的 web 标准
- 模式 —我目前最喜欢的数据协作工具
事实上,我更喜欢对信息的想象而不是他更著名的作品 对量化信息的可视化展示 ,因为我认为其中的讨论和例子与现代媒体更相关。
在 Amino,我们为 R 使用 ggplot2/ggmap,结合 Sketch 来创建我们的视觉效果。
我的时间序列模型表现如何?
原文:https://towardsdatascience.com/how-well-my-time-series-models-performed-actual-vs-prediction-r-1281fc66238e?source=collection_archive---------11-----------------------
实际与预测— R
对英格兰国民健康服务(NHS)每月事故和急诊就诊人数的时间序列分析和预测是一个有趣的项目。在那里,我建立了四个不同的预测模型,以预测 2018 年 8 月至 2019 年 7 月期间 NHS 组织的每月总人次。 了解更多(点击此处 )。
这四个模型分别是:【SN】【LR】ARIMA和自动 ARIMA 模型。然而,我在 2018 年 8 月制造了那些模型。从那以后,我一直通过 NHS 网站——A&E 就诊和急诊,监测每个月底总就诊人数的实际统计数字。
现在已经快三个月了,总的来说,我可以说这些模特表现得非常好。但在这里,我们将通过比较三个月前每个模型的预测数据与实际数据,更深入地了解他们的表现。这可以简单地通过计算绝对误差(AE) 、均方根误差(RMSE) 和均方根对数误差(RMSLE) 来实现。
首先,我想展示 12 个月内【TA】各模型预测的汇总。然后,将 3 个月的真实/实际统计数据与预测进行比较:
现在,让我们将每个模型的前 3 个月的值与 NHS 网站上的实际总出席人数 ( TA )数据进行比较:
所有模型相对于实际 TA 值的条形图和散点图:
粗黑线是实际 TA 值,我们可以看到所有模型的趋势表现与 TA 相同。但是季节性的天真倾向于在前两个月有更大的差异。说到这里,我们来计算一下绝对误差,把数据可视化。但我们可以清楚地注意到,线性回归和 ARIMA 模型是最好的。我们会进一步调查!
绝对误差
> Period SN.ae LR.ae ARIMA.ae Auto.ae
> Aug-18 70,742 4,697 26,322 19,957
> Sep-18 79,540 21,022 8,984 8,368
> Oct-18 18,197 16,977 7,877 17,348
均方根误差(RMSE)
> SN.rmse 62,348.95
> LR.rmse 15,834.61
> ARIMA.rmse 16,689.39
> Auto.rmse 16,013.10
线性回归具有最低的 RMSE 值,而季节性朴素具有最高的值。
均方根对数误差
> SN.rmsle 0.031723822
> LR.rmsle 0.007851101
> ARIMA.rmsle 0.008291625
> Auto.rmsle 0.007913693
区块链将如何让预测分析变得可及?
原文:https://towardsdatascience.com/how-will-blockchain-make-predictive-analytics-accessible-d256d543081d?source=collection_archive---------8-----------------------
数据正在转变为货币,数据分析是这一转变的根源。预测未来的能力是所有公司的目标,从财务管理到营销,甚至是肿瘤学。我们每个人都想对未来有所了解,以便更好地准备和抓住即将到来的机会。
不幸的是,以这种方式使用数据来提取趋势和可操作的信息存在很高的准入门槛。训练有素的专家稀缺、昂贵,而且需要多年的学习才能创造出新的专家。到目前为止,这一直是使用预测分析的一个基本缺点。
预测分析的挑战
如前所述,第一个问题是操作数据所需的知识非常有限。数据科学家是就业市场的新成员。他们的背景通常是工程师、统计学家或数学家,除了这些技能,他们还学习了大数据和处理不确定性。
第二个挑战是训练算法所需的数据量。只有在使用数千甚至数百万条记录训练神经网络之后,才能创建校准良好的伟大模型。访问如此大量的数据并不总是可行的,尤其是对于没有必要的运营规模的小公司。一个潜在的解决方案是从大量类似的公司收集数据,并为这些公司创建一个平均模型。大多数时候这是不可能的,或者需要额外的数据处理。
最后,操纵大型数据集所需的纯粹计算能力有时过于昂贵。大多数中小型企业负担不起自己的服务器来处理数据,这些数据大部分时间都是非结构化的,分散在各种存储设备中。
看起来区块链可以为每一个挑战甚至更多的挑战提供可行的解决方案。
什么是区块链?
多年来,区块链是比特币的代名词,因为它是底层技术。现在情况不再是这样了。区块链协议依赖于分布式账本的思想。因此,区块链主要是从一开始的所有交易的列表,它由一组单独的计算机持续维护和更新。有一些特性可能使区块链成为未来一些不同问题的可能解决方案,包括安全性、预测等。
首先,所有数据都存储在每台计算机上,因此,如果支持区块链网络的任何节点突然出现故障或完全消失,不会对账本产生影响。该分类帐是公开的,任何想加入该协议的人都可以免费下载。这使得区块链成为一种高度透明的交易方式。
该协议依赖于加密签名。这使得它是安全的,保证了安全性、真实性和身份。只有在每个参与者登录并验证其身份后,他们才能向网络提供支持。这很重要,因为维护分类帐意味着添加新的块。
一旦一条新信息被加入队列,就几乎不可能修改。因此,必须真诚地去做。这可以通过工作证明来实现,基本上就是解一个方程来验证一个块,参与者通过这个过程获得一个令牌。
为什么区块链会扰乱预测分析?
如上所述,区块链运算意味着将潜在的数千台计算机的计算能力结合在一起。这创造了相当于物理超级计算机的云,即使是小公司也能够通过按使用付费的系统进入预测分析的世界。
这种计算能力也可以用于其他目的,比如定义将要分析的模型。由于大多数小公司没有数据科学家,他们只能使用业务分析师来确定他们想要解决的问题。然而,结果将主要用自然语言来表达,这是机器不能直接处理的。使用 NLP(自然语言处理),计算机可以使用现有的能力来理解问题,并选择那些可以提供答案的数据集。基本上,区块链可以是破坏性的,因为它通过使用人工智能给大众带来了权力。
其次,由于这是一个高度透明的系统,它可以通过绝大多数人的共识和接受来验证或拒绝。
潜在应用
使用预测分析解决方案等同于依赖数据进行决策,而不是依赖经验和惯例。应用包括用于营销和招聘目的的分析、预测客户终身价值、流失率、创建动态价格等。
通过区块链首次使用预测分析几乎是自发的。这项技术可以用来预测加密货币和其他金融市场的价格走势。
分析是众多营销应用的核心。例如,客户细分过去只考虑人口统计和社会地理坐标,而现在新的类别可以由市场现实来定义。
通过预测分析,前面提到的类别的推荐系统可以增加参与度、销售额和客户对品牌的看法。这样的政策不仅会创造一种销售更多的方式,而且还可以动态调整价格,以保持您的报价具有竞争力,并提高利润率。
在正确的时间销售更多正确产品的另一种方法是通过查看内部和外部数据来预测每个类别的需求。例如,内部数据可以给出平均销售额的估计,而像天气预报这样的外部数据可以表明即将到来的需求高峰。
结论
预测分析背后的逻辑是,人是习惯的动物。我们通过互动学习我们的行为,我们倾向于复制我们周围看到的东西。通过处理大量数据,某些模式出现了。如果我们把这种努力从集中的情况下转移到区块链提供的分散的方法,更多的公司可以赶上潮流,并利用这一优势。
你将如何被招聘为数据科学家?我的 LinkedIn 消息的简要分析。
原文:https://towardsdatascience.com/how-will-you-be-recruited-as-a-data-scientist-a-brief-analysis-of-my-linkedin-messages-498c6e20916d?source=collection_archive---------7-----------------------
使用一些数据科学和 LinkedIn 的数据对数据科学招聘进行分析,然后我会在 LinkedIn 上发布这些数据。
A picture I took in London, UK that has nothing to do with this article.
关于数据科学领域的工作,有大量的统计数据被抛出:空缺职位的数量、较高的基本工资中位数、未满足的市场需求等。虽然这很有希望,但如果你是求职者或数据科学领域的新手,你不一定要将这些统计数据等同于任何直接的个人结果。因此,这篇文章的目的是给我一点点洞察力,自从我在 LinkedIn 上的头衔变成“数据科学家”以来,我是如何被招聘的,我的个人资料获得了越来越多的技能/流行语。
为了透明起见——并且因为这样做将是讽刺性的而不是,我将使用一些基本的数据科学技能来进行分析并分享 Python 代码,这样如果您感兴趣的话可以跟随。
关于我的一点点
我的背景其实是生物。当我获得分子和细胞生物学硕士学位时,我很幸运地在一家生物技术公司找到了一份数据分析师的工作。在那里,我的角色基本上是自学 R 和 Python 来对我们的细胞和生物数据进行统计分析。随着我对编程数据科学越来越感兴趣,我想要更正规的教育——或者基本上除了我和 stack overflow 之外的任何东西。
Me
因此,我参加了纽约市数据科学院(NYCDSA)训练营。我为他们工作了一段时间,撰写和管理数据科学面试问题,以及其他一些数据科学和分析工作,直到我在辉瑞获得数据科学实习。现在我已经在他们那里做了一年多的数据科学家,主要从事深度学习、NLP、数据工程和架构方面的工作。
下载您的电子邮件
随着我从招聘人员那里收到越来越多关于数据科学职位空缺的消息,我开始想知道是否有一种好的方法来访问这些数据,而不破坏我自己的个人资料。虽然 LinkedIn API 在这种情况下没有用,但实际上您可以将所有消息数据下载到一个方便的。csv 文件。你可以通过个人资料的设置&隐私部分访问它,但为了方便起见,这里有个链接:【https://www.linkedin.com/psettings/member-data】的。然后,您应该会看到下面的选项。
然后,您可以选择您想要下载的数据,它会向您发送一封电子邮件确认链接。对于本演练/分析,它只是“消息”。
非常基本的情节和统计
好了,现在我们可以开始处理数据了。让我们启动 python,看看我们得到了什么。
import pandas as pd
import matplotlib.pyplot as plt
from datetime import datetimemessages = pd.read_csv("messages.csv")
messages.head()
为了匿名起见,我已经删除了From
和Content
列中的值,但是您应该会看到上面的字段。我们可以看到谁发的邮件,日期/时间,主题和内容。首先,我们只需要稍微清理一下数据。对于绘图,将日期和时间作为索引会很有帮助。此外,我真的不想看所有的来回信息,因为这可能有点误导。让我们只保留每个人给我发的第一条消息。
## properly format the date and set it as the index
messages['Date'] = [datetime.strptime(x, '%m/%d/%y, %I:%M %p') for x in messages['Date']]## keep only message sent to me
df = messages[messages['Direction'] == "INCOMING"]## keep only the first message everyone sent me
df = df.drop_duplicates('From', keep = 'last')
现在我们只有每个人发给我的第一条消息,让我们来看看一些基本的统计数据。
df = df.set_index(pd.DatetimeIndex(df['Date']))total_msg = len(df)
min_date = min(df.index)
mean_msg_month = df.resample('MS').size().mean()
mean_msg_week = df.resample('W-MON').size().mean()print("Earliest Message: %s" % min_date)
print("Total All Time Incoming Messages: %s" % total_msg)
print("Avg # of Messages per Month: %s" % mean_msg_month)
print("Avg # of Messages per Week: %s" % mean_msg_week)
所以我收到了 300 多条来自不同个人的信息。为简单起见,我们假设大部分是招聘人员,排除偶尔的产品促销、垃圾传销或其他。然而,直到 2017 年 2 月或 3 月,我才在我的个人资料中添加任何关于数据科学的内容,我的第一条消息是在 2016 年 7 月;这可能有点扭曲了数据。让我们策划一下,找出答案。
of LinkedIn Messages over Time
好了,你可以看到,在 2017 年 2 月将数据科学术语添加到我的个人资料之前,我的电子邮件中基本上没有招聘人员。一旦我这么做了,我的信息就会激增!请注意,我想我也打开了该设置,让招聘人员知道我在这个时候对新的机会持开放态度,但我在 2017 年 8 月关闭了它,因为几乎看不到归因。12 月份接近年底时会有一段短暂的平静,但 2018 年 1 月再次以大量消息开始,自那以来一直相当稳定。
知道我有很多前数据科学数据影响我的平均计算,让我们重做 2017 年以后的数据。
mean_msg_month = df[df.index > '2017-01-01'].resample('MS').size().mean()
mean_msg_week = df[df.index > '2017-01-01'].resample('W-MON').size().mean()print("Avg # of Messages per Month: %s" % mean_msg_month)
print("Avg # of Messages per Week: %s" % mean_msg_week)
那更好。平均而言,我每月收到 14 条消息,每周收到 3 条,标题为数据科学家,个人资料中包含数据科学术语。从图表中可以看出,有些月份比其他月份强得多。
一点自然语言处理
这些统计数据提供了丰富的信息,但这是我一年中做过的最无聊的 python。尽管可能没有那么大的收获,但让我们稍微研究一下文本,看看我们能提取出什么信息。我们可以回到我们读到的原始表格,在Content
列中删除 NA 值,并从 NLP 视觉效果最差的单词云开始查看传入的消息。
from wordcloud import WordCloud, STOPWORDSstopwords = set(list(STOPWORDS) + ['hi','kyle','will','thank','thanks'])df = messages[messages['Direction'] == "INCOMING"]
df = df[pd.notnull(df['Content'])]wc = WordCloud(background_color='white',
stopwords=stopwords,
).generate(' '.join(list(df['Content'])))plt.imshow(wc)
plt.axis("off")
plt.show()
在删除停用词和一些额外的自定义词后,我们看到我的大部分邮件都在讨论数据科学和数据科学角色。一些人提到了我目前的职位,但更多人提到了数据科学或“机器学习”角色的“客户”或“业务”的新“机会”。这很酷,但没有告诉我们太多,让我们看看我们是否可以用更高级的东西来深入挖掘。
实体识别
“命名实体识别(NER)(也称为实体识别、实体分块和实体提取)是信息提取的子任务,旨在定位非结构化文本中提到的命名实体并将其分类为预定义的类别,如人名、组织、位置等……”—维基百科。基本上是从非结构化文本中提取有用的标记数据。
不用训练我们自己的模型或标记数据,我们可以使用像spacy
这样的包来提供预训练的 NER 模型,这些模型能够识别许多对象,其中一些可以在下面看到。
这样,使用几行代码,您就可以从任何文本中快速收集和显示实体。下面的例子使用了一个随机匿名的例子,来自我在 jupyter 笔记本上呈现的消息。
import spacy
from spacy import displacynlp = spacy.load('en_core_web_sm')
text = df['Content'][i]
displacy.render(nlp(text), jupyter=True, style='ent')
它很酷,但不是很好用。该算法用 4 种不同的方式给公司“定位”,分别是GPE
、PERSON
、无,最后是正确的方式ORG
。NY 和 CHI 应该也不是ORG
的年代
我原本希望利用这一点来更好地了解我被招聘的公司职位和薪水提及,但如果不标记大量我自己的数据(我不会这样做)和训练一个新模型(我不想这样做),它可能不会产生好结果。看来我们得尝试更硬的编码方法了。
positions = ['data scientist',
'data analyst',
'data engineer',
'senior data scientist']text = ' '.join(list(df['Content'])).lower()
for job in positions:
count = text.count(job)
print(job + ': %d' % count)
可能仍然遗漏了许多只在邮件主题中提到的边缘案例、角色或职位,但你知道了。对我邮件中提到的角色的简短探索。
未来方向
用这些数据做一些机器学习会很酷。我用平均预训练单词嵌入对数据做了 k-means,但这对于这篇文章来说有点过了。
此外,如果我有我的 LinkedIn 个人资料随时间变化的全面日志(简历、证书、职位、联系等),我会希望看到某些术语是否能激发最佳互动,并更多地挖掘时间序列方面。不幸的是,我可能没有这样的时间和数据。不管怎样,希望你喜欢它,如果你有更多的探索想法,请告诉我。
多年轻才算太年轻不适合约会?
原文:https://towardsdatascience.com/how-young-is-too-young-to-date-ae0061bc2115?source=collection_archive---------0-----------------------
你可以约会的老老少少的真正规则
多大才算太老?多年轻才算太年轻?
关于多大年纪和多年轻可以约会的真正规则。
“恐怖法则”指出,你应该约会的最小年龄是“你年龄的一半加七岁”一个不太常用的推论是,你应该约会的最大年龄是“从你的年龄中减去 7,然后加倍。”
根据这条规则,社会应该接受一个 50 岁的男人和一个 32 岁的女人约会。对我朋友的一项快速调查显示,情况并非如此。反应从“当然”到“这很奇怪”到“你为什么问我这个?”。当我颠倒性别时——一个 50 岁的女人和一个 32 岁的男人约会——人们的反应也经常颠倒。
这让我想知道,当谈到约会中的年龄差异时,creepiness 规则实际上反映了什么是社会可以接受的吗?换句话说,令人毛骨悚然的规则实际上反映了社会所发现的……令人毛骨悚然的东西吗?
研究表明
互联网上对这个话题的看法不一。文章和博客文章在声称年龄在一段关系中绝对重要和年龄在一段关系中绝对不重要之间交替出现。有一点是清楚的——没有什么比其他人的爱情生活更能引发更多的观点。
Buunk 和他的同事写了一篇论文,调查了年龄、性别和浪漫关系类型(随意、认真、婚姻等)等因素是如何影响爱情的。)影响人们对潜在浪漫伴侣的年龄限制。
研究人员在公共场合随机接近一些人,让他们想象自己和一个有魅力的异性处于浪漫关系中。研究人员随后展示了不同类型的关系——性幻想、临时恋情、长期关系、婚姻——并询问参与者在每种情况下他们伴侣的最小和最大年龄是多少。
除了允许你以科学的名义违反所有社会规范之外,以下是实际结果:
- 不管是什么类型的关系,女人都喜欢和自己年龄相仿的男人。根据 Buunk &同事的研究进行的另一项分析,女性在“恐惧法则”的指导下寻找伴侣。
- 男人想要年轻得多的女人,以换取更少的承诺,更多的私人关系(例如,性幻想,随便的事情)。对于这些类型的关系,男性寻找的女性年龄低于令人毛骨悚然规则的下限。对于更加忠诚和公开的关系,男性会寻找与自己年龄相近的女性。
- 男人和女人都没有兴趣像猥琐法则允许的那样约会。男性和女性的最大年龄偏好都远低于恐怖规则的上限。
结果很有趣,但是仅仅因为我想和比我年轻得多的人约会并不意味着我可以接受别人做同样的事情。我仍然不知道这些令人毛骨悚然的规则是否真正代表了社会所能接受的东西。
所以我决定自己寻找答案。
设置调查
我用我所知道的唯一方法解决了这个范式转换的研究:我创建了一个调查。
我向人们展示了一些假设的场景,在这些场景中,他们的朋友“约翰”或“劳伦”开始了一段新的浪漫关系,这段关系还太早,无法定义。然后我给了他们的朋友不同的年龄——20 岁、30 岁、40 岁、50 岁、60 岁——并询问参与者他们朋友的新欢的社会可接受的最小和最大年龄是多少。
尽管我本可以走上纽约街头,以一种非传统的方式亲自调查人们,但我还是决定用手机做调查。我尽量避免日常生活中的社交活动。
对于那些不知道现代血汗工厂的人来说,你错过了。Mechanical Turk 是亚马逊的在线平台,人们向其他人支付费用来完成在线任务。这可以从转录一部电影,到识别收据上的一个项目,到进行一项关于假设的浪漫关系的调查。几天之内,我收到了 274 份回复:110 名男性,163 名女性,还有一个人“宁愿不说”。
测试“爬行规则”
结果显示,对于多年轻就可以约会,猥琐法则通常过于宽松——尤其是当你变老的时候。
根据恐怖法则,20 岁的约翰/劳伦可以和 17 岁的人约会。这与被调查者认为可以接受的结果一致(约 18)。然而,随着约翰和劳伦年龄的增长,令人毛骨悚然的规则与人们的实际反应有所不同。根据规定,一个 60 岁的女人可以和 37 岁的人约会。然而根据调查,37 岁远远超出了社会认可的年龄范围。
研究结果还显示,当你年轻的时候,关于多大年龄可以约会,这个令人毛骨悚然的规则过于严格,但是随着年龄的增长,这个规则就变得过于宽松了。
当约翰/劳伦 20 岁时,最大约会年龄限制在 26 岁([20–7]* 2)。然而,接受调查的人对约翰和劳伦在 30 岁出头时约会没有意见。
当约翰/劳伦 30 岁的时候,令人毛骨悚然的规则实际上符合人们的反应。该规则规定劳伦情人的最大年龄是 46 岁,根据调查,实际可接受的年龄是 45.4 岁。
当约翰和劳伦 60 岁时,猥琐规则允许他们和任何比自己大的人约会(官方上限是 106)。然而,社会对年龄的限制更多,分别为 71 岁和 75 岁。
总的来说,令人毛骨悚然的规则不能准确地代表人们认为社会可以接受的东西;人们比“恐惧法则”所暗示的更具批判性。对于多大年龄和多年轻的人被“允许”约会,该规定过于宽松。
我有了最初问题的答案,但我并不满意。如果恐怖规则是错误的,那么我需要一个新的规则来指导我不存在的爱情生活。当我查看数据时,我意识到一条规则是不够的。
不同的人有不同的规则
社会对男人和女人有不同的期望——男人可以比女人年轻约会,女人可以比男人年长约会。
在调查中,约翰伴侣的可接受最低年龄一直低于劳伦。当约翰/劳伦年幼时,这种差异很小(大约 6 个月),但随着约翰/劳伦年龄的增长,这种差异会增大。到他们 60 岁的时候,约翰被“允许”和比劳伦最小年龄小三岁的人在一起。
说到和年长的人约会,女人更有优势。劳伦伴侣的可接受最大年龄始终比约翰高 3.5 岁左右。
根据你在关系中的地位,社会也会有不同的期望——仅仅因为你可以接受和你的伴侣约会,并不意味着你的伴侣也可以接受和你约会。
根据调查,20 岁的约翰可以和 30 岁的人约会。然而,当劳伦 30 岁时,她应该和至少 22 岁的人约会。社会对老年人如何约会的期望与对年轻人如何约会的期望并不总是一致。
关于年龄外约会的新规则
考虑到这些不同的期望,我创造了四个“修订”规则来捕捉社会实际上认为可以接受的年龄限制。我不仅为男性和女性制定了不同的规则,还制定了不同的规则来决定男女可以约会的年龄和年龄。
对于男性:
女方最大年龄=(男方年龄)+ 12
女性伴侣的最低年龄= (2/3)*(男性年龄)+ 2【至少 18 岁】
对于女性:
男性伴侣的最大年龄=(女性的年龄)+ 15
男性伴侣的最低年龄= (3/4)*(女性的年龄)【至少 18】
下面的图表比较了修订规则的输出与原始蠕变规则的预测。我加入了“至少 18 岁”的要求,以帮助防止我出现在任何联邦调查局的监视名单上。在几乎所有的情况下,修订后的规则比“令人毛骨悚然”的规则更具限制性。
请不要用这篇文章作为建议
我认为有机会在这项如此重要的研究上更进一步。情侣之间的实际平均年龄差是多少?这项研究如何转化为同性关系?富有/出名会影响人们认为什么是社会认可的吗?
说到底,这篇文章是关于人们如何思考, 而不是 人们应该如何思考。不要把你的感情决定建立在别人的判断上。寻找能让你快乐的关系。
你可能喜欢的其他文章
如果你喜欢这篇文章,请访问LateNightFroyo.com阅读关于爱情、生活等话题的话题。
什么时候去参加聚会比较合适?
如何走出去?
多年轻才算年轻到不能约会?
来源:
Buunk,B. P .,Dijkstra,p .,Kenrick,D. T .,& Warntjes,A. (2001 年)。与性别、自身年龄和参与程度相关的择偶年龄偏好。进化和人类行为,22(4),241–250 页。
谁对你来说太年轻或太老而不能约会?今日心理学,2014 年 5 月 2 日。网络。2016 年 10 月 2 日。
[1] 虽然我们关注的是异性恋关系,但同性恋关系也会是一个有趣的后续问题。
YouTube 如何推荐视频
原文:https://towardsdatascience.com/how-youtube-recommends-videos-b6e003a5ab2f?source=collection_archive---------1-----------------------
这是麻省理工学院机器智能社区(MIC)的“ML 开创性论文”系列的第一篇论文。麻省理工学院 MIC 旨在教育整个社区关于机器学习的知识,并降低进入门槛。如需了解更多信息,请访问 https://mitmic.io 或发送电子邮件至【mic-exec@mit.edu】T2。
推荐系统是用户会遇到的最常见的机器学习形式之一,无论他们是否意识到这一点。它在脸书和推特以及 YouTube 上为策划时间线提供了动力。
之前被公式化为试图预测特定用户的电影评级的矩阵分解问题,现在许多人正在使用深度学习来解决这个问题;直觉是特征的非线性组合可能比传统的矩阵分解方法产生更好的预测。2016 年,Covington、Adams 和 Sargin 用“用于 YouTube 推荐的深度神经网络”展示了这种方法的好处,使谷歌成为首批为推荐系统部署生产级深度神经网络的公司之一。
鉴于 YouTube 是美国第二大访问量网站,T2 每分钟上传超过 400 小时的内容,推荐新鲜内容并不是一件简单的任务。在他们的论文中,Covington 等人展示了一种两阶段信息检索方法,其中一个网络生成推荐,第二个网络对这些生成的推荐进行排名。这种做法其实挺有想法的;由于推荐视频可以被提出为一个极端的多类分类问题,因此使用一个网络将任务的基数从几百万个数据点减少到几百个数据点允许排名网络利用更复杂的特征,这些特征对于候选生成模型来说可能太微小而无法学习。
背景
YouTube 对推荐系统的深度学习方法背后有两个主要因素:
- 规模:由于这些矩阵极其稀疏,先前的矩阵分解方法很难在整个特征空间中进行规模扩展。此外,以前的矩阵分解方法很难处理分类变量和连续变量的组合。
- 一致性:谷歌许多其他基于产品的团队已经转而将深度学习作为学习问题的通用框架。自从 Google Brain 发布了 Tensorflow ,以分布式方式训练、测试和部署深度神经网络就足够容易了。
此外,最近在这一领域的成功证明了这一方法的可行性。 Sedhain 等人 已经证明,使用自动编码器来解决协作问题会比有偏矩阵分解等方法产生更好的结果。
网络结构
Fig. 1, the “funnel” approach of narrowing down the set space for videos to be recommended.
有两个网络在起作用:
- 候选生成网络获取用户的活动历史 (例如,正在观看的视频的 id、搜索历史和用户级别的人口统计数据)并输出数百个可能广泛适用于用户的视频。
总的想法是这个网络应该针对精度进行优化;每个实例都应该高度相关,即使这需要放弃一些可能广受欢迎但不相关的项目。 - 相比之下,排名网络对每个视频采用更丰富的特征集,并对来自候选生成网络的每个项目进行评分。对于这个网络来说,高召回率是很重要的;只要你没有错过最相关的项目 ,有些推荐不太相关也没关系。
总的来说,这个网络是端到端训练的;训练集和测试集由保留数据组成。换句话说,网络被给予一个用户的时间历史,直到某个时间 t ,并且网络被询问他们在时间 t+1 想要观看什么!作者认为,如果 YouTube 上的视频具有情节性,这是推荐视频的最佳方式之一。
发电网络
Covington 等人将候选生成问题作为极端多类分类问题提出,其中预测问题变为“在某个时间 t 对 w(t)的某个观看时间进行准确分类”,对于某个给定的项目 i ,上下文 C 和用户 u。图 2 展示了目标的形式化。
Figure 2: Understanding the probability of the watch time distribution.
模型架构遵循传统的“塔式”方法,其中网络的底部是最宽的一层,此后每层将网络的宽度减半。作者实验了不同的网络,深度从一层到四层不等。最小的层是 256 个 ReLu 单位的一层,而最宽的层是 2048 个 ReLu 单位宽,并且是四层深。
该模型使用负采样进行训练,其中我们试图通过仅传播这些负样本的子集而不是全部来加强负结果,并针对负样本之间的关系来加强这种相关性。在服务时间,使用近似最近邻算法来服务次线性时间中的前 N 个结果。
性能黑客
在候选人生成和候选人排名网络中,作者利用各种技巧来帮助降低模型的维度或性能。我们在这里讨论这些,因为它们与两个模型都相关。
首先,他们训练了一个子网,通过学习这些特征的嵌入,将稀疏特征(如视频 id、搜索令牌和用户 id)转换为密集特征。这种嵌入是通过梯度下降与模型参数的其余部分联合学习的。
其次,为了帮助对抗开发/探索问题,他们将训练范例的年龄作为一个特征。这有助于克服模型中倾向于推荐陈旧内容的隐含偏见,这是训练时间期间平均观看可能性的结果。在服务时,他们简单地将示例的年龄设置为零,以补偿这个因素。下图有助于展示基线模型对统一类别概率的偏差。
Figure 3: a comparison on the probability of classes, with and without the “example age” feature.
它们以 A/B 测试的形式结合了生产化模型的反馈,而不是离线度量(如精度、召回或优化的损失函数)。这提供了比任何离线指标更真实的目标。为了优化这一指标,作者平等地权衡了所有用户,这样一小部分高级用户就不会影响面向大众的内容推荐。
对预测进行排序
将推荐系统分成两个网络背后的基本思想是,这为分级网络提供了用比候选生成模型更精细的齿梳检查每个视频的能力。
例如,候选生成模型可能只能访问诸如视频嵌入和观看次数之类的特征。相比之下,排名网络可以采用诸如缩略图和他们的同行的兴趣之类的特征,以便提供更加准确的评分。
排名网络的目标是最大化任何给定推荐的期望观看时间。由于视频中常见的“点击诱饵”标题,Covington 等人决定尝试最大化点击概率的观看时间。
与候选生成网络类似,作者使用嵌入空间将稀疏分类特征映射到密集表示中。与多个项目相关的任何特征(即,在多个视频 id 上的搜索等)在被馈送到网络之前被平均。然而,依赖于相同底层特征的分类特征(即印象的视频 ID、最后观看的视频 ID 等)在这些类别之间共享,以便保留存储器和运行时间要求。
就连续特征而言,它们通过两种方式进行规范化。
- 首先,它遵循[0,1]之间的标准归一化,使用累积均匀分布。
- 其次,除了标准归一化 x 之外,还馈入了表格 sqrt(x) 和 x 。这允许模型创建每个特征的超线性和亚线性函数,这对于提高离线精度至关重要。
为了预测预期观看时间,作者使用了逻辑回归。点击印象用观察到的观看时间来衡量,而负面例子都接受单位重量。在实践中,这模拟了概率 ET ,其中 E[T] 模拟了印象的预期观看时间,P 模拟了点击视频的概率。
最后,作者展示了更广更深的网络对每用户损失的影响。每用户损失是指错误预测的观看时间总量,与保留数据的总观看时间之比。这允许模型预测作为好的推荐的代理的东西;而不是预测一个好的推荐本身。
Figure 4: Demonstrating the effects of wider and deeper networks on next-day holdout data.
相对清楚的是,这些结果表明,更宽+更深的网络往往会大大减少损失。作者选择部署最后一个模型。有趣的是,选择最后一个模型,同时决定平等地权衡正面和负面的例子,会导致加权损失增加 4.1%。
结论
“用于 YouTube 推荐的深度神经网络”是首批强调深度学习可能为推荐系统提供的进步的论文之一,出现在 ACM 2016 年推荐系统会议上。它为后来的许多论文奠定了基础,包括有影响的“ Irgan:统一生成式和判别式信息检索模型的极小极大博弈”。
我们“ML 开创性论文”系列的下一篇是更快的深度学习:最佳 DNN 原语。之后请继续关注 WaveNet 了解更多信息!
有兴趣了解更多关于机器智能及其对我们世界的影响吗?在http://machineintelligence.cc/了解更多关于机器智能社区的信息,并发送电子邮件mic-exec@mit.edu了解更多!
关于作者
莫因·纳迪姆(Moin Nadeem)是麻省理工学院(MIT)的大三学生,也是麻省理工学院机器智能社区本科生人工智能俱乐部(本科生 AI club)的联合主席。今年夏天,他正致力于开发一种协同过滤方法,在 Quizlet 上推荐内容,并在空闲时间和朋友们一起闲逛。了解更多关于 MIC 的信息。
如何成为一名计算机科学家
原文:https://towardsdatascience.com/howto-became-a-computer-scientist-2ecb6e9e7835?source=collection_archive---------4-----------------------
Just cool fractals made by Nick Spratt
经常有人问我如何成为一名计算机科学家。这就是为什么我决定描述我自己的道路。当然,网上已经有很多其他的教程了,所以这里我只收集它们并把它们合并成一个。此外,由于每个人的知识水平不同,因此是否跳过某些部分由您决定。
主要学习可以分为四个主要主题:附加资源、数学、编程和机器学习本身。
其他来源
有些资源是完全可选的,不是理解该领域所必需的。但是如果你覆盖了它们,学习其他的东西就容易多了。
- 学习如何学习(Coursera )。它将向你解释我们的大脑是如何工作的,以及如何利用这些知识进行更快更好的学习。我强烈建议在开始学习之前先通过这门课程,它真的很有帮助。
- 数学思维入门(Coursera) 。这门课程让你了解如何不用数学,而是用数学来思考。“数学思维不同于做数学——至少不同于我们学校系统中典型的数学”。如果你打算深入研究数据科学的数学方面,这将是适用的。
数学
为了计算机科学的目的,你至少应该知道线性代数和概率和信息理论。目前我还没有为这些主题选择资源,但是简介在深度学习书籍,第一部分中有很好的介绍
如果你觉得深度学习的书很复杂——试着通过可汗学院的线性代数和统计和概率课程。
编程;编排
作为一门编程语言,我会选择 Python3 ,因为它易学易用。我建议通过这样的书去接触它:
- 思考 Python——一本介绍 Python 世界、算法和编程的书。
- 深入研究 Python—Python 的更深入的用法。它会通过例子教你如何使用这种语言。
- Python 食谱 —带讨论的现成 Python 示例。
- 流利的 Python——成为真正的 Python 高手。
- 用于数据分析的 Python—描述如何使用 Python 库,如 numpy、pandas、matplotlib 和其他用于数据分析的库。
- Scipy 课堂笔记——完全免费的笔记,在这里你可以学习如何使用主要的 Python 包,也是为了科学。
另一个对你有用的话题是:
- linux/unix 系统和 bash。看一看这个教程。
- 版本控制系统,比如 GIT。这里有个很酷的在线教程,大概 30 分钟就能传过去。
机器学习
在学习了数学基础和一些编码之后,您可以开始学习 ML 本身:
- 阅读 Adam Geitgey 系列博文。至少有几个。他们会给你一些想法,机器学习到底是关于什么的,为什么它如此酷和有趣。
- 来自 AndreNg 的 Pass 入门课程—可在 Coursera 和斯坦福网站获得。它将描述机器学习的主要原理和应用。出于教育目的,本课程使用 Octave 作为主要语言,但使用它很容易理解。课程中还有对 Octave 的介绍。
- 利用所学知识,尝试通过 Kaggle 的一些入门比赛,如泰坦尼克号:灾难机器学习或数字识别器。 Kaggle 本身“是作为一个预测建模和分析竞赛的平台而成立的,公司和研究人员在这个平台上发布他们的数据,来自世界各地的统计学家和数据挖掘者竞争产生最好的模型”( wiki )。为了解决入门任务,我建议你学习一种用于机器学习的 Python 框架: scikit-learn (更容易)或 tensorflow (更难)。在 udacity 有一个关于 tensorflow 的相当不错的[课程。](https://www.udacity.com/course/deep-learning--ud730)
- 通过 CS231n:用于视觉识别的卷积神经网络斯坦福课程。它将教你如何将机器学习应用于图像。
- 从教程中改进结果。开始在你自己的项目中使用机器学习。实验算法/神经网络架构。
- 不要犹豫尝试任何其他框架,如 Theano、Caffe、Pytorch 等。
- 端到端阅读深度学习书籍。
- 看一些报纸。尝试自己实现一些模型。
- 更新一些型号。发表自己的论文。
结论
我希望这样的途径对你有用。以后我会尽量用相关资源更新。所以请在评论中随意指出一些有趣的东西。感谢阅读!
如何分析张量流:
原文:https://towardsdatascience.com/howto-profile-tensorflow-1a49fb18073d?source=collection_archive---------1-----------------------
现在 TensorFlow 是机器学习最常用的库之一。有时,绘制张量流图并了解哪些操作花费更多时间,哪些花费更少时间可能非常有用。这可以通过 tensorflow timeline
模块完成。不幸的是,我找不到任何清晰的教程如何使用它。因此,在这篇博文中,我将尝试解决这个问题,涵盖以下主题:
- 如何执行张量流代码的剖析?
- 如何合并多个会话运行的时间线。
- 分析过程中可能会出现哪些问题以及如何解决这些问题。
简单的例子
首先让我们定义一个简单的例子,然后是 StackOverflow 回答:
您应该注意到为会话运行提供了额外的options
和run_metadata
。这个脚本应该在 CPU 和 GPU 上运行。执行之后,我们将拥有一个timeline_01.json
文件,其中包含以 Chrome trace 格式存储的分析数据。如果您的脚本失败了——请尝试来自【profiling 期间的问题部分的第一个解决方案。
要查看存储的数据,我们应该使用 Chrome 浏览器(不幸的是,据我所知,只有它支持自己的跟踪格式)。进入chrome://tracing
页面。在左上角,你会发现Load
按钮。按下它并加载我们的 JSON 文件。
Example profiling of our simple script on CPU.
在顶部,你会看到以毫秒为单位的时间轴。要获得一些操作的更精确的信息,只需点击它。同样在右边,有简单的工具存在:选择,平移,缩放和计时。
更复杂的例子
现在让我们用一些占位符和优化器来定义更复杂的例子:
现在我们的操作存储在变量作用域下。使用这种方法,操作名称将以作用域名称开始,并在时间线上明确区分。
此外,代码存储三次运行的跟踪。如果我们在 CPU 上执行脚本,我们会收到三个相对相似的时间线,如下所示:
Profiling second script on CPU.
但是,如果我们检查来自 GPU 分析的结果,第一个结果将与接下来的结果不同:
Profiling second script on GPU, 1-st run.
Profiling second script on GPU, 2-nd or 3-rd run.
你可能会注意到,第一次运行比以后的运行花费更多的时间。这是因为 tensorflow 在第一次运行时会执行一些 GPU 初始化例程,稍后会对它们进行优化。如果你想要更精确的时间线,你应该在运行一百次左右后存储轨迹。
此外,现在所有输入/输出流都以变量作用域名称开始,我们确切地知道一个或另一个操作在源代码中的位置。
在一个文件中存储多次运行的时间线
如果出于某种原因,我们希望在一个文件中存储多个会话运行,该怎么办?不幸的是,这只能手动完成。Chrome trace 格式中存储了每个事件及其运行时间的定义。在第一次迭代中,我们将存储所有数据,但是在下一次运行中,我们将只更新运行时间,而不是定义本身。这里只是合并事件的类定义,完整的例子你可以在这里找到:
我们收到了很酷的合并时间线:
Merged profiling for 5 runs.
看起来初始化还是需要很多,我们放大到右边:
Merged profiling for 5 runs zoomed.
现在我们可以看到一些重复的模式。运行之间没有任何特定的分隔符,但我们可以在视觉上区分它们。
分析期间的问题
在剖析过程中可能存在一些问题。首先,可能根本行不通。如果您遇到了类似这样的错误:
I tensorflow/stream_executor/dso_loader.cc:126] Couldn't open CUDA library libcupti.so.8.0\. LD_LIBRARY_PATH:
你确定不按预期对所有作品进行概要分析,它可以通过安装额外的库libcupti-dev
根据 GitHub 问题得到解决。此命令应该可以修复所描述的错误:
sudo apt-get install libcupti-dev
其次是运行过程中的延迟。在最后一张图片上,我们看到了运行之间的间隙。对于大型网络,这可能会花费大量时间。这个 bug 不能完全解决,但是使用定制的 C++ protobuf 库可以减少延迟。在 tensorflow 文档中清楚地描述了如何执行安装。
结论
我希望通过这样的分析,您能更深入地了解 tensorflow 的内部情况,以及您的图表的哪些部分可以优化。所有已经在 CPU 和 GPU 上生成时间线的代码示例都存储在这个 repo 中。
感谢阅读!
假人的降维第 1 部分:直觉
原文:https://towardsdatascience.com/https-medium-com-abdullatif-h-dimensionality-reduction-for-dummies-part-1-a8c9ec7b7e79?source=collection_archive---------2-----------------------
人类是视觉生物。我们需要亲眼目睹才能相信。当你有一个超过三维的数据集时,我们的眼睛就不可能看到发生了什么。但是谁说这些额外的维度是真的必要的呢?有没有办法把它减少到一维、二维或三维?原来是有的。
主成分分析(PCA)就是这样一种技术。简单又优雅。可惜,简单并不意味着容易看透,真正明白是怎么回事。如果你以前读过它,你可能会遇到一个完全数学化和抽象的处理,但对它的意义没有直觉。或者它可能被解释为“外行风格”,没有数学依据。或者两者都有一点,中间有一个概念上的空白,没有把直觉和严谨联系起来。我会尽量避免这种情况。
降维的主要目的是:找到数据的低维表示,尽可能多地保留信息。这是一个相当大胆的说法。让我们看看这是什么意思。
摆脱不必要的东西
假设我们有以下某个地区的房价数据集,单位为千美元:
Dataset with 4 features per item
该数据集有 4 个特征(4 个维度),不可能作为一个整体进行图形可视化。但是,如果您仔细研究这些特性之间以及它们之间的关系,您会发现并非所有的特性都同等重要。
例如,你能通过楼层数来描述每栋房子的特征吗?楼层数有助于区分不同的房子吗?似乎不是,因为它们几乎等于,也就是说它们有低方差,即σ = 0.2、和因此不是很有帮助。家庭呢?变化不大,但其方差肯定大于楼层数(σ = 28),因此更有用。现在,对于最后两个特征,面积(σ = 43)和值(σ = 127),它们变化更大,因此比我们的其他两个数据更具代表性。
但是我们可以做一些事情来最大限度地充分利用每个特性,而不会牺牲太多的准确性。到目前为止,我们已经分别研究了每个特性。他们彼此之间的关系如何?如果你仔细观察前两个特征,值和面积,你会注意到值大约是面积的两倍。这非常有用,因为我们现在可以从一个特征推断出另一个特征,而且只需要一个而不是两个。这个性质叫做协方差。协方差越高,两个特征的相关性越强,这意味着数据中存在冗余,因为我们可以从一个特征推断出另一个特征,所以信息比需要的多。
从前面的讨论可以明显看出:
- 拥有高方差的特性是件好事,因为它们会提供更多信息,也更重要。
- 具有高度相关的特征是一件坏事,因为它们可以在信息损失很少的情况下从另一个特征中推断出来,因此将它们放在一起是多余的。
这正是 PCA 所做的。它试图找到数据的另一种表示法(另一组要素),以使该表示法中的要素具有最高的可能方差和最低的可能协方差。但是现在这应该说不通,直到我们亲眼看到…
给我看看魔法
在接受 PCA 采访时,我问了她以下问题:“你的完美数据集是什么样的?”她给我看了这个:
这是有意义的——数据本质上可以被简化为一行。观察:与 x 2 方向相比,沿x1 方向的变化非常大,这意味着我们可以安全地丢弃 x 2 特征而不会造成太大损害(通过说“沿 x 1 方向的变化”,我指的是第一个特征的变化,因为我们选择用 x 1 轴来表示它,对于 x 【T29 也是如此)而且, x 1 似乎根本不依赖于 x 2,它只是继续增加,与 x 2 的值无关,这暗示着相对低协方差。至于为什么这对 PCA 来说是完美的,原因很简单,因为她需要做的就是:
Projecting the dataset on the x1 axis.
After projection, the data only has one dimension.
了解发生了什么至关重要。因为 x 1 比 x 2 重要得多(根据前面说的两个标准),我们决定只保留 x 1,通过将数据点投影到它的轴上,这相当于只保留了点的x1-坐标,这也相当于去掉了“不重要”的特征 x 2。现在我们有了 1D 的数据集,而不是 2D!
这实质上是维度缩减:寻找数据的最佳低维表示。当然,会有一些误差,因为我们忽略了第二个特征,它由上面的虚线表示。但是这种误差被保持在最小,因为数据几乎位于一条线上,并且这是我们利用给定的信息实际上能做的最好的事情(稍后将详细介绍)。
事情变得复杂了
“那么,你不那么完美的数据集呢?长得怎么样?”我问过 PCA。她毫不犹豫地说:“我真的不相信有这种事,你知道。每个人都是完美的,你只需要换个角度。来,看看这个。”
“不像以前那么容易了,你不觉得吗?没有。”她歪着头说。
“这实际上是我之前向您展示的同一个‘完美’数据集,只是旋转了 45 度。我们所要做的就是旋转我们自己的轴以与数据集对齐,并像以前一样继续:投影到新 x 1 轴上,并省略新 x 2 轴”
停下来思考一下这一意想不到的事件变化是至关重要的。就像工程师通常做的那样,主成分分析将没有“对齐”的数据集的不太完美的问题简化为容易解决的完美的“对齐”问题。
这是怎么发生的?本质上,PCA 试图找到另一组轴,使得沿该轴的方差尽可能大。当我说“沿 x 1 轴的方差”时,我指的是特征 x 1 的方差。但是旋转了我们的轴之后,轴就失去了意义——它们不再代表 x 1 或者 x 2。相反,它们代表了两者的线性组合。要了解如何操作,请注意上面的新 x 1 和 x 2 轴可以通过对旧轴执行旋转变换来获得,获得:
这两个新方向, z 1 和 z 2,是数据集的主成分。第一主成分, z 1 是方差最大的一个,因此也是最重要的一个,携带最多的信息,从某种意义上说,数据依赖于它。第一主分量方向上的变化现在被解释为新的合成特征 z 1 的变化。至于第二主成分, z 2,它只是方差第二大的一个主成分垂直于第一主成分。**
顾名思义,主成分分析就是寻找这些主成分,以便我们可以利用前几个方差最大的主成分来表示我们的数据,就像我们将完美的数据集投影到一条直线上时所做的那样。
很容易看出这如何能推广到二维以上。我们不是投影到线中,而是投影到平面中,我们完美的 3D 数据集现在大约位于一个平面上(或者,更好的是,一条线)😗*
神奇的线条以及在哪里可以找到它们
现在真正的问题来了:如何找到这些主要成分?
我将把这个问题留给下一部分,在那里我们将开发那个主公式:
Singular Value Decomposition
在这个过程中,我们将发现如何将我们在这里发展的定性直觉转化为适用于所有维度的优雅的数学结构的深刻见解。
一个小样本能告诉我们关于一个大群体的什么?—第一部分
原文:https://towardsdatascience.com/https-medium-com-aparnack-what-can-a-small-sample-teach-us-about-a-big-population-part-1-b7c048c22bf2?source=collection_archive---------6-----------------------
理解基本术语
Pixabay
简介:
推断统计学:它是什么?查看这里的正式定义。推断统计学和数据科学是如何关联的?推断统计学通过从大量数据(总体)中抽取一个小的子集(样本)来帮助估计数据中的未知量,并检查我们对未知量的假设。这对学习机器学习的底层原理很重要(跳到最后看看怎么做)。它是营销数据科学的面包和黄油。
推断统计是非常基本的,但被低估的概念。大多数数据科学训练营只是触及了皮毛。然后是关于 p 值黑客和样本测试无用的帖子,因此使我们中的一些人能够愉快地忽略这一部分。我是推断统计学的粉丝之一。
当我第一次通过这个 coursera 课程学习时,推理统计学给了我很大的刺激。我想写一写它,但是想知道用一个像温度数据这样的小数据集来展示它是否有趣。在做了一些研究之后,我确信我将要在这里展示的东西会引起人们的兴趣。为什么?那是你看完之后决定的。以下是我认为你会感兴趣的原因。大多数研究从 t-检验/z-检验的公式开始,定义诸如误差范围、z-stat 等术语以及如何计算它们。在这篇文章中,公式出现在最后,所有的困惑都被正面处理。
在阅读任何与统计相关的文章时,很容易感到困惑。我将尽可能地强调混淆点,基于我在道路上混淆的地方(当第一次学习概念时)。
先决条件:
没有推断统计学的先验知识。然而,你应该知道什么是均值、标准差、方差、条件概率、分布函数、正态分布和中心极限定理(CLT)。如果你不知道 CLT,请浏览这个由可汗学院制作的短片或阅读这篇文章。如果你不知道其他条款,请不要马上阅读这篇文章。首先从一个在线课程(Coursera,datacamp,Udacity,任何一个取决于你对什么感兴趣)中学习“描述统计学”,然后回来。这是一个很大的话题,因此我决定写一系列的帖子。这篇文章将有术语介绍。
术语和直觉:
看这张照片。这是您在进行任何样本测试并满怀信心地报告您的发现之前,至少需要了解的内容!!
Image: Drawn by myself
人口:精确分布或汇总统计数字未知的一组数字。 (你只有一些想法,不能称之为“已知”)
例如:全世界人的体温,印度农村儿童的智商,某一种花的萼片长度。你说吧!
样本:来自总体的一小部分。混乱从这里开始。“样本”是一个数字吗?不,这是一组数字。
Taking Sample and Drawing Inferences (Image Courtesy: Google Images)
例如,人类心率的 100 次测量。这是人类心率群体的样本。它不是人口的“样本”。如果您有 3 组不同的 100 个测量值,那么就是人口的 3 个“样本”。获取样品的过程称为取样。这里的数字 100 是样本量,通常用 n 表示。通常当取 1000 个大小为 100 的样本时,会有将 1000 混淆为 n 的倾向。
样本不必总是从总体中抽取。也可以从另一个样本中取样!
可以进行采样,
I)无替换:来自总体或原始样本(从中进行抽样)的每个成员在所取样本中只能出现一次。
ii)替换:总体或原始样本(从中进行抽样)中的每个成员可以出现与样本大小一样多的次数。替换取样在开始时似乎有点奇怪。
样本分布:样本分布。这通常使用直方图命令绘制(对于 Python 用户,为 matplotlib.pyplot.hist 或 seaborn.distplot)。样本是总体的一个子集,因此,在没有替换的情况下进行抽样时,分布的形状类似于总体分布。然而,我们应该始终意识到这只是一个近似值,因为它是总体的一个抽样版本。当样本量 n 足够大时,这通常足以收集关于总体的大量信息。
样本中心:中心指均值、众数或中位数。一个样本的中心靠近人口的中心,这就是为什么我们要取样并试图了解他们的原因。永远记住这篇文章的开头句子。我们的目标是理解/估计未知量,即总体及其参数/统计量。
样本的离差:离差可以指以下任何一项:方差、范围值,或通常指距中心的几个标准差。样本分布是总体分布的近似值。仔细阅读下一句话:很多时候,从样本中心估计人口中心(例如:平均值)的公式将需要人口分布(比如标准差)的值,显然这是不可测量的(人口参数是不可测量的),因此在公式中,我们使用样本分布。
还有一个术语叫做抽样分布,也叫 Bootstrap 分布。如上图所示,以样本均值作为感兴趣的统计量。
抽样分布:我们可以从总体中抽取 N 个大小为 N 的样本,并测量样本统计量。这些测量值的分布称为抽样分布。
这是另一个困惑点。近似总体分布的样本分布和作为测量样本统计量(如均值)分布的样本分布是不同的。
中心极限定理的妙处:回想一下,对于一个正态分布,均值、中位数、众数都是一样的。还记得我们用样本分布代替总体分布。
Image courtesy: Screen capture from coursera inferential statistics course
样本均值的抽样分布(不是总体均值的抽样分布!)理论上是以“人口平均数”为中心的。请注意,测量真实的总体平均值是不可能的。经常(conf)使用【估计】样本均值是正常的。这是不对的。样本可用,因此其平均值是测量值,不是估计值。这种抽样分布的标准偏差是 n 的平方根的“理论总体标准偏差”。这被称为平均值的标准误差,或 SEM 。
现在,我们如何用 CLT 来从 N 个样本均值中估计总体均值?N 是每个样本的大小,N 是样本的数量。CLT 的有用性来自于这样一个事实,即人们可以通过增加样本大小 n 来提高获得更好估计的机会,即降低估计中的误差。N 越高,正态曲线越平滑,视觉效果越好,但这并不影响估计的理论精度。人们通常很容易混淆 n 和 n。请试用这个免费工具,通过研究不同类型的人口分布和不同的 n 和 n 值来了解 CLT
[## 平均值的中心极限定理
编辑描述
gallery.shinyapps.io](https://gallery.shinyapps.io/CLT_mean/)
我认为触及 bootstrap 也很重要,因为基于 CLT 的人口参数估计不够通用。
Bootstrapping:Bootstrapping 技术在无法应用 CLT 时很有用,因为要么假设不成立,要么我们感兴趣的是统计而不是均值。如果只有一个大小为 n 的样本可用,我们通过复制这个样本来创建更多的样本。要做到这一点,用更换的样品再次进行相同大小(即 n)的取样。注意,如果自举采样是在没有替换的情况下进行的,我们得到的是原始样本本身,这是没有用的。这使我们能够估计人口的任何统计数据,不像基于 CLT 的估计,这只是为了平均。
Bootstrap 分布:假设我们取 N 个这样的样本,称为 Bootstrap 样本。测量每个样本的感兴趣的统计量,这种测量被称为“引导复制”。这些副本的分布称为引导分布。N 越大,绘制的分布越平滑。
置信区间和置信水平:我们有这个正态分布,就是样本均值的概率分布(pdf)。就像所有的 pdf 一样,这条曲线下的面积是 1。出于所有计算目的,我们将其视为理想的正态曲线,即围绕平均值对称。
Plot showing P(Sample mean < a) as shaded green area
上述曲线的含义:如果从总体中随机抽取一个大小为 n 的样本,测量样本均值(xbar),xbar 小于某个值“a”的概率为= a(绿色虚线)处垂直线左侧的曲线下面积。理解这一点非常关键。这将有助于理解这篇文章的剩余部分和这个系列的下一篇文章,解释 p 值,假设检验。
假设 xbar 是这条曲线的平均值。样本均值在区间[xbar-b,xbar+b]内的概率就是该区间内曲线下的面积,把这个面积数称为 a .直观地表示出来,
Figure demonstrating the confidence interval corresponding to a confidence level
上界为 1(因为是概率)。 [xbar-b,xbar+b]是对应于置信水平 A*100%的总体均值估计的置信区间。一种解释方式是,如果从总体中抽取 100 倍的随机样本并测量其平均值,则 A*100 倍的平均值预计位于区间[xbar-b,xbar+b]。
对于较大的 A,置信区间较长(较宽),对于较小的 A,置信区间较短。混淆点:置信水平 Vs 置信区间。置信区间是长度和 x 轴的一部分。置信水平为面积,为曲线下面积的部分;在这种情况下,两者之间存在一对一的关系。
z-stat : z-stat 更多时候被看作是一个公式,而不是直观的。z-stat 只是一个用于计算与所选置信水平相对应的标准偏差的实数的别称。换句话说,要得到一个*100%的曲线下面积,两边要取多少个均值周围的标准差?那是你的 z-stat。人们经常会混淆 z-score 和 z-stat。z-score 用于(样本的)任何单个数据点,z-stat 用于样本统计。
Image courtesy : Wikipedia
深蓝色是平均值两边的一个标准差。对于正态分布,这占集合的 68.27%(对于 A = 0.6827,z-stat = 1);而平均值的两个标准偏差(中蓝色和深蓝色)占 95.45%;三个标准差(浅蓝、中蓝和深蓝)占 99.73%;四个标准差占百分之 99.994(对于 A = 0.99994,z-stat=4)。z-stat 和置信水平/区间具有 1-1 的关系。陈述其中一个就足以找出其余的。
有人可能想知道我们熟悉的 z-stat 公式在哪里。这是你在想的吗?
如果您有一个带有均值 xbar 和样本标准差的样本,
Formula for z-stat
可以这样想,有一个正态分布,以真实的总体平均值为中心,人们试图找出随机抽取的样本平均值 xbar 位于各种蓝色阴影中的哪个区域。
误差范围:使用 CLT 完成所有估算后,如何陈述结果?你知道在我们上面定义的均值估计中有一个标准误差。希望你明白它的意思。那么,它如何转化为真实人口的误差呢?误差幅度对应于一些标准偏差或置信水平。标准差是 sqrt(n)*SEM。可以将结果表述为,“我对总体均值的估计= xbar +- z-stat *样本 std”(回想一下,样本 std 只是总体 std 的一个替代)
这里可能会出现混乱:人口均值估计中对应 A*100%置信度的误差幅度是 b ?否。这通常是我在许多 Python 笔记本中观察到的基于估计值测量总体参数正常范围的错误。事实上 xbar+ b 或 xbar -b 是抽样分布图的 x 轴上的点,而不是人口分布上的点。A100%对应的总体均值的误差幅度实际上会是 xbar +- z-stat sqrt(n)*b,为什么?回忆一下中心极限定理和由此产生的分布的标准差。它是总体的标准差/ sqrt (n)。直观上,真实总体均值的置信区间更宽,因为其标准差是 sqrt(n)倍。(抱歉重复,我认为在统计学研究中,重复和重新措辞有助于概念的强化)
从本质上讲,取样和测量样本均值的整个过程有助于估计总体均值。样本量越大,平均值的标准误差越小,相同 b(相同宽度)的 A(更高置信度)越高。
与机器学习的关系:
以多元线性回归为例。一个是试图拟合一条 n 维直线 y = f(x),其中 f(x) = a0 + a1x1 +a2x2 + …。an * xny 是目标变量,x1 到 xn 是特征,a0 是截距,a1 到 an 是系数。每个特征向量在机器学习中称为一个样本,这个样本类似于上面段落中讨论的样本。这里,f(x)实际上是将特征向量 x 与 y 相关联的真实函数的估计值。f(x)是使用称为训练数据的一组特征来估计的。使用称为测试数据的另一组样本来测试这种线性拟合 f(x)。群体是从中抽取训练样本、测试样本的整个集合,并且群体具有许多我们从未见过的样本(这就是为什么再多的测试也不能保证 ML 算法的性能)。a0 到 an 类似于 xbar。就像 xbar 是作为几个样本平均值计算出来的,a0 到 an 是从总体的几个样本计算出来的。解释机器学习算法基础的书籍也谈到了系数估计的置信区间。现在,你也许能更好地和他们相处。
编辑:1。中心极限定理是理解当构建多个树以形成集合(如在 Bagging 分类器、随机森林等中)时为什么过度拟合(方差)减少的关键。
2.“B”oot spatting 和“Agg”regating 是使它“bagging”的原因。因此,如果一个人理解自举背后的直觉,他会更好地记住 Bagging 分类器及其修改版本 Random Forest。
结论:
希望到本文结束时,一些术语已经很清楚了,我们已经为这个系列的下一部分做好了准备。在下一篇文章中,我将借助 python jupyter notebook 分析的人体体温数据来解释所有这些术语。我还计划引入新的术语,并举例说明假设检验(1 样本,2 样本检验)。在那之前,希望你喜欢阅读这篇文章,并在这里提出问题。我强烈建议做一个谷歌搜索,从多个来源阅读,看看你的理解是否超越了公式。不同的资源有时会有不同的符号,如果你的大脑很清楚,尽管阅读不同的资源,你应该保持清晰。
审查学分
该系列由数据科学社区的活跃人士之一进行审查后发布: Megan Silvey
你可以去我的 github 查看我的数据科学工作。在推特上关注我,听听关于数据科学/机器学习/哲学的偶然想法。如果有任何令人兴奋的合作机会,请给我发邮件到 aparnashastrymls@gmail.com
机器学习入门:几乎没有数学—第 2 部分:感知器
原文:https://towardsdatascience.com/https-medium-com-atharvaj-a-machine-learning-primer-almost-without-the-math-part-2-perceptron-33145c6df067?source=collection_archive---------10-----------------------
在上一篇文章中,我们让自己熟悉了机器学习中的基本术语。在下面的文章中,我们将学习一些机器学习算法,首先是感知器。我还将介绍更多的概念,当它们开始发挥作用时。
感知器
感知器是一种受人类神经元启发的构造。它有一组输入通道、一个细胞体和一个细胞输出。感知器是一个二元线性分类器。它只能产生线性决策边界。
让我们试着一个一个来看术语 :
- 线性分类器:任何可以对线性可分数据进行分类的分类器,即可以通过线性判定边界进行分离的数据。
Decision boundary in 2 dimensions.
- 决策边界:决策边界是一个假想的边界,可以分隔不同类别的数据点。
- 线性判定边界:在 2 维中(对于 2 个特征),它是一条直线,在 3 维中(对于 3 个特征),它是一个平面。很难想象 3 维以上的超平面。对于给定的数据集,可能有一个以上的决策边界。
Decision boundary in 3 dimensions.
我们将试图理解作为分类器的感知器的结构和工作原理。
考虑这样一种情况,我们想要预测在给定的十字路口是否会发生事故。我们从交通部门获得了关于在给定的交叉路口过去事故的数据。
每个例子都有一些特征,包括车速、雨的强度、红灯是否亮着,以及出于某种奇怪的原因,那个地区的冰淇淋价格。
下面是一个简单感知器的架构:
- 权值:权值是感知器的型号 参数 。它们代表了与每个特性相关的重要性。通常,当模型被初始化用于训练时,这些是随机化的。
- 求和:所有特征值加权求和的结果。
- 激活函数:一个数学函数,帮助理解从求和(或任何先前的一组运算)中获得的单个值。例如,如果求和后的最终值大于 0.3,则该模型将预测事故。对于下面的示例,我们将阈值设置为 0.3。
如果激活函数值>为 0.3,则事故发生
训练感知器
当输入数据被输入到模型中时,根据权重对其进行加权、求和并通过激活函数,激活函数根据阈值给出输出。
让我们将第一个数据点传入感知器。最初,权重值是随机的(或者可以设置为任何指定值)。为了便于理解,我们将假设所有数字数据都在 1 到 5 的相似范围内:
RANDOM WEIGHTS TO START WITH
在上图中,模型对汽车速度给予了更多的权重,其次是冰淇淋价格,然后是红灯,然后是雨。
由于冰淇淋价格被赋予了更大的权重,并且它在我们的输入中的值很高,因此该模型将主要基于冰淇淋价格进行预测。
让我们假设该模型基于给定的输入给出了 0.5 的输出值。给定我们的阈值 0.3,模型将预测导致事故的输入。
(输入*权重)之和= 0.5
激活阈值= 0.3
0.5 > 0.3,因此会发生事故。
但是从输入标签上,我们知道它不会造成事故。在产生的值中存在 0.2 的误差,并且该信息需要被反向传播到模型中,以便它可以更好地执行。
反向传播
在这个过程中,预测中的任何错误都被发送回模型,以便它可以更新其权重,从而在看到的下一个样本中做出更好的预测。有不同的方法可以在权重之间分配误差,其中一种常见的方法称为随机梯度下降。这些方法被称为优化算法。
遵循优化算法,模型现在更新与冰淇淋价格相关的权重。
WEIGHT OF ICE CREAM PRICE DECREASES
当看到越来越多的例子时,它最终赋予冰淇淋价格 0 的权重,从而意识到这个特征在决定情况的结果中不起作用。
WEIGHT FOR ICE CREAM PRICE ULTIMATELY REDUCES TO 0
模型没有必要只从输出为“是”的例子中学习。可能会有这样的情况,当冰淇淋价格低时,模型预测为否,而当冰淇淋价格高时,模型预测为是。在这种情况下,模型也将通过增加冰淇淋价格的权重来学习。
在这一切发生的同时,与其他特征相关联的权重也在同步更新。因此,如果误差为 0.2,并非所有权重都会更新 0.2,而是根据权重对结果的影响程度,由所有权重共享 0.2。为了简洁起见,上面的例子只显示了一次更新一个权重。
类似于去掉一个特征,如上所述,模型也能理解哪些特征应该被赋予更大的权重。对于汽车速度高和/或雨水多的情况,随着看到越来越多的例子,模型将慢慢赋予这些权重更多的值。
WEIGHT FOR RAIN INCREASED
对于具有数值的特征来说,所有这些都没问题,但是对于具有“是”或“否”等值的分类特征来说,情况又如何呢?嗯,我们把它们转换成数字形式!
虚拟变量/一个热编码
虚拟变量实际上是虚拟变量,用来代替分类变量。单个分类变量被分成与类别数量一样多的虚拟变量。
因为红灯可以有两个值,是和不是,所以有一个虚拟变量,假设是。因此,如果值为 YES,虚拟变量的值将为 1,否则为 0。
DUMMY VARIABLES FOR 2 CATEGORIES
是/否将变成 YES_dummy = 0 或 1,NO_dummy = 0 或 1。如果 YES_dummy = 0,NO_dummy = 1,则类别为 NO.
如果有三个值,是,否和也许,那么我们可以用两个虚拟变量来表示它们。如果我们仍然在虚拟世界中保留是和不是,那么我们可以忽略也许。可以对任意数量的值进行类似的操作。
DUMMY VARIABLES FOR MORE THAN 2 CATEGORIES
YES /NO /MAYBE 将变成 YES_dummy / NO_dummy,每个值为 1 或 0。
如果 YES_dummy 的值为 1,那么是。如果 NO_dummy 的值为 1,则 NO.
如果 YES_dummy 和 NO_dummy 都为 0,则值必须为 MAYBE。
因此,当前类别的值为 1,其余都为 0。
在我们的示例中,我们将分类特征转换为两个虚拟变量,YES_red、NO_red,每个变量的值为 0 或 1。
CONVERTING INTO DUMMY VARIABLES
正如您可能已经想到的那样,将分类变量转换为数字变量的过程甚至需要在训练开始之前或构建模型之前完成,以便权重和输入的数量是适当的。
现在,在查看了许多例子之后,这个模型得出了以下权重:
TRAINED MODEL
看重量 we,或者模型,可以说车速高,下大雨,车在红灯的时候,发生事故的几率更大。也许在这种情况下汽车不会那么容易抛锚,谁知道呢?!
没有必要所有的权重都是正的。有些要素的高值会对结果产生负面影响。假设有一个新的功能制动等级,制动等级越高,汽车在潮湿条件下的制动性能越好。
WEIGHTS CAN BE NEGATIVE AS WELL
有些例子可能会误导模型。像是下了高雨高速却没出事的情况。这被认为是数据中的异常值,在训练时应该会遇到。这就是为什么在该算法中更多的训练数据会产生更好的结果,因为模型将会看到更多的数据来进行推断,并且可以防止过度拟合离群值,从而更好地进行概括。
过度拟合
过度拟合不好!这是模型学习预测几乎所有定型示例的情况,即使它们是异常值。如果它学会正确预测所有的例子,那有多糟糕?如前所述,它学习预测所有的“训练”例子。我们为它创建一个 ML 模型,用于新的例子,而不是训练数据。训练数据不代表所有可能数据的一般分布。当模型过度拟合时,它可以很好地预测所有的训练样本,但不能正确预测任何其他测试样本;正是为其创建模型的任务。
正如我们在之前的帖子中看到的,并非数据集中的所有点都位于训练好的模型上,可能有一些点靠近线但不在线上。在过拟合的情况下,直线会通过几乎所有的点,从而失去泛化能力。
欠拟合
不合身也不好。这是模型无法“适应”数据集的情况。换句话说,该模型未能从提供的数据中获得足够的信息。
这张来自 scikit-learn 网站的图说明了过度拟合和欠拟合会发生什么:
OVERFITTING AND UNDERFITTING (Scikit-Learn)
理解是什么导致了过度适应和欠适应是很重要的,但是我将在以后的其他文章中讨论这个问题。
测试模型
正如在上一篇文章中所讨论的,我们假设测试数据将来自与训练数据相同的分布。根据在美国获得的历史数据,这个模型很难对英国的事故做出预测。
训练数据和测试数据
从手头的数据来看,我们将它按一定的比例分割,这样大部分数据可用于训练,大约 70%和 30%。我们不在我们拥有的全部数据上训练,因为我们需要一些数据来测试模型的效率。由于测试数据需要来自同一个分布,最好从我们拥有的数据中进行分割。如果在训练阶段将测试数据暴露给模型,它可能会在那里学习一些示例,并总是正确地预测它们,从而挫败了泛化的预期目标。重要的是要确保模型不能访问测试数据,除非它已经过令人满意的训练。
现在,当我们的模型已经学习了与所有特征相关的权重时,我们可以传入新的样本,我们不知道的标签,并让我们的模型正确地预测它们!
以下是我们在本文中涉及的一些概念的列表:
- 感知器
- 线性分类器
- 判别边界
- 砝码
- 激活功能
- 感知器的训练
- 反向传播
- 虚拟变量/一个热编码
- 过度装配和装配不足
- 培训和测试数据
同样,这里涵盖的概念是淡化的版本。维基百科上关于感知器的文章很好地介绍了相关的数学和其他一些复杂的概念。我将推荐吴恩达在 Coursera 上的机器学习课程,以及深度学习课程,对这些主题进行深入的数学展望。
机器学习之旅
原文:https://towardsdatascience.com/https-medium-com-avikjain-journey-to-machine-learning-62105b2de077?source=collection_archive---------10-----------------------
你会让人工智能代表你做决定吗?—如果是的话,那么到什么程度,可能你的人生就靠它了。随着所有关于人工智能的讨论和对其监管的呼吁(显然人工智能有一天会杀死我们所有人),我一直在思考在什么情况下我们可能会从机器(称之为人工智能)那里拿走决策权。但是我们仍然(尽我们所能)利用它们——这并不像听起来那么疯狂,因为人类已经这样做了很多年。它无处不在,我们无法回避它会一直存在的事实。
Source — https://www.reddit.com/r/memes/comments/8s6wq1/terrifying_artificial_intelligence
从苹果个人助理 Siri 令人难以置信的友好声音,到《前玛奇纳》这样的电影,al 总是比任何其他东西都更让我兴奋。我不知道你怎么想,但是网飞可以根据你对以前看过的电影的反应来预测电影的推荐列表,这个想法听起来很吸引我。有一天,不知从哪里我在 Youtube 上看到了 Siraj Raval 的一个视频,他在视频中谈到了一个叫做#100DaysOfMLCode Challenge 的东西。这意味着在接下来的 100 天里,每天至少花一个小时来编码和学习机器学习。我强烈推荐看一下视频。
这正是我开始深入学习我一直关心的东西所需要的动力。所以我接受了这个挑战,开始学习机器学习。
从最基本的算法开始,用 Python 语言实现它们。
为了对我所学的一切有一个好的日志,我在 GitHub 上创建了一个知识库。我强烈建议你也这样做。随着我不断学习关于 ML 的新东西,我也用实现 ML 算法的代码和一些信息图更新了库,以便更好地理解。
Some of the Infographics
我收到的关于这个库的回应非常热烈,至少可以说,我没有预料到这一点。人们一直在社交媒体的各个角落支持我,这无疑让我感到谦卑,我想借此机会感谢所有为我付出宝贵时间的人。
Checkout My Repository
数字在这里无关紧要,因为我这样做不是为了名声或任何知名度。我这样做是因为我想这样做,我关心它,我相信我可以有所作为。
K — Nearest Neighbor Info graphic
综上所述,我认为我现在只是在学习,在这个快速变化和不断发展的世界里,我认为你永远不会真正完成学习。这只是一个很大的学习曲线。说实话,目的地还不在这里,我甚至还没有接近。但是我知道我的道路是正确的,我的思想集中在实现我渴望做的事情上。因此,我想挑战现在正在阅读这篇文章的每一个人,来加入我的旅程,参加#100DaysOfMlCode 挑战
,开始每天的工作。
如果你对人工智能领域不感兴趣,这不是问题也不是借口,找一些你关心的事情,一些感觉不像工作的事情,一些你可以奉献一生的事情。莱斯·布朗曾经说过,“要想在生活中取得任何有价值的成就,你必须要有饥饿感。”渴望成功,追随你的梦想,看着它们成为你的现实。
和我一起开始这段旅程,也许有一天我们会一起到达一个点,在那里我们可以实现我们的梦想,你知道去哪里。
从下面的链接关注我在#100DaysOfMLCode 上的工作—
GithubLinkedInTwitter网站
感知器:什么、为什么和如何
原文:https://towardsdatascience.com/https-medium-com-francesco-cicala-whats-whys-and-hows-of-perceptron-f87c66f512c5?source=collection_archive---------4-----------------------
如果有一天我们会告诉我们的曾孙们人工智能的故事,它也许应该从感知机开始。
生物学导论
神经元是一种电可兴奋细胞,通过电信号和化学信号接收、处理和传输信息。
Very simplified diagram of a neuron
信号通过连接神经元的轴突在神经元之间传播。这种连接发生在发射神经元的轴突末梢和接收神经元的树突之间,在一种称为突触的结构中。
当一个神经元处于静止状态时,即它没有接收到任何信号时,它会受到一个静止电位的影响,该电位平均在-70 毫伏左右,并且与神经元内外的电荷差有关。
当一个细胞发出电 脉冲时,一个与之相关的电位通过轴突传播。叫做动作电位。
The action potential propagates through the axon
最终,动作电位到达神经元,在那里,电压迅速变化。如果它的值大于某个阈值,所谓的触发过程被触发,包括从神经元本身发出信号。
不存在部分发放,即当电位达到阈值时,神经元发放一个强度与接收到的电信号无关的电信号。
Illustration of the electrical chemical signal crossing a synapse. (Andrii Vodolazhskyi via Shutterstock)
关于接收电信号的强度,要提两点:
1。当神经元接收到一个或多个信号时,它所经受的电位变化由所接收的动作电位的总和给出。
2.通常,从神经元 N3 接收的信号强度与从该神经元发送的信号强度不同:当通过轴突传播时,强度会根据覆盖轴突的髓鞘的厚度而变化。它越厚,信号的色散越小。
生物神经元的数学模型
我们可以用一个非常简单的数学模型来形式化这个过程。我们将为上一段中用粗体显示的每个术语分配一个变量:
- 神经元从 N 个不同细胞接收到的电脉冲由 N 维向量 x ,输入向量描述。
- 静止电位为 阈值 。如果接收到的动作电位之和达到阈值,神经元就会放电。我会用字母 b 表示阈值,有时候阈值叫做偏差。
- 携带电脉冲的轴突的髓鞘越厚,接收的强度越高。事实上,髓磷脂是一种绝缘体,它有助于电脉冲的传导,减少其向新神经元的扩散。乘法因子,代表覆盖连接两个神经元的轴突的髓鞘厚度,在我们的模型中由参数 w 表示,称为 权重 。如果我们考虑神经元在每个时间步长通过 N 个不同的轴突接收 N 个脉冲的模型,我们得到 N 个权重的向量, w 。
- 加权输入和偏置之和有时被称为感应局部场,我们将用字母 v 表示:
v=w∙x+b** - 神经元的输出表示激发信号的强度,用 y 表示。它是 v 的函数(T21 激活函数)
感知器的架构
概括一下:一个神经元接收一个 N 维输入 x ,用权重向量 w 加权。如果诱发的局部场,v=w∙x+b,等于或大于零,那么神经元发射一个固定强度的信号,我们说 1。否则,它不会,这意味着发射的强度为 0。
我们可以用一个简单的公式将其形式化,使用 Heaviside 阶跃函数θ作为激活函数:
我把 w 和 b 放在分号的右边,以区别于 x :其实前者是参数,后者是输入向量。
让我们用 Python 实现这个函数:
未完待续——深度学习药丸
这是关于深度学习系列文章的第一篇,我称之为 深度学习药丸 。在下一集里,我们将看到感知器能解决什么样的问题,它是如何学习的,以及它的局限性是什么。我将很快发表,敬请期待!
还有,可以随时在 Linkedin 和 Quora 上和我联系。
如果你喜欢这篇文章,我希望你会考虑鼓掌或评论:)
很快再见,弗兰克
认为机器学习和人工智能不会影响你的网络产品——再想想吧!
原文:https://towardsdatascience.com/https-medium-com-guruchahal-think-machine-learning-and-ai-wont-impact-your-networking-product-think-again-136e1ff39e79?source=collection_archive---------23-----------------------
使用 ML 和 AI 作为力量倍增器将是网络产品团队的重要竞争优势
Photo by Hitesh Choudhary on Unsplash
机器学习和相关技术在过去几年里取得了巨大的进步。虽然有时人们可能会觉得这个领域有很多宣传,但很明显,这些方法将对每个垂直领域的软件产生深远的影响,包括网络、存储、安全、软件开发等领域的产品。以下是 AI/ML 技术目前在网络产品中创造重大价值的几个领域:
模式识别
机器学习是识别网络流量模式的一个很好的工具,例如自动基线。负载平衡器或防火墙在处理流量时,可以使用 ML 算法来获取应用程序的每周/每月访问模式,并根据这些模式为数百个指标创建自动基线。这可用于性能分析以及获得安全见解。然后,开发运维团队可以进一步将其与 CI/CD 链结合起来,以实现更智能的蓝/绿部署。
异常检测
当流量流经网络时,ML/AI 技术可以在访问应用程序的方式中发现异常,然后实时吸引运营商对这些异常的注意。有了足够的信心,他们甚至可以采取缓解措施,如通过进一步的重型清理发送传入流量,例如通过 Web 应用程序防火墙。
网络最佳化
网络结构可以被建模为具有许多配置和运行时间变量的大型复杂系统,这些变量然后影响单个应用从网络获得的服务水平(QoS /性能)。人工智能可以随着时间的推移了解不同的配置参数、网络设计和流量模式如何影响网络服务。在此基础上,它可以提出改进服务质量的建议,就像网络架构师一样。例如,它可能会建议在两个交换机(以太信道)之间的中继上添加更多链路,添加更多交换机,或更改 BGP 权重以不同方式路由流量,等等。
下面是一篇关于谷歌如何利用 AI 优化数据中心的文章:https://deep mind . com/blog/deep mind-AI-reduces-Google-data-centre-cooling-bill-40/。来自文章:
“由于该算法是理解复杂动态的通用框架,我们计划将其应用于数据中心环境中的其他挑战”
我敢打赌,他们已经应用了类似的技术来优化网络服务。
转发路径简化
大多数网络产品本质上都是一个庞大的数据结构,与快速查找结合在一起。网络中 CRUD(创建/读取/更新/删除)操作的最佳数据结构通常是大规模快速查找索引。在过去的几十年里,这个领域已经有了大量的研究。
但是 ML 能帮助想出更好的方法来进行这些查找吗?也许使用神经网络作为散列函数?有一些有趣的论文将这一系列应用到数据库领域,但是毫无疑问,应用到网络领域也能带来重大突破…
顺便说一句,这里有一篇由蒂姆·菲利普·克拉斯卡(麻省理工学院)和亚历克斯·比特尔及其谷歌团队撰写的有趣论文:https://www.arxiv-vanity.com/papers/1712.01208v1/:
“…我们从这个前提出发,假设所有现有的索引结构都可以用其他类型的模型来代替,包括深度学习模型,我们称之为学习索引…”,
“…通过使用神经网络,我们能够在速度上超过缓存优化的 B 树高达 70%,同时与几个真实世界的数据集相比节省一个数量级的内存…通过学习模型替换数据管理系统的核心组件对未来的系统设计具有深远的影响…”
由于 ML/AI 的应用,这些只是跨堆栈、有线和无线、L2/L3 和应用层的网络产品实现“超能力”的几种方式。然而,并不是每个产品都能实现这种转变。为不同时代设计的产品通常处理能力不足,很少或没有遥测功能,这意味着它们既不能收集所需的数据,也不能处理数据以获得见解。真正创新的产品将来自对传统网络产品的自下而上的重新设计,这样,该体系结构支持大规模的数据收集和数据分析。能够做到这一点的产品和平台将为自己在市场上创造显著而持久的竞争优势——尤其是在设计时考虑了网络效应。
我期待着这一领域的持续创新——激动人心的时代!
然而,并不是每个产品都能实现这种转变。为不同时代设计的产品通常处理能力不足,很少或没有遥测功能,这意味着它们既不能收集所需的数据,也不能处理数据以获得见解。
网络抓取是如何通过它的应用改变世界的
原文:https://towardsdatascience.com/https-medium-com-hiren787-patel-web-scraping-applications-a6f370d316f4?source=collection_archive---------7-----------------------
猜猜看,设想新公司的企业家、财富 500 强公司的首席执行官、股票分析师、营销人员和记者之间有什么共同点?
嗯,他们都是从数据中得出自己的策略和见解的!
数据是新的竞争优势。
它是市场研究和商业战略的核心。
无论您是想开始一个新项目,还是想为现有业务制定一个新战略,您都需要访问和分析大量数据。这就是网络抓取的用武之地。
你可能会认为网络抓取对一两个特定的行业有用。它与不同的行业有什么关系?
别担心!
我们收集了不同行业中网络抓取应用的完整列表。
然而,在我们深入研究之前,让我们先快速了解一下网络抓取。
什么是网页抓取?
比方说,数据对你的电商公司至关重要。你可以在竞争对手的网站上看到这些数据。
问题是你如何以一种可用的格式下载它?
大多数人只能手动复制和粘贴它。但是对于几百页的大型网站来说,这样做是不可行的。
这就是网络抓取发挥作用的地方。
网页抓取是一个高效快速地自动提取数据的过程。在网络抓取的帮助下,你可以在你的电脑上从任何网站提取数据,不管数据有多大。
此外,网站可能有你不能复制和粘贴的数据。网络抓取可以帮助你提取任何你想要的数据。
这还不够。比方说,你复制并粘贴了一些数据,但如何转换或保存成你选择的格式?
网络抓取也能解决这个问题。当您在网络抓取的帮助下提取网络数据时,您将能够以 CSV 等格式保存数据。然后,您将能够以您想要的方式检索、分析和使用数据。
因此,web scraping 简化了提取数据的过程,通过自动化加快了提取速度,并通过以 CSV 格式提供废弃数据来创建对废弃数据的轻松访问。
简而言之,网络抓取省去了你手动下载或复制任何数据的麻烦,并使整个过程自动化。
以下是网页抓取应用列表:
零售和制造业中的网页抓取应用:
Photo by Roberto Cortese on Unsplash
在这一部分中有许多网页抓取的应用,这些应用可以细分为以下不同的类别:
竞争对手价格监控
- 在这个电子商务时代,价格起着关键作用。你需要跟踪竞争对手的定价策略。
- 然而,手动跟踪价格并不是一个可行的选择。此外,价格时不时会发生变化。因此,手动跟踪价格几乎是不可能的。
- 这就是网络抓取的用武之地。它自动化了获取竞争对手价格的过程,并让您了解竞争对手部署的新定价策略。网络抓取可以在任何时间内完成,次数不限。
监控地图合规性
- 制造商需要密切关注零售商是否遵守最低价格。
- 然而,不可能访问每个网站并检查相同的内容。网络抓取在这里拯救了他们。
- 在网络抓取的帮助下,制造商可以轻松有效地监控地图符合性。他们不需要花费大量的时间就可以做到,因为网络抓取可以以闪电般的速度产生这些数据。
获取图像和产品描述
- 从不同的制造商手动获取图像和产品描述将是一场磨难。
- 网络抓取可以让这变得很容易。它使整个过程自动化,并立即提供图像和产品描述。
监测消费者情绪
- 有必要对消费者情绪进行跟踪分析。它是通过审查消费者的反馈和不同企业的评论来完成的。
- 然而,手动获取不同网站的所有评论是不可行的。
- 因此,网页抓取被用来使它变得非常简单。通过网络抓取,你可以在一个电子表格上获得所有的评论,甚至可以根据关键词比较不同的评论。
股票和金融研究中的网络抓取应用
Photo by M. B. M. on Unsplash
这是一个广阔的领域,网络抓取的应用令人难以置信。看一看:
综合新闻文章
- 在金融和保险领域,新闻是洞察力的重要来源。但是,不可能手动阅读每一份报纸和每一篇文章。
- 因此,网络抓取被用于从不同的新闻故事、标题等中提取有价值的输入。将它们转化为可操作的投资见解。
市场数据汇总
- 虽然互联网上有很多市场数据,但它们分散在成千上万个网站上。
- 你可以搜索和浏览搜索结果,但这太费时间和繁琐。
- 网络抓取用于从不同的网站抓取数据,并从这些网站收集关于股票研究的可操作的情报。
提取财务报表
- 分析师需要财务报表来确定一家公司的健康状况,并就是否投资该公司向客户提出建议。
- 然而,手动获取数家公司多年的财务报表是不可能的。
- 网络抓取工具用于从不同网站提取不同时间段的财务报表,以供进一步分析,并基于此做出投资决策。
保险
- 越来越多的趋势是研究替代数据以确定风险等。保险公司设计他们的产品和政策。
- 但是他们不可能通过手动复制或存储来利用这些数据。
- 因此,保险公司利用网络搜集来搜集替代数据,并做出关于保险产品和政策的决策。
数据科学中的网络抓取应用
Photo by Franki Chamaki on Unsplash
实时分析
- 实时分析简单地说就是在数据可用后立即进行分析。它不同于批处理式分析,因为批处理式分析可能需要数小时或延迟来处理数据和产生见解。
- 相比之下,实时分析可以毫无延迟地产生见解。
- 金融机构使用实时分析进行信用评分,以决定是否延长信贷或停止信贷。
- 客户关系管理(CRM)是如何利用实时分析来优化客户满意度和提高业务成效的一个显著例子。
- 实时分析也用于销售点,以便检测任何类型的欺诈。在零售商店中,在激励等方面处理个人客户时,实时分析开始发挥作用。
- 正如每个示例所示,实时分析依赖于处理大量数据。当且仅当大量数据能够被非常快速地处理时,实时分析也能以一种无障碍的方式工作。
- 这就是网络抓取派上用场的地方。如果不能快速访问、提取和分析数据,就不可能进行实时分析。
预测分析
- 预测分析是分析现有数据的过程,目的是找出模式并预测未来的结果或趋势。预测分析不能准确预测未来,但它是关于预测可能性的。
- 除了其他领域,预测分析在商业领域也有应用。预测分析用于研究和了解客户行为、产品和各种其他事物,以计算出风险和机会。
- 然而,显而易见,这是一种基于大量现有数据的分析。
- 这就是为什么网络抓取变得越来越重要,因为它可以提取和提供大量的数据,这些数据以后可以用于预测分析。换句话说,网络抓取对于预测分析是至关重要的。
自然语言处理
- 自然语言处理是使机器能够解释人类使用的自然语言的过程,这不同于诸如 Python 等计算机语言。
- 情感分析是自然语言处理的一个显著用例。数据科学家使用社交媒体上的评论来处理和评估特定品牌的表现。
- 顾名思义,机器需要访问大量数据,NLP 的任何应用程序才能工作。
- Web 抓取是少数几种有效的方式之一,可以抓取与社交媒体评论或其他任何可用格式相关的数据。因此,随着自然语言处理的重要性日益增加,网页抓取也变得越来越重要。
机器学习训练模型
- 机器学习基本上意味着我们向机器提供数据,让它们自己学习和改进,而不必使用任何显式编程。
- 网络是这类数据的理想来源。通过训练机器学习模型,我们可以让它们执行不同的任务,如分类、聚类、属性等。
- 然而,只有当高质量的数据可用时,机器学习模型才能被训练。Web 抓取用于提取这些数据并使其可用于机器学习训练模型。
风险管理中的网络抓取应用
Image by mohamed Hassan from Pixabay
- 在商业中,当你雇佣员工或与新客户打交道时,会有一些风险。人们不能忽视风险而没有任何风险管理策略。
- 因此,企业通常会对新员工、客户或顾客进行背景调查。然而,考虑到这意味着检查几个不同的数据来源,如新闻报道和新闻文章、制裁名单、公司登记册、法律数据库、被取消资格的董事名单、破产登记册、财务登记册和许多其他资料,这可能是一项耗时而乏味的工作。
- 任何个人都不可能手动完成背景调查。因此,利用网络抓取工具从上述来源快速提取数据并进行处理,以完成背景检查。
产品、营销和销售中的网络抓取应用
Photo by Campaign Creators on Unsplash
数据驱动的营销
- 数据对于任何营销和销售工作都是必不可少的。这没什么新鲜的。然而,获取数据有时是区分两个营销者的东西。网络搜集可以使数据可用于制定策略。
内容营销
- 当谈到内容营销时,网络抓取用于整理来自不同网站的数据,如 Twitter、Tech Crunch 等。然后,这些数据可以用于创建引人入胜的内容。如你所知,吸引人的内容是业务增长和网络流量的关键。
线索挖掘
- 就潜在客户的产生而言,许多公司不得不花费大量资金来获得海外潜在客户。这可能会花掉你一大笔预算。取而代之的是,网络抓取现在被用来直接从不同的来源抓取数据并产生线索。
- 通过这种方式,可以以较低的成本产生高质量的销售线索,并且可以将预算用于其他重要的事情。
竞争分析
- 说到竞争分析,很难从不同的网站获取你需要的所有数据,以便对你的竞争对手进行比较和了解。
- 手动执行不仅耗时,而且效率低下,因为您可能无法准确获取数据。在这个充满竞争的世界里,速度和准确性就是一切。
- 相反,网络抓取现在已经改变了这个领域,并通过快速获取数据和促进竞争分析提供了一个更有效的替代方案。以这种方式,网络搜集被用于自动化数据提取和竞争分析。
搜索引擎优化监控
- 嗯,搜索引擎告诉我们很多关于商业世界是如何运动的。内容如何在排名中上下移动也是一个人如何在这个互联网时代茁壮成长的关键。
- 人们可以研究内容在互联网上的工作方式,并从中获得见解和策略。
- 但是,手动无法完成。因此,越来越多地使用网络抓取工具来抓取关于搜索引擎幕后发生的事情的数据。网络抓取可以增强你对搜索引擎优化内容的理解,并为搜索引擎优化提供可操作的情报。
信誉监控
- 了解顾客对你和你的品牌的感受是至关重要的。你可以有一个模糊的想法,但提供一个基于数据的帐户可能是困难的。
- 然而,网络抓取工具已经变得如此复杂,以至于它们现在能够立即从网站上提取客户评论和其他输入,并且非常容易地促进品牌或声誉监控。一些公司使用网络抓取来了解客户的观点并更好地为他们服务。
其他使用网页抓取的行业
很难列出所有可以利用网络抓取的东西,因为它的应用现在正被用于几乎所有已知的人类交易。无论是慈善事业还是新闻业,网络抓取都可以做出实质性的贡献。这里有一些其他的行业或领域,网络抓取已经找到了它的应用。
新闻和声誉监控
- 为了跟踪有关个人、产品或公司的信息,新闻搜集是非常有用的。
- 网络抓取是这一过程中不可或缺的一部分,因为它可以快速有效地从不同来源的新闻中提取数据。
- 然后可以处理这些数据,以便根据需要收集见解。因此,它还可以跟踪一家公司的品牌和声誉。
学术的
- 学术界很大程度上依赖于数据。学术工作主要围绕着这样或那样的信息。
- 无论是教学任务还是研究项目,学者们都必须掌握数据,然后对其进行处理,以得出必要的见解。
- 网络搜集现在使得他们提取和处理他们需要的数据变得极其容易。
数据新闻
- 顾名思义,这是一种使用数据支持新闻故事的新闻业。
- 信息图或图表的使用是如何将数据编织到这些故事中的典型例子。
- 数据之所以对他们如此重要,是因为数据为故事中的论点和主张提供了可信度。
- 它也是有用的,因为它使读者能够以可视化的方式理解复杂的主题。
- 网络抓取在这里很方便,因为它首先使数据可用,并使记者能够通过创造性地使用数据来产生影响。
非营利组织
即使在非营利组织的情况下,他们也需要数据来确定他们的使命和推进他们的工作。网络抓取工具可以很容易地提取他们需要的数据,以计算出他们的目标和结果,这样他们就可以在他们崇高的项目中前进。
雇用
- 你有没有注意到的求职公告栏上满是与职位相关的数据?你有没有想过数据是从哪里来的?
- 工作公告板使用爬虫抓取不同的网站,抓取关于新的工作发布的信息。职务公告板收集诸如职务公告、公司简介、职务说明和员工简介等信息。
- 这使他们能够提供有关职位发布的信息,并将求职者与雇主联系起来。网络抓取使这一切成为可能!
分类网站的搜索引擎
- 有一些网站充当汽车分类广告的搜索引擎。访问者可以在网站上搜索具体的汽车品牌和型号。
- 但是,不可能手动获取此类数据。利用网络抓取工具来抓取和提取不同车辆的技术规格。
- 这些数据随后会在网站上供访问者搜索和访问。
结论:
随着互联网的飞速发展,企业越来越依赖于数据,获取每个特定主题的最新数据已经成为一种必然。
无论是企业还是非营利组织,数据都已成为所有决策过程的基础。因此,在当代,网络抓取在每一个值得注意的领域都有应用。
越来越明显的是,那些将创造性地和先进地使用网络抓取工具的人将会领先于其他人并获得竞争优势。
因此,利用网络抓取,在你选择的努力领域提升你的前景!
是什么推高了利率?
原文:https://towardsdatascience.com/https-medium-com-hisham-hawara-what-drives-up-loan-interest-rates-45c778baafc2?source=collection_archive---------12-----------------------
利率是一种极其强大的金融工具;一方面,它们有创造机会和促进增长的潜力,但另一方面,它们也可能造成沉重的债务、数万亿美元的泡沫,并摧毁它们本应服务的经济体。
但是为什么贷款利率会有如此巨大的差异呢?真正的潜在因素是什么?让我们利用数据科学的力量来探索 Lending Club(美国最大的贷款人)—贷款数据集,以找到满意的答案。
[## Lending Club 贷款数据
分析 Lending Club 发放的贷款
www.kaggle.com](https://www.kaggle.com/wendykan/lending-club-loan-data)
贷款金额:
不出所料,随着贷款规模的增加,贷款利率也会上升,以适应与贷款相关的风险增加。然而,我们注意到低利率和中低贷款利率相对相同。
期限:
这张图表清楚地表明,期限越长,利率越高。这可能与短期贷款通常涉及较小的贷款金额这一事实直接相关。
等级:
为了解释贷款等级的含义,这里有一段瑞恩·高斯林在《大空头》中解释贷款等级及其区别的片段:
The Big Short — (2015)
简单来说,贷款等级是一个公式的结果,它不仅考虑了信用评分,还考虑了来自信用报告和贷款申请的几个信用风险指标的组合。A 的风险最小,G 的风险最大。因此,我们可以理解为什么 A 级贷款的利率最低,而 G 级贷款的利率最高。
目的:
这张图表具体显示了贷款的目的如何影响其利率。小企业有最高的利率,这可能是因为他们失败和取消贷款的几率最高。另一方面,信用卡的利率最低。
房屋所有权:
与其他住房来源相比,自有住房对贷款利率的影响很小。然而,没有住宿来源增加了兴趣。不出所料,成为沙发冲浪者或无家可归者会大幅提高利率。
很明显,贷款利率是由非常复杂的系统估算的,这些年来,这些系统不断发展,以尽量降低为金融机构提供贷款的风险。然而,这些系统仍然不是最佳的,并且在将来仍然可以添加许多新的因素来改进它们。既然我们已经用数据科学的力量回答了我们的问题,也许我们也可以用它来发现这些因素是什么!
如何实现你的想法的全部潜力?
原文:https://towardsdatascience.com/https-medium-com-how-to-realize-the-full-potential-of-your-ideas-f2105029ee05?source=collection_archive---------10-----------------------
这个想法会带你去月球。还是注定永远离不开发射台?知道一个想法是好是坏真的很难。但是,不要绝望!有了合适的工具,你就能实现你想法的全部潜力。
早期的挫折
我自己的想法冒险始于我读博士的时候。我发现我天生有很多想法,问题是它们大多都很糟糕。更糟糕的是,我花了很长时间才发现每个想法有多糟糕。结果,在最终意识到这些想法都是无用的之前,我花了几个月的时间跟踪它们。
当我最终完成博士学位并加入英国政府时,我发现情况大同小异。在这两个地方,我都在寻找辨别哪些想法是有成效的,哪些想法是垃圾的方法。
Some ideas are easier to are easier to discern than others!
原来不只是我!其他每个人似乎都同样绝望。在学术界,我看到人们追求早已不可信的观点。在政府中,我看到人们建立没人想要的系统。
我的大主意
我的职业生涯即将彻底改变。我有一个想法,一个我坚信会改变我工作的行业的想法。这很疯狂,很奇怪,我想这可能只是关于工作。
我开始和每一个愿意倾听的人交谈。这个想法不断发展壮大,但我仍然无法获得资助。9 个月后,我打算放弃它。我还有一次会议,一个朋友推荐我和里奇·波特坐下来谈,他负责一个内部孵化器项目。
我与 Rich he 的第一次会面就立刻喜欢上了这个想法,并暂时接受我进入孵化器流程,解释说在向高级利益相关者进行最终推介之前,我将有 6 周的时间来建立我的案例。他还向我介绍了一个叫做精益的概念,并推荐我读一本由 Eric Ries 写的叫做精益创业的书。我在周末如饥似渴地阅读了这本书,我的职业生涯从此改变。
“精益方法”
The Build-Measure-Learning Cycle. (used courtesy of JODY OWEN)
这本书解释了颠覆传统模式的“精益方法”。本质上,无论你认为什么,都是最有可能让你的想法落空的事情,先去检验它。然后找出一个度量标准来衡量你的测试是通过还是失败。然后构建最小最简单的东西来获取测试数据。这就是所谓的构建-测量-学习循环。
我现在有了测试我的想法的框架,也有了我的训练场——孵化器——在这里我可以学习精益所能提供的一切。
测试,测试,更多的测试
在“鲨鱼池”式的资源推介之前,我有 6 周时间,所以我需要快速行动。我发现精益的早期先驱之一史蒂夫·布兰克(Steve Blank)会在这个小组里(大口)。
运用精益,我完全适应了我处理问题的方式。我查看了我收到的所有批评,以及我自己对什么可能扼杀这个项目的担忧,并开始对它们进行排序,将风险最大的假设放在列表的首位。
然后我开始做实验。目的是了解这些假设是否可以被测试并失败,这样我就可以改变想法或者完全放弃它。
一个示例实验
这是我的一个实验的例子,然而,它是我从事的许多早期实验的特征。
当时,该项目的最大风险之一是项目完成后,工程部门不会支持该平台。这是过去我和其他人的许多项目的结尾。因此,我想先设计一个实验来验证这一点:
- 假设/断言(学习):工程愿意在平台建成后支持它。
- 测试(衡量):如果孵化器成功支持平台,工程总监是否会书面承诺。
- 实验(构建):与工程总监会面,解释工作的规模和潜在价值,并要求书面承诺。
测试是成功的,工程总监承诺支持该项目。端到端实验进行了两周。而不是花 6 个月来构建一个因为不支持而失败的系统。
精益的最大挑战
建筑很有趣。我喜欢写代码。我喜欢新技术和工具。然而,精益迫使我遵守纪律,做出短期牺牲,以获得长期影响。
我经常会想到,在早期阶段,我一行代码都没写。例如,如果我需要了解用户界面应该是什么样子,我会在纸上敲出一个给目标用户看,而不是花几天时间去构建一个复杂的(尽管令人满意的)界面。这样,我可以在几个小时而不是几周内迭代构建-测量-学习周期。
精益的真正秘密不仅在于它能帮助你构建人们想要的东西,还在于它能帮助你在拥有一个笨拙而不灵活的 10000 多行代码库之前尽早转向。
使用精益时面临的另一个不太明显的挑战是“围攻心态”和人们对自己想法的防御性。当我们的想法失败时,我们(我)倾向于把它当成个人的。我们变成了保护性的、令人窒息的实验,而不是测试最危险的断言,我们测试那些可能验证我们想法的断言。
精益是一项团队运动
在成功获得资金和召集我的团队后,我们开始了为期六个月的旅程,以测试这个想法的极限。我们团队的文化令人惊叹。由于早期的测试,有一个强有力的愿景和一组清晰的假设需要测试。
我们经常每天开两次会,一次在早上,一次在午饭后。在每个环节中,我们都将完成构建-测量-学习循环。
这个项目取得了巨大的成功,可以说是迄今为止我职业生涯中最有影响力的事情。
前进
对我来说,利用精益来构思想法是我加入一家小型早期创业公司黑曜石安全的关键激励因素之一(如果你有兴趣了解更多关于我的黑曜石之旅,请阅读坚持下降)。你会不断听到我们的产品负责人试图让我们“闭环”。他这么说的意思是,关注尽可能快地到达构建-测量-学习周期的末端。
当整个公司都在实践精益时,其产生的速度是令人难以置信的。
应用
孵化器对我来说是一个很好的训练场。我拥有快速开发的所有关键要素:优秀的队友、出色的导师和一个要测试的好主意。这三样东西不一定都能拥有,但是,如果你想开始学习精益,我推荐以下几点:
- 找一个很棒的导师。我很幸运拥有里奇,并和绝地大师—史蒂夫·布兰克共度时光。
- 对自己的观点和动机持怀疑态度。一个想法或假设的失败是前进而不是后退。
- 让你的队友站在一边,精益最好作为一个团队来完成。
- 开始阅读。Eric Ries 的精益创业公司是一个很好的起点。
- 有一个想法要测试,它不一定要改变世界,但你可以测试的东西是关键。精益非常实用。
- 找到那些最有可能扼杀你想法的方面,先测试一下。
- 不要太“元”,一般来说,当我看到精益出错时,是因为人们最终测试了所有东西,包括现实的结构。保持它的实用性和范围。
- 享受乐趣,我们大多数人做我们所做的事情是因为我们想对世界产生影响,在我看来,精益是实现这一目标的最佳机制之一。
如果您有任何问题,请联系。如果你想在建立一个了不起的公司的同时学习精益,我们正在招聘!
祝你好运,我希望精益对你的生活产生和对我一样大的影响!
我们是如何从零开始组织黑客马拉松的
原文:https://towardsdatascience.com/https-medium-com-hugoperrier-how-we-organized-a-hackathon-from-scratch-75ef5d2c2780?source=collection_archive---------7-----------------------
Photo by rawpixel on Unsplash
通过这篇文章,我旨在揭开黑客马拉松的神秘面纱,降低任何考虑组织黑客马拉松的人的门槛。
我描述的黑客马拉松专注于“数据科学”这个时髦的话题,但是,在我看来,黑客马拉松并不局限于数据或计算机科学。
我鼓励任何人加入黑客马拉松冒险,不管他们的背景如何。
什么是黑客马拉松?
黑客马拉松这个词是“黑客”和“马拉松”的缩写。“hack”可能用于入侵计算机系统的意思,但我更喜欢寻找快速解决方案(“Hack”)来解决特定问题的广义含义。
这个想法是把有积极性的人聚集起来,组成团队,给他们一个挑战,让他们在短时间内(通常是一天或一个周末)解决,然后让奇迹发生!
例子从技术任务——比如发现安全系统的漏洞——到公开挑战——比如就如何改善伦敦人的通勤状况进行头脑风暴。
这一切是如何开始的…
11 月 29 日星期三收到的电子邮件
“亲爱的雨果
我目前在伦敦帝国理工学院攻读理学硕士学位,我很好奇你们协会是否会组织一次与数据科学相关的黑客马拉松?
最好的,
SK "
有意思…我们去年想组织一次黑客马拉松,但没有实现…我们应该再试一次吗?
是的,我就是这样开始的!但在我描述我的黑客马拉松组织之旅之前,让我自我介绍一下:
我叫雨果·巴黎水,我在法国阿尔卑斯山长大。在洛桑、斯德哥尔摩和苏黎世学习后,我最终去了伦敦攻读流体动力学博士学位。
那时,我对“类似黑客马拉松”活动的体验仅限于巴厘岛的“创业周末”,我在那里度过了一个周末,启动了一个商业想法。
我必须说,起初,组织一次黑客马拉松对我来说听起来很吓人。如果参与者不喜欢提出的挑战怎么办?如果没人出现呢?
我早期的审讯
Photo by Kyle Simmons on Unsplash
黑客马拉松形式
黑客马拉松的一种普遍形式如下:
周五晚上与你的团队见面,整个周末工作,周日下午向评委展示。
三天一个活动挺长的!我们能在整个周末保持参与者的积极性吗?如果人们在周五晚上退出怎么办?是不是太贵了?
挑战的类型
数据科学竞赛并不新鲜。有了在线平台 Kaggle,竞争对手被给予解决同样的问题,并且有一个明确的量化指标来对参与者进行排名。
Kaggle 式的挑战便于组织和判断,但是它们技术性太强,与大多数企业面临的挑战相去甚远。
我们的目标受众是多样化的,包括有商业背景的学生。为了取悦所有人,我们正在考虑更多的开放式挑战。向参与者提供与业务相关的数据,并让他们决定他们想用这些数据做什么。
据我所知,这种类型的挑战在数据科学领域并不常见。我们有能力组织一场新型的黑客马拉松吗?
组建团队并开始行动
组织黑客马拉松听起来工作量很大,我肯定需要一个团队来帮助我。我的第一个想法是与我担任副主席的学生社团讨论黑客马拉松。我来介绍一下 ICDSS。
帝国学院数据科学学会
该协会拥有庞大的会员基础、高效的沟通渠道(邮件列表、社交媒体)、赞助商网络和在校园组织活动的经验。但是有一个问题…大多数委员会成员已经忙于其他 ICDSS 活动和考试。
所以我们在这里,与 SK(来自电子邮件),SL(ICDSS 的营销主管)和我在一起。这是一个开始,但可能还不够。
我想我们需要帮助!!
研究生会(GSU)
1 月 10 日星期三收到的电子邮件
“亲爱的研究生们:
研究生会(GSU)是伦敦帝国理工学院所有研究生的唯一代表。
[…]
大数据黑客马拉松
我们已经和几个横跨不同行业的大公司取得了联系(有待透露)。公司会提供与大数据相关的问题来解决。学生组成多学科团队,竞争最佳解决方案。
日期:2018 年 4 月 28 日
[…]
GSU 总统”
哇!!这是及时的!研究生会(GSU)也提出了同样的想法。我不认识那里的任何人,但他们似乎在我们前面,让我们试着联系一下!
与 GSU 会谈的要点
- 名称:大数据黑客马拉松——帝国理工学院数据挑战赛——数据日——等。
- 目标受众:我们应该只招收研究生还是包括本科生?
- 预期人数:约 80 名学生,6-8 家公司提供挑战(目前已确定 3 家),从每家公司获得 2 名助手。
- 财务:通过要求参与公司出资来支付费用(500 英镑/公司)。如有必要,使用社会资金。
- 场地:使用大学基础设施(待定)。
- 营销:社团的邮件列表和社交媒体、传单、校园屏幕等(我们需要更多,让我们发挥创意!).
- 参与者报名 : Eventbrite?谷歌表单?(待讨论)
- 日期:仍未确认,有与复活节假期冲突的风险。
太好了!GSU 团队非常友好,他们乐于合作。仍然有许多工作要做,但是,现在,我们已经有足够的人员和路线图可以遵循。当务之急之一是找到提供挑战的公司!这被证明是最困难的部分之一。
The IC Data Challenge organizers
寻找参与黑客马拉松的公司
我们正在组织首届 IC 数据挑战赛(没错,这就是我们选择的名称)。没有人听说过我们,挑战的形式仍然不确定,在这一点上,我们召集 70 名学生的能力是不确定的。
尽管我们自己也有疑问,但我们需要让公司相信黑客马拉松正在发生,他们将从中受益。
我们如何说服公司加入冒险?!
简单的答案是招聘。黑客马拉松是学生和公司员工互动的特权环境。公司有机会向顶尖大学的学生深入展示他们的业务。
起初,联系公司的任务令人沮丧:发送冷冰冰的电子邮件,得不到回应,面对管理上的死胡同。即使我们得到了积极的回应,也需要做大量的工作来保持沟通。有时,我们还需要适应公司的特定需求。
“嘿 SK,
谢谢你伸出援手。
我们通常不赞助黑客马拉松。有没有一本所有学生都参与的简历书?这样,我们可以审查并决定这是否是我们想要考虑的事情。
最好的,
X 公司"
一本履历书!真的吗?那个特别的回答很吓人!
获得第一个积极的回应需要奉献和毅力。几周后,我们获得了一家大公司(一家提供食品的公司)的参与,团队士气大增。在接下来的几周里,又有一些公司加入了黑客马拉松,干得好,伙计们!
说服学生参与黑客马拉松
如果你和我一样,你参加过一些活动,比如聚会、会议、培训等,由于定向广告,你现在淹没在活动邀请的海洋中。
由 DeepMind 的联合创始人主演的关于人工智能未来的演讲?哇,我一定要注册!
如果你像我一样,你也会中途退出你报名参加的活动。一天只有 24 小时,我们都需要睡眠。
这正是我们在大学组织的活动所发生的事情。根据我们的经验,参加活动的人数大约是注册人数的三分之一。我们怎样才能保证参与者的正确数量?
我不会用我们采取的策略的细节来烦你,但我想给你一个遇到的挑战的提示。
营销材料设计
说到广告,一个很酷的 logo 和一张精美的宣传单能帮上大忙!幸运的是,ICDSS 的委员会中有熟练的设计师。我敢打赌,我们很快就会得到高质量的营销材料!
3 月 30 日星期五在时差收到的消息
“嗨,团队,
对此我深表歉意,但不幸的是,我的公寓两天前遭到了搜查。
我们很多贵重物品被偷了,包括我的笔记本电脑。警方的法医小组来做了犯罪调查。在我的新笔记本电脑到来之前,我无能为力。
幸运的是,我把所有东西都存到了 Dropbox,所以文件应该还在。
祝你好运,
SL(ICDSS 营销主管)"
听到 SL 被搜查的消息很难过…但他还是设法把文件保存在了 Dropbox 上。这家伙是个英雄!
Advertisement flyer for the IC Data Challenge designed by SL
我们的广告策略非常有效,我们记录了 300 份 IC 数据挑战申请!
还有许多其他与组织黑客马拉松相关的话题。活动后勤,组成(平衡的)团队,给公司分配团队,评判(陪审团,标准),奖励等等…
为了简洁起见,我将跳过这些话题,直接跳到黑客马拉松那天。如果你想知道更多,请随时留下你的评论。
帝国理工学院数据挑战 2018
黑客马拉松终于要开始了,我们需要解决最后一分钟的事态发展:公共交通中断,一名学生不请自来,Wi-Fi 问题。上午 8:00,我们准备启动活动!我们首先介绍公司和面临的挑战。
IC Data Challenge participants listening to the company presentations.
创建算法来预测公共交通延误。分析足球比赛中进球或黄牌等事件如何影响赔率。调查各种餐馆的食物菜单,并对推荐的食物进行分类。提出的挑战范围很广。
IC Data Challenge participants getting insight from their assigned industry supervisor.
在 12 个小时里,这些挑战让参与者忙个不停。挑战是激烈的,但参与者得到了公司主管的帮助。一些团队太专注于他们的挑战,以至于错过了食物休息时间!
IC 数据挑战赛是一项竞赛,因此每个团队都要向评审团展示自己的作品。最佳技术演示和最佳商业演示获得了两项现金奖。
Team who won the best business presentation prize (500£).
参与者、行业帮手、评委、组织者,一天下来,我们都显得筋疲力尽。为了放松和结束忙碌的一天,我们邀请大家去大学酒吧喝一杯。
参与者的反馈
“我以前从未参加过黑客马拉松。在一个多学科团队中工作对我来说是新鲜的,但这非常刺激。
DM(集成电路数据挑战参与者)”
花一整天的时间和团队一起完成一项挑战,是结交新朋友的好方法。参与者喜欢团队合作,也有机会认识不同背景的人。
学术界和公司之间有一条鸿沟。对于学生来说,黑客马拉松是一个接触行业问题和增长商业意识的绝佳机会。他们也有机会为将来找工作发展有价值的技能。
尽管有很多积极的反馈,但最后一刻披露的挑战让一些参与者感到措手不及。一名学生提到,如果提前几天通知,他本可以熟悉相关技术。对于未来的活动,尽管有退出的风险,我们应该尽早让参与者了解挑战。
来自公司的反馈
对公司来说,提出挑战并不容易,尤其是对初创公司。他们中的大多数人以前从未参加过黑客马拉松。他们必须收集、清理和匿名化挑战所需的数据。这些任务需要付出巨大的努力。他们还必须就挑战的复杂性集思广益,是不是太容易了?太用力了?太具体了?太开放?
不过,我们从公司得到的反馈令人鼓舞。他们珍惜与各种学生交流的机会。如果一些参与者在黑客马拉松后被雇佣,我不会感到惊讶!
所有的公司都说他们愿意参加我们组织的下一次黑客马拉松!
总结一下…
组织一次黑客马拉松是一次令人生畏的经历,有时令人沮丧,而且常常令人不安。然而,整个过程也真的令人兴奋,最终,非常值得!
我相信,由于我们学到的教训,下一届帝国理工学院数据挑战赛将会更好,我希望我的故事能激励其他人继续前进,规划丰富的活动。
承认
非常感谢所有的黑客马拉松组织团队,GSU 和 ICDSS。你做了出色的工作,使这次活动成为可能!
公司和参与者都表现出极大的热情,这使得活动非常愉快。这是我能期待的最好的回报!
我也很感谢给我反馈帮助我写这篇文章的人。欢迎在评论区提出更多的批评、建议和问题。
将吴恩达第一深度神经网络应用于泰坦尼克号生存数据集
原文:https://towardsdatascience.com/https-medium-com-janzawadzki-applying-andrew-ngs-1st-deep-neural-network-on-the-titanic-survival-data-set-b77edbc83816?source=collection_archive---------0-----------------------
你被吴恩达第一个关于深度学习的 Coursera 课程震惊了,甚至可能在一周内就把它吃光了。我们都是!但是,在将新获得的知识应用到新的数据集之前,请控制您急切的手指不要跳到第二道菜。
Utilize Andrew Ng’s Deep Learning course to predict Titanic Survival rates
这篇文章介绍了神经网络在 kaggle 的泰坦尼克号生存数据中的应用。它帮助读者加深对神经网络的理解,而不是简单地执行吴恩达精心安排的代码。泰坦尼克号的生存数据集只是一个例子。请随意使用您喜欢的任何其他二元分类数据集!
代码在 Github repo 这里。现在让我们开始享受乐趣吧。
- 从 Coursera hub 下载“深度神经网络应用”和“dnn_utils_v2.py”文件并保存在本地
- Github repo 不包含 deeplearning.ai 提供的代码,请报名参加 Coursera 深度学习专业化的课程 1。所需材料在第四周的编程作业中。
Download the “Deep Neural network Application v3” notebook from the Coursera hub and click on “Open”
Download the dnn_app_utils_v2.py file
2。从 kaggle 下载 泰坦尼克号生存数据集 并将其保存在“数据集”文件夹中与您的笔记本相同的位置
- 为了方便起见,我已经在 Github repo 中包含了数据集
3。打开“深度神经网络应用”笔记本
- 除了 import 和 L-Layer_model 单元格之外,您可以安全地删除所有其他单元格
- 运行两个单元
4。加载泰坦尼克号生存数据集
5。预处理数据集
- 基于阶层估算乘客年龄——这是何塞·波尔蒂利亚极力推荐的 Udemy 课程“Python 用于数据科学和机器学习训练营”,逻辑回归的一个分支
- 从姓名中提取乘客头衔——我跟随了 Manuel 关于从姓名中提取头衔的伟大而简单的帖子,感谢分享!
- 删除列 passengerId、cabin 和 name
- 虚拟编码分类变量性别、出发和标题
- 比例年龄和费用-特征比例有助于梯度下降算法更快收敛,请参考 scikit-learn 文档或 Github repo
预处理后的数据现在看起来像这样:
The training set contains 11 features, ready for the neural net to evaluate it
6。应用你的神经网络
获取 X 和 y 变量,然后转置它们以适应神经网络架构。
根据你的特征数量选择第一层尺寸。在这种情况下,第一维是 11。随后选择尽可能多的隐藏层。
The first try yields 85% training and 82% test accuracy!
预处理测试数据。通过使用 X 和来自训练神经网络的参数的前向传播来生成预测。
Last step: Generate predictions on the test data
瞧啊!您生成了预测,并将其保存为 csv 文件,现在您可以将该文件提交给 kaggle 。这个预测会让你进入前 30%的参与者。
Submitting the predictions file lands you in the upper third and helps you get used to participating in kaggle competitions
恭喜你,你已经将神经网络应用到你自己的数据集中了!
现在我鼓励你去玩网络中的迭代次数和层数。能提高分数吗?你做了哪些不同的事情?
将神经网络应用于泰坦尼克号生存数据集是否有些矫枉过正?大概吧。
网络是否正规化优化?还没有。完成课程 2 后,我们可能会有现成的工具来调整我们的神经网络并提高我们的分数。
关键要点:
- 从 Coursera hub 下载“应用深度学习”和“dnn _ utils _ v2”jupyter 笔记本,并在您的本地环境中运行它们
- 相应地预处理您的数据
- 转置你的 X 和 y 变量,这样你就有了一个“示例特征”训练矩阵
- 调整第一层尺寸以匹配您的要素数量
- 训练神经网络并保存生成的参数
- 通过对测试数据和以前保存的神经网络参数进行正向传播,生成对测试集的预测
感谢您阅读帖子。欢迎通过 LinkedIn联系我,在评论中提出问题,或者关注我,了解我在通往成功的Coursera 深度学习 T13 专业化道路上的最新知识。
甜还是骗?完成吴恩达的第二个课程后,建立一个运动鞋评分者
原文:https://towardsdatascience.com/https-medium-com-janzawadzki-sweet-or-cheat-build-a-sneaker-rater-after-finishing-andrew-ngs-2nd-course-49475fc75429?source=collection_archive---------5-----------------------
你尝过 tensorflow,现在你想要更多。创建您自己的图像分类器来评价运动鞋,并将其应用于吴恩达的第二课程 tensorflow 网。
Hotter than the sun or cooler than the north pole? Let’s find out.
Youbing吴恩达深度学习专业化的第一期课程,应用你的所学,完成了 deeplearning.ai 的第二期课程,你用 tensorflow 实现了你的第一个神经网络,并见证了它创造的奇迹。现在,您很想看看自己能否创建一个图像分类器。
我们将一起从零开始创造一个男式运动鞋评级机构。这篇文章向你展示了如何将运动鞋图片抓取、评级和摄取到你刚刚完成的 tensorflow 网络中。我们依靠首席执行官和snkrgks.com蒂姆·瓦尔兹的创始人的天真无邪的品味来评价大约 1400 双运动鞋的吸引力。
这里描述的过程可以用来创建任何类型的图像分类器。要不要给车打分?衣服?行星?你需要的只是一个想法,按照这些步骤收集和标记数据,并应用深度学习。
该代码可在 github repo 上找到。让我们踢它。
收集数据
任何机器学习算法最重要和最有价值的成分是它的数据。我们需要大约 1400 张图像来训练我们的神经网络,就像吴恩达的手指例子一样。你可以随意使用和标注更多。我决定借助简单而高效的 Python ImageScraper 库从一个流行的时尚网站上抓取图片。
安装图库并访问包含您的图像的网站。执行以下命令:
image-scraper 'https://www.fashionsite.com/mens-sneakers/'
该工具将自动从网站下载所有图片,并将其保存在一个单独的文件夹中。请注意,您可能需要增加页码,以便不仅从第一页抓取图像。从第二页抓取图像的命令如下所示:
image-scraper 'https://www.fashionsite.com/mens-sneakers/?p=2'
Example of a scraped sneaker image
请注意,抓取图片并不一定适合每个网站。因为我们只是将这些数据用于我们的私人项目,所以应该没问题。但是您也可以创建一个 API 调用并以这种方式收集数据。易贝的友好的人们提供了一个记录良好的 API 来收集他们的库存信息。
遍历页面后,您应该已经收集了足够多的图像。恭喜你,你已经完成了图像分类器的基础工作!该喝点咖啡了,然后继续。
将图像裁剪为相同大小
现在您已经收集了足够的数据,您必须将图像裁剪为标准大小,以便您的网络可以处理输入大小。幸运的是, ImageMagick 为我们提供了所需的所有工具。
首先,试着找出最适合你的图片的尺寸。尝试使用 2 的不同指数作为窗口框架,例如 128x128、256x256 等,并添加 x 和 y 偏移以捕捉图像,同时裁剪掉不必要的像素。执行以下命令:
convert -crop 256x256+1+50 pic_to_be_cropped.jpg cropped_pic_name.jpg
为了理解{ Width } X { Height }+{ X _ Offset }+{ Y _ Offset }命令,我发现这篇文章很有帮助。一旦你确定了最佳图像尺寸,批量裁剪文件夹中的所有图像。
mogrify -crop 256x256+0+50 -path ./cropped/ *.jpg
该命令将裁剪当前路径中的所有图像。jpg 扩展名,并将图像保存在新创建的名为“cropped”的文件夹中。
在你去除了不必要的信息并标准化了你的图片尺寸后,我们将进入有趣的部分——给你的图片加标签。
Hotdog or not hotdog? Time to label images. image credit: https://www.theverge.com/tldr/2017/5/14/15639784/hbo-silicon-valley-not-hotdog-app-download
标签图像
你收集了大量的图片。现在,您需要一种简单易行的方法来给这些图像评级。
由于找不到符合我们需求的库,我自己创建了一个 Python 模块。该工具允许您设置评级范围,例如从 1 到 5,并读取文件夹中带有裁剪图像的每个文件。我正在把这个库上传到 PyPi,这样你最终可以 pip 安装它。现在,你可以查看下面的代码,或者从 github 获取脚本。
将文件保存在与裁剪图像数据集相同的文件夹中。导航到您的文件夹结构,并执行以下命令行:
python imagerater.py -i 1 -x 5-f ‘./cropped/*.jpg' -q “Rate shoe here: “
该命令执行 imagerater 脚本,在 1 到 5 之间设置等级,读取所有。jpg 图像,并将输入提示定义为“Rate shoe here:”。
Executing the imagerater script displays an image and allows you to rate it.
该库将您的图像展平、标准化并保存在一个 m x n 矩阵中,m 是您的图像数量,n 是您的图像展平后的大小加上指定的评级。
给你的图片打分的技巧
Timm is locked in rating sneakers.
Timm 是运动鞋专家,根据预定义的标准应用严格的分级,以确保同质评级。我们建议您也这样做。如果你在评价图像时不坚持一种模式,没有神经网络能够从随机标记的数据中归纳出规律。
Timm 在审查运动鞋方面很有经验,之前已经收到和评估了数百次踢腿。查看他关于粉丝最爱的 overkill x hummel 马拉松发布的文章。在评价运动鞋时,Timm 遵循明确的模式,并专注于鞋的形式、材料、颜色和缓冲。他倾向于不顾鞋子品牌而客观地评判每一双运动鞋。
他更喜欢简单而优雅的低帮鞋,得体的颜色(没有不必要的亮色),高质量的材料和顶级的缓冲,以获得最佳的舒适度。关于运动鞋的背景信息,比如围绕 Yeezy Boost 的人为炒作,不包括在这篇评论中,因为一个网络通常无法找出围绕一双鞋的公关努力。
Prime example of a 5 star rating
恭喜你,你刚刚完成了最复杂最耗时的任务!现在有趣的来了,让我们应用吴恩达的 tensorflow 网上的数据。
应用神经网络
从 Coursera hub 下载 Coursera 课程 2“tensor flow 教程”笔记本和“tf_utils”文件。执行所有方法并将保存的图像数据加载到您的笔记本中。
现在,让我们调整吴恩达的代码,以适应我们的训练数据。采取以下三个步骤:
- 随机洗牌,把你的训练数据分成 X 和 Y 变量。
- One_hot_encode 你的 Y 变量。将 Y dtype 调整为 int,tf_utils 不能处理 float。如果您遇到 one_hot_encoding 的问题,请尝试增加目标类的大小。有时,训练数据中会出现一个非故意的零分。
- 将 W1 中的第一个输入图层大小更改为与展平数据相匹配。在我们的 246x256 像素图像中,我将第一个维度从 12228 更改为 188928。还要更改 W3 和 b3 中的输出变量,以匹配类的数量。我们使用从 1 到 5 的等级量表,因此我们有 5 个等级。
就这样,现在你准备好了!按 Shift + Enter,让模型运行。
Result of training the tensorflow network.
正如我们所见,神经网络很好地收敛了。看起来我们有一个偏差问题,训练精度似乎没有应有的好。测试准确率也真的很低,比随便猜五个类中的任何一个都差。这种行为是意料之中的,因为我们只训练了一个非常浅的网络,并且没有应用任何优化技术。我只是为了好玩,训练了一个稍微深一点的网络,把准确率提高到了 36%,所以分类器还有很大的改进空间。
在下一次迭代中,我们将应用 deeplearning.ai 第三次课程中的技巧进一步改进你的模型,并可能使用我们将在第四次课程中学习的网络架构(有人说了 ConvNet 吗?).
1–5, how would you rate it?
恭喜你!您成功地从头开始构建了自己的图像分类器,并应用了之前学到的知识。我知道 deeplearning.ai 的人会为你感到骄傲,我肯定。
所有深度学习学分归 Coursera 和 deeplearning.ai 所有。
如果你想阅读更多关于 Coursera 深度学习专业化和其他机器学习冒险的内容,请为这篇文章鼓掌,并在 Medium 上关注我。如果你认为我们应该继续这个项目,请随时在 LinkedIn 上给我发消息或评论这个帖子。感谢您的关注。
在 Scout24 担任数据科学家
原文:https://towardsdatascience.com/https-medium-com-janzawadzki-working-as-a-data-scientist-at-scout24-48b15286e1a?source=collection_archive---------5-----------------------
欧洲独角兽公司应用创新的结构和方法来充分利用他们的数据科学团队。找出方法。
我和 Scout24 数据科学团队正在撰写我的硕士论文,并在这里学到了很多关于实践和组织结构的知识。在我之前担任管理顾问期间,我见过不同的组织,我相信 Scout24 已经找到了一种有趣的组织结构和方法组合,可以与数据科学家合作。在结束我的工作之前,我想让大家了解一下在 Scout24 做一名数据科学家的感受。
所以,请舒适地坐好,系好安全带,去探索 Scout24 数据科学家的世界。
谁是 Scout24?
就房源数量、用户数量和在平台上停留的时间而言,Scout24 AG 是欧洲领先的房地产和汽车销售在线平台。这家上市公司每月接待约 800 万独立访客,并雇佣 1200 名球探。它的使命是“激发你的最佳决策。我们连接人、车和家。”其主要平台有 ImmobilienScout24 、 AutoScout24 和 Scout 消费者服务。Scout24 在柏林、慕尼黑和巴塞罗那设有办事处。预计 2018 年收入将超过 5.4 亿€,估值为 30 亿€,你可以称该公司为欧洲在线巨擘。对数据科学家来说,最酷的事情是首席执行官最近宣布许多新产品将使用人工智能。此外,其中一个核心价值是数据驱动,这将数据科学置于驾驶员位置,以提供新的见解和产品。
Scout24 的数据科学家是如何工作的?
数据科学团队是 scout 24 DNA 的一部分,即数据分析团队。DNA 由专门的数据工程师、数据分析师和数据科学家组成。这些团队都坐得很近,所以每当出现问题时,通常会联系具有互补技能的同事。数据科学团队采用敏捷的工作方法,包括与来自慕尼黑的同事一起进行每日状态更新、回顾和深入研究,等等。
Scout24 以用户为中心,拥有由产品负责人和软件工程师组成的专门跨职能团队,为特定的用户组维护和创建产品。这些团队被称为细分市场,DNA 服务于所有细分市场,使他们能够做出数据驱动的决策,并构建机器学习产品。
Data Science is a part of DNA which supports all market segments in serving Scout24's users.
细分市场划分优先级,并决定团队下一步的工作计划。这种基于项目的工作方式确保工作永远不会无聊。数据科学团队成员还担任公司其他部门的顾问,帮助他们确定计划范围并讨论想法。
创新不是你兼职做的事情,你必须全身心地投入。—sébastien Foucaud 博士,Scout24 前数据科学主管
该公司还进行季度数据实验室。来自各个领域的童子军提出与新数据产品相关的想法,最有希望的三个想法由一组数据科学家、工程师和分析师进行测试。数据实验室的目标是试验开箱即用的想法,并提供概念证明。这个想法可行不可行?如果是这样的话,这个项目将在下面的一个计划中被推向市场。一个很好的例子是 https://www.propertyinvestgermany.com/的平台,一个测试如何最好地将建筑开发商与国际投资者联系起来的 MVP。这是第一次 DataLab 迭代的结果。点击了解更多关于项目的信息。
Few impressions from the DataLab pitch event.
除了这些计划之外,数据科学团队还采用了数据科学常驻计划。常驻数据科学家专门负责一个细分市场,并为该团队提供支持。这位数据科学家致力于细分市场的特定数据产品。
数据科学家在 Scout24 做什么项目?
Scout24 是一个数据驱动的组织。该公司拥有大量有价值的数据,因此数据科学部门在开发新的数据产品方面处于关键地位。
- 推荐 提供了一种更好的方式来探索庞大的房地产和汽车列表目录。推荐引擎将用户的搜索行为与来自相似用户的搜索相匹配,并推荐新的房产或汽车。这些推荐非常成功,每个月都会带来 10 万条额外的联系线索。此外,3 个推荐项目中的 2 个不会被用户通过常规搜索找到。
- 预测引擎计算哪些用户正在寻找抵押贷款。该引擎现在向感兴趣的用户推荐抵押贷款。结果是:点击率比最佳人类猜测高出 10 倍,通知减少了 88%以避免用户收到垃圾邮件,通知打开率增加了 228%,从通知到实际销售线索的比率增加了 27,000%。这表明数据科学团队在找到相关用户并向他们传递相关信息方面做得非常出色!
- 当你在 AutoScout24 上寻找新车或二手车时,你现在会看到每辆车的价格评估,显示一个好的、公平的或不好的价格。由于大多数用户很难判断销售价格是好是坏,数据科学团队为他们开发了一个解决方案。对于二手车,他们会根据市场价格计算出一个定制价格建议。查看博客上的视频,了解更多关于它是如何工作的!
Pssst — this Lambo Huracán is a good price!
该团队还有大量其他令人惊叹的计划,敬请关注新的数据驱动产品和博客帖子。
Scout24 为员工提供了什么?
The Data Analysts sharpen their R saw in their learning group
Scout24 致力于培养一种学习文化。数据科学团队每周进行两次学习会议,他们在不同的在线学习课程中工作。每位员工都可以从日常工作中抽出时间来提高自己的技能。此外,该公司还组织了童子军学校,在那里,童子军们聚集在一起,互相教授他们想要的任何东西。童子军学校提供冥想课程,例如教德语、英语和瑜伽。
The Scout School is here to teach you new skills.
公司还积极支持员工参加会议并在会上发言。数据科学团队的成员在伦敦举行的 2017 年预测分析世界上展示了 AutoScout24 价格估值。如果你想参加一个会议,Scout24 支持你。
The Scouts Alexander Diergarten and Dr. Sean Gustafson representing Scout24 Data Science during the Predictive Analytics World London 2017.
除了数据实验室,该公司还提供一年两次的黑客周。如果你没有机会参加这个 DataLab 迭代,你有整整一周的时间来构思自己的想法,不要问任何问题。自由!
A Scoutie trying out new ideas during a hackweek project.
Impressions from the Hackweek.
最后但并非最不重要的一点是,在柏林、慕尼黑、巴塞罗那的中心位置,以及 OneScout 方法,搬迁到另一个办公室真的不成问题。
The rent map shows the average rent price for a two-bedroom, 70 m2 apartment close to each public transport station in Berlin.
虽然我已经决定毕业后接受一份不同的工作,但我对这家公司只有温暖的感觉,并强烈建议你去看看他们的博客和求职板寻找新的内容和空缺职位。
摘要
概括一下这篇文章,Scout24 的数据科学家是跨职能团队的一部分,与数据工程师和数据分析师一起工作。数据科学家帮助细分市场建立相关的数据产品,以激励用户找到他们梦想中的房子或汽车。作为一颗樱桃,数据实验室鼓励创新,允许对新想法进行实验,从而产生新的见解,有时还会产生新产品。
我希望您喜欢这篇关于 Scout24 数据科学家日常工作的离题文章。你觉得他们的数据科学方法怎么样?请随意在下面添加任何评论。期待您的反馈。✌️
有用的 Keras 功能
原文:https://towardsdatascience.com/https-medium-com-manishchablani-useful-keras-features-4bac0724734c?source=collection_archive---------0-----------------------
以下是一些有趣功能的总结,我觉得在我构建深度学习管道时,我会发现参考这些功能很有用,也就是我通常不记得的东西。来自 Keras 文档 https://keras.io 和其他在线帖子。
当验证损失不再减少时,我如何中断培训?
您可以使用EarlyStopping
回调:
**from** keras.callbacks **import** EarlyStopping
early_stopping = EarlyStopping(monitor='val_loss', patience=2)
model.fit(X, y, validation_split=0.2, callbacks=[early_stopping])
如何获得中间层的输出?
一个简单的方法是创建一个新的Model
,它将输出您感兴趣的图层:
**from** keras.models **import** Modelmodel = ... *# create the original model*layer_name = 'my_layer'
intermediate_layer_model = Model(inputs=model.input,
outputs=model.get_layer(layer_name).output)
intermediate_output = intermediate_layer_model.predict(data)
或者,您可以构建一个 Keras 函数,在给定特定输入的情况下返回特定图层的输出,例如:
**from** keras **import** backend **as** K*# with a Sequential model*
get_3rd_layer_output = K.function([model.layers[0].input],
[model.layers[3].output])
layer_output = get_3rd_layer_output([X])[0]
类似地,您可以直接构建一个 Theano 和 TensorFlow 函数。
请注意,如果您的模型在训练和测试阶段有不同的行为(例如,如果它使用Dropout
、BatchNormalization
等)。),您需要将学习阶段标志传递给您的函数:
get_3rd_layer_output = K.function([model.layers[0].input, K.learning_phase()],
[model.layers[3].output])*# output in test mode = 0*
layer_output = get_3rd_layer_output([X, 0])[0]*# output in train mode = 1*
layer_output = get_3rd_layer_output([X, 1])[0]
如何在 Keras 中使用预训练模型?
代码和预训练权重可用于以下影像分类模型:
- 例外
- VGG16
- VGG19
- ResNet50
- 盗梦空间 v3
它们可以从keras.applications
模块导入:
**from** keras.applications.xception **import** Xception
**from** keras.applications.vgg16 **import** VGG16
**from** keras.applications.vgg19 **import** VGG19
**from** keras.applications.resnet50 **import** ResNet50
**from** keras.applications.inception_v3 **import** InceptionV3model = VGG16(weights='imagenet', include_top=**True**)
关于一些简单的使用示例,请参见应用模块的文档。
有关如何使用这种预训练模型进行特征提取或微调的详细示例,请参见这篇博文。
VGG16 模型也是几个 Keras 示例脚本的基础:
- 风格转移
- 特征可视化
- 深梦
使用非常少的数据构建强大的图像分类模型
https://blog . keras . io/building-powerful-image-class ification-models-using-very-little-data . html
数据预处理和数据扩充
from keras.preprocessing.image import ImageDataGenerator
datagen = ImageDataGenerator(
rotation_range=40,
width_shift_range=0.2,
height_shift_range=0.2,
rescale=1./255,
shear_range=0.2,
zoom_range=0.2,
horizontal_flip=True,
fill_mode='nearest')
这些只是可用选项中的一部分(更多信息,请参见文档)。让我们快速回顾一下我们刚刚写的内容:
rotation_range
是以度为单位的值(0-180),在此范围内随机旋转图片width_shift
和height_shift
是随机垂直或水平平移图片的范围(作为总宽度或高度的一部分)rescale
是一个值,在进行任何其他处理之前,我们会将数据乘以该值。我们的原始图像由 0-255 的 RGB 系数组成,但是这样的值对于我们的模型来说太高而无法处理(给定典型的学习率),所以我们通过 1/255 的缩放将目标值设置在 0 和 1 之间。因素。shear_range
用于随机应用剪切变换zoom_range
用于图片内部随机缩放horizontal_flip
用于在没有水平不对称假设的情况下,随机翻转一半水平相关的图像(如真实图片)。fill_mode
是用于填充新创建像素的策略,可在旋转或宽度/高度移动后出现。
现在,让我们开始使用该工具生成一些图片,并将它们保存到一个临时目录中,这样我们就可以感受一下我们的增强策略正在做什么——在这种情况下,我们禁用了重新缩放,以保持图像可显示:
让我们准备我们的数据。我们将使用.flow_from_directory()
直接从各自文件夹中的 jpg 生成批量图像数据(及其标签)。
img = load_img('data/train/cats/cat.0.jpg') # this is a PIL image
x = img_to_array(img) # this is a Numpy array with shape (3, 150, 150)
x = x.reshape((1,) + x.shape) # this is a Numpy array with shape (1, 3, 150, 150)
# the .flow() command below generates batches of randomly transformed images
# and saves the results to the `preview/` directory
i = 0
for batch in datagen.flow(x, batch_size=1,
save_to_dir='preview', save_prefix='cat', save_format='jpeg'):
i += 1
if i > 20:
break # otherwise the generator would loop indefinitelybatch_size = 16
# this is the augmentation configuration we will use for training
train_datagen = ImageDataGenerator(
rescale=1./255,
shear_range=0.2,
zoom_range=0.2,
horizontal_flip=True)
# this is the augmentation configuration we will use for testing:
# only rescaling
test_datagen = ImageDataGenerator(rescale=1./255)
# this is a generator that will read pictures found in
# subfolers of 'data/train', and indefinitely generate
# batches of augmented image data
train_generator = train_datagen.flow_from_directory(
'data/train', # this is the target directory
target_size=(150, 150), # all images will be resized to 150x150
batch_size=batch_size,
class_mode='binary') # since we use binary_crossentropy loss, we need binary labels
# this is a similar generator, for validation data
validation_generator = test_datagen.flow_from_directory(
'data/validation',
target_size=(150, 150),
batch_size=batch_size,
class_mode='binary')
我们现在可以使用这些生成器来训练我们的模型。每个历元在 GPU 上需要 20–30 秒,在 CPU 上需要 300–400 秒。所以如果你不着急的话,在 CPU 上运行这个模型是完全可行的。
model.fit_generator(
train_generator,
steps_per_epoch=2000 // batch_size,
epochs=50,
validation_data=validation_generator,
validation_steps=800 // batch_size)
model.save_weights('first_try.h5') # always save your weights after training or during training
这种方法使我们在 50 个时期后达到 0.79–0.81 的验证精度(这是一个任意选取的数字,因为模型很小,并且使用了积极的压降,所以到那时它似乎不会过度拟合)
使用预训练网络的瓶颈功能:一分钟内 90%的准确率
我们的策略如下:我们将只实例化模型的卷积部分,直到全连接层。然后,我们将在我们的训练和验证数据上运行该模型一次,在两个 numpy 阵列中记录输出(来自 VGG16 模型的“瓶颈特性”:全连接层之前的最后激活映射)。然后,我们将在存储的特征之上训练一个小的全连接模型。
我们离线存储特征而不是在冻结的卷积基础上直接添加全连接模型并运行整个过程的原因是计算效率。运行 VGG16 是很昂贵的,尤其是如果你在 CPU 上工作,我们希望只做一次。请注意,这阻止了我们使用数据扩充。
我们达到了 0.90–0.91 的验证精度:一点也不差。这肯定部分是由于基础模型是在已经有狗和猫的数据集上训练的(在数百个其他类中)。
微调预训练网络的顶层
为了进一步改善我们之前的结果,我们可以尝试在顶级分类器旁边“微调”VGG16 模型的最后一个卷积块。微调包括从训练好的网络开始,然后使用非常小的权重更新在新的数据集上重新训练它。在我们的案例中,这可以通过 3 个步骤来完成:
- 实例化 VGG16 的卷积基并加载其权重
- 在顶部添加我们之前定义的全连接模型,并加载其权重
- 冻结 VGG16 模型的层,直到最后一个卷积块
请注意:
- 为了进行微调,所有层都应该从经过适当训练的权重开始:例如,你不应该在预先训练的卷积基础上,加上随机初始化的全连接网络。这是因为由随机初始化的权重触发的大梯度更新会破坏卷积基中的学习权重。在我们的情况下,这就是为什么我们首先训练顶级分类器,然后才开始微调卷积权重。
- 我们选择仅微调最后一个卷积块,而不是整个网络,以防止过拟合,因为整个网络将具有非常大的熵容量,因此很容易过拟合。低级卷积块学习到的特征比高级卷积块更通用,更不抽象,因此保持前几个块固定(更通用的特征)并且只微调最后一个(更专用的特征)是明智的。
- 微调应该以非常慢的学习速率进行,通常使用 SGD 优化器,而不是自适应学习速率优化器,如 RMSProp。这是为了确保更新的幅度保持很小,以免破坏先前学习的功能。
什么是全球平均池?
引用谷歌搜索“全球平均池”的第一篇论文。http://arxiv.org/pdf/1312.4400.pdf
CNN 没有采用传统的全连接层进行分类,而是通过全局平均池层直接输出最后一层 mlpconv 特征图的空间平均值作为类别的置信度,然后将得到的向量送入 softmax 层。在传统的 CNN 中,很难解释来自目标成本层的类别级信息如何传递回先前的卷积层,因为完全连接的层在它们之间充当黑盒。相比之下,全局平均池更有意义和可解释性,因为它加强了特征地图和类别之间的对应性,这通过使用微观网络的更强的局部建模而成为可能。此外,完全连接的层容易过拟合,并严重依赖于下降正则化[4] [5],而全局平均池本身就是一个结构正则化,它本身可以防止整个结构的过拟合。
和
在本文中,我们提出了另一种称为全局平均池的策略来取代 CNN 中传统的全连接层。其思想是在最后的 mlpconv 层中为分类任务的每个相应类别生成一个特征图。我们没有在特征地图上添加完全连接的层,而是取每个特征地图的平均值,并将结果向量直接输入 softmax 层。与完全连接的图层相比,全局平均池的一个优势是,它通过加强要素地图和类别之间的对应关系,更适合卷积结构。因此,特征图可以很容易地解释为类别置信度图。另一个优点是在全局平均池中没有要优化的参数,因此在这一层避免了过拟合。此外,全局平均池汇总了空间信息,因此对输入的空间平移更具鲁棒性。
我们可以将全局平均池视为一种结构正则化器,它明确地将特征映射强制为概念(类别)的置信度映射。这通过 mlpconv 层成为可能,因为它们比 GLMs 更好地逼近置信图。
在有 10 个分类的情况下(CIFAR10,MNIST)。
这意味着,如果在最后一次卷积结束时有一个 3D 8,8,128 张量,在传统方法中,你要将其展平为大小为 8x8x128 的 1D 矢量。然后添加一个或几个完全连接的层,最后添加一个 softmax 层,将大小减少到 10 个分类类别,并应用 softmax 运算符。
全局平均池意味着你有一个 3D 8,8,10 张量,计算 8,8 切片的平均值,你最终得到一个形状为 1,1,10 的 3D 张量,你将它整形为形状为 10 的 1D 向量。然后添加一个 softmax 运算符,中间没有任何运算。平均池之前的张量应该具有与您的模型具有的分类类别一样多的通道。
该文件并不清楚,但当他们说“softmax 层”时,他们指的是 softmax 操作符,而不是与 softmax 激活完全连接的层。
不是 y=softmax(W*flatten(GAP(x))+b)而是 y=softmax(flatten(GAP(x)))。
在一组新的类上微调 InceptionV3
**from** keras.applications.inception_v3 **import** InceptionV3
**from** keras.preprocessing **import** image
**from** keras.models **import** Model
**from** keras.layers **import** Dense, GlobalAveragePooling2D
**from** keras **import** backend **as** K*# create the base pre-trained model*
base_model = InceptionV3(weights='imagenet', include_top=**False**)*# add a global spatial average pooling layer*
x = base_model.output
x = GlobalAveragePooling2D()(x)
*# let's add a fully-connected layer*
x = Dense(1024, activation='relu')(x)
*# and a logistic layer -- let's say we have 200 classes*
predictions = Dense(200, activation='softmax')(x)*# this is the model we will train*
model = Model(inputs=base_model.input, outputs=predictions)*# first: train only the top layers (which were randomly initialized)*
*# i.e. freeze all convolutional InceptionV3 layers*
**for** layer **in** base_model.layers:
layer.trainable = **False***# compile the model (should be done *after* setting layers to non-trainable)*
model.compile(optimizer='rmsprop', loss='categorical_crossentropy')*# train the model on the new data for a few epochs*
model.fit_generator(...)*# at this point, the top layers are well trained and we can start fine-tuning*
*# convolutional layers from inception V3\. We will freeze the bottom N layers*
*# and train the remaining top layers.**# let's visualize layer names and layer indices to see how many layers*
*# we should freeze:*
**for** i, layer **in** enumerate(base_model.layers):
print(i, layer.name)*# we chose to train the top 2 inception blocks, i.e. we will freeze*
*# the first 172 layers and unfreeze the rest:*
**for** layer **in** model.layers[:172]:
layer.trainable = **False**
**for** layer **in** model.layers[172:]:
layer.trainable = **True***# we need to recompile the model for these modifications to take effect*
*# we use SGD with a low learning rate*
**from** keras.optimizers **import** SGD
model.compile(optimizer=SGD(lr=0.0001, momentum=0.9), loss='categorical_crossentropy')*# we train our model again (this time fine-tuning the top 2 inception blocks*
*# alongside the top Dense layers*
model.fit_generator(...)
如何使用有状态 rnn?
使 RNN 有状态意味着每批样本的状态将被重新用作下一批样本的初始状态。
因此,当使用有状态 rnn 时,假设:
- 所有批次都有相同数量的样本
- 如果
X1
和X2
是连续批次的样品,那么X2[i]
是X1[i]
的后续序列,对于每个i
。
要在 RNNs 中使用状态,您需要:
- 通过向模型中的第一层传递一个
batch_size
参数,显式指定您正在使用的批量大小。例如batch_size=32
对于 10 个时间步长的 32 样本批次序列,每个时间步长具有 16 个特征。 - 在你的 RNN 图层中设置
stateful=True
。 - 调用 fit()时指定
shuffle=False
。
要重置累积的状态:
- 使用
model.reset_states()
重置模型中所有层的状态 - 使用
layer.reset_states()
重置特定有状态 RNN 层的状态
示例:
X *# this is our input data, of shape (32, 21, 16)*
*# we will feed it to our model in sequences of length 10*model = Sequential()
model.add(LSTM(32, input_shape=(10, 16), batch_size=32, stateful=**True**))
model.add(Dense(16, activation='softmax'))model.compile(optimizer='rmsprop', loss='categorical_crossentropy')*# we train the network to predict the 11th timestep given the first 10:*
model.train_on_batch(X[:, :10, :], np.reshape(X[:, 10, :], (32, 16)))*# the state of the network has changed. We can feed the follow-up sequences:*
model.train_on_batch(X[:, 10:20, :], np.reshape(X[:, 20, :], (32, 16)))*# let's reset the states of the LSTM layer:*
model.reset_states()*# another way to do it in this case:*
model.layers[0].reset_states()
注意,方法有predict
、fit
、train_on_batch
、predict_classes
等。所有的将更新模型中有状态层的状态。这不仅允许您进行状态训练,还允许您进行状态预测。
在约会市场上,我们是否感到被低估了?
原文:https://towardsdatascience.com/https-medium-com-melanietsang-do-we-feel-undervalued-in-the-dating-market-153c03eb6dc8?source=collection_archive---------12-----------------------
速配实验数据分析
什么影响了人们对选择约会对象的看法?是这个人的长相,性格还是幽默?哥伦比亚大学商学院教授雷·菲斯曼和希娜·艾扬格在 2002 年至 2004 年期间进行了一系列实验,他们要求 500 多名参与者与其他异性进行四分钟的第一次约会,对他们的吸引力、真诚、智力、风趣、雄心和共同兴趣进行评级,并回答他们是否会再次与伴侣约会的问题。该数据集是在 Kaggle 上发现的,它包含了问卷答案,包括人口统计数据、约会习惯、自我认知和关键属性评级,以及约会决定。
我在试图理解什么?
对这个数据集进行了各种数据分析,洞察范围从择偶的性别差异到约会的种族偏好。我的目标是进行一项以前可能没有进行过的分析,我特别感兴趣的是关键属性如何影响约会决策,以及人们是否清楚地意识到他们的自我价值与他们的感知价值。
数据准备过程
过滤掉无关的数据
我首先阅读速配数据 Key.doc 以了解每个字段,然后过滤掉我不需要的数据,如 SAT 分数、学费信息、收入水平和邮政编码。
标准化数据
我对通过不同标度方法收集的数据进行了标准化,例如 1-10 标度的评级方法与 100 点分布方法,顺序标度与间隔标度(例如,当 3 =一个日期/周时,我将其转换为 52 次/年)。
处理缺失数据
对于每个条目,如果丢失的变量数量很大,我选择删除整个条目。例如,如果缺少合作伙伴对某个参与者所有属性的评分,我会删除属性分析中的整个条目,但保留它用于其他有效的分析。如果只有一个变量缺失,比如真诚度,我就用其他九个伙伴对同一个参与者的评分均值来代替。除了手工清理,我还使用了最近邻法来自动替换剩余的缺失值。
数据分析结果
一.一般信息
总共有 552 名参与者,其中 275 名为女性,270 名为男性(7 个缺失值)。虽然年龄最大且唯一的参与者为 55 岁,但 75%的参与者年龄在 24 至 34 岁之间。第一大部分参与者是欧洲/高加索裔美国人,而第二大部分是亚洲人。
二。属性分析
约会中最重要的属性是什么?
在约会实验开始之前,参与者被要求根据他们在潜在约会中的重要性给下面的属性分配 100 分。总的来说,整个参与者群体认为吸引力是潜在约会中最重要的属性,其次是 T2 智力。
对女性来说,排名前三的属性是智力、真诚和吸引力,而对男性来说,则是吸引力、智力和乐趣。此外,男性倾向于有更独特的偏好,但女性的偏好似乎更均匀。
然而,当结果按种族分类时,我发现亚裔是唯一一个认为真诚比智慧更重要的种族。
此外,当结果按工作行业细分时,我发现虽然许多群体认为智力比吸引力更重要,但建筑是唯一一个给予智力更高认可的群体。
三。感知分析
在实验之前,参与者还被要求按照 1-10(1 =糟糕,10 =很好)的等级对这五个属性进行评级,不包括共同的兴趣。在每次四分钟的第一次约会后,他们被要求对他们的伴侣的六个特征进行评价。
我们是否觉得自己总是被低估?
比较自我评级和参与者认为他们会得到的评级可能会引发许多社会学问题。人们是否有被低估的感觉或经历?他们是否倾向于夸大自己的优点,隐藏自己的缺点?结果显示,人们普遍认为伴侣低估了自己的属性,除了智力。这将是进一步研究的一个有趣点,是什么让人们相信他们的智力会被高估?此外,野心似乎是人们认为他们所表现出来的唯一属性。
我们真的高估了自己吗?
当比较自我评价和实际评价时,它表明参与者确实普遍高估了自己。他们最高估的属性是乐趣,而最不高估的属性是智力。有趣的是,当人们相信他们的智力会被高估时,其他人却知道他们实际上有多聪明!
当我们认为自己被低估时,我们真的被低估了吗?
当比较他们假设的伴侣的评价和实际的评价时,我发现虽然参与者知道他们被低估了,但他们对每个属性的评价甚至比他们想象的还要低。好难过!
是不是第一个永远是最好的?
由于参与者在每个实验中都遇到了几个伙伴,我做了一个皮尔森相关分析以了解会面顺序是否会影响人们的评级。首先,我发现顺序和他们喜欢自己伴侣的程度之间存在负相关。订单与四个属性之间的负相关也被证明,真诚、聪明、有趣和野心。比如,越晚遇到伴侣,越觉得伴侣不真诚。值得进行更多的研究,以了解更多的经验,人们是否表现出较少的真诚,或者只是感觉到来自他们的伴侣的较少的真诚,即使他们的伴侣同样真诚。
我还发现这些属性之间存在正相关关系。真诚和聪明的相关性最强,其次是聪明和野心,然后是乐趣和共同兴趣。
四。匹配分析
我们需要说多少个“是”才能听到一个“是”的回答?
在每次第一次约会后,参与者都要回答他们是否愿意再见他们的伴侣的问题。在这个实验中,他们发出 6 个“是”,平均得到 2 个匹配。换句话说,他们每尝试 3 次,总会得到 1 次“爱的回应”。
我们对爱情乐观吗?
实验结束后,参与者还被要求预测他们将得到多少个匹配,并收集实际的匹配数。平均来说,他们预测在每个实验中会有 3 次匹配,但实际上只有 2 次。
上面的数字是通过从匹配数中减去匹配估计值计算出来的。如图所示,男性参与者的预测往往比女性更乐观。
不考虑其他未定义的种族,黑人/非洲裔美国人和亚裔美国人似乎最乐观,而拉丁裔/西班牙裔美国人群体的预测最准确。
爱情可以实践吗?
平均来说,参与者每月约会两次。但是,更多的约会经验是否有助于他们获得更多的匹配,并更准确地预测他们的匹配?我做了一个皮尔逊相关分析,发现约会的频率与匹配的数量有轻微的正相关,但与匹配估计的准确度没有正相关。
动词 (verb 的缩写)约会决策预测
我感兴趣的是建立一个约会决策模型,来预测人们在六个属性和种族上是否会再见他们的伴侣。因此,我使用了逻辑回归分析来建立这个有 7777 个条目的模型,并使用随机方法将训练集和验证集按 80:20 分开。对于缺失值,我用同一个类中的均值代替。例如,当一个人遇到了 10 个伴侣,得到了 9 个关于吸引力的评分,我用吸引力评分的平均值来代替缺失的那个。由于“否”的决定比“是”的决定多 15%,我也相应地修正了权重。最后,我用同样的方法建立了 5 次模型来检验性能的稳定性。
当预测日期决定为“是”或“否”时,曲线下的面积(0.828)证明了分类的良好性能。
虽然我们都知道爱情没有方程式,但至少我们有方程式来预测你和他/她约会的可能性:
我发现,在实际的约会决策中,吸引力仍然是最重要的属性,其次是共同兴趣,然后是乐趣,这是出乎意料的,因为共同兴趣在参与者的偏好排名中似乎不是很重要。相反,在这种情况下,智力与决策没有多大关系。令人惊讶的是,当谈到实际的约会决定时,野心和真诚似乎是两个负面属性。此外,尽管跨种族伴侣似乎根本不会影响决定,但同种族与决定略有负相关。
我们真的知道自己想要什么吗?
在我的属性分析的开始,它说明了潜在约会对参与者的重要性排序是吸引力、智力、真诚/有趣(它们是等价的)、共同的兴趣和雄心。然而,当人们做出实际的约会决定时,排名是不同的:吸引力,共同的兴趣,乐趣,智力,真诚,野心。人们似乎低估了共同利益,高估了真诚。
结论
总而言之,在约会时,吸引力是人们考虑的首要因素,而野心是最不重要的。我们希望我们的伴侣聪明、真诚,但是一旦我们更加了解对方,我们就会意识到共同的兴趣在潜在的关系中是多么重要。然而,不要被我们自己的感知所迷惑,因为当我们遇到更多的人时,它也会受到影响。有时我们可能对爱情过于乐观,对自己过于自信,但事实证明是令人失望的。我们应该放弃吗?不要!因为即使更多的约会经历不会让我们在寻找灵魂伴侣时变得更聪明,我们仍然有更高的几率不期而遇❤.