TowardsDataScience 博客中文翻译 2019(二百六十七)

原文:TowardsDataScience Blog

协议:CC BY-NC-SA 4.0

如何在调查报告中使用开源卫星数据

原文:https://towardsdatascience.com/how-to-use-open-source-satellite-data-for-your-investigative-reporting-d662cb1f9f90?source=collection_archive---------3-----------------------

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

Investigation on water levels of the Theewaterskloof Dam dam, South Africa

毫无疑问,这是一座巨大的信息金矿——也许太大了——许多记者仍然回避广泛使用卫星数据。自从像digital globePlanet Labs这样的公司提供高分辨率数据以来,卫星故事的供应如雨后春笋般增长。但是开源数据——尽管分辨率较低,但仍然是有效和及时的故事来源——仍然没有得到充分利用。手里有一座未被触及的数据山,许多人要么害怕错过森林——或者这个案例中的故事——因为树木或者误解。两者都是合理的担忧。今天,我们将尝试解决您可能与同事分享的一些保留意见,并教授一些访问、理解和处理开源卫星数据的基础知识。

最近关于在新闻编辑室内外开展遥感活动的技术评论试图揭开如何利用开源卫星数据平台的神秘面纱。有些人试图解释如何简化收集数据的过程。很少有人在可行的故事和技术能力之间建立可行的联系。本教程试图挑战这种观念。我们将带您看一些基本的例子——从初学者到更高级的技术水平。

了解卫星图像的工作原理:

不同的卫星向地球发送不同的图像。区别包括分辨率(图像的清晰度),它们产生的波段的数量和类型,以及它们更新的频率。

决议事关重大

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

Finding the balance between resolution, capabilities of bands and availability: Credit: Mark Corcoran, Reuters Institute Fellowship Paper, University of Oxford

有多频繁?

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

Credit: Mark Corcoran, Reuters Institute Fellowship Paper, University of Oxford

什么是光谱带?

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

Not a new musical genre: Spectral bands determine what type of analysis you can do with the data; Credit: Mark Corcoran, Reuters Institute Fellowship Paper, University of Oxford

例如,Sentinel 2 卫星图像数据以 13 个不同光谱带的形式出现,范围从可见和近红外到短波红外,具有 10 米的 4 个光谱带、20 米的 6 个光谱带和 60 米空间分辨率的 3 个光谱带。

将这些波段视为一种双筒望远镜,它可以让您发现原本隐藏在数据中的东西。这些乐队的正确组合是关键。可以在数据上运行各种脚本(可以是不同的波段组合,如果你愿意的话)(可以在本地机器上运行,也可以在 Sentinel hub 上运行)。

如果你是在广泛的基础上报道,你要让自己熟悉这些不同的组合,以及它们为你实现的目标,因为当其他渠道错过节拍时,它可能会派上用场。

教程:从这里你需要什么?

  • Python 3.6
  • 一个合适的 Tif 阅读器(如果你想下载光栅文件)
  • Jupyter 笔记本和各种 python 包
  • Sentinel hub 的免费帐户(在 python 教程中找到描述)

2.使用 Sentinel Hub 浏览器工具搜索报道:

如果你是一个热爱技术的人,你可能会对使用浏览器应用程序的想法有点反感。但是请听我说完。对于探索和调查来说, EO 浏览器是一个不错的选择(如果你想退得更远,哨兵游乐场的卫星更少,但提供了一种稍微简单的探索方式)。

Predecessor 和其他开源卫星平台在工作流中使用 python 时可能会提供有限的选项。在这方面,Sentinel Hub 提供了一些有用的选项。此外,不需要为了做一些有趣的事情而下载整个栅格切片(可以说,调查很少同时需要所有切片数据)。相反,它允许放大特定区域。

以下是 EO 浏览器提供的数据列表以及使用这些数据的理由:

Description of EO Browser data

让我们开始沉迷于卫星狂潮吧。

1.新手

追踪野火:

对野火突然扩散和破坏的检测和报告,去年创纪录的火焰肆虐美国加利福尼亚州。这可能不是最后一次。专家称,这样的火灾在不久的将来有可能再次出现。免费获取的资源构成了 Landsat 8 数据(在美国地质调查局的帮助下提供)和 Sentinel-2 数据。

Sentinel-2 在可见光和红外光谱部分提供了比其开源同事更高分辨率的图像,完全可以胜任监测植被、土壤和水覆盖、内陆水道和沿海地区的任务。

挑战

  • 进入 EO 浏览器 —注册并登录(免费)
  • 选择哨兵-2
  • 通过将云覆盖率限制在 30%来缩小数据收集范围。
  • 发现美国加利福尼亚州的野火,这些野火在 2018 年 7 月至 8 月期间达到高潮(它们在全州范围内如此全面地宣布,你应该不会有问题来发现云的羽状物)

2018 年火灾可能的例子:

纳齐兹大火(2018 年 7 月 20 日):41.956N 123.551 W卡尔大火(2018 年 7 月 28 日):40.6543N 122.6236 W门多西诺复杂大火(2018 年 7 月 29 日):39.243283 N

接下来,我们要渲染一个特定的波段组合,以便更清楚地看到地面上的行动正在发生。

复制’ 野火脚本’:

Pierre Markuse 好心地提供了这份文件。将其插入显示“< / >”的“自定义”部分(可视化选项卡下)(手动按钮旁边)。

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

Locating California wildfires (August 2018)

有趣的角度:消防员在控制/隔离火势方面有多成功

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

Example by Pierre Markuse: Fire retardant caused by firefighting planes https://flic.kr/p/Wt8Vzo

如果您在指定的时间范围内成功发现了野火,您应该会发现黄红色的斑点。重要的是:不要把这些解释为火焰。尽管展示了它,你应该告诉你的观众所能看到的并不是真正的火灾,而仅仅是一个红外覆盖图——在某种程度上,它与活跃的火灾和热点是一致的。

挑战

在写这篇文章的时候,新的野火已经蔓延了近一周。

如果您有时间,发现这些火灾,像以前一样应用脚本并进行调查。

中规模集成电路(medium-scale integration 的缩写)

其他波段组合可用于说明潜在的野火风险区域。植被的干燥就是这样的指标之一。潮湿压力指数(MSI)可以揭示这种干燥区域,并有助于所谓的“火灾条件分析”。

该指数与其他水植被指数相反。值越高,水分胁迫水平越大(含水量越少)。试一试,用不同的乐队脚本遵循相同的程序,看看您能检索到什么。

MSI 脚本:

现在让我们使用 Python:

为了使用 Sentinel Hub 服务,您需要一个 Sentinel Hub 帐户(如果您还没有注册,请在此【https://www.sentinel-hub.com/】免费注册)。

登录 Sentinel Hub 配置器。具有实例 ID(长度为 36 的字母数字代码)的配置已经存在。对于本教程,建议您创建一个新的配置**(通过“添加新配置”)**,并将配置设置为基于’ Python 脚本模板’

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

记下您的配置的实例 ID,并将其粘贴到 INSTANCE_ID 变量声明中:

所有请求都要求给定一个边界框作为 sentinelhub.geometry.BBox 的实例,并带有相应的坐标参考系统(sentinelhub.geometry.CRS)。我们将使用 WGS84,并且可以使用 sentinelhub.geometry.CRS 中预定义的 WGS84 坐标参考系统。

现在,我们只需提供一个 JS evalscript 的 URL 地址(在这个专用页面上有许多其他巧妙的脚本)。

让我们再次选择 fire 脚本,并将其 URL 作为参数 CustomUrlParam.EVALSCRIPTURL 的值提供。

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

Python output: Downloaded Sentinel-2 image with the provided wildfire JS evalscript

腈基丁二烯橡胶(nitrile-butadiene rubber 的缩写)

另一个专门检测火灾的自定义脚本是 NBR——归一化燃烧比的缩写— ( 链接到此处的脚本)。如果你报道一场大火的事后状态,这将有助于你的分析和报道。

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

Further explanation of NBR here

挑战

NBR 脚本 t 找到被烧毁的植被。

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

Python output: Downloaded Sentinel-2 image with the provided NBR JS evalscript

2.中级—变得更具调查性

依靠火力脚本找到苏黑尔·哈桑准将的藏身之处——叙利亚最臭名昭著的军阀之一

这位绰号“老虎”的将军是“老虎部队”的舵手,这是一场俄罗斯支持的战役,也是叙利亚阿拉伯军队的精英部队,在叙利亚内战中主要作为进攻部队。

在叙利亚夺回东姑塔的行动中,根据侵犯人权文献中心(VDC)的数据,最近由猛虎组织执行的行动造成至少 600 名平民死亡,其中至少 100 名是儿童。

为了找出 2016 年苏黑尔·哈桑的藏身之处,我们进行了一次典型的情报工作,从看下面的视频开始:

我们可以看到向左飘来的几缕烟。在另一个序列中,我们看到了将军的藏身之处。

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

The Hideout (left) of Brigadier General Suheil al-Hassan, a.k.a the Tiger — “If you’re not with God then you’re with the devil. Be on the side of God so that God will be with you,” should Hassan reportedly have said at a more recent campaign on the edge of eastern Ghouta

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

Smoke clouds from nearby Aleppo thermal plant

从视频中,我们了解到这是为“打击 ISIS 的巴尔米拉之战”拍摄的。这可能是阿勒颇热电厂。

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

Confirmation: Google earth pics for the power plant show the extent of destruction after the fire raged (burned out circles on the right)

一个简单的网络搜索为我们提供了一定程度的澄清:

  • 在谷歌上搜索’ 阿勒颇热电厂 。维基百科的链接为我们提供了热电厂的长/纬度。
  • 接下来,进入谷歌地球或谷歌地图,输入你找到的坐标:‘36° 10′30″N 37° 26′22″E’。你将会看到在工厂的右边有一组烧毁的塔。

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

在 EO Brower 上,打开 roads 并输入谷歌地图结果中的经度和纬度(36.175000,37.439444)(进入 EO 浏览器的搜索窗口)。在我们的例子中,我们对 2016 年 2 月 16 日(2016-02-16)感兴趣,在这一天我们目睹了奇妙的烟柱。

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

Smoke plums move to the left

接下来,我们像以前一样继续并应用火灾脚本来可视化 Sentinel-2 图像中的火灾(挑战:如果你有信心,在你的 Python 环境中做,或者在你的 EO 浏览器窗口中模拟)。

既然我们有了更好的了解,我们就可以推断火灾发生时老虎的藏身之处。

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

Al-Hassan hideout (left) and Aleppo thermal plant (right) on google maps

为了证实我们的怀疑,我们可以检查谷歌地图卫星图像,并了解到藏身之处已被炸毁。

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

冲突、安全、武器和数字取证领域的开源专家 Benjamin Strick 解释说,这确实有助于显示当时哪座大楼着火了。后来,哈桑在工厂里的照片证实了这一点:那天那四座塔着火了。

从太空中观察某些地方的具体细节有其优点。事实上,是在人权领域。最近的一项调查显示卫星图像有助于从太空揭示奴隶制。英国诺丁汉大学权利实验室数据项目主任 Doreen Boyd 估计,三分之一的奴隶制将在太空中可见——无论是以的疤痕形式,还是以非法矿场或短暂的鱼类加工营地的轮廓形式(可以说,高分辨率的商业图像可能更适合这种调查)。

3.高级-运行算法

水位提取

让我们假设你正在报道水位下降的情况,可能会报道由此引发的冲突(根据最近的研究,缺水导致的紧张局势和冲突越来越有可能发生,这一点已被《经济学家》特别报道)报道过。

使用 Sentinel-2 多光谱和多时相图像制作了一个 Jupyter 笔记本*来探测水体的水位。

我们将在 python 中运行水检测算法,并在给定的时间间隔内提取单个水库的地表水位。

你要做的是:

  1. 定义一些水体的几何形状
  2. 准备并执行水探测的完整工作流程:使用 SentinelHub 服务下载 Sentinel-2 数据(真彩色和 NDWI 指数),使用 s2cloudless 云探测器进行云探测,最后探测水
  3. 可视化一段时间内的水体和水位
  4. 过滤掉多云的场景以改善结果

你需要什么?

基本终端/文件设置:

和前面的例子一样:之前,为了运行它,您还需要一个 Sentinel Hub 帐户。您可以在 Sentinel Hub 网页创建一个免费试用账户。帐户设置好后,登录 Sentinel Hub Configurator 。默认情况下,您已经拥有了带有实例 ID (长度为 36 的字母数字代码)的默认配置。对于本教程,我们建议您创建一个新的配置("Add new configuration")并将配置设置为基于 Python 脚本模板。这种配置将已经包含这些示例中使用的所有层。否则,您必须自己为您的配置定义层。准备好配置后,请按照配置说明将配置的实例 ID 放入sentinelhub包的配置文件中。

通过加载以下 Python 库来设置 Python 工作环境。确保按照上面的说明运行 Python 虚拟环境

获得水体的几何形状

让我们以南非的 Theewaterskloof 大坝为例——这个巨大的水资源储备为开普敦 400 万居民中的大部分人提供了宝贵的资源。它是西开普省供水系统中最大的水坝,在干旱时水量会减少。有迹象表明人们对水资源短缺的意识增强了。如何覆盖这样一个话题说明了这个例子

the waters kloof Dam或地球上任何其他大型水体的情况下,你可以通过BlueDot Water ObservatoryAPI 轻松获得几何图形。

通过搜索特定水体,您可以复制 URL 中的ID号,以便访问相应水体的标称几何形状(即 url [https://water.blue-dot-observatory.com/38538/2019-02-05](https://water.blue-dot-observatory.com/38538/2019-02-05))中的38538))

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

The BlueDot Water Observatory

用于下载几何图形的 Python 代码:

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

现在,为了下载 Sentinel-2 数据,我们需要这个几何体的边界框。我们定义了一个边界框,并对其进行了一点膨胀,以构建一个 BBox 对象,用于 Sentinel Hub 服务。BBox 类也接受坐标系(CRS),这里我们使用与几何图形相同的坐标系(即 WGS84 )。

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

Plotting the BBox and the geometry

准备/执行水检测的完整工作流程

哨兵枢纽服务安装有eo-learn。它是 Python 中用于机器学习的开源地球观测处理框架,提供无缝访问和处理任何卫星舰队获取的时空图像序列的能力。

eo-learn以工作流的形式工作——工作流由一个或多个任务组成。每个任务完成一个特定的工作(下载数据,计算波段组合等。)在一个区域的一小片上,叫做 EOPatch。EOPatch 是 EO 和非 EO 数据的容器。

让我们定义一个工作流来下载和获取水检测所需的数据。我们将下载 RGB 波段,以便实际可视化水体的真彩色图像。此外,我们将下载NDWI波段组合(归一化差异水体指数),用于水体检测。它被定义为

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

Formula for Normalized Difference Water Index

其中 B3 和 B8 分别是绿色和近红外哨兵-2 波段。

**Next: Definitions of some custom tasks that will be used in the workflow**
**Initializations of EOTasks:**
Output: Finished loading model, total used 170 iterations
Output: CPU times: user 3min 9s, sys: 14.7 s, total: 3min 24s
Wall time: 3min 23s

“EO patch”的结构

通过键入来检查结构

Input: eopatch

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

现在让我们来看一下给定时间序列中所选水体的前几张真彩色图像。我们在下面看到一些图像包含云,这导致了正确的水位检测问题。

**Plot the NDWI to see how the water detector traces the waterbody outline:**

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

Plotting of Normalized Difference Water Index

**Plot true-color images with the detected water outlines:**

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

Clear as day: comparing true water levels with Theewaterskloof Dam dam’s outline

**Plotting the detected water levels**

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

由于云的干扰,您应该会看到数据中有很多波动(灰色表示云的覆盖范围。它与水位异常值共享相同的日期)。

现在让我们设定一个最大云量为 2 %的阈值,并过滤掉对应于多云场景的日期。这是通过过滤掉值eopatch.scalar['COVERAGE']大于 0.02 的日期来完成的。

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

A lot less vacillating

瞧,这就是 T2。水位在 2018 年年中创下三年来的历史新低,但此后逐渐恢复。

结论:

仍然渴望更多的卫星图像分析?我在这里介绍了一些与经济夜灯分析相关的基本技术(它充当了经济增长的代理)。99 . Gisgeography.com 汇集了其他应用设想,列举如下。请自便。

c

本教程由一名调查记者撰写,并得到了 Matic Lubej **、**在 @sinergise的数据科学家、遥感布道者 Pierre MarkuseBenjamin Strick的友好支持,Benjamin Strick 是 BBC 的一名开源调查员,也是 EUArms 工作室的讲师。

如何使用光学字符识别进行安全系统开发

原文:https://towardsdatascience.com/how-to-use-optical-character-recognition-for-security-system-development-9dc57258afa3?source=collection_archive---------14-----------------------

用于身份证件数据识别的深度学习和计算机视觉。

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

将机器学习技术应用于安全解决方案是当前 AI 趋势之一。本文将介绍使用深度学习算法开发基于 OCR 的软件的方法。该软件可用于分析和处理身份证明,如美国驾照,作为验证身份的安全系统的一部分。

机器学习公司已经在使用 OCR(光学字符识别)技术进行业务流程自动化和优化,使用案例从 Dropbox 使用它解析图片到谷歌街景识别不同的街道标志到搜索短信和实时翻译文本。

在这种特殊情况下,OCR 可以用作自动化
生物特征验证系统的一部分。该解决方案使用自拍照片,并与包含从驾驶执照中提取的面部特征(面部嵌入)的数据库进行比较。

OCR 过程使用以下数据:

  • 一张与官方身份照片对比的自拍照。
  • 驾照正面的照片,用于检测脸部。
  • 包含条形码的驾驶执照背面的图片,我们从中获取数据,如出生日期、姓名和其他字段。

在 beta 测试中,很明显用户能够欺骗验证过程。一种方法是传递来自多个文档的图片。用户展示的第一张照片是有效的身份证明,但第二张背面的照片包含虚假信息。对于任何现实世界的实施来说,欺诈企图都是已知的,并且已经创建了一个独立的验证系统来防止欺骗企图。它交叉检查代表 ID 两侧的两张图片,以确认匹配或标记差异。

决定最佳 OCR 解决方案

一旦阐明了用例的范围,我们就开始使用光学字符识别 SDK 和 API。OCR 解决方案有多种形式,从开源到商业的现成解决方案。

人们可能会认为简单的方法是最好的,在这种方法中,可以实现顶级的商业 OCR 解决方案来读取图片并处理相关信息。但是这并不是一个有效的方法。

OCR 的用户友好性和安全性问题

一个重大挑战是,身份证上的照片和自拍照片有时会有明显的定位和质量差异。这是用不同的相机和工艺拍摄不可避免的后果。

如果系统在查找匹配时要求高的准确性阈值,大量合法的照片将被拒绝,这可能导致用户体验的问题。需要在保持高安全标准的同时将错误拒绝保持在最低限度之间取得平衡。

解决这个问题的一个方法是提高用户提交的自拍照的质量。通过创建一个平滑的用户界面/UX 体验以及一套易于遵循的拍照说明,自拍照片的质量可以大大提高。

一旦用户提交的图片变得标准化,就有可能在用户友好性和安全性之间取得更好的平衡。虽然许多基于计算机视觉的 OCR 解决方案可以被描述为一个“黑盒”,但这个解决方案需要原始数据才能运行。

驾照数据识别的挑战

美国的每个州都会创建一个独特的驾照格式,这些格式会定期更改。因此,不可能简单地预先生成用于解析许可证的模板。另一个障碍是驾照照片的质量经常很差。任何使用它们的 OCR 解决方案都必须考虑这些问题。

任何使用 CV 和 ML 的 OCR 系统都会产生错误。对于这个系统,有必要创建一个安全可靠的解决方案,能够处理与 OCR 组件配对的低质量图片。因此,DS 和软件工程团队都参与了开发过程。

为了规划任何基于人工智能的解决方案的开发,有必要回答几个基本问题。首先,强制性的数据要求是什么,可用数据的使用方式是什么?

我们开始对大约 150 个 id 和 100 个驾照进行数据挖掘,这些数据来自现有的公开数据集和我们收集的数据。

在初始阶段,对现有的开源和商业 OCR 系统进行了比较和评估。选择了最适合的 OCR 解决方案的短列表,并使用真实数据集对这些系统进行了评估。

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

研究过程中跟踪的指标是出生日期、姓名和姓氏的直接匹配,谷歌视觉是这一过程的自然选择。

评估大型开放数据集

另一种方法可能是尝试用书籍扫描或包含文本的图片来处理大型开放数据库。然而,这种方法不适合处理驾照的独特任务。考虑到驾照模板的可变性以及随之而来的低质量照片,许多原本适用的 OCR 解决方案根本无法胜任这项任务。需要完美对齐的文本和优秀图片才能运行的 OCR 解决方案在这方面将会失败。

解析驾照和其他 id 的实际任务给出了解决方案适用性的最真实指标。最佳数据集是根据目标受众的任务专门收集的数据集。

实现 OCR 引擎

符合数据安全的 OCR 解决方案需要一种结合 ds、ML 和软件工程的方法。

一个主要挑战是处理 Google Vision 提供的原始数据,并以 100%的准确度将其与条形码提供的数据进行交叉引用。虽然谷歌的 OCR 系统是行业顶级的,但错误是不可避免的。虽然许多情况下允许出现错误,但在与安全相关的领域中,这些错误不会出现。这种 OCR 解决方案需要额外的安全层来挫败利用 OCR 的局限性进行欺诈的企图。

对机器可读区的额外关注

MRZ(机器可读区)是任何旅行证件的一部分,具有清晰的数据字段,无论是数字还是字母。MRZ 还会有校验位,以确保数据被准确解析。

然而,即使使用谷歌视觉,MRZ 识别能够达到的准确度值也远低于 100%。因此,有必要创建一个额外的数据交叉检查流程。

OCR 在读取数据时容易犯一些常见的错误。一个例子是符号“1,l,I,I”和“O,D,Q,0”。这些符号在物理上是相似的,可能会被引擎错误分类。通过收集历史错误数据,可以构建一个组件来纠正 OCR 系统造成的错误。

总之,使用 OCR 的四个技巧:

  1. 首先确定系统需要能够实现的所有用例以及业务目标。这推动了您选择工具和系统架构的方法。
  2. 了解您的数据并使用尽可能多的真实数据至关重要。
  3. 一旦理解了数据的基本原理,您就可以做出明智的决定,决定是使用商业数据集还是开放数据集。
  4. 在训练神经网络和创建自定义数据科学模型时,最好在较小的数据集中使用更相关的数据。虽然使用大规模数据集可能看起来很有吸引力,但如果它不能很好地反映您最终的真实数据,您的结果将是无效的。
  5. 基于深度学习的 OCR 可以作为初步工具,将提供的信息与用户文档进行比较开发多模态生物特征认证系统

如何以正确的方式使用熊猫来加速你的代码

原文:https://towardsdatascience.com/how-to-use-pandas-the-right-way-to-speed-up-your-code-4a19bd89926d?source=collection_archive---------9-----------------------

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

Just a Panda, chillin’

想获得灵感?快来加入我的 超级行情快讯 。😎

熊猫图书馆对数据科学界来说是一份天赐的礼物。问任何一个数据科学家他们喜欢如何用 Python 处理他们的数据集,他们无疑会谈论熊猫。

Pandas 是一个优秀编程库的缩影:简单、直观、功能广泛。

然而,在熊猫数据帧上进行数千甚至数百万次计算,这是数据科学家的常规任务,仍然是一个挑战。你不能只是把你的数据扔进去,写一个 Python for-loop,然后期望你的数据在合理的时间内得到处理。

Pandas 是为一次处理整行或整列的矢量化操作而设计的——遍历每个单元格、行或列根本不是该库的设计用途。因此,当使用 Pandas 时,你应该从高度并行化的矩阵 运算的角度考虑问题。

本指南将教你如何使用熊猫的设计方式,并根据矩阵运算进行思考。在这个过程中,我将向您展示一些实用的节省时间的技巧和诀窍,它们将使您的熊猫代码运行得比那些可怕的 Python for-loops 快得多!

我们的设置

在整个教程中,我们将使用经典的鸢尾花数据集。让我们开始用 seaborn 加载数据集,并打印出前 5 行。

厉害!

现在让我们建立一个基线,用 Python for-loop 来测量我们的速度。我们将通过循环遍历每一行来设置要在数据集上执行的计算,然后测量整个操作的速度。这将为我们提供一个基线,看看我们的新优化对我们有多大帮助。

在上面的代码中,我们创建了一个基本函数,使用 If-Else 语句根据花瓣长度选择花的类别。我们编写了一个 for 循环,通过遍历数据帧将函数应用于每一行,然后测量循环的总运行时间。

在我的 i7–8700k 的机器上,在 5 次运行中,循环平均花费了 0.01345 秒。

循环使用。iterrows()

我们可以马上做的最简单但非常值得的加速是使用 Pandas 内置的.iterrows()功能。

当我们在前一节中编写 for 循环时,我们使用了range()函数。然而,当我们在 Python 中循环大量的值时,生成器往往要快得多。你可以在本文这里阅读更多关于发电机如何工作并使事情变得更快的信息。

Pandas 的.iterrows()函数在内部实现了一个生成器函数,它将在每次迭代中yield一行数据帧。更准确地说,.iterrows()为数据帧中的每一行生成(index,Series)对(元组)。这实际上与在原始 Python 中使用类似于enumerate()的东西是一样的,但是运行起来要快得多

下面我们修改了代码,使用.iterrows()代替常规的 for 循环。在我在上一节中用于测试的同一台机器上,平均运行时间是 0.005892 秒——加速了 2.28 倍!

完全丢弃循环。应用()

这个.iterrows()函数让我们的速度有了很大的提升,但是我们还远远没有完成。永远记住,当使用一个为向量运算设计的库时,可能有一种完全不用 for 循环就能最有效地做事的方法。

为我们提供这种能力的 Pandas 函数是.apply()函数。我们的函数.apply()将另一个函数作为其输入,并沿着数据帧(行、列等)的轴应用它。在我们传递函数的情况下,lambda 通常可以方便地将所有东西打包在一起。

在下面的代码中,我们用.apply()和一个 lambda 函数完全替换了我们的 for 循环,以打包我们想要的计算。在我的机器上,这段代码的平均运行时间是 0.0020897 秒,比我们原来的 for 循环快了 6.44 倍。

.apply()快得多的原因是它在内部试图循环遍历 Cython 迭代器。如果你的函数恰好针对 Cython 进行了优化,.apply()将会给你带来更大的速度提升。额外的好处是,使用内置函数会产生更干净、更易读的代码

最终剪辑

之前我提到过,如果你正在使用一个为矢量化运算设计的库,你应该总是寻找一种不使用 for 循环的方法来进行任何计算。

类似地,许多以这种方式设计的库,包括 Pandas,将有方便的内置函数来执行你正在寻找的精确计算——但要快得多。

Pandas 的.cut()函数将一组定义 If-Else 的每个范围的bins和一组定义每个范围返回哪个值的labels作为输入。然后,它执行与我们用compute_class()函数手动编写的完全相同的操作。

查看下面的代码,看看.cut()是如何工作的。我们再次得到了更干净、更易读的代码的好处。最终,.cut()函数平均运行时间为 0.001423 秒——比原来的 for-loop 快了 9.39 倍!

喜欢学习?

在推特上关注我,我会在这里发布所有最新最棒的人工智能、技术和科学!也请在 LinkedIn上与我联系!

如何用熊猫分析数值型数据?

原文:https://towardsdatascience.com/how-to-use-pandas-to-analyze-numeric-data-9739e0809b02?source=collection_archive---------10-----------------------

这比你想象的要容易得多。

Python 已经成为数据科学领域一种流行的编程语言。Pandas 是数据科学中许多受欢迎的库之一,它提供了许多帮助我们转换、分析和解释数据的强大功能。我确信已经有太多的教程和资料教你如何使用熊猫。然而,在这篇文章中,我不仅仅是教你如何使用熊猫。相反,我想用一个例子来演示如何在熊猫的帮助下正确流畅地解读你的数据。

熊猫大战熊猫

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

Photo by Ilona Froehlich on Unsplash

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

在我们开始之前:

  1. 准备一个 python 环境

  2. 从 Kaggle 下载数据集

  3. 进口熊猫

  4. 准备一个 python 环境

既然我们使用 Python 来分析数据,当然首先我们需要安装 Python。对于初学者,我强烈建议您安装 Anaconda,因为 Anaconda 已经预装了一系列对数据科学非常有用的库。你不需要关心编译器或 IDE。

这里是免费下载 Anaconda 发行版的链接

去下载

Jupyter Notebook 是一个很好的数据分析工具,因为你可以一部分一部分地看到结果,这样你就可以知道结果是否是你预测的,你也可以立即知道你是否犯了任何错误。

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

Jupyter Notebook in Anaconda Distribution

启动 Jupyter Notebook 后,会弹出一个网页,你会看到这样的页面。您可以选择并创建存储文件的路径。在右边,有一个“新建”按钮。单击此处创建文件夹或 Python 文件。

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

Jupyter 笔记本提供的有用功能和快捷方式太多了。我在这里不做详细描述和解释。另外,我希望你已经掌握了一些编写 Python 代码的基础知识,因为这不是对 Python 的介绍。不管怎样,如果你有任何问题,请随意评论,我会解决你的问题。

2.从 Kaggle 下载数据集

本文将使用的数据集来自 Kaggle。该数据集包括 1985 年至 2016 年不同国家的自杀率及其社会经济信息。

下载链接

3.进口熊猫

最后准备,进口熊猫

通常我们会给每个库一个缩写。你可以跳过这一步,但每次当你想使用任何功能时,你必须输入完整的名称。所以为什么不给它一个简短的缩写。

虽然这篇文章关注的是使用熊猫,但是我们仍然需要 numpy 的帮助,所以我们也将导入 numpy。

我们开始吧

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

第一步是导入我们从 Kaggle 下载的数据集。虽然您可以从任何路径导入数据,但我的建议是将所有数据和代码放在一起,这样您就不需要键入确切的路径,而只需键入文件名。下载的文件名是“master.csv”。所以我们知道数据集是 csv 文件类型。其他常见的文件类型包括 excel 文件和 json。

熊猫我们用的第一个熊猫函数是 read_csv。称为数据的数据帧是通过以下方式创建的:

data= pd.read_csv('master.csv')

我们可以使用它将 csv 文件导入到 python 中,并将其存储为数据帧。Dataframe 就像一个 excel 表格。

通常情况下,pandas 会自动解释数据集并识别所有必要的参数,以便正确导入数据集。但是,如果您发现输出不像您期望的那样,您可以手动更改参数。以下是使用 read_csv 时可以修改的一些常见参数:

  1. sep:用于分隔变量间值的分隔符。默认使用逗号’,'。您可以更改 sep,如下所示
data = pd.read_csv('master.csv', sep = ';')

2.header:通常 csv 文件的第一行显示所有变量的名称。但是,如果在 csv 文件中没有这样的名称行,最好告诉 pandas 没有标题

header = None

现在您已经导入了数据集。如前所述,您可以在运行代码后直接看到结果。让我们来看看数据集

data

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

我希望你会得到和我一样的结果。现在当你向下滚动时,你可以看到一个数字,但不是所有的记录。如果您不想显示这么多记录,您可以通过键入来显示一些顶部或底部的记录

data.head(5) # showing top 5 records from the dataframe# ordata.tail(5) # showing bottom 5 records from the dataframe

在进行任何分析之前,了解数据集是必要的,因为首先这将使您有一个简要的了解,其次这将防止您在分析时产生误解。

导入后您可能会问的第一个问题是数据集中有多少条记录。幸运的是,您可以通过一行代码得到答案。

data.shape

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

第一个数字(index 0,python 从零开始)显示了行数,第二个数字(index 1)显示了列数。因此数据集有 27,820 行和 12 列。

你可能会问的第二个问题是这 12 列是什么。有很多方法可以显示列名。但是我最喜欢的是用

data.info()

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

info()不仅为您提供数据帧中的所有列名,还为您提供存储在该数据帧中的数据类型。此外,您可以知道数据帧中是否有丢失的值。如上所示,number 列显示了该变量中有多少个非空计数。除人类发展指数外,这一年的所有指数都是 27,820。因此,至少我们知道导入的数据集中有缺失值。

现在你想知道这个数据帧里有什么数据。例如,在那些几乎 28k 的记录中有多少个国家?你想得到所有国家的列表。您可以通过以下方式获得每列的值

data['country']

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

但是这将返回没有重复数据删除的所有值。如果你想得到一个独一无二的国家,我最喜欢的方法是使用 set 函数。Set 函数将只返回一个没有重复的唯一值列表。

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

总共有多少个国家?

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

总共有 101 个国家。

然后你想知道每年自杀的人数。在 Excel 中,您可以通过透视表来执行此操作。熊猫也有类似的功能,叫做 pivot_table。假设你现在使用 excel 数据透视表来计算自杀人数。您将把 year 拖到行标签上,并将 sudience _ no 拖到 Values 上

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

如果您熟悉 excel 数据透视表,那么请记住与 pandas pivot_table 相同的格式。

data.pivot_table(index='year',values='suicides_no',aggfunc='sum')

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

哦,你也想分解成性?

data.pivot_table(index='year',columns='sex',values='suicides_no',aggfunc='max')

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

这里的“index”表示要放在行标签中的变量;“columns”表示列;“值”表示数据透视表中的数字。就像 excel 一样,你可以计算总和、平均值、最大值或最小值。

data.pivot_table(index='year',columns='sex',values='suicides_no',aggfunc=['sum','mean','max','min'])

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

您还可以对行或列执行多重索引。

data.pivot_table(index=['country','year'],columns='sex',values='suicides_no',aggfunc=['sum'])

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

通过使用数据透视表,我们可以根据不同的变量了解数据集的一般分类。您还可以发现数据集中的任何异常,这可能有助于您进一步的分析。就像下面这样:

data.pivot_table(index=['year'],columns='sex',values='suicides_no',aggfunc=['sum'])

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

2016 年发生了什么?为什么会突然下降?

现在你想检查数据集,看看 2016 年会发生什么。在 pandas 中,您需要指定要返回的行和列。这可以通过提供索引号或名称或标准来实现。现在的标准是 2016 年。您可以通过以下方式获得结果

data[data['year']==2016]

如何解读这行代码?

有两部分。内部分“数据[‘年份’]==2016”是需要满足的条件。这里表示数据中的年份列必须是 2016 年。小心有两个等号,代表比较。类似地,你可以有一个更大、更小或不相等的条件

data['year'] >= 2016 # larger than or equal to 
data['year']!=2016 # not equal to

条件多,没问题。但是,如果你想满足全部或其中一个条件,请确保你明确说明。

# year must be larger than 2010 and smaller than 2015
(data['year'] > 2010) & (data['year']<2015)# year can be larger than 2010 or smaller than 2000
(data['year'] > 2010) | (data['year']<2000)

外部部分“data[…]”表示返回内部部分中满足条件的所有行。回到示例,我们希望返回年份等于 2016 年的所有行。

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

似乎没问题。但如果算上 2016 年和 2015 年的国家数量,问题就出现了。

现在,我们想从数据集中获取列 country,其年份必须是 2016 年。最简单的方法是用

data[data['year']==2016]['country']

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

然后再次使用 set 和 len 函数计算 2016 年的国家数量。

len(set(data[data['year']==2016]['country']))

在 2015 年做同样的事情。我们来了

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

2016 年的数据显然不完整,因此我们不应将 2016 年与其他年份进行比较。所以我们最好删除 2016 年的所有记录。

如上所述,我们可以应用一个条件来过滤 2016 年的记录,如下所示:

data2= data[data['year']!=2016]

现在,我们创建另一个名为“data2”的数据帧,用于进一步分析。

找到哪些变量与数据集相关至关重要,因为这可以帮助您发现哪些变量会导致结果的变化。例如,在数据集中有一些分类变量:

国家、年份、性别和世代

选一个简单的,比如性。你可以比较一下每种性别的总自杀人数。如果差异很大,那么性别是导致自杀差异的一个因素

当然,我们可以使用 pivot_table 函数来实现。但是我在这里介绍另一个功能,groupby。如果你有使用 SQL 的经验,我相信你对 group by 很熟悉。

data2.groupby('sex').agg({'suicides_no':'sum'})

就 SQL 而言,上述语句相当于:

select sex, sum(suicides_no) from data2 group by sex

Python 将首先根据“性别”列中的值对所有记录进行分组。之后 python 会计算每组‘性’的自杀总数。

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

男性自杀率远高于女性自杀率。这时,我们可以相当肯定,性别是影响自杀人数的一个因素。

groupby 的高明之处在于,您可以再次将数据集分成更多级别。请记住,当您包括多个级别时,您需要使用方括号[ ]向熊猫提供一个列表。

data2.groupby(['sex','generation']).agg({'suicides_no':'sum'})

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

此外,就像 SQL 一样,您可以在 groupby 函数中执行多个聚合。

data2.groupby(['sex']).agg({'suicides_no':['sum','max']})

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

或者

data2.groupby(['sex']).agg({'suicides_no':'sum', 'population':'mean'})

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

现在我们知道性是一个因素。那年龄呢?

data2.groupby(['age']).agg({'suicides_no':'sum'})

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

所以自杀最流行的年龄范围是 35-54 岁。对吗?

不完全是。不像性是一半一半,每个年龄组的人口都不均匀。这是一种常见误解,因为不同的类别有不同的人口规模或基数。

因此,为了更好地进行比较,我们应该更好地比较每个总人口的自杀人数。为了在熊猫中做到这一点,首先创建另一个数据框架来存储每个年龄层的自杀人数和人口。然后计算一个除法,得到每个年龄段的平均自杀人数。

# create a dataframe called data_age for age groupby 
data_age = data2.groupby([‘age’]).agg(
{‘suicides_no’:’sum’,’population’:’sum’})# calculate average of suicide number for each age group 
data_age[‘suicides_no’]/data_age[‘population’]

代码的第一部分与前面类似。第二部分是执行除法。python 的好处是可以将计算作为一整列来执行,而不是像 excel 那样逐个单元格地执行。所以我们把自杀人数一栏和人口一栏分开。

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

现在结果不同了。随着年龄的增长,自杀的情况变得更糟。

这时,你可能会说排名不明确,你想根据平均自杀人数来排列结果。那么是时候引入 sort_values 函数了。

(data_age['suicides_no']/data_age['population']).sort_values()

因为这里只有一列,所以我们不需要指定按哪一列排序。但是,如果数据帧中有多列,则必须指定哪一列。此外,默认顺序是升序,您可以通过在括号内添加 ascending = False 来更改它。就像下面这样:

(data_age['suicides_no']/data_age['population']).sort_values(ascending=False)

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

现在你可以很容易地看到随着年龄增长的趋势。

我们已经研究了性别和年龄的影响。现在我们转到乡下。我们可以找到哪个国家更流行自杀。

第一步是创建一个表格,包括各国自杀人数和人口。这可以通过使用 groupby 函数来完成。

data_country = data2.groupby(['country']).agg({'suicides_no':'sum','population':'sum'})

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

在这里,我们不关心是否所有国家都有相同数量的记录,因为我们正在计算一段时间内的平均数。

然后我们用自杀人数除以人口来计算平均自杀人数。

data_country['average_suicide'] = data_country['suicides_no']/data_country['population']

这里我们创建了一个名为“average_suicide”的新列,它将存储除法结果。稍后使用 sort_values 函数以降序获得结果。我们可以使用 head 函数只显示前 N 个国家,而不是显示所有国家

data_country.sort_values(by='average_suicide',ascending=False).head(10)

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

从结果中,我们可以看到大多数国家在东欧。那么你可以说地理位置也是影响自杀的一个指标。

今天到此为止。我希望你不仅能学会如何使用 Python,还能学会如何处理数据集,从而得出更好、更准确的结论。

欢迎评论,这样我就知道如何改进和写一个更好的博客。如果你喜欢,就鼓掌,分享给和你一样同样有需要的人。下次见。

如何将 Pipenv 与 Jupyter 和 VSCode 一起使用

原文:https://towardsdatascience.com/how-to-use-pipenv-with-jupyter-and-vscode-ae0e970df486?source=collection_archive---------4-----------------------

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

Activating the right environment in VSCode for Jupyter Notebook

更新 2021

本文写于 2019 年。在多年的开发过程中,我遇到了 pipenv 设置的各种问题。我将环境和依赖管理改为使用一个 conda 环境和一个带有 pip-compile 的需求文件。在我的新文章“如何开始一个数据科学项目https://towards data science . com/How-to-start-a-data-science-project-boilerplate-in-2021-33d 81393 e50中描述了我的最新设置

如果你还想用 pipenv,那么这篇文章应该还是有价值的。享受吧。

介绍

目前,我在 JKU 大学学习人工智能,对于一些练习,我们需要使用 jupyter 笔记本。使用 Python 一点点之后,包管理器 pipenv 被证明是有价值的。现在,我在 Jupyter 笔记本和 VSCode 中使用它时遇到了一些问题。因此,一个简短的指导我如何解决它。

目录

问题

正如我在上一篇文章使用 Jupyter 和 VSCode 中所描述的,我使用 pyenv 和 pipenv 来管理我的 python 开发中的所有包。我还参考了一些文章,为什么这种方式是有帮助的,易于使用。现在,有必要再深入一点。有两种方法可以让你用 jupyter notebook 进行开发。您可以直接在浏览器中或在 VSCode 中使用它。在这两种用例中,都会出现问题。

在浏览器中用 Jupyter 笔记本开发

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

Jupyter Notebook in the browser

假设您的系统上已经有了合适的 python 环境,现在您想为一个项目创建一个特定的环境。

  1. 首先,创建一个 Pipenv 环境。
  2. 确保导航到正确的目录。
  3. 使用pipenv install <packages>来安装你所有的软件包。
  4. 然后用pipenv shell激活你的外壳。
  5. 然后用pipenv install jupyter,之后用pipenv run jupyter notebook

现在 jupyter 服务器已经启动,您的笔记本将可以访问正确的环境。

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

Activating the right environment for Jupyter notebook in the browser

在 VSCode 中用 Jupyter 笔记本开发

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

Jupyter Notebook in VSCode

现在来看看 VSCode 中的工作流。在这里,了解不同的 shells 是很重要的。我经常使用单独的终端(iterm2 ),有时激活的 shell 无法被 VSCode 识别,或者您位于错误的目录中,或者它没有被激活。所有这些都会带来问题。因此我的工作流程如下:

  1. 首先,创建一个 Pipenv 环境。
  2. 确保导航到正确的目录。
  3. 使用pipenv install <packages>来安装你所有的软件包。
  4. 然后,确保在 vscode 文件夹中有一个正确的设置文件,其内容如下:
{
    "python.venvPath": "${workspaceFolder}/.venv/bin/python",
    "python.pythonPath": ".venv/bin/python",
}
  • 之后,您可以在 VSCode 中选择合适的 python 环境。(应该是用 Pipenv 创建的!)现在,python 文件可以识别正确的环境。

通常这对于 VSCode 应该足够了,你可以在其中启动 Jupyter 服务器。

但是有时你改变了环境,或者设置文件有问题。如果是这种情况,您需要打开 VSCode 终端并运行pipenv shell来激活 shell。(检查是否仍在 VSCode 中选择了正确的环境):

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

Activating the right environment in VSCode for Jupyter Notebook

现在打开。ipynb 文件,您将能够运行单元格,而不会得到错误"... was not able to start jupyter server in environment xxx"

如果有帮助,或者在 VSCode 和 Jupyter Notebook 中使用 Pipenv 有其他问题或解决方案,请告诉我。

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

You can support me on https://www.buymeacoffee.com/createdd

关于

我认为自己是一个解决问题的人。我的强项是在复杂的环境中导航,提供解决方案并分解它们。我的知识和兴趣围绕商业法和编程机器学习应用发展。我在构建数据分析和评估业务相关概念方面提供服务。

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

接通:

如何在数据分析项目中使用 Python 特性

原文:https://towardsdatascience.com/how-to-use-python-features-in-your-data-analytics-project-e8032374d6fc?source=collection_archive---------11-----------------------

使用 OO,NumPy,pandas,SQL,PySpark 的 Python 教程

1.介绍

许多公司正在向云迁移,并考虑应该使用什么工具进行数据分析。在内部,公司大多使用专有软件进行高级分析、商业智能和报告。然而,这种工具在云环境中可能不是最合理的选择。原因可能是 1)缺乏与云提供商的集成,2)缺乏大数据支持,或者 3)缺乏对机器学习和深度学习等新用例的支持。

Python 是一种通用编程语言,广泛用于数据分析。几乎所有的云数据平台都提供 Python 支持,并且通常新特性首先在 Python 中可用。在这方面,Python 可以被视为数据分析的瑞士军刀。

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

1. Python as Swiss Army knife for data analytics

2.目标

在本教程中,创建了两个考虑到 Python 重要特性的项目。项目描述如下:

  • 在第一个项目中,在 Azure 中的数据科学虚拟机(DSVM)上执行 Jupyter 笔记本。面向对象(OO)类是使用数据的继承、重载和封装创建的。随后,NumPy 和 pandas 用于数据分析。最后,数据存储在 DSVM 上的数据库中。
  • 在第二个项目中,Databricks 笔记本在具有多个虚拟机的 Spark 集群上执行。PySpark 用于创建机器学习模型。

因此,将执行以下步骤:

  • 3.先决条件
  • 4.DSVM 上带有 Jupyter 的 OO、NumPy、pandas 和 SQL
  • 5.Spark 集群上带有 Azure 数据块的 PySpark
  • 6.结论

这是一个独立的教程,重点是学习 Python 的不同方面。重点不在于“深入”各个方面。如果你对深度学习更感兴趣,请参见这里或在 devops for AI,参考我以前的博客,这里和关注安全,请参见这里

3.先决条件

需要创建以下资源:

4.DSVM 上带有 Jupyter 的 OO、NumPy、pandas 和 sql

在这一部分中,一个包含三个类的示例 Python 项目。使用这些类,足球运动员的数据被登记。执行以下步骤:

  • 4a。开始
  • 4b。面向对象编程
  • 4c。使用 NumPy 的矩阵分析
  • 4d。使用熊猫进行统计分析
  • 4e。读取/写入数据库

4a。开始

登录到您的 Windows 数据科学虚拟机(DSVM)。在桌面上,可以找到预装组件图标的概述。点击 Jupyter 快捷方式开始 Jupyter 会话。

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

4a1. preinstalled components on DSVM needed in this tutorial

随后,打开可以在任务栏中找到的 Jupyter 命令行会话。复制 URL 并在 Firefox 会话中打开它。

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

4a2. Localhost URL to be openen in Firefox

然后将以下笔记本下载到 DSVM 的桌面上:

[https://raw.githubusercontent.com/rebremer/python_swiss_army_knife/master/SwissArmyKnifePython.ipynb](https://raw.githubusercontent.com/rebremer/python_swiss_army_knife/master/SwissArmyKnifePython.ipynb)

最后,选择在 jupyter 会话中上传笔记本。然后点击菜单中的运行按钮,运行单元格中的代码。笔记本最重要的部分也将在本章的剩余部分讨论。

4b。面向对象编程

这部分教程的灵感来自 Theophano Mitsa 的教程。在这一部分中,创建了三个类来跟踪足球运动员的数据。一级球员的片段可以在下面找到:

# Class 1: Player
class Player(object):
    _posList = {'goalkeeper', 'defender', 'midfielder', 'striker'}

    def __init__(self,name):
        self._playerName=name
        self._trainingList=[]
        self._rawData = np.empty((0,3), int)

    def setPosition(self, pos):
        if pos in self._posList:
            self._position=pos
            print(self._playerName + " is " + pos)
        else:
            raise ValueError("Value {} not in list.".format(pos))        

    def setTraining(self, t, rawData):
        self._trainingList.append(t)
        self._rawData = np.append(self._rawData, rawData, axis=0) def getTrainingRawData(self):
        return self._rawData #def getTrainingFilter(self, stage, tt, date):
    # see github project for rest of code

在这个类中可以看到以下内容:

  • 一个 _rawData 属性在新玩家被实例化时被创建。该属性用于用 setTraining 方法封装训练数据
  • _rawData 被创建为受保护的变量。这告诉程序员应该使用 get 和 set 方法来处理 _rawData

随后,可以在下面找到 FirstTeamPlayer 类:

# Class 2: FirstTeamPlayer
class FirstTeamPlayer(Player):
    def __init__(self,ftp):
        Player.__init__(self, ftp)

    def setPosition(self,pos1, pos2):
        if pos1 in self._posList and pos2 in self._posList:
            self._posComp=pos1
            self._posCL=pos2
            print(self._playerName + " is " + pos1)
            print(self._playerName + " is " + pos2 + " in the CL")
        else:
            raise ValueError("Pos {},{} unknown".format(pos1, pos2))   

    def setNumber(self,number):
        self._number=number
        print(self._playerName + " has number " + str(number))

在这个类中可以看到以下内容:

  • FirstTeamPlayer 从 Player 类继承了,这意味着 Player 类的所有属性/方法也可以在 FirstTeamPlayer 中使用
  • 方法 setPosition 在 FirstPlayerClass 中被重载,并有了新的定义。方法 setNumber 仅在 FirstPlayerClass 中可用

最后,可以在下面找到培训课程的一个片段:

# Class 3: Training
class Training(object):
    _stageList = {'ArenA', 'Toekomst', 'Pool', 'Gym'}
    _trainingTypeList = {'strength', 'technique', 'friendly game'}

    def __init__(self, stage, tt, date):
        if stage in self._stageList:
            self._stage = stage
        else:
            raise ValueError("Value {} not in list.".format(stage))
        if tt in self._trainingTypeList:
            self._trainingType = tt
        else:
            raise ValueError("Value {} not in list.".format(tt))

        #todo: Valid date test (no static type checking in Python)
        self._date = date

    def getStage(self):
        return self._stage

    def getTrainingType(self):
        return self._trainingType

    def getDate(self):
        return self._date

在这个类中可以看到以下内容:

  • Python 中没有静态类型检查**。例如,日期属性不能声明为日期,必须创建一个附加检查**

这三个类是如何实例化和使用的示例可以在下面的最终代码片段中找到:

# Construct two players, FirstTeamPlayer class inherits from Player
player1 = Player("Janssen")
player2 = FirstTeamPlayer("Tadic")# SetPosition of player, method is overloaded in FirsTeamPlayer
player1.setPosition("goalkeeper")
player2.setPosition("midfielder", "striker")# Create new traning object and add traningsdata to player object. 
training1=Training('Toekomst', 'strength', date(2019,4,19))
player1.setTraining(training1, rawData=np.random.rand(1,3))
player2.setTraining(training1, rawData=np.random.rand(1,3))# Add another object
training2=Training('ArenA', 'friendly game', date(2019,4,20))
player1.setTraining(training2, rawData=np.random.rand(1,3))
player2.setTraining(training2, rawData=np.random.rand(1,3))

4c。使用 NumPy 的矩阵分析

NumPy 是使用 Python 进行科学计算的基础包。在本教程中,它将被用来做矩阵分析。请注意,attribute _rawData 已经作为 NumPy 数组封装在 Player 类中。NumPy 通常与 Matplotlib 一起使用来可视化数据。在下面的代码片段中,数据取自玩家类,然后进行一些矩阵运算,从基础到更高级。完整的例子可以在 github 项目中找到。

# Take the matrix data from player objecs that were created earlier
m1=player1.getTrainingRawData()
m2=player2.getTrainingRawData()# print some values
print(m1[0][1])
print(m1[:,0])
print(m1[1:3,1:3])# arithmetic
tmp3=m1*m2 # [m2_11*m1_11,  ..,  m1_33*m2_33]
print(tmp3)# matrix multiplication
tmp1 = m1.dot(m2) # [m1_11 * m2_11 + m1_23 * m2_32 +  m1_13 * m2_31, 
                  #   ..., 
                  # m1_31 * m2_13 + m1_23 * m2_32 +  m1_33 * m2_33]
print(tmp1)# inverse matrix
m1_inv = np.linalg.inv(m1)
print("inverse matrix")
print(m1_inv)
print(m1.dot(m1_inv))# singular value decomposition
u, s, vh = np.linalg.svd(m1, full_matrices=True)
print("singular value decomposition")
print(u)
print(s)
print(vh)

4d。使用熊猫进行统计分析

Pandas 是 Python 中高性能、易于使用的数据结构和数据分析工具的包。在幕后,pandas 使用 NumPy 作为它的数组结构。在本教程中,它将用于计算一些基本的统计数据。在下面的代码片段中,数据取自 player 类,然后进行一些统计操作。完整的例子可以在 github 项目中找到。

# Create the same matrices as earlier
m1=player1.getTrainingRawData()
m2=player2.getTrainingRawData()# create column names to be added to pandas dataframe
columns = np.array(['col1', 'col2', 'col3'])

# Create pandas dataframe
df_1=pd.DataFrame(data=m1, columns=columns)
df_2=pd.DataFrame(data=m2, columns=columns)# calculate basic statistics col1
print(df_1['col1'].sum())
print(df_1['col1'].mean())
print(df_1['col1'].median())
print(df_1['col1'].std())
print(df_1['col1'].describe())# calculate correlation and covariance of dataframe
tmp1=df_1.cov()
tmp2=df_1.corr()

print("correlation:\n " + str(tmp1))
print("\n")
print("covariance:\n " + str(tmp2))

4e。读取/写入数据库

最后,数据将被写入 SQL 数据库。在本教程中,使用了作为 DSVM 一部分的 MSSQL 数据库。在任务栏中查找 Microsoft SQL Server Management Studio(SSMS)图标,并启动一个新会话。使用 Windows 身份验证登录,另请参见下文。

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

4e1. SSMS session using Windows Authentication

在菜单中查找“新查询”并开始新的查询会话。然后执行以下脚本:

USE [Master]
GO

CREATE DATABASE pythontest
GO

USE [pythontest]

CREATE TABLE [dbo].[trainingsdata]
(  
 [col1] [float] NOT NULL,
 [col2] [float] NOT NULL,
 [col3] [float] NOT NULL
)
GO

最后,可以将数据写入数据库和从数据库中读取数据。熊猫数据帧将用于此,也见下面的片段。

# import library
import pyodbc# set connection variables
server  = '<<your vm name, which name of SQL server instance >>'
database = 'pythontest'
driver= '{ODBC Driver 17 for SQL Server}'# Make connection to database
cnxn = pyodbc.connect('DRIVER='+driver+';SERVER='+server+';PORT=1433;DATABASE='+database + ';Trusted_Connection=yes;')
cursor = cnxn.cursor()#Write results, use pandas dataframe
for index,row in df_1.iterrows():
    cursor.execute("INSERT INTO dbo.trainingsdata([col1],[col2],[col3]) VALUES (?,?,?)", row['col1'], row['col2'], row['col3'])
    cnxn.commit()#Read results, use pandas dataframe
sql = "SELECT [col1], [col2], [col3] FROM dbo.trainingsdata"
df_1read = pd.read_sql(sql,cnxn)
print(df_1read)
cursor.close()

5.Spark 集群上带有 Azure 数据块的 PySpark

在前一章中,所有的代码都在一台机器上运行。如果产生更多的数据或需要进行更高级的计算(例如深度学习),唯一的可能是采用更重的机器,从而将放大以执行代码。也就是说,计算不能分配给其他虚拟机。

Spark 是一个分析框架,可以将计算分配给其他虚拟机,因此可以通过添加更多虚拟机来横向扩展。这比让一台“超级计算机”做所有的工作要高效得多。Python 可以在 Spark 中使用,通常被称为 PySpark。在本教程中,将使用 Azure Databricks,这是一个针对 Azure 优化的基于 Apache Spark 的分析平台。在这种情况下,执行以下步骤。

  • 5a。开始
  • 5b。项目设置

5a。开始

启动 Azure Databricks 工作区并转到群集。使用以下设置创建新群集:

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

5a1. Create cluster

接下来,选择工作区,右键单击,然后选择导入。在单选按钮中,选择使用 URL 导入以下笔记本:

[https://raw.githubusercontent.com/rebremer/devopsai_databricks/master/project/modelling/1_IncomeNotebookExploration.py](https://raw.githubusercontent.com/rebremer/devopsai_databricks/master/project/modelling/1_IncomeNotebookExploration.py)

另请参见下图:

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

5a2. Import notebook

选择您在 4b 中导入的笔记本,并将该笔记本连接到您在 4a 中创建的集群。确保集群正在运行,否则启动它。使用快捷键 SHIFT+ENTER 逐个单元格地浏览笔记本。

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

5a3. Run notebook

最后,如果你想跟踪模型,创建模型的 HTTP 端点和/或创建项目的 DevOps 管道,请参见我的高级 DevOps for AI 教程这里,关于安全性,请参见这里

5b。项目的设置

在这个项目中,创建了一个机器学习模型,该模型使用年龄、每周工作时间、教育程度等特征来预测一个人的收入阶层。在这种情况下,执行以下步骤:

  • 以 Spark 数据框架的形式接收、探索和准备数据
  • 逻辑回归-使用一周工作时间的 1 个特征
  • 逻辑回归—所有特征(工作时间、年龄、状态等)
  • 逻辑回归—防止过度拟合(正则化)
  • 决策树—不同的算法,找出性能最好的算法

请注意,pyspark.ml 库用于构建模型。也可以在 Azure Databricks 中运行 scikit-learn 库,但是,工作只能由驱动程序(主)节点完成,计算不是分布式的。请看下面使用 pyspark 包的片段。

from pyspark.ml import Pipeline, PipelineModel
from pyspark.ml.classification import LogisticRegression
from pyspark.ml.classification import DecisionTreeClassifier
#...

6.结论

在本教程中,创建了两个 Python 项目,如下所示:

  • Jupyter 笔记本在数据科学虚拟机上使用面向对象编程、NumPy、pandas 进行数据分析,并使用 SQL 存储数据
  • 分布式 Spark 集群上的 Databricks 笔记本,具有多个使用 PySpark 构建机器学习模型的虚拟机

许多公司考虑在云中使用什么工具进行数据分析。在这方面,几乎所有的云数据分析平台都支持 Python,因此,Python 可以被视为数据分析的瑞士军刀。本教程可能会帮助你探索 Python 的可能性。

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

6. Python as Swiss Army knife for data analytics

没有管理权限如何使用 Python

原文:https://towardsdatascience.com/how-to-use-python-without-administrative-right-at-your-workplace-a50ee2ee2267?source=collection_archive---------6-----------------------

现实世界中的数据科学

在您的工作场所或在便携模式下使用

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

Image from freepik.com

从我的经验来看,Python 是一门漂亮的语言。它工作如此之快,简单易学,可以适用于各种领域。我开始使用 Python 学习数据科学,但最近发现它还可以扩展到 web 抓取或自动化机器人编程。通常,大多数工作在我有管理权限的个人笔记本电脑上运行良好。然而,当我试图将这些知识应用到我在工作场所的职责领域时(即,在我公司的没有管理权限的用户工作环境中),他们感到沮丧,并且大多数时候,软件包安装工作不顺利。经过几天的寻找和尝试,我终于找到了一个有效的方法。因此,我相信写这篇博客可以帮助其他人解决我所面临的同样的问题。也就是说,如何在没有管理权限的情况下在工作场所使用 Python。

没有管理权限,我将需要使用软件,可以安装在便携式模式或基于网络的应用程序。我尝试过很多可以用来运行 Python 的便携软件或者云平台。其中包括 AnacondaSublimeTextPortablePythonWinPythonGoogle Colaboratory微软 Azure services 等等。由于我只是彻底尝试了其中的一部分,所以我在这里只提到其中的一部分。

第一个推荐的软件是使用 Anaconda ,因为它附带了大多数有用的便捷包,并且它可以以便携模式直接安装到您的工作机器上,而不需要管理权限。我开始用这个软件是通过 Jupyter 笔记本运行自学的,用了几个月。但是,我不能使用这个 Anaconda 环境安装任何额外的包,比如著名的 XGBoost ML 算法。在 Stackoverflow 上有几个帖子,像这个我已经浏览过了,但是并没有解决问题。归根结底,我似乎需要配置系统路径,但我没有权限这样做。对于 Windows 10,您可以通过控制面板访问此路径配置,并在搜索栏中键入“PATH”。正如您在下面的快照中看到的,我没有更改系统路径的管理权限。我也许可以请 IT 支持人员帮我修改一下,但是应该有一些更好的方法在用户模式下编写 Python 代码。让我们试试其他的选择。

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

PATH configuration in Windows 10

其次,我在 Google 联合实验室尝试过免费的云平台。这只是典型的免费 Jupyter 笔记本环境,不需要设置,完全在云中运行。我可以用!pip install XXX 在我的个人笔记本上安装类似 Jupyter notebook 的新包。对我来说,这在一段时间内相当有效。直到我发现使用这个平台有三个主要缺点。首先,这个 Colab 平台是为间歇用户设计的,因为运行一整套冗长的机器学习模型可能会消耗服务器的大量资源。在我尝试了 2 天的运行时间后,我收到了一些警告消息,要求我降低 GPU 级别,以便将资源让给其他人使用。其次,模型中需要输入的数据需要上传到 Colab 中。虽然它可以很好地与 Google Drive 同步,但这违反了我公司关于数据保留的政策。每一个上传到外部服务器的文件都将被跟踪,我不想仅仅因为这个愚蠢的原因被解雇。第三,由于这个平台在云中工作,一些 GUI 包无法安装。对于我来说,我打算使用 pyautogui 构建一些 BOT 来控制鼠标移动,并使用 keyboard 来帮助我减少一些重复的复制和粘贴任务。这个 Colab 不支持 GUI 控制,因为它在云中没有鼠标或键盘。

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

Google Colab

第三,我试过 SublimeText3 。在未注册版本中使用代码编辑软件是免费的(您需要为注册版本付费,但您可以继续使用免费版本)。这个软件不仅是为 Python 用户设计的,它还可以选择编译哪种语言。它非常好,因为代码编辑模块可以定制,批量编辑,并添加一些代码检查器包。对我来说,它看起来像是真正为开发者而建的。不幸的是,在尝试了几天之后,我无法在不修改系统路径的情况下安装任何额外的软件包。你可以注意到它漂亮的教程视频。

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

https://www.sublimetext.com/

最后,在尝试了几种方法都没有成功之后,我发现 WinPython 可能是一种有用的可移植 Python 编辑器软件方法。在我看来,与 Anaconda 相比,有一些可移植的软件,如 PortablePython 等,它们的根文件夹/安装文件更容易理解,WinPython 对我来说最好。我可以在 WinPythonCommandPrompt for 中使用 pip install 添加新的软件包安装。whl 文件或者我可以解压.tar.gz 文件,放在 WinPython 包根文件夹。与之前解释的两个平台不同,这两种包安装方法都运行良好,我可以使用这个 WinPython 安装 XGboost 和 pyautogui。它在 Jupyter notebook 中工作,不需要任何管理权限,我想让您知道,这是我让 Python 在公司环境中运行的最佳方法,但仍符合数据泄漏预防政策,并且不使用外部云服务器。我也把我的赞成/反对的比较放在这个博客的底部。感谢您的阅读。有什么建议可以随意评论。

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

Jupyter notebook running from WinPython

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

提升你的正则表达式技能

原文:https://towardsdatascience.com/how-to-use-regex-7aeaf4dd25e9?source=collection_archive---------15-----------------------

为了乐趣和利益的正则表达式

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

正则表达式名声不好。它们很硬,不透明,会打碎东西。

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

They even broke Stack Overflow.

依赖内置模块进行字符串匹配对于某些任务来说是不错的,但是您将错过编写自己的正则表达式所带来的强大功能和灵活性。(如果你真的很专注,你甚至可以让他们做算术。)

这篇文章将向你展示一些你以前可能没有尝试过的正则表达式的用例,并给你一些资源,让学习它们变得有趣。

让你的 f 弦更加百搭

Python 的 f-strings 非常棒——它们可读性强、简洁,并且比旧的%格式化方法更不容易出错。

使用 regex,您可以从中获得更多。为表达式加上前缀 r 表示“raw ”,这告诉 Python 忽略所有的转义字符。

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

But beware, even a raw string can’t consist entirely of a single backslash.

当你需要交换你的正则表达式的部分时,结合使用前缀 r 和前缀 f 。您可以用它来编写更短的循环,或者为您还没有或不需要编译的值保留一个位置。(这里有一个后一种情况的例子。)

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

Use re.compile to pre-compile a regular expression object.

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

精确查找和替换文本

正则表达式为您提供了一种改变字符串内容的简洁方法。在一行中,您可以使用捕获组来定位要替换和更改的项目。

在这里,我用这种技术扫描新闻文章中的句子,并用单词“alien”制作标签。

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

Use a numbered reference to the capturing group enclosed in parentheses.

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

The second expression replaces the targeted substring in the call to re.sub.

从嘈杂的数据中获取有价值的信息

我在日常生活中使用 regex 来简化其他任务(是的,真的)。例如,我想要 requirements.txt 文件中的包列表,但是不想要它们的具体版本。

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

Not pleasant.

Regex 避免了手动提取包名的繁琐。你可以在 Regex101 看到我是怎么做的。为此,我喜欢使用 BBEdit (以前的 TextWrangler),但是你也可以使用 Regex101 中的“导出匹配”特性。这个网站给了你实时调试你的表达的额外好处。

花在学习正则表达式上的时间可以让你从繁琐的搜索中解脱出来,从而获得数倍的回报。我使用正则表达式从其他 Python 脚本中提取正则表达式,并在命令行中使用 T2 对文件进行 grepping。

训练你的大脑,享受挑战

在应用正则表达式时,您将通过分解搜索问题、抽象模式并在算法上应用它们来提高您的计算思维技能。

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

I’m fun at parties.

但是使用正则表达式的最好理由可能是它们只是的乐趣。如果你是那种喜欢解谜的人,你会沉迷于寻找不同的方法来解决同一个问题和解决边缘案例。

虽然正则表达式确实很难,有时甚至很危险,但生活中大多数美好的事情都是如此。做几个填字游戏,打一点 regex 高尔夫,看你合不同意。

如何在处理无聊任务时使用硒作为救命稻草

原文:https://towardsdatascience.com/how-to-use-selenium-as-life-saver-when-dealing-with-boring-tasks-ca264d1ce88?source=collection_archive---------18-----------------------

以 Selenium 的方式自动化永无止境的重复任务

如果您是一名开发人员,那么您可能不需要介绍 selenium。Selenium 是一个强大的工具,用于与 web 服务器交互,以编程的方式处理请求。它用于自动执行各种各样的任务,包括与远程 web 服务器的交互。在本文中,我将通过一个简单的例子来演示它的强大用法。

让我们考虑使用在线服务从扫描图像样本中自动提取文本的任务,称为光学字符识别(OCR)。该过程包括以下步骤。

  1. 从本地存储器上传图像。
  2. 启动 OCR 提取过程
  3. 等待文本提取完成
  4. 找到文本元素并检索
  5. 将它写在 txt 文件中

我正在使用 newocr 在线 ocr 服务进行任务演示。当我们一步一步地看代码时,我会解释正在做什么。代码是用 python 写的,但是没有 python 知识的读者也能理解这里讨论的概念。我已经挑选了一个样本扫描图像。让我们来看看样本图像。

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

1.导入所需的库

webdriver —与服务器交互的 Selenium 驱动类对象

WebDriverWait —暂停执行一段时间的功能

预期条件 —等待条件通过

超时异常 —用于处理因服务器响应延迟而导致的错误

By —用于指定要查找的元素类型

ChromeDriverManager —用于启动浏览器的 Chrome 版本

列出文件名以’结尾的所有文件。工作目录中的 jpeg’ (jpeg 图像)。此外,你应该会看到一个 Chrome 浏览器自动启动,并登陆到 Newocr 主页。

注意:如果 chromedriver.exe 在 executable_path 中不可用,那么您将遇到“**web driver exception”**这意味着驱动程序存储在其他地方或者驱动程序不存在。如果 chromedriver.exe 不存在,下载它并指定位置的完整路径。

2.找到元素标签

对于每个动作,我们希望 selenium 在元素上执行,我们需要提供相应的元素路径。元素路径是指向 HTML 文档中给定标签的东西。这样做背后的想法是,我们要求 Selenium 在给定的位置标记并对其执行指定的操作。按照下面显示的步骤获取元素路径。

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

有许多方法可以定位元素,“CCS 选择器”是其中之一。一旦你做了上面的步骤,CSS 选择器的元素就会被复制到剪贴板上。然后使用这个选择器来定位元素。下面是从图像中提取文本的代码片段。

上面的代码片段做了以下事情:

  1. 找到“选择文件”按钮并发送图像文件的完整路径
  2. 找到“预览”按钮,并执行触发上传过程的点击操作。
  3. 等待,直到“#ocr”元素出现,这意味着上传过程已完成,但不会超过 25 秒。
  4. 一旦元素“#ocr”出现,就执行触发文本提取过程的点击动作。
  5. 等待提取完成。
  6. 定位检索到的文本元素,然后复制结果并存储在变量“txt”中。

让我们付诸行动吧。

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

您可能想知道手动执行过程是否比编程更容易,为什么要编写代码。想象一下你自己处于这样一种情况,你必须处理 100 张图像来从中提取文本,这是一个繁琐的过程。在这种情况下,硒可能是救命稻草。当你在办公室自助餐厅和同事聊天、喝咖啡时,Selenium 会让你的机器完成工作。让我们看看它是怎么做的。

该代码循环遍历每个图像,并应用前面讨论过的操作。对样本图像运行的代码片段产生以下结果。

Output from the Sample_1.jpeg :In 1830 there were Dut twenty-three
miles of railroad in operation in the
United States, and in that year Ken-
tucky took the initial step in the work
weat of the Alleghanies. An Act to
incorporate the Lexington & Ohio
Railway Company was approved by
Gov. Metcalf, January 27, 1830.. {t
provided for the construction and re.Output from the Sample_2.jpeg :When you skim and scan, you need to cover
everything, even titles, subtitles, side features, and
visuals. That bit of information you need may not be
tidily packaged in a paragraph, so you need to check
the entire page--not just the main body of the text,
there are also many visual clues that help you to
find information. Heads and subheads break up the
text and identify the content of each part. Where
key terms are introduced and defined, they appear
in boldface type. Graphs and charts have titles
and/or captions that tell you what they are about.
These clues will help you to find information. . . but
only if you use them.Output from the Sample_3.jpeg :irks ScanTris scanning meusures the iris pattern in the cotored part of the eye,
although the iris color has nothing to do with the biornetric. tris
patterns are formed randomly. As a result, the iris patterns in your
left and right eyes are different, and so are the iris patterns of identi-
cal twins, Iris scan templates ure typically around 256 bytes. bis
scanning can be used quickly for both identification and verification
applications because of its large number of degrees of freedom, Cur-
Tent pilot programs and applications include ATMs (“Eye-TMs"),
grocery stores (for checking out), and the Charlotte/Douglas Inter-
national Airport (physical access}. During the Winter Otympics in
Nagano, Japan, an iris scanning identification system controlled
access to the rifles used in the biathlon.

感谢您的阅读。

如何使用 SQL 进行数据分析(房产销售时间序列)

原文:https://towardsdatascience.com/how-to-use-sql-to-perform-data-analysis-house-property-sales-time-series-bf36cd3c2528?source=collection_archive---------13-----------------------

欢迎阅读我的新文章。如果你想在求职过程中脱颖而出,数据分析永远是一项必要的技能。也许你知道怎么用 Python 或者 R 甚至 SAS/Matlab 来执行。但是了解 SQL 通常是您应该拥有的一项必要而重要的技能。许多公司仍然大量使用 SQL 进行数据提取和分析。简单但能够处理足够多的数据帮助 SQL 在多年后仍然很重要(我编写 SQL 已经超过七年了)。

因此,我在这里演示一个使用 SQL 的数据分析。我做 SQL 用的平台是 MySQL Workbench。您可以从以下链接免费下载:

[## MySQL::下载 MySQL 工作台

MySQL Workbench 为数据库管理员和开发人员提供了一个集成的工具环境,用于:数据库设计和建模

dev.mysql.com](https://dev.mysql.com/downloads/workbench/) 外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

而这个分析的数据集是来自 Kaggle 的“房产销售时间序列”。

[## 房产销售时间序列

下载数千个项目的开放数据集+在一个平台上共享项目。探索热门话题,如政府…

www.kaggle.com](https://www.kaggle.com/deltacrot/property-sales)

关于如何使用 MySQL Workbench 超出了本文的范围。您可以从文档中获得更多信息。有一点要提的是,我是用 MySQL 编码 SQL 的。如果您使用 Oracle 或其他软件编码,可能会有一些不同。如果遇到错误,不必惊慌。只要变回你的语言应该有的样子。

[## MySQL 工作台

这是 MySQL 工作台参考手册。它记录了 MySQL Workbench 社区和 MySQL Workbench…

dev.mysql.com](https://dev.mysql.com/doc/workbench/en/)

该模式称为“数据集”,数据存储为一个名为“raw_sales”的表

第一步总是打印数据集中的一些记录。

SELECT * FROM dataset.raw_sales
LIMIT 10

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

因此,数据集中有五列,日期出售、邮政编码、价格、财产类型和卧室。

select min(datesold) as min_datesold, max(datesold) as max_datesold 
from dataset.raw_sales;select count(1) from dataset.raw_sales;

该数据集涵盖了从 2007 年 2 月 7 日到 2019 年 7 月 27 日的 29580 条记录。

那么哪个日期的销售最频繁呢?

select datesold, count(1) as sales_count, sum(price) as price_sum
from dataset.raw_sales
group by datesold
order by sales_count desc 
limit 10;

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

所以一天的最大销售量是 50 件,总价是 4200 万英镑。

哪个邮政编码的平均销售价格最高?

select postcode,avg(price) as price_avg , count(1) as sales_count
from dataset.raw_sales
group by postcode
order by price_avg desc
limit 10;

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

邮编 2618 的共 9 笔销售,均价 1.08M

而哪一年的销量最低?

select year(datesold) as year , count(1) as sales_count, sum(price) as price_sum 
from dataset.raw_sales
group by year 
order by sales_count
limit 10;

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

有没有可能知道每年价格排名前五的邮编?当然可以,但是要知道什么是窗函数。

一开始我不知道什么是窗口函数。但是后来我在面试中被一次又一次地问到。所以我查了一下,意识到我应该早点知道这个(至少帮我面试回答问题)。

基本上,window 函数可以基于分区执行聚合,并将结果返回给一行。如果您想了解更多关于窗口函数的语法和用法,我建议您阅读 Oracle 的文档,如下所示:

[## MySQL :: MySQL 8.0 参考手册::12.21.1 窗口函数描述

在以下函数描述中,over_clause 表示 over 子句,如第 12.21.2 节“窗口…”所述

dev.mysql.com](https://dev.mysql.com/doc/refman/8.0/en/window-function-descriptions.html)

所以我首先按年份和邮编合计价格

select year(datesold) as year ,postcode, sum(price) as price_sum 
from dataset.raw_sales
group by year, postcode

然后我使用窗口函数得到每年总价的排名。

select year,postcode, price_sum, row_number() over (partition by year order by price_sum desc) as ranking
from (
select year(datesold) as year ,postcode, sum(price) as price_sum 
from dataset.raw_sales
group by year, postcode
)  a

最后,选择所有排名小于或等于 5 的记录

select * from
(
select year,postcode, price_sum, row_number() over (partition by year order by price_sum desc) as ranking
from (
select year(datesold) as year ,postcode, sum(price) as price_sum 
from dataset.raw_sales
group by year, postcode
)  a
) b
where ranking <=5 
order by year,ranking

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

接下来,我将继续讨论 propertyType。有两种类型,房子和单位。

那么每年有多少房子和单元的销售呢?

最简单的方法是分组,然后数有多少条记录。但在这里,我通过使用 case when 提出了另一种方法。函数是根据标准进行聚合的另一个有用函数的情况。在这里,当我计算记录的数量时,我没有使用 count 函数,而是使用 sum 函数和 case when 函数。

select year(datesold) as year, 
sum(case when propertyType = "house" then 1 else 0 end) as house_sales_count,
sum(case when propertyType = "unit" then 1 else 0 end) as unit_sales_count 
from dataset.raw_sales
group by year;

因此,对于 house_sales_count,如果 propertyType 等于 house,则返回 1。否则,它返回 0。然后对所有记录求和。这将显示 propertyType 等于 house 的销售数量。

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

另一个优点是结果看起来像 Excel 数据透视表。可以直接做个对比。

你可以清楚地看到,每年的房屋销售量都比单位销售量多。那么后续的问题一定是关于房子和单位的平均差价。当然我们也可以用 case 当函数。但有一点需要谨慎的是,else 部分。

select year(datesold) as year,
avg(case when propertyType = "house" then price else null end) as house_price_avg,
avg(case when propertyType = "unit" then price else null end) as unit_price_avg
from dataset.raw_sales
group by year;

有必要返回一个空值,而不是返回 0,这样在计算平均值时就不会包括该特定记录。

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

再说一次,房子的平均价格比单位价格更高。

进一步考虑卧室数量怎么样?

select year(datesold) as year,
avg(case when propertyType = "house" then price/bedrooms else null end) as house_price_bedroom_avg,
avg(case when propertyType = "unit" then price/bedrooms else null end) as unit_price_bedroom_avg
from dataset.raw_sales
group by year;

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

这次的情况有所不同。就卧室数量而言,该单元的平均价格高于房子。

这个分析到此结束。我会说 SQL 已经削弱了它在数据分析中的重要性,尤其是许多公司仍然只将 SQL 用于数据挖掘和分析。知道如何掌握 SQL 绝对有助于你获得一个分析职位。希望你看完我的文章能有所收获。请随意给出你的评论或者下次你想让我介绍什么。希望你喜欢,下次再见。

如何在熊猫小组中运用分裂-运用-结合策略

原文:https://towardsdatascience.com/how-to-use-the-split-apply-combine-strategy-in-pandas-groupby-29e0eb44b62e?source=collection_archive---------1-----------------------

通过这个熊猫视觉指南掌握 Python 中的分割-应用-组合模式groupby-apply

TL;速度三角形定位法(dead reckoning)

Pandas groupby-apply是 Python 数据科学家工具箱中的一个无价工具。在没有完全理解其所有内部复杂性的情况下,您可能会走得很远。然而,有时这可能会表现为意外的行为和错误。吃过吗?或者也许您正在努力解决如何处理更高级的数据转换问题?然后阅读这个熊猫groupby-apply范例的视觉指南,一劳永逸地理解它是如何工作的。

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

来源:我的团队在 晒版机 提供。

介绍

在 Pandas 中处理更高级的数据转换和数据透视表时,对groupby-apply机制的深入理解通常是至关重要的。

这对新手来说可能是一个陡峭的学习曲线,对中级熊猫用户来说也是一种“陷阱”。这就是为什么我想与你分享一些视觉指南,展示当我们运行groupby-apply操作时实际发生的事情。

下面是我认为您应该首先了解的一些事情,以便更直接地使用更高级的 Pandas 数据透视表:

Groupby —它是做什么的?

  1. 应用—它是如何工作的,我们传递给它什么?
  2. 联合收割机阶段会发生什么?
  3. 当自定义函数返回一个序列时会发生什么?
  4. 当它返回一个数据帧时呢?
  5. 当自定义函数返回除了上面两个以外的东西时会发生什么?

请继续阅读,以获得这些问题的答案以及关于在 Pandas 中使用数据透视表的一些额外见解。

我们的示例表

让我们以经典的 Iris 数据集为例(可从 Seaborn 绘图库中获取),为简单起见,将其限制为 15 行:

import seaborn as snsiris_data = sns.load_dataset(‘iris’)
df = iris_data.head(5).copy()
df = pd.concat([df, iris_data..iloc[50:55]])
df = pd.concat([df, iris_data.iloc[100:105]])

该表很小,但足以满足我们的需求,非常适合本文中的演示目的:

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

使用 groupby()分组

让我们从更新一些关于groupby的基础知识开始,然后在我们进行的过程中在上面构建复杂性。

您可以将groupby方法应用于具有简单 1D 索引列的平面表。它还没有在表上执行任何操作,只是返回了一个DataFrameGroupBy实例,因此需要链接到某种聚合函数(例如,summeanminmax等)。更多的见这里的,它们将对分组行起作用(我们将在后面讨论应用)。

这里需要记住的重要一点是,它会自动将单个聚合结果连接回一个数据框架。

一个非常简单的例子是按特定的列值分组(如我们表中的“物种”),并对所有剩余的适用列求和:

df.groupby(‘species’).sum()

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

或者,我们可以指定要对哪些列求和。一些人犯的一个常见错误是先计算总和,然后在末尾添加一个列选择器,如下所示:

df.groupby(‘species’).sum()[‘sepal_width’] *# ← BAD!*

这意味着首先对每个适用的列(数字或字符串)进行求和,然后选择一个指定的列进行输出。

这里有一个更好的方法:

在聚合函数之前指定列,以便在过程中只对一列求和,从而显著提高速度(对于这个小表是 2.5 倍):

df.groupby(‘species’)[‘sepal_width’].sum() *# ← BETTER & FASTER!*

注意,由于只有一列被求和,因此结果输出是一个pd.Series对象:

species
setosa 16.4
versicolor 14.6
virginica 14.9
Name: sepal_width, dtype: float64

但是,如果您想直接自动返回 dataframe 对象(毕竟它的可读性要好得多),就没有必要通过pd.Dataframe()进行强制转换。相反,将列名作为列表提供给列选择(本质上,使用双括号),如下所示:

df.groupby(‘species’)[**[**‘sepal_width’**]**].sum()

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

最后,groupby可以接受一个列名列表,并对所有剩余的适用列(之前没有提到)执行聚合函数。

理解这一点很重要,结果表将有一个 **MultiIndex** 对象作为索引,其行为与常规表略有不同。

multicol_sum = df.groupby([‘species’, ‘petal_width’]).sum()

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

有用提示:使用 **MultiIndex** 表时,您可以使用 **.xs** 选择数据帧的子集,方法是选择一个值,然后选择特定的索引级别。产生的输出通常也是 dataframe 对象。

这里有一个例子:

multicol_sum.xs(‘virginica’, level=’species’)

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

另外,不要忘记您可以通过运行reset_idnex方法将索引“展平”成列:

multi_sum.reset_index()

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

此外,如果您将一个drop=True参数传递给reset_index函数,您的输出数据帧将删除组成MultiIndex 的列,并创建一个具有增量整数值的新索引。

apply()

现在让我们进入下一个阶段。

我们可以定义自己的自定义函数,并通过apply()方法在表上运行它,而不是使用 Pandas 提供的常用函数来操作组。

要写好一个自定义函数,你需要理解这两个方法如何在所谓的 Groupby-Split-Apply-Combine 链式机制中相互协作(更多关于这个在这里)。

正如我已经提到的,第一阶段是创建一个 Pandas groupby对象(DataFrameGroupBy),它为 apply 方法提供一个接口,以便根据指定的列值将行分组在一起。

我们暂时将这些组分开,并通过一个优化的 Pandas 内部代码将它们循环。然后,我们将每个组作为一个SeriesDataFrame对象传递给一个指定的函数。

函数的输出被临时存储,直到所有组都被处理。在最后一个阶段,所有结果(来自每个函数调用)最终被组合成一个输出。

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

这里有几点我们需要记住,以避免在使用groupbyapply方法时可能出现的意外。

在极少数情况下,当我们被迫使用一个 for-in 循环迭代单个行组时,这一点尤其重要(通常,这是一种不好的做法——然而,在某些情况下这可能是不可避免的)。

1]应用功能

您可以通过几种方式为每组操作提供逻辑。

您可以定义单独的函数并将其作为要应用的对象传递,也可以直接传递 lambda 表达式。还有一种.agg()方法,它通过提供一个名称或一系列函数名称来实现多个聚合函数(但这超出了本文的范围)。

例如,这两个命令

df.groupby(‘species’).apply(lambda gr: gr.sum())

def my_sum(gr):
 return gr.sum()df.groupby(‘species’).apply(my_sum)

产生完全相同的结果:

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

顺便说一下,是的,具有字符串值的列也被“求和”,它们只是简单地连接在一起。

2]功能输入

定制函数应该有一个输入参数,该参数可以是一个Series或一个DataFrame对象,这取决于通过groupby方法指定的是一列还是多列:

def foo(gr):
 print(type(gr))
 return Nonedf.groupby(‘species’).apply(foo)

产出:

<class ‘pandas.core.frame.DataFrame’>
<class ‘pandas.core.frame.DataFrame’>
<class ‘pandas.core.frame.DataFrame’>
<class ‘pandas.core.frame.DataFrame’>

,而(忽略这里有 4 行的事实,我稍后会解释)

df.groupby(‘species’)[‘petal_length’].apply(foo)

退货:

<class ‘pandas.core.series.Series’>
<class ‘pandas.core.series.Series’>
<class ‘pandas.core.series.Series’>

3]在自定义函数中使用 print()语句

当编写一个复杂的表转换时,你有时可能想要遍历applyed 函数的内部工作方式,并添加一个print()语句来检查操作过程中发生了什么(我经常这样做,以便在遇到困难时确定方向)。

对你们中的一些人来说,这可能很令人吃惊,但是当你运行下面的代码时,你将得到一个你可能没有预料到的额外的位:

def foo(gr): 
 print(gr, ‘\n’)

df.groupby(‘species’).apply(func=foo)

这是打印出来的内容:

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

这种神秘的行为实际上在熊猫文档中有解释,但是很容易被忽略——我知道我是这么做的,而且不得不艰难地学习它,所以让我来帮你省点麻烦:

在当前实现中,在第一列/行上应用调用 func 两次,以决定它是否可以采用快速或慢速代码路径。如果 func 有副作用,这可能会导致意外的行为,因为它们会对第一列/行生效两次。

4]功能输出

拼图的最后一块是应用函数的输出,以及如何在合并阶段处理它。这里发生的事情是,Pandas 从每个后续的组操作中获取所有的输出,并将它们与它们相应的标签连接起来,这些标签也是由DataFrameGroupBy对象提供的。后者随后被用于创建新的索引。

这意味着您可以设计一个自定义函数来返回任何内容,它将被放置在组名标签下的特定组的一行中。

这个例子应该很好地说明了这一点:

def foo(gr):
 return pd.Series(“This is a test”)df.groupby(‘species’).apply(func=foo)

将创建:

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

然而,在大多数情况下(例如,使用 sum 函数),每次迭代都返回每行一个 Pandas Series对象,其中索引值用于将值分类到最终数据帧中的正确列名。

这个例子应该说明:

让我们创建一个定制的Series对象,并通过apply方法在每个组上返回它:

myseries = pd.Series(
 data=[‘one’, ‘two’, ‘3’],
 index=[‘a’, ‘b’, ‘c’]
)def foo(gr):
 return myseriesdf2.groupby([‘species’, ‘petal_width’]).apply(func=foo)

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

如果我们为每个迭代组返回一个DataFrame会怎么样?结果有点有趣,因为它将创建一个具有MultiIndex结构的表。它将把DataFrame按原样追加到每一行中,并且它的索引将与组标签值集成在一起,例如:

def foo(gr):
 return pd.DataFrame(myseries) df2.groupby([‘species’, ‘petal_width’]).apply(func=foo)

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

现在就这样。

理解这些问题将使您更容易在 Pandas 表上处理一些更复杂的枢轴和操作。每当我陷入困境时,我会时不时地重温这些基础知识——它总能帮助我大大加快这个过程!

如何在 Seaborn 中使用自己的调色板

原文:https://towardsdatascience.com/how-to-use-your-own-color-palettes-with-seaborn-a45bf5175146?source=collection_archive---------5-----------------------

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

前几天,我用 seaborn 制作了一些可视化效果,这是一个基于 Matplotlib 的非常棒的超级易用的库。

即使我很喜欢 seaborn 的默认风格,因为它们的美学非常干净,但我通常喜欢定制的一点是数据点上的颜色。

我试图寻找如何在 seaborn 中使用或创建自定义调色板的端到端示例,但是很难找到。

所以我决定利用我的 matplotlib 知识,收集我能找到的关于 seaborn 调色板的所有信息,来创建我自己的代码示例/模板。

希望你觉得有用。

像往常一样,您从漂亮的虚拟数据开始😀

import numpy as np
import pandas as pd
import seaborn as sns
import matplotlib.pyplot as pltdata = np.array([[1, 3, 'weekday'], [2, 2.5, 'weekday'],[3, 2.7, 'weekend'], [4, 2.8, 'weekend'], [5, 3, 'weekday'], [6, 3.1, 'weekday'], [7, 3, 'weekday'], [8, 3.1, 'weekday'], [9, 3.1, 'weekday'], [10, 3.1, 'weekend']])# Creating a data frame with the raw data
dataset = pd.DataFrame(data, columns=['day', 'miles_walked', 'day_category'])

如果你想看一眼数据集

print(dataset)

你会看到这样的东西

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

1.使用现有的调色板

seaborn 和 matplotlib 有很多不同的调色板可供选择。在这个例子中,我将使用配对调色板

# Set the color palette
sns.set_palette(sns.color_palette("Paired"))# Plot the data, specifying a different color for data points in
# each of the day categories (weekday and weekend)
ax = sns.scatterplot(x='day', y='miles_walked', data=dataset, hue='day_category')# Customize the axes and title
ax.set_title("Miles walked")
ax.set_xlabel("day")
ax.set_ylabel("total miles")# Remove top and right borders
ax.spines['top'].set_visible(False)
ax.spines['right'].set_visible(False)plt.show()

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

使用现有的调色板,您唯一需要做的事情是在调用 plot 方法和您想要的任何其他定制之前设置它。

2。使用自己的调色板

如果你想使用一组特定的颜色,或者因为它们是你最喜欢的颜色,或者是你正在使用的风格指南的一部分,你也可以这样做!

# Create an array with the colors you want to use
colors = ["#FF0B04", "#4374B3"]# Set your custom color palette
sns.set_palette(sns.color_palette(colors))# And then, from here onwards, it's exactly like the previous example# Plot the data, specifying a different color for data points in
# each of the day categories (weekday and weekend)
ax = sns.scatterplot(x='day', y='miles_walked', data=dataset, hue='day_category')# Customize the axes and title
ax.set_title("Miles walked")
ax.set_xlabel("day")
ax.set_ylabel("total miles")# Remove top and right borders
ax.spines['top'].set_visible(False)
ax.spines['right'].set_visible(False)plt.show()

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

如果您想在多个图中使用自己的调色板,您也可以在 seaborn 图中使用参数palette,并在整个代码中引用您的自定义调色板。

# Create an array with the colors you want to use
colors = ["#FF0B04", "#4374B3"]# Set your custom color palette
customPalette = sns.set_palette(sns.color_palette(colors))# Use the parameter palette and use your own palette across all your
# plots
ax = sns.scatterplot(x='day', y='miles_walked', data=dataset, hue='day_category', palette=customPalette)# Customize the axes and title
ax.set_title("Miles walked")
ax.set_xlabel("day")
ax.set_ylabel("total miles")# Remove top and right borders
ax.spines['top'].set_visible(False)
ax.spines['right'].set_visible(False)plt.show()

这样就会造成和上面一样的剧情!但是现在你可以在你的任何一幅 seaborn 图中引用customPalette来使用相同的调色板。

就是这样!一个很好的方式来定制您的情节,使您的可视化更有见地。

感谢阅读!

如何用 Python (2020)三步可视化决策树

原文:https://towardsdatascience.com/how-to-visualize-a-decision-tree-in-5-steps-19781b28ffe2?source=collection_archive---------10-----------------------

用 Python 学习 Scikit 的一个例子

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

Photo by Alexandre Chambon on Unsplash

决策树是一种非常流行的机器学习模型。它的美妙之处在于其易于理解的可视化和在生产中的快速部署。

在本教程中,你将发现一个的三步程序,用于可视化 Python(Windows/Mac/Linux)中的决策树

跟着做,画出你的第一棵决策树!

2020 年 4 月更新**:
sci kit-learn(sk learn)库增加了一个新功能,允许我们在没有 GraphViz 的情况下绘制决策树。
所以我们可以使用 matplotlib 库的 plot_tree 函数。**

步骤 1:下载并安装 Anaconda

根据您的计算机操作系统版本,选择正确的 Anaconda 包进行下载。Anaconda 是一个常见的 Python 发行版,通常允许大型公司下载和安装。

** [## Anaconda Python/R 发行版-免费下载

开源的 Anaconda 个人版(正式的 Anaconda 发行版)是执行 Python/R…

www.anaconda.com](https://www.anaconda.com/distribution/#download-section)

相关文章: 如何安装/设置 Python 并立即准备数据科学
查看使用 Anaconda 安装 Python 的分步说明。

步骤 2:导入包并读取数据

首先,让我们从 Python 机器学习库 scikit-learn 导入一些函数。

sklearn 需要 0.21 或更高版本。如果你刚刚安装了 Anaconda,它应该足够好了。

接下来,让我们读入数据。这里以乳腺癌数据为例。

第三步:创建决策树并将其可视化!

在您的 Python 版本中,复制并运行以下代码来绘制决策树。我更喜欢 Jupyter 实验室,因为它的互动功能。

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

恭喜你的第一个决策树图!

希望本指南对您有所帮助。

如果你有任何问题,请留言。**

在你离开之前,别忘了 报名参加刚刚进入数据快讯的 !或者通过推特脸书与我们联系。

更多数据科学相关文章来自 Lianne 和 Justin:

** [## 如何在线学习数据科学:你需要知道的一切——进入数据

这是利用在线资源进入数据科学的完整路线图/课程。你是否想学习…

www.justintodata.com](https://www.justintodata.com/how-to-learn-data-science-online-all-you-need-to-know/) [## Python 中的数据清理:终极指南(2020)——只进入数据

我们用 Python 创建了这个新的完整的分步指南。你将学习如何寻找和清理的技巧:丢失…

www.justintodata.com](https://www.justintodata.com/data-cleaning-python-ultimate-guide/) [## 预测时间序列的三个步骤:LSTM 与 TensorFlow Keras -只是进入数据

这是利用在线资源进入数据科学的完整路线图/课程。你是否想学习…

www.justintodata.com](https://www.justintodata.com/forecast-time-series-lstm-with-tensorflow-keras/)**

如何用 40 行代码可视化卷积特征

原文:https://towardsdatascience.com/how-to-visualize-convolutional-features-in-40-lines-of-code-70b7d87b0030?source=collection_archive---------2-----------------------

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

卷积神经网络彻底改变了计算机视觉,并将彻底改变整个世界。开发解释它们的技术是一个重要的研究领域,在本文中,我将向您解释如何可视化卷积特征,如标题图片所示,只需 40 行 Python 代码。

最近,在读杰里米·里夫金的书《工作的终结》时,我看到了人工智能的一个有趣定义。里夫金写道:“今天,当科学家们谈论人工智能时,他们通常指的是‘创造机器的艺术,这些机器执行的功能需要人来执行。”(摘自 Kurzweil,Raymond 著《智能机器时代》(麻省剑桥:麻省理工出版社,1990 年),第 14 页。)".我喜欢这个定义,因为它避免了人工智能在我们的智能意义上是否真正智能的大肆讨论。作为一名科学家,揭示我们大脑的功能原理并创造一个真正智能的机器的想法让我兴奋,但我认为重要的是要认识到深度学习模型不是大脑的模型(弗朗索瓦·乔莱,用 Python 进行深度学习(纽约州谢尔特岛:曼宁出版公司,2018 年),第 8 页)。深度学习研究旨在从数据学习规则,以自动化到目前为止还不能自动化的过程。虽然这听起来不那么令人兴奋,但它确实是一件伟大的事情。仅举一个例子:深度卷积神经网络的出现彻底改变了计算机视觉和模式识别,并将允许我们在医疗诊断等领域引入大量自动化。这可以让人类迅速将顶尖的医学诊断带给贫穷国家的人们,这些国家没有能力培养他们原本需要的许多医生和专家。

尽管有关于深度学习的所有令人兴奋的消息,但神经网络看待和解释世界的确切方式仍然是一个黑箱。更好地理解它们如何准确地识别特定的模式或对象,以及它们为什么工作得如此好,可能会让我们 1)进一步改进它们,2)还会解决法律问题,因为在许多情况下,机器做出的决定必须是人类可以解释的。

有两种主要方法可以尝试理解神经网络如何识别某种模式。如果您想知道哪种模式显著激活了某个特征图,您可以 1)尝试在数据集中查找导致该特征图高平均激活率的图像,或者 2)尝试通过优化随机图像中的像素值来生成这种模式。后一种想法是由尔汗等人 2009 提出的。在本文中,我将向您解释如何通过优化随机图像的像素值来为封面图片所示的卷积神经网络生成特征可视化,只需大约 40 行 Python 代码。

这篇文章的结构如下:首先,我将向您展示一个 VGG-16 网络的几层中卷积特征的可视化,然后我们将尝试理解其中一些可视化,我将向您展示如何快速测试某个过滤器可能检测到哪种模式的假设。最后,我将解释创建本文介绍的模式所必需的代码。

我们开始吧:)

特征可视化

神经网络学习将输入数据(如图像)转换成意义越来越大、越来越复杂的连续层。

你可以把一个深层网络想象成一个多阶段的信息提炼操作,信息经过连续的过滤,越来越纯净。(弗朗索瓦·乔莱(Franç ois Chollet),用 Python 进行深度学习(纽约州谢尔特岛:曼宁出版公司,2018 年),第 9 页)

阅读完他的文章后,您将知道如何生成模式,以最大化在那些分层表示的特定层中所选特征图的平均激活,如何能够解释其中一些可视化,以及最终如何测试所选过滤器可能响应哪种模式或纹理的假设。下面你会看到一个 VGG-16 网络的几层中过滤器的可视化特征。在观察它们的同时,我希望你能观察到,随着我们深入网络,生成的模式的复杂性是如何增加的。

第 7 层:Conv2d(64,128)

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

filters 12, 16, 86, 110 (top left to bottom right, row-wise)

第 14 层:Conv2d(128,256)

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

filters 1, 6, 31, 32, 54, 77, 83, 97, 125, 158, 162, 190 (top left to bottom right, row-wise)

第 20 层:Conv2d(256,256)

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

filters 3, 34, 39, 55, 62, 105, 115, 181, 231 (top left to bottom right, row-wise)

第 30 层:Conv2d(512,512)

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

filters 54, 62, 67, 92, 123, 141, 150, 172, 180, 213, 233, 266, 277, 293, 331, 350, 421, 427 (top left to bottom right, row-wise)

第 40 层:Conv2d(512,512) —网络顶部

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

filters 4, 9, 34, 35, 75, 123, 150, 158, 203, 234, 246, 253, 256, 261, 265, 277, 286, 462 (top left to bottom right, row-wise)

那些图案真的让我大吃一惊!部分原因是我认为它们中的一些非常漂亮(以至于我会立刻把它们裱起来挂在墙上),但主要原因是我认为它们只是通过最大化一个复杂的参数化数学函数产生的某个值而创造出来的,这个函数是对数千张图像进行训练的。在扫描通过最大化最后一个卷积层中特征映射的平均激活而获得的 512 个模式时,我遇到了几个让我想到“等等,这是一只鸡!”或者“这看起来不像羽毛吗?”

识别模式

让我们试着解释一下这些可视化的特性!

从这个开始,有没有让你想起什么?

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

layer 40, filter 286

这张照片立刻让我想起了教堂里拱形天花板的圆形拱门。

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

Source

那么我们如何检验这个假设呢?人造拱门的图片是通过最大化第 40 层中第 286 个特征地图的平均激活来创建的。因此,我们简单地将网络应用于图片,并在第 40 层绘制特征图的平均激活。

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

我们看到了什么?在特征地图 286 处有一个强烈的尖峰,正如所料!那么这是否意味着层 40 中的过滤器 286 是负责检测拱形天花板的过滤器?好吧,我会小心一点的。滤波器 286 显然响应图像中的拱形结构,但是要记住,这种拱形结构可能对几个不同的类别起重要作用。

注意:当我使用第 40 层(一个卷积层)来生成我们正在看的图像时,我使用第 42 层来生成显示每个特征图的平均激活的图。层 41 和 42 是批量标准和 ReLU。ReLU 激活函数移除所有负值,选择层 42 而不是层 40 的唯一原因是,否则,图中将显示大量的负噪声,使得难以看到我们感兴趣的正尖峰。

继续下一个例子。我可以发誓那些是鸡头(或者至少是鸟头)!你看到尖尖的嘴和黑黑的眼睛了吗?

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

layer 40, filter 256

我测试了这张图片:

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

Source

瞧,特征图 256 显示了一个强尖峰。

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

下一个:

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

layer 40, filter 462

会不会是滤镜 462 对羽毛有反应?

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

Source

是的,过滤器 462 响应羽毛:

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

对 265 号过滤器有什么猜测吗?

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

layer 40, filter 265

或许是锁链?

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

Source

是的,似乎是对的!

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

然而,还有一些其他的大高峰!让我们来看看为两个相应的过滤器生成的特征可视化:

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

layer 40, filters 95, 303

当快速浏览为第 40 层的 512 个滤镜生成的图案时,两张图片都没有响铃。但是现在网络说话了?也许有一点点连锁,你说呢?

这是一个很酷的例子:

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

layer 40, filter 64

我相信我看到了许多类似羽毛的结构,这让我想起了鸟的腿,在左下方可能有一些类似于黑色眼睛和长喙的鸟头的东西。比“鸡特征可视化”中的喙长。我真的不是鸟类专家,但这两只呢?它们有长长的腿和喙。

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

Source

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

好吧,很明显在特征地图 64 上有一个尖峰,但是有更多甚至更大的尖峰!让我们来看看为其他四个滤波器生成的模式,这些滤波器的特征图显示了尖峰:

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

layer 40, filters 172, 288

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

layer 40, filters 437, 495

更多的鸟腿和更多的眼睛和嘴在最上面一排?然而,关于最下面一行,我没有任何线索。也许这些图案与图像的背景有关,或者只是代表了网络检测我不理解的鸟类所需的东西。我想这将是目前黑匣子的一部分…

最后一个可爱的,然后我们直接跳到代码,我保证。猜猜这是什么?

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

layer 40, filter 277

我养了两只猫很多年了,当我看到一只:D 时,我能认出一只小猫的耳朵,你看到它们了吗?在左上角找一个大的!

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

Source

是的,在特征地图 277 上有一个尖峰,但是是什么导致了它右边的尖峰呢?

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

让我们快速生成最大化层 40 中的特征地图 281 的平均激活的图片:

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

layer 40, filter 281

可能是条纹猫毛?

试图从网络中窥探一些秘密让我很开心。然而,事实是,大多数滤波器甚至在最后的卷积层对我来说仍然是绝对抽象的。

更严格的方法是将网络应用于许多不同种类图像的整个数据集,并跟踪最能激发特定图层中特定过滤器的图像。

还有一件事我觉得很有趣。在浏览生成的模式时,我发现许多模式似乎出现在不同的方向(有时甚至是相同的方向)。

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

layer 20, filters 11, 36, 50, 125, 144, 213

这是有道理的!卷积是平移不变的,因为过滤器在图像上水平和垂直滑动。但是它们不是旋转不变的,因为过滤器不旋转。因此,该网络似乎需要不同方向上的几个类似的滤波器来检测不同方向上的对象和模式。

代码

想法如下:我们从包含随机像素的图片开始。我们将评估模式中的网络应用于该随机图像,计算某一层中某一特征图的平均激活,然后从该层计算相对于输入图像像素值的梯度。知道了像素值的梯度,我们接着以最大化所选特征图的平均激活的方式来更新像素值。

我知道这听起来可能令人困惑,所以让我们用不同的话再次解释它:网络权重是固定的,网络将不会被训练,我们试图通过对像素值执行梯度下降优化来找到最大化某个特征图的平均激活的图像。

这种技术也用于 神经风格转移

为了实现这一点,我们需要:

  1. 一个随机的图像开始
  2. 评估模式下的预训练网络
  3. 一个很好的方法来访问我们感兴趣的任何隐藏层的激活结果
  4. 计算梯度的损失函数和更新像素值的优化器

让我们从生成一个噪声图像作为输入开始。我们可以这样做,即按照下面的方式:img = np.uint8(np.random.uniform(150, 180, (sz, sz, 3)))/255其中sz是图像的高度和宽度,3 是颜色通道的数量,我们除以 255,因为这是uint8类型的变量可以存储的最大值。如果你想要更多或更少的噪音,玩数字 150 和 180。然后,我们使用img_var = V(img[None], requires_grad=True)(这是 fastai 语法)将其转换为需要渐变的 PyTorch 变量。像素值需要梯度,因为我们希望使用反向传播来优化它们。

接下来,我们需要一个评估模式下的预训练网络(这意味着权重是固定的)。这可以通过model = vgg16(pre=True).eval()set_trainable(model, False)来完成。

现在,我们需要一种方法来访问其中一个隐藏层的功能。我们可以在我们感兴趣的隐藏层之后截断网络,这样它将成为输出层。然而,PyTorch 中有一个更好的方法来解决这个问题,叫做钩子,它可以在 PyTorch ModuleTensor上注册。要理解这一点,你必须知道:

  1. Pytorch Module是所有神经网络模块的基类。
  2. 我们神经网络中的每一层都是一个Module
  3. 每个Module都有一个名为forward的方法,用于计算给定输入的Module的输出。

当我们将我们的网络应用于我们的噪声图像时,第一层的forward方法将图像作为输入并计算其输出。这个输出是第二层的forward方法的输入,依此类推。当你在某一层注册一个前向钩子时,该钩子在该层的forward方法被调用时被执行。好吧,我知道这听起来很混乱。我想让你从这里得到的是:当你把你的网络应用到一个输入图像时,第一层计算它的输出,然后第二层,等等。当我们到达一个注册了钩子的层时,它不仅计算输出,还执行钩子。

那么这有什么好处呢?假设我们对图层 i 的特征地图感兴趣。我们在层 i 上注册一个 forward 钩子,一旦调用层 i 的 forward 方法,就将层 i 的特征保存在一个变量中。

下面的类实现了这一点:

当钩子被执行时,它调用方法hook_fn(见构造函数)。方法hook_fn保存self.features中输出的图层。注意,这个张量需要梯度,因为我们想对像素值进行反向传播。

你将如何使用一个SaveFeatures对象?

activations = SaveFeatures(list(self.model.children())[i])为层 i 注册你的钩子,用model(img_var)将你的模型应用到图像后,你可以在activations.features中访问钩子为我们保存的特性。记得调用方法close来释放已用的内存。

太好了,我们现在可以访问图层 i 的特征图了!特征图可以具有形状[1,512,7,7],其中 1 是批量维度,512 是过滤器/特征图的数量,7 是特征图的高度和宽度。目标是最大化所选特征图 j 的平均激活。因此,我们定义以下损失函数:loss = -activations.features[0, j].mean()和优化像素值的优化器optimizer = torch.optim.Adam([img_var], lr=lr, weight_decay=1e-6)。默认情况下,优化器会将损失最小化,因此我们只是将平均激活乘以-1,而不是告诉优化器将损失最大化。用optimizer.zero_grad()重置梯度,用loss.backward()计算像素值的梯度,用optimizer.step()改变像素值。

我们现在已经有了我们需要的一切:我们从一个随机图像开始,在评估模式中定义了一个预训练的网络,注册了一个前向挂钩来访问层 i 的特征,并定义了一个优化器和一个损失函数,允许我们以最大化层 i 中的特征图 j 的平均激活的方式来改变像素值。

很好,让我们来看一个例子:

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

layer 40, filter 265

等等,这不是我们想要的,对吗?这应该会导致我之前给你们看的连锁模式。如果你捏捏你的眼睛,你也许能猜出“锁链”可能在哪里。然而,我们必须以一个非常差的局部最小值结束,并且必须找到一种方法来引导我们的优化器朝向一个更好的最小值/更好看的模式。与我之前给你看的生成模式相比,这幅图是由一个类似于对立例子的高频模式主导的。那么,我们能做些什么来解决这个问题呢?我尝试了不同的优化器、学习率和规则,但似乎没有减少高频模式。

接下来,我改变了噪声输入图像的大小。

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

image sizes 200x200, 300x300, 400x400

你能观察到“链状图案”出现的频率随着图像尺寸的增加而增加吗?我知道可能很难理解我的意思。然而,对我来说,生成模式的频率随着图像大小的增加而增加确实是有意义的,因为卷积滤波器具有固定的大小,但是它们与图像相比的相对大小随着图像分辨率的增加而减小。换句话说:假设创建的图案总是具有大致相同的像素尺寸。如果我们增加图像尺寸,则生成的图案的相对尺寸将减小,并且图案频率增加。

如果我的假设是真的,我们想要的是低分辨率示例的低频模式(甚至低于上面显示的模式),但具有高分辨率。这有道理吗?我们如何做到这一点?

我试图从一个非常低分辨率的图像开始,即 56×56 像素,优化了几个步骤的像素值,然后以一定的系数增加图像大小。放大图像后,我又优化了几个步骤的像素值,然后再次放大图像…

这样效果更好:

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

layer 40, filter 265

我们现在有了一个分辨率更好的低频模式,没有太多的噪声。为什么会这样?我有以下想法:当我们从低分辨率开始时,我们会得到低频模式。放大后,放大模式的频率低于优化器在随机图像的较大图像尺寸下生成的频率。因此,当在下一次迭代中优化像素值时,我们处于更好的起点,并且似乎避免了糟糕的局部最小值。这有道理吗?为了进一步减少高频模式,我在放大后稍微模糊了图像,这对高频模式的影响比对低频模式的影响更大。

我发现按 1.2 的因子放大 12 倍会得到很好的结果。

看看下面的代码。你会发现我们已经讨论了最重要的几行,比如创建随机图像,注册钩子,定义优化器和损失,以及优化像素值。唯一重要的新方面是,1)我将代码包装在一个类中,2)在优化像素值几个步骤后,我们将图像放大几次。

像这样使用FilterVisualizer:

如果你想玩这个,请随意使用和更换笔记本。如果你不明白每一行,不要担心,首先你可以简单地改变层和过滤器指数,并运行笔记本从上到下。按照 自述文件 中的说明创建一个安装了fastai==0.7.0的 conda 环境。

你能找到其他能识别模式的特征地图吗?如果你想像我在这篇文章中一样用一张图来测试你的假设,请随意使用这个笔记本。如果你发现了很酷的东西,现在就告诉我吧!😃

我希望你和我一样喜欢这些视觉化特征的美丽,并且我能够教你一些有趣的东西。如果有任何不清楚的地方或者你需要更多的解释,请留下评论,我很乐意帮助你理解:)

更新:一位读者给我看了这篇令人兴奋的新 论文 ,它表明神经网络可能无法识别形状,而是对纹理做出反应。看看吧!

如何使用 Geoviews 库在 Python 中可视化地图顶部的数据

原文:https://towardsdatascience.com/how-to-visualize-data-on-top-of-a-map-in-python-using-the-geoviews-library-c4f444ca2929?source=collection_archive---------9-----------------------

所以让我们从我们将要解决的问题开始。假设您有一些数据代表一个特定的数字(如人口),该数字因地点而异(如不同的城市),您希望绘制一个图表来可视化该数据。你是怎么做到的?

一种方法(也是最常用的方法)是创建一个条形图。y 轴代表数字(如人口),x 轴代表地点(如城市)。我敢打赌,这种数据上的绝大多数图都是这种类型的。结果,网上有无数这样的例子,因此我没有必要再增加一个。

幸运的是,有一种更好的方法来可视化这种数据。请记住,情节必须直观,观众才能更好地掌握他们面前的东西。因此,在这种情况下,将数据可视化的更直观的方法是将它们绘制在地图上。有什么比交互式地图更直观的呢?在交互式地图上,你可以放大、缩小和查看你要找的地方或人物。

出于本教程的目的,我们将绘制一个图表来显示我国希腊和邻国土耳其最繁忙的机场的客流量,以便进行比较。

首先,我们需要导入将要使用的库和方法。

import pandas as pd
import numpy as np
import geoviews as gv
import geoviews.tile_sources as gvts
from geoviews import dim, opts
gv.extension('bokeh')

我们的两个数据框架greek_aiportsturkish_airports,分别由客流量排名前 10 位的希腊机场和前 5 位的土耳其机场组成。

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

Stats for 2018

对于这些数据帧,我们将添加一个额外的列country

greek_airports['country']= 'GR'
turkish_airports['country']= 'TR'

我们还将添加列color。你以后会明白我们为什么这样做。

greek_airports['color']= '#30a2da'
turkish_airports['color']= '#fc4f30'

现在如果我们把这两个数据帧合并成airports

airports = pd.merge(greek_airports, turkish_airports, how='outer')

airports数据帧看起来像这样。

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

airports dataframe

对于这个例子,我不需要citizens(k)列,所以我将删除它。

airports.drop('citizens(k)', axis=1, inplace=True)

所以最终的airports数据帧看起来会像这样。

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

airports dataframe

(对于那些想在笔记本上跟随的人,可以在这里找到airports数据框)

现在让我们开始使用 geoviews 模块。具体来说,让我们使用geoviews.Points功能创建一个带有我们的点的情节。

airports_gv_points = gv.Points(airports, ['longitude', 'latitude'],
                               ['IATA', 'city', 'passengers',
                               'country', 'color'])

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

airports_gv_points

为了在地图上标出这些点,我们需要一张…地图。geoviews 模块提供了许多我们可以使用的 tilemaps。如果我们输入的话,我们可以看到什么是可用的

gvts.tile_sources

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

Available tilemaps

例如,让我们使用 CartoLight tilemap。让我们看看我们能得到什么

gvts.CartoLight

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

CartoLight

现在,我们可以在 CartoLight 的顶部用

gvts.CartoLight * airports_gv_points

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

gv.Points on CartoLight

这里有几个问题:

  • 剧情维度真的很小。
  • 我不喜欢经纬度的轴标签。
  • 我不喜欢地图上的网格。

我可以通过在gvts.CartoLight上添加一些选项来解决这些问题,比如

gvts.CartoLight.options(width=1300, height=800, xaxis=None, yaxis=None, show_grid=False)  * airports_gv_points

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

geoviews.Points on CartoLight

现在,因为点仍然只是点,因此它们不能说明客流量,我将使用我们之前导入的opts方法。我们需要的参数是size。此外,为了让数字更接近,我将使用np.sqrt函数来获得它们的平方根。

airports_plot = (gvts.CartoLight * airports_gv_points).opts(
    opts.Points(width=1200, height=700, alpha=0.3,
                xaxis=None, yaxis=None,
                size=np.sqrt(dim('passengers'))*10))

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

airports_plot

如你所见,我们现在有了互动地图,显示了希腊和土耳其的机场有多繁忙。显然,雅典拥有希腊最繁忙的机场,而土耳其最繁忙的机场位于伊斯坦布尔。

为了使绘图更好,我们可以为每个国家使用不同的颜色,同时我们还可以添加一个悬停工具,以便在我们将光标移动到机场上方时获得一些关于机场的信息。为了添加颜色,我们添加了参数color=dim('color'),它使用我们在color列中指定的颜色,对于悬停工具,我们添加了参数tools=['hover']

airports_plot = (gvts.CartoLight * airports_gv_points).opts(
    opts.Points(width=1200, height=700, alpha=0.3,
                color=dim('color'), hover_line_color='black',  
                line_color='black', xaxis=None, yaxis=None,
                tools=['hover'],size=np.sqrt(dim('passengers'))*10))

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

airports_plot

我们甚至可以创建自己的悬停工具来完全控制悬停工具显示的内容。例如,我不希望它显示每个国家使用的颜色代码。
最后,当我将光标放在每个点上时,我希望每个点的颜色变暗一点,所以我添加了参数hover_fill_alpha=0.5

from bokeh.models import HoverTool
tooltips = [('IATA', '[@IATA](http://twitter.com/IATA)'),
            ('Passengers', '[@passengers](http://twitter.com/passengers){0.00 a}m'),
            ('City', '[@city](http://twitter.com/city)'),
            ('Country', '[@country](http://twitter.com/country)'),
            ('Longitude', '$x'),
            ('Latitude', '$y'),
            ]
hover = HoverTool(tooltips=tooltips)airports_plot = (gvts.CartoLight * airports_gv_points).opts(
    opts.Points(width=1200, height=700, alpha=0.3,
                color=dim('color'), hover_line_color='black',  
                line_color='black', xaxis=None, yaxis=None,
                tools=[hover],size=np.sqrt(dim('passengers'))*10,
                hover_fill_color=None, hover_fill_alpha=0.5)) 

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

airports_plot

如果你像我一样喜欢深色主题,你可以随时使用gvts.CartoDark tilemap。

airports_plot = (gvts.CartoDark.options(alpha=0.8) * airports_gv_points).opts(
    opts.Points(width=1200, height=700, alpha=0.3,
                color=dim('color'), hover_line_color='black',  
                line_color='black', xaxis=None, yaxis=None,
                tools=[hover],size=np.sqrt(dim('passengers'))*10,
                hover_fill_color=None, hover_fill_alpha=0.5))

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

airports_plot

今天到此为止。希望你觉得有用。下次见!

你可以点击这里在 LinkedIn 上找到我。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值