TowardsDataScience-博客中文翻译-2020-一百二十七-

TowardsDataScience 博客中文翻译 2020(一百二十七)

原文:TowardsDataScience Blog

协议:CC BY-NC-SA 4.0

使用 Python 的 Matplotlib 的华夫饼图表

原文:https://towardsdatascience.com/waffle-charts-using-pythons-matplotlib-94252689a701?source=collection_archive---------19-----------------------

如何使用 Matplotlib 库在 Python 中绘制华夫饼图表

资料来源:佩雷斯·冈萨雷斯的 Unsplash

华夫饼图表可能是仪表板中一个有趣的元素。显示实现目标的进度以及查看每个项目对整体的贡献尤其有用。但是如果你试图在里面放太多的项目,华夫饼图表就不是很有用了。r、Tableau 和 Python 都有用于华夫饼图表的包或函数。我将展示如何从头开始生成一个华夫饼干图表,并使用 pywaffle 中的华夫饼干函数。

要使用的工具

对于本教程,我们将使用:

  1. Numpy 图书馆
  2. 熊猫图书馆
  3. Matplotlib 库
  4. Jupyter 笔记本环境。

开发一个没有华夫饼包装的华夫饼图表

  1. 导入必要的包:
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.patches as mpatches

2.创建一个数据框架。在本教程中,我将制作一个数据图,假称从阿根廷、巴西、古巴和秘鲁移民到美国的人数。这些数字只是虚构的。

df = pd.DataFrame({
    'country': ['Argentina', 'Brazil', 'Cuba', 'Peru'],
    'number': [212, 334, 1500, 130] 
})

3.由于我们将呈现每个国家的移民人数对总数的贡献,我们需要知道总数。计算总数:

total = sum(df['number'])

4.计算每个国家的比例

proportions = [(float(value) / total) for value in df['number']]#Output:
[0.0974264705882353,
 0.15349264705882354,
 0.6893382352941176,
 0.05974264705882353]

5.指定图表的宽度和高度。然后计算华夫饼图表中瓷砖的总数

width = 40
height=10
total= width * height

6.确定每个国家将分配多少瓷砖

tiles_per_category = [round(proportion * total) for proportion in proportions]#Output:
[39, 61, 276, 24]

所有的数据准备都做好了。

来源: GIPHY

7.所有容易的工作都完成了。现在是棘手的部分。生成华夫饼。为此,我们将生成一个全零矩阵。然后用相应的类别替换每个零。这个矩阵将类似于华夫格图。

waffle = np.zeros((height, width))
category_index = 0
tile_index = 0for col in range(width):
    for row in range(height):
        tile_index += 1
        if tile_index > sum(tiles_per_category[0:category_index]):
            category_index += 1
        waffle[row, col] = category_index

8.选择颜色图并使用 matshow 显示矩阵

fig = plt.figure()
colormap = plt.cm.coolwarm
plt.matshow(waffle, cmap=colormap)
plt.colorbar()

9.添加一些美化元素,如蜱和网格

fig = plt.figure()
colormap = plt.cm.coolwarm
plt.matshow(waffle, cmap=colormap)
ax = plt.gca()ax.set_xticks(np.arange(-0.5, (width), 1), minor=True)
ax.set_yticks(np.arange(-0.5, (height), 1), minor=True)ax.grid(which='minor', color='w', linestyle='-', linewidth=2)plt.xticks([])
plt.yticks([])
plt.colorbar()

10.最后,添加图例来完成华夫饼图表。这是华夫饼图表的完整代码。如果您喜欢,您可以简单地保留这段代码,并在您的数据中重用它。

fig = plt.figure()
colormap = plt.cm.coolwarm
plt.matshow(waffle, cmap=colormap)
ax = plt.gca()ax.set_xticks(np.arange(-0.5, (width), 1), minor=True)
ax.set_yticks(np.arange(-0.5, (height), 1), minor=True)ax.grid(which='minor', color='w', linestyle='-', linewidth=2)plt.xticks([])
plt.yticks([])values = df['number']
categories = df['country']
value_sign = ''
values_cumsum = np.cumsum(values)
total_values = values_cumsum[len(values_cumsum) - 1]legend_handles = []
for i, category in enumerate(categories):
    if value_sign == '%':
        label_str = category + ' (' + str(values[i]) + value_sign + ')' 
    else:
        label_str = category + ' (' + value_sign + str(values[i]) + ')'
    color_val = colormap(float(values_cumsum[i]) / total_values)
    legend_handles.append(mpatches.Patch(color=color_val, label=label_str))

plt.legend(handles=legend_handles, loc = 'lower center', ncol=len(categories),
          bbox_to_anchor=(0., 0.2, 0.95, 0.1)) #positioning legends
plt.colorbar()

看,每个国家的移民人数对总人数的贡献是非常明显的

来源: GIPHY

如果情节中的元素太多,就不再那么清晰了。这是华夫饼图表的一个重要缺点

使用 Waffle 类开发 Waffle 图表

您需要使用以下命令安装 pywaffle 包

pip install pywaffle

现在从 pywaffle 包中导入华夫饼

from pywaffle import Waffle

使用与上一个示例相同的数据,使用 waffle 函数绘制一个 Waffle 图

fig = plt.figure(
    FigureClass=Waffle, 
    rows=10, 
    values=list(df.number/5),
    labels=list(df.country),
    figsize=(12, 8),
    legend={'bbox_to_anchor': (0.5, 0.5)}    
)

我试图展示如何使用 Matplotlib 库而不是 pywaffle 包来编写一个 waffle 图表,因为我认为这样可以给你更多的灵活性。使用 pywaffle 包也不错。这也可以制作一个像样的华夫饼图表,并很好地服务于您的目的。点击此链接了解更多关于 pywaffle 套餐的选项和细节。

非常感谢您阅读这篇文章。我希望这有所帮助。

推荐阅读:

Matplotlib 中的气泡图

Matplotlib 中的基本绘图:Python 中的可视化

Pandas 的详细分组功能,用于高效的数据汇总和分析

使用直方图和箱线图理解数据,并举例

如何在 Python 中展现多个变量之间的关系

等等,那么什么是 P 值?

原文:https://towardsdatascience.com/wait-so-whats-a-p-value-6fc50f362df1?source=collection_archive---------22-----------------------

概率值快速介绍

如果有人让你解释什么是概率值(p 值),你会怎么直观地解释?在本文中,我将探讨这个问题,并让你对 p 值的真正含义有一个直观的认识。

建立

先说个例子。假设我们有两个篮球队…

A 队——NBA 球员

B 队——高中全明星

为了这个例子,让我们假设 A 队全是 NBA 球员,B 队是高中全明星。鉴于这种天赋的不平衡,我们假设 A 队每场比赛获胜的概率是 99%。

分析

那么如果这两个队互相比赛 100 次会怎么样呢?A 队在 100 场比赛中赢 99 场的概率是多少?

99%你猜对了吗?

可惜低了不少。A 队在 100 场比赛中赢 99 场的概率大约是 37%。这可能看起来不直观,但是先忘掉这个数字,想想 A 队能赢多少场比赛。

A 队确实有大概率赢 99 场,但是它也有大概率赢 100 场或者 98 场。我们必须考虑到 A 队每场比赛都赢或者比 99 场比赛少*。左边的表格是 90+游戏获胜的概率。赢得 99 场比赛是最有可能的结果,但赢得 100 或 98 场比赛也是有可能的。*******

所以现在你可以问问自己,A 队赢 96 场的概率是多少?嗯,这种事发生的几率只有可怜的 1.49%。

注意,我们不会深入计算,但我在文章末尾列出了公式和一个 参考,此处为

结论

假设你去一个偏远的小岛度假一周,与外界没有任何联系。当你回来的时候,A 队和 B 队打了 100 场比赛,你的朋友问“嘿,如果我告诉你他们只赢了 93 场比赛呢?”“哈,我得说这种情况发生的概率不到 1%,你也不再是我的朋友了。”

虽然是开玩笑,但当你听到一种新药的成功具有统计学意义时,他们正在评估成功结果的可能性(想想玩游戏的次数)。如果成功的概率小于某个阈值(行业标准通常为 5%),则该结果被视为成功。即使这个结果有的随机几率发生,也不足以得出我们的结果是成功的结论。****

从高层次上讲,下次你听到一种新药显示出统计学意义时,想想…

在该公司进行的所有测试中,他们的药物对试验患者无效的可能性小于 5%。

感谢阅读!为了简单起见,我偏离了假设检验、不同的统计检验和置信水平。

公式使用

**********

排队模型

原文:https://towardsdatascience.com/waiting-line-models-d65ac918b26c?source=collection_archive---------10-----------------------

排队模型和排队论完全指南

排队模型。在 Unsplash 上由halance拍摄的照片

在这篇文章中,我将详细介绍排队模型。我将从商业角度讨论何时以及如何使用等待线模型。在第二部分中,我将深入研究多个特定的排队论模型,这些模型可用于特定的等待队列,以及排队论的其他应用。

排队模型介绍

等待线模型是用来研究等待线的数学模型。这个领域的另一个名字是排队论。

排队等候的方式有很多种。在主题公园里,你通常只有一条线。在超市里,你有多个收银员,每个人都有自己的等候队伍。在快餐店,你可能会遇到多名服务员和一个人排队的情况。

等待线模型的目标是描述等待线系统的预期结果 KPI,而不必为了经验观察而实现它们。等候线的结果 KPI 可以是,例如,人员成本的减少或顾客满意度的提高。

何时使用等待线模型?

只要你的情况符合等待线的概念,就可以使用等待线模型。这意味着,对于到达的客户机(或者您正在建模的任何对象),必须有一个特定的过程,对于服务器,也必须有一个特定的过程(通常是在得到服务后客户机离开系统)。

排队模型需要到达、等待和服务

这个想法可能看起来非常特定于等待线,但是实际上等待线模型有许多可能的应用。例如,等待线模型对于以下情况非常重要:

  • 计算机处理器和任务处理。许多任务同时到达你计算机的处理器,它必须一个接一个地处理它们,而不使计算机出故障。
  • 电信型号。例如,当许多消息在短时间内被发送,并且必须在限制消息的“等待时间”/“延迟”的同时被正确处理时。
  • 交通工程。例如,当许多汽车同时到达同一地点,他们必须等待时。
  • 复杂的多层系统具有多种服务的呼叫中心就是多条等候线连接在一起的一个例子。

使用排队模型的好处

想象一家商店,平均每分钟有两个人排队等候,每分钟也有两个人离开。这似乎是一条平衡的等待线,但是为什么首先会有一条等待线呢?

答案是平均值的变化。让我们看一个例子:

想象一条平衡的等待线,每分钟有 2 个人到达,每分钟有 2 个人被服务:

平衡中的等待线(来源:作者)

今天剩下的时间都在排队等候(来源:作者)

总之,使用等待线模型的好处是,它们允许根据特定等待线的组织情况,估计不同场景发生在等待线系统中的概率。

找到经济上最优的等待线

一个有趣的面向业务的排队建模方法是分析你的等待时间从什么时候开始对你的销售产生负面的财务影响。

数字巨头们已经在这方面做了一些有趣的研究。例如,亚马逊发现等待时间(页面加载)每增加 100 毫秒,他们就会损失 1%的销售额(来源)。这种类型的研究可以针对任何特定的等候线进行,以找到理想的等候线系统。

提示:在建立实际等待线模型之前,找到你的目标等待线 KPI

排队模型 KPI

等待时要遵循的主要财务 KPI 是:

  • 人事费
  • 等待时间的成本(机会成本)
  • 总成本

客观研究这些成本的一个很好的方法是试验不同的服务级别,并构建一个图表,x 轴表示服务量(或服务人员), y 轴表示成本。这给出了以下类型的图形:

寻找最佳的财务服务水平。(来源:作者)

在此图中,我们可以看到,服务级别为 30 到 40 时,总成本最小。即使我们可以在服务级别为 50 的情况下为更多的客户提供服务,这也抵不上员工成本。

概率 KPI 达到我们的目标-等待线

一旦我们设置好这些成本 KPI,我们就应该研究概率 KPI。这意味着:试图确定我们的等待线的数学定义,并使用模型来计算等待线系统达到某个极值的概率。

这种概率问题的例子有:

  • 每月至少“有可能”出现一次的最糟糕的排队情况是什么?
  • 有多少人会等超过 x 分钟?

等待线建模还可以模拟更长的运行时间和极端情况,以分析非常复杂的多级等待线系统的假设情景。

M/M/1 队列——标准的等待队列

我们将进入的第一个等待队列是最简单的等待队列。它有一条等待线和一个服务器。

最简单的排队系统

只要知道到达过程和服务过程的概率分布,这条等待线的所有 KPI 都可以用数学方法识别出来。

如果满足下列条件,这个等待系统称为 M/M/1 队列:

1。到达遵循泊松分布

泊松分布是一种著名的概率分布,它描述了在给定平均事件率的情况下,在固定时间范围内发生一定数量事件的概率。

如果之前的分析表明我们的到达遵循泊松分布(通常我们会将此作为一种假设),我们可以使用平均到达率,并将其代入泊松分布,以获得固定时间范围内特定数量的到达的概率。

以下示例显示了当到达率为 1/次且到达次数遵循泊松分布时,每个客户端到达次数的可能性。

我们使用泊松分布的原因很简单,在实践中,等待线上到达的变化经常遵循这个概率。还有其他选择,我们将在后面看到一个例子。

2.服务时间遵循指数分布

M/M/1 排队的第二个准则是服务持续时间服从指数分布。这意味着服务持续时间有一个平均值,以及围绕该平均值的变化,该变化由指数分布公式给出。

平均等待时间为 1 分钟的指数分布示例如下:

一个 M/M/1 排队模型的分析

对于 M/M/1 队列的分析,我们从以下内容开始:

  • 平均到达率(观察到的或假设的),称为λ(λ)
  • 平均服务时间(观察到的或假设的),定义为 1μ(mu)。服务时间可以通过做 1 / μ转换成服务率μ。

根据这些输入,使用 M/M/1 队列的预定义公式,我们可以找到等待线模型的 KPI:

1。分析我们的 M/M/1 队列的稳定性

只要λ < μ

It is often important to know whether our waiting line is stable (meaning that it will stay more or less the same size). For the M/M/1 queue, the stability is simply obtained as long as λ (lambda) stays smaller than μ (mu). This means that service is faster than arrival, which intuitively implies that people the waiting line wouldn’t grow too much.

2,M/M/1 队列就是稳定的。计算我们的 M/M/1 队列的利用率

第二个要做的分析是计算服务器被占用的平均时间。这叫利用率。利用率称为ρ (rho ),计算公式如下:

ρ = λ / μ

3.计算 M/M/1 队列中的客户数量

可以使用以下公式计算系统中的平均客户数量:

ρ/(1ρ**

客户平均数量的变化定义如下:

ρ/(1ρ)^2**

4.计算 x 个客户在我们的 M/M/1 队列中的概率

在客户数量上更进一步,我们也可以反过来问这个问题。与其问顾客的平均数是多少,我们可以问给定数量 x 的排队顾客的概率。

P (x 客户)=(1ρ)ρ^ x***

5.计算 M/M/1 队列中的平均响应时间

响应时间是客户从到达到离开所需的时间。包括等待和被服务。平均响应时间可以计算为:

1/(μλ)

6.计算 M/M/1 队列中的平均等待时间

平均等待时间可以计算如下:

ρ/(μλ**

M/M/1 队列示例 1

举个实际的例子,让我们把分析应用到一个小商店的等待线上。有一行和一个收银员,M/M/1 队列适用。假设收银员的平均工作时间是 30 秒,每分钟有两个新顾客进来。

  • ****稳定性:到达率λ为每分钟 2 个客户。服务时间 1 / μ为 0.5 分钟,所以服务率μ为 1 / 0.5= 2。我们注意到λ并不严格小于μ,因此这种情况是不稳定的。
  • ****结论:这不是一个好的排队规划,因为服务不够快,无法应对顾客的数量。

M/M/1 队列示例 2

作为解决方案,收银员说服店主给他买了一台更快的收银机,现在他平均能在 15 秒内处理一名顾客。然而,在某个时候,店主走进他的商店,看到 4 个人在排队。车主应该为此担心吗?

  • 稳定性: λ仍然是每分钟 2 个客户。服务时间 1/μ是 0.25 分钟,所以μ是 1 / 0.25 = 4。λ现在严格小于μ,因此这种情况是稳定的。
  • 使用公式 4。P (x 个顾客)=(1ρ)ρ^ x,我们可以计算出有 4 个顾客排队的概率。
    首先我们将ρ计算为λ / μ,则得出 2 / 4 = 0.5。
    然后我们计算
    P ( 4 个客户)=(1
    ρ)**ρ^ x
    p(4 个客户)= (1 — 0.5) * 0.5 ^ 4
    P ( 4 个客户)= 0.5 * 0.0625
    P ( 4 个客户)= 0.03125**
  • ****结论:有 4 个客户排队的概率比较低(100 个里面有 3 个左右)。这种情况可能发生在平均客户服务时间为 15 秒的情况下,但可能性不大。我们可以假设平均客户服务时间可能稍长,或者在那个时间有更多的客户进来。
  • 为了确保商店的正确运营,我们可以尝试调整 lambda 和 mu,以确保我们的流程在新数字下仍然稳定。

其他类型的队列

现在,我们已经了解了 M/M/1 队列的所有内容,接下来我们将讨论一些更复杂的队列类型。为了做到这一点,我们通常会更改名称中三个参数中的一个。这就是所谓的肯德尔符号。

肯德尔符号

我们通常有 3 种类型的流程:

  • m 代表马尔可夫过程:它们具有泊松到达和指数服务时间
  • d 代表到达之间的固定时间固定服务时间。d 代表确定性。
  • g 代表到达和服务时间的“任何”分布:将其视为“不确定分布”

末尾的数字是从 1 到无穷大的服务器数量。M/M/1,之前覆盖的队列代表马尔可夫到达/马尔可夫服务/1 服务器。带 G 的模型可能很有趣,但是已经为它们确定了一些公式。已经对 G 队列进行了一些分析,但我更倾向于将重点放在更实用和直观的 M 和 d 组合模型上。让我们来看看三个众所周知的队列:

  • M/M/c 队列—一条等待线上的多个服务器
  • M/D/c 排队——马氏到达,固定服务时间,多服务台
  • D/M/1 排队——固定到达间隔,马尔可夫服务和 1 个服务员

M/M/c 队列——一条等待线上的多个服务器

M/M/c 队列的特征在于:

  • 每个时间段到达人数的泊松分布
  • 服务持续时间的指数分布
  • 同一等待线上的“c”个服务器(c 的范围可以从 1 到无穷大)

这种情况的一个例子是在快餐店的等待线上,每个人都站在同一条线上,并且将由多个服务器中的一个来服务,只要到达是泊松分布并且服务时间是指数分布的。

其公式如下:

  • 服务器利用率ρ= λ / c * μ
  • 如果ρ < 1
  • Probability of observing x customers in line:

,则队列稳定

来源

  • 到达的顾客在到达时必须排队等候的概率是:

来源

  • 系统中的平均客户数量(等待和接受服务)为:

来源

  • 顾客平均花费的时间(等待+接受服务)是:

来源

M/D/c 队列—固定服务时间

M/D/c 队列的特征在于:

  • 每个时间段到达人数的泊松分布
  • 固定服务持续时间(无变化),称为 D 表示确定性
  • 同一等待线上的“c”个服务器(c 的范围可以从 1 到无穷大)

这种情况的一个例子可以是机场中用于安全扫描的自动照相亭。如果我们假设为每位乘客拍照花费的时间完全相同,并且人们按照泊松分布到达,这将符合 M/D/c 队列。

在只有一台服务器的更简单的常见情况下,我们有 M/D/1 的情况。适用于 M/D/1 情况的公式如下:

  • 服务利用率ρ = λ / μ
  • 系统中的平均客户数量是

来源

  • 队列中等待的平均实体数计算如下:

来源

  • 我们还可以计算顾客平均花费的时间(等待+接受服务):

来源

  • 平均等待时间可以计算为:

来源

  • 队列中有一定数量 n 个顾客的概率可以计算如下:

来源

当 c > 1 时,我们不能使用上述公式。我们需要使用以下内容:

  • 服务利用率ρρ=(λD)/c
  • 只要ρ1,等待线就稳定
  • 等待时间的分布如下:

来源

  • 系统中的客户数量为“n”或更少的概率可以计算为:

来源

D/M/1 队列——固定的到达间隔

D/M/1 队列的特征在于:

  • 到达之间的固定间隔( β) (D 表示确定性)
  • 服务持续时间的指数分布(速率 μ,平均持续时间 1 / μ) (M 为马尔可夫)
  • 1 台服务器

专用于 D/M/1 队列的公式有:

  • 如果μβ为 1,则队列稳定
  • δ 是绝对值最小的方程δ= e ^(-μβ(1—δ))的根。**
  • 到达顾客的平均等待时间为(1/μ)δ/(1—δ)
  • 零顾客队列的平均时间(空闲时间)为 β — 1/ μ
  • 系统中有一定数量客户的概率是:

来源

特殊排队——队列变量概述

在本文的最后一部分,我想展示在对等待队列建模时,许多不同之处会付诸实践。在某些情况下,我们可以找到合适的公式,而在其他情况下,我们可能很难找到合适的模型。

以下是您可能遇到的各种变体的概述

  • ****线路数量:一些队列被分割成多条线路(或者由系统分割,或者由客户选择)
  • ****阶段数量:一些队列被分成多个阶段,例如在外卖餐馆,队列通常被分为点菜和取餐两个阶段。
  • ****优先级规则:有些队列有特定的优先级规则,会影响系统的吞吐量。
  • 批量排队:一些系统成批提供服务(如主题公园景点),或者有时顾客成批到达,但却是一对一地服务(如对刚着陆的飞机上的每个乘客进行护照检查)。
  • ****杰克逊网络:有时多个队列在服务节点相互连接,从而创建队列网络。多层等候队伍的一个例子是呼叫中心,你从一个代理人到另一个代理人,每一步都更靠近出口。
  • ****犹豫表示客户拒绝在队列过长时加入。如果已知顾客没有耐心,这可能是排队系统中的一个重要因素。
  • ****出尔反尔指进入后离开队列。如果这种情况经常发生,你可以考虑两阶段排队,这样人们就不太可能离开。或者改善平均等待时间。
  • 变换位置意味着从一个队列换到另一个队列。对于你的情况来说,这可能有问题,也可能没有问题,但是它可能对你的计算的正确性有影响。

结论

看完这篇文章,你应该对分析上众所周知的不同的等待线模型有所了解。由于对排队论的研究,在实践中把排队论应用到等待线上变得相对容易了。

对于一些复杂的排队问题,可能更难找到解决方案,因为这可能需要更理论化的数学方法。

我希望这篇文章能为你进入排队模型和排队论提供一个很好的起点。感谢阅读!

带着动作识别环游世界

原文:https://towardsdatascience.com/walking-around-the-globe-with-action-recognition-64bceaa65435?source=collection_archive---------57-----------------------

古伊列梅·斯特卡内拉在 Unsplash 上的照片

如何在家使用 AI 技术环游地球?

在本文中,我们将构建一个能够使用 Tensorflow 识别一些动作的应用程序,并将结果发送到 Google Street View,由它来执行这些动作。下面的 GIF 显示了应用程序的输出:

实时动作识别示例及其在谷歌街景中的应用

在开始之前,需要注意的是有两个人参与了这个项目。因此,在本文中,我们将使用复数。

有各种各样的方法来解决这个问题:在意识到没有多少现成的动作识别模型来重新训练所需的动作后,任何人脑海中出现的第一个想法可能是使用在具有不同动作的巨大数据集上训练的卷积神经网络,将每个图像映射到人正在执行的动作。该领域受过更多培训的人可能会考虑使用 Inception Network 或 ResNet,并在 ImageNet 或 COCO 数据集上转移学习。

然而,经过一些思考后,人们可以意识到,将图像输入神经网络并期望获得准确的分类是远远不现实的。模型将如何识别人在哪里?如果图像中不止一个人呢?假设地球上有和人一样多的体形,我们如何做出一个可接受的概括?

通过前面的段落,我们想指出,在某些情况下,最初的想法并不是更好的想法,对问题的反思可能会导致更深入、更稳健的解决方案。(看到我们在那里做了什么吗?)

“两阶段”方法

在我们看来,这不是一个单一的神经网络可以解决的问题,至少有两个阶段必须顺序工作:首先,应该有一种检测人身体关键点(或接合点)的方法,从而解决不同体型的问题。第二,分类系统应该在第一阶段的结果上工作,以关键点作为坐标,并且以这种方式使其不知道初始图像的具体属性。

动作识别的基本模型

  1. 姿态检测

姿势检测的问题非常广泛,对于我们大多数必须在 Google Colab 中训练他们的模型的人来说,这可能是不可估量的。幸运的是,有一些选项(训练过的模型)表现很好并且具有很高的准确性,比如 PoseNet 或者 OpenPose 。这里我们只有一个小条件:选择的模型必须在推理模式下以合适的帧速率运行,因为我们希望实时识别动作。

姿态估计。来源:https://www . tensor flow . org/lite/models/pose _ estimation/overview

受限于这个条件,我们准备选择 PoseNet,即使在手机中也是实时运行的。此外,PoseNet 更容易使用,因为它提供了 Tensorflow Lite 和 tfjs 文件。PoseNet 有两种不同的“风格”:MobileNet 和 ResNet,第一种更快,但是(经过一些试错过程)非常不准确。因此,我们将使用以 ResNet 为主干的 PoseNet。

一旦我们得到了关键点,下一步就是用分类模型识别动作。

2.分类模型

让我们停下来想一想,我们要对哪些动作进行分类:行走、向左或向右看、站立。从关键点的角度来看,第一个(行走)与最后一个(站立)的不同之处在于它们跨帧的移动:行走是不同站立帧的拼接,而站立是相等站立帧的拼接。因此,对分类模型的输入必须来自一系列帧,而不是一个单独的帧。以前的模式应该相应地改变:

动作识别的选定模型

因为我们想要处理时间演化,所以一个好主意是选择递归神经网络,其输入将具有维度(#帧,#关键点),其中#帧表示预测动作所需的图像数量。此外,人们必须注意到关键点带有一定程度的信心,这意味着从一帧到下一帧可能会有“消失”的关键点。为了解决这个问题,我们施加了这样的条件,即一个系列的第一帧应该呈现眼睛和臀部,并且在同时出现的帧中消失的关键点将通过先前的高置信度关键点来推断。这一推理的动机来自于这样一个事实,即一幅图像在两帧之间不会有很大的不同,为了实现这一点,我们需要一个高的帧速率。

我们将使用一个带有一层 LSTM 细胞的 RNN,后面跟着一个前馈神经网络。使用正常反向传播和 SGD 进行训练,下面的图片显示了训练过程的准确性(左)和损失(右):

左:模型精度。右:损失。绿色表示培训结果,灰色表示验证结果

识别出这个动作后,剩下的唯一工作就是将它传输到谷歌街景中。鉴于街景可以通过键盘控制,Selenium 是一个很好的选择,可以让我们与网页进行交互。建立连接后,向前执行一步,向驱动程序发送一个点击:

使用 Selenium 在谷歌街景中前行

并且按键事件将向左或向右移动相机:

使用 Selenium 旋转谷歌街景的摄像头

这样,关于如何制作一个动作识别系统的基本概念将被涵盖。如果您想改进我们的模型或者只是玩玩它,请随意浏览 GitHub 中的资源库。

[## 移动人工智能/虚拟行走

在隔离期间,由于新冠肺炎疫情,我们现在有权利在街上自由行动…

github.com](https://github.com/Moving-AI/virtual-walk)

此外,让我知道任何关于模型或文章本身的方法的建议或意见。

走过线性回归

原文:https://towardsdatascience.com/walking-through-a-linear-regression-dca9942111e4?source=collection_archive---------6-----------------------

机器学习过程的全面分解

卢卡·布拉沃在 Unsplash 上的照片

处理数据时,线性回归是基础算法。它被广泛使用,是现有的最适用的监督机器学习算法之一。通过执行线性回归,我们试图捕捉预测自变量( X1,X2 等)和预测因变量( Y) 之间的最佳线性关系。让我们一起来看看 Python 中的线性回归模型过程。包含所有代码和数据的存储库可以在这里找到。

该设置

我们将使用一个模拟数据集来代表一家公司的汽车座椅销售。该公司希望他们的数据团队建立一个模型,在给定一个包含多个预测独立变量的数据集的情况下,该模型能够准确地捕捉和预测他们商店所在地的汽车座椅销售活动。变量描述如下:

  • 销售额:每个地点的单位销售额
  • CompPrice:在每个地点最接近的竞争对手收取的价格
  • 收入:社区收入水平
  • 广告:公司在各地的本地广告预算
  • 人口:该地区的人口规模(以千计)
  • 价格:每个站点汽车座位的收费价格
  • 搁置位置:现场搁置位置的质量(好|差|中)
  • 年龄:当地人口的平均年龄
  • 教育:每个地点的教育水平
  • 城市:商店位于城市还是农村
  • 美国:无论商店是否在美国

销售将是我们的因变量(或目标),其余 10 个变量(特征)将被处理和操纵,以协助我们的回归。在这一点上,注意我们的变量由什么组成是很重要的。我们有某些变量,如收入、广告或人口,这些都是基于整数的变量。然而,我们也有像 Urban、USA 和 ShelveLoc 这样的变量。这些变量的值代表分类值(是/否;好/差/中等;等等。).随着我们的进展,我们将会看到如何解释这些差异,在这个阶段,重要的是要注意到它们是不同的。(利用 Python 中的‘df . info()’命令将有助于识别变量值的构成。

这是我们数据帧的快照:

df.head()

预处理

令人震惊的是,预处理阶段是我们在构建模型之前准备数据框架及其内容的阶段。在此阶段,我们将执行训练-测试-分割,使用编码处理上述分类变量,最后处理可能出现的任何缩放问题。

我们需要做的第一件事是将数据框架分成目标系列和预测系列。x 将是我们的独立变量的数据框架,而 y 将是我们的目标特征。

X = df.drop('Sales', axis = 1)
y = df.Sales

现在我们已经有了每个分割,我们可以执行训练-测试-分割。这一步对我们的机器学习模型至关重要。我们将数据分为“训练”组和“测试”组。训练集将用于我们的模型进行实际学习,我们的测试集将用于验证输出,因为我们已经知道这些值。为了让我们访问这个特性,我们必须从 Sklearn 导入它。我们有 400 个数据条目,这是一个足够大的数据量,所以我们将对我们的训练量和测试量分别使用 70/30 的比率(对于函数中的 test_size 参数)。

from sklearn.preprocessing import train_test_splitX_train, X_test, y_train, y_test = train_test_split(X, y, test_size = .30, random_state = 33)

接下来,我们需要进行一些快速清洁程序。让我们从训练数据集中删除任何重复值或缺失值。

X_train.drop_duplicates(inplace = True)
X_train.dropna(inplace = True)

处理不同的数据类型

如前所述,区分数据集中的数据类型至关重要。这要求我们将数字数据(整数或连续数)与分类数据(二进制结果、用数字表示的位置等)分开。).至此,所有的数据类型都包含在我们的 X_train 中。

X_train.info()

我们在第三列中看到了数据类型,其中除了三个特性之外,所有特性的数据类型都是“int64”,这意味着我们的数据帧将该数据解释为整数。这些将被视为我们的数字数据。剩下的三个分类变量将被暂时排除。

数字数据

下面的代码块将选择所有数据类型的特性,不包括我们的分类数据“object”。第二行和第三行代码只是从我们的 X_train 中带来了列标题。

X_train_numerics = X_train.select_dtypes(exclude = 'object')
X_train_cols = X_train.columns
X_train_numerics.columns = X_train_cols

为了验证这一点,下面左边是我们新的纯数值型数据集的数据信息。下图右侧是我们的数字数据帧的快照。

尽管我们现在已经收集了所有的数字数据,但是我们的预处理工作还没有完成。现在我们必须了解每个数字序列包含什么。例如,“CompPrice”代表来自另一个竞争对手的美元数字,而“Education”代表每个地点的教育水平,但我们没有任何进一步的信息。人口代表(以千计)一个地区有多少人。即使这些都是数字数据的形式,我们也不能真正比较它们,因为单位都是不同的!我们如何处理这个难题?缩放!

缩放我们的数据

缩放将允许我们所有的数据转换成一个更正常的分布。我们将使用 Sklearn 的 StandardScaler 方法。该函数将通过移除平均值并缩放至单位方差来有效地标准化各自的特征。此函数将允许我们移除某个要素(比如 CompPrice,由于其较大的值)对预测变量产生不正确影响的任何影响。

from sklearn.preprocessing import StandardScaler
from scipy import statsss = StandardScaler()X_train_numeric = pd.DataFrame(ss.fit_transform(X_train_numeric))
X_train_numeric.set_index(X_train.index, inplace = True)X_train_numeric.columns = X_numeric_cols
X_train_numeric.head()

首先,我们导入并实例化一个 StandardScaler 对象。然后,我们拟合并转换我们的数字数据帧,并将索引特征设置为等于我们的原始 X_train 的索引特征。这将确保我们对正确的数据条目进行操作。我们必须再次设置列名,因为它们在通过 StandardScaler 对象时被删除了。我们得到的数据如下所示:

我们注意到一些事情。我们的数据值不再像以前那样了。我们已经去除了原始特征的任何和所有大小差异,它们现在都是一致的尺度,没有任何单个特征对我们的预测变量有不准确的影响。

去除异常值

我们处理数字数据的最后一步是移除任何异常值。异常值可能会导致要素数据的不准确表示,因为少量的输入值可能会对另一个变量产生不准确的影响。我们将通过使用“stats”包并过滤任何 z 得分值大于平均值 2.5 倍标准差的值来实现这一点。

X_train_numeric = X_train_numeric[(np.abs(stats.zscore(X_train_numeric)) < 2.5).all(axis = 1)]

分类数据

现在我们已经准备好了数字数据,我们想处理分类数据。让我们把我们的分类数据隔离到它自己的数据框架中,看看我们在处理什么。这与使用 numeric 时的第一步相同,我们只需将“select_dtypes”方法中的参数从“exclude”更改为“include”。

X_train_cat = X_train.select_dtypes(include = 'object')

右图向我们展示了我们的分类数据框架实际上看到了什么。如果我们的计算机能够理解如何解释“好”、“中等”或“是”,这将是非常酷的,但不幸的是,它还没有那么智能——我们将稍后保存 NLP 模型;).此时,我们需要通过一个称为编码的过程将这些值转换成我们的计算机可以理解的东西。

编码分类数据

让我们开始处理我们的城市和美国变量。这些变量都是二进制的(“是”或“否”),所以我们想把它们用二进制值表达给我们的计算机,而不是“是”或“否”。我们将使用 sklearn 的 LabelBinarizer 函数来实现。要使用该函数,我们首先为每个特性实例化一个 LabelBinarizer()对象,然后对每个特性执行 fit_transform。

from sklearn.preprocessing import LabelBinarizerurban_bin = LabelBinarizer()
us_bin = LabelBinarizer()X_train_cat.Urban = urban_bin.fit_transform(X_train_cat.Urban)
X_train_cat.US = us_bin.fit_transform(X_train_cat.US)

我们得到的数据帧现在用 1 表示“是”,用 0 表示“否”。现在让我们把注意力转向“ShelveLoc”特性。因为这个特性不再有二进制值集,所以我们必须使用不同类型的编码。我们将为每个值创建一个新的二进制变量,并删除原来的特性。这将允许计算机解释哪个变量具有“真”二进制值,然后给它分配一个整数。我们实际上是为每个值创建虚拟变量。这听起来有点令人困惑,但是让我们来看看它的实际应用。我们将使用熊猫。get_dummies()函数将每个值分配给一个虚拟变量。注意:我们通过“drop_first = True”参数来避免我们的数据帧中的自相关,这是 基本的

X_cat_prepped = X_train_cat.merge(pd.get_dummies(X_train_cat.ShelveLoc, drop_first=True), left_index=True, right_index=True)X_cat_prepped.drop('ShelveLoc', axis = 1, inplace=True)

我们现在可以很容易地看到分类值选项是如何被转换成新的二进制变量供我们的计算机解释的。

现在我们已经完成了数字和分类数据类型的预处理,我们将它们合并回一个完整的准备好的数据帧。

X_train_prep = pd.merge(X_cat_prepped, X_train_numeric, left_index = True, right_index = True)

我们的最后一步是设置我们的 y_train 来包含正确的条目。请记住,当我们考虑到重复、缺失值和异常值时,我们在训练测试分割后从我们的 X_train 中删除了几个条目。该步骤确保我们的 y_train 与我们的 X_train 长度相等且准确。

y_train = y_train.loc[X_train_prep.index]

建立线性回归模型

我们已经处理了模型的本质,即预处理。一旦我们有了准备好的数据,构建实际的线性回归模型就相当简单了。我们将首先导入一个线性回归模型,并从 Sklearn 实例化它。然后,我们将 X_train_prepy_train 拟合到我们的线性回归对象。最后,我们将利用。predict()方法来预测我们未来的值。

from sklearn.linear_model import LinearRegressionlr = LinearRegression()lr.fit(X_train_prep, y_train)y_hat_train = lr.predict(X_train_prep)

我们的模型现在已经完全建立和预测好了。为了了解我们的模型表现如何,我们将利用两个指标:一个 r 平方值均方根(rmse)。

  • R 平方:数据与我们拟合的回归线接近程度的统计度量(也称为“拟合优度”)。范围是[0,1],其中 r2 = 1.00 意味着我们的模型解释了响应数据围绕其平均值的所有可变性,而 r2 = 0 意味着我们的模型解释不了任何可变性。R2 越高,模型越好。
  • RMSE: 预测值向量和观测值向量之间的归一化相对距离。“小”值表示误差项更接近预测的回归线,因此证明模型更好。RMSE 越低,模型越好。
from sklearn.metrics import r2_score, mean_squared_errorprint(f"r^2: {r2_score(y_train, y_hat_train)}")
print(f"rmse: {np.sqrt(mean_squared_error(y_train, y_hat_train))}")

上述函数将通过我们的训练集和预测集( y_hat_train )来建立模型性能的度量分数。

我们的两个指标看起来都非常好!我们的 r2 值 0.88 告诉我们,我们的模型已经捕获了我们的平均投影周围的 88.6%的可变性。对于我们的 RMSE,我们可能需要多个模型进行比较,因为它们是一个相对的衡量标准。如果我们运行另一个模型并返回 RMSE = 1.5,我们的第一个模型将是两个模型中较好的。

线性回归假设

当执行 OLS 线性回归时,在模型建立和预测之后,我们剩下最后一步。这些回归有一些模型假设,如果它们不满足,那么我们的结果就不能被认为是稳健和可信的。这些假设之所以存在,是因为 OLS 是一种参数技术,这意味着它使用从数据中学到的参数。这使得我们的基础数据必须满足这些假设。

1。线性度

线性假设要求我们的目标变量(销售额)与其预测变量之间存在线性关系。试图将非线性数据集拟合到线性模型会失败。最好用散点图来测试。由于离群值的存在会产生重大影响,因此删除离群值对于这一假设非常重要。因为这个数据集是根据线性假设随机生成的,所以我们不需要为我们的数据测试这个假设。

2.常态

正态假设要求模型残差应遵循正态分布。检验这一假设最简单的方法是通过直方图或分位数-分位数图(Q-Q-Plot)。

  • QQ 图:通过绘制两个概率分布的分位数来比较它们的概率图。这张图有助于我们了解样本是否呈正态分布。该图应显示一条正直线,剩余点在直线上。如果我们的残差线有失真,那么我们的数据表明是非正态分布。
from statsmodels.graphics.gofplots import qqplotqqplot(residuals, line = 'q')

正如我们在上面看到的,蓝色的观测点始终以线性模式下降,向我们证明了我们的残差是正态分布的。这个假设现在得到了验证。

3.同方差性

同方差性表示因变量在自变量的值之间具有相等的方差。我们的残差在回归线上应该是相等的。如果不满足这一假设,我们的数据将是异方差的,我们的变量散点图将是圆锥形的,表明我们的独立变量值的方差不相等。要查看我们的残差:

residuals = y_hat_train - y_trainplt.scatter(y_hat_train, residuals)

我们没有看到任何类似圆锥曲线的形状,也没有证据表明所有值的方差不相等,所以我们可以说这个假设也得到验证。

总结

我们现在已经完成了线性回归的整个过程。希望这个笔记本可以为一个非常强大和适应性强的机器学习模型提供一个良好的开端。同样, GitHub 库可用于所有代码。在我的下一篇博客中,我将通过一个非常强大的数据科学工具——特征工程来改进这个模型!

演练:在 Python 中映射 GIS 数据

原文:https://towardsdatascience.com/walkthrough-mapping-gis-data-in-python-92c77cd2b87a?source=collection_archive---------6-----------------------

视频教程

地理数据似乎从未像现在这样重要。本文将提高您对地理空间信息的理解,通过简洁、易于使用的 pandas 数据框架,让您进入丰富的地理信息科学(GIS)世界。

简介 | 活动 | 资源

通过遵循这些代码,您将学会在 Google Colab 的虚拟环境中托管的 Jupyter 笔记本中导航地理形状文件。最后你会得到一些非常漂亮的地图,突出显示 DC 华盛顿州的住房情况。

地理信息科学(GIS)可能是一个相当复杂的领域,因此请将本演练视为一个入门教程。为了跟进,你需要有一个免费的 Google Drive 账户——所以如果你还没有的话就去设置吧。谷歌提供了 15GB 的免费存储空间,所以至少你的硬盘上会有更多的空间来存放潮湿的地理信息系统迷因。

在本演练中,您将从 DC 的开放数据门户上传数据,然后从 Google 的 Colab 平台连接到这些数据集。在这个环境中,我们将对数据集进行一些分析,并最终制作地图。

本教程中提到的所有资源,包括 Google DriveGoogle ColabTableau Public ,都是免费的——不需要你的信用卡,没有注册试用期,没有“你的第一个孩子叫什么名字,Rumpelstiltskin?”废话。

如果您不想参与代码跟踪,单击此处链接到完整的 Colab 笔记本和本练习中使用的其他材料。但是你听过他们说的旅程比目的地更重要吗?让我们开始演练吧!

目录

  1. 简介 | 映射成表 | | 数据结构
  2. 活动 | 虚拟环境 | 数据收集 | 打码
  3. 总结 | 资源

将地图翻译成表格 | 地理空间包 | 地理空间数据结构

将地图转换成表格

在本练习中,我们将在 Google Colab 托管的 Jupyter 笔记本中创建一个地图,显示分区豁免的位置。此分析将直观地回答以下问题:

我们如何对 DC 华盛顿州获得分区豁免的建筑进行分类?

展示 DC 华盛顿州分区豁免的地图

如果你想了解更多关于 DC 分区豁免的信息,以及它们如何代表企业利益和公平发展之间的脆弱妥协,请查阅这篇文章。

由于多种原因,使用地理数据可能会很困难。首先,数据科学家可能会对许多层次的信息感兴趣。其次,这些信息并不总是以一种易于格式化为表格数据帧的方式来组织。

GIS 流程中图层的图示

处理 GIS 数据通常需要压缩不同类型的非结构化物理和政治信息。为了给这些数据的数字表示提供意义,我们将使用坐标参考系统(CRS)的初始化来导入数据集中的每个“层”。这组数字(例如 epsg:4326)构成了地球的标准坐标框架——解释了空间中的点如何相互关联( 阅读更多 )。

例如,在本演练中,我们将查看建筑物的物理位置,用经度和纬度表示,以及它们在 DC 华盛顿州的政治边界内的位置(基于 EPSG 的标准 4326 CRS)。

下面是我们在设置 CRS 时如何导入数据集的预览。不要太担心理解这段代码的每一个方面——它将在演练部分详细解释。

Python 的地理空间包

GeoPandas 是在 Python 中操作地理数据的基本包

如果你使用 Python 已经有一段时间了,你可能对熊猫有些熟悉。本质上来说,熊猫在 Python 方面更胜一筹。您可以将数据组织为行和列,并使用类似于 Excel 的功能执行操作,甚至更多。

GeoPandas 是一个建立在这些能力之上的库,能够从 GIS 包 Shapely 中建模点、线和多边形。您还需要导入几个名为 rtreespatialindex 的附加包来支持 GeoPandas 中的操作。

相关包的导入语句——我们将在代码部分回到这个问题

注意:要让 rtree 在您的本地环境中运行,我建议使用家酿软件包管理器 brew 安装 spatial index

地理空间数据结构

为了保存数据集中的地理空间信息,这些信息保存在一个 shapefile 中。shapefiles 不是一个文件,而是由几个组件组成,每个组件都有自己的扩展名。这组文件将共享相同的文件名前缀,并且应该存储在一个目录中。

下面是这些文件在您的文件系统中的样子。

使用 shapefile 时,其中三个组件文件是必不可少的:

  • 。shp —提供对每个记录的直接访问的主文件,作为具有顶点列表的形状
  • shx — 索引文件,包含记录相对于主文件开头的偏移量
  • DBF-dBASE 表文件,包含基于主文件“几何图形”栏的特征属性

“几何”列是保存地理空间信息的字段,即数据的形状,无论是点、线还是多边形。在我们的例子中,“geometry”列中的每条记录都包含一个多边形,它代表了 DC 一个免分区建筑的物理轮廓。

在 shapefile 的地理数据框表示中,您可以看到“几何”列包含一个面或多面对象,其坐标表示每条记录的折点

虽然在使用 GIS 数据库和制图应用程序时非常有用,但 shapefiles 也有一些主要限制:

  • 列标题的最大长度为 10 个字符
  • 文本字段的最大长度为 254 个字符
  • 最大字段数为 255

我们需要记住这些约束,因为我们将从该活动中导出数据集作为 shapefile。当通过添加新列来操作 GIS 数据时,我们需要将列名控制在 10 个字符以内。如果我们希望将一长串文本与每条记录相关联,我们会将该信息与主地理数据框架分开存储(例如,作为熊猫数据框架,我们可能会将其导出为 csv 或 json ),以避免该文本被截断。最后,如果我们处理非常宽的数据帧,我们需要注意不要超过 255 列。

虚拟环境中的 GIS|数据采集 | 代码跟踪

虚拟环境中的 GIS

Google Colab 为 Python 编码提供了一个智能且轻松的虚拟环境/虚拟机设置

我们将在 Google Colab 中做这个演练。沿着其驱动产品(文档、表格、幻灯片等)的路线。),Google Colab 提供了一个云设置,让工作变得更加容易。

Colab 是基于 Jupyter Notebook 技术为 Python 用户构建的,因此任何不熟悉这个平台但熟悉 Jupyter 的人都应该立即对逐个单元格的执行格式感到放心。有了 Colab,你的代码在云中执行,笔记本存储到 Google Drive。这种设置使得 Colab 成为临时项目以及那些需要协作的项目的绝佳选择。

以下是 Google Colab 用户体验的几个亮点:

  • 通用虚拟环境预装了数百个最常见的 Python 包
  • Colab 笔记本存储在 Google Drive 中,可以下载为。ipynb 文件
  • 只需传递链接即可轻松共享笔记本,收件人无需下载、安装或运行任何东西

最后这一点使得 Colab 成为与非技术观察者分享发现、建立同事间协作或创建教育资源的理想媒介(就像这个演练!)

数据收集

本练习的数据来自 DC 的开放数据门户。查看他们关于规划单元开发(又名 PUDs——又名分区豁免)和经济适用房的页面。在 PUDs 页面上,您需要从下拉选项中下载 shapefile。从经济适用房,我要请你下载电子表格。我知道也有一个用于经济适用房的 shapefile 选项,但出于本练习的目的,我想浏览一下获取常规 ol 数据文件(如 csv)并赋予其特殊地理空间属性的过程。

一旦你下载了数据,你需要把它上传到你的谷歌硬盘。为了便于在代码运行期间访问数据,请设置以下文件结构:

  • 从你的 My Drive 文件夹(如果你愿意,可以称之为 Google Drive 存储系统的根目录)创建一个名为 gis 的文件夹
  • 在该文件夹中,创建输入输出文件夹
  • 输入文件夹中,解压后上传 bufferentable _ housing . CSV 以及规划单元开发文件夹中的所有文件

使用这些精确的命名约定和组织系统,或者在代码编写过程中对导入/导出语句进行必要的更新,这一点很重要。

你还需要一个我为这个活动做的人行横道。你可以在这里得到那个文件——然后把 csv 文件也上传到你的输入文件夹。

确保您的文件夹和文件的命名约定与此屏幕截图相匹配

Google Colab 中的代码

接下来,我们将使用新的 Google Colab 笔记本电脑。为此,您需要前往colab.research.google.com并点击新建笔记本。这将在您的 Google 帐户独有的虚拟机上打开一个 Jupyter 笔记本。

从 Google Colab 的欢迎页面移到一个空白的笔记本,在这里我们可以一个单元一个单元地执行 Python 代码

一旦到达那里,您可以通过键入来检查 Colab 环境中预装的所有包!皮普别动。因为 Colab 虚拟镜像了 linux 操作系统的设置,我们可以使用与 bash shell 交互!在虚拟 Colab 终端上执行代码的神奇命令。然后通过点击看起来像播放按钮的东西或者用快捷键 Command / Ctrl + Enter 来运行单元格。

!pip freeze 显示了 Google 环境中预装软件包的完整列表

在本演练中,我们将主要使用 GeoPandas,它构建在更常用的 Pandas 包之上。虽然 pandas 已经安装在 Google Colab 环境中,但是我们还需要安装更具体的 GIS 包。为了将这些特定于地理空间的包引入 Google 的环境,请通过运行以下代码来安装它们:

注意:这里我们使用 linux 的安装语法( apt-get )将一个 spatialindex 包引入 Colab 环境。这个包是 rtree 的一个依赖项,而 rtree 又是 GeoPandas 强大的地理空间连接方法的一个依赖项。sjoin()。如果你是一个想在本地机器上复制它的 Mac 用户,我推荐你使用家酿软件包管理器 安装 spatialindex

接下来,我们将把 Google Colab 连接到 Google Drive。这是一种管理小型数据科学项目并将相关数据存储在云中的好方法。

此时,Google 会要求您提供一个授权码,您可以从提供的链接中抓取并粘贴到 Colab 的文本框中。现在这款 Colab 笔记本已经链接到你的 Google Drive 了!这非常方便——现在我们可以读取 Google Drive 云中的任何文件,也可以导出到 Google Drive。

不要迷路,确保你有正确的文件夹设置

这是我们导入数据文件的地方。只有 PUDs shapefile 具有 GeoPandas 可以解释的地理空间属性。模仿熊猫的。read_csv()方法,GeoPandas '。read_file()函数需要指向. shp 的文件路径。然后,我们需要使用之前讨论过的标准 crs 来初始化地理空间属性。

在下面的代码中,pud。shp shapefile 组件作为地理数据框读入,而两个 csv 文件作为标准 pandas 数据框读入。

注意:为了使这个工作,重要的是你把你的文件系统设置成我的驱动器>GIS>输入 >文件。如果您在这方面有问题,请查看数据收集部分的屏幕截图。

就检查数据集的一些初始方法而言,我建议您运行一些。info()和。每个数据帧上的 sample()方法。您将看到这些函数在 GeoPandas 和 dfs 上的工作方式与它们在 Pandas 上的工作方式相同。提醒一下,你可以把 GeoPandas 想象成一个附加的功能层,它位于熊猫的上面,形状优美。所有与 pandas 相关的功能都应该很好地转移到我们的地理数据框架中——我们稍后将利用一些合并功能。

正如我们在 GeoPandas 简介中所讨论的,如果您查看 PUDs 地理数据框架,您会注意到最后一列“几何图形”包含表示分区豁免建筑物外部的多边形矢量。

接下来,我们来解决将经济适用房 csv 转换为地理数据框架的项目。我们将通过将经度(' X ')和纬度(' Y ')包装在一个形状优美的点对象中来实现这一点,如下所示:

现在当我们。sample()df,您将看到一个“geometry”列,其中包含每个记录的 POINT 对象。。info()确认数据类型已转换为地理数据框架。

要根据地理交叉点合并数据集:

现在,我们有了一个主地理数据框架,其中包含相同地理位置的分区豁免以及经济适用房项目的信息。因为我们将 puds df 左连接为左表,所以生成的 geo-df 保留了 puds 的“geometry”列,并从表中删除了 aff df 的“geometry”列。

最后一步——与分区类别合并人行横道将分区代码转换成简单的英语,将分区豁免的建筑物分类为商业、住宅或其他/混合用途。

现在,让我们看看这些 pud 如何归入每个分区类别。使用一行代码即可在地理数据框上创建地图。plot()函数——这绝对不是一个普通的熊猫 df 所能做到的。

DC 免分区建筑地图,按分区类别着色

各位,这是一张彩色的 DC 华盛顿州分区豁免地图。

让我们再来看一个——这次是提供经济适用房的分区豁免建筑的位置。

在 Google Colab 中,您可以做更多的事情,但是假设您想暂停数据探索,开始考虑创建一个工具来与世界共享这些信息。为此,我们将从 Colab 中导出 shapefile,如下所示:

就是这样!

为了操作我们到目前为止所做的工作,你可以考虑创建一个Tableau Dashboard——但这是另一篇文章的主题。

Tableau Public 一起开发的分区豁免仪表板

总结

在这个练习中,我们学习了如何使用 Python 的 GeoPandas 包在 Google Colab 托管的笔记本中制作地图。你可以在这里找到所有的资料,包括一个完成的 Colab 笔记本所有需要的数据集

资源

GIS 简介:

DC 华盛顿州的分区豁免和住房:

虚拟环境/包管理:

使用 Python 的其他制图演练:

只是为了好玩:

想成为“真实世界”的数据科学家?

原文:https://towardsdatascience.com/want-to-be-a-real-world-data-scientist-make-these-changes-to-your-portfolio-projects-e61d1139c018?source=collection_archive---------47-----------------------

对您的投资组合项目进行这些更改。

注:

我注意到这个库的所有代码最初都在付费墙后面。不幸的是,我换了公司,失去了所有这些代码。

幸运的是,我重新编写了它——现在它可能更好了(尽管可能与原始代码略有不同)。储存库可以在这里找到。

下面的任何断开的链接应该导致这个回购代替。干杯!

简介

无论你想成为软件工程师、数据科学家、机器学习工程师,还是人工智能工程师;构建一个解决数独的应用程序是一个很好的项目组合。

这是一个如此伟大的项目,以至于 Peter Norvig 在这里写了一篇关于解决这个问题的惊人帖子。然后 Aaron Fredrick 写了另一篇关于如何解决这个问题的好文章。事实上,如果你想要一个不同语言的数独解决方案,你可以从以下每个人那里找到相应语言的解决方案:

  • 保罗·费尔南德斯的 C++
  • 由 Richard Birkby 编写的 C#和 LINQ 版本
  • 贾斯汀·克莱默的 Clojure 版本
  • Andreas Pauley 的 Erlang 版本
  • 伊曼纽尔·德拉博德的哈斯克尔版本
  • 约翰尼斯·布罗德沃尔的 Java 版本
  • 布兰登·艾希的 Javascript 版本
  • Pankaj Kumar 的 Javascript 版本
  • 卢德派极客的红宝石版本
  • 红宝石版作者马丁-路易·布莱特

鉴于这个问题已经被许多不同的人用许多不同的语言解决了很多次,你如何让你的解决方案脱颖而出呢?

让你脱颖而出的一个方法是扩展现有的解决方案。例如,亚伦的解决方案包括建立一个卷积神经网络,以便在解谜之前处理数独图像。这增加了另一层复杂性,它显示了他对深度学习解决方案的舒适性。

另一种脱颖而出的方法是展示你的 软件工程技能 作为你解决方案的一部分。具体来说,雇主寻找的是那些已经了解

  • 测试
  • 林挺
  • 证明文件
  • 记录

除此之外,对于任何新用户来说,编写易于使用和维护的代码也很重要。在这篇文章中,我们将关注测试、林挺文档。

假设我们从 Github 中所示的初始解决方案开始。我们如何着手改变这个解决方案来展示我们的技能?

测试

在你开始写你的解决方案之前,你可能应该写测试。你的脑海中可能会闪现一幅如下图所示的画面,但这并不完全是我想要的…

法师最初发现这里

python 中的测试是一种确保您打算编写的代码按照您期望的方式执行并提供您期望的输出的方法。

在这个例子中,编写测试可能意味着知道一个特定的起始难题的解决方案,然后将我们代码的结果与已知的解决方案进行比较。

一个健壮的测试工具包将有一系列不同的例子来测试。下面你可以看到一个简单的例子,其中容器和解决方案是由函数提供的。你可以想象有多个这样的例子,其中你将container定义为起始数独,container_sol是相应的解。

你也可能有一些边缘情况。我想到的三个例子是

  • 如果我有一个空的板子,它有多种可能的解决方案呢?
  • 如果我的起始板违反了有效的解决方案,该怎么办?例如,如果同一行中有两个 1,或者同一列中有两个 2,该怎么办?
  • 如果一块起始板的值大于 9 或小于 1,该怎么办?

您可以在这里找到一个文件,其中包含我的每个测试用例的函数。下面你可以看到我们如何引入SudokuSolver,并将求解器的解(code_sol)与我们的测试解(sol)进行比较。

我们可以为我们的每个测试用例设置如上所示的案例。好消息是,两个“正常”的测试用例——在函数test1sudoku_tests.pytest2中找到——可以用现有代码轻松处理。

不幸的是,边缘案例留给我们的是一个永远不会结束的程序。因此,我们需要编写代码来处理这些边缘情况。这非常简单(尽管有些乏味),因为我们提前编写了测试,并且我们知道每种情况应该如何处理。

下面你可以看到一个函数,它将根据上面提到的三种情况来检查以确保任何提供的数独puzzle都是有效的。

从这个函数来看,如果返回值是False,那么我们的谜题就是有效的。如果返回其中一个字符串,那么我们的谜题由于该字符串指定的原因而无效。

林挺

现在我们所有的测试用例都准备好了,我们将开始编写我们的解决方案。众所周知,第一个解决方案可能会完成任务。也就是说,它解决了问题,但是代码可能没有被很好地文档化,不容易阅读,或者没有使用最佳的编码实践。这样就可以了!

重要的是找到解决问题的节奏,不要对编码最佳实践太过焦虑,否则你根本写不出任何东西!然而,当你有了一个可行的解决方案,你应该回去重构你的代码,提高它的可读性,看看它是否可以被优化。

我通过将现有代码改为 python class开始了我的重构。我编写测试的方式要求是这样的,而且很简单,把现有的函数放在一个class体中,在必要的地方放上一堆self。重构一个类的结果在这里可用

此时,可以从您的终端运行该文件来查看两个示例,使用:

$ python sudoku.py

以上将产生两个起始谜题,以及每个谜题对您的主机的解决方案。

如果这个文件与您的sudoku_tests.py在同一个目录中,您可以运行:

$ python sudoku_tests.py

上面的命令不会产生任何结果,因为您的所有测试现在都应该通过了!

Tumblr 上找到的图片

从这里,我们应该可以看到我们的代码是如何遵守 Python 标准的,也就是所谓的 PEP8 。这些不是严格的规则,而是指导方针。

通过运行以下命令,您可以了解您的代码符合这些准则的程度:

$ pylint sudoku.py

你会得到一个问题列表,以及一个分数:Your code has been rated at -0.60/10。而且,问题的清单很长。您可能会直接开始手动修复每个项目,但是有一些库可以帮助您加快这个过程。

最初在这里找到的图像

有一个 autoPEP8 库可以用来快速清理代码。要安装,请运行以下命令:

$ pip install —-upgrade autopep8

然后使用新的库运行:

$ autopep8 --in-place --aggressive --aggressive sudoku.py

让我们看看这在多大程度上改进了我们的解决方案。

$ pylint sudoku.py
Your code has been rated at 7.95/10 (previous run: -0.60/10, +8.56)

看起来这是一个显著的进步。虽然仍然有一个相当大的变化列表,主要属于

  • 间隔
  • 未使用的变量
  • 变量命名
  • 文档字符串

虽然使用林挺的输出,每个修复都是不言自明的,但要完成完整的列表可能需要一些时间。同样,这些更多的是作为指导方针,而不是严格的规则,所以这取决于你有多在乎做出特定的改变。

我创建了refactor-branch,它包含了与master相同的代码,但是sudoku.pysudoku_tests.py文件分别针对8.76/109.32/10进行了重构。你可以在这里查看的修改。考虑到这些分别从-0.60/10-46.60/10开始,这已经很不错了。

证明文件

正如你已经从林挺过程中看到的,记录你的工作是非常重要的!针对这种特殊情况的文档意味着提供信息性的README.md;每个脚本的文档;以及每个脚本中每个函数、类和方法的文档字符串。

我们在上一节中使用的pylint可以通过简单地在必要的地方提供空字符串来欺骗。然而,Google Style Python Docstrings提供了一个很好的指南。

就写一篇好的自述而言,Akash 的帖子很好地解释了一篇好自述的来龙去脉。对于这个特定的项目,我们不需要所有这些组件,但是这给了你一个好主意,当你创建一个自述文件时应该考虑什么。

一般来说,你的自述文件对于让个人与你的代码互动是非常重要的。如果你想让人们看到你的作品,附上一份好的自述。我经常在项目的最后写我的自述,因为我想变得非常有用并且与代码相关。通常我不知道如何向读者解释一些事情,直到我写完所有的代码!

你可以在下面看到我的模块字符串的例子。请注意,它包括如何运行脚本的示例,以及关于脚本用途的信息。

然后类和方法字符串应该遵循 Google 的协议,这意味着类文档包含ArgsAttributes。方法字符串包含ArgsReturns。如果有你认为对用户有帮助的附加信息,你也可以把它包括进去。

下面是一个例子,您可以用它来创建自己的函数字符串:

我们也可以按照相同的格式向sudoku_tests.py文件添加文档字符串。由于测试并不真正供其他人使用,所以愿意在这个文档上花费更少的时间似乎是合理的,但是您可以在上面链接的存储库中再次看到结果。

在完成文档的最后,我通过运行以下命令重新运行pylint来查看更新的分数:

$ pylint sudoku.py

$ pylint sudoku_tests.py

sudoku.pysudoku_tests.py的最终得分分别为9.66/1010.00/10

最后,让我们把自述文件放在一起!整理自述文件没有完全正确的答案。为了展示数据科学项目,一个好的自述文件的大纲可能与创建一个生产库(这是上面 Akash 的自述文件的作用)有很大不同。对于我的项目,我通常尝试在我的自述文件中包含以下部分,但是还是没有正确的答案:

  • 一个项目的标题
  • 项目的简短描述
  • 项目的动机
  • 一些关于用户如何与你的代码交互或使用你的代码的指示。
  • 对你在项目中使用资源和获得灵感的地方给予肯定。
  • 一个许可证如果对其他人如何使用你的代码有任何限制的话。

你可以在我的库的documentation-branch上看到sudoku.py的完整文档。

这样,您的项目看起来前所未有的专业,您已经准备好与全世界分享它了!

想打入数据科学?开始建造

原文:https://towardsdatascience.com/want-to-break-into-data-science-start-building-db5ed24a7d77?source=collection_archive---------33-----------------------

为什么您应该先构建,后提问

📸克里斯托弗·伯恩斯

这篇帖子的灵感来自于一个得到很多人喜爱的 Twitter 帖子

要找到一份数据科学家、机器学习工程师或任何编写软件的工作,需要的不仅仅是数学和编程知识。在现实中,这些角色需要你每天做出数百个决定。

这些可能是重大决策,比如:

  • 我应该如何以及在哪里存储我的数据?
  • 我应该使用哪种算法?
  • 我应该使用哪些框架和库?
  • 我使用什么平台来托管我的模型?

或者微小的决定,比如:

  • 我给这个函数取什么名字?
  • 我应该遵循哪些格式规则?
  • 我如何处理这种边缘情况?

更好地做出这些决定需要练习,而练习的唯一方法就是做事情。这就是为什么我们强烈鼓励sharpes minds的导师和学员专注于构建端到端的 ML 项目。收集和清理数据,训练模型,部署它。在这条管道中隐藏着如此多的不同规模的决策。

构建端到端项目的压力迫使你做出许多选择 类似于你在构建真实产品的工作中所做的选择。事实上,将您的数据科学项目视为产品会有所帮助。与其只是训练一个模型来证明自己可以,不如试着解决一个真实的问题。

没必要把这个类比扯得太远。把建立一个有利可图的企业作为一个业余爱好项目,虽然令人印象深刻,但却是矫枉过正。像对待产品一样对待你的项目的好处是鼓励你从一个问题开始并找到解决方案。你使用的技术栈和你在构建时做出的决定将取决于问题所强加的约束。

从一项技术开始,并试图找到使用它的方法,这在工业界是很少见的。然而,这是许多业余爱好项目的必经之路。如果你唯一的工具是锤子,而那个锤子是深度神经网络,那么每个问题都开始看起来像深度学习钉。但是大多数钉子不需要神经网络——它们需要一把锤子,或者仅仅是一块石头。

公司不会因为知道特定类型的算法而雇佣人(尽管数据科学面试有时会让它看起来是这样)。公司雇人解决问题,为工作挑选最好的工具,做出正确的决定。

构建解决真实用例的东西将会引入你在千篇一律的数据科学项目和 Kaggle 竞赛中看不到的权衡。如果在另一端有一个真实的人在等待结果,你可能需要优化推理时间而不是准确性。如果是高度监管的行业,隐私性和可解释性会更重要。这些是你在工作中必须做出的权衡。

没有经验很难擅长这些决策和取舍。对于许多职业来说,你需要找到一份工作来开始积累经验。但是当涉及到数据科学和机器学习时,有一个奇妙的区别——你可以在被雇用之前获得足够的经验。怎么会?由造东西。

当你开始构建时,你将面临的数百个决策的答案一开始并不明显。你会犯错误。但是这些错误正是学习发生的地方。在构建的中途,您可能会意识到您最初选择的框架并不支持您需要的功能。但是下一次当你面临类似的决定时,你会因为亲身经历过这个错误而获得更多信息。

这些类型的错误也是面试的好题材。解释你所面临的挑战和你在建造过程中所学到的东西是展示你解决问题的技巧和学习能力的好方法。“我最初用 X 实现了这个,但结果是 X 不太擅长处理 Y,所以我用 z 做了重构。”这是我想从候选人那里听到的故事——,当然还有更多细节。

然而,在构建端到端的机器学习项目时,存在冷启动问题。作为初学者,很容易陷入决定什么是“最好的”框架或“正确的”数据库的困境。我看到人们经常陷入这种计划陷阱。我也去过那里。

走出陷阱的方法是认识到行动比不行动更好。从你最熟悉的工具开始。他们会让你更快地建立和学习。如果它们是错误的工具,你会从直接的经验中找到原因。如果你完全是新手,就选择一个流行的工具,边学边用。TensorFlow vs. PyTorch,PostgreSQL vs . MySQL——如果你不知道其中的取舍,其实也无所谓。选择一个并开始建造。这是你开始学习权衡的唯一途径。

想要建立有效的机器学习模型?

原文:https://towardsdatascience.com/want-to-build-effective-machine-learning-models-aws-recommends-these-steps-to-follow-b11f52cd9a41?source=collection_archive---------50-----------------------

AWS 建议遵循以下步骤

不到一个月前(2020 年 4 月初),AWS 宣布发布关于 AWS ML 最佳实践的官方白皮书。这是一份 78 页长的白皮书,充满了有用的信息,涵盖了机器学习最佳实践的所有方面,从定义问题到分析 ML 模型结果。

在本文中,我将用 15 分钟的时间总结 AWS ML 最佳实践白皮书。如果您没有时间阅读完整的 78 页白皮书,那么这篇文章就是为您准备的。如果你是机器学习的初学者或专业数据科学家,或者正在准备 AWS ML 专业考试,那么这篇文章也适合你。我确保用简单易读且没有行话的语言写这篇文章,这样它可以适合每个人。

声明:我建议阅读白皮书原文,以获得充分的好处。

数据有更好的想法。来源: Unsplash

让我们开始看看这篇 ML 最佳实践论文是关于什么的。

官方 AWS ML 最佳实践白皮书分为 3 个主要部分。

  • 定义 ML 堆栈和 ML 工作量阶段
  • 一般设计原则&参考架构
  • 从 ML 的角度来看,架构良好的框架的 5 个支柱

我们将一起浏览上述每个部分并理解它们,现在开始。

定义 ML 堆栈和 ML 工作负载的阶段

ML 栈 可以分为 3 个桶,如下图所示。AWS 希望迎合所有专业水平,并使 ML 民主化。

Bucket 1 AI 服务是像 AWS 翻译、转录、Polly、Rekognition 等预建的服务。用户不需要任何 ML 知识来使用这些服务,简单的 API 调用就能得到答案。

机器学习栈

Bucket 2 ML 服务主要是 AWS SageMaker 的所有口味,AWS 的 ML 旗舰,用户需要 ML 知识来使用 SageMaker 的工具标记数据,构建,训练,部署,操作定制 ML 模型。AWS SageMaker 是完全托管的,这意味着用户不需要担心基础设施,因为 AWS 会做繁重的工作。

Bucket 3 ML 框架&面向高级用户的基础设施。AWS 将为他们提供预装了 TensorFlow、PyTorch、MXNet 等主要开源框架的容器和计算基础设施。他们可以从头开始建立自己的模型。

ML 工作负载 是端到端的机器学习过程如下图所示。

端到端的机器学习过程。来源: AWS ML 白皮书

AWS 的白皮书详细介绍了流程中每个步骤的最佳实践。前 3 个步骤是关于业务需求、定义 ML 问题和收集数据。

第一步是业务目标识别这基本上是后退一步,问自己为什么要这样做,这里是否需要 ML,应该监控哪些关键绩效指标(KPI)。

然后是 ML 问题框架步骤,定义输入,给出 ML 模型和期望的输出。这一步你要知道是分类还是回归还是聚类问题等等。

数据收集步骤之后,您确认数据可用性并将其收集到数据湖中。我在下图中总结了这些步骤的 AWS 最佳实践。

ML 构建流程前 3 步的 AWS 最佳实践

一旦您收集了 ML 模型的数据,就到了数据准备步骤。这一步非常重要,你应该花很多时间,因为

ML 模型的好坏取决于用来训练它们的数据

在这里,您应该利用 AWS SageMaker 等 AWS 服务来标记和准备您的数据,或者利用 AWS GroundTruth 来标记原始数据并生成高质量的训练数据集。您还可以利用 AWS Glue,它是一个完全托管的提取、转换和加载(ETL)服务。如果你需要 Hadoop 或 ApacheSpark 或 HBase 框架,那么你可以使用 AWS EMR。

一旦你的数据准备好了,可视化&分析步骤将帮助你更好地理解和识别你的数据模式。AWS 提供了一套可视化工具,如 AWS SageMaker,您可以在其中托管 Jupyter 笔记本并使用 seaborn 或 matplotlib 或 plotly 等库。AWS Athena 是一个完全托管的服务,可以查询您的 S3 数据湖,AWS Kinesis 数据分析提供实时分析功能。最后,AWS QuickSight 是一个商业智能(BI)工具,为故事板提供安全的共享和协作。

现在到了特征工程步骤,在该步骤中,您考虑数据集中的每个属性,并决定它与您的模型的相关程度,是否需要转换或提取。在这一步中,您可能会遇到维数灾难,因为您有大量的相关要素,并且想要减少它们。最好使用带有 AWS SageMaker 的 Jupyter notebook 或 SageMaker Processing 中的内置数据处理容器来完成特征工程。

这 3 个步骤的 AWS 最佳实践总结如下。

ML 构建流程后三步的 AWS 最佳实践

ML 构建过程的最后 3 步是有趣的,在这里你将看到你所有努力的结果。

现在你已经有了一个干净的数据集,所以是时候进行模型训练步骤了,在这里你选择适合你的业务问题的最大似然算法。您必须调整您的模型的超参数,以实现低训练误差,并避免过度拟合&欠拟合。常用的超参数的一些例子是学习率、时期数、隐藏层、隐藏单元和激活函数。您将使用 AWS SageMaker 完成所有这些工作,其中您的所有数据都在 S3 数据湖中,并且您可以调用 SageMaker 的 API 进行培训。您还可以利用 AWS SageMaker 调试器来警告您模型训练问题,如梯度值变得过大或过小。根据你的专业水平,你可以使用 AWS 深度学习 AMI 或深度学习容器,并在其上运行开源框架,如 TensorFlow、PyTorch、MXNet、Horovod 和 Keras。

上一步是模型&业务评估,用于确定模型的性能和准确性是否能让你实现业务目标。您可以使用历史数据或实时数据评估您的模型。在这两种情况下,您的模型将会看到以前在训练中从未看到过的数据。对于评估,您应该利用 AWS SageMaker、AWS 深度学习 AMI 或 AWS EMR。如果你对结果不满意,你可以随时调整和重新训练你的模型。对模型的结果感到满意后,就该在生产中部署它了。

最后,是进行推理的时候了,您的模型正在部署中,您希望从中获得一个预测。模型部署选项包括 AWS SageMaker,您可以通过 API 调用进行推理,您可以使用非常灵活且可定制的 AWS SageMaker 推理管道。不要忘记使用 SageMaker 模型监视器,该监视器持续监视生产中的 ML 模型的输入数据漂移和模型质量偏差。如果您正在使用 edge 或物联网(IoT)设备,请利用 AWS SageMaker Neo 在 edge 设备上进行编译。您还可以使用 AWS 弹性推理,它允许您将低成本的 GPU 推理加速附加到您正在使用的任何 EC2 或 SageMaker 上。

ML 流程最后 3 个步骤的 AWS 最佳实践总结如下。

ML 构建流程最后 3 步的 AWS 最佳实践

一般设计原则和参考架构

在本文的这一部分,AWS 确定了一组通用设计原则,以促进良好的 ML 云设计。让我们看看他们。

  • 通过高质量数据的可用性实现敏捷性
  • 从简单开始,通过实验进化
  • ****将模特培训&评估与模特主持分离
  • 检测数据漂移
  • 自动化培训&评估流程
  • 偏好更高的抽象以加速结果

然后,本文介绍了一些常见的场景,并展示了它们的 AWS 参考架构实现。我将把每个场景分解成业务问题、实现和参考架构。

场景 1:使用 AWS AI 服务构建智能应用

****业务问题零售店希望捕捉和分析客户人口统计数据,以提高客户参与度和体验。

****实现使用多个 AWS AI 服务层,几乎不需要 ML 知识。

****参考架构利用 AWS Rekognition 进行面部分析,向 AWS Athena 发送数据以分析面部属性数据,最后通过 AWS QuickSight 可视化分析数据。请注意,所有这些都是完全托管的 AWS 人工智能服务,具有预先训练的模型。下面显示的参考架构也可以应用于文本或音频分析,但在这些情况下,您应该使用 AWS 转录(音频分析)或 AWS 理解(文本分析)而不是 AWS 识别。

参考架构:客户人口统计分析。来源: AWS ML 白皮书

基于相同参考架构构建的是媒体分析用例。假设您想要上传一个媒体文件,并使用多个 AWS AI 服务来进行视频和音频分析。最终目标是一个可搜索的元数据库。AWS 的人员推荐以下参考架构,他们使用 AWS Step 函数来编排媒体分析流程,并使用 AWS ElasticSearch 来使内容可搜索。

参考架构:媒体分析。来源: AWS ML 白皮书

场景 2:使用托管 ML 服务构建定制 ML 模型

****业务问题你想在 AWS 上建立自己的模型,因为没有一个 AWS 人工智能服务能满足你的需求。你要控制数据准备&分析、模型训练&评估、模型推断的步骤。

实施 AWS SageMaker 可以端到端地完成所有这些功能,同时完全由 AWS 管理。AWS Lambda 支持事件驱动架构,并将 ML 流程的不同阶段连接在一起。

****参考架构假设亚马逊 S3 充当原始数据、建模数据、增强数据和转换数据的数据湖。AWS 推荐以下参考架构,用于构建您自己的模型以及从摄取到推断的流程。

参考架构:使用 SageMaker 构建自己的 ML。来源: AWS ML 白皮书

场景 3:用于数据处理的托管 ETL 服务

****业务问题您正在开展一项有针对性的营销活动,并希望通过电子邮件和短信向消费者发送信息。您需要一个 ML 模型来根据历史消费者购买模式识别正确的客户。

实现 AWS Pinpoint 是一个托管服务,可以通过各种渠道发送目标消息。在 AWS EMR 上利用 Spark 或 Hadoop。

****参考架构使用多种服务的 AWS 推荐流程如下所示。

参考架构:使用 AWS Pinpoint 的定向活动。来源: AWS ML 白皮书

场景 4:边缘和多平台上的机器学习

****业务问题在你计算能力有限的边缘考虑物联网和设备。例如,您想在边上建立一个鸟类物种标识。

实现 AWS 物联网 Greengrass 在边缘设备上实现机器学习。AWS 物联网 Greengrass 使用在云中创建、训练和优化的模型,可以轻松地在设备上本地执行 ML 推理。

****参考架构展示了 AWS DeepLens,这是 AWS 的相机,带有预训练的 ML 模型。请记住,AWS 通过 AWS SageMaker Neo 支持英特尔和 Invidia 等多种硬件平台,check 的 AWS 网站提供物联网支持的设备。SageMaker Neo 有编译器和运行时。针对特定硬件进行了优化。

参考架构:边缘的鸟类物种识别。来源: AWS ML 白皮书

场景 5:模型部署方法

****业务问题建立模型后,你应该有一个简单的方法来推断模型并得到预测。

****实现使用 AWS SageMaker 端点,这些是 HTTPS 端点,您可以使用它们对您的模型进行 API 调用。

参考架构 AWS 根据您的需求推荐了 4 种部署模型,我总结如下。

参考架构:AWS 部署模型。图片来源: AWS ML 白皮书

从 ML 的角度来看,架构良好的框架的 5 个支柱

AWS 通常在云中有 5 个架构良好的框架支柱,本文的这一部分从机器学习的角度来看这 5 个支柱。我将以问答的形式对它们进行总结。

ML 架构良好的框架的 5 大支柱

卓越运营支柱

这是运行、监控和洞察系统以交付业务价值并持续改进支持流程和程序的能力。

  • 你是如何让你的团队做好运营和支持机器学习工作负载的准备的?

确保 ML 模型有效集成到生产环境中并满足业务目标的最佳实践包括确保团队之间的交叉协作,以及培训所有负责支持和维护机器学习工作负载的资源达到基本熟练水平。

  • 您如何记录模型创建活动?

为了更清楚地支持和使用模型版本,请记录模型创建过程,尤其是与所做的假设、模型所需的数据预处理/后处理以及将系统或应用程序与模型版本集成相关的过程。SageMaker 笔记本和 SageMaker Studio 提供托管笔记本环境,数据科学家可以在其中记录他们的开发过程和实验。这些笔记本可以与源代码控制系统集成,并成为为每个部署的模型创建的文档的标准部分。

  • 你是如何追踪模特血统的?

SageMaker 实验允许您组织和跟踪 ML 模型的迭代。SageMaker Experiments 自动捕获每个模型的输入参数、配置和输出工件,并将它们存储为实验。这避免了使用手动跟踪或者构建定制的跟踪解决方案来管理为模型开发的每个迭代创建和利用的输入和输出工件的众多版本。

  • 你是如何为你的 ML 工作负载自动化开发和部署管道的?

创建管道的一般准则包括使用编排层(如 AWS CodePipeline ),并结合负责执行管道内各阶段的逻辑。使用 AWS Lambda 创建和执行基于函数的逻辑,因为它的运营开销低,无需管理服务器。

  • 您是如何监控和记录模型托管活动的?

SageMaker 自动监控核心系统指标,还包括为您的托管模型设置自动扩展功能的能力,以根据需求动态调整支持端点的底层计算。SageMaker Model Monitor 能够监控生产中的 ML 模型,并在出现数据质量问题时发出警报。最佳实践包括创建一种机制,使用服务来聚合和分析模型预测端点指标,如 Amazon Elasticsearch,内置对 Kibana 的支持,用于仪表板和可视化。

  • 你怎么知道什么时候用新的或者更新的数据重新训练 ML 模型?

最佳实践是表示模型性能和准确性的已定义指标,确保有一种机制来定期捕获这些指标以进行分析和基于指标阈值发出警报,并评估是否适合重新训练模型。SageMaker Model Monitor 可以在数据分布发生变化时检测模型漂移,并使用 AWS CloudWatch 发布指标。

  • 您如何在模型开发、模型训练和模型托管的迭代之间整合知识?

这包括所有维度的模型评估:业务评估、ML 模型评估和系统评估。通过提供对收集的关键运营指标的集中可见性,团队可以持续审查并对您的运营进行回顾性分析。

安全支柱

这是在提供业务价值的同时保护信息、系统和资产的能力。

  • 你如何控制对自己 ML 工作量的访问?

对 ML 流程各阶段使用的所有资源的访问,包括数据、算法、超参数、经过训练的模型工件和基础设施,必须通过基于最低特权的访问进行严格控制。这可以使用 AWS IAM 轻松完成。

  • 您如何保护和监控对 ML 工作负载中使用的敏感数据的访问?

使用亚马逊 S3 上的 AWS Lake Formation 实现了集中式数据湖。保护和监控亚马逊 S3 上的数据湖是通过使用各种服务和功能的组合来加密传输中的数据和静态数据,并监控访问,包括粒度 AWS IAM 策略、S3 存储桶策略、S3 访问日志、AWS CloudWatch 和 CloudTrail。构建大数据存储解决方案(数据湖)以获得最大的灵活性讨论了如何使用这些不同的功能来构建安全的数据湖。

  • 你是如何保护训练有素的 ML 模特的?

在训练阶段结束时生成的 ML 模型通常保存在亚马逊 S3 中。使用私人 VPC 端点将在您的 VPC 内训练的模型上传到亚马逊 S3。这确保了模型在 AWS 网络内安全地传输到亚马逊 S3。当使用 Amazon SageMaker 训练一个模型时,该服务会加密传输中和静态的模型工件和其他系统工件。SageMaker 托管端点使用 IAM 为保护您的模型和调用提供了额外的安全性。这使您能够控制哪些 IAM 用户、IAM 角色、源 VPC 或 IP 可以对您的模型执行推理。

可靠性支柱

这是系统通过动态获取计算资源来缓解问题,从而从任何类型的服务中断中恢复的能力。

  • 你如何管理你的机器学习模型和预测端点的变化?

创建一种机制,以便能够跟踪对模型所做的更改以及对预测端点所做的更改。如果新型号的性能不如预期,这样可以更快地排除故障并恢复到以前的型号版本。部署新型号时,AWS 推荐标准 A/B 测试策略。使用 AWS 弹性容器注册中心(ECR)来托管所有的容器图像。

  • 如何在您的工作负载中协调 ML 模型的变更?

遵循已定义的变更管理策略来引入变更,并将它们传达给受影响的团队,并实现这些变更的可追溯性。以治理和控制应用程序级变更的相同方式管理新模型版本的部署。ML 模型的变更管理策略必须考虑如何传达和部署变更,以帮助避免服务中断以及模型性能和准确性下降。

  • 您如何扩展端点托管模型进行预测?

您必须包括对端点的监控,以确定触发添加或删除资源来支持当前需求的阈值。一旦收到扩展的触发信号,必须准备好解决方案来扩展支持该端点的后端资源。对端点执行负载测试,以便能够验证它们有效伸缩和可靠提供预测的能力。

  • 如何从一个训练好的 ML 模型的失败或无意丢失中恢复?

意外删除是一个问题,为了保护模型工件不被意外删除,请确保模型工件受到保护,方法是只允许使用工件所需的最低权限,实现额外的机制,如 MFA 以供特权用户删除,并根据您定义的灾难恢复策略的要求存储工件的辅助副本。此外,实现工件版本化策略允许恢复特定的版本化工件。

  • 您如何从模型托管资源的故障或意外丢失中恢复?

最佳实践是确保负责承载模型预测的端点可以完全恢复到业务定义的特定版本或时间点。恢复模型端点的能力要求用于创建该端点的所有组件和配置都包括在受管版本控制策略中,以在任何组件不可用时实现完全恢复。

绩效效率支柱

这集中于计算资源的有效使用以满足需求,以及如何随着需求的变化和技术的发展保持这种效率。

  • 您如何选择最合适的实例类型来训练和托管您的模型?

数据大小、数据类型和算法的选择对哪种配置最有效有明显的影响。当重复训练同一个模型时,强烈建议在一系列实例类型中执行初始测试,以发现高性能和经济高效的配置。建议将 GPU 实例用于大多数深度学习目的,因为在 GPU 上训练新模型比在 CPU 上更快。当您有多个 GPU 实例时,或者如果您使用跨多个 GPU 实例的分布式培训,您可以进行次线性扩展。然而,重要的是要注意,在 GPU 上训练最有效的算法可能不一定需要 GPU 来进行有效的推理。

  • 您如何在保持最佳性能的同时扩展 ML 工作负载?

SageMaker 代表您管理您的生产计算基础架构,以执行运行状况检查、应用安全补丁和进行其他日常维护,所有这些都通过内置的 CloudWatch 监控和日志记录来实现。SageMaker Model Monitor 持续监控生产中的 ML 模型,检测诸如数据漂移等会降低模型性能的偏差,并提醒您采取补救措施。此外,SageMaker 主机使用应用程序自动伸缩功能,自动伸缩到您的应用程序所需的性能。

您可以选择使用亚马逊弹性推理(EI)进行扩展,以增加吞吐量并减少针对深度学习模型的实时推理的延迟。Amazon 弹性推理使您能够将 GPU 支持的推理加速附加到任何 Amazon EC2 实例上。

成本优化支柱

这是建立和运行成本感知系统的能力,以实现业务成果和最小化成本,从而使您的企业最大化其投资回报。

  • 如何优化数据标注成本?

利用 AWS SageMaker Ground Truth,它通过 Amazon Mechanical Turk、第三方供应商或他们自己的员工使用人工标注器来简化数据标注任务。SageMaker Ground Truth 实时从这些人工注释中学习,并应用主动学习来自动标记剩余数据集的大部分,从而减少人工审查的需要。与单独的人工注释相比,这降低了成本。

  • 你如何在 ML 实验中优化成本?

SageMaker notebook 实例提供了一个托管的 Jupyter 环境,可用于探索小样本数据。当您不经常使用笔记本实例时,请停止它们。在可行的情况下,提交你的工作,停止它们,并在你需要它们的时候重启它们。存储是持久的,您可以使用生命周期配置来自动化软件包安装或存储库同步。

查看 AWS 机器学习市场,该市场提供了不断增长的机器学习算法和模型目录。来自 AWS Marketplace 的模型被直接部署到 Amazon SageMaker,并允许您快速构建 ML 应用程序。这为您节省了与模型开发相关的成本和时间。

  • 你如何为 ML 培训选择最划算的资源?

使用 SageMaker Training API 创建一个托管实例集群。在训练集群中使用多个实例可以实现分布式训练,从而缩短训练时间。训练完成时,训练群集中的所有实例都会自动终止。在处理大量训练数据时,Amazon SageMaker 管道模式比 Amazon SageMaker 文件模式提供了更好的读取吞吐量。

  • 如何优化 ML 推理的成本?

首先要考虑延迟、吞吐量和成本。同样,建议您从小规模开始,先横向扩展,然后纵向扩展。利用推理端点的自动缩放。当您的模型不需要实时预测时,请使用批量预测。

最后 ,这是对第一个 AWS ML 良好架构框架的全面总结。我试图用一种易读的格式来总结它,以适应从初学者到高级的所有 ML 专业水平。ML 可能有趣而复杂,但是,遵循这些 AWS 推荐的最佳实践将帮助您构建更好的模型,进一步了解 ML,并成为更好的 ML 专家。我希望你喜欢阅读这篇文章。

想用 python 轻松集成数据?

原文:https://towardsdatascience.com/want-to-easily-integrate-data-with-python-e9d808f88455?source=collection_archive---------51-----------------------

克里斯托夫·高尔在 Unsplash 上拍摄的照片

与 data.world 的 5 分钟数据集成

介绍

想象一下:你和几个同事正在用 python 开发一个数据科学项目。您没有费心将数据输入或输出与 SQL/python 数据库集成联系起来,因为没有那么多的数据转手。但是,还是有足够的。csv 文件被创建和更新,以至于很难通过电子邮件发送、备份或将其放在驱动器文件夹中。

在过去的几个月里,我个人多次遇到这种情况。我不想经历整个 SQL 集成过程,但是文件传输仍然很繁琐。

我最近发现有一种更简单的方法,没有平台集成经验的人可以在短短 5 分钟内完成设置。解决方法: data.world

data.world 是一个企业数据目录,拥有世界上最大的开放数据社区,个人使用免费。您可以将各种数据、代码和分析上传到数据集或项目中。

设置您的帐户

第一步是创建一个免费帐户。你可以在 data.world/login 使用谷歌、脸书、GitHub 或 Twitter 来做这件事。您将看到这样一个页面:

作者图片

点击“+新建”,然后点击“创建新数据集”。选择一个名称和一些其他设置,然后“创建数据集”。我把我的命名为“中等文章样本”。您可以现在添加描述和数据,也可以以后再添加。我添加了 Kaggle 的泰坦尼克号比赛的训练数据。

作者图片

接下来,转到data.world/integrations(或点击屏幕左下方的“整合”图标)。在过滤器搜索栏中键入“python ”,或者向下滚动直到看到它。点开它,点击“启用集成”,然后“授权 Python”

作者图片

现在集成已经完成,您可以点击“开始”并按照那里的步骤操作。我也将把它们包含在本文中。

安装软件包

1.使用命令行(或 jupyter 笔记本),从 PyPI 安装 data.world 包。

pip install datadotworld[pandas]

2.使用命令行配置包。你需要你的 data.world API 令牌,在这里找到(点击“获取令牌】)。现在您已经准备好使用这个包了!

dw configure

3.在笔记本或脚本中导入包。

import datadotworld as dw

使用软件包

使用 datadotworld 包可以做很多事情,但这里有一些我们正在寻找的基本数据集成的基础。

首先,您可以读取数据集中的所有文件,并获取特定文件作为数据帧(根据文件类型,您可能需要将其作为表或原始数据导入;更多关于那个这里。注意,表名都是小写的,用下划线代替空格。

dataset = dw.load_dataset('ryan-brown/medium-article-sample')
df = ds.dataframes['titanic_training_data']

如果您使用的是 Windows,编码可能会有问题;我创建了一个快速函数,利用了 datadotworld 的。查询函数从数据集中读取特定的表。

def dw_get(dataset_name, table_name):
    results = dw.query(dataset_name, "SELECT * FROM `{}`".format(table_name)) df = results.dataframe
    return dfdf = dw_get('ryan-brown/medium-article-sample', 'titanic_training_data')

无论哪种方式,您现在都可以在笔记本中创建一个数据框架,您可以对其进行清理、处理和分析。假设我决定用 NaN 值填充 drop“ticket”列和所有行来清理数据。我现在有以下数据框架:

作者图片

我准备更新数据集上的文件,供我的同事在项目分析中使用。这样做很容易——只需将数据帧作为. csv 文件保存在工作目录中,然后调用 datadotworld api 客户端并上传文件。

df.to_csv('titanic_data_clean.csv',index=False)
client = dw.api_client()client.upload_files('ryan-brown/medium-article-sample', files=['titanic_data_clean.csv'])

请注意,我决定给它一个不同于 titanic_training_data.csv 的名称,这样它将在数据集中显示为一个新文件。但是,如果我决定将其命名为 titanic_training_data.csv,它将替换数据集中旧的 titanic_training_data.csv 文件(同时仍然保留您可能添加的任何标签或描述)。

现在我们已经上传了新数据,让我们来看看数据。世界数据集:

作者图片

您可以看到清理后的数据在那里,在右边有一个更新,表明我使用 python 添加了数据。就这么简单。

要授予对等用户访问权限,以便您可以协作处理和上传数据,请单击数据集的“Contributors”选项卡,然后单击“Invite”通过电子邮件或用户名邀请他们。

作者图片

这只是 datadotworld 包可以做的许多事情的一小部分,这个站点可以作为一个整体使用;你可以在这里写的一篇很棒的文章中查看这个库的更多特性。

你的数据科学项目需要一个成功的条件。

原文:https://towardsdatascience.com/want-to-get-hired-build-a-project-with-a-win-condition-6526d90a247d?source=collection_archive---------57-----------------------

离开一个项目很难,但是你需要知道什么时候去做。

温斯顿·丘吉尔,大概是在完成他的第一个数据科学项目之后。来源:https://www.flickr.com/photos/levanrami/45544041992

sharpes minds数据科学导师项目工作最酷的事情之一是,我们有机会看到人们建立了什么项目,以及哪些项目让他们被雇用。

我们反复学到的最重要的一点是,最好的项目根本不是项目:它们是产品。

在这篇文章中,我想解释构建一个产品意味着什么,以及构建产品如何能帮助你在你的项目准备好发布之前弄清楚它必须有多好(并且给雇主留下深刻印象!).

什么是产品?

数据科学产品是一个有用例的项目。理想情况下,这是你自己会用到的东西。

它可以是推荐系统、仪表板或分类器。但是不管它最终是什么,它应该对某人有用——而且你对那个人是谁的想法越具体越好。

专注于有用性和构建产品使得为你的项目定义一个“赢”的条件成为可能:模型性能的水平(准确性、召回率、AUC 分数等)使得你的模型“对实际目的来说足够好”。

获胜条件是大多数数据科学项目中最常见的缺失因素。这真的很糟糕,因为它们是公司需要你能够弄清楚的最重要的事情之一。

作为一名数据科学家,你不会下载数据集,清理它们,并根据某个经理从高层给你的损失函数调整模型。通常情况下,你必须想出这个损失函数,并计算出在你有一个可以出货的产品之前,它必须有多好。

因此,公司——尤其是招聘经理——会在面试中花费大量时间寻找你能够找出成功条件的暗示。如果你的项目不包括一个,你基本上就失去了勾选这个框的最好机会。

以下是如何选择一个。

设置您的获胜条件

您的获胜条件将有两个组成部分:您想要优化的指标,以及一个阈值,超过该阈值,您认为该指标将被优化。

但是只有当你对你的项目有一个清晰的用例时,你才能弄清楚这些事情。

例如,假设您正在构建一个时尚推荐系统,以帮助人们找到匹配的衬衫和裤子。如果您的绩效指标高出 1%,这有什么关系吗?用户能够区分 0.99 AUC 和 0.98 AUC 吗?

大概不会。所以不要让你的获胜条件 0.99 AUC。你花在模型上的时间可以更好地用来做其他事情,比如收集更多的数据,改善你的可视化,或者解决一个完全不同的问题。

但是假设你正在建立一个癌症诊断工具。那 1%可以拯救生命。因此,每个百分点的性能都非常有价值,绝对值得投入大量资金来调整您的模型。

成功的条件并不总是简单的指标。如果你的项目是为网上购物者建立一个时尚推荐系统,那么成品不是一个算法——而是一个应用程序。如果您的项目是构建一个仪表板,使其易于发现某些趋势,那么您的成功条件就是该仪表板的部署。

下面的是一个如何做到这一点的很好的例子,直接来自一个敏锐的学员的项目:这是一个应用程序,让两个对音乐有不同品味的朋友通过考虑他们的偏好来妥协他们想听什么。因为这是一个有趣的、面向消费者的应用程序,应用程序的界面和结构与模型一样重要,所以更平衡的时间投资(和获胜条件)更有意义。此外,对音乐的品味是非常主观的,用户不太可能注意到哪怕是模型损失值的 5%的改善。

向招聘经理解释这些权衡是一种很好的方式,可以表明你的重点在哪里:不是像 Kaggle 一样的柔术模式,而是为真实的人和真实的用例提供真正的价值。

作为一个临别的提示:定义你的成功条件的时间是在你开始你的项目之前,以避免陷入永无止境的优化和调整的漩涡的风险,这将导致你浪费时间去做那些没有真正价值的事情。

没有一个明确的成功条件就着手一个项目是浪费你的时间和公司的钱去解决不需要解决的问题。大多数公司担心这种风险是可以理解的,作为求职者脱颖而出的最佳方式之一是通过展示你可以将业务问题与数据科学问题联系起来,正面解决这一问题。

这一切都始于成功的条件。

你可以在推特上关注我,地址是 @ jeremiecharris

想入门函数式编程?输入 Scala。

原文:https://towardsdatascience.com/want-to-get-started-in-functional-programming-enter-scala-ea71e5cfe5f8?source=collection_archive---------16-----------------------

意见

如果你厌倦了 Java 或 Python,这可能会让你的职业生涯更上一层楼

Scala 可能是成为函数式程序员的下一步。妮可·沃尔夫在 Unsplash 上的照片

If 如果 你还没有使用 Scala,你不是唯一一个:根据 StackOverflow 的数据,截至去年,不到 4%的程序员在使用这种语言。这使它在最常用的语言中排名第 22,JavaScript 和 HTML 是前两名。

然而,使用 Scala 的程序员似乎从中受益。它不仅在 StackOverflow 最受欢迎的语言中排名第 14 位。这明显高于使用排名 22。

从经济上来说,了解这门语言似乎是有回报的:在全球范围内,只有 Perl 程序员的薪水高于 Scala 程序员,两者的年薪都在 7.6 万美元左右。在美国,Scala 的薪资最高,程序员的年薪预计约为 15 万美元。我觉得没问题!

为什么一些编程语言比其他语言更受欢迎或更有利可图,有不同的原因。在 Scala 的例子中,主要原因是它让程序员很容易学习函数式编程,而不像面向对象编程那样放弃已知和喜爱的范例

函数式编程在过去几年里越来越受欢迎,因为它非常适合处理大数据量、实现机器学习算法等等。由于此类技术的可扩展性非常好,对它们的投资已经为无数行业的公司带来了收入。这就是为什么 Scala 程序员的高薪是合理的。

[## 如何让您的 Python 代码更具功能性

以及为什么这会使您的代码更加健壮、可测试和可维护

towardsdatascience.com](/how-to-make-your-python-code-more-functional-b82dad274707)

统一面向对象和函数式编程

Scala 当然不是市场上唯一的多范例语言。例如,Python 支持面向对象和函数式编程。在 Java 中,函数式编程原则上是可能的,尽管它最初是作为面向对象的编程语言而设计的。

然而,Scala 的特别之处在于它寻求无缝集成面向对象和函数式编程。通常,这两种范式表现为彼此的对立面:在函数式代码中,你只会发现纯函数。在面向对象的代码中,你也会遇到不纯的函数。

在函数式代码中,所有变量都是不可变的,也就是说,它们的值一旦固定就不会再改变。在面向对象的代码中,您可以随时更改变量值。在功能代码中,你不会发现任何副作用;在面向对象的代码中,您可能会不时遇到它们。

这并不意味着没有很多方法可以在主要面向对象的代码中包含更多的函数式编程。在许多语言中,您可以在常规代码中使用从函数式编程中窃取的基本概念。例如,在 Python 中,构建迭代器、生成器和匿名函数相当容易。

但是 Scala 反过来也是这样做的:它使得开发人员可以非常容易地编写主要是函数性的代码,然后可以用面向对象的代码来修补函数性的代码过于繁琐的地方。这是对纯函数式编程的一个很好的妥协,例如,像用户定义的 I/O 这样的东西是不容易实现的。

Scala 入门并不像听起来那么难。照片由普里西拉·杜·普里兹Unsplash 上拍摄

Scala 中的快速入门

像许多其他语言一样,有两种方式使用 Scala:使用 IDE 或者命令行。就我个人而言,我是一个命令行爱好者,但最终还是要看个人喜好。

然而,在这两种情况下,你都必须下载并安装 Scala。但是,有时您只想先涉猎一下,而不安装任何东西,或者按照我将在下面几节中介绍的内容进行操作——我鼓励您这样做。好消息是,你可以使用 ScastieScalaFiddle 在浏览器中编写和运行你的代码。

这两个网站都适合像下面这样的小项目,在那里你不会加载很多库。如果你需要加载很重的东西,那么 ScalaFiddle 可能是更好的选择,因为它处理库的效率很高。

不言而喻,至少目前,浏览器代码项目不应该太大。如果你已经喜欢上了 Scala,并且想要构建更大的东西,那么在你的机器上安装 Scala 将是更好的选择。

也就是说,如果你现在没有时间跟进,这完全没问题。到这个故事结束时,你仍然能够理解发生了什么,并对如何用 Scala 编码有一个基本的了解。

[## 函数式编程太棒了

为什么函数式编程正在兴起

towardsdatascience.com](/functional-programming-is-awesome-c94bcd150ae6)

Scala 的“你好,世界!”

转到 ScastieScalaFiddle ,键入:

println("Hello, world!")

然后按“运行”。你会发现就这么简单。

好吧,如果你想在本地机器上运行一个真正的脚本,你需要一些样板代码。但是我们一会儿就会讲到。首先,我们需要了解一些基础知识。

值和变量

您可以使用val前缀来分配不可变变量——在 Scala 中它们被称为值:

val Greeting = "Hello, World!"
println(Greeting)

因为值是不可变的,所以你不能给它们重新赋值。如果你试图这么做,编译器会抛出一个错误。你猜对了:这就是函数式编程!

不过,如果你需要重新分配任务,还有一个选择:使用前缀var,然后就到此为止。

Scala 既是面向对象的,也是函数式的。照片由7 档上的拍摄

功能和方法

在 Scala 中,函数的构造非常容易:

val GreetMe = (name: String) => println("Hi, " + name + "!")
GreetMe("Rhea")

这将按预期返回Hi, Rhea!。在=之前的部分定义了函数的名字,然后是它的参数,在=>之后你会发现函数体。

您可以通过省略名称定义来定义匿名函数,这非常符合函数式编程的风格。根本不是函数式的是你可以定义没有参数的函数——在函数式编程中,你总是需要一个参数。

还有一些方法,与函数非常相似:

def GreetMe2(name: String): Unit = {
    val greeting = "Hi, " + name + "!"
    println("Hi, " + name + "!")
}
GreetMe2("Rhea")

它们非常类似于函数,但是它们的语法有点不同。需要指定一个输出类型,就像本例中花括号前面的Unit

在更理论的层面上,函数是方法的推广。这是因为方法总是类的一部分。函数可以是类的一部分,但不是必须的;如果它们碰巧是一个方法的一部分,它们就被称为方法。

类别和对象

类的定义如下(这个我直接从 Scala 的之旅复制过来的):

class Greeter(prefix: String, suffix: String) {
    def greet(name: String): Unit = 
        println(prefix + name + suffix) 
}

然后我可以用下面的方法定义这个类的一个实例:

val GreetMe3 = new Greeter("Hello, ", "!") 
GreetMe.greet("Rhea")

在类中调用方法greet的方式与在 Python 或其他语言中的方式相同。

Scala 中的对象是它们自己定义的实例:

object HowManyGreets {
    private var counter = 0
    def greet(): Int = {
        counter += 1
        counter
    }
}

与类不同,它们不能带任何参数。但是,当你调用它们的方法时,它们会返回一些东西:

val onegreet: Int = HowManyGreets.greet()
println(onegreet)    *// outputs 1*
val twogreets: Int = HowManyGreets.greet()
println(twogreets)    *// outputs 2*

[## 从面向对象编程转换到函数式编程

为什么函数式编程这么难?

medium.com](https://medium.com/@olxc/switching-from-oop-to-functional-programming-4187698d4d3)

把所有的放在一起

有一个特殊的对象,main 方法,它是每个 Scala 程序的入口点。这类似于 Python、Java 或 C 和 C++,在这里你也会遇到 main 方法。

所以我们来写一个可以问候我的 main 方法:

object Main {
  def main(name: String): Unit =
    println("Hello, "+ name + "!")
}
val greettheworld: Unit = Main.main("World")    *// Hello, World!*

完美!如果您在命令行或 IDE 上工作,您可以将这段代码保存为Hello.scala。然后像这样编译并执行它($表示这发生在您的 shell 中):

$ scalac Hello.scala
$ scala Hello

恭喜你!你不仅理解了如何用 Scala 编写你的第一个小程序。您还了解了一些关于构成该程序的概念的背景知识。

Scala 非常适合函数式编程。由 DISRUPTIVOUnsplash 上拍摄的照片

Scala 中的函数化:高阶函数和嵌套方法

我们已经在 Scala 中遇到了一些函数式编程的基本概念,例如,不可变变量和匿名函数。函数式编程中经常出现的其他现象是接受或返回其他函数的函数,以及在彼此内部定义的方法。

这些事情在面向对象编程中也是可能的。但是在函数式编程中,它们是自然出现的,而且经常发生。在面向对象编程中,这些现象有些少见。

高阶函数

说你在一遍又一遍的做类似的操作。通常更容易的是定义一个函数来做这些操作共有的所有事情,以及在每个操作中做不同事情的子函数。

例如,假设我们试图在一个列表上执行不同的操作。也许我们想给每个元素加 2,或者我们想把每个元素平方。您可以编写一个函数calcAnything,它可以对一个函数执行任何计算。然后,编写不同的函数来将 2 相加或对元素求平方:

object CalcSomething {private def calcAnything(numberslist: List[Double], calcFunction:     Double => Double): List[Double] =
    numberslist.map(calcFunction)def add2(numberslist: List[Double]): List[Double] =
    calcAnything(numberslist, number => number + 2)def square(numberslist: List[Double]): List[Double] =
    calcAnything(numberslist, number => number * number)}

calcAnything中的map函数负责列表上的操作。我们可以像以前一样调用这些函数:

val newList = List(1.2, 4.5, 3.6)val squared: List[Double] = CalcSomething.square(newList)
println(squared)    *// output: List(1.44, 20.25, 12.96)*val plustwo: List[Double] = CalcSomething.add2(newList)
println(plustwo)    *// output: List(3.2, 6.5, 5.6)*

注意,当plustwo被执行时,操作按照开始时的定义在列表上执行。这是函数式编程的直接结果:像val这样的变量是不可变的。如果您想顺序应用这些操作,您需要使用squared作为add2的参数。

同样,我们可以定义返回其他函数的函数。如果你有兴趣深入了解,Scala 文档中有一个很好的例子。为了简洁起见,我在这里不再进一步阐述。

嵌套方法

像许多其他语言一样,您可以在彼此内部定义函数。一个简单的例子是计算特定数字之前所有整数的和:

def bigSum(x: Int): Int = {
    def sum(x: Int, summator: Int): Int = {
        if (x < 1) summator
        else sum(x - 1, x + summator)
    }  
    sum(x, 0)
}println("Sum of 0 to 8: " + bigSum(8))    *// outputs 36*
println("Sum of 0 to 100: " + bigSum(100))     *// outputs 5050*
println("Sum of 0 to 0: " + bigSum(0))    *// outputs 0*

你可以用高斯和公式来验证这一点:任意整数序列的和达到一个整数 n 就是 S = n⋆(n-1)/2

[## 为什么开发人员会爱上函数式编程

从 Python 到 Haskell,这种趋势不会很快消失

towardsdatascience.com](/why-developers-are-falling-in-love-with-functional-programming-13514df4048e)

在 Scala 中实现面向对象:类、副作用等等

如果你知道 Java、Python、C++或者其他主要的编程语言,你不可能没有听说过面向对象编程。我相信在整篇文章中,你已经认识到了一些概念!

从带有前缀object的 main 方法开始,一直到类和类中的方法,面向对象编程的基本要素都出现在 Scala 中。副作用,即没有明确声明的函数的参数,也很容易实现:例如,可以定义一个没有任何参数的函数——但是从技术上讲,每个函数都需要某种类型的参数,即使它只是self

如果你是一个专门的函数式程序员,你唯一不能回避的面向对象的东西就是 main 方法。但是如果你的舒适区在面向对象的领域,你也会被覆盖。

是什么让 Scala 从其他语言中脱颖而出

当今大多数流行的编程语言都是从面向对象开始的,现在随着需求的增长,集成了越来越多的函数式编程的特性。想一想 PythonJavaPerl 的更多上下文。另一方面,Scala 从第一天起就准备集成两者。

它不是唯一一种以混合编程范式开始的语言。例如,围棋也使用了许多不同的方法。Go 的构成和简单性使得它对于微服务、系统架构和此类问题令人惊叹。

在光谱的另一端是 Rust :作为一门语言,它比 Scala 更难学,比 Go 更难学。像 Scala 和 Go 一样,它混合了范例,但也有一些自己独特的特性。了解所有这些意味着你可以轻松地花两周时间来提高效率。

Rust 用于许多与 Scala 相同的问题,如大数据处理、机器学习、并行编程等。但是,如果你想快速提高工作效率,并且不被沉重的术语淹没(或者你听说过幺半群、arity 或 foldables 吗?),Scala 可能是更好的选择。

如果你不怕数学术语和其他怪癖,那么 Rust 也值得一试。如果你打算长期从事函数式编程,这一点尤其适用。然而,对于函数式编程的初学者,我推荐 Scala。

与他人一起学习新的语言尤其令人鼓舞。由布鲁克·卡吉尔Unsplash 拍摄的照片

从哪里了解更多信息

如果这篇文章促使你下载 Scala 并亲自尝试,那么 Scala 的入门页面是你需要去的地方。

Scala 附带了非常优秀的文档。该网站还为你提供了一些不错的在线资源,值得一试。

如果你是一个动手学习者(我知道我是),那么这两个 教程值得一试。要获得更加结构化的方法和大量简洁的示例,请查看 Scala 的之旅。为了更深入的了解,请查看 Scala 书籍。

底线:Scala 对你的职业生涯来说不仅仅是有利可图

如果你在 Scala 中升级游戏,这可能会导致薪水的大幅提升。但这只是事情的一面。

Scala 为您提供了足够多的面向对象编程,让您感觉似曾相识。同时,这也是按照自己的进度了解函数式编程的一个很好的方式。

函数式编程对于大数据、机器学习等任何事情都是极好的。这些领域的需求不会很快停止。

还不确定 Scala 是否是主导函数式编程的语言。我更愿意将 Scala 视为学习一个极其重要的编程范式的基础。

无论您坚持使用 Scala,回到 Python 或 Java 并在代码中添加更多的函数片段,还是转向 Rust 等更复杂的语言,这完全取决于您。即使你不坚持使用 Scala,它也可能是你掌握函数式编程的敲门砖。

想掌握自己的数据?这就是你应该关心元数据的原因

原文:https://towardsdatascience.com/want-to-master-your-data-heres-why-you-should-care-about-metadata-8fcd7754c3b8?source=collection_archive---------33-----------------------

比了解自己更了解自己的数据

马太·亨利Unsplash 上拍照

E 不管你是数据科学家、数据工程师还是对数据感兴趣的人,了解你的数据是你不想忽视的一件事。我们通常把数据看成是数字、文本或者图像,但数据不仅仅是这些。

我们应该将数据视为一个独立的实体。数据可以做自我介绍,讲故事,可视化趋势。为了达到这些结果,您必须首先了解您的数据。不仅仅是它是如何形成的或它的起源,而是它将如何随着时间的推移而改变,以及它的可用性。其中一些信息就是我们所说的元数据。

为什么元数据如此重要?为什么我们必须在掌握数据之前掌握元数据?今天,我将向您展示我们如何在数据业务中利用元数据。

元数据到底是什么?

根据维基百科,元数据是“提供其他数据信息的数据”。是“关于数据的数据”。这听起来很简单,不是吗?所有数据都包含特定事物的信息。对于元数据,那个特定的东西是另一个数据。

然而,元数据本身的定义也各不相同。它可以是数据集的名称、创建信息或数据点的统计分布。它可以是与数据属性相关的任何内容。也就是说,所有数据都必须拥有元数据。但这并不总是详尽的情况。

没有元数据的数据总是不完整的。

元数据的类型。归功于作者。

我们使用数据是希望提取有用的见解,以及数据理解的目的。元数据有助于我们维护数据的完整性,验证事实的来源,或者保持稳定的数据质量。

电子邮件元数据的一个例子。归功于作者。

然而,在某些情况下,数据用户忽略了元数据的作用。他们认为它只是标签,它带来的价值是有限的。接下来我们将看到元数据如何与数据的另一个重要方面相关联:数据质量

数据质量

再次,维基百科说:“数据质量是指定性或定量信息片段的状态”一般来说,当“无论数据用户是谁,数据都符合预期的用例”时,就被认为是高质量的。

数据是有价值的信息来源,但是没有人愿意使用一堆垃圾。你越想从数据中提取信息,数据质量就越重要。在大数据的世界里,这也成为一个瓶颈。

马库斯·温克勒在 Unsplash 上拍摄的照片

随着数据越来越大,元数据也越来越多。我们不习惯处理大量的元数据。既然它需要一种特殊的处理,我们必须考虑它同时是数据而不是数据。元数据不是独立的信息,而是数据的附件。我们有可能将其扩展为对数据质量的评估。

数据是有价值的信息来源,但是没有人愿意使用一堆垃圾

在培养大数据管道的高数据质量的共同努力中,科技公司对这个新课题给予了很多关注。从检测异常到自动警报系统,我们希望尽可能少地限制错误数据的影响。没有数据理解,或者准确地说,没有元数据,我们无法做到这一点。

[## 利用统计建模大规模监控数据质量

糟糕的数据无法做出好的商业决策。在优步,我们使用汇总和匿名数据来指导…

eng.uber.com](https://eng.uber.com/monitoring-data-quality-at-scale/)

数据质量反映在许多方面,但最常见的是数值的正确性。想象你绘制了一个学期内大学生成绩的直方图。直方图是这些值的统计表示,它描述了您的数据。它变成了元数据。您可能要解释的是分数的分布,然后您可以得出结论,它是否适合您的用例。

使用直方图了解您的数据

事先要问很多关于数据值的问题。这些值随着时间的推移是稳定的吗?有没有异常值?如果是,我们应该如何处理这些异常值?通过回答这些问题,我们获得了一些见解,不是信息方面的,而是数据方面的。我们可以创造元数据,有用的元数据。这只是通过元数据断言数据质量的原始步骤。我们将在下一节详细讨论如何利用我们可以生成的元数据。

如何利用元数据

有些人可能会被我们从数据集中提取的各种统计数据所淹没。其他人可能会忽略这些额外的信息,认为它们是无用的。诚然,我们不需要每次处理数据时都绘制直方图,但这很有帮助。为了利用有洞察力的元数据,数据用户必须首先回答三个重要问题:

  • 什么: 你想验证你的数据质量吗?有些数据需要严格的稳定性,而有些数据需要注意是否正确。对于每一种数据,我们将提取的信息作为元数据。统计分布、长期趋势、差异等。这就是我们所说的元数据策略。在处理数据和元数据时,我们的存储和人力资源有限。所以,一定要慎重考虑重点放在哪里。
  • 如何: 我们如何衡量数据质量?这些操作遵循元数据策略。我们可以选择测量整个数据库,或者一些表,或者一组特定的列。值的总数、字符串的最大/最小长度、缺失数据的比例。我们决定衡量什么取决于我们如何使用这些数据来产生结果。
  • 何时: 数据随时间变化。当我们通过元数据提取洞察力时,我们正在跟踪这些转变。我们什么时候跟踪元数据?每天?每小时吗?每个季度?这取决于多少粒度足以解决数据质量问题。我们根据数据变化的速度来调整我们的衡量标准。例如,每一分钟或每一秒钟都需要跟踪股票市场数据。天气数据每小时都在变化,而航空数据可能需要几个月或几年的时间才能改变。

股票市场数据需要每分钟都被跟踪。马库斯·斯皮斯克在 Unsplash 上的照片

元数据有着悠久的历史,但我们最近才发现它对数据管理的贡献,尤其是对数据质量的贡献。元数据本身不能改变数据的结果,但它在我们的原始数据和它的使用之间增加了一个安全和管理层。您甚至可能在不知不觉中使用元数据来发现您的数据。

当数据很小时,数据质量可能无关紧要,但是当处理大量数据时,数据质量就变得至关重要。元数据帮助我们跟踪这种增长,并确保数据按照应有的方式发展。由于未能利用元数据,我们无法理解您的数据。

元数据该怎么处理?

如果您希望掌握您的数据,您应该开始系统地处理元数据。基于我们上面看到的框架,你为自己选择一个合适的数据策略。还没有什么新奇的东西。它始于您希望如何使用您的数据,以及您如何控制其使用质量。 一切始于目标。

ETL 过程中有一个阶段叫做 探索性数据分析 。我觉得更多地了解你们数据的统计方面很有意思。它似乎接近我们希望通过元数据了解的内容。

我总是看到我的数据科学家和/或数据分析师朋友在对他们的原始数据做任何事情之前先从 EDA 开始。所以我认为这肯定是一个重要的步骤,我想知道它是如何与我的元数据框架相联系的。他们有很多共同之处。

首先是目的。EDA 中的“探索性”部分与元数据的发现目标不谋而合。其次是他们如何看待数据的统计方面,以评估其未来的用途。综上所述,EDA 实际上是一个必不可少的步骤,因为它类似于基于元数据的数据质量评估。

您已经有了数据策略和数据评估,现在是您决定如何处理所有这些信息的时候了。在数据质量控制人员看来,数据将如何被使用决定了它是否正当和可信。

***Key takeaways:*** - Build your data strategy based on data usability
- Apply an EDA - Exploratory Data Analysis to evaluate the data
- Decide on whether you have a solid confidence on your data

结论

我已经分享了我对元数据的一些观点。对我来说,它和数据本身一样有价值。那些利用这些价值的人是理解他们的数据的人。误用我们不理解的东西更容易。元数据为我们提供了更清晰的数据视图,此外还有数据质量、完整性和可用性。

我的名字叫 Nam Nguyen,我写的主要是关于大数据的文章。享受你的阅读?请在 Medium 和 Twitter 上关注我,了解更多更新。

我的数据科学硕士学位值得吗?

原文:https://towardsdatascience.com/was-my-data-science-masters-degree-worth-it-6b524dd35b33?source=collection_archive---------12-----------------------

一连串的课程,现实生活中的收获,以及这一切是否最终值得

罗尼·库尔茨在 Unsplash 上拍摄的照片。

目录

  1. 介绍
  2. 数据科学
  3. 课程
  4. 职业
  5. 摘要
  6. 参考

介绍

我去了南方卫理公会大学(SMU)攻读我的数据科学硕士学位【2】。这个决定是在做了几年分析化学家后做出的。虽然我本科主修生物学,辅修化学和汉语,但我一直专注于研究科学和实验设计。当我发现自己不满足于做一名化学家时,我开始寻找其他的职业,以及如何才能达到相应的职业。我研究了数据分析、软件工程和数据科学。在我目前的工作岗位上,我已经从这三个可能的职业中演绎了相似的概念,但我甚至连一次面试的机会都没有。为了解决我的问题,我不得不最终寻找正规教育。下面,我将讨论数据科学对我来说意味着什么,我在大学里学的课程,以及这些经历是否适用于今天并最终值得。

数据科学

我已经编写了几篇关于数据科学的文章,以及该领域、机器学习和数据分析之间的差异和相似之处,以及对在线学习的影响。除了我将在本文末尾列出的具体文章之外,请随意查看我的个人资料。

根据我的经验,数据科学可以最好地概括为一个领域,在这个领域中,通过使用来自工具和语言的库和包,传统的统计和数学实现了自动化,例如:

Python, R, sklearn (scikit-learn), TensorFlow, Keras, and pandas. 

虽然该领域不断变化,但解决问题、编程、统计和业务理解等共同主题处于数据科学核心的最前沿。对我来说,可能有几个地方我可以获得所有这些技能。我申请了数据科学学位,因为我没有接受过正式的 it 本科教育,我想提升自己,并在竞争激烈的就业市场中具有竞争力。

课程

Max Duzij 在Unsplash【3】上的照片。

虽然我会列出 SMU 大学的具体课程,但大多数课程在类似的大学和项目中会有重叠。在我的项目中,不仅有各种各样的课程,还有两个主要的专业:机器学习和商业分析。第一部分侧重于数据科学的编码方面以及所使用的公共库,而第二部分强调项目设计的重要性,以及它将如何为您未来的数据公司带来商业价值。如果你想在同一所或不同的大学找到类似的课程,我还会强调哪些课程是我认为对现实生活最有益和最有用的。

我将首先谈论核心课程,然后将包括选修课。

核心班级:

  • 数据科学的统计基础

这是您首先学习的课程之一,因为为了学习数据科学的有趣和有趣的算法,您需要在初级数据科学和统计学方面有坚实的基础。本课程的关键要点是统计抽样、方差分析(ANOVA)、回归和结果交流,主要工具是 SAS 和 r。

我很惊讶这门课有多棒,我强烈建议在学习任何数据科学之前先学习统计学。例如,当面试官问你如何开发方差分析时,你会认为你只需要专注于编写深度学习算法,这也会让你在面试中变得更受欢迎。

  • 做数据科学

另一门课是在我的课程开始时上的,这门课强调了探索性数据分析(EDA)在任何数据科学项目的第一部分是多么重要。要真正开始使用像随机森林或 K-means 这样的算法,你需要有一个你理解的可用数据集,EDA 可以帮助你有一个强大的数据集,你可以在其上运行模型。

  • 应用统计学:推理与建模

这门课重在统计,也许是学生最纠结的地方。这里的目标不是编程,而是回归、时间序列和商业应用案例。我在这里学到的一件有趣的事情是使用自回归移动平均模型(ARIMA)预测股票市场。

  • 文件组织&数据库管理

虽然之前的课程以统计为目标,同时使用 SAS 和 R 等工具和语言,但本课程涵盖了 SQL、Python 和 GitHub。

设置您的数据科学项目不是从数据集开始,而是从使用 SQL 查询开发数据集开始。

  • 机器学习 I

也许是最有趣的核心课程,这门课程讲述了所有常见的机器学习算法,如支持向量机(SVM)、多项式朴素贝叶斯和逻辑回归。

  • 信息可视化

学会如何将你的复杂结果传达给利益相关者是很重要的,所以学会如何可视化可以在很大程度上帮助解决这个问题。大多数工作你可以使用 Tableau、Google Data Studio 等工具,甚至可以用 Python 编写自己的程序,使用 matplotlib 等流行的库,用 Java 编写代码。

  • 量化世界

本课程总结了您所学的所有基础知识,并总结了如何处理数据、清理数据、执行 EDA 以及对数据集建模。这也是你开始你的顶点项目的地方,在其他大学也可能被称为你的论文。

选修课:

我不会去特别在这些,但他们提到了 SMU 的网站。我认为这里最重要的课程是自然语言处理(NLP)。根据我的经验,一些数据科学家会避开它,但是在你的工作中,你很可能会遇到文本数据,并且必须处理大量的文本数据。这实际上是我最喜欢的数据科学方面,可以帮助分析文档、分类文本和返回情感。以下是我参加的课程中包含的选修课:

  • 云计算
  • 机器学习 2
  • 统计抽样
  • 自然语言处理
  • 商业分析
  • R 时间序列分析
  • 数据和网络

职业

照片由克里斯蒂娜@ wocintechchat.comUnsplash【4】上拍摄。

为了回答这个问题,我的数据科学硕士学位值得吗?是的。

这个项目的第一个好处是我可以在工作的时候在线完成。教育可能相当昂贵,所以我非常高兴知道我仍然在学习的同时赚钱。我确实为每堂课做了现场视频交流,并参加了现场活动,这使我在职业生涯中获得了这个学位的下一个好处。参加这个项目的会议,除了和来自知名公司的同学一起工作,我很快建立了我的数据科学家网络。其中一次会议实际上是我们不得不介绍的课程— 顶点。在那里,我和另外两个同学介绍了我们关于如何对假新闻进行分类的话题,这都是因为我的学位和各自的研究。

在我的简历上有这么大的一个项目和出版物是非常有价值的,我可以向其他数据科学家和我采访的人进行交流和描述。因为我在高教育水平下获得了一个纯粹专注于数据科学的学位,所以我能够在 Indeed,HomeAway (Vrbo)以及现在我工作的地方找到工作,这是一家位于德克萨斯州奥斯汀的成功创业公司,名为 ScaleFactor 。如果没有成功完成这个项目,我不知道我会在哪里。它让我成为一名受过教育的专业数据科学家。

摘要

虽然由于各种原因,这条道路可能不是每个人的最佳选择,但我相信对我来说,这是我成为数据科学家的原因。一路上,我学到了很多,建立了令人敬畏的关系,甚至交了更好的朋友。所以是的,这是值得的。我希望这篇文章对你有用,感谢你的阅读!请从我这里找到这些文章,它们包括数据科学、数据分析、机器学习的差异和相似之处,以及下面分别在线学习数据科学的影响和结果[5]、[6]和[7]。

[## 数据科学与数据分析。区别就在这里。

数据科学家和数据分析师的主要区别和相同点是什么?阅读下面的概述…

towardsdatascience.com](/data-science-vs-data-analysis-heres-the-difference-4d3da0a90f4) [## 数据科学 vs 机器学习。区别就在这里。

数据科学家和机器学习工程师的主要区别和相同点是什么?阅读以下内容,了解…

towardsdatascience.com](/data-science-vs-machine-learning-heres-the-difference-530883d6de3a) [## 是的,你可以在网上成为一名数据科学家。以下是方法。

在线学习的专业数据科学家指导您在家开始数据科学生涯

towardsdatascience.com](/yes-you-can-become-a-data-scientist-online-heres-how-dc73c7faae0f)

参考

[1]照片由罗尼·库尔兹Unsplash(2019)拍摄

[2]南方卫理公会大学,在线数据科学硕士,(2020)

[3]Max Duzij 在 Unsplash 上拍摄的照片,(2019)

[4]照片由克里斯蒂娜@ wocintechchat.comUnsplash(2019)上拍摄

[5] M.Przybyla,数据科学家 vs 数据分析师。区别就在这里。(2020 年)

[6] M.Przybyla,数据科学 vs 机器学习。区别就在这里。(2020 年)

[7] M.Przybyla,是的,你可以在网上成为一名数据科学家。以下是方法。(2020 年)

"那是唧唧声吗?"在 PyTorch 上制作鸟类音频检测网络

原文:https://towardsdatascience.com/was-that-a-chirp-making-a-bird-audio-detection-convnet-on-pytorch-88400450bb19?source=collection_archive---------32-----------------------

为什么鸟类声音探测对我们环境的未来如此重要

简·梅乌斯在 Unsplash 上拍摄的照片。由我编辑:)

介绍

你听说过自动语音识别,你听说过音乐标记和生成,但你听说过鸟类音频检测吗?

大约一年前,在我高二的时候,我第一次听说这种音频深度学习的用例。事实上,鸟音频检测(讽刺的缩写为 BAD,但我会尽量避免这个缩写😅)是我在深度学习和计算机科学方面做的第一批项目之一的主题。我参与了一个研究项目,在北阿拉斯加郊区使用纯音频探测鸟类的存在。跃入其中,鸟音探测作为这样一个小众却又引人入胜的应用出现了!在本文中,我将向您展示如何在 BirdVox-70k 数据集上使用简单的卷积神经网络(CNN)来实现这一点。

好吧,但是为什么鸟类音频检测很重要呢?

多年来,深度学习模型在鸟类音频检测应用中的使用一直在不断发展进步,有些人对此非常感兴趣是有原因的。首先,鸟类的移动速度很快,体型相对较小,已经很难追踪了。此外,不同种类的鸟类有自己独特的发声方式,这使得通过听觉和听觉来探测鸟类比亲眼目睹更为可取。最后,由于鸟类是生态系统的一部分,它们的存在和迁徙模式通常是任何特定地区环境健康的警示信号。

那么,为什么不录下一段音频片段,然后发送给人类,让他们稍后再听呢?然而,让我们现实一点:

手动标记音频既昂贵又繁琐,而且可能无法接近实时。

所以,这就是深度学习和 CNN 发挥作用的地方。如果我们的模型足够精确,我们可以通过在荒野周围设置麦克风来自动记录鸟类迁徙模式和跟踪鸟类物种。有了这些数据,我们可以更深入地了解我们世界的生态系统,并充分了解气候变化对我们环境的影响。

等等,上面那张图中那些很酷的情节是什么?

先说说声音的一切。声音基本上是由通过空气进入我们耳膜的奇特压力波组成的,可以用数字设备记录为信号。事实证明,我们可以将这个信号绘制如下:

音频信号/波形的示例图,没什么特别的。或者也许…

然而,这个长线图看起来并不特别吸引人,可以馈入任何深度学习模型,更不用说 CNN 了。事实上,如果我现在告诉你,上面的音频信号代表的是一只鸟的鸣叫,你会相信吗?很可能不是…你反而认为这是我随机创作的情节。 如果你认为鸟鸣声在第 10000 次滴答附近,如果我说鸟鸣声正好在中间,在第 6000 次滴答时呢? 重点是:

如果我们自己都不能对任何特定的信号图代表什么做出任何强有力的假设,我们怎么能指望深度学习模型做到这一点呢?

…我们并没有完全陷入困境。实际上还有另一种方式来表示音频:频谱图。频谱图是通过在一个小的时间窗口中记录频率的存在和各自的强度,沿着 x 轴(由时间单位表示)堆叠,直到频谱图覆盖音频信号的总持续时间而制成的。当时间窗在谱图创建过程中移动时,时间窗自身重叠是常见的,并且通常频率强度(音量或响度)用颜色表示,或者用数字表示,较高/较低值。

从上面显示的完全相同的波形伪造的声谱图。x 轴、y 轴和绘图颜色分别代表时间单位、频率(单位为赫兹)和频率强度。现在,你能清楚地分辨出这只鸟是不是在叫,什么时候叫吗?

给定来自上方的信号的频谱图,如果和当鸟鸣叫时,它应该更清楚。具体来说“只是因为”,你可以在 250 ms 标记处看到 6000 Hz 左右的独特活动;那是鸟鸣声。因此, CNN 音频分类器通常将频谱图作为输入,鸟类音频检测模型也不例外。

准备

数据集

为此,我使用了来自 BirdVox 的 BirdVox-70k 数据集,它包含半秒(500 毫秒)的记录/波形,包含或不包含鸟啁啾声。该数据集来自其更大的兄弟,BirdVox-full-night,两者都是在 2015 年秋季在美国纽约伊萨卡记录的。每个波形的标签作为最后一位数字包含在每个文件名中(或者是0或者是1)。尽管 70k 数据集拥有大约 70,000 个数据片段(因此得名),但我将只使用其中的三分之二(更确切地说,大约 50,000 个),因为我的 Paperspace 帐户中的持久存储空间越来越少😦。

数据被捆绑在单独的 HDF5 文件中,这意味着我计划使用的已经减少的 50,000 个样本实际上被分成 4 个不同的. hdf5 文件。为了增加融合,每个波形被存储到一个有自己的“文件名”标签的组中,所有这些被存储到另一个称为“波形”的组中。即使在阅读了 h5py 文档之后,我还没有看到如上所述的这种安排。这些发现已经让我做了两个最糟糕的数据准备噩梦。几乎没有存储空间了,我无法改变已经给我的数据格式。这给我留下了最后一个选择:创建一个非常定制的 PyTorch 数据集类,这样我就可以继续了。

但在我继续之前,让我们听一些简短的音频样本,以及对数据集的一些简单数据分析(警告—降低音量,因为样本可能比预期的更响):

一些鸟积极的音频片段供您欣赏

一些鸟负面的音频片段供您欣赏

事实证明,在将所有文件组合在一起后,bird 阳性音频样本的比例正好是 50%,正如他们在网站中承诺的那样。每个鸟正波形的文件名还包括鸟叫的频率。综合所有这些,以下是我的发现:

我预计许多电话会相当高。 很大一部分样本都是如此,但绝大多数实际上更接近低频(2000–3500Hz)。 挺惊喜的!

数据集和数据加载器类

好了,我们知道有单独的. hdf5 文件要处理成一个“数据集”,每个文件都有一个有点笨拙的数据结构。这些条件肯定需要一个定制的 PyTorch 数据集类来正确地加载我们的音频数据,以便稍后进行训练。数据集类主要需要__init____getitem__函数(还有__len__,但这很简单)。以下是我计划每个人要做的事:

**def __init__():**

  • 遍历所有四个文件中每个波形的每个组名&将它所属的文件和 HDF5 组添加到属于该类的列表中。
  • 获取波形的标签(文件/组名的最后一位)并添加到属于该类的另一个列表中。例如,文件名unit03_012712228_00000_0表示没有任何鸟类发声。
  • 准备一个应用于波形的变换函数,将其转换为声谱图(特别是 mel 缩放的声谱图),并允许其他增强技术。

**def __getitem__():**

  • 先前初始化的两个列表的索引
  • 通过列表接收到波形的位置后,打开该波形的 HDF5 文件。所有 HDF5 I/O 将使用 python 库h5py进行处理
  • 将其转换为 PyTorch 张量,并应用任何变换,包括频谱图变换。
  • 将物品返还给呼叫者。

下面,我将这些想法转化为数据集类的代码:

呀,这个太长了!如果太多了,只要相信我上面描述的任何功能都是在这里实现的。但是往好的方面看,基本上这次努力最难的障碍已经被超越了!

我们定义数据集文件的目录,以及文件名本身。我决定使用 4 个文件中的 3 个作为测试数据,最后一个作为验证/测试集来测量模型的性能,为后者留下最小的文件。由于每个文件的所有记录设备都设置得相对靠近(在伊萨卡的同一个城市),我相信绕过随机分割不会引入大量偏差。

用上面列出的三个文件制作一列火车

从最后一个(也是最小的)文件创建验证集

设置好数据集后,就该定义数据加载器了:

批量

定义数据加载器,它将成批返回数据。在意识到使用 PyTorch 和 HDF5 文件时存在一个 bug 之前,我已经尝试过设置多个“num_workers”

模型

模型创建

我为我的模型设置了任何必要的辅助函数,以便稍后进行训练:

定义多个函数,稍后可以使用这些函数来训练继承该类的 PyTorch 模型。

此函数在上述类的 val_step 函数中短暂使用,以确定验证数据加载器上模型的%(百分比)准确性,而不仅仅是验证损失。

并定义用于拟合/训练模型并在验证数据集上测试模型的主要函数:

定义训练/验证循环

最后, 这是我们一直在等待的简单 CNN 模型 :

相对简单,考虑到 ResNets 和其他流行的网络模型都比这个大很多很多!

我利用了多个卷积层,正如我们之前的理论推断建议我们为模型所做的那样,使用一些最大池层,然后是一个非常简单的全连接网络来进行实际分类。令人惊讶的是,这个架构后来表现得相当好,甚至超过了我自己的预期。

利用 GPU

如今,几乎每个人都需要一个 GPU 来训练比普通前馈神经网络更复杂的东西。幸运的是,PyTorch 使我们能够轻松利用可用 GPU 的能力。首先,我们将 cuda 设备定义为关键字device,以便于访问:

我们还确保如果没有 GPU,将使用 CPU 来代替。

这里还有另一个技巧:

这有助于提高你的训练速度(如果你的输入在大小/形状上没有变化的话)

显然,您可以“告诉”PyTorch 在反复训练时优化自己,只要训练输入在大小和形状方面保持不变。它会知道为你的特定硬件(GPU)使用最快的算法。你知道的越多!

然后,我们定义助手函数,将数据加载器、张量和我们的模型移动到我们的 GPU 设备。

各种助手功能,以确保我们总是在使用我们的 GPU。

培养

培训先决条件

使用我们的设备助手函数,我们将所有东西移动到我们的 GPU,如下所示:

我们的数据加载器-> GPU

型号-> GPU

我们还指定了我们的学习率和我们的纪元数量,这花了我很长的时间来为这两者找到一个好的值。

在我的实验中,我发现这些超参数是最有效的。

现在, 起!

好了,我们终于开始训练了!

我们发现模型在任何训练之前的表现:

很明显,我们在准确性上有点幸运,开始时有点有利,但根据几次试验,最终结果将非常相似,如果不是相同的话。

接下来,我们使用我们之前定义的fit函数来训练我们简单的Classifier模型实例:

忽略' HBox '文物,我知道我不应该使用 tqdm!

在看到准确性略有下降后,我决定再训练一点点,以将模型重定向回正确的方向:

啊,更多的盒子!但是,看那准确性!

总而言之,以下是我们在用于训练的 11 个时期内的训练统计数据:

总的来说,我们的模型训练得很好,从表面上看,我们可能已经找到了模型损失的相对最小值。

等等,一个更复杂的模型或者使用不同的变换怎么样?

相信我,在我简单的Classifier()第一次尝试成功后不久,我也尝试过这两种方法。我决定不包括两者的细节,因为我发现他们的结果实际上比我们已经取得的结果更糟糕,很奇怪。

如果你想看看我是如何尝试实现这两者的,请直接来看我贴在这里的笔记本:https://jovian.ml/richardso21/bird-audio-detection

对于额外的声谱图转换,我尝试了随机时移和噪声注入。长话短说,它似乎根本没有提高验证的准确性。此后,我对此进行了推理,因为数据集规范明确指出,所有啁啾都将位于音频记录的中间处,因此随机移动频谱图以实现更好的模型泛化实际上可能会损害其性能。然而,我还没有尝试只有随机噪声注入。**

我还试图训练一个 ResNet50 模型,希望进一步提高验证的准确性。这里是最令人难以置信的部分: 我从未得到过超过 50%准确率的模型当我写这篇文章的时候,我还不确定我到底做错了什么,所以如果其他人可以看看我上面的笔记本并帮助我,我非常乐意接受任何意见或建议!**

结论

总的来说,我会说这是一次非常有趣的尝试,值得花些时间去隔离。首先,我不得不重温我去年夏天调查过的东西,这确实有一种怀旧的感觉。更重要的是,我们学习了如何为一个很可能是真实世界的场景实现一个 PyTorch 数据集类,在这个场景中,数据不一定是按照您所期望的那样设置的。最后,大约 84%的最终验证分数对于我在运行中构建的这样一个简单的网络架构来说是相当不错的。**

然而,我希望你喜欢这篇文章,就像我喜欢做它一样!一如既往,快乐编码!(这是* 真的 开始成为我在媒体上的流行语……)*

如果你想要这篇文章中所有代码示例的源代码/笔记本,你可以访问https://jovian.ml/richardso21/bird-audio-detection

如何稳定甘训练

原文:https://towardsdatascience.com/wasserstein-distance-gan-began-and-progressively-growing-gan-7e099f38da96?source=collection_archive---------16-----------------------

Wasserstein 距离、边界平衡和渐进生长 GAN

gan 主导图像生成和图像翻译等深度学习任务。

在之前的帖子中,我们已经了解了不成对的图像到图像的转换。然而,在你实现你自己的超级酷的深度 GAN 模型之前,有一些真正重要的概念你必须理解。

在这一部分,我们将看看一些基础性的工作。我们将看到最常见的 GAN 距离函数及其工作原理。然后,我们会把甘斯的训练感知为试图寻找一个两人博弈的均衡。最后,我们将看到渐进式训练的革命性成果,首次实现了逼真的百万像素图像分辨率

图片来自作者。希腊某地的日出。如果你的 GAN 模特训练得像日出一样流畅岂不是很好?

我们将探索的研究主要解决模式崩溃和训练不稳定性。一些从未训练过 GAN 的人会很容易地认为我们总是指这两个轴。在现实生活中,为一个新问题训练一个大规模的 GAN 可能是一场噩梦

如果你开始阅读和实施最新的方法,在新问题中训练新手几乎是不可能成功的。其实就像中了彩票一样。

当你离开最常见的数据集(CIFAR、MNIST、CELEBA)时,你已经陷入混乱。

这个评论系列的目标是像我们这样的人,他们超级有野心,但不想花所有的时间阅读该领域的所有参考书目。

通常情况下,您试图在调试时直观地理解学习曲线,以便猜测可能工作得更好的超参数。但是 GAN 训练是如此不稳定,以至于这个过程经常是浪费时间。这个可爱的工作是第一个为甘训练计划提供广泛理论依据的工作之一。有趣的是,他们发现了分布之间所有现存距离的模式。

核心理念

核心思想是有效测量模型分布与真实分布的接近程度。因为选择如何测量距离会直接影响模型的收敛。正如我们现在所知道的,GANs 可以表示来自低维流形的分布(噪声 z)。

直觉上,这个距离越弱,就越容易定义从参数空间(θ-空间)到概率空间的映射,因为已经证明分布更容易收敛。

我们有理由要求这种连续映射。主要是因为可以定义一个连续函数来满足这个连续映射,这个连续映射给出了期望的概率空间或生成的样本。

出于这个原因,这项工作引入了一个新的距离,称为瓦瑟斯坦-甘。它是推土机(EM)距离的近似值,理论上表明它可以逐步优化 GAN 的训练。令人惊讶的是,不需要在训练期间平衡 D 和 G,也不需要网络架构的特定设计。这样,减少了 GANs 中固有的模式崩溃。

理解 Wasserstein 距离

在我们深入讨论拟议损失之前,让我们先来看一些数学计算。正如 wiki 中完美描述的,部分有序集合的子集的上确界 ( sup) 是大于或等于的所有元素中的最小元素。因此,上确界也被称为最小上界。我个人把它称为 T 中能找到的所有可能组合的子集的最大值。

现在,让我们在 GAN 术语中引入这个概念。 T 是我们可以从 GD 中得到的所有可能的配对函数近似值 f。S 将是那些函数的子集,我们将约束这些函数以使训练更好(某种正则化)。排序将自然地来自计算的损失函数。基于以上所述,我们最终可以看到 Wasserstein 损失函数,其测量两个分布 Pr 和 Pθ之间的距离。

图片由作者提供,最初用 Latex 编写。

这个严格的数学约束被称为 K-Lipschitz 函数以得到子集。但是如果它被广泛证明,你不需要知道更多的数学。但是我们如何引入这种约束呢?

处理这种情况的一种方法是通过训练一个神经网络,使其权重位于一个紧凑空间中,来粗略地近似这个约束。为了达到这一点,最简单的方法就是将砝码固定在一个固定的范围内。

就是这样,重量剪裁如我们所愿!因此,每次梯度更新后,我们将 w 范围削波至[0.01,0.01]。这样,我们显著地加强了 Lipschitz 约束。简单,但我可以向你保证它的工作!

事实上,有了这个距离损失函数,它当然是连续的和可微的,我们现在可以用提出的标准训练 D 直到最优,而其他距离饱和。饱和意味着鉴频器的损耗为零,生成的样本仅在某些情况下有意义。所以现在,饱和(自然导致模式崩溃)得到了缓解,我们可以在所有训练范围内使用更线性风格的梯度进行训练。让我们看一个例子来阐明这一点:

图片由 WGAN paper[https://arxiv.org/abs/1701.07875]提供

WGAN 标准在空间的所有部分提供了清晰的梯度。

为了在实践中看到所有以前的数学,我们在 Pytorch 中提供了 WGAN 编码方案。您可以直接修改您的项目以包含此损失标准。通常在真实的代码里看比较好。值得一提的是,为了保存子集并获取上限,这意味着我们必须获取许多对。这就是为什么你会看到我们每隔一段时间就训练一次生成器,以便鉴别器得到更新。这样,我们就有了定义上确界的集合。注意,为了接近上确界,我们也可以在升级 D 之前为 G 做很多步骤。

在后来的工作中,事实证明,即使这个想法是可靠的,重量削减也是一种加强期望约束的可怕方式。使函数成为 K-Lipschitz 的另一种方法是梯度惩罚

关键的想法是一样的:将重量保持在紧凑的空间。然而,他们通过约束评论家的输出相对于其输入的梯度规范来做到这一点。

我们不会讨论这篇文章,但是为了一致性和方便用户实验,我们提供了代码作为普通 wgan 的改进替代方案。

结果和讨论

在我们简短的描述之后,我们现在可以进入一些结果。看到 GAN 在训练中如何学习是很美好的,如下图所示:

图片由 WGAN paper[https://arxiv.org/abs/1701.07875]提供

使用 DCGAN 发生器的 Wasserstein 损耗准则。如您所见,损耗快速稳定下降,同时样品质量提高。这项工作被认为是 GANs 理论方面的基础,可以总结为:

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

  • 瓦瑟斯坦准则允许我们训练 D 直到最优。当准则达到最佳值时,它只是向生成器提供一个损耗,我们可以像训练任何其他神经网络一样训练该损耗。
  • 我们不再需要适当地平衡 GD 容量。
  • Wasserstein 损失导致训练 G 的梯度质量更高。
  • 据观察,对于发电机和超参数调谐的架构选择,WGANs 比普通 gan 更加鲁棒

的确,我们确实提高了优化过程的稳定性。然而,没有什么是零成本的。WGAN 训练变得不稳定基于动量的优化器如 Adam,以及高学习率。这是合理的,因为标准损失是高度不稳定的,所以基于动量的优化器似乎表现更差。这就是他们使用 RMSProp 的原因,众所周知 RMSProp 在非平稳问题上表现出色。

最后,理解本文的一个直观方式是与层内激活函数历史上的梯度进行类比。特别是,sigmoid 和 tanh 激活的梯度消失,有利于 ReLUs,因为在整个数值范围内梯度得到了改善。

始于(边界均衡生成对抗网络 2017)

我们经常看到,鉴频器在刚开始训练的时候进步太快。然而,平衡鉴别器和生成器的收敛是一个现有的挑战。

这是第一个能够控制图像多样性和视觉质量之间的平衡的作品。利用简单的模型架构和标准的训练方案,获得高分辨率图像。

为了实现这一点,作者引入了一个技巧来平衡生成器和鉴别器的训练。BEGAN 的核心思想是这种新的强制平衡与描述的 Wasserstein 距离相结合。为此,他们训练了一个基于自动编码器的鉴别器。有趣的是,由于 D 现在是一个 自动编码器,它产生图像 作为输出,而不是标量。在我们继续之前,让我们记住这一点!

正如我们所见,匹配误差分布比直接匹配样本分布更有效。一个关键点是,这项工作旨在优化自动编码器损耗分布之间的 Wasserstein 距离,而不是样本分布之间的 wasser stein 距离。begin 的一个优点是不明确要求鉴别器受 K-Lipschitz 约束。自动编码器通常用 L1 或 L2 范数来训练。

两人博弈均衡的形成

为了用博弈论来表达问题,增加了一个平衡鉴别器和生成器的平衡项。假设我们可以理想地生成不可区分的样本。那么,它们的误差分布应该是相同的,包括它们的期望误差,也就是我们在处理每一批后测量的误差。完美平衡的训练将导致 L(x)和 L(G(z)的期望值相等。然而,从来不是这样!由此开始决定量化平衡定额,定义为:

图片由作者提供,最初用 Latex 编写

这个量在网络中被建模为超参数。因此,新的训练方案涉及两个相互竞争的目标:a)自动编码真实图像和 b)辨别

真实来自生成的图像。γ项让我们平衡这两个目标。γ值越低,图像多样性越低,因为鉴别器更侧重于自动编码真实图像。但是,当预期损失变化时,如何控制这个超参数呢?

边界平衡 GAN(开始)

答案很简单:我们只需引入另一个落入[0,1]范围内的变量 kt。这个变量将被设计来控制在训练期间放在 L(G(z))上的焦点。

图片由作者提供,最初用 Latex 编写

它初始化为 k0 = 0,λ_k 也被定义为本研究中 k (使用 0.001)的比例增益。这可以被视为闭环反馈控制的一种形式,其中 kt 在每一步都被调整,以保持所选超参数γ的期望平衡。

注意,在早期训练阶段, G 倾向于为 D 生成易于重建的数据。同时,真实的数据分布还没有被准确地获知。基本上就是 L(x) > L(G(z))。与许多 GANs 相反,BEGAN 不需要预训练,可以用 Adam 进行优化。最后,通过使用平衡概念,导出收敛的全局度量。

本质上,可以将收敛过程公式化为寻找 a)最接近的重构 L(x)和 b)控制算法| |γL(x)—L(G(z))| |的最低绝对值。将这两项相加,我们就可以知道网络何时收敛。

模型架构

模型架构非常简单。一个主要的区别是引入了指数线性单位而不是 ReLUs。他们使用带有深度编码器和解码器的自动编码器。超参数化旨在避免典型的 GAN 训练技巧。

图片来自 https://arxiv.org/abs/1703.10717 报纸。模型架构

使用 U 形结构,没有跳过连接。下采样被实现为核为 3、步长为 2 的子采样卷积。另一方面,上采样是通过最近邻插值完成的。在编码器和解码器之间,经过处理的数据的张量通过完全连接的层被映射,没有任何非线性。

结果和讨论

在下面的 128x128 插值图像中可以看到一些呈现的视觉效果:

图片由 begin[https://arxiv . org/ABS/1703.10717]提供。由 BEGAN 生成的插值 128x128 图像

值得注意的是,观察到变化随着γ增加,但伪像(噪声)也增加。可以看出,插值显示出良好的连续性。在第一行,头发过渡和发型被改变。同样值得注意的是,左图中的一些特征消失了(香烟)。第二行和最后一行显示简单的旋转。虽然旋转是平滑的,但是我们可以看到侧面照片没有被完美地捕捉。

最后一点,使用 BEGAN 平衡法,网络收敛到多样的视觉愉悦的图像。这在 128x128 分辨率下仍然适用,只需稍加修改。训练是稳定的、快速的,并且对于小的参数变化是鲁棒的。

但是让我们看看真的高分辨率会发生什么!

渐进 GAN(2017 年为提高质量、稳定性和变化而渐进生长 GAN)

到目前为止,我们所描述的方法可以产生清晰的图像。然而,它们只能以相对较小的分辨率生成图像,并且变化有限。分辨率低的原因之一是训练不稳定。如果您已经部署了自己的 GAN 模型,您可能知道由于计算空间的复杂性,大分辨率需要较小的小批量。以这种方式,时间复杂性的问题也增加了,这意味着你需要几天来训练一个 GAN。

增量增长架构

为了解决这些问题,作者从低到高分辨率图像开始,逐步增加生成器和鉴别器

直觉是,随着训练的进行,新添加的层旨在捕捉对应于高分辨率图像的更高频率的细节。

但是是什么让这种方法如此好呢?

答案很简单:模型首先发现大规模(全局)结构,然后发现局部细粒度细节,而不是必须同时学习所有规模。增量训练自然以此为目标。值得注意的是,在整个训练过程中,所有层都是可训练的,并且网络架构是对称的(镜像)。下面描述了所描述的体系结构的图示:

甘斯纸业[https://arxiv.org/abs/1710.10196]逐步增长的图像

然而,由于不健康的竞争,模式崩溃仍然存在,这增加了 GD 中误差信号的幅度。

在过渡之间引入平滑层

这项工作的关键创新是新增层的平滑过渡稳定训练。但是每次转变之后会发生什么呢?

图片由甘斯纸业逐步成长而来,链接:https://arxiv.org/abs/1710.10196

真正发生的是图像分辨率翻倍。因此在 GD 上新增一层。这就是奇迹发生的地方。在过渡期间,在较高分辨率上操作的层被用作剩余的跳跃连接块,其权重(α)从 0 线性增加到 1。一个意味着跳过连接被丢弃。

所描绘的 toRGB 块代表层,该层将一维特征向量投影和整形为 RGB 颜色。它可以被视为总是以正确的形状带来图像的连接层。并行地,来自 RGB 的执行相反的操作,而两者都使用 1 × 1 卷积。真实图像被相应地缩小以匹配当前尺寸。

有趣的是,在转换过程中,作者在真实图像的两种分辨率之间进行插值,以模拟 GANs 式学习。此外,对于渐进式 GAN,大多数迭代都是在较低的分辨率下执行的,从而导致 2 到 6 次训练加速。因此,这是第一个达到百万像素分辨率的作品,即 1024x1024

与遇到协方差偏移的下游任务不同,gan 表现出越来越大的误差信号幅度和竞争问题。为了解决这些问题,他们使用正态分布初始化和每层权重归一化,通过每批动态计算的标量。这被认为是使模型学习尺度不变性。为了进一步限制信号幅度,它们还将逐像素特征向量归一化为生成器中的单位长度。这防止了特征地图的升级,同时不会显著恶化结果。附带的视频可能有助于理解设计选择。官方代码发布在 TensorFlow 这里

TL;DR:结果和讨论

结果可总结如下:

1)网络容量的逐渐增加解释了收敛速度的提高直觉上,现有的层学习较低的尺度,因此在过渡之后,引入的层仅负责通过逐渐变小的尺度效果来改进表示。

2)渐进增长的加速随着输出分辨率的增加而增加。这使得第一次能够生成 1024x1024 的清晰图像。

3)即使实现这样的架构真的很难,并且缺少很多培训细节(即何时进行过渡以及为什么),但它仍然是我个人崇拜的不可思议的作品。

GANs 渐进生长图像,百万像素分辨率,链接:https://arxiv.org/abs/1710.10196

结论

在这篇文章中,我们遇到了一些至今仍在使用的最先进的训练理念。我们关注这些重要培训方面的原因是为了能够进一步展示更高级的应用程序。如果你想从游戏理论的角度来看甘斯,我们强烈建议你去看达斯卡拉基斯的谈话。最后,对于我们的数学爱好者来说,这里有一篇精彩的文章,它更详细地介绍了向 WGAN 的过渡。

总之,我们已经找到了几种方法来处理模式崩溃、大规模数据集和百万像素分辨率的增量训练。欲了解整个文章系列,请访问艾夏。

参考

[1]阿尔乔夫斯基,m .,钦塔拉,s .,&博图,L. (2017)。瓦瑟斯坦·甘。 arXiv 预印本 arXiv:1701.07875

[2]贝特洛博士、舒姆博士和梅斯博士(2017 年)。开始:边界平衡生成对抗网络。 arXiv 预印本 arXiv:1703.10717

[3]t . Karras,t . Aila,t . Laine,s .,& Lehtinen,J. (2017)。为了提高质量、稳定性和多样性而逐步种植甘蔗。 arXiv 预印本 arXiv:1710.10196

[4]达斯卡拉基斯,c .,a .,西尔格卡尼斯,v .,&曾,H. (2017)。乐观地训练甘斯arXiv 预印本 arXiv:1711.00141

[5]古尔拉贾尼、艾哈迈德、阿尔乔夫斯基、杜穆林和库维尔(2017 年)。改进了瓦瑟斯坦·甘斯的训练。在神经信息处理系统的进展(第 5767–5777 页)。

原载于 2020 年 4 月 21 日 https://theaisummer.com**T21

通过 Seaborn 和 Matplotlib 观看板球比赛

原文:https://towardsdatascience.com/watch-a-cricket-game-through-seaborn-and-matplotlib-7047c82b380?source=collection_archive---------41-----------------------

印度超级联赛 T20 板球比赛数据点的可视化——孟买印度人队对钦奈超级国王队

阿克什·亚达夫Unsplash 上的照片

现代板球比赛产生大量统计数据和用户生成的数据。教练和性能分析师利用这些信息为未来的比赛设计策略,并寻找新的人才。在本文中,我使用 Seaborn 和 Matplotlib 库可视化了最近结束的印度超级联赛(IPL) T20 比赛的数据。这个练习的动机是探索和理解各种数据点,并识别可能的机器学习用例的不同特征。

资料组

我使用了来自https://www.espncricinfo.com的公开数据进行 IPL 2020 赛季揭幕战——2020 年 9 月 19 日孟买印度人(MI) vs 钦奈超级国王(CSK) @阿布扎比。

更新:2020 年 12 月——这里使用的数据是我在 Kaggle 发布的综合数据集的一部分。请 参考这里的

为什么?

我是钦奈超级国王队的狂热粉丝,CSK vs 米是 IPL 中的激烈战斗,这两支球队在世界范围内都有大量的粉丝。这是 IPL 的“El Clásico”,IPL 的利物浦 vs 曼联,Dhoni 女士又名“Thala”&“酷队长”是 CSK 的杰拉德。

让我们来玩吧!

条形图、计数图和分布图

首先,让我们用柱状图和计数图来看看两个队的得分。

运行 per over-MI vs CSK(图片由作者提供)

赛跑的种类——米对 CSK(图片由作者提供)

运行分发(图片由作者提供)

前两个图显示了每场比赛的得分,接下来的两个图显示了每支球队得分的得分类型。计数图(跑垒次数)和分布图确实表明两局得分类型相似,只有很小的差异。然而,条形图(每回合得分)描绘了两局之间的重要对比。米在开始的几局力量比赛中表现抢眼,随后是几局下滑,而 CSK 的力量比赛令人不安,并在力量比赛结束时(6 局后)加快了速度,并保持稳定的速度,直到比赛结束。

线形图

下一组线图显示了游戏从开始到结束的过程(从超过 1 到 20)

游戏进度——米 vs(线条图——作者图片)

从这些情节中得出的主要结论是,尽管 CSK 的总得分直到比赛结束时都低于米,但随着比赛的进行,他们的得分率比米高得多,而米的得分率却在下降(这要归功于队长 MSD 指挥的 CSK 的精彩保龄球表演)。很明显,CSK 在生死关头加快了他们的得分速度(像往常一样!)并在最后经过 m1(如上面的第二和第三线图所示)

热图

让我们用热图来想象击球手和投球手的表现。

击球手 vs 投球手——米 vs(图片由作者提供)

小提琴情节

让我们看看每个击球手对特定保龄球攻击得分的分布。使用小提琴的节奏和旋转

击球手跑垒分布(图片由作者提供)

返回条形图

现在让我们看看每个击球手对特定保龄球攻击的总得分。步伐和旋转

击球手的跑位与保龄球的类型(图片由作者提供)

更多热图

下面的热图提供了 CSK 保龄球表现的详细直观表示。

CSK 保龄球线和长度(作者图片)

CSK 保龄球线和长度米击球手(图片由作者)

还有更多热图!

CSK 保龄球线和长度与击球(图片由作者提供)

保龄球手 vs 击球风格(作者图片)

散点图

散点图有助于了解谁在局的不同部分得分以及他们得分了多少分。正如我们在下面所看到的,MI 击球手在强力击球时得分更多,而 CSK 击球手在临近结束时得分更多。

随着比赛的进行,球队得分(图片由作者提供)

每局比赛中击球手的分数(图片由作者提供)

上面的散点图显示了安巴蒂·拉尤杜和 F 阿夫·杜·普莱西通过轮换击球来构建他们的局,承担计算好的风险来得分,以跟上游戏进行中所需的跑分率——这是他们建立的伟大合作关系的可视化。

词云

最后,让我们来看看游戏期间 www.espncricinfo.com 记分卡中显示的用户评论的词云表示。它很好地总结了这场比赛,公平地回应了公众的情绪

游戏过程中来自用户评论的文字云(图片由作者提供)

接下来呢?

观看 CSK 今年在 COVID 的情况下比赛是一种美妙的体验。甚至很高兴看到 MSD 领导这支伟大的球队,做他最擅长的事情。玩这些数据,帮助我在探索数据可视化和体育分析方面的同时,重温了这场伟大的比赛。可以做进一步的工作来开发数据集和建立机器学习模型,以预测影响游戏甚至游戏结果的各种数据点。更多即将推出…

我的 GitHub 链接到 Jupyter 笔记本

链接到数据集— Kaggle

参考资料:

https://www.espncricinfo.com—数据抓取

[## Matplotlib: Python 绘图— Matplotlib 3.3.2 文档

Matplotlib 是一个全面的库,用于在 Python 中创建静态、动画和交互式可视化…

matplotlib.org](https://matplotlib.org) [## 用户指南和教程— seaborn 0.11.0 文档

编辑描述

seaborn.pydata.org](https://seaborn.pydata.org/tutorial.html)

观看这个人工智能算法在一个在线游戏中击败玩家

原文:https://towardsdatascience.com/watch-this-ai-algorithm-beating-players-in-an-online-game-video-27fde513333e?source=collection_archive---------64-----------------------

艾玩拼图

这是代理在与其他玩家在线对战时“看到”的内容。

这是一篇三篇文章的最后一篇,在这篇文章中,我走过了这个 AI 算法的训练。随意退房:第一部第二部第三部

在训练过程中,代理通过与自己对抗,挑战自己的知识来学习如何玩游戏。以下是代理与其他玩家在线对战的结果:

为什么 AI 一直赢不了?

我想通过解释为什么经纪人会输给一些球员来说明最后一点。

简称 Agent,是一种通过深度强化学习训练的 AI 算法。代理能够击败一些球员,但不能击败其他人。看不到敌人何时“把代理人推到边缘”,迫使它不可避免地做出糟糕的举动。此外,有时代理人执行一个荒谬的行动,让对手得到很多分。

在训练过程中,代理通过与自己对抗,挑战自己的知识来学习如何玩游戏。请注意,这将产生一个不同的训练数据,而不是代理人为了训练而与人对弈的情况。总是有可能存在一个策略来对抗代理的策略。从理论上讲,如果代理被迫对训练中没有遇到的状态做出决策,它很可能会做出糟糕的决策。

“我们对强化学习问题的框架迫使我们满足于近似。然而,它也为我们提供了一些获得有用近似值的独特机会。例如,在逼近最优行为时,可能有许多状态,代理面临的概率如此之低,以至于为它们选择次优行动对代理接收的奖励量几乎没有影响。例如,Tesauro 的西洋双陆棋玩家具有非凡的技能,尽管它可能会在棋盘配置上做出非常糟糕的决定,而这种情况在与专家的游戏中从来不会发生。事实上,TD-Gammon 有可能在游戏的大部分状态设置中做出错误的决定。强化学习的在线性质使得有可能以这样的方式逼近最优策略,即以较少的努力用于不经常遇到的状态为代价,将更多的努力用于学习以便为经常遇到的状态做出好的决策。这是强化学习区别于其他近似求解 MDP 的方法的一个关键特性。”

—萨顿&巴尔托,《强化学习导论》,2018 年

简而言之,打败人工智能算法是可能的。也有可能训练出一种比我们现有的算法更接近无敌的算法。

伦理学

从其他玩家的角度来看,与人工智能算法比赛可能是一次令人生畏的经历。作为我的辩护,打败人工智能是可能的,就像我和其他玩家一样。因此,这并不像和我比赛那样令人畏惧,如果 AI 不在的话,他们会和我比赛。此外,游戏是在游戏内货币的赌注上进行的。正因为如此,赌注保持在很小的范围内,每次代理人赢了另一个玩家,赢得的钱会立即退还。

想了解更多信息吗?

这是一篇三篇文章的最后一篇,在这篇文章中,我走过了这个 AI 算法的训练。随意退房:第一部第二部第三部

关于我

我是一名数据科学家,住在旧金山。热衷于使用用户生成的数据。在 Linkedin 上找到我:mer sakar ya

沃森·奥塔伊

原文:https://towardsdatascience.com/watson-autoai-7fb1e82471ea?source=collection_archive---------50-----------------------

autoML 系列的第六部:蓝色巨人给人留下了互动进步的印象

图片由皮克斯拜的 Gerd Altmann 提供

惊讶!令人惊喜的是,这是 m autoML 系列的第六次安装。虽然我几年前使用过 IBM 的数据科学云平台,但我之前从未接触过 Watson Studio 或他们的 AutoAI 产品。我不确定我会找到什么,但我对我所看到的很满意。对于那些希望(需要)在训练过程中不断得到进度反馈的人来说,我喜欢所提供的大量信息。精确度不如 DataRobot 或 H2O 无人驾驶人工智能,但基于价格的巨大差异(每年数万美元),这是可以预期的。

为什么选择 IBM Watson Studio AutoAI?

蓝色巨人不仅仅是大型机和 SPSS。我几年前用过 IBM 数据科学云笔记本环境。沃森在 IBM 有一段传奇历史。虽然你没有运行“华生”,但声誉带来了权威。

成本

我可以免费进行这个实验。对于数据科学家个人来说,定价等级非常合理。

作者定价截图

设置

试试 IBM Watson Studio

“这些功能是针对 IBM Cloud 上的数据服务的完全托管的 Cloud Pak 初始集的一部分。立即免费提供 Watson Studio 和 Watson Machine Learning 的集成精简版,作为 Cloud Pak for Data as a Service 的一部分。”

上面的链接会带你到 Watson Studio 上的“尝试 AutoAI”按钮。AutoAI 是一个托管云解决方案,因此建立一个新项目的过程非常简单。

进入 Watson Studio 后,您可以添加一个 AutoAI 资产。

作者截图

从那里,你可以建立一个新的实验。

作者截图

数据

为了保持本系列中各种工具的平等性,我将坚持使用 Kaggle 培训文件。矛盾,我亲爱的华生。使用 TPUs 检测多语言文本中的矛盾和蕴涵。在这个入门竞赛中,我们将句子对(由一个前提和一个假设组成)分为三类——蕴涵、矛盾或中性。

6 列 x 13k+行—斯坦福 NLP 文档

  • 身份证明(identification)
  • 前提
  • 假设
  • 朗 abv
  • 语言
  • 标签

加载数据

再简单不过了。

作者截图

训练您的模型

配置和运行实验的界面非常简单。在实验设置下还有一些其他选项,但是我想尽可能简单地运行它。选择你的标签,点击运行实验。

作者截图

这就是乐趣所在!有一个互动的可视化,让你看到你在实验过程中的位置。我喜欢这个!您还可以在培训期间查看排行榜。

作者训练 gif

评估培训结果

有一个小指标表明实验已经完成。我本以为会有更引人注目的东西,但我很高兴它在合理的时间内完成,22 分钟。

作者截图

排行榜提供了关于准确性和其他成功指标的信息,以及模型类型和所做的改进(如功能工程)。我没有看到各种各样的模型尝试,因此培训时间很短。

作者截图

作者截图

对于 Pipeline 3,我研究了工程特性。你必须研究细节,因为‘new feature _ 2’不是很能说明问题。

作者截图

结论

有趣的是,在培训结束后,我看到一个弹出窗口,介绍对多个数据集的特征工程。肯定的,要调查的东西!如果他们能够识别数据集之间的关系,并创建新的功能,那将是惊人的。

总的来说,我很喜欢 Watson AutoAI 体验本身。这个过程运行得很快(22 分钟,而 H2O 无人驾驶人工智能的时间超过 4 小时),但代价是开箱即用的模型多样性和准确性。将需要额外的实验装置。但对于比 DataRobot 和 H2O 无人驾驶人工智能低 7.8 万美元的价格来说,这可能是一个可以接受的权衡。

我鼓励你考虑使用 AutoAI。这个 IBM 产品是一个价格合理的 autoML 工具。

如果您错过了本系列中的一篇文章,这里有链接。

[## AWS Sagemaker Studio 自动驾驶仪准备好迎接黄金时段了吗?

带有一些评论的自动驾驶界面演示

towardsdatascience.com](/is-aws-sagemaker-studio-autopilot-ready-for-prime-time-dcbca718bae7) [## 免费体验 Google autoML 表格

autoML 工具用户体验评论系列之二。

towardsdatascience.com](/experience-google-automl-tables-for-free-d5648ae3d0e5) [## Azure Automated ML 倾听他们的设计师

本 autoML 系列的第 3 部分,微软,绝地大师

towardsdatascience.com](/azure-automated-ml-listens-to-their-designers-7f1c68d19eb4) [## 数据机器人让生活变得简单

汽车系列之四——设计之美

towardsdatascience.com](/datarobot-makes-life-easy-8505637241e5) [## H2O 无人驾驶人工智能

autoML 系列的第五名—可视化和可解释性的第一名

towardsdatascience.com](/h2o-driverless-ai-71414b441425)

Wav2Lip:一个唇同步专家是你在野外进行语音到唇生成所需要的

原文:https://towardsdatascience.com/wav2lip-a-lip-sync-expert-is-all-you-need-for-speech-to-lip-generation-in-the-wild-b1cb48787190?source=collection_archive---------17-----------------------

Wav2Lip 模型架构(https://arxiv.org/pdf/2008.10010v1.pdf)

本文提出了 Wav2Lip,它是 SyncNet 模型的一种改进,在视频-音频唇形同步任务方面优于所有先前的与说话人无关的方法。

作者指出,虽然现有方法在呈现训练集中不存在的说话者的视频时通常不能通用化,但 Wav2Lip 能够对各种说话者产生准确的嘴唇运动。

他们继续总结了本文的主要意图:

  1. 识别先前方法不能推广到各种说话者的原因。
  2. 通过结合强大的唇同步鉴别器来解决所述问题。
  3. 提出新的基准来评估对口型任务的方法的性能。

介绍

作者的第一点是关于最近视频和音频内容消费的繁荣。除此之外,越来越需要将音像翻译成多种语言,以促进更多公众的参与。因此,将机器学习应用于诸如不受约束的视频-音频内容的自动口型同步这样的任务有很大的动机。

然而,不幸的是,早期的方法通常不能推广到多种说话人身份,只有在对组成其训练集的潜在说话人的小子集进行评估时才表现良好。

这种方法将不能满足上述实际应用的严格要求,其中合适的模式必须能够精确地同步各种扬声器。

由于在实践中使用这种方法的苛刻要求,人们需要一种可以推广到各种说话者身份的模型。结果,出现了与说话者无关的方法。这些模型在数千个说话者身份上被训练。然而,即使是在以前的出版物中采用的这些方法也不能满足本工作作者的期望。他们承认,先前的与说话者无关的模型虽然能够在单独的静态图像上生成准确的唇同步,但不适用于动态内容。对于诸如电视连续剧和电影的翻译的应用,要求一种方法对于不同的无约束视频中说话者的变化的唇形更具普遍性。

作者指出,人类可以检测到大约 0.05-0.1 秒不同步的视频片段,因此这意味着一个具有细微误差的广泛挑战。

本节最后简要总结了作者的贡献:

  1. 他们提出了 Wav2Lip ,这明显优于以前的方法。
  2. 他们引入了一套新的基准/指标来评估模型在这项任务中的表现。
  3. 他们发布自己的数据集,以评估他们的方法在呈现从野外采样的看不见的视频音频内容时的性能。
  4. Wav2Lip 是第一个与说话者无关的方法,它经常匹配真实同步视频的准确性;根据人类评估,他们的方法在大约 90%的情况下优于现有的方法。
  5. 他们将为配音视频生成同步视频帧的 FID 分数从 12.87 (LipGAN)提高到 11.84 (Wav2Lip + GAN),将平均用户偏好从 2.35% (LipGAN)提高到 60.2% (Wav2Lip + GAN)。

现有文献综述

(我将把这一部分限制在作者提及这些论文的原因上,而省略掉具体关于这些作品的方法的深入信息)

作者承认以前的方法和在现实世界中完全工作的方法的要求之间存在一些差异:

  1. 一些方法需要大量的训练数据。
  2. 该模型在词汇学习范围方面的局限性。
  3. 在具有有限词汇集的数据集上进行训练妨碍了现有方法学习各种音位-视位映射的能力。

他们继续争论为什么当呈现来自野外的看不见的视频内容时,先前的方法通常不能产生准确的唇同步:

  1. 像素级重建损失是对口型同步的弱判断:先前工作中包含的损失函数不足以惩罚不准确的口型同步生成。
  2. 弱唇同步鉴别器:Lip gan 模型架构中的鉴别器在检测不同步视频音频内容时只有 56%的准确率,而 Wav2Lip 的鉴别器在同一测试集上区分同步内容和不同步内容的准确率为 91%。

你只需要一个对口型专家

最后,作者提出了他们的方法,考虑到上述两个问题在以前的工作。

  • 使用预先训练的唇形同步鉴别器,该鉴别器在检测原始的、不受约束的样本中的不同步视频-音频内容方面已经是准确的。
  • 为此任务调整先前存在的 SyncNet 模型。(这个我就不深究了,我只强调一下 Wav2Lip 架构)。

Wav2Lip 模型架构概述

Wav2Lip 模型架构(【https://arxiv.org/pdf/2008.10010v1.pdf】T4)

术语

作者使用以下术语来指代他们网络的各个部分,我将在本节后面继续使用这些术语:

  • 随机参考片段:用于识别特定说话人的一段连续帧的随机样本,提供特定于前述说话人的身份的网络上下文。
  • 身份编码器:对基础真相帧和随机参考片段的连接进行编码,为网络提供可视上下文以适当适应任何特定的说话者。
  • 语音编码器:编码音频数据(不言自明)。
  • 人脸解码器:将串接的特征向量解码成一系列重构帧。

方法学

在高级别上,Wav2Lip 输入特定音频片段的 Mel-频谱图表示,以及对应的基本事实帧(下半部分被屏蔽)和随机参考片段的拼接,该随机参考片段的扬声器确认基本事实片段的扬声器。它通过卷积层减少这种输入,以形成音频和帧输入的特征向量。然后,它连接这些特征表示,通过一系列转置卷积层将结果矩阵投影到一段重建帧上。在身份编码器和面部解码器的层之间存在剩余的跳过连接。

Wav2Lip 试图从它们的屏蔽副本中完全重建地面真实帧。我们计算重建帧和地面真实帧之间的 L1 重建损失。然后,重构的帧通过预训练的“专家”唇形同步检测器馈送,而重构的帧和地面真实帧都通过视觉质量鉴别器馈送。视觉质量鉴别器试图区分重构帧和真实帧,以提高帧生成器的视觉生成质量。

损失函数

发电机

生成器旨在最小化重建帧\(L_g\)和地面真实帧\(L_G\)之间的 L1 损耗:

其中,𝑵是普遍接受的表示批量的符号。

唇形同步鉴别器

对于唇同步,他们使用二进制交叉熵损失实现余弦相似性,从而计算给定两帧的概率。更具体地,在重新激活的视频和语音嵌入𝑣和𝑠.之间计算损失这会产生一个概率列表,每个样本一个,表示相应样本同步的概率。

其中应用的 ReLU 激活可以描述为:

完整的专家鉴别器损耗通过取分布\(P_{sync}\)的交叉熵来计算,如下所示:

视觉质量鉴别器

视觉质量鉴别器被训练成最大化以下损失:

其中,发电机损耗\(L_{gen}\)的计算公式如下:

因此,生成器试图最小化重建损失、同步损失和对抗损失的加权和(回想一下,我们正在处理两个鉴别器):

其中\(s_w\)是表示归因于同步的惩罚的加权值,而\(s_g\)是对抗性损失。

这两个不相交的鉴别器允许网络实现优越的同步精度和视觉生成质量。

结论和进一步阅读

这就是“一个唇同步专家是你在野外进行语音到唇生成所需要的一切”。如果您想阅读更深入的内容,或者关于我在这里没有谈到的一些事情:

  • 提议的度量/评估系统
  • Wav2Lip 和先前模型之间的基准比较
  • 作者使用的详细训练程序和超参数
  • Wav2Lip 的真实世界评估

你可以通过阅读报纸进一步调查:【https://arxiv.org/pdf/2008.10010v1.pdf

模型架构图片归功于的作者“一个唇同步专家是你在野外进行语音到唇生成所需要的一切”。

与 Python 相比,R 的优势何在

原文:https://towardsdatascience.com/ways-r-still-excels-compared-to-python-34835e6071ee?source=collection_archive---------24-----------------------

虽然 Python 和 R 曾经是数据科学的两大主流语言,但前者已经让后者黯然失色了一段时间。然而,R 似乎正在强势回归。

当查看 R 的 TIOBE 指数时,我们可以看到,在 2018 年 1 月达到收视率峰值后,该语言在该点后出现了明显的下降。然而,很明显,自 3 月份以来,收视率一直在回升。

资料来源:www.tiobe.com

这是什么原因呢?

其中一个重要原因是新冠肺炎激发了人们对统计学的强烈兴趣。

到目前为止,数据科学领域一直在回避这个领域,而倾向于更“性感”的话题,如自然语言处理、计算机视觉等。

然而,正在进行的疫情重新点燃了围绕统计分析在分析和最终抗击这种病毒中必须发挥的作用的辩论。

鉴于比较不同国家之间的统计数据的性质,人们对对数图表及其在比较不同尺度的数据时的用途特别感兴趣,如下文所示:

资料来源:twitter.com

因此,显而易见的是,如果想要快速进行有效的统计分析,就需要一个直观的统计环境来运行这些数字。证据表明 R 在这里仍然占优势。

然而,在我同时使用 Python 和 R 的经历中,以下是我关于后者如何仍然优于前者的经历。

1.在分析时间序列数据时,r 仍然可以胜过 Python

如果你以前做过时间序列分析,你很可能熟悉所谓的 ARIMA(自回归综合移动平均)模型

这是一种可用于根据时间序列的结构进行预测的模型。ARIMA 模型由坐标(p,d,q)组成:

  • p 代表自回归项的数量,即用于预测未来值的过去时间值的观测值的数量。例如,如果 p 的值是 2,那么这意味着序列中的两个先前的时间观察被用于预测未来趋势。
  • d 表示使时间序列稳定所需的差异数(即具有恒定均值、方差和自相关的时间序列)。例如,如果 d = 1,则意味着必须获得级数的一阶差分,才能将其转换为平稳的级数。
  • q 代表我们模型中之前预测误差的移动平均值,或者误差项的滞后值。例如,如果 q 的值为 1,那么这意味着我们在模型中有一个误差项的滞后值。

然而,R 和 Python 都允许基于最佳拟合自动选择这些坐标。这可以使用 R 中的 auto.arima 和 Python 中的金字塔来完成。金字塔中的 auto_arima 函数基于原始的 R 函数,即 R 是第一种能够自动选择 p,d,q 坐标的语言。

在另一篇文章(可从下面的参考资料部分获得)中,我比较了 R 和 Python 使用该函数预测天气数据的能力——R 显示出做出准确预测的能力明显更强,相对于实际情况,百分比误差低于 10%的预测数量超过了 70% 。在 Python 的例子中, 40% 的预测与实际相差在 10%以内。

资料来源:RStudio

2.回归分析

说到回归分析,与 Python 相比,R 可以使用更少的代码行来运行分析。

我们举个例子。假设我们正在运行一个回归来预测基于各种因素的股票回报,例如公司股息、收益和债转股。

现在,假设我们希望测试多重共线性,即测试是否有任何独立变量彼此显著相关,从而导致结果偏斜。回归( reg1 )运行如下。

现在,我们需要计算方差膨胀因子。计算方法如下:

然而,我们不需要在 r 中手动计算。相反,使用 car 库,VIF 函数可以如下调用:

VIF 统计数据远低于常用的阈值 510 ,这表明模型中不存在多重共线性

然而,使用 Python 的过程稍微复杂一些。

使用 sklearn 时,我们分别获取每个变量的 VIF。例如,让我们试着找出股息变量的 VIF 值。

在上述示例中,必须首先手动计算 R 平方统计量,然后只计算一个变量的 VIF 统计量:

我们已经获得了这一变量的 VIF,但还需要采取更多的步骤才能获得。此外,为了找到其他两个变量的 VIF 值,必须对每个变量重复这一过程。

从这个角度来看,在快速生成统计洞察时,R 仍然可以证明更加直观。

3.闪亮的直观统计分析

Python 中的 pyplotseaborn 等库在生成统计图方面已经变得相当流行。

然而,R 快速生成统计洞察的能力,加上闪亮的交互可视化能力,构成了一个强大的组合。

这是一个在 Shiny 中生成的累积二项式概率图的示例,通过它可以操纵左边的滑块(个体概率),以计算某一事件在指定次数的试验中发生的累积概率。

资料来源:RStudio

对于那些可能不擅长编写代码,但正在寻找一种有效的方法来操作统计数据和快速生成见解的人来说,这样的工具具有巨大的价值。此外,Shiny 本身就是一个非常直观的 R 包,并不难学!

这个闪亮的网络应用程序可以在下面的 GitHub 库中获得。

要操作该应用程序,只需:

  1. 下载存储库
  2. 点击 shiny web app 文件夹,打开 ui。R服务器。RStudio 中的 R 文件。
  3. 完成后,只需选择“运行应用程序”按钮,上面的应用程序将会显示:

资料来源:RStudio

结论

Python 擅长机器学习,在通用编程方面将继续主导 R。从技术上讲,R 不是一种编程语言——它是一种统计环境。

然而,统计学作为一个领域已经存在——因此 r 也是。

免责声明:本文是在“原样”的基础上编写的,没有任何担保。本文旨在提供数据科学概念的概述,不应以任何方式解释为专业建议。

参考

评估回归模型的方法

原文:https://towardsdatascience.com/ways-to-evaluate-regression-models-77a3ff45ba70?source=collection_archive---------0-----------------------

评估模型最简单的方法是考虑 R 平方值。假设我得到 95%的 R 平方,这样够好了吗?通过这个博客,让我们试着了解评估你的回归模型的方法。

图片来源:Shravankumar Hiregoudar

评估指标;

  1. 预测的平均值/中值
  2. 预测的标准偏差
  3. 预测范围
  4. 决定系数(R2)
  5. 相对标准偏差/变异系数(RSD)
  6. 相对平方误差
  7. 平均绝对误差
  8. 相对绝对误差(RAE)
  9. 均方误差
  10. 预测均方根误差(RMSE/RMSEP)
  11. 归一化均方根误差(范数 RMSEP)
  12. 相对均方根误差

让我们考虑一个预测片剂中活性药物成分(API)浓度的例子。使用近红外光谱的吸光度单位,我们预测片剂中的 API 水平。片剂中的 API 浓度可以是 0.0、0.1、0.3、0.5、1.0、1.5、2.0、2.5、3.0。我们应用偏最小二乘法(PLS)和支持向量回归机(SVR)来预测 API 水平。

注意:指标可用于比较多个模型或一个模型与不同的模型

预测的平均值/中值

我们可以使用预测值的算术平均值来了解两个模型之间的预测偏差。

例如,API 为 0.5 的预测值的平均值是通过将 API 为 0.5 的预测值的总和除以 API 为 0.5 的样本总数来计算的。

np.mean(predictedArray)

在图 1 中,我们可以理解 PLS 和 SVR 如何执行 wrt 均值。SVR 比 PLS 更好地预测 0.0 API,而 PLS 比 SVR 更好地预测 3.0 API。我们可以根据对 API 级别的兴趣来选择模型。

缺点:均值受离群值影响。当预测值中有异常值时使用中位数

图 1 .比较两种模型预测值的平均值

预测的标准偏差

标准差(SD)是一组值的变化量或离差的度量。较低的标准差表示这些值倾向于接近集合的平均值(也称为期望值)。相反,高标准偏差表明这些值分布在更大的范围内。预测值的标准差有助于理解不同模型中值的离差。

标准差公式

np.std(predictedArray)

在图 2 中,SVR 中预测值的离差小于 PLS。因此,当我们考虑 SD 度量时,SVR 表现得更好。

图 1 .比较两种模型预测值的标准偏差

预测范围

预测的范围是预测值中的最大值和最小值。偶数范围有助于我们理解模型之间的离散度。

决定系数(R2)

r 平方(R2)是一种统计测量方法,表示由回归模型中的一个或多个自变量解释的因变量方差的比例。相关性解释了自变量和因变量之间的关系强度,而 R 平方解释了一个变量的方差在多大程度上解释了第二个变量的方差。因此,如果模型的 R2 是 0.50,那么大约一半的观察到的变化可以用模型的输入来解释。

r 平方公式

r(相关性)(资料来源:http://www.mathsisfun.com/data/correlation.html

from sklearn.metrics import r2_score
r2_score(Actual, Predicted)

缺点:R2 不考虑过度合身。 了解更多详情

相对标准偏差(RSD) /变异系数(CV)

有一种说法是,苹果不应该与桔子相比较,或者换句话说,不要比较实际上不可比较的两个或一组项目。但是,如果这两个项目或组别以某种方式标准化或放在同一尺度上,缺乏可比性是可以克服的。例如,当比较总体上非常不同的两组的方差时,例如蓝鳍金枪鱼和蓝鲸的大小的方差,变异系数(CV)是选择的方法:CV 简单地表示通过其组均值标准化的每个组的方差

变异系数(CV),也称为相对标准偏差(RSD),是概率分布或频率分布离差的标准化度量。它有助于我们理解两个不同测试中的数据是如何分布的

标准差是单个数据集可变性的最常见度量。但是为什么我们还需要另一个度量,比如变异系数?嗯,比较两个不同数据集的标准差是没有意义的,但是比较变异系数是有意义的。

变异系数公式

from scipy.stats import variation
variation(data)

例如,如果我们考虑两个不同的数据;

数据 1:平均值 1 = 120000 : SD1 = 2000

数据 2:均值 2 = 900000 : SD2 = 10000

让我们计算两个数据集的 CV

CV1 = SD1/平均值 1 = 1.6%

CV2 = SD2/均值 2 = 1.1%

我们可以得出结论,数据 1 比数据 2 更分散

相对平方误差

相对平方误差(RSE)是相对于使用简单预测器时的误差而言的。更具体地说,这个简单的预测值只是实际值的平均值。因此,相对平方误差采用总平方误差,并通过除以简单预测值的总平方误差对其进行归一化。可以在误差以不同单位测量的模型之间进行比较。

在数学上,单个模型 i 的相对平方误差 Ei 由以下等式评估:

相对平方误差公式

其中 P ( ij )是单个模型 i 对记录 j (来自 n 条记录)的预测值; Tj 是记录 j 的目标值, Tbar 由公式给出:

对于完美的拟合,分子等于 0 并且 Ei = 0。因此, Ei 指数的范围从 0 到无穷大,0 对应于理想值。

平均绝对误差

在统计学中,平均绝对误差(MAE)是表达同一现象的成对观察值之间误差的度量。 YX 的例子包括预测与观察、后续时间与初始时间的比较,以及一种测量技术与另一种测量技术的比较。它与原始数据具有相同的单位,并且它只能在以相同单位测量误差的模型之间进行比较。它的震级通常与 RMSE 相似,但略小一些。MAE 的计算公式为:

平均绝对误差公式

from sklearn.metrics import mean_absolute_error
mean_absolute_error(actual, predicted)

因此,它是绝对误差的算术平均值,其中 yi 是预测值,是实际值。注意,替代公式可以包括相对频率作为权重因子。平均绝对误差使用与被测数据相同的标度。这被称为依赖于尺度的精度度量,因此不能用于在使用不同尺度的系列之间进行比较。

注意:如你所见,所有的统计数据都是将真实值与估计值进行比较,但方式略有不同。它们都告诉你,你的估计值与真实值“有多远”。有时使用平方根,偶尔使用绝对值——这是因为使用平方根时,极值对结果的影响更大(参见 为什么在标准差中求差的平方而不是取绝对值? math overflow)。

在《梅和 RMSE》中,你只需查看这两个值之间的“平均差异”。因此,您将它们与您的变量规模进行比较(即,1 点的 MSE 是预测值与实际值之间 1 点的差异)。

在 RAE 和相对 RSE 中,您将这些差异除以实际值的变化,因此它们的范围从 0 到 1,如果您将该值乘以 100,您将获得 0-100 范围内的相似性(即百分比)。

∑(MeanofActual—actual)或∑|MeanofActual — actual|的值告诉您实际值与其平均值相差多少——因此您可以知道实际值与其自身相差多少(比较 方差 )。正因为如此,这些度量被命名为“相对的”——它们给出与实际规模相关的结果。

相对绝对误差(RAE)

相对绝对误差(RAE)是一种衡量预测模型性能的方法。不要将 RAE 与相对误差相混淆,相对误差是钟表、尺子或天平等仪器的精度或准确度的一般度量。它表示为一个比率,将平均误差(残差)与平凡或简单模型产生的误差进行比较。一个好的预测模型会产生一个接近于零的比率;一个差的模型(比简单模型更差的模型)会产生一个大于 1 的比率。

它与相对平方误差非常相似,因为它也与简单的预测值相关,而简单的预测值只是实际值的平均值。不过,在这种情况下,误差只是总绝对误差,而不是总平方误差。因此,相对绝对误差采用总绝对误差,并通过除以简单预测器的总绝对误差对其进行归一化。

在数学上,单个模型 i 的相对绝对误差 Ei 由以下等式评估:

相对绝对误差(RAE)公式

其中 P ( ij )是单个模型 i 对记录 j (来自 n 条记录)的预测值; Tj 是记录 j 的目标值, Tbar 由公式给出:

对于完美的拟合,分子等于 0 并且 Ei = 0。因此, Ei 指数的范围从 0 到无穷大,0 对应于理想值。

均方误差

估计量的均方误差(MSE)或均方偏差(MSD )(用于估计未观察到的量的过程)测量误差平方的平均值,即估计值和实际值之间的平均平方差。MSE 是一个风险函数,对应于平方误差损失的期望值。MSE 几乎总是严格为正(且不为零)的事实是因为随机性或者因为估计器没有考虑可以产生更精确估计的信息。

MSE 评估预测值(即,将任意输入映射到某个随机变量的样本值的函数)或估计值(即,将数据样本映射到从中采样数据的总体参数估计值的数学函数)的质量。根据描述的是预测值还是估计值,MSE 的定义是不同的。

MSE 是对估计量质量的一种度量,它总是非负的,值越接近零越好。

均方差(MSE)公式

from sklearn.metrics import mean_squared_error
mean_squared_error(actual, predicted)

我们来分析一下这个等式实际上是什么意思。

  • 在数学中,看起来像怪异 E 的字符被称为求和(希腊文 sigma)。它是一系列数字的总和,从 i=1 到 n。让我们把它想象成一个点的数组,我们遍历所有的点,从第一个(i=1)到最后一个(i=n)。
  • 对于每个点,我们取该点的 y 坐标和 y '-坐标。我们从 y '坐标值中减去 y 坐标值,并计算结果的平方。
  • 第三部分是取所有(y-y’)值之和,除以 n,这将给出平均值。

我们的目标是最小化这个平均值,这将为我们提供通过所有点的最佳直线。了解更多信息

预测均方根误差(RMSE / RMSEP)

在统计建模尤其是回归分析中,测量模型拟合质量的一种常用方法是 RMSE(也称为均方根偏差),由下式给出

RMSE 公式

from sklearn.metrics import mean_squared_error
mse = mean_squared_error(actual, predicted)
rmse = sqrt(mse)

其中,yi 是 y 的第 I 个观测值,是给定模型的预测 y 值。如果预测响应非常接近真实响应,RMSE 将会很小。如果预测的和真实的响应相差很大(至少对于某些观测来说), RMSE 将会很大。零值表示与数据完全吻合。由于 RMSE 是在与 y 相同的比例和单位下测量的,因此可以预计 68%的 y 值在 1 RMSE 以内-假设数据呈正态分布。

注:RMSE 关注的是与真实值的偏差,而 S 关注的是与平均值的偏差。

所以计算 MSE 有助于比较基于相同 y 观测值的不同模型。但是如果

  1. 人们想要比较不同响应变量的模型拟合?
  2. 响应变量 y 在某些模型中被修改,例如标准化或 sqrt-或 log-transformed?
  3. 并且将数据分成训练和测试数据集(在修改之后)以及基于测试数据的 RMSE 计算对点 1 有影响吗?第二。?

前两点是比较生态指标性能时的典型问题,而后者,即所谓的验证集方法,在统计和机器学习中非常常见。克服这些障碍的一个解决方案是计算归一化 RMSE。

归一化均方根误差(范数 RMSEP)

归一化 RMSE 有助于不同比例的数据集或模型之间的比较。然而,你会在文献中发现各种不同的 RMSE 归一化方法:

您可以通过以下方式进行标准化

如果响应变量很少有极值,选择四分位范围是一个好的选择,因为它对异常值不太敏感。

RRMSEP 标准差称为相对均方根误差

1/RRMSEP 也是一个度量。大于 2 的值被认为是好的。

还有一些主要用于化学计量学的术语,如预测的标准误差(SEP)和预测的标准误差与标准偏差之比(RPD)。

我希望这篇博客能帮助你理解评估你的回归模型的不同标准。我使用了多种资源来理解和撰写这篇文章。谢谢你的时间。

参考文献:

)(我)(们)(都)(不)(知)(道)(,)(我)(们)(还)(不)(知)(道)(,)(我)(们)(还)(不)(知)(道)(,)(我)(们)(还)(不)(知)(道)(,)(我)(们)(还)(不)(知)(道)(,)(我)(们)(还)(不)(知)(道)(,)(我)(们)(还)(不)(知)(道)(,)(我)(们)(们)(还)(不)(知)(道)(,)(我)(们)(们)(还)(不)(知)(道)(。

用实现处理分类数据的方法

原文:https://towardsdatascience.com/ways-to-handle-categorical-data-before-train-ml-models-with-implementation-ffc213dc84ec?source=collection_archive---------5-----------------------

使用 Python 实现了流行的技术

在我的上一篇博客中,我解释了类型的缺失值以及处理连续分类缺失值的不同方法和实现。

处理完数据集中的缺失值后,下一步是处理分类数据。在这篇博客中,我将解释处理分类特征/列的不同方法以及使用 python 的实现。

图片作者:altum code|Unsplash.com

简介:所有的机器学习模型都是某种需要数字进行运算的数学模型。分类数据有可能的值(类别),它可以是文本形式。比如性别:男/女/其他,职级:1/2/3 等。

在处理完数据集的缺失值后,在从事数据科学项目时。下一步工作是在应用任何 ML 模型之前处理数据集中的分类数据。

首先,让我们了解分类数据的类型:

  1. 标称数据:标称数据称为 标注/命名为 数据。允许改变类别的顺序,顺序的改变不影响它的值。比如性别(男/女/其他)、年龄组(年轻/成年/年老)等。
  2. 序数数据:离散地表示 ,有序地表示单位 。与名义数据相同,但有顺序/等级。不允许改变类别的顺序。比如排名:第一/第二/第三,学历:(高中/本科/研究生/博士)等。

处理分类特征的方法:

用来解释的数据集是 Titanic ( Kaggle dataset ):

import pandas as pd
import numpy as np
Data = pd.read_csv("train.csv")
Data.isnull().sum()

数据类型-对象是数据集中的分类要素。

  1. 制造假人

描述: 为对象/类别类型特征中的每个类别创建虚拟或二进制类型列。如果该类别在每行中可用,则该行的值为 1,否则为 0。使用 pandas get_dummies()函数创建虚拟模型。

实现:

DataDummies = pd.get_dummies(Data)
DataDummies

示例:乘客类别创建 3 个新列。

优点:

  • 易于使用和快速的方法来处理分类列值。

劣势:

  • 当数据有许多分类列时,get_dummies 方法没有用。
  • 如果类别列有许多类别,会导致向数据集中添加许多要素。

因此,这种方法仅在数据的分类列较少且类别较少时有用。

2。序数编码

描述: 当分类变量为序数时,最简单的方法是根据秩用某个序数替换每个标签/类别。在我们的数据中,Pclass 是具有值第一、第二、第三的顺序特征,因此每个类别分别由它的等级,即 1、2、3 代替。

实现:

步骤 1:创建一个字典,以关键字作为类别,以值作为等级。

第 2 步:创建一个新列,并用创建的字典映射 ordinal 列。

第三步:删除原来的列。

# 1\. 
PClassDict =   {   'First':1,
                    'Second':2,
                     'Third':3,              
                }# 2\. 
Data['Ordinal_Pclass'] = Data.Pclass.map(PClassDict)# Display result

      Data[['PassengerId', 'Pclass', 'Ordinal_Pclass']].head(10)# 3.Data = Data.drop('Pclass', axis = 1)

优点:

  • 处理数据集中序号要素的最简单方法。

缺点:

  • 不适用于数据集中的名义类型要素。

3。计数/频率编码

描述: 用类别在该列中出现频率/次数替换每个类别。

实现:

第一步。创建字典,以关键字作为类别名称,以类别计数作为值,即该类别在每个分类列中的频率。

第二步。创建一个新列,作为该类别的权重,并映射到相应的字典。

第三步。删除原始列。

# 1.Pclass_Dict = Data['Pclass'].value_counts()
Salutation_Dict = Data['Salutation'].value_counts()
Sex_Dict = Data['Sex'].value_counts()
Embarked_Dict = Data['Embarked'].value_counts()
Cabin_Serial_Dict = Data['Cabin_Serial'].value_counts()
Cabin_Dict = Data['Cabin'].value_counts()# 2.Data['Encoded_Pclass'] = Data['Pclass'].map(Pclass_Dict)
Data['Salutation_Dict'] = Data['Salutation'].map(Salutation_Dict)
Data['Sex_Dict'] = Data['Sex'].map(Sex_Dict)
Data['Embarked_Dict'] = Data['Embarked'].map(Embarked_Dict)
Data['Cabin_Serial_Dict'] = Data['Cabin_Serial'].map(Cabin_Serial_Dict)
Data['Cabin_Dict'] = Data['Cabin'].map(Cabin_Dict)# Display ResultData[['Pclass','Encoded_Pclass','Salutation','Salutation_Dict','Sex'       ,'Sex_Dict','Embarked','Embarked_Dict','Cabin_Serial','Cabin_Serial_Dict','Cabin','Cabin_Dict']].head(10)# 3\. 
Data = Data.drop(['Pclass','Salutation','Sex','Embarked','Cabin_Serial','Cabin'], axis = 1)

每个类别及其频率计数。

优点:

  • 向东实施。
  • 不增加任何额外的功能。

缺点:

  • 无法处理相同数量的类别,即向两个类别提供相同的值。

4。目标/导向编码

描述: 此处,列的类别已被替换为其相对于目标列的依赖连接概率排名。

实现: 显示我正在使用的关于幸存目标列的 Cabin 列的实现。相同的步骤适用于数据集中的任何顺序列。

第一步。用客舱名称的第一个字符替换原始客舱值。

第二步。基于目标列值计算每个类别的联合概率。

第三步。创建一个按连接概率升序排列索引的列表。

第四步。创建一个字典,其中键作为类别名,值作为联合概率排名。

第五步。创建一个新列,并使用字典联合概率排名映射客舱值。

第六步。删除原始客舱栏。

*# 1.*Data['Cabin'] = Data['Cabin'].astype(str).str[0]*# 2.*Data.groupby(['Cabin'])['Survived'].mean()*# 3.*Encoded_Lables = Data.groupby(['Cabin'])  ['Survived'].mean().sort_values().index*# 4.*Encoded_Lables_Ranks = { k:i for i, k in enumerate(Encoded_Lables, 0) }# 5.Data['Cabin_Encoded'] = Data['Cabin'].map(Encoded_Lables_Ranks)# 6.Data = Data.drop('Cabin', axis = 1)

具有相对于目标列的连接概率等级的客舱值。

优点:

  • 它不会影响数据量,即不会添加任何额外的功能。
  • 帮助机器学习模型更快地学习。

缺点:

  • 通常,均值或联合概率编码导致过拟合。
  • 因此,为了避免过度拟合,大多数时候需要交叉验证或其他方法。

5。平均编码

描述: 与目标/导向编码类似,唯一的区别是这里我们用目标列的平均值替换类别。在这里,我们还实现了与客舱和幸存目标列。

实现:

第一步。计算客舱列中每个类别相对于目标列(幸存)的平均值。

第二步。创建一个新列并替换为平均值,即使用其编码的平均值字典映射客舱列类别。

第三步。丢弃原始座舱立柱

# 1.Encoded_Mean_Dict = Data.groupby(['Cabin'])['Survived'].mean().to_dict()# 2.Data['Cabin_Mean_Encoded'] = Data['Cabin'].map(Encoded_Mean_Dict)# Display resultData[['Cabin','Cabin_Mean_Encoded']].head()# 3.Data = Data.drop('Cabin', axis = 1)

客舱类别及其相对于目标列的相应含义。

优点:

  • 捕获标签或类别中的信息,提供更多预测功能。
  • 在自变量和目标变量之间建立单调的关系。

缺点:

  • 可能会导致模型过拟合,为了克服这个问题,大多数时候使用交叉验证。

6。概率比编码

描述: 这里列的类别被替换为相对于目标变量的概率比。在这里,我使用船舱作为一个独立变量,其类别被替换为每个船舱中幸存人员与死亡人员的概率比。

实现:

第一步。用客舱名称的第一个字符替换原始客舱值。

第二步。找出在特定船舱中幸存的人的百分比(%),并存储到新的数据帧中。

第三步。在幸存概率数据框中创建一个新列,列出在特定船舱中死亡的概率。

第四步。在幸存概率数据框中再创建一个新列,即幸存概率与死亡概率之比。

第五步。创建一个带有概率比列的字典。

第六步。在数据中创建新列,并用其编码的概率比字典映射客舱列类别。

第七步。放下原来的座舱立柱。

#1\. Data['Cabin']  = Data['Cabin'].astype(str).str[0]# 2\. Probability_Survived = Data.groupby(['Cabin'])['Survived'].mean()
Probability_Survived = pd.DataFrame(Probability_Survived)# 3.Probability_Survived['Died'] = 1 - Probability_Survived['Survived']# 4.Probability_Survived['Prob_Ratio'] = Probability_Survived['Survived'] / Probability_Survived['Died']# 5.Encode_Prob_Ratio = Probability_Survived['Prob_Ratio'].to_dict()# 6.Data['Encode_Prob_Ratio'] = Data['Cabin'].map(Encode_Prob_Ratio)# Display resultData[['Cabin','Encode_Prob_Ratio']].head(10)# 7.Data = Data.drop('Cabin', axis = 1)

客舱类别及其相应的生存概率比。

优点:

  • 不增加任何额外的功能。
  • 捕捉标签或类别中的信息,从而创建更多预测功能。
  • 创建变量和目标之间的单调关系。所以它适用于线性模型。

缺点:

  • 分母为 0 时未定义。
  • 与上述两种方法相同,会导致过度拟合,为了避免和验证,通常会进行交叉验证。

结论:

因此,在这篇博客中,我试图解释在为机器学习准备数据时处理分类变量的最广泛使用的方法。实际代码笔记本可从https://github . com/GDhasade/medium . com _ Contents/blob/master/Handle _ categorial _ data . ipynb获得

欲了解更多信息,请访问http://contrib . sci kit-learn . org/category _ encoders/index . html

参考资料:

  1. Scikit-learn.org(2019)。sk learn . preprocessing . onehotencoder—scikit-learn 0.22 文档。[在线]可从以下网址获得:https://sci kit-learn . org/stable/modules/generated/sk learn . preprocessing . onehotencoder . html
  2. ‌contrib.scikit-learn.org(未标明)。类别编码器——类别编码器 2.2.2 文件。[在线]见:http://contrib . sci kit-learn . org/category _ encoders/index . html
  3. 克里斯·纳伊克(2019)。特征工程-如何对多分类变量进行一次热编码。YouTube 。可在:https://www.youtube.com/watch?v=6WDFfaYtN6s&list = plzotaelrmxvpwyge 2 pxd 3 x 0 bfknr0cjn&ab _ channel = KrishNaik【2020 年 9 月 10 日获取】。

你可以在家免费自学机器学习的方法!!

原文:https://towardsdatascience.com/ways-you-can-teach-yourself-machine-learning-for-free-at-home-851f79a87d5d?source=collection_archive---------35-----------------------

Unsplash 上的位云拍摄的照片

大约一年前,在我读完佩德罗·多明戈斯的书《大师算法》后,我立即开始了我的机器学习之旅。这本书深刻地激励我成为当前机器学习/深度学习革命的一部分。所以我决定在每天的时间表中抽出几个小时来学习机器学习。在将近一年的时间里,我学到了很多东西,我非常感谢互联网上慷慨的资源使这一切成为可能。

今天,我想分享这些免费资源,以及你可以使用它们的方法,以便进入你的机器学习之旅。你所需要的只是一个互联网连接,基本的编程技能(Python),一台电脑和足够的动力。开始…
注意:‘’表示推荐完成*

  1. fast.ai*:

Fast.ai 是杰瑞米·霍华德和他的团队的一个项目,旨在让每个人都可以使用深度学习。这门课程很受初学者的欢迎。杰瑞米·霍华德教授机器学习的方法既直观又实用。在我的第一堂课上,我学会了如何建立一个图像分类器来对狗的品种进行分类。光是这种动力就足以让我坚持到最后。fast.ai 库功能强大,由 Kaggle、Google 云平台、Amazon Web Services、Paperspace 和其他几个平台支持。他们最近推出了 fast.ai 第二版,更灵活、更快、对初学者更友好。一定要去看看他们的深度学习课程。很神奇,而且绝对免费。

2.YouTube 上的讲座和视频教程:

YouTube 上有大量的机器学习课程。斯坦福大学、麻省理工学院、加州理工学院、保罗·g·艾伦学院……都提供优秀的课程。你甚至可以从课程网站上获得讲座幻灯片、作业* ( 良好实践)和解答。你可以从你的房间里获得世界级的教育。此外,你可以找到微积分、统计学、概率、线性代数等基础学科的课程,以及计算机视觉、强化学习、语音和自然语言处理等高级主题的课程。

你可以随时寻找教程来快速了解或回顾某个主题。以下是其中一些来源的列表:

a.杨安泽斯坦福的机器学习课程(新版) *
b. 保罗·g·艾伦学校的机器学习课程
c. 麻省理工学院开放课件-线性代数、概率统计、微积分等
d. 与乔希·斯塔默的 stat quest-机器学习的伟大教程
e. 两分钟论文-快速洞察
f.

我还会推荐听 Lex Fridman 的播客(在 YouTube 和 Spotify 上)和走向数据科学(在 Spotify 上),他们采访了机器学习和人工智能方面的专家。他们见解深刻,激励人心。

4。博客、文章

你可以在网上找到几乎所有机器学习主题的精彩文章。您可以找到几篇关于实现模型、特征工程、数学直觉、问题解决、ML 库等等的文章。以下是一些非常有用的网站列表:

3。

Kaggle 是一个很好的平台,在这里你可以练习你的机器学习技能。有成千上万的数据集可供你下载和实验。Kaggle 举办比赛,你可以测试你的机器学习技能,以解决真正的 ML 问题。我强烈建议浏览一下其他 Kagglers 的笔记本和讨论。你不需要理解笔记本上的每一个细节。无论你现在处于哪个阶段,你都会从他们身上学到新的东西。

4.免费计算****

机器学习是一个计算资源密集型过程。买一台像样的机器可能要花上几千美元。不是每个初学者都能负担得起,或者愿意做这样的投资。幸运的是,你可以从许多在线来源获得免费的云计算:
ka ggle
ka ggle 笔记本拥有足够的计算资源来完成大多数机器学习任务。最重要的是,Kaggle 每周为其用户提供高达 42 小时的 GPU 时间和 2 小时的 TPU 时间。这些是体面的特斯拉 K80 GPU可以加速你的大部分深度学习任务。不像这个列表中的其他选项,你不需要给出你的信用卡信息。你只需要一个电话号码来验证。你几乎可以立即将 Kaggle 上的数据集加载到你的笔记本文件夹中,大多数机器学习库,如 NumPy,Pandas,PyTorch,TensorFlow 都是预装的。

谷歌云平台(GCP)免费积分——一年时间限制 GCP 提供价值 300 美元的免费积分,从你注册之日起,你可以使用长达 1 年。你可以以每小时 1 美元的价格创造和使用一台像样的机器。加上 Kaggle 笔记本,这些学分应该够用一年了。我通常尽可能使用 Kaggle 笔记本,当 Kaggle 上的计算不够用时,我会求助于 GCP。

5。 机器学习论文

一旦你正确掌握了机器学习/深度学习的概念,你就可以逐渐开始阅读研究论文了。你可以在 arXiv.org 上找到大多数关于机器学习的研究论文。如果你不能掌握任何概念,你肯定会在上面列出的一些博客网站上找到简化的解释。尝试将论文中的想法应用到你自己的项目中,观察它们的表现。

考虑到互联网上的信息量,这篇文章并不完整。互联网提供的多样性可能会让初学者不知所措。通过这篇文章,我想通过列出我的个人选择来限制这种多样性。希望这有帮助。

祝你一路顺风,虽然艰难但令人欣慰😀!!!

我们不邪恶

原文:https://towardsdatascience.com/we-are-not-evil-4c294a1e743e?source=collection_archive---------53-----------------------

人工智能及其创造者正在让世界变得更好,而不是更糟。

我们不邪恶。(来源:作者)

人工智能是由全世界的程序员、数据科学家和数学家共同努力推动的。总的来说,这种特殊的全球亚文化(我自己也算在内)大多是乐观的,相信进步,并最终希望通过技术来改善世界。

关注这条新闻,你可能会看到一幅不同的艾和他背后的人的画面。当班卓琴的故事爆发时[1],我们了解到整个人工智能历史上的主要人物都是白人至上主义者[2]。自从 COMPAS 丑闻[3]以来,我们几乎在任何主要的人工智能系统中都读到了性别和种族偏见。就在几天前,IBM、亚马逊和谷歌绝望地拔掉了他们面部识别软件的插头[4-6],看不到其他方法来防止对少数民族的不公平待遇。更糟糕的是,统计学,所有现代机器学习和数据科学背后的数学学科,现在也被怀疑是种族主义的,因为它在很大程度上是由优生学家开发的[7,8]。

尽管统计学就像一般的科学一样,肯定充满了伦理污染(借用朗·霍华德的一个术语[9]),但它本身并不邪恶。我们也不是,来自世界各地的绝大多数热情的数据科学家和机器学习工程师,他们在我们做的一切事情中都依赖于统计数据。

不,统计数据不是问题,而是解决问题的关键。它是揭露任何地方的歧视和不公正的一个必要工具。只有通过系统的数据分析和统计,才能揭示当今公司和机构中普遍存在的不公平做法。统计使我们能够量化不公正,并监测我们是否在减少不公正方面取得进展。

ProPublica 是如何揭露 COMPAS 丑闻的?利用统计学和数据科学,从他们的代号可以看出。我们怎么知道 AI 研发存在多样性问题?通过观察——你猜对了——统计数据[10]。凯茜·奥尼尔怎么可能写出“数学毁灭武器”?利用她作为数学家和数据科学家的知识和经验。她是我们中真正关心的人之一。

问题不在于学习了你不道德行为的 AI。首先,问题是你的行为不道德!

的确,像 COMPAS 丑闻这样的事件表明 AI 做出了不道德的决定。但是,亲爱的公司和机构,问题不在于学习了你们不道德行为的 AI。首先,问题是你的行为不道德!

为了识别和纠正这一点,做了大量的工作。伦理人工智能已经成为一个活跃的研究领域,产生了新的工具、方法和最佳实践来实现数据透明和算法可解释性。是的,对一些公司和机构来说,可解释人工智能的时代将是不舒服的,因为随着透明度的增加,会有更多的审查。然而,最终还是别无选择。将通过统计的贡献来系统地发现、衡量和打击不平等现象。

而我们,你和我,将成为实现这一目标的人。

参考

[1] M. Stroud,监视公司 Banjo 的首席执行官曾经帮助三 k 党领导人枪杀了一个犹太教堂 (2020),OneZero

[2] S. Myers West, AI 和极右翼:一段我们不能忽视的历史 (2020)

[3]朱莉娅·安格温等著,机器偏见 (2016),ProPublica

[4] L. Hirsch, IBM 退出面部识别业务,呼吁国会推进解决种族不公正的政策 (2020),美国消费者新闻与商业频道

[5] A. Levy,微软表示,除非有一部以人权为基础的国家法律,否则不会向警方出售面部识别软件,(2020),美国消费者新闻与商业频道

[6] K. Weise 和 N. Singer,亚马逊暂停警方使用其面部识别软件,(2020 年),《纽约时报》

[7] K. Evans,统计学是种族主义的吗?

[8]d . cle ther,统计学是种族主义的吗?,(2020),启动

[9] S .拉哈,伦理污染

[10] K. Paul,《卫报》研究发现,人工智能行业多样性的“灾难性”缺乏延续了偏见 (2019)

(来源:作者)

我们创造了一个懒惰的人工智能

原文:https://towardsdatascience.com/we-created-a-lazy-ai-5cea59a2a749?source=collection_archive---------28-----------------------

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

丁薇Unsplash 上拍照

TLDR: 许多文章解释了强化学习(RL)的概念,但没有多少文章讨论如何在现实世界中实际设计和实现强化学习。在本文中,我将分享为纽约市实施 RL 解决方案的范式转变经验、一些见解和一个通用参考架构。

喜欢读什么? 跟我上 领英 ,或者 推特

:感谢亚历克斯·香农、阿邦库王子和布雷顿·阿纳博尔迪,他们是我在 NYU 的出色队友,是他们的贡献和成就了这一切。

但是,先喝一杯?

我以为你在一个派对上。你有点(或很)醉了。你自愿玩喝酒游戏来给一个(或多个)有魅力的熟人留下深刻印象。

来源

有人蒙住你的眼睛,给你一个玻璃杯和一瓶啤酒,喊:“开始倒!”

你会怎么做?

你大概有以下反应:sht,我该怎么办!?我怎么赢!?如果我输了会怎么样!?*

原来规则是这样的:你需要在 10 秒钟内把啤酒灌到尽可能接近杯子上的一个标记。可以倒啤酒进出。

欢迎来到我们的 RL 解决方案的头脑他面临着类似的任务,但为了一个更高尚和更有意义的目的。

现实世界中的啤酒问题

我们的环保自行车共享业务存在一个大问题。一整天,每个自行车站(玻璃杯)可以有太少或太多自行车(啤酒)。

纽约的缺货()和缺货()车站

这对骑自行车的人来说非常不方便,并且需要花费数百万美元来管理运营。不久前,我在 NYU 的团队受命提出一个人工智能解决方案,以最少的人工干预来帮助管理自行车库存。

目标:全天保持每个自行车站的库存在 1 到 50 之间(想想玻璃上的标记)。这在共享经济中被称为再平衡问题

约束:由于操作限制,团队在一天中的每个小时只能移动 1、3 或 10 辆自行车(你可以倒入或倒出的啤酒量)。当然,他们可以选择什么都不做。团队移动的自行车越多,价格就越贵。

我们的惰性 RL 解决方案

我们决定使用 RL ,因为它克服了传统方法的许多限制(例如基于规则和预测)。

如果您想了解 RL 是什么以及它的一些关键概念, Jonathan Hui 写了一篇非常好的简介Thomas Simonini 更详细地解释了 Q-Learning ,一种在我们的解决方案中使用的 RL 算法。

结果是,我们创造了一个非常懒惰的人工智能。当自行车库存超过 60 辆时,它通常会选择什么都不做或最小化(移动 1 或 3 辆自行车)。这似乎有悖常理,但却非常明智。

来源

根据人类的直觉,我们可能会移动尽可能多的自行车,使其保持在 50 辆以下,尤其是当加油站越来越满的时候。但是,RL 认识到移动自行车的成本(移动的自行车越多,成本越高)以及在某些情况下成功的机会。考虑到还剩多少时间,根本不可能实现目标。它知道最好的选择是“放弃”。所以,有时候放弃比继续尝试更好。

来源

有不同的方法来“轻推”人工智能以避免懒惰。这与我们如何设计奖励函数有关。我们将在下一篇文章中讨论这个问题,所以现在请继续阅读。

那又怎样?类似于谷歌 Alpha Go 著名的棋 37 和 78 ,当人工智能做出非常规决策时,它们挑战我们的偏见,帮助打破知识的诅咒,并将我们推向未知的道路。

创造人工智能既是一项发明,也是一次探索我们大脑内部运作的旅程。—戴密斯·哈萨比斯,DeepMind 创始人,经济学人上的 2020 年世界

但是,要谨慎。没有什么可以取代人类的价值体系,这样我们才不会掉下悬崖或迷路。

让我们现实一点

RL 如何管理自行车站?下图显示了自行车库存从第 0 小时到第 23 小时(有和没有 RL)的变化。

  • 蓝色是没有 RL 的自行车股的走势。
  • 黄色是一个天真的女孩。它只是不停地移走自行车。成本很高。
  • 格林和一个受过更好训练的女孩在一起。它移除刚好足够的自行车来满足目标。它更注重成本。

作者分析

RL 如何决定做什么?以下是我们的 RL 解决方案在 98,000 次训练后的 Q 表快照。它解释了给定一个站点(垂直)有多少辆自行车,我们的 RL 如何决定做什么(水平)。RL 不太可能选择做任何红色的事情。看看底部的红色区域。

作者分析

RL 能变得多聪明?以下是 RL 管理自行车站的情况。随着更多的学习,RL 能够将整体成功率逐渐提高到令人印象深刻的 98%。

作者分析

这看起来棒极了,我们的解决方案是如何工作的?这里是高层架构。对于大多数 RL 应用来说,这是一个通用的设计。每个 RL 解决方案需要有以下三个基本组件:训练循环、代理和环境。

作者的分析

训练循环:循环便于剧集的运行。每一集意味着一个事件的端到端过程(在这种情况下,它意味着一轮寻宝的开始和结束)。该程序可以运行数千集(或你想要的任何数量)来训练 RL 代理。

RL 代理:RL 代理有两个主要功能。 学习 允许智能体从每次与环境的交互中学习,并将学习带到新的一集。“大脑”有不同的设计。最简单的是通过使用 Q 学习。Alpha Go 使用深度神经网络。代理 基于学习和环境提供的情况选择动作

环境:这是给定应用的世界的表示。在我们的例子中,这是自行车在城市中行驶的方式。该环境基于代理的动作提供反馈。反馈包括奖励或惩罚以及环境的最新状态。我们稍后将更详细地讨论这一点。

下一步是什么

我希望你喜欢这篇文章,并且对 RL 在现实世界中的能力和潜力感到兴奋。取决于本文的表现,我们将在下一篇文章中深入研究设计、权衡,并进行详细的代码演练。

与此同时,如果你想了解更多关于开发 RL 的基础知识,请查看我的新 RL 教程 。我们将用大约 100 行代码制作一个有趣的寻宝程序,熟悉上面讨论的一般 RL 架构,并构建一个演示包。

喜欢读什么? 跟我上 LinkedIn,或者Twitter**

下次见。

伊恩

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

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

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

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

用 Streamlit 探索蒙特卡罗模拟

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

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

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

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

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

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

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

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

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

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

towardsdatascience.com](/fixing-the-last-mile-problems-of-deploying-ai-systems-in-the-real-world-4f1aab0ea10) [## ML 和敏捷注定的联姻

Udacity 的创始人巴斯蒂安·特龙毁了我的 ML 项目和婚礼

towardsdatascience.com](/a-doomed-marriage-of-ml-and-agile-b91b95b37e35)**

我们整个周末都在推特上追踪 COVID。这是你错过的。

原文:https://towardsdatascience.com/we-tracked-covid-on-twitter-all-weekend-heres-what-you-missed-e3203dc7f41c?source=collection_archive---------50-----------------------

由史蒂夫·赫登和大卫·波尔分别担任

为了进行这项分析,我们在整个周末(美国东部时间 7 月 24 日晚 7 点至 7 月 26 日中午)流式传输了所有与 COVID 相关的推文。我们从这些数据中提取了一个网络,使用个人 Twitter 账户作为节点,RTs 或提及作为链接。

下面演示了网络是如何创建的。@realDonaldTrump 和@jonvoigt 代表节点。既然@realDonaldTrump 转推了@jonvoigt,那两者之间就有联系了。

在过滤了网络中最有影响力的节点之后,我们创建了一个总结网络。

7 月 24 日—26 日周末 COVID 相关推特汇总网络。

图中的每个节点(气泡)代表一个 Twitter 用户,每个链接代表与另一个用户的连接。如果在时间间隔内的任何时间点,两个账户彼此交互或者与同一个中间账户紧密交互,则这两个账户是关联的。每个节点的大小对应于它们的度中心性——用户拥有的连接越多,它们的中心性越高。节点的颜色对应于它们的社区或组。当用户之间的互动多于他们社区之外的用户时,社区就形成了。

主要要点

从上面的视频可以看出,Twitter 上的 COVID 对话揭示了几个不同的社区。这些人在周末定期进行互动,无论是通过直接转发和提及,还是通过转发相同的推文或提及相同的用户。这些社区的详细信息(顶级影响者、关键词、总体情绪)将在下面详细解释,但是存在这样的独特社区本身就很重要。在网络分析术语中,我们可以说这是一个非常模块化的图,具有密集连接的节点的不同集群。用外行的话来说,我们有一群人,他们彼此之间有很多互动,但他们不经常与他们圈子之外的人互动。这可能是因为大多数人的 Twitter 订阅由他们关注的用户的推文主导,Twitter 建议他们关注其他类似的用户,这被称为“过滤泡沫”。

来自 Dictionary.comhttps://www.dictionary.com/browse/filter-bubble?s=t

由于语言和时区的差异,这些社区看起来也很独特。例如,有巨大的西班牙语社区,尤其是来自委内瑞拉的社区。在那个半球的白天,也有不同的印度和马来西亚社区出现和成长。

周末热门推文(截至 7 月 26 日周日晚的转发数)

  1. 来自@ alsoto_7,转发约 153,000 条

2.来自@ davenewworld_2,转发量约为 107,000 次

3.来自@ TristanTaylor88,转发量约为 66K

4.来自@ Theresa_Chappie,转发量约 51K

5.来自@ JoeBiden,转发量约为 32K

6.来自@ kylegriffin1,转发量约 20000 条

7.来自@ funder,转发量约为 1.6 万

8.来自@ jsolomonReports,转发量约为 16K

顶级群体

有几个不同的团体在这段时间内一直存在。以下是对群组的一些高级描述,包括顶级影响者(基于每个用户的程度中心性)、群组的关键词和总体情绪。使用自然语言处理(NLP)来计算关键词和情感。对于关键词,我们确定了该组所有推文中最常用的名词。这种情绪有好有坏。大多数推文相当负面(毕竟,我们在谈论一个全球性的疫情)。

第 1 组——美国医疗保健专业人员、记者和政治家

最有影响力的人

  1. 埃里克·费格丁博士(@德瑞克丁)
  2. CNN (@ CNN)
  3. 凯尔·格里芬(@ kylegriffin1)
  4. 安迪·斯拉维特(@阿斯拉维特)
  5. 丹尼尔·乌尔菲尔德(@ DWUhlfelderLaw)

关键词:佛罗里达州,川普,冠状病毒,得克萨斯州,美国

总体情绪: -0.21(负面)

这是迄今为止网络中最大的社区。顶级成员在整个周末都在变化,但美国科学家联合会高级研究员、流行病学家和健康经济学家 Eric Feigl-Ding 博士始终是最有影响力的人之一。他周末最热门的推文实际上是在周四下午发出的:

同样,CNN 也有一些重要的推文。周末转发量最大的一条也是在周四发出的:

凯尔·格里芬(Kyle Griffin)周五晚上在推特上警告说,辛克莱广播集团准备播放一部纪录片,声称福奇博士对冠状病毒负责:

格里芬的这条推文获得了如此多的关注,以至于他们推迟了这部纪录片的发布,这部纪录片本身就是我们网络中的一个重大事件:

安迪·斯拉维特在推特上讲述了疾控中心的衰落程度:

以及德州州长 Abbott 如何需要立即采取激烈的行动:

丹尼尔·乌尔菲尔德(Daniel Uhlfelder)报道称,阿肯色州参议员杰森·雷佩特(Jason Rapert)因 COVID:

上周末,该社区的其他顶级影响者包括斯蒂芬·金、卡玛拉·哈里斯、乔·斯卡伯勒、特里萨·查普尔博士、乔伊·里德和乔·拜登。

第二组——特朗普和他的朋友们

顶级影响者

  1. 唐纳德·特朗普(@ realDonaldTrump)
  2. 贾尼斯·迪恩(@ JaniceDean)
  3. 约翰·所罗门(@ jsolomonReports)
  4. 大卫·萨马迪博士(@ drdavidsamadi)
  5. 汤姆·菲顿(@汤姆菲顿)

关键词: CCP,佛罗里达州,美国,60 万美国,参议院

总体情绪: -0.27(负面)

特朗普周末的第一条推文是在周五晚上,当时他回应了斯科特拒绝内华达州一所教堂增加教堂容量的上诉的消息:

贾尼丝·迪恩宣传了她关于科莫“致命”养老院政策的文章:

约翰·所罗门宣传羟氯喹是“击败”病毒的关键:

大卫·萨马迪博士分享最多的推文比较了各国人均因 COVID 导致的死亡人数:

他还称新冠肺炎为“CCP 病毒”,大概是在中国***之后。术语“CPP”获得了足够的关注,它从 NLP 中脱颖而出,成为这个社区中所有推文中的顶级名词之一。

汤姆·菲顿也对罗伯茨法官不允许内华达教堂增加容量的决定表示反对:

下面,我们列出了我们定义的每个剩余社区的前 5 名影响者。

请记住,这些社区在不断变化。对于实时更新,我们建议您使用 covidtwitternetwork 亲自探索对话及其主要参与者。

第三组—国际新闻

顶级影响者

  1. 路透社(@路透社)
  2. 电晕更新机器人(@电晕更新机器人)
  3. 哥伦比亚广播公司新闻(@ CBSNews)
  4. 彭博(@商业)
  5. 小山(@ thehill)

第 4 组—委内瑞拉(查韦斯主义者)

顶级影响者

  1. VTV 运河 8 (@ VTVcanal8)
  2. 委内瑞拉统一社会党
  3. 大众通信和信息部(@ Mippcivzla)
  4. Con El Mazo Dando (@ ConElMazoDando)
  5. patria rebel de RR(@ ronel Rodriguez 6)

第 5 组—印度政治家、名人、医疗保健专业人士

顶级影响者

  1. shiv Raj Singh Chou Han(@ ChouhanShivraj)
  2. 阿尼(@阿尼)
  3. 索努·苏德(@ SonuSood)
  4. Kumar Vishvas 博士(@ DrKumarVishwas)
  5. 总部新闻(@ ABPNews)

第 6 组—英国

顶级影响者

  1. 莎拉·墨菲(@ 13 莎拉·墨菲)
  2. 德里克·詹姆斯(@ derekjames150)
  3. 戈登财富#FBPE (@戈登 _ 财富)
  4. 理查德·科比特(@ RichardGCorbett)
  5. 詹姆斯·梅尔维尔(@詹姆斯·梅尔维尔)

第 7 组——马来西亚

顶级影响者

  1. KKMPutrajaya (@ KKMPutrajaya)
  2. anep (@ hanifjamals)
  3. 哈里安地铁(@ hmetromy)
  4. 伯纳玛(@ bernamadotcom)
  5. 贝里塔·哈里安(@ bharianmy)

第八组—委内瑞拉(胡安·瓜伊德)

顶级影响者

  1. 胡安·瓜伊多(@ jguaido)
  2. 全国通讯中心
  3. 雨果·洛佩斯-盖特尔·拉米雷斯(@赫尔盖特尔)
  4. Reporte Ya (@ ReporteYa)
  5. 尼尔森·博卡兰达 S. (@尼尔森·博卡兰达)

第 9 组——厄瓜多尔

顶级影响者

  1. El Comercio (@ elcomerciocom)
  2. El Universo (@ eluniversocom)
  3. 厄瓜多尔人(@厄瓜多尔人)
  4. tele amazonas(@ tele amazonas sec)
  5. CNN en 西班牙语(@ CNNEE)

我们将继续使用 covidtwitternetwork 来分析 Twitter 上正在进行的与新冠肺炎有关的对话。该应用程序仍在开发中,因此我们欢迎任何评论或反馈。

感谢杰西卡·雷蒂格的反馈和支持:)

我们不会被机器取代

原文:https://towardsdatascience.com/we-will-not-be-replaced-by-machines-f1d1a8664c59?source=collection_archive---------45-----------------------

这个故事是关于合作而不是竞争

Unsplash尔汗·阿斯塔姆的照片

在以前的文章中,我们已经讨论了在不同研究领域工作的专家之间合作的重要性。现实世界中的问题往往不完全属于某个特定的研究领域——我们需要学会一起面对问题,不仅要分享我们所知道的,还要愿意倾听——仔细倾听他人的想法 。我们需要保持足够的开放,承认我们没有所有的答案,其他人可能有我们没有的知识和观点。

我想我们都同意,协作是一件好事,我们的综合思维大于其各个部分的总和。那么,当涉及到与人工智能合作时,我们为什么会觉得有必要采取不同的观点呢?

我们对他们

科学论文不断将他们的人工智能算法在解决某些特定问题时的性能与专家的性能进行比较。它被视为超越人类的战利品,即使只是狭义的。虽然这可能是一个有用的基准,将研究的成就和意义放入上下文中,但我认为它也不知不觉地建立了一种对立的关系。突然变成了竞争。我们对抗机器。

人类和他们的人工智能作品之间的竞争和最终冲突已经成功地抓住了我们社会的集体想象力。我们在文学和电影中戏剧化地表现了这个想法,产生了巨大的影响。这当然是发人深省的材料,并提出了许多非常好(也非常困难)的伦理问题,我们绝对应该尽早思考。

但硬币的另一面是,这种魅力也导致了一种广泛的观点,即人工智能在某种程度上反对我们。粗心的科学家盲目追求他们的研究进展,而牺牲了我们的其他生计。我们害怕有一天我们被机器人取代,而这正是我们花了大半辈子学习的事情。

很容易理解为什么这让我们如此恐惧。当我们觉得工作过度、报酬过低时,我们可能会抱怨,但我们内心深处还是有一部分喜欢工作。我们喜欢工作,也喜欢贡献。我们希望感受到他人的重视。我们从工作中获得自我价值。我们从工作中获得认同感。在许多方面,我们我们的工作。如果我们觉得我们的工作——以及我们的自我——受到了威胁,我们就会努力工作。我们变得有防御性。这是对我们所珍视的东西的攻击。

被算法淘汰的前景似乎意味着我们所做的不再有价值,这理所当然地让我们感到不安。然而,我们不应该让我们的想象力战胜我们。在我们决定必须不惜一切代价阻止人工智能研究的无情前进之前,让我们检查一下现实。

人为因素的情况

人类将永远保持机器所不具备的灵活性。诚然,在简单和重复的决策方面,我们远远胜过他人——但是人类学习、适应以及更普遍的对新奇事物做出适当反应的能力是无法用代码行复制的。在历史上,我们对未知事物的成功探索行为使我们人类比地球上任何其他生物都更强大、更成功。

在出现异常信息时,我们可以(只要我们愿意面对它)推导出它的含义,并将我们需要知道的信息整合到我们现有的决策过程中。虽然算法在某种意义上确实“学习”,但我们还远远没有开发出像通用智能那样可以模仿人类能力的东西。

本质上:在未来很长一段时间里,我们将与人工智能一起工作,而不是与之竞争。

我们的工作将因人工智能而得到加强。通过处理工作中枯燥、重复的部分,我们将能够把注意力集中在工作中更有趣、更重要、更有影响力的方面。每个人都有那些他们知道他们应该做的事情,那些我们知道如果我们做了会对我们和我们的组织有好处的重要但不紧急的任务,但我们似乎就是不能去做。我们会陷入所有不太重要但最终更紧迫的事情中。

想象一下,如果你组织中的每个人都只做重要的事情。为,像,连续一年。在那段时间里,事情会发生怎样的变化?流程的效率会提高多少?工作质量会提高多少?你的客户会有多开心呢?会有更多的事情要做。

或者也许人工智能确实在你工作的某个关键方面胜过你。下一个问题是:如果你和机器一起工作,你会取得什么成就?你们如何弥补对方的弱点?人工智能能帮助你处理特别模糊的情况吗?你能掩盖机器的故障模式吗?

选择不要害怕

重点是这个。替换可怕的问题:

“这项技术会取代我们吗?”

…带着协作问题:

“如果我们一起努力,我们能取得什么成就?”

不是机器人对人类。是机器人和人类对抗问题。重大而令人挠头的问题。

我们越早开始这样思考——从与人工智能合作而不是对抗的角度来看——我们就能越快实现目标。

学分和更多信息

Andrew Hetherington 是英国伦敦的一名见习精算师和数据爱好者。

  • 在我的网站上查看我的更多作品。
  • LinkedIn 上与我联系。
  • 看看我在 GitHub 上摆弄什么。

尔汗阿斯塔姆Unsplash 上拍照。

弱自我监督学习—第一部分

原文:https://towardsdatascience.com/weakly-and-self-supervised-learning-part-1-8d29fce2dd92?source=collection_archive---------15-----------------------

FAU 讲座笔记关于深度学习

从类到像素

FAU 大学的深度学习。下图 CC BY 4.0 来自深度学习讲座

这些是 FAU 的 YouTube 讲座 深度学习 的讲义。这是与幻灯片匹配的讲座视频&的完整抄本。我们希望,你喜欢这个视频一样多。当然,这份抄本是用深度学习技术在很大程度上自动创建的,只进行了少量的手动修改。 自己试试吧!如果您发现错误,请告诉我们!

航行

上一讲 / 观看本视频 / 顶级 / 下一讲

弱监督训练也可以利用非常粗糙的注释。使用 gifify 创建的图像。来源: YouTube

欢迎回到深度学习!所以,今天我想和你们谈谈几个高级的话题,特别是研究稀疏标注。我们知道数据质量和注释是极其昂贵的。在接下来的几个视频中,我们想谈谈如何保存注释的一些想法。主题是弱监督学习和自我监督学习。

监督训练的标签似乎很多。 CC 下的图片来自深度学习讲座的 4.0 。

好吧。那么,让我们看一下幻灯片,看看我为你准备了什么。题目是弱自监督学习。我们今天从有限的注释和一些定义开始。稍后,我们将研究代表学习的自我监督学习。那么,用有限的注解学习有什么问题呢?目前为止。我们有监督学习,我们已经看到这些令人印象深刻的结果是通过大量的训练数据和一致的高质量注释实现的。这里,你可以看到一个例子。我们有基于实例的分段的注释,并且我们简单地假设所有这些注释都在那里。我们可以使用它们,甚至可以公开获得。所以,没什么大不了的。但实际上,在大多数情况下,这是不正确的。

其实标注很贵的。来自深度学习讲座CC BY 4.0 下的图片。

通常,您必须进行注释,而注释是非常昂贵的。如果查看图像级别的分类标签,每个样本大约需要 20 秒。这里,你可以看到一只狗的图像。也有想法,我们试图让它更快。例如你在[11]中看到的例子。如果你接着去实例分割,你实际上必须画出轮廓,这是你必须在这里花费的每个注解至少 80 秒。如果您继续进行密集像素级注释,您可以轻松地花费一个半小时来注释这样的图像。你可以在[4]中看到。

监管不力试图充分利用你的标签。 CC 下的图片来自深度学习讲座的 4.0 。

现在,弱监督学习和强监督学习的区别,你可以在这个图表中看到。这里你看到如果我们有图像标签,当然可以对图像标签进行分类,进行训练。这基本上是监督学习:训练边界框以预测边界框,训练像素标签以预测像素标签。当然,您也可以从像素级标签抽象到边界框,或者从边界框抽象到图像标签。那都将是强有力的监督。现在,弱监督学习的想法是,你从图像标签开始,然后去包围盒,或者你从包围盒开始,然后尝试预测像素标签。

弱标签的例子。 CC 下的图片来自深度学习讲座的 4.0 。

这是弱监督学习的核心思想。不知何故,您希望使用稀疏注释,然后创建更强大的预测器。弱监督学习的关键要素是使用先验知识。你使用关于形状、大小和对比度的显性和隐性先验。此外,运动可以用来,例如,移动边界框。类别分布告诉我们,有些类别比其他类别更频繁。此外,图像间的相似性也有帮助。当然,您也可以使用像图像标签、边界框和图像标题这样的提示作为弱监督标签。稀疏时态标签随时间传播。对象内部的涂鸦或点击也是合适的。这里有几个关于涂鸦和点击的稀疏注释的例子。

从标签到本地化的第一种方法。来自深度学习讲座CC BY 4.0 下的图片。

有一些通用的方法。从标签到本地化的一个方法是使用预先训练好的分类网络。然后,举例来说,你可以使用一些技巧,就像在视觉化的讲座中一样。你就产生了一个定性的分割图。所以在这里,我们有这样一个想法,将类标签反向传播到图像域中,以产生这样的标签。现在,问题是这个分类器从来没有被训练用于局部决策。第二个问题是好的分类器不会自动产生好的地图。所以,让我们看看另一个想法。这里的关键思想是使用全球平均池。因此,让我们重新思考一下全卷积网络以及我们一直在做的事情。

全卷积处理概述。 CC 下的图片来自深度学习讲座的 4.0 。

你记得我们可以用 M 乘以 N 的卷积来替换只有固定输入大小的完全连接的层。如果你这样做,我们会看到,如果我们有一些输入图像,我们与张量卷积,那么本质上我们得到一个输出。现在,如果我们有多个张量,那么我们就有多个通道。如果我们现在开始跨图像域移动卷积掩模,可以看到,如果输入图像更大,输出也会相对于输出域增长。我们已经看到,为了解决这个问题,我们可以使用全局平均池方法来为每个实例生成类标签。

让我们重新排序汇集和分类。来自深度学习讲座CC BY 4.0 下的图片。

现在,你可以做的另一个选择是,你首先汇集到正确的大小。比方说,这是您的输入,然后您首先汇集,这样您就可以应用您的分类网络。然后,转到全连接层中的类。因此,您实际上交换了全连接层和全局平均池的顺序。你先全局平均池,然后产生类。我们现在可以使用它来生成一些标签。

对于类激活图,我们在倒数第二层汇集以获得像素级的类标签。 CC 下的图片来自深度学习讲座的 4.0 。

这个想法是,现在我们看看倒数第二层,我们产生类激活图。所以,你可以看到我们有两个完全连接的层来产生类预测。我们基本上有输入特征地图,我们可以放大到原始图像大小。然后,我们使用分配给倒数第二层输出的权重,相应地缩放它们,然后为每个输出神经元生成一个类激活图。您可以在底部看到这种情况,顺便提一下,还有一种概括,即 Grad-CAM,您可以在[12]中查看。因此,有了这个,我们可以生成类激活映射,并将其用作本地化的标签。

GradCAM 可视化示例。使用 gifify 创建的图像。来源: YouTube

我们也可以从包围盒到分割。这里的想法是,我们希望用边界框取代昂贵的注释、完全监督的训练,因为它们不那么单调乏味。

我们能从包围盒到像素标签吗?来自深度学习讲座CC BY 4.0 下的图片。

它们可以更快地被注释,当然,这会降低成本。现在的问题是,我们能使用那些廉价的标注和弱监督来产生好的分割吗?实际上有一篇论文研究了这个想法。

自举训练程序怎么样? CC 下的图片来自深度学习讲座的 4.0 。

你可以在[6]中看到。关键的想法是你从输入矩形开始。然后,你对卷积神经网络进行一轮训练。您可以看到,卷积神经网络对标签噪声有一定的鲁棒性,因此,如果您重复该过程,并在迭代过程中优化标签,您可以看到,每一轮训练和优化标签都会获得更好的预测。所以在右手边,你可以看到地面真相,以及我们如何逐渐接近它。现在,实际上有一个问题,因为训练很快就会退化。唯一能让它实际工作的方法是在中间预测中使用后处理。

对于迭代训练,你需要使用一些技巧。 CC 下的图片来自深度学习讲座的 4.0 。

他们使用的想法是他们抑制例如错误的检测。因为你有边界框,所以你可以确定在这个边界框中,它不可能有一个非常不同的类。然后,您还可以删除边界框之外的所有预测。它们可能不准确。此外,您还可以检查它是否小于盒子面积的某个百分比,这可能也不是一个准确的标签。此外,您可以使用条件随机字段边界的外部。我们本质上运行一种传统的分割方法,使用边缘信息来细化边界。您可以使用它,因为没有信息来完善您的标签。如果您使用较小的盒子,还可以做进一步的改进。平均来说,物体是有点圆的,因此角和边包含最少的真阳性。这是一些图像的例子,然后你可以定义带有未知标签的区域。

这些技巧有助于提高性能。不需要训练的传统分割方法消除了迭代的需要。来自深度学习讲座CC BY 4.0 下的图片。

以下是一些结果。你可以看到,如果我们不对标签进行任何细化,只是一遍又一遍地训练网络,那么你最终会出现在这条红线中。在训练轮数的天真方法中,你实际上降低了分类的准确性。所以网络退化了,标签也退化了。这不起作用,但如果你使用的技巧与细化的标签与框和排除离群值,你真的可以看到两条绿色曲线出现。经过一轮又一轮的迭代,你实际上在进步。老实说,如果你只是使用 GrabCut+,那么你可以看到,仅仅一轮迭代就已经比应用程序的多次重新运行要好。如果你将 GrabCut+与所谓的 MCG 算法(多尺度组合分组)结合起来,你甚至可以在一轮训练中获得更好的结果。因此,使用启发式方法也有助于将标签从包围盒改进为像素标签。如果你看看这个,完全监督的方法仍然更好。做完整的注释仍然是有意义的,但是如果我们使用这些弱监督的方法之一,我们已经可以在性能方面非常接近了。这确实取决于您的目标应用程序。如果你已经接受了联合中 65%的平均交集,那么你可能会对弱监督方法感到满意。当然,这比生成非常昂贵的基本事实注释要便宜得多。

在这个深度学习讲座中,更多令人兴奋的事情即将到来。 CC 下的图片来自深度学习讲座的 4.0 。

所以下一次,我们想继续讨论我们的弱监督的想法。在下一堂课中,我们不仅会研究二维图像,还会研究体积,并了解一些关于如何使用弱注释来生成体积三维分割算法的巧妙想法。非常感谢大家的聆听,下节课再见。拜拜。

使用弱注释的更多结果。使用 gifify 创建的图像。来源: YouTube

如果你喜欢这篇文章,你可以在这里找到更多的文章,或者看看我们的讲座。如果你想在未来了解更多的文章、视频和研究,我也会很感激关注 YouTubeTwitter脸书LinkedIn 。本文以 Creative Commons 4.0 归属许可发布,如果引用,可以转载和修改。如果你有兴趣从视频讲座中获得文字记录,试试自动博客

参考

[1] Özgün Çiçek, Ahmed Abdulkadir, Soeren S Lienkamp, et al. “3d u-net: learning dense volumetric segmentation from sparse annotation”. In: MICCAI. Springer. 2016, pp. 424–432.
[2] Waleed Abdulla. Mask R-CNN for object detection and instance segmentation on Keras and TensorFlow. Accessed: 27.01.2020. 2017.
[3] Olga Russakovsky, Amy L. Bearman, Vittorio Ferrari, et al. “What’s the point: Semantic segmentation with point supervision”. In: CoRR abs/1506.02106 (2015). arXiv: 1506.02106.
[4] Marius Cordts, Mohamed Omran, Sebastian Ramos, et al. “The Cityscapes Dataset for Semantic Urban Scene Understanding”. In: CoRR abs/1604.01685 (2016). arXiv: 1604.01685.
[5] Richard O. Duda, Peter E. Hart, and David G. Stork. Pattern classification. 2nd ed. New York: Wiley-Interscience, Nov. 2000.
[6] Anna Khoreva, Rodrigo Benenson, Jan Hosang, et al. “Simple Does It: Weakly Supervised Instance and Semantic Segmentation”. In: arXiv preprint arXiv:1603.07485 (2016).
[7] Kaiming He, Georgia Gkioxari, Piotr Dollár, et al. “Mask R-CNN”. In: CoRR abs/1703.06870 (2017). arXiv: 1703.06870.
[8] Sangheum Hwang and Hyo-Eun Kim. “Self-Transfer Learning for Weakly Supervised Lesion Localization”. In: MICCAI. Springer. 2016, pp. 239–246.
[9] Maxime Oquab, Léon Bottou, Ivan Laptev, et al. “Is object localization for free? weakly-supervised learning with convolutional neural networks”. In: Proc. CVPR. 2015, pp. 685–694.
[10] Alexander Kolesnikov and Christoph H. Lampert. “Seed, Expand and Constrain: Three Principles for Weakly-Supervised Image Segmentation”. In: CoRR abs/1603.06098 (2016). arXiv: 1603.06098.
[11] Tsung-Yi Lin, Michael Maire, Serge J. Belongie, et al. “Microsoft COCO: Common Objects in Context”. In: CoRR abs/1405.0312 (2014). arXiv: 1405.0312.
[12] Ramprasaath R. Selvaraju, Abhishek Das, Ramakrishna Vedantam, et al. “Grad-CAM: Why did you say that? Visual Explanations from Deep Networks via Gradient-based Localization”. In: CoRR abs/1610.02391 (2016). arXiv: 1610.02391.
[13] K. Simonyan, A. Vedaldi, and A. Zisserman. “Deep Inside Convolutional Networks: Visualising Image Classification Models and Saliency Maps”. In: Proc. ICLR (workshop track). 2014.
[14] Bolei Zhou, Aditya Khosla, Agata Lapedriza, et al. “Learning deep features for discriminative localization”. In: Proc. CVPR. 2016, pp. 2921–2929.
[15] Longlong Jing and Yingli Tian. “Self-supervised Visual Feature Learning with Deep Neural Networks: A Survey”. In: arXiv e-prints, arXiv:1902.06162 (Feb. 2019). arXiv: 1902.06162 [cs.CV].
[16] D. Pathak, P. Krähenbühl, J. Donahue, et al. “Context Encoders: Feature Learning by Inpainting”. In: 2016 IEEE Conference on Computer Vision and Pattern Recognition (CVPR). 2016, pp. 2536–2544.
[17] C. Doersch, A. Gupta, and A. A. Efros. “Unsupervised Visual Representation Learning by Context Prediction”. In: 2015 IEEE International Conference on Computer Vision (ICCV). Dec. 2015, pp. 1422–1430.
[18] Mehdi Noroozi and Paolo Favaro. “Unsupervised Learning of Visual Representations by Solving Jigsaw Puzzles”. In: Computer Vision — ECCV 2016. Cham: Springer International Publishing, 2016, pp. 69–84.
[19] Spyros Gidaris, Praveer Singh, and Nikos Komodakis. “Unsupervised Representation Learning by Predicting Image Rotations”. In: International Conference on Learning Representations. 2018.
[20] Mathilde Caron, Piotr Bojanowski, Armand Joulin, et al. “Deep Clustering for Unsupervised Learning of Visual Features”. In: Computer Vision — ECCV 2018. Cham: Springer International Publishing, 2018, pp. 139–156. A.
[21] A. Dosovitskiy, P. Fischer, J. T. Springenberg, et al. “Discriminative Unsupervised Feature Learning with Exemplar Convolutional Neural Networks”. In: IEEE Transactions on Pattern Analysis and Machine Intelligence 38.9 (Sept. 2016), pp. 1734–1747.
[22] V. Christlein, M. Gropp, S. Fiel, et al. “Unsupervised Feature Learning for Writer Identification and Writer Retrieval”. In: 2017 14th IAPR International Conference on Document Analysis and Recognition Vol. 01. Nov. 2017, pp. 991–997.
[23] Z. Ren and Y. J. Lee. “Cross-Domain Self-Supervised Multi-task Feature Learning Using Synthetic Imagery”. In: 2018 IEEE/CVF Conference on Computer Vision and Pattern Recognition. June 2018, pp. 762–771.
[24] Asano YM., Rupprecht C., and Vedaldi A. “Self-labelling via simultaneous clustering and representation learning”. In: International Conference on Learning Representations. 2020.
[25] Ben Poole, Sherjil Ozair, Aaron Van Den Oord, et al. “On Variational Bounds of Mutual Information”. In: Proceedings of the 36th International Conference on Machine Learning. Vol. 97. Proceedings of Machine Learning Research. Long Beach, California, USA: PMLR, Sept. 2019, pp. 5171–5180.
[26] R Devon Hjelm, Alex Fedorov, Samuel Lavoie-Marchildon, et al. “Learning deep representations by mutual information estimation and maximization”. In: International Conference on Learning Representations. 2019.
[27] Aaron van den Oord, Yazhe Li, and Oriol Vinyals. “Representation Learning with Contrastive Predictive Coding”. In: arXiv e-prints, arXiv:1807.03748 (July 2018). arXiv: 1807.03748 [cs.LG].
[28] Philip Bachman, R Devon Hjelm, and William Buchwalter. “Learning Representations by Maximizing Mutual Information Across Views”. In: Advances in Neural Information Processing Systems 32. Curran Associates, Inc., 2019, pp. 15535–15545.
[29] Yonglong Tian, Dilip Krishnan, and Phillip Isola. “Contrastive Multiview Coding”. In: arXiv e-prints, arXiv:1906.05849 (June 2019), arXiv:1906.05849. arXiv: 1906.05849 [cs.CV].
[30] Kaiming He, Haoqi Fan, Yuxin Wu, et al. “Momentum Contrast for Unsupervised Visual Representation Learning”. In: arXiv e-prints, arXiv:1911.05722 (Nov. 2019). arXiv: 1911.05722 [cs.CV].
[31] Ting Chen, Simon Kornblith, Mohammad Norouzi, et al. “A Simple Framework for Contrastive Learning of Visual Representations”. In: arXiv e-prints, arXiv:2002.05709 (Feb. 2020), arXiv:2002.05709. arXiv: 2002.05709 [cs.LG].
[32] Ishan Misra and Laurens van der Maaten. “Self-Supervised Learning of Pretext-Invariant Representations”. In: arXiv e-prints, arXiv:1912.01991 (Dec. 2019). arXiv: 1912.01991 [cs.CV].
33] Prannay Khosla, Piotr Teterwak, Chen Wang, et al. “Supervised Contrastive Learning”. In: arXiv e-prints, arXiv:2004.11362 (Apr. 2020). arXiv: 2004.11362 [cs.LG].
[34] Jean-Bastien Grill, Florian Strub, Florent Altché, et al. “Bootstrap Your Own Latent: A New Approach to Self-Supervised Learning”. In: arXiv e-prints, arXiv:2006.07733 (June 2020), arXiv:2006.07733. arXiv: 2006.07733 [cs.LG].
[35] Tongzhou Wang and Phillip Isola. “Understanding Contrastive Representation Learning through Alignment and Uniformity on the Hypersphere”. In: arXiv e-prints, arXiv:2005.10242 (May 2020), arXiv:2005.10242. arXiv: 2005.10242 [cs.LG].
[36] Junnan Li, Pan Zhou, Caiming Xiong, et al. “Prototypical Contrastive Learning of Unsupervised Representations”. In: arXiv e-prints, arXiv:2005.04966 (May 2020), arXiv:2005.04966. arXiv: 2005.04966 [cs.CV].

弱自我监督学习—第二部分

原文:https://towardsdatascience.com/weakly-and-self-supervised-learning-part-1-ddfdf8377f1d?source=collection_archive---------38-----------------------

FAU 讲座笔记关于深度学习

从二维批注到三维批注

FAU 大学的深度学习。下图 CC BY 4.0 来自深度学习讲座

这些是 FAU 的 YouTube 讲座 深度学习 的讲义。这是与幻灯片匹配的讲座视频&的完整抄本。我们希望,你喜欢这个视频一样多。当然,这份抄本是用深度学习技术在很大程度上自动创建的,只进行了少量的手动修改。 自己试试吧!如果您发现错误,请告诉我们!

航行

上一讲 / 观看本视频 / 顶级/下一讲

在野外,数据也可以用于训练弱监督的 3D 系统。使用 gifify 创建的图像。来源: YouTube

欢迎回到深度学习!所以今天,我们想继续讨论每周注释的例子。今天的主题将特别关注三维注释。

让我们看看那些密集的%\(!"%\)$!!! CC 下的图片来自深度学习讲座的 4.0 。

欢迎回到我们关于弱学习和自我监督学习的讲座,第二部分:从稀疏标注到密集分割。这里的密集是什么意思?“你真笨……”。大概不会。

我们能把二维注释扩展到三维吗?来自深度学习讲座CC BY 4.0 下的图片。

我们真正感兴趣的是密集的三维分割。这里,你有一个体积图像的例子,你可以看到我们在左侧看到了几个切片。然后,我们可以注释这些切片中的每一个,然后我们可以用它们来训练,例如,一个三维 U-net 来产生一个完整的三维分割。正如你可能已经猜到的那样,为了消除切片方向引入的偏差,随后用不同的方向对所有切片进行注释是非常乏味的。所以,你不想这么做。在接下来的几分钟里,我们将讨论如何使用稀疏采样切片来获得全自动三维分割。此外,这种方法很有趣,因为它允许交互式纠正。

让我们利用来自深度学习讲座的 4.0 的 CC 下的 D. Image 中的单热编码标签的属性。

让我们研究一下这个想法。你带着稀疏的标签训练。通常,我们有这些一键标签,本质上是一个,如果你是分段掩码的一部分。面具不是真的就是假的。然后,你得到这个交叉熵损失,本质上就是。您使用的正是返回 1 的标签,因为它是带注释的。但是,当然,对于没有注释的样本,这是不正确的。你能做的是,你可以进一步发展这个,叫做加权交叉熵损失。这里,您将原始的交叉熵乘以一个额外的权重 ww 的设置方式是,如果没有标记,它就是零。否则,您可以指定一个大于零的权重。顺便说一句,如果你有这个 w ,你也可以通过更新 yw ( y )来扩展它,使其具有交互性。因此,这意味着您在迭代过程中与用户一起更新标签。如果你这样做,你实际上可以用稀疏标注的三维体积和训练算法来产生完整的三维分割。

拿走监管不力的留言。来自深度学习讲座的 4.0CC 下的图片。

我们来看一些外卖留言。弱监督学习实际上是一种省略细粒度标签的方法,因为它们很昂贵。我们试图买到便宜得多的东西。核心思想是标签的细节比目标少,方法本质上依赖于先验知识,如关于对象的知识、关于分布的知识,甚至是可以帮助您细化标签的先验算法,以及我们之前称为提示的弱标签。

我们也可以用声音提示弱监管。使用 gifify 创建的图像。来源: YouTube

通常这比完全监督的训练差,但是在实践中它是高度相关的,因为注释是非常非常昂贵的。别忘了迁移学习。这个也能帮到你。在之前的讲座中,我们已经讨论了很多。我们在这里看到的,当然,与半监督学习和自我监督学习有关。

在这个深度学习讲座中,更多令人兴奋的事情即将到来。 CC 下的图片来自深度学习讲座的 4.0 。

这也是为什么我们下次要谈论自我监督的话题,以及这些想法在过去几年里是如何在这个领域引发了相当大的推动。非常感谢您的收听,期待在下一段视频中与您见面。拜拜。

但是,音频有时可能不明确。使用 gifify 创建的图像。来源: YouTube

如果你喜欢这篇文章,你可以在这里找到更多的文章,更多关于机器学习的教育材料,或者看看我们的深度学习讲座。如果你想在未来了解更多的文章、视频和研究,我也会很感激关注 YouTubeTwitter脸书LinkedIn 。本文以 Creative Commons 4.0 归属许可发布,如果引用,可以转载和修改。如果你有兴趣从视频讲座中生成文字记录,试试自动博客

参考

[1] Özgün Çiçek, Ahmed Abdulkadir, Soeren S Lienkamp, et al. “3d u-net: learning dense volumetric segmentation from sparse annotation”. In: MICCAI. Springer. 2016, pp. 424–432.
[2] Waleed Abdulla. Mask R-CNN for object detection and instance segmentation on Keras and TensorFlow. Accessed: 27.01.2020. 2017.
[3] Olga Russakovsky, Amy L. Bearman, Vittorio Ferrari, et al. “What’s the point: Semantic segmentation with point supervision”. In: CoRR abs/1506.02106 (2015). arXiv: 1506.02106.
[4] Marius Cordts, Mohamed Omran, Sebastian Ramos, et al. “The Cityscapes Dataset for Semantic Urban Scene Understanding”. In: CoRR abs/1604.01685 (2016). arXiv: 1604.01685.
[5] Richard O. Duda, Peter E. Hart, and David G. Stork. Pattern classification. 2nd ed. New York: Wiley-Interscience, Nov. 2000.
[6] Anna Khoreva, Rodrigo Benenson, Jan Hosang, et al. “Simple Does It: Weakly Supervised Instance and Semantic Segmentation”. In: arXiv preprint arXiv:1603.07485 (2016).
[7] Kaiming He, Georgia Gkioxari, Piotr Dollár, et al. “Mask R-CNN”. In: CoRR abs/1703.06870 (2017). arXiv: 1703.06870.
[8] Sangheum Hwang and Hyo-Eun Kim. “Self-Transfer Learning for Weakly Supervised Lesion Localization”. In: MICCAI. Springer. 2016, pp. 239–246.
[9] Maxime Oquab, Léon Bottou, Ivan Laptev, et al. “Is object localization for free? weakly-supervised learning with convolutional neural networks”. In: Proc. CVPR. 2015, pp. 685–694.
[10] Alexander Kolesnikov and Christoph H. Lampert. “Seed, Expand and Constrain: Three Principles for Weakly-Supervised Image Segmentation”. In: CoRR abs/1603.06098 (2016). arXiv: 1603.06098.
[11] Tsung-Yi Lin, Michael Maire, Serge J. Belongie, et al. “Microsoft COCO: Common Objects in Context”. In: CoRR abs/1405.0312 (2014). arXiv: 1405.0312.
[12] Ramprasaath R. Selvaraju, Abhishek Das, Ramakrishna Vedantam, et al. “Grad-CAM: Why did you say that? Visual Explanations from Deep Networks via Gradient-based Localization”. In: CoRR abs/1610.02391 (2016). arXiv: 1610.02391.
[13] K. Simonyan, A. Vedaldi, and A. Zisserman. “Deep Inside Convolutional Networks: Visualising Image Classification Models and Saliency Maps”. In: Proc. ICLR (workshop track). 2014.
[14] Bolei Zhou, Aditya Khosla, Agata Lapedriza, et al. “Learning deep features for discriminative localization”. In: Proc. CVPR. 2016, pp. 2921–2929.
[15] Longlong Jing and Yingli Tian. “Self-supervised Visual Feature Learning with Deep Neural Networks: A Survey”. In: arXiv e-prints, arXiv:1902.06162 (Feb. 2019). arXiv: 1902.06162 [cs.CV].
[16] D. Pathak, P. Krähenbühl, J. Donahue, et al. “Context Encoders: Feature Learning by Inpainting”. In: 2016 IEEE Conference on Computer Vision and Pattern Recognition (CVPR). 2016, pp. 2536–2544.
[17] C. Doersch, A. Gupta, and A. A. Efros. “Unsupervised Visual Representation Learning by Context Prediction”. In: 2015 IEEE International Conference on Computer Vision (ICCV). Dec. 2015, pp. 1422–1430.
[18] Mehdi Noroozi and Paolo Favaro. “Unsupervised Learning of Visual Representations by Solving Jigsaw Puzzles”. In: Computer Vision — ECCV 2016. Cham: Springer International Publishing, 2016, pp. 69–84.
[19] Spyros Gidaris, Praveer Singh, and Nikos Komodakis. “Unsupervised Representation Learning by Predicting Image Rotations”. In: International Conference on Learning Representations. 2018.
[20] Mathilde Caron, Piotr Bojanowski, Armand Joulin, et al. “Deep Clustering for Unsupervised Learning of Visual Features”. In: Computer Vision — ECCV 2018. Cham: Springer International Publishing, 2018, pp. 139–156. A.
[21] A. Dosovitskiy, P. Fischer, J. T. Springenberg, et al. “Discriminative Unsupervised Feature Learning with Exemplar Convolutional Neural Networks”. In: IEEE Transactions on Pattern Analysis and Machine Intelligence 38.9 (Sept. 2016), pp. 1734–1747.
[22] V. Christlein, M. Gropp, S. Fiel, et al. “Unsupervised Feature Learning for Writer Identification and Writer Retrieval”. In: 2017 14th IAPR International Conference on Document Analysis and Recognition Vol. 01. Nov. 2017, pp. 991–997.
[23] Z. Ren and Y. J. Lee. “Cross-Domain Self-Supervised Multi-task Feature Learning Using Synthetic Imagery”. In: 2018 IEEE/CVF Conference on Computer Vision and Pattern Recognition. June 2018, pp. 762–771.
[24] Asano YM., Rupprecht C., and Vedaldi A. “Self-labelling via simultaneous clustering and representation learning”. In: International Conference on Learning Representations. 2020.
[25] Ben Poole, Sherjil Ozair, Aaron Van Den Oord, et al. “On Variational Bounds of Mutual Information”. In: Proceedings of the 36th International Conference on Machine Learning. Vol. 97. Proceedings of Machine Learning Research. Long Beach, California, USA: PMLR, Sept. 2019, pp. 5171–5180.
[26] R Devon Hjelm, Alex Fedorov, Samuel Lavoie-Marchildon, et al. “Learning deep representations by mutual information estimation and maximization”. In: International Conference on Learning Representations. 2019.
[27] Aaron van den Oord, Yazhe Li, and Oriol Vinyals. “Representation Learning with Contrastive Predictive Coding”. In: arXiv e-prints, arXiv:1807.03748 (July 2018). arXiv: 1807.03748 [cs.LG].
[28] Philip Bachman, R Devon Hjelm, and William Buchwalter. “Learning Representations by Maximizing Mutual Information Across Views”. In: Advances in Neural Information Processing Systems 32. Curran Associates, Inc., 2019, pp. 15535–15545.
[29] Yonglong Tian, Dilip Krishnan, and Phillip Isola. “Contrastive Multiview Coding”. In: arXiv e-prints, arXiv:1906.05849 (June 2019), arXiv:1906.05849. arXiv: 1906.05849 [cs.CV].
[30] Kaiming He, Haoqi Fan, Yuxin Wu, et al. “Momentum Contrast for Unsupervised Visual Representation Learning”. In: arXiv e-prints, arXiv:1911.05722 (Nov. 2019). arXiv: 1911.05722 [cs.CV].
[31] Ting Chen, Simon Kornblith, Mohammad Norouzi, et al. “A Simple Framework for Contrastive Learning of Visual Representations”. In: arXiv e-prints, arXiv:2002.05709 (Feb. 2020), arXiv:2002.05709. arXiv: 2002.05709 [cs.LG].
[32] Ishan Misra and Laurens van der Maaten. “Self-Supervised Learning of Pretext-Invariant Representations”. In: arXiv e-prints, arXiv:1912.01991 (Dec. 2019). arXiv: 1912.01991 [cs.CV].
33] Prannay Khosla, Piotr Teterwak, Chen Wang, et al. “Supervised Contrastive Learning”. In: arXiv e-prints, arXiv:2004.11362 (Apr. 2020). arXiv: 2004.11362 [cs.LG].
[34] Jean-Bastien Grill, Florian Strub, Florent Altché, et al. “Bootstrap Your Own Latent: A New Approach to Self-Supervised Learning”. In: arXiv e-prints, arXiv:2006.07733 (June 2020), arXiv:2006.07733. arXiv: 2006.07733 [cs.LG].
[35] Tongzhou Wang and Phillip Isola. “Understanding Contrastive Representation Learning through Alignment and Uniformity on the Hypersphere”. In: arXiv e-prints, arXiv:2005.10242 (May 2020), arXiv:2005.10242. arXiv: 2005.10242 [cs.LG].
[36] Junnan Li, Pan Zhou, Caiming Xiong, et al. “Prototypical Contrastive Learning of Unsupervised Representations”. In: arXiv e-prints, arXiv:2005.04966 (May 2020), arXiv:2005.04966. arXiv: 2005.04966 [cs.CV].

弱自我监督学习——第三部分

原文:https://towardsdatascience.com/weakly-and-self-supervised-learning-part-3-b8186679d55e?source=collection_archive---------37-----------------------

FAU 讲座笔记关于深度学习

自我监督标签

FAU 大学的深度学习。下图 CC BY 4.0 来自深度学习讲座

这些是 FAU 的 YouTube 讲座 深度学习 的讲义。这是与幻灯片匹配的讲座视频&的完整抄本。我们希望,你喜欢这个视频一样多。当然,这份抄本是用深度学习技术在很大程度上自动创建的,只进行了少量的手动修改。 自己试试吧!如果您发现错误,请告诉我们!

航行

上一讲 / 观看本视频 / 顶级 / 下一讲

自我监督的人脸模型学习。使用 gifify 创建的图像。来源: YouTube

欢迎回到深度学习!所以今天,我们想开始谈论被称为自我监督学习的想法。我们希望通过自我监督获得标签,并将在接下来的几个视频中研究这个术语的实际含义以及核心思想。

AI 的革命不会被监督。 CC 下的图片来自深度学习讲座的 4.0 。

这是弱自我监督学习的第三部分。今天,我们实际上开始谈论自我监督学习。有一些关于自我监督学习的观点,你可以把它们分成两部分。你可以说,一部分是如何获得自我监督的标签,另一部分是你对损失进行处理,以便嵌入这些标签。我们有适合自我监督的特殊损失。所以,我们先从定义说起。动机是你可以说,传统上,机器学习领域的人相信,监督当然是产生最佳结果的方法。但是,我们有大量我们需要的标签。所以,你可以很快得出结论,人工智能革命不会被监督。这在 Yann LeCun 的以下声明中非常明显。“人类和动物的大部分学习都是无监督学习。如果智能是一块蛋糕,无监督学习就是蛋糕,有监督学习就是蛋糕上的糖衣,强化学习就是蛋糕上的樱桃。”当然,这是由生物学中的观察以及人类和动物如何学习来证实的。

自我监督的理念。来自深度学习讲座CC BY 4.0 下的图片。

自我监督的想法是,你试图利用你已经掌握的关于你的问题的信息,想出一些替代标签,让你做训练过程。Yann LeCun 在这张幻灯片上的主要观点可以总结如下:你试图从过去预测未来,你也可以从最近的过去预测未来,你从现在预测过去或者从底部预测顶部。此外,一个选项可以是从可见物中预测被遮挡物。你假装有一部分输入你不知道,并预测。这实际上允许您提出一个代理任务。使用代理任务,您已经可以执行培训了。好的一面是你根本不需要任何标签,因为你本质上使用了数据的结构。

Yann LeCun 对自我监督学习的定义。 CC 下的图片来自深度学习讲座的 4.0 。

本质上,自我监督学习是一种无监督的学习方法。但时不时地,你需要清楚地表明,你正在一个已经研究了几十年的领域里做一些新的事情。所以,你可能不会再提到无监督这个术语,Yann LeCun 实际上提出了自我监督学习这个术语。他意识到无人监管是一个复杂而令人困惑的术语。因此,尽管这些想法以前就已经存在,术语自我监督学习已经建立。使用这个术语来专注于一种特定的无监督学习是有意义的。所以,你可以说这是无监督学习的一个子类。它以受监督的方式使用伪任务的借口代理。这实质上意味着你可以使用所有的监督学习方法,并且你有自动生成的标签。然后,它们可以被用来衡量正确性,以创造一个损失,以训练你的重量。其想法是,这对于下游任务是有益的,如检索、监督或半监督分类等。顺便说一下,在这种广义的定义中,你也可以认为像生成对抗网络这样的生成模型也是某种自我监督的学习方法。所以基本上,Yann LeCun 有一个非常好的想法,用一种新的方式来构建这种学习。如果你这样做,这当然非常有帮助,因为你可以清楚地表明你正在做一些新的事情,你不同于许多已经存在很长时间的无监督学习方法。

不同自我监督任务的概述。来自深度学习讲座CC BY 4.0 下的图片。

所以,让我们来看看这些想法。当然,有这些托词任务,您可以使用基于生成的方法。所以,你可以使用 GANs,你可以做像超分辨率方法这样的事情。在那里,您向下采样并尝试预测更高分辨率的图像。你可以做修补方法或着色。当然,这也适用于视频。您可以使用基于上下文的方法。在这里,您尝试解决像拼图游戏或聚类这样的问题。在基于语义标签的方法中,您可以尝试估计移动对象或预测相对深度。此外,还有跨通道方法,您可以尝试使用来自多个通道的信息。你有一个链接的传感器系统,假设你有一个深度相机和一个 RGB 相机。然后,您可以将两者联系起来,并尝试从另一个预测一个。如果你有一个附加的传感器,假设你有一辆车,你正在移动,你有一个 GPS 传感器或任何其他传感系统,它会告诉你你的车是如何移动的,那么你可以尝试从实际的视频序列中预测自我运动。

自我监督的汽车场景分析。使用 gifify 创建的图像。来源: YouTube

因此,让我们更详细地研究一下这个问题,看看基于图像的自我监督学习技术,以完善表示学习,这是第一个想法,也是生成性的。例如,您可以在非常容易生成标签的地方对图像进行着色。

学习颜色。来自深度学习讲座CC BY 4.0 下的图片。

从彩色图像开始,计算通道的平均值,得到灰度值图像。然后,你再尝试预测一下原来的颜色。你可以使用一种场景和编码器/解码器的方法来预测正确的颜色图。

学习图像补丁。 CC 下的图片来自深度学习讲座的 4.0 。

此外,你也可以去修补。你可以遮挡图像的一部分,然后试着预测它们。这实际上导致了这样一个任务,您尝试预测一个完整的图像,然后将实际的完整图像与生成器创建的预测进行比较。例如,你可以在 GAN 类型的损失设置中训练这些东西。我们有一个鉴别器,然后告诉你这是否是一个好的修复结果。

学习拼图。 CC 下的图片来自深度学习讲座的 4.0 。

还有关于空间语境的想法。在这里,一个非常常见的方法是解决一个拼图游戏。你取一个小块,或者实际上,你取图像的九个小块,你基本上试图预测你是否有中心小块,比方说,对于猫的脸,你有一个。然后,您希望预测所显示的修补程序的 ID。所以,你放入两张图片,试着预测第二块的正确位置。请注意,这有点棘手,因为有一个简单的解决方案。如果您有持续的边界模式,就会发生这种情况。如果你有连续的纹理,那么在下一个补片中实际的补片很容易被发现,因为纹理是连续的。因此,您应该使用足够大的间隙来解决这个问题。颜色可能也很棘手。您可以使用色差,并通过将绿色和洋红色向灰色移动来预处理图像,或者您可以随机删除两个颜色通道,以避免您只是了解颜色。

学习更难的谜题。来自深度学习讲座CC BY 4.0 下的图片。

这是拼图游戏的改进版本。在 jigsaw puzzle++中,想法是你基本上随机化补丁的顺序,并且你试图预测每个补丁的正确位置。现在,最酷的事情是,如果你有 9 块瓷砖,那么你就有 9 块!可能的排列。这是 30 多万。因此,我们可以为这项任务创建大量的标签,你会看到,以正确的方式完成这项任务实际上是非常关键的。所以,不仅仅是你有很多排列。

问题的正确选择至关重要。 CC 下的图片来自深度学习讲座的 4.0 。

您还需要确保有一个合适的平均汉明距离。你可以看看你是否真的遵从了这个想法,那么这就有所不同了。如果你有一个太低的平均汉明距离,拼图任务精度不是很高。如果你增加它,拼图任务的准确性也会增加。这种高精度很有可能也会应用到感兴趣的实际任务中。在这里,这是一个检测任务,在 jigsaw 任务精度很高的情况下,您还可以构建一个更好的检测器。

学习形象定位。来自深度学习讲座CC BY 4.0 下的图片。

嗯,我们还会对哪些想法感兴趣呢?当然,你可以用旋转做类似的事情。然后,你试着预测图像的正确旋转。这也是一个非常便宜的标签,你可以生成。

在扭曲中学习等价。 CC 下的图片来自深度学习讲座的 4.0 。

让我们看一下上下文相似性。这里的想法是,你想弄清楚这个图像是来自相同还是不同的上下文。所以,你可以选择一个输入补丁,然后扩大它。您可以使用不同的增强方式,如颜色对比度的变化、轻微的移动和一般的像素转换:您还可以添加噪声,这基本上为每个补丁提供了大量其他补丁,它们应该显示相同的内容。现在,您可以用其他补丁重复这一过程,这样您就可以构建一个大型数据库。有了这些补丁,你就可以训练它是否是同一个补丁,然后你可以区分这几个好的类,并以类似的方式训练你的系统。

聚类作为标签。来自深度学习讲座的 4.0CC 下的图片。

另一种方法是使用集群。这是我的同事文森特·克里斯特林的作品。他感兴趣的是为作者识别构建更好的特征。所以,他从检测关键点开始。然后关键点允许你提取补丁。同时,如果使用像 SIFT 这样的算法检测到关键点,则这些关键点会带有一个特征描述符。在未来的描述符上,您可以执行聚类,您得到的聚类可能已经是相当好的训练样本。因此,您可以使用 cluster-ID 来训练一个 ResNet 来预测相应的补丁。这样,您可以使用完全无标签的数据集,进行聚类,生成伪标签,并训练您的系统。文森特已经表明,这实际上给了相当多的性能,以改善表征学习。

迭代聚类学习。 CC 下的图片来自深度学习讲座的 4.0 。

这个想法后来得到了进一步发展。你可以交替进行。这个想法被称为 DeepCluster。现在,你接受一些输入,你有一个网络,然后你基本上从一个未经训练的网络开始。您可以对生成的特征进行聚类,通过聚类,例如简单的 k-means,您可以生成伪标签,从而允许反向传播和表示学习的训练。现在,当然,如果你从随机初始化开始,聚类可能不是很好。因此,您希望在分类和聚类之间交替进行。然后,这也允许你建立一个非常强大的卷积神经网络。琐碎的解决方案也有一些你想避免的问题。因此,您希望重新分配空的聚类,当然,您可以使用一些技巧,例如通过分配给它的聚类大小的倒数来对输入的贡献进行加权。

具有最佳运输的集群。来自深度学习讲座CC BY 4.0 下的图片。

你甚至可以进一步发展这个想法。这导致最佳运输的自我标记[24]。在这里,他们基本上进一步发展了 DeepCluster。他们没有使用聚类,而是使用 Sinkhorn-Knopp 算法来确定伪标签。这里的想法是你试图预测最佳运输。这里,我们可以看到一个最优运输问题的例子。假设,您在仓库 A 和仓库 b 中有供应品。它们各有 25 台笔记本电脑,您在商店 1 和商店 2 中各有 25 台笔记本电脑的需求。然后,您可以看到您想要将这些笔记本电脑运送到各自的商店。当然,你从仓库 A 拿走最近的一台和所有的笔记本电脑,在这种情况下,去商店 1,仓库 B 的所有笔记本电脑去商店 2。

聚类方法的比较。 CC 下的图片来自深度学习讲座的 4.0 。

这个算法的好处是,你可以找到它的线性版本。所以,你可以用线性代数来表达所有这些,这意味着你也可以把它嵌入到神经网络中。如果您将 DeepCluser 与最优传输进行比较,那么您可能需要记住,如果您没有单独的聚类损失,这可能会导致退化的解决方案。此外,请记住,聚类方法会最小化网络也试图优化的相同交叉熵损失。

综合和多任务学习也非常有用。来自深度学习讲座CC BY 4.0 下的图片。

嗯,还有几个主意。我们知道这些食谱就像多任务学习一样。也可以做多任务学习,进行自我监督学习。这里的一个例子是你使用合成图像。所以,你有一些合成图像,你可以生成深度,表面法线,或者轮廓。然后,你可以使用这些作为标签,以训练你的网络,并产生一个良好的表现。此外,您还可以在一种 GAN 设置中最小化真实数据和合成数据之间的特征空间域差异。这也导致了非常好的表征学习。

在这个深度学习讲座中,更多令人兴奋的事情即将到来。 CC 下的图片来自深度学习讲座的 4.0 。

下一次,我们想谈谈如何处理这些损失,并使它们更适合自我监督的学习任务。我们将特别看到,对比损失对此非常有用。非常感谢大家的收听,下期视频再见。拜拜。

更多的自我监督的人脸建模。使用 gifify 创建的图像。来源: YouTube

如果你喜欢这篇文章,你可以在这里找到更多的文章,更多关于机器学习的教育材料,或者看看我们的深度学习讲座。如果你想在未来了解更多的文章、视频和研究,我也会很感激关注 YouTubeTwitter脸书LinkedIn 。本文以 Creative Commons 4.0 归属许可发布,如果引用,可以转载和修改。如果你有兴趣从视频讲座中生成文字记录,试试自动博客

参考

[1] Özgün Çiçek, Ahmed Abdulkadir, Soeren S Lienkamp, et al. “3d u-net: learning dense volumetric segmentation from sparse annotation”. In: MICCAI. Springer. 2016, pp. 424–432.
[2] Waleed Abdulla. Mask R-CNN for object detection and instance segmentation on Keras and TensorFlow. Accessed: 27.01.2020. 2017.
[3] Olga Russakovsky, Amy L. Bearman, Vittorio Ferrari, et al. “What’s the point: Semantic segmentation with point supervision”. In: CoRR abs/1506.02106 (2015). arXiv: 1506.02106.
[4] Marius Cordts, Mohamed Omran, Sebastian Ramos, et al. “The Cityscapes Dataset for Semantic Urban Scene Understanding”. In: CoRR abs/1604.01685 (2016). arXiv: 1604.01685.
[5] Richard O. Duda, Peter E. Hart, and David G. Stork. Pattern classification. 2nd ed. New York: Wiley-Interscience, Nov. 2000.
[6] Anna Khoreva, Rodrigo Benenson, Jan Hosang, et al. “Simple Does It: Weakly Supervised Instance and Semantic Segmentation”. In: arXiv preprint arXiv:1603.07485 (2016).
[7] Kaiming He, Georgia Gkioxari, Piotr Dollár, et al. “Mask R-CNN”. In: CoRR abs/1703.06870 (2017). arXiv: 1703.06870.
[8] Sangheum Hwang and Hyo-Eun Kim. “Self-Transfer Learning for Weakly Supervised Lesion Localization”. In: MICCAI. Springer. 2016, pp. 239–246.
[9] Maxime Oquab, Léon Bottou, Ivan Laptev, et al. “Is object localization for free? weakly-supervised learning with convolutional neural networks”. In: Proc. CVPR. 2015, pp. 685–694.
[10] Alexander Kolesnikov and Christoph H. Lampert. “Seed, Expand and Constrain: Three Principles for Weakly-Supervised Image Segmentation”. In: CoRR abs/1603.06098 (2016). arXiv: 1603.06098.
[11] Tsung-Yi Lin, Michael Maire, Serge J. Belongie, et al. “Microsoft COCO: Common Objects in Context”. In: CoRR abs/1405.0312 (2014). arXiv: 1405.0312.
[12] Ramprasaath R. Selvaraju, Abhishek Das, Ramakrishna Vedantam, et al. “Grad-CAM: Why did you say that? Visual Explanations from Deep Networks via Gradient-based Localization”. In: CoRR abs/1610.02391 (2016). arXiv: 1610.02391.
[13] K. Simonyan, A. Vedaldi, and A. Zisserman. “Deep Inside Convolutional Networks: Visualising Image Classification Models and Saliency Maps”. In: Proc. ICLR (workshop track). 2014.
[14] Bolei Zhou, Aditya Khosla, Agata Lapedriza, et al. “Learning deep features for discriminative localization”. In: Proc. CVPR. 2016, pp. 2921–2929.
[15] Longlong Jing and Yingli Tian. “Self-supervised Visual Feature Learning with Deep Neural Networks: A Survey”. In: arXiv e-prints, arXiv:1902.06162 (Feb. 2019). arXiv: 1902.06162 [cs.CV].
[16] D. Pathak, P. Krähenbühl, J. Donahue, et al. “Context Encoders: Feature Learning by Inpainting”. In: 2016 IEEE Conference on Computer Vision and Pattern Recognition (CVPR). 2016, pp. 2536–2544.
[17] C. Doersch, A. Gupta, and A. A. Efros. “Unsupervised Visual Representation Learning by Context Prediction”. In: 2015 IEEE International Conference on Computer Vision (ICCV). Dec. 2015, pp. 1422–1430.
[18] Mehdi Noroozi and Paolo Favaro. “Unsupervised Learning of Visual Representations by Solving Jigsaw Puzzles”. In: Computer Vision — ECCV 2016. Cham: Springer International Publishing, 2016, pp. 69–84.
[19] Spyros Gidaris, Praveer Singh, and Nikos Komodakis. “Unsupervised Representation Learning by Predicting Image Rotations”. In: International Conference on Learning Representations. 2018.
[20] Mathilde Caron, Piotr Bojanowski, Armand Joulin, et al. “Deep Clustering for Unsupervised Learning of Visual Features”. In: Computer Vision — ECCV 2018. Cham: Springer International Publishing, 2018, pp. 139–156. A.
[21] A. Dosovitskiy, P. Fischer, J. T. Springenberg, et al. “Discriminative Unsupervised Feature Learning with Exemplar Convolutional Neural Networks”. In: IEEE Transactions on Pattern Analysis and Machine Intelligence 38.9 (Sept. 2016), pp. 1734–1747.
[22] V. Christlein, M. Gropp, S. Fiel, et al. “Unsupervised Feature Learning for Writer Identification and Writer Retrieval”. In: 2017 14th IAPR International Conference on Document Analysis and Recognition Vol. 01. Nov. 2017, pp. 991–997.
[23] Z. Ren and Y. J. Lee. “Cross-Domain Self-Supervised Multi-task Feature Learning Using Synthetic Imagery”. In: 2018 IEEE/CVF Conference on Computer Vision and Pattern Recognition. June 2018, pp. 762–771.
[24] Asano YM., Rupprecht C., and Vedaldi A. “Self-labelling via simultaneous clustering and representation learning”. In: International Conference on Learning Representations. 2020.
[25] Ben Poole, Sherjil Ozair, Aaron Van Den Oord, et al. “On Variational Bounds of Mutual Information”. In: Proceedings of the 36th International Conference on Machine Learning. Vol. 97. Proceedings of Machine Learning Research. Long Beach, California, USA: PMLR, Sept. 2019, pp. 5171–5180.
[26] R Devon Hjelm, Alex Fedorov, Samuel Lavoie-Marchildon, et al. “Learning deep representations by mutual information estimation and maximization”. In: International Conference on Learning Representations. 2019.
[27] Aaron van den Oord, Yazhe Li, and Oriol Vinyals. “Representation Learning with Contrastive Predictive Coding”. In: arXiv e-prints, arXiv:1807.03748 (July 2018). arXiv: 1807.03748 [cs.LG].
[28] Philip Bachman, R Devon Hjelm, and William Buchwalter. “Learning Representations by Maximizing Mutual Information Across Views”. In: Advances in Neural Information Processing Systems 32. Curran Associates, Inc., 2019, pp. 15535–15545.
[29] Yonglong Tian, Dilip Krishnan, and Phillip Isola. “Contrastive Multiview Coding”. In: arXiv e-prints, arXiv:1906.05849 (June 2019), arXiv:1906.05849. arXiv: 1906.05849 [cs.CV].
[30] Kaiming He, Haoqi Fan, Yuxin Wu, et al. “Momentum Contrast for Unsupervised Visual Representation Learning”. In: arXiv e-prints, arXiv:1911.05722 (Nov. 2019). arXiv: 1911.05722 [cs.CV].
[31] Ting Chen, Simon Kornblith, Mohammad Norouzi, et al. “A Simple Framework for Contrastive Learning of Visual Representations”. In: arXiv e-prints, arXiv:2002.05709 (Feb. 2020), arXiv:2002.05709. arXiv: 2002.05709 [cs.LG].
[32] Ishan Misra and Laurens van der Maaten. “Self-Supervised Learning of Pretext-Invariant Representations”. In: arXiv e-prints, arXiv:1912.01991 (Dec. 2019). arXiv: 1912.01991 [cs.CV].
33] Prannay Khosla, Piotr Teterwak, Chen Wang, et al. “Supervised Contrastive Learning”. In: arXiv e-prints, arXiv:2004.11362 (Apr. 2020). arXiv: 2004.11362 [cs.LG].
[34] Jean-Bastien Grill, Florian Strub, Florent Altché, et al. “Bootstrap Your Own Latent: A New Approach to Self-Supervised Learning”. In: arXiv e-prints, arXiv:2006.07733 (June 2020), arXiv:2006.07733. arXiv: 2006.07733 [cs.LG].
[35] Tongzhou Wang and Phillip Isola. “Understanding Contrastive Representation Learning through Alignment and Uniformity on the Hypersphere”. In: arXiv e-prints, arXiv:2005.10242 (May 2020), arXiv:2005.10242. arXiv: 2005.10242 [cs.LG].
[36] Junnan Li, Pan Zhou, Caiming Xiong, et al. “Prototypical Contrastive Learning of Unsupervised Representations”. In: arXiv e-prints, arXiv:2005.04966 (May 2020), arXiv:2005.04966. arXiv: 2005.04966 [cs.CV].

弱自我监督学习——第四部分

原文:https://towardsdatascience.com/weakly-and-self-supervised-learning-part-4-2fbfd10280b3?source=collection_archive---------39-----------------------

FAU 讲座笔记关于深度学习

对比损失

FAU 大学的深度学习。下图 CC BY 4.0 来自深度学习讲座

这些是 FAU 的 YouTube 讲座 深度学习 的讲义。这是与幻灯片匹配的讲座视频&的完整抄本。我们希望,你喜欢这个视频一样多。当然,这份抄本是用深度学习技术在很大程度上自动创建的,只进行了少量的手动修改。 自己试试吧!如果您发现错误,请告诉我们!

航行

上一讲 / 观看本视频 / 顶级 / 下一讲

通过视频学习进行自我监督。使用 gifify 创建的图像。来源: YouTube

欢迎回到深度学习!所以,今天我们想在最后一部分讨论弱自我监督学习:一些新的损失也可以帮助我们进行自我监督。那么,让我们看看幻灯片上有什么:今天是第四部分,主题是对比自我监督学习。

对比学习导论。 CC 下的图片来自深度学习讲座的 4.0 。

在对比学习中,你试图把学习问题公式化为一种匹配方法。这里,我们有一个监督学习的例子。这样做的目的是将正确的动物与其他动物相匹配。学习的任务是动物是相同的还是不同的。这实际上是一种非常强大的训练形式,因为你可以避免生成模型或上下文模型中的一些缺点。例如,像素级损失可能过度集中于基于像素的细节,而基于像素的目标通常假定像素无关。这降低了模拟相关性或复杂结构的能力。在这里,我们基本上可以建立抽象模型,这些模型也是以一种分层的方式建立的。现在,我们有了这个受监督的示例,当然,这也适用于我们之前看到的许多不同的伪标签。

数学实现。来自深度学习讲座CC BY 4.0 下的图片。

然后我们可以建立这种对比损失。我们所需要的是当前样本 x 一些正样本 x plus,然后是来自不同类别的负样本。此外,我们需要一个相似度函数 s,例如,这可以是余弦相似度。你也可以有一个可训练的相似性函数,但一般来说,你也可以使用一些我们在这节课中已经讨论过的标准相似性函数。此外,您希望应用网络 f( x )并计算相似性。目标是在阳性样本和考虑中的样本以及所有阴性样本之间具有更高的相似性。这就导致了对比损失。它有时也被称为信息归一化交叉熵损失。在文献中也有其他名称:n 对损失,一致性损失,和基于 NCE 的排名。对于 n 路 softmax 分类器来说,这本质上是交叉熵损失。这里的想法是,你基本上有正面的例子,然后这被所有的例子标准化。这里,我将第一行中的两个样本进行拆分,但您可以看到,拆分实际上是所有样本的总和。这就产生了一种 softmax 分类器。

对比损耗也可以包括温度参数。 CC 下的图片来自深度学习讲座的 4.0 。

因此,最小化对比损失实际上最大化了 f( x )和 f( x plus)之间的互信息的下限,如这两个参考文献所示。还有一个常见的变化是引入温度超参数,如本例所示。所以,你除以一个额外的τ。

对比损失的两个重要性质。 CC 下的图片来自深度学习讲座的 4.0 。

对比损失是非常有效的,它们有两个非常有用的性质。一方面,它们是一致的。所以,相似的样本有相似的特征。另一方面,它们创造了一致性,因为它们保留了最大限度的信息。

SimCLR 中的设置。来自深度学习讲座的 4.0CC 下的图片。

让我们来看一个如何构建的例子。这是出自[31]。在这里,您可以看到,我们可以从一些样本 x 开始。假设你从一个小批量的 n 个样本开始。然后,用两种不同的数据扩充操作来转换每个样本。这导致 2n 个扩充样本。因此,对于该批次中的每个样本,您会得到两个不同的增量。这里,我们将 t 和 t '应用于同一个样本。然后,这个样本是相同的,并且你的变换 t 和 t '取自一组扩充 t。现在,你最终得到每个样本的一个正对和 2(n-1)个负对。因为它们都是不同的样本,所以您可以通过基本编码器 f( x )计算一个表示,然后产生一些 h ,这是我们感兴趣的实际特征表示。f( x )的一个例子可以是 ResNet-50。在此之上,我们有一个表示头 g,然后进行额外的降维。注意 g 和 f 在两个分支中都是相同的。所以,你可以说这种方法和所谓的连体网络有很多相似之处。因此,您可以从 g 中获得两个不同的集合 z 下标 I 和 z 下标 j。利用这些 z ,您可以计算对比损失,然后将其表示为两个 z 在温度参数τ上的相似性。你看,这基本上是我们之前已经看到的相同的对比损失。

通过运动传播的自我监督学习。使用 gifify 创建的图像。来源: YouTube

当然,对比损失也可以在监督下合并。这就导致了有监督的对比学习。这里的想法是,如果你只是进行自我监督的对比,你会有正面的例子和负面的例子。有了监督对比损失,你还可以嵌入额外的类信息。

监督与自我监督的对比学习。来自深度学习讲座的 4.0CC 下的图片。

所以,这有额外的积极影响。让我们看看这是如何应用的。我们基本上保持训练两个耦合网络的相同想法。

自我监督和监督对比损失是兼容的。 CC 下的图片来自深度学习讲座的 4.0 。

所以让我们总结一下对比学习和监督对比学习的区别。在监督学习中,你基本上有你的编码器,这里显示为这个灰色块。然后,你最终得到一些描述,这是一个 2048 维向量,你进一步训练一个分类头,使用经典的交叉熵损失产生类别 dog。现在,在对比学习中,你可以扩展这个。基本上你会有两个耦合的网络,你有两个补片,它们要么相同,要么不同,使用不同的增强技术。你训练这些耦合的重量共享网络来产生 2048 维的表现。在顶部,你有这个表现头部,你使用表现层本身的对比损失。现在,如果将监督损失和对比损失两者结合起来,基本上与对比损失的设置相同,但在表示层,您可以增加一个严格监督的额外损失。这里,你仍然有典型的 softmax,比如说一千个类,在这个例子中预测 dog。你把它耦合到表示层来融合对比损失和监督损失。

监督对比损失。来自深度学习讲座CC BY 4.0 下的图片。

因此,自我监督不知道类别标签,它只知道一个正例。被监督的人知道所有的类别标签,并且每个例子都有许多优点。然后可以将其合并,并计算具有相同类别锚的任何样本 z 之间的损耗。然后,这允许你计算任何样本 z 下标 j 与锚 z 下标 I 具有相同类别之间的损耗。因此,这两个类别是相同的。这导致了下面的损失:你可以看到这仍然是基于这种对比损失。现在,我们明确地使用余弦相似度,仅仅使用两个向量的内积。此外,您可以看到,我们在这里添加了红色术语,告诉我们只使用有不同样本的情况。所以 I 不等于 j,我们想在这个损失中使用样本,我们想在这个损失中使用样本,实际的类成员是相同的。

监督对比损失的性质。来自深度学习讲座的 4.0CC 下的图片。

有几件额外的事情你必须记住。向量 z 需要被归一化。这意味着您想要引入一个缩放比例,其中这个 w 实际上是投影网络的输出,您对其进行缩放,使其具有单位范数。这实质上导致了某种你可以解释为内置焦损失的东西,因为相对于 w 的梯度对于硬正片和负片来说会很高,否则会很小。顺便说一下,对于一个正的和一个负的,这个损失与实际观测值和正的欧几里德距离的平方成正比,减去实际观测值和负的欧几里德距离的平方。顺便说一下,这也是暹罗网络中非常常见的对比损失。

根据[33],监督对比损失相对于超参数而言相当稳定。来自深度学习讲座的 4.0CC 下的图片。

让我们来看看超参数。事实证明,对于超参数,监督对比损失也非常稳定,就学习速率、优化器以及增强而言,您不会看到这些大的变化,就好像您只使用监督交叉熵损失一样。如果你对确切的实验细节感兴趣,请看看[33]。

你应该知道的关于对比损失的其他一些事情。 CC 下的图片来自深度学习讲座的 4.0 。

还有什么?嗯,训练比交叉熵损失慢 50%左右。它确实通过 CutMix 等最先进的数据增强技术改进了训练,并且支持潜在空间中的无监督聚类。这允许他们校正标签噪声。它还为半监督学习等引入了新的可能性。

引导你自己的潜能使用其他学习方式的技巧。来自深度学习讲座CC BY 4.0 下的图片。

嗯,是这样吗?没有别的想法了吗?嗯,还有一个有趣的想法是自我监督学习。你可以说这是一个范式的转变。这是一篇非常新的论文,但我把它放在这里是因为它有一些非常有趣的想法,与对比损失非常不同。所以这叫做“引导你自己的潜能”(BYOL),他们观察到的问题是,配对的选择是至关重要的。因此,为了得到正确的配对,通常需要大批量、内存库和定制挖掘策略。你还需要有正确的增强策略。在引导你自己的潜能时,他们不需要消极的一对。它们不需要对比损失,并且与对比对应的图像相比,它们对批量大小和图像增强集的变化更有弹性。

该架构从在线网络和目标网络构建损耗。 CC 下的图片来自深度学习讲座的 4.0 。

有什么想法?他们这里也有类似的设置。他们有这种网络来进行观察、表现、投射和预测。现在,他们有了一个在线网络和一个目标网络。他们相互影响,相互学习。现在,当然,这是有问题的,因为理论上有一个微不足道的解决方案,比如对所有图像都是零。因此,他们用在线网络的慢速移动平均值作为目标网络来应对。这可以防止塌陷或重量很快变为零。作为损失,他们使用 l2 归一化预测的均方误差。这与余弦距离成正比。

BYOL 超越了最先进的性能。 CC 下的图片来自深度学习讲座的 4.0 。

非常有趣的是,通过这个非常简单的想法,他们实际上胜过了最先进的和自我监督的学习方法。因此,你可以在这里看到我们在开始和 simCLR 中谈到的着色和不同的想法。他们用他们的方法胜过他们。他们甚至超过了 simCLR。

就性能与参数而言,BYOL 也接近监督学习。来自深度学习讲座CC BY 4.0 下的图片。

有趣的是,就参数数量而言,它们非常接近监督学习,在 ImageNet 上的图像精度排名第一。因此,他们用非常简单的方法就能非常接近最先进的性能。事实上,我很想知道这是否也可以转移到 ImageNet 之外的其他领域。特别是,例如,在医学数据上研究这种方法将是有趣的。你可以看到,有了自我监督学习,我们非常非常接近最先进的水平。这是一个非常活跃的研究领域。所以,让我们看看这些结果在接下来的几个月和几年里会如何发展,以及在几个月后哪些方法会被认为是最先进的方法。

在这个深度学习讲座中,更多令人兴奋的事情即将到来。 CC 下的图片来自深度学习讲座的 4.0 。

当然,我们现在正慢慢接近我们的讲座的尾声。但是下次还是会有一些事情出现。特别是,下次我们要讨论如何处理图形。还有一个非常好的概念,叫做图卷积,我想在下一个视频中向你们介绍这个主题。我仍然想展示的另一个新兴方法是如何避免从头开始学习一切以及如何将特定的先验知识嵌入深度网络的想法。也有一些非常酷的方法,我认为值得在这个讲座中展示。所以,我下面有很多参考资料。非常感谢您的收听,期待在下一段视频中与您见面。拜拜。

如果你喜欢这篇文章,你可以在这里找到更多的文章,或者看看我们的讲座。如果你想在未来了解更多的文章、视频和研究,我也会很感激关注 YouTubeTwitter脸书LinkedIn 。本文以 Creative Commons 4.0 归属许可发布,如果引用,可以转载和修改。如果你有兴趣从视频讲座中获得文字记录,试试自动博客

参考

[1] Özgün Çiçek, Ahmed Abdulkadir, Soeren S Lienkamp, et al. “3d u-net: learning dense volumetric segmentation from sparse annotation”. In: MICCAI. Springer. 2016, pp. 424–432.
[2] Waleed Abdulla. Mask R-CNN for object detection and instance segmentation on Keras and TensorFlow. Accessed: 27.01.2020. 2017.
[3] Olga Russakovsky, Amy L. Bearman, Vittorio Ferrari, et al. “What’s the point: Semantic segmentation with point supervision”. In: CoRR abs/1506.02106 (2015). arXiv: 1506.02106.
[4] Marius Cordts, Mohamed Omran, Sebastian Ramos, et al. “The Cityscapes Dataset for Semantic Urban Scene Understanding”. In: CoRR abs/1604.01685 (2016). arXiv: 1604.01685.
[5] Richard O. Duda, Peter E. Hart, and David G. Stork. Pattern classification. 2nd ed. New York: Wiley-Interscience, Nov. 2000.
[6] Anna Khoreva, Rodrigo Benenson, Jan Hosang, et al. “Simple Does It: Weakly Supervised Instance and Semantic Segmentation”. In: arXiv preprint arXiv:1603.07485 (2016).
[7] Kaiming He, Georgia Gkioxari, Piotr Dollár, et al. “Mask R-CNN”. In: CoRR abs/1703.06870 (2017). arXiv: 1703.06870.
[8] Sangheum Hwang and Hyo-Eun Kim. “Self-Transfer Learning for Weakly Supervised Lesion Localization”. In: MICCAI. Springer. 2016, pp. 239–246.
[9] Maxime Oquab, Léon Bottou, Ivan Laptev, et al. “Is object localization for free? weakly-supervised learning with convolutional neural networks”. In: Proc. CVPR. 2015, pp. 685–694.
[10] Alexander Kolesnikov and Christoph H. Lampert. “Seed, Expand and Constrain: Three Principles for Weakly-Supervised Image Segmentation”. In: CoRR abs/1603.06098 (2016). arXiv: 1603.06098.
[11] Tsung-Yi Lin, Michael Maire, Serge J. Belongie, et al. “Microsoft COCO: Common Objects in Context”. In: CoRR abs/1405.0312 (2014). arXiv: 1405.0312.
[12] Ramprasaath R. Selvaraju, Abhishek Das, Ramakrishna Vedantam, et al. “Grad-CAM: Why did you say that? Visual Explanations from Deep Networks via Gradient-based Localization”. In: CoRR abs/1610.02391 (2016). arXiv: 1610.02391.
[13] K. Simonyan, A. Vedaldi, and A. Zisserman. “Deep Inside Convolutional Networks: Visualising Image Classification Models and Saliency Maps”. In: Proc. ICLR (workshop track). 2014.
[14] Bolei Zhou, Aditya Khosla, Agata Lapedriza, et al. “Learning deep features for discriminative localization”. In: Proc. CVPR. 2016, pp. 2921–2929.
[15] Longlong Jing and Yingli Tian. “Self-supervised Visual Feature Learning with Deep Neural Networks: A Survey”. In: arXiv e-prints, arXiv:1902.06162 (Feb. 2019). arXiv: 1902.06162 [cs.CV].
[16] D. Pathak, P. Krähenbühl, J. Donahue, et al. “Context Encoders: Feature Learning by Inpainting”. In: 2016 IEEE Conference on Computer Vision and Pattern Recognition (CVPR). 2016, pp. 2536–2544.
[17] C. Doersch, A. Gupta, and A. A. Efros. “Unsupervised Visual Representation Learning by Context Prediction”. In: 2015 IEEE International Conference on Computer Vision (ICCV). Dec. 2015, pp. 1422–1430.
[18] Mehdi Noroozi and Paolo Favaro. “Unsupervised Learning of Visual Representations by Solving Jigsaw Puzzles”. In: Computer Vision — ECCV 2016. Cham: Springer International Publishing, 2016, pp. 69–84.
[19] Spyros Gidaris, Praveer Singh, and Nikos Komodakis. “Unsupervised Representation Learning by Predicting Image Rotations”. In: International Conference on Learning Representations. 2018.
[20] Mathilde Caron, Piotr Bojanowski, Armand Joulin, et al. “Deep Clustering for Unsupervised Learning of Visual Features”. In: Computer Vision — ECCV 2018. Cham: Springer International Publishing, 2018, pp. 139–156. A.
[21] A. Dosovitskiy, P. Fischer, J. T. Springenberg, et al. “Discriminative Unsupervised Feature Learning with Exemplar Convolutional Neural Networks”. In: IEEE Transactions on Pattern Analysis and Machine Intelligence 38.9 (Sept. 2016), pp. 1734–1747.
[22] V. Christlein, M. Gropp, S. Fiel, et al. “Unsupervised Feature Learning for Writer Identification and Writer Retrieval”. In: 2017 14th IAPR International Conference on Document Analysis and Recognition Vol. 01. Nov. 2017, pp. 991–997.
[23] Z. Ren and Y. J. Lee. “Cross-Domain Self-Supervised Multi-task Feature Learning Using Synthetic Imagery”. In: 2018 IEEE/CVF Conference on Computer Vision and Pattern Recognition. June 2018, pp. 762–771.
[24] Asano YM., Rupprecht C., and Vedaldi A. “Self-labelling via simultaneous clustering and representation learning”. In: International Conference on Learning Representations. 2020.
[25] Ben Poole, Sherjil Ozair, Aaron Van Den Oord, et al. “On Variational Bounds of Mutual Information”. In: Proceedings of the 36th International Conference on Machine Learning. Vol. 97. Proceedings of Machine Learning Research. Long Beach, California, USA: PMLR, Sept. 2019, pp. 5171–5180.
[26] R Devon Hjelm, Alex Fedorov, Samuel Lavoie-Marchildon, et al. “Learning deep representations by mutual information estimation and maximization”. In: International Conference on Learning Representations. 2019.
[27] Aaron van den Oord, Yazhe Li, and Oriol Vinyals. “Representation Learning with Contrastive Predictive Coding”. In: arXiv e-prints, arXiv:1807.03748 (July 2018). arXiv: 1807.03748 [cs.LG].
[28] Philip Bachman, R Devon Hjelm, and William Buchwalter. “Learning Representations by Maximizing Mutual Information Across Views”. In: Advances in Neural Information Processing Systems 32. Curran Associates, Inc., 2019, pp. 15535–15545.
[29] Yonglong Tian, Dilip Krishnan, and Phillip Isola. “Contrastive Multiview Coding”. In: arXiv e-prints, arXiv:1906.05849 (June 2019), arXiv:1906.05849. arXiv: 1906.05849 [cs.CV].
[30] Kaiming He, Haoqi Fan, Yuxin Wu, et al. “Momentum Contrast for Unsupervised Visual Representation Learning”. In: arXiv e-prints, arXiv:1911.05722 (Nov. 2019). arXiv: 1911.05722 [cs.CV].
[31] Ting Chen, Simon Kornblith, Mohammad Norouzi, et al. “A Simple Framework for Contrastive Learning of Visual Representations”. In: arXiv e-prints, arXiv:2002.05709 (Feb. 2020), arXiv:2002.05709. arXiv: 2002.05709 [cs.LG].
[32] Ishan Misra and Laurens van der Maaten. “Self-Supervised Learning of Pretext-Invariant Representations”. In: arXiv e-prints, arXiv:1912.01991 (Dec. 2019). arXiv: 1912.01991 [cs.CV].
33] Prannay Khosla, Piotr Teterwak, Chen Wang, et al. “Supervised Contrastive Learning”. In: arXiv e-prints, arXiv:2004.11362 (Apr. 2020). arXiv: 2004.11362 [cs.LG].
[34] Jean-Bastien Grill, Florian Strub, Florent Altché, et al. “Bootstrap Your Own Latent: A New Approach to Self-Supervised Learning”. In: arXiv e-prints, arXiv:2006.07733 (June 2020), arXiv:2006.07733. arXiv: 2006.07733 [cs.LG].
[35] Tongzhou Wang and Phillip Isola. “Understanding Contrastive Representation Learning through Alignment and Uniformity on the Hypersphere”. In: arXiv e-prints, arXiv:2005.10242 (May 2020), arXiv:2005.10242. arXiv: 2005.10242 [cs.LG].
[36] Junnan Li, Pan Zhou, Caiming Xiong, et al. “Prototypical Contrastive Learning of Unsupervised Representations”. In: arXiv e-prints, arXiv:2005.04966 (May 2020), arXiv:2005.04966. arXiv: 2005.04966 [cs.CV].

摧毁数学的武器:数据科学家的收获

原文:https://towardsdatascience.com/weapons-of-math-destruction-takeaways-for-data-scientists-bb0ddd148b0?source=collection_archive---------24-----------------------

凯茜·奥尼尔为广大读者写的书也呼吁数据科学家采取行动

威廉·康托伊斯·让拍摄的关于 Pix 生活的照片

尽管 Cathy O'Neil 几年前写了《数学毁灭的武器》(2016 年出版),但它向数据科学家传达了一个信息,即 100%适用于今天,并将可能被证明是永恒的。在这里你可以找到我的要点:

数据科学家不仅需要考虑他们的模型对底线的影响,还需要考虑对人的影响。

我们必须检查假阳性和假阴性,看看谁被我们的模型描述错了。我们需要思考我们的模型是如何被使用的——能够准确预测每分钟在任何给定位置将出现的客户数量是非常酷的,但是经理或公司领导人会如何处理这些信息呢?我们是不是让艰难的工作变得更加艰难了?我们需要让我们的公司遵守与我们的价值观一致的标准(参见下文:政策)。

数据科学家需要有效地沟通他们的算法做什么和不做什么。

不完全理解数据建模的人很容易兴奋,认为模型是“科学的”和“无偏见的”,它反映了基本事实。事实上,我们正在根据历史数据对人们进行分类,这些数据可能充满了制度化的种族主义、性别歧视、能力歧视、阶级歧视等,并使用这种分类来预测他们的未来,决定他们在监狱里呆多久,并设定信贷、保险等的价格。我们需要明确我们模型的假设和输入。

数据科学家需要为符合其价值观的政策变革做出贡献。

仅仅因为你选择不做歧视性的数据科学来帮助有钱有势的人在不太有钱没势的人身上变得越来越有钱有势,并不意味着其他人不会。了解数据科学技术方面的人需要为围绕不同行业的公司被允许使用数据的方式以及他们被允许将哪些数据用于各种目的的政策对话做出贡献。许多公司都在努力在法律允许的范围内最大限度地实现利润最大化(或者是灰色地带,或者不是,取决于你的视角,对美国公司的信念等)。在推动执法的同时,我们需要加强和更新法律,以影响算法和模型的使用。法律通常落后于技术进步,但近年来技术进步的速度迅速提高,而国会的行动却越来越慢。这种不断扩大的差距正在扩大我们的能力、道德和法律之间的可疑灰色区域。

一些惊人的报价:

  • 种族主义是最不修边幅的预测模型。它由随意的数据收集和虚假的相关性驱动,由制度不平等强化,并被确认偏差污染。
  • 尽管模型以公正著称,但它们反映了目标和意识形态……从我们选择收集的数据到我们提出的问题,我们自己的价值观和欲望影响着我们的选择。模型是嵌入在数学中的观点。
  • 模型的盲点反映了其创建者的判断和优先级。
  • 承诺效率和公平的[数学毁灭武器,即重要的、秘密的和破坏性的算法]扭曲了高等教育,推高了债务,刺激了大规模监禁,几乎在每个关头都打击了穷人,并破坏了民主。
  • 大数据流程整理了过去。他们没有发明未来。做到这一点需要道德想象力,而这是只有人类才能提供的。我们必须明确地将更好的价值嵌入到我们的算法中,创建符合我们道德标准的大数据模型。有时,这意味着将公平置于利润(最大化)之前。

渴望更多?

天气数据收集:使用 Python 进行网络搜集

原文:https://towardsdatascience.com/weather-data-collection-web-scraping-using-python-a4189e7a2ee6?source=collection_archive---------10-----------------------

图像来源

在这篇博客中,我将讨论如何从网站上收集数据。希望你已经使用 API 参观了我的数据收集技术。在现实世界中,我们可能会遇到不同的数据源,如数据库、日志文件、结构化文件、服务或 API 等。这些来源可能包含记录、图表或文本形式的数据。因此,数据随处可见,为了执行不同的创新数据科学技术,我们需要解析这些数据。我们知道维基百科是文本形式数据的最大来源之一。

如何解析这些类型的文本数据?

这里网页抓取进入图片!这是一种使用 HTML 标签提取数据的技术。这里我将讨论从 EstesPark 天气网站获取天气数据的技术。这个网站主要是为科罗拉多州埃斯蒂斯帕克附近的居民提供公共服务。下面是网站截图。你可以点击链接进入网站。

来源:https://www.estesparkweather.net/archive_reports.php?日期=202005 年

一些关于网站的有用信息

  1. 该网站包含日期方面的天气数据,如平均温度、平均湿度、平均露点等。这些数据存储在 HTML web 表中。
  2. 有一个下拉框,你可以自由选择月份和年份来查看天气数据。
  3. 每次您更改下拉选择时,日期值将根据所选的月份和年份进行更改,但采用 yyyymm 格式。参考上图,我选择2020 年 5 月,链接中的,日期值改为 202005。

https://www.estesparkweather.net/archive_reports.php?日期=202005 年

首先导入案例研究所需的所有库

import bs4
from bs4 import BeautifulSoup
import requests
import pandas as pd
from datetime import datetime

让我们来理解这段代码。

url=‘https://www.estesparkweather.net/archive_reports.phpdate=202005'
page = requests.get(url)
print(page)
soup =  BeautifulSoup(page.content,'html.parser')
print(soup)

requests 库允许您轻松地发送 HTTP 请求,并且不需要手动向您的 url 添加查询字符串,或者对您的帖子数据进行格式编码。requests 模块中的 urllib3 模块使 url 处于保持活动状态,您可以连续地将数据放入池中。

一个有效的 url 会给你一个状态码 200。这意味着网址工作正常。

BeautifulSoup 库帮助您解析网页上的 HTML 内容和 XML 文件中的 XML 内容。BeautifulSoup 的文档字符串如下。

您将在 BeautifulSoup 对象上调用的大多数方法都继承自
PageElement 或 Tag。

在内部,这个类定义了在将 HTML/XML 文档转换成数据
结构时由
树构建器调用的基本接口。该接口抽象出了
解析器之间的差异。要编写一个新的树构建器,你需要从整体上理解
这些方法。

这些方法将被 BeautifulSoup 构造函数调用:

  • reset()
  • feed(markup)

树构建器可以从其 feed()实现中调用这些方法:

  • handle_starttag(name,attrs) #参见关于返回值的注释
  • handle _ end tag(name)
  • handle _ data(data)#追加到当前数据节点
  • endData(containerClass) #结束当前数据节点

节目结束时,您应该能够使用“开始标记”事件、“结束标记”事件、“数据”事件和“完成数据”事件构建一个树。

在 BeautifulSoup 构造函数中,我输入了 url 的 HTML 内容,并给出了命令“html.parser”。这将给我网页的 HTML 内容。对于 XML,可以使用' lxml '。

版权所有 Somesh

那汤是什么?

这是一个漂亮的组对象,它有专门用于处理 HTML 内容的方法。

版权所有 Somesh

正如我前面提到的,网站上的天气数据是 HTML 网页表格的形式。因此,我们在 HTML 内容中查找表格,并分析行和列。

table = soup.find_all(‘table’)raw_data = [row.text.splitlines() for row in table]
raw_data = raw_data[:-9]for i in range(len(raw_data)):
 raw_data[i] = raw_data[i][2:len(raw_data[i]):3]
print(raw_data)

在下拉列表中,当我们选择 2020 年 5 月时,它将为您提供单独的表,其中包含每天的所有天气属性值。因此,我们将拆分表中的行并追加到一个列表中。最后,你会得到一个列表列表。值得注意的是,每个子列表都包含特定月份的天气属性及其值。

如何获取其他月份的天气数据?

如前所述,该链接包含页面值等于下拉值,但格式为 yyyymm。因此,您创建了一个日期范围,将日期分解成所需的格式,并与字符串 URL 连接起来。

Dates_r = pd.date_range(start = ‘1/1/2009’,end = ‘08/05/2020’,freq = ‘M’)
dates = [str(i)[:4] + str(i)[5:7] for i in Dates_r]
dates[0:5]for k in range(len(dates)):
    url = "[http://www.estesparkweather.net/archive_reports.php?date=](http://www.estesparkweather.net/archive_reports.php?date=)"
    url += dates[k]

现在,您可以执行字符串剥离技术来创建数据集。下面是一个例子。

for u in url:
 for i in range(len(raw_data)):
 c = [‘.’.join(re.findall(“\d+”,str(raw_data[i][j].split()[:5])))for j in range(len(raw_data[i]))]
 df_list.append(c)
 index.append(dates[k] + c[0])
 f_index = [index[i] for i in range(len(index)) if len(index[i]) > 6]
 data = [df_list[i][1:] for i in range(len(df_list)) if len(df_list[i][1:]) == 19]

要将日期作为数据集的索引,可以使用下面的代码。

final_index = [datetime.strptime(str(f_index[i]), ‘%Y%m%d’).strftime(‘%Y-%m-%d’) for i in range(len(f_index))]

您可以为列名制作一个天气属性列表,如湿度、温度、降雨量,或者为数据选择自定义列名。

恭喜你!!!你离创建一个数据框架还差得很远。

在 DataFrame()中,您将赋予 数据 值作为您为所有天气属性值所做的数据, 等于包含自定义列名的列表变量,最后 索引 值将成为日期的列表变量。

样本输出版权所有 Somesh

这不是结束,而是开始。你可以用这个概念来抓取电子报、歌曲网站等的数据。

在下一篇博客中,我将提出不同的数据收集技术。我希望你已经喜欢了自然语言处理第一部分 & 第二部分

我很乐意听到对上述分析的任何评论——欢迎在下面留言,或者通过 LinkedIntwitter @RoutraySomesh 联系我!!!

天气预报:深度学习方法

原文:https://towardsdatascience.com/weather-forecasting-a-deep-learning-approach-7ecddff0fa71?source=collection_archive---------16-----------------------

利用印尼 10 年的数据集和 LSTM 模式预测天气

SHAH ShahUnsplash 上拍摄的照片

天气不仅与我们息息相关,而且对我们的生存至关重要。不利的天气可能会摧毁我们吃的食物、我们依赖的商业和我们依赖的福祉。因此,必须准确及时地预报天气,以便我们能够采取必要的预防措施,最大限度地减少与天气相关的风险。

在本文中,我们将了解如何利用印度尼西亚遍布群岛的 70 多个气象站的 10 年每日降水记录来提前预测天气,特别是降雨量。我们将建立一个基于长短期网络(LSTM)的模型。

LSTM:概述

LSTM 通常适用于时间序列数据(如我们的降水数据集),因为它能够“记住”来自称为单元状态的特征的长期相关性/信息。这种细胞状态在整个网络中运行,并向下(或向上)传递信息,例如,来自一个序列的早期信息可以影响后来输入的预测。这种信息传递对于时间序列天气数据至关重要,因为每个输入都依赖于不同时间点的其他输入。

存储、删除、修改和传递的信息由控制。下面的图 1 展示了 LSTM 模型的一般架构。本文假设读者熟悉 LSTM,但不会涉及网络架构的具体细节。如果你想了解更多,你可以访问这本简明扼要的 LSTM 简介。

图 1: LSTM 单个细胞的架构

天气预报:数据准备

既然我们已经解释了基本网络,让我们开始导入数据集。你可以在这里找到我们的雨量 CSV 数据的清理版本。

import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
from keras.models import Sequential
from keras.layers import LSTM, Dense, Dropout, BidirectionalDATA_DIR = './dataset/rainfall.csv'
dataset = pd.read_csv(DATA_DIR)
rainfall_df = dataset[['rainfall']]rainfall_df

CSV 的摘要可以在下面的图 2 中看到。

图 2:降雨量数据框汇总

然后,我们将按照 90:10 的比例分割训练集和测试集。

train_split= 0.9
split_idx = int(len(rainfall_df) * 0.9)training_set = rainfall_df[:split_idx].values
test_set = rainfall_df[split_idx:].values

我们的想法是利用过去 30 天的数据,预测未来 5 天的。为此,我们需要创建一个训练数据集,其中 x 值是 30 天的窗口化数据,相应的 y 值是未来 5 天的后续降雨量数据。

# 5-day prediction using 30 days datax_train = []
y_train = []
n_future = 5 #Next 5 days rainfall forecast
n_past = 30 #Past 30 daysfor i in range(0, len(training_set) - n_past - n_future + 1):
 x_train.append(training_set[i : i + n_past, 0])
 y_train.append(training_set[i + n_past : i + n_past + n_future, 0])

在为训练集生成 x 和 y 之后,我们将确保数据类型是正确的,并且形状符合模型的要求。

x_train , y_train = np.array(x_train), np.array(y_train)
x_train = np.reshape(x_train, (x_train.shape[0] , x_train.shape[1], 1))

天气预报:模型定义

现在我们已经有了我们的训练集,我们将利用 LSTM 架构来定义我们的预测器。我们有以下内容:

  1. 双向:确保序列前一部分的信息对后一部分可用,反之亦然。
  2. LSTM (x3)层:30 个单元代表 30 天窗口化的历史数据集,而 return_sequences 参数指定每个单元的输出将作为下一层的输入。
  3. Dropout (p=0.2) :用于正则化效果,防止网络过拟合训练集。
  4. 密集层:有 5 个预测神经元,每个神经元代表未来的一天。
EPOCHS = 500
BATCH_SIZE = 32regressor = Sequential()regressor.add(Bidirectional(LSTM(units=30, return_sequences=True, input_shape = (x_train.shape[1], 1))))
regressor.add(Dropout(0.2))
regressor.add(LSTM(units= 30, return_sequences=True))
regressor.add(Dropout(0.2))
regressor.add(LSTM(units= 30, return_sequences=True))
regressor.add(Dropout(0.2))
regressor.add(LSTM(units= 30))
regressor.add(Dropout(0.2))
regressor.add(Dense(units = n_future, activation=’relu’))regressor.compile
(
optimizer=’adam’, 
loss=’mean_squared_error’, 
metrics=[‘acc’]
)regressor.fit
(
x_train, 
y_train, 
epochs=EPOCHS, 
batch_size=BATCH_SIZE
)

天气预报:推论

既然模型已经被训练了 500 个时期,我们就可以在准备好的测试集上进行推论了。

x_test = test_set[: n_past, 0]
y_test = test_set[n_past : n_past + n_future, 0]x_test, y_test = np.array(x_test), np.array(y_test)
x_test = np.reshape(x_test, (1, x_test.shape[0], 1))predicted_temperature = regressor.predict(x_test)print('Predicted temperature {}'.format(predicted_temperature))
print('Real temperature {}'.format(y_test))

如果我们对样本数据集中的 30 天进行采样,预测结果及其对应的实际温度将打印如下:

Predicted temperature 
[[47.51087   11.603558   2.5133722  0\.         2.019637 ]]Real temperature 
[9.8 6.6 0.2 0\.  0\. ]

讨论和结论

我们的初始预测器似乎对极端降水水平(如 47 毫米)表现不佳。可以通过以下方式进行一些改进:

  1. 调整历史窗口期以说明季节性(如 120 天而不是 30 天)。
  2. 通过增加更多的 LSTM 层、改变损失函数和增加丢失概率来改进架构,以更好地正则化训练数据。

总之,在天气预报(一般来说,时间序列数据集)的情况下,使用 LSTM 作为改进的基于 RNN 的架构是有趣的。并且能够以及时有效的方式进行天气预报不仅是有益的,而且对于直接或间接依赖好天气的大众来说是至关重要的。

注意:本文提供的数据已经被清理并合并成一个 CSV 文件。如果你想获得 70+印度尼西亚的天气信息,你可以随时 PM 我!

做订阅我的邮件简讯:https://tinyurl.com/2npw2fnz在这里我定期用通俗易懂的语言和漂亮的可视化方式总结 AI 研究论文。

参考

[1] 了解 https://colah.github.io/posts/2015-08-Understanding-LSTMs/ LSTM 网

[2]【https://www.bmkg.go.id/ 印尼气象局:印尼

使用 FOSS4G 和 JavaScript 处理天气模型:最佳实践

原文:https://towardsdatascience.com/weather-model-processing-with-foss4g-and-javascript-best-practices-d583e6dde201?source=collection_archive---------53-----------------------

作者图片

使用免费开源地理软件(FOSS4G)和/或 JavaScript 检索、处理和管理天气模型数据的技巧和诀窍。

一年前我写了《用 FOSS4G 自动化天气模型处理 :经验教训 ,概述了我创建一个使用开源地理软件自动检索、处理和管理天气模型数据的系统的旅程。我已经用这个系统工作了一年,包括为科罗拉多州发布了一个最先进的天气预报网站,并有机会向商业和学术天气预报领域的关键人物学习。

作为分发和使用原始天气模型数据的常见范例的介绍,原始文章中的发现仍然很有用。后续文章在此基础上进行扩展,涵盖了处理这些数据的最佳实践和技术,仅使用免费和开源地理软件(FOSS4G)。还有一些使用 JavaScript 处理这些数据的技巧和诀窍,JavaScript 正在成为一种更普遍的语言,包括在地理信息系统(GIS)领域。

本文假设您已经安装了 GDAL ,并且已经知道从哪里下载天气模型文件以及它们通常是如何构造的。“索引文件”会经常被引用,也就是您经常看到的伴随着grib2文件的.idx文件:

这些文件对于管理大型栅格和可变波段排序非常有用,您应该尽可能地利用它们。

作者图片

1.使用梯度

不直接推荐这一点的原因是它偏离了本文的主题-已经有大量的人在使用 GIS 和地理空间栅格做令人难以置信的事情,目标是帮助在该领域更容易地访问天气模型数据并利用现有的人才。

然而,如果你的重点是纯粹的气象学或更科学的学科,你可能只想使用处理天气模型和其他科学数据的行业标准——GRaDS。该软件有自己的脚本语言,它需要大量的工作来制作看起来像普通桌面 GIS 应用程序中可以轻松生成的质量的地图,因此它代表了一种可能超出 GIS 学科范围的用例。

2.除非需要在 web 地图上绘制数据,否则不要重新投影数据

天气模型有各种各样的投影(通常是某种形式的朗伯共形圆锥曲线),如果不丢失数据或强制插值,就不容易重新投影到 EPSG:4326 或 Web 墨卡托。如果查询重新投影的数据,与原始模型数据相比,您可能会得到不准确的预测。

顶部栅格(NAM 3km 模型)处于其原始投影中。底部栅格是重新投影到 EPSG 的结果:4326。忽略倾斜(底部的图像仍然用顶部图像的投影绘制在地图上),注意原始数据是如何未被充分表示的,例如画圈的像素簇。图片作者。

3.基于 JavaScript 的投影库(如 Proj4js)不能正确地重新投影大多数天气模型的坐标

如果您正在使用 Node.js 查询地理空间栅格(使用类似于 Geotiff.js 的东西),并且您希望在查询纬度/经度坐标时将它们保留在原始投影中,那么 GDAL 提供的 Proj4 和 WKT 字符串可以传递给 proj4js —但是您会注意到重新投影后出现了一些非常严重的空间误差(许多英里,而不是几英尺)。有些转换是 proj4js 做不到的,似乎大多数天气模型预测都属于这一类。

您将需要使用 gdal 绑定( gdal-js —不理想,因为它们需要旧版本的 GDAL)或者调用一个 shell 来调用 GDAL 的gdaltransform以获得更精确的重新投影——或者 JavaScript 之外的另一个重新投影库。为了简单起见,您可以将 grib2 文件加载到 QGIS 中,并使用“提取投影”工具导出一个可以传递给gdaltransform.prj文件。

4.使用 PostGIS out-db 栅格来管理大量文件

如果您以任何程度的规律性处理天气模型数据,您将拥有大量的地理空间栅格,其中包含许多波段。 PostGIS for PostgreSQL 是一个很好的工具来组织这些数据,但是在读取/写入数据本身时太慢了——但是,您可以将栅格作为文件系统上的 GeoTIFF(或任何东西)保存,并从 PostGIS 中将其作为 out-db 栅格进行引用。

5.对于制作处理地理空间天气模型数据的 API 来说,Node.js 是一个不错的选择

使用其他语言作为后端或 API 有很多好处(比如 python,及其 GDAL 绑定),但是 Node.js 越来越流行,它是处理这些数据的可行选择。如果您使用 Postgres 和 GeoTIFF 文件,这是一个可以接受的解决方案,但是如果您预计有巨大的并发需求,您可能会希望采用不同的方法,使用原始二进制文件或极端的缓存技术。对于基于 JS 的方法,您可以使用 Geotiff.js 加载天气模型 GeoTIFF 文件,并以不错的性能查询它们。我写了一篇文章,详细介绍了这里的细节。

6.识别未知波段

NOAA 的 NCEP(通常负责开发和传播天气模型的美国机构)与 GRIB2 格式的使用并不完全一致,这导致了各种 GRIB 解码器,包括 NOAA 自己创建的一些解码器!在撰写本文时,NBMv4 模型显示了未知的谱带,甚至在 NCEP 自己的索引查找文件中也是如此:

然而,GDAL 似乎比其他一些库更难识别波段,因此您的栅格中可能有许多“未知”波段。如果元数据似乎无法描述天气模型参数和/或级别,则尝试找出波段所属的工作流程如下:

  1. 试着在附随里找。grib2 文件的 idx 文件。
  2. 使用美国宇航局的全景数据查看器,它似乎比其他 GRIB 解码器如 degrib 更成功。
  3. 使用 wgrib2 ,这是标准的(也是 GRaDS 中使用的一个选项),但可能很难使用。

Grib2 文件在历史上被辛勤工作的 GDAL 贡献者忽略了一点,但它们在修复我最近在更新的天气模型(如 NBMv4)中发现的一些错误方面非常棒。这些模型应该在 GDAL >3.1 中完全工作,但是旧版本,比如一些 Linux 发行版中的当前上游版本(3.0.4),在处理一些参数(比如积雪)时会出现阻塞。如果您注意到其他问题,请联系 gdal listserv!

7.订阅游牧者列表服务

天气模型的主要分发服务器——NCEP 游牧部落——往往会以相当惊人的频率经历中断,但通常会被排除或很快在列表服务器上发布中断通知。其他重要的通知包括对模型的更改以及对它们的添加或删除,这可能会破坏您的脚本。

8.优化服务器的读/写速度和 RAM,而不是 CPU 速度

一般来说,如果您只是执行天气模型数据的基本转换和简单的分析或查询,那么您将受到在磁盘上读/写数据和将大型栅格文件加载到 RAM 中的能力的限制,而您的 CPU 大部分时间都处于空闲状态。你肯定应该使用固态硬盘。如果你正在做大量的光栅文件重投影,CPU 将会更重要。如果你要存储全球天气模型或者一些更高级的模型(比如 NAM 或者 HRRR ),你需要几兆字节的硬盘空间。

9.“表面”高度完全取决于模型的分辨率

在不同空间分辨率的模型之间比较表面上的两个值(例如温度)是不公平的比较,尤其是在崎岖的地形中。每个模型都有一个基本的 DEM,通常可以从“分析”预测小时(也就是零)中提取。例如,根据相应的索引文件,此数据在fh00 / analysis 的 NAM 模型中可用:

10.索引文件可能会将两个变量视为同一字节范围的一部分

你可能会在风的ugrdvgrd分量中遇到这种情况。

您只能同时获得这两个变量,这意味着如果您的检索/处理脚本完全依赖于索引文件中每一行的一个变量,事情将会出错。当您检索这个字节范围时,您将得到一个双波段栅格,第一个波段属于ugrd,第二个属于vgrd

11.有些模型的投影经度范围为 0 到 360 度

这似乎是全球通用的模式,如 GFS 和 GEFS。当你开始使用这个投影时,奇怪的事情会发生。在处理这些数据之前,您可能想用--config CENTER_LONG 0(或者 Python 绑定中的config=["CENTER_LONG 0"])调用gdalwarp

天气预测:“经典”机器学习模型 Vs Keras

原文:https://towardsdatascience.com/weather-predictions-classic-machine-learning-models-vs-keras-41604f8553e2?source=collection_archive---------25-----------------------

在深度学习中应用管道和网格搜索等有用的 Scikit-learn 功能的实际例子。

照片:蔡展汉

在花了 2019 年的大部分时间学习机器学习的基础知识后,我热衷于开始尝试一些基本的深度学习。

虽然不缺乏像 Keras 这样的用户友好型库入门的伟大教程,但要找到通过展示管道和网格搜索等 Scikit-learn 功能如何在深度学习中发挥作用来为初学者连接这些点的例子要难得多。

因此,我决定将我在这个主题上找到的材料收集在一起,并匆匆制作了一系列笔记本,希望能够帮助那些希望投身深度学习的新来者。

在这些笔记本中,我使用了机器学习和深度学习技术的混合,试图预测 2019 年 12 月新加坡的降雨模式。这些模型是根据新加坡从 1983 年 1 月 1 日到 2019 年 1 1 月底 37 年的天气数据进行训练的。

笔记本、数据和假设

这是我正在进行的一系列数据科学项目的 Github repo ,使用的是新加坡的历史天气数据。这个帖子的具体笔记本可以在这里,这里这里,这里这里,这里这里找到。

为了简洁起见,我不会在这篇文章上粘贴任何代码。这些笔记本简单易懂,在 Github 上或通过直接下载更容易阅读。

这篇文章的数据来自新加坡气象局的网站。为了保持项目的简单,它被保持为一个二元分类问题,以预测某一天是多雨(1)还是干燥(0)。我还选择不丢弃离群值,以便将模型暴露给尽可能多的数据。

我使用的数据集跨越了 37 年,但它包含了不到 13,500 行数据。有理由问你是否需要像这样的数据集进行深度学习,它是否一定会产生更好的结果。

这些都是合理的担忧,尤其是考虑到所需的额外时间和资源。但是我决定把它们放在一边,因为这里的目标是实验和学习。

结果

我讨厌仅仅为了看到结果而滚动冗长的博客帖子,所以让我们快速看一下 XGB 模型在预测 2019 年 12 月新加坡的降雨/无雨模式时如何对抗 Keras 分类器:

Keras 模型比 XGB 模型表现稍好,在 31 天中正确地将 26 天划分为下雨/不下雨。XGB 模型管理了 31 个中的 25 个。

Keras 和 XGB 模型在回忆分数方面都有相同的弱点(与 precision 和 f1 分数相比相对较低),即正确分类雨天的能力。

尽管如此,总的来说还不算太差。有了更丰富的气象数据,如湿度和大气压力,我们可能会得到更准确的预测。

现在,让我们分别深入研究每种方法。

使用逻辑回归和 XGB 分类器的“经典”机器学习方法

预测建模包括尝试许多不同的模型,看看哪一个效果最好,以及微调每个模型的超参数,以获得最佳组合。

Scikit-learn 的管道和网格搜索功能允许您有效地组织这两项任务并一次运行它们。在笔记本 5.1 中,我选择用逻辑回归模型对抗 XGB 分类器。

您可以在同一管道中包含更多的模型,或者增加 XGB 超参数的数量来调优。但是时间和资源的权衡是你必须仔细权衡的。我选择了 LogReg 和 XGB 模型来说明在这些任务中可能遇到的权衡取舍的极端情况。

LogReg 模型只需要几秒钟就可以完成一次像样的网格搜索,而 XGB 分类器需要 7 个小时(在 6 核 2018 Mac Mini 上)才能完成超过 5 个超参数的网格搜索。

XGB 模型给出了稍微好一点的分数,并且可能通过更彻底的网格搜索得到改进。但是这 0.02 分的提升值得付出额外的努力吗?在这种情况下很有争议。

在任何情况下,我都继续使用 XGB 模型,尽管它的性能只比 LogReg 模型稍好一点。让我们来看看 XGB 对 2019 年 12 月预测的困惑矩阵:

XGB 模型正确地将 31 天中的 25 天划分为多雨/干旱天,准确率为 0.8。

模型错误地预测两天后会下雨,而实际上是晴天(误报)。它还错误地预测了 4 个晴天,而实际上这几天有雨(假阴性)。

就回忆分数而言,XGB 模型是最弱的,在这种情况下,这意味着它正确识别雨天的能力(14 分中的 10 分)。深度学习模型能做得更好吗?

带网格搜索的 Keras 分类器

人们可以通过多种方式开始尝试深度学习模型。我想从小处着手,看看我是否能把我在 Scikit-learn 中学到的东西与新技术结合起来。

鉴于 Scikit-learn API (用于分类和回归)的两个包装器,Keras 很快成为一个不错的选择。我还依靠两个优秀的在线帖子(这里这里)来指导我的笔记本 5.2 的代码。

工作流本质上类似于常规的 Scikit-learn 方法,尽管有一个新步骤需要一点反复试验:定义创建和返回 Keras 顺序模型的函数。

根据您想要优化的超参数的数量,函数的结构必须相应地进行调整。在这篇文章中,我选择调整隐藏层的数量、神经元的数量、优化器、退出率、批量大小和时期的数量。

pipeline/gridsearch 结构本质上是相同的,只是需要将您定义的 Keras 函数传递给 Keras 分类器的“build_fn”参数。

在我的机器上用这些设置进行网格搜索花了 18 个多小时(仅限 CPU)。如果你想要更快的审判,相应地调整。让我们看看优化的 Keras 分类器预测的混淆矩阵:

Keras 模型比 XGB 模型表现得更好,它正确地预测了多一天的多雨天气,即它正确地将 31 天中的 26 天划分为多雨/少雨天,而 XGB 模型为 25 天。

模型错误地预测两天后会下雨,而实际上是晴天(误报)。它还错误地预测了 3 个晴天,而实际上这几天有雨(假阴性)。

与 XGB 模型一样,Keras 模型在回忆分数方面也是最弱的,在这种情况下,这意味着它正确识别雨天的能力(14 分中的 11 分)。让我们在验证集(2019 年 12 月的天气数据)上比较 XGB 和 Keras 模型的预测指标:

Keras 模型明显优于 XGB 版本,但网格搜索花费的时间是 XGB 的两倍多。在现实世界中,性能的提高意味着那个月的 31 天天气预报正确率增加了一天。

我最近发现了关于 Keras Tuner 的情况,并渴望看到它是否能提供比 Scikit-learn/grid 搜索方法更好的结果。

Keras 调谐器

至少有 4 个调谐器可供选择,但我选择尝试只 Hyperband 和 RandomSearch 调谐器。我还选择使用 HyperModel 子类方法,这使得两个调谐器的测试更加有效。

我改编了两个有用的在线帖子的代码。我选择了以下参数进行调整:隐藏层数、辍学率、学习率和动量。两个调谐器的性能水平相当:

带 Hyperband 的 Keras 调谐器(左)和带 RandomSearch 的 Keras 调谐器(右)

与通过 Scikit-learn 的网格搜索过程相比,Keras Tuner 非常快。不幸的是,尽管进行了几轮试错,我还是无法让精度水平超过 0.7。

可能还有很多我不知道的使用 Keras 调谐器的艺术,但我将不得不把它留给将来的更合适的数据集。

结束注释

正如许多在线文章所表明的那样,你正在处理的数据的性质和数量在很大程度上决定了你是采用“经典”的机器学习模型还是使用深度学习方法。

但是,很难获得一个大规模的真实世界数据集,它很容易进行深度学习。大规模数据集所需的时间和计算资源对初学者来说可能也不实际。

简而言之,不要让完美妨碍了美好。在这一点上,学习过程比结果更重要。在从事这个项目的过程中,我获得了一些好的经验,希望这些笔记本能够帮助任何想要尝试深度学习的人。

和往常一样,如果您发现代码中有任何错误,请 ping 我@

推特: @chinhon

领英:【www.linkedin.com/in/chuachinhon

如果你对研究新加坡的天气数据集感兴趣,这里是我使用相同记录的早期项目:

编织与人工智能

原文:https://towardsdatascience.com/weaving-and-ai-35e4801f0473?source=collection_archive---------60-----------------------

过去的技术能告诉我们未来的技术

照片由 s2 artUnsplash 上拍摄

在人类历史的大部分时间里,女人总是与编织联系在一起。编织是制作服装不可或缺的一部分,而制作服装是妇女操持家务的核心角色。甚至像雅典娜这样的女神也与编织有着密切的联系(正如我们在雅典娜和阿拉克尼的故事中看到的)。在这篇维基百科文章中,你可以看到在许多文化中,编织和女性是如何在他们的神话和民间传说中紧密交织在一起的。然而,这种联系并没有延续到今天,这要归功于纺织的自动化,特别是提花织机,它引入了用机器代替人织布的理念。

在赛迪·普兰特的《未来织布机:编织妇女和控制论》一书中,她讨论了玛格丽特·米德对尼日尼亚 Tiv 人的研究。她特别指出,编织的机械化导致了家庭的巨大混乱,而妇女的主要任务之一实际上就是编织。这使她得出这样的结论:

米德的研究表明编织是 Tiv 女性身份的一部分;在其他文化中,洗衣、捶打和挑水可能会起到这种作用,在这些文化中,洗衣、捶打和挑水就像织布一样,永远不仅仅是实用的任务。(第。56)

换句话说,编织不仅仅是生产布料。编织是 Tiv 女性身份的一部分,是她定义自己的方式之一。工厂继续讨论机械化编织的含义如下:

将机械引入到这些工作中所造成的家庭关系的破裂打破了女性身份的风景:机械化节省了时间和劳动力,但这些都不是问题所在(pg。56)

对于一个 Tiv 女性来说,编织不仅仅是结果。编织不仅与最终产品有关,也与制作它的人有关。所有这些都使电厂面临一个新技术引入带来的核心问题:

如果女人不是织工和挑水工,她们会是谁呢?

这在现在看来可能是一个荒谬的问题,但在当时,这是一个非常合理的问题。编织是女性身份不可或缺的一部分,现在这项工作被机器取代了,它们现在是谁呢?

这个问题听起来很荒谬,因为我们知道女人不仅仅是挑水工和织布工。虽然他们可以选择专注于家务和呆在家里,但他们不会局限于此。至少,他们不再像以前那样局限于此。总的来说,我们当然承认女性不仅仅是由她们的家务技能来定义的。

这跟 AI 有什么关系?

任何关于人工智能的报道都是两极分化的。要么是拯救世界的东西,要么是终结世界的东西。这是我在以前的文章中讨论过的事情,也是在关于构建大数据的新闻语料库研究中详细讨论过的事情。其中一件被讨论为负面的事情是,人工智能将自动化一切,并取代我们所有的工作。每个人都或多或少听说过,不管是认真的还是开玩笑的,“机器人将会取代我们的工作。”这被认为是担忧和焦虑的巨大原因。一旦技术做了他们能做的事情,人们就会失业,特别是如果技术更高效、更不容易出错或者可以工作更长时间。

虽然我不会说这些担忧完全不合理,但我确实认为这是另一个“天没有塌下来”的例子。当然,有些工作将不复存在,因为机器可以像人一样做好这些工作。但这并不是人工智能独有的,这只是人类进步的方式。此外,通过关注我们失去的东西,我们忘记了关注我们可能得到的东西。这就是机械化编织的出现可以向我们展示我们自己的未来的地方。

让妇女选择离开家庭领域有许多原因。其中一个巨大的原因是因为有足够的技术可以自动做她过去必须手动做的事情。她不用织布,甚至不用做自己或家人的衣服。当我们获得为我们做事的技术时,我们能够完成更多的事情。女性能够做更多的事情,完成更多的事情,因为管理一个家实际上比过去需要更少的工作。这并没有导致整个性别在家里萎靡不振,几乎无所事事。这导致了性别角色的重新定义和妇女在社会中更多的选择。

人们很容易对未来感到焦虑,但事实是,太阳底下没有新鲜事。虽然技术本身可能是新颖的,但它的影响和潜力我们已经见过很多次了。通过回顾看似不起眼的编织例子,我们可以看到机械化和自动化改变人类社会角色的例子。当然有人会说自动化失去了一些东西,作为一个自己编织和制作衣服的人,我不能说我完全不同意他们的观点。然而,我不是出于必要才编织的,正因为如此,我可以自由地做更复杂、更耗时的项目。同样地,自动化能够,也确实,导致人类的创造力和创新,因为他们不局限于单调的任务。另外,我想我们都知道有人的职位不久前还不存在。我们可能会在某些领域失去工作,但我们也会收获很多。

[1]植物,赛迪。"未来织机:编织妇女和控制论."《身体与社会》1,第 3-4 期(1995 年 11 月):45-64 页。doi:10.1177/1357034 x 95001003003。

[2]玛丽亚·克里斯蒂娜·帕戈诺尼。构建大数据:语言和话语方法。斯普林格,2019。

网络分析数据仓库:谷歌分析和搜索

原文:https://towardsdatascience.com/web-analytics-data-warehouse-google-analytics-and-search-f2d244e110c9?source=collection_archive---------18-----------------------

在本教程中,我们将看到如何创建一个数据仓库和一个依赖于 SEO(搜索引擎优化)的内容营销仪表板。它将利用和混合来自谷歌分析(跟踪你网站的流量)和谷歌搜索控制台(你的网站在谷歌搜索上的表现)的数据。

结果将是这个 Google Sheet dashboard (你可以点击链接或者看下面的截图)自动更新。这是来自我的博客DataIntoResults.com的直播,它运行在 WordPress 上,但是任何内容营销平台都可以。

这篇文章将包含许多主题:设置数据仓库和 ETL 基础设施,从 Google Analytics 和 Google Search 获取数据到数据仓库,对数据建模以便使用,以及在 Google Sheets 中设置一个漂亮的仪表板。

我们开始吧!

什么是网络分析数据仓库?

我们需要问自己的第一个问题是,我们想要实现什么?建立 web analytics 数据仓库的全部意义在于能够获得完全符合您需求的定制报告。如果没有,你也可以使用谷歌分析前端。

在这里,我将把我的兴趣缩小到两个问题上:什么与我的受众相关,以及如何让我的文章更加 SEO 友好。尽管如此,这篇文章的目的是让你有足够的数据来更加关注你的具体情况。

内容是否与受众相关?

哪些内容是观众感兴趣的?我不做 clickbait,所以我的文章往往比较长。因此,怀疑兴趣的一个方法是看有多少访问者阅读了整篇文章,而不是那些在文章开始就停下来的访问者。在 Medium 中有一个很酷的特性叫做读取率(见下面的截图)。我们将与谷歌分析这个功能。

第二个感兴趣的指标是谷歌搜索上显示的内容的点击率(CTR)。如果你的内容被推到人们面前,但他们没有点击,这可能是因为你的主题不正确,或者你的标题和描述不够有趣。

内容搜索引擎优化准备好了吗?

有相关的内容是很好的,但是如果没有一种方法把它放在观众面前,它是没有用的。 SEO 营销的基础是让人们正在寻找的一些关键词的内容处于有利位置

例如,这些天我在搜索“postgresql 数据科学”上排名很好(在 DuckDuckGo 上排名第一)。这是一个合理的关键字组合,流量和排名第一有助于推动游客。

尽管如此,总的来说,该页面位于第 27 位。挖掘了一下,我发现了一些既相关又有一些流量(新内容创作的机会)的关键词组合。

设置数据仓库基础设施

现在我们知道了我们想要什么,我们需要在基础设施上花些时间。需要帮助的话可以联系我。让我们为您未来的发展打下坚实的基础。

我们将使用一个 PostgreSQL 数据仓库(开源)和数据酿酒厂 ETL (我的一个产品,也是开源的)。PostgreSQL 将是存储和处理数据的地方,而 Data Brewery 将把数据从谷歌服务转移到数据库并管理工作流。

有两个数据源,Google Analytics 和 Google Search 将存储在 PostgreSQL 数据仓库中(每个都在一个特定的模块中)。然后,我们将把它们融合到一个名为内容营销的新模块中。最后,我们将数据放入 Google 工作表中。这里没什么特别的。

你可以在 GitHub 上找到完整的 Data Brewery 项目(在文件夹 v1 中)。

我不会详细讨论实现,但是数据存储目录包含数据源的视图。例如,下面是谷歌搜索的数据存储。它定义了一个名为 seo_pages 的表(虚拟的),该表将包含一些关于过去 10 天的信息(有多少印象,点击和每页每天的平均位置)。

然后,数据被集成到归档模块中。

运行该流程(使用 shell 命令ipa run-process update)后,将填充表 google_search.seo_pages。

Google Sheets 数据存储用于输出数据,每个表都有一个 SQL 查询要在数据仓库中执行,以便填充 Google Sheets 中的相应区域。

如果你想了解更多关于整合配置的信息,你可以阅读来自 Data BreweryGoogle AnalyticsGoogle SearchGoogle Sheets 文档页面。

数据建模

既然我们在 web analytics 数据仓库中有了原始数据,我们可能希望在仪表板中很好地呈现它。为此,我们将利用 SQL 语言(大多数数据库的说法)。

第一次查询

让我们从一些简单的东西开始(但绝不简单),每个国家每月的用户图表。

你可能会看到,我们将展示的国家数量限制为五个,并将其余的国家重新组合在另一个国家。这对可读性很重要。但是你必须定义你如何选择五个重要的国家。它可以是静态选择,也可以是动态选择。在这种情况下,我选择了前一个月最大的 5 个国家。

正如您在下面看到的, user_country 部分(第一个选择)很简单,其余的只是 5 个国家的选择。

正如您在数据—用户国家表中看到的,栏 A 到栏 C 由 ETL 填充。在此基础上,我们使用交叉表来生成图表。

正如你所看到的,这并不简单,因为我们想展示一些好的东西,我们操纵原始数据,最后是因为谷歌工作表是有限的。

但是让我们变点魔法吧。

读取比率

请记住,阅读率是阅读整个内容的访问者数量除以该内容的访问者数量。第二部分很简单,因为它在谷歌分析上是默认提供的。

对于第一部分,阅读全文的访问者数量,我们将使用 Google Analytics 的事件机制。我推荐使用谷歌标签管理器,它允许轻松配置谷歌分析事件。

我定义了下面的标签(参见截图)。我们将有一个名为 Scroll 的事件类别,它将在页面滚动时被触发(我已经设置了 25、50、75 和 90%)。参数{{UA DataIntoResults}}是我的 Google Analytics 视图 ID。

Google _ analytics . events表中,我们将找到这些事件。

请注意,动作值与页面相同。这是因为我们将使用 unique_events 列。如果动作是一个像“滚动”一样的常量,那么 unique_event 将在每次访问时只计算一次,即使访问者阅读了许多完整的帖子。

现在,开始行动,或者 SQL 查询。我想强调三件事:

  • 原始数据必须清理一点,页面有时有参数。例如,/mypage/mypage?parameter=1不是谷歌分析的同一个页面。从商业角度来看,大多数时候都是一样的。代码regexp_replace(page, '[?&].*$', '')将会清除它(第 4 行和第 9 行)。
  • 我们过滤数据,只保留 2020 年 1 月 15 日之后的数据。滚动跟踪是在那一天实现的(第 20 和 29 行)。
  • 我们使用 75%的阈值来定义一篇文章为已读。合适的值取决于你的网站布局(第 18 行)。

这是我们的阅读率:

最后一个焦点:那些迷你图

我是爱德华·塔夫特的超级粉丝,他在探索信息密度的过程中发明了迷你图这个术语。迷你图无需占用太多空间即可提供时间上下文。

例如,我们使用印象指标(节选如下),它反映了在谷歌搜索上看到每个页面的人数。通过为过去 13 个月的趋势添加迷你图,我们提供了更多价值。我们可以看到,虽然第二篇文章( PostgreSQL for Data Science )上升缓慢,但第一篇文章( Jupyter for Complex Python 和 Scala Spark project)却迅速获得了更多的印象。最后一个(数据仓库宣言),印象不多,从来没有过。这只是不是搜索引擎优化的好内容。

现在坏消息是,每页绘制 13 个数据点需要 13 列,这在 SQL 中有点麻烦。我们首先创建一个参考表,提供每个月(过去 13 个月)的订单(从 1 到 13)。这是在第 8 到 11 行完成的。然后,从第 42 行开始,我们用一个关于月份的条件来聚集数据。这允许将数据从行旋转到列。

现在每个指标有 13 列(浏览量、浏览量、点击量和位置)用于每个页面(每个页面是一行),我们可以在 Google Sheet 中绘制这些小的迷你图。

请注意,除了数据点选择之外,您还可以传递参数来控制行为。你可以在 Google Sheets 文档中阅读更多关于迷你图的内容。

初始化并自动刷新

默认配置从谷歌分析和谷歌搜索中查找最近 10 天的信息。当您有一份过去 13 个月的报告时,这显然不方便(您需要等待 13 个月)。

因此,我们将使用 init.conf(见下文)来使用ipa run-module -c init.conf update引导数据仓库。这将需要一些时间,因为我们要获取最近 400 天的数据。

最后,我们希望 web 分析数据仓库在没有人工交互的情况下被刷新。最简单的方法是使用调度程序,例如 Linux 下的 cron。在下面,您可以看到每天在 UTC 时间早上 5 点更新数据仓库的命令。

# m h dom mon dow command 0 5 * * * cd ~/dwh/web-analytics-data-warehouse/v1 &amp;&amp; ~/app/ipa/bin/ipa run-process update

因此,我们的 Google Sheet dashboard 每天都会更新(每天不会有太大变化,因为它是一份月度报告)。

恭喜,我们现在有了一个完全可操作的 web 分析数据仓库!你会添加什么使它更相关?

原载于 2020 年 1 月 22 日

用 Python 开发 Web 应用程序

原文:https://towardsdatascience.com/web-app-development-in-python-469e1cf2116b?source=collection_archive---------17-----------------------

构建前端用户体验简介

来自 Unsplash 的照片

烧瓶是什么?

Flask 是一个帮助我们开发 web 应用程序的轻量级 Python 库。我已经在个人项目中使用 Flask 来构建交易仪表板,并在专业环境中为医院部署人工智能工作流管理系统。在本文中,我想介绍 Flask,并演示开始构建自己的 web 应用程序是多么容易。

按指定路线发送

理解 Flask 如何工作的最好方法是亲自动手使用它。之后,您将了解如何构建 web 应用程序的各个部分。首先,让我们导入并创建一个 Flask 实例。

当我们最终运行 Flask 实例并在浏览器中连接到它时,它将拥有一个默认主机( 127.0.0.1localhost )和一个默认端口( 5000 )。要在浏览器中连接到我们的 web 应用程序,我们需要键入 URL 和端口(localhost:5000)以及一个规则来帮助我们检索适当的内容。因此,让我们创建一个新的 URL 规则,这基本上相当于一个主页。当我们在浏览器中键入 localhost:5000 时,它将检索该函数返回的数据。

现在我们需要一些东西来展示。

模板

模板是 HTML,它将由伴随 URL 规则的函数呈现并返回给用户。在这种情况下,home 函数将负责呈现和返回主页模板。所有模板都应该存储在名为 templates 的文件夹中,该文件夹与保存 Flask 实例的脚本位于同一文件夹中。HTML 可以是您喜欢的任何东西,对于这个例子,我将创建一个简单的网格布局,类似于我用来构建交易仪表板的布局。

为了让 home 函数呈现并返回这个模板,我们可以将下面的代码添加到 home 函数中。

每当我们到达主页(localhost:5000)时,home 函数将呈现并返回 home HTML 模板。

将 Python 变量传递给 HTML

拥有 Python 后端的全部目的是在前端向用户显示相关数据。为此,我们可以使用 Jinja。Jinja 允许我们轻松地引用 Python 变量,并编写 Python 代码来控制我们选择如何在 HTML 中显示这些变量。首先,我将在 Python 中创建两个变量: first_namelast_name 。然后我将通过我们的 home 函数中的 render_template 把它们传递给模板。我将把 Python 变量传递给 fnln——这就是我们在 HTML 中引用 first_namelast_name 的方式。

我想在第一列显示变量,在第二列显示变量。为此,我将把对这些变量的引用, fnln,用花括号( {{ fn }},{{ ln }} )包装起来,向 HTML 表明它们将从 Python 传递到模板。

这将使用 Python 变量呈现主 HTML 模板。

发射

要启动我们的 web 应用程序,我们所要做的就是运行 Flask 的实例。

运行 Python 脚本后,在浏览器中输入 localhost:5000。

我把我的文本放在 h1 标签中以提高可视性

这就是你用 Python 和 Flask 构建的第一个 web 应用程序。

实时部署

一个非常典型的问题出现了:我们如何在线部署 Python web 应用程序?有很多方法可以做到这一点。然而,如果你正在寻找一个具体的答案,我会建议看看亚马逊网络服务的弹性豆茎。这就是我部署所有 web 应用程序的方式。

[## AWS 弹性 Beanstalk -部署 Web 应用程序

易于开始,不可能超越 AWS 弹性 Beanstalk 是一个易于使用的服务,用于部署和扩展 web…

aws.amazon.com](https://aws.amazon.com/elasticbeanstalk/)

分拣机器人—第 1 部分

原文:https://towardsdatascience.com/web-application-to-control-a-swarm-of-raspberry-pis-with-an-ai-enabled-inference-engine-b3cb4b4c9fd?source=collection_archive---------34-----------------------

一个基于网络的解决方案,用于控制一群覆盆子 pi,具有实时仪表盘、深度学习推理机、一键式云部署和数据集标记工具。

这是由三部分组成的 SorterBot 系列的第一篇文章。

GitHub 上的源代码:

  • 控制面板 : Django 后端和 React 前端,运行在 EC2 上
  • 推理机:运行在 ECS 上的 PyTorch 对象识别
  • 树莓:控制机械臂的 Python 脚本
  • 安装程序 : AWS CDK、GitHub 动作和一个 bash 脚本来部署解决方案
  • 标签工具:使用 Python 和 OpenCV 的数据集标签工具

我最近在 SharpestMinds 完成了一个人工智能导师项目,其核心要素是建立一个项目,或者更好的是一个完整的产品。我选择后者,在这篇文章中,我写了我构建了什么,我是如何构建的,以及我一路走来学到了什么。在我们开始之前,我想特别感谢我的导师托马斯·巴贝吉(CTO@ProteinQure)在这段旅程中给予的宝贵帮助。

在考虑构建什么的时候,我想到了一个基于网络的解决方案来控制一群树莓 pi,它具有实时仪表盘、深度学习推理引擎、一键云部署和数据集标记工具。Raspberry Pis 可以连接任何传感器和执行器。他们收集数据,将其发送到推理引擎,推理引擎对数据进行处理,并将其转化为执行器可以执行的命令。还包括一个控制面板来管理和监控系统,同时子系统使用 WebSockets 或 REST API 调用相互通信。

作为上述总体思想的实现,我构建了 SorterBot,其中传感器是一个摄像头,执行器是一个机械臂和一个电磁铁。该解决方案能够根据金属物品的外观对其进行自动分类。当用户开始一个会话时,手臂扫描它前面的区域,找到它所及范围内的物体和容器,然后自动将物体分成与找到的容器一样多的组。最后,它将对象移动到它们对应的容器中。

SorterBot 自动拾取对象(图片由作者提供)

为了处理手臂摄像头拍摄的图像,我基于脸书 AI 的 Detectron2 框架构建了一个推理机。当图片到达进行处理时,它在该图像上定位项目和容器,然后将边界框保存到数据库。在给定会话中的最后一张图片被处理之后,项目被聚类到与找到的容器一样多的组中。最后,推理引擎生成命令,这些命令指示手臂将相似外观的项目移动到同一个容器中。

为了更容易控制和监控系统,我构建了一个控制面板,前端使用 React,后端使用 Django。前端显示已注册的 arm 列表,允许用户启动会话,还显示现有会话及其状态。在每个会话下,用户可以访问逻辑分组的日志,以及工作区的前后概览图像。为了避免为 AWS 资源支付不必要的费用,用户还可以选择使用标题中的按钮来启动和停止运行推理引擎的 ECS 集群。

控制面板的用户界面(图片由作者提供)

为了让用户更容易看到手臂在做什么,我使用 OpenCV 将相机在会话期间拍摄的照片拼接在一起。此外,在手臂将物体移动到容器后拍摄另一组照片,因此用户可以看到该区域的前/后概览,并验证手臂实际上将物体移动到容器。

由会议图像拼接而成的概览图像(作者提供的图像)

后端通过 WebSockets 和 REST 调用与 Raspberry Pis 通信,处理数据库并控制推理引擎。为了能够在更新发生时从后端进行实时更新,前端还通过 WebSockets 与后端进行通信。

由于该解决方案由许多不同的 AWS 资源组成,手动提供它们非常繁琐,所以我利用 AWS CDK 和一个冗长的 bash 脚本自动化了部署过程。要部署该解决方案,必须设置 6 个环境变量,并且必须运行一个 bash 脚本。该过程完成后(大约需要 30 分钟),用户可以从任何 web 浏览器登录到控制面板,并开始使用该解决方案。

Web 应用程序

从概念上讲,通信协议有两个部分。第一部分是一个重复的心跳序列,arm 定期运行该序列,以检查是否为启动会话做好了一切准备。第二部分是会话序列,负责跨子系统协调整个会话的执行。

说明解决方案不同部分如何相互通信的图表(图片由作者提供)

心跳序列

第一部分开始执行的点用绿色矩形标记。作为第一步,Raspberry Pi ping web socket 连接到推理引擎。如果连接是健康的,它会跳到下一部分。如果推理引擎显示为脱机,它会从控制面板请求其 IP 地址。在控制面板返回 IP(或者如果推理引擎实际上是离线的,则返回“假”)之后,它试图建立与新地址的连接。这种行为使得推理引擎在不使用时可以关闭,从而大大降低了成本。它还简化了手臂的设置,这在使用多个手臂时尤其重要。

不管与新 IP 的连接是否成功,结果都会与 arm 的 ID 一起报告给控制面板。当控制面板接收到连接状态时,它首先检查数据库中是否已经注册了 arm ID,并在需要时进行注册。之后,连接状态被推送到 UI,其中状态 LED 以绿色或橙色亮起,分别表示连接是否成功。

出现在用户界面上的手臂,带有开始按钮和状态灯(图片由作者提供)

在用户界面上,状态 LED 旁边有一个“播放”按钮。当用户点击该按钮时,手臂的 ID 被添加到数据库的列表中,该列表包含应该开始会话的手臂的 ID。当 arm 检查连接状态,并且该状态为绿色时,它会检查其 ID 是否在该列表中。如果是,ID 将被删除,一个响应将被发送回 arm 以启动会话。如果不是,则发送回一个响应来重新启动心跳序列,而不启动会话。

会话序列

手臂的首要任务是拍照进行推断。为此,手臂移动到推断位置,然后开始在其底部旋转。它每隔一段时间就停下来,然后相机拍一张照片,直接以字节的形式发送给推理机,使用 WebSocket 连接。

推理机的高层图(图片由作者提供)

当从 Raspberry Pi 接收到图像数据时,图像处理开始。首先,从字节解码图像,然后产生的 NumPy 数组用作 Detectron2 对象识别器的输入。该模型输出已识别对象的边界框坐标以及它们的类别。坐标是距图像左上角的相对距离,以像素为单位。这里只进行二元分类,这意味着一个对象可以是一个项目或一个容器。项目的进一步聚类在后面的步骤中完成。在处理结束时,结果被保存到 PostgreSQL 数据库,然后图像被写入磁盘供矢量器使用,并存档到 S3 供以后参考。保存和上传图像不在关键路径中,所以它们在一个单独的线程中执行。这降低了执行时间,因为序列可以在上载完成之前继续。

当在 Detectron2 的 model zoo 中评估模型时,我选择了更快的 R-CNN R-50 FPN,因为与其他可用的架构相比,它提供了最低的推理时间(43 ms)、最低的训练时间(0.261s/迭代)和最低的训练内存消耗(3.4 GB),而没有放弃太多的准确性(41.0 box AP,是最佳网络的 box AP 的 92.5%)。

矢量器的高级图(图片由作者提供)

在所有的会话图像已经被处理并且生成会话命令的信号到达之后,将这些图片拼接在一起在单独的过程中开始,为用户提供“之前”的概览。与此同时,从数据库中加载属于当前会话的所有图像处理结果。首先,使用随请求发送的特定于 arm 的常数将坐标转换为绝对极坐标。常数 r 代表图像中心和手臂基轴之间的距离。相对坐标( xy 在下图中)是距离图像左上角的像素距离。图像拍摄的角度用 γ 表示。δγ表示给定项目与图像中心之间的角度差,可以使用下图中的公式 1) 计算。项目的第一个绝对极坐标(角度, γ' ),可以简单地用这个等式计算:γ' =γ+δγ。第二个坐标(半径,r’),可以用图上的公式 2) 计算。

用于将相对坐标转换为绝对极坐标的绘图和方程(图片由作者提供)

在坐标转换之后,属于相同物理对象的边界框由它们的平均绝对坐标代替。

在矢量器的预处理步骤中,加载前一步骤中保存到磁盘的图像,然后围绕每个对象的边界框进行裁剪,从而生成每个项目的小图片。

围绕其边界框裁剪的对象示例(作者提供的图像)

这些图片被转换成张量,然后添加到 PyTorch 数据加载器中。一旦所有的图像被裁剪,所创建的批次由矢量器网络处理。选择的架构是 ResNet18 模型,它适合这些小尺寸的图像。PyTorch 钩子被插入到最后一个完全连接的层之后,因此在该层的每个推理步骤的输出中,512 维特征向量被复制到网络外部的张量。在矢量器处理了所有的图像之后,得到的张量被直接用作 K-Means 聚类算法的输入。对于其他所需的输入,即要计算的聚类数,从数据库中插入已识别容器的简单计数。这一步输出一组配对,表示哪个项目进入哪个容器。最后,这些配对被替换为发送到机械臂的绝对坐标。

这些命令是表示项目和容器的坐标对。机械臂一个接一个地执行这些动作,利用电磁铁将物体移动到容器中。

物体被移动后,手臂拍摄另一组照片进行拼接,作为手术后的景观概览。最后,机械臂复位到初始位置,会话完成。

感谢您的阅读,如果您有任何问题、意见或建议,请告诉我!

在下一部分,我将写关于装配和控制机械臂。

未完待续第二部……

分拣机器人—第二部分

原文:https://towardsdatascience.com/web-application-to-control-a-swarm-of-raspberry-pis-with-an-ai-enabled-inference-engine-part-2-73804121c98a?source=collection_archive---------24-----------------------

一个基于网络的解决方案,用于控制一群覆盆子 pi,具有实时仪表盘、深度学习推理机、一键式云部署和数据集标记工具。

我最近在 SharpestMinds 完成了一个人工智能导师项目,其核心要素是建立一个项目,或者更好的是一个完整的产品。我选择后者,在这篇文章中,我写了我构建了什么,我是如何构建的,以及我一路走来学到了什么。

上接第 1 集……

这是由三部分组成的 SorterBot 系列的第二篇文章。

GitHub 上的源代码:

  • 控制面板 : Django 后端和 React 前端,运行在 EC2 上
  • 推理机:使用 PyTorch 进行对象识别,运行在 ECS 上
  • 覆盆子:控制机械臂的 Python 脚本
  • 安装程序 : AWS CDK、GitHub 动作和一个 bash 脚本来部署解决方案
  • 标签工具:使用 Python 和 OpenCV 的数据集标签工具

机械臂

组装前的机器人(作者拍摄)

来自全球速卖通的机械臂没有特定的品牌,被宣传为 DIY 玩具,这使它成为一个负担得起的选择,只花了我 118 美元(40 美元的关税)。由于用机器人手臂抓取物体需要很高的精度,我不可能指望这个价格类别的手臂,我决定使用磁铁将物体移动到容器中。我花 11 美元从 Grove 订购了一个,专门为树莓派设计的。它自带控制电子设备,因此可以使用 GPIO(通用输入/输出)引脚来开关它。至于相机,我花了 45 美元买了一台黑色派 V2 相机,安装起来也很容易。为了运行我的软件并控制上述所有设备,我购买了最新版本的树莓 Pi,这是树莓 Pi 4 Model B,内存为 4 GB。我以 130 美元的价格订购了一个套装,连同 SD 卡、外壳、散热器和电源适配器。硬件总共花了我 344 美元。

控制手臂

手臂运到时是碎片,我不得不自己组装。我原以为这不成问题,但这比我想象的要有挑战性。首先,说明书是中文的,但是有图片。我没有任何问题地完成了最初的几个步骤,然后零件的图片开始出现在我没有的说明中。起初我认为我的工具包不完整,但后来我注意到我有类似的零件,但大小不同,孔在不同的地方,等等。我看了看手册所在的网站,还有一些其他型号,其中一些型号的零件与我的完全相同。我试图弄清楚我是否会收到一个不同的模型,但不幸的是没有:我有来自不同手臂的混合零件。从这一点来看,说明是完全无用的。因为手臂用了将近一个月的时间才到达,所以订购一个不同的并不是一个真正的选择,我不得不从我现有的开始工作。经过 8 个小时的努力,在不同的地方钻孔,在不同的地方弯曲金属片,我成功地组装了一个功能正常的手臂。它并不完美,但做得足够好了。

这个机械臂有 6 个自由度,这意味着它有 6 个伺服系统。我只需要其中的 4 个,这是幸运的,因为当我试图用手转动它时,其中一个伺服系统立即坏了,另一个则根本不起作用。

精确控制伺服系统不是一项简单的任务。当它们收到信号时,它们会尽可能快地移动到想要的位置,然后保持在那里,直到另一个信号到来。这种行为更适合像遥控飞机这样的应用,其中伺服系统用于控制飞机的鳍。相反,在机器人应用中,这可能会导致非常突然和不稳定的运动,但通过基于软件的运动平滑,这种情况可以得到缓解。

伺服系统由 PWM 控制,PWM 代表脉宽调制。PWM 有一个周期时间(T ),在模拟伺服的情况下通常为 50 赫兹。这个频率意味着所需的伺服位置每秒更新 50 次(每 20 毫秒一次)。为了设置轴角,必须向伺服系统施加电脉冲,其宽度在 0.5 至 2.5 毫秒之间,称为占空比。如果施加 0.5 毫秒的脉冲宽度,伺服将移动到最逆时针的位置,在 1.5 毫秒时,它将移动到中间(中间)位置,在 2.5 毫秒时,它将移动到最顺时针的位置。通常,伺服系统可以移动 180 度,但它会因型号而异。脉冲必须在每个周期中重复,以指示伺服机构保持该位置。如果没有施加脉冲,伺服机构关闭,轴可以自由移动。

在我将我的伺服系统连接到 Pi 并 SSH'd 到它之后,我安装了控制 GPIO 管脚的默认库: RPi。GPIO 。这是非常容易使用,我只是设置了一个引脚作为 PWM 输出,设置一个脉冲宽度和伺服已经在移动。它立即全速前进,然后突然停止。由于机器人手臂比遥控飞机的鳍重得多,我担心这些突然的运动最终会损坏伺服系统中的小齿轮,特别是承载最大重量的底部齿轮。我遇到的另一个问题是 RPi。GPIO 提供软件定时 PWM,这意味着脉冲由 Pi 的 CPU 产生。如果 Pi 同时在做其他工作,脉冲可能会明显延迟甚至失真。如果它用于使 LED 闪烁,这可能不是问题,但在我的情况下,我需要尽可能从系统中挤出所有的精度。解决方案是使用另一个提供硬件定时 PWM 的库,它更加精确(精确到几微秒)并且独立于 CPU 负载。一个提供这个特性的流行库是 PiGPIO

执行命令

arm 从推理机接收的每个命令都是一对绝对极坐标。第一个坐标总是项目,第二个是容器。为了将物品移动到容器,手臂必须移动到物品,打开磁铁,移动到容器上方,然后关闭磁铁。为此,必须解决两个任务:

  1. 以适当的速度尽可能平稳地移动单个伺服系统。
  2. 坐标 4 伺服移动手臂到所需的位置。

以天真的方式控制伺服,仅仅立即发送目标脉冲宽度会导致不可接受的快速和突然的移动。减慢这种运动的唯一方法是生成中间点,并以小间隔将它们发送到伺服系统,从而有效地减慢运动。

原始控制(左),较慢,但线性轨迹(中),正弦平滑(右)

为了进一步平滑移动,可以应用正弦平滑来代替线性轮廓。

线性(蓝色)和正弦(红色)轨迹

为了从 x 值产生红线,可以使用以下等式:

生成正弦平滑轨迹的方程

这种技术在开始后和停止前减慢运动,这有助于实现平稳的运动。

为了将手臂移动到特定的位置,所有的伺服系统必须同步移动。通常,如果所有伺服系统同时移动(并行控制),速度会更快,但在某些情况下,例如,在拾起一个物体后,最好先向上移动机械臂(串行控制),否则磁铁会撞到附近的物体。由于移动手臂包括以小间隔向伺服系统发送命令,并在伺服系统执行命令时休眠,因此并行控制多个伺服系统需要多线程方法。

控制手臂的最后一部分是计算出哪些伺服角度属于从推理引擎接收的坐标。接收到的位置是一个绝对极坐标:第一部分是以脉冲宽度( γ 表示的手臂基伺服角度,第二部分是以像素表示的手臂基轴和图像中心点之间的距离( d )。

由于 γ 是用脉宽表示的,所以可以直接送到伺服。弄清楚哪些伺服角度属于所需距离, d 是一项更艰巨的任务。在最佳情况下,当机器人臂的精确尺寸已知并且关节基本上没有间隙时,可以使用基本的三角学来计算伺服角度。在我的情况下,不知道尺寸,也缺乏适当的工具来测量它们,我决定采取一种实验方法:我手动移动手臂到 7 个位置,均匀分布在操作范围内,并记录每个位置的伺服角度。

显示伺服数字的照片

由于 d 主要取决于伺服 1 的角度,我绘制了伺服 2 和伺服 3 的角度作为伺服 1 位置的函数,对应于记录的 7 个点。

伺服 2 和伺服 3 的脉冲宽度值作为伺服 1 的函数,对应于所需位置

如上图所示,给定 servo1,三次多项式给出了相当好的拟合,并产生了可在代码中用于计算 servo2 和 servo3 的位置的方程。servo1 的角度可以通过特定于手臂的常数来计算,即以像素为单位测量的相机视野中心和手臂基轴之间的距离,以及对应于极坐标中最小和最大距离的 servo1 的脉冲宽度值。这些值可以通过粗略的测量来估计,比如使用尺子,然后通过反复试验来微调。

完成以上所有操作后,手臂就可以直接移动到任意坐标。唯一需要调整的是处理容器上方的落物,此时臂需要停在更高的位置。简单地用负值偏移 servo1 就可以实现。

感谢您的阅读,如果您有任何问题、意见或建议,请告诉我!

在第三部分也是最后一部分,我将讲述我如何使用迁移学习,以及我如何将解决方案部署到 AWS。

未完待续第三部……

分拣机器人—第三部分

原文:https://towardsdatascience.com/web-application-to-control-a-swarm-of-raspberry-pis-with-an-ai-enabled-inference-engine-part-3-77836f9fc4c2?source=collection_archive---------40-----------------------

一个基于网络的解决方案,用于控制一群覆盆子 pi,具有实时仪表盘、深度学习推理机、一键式云部署和数据集标记工具。

这是由三部分组成的 SorterBot 系列的第三篇文章。

GitHub 上的源代码:

  • 控制面板 : Django 后端和 React 前端,运行在 EC2 上
  • 推理机:运行在 ECS 上的 PyTorch 对象识别
  • 树莓:控制机械臂的 Python 脚本
  • 安装程序 : AWS CDK、GitHub 动作和一个 bash 脚本来部署解决方案
  • 标签工具:使用 Python 和 OpenCV 的数据集标签工具

推理机的迁移学习

所有的 Detectron2 模型都是在 ImageNet 上训练的,ImageNet 包括像人、狗、树等类别,但不包括小的金属物体,所以我需要定制训练模型来识别我想要使用的物体。为了节省训练时间和减少必要的数据集大小,我从预先训练的权重开始(迁移学习)。

创建数据集

对于我的用例,我需要几千张带标签的训练图片。在创建训练集时,我应用了两个策略来减少花费的精力。我的第一个想法是,我将录制一个视频,并从中抓取帧,而不是拍照。首先,我试图相对快速地移动手臂,但这样一来,大多数图像最终都很模糊,因为 Pi 相机在最大分辨率下只能提供 30 fps。为了克服这一点,我试图将手臂移动得更慢,但由于手臂的质量较差,这导致了不均匀、不平稳的运动。解决方法是移动手臂,等待一秒钟直到它稳定下来,然后进一步移动。由此产生的视频被用作我的数据集创建工具的输入。

为了减少用户必须绘制的边界框的数量,我计算了一个点在视频中出现的轨迹。

用于计算训练视频上项目的表观轨迹的绘图和方程(图片由作者提供)

最初,边界框是在笛卡尔坐标系中定义的,其原点在图像的左上角。这个计算的目标是在手臂旋转了δγ之后,检索一个点的新坐标。为此,我定义了两个额外的坐标系:一个极坐标系统和另一个笛卡尔坐标系。它们的两个原点都被定义为手臂的基轴,在这两个原点中,图像的中心点的坐标为(0,rc),其中 rc 是特定于手臂的半径常数。

为了进行计算,首先我在新的笛卡尔坐标系中表示旧的点(图上的点 1),然后将其转换为极坐标(点 2)。在我有了旧点的极坐标之后,我简单地把手臂的旋转加到它上面(点 3),然后把它转换回原来的笛卡尔系统(点 4)。使用这种方法,我可以计算出物品在摄像机视口中移动时的表观轨迹。这种方法的好处是,我可以为每个视频绘制一个边界框,然后为其余的帧计算它的位置,而不是抓取每个帧并在其上手动绘制边界框。这将标注数据集所花费的时间减少了至少十分之一。

绘制边界框,然后在数据集标注工具上调整旋转滑块(图片由作者提供)

在数据集创建工具中,有两个滑块定义边界框的轨迹:半径(以像素为单位)和角度(以度为单位)。半径表示机器人的基轴和摄影机视口中心之间的距离。而角度代表最逆时针和最顺时针位置之间的角度。设置这些滑块定义了边界框的位置,因此用户应该找到边界框适合实际对象的值。首先,半径滑块的值应该是近似值,然后角度滑块应该移动,直到边界框处于正确的位置。

在数据集标注工具中调整角度和半径滑块(图片由作者提供)

另外两个滑块用来定义应该抓取哪些帧:间隔和偏移。用户应该以一种方式设置它们,以确保在手臂不移动时的短暂停顿中抓取帧。为了使这更容易,当当前帧被设置为抓取时,边界框的颜色将变为白色。

即使我想出了所有的软件技巧,一些图片还是模糊不清,或者边框放错了位置。为了避免这些出现在数据集中,我创建了另一个简单的工具,它允许我浏览整个数据集,并通过按键来保留或删除图像。这增加了数据集创建的时间,但也提高了结果的质量。验证后,创建的数据集由标记工具上传到 AWS S3 桶,以便于培训。

训练网络

培训是在 DeepNote 上进行的,使用的是这个笔记本。我基本上遵循了 Detectron2 文档中描述的标准训练程序。作为我的第一次尝试,学习率为 2.5e-4,批量大小为 512,训练花费了大约 5 分钟,在 600 次迭代后停止。这导致平均精度(AP)为 33.4,明显低于在 ImageNet 上测量的相同网络的基准 AP(40.2),但我使用这些权重测试了应用程序,它工作得非常好,即使对象不在训练数据集中。这样做的原因大概是用磁铁抓取一个物品并不需要很大的精度,基本上,如果磁铁接触到物品的任何地方,它都可以捡起来。这意味着即使边界框偏离了很大一部分,磁铁仍然可以完成它的工作。最有可能的是,我可以通过更长的训练、更多的数据和超参数调整来显著提高精度,但为了避免试图修复没有损坏的东西的错误,我决定将我的努力集中在其他地方。

训练结束后,我将网络设置为推理模式,并使用验证集中的一些图片来可视化网络的表现。

可视化的预测边界框(图片由作者提供)

正如您在上面的图片中看到的,所有的物品和容器都以相对较高的置信度(87–94%)被识别,这远远高于我定义的 70%的阈值。左下角的螺钉无法识别,因为它的边界框会在图片之外。这是有意的,我从训练集中移除了每个这样的边界框,以避免边界框的中心发生位移,因为它被裁剪以适应图片。您还可以注意到,螺钉周围留有一些衬垫,这也是有意为之。我决定在物体周围画稍微大一点的边界框,以适应不完美的硬件造成的小偏差。由于磁铁被移动到边界框的中间,只要填充均匀分布在对象周围,这不会阻止手臂拾取对象。

最后,训练好的权重被上传到另一个 AWS S3 桶,GitHub Actions CI 管道可以方便地访问它们。

部署到 Amazon Web 服务

为了将整个解决方案部署到 AWS,必须创建和配置 43 个资源。首先,我使用 AWS 控制台手动完成了它,还编写了一个逐步指南来跟随。该指南有 100 个步骤,手动完成所有步骤大约需要 3 个小时,这给错误留下了很大的空间。为了确保没有人(包括我)必须再次经历这个过程,我决定利用 AWS CDK 和一个冗长的 bash 脚本来自动化部署。CDK(云开发工具包)允许用户使用传统的编程语言来定义、配置和部署 AWS 资源。目前支持 Javascript、Python、C#和 Java,我选择 Python。bash 脚本用于编排流程,也用于管理秘密,因为 CDK 不支持该功能。

自动化部署

在 sorterbot_installer 存储库中,有两个 CDK 堆栈:一个用于开发,一个用于生产。开发堆栈是生产的子集,它提供 S3 桶和 PostgreSQL 实例,因此解决方案的全部功能也可以在开发模式下访问。除此之外,生产栈还包括一个 EC2 t2.micro 实例(包含在自由层中)来运行 SorterBot 控制面板,一个 ECR 存储库来存储推理引擎的 Docker 图像,一个 ECS FarGate 集群来部署推理引擎,以及这些组件协同工作所需的一些附加基础设施,如 VPC、安全组和 IAM 角色/策略。还包括用于部署和销毁开发和生产版本的脚本。开发脚本主要是生产脚本的子集,所以我不会在这里详细描述它们。部署到生产环境时,脚本执行以下步骤:

  • 环境变量是从。env 文件和一些其他变量是显式设置的。必须由用户设置的环境变量如下:AWS 帐户 ID、GitHub 用户名、GitHub 个人访问令牌、训练模型权重的 S3 URL 以及用于登录控制面板的用户/密码组合(也用作 Django 管理凭证)。除此之外,将部署解决方案的 AWS 区域是从本地系统的默认配置文件中检索的,可以使用“aws configure”命令进行设置。
  • 为了存储机密,使用 AWS 简单系统管理器(SSM)的参数存储。这是一个免费的选项(相对于 AWS Secrets Manager,每个秘密每月花费 0.40 美元),如果选择 SecureString 选项,秘密将被加密存储。
  • AWS CLI 用于创建一个 SSH 密钥对,稍后可用于访问已部署的 EC2 实例。
  • 授予 GitHub 操作工作流对 AWS 帐户的访问权限。为此,首先创建一个 AWS IAM 用户,然后将一个提供必要权限的策略附加到该用户。最后,为这个用户创建一个访问密钥,使用 GitHub API 将它作为 GitHub 秘密保存到 sorterbot_cloud 存储库中。
  • CDK 部署生产堆栈,它提供和配置上述所有资源。
  • 检索新创建的 EC2 实例的主机,并通过 SSH 在其上执行 bash 脚本,以安装运行控制面板所需的依赖项:Git LFS、Python、Docker、Docker Compose 等。
  • 安装完依赖项后,控制面板的 Docker 映像就构建好了。
  • 为了避免使用密码作为 Docker 构建参数时出现的安全问题,Django 迁移和用户创建在 Docker 之外执行。为此,requirements.txt 中列出的 pip 包也安装在 Docker 容器之外。
  • 设置控制面板时,在 sorterbot_cloud repo 中创建了一个新的版本,它触发了 GitHub Actions 工作流,该工作流将推理引擎的 Docker 映像部署到 ECS。
  • 最后,在创建了发行版之后,控制面板开始使用 Docker Compose。DNS 地址被打印到日志中,用户可以使用。部署前的 env 文件。

部署推理引擎的 CI 工作流

将推理引擎部署到 AWS ECS 的 CI 工作流被定义为 GitHub 动作。它可以通过在 GitHub repo 中创建一个新版本来触发,这是在生产部署脚本运行时自动完成的。工作流首先检查主分支,使用 flake8 链接它,安装依赖项(或者如果 requirements.txt 文件没有改变,从缓存中加载它们),然后使用 pytest 运行测试。如果所有测试都通过了,部署就开始了。

首先,通过 Git LFS 检查主分支,因此如果没有提供模型权重 URL,可以使用默认的样本权重,这些权重被提交给存储库。然后,下一个操作配置 AWS 凭证,这些凭证用于登录 ECR。之后,Docker 映像被构建、标记并推送到 ECR。接下来,创建任务定义的新版本,最后,部署任务定义。使用此工作流可以轻松替换模型权重。在新的权重被上传到适当的 S3 存储桶之后,只需要创建一个新的发布,Github Actions 会自动部署它,无需用户进一步输入。

结论和未来工作

在这个项目中,我构建了一个易于部署和管理的 web 应用程序。它可以控制任意数量的机械臂。目前的架构可能可以处理同时运行的几个分支,但如果超过这一水平,由于缺乏适当的多处理,很可能会导致严重的延迟。因为在这个项目中,我的目标不是处理许多 arm,而且我不想花钱购买具有 1 个以上内核的更强大的 ECS 实例,所以我没有太关注扩展推理引擎。由于它部署在 ECS 上,因此通过设置自动扩展或将图像处理转移到每个图像的单独流程,以及购买多核实例,可以轻松实现可扩展性。

到目前为止,最大的问题是机械臂的低质量。为了避免它的缺点,我在软件中实现了一些额外的逻辑,如果使用高质量的 arm,可以省略这些逻辑。此外,神经网络的准确性仍然可以提高,但由于硬件的准确性受到严重限制,致力于改善模型可能不会导致太多的整体改善,如果有的话。

下一步,我计划用 3D 打印技术自己制造一个机器人手臂。高精度 3D 打印变得非常实惠,Elegoo Mars 树脂打印机的价格不到 400 美元,精度不到 50 微米。结合创成式设计,就像 Autodesk 提供的设计,一个精确、轻便、看起来像有机体的机械臂就能被制造出来。

另一个限制是抓握:使用磁铁会限制手臂抓握金属物体。为了解决这个问题,可以使用另一种抓取机制,像【Festo 的这个(灵感来自变色龙抓住猎物时的舌头)。

感谢您的阅读,如果您有任何问题、意见或建议,请告诉我!

Python 中的 Web 应用程序

原文:https://towardsdatascience.com/web-applications-in-python-a1a7edcb5b9e?source=collection_archive---------8-----------------------

Django 入门

来源

Django 是一个基于 python 的开源 web 框架,可以轻松创建数据库驱动的网站。使用 Django 的网站包括 Instagram、Mozilla 和 Bitbucket。

在这篇文章中,我们将介绍用 Django 构建一个简单的 web 应用程序的步骤。Django 的文档可以在这里找到。

我们开始吧!

我们需要做的第一件事是确保我们已经安装了 Django。要安装 Django,打开终端并执行以下 pip 命令:

pip install django

然后我们可以显示 Django 的版本:

python -m django --version

在我写这篇文章的时候,我使用的版本是 2.2.6。现在,让我们在桌面上创建一个名为“first_site”的新目录:

mkdir first_site
cd first_site

让我们在“first_site”文件夹中创建 Django 项目:

django-admin startproject first_site

我们可以看看创建的文件的结构,我们看到:

我们有一个“manage.py”文件和一个 Django 项目目录“first_site”。“manage.py”文件是命令行实用程序,它允许我们执行管理任务。

' init '“py”文件是一个空文件,它告诉 python 我们的应用程序是一个 python 包。“setting.py”文件允许我们更改设置和配置。“url.py”允许我们指定从 url 到我们将用户发送到的位置的映射。“wsgi.py”用于允许我们的服务器和 web 应用程序之间的通信。

现在,让我们打开每个新项目的默认网站。在我们的终端中,我们运行:

python manage.py runserver

我们应该看到以下内容:

我们看到我们的网站正在运行。我们可以通过“http://127.0.0.1:8000/”访问我们的网站,这对应于我们的本地计算机。我们应该看到以下内容:

这是 Django 为我们创建的默认网站。Django 框架背后的思想是,在创建一个网站项目时,它本身就是一个应用程序,我们可以在我们的 web 应用程序中创建额外的应用程序。你可以把每个应用程序想象成我们网站上它自己的部分,比如博客部分、商店部分等等。这个框架的好处在于,在创建应用程序时,您可以在后续的 web 应用程序中重用代码。

我们将继续为我们的网站创建一个博客应用程序。首先,按“control”+“C”来关闭运行我们的 web 应用程序的服务器:

接下来,为了创建我们的博客应用程序,我们要做以下事情:

python manage.py startapp blog

我们可以在创建新应用程序时查看我们的项目结构:

现在,让我们进入博客目录,打开“views.py”文件。我们应该看到以下内容:

from django.shortcuts import render# Create your views here.

让我们也导入 HttpResponse。让我们也创建一个名为“home”的新功能,它将允许我们处理来自我们博客主页的流量:

from django.shortcuts import render
from django.http import HttpResponsedef home(request):
    return HttpResponse('<h1>Blog Home</h1>')# Create your views here.

接下来,我们需要将我们的 url 模式映射到这个‘view’函数。我们转到我们的博客应用程序目录,创建一个名为“urls.py”的新文件。在该文件中,我们复制并粘贴以下内容:

from django.urls import path
from . import viewsurlpatterns = [
path('', views.home, name='blog-home'),
]

现在我们有了一个映射到视图文件中 home 函数的博客主页的 url 路径。

为了充分发挥作用,我们需要修改主项目目录“first_site”中的“urls.py”模块。这个模块告诉我们的网站哪些网址会把我们发送到我们的博客应用程序。

让我们打开“first_site”目录中的“urls.py”文件:

from django.contrib import admin
from django.urls import pathurlpatterns = [
path('admin/', admin.site.urls),
]

我们看到有一条路由映射到我们的管理站点 URL。我们现在需要指定映射到我们博客 URL 的路由。我们需要从 django.urls 导入 include 函数,并为我们的博客 url 添加一个额外的路径:

from django.contrib import admin
from django.urls import path, includeurlpatterns = [
path('admin/', admin.site.urls),
path('blog/', include('blog.urls'))
] 

现在让我们试着运行服务器。在尝试运行服务器时,我经常遇到以下错误:

要解决此问题,请执行:

ps -ef | grep python

并使用以下命令终止适当的进程:

kill -9 procees_id

现在尝试运行服务器:

python manage.py runserver

如果我们键入 http://127.0.0.1:8000/blog/我们应该会看到以下内容:

我们可以进一步编辑博客主页的内容。让我们引用我最喜欢的小说之一,戴维·福斯特·华莱士的《无限玩笑》:

from django.shortcuts import render
from django.http import HttpResponsedef home(request):
    return HttpResponse('<h1>Blog Home</h1><p1>Everybody is identical in their secret unspoken belief that way deep down they are different from everyone else.</p1>')

我们还将为我们的博客添加一个关于页面。在“views.py”模块中,让我们定义一个名为“about”的函数:

from django.shortcuts import render
from django.http import HttpResponsedef home(request):
    return HttpResponse('<h1>Blog Home</h1><p1>Everybody is identical in their secret unspoken belief that way deep down they are different from everyone else.</p1>')def about(request):
    return HttpResponse('<h1>About Home</h1>')

现在,让我们在博客应用程序的“urls.py”模块中为“关于”部分添加一个新路径:

from django.urls import path
from . import viewsurlpatterns = [
path('', views.home, name='blog-home'),
path('about/', views.about, name='blog-about')
]

现在如果我们去http://127 . 0 . 0 . 1:8000/blog/about我们应该会看到:

我将在这里停下来,但是您可以随意摆弄博客主页的内容以及我们的 web 应用程序的各个部分。此外,了解 Django 的一个很好的资源是科里·斯查费的 YouTube 教程,你可以在这里找到。

结论

总之,在这篇文章中,我们讨论了如何使用 Django 构建 web 应用程序和定义 url 路由。首先,我们讨论了用 Django 创建新的 web 应用程序时生成的特定文件。然后,我们在项目中创建了一个博客应用程序,并定义了视图函数,这允许我们指定用户看到的内容。我们还展示了如何在我们的博客应用程序中添加额外的 url 路由和视图。我希望你觉得这篇文章有用/有趣。感谢您的阅读!

Web 自动化噩梦:克服它们的 6 个技巧

原文:https://towardsdatascience.com/web-automation-nightmares-6-tricks-to-overcome-them-4241089953e3?source=collection_archive---------27-----------------------

塞巴斯蒂安·赫尔曼Unsplash 拍摄的照片

当硒和美丽的食物不够的时候。

当我第一次发现 Python 的一些网络抓取库时,真是梦想成真。想想一个人能做的所有事情!可能性是无限的。不用说,当我想刮的那几页纸直接从地狱出来时,我的希望破灭了。

当你开始怀疑如果你自己动手,这个过程会不会更快时,你知道你遇到了一个真正的障碍。

经过几个小时的搜索 StackOverflow,以下是我在开始自动化我的 web 流程时克服一些挑战的 6 个简单方法:

1.从 Selenium 导入例外

问题:有时候你想定位的按钮可能会被隐藏,可能是因为讨厌的弹出窗口。当您无法确定这些弹出窗口何时会弹出时,这就变得更加令人恼火了。而在其他时候,您的问题可能是由于互联网连接速度慢造成的…

解决方案:顺利抓取网页的道路布满了例外——并学习如何处理它们!每当发生这些异常时,知道自己有一个备份计划总是很方便的。首先导入它们:

from selenium.common.exceptions import NoSuchElementExceptionfrom selenium.common.exceptions import StaleElementReferenceExceptionfrom selenium.common.exceptions import ElementClickInterceptedExceptionfrom selenium.common.exceptions import ElementNotInteractableException

然后用 try/except 块解决可能出现的问题!

2.让您的浏览器等待

回到上一个问题:假设一个缓慢的互联网连接导致了 NoSuchElementException。上面提到的一种方法是使用 try/except 块让您的脚本等待 10 秒钟:

try: 
    button = driver.find_element_by_id('button-id')
    button.click()except NoSuchElementException: 
    sleep(10)
    button = driver.find_element_by_id('button-id')
    button.click()

这很棒,而且很可能解决了问题(如果没有,那么你真的需要考虑修理那个路由器),但是这意味着每次你想点击那个按钮的时候都必须等待整整 10 秒钟。

解决方法:换个更优雅的方式怎么样?使用 WebDriverWait,并将按钮的可见性指定为条件!一旦找到按钮,你的浏览器就会停止等待,允许你点击它。每当你想找到一个按钮时,这可以节省你宝贵的时间:

from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as ECbutton = WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.XPATH, 'insert_button_xpath_here')))

3.用 Javascript 输入文本

问题:现在你正在填写一张表格,然后你意识到 Selenium 的send_keys()选项是有帮助的,但是帮助不够快。当然,它能以最快的速度打字,但是你很快就会怀疑自己复制粘贴是否真的会更快。当你看到你的一大段文字在页面上一行一行慢慢串起来时,自我怀疑就开始了。

解决方案:通过执行脚本输入文本!这要容易得多,也不需要导入。

text = text.replace('\n', '\\n')script='''document.getElementById("source").value='{}';'''.format(text)driver.execute_script(script)

现在,您的文本值立即被设置,文本几乎立即出现在表单中!请注意,您应该首先在新行前面添加一个额外的反斜杠' \ ',否则它将不起作用。如果您使用大量文本,这尤其有用。

另外,我唯一一次遇到这个问题是在输入外语时(在这种情况下,它不起作用)。如果有人找到了更好的解决方法,请告诉我!

4.使用动作链点击

问题:一些网站的格式很糟糕,或者找到一些带有 id(或任何其他属性)的按钮似乎无法工作。

解决方法:在这种令人沮丧的情况下,不要惊慌!有其他方法可以解决这个问题。首先问问自己: 什么是工作?也许我们可以利用这一点。

在之前类似这样的体验中,我首先找到了我知道我肯定能识别的按钮,然后弄清楚了我想点击的按钮的相对位置,但却不能这样做。

因为有了 ActionChains,你可以先找到一个工作按钮,然后通过选择的坐标偏移点击来点击屏幕上的任何地方!这在大多数情况下工作得很漂亮,但是找到坐标是关键的一步。

from selenium.webdriver.common.action_chains import ActionChainsac = ActionChains(driver)ac.move_to_element(driver.find_element_by_id('insert_id_here').move_by_offset(x,y).click().perform()

现在你可以点击屏幕上的任何地方!

5.做人,随机应变

问题:最后,事情进展顺利,你收集了所有你需要的信息…直到你找到验证码。

解决方法:负责任的刮!在操作之间引入随机等待时间,以防止服务器过载。更重要的是,它可以防止你的脚本的重复模式被发现。

from time import sleep
import randomsleepTimes = [2.1, 2.8, 3.2]
sleep(random.choice(sleepTimes))

6.最后,确保您的数据得到备份

问题:我一开始犯的一个新手错误就是没有引入备份选项,以防我的抓取在中途随机失败(有我的互联网中途断网的可能)。我只是在脚本的结尾将我收集的数据保存到一个文件中。这是个大错误。

解决方案:备份数据有很多种方法。一些对我有用的方法:

  1. 将我的数据的每个“条目”保存到一个 JSON 文件(或任何其他方便的格式)。这让我放心,因为我知道我的脚本运行的每个循环/页面都保存在我的计算机上的某个地方,如果有任何失败,我仍然有我的数据。这也是节省计算机内存的好方法。
  2. 将循环放在一个 try/except 块中,如果出现任何问题,它会将我的所有数据保存到一个文件中。

布伦特兰博的 Gif

成功了!

这些只是除了简单的 BeautifulSoup 和 Selenium 库之外,您可以使用的许多技巧中的一部分。

我希望这有所帮助,感谢您的阅读!

利用 CityGML 城市模型实现基于 Web 的三维数据可视化

原文:https://towardsdatascience.com/web-based-3d-data-visualization-with-ciytgml-city-models-f0796b37e9f5?source=collection_archive---------26-----------------------

3D 数据可视化基本指南

分步指南-可视化纽约市曼哈顿的 3D 城市模型

插图作者:金彩云

在这篇文章中,我将向您展示一种在基于 web 的应用程序上使用 Node.js铯. js web globe 库可视化 CityGML 3D 城市模型的简单方法,并以曼哈顿纽约市区域为例。在本简短教程结束时,您将能够构建一个看起来或多或少像这样的 web 应用程序:

关于铯应用的纽约曼哈顿 3D 城市模型(现场演示:

CityGML 简介

在我们开始之前,我想向您介绍一下 CityGML 3D 城市模型。 CityGML 是一种开放的标准化数据模型和交换格式,用于存储 OGC(开放地理空间联盟)推出的城市和景观的数字 3D 模型。CityGML 的特殊之处在于它是一个语义城市模型,包含属性和几何数据。

CityGML 德国慕尼黑带有属性数据的语义 3D 城市模型。(现场演示:3D 德国

CityGML 模型的几何形状和属性允许各种模拟建筑能源需求、光伏潜力等等。

使用 CityGML 对德国路德维希堡—格伦布尔的建筑能源需求进行建模的示例(能源建模使用 SimStadt2 软件进行计算)

好消息!!世界上有几个城市有自己的 CityGML,其中许多城市都以开源数据集的形式提供了它们的 CityGML。

从 CityGML 构建基于网络的 3D 应用程序

1.准备 3D 数据集

纽约市 DoITT 以 CityGML 格式发布了纽约市的语义 3D 城市模型,包括纽约市的每一栋建筑。在这里随意下载。从这个数据集中,我们将只关注曼哈顿地区(DA12 _ 3D _ Buildings _ merged . GML~ 48,000 栋建筑),并使用它来创建 3D web 应用程序。

虽然 CityGML 适合交换和存储 3D 建筑模型,但它不能直接在 web 上可视化。因为我们将在我们的 web 应用程序中使用铯,所以我们需要将 CityGML 转换为 3D Tiles 格式。FME 工作台是我所知道的最好的工具,对学生和开源研究项目也是免费的。

或者,你可以跳过这一步,从下面我的 GitHub 项目中下载已经转换好的 3D 图片。

2.设置 Web 服务器

对于 web 服务器,使用以下依赖项创建一个项目文件夹和 Node.js 项目:

$ **npm init** #initiate node project
$ **npm install express** #install express framework
$ **npm install compression** #install compression 

然后,用 Express 为 Node.js 创建一个简单的 server.js 文件。

带有 Express Framework 的简单 Node.js 示例

您可以通过$ node server.js命令来试运行您的服务器。

3.使用 CesiumJS 的 3D 应用程序

我们将使用 CesiumJS 来渲染我们的 3D 建筑模型。这是一个开源的 JavaScript 库,用于 web 浏览器中的 3D 地球仪和 2D 地图。

现在,让我们在public文件夹中创建一个index.html文件,并放置以下代码:

index.html(用于铯 3D 纽约应用)

这个 HTML 基本上从 cesium.com 加载铯依赖项,并创建一个铯容器。变量tileset通常指的是 3D 瓦片数据集。只需在此处用您的本地零件替换url值即可转换为 3D 图块。搞定了。

从这里,当你运行$ node server.js并前往http://localhost:3000,你已经可以看到曼哈顿的 3D 模型了。如果你想要一些建筑模型的颜色/样式,可以通过 tileset 样式添加。下面的示例脚本显示了如何基于建筑高度设置建筑模型的样式。

colorbyHeight.js(按建筑高度设置 3D 图块样式)

耶!我们对纽约城市模型的最终应用

差不多就是这样!我为挑选功能添加了一些代码,如果你感兴趣,可以从我的 GitHub 这里查看全部代码:

[## JoeThunyathep/NYC3D_CesiumJS

纽约市三维城市模型。在…上创建一个帐户,为 JoeThunyathep/NYC3D_CesiumJS 的发展做出贡献

github.com](https://github.com/JoeThunyathep/NYC3D_CesiumJS)

奖金

如果你想继续开发这个应用程序,你可以用铯和 3D 城市模型做更多很酷的事情。请在此查看一些资源:

  • CesiumJS API 文档:链接 /一些好看的展示:链接
  • 掌握你的铯式表情文档:链接
  • 开放 CityGML 数据
    -美国纽约市所有建筑的 CityGML【LOD 2】(链接 )
    -美国所有建筑的 City GML!!!!【LOD 1】(链接 )
    -德国北莱茵-威斯特伐利亚州所有建筑的 CityGML【LOD 1,2】(链接)
    -TU-Delft 多个城市开放 CityGML 数据列表(链接 )
    )【无 city GML,无忧。查看 FME 的《城市地图指南》
  • 3DCityDB :开源地理数据库,用于存储、表示和管理虚拟 3D 城市模型:(链接)
  • 更多关于 OGCcity GML的信息(链接)
  • 真实世界应用:请查看 VCS 公司提供的使用铯+ CityGML( 链接)的智能 Cites 解决方案

作者消息:

总的来说,本教程涵盖了使用铯. js 和 3D 城市模型创建 3D 基于 web 的应用程序的基础。我希望你喜欢这篇文章,并发现它对你的日常工作或项目有用。

关于我&查看我所有的博客内容:链接

安全健康健康!💪

感谢您的阅读。📚

带有洛杉矶公寓和社区搜索工具的网络搜索工具

原文:https://towardsdatascience.com/web-scraper-with-search-tool-for-los-angeles-apartments-neighborhoods-4b1958ef7500?source=collection_archive---------40-----------------------

概念验证公寓和邻居指标

作为一名洛杉矶的常住居民,我发现在这个城市找到符合你要求的出租房可能会很棘手。在像 Craigslist 和 apartments 这样的网络数据库中,帖子包含了关于公寓本身的丰富信息。然而,缺少邻居数据… 为了全面了解公寓邻居,用户必须建立单独的邻居数据库,并手动交叉引用公寓列表。另一个障碍是,像 Craigslist 和 Apartments.com这样的网站不提供每套公寓的指标或邻居基准,这使得用户在选择他们在洛杉矶想要的公寓和邻居时,无法做出完全知情的决定

拟议解决方案

为了解决洛杉矶出租房屋信息的缺口,我创建了一个 Craigslist 公寓搜索工具和增强的搜索工具。该项目使用 Python & SQLite 构建,将洛杉矶 Craigslist 公寓与社区经济和无家可归者指标相结合。概念验证(POC)现已在我的 Github 页面上提供用户友好的指南- > 此处

POC 目前包括:

  • Python 脚本的存储库,它执行 web 抓取、数据库生成和测试查询。
  • Python Jupyter Notebook ,它显示查询结果、一些简单的生成指标散点图,以及对这些指标的数据进行排序的可能性

下面我将提供 python 代码每个组件设计背后的一些细节,突出优点和缺点。该项目基于 2019 年秋季南加州大学维特比工程学院应用数据科学硕士项目的一门课程的作业,由 Jeremy Abramson 教授提供建议。我也从 Julio Malegria 的 python-craigslist 模块Riley PredumCraigslist 网页抓取教程中获得了灵感。我从这些已有的知识中学到了很多,并希望能在此基础上更上一层楼!

脚本驱动程序

为了给 python 脚本和结果数据库创建一些组织,我用两个子文件夹构建了存储库:

  • src —保存用于生成数据库的所有脚本,包括:驱动文件、python 模块需求、公寓刮刀、邻居刮刀和测试查询
  • 数据 —保存 SQLite 数据库,该数据库包含公寓和邻居抓取脚本的结果

python 脚本、数据、查询和图形的报告结构

使用驱动程序获取数据

下载存储库并导航到终端内的“src”文件夹后,用户可以使用远程或本地数据调用驱动程序文件“LA_Apartment_Analysis.py”。可以输入的两个命令是:

$ python3 LA_Apartment_Analysis.py local
$ python3 LA_Apartment_Analysis.py remote
  • 本地 —用本地数据库(缓存)运行程序,如果有的话。如果本地数据库不存在,您将需要远程运行程序,以便在分析(也称为查询)完成之前生成一个本地数据库。
  • remote —首先从‘neighborhoods _ API . py’和‘apartments _ scrape . py’中的远程 web 源创建数据库,然后运行程序。

从命令行调用的驱动程序文件“LA_Apartment_Analysis.py”,用于调用抓取器和查询

Craigslist 网页抓取

司机调用公寓抓取器‘apartments _ scrape . py’后,Craigslist 公寓抓取就开始了。代码被彻底地注释了,所以人们可以在那里回顾每一步,但是我在下面强调了 scraper 的主要步骤。这里使用的主要 python 库是:requests、BeautifulSoup、pandas 和 sqlite3。

步骤 1:创建一个 craigslist 公寓搜索查询,并获得所有公寓链接的列表。

为了验证概念,我的默认搜索是洛杉矶有照片的公寓,今天发布的租金价格在 1800-2800 美元之间,距离邮政编码 90036(贝弗利-费尔法克斯区)3 英里。如果用户的查询有超过 120 个结果,应该激活第 201–212 行,以便从包含许多公寓列表的多个页面中获取链接。

get_link_list(url_query)生成包含嵌入公寓链接的 html 对象列表

步骤 2:对于每个公寓链接,从链接的 html 对象中解析公寓属性,并存储在字典列表中。

名为‘process _ links(link _ list)’的函数获取每个链接,并发送一个对该链接的 html 对象的请求。请求成功完成后,代码提取嵌入在 hmtl 对象中的有意义的公寓属性,比如:卧室、浴室、价格、平方英尺、纬度和经度。

在当前代码中,大约 70–80%的公寓列表的公寓抓取是成功的。如果一个单元属性不能被抓取,代码继续尝试抓取下一个单元。这就是为什么我们在处理请求时实现了大量的异常处理。在未来的迭代中,我希望将所有公寓房源的成功率提高到 100%。

处理链接的速度可以接受,但是速度可以通过 python 并发 来提高。使用 python 实现并发性将允许在同一台计算机的多个处理器中同时执行任务。这应该是提高处理速度的可行途径,但我们也必须尊重 Craigslist 的限速政策,以避免该网站可能维持的任何 IP 禁止政策。

process_links(link_list)接受一个链接列表,并为每个单元链接创建一个一行的单元属性表

步骤 3:对于每个公寓纬度&经度,获取人口普查区域 ID。

这一步对于实现到洛杉矶邻居表的连接至关重要。为此,我们必须在一个 GET API 请求中向 geocoding.geo.census.gov 发送每个公寓的纬度和经度。由于 census 提供的这个 API 的性能较慢,这个步骤比 Craigslist 抓取花费的时间要长得多…在未来的版本中,我将实现一些 python 并发来减少处理时间。这仍然不会对人口普查地理编码器 API 的缓慢产生影响。

request _ tractid(apt _ tractid _ URL _ list)接受一个人口普查 api urls 列表,并返回具有 apartment tract_id 的相关 json 对象。

步骤 4:在 SQLite 表中存储公寓属性和人口普查区域 id。

为了序列化收集的数据,代码获取字典列表,并将它们转换成 pandas 数据帧。接下来,代码移动到/data 存储库中,并创建名为“la_apartments.db”的 SQLite 数据库和一个名为“apartment”的表。最后,公寓数据帧的每一行都被复制到“公寓”表中。

存储熊猫数据帧中的公寓表

洛杉矶邻里 API

在这一步中,我们使用“neighborhoods_api.py”脚本构建一个邻域表。邻域表将包含每年每个人口普查区域 ID 的一行。邻域属性从两个独立的站点获取,都是通过 API 功能。由于这些站点提供 API 服务来获取数据,因此创建“邻居”表所需的时间比创建“公寓”表要少得多。

用于收集邻域数据的两个来源如下:

  • 洛杉矶市— 该站点包含基本的社区属性,如 TRACT_ID、COUNTY、YEAR、POPULATION。到数据集和 API 文档的链接是 这里是
  • 南加州大学社会创新价格中心— 该网站包含一系列不同的社区数据集,按人口普查区域 ID 排列。使用的主要数据集:平均租金价格数据集— 此处;无家可归数据集— 此处

通过 API 收集邻域数据后,“neighborhoods_api.py”使用 pandas 来转换数据,以组合来自三个来源的属性。然后,该表作为“邻居”表写入 SQLite 数据库。

存储熊猫数据帧中的邻居表

查询和散点图

在数据库中创建了“公寓”和“邻居”表之后,驱动程序从“查询 _ 来自 _ 终端. py”中调用测试查询。结果显示在终端中,显示一些关于关系数据库的基本查询。

如果用户愿意,他们可以通过 Jupyter 笔记本“mann_mark.ipynb”查看查询结果和一些额外的散点图。查询和绘图提供了对公寓搜索过程至关重要的先前未回答的问题的洞察力。最终,这个数据库和查询可以构建到单页面 web 应用程序中的交互式搜索工具中。

来自 Jupyter 笔记本“mann_mark.ipynb ”,显示计算指标,如“价格每平方英尺”和“无家可归者每平方英尺”

散点图展示了如何根据计算出的指标可视化公寓数据

未来版本

将来,我希望创建一个连接到这个公寓和邻居数据库的 web 应用程序。在 web 应用程序中,用户可以查询他们自己对洛杉矶公寓的偏好。将有一个选项供用户设置重复工作(每天,每周,每月)和发送电子邮件时,数据被刷新。还可以选择从数据库下载标准化报告,或者公寓和邻居表本身。

突出显示人口普查区域和公寓位置的地图工具也会有所帮助。在这个工具中,用户可以根据邻居的度量标准,比如每平方英里无家可归的人数,来给邻居着色。下面是一个工具的例子,我想在未来创造。

每平方英里的无家可归者地图,每个区域 id。使用 datawrapper [ 链接创建的映射

如果你已经做到这一步,感谢你的阅读!我乐于接受问题、评论或反馈。

原载于 2020 年 1 月 9 日【https://medium.com】

网页抓取 101

原文:https://towardsdatascience.com/web-scraping-101-d9170e880117?source=collection_archive---------11-----------------------

如何制作一个简单的机器人在任何投票或竞争中获胜

斯科特·格雷厄姆Unsplash 上拍照

网络抓取是一个在网上检索数据和执行特定操作的过程。它通常由机器人来完成,以便自动化某些重复的任务。这是一个相当大的研究领域,你可以用它做很多有趣的事情。开始并不一定是缓慢和困难的。在本文中,我将向您介绍一个创建机器人的简单过程,以及将来如何对其进行扩展。不需要以前的经验,只需要 Python 和互联网连接。

入门指南

本教程适用于任何编程水平的初学者,所有内容都将尽可能清晰明了地解释。我将使用一个随机的民俗比赛来演示投票。你可以使用任何你喜欢的网站,并在此基础上进行调整。

(作者截图)

在直接进入编码之前,我们必须设置两件事情。

第一步。安装 IDE

首先,我们需要一个地方来写代码,如果你还没有的话。我更喜欢使用 Visual Studio 代码,因为它简单并且提供你需要的任何东西。只需搜索“Visual Studio 代码”并下载最新版本。

安装完成后,单击扩展按钮并安装 Python。

(作者截图)

第二步。下载 ChromeDriver

我们需要一个模块,能够与谷歌浏览器。这一步相当短。搜索“ChromeDriver Chromium”并下载最新版本。下载完成后,解压文件。

对于 Windows,复制文件,创建一个文件夹,如“C:\webdrivers”并放在那里。现在,转到路径设置,并在那里添加文件夹路径(如果你不知道这是在哪里,在谷歌有大量的解释)。

对于 Mac 和 Linux,打开终端并键入

mv ~/Downloads/chromedriver /usr/local/bin

制作机器人

第一步。准备文件和包

太好了,现在我们已经设置好了,可以开始了!让我们创建一个新文件夹,命名为“网络抓取”。现在,打开 Visual Studio 代码,创建一个名为“vote_bot.py”的新文件。

在终端窗口中键入:

python -m venv venv

这将创建一个虚拟环境,它基本上允许我们在不修改您的系统软件包的情况下安装软件包。要激活它:

source venv/Scripts/activate

接下来,我们需要一个软件包,它将帮助我们使用 web 浏览器。类型:

pip install selenium

第二步。开始编码

用 VS 代码打开我们的 vote_bot 文件。我们要使用的第一行是:

from selenium import webdriver
import time

这将为我们的项目添加 web 驱动程序支持,并在后面的步骤中帮助我们。此外,我们导入时间只是为了能够让页面打开更长时间。

接下来,我们将定义一个机器人。这个机器人将为我们工作。类定义基本上是描述一个我们想要的对象。例如,狗具有某些特征,例如腿、高度、速度和年龄。和机器人一样,我们需要输入它的特征。在本教程中,我试图使它尽可能简单,所以我们需要的唯一定义是我们将用于浏览器的驱动程序。

class VoteBot():
  def __init__(self):
      self.driver = webdriver.Chrome("C:\webdrivers\chromedriver.exe")

现在,当我们创建一个机器人时,首先要做的是定义驱动程序。我们可以实际尝试一下,看看效果如何。通过键入 python vote_bot.py,我们可以运行该程序。如果加上“-i”,就可以直接和代码交互了。

(作者截图)

重复上述步骤后,应该会打开一个新的浏览器窗口。如果你没有看到一个新的 Chrome 窗口,请确保你已经正确安装了 ChromeDriver 和 selenium,这在前面的步骤中有解释。

我们需要一个函数来完成投票。这里的投票过程只是打开一个链接,所以说我们选择第二个参赛者,我们只是复制投票的链接。下面的代码将打开投票页面,保持打开 1 秒钟,然后关闭。

class VoteBot():
  def __init__(self):
      self.driver = webdriver.Chrome("C:\webdrivers\chromedriver.exe")def vote(self):
    self.driver.get('[https://eaff.eu/bg/online-festival-vote-choice/30](https://eaff.eu/bg/online-festival-vote-choice/15)')
    time.sleep(1)
    self.driver.close()

现在,我们已经完成了我们的机器人。我们只需要添加一个循环,这样我们就可以生成无限量的投票并测试它。完整代码附后。

class VoteBot():
  def __init__(self):
      self.driver = webdriver.Chrome("C:\webdrivers\chromedriver.exe")def vote(self):
    self.driver.get('[https://eaff.eu/bg/online-festival-vote-choice/30](https://eaff.eu/bg/online-festival-vote-choice/15)')
    time.sleep(1)
    self.driver.close()while True:
  bot = VoteBot()
  bot.vote()

第三步。坐下来享受吧

(作者截图)

只需在您的终端中键入“python vote_bot.py ”,然后观察机器人多次重复该任务。正如你所看到的,机器人将投票,关闭窗口,并再次投票。

最后的话

本教程是为刚刚开始编程和网络抓取的人编写的。对于任何问题,请随时在这个帖子中留下你的问题,我会尽我所能帮助你。为了进一步实验,尝试使用不同类型的按钮和登录序列,更多的我将很快摆姿势。保持冷静,继续编码!

面向自然语言处理的网页抓取和预处理

原文:https://towardsdatascience.com/web-scraping-and-pre-processing-for-nlp-2e78810b40f1?source=collection_archive---------24-----------------------

冥想项目

使用 Python 抓取和处理 web 上的文本数据

照片由 timJUnsplash 上拍摄

对于自然语言处理,干净的数据很重要。当数据来自网络时更是如此。在这篇文章中,我们将通过一个斯多葛派哲学文本生成器的 web 抓取和数据预处理的真实例子。

我们将使用的数据是由流亡的罗马参议员塞内卡在斯托晚期写的《致卢西留斯的道德书》。

书信

这些信件来源于维基资源,这里是。这一页包括所有 124 封信的列表。其中每个字母都包含在它自己的页面中。

首先,我们必须从这个内容页面中提取 HTML。为此,我们使用 Python 的requestsBeautifulSoup库。

这给了我们一个漂亮的 Soup 对象,它包含了我们通过html给出的原始 html。让我们看看这是什么样子。

在这种情况下,我们必须提取每个字母的本地路径。BeautifulSoup 对象允许我们用soup.find_all('a')提取所有的<a>元素。然而,这将返回所有的 <a>元素,所以我们需要过滤那些链接到字母的元素。

我们使用正则表达式来实现这一点,这非常简单,我们构建正则表达式来搜索任何以Letter开头,后跟一个或多个空格\s+,最后以一到三位数\d{1,3}结尾的内容。这给了我们re.compile(r"^Letter\s+\d{1,3}$")

通过将这个正则表达式应用于 BeautifulSoup 提供的<a>元素列表,我们将得到如下结果。

麻痹性鼻出血

现在我们需要定义一个函数来解析每个页面的 HTML。这实际上非常简单,因为字母文本全部包含在页面上仅有的<p>元素中。

因此,与之前类似,我们提取所有的<p>元素。然后,在返回信件文本之前,我们进行少量的格式化,使文本更具可读性。

Omnis 书信

通过我们的pull_letter功能和letters_regex,我们可以阅读所有的信件,我们将把它们放在moral_letters中。

此时我们已经得到了所有需要的数据,整齐地存储在moral_letters中。

准备工作

将我们的数据格式化成 NLP 友好的格式要简单得多,尽管抽象得多。

我们需要将当前的文本转换成数字,创建数据的数字表示,我们称之为data_idx

为此,我们将创建一个char2idx字典,代表字符索引。顾名思义,这将字符'a', 'b', 'c'转换为索引0, 1, 2

char2idx中的每个字符也必须映射到一个唯一的索引。为此,我们必须在数据中创建所有字符的集合(集合只是列出唯一的值)。这组字符被称为词汇表,我们将把它定义为vocab

现在,让我们用新的格式来读塞内加的第一封信。

虽然这看起来很荒谬,但这正是我们在为 NLP 格式化文本数据时想要的。

现在剩下的就是对我们的数据进行切片和洗牌,然后就可以输入到模型中了。在我们的例子中,我们使用的是tensorflow

单形世界

TensorFlow 允许我们使用[tf.data.Dataset](https://www.tensorflow.org/api_docs/python/tf/data/Dataset),一个我们可以用来简化数据集转换过程的 API。为了从我们的 Numpy 数组data_idx创建数据集,我们使用tf.data.Dataset.from_tensor_slices

在训练中,我们一次只会看一段文字。为了将数据分割成序列,我们使用Dataset .batch方法。

由于这是一个文本生成器,我们的目标数据将只包含输入数据,向前移动一个字符。为此,我们将定义一个名为split_xy的函数。

最后,我们再次使用.batch创建 64 个序列的批次,然后使用.shuffle将它们混洗。

dataset里面,我们有 175 个批次(由于 *len(txt) / (SEQLEN * BATCHSIZE)* ) 。每个批处理都包含一个由split_xy函数构建的输入和目标数组。

这些数据现在已经完全准备好了,可以输入到模型中进行训练。

结论是什么

尽管外表复杂。机器学习的实现不再是一项庞大的任务,只留给我们这个时代最聪明的人。

我们现在生活在这样一个时代,我们可以教计算机从人类历史上一些最伟大的头脑中复制哲学。我们不仅能做到,而且非常容易做到。

这是一个迷人的时代,我希望我们都能充分利用这个时代。

感谢阅读!

我以前写过设计神经网络来重现斯多葛派哲学。如果你感兴趣,你可以在这里阅读:

[## 斯多葛派哲学——由算法构建

再现历史上最有权势的人之一所写的斯多葛派哲学

towardsdatascience.com](/stoic-philosophy-built-by-algorithms-9cff7b91dcbd)

For anyone that is curious, here are my (attempted) Latin translations of the article headers.**Epistulae**: Letters
**Unum Epistula Legimus**: We read one letter
**Omnis Epistulae**: All letters
**Praeparatio**: Preparation (eg preparing the data)
**Simplex Munditiis**: Elegance through simplicity
**Qui Conclusioni**: Here concludes / the conclusion

网页抓取基础知识

原文:https://towardsdatascience.com/web-scraping-basics-82f8b5acd45c?source=collection_archive---------0-----------------------

如何用 Python 从网站上抓取数据

照片由弗朗克五世从 Unsplash

在数据科学中,我们总是说“垃圾进垃圾出”。如果你没有好的质量和数量的数据,很可能你不会从中获得很多见解。Web 抓取是自动检索第三方数据的重要方法之一。在这篇文章中,我将介绍 web 抓取的基础知识,并用两个例子来说明用 Python 实现 web 抓取的两种不同方式。

什么是网络抓取

Web 抓取是一种从网站检索非结构化数据并以结构化格式存储它们的自动方式。比如你想分析什么样的面膜能在新加坡卖的更好,你可能想在 Lazada 这样的电商网站上把所有的面膜信息都刮下来。

你能从所有的网站上搜集信息吗?

抓取使网站流量激增,并可能导致网站服务器崩溃。因此,并不是所有的网站都允许人们刮。如何知道哪些网站是允许的,哪些是不允许的?你可以看看网站的‘robots . txt’文件。你只需简单地把 robots.txt 放在你想抓取的网址后面,你就会看到网站主机是否允许你抓取网站的信息。

以 Google.com 为例

Google.com 的 robots.txt 文件

你可以看到谷歌不允许它的许多子网站进行网络抓取。然而,它允许像“/m/finance”这样的路径,因此如果你想收集金融信息,这是一个完全合法的地方。

另一个注意事项是,您可以从 User-agent 上的第一行看到。在这里,谷歌为所有用户代理指定了规则,但网站可能会给某些用户代理特殊权限,所以你可能想参考那里的信息。

网页抓取是如何工作的?

网络抓取就像一个机器人浏览网站的不同页面,并复制粘贴所有的内容。当您运行代码时,它将向服务器发送一个请求,数据包含在您得到的响应中。然后您要做的是解析响应数据并提取出您想要的部分。

我们如何做网页抓取?

好了,我们终于到了。根据网站内容的结构,有两种不同的方法来抓取网页。

方法 1: 如果网站将所有信息都存储在 HTML 前端,你可以直接用代码下载 HTML 内容,从中提取有用的信息。

大致有以下 5 个步骤:

  1. 检查您要爬网的网站 HTML
  2. 使用代码访问网站的 URL,并下载页面上的所有 HTML 内容
  3. 将下载的内容格式化为可读格式
  4. 提取有用的信息,并将其保存为结构化格式
  5. 对于显示在网站多个页面上的信息,您可能需要重复步骤 2-4 以获得完整的信息。

这种方法的利弊:简单直接。然而,如果网站的前端结构发生变化,那么你需要相应地调整你的代码。

方法二:如果网站将数据存储在 API 中,用户每次访问网站时网站都会查询 API,那么您可以模拟请求,直接从 API 中查询数据

步骤:

  1. 检查您要爬网的 URL 的 XHR 网络部分
  2. 找出为您提供所需数据的请求-响应
  3. 根据请求的类型(post 或 get)以及请求头和负载,在您的代码中模拟请求并从 API 中检索数据。通常,从 API 获得的数据格式非常简洁。
  4. 提取出你需要的有用信息
  5. 对于对查询大小有限制的 API,您需要使用“For 循环”来重复检索所有数据

这种方法的利与弊:如果您能找到 API 请求,这绝对是一种首选方法。你收到的数据会更加结构化,更加稳定。这是因为与网站前端相比,公司不太可能改变其后端 API。但是,它比第一种方法稍微复杂一些,尤其是在需要身份验证或令牌的情况下。

web 抓取的不同工具和库

有许多不同的不需要任何编码的抓取工具。然而,大多数人仍然使用 Python 库来做 web 抓取,因为它易于使用,而且你可以在它的大社区中找到答案。

Python 中网页抓取最常用的库是美汤、请求、硒

Beautiful Soup: 它帮助您将 HTML 或 XML 文档解析成可读的格式。它允许您在文档中搜索不同的元素,并帮助您更快地检索所需的信息。

请求:这是一个 Python 模块,您可以在其中发送 HTTP 请求来检索内容。它通过发送 Get 或 Post 请求来帮助您访问网站 HTML 内容或 API。

Selenium: 它广泛用于网站测试,它允许你自动化网站上的不同事件(点击、滚动等)以获得你想要的结果。

你要么用 Requests +美汤,要么用 Selenium 做网页抓取。如果你需要与网站交互(JavaScript 事件),Selenium 是首选,如果不是,我会首选请求+漂亮的汤,因为它更快更容易

网页抓取示例:

问题陈述:我想了解一下当地的面膜市场。我对网上面膜的价格、折扣、评分、销售量等很感兴趣。

方法 1 示例(下载所有页面的 HTML)—laza da:

第一步:检查网站(如果使用 Chrome,可以右键单击并选择检查)

检查 Chrome 上的 Lazada 页面

Lazada 上价格的 HTML 结果

我可以看到我需要数据都用惟一的类名包装在 HTML 元素中。

第二步:使用代码访问网站的 URL,下载页面上所有的 HTML 内容

# import library
from bs4 import BeautifulSoup
import requests# Request to website and download HTML contents
url='https://www.lazada.sg/catalog/?_keyori=ss&from=input&q=mask'
req=requests.get(url)
content=req.text

在应用美丽的汤之前请求内容

我使用请求库从一个网站获取数据。你可以看到,到目前为止,我们得到的是无结构的文本。

第三步:将下载的内容格式化为可读格式

soup=BeautifulSoup(content)

这一步非常简单,我们所做的只是将非结构化的文本解析成漂亮的汤,你得到的如下。

使用美汤后的 HTML 内容

输出是一种可读性更强的格式,您可以在其中搜索不同的 HTML 元素或类。

第四步:提取出有用的信息并保存成结构化的格式

这一步需要一些时间来理解网站结构,并找出数据存储的确切位置。对于 Lazada,它以 JSON 格式存储在脚本部分。

raw=soup.findAll('script')[3].text
page=pd.read_json(raw.split("window.pageData=")[1],orient='records')
#Store data
for item in page.loc['listItems','mods']:
    brand_name.append(item['brandName'])
    price.append(item['price'])
    location.append(item['location'])
    description.append(ifnull(item['description'],0))
    rating_score.append(ifnull(item['ratingScore'],0))

我创建了 5 个不同的列表来存储我需要的不同字段的数据。我在这里使用了 for 循环来遍历内部 JSON 文档中的项目列表。之后,我将这 5 列合并到输出文件中。

#save data into an output
output=pd.DataFrame({'brandName':brand_name,'price':price,'location':location,'description':description,'rating score':rating_score})

Python 数据帧格式的最终输出

步骤 5:对于显示在网站多个页面上的信息,您可能需要重复步骤 2-4 以获得完整的信息。

如果你想收集所有的数据。首先,你应该了解卖家的总数。然后,您应该通过使用有效负载到 URL 传递递增的页码来遍历页面。下面是我收集的完整代码,我循环了前 50 页来获取这些页面上的内容。

for i in range(1,50):
    time.sleep(max(random.gauss(5,1),2))
    print('page'+str(i))
    payload['page']=i
    req=requests.get(url,params=payload)
    content=req.text
    soup=BeautifulSoup(content)
    raw=soup.findAll('script')[3].text
    page=pd.read_json(raw.split("window.pageData=")[1],orient='records')
    for item in page.loc['listItems','mods']:
        brand_name.append(item['brandName'])
        price.append(item['price'])
        location.append(item['location'])
        description.append(ifnull(item['description'],0))
        rating_score.append(ifnull(item['ratingScore'],0))

方法 2 示例(直接从 API 查询数据)— Ezbuy:

第一步:检查您想要抓取的 URL 的 XHR 网络部分,并找出提供您想要的数据的请求-响应

网络下的 XHR 部分—产品列表 API 请求和响应

我从网络上看到,所有的产品信息都列在这个叫做‘按条件列出产品’的 API 里。该响应提供了我需要的所有数据,并且是一个 POST 请求。

步骤 2:根据请求的类型(post 或 get)以及请求头&有效负载,在您的代码中模拟请求并从 API 中检索数据。通常,从 API 获得的数据格式非常简洁。

s=requests.session()#Define API url
url_search='[https://sg-en-web-api.ezbuy.sg/api/EzCategory/ListProductsByCondition'](https://sg-en-web-api.ezbuy.sg/api/EzCategory/ListProductsByCondition')#Define **header** for the post request
headers={'user-agent':'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36'}#Define **payload** for the request form
data={
    "searchCondition": 
        {"categoryId":0,"freeShippingType":0,"filter: [],"keyWords":"mask"},
        "limit":100,
        "offset":0,
        "language":"en",
        "dataType":"new"
    }req=s.post(url_search,headers=headers,json=data)

这里我使用请求库创建 HTTP POST 请求。对于 post 请求,您需要定义请求头(请求的设置)和有效负载(与这个 post 请求一起发送的数据)。有时这里需要令牌或身份验证,在发送 POST 请求之前,您需要先请求令牌。这里不需要检索令牌,通常只需遵循网络中请求有效载荷的内容,并为报头定义“用户代理”。

这里要注意的另一件事是,在有效负载中,我将 limit 指定为 100,offset 指定为 0,因为我发现它一次只允许我查询 100 个数据行。因此,我们稍后可以做的是使用 for 循环来改变偏移量并查询更多的数据点。

第三步:提取出你需要的有用信息

#read the data back as json file
j=req.json()# Store data into the fields 
for item in j['products']:
    price.append(item['price'])
    location.append(item['originCode'])
    name.append(item['name'])
    ratingScore.append(item['leftView']['rateScore'])
    quantity.append(item['rightView']['text'].split(' Sold')[0]#Combine all the columns together
output=pd.DataFrame({'Name':name,'price':price,'location':location,'Rating Score':ratingScore,'Quantity Sold':quantity})

来自 API 的数据通常非常整洁和结构化,因此我所做的只是以 JSON 格式读取它。之后,我将有用的数据提取到不同的列中,并将它们组合在一起作为输出。您可以在下面看到数据输出。

EZbuy 面罩数据输出

第四步:对于查询大小有限制的 API,您需要使用‘For 循环’来重复检索所有数据

#Define API url
url_search='[https://sg-en-web-api.ezbuy.sg/api/EzCategory/ListProductsByCondition'](https://sg-en-web-api.ezbuy.sg/api/EzCategory/ListProductsByCondition')#Define header for the post request
headers={'user-agent':'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36'}for i in range(0,14000,100):
    time.sleep(max(random.gauss(3,1),2))
    print(i)
    data={
        "searchCondition":
       {"categoryId":0,"freeShippingType":0,"filters":
        [],"keyWords":"mask"},
        "limit":100,
        "offset":i,
        "language":"en",
        "dataType":"new"
    }
    req=s.post(url_search,headers=headers,json=data)
    j=req.json()
    for item in j['products']:
        price.append(item['price'])
        location.append(item['originCode'])
        name.append(item['name'])
        ratingScore.append(item['leftView']['rateScore'])
        quantity.append(item['rightView']['text'].split(' Sold')[0])#Combine all the columns together
output=pd.DataFrame({'Name':name,'price':price,'location':location,'Rating Score':ratingScore,'Quantity Sold':quantity})

下面是在 Ezbuy 中抓取所有面膜数据行的完整代码。我发现总行数是 14k,因此我编写了一个 for 循环来遍历增量偏移量以查询所有结果。这里需要注意的另一件重要事情是,我在每个循环的开始放置了一个随机超时。这是因为我不希望非常频繁的 HTTP 请求损害网站的流量,并被网站发现。

最后,推荐

如果你想抓取一个网站,我建议先用 inspect 在网络部分检查 API 的存在。如果您可以找到对请求的响应,并为您提供所需的所有数据,那么您就可以构建一个稳定而简洁的解决方案。如果在网络中找不到数据,应该尝试使用 requests 或 Selenium 下载 HTML 内容,并使用 Beautiful Soup 格式化数据。最后,请使用超时来避免过于频繁地访问网站或 API。这可以防止你被网站屏蔽,有助于缓解网站的流量。

如果你有兴趣了解更多关于使用 Python 中的 Scrapy 进行网络抓取的知识,可以参考我下面的最新文章

[## Python 中使用 Scrapy 的 Web 抓取

如何检索新加坡的二手车信息

songhaowu.medium.com](https://songhaowu.medium.com/web-scraping-in-scrapy-c2d87796f677)

使用 Selenium、BeautifulSoup、Requests、lxml 和 Scrapy 的网络抓取 Boardgamegeek.com

原文:https://towardsdatascience.com/web-scraping-boardgamegeek-com-using-selenium-beautifulsoup-requests-lxml-and-scrapy-1902d478ecde?source=collection_archive---------48-----------------------

用 3 种不同的方法刮 boardgamegeek.com

左图:马库斯·斯皮斯克Unsplash 拍摄的照片。右图:罗伯特·科埃略Unsplash 拍摄的照片

这是一个使用 5 种不同工具以 3 种方式进行网络抓取的教程:Selenium、BeautifulSoup、Requests、LXML 和 Scrapy。我们将从同一个网站boardgamegeek.com收集数据。

目标

  1. 抓取大约 20,000 个棋盘游戏,解析数据,然后将数据转换为 CSV 文件。
  2. 学习 3 种不同的 web 抓取方法:Selenium + BeautifulSoup、Python 请求库+ lxml 库和 Scrapy 框架。

关于 Boardgamegeek.com

该网站存储了近 120,000 款桌游的数据,包括游戏元数据、论坛数据、在线市场数据、玩家社区数据等。你可以说 Boardgamegeek.com 是桌游的 IMDB。

该网站提供了一个排名列表。下图是排名前 10 的游戏。你可以在右上方看到,排名列表有 1180 页。每页有 100 个游戏。截至 2020 年 6 月 16 日,该数据库存储了 118,066 款桌游。然而,并不是所有的博弈都有完整的信息。只有 19023 场比赛有排名数据。排名值是根据玩家的投票计算的。没有排名意味着没有人为这个游戏投票。在这个项目中,我们将只收集 19,023 个有可用排名数据的游戏。

boardgamegeek.com 十大游戏

BGG 也有 API。每个游戏都有自己的 XML 页面。下面是游戏‘gloom haven’的 XML 文件的部分截图。

来自 BGG API 的游戏“Gloomhaven”的 XML 文件

方法和工具介绍

每个工具或语言库都是为了满足特定的用例而发明的。基于网站设计和数据量/复杂性,利用不同的工具将使工作更容易或更快。

简而言之,web 抓取是请求网页,然后解析 HTML 中包含的数据的过程。

请求阶段:

Python 请求库:

优点:是最常用的 Python 库。它简单易学。用 API 连接网站的绝佳选择。

缺点:不能用来模拟人类交互,比如点击按钮。

硒:

优点:它可以通过模仿人类的动作,如点击和拖动,与网站进行交互。对于用动态 Javascript 编写的网站来说,这是一个很好的选择。

缺点:它需要一个 chrome 驱动程序才能工作,并且必须与你的 Chrome 版本完全匹配。这降低了代码的可移植性。它的速度也很慢。

刺儿头:

优点:它速度快,结构化,功能丰富。它使用并行处理来快速收集数据。它拥有能够在同一个工具中抓取和处理数据的工具。

缺点:学习曲线很陡。

解析阶段:

美丽组图:

优点:对破损的 HTML/XML 文件非常宽容。简单易学,有据可查。直接从网站而不是 API 文件获取 html 的最佳选择。

缺点:比 lxml 慢一点。

Python lxml 库:

优点:专门解析 XML。Python 内置 ElementTree 的强大扩展,具有完整的 xpath 特性。好用。

缺点:没有刺儿头快。仅适用于 XML 文件。

刺儿头:利弊同上请求阶段

项目步骤:

要获得最高排名的 19,023 场比赛,我们需要做如下工作:

第一步:获取前 19,023 个游戏的游戏 id 列表

BGG API 不提供排名信息,所以我们需要先抓取排名页面。然后我们从每个游戏的 URL 中提取 gameID,这样我们就可以使用包含 gameID 的 URL 调用 API 来请求每个游戏的页面。我们需要先抓取排名网页的 HTML。

步骤 2:下载每个游戏的 XML 文件并解析数据

有了 gameID 列表,我们将能够请求每个游戏的 XML 文件,将它们下载到本地计算机,然后将数据解析到数据帧中,并保存到 CSV 文件中。

第三步:试着只用一个工具 Scrapy 来做上面的所有事情

有一种方法可以使用 Scrapy 做上面的所有事情。我们将试一试。

第一步:用硒+美容素刮痧

左:来自硒。右:来自 https://funthon.wordpress.com/2017/05/21/beautiful-soup-4/

为什么选择这些工具?

我们正在抓取网站的 HTML。网站包含 Javascript,所以需要 Selenium。此外,我们不确定 HTML 是否有任何错误,因为直接来自网页的数据不像来自 API 的数据那样结构化。因此,选择 BeautifulSoup 来解析数据。

设置硒

设置硒

写解析函数

用 Selenium 和 BeautifulSoup 解析函数

游戏排名列表的前 5 行

游戏 id 在 URL 里面。为了下一步,我们需要将它们提取到一个列表中。

步骤 2:使用 Python 的请求库+ lxml 库进行抓取

左:来自 pipy.org 右:来自 lxml.de

为什么选择这些工具?

我们将通过 BGG API 请求 XML 页面。这是一个简单的任务,不需要类似人类的互动。所以 Python 的请求库可以很好地完成这项工作。在我们获得 xml 文件之后,使用 lxml 解析它们是一个好方法,因为 lxml 专门用于 XML 解析,具有完整的 Xpath 特性和相对较快的速度。

请求 XML API 并将文件保存在本地

使用 Python 的请求库下载 XML 文件

编写解析函数

有 47 个标记后来被转换为数据框列。实际的解析代码非常长。下面是一些示例代码,涵盖了 BGG XML 文件中不同的标签情况。

这很好地展示了如何使用 lxml。

使用 lxml 解析函数的示例代码

通过连接步骤 1 和步骤 2 中的两个表获得最终的 CSV

由于 XML 文件没有排名信息或游戏 URL,我们需要连接两个表来获得最终的数据框。

连接两个数据框

我们需要删除包含重复数据的列,然后将数据框保存到 CSV 文件中。我们的最终数据有 50 列和 19023 行。

删除重复的列并保存到 csv 中

第三步:零碎的框架

来自 Scrapy.org

为什么用 Scrapy?

Scrapy 是一个强大的抓取框架。我们在步骤 1 和 2 中所做的所有工作都可以通过使用 Scrapy 来完成。此外,它还有许多优点:

  1. 它超级快!Scrapy 使用多线程,这使得它比使用其他一些 Python 库要快得多。例如,第一步中使用硒和 BeautifulSoup 的刮擦需要大约 20 分钟,但 Scrapy 只需要大约 90 秒!
  2. 一切都在一个地方,井井有条,非常适合复杂项目
  3. 与 BeautifulSoup、lxml 解析器和 Xpath 兼容

Scrapy 怎么编码?

VS 代码中的碎片

1。安装 Scrapy 并创建一个新项目

首先打开命令行终端,键入“pip install scrapy”。然后导航到保存项目文件的文件夹,在终端中键入:

BGG scrapy start project(或你的项目名)

2。红区:好有条理!

在终端中创建新项目后,Scrapy 会在项目文件夹中自动生成一组文件。当您在代码编辑器中加载文件夹时,您可以在红色正方形区域中看到文件结构。

Scrapy 用“蜘蛛”来刮。在 spiders 文件夹中,您可以创建一个新的蜘蛛文件,这将是一个 Python 脚本。另一个包括。py 文件为您提供了各种用途的代码结构,有助于您以后的编码,例如将所有自定义设置分组到“settings.py”中,或者用于构建数据管道。为了方便起见,输出文件也组织在这个区域中。

3。黄色区域:一切都以蜘蛛类开始

现在我们将编写蜘蛛 Python 脚本。为了刮擦,所有 Scrapy 需要的是一个蜘蛛类。首先,需要定义两个变量:“name”和“start_urls”。注意他们的名字是预先确定的,你不能用其他名字。“名称”用于稍后运行蜘蛛,start_urls 显示要抓取的第一个页面。

4。绿色区域:实际执行工作的解析函数

在 BS4 和 lxml 中,我们操作的对象是“汤”和“树”。在 Scrapy 中,它是“响应”。Scrapy 的与众不同之处在于它的语法。它只使用。css 和。xpath 作为它的选择器。考虑到新的语法,编写解析函数实际上类似于使用 BS 或 lxml。以下是 Scrapy 文件中的引文:

XPath 和 CSS 选择器

css 和 XPath 之间的语法差异

另一个区别是我们如何存储输出。我们需要创建一个字典来存储数据。我们需要用“收益”而不是“回报”。“yield”会将每次迭代的解析数据结果发送到 Scrapy,然后返回到循环中继续解析下一行数据。Scrapy 将保存所有迭代的结果,然后将数据保存到 setting.py 文件中定义的四种文件类型之一:CSV、JSON、JSON Lines 或 XML。

5。蓝色区域:请下一页!

当我们使用其他库时,我们通常定义一个输入页数的函数。而使用 Scrapy,你只需要告诉它的网址开始,然后它会使用一个下一页选择器继续点击下一页,直到结束或到达页面限制你在代码中设置。这是一个自我回调函数,也就是几行代码。

6.是时候坐下来享受了!

最后一步是运行蜘蛛脚本。在终端中,键入

scrapy crawl BG ranks(或你的‘name’变量的字符串)

轻轻一点,就能见证 Scrapy 的超级爬行速度。下图显示了生成的 CSV 文件。短短 90 秒就刮出了 19000 个游戏排名记录!

生成的 CSV 文件的预览

摘要

在本文中,我们了解了多种 web 请求工具和 XML/HTML 解析工具之间的区别。在现实中,人们通常出于习惯而坚持使用某些工具。然而,了解多种工具可以使你的网络抓取更快,更容易处理复杂的项目。感谢您的阅读!

使用 Selenium 的网页抓取

原文:https://towardsdatascience.com/web-scraping-e-commerce-website-using-selenium-1088131c8541?source=collection_archive---------12-----------------------

抓取网上书店的一个简单例子。

Christopher Gower 在 Unsplash 上的照片

在这篇文章中,我们将通过一个电子商务网站的网页抓取过程。我设计了这篇特别的帖子,是为了方便初学者。因此,如果您没有 web 抓取或 Selenium 方面的知识,您仍然可以继续学习。

为了理解网络抓取,我们需要理解 HTML 代码的基础知识。我们也会谈到这一点。

HTML 基础

关于 HTML 基础知识有很多东西要谈,但是我们将把重点放在对网络抓取有帮助的东西上(至少大多数时候)。

图 1,:一个简单的 HTML 代码, : HTML 元素,来源:作者

  • HTML 元素(图 1 右侧)—HTML 元素是开始标签、其属性、结束标签以及它们之间的所有内容的集合。
  • 属性 —是在开始标签中使用的特殊单词,用于控制元素的行为。属性及其值一起用于引用标记及其内容进行样式化。我们将在网络抓取中使用的最重要的属性包括classidname
  • **class** **id** 属性 — HTML 元素可以有一个或多个类,用空格分隔(见上图 1 左)。另一方面,HTML 元素必须有唯一的id属性,也就是说,一个id不能用于引用多个 HTML 元素。

简单的网页抓取

在我们进入电子商务网站的实际抓取之前,让我们抓取下图所示的网站(来自图 1 左边的 HTML 代码)

图 2:现场

从上图(图 2)中,请注意以下几点:

  1. 这是统一资源定位符( URL )。对于这种特殊的情况,定位器指向本地存储的 HTML 代码。
  2. 当您在页面中悬停以识别您感兴趣的元素时,标记为 2 的按钮非常重要。一旦您感兴趣的对象被突出显示,标签元素也将被突出显示。
  3. 这是页面源代码。它只是像图 1 左边的 HTML 代码。您可以通过单击 Ctrl+Shift+I 来检查页面,或者在站点上右键单击并选择选项上可用的检查元素检查来查看该页面源代码。

先决条件

为了进行网页抓取,我们需要selenium Python 包(如果你没有这个包,用pip安装)和浏览器webdriver。为了让selenium工作,它必须能够访问驱动程序。从这里下载与你的浏览器匹配的 web 驱动: ChromeFirefoxEdgeSafari 。下载 web 驱动程序后,保存它并记下路径。默认情况下, selenium会在当前工作目录下寻找驱动程序,因此你可能想把驱动程序保存在 Python 脚本所在的目录下。然而,您没有义务这样做。您仍然可以保存它,并在下面的第 5 行提供可执行文件的完整路径

代码片段 web 抓取的基本示例

  • 1 号线和 2 号线导入必要的库。
  • Line 4 an 5 —定义你下载的 web 驱动的路径,实例化一个 Chrome 驱动。我用的是 Chrome 网络驱动,但你也可以用 Firefox、Microsoft Edge 或 Safari。
  • 第 6 行 —驱动程序在 5 中启动一个 Chrome 会话,并在 6 中获取 url 源。
  • 第 7 行和第 8 行 —这一行暂停 Python 执行 5 秒钟,然后在第 8 行关闭浏览器。暂停是很重要的,这样你就可以对浏览器上发生的事情有一个粗略的了解,而关闭可以确保浏览会话结束,否则我们将会有很多 Chrome 会话窗口。等待页面加载时,睡眠时间也可能非常重要。然而,还有另一种开始等待的适当方法。

定位元素

这是网络抓取最重要的部分。在这一节中,我们需要学习如何通过使用不同的属性来获取 HTML 元素。

回忆 : 网页的元素可以用 **class** **id** **tag** **name** 或/和 **xpath** 来标识。id 是唯一的,但类不是。这意味着给定的 **class** 可以标识多个 web 元素,而一个 **id** 只能标识一个元素。

可以使用以下任何一种方法来标识一个 HTML 元素

  • driver.find_element_by_id
  • 驱动程序.按名称查找元素
  • driver.find_element_by_xpath
  • driver.find _ element _ by _ 标签 _ 名称
  • driver . find _ element _ byclass _ name

可以使用以下任何一种方法来标识多个 HTML 元素(结果是找到的元素列表)

  • 驱动程序.按名称查找元素
  • driver.find_elements_by_xpath
  • driver . find _ elements _ by _ tag _ name
  • driver . find _ elements _ by _ class _ name

注意: **id** 不能用于识别多个元素,因为 **id** 只能识别一个元素。

Snipet 2:定位元素

输出:

Element identified by id: **Content 2 here**
Element identified by class: **Content here**
Element identified by class: **Content 3 here**
Element identified by tag name: **My First Heading**
Element identified by xpath: **My first paragraph.**
  • 第 8 行 —注意container1是标识两个元素的类属性值,drive.find_element_by_class_name返回找到的第一个元素。
  • 为了从 HTML 元素中提取文本,我们使用了.text函数,如上面的代码片段所示。
  • 第 11 行 —通过xpath检查站点元素来定位元素,右键单击与感兴趣的元素匹配的源代码,并复制 XPath,如下图所示(图 3)

图 3:获取特定元素的 XPath

我们可以识别并循环通过由container1类识别的两个元素,如下所示

代码片段 3:定位多个元素

输出:

Content here
Content 3 here

抓取实际站点

现在,您已经了解了 selenium 的工作方式,让我们继续前进,清理我们应该清理的实际站点。我们将刮网上书店[ 链接 ]。

图 4:我们想要抓取的网站(来源:作者)

我们将如下进行。

  • 在页面上刮掉每本书的细节。每页 20 本书。利用每张卡片上的网址可以找到每本书的详细内容。因此,要获得这本书的详细信息,我们需要这个链接。
  • 把书的每一页都刮下来。这意味着我们将有一个循环来抓取页面中的每本书,还有一个循环来遍历页面。
  • 从一个页面移动到另一个页面需要修改 URL,这使得预测到任何页面的链接变得很容易。

以下是页面:

显然,我们可以注意到一个模式,它暗示着在页面中循环将会很简单,因为我们可以在循环过程中生成这些 URL。

刮一本书

图 5:一本书的元素检查。

在检查网站时,这里是突出显示区域的 HTML 代码(代表一本书)

<article class="product_pod">
 <div class="image_container">
  <a href="the-nameless-city-the-nameless-city-1_940/index.html">
   <img src="../media/cache/f4/79/f479de5f305c2ac0512702cf7155bb74.jpg" alt="The Nameless City (The Nameless City #1)" class="thumbnail">
   </a>
  </div>
  <p class="star-rating Four">
   <i class="icon-star"></i>
   <i class="icon-star"></i>
   <i class="icon-star"></i>
   <i class="icon-star"></i>
   <i class="icon-star"></i>
  </p>
  <h3>
   <a href="the-nameless-city-the-nameless-city-1_940/index.html" title="The Nameless City (The Nameless City #1)">The Nameless City (The ...</a>
  </h3>
  <div class="product_price">
   <p class="price_color">£38.16</p>
   <p class="instock availability">
    <i class="icon-ok"></i>

        In stock</p>
   <form>
    <button type="submit" class="btn btn-primary btn-block" data-loading-text="Adding...">Add to basket</button>
   </form>
  </div>
 </article>

在我们开始编码之前,让我们做一些观察

  • 有问题的书在article标签里面。值为product_prod的类属性标签
  • 我们在这张卡中需要的是获取 URL,也就是 a标签中的href。要进入href,我们需要向下移动层次如下:class= “product_prod” > h3标签> a标签和href属性的 get 值。
  • 事实上,所有页面中的所有书籍都属于同一个类别product_prod并带有article标签。

图 6:一本书的详细信息页面(添加了注释以显示我们感兴趣的细节)

片段 4:搜集一本书的细节

让我们浏览几行代码,这样你就能理解代码实际上在做什么

  • 第 16 行到第 18 行— 我们沿着 HTML 代码向下移动,以获得这本书的 URL。一旦我们得到链接,我们在 19 打开。注意 16 定位页面中所有的书,因为所有的书都属于同一个类product_prod,这就是为什么我们对它进行索引(索引 0)以只获得一本书
  • 同样值得注意的是,一本书的星级数是作为p标签的属性而来的。这是这颗星的位置:
<p class="star-rating Four">
   <i class="icon-star"></i>
   <i class="icon-star"></i>
   <i class="icon-star"></i>
   <i class="icon-star"></i>
   <i class="icon-star"></i>
  </p>

这本书被评为 4 星级,但这一事实被隐藏为 class 属性的值。你用get_attribute(class)来获取这样一个信息。在使用文本函数提取第行第 24 行的内容时,您将得到这样一个字符串

star-rating Four

因此,我们必须在使用第 28–38 行中的函数之前拆分字符串,以获得实际的星号。

  • 如果你在 23 中提取文本内容,你会得到这样的字符串
In stock (22 available)

我们需要的只是数字 22,这意味着我们有 22 份拷贝。我们通过第 25 行实现了这一点,在这里我们使用正则表达式来提取数字。

re.findall("\d+","In stock (22 available)")Output:
['22']
  • 在正则表达式中,\d 表示值[0–9 ],而+表示一个字符在该类中出现一次或多次,也就是说,在我们的例子中,我们希望捕获字符串中的任何数字(不考虑数字的数量)。

把所有的书都刮到一页

回想一下上面的第 16 行定位页面中的所有书籍。因此,为了在一页中抓取所有的书,我们需要循环遍历该行中生成的列表,如下所示

片段 5:把所有的书都刮到一页。一页里有 20 本书。

一旦你理解了前面抓取一本书的例子,那么这本书应该很容易理解,因为唯一的区别是我们想要遍历所有的书来提取链接(第 33 行到第 38 行),然后遍历这些链接来提取我们需要的信息(第 42–84 行)。

在这个代码片段中,我们还引入了 try-except 块来捕捉我们想要的信息不可用的情况。具体来说,有些书漏掉了description一节。

我相信您也会喜欢看到 selenium 在您观看时打开页面。尽情享受吧!

抓取所有页面的所有书籍

这里要理解的关键概念是,我们需要循环遍历每一页中的每一本书,也就是说,这里涉及到两个循环。如前所述,我们知道页面 URL 遵循某种模式,例如,在我们的例子中,我们有

我们可以很容易地创建一个 Python for-loop 来生成这样的 URL。让我们看看如何生成前 10 个

代码片段 6:通过修改页面 URL 生成 URL

输出:

[http://books.toscrape.com/catalogue/category/books_1/page-1.html](http://books.toscrape.com/catalogue/category/books_1/page-1.html)
[http://books.toscrape.com/catalogue/category/books_1/page-2.html](http://books.toscrape.com/catalogue/category/books_1/page-2.html)
[http://books.toscrape.com/catalogue/category/books_1/page-3.html](http://books.toscrape.com/catalogue/category/books_1/page-3.html)
[http://books.toscrape.com/catalogue/category/books_1/page-4.html](http://books.toscrape.com/catalogue/category/books_1/page-4.html)
[http://books.toscrape.com/catalogue/category/books_1/page-5.html](http://books.toscrape.com/catalogue/category/books_1/page-5.html)
[http://books.toscrape.com/catalogue/category/books_1/page-6.html](http://books.toscrape.com/catalogue/category/books_1/page-6.html)
[http://books.toscrape.com/catalogue/category/books_1/page-7.html](http://books.toscrape.com/catalogue/category/books_1/page-7.html)
[http://books.toscrape.com/catalogue/category/books_1/page-8.html](http://books.toscrape.com/catalogue/category/books_1/page-8.html)
[http://books.toscrape.com/catalogue/category/books_1/page-9.html](http://books.toscrape.com/catalogue/category/books_1/page-9.html)
[http://books.toscrape.com/catalogue/category/books_1/page-10.html](http://books.toscrape.com/catalogue/category/books_1/page-10.html)

因此,我们可以像下面这样简单地将所有页面中的所有书都刮掉

代码片段 7:抓取所有页面中的所有书籍(50 页,每页 20 本= 1000 本要抓取的书籍)

这个代码片段与上一个代码片段之间的唯一区别是,我们从第 34 行开始循环遍历页面,并且我们还将所有搜集到的信息写入一个名为all_pages.csv的 CSV 文件中。

我们还使用 try-expect 来处理在抓取过程中可能出现的异常。如果出现异常,我们只需退出并关闭浏览器(第 94 行)

图 7:生成的 CSV 文件(all_pages.csv)的主视图

结论

Web 抓取是从互联网上收集数据的一个重要过程。不同的网站有不同的设计,因此没有一个特定的刮刀可以用于任何特定的网站。最基本的技能是在高层次上理解 web 抓取:知道如何定位 web 元素,并能够在出现错误时识别和处理错误。当我们在不同的网站上练习网络抓取时,这种理解就产生了。

以下是更多网页抓取示例:

[## 网页抓取:抓取表格数据

在这篇文章中,我们将学习如何使用 Python 抓取 web 数据。简化。

towardsdatascience.com](/web-scraping-scraping-table-data-1665b6b2271c) [## 使用 Python 中的 BeautifulSoup 对新冠肺炎数据进行网络抓取

网络搜集是数据收集最重要的概念。在 Python 中,BeautfiulSoup、Selenium 和 XPath 是…

medium.com](https://medium.com/analytics-vidhya/web-scraping-covid-19-data-using-beautifulsoup-in-python-1bc087918980)

最后,一些网站不允许他们的数据被抓取,尤其是抓取和发布结果。因此,在抓取之前检查站点策略是很重要的。

https://medium.com/@kiprono_65591/membership加入媒体以获取媒体上的所有报道。

你也可以在我发文章的时候通过这个链接把文章发到你的邮箱里:https://medium.com/subscribe/@kiprono_65591

一如既往地感谢您的阅读:-)

用于机器学习的网页抓取

原文:https://towardsdatascience.com/web-scraping-for-machine-learning-5fffb7047f70?source=collection_archive---------14-----------------------

图片作者贝蒂·隆巴顿/ 阿奇博尔德汽车商店——教堂街 / CC BY-SA 2.0

买东西有个普遍规律,“少花钱不如多花钱”。出于个人原因,我需要买一辆二手车,但我并不着急,我有时间考虑并找到最好的交易。

在检查当地的二手车商店时,他们向我展示了价格在 7,000 至 10,000 欧元之间的汽车。这是一大笔钱,所以我想我应该利用我的数据科学技能来找到最好的交易。

数据采集

机器学习项目首先需要的是数据。你可以猜到,西班牙市场上没有二手车数据的数据集,即使有,也会因为价格不断变化而每个月都过时。

我从西班牙最受欢迎的二手车分类广告页面获得数据。出于隐私原因,我将对我使用的页面名称保密。用于搜索的限制如下:

  • 距离我:不到 100 公里
  • 车龄:10 年以下
  • 价格:低于 10.000 欧元

让我们检查一下用于从这些网站收集数据的工具:

  • urllib.request: 使用 Python 标准库中的这个模块来下载网站的 html 代码。
  • BeautifulSoup4: 用这个模块解析 html 代码,找到相关信息。

我们需要下载两件东西,一个页面包含我们限制的可用汽车列表,另一个页面包含汽车的所有信息。

对于汽车列表,一些示例 URL 可能是:

https://www.adspage/cars-search/?location=Barcelona&最高价格=10000 &年起=2010

对于某辆汽车,URL 可能是这样的:

【https://www.adspage/cars/?carid】= 141238

我们使用 urllib 下载并保存这些页面:

from urllib.request import urlopendef download_and_save_page(url, file):
    html_code = urlopen(url).read()#.decode('utf-8')
    f = open(file, 'wb')
    f.write(html_code)
    f.close()
    return html_code

首先,我们删除包含汽车列表的页面,找到所有可用汽车的链接并下载它们。这很容易用 BeautifulSoup 的 find_all 方法完成

links = soup.find_all('a', href=True, class_='car-link')
for link in links:
    print(link['href'])

请记住,分类广告页面通常遵循分页系统,因此在每个页面中,我们都会列出一定数量的汽车(例如 20 辆),为了让所有汽车可用,我们需要了解分页系统是如何工作的。通常我们只需在 URL 上添加一个页码,例如:

https://www.adspage/cars-search/?location=Barcelona&up price = 10000&year from = 2010&page= 7

使用此代码,我们可以创建一个汽车链接数据库,并将它们提供给下载功能,以使我们的 scraper 运行并下载包含所有可用汽车信息的页面。

下一步是处理所有下载的页面并提取汽车的相关信息。所有信息都保存在一个 CSS 文件中。我决定保存的数据是:

  • 广告网址(以便以后我发现有趣的东西时手动检查)
  • 汽车品牌
  • 汽车模型
  • 卖家类型(私人/专业)
  • 价格
  • 描述
  • Kms
  • 出版日期
  • 带图片的 URL 列表

我最终没有使用一些字段(描述和图片),因为它们增加了很多复杂性,但是它们可以包含相关信息,你可以通过查看图片来了解汽车的状况,描述多次谈到汽车的额外功能,可以提供相关信息(发动机损坏的部分)

提取数据主要是通过 BeautifulSoup 的 findfind_all 方法完成的,搜索页面上的相关字段。

soup.find('div', class_='car-price').get_text()

找到正确的类名很重要,我用 Firefox 的开发工具做到了这一点(用 Ctrl+Shift+C 打开检查器)。

使用检查器选择网站栏

使用检查器,我们选择页面上的所有相关字段,并记录它们的信息。

  • 是元素、

    元素还是什么样的元素?

  • 如何从所有同类元素中识别它们(惟一 id 或惟一类名)

连接所有这些元素,我们可以创建一个包含所有汽车数据的 CSV 文件。在我的例子中,CSV 文件是 5 MB,包含 3487 辆汽车的数据。该数据仅适用于 2019 年 12 月销售的汽车,并且符合我之前描述的搜索标准。获得更老的数据会很有趣,但在网上无法获得。

数据分析

现在到了有趣的部分,我们打开我们的 Jupyter 笔记本,开始分析数据。

#Load data
df = pd.read_csv('data/car_data.csv')

让我给你介绍一下 Pandas Profiling ,这是一个 python 模块,可以从 Pandas 数据帧生成报告。该报告为我们提供了数据集中所有变量的统计数据的快速可视化。

from pandas_profiling import ProfileReport
prof = ProfileReport(df)
prof.to_file('output.html')

kms 变量的统计信息

公里直方图

在极端值上,我们可以看到输入错误的值(超过一百万公里的汽车)

一些有趣的统计数据是在西班牙销售的最常见的品牌和型号:

快速可视化之后,我检查了数据集上不太常见的品牌,发现一些汽车品牌只有几个条目。我把它们删除了,因为这么少的数据会让它过度适合这些特定的品牌。

然后对品牌和型号应用一个热编码,最终得到 371 个变量。

使用训练/测试分割来检查 ML 模型的准确性,并使用 RMSE 来评估它们的性能。目标变量是汽车的价格。

我想谈论的车型是 XGBoost,它为 RMSE 和 KNN 提供了最佳价值,我发现这个应用程序很有趣,因为我们在搜索汽车价格时直观地将它与其他在售的类似汽车进行比较。

XGBoost:

import xgboost as xgb
model=xgb.XGBRegressor(random_state=1, n_estimators=5000, learning_rate=0.01)
model.fit(X_train, y_train)sqrt(mean_squared_error(y_val, model.predict(X_val)))

得到了 1.288,39 的 RMSE。请注意,这一幅度相当于欧元误差。这是一个很高的值,请记住,我们只查看价格超过 10.000 欧元的汽车,平均值为 7.226 欧元。

KNN:

from sklearn.neighbors import KNeighborsRegressor
knn = KNeighborsRegressor(n_neighbors=5)
knn.fit(X_train, y_train)sqrt(mean_squared_error(y_val, model.predict(X_val)))

即使我期望从这个模型的直观方法中得到好的结果,它也悲惨地失败了,给出了 7.242 的 RMSE。

结论

我从这个项目中得到的主要收获是,我可以找到与我在附近商店看到的一样好的汽车,并获得更好的价格,能够找到 4,000 至 5,000 英镑范围内的汽车,这是目前最划算的价格。

最后,我买了一辆我非常满意的雪铁龙 C4。

我买的车

我想提到的一些事情是,从分类广告页面提取的数据并不意味着以某一价格发布的汽车最终以该价格售出。大多数情况下,卖家在与买家谈过之后会降低价格,而这并没有反映在网站上。其他卖家可能会开出一个高得离谱的价格,但却无人问津,因为没有人愿意以这个价格购买他们的汽车。所有这些都使算法偏向于给出比真实价格更高的价格。

有很多广告缺少一些信息,有时他们缺少车龄,有时缺少公里数等。其他时候数据格式不佳,卖家没有在适当的字段中引入数据,最终导致数据点缺少大部分功能,但是他们在描述中以自己的格式引入所有这些数据,这是算法无法解释的。所有这些都会影响数据的质量,从而影响我们的结果。

改善这种分析的其他方法包括使用 NLP 从描述中添加信息,卖家有时会谈到汽车中包含的额外功能,有时会谈到汽车的发动机或状况,有时会说有机械问题。我相信从这些描述中可以提取出许多有趣的信息。另一种方法是使用计算机视觉从贴有广告的汽车图片中获得额外的信息,有时你可以看到汽车受到了一些影响,有时你可以看到汽车的内部,有时没有图片,这是一个不好的迹象。

这些仅仅是可以持续改善这个项目结果的许多途径中的一部分,然而在买了车之后,我感觉不到继续在这个项目上工作的动力。

Web 抓取:如何用 Selenium 处理日历

原文:https://towardsdatascience.com/web-scraping-how-to-handle-a-calendar-with-selenium-862ce689a7d7?source=collection_archive---------5-----------------------

照片由贾兹敏·奎诺尔Unsplash 拍摄

学习使用 Python 工具来抓取 web

❝ … 时间过得很慢,但却过得很快…❞—·爱丽丝·沃克

我坐在我最喜欢的沙发上看电视。嗯,说实话,我在频道冲浪。

也许没有什么有趣的东西可看,或者我太分心去想我在工作中不能解决的问题。

我把视线从电视上移开一分钟来回答一条信息。当我回头看屏幕时,它就在那里。我反复看的电影之一。

等一下。等等,博士,你是说你用一辆德罗宁造了一台时光机?马蒂·小飞侠说

"依我看,如果你要把时间机器做成一辆汽车,为什么不做得有点风格呢?”—医生回答

时间旅行。很多电影都在讲这个话题。我相信这是朋友们深夜闲聊的话题。

起初,我很高兴找到这部电影,因为我非常喜欢它。但后来,它提醒了我一个我无法解决的问题。

我并没有试图建造一台时间机器或者进行时间旅行。

我只是想在一个特定的网站上搜集历史数据。这个页面总是有相同的网址。但是当你从日历中选择不同的日子时,内容就变了。

如果选择新的日期,内容将会改变。但是,URL 地址将保持不变。

我当时真的很挣扎。我以前用 Scrapy 制作过刮刀(如果你想了解更多,请阅读我的 以前的帖子 )。

但是我知道这个 Python 框架有一些限制。其中之一是处理 Javascript。

我决定停止浏览频道。我开始阅读,突然,我找到了解决办法:硒。

S elenium 是一款方便的网络浏览器自动化工具。它能够打开选择的浏览器并模仿人类行为。

这意味着它可以执行点击按钮、填写表格或在网站上搜索信息等任务。很酷,对不对

安装包也非常容易。我们需要使用正常的 pip 语法:pip install selenium

但是还有一个额外的步骤需要完成。我们需要下载 Chrome 驱动 这个 WebDriver 是一个用于自动化测试的开源工具,它提供了导航到网页、用户输入、JavaScript 执行等功能。

注意下载与你的浏览器版本兼容的 ChromeDriver 版本

开始编码吧!

首先,我们将导入我们需要的模块。

  • 使用正则表达式的模块re
  • BeautifulSoup从网站上提取数据
  • selenium.webdriver启动浏览器
  • selenium.webdriver.[ActionChains](https://www.selenium.dev/selenium/docs/api/py/webdriver/selenium.webdriver.common.action_chains.html)实现鼠标移动等低级交互的自动化。

之后,我们需要创建一个新的 google chrome 实例。

我们将使用webdrive.Chrome()传递指向我们下载 ChromeDrive 的位置的 确切路径 作为参数。

然后,我们使用.get()方法将所需的 URL 作为参数传递。

如果我们运行这个,我们会看到一个新窗口打开,显示图例Chrome is being controlled by automated test software

刮网站首先要做的是了解网站的结构。特别是,我们如何指示硒,如何选择不同的日期。

让我们检查网页 HTML 代码,重点是日历元素。

我们想取消过去两年网站的内容。这里有许多可以遵循的策略。

我们将指示 WebDriver 点击 n 次前一个<按钮。所以如果我们在March 2020想去March 2018,就要按 24 次按钮。

让我们重温一下关于 XPath 的知识。

XPath代表 XML 路径语言。跟网页抓取有什么关系?我们将学习如何识别 HTML 元素。但是现在出现的问题是我如何向刮刀指出元素?答案是 XPath。

XPath 是一种特殊的语法,可用于浏览 XML 文档中的元素和属性。此外,它将帮助我们获得某个 HTML 元素的路径并提取其内容。

让我们看看这个语法是如何工作的

/用于向前移动一个代,tag-names给出哪个元素的方向,[]告诉我们选择哪个兄弟姐妹,//查找所有后代,@选择属性,*是通配符,表示我们想要忽略标签类型?

如果我们看到下面的 XPath:

Xpath = '//div[@class="first"]/p[2]'

我们会理解,从所有(//)带有class"""(div[@class="first"])的div元素中,我们想要第二个([2])段落(p)元素。

幸运的是,web 浏览器有一种简单的方法来获取元素的 XPath。

我们复制元素的 XPath 并将其传递给函数[.find_element_by_xpath()](https://selenium-python.readthedocs.io/locating-elements.html)

现在,是时候告诉 WebDriver 去点击这个元素了。我们通过从ActionChains()链接以下函数来实现:

  • .click()即会点击元素
  • .perform()即会执行动作

web 驱动程序应该如何按时返回

一旦日历回到 24 个月前,我们应该告诉 selenium 每天点击并抓取内容。

为了理解如何指向日元素,让我们再次检查网站。

看 HTML 代码。我们可以观察到不同的日期属性被赋予了不同的类值。

以灰色出现的日子,有day disable类。黑色的那一天,有类别day,选择的那一天(当前日期)有类别active day

最后一个类对于当前日期属性是唯一的,所以我们可以用它从日历中选择当前日期。

首先,我们将列出所有具有包含单词day的 class 属性的元素。

这一次,我们将使用函数[.find_element_by_class_name()](https://selenium-python.readthedocs.io/locating-elements.html)指向这些元素。当我们想通过类属性名定位一个元素时,这很方便。

一旦我们有了那个列表,我们将循环这个列表。对于我们找到的每个元素,我们获取它的属性并询问它是否严格等于day。如果是,我们会告诉 webdriver 点击它。

我们将等待 5 秒钟,以便可以加载网站。

之后,我们将使用BeautifulSoup浏览网站。在这里,我们可以插入任何代码来删除网站的内容。我们可以使用find()findall()方法。

一旦我们删除了内容,循环将移动到找到的下一个day元素。

请注意,我们每个月都需要这样做。所以一旦这个月的所有元素都循环了,我们就需要进入下个月。该过程与我们对上一个按钮所做的完全相同。

现在,我们将这个脚本保存在一个文件中(例如selenium_script.py))。为了运行脚本并开始废弃,我们打开一个新的终端窗口。

我们需要转到文件所在的文件夹,然后键入:

python3 selenium_script.py

之后会弹出一个 Chrome 窗口。开始自动点击不同的日期。我们会看到这样的情况:

网络驱动程序将模拟选择不同的日期

一旦所有的网站和日期都被废弃,我们将在终端中看到以下消息:

Process finished with exit code 0

这意味着一切顺利,没有遇到错误。

如果我们指定了一个文件来保存网站的内容,我们现在可以转到该文件并检查废弃的内容。

现在,轮到你用 Selenium 刮网站了!

如果你想了解更多关于这个话题的内容,请查看以下帖子:

使用 Selenium 的网页抓取简介

使用 Selenium-Python 进行网页抓取

3 分钟内完成网页抓取

原文:https://towardsdatascience.com/web-scraping-in-3-minutes-1c37830a29c1?source=collection_archive---------24-----------------------

简介:

数据,或任何种类的信息,是 21 世纪最宝贵的东西之一。数据是如此强大,以至于可以在许多方面利用它,例如预测未来的销售趋势以获取利润,在医疗保健行业中用于早期诊断结核病,从而挽救患者的生命,等等。因此,从不同来源提取有价值的数据是数据科学家应该掌握的关键技能之一。

在本文中,我们将学习如何使用 python 中的不同库从网站中提取数据。我们将使用 shorts 网站中的 来提取与板球、羽毛球和网球等不同运动相关的新闻文章。

照片由 Florian OlivoUnsplash 上拍摄

步骤 1:导入相关库

步骤 2:用漂亮的汤发出 Web 请求并解析

我们来看看某一类新闻的源代码这里

进入这个网页后,我们将看到不同的新闻,让我们集中在一个特定的新闻和它的源代码提取使用美丽的汤。

我们可以在右边看到新闻文章及其各自的源代码。我们将使用请求库和使用。在 url 上获取()以从网页访问 HTML 脚本。然后,我们将使用漂亮的 soup 库来解析 python 中的 HTML 语言。然后,进一步根据我们想要提取的信息类型,我们可以使用不同的 html 标签过滤信息,如使用

、。find()函数。

在完成上述步骤并解析 HTML 语言后,这个特定新闻的部分如下所示

在这种情况下,我们可以看到文章的标题位于这个类下-<div class = " news-card-title news-right-box ">。我们可以进一步看到标题存在于带有 attributes= "itemprop "和" headline "的< span >标签中。这可以通过使用。find()函数。

news1=soup.find_all('div', class_=["news-card-title news-right-box"])[0]title=news1.find('span',attrs={'itemprop':"headline"}).stringprint(title)We get the following output given below-Shuttler Jayaram wins Dutch Open Grand Prix

同样,如果我们要访问新闻内容,它位于这个类 <下 div class = " news-card-content news-right-box ">。我们可以进一步看到新闻的主体在于带有 attributes= "itemprop "和" articleBody "的< div >标签。这可以通过使用。find()函数。

news1=soup.find_all('div', class_=["news-card-content news-right-box"])[0]content=news1.find('div',attrs={'itemprop':"articleBody"}).stringprint(content)Indian Shuttler Ajay Jayaram clinched $50k Dutch Open Grand Prix at Almere in Netherlands on Sunday, becoming the first Indian to win badminton Grand Prix tournament under a new scoring system. Jayaram defeated Indonesia's Ihsan Maulana Mustofa 10-11, 11-6, 11-7, 1-11, 11-9 in an exciting final clash. The 27-year-old returned to the circuit in August after a seven-month injury layoff.

以类似的方式,我们可以提取任何信息,无论是图像、作者姓名、时间等。

步骤 3:构建数据集

让我们为 3 个不同的类别实现这一点,并将所有的文章、各自的内容和类别存储在一个数据框中。在本节中,我们将使用三个不同的 Url,然后我们将对每个 Url 执行相同的过程,并将所有文章、其内容、类别存储到一个列表中。

输出-

结论:

我们可以看到使用漂亮的 soup 库在 python 中实现 web-screwing 是多么容易。使用这种技术,我们可以轻松地收集优秀的数据,以便开始任何数据科学项目。

感谢阅读!

如果你喜欢我的工作,想支持我。支持我的最好方式就是在媒体上关注我。

使用 CSS 选择器在 R 中抓取网页

原文:https://towardsdatascience.com/web-scraping-in-r-using-rvest-and-selectorgadget-5fc5124547e?source=collection_archive---------17-----------------------

又名当客户做空你时如何获得更多数据

R 中的 Web 抓取比你想象的要容易——像 CSS 选择器和抓取库这样的工具可以快速完成工作。事实上,“最困难”的部分是识别元素的 CSS 路径,但是我将向您展示如何轻松地到达那里!

我曾经有一个客户(美国的一家商业保险经纪公司),他想要一个数据科学解决方案来提高他们的销售和转化率。看似直白?客户给我们的数据非常少——只有客户的唯一许可证号、销售结果(保单状态)和保费价格。

我开始在网上寻找相关数据的其他来源。客户的唯一许可证号是由美国政府交通部(DOT)颁发的 DOT 号。联邦汽车运输安全管理局(FMCSA)对与 DOT 编号相关的车辆和司机进行例行检查,并在其网站上发布报告。这是公共信息,不需要登录/密码即可访问。

一个点号的 FMCSA 安全报告部分截图。

像报告的撞车次数、车辆/驾驶员危险率这样的数据可以帮助优化保单保费,以增加客户购买保单的几率。

获得这一点需要 3 个步骤:

  1. 识别感兴趣的元素,并获取它们的 CSS 路径。
  2. 将抓取的元素压缩成一个数据帧。
  3. 清理输出,然后将其连接到现有数据(由客户端提供)。

包和工具

我使用了 rvest 库和 CSS 选择器 SelectorGadget 来抓取网页。该工具可以作为浏览器的扩展下载,这样可以更容易地确定网页上每个元素的 CSS 路径。

定义 URL 和网页

我开始使用单点编号报告。报告的 URL 包含点号本身,这对于以后遍历点号列表非常有用。

检查感兴趣的元素

首先,我想收集每个点号的注册地址,以及它们拥有的驱动程序的数量。我需要这些元素的 CSS 路径——这告诉 scraper 要抓取的元素的精确位置。一个地址,如果你愿意的话。

打开 SelectorGadget 扩展——浏览器底部会出现一个框。选择屏幕上列出地址的区域。该工具将在屏幕上突出显示许多其他元素——此时它已经选择了 67 个其他元素。只需点击黄色元素,直到只剩下绿色的地址部分。(这只需要 3 到 4 次点击)。额外元素的每次“取消选择”都会将 CSS 路径更新到地址的精确位置。

现在 address 元素的 CSS 路径可用了。截图自此处

现在“地址”是唯一突出显示的元素。红框里看似乱码的文字就是这个元素的 CSS 路径,这就是我们要传递给 rvest 去刮取的东西。

类似地,要获得驱动程序数量的 CSS 路径:

截图自此处

将 CSS 路径传递给 rvest:

我们有产出了!它必须被清洗,很多,但它的工作!

现在我将为所有的点号刮取更多的元素。

遍历所有的点号

我利用了 URL 反映点号的事实-https://ai . fmcsa . DOT . gov/SMS/Carrier/2844805/complete profile . aspx

我创建了一个包含每个点号的 URL 的向量。

现在,刮!

最后一步将所有不同的元素组合成一个数据帧,称为 fmcsa_data。这将需要一些时间,取决于你有多少迭代。我建议把电脑插上电源,给自己泡杯茶。

清洁数据框

产生的数据帧并不美观——大量无关的文本隐藏了相关的信息。还有一些缺失的数据——FMCSA 网站还没有一些点号的报告,所以什么也没有收集到。

对数据的进一步观察也揭示了许多不可见的特征。

清理这些数据是一个简单的过程:

  1. 删除空行。将每一列从因子转换为字符类型。
  2. 删除地址的不可见字符。
  3. 仅提取除地址、姓名和安全等级之外的所有列的数字。

清理后的 dataframe 就懂事多了!

这就是我们从成千上万份报告中整理出来的简洁明了的数据框架。

我是帕洛阿尔托 ScoreData 公司的数据科学家。我非常热衷于有效的沟通——我热衷于将统计数据转化为对业务友好的、可操作的见解。我想让这个博客成为一个分享我一路走来所学到的一些东西的空间,所以一起来吧!

https://www.linkedin.com/in/namrata-date/

使用 Selenium 从 Indeed.com 收集招聘信息

原文:https://towardsdatascience.com/web-scraping-job-postings-from-indeed-com-using-selenium-5ae58d155daf?source=collection_archive---------21-----------------------

使用 NLP 和神经网络的工作工资预测项目的第一部分

戴安娜·奥雷在 Unsplash 上的照片

我希望在我的数据科学之旅的早期就知道如何进行网络搜集!这是一个非常方便的工具,打开了很多酷项目的大门。对于刚接触编码的人来说,这听起来可能有点难以接受。但是相信我,这比你想象的更容易,更直观!

这篇文章是我最近完成的一个更大项目的第一部分,该项目旨在预测数据相关领域(数据科学、商业智能、分析等)的工作薪水。)通过文本分类和深度学习。为了构建模型,我需要收集大量的职位发布以及与职位发布相关的工资。

因此,我决定从 Indeed.com 那里刮乔布斯。我正在使用的 API 叫做 Selenium 。Selenium 广泛用于 web 自动化,它实际上非常容易安装和使用。您可以像这样安装 selenium:

pip install selenium

Selenium 需要一个驱动程序来连接 web 浏览器。你可以在这里找到 Chrome,Edge,Firefox 或者 Safari 的驱动。下载后,确保驱动程序与您的浏览器应用程序在同一路径。

进口硒

from selenium.webdriver.common.by import By
from selenium import webdriver
from selenium.webdriver.common.keys import Keysfrom selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC#specify driver path
DRIVER_PATH = '/Users/bonniema/Desktop/chromedriver'
driver = webdriver.Chrome(executable_path = DRIVER_PATH)

浏览页面

driver.get 方法将导航到 URL 给出的页面。执行此操作后,您将看到一个网页打开,表明 web 浏览器正在被控制。

driver.get('[https://indeed.com'](https://indeed.com'))

下一步是找工作。使用 Selenium 的一个好处是可以通过 id、名称或者 xpath 来识别一个项目或者按钮。在这种情况下,我想单击“查找工作”按钮。如果你检查页面,你可以看到 HTML 的“寻找工作”按钮。正如下图中突出显示的,我们可以看出按钮元素在一个<按钮>标签中,该标签在一个分隔线< div >下,该分隔线在 id="whatWhereFormId "的表单下。虽然您可以有不同的方法来标识按钮,但我将使用该表单 ID 来标识按钮。最好使用一个足够唯一的项目或属性(比如类),但是不要随时间而改变。

initial_search_button = driver.find_element_by_xpath
(‘//*[[@id](http://twitter.com/id)=”whatWhereFormId”]/div[3]/button’)initial_search_button.click()

关闭弹出窗口

单击“搜索”按钮后,会显示一个弹出窗口。我们可以用

close_popup = driver.find_element_by_id("popover-close-link")
close_popup.click()

执行高级搜索

在稍微摆弄了一下页面之后,我知道我想要执行高级工作搜索,在这里我可以指定搜索术语并设置每页显示的工作数量。查看 HTML 结构,看起来“高级工作搜索”被包装在一个标签中。一种方法是使用“contains”通过文本定位 xpath。

advanced_search = driver.find_element_by_xpath("//a[contains(text(),'Advanced Job Search')]")advanced_search.click()

另一种方法是右键单击该路径,检查是否可以直接复制 XPath。

似乎这个 XPath 不够通用,不能在这里使用。

//*[[@id](http://twitter.com/id)="jobsearch"]/table/tbody/tr/td[4]/div/a

输入搜索值

接下来,我们需要向搜索表单发送值。下面这段代码发送位置关键字,设置显示限制,并按日期对结果进行排序

#search data science 
search_job = driver.find_element_by_xpath('//input[[@id](http://twitter.com/id)="as_and"]')
search_job.send_keys(['data science'])#set display limit of 30 results per page
display_limit = driver.find_element_by_xpath('//select[[@id](http://twitter.com/id)="limit"]//option[[@value](http://twitter.com/value)="30"]')
display_limit.click()#sort by date
sort_option = driver.find_element_by_xpath('//select[[@id](http://twitter.com/id)="sort"]//option[[@value](http://twitter.com/value)="date"]')
sort_option.click()search_button = driver.find_element_by_xpath('//*[[@id](http://twitter.com/id)="fj"]')
search_button.click()

找到工作卡,立刻获得所有信息

我们的目标是从一个工作卡中获取职位、公司名称、城市和公司评级、工资(如果有的话)以及工作 url,然后迭代该页面上的所有工作卡。然后到下一页去刮更多的数据。

下面这段代码使用 for 循环遍历每页中的工作卡,并将相关信息保存在一个列表中。

现在繁重的提升部分已经完成了!

从个人网址获取职位描述

descriptions=[]
for link in links:

    driver.get(link)
    jd = driver.find_element_by_xpath('//div[[@id](http://twitter.com/id)="jobDescriptionText"]').text
    descriptions.append(jd)

把它们放在一个数据框里!

df_da=pd.DataFrame()
df_da['Title']=titles
df_da['Company']=companies
df_da['Location']="Palo Alto, CA"
df_da['Link']=links
df_da['Review']=reviews
df_da['Salary']=salaries
df_da['Description']=descriptions

网页抓取—朝鲜棒球组织(KBO)

原文:https://towardsdatascience.com/web-scraping-korea-baseball-organization-kbo-40bf6210a267?source=collection_archive---------65-----------------------

抓取网页,创建一个体育场的地图,球队发挥和可视化击球统计

南韩蚕室棒球场(照片由晓星崔Unsplash 上拍摄)

大约一周前,ESPN 开始转播朝鲜棒球组织(KBO)的比赛,自 3 月以来首次提供现场体育比赛。渴望现场表演的粉丝们,它提供了一些东西。除非你是丹()那样的铁杆球迷,否则你不会对 KBO 队或球员很熟悉。因此,我尝试用数据科学和 Python 编程来介绍 KBO。

KBO 队在哪里比赛?

KBO 是南韩最高的职业棒球联盟。它从 1982 年开始有六个队参加比赛,后来扩大到 10 个队。这是十支 KBO 球队和他们主场比赛的城市。

  • 斗山熊队(首尔)
  • 韩华鹰队(大田)
  • 起亚老虎队(光州)
  • 基武姆英雄(首尔)
  • KT Wiz(水原)
  • LG 双胞胎(首尔)
  • 乐天巨人(釜山)
  • 数控恐龙(昌原)
  • 三星雄狮(大邱)
  • SK 双足飞龙(仁川)

废弃 Wiki 页面以检索体育场名称

KBO 维基页面提供了几个表格,其中一个包含球队名称和他们比赛的体育场。我们可以使用 Pandas 的 read_html 废弃这些表。Pandas 的 read_html 提供了一种将表读入 DataFrame 对象列表的简洁方法。

[## KBO 联赛

KBO 联赛(韩语:KBO 리그),原名韩国棒球锦标赛(韩语:한국야구선수권대회;罗马化…

en.wikipedia.org](https://en.wikipedia.org/wiki/KBO_League)

wikipage = "[https://en.wikipedia.org/wiki/KBO_League](https://en.wikipedia.org/wiki/KBO_League)"
result = pd.read_html(wikipage)
result

检查结果后,我们可以看到第三个表包含球队、城市、体育场、容量和加入。

在选择了第三个表并用第一行替换了标题之后,我们有了一个显示体育场信息的熊猫数据帧。

#df = third table
df = result[2]#change top row to header
df.columns = df.iloc[0]
df = df[1:]
df

从体育场名称获取地理编码

使用 geopy 的地理编码器,我们可以只传递体育场的名称来检索纬度和经度。我不得不把“大田汉巴特棒球场”替换为“韩华生命鹰公园”,因为地理定位器无法识别前者。

def geolocate(loc):
    try:
        loc = geolocator.geocode(loc)
        # Return latitude and longitude
        return (loc.latitude, loc.longitude)
    except:
        # Return missing value
        return np.nandf['Geolocate'] = df['Stadium'].apply(geolocate)

创建地图

在我们检索了每个体育场的纬度和经度之后,我们可以使用 yellow 来创建球队比赛的地图。

import folium
from folium.plugins import MarkerCluster

#empty map
m= folium.Map(tiles="cartodbpositron")marker_cluster = MarkerCluster().add_to(m)for i in range(len(df)):
        lat = df.iloc[i]['Latitude']
        long = df.iloc[i]['Longitude']
        radius=10
        popup_text = """Team : {}<br>
                     City : {}<br>"""
        popup_text = popup_text.format(df.iloc[i]['Team'],
                                   df.iloc[i]['City']
                                   )
        folium.CircleMarker(location = [lat, long], radius=radius, popup= popup_text, fill =True).add_to(marker_cluster)#show the map
m

五个队在汉城或附近比赛,另外五个队在韩国南部比赛。

周围的首尔区域被缩放,并且显示了带有球队名称和城市的 folium 标记。

刮 KBO 统计

这篇文章(网络搜集 NBA 数据)提供了一个从篮球参考网站搜集 NBA 数据的极好的教程。类似地,我们可以删除 Baseball-Reference.com 的棒球统计数据,因为该网站提供了包括 KBO 在内的全面的球队和球员统计数据。

下面的代码块将 2020 年 KBO 的击球统计数据抓取到一个熊猫数据帧中。

然而,抓取的熊猫数据帧的数据类型是对象。我们可以将非对象类型转换成数字,以便以后可视化。

我们现在可以可视化团队本垒打或任何其他你想要的统计数据。

摘要

总而言之,从维基百科中抓取一个表格,然后用于创建一个地图,从棒球参考中抓取当前击球数据。希望这能提供一些有价值的信息。下面你可以找到更多的资源,如如何观看。希望你也喜欢这些现场棒球比赛!

[## ESPN 时间表上的 KBO,如何观看,朝鲜棒球联盟的球队等等

韩国棒球组织的常规赛季正在进行中,这意味着是时候进行一些现场棒球比赛了——

www.espn.com](https://www.espn.com/mlb/story/_/id/29136672/kbo-espn-schedule-how-watch-teams-korea-baseball-league-more) [## MyKBO.net

致力于韩国棒球组织(KBO)和韩国棒球的一个地点。韩国棒球时间表,统计数据…

www.mykbo.net](http://www.mykbo.net/) [## 在电视上看韩国棒球?让我们来帮忙

有很多蝙蝠翻转,但吐痰是不允许的。这里有一批球员要留意谁可能会登陆…

www.nytimes.com](https://www.nytimes.com/2020/05/05/sports/baseball/coronavirus-baseball-korea-opening.html)

网页抓取—制作您自己的数据集

原文:https://towardsdatascience.com/web-scraping-make-your-own-dataset-cc973a9f0ee5?source=collection_archive---------21-----------------------

图片鸣谢:巨蟒请求巨蟒美瞳

尽管有许多资源可以获得所需的数据集,但最好还是有一个自己创建的数据集。在当前新冠肺炎的场景中,我发现了关于worldometers.com的有趣数据。它显示了一个包含案例总数、已执行测试总数、已关闭案例总数等的表格。该表每天更新。

出于好奇,我想在自己的数据集中包含这些新冠肺炎数据。在基本 python 库、pandas、numpy 和 BeautifulSoup 的帮助下,我决定将这些数据收集到我自己的数据集中。由于我成功地创建了数据集,我想与大家分享我的故事。因此,我将带你浏览我的笔记本。

网页抓取是从网页中收集信息的过程

当手动收集大量数据时,需要大量的时间和精力。如果要收集的数据来自定期更新的网页,这将是非常激烈的。因此,最好有一个脚本,它可以自动从网页中提取数据,并以所需的格式存储。

你所需要的是一个 python 包来解析来自网站的 HTML 数据,以表格形式排列它,并做一些数据清理。有几十个软件包可以完成这项工作,但我的故事继续与 BeautifulSoup。

美丽组图

它是一个 python 库,使我们能够从网页中抓取所有内容。假设有一个网页包含一些有趣的信息,但没有提供直接下载数据的方法。BeautifulSoup 提供了一套工具来从网页中提取数据,并定位隐藏在 HTML 结构中的内容。

让我们开始创建自己的数据集……

第一步:安装所需的软件包

您需要 requests 包,它允许您使用 Python 发送 HTTP 请求。如果你已经预装了,你只需要导入它。否则,您需要使用 pip 安装程序来安装它。

pip install requests
pip install beautifulsoup4

我使用 Python 内置的 HTML 解析器将网站输入的文本数据转换成复杂的解析树,可以进一步处理得到所需的数据。如果你想使用不同的解析器,在这里你可以找到一个助手。

一旦你安装了所有的包,把它们导入到你的脚本中。

import pandas as pd
import numpy as np
import requests
from bs4 import BeautifulSoup

第二步:BeautifulSoup 构造器

BeautifulSoup 构造函数接受 2 个输入参数

  • 字符串—它是您要解析的标记。这个标记是使用 python requests包的 get()方法获得的。这个 get()方法返回包含服务器对 HTTP 请求的响应的requests.Response()对象。此外,此响应对象的 text 方法获取响应的内容。整个字符串作为 BeautifulSoup 构造函数的第一个参数传递。
  • 解析器—它是您想要用来解析标记的方法。您需要提供解析器的名称。我使用了 python 内置的 HTML 解析器。
website='[https://www.worldometers.info/coronavirus/#countries'](https://www.worldometers.info/coronavirus/#countries')
website_url=requests.get(website).text
soup = BeautifulSoup(website_url,'html.parser')

好了..在 3 行代码中,您将所需网页的所有内容都输入到了笔记本中。

图 1:开发者工具中的信息

开发者工具中来自元素标签(红色标记)的所有 HTML 文本都将存储在 BeautifulSoup 对象soup中。如上图 1 所示,当你在元素标签中滚动特定行时,它会在网站的实际表格中高亮显示相应的单元格。

第三步:熊猫数据框

为了制作 Pandas DataFrame,我们需要将对象soup中的所有文本数据转换成表格格式。在上面的图片 1 中,我还标记了 3 个绿色矩形。这些是你需要在汤里找到的术语。

让我们简单理解一下,这些术语是什么意思—

  • <tbody>:指定网页上的表格。
  • <tr>:指向该表中的特定行。
  • <td>:指向该行的特定单元格。

在 python 脚本中,您将使用 object soup的方法在解析的文本中查找这些术语。

my_table = soup.find('tbody')

变量my_table将包含网页上的表格,但仍然是 HTML 格式。它包含另外两个术语<tr><td>,分别指向单独的行和单元格。在下面的代码中,您将把这个my_table转换成包含列和值的实际表格。

请注意,下面这段代码是 2020 年 4 月写的。稍后,请检查网站上的列的顺序,并相应地修改代码。

table_data = []for row in my_table.findAll('tr'):
    row_data = [] for cell in row.findAll('td'):
        row_data.append(cell.text) if(len(row_data) > 0):
        data_item = {"Country": row_data[0],
                     "TotalCases": row_data[1],
                     "NewCases": row_data[2],
                     "TotalDeaths": row_data[3],
                     "NewDeaths": row_data[4],
                     "TotalRecovered": row_data[5],
                     "ActiveCases": row_data[6],
                     "CriticalCases": row_data[7],
                     "Totcase1M": row_data[8],
                     "Totdeath1M": row_data[9],
                     "TotalTests": row_data[10],
                     "Tottest1M": row_data[11],
        }
        table_data.append(data_item)

现在您得到了table_data,它实际上是一个包含列和值的表。这个表现在将被转换成一个熊猫数据帧df

df = pd.DataFrame(table_data)

注意,在这个数据帧中,所有的列都是 object 类型。此外,这些物品中还有一些不需要的字符,如 /\n|+。所有常用的数据清理过程现在都可以在上面使用。

根据个人需求,您可以从原始数据帧中提取不同的列和行,根据需求对其进行清理和转换。

这种数据的收集、评估、清理和转换被称为数据争论过程。这里有一个关于数据争论过程的有趣的可视化快速阅读。

[## 数据争论—从原始到干净的转变

简单的三个字的解释

towardsdatascience.com](/data-wrangling-raw-to-clean-transformation-b30a27bf4b3b)

第四步:导出到 Excel

然后,可以使用 pandas 将经过清理和转换的最终数据帧导出到 excel。

df.to_excel('Covid19_data.xlsx', index=True)

总之,您为新冠肺炎创建了自己的数据集。

您还可以通过抓取不同的网页来创建多个数据集,并最终将所有数据集组合在一起。想了解更多关于组合不同数据集的信息吗??

在这里,我有一个关于 Python Pandas 中合并选项的简单的 4 分钟阅读。你需要记住的只是下面文章的最后一张图,解释了所有类型的数据集 join 操作。

[## 加入表格

了解 Python pandas 中的 merge()和 concat()

towardsdatascience.com](/join-the-tables-ab7fd4fac26b)

使用 Matplotlib Python 库可以很容易地可视化这种自行创建的数据集,并且可以很容易地定制可视化,如下文所述。

[## matplotlib——一个分层的数据可视化库

使用 Matplotlib 了解地块定制的简单方法

medium.com](https://medium.com/analytics-vidhya/matplotlib-a-layered-data-visualization-library-870d992ff4b5)

通过我的故事……

我带你通过 4 个简单的步骤将一个网页抓取到一个 excel 表格中。我演示了如何使用简单易用的 BeautifulSoup 包抓取网页,并将这些数据转换成熊猫数据帧。完整的笔记本可以在我的 Github 个人资料中找到。

这里有一些资源,可以帮助你解决这个问题

欢迎您随时提出反馈意见,并通过 LinkedIn 与我联系!!!

网络抓取 NBA 2k 数据

原文:https://towardsdatascience.com/web-scraping-nba-2k-data-d7fdd4c8898c?source=collection_archive---------40-----------------------

照片来自 Pixabay,作者为 Rochigb

这是一个学习宝贵的数据科学技能的实践示例

并不是所有值得分析的数据都打包好了(我正看着你呢,Kaggle)。最终,在您的数据科学之旅中,您会发现自己在寻找一个并不存在的数据集。是吗?

进入:网页抓取。

网络抓取是从网页中获取数据的一个非常有价值的工具。抓取不是手动收集信息,而是自动获取和存储数据。它涉及一个网页:

  • 从语法上分析
  • 重新格式化
  • 复制到电子表格中

入门

此时,您可能想知道可以使用哪些库来开始 web 抓取。有多种选择,但最常见的库和框架是:

  • 要求
  • 美味的汤
  • Scrapy
  • LXML

在本教程中,我们将使用以下库:

  • 熊猫
  • 要求
  • 美丽的声音
  • 有平面的

第一步是导入上面的内容:

查看网页

网站包含许多不同的元素,因此检查网页以了解 python 代码应该以哪些元素为目标非常重要。

像 HoopsHype 这样的网站定期收集体育数据并发布。

我们将关注 2016 年 NBA 2K 收视率。这将是基于篮球评级的数据可视化或机器学习项目的伟大先驱。

检查一个网站将揭示其源代码

要轻松检查网站,请将光标放在包含数据的元素中或突出显示该元素。然后,右键单击并选择“Inspect”来访问站点的源代码。如果数据存储在一个表中,您将会知道,因为像表行()和数据单元格()这样的标记不是实际的元素。

下面是一个数据单元格标签示例:

<td style=”text-align:center;”>71</td>

下面是一个表格行标签的例子:

<tr style=”font-size:11px;”></tr>

解析网页

解析的第一步是获取你想要抓取的网页的 url。接下来,使用 requests get()方法查询页面。这将返回一个请求。响应对象。

让我们创建一个漂亮的对象。这将表示已解析的页面。使用“美化”方法可以让我们更好地看到嵌套标签,但这不是必需的。LXML 是 BeautifulSoup 可以使用的 XML 和 HTML 解析器。这增加了额外的功能,尤其是涉及字符串处理的功能。

调用 BeautifulSoup 对象应该会产生页面的源代码:

解析页面的最后一步是定位我们想要的表。我们需要选择源代码中的第一个表(因此是[0])。如果您的目标表是源代码中的第二个表,您应该使用[1]等等。

Pandas 中的 read_html 方法返回一个数据帧列表,这对下一步很重要。

重新格式化数据

现在我们有了一个数据帧的列表,我们需要以一种有意义的方式重新格式化数据。让我们打印 read_html 方法返回的内容:

调用 to_json 方法会将传递的对象转换成一个 JSON 字符串。orient 参数告诉方法预期的 JSON 字符串格式。我们选择'记录指示,因为我们知道 read_html 方法返回一个列表,并且列表相对容易操作。处理其他适应症是可行的,但更困难。

因为我们最终想要一个有不同数据行的数据帧,我们需要制表(排列)数据。

我们将数据帧列表的第一个元素(唯一的数据帧)制成表格。

因为我们现在可以看到新的行字符(\n),所以让我们将每一行拆分到它自己的列表中。

数据开始变得越来越清晰。

现在每一行都是一个列表元素

最后,让我们通过按空格字符拆分来将每一行拆分成单元格。

这导致破折号成为额外的第一行。

我们可以使用 pop()函数轻松删除行。

将数据复制到数据帧中

将数据复制到 Pandas 数据帧并检查输出非常简单。

我们还需要几个步骤来准备这个表,以便进行分析。

首先,每隔一行用 NaN 值填充。让我们重新定义 DataFrame,只取每隔一行。

我们还需要删除第一列、最后两列和第一行,因为它包含标题值。

DataFrame 现在没有多余的列或行了!

如果需要,您可以重命名这些列。

该表现在可以进行分析了!

如果您想将数据帧写入 csv,可以通过 to_csv 函数来完成。

现在我们已经有了分数和球员的名字,我们可以绘制这些数据了。我用了 Plotly。

这里没有惊喜。

2016 年得分最高的球员是勒布朗詹姆斯。现在它已经被清理了,您可以用这些数据做更多的事情!

结论

以下是最终代码:

本教程涵盖了:

  • 常见的 web 抓取库
  • 使用 BeautifulSoup 和 LXML 解析 HTML
  • 将数据复制到熊猫数据框架中
  • 修复网页抓取的常见错误
  • 导出 web 抓取的数据

网络抓取是利用数据和练习熊猫技能的好方法。这是为机器学习或可视化项目获取数据的一种很好的方式。

Web 抓取新闻文章以构建 NLP 数据管道

原文:https://towardsdatascience.com/web-scraping-news-articles-to-build-an-nlp-data-pipeline-92ec6083da2?source=collection_archive---------7-----------------------

Tensorflow 2.0、Scrapy 和 SpaCy 的 3 个简单步骤!

照片由 Marija ZaricUnsplash 上拍摄

尽管可以使用现成的数据集进行实验,但是生成 NLP 数据管道可以进一步提高您的技能,并在项目选择上给予您更多的自由。

在这篇文章中,我将从头到尾解释我的 NLP 数据工作流程。我在下面列出了我在工作流程中使用的三个开源 Python 框架;

完整的工作流程将通过 3 个易于遵循的步骤进行解释。我的 GitHub 资源库中提供了完整的源代码。

让我们从第一步开始。

步骤 1 — Web 抓取:从 Web 中提取原始文本数据

我决定从 TRT World 网站 上抓取新闻文章,使用抓取的文本数据来试验几种 NLP 算法和数据管道概念。

我的目标是收集大约 2000-3000 篇文章,并将它们存储在一个 JSON 文件中。

为此,我创建了一个 Scrapy 项目并生成了 2 个蜘蛛;一个用于提取文章链接,另一个用于提取文章标题,以及使用上一步中捕获的链接的正文。

让我们安装 Scrapy 并开始我们的 Scrapy 项目。

**# Install the scrapy**
$ pip install scrapy**# Start web scraping project with scrapys**
$ scrapy startproject TRTWorld
$ cd TRTWorld**TRTWorld $** scrapy genspider Articles trtworld.com
**TRTWorld $** scrapy genspider ArticleScraper trtworld.com

我们的第一个蜘蛛是 "Articles.py" ,它将通过访问 500 个网页来获取文章链接。它将提取每个页面上可用的文章链接的 href 信息,并将它们存储在一个 JSON 文件中。

**# Spider 1 
# Articles.py which scrape article links****# imports**
import scrapy
from scrapy.http import Request
from TRTWorld.items import TrtworldItemclass ArticlesSpider(scrapy.Spider):
 name = 'Articles'
 allowed_domains = ['trtworld.com']
 start_urls = ['http://trtworld.com/']def start_requests(self):**# Hardcoded URL that contains TURKEY related subjects**
  url="https://www.trtworld.com/turkey?page={}"link_urls = [url.format(i) for i in range(0,500)]**# Loops through 500 pages to get the article links**
  for link_url in link_urls:print(link_url)**# Request to get the HTML content**
    request=Request(link_url, cookies={'store_language':'en'}, 
    callback=self.parse_main_pages)yield requestdef parse_main_pages(self,response):item=TrtworldItem()**# Gets HTML content where the article links are stored**
  content=response.xpath('//div[@id="items"]//div[@class="article- 
  meta"]')**# Loops through the each and every article link in HTML 'content'**
  for article_link in content.xpath('.//a'):**# Extracts the href info of the link to store in scrapy item**
   item['article_url'] =    
   article_link.xpath('.//@href').extract_first()item['article_url'] =   
   "https://www.trtworld.com"+item['article_url']yield(item)def parse(self, response):
  pass

在我们完成我们的第一个蜘蛛后,我们现在可以用下面的命令运行它来生成“article _ links”JSON 文件。

**TRTWorld $** scrapy crawl -o article_links.json -t json Articles

下一步是使用存储在 JSON 文件中的链接抓取新闻文章。为此,让我们创建我们的第二个蜘蛛是“文章刮刀”。

**# Spider 2
# ArticleScraper.py which scrape article headlies and bodies****# imports**
import scrapy
from scrapy.http import Request
from TRTWorld.items import TrtworldItemimport jsonclass ArticlescraperSpider(scrapy.Spider):
 name = 'ArticleScraper'
 allowed_domains = ['trtworld.com']
 start_urls = ['[http://trtworld.com/'](http://trtworld.com/')]def start_requests(self):

  **# Open the JSON file which contains article links** with open('/Users/erdemisbilen/Angular/TRTWorld
  /article_links.json') as json_file:

   data = json.load(json_file)

   for p in data:
    print('URL: ' + p['article_url'])**# Request to get the HTML content**
    request=Request(p['article_url'],
               cookies={'store_language':'en'},
               callback=self.parse_article_page)
    yield requestdef parse_article_page(self,response):item=TrtworldItem()
 a_body=""**# Extracts the article_title and stores in scrapy item**
 item['article_title']=response.xpath('//h1[[@class](http://twitter.com/class)="article-
 title"]/text()').extract();**# Extracts the article_description and stores in scrapy item**
 item['article_description']=response.xpath('//h3[[@class](http://twitter.com/class)="article-
 description "]/text()').extract();**# Extracts the article_body in <p> elements**
 for p in response.xpath('//div[[@class](http://twitter.com/class)="contentBox bg-w 
 noMedia"]//p/text()').extract():

   a_body=a_body+p
   item['article_body']= a_body
   yield(item)def parse(self, response):
  pass

下面的命令运行文章抓取器蜘蛛并生成一个包含 3000 篇新闻文章的 JSON 文件。您可以在下面看到蜘蛛生成的 JSON 文件的内容。

**TRTWorld $** scrapy crawl -o article_body.json -t json ArticleScraper

' article_body.json '文件,包含 3000 篇世界新闻文章

步骤 2 —文本预处理:归一化和去噪

既然我们的 JSON 文件中存储了大约 3000 篇文章,我们可以开始考虑在我们的实验性 NLP 研究中使用它们。

要在 NLP 应用程序中使用任何文本数据,我们必须将文本转换成数字,因为计算机很难理解这些单词。

在此之前,我们应该清理和规范化我们的文本。这一步将我们的文本转换为更简单和结构化的形式,以便机器学习算法可以更有效和更好地执行。

在我们的例子中,我们有包含结构良好的句子的新闻文章,所以我们可能不需要应用下面列出的所有预处理。请参见下面的示例文章。

任何预处理之前的示例新闻文章

让我们从安装空间 和它所需的依赖项开始。

**# Install the spaCy**
pip install -U spacy**# Install the spaCy Lemmatization** pip install -U spacy-lookups-data**# Install the spaCy English Model**
python -m spacy download en_core_web_sm

为了清理和规范文本,我们将在文本中应用以下流程:

  • 句子分割

首先,我们将把每篇文章分成句子。然后我们将在 spaCy 库的帮助下清理和规范化每个句子。

**# Splitting text into sentences using spaCy**
def split_sentences(document):
 sentences = [sent.string.strip() for sent in doc.sents]
 return sentences
  • 删除停用词

停用词是语言中最常用的词,对自然语言处理任务(如情感分析或文本分类)没有帮助。因此,您可以考虑将它们从文本中删除,以提高模型的速度和准确性。

在我们的例子中,我使用了 spaCy 的内置停用词。您可以根据特定领域的要求自定义默认停用词。

**# Removes stopwords from a sentence using spaCy (token.is_stop)**
def remove_stopwords(sentence):
 sentence = nlp(sentence)
 processed_sentence = ' '.join([token.text for token in sentence if token.is_stop != True ])
 return processed_sentence**# Removes stopwords from spaCy default stopword list**
nlp.Defaults.stop_words -= {"my_stopword_1", "my_stopword_2"}**# Adds custom stopwords into spaCy default stopword list** nlp.Defaults.stop_words |= {"my_stopword_1", "my_stopword_2"}**# Prints spaCy default stopwords**
print(nlp.Defaults.stop_words)
  • 删除标点、引号、括号、货币字符和数字

通常,我们只需要 NLP 管道中的单词,这意味着我们必须从句子中删除标点符号和其他特殊字符,包括数字。

**# Removes punctuation and special chars from a sentence using spaCy** 
def remove_punctuation_special_chars(sentence):
 sentence = nlp(sentence)
 processed_sentence = ' '.join([token.text for token in sentence 
 if token.is_punct != True and 
     token.is_quote != True and 
     token.is_bracket != True and 
     token.is_currency != True and 
     token.is_digit != True])
 return processed_sentence**# spaCy - List of special charecters to be removed
_currency = r"\$ £ € ¥ ฿ US\$ C\$ A\$ ₽ ﷼ ₴"
_punct = (
    r"… …… , : ; \! \? ¿ ؟ ¡ \( \) \[ \] \{ \} < > _ # \* & 。 ? ! , 、 ; : ~ · । ، ۔ ؛ ٪" )
_quotes = r'\' " ” “ ` ‘ ´ ’ ‚ , „ » « 「 」 『 』 ( ) 〔 〕 【 】 《 》 〈 〉'**
  • 词汇化

词汇化是将单词还原成它的基本形式。这是通过把一个词的屈折和派生的相关形式简化为它的基本形式来实现的。

词汇化旨在减少词汇量并使单词规范化。

**# Lemmatization process with spaCy**
def lemmatize_text(sentence):
    sentence = nlp(sentence)
    processed_sentence = ' '.join([word.lemma_ for word in 
    sentence])

    return processed_sentence

空间化和降噪处理后的例句

你可以在上面看到在词汇化和停用词删除后句子是如何被修改的。

根据手头的 NLP 任务,您可以考虑不应用某些清理和规范化过程,因为在上述每个过程中都会有一定程度的信息丢失。

在某些情况下,我们可能希望看到词频来理解文本的内容。【spaCy】提供易于应用的工具来实现这一点。下面,您可以看到包含文本预处理和词频计算功能的完整 Python 脚本。

**# JSONtoTXT.py****# Reads news articles from a JSON file
# Splits the content into sentences
# Cleans and normalizes the content
# Write each processed sentence into a text file**import json
import spacy
from spacy.lang.en import English # updated
from spacy.lang.en.stop_words import STOP_WORDS
from collections import Counter
import re**# Loads the spaCy small English language model**
nlp = spacy.load('en_core_web_sm')**# Removes stopwords from spaCy default stopword list** nlp.Defaults.stop_words -= {"my_stopword_1", "my_stopword_2"}**# Adds custom stopword into spaCy default stopword list** nlp.Defaults.stop_words |= {"my_stopword_1", "my_stopword_2"}print(nlp.Defaults)**# Calculates the frequency of words in a document**
def word_frequency(my_doc):**# all tokens that arent stop words or punctuations**
 words = [token.text for token in my_doc if token.is_stop != True 
 and token.is_punct != True]**# noun tokens that arent stop words or punctuations**
 nouns = [token.text for token in my_doc if token.is_stop != True 
 and token.is_punct != True and token.pos_ == "NOUN"]**# verb tokens that arent stop words or punctuations**
 verbs = [token.text for token in my_doc if token.is_stop != True 
 and token.is_punct != True and token.pos_ == "VERB"]**# five most common words**
 word_freq = Counter(words)
 common_words = word_freq.most_common(5)
 print("---------------------------------------")
 print("5 MOST COMMON TOKEN")
 print(common_words)
 print("---------------------------------------")
 print("---------------------------------------")**# five most common nouns**
 noun_freq = Counter(nouns)
 common_nouns = noun_freq.most_common(5)
 print("5 MOST COMMON NOUN")
 print(common_nouns)
 print("---------------------------------------")
 print("---------------------------------------")**# five most common verbs**
 verb_freq = Counter(verbs)
 common_verbs = verb_freq.most_common(5)
 print("5 MOST COMMON VERB")
 print(common_verbs)
 print("---------------------------------------")
 print("---------------------------------------")**# Removes stopwords from a sentence using spaCy (token.is_stop)**
def remove_stopwords(sentence):
 sentence = nlp(sentence)
 processed_sentence = ' '.join([token.text for token in sentence if 
 token.is_stop != True ])
 return processed_sentence**# Removes punctuation and special chars from a sentence using spaCy** def remove_punctuation_special_chars(sentence):
 sentence = nlp(sentence)
 processed_sentence = ' '.join([token.text for token in sentence 
  if token.is_punct != True and 
     token.is_quote != True and 
     token.is_bracket != True and 
     token.is_currency != True and 
     token.is_digit != True])
 return processed_sentence**# Lemmatization process with spaCy**
def lemmatize_text(sentence):
    sentence = nlp(sentence)
    processed_sentence = ' '.join([word.lemma_ for word in 
    sentence])
    return processed_sentencedef remove_special_chars(text):
 bad_chars = ["%", "#", '"', "*"] 
 for i in bad_chars: 
  text = text.replace(i, '')
 return text**# Splitting text into sentences using spaCy**
def split_sentences(document):
 sentences = [sent.string.strip() for sent in doc.sents]
 return sentencessentence_index = 0with open('/Users/erdemisbilen/TFvenv/articles_less.json') as json_file:
 data = json.load(json_file)

 with open("article_all.txt", "w") as text_file:
  for p in data:
   article_body = p['article_body']
   article_body = remove_special_chars(article_body)doc = nlp(article_body)sentences = split_sentences(doc)
   word_frequency(doc)for sentence in sentences:
    sentence_index +=1
    print("Sentence #" + str(sentence_index) + "-----------------")
    print("Original Sentence               : " + sentence)
    sentence = remove_stopwords(sentence)
    sentence = remove_punctuation_special_chars(sentence)
    print("Stopwors and Punctuation Removal: " + sentence)
    sentence = lemmatize_text(sentence)
    print("Lemmitization Applied           : " + sentence)
    text_file.write(sentence + '\n')

 text_file.close()

您可以在下面看到,脚本在处理新闻文章后产生的内容。

既然我们已经清理并规范化了我们的文本,并将其拆分成句子,现在是时候用 Tensorflow 2.0 构建一个数据管道了。

步骤 3 —构建数据管道:tf.data API

在许多情况下,将文本内容直接输入 NLP 模型并不是管理数据输入过程的有效方式。

tensor flow 'TF . data API'考虑到灵活性和效率,提供了更好的性能。如果你想了解为什么'TF . data '比传统的数据管道更好,我鼓励你观看这个视频。

我将使用 tensor flow"TF . data . textline dataset API "来构建我的 NLP 数据管道。

让我们从安装“张量流”和“张量流-数据集”开始。

**# Install the tensorflow with pip**
$ pip install tensorflow**# Install the tensorflow-datasets with pip**
$ pip install tensorflow-datasets

我将主要按照 TensorFlow 提供的 【加载文本】 教程来开发我的数据管道。

首先,我们将使用" TF . data . textline dataset "和我们在前面步骤中生成的" articlesTXT.txt "文件来构建我们的数据集。

虽然我们的数据管道中只有一个 txt 文件,但是下面的代码提供了加载和标记几个 txt 文件的能力。

parent_dir = "/Users/erdemisbilen/Angular/TRTWorld/articlesTXT"
FILE_NAMES = ['article_all.txt']BUFFER_SIZE = 2000
BATCH_SIZE = 128
TAKE_SIZE = 200def labeler(example, index):
  return example, tf.cast(index, tf.int64)labeled_data_sets = []for i, file_name in enumerate(FILE_NAMES):
  lines_dataset = tf.data.TextLineDataset(os.path.join(parent_dir, 
  file_name))
  labeled_dataset = lines_dataset.map(lambda ex: labeler(ex, i))
  labeled_data_sets.append(labeled_dataset)all_labeled_data = labeled_data_sets[0]for labeled_dataset in labeled_data_sets[1:]:
  all_labeled_data = all_labeled_data.concatenate(labeled_dataset)

all_labeled_data = all_labeled_data.shuffle(
    BUFFER_SIZE, reshuffle_each_iteration=False)

然后我们会使用" tfds . features . text . tokenizer "将句子拆分成记号,构建我们的词汇集。

tokenizer = tfds.features.text.Tokenizer()vocabulary_set = set()for text_tensor, _ in all_labeled_data:
  some_tokens = tokenizer.tokenize(text_tensor.numpy())
  vocabulary_set.update(some_tokens)vocab_size = len(vocabulary_set)print("Vocabulary size.   :" + str(vocab_size))
print("-------------------------------")
print(vocabulary_set)
print("-------------------------------")

词汇量和我们词汇中的单词

一旦我们创建了词汇表,下一步就是通过为词汇表中的每个单词分配一个惟一的整数值来对词汇表中的每个单词进行编码。这是一个基于索引的编码过程,它用唯一的索引号映射每个单词。

encoder = tfds.features.text.TokenTextEncoder(vocabulary_set)example_text = next(iter(all_labeled_data))[0].numpy()
print(example_text)encoded_example = encoder.encode(example_text)
print(encoded_example)

然后,我们可以使用映射函数对整个数据集进行编码。

def encode(text_tensor, label):
  encoded_text = encoder.encode(text_tensor.numpy())
  return encoded_text, labeldef encode_map_fn(text, label):
  encoded_text, label = tf.py_function(encode, 
                                       inp=[text, label], 
                                       Tout=(tf.int64, tf.int64))
  return encoded_text, labelall_encoded_data = all_labeled_data.map(encode_map_fn)

句子的编码形式

我们的数据集包含不同长度的句子。现在,最后一步是将每个数据集项目填充到特定大小的向量,因为许多 NLP 模型使用固定长度的向量维度。

同时,我们将以 128 的批处理大小对数据集的内容进行批处理。这将是我们在训练过程的每次迭代中输入到模型中的数据集项目的数量。

train_data = all_encoded_data.skip(TAKE_SIZE).shuffle(BUFFER_SIZE)
train_data = train_data.padded_batch(BATCH_SIZE, padded_shapes=([200],()))test_data = all_encoded_data.take(TAKE_SIZE)
test_data = test_data.padded_batch(BATCH_SIZE, padded_shapes=([200],()))sample_text, sample_labels = next(iter(test_data))sample_text[0], sample_labels[0]

填充后,我们数据集中的所有句子都表示为一个向量(大小为 200),如下所示。

填充后的数据集项

现在我们的数据管道已经准备好了,我们可以开始构建一个 LSTM 模型来测试我们的数据管道。

**#Training a LSTM model to test the data pipeline**
vocab_size += 1model = tf.keras.Sequential()
model.add(tf.keras.layers.Embedding(vocab_size, 64))
model.add(tf.keras.layers.Bidirectional(tf.keras.layers.LSTM(64)))for units in [64, 64]:
  model.add(tf.keras.layers.Dense(units, activation='relu'))# Output layer. The first argument is the number of labels.
model.add(tf.keras.layers.Dense(3, activation='softmax'))optimizer = tf.keras.optimizers.Adam(learning_rate=0.005, amsgrad=True)model.compile(optimizer= optimizer,
              loss='sparse_categorical_crossentropy',
              metrics=['accuracy'])log_dir="logs/fit/" + datetime.datetime.now().strftime("%Y%m%d-%H%M%S")tensorboard_callback = tf.keras.callbacks.TensorBoard(log_dir=log_dir, histogram_freq=1)model.fit(train_data, epochs=10, steps_per_epoch=4, validation_data=test_data, callbacks=[tensorboard_callback])eval_loss, eval_acc = model.evaluate(test_data)print('\nEval loss: {:.3f}, Eval accuracy: {:.3f}'.format(eval_loss, eval_acc))

用 Tensorflow 训练 LSTM 模型

从上面可以看到,数据通过我们构建的数据管道成功地输入到模型中。

摘要

在这篇文章中,我试图解释我从零开始构建 NLP 数据管道的方法。我希望我的文章能帮助你构建你的 NLP 应用程序。

Web 抓取 1:抓取表格数据

原文:https://towardsdatascience.com/web-scraping-scraping-table-data-1665b6b2271c?source=collection_archive---------7-----------------------

在这篇文章中,我们将学习如何使用 Python 从 web 上抓取表格数据。简化。

卡洛斯·穆扎Unsplash 上拍摄的照片

网络搜集是数据收集最重要的概念。在 Python 中, BeautifulSoupSeleniumXPath 是可以用来完成网页抓取任务的最重要的工具。

在本文中,我们将重点关注 BeautifulSoup 以及如何使用它从维基百科页面获取 GDP 数据。我们在这个网站上需要的数据是表格的形式。

概念的定义

请看下图,然后我们可以继续定义 HTML 表格的组成部分

图 2

从上图我们可以推断出如下:

标签定义了一个 HTML 表格。

一个 HTML 表格由一个元素和一个或多个、

| 和 | 元素组成。 |

元素定义了表格行,元素定义了表格标题,元素定义了表格单元格。

一个 HTML 表格也可以包括、、、和元素。

我们感兴趣的是检查给定站点的元素(在这种情况下,是我们想要废弃的站点——图 1 的最右边显示了站点的元素)。在大多数电脑中,你访问网站并点击 Ctrl+Shift+I 来检查你想要废弃的页面。

注意:网页的元素通过使用标签上的 class 或 id 选项来识别。id 是唯一的,但类不是。这意味着一个给定的类可以标识多个 web 元素,而一个 id 只能标识一个元素。

现在让我们看看我们想要刮的网站的图像

图 3

从该图中,请注意以下几点:

  1. 这是统一资源定位符( URL )。我们需要这个。
  2. 感兴趣对象的标签元素。该对象由定义,而不是由 id : class = “wikitable sortable jquery”定义。注意,tag 元素包含 3 个标识一个表的类(类之间用空格分隔)。除了我们将在这里使用的站点元素的一般引用外,id被用作支持使用 CSS 等语言的样式的引用。
  3. 现场共有 3 张桌子,上图中编号为 345 。为了这篇文章,我们将通过如何刮表 3 ,你可以很容易地找出如何做 45
  4. 当你在页面中悬停以识别你感兴趣的元素时,标有 6 的按钮非常重要。一旦您感兴趣的对象被突出显示,标签元素也将被突出显示。例如,对于我们的案例,标签 2 与标签 3 相匹配。

实际刮削

必需的包: bs4,lxml,pandas 和 requests。

一旦你有了所说的包,我们现在可以通过代码。

在这个代码片段中,我们导入必要的包并解析站点的 HTML 内容。

片段 1

检查代码片段 1 中的站点元素和/或soup变量后,您会发现图 3 中显示的三个表属于同一个类wikitable

片段 2

OUTPUT: 
Number of tables on site:  3

为了废弃第一个表,我们只需要从gdp获得第 0 个索引。下面代码片段中的body 变量包含表格的所有行,包括标题。标题将在body[0]中,所有其他行将在列表body[1:]

片段 3

OUTPUT:
['Rank', 'Country/Territory', 'US$']

标题看起来没错。

接下来,我们需要如下循环其余的行

片段 4

此时,我们在标题上有了标题,在 all_rows 上有了所有其他行,从这里我们可以将这些数据和标题作为 Pandas 数据帧传递

图 4

完整代码

警告

网络内容受版权保护,在大多数情况下,版权限制内容的复制、分发、传输和采用。当你打算删除这样一个网站时,你可能需要获得内容所有者的明确许可,否则你未经适当同意的删除行为可能会给你带来违约的麻烦。

然而,一些网站在知识共享许可下提供其内容,允许您毫无问题地复制、修改和分发这些内容,尽管一些网站可能对此类内容的商业化提供限制。

底线是在抓取网页之前,你需要确定你有权利这样做。

结论

网络搜集是从网络上收集数据的最重要的工具。要了解更多关于网络抓取的信息,你可以浏览这个包含更多例子的知识库。

加入 https://medium.com/@kiprono_65591/membership的媒体,全面了解媒体上的每个故事。

你也可以在我发文章的时候通过这个链接把文章发到你的邮箱里:【https://medium.com/subscribe/@kiprono_65591

感谢阅读。

网页抓取工具比较—入门所需的一切

原文:https://towardsdatascience.com/web-scraping-tools-comparison-all-you-need-to-get-started-915f1d0d57d8?source=collection_archive---------13-----------------------

一个简单而简洁的美丽的汤,硒,和羊瘙痒的回顾。完成实际的网页抓取例子。

每种工具都有其优点和缺点

我希望您的反馈能让我知道您想阅读什么样的项目——请花几秒钟时间在最后的投票中留下您的答案!谢谢大家!

什么是网页抓取?

网络抓取在当今变得越来越重要。我在这里大胆地说一下,假设你已经听说过“数据是新的石油”这句话。如果我们将网络抓取定义为从几乎任何网站快速收集各种数据的能力,就不难理解为什么会有如此多的企业和工具提供网络抓取服务。

在你开始自己的项目之前,最好记住什么是好的网页抓取礼仪

极限是天空

你可以使用网络抓取来获取各种各样的数据,如文本、数字、图像、视频、声音等等。并不是所有的网站都提供无缝获取数据的 API,所以我们通常不得不创造性地使用一些好的老式抓取方法。

更复杂的网站结构将需要更先进的抓取技术,但你会惊讶地发现,收集数据和从零开始构建自己的数据集是多么容易。如果您希望自己的数据科学产品组合脱颖而出,这一点尤其有用!

网络抓取三位一体

本文将重点介绍三个不同的 Python 库,对于您开始第一个项目来说,这已经足够了:

  • 美汤
  • 刺儿头

我将介绍它们的主要特性和局限性,并提供一些何时使用其中一种的例子。

如何做出一道漂亮的汤

如果你之前没有经验,美丽的汤可以说是开始你的网络抓取之旅的最佳方式。了解一两件关于 Python 的事情会有所帮助,比如如何遍历列表或字典,以及一点点 pandas 来处理你提取的数据。

它是最友好的用户界面,但这是有代价的——它也是最不灵活的,它不能与使用 JavaScript 的网站一起工作——稍后会详细介绍。

它是如何工作的

网站是用 HTML 代码构建的(至少大部分是这样!).如果你想看到你喜欢的网站背后的代码,在 Chrome 上按 CTRL+U 就可以了(在其他浏览器上找“查看源代码”)。您将看到一个 HTML 文档,其中包含您正在浏览的页面的结构。这些 HTML 代码是我们注入到美丽的汤里的。

该过程的第一步通常是使用请求模块和获取命令来获取 HTML 代码并将其放入变量中。一旦完成,您就可以提取您需要的信息了。

你所需要做的就是煮一些 …明白了吗?!

这实际上是一个很好的类比,可以理解下面的例子中发生了什么。一旦您获得了带有页面代码的变量,您就可以将它转换成一个漂亮的 Soup 对象,让您选择想要的任何配料。

在本例中,该对象是 soup 变量,我们将尝试打印页面的标题。在一个普通的 HTML 页面中,主标题总是一个“h1”标签,所以你可以看到对我来说,要汤,要配料是多么容易。

一些成分——我指的是 HTML 标签——将需要一些尝试和错误!每次的逻辑都一样。唯一的区别将是网站的结构如何,以及你如何定义你想要的标签。

多给我看看!

有一个非常好的视频很好地解释了这个问题,如果你决定更深入地研究这个问题,你也可以查看我的个人资料。你会对我们如何从页面中获取特定的标签有一个更好的了解。

如果你试图抓取一个使用 JavaScript 来加载内容的网站,那么到目前为止我们所看到的还不够。为此,我们将不得不使用硒!

用硒赢得你的条纹

当你进入网络抓取的世界时,你最终会到达一个包含 JavaScript 来加载内容的网站。这意味着是时候远离美味的汤,摄入硒了。

如果您对 JavaScript 不熟悉,可以考虑交互式网站,它需要您展开和/或点击对象来显示新信息。预订是一个很好的例子,一个有很多按钮和下拉菜单的网站……你明白了吧!

请务必检查网站是否允许刮擦,并查看 robots.txt 文件。

它是如何工作的

Selenium 是作为自动化测试(web 应用程序和网站)的工具而创建的。简单地说,它就像一个自动化的浏览器窗口。它会打开一个浏览器窗口,让你浏览网站,并随时获取信息。

要使用 Selenium,您需要安装一个模拟浏览器窗口的 web 驱动程序。不同的浏览器有不同的网络驱动程序,但是你应该首先使用你熟悉的浏览器!我的大多数项目都使用了 Chrome 浏览器的网络驱动程序,但是你也可以为 Firefox 和 IE 浏览器安装一个。

对于一个在浏览器窗口没有真正打开的情况下运行 Selenium 的选项,检查一下 PhantomJS 的 webdriver 尽管使用起来有点棘手。

如果您对使用 JavaScript 的网站不确定,请在检查页面时寻找包含 JS 代码的标签(右键单击页面,并选择检查)。

在您完成设置后,是时候刮点东西了!自动化浏览器窗口打开后,您将通过 web 驱动程序与浏览器互动。

多给我看看!

从这里开始,如果你已经和美丽的汤一起工作过,那么接下来应该很容易。您将使用相同的逻辑在包含页面的变量中查找 HTML 标记。你有一个名为“webdriver”的浏览器窗口,而不是一个“汤”。

我试着把上面的代码分成易于阅读的代码块。当您调用 webdriver 时,自动浏览器窗口将会打开。铬合金()。

窗口打开后,您可能会认出获取 somewebsite 页面的 get 方法。它在页面上查找“用户名”字段,并在该字段中发送“您的用户名”。

与“密码”字段相同。然后单击登录。很直接,对吧?诀窍是能够找到标签

值得一提的是,尽管 Selenium 并不是为 web 抓取而构建的,但它可以成为一个非常有趣的工具!

和 Scrapy 一起拥有互联网

然后我发现了 Scrapy……我看过关于它的视频和教程,但是不得不使用 shell 终端在当时有点吓人。我结束了使用 BS 和硒很长一段时间,直到我决定探索 Scrapy。

一旦我理解了这个概念并释放了我的第一只蜘蛛……嗯,只能说感觉整个世界的可能性刚刚打开。

有一个微小的机会,它甚至会让你觉得像一个黑客,因为你将使用终端,它会在忙的时候打印出很多东西。那肯定是有意义的,对吧?!

它是如何工作的

很快,它的速度快得不可思议。这不是偶然的,因为 Scrapy 是使用 Twisted Python 框架构建的。这个框架给了它异步能力,这使得 Scrapy 没有必要单独等待每个响应。但是这可能比你现在需要知道的还要多!

它也不需要依赖,所以它是一个非常便携的解决方案,你可以在任何安装了 Python 的地方实现。

请放心,您不需要理解它背后的框架就能够使用它。如果您以前见过命令提示符,并且不怕在终端中键入内容,这会很有帮助!

我先解释一下,不需要任何代码,然后我会分享一个简短的视频来展示它的作用。

爬行的蜘蛛

为了创建你的第一个蜘蛛(蜘蛛是你创建来抓取网页的小机器人),你在命令提示符下告诉 Scrapy 生成一个新的蜘蛛

如果你想知道,我说的 命令提示符 就是你在 Windows 开始菜单上输入“cmd”时得到的那个!

该命令将创建几个。您运行命令的文件夹中的 py 文件。使用您最喜欢的 IDE,编辑蜘蛛并给它一些参数,如:

  • 你希望蜘蛛从哪个域开始抓取
  • 你希望允许蜘蛛抓取哪些域名
  • 你希望蜘蛛从它访问的每一页中得到什么信息

我们过滤它跟随的链接,通过指定类似“只允许蜘蛛跟随包含 newspaper.com/economy/".的 url。这样,蜘蛛将只跟随有“经济”文章的链接!

设置好之后,回到 shell 终端,键入命令来运行 spider。它将从你的初始页面开始,并立即获得该页面上的每个链接。如果我们以报纸网站为例,在任何文章页面都会有不同的部分,甚至外部链接(如广告)。

在它跟随的每个链接中,它将试图获取你之前定义的 HTML 标签。这就像是服用了类固醇的美妙汤药,因为它有跟踪页面内部链接的能力。

您还可以在运行 spider 时键入的同一命令中定义将结果导出到哪里。

多给我看看!

不幸的是,在这一点上我没有任何公开的 Scrapy 项目可以炫耀!但是我可以分享我在网上找到的最容易跟随的视频之一。该频道甚至有一个专门为 Scrapy 播放的播放列表,这个家伙做了一个很棒的解释工作。

这是我所需要的吗?

我已经向您简单介绍了每个工具及其核心特性。无论你决定使用哪种工具,一定要阅读或观看一些教程,这样你就能理解如何选择 HTML 标签。不管你选择什么样的库,这都将是你最大的挑战。

所以如果你对 Python 没有太多的经验,我会从选择一个简单的网站开始,比如维基百科,然后开始美丽的汤

当你对它感到舒适时,可以随意寻找更高级的项目来用 Selenium 解决。我已经留下了一些我自己项目的链接,所以从这里开始吧。

有一天你会醒来并决定你想从一份特定的在线报纸上抓取每一篇文章并进行 NLP 分析。这可能是你需要加载刺儿头的信号!

我希望这篇文章对你开始使用网络抓取有用,或者为你将来的项目提供不同的选择。我真的很想知道你对什么样的话题更感兴趣,所以请花 5 秒钟回答下面的投票!谢谢!

感谢您的阅读!

与往常一样,我欢迎反馈和建设性的批评。

如果想取得联系,可以在这里联系我 或者直接回复下面的文章。

使用 Selenium 和 YOLO 构建计算机视觉数据集的 Web 抓取

原文:https://towardsdatascience.com/web-scraping-using-selenium-and-yolo-to-build-computer-vision-datasets-73a23d1909d2?source=collection_archive---------48-----------------------

此工作流简化了构建数据集的繁重工作

尼古拉斯·皮卡德在 Unsplash 上拍摄的照片

如果我们向几位专家询问计算机视觉项目的关键(特别是如果我们想要一个真正的应用程序),也许最重复的元素(在我看来也是最重要的)就是数据集。当我们问及最艰巨、最费力的任务时,问题就出现了,答案通常也是一样的:数据集。

组成数据集的任务可以概括为三个步骤:

  1. 捕捉图像
  2. 注释图像:为一组类别标记样本。
  3. 验证:检查标签是否正确。

我们要做的第一件事是求助于可以用于我们任务的最先进的数据集,但问题是我们并不总是能找到我们需要的东西。此时此刻,我们面临着一项艰巨而痛苦的任务。本文展示了如何避免这种手工操作。

使用 Selenium [1】(一个开源的基于 web 的自动化工具) Instagram (间接世界上最大的图像数据库之一)和 YOLO [2】(物体检测中最常用的深度学习算法之一),我们可以自动生成数据集(唯一无法避免的是验证步骤)。为了展示一个简单的例子,我们将生成两个类的简单数据集:cat 和 dog。

我们将设计一个带有 Selenium 的机器人,它将自动访问 Instagram 并在其中移动。此外,我们将使用 YOLO,一个卷积神经网络来检测和排序我们需要的狗和猫。

环境设置

我们将要使用的编程语言是 Python 3.6,它允许我们轻松地使用 Selenium 和 YOLO。

我们将需要以下外部依赖:

  • GluonCV :提供计算机视觉中最先进深度学习算法实现的框架。这个工具包为我们提供了大量预先训练好的模型。我们将使用其中的一个[3]。
  • : Python 影像库。
  • 【硒】 :它是一个伞式项目,包含一系列工具和库,支持 web 浏览器的自动化。我们将使用该库提供的 Python 模块。
  • 请求 :是一个优雅简单的 Python HTTP 库。我们将用它来下载图像。

您可以使用以下命令安装这些依赖项:

pip install mxnet gluoncv Pillow selenium beautifulsoup4 requests

另外,你还需要 ChromeDriver 。这提供了从 Selenium 导航到 web 页面的能力。你要把它复制到usr/local/bin,瞧!您现在可以从 Selenium 控制您的 Chrome 浏览器了!

物体检测模块

正如我们已经提到的,我们将使用 YoloV3 作为检测模块(顺便说一下, YoloV4 从一个月前就有了)。通过这种方式,我们将尝试寻找和区分猫和狗。

使用 GluonCV 和 MXNet 的 YoloV3 模块

概括地说,YOLO(你只看一次)基本上是一个单一的 CNN,它提供了多个预测(边界框),每个类别都有一个相关的概率。此外,NMS(非最大抑制)用于将多个检测合并为一个检测。我们面对的是一个实时工作的快速神经网络。

使用 YoloV3 模块检测狗和猫。狗:由乔·凯恩Unsplash 上的基础图像。猫:基础图片由内森·赖利Unsplash 上制作

硒机器人模块

我们将使用 Selenium 对机器人进行编程,使其登录并通过 Instagram,使用检测模块自动下载图像。

正如您在__call__()方法中看到的,我们可以将代码分为 4 个主要步骤:

  1. 打开 Instagram 主页。
  2. 用你的用户名和密码登录 Instagram】。
  3. 放上你的标签来限制搜索,这里是#宠物,因为在这个例子中我们想要狗和猫。
  4. 还有最重要的一步,滚动和下载图片。

在最后一步中,我们滚动并解析 HTML 以获得下载图像并使用 Pillow 对其进行合成所需的 URL。此时,我们检查图像是否包含一只狗、一只猫,或者什么都不包含,然后将它保存到每个类对应的文件夹中,或者丢弃该图像。

最后,您只需要担心验证样本。尽情享受吧!😉

如果您想轻松地启动这个代码,您可以在这个存储库中找到它。您只需按照自述文件中指示的步骤进行操作。

[## bsouto/selenium-bot

使用 Selenium 和 Yolo V3 从 Instagram 构建计算机视觉数据集的 Web 抓取。- bsouto/selenium-bot

github.com](https://github.com/bsouto/selenium-bot)

在下面的 GIF 中,你可以看到数据集是如何自动生成的:机器人用用户名和密码访问 Instagram,输入#PETS 标签,滚动,同时只下载狗(底部文件夹)和猫(顶部文件夹)的图像。

操作程序

强调这是一个简单的例子,当然还有很多关于狗和猫的公开数据集。我们可以将我们想要的复杂性添加到我们的生成器中,这是一个概念验证,可能我们的任务不是那么简单,我们需要的数据也不是那么基本。

感谢阅读!

参考

[1]https://selenium-python.readthedocs.io/

https://pjreddie.com/darknet/yolo/

[3]https://gluon-cv . mxnet . io/build/examples _ detection/demo _ yolo . html

使用 Python 和 BeautifulSoup 进行网页抓取

原文:https://towardsdatascience.com/web-scraping-with-python-beautifulsoup-40d2ce4b6252?source=collection_archive---------9-----------------------

如何从网站中提取数据

图片来自 Pixabay 詹姆斯·奥斯本

网络包含大量的数据。毫无疑问,从中提取你需要的信息的能力是有用的,甚至是必要的。当然,在 Kaggle 这样的地方,仍然有许多数据集可供你下载,但在许多情况下,你不会找到你特定问题所需的确切数据。然而,很有可能你会在网上的某个地方找到你需要的东西,你需要从那里提取。

网络抓取就是这样做的过程,从网页中提取数据。在这篇文章中,我们将看到如何用 python 进行 web 抓取。对于此任务,有几个库可供您使用。这其中,这里我们就用美汤 4 。这个库负责从 HTML 文档中提取数据,而不是下载数据。对于下载网页,我们需要使用另一个库:请求

所以,我们需要两个包:

  • 请求—用于从给定的 URL 下载 HTML 代码
  • 美丽的汤——用于从 HTML 字符串中提取数据

安装库

现在,让我们从安装所需的包开始。打开终端窗口并键入:

python -m pip install requests beautifulsoup4

…或者,如果您使用的是 conda 环境:

conda install requests beautifulsoup4

现在,尝试运行以下命令:

**import** requests
**from** bs4 **import** BeautifulSoup

如果您没有得到任何错误,那么软件包安装成功。

使用请求&漂亮的汤来提取数据

requests包中,我们将使用get()函数从给定的 URL 下载网页:

requests.get(url, params**=None**, ******kwargs)

其中参数为:

  • url —所需网页的 url
  • params —可选字典,查询字符串中要发送的元组或字节的列表
  • **kwargs —请求采用的可选参数

这个函数返回一个类型为requests.Response的对象。在这个对象的属性和方法中,我们最感兴趣的是由目标网页的 HTML 字符串组成的.content属性。

示例:

html_string **=** requests.get("http://www.example.com").content

在我们获得目标网页的 HTML 之后,我们必须使用BeautifulSoup()构造函数来解析它,并获得一个BeautifulSoup对象,我们可以用它来导航文档树并提取我们需要的数据。

soup = BeautifulSoup(markup_string, parser)

其中:

  • 标记 _ 字符串 —我们网页的字符串
  • 解析器 —由要使用的解析器的名称组成的字符串;这里我们将使用 python 的默认解析器:“html.parser”

注意,我们将第一个参数命名为“markup_string”而不是“html_string ”,因为 BeautifulSoup 也可以用于其他标记语言,不仅仅是 html,但是我们需要指定一个适当的解析器;例如,我们可以通过将“xml”作为解析器来解析 XML。

一个BeautifulSoup对象有几个方法和属性,我们可以用它们在解析过的文档中导航并从中提取数据。
最常用的方法是.find_all():

soup.find_all(name, attrs, recursive, string, limit, ******kwargs)
  • 名称 —标记的名称;例如“a”、“div”、“img”
  • attrs —带有标签属性的字典;例如{“class”: “nav”, “href”: “#menuitem”}
  • 递归 —布尔;如果为 false,则只考虑直接子代;如果为 true(默认),则在搜索中检查所有子代
  • 字符串 —用于在元素内容中搜索字符串
  • 限制 —将搜索限制在找到的元素的数量

示例:

soup.find_all("a", attrs**=**{"class": "nav", "data-foo": "value"})

上面的行返回一个列表,其中包含所有具有指定属性的“a”元素。

不能和这个方法的参数或者 python 的关键字混淆的 HTML 属性(比如“class”)可以直接作为函数参数使用,不需要放在attrs字典里面。HTML 类的属性也可以这样使用,但是不要用class=”…”class_=”…”

示例:

soup.find_all("a", class_**=**"nav")

因为这个方法是用的最多的一个,所以它有一个捷径:直接调用BeautifulSoup对象和调用.find_all()方法效果一样。

示例:

soup("a", class_**=**"nav")

.find()方法类似于.find_all(),但它在找到第一个元素后停止搜索;将被返回的元素。它大致相当于.find_all(..., limit=1),但它不是返回一个列表,而是返回一个元素。

BeautifulSoup对象的.contents属性是一个包含所有子元素的列表。如果当前元素不包含嵌套的 HTML 元素,那么.contents[0]将只是其中的文本。因此,在我们使用.find_all().find()方法获得包含我们需要的数据的元素后,我们需要做的就是访问.contents[0]来获得其中的数据。

示例:

soup **=** BeautifulSoup('''
    <div>
        <span class="rating">5</span>
        <span class="views">100</span>
    </div>
''', "html.parser")views **=** soup.find("span", class_**=**"views").contents[0]

如果我们需要的数据不在元素内部,而是作为属性值,那该怎么办?我们可以按如下方式访问元素的属性值:

soup['attr_name']

示例:

soup **=** BeautifulSoup('''
    <div>
        <img src="./img1.png">
    </div>
''', "html.parser")img_source **=** soup.find("img")['src']

Web 抓取示例:获得前 10 个 linux 发行版

现在,让我们用上面的概念来看一个简单的 web 抓取示例。我们将从 DistroWatch 网站上抽取一个列表,列出最受欢迎的 10 个 linux 发行版。distro watch(https://distrowatch.com/)是一个以 linux 发行版和运行在 linux 上的开源软件的新闻为特色的网站。这个网站的右边有一个最流行的 linux 发行版的排名。我们将从这个排名中抽取前 10 名。

首先,我们将下载网页并从中构造一个漂亮的 Soup 对象:

**import** requests
**from** bs4 **import** BeautifulSoup

soup **=** BeautifulSoup(
    requests.get("https://distrowatch.com/").content,
    "html.parser")

然后,我们需要找出如何在 HTML 代码中识别我们想要的数据。为此,我们将使用 chrome 的开发工具。右键点击网页中的某个地方,然后点击“检查”,或者按“Ctrl+Shift+I”来打开 chrome 的开发者工具。它应该是这样的:

然后,如果你点击开发者工具左上角的小箭头,然后点击网页上的某个元素,你应该在开发者工具窗口中看到与该元素相关的 HTML 片段。之后,您可以使用您在 dev tools 窗口中看到的信息来告诉 beautiful soup 在哪里可以找到该元素。

在我们的例子中,我们可以看到排名被构造成一个 HTML 表,每个发行版名称都在一个带有类“phr2”的 td 元素中。然后在 td 元素里面是一个包含我们想要提取的文本的链接(发行版的名称)。这就是我们在接下来的几行代码中要做的事情:

top_ten_distros **=** []
distro_tds **=** soup("td", class_**=**"phr2", limit**=**10)
**for** td **in** distro_tds:
    top_ten_distros.append(td.find("a").contents[0])

这是我们得到的结果:

我希望这些信息对你有用,感谢你的阅读!

这篇文章也贴在我自己的网站这里。随便看看吧!

使用 Python 简化 Web 抓取

原文:https://towardsdatascience.com/web-scraping-with-python-made-easy-f069ffaf7754?source=collection_archive---------15-----------------------

了解如何用 Python 抓取网站

Beautiful Soup 是一个 Python 库,便于从网站上抓取信息。在这篇文章中,我想向你展示一些基础知识,让你自己开始抓取网站。我们将一步一步地构建一个 Python Web Scraper 。这比听起来容易。

照片由马库斯·斯皮斯克·temporausch.com派克斯拍摄

为什么使用 Python Web 抓取?

网络抓取包括通过程序或脚本从网站提取信息。抓取有助于自动提取数据,比我们手动提取信息要快得多。它真的可以节省数小时的手工和繁琐的工作。

例如,如果我们想获得一个包含上传到易贝“无线耳机”类别的所有产品名称的列表,我们可以编写一个 Python 脚本,并使用 Beautiful soup 自动完成这项任务。

如何装美汤?

在终端中运行 pip 命令可以安装 Beautiful Soup。查看官方文档了解更多详情。

pip install beautifulsoup4

在开始编写我们的代码之前,请注意,虽然抓取公共数据并不违法,但我们应该避免每秒向网站发出数百个请求,因为这可能会使网站服务器过载。此外,最好检查你打算删除的网站的条款,以了解它们是否允许删除。

创建我们的 Python 刮刀

好,我们开始吧。我们将抓取 cryptonewsandprices.me 这是一个包含加密新闻库的网站。我们的目标是从站点中提取出版的标题日期

首先,我们应该检查网页的 html 代码,以确定我们希望从站点中提取哪些元素。我们在这篇文章中删除的页面如下所示:

要查看该站点的页面源,右键选择“查看页面源”。然后,我们就可以看到我们将使用美汤解析的站点的 html 源代码 代码。通过查看下面的 html source 的摘录,我们可以看到我们的标题被一个 h5 标签类“card-title”所包围。在 Beautiful Soup 及其强大的解析器的帮助下,我们将使用这些标识符来删除信息。

我们需要做的第一件事是导入我们的库请求美丽组 。因为我们需要向要废弃的页面发送一个请求,所以我们需要使用请求库。然后,一旦我们得到来自站点的响应,我们将它存储在一个名为" mainContent 的变量中,稍后我们将解析它:

import requests
from bs4 import BeautifulSoupmainContent = requests.get("https://cryptonewsandprices.me/") print(mainContent.text)

我们的问题是,我们用 requests.get 得到的请求不是很用户友好,因此,我们需要把它转换成更容易理解的东西。注意,我们的 mainContent 变量包含了站点的整个 html 代码。

从一个元素中抓取信息

现在让我们摘录一下新闻标题。首先,我们需要将我们在main content变量中的字符串转换成一个 soup Beautiful Soup解析器能够理解(并解析)的“Soup”。可以选择不同的解析器来读取数据。在这篇文章中,我使用“ lxml ”,因为它是最通用和最快的解析器之一。

在下面的代码行中, Soup 包含了我们的 get 请求所指向的整个页面的 html 代码。然后,美汤 lxml 解析器让我们从 html 源代码中提取想要的信息。

Beautiful Soup 提供了一些方法来提取 html 标签、或网站中其他元素中的文本。既然我们知道每条新闻的标题都使用了一个H5html 标签和类 card-title ,我们可以使用“find”在页面中定位它们,并将值提取到我们的 title 变量中。此外,我们使用“get_text()”只提取 html 标签 h5 和类“card-title”中的文本,而不提取 html 标记。

soup = BeautifulSoup(mainContent.text,'lxml')
title = soup.find('h5', class_='card-title').get_text()
print(title)

太好了,我们已经在页面上打印了第一篇新闻的标题。现在,让我们提取关于这篇文章何时发表的信息。为此,我们首先需要查看一下站点,了解我们可以使用哪个 html 元素来识别“发布在之前”的信息。

如下图所示,我们可以通过“ small 标签和“ text-info 类来识别元素。同样,我们可以使用方法 find 从我们的站点定位并提取对象。

published = soup.find('small', class_='text-info').get_text().strip()print(published)

太好了,现在我们有了发布的信息和最新文章中的图片。

从多个元素中抓取信息

如果能从所有新闻中获得所有标题和发布的信息,而不是只有一个新闻元素,那就更好了。为此,BS 有一个方法叫做 find_all 。其工作原理类似于 查找 😗*

titleall = soup.find_all('h5', class_='card-title')
print(titleall)##printed answer [<h5 class="card-title">Ex-UFC Fighter &amp; Bitcoin Bull Ben Askren: XRP is a Scam </h5>, <h5 class="card-title">Opporty founder calls SEC's ICO lawsuit 'grossly overstated' and 'untruthful' in an open letter </h5>,...]

美汤查找所有方法返回的是一个包含网站包含的所有新闻标题的列表。列表中的每个元素都是一个标题。然而,我们将 html h5 标签作为结果的一部分。

我们之前用来提取文本的 Get_text 方法不适用于列表。因此,为了获得没有 html 标签的每个标题,我们可以遍历列表,然后将 get_text 应用于列表的每次迭代,以将其附加到名为 title_list 的新列表中:

title_list =[]for item in titleall: 
   individualtitle = item.get_text() 
   title_list.append(individualtitle) print(title_list)

很好,现在我们得到了没有 html 标签的标题,只有文本。

完成我们的 Python Web Scraper

作为最后一步,如果我们能够提取标题并将其写入一个 csv 文件,那将会非常有趣。为此,我们可以使用 csv 库和 writer 方法:

import csv with open('pythonscraper.csv','w') as csvfile: 
     writer = csv.writer(csvfile)
     for item in title_list: 
        writer.writerow([item])

就像这样,我们在一个 csv 文件中获得标题新闻列表。你现在可以自己尝试并提取任何其他信息。

如果有什么不清楚的地方,请不要犹豫,在这里写下评论,或者观看下面的 Youtube 视频,在那里我一行一行地浏览脚本。

原载于 2020 年 1 月 28 日 https://codingandfun.com

一步一步的使用 R 进行网页抓取的指南

原文:https://towardsdatascience.com/web-scraping-with-r-easier-than-python-c06024f6bf52?source=collection_archive---------23-----------------------

让我们用 R 开发一个实时 web 抓取应用程序——比用 Python 简单多了

rawpixel.com创建的技术向量

好的数据集很难找到。这是意料之中的,但没什么好担心的。像网络抓取这样的技术使我们能够随时随地获取数据——如果你知道怎么做的话。今天我们将探索用 R 抓取网络数据有多简单,并通过 R Shiny 漂亮的 GUI 界面来实现。

那么,什么是网页抓取呢?简单来说,就是从各种网站收集数据的技术。在以下情况下可以使用它:

  • 没有可用于所需分析的数据集
  • 没有可用的公共 API

尽管如此,你还是应该经常查看网站关于网络抓取的政策,以及这篇关于网络抓取伦理的文章。在这之后,你应该能够用常识来决定刮擦是否值得。

如果感觉不对,就不要做。

幸运的是,有些网站完全是为了练习抓取网页而制作的。其中之一是books.toscrape.com,顾名思义,它列出了各种流派的书籍:

截图来自http://books.toscrape.com

那么,我们接下来刮那个混蛋,好吗?

行动(或活动、袭击)计划

打开网页,点击任意两个类别(左侧边栏),检查网址。以下是我们的选择:

http://books.toscrape.com/catalogue/category/books/**travel_2**/index.html
http://books.toscrape.com/catalogue/category/books/**mystery_3**/index.html

这些网址有什么共同点?嗯,除了加粗的部分。那就是品类本身。不知道编号是怎么回事,但事实就是如此。每一页都包含一个书单,一本书看起来像这样:

推理类单本书截图

我们的工作是获取一个类别中每本书的信息。这样做需要一点 HTML 知识,但它是一种简单的标记语言,所以我不认为这有什么问题。

我们想刮:

  • 标题— h3 > a >标题房产
  • 等级— 星级>等级属性
  • 价格— 部门产品价格>部门价格颜色>文本
  • 可用性— 部门产品价格>部门库存>文本
  • 图书 URL—div . image _ container>a>href属性
  • 缩略图 URL—div . image _ container>img>src属性

你现在什么都知道了,所以接下来让我们从刮痧开始。

刮书

在 R 中使用rvest包来执行 web 抓取任务。由于管道操作员的使用和一般行为,它与著名的数据分析包dplyr非常相似。我们知道如何到达某些元素,但是如何在 R 中实现这个逻辑呢?

下面是一个如何在旅游类别中搜集书名的例子:

library(rvest)

url <- 'http://books.toscrape.com/catalogue/category/books/travel_2/index.html'
titles <- read_html(url) %>% 
  html_nodes('h3') %>%
  html_nodes('a') %>% 
  html_text()

作者图片

那不是很容易吗?类似地,我们可以刮去其他所有东西。剧本是这样的:

library(rvest)
library(stringr)

titles <- read_html(url) %>% 
  html_nodes('h3') %>%
  html_nodes('a') %>% 
  html_text()

urls <- read_html(url) %>%
  html_nodes('.image_container') %>% 
  html_nodes('a') %>% 
  html_attr('href') %>% 
  str_replace_all('../../../', '/')

imgs <- read_html(url) %>% 
  html_nodes('.image_container') %>%
  html_nodes('img') %>%
  html_attr('src') %>%
  str_replace_all('../../../../', '/')

ratings <- read_html(url) %>% 
  html_nodes('p.star-rating') %>% 
  html_attr('class') %>% 
  str_replace_all('star-rating ', '')

prices <- read_html(url) %>% 
  html_nodes('.product_price') %>% 
  html_nodes('.price_color') %>% 
  html_text()

availability <- read_html(url) %>% 
  html_nodes('.product_price') %>% 
  html_nodes('.instock') %>% 
  html_text() %>% 
  str_trim()

厉害!最后一步,让我们将所有这些粘合在一个单独的数据帧中:

scraped <- data.frame(
  Title = titles, 
  URL = urls, 
  SourceImage = imgs, 
  Rating = ratings, 
  Price = prices, 
  Availability = availability
)

作者图片

你可以在这里结束这篇文章,今天就到此为止,但是我们还可以在此基础上构建一些东西——一个简单易用的 web 应用程序。让我们接下来做那件事。

用于抓取的 Web 应用程序

r 有一个非常棒的 web/dashboard 开发库— Shiny。它比 Python 中任何类似的东西都容易使用,所以我们将坚持使用它。首先,创建一个新的 R 文件,并将以下代码粘贴到其中:

library(shiny)
library(rvest)
library(stringr)
library(glue)

ui <- fluidPage()

server <- function(input, output) {}

shinyApp(ui=ui, server=server)

这是每个闪亮的应用程序都需要的样板。接下来,让我们来设计 UI 的样式。我们需要:

  • 标题——只是在所有内容之上的一个大而粗的文本(可选)
  • 侧栏—包含一个下拉菜单,用于选择图书流派
  • 中央区域—一旦数据被擦除,显示表格输出

代码如下:

ui <- fluidPage(
  column(12, tags$h2('Real-time web scraper with R')),
  sidebarPanel(
    width=3,
    selectInput(
      inputId='genreSelect',
      label='Genre',
      choices=c('Business', 'Classics', 'Fiction', 'Horror', 'Music'),
      selected='Business',
    )
  ),
  mainPanel(
    width=9,
    tableOutput('table')
  )
)

接下来,我们需要配置服务器功能。它必须将我们精心格式化的输入重新映射到一个 URL 部分(例如,“Business”到“business_35”),并抓取所选流派的数据。我们已经知道如何这样做。下面是服务器函数的代码:

server <- function(input, output) {
  output$table <- renderTable({
    mappings <- c('Business' = 'business_35', 'Classics' = 'classics_6', 'Fiction' = 'fiction_10',
                  'Horror' = 'horror_31', 'Music' = 'music_14') 

    url <- glue('http://books.toscrape.com/catalogue/category/books/', mappings[input$genreSelect], '/index.html')

    titles <- read_html(url) %>% 
      html_nodes('h3') %>%
      html_nodes('a') %>% 
      html_text()

    urls <- read_html(url) %>%
      html_nodes('.image_container') %>% 
      html_nodes('a') %>% 
      html_attr('href') %>% 
      str_replace_all('../../../', '/')

    imgs <- read_html(url) %>% 
      html_nodes('.image_container') %>%
      html_nodes('img') %>%
      html_attr('src') %>%
      str_replace_all('../../../../', '/')

    ratings <- read_html(url) %>% 
      html_nodes('p.star-rating') %>% 
      html_attr('class') %>% 
      str_replace_all('star-rating ', '')

    prices <- read_html(url) %>% 
      html_nodes('.product_price') %>% 
      html_nodes('.price_color') %>% 
      html_text()

    availability <- read_html(url) %>% 
      html_nodes('.product_price') %>% 
      html_nodes('.instock') %>% 
      html_text() %>% 
      str_trim()

    data.frame(
      Title = titles, 
      URL = urls, 
      SourceImage = imgs, 
      Rating = ratings, 
      Price = prices, 
      Availability = availability
    )
  })
}

就这样,我们现在可以运行应用程序并检查行为!

作者 GIF

正是我们想要的——简单,但仍然完全可以理解。让我们在下一部分总结一下。

离别赠言

在短短几分钟内,我们从零到一个工作的网页抓取应用程序。扩展它的选项是无穷无尽的——添加更多的类别、处理视觉效果、包含更多的数据、更好地格式化数据、添加过滤器等等。

我希望你已经设法跟上,你能够看到网络抓取的力量。这是一个虚拟的网站和一个虚拟的例子,但是方法保持不变,与数据源无关。

感谢阅读。

加入我的私人邮件列表,获取更多有用的见解。

喜欢这篇文章吗?成为 中等会员 继续无限制学习。如果你使用下面的链接,我会收到你的一部分会员费,不需要你额外付费。

[## 通过我的推荐链接加入 Medium-Dario rade ci

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

medium.com](https://medium.com/@radecicdario/membership)

原载于 2020 年 10 月 19 日https://betterdatascience.com

用 Scrapy 刮网

原文:https://towardsdatascience.com/web-scraping-with-scrapy-8071fd627051?source=collection_archive---------34-----------------------

构建您的第一个网络爬虫

尼古拉斯·皮卡德在 Unsplash 上拍摄的照片

S crapy 是一个流行的用于网页抓取的 Python 框架。出于本教程的目的,我想使用一个我熟悉的网站。我以前做过一个项目,用 Billboard Hot 100 排行榜上的条目作为基本事实,对热门唱片进行分类。我当时使用了一个 python 包装器,它在获取我的数据集时非常有效。然而,我想展示使用 Scrapy 可以很容易地做到这一点。

免责声明:这仅用于培训和教育目的。请熟悉道德规范,因为它们与从网上抓取内容有关。

任何成功的网络抓取项目的第一步是审查要抓取的网站。试着理解发生在引擎盖下的。在这一步,你的浏览器的网络开发工具将是必不可少的。确定要提取以包含在数据集中的信息。

我之前在一个项目中使用过 Billboard Hot 100 数据。为了给我的热门歌曲分类器建立真实点击率,我使用 billboard.py 提取每周图表数据。这个包是一个 python 包装器,它使用Beautiful Soup解析来自 Billboard 站点的 html 数据。因为我对这个数据集很熟悉,所以我认为演示如何使用 Scrapy 来构建您的第一个网络爬虫是一个不错的选择。

导航到https://billboard.com/charts/hot-100/。通过右键单击并选择检查或按下option-command-I打开浏览器的 web 开发工具。我在这里禁用 JavaScript,方法是按下shift-command-P,输入 javascript ,选择 禁用 JavaScript 选项。记得点击刷新按钮或者按下 command-R 来刷新页面。这一步对于决定创建网络爬虫是至关重要的,因为这可以让我看到 Scrapy 看到的页面。

网络开发工具的使用。

我决定从网站上收集以下数据:

  • 图表日期
  • 歌名
  • 艺人
  • 本周排名
  • 上周排名
  • 峰值位置
  • **图表上的周数

我发现从 1958 年 8 月 4 日到 1961 年 12 月 25 日,图表每周出现和每周一编目。图表是在周六之后公布的。以前图表的 url 遵循 base_url/date_string 的格式。例如,从 1999 年 12 月 25 日这一周的图表将在 https://billboard.com/charts/hot-100/1999–12–25.找到,我们稍后将需要它为我们的网络爬虫创建分页。****

如果你还没有这样做,一定要安装 scrapy。

***$ pip install scrapy***

仍然在命令行中,选择一个您想要工作的目录,创建一个新项目,并创建一个基本的蜘蛛。

***$ cd projects
$ scrapy startproject billboard
$ cd billboard
$ scrapy genspider hot100 billboard.com/charts/hot-100/***

Scrapy 为你的网络爬虫创建了一个具有所有适当层次的新项目。

项目文件夹结构。

scrapy shell 命令和 web dev tools 之间,我可以发现如何最好地从 html 中提取我需要的数据。有 100 首歌 出现在每个周图中。它们可以在有序列表元素中找到。通过将这 100 个元素放入一个变量中,我可以遍历每个元素,从每个元素中提取相关信息。我选择使用XPath提取我的数据。如果你愿意,你可以使用 css 选择器 。这个简短的教程假设您对这两者都有一定的了解,所以我不会深入讨论。

**$ scrapy shell billboard.com/charts/hot-100/>>> hit = response.xpath("//li[starts-with(@class, 'chart-list__element')]")>>> len(hit)
100>>> title = hit.xpath(".//span[starts-with(@class, 'chart-element__information__song')]/text()").get()>>> title
'The Scotts'**

既然我已经对我想要抓取的每个项目有了一个好的想法,我将在我选择的文本编辑器中打开我的蜘蛛。我在这个例子中使用了 Visual Studio 代码 ,但是任何代码都可以。我打开项目文件夹,然后打开我创建的名为 hot100.py 的蜘蛛。

我将allowed _ domains从“www.billboard.com/charts”稍微修改为“billboard.com”。我还在start _ requests函数中包含了开始 url,这样我就可以删除 start_urls 变量,因为它不再是必需的。还要注意,我已经包括了 用户代理 而不是允许 Scrapy 使用默认的,这有时会妨碍你的蜘蛛。

蜘蛛的初始设置。

接下来,我想指导蜘蛛如何抓取网站获取信息。我创建了一个变量, hits,,它包含了页面上所有的 100 次点击。然后我创建了一个循环来查找每次命中的变量。

最后,我指示蜘蛛如何前进到下一页。我根据图表的日期创建了一个 date 对象,以便轻松计算前一个图表的日期。该日期随后被转换成格式为 YYYY-mm-dd 的字符串对象。如果您还记得前面的内容,这就是我们需要添加到基本 url 中以获取前一周图表 url 的格式。一个 回调 用于通知蜘蛛回到 解析方法

解析方法。

按下 command-J ,在 VS 代码 中打开一个终端窗口。确保您位于预期的目录中。如果没有,请确保相应地更改目录。然后让你的蜘蛛爬出网站!我选择将我的记录保存在一个 中。csv 文件您可以将您的文件存储为任何您想要的结构化格式,例如 。json。xml** 等。总共我蜘蛛爬了大概 4 个小时 30 多万条记录 !**

**$ pwd
$ cd /projects/billboard
$ scrapy crawl -o hot100.csv**

我遇到的挑战之一是超时错误。在 Aminah Nuraini 关于 栈溢出解决方案的帮助下,我对我的 settings.pymiddleware . py文件进行了修改,使我的爬虫运行顺畅。如果她的解决方案适合你的个人情况,请随时查看。我不会深入细节,因为它们超出了这个简短教程的范围。**

你有它!你完全有能力创建你的第一个网络爬虫来完成网络抓取的任务。完整的 源代码 可以在 这里找到 。如果你觉得这篇文章很有帮助,请联系我这里和/或 的链接。

用 Scrapy 抓取网页:实践理解

原文:https://towardsdatascience.com/web-scraping-with-scrapy-practical-understanding-2fbdae337a3b?source=collection_archive---------6-----------------------

网刮系列

与 Scrapy 一起动手

伊利亚·巴甫洛夫Unsplash 上拍摄

第 1 部分 中讨论了使用 Scrapy 的所有理论方面,现在是时候给出一些实际例子了。我将把这些理论方面放到越来越复杂的例子中。有 3 个例子,

  • 一个通过从天气站点提取城市天气来演示单个请求和响应的例子
  • 一个通过从虚拟在线书店提取图书详细信息来演示多个请求和响应的示例
  • 一个演示图像抓取的例子

你可以从我的 GitHub 页面下载这些例子。这是关于使用 Scrapy 和 Selenium 进行网络抓取的 4 部分教程系列的第二部分。其他部分可在以下网址找到

第 1 部分:用刮刀刮网:理论理解

第 3 部分:用硒刮网

第 4 部分:用硒刮网&刮屑

重要提示:
在你尝试抓取任何网站之前,请先通读其 robots.txt 文件。可以像www.google.com/robots.txt一样访问。在那里,你会看到一个允许和不允许抓取谷歌网站的页面列表。您只能访问属于User-agent: *的页面和Allow:之后的页面。

示例 1 —通过从天气站点提取城市天气来处理单个请求和响应

我们这个例子的目标是从weather.com提取今天的“Chennai”城市天气预报。提取的数据必须包含温度、空气质量和条件/描述。你可以自由选择你的城市。只需在蜘蛛代码中提供您所在城市的 URL。如前所述,该网站允许抓取数据,前提是抓取延迟不少于 10 秒,也就是说,在从 weather.com 请求另一个 URL 之前,你必须等待至少 10 秒。这个可以在网站的 robots.txt 中找到。

User-agent: *
# Crawl-delay: 10

我用scrapy startproject命令创建了一个新的 Scrapy 项目,并用

scrapy genspider -t basic weather_spider weather.com

开始编码的第一个任务是遵守网站的政策。为了遵守 weather.com 的爬行延迟政策,我们需要在 scrapy 项目的settings.py文件中添加下面一行。

DOWNLOAD_DELAY = 10

这一行让我们项目中的蜘蛛在发出新的 URL 请求之前等待 10 秒钟。我们现在可以开始编码我们的蜘蛛。

如前所示,生成了模板代码。我对代码做了一些修改。

import scrapy
import re
from ..items import WeatherItemclass WeatherSpiderSpider(scrapy.Spider):
    name = "weather_spider"
    allowed_domains = ["weather.com"]def start_requests(self):
        # Weather.com URL for Chennai's weather
        urls = [
            "https://weather.com/en-IN/weather/today/l/bf01d09009561812f3f95abece23d16e123d8c08fd0b8ec7ffc9215c0154913c"
        ]
        for url in urls:
            yield scrapy.Request(url=url, callback=self.parse_url)def parse_url(self, response):# Extracting city, temperature, air quality and condition from the response using XPath
        city = response.xpath('//h1[contains(@class,"location")]/text()').get()
        temp = response.xpath('//span[@data-testid="TemperatureValue"]/text()').get()
        air_quality = response.xpath('//span[@data-testid="AirQualityCategory"]/text()').get()
        cond = response.xpath('//div[@data-testid="wxPhrase"]/text()').get()temp = re.match(r"(\d+)", temp).group(1) + " C"  # Removing the degree symbol and adding C
        city = re.match(r"^(.*)(?: Weather)", city).group(1)  # Removing 'Weather' from location# Yielding the extracted data as Item object. You may also extract as Dictionary
        item = WeatherItem()
        item["city"] = city
        item["temp"] = temp
        item["air_quality"] = air_quality
        item["cond"] = cond
        yield item

我认为这个例子的代码是不言自明的。然而,我将解释流程。希望你能从 最后一部分 记住 Scrapy 的整体流程图。我希望能够控制请求,所以我使用start_requests()而不是start_urls。在start_requests()中,指定了钦奈天气页面的 URL。如果你想把它改成你喜欢的城市或者增加更多的城市,请随意。对于 URL 列表中的每个 URL,生成一个请求并产生它。所有这些请求都将到达调度程序,调度程序将在引擎请求时分派这些请求。在对应于该请求的网页被下载器下载之后,响应被发送回引擎,引擎将其定向到相应的蜘蛛。在这种情况下,WeatherSpider 接收响应并调用回调函数parse_url()。在这个函数中,我使用 XPath 从响应中提取所需的数据。

你可能理解到这一部分,代码的下一部分对你来说是新的,因为它还没有被解释。我使用了刺儿头 物品 。这些是定义键值对的 Python 对象。您可以参考此链接了解更多关于物品的信息。如果您不希望使用条目,您可以创建一个字典并放弃它。
可能会出现一个问题,在哪里定义这些所谓的项目。请允许我提醒你一下。在创建一个新项目时,我们看到 Scrapy 正在创建一些文件。记得吗?

weather/
├── scrapy.cfg
└── weather
    ├── __init__.py
    ├── items.py
    ├── middlewares.py
    ├── pipelines.py
    ├── __pycache__
    ├── settings.py
    └── spiders
        ├── WeatherSpider.py
        ├── __init__.py
        └── __pycache__

如果您耐心地沿着这棵树看,您可能会注意到一个名为items.py的文件。在这个文件中,你需要定义项目对象。

# -*- coding: utf-8 -*-# Define here the models for your scraped items
#
# See documentation in:
# [https://docs.scrapy.org/en/latest/topics/items.html](https://docs.scrapy.org/en/latest/topics/items.html)import scrapyclass WeatherItem(scrapy.Item):
    city = scrapy.Field()
    temp = scrapy.Field()
    air_quality = scrapy.Field()
    cond = scrapy.Field()

Scrapy 已经创建了这个类,你需要做的就是定义键值对。在这个例子中,因为我们需要城市名称、温度、空气质量和条件,所以我创建了 4 项。您可以根据项目需要创建任意数量的项目。

当您使用下面的命令运行项目时,将会创建一个包含抓取项目的 JSON 文件。

scrapy crawl weather_spider -o output.json

里面的东西看起来会像,

output.json
------------[
{"city": "Chennai, Tamil Nadu", "temp": "31 C", "air_quality": "Good", "cond": "Cloudy"}
]

万岁!!。你已经成功地执行了一个简单的 Scrapy 项目,处理一个请求和响应。

示例 2 —通过从虚拟在线书店提取图书详细信息来处理多个请求和响应

本例中我们的目标是从网站books.toscrape.com中搜集所有书籍(确切地说是 1000 本)的详细信息。不要担心 robots.txt。这个网站是专门为练习网络抓取而设计和托管的。所以,你是清白的。这个网站是这样设计的,它有 50 页,每页列出 20 本书。您无法从列表页面提取图书详细信息。你必须导航到单本书的网页,以提取所需的细节。这是一个需要抓取多个网页的场景,所以我将使用爬行蜘蛛。像前面的例子一样,我已经创建了一个新项目和一个爬行蜘蛛,使用了scrapy startproject

scrapy genspider -t crawl crawl_spider books.toscrape.com

对于这个例子,我将提取书名,它的价格,评级和可用性。这个items.py文件应该是这样的。

class BookstoscrapeItem(scrapy.Item):
    title = scrapy.Field()
    price = scrapy.Field()
    rating = scrapy.Field()
    availability = scrapy.Field()

现在项目所需的一切都准备好了,让我们看看crawl_spider.py

class CrawlSpiderSpider(CrawlSpider):
    name = "crawl_spider"
    allowed_domains = ["books.toscrape.com"]
    # start_urls = ["http://books.toscrape.com/"] # when trying to use this, comment start_requests()rules = (Rule(LinkExtractor(allow=r"catalogue/"), callback="parse_books", follow=True),)def start_requests(self):
        url = "http://books.toscrape.com/"
        yield scrapy.Request(url)def parse_books(self, response):
        """ Filtering out pages other than books' pages to avoid getting "NotFound" error.
        Because, other pages would not have any 'div' tag with attribute 'class="col-sm-6 product_main"'
        """
        if response.xpath('//div[@class="col-sm-6 product_main"]').get() is not None:
            title = response.xpath('//div[@class="col-sm-6 product_main"]/h1/text()').get()
            price = response.xpath('//div[@class="col-sm-6 product_main"]/p[@class="price_color"]/text()').get()
            stock = (
                response.xpath('//div[@class="col-sm-6 product_main"]/p[@class="instock availability"]/text()')
                .getall()[-1]
                .strip()
            )
            rating = response.xpath('//div[@class="col-sm-6 product_main"]/p[3]/@class').get()# Yielding the extracted data as Item object.
            item = BookstoscrapeItem()
            item["title"] = title
            item["price"] = price
            item["rating"] = rating
            item["availability"] = stock
            yield item

你注意到start_requests()的变化了吗?为什么我生成一个没有回调的请求?是我在最后一部分说每个请求都必须有相应的回调吗?如果你有这些问题,我赞赏你对细节和批判性推理的关注。向你致敬!!拐弯抹角说够了,让我继续回答你的问题。我没有在初始请求中包含回调,因为rules中指定了回调和 URL,后续请求将使用该 URL。

流程将从我用http://books.toscrape.com 显式生成一个请求开始。紧随其后的是 LinkExtractor 用模式http://books.toscrape.com/catalogue/.提取链接,爬行蜘蛛开始用 LinkExtractor 用parse_books作为回调函数创建的所有 URL 生成请求。这些请求被发送到调度程序,当引擎发出请求时,调度程序依次调度请求。像以前一样,通常的流程继续进行,直到调度程序中不再有请求。当您使用 JSON 输出运行这个蜘蛛时,您将获得 1000 本书的详细信息。

scrapy crawl crawl_spider -o crawl_spider_output.json

示例输出如下所示。

[
  {
    "title": "A Light in the Attic",
    "price": "\u00a351.77",
    "rating": "star-rating Three",
    "availability": "In stock (22 available)"
  },
  {
    "title": "Libertarianism for Beginners",
    "price": "\u00a351.33",
    "rating": "star-rating Two",
    "availability": "In stock (19 available)"
  },
  ...
]#Note: /u00a3 is the unicode representation of £

如前所述,这不是提取所有 1000 本书的细节的唯一方法。一个基本的蜘蛛也可以用来提取精确的细节。我已经用一个基本的蜘蛛程序包含了代码。使用以下命令创建一个基本的蜘蛛。

scrapy genspider -t basic book_spider books.toscrape.com

基本的蜘蛛包含以下代码。

class BookSpiderSpider(scrapy.Spider):
    name = "book_spider"
    allowed_domains = ["books.toscrape.com"]def start_requests(self):
        urls = ["http://books.toscrape.com/"]
        for url in urls:
            yield scrapy.Request(url=url, callback=self.parse_pages)def parse_pages(self, response):
        """
        The purpose of this method is to look for books listing and the link for next page.
        - When it sees books listing, it generates requests with individual book's URL with parse_books() as its callback function.
        - When it sees a next page URL, it generates a request for the next page by calling itself as the callback function.
        """books = response.xpath("//h3")""" Using response.urljoin() to get individual book page """
        """
        for book in books:
            book_url = response.urljoin(book.xpath(".//a/@href").get())
            yield scrapy.Request(url=book_url, callback=self.parse_books)
        """""" Using response.follow() to get individual book page """
        for book in books:
            yield response.follow(url=book.xpath(".//a/@href").get(), callback=self.parse_books)""" Using response. urljoin() to get next page """
        """
        next_page_url = response.xpath('//li[@class="next"]/a/@href').get()
        if next_page_url is not None:
            next_page = response.urljoin(next_page_url)
            yield scrapy.Request(url=next_page, callback=self.parse_pages)
        """""" Using response.follow() to get next page """
        next_page_url = response.xpath('//li[@class="next"]/a/@href').get()
        if next_page_url is not None:
            yield response.follow(url=next_page_url, callback=self.parse_pages)def parse_books(self, response):
        """
        Method to extract book details and yield it as Item object
        """title = response.xpath('//div[@class="col-sm-6 product_main"]/h1/text()').get()
        price = response.xpath('//div[@class="col-sm-6 product_main"]/p[@class="price_color"]/text()').get()
        stock = (
            response.xpath('//div[@class="col-sm-6 product_main"]/p[@class="instock availability"]/text()')
            .getall()[-1]
            .strip()
        )
        rating = response.xpath('//div[@class="col-sm-6 product_main"]/p[3]/@class').get()item = BookstoscrapeItem()
        item["title"] = title
        item["price"] = price
        item["rating"] = rating
        item["availability"] = stock
        yield item

你有没有注意到两只蜘蛛都用了同样的parse_books()方法?提取图书详细信息的方法是相同的。唯一不同的是,我在基本蜘蛛中用一个专用的长函数parse_pages()替换了爬行蜘蛛中的rules。希望这能让你看到爬行蜘蛛和基础蜘蛛的区别。

示例 3 —图像刮擦

在开始这个例子之前,让我们看一下 Scrapy 如何抓取和处理文件和图像的简要概述。要从网页中抓取文件或图像,您需要使用内置管道,具体来说就是FilesPipelineImagesPipeline,分别用于各自的目的。我将解释使用FilesPipeline时的典型工作流程。

  1. 您必须使用蜘蛛抓取一个项目,并将所需文件的 URL 放入一个file_urls字段。
  2. 然后,您返回该项目,该项目将进入项目管道。
  3. 当项目到达FilesPipeline时,file_urls中的 URL 被发送到调度器,由下载器下载。唯一的区别是这些file_urls被赋予了更高的优先级,并在处理任何其他请求之前被下载。
  4. 当文件被下载后,另一个字段files将被结果填充。它将包括实际的下载网址,一个相对的路径,在那里存储,其校验和和状态。

FilesPipeline可用于抓取不同类型的文件(图片、pdf、文本等。).ImagesPipeline专门用于图像的抓取和处理。除了FilesPipeline的功能外,它还具有以下功能:

  • 将所有下载的图像转换为 JPG 格式和 RGB 模式
  • 生成缩略图
  • 检查图像宽度/高度,确保它们满足最小限制

此外,文件名也不同。使用ImagesPipeline时,请用image_urlsimages代替file_urlsfiles。如果您希望了解更多关于文件和图像处理的信息,您可以随时点击此链接

我们这个例子的目标是从网站books.toscrape.com上抓取所有书籍的封面图片。为了实现我们的目标,我将重新利用前面例子中的爬行蜘蛛。在开始编写代码之前,有一个重要的步骤需要完成。您需要设置ImagesPipeline。为此,将以下两行添加到项目文件夹中的settings.py文件中。

ITEM_PIPELINES = {"scrapy.pipelines.images.ImagesPipeline": 1}
IMAGES_STORE = "path/to/store/images"

现在您已经准备好编码了。因为我重用了爬行蜘蛛,所以爬行蜘蛛的代码不会有太大的不同。唯一的区别是,您需要创建包含imagesimage_urls的 Item 对象,并从 spider 中产生它。

# -*- coding: utf-8 -*-
import scrapy
from scrapy.linkextractors import LinkExtractor
from scrapy.spiders import CrawlSpider, Rule
from ..items import ImagescraperItem
import reclass ImageCrawlSpiderSpider(CrawlSpider):
    name = "image_crawl_spider"
    allowed_domains = ["books.toscrape.com"]
    # start_urls = ["http://books.toscrape.com/"]def start_requests(self):
        url = "http://books.toscrape.com/"
        yield scrapy.Request(url=url)rules = (Rule(LinkExtractor(allow=r"catalogue/"), callback="parse_image", follow=True),)def parse_image(self, response):
        if response.xpath('//div[@class="item active"]/img').get() is not None:
            img = response.xpath('//div[@class="item active"]/img/@src').get()"""
            Computing the Absolute path of the image file.
            "image_urls" require absolute path, not relative path
            """
            m = re.match(r"^(?:../../)(.*)$", img).group(1)
            url = "http://books.toscrape.com/"
            img_url = "".join([url, m])image = ImagescraperItem()
            image["image_urls"] = [img_url]  # "image_urls" must be a listyield image

items.py文件看起来像这样。

import scrapyclass ImagescraperItem(scrapy.Item):
    images = scrapy.Field()
    image_urls = scrapy.Field()

当您使用输出文件运行蜘蛛程序时,蜘蛛程序将抓取http://books.toscrape.com 的所有网页,抓取书籍封面的 URL 并将其作为image_urls输出,然后将其发送给调度程序,工作流将继续进行,如本例开头所述。

scrapy crawl image_crawl_spider -o output.json

下载的图像将被存储在由IMAGES_STORE指定的位置,并且output.json将看起来像这样。

[
  {
    "image_urls": [
      "http://books.toscrape.com/media/cache/ee/cf/eecfe998905e455df12064dba399c075.jpg"
    ],
    "images": [
      {
        "url": "http://books.toscrape.com/media/cache/ee/cf/eecfe998905e455df12064dba399c075.jpg",
        "path": "full/59d0249d6ae2eeb367e72b04740583bc70f81558.jpg",
        "checksum": "693caff3d97645e73bd28da8e5974946",
        "status": "downloaded"
      }
    ]
  },
  {
    "image_urls": [
      "http://books.toscrape.com/media/cache/08/e9/08e94f3731d7d6b760dfbfbc02ca5c62.jpg"
    ],
    "images": [
      {
        "url": "http://books.toscrape.com/media/cache/08/e9/08e94f3731d7d6b760dfbfbc02ca5c62.jpg",
        "path": "full/1c1a130c161d186db9973e70558b6ec221ce7c4e.jpg",
        "checksum": "e3953238c2ff7ac507a4bed4485c8622",
        "status": "downloaded"
      }
    ]
  },
  ...
]

如果你想抓取其他不同格式的文件,你可以使用FilesPipeline来代替。我将把这个留给你的好奇心。你可以从这个链接下载这 3 个例子。

避免被禁止

热衷于网络抓取的初学者可能会走极端,以更快的速度抓取网站,这可能会导致他们的 IP 被网站禁止/列入黑名单。一些网站实施了特定的措施来防止机器人爬取它们,这些措施的复杂程度各不相同。

以下是在处理这类网站时需要记住的一些技巧,摘自 Scrapy Common Practices :

  • 从浏览器中众所周知的用户代理中轮换你的用户代理(谷歌一下可以得到他们的列表)。
  • 禁用 cookie(参见 COOKIES_ENABLED ),因为一些网站可能会使用 cookie 来发现机器人行为。
  • 使用下载延迟(2 或更高)。参见 DOWNLOAD_DELAY 设置。
  • 如果可能的话,使用谷歌缓存获取页面,而不是直接访问网站
  • 使用轮换 IP 池。比如免费的 Tor 项目或者像 ProxyMesh 这样的付费服务。一个开源的选择是 scrapoxy,一个超级代理,你可以附加你自己的代理。
  • 使用高度分布式的下载器,在内部绕过禁令,这样你就可以专注于解析干净的页面。这种下载程序的一个例子是 Crawlera

结束语

因为我的目标是让你在读完这篇教程后自信地与 Scrapy 一起工作,所以我克制自己不去深入 Scrapy 的各种错综复杂的方面。但是,我希望我已经向您介绍了与 Scrapy 一起工作的概念和实践,明确区分了基本蜘蛛和爬行蜘蛛。如果你有兴趣游到这个池子的更深的一端,请随意接受通过点击这里可以到达的零碎的官方文件的指导。

在本网刮系列的 下一部分 中,我们将着眼于硒。

在那之前,祝你好运。保持安全和快乐的学习。!

Scrapy 网络抓取:理论理解

原文:https://towardsdatascience.com/web-scraping-with-scrapy-theoretical-understanding-f8639a25d9cd?source=collection_archive---------4-----------------------

网刮系列

Scrapy 入门

照片由 timJUnsplash 上拍摄

在这个知识时代,数据就是一切。它或隐或显地驱动着我们的日常活动。在一个典型的数据科学项目中,数据收集和数据清理约占总工作的 80%。本教程和后续教程将集中在使用 Scrapy 通过网络搜集数据。Scrapy 是一个用于抓取网站和提取结构化数据的应用程序框架,可用于广泛的有用应用程序,如数据挖掘、信息处理或历史档案。

Scrapy 有许多优点,其中一些是:

  • 比其他网页抓取工具快 20 倍
  • 最适合开发复杂的网络爬虫和抓取工具
  • 消耗更少的 RAM 并使用最少的 CPU 资源

尽管有其优势,Scrapy 有一个陡峭的学习曲线和不适合初学者的名声。但是,一旦掌握了,它将成为网络抓取的首选工具。这篇教程是我的一点小小的尝试,让它对初学者更友好。我的目标是让你理解 Scrapy 的工作方式,并让你有信心使用 Python 作为编程语言来使用 Scrapy。要自信地使用 Scrapy,首先必须了解它是如何工作的。

这是关于使用 Scrapy 和 Selenium 进行网络抓取的 4 部分教程系列的第一部分。其他部分可在以下网址找到

第二部分:用 Scrapy 进行网页抓取:实用理解

第 3 部分:用硒刮网

第 4 部分:硒刮网&刮网

数据流概述

杂乱的数据流(来源:https://docs.scrapy.org/en/latest/topics/architecture.html

上图清晰简明地概述了 Scrapy 的工作。让我尽可能清晰简单地解释这些步骤。

  1. Scrapy 的主要工具蜘蛛向 Scrapy 引擎发送请求。该引擎负责控制框架所有组件之间的数据流,并在特定操作发生时触发事件。这些初始请求启动了抓取过程。
  2. 引擎将请求发送给调度器,调度器负责收集和调度蜘蛛发出的请求。您可能会问,“为什么需要调度程序?刮难道不是一个直截了当的过程吗?”。这些问题将在下一节中回答。让我们继续工作流程。
  3. 调度器将请求分派给引擎进行进一步处理。
  4. 这些请求通过下载器中间件发送到下载器(在图中由引擎和下载器之间的深蓝色条表示)。关于下载器中间件的更多细节,请参考 Scrapy 文档。
  5. Downloader 然后下载请求的网页,生成响应,并将其发送回引擎。
  6. 引擎通过蜘蛛中间件将响应从下载器发送到生成请求的相应蜘蛛(在图中由引擎和蜘蛛之间的深蓝色条表示)。你可以在 Scrapy 文档中了解更多关于蜘蛛中间件的信息。
  7. Spider 通过提取所需的项来处理收到的响应,如果需要,从该响应生成进一步的请求,并将请求发送到引擎。
  8. 引擎将提取的项目发送到项目管道,以供进一步处理或存储。请点击关于项目管道的链接了解更多信息。引擎还将生成的请求发送给调度程序,并要求将下一个请求发送给下载器。
  9. 重复上述步骤,直到调度器不再有请求可用。

为什么需要调度程序?

Scrapy 遵循异步处理,即请求进程不等待响应,而是继续执行进一步的任务。一旦响应到达,请求进程就开始操作响应。Scrapy 中的蜘蛛也以同样的方式工作。它们向引擎发出请求,这些请求又被发送到调度程序。可以有任意数量的蜘蛛,每个蜘蛛发送 n 个请求(当然有一个条件。您的硬件的处理能力是极限)。为了处理这些请求,调度程序使用了队列。它不断向队列中添加新请求,并在引擎请求时从队列中调度请求。既然您已经知道需要一个调度器,那么让我来详细说明 Scrapy 是如何处理请求和响应的。

处理单个请求和响应

在 Scrapy 中,提出请求是一个简单的过程。要生成请求,您需要想要从中提取有用数据的网页的 URL。你还需要一个回调函数。当有对请求的响应时,回调函数被调用。这些回调函数使 Scrapy 异步工作。因此,要发出请求,您需要:网页的 URL 和处理响应的回调函数。为了让您更好地理解,我将使用几行代码。典型的 Scrapy 请求如下所示。

scrapy.Request(url="abc.com/page/1", callback=self.parse_page)

这里,url是要抓取的网页的地址,下载网页后的响应会发送给parse_page()回调函数,参数是传递的response,如下图所示。

def parse_page(self, response):
    # Do your data extraction processes with the response

您可以使用 XPath 或 CSS 选择器从响应中提取所需的数据。这个提取过程将在后面的部分解释。蜘蛛可以发出任意数量的请求。最需要记住的是 每个请求必须有一个对应的回调函数。

多请求和响应处理

从上一节中,您可能已经理解了如何处理一个请求及其响应。但是,在典型的 web 抓取场景中,会有多个请求。我会尽可能简单地让你理解它的工作原理。让我继续上一节的请求部分。即使这是一个请求,它仍然会被发送到调度程序。根据文档,使用 python 的yield关键字将请求创建为 iterables 。因此,用 python 的术语来说,请求是使用 python 生成器创建的。产生一个请求会触发引擎将它发送给调度程序,其工作原理前面已经解释过了。类似地,蜘蛛可以使用yield发出多个请求。下面是一个例子。

def make_requests(self, urls): for url in urls:
        yield scrapy.Request(url=url, callback=self.parse_url)

在上面的代码片段中,让我们假设urls中有 10 个 URL 需要废弃。我们的make_requests()将向调度程序产生 10 个scrapy.Request()对象。一旦对其中一个请求有了响应,parse_url()回调函数就会被调用。现在让我们深入了解响应处理的工作原理。像请求一样,回调函数也必须yield它从响应中提取的项目。让我用上面代码片段中的回调函数parse_url()来解释一下。

def parse_url(self, response):

    item_name = # extract item name from response using XPath or CSS selector
    item_price = # extract item price from response using XPath or CSS selector# yields a dictionary containing item's name and price
    yield {
        'name': name,
        'price': price,
    }

提取的项目可以在需要时使用,也可以存储以供持久使用。回调函数可以返回可迭代的请求、字典、项目对象、数据类对象、属性对象或什么都不返回。欲知详情,请点击此处

Scrapy 的安装和基本操作

我希望你对 Scrapy 的工作原理有一个基本的了解,现在是你开始使用它的时候了。但首先,你需要安装 Scrapy。

安装刮刀

Scrapy 可以通过 anaconda 或 pip 安装。

conda install -c conda-forge scrapy

或者

pip install Scrapy

对于在其他操作系统上安装或任何其他安装查询,请点击此处

创建新项目

现在你已经安装了 Scrapy,让我们创建一个新项目。Scrapy 提供了一个简单的方法来创建新的项目。导航到您想要创建新的 Scrapy 项目的目录,并键入以下命令。我已经将这个项目命名为tutorial。您可以自由命名您的项目。

scrapy startproject tutorial

这将创建一个名为tutorial的文件夹,其中包含以下文件和文件夹。

tutorial/
├── scrapy.cfg
└── tutorial
    ├── __init__.py
    ├── items.py
    ├── middlewares.py
    ├── pipelines.py
    ├── __pycache__
    ├── settings.py
    └── spiders
        ├── __init__.py
        └── __pycache__

让我把你的注意力引向spiders文件夹。这是你创造蜘蛛的地方。要了解每个生成文件的用途,请参考这个链接

创造蜘蛛

Scrapy 再次提供了一条简单的线来创建蜘蛛。下面显示的语法使用您提供的参数为新的蜘蛛创建了一个模板。

scrapy genspider [-t template] <name> <domain>

有 4 种模板可用,即 4 种蜘蛛类型:basiccrawlcsvfeedxmlfeed。在本教程中,我们将重点关注basiccrawl蜘蛛。<name>参数被设置为蜘蛛的名称,而<domain>参数用于生成allowed_domainsstart_urls蜘蛛属性。这些<name><domain>参数都是强制性的。

创建一个基本的蜘蛛

要为域example.com创建一个基本的 spider,在 spider 项目的根目录下键入以下内容。

scrapy genspider -t basic example_basic_spider example.com

这将在spiders文件夹中创建一个文件名为example_basic_spider.py的基本蜘蛛。这个文件的内容应该是这样的。

# -*- coding: utf-8 -*-
import scrapyclass ExampleBasicSpiderSpider(scrapy.Spider):
    name = 'example_basic_spider'
    allowed_domains = ['example.com']
    start_urls = ['http://example.com/']def parse(self, response):
        pass

让我解释一下生成的模板的组件。

  • name:必须填写。Scrapy 通过蜘蛛的名字来识别它们。
  • allowed_domains:在抓取网页的过程中,你可能会碰到一个完全指向其他某个网站的 URL。这有助于限制蜘蛛爬行到不必要的域。您可以添加任意数量的想要爬网的域。
  • start_urls:指定蜘蛛抓取的起始 URL。您可以从多个 URL 开始。
  • parse(self, response):这是默认的回调函数。您可以编写代码来操作和提取响应中的数据。

您现在可以自由地用您希望抓取的网页地址修改start_urls

等一下!!您可以看到响应,但是请求是如何生成的呢?(你可能还记得上一节的scrapy.Request())。当 Scrapy 看到start_urls时,它会使用start_urls中的 URL 自动生成scrapy.Request(),并将parse()作为回调函数。如果您不希望 Scrapy 自动生成请求,您必须使用start_requests()功能来生成请求。我将修改为基本蜘蛛生成的相同代码来说明start_requests()

# -*- coding: utf-8 -*-
import scrapyclass ExampleBasicSpiderSpider(scrapy.Spider):
    """
    Modified Basic Spider to make use of start_requests()
    """
    name = 'example_basic_spider'
    allowed_domains = ['example.com']def start_requests(self):
        urls = ['http://example.com/']
        for url in urls:
            yield scrapy.Request(url=url, callback=self.parse)def parse(self, response):
        pass

请注意,Scrapy 生成的代码只是一个模板。它并不要求你遵守它。你可以随意改变它。你可以定义你的回调函数,但是记住在发出请求的时候使用它。

创建爬行蜘蛛

既然我们已经完成了基本的蜘蛛,让我们继续学习爬行蜘蛛。要创建爬行蜘蛛,请在蜘蛛项目的根目录下键入以下命令。

scrapy genspider -t crawl example_crawl_spider example.com

这将在spiders文件夹中创建一个文件名为example_crawl_spider.py的爬行蜘蛛。内容应该是这样的。

# -*- coding: utf-8 -*-
import scrapy
from scrapy.linkextractors import LinkExtractor
from scrapy.spiders import CrawlSpider, Ruleclass ExampleCrawlSpiderSpider(CrawlSpider):
    name = 'example_crawl_spider'
    allowed_domains = ['example.com']
    start_urls = ['http://example.com/']rules = (
        Rule(LinkExtractor(allow=r'Items/'), callback='parse_item', follow=True),
    )def parse_item(self, response):
        item = {}
        #item['domain_id'] = response.xpath('//input[@id="sid"]/@value').get()
        #item['name'] = response.xpath('//div[@id="name"]').get()
        #item['description'] = response.xpath('//div[@id="description"]').get()
        return item

你可能会奇怪看到这么多不同于基本的蜘蛛。爬行蜘蛛是一种特殊的基本蜘蛛,它提供内置的方式从start_urls中抓取网页,而基本蜘蛛没有这个功能。

你可能已经注意到了主要的区别:rules。规则定义了抓取网站的特定行为。上述代码中的规则由 3 个参数组成:

  • LinkExtractor(allow=r'Items/'):这是爬行蜘蛛最重要的方面。LinkExtractor 提取正在抓取的网页上的所有链接,并且只允许那些遵循由allow参数给出的模式的链接。在这种情况下,它提取以“Items/”开头的链接(start_urls + allow,即“http://example.com/Items/”),并使用回调函数parse_item为这些提取的链接生成一个请求
  • callback='parse_item':为 LinkExtractor 提取的链接生成的请求的回调函数。
  • follow=True:指定蜘蛛是否应该跟随提取的链接。如果设置为False,蜘蛛将不会爬行,仅通过start_urls停止。

如果你想了解更多的规则,你可以点击这里

side note:可以修改基本蜘蛛跨 URL 爬行。这将在本教程的 第二部分 中举例说明。

从响应中提取感兴趣的项目

有两种方法可以从响应(即下载的网页)中提取感兴趣的项目/数据。

  • 使用 CSS
  • 使用 XPath

响应将保持不变,区别只是从中提取数据的方式不同。在这里的例子中,我将使用 XPath 提取感兴趣的项目。选择 XPath 而不是 CSS 的原因是它们提供了更多的能力和功能。我强烈建议您使用 XPath 浏览一下关于的零碎文档。这里还有一个关于 XPath 的优秀教程
我将解释示例中使用的几个 XPath 表达式。

示例 XPath 表达式(图片由作者提供)

使用浏览器识别感兴趣项目的标签

打开包含您想要提取的数据的网页。右键点击网页上的任意位置,选择“检查”(Chrome)或“检查元素”(Firefox)。它将打开一个新的面板,显示网页的原始 HTML 版本。当您在 raw 版本上滚动时,网页上相应的元素会高亮显示。向上/向下滚动到要提取的项目,选择该项目,右键单击它,选择“复制”,然后从“新建”菜单中选择“XPath”。如果将复制的 XPath 粘贴到记事本或任何文本编辑器中,您将看到从根到当前项的完整 XPath。现在您已经有了感兴趣的项目的 XPath。您可以使用这个路径作为response.xpath()的参数并提取值。

使用 XPath 从感兴趣的项目中获取值

使用 XPath 从感兴趣的项目中获取值有两种方法。

get()

  • 以字符串的形式返回当前或第一个匹配标签/项目的值
  • 示例:response.xpath('//div[@id="name"]').get()使用属性“id="name "”返回“div”标记内的值

getall()

  • 以列表的形式返回匹配标签/项目的所有值
  • 示例:response.xpath('//div[@id="name"]').getall()返回一个列表,该列表包含属性为“id="name "”的所有“div”标记的值

追踪蜘蛛

如果你不能运行蜘蛛,所有这些工作都将是浪费,不是吗?不要担心。运行/执行蜘蛛只需要一行命令。你需要做的就是遵循这个语法:scrapy crawl <spider_name>

让我试着运行我们刚刚创建的两个示例蜘蛛。
scrapy crawl example_basic_spider
scrapy crawl example_crawl_spider

当您运行蜘蛛时,如果一切正常,没有错误或异常,所有提取的数据将被转储到终端或控制台。要存储这些提取的数据,你需要做的就是给scrapy crawl命令添加一个选项。

语法:scrapy crawl <spider_name> -o <output_file>

Scrapy 可以以 JSON、CSV、XML 和 Pickle 格式存储输出。Scrapy 还支持更多存储输出的方式。你可以跟随这个链接了解更多。

让我用输出文件重新运行示例蜘蛛。
scrapy crawl example_basic_spider -o output.json
scrapy crawl example_crawl_spider -o output.csv

在典型的真实场景中,您可能需要使用许多蜘蛛来实现特定的目的。当你有很多蜘蛛时,你可能很难记住所有蜘蛛的名字。Scrapy 来救你了。它有一个命令来列出一个项目中所有可用的蜘蛛。

语法:scrapy list

旁注 : Scrapy 有全局命令和项目专用命令。您可以参考这个 链接 来了解这些命令及其功能。

粗糙的外壳

你已经学会了如何创建、提取数据和运行蜘蛛。但是如何得到满足您需要的正确的 XPath 表达式呢?您不能对 XPath 表达式的每一次试验和调整都运行整个项目。为此,Scrapy 为我们提供了一个交互式 shell,您可以在其中摆弄 XPath 表达式,直到对提取的数据感到满意为止。下面是调用交互式 shell 的语法。

刺儿壳:scrapy shell <url to scrape>

一旦 Scrapy 下载了与提供的 URL 相关的网页,您将看到一个带有In [1]:的新终端提示。您可以开始测试您的 XPath 表达式或 CSS 表达式,无论您喜欢哪个,通过键入您的表达式与response如下所示。

scrapy shell [https://docs.scrapy.org/en/latest/index.html](https://docs.scrapy.org/en/latest/index.html)...In [1]: response.xpath('//div[@id="scrapy-version-documentation"]/h1/text()').get()
Out[1]: 'Scrapy 2.2 documentation'

您可以在这个交互式 shell 中试验 XPath 或 CSS 表达式。要脱离这个 shell,只需像在 python 交互式 shell 中一样键入exit()。我建议你首先利用这个 shell 来设计你的表达式,然后开始你的项目。

结束语

至此,本教程的理论部分已经结束。我们先从 中的实际例子开始下一部分

在那之前,祝你好运。保持安全和快乐的学习。!

用硒刮网

原文:https://towardsdatascience.com/web-scraping-with-selenium-d7b6d8d3265a?source=collection_archive---------7-----------------------

网刮系列

硒的实际操作

克里斯托夫·高尔在 Unsplash 上拍摄的照片

概观

Selenium 是用于测试 web 应用程序的可移植框架。它是在 Apache License 2.0 下发布的开源软件,可以在 Windows、Linux 和 macOS 上运行。尽管 Selenium 有其主要用途,但它也用作 web 抓取工具。在不深入研究 Selenium 的组件的情况下,我们将关注对 web 抓取有用的单个组件, WebDriver 。Selenium WebDriver 为我们提供了通过编程接口控制 web 浏览器来创建和执行测试用例的能力。

在我们的例子中,我们将使用它从网站上抓取数据。当网站动态显示内容,即使用 JavaScripts 呈现内容时,Selenium 就派上了用场。尽管 Scrapy 是一个强大的网络抓取框架,但它对这些动态网站毫无用处。本教程的目标是让您熟悉 Selenium 并使用它进行一些基本的 web 抓取。

让我们从安装 selenium 和一个 web 驱动程序开始。WebDrivers 支持 7 种编程语言:Python、Java、C#、Ruby、PHP、。Net 和 Perl。本手册中的示例是用 Python 语言编写的。互联网上有其他语言的教程。

这是关于使用 Scrapy 和 Selenium 进行网络抓取的 4 部分教程系列的第 3 部分。其他部分可在以下网址找到

第 1 部分:带 Scrapy 的网页抓取:理论理解

第 2 部分:用 Scrapy 进行网页抓取:实用理解

第 4 部分:用硒刮网&刮屑

安装 Selenium 和 WebDriver

安装 Selenium

在任何 Linux 操作系统上安装 Selenium 都很容易。只需在终端中执行以下命令,Selenium 就会自动安装。

pip install selenium

安装 web 驱动程序

Selenium 官方有针对 5 网络浏览器的网络驱动。在这里,我们将看到两个最广泛使用的浏览器的 WebDriver 的安装:Chrome 和 Firefox。

为 Chrome 安装 Chrome 驱动程序

首先,我们需要从 Chrome 的官方网站下载 chromedriver 的最新稳定版本。这将是一个 zip 文件。我们需要做的就是提取它,并把它放在可执行路径中。

wget [https://chromedriver.storage.googleapis.com/83.0.4103.39/chromedriver_linux64.zip](https://chromedriver.storage.googleapis.com/83.0.4103.39/chromedriver_linux64.zip)unzip chromedriver_linux64.zipsudo mv chromedriver /usr/local/bin/

为 Firefox 安装 Geckodriver

为 Firefox 安装 geckodriver 更加简单,因为它是由 Firefox 自己维护的。我们所需要做的就是在终端中执行下面的代码行,然后您就可以开始使用 selenium 和 geckodriver 了。

sudo apt install firefox-geckodriver

例子

有两个越来越复杂的例子。第一个将是一个更简单的网页打开和输入文本框和按键。这个例子展示了如何使用程序通过 Selenium 控制网页。第二个是更复杂的 web 抓取示例,包括鼠标滚动、鼠标按钮点击和导航到其他页面。这里的目标是让你有信心开始用 Selenium 进行 web 抓取。

示例 1 —使用 Selenium 登录脸书

让我们使用 Selenium 和 chromedriver 尝试一个简单的自动化任务,作为我们的训练轮练习。为此,我们将尝试登录一个脸书帐户,我们不会执行任何类型的数据搜集。我假设你对使用浏览器的开发工具识别网页中使用的 HTML 标签有所了解。下面是一段 python 代码,它打开一个新的 Chrome 浏览器,打开脸书主页,输入用户名和密码,然后点击登录按钮。

from selenium import webdriver
from selenium.webdriver.common.keys import Keysuser_name = "Your E-mail"
password = "Your Password"# Creating a chromedriver instance
driver = webdriver.Chrome()  # For Chrome
# driver = webdriver.Firefox() # For Firefox# Opening facebook homepage
driver.get("https://www.facebook.com")# Identifying email and password textboxes
email = driver.find_element_by_id("email")
passwd = driver.find_element_by_id("pass")# Sending user_name and password to corresponding textboxes
email.send_keys(user_name)
passwd.send_keys(password)# Sending a signal that RETURN key has been pressed
passwd.send_keys(Keys.RETURN)# driver.quit()

执行完这段 python 代码后,你的脸书主页将在一个新的 Chrome 浏览器窗口中打开。让我们研究一下这是如何成为可能的。

  1. 这一切都始于为您的浏览器创建一个 webdriver 实例。由于我在使用 Chrome,所以我使用了driver = webdriver.Chrome()
  2. 然后我们用driver.get("https://www.facebook.com")打开脸书网页。当 python 遇到driver.get(URL)时,它会打开一个新的浏览器窗口,打开URL指定的网页。
  3. 一旦主页被加载,我们使用它们的 HTML 标签的 id 属性来识别文本框以键入电子邮件和密码。这是使用driver.find_element_by_id()完成的。
  4. 我们使用send_keys()发送用于登录脸书的usernamepassword值。
  5. 然后,我们通过使用send_keys(Keys.RETURN)发送相应的信号来模拟用户按下回车键的动作。

重要提示:
在程序中创建的任何实例都应该在程序结束时或者在它的目的完成后关闭。因此,每当我们创建一个 webdriver 实例时,必须使用driver.quit()终止它。如果我们不终止打开的实例,它就会开始耗尽 RAM,这可能会影响机器的性能并降低速度。在上面的例子中,这个终止过程已经被注释掉,以便在浏览器窗口中显示输出。如果终止,浏览器窗口也将关闭,读者将看不到输出。

示例 2 —从 OpenAQ 中收集污染数据

这是一个更复杂的例子。 OpenAQ 是一个收集和分享空气质量数据的非营利组织,这些数据是公开的,可以通过多种方式访问。这一点从该网站的 robots.txt 中可见一斑。

User-agent: * 
Disallow:

我们的目标是收集 http://openaq.org 上列出的所有国家的 PM2.5 数据。 PM2.5 是指直径小于 2.5 微米的颗粒物(PM),比人类头发的直径还要小。如果读者有兴趣了解更多关于 PM2.5 的信息,请点击此链接。

选择 Selenium 而不是 Scrapy 的原因是http://openaq.org使用 React JS 来呈现数据。如果是静态网页,Scrapy 会高效地抓取数据。为了收集数据,我们首先需要分析网站,手动导航页面,并记下提取数据所需的用户交互步骤。

了解http://openaq.org的布局

尽量少用网页导航刮总是比较好的。该网站有一个网页https://openaq.org/#/locations可以作为抓取的起点。

来自 https://openaq.org/#/locations的截图突出显示过滤选项

左侧面板上的过滤器位置选项用于过滤出每个国家的 PM2.5 数据。右侧面板上的结果显示了点击显示 PM2.5 和其他数据时打开新页面的卡片。

来自https://openaq.org/#/locations的截图显示了选择国家和 PM2.5 后的结果

包含 PM2.5 数据的示例页面如下所示。从这个页面,我们可以提取 PM2.5 值,位置,城市,国家,日期和时间记录 PM2.5 值使用 XPATH 或 CSS。

来自 https://openaq.org的截图显示点击上一张图片中的位置后的 PM2.5 值

同样,左侧面板可用于过滤和收集包含 PM2.5 数据的所有位置的 URL。以下是我们为收集数据而手动执行的操作。

  1. 打开 https://openaq.org/#/locations
  2. 从左侧面板中,选择/单击国家/地区的复选框。让我们按字母顺序浏览一下这些国家。
  3. 此外,在左侧面板中,选择/单击复选框 PM2.5。
  4. 等待卡片装入右侧面板。每张卡片点击后都会打开一个新的网页,显示 PM2.5 和其他数据。

收集 PM2.5 数据所需的步骤

根据执行的手动步骤,从http://openaq.org收集数据分为 3 个步骤。

  1. 收集 OpenAQ 国家网页上显示的国家名称。这将用于在过滤时选择适当的复选框。
  2. 从每个国家收集包含 PM2.5 数据的 URL。一些国家包含从不同地点收集的 20 多个 PM2.5 读数。这将需要对网页进行进一步的操作,这将在代码部分进行解释。
  3. 打开个人网址的网页并提取 PM2.5 数据。

抓取 PM2.5 数据

现在我们有了需要的步骤,让我们开始编码。该示例分为 3 个函数,每个函数执行与上述 3 个步骤相对应的任务。这个例子的 python 代码可以在我的 GitHub 资源库 中找到。

获取 _ 国家()

有一个https://openaq.org/#/countries网页,可以一次显示所有国家,而不是使用 OpenAQ locations 网页。从这个页面提取国家名称更容易。

来自https://openaq.org/#/countries的显示国家列表的截图

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
import jsondef get_countries():countries_list = []# driver = webdriver.Chrome() # To open a new browser window and navigate it# Use the headless option to avoid opening a new browser window
    options = webdriver.ChromeOptions()
    options.add_argument("headless")
    desired_capabilities = options.to_capabilities()
    driver = webdriver.Chrome(desired_capabilities=desired_capabilities)# Getting webpage with the list of countriesdriver.get("https://openaq.org/#/countries")# Implicit wait
    driver.implicitly_wait(10)# Explicit wait
    wait = WebDriverWait(driver, 5)
    wait.until(EC.presence_of_element_located((By.CLASS_NAME, "card__title")))

    countries = driver.find_elements_by_class_name("card__title")
    for country in countries:
        countries_list.append(country.text)driver.quit()# Write countries_list to json file
    with open("countries_list.json", "w") as f:
        json.dump(countries_list, f)

让我们了解代码是如何工作的。和往常一样,第一步是实例化 webdriver。这里,不是打开一个新的浏览器窗口,而是将 webdriver 实例化为一个无头窗口。这样,就不会打开新的浏览器窗口,从而减轻了 RAM 的负担。第二步是打开包含国家列表的网页。在上面的代码中使用了等待的概念。

  • 隐式等待:当创建时,它是活动的,直到 WebDriver 对象终止。并且对于所有操作都是通用的。它指示 webdriver 在元素加载到网页之前等待一段时间。
  • 显式等待:限制于特定 web 元素的智能等待,在本例中,用类名“card__title”标记。一般和ExpectedConditions一起使用。

第三步是使用类名为“card__title”的标签提取国家名称。最后,国家名称被写入一个 JSON 文件以便持久保存。下面是 JSON 文件的一瞥。

countries_list.json["Afghanistan", "Algeria", "Andorra", "Antigua and Barbuda", ... ]

get _ urls()

获得国家列表后的下一步是获得记录 PM2.5 数据的每个位置的 URL。为此,我们需要打开 OpenAQ locations 网页,并利用左侧面板过滤出国家和 PM2.5 数据。一旦被过滤,右侧面板将被填入记录 PM2.5 数据的各个位置的卡片。我们提取与这些卡中的每一个对应的 URL,并最终将它们写入一个文件,该文件将在提取 PM2.5 数据的下一步中使用。一些国家有 20 多个地点记录 PM2.5 数据。例如,澳大利亚有 162 个位置,比利时有 69 个位置,中国有 1602 个位置。对于这些国家/地区,位置网页的右侧面板细分为多个页面。这是非常必要的,我们通过这些网页导航,并收集所有地点的网址。下面的代码有一个while TRUE:循环来执行页面导航的任务。

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.action_chains import ActionChains
from logzero import logger
import selenium.common.exceptions as exception
import time
import jsondef get_urls():# Load the countries list written by get_countries()
    with open("countries_list.json", "r") as f:
        countries_list = json.load(f)

    # driver = webdriver.Chrome()

    # Use headless option to not open a new browser window
    options = webdriver.ChromeOptions()
    options.add_argument("headless")
    desired_capabilities = options.to_capabilities()
    driver = webdriver.Chrome(desired_capabilities=desired_capabilities)urls_final = []
    for country in countries_list:# Opening locations webpage
        driver.get("https://openaq.org/#/locations")
        driver.implicitly_wait(5)
        urls = []# Scrolling down the country filter till the country is visible
        action = ActionChains(driver)
        action.move_to_element(driver.find_element_by_xpath("//span[contains(text()," + '"' + country + '"' + ")]"))
        action.perform()# Identifying country and PM2.5 checkboxes
        country_button = driver.find_element_by_xpath("//label[contains(@for," + '"' + country + '"' + ")]")
        values_button = driver.find_element_by_xpath("//span[contains(text(),'PM2.5')]")

        # Clicking the checkboxes
        country_button.click()
        time.sleep(2)
        values_button.click()
        time.sleep(2)while True:
            # Navigating subpages where there are more PM2.5 data. For example, Australia has 162 PM2.5 readings from 162 different locations that are spread across 11 subpages.locations = driver.find_elements_by_xpath("//h1[@class='card__title']/a")for loc in locations:
                link = loc.get_attribute("href")
                urls.append(link)try:
                next_button = driver.find_element_by_xpath("//li[@class='next']")
                next_button.click()
            except exception.NoSuchElementException:
                logger.debug(f"Last page reached for {country}")
                breaklogger.info(f"{country} has {len(urls)} PM2.5 URLs")
        urls_final.extend(urls)logger.info(f"Total PM2.5 URLs: {len(urls_final)}")
    driver.quit()# Write the URLs to a file
    with open("urls.json", "w") as f:
        json.dump(urls_final, f)

记录运行时间超过 5 分钟的程序的输出总是一个好的习惯。为此,上面的代码使用了logzero。包含 URL 的输出 JSON 文件如下所示。

urls.json[
    "https://openaq.org/#/location/US%20Diplomatic%20Post%3A%20Kabul",
    "https://openaq.org/#/location/Kabul",
    "https://openaq.org/#/location/US%20Diplomatic%20Post%3A%20Algiers",
    ...
]

get_pm_data()

从单个位置获取 PM2.5 数据的过程是一个直接的 web 抓取任务,即识别包含数据的 HTML 标签并通过文本处理提取它。在下面提供的代码中也会发生同样的情况。该代码提取国家、城市、位置、PM2.5 值、位置的 URL、记录 PM2.5 值的日期和时间。因为有超过 5000 个 URL 要打开,所以除非安装的 RAM 超过 64GB,否则 RAM 使用会有问题。为了让这个程序在最低 8GB 内存的机器上运行,每 200 个 URL 就终止并重新实例化 webdriver。

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.action_chains import ActionChains
from logzero import logger
import selenium.common.exceptions as exception
import time
import jsondef get_pm_data():# Load the URLs list written by get_urls() 
    with open("urls.json", "r") as f:
        urls = json.load(f)# Use headless option to not open a new browser window
    options = webdriver.ChromeOptions()
    options.add_argument("headless")
    desired_capabilities = options.to_capabilities()
    driver = webdriver.Chrome(desired_capabilities=desired_capabilities)list_data_dict = []
    count = 0for i, url in enumerate(urls):
        data_dict = {}# Open the webpage corresponding to each URL
        driver.get(url)
        driver.implicitly_wait(10)
        time.sleep(2)try:
            # Extract Location and City
            loc = driver.find_element_by_xpath("//h1[@class='inpage__title']").text.split("\n")
            logger.info(f"loc: {loc}")
            location = loc[0]
            city_country = loc[1].replace("in ", "", 1).split(",")
            city = city_country[0]
            country = city_country[1]
            data_dict["country"] = country
            data_dict["city"] = city
            data_dict["location"] = locationpm = driver.find_element_by_xpath("//dt[text()='PM2.5']/following-sibling::dd[1]").textif pm is not None:
                # Extract PM2.5 value, Date and Time of recording
                split = pm.split("µg/m³")
                pm = split[0]
                date_time = split[1].replace("at ", "").split(" ")
                date_pm = date_time[1]
                time_pm = date_time[2]
                data_dict["pm25"] = pm
                data_dict["url"] = url
                data_dict["date"] = date_pm
                data_dict["time"] = time_pmlist_data_dict.append(data_dict)
                count += 1except exception.NoSuchElementException:
            # Logging the info of locations that do not have PM2.5 data for manual checking
            logger.error(f"{location} in {city},{country} does not have PM2.5")# Terminating and re-instantiating webdriver every 200 URL to reduce the load on RAM
        if (i != 0) and (i % 200 == 0):
            driver.quit()
            driver = webdriver.Chrome(desired_capabilities=desired_capabilities)
            logger.info("Chromedriver restarted")# Write the extracted data into a JSON file
    with open("openaq_data.json", "w") as f:
        json.dump(list_data_dict, f)logger.info(f"Scraped {count} PM2.5 readings.")
    driver.quit()

程序的结果如下所示。该程序从 4114 个单独的位置提取了 PM2.5 值。想象一下打开这些单独的网页并手动提取数据。总的来说,正是这种时候让我们欣赏网络抓取程序或机器人的使用。

openaq_data.json[
    {
        "country": " Afghanistan",
        "city": "Kabul",
        "location": "US Diplomatic Post: Kabul",
        "pm25": "33",
        "url": "https://openaq.org/#/location/US%20Diplomatic%20Post%3A%20Kabul",
        "date": "2020/07/31",
        "time": "11:00"
    },
    {
        "country": " Algeria",
        "city": "Algiers",
        "location": "US Diplomatic Post: Algiers",
        "pm25": "31",
        "url": "https://openaq.org/#/location/US%20Diplomatic%20Post%3A%20Algiers",
        "date": "2020/07/31",
        "time": "08:30"
    },
    {
        "country": " Australia",
        "city": "Adelaide",
        "location": "CBD",
        "pm25": "9",
        "url": "https://openaq.org/#/location/CBD",
        "date": "2020/07/31",
        "time": "11:00"
    },
    ...
]

结束语

我希望这篇教程已经给了你用 Selenium 开始 web 抓取的信心。示例的完整代码在我的 GitHub 资源库 中。在 下一篇教程 中,我将向你展示如何将硒与 Scrapy 整合。

在那之前,祝你好运。保持安全和快乐的学习。!

网页抓取雅虎财经

原文:https://towardsdatascience.com/web-scraping-yahoo-finance-477fe3daa852?source=collection_archive---------5-----------------------

从任何公开交易的公司提取财务报表和股票数据

马库斯·斯皮斯克在 Unsplash 上的照片

这个博客的代码可以在我的 GitHub 上找到。

在商界,了解一家公司的财务状况很重要。查看财务报表是了解一家公司经营状况的好方法。

在这篇博客中,我将用 Python 从雅虎财经的数据库中提取任何公司的财务报表。因为 Yahoo Finance 使用 JavaScript,所以我们结合使用了 BeautifulSoup 和 Selenium

导入库

让我们从必要的库开始:

import pandas as pd
from bs4 import BeautifulSoup
import re
from selenium import webdriver
import chromedriver_binary
import stringpd.options.display.float_format = '{:.0f}'.format

设置并运行驱动程序

is_link = '[https://finance.yahoo.com/quote/AAPL/financials?p=AAPL'](https://finance.yahoo.com/quote/AAPL/financials?p=AAPL')driver = webdriver.Chrome()
driver.get(is_link)
html = driver.execute_script('return document.body.innerHTML;')
soup = BeautifulSoup(html,'lxml')

我更喜欢使用 Chrome 作为我的网络浏览器,但也可以随意使用你最熟悉的浏览器(Firefox、Safari 等)。).我也使用苹果公司作为我的示例公司,但是您可以更改链接中的 AAPL 股票代码到另一家公司的股票代码来更改数据。

上述代码将在虚拟浏览器中打开页面,并提取网站正文中的所有数据。由于 Yahoo Finance 是在 JavaScript 上运行的,所以通过这种方法运行代码会提取所有数据并保存,就像它是一个静态网站一样。这对于拉动股价很重要,因为这些是网页上的动态项目,可以定期刷新/更新。

为了提取股票数据,我们从获取股票价格的位置开始。通过将鼠标悬停在股票价格上,我们可以使用 Inspect 工具找到股票价格的确切语法。

将这些信息转移到 Python 中,代码将如下所示:

close_price = [entry.text for entry in soup.find_all('span', {'class':'Trsdu(0.3s) Fw(b) Fz(36px) Mb(-4px) D(ib)'})]

这段代码在所有 HTML 代码中搜索“span”标记,并查找与输入的属性相匹配的 class 属性。幸运的是,这只拉了一个数字,即收盘时的股价。

现在我们有了这个,我们可以继续看财务报表了。

提取财务报表数据

继续抓取,我们搜索页面以找到所有的 div 容器,并深入一点以找到我们想要使用的特性。我发现财务数据的每一行都存储在一个 div 容器中,该容器有一个公共的 class 属性 'D(tbr)' 。在下面的例子中,class 属性中有额外的数据,但是只要第一部分与我们要搜索的内容匹配,它就会提取这些数据。

财务报表上的每一行都存储在一个 div 中

features = soup.find_all('div', class_='D(tbr)')

这将拉出很多看起来杂乱的数据,让我困惑了一段时间。在深入研究提取的数据后,我使用 find 函数来查看我想要的每行数据在哪里。经过大量的试验和错误,我能够生成只提取财务数据的代码:

headers = []
temp_list = []
label_list = []
final = []
index = 0#create headers
for item in features[0].find_all('div', class_='D(ib)'):
    headers.append(item.text)#statement contents
while index <= len(features)-1:
    #filter for each line of the statement
    temp = features[index].find_all('div', class_='D(tbc)')
    for line in temp:
        #each item adding to a temporary list
        temp_list.append(line.text)
    #temp_list added to final list
    final.append(temp_list)
    #clear temp_list
    temp_list = []
    index+=1df = pd.DataFrame(final[1:])
df.columns = headers

头与数据的其余部分是分开的,因为当把所有数据放在一起时会引起一些问题。在为财务报表中的数据创建一个标题列表和多个列表后,它将所有内容组合在一起生成一个副本!

它看起来就像苹果的损益表(没有格式化),但尽管看起来很完整,下一个问题是页面上的所有数字都保存为字符串。如果我们想对它做任何未来的计算,我们必须把它们都变成整数:

#function to make all values numerical
def convert_to_numeric(column): first_col = [i.replace(',','') for i in column]
    second_col = [i.replace('-','') for i in first_col]
    final_col = pd.to_numeric(second_col)

    return final_col

通过快速 for 循环,我们可以将所有数字字符串转换为整数:

for column in headers[1:]:

    df[column] = convert_to_numeric(df[column])final_df = df.fillna('-')

这会将所有带编号的字符串转换为实际数字,对于所有 nan,它会被一个破折号替换。

最终产品看起来非常好,现在可以用于计算!

最终损益表

虽然这只是从苹果公司提取损益表,但如果你在资产负债表或现金流量表上使用雅虎金融的链接,代码应该会提取所有细节,并像上面一样将报表放在一起。

我确信有很多额外的工作可以做,以清理这一点,我很乐意在不久的将来使它看起来更像一个官方声明。在继续这方面的工作的同时,我想对数据进行一些深入研究,以找到基本的财务比率,并检查公司估值、投资分析以及我可以从这些数据中挖掘出的其他趋势/发现。敬请期待!

我希望这段代码有所帮助,如果你有任何反馈或建议,我很乐意听到!

Web 报废、下载 Twitter 数据和使用 Python 进行情感分析

原文:https://towardsdatascience.com/web-scrapping-downloading-twitter-data-and-performing-sentimental-analysis-using-python-fce3ea45c825?source=collection_archive---------23-----------------------

使用数据细分非洲影响者,以推动营销决策。

斯蒂芬·道森在 Unsplash 上拍摄的照片

社交媒体影响者在当前人类互联日益增加的社会中发挥着重要作用;商业组织正在意识到对影响者营销活动的需求(Newberry,2019)。成功的影响者营销活动需要与合适的社交媒体影响者合作。那么,我们如何确定正确的影响者呢?

对于数据科学界来说,只有数据才有答案。让我们进行一个案例研究,以确定在数字营销活动中可以与之合作的合适的非洲影响者。我们将探索从相关网站上删除数据,从 twitter 上为特定用户提取数据,并进行情感分析,以确定合适的影响者进行合作。

Web 报废

网站有一份预先确定的非洲 100 名有影响力人士的名单,而网站有一份非洲关键政府官员的名单。要废弃这两个网站,我们首先导入必要的库:

from requests import get
from requests.exceptions import RequestException
from contextlib import closing
from bs4 import BeautifulSoup
import pandas as pd
import re
import os, sysimport fire

接下来,我们通过制作一个HTTP GET request来定义一个获取网站内容的函数:

def simple_get(url):
    try:
        with closing(get(url, stream=True)) as resp:
            if is_good_response(resp):
                return resp.content
            else:
                return None
    except RequestException as e:
        log_error('Error during requests to {0} : {1}'.format(url, str(e)))
        return None

我们还将定义另一个函数来下载由 URL 指定的页面,并返回一个字符串列表,每个标签元素一个字符串:

def get_elements(url, tag='',search={}, fname=None):
    if isinstance(url,str):
        response = simple_get(url)
    else:
        #if already it is a loaded html page
        response = urlif response is not None:
        html = BeautifulSoup(response, 'html.parser')

        res = []
        if tag:    
            for li in html.select(tag):
                for name in li.text.split('\n'):
                    if len(name) > 0:
                        res.append(name.strip())

        if search:
            soup = html            

            r = ''
            if 'find' in search.keys():
                print('finding',search['find'])
                soup = soup.find(**search['find'])
                r = soup if 'find_all' in search.keys():
                print('finding all of',search['find_all'])
                r = soup.find_all(**search['find_all'])

            if r:
                for x in list(r):
                    if len(x) > 0:
                        res.extend(x)

        return res

上面的函数使用 BeautifulSoup 库进行原始 HTML 选择和内容提取。选择是基于标签元素或与findfind_all一起使用搜索完成的。

我们现在可以调用我们定义的函数并传入我们两个网站的 URL。

res = get_elements('[https://africafreak.com/100-most-influential-twitter-users-in-africa'](https://africafreak.com/100-most-influential-twitter-users-in-africa'), tag = 'h2') url= '[https://www.atlanticcouncil.org/blogs/africasource/african-leaders-respond-to-coronavirus-on-twitter/#east-africa'](https://www.atlanticcouncil.org/blogs/africasource/african-leaders-respond-to-coronavirus-on-twitter/#east-africa')
response = simple_get(url)
res_gov = get_elements(response, search={'find_all':{'class_':'twitter-tweet'}})

这些函数返回网站上符合我们搜索标准的所有内容,因此,我们需要清理数据,只获取 twitter 用户名:

数据清理

在数据清理过程中使用了.split().strip()方法来去除任何空白或特殊字符。例如,清除res数据将会:

res_cleaned = []
for element in res:
    if re.findall("@", element):
        res_cleaned.append(element)

df = pd.DataFrame(res_cleaned)
df1 = df[0].str.split('@', expand = True)influencers = df1[1].tolist()final = []
for influencer in influencers:
    influencer = influencer.strip(')')
    final.append(influencer)

最后,我们将废弃和清理的数据保存到一个 CSV 文件中:

pd.DataFrame(final, columns = ['Twitter handles']).to_csv('influencers_scraped.csv', index = False, encoding = 'utf-8')

下载 Twitter 数据

就像任何 python 程序都需要的一样,我们从导入所需的库开始。对于这个提取,我们将使用 Tweepy 库来提取 Twitter 数据:

import tweepy
from tweepy.streaming import StreamListener
from tweepy import OAuthHandler
from tweepy import Stream
from tweepy import Cursor
from tweepy import API

接下来,我们初始化变量来存储访问 Twitter API 的用户凭证,验证凭证,并创建到 Twitter 流 API 的连接:

consumer_key = 'YOUR TWITTER API KEY'
consumer_secret = 'YOUR TWITTER API SECRET KEY'
access_token = 'YOUR TWITTER ACCESS TOKEN'
access_token_secret = 'YOUR TWITTER ACCESS TOKEN SECRET'#authentication and connection
auth = OAuthHandler(consumer_key, consumer_secret)
auth.set_access_token(access_token, access_token_secret)

auth_api = API(auth)

在成功创建到 twitter 的连接之后,我们继续为用户提取数据,并将数据存储在 CSV 文件中,以便在分析过程中更容易访问。

以下函数接收用户列表和 CSV 文件名作为参数,遍历列表获取每个用户的数据,并将数据保存到 CSV 文件中。

def get_user_info(list, csvfile):
    users_info = []
    for user in list:
        print ('GETTING DATA FOR ' + user)
        try:
            item = auth_api.get_user(user)

            users_info.append([item.name, item.description, item.screen_name, item.created_at, item.statuses_count, item.friends_count, item.followers_count])

        except Exception:
            pass

    print('Done!!')

    user_df = (pd.DataFrame(users_info, columns = ["User", "Description", "Handle", "Creation Date", "Tweets", "Following", "Followers"])).to_csv(csvfile, index = False, encoding = 'utf-8')

用户推文中的标签和提及次数也有助于确定个人的影响力水平。因此,我们在 Cursor 对象的帮助下获得用户每条 tweet 中的标签和提及,并再次使用以下函数将数据保存在 CSV 文件中:

def get_tweets(list,csvfile1, csvfile2, csvfile3):
    hashtags = []
    mentions = []for user in list:
        print ("GETTING DATA FOR "+ user)
        try:
            for status in Cursor(auth_api.user_timeline, id = user).items():
                if hasattr(status, "entities"):
                    entities = status.entities
                    if "hashtags" in entities:
                        for ent in entities["hashtags"]:
                            if ent is not None:
                                if "text" in ent:
                                    hashtag = ent["text"]
                                    if hashtag is not None:
                                        hashtags.append(hashtag)
                    if "user_mentions" in entities:
                        for ent in entities["user_mentions"]:
                            if ent is not None:
                                if "screen_name" in ent:
                                    name = ent["screen_name"]
                                    if name is not None:
                                        mentions.append([user, name])
        except Exception:
            pass

    print("Done!")

    hashtags_df = (pd.DataFrame(hashtags, columns = ["hashtags"])).to_csv(csvfile1, index = False, encoding = "utf-8")
    mentions_df = (pd.DataFrame(mentions, columns = ["mentions"])).to_csv(csvfile2, index = False, encoding = "utf-8")

情感分析

既然我们已经挖掘了所有必要的数据,我们可以继续进行分析,以确定影响者的排名和最常用的标签。用于排名的公式基于“衡量 Twitter 中的用户影响力:百万追随者谬误”的论文。

根据 Gummadi、Benevenuto、Haddadi 和 Cha (2010)的研究,一个人的影响力可以通过以下方面来衡量:

  • 深度影响力——个人的受众,
  • 转发影响力——个人产生有价值内容的能力,以及
  • 提及影响力 —个人进行引人入胜的谈话的能力。

这三个度量可以分别计算为到达分数、流行度分数和相关性分数。

reach_score = item.followers_count - item.friends_count
popularity_score = retweet_count + favorites_count
relevance_score = mentions_count

另一方面,最常用的 hashtags 是使用 Counter 模块计算的:

unique_hashtags = []
for item, count in Counter(hashtags).most_common(5):
        unique_hashtags.append([item, count])

最常见的标签数据可用于理解标签的分布以及不同影响者如何使用标签。下面的代码输出一个包含这些信息的条形图。

df = pd.DataFrame(pd.read_csv('hashtags_data.csv'))unique_hashtags = ['...',...,'...'] 

# selecting rows based on condition 
hashtags_grouping_data = df[df['hashtags'].isin(unique_hashtags)]grouped = hashtags_grouping_data.groupby(['hashtags', 'user_type']).agg({'user_type': ['count']})grouped.columns = ['count']
grouped = grouped.reset_index()bp = sns.barplot(x = 'hashtags', y = 'count', hue = 'user_type', data = grouped)#Position the legend out the graph
bp.legend(bbox_to_anchor=(1.02, 1),
          loc=2, 
          borderaxespad=0.0);
bp.set(title='Bar plot for Influencers and Top Government Officials by hashtag', xlabel='Hashtags', ylabel='Count')

由上述代码构建的示例条形图如下所示:

作者图片

结论

影响者营销已经成为新的营销利基,商业组织正在寻找合适的社交媒体影响者,以便与他们合作开展有效的营销活动。利用数据科学,我们可以帮助推动基于事实数据的营销决策。它就像从相关网站上删除数据,从 Twitter 等社交媒体平台下载用户数据,并对数据进行情感分析,以得出商业组织可以更好理解的视觉效果一样系统。帖子概述了该过程中使用的主要代码,完整代码可在此处找到

参考

[1]: C .米扬,h .哈默德,b .法布里西奥,g .克里希纳,测量推特中的用户影响力:百万追随者谬误 (2010),【http://twitter.mpi-sws.org/icwsm2010_fallacy.pdf】T4

[2]: N. Christina,影响者营销指南:如何与社交媒体影响者合作 (2019),https://blog.hootsuite.com/influencer-marketing/

实时机器学习端点的 Web 服务与流

原文:https://towardsdatascience.com/web-services-vs-streaming-for-real-time-machine-learning-endpoints-c08054e2b18e?source=collection_archive---------25-----------------------

Playtika 如何确定大规模交付实时多媒体流端点的最佳架构

作者图片

机器学习(ML)已经成为行业中发展最快的趋势之一。许多公司花费时间和金钱进行营销活动,以展示他们如何使用 ML 进行业务自动化和洞察,从而创造出击败竞争对手的成功产品。当然,很少有公司真正生产和研究塑造用户体验的机器学习模型(并且是实时的)。

Playtika 的人工智能研究是数据科学研究的所有魔力所在,以便产生实时游戏决策,为我们的用户提供更好的游戏体验。Playtika 是一家游戏娱乐公司,为世界各地的观众提供各种基于质量的游戏,以及不断变化并专门为每位玩家量身定制的原创内容。Playtika 利用海量数据,通过根据游戏中的动作定制用户体验,重塑游戏格局。凭借超过 3000 万的月活跃用户(MAU)、100 亿次每日事件和超过 9TB 的每日处理数据,Playtika 能够为其科学家提供所需的数据,以根据用户的游戏行为为其用户创建不断变化和自适应的游戏环境。

随着使用机器学习模型来满足业务需求的需求增加,大脑工程团队发现自己需要一个强大的基础设施,能够水平扩展,并能够处理突发事件、峰值和快速创建新的 ML 管道。我们对如何处理我们的实验、扩展和部署进行了大量思考,并找到了一家新的本土(以色列)创业公司,由经验丰富的数据科学家创建,满足了我们的需求:满足 cn vrg . iocn vrg . io 是一款人工智能操作系统,旨在组织数据科学项目的每个阶段,包括研究、信息收集、代码编写和大规模模型优化。 cnvrg.io 统一了我们的 ML 工作流程,并提供了 MLOps 解决方案,以便我们的团队可以更加专注于交付高影响力的机器学习模型,并为我们的业务和用户创造价值。

使用 cnvrg.io 的 MLOps 解决方案,我们能够分离我们的数据科学家和 ML 数据工程师之间的大部分工作。cnvrg.io 能够持续编写、训练和部署机器学习模型到各种阶段(即训练、试运行、生产),只需点击一个按钮,就能满足我们从研究到生产的流程和需求。它在一个用户友好的界面中拥有 Amazon SageMaker、Mlflow、Kubeflow 等世界知名框架提供的所有工具,其功能包括数据版本控制和管理 t、实验跟踪、模型管理、模型监控和部署。一旦我们的模型被训练、管理和验证,它们就被推到我们的 Kubernetes 集群之上进行生产,准备接收 RESTful API 对预测和推理的请求。能够轻松地部署 ML 模型非常好,但是我们发现我们的模型使用了各种类型的流程。一些模型由批处理触发,其中每天一次,一个预定的气流任务调用一个火花过程,该火花过程将收集数百万玩家的特征,然后发送请求给模型进行预测。其他模型有 Kafka 消费者过程,由游戏中的事件触发,然后调用该模型进行推理。我们已经看到,随着 Playtika 的 DAU 增长,业务将更多的玩家流量推向我们的模型,我们无法总是预测我们的峰值,我们突然需要处理请求失败、批量分区等问题。我们认识到,正如软件世界从 RESTful 服务转向流 API 一样,ML 的世界也应该如此。

作者图片

遇到的问题

在更高的层面上,我们在 ML 管道中遇到的 REST APIs 的主要问题可以归纳为以下三类:

  1. 服务用尽
  2. 客户端饥饿
  3. 处理失败和重试
  4. 批量分区的大容量性能调整

由于我们的批处理过程收集了数百万用户和数百(如果不是数千)个功能,我们无法通过 REST API 向机器学习模型发送一个批量请求,并期望它在合理的时间内返回(不到几分钟——个位数)。这时,我们的数据工程师决定,最好是将这一批分成大约 1000 个播放器的批量(在对批量吞吐量进行一些调整之后)。然而,串行发送 1000 个批量数据会花费很长时间,所以我们允许并行处理这个过程,因此有多个客户端线程发送请求。但是,这反过来又导致了模型的耗尽,这些模型向发出呼叫的客户端引入了超时,并导致了重试机制以及基于死信队列的统计分析的需要。客户端重试产生了更多的流量和混乱,导致服务耗尽和客户端饥饿,我们喜欢称之为“自我拒绝服务”。

这让我们开始研究断路器和速率限制,甚至改变架构。那些广泛使用微服务的人可能听说过隔板模式,这是一种容许失败的应用程序设计。在隔板架构中,应用程序的元素被隔离到池中,这样,如果一个元素出现故障,其他元素将继续工作。它以船体的分段隔板(舱壁)命名。如果船体受损,只有受损部分会进水,从而防止船只沉没。然而,按用户组或请求者 ID 划分模型在设计和部署中是一个很大的开销,因此看起来是一个与我们的问题无关的解决方案。

思维能力

所以,我们决定最好回到我们系统架构的起源和我们游戏架构的关键概念。Playtika 的游戏有一个基于事件驱动的服务后端。一些工作室(游戏)部署了数百个微服务,它们之间的通信主要是通过 Kafka(我们的消息总线)来完成的。这反过来创建了一个异步的(因此最终是一致的)、容错的、可重复的和高度可扩展的系统。我们也知道,我们的游戏和机器学习模型从来不会使用 RESTful APIs 直接通信。背后的基本推理是,我们成功的最重要参数是主游戏玩法和用户体验不会受到影响。所有额外的“最好拥有”功能和见解都很重要,但我们的主要目标是让用户在继续玩游戏的同时保持兴奋、参与和娱乐。因此,来自游戏的所有事件都通过公共 Kafka 主题到达我们的数据平台,这些主题被传输到我们系统的不同层,包括我们的数据湖和流处理管道,这些管道对数据进行装饰和标准化,以允许 Playtika Brain 等消费者运行机器学习模型。而且这些模型的结果通过同样的手段——卡夫卡主题,以治疗(游戏动作中)或者用户状态预测的形式推回到游戏中。由于 Playtika 建立的这种事件驱动的生态系统,我们自己引入流预测管道才有意义。

这时,我们与 cnvrg.io 进行了一次通话,并讨论了不仅使用 REST API 打包我们的模型,而且使用 Kafka Streams 进行传入请求和传出推理的可能性。对于那些不熟悉 Kafka Streams 的人,Kafka Streams 是一个用于构建应用程序和微服务的客户端库,其中的输入和输出数据存储在 Kafka 集群中。它解决了我们在使用批处理和 REST API 方法时遇到的许多难题。

  • 毫秒级延迟的一次一个事件处理(非微批处理)
  • 一次加工
  • 分布式处理和容错以及快速故障转移
  • 重新处理功能,以便您可以在代码更改时重新计算输出

除了 Kafka Streams 解决的强大功能之外,流处理本身还允许我们获得更好的模型计算性能。由于 Playtika 是事件驱动的,所以我们通常看吞吐量而不是延迟。我们承认延迟很重要,尤其是在我们的前端服务中,但我们的许多后端服务明确地关注它们可以处理的消息数量,而不是单个请求的延迟。转向流处理使我们能够将 Kubernetes 豆荚发挥到最佳配置。我们确保部署每个 Pod,使得在该节点上运行的应用程序线程的数量最多为 N-1,其中 N 是该节点上的 CPU 数量。由于我们的模型执行很少的 I/O,并且仅受计算限制,因此我们希望尽可能少的上下文切换,并希望确保每个线程运行并利用单个 CPU。你问为什么是 N-1 而不是 N?嗯,我们确实希望我们心爱的操作系统有自己的处理单元。因此,通过使用流处理,我们能够提高底层 CPU 的使用率和性能,从而实现更大的吞吐量。

测试和概念验证

带着所有这些想法,我们决定对它们进行试验。这正是我们与 cnvrg.io 的对话变得有趣的时候,并且在流媒体功能处于开发阶段时,我们与 cnvrg.io 进行了一次快速概念验证,结果如下。

作者图片

我们采用了一个经过训练的 IMDB 情感分析模型,并以两种形式部署它。第一个是使用包含 Nginx 和 Flask 的 Pod,而第二个是使用包含 Kafka Streams 应用程序的 Pod。

作者图片

部署架构

实验是在 AWS 平台上进行的。每个模型都运行在自己专用的 EC2 m5 .大型实例上(2 个 CPU,8GB RAM)。

REST API

作者图片

REST 服务(模型)是部署到驻留在 nginx 后面的 uWSGI 服务器的 Flask 微服务。

卡夫卡溪流

作者图片

流微服务是一个守护程序服务,它使用 Faust(python 流处理库)来消费来自 Kafka 主题的数据,并将结果输出到输出主题。

结果

实际的结果参数可以在附录部分看到,在那里可以找到所有的图表。

吞吐量

从下面的结果中,我们发现通过使用 Kafka Streams,与 RESTful APIs 相比,我们能够将模型吞吐量提高 50%,平均提高 30%。应该注意的是,在考虑吞吐量时,我们应该考虑成功的吞吐量。这是发送的成功请求数(返回 HTTP 状态代码 200 的请求数)除以测试运行的总秒数。由于计算中存在失败(大多是由 HTTP 超时引起的),我们不仅“丢失”了发送的请求,我们可能还需要将它们作为重试来重放,并在模型上创建更多的流量。

另一个观察结果是,Kafka Streams 微服务吞吐量不会随着时间的推移而出现很大差异。在 web 服务中,差距为 0.5 万亿次,而在 web 服务中,差距超过了 5 万亿次。吞吐量随时间的一致性使我们能够评估和规划模型的性能和可扩展性。

错误

由于 Kafka Streams 是容错的,并且只进行一次处理,所以我们的实验中没有错误。这并不意味着 Kafka 没有问题,可以失败,但是,在其基础上,它被设计为高度可用和传输数十亿条记录。它能够处理突发,因此错误的数量总是最小的。此外,Kafka Streams 被设计为只允许一次处理,因此我们知道我们不会导致消息重复。

当观察 REST API 结果时(如图 1 所示),我们看到错误率在第一分钟后增加,并根据模型实例的负载持续发散。客户端正在耗尽 web 服务,这导致模型吞吐量降低,从而导致更大的延迟和错误。可以清楚地看到,延迟和错误率彼此正相关,而吞吐量与两者负相关。

结论

在对我们的模型运行时进行深入分析后,我们能够看到,迁移到 Kafka Streams 等流技术不仅增加了我们在高峰时段的模型吞吐量,还使我们的容量规划更具确定性和可预测性。我们现在能够处理高峰和故障,而不必创建卫星系统或编写代码来处理故障和边缘情况。我们得出了一条经验法则,即“ 当计算独立且离散 时,所有异步预测都可以转化为流”。这意味着当对来自不同玩家(实体)的事件的预测不受影响(独立)并且同一玩家(实体)的事件不需要分组在一起(离散)时,可以应用流式技术。这个定义不适用的一个用例是聚类问题,其中事件必须被分组在一起,任何类型的重新分组都会影响标签(目标结果)。

REST API

图表-1

作者图片

表-1

作者图片

图表-2

作者图片

表-2

作者图片

流结果

图形-3

作者图片

表-3

作者图片

在谷歌 Colab 上使用 Mask R-CNN 进行网络摄像头对象检测

原文:https://towardsdatascience.com/webcam-object-detection-with-mask-r-cnn-on-google-colab-b3b012053ed1?source=collection_archive---------14-----------------------

如何使用 Mask R-CNN 在 Google Colaboratory 上通过实时摄像机流进行对象检测

在弱光下屏蔽 R-CNN 算法——认为它看到了一只猫_(ツ)_/

有很多方法可以进行物体检测。YOLO(你只看一次)是许多人选择的算法,因为它通过完全卷积神经网络(FCNN)的图像只有一次。这使得推断很快。在 GPU 上大约每秒 30 帧。

YOLO 预测的物体包围盒

另一种流行的方法是使用区域提议网络(RPN)。基于 RPN 的算法有两个部分。第一部分给出感兴趣区域(RoI)的建议…即图像中可能有物体的位置。第二个组件对这些建议的区域执行图像分类任务。这种方法比较慢。Mask R-CNN 是脸书人工智能公司的一个框架,它利用 RPN 进行目标检测。Mask R-CNN 可以在 GPU 上以每秒 5 帧的速度运行。我们将使用面具 R-CNN。

当有更快的替代方案时,为什么要使用慢的算法呢?很高兴你问了!

Mask R-CNN 除了对象检测和边界框预测之外,还输出对象遮罩。

由遮罩 R-CNN 预测的对象遮罩和边界框( Matterport

以下部分包含对代码和概念的解释,有助于理解对象检测,以及在 Colab 上使用 Mask R-CNN 处理摄像机输入。这不是一个循序渐进的教程,但希望它会一样有效。在本文的最后,你会找到 Colab 笔记本的链接,让你自己尝试一下。

Matterport 使用 Keras 和 Tensorflow 对 Mask R-CNN 进行了很好的实现。他们提供了笔记本来玩 Mask R-CNN ,用自己的数据集训练 Mask R-CNN,并检查模型和重量。

为什么选择 Google Colab

如果你没有 GPU 机器或者不想经历设置开发环境的繁琐任务,Colab 是最好的临时选择。

就我而言,我最近丢失了我最喜欢的笔记本电脑。所以,我用的是我的备份机——一台带键盘的 windows 平板电脑。Colab 使你能够在浏览器中的 Jupyter 笔记本上工作,连接到强大的 GPU 或谷歌云中的 TPU(张量处理单元)虚拟机。虚拟机预装了 Python、Tensorflow、Keras、PyTorch、Fastai 和许多其他重要的机器学习工具。全部免费。请注意,您的会话进度会因为几分钟的不活动而丢失。

Google Colab 入门

欢迎使用合作指南让您轻松入门。当从相机获取输入、在笔记本的不同单元之间通信以及在 Python 和 JavaScript 代码之间通信时,高级 Colab 指南就派上了用场。如果你没有时间看它们,只要记住以下几点。

Colab notebook 中的一个单元格通常包含 Python 代码。默认情况下,代码在连接的虚拟机的/content目录中运行。Ubuntu 是 Colab VMs 的操作系统,您可以通过用!开始命令行来执行系统命令。

以下命令将克隆存储库。

!git clone https://github.com/matterport/Mask_RCNN

如果你在同一个单元格中有多个系统命令,那么你必须将%%shell作为单元格的第一行,后跟系统命令。因此,下面的命令集将克隆存储库,将目录更改为 Mask_RCNN 并设置项目。

%%shell
# clone Mask_RCNN repo and install packages
git clone https://github.com/matterport/Mask_RCNN
cd Mask_RCNN
python setup.py install

导入屏蔽 R-CNN

以下代码来自 Matterport 提供的演示笔记本。我们只需要将ROOT_DIR改为./Mask_RCNN,这是我们刚刚克隆的项目。

python 语句sys.path.append(ROOT_DIR)确保后续代码在Mask_RCNN目录的上下文中执行,在该目录中我们有 Mask R-CNN 实现可用。代码导入必要的库、类,并下载预先训练好的 Mask R-CNN 模型。穿过它。注释使理解代码变得更容易。

根据训练的权重创建模型

以下代码在推理模式下创建模型对象,因此我们可以运行预测。然后,它将我们之前下载的预训练模型中的权重加载到模型对象中。

运行对象检测

现在我们在一些图像上测试这个模型。Mask_RCNN 存储库有一个名为images的目录,其中包含...你猜对了...一些图像。下面的代码从该目录中取出一幅图像,将它传递给模型,并在笔记本上显示结果以及边界框信息。

预测的结果

使用相机图像

在 Colab 的高级使用指南中,他们提供了代码,可以从笔记本中的网络摄像头捕捉图像,然后将其转发给 Python 代码。

Colab notebook 预装了名为google.colab的 python 包,其中包含了方便的助手方法。有一个叫做output.eval_js的方法可以帮助我们评估 JavaScript 代码并将输出返回给 Python。在 JavaScript 中,我们知道有一种叫做[getUserMedia()](https://developer.mozilla.org/en-US/docs/Web/API/MediaDevices/getUserMedia)的方法,它使我们能够从用户的网络摄像头和麦克风中捕获音频和/或视频流。

看看下面的 JavaScript 代码。使用 JavaScript 的 WebRTC API 的getUserMedia()方法,它捕获网络摄像头的视频流,并在 HTML 画布上绘制各个帧。像google.colab Python 包一样,我们在 JavaScript 中也有google.colab库。这个库将帮助我们使用 JavaScript 代码中的kernel.invokeFunction函数调用 Python 方法。

从网络摄像头捕获的图像被转换为 Base64 格式。这个 Base64 图像被传递给一个 Python 回调方法,我们将在后面定义它。

我们已经讨论过,将%%shell作为 Colab 笔记本单元的第一行使其作为终端命令运行。同样,您可以通过以%%javascript开始单元格,在整个单元格中编写 JavaScript。但是我们将简单地把上面写的 JavaScript 代码放在 Python 代码中。像这样:

Python — JavaScript 通信

我们上面写的 JavaScript 代码调用了我们的 Python 代码的notebook.run_algo方法。下面的代码定义了一个 Python 方法run_algo,它接受一个 Base64 图像,将其转换为一个 numpy 数组,然后将其传递给我们上面创建的 Mask R-CNN 模型。然后显示输出图像和处理统计数据。

重要!别忘了在 *try / except* 块中圈出你回调方法的 Python 代码,并记录下来。因为它将被 JavaScript 调用,并且在调用 Python 回调时没有发生错误的迹象。

我们把run_algo注册成notebook.run_algo吧。现在 JavaScript 代码可以调用它了。我们还调用上面定义的take_photo() Python 方法,来启动视频流和对象检测。

你自己试试

您现在已经准备好在 Google Colab 中尝试 Mask R-CNN on camera。笔记本会一步一步地引导你完成这个过程。

(可选)出于好奇

我们上面使用的过程在浏览器(JavaScript)中将相机流转换为图像,并将单个图像发送到我们的 Python 代码进行对象检测。这显然不是实时的。所以,我花了几个小时试图将 WebRTC 流从 JavaScript(对等体 A)上传到 Python 服务器(对等体 B),但没有成功。也许我对async / await和 Python Threads的组合不熟悉是主要的障碍。我试图使用[aiohttp](https://github.com/aio-libs/aiohttp)作为 Python 服务器,它将使用[aiortc](https://github.com/aiortc/aiortc)处理 WebRTC 连接。Python 库aiortc使得创建 Python 作为 WebRTC 的对等体变得容易。这里是到 Colab 笔记本的链接,创建 WebRTC 服务器的工作尚未完成。

原载于 2020 年 1 月 29 日 https://emadehsan.com

Python 中用于 NLP 的 HTML 数据清理

原文:https://towardsdatascience.com/website-data-cleaning-in-python-for-nlp-dda282a7a871?source=collection_archive---------14-----------------------

如何彻底清理由废弃的 HTML 网站组成的数据集

照片克莱门特 H 拍摄

任何数据驱动项目最重要的一步是获得高质量的数据。如果没有这些预处理步骤,项目的结果很容易产生偏差或被完全误解。这里,我们将重点关注清理由抓取的网页组成的数据。

获取数据

有很多工具可以抓取网页。如果你正在寻找快速简单的方法,Python 中的 URL 处理模块 urllib 可能会帮你实现。否则,我推荐 scrapyd ,因为可能的定制和健壮性。

确保您抓取的页面包含适合您的用例的富文本数据是很重要的。

从 HTML 到文本

一旦我们获得了抓取的网页,我们就开始从每个网页中提取文本。网站上有很多标签并不包含 NLP 的有用信息,比如<script><button>。令人欣慰的是,有一个名为 boilerpy3 的 Python 模块使得文本提取变得容易。

我们使用ArticleExtractor来提取文本。这个提取器已经针对新闻文章进行了调整,适用于大多数 HTMLs。您可以尝试 boilerpy3 文档中列出的其他提取器,看看哪种最适合您的数据集。

接下来,我们将所有换行符(\n\r)压缩成一个\n字符。这样做是为了当我们用\n和句号将文本分成句子时,我们不会得到没有单词的句子。

如果 boilerpy3 中的提取器对您的网页不起作用,您可以使用 beautifulsoup 来构建您自己的自定义文本提取器。下面是一个替换parse_html方法的例子。

大 N 克清洗

一旦文本被提取出来,我们希望继续清理过程。网页包含重复信息是很常见的,尤其是当你从同一个领域抓取多篇文章时。网站标题、公司标语和页脚等元素可以出现在解析后的文本中。为了检测和删除这些短语,我们通过查看大 n 元语法的频率来分析我们的语料库。

N-grams 是 NLP 中的一个概念,其中“gram”是来自文本主体的单词的连续序列,“N”是这些序列的大小。这经常被用来建立语言模型,它可以帮助从文本摘要到单词预测的任务。以下是三元模型(3 元模型)的示例:

input = 'It is quite sunny today.'
output = ['It is quite', is quite sunny', 'quite sunny today.']

当我们阅读文章时,有许多单个单词(unigrams)会重复出现,例如“the”和“a”。然而,当我们增加 n-gram 的大小时,n-gram 重复的概率会降低。三元组开始变得更加罕见,文章几乎不可能包含 20 个单词的相同序列。通过搜索频繁出现的大型 n 元语法,我们能够检测出语料库中跨网站的重复元素,并手动将其过滤掉。

我们通过用换行符和句号将文本块分割成句子来开始这个过程。接下来,我们对句子进行分词(将句子分解成单词串)。有了这些标记化的句子,我们能够生成特定大小的 n 元语法(我们希望从大的开始,大约 15 个)。我们希望使用nltk提供的FreqDist函数按频率对 n 元文法进行排序。一旦我们有了频率字典,我们就打印前 10 个 n-gram。如果频率高于 1 或 2,那么你可能会考虑从语料库中删除这个句子。要删除句子,复制整个句子并将其作为一个字符串添加到filter_strs数组中。复制整个句子可以通过增加 n-gram 的大小来完成,直到整个句子被捕获在一个 n-gram 中并打印在控制台上,或者简单地打印parsed_texts并搜索句子。如果有多个单词略有不同的不想要的句子,可以将共同的子串复制到filter_strs,正则表达式会过滤掉所有包含该子串的句子。

如果您在数据集上运行上面的代码,而没有向filter_strs添加任何过滤器,您可能会得到类似于下图的图形。在我的数据集中,你可以看到有几个 15 克重复了 6 次,3 次,2 次。

一旦我们经历了用不想要的句子填充filter_strs的过程,我们的 15-grams 图就变平了。

请记住,对于 n-gram 的大小和频率,没有一个最佳的阈值来决定一个句子是否应该被删除,所以请随意使用这两个参数。有时,您需要将 n-gram 的大小降低到 3 或 4,以提取重复的标题,但注意不要删除有价值的数据。这段代码被设计成一个迭代的过程,在这个过程中,你在许多不同的实验之后慢慢地构建filter_strs数组。

标点、大写和标记化

在我们清理了语料库之后,下一步是处理我们的语料库的单词。我们希望删除标点符号,将所有单词小写,并将每个句子分解成单个单词的数组(标记化)。为此,我喜欢使用来自 gensimsimple_preprocess库方法。这个函数一次完成所有这三个任务,并且有几个允许定制的参数。通过设置deacc=True,重音将被移除。删除标点符号时,标点符号本身被视为空格,标点符号两边的两个子字符串被视为两个单独的单词。在大多数情况下,单词将被拆分成一个长度为 1 的子串。比如“不要”最后会变成“don”和“t”。因此,默认的min_len值是 2,所以不保留带有 1 个字母的单词。如果这不适合您的用例,您还可以从头创建一个文本处理器。Python 的string类包含一个punctuation属性,列出了所有常用的标点符号。使用这组标点符号,您可以使用str.maketrans删除字符串中的所有标点,但保留那些有标点的单词作为一个单词(“不”变成“不”)。请记住,这不会像 gensim 的simple_preprocess一样捕捉标点符号。例如,有三种类型的破折号(' em 破折号,-' en 破折号,-'连字符),而simple_preprocess将它们全部删除,string.punctuation不包含 em 破折号,因此不会删除它。

停止言语

一旦我们很好地标记了语料库,我们将从语料库中删除所有停用词。停用词是对句子没有太多额外意义的词。英语词汇中的单词包括“the”、“a”和“in”。nltk包含一个英文停用词列表,所以我们用它来过滤我们的令牌列表。

词汇化和词干化

词汇化是将同一单词的不同形式组合在一起,并用单词的词汇(词典形式)替换这些实例的过程。比如“functions”简化为“function”。词干化是将一个单词缩减为其词根(没有任何后缀或前缀)的过程。比如“跑”就简化为“跑”。这两个步骤减少了词汇量,使机器更容易理解我们的语料库。

现在您已经知道如何提取和预处理文本数据,您可以开始数据分析了。祝你的 NLP 冒险之旅好运!

笔记

  • 如果您使用词性标签对语料库进行标记,那么停用词应该保留在数据集中,并且在标记之前不应该进行词汇化。
  • Jupyter 笔记本的 GitHub 库可以在这里找到。

Websocket —检索实时数据

原文:https://towardsdatascience.com/websocket-retrieve-live-data-f539b1d9db1e?source=collection_archive---------9-----------------------

如何有效检索实时加密货币价格

诺亚·西利曼在 Unsplash 上的照片

为什么我们需要学习如何从 WebSocket 中提取数据?

不是已经可以抓取几乎所有类型的网站了吗?

首先我简单介绍一下 WebSocket,你就知道为什么我们需要学习如何刮了。

Websocket 协议用于提供持久的实时连接。这意味着大多数网站使用 WebSocket 从其服务器向网络发送实时数据,以便您能够查看不断变化的实时数据。

你可能会问,一般什么样的网站会用 WebSocket?

我知道有一些特定类型的网站使用 WebSocket。例如,现场赌博、加密货币和股票市场网站。

现在,让我们全面了解 WebSocket 是如何工作的。为了让它更实用,我将使用 Python 来抓取 Cryptocompare (一家全球加密货币市场数据提供商)作为示例。

首先,您需要找到 WebSocket URI。

在这里,我使用 Chrome 开发工具来检查。打开 Chrome DevTools 后,点击 WS (Web Socket)标签,然后你就可以找到上面紫色方框所包围的请求 URL。

request _ URL:WSS://streamer . crypto compare . com/v2

此外,需要注意的一点是成功状态代码不同于普通的请求。通常,当你请求一个网站时,成功状态码是 200,但是 WebSocket 的成功状态码是 101,在上面的截图中被红框包围。

在开始握手部分之前,让我们讨论一些通过 WebSocket 连接时简单而重要的概念。让我们看看下面的图表。

单击“消息”选项卡,您将看到与我相同的视图。你会注意到有绿色和红色的箭头。绿色箭头表示您正在向网站发送此消息。另一方面,红色箭头是通过 WebSocket 连接时您将收到的消息。

让我们进入下一部分——握手。还记得上图有个绿色箭头吗?这实际上是一个握手的过程。

这是什么意思?

你可以把这个过程想象成一个验证过程。在您设法将此消息发送到网站后,您将能够检索实时数据。整个过程到此结束,让我们进入代码部分。

您可以使用几个包,但是在这种情况下,我将使用 websocket-client Python 包

编码部分

首先,您需要将 web 浏览器的标题复制到这里,并使用json.dumps将其转换为字符串格式。

之后,使用create_connection创建到服务器的连接。然后,通过发送消息来执行握手,您将能够看到您这边的数据。

下面是您应该看到的类似输出。

你可能会想,这条信息似乎毫无意义而且混乱,你确定价格在这里的信息里吗?

答案是肯定的。你可以看看上面截图中紫色方框所围的文字,那其实是 BTC 对美元的现价。

抓取这个网站后,你会发现通过 WebSocket 检索信息是多么容易。如果你有兴趣知道为什么你应该勉强通过 WebSocket,请随意访问这个链接

最终想法

胡安·门德斯摄于 Pexels

写这篇文章是为了回答我在文章评论区收到的一个问题。如果你有任何想让我澄清的问题,欢迎在下面评论。

谢谢你一直读到最后。下期帖子再见!

关于作者

低伟鸿是 Shopee 的数据科学家。他的经验更多地涉及抓取网站,创建数据管道,以及实施机器学习模型来解决业务问题。

他提供爬行服务,可以为你提供你需要的准确和干净的数据。你可以访问这个网站查看他的作品集,也可以联系他获取抓取服务

你可以在 LinkedInMedium 上和他联系。

[## ●伟鸿-中等

在媒体上阅读低纬鸿的作品。数据科学家|网络抓取服务:https://www.thedataknight.com/.每…

medium.com](https://medium.com/@lowweihong)

弱监督学习:具有有限标注能力的分类

原文:https://towardsdatascience.com/weekly-supervised-learning-getting-started-with-unstructured-data-123354dad7c1?source=collection_archive---------10-----------------------

随着大量基于海量数据训练的预训练模型的引入,机器学习在工业应用中的成功呈指数级增长。虽然我们可以通过迁移学习(作为特征提取器或通过对我们的特定数据集进行微调)来轻松利用这些模型,但通常情况下,如果模式与这些模型最初训练的数据明显不同,性能不会很好。

特别是在自然语言处理的情况下,有许多特定于数据的模式,这通常会降低预训练模型的适用性。与此同时,获取特定于应用程序的注释所涉及的挑战不仅降低了数据的可用性,还降低了建模的监督(转移)学习的可用性。

由于未标注的文本数据通常大量存在,无监督/弱监督方法成为数据探索甚至建模的第一手选择。因为建立一个具有领域专业知识的注释者团队不仅昂贵而且耗时,所以最近,从业者已经转向了较弱形式的监督,这也是这篇博客的主要焦点。

图片(按作者):结构化非结构化信息的各种方法

什么是监管不力?

正如在维基百科中提到的,弱监督是机器学习的一个分支,其中嘈杂、有限或不精确的来源被用来提供监督信号,以便在监督学习设置中标记大量训练数据。这种方法减轻了获取手工标记的数据集的负担,这可能是昂贵的或不切实际的。取而代之的是,使用廉价的弱标签,因为它们是不完美的,但是仍然可以用来创建强预测模型。

弱监督学习在亚马逊商品评论上的应用

对于大规模数据集,例如亚马逊情感评论,目标是识别关于用户在图书的负面评论 中提及的内容的广泛类别,并进一步构建可用于向卖家提供分类反馈的预测模型。

表:亚马逊评论数据示例(总共 360 万行)

通过集群上的批量注释建立训练数据集

  1. 启发式提取评分较低的评论
import pandas as pd# Load dataset
df = pd.read_csv("amazon_product_reviews.csv")# Negative Reviews (With rating 1-2)
df = df[df['Rating'] == '1-2']# Sample set of negative Review that mentions book
df = df[df['Amazon Review'].str.contains(
    'book|publication|novel|paperback|hardcover')].sample(50000)

2。文本数据的标准预处理

import re
import nltk
import itertools
import contractions # Load dataset
df = pd.read_csv("amazon_product_reviews.csv")column = 'Amazon Review'# Lowercase text
df[column] = df[column].apply(
    lambda x: x.lower())# Fix contraction in the words
df[column] = df[column].apply(
    lambda x: contractions.fix(str(x)))# Standardise words
df[column] = df[column].apply(
    lambda x: ''.join(''.join(c)[:2] for _, c in itertools.groupby(x)))# Remove punctuations
punctuations_regex="!#%&\'()\*+,-/:;<=>?@\[\]^_`{|}~.1234567890"
df[column] = df[column].apply(
    lambda x: re.sub('[%s]'%re.escape(punctuations_regex), ' ', x))# Tokenize words
df[column] = df[column].apply(
    lambda x: ' '.join(nltk.word_tokenize(x)))

3。特征提取和聚类

  • 可以进一步试验 ngram_range 和 min_df,以优化对重要短语的更多覆盖和对不重要短语的更少覆盖。
  • n_clusters 基于 Elbow 方法+后续步骤中注释集群的专家的可用性进行了优化。
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.cluster import KMeans# Extract TFIDF features with 1-4 grams
TFIDF_PARAMS = {
    'strip_accents': 'ascii',
    'stop_words': 'english',
    'sublinear_tf': True,
    'ngram_range': (1, 4),
    'min_df': 0.003,
}
vectorizer = TfidfVectorizer(**TFIDF_PARAMS)
tfidf_model = vectorizer.fit(df[column])
train_features = tfidf_model.transform(df[column])# Identify clusters on the model
cluster_model = KMeans(n_clusters=200).fit(train_features)
df['cluster_label'] = cluster_model.labels_

4。分析和注释集群

  • 所有的聚类由领域专家标记,并且聚类标签被分配给所有的聚类样本。这极大地减少了标注时间和成本,因为只有 n 个聚类被标记为 ,而不是所有 360 万个样本。

图:分析基于 TFIDF 分数的聚类,并为其添加标签。

  • 最后,对提取的数据集上的“最终类别”的采样结果表明,它的 85 ( 5 ) %准确。

训练预测模型以分配最终类别进行审查

最后,通过对整个非结构化数据运行聚类模型来管理大型训练数据集,并基于聚类标识符来分配标签。最终的预测模型以受监督的方式在该数据集上训练,这不仅处理数据集中的错误,而且以更高的置信度(基于置信度阈值)提供高质量的预测。

# Training XGBoost (Weak supervision)
from xgboost import XGBClassifier
from sklearn.metrics import classification_reportclf = XGBClassifier(n_jobs= -1, objective='multi:softmax')
clf = clf.fit(X_train, y_train)
scores = clf.predict_proba(X_test)y_true = pd.DataFrame(scores,columns=clf.classes_).idxmax(axis=1)
print (classification_report(y_test, y_true, digits=4)) 

图:对 XGBoost 模型的评估,该模型根据聚类定义的类别进行训练

该模型在弱监管下表现异常出色,但根据类别和属于该类别的簇的纯度,准确性可能会在现场设置中下降 5–15%。

这种方法无疑帮助我们快速解决问题,而无需花费大量的时间和金钱来构建大量的训练数据。此外,它可以是基于启发法、分层聚类和建模的学习算法的迭代过程,直到我们获得高质量的基础事实标签。

通过对更高质量的数据集进行重新训练,预测模型的性能会随着时间的推移而提高,该数据集是由领域专家对模型预测进行重复采样而收集的。

参考文献:

权重衰减== L2 正则化?

原文:https://towardsdatascience.com/weight-decay-l2-regularization-90a9e17713cd?source=collection_archive---------2-----------------------

神经网络是很好的函数逼近器和特征提取器,但有时它们的权重变得过于专业,导致过度拟合。这就是正则化概念出现的地方,我们将讨论这两种被误认为相同的主要权重正则化技术之间的细微差别。

(来源)

简介:

神经网络由沃伦麦卡洛克和沃尔特皮茨于 1943 年首次推出,但当时还不够流行,因为它们需要大量的数据和计算能力,这在当时是不可行的。但是,随着上述约束以及其他训练进步(如参数初始化和更好的激活功能)变得可行,它们再次开始主导各种比赛,并在各种人类辅助技术中找到应用。
今天,神经网络形成了许多著名应用的主干,如自动驾驶汽车、谷歌翻译、面部识别系统等,并应用于进化人类使用的几乎所有技术中。

神经网络非常擅长逼近线性或非线性函数,在从输入数据中提取特征时也非常出色。这种能力使他们能够在大范围的任务中创造奇迹,无论是计算机视觉领域还是语言建模。但是我们都听过这句名言:
“权力越大,责任越大”。 这句话同样适用于无所不能的神经网络。他们作为强大的函数逼近器的能力有时会导致他们通过逼近一个函数来过度拟合数据集,该函数在它被训练的数据上表现得非常好,但在它从未见过的数据上测试时却悲惨地失败了。更专业地说,神经网络学习更专门针对给定数据的权重,而不学习可以概括的特征。
为了解决过度拟合的问题,应用了一种称为正则化的技术来降低模型和约束权重的复杂性,其方式是迫使神经网络学习可概括的特征。

正规化:

正则化可以被定义为我们对训练算法进行的任何改变,以便减少泛化误差,而不是训练误差。正则化策略有很多。一些对模型施加额外的约束,例如对参数值添加约束,而一些对目标函数添加额外的项,这可以被认为是对参数值添加间接或软约束。如果我们小心使用这些技术,这可以提高测试集的性能。在深度学习的背景下,大多数正则化技术都基于正则化估计器。当正则化一个估计量时,有一个权衡,我们必须选择一个增加偏差和减少方差的模型。一个有效的规则化是一个有利可图的交易,显著减少方差,同时不过度增加偏差。

实践中使用的主要正则化技术有:

  1. L2 正则化
  2. L1 正则化
  3. 数据扩充
  4. 拒绝传统社会的人
  5. 提前停止

在这篇文章中,我们主要关注 L2 正则化,并讨论我们是否可以将 L2 正则化和权重衰减视为一枚硬币的两面。

L2 正规化:

L2 正则化属于被称为参数范数罚的正则化技术类别。之所以这样说,是因为在这类技术中,特定参数(主要是权重)的范数被添加到被优化的目标函数中。在 L2 规范中,通常称为正则化项的额外项被添加到网络的成本函数中。
例如:

让我们考虑交叉熵成本函数,其定义如下。

图一。交叉熵损失函数

为了将 L2 正则化应用于任何有交叉熵损失的网络,我们将正则化项添加到成本函数中,正则化项如图 2所示。

图二。 L2 范数或欧几里德范数

图 2 中,λ是正则化参数,与应用的正则化量成正比。如果λ =0,则不应用正则化,当λ为 1 时,将最大正则化应用于网络。
λ是一个超参数,这意味着它不是在训练期间学习的,而是由用户手动调整或使用一些超参数调整技术,如随机搜索。

现在让我们把这些放在一起,形成应用于图 3 给出的交叉熵损失函数的 L2 正则化的最终方程。

图 3。最终 L2 正则化成本函数

上面的例子示出了应用于交叉熵损失函数的 L2 正则化,但是这个概念可以推广到所有可用的成本函数。下面在图 4 中给出了 L2 正则化的更一般的公式,其中 Co 是未正则化的成本函数,C 是添加了正则化项的正则化成本函数。

图四。任意代价函数的 L2 正则化的一般形式

注意 : 我们在正则化网络时不考虑网络的偏差,原因如下:
1 .与权重相比,偏差通常需要较少数据来精确拟合。每个权重规定了两个变量(w 和 x)如何相互作用,因此很好地拟合权重需要在各种条件下观察两个变量,而每个偏差仅控制一个变量(b)。因此,我们不引入太多的偏差,让偏差不规范。
2。调整偏差会引入大量的不匹配。

为什么 L2 正规化有效??

实际原因:

让我们试着理解基于成本函数梯度的 L2 正则化的工作原理。
如果我们采用图 4 中所示方程的偏导数或梯度,即网络中所有权重和偏差的∂C/∂w 和∂C/∂b。
取偏导数我们得到:

图 5。成本函数关于权重和偏差的梯度。

我们可以使用反向传播算法计算上述方程中提到的∂C0/∂w 和∂C0/∂b 项。
偏差参数的偏导数将保持不变,因为没有正则化项应用于它,而权重参数将包含额外的((λ/n)*w)正则化项。

偏差和权重的学习规则因此变成:

图 6。偏差参数的梯度下降学习规则

图七。权重参数的梯度下降学习规则

上面的权重公式类似于通常的梯度下降学习规则,除了现在我们首先通过(1(η*λ)/n)重新调整权重 w 。这一项是 L2 正则化经常被称为权重衰减的原因,因为它使权重变小。因此,你可以看到为什么正则化工作,它使网络的权重更小。权重的小意味着,如果我们在这里或那里改变一些随机输入,网络行为不会改变太多,这反过来使得正则化网络难以学习数据中的局部噪声。这迫使网络只学习那些在训练集中经常看到的特征。

个人直觉: 从优化成本函数的角度来简单考虑 L2 正则化,当我们将正则项添加到成本函数中时,我们实际上增加了成本函数的值。因此,如果权重较大,也会导致成本上升,训练算法会通过惩罚权重来降低权重,迫使权重取较小的值,从而调整网络。

L2 正则化和权重衰减是一回事吗?

没有 L2 正则化和权重衰减是不同的东西,但可以通过基于学习速率的权重衰减因子的重新参数化来使 SGD 等效。迷茫?我来给你详细解释一下。

重量衰减方程如下所示,λ为衰减系数。

图 8 :神经网络中的权重衰减

在 SGD 的情况下,L2 正则化可以在以下证明中被证明为等价于权重衰减:

  1. 让我们首先考虑下面图 9 中给出的 L2 正则化方程。我们的目标是对其进行重新参数化,使其等效于图 8中给出的重量衰减方程。

图九。神经网络中的 L2 正则化

2.首先,我们找到 L2 正则化成本函数相对于参数 w 的偏导数(梯度),如图图 10 所示。

图十。损失函数 C 关于 w 的偏导数

注:图中两个符号的意思相同。

3.在我们获得成本函数的偏导数的结果后(图 10 ),我们将该结果代入图 11 所示的梯度下降学习规则中。代入后,我们打开括号并重新排列术语,使其在某些假设下等同于重量衰减方程(图 8 )。

图 11 。替换梯度下降规则中成本函数的梯度并重新排列术语。

4.正如你所注意到的,最终重新排列的 L2 正则化方程(图 11 )和权重衰减方程(图 8 )之间的唯一区别是α(学习速率)乘以λ(正则化项)。为了得到两个方程,我们通过用λ′/α代替λ
来重新参数化 L2 正则化方程,如图图 12 所示。

图 12。L2 正则化与权重衰减等价的条件

5.在用λ代替λ′后,L2 正则化方程被重新参数化,现在等价于重量衰减方程(图 8 ),如图图 13 所示。

图十三。重新参数化的 L2 正则化方程

从上面的证明中,你一定已经理解了为什么在 SGD 的情况下,L2 正则化被认为等同于权重衰减,但是对于其他优化算法,如 Adam、AdaGrad 等,情况并非如此,它们是基于自适应梯度的。特别地,当与自适应梯度结合时,L2 正则化导致具有大历史参数和/或梯度幅度的权重被正则化得比使用权重衰减时更少。与 SGD 相比,当使用 L2 正则化时,这导致 adam 表现不佳。另一方面,体重下降在 SGD 和 Adam 上的表现是一样的。

令人震惊的结果是,具有动量的 SGD 优于 Adam 等自适应梯度方法,因为常见的深度学习库实现了 L2 正则化,而不是原始的权重衰减。因此,在使用 L2 正则化对 SGD 有利的任务上,Adam 导致比带动量的 SGD 差的结果。

结论

因此,我们得出结论,尽管权重衰减和 L2 正则化在某些条件下可能达到等价,但仍然是稍微不同的概念,并且应该被不同地对待,否则会导致无法解释的性能下降或其他实际问题。

我希望你喜欢这篇文章,并学到一些新的东西。如果您有任何疑问或想进一步讨论,请随时通过 TwitterLinkedin 与我联系。

进一步阅读 g:

  1. 解耦权重衰减正则化

参考资料:

  1. 神经网络和深度学习
  2. 伊恩·古德菲勒、约舒阿·本吉奥和亚伦·库维尔的《深度学习》。

3.神经网络 L2 正则化和权重衰减的区别

神经网络的权重初始化——重要吗?

原文:https://towardsdatascience.com/weight-initialization-for-neural-networks-does-it-matter-e2fd99b3e91f?source=collection_archive---------31-----------------------

不同权重初始化技术的比较研究

作者对不同统一初始化|图像的验证准确性和损失比较

机器学习和深度学习技术已经侵入了你能想到的每一个可能的领域。随着数字化数据可用性的增加和现代计算机计算能力的提高,它可能在不久的将来蓬勃发展。作为其中的一部分,每天都有越来越多的人钻研构建和训练模型的任务。作为该领域的新手,我还必须建立和训练一些神经网络模型。嗯,大多数时候,我的主要目标仍然是建立一个高度精确且通用的模型。为了实现这一点,我通常会绞尽脑汁为我的模型找到合适的超参数,我可以应用哪些不同的正则化技术,或者思考这样一个问题,我是否需要进一步深化我的模型等等。但是我经常忘记使用权重初始化技术。我相信很多像我一样的人也是如此。

等等,重量初始化?这有关系吗?我写这篇文章来寻找这些问题的答案。当我上网寻找这个问题的答案时,关于它的信息铺天盖地。有些文章讨论了这些文章背后的数学原理,有些文章从理论上比较了这种技术,有些文章则更倾向于决定统一初始化更好还是普通初始化更好。在这种情况下,我采用了基于结果的方法。我试图通过一个小实验来找出权重初始化技术的影响。我将这些技术中的一些应用到一个模型中,并试图将训练过程本身可视化,暂时将实现高准确性的目标放在一边。

设置:

模特|作者图片

我创建了一个简单的 CNN 模型,结合了 Conv-2D,最大池,辍学,批量-规范,密集层与 Relu 激活(除了最后一层,这是 Softmax)。我已经为 Cifar-10 数据集的分类任务训练了它。我已经用六种不同的内核初始化方法初始化了模型,并分析了训练阶段。我使用 SGD 优化器,用 30 个时期和 512 个批处理大小来训练模型。本实验中使用的六种初始化方法分别是:

  • 格洛特制服
  • 格洛特正常
  • 何制服
  • 他正常吗
  • 随机制服
  • 随机正态

用于模型构建和训练的代码片段|按作者排序的图像

注意:Keras 层默认的内核初始化方法是 Glorot Uniform。

实验结果:

让我们首先来看看三种不同方法的统一和正常初始化是如何表现的。

不同初始化方法的验证准确性|图片由作者提供

对于前两种方法,使用正常初始化技术的模型的验证准确性曲线几乎遵循统一技术,如果不是始终如此的话。对于 Glorot 方法(第一个情节)后,它采取了缓慢的开始,然后它开始上升。在第十个时期之后,正常和均匀的曲线都显示出非常跳动的行为。但是在过去的几个时期,正常曲线呈下降趋势,而统一曲线的总体趋势是上升的。

对于随机方法(最后一个图),两条曲线的趋势完全不匹配。随机正态的总体验证准确性趋势仍然非常低,低于 40%(除了两个向上的尖峰)。而均匀方法显示出更好的结果。尽管均匀技术的曲线本质上是非常不稳定和跳动的。在第 23 个时期之后,两条曲线都显示了验证准确性的下降。随着 Glorot 方法的趋势,我们在这里也看到一个非常缓慢的启动到第 5 纪元,显示验证精度低至约 10%。对于 Glorot 和随机方法,验证精度曲线没有显示出合适的收敛模式,并且在整个训练过程中保持不稳定。

在这方面,he 方法(中间图)比其他两种方法表现得更好。统一技术和正常技术的曲线是相似的,并且彼此跟随,直到 30 个时期的训练结束。它们都显示出整体上升的趋势,曲线相对来说不那么跳跃。与 Glorot 和 Random 不同,当使用 He 方法时,验证准确性从第一个时期开始上升,而没有表现出缓慢的开始。

现在让我们深入分析这些方法在几个方面的性能。

比较统一技术之间的验证准确性和损失|图片由作者提供

常规技术验证准确性和损失的比较|图片由作者提供

  • 准确度:就准确度而言,使用 Glorot 方法(蓝色曲线)可获得最高的验证准确度。尽管如曲线所示,它未能保持位置,而是表现出非常不稳定的行为。方法(橙色曲线)比其余两种方法更稳定可靠,验证精度与 Glorot 相当。在这些技术中,随机技术,包括统一的和正常的,在整个训练中产生最低的验证准确性。下表将为您提供这些方法行为的总体总结。

准确度对照表|作者图片

  • 趋同:现在的人都在训练非常深度的模型。GPT-3 有 1750 亿个参数要训练,因此更快和更明显的收敛总是一个可取的方面。正如我已经提到的 Glorot 和 Random 方法的曲线非常不稳定和跳动,所以很难推断是否达到了收敛。如果我们分析整体趋势,随机初始化方法表现很差,我们可以说随机正态的训练收敛在 40%左右,而随机均匀的训练在 50%以下。随机曲线至少需要 15-16 个时期才能达到验证准确度的水平。对于 Glorot 均匀和正常初始化,验证精度收敛在 50–60%之间(一些随机峰值超过 60%)。并且在 15 个时代之后,融合趋势开始正式化。增加后的 he 曲线在大约 12 个时期不断越过 50%标记(He 正常曲线更快)。此后,均匀曲线和正常曲线都继续向上,并在 60%左右结束。此外,如果我们查看 he 损耗曲线,Glorot 均匀和随机均匀方法的起始损耗低于 He 均匀方法。这可能是因为 he 初始化方法将权重初始化得偏高。
  • 训练的稳定性和随机性:验证精度对比曲线非常清楚地表明,Glorot 和 Random 方法非常不稳定,因此阻碍了设计者的决策能力,使训练过程提前停止。这是一个非常重要的技巧,可以减少过度拟合,建立一个通用的模型。另一方面,当用均匀或随机方法初始化模型时,验证精度曲线显示出非常稳定和一致的行为。这也给了设计者关于模型的训练过程的信心。设计师可以随心所欲地停在任何想要的位置。为了证明我们的发现是正确的,我们用每种初始化方法对模型进行了五次训练。

作者对统一初始化(多次运行)|图像的验证准确性比较

Glorot Uniform(多轮)|图像的验证准确性比较(由作者提供)

作者对随机均匀(多次运行)|图像的验证准确性比较

这些图清楚地显示了当用 Glorot 和 Random 方法初始化时,训练过程会有多不稳定。随机均匀方法未能显示直到第 5 个时期的任何增量,并且对于 Glorot 均匀直到第 3 个时期的情况是相同的。

  • 一般化:除了准确性,我们作为设计师希望训练一个既一般化又精确的模型,这样他们就能在看不见的数据上表现良好。因此,我们希望我们的模型显示出训练和测试之间的最小差距。

培训与验证(Glorot 制服)|作者图片

培训与验证(随机统一)|作者图片

培训与验证(He 制服)|作者图片

因为以上这些图表明,当用统一方法初始化模型时,训练和测试之间的差距最窄。验证损失和训练损失曲线几乎相互叠加。当用随机均匀技术初始化模型时,差距最大,以高度过度拟合的模型结束

  • 环境:是你没看错。标题是环境。发表在《麻省理工技术评论》上的一篇文章说,“训练一个人工智能模型在其一生中可以排放五辆汽车一样多的碳”。

[## 训练一个人工智能模型在它们的一生中可以排放相当于五辆汽车的碳

人工智能行业经常被比作石油行业:一旦被开采和提炼,数据就像石油一样,可以…

www.technologyreview.com](https://www.technologyreview.com/2019/06/06/239031/training-a-single-ai-model-can-emit-as-much-carbon-as-five-cars-in-their-lifetimes/)

由于人工智能正在塑造人类的未来,另一方面,在训练我们的模型时,我们必须减少通过利用计算机的计算能力来保持世界宜居而产生的碳足迹。由于模型训练是一个循环过程,我们必须寻找快速收敛的技术。查看训练曲线,我们可以看到用这些方法初始化的模型收敛得很快,平滑的训练曲线可以使设计者提前停止。

结论:

当深度学习社区对哪种初始化方法最有效,我们应该使用统一还是正常的方法产生分歧时,这个实验给了我信心,在给定模型的任务设置下,初始化方法在几个方面表现更好。

1)非常稳定和平稳的训练进度

2)快速收敛到期望的验证精度

3)从非常快的历元开始验证精度的不断增加

4)多次运行相似,训练过程中随机性较小

5)与其他相比,明显的收敛和非常小的泛化差距(训练与测试)。

深度神经网络中的权重初始化

原文:https://towardsdatascience.com/weight-initialization-in-deep-neural-networks-268a306540c0?source=collection_archive---------20-----------------------

了解神经网络中不同的权重初始化方法

作者图片

权重和偏差是神经网络的可调参数,在训练阶段,使用梯度下降算法来改变它们,以最小化网络的成本函数。然而,在可以开始训练网络之前,它们必须被初始化,并且这个初始化步骤对网络训练有重要影响。在本文中,我将首先解释权重初始化的重要性,然后讨论可用于此目的的不同方法。

符号

目前 Medium 只支持数字的上标,不支持下标。所以要写变量的名字,我使用这个符号:^后面的每个字符都是上标字符,而 _(和^之前,如果有的话)后面的每个字符都是下标字符。例如

在这个符号中被写成 w_ij^[l。

前馈神经网络

在我们讨论权重初始化方法之前,我们简要回顾一下控制前馈神经网络的方程。关于这些方程的详细讨论,可以参考参考文献[1]。假设您有一个前馈神经网络,如图 1 所示。这里

是网络的输入向量。每个 x_i 都是一个输入特征。网络有 L 层,层 l 中的神经元数量为n[l】*。输入层被认为是零层。所以输入特征的数量是*n[0】。层 l 中神经元 i 的输出或激活a_i^[l】

图 1(作者图片)

l 中神经元 i 的权重可以由向量表示

其中w_ij^[l】代表输入 j (来自 l-1 层神经元 j )进入 l 层神经元 i 的权重(图 2)。

图 2(作者图片)

在层 l 中,每个神经元接收前一层中所有神经元的输出乘以其权重, w_i1w_i2 ,。。。, w_in 。加权输入被加在一起,一个被称为偏差(b_i^[l】)的常数值被加到它们上,以产生神经元的净输入

l 中神经元的净输入可以由向量表示

类似地,层 l 中神经元的激活可以由激活向量表示

所以情商。3 可以写成

其中求和已经被权重和激活向量的内积所代替。然后,净输入通过激活函数 g 产生神经元 i 的输出或激活

我们通常假设输入层是零层

所以对于第一层,Eq。7 写为

我们可以将一个层的所有权重组合成该层的权重矩阵

所以w【^[l】是一个 n[1] × n^[l-1 矩阵,这个矩阵的( i,j )元素给出了从层 l-1 中的神经元 j 到层 l 中的神经元 i 的连接的权重。我们还可以为每一层设置一个偏置向量

现在我们可以写 Eq 了。6 以矢量化的形式

并利用 Eq。7 我们得到

我们通常用 yhat 来表示输出层的激活

以及向量 y 来表示输入向量的实际标签(等式)。1).对于二元分类 y 只有一个元素,可以认为是标量。但是对于多类和多标签分类,它是一个一热或多热编码向量(参考[1]了解更多细节)。在反向传播过程中,我们首先计算最后一层神经元 i误差。误差定义为损失函数相对于净输入的偏导数

误差是该神经元改变整个网络的损失函数的效果的量度。然后我们用这个误差项来计算前一层神经元的误差

这样,我们使用前一层的误差项来计算每一层的误差项,直到我们到达第一层。我们可以使用每层的误差项来计算该层中损失函数相对于权重和偏差的梯度

并且使用它们,我们可以为梯度下降的下一步更新权重和梯度的值

其中 J 是网络的成本函数。权重和偏差被更新,直到它们收敛到最小化成本函数的最优值。

随机权重初始化的重要性

我们可以用于权重初始化的最简单的方法是为所有权重分配一个常数。例如,我们可以将所有权重初始化为零。然而,事实证明这是一个坏主意。让我更详细地解释一下。假设我们有一个神经网络(称为网络 A ),有 L 层,每层有n[l】*个神经元。现在,对于网络的每一层,我们用恒定值*ω[l】初始化权重矩阵,用恒定值β^[l】初始化偏置向量。所以在层 l 中我们有

对于 ij 的所有值。请注意,两个不同的层可以有不同的值ω[l】*和*β[l】。如果我们用等式初始化权重和偏差。21,则可以证明在梯度下降的每一步中,每一层中的权重和偏差都是相同的(证明在附录中给出)。所以我们可以假设,在一个数据集上训练网络 A 之后,它的权重和偏差收敛到ω_f^[l】β_f[2].所以在每一层中,的权重和的偏差对所有的神经元都是一样的。

现在假设我们有第二个网络(称为网络 B ,层数相同,它每层只有一个神经元。为了能够比较网络 AB ,我们使用上标 < B > 来表示属于网络 B 的数量。两个网络如图 3 所示。

图 3(作者图片)

在每一层,两个网络具有相同的激活函数,并且它们也具有相同的输入特征,所以

我们用β^[l】初始化所有的偏置值(来自等式。21).对于第一层,我们初始化权重矩阵(等式)。10)具有相同值的网络 A

由于我们只有一个神经元和n[0】<b>*输入特征,权重矩阵确实是一个行向量。这个矩阵的每个元素都是常量值*ω_f[1】。对于接下来的层,我们将权重矩阵定义为

其中n^[l】是网络 Al 层神经元的数量。由于我们只有一个神经元,每层只有一个输入 l≥1 ,权重矩阵只有一个元素,这个元素就是ω_f[l】n[l】。因此,对于网络 B 中的每一层 l≥1 ,我们用网络 A 的权重乘以网络 A 的同一层中的神经元数量来初始化权重矩阵。现在我们可以很容易地证明(证明在附录中给出)网络 B 等价于网络 A ,这意味着对于相同的输入向量,它们在梯度下降期间和收敛后产生相同的输出。

因此,通过使用这种对称权重初始化,网络 A 表现得像具有有限学习能力的网络 B 一样,然而,计算成本保持不变。用相同的值初始化网络的所有权重和偏差是导致相同问题的这种方法的特例。最坏的情况是我们用零初始化所有的权重。在这种情况下,根据等式。16,除了最后一层,所有层的误差项将为零,因此损失函数的梯度也将为零(等式)。第 19 和 20 段)。因此,这些层中的权重和偏差不会更新,网络根本无法训练。

神经网络可以被认为是具有两个元素的矩阵。它有一个深度即层数,一个宽度即每层的神经元数(为了简单起见,假设所有层的神经元数相同)。在所有层中使用线性激活函数缩小了网络的深度,因此它的行为类似于只有一层的网络(证明在[1]中给出)。使用对称权重和偏差初始化将缩小网络的宽度,因此它的行为就像一个每层只有一个神经元的网络(图 4)。

图 4(作者图片)

因此,为了打破对称性,权重或偏差都不应该以这种方式初始化。在实践中,我们对权重使用随机初始化,并用零或一个小数字初始化所有偏差。为此目的选择权重,因为它们适当的随机初始化不仅破坏了对称性,而且有助于解决下一节讨论的消失和爆炸梯度问题。

消失和爆炸渐变

使用反向传播方程(方程。15 和 16),我们可以计算网络中任何一层的误差项。假设我们想为层 l 计算它。我们首先计算输出层的误差项,然后向后移动并计算先前层的误差项,直到我们到达层 l 。可以看出,层 l 的误差项为

这个方程的推导可以参考[1]。基于这个等式,误差向量的每个元素(该层中一个神经元的误差)与下一层中神经元的权重的链式乘积成比例。现在,如果权重是小数字,这些权重的链式乘法可以产生极小的误差项,特别是如果您有一个有这么多层的深度网络。因此,误差向量的一些或所有元素将会非常小。

根据方程式。如图 17 和 18 所示,损失函数和成本函数的梯度与误差项成比例,因此它们也将变成非常小的数,这导致梯度下降中的权重和偏差更新的步长非常小(等式 1 和 2)。第 19 和 20 段)。最终结果是梯度下降法和网络的学习过程变慢。这被称为消失梯度问题

也有可能权重是非常大的数字。然后,这些的链式相乘就变成了一个非常大的数,梯度下降中的梯度和步长可以爆炸。结果是不稳定的网络,并且梯度下降步骤不能收敛到权重和偏差的最佳值,因为步骤现在太大并且错过了最佳点。这被称为爆炸梯度问题。我们可以使用权重初始化技术来解决这些问题。

均值和方差规则

在讨论初始化方法之前,我们需要回顾一下均值和方差的一些性质。我们用E【X】表示随机变量 X 的均值,用 Var(X) 表示其方差。如果 X_1,X_2,.。。,X_n 为有限均值的独立随机变量,若 a_1a_2 ,。。。、 a_nb 为任意常数,则

另外,如果 XY 是两个独立的随机变量,那么我们有

方差也可以用平均值来表示。如果我们有一个随机变量 X,那么

随机初始化方法

将在下一节中介绍的初始化方法是基于随机权重初始化来打破对称性的。然而,由于权重不再对称,我们可以安全地用相同的值初始化所有的偏差值。所以在所有这些方法中,偏置值初始化为零。初始化方法基于一些假设,这些假设将在下一节讨论。

假设

1-我们假设每一层的权重是独立且同分布的(IID)。它们被初始化为均匀或正态分布,平均值为 0,方差为var(w^[l】)

每层中的权重独立于其他层中的权重。

2-特征输入也被假设为独立且同分布(IID)。特征输入与权重无关。此外,它们是规范化的,所以

我们还需要对激活函数做一个假设。我们有两种类型的激活函数。在 z =0 处可微的(像 sigmoid)和不可微的(像 ReLU)。如果激活函数在 z =0 处可微,那么当 z 较小时,我们可以用 Maclaurin 级数来逼近它。函数的 Maclaurin 级数被定义为

x 接近零时,其可用于计算 f(x) 的近似值。 tanh 的 Maclaurin 系列是

z 接近零时,我们可以忽略 z 的较大幂并写入

乙状结肠的马克劳林级数是

对于小的 z 值,我们可以写为

因此,当 z 接近零时,sigmoid 和 tanh 可以用一个线性函数来近似,我们说我们处于这些函数的线性区域。由于我们假设输入特征是归一化的,它们的值在第一次迭代中相对较小,并且如果我们用较小的数字初始化权重,则神经元的净输入(【z_i^[l】)最初将较小。所以我们假设:

3-激活函数在第一次迭代时处于线性状态。

现在基于这些假设我们可以得出一些结论:

1-在梯度下降的第一次迭代期间,每层中神经元的权重和前一层中神经元的激活是相互独立的。此外,在每一层中,所有激活都是独立的。

基于等式。我们有 3,7 和 9

假设偏差为零。因此【a_k[l-1】*可以从前一层的激活开始递归计算,直到我们到达第一层,并且*【a_i[l】是输入特征和层 1 到层 l 的权重的非线性函数

由于每层中的权重是独立的,并且它们也独立于 x_j 和其他层的权重,因此它们也将独立于等式中的权重和 x_j (f 的函数。42 ) 。因此【a_i^[l-1】对于 i,p,k,l 的所有值都是独立的。

此外,由于所有的权重是独立的,并且输入特征也是独立的,所以它们的功能( f(w_kp^[m】,x_j) )也是独立的。因此在层 l-1 中,所有的a_i^[l-1】都是独立的,这意味着在每一层中,所有的激活都是独立的。当然,如果我们有 softmax 激活函数,那么输出层就不是这样了。Softmax 定义为

softmax 激活函数中每个神经元的输出是其他神经元输出的函数,因为它们的总和应该是 1。然而,由于 z 的值在第一次迭代中很小,我们可以写成

因此,softmax 函数的输出对于所有神经元大致相同,并且只是输出层中神经元数量的函数。因此,我们可以假设激活仍然不依赖于彼此或该层的权重。

2-在第一次迭代中,每一层的净输入的平均值为零。

使用等式。6、26 和 28 以及权重和激活在第一次迭代中相互独立的事实,我们可以写

基于第一个假设,权重的平均值为零(等式)。31).所以对于 l 的所有值 T21,我们有

同样,我们可以使用 Eq。6、27 和 29 来写

使用等式。31 和 32,前面的等式可以简化

LeCun 重量初始化

该方法最早由 LeCun 等人提出[2]。如前所述,我们希望在反向传播过程中防止梯度的消失或爆炸。所以我们不应该允许 Eq 中的错误。25 消失或爆炸。每层中的误差是输出层误差的函数(【δ^[l】)。另一方面,输出层的误差是输出层激活的函数(等式)。15).因此,如果在正向传播过程中,激活消失或爆炸,同样的事情会发生在错误上。因此,在正向传播过程中,我们应该防止每一层中激活的爆炸或消失。方差代表数据围绕其均值的分布,因此如果层 l 中激活的均值和方差大致等于层 l-1 的均值和方差,那么这意味着激活不会从层 l-1 传播到层 l 而消失或爆炸。所以对于所有的值,I 和 j 应该有两个条件

**

对于 l =1,前一层的激活是输入特征(等式。8),并且它们的方差等于 1(等式。34).因此,前面的等式可以写成

这个 LeCun 方法只对在 z =0 处可微的激活函数有效。它最初是针对 tanh 激活函数推导出来的,但也可以扩展到乙状结肠。

Tanh 激活功能

对于 tanh,我们可以使用等式。37 和 48 来写

使用等式。37,46 和 49 我们得到:

这个等式适用于所有的 l 值。所以等式中的条件。49,并且激活的平均值在不同层中不变。通过替换等式。53 进 Eq。52,并利用层中所有激活的方差相同的事实(等式。51),我们得到

现在来满足 Eq 的条件。51 我们应该有

这是 LeCun 初始化公式。如果我们假设权重具有正态分布,那么我们需要从均值为零且方差为1/n^[l-1】的正态分布中选择权重。我们也可以对权重使用均匀分布。如果我们在区间[ a,b ]上有一个均匀分布,它的平均值将是

它的方差是

所以如果我们从区间上的均匀分布中选择每一层的权重

其平均值将为零,其方差将与等式中给出的方差相同。55.

Xavier 权重初始化

Lecun 方法只考虑输入信号的正向传播。我们也可以把前面的讨论扩展到反向传播。基于此,Xavier Glorot 等人[3]提出了包括信号反向传播的另一种方法。

反向传播

输出层中每个神经元的误差由等式给出。15.所以【δ^[l】是输出层激活的函数(yhat)和标签向量( y )。我们已经表明,在每一层中,所有的激活都是独立的。对于二元分类 y 只有一个元素(在那种情况下是标量 y)。对于多类和多标签分类,它要么是一个热码,要么是多个热码的编码向量,显然,所有的元素都是相互独立的。所以输出层中神经元的误差是一些独立变量的函数,它们将是相互独立的。对于等式中的 tanh 。37,我们得到

把这个等式代入等式。我们有 16 个

因此δ_i^[l】可以从下一层的误差递归计算,直到我们到达输出层,并且它是输出层的误差和层 l+1L 的权重的线性函数

我们已经知道层l(【w_ik[l】*)的所有权重都是独立的。输出层的误差是独立的。权重和误差不是完全独立的。因为误差取决于输出层的激活,输出层可以写成网络权重的函数(等式)。42).然而,每个权重*w_pk[l】仅被使用一次来产生层 l 中神经元 p 的激活。由于我们有这么多层,通常每层有这么多神经元,单个权重对输出层的激活和错误的影响可以忽略不计,因此我们可以假设输出层中的每个激活都独立于网络中的每个权重。

因此,我们也可以假设每层中的误差与该层的权重无关。现在利用这个假设和等式。我们有 26、28 和 57 个

现在我们可以使用这个等式和方程。27、29、31 和 32 来写

基于这个等式δ_i^[l】不是 i 的函数,这意味着每层中所有误差的方差是相同的

所以我们可以简化 Eq。60 和写

类似于正向传播,误差的平均值对于所有层都是相同的(等式)。59),我们希望方差保持不变。所以从情商来说。62,我们得到

正如您在反向传播中看到的,每层中权重的方差等于该层中神经元数量的倒数,然而,在前向传播中,则等于前一层中神经元数量的倒数。为了解决这一冲突,我们可以从均值为零且方差为的正态分布中选取每个图层的权重

这个方差是方程中给出的方差的调和平均值。55 和 63。这是 Xavier 初始化公式。我们也可以对权重使用均匀分布。所以如果我们从区间上的均匀分布中选择每一层的权重

其平均值将为零,其方差将与等式中给出的方差相同。64.

sigmoid 激活函数的 Kumar 初始化

Kumar [4]研究了神经网络中的权重初始化。他对任意可微的激活函数提出了一种通用的权重初始化策略,并用它来导出 sigmoid 激活函数的初始化参数。这里我们不打算讨论他的方法。相反,我们扩展了 Xavier 方法,将其用于 sigmoid 激活函数。我们可以用等式。27、39 和 48 来写

使用等式。我们得到 26,39 和 46

通过替换等式。66 入 Eq。并利用层中所有激活的方差相同的事实(等式)。50),我们得到

但是我们知道每一层中激活的方差是 1(等式。51),所以我们可以简化前面的等式

这是 Kumar 得到的结果,他认为没有必要为反向传播过程中激活的变化设置另一个约束。因此,您可以根据等式中给出的方差从正态或均匀分布中选择权重。68.然而,我们也可以研究反向传播。对于反向传播,我们首先需要计算误差的平均值。来自 Eq。我们有 39 个

误差的平均值是

他们的方差是

所以为了保持不同层的方差相同,我们应该

如果我们假设权重具有正态分布,则它具有零均值,并且它的方差可以从等式的调和均值中得到。68 和 72。

权重初始化

该方法最早由何等人提出[5]。如果我们有一个在 z =0 处不可微的激活函数(像 ReLU),那么我们不能用 Maclaurin 级数来近似它。因此,Xavier 方法不能再用了,我们应该使用不同的方法。

ReLU 激活功能

ReLU 是广泛使用的非线性激活函数,定义为

它在 z=0 处不可微,我们通常假设它的导数在这一点上是 0 或 1,以便能够进行反向传播。然而,当 z 接近零时,我们不能使用 Maclaurin 级数来近似它。来自 Eq。我们有 49 个

对于 l 的所有值。为了使用 he 初始化方法,我们从等式开始。48,我们用等式。30、51 和 74 来简化它

基于情商。75, z_i[3] 的方差对于层 l 中的所有神经元是相同的。所以我们可以写作

回想一下,我们假设权重具有均值为零的均匀或正态分布。所以它们应该在零附近对称分布。我们知道这一点

所以 z_i[4]可以被认为是权重的线性组合。我们也知道它的均值为零(等式。46),所以也应该在零附近有对称分布。因此,它的分布是一个均匀的函数。现在我们可以写了

因为被积函数是一个偶数函数。基于 ReLU 激活的定义(等式)。73),我们有

所以用等式。我们有 77 和 78

现在我们可以用 Eq 了。30 和写作

所以用等式。我们得到 74 和 76

通过替换等式。81 成情商。我们有 75 个

为了防止正向传播过程中每层激活的爆炸或消失,我们应该确保网络输入不爆炸或消失,因此层 l 的网络输入的方差应该大致等于层 l-1 的方差。因此,根据前面的等式,我们得出结论

反向传播

如前所述,虽然 ReLU 在 z =0 处不可微,但我们假设它在这一点的导数为零或一(这里我们假设它是一)。所以 ReLU 的导数是

因为 g'(z)的一半值是 1,另一半是 0,所以它的平均值将是

并且g’(z)的每个值与其平均值的距离将是 0.5。所以我们可以写作

g'(z_i^l)z_i^l 的函数,δ_z_i[l】*的依赖性很弱,所以我们可以假设*g'(z_il)δ_k^[l+1】*是独立的。此外, g'(z_i^l) 与层 l+1 中的权重无关。因此我们可以写*

基于等式。16 和 29 我们可以写

正如我们针对 Xavier 方法所展示的,单个权重对输出层的激活和错误的影响可以忽略不计,因此我们可以假设输出层中的每个激活都独立于网络中的每个权重。因此

以及 Eq 右边的最后一项。88 变成零。通过将g’(z)的平均值和方差代入等式。88 我们得到

现在我们可以使用 Eqs。29、31、32 和 87 来简化它

这个等式的右边不依赖于 i ,所以层 l 中所有误差的方差是相同的,并且这对于所有其他层也是成立的。所以,我们可以写

与 Xavier 方法类似,所有层的误差均值都是相同的,我们希望其方差保持不变。所以从情商来说。91,我们得到

这种方差可以表示为等式 2 中给出的方差的调和平均值。83 和 92

因此,我们可以从均值为零、方差为 Eq 的正态分布中选取权重。93.

本文中讨论的权重初始化方法对于训练神经网络非常有用。权重初始化方法可以打破对称性,并解决消失和爆炸梯度问题。对称权重初始化会缩小网络的宽度并限制其学习能力。用零初始化权重,不允许权重和偏差被更新。

权重初始化技术基于随机初始化。权重从正态或均匀分布中选取。该分布的平均值为零,并且仔细选择其方差以防止在梯度下降的第一次迭代期间权重的消失或爆炸。当激活函数可微时,LeCun 和 Xavier 方法是有用的。然而,今天大多数深度神经网络使用类似 ReLU 的不可微激活函数。对于这样的激活函数,我们应该使用 he 初始化方法。

权重初始化是训练深度神经网络的必要部分。然而,重要的是要注意,他们不能完全消除消失或爆炸梯度问题。权重初始化方法只能在梯度下降的第一次迭代期间控制权重的方差。权重将在下一次迭代中改变,并且它们仍然可以在以后变得太小或太大。然而,正确的权重初始化可以延迟这个问题,使其稍后发生。通过在第一次迭代期间控制权重的方差,网络可以在权重消失或爆炸之前进行更多次迭代,因此它具有更高的收敛机会。

参考

[1] Bagheri,r .,深度前馈神经网络简介,https://towards data science . com/An-Introduction-to-Deep-forfeed-Neural-Networks-1af 281 e 306 CD

[2] LeCun Y.A .,Bottou L .,Orr G.B .,Müller KR .高效的反向投影。在:蒙塔冯 g,奥尔 G.B .,米勒 KR。神经网络:商业诀窍。计算机科学讲义,第 7700 卷。斯普林格(2012)。

[3] Glorot,x .,Bengio,y .:理解训练深度前馈神经网络的难度。载于:第十三届人工智能和统计国际会议论文集,第 249-256 页(2010 年)。

[4] Kumar,S.K .:关于深度神经网络中的权重初始化。预印于 arXiv:1704.08863 (2017)。

[5],何,,,任,.深入研究整流器:在 imagenet 分类上超越人类水平的性能。IEEE 计算机视觉国际会议论文集,第 1026–1034 页(2015)。

附录

用恒定值初始化权重

我们首先从网络 A 开始,使用等式计算层 l 的净输入。12(回想一下,所有的权重都是用ω^[l】初始化的):

因此

这意味着层 l 中所有神经元的净输入是相同的,并且我们可以假设它等于z[l】*(*z[l】没有索引,因为它对于所有元素都是相同的,然而,它对于每一层仍然可以是不同的数目)。此外,这一层中所有神经元的激活将是相同的

并且我们假设它等于a^[l】。类似地,所有其它层中神经元的净输入和激活将是相同的。对于第一层,我们可以用 Eq。8 并写出等式。A2 组件

但是对于其他层,我们可以使用 Eq。A2 并将其写成

现在,如果我们在输出层只有一个具有 sigmoid 激活函数的神经元,并使用二进制交叉熵损失函数,等式。15 转变成

这个方程的推导可以参考[1]。由于我们在输出层中只有一个神经元,因此前面等式中的变量没有索引。现在情商。16 可以写成

由于我们在输出层只有一个神经元, k 可以只有 1。此外,对所有神经元都是一样的,所以我们可以简化 Eq。A7 并将其写成

因此层 L-1 的误差向量的所有元素等于δ^[l-1】。对于层 l ,我们可以写成**

因为层 l+1 的所有误差项、所有权重以及层 l 的所有净输入都是相同的。因此层 l 的所有神经元的误差项将相等。使用 Eq。18 我们可以写

因此损失函数相对于偏置的梯度对于层 l 中的所有神经元将是相同的。最后用 Eq。17 我们可以写

这意味着层 l 中所有神经元的损失函数相对于权重的梯度是相同的。结果,当我们更新等式中层 l 的权重和偏差值时。如图 19 和 20 所示,初始值和梯度对于所有神经元都是相同的,并且在梯度下降的每一步,更新的值都是相等的

****

因此,我们最终得到一个网络,其中每一层的权重和偏差都是相同的。在这种初始化方法中,我们对每一层中的所有神经元都有一个对称的行为,它们将一直有相同的输入和输出。

现在假设网络 A 已经使用梯度下降在数据集上训练,并且它的权重和偏差已经收敛到ω_f[l】*和*β_f[l】,这对于每层中的所有神经元都是相同的。假设我们有第二个网络(称为网络 B ),层数相同,它每层只有一个神经元(图 3)。为了能够比较网络 AB ,我们使用上标B>来表示属于网络 B 的数量。

在每一层,两个网络具有相同的激活函数,并且它们也具有相同的输入特征,所以

我们在每一层用β^[l】*初始化网络 B 的所有偏置值(来自等式。21).对于网络的第一层 B ,我们初始化权重矩阵(等式。10)具有相同值的网络 A*

由于我们只有一个神经元和n[0】*输入特征,权重矩阵确实是一个行向量。这个矩阵的每个元素都是常数*ω_f[1】。对于网络的下一层 B ,我们将权重矩阵定义为

其中n^[l】是网络 Al 层神经元的数量。在网络 B 中,我们只有一个神经元,每层只有一个输入 l≥1 ,所以权重矩阵只有一个元素,这个元素就是ω_f[l]n[l】。因此,对于网络 B 中的每一层 l≥1 ,我们用网络 A 的权重乘以该层中网络 A 的神经元数量来初始化权重矩阵。

现在我们可以很容易地证明网络 B 等价于网络 A 这意味着对于相同的输入向量,它们产生相同的输出。对于网络 B,我们可以使用等式。6、8 和 A14 来写

使用等式。A4 和 A5,网络 A 收敛后的净输入为

**

因此,网络 A 中第 1 层的每个神经元的净输入等于网络 b 中同一层的单个神经元的净输入。由于它们共享相同的激活函数,它们的激活也将相等

我们可以用等式。3 和 A16,以获得网络 B 中其他层的网络输入

对于第二层,我们可以使用等式。A20 和 A21 到达

这与网络第二层 A 中神经元的净输入相同(等式。A18)。所以我们得到了

同样,我们可以证明网络 B 每层中单个神经元的净输入和激活等于网络同一层神经元的净输入和激活。所以我们有

因此,通过使用这种对称权重初始化,网络 A 的行为类似于具有有限学习能力的网络 B ,然而,计算成本保持不变(图 3)。

加权 K 均值聚类示例-人造国家

原文:https://towardsdatascience.com/weighted-k-means-clustering-example-artificial-countries-f91c541827fe?source=collection_archive---------31-----------------------

应用于世界人口地图的加权 K 均值聚类示例,看看会发生什么。

图一。世界人口密度图。为了可视性,我们对每个像素取对数。

介绍

WKMC 算法可以应用的领域之一是人口统计学。想象一下这样一种情况,如果所有的行政区划或历史冲突都消失了,或者种族、民族或部落身份不再重要,你希望看到人们如何分组或愿意分组?那么人们如何着手创建社区呢?

在本帖中,我们将使用 WKMC 算法来找出人们如何根据他们目前的地理分布来分组。为此,我们将关注两个参数:

  • 地理坐标,
  • 特定位置的人口密度。

由于这是一个好奇心驱动的模拟,这是一个具有纯粹假设性质的极大简化。该模拟没有考虑自然资源或地形障碍等会阻碍人们定居的条件。然而南极洲是唯一的例外。我们将它排除在外,因为它是地图的一大部分,对于算法来说太大而无法忽略,但几乎完全可以居住。

数据集

我们将使用美国宇航局的人口密度数据集。该网站提供了四个版本的数据集,有不同的分辨率,非常适合实验。

图一。世界人口密度图。为了可视性,我们对每个像素取对数。

该数据集有四种不同的分辨率版本。当然,最高分辨率的分辨率会给出最好的结果,尽管必要的计算可能会成为一个问题。要获取数据集,请执行:

mkdir dataset
wget -O dataset/world.csv "https://neo.sci.gsfc.nasa.giv/servlet/RenderData?si=875430&cs=rgb&format=CSV&width=360&height=180"

然后:

import pandas as pd

df = pd.read_csv('./dataset/world.csv', header=-1)
df = df.replace(df.max().max(), 0)
df = df.loc[10:145, :]
df = df.reset_index()
df = df.drop(columns=['index'])
df.columns = range(df.shape[1])

对于这个数据集,地理经度纬度被简单地表示为整数,并被视为一个矩阵的 (x,y) 索引,地图具有圆柱表示。同时,这个矩阵的每一个元素都代表了居住在特定区域的人口密度。

海洋被标记为99999.0,这是不自然的,因此我们将其置零。稍后,我们移除北冰洋(只是为了稍微加快计算速度)和南极洲的“狭长地带”,正如前面示意的那样。然后,我们重新枚举行和列的索引,使它们从零开始计数。

特征工程

在我们继续之前,我们需要对我们的数据集进行一点转换,以适应聚类问题。首先,我们需要将数据集的表示从一个人口密度矩阵改为一个经度和纬度坐标点的列表,以便 WKMC 能够计算距离。但是,我们还需要保留人口密度值,我们和机器都可以将其解释为每个数据点的权重。换句话说,与农村地区或沙漠相比,大城市等大型居住区更倾向于将最近的点拉入聚类。

latitude_idx = df.index.to_numpy()
longitude_idx = df.columns.to_numpy()

lat_max = len(latitude_idx)
lon_max = len(longitude_idx)

x0 = latitude_idx.repeat(lon_max)
x1 = np.tile(longitude_idx, lat_max)
x  = df.to_numpy()

dd = pd.DataFrame({
    'x0':     x0,
    'x1':     x1,
    'weight': x.flatten()
})

首先,我们从 dataframe 对象中提取纬度经度。然后,我们重复纬度和纬度值,以便它们形成沿着某个新索引排序的唯一对。我们还转储所有的权重并将它们展平为一个系列,我们将其加入到一个新的数据帧中,这样我们就可以保留引用。

世界是圆的…

我们知道现在人们倾向于把所有事情都放在一起讨论,但是不……地球还在转。这里我们有一个圆柱表示的地图,这个地图有一个重要的结果:地图的左右两边连在一起。因此,确保我们的算法不会将靠近两条边的两个点视为非常分离是至关重要的。

因为 skearn API 不允许我们轻易覆盖距离度量,所以我们必须对数据集进行不同的参数化:

dd['latitude']      = (x0 / x0.max() - 0.5) * 2.0
dd['longitude_sin'] = np.sin((x1 / x1.max()) * np.pi * 2.0)
dd['longitude_cos'] = np.cos((x1 / x1.max()) * np.pi * 2.0)

经度是循环的维度,如果我们把它换算成一个区间[0:2.0*np.pi],它就会变成纵向角度。问题是 1 和 360 度之差是 360 度,而距离应该等于 1 度。所以我们可以把这个维度分解成两个特征,分别用正弦和余弦。

这里的纬度不应该是循环的。但是,如果我们查看刚刚定义的与经度相关的特征,我们可以看到沿这些轴出现的最大值是 2。因此,为了在缩放纬度时补偿它,我们需要确保沿它的最大距离也是 2。

因为我们的 dataframe dd保存了所有的引用,所以我们可以简单地向其中添加新的特性,就像我们刚刚做的那样。

解决办法

现在,我们的特征矩阵X可以通过参考通过纬度经度的正弦/余弦投影的所有点来构建。同时,我们把人口密度作为权重。然而,在此之前,我们移除所有权重严格为零的点。由于我们的飞机表面大约 70%是水,这可以大大减少所需的计算。

N_CLUSTERS = 195

dd = dd[dd['weight'] != 0.0]

dd = dd.reset_index()
dd = dd.drop(columns=['index'])

X = dd[['latitude', 'longitude_sin', 'longitude_cos']].to_numpy()
weights = dd['weight'].to_numpy()

dd['cluster'] = KMeans(n_clusters=N_CLUSTERS).fit_predict(X,
    sample_weight=weights)

195 这个数字不是偶然的。目前,我们有 195 个地区被认定为国家。我们可以用这个数字作为新世界的参考。

解决了 WKMC 问题后,我们需要“重组”旧坐标的解决方案,这相当容易,因为我们保留了对原始索引的引用。

XX = -1 * np.ones((lat_max, lon_max))
for i in range(len(dd)):
        u, v = dd['x0'].iloc[0], dd['x1'].ilox[i]
        cluster_id = dd['cluster'].iloc[i]
        XX[u, v] = cluster_id

现在,让我们画出结果。我们将用新的“国家”覆盖原始人口密度图。(请注意,np.where功能仅用于增强绘图。)

fig, ax = plt.subplots(1, 1, figsize=(24, 24))
ax.imshow(np.where(XX == -1, np.NaN, XX), 
    cmap='Spectral', 
    alpha=0.75)
ax.imshow(df.apply(lambda x: np.log(x)), alpha=0.25, cmap='gray')
ax.contour(longitude_idx, latitude_idx, 
    np.where(XX == -1, -10, XX), 
    levels=N_CLUSTERS, 
    linewidths=0.1, 
    alpha=0.5, 
    colors='k')
plt.show()

通过 K-Means 聚类算法定义的 195 个国家的世界。

讨论

我们终于聚集了人口。观察 WKMC 算法假设的结果是有用的。

首先,因为我们已经移除了零权重的点,所以没有聚类的标签被分配给这些点。然而,人口密度越大,集群就越集中。这在印度和中国这两个世界上人口最稠密的地区尤为明显。西伯利亚和加拿大北部、格陵兰岛、撒哈拉和澳大利亚形成较大的星团。

其次,通过缩放特征(记住,所有特征都在[-1, 1]范围内),集群在任何方向都不会表现出各向异性。换句话说,如果例如 x 轴具有 5 倍的范围,我们将期望它的影响更强,因此集群将被垂直拉长。

最后,通过确保东西轴的连续性,我们的集群不会因为边界条件的存在而失真。

结论

我们已经看到了 K-Means 聚类算法是如何在我们的假设世界中投入使用的。然而,刚刚演示的用法实际上非常传统,可以应用于类似的情况,在处理较小的地图时会产生特别好的效果。该算法有助于发现存在的相似性,而不管行政区划如何。

还会有更多…

我计划把文章带到下一个层次,并提供简短的视频教程。

如果您想了解关于视频和未来文章的更新,订阅我的 简讯 。你也可以通过填写表格让我知道你的期望。回头见!

原载于https://zerowithdot.com

不平衡数据集的加权 Logistic 回归

原文:https://towardsdatascience.com/weighted-logistic-regression-for-imbalanced-dataset-9a5cd88e68b?source=collection_archive---------0-----------------------

数据集中标签的不平衡分布

在数据科学中,分类是将事物或样本分配到相同类型的类或类别中的任务。在机器学习中,分类是一种监督学习,其中每个样本点或实例都与一个目标相关联,该目标称为类或类别,或简称为标签。一个基本的例子是将一个人分类为男性或女性,或者将一封电子邮件分类为“垃圾邮件”或“非垃圾邮件”,或者将一笔金融交易分类为“欺诈”或“非欺诈”。

用外行人的话来说,分类算法是将事物或样本排列成类或类别的基本认知过程。在机器学习中使用分类算法是一个两步过程。在称为训练或拟合的第一步中,分类算法使用标签数据集(也称为训练数据集)来获得每个标签的边界条件。在这个训练过程中,识别分类器的基本权重或函数,以给出最准确和最好的标签分离。在称为预测的第二步中,每个样本/数据点或实例被馈送到算法中以预测目标标签,即算法将标签分配给输入样本/数据点。

在机器学习中,有许多分类算法可用,如逻辑回归、决策树、SVM、朴素贝叶斯、KNN 等。每种算法都有不同的底层逻辑/过程,并有自己的优缺点和用例。此外,在现实世界中,分类问题可以有两个以上的标签,例如花卉种类分类、水果分类、物体分类等。许多分类算法能够或能够在这样的多类/标签数据集上工作。

不平衡数据集

不平衡数据集是一种数据集,其中标签在数据集上的分布不平衡,即分布有偏差或偏斜。具有更多数据点/样本的组被称为多数类,而具有较少数据点的组被称为少数类。数据集中的分布可能有轻微不平衡或高度不平衡。完全均等的分布是非常罕见的,尽管大多数时候分布稍微偏向一个阶层。

在这种情况下,分布是高度倾斜的,以至于对于数百、数千或数百万多数类的数据点,可能有一个少数类的数据点。一些实际的场景是:

  • 信用卡欺诈交易(欺诈交易在所有金融交易中非常少)
  • 电子邮件的垃圾邮件分类(与普通电子邮件相比,垃圾邮件非常少)
  • 机器故障(机器发生故障的情况很少)
  • 保险索赔预测。
  • 员工流失率(通常员工流失率最高为 20%)

在这种情况下,少数类比多数类更重要,分类器的目的是有效地将少数类从多数类中分类出来,例如从所有交易中识别欺诈交易。这种高度不均衡分布对类别预测提出了挑战。原因是大多数分类器被设计或具有默认值,假设每个标签的分布相等。轻微的不平衡不构成任何挑战,可以像正常的分类问题一样对待。

使用准确度分数作为这种高度不平衡的数据集的评估度量不是分类器性能的良好度量。例如,如果多数类与少数类的分布是 95:1,那么将所有数据点标记为多数类将得到 95%的准确性,这在预测建模中是非常好的分数。但是在这种情况下,分类器算法没有学习到关于手边问题的任何东西,即少数类,例如欺诈交易、垃圾邮件等。在某些情况下,如欺诈交易,阶级分布的不平衡可能高达 99%。

在这种情况下,ROC-AUC 曲线等评估指标是分类器性能的良好指标。这是一个衡量模型区分不同类别能力的标准。ROC-AUC 分数越高,模型预测 0 为 0 和 1 为 1 的能力越强。提醒一下,ROC 是概率曲线,AUC 代表可分性的程度或度量。除了这个指标,我们还将在构建分类器时检查召回分数、假阳性(FP)和假阴性(FN)分数。

在本文中,我将坚持只在不平衡 2 标签数据集上使用逻辑回归,即用于不平衡二元分类的逻辑回归。尽管基本方法可以应用于多标签/类数据集。我已经创建了一个包含两个类的人工不平衡数据集。对于每 99 个多数类样本,数据集具有 1 个少数类样本。因此,每 100 个数据点中,少数群体只有一个样本,而且分布高度偏向多数群体。

# basic libraries
import pandas as pd
import numpy as np
from matplotlib import pyplot as plt
%matplotlib inline
import seaborn as sns
from sklearn.datasets import make_blobs, make_classification# create a imbalanced dataset of 10K with 2 class
x,y = make_classification(n_samples=10000  # number of samples
                          ,n_features=2    # feature/label count
                          ,n_informative=2 # informative features
                          ,n_redundant=0   # redundant features
                          ,n_repeated=0    # duplicate features
                          ,n_clusters_per_class=1  # number of clusters per class; clusters during plotting
                          ,weights=[0.99]   # proportions of samples assigned to each class
                          ,flip_y=0         # fraction of samples whose class is assigned randomly. 
                          ,random_state=13 )# club together into a dataframe
df = pd.DataFrame(x,columns=['x1','x2'])
df['y'] = y

生成数据集后,让我们检查数据以确认分布是否不平衡。

# check the distribution
df[‘y’].value_counts()/df.shape[0]

输出:

0    0.99
1    0.01
Name: y, dtype: float64

让我们用不同的颜色为每个类绘制分布图。

# scatter plot
plt.figure(figsize=(10,5))
sns.scatterplot(data=df,x=’x1',y=’x2',hue=’y’)

阶级不平衡散点图

视觉分布看起来很吸引人。多数标签(0)在数据集中占 99%,而少数标签(1)仅占 1%。因此,99%的准确度可以简单地通过将完整集预测为多数标签即 0 来实现。但是这是没有帮助的,因为我们正在建立分类器来从多数标签中分类少数标签(重要的)。
有许多技术可以用来处理阶级不平衡。一种流行的技术是上采样(例如 SMOTE),其中将更多相似的数据点添加到少数类,以使类分布相等。在这个上采样的修改数据上,可以应用任何分类器。

在逻辑回归中,另一种技术可以方便地处理不平衡分布。这是根据等级分布使用等级权重。类权重是算法因该类的任何错误预测而受到惩罚的程度。

使用默认权重,分类器将假设两种标签错误,即假阳性(FP)和假阴性(FN)具有相同的成本。或者换句话说,分类器假设任一标签的错误预测具有相同的成本。但事实上,少数阶级的错误预测比多数阶级的错误预测更糟糕。在欺诈交易等情况下,未检测到欺诈交易比错误地将非欺诈交易标记为欺诈交易对组织造成的损失更大。

逻辑回归(默认)

说够了,现在让我们看看加权逻辑回归的作用。

# import model and matrics
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import train_test_split, GridSearchCV, cross_val_score, RepeatedStratifiedKFold, StratifiedKFold
from sklearn.metrics import accuracy_score, confusion_matrix,roc_curve, roc_auc_score, precision_score, recall_score, precision_recall_curve
from sklearn.metrics import f1_score# split dataset into x,y
x = df.drop('y',axis=1)
y = df['y']# train-test split
X_train, X_test, y_train, y_test = train_test_split(x, y, test_size=0.3, random_state=13)

在上面的测试训练分割之后,让我们用默认的权重建立一个逻辑回归。

# define model
lg1 = LogisticRegression(random_state=13, class_weight=None
# fit it
lg1.fit(X_train,y_train)
# test
y_pred = lg1.predict(X_test)# performance
print(f'Accuracy Score: {accuracy_score(y_test,y_pred)}')
print(f'Confusion Matrix: \n{confusion_matrix(y_test, y_pred)}')
print(f'Area Under Curve: {roc_auc_score(y_test, y_pred)}')
print(f'Recall score: {recall_score(y_test,y_pred)}')

输出:

Accuracy Score: 0.9946666666666667
Confusion Matrix: 
[[2970    1]
 [  15   14]]
Area Under Curve: 0.7412110168409568
Recall score: 0.4827586206896552

对于少数类,上述模型能够预测 29 个样本中 14 个正确。对于多数类,模型只有一个预测错误。模型在预测少数民族阶层方面做得不好。尽管如此,有了这些默认的权重性能值,我们就有了衡量后续模型修改的基准。

加权逻辑回归

在不平衡标签分布的情况下,权重的最佳实践是使用标签分布的反转。在我们的集合中,标签分布是 1:99,因此我们可以将权重指定为标签分布的倒数。对于多数类,将使用权重 1,对于少数类,将使用权重 99。因此,少数类错误预测的惩罚将比多数类错误预测的惩罚重 99 倍。此外,有了这个类权重值,我们会期望我们的模型比默认模型(即以前的模型)表现得更好。

为了指定权重,我们将利用逻辑回归的 class_weight 超参数。class_weight 超参数是一个定义每个标签权重的字典。与形式为 {class_label: weight} 的类相关联的权重。如果没有给出,所有的类都应该有相同的权重值。

# define class weights
w = {0:1, 1:99}# define model
lg2 = LogisticRegression(random_state=13, class_weight=w)
# fit it
lg2.fit(X_train,y_train)
# test
y_pred = lg2.predict(X_test)# performance
print(f'Accuracy Score: {accuracy_score(y_test,y_pred)}')
print(f'Confusion Matrix: \n{confusion_matrix(y_test, y_pred)}')
print(f'Area Under Curve: {roc_auc_score(y_test, y_pred)}')
print(f'Recall score: {recall_score(y_test,y_pred)}')

输出:

Accuracy Score: 0.898
Confusion Matrix: 
[[2669  302]
 [   4   25]]
Area Under Curve: 0.880209844589654
Recall score: 0.8620689655172413

对于加权 LG,曲线下面积(AUC)从 0.7412 急剧增加到 0.8802。回忆分数从 0.4827 提高到 0.8620。对少数民族标签的正确预测也增加了。尽管模型在多数类中几乎没有错误预测,但是自定义权重在预测少数类中如预期的那样显示出改进。

权重网格搜索

可以有其他权重组合,它们可以表现得同样好或者可能更好。在这一部分中,将对不同的权重组合执行网格搜索,并将保留具有更好性能得分的权重组合。

# define weight hyperparameter
w = [{0:1000,1:100},{0:1000,1:10}, {0:1000,1:1.0}, 
     {0:500,1:1.0}, {0:400,1:1.0}, {0:300,1:1.0}, {0:200,1:1.0}, 
     {0:150,1:1.0}, {0:100,1:1.0}, {0:99,1:1.0}, {0:10,1:1.0}, 
     {0:0.01,1:1.0}, {0:0.01,1:10}, {0:0.01,1:100}, 
     {0:0.001,1:1.0}, {0:0.005,1:1.0}, {0:1.0,1:1.0}, 
     {0:1.0,1:0.1}, {0:10,1:0.1}, {0:100,1:0.1}, 
     {0:10,1:0.01}, {0:1.0,1:0.01}, {0:1.0,1:0.001}, {0:1.0,1:0.005}, 
     {0:1.0,1:10}, {0:1.0,1:99}, {0:1.0,1:100}, {0:1.0,1:150}, 
     {0:1.0,1:200}, {0:1.0,1:300},{0:1.0,1:400},{0:1.0,1:500}, 
     {0:1.0,1:1000}, {0:10,1:1000},{0:100,1:1000} ]
hyperparam_grid = {"class_weight": w }

我将对上述一组权重值组合进行网格搜索。这个列表可以详尽到你想要的程度。甚至可以制作一个简单的函数来创建一个不同组合的大网格。因为 ROC-AUC 分数是这里的评估度量,所以这个分数将被优化。

# define model
lg3 = LogisticRegression(random_state=13)# define evaluation procedure
grid = GridSearchCV(lg3,hyperparam_grid,scoring="roc_auc", cv=100, n_jobs=-1, refit=True)grid.fit(x,y)print(f'Best score: {grid.best_score_} with param: {grid.best_params_}')

输出:

Best score: 0.964040404040404 with param: {'class_weight': {0: 0.01, 1: 1.0}}

请注意,GridSearch 确定的权重分布的最佳值与我们之前使用的略有不同,即类别分布的倒数。在这里发挥作用的因素是评估指标和交叉验证。如果选择使用不同的评估指标,您可能会收到不同的权重值。使用上述权重值,让我们建立逻辑回归。注意,我也可以使用 grid.predict。

# define model
lg3 = LogisticRegression(random_state=13, class_weight={0: 0.01, 1: 1.0})
# fit it
lg3.fit(X_train,y_train)
# test
y_pred = lg3.predict(X_test)# performance
print(f'Accuracy Score: {accuracy_score(y_test,y_pred)}')
print(f'Confusion Matrix: \n{confusion_matrix(y_test, y_pred)}')
print(f'Area Under Curve: {roc_auc_score(y_test, y_pred)}')
print(f'Recall score: {recall_score(y_test,y_pred)}')

输出:

Accuracy Score: 0.8863333333333333
Confusion Matrix: 
[[2633  338]
 [   3   26]]
Area Under Curve: 0.8913926577606518
Recall score: 0.896551724137931

使用新的权重,我们在 AUC 和回忆分数上有了轻微的提高。从混淆矩阵可以看出,模型在预测少数民族阶层方面做得很好。虽然我们对多数标签有轻微的错误预测,但它应该是可行的,主要是因为少数标签在这里很重要,并且有很高的相关成本。

超参数网格搜索

逻辑回归的其他超参数的非缺省值有可能实现更好的性能。因此,在这一部分中,我们将对逻辑回归的各种超参数的一系列不同值进行网格搜索,以获得更好的性能分数。下面是执行网格搜索的参数网格和各种数值范围。

# define hyperparameters
w = [{0:1000,1:100},{0:1000,1:10}, {0:1000,1:1.0}, 
     {0:500,1:1.0}, {0:400,1:1.0}, {0:300,1:1.0}, {0:200,1:1.0}, 
     {0:150,1:1.0}, {0:100,1:1.0}, {0:99,1:1.0}, {0:10,1:1.0}, 
     {0:0.01,1:1.0}, {0:0.01,1:10}, {0:0.01,1:100}, 
     {0:0.001,1:1.0}, {0:0.005,1:1.0}, {0:1.0,1:1.0}, 
     {0:1.0,1:0.1}, {0:10,1:0.1}, {0:100,1:0.1}, 
     {0:10,1:0.01}, {0:1.0,1:0.01}, {0:1.0,1:0.001}, {0:1.0,1:0.005}, 
     {0:1.0,1:10}, {0:1.0,1:99}, {0:1.0,1:100}, {0:1.0,1:150}, 
     {0:1.0,1:200}, {0:1.0,1:300},{0:1.0,1:400},{0:1.0,1:500}, 
     {0:1.0,1:1000}, {0:10,1:1000},{0:100,1:1000} ]
crange = np.arange(0.5, 20.0, 0.5)
hyperparam_grid = {"class_weight": w
                   ,"penalty": ["l1", "l2"]
                   ,"C": crange
                   ,"fit_intercept": [True, False]  }

使用上述范围值,我们对逻辑回归进行网格搜索。

# logistic model classifier
lg4 = LogisticRegression(random_state=13)# define evaluation procedure
grid = GridSearchCV(lg4,hyperparam_grid,scoring="roc_auc", cv=100, n_jobs=-1, refit=True)grid.fit(x,y)print(f'Best score: {grid.best_score_} with param: {grid.best_params_}')

输出:

Best score: 0.9649494949494948 with param: {'C': 13.0, 'class_weight': {0: 1.0, 1: 100}, 'fit_intercept': True, 'penalty': 'l2'}

用上述最优值建立 logistic 回归模型。

# define model
lg4 = LogisticRegression(random_state=13,C=13.0,fit_intercept=True, penalty='l2',class_weight={0: 1, 1: 100} )
# fit it
lg4.fit(X_train,y_train)
# test
y_pred = lg4.predict(X_test)# performance
print(f'Accuracy Score: {accuracy_score(y_test,y_pred)}')
print(f'Confusion Matrix: \n{confusion_matrix(y_test, y_pred)}')
print(f'Area Under Curve: {roc_auc_score(y_test, y_pred)}') # 0.5
print(f'Recall score: {recall_score(y_test,y_pred)}')

输出:

Accuracy Score: 0.8876666666666667
Confusion Matrix: 
[[2637  334]
 [   3   26]]
Area Under Curve: 0.892065831776135
Recall score: 0.896551724137931

我们的 ROC-AUC 评分略有改善。使用最佳超参数,it 得分从之前的值 0.8913 提高到 0.8920,而回忆得分保持不变。准确度也略有提高。现在,有了这些超参数值,逻辑回归可以很好地用于上述不平衡数据集。这也表明准确性并不总是最好的评估方法。

结论

拥有不平衡的数据集并不一定意味着这两个类不可预测。对于处理不平衡数据集,上采样(例如 SMOTE)不是唯一的选择。虽然大多数算法被设计成以相等的类分布工作,但是对于处理类不平衡,上采样(例如 SMOTE)不是唯一剩下的选择。在逻辑回归的情况下,类权重(一个模型超参数)可以被修改以加权每个类分布的模型误差。

本文是针对欺诈检测等场景的实践,在这些场景中,类别不平衡可能高达 99%。此外,准确性并不总是模型的最佳评估标准。评估指标的选择取决于数据集和手头的情况。

希望你喜欢这篇文章。如果你想分享关于任何方法的任何建议,请在评论中畅所欲言。读者的反馈/评论总是给作家带来灵感。

权重、偏差和反向传播

原文:https://towardsdatascience.com/weights-biases-and-backpropagation-bb9dfbb10f62?source=collection_archive---------23-----------------------

神经网络的一些基本组件的简化视图。

从 Adobe Stock 获得许可的图像

神经网络是复杂、强大的人工智能(AI)系统,可以执行诸如识别照片中的对象或现场或录制语音中的单词等任务。这个名字来自于这些系统如何模仿人类大脑的一个方面——一个相互连接的神经元系统。许多优秀的资源可以在线获得,以了解神经网络和一般的人工智能,特别是在 YouTube 和像走向数据科学这样的出版物上。在本文中,我将简要介绍神经网络的两个基本组成部分:权重和偏差。

神经网络

神经网络包含多层“节点”例如,如果一幅图像由 28 x 28 像素的灰度网格组成,就像通常使用的 MNIST 手写数字训练集一样,神经网络的第一层将有 784 (28x28)个节点。每个初始层节点对应于图像中的一个像素,并且具有从 0 到 1 的值。“0”意味着像素是白色的,而“1”意味着像素是黑色的。第二层节点可以有另外 784 个节点,也可以有更多或更少的节点。为简单起见,我们假设第一层中的每个节点都“连接”到第二层中的每个节点。在神经网络中,可以使用许多后续的“隐藏”连接层,每个节点的值称为其“激活”最后一层称为输出层,其节点数量与“标签”(类别等)相对应。)的数据来训练网络。在 MNIST 的示例中,输出图层有十个节点,每个节点对应一个以 10 为基数的数字系统(0–9)中的一位数字。输出层(0–9)中具有最高值的节点将是系统对其刚刚评估的数字的猜测。

从 Adobe Stock 获得许可的图像

权重和偏差

一层中的单个节点与下一层中的每个节点之间的每个“连接”都有一个“权重”(正或负),它表示该源节点对它所连接的任何特定节点的影响有多强。当网络初始化时,所有这些权重都是随机选择的。

以 MNIST 为例,如果第二层有 16 个节点,将有 12,544 个权重将输入层连接到第二层(784 x 16)。新的 16 个节点中的每一个都有 784 个不同的连接,一个连接到输入层中的每个节点。

计算下一层中节点值的第一步是将源节点的值乘以它与下一层中每个节点的连接权重。接下来,为新层中的每个节点分配一个“偏移”值(正或负),以允许进一步“调整”该节点的值。最后一步包括将这两个计算的结果“压缩”到 0 到 1 的范围内,这就给出了每个连接节点的激活(值)。可以使用不同的“压缩”值的方法,但这超出了本文的范围。

每个后续层中所有连接的节点都以相同的方式计算:

第一步:((节点值)x(权重))+偏差

第二步:“Squishify”(将结果压缩到 0 到 1 的范围内)

步骤 3:将该值放入连接节点中

因此,网络在每个输出层节点中以激活值(0 到 1)结束。然后,基于这些激活的准确性,计算“成本”。例如,如果一个手写数字在 MNIST 数据集中是 7,但是“7”的输出节点有一个小的激活(0.15),但是“1”节点(0.72)和“9”节点(0.68)有较高的激活,这将产生一个高“成本”“猜测”的成本是每个输出节点的正确值和预测值之间的差的平方和。

反向传播

使用微积分来计算将使该特定预测更准确的权重和偏差的改变(以实现不正确输出节点的较低激活和正确输出节点的较高激活)。这个过程被称为反向传播,是神经网络“学习”的本质

在系统评估了“足够多”的图像之后(为了提高训练网络的效率,通常最好将数据分成块),所有这些针对权重和偏差变化的单独反向传播“投票”被组合起来,以得出考虑所有不同“投票”的“轻推”

一遍又一遍地重复这个过程,每次都使用组合的“投票”来微调权重和偏差,网络聚焦于每个权重和偏差的最佳值。即使在只有几层的简单网络中,这也意味着成千上万的计算。

如果你是神经网络的新手,我希望这些信息是有用的。如果你想深入了解,我最喜欢的资源之一是 YouTube 上的 3Blue1Brown 的一个系列。

我乐观地认为,人工智能将越来越多地被用来让我们所有人的生活变得更好。您是否面临数据科学问题/挑战?我很乐意帮忙;我们连线吧!

感谢阅读!

奇怪而不寻常的 SQL

原文:https://towardsdatascience.com/weird-unusual-sql-627b3cc895bf?source=collection_archive---------21-----------------------

照片由Meagan car scienceUnsplash 上拍摄

数据工程

使用异常的 SQL 查询探索数据库行为

答虽然阅读数据库理论和数据库文档是最重要的,但是通过尝试来习惯一个系统也是非常重要的。为了更好地掌握 SQL,从实验开始,无止境地编写愚蠢的查询,使用查询解决数学难题,使用查询创建一个随机的国际象棋游戏等等。当然,你可能没有机会在工作中做这些事情,所以抽出时间,尤其是如果你是一名数据人员的职业生涯的早期阶段。很明显,在你自己的机器上做。

了解 where 子句如何求值、子查询如何工作、排序如何工作以及空值在数据库中的行为,如果您进行实验,将会对这些内容有更深的理解。这样做也能为面试中被问到的任何棘手问题做好准备。然而,现在在面试中问一些刁钻的问题已经不太流行了。

[## SQL 查询的简单修复

查询任何传统关系数据库的经验法则

towardsdatascience.com](/easy-fixes-for-sql-queries-ff9d8867a617)

首先,看看这个例子——所有的 SQL 都归结于对WHERE子句的有效使用。理解它的行为是很重要的。

SQL 中整数是如何求值的!

当您在WHERE子句中使用整数时,它表示整数,但是当您在GROUP BYORDER BY子句中使用整数时,整数表示列在结果集中的位置号(不在表中)。这是另一个让查询写得更快的懒惰伎俩。但是,建议您不要使用GROUP BY 1, 3 ORDER BY 1 DESC,因为它为将来其他人编辑查询时导致错误留下了空间,特别是如果它是一个复杂的查询。一些零怎么样?

空值的行为方式!

对于大多数数据库,您会发现一篇专门的文档讨论如何处理空值。这里有一段来自 MySQL 的官方文档,讲述了使用空值的,还有一段是关于空值问题的信息。阅读这些内容,您会发现不能对空值使用等式或比较运算符。

[## 如何避免编写草率的 SQL

让您的 SQL 代码更易读、更容易理解

towardsdatascience.com](/how-to-avoid-writing-sloppy-sql-43647a160025)

继续前进。理解逻辑运算符对于编写 SQL 查询非常重要。大多数 SQL 引擎支持所有主要的局部运算符,如 AND、or、NOT、XOR。尽管我们在 where 子句中没有看到它们的替代项,但我们绝对可以编写这样的查询——

逻辑运算符&波浪号的使用

我在这里有了一些有趣的发现。对整数使用波浪号将从数据库中可能的最大整数中减去该数字,并返回结果。但是如果单独选择~,会给你一个错误。关于 and 和& &的可互换性,建议您在整个代码库中使用 AND 而不是& &或反之亦然,以便具有良好的可读性。否则会很混乱。还有,大家最喜欢的工具搜索&替换不会正常工作。

关于逻辑运算符的另一点是,它们支持所有附带的逻辑数学。例如,SELECT NOT NOT 1会给我们 1。当我们做SELECT NOT NOT 'Nice'时会发生什么。这里有几个例子来演示。

以串行方式使用多个逻辑运算符

当与数学运算符一起使用时,逻辑运算符应该用括号分隔,否则数据库引擎将无法识别逻辑运算符,并将其视为字符串,从而引发错误。

结合使用逻辑和算术运算符

我发现这种探索数据库行为的方法非常迷人。大多数已编写的查询都使用了内置于数据库引擎中的上述原则,大多数数据库都处理空值,但是我们了解数据库实际上是如何读取和解释我们的查询的吗?我认为,为了更深入地理解数据库,人们必须经历这样的随机查询。它们就像数学难题,但显然非常简单。

几乎所有支持 SQL 的数据库都是如此。我已经在这里写下了—

[## SQL 的多种风格

2020 年的 SQL 前景会是怎样的?它的未来会是怎样的?

towardsdatascience.com](/the-many-flavours-of-sql-7b7da5d56c1e)

欢迎来到人工智能游戏。你敢吗?

原文:https://towardsdatascience.com/welcome-to-the-ai-game-you-dare-7f3d3c3dac51?source=collection_archive---------87-----------------------

在探索机器学习及其算法背后的主要概念时获得乐趣。

“只是玩玩。玩得开心。享受比赛”——迈克尔·乔丹

我们将从头开始。在机器学习中,我们将使用矩阵、数组和向量符号来指代数据。

游戏规则是这样的:

  • 一行、一次观察或特定数据。
  • 前一次观察的一列、一个特征(或属性)。
  • 在最一般的情况下,会有我们会称之为“目标”,标签或回应,这将是我们要预测或实现的价值。

仅此而已。我让你轻松了,对吧?

照片由埃里克·麦克莱恩Unsplash 上拍摄

如果你想了解更多,请访问oscargarciaramos.com

现在,三种不同的机器学习技术:

监督学习,

“我们的第一场比赛”。这些算法采用一组已知的输入数据集及其对数据的已知响应(输出)来学习。我们知道什么“进”,什么“出”。一旦算法学习并得到适当的训练,我们就可以进行“泛化”,即模型有能力适当地适应新的、以前从未见过的数据。我们将区分两种类型的监督学习算法:回归和分类。

—标记数据、直接反馈、预测结果/未来

无监督学习

“走出下一步”。这一次,数据将被取消标记,结构将是未知的。我们的任务?找到数据的内在结构或模式。我们会发现两种类型的算法:聚类和降维。

没有标签,没有反馈,在数据中找到隐藏的结构

强化学习

“从经验中学习”。我们最后一个。尝试最大化算法因其行为而获得的回报。使用反馈反复试验。

—决策过程、奖励系统、学习系列行动

我们可以开始玩了吗?

线性回归

你家里有原木吗?根据体重有条理地摆放。但是,你不能称它们。你必须通过观察高度和它的直径来猜测(视觉分析)通过组合这些“可见”的参数来组织它们。 那是一元线性回归

我们该怎么办?我们通过将自变量和因变量拟合到一条直线上来建立它们之间的关系,这条直线就是我们的回归线,表示为 Y = a * X + b

  • y-因变量
  • a-斜率
  • X —独立变量
  • b —截距

我们如何计算系数 a 和 b?最小化数据点和回归线之间距离的平方差之和。

逻辑回归

我们将讨论 0 和 1,我们的离散值,我们必须从一组独立变量中估计它们。

该模型将尝试用一条线来拟合这些点,它不可能是一条直线,而是一条 S 形曲线。它也被称为 logit 回归

如果我们想改进我们的逻辑回归模型呢?包括交互项、消除特征、调整技术或使用非线性模型。

决策图表

当今数据科学家最喜欢的算法之一。

这是一种用于分类问题的监督学习算法。我们将从对某个项目的观察(在分支中表示)到关于该项目的目标值的结论(在树叶中表示)。它对分类变量和连续因变量的分类都很有效。

它是如何工作的?我们根据最重要的属性/独立变量将总体分成两个或更多的同类集合,然后…我们往下走!

SVM(支持向量机)

SVM 是一种分类方法,在这种方法中,算法将原始数据绘制为 n 维空间中的点,其中 n 是您拥有的要素数量。然后,每个要素都被绑定到一个特定的坐标,这使得对数据进行分类变得很容易。

算法的特别之处在哪里?我们将以苹果和橘子为例。它不是在群体中寻找那些最能被描述为苹果和橘子的,而是寻找苹果更像橘子的情况,这是最极端的情况。这将是我们的支持向量!一旦确定,我们将使用称为“分类器”的线来分割数据,并将它们绘制在图表上。

朴素贝叶斯

朴素贝叶斯分类器。它是一种基于贝叶斯定理的分类技术,假设预测器之间是独立的。朴素贝叶斯之所以“朴素”,是因为它假设测量的特征是相互独立的。

一种快速简单的方法来预测类,用于二进制和多类分类问题。

KNN(K-最近邻)

想象一下,你要去拜访一个比你的朋友或家人更好的人,对吗?

这是一样的。我想和我的朋友在一起。

我们可以将这种算法应用于分类问题和回归问题。它是如何工作的?简单,我们将所有可用的案例进行排列,并根据其 K 个邻居的多数投票对新案例进行分类。案例将被分配到具有最大共同点的类别或分类中。测量是如何进行的?用一个距离函数,一般是欧几里德距离。

注意:KNN 计算量很大,变量应该归一化。

k 均值

这是一种解决聚类问题的无监督算法。橘子配橘子,苹果配苹果。数据集被分类成特定数量的簇,我们的 k 数,因此一个簇中的所有数据点都是同质的,同时与其他簇中的数据是异质的。很简单:

  • 1.选择 k 个簇的数量。
  • 2.选择一个随机的 k 点,质心。
  • 3.将每个数据点分配到最近的质心(欧几里得)。
  • 4.计算并放置每个簇的新质心。
  • 5.将每个数据点重新分配给新的最近质心。

再次执行第 4 步…第 5 步,一遍又一遍…

随机森林

随机森林背后的基本思想是将许多决策树组合成一个模型。

为什么?作为一个委员会运作的大量相对不相关的模型(树)将胜过任何单个组成模型。

这个模型确保了 bagging (允许每棵树随机地从数据集中进行替换采样,从而产生不同的树)特征随机性 (其中每棵树只能从随机的特征子集中选取,从而产生更多的变化)

降维算法

虽然看起来不合逻辑,但是“多多益善”并不总是对的。由于这种类型的算法,我们通过获得一组主要变量来减少所考虑的随机变量的数量。 PCA (主成分分析) 缺失值比率因子分析 就是一些例子。

梯度增强和 AdaBoost

我们的赢家! 其主要目标是什么?进行高精度的预测。

我们将组合多个“弱或平均”预测器来构建一个强预测器。它结合了几种基本估计量的预测能力,以提高模型的稳健性。

这是最优秀的算法,也是当今最受欢迎的算法。

那么,下一步是什么?

现在开始,开始玩吧!这就是我要说的全部…

欢迎留言、鼓掌或分享这篇文章。以后的帖子关注 me

如果你想了解更多,你可以在 oscargarciaramos.com找到我

欢迎加入数据团队!请解决一切。(第一部分:问题)

原文:https://towardsdatascience.com/welcome-to-the-data-team-please-solve-everything-part-i-the-problem-13a157551804?source=collection_archive---------48-----------------------

数据产品不是灵丹妙药。

先说一个常见的情况。不管是勇敢的 MBA 市场实习生还是首席执行官,至少拥有一点权力的人都会面临一个难题。他们安排了一个项目启动会议,与不同的人一起集思广益,想出一个解决方案,并且知道如果它有任何机会被他们的上级批准,它将需要数据的支持。虽然他们让会议邀请对一些人来说是可选的,但他们确保来自数据分析或科学团队(以下称为“数据团队”)的一些人会出席。

简要说明:在我看来,关于数据分析和数据科学之间的区别,还没有达成共识。一家公司的数据分析师执行的任务符合另一家公司的数据科学家的工作描述。无论如何,当我在本文的其余部分和以后的文章中提到“数据团队”时,我指的是数据的最终用户,他们进行数据报告、分析和/或建模,以帮助组织实现其目标。他们不是数据工程师,任务是建立、维护和改进数据管道和其他基础设施。他们也不是机器学习工程师,他们正在构建集成到公司产品中的模型,如推荐器算法定价系统。

让我们假设您在这个高要求数据团队中。一方面,你直接参与解决公司面临的一些最重要的问题。另一方面,你面临的一些问题很可能属于以下不幸的类别之一:

1。这个问题不是由数据提供的。

虽然在自然语言处理方面正在取得进展,但创造性写作最好留给人类。特别想到的是品牌信息。

我们没有得到成功的口号"牛肉在哪里?就这么做,还是得了奶?“从大数据进入花哨的建模框架和动态仪表盘。事实上,如果我们想象一个可以访问历史品牌广告活动表现的数据和建模团队大量参与后两个活动的广告代理,我们可能会以“空气在哪里而告终?”和“牛奶在哪里?”这些广告商的目标是想出一个强有力的原创口号,让与其他品牌区分开来。我分享的算法生成的口号显然是荒谬的,但它们揭示了一个事实,即历史广告数据和典型的建模技术不适合这个问题。

将创意作为 crtv 导入。照片由 Pixabay像素拍摄。

在最好的情况下,参与项目的数据人员会浪费他们的时间,并随着项目的进展礼貌地原谅自己。最坏的情况是,他们用令人印象深刻但不相关的分析迷惑涉众,挤走了需要由其他项目贡献者完成的实际工作。

随着越来越多的数据(尤其是新数据集)随着时间的推移而产生,因此决策对数据的依赖也在增加,我们会发现自己在这种情况下的频率低于后续情况。

2。问题是有数据告知的,但是你没有。

现在,假设你是一名初级数据科学家,在一家个人金融初创公司协助产品团队。你被要求帮助他们,因为你已经工作了几个月,在其他项目上表现出色,并证明了你了解公司的内部数据集。贵公司目前的产品是一种工具,它允许人们通过导入和显示信用卡消费来设置预算并跟踪预算。您公司的领导层希望扩大初创公司的产品种类,并考虑增加个人贷款或投资平台,但没有产品开发资源来同时完成这两项工作。他们希望利用您的数据能力来提出合理的预测,如潜在受众和预测的贷款和投资金额,以帮助他们选择要开发的产品。

让我们从个人贷款产品开始。我在上面提到过,我们可以访问信用卡消费,但如果进一步检查,我们的数据集可能也包含还款历史或未偿余额。使用这些信息,我们可以确定我们服务中的用户数量,我们认为这些用户会对信用卡支付整合的个人贷款感兴趣。如果我们能够获得未偿余额,我们甚至可以预测贷款金额。不错!

对于在我们的平台上识别潜在的投资者来说,这有点棘手,但我们有创造力和毅力。我们可以浏览我们的数据集,确定可能的投资者会进行的购买,例如订阅投资出版物,如 Barrons投资者商业日报Kiplinger 的个人理财,以及服务,如 The Motley FoolSeeking Alpha 。为了预测在我们的潜在平台上可以投资的金额,我们可以选择我们可能的投资者,并应用一些假设,预测他们的收入和可投资的储蓄。太棒了。

我们向项目组的其他人介绍我们的方法和结果,用我们对棘手问题的冷静、冷静的回答给一些高管留下了深刻的印象。他们会审查您提供的信息,并决定使用您的作品来构建和发布哪种产品。你对自己得到的认可感到兴奋,你的公司必然会取得成功,你在做白日梦,想着如何在你职业生涯后期的开创性 ted 演讲中描述这段经历。

但是沉住气,在训练中,你错过了一些重要的东西。我想,这里有一些你没有解决的问题,这些问题很容易影响产品发布的选择:

  • 竞争对手:对于我们的竞争对手,我们有太多的不了解。对于那些我们认为可能对个人贷款感兴趣的人,我们如何知道他们是否在积极考虑其他贷款提供商?我们的产品如何与那些竞争?类似的推理也适用于投资的例子,更糟糕的是,他们可能已经在其他地方投资,并且对他们选择的平台非常满意。尽管他们是我们平台上的重要客户,但我们没有赢得他们的机会,并且对此视而不见。
  • 个人贷款的其他原因:仅从我们内部的信用卡消费数据来看,我们可能低估了个人贷款市场。获得个人贷款还有很多其他原因:为现有贷款再融资或支付紧急费用。在我们即将成为竞争对手的 LendingClub 上,只有 23%的个人贷款用于信用卡整合。

资料来源 : LendingClub 统计截至 2020 年 6 月 26 日。

  • 其他各种原因:我们可能无法获得用户所有信用卡的数据,这影响了我们的销量估计;对于我们可能的美元投资估计,我们猜测信用卡消费的总收入,但不是所有的消费都发生在信用卡上;并不是所有有信用卡债务的人都需要或对个人贷款感兴趣…

那么,有什么解决办法呢?在第一次项目会议上,我们是否会先发制人地指出这些与拟议分析相关的突出问题,然后几周内无所事事?不。事实证明,有一些偷偷摸摸的方法可以代替或补充我们的内部数据分析来获取我们需要的数据:

  • :可能就那么简单。让我们通过设计一份调查问卷并发送给用户来询问他们。显然,我们在准确性方面也有自己的一系列挑战(例如,当我们推出产品时,那些说要利用我们进行个人贷款的人真的会这样做吗?)、回复率(即,如果太多用户忽略调查怎么办?),以及抽样(即,如果非受访者与受访者在结构上不同怎么办?).好的调查设计可以帮助我们改善这些问题。作为奖励,我们甚至可以在调查中更详细地描述我们提议的服务,或者让用户告诉我们在个人贷款或投资服务中对他们来说什么是重要的。
  • 让我们通过使用越来越流行的安慰剂按钮,让我们的用户给我们提供有用的信息。我们在网页上添加了一个按钮,标有“个人贷款”、“投资”或两者之一。当用户导航到那里时,他们被告知该功能尚不可用,但他们可以注册了解更多信息。我们甚至可以将此与 Beg 战略相结合,通过发送后续调查来确定可能的贷款和投资量、两种产品的预期功能,并进一步评估兴趣。
  • 购买:让我们与第三方数据提供商合作,进一步了解我们的用户中有多少人对个人贷款或投资感兴趣,以及他们是否已经在使用有竞争力的服务。

期望其中一方(数据科学家或产品团队)知道寻找替代数据来解决问题公平吗?我的答案是否定的。数据科学家为他们的工作做准备的大部分课程都不涉及数据采购。甚至在问题集的第一个问题之前,他们通常会得到完成问题所需的数据集。倡导这些替代数据集不应该是他们的责任。同样,要求新数据的责任也不应该由产品人员承担。他们可能专注于其他一切:战略、设计、开发和上市计划。尽管这种情况令人沮丧,但我发现这三个类别中的下一个非常令人恼火。

3。问题是由数据告知的,你有数据,但没有人要求你这么做!

在这种情况下,组织如此接近做出正确的行动,但最终还是搞砸了。这就像学习了 SAT 考试中涵盖的所有概念,但却把错误类型的铅笔带到了考试中心。

你忘在家里的东西。照片由金·戈尔加Unsplash 上拍摄。

让我们想象一下,尽管在前面的例子中,我们的初创公司在决策过程中可能犯了一些错误,但我们已经成功地推出了个人贷款和投资服务。事情进展顺利,我们新雇了一位首席营销官(CMO),他想给首席执行官留下深刻印象。

CMO 自称是一个有创造力和远见的人。他总是有模糊的晚上计划。在他的 LinkedIn 个人资料照片中,他把一盆盆栽植物放在面前。他去年没去火人节是因为“他们毁了”(他们是谁?!).通过结合直觉、经验和吸毒的长期影响,他单方面决定让更多的大学生上你的网站将使公司进入“超增长”模式。他已经计划好了整个营销活动:专门针对 Z 世代的信息、学生品牌大使策划的游击营销策略、t 恤,但有一个问题:首席执行官希望看到支持这一大赌注的数据。为了得到 CMO 需要的数据,他需要你。

一天早上,你醒来时发现 CMO 在早上 5:53 分直接给你发了一封非常重要的电子邮件。你知道它非常重要,因为他添加了非常重要的标志,并在主题行中添加了“非常重要”。他直到最后一刻才开始填写演示文稿的数据幻灯片,并且需要了解贵公司活跃用户的平均生命周期价值(LTV) 。

你很兴奋,你建立的复杂的用户级 LTV 预测模型正在获得牵引力,并一直向上通过 c-suite 没有少!您已经设置了这个重要指标的自动报告,并催促他回复。

他对你表示感谢,并告诉你这个数字“比我预期的要好得多”,还说他欠你一杯啤酒,但就像急躁的人喝的一种非常特别的啤酒。在他得到你的回应后,他把平均 LTV 数放在一张幻灯片上,与这些大学生低得多的客户获取成本(CAC) 进行对比,证明有大量利润可赚。他在公园里睡了两个小时,完成了给首席执行官的报告。超增长,我们来了!

没那么快。如何使用你的分析发现各种问题?下面是一些被忽略的被收购用户的属性,这可能对我们不利:

  • 大学生:大学生可能有一些特定的特点,这些特点可能使他们比普通用户更有价值或更无价值。他们可能需要个人贷款服务,但不一定是大额信用卡债务合并,但可能是学生债务。你们公司的产品有竞争力吗?他们也不太可能需要一个投资平台,直到他们毕业之后。这两个特征可能意味着你提供的 CMO 的 LTV 数太高了。
  • 新消息:你的平均 LTV 包括那些已经使用你的服务一段时间的用户和那些最近加入的用户。如果任期越长的越值钱,这也是你给 CMO 的 LTV 数太高的另一个原因。
  • 主动:痛苦列车不断驶来。我们发送了活跃用户的平均 LTV,但是活跃用户到底是怎么定义的呢?让我们假设一个用户是活跃的,如果他们建立一个账户导入信用卡数据,获得个人贷款,或投资金钱。如果 CMO 使用的是 CAC 估计值,其中包括刚刚开设账户的用户,会怎么样?这也是我们的 LTV 数过高的另一个原因。

整个情况最糟糕的部分是,如果我们知道 CMO 计划如何使用我们的号码,我们可能已经能够使用我们已经拥有的数据为这些用户发送更准确的 LTV 估计。我们可以将我们的 LTV 预测数据集分成新注册的大学生的子集,包括活跃的和不活跃的,以便更好地估计类似用户的价值。

总结,并提示解决方案

在这三种情况下,数据的使用方式都无法最好地实现组织的目标。在品牌口号的例子中,数据团队的努力分散了需要完成的实际工作,这些工作甚至不需要数据分析或建模。在个人贷款或投资特征的例子中,预先存在的数据被用于体面的效果,但是需要获得的新数据会更好。在营销收购的例子中,错误的数据点被用于通知计划,即使正确的数据点是可用的。

如示例所示,由于缺乏数据,这些问题更加频繁和严重。数据盲有各种形式。有些人,比如第一个例子中的人,希望数据能够提供更多的东西,从类固醇(加速增长)到万能药(修复一切)都可以。其他人把它看作是一个被勾选的框: 用过的数据。在我们的第二个例子中,产品团队让他们的决策完全依赖于糟糕的数据,我认为这反映了一种普遍的态度:如果一个决策是由数据决定的,那么它一定是一个好的决策。在第三个例子中,CMO 已经决定吸引更多的大学生加入我们的平台。他只需要处理向首席执行官展示数据点以获得她的批准的麻烦。数据请求者和提供者之间权限的巨大差异会加剧这些问题。数据盲越往上走,数据团队就越不可能澄清(或直接拒绝)请求。

因此,解决方案是让某人明确负责确保数据得到负责任和有效的使用。这个人首先确定数据对于完成一个项目的目标是否必要,寻找数据,如果数据不可用,甚至生成或获取数据。

我鼓励你花一点时间思考一下你希望谁来承担这些责任。他们的工作描述是什么样的?你希望他们拥有什么样的技能和背景?是否已经存在类似的角色或领域?在“欢迎加入数据团队!请解决一切。(第二部分:解决方案)”,链接如下!

[## 欢迎加入数据团队!请解决一切。(第二部分:解决方案)

数据产品不是灵丹妙药,但无论如何请负责任地饮用。

medium.com](https://medium.com/@jarussingh/welcome-to-the-data-team-please-solve-everything-part-ii-the-solution-91cc06d55316)

欢迎加入数据团队!请解决一切。(第二部分:解决方案)

原文:https://towardsdatascience.com/welcome-to-the-data-team-please-solve-everything-part-ii-the-solution-91cc06d55316?source=collection_archive---------66-----------------------

数据产品不是灵丹妙药,但无论如何请负责任地饮用。

在"欢迎加入数据团队!请解决一切。(第一部分:问题),如果您还没有读过,我鼓励您去读一读,我分享了三个例子来说明组织滥用数据的常见方式。我们遇到的所有这三种类型的问题都可以通过让某人负责负责和有效地使用数据来解决。在这篇文章的结尾,我暗示了类似的角色在其他地方也存在。是图书管理员出于我们的目的,我们需要拥有更大权力的人,我称之为数据超级图书馆

那么,什么是数据超级图书馆?让我们从思考普通的非数据图书馆员的职责开始。图书馆员的任务是提供和维护信息。通过进行反事实分析,我们可以更好地理解图书馆员通过想象一个没有他们的世界所提供的价值。

在这个反事实中,我们是大学历史课的学生,我们的教授给我们布置了一篇关于珠宝在中世纪所扮演的角色的论文。奇怪的具体。我们参观了理论上没有图书馆的校园图书馆开始研究。我们穿过前门,在前台闲着,但是没有人帮助我们。没关系,我们自己找到历史部分,开始浏览。但是在一个没有图书馆员的世界里,没有人来组织书籍,甚至没有人来为不同的部分设计布局。我们面对的是随意摆放在书架上并散落在地板上的书籍!

照片由达尔文·维格Unsplash 上拍摄

我们开始拿起离我们最近的书,浏览它们的内容,但这需要太长时间。找到任何一本关于中世纪或珠宝的书的几率都很低,所以我们开始扫描书名。几个小时过去了,我们终于中了头彩!我们发现有一本书在书名中有封建称谓一种珠宝。我们把它带回家,从头到尾读完,敲出我们的论文,第二天交一篇关于珠宝如何在中世纪发挥关键作用的文章,事实上,一个邪恶的领主为了统治人类而铸造了一枚戒指,多个王国组成的多样化的特种部队摧毁了它以确保我们的救赎

我希望你喜欢我的宝贝,尽管这个例子有些夸张。让我们开始在 it 和商业世界之间进行比较。你可能认为书是数据,但是我想用一个更宽泛的定义。图书馆的书籍是一个组织目前拥有的数据产品,如报告、分析或建模。图书馆顾客是使用数据产品的商业利益相关者。在没有任何图书馆员指导的情况下,他们在数据产品中搜寻,直到找到一个他们认为可以解决问题的产品——即使这个产品不适合或不符合他们的目的。

图片作者。

当一个组织有一个数据管理员时,这个人可以将涉众与适当的数据产品联系起来。这可以对业务成果产生巨大的积极影响。适用于其用例的数据产品提供了改进优化的信息(例如,我们公司可以盈利的获取用户的最大数量是多少?)和决策制定(例如,是否有足够的需求来证明开发新功能的合理性?).

图片作者。

数据超级图书馆员甚至比他们的非超级同行拥有更大的权力和责任。他们还可以联系内部数据团队成员和外部服务,以委托最能解决业务问题的数据产品。在下图中,他们认识到需要现有的和新的数据来解决利益相关者的问题,这些数据可以是内部生成的(如调查数据)或外部生成的(如从第三方购买的),并将数据团队成员与这两种来源联系起来,为给定的用例创建最佳的数据产品。

图片作者。

我希望我已经让你相信这是组织中的一个关键角色,并且我不是唯一一个这样想的人。拥有一个数据超级图书馆的想法并不新鲜。在为本文做研究的过程中,我偶然发现了各种类似的职位,比如数据翻译数据策略师数据产品经理。尽管一些组织意识到了数据超级图书馆员的重要性,但对这类工作的讨论远远少于对数据科学、机器学习和人工智能的讨论。我将在下一篇文章“欢迎加入数据团队”中深入探讨为什么我认为这项工作普遍被低估了。请解决一切。(第三部分:被忽略的解决方案)”,链接如下。

[## 欢迎加入数据团队!请解决一切。(第三部分:被忽略的解决方案)

数据产品不是灵丹妙药——因为利益相关者更像图书馆的顾客,而不是巫师。

medium.com](https://medium.com/@jarussingh/welcome-to-the-data-team-please-solve-everything-part-iii-the-solution-ignored-f61573ac56c7)

欢迎加入数据团队!请解决一切。(第三部分:被忽略的解决方案)

原文:https://towardsdatascience.com/welcome-to-the-data-team-please-solve-everything-part-iii-the-solution-ignored-f61573ac56c7?source=collection_archive---------42-----------------------

数据产品不是灵丹妙药——因为利益相关者更像是图书馆的老顾客,而不是弱者。

这篇文章是我的“欢迎加入数据团队!请解决一切”系列。在第一篇文章中,我分享了组织中常见的数据误用,这是由非数据人员的过度自信或天真造成的。

[## 欢迎加入数据团队!请解决一切。(第一部分:问题)

数据产品不是灵丹妙药。

towardsdatascience.com](/welcome-to-the-data-team-please-solve-everything-part-i-the-problem-13a157551804)

第二,我建议这个问题的解决方案是给某人一个数据超级图书馆员的职责——通常被称为 数据翻译数据战略家数据产品经理——他决定哪些现有的数据产品最适合于实现企业的目标,并且如果需要,还有权委托新的产品。

[## 欢迎加入数据团队!请解决一切。(第二部分:解决方案)

数据产品不是灵丹妙药,但无论如何请负责任地饮用。

towardsdatascience.com](/welcome-to-the-data-team-please-solve-everything-part-ii-the-solution-91cc06d55316)

数据超级图书馆员决定这些产品是否应依赖预先存在的或尚未生成的(例如通过调查)或获取的(例如通过第三方)数据。尽管这一角色的责任很重要,但大多数数据科学和分析文章、讲座和课程都侧重于学习和应用统计或预测技术。虽然掌握编程语言和算法很重要,但在您的大型数据组织中有人负责有效地使用数据对于成功至关重要。以下是阻碍数据超级图书馆获得更多关注的态度。

组织没有意识到角色的存在

作者 Mummelgrummel——自己的作品,CC BY-SA 3.0,https://commons.wikimedia.org/w/index.php?curid=25796381

让我们考虑一个常见的情况。业务领导和数据团队为解决业务的一个关键问题开了一个长会,双方都不满意地离开了。数据团队不能回答简单的问题,解释他们提出的解决方案,并同意交付具体的结果,这让业务领导感到沮丧。数据团队感到沮丧的是,业务领导过度简化问题,不理解简单的统计概念,并频繁改变需要解决的问题的范围。

无论是否公开承认,双方都不得不接受与对方进行无益的互动。“这就是他们的方式,”两个团体的成员都声称。由于这种态度,双方都没有意识到中间人的必要性,此外,他们的态度使他们意识不到——随着思维的转变和一些培训——填补这一角色的人不需要成为外部雇员,也可以是他们中的一员。

也是一种我们不知道自己不知道的情况。不像在工厂车间闲置机器或运送有缺陷的产品,这是显而易见的问题,对于任何相关人员来说,组织没有有效地使用数据并不明显。

组织认为他们不需要这个角色

公司里谁负责决策通常是显而易见的。最有影响力的决策是由首席执行官制定的,或者至少是由首席执行官审核和批准的。下一层决策仍然是重要的,并且可能需要领域专业知识,是由剩余的高层管理人员做出的。随着我们沿着链条往下走,我们变得越来越专业化,影响力越来越小。这有道理;决策的影响力越大,决策者做出正确选择所需的资源和权力就越大。如果某个底层的人由于精明的决策对公司产生了不成比例的巨大影响,那么他们早就该升职了!

决策过程怎么样?谁对此负责?在这里,我怀疑大多数组织无疑是在以下假设下运作的:

负责决策的人* 也应该*负责请求最有助于做出决策的数据产品

通过雇佣数据超级图书馆员来确定最合适的数据产品,为决策提供信息,决策者正在放弃一项他们可能认为是其工作一部分的责任,一项他们可能不一定做得特别好的责任,特别是如果他们没有在负责任的数据应用方面的强大背景。这些高管不愿意相信任何其他人,甚至是一个熟练的专家,可以改善他们的决策过程。

作者 Jacob Peter Gowy—http://www . museodelprado . es/imagen/alta _ resolution/p 01540 _ 01 . jpg,公共领域,【https://commons.wikimedia.org/w/index.php?curid=27493281】T2

组织假设他们的数据团队管理已经在扮演这个角色

我发现,商业领袖对数据的二元态度常常是这种假设的基础。在本系列第一篇文章的第三个例子中,我谈到了一位假设的高管,他认为使用数据来支持他的决策是不方便的。对他来说,与预期目的相关的数据质量并不重要;这位高管只需要用足够的相关表面数据点来填充一副牌,以确保他的项目获得批准。

我见过这种同样的二元态度被应用到那些处理数据的人身上。假设您是数据团队的一员,通常只需要 SQL、Python、R、Tableau 或 Excel 的基础知识,您总是知道支持给定任务的合适或最佳数据产品。我们可以理解为什么他们会有这种想法。如果您自己在有效使用数据方面没有太多经验,但您看到它几乎被普遍应用,而且经常取得难以置信的成功,它看起来像是企业的灵丹妙药。如果数据产品是灵丹妙药,那就意味着创造它们的人一定是巫师。你不要干涉他们的神秘药水制作过程;你退后,给他们需要的资源,毫无疑问地一饮而尽。

作者威廉·亨利·马杰特森——http://d . lib . rochester . edu/Camelot/image/Margetson-she-was-known-have-study-magic(已剪辑),公共领域,https://commons.wikimedia.org/w/index.php?curid=69727077

尽管所有相关人员都希望如此,我还是要把我的魔药食谱放回架子上,脱掉我的斗篷,并解释为什么不是这样。iRobot 的分析、数据科学和机器学习主管安吉拉·巴萨(Angela Bassa)表示:“(T2)任何数据科学团队的经理之所以成为经理,是因为他们是伟大的个人贡献者。“我们可能会同意,这些战场提拔的数据科学经理是强有力的思想家,毕竟,他们是如何获得晋升的,但这并不能使他们免受偏见(心理的,而不是统计的)。

我接触过的大多数数据科学家都是在内部的、用户生成的数据上积累经验的,这是有充分理由的。如何收集的细节都有记录。有很多。一旦数据管道到位,它实际上是免费的。从一组用户行为中收集到的见解可以直接应用于产生这些行为的用户。

但是如何判断其他数据的相对有用性呢?当涉及到开发新功能时,是否完全依赖于对内部数据的用户细分分析来确定应该鼓励哪些行为来提高整体参与度?一个人会调查用户的潜在功能吗?他完全知道收集的数据可能不可靠。如果一个人既做内部分析又做外部分析,他如何权衡每一种分析的结果?在这个世界上,大多数数据科学管理人员最喜欢使用大量内部用户生成的数据来提出建议,调查数据是否得到了适当的重视?它甚至是作为一个选项提出来的吗?如果数据科学管理人员对如何有效地将调查数据集成到他们的分析中没有信心,他们就没有动力谈论调查数据。宣传你的弱点不是一个成功的策略。传统的数据科学管理人员不是我们要找的超级图书馆员,因为他们对图书馆的某些部分比其他部分更熟悉,因此更有可能误导他们的顾客。

充满希望的结论

事实证明,我们需要我们的数据超级图书馆员拥有的纪律是存在的!它被称为决策智能自 2018 年以来一直在谷歌由他们的首席决策官凯西·科济尔科夫领导开发。在为这篇文章做研究时,我了解到她写了关于数据科学领导的问题——以及其他所有人——没有得到足够的培训来改进决策和最大限度地提高数据产品的有效性。作为一门新兴学科,在谷歌、麦肯锡和 Instagram 等公司内部发展(名称不同),目前没有太多资源可以开始学习它。

由 Jeremykemp 在英文维基百科,CC BY-SA 3.0,https://commons.wikimedia.org/w/index.php?curid=10547051。作者所做的编辑。

如果你现在想在你的公司推出一个包装整齐的解决方案,这是一个令人沮丧的消息,但如果你想帮助发展这个学科并使其最佳实践民主化,这是一个巨大的机会。就我而言,我很高兴通过决策智能的视角来查看我所有的个人和工作数据项目,付出额外的努力来评估不同技术和框架的有效性,并分享我的发现。通过这样做,我回答了 Kozyrkov 在 2018 年发出的挑战,即“T16 加入[她]的行列,承认[决策智能]是一门独立的学科,并尽可能广泛地[产生以及]分享我们的智慧。“我希望我的系列文章为你做同样的决定提供足够的数据

数据科学家与钟形曲线的幽会

原文:https://towardsdatascience.com/welcome-to-the-world-of-data-416d03175df0?source=collection_archive---------35-----------------------

以及为什么数据科学家无法逃脱它

弗兰基·查马基在 Unsplash 上拍摄的照片

对于我们大多数人来说,数据科学和机器学习最可怕的部分是其中涉及的数学和统计学。

如果你是一个科学家,你必须有一个答案,即使在没有数据的情况下,你也不会成为一个好科学家。

-尼尔·德格拉斯·泰森

每个人都有自己培养对数据和数据科学的热爱的方式。对我来说,理解基础知识就像变魔术一样。曾经,我掌握了数据类型、分布和分布形状等基本概念。,深入研究高级概念是相当容易的。

我们来分解一下。

数据科学项目的主要输入是观察值:换句话说就是“特征值”。这些特征值(也称为变量)可以是定量的,也可以是定性的。

如果你的焦虑水平仅仅因为阅读这两个术语而增加,并且在你看完所有定量和定性数据之前你不会前进,请看下图。

作者图片

不要对自己太苛刻。先来了解一下这两种类型。

1.定量/数字数据

拍摄的亚历山大·米尔斯Unsplash

如果你能把数据加、减、乘、除,那就是定量的。数字数据被进一步细化为

  • 连续数据:可测量的数据。可以取任何值。例如:比赛时间、个人收入、个人年龄等。比赛中的时间可以是任何值,可以是小时、分钟、天等等..对值没有限制。

Jonathan Chng 在 Unsplash 上拍摄的照片

  • 离散数据:有限的和可计数的数据。只能接受某些整数值。《出埃及记》掷骰子的结果,一个班的学生人数,一朵花的花瓣。如果你掷骰子,你可以得到 1,2,3..最多 6 个。可能性是有限的。

吉列尔莫·贝拉尔德在 Unsplash 上拍摄的照片

1.1 连续数据

如果您打算为金融机构、零售行业等企业工作,那么您在数据科学领域的大部分时间都将与连续数据打交道。顾名思义它就像水一样。就像水可以流向任何地方一样,连续的数据可以取任何值。

要理解连续数据,你必须找到以下问题的答案。

  • 数据的意义是什么?
  • 数据值有多分散?即方差。
  • 关于平均值,总体数据分布是什么?
  • 有没有异常值?即标准偏差。

虽然我不想用公式来吓唬你,但只是触及表面并无大碍。

连续数据分布的均值是如何计算的?

连续数据分布的方差是如何计算的?

方差计算为平均值和单个值之差的平方和。

连续数据分布的标准差是如何计算的?

标准差是方差的平方根。

连续数据分发:

照片由艾萨克·史密斯Unsplash 拍摄

既然您已经了解了如何度量连续数据的均值、方差和标准差等具体细节,那么让我们来了解一下它的分布性质。

连续数据遵循以下分布之一。

  • 正态分布
  • t 分布

正态分布

我们周围的大部分事物都遵循正态分布。

奇怪!!

这个怎么样,如果你取你国家的人的身高,创建一个身高范围和该身高人数的图表,它将是正态分布,图表将类似于下图。

正态分布:作者图片

你可能会想,这是不可能的。

这看起来很奇怪,但却是真的。自然界中的许多其他东西。血压、智商、鞋码、出生体重,以及某种程度上的科技股市场,都遵循这个钟形曲线形状,数据以平均值为中心,并在平均值的两侧显示对称分布。

当我们谈论对称分布时,你也应该记住下面的公式来计算数据分布的偏斜度。

正态分布数据的偏斜度为 0。

你可能永远都不需要它,但是万一你需要,下面是绘制这个图表的方程式

以下是正态分布的主要特征。

  • 数据总体均值和中值是相同的。
  • 大多数数据点都以平均值为中心。
  • 数据点以对称的方式分散在平均值周围。

埃文·丹尼斯在 Unsplash 上的照片

如果你还在读这篇文章(我希望你是!!),现在您一定在想,为什么您需要理解数据分布呢?

答案是一个词概括

作为数据科学家,你可能会遇到很多垃圾数据、离群值等。来到你身边,你将会被迫去理解这些数据的意义,并根据这些数据来预测下一步的行动。

如果您了解数据分布的整体性质,您就可以排除离群值和不需要的数据,并使信息有意义。

记住这句“宇宙无混沌!”。

数据分布遵循一种模式。除了决策树之外,大多数机器学习模型期望具有连续数据的特征遵循正态分布。您可能会遇到这样的情况,即特征值本身并不遵循正态分布,但是如果您对值应用类似 log 的函数,它将遵循正态分布。

统计学家喜欢正态分布。一些统计学家会试图用正态分布中的连续数字来拟合每个观察值。有些人认为,如果数据总体不符合正态分布,这意味着我们没有足够的观察数据。

任何关于正态分布的讨论不提及 z 得分都是不完整的。z 得分表示特定数据值与数据总体的平均值有多远。下面是 z 分数的公式。

如果您计算数据总体中每个数据点的 z 得分,并根据标准差绘制它们,结果如下所示

https://www . int math . com/counting-probability/14-normal-probability-distribution . PHP

这被称为标准正态分布。标准正态分布的主要特征是

  • 它遵循正态分布。
  • 平均值、中值和众数值为 0。
  • 68.27%的数据位于 1 个标准差以内。95.45%的数据位于 2 个标准偏差内,99.73%的数据位于 3 个标准偏差内。

z score 将帮助您在特征工程期间发现异常值并验证零假设(p 值)和反向消除。

示例:如果特征值的 z 得分小于 1.96 且大于 1.96,则拒绝零假设。

在结束我最喜欢的话题,正态分布之前,我先给大家讲讲中心极限定理(CLT)

根据中心极限定理,如果你从一个数据群体中取几个样本,计算平均值并绘制平均值的频率,它将看起来像一个正态分布。样本数量越多,就越符合正态分布。即使从中抽取样本的总体数据不符合正态分布,也是如此。

这不是很奇怪吗!!!

这篇文章太大了。让我们总结一下正态分布,然后继续讨论 t 分布。

1.1.2 t 分布

现在你已经理解了正态分布和 CLT,是时候复习一下 t 分布了。

根据 CLT,只要样本量足够大(至少 30 次观察),样本的均值就遵循正态分布。因此,如果您知道数据总体的标准偏差,您可以计算 z 得分,并且使用正态分布,您可以使用样本平均值来评估概率。

如果样本量很小,并且不知道总体的标准差,该怎么办?当数据科学家遇到这样的约束时,他们依赖于 t 分布。计算如下。

数据科学家在无法使用正态分布的情况下使用 t 分布来分析数据集。数据总体应该是近似正常的。

作为一名数据科学家,您将在以下情况之一中使用 t 分布。

  • 如果数据大小大于 10 但小于 30。如果数据总体大小小于 30,则太小,无法显示正态分布。
  • 您经常会遇到这样的情况,您有数百万的数据要处理,而您不知道数据的分布(标准偏差)。在这种情况下,您必须首先获得少量数据样本(样本大小相同),然后计算其平均值、中值、众数、方差和标准差。基于这些样本大小的值,你将不得不推导出整个人口的这些值。

对了,t 分布也叫学生分布。但是,与学生使用这些统计数据无关。阅读下面链接背后的历史。

[## 学生 T 分布

威廉·戈塞特是一名为吉尼斯啤酒厂工作的英国统计学家。他为…开发了不同的方法

365datascience.com](https://365datascience.com/explainer-video/students-t-distribution/)

如果您想在 excel 中体验这些发行版,下面的链接包含了您可以使用的交互式 Excel 模板。

[## 交互式电子表格介绍商业统计-第一版加拿大

本书中使用的交互式电子表格已被锁定,除了允许学生…

opentextbc.ca](https://opentextbc.ca/introductorybusinessstatistics/back-matter/appendix-interactive-spreadsheets-editable/)

2.定性/分类

安德鲁·斯图特斯曼在 Unsplash 上的照片

分类数据没有数学意义,因为像加、减、乘、除这样的数学运算不能在这样的数据上执行。例如,加拿大的省份是一个分类变量。你不能像数学数字一样比较这些省份。分类数据可以进一步分为。

  • 二项式数据
  • 标称数据
  • 序数数据

不幸的是,我现在需要结束这篇文章。我喜欢理解数据,而且我可以继续下去。但是太大的文章意味着被出版商拒绝:(

如果你是一名有抱负的数据科学家,一定要培养你对数据的热爱。并且,爱因理解而绽放,所以花必要的时间去理解数据和它的本质。

参考:

[## 机器学习实践课程

加入最全面的机器学习实践课程,因为现在是开始的时候了!从基础…

www.udemy.com](https://www.udemy.com/course/applied-machine-learning-hands-on-course/?referralCode=00F08274D257B06E3201) [## 端到端机器学习

Sanrusha 是基于机器学习和人工智能的解决方案的领先提供商。我们努力通过使用人工智能让生活变得更美好。

www.youtube.com](https://www.youtube.com/c/endtoendmachinelearning)

我们总会有续集

原文:https://towardsdatascience.com/well-always-have-sequel-55325432174?source=collection_archive---------24-----------------------

卡斯帕·卡米尔·鲁宾在 Unsplash 上的照片。这幅作品的标题灵感来自在《卡萨布兰卡》中的这一幕

数据工程

为什么 SQL 会在数据工程、数据科学和软件开发领域占据一席之地

第一次做对的技术往往会持续很长一段时间。SQL 就是这些技术中的一种。然而,像许多伟大的技术一样,它在早期的迭代中不得不经历一些变化。在设计这种语言时,我们投入了大量的思考,让它易于理解,易于使用,并发挥其最大的威力。

SQL 为什么不消失

虽然许多人预测 SQL 的死亡,但它拒绝死亡。SQL 带来了许多独特的东西。没有可行的替代方案能像 SQL 那样提供灵活性、强大的功能和易用性。这些年来,有几件事让 SQL 生存了下来

  • SQL 的通用性和可接受性已经在几十年中得到证明
  • SQL 查询的强大威力和探索所有可能的数据访问模式
  • 以最有效的方式表达结构化和关系数据的能力以及以确定性方式分析数据的能力

使用 SQL 还有更多原因,更不用说市场上已经存在的训练有素的劳动力,不仅包括软件工程师,还包括数据分析师、营销和销售人员、数据工程师等等。他们说数据是世界上最有价值的资源。如果是这样的话,SQL 是最有价值的技能,因为 SQL 是数据说话的语言。

为什么有人说 SQL 已死

在给它取名关系模型死了,SQL 死了,我自己也感觉不太好之后,发表在 SIGMOD Record Journal 上的论文的六位作者得出了以下结论——

我们都相信关系数据库系统和 NoSQL 数据库系统将继续共存。在大型、分散、分布式环境的时代,设备和数据的数量及其异构性正在失去控制,数十亿个传感器和设备收集、通信和创建数据,而 Web 和社交网络正在扩大数据格式和提供商的数量。 NoSQL 数据库最适合这类应用,它们要么不需要 ACID 属性,要么需要处理用关系术语 笨拙表示的对象。

总之,NoSQL 数据存储似乎是商业企业可以选择的附加设备,以完成其存储服务的分类。

学习 SQL 有多重要

SQL 天生就是一种简单易学的语言。这是它如此受欢迎的原因之一。学习如何编写 SQL 并不真的需要有计算机科学背景。产品经理、数据分析师、业务分析师、营销助理、销售主管、数据工程师、数据科学家、软件工程师——这些都是 SQL 有用的工作。有些人在谈论 为什么学习 SQL 很重要的时候,相当简洁地在 Reddit 线程上写道。

这就像为了运动而知道如何走路一样。基本水平,但很重要。

在一个 YCombinator 线程中,人们讨论 为什么 SQL 正在击败 NoSQL ,以及这对数据的未来意味着什么。关于 SQL 是什么和不是什么,它有多优雅或丑陋,SQL 的正交性问题,处理大规模数据的问题,以及在许多情况下对 SQL 带给您的所有功能的热爱,都出现了有趣的观点。

谁应该学习 SQL?为什么要学习 SQL?

第一个问题的答案是每个和数据打交道的人。SQL 是最重要的技能,是利用数据价值所需要的——不管你的数据放在哪里。如前所述,大多数数据技术都有某种 SQL 接口。Atlassian 的吉拉有 JQL,Salesforce 有 SOQL,Kafka 有 KSQL 等等。不可否认的是,每种数据技术都必须支持一种新的方言或 SQL 风格。这是去年 StackOverflow 开发者调查的快照。

不必要的批评

人们批评 SQL 不能帮助查询非结构化数据和实时查询数据。该语言旨在查询结构化的持久数据。不能责怪语言没有做它从未承诺或声称要做的事情。就像问这车为什么不飞?然而,许多基于 SQL 的包装器和层已经被引入市场,并被混合采用。

SQL 被设计成既可以作为交互式查询的独立语言,也可以作为 OLTP 的应用程序开发语言。

所有查询语言之母

我的个人经历

作为数据行业的一员,我多年来一直听说 SQL 的死亡,但它似乎不会消失。大约十年前,当大数据获得牵引力时,人们认为这将是传统数据系统的末日。事实证明情况并非如此。每天编写代码的业内人士可能知道,关系数据库和 SQL 不会很快走向任何地方。原因是,

SQL 是数据交流的语言

21%的纽约市居民真的感染了新型冠状病毒吗?

原文:https://towardsdatascience.com/were-21-of-new-york-city-residents-really-infected-with-covid-19-aab6ebefda0?source=collection_archive---------4-----------------------

是时候了解一下偏见了!

下面是文章的音频版本,由作者为你朗读。

当我看到昨天《商业内幕》的标题时,我知道这将是一个关于统计偏差的完美案例。科莫说,一项全州范围的抗体研究估计,21%的纽约市居民患有冠状病毒。

我不可能要求一个更好的。

新冠肺炎可不是闹着玩的,作为一名纽约市居民,我痛苦地意识到这一点,她今年的生日是在与几乎要了她的命的肺炎的斗争中度过的。然而,人们找到的曲解数据的创造性方法是像我这样的统计学家的永恒笑点——这些天我会把我的笑声带到我能得到它们的地方。图片:meme 模板来源信息

有人要被批评了…但是是谁呢?在我掰指关节的时候拿好你的爆米花。准备好了吗?我们开始吧。

什么是偏见?

取决于你从哪里听到这个词。我半开玩笑地列出了各种偏见用法的清单供你娱乐,但在本文中,我们将重点关注偏见的统计种类。

在统计学中,偏见就是系统的不平衡。

如果不平衡的结果具有误导性,那并不一定意味着它们是出于误导的意图而产生的。也许是,也许不是。统计偏差可能来自疏忽、无知、浪费或诡计。

我们来谈谈离题的结论,好吗?图片:来源

统计学家可能会用**一词偏向一词**来指代:

  1. 我们的技术定义——在 瞬间 揭晓。
  2. 随机化中的意外事件。
  3. 扭曲的结论。
  4. 任何偏差的其他定义。(我们有些人是人。)

我们将从这些(重叠的)角度来看我们的小案例研究。

巨大期望

图片:来源

在统计学中,偏差是估计量的期望值和它的估计值之间的差异。

这是非常的技术,所以请允许我翻译。偏见是指结果系统地偏离了目标。想想射箭时,你的弓没有被正确瞄准。

偏差指的是系统性偏离目标的结果。

高偏差并不意味着你在到处射击(这是高方差),但可能会导致一个完美的射手一直击中靶心以下。

标题称,该研究估计 21%的纽约市居民患有冠状病毒。我的猜测是这个数字偏上。

21%?我怀疑真实数字更低。

为什么?我嗅到了随机问题的刺鼻气味,这些数据是如何获得的,这让我想到了统计子定义#2。

选择偏差

触发系统性偏离目标的结果的一种特殊方式是以一种有问题的方式收集你的数据。对于喜欢抱怨的统计学家来说, 选择偏差 是一种值得珍惜的友敌关系。它经常来访!

当你感兴趣的群体中的不同成员到达你的样本概率不同时,选择偏差就发生了。

换句话说,你从你的样本中得出结论,就好像它是随机抽取的,而实际上是“随机”抽取的。

图片:meme 模板来源信息

在这种情况下,你的样本并不能代表你的人口中的 T21……这使得你的结论不可信。

如果你的感兴趣人群所有纽约市居民,那么你就没有随机样本 (SRS),除非每个单一纽约市居民被包括在内的概率相等。纽约抗体研究所满足这一要求吗?肯定不是。

这项研究没有平等地代表每个人。

在我打开这篇文章之前,我就在想,“是的,没错。他们做了什么聪明的事情来收集呆在室内的人的数据?”事实证明,没有聪明的事。这项研究测量完全自我隔离的人的概率有多大?零。有多少纽约居民完全不与人交往?我们不知道。

覆盖不足偏差:当你的方法不能覆盖整个事情时,一些未覆盖的部分被遗漏了。图片:来源

这种类型的选择偏差被称为 欠覆盖偏差 。如果某些部分没有机会被抽样,你的样本就不能覆盖你的总体。一个务实的快速解决覆盖不足偏差的方法是接受一个不太雄心勃勃的人口定义。不要试图对“所有纽约市居民”做出推论,你可以选择谈论“所有纽约市居民以外的地方”——问题解决了!

不完全是。情况变得更糟。

如果我们有更有趣的 采样偏差 呢?如果非零概率也被系统地打乱了呢?如果有什么特殊的东西使得一些外出者比其他人更容易被检测到呢?

纽约人在疫情杂货店购物。经许可使用的图像。

让我们看看数据是如何收集的。这项研究测试了“在杂货店和大卖场”的人们如果你想增加曝光率,你会去哪里?去人口密度更高的地方,比如杂货店和大型超市。这项研究是在哪里进行的?没错。

携带病毒承担更大风险的人有更高的概率参与抗体研究。

如果你真的,真的,真的想得到病毒呢?你可能会经常去杂货店和大卖场,比那些试图降低感染几率的人去得更频繁。在这两种人当中,哪一种人更可能有新冠肺炎抗体?你认为哪个更有可能在正确的时间出现在正确的地点参与研究?你好,选择偏差!

因为认为这是个好主意的人和其他人没有区别。图片:来源

事实上,这项研究的设计是各种选择偏差的宾果表——抽样偏差、覆盖不足偏差、自我选择偏差、便利性偏差、志愿者偏差等等。如果你想让我写一篇后续文章,带你浏览一下这些(以及如何战胜它们的技巧),转发是我最喜欢的动机。

有偏见的弓箭手很容易——如果你一直击中中心以上的目标,至少你可以看到它并做出调整。有选择偏见的研究人员就没那么幸运了。选择偏差意味着你所有的结果都是错的,而你不知道错了多少

选择偏差意味着你所有的结果都是错的,而且你不知道错得有多离谱。

你害怕吗?应该会吓到你吧!我能做的就是猜测结果被抽样程序偏上,但是没有办法知道真正的数字是多少。但是等等,还有呢!更糟的是。

有偏见的结论

如果不平等的代表性不是唯一扰乱我们做出明智结论的能力的事情呢?还有很多其他偏见可能会损害你的统计结论。

如果抗体测试本身有研究人员没有意识到的问题呢?

例如, 信息偏差 发生在测量系统不正确的时候。如果抗体测试本身有研究人员没有意识到的问题呢?如果他们只检测高于严格阈值的抗体以避免假警报呢?那么这些测试将会遗漏病毒病例,所以他们将会降低估计值。

图片:来源

如果信息偏差和选择偏差无形中拉向相反的方向,那么估计值是过高还是过低?不可能知道。我们能确定的是什么?杂货店和大盒子店里的一些人从一种叫做抗体测试的东西中得到了令人兴奋的读数。我们对纽约居民的实际暴露率了解多少?耸肩

报告偏差和确认偏差

在人类可能使用“偏见”一词的许多其他方式中,有几个跨学科的方式,统计学家发现它们与我们最喜欢的对话方式特别相关:指出某人在某件事上是错的。这里我只提确认偏差和报告偏差。

公平地说,商业内幕,我认为他们做了很好的报道。他们甚至称结果为“初步的”,并提到了一些我谈到过的相同的抽样问题。太棒了。这些都是由纽约州长和进行这项研究的团队最初发出的谨慎的声音。我和他们也没有过节。相反,我的抱怨是互联网上的其他人正在玩的破碎的电话游戏。

这只树懒没看文章。就像有些只看标题就会评论的乡亲一样。我们看到你了。图片:来源

有些人不会花时间去读全篇 。好吧,我知道了,你很忙。唉,有些人没有用适当的“没读过的笑话”来谦逊,而是把这个标题当成了全部。当他们与他人分享他们“学到”的东西时,他们将创造一个报告偏见的教科书范例。

当人们得出一个结论,而不是给出他们的消息来源所拥有的所有信息时,就会出现报道偏差。

每当人们只传递最极端或“有趣”的信息,而留下削弱他们结论的无聊信息时,就会出现报道偏差。你会发现,只要人们有动力去:

  • 对复杂的事情进行简明扼要的总结(例如,将所有内容压缩到一条 280 个字符的推文中)。
  • 防止读者的眼睛变得呆滞(例如记者对科学出版物发表评论)。
  • 通过诡计说服某人(例如,方便地“忘记”提及对你希望提出的论点产生怀疑的研究)。
  • 对他们的意见感觉更好(例如,当他们遭受确认偏差时)。

不管报道偏见背后的意图是什么,它的存在会削弱你的结论的有效性。

是不是每个有罪的人都知道自己在做这件事?如果他们成为确认偏见的牺牲品就不会。

确认偏差 会干扰你感知/注意/记住与你的观点不一致的证据的能力。

提出这种认知偏见让我们从统计学领域进入心理学丛林,所以我会很简短。

* [## 克服新冠肺炎期间的确认偏差

在疫情期间,你的大脑是如何干扰你的,你能做些什么

towardsdatascience.com](/overcoming-confirmation-bias-during-covid-19-51a64205eceb)

确认偏差是一个感知、注意力和记忆的问题。用最简单的话来说,一个证据对你来说是否“坚持”,是受你事先的看法影响的。如果你不小心,你会注意到并记住那些证实你已经相信的信息。如果你不能看到一个故事的所有方面,你可能甚至不知道你只报道了你最喜欢的,用谎言感染信任你的人。

研究没有价值吗?

我猜想有很多人会因为这项纽约抗体研究而得出无根据的结论。像往常一样,最不了解数据的读者将从中“学到”最多的东西。

这是否意味着这项研究毫无价值?不,但这取决于你对它的假设。由于我们从数据中很难确定知道什么,所以做出超越事实的推论的唯一方法就是用假设来弥补差距。这就是所有的统计数据。假设,不是魔法。

这项研究的好坏取决于你对它的假设。

不幸的是,我们并不都同样有资格做出好的假设,从而得出有用的结论。例如,虽然我是一名拥有丰富现实世界数据收集经验的统计学家,但我不是抗体测试方面的专家,所以你不应该相信我会对它们的准确性做出明智的假设。太棒了。我也不相信我,所以我最终会对 NYC 的病毒暴露率一无所知。这项研究在我的手里毫无价值。

我们并非都同样有资格做出好的假设,从而得出有用的结论。

我可以怀疑任何我喜欢的导致高估的选择偏差,但我所知道的是结果可能是错误的,我们不知道错误有多严重。如果你告诉你的朋友,我说这个数字低于 21%,你就向我们展示了报告偏差的一个主要演示。

但是,当一生都在研究病毒的专家与精通纽约人行为的医学专业人士和心理学家合作……并与那些了解所有实际细节的人合作,了解在开发和部署那些抗体测试到杂货店期间实际上发生了什么,那么,也许那些人正坐在漂亮的位置上做出假设,解开收集的美味数据的营养价值。

图片:来源

在他们能干的手中,这项研究可能确实非常有价值。

在有能力的人看来,这项研究可能确实非常有价值。

也许我们其余的人应该保持安静,让成年人继续他们的工作。

感谢阅读!喜欢作者?

如果你渴望阅读更多我的作品,这篇文章中的大部分链接会带你去我的其他思考。不能选择?试试这个:

[## 一位决策科学家给新冠肺炎的十大禁忌

在疫情期间,照顾好你的大脑,聪明对待数据,做出更明智的决定

towardsdatascience.com](/a-decision-scientists-10-dos-don-ts-for-covid-19-805577bccd67)

与凯西·科兹尔科夫联系

让我们做朋友吧!你可以在 TwitterYouTubeLinkedIn 上找到我。有兴趣让我在你的活动上发言吗?用这个表格联系。

人工智能课程怎么样?

如果你正在寻找一门为初学者和专家设计的有趣的应用人工智能课程,这里有一个我为你制作的娱乐课程:

在这里欣赏整个课程播放列表:bit.ly/machinefriend*

我们正处于一场技术革命中…那么,我们需要更多的科技 MBA 吗?

原文:https://towardsdatascience.com/were-in-a-tech-revolution-so-do-we-need-more-tech-mbas-52ba20dbafaa?source=collection_archive---------54-----------------------

越来越多的商学院正在重新定位它们的 MBA 课程

来源:图片由 Free-Photos 来自 Pixabay

传统的 MBA 是 19 世纪末和 20 世纪美国工业化的产物。在工业化时期,美国需要提高劳动生产率,其企业开始全球化。1911 年,F.W .泰勒写了一本名为《科学管理原理》的书,主张用科学的方法来帮助管理者提高员工的生产力。在接下来的一个世纪里,它对管理教育产生了巨大的影响。我们今天看到的事实是,人力资源管理、领导力、运营规划和会计仍然是 MBA 的核心课程。

然后,在第二次世界大战后,美国的跨国公司征服了世界,其他地方的跨国公司也试图效仿。正如经济学家 所描述的那样:“麦当劳和肯德基体现了一种理念,这种理念将变得非常强大:由全球经理人经营、由全球股东所有的全球企业,应该向全球客户销售全球产品。很长一段时间,他们的跨星球模型就像他们的薯条一样又热又脆又多味。像 IBM、麦当劳、福特、H & M、Infosys、联想和本田这样的公司已经成为经理人的基准……”有了这个“基准”,公司需要能够管理大公司、跨越全球、了解国际业务、此外还能征服新市场、战胜竞争、筹集所需资金以扩大全球业务的经理人。我们看到,如今这种需求反映在 MBA 课程对战略和品牌、营销、国际贸易、物流和供应链管理以及金融的强烈关注上。

这似乎在一段时间内很好,但现在,世界又在发生变化。劳动生产率(泰勒关注的问题)和企业全球化(“麦当劳”模式)都越来越感到举步维艰。世界上最大的经济体之间的贸易战正在成为现实,越来越多的公司正在重新支撑或加倍关注本地和区域市场——由于疫情的冠状病毒,这种趋势可能会加速。简而言之,在过去的二十年里,西方国家的劳动生产率(T3)增长持续下降,企业家精神(T4)衰退(T5),创新(T7)变得不那么有效,不平等(T8)和 CEO 薪酬(T10)飙升,全球化(T12)正在倒退。

所有这些都是在 MBA 项目注册人数大幅增长的情况下发生的——或许是因为这一原因——例如,在 1970 年至 2012 年间,MBA 项目注册人数增长了 623 %,而同期其他硕士学位的增幅仅为 103%。鉴于所有 MBA 工厂的潜在供应过剩,人们可能已经预料到 CEO 的相对薪酬会下降,除此之外,为什么这种情况对生产力、创新和企业家精神等基本管理问题的影响如此令人失望?

最近一段时间,便士已经掉了。有些人,比如马丁·帕克(Martin Parker)认为所有的商学院都应该关闭,称“商学院有着巨大的影响力,但它们也被广泛认为是智力欺诈的场所,助长了一种短期主义和贪婪的文化……解决这些问题的最佳方案是彻底关闭商学院

难怪商学院开始反思 MBA 的性质和内容。近年来,不断下降的 MBA 入学人数,以及 MBA 逐渐失去光彩的迹象,使得对 MBA 的反思变得更加紧迫。这种观点认为,如果我们重新设计 MBA 课程,那么商学院本身可能会得救,因为它们培养的不是导致上述困境的毕业生,而是为一个容易发生危机的世界提供全面的领导力,在这个世界里,政治家们似乎已经迷失了方向。具有讽刺意味的是,商学院正变得越来越雄心勃勃,甚至对自己在社会中的地位越来越浮夸,尽管有人呼吁关闭商学院。

在这种反思中,一个已经广泛传播的观点是社会“影响”或目的。商学院毕业生炫耀自己是为了积累财富和实现利润最大化的日子已经一去不复返了。今天走进任何一所所谓的三冠王认证商学院,你都会受到一大群社会企业家、慈善家、企业社会责任爱好者、社会正义斗士、气候活动家和商业伦理教授的欢迎。MBA 毕业生如何帮助世界实现可持续发展目标(SDG)的课程正成为必备课程。“负责任的商业教育”这里“”是关键词,是新常态。

另一个同时获得更多关注的想法是,MBA 需要重新设计,以使毕业生能够在一个正在经历技术革命的世界中产生影响。它是由 ICT 的创新驱动的,这些创新见证了计算成本的骤降,联网设备数量的飙升,并使数字平台公司成为全球超级明星。世界上最有价值的公司是数字平台公司。他们在人工智能(AI)的发展方面处于领先地位。事实上,人工智能正在被大肆宣传,被吹捧为一种类似于电力的通用新技术,数据比石油更有价值,数据科学家是 21 世纪最性感的工作。在 20 世纪上半叶,MBA 毕业生必须管理他们公司的生产力转型,而在下半叶,他们公司的全球转型,现在在 21 世纪,他们必须管理他们公司的数字化转型,并为人工智能的力量喝彩。

鉴于上述情况,越来越多的商学院正在重新定位它们的 MBA 课程,推出所谓的“科技 MBA”。当然,科技行业已经成为 MBA 毕业生最大的雇主之一,这是有帮助的。例子包括康乃尔商学院 2017 年推出的科技 MBA,以及最近 IE 商学院推出的他们称之为“欧洲首个科技 MBA ”我们可以预期会有更多的商学院效仿。他们嗅到了一个市场,可以高价出售更多的 MBA 名额:康奈尔理工学院的 MBA 价格高达 10.7 万美元。许多其他人,即使他们不称自己的是科技 MBA,也一直在更多地关注“科技”主题,如大数据分析、人工智能和数字经济。最受欢迎的,也是最有争议的,是数字营销,这是不断增长的注意力产业的核心,也是对数据隐私算法偏差和投票者操纵的担忧。

这些争议和担忧,以及对滥用技术的更广泛的担忧,标志着商学院转向社会目的和高科技的冲突。许多新技术提出了道德、伦理和治理方面的挑战和问题,而商学院通常没有很好地解决这些问题,这与负责任的商业教育理念相冲突。许多科技公司将最急切地吸纳这些科技 MBA 项目的毕业生,但它们并没有雇佣自己的技术人员来解决重大的全球挑战,甚至可能加剧不平等。商学院往往会忽略的问题包括:高科技作为一种宗教的兴起(超人类主义)、高科技行业的例外主义、持续存在的性别差距、自主致命武器、高科技与军事、监视国家、关于人工智能的过度炒作、跨国公司的避税

然而,更明显的是,如果商学院确实希望对可持续和共享发展以及全球领导力产生影响,那么提供价格昂贵的“科技”MBA 项目似乎有些奇怪。这也很讽刺,因为技术革命让东西变得更便宜、更容易获得。因此,商学院难道不能通过利用同样的技术创新性地降低成本、增加受教育机会、提供差异化学习来实践他们对高科技的热情吗?与计算和信息成本的大幅下降形成对比的是,商学院教育的成本,就像更广泛的高等教育一样,一直在上升:例如,美国高等教育的学费在 1978 年至 2015 年间上涨了1225%——比商品和服务的平均价格上涨了 5 倍。

那么,我们需要更多的科技 MBA 吗?是也不是。是的,如果这些项目能明显偏离 20 世纪的 MBA 教学方法。是的,如果他们能以内部一致的方式调和高科技和社会目的。是的,如果他们不仅仅是为了高科技商业利益而出卖自己的话。否则,它们最终可能会让商学院看起来不真诚、精神分裂,加剧工资溢价,并转移人们对不那么可扩展、不那么性感、但却至关重要的其他(非数字)技术的关注。要脱离 20 世纪的 MBA 教育方式,商学院的商业模式需要改变。然而,对于大多数商学院来说,由于它们的短期主义传统和从众行为,在 MBA 课程中加入一些科技课程,并将其标榜为一种专属“体验”,似乎要容易得多。只要有足够多的富有或负债累累的学生愿意支付这个价格,我们就会看到我们并不真正需要的科技 MBA 的激增。

我们发布了一个新冠肺炎知识图表

原文:https://towardsdatascience.com/weve-released-a-covid-19-knowledge-graph-96a15d112fac?source=collection_archive---------44-----------------------

介绍 BioGrakn Covid

我们很高兴发布一个开源知识图表来加速对新冠肺炎的研究。我们的目标是为研究人员提供一种方法,方便他们分析和查询与病毒相关的大量数据和论文。

BioGrakn Covid 使快速追踪信息源和识别文章及其信息变得容易。第一次发布包括从新冠肺炎论文、和其他数据集提取的实体,这些数据集包括蛋白质、基因、疾病-基因关联、冠状病毒蛋白质、蛋白质表达、生物途径和药物

例如,通过查询病毒新型冠状病毒,我们可以找到相关的人类蛋白质,蛋白酶体α亚单位 2 型 (PSMA2),蛋白酶体的一个组成部分,涉及新型冠状病毒复制,和其编码基因( PSMA2)。此外,我们可以确定药物 carfilzomib,一种已知的蛋白酶体抑制剂,因此可以作为新冠肺炎患者的潜在治疗方法进行研究。为了支持这种关联及其含义的合理性,我们可以很容易地在新冠肺炎的文献中找到提到这种蛋白的论文。

通过检查这些特定的关系及其属性,我们被引导到数据源,包括出版物。这将有助于研究人员有效地研究冠状病毒感染和免疫反应的机制,并有助于更有效地找到治疗或疫苗开发的目标。

我们的团队目前由葛兰素史克、牛津制药(T21)和 Vaticle 组成

如何设置

在第一版中,我们将 CORD-19 论文与公开的带注释的分子数据集整合在一起。BioGrakn Covid 可通过 GCP 免费访问。您可以使用 Workbase 查询它:

  1. 下载并运行 Workbase ( 下载)
  2. 确保 Grakn 没有在你的本地机器上运行
  3. 在 Workbase 主屏幕上,使用端口 48555 将主机更改为本页显示的 IP 地址(链接)
  4. 点击连接,选择密钥空间 biograkn_covid 开始探索数据!

您还可以使用其中一个 Grakn 客户端(链接)进行编程连接。使用上面指定的 IP 地址、端口和密钥空间。

Github 上提供了迁移脚本和模式:https://github.com/graknlabs/biograkn-covid

要查看模式文件,您可以在这里找到这个。

数据集和见解

目前,我们集成的数据集包括:

  1. CORD-19 :我们纳入了原始语料库,其中包括来自 bioRxiv、medRxiv 和其他机构的同行评审出版物。
  2. CORD-NER :白宫发布的 CORD-19 数据集已经被标注并公开发布。它使用各种 NER 方法在远程或弱监管下识别 CORD-19 上的命名实体。
  3. Uniprot :我们已经下载了审查过的人类子集,并摄取了基因、转录物和蛋白质标识符。
  4. 冠状病毒:这是一个由牛津制药基于文献综述整理的冠状病毒及其潜在药物靶点的注释数据集。
  5. DGIdb :我们采用了相互作用 TSV ,其中包括所有药物-基因相互作用。
  6. 人类蛋白质图谱:正常组织数据包括人类组织中蛋白质的表达谱。
  7. 反应组:这个数据集连接通路和它们参与的蛋白质。
  8. DisGeNet :我们已经收集了精选的基因疾病关联数据集,其中包含来自 Uniprot、CGI、ClinGen、Genomics England 和 CTD、PsyGeNET 和 Orphanet 的关联。

我们计划添加更多的数据集!

我们可以运行的一些查询包括:

退回与基因相关的药物,与 SARS 相关基因在同一篇论文中被提及。

match 
$v isa virus, has virus-name “SARS”; 
$g isa gene; 
$1 ($g, $v) isa gene-virus-association; 
$2 ($g, $pu) isa mention; 
$3 ($pu, $g2) isa mention; 
$g2 isa gene; 
$g2 != $g; 
$4 ($g2, $dr); $dr isa drug; 
get; offset 0; limit 10;

BioGrakn Covid 包含一些规则,允许我们推断数据之间的关系。这在并非所有数据都完整的情况下特别有用。例如,BioGrakn Covid 的源数据不包括药物和蛋白质之间的直接联系。然而,我们可以从基因和药物、蛋白质和基因之间的联系中推断出这一点。当查询蛋白质和药物之间的联系时,Grakn 将自动推断,如下所示:

显示的推论是在药物“克唑替尼”和蛋白质“ALK”之间(实线),而解释是通过药物、基因和蛋白质显示的(虚线)。

你能帮上什么忙

这是一个正在进行的项目,我们需要你的帮助!如果您想做出贡献,您可以帮助我们,包括:

  • 迁移更多数据源(如临床试验、药物库、Excelra)
  • 通过添加相关规则来扩展模式
  • 创建网站
  • 撰写教程和文章,供研究人员入门

如果您希望取得联系,请通过#biograkn 频道与我们讨论我们的不和(链接此处)。

Ep 7:文化契合度

原文:https://towardsdatascience.com/wewillcallyou-ep-7-culturalfit-682aa09e3c05?source=collection_archive---------70-----------------------

我们会叫你

基于事实的求职——极客歌剧

作者图片

“正如你所看到的,我准备的原型检查了任务描述中列出的所有框。此外,我还编写了一个可视化模块,这不是必需的,但我认为它会自然地补充练习。”

当他伸手去拿一杯水时,多姆纳尔骄傲地笑了。他在过去的 40 分钟里试图总结一周紧张的原型准备工作。这项任务在概念上并不难,但它以其繁琐性弥补了这一点。提供的数据原来是一堆未经处理的互联网帖子——主要是口头放屁、打嗝和打嗝——互联网用户在社交媒体上激烈交流。Domnall 通过简单地清除不相关的字符簇、拼写错误和自我宣传装饰品的数据,损失了整整五天。在接下来的两天里,他构建了所需的分类器,并准备了一个演示文稿。

他感到筋疲力尽,但很满足。他提供了一个原型,任何咨询公司都可能收取相当于他 6 个月工资的费用。这足以证明他毫无疑问是有用的。他申请的公司可能也得出了同样的结论,因为他们跳过了与人力资源部门的面试,直接跳到了与软件开发团队负责人的会面。

“是的……是的……”桌子另一边的男人喃喃自语。“这种视觉化……很简单……”他低声说道,甚至没有抬头。他所有的注意力都被吸引到他正在笔记本上连续第四页上填写的潦草字迹上。“如果你愿意的话……并且回到……”他轻快地把最后一段。他抬头看了看,完成了:“……然后回到代码片段,在那里你链接了来自几个不同来源的已清除的帖子。”他给了多姆纳尔一点时间在剧本中找到合适的台词。“如果你要把这个演示给一个非技术人员,你会怎么做?”

多姆纳尔压抑着如释重负的叹息。当他听到他将与谁交谈时,他害怕关于代码优化的问题,他对此有一个相当模糊的想法。而技术经理决定测试他与企业的沟通技巧。对事态的发展感到满意,多姆纳尔脸上露出了耐心的微笑。

“想象一下,你正在和来自两个不同部门的两位经理交谈。他们带着不同格式的演示文稿来参加会议……”

“不,不是这样。”男人紧张地笑了笑。“我们的业务团队精通技术问题,没有必要进入如此高的抽象层次。”

多姆纳尔扬起了眉毛。

“这可能是一次有趣的经历。迄今为止,与我共事过的经理们通常都乐于看到与他们相关的例子。”

“在这里,我们有其他的需求。”

"那么我应该进入什么抽象层次?"

”解释您是如何组合这两个文本清理模块的输出的。根据你在这里的描述,它们似乎有不同的格式。”

多姆纳尔看着剧本,拍了拍额头。

“是啊。在第一个模块中,就在返回字符串之前,我使用这里调用的函数重新格式化它。多姆纳尔在屏幕上标出了正确的代码行。"由于这两个结果有相同的格式."

“这个功能在哪里?”

“在图书馆……我把它作为一个单独的文件附上了,”多姆纳尔不确定地回答,不知道他是在和软件开发部门的负责人说话,还是在和那个家伙扮演的商业幽灵说话。然而,他不敢向他指出,这种类型的问题来自那些更愿意对他的软件的应用感兴趣的人会有些…不寻常。

与此同时,这个人咬着嘴唇研究着代码片段。

“哦,”他最后说,“所以你只是合并两个清洁器的结果数据,然后把它作为预测器的输入?”

“正是。”

“太好了。”那人高兴地点了点头。“这就是我所需要的。非常感谢。”他从椅子上站起来,从桌子上拿起笔记本电脑和他的笔记本,避开对话者的目光,补充道:“我会将我们的谈话报告发送给人力资源部。”

多姆纳尔看着他。突然,他确信这里出了问题。他几乎绝望地喊道:

“为什么这个意见会是否定的?”

那人害怕地跳了起来。他惊恐地看了受访者一眼,握紧了电脑,就好像手中的设备突然变重了一样。

“嗯……你知道,”他结结巴巴地说,一边用眼角打量着他和门之间的距离。“每个公司都有其……呃……独特的文化。我的印象是,你不是最好的……嗯……合适吗?”

多姆纳尔咬紧牙关进行自我审查,因为他找不到任何可以对这个人说的话。缺乏文化契合是事实——他绝不会想到以如此生硬的方式盗用某人的作品。

“如果没别的事了,再见,”那人着急地说。庞大的赃物阻止他握手。“我们会打电话给你。”

我们将称您为系列:

第 1 集:数据民主化

第二集:刺激的工作环境

第三集:软技能

第四集:技能红娘

第五集:沉没成本

第六集:激情,更激情,录用!

第 7 集:文化契合度(当前)

多姆纳尔是个聪明的家伙。但是,找工作是长期的娱乐,很可能要花他一段时间。尤其是工作面试不是每天都有的。与此同时,你可以考虑阅读我们的 【药理】 社会学惊悚片中的其他(同样出色的)人物。

Ep 6:激情,更激情,录用!

原文:https://towardsdatascience.com/wewillcallyou-ep6-passionate-630b9fa68f0d?source=collection_archive---------78-----------------------

我们会叫你

基于事实的求职——极客歌剧

作者图片

“我看你理解业务流程,”经理冷漠地说。“我承认你的同事中几乎没有人关注他们。总而言之,我并不感到惊讶……”他遗憾地叹了口气,过了一会儿又高兴地补充道,“当技术革命无处不在,为新事物提供机会时,谁会愿意在这上面浪费时间呢?”

“现代分析面临的问题范围仍在扩大,”多姆纳尔同意道,“但在我看来,坚实的基础仍然至关重要。”

那人不听。他继续自己的思路,“你知道吗,即使是我们通常在实时上下文数据流处理中使用的量子机器学习工具,也无法应对预测值得关注的 IT 趋势?!"

多姆纳尔退缩了。部分原因是他不喜欢技术上的胡言乱语,部分原因是他将盲目追随潮流与社交媒体影响者之间争夺注意力的争斗联系在一起,而不是基于可靠数据的研究。

“当有人提出解决问题的新方法时,趋势就出现了,然后有人把它提升到灵丹妙药的高度,”他说。“恐怕在 IT 趋势预测中,你最好带上水晶球或阅读茶叶。”

“哈!爆笑!”经理嗤之以鼻。“我们使用区块链·美联储认知计算来预测哪些技术在未来可能会找到新的应用,”他几乎从椅子上站起来,自豪地说。

多姆纳尔第二次退缩。他的对话者似乎热衷于流行词,越多,他越不理解它们。通过这种方式,他已经浏览了他真正了解的商业话题,带着略微心不在焉的表情听着多姆纳尔的回答。当话题转到他不了解的技术时,他甚至坐不住了。

“但不是关于我们,而是关于你。这是我们的座右铭!”经理靠在椅背上。"具体来说,你为什么想为我们工作?"

“您运营领域的多样性…”

“是的!”那人向他伸出一根手指。“我们不仅处理结构化数据,还处理图表、自然语言处理、地理定位……”

多姆纳尔等着曼的气息耗尽,完成了他的思考,“我只是喜欢有机会处理各种领域的多层问题。”

“是的!”经理的手指又放在了多姆纳拉的面前。“你甚至无法想象我们为客户构建的深度神经网络有多少层!当我们向投资者展示我们在云中的超大规模数据科学竞争中遥遥领先时,他们非常高兴!它不再仅仅是一个数据湖。是一片海洋!”

经理愣住了,可能是在等掌声。Domnall 想知道如何让他明白,数据科学的质量既不是以 Pb 来衡量,也不是以神经网络的层数来衡量。

“我听说你也在政府机构工作,”他小心翼翼地开始说道。“我想这样的责任需要对结果进行一丝不苟的质量评估。我要补充一点,我在这个领域有一些成就……”

“你用什么库?”经理开始感兴趣了。

“看情况……”多姆纳尔困惑地眨了眨眼。到目前为止,他的对话者没有说任何表明他知道至少一个图书馆的名字。多姆纳尔傻笑。“大学图书馆,公共……”

“我们总是使用最新的库!不仅是公共的,还有商业的!”经理得意地笑了。“此外,我们始终使用最高效的服务器、最大的数据集和最新的元数据,因此我们的结果的可靠性毋庸置疑!”

“这无疑是对深思熟虑的分析的巨大支持,”多姆纳尔称赞道,努力不去问公司的工作时间是否也用世界上最快的手表来衡量。

经理看了看他的手腕,好像看出了他的心思。

“哦,时间过得真快!”他抓着自己的头,急忙补充道:“我还有最后一个问题。你对哪些技术领域充满热情?”

看到面试过渡到“爱好和兴趣”部分,多姆纳尔感到如释重负。他已经受够了专业人士。

“我猜太空旅行最多。真是太棒了…”

“哈!爆笑!”男人打断道。“但我指的是信息技术。”

多姆纳尔沉默了一会儿。他试图用排山倒海的行话来报复对话者,但最终,他决定表现出仁慈。他如实回答:

“让我兴奋的是发现真相。我对任何数据处理技术都没有感情上的依恋。让我兴奋的是,我发现了一些规则,让我能够足够准确地模拟现实,从而获得一些预测能力。”

经理瘫软了,就像一个充气玩具失去了空气。

“嗯……我们团队的人通常对数据更有热情,”他失望地嘀咕道。一秒钟后,他想起了那个礼貌的微笑,说道:“我们会打电话给你的。”

我们将称您为系列:

第 1 集:数据民主化

第二集:刺激的工作环境

第三集:软技能

第四集:技能红娘

第五集:沉没成本

第六集:激情,更激情,被录用!(当前)

第七集:文化契合度

多姆纳尔是个聪明的家伙。但是,找工作是长期的娱乐,很可能要花他一段时间。尤其是工作面试不是每天都有的。与此同时,你可以考虑阅读我们的 【药理】 社会学惊悚片中的其他(同样出色的)人物。

通过将尾部作为时间序列进行处理来识别鲸鱼

原文:https://towardsdatascience.com/whale-identification-by-processing-tails-as-time-series-6d8c928d4343?source=collection_archive---------24-----------------------

抹香鲸尾巴——参赛照片(凯捷全球数据科学挑战赛,2020 年)

使用积分曲率和动态时间扭曲,让我们深入研究抹香鲸识别!

语境

最近,我们和几个同事一起尝试了凯捷的全球数据科学挑战。与鲸鱼 Acores 研究中心合作,挑战的目的是识别抹香鲸,用人工智能帮助拯救抹香鲸的生命。为了这个任务,我们收到了几千张过去几年的鲸鱼照片。在训练数据集中,每只鲸鱼平均有 1.77 张照片,许多动物只出现一次。因此,主要思想是,给定一张新图片,在已经看到的数据中识别最接近的图片。这样,如果鲸鱼已经被拍照,研究人员就能知道拍摄的时间和地点。

我很自豪地宣布我们获得了第三名,一个使用连体网络的获胜解决方案。但是因为已经有很多关于这个奇妙架构的文章了,今天我将展示一个更有趣、更新颖的方法来解决这个问题

方法学

魏德曼等人在他们的论文“ 海豚和鲸鱼识别的积分曲率表示和匹配算法 ”中设计的,下面是我今天要介绍的方法论的关键步骤:

  • 基于颜色分析和轮廓检测的尾部提取
  • 具有积分曲率的尾部处理
  • 动态时间弯曲的尾部比较(DTW)

免责声明 1 :预测率不如暹罗网络,我们必须探索其他解决方案。但是想法很有意思,值得分享和了解。

免责声明 2: 和许多数据科学项目一样,数据准备是最困难的部分。事实上,要把尾巴当作信号来处理,信号的质量必须非常好。在本文中,我们将花时间了解信号处理的所有必要步骤。

让我们深潜吧🐳

探索我们的数据集,分析图片

正如在介绍中提到的,我们得到了几千张图片,这是很多要看的。乍一看,鲸鱼就是鲸鱼。所有这些照片看起来像蓝色背景(天空和海洋),中间有一个灰色斑点(尾巴)。

然而,在第一次探索之后,我们开始区分两种不同的抹香鲸,主要是因为尾巴的形状,并且确信这对我们的算法具有决定性意义。颜色呢?像素的分布有什么有趣的信息吗?

每张图片中颜色数量的相关性(绿色对红色—蓝色对红色—绿色对蓝色)

使用散景可视化库,我们很快发现图像中的颜色高度相关。所以我们专注于轮廓,试图通过颜色变化来检测它们。

基于颜色滤波器的尾部提取

检测尾巴轮廓的第一步是从天空和水中提取它们。实际上,这是整个过程中最困难的部分。

首先,我们使用轮廓检测算法。但由于每次拍摄的阳光都在不断变化,对比度变化很大,结果远不能令人满意。顺便说一下,看到算法最失败的图片很有趣,因为大多数时候,尾巴和大海之间的区别对人类来说是显而易见的。

也就是说,让我们深入研究颜色分析和轮廓提取自动化。

用颜色提取尾巴

让我们为每个通道强度(红、绿、蓝)绘制灰度图像

观察单个图像的三个通道

正如你在上面看到的,大多数图片都是如此,图片中间的颜色较少,允许按像素强度过滤。由于尾巴通常是灰色的,所以每种颜色的数量几乎相同(R = G = B),然而,海洋和天空往往是蓝色的,这使得这种颜色成为过滤的理想候选颜色。

让我们看看当只保留蓝色值,并且只保留blue_value < SELECTED_THRESHOLD.处的像素时会发生什么

这个SELECTED_THRESHOLD的最大值是 255,因为它是像素强度的最大值。

基于像素强度滤波的尾部提取处理

有了这一系列的图片,我们可以相信尾部提取是轻而易举的事情。但是我该如何选择过滤阈值呢?

下面是使用从 10 到 170(十乘十)的所有值作为单一图片的阈值的结果示例。

根据蓝色像素的强度,在一张图片上应用 17 种不同的滤镜

以下是一些有趣的发现:

  • 如果阈值很小(10 左右),海会消失,但尾巴也会消失
  • 如果阈值很小(20 左右),部分尾部会消失
  • 由于阈值不是很高(大约 40),提取看起来很完美。所有的尾巴都不如门槛蓝,但所有的大海都比门槛蓝。
  • 有了一个中间阈值(大约 80),尾部保持完整,但是我们开始保留海的一部分
  • 由于阈值几乎是中间值(大约 110),很难区分大海和尾巴
  • 阈值稍高(140 及以上),尾部完全消失。这意味着即使是大海也没有蓝到可以通过滤镜选择。

因此,我们在这里,似乎很清楚,我们应该采取SELECTED_THRESHOLD = 40和应用过滤器blue_value < 40

你可以猜到,这并不容易。给定图片的光强度,40 是该图片的正确值。但它从陈词滥调变成陈词滥调。通过在随机图片上绘制具有所有这些阈值的结果,阈值在 10 到 130 之间变化。那么如何选择合适的数值呢?

使用边界框选择阈值

通过查看前面的图片,我们想到了一些事情:具有正确阈值的正确图片是外部区域最空而内部区域最满的图片。希望在 ImageNet 上训练的一些神经网络可以在照片中定位鲸鱼。我们决定使用基于 ImageNet 类MobileNet

灰鲸,灰鲸,乌贼,大菱鲆,大菱鲆

一批提取的尾巴与原始图片相比,具有边界框

这是个很棒的主意。如下图所示,我们可以非常精确地识别照片中尾巴的位置。然后,我们可以在几乎所有的图片中将“尾部——内部”与“海洋部分——外部”分开。

带有边框的图片爆炸

为了更好地了解这种分离,对于训练集的每张图片,我们对边界框内每个像素的蓝色值进行求和,并对框外的像素进行同样的操作。

然后,我们在下图中绘制每张图片,X 轴表示内部结果,Y 轴表示外部总和。蓝线代表X = Y。从这个图形中我们可以得到如下的感觉:你离线越远,尾巴和大海就越容易分开。

给定边界框内外蓝色像素强度的抹香鲸图片的比较

我们尝试根据到线的距离来应用过滤器阈值,但这并没有导致任何结果。在几次尝试之后,仅仅根据图片的颜色分布,我们就放弃了,我们决定使用硬方法。我们不是看着图片决定阈值,而是对每张图片应用 15 个过滤器,分析它们,并自动选择最佳过滤器进行进一步处理。

然后,对于给定的图片,我们使用 15 个不同值的 15 个过滤器作为阈值。对于每个滤镜,我们统计了边界框内部和外部像素的数量(过滤后,像素值为 0 或 1,不再需要对亮度求和)。然后我们将结果标准化,使数字与图片的大小无关,并将结果绘制在图表上。

单个图片和不同过滤阈值的边界框内部(X 轴)和外部(Y 轴)的像素数。

对于每张图片,我们得到了一条类似于上图的曲线,这是我们之前关于阈值演变的陈述的数学翻译。

  • 当阈值很小时,尾和海消失。尾巴里面没有像素,外面也没有
  • 当阈值增加时,尾部出现,X 轴的值增加。
  • 直到门槛开始让海的某些部分出现,外面的价值开始增长。

使用线性回归或导数,现在很容易检测正确的阈值:它是图中两条线的交点。

注意:橙色线是y = y_of_the_selected_threshold

拔尾的最后一招

最后,为了在提取时获得我们的最佳图片,当我们计算出最佳阈值(在 10,20,30,40,…,120,130,140,150 之间)时,我们假设为 80。我们对-5/+5 值应用了过滤器。于是我们有了三张照片blue < 75blue < 80blue < 85。然后,我们将这三个网格图片(0 和 1)相加,只保留值等于 2 的结果像素。这将作为最后的过滤器,消除尾巴周围的噪音。这在整体上导致了更好的提取,我们决定应用于所有的图片。

结果

作为总结,以下是我们到目前为止所做的假设:

  • 我们可以使用蓝色像素强度的过滤器将尾巴从海洋中分离出来
  • 在滤波之前,要为每幅图片找到一个阈值
  • 使用包围盒是找到这个阈值的一种有前途的方法

经过几个(很多)小时的工作,我们最终得到了一个非常好的尾巴提取器,可以很好地处理不同亮度、天气、海洋颜色、尾巴颜色的尾巴,并能够处理最困难的图片。

一批提取出来的尾巴对比原图

轮廓检测

既然尾巴在图片中被定位,我们处理轮廓检测。事实上,要把尾部作为时间序列来处理,我们需要一个信号。

在这一步,我们可以使用 OpenCV 中的轮廓检测算法,但它似乎比以下两步更快:

第一步:使用熵去除尾巴周围的噪声

使用熵变化仅保留提取的尾巴的轮廓

第二步:为每列保留图片的高光像素

在应用熵过滤器之后,检测提取的尾部的轮廓

这一步非常简单,没有特别复杂的地方。可能是单身的那个;)

积分曲率

通过从海洋中提取尾巴,并获取图片的上部像素,我们得到了尾巴的后缘作为信号。现在我们有了这个,我们将不得不处理正常化。事实上,并非所有图片都具有相同的大小或像素数量。此外,到抹香鲸的距离并不总是相同的,拍摄时方向可能会改变。

尾巴方向的例子,在同一条鲸鱼的两张照片中可能有所不同

对于归一化,我们必须沿着两个轴来做。首先,我们决定用每条尾巴 300 个点来进行信号比较。然后我们对最短的进行插值,对最长的进行采样。第二,我们将 0 到 1 之间的所有值标准化。这导致了信号叠加,如下图所示。

缩放信号叠加

为了解决方向问题,我们使用了积分曲率度量,通过局部评估将信号转换为另一个信号。

正如在原始论文中提到的:“它在沿后缘的每一点捕捉局部形状信息。对于位于后缘的给定点,我们在该点放置一个半径为*r*的圆,并找到后缘上位于该圆内的所有点。”

然后,在每一步,我们拉直圆圈中信号的边缘,使其内接在一个正方形中。

积分曲率原理

最后,我们将曲率定义如下:

曲率是曲线下的面积与正方形的总面积之比,这意味着直线的曲率值为 c = 0.5

我们由此获得了标准化的信号,与鲸鱼和摄影师之间的距离无关,与鲸鱼和摄影师之间的角度无关,与鲸鱼和大海之间的倾角无关。

对于训练测试的每张图片,我们随后在 IC 相位期间为半径为 5、10 和 15 个像素创建这些信号。我们存储它们并用于最后一步:时间序列之间的比较。

在本文中,我将忽略这种算法的实现。一旦成功,我们可以把它应用到我们的后缘,从环境细节中提取信号。对于单个尾巴,它看起来像下面的信号。

用 3 个不同的半径值应用于抹香鲸后缘的积分曲率

现在,让我们进行信号对比!

动态时间扭曲

动态时间扭曲 (DTW)是一种能够找到两个时间序列之间最佳对齐的算法。它通常用于确定时间序列的相似性、分类,以及寻找两个时间序列之间的对应区域。

DTW 距离与欧几里得距离(指两条曲线之间的逐点距离)相反,它允许链接曲线的不同部分。算法是这样工作的:

  • 使用两条曲线,我们创建两个系列之间的距离矩阵,从左下角开始直到右上角,并计算两点之间的距离Ai (from serie A) and Bi (from serie B)如下:D(Ai, Bi) = |Ai — Bi] + min(D[i-1, j-1], D[i-1, j], D[i, j-1])
  • 当满足距离矩阵时,我们计算从右上角到左下角的权重较小的路径。为了做到这一点,在每一步我们选择具有最小值的正方形。
  • 最后,所选择的路径(下图中的绿色)表示来自系列 A 的哪个数据点对应于来自系列 b 的数据点。

DTW 解释——来自这个【YouTube 视频的幻灯片

这种基本计算的实现非常容易。作为一个例子,这里有一个从两个序列st创建距离矩阵的函数。

Python 在 DTW 上的基本实现

话虽如此,让我们回到我们的抹香鲸!我们数据集的每个尾部都转换成一个“积分曲线信号”,我们计算所有尾部之间的距离,以发现哪些是最接近的。

之后,当接收到一张新图片时,我们必须让它通过整个准备管道:用蓝色过滤器提取尾部,用熵方法检测轮廓,用 IC 进行轮廓变换。这给了我们一个300x1 shaped tensor,我们最终必须计算整个数据集的距离。顺便说一句,这很费时间。

结论:结果相当不错!当我们有同一条鲸鱼的两张照片时,在大多数情况下,这两张照片都在最接近的 40 位,这在 2000 张照片中是很棒的。然而,正如在介绍中提到的,使用暹罗网络的结果优于(图片通常在最近的 5 个中)这一个,并且考虑到比赛的时间,我们必须在我们的调查中进行选择;并且没有继续使用这种方法。

额外收获:用一半尾巴和一半信号工作

我们试着用半尾来工作,假设:

  • 尾巴是对称的,这将简化计算。
  • 尾巴是不对称的,这将允许通过半个尾巴进行比较。

尽管进行了无数次测试,但这并没有给我们非常确定的结果。我们认为我们的分离不够可靠:我们需要更多的时间通过信号处理来研究更好的分离。

最后的想法

由于图片的颜色(基本上是蓝色——海洋和天空)以及来自数据集的图片的各种亮度,在尾部提取上花费了一些时间(这比我们想象的要困难),我们对尾部识别应用了两个连续的处理。首先是积分曲率,这是一种通过观察曲线的局部变化来归一化信号的方法。然后,我们使用动态时间扭曲,这是两条曲线之间的距离计算,即使两条曲线被移动,也可能发现它们之间的相似性。

不幸的是,结果并不像我希望的那样好,我们无法继续这个解决方案。随着更多的时间和更多的努力,我深信我们可以改进流水线的每一步,从而得到一个更好的模型。然而,我真的很喜欢这篇文章和这些概念。由于所有的步骤、实现它们的不同方式以及参数,监视所有的转换是相当具有挑战性的。因为我们有一个路线图,每一步都有自己的困难,每一个小小的成功都是一个胜利,开启了下一步。这非常令人满意。

我发现这种方法非常有趣,与通常的预先训练好的 CNN 完全不同。希望您也喜欢这种方法的美妙之处,这也是本文的主题。如果你有任何问题,请随时联系我😃

参考文献

200,000 年的人类教会了我们如何用数据讲故事

原文:https://towardsdatascience.com/what-200-000-years-of-humanity-taught-us-about-data-storytelling-919f0a44215b?source=collection_archive---------38-----------------------

数据科学家也是一个高效的沟通者,他将数据带入生活。

用您的数据故事吸引您的受众,并帮助他们理解您的见解。[图片由 Sasin Tipchai 提供]

在古代,20 万年前,人们围坐在篝火旁,通过故事相互学习经验。我们的祖先互相教导如何控制火势,如何捕猎动物,什么该吃,什么不该吃。这些故事通过从他人的成功和失败中学习来提升人类的知识。

古埃及艺术包含了关于过去发生的事情的故事,这些故事代代相传。他们如何建立他们的帝国,他们使用什么工具,他们认为什么是重要的。即使在今天,我们也可以从绘画中了解人类的历史。

古埃及艺术[来源于维基百科

今天,最吸引人的 TED 演讲和票房最高的电影都是以讲故事为基础的。与我们产生共鸣的故事,将想法带入生活的故事,连接观众的故事。

讲故事和时间一样古老,它在每个文化和社会中都有一席之地。这是一种有效的方式,可以从对方身上学到最重要的东西。

在这个大数据时代,这是我们相互学习的方式——讲述数据故事。数据叙事有三个至关重要的基础:数据、可视化和叙事。

数据叙事的 3 个基础:数据、可视化和叙事

#1.收集和清理您的数据

在你讲述任何数据故事之前,你需要数据。如果你在一个组织、一个班级作业或一个 Kaggle 数据集工作;你有数据。你得弄清楚你想讲的故事是什么。

如果你还没有数据,你必须在收集数据之前定义你的假设。你的假设应该是可测量的和清晰的。这将引导您找到或收集合适的数据集进行分析。尝试搜索一个可能回答你关键问题的开源数据集。然而,如果你的问题是小众的,你必须建立你的数据收集系统。

在从数据中提取任何见解之前,您必须确保数据是正确的。这个过程被定义为 数据清理 。通常,您希望清理不完整、不准确、不一致和重复的数据;才能得到准确的结果。

识别不良数据

想象一下,如果有人在你的演示过程中发现了一个错误,那会让你的工作不那么可信。例如,如果你有一个包含人类年龄的数据集,如果某人已经 5000 岁了,那就没有意义了。您可能需要先删除它们。

识别缺失值

缺失值可以表示为空值或超出范围的值,如人类年龄的“-1”或“-99”。你的工作是识别和处理这些缺失的值。您可能必须删除缺少太多值的列或行。

寻找异常值

这些数据点包含超出正常范围的值。与坏数据不同,离群值是有效的。例如,在西雅图 Airbnb 数据集中,有 1 个主机将最低租赁夜数设置为 1000。它可能提供有趣的故事和见解,但也可能扭曲你的结果。你必须识别并决定如何处理这些类型的数据。

#2.用可视化检查数据

这部分俗称探索性数据分析,简称 EDA。在这里,当你着手研究你所拥有的数据时,你会问自己一些问题。你将分析特征,寻找特征之间的模式和关系。

寻找趋势

如果您拥有的数据由时间变量组成,您可能会有兴趣了解变量随着时间的推移是增加还是减少。可视化趋势的最简单方法是绘制一个折线图。

有时,一个特征可以有一个循环模式。例如,假期期间航空旅行的乘客数量会增加,一年的降雨量因季节而异。

折线图可以显示一段时间内的趋势

价值分布

对于数字特征,您可能希望找到变量的范围。这使您能够知道特征的最小值、最大值、平均值和中值。它还能告诉我们数据是左偏还是右偏。显示分布的常用方法是使用直方图。

条形图对于可视化分布很有用

直方图还可以识别异常数据和默认值。例如,您可以提取那些具有巨大建筑面积的房屋和具有-1 默认值的变量。

左图:最右边栏是一些建筑面积巨大的房子。右图:年龄为-1 的若干人。

特征之间的相关性

寻找两个或更多特征之间的相互关系是有价值的见解。它通常很有趣,可以帮助你的观众了解一些他们可能不知道的东西。例如,在这项研究中,研究人员发现,眼疾与日照时间呈正相关。这很有趣。

显示相关性的有用图表是散点图。还可以添加一条拟合线,检查是正相关还是负相关。

检查两个变量之间相关性的最简单的形式是使用散点图

了解特征之间的相互关系有助于构建更好的预测模型。如果两个特征高度相关,您必须仔细检查,因为这可能是重复数据的结果。如果一个特征与你的目标标签高度相关,那么这个特征可能是重要的。

“一图胜千言。”这是常见的口头禅,但当谈到数据可视化时,数千字可能不足以让人们理解。— 古平顺

这让我想到了下一点,你需要一个故事来传达你的发现。

#3.通过叙述传达见解

有用的数据集和漂亮的可视化并不能构成一个好的数据故事。一个数据故事只有在为受众提供价值的情况下才会引人注目。它允许他们学习新的东西,或者提供一个新的视角来做出更好的决定。或者至少,你的观众可以理解你在做什么。

你的叙述应该通过你的洞察力引导观众,并帮助他们跟随你的思路。使用叙述和视觉化的数据来支持你的故事是非常强大的,因为它增加理解和记忆,并且它是引人入胜的

理解

在你的故事中使用视觉化可以让你的听众看到数据变得栩栩如生。我们的大脑天生更擅长识别图案和颜色,而不是原始数字。帮助你的观众看到数据将有助于他们理解它。

保留

通过结合叙述和想象,它帮助你的观众记住你的内容。这样做,你可以有效地向你的听众提供分析和情感体验。巩固你传递的信息。

迷人的

你的听众需要他们应该听你讲话的理由。使用叙述可以帮助他们将共享的数据联系起来,以及为什么这些数据对他们很重要。如果你能为你的观众设计出符合他们兴趣和目标的故事;他们会关注你的故事。

一个伟大故事的线索

安德鲁·斯坦顿是一名电影导演,曾参与《玩具总动员》、《海底总动员》和《怪兽电力公司》的制作。他在这个 TED 演讲中分享了他在讲故事方面的发现。他解释了伟大的故事如何吸引观众,以及我们如何联系彼此的经历。

[## 数据科学家:21 世纪最肮脏的工作

40%的吸尘器,40%的看门人,20%的算命师。

towardsdatascience.com](/data-scientist-the-dirtiest-job-of-the-21st-century-7f0c8215e845) [## 西雅图的 Airbnb 数据分析

了解西雅图的 Airbnb 租赁情况

towardsdatascience.com](/airbnb-in-seattle-data-analysis-8222207579d7)

一段感情 5 年后的信息是什么样的

原文:https://towardsdatascience.com/what-5-years-of-a-relationships-messages-look-like-45921155e3f2?source=collection_archive---------25-----------------------

或者,用 Python 处理时间序列数据(和表情符号)的一些很酷的方法

来源:Pexels(不是我女朋友)

当政府强制实施的封锁进入第三周时,我的女朋友做了一个随意的评论:“我打赌我们的信息发送量正处于历史最低点…”

这是一个足不出户的数据科学家不会长久忽视的言论。所以我打开 丨t丨e丨l丨e丨g丨r丨a丨m丨s丨 的桌面应用程序,下载了我们的全部信息历史。输出以 HTML 文件的形式出现,每个文件包含 500 条消息的数据(有超过 160 个这样的文件)。令人高兴的是,人们可以使用一般网络搜集的技术——特别是各种 BeatifulSoup4 方法——来自动创建数据帧,其中每行代表一条消息。

我不记得当时我们在谈论哪个美国人了…

注意—这里的一个关键特性是时间戳列。对于我们将在后面使用的 Pandas 方法来说,重要的是它的类型是‘datetime ’,而不仅仅是一个字符串。使用 Pandas 的内置 to_datetime 方法很容易实现这一点:

df[‘Timestamp’] = pd.to_datetime(df[‘Timestamp’], dayfirst=True)

电报 HTML 使用 dd/mm/yyyy 格式给出其时间戳。因此,我们传递了 'dayfirst' 参数,以确保这是字符串的解释方式(即 2020 年 5 月 4 日应该是 4 月 5 日,而不是 5 月 4 日)。

那么我们可以用这个数据集做什么呢?我们当然可以尝试一些 NLP 工作(这可能是未来博客的主题——我对我们在一起的时间里我们的词汇是如何融合的有一定的假设…)现在,让我们简单地想想如何可视化我们的时间序列数据,以及如何最好地呈现这样的可视化以实现洞察力的提取。

让我们首先通过创建一个每天发送的邮件的折线图来调查我们的邮件量在过去五年中是如何发展的。Pandas 提供了一种内置的方法,允许我们按给定的时间间隔(例如,每天的消息计数)聚合数据。

df.set_index('Timestamp').groupby(pd.Grouper(freq ='D')).count()

这里有几个链接的方法—让我们来分解一下:

  • 。set_index('Timestamp') 首先,我们需要有 datetime 特性作为我们的索引。
  • 。groupby(pd。Grouper()) 这就像一个 标准的熊猫 groupby 一样,但是它不是为列中的唯一项创建一个索引,而是为样本中“最小”和“最大”日期之间(包括这两个日期)的天数创建一个索引。至关重要的是,这也为数据集中没有考虑到的日子创建了行(例如,因为我们在某些日子没有交换消息)。
  • 频率='D' 这个频率不一定是“天”——我们可以将它设置为任何我们想要的间隔(M 代表月,等等。)
  • 。像标准的 groupby 一样,我们需要调用一个聚合方法来创建实际的 dataframe。

那么这在标准折线图中是什么样的呢?

基本上是一团糟。

如果我们以每天的总字数为基础来看,这并没有真的好到哪里去(也就是说,我们的数据并没有受到我将句子中的每个子句作为单独的消息发送的明显令人讨厌的倾向的影响)。

然而,我们可以从这些图表中得到一些信息:

  • 我们通常保持在大约 150 条消息或 600 个单词的上限内
  • 我们发了很多关于我们分开度过的两个圣诞节的消息(2015 年和 2016 年的两个高峰),而不是关于我们一起度过的圣诞节的消息(2017 年、2018 年和 2019 年)
  • 随着时间的推移,我们相互发送信息的总量似乎并没有改变那么多

让我们更深入地研究最后一点。图表显示,尽管五年来每天的消息量有一个相当稳定的上限,但它们每天都在剧烈波动(我们一天交换 500 个单词,第二天为零)。

我们可以通过使用滚动平均值来稍微清理一下这个问题——换句话说,给定一天的值计算为过去 x 天的平均值。这意味着,理论上,我们上面非常参差不齐的图应该变得平滑(特别是当我们增加窗口宽度时, x )。这应该能揭示任何潜在的趋势。

熊猫对此有一个简便的方法:

df[‘WordCount’].rolling(window = x).mean()
  • 我们可以改变 x 来设置窗口宽度
  • 我们不需要使用平均值——我们可以查看滚动总和等。
  • 这将创建一个与原始序列长度相同的新序列,但是其中第一个 x -1 元素是 nan

现在让我们看看每天交换的总字数,在发送者之间分开,窗口宽度增加(一周、四周和八周)。让我们再添加两条红色垂直线来显示:

  1. 我们同居时(2017 年 4 月)
  2. 当我们搬到城市,我开始在家学习(2019 年 5 月)

56 天滚动平均线开始让一些事情变得更加清晰:

  • 在我们搬到一起住之前,我们每天都要说更多的话(第一条红线的左边)
  • 我的女朋友每天发送的文字一直比我多
  • 然而,当我们搬到不同的城市,她开始处理一个要求更高的客户项目时,她的消息量下降到了我的水平——她有更少的时间进行正常水平的消息传递,但显然当我发送一些东西时,她仍然足够体贴
  • 时间序列最右边的封锁确实导致了我们每天交流的字数急剧下降…

当然,现代信息不仅仅是你交换的词语(2015 年牛津词典年度词汇成为表情符号是有原因的)。令人惊讶的是,电报 HTML 最初的刮擦居然保留了原始表情符号。

原生 Python 无法处理这些字符,但是有一个简洁的小软件包(想象中称为“表情符号”)可以让你识别、计数和解码字符串中的表情符号。

如果我们调查“非文本”信息,我们会发现表情符号对我女朋友来说是一种特别重要的交流方式。另一方面,我通过分享照片和链接(通常来自 Reddit)以及贴纸(丨t丨e丨l丨e丨g丨r丨a丨m丨s丨 相对较早推出的一项功能)来增加价值。

我们可以尝试使用相同的滚动平均技巧来查看这些非文本消息的数量如何随时间变化。然而,除了 2018 年初的贴纸高峰(当我们发现你可以下载定制集——真的,这是一个改变游戏的时刻),没有多少可辨别的模式。

相反,让我们建立一个图表,按类型显示这些非文本消息的累积。为此,我们可以使用 NumPy 的 cumsum()方法,该方法将对一个序列进行累加求和。假设我们有一个数据帧,其索引是一个日期范围,每一列描述了当天发送的每种类型的消息的数量:

**#Create a list of message types**
required_cols = ['Emoji','Photo','Sticker','Link','Voice message','Animation']**#Create a new dataframe of just these types**
df_types_cum = df_types[required_cols]**#Iterate through the columns and replace
#each with the cumulative sum version**
for i in required_cols:
    df_types_cum[i] = np.cumsum(df_types_cum[i])**#Use Pandas' in-built plot method to show it**
df_types_cum.plot.area(figsize=(15,6), lw=0)

这产生了下面的图表。

同样,我们可以看到贴纸(琥珀色部分)的引入和使用,以及从 2018 年起表情符号的使用加速。

我们之前的分析没有涉及到的是我们共享消息的时间(只有每天的数量)。对此的想象可能会很快变得非常混乱。一天已经有 24 小时了,如果我们想看看是否有其他指标的差异(例如,一周中的某一天,一年中的某一天,等等)。)然后,我们突然有了大量需要在一个图表中传达的视觉数据。

热图让我们可以相当灵活地做到这一点。在这里,我创建了一个数据帧,显示了我们开始共同生活之前和之后一周中每天每小时发送的单词量(使用 Pandas 的 pivot_table 方法):

df_times = pd.pivot_table(df,fill_value=0,
               index=['LivingTogether','Day'],
               columns='Hour',
               aggfunc='sum')['WordCount'].T**#Note - the .T at the end of the code transposes the dataframe**

然后,我可以通过将数据帧的两部分除以不生活和生活在一起的适当周数,得到每小时发送的平均字数。然后,我们可以使用 Seaborn 的热图功能来可视化数据帧。

sns.heatmap(df_times)

添加了一些垂直和水平线来区分工作时间和周末,我们可以很容易地从热图中提取视觉信息。在搬到一起住之前,我们一整天都在不停地发信息,尤其是在睡觉前(周五和周六的浅色方块表明我们更有可能在对方家里过夜)。

搬到一起住后,我们发现我们的信息交流仅限于工作时间。有趣的是,在一天中的这个时候,信息的数量实际上增加了。我们还可以看到,这段时间我们的就寝时间大大改善了——凌晨 1 点前发信息的日子已经一去不复返了。

感谢你一直读到博客的结尾!我很乐意听到任何关于上述分析的评论,或者这篇文章涉及的任何概念。欢迎在下面留言,或者通过 LinkedIn 联系我。

650 万条#冠状病毒推文和深度拓扑分析揭示了疫情期间人们的想法

原文:https://towardsdatascience.com/what-6-5-million-of-coronavirus-tweets-and-deep-topological-analysis-reveal-about-peoples-3354b7442690?source=collection_archive---------57-----------------------

我们将拓扑数据分析和深度学习应用于大量文本数据,以揭示讨论中隐藏的模式

  • 使用深度拓扑分析分析了 650 万条关于#冠状病毒的推文
  • 以美国为中心的主题主导了讨论
  • 每有 1 条推特遭到反对,就有 20 条赞成封锁
  • “感谢关键员工”是最高的积极情绪,其次是朋友和生日
  • “呆在家里,拯救生命”占据了负面情绪的首位,因为人们抱怨其他人不遵守规则
  • 短时间内# cancelstudentdebt****hashtag 是最突出的峰值
  • 数据集可从 下载

问题是

文本分析是一项复杂的任务,尤其是当我们谈论大量文本时。与数字数据不同,在我们能够提取任何洞察力之前,文本需要以需要大量计算和复杂模型的方式进行转换。

这些信息应该以简单的形式呈现给用户进行分析。用户应该能够与平台交互并快速理解数据。

在这篇文章中,我用 Twitter 数据做了一个例子,但是同样的方法也应用到了用户评论、公司文件或者新冠肺炎科学论文上。

[## 利用拓扑文本分析迎接新冠肺炎公开研究挑战

我对新冠肺炎·卡格尔挑战科学白皮书的分析。这项研究是帮助……

towardsdatascience.com](/using-topological-text-analysis-for-covid-19-open-research-challenge-184d44bb92a6)

解决方案

DataRefiner 是一个简单而强大的平台,用于分析复杂的数据,如客户活动、物联网中的传感器或文本:

[## 物联网、用户活动或文本的数据分析和细分平台

DataRefiner 是一个数据分析平台,有助于理解来自传感器、用户活动或文本的复杂数据…

datarefiner.com](https://datarefiner.com/)

其核心是深度拓扑分析,这种方法不同于传统的商业智能工具,允许以易于理解的形式显示复杂的多维数据。

拓扑结构的三维投影

拓扑分析与深度学习和语言模型如 BERT 一起为文本分析提供最佳结果。它有助于将单词分割成主题,并显示主题之间的联系。

#冠状病毒数据

在新冠肺炎疫情几个月后,我们在 DataRefiner 平台上使用深度拓扑分析(DTA)分析了#冠状病毒标签下的 6 556 683 条推文。如果你想亲自尝试一下,可以从 https://datarefiner.com/feed/covid-twitter下载数据集——2020 年 3 月 8 日至 4 月 24 日期间发布的英文推特消息。

每小时的推文数量。人们在 3 月份谈论#冠状病毒的次数比 4 月份多得多

650 万条推文的拓扑图

当我们将数据集上传到 DataRefiner 平台时,它自动创建了一个推文拓扑图,图上的每个点都至少是一条推文或许多内容非常相似的推文。虽然该系统以完全无人监管的方式分割数据集,但分析师能够放大单个或一群推文,以更好地理解结果。

冠状病毒标签下 650 万条推文的拓扑图

所有的推文被分割成 30 个主题,你可以在地图上看到,加上 170 个主题,全部分组在“一般讨论”集群中。地图上聚类的大小反映了主题的受欢迎程度。相邻的聚类具有相似的内容和关键词。类属类位于结构的中心,而特定和不常见的内容位于边缘。

最大的集群“一般讨论”包含许多较小的主题,这些主题不包含任何特定的关键字集,因此很难分割。

用于文本分析的 DataRefiner 用户界面

转发

大多数转发都在“新闻:特定患者/病例”群中,其中包括关于鲍里斯·约翰逊(英国首相)和其他确诊病例的新闻。

情感分析

Twitter 情感分析是一个受欢迎的请求,我们在 DataRefiner 平台上提供情感分析。毫不奇怪,“感谢关键员工”占据了积极情绪的首位。

带有以颜色表示的情绪积极参数的拓扑图

如果我们放大,这是人们在推特上说的话:

所选聚类中最具代表性的推文显示在文本摘要选项卡下,供用户查看。

DataRefiner 情绪分析提供 3 个级别:(负面、中性和正面)。为了比较所有集群的情绪,我们在条形图上绘制了相对积极的分数。通常,中性情绪是最常见的,所以平均积极情绪值在 28%左右是一个相当不错的结果。

不幸的是,或许正如新冠肺炎的话题所表明的那样,负面情绪的水平明显高于正面情绪。

呆在家里——保持安全

' '呆在家里—保持安全'的主题出现在负面情绪的顶端。原因之一是人们指责他人违反封锁规则的多条评论。此外,看起来系统接收到了一些评论员支持锁定消息的被动攻击语气。

“呆在家里—保持安全”聚类分析

特朗普总统/ 副总统便士

围绕特朗普总统经常有激烈的讨论。要么是自由派指责政府,要么是保守派指责自由派。无论哪种方式,它总是变得非常混乱:

“特朗普总统/彭斯副总统”聚类分析

赞成锁定/反对锁定讨论— 主动学习案例研究

在这个分析中,我们想知道有多少人赞成一级防范禁闭,多少人反对。

以下是几条反对封锁的推文:

原推文

原推文

专业锁定示例:

原推文

原推文

主动学习

正如你从上面的推文中看到的,这些例子中的语言可以有很大的不同。事实上,关于这个话题有着更加活跃的讨论。仅仅使用拓扑和聚类是不可能区分这两个类别的,所以我使用了监督机器学习。

为了加快这个过程,我使用了一种主动学习的方法:

  1. 用户向大量初始样本添加标签;
  2. 分类器学习模型并将其应用于其余数据;
  3. 分类器识别最不确定的新样本,并要求用户对它们进行分类。

这个过程重复进行,直到模型学习到一个好的表示。这种方法有助于用户专注于最具挑战性的样本,并加快训练速度。下面的图表解释了这种方法:

主动学习的图示过程。资料来源:blog.cloudera.com

地图上的结果

令我们惊讶的是,大多数赞成锁定的讨论都发生在“呆在家里—保持安全”集群中,这是我们之前讨论过的。在这种情况下,拓扑方法能够以无监督的方式自动识别与 pro-lockdown 相关的语言:

拓扑图上覆盖的预锁定参数值

为了证明这一点,我们可以将其绘制为每个集群的条形图:

…作为对比,与针对锁定的推文相关的图表:

请注意,这些图的坐标轴刻度是不同的。与普遍看法相反,反对一级防范禁闭的推文比支持一级防范禁闭的少得多,几乎是 1 : 20。如前所述,反对和支持封锁的推文被分组在同一个集群“呆在家里——保持安全”。

一段时间内的讨论

这项研究的另一个重要部分是确定每个集群的趋势以及它们如何随时间变化。在这一部分中,我们从分析中移除集群“一般讨论”,并关注由我们的拓扑结构提取的主要主题。这些讨论的堆积面积图如下:

这是所有 30 个集群在 1.5 个月的数据中每个集群的相对 tweets 数。你可以看到讨论中有很多峰值。下面是一个替代视图,显示了最高峰值注释的折线图:

这里发生了很多事情,所以让我们分别回顾其中的一些集群。

除了名为“纽约的紧急情况”的集群之外,这里还记录了其他紧急情况。其中之一是与解除对也门的封锁有关的重大突破:

美国疾病控制和预防中心(CDC)在公共沟通和应对危机方面发挥了重要作用:

大多数时候,关于心理健康的讨论相对平静,然而有几个小时,讨论出现了明显的高峰,与 it #cancelstudentdebt 标签相关。这代表了整个分析期间所有集群中最突出的峰值:

世卫组织(世界卫生组织)是联合国的一部分,并在疫情期间发挥了重要作用:

与世卫组织和联合国行动有关的讨论反映在许多其他群组中,但大多数重叠出现在“特朗普总统/彭斯”群组内。特朗普总是在推特上讨论,这里有很多趋势和副主题。我强调了两个最重要的问题:

英国最重要的活动高峰都与鲍里斯·琼森(Boris Jonson)被检测为阳性以及后来他的住院和重症监护治疗有关:

结论

现代自然语言处理和深度拓扑分析的出现让我们对 Twitter 数据挖掘这一热门任务有了新的看法。文本数据包含大量信息,允许用户访问和理解这些信息非常重要。

市场上没有其他方法可以让用户处理如此大量的数据,同时为这些复杂数据集的分析提供如此逼真的视觉效果。这项技术已被证明能为许多行业带来非凡的效果。

原文:

DataRefiner.com 是一家总部位于英国的公司,专注于复杂数据的分析和细分,如用户活动、传感器或文本。DataRefiner 平台是本文讨论的多年提炼方法的结果,但它被广泛应用于各种行业,包括航空、社交网络、欺诈检测等。如需了解更多关于您所在行业的信息,请通过 ed@datarefiner.com 联系我们

机器学习硕士(不会)教你什么

原文:https://towardsdatascience.com/what-a-masters-in-machine-learning-wont-teach-you-b84e5aac8837?source=collection_archive---------61-----------------------

观点和经验

关于攻读机器学习高级学位的常见误解

马修·费尼在 Unsplash 上的照片

介绍

本文向您展示了机器学习中的一些方面和误解,这些方面和误解不一定在高级学位中教授。

这篇文章的内容是基于我的经验,所以一定要考虑到你和其他人的经验可能与我的不同。

尽管如此,享受阅读。

机器学习作为一个学术领域仍然越来越受欢迎,我们可以观察到这一点,因为越来越多的大学和机构允许本科生和学者进入机器学习相关的主题。

攻读机器学习的高级学位可以获得丰富的知识。我也是这么想的,并在 2018 年攻读了计算机视觉和机器学习硕士学位。

在我的学习中获得的理论和实践知识中,有一些学习和发展的关键方面,我认为是能够在商业工作环境中成为一个积极的组成部分所必不可少的。

软件工程

软件工程是一种方法论,它由一组应用于软件开发的原则组成。软件工程原理的例子有分析、设计、测试和实现。

在 2020 年,将软件工程作为一项技能是任何严肃的开发者的基本需要。很多人可能会错误地认为软件工程始于编程或拥有编码技能。但是所有技术领域的经验丰富的开发人员将证明这样一个事实:软件工程更多的是一种实践而不是一种技能。

不幸的是,软件工程不是大多数高级机器学习学位都会教授的技能。

在机器学习的理学硕士课程中,有足够多的内容可以涵盖。有些课程根本没有足够的时间来研究如何开发利用机器学习技术的系统和应用程序。

在我的理学硕士学习中,有软件工程的背景,加上对一些编程语言的了解是必须满足的先决条件。

为什么理解软件工程至关重要?

如果你了解卷积层的内部工作原理,或者能够详细描述各种神经网络架构,那就太好了。

然而,事实是,在现实世界中,机器学习模型存在于 python 脚本和笔记本之外。

你将在学业结束后从事的商业产品以网络、桌面和移动应用的形式出现。作为一名机器学习实践者,了解开发具有嵌入式机器学习模型的软件的标准方法对你的成功至关重要。

在我目前作为一名计算机视觉工程师的角色中,被证明有用的最重要的技能是我掌握新的 OOP 编程语言和开发软件的能力,更具体地说,是 iOS 应用程序。

机器学习模型可以存在于各种系统中,但所有这些系统都有一个标准的方法来开发和维护它们。软件工程教你这些方法。软件工程也充斥着指导软件开发和维护过程的原则,例子有OOP 等。

下面是一个快速、友好的软件工程原理介绍视频。

领导力

塞缪尔·佩雷拉在 Unsplash 上拍摄的照片

机器学习的领导有多种形式。

对我来说,机器学习中的领导力是指导产品、技术或工具的工作和进展的能力,朝着更好地服务于更广泛的社会并创造积极影响的方向发展。

机器学习领域有明显的领导者,他们在 Medium、Twitter、YoutTube 等社交媒体网络上积累了大量追随者。

他们的大量观众通常是他们在机器学习领域的影响和贡献的结果。

机器学习领域的领导者或影响者不是一夜之间形成的,他们的地位是多年来,有时是几十年来在他们选择的专业领域不断学习和工作的结果。

任何被认为是机器学习领域的影响者或领导者的人几乎都是高智商的人,并且在他们的领域内拥有无可匹敌的专业知识。

机器学习的领导力不是简单的教出来的。它是数小时的学习、工作和对该领域的贡献的积累,再加上一个人学术和职业生涯中的经验教训。

这里有一些我渴望效仿的机器学习领域的领导者和有影响力的人的名字,有些名字你可能很熟悉:

人工智能

你不会在你的理学硕士研究中建造天网,以后也可能不会。

有一个常见的误解,即理解机器学习方面的能力与一个人能够开发高级通用人工智能的可能性相关联。

就我而言,我陷入了这种误解,因为我认为,如果我在学术层面上理解机器学习,我就可以制造出与托尼·斯塔克(Tony Stark)的贾维斯(Jarvis)相媲美的个人助理。

图片来自 indian2web.com

事实是,机器学习的理学硕士揭示了人类在开发能够学习的独立系统方面已经走了多远。然而,更重要的是,理学硕士研究让你意识到,我们还没有触及这个领域的表面,以及突破和进步带来的可能性。

请记住,人工智能作为一个领域只有大约 64 年的历史,人工智能这个术语是在达特茅斯学院的一次会议上正式引入的。我们还有很长的路要走,成为旅程的一部分总是令人兴奋的。

结论

最后,我将总结一下这篇文章的要点。我希望读者理解以下内容:

  • 软件工程在机器学习行业中很重要。了解开发软件的基本原则将为您提供开发健壮和稳定的应用程序的能力,您的机器学习模型驻留在这些应用程序中。
  • 通用人工智能可能还有很长的路要走,但在当前时代,机器学习系统仍然可以实现一些惊人的壮举。
  • 立志成为机器学习领域的领导者,因为领导者的地位可以反映出你在机器学习行业的工作水平和影响力。

希望这篇文章对你有用。

要联系我或找到更多类似本文的内容,请执行以下操作:

  1. 订阅我的 YouTube 频道 即将上线的视频内容 这里
  2. 跟我上
  3. 通过 LinkedIn 联系我

关于我们的预测模型,疫情应该教给我们什么

原文:https://towardsdatascience.com/what-a-pandemic-should-teach-us-about-our-predictive-models-bd08c848d99?source=collection_archive---------71-----------------------

来源:https://www . oxy . edu/sites/default/files/styles/article _ main _ image/public/landing-page/main-images/coronavirus _ 895 x500 . jpg?itok=mAVhejJ6

如果您的组织有一个预测模型,您可能会对它在经济危机期间的准确性感兴趣,就像我们目前在新冠肺炎经历的那样。虽然期望你的模型在 100%的时间里都是完美的是不合理的(记住,模型只是他们被训练的数据的概括),但是从风险管理的角度来看,有三个主要的教训可以吸取,以确保你的模型不会被不和谐的事件摧毁。

第一课:正态分布很少见

大多数传统的经济模型(特别是输出数字的预测和回归模型,与可能输出“是/否”的分类模型相反)都假设每个变量的数据是正态分布的。这是因为,由于它们的线性关系,每个独立(“预测”)变量的平均值的方差应该解释因变量(“目标”)变量的平均值的方差。然而,现实世界中的经济数据很少遵循正态分布。让我们看一个例子:

如果我们绘制美国粮食生产者价格指数每月百分比变化的直方图,我们会看到数据看起来非常接近代表正态分布的 a:

大多数数据代表以 0%变化为中心的正态分布。然而,有一个观察结果与其他观察结果大相径庭,代表着一个月有 70%的增长。这就产生了一个“长尾”分布,这在构建模型时是很危险的。现在的问题变成了:我们如何处理这个异常值?

一方面,我们知道,在我们开发模型的数据中包含这一观察结果将打破“常态”假设。另一方面,移除异常值意味着我们的模型不会从那个月发生的事情中学习。例如,如果您正在训练一个模型,使用这个粮食 PPI 变量的百分比变化来预测贷款组合的违约率,删除这个异常值意味着您还必须丢弃该月观察到的违约率。你可以希望并祈祷这种影响与其他数据呈线性关系,但正如我们在几乎每张新冠肺炎图表中看到的那样,现实生活中异常值的影响通常是指数的而不是线性的。

处理这种情况的一些可能方法包括:

  • 从模型训练数据中移除异常值,但是让异常值出现时所发生的事情便于模型的最终消费者查看
  • 转向另一种对非线性更稳健的算法(例如,基于树的模型)或考虑贝叶斯方法
  • 在你的参数估计中模拟敏感性(例如,“我们的模型告诉我们,粮食的 PPI 月度百分比变化每减少 1%,月度违约率就会增加 0.05%。如果结果是月违约率上升 0.10%,那会怎么样?”)并将其作为模型输出的附录。

第二课:让你的模型输出概率(引导它!)

术语“风险”意味着有不止一种可能的结果,并且每种结果都有特定的发生可能性。如果我们试图对风险建模,那么默认情况下,我们的模型应该返回可能结果的分布以及相关的发生可能性。

从完全确定性模型到概率方法的第一步是引导你的模型。bootstrapping 不是对所有数据拟合一次模型,而是对训练数据进行预定义数量的随机采样(替换),每个采样的大小等于原始训练数据集。这意味着,如果我们定义我们需要 1,000 个引导样本,我们可以创建 1,000 个不同的模型,每个模型都根据原始训练数据集的稍微不同的变体进行训练。此外,我们对模型中的每个独立变量都有 1000 个不同的系数估计。

在我们之前的例子中,我们使用粮食 PPI 的月度百分比变化来预测贷款组合的月度违约率。如果我们采用 bootstrap 方法,为我们的自变量绘制 1000 个不同的参数估计值,它可能看起来像这样:

由于自举方法为我们的参数估计生成了可能值的分布,我们可以得出如下结论:

“我们有 95%的信心认为,我们违约率的粮食 PPI 百分比变化的权重在-0.043 到-0.035 之间。”

另一个人说:

“粮食 PPI 的月度百分比变化每下降 1%,我们就有 95%的信心认为,其影响将是月度违约率增加 0.043%至 0.035%。”

虽然 0.043%和 0.035%之间的差异可能看起来很小,但它相当于 100 亿美元贷款组合中的 800,000 美元差异。当您添加额外的独立变量时,这种效应会加剧,每个独立变量都有自己的可能参数估计分布。

第三课:数据为王

自 2000 年以来,我们已经经历了三次经济灾难:网络泡沫、2008 年房地产危机和现在的新冠肺炎。也许你在 2000 年甚至 2008 年都没有收集数据,但希望你现在正在收集。这可能是你第一次有机会在未来的所有模型中使用经济衰退的数据。

此外,频率也很重要。如果你只是每季度收集一次数据,就没有办法使用这些数据进行月度预测。相反,您总是可以将高频率数据聚合到较低的频率(如果您每月收集数据,您可以进行季度预测)。

最后,以更高的频率收集数据和建模会减少数据中出现明显异常值的机会。如果你有一个糟糕的年份,并且每年都在收集数据(只有一个数据点来代表那个糟糕的年份),那么你就要决定如何处理这个异常值。然而,如果您在一年中经常收集数据,那么糟糕的一年可能不再代表异常值,而是符合更适合建模的分布。

原载于https://www.ketchbrookanalytics.com/】

如何拉平信息曲线?

原文:https://towardsdatascience.com/what-about-flattening-the-infodemic-curve-a19ccac7199a?source=collection_archive---------34-----------------------

利用道德人工智能和以人为中心的产品设计来治疗数字经济的慢性疾病

伊利亚·安东内尔在 Unsplash 上的照片

与迅速发展的冠状病毒流行病交织在一起的是一种可能证明同样致命的阴险的信息流行病。2020 年 2 月,世界卫生组织总干事 Tedros Adhanom Ghebreyesus 首次创造了这个术语:

“……我们不仅仅是在抗击流行病;我们在与信息时代作斗争。假新闻比这种病毒传播得更快更容易,也同样危险。”

这种比较既不是耸人听闻,也不是夸张——社会现象的传播是如此强大, 2016 年的研究显示它可以完全遵循追踪流行病传染的相同模型。

这两种学说相互影响的例子包括大量被揭穿的新闻文章,从神奇的治疗和预防方法,如食用绿色草药煮生姜维生素 D ,到虚假声称疫苗治愈了数百名患者

与在短短几个月内出现并在世界上造成严重破坏的冠状病毒不同,信息流行病学深深植根于数字经济的结构中。

但是就像病毒一样,每个人都有责任阻止它的传播。

假新闻的味道

在我们继续之前,有必要解构一下“假新闻”的概念。《联合国教科文组织新闻教育和培训手册》指出这个术语既模糊又容易被政治化,并建议从意图和事实真相两个维度对假新闻进行更有帮助的分类,从而得出以下有用的定义

资料来源:firstdraftnews.org

  • 虚假信息:故意制造的虚假信息,以伤害个人、社会团体、组织或国家
  • 误传:虚假信息,但并非有意制造伤害
  • 不良信息:基于现实的信息,用于对个人、社会团体、组织或国家造成伤害。

以病毒情况为背景,虚假信息的一个例子是一个草药商发布消息说吃他们的草药可以防止感染新冠肺炎病毒。相比之下,目睹某人晕倒在推特上说这是一个与病毒有关的死亡,而没有进行适当的事实检查,因为当时被抓住了,这将是错误的信息。入侵政客的电子邮件以破坏其竞选活动将是错误信息。

所有这些都是有害的,尤其是当被今天的技术放大时。但是了解你的敌人是走向胜利的第一步。

追踪源头

但是我们是怎么到这里的呢?我们分三部分对此进行研究:

  • 失去控制和平衡的平台
  • 现在为上瘾而设计的用户界面,以及
  • 两者都以消费者为猎物,天生的认知弱点助长了无情的商业模式,这种模式会让人上瘾并过滤随之而来的泡沫。

检查我们向数字平台的迁移

虽然各国的研究结果不同,从我们在公共场所看到的情况来看,我们对屏幕的痴迷似乎无处不在,但数据显示,直到 2018 年,社交媒体才取代纸质报纸成为美国的主要新闻发布平台。这对我们消费的内容的集中度有着深远的影响。

经典报纸的性质意味着购买报纸的读者可以接触到相对均匀的内容分布——本地、国外和世界新闻、观点和社论、娱乐和体育版以及分类广告的混合。如果一份普通的报纸刊登 100 个故事,读者可能只对其中的 10 个感兴趣。但是由于媒体的设计,他或她会暴露在所有的 100 个人面前。

但是数字平台改变了分销的动力新闻经济学及其聚合方法、为今天的信息时代奠定了基础:

  • 任何有网络连接的人都可以发布新闻,这改变了新闻的面貌。尽管对独立新闻业的信任正在下降,但直到最近,报纸一直扮演着(尽管不完美)真理的守门人,只发布被认为可信的人的观点。
  • 然而,数字新闻的经济学是严酷的——与印刷视图相比,数字视图仅带来一小部分收入,加上越来越多的注意力转向非传统新闻来源,导致新闻收入在过去十年中下降了 60%以上
  • 进入推荐引擎。市场已经从新闻转移到注意力,随着令人讨厌的新闻经济学推动公司最大化眼球时间(从而最大化广告收入),推荐引擎的出现提供了手段。由为每个人优化的算法编辑器驱动,他们只有一个任务:学习让我们上瘾的独特鸡尾酒。然后不断喂给我们。

英国电信监管机构 Ofcom 对新闻消费的研究将这一结果总结为人们在网上获取新闻的三个明显趋势:

  • 他们获取新闻的主要设备是他们的智能手机。
  • 他们获取大部分新闻的主要平台是社交媒体。
  • 他们对待新闻的主要心态现在是被动的。

“卷轴锁”:无限卷轴把我们锁进系统 1 思维

这些力量注定与一个普遍的特征不谋而合,这个特征将形成今天新闻体验的主干。

2006 年,领先的技术工程师阿萨·拉斯金设计了无限滚动,允许用户连续上下翻页,而无需点击“刷新”或“下一页”。虽然最初的设计是为了创造一种无缝的体验,但他表示,这种做法产生了意想不到的副作用,“没有给你的大脑时间来跟上你的冲动”,从而让用户看手机的时间远远超过了必要的时间。

作为 Mozilla 和 Jawbone 的前雇员, Aza 现在后悔他的创作,这已经成为许多内容平台的核心特征,并被视为高度习惯形成。

虽然我们可能会责备周围的人“有更多的意志力”来克服在消费内容时被引入无益的思维模式,但 Aza 提醒我们,这不是一场公平的战斗:

“在你手机的每一个屏幕后面,通常都有差不多 1000 名工程师在研究这个东西,试图让它最大限度地上瘾。”

来源:照片来自 Pexels ,来自我在【2020 年悉尼高德纳分析峰会上展示的一张幻灯片

结合推荐引擎,最终结果是设计成瘾,Natasha Schull,一本同名书籍的作者,在描述这一现象时,将吃角子老丨虎丨机和其他系统如何被设计成将用户锁定在成瘾循环中进行了比较:

“脸书、Twitter 和其他公司使用类似于博彩业的方法让用户留在他们的网站上……在网络经济中,收入是消费者持续关注的函数——以点击次数和花费的时间来衡量。”

利用我们的认知弱点

假新闻吸引力背后的另一个因素是被称为确认偏差的认知心理学现象。这是指人们倾向于接受证实他们先前存在的信念的信息,而忽略挑战他们的信息。这种有偏见的信息处理方法在很大程度上是无意的,如果它符合人们现有的信念,就会导致人们更容易接受“假新闻”。

认知偏见本身是危险的,但我们现在有了一个完整的图景:

我们获得了通过数字新闻平台无法获得的假新闻,在绕过我们强大的深思熟虑的思维过程的用户界面功能环境中消费假新闻,通过推荐引擎重复获得更多相同的内容,并通过确认偏见将我们自己推入更深的回音室。

但还是有希望的。假新闻是设计出来让人上瘾的,也是设计出来可以平衡的。为观点而优化的人工智能使信息变得致命,而为真理而优化的人工智能可以阻止它的传播。

新闻消费的另一种未来

信息经济学是复杂的。多方面的问题很少能找到简单的解决办法,而且已经有一系列举措试图解决这个问题。波因特列出了这些措施,其中包括促进新闻素养,建议人们培养不同的观点,保持高质量的新闻报道,甚至法律和监管行动。

教育和制度都是必要的,但不是充分的。教育需要时间,我们将在下面看到,目前的措施正在努力解决这个问题。我们还应该警惕的是,严厉的监管可能会带来滥用的风险,合法的言论和新闻报道可能会受到武断的“真实”标准的审查。

除了这些措施,我们还需要修理机器。

设计真理的现代守门人

将我们的注意力转向未来——当今世界大部分人消费新闻的镜头是服务新闻的技术产品和社交媒体平台,以及驱动它们的算法。

在寻找解决方案时,我们的第一本能可能是用人工智能来对抗人工智能——具有检查和监管功能的自然语言处理和机器学习模型是否足以阻止假新闻的传播?

标记新闻标准、政治偏见和消费者信任以训练这种假新闻识别模型的基线数据集存在(例如这里的和这里的)。然而,这些步骤有其自身的风险。误报(即错误地标记真实的新闻文章)和有偏见的训练数据(就其本身而言是一个完整的主题)使得这些工具单独使用时备受争议。只有当一个人处于循环中时,这些方法才会发挥作用。

如果新闻产品和平台是我们的前线,那么我们对 AI 的部署必须在以人为中心的产品设计范围内。复制当我们观察到犯罪时呼叫紧急服务的真实体验,平台可以设计成具有反馈回路等功能,以抑制信息传播并促进可信的新闻。

脸书已经试验并实施了此类措施来打击假新闻。这种方法有两个方面:

  • 解决假新闻的方法是让假新闻报道变得更容易,让独立的事实核查机构来核查内容,并标记有争议的文章以限制其传播
  • 推广可信来源通过提高来自社区评定为可信来源的文章的可见性来补充这一点。

众包内容标记、让可信的事实核查人员参与进来,以及抑制有争议内容的流动和增加可信内容的流动的能力,这些结合在一起,是一种强大的积极力量。

用愚蠢的卷轴换取深思熟虑的参与

收回对我们系统 2 思维能力的控制的一个简单方法是在我们的用户界面上换出无限滚动。但是我们用什么来代替它呢?

卡塔尔计算研究所(QCRI)的团队通过项目 Tanbih 提供了一个令人信服的建议。Tanbih 在阿拉伯语中大致翻译为警报预防的意思,是一个新闻聚合器,提供 产品在线演示 界面呈现了关于同一事件的多个故事,可以通过左右滑动来访问,让读者对每个展开的事件获得不同的视角。

通过反映“故事的更多方面”和减缓消费,这个界面允许读者更深入地参与内容并得出自己的结论。

Tanbih 的读者参与方法也明确了每条新闻背后消息来源的立场和偏见。每个故事都有一个可点击的来源图标(如 CNN,每日镜报等。),它提供了一个全面的仪表板,可以精确地评估源的位置。这些仪表板元素的选择如下所示:

来源:来自 Tanbih 演示的新闻源的各种仪表板元素的屏幕截图

QCRI NLP 教授 Preslav Nakov 博士在一次题为“在假新闻被写出来之前检测假新闻”的研讨会上提出了这一想法。

QCRI 和麻省理工学院的计算机科学和人工智能实验室(CSAIL)合作,努力的中心是从事实核查转向来源核查。这种方法的逻辑是合理的:

  • 目前,大多数事实核查工作都是针对个人索赔,这是一个耗时且无法扩展的解决方案。2018 年,脸书宣布计划将他们的版主人数增加到 20000 人。这是一个令人钦佩的举动,但这一数字将占他们劳动力的 45%以上,可能会极大地摆脱大型科技公司的商业模式。对于无数的小型平台来说,这也是遥不可及的。
  • 此外,检查每篇文章是一个繁琐的过程。在核实一篇文章的时间里,它可能已经传遍了全世界。
  • 更可行的方法是提前检查消息来源,这样就产生了研讨会的名称。简单地说,Ramy Baly 是涵盖这项研究的论文的第一作者:

“如果一个网站以前发布过假新闻,他们很有可能会再次发布。”

大规模人群媒介素养

从平台到用户体验,我们现在到了消费者。虽然媒体素养的呼声不绝于耳,但我们实际上做得如何呢?我们能做得更好吗?

一直在努力将此纳入我们的学校,但差距很大,进展也不均衡。假新闻和学校批判性读写技能教学委员会 2018 年的一份报告发现英国只有 2% 的儿童和年轻人拥有辨别新闻故事真假所需的批判性读写技能。在其他地方,一份 2020 年 1 月的美国媒体素养政策报告显示,只有 14 个州在 K-12 学校的媒体素养教育法方面取得了有意义的进展。

成人扫盲——可以说是更紧迫的事情——描绘了一幅类似的模糊画面。有网上资源,这是一个积极的信号,成熟的课程可以在知名平台上找到,比如 Coursera 和 edX。但兴趣不足,似乎有更多的人希望实现人工智能,而不是学习如何明智地使用它。对同一个平台上流行的深度学习课程的兴趣超过新闻课程 25 倍。

也许需要一种不同的策略来增强我们对信息流行病的免疫力。用在线课程来解决问题从来都不是万灵药,越来越多的证据表明,它们伤害了那些最需要的人,因为他们需要高度的自我激励和自我调节。前面提到的 Tanbih 项目的一个更雄心勃勃的扩展教育的方式是在新闻上覆盖一个宣传探测器,在文章本身上突出显示说服技术的每个实例(例如加载的语言、口号和宣传车)。在读者使用这种帮助一段时间后,他或她会自动发现这些技术,即使没有帮助。

或者我们可以转而玩游戏:波因特的综述游戏,教用户如何识别错误信息,既有趣又有教育意义。它们涵盖了所有的坏消息,玩家通过角色扮演假新闻制作人来学习假新闻网站的策略,还有用真实新闻文章挑战玩家的假新闻。

坏消息Fakey 截图,基于网络的互动教育工具,旨在提高媒体素养

综上所述,这幅图有一个美丽的讽刺。

当我们窥视信息时代的内幕时,我们最初可能会被当今复杂的数字服饰弄得眼花缭乱。但是坚持我们的注视,我们开始看到一些熟悉的东西。

现代平台的运作方式可能是仅仅一代人之前的印刷领导者无法想象的。它们建立在生命周期非常短的框架上,配备了工业 4.0 角色,并利用了最先进的人工智能。但他们也兜了一圈:他们发现成为今天的新守门人意味着什么。这场斗争最终是一场争取关注的斗争,一场争取真理的斗争。

因此,我们的武器是新的,但我们的战斗是旧的。我们需要受过教育的买家、负责任的审查和平衡的观点。我们的平台应该平衡商业价值和道德设计。在考虑人工智能的强大工具时,我们需要记住,它们的核心人工智能系统是优化工具,我们需要注意我们在优化什么。

上面显示的所有图像仅用于非商业说明目的。本文是以个人身份撰写的,不代表我所工作或隶属的组织的观点。

三星的 Ballie 能找到哪些 AI 技术?

原文:https://towardsdatascience.com/what-ai-techniques-can-be-found-in-samsungs-ballie-d379864a6132?source=collection_archive---------46-----------------------

我们正在剖析三星的 Ballie 功能和能力,以及人工智能在其中的位置。

介绍

Sebastian Seung 在 CES 2020 上介绍 Ballie

在 CES 2020 上,三星提出了对个人家庭助理的重新定义。

他们称之为贝利。

这是理所当然的,因为这个家真的滚滚而来,有着充满活力的太阳般的黄色。

Ballie 是一款由人工智能驱动的手机助手。

三星展示 Ballie 特征的短片(下面几段)展示了 Ballie 如何与人类、环境和宠物狗互动。

该视频演示了可以通过人工智能和机器学习技术实现的各种功能。

本文探索了嵌入在 Ballie 中的 AI 和 ML 技术;以及每种技术的摘要。本文还包括详细介绍实现策略的研究论文,供更实用的读者参考。

请随意观看下面的演示视频。

侦查

我们将从 Ballie 的探测能力开始。

从演示视频中,我们可以得出在 Ballie 的嵌入式人工智能中实现的检测系统的类型。

  • 目标检测
  • 人脸检测
  • 变化检测

目标检测和识别

Ballie 能够探测人类,这些探测能力也适用于动物。

我们可以更进一步说,Ballie 的检测系统非常健壮。

为了像演示视频中描述的那样实用,它必须能够识别各种家居用品。

那可是一大堆训练数据啊!

在我们进一步讨论之前,让我们定义一下什么是对象检测。

目标检测包含在计算机视觉中,概括了系统识别图像中所需目标的存在和位置的能力。

对象检测过程的输出是一个图像,在感兴趣的对象周围有边界框,并指示对象的类实例,如下图所示。

【CES 2020】贝利的华尔兹|三星视频。三星左:巴利认一个人。右图:贝利认出了一只狗

在探测过程开始之前,我们必须识别实际的物体。这个过程被称为对象识别。

物体识别的技术定义如下:

发现与目标对象相关联的类的过程。对象识别和检测是具有相似最终结果和实现方法的技术。

有几种方法来实现对象识别和检测。这里有几篇研究论文提供了实现策略的方法。

[## 更快的 R-CNN:用区域提议网络实现实时目标检测

最先进的目标检测网络依靠区域提议算法来假设目标位置…

arxiv.org](https://arxiv.org/abs/1506.01497) [## 你只看一次:统一的,实时的对象检测

我们提出了 YOLO,一种新的目标检测方法。先前关于目标检测的工作将分类器重新用于执行…

arxiv.org](https://arxiv.org/abs/1506.02640)

变化检测

短视频演示中,有一个场景是宠物狗打翻了一碗麦片(坏狗)

Ballie 然后继续自动使用机器人真空吸尘器。

【CES 2020】贝利的华尔兹|三星

让我们推理一下变更检测将如何在 Ballie 的内部系统中运行。

Ballie 大概已经注意到环境状态从理想状态的变化。

在 Ballie 的记忆中,可能有每个房间在其环境中的理想状态的快照。因此,对该快照的偏差进行处理。在这种情况下,偏差要求采取行动来启用清洁机器人。

在这个特定的场景中,可能还会发生更多的事情。但是现在,我们将把重点放在探测环境变化的能力上。

图像中的变化检测是定位和识别图像序列中的变化的过程。当检测视频资源而不是图像的变化时,您可以简单地利用连续的帧作为变化检测对。

以下是使用 ML 和深度学习技术实现变化检测的方法。

[## 学习测量变化:场景变化检测的全卷积暹罗度量网络

场景变化检测的一个关键挑战问题是由变化的照明、阴影…

arxiv.org](https://arxiv.org/abs/1810.09111) [## ECCV 2018 年奥运会开放存取知识库

ChangeNet:用于视觉变化检测的深度学习架构 Ashley Varghese,Jayavardhana Gubbi,Akshaya…

openaccess.thecvf.com](http://openaccess.thecvf.com/content_eccv_2018_workshops/w7/html/Varghese_ChangeNet_A_Deep_Learning_Architecture_for_Visual_Change_Detection_ECCVW_2018_paper.html)

追踪和跟踪

Wallie 的,抱歉我指的是 Ballie 的跟踪和跟随能力,是家庭助理设备的一个可区分的属性。

像 Alexa 和 Google Home 这样的应用被限制在固定的位置,而 Ballie 可以跟踪和跟随目标(同时尊重个人空间,显然是)。

跟踪:一种在一段时间内在一系列图像中识别、检测和跟踪感兴趣的物体的方法。在许多监控摄像机和交通监控设备中可以找到系统内跟踪的应用。

但我不太清楚的是,Ballie 如何在一个房间里处理多个人,然后选择跟随谁?

左:【CES 2020】Ballie |三星的华尔兹。右图:三星 Ballie 在 CES 2020 上的演示

姿势估计/活动识别

姿态估计是从图像或图像序列中导出身体的重要身体部分和关节的位置和方向的过程。

人类活动识别(HAR)是利用感觉数据识别个体所采取的动作的过程。在 Ballie 的例子中,很明显它使用了视觉传感器(摄像头),但它也可以利用雷达和音频传感器。

通过识别一个人可以做出的各种姿势,我们可以创建一个活动数据库,其中每个活动都与一段时间内做出的各种不同姿势相关联。然后,有可能训练机器学习模型,以便能够基于某些姿势来推断活动分类。

因此,我们可以推断,Ballie 识别其主人正在表演瑜伽的能力(图片在下方),是因为在其人工智能系统中,有经过各种姿势及其相关活动训练的 ML 模型。

因此,Ballie 能够检测瑜伽活动和问候手势。

【CES 2020】贝利的华尔兹|三星

让我们来看看机器学习方面的东西。

卷积神经网络(CNN)可以用于姿态估计和 HAR。

HAR 的 CNN 能够发现和学习与特定活动相关联的姿势中的重复出现的模式。因此,HAR 问题是作为一项分类任务提出来的。

另一方面,一个活动也可以被看作是一段时间内一系列姿势的组合。

为了让 Ballie 能够关联姿势的时间信息来推断活动,它必须利用递归神经网络(RNN)。

RNNs 可以提取与接收到的视觉传感数据相关联的特定时间步长的特征。

下面是使用 ML 和深度学习技术实现姿态估计的方法。

[## 卷积姿态机器

姿态机器为学习丰富的隐式空间模型提供了顺序预测框架。在这部作品中,我们展示了…

arxiv.org](https://arxiv.org/abs/1602.00134)

结论

我们在很短的时间内经历了很多,毫无疑问,Ballie 可能会实现更多的人工智能功能,并且在我们看到测试版发布之前会经历几次迭代。

还有更多我没有涉及的功能,比如 Ballie 的自动语音识别或者它的硬件控制。快速的 google 搜索将提供一些关于所提到的技术的描述和实现策略的信息。

如果 Ballie 向公众发布,它可能会成为头条新闻,并改变个人处理日常活动的方式。

我喜欢它的移动性和在没有人类控制者的情况下执行任务的能力— 经过再三考虑,我可能会关闭这一功能。

如果你有兴趣了解你可能是什么样的人工智能爱好者,并学习一些人工智能/人工智能术语,那么请阅读下面的文章。

[## 你是什么类型的人工智能爱好者?

根据人工智能领域内的常用术语,衡量你在人工智能爱好者等级中的排名。

towardsdatascience.com](/what-type-of-artificial-intelligence-enthusiast-are-you-32ca88c01a7e)

如果你喜欢这篇文章,并想阅读我的更多内容,请关注我,或者你可以通过 LinkedIn 与我联系。

AlexNet 给深度学习世界带来了什么

原文:https://towardsdatascience.com/what-alexnet-brought-to-the-world-of-deep-learning-46c7974b46fc?source=collection_archive---------17-----------------------

Unsplash 上的 Pietro Jeng 拍摄

技术和解释

花一分钟时间来理解彻底改变深度学习方法的琐碎技术和神经网络架构

TAlex net 卷积神经网络(CNN)于 2012 年推出。从那时起,深度卷积神经网络的利用已经飙升到几个机器学习解决方案利用深度 CNN 的程度。

本文将介绍研究论文的基本发现和讨论要点,其中介绍了 AlexNet 架构。

在本文中,您可以找到以下内容:

  • 介绍 AlexNet 的研究论文分解
  • Alex net 架构的图示
  • Alex net内层成分表
  • 对各种技术的解释,如剔除、数据扩充、标准化等。

所有级别的机器学习和深度学习实践者都可以遵循本文中介绍的内容。

介绍

AlexNet 卷积神经网络架构在论文 ImageNet 分类与深度卷积神经网络中提出。该论文由 Alex Krizhevsky、Ilya Sutskever 和深度学习教父 Geoffery Hinton 撰写。

左:亚历克斯·克里热夫斯基,中:伊利亚·苏茨科夫,右:杰弗里·辛顿

该论文的作者旨在表明图像分类的琐碎任务可以通过使用深度卷积神经网络、有效的计算资源和常见的 CNN 实现技术来解决。

论文证明了一个由 5 个卷积层和 3 个全连接层组成的深度卷积神经网络可以高效、准确地对图像进行分类。

一种深度卷积神经网络被称为 AlexNet,它被引入 ImageNet 大规模视觉识别挑战(ILSVRC 2012 竞赛),在那里它为深度学习领域开创了先例。

好时机

在 AlexNet 推出之前,许多传统的神经网络和卷积神经网络在解决数据集上的图像分类方面表现良好,如 MNIST 手写字符数据集。但是为了解决日常生活中物体的一般图像分类的问题,需要更大的数据集来说明图像中出现的物体的相当大的多样性。

MNIST 数据集插图

通过引入大型数据集(如 ImageNet,包含 1500 万幅高分辨率图像中的 22,000 个类)解决了缺乏强大数据集的问题。

引入 AlexNet 之前的另一个限制是计算机资源。

增加网络的容量意味着增加网络的层数和神经元的数量。

当时,训练这样一个网络的计算资源是稀缺的。但是优化的 GPU 的引入使得训练深度常规神经网络成为可能。用于训练 AlexNet CNN 架构的特定 GPU 是英伟达 GTX 580 3GB GPU

英伟达 GTX 580

AlexNet 架构的独特特征

整流线性单位(ReLU)

为了训练神经网络内的神经元,标准做法是利用双曲正切或 sigmoid 非线性,这是 goto 激活函数,用于模拟 CNN 内的内部神经元激活。

AlexNet 继续使用校正线性单位,简称 ReLU。ReLU 是由 Vinod Nair 和 Geoffrey E. Hinton 于 2010 年在这篇论文中介绍的。

ReLu 可以被描述为对先前卷积层的输出执行的传递函数运算。ReLu 的使用确保了神经元内的正值被保持,但是对于负值,它们被箝位到零。

使用 ReLu 的好处是,与其他标准非线性技术相比,它能够加速训练过程,因为梯度下降优化以更快的速度发生。

ReLu 层的另一个好处是它在网络中引入了非线性。它还消除了连续卷积的关联性。

绘图处理器

在介绍 AlexNet 神经网络架构的原始研究论文中,模型的训练是利用两个具有 3GB 内存的 GTX 580 GPU 进行的。

GPU 并行化和分布式训练是当今非常常用的技术。

根据从研究论文中获得的信息,该模型在两个 GPU 上进行训练,其中一半的模型神经元在一个 GPU 上,另一半在第二个 GPU 的内存中。GPU 之间相互通信,不需要通过主机。GPU 之间的通信被限制在层的基础上;因此,只有特定的层可以相互通信。

例如,AlexNet 网络第四层中的输入是从当前 GPU 上第三层的一半特征图中获得的,而另一半的剩余部分是从第二个 GPU 中获得的。这将在本文后面更好地说明。

局部反应标准化

标准化是将一组数据点放在一个可比较的基础或尺度上(这是一个过于简单的描述)。

CNN 中的批量标准化(BN) 是一种通过将一批输入数据转换为均值为零、标准差为一的方式来标准化和规范化输入的技术。

许多人都熟悉批量标准化,但 AlexNet 架构在网络内使用了一种不同的标准化方法:本地响应标准化(LRN)。

LRN 是一种最大限度地激活邻近神经元的技术。相邻神经元描述了共享相同空间位置的多个特征图中的神经元。通过标准化神经元的激活,具有高激活的神经元被突出显示;这基本上模仿了神经生物学中发生的侧抑制。

LRN 在现代 CNN 架构中没有被广泛使用,因为还有其他更有效的归一化方法。虽然,LRN 的实现仍然可以在一些标准的机器学习库和框架中找到,所以请随意试验。

重叠池

CNN 中的池图层本质上封装了要素地图中一组像素或值内的信息,并将它们投影到较小尺寸的格网中,同时反映原始像素集中的一般信息。

下图提供了一个池的示例,更具体地说是最大池。最大汇集是子采样的变体,其中落在汇集窗口的感受域内的像素的最大像素值。

贾斯汀·弗朗西斯在奥里利的最大池插图

在介绍 AlexNet CNN 架构的文章中,介绍并利用了一种不同的池方法。重叠池。在传统的汇集技术中,从一个汇集窗口的一个中心到另一个中心的步幅被定位成确保来自一个汇集窗口的值不在随后的汇集窗口内。

与传统的池化方法相比,重叠池化利用的跨度小于池化窗口的尺寸。这意味着后续汇集窗口的输出封装了来自已经汇集了不止一次的像素/值的信息。很难看出这样做的好处,但根据这篇论文的发现,重叠池降低了模型在训练期间过度适应的能力。

[## (你应该)理解深度学习中的子采样层

平均池、最大池、子采样、下采样,这些都是你在深度学习中会遇到的短语…

towardsdatascience.com](/you-should-understand-sub-sampling-layers-within-deep-learning-b51016acd551)

数据扩充

另一种减少网络过度拟合机会的标准方法是通过数据扩充。通过人为扩充数据集,可以增加训练数据的数量,这反过来又会增加网络在训练阶段所暴露的数据量。

图像的放大通常以变换、平移、缩放、裁剪、翻转等形式出现。

原始 AlexNet 论文中用于训练网络的图像在训练阶段被人工增强。所使用的增强技术是图像中像素强度的裁剪和改变。

训练集中的图像从其 256×256 的尺寸被随机裁剪,以获得 224×224 的新裁剪图像。

增强为什么会起作用?

事实证明,对训练集进行随机扩充可以显著降低网络在训练过程中过度适应的可能性。

增强图像仅仅是从原始训练图像的内容中得到的,那么为什么增强效果如此之好呢?

简单地说,数据扩充增加了数据集中的不变性,而不需要寻找新的数据。网络对看不见的数据集进行良好概括的能力也增加了。

让我们举一个非常字面的例子;“生产”环境中的图像可能并不完美,有些可能会倾斜、模糊或只包含一些基本特征。因此,针对包括训练数据的更稳健变化的数据集来训练网络将使训练好的网络能够更成功地对生产环境中的图像进行分类。

拒绝传统社会的人

辍学是许多深度学习从业者都很熟悉的一个术语。Dropout 是一种用于降低模型过度拟合可能性的技术。

Dropout 技术的工作原理是在 CNN 层内的神经元激活中增加一个概率因子。这个概率因子向神经元指示在电流前馈步骤期间以及在涉及反向传播过程期间被激活的机会。

丢弃是有用的,因为它使神经元能够减少对相邻神经元的依赖性;这样一来,每个神经元都会学到更多有用的特征。

在 AlexNet 架构中,在前两个完全连接的层中使用了 dropout 技术。

使用丢弃技术的一个缺点是它增加了网络收敛的时间。

虽然,利用辍学的优势远远超过其缺点。

[## 在 TensorFlow 和 Keras 中理解和实现辍学

辍学是一种常见的正规化技术,是杠杆在国家的艺术解决方案,以计算机视觉…

towardsdatascience.com](/understanding-and-implementing-dropout-in-tensorflow-and-keras-a8a3a02c1bfa)

AlexNet 架构

在本节中,我们将了解 AlexNet 网络的内部组成。我们将关注与这些层相关的信息,并分解每个重要层的内部属性。

AlexNet CNN 架构由 8 层组成,其中包括 5 个 conv 层和 3 个全连接层。一些 conv 层由卷积层、池层和归一化层组成。

AlexNet 是第一个采用连续卷积层(conv 第 3、4 和 5 层)架构的架构。

网络中的最终全连接层包含 softmax 激活函数,该函数提供表示 1000 个类的概率分布的向量。

Softmax 激活功能

Softmax 激活用于导出输入向量中一组数字的概率分布。softmax 激活函数的输出是一个向量,其中它的一组值表示一个类或事件发生的概率。向量中的值加起来都是 1。

除了最后完全连接的层之外,ReLU 激活功能被应用于网络中包括的其余层。

简化的 AlexNet 神经网络多 GPU 架构

上面 AlexNet 网络的图示被分成两个分区,因为该模型是在两个 GTX 580 GPU 上训练的。虽然网络跨两个 GPU 划分,但从图中我们可以看到 conv3、FC6、FC7 和 FC8 层中的一些跨 GPU 通信。

下表列出了网络中各层的一些特征和属性。

AlexNet 架构属性表

在原始论文中,输入层的尺寸为 224 x 224 x 3,但在上表中,输入层的输入尺寸为 227 x 227 x 3,这种差异是由于在网络的实际训练过程中出现了一些未提及的填充,这些填充没有包括在已发表的论文中。

结论

AlexNet 的推出和成功改变了深度学习的格局。在其在 ILSVRC'12 竞赛中的胜利表现之后,接下来几年的获奖架构都是深度卷积神经网络。

AlexNet 的一个变体以不同的超参数赢得了 ILSVRC'13 竞赛。2014 年、2015 年和 2016 年的获奖架构采用了更深的网络和更小的卷积内核/滤波器。

理解 AlexNet 的架构很容易,甚至更容易实现,特别是使用像 PyTorch 和 TensorFlow 这样的工具,这些工具在其库和框架中包含了一个架构模块。

在以后的文章中,我将展示本文中介绍的 AlexNet 架构如何在 TensorFlow 中实现和使用。

我希望这篇文章对你有用。

要联系我或找到更多类似本文的内容,请执行以下操作:

  1. 订阅我的 YouTube 频道 视频内容即将上线 这里
  2. 跟着我上
  3. 通过 LinkedIn 联系我

[## 根据吴恩达(斯坦福深度学习讲座),你应该如何阅读研究论文

关于如何通过知名人士发表的研究论文获取知识的指导。

towardsdatascience.com](/how-you-should-read-research-papers-according-to-andrew-ng-stanford-deep-learning-lectures-98ecbd3ccfb3) [## 人工智能中的算法偏差需要讨论(和解决)

你在这件事上有责任…

towardsdatascience.com](/algorithm-bias-in-artificial-intelligence-needs-to-be-discussed-and-addressed-8d369d675a70)

scikit 中 fit_transform()和 transform()背后的内容和原因-学习!

原文:https://towardsdatascience.com/what-and-why-behind-fit-transform-vs-transform-in-scikit-learn-78f915cf96fe?source=collection_archive---------1-----------------------

Scikit-learn 是 Python 编程语言中最有用的机器学习库。它有很多工具来建立机器学习模型,并且非常容易使用。然而,我们有时会努力理解一些非常简单的方法,这些方法通常是我们在构建机器学习模型时经常使用的。

一种这样的方法是 fit_transform() ,另一种是 transform() 。两者都是在缩放或标准化我们的训练和测试数据时几乎一起使用的类sk learn . preprocessing . standard scaler()和的方法。

Tekton 的照片来自 Unspalsh

写这篇博客的动机来自于在一个关于机器学习的在线课程中发布的关于这些方法的多个问题。

问题是:

为什么我们对训练数据使用 fit_transform(),而对测试数据使用 transform()。

我们都知道,我们对训练数据调用 fit_transform()方法,对测试数据调用 transform()方法。但实际问题是我们为什么要这样做?我的动机是以尽可能简单的方式解释这个简单却令人困惑的观点。所以让我们开始吧!

假设我们正在构建一个 k-最近邻模型,并且我们必须缩放我们的特征。最常见的扩展特性的方法是通过 scikit-learn 的 StandardScaler 类。

注:

  1. 数据标准化是重新调整属性的过程,使其均值为 0,方差为 1。
  2. 执行标准化的最终目标是在不扭曲数值范围差异的情况下,将所有特征降低到一个共同的尺度。
  3. 在 sk learn . preprocessing . standard scaler()中,居中和缩放在每个特征上独立发生。

执行标准化的神奇公式:

作者图片

现在让我们深入了解这个概念。

fit_transform()

fit_transform()用于训练数据,因此我们可以缩放训练数据,还可以了解该数据的缩放参数。在这里,我们建立的模型将学习训练集特征的均值和方差。然后,这些学习到的参数被用于调整我们的测试数据。

这里到底发生了什么!🤔

拟合方法是计算数据中每个特征的平均值和方差。变换方法是使用各自的平均值和方差对所有要素进行变换。

现在,我们希望将缩放应用于我们的测试数据,同时不希望我们的模型有偏差。我们希望我们的测试数据对于我们的模型来说是一个全新的和令人惊讶的集合。在这种情况下,transform 方法可以帮助我们。

相关文章—想了解多重共线性读到这里

变换()

使用转换方法,我们可以使用从我们的训练数据计算的相同的均值和方差来转换我们的测试数据。因此,我们的模型使用训练数据学习的参数将帮助我们转换我们的测试数据。

现在的问题是我们为什么这样做?🙃

下面是背后的简单逻辑!

如果我们也对测试数据使用拟合方法,我们将计算新的平均值和方差,这是每个特征的新尺度,并将让我们的模型也了解我们的测试数据。因此,我们想要保持惊喜的是,我们的模型不再是未知的,并且我们将不会得到我们的模型在测试(看不见的)数据上表现如何的良好估计,这是使用机器学习算法建立模型的最终目标。

这是在构建机器学习模型时缩放我们的数据的标准程序,以便我们的模型不会偏向数据集的特定特征,同时防止我们的模型学习我们测试数据的特征/值/趋势。

希望这个解释能帮助你理解这些方法背后的简单逻辑。

参考:

[## sk learn . preprocessing . standard scaler-sci kit-learn 0 . 23 . 2 文档

通过移除平均值并缩放至单位方差来标准化要素。样本的标准分数计算如下…

scikit-learn.org](https://scikit-learn.org/stable/modules/generated/sklearn.preprocessing.StandardScaler.html#sklearn-preprocessing-standardscaler)

这是我的第一个博客。请分享您的意见和建议,以改进这篇博文。

领英

NLP 中有哪些对抗性的例子?

原文:https://towardsdatascience.com/what-are-adversarial-examples-in-nlp-f928c574478e?source=collection_archive---------11-----------------------

揭露 NLP 模型中的盲点,从罗伯塔到 GPT-3

自然语言处理中对立范例的两种不同理解。这些结果是在烂番茄电影评论情感分类数据集上训练的 LSTM 上使用 TextAttack 生成的。这些是* 真实* 对抗的例子,使用 DeepWordBugTextFooler 攻击生成。要自己生成它们,在安装 TextAttack 后,运行“text attack attack-model lstm-Mr-num-examples 1-recipe RECIPE-num-examples-offset 19”其中 RECIPE 为“deepwordbug”或“textfooler”。[图片由作者提供]

本文讨论了应用于自然语言处理的对立例子的概念。术语有时会令人困惑,所以我们将从讨论对抗性例子和对抗性攻击的语言概述开始。然后,我们将讨论 TextAttack ,这是我们的开源 Python 库,用于 NLP 中的对抗示例、数据增强和对抗训练,它正在改变人们研究 NLP 模型鲁棒性的方式。最后,我们将对这一研究领域的未来进行一些思考。

术语

一个对立的例子是一个被设计用来愚弄机器学习模型的输入[1]。作为良性输入的变化而精心制作的对抗性示例被称为对抗性扰动。“对抗性扰动”比“对抗性例子”更具体,因为所有对抗性例子的类别还包括从头开始设计的输入,以欺骗机器学习模型。文本攻击攻击产生一种特殊的对抗性例子,对抗性干扰。

对机器学习模型的对抗性攻击是产生对抗性扰动的过程。TextAttack 攻击遍历数据集(模型的输入列表),并对每个正确预测的样本搜索敌对扰动。如果一个例子一开始就被错误地预测,它就不会被攻击,因为输入已经欺骗了模型。TextAttack 将攻击过程分成几个阶段,并提供了一个可互换组件的系统来管理攻击的每个阶段。

对抗性稳健性是对模型对对抗性例子的易感性的度量。TextAttack 通常使用攻击成功率攻击后准确性来衡量健壮性,前者是产生成功对抗示例的攻击尝试的百分比,后者是正确分类和攻击失败的输入的百分比。

为了提高我们讨论对抗性攻击的计算能力,让我们看一个具体的例子:

这些结果来自于使用 TextAttack 对在烂番茄电影评论情感分类数据集上训练的 LSTM 运行 DeepWordBug 攻击,总共使用了 200 个例子。[图片由作者提供]

这种攻击在 200 个例子上运行。在这 200 个中,模型最初错误地预测了其中的 43 个;这导致了 157/200 或 78.5%的准确度。TextAttack 对剩余的 157 个示例运行对抗性攻击过程,试图为每个示例找到有效的对抗性干扰。在这 157 次攻击中,29 次攻击失败,导致成功率为 128/157 或 81.5%。另一种表达方式是,该模型正确预测了原始样本,然后在 200 个样本中的 29 个样本中抵抗了对抗性攻击,导致攻击下的准确性(或“攻击后准确性”)为 29/200 或 14.5%。

TextAttack 还记录了此攻击的一些其他有用的统计数据。在 157 次成功的攻击中,平均来说,攻击改变了 15.5%的单词来改变预测,并进行 32.7 次查询来找到成功的扰动。在所有 200 个输入中,平均字数是 18.97。

现在我们已经提供了一些术语,让我们来看一些提议的对抗性攻击的具体例子。我们将给出一些其他领域的对抗性攻击的背景,然后是 NLP 中不同攻击的例子。

对立的例子

2013 年的研究[2]显示,神经网络容易受到对立例子的影响。这些原始的对抗性攻击对图像应用小的、精心选择的扰动来欺骗图像分类器。在这个例子中,分类器正确地预测原始图像是猪。然而,在一个小扰动之后,分类器预测这头猪是一架客机(具有极高的可信度!).

ImageNet 分类器的反面例子。叠加一点点(但故意的)噪音会让模型将这头猪归类为客机。[图片来自这篇可爱的文章讲述了亚历山大·mądry's 集团的反面例子。]

这些对立的例子展示了深度神经网络中的严重安全缺陷。因此,对抗性的例子给所有包括神经网络的下游系统带来了安全问题,包括文本到语音系统和自动驾驶汽车。对立的例子在安全之外是有用的:研究人员已经使用对立的例子来改进和解释深度学习模型。

正如你可能想象的那样,深度神经网络中的对立例子已经引起了世界各地许多研究人员的注意。他们在 2013 年的发现引发了对该主题的研究热潮。

2014 年至 2020 年间与 arxiv.org“对立例子”相关的论文数量。[图片来自https://Nicholas . Carlini . com/writing/2019/all-adversarial-example-papers . html]

许多新的、更复杂的对抗性攻击已经被提出,还有防御,训练神经网络抵抗(健壮)对抗性攻击的程序。训练高度准确的深度神经网络同时保持对敌对攻击的鲁棒性仍然是一个公开的问题[3]。

自然地,许多人想知道 NLP 模型可能会有什么对立的例子。对于 NLP 来说,不存在与计算机视觉中的对立例子(例如上面的猪对飞机的迷惑)的自然类比。在上面的例子中,猪分类的输入和它的客机分类的扰动对人的眼睛来说几乎是不可区分的。与图像不同,两个文本序列如果不是相同的,就不可能真正无法区分

自然语言处理中的对立例子

因为两个文本序列从来都是不可区分的,研究人员已经为 NLP 中的对立例子提出了各种不同的定义。我们发现根据他们选择的对抗性例子的定义对对抗性攻击进行分组是有用的。

尽管 NLP 中的攻击无法找到与原始输入完全无法区分的敌对扰动,但它们可以找到非常相似的扰动。我们的心理模型根据“相似性”的概念将 NLP 对抗性攻击分为两组:

自然语言处理中的对立例子使用了两种不同的文本相似性概念:视觉相似性和语义相似性。[图片由作者提供]

  • 视觉相似度。一些 NLP 攻击认为一个敌对的例子是一个看起来与原始输入非常相似的文本序列——可能只是几个字符的变化——但是从模型接收到不同的预测。其中一些对抗性攻击试图改变尽可能少的字符来改变模型的预测;其他人试图引入类似人类会犯的真实“错别字”。

一些研究人员提出了这样的担忧,即通过使用基于规则的拼写检查器或训练来纠正对抗性拼写错误的序列对序列模型,可以非常有效地防御这些攻击。

属于这一类别的攻击配方: deepwordbug,hotflip,pruthi,textbugger,morpheus*

  • 语义相似。其他 NLP 攻击认为一个敌对的例子是有效的,如果它在语义上与原始输入不可区分的话。换句话说,如果扰动是原始输入的意译,但是输入和扰动接收不同的预测,那么输入是有效的对抗例子。

一些 NLP 模型被训练来测量语义相似度。基于语义相似性概念的对抗性攻击通常使用另一个 NLP 模型来强制扰动在语法上有效并且在语义上与原始输入相似。

属于这一类的攻击配方: alzantot,bae,bert-attack,faster-alzantot,iga,kuleshov,pso,pwws,textbugger,textfooler*

** text bugger 攻击使用类似打字错误的字符编辑和同义词替换来产生干扰。可以考虑使用不可区分性的两种定义。*

利用文本攻击生成对立范例

TextAttack 支持基于两种不可区分性定义的对抗性攻击。这两种类型的攻击对于训练更健壮的 NLP 模型都是有用的。我们的目标是通过提供一组直观的、可重用的组件,从文献中构建尽可能多的攻击,从而支持对 NLP 中对抗性例子的研究。

我们使用四个组件来定义对抗性攻击处理:目标函数、约束、转换和搜索方法。(我们将在以后的帖子中详细讨论这个问题!)这些组件允许我们在不同研究论文的攻击之间重用许多东西。它们也使得开发 NLP 数据扩充的方法变得容易。

TextAttack 还包括用于加载流行的 NLP 数据集和其上的训练模型的代码。通过将这种训练代码与对抗性攻击和数据增强技术相结合,TextAttack 为研究人员提供了一个在许多不同场景中测试对抗性训练的环境。

下图概述了 TextAttack 的主要功能:

TextAttack 功能概述。[图片由作者提供]

自然语言处理中对抗性攻击的未来

我们很高兴看到 TextAttack 对 NLP 研究社区的影响!我们希望看到的一件事是将不同论文中的成分结合起来。TextAttack 使运行消融研究来比较交换的效果变得容易,比如说,纸 A 中的搜索方法与纸 B 中的搜索方法,而无需进行任何其他更改。(这些测试可以在数十个预先训练好的模型和数据集上运行,无需下载!)

我们希望文本攻击的使用能使对抗性攻击更加多样化。当前所有对抗性攻击的一个共同点是,它们在单词或字符级别进行替换。我们希望 NLP 中未来的对抗性攻击可以扩大范围,尝试不同的短语级替换和整句释义方法。此外,在对抗性攻击文学中,英语一直是焦点;我们期待看到对抗性攻击应用于更多的语言。

如果您对 TextAttack 感兴趣,或者对为 NLP 模型生成对抗性示例这一更广泛的问题感兴趣,请联系我们!你可以看看我们在 ArXiv 上的论文或者在 Github 上的知识库。

[1]《用对抗性例子攻击机器学习》,Goodfellow,2013。https://openai.com/blog/adversarial-example-research/

[2]“神经网络的耐人寻味的性质”,赛格迪,2013。https://arxiv.org/abs/1312.6199

[3]“稳健性可能与准确性不一致”,齐普拉斯,2018 年。https://arxiv.org/abs/1805.12152

什么是分类变量,如何编码?

原文:https://towardsdatascience.com/what-are-categorical-variables-and-how-to-encode-them-6e77ddc263b3?source=collection_archive---------44-----------------------

初学者分类变量编码指南。

图片由 alan9187 来自 Pixabay

简介

在这篇文章中,我们将解释什么是分类变量,我们将学习不同类型的变量之间的区别。我们将讨论:

名义分类变量

对抗

有序分类变量。

最后,我们将通过例子了解对每个分类变量类型进行编码的最佳方法。我们将涵盖:

一个热编码

整数编码。

先说一些简单的定义。

什么是分类变量?

为了理解分类变量,最好先从定义连续变量开始。连续变量可以取任意数量的值。连续变量的一个很好的例子是体重或身高。理论上它们都可以取任何值。

分类变量是数据集中的变量,它不同于连续变量,取有限的一组值。例如,老师给学生的作业分数(A、B、C、D、E 和 F)。

分类变量的另一个例子是大学出售的球衣颜色。想象一下,他们只出售绿色、蓝色和黑色。球衣颜色是一个有三个可能值的分类变量。

在数据集中,分类变量通常是字符串。在上面的两个例子中,我们已经看到,它们是字符串,因为等级和颜色值都具有这种数据类型。

然而,我们需要小心,因为有时整数也可能隐藏分类。因此,在决定一个整型变量是连续变量还是分类变量之前,了解它有多少个唯一值是很重要的。

名义分类变量

上面给出的分类变量的例子并不完全相同。正如你的直觉所暗示的,球衣颜色和等级是有区别的。球衣的颜色是绿色、蓝色和黑色,它们之间没有任何排序。如果分类变量的值之间缺乏任何逻辑排序,我们称之为名义变量

有序分类变量

有序分类变量是指其值之间具有某种逻辑顺序的分类变量,就像我们的年级示例一样。记得等级从 A 到 F,有一个有序的关系(A > B > C > D > E > F)。

分类顺序变量的其他例子有滑雪道分类:简单、中等和困难。

需要编码

为什么我们需要对分类变量进行编码?

原因很简单,大多数机器学习算法只允许数字形式的特征。这意味着它们必须是浮点数或整数,而字符串是不允许的。正如我们之前提到的,分类特征通常是字符串,因此我们需要将它们编码成整数。

对于名词性分类变量和序数分类变量来说,这样做的方式有点不同,我们将在下面的章节中解释这种不同。

一种热编码——最适合名义分类变量

我们要学习的第一种方法叫做一键编码,它最适合于名义变量。在使用一次性编码时,我们为每个变量值创建一个新变量。

让我们回到球衣颜色的例子。我们有三种颜色值:绿色、蓝色和黑色。因此,我们需要创建三个新变量,每种颜色一个,并为每个变量分配一个二进制值 0 或 1,1 表示球衣是该颜色,0 表示球衣不是可变颜色。为了应用一键编码,我们可以在 pandas 中使用 get _ dummmies()函数。

我们用一个真实的例子来演示一下。想象一下,我们有一个保存学生信息的数据集,其中有学生的姓名、成绩和学生在注册大学时选择的球衣颜色。我将创建一个包含五名学生信息的数据框架。

import pandas as pd
import numpy as np
student_dictionary = {'name': ['Michael', 'Ana', 'Sean', 'Carl', 'Bob'], 
                     'grade': ['A', 'C', 'A', 'B', 'F'], 
                     'jersey': ['green', 'green', 'blue', 'green', 'black']}
df = pd.DataFrame(student_dictionary)
df.head()

正如我们所看到的,这是一个只有五个学生条目和三列的数据框:姓名、年级和球衣。这里的 Jersey 只有三个值:绿色、蓝色和黑色。它们之间没有逻辑顺序,因此我们可以应用一键编码。我们将使用熊猫的 get_dummies()函数来实现。

pd.get_dummies(df.jersey)

这些是我们创造的虚拟变量。如你所见,有三个不同值的分类变量 jersey 现在由三个二元变量描述:黑色、蓝色和绿色。

如果我们将 jersey 变量替换为它的虚拟变量,并输入到机器学习模型中,我们还应该确保丢弃一个二元变量。这样做的原因是为了避免虚拟变量之间的完美相关性。使用 get_dummies 函数时,通过将 drop_first 参数设置为 True,可以很容易地删除第一个二元变量。

pd.get_dummies(df.jersey, drop_first=True)

正如我们所见,第一个二元变量现在被排除在结果之外。两个结果变量蓝色和绿色现在准备好被传递给机器学习算法。

整数编码——最适合有序分类变量

为了对有序分类变量进行编码,我们可以像对标称变量一样使用一键编码。然而,这不是最好的选择,因为我们会丢失一些关于变量和排序的信息。

更好的方法是使用整数编码。每个变量都将被转换成相应的整数。这样我们就能保持秩序。因此,我们可以通过以下方式对样本数据框中的等级进行编码:

答-> 1

B -> 2

C -> 3

D -> 4

E -> 5

F -> 6

为了用 pandas 做到这一点,我们可以用映射创建一个字典,并使用 map()函数:

mapping_dictionary = {'A': 1,
                      'B': 2,
                      'C': 3,
                      'D': 4,
                      'E': 5,
                      'F': 6,
                     }
df.grade.map(mapping_dictionary)0    1
1    3
2    1
3    2
4    6
Name: grade, dtype: int64

正如您所看到的,map 函数返回了一个应用了映射的转换后的序列。现在,这可以添加到数据框中,并用作机器学习模型中的一个特征。

还有其他方法来应用整数或标签编码(整数编码的另一个名称),但使用映射函数和字典方法是我的最爱之一。这是因为它给了我们分配映射值的控制权。

想象一下,除了标准分数之外,我们想要增加一个新的值:“甚至没有尝试过”,并且我们认为不尝试测试比以最低分数不及格要糟糕得多。在这种情况下,我们可以为“甚至没有尝试”映射值 10,表明这比映射中值为 6 的最差可能标记 F 差得多。

总结

在本文中,我们已经了解了什么是分类变量。我们已经讨论了顺序和名义分类变量,并展示了为机器学习模型编码它们的最佳方式。

我希望你现在知道更多关于分类变量的知识,并且你将能够在开发你的第一个机器学习模型时应用这些知识。

最初发布于 aboutdatablog.com: 什么是范畴变量,如何编码?2020 年 5 月 28 日。

PS:我正在 Medium 和上撰写深入浅出地解释基本数据科学概念的文章。你可以订阅我的* 邮件列表 *每次我写新文章都会收到通知。如果你还不是中等会员,你可以在这里加入**

下面还有一些你可能喜欢的帖子

** [## 9 熊猫有效数据分析的可视化技术

学习如何使用折线图、散点图、直方图、箱线图和其他一些可视化技术

towardsdatascience.com](/9-pandas-visualizations-techniques-for-effective-data-analysis-fc17feb651db) [## python 中的 lambda 函数是什么,为什么你现在就应该开始使用它们

初学者在 python 和 pandas 中开始使用 lambda 函数的快速指南。

towardsdatascience.com](/what-are-lambda-functions-in-python-and-why-you-should-start-using-them-right-now-75ab85655dc6) [## Jupyter 笔记本自动完成

数据科学家的最佳生产力工具,如果您还没有使用它,您应该使用它…

towardsdatascience.com](/jupyter-notebook-autocompletion-f291008c66c)**

数据科学招聘人员在简历中寻找什么?

原文:https://towardsdatascience.com/what-are-data-science-recruiters-looking-for-in-a-resume-edc90b28bee6?source=collection_archive---------11-----------------------

从与 DS 招聘人员的交谈中获得的见解。

为面试或社交活动准备一份好的数据科学简历从来都不容易,不是吗?准备一份“被录用”的简历需要大量的学习、探索、理解和分析。

数据科学是一个跨学科的领域,一个数据科学家应该知道很多事情;算法、科学方法、流程和系统,用于从数据中提取见解,并基于这些知识做出决策。

无论你在数据科学之旅中投入了多少工作,或者你过去参加过什么数据科学认证或课程,面试官肯定会问你一系列你没有想到会遇到的问题,或者你的简历中没有列出的技能。但这是你必须面对的,对吗?

在这个故事中,我列出了招聘人员希望在你的数据科学简历上看到的要点,这些要点是在与 80 多名数据科学招聘人员和雇主交谈和面试后整理的。

1.根据职位描述整理简历

雇主总是在寻找你的简历与他们工作描述的“相关性”。即使有一个机器人浏览你的简历,他们也更关心你是否想在数据科学领域谋得一份职业,而不是你是否想在他们那里谋得一份职业。在你开始整理你的数据科学简历之前,确保你知道你要把简历发给谁;商业专长。

如果工作描述是金融公司或食品饮料公司,你可以试着展示至少一些领域知识。实际上,你的简历不会因为你申请的每一份工作而大相径庭,但它应该有些不同。

我遇到的一位来自 Discover 的招聘人员告诉我“我们欣赏与众不同的简历;我们喜欢想要这份工作而不是任何工作的候选人。”

申请人有时无法理解根据职位描述修改简历的重要性,这通常概括了被拒的主要原因之一:领域专长。招聘人员会看你是否适合这家公司、这个部门以及他们参与的项目?你的数据科学简历是否反映了你非常适合这一事实?

2.选择正确的关键词

如果是数据科学,它必须有数据库、机器学习、统计的部分或形式,

除了寻找合适的人选之外,选择适合你的合适词汇也很重要,同时也要向招聘人员展示你的潜在合适度。简历大多由申请人跟踪系统(ATS)扫描。ATS 简历扫描软件旨在扫描简历中的工作经验、技能、教育和其他相关信息。

通过 ATS 获得数据科学硬技能的关键词

确保你简历中的关键词和你的经历能够反映公司的使命和愿景。(我们努力做到完美契合!)

该公司的简历扫描软件通常会选择带有特定关键词的简历,所以即使你想加入常见数据科学关键词的同义词,也应该可以。但是,阅读职位描述是非常重要的。

有时,在求职信中包含关键词也会有所帮助。在信的正文中包含关键词,确保它们与工作清单中提到的最重要的关键词和技能相匹配。

3.指出你在必要技能方面的专长

注意价格!

一位来自 迪士尼 的招聘人员就明确提到了这一点:“一位招聘人员想看看应聘者是否真的为她申请的职位做了些什么。如果我们看到技能、项目、课程或认证与我们现在谈论的完全一致,你和我们都是好的。”

简历的格式非常重要。当谈到强调你的工作时,简历应该准确地指出为什么招聘人员对你感兴趣。

一份数据科学家的简历应该展示你在管理数据方面的能力,以及从项目中获得的软技能。

另一位来自美国银行的招聘人员指着我简历上的项目部分说:“如果你曾致力于提高某项技能、领域或技术的能力水平,这肯定会在你的简历中体现出来。这就是我们所寻求的;一个不断学习和实施的循环。”

4.你的 X 因素

总的来说,人们会认为我在简历中加入一个奖项爱好部分而不是一个完整的开场白总结是愚蠢的。

我选择不回避自己独特的兴趣和成就。

简历看起来非常相似的概率为 7/10,在简历中加入一个部分或内容来识别你总是有帮助的。我简历上的爱好包括股票交易、博客和印度古典舞,在我与招聘人员的大部分互动或面试中,我被要求更多地谈论这些;目标是一个新颖的对话。

在我与 Intuit 的面试中,招聘人员本人接受了与我相同的舞蹈形式训练,她确实与我就此进行了长达 3 分钟的对话,这在面试中是很重要的。

在与查尔斯·施瓦布的面试中,招聘人员问我至今持有哪些股票,以及我是否在寻找新的股票进行投资。对《泰晤士报》来说,我有他们所有问题的完美答案。

同样,这样的部分不仅仅是将你与其他候选人区分开来,而是引入与招聘人员谈话的新话题;展示课外活动的人。

5.写出简明扼要的要点

不是所有的招聘人员都是领域专家,除非是有针对性的信息会议或实际的招聘过程。

关于你在一个项目中所做的事情的冗长的要点绝对是有害的!

大型招聘会招聘人员看简历,相当字面意思!据我观察,在参加招聘会时,有 100 多名求职者在同一个展位等着与招聘人员交谈,如果招聘人员发现一个项目、相关技能或工作经验会让你“非常适合”,那么一眼就能看出这一点。

例如,对于你做的一个机器学习项目,你如何记录它以引起招聘人员的注意?

  • 好了,接下来:在数据集上训练优化了一个随机森林机器学习模型,预测葡萄酒的品质,准确率达到 99%。
  • 好:训练了一个随机森林,以 99%的准确率预测葡萄酒质量。

关键是要简明扼要。避免隐含的或多余的短语,重新安排冗长的短语或避免过于冗长的先前经验。向…深处铺路

接下来,用粗体强调你简历中的数字或指标,以展示你能够带来的影响,而不是仅仅提到冗长的最高级。

  • 好的,下一个:使用 SVM 显著提高了转换率,大幅降低了跳出率。
  • 良好: 加倍转换率0.5%到 1% 并且使用 SVM 将反弹率*降低 18% 。*

在简历中加入一些小而重要的内容肯定有助于获得更多的关注和互动。

感谢您的阅读!我希望你喜欢这篇文章。一定要让我知道你的简历上已经有了哪些你打算在简历上更新的东西。祝愿在这个季节寻找工作的人们一切顺利!

探索快乐!

免责声明:本文表达的观点仅代表我个人,不代表严格的观点。

了解你的作者

拉什是芝加哥伊利诺伊大学的研究生。她喜欢将数据可视化,并创造有见地的故事。她是用户体验分析师和顾问、技术演讲者和博客作者。

什么是特征存储,为什么它们对扩展数据科学至关重要?

原文:https://towardsdatascience.com/what-are-feature-stores-and-why-are-they-critical-for-scaling-data-science-3f9156f7ab4?source=collection_archive---------4-----------------------

每个人都需要了解的数据科学特性

来源:Shutterstock

什么是特色店?

如果数据是新的黄金(过度使用,但仍然是真实的),我会说特征实际上是金条,因此需要相应地对待。为了得到黄金,你需要做一些挖掘和艰苦的工作,这对于找到正确的特征也是如此。

创建特征的过程被称为特征工程,对于任何机器学习过程来说,这是一个非常复杂但又非常关键的组件。更好的特性意味着更好的模型会带来更好的业务成果。

生成新功能需要大量的工作,而创建构建功能的管道只是一个方面。为了达到那个阶段,你可能有一个长时间的试验和错误过程,有大量不同的特性,直到你对你的新特性满意为止。接下来,您需要将它作为操作管道的一部分进行计算和存储,这取决于该特征是在线还是离线。

最重要的是,每个数据科学项目都是从寻找合适的功能开始的。问题是,在大多数情况下,没有一个单一的,集中的地方来搜索;功能在任何地方都可以托管。因此,首先也是最重要的是,功能商店提供了一个单一平台来共享所有可用的功能。当数据科学家开始一个新项目时,他或她可以访问该目录并轻松找到他们正在寻找的功能。但是,特征存储不仅仅是数据层,它还是一种数据转换服务,使用户能够操作原始数据并将其存储为可供任何机器学习模型使用的特征。

离线和在线功能

有两种类型的功能:在线和离线

离线特征 —一些特征作为批处理作业的一部分进行计算。例如,平均每月花费。它们主要由离线进程使用。鉴于其性质,创建这些类型的功能可能需要时间。通常,离线特征是通过 Spark 等框架计算的,或者通过简单地对给定的数据库运行 SQL 查询,然后使用批处理推理过程。

在线功能 —这些功能有点复杂,因为它们需要非常快速地计算,并且通常以毫秒级延迟提供。例如,为实时欺诈检测计算 z 分数。在这种情况下,通过实时计算滑动窗口上的平均值和标准偏差来构建管道。这些计算更具挑战性,需要快速计算以及快速访问数据。数据可以存储在内存或非常快速的键值数据库中。该流程本身可以在云中的各种服务上执行,也可以在 Iguazio 数据科学平台等平台上执行,该平台将所有这些组件作为其核心产品的一部分。

下面是一个使用功能库的在线和离线管道的示例。这是优步设计的米开朗基罗平台的一部分:

优步内部 ML 即服务系统的架构

好处:

发展更快

理想情况下,数据科学家应该专注于他们研究做什么和他们最擅长什么——建立模型。然而,他们经常发现自己不得不将大部分时间花在数据工程配置上。一些特性的计算成本很高,需要构建聚合,而另一些特性则非常简单。但这真的不是数据科学家应该关心的事情,也不应该阻止他们为自己的模型利用最好的功能。因此,特征库的概念是抽象所有这些工程层,并提供读取和写入特征的简单访问。

如前所述,在线和离线功能具有不同的特征。在幕后,离线特性大多构建在 spark 或 SQL 等框架上,实际的特性存储在数据库中或作为 parquet 文件。而在线功能可能需要使用 Kafka、Kinesis 等流媒体引擎的 API 或 Redis 或 Cassandra 等内存键值数据库进行数据访问。

使用功能存储抽象了这一层,因此当数据科学家寻找功能时,他可以使用简单的 API 来检索他需要的数据,而不是编写工程代码。这可能很简单,只需运行以下命令:

df = feature _ store . get(" transaction _ volume ")。filter_by(事务标识)

在生产中顺利部署车型

在生产中实现机器学习的一个主要挑战来自于这样一个事实,即在开发环境中用于训练模型的功能与生产服务层中的功能不同。因此,在培训层和服务层之间启用一致的功能集可以使部署过程更加顺畅,确保经过培训的模型确实反映了生产中的工作方式。

提高模型精度

除了实际的要素之外,要素存储还保存每个要素的附加元数据。例如,显示功能对与其相关的模型的影响的指标。在为新模型选择功能时,这些信息可以极大地帮助数据科学家,使他们能够专注于那些对类似的现有模型产生更好影响的功能。

更好的协作
老话说得好——分享就是关爱!今天的现实是,几乎每个新的业务服务都是基于机器学习的,因此项目和功能的数量正在呈指数级增长。这降低了我们全面了解可用特性的能力,因为这些特性实在太多了。功能库允许我们与同行共享我们的功能及其元数据,而不是在孤岛中开发。在大型组织中,不同的团队最终开发出相似的解决方案,仅仅是因为他们不知道彼此的任务,这已经成为一个普遍的问题。特色商店弥补了这一差距,使每个人都能够分享他们的工作,避免重复。

跟踪血统并解决法规遵从性问题

为了满足指南和法规的要求,尤其是在生成的人工智能模型服务于医疗保健、金融服务和安全等行业的情况下,跟踪正在开发的算法的血统非常重要。要实现这一点,需要了解整个端到端数据流,以便更好地理解模型是如何生成结果的。由于特征是作为过程的一部分生成的,因此需要跟踪特征生成过程的流程。在特征存储中,我们可以保留特征的数据血统。这提供了必要的跟踪信息,可以捕获功能是如何生成的,并提供法规遵从性所需的洞察力和报告。

功能存储和 MLOps

MLOps 是 DevOps 的扩展,其思想是将 DevOps 原则应用于机器学习管道。开发一个机器学习流水线和开发软件不一样,主要是数据方面的原因。模型的质量不仅仅基于代码的质量。它还基于用于运行模型的数据(即要素)的质量。据 Airbnb 称,数据科学家大约 60%-80%的时间用于创建、训练和测试数据。要素存储使数据科学家能够重用要素,而不是为不同的模型一次又一次地重新构建这些要素,从而节省了宝贵的时间和精力。特性存储使这一过程自动化,并且可以在推送到 Git 的代码更改或新数据到达时被触发。这种自动化特征工程是 MLOps 概念的重要组成部分。

总结

一些与人工智能广泛打交道的大型科技公司已经建立了自己的特色商店(优步、推特、谷歌、网飞、脸书、Airbnb 等)。).这很好地向业内其他人表明了使用特性库作为高效 ML 管道的一部分是多么重要。鉴于人工智能项目的数量不断增加以及将这些项目投入生产的复杂性,行业需要一种方法来标准化和自动化功能工程的核心。因此,假设特征存储被定位为任何机器学习管道的第一级公民是公平的。

人类有什么用?自动化和独创性

原文:https://towardsdatascience.com/what-are-humans-good-for-automation-and-ingenuity-a6f68fa3d8c3?source=collection_archive---------62-----------------------

自动化流程解放了人类的时间和创造力。也许他们也会让我们成为更好的人。

Clem Onojeghuo 在 Unsplash 拍摄的照片

我最近阅读的一篇研究论文让我思考:流程自动化不仅能通过帮助我们避免枯燥的任务,还能从根本上改变我们的思维方式,从而赋予人类力量吗?将自动化过程视为与人类的合作者,而不仅仅是简单的替代者,为人类和算法开辟了一个全新的可能性领域。

大约在同一时间,Alteryx 在举办了第一次 Twitter 聊天,讨论数据民主化和提高数据职业技能等话题。聊天中的第 5 个问题与自动化、人工智能的作用以及人和算法如何协同工作等问题紧密相连:

这里有很多话要说!✅,我们去兜兜风吧🚗变得更有哲理🤔。

少一些乏味,多一些创意✅

聊天中的每个人都理所当然地对自动化取代日常工作中枯燥部分的潜力感到兴奋:

改变容易出错的人的角色还有另一个好处:

我们人类拥有能够进行复杂推理的奇特大脑,但我们仍然会犯错。单调乏味的任务会变得令人麻木,以至于无聊的人开始犯错误。幸运的是,算法不会疲劳;他们继续按照要求,一排接一排地清理、分类、预测。

完全自动驾驶与人工参与🚗

自动化解放了人类的脑力,使其专注于最适合的任务:

但这里有一个有趣的困境:某些类型的人类参与对参与预测算法应用的每个人都有益吗?

想象一下这个(稍微)未来的场景。你在自动驾驶汽车的方向盘后面。汽车处于“自动驾驶”状态,正沿着你熟悉的路线行驶。你应该在汽车行驶时保持警惕,但你的手机上也有一封你真的需要回复的电子邮件。你拿起手机开始写,忽略了车在做什么。自动化将你从驾驶(一项通常枯燥、非智力任务)中解放出来,这样你就可以专注于一项更适合人类的任务,这项任务涉及批判性思维和语言技能,目前超出了人工智能的能力。鉴于 94%的严重车祸据说是由人为错误造成的,自动驾驶也可能减少事故。

但自动驾驶技术尚未完善或普及。仍然有一个具有批判性思维能力的“人在决策过程中”。

图片来自SAE

如果自动化是💯,丢的是什么?

然而,总有一天,我们会拥有广泛、熟练的自动驾驶技术。当像驾驶这样的日常任务实现自动化时,作为旁观者的人参与进来的动机是什么?为什么不写那封邮件而不看路呢?

随着人工智能可以处理越来越复杂的任务,人类仍然是人类。我们仍然需要感到被重视,这样我们才有动力参与自动化过程的结果。如果我们能够制造一辆完美的自动驾驶汽车,并确保始终处于理想的驾驶状态,那么人类就没有动力看路了。

同样,如果我们可以使用人工智能来完美地选择抵押贷款的申请人,或者在各种媒体上投放广告以产生线索的理想位置,或者新零售店的位置——为什么与这些过程相关的人类要花费额外的时间来彻底研究申请人、媒体或位置?

人类可能会忍不住说,“哦,我相信人工智能是对的。”我们可能会失去人类带给这些过程的重要细微差别和高级批判性思维。

与自动化协作制定决策🤔

研究人员一直在探索这种微妙的平衡。他们正在考虑是否、何时以及如何保持人类在流程和决策中的作用,从理论上来说,可能会完全自动化,但仍然会受益于人类的合作。

最近的一篇论文“人类和人工智能决策权的分配”深入研究了人类和人工智能在决策过程中的作用:

…我们考虑一个委托人[一个组织领导人],他面临一个选择,即在做决定时是给人类代理人还是给人工智能权力。人工智能的引入如何影响人类的努力?当人工智能预测准确时,人类会不会过于放松努力(“在方向盘上睡着”)?人工智能或人类何时有权做出最终决定?统计预测意义上的“更好的”人工智能对一个组织来说一定更有利可图吗?

这些研究人员并没有得出人类应该做所有决定的结论。他们不是反科技或制造恐慌。如果有的话,他们揭示了对人类抛开偏见和接受新观点的能力的怀疑,他们提出人工智能可以帮助我们超越我们的思维习惯。

这项研究的酷之处还在于它对人工智能的不同思考方式。作者认为,我们可能不总是想要技术上最高性能的模型,这些模型通常提供近乎完美的预测,并可能自动化人类角色(他们称之为“替代人工智能”)。他们说,有时这很好,但人工智能的“不完美”建议在某些情况下可能更有益。

一个“增强人工智能”能够合理地执行并通知人类,但不接管最终决策,在许多情况下可能是最具生产力的(也是利润最大化的)。虽然从技术角度来看并不完美,但这种合作让人们有动力从他们独特的、有价值的视角来评估数据。这种人类/人工智能的“增强”既允许高效、减少厌倦的决策自动化,也允许人类保持意识和捕捉错误的动机。**

🍦或者🏋️?用人工智能故意惹恼人类😡

令人惊讶的是,这些研究人员提出,在某些场景下,使用他们所谓的“不可靠的人工智能”或“对抗性人工智能”甚至可能是富有成效的和利润最大化的。

他们说,不可靠的人工智能可能是理想的,当需要让人类特别有动力保持参与时。想象一下,你回到了自动驾驶汽车中,但现在汽车有了一项“功能”,可以在未知的时间间隔内偶尔关闭自动驾驶模式一分钟。你不知道那什么时候会发生,所以你把你的手放在方向盘上,保持对情况的了解,而不是写那封邮件。你可能讨厌这辆车的这个特点,但你不得不承认它让你保持警觉。类似地,不可靠的人工智能将通过提供不太完美的表现来确保一些人类参与和动机,需要人类干预来纠正其偶尔的错误。

“对抗性人工智能”走得更远,它做出主动“对抗性”或挫败接收人工智能结果的人类的决定。众所周知,这些决定会与人类现有的偏见相冲突,迫使他们重新考虑自己的偏好,更加努力地思考他们为什么要做出某个决定。

想象一下,现在你已经把你的目的地——当地的冰淇淋店——输入到你的自动驾驶汽车的导航系统中,它回应道,“真的吗?你确定吗?不,我们去健身房吧,”然后开始开车送你去健身房。你必须主动超越系统,才能回到冰淇淋的轨道上。虽然你可能会觉得汽车的反应相当恼人,但你也(可能不情愿地)不得不问自己:我现在应该去哪里:去买冰淇淋还是去健身?

对抗性的人工智能会做出人类可能不喜欢的决定,因此人类必须更深入地参与决策——并且,或许,会在这个过程中重新评估他们的倾向和偏见。研究人员以一位招聘经理为例,他的人工智能工具会建议一些候选人,这些候选人的特征与经理的偏见相冲突(例如,亲和力偏见,这是一种普遍持有的偏见,倾向于雇用与自己背景相似的人)。经理可能会发现这些建议令人沮丧,但他们必须做出更合理的努力,向自己和他人解释为什么应该或不应该考虑那些不太相似的候选人。最终,对抗性人工智能帮助人类基于更彻底的推理做出更强有力的决定的能力可以支持组织目标并增加利润。

人类如何随着人工智能的补充而改变,或者😃 ➕ 🤖 = ❓

我们现在才开始看到自动化将如何释放时间、创造力和创新机会,以便人类可以探索和设计全新的事物。

但正如这里讨论的研究表明的那样,也许这些自动化人工智能过程还有另一个我们通常不考虑的哲学层面,一些超越最大化技术性能的东西。这些技术在补充人类努力的同时,不仅仅可以减少单调乏味。它们也有可能以简单而深刻的方式改变我们的思维方式。即使技术上不太理想的模型也可能通过提供新的视角来帮助我们探索我们的推理和决策——并帮助我们成为更有洞察力、更有思想的人。

阅读更多关于聊天中的前三个问题。

原载于 Alteryx 社区 并精选于 Alteryx 数据科学门户

python 中的 lambda 函数是什么,为什么你现在就应该开始使用它们?

原文:https://towardsdatascience.com/what-are-lambda-functions-in-python-and-why-you-should-start-using-them-right-now-75ab85655dc6?source=collection_archive---------14-----------------------

初学者在 python 和 pandas 中开始使用 lambda 函数的快速指南。

图片由来自 PixabayXavier Espinosa 拍摄

许多初学数据的科学家听说过 lambda 函数,但可能不确定它们是什么以及如何使用它们。本文将解释:

什么是 lambda 函数?

lambda 函数和普通函数有什么不同?

lambdas 函数为什么有用?

will 将给出一些 lambda 函数在 python 和 pandas 中的实际用法。

让我们开始吧。

什么是 lambda 函数,它们与普通函数有什么不同?

这里我假设您熟悉普通的 python 函数定义。它总是以单词 def 开头,后面是函数名、括号中的参数,最后是冒号。然后在新的一行或多行中,我们有一个函数体来执行所需的操作,通常以返回语句结束。让我们来看看这个函数的例子,它执行一个非常简单的操作,将一个数字加 1:

def add_one_to_number(number):
    return number + 1

上述函数实际上可以用 lambda 符号重写:

lambda x: x + 1

您会注意到,为了使用 lambda 函数,您需要使用 lambda 关键字,后跟参数名(通常是一个字母)和一个冒号。冒号后面是函数定义。仅此而已。

您可以看到,这个定义比您习惯的普通 python 函数定义简单得多。它简单、简洁,可以用一行代码编写。在继续之前,有一些关于 lambda 函数的重要事情需要记住:

Lambda 函数有时被称为匿名函数。这是因为它们没有名字。

Lambda 函数只能接受一个表达式,因此您将无法创建长的多表达式函数定义。

为什么 lambdas 函数有用?

一旦你理解了 lambda 函数就像是没有名字的普通函数,并且是用单一表达式编写的,那么就该解释为什么它们是有用的了。当您想要使用将另一个函数作为参数的函数时,它们会很有用。python 中这种函数的一个例子是:filter()、map()或 reduce()。

lambda 函数变得如此有用的原因是,使用简单明了的 lambda 符号通常比以传统方式定义新函数更方便,特别是如果函数被设计为只执行一个单一操作,而不是作为可重复的组件。

python 中 lambda 函数的一个实际例子。

让我们看看如何使用带有 lambda 符号的 python filter()函数。 Filter() 函数将一个函数作为第一个参数(这将是我们的 lambda 函数),将 list 作为第二个参数,我们要对其应用过滤函数。让我们看一个例子:

my_list = [1, 2, 3, 4, 5]
list(filter(lambda x: x > 2, my_list))[3, 4, 5]

在上面的例子中,我们可以看到我们使用了 filter()函数和一个被定义为 lambda x: x > 2 的匿名函数,并将其应用于 my_list 。因此,我们过滤了初始列表,只包含大于数字 2 的元素,结果得到[3,4,5]。注意,我们必须将 filter()函数的结果改为一个列表,否则结果将是一个 filter 对象而不是列表本身。

我们可以以类似的方式对 map()reduce() 使用 lambda 符号,但是我们不打算在这里讨论它。Filter()示例应该可以让你自己理解如何使用 lambda 实现上述功能。相反,我们将转到一些熊猫函数的例子。

lambda 函数与熊猫应用的实际例子()

作为一名数据科学家,你会经常使用熊猫图书馆,这是一个你会经常使用 lambda 符号的地方。匿名函数主要与 apply()、applymap()和 map()一起使用。如果你不确定这些函数是什么,你可以看看我解释它们用法的文章:

* [## Pandas 数据操作函数:apply()、map()和 applymap()

以及如何在熊猫身上正确使用它们…

towardsdatascience.com](/pandas-data-manipulation-functions-7b3519fc1370)

如果你已经知道这些函数是如何工作的,你可以直接跳到例子中。我们先从加载虹膜数据集开始。

from sklearn import datasets
import pandas as pdiris_data = datasets.load_iris()
df_iris = pd.DataFrame(iris_data.data,columns=iris_data.feature_names)
df_iris['target'] = pd.Series(iris_data.target)
df_iris.head()

现在让我们创建一个函数,它将在初始的萼片长度列的基础上添加一个萼片长度描述列。为此,我们将在萼片长度列上使用 apply()。

df_iris['sepal_length_description'] = df_iris['sepal length (cm)'].apply(lambda x: 'sepal length is: ' + str(x))
df_iris.head()

如您所见,我们已经创建了一个简单的函数“on the go ”,它连接了字符串“ sepal length is: ”,结果是将 sepal_length 列的数值更改为字符串。

可以想象,带有 lambda 符号的 apply()非常强大,它将允许您高效地操作和创建具有所需结果的新列。但是,如果您想对多个数据框列使用 lambda 函数,会发生什么情况呢?*

如何通过 apply()使用 lambda 函数并访问不同的列

如上所述,您可以使用 lambda 函数和 apply()来组合来自不同列的信息。说明这一点的一个很好的例子是对 Iris 数据集使用 apply()函数。我们将合并几个栏目的信息,创建一个名为“sepal description”的新栏目:

*df_iris['sepal_description'] = df_iris.apply(lambda x: 'sepal length/width ration is :' + str(round(x['sepal length (cm)'] / x['sepal width (cm)'], 2)), axis=1)
df_iris.head()*

如您所见,我们在这里使用了整个数据框的 apply()函数。在这个例子中,变量“x”指的是整个数据帧,我们可以像对传统数据帧那样调用各个列。因此,我们使用 x['萼片长度(厘米)']x['萼片宽度(厘米)'【T3]]来计算萼片比例,然后我们对结果进行舍入,将其改为浮点型,最后将结果连接到描述字符串。

这个例子很好地展示了 lambda 函数在处理数据时是多么有用。这里我们只使用了两列,但是您可以很容易地看到,如果您的操作需要,您可以访问任意数量的列。

总结

在这篇简短的文章中,我们解释了什么是 lambda 函数,以及如何在 python 和 pandas 中使用它们。我们已经介绍了一个 filter()示例,然后演示了如何将 lambdas 与 apply()一起用于 os 系列和 DataFrame 对象。

我希望您已经发现这些示例很有用,并且您将开始在自己的代码中使用 lambdas。

最初发布于 about datablog . com:python 中的 lambda 函数是什么,为什么你现在就应该开始使用它们?2020 年 4 月 16 日。

PS:我正在aboutdatablog.com上撰写深入浅出地解释基本数据科学概念的文章。 如果你喜欢这篇文章,还有一些其他的你可能会喜欢:

* [## Pandas 数据操作函数:apply()、map()和 applymap()

以及如何在熊猫身上正确使用它们…

towardsdatascience.com](/pandas-data-manipulation-functions-7b3519fc1370) [## 对熊猫中的数据框进行排序

如何快速有效地排序数据帧

towardsdatascience.com](/sorting-data-frames-in-pandas-a5a3af6f346a) [## Jupyter 笔记本自动完成

数据科学家的最佳生产力工具,如果您还没有使用它,您应该使用它…

towardsdatascience.com](/jupyter-notebook-autocompletion-f291008c66c)*

人们都在问新冠肺炎什么?一种新的问题分类数据集

原文:https://towardsdatascience.com/what-are-people-asking-about-covid-19-a-new-question-classification-dataset-adcaeaddcce4?source=collection_archive---------70-----------------------

COVID-Q 是一个新的数据集,包含 1,690 个关于新冠肺炎的问题,已被注释为 15 个问题类别和 207 个问题类别。

这个问题。在像目前新冠肺炎疫情这样的大规模流行病期间,最大的挑战之一是能够让人们了解最新和最相关的信息。即使像疾病预防控制中心和食品及药物管理局这样的知名来源维护着新冠肺炎的常见问题网站,用户可能仍然很难找到他们的问题,许多常见问题仍然没有答案。

我与其他研究人员合作编译了 COVID-Q [ 数据集链接 ],这是一个新冠肺炎问题的数据集,希望这个数据集对其他研究人员有用。我们的全文可以在这里找到。

数据集—概述。COVID-Q 是一个由 13 个在线来源的 1690 个关于新冠肺炎的问题组成的数据集。数据集通过将问题分类为 15 个问题类别以及将询问相同问题的问题分组为 207 个问题类别来进行注释。

COVID-Q 可用于多种问题理解任务:

  • 问题类别可用作标准文本分类任务,以确定问题询问的信息的一般类别。
  • 问题类可用于检索问题回答。在这个任务中,系统有一个问题和答案的数据库。给定一个新问题,系统必须在数据库中找到与给定问题提出相同问题的问题,并返回相应的答案。

COVID-Q 中问题的来源分布。报告的问题数量不包括已经删除的无关、模糊和无意义的问题。A *表示问题来自 FAQ 页面。

数据采集和处理。为了收集数据,搜集了十三个来源来收集关于新冠肺炎的问题;其中 7 个来源是来自 CDC 和 FDA 等知名组织的官方 FAQ 网站,6 个来源是基于人群的(如 Quora、Yahoo Answers)。

COVID-Q 中问题类别的分布,每个类别的问题数量显示在括号中。

数据标注。数据集有两种注释方式。首先,问同样问题的问题被手动分组到问题类别中。两个问题被定义为问相同的问题,如果它们可以用相同的答案来回答。接下来,每个至少有两个问题的问题类被赋予一个名称,这个名称概括了问题类询问的内容。然后使用这些来将每个问题分类到上图所示的 15 个问题类别中的一个。在下图中也可以看到问题类的分布。

至少有两个问题的所有问题类的每个问题类的问题数。问题类中的所有问题问的都是同一个问题。

标注质量。现在,你可能想知道:如果这些问题是人工标注的,我们怎么能相信你没有疯狂地标注呢?嗯,这是个公平的观点。为了验证注释的质量,标签由两个合作者进行了两轮验证。在这些验证中,每个合作者独立检查给予每个问题的类别和类标签,以验证标签是正确的。在第一轮验证中,有 67 个标签被更改。在第二轮验证中,又修改了 15 个标签。

我们还通过向三名土耳其机械工人展示每个问题类中的三个随机问题(至少四个问题)来验证注释。给定一个问题,我们要求每个工人从五个选项中选择最能描述该问题的问题类别,其中一个是我们的原始注释。对于这些抽样问题,我们 93.3%的标签同意工人的大多数投票。

官方 FAQ 网站没有回答的常见问题示例。中间一列表示问题类别中的问题数量(即,询问此问题的问题的出现次数)。

常见问题不匹配。我们发现一个有趣的现象,即疾病预防控制中心和食品及药物管理局等政府机构的常见问题网站上有很大一部分问题与其他来源的问题不匹配。例如,44.6%的疾病预防控制中心的常见问题是不匹配的,42.1%的食品和药物管理局的常见问题是不匹配的。此外,54.2%的问题类别包含来自至少两个非官方来源的问题,但仍未得到官方来源的回答。这些数据似乎表明,组织认为人们正在询问的关于新冠肺炎的问题和人们实际上正在询问的关于新冠肺炎的问题之间存在不匹配。

作者生成的问题。由于数据集在分成训练集和测试集时很小,因此手动生成了 249 个问题。这些问题以与其他问题相同的方式进行了注释和验证。

问题分类任务。如前所述,COVID-Q 可用于问题类别分类(这个问题问的是什么类型的信息?)和问题类分类(还有什么问题在问和这个问题一样的东西?).

问题类别分类。问题类别分类任务将每个问题分配到一个宽泛的类别。对于我们的基线,我们为训练集的每个类别选择了 20 个随机问题,并将剩余的问题放入测试集中。下表显示了这种数据集分割。

问题类别分类的数据分割。

我们使用支持向量机(SVM)和基于余弦相似性的 k-近邻分类(k-NN)作为我们数据集的基线模型,其中 k = 1。通过获得每个问题的 BERT 平均汇集令牌,对这些模型进行评估。我们还测试了一些简单的数据扩充技术。这些结果可以在下表中看到。

在训练集中有 15 个类和每个类 20 个示例的问题类别分类上的 BERT 基线的性能(准确度为%)。

题型分类。问题类分类任务要求将一个测试问题分组到一个问同样事情的问题类中。对于我们的基线,我们只考虑至少有四个问题的问题类别。我们将每个问题类中的三个问题分成训练集,其余的问题分成测试集。下表显示了这种数据集分割。

问题分类的数据集分割。

对于基线模型,我们使用来自问题类别分类的 k-NN 基线,还使用一个简单模型,该模型使用三重损失函数来训练一个两层神经网络。这些模型也通过获得每个问题的 BERT 平均池标记来评估。类似地,我们也为这个任务运行数据扩充。这些结果可以在下表中看到。

在训练集中有 89 个类别和每个类别 3 个示例的问题类别分类上,BERT 基线的性能(准确度百分比)。

结论。 COVID-Q 是一个新的数据集,包含来自 13 个来源的 1,690 个新冠肺炎问题,标注了 15 个类别标签和 207 个类别标签。COVID-Q 可以直接帮助训练问答系统或作为评估资源。COVID-Q 包含了简单的 BERT 基线。未来的工作包括收集更多的问题(可能与搜索引擎公司合作)或评估更复杂的模型。

完整的数据集可以在这里找到。

全文可以在这里找到。

什么是随机变量

原文:https://towardsdatascience.com/what-are-random-variables-7c4794fae530?source=collection_archive---------29-----------------------

理解什么是随机变量以及它们与函数的关系

在概率论或数理统计课程中,随机变量第一次成为人们的噩梦。在这篇博客中,我将带你了解随机变量。如果我说随机变量不是变量,而是取随机值的函数呢。我在上面的定义中使用了 function 这个词。让我们从理解数学中的函数开始。

想象一下,你有一台果汁自动售货机,你只有 3 种水果:苹果、芒果和香蕉。你把苹果放进机器,然后你得到苹果汁作为输出。同样,芒果可以得到芒果汁,香蕉可以得到香蕉汁。

这里我们可以看到两组:

  1. 输入集:
  2. 输出集:

这两个集合通过果汁自动售货机相互关联。同样,数学函数也是两个集合之间的映射:输入集合和输出集合。这些通过称为 f(x) 的规则相互关联。设 f(x) = 2x + 1 。现在如果你输入 1 到这个函数,你会得到 3 作为输出。对于-2,输出将是-3,对于输入 5,输出将是 11。

在上面果汁的例子中,输入集合是水果,输出集合是果汁,这两个集合通过榨汁机(我们的 f(x) 相互关联。

随机变量也是函数,其输入集是随机实验的结果,输出集是一组实数。这些用大写字母表示(例如 X )考虑一个抛硬币的实验。我们可以有两种结果:正面反面。让我们把正面映射到 1,反面映射到 0。

  • X(头)= 1
  • X(尾部)= 0

同样,我们可以使用随机变量将任何实验结果映射到实数。再举一个例子,我们在一个盒子里放了三个不同颜色的球:红色、绿色和蓝色。所以我们用下面的方式映射实验的结果。

现在有人会问,我们为什么要做这样的映射?为了理解这一点,让我提出几个概率问题:

  • P(掷骰子一次得到 3 个以上)
  • P(掷 4 次硬币得到 2 个正面)
  • P(在一次掷骰子中得到 2 到 5 之间的数字)

你不觉得这种表示概率的方法很乏味吗?我们需要找到一种方法来用数学形式表示这些概率,以便我们可以对它们进行数学运算。这是使用随机变量实现的。现在我将使用随机变量重写上述概率。

  • P(X > 3) :这里 X 是骰子上的数值
  • P(X = 2) :此处 X 为头数
  • P(2 < X < 5) :此处 X 为模具上的数值

正如我们所看到的,随机变量方法更加简洁,并且提供了一种执行数学运算的便捷方式。

但为什么称之为 变量 又叫 随机 ?让我们考虑一下上面的果汁例子。我们对果汁机的投入是水果。但是哪种水果呢?水果可以是苹果、香蕉或芒果。那么,对于水果的价值,我们能说些什么呢?是固定的还是可变的?由于水果的值可以取水果集中的任何值,所以它是可变的。所以任何值不固定的东西都叫做变量。如果我们将 X 作为投掷硬币的结果,其中正面将被映射为 1,反面将被映射为 0。那么 X 可以取什么值呢? X 可以是 0 或者 X 可以是 1。这样,随机变量就被当作一个变量。

现在让我们扩展一下果汁的例子。现在你拥有了一家出售 3 种果汁的果汁店。所以你的顾客会来要这三种果汁中的任何一种。作为一名店主,你能确定下一位顾客会要求哪种果汁吗?根据你过去的经验,你只能猜测,但不能百分之百肯定地说什么。对果汁类型的需求是随机的,可以取任何值。同样,当你扔硬币时,你能肯定地说它是正面还是反面吗?或者当你扔骰子时,你能预测它的结果是什么数字吗?所以随机变量之所以称为随机,是因为这个变量的值不能确定地定义,我们只能猜测,这个猜测称为随机变量具有特定值的 概率 。抛硬币实验中, P(X=1) = 0.5 。所以我们只能说有 50%的机会正面朝上。

但是方程中变量 x 的区别是什么:

*y = 2x + 1*

以及抛硬币的变量 X 。如果我告诉你 y=1,你能告诉我 x 的值是多少?你不能完全肯定的说 x 的值会是 0 吗?所以这里的变量 x 是确定性的,不是随机的。所以这不能称为随机变量。

从上面的讨论中,我们可以说随机变量是一个将随机实验的结果映射到 T42 实数的函数。因为这是函数的输入集,所以它被称为随机变量的定义域,用ω表示。而输出集或 Co 域是由ℝ.表示的一组实数在函数符号中,它可以这样定义:

X: Ω → ℝ

对于抛硬币实验,ω= {正面,反面}和ℝ = {1,0}。所以我们可以这样写:

  • X(人头)= 0
  • X(尾)= 1

为了方便起见,我们省略了括号部分,简单地写成 X = 0X = 1 ,这样看起来更像是一个变量而不是函数。

我希望这已经澄清了随机变量的概念,现在你可以明白为什么我们更多地把随机变量当作一个变量而不是一个函数,尽管随机变量实际上是函数!

什么是小世界网络模型?

原文:https://towardsdatascience.com/what-are-small-world-network-models-87bbcfe0e038?source=collection_archive---------12-----------------------

来源:像素

介绍将现实世界的网络浓缩成小型网络的数学模型。

什么是小世界网络模型,为什么

在社会网络分析领域,许多现实世界的网络,如互联网,脸书网络,有数百万个节点和数十亿条边。它们的拓扑结构太复杂,而且太大,研究人员无法分析。

因此,研究人员转向网络的生成模型。其思想是,如果我们可以设计生成图形的模型,并保证模拟图形在网络属性方面与真实世界的网络非常相似,我们就可以以更简单的方式对合成网络而不是真实世界的网络进行分析。此外,利用网络的生成模型,我们不仅可以更好地理解现实世界网络的数学基础,还可以进行现实世界网络可能无法进行的受控实验。

基于上述原因,研究人员提出了几种产生小世界网络的网络模型。在本帖中,我们将列出社交网络分析领域中 3 个最常见的网络模型。

  1. 鄂尔多斯-雷尼模型
  2. 瓦特-斯特罗加兹模型
  3. 巴拉巴斯-艾伯特模型

erdős–rényi 模型

鄂尔多斯-雷尼模型通常被称为随机图模型;它根据概率分布随机生成网络。鄂尔多斯-雷尼模型有两个变体, G(n,p)G(n,m) ,它们彼此非常相似。

网络生成

使用 G(n,p) 模型,我们生成一个具有 n 个节点的无向网络,并且网络中每个可能的边都是独立生成的,并且以概率 p 同分布。

使用 G(n,m) 模型,我们生成一个具有随机均匀选择的 n 个节点和 m 条边的无向图。

限制

  • 它的度分布不同于真实世界的网络,真实世界的网络通常遵循幂律。
  • 鄂尔多斯-仁义网络的聚类系数太小。
  • 最重要的是,现实世界的网络不是随机产生的。

瓦特-斯特罗加兹模型

由于 Erdos-Renyi 模型具有小的聚类系数,这与真实世界的网络非常不同,Watts-Strogatz 模型的思想是在生成的模型中具有高的聚类系数和短的平均路径长度。

网络生成

如果我们生成规则的网格,我们可以有高的聚类系数,但是它们在形状上是固定的。我们想给网络增加随机性,这可以通过随机重新布线来实现。随机的重新布线过程会产生长距离连接,并给生成的网络增加随机性。

  • 生成一个规则的格子
  • 对于网络中的每条边,以概率 p 重新布线,同时避免自循环和链路重复(多条边)

来源:维基百科

限制

  • 它仍有不符合幂律的不切实际的度分布
  • 固定的节点数量,与真实网络不同,节点数量会持续增长

巴拉巴希-艾伯特模型

上面提到的两个随机网络模型受限于两个条件,这两个条件不同于真实世界的网络。

  1. 不切实际的学位分布
  2. 固定数量的节点

为了解决这些限制,研究人员试图模拟真实世界网络的形成过程。结果,他们观察到以下特征,并开发了巴拉巴斯-艾伯特模型。

  • 现实世界的网络建设是一个稳定增长过程的产物。这种特征被描述为持续增长。
  • 大多数真实网络中的新节点更喜欢链接到更多连接的节点。这种特性被称为优先依恋。

上述两个特征是现实世界网络具有无标度特性的原因,这种特性使得网络的度分布遵循幂律。Barabasi-Albert 模型旨在捕捉导致现实世界网络无标度特性出现的机制。

网络生成

构建 Barabasi-Albert 网络,我们从 m0 节点开始,任意选择节点之间的链路,只要每个节点至少有一条链路。网络发展了以下两个步骤,

  • 在每个时间步,我们添加一个新节点,该节点有 m (≤ m0 )条链路,这些链路将新节点连接到网络中已经存在的 m 个节点。这使得网络不断增长。
  • 新节点的链路连接到节点 i 的概率与节点 i 的度成比例。这也被称为优先依附。

来源:维基百科

摘要

  • 小世界网络旨在生成与真实世界网络相似的网络,以提供真实世界网络的数学解释。
  • Erdos-Renyi 模型和 Watts-Strogatz 模型是随机生成的。
  • Barabasi-Albert 模型通过在网络生成中加入连续增长和优先依附特性,生成具有无标度特性的网络。
  • 总的来说,所有小网络模型的另一个限制是随机模型只生成无向网络,而许多现实世界的网络是有向的。

参考

[1]邓肯·j·瓦茨和史蒂文·h·斯特罗加兹,“小世界”网络的集体动力学,自然杂志

[2]艾伯特-拉斯洛·巴拉巴希,网络科学:巴拉巴希-艾伯特模型

[3] 鄂尔多斯-仁义模型,维基百科

python 中最流行的 10 个标准库是什么?

原文:https://towardsdatascience.com/what-are-the-10-most-popular-standard-libraries-in-python-359defb104d6?source=collection_archive---------31-----------------------

基于 GitHub 存储库的样本数据集探索流行的 python 标准库。

杰西卡·鲁斯切洛在 Unsplash 上的照片

Python 以其有用的库和包而闻名,即使没有软件工程背景的人也可以编程。

如今,Python 是人工智能和机器学习领域最受欢迎的编程语言之一。Python 以其有用的库和包而闻名,即使没有软件工程背景的人也可以编程。Python 有一组用 Python 语言发布的标准库,如 DateTimemath、random 。在本文中,我们的目标是在 GitHub 的 python 库中找到 10 个最有用的标准库。为了实现我们的目标,我们研究了 GitHub 中不同的 python 库,并收集了它们常用的库来回答这个问题。为了开始我们的研究,首先,我们收集了 GitHub 中 5 个著名的 python 库去年的提交。然后,我们解析这些存储库中的 python 源文件,并收集提交中使用的库。最后,我们可视化了这些 GitHub repos 的提交中使用的 10 个最流行的 python 标准库。

这篇文章结构如下:

1.如何收集数据?

2.如何解析 Python 源代码?

3.GitHub 库中最受欢迎的 10 个 python 库是什么?

4.结论

5.参考

  1. 如何收集数据?

有不同的方法可以访问 GitHub 存储库中的数据,如 GitHub torrentGit API 调用、google big query 。但是,在本文中,我们想尝试一个新的非常有用的 python 包,名为 Pydriller ,来收集我们需要的数据。Pydriller 快速且易于使用。我通过我的博士研究熟悉了这个有趣的包。你可以在这里查看 Pydriller 的文档。从 Pydriller 开始,首先,我们安装这个包:

pip install pydriller

在 GitHub 中,每次提交可以更改一个或多个源文件。在 GitHub 等版本控制系统中,每次提交都有一个文件,名为“diff”。它通过提交特定的提交来存储源文件中应用的更改。在 GitHub 库的提交中查找库的方法之一是在“diff”文件中搜索正则表达式。但同样,我们想在这篇文章中尝试一些不同的东西。我们在应用提交之前和之后比较源文件的两个不同版本,然后收集这两个文件在库名上的差异。通过这种方法,我们可以发现这些库在不同的提交中使用的频率。好消息是 Pydriller 允许我们在提交之前和之后访问源文件的版本。下面是收集数据所需的代码:

使用 Pydriller 收集 GitHub 中 5 个著名的 python 库

我们在 GitHub 上收集了去年提交的 5 大 python 项目:【Django】熊猫NumPyhome assistant系统-设计-初级"repository mining"是 Pydriller 中主要的 API 调用之一。我们可以用repository mining:中的两个参数定义一个时间段来收集不同存储库中的提交。此外,我们考虑提交所有以“结尾的源文件。py “因为在这些库中有其他编程语言的源文件,但是我们专注于 python 库。我们收集三个特征:*【commit . hash】source _ code _ before’【source _ code】。Pydriller 中的commit . hash*返回提交 id, source_code_before 是应用提交前源文件的版本, source_code 显示提交提交后源文件的内容。这是我们收集的数据的标题:

“图片由作者提供”:tf_source.head()

到目前为止,我们收集了开始旅程所需的数据。在下一节中,我们将学习如何在这些源文件中探索库。

2。如何解析 python 源代码?

从源代码中提取信息的方法之一是将源代码转换成抽象语法树。然后,我们可以遍历树并收集目标节点。但是,重要的一点是,我们只想收集 python 标准库,而不是存储库中使用的所有包,比如只在存储库中有意义的本地定义的库。Python 标准库是用 python 语言发布的。因此,为了将标准包与其他包分开,我们需要拉取 python 中所有有效的标准库。然后,我们可以编写一个函数来收集源代码中的库名。我们可以将这一部分分为两步:

2.1.收集 python 中所有可用标准库的列表

2.2.构建一个基于 AST 收集库名的函数

2.1。收集 python 中所有可用标准库的列表

python 网站上,有一个 python 中所有标准库的列表,还有一个小描述。这个页面按照字母名称对所有 python 标准库进行排序,帮助我们了解 python 中的所有标准库。我把所有 python 标准库的列表放在这里放在一个中。csv 格式。**

2。2.构建一个函数来收集基于 AST 的库名

现在我们有了所有标准 python 库的列表,我们需要从 python GitHub 存储库中收集样本数据集中的库名。正如我们提到的,方法之一是遍历 AST。在本文中,我们的目标节点是【import】【import from】。我们希望有一个函数遍历解析树,找到目标节点,并返回库的名称。下面是一个这样做的类。

用 python 代码收集库名的类

为了更好地理解这个类是如何工作的,这里有一个简单的代码。这个示例代码只有两行,分别导入两个不同的库。其中一个库是 python 标准库: tokenize 另一个是本地库: assistant

**import tokenize as tz
import assistant as ass**

下面是这个示例代码的解析树的转储。可以发现,我们需要收集的是作为 【名称】 自变量的 别名 类。此外,我们需要检查库的名称是否在我们从 python 原始网站收集的所有标准库的列表中。我们拯救了。csv 文件在一个名为【API _ name】的列表中。如果我们在这个示例代码上应用这个类 FuncParser,,它将只返回 "tokenize" ,因为另一个库 assistant 在 python 标准库列表中不可用。

**Module(body=[Import(names=[alias(name='tokenize', asname='tz')]), Import(names=[alias(name='assistant', asname='ass')])])**

3。python 库中最流行的 10 个基于 GitHub 提交的标准库是什么?

到目前为止,我们在 GitHub 中收集了 5 个著名的 python repo 的样本数据集,并构建了一个类来收集 python 代码中的库名。现在,我们需要将这个函数应用于来自 GitHub 的样本数据,并找到提交这些存储库时使用的前 10 个库。正如我们前面所讨论的,我们将提交提交之前源文件的 AST 与提交提交之后同一源文件的 AST 进行比较。然后我们收集不同的库节点。首先,我将向您展示如何比较这两个 AST 的分步示例,最后,我将所有代码一个接一个地放在一起,循环遍历整个数据集,并计算每个库的出现次数。

3.1.在 提交提交之前,收集库名 列表

正如您在第 1 节中看到的,我们将样本数据集存储在*“TF _ source”中。我选择这个数据集的第一行来解释整个过程。TF _ source[' Commit _ before '][0]返回在我们的示例数据集中应用第一次提交之前的代码内容。然后,我们应用 FuncParser() 来收集这个源文件中的所有库名,并将结果返回到 file_contents 列表中。我们在之前创建一个名为tokens _ 的数据帧,并存储这个列表。*****

 **text_before=str(**tf_source[‘Commit_before’][0]**)

 bf_obj = **FuncParser**()
 bf_tree = ast.parse(text_before)
 **file_contents** = []
 bf_obj.visit(bf_tree)
 dtobj_before = pd.DataFrame(file_contents, columns=[‘token’])
 **tokens_before** =pd.DataFrame(dtobj_before[‘token’].value_counts())**

3.2.在 提交提交后,收集库名 的列表

我们重复与 3.1 相同的过程。,但这次对源文件的内容提交了 commit 后,TF _ source[' Commit _ after '][0]。**同样,我们将结果存储在一个数据帧中,称为, tokens_after。**

**text_after=str(**tf_source**[‘Commit_after’][0])

 aft_obj = **FuncParser**()
 aft_tree = ast.parse(text_after)
 **file_contents** = []
 aft_obj.visit(aft_tree)
 dtobj_after = pd.DataFrame(file_contents, columns=[‘token’])
 **tokens_after** =pd.DataFrame(dtobj_after[‘token’].value_counts())**

3.3.提取两个列表之间的差异

在这一步中,我们从令牌 _after** 中减去令牌 _before 中的令牌 _ after来计算它们的差值。**

**diff = tokens_after.**subtract**(tokens_before)
diff_token = diff[(diff.select_dtypes(include=[‘number’]) != 0).any(1)]
 diff_token=diff_token.fillna(0)
 diff_token= diff_token.abs()
 **diff_token** = diff_token.reset_index()**

3.4.计算库的数量

最后,我们统计每个库在 diff_token 数据帧中出现的次数。为此,我们创建一个名为 py_lib 的字典,并统计库的出现次数。

****py_lib**={}
j=0 
for j in range(0,len(diff_token)):
        word = diff_token['index'][j].lower()
        if word in py_lib:
            py_lib[word]+=diff_token['token'][j]
        else:
            py_lib[word]=1
        j+=1**

为了将上述步骤应用到我们在第 1 节中收集的整个样本数据中,我在步骤的开头添加了一个循环。代码如下:

收集整个样本数据集中的库

现在我们收集了 GitHub 中 python 库提交的所有库及其频率,我们希望在 py_lib 字典中找到前 10 个库。我们可以用下面的代码收集字典中的前 10 个值。我们可以看到,基于我们的样本数据集,诸如‘warnings’,【sys’‘datetime’之类的库位于前 10 名 python 标准库的列表中。

**from operator import itemgetterd=sorted(py_lib.items(), key=itemgetter(1),reverse=True)[:10][('warnings', 96.0),
 ('sys', 73.0),
 ('datetime', 28.0),
 ('test', 27.0),
 ('os', 22.0),
 ('collections', 18.0),
 ('io', 16.0),
 ('gc', 10.0),
 ('functools', 9.0),
 ('threading', 7.0)]**

“作者图片”:基于 GitHub 样本数据集的 python 十大标准库

另外,我们可以绘制 python 库的单词云图和它们的频率。

**import matplotlib.pyplot as plt
from wordcloud import WordCloud wordcloud = WordCloud(background_color='black',max_font_size = 50)
wordcloud.generate_from_frequencies(frequencies=py_lib)
plt.figure(figsize=(8,6))
plt.imshow(wordcloud, interpolation="bilinear")
plt.axis("off")
plt.show()**

“Image by Author”:基于 GitHub 样本数据集的流行 python 库的单词云图

4。结论

在本文中,我们试图基于一个样本数据集收集 10 个最流行的 python 库。该数据集包含 GitHub 中 5 个著名 python 库去年的提交。我们使用 Pydriller 从 GitHub 收集数据。我们比较提交提交前后源文件的 AST,并收集这些提交中使用的库的列表。然后,我们在 word 云图中绘制最流行的 python 库。

复制这篇文章的所有代码都可以在 GitHub 的这里获得。

5。参考文献

[1]牟,李,郭刚,张,李,王,田,金,张(2014).用于程序语言处理的树形结构卷积神经网络。 arXiv 预印本 arXiv:1409.5718

[2] Spadini,d .,Aniche,m .,Bacchelli,a .,2018,10 月。Pydriller:用于挖掘软件仓库的 Python 框架。在2018 年第 26 届 ACM 欧洲软件工程会议和软件工程基础研讨会会议录(第 908–911 页)。

[3]d .舒勒和 t .齐默尔曼(2008 年 5 月)。从版本档案中挖掘使用经验。在2008 年矿业软件库国际工作会议论文集(第 121-124 页)。

https://github.com/ishepard/pydriller

https://docs.python.org/3/py-modindex.html#cap-p

评估回归模型的 3 个最佳指标?

原文:https://towardsdatascience.com/what-are-the-best-metrics-to-evaluate-your-regression-model-418ca481755b?source=collection_archive---------1-----------------------

R 平方,校正的 R 平方,均方差,缅因州 RMSE

来源:Issac Smith 在 Splash 上拍摄的照片

模型评估在数据科学中非常重要。它有助于您了解模型的性能,并使向其他人展示您的模型变得容易。有许多不同的评估指标,但只有其中一些适合用于回归。本文将涵盖回归模型的不同度量以及它们之间的差异。希望在你读完这篇文章后,你能清楚哪些指标适用于你未来的回归模型。

每次当我告诉我的朋友:“嘿,我建立了一个机器学习模型来预测 XXX。”他们的第一反应会是:“酷,那么你的模型预测的准确度是多少?”与分类不同,回归模型中的准确性稍微难以说明。你不可能预测准确的值,而是你的预测与真实值有多接近。

回归模型评估有 3 个主要指标:

1.R 平方/调整后的 R 平方

2.均方差(MSE)/均方根误差(RMSE)

3.平均绝对误差

R 平方/调整后的 R 平方

r 平方衡量模型可以解释因变量的多少可变性。它是相关系数(R)的平方,这就是它被称为 R 平方的原因。

r 平方公式

通过预测误差的平方和除以用平均值代替计算预测的平方和来计算 r 平方。r 平方值在 0 到 1 之间,较大的值表示预测值和实际值之间的拟合较好。

r 平方是确定模型拟合因变量的好方法。但是没有考虑过拟合问题。如果您的回归模型有许多独立变量,由于模型太复杂,它可能非常适合定型数据,但对于测试数据来说表现很差。这就是引入调整后的 R 平方的原因,因为它将惩罚添加到模型中的额外独立变量,并调整度量以防止过度拟合问题。

#Example on R_Square and Adjusted R Square
import statsmodels.api as sm
X_addC = sm.add_constant(X)
result = sm.OLS(Y, X_addC).fit()
print(result.rsquared, result.rsquared_adj)
# 0.79180307318 0.790545085707

在 Python 中,可以使用 Statsmodel 或者 Sklearn 包计算 R 平方

从样本模型中,我们可以解释大约 79%的相关可变性可以由模型来解释,并且调整后的 R 平方与 R 平方大致相同,这意味着模型相当稳健。

均方差(MSE)/均方根误差(RMSE)

虽然 R 平方是模型拟合因变量的相对度量,但均方差是拟合优度的绝对度量。

均方差公式

MSE 的计算方法是预测误差的平方和,即实际输出减去预测输出,然后除以数据点数。它给你一个绝对的数字,告诉你你的预测结果与实际数字有多大的偏差。您无法从一个单一的结果中解读许多见解,但它给了您一个真实的数字来与其他模型结果进行比较,并帮助您选择最佳的回归模型。

均方根误差(RMSE)是 MSE 的平方根。它比 MSE 更常用,因为首先有时 MSE 值可能太大而不容易比较。第二,MSE 是通过误差的平方计算的,因此平方根使它回到预测误差的相同水平,并使它更容易解释。

from sklearn.metrics import mean_squared_error
import math
print(mean_squared_error(Y_test, Y_predicted))
print(math.sqrt(mean_squared_error(Y_test, Y_predicted)))
# MSE: 2017904593.23
# RMSE: 44921.092965684235

可以使用 Sklearn 包在 Python 中计算 MSE

平均绝对误差

平均绝对误差(MAE)类似于均方误差(MSE)。然而,MAE 取的不是 MSE 中误差的平方和,而是误差绝对值的和。

平均绝对误差公式

与 MSE 或 RMSE 相比,MAE 是误差项和更直接的表示。 MSE 通过平方对大的预测误差给予较大的惩罚,而 MAE 对所有误差一视同仁

from sklearn.metrics import mean_absolute_error
print(mean_absolute_error(Y_test, Y_predicted))
#MAE: 26745.1109986

可以使用 Sklearn 包用 Python 计算 MAE

总体建议/结论

R 平方/调整后的 R 平方更适合用于向其他人解释模型,因为您可以将数字解释为输出可变性的百分比。MSE、RMSE 或 MAE 更适合用来比较不同回归模型之间的性能。就我个人而言,我更喜欢使用 RMSE,我认为 Kaggle 也使用它来评估提交。但是,如果值不太大,使用 MSE 是完全有意义的,如果不想惩罚大的预测误差,则使用 MAE 也是完全有意义的。

调整后的 R 平方是这里唯一考虑过拟合问题的度量。R square 在 Python 中有一个直接的库可以计算,但是除了使用 statsmodel 结果之外,我没有找到一个直接的库来计算调整后的 R Square。如果你真的想计算调整后的 R 平方,你可以使用 statsmodel 或者直接使用它的数学公式。

有兴趣了解用于评估分类模型的顶级指标吗?请参考下面的链接:

[## 评估分类模型的 5 大指标

与回归模型不同的是,当我们评估分类模型的结果时,我们不应该只关注预测…

medium.com](https://medium.com/@songhaowu/top-5-metrics-for-evaluating-classification-model-83ede24c7584)

需求计划的最佳实践:预测流程

原文:https://towardsdatascience.com/what-are-the-best-practices-for-demand-planning-part-2-forecasting-process-be9800c981db?source=collection_archive---------25-----------------------

下面这篇文章是我的一篇 LinkedIn 帖子 的总结。如果你对这样的辩论感兴趣,那就 连线吧! 感谢以下人士在原讨论中的真知灼见: 蒂莫西·布伦南克里斯·戴维斯瓦列里·马诺欣莱昂纳多·卡夫雷拉查理·坎茨卡尔-埃里克·德沃斯派罗斯·马克里达基斯

供应链需求计划人员经常问自己:预测我的需求的最佳模型是什么?我应该遵循哪些最佳实践来改进(或建立)我的预测(并使其对我的供应链更有用)?

对这些问题不可能给出一个明确、绝对的答案。但是我将尝试在两篇文章中(这是第二篇,你可以在这里找到第一篇)回顾大多数现有的预测模型,然后向你展示调整和选择它们的技巧、诀窍和最佳实践。第二篇文章将研究各种最佳实践,介绍如何选择最佳预测模型,根据您的供应链进行调整,并改进您的总体需求计划流程。

📔步骤 1:四维预测框架

在任何供应链中,预测总是达到目的的手段,而不是目的本身。我们需要记住的是,只有当预测能够使供应链采取适当的行动时,预测才是有意义的。一个好的预测模型应该允许你的供应链提高服务水平,更好地计划,减少浪费和总成本。

在进行预测时,您必须定义四个维度:粒度范围审查频率指标(我喜欢称之为四维预测框架)。让我们一个一个地讨论那些。

📦 1.粒度

您应该首先为您的预测确定正确的粒度。你应该预测每个产品,每个包装类型,每个国家,每个销售渠道,每周,每月?要回答这些问题,你必须考虑你的供应链基于这一预测所采取的决策。请记住,只有当预测有助于供应链采取行动时,它才是有意义的。例如,假设您必须在本地仓库运送产品。在这种情况下,对每个国家进行预测可能是个好主意。如果您的生产过程需要生产特定包装的产品,您应该预测每个包装。如果不同的仓库(或流程)服务于不同的销售渠道,您应该分别对它们进行预测。另一方面,如果你只有一个仓库,你应该问问自己,你真的需要对每个地区进行预测吗?

🔭 2.地平线

一旦您知道您将在什么粒度级别上工作,您就应该选择正确的预测范围。同样,你可以通过思考你的供应链试图优化/实现什么来回答这个问题。假设你的供应商(或生产工厂)需要提前三个月收到订单/预测。在这种情况下,你知道你应该在 M+1/+2/+3 上工作。可以跳过 M+4(或者至少不关注它)。

❗统计模型可以免费提供无限期的预测。机器学习模型就不是这样了。所以你可能不得不坚持用统计模型来预测长期趋势。需求计划员(以及任何其他从事预测工作的人)的时间也是有限的,所以他们也应该选择一个有限的时间范围来关注。

多重视野?注意多个流程(团队)可能会使用您的预测。一个团队可能使用它进行短期规划(提前 1-3 周;例如,部署),另一个团队负责长期决策(提前 6 到 18 个月;例如,打开/关闭工厂)。在这种情况下,拥有两个不同的预测过程(具有不同的粒度、范围、审查频率和指标)可能会很有趣。

⏱️ 3.审查频率

现在您已经知道了您的预测范围,您可以定义预测复查频率:您应该每周、每月还是每季度进行预测?

更频繁地更新预测可能会提高准确性(因为您手头有更新的数据)。更新太频繁可能会造成混乱,因为你对需求的变化反应过度,为了有限的附加值消耗太多的资源。如果您发现您的预测流程的预测附加值越来越低,也许您应该减少预测审核频率。

📖定义:预测附加值。一个预测流程框架,跟踪每个团队/流程步骤相对于基准的附加值。它是由迈克尔·吉利兰在 21 世纪 10 年代设想和推广的(见他的书这里)。

🎯 4.韵律学

为预测流程/模型选择正确的指标并不简单。根据所选的指标,你可能会过于重视异常值(RMSE 弱点),或者冒着预测有偏差的风险(美国市场弱势)。我在这里详细讨论这些指标。通常,查看 KPI 的组合(如 MAE & Bias)将是一个实用的解决方案。

💡加权 KPI。在我的《供应链预测的数据科学第二版(你可以在这里 预定 )中,我建议在总体指标计算中根据盈利能力、成本或总体供应链影响对每种产品(或 SKU)进行加权。这个想法是,你想更多地关注最重要的 SKU。

💾步骤 2:数据质量和收集

一旦定义了预测流程的四个维度,就可以开始收集数据了。它在项目中经常被忽视,因为这部分不是最性感的,而且经常被视为一种成本。但是如果没有足够好的数据,你将无法创建一个有意义的模型。在讨论型号选择之前,发现哪些数据可用非常重要。

🔎数据质量

我喜欢调整模型,直到我不能挤出超过 0.1%的额外精度。如果您正在争取额外的 0.1%的准确性,您应该分配多少时间来使您的需求数据质量达到 99.99%?要提高需求数据质量,您应该注意以下几点:

  • 你收集失去的销售(或未完成的订单)吗?
  • 你跟踪每个订单的初始要求交货日期还是仅仅发货日期(或者更糟,开票日期)?
  • 您是否记录了每个取消订单的取消原因
  • 假设一个客户由于缺乏库存而无法履行其初始订单,后来又回来下同样的订单。你会将注册为需求的两倍吗?

数据量

您将需要一定数量的需求数据,这取决于您需要预测的模式类型以及您将使用的模型。如果你面对季节性需求,你将需要至少三年的数据才能让一个统计模型工作。机器学习模型通常需要更多数据(尤其是如果你想进行中长期预测)。

第三步选择模型

一旦你收集了数据,知道了你的预测过程的 4 个维度,你就可以选择一个模型(关于预测模型的回顾,见本文的第一部分这里)。

🧮统计模型

使用指数平滑通常是一个安全的赌注。它们易于实现,易于解释(大多数需求计划软件都依赖于它们)。他们也可以很容易地做出长期预测。

🖥️机器学习

假设您想更进一步,实现更好的预测准确性。那样的话,你应该去找机器学习模型。不幸的是,尽管指数平滑模型相当通用(它们仍然需要一些微调),但机器学习模型需要适合你的数据集。这就是为什么你应该首先寻找数据收集,然后选择模型。对你来说,不经过任何调查和微调,很难得到现成的模型。和往常一样,您应该首先检查您的需求数据质量。在一个糟糕的数据集上运行最先进的 ML 模型是没有意义的。关于如何使用机器学习进行预测的介绍,请参见我的文章这里

📊功能选择

(大部分)数据科学的艺术在于特征选择。你应该向你的机器学习模型展示哪些信息,让它预测需求?同样,对于每个供应链来说,没有最好的特性。

🎚️参数优化

最后,一旦您选择了一个模型和一组(潜在的)特征,模型优化应该遵循数据科学的最佳实践(例如使用随机搜索和交叉验证)。

💪更进一步:了解你的业务

一旦建立了预测模型,您仍然有许多机会来进一步提高预测的准确性。

特定产品的特定型号

假设您有一个由不同需求模式的产品组成的产品组合。在这种情况下,为它们中的每一个开发特定的模型可能是一个好主意。值得注意的是,间歇产品和新产品可以受益于特定的模式。

  • 间歇性产品。间歇性产品可能需要特定的模型、库存政策和供应链管理技术。参见我的文章如何预测高利润低产量的产品?了解更多信息。
  • 新产品。新产品也需要不同的算法,因为你不能依赖太多(如果有的话)历史数据。开发特定的 ML 算法可能是在产品发布期间预测需求的正确解决方案。

🧠判断性预测和预测附加值

通过使用判断性预测,需求计划员应该能够改进预测基线。与各种利益相关者(客户、营销和定价团队)沟通应该有助于你微调你的预测。

一旦你知道在哪里可以找到额外的信息来丰富你的基线预测,你就应该跟踪你可以增加多少额外的准确性。为此,您必须跟踪每一步的预测附加值

🏆培训和用户成功

最后一点,最好的预测模型或软件,如果没有训练有素的用户,将会是一场灾难。这就是为什么我通常会通过一轮培训来启动任何咨询项目。

通常,一个被用户很好理解和使用的标准预测引擎,与它所影响的供应链同步,将会创造出比最佳预测模型更好的结果(而且你现在知道没有所谓的最佳预测模型)。

关于作者

[## Nicolas vande put——顾问,创始人——供应链| LinkedIn

查看 Nicolas Vandeput 在世界上最大的职业社区 LinkedIn 上的个人资料。尼古拉斯有 7 份工作列在…

www.linkedin.com](https://www.linkedin.com/in/vandeputnicolas/)

icolas Vandeput 是一名供应链数据科学家,擅长需求预测和库存优化。他在 2016 年创立了自己的咨询公司 SupChains ,并在 2018 年共同创立了 SKU 科学——一个快速、简单、实惠的需求预测平台。尼古拉斯对教育充满热情,他既是一个狂热的学习者,也喜欢在大学教学:自 2014 年以来,他一直在比利时布鲁塞尔为硕士学生教授预测和库存优化。自 2020 年以来,他还在法国巴黎的 CentraleSupelec 教授这两个科目。他于 2018 年出版了 供应链预测的数据科学(2021 年第 2 版)和 2020 年出版了 库存优化:模型与模拟

数据科学中常用的统计检验有哪些

原文:https://towardsdatascience.com/what-are-the-commonly-used-statistical-tests-in-data-science-a95cfc2e6b5e?source=collection_archive---------11-----------------------

数据科学家的便利收藏

JESHOOTS.COMUnsplash 上拍照

业务分析和数据科学融合了许多专业领域。来自多个领域和教育背景的专业人士正在加入分析行业,追求成为数据科学家。

我职业生涯中遇到的两种数据科学家。关注算法和模型细节的人。他们总是试图理解幕后的数学和统计学。想要完全控制解决方案及其背后的理论。另一类人对最终结果更感兴趣,不看理论细节。他们着迷于新的和先进的模型的实现。倾向于解决手头的问题而不是解决方案背后的理论。

这两种方法的信徒都有自己的逻辑来支持他们的立场。我尊重他们的选择。

在这篇文章中,我将分享一些数据科学中常用的统计测试。不管你相信哪种方法,知道其中的一些是有好处的。

在统计学中,从任何探索中得出推论有两种方法。参数估计是方法之一。这里,通过各种方法计算总体参数的未知值。另一种方法是假设检验。它有助于我们测试由一些先验知识猜测的参数值。

我将列出一些你在数据科学中经常会遇到的统计测试程序。

"检验一个假设有效性的唯一相关方法是将其预测与经验进行比较."—米尔顿·弗里德曼

作为一名数据科学家,我真的需要了解假设检验吗?

在数据科学的大多数决策过程中,我们都知道或不知不觉地使用假设检验。这里有一些证据来支持我的说法。

作为数据科学家,我们所做的数据分析可以分为四大领域

  1. 探索性数据分析

2.回归和分类

3.预测

4.数据分组

这些领域中的每一个都包括一些统计测试。

探索性数据分析

这是数据科学不可避免的一部分,每个数据科学家都要在其中花费大量时间。它为创建机器学习和统计模型奠定了基础。EDA 中涉及统计测试的一些常见任务是—

  1. 正态性检验

2.异常值测试

3.相关性测试

4.匀性检验

5.分布相等性检验

这些任务中的每一项都涉及到在某一点上对假设的检验。

1。如何检验正常?

统计学中正态性无处不在。我们在统计学中使用的大多数理论都是基于正态假设。正态性意味着数据应该遵循一种特定的概率分布,即正态分布。它有特定的形状和特定的功能。

在方差分析中,我们假设数据是正态的。在进行回归时,我们期望残差服从正态分布。

为了检查数据的正态性,我们可以使用夏皮罗-维尔克检验。此测试的零假设是—数据样本的分布是正态的。

Python 实现:

import numpy as np
from scipy import stats
data = stats.norm.rvs(loc=2.5, scale=2, size=100)
shapiro_test = stats.shapiro(data)
print(shapiro_test)

2。如何检验一个数据点是否是离群值?

当我开始任何新的数据科学用例时,我必须适应一些模型,我做的例行任务之一是检测响应变量中的异常值。异常值对回归模型影响很大。对于异常值,需要采取谨慎的消除或替换策略。

如果离群值明显偏离数据的其余部分,则离群值可以是全局离群值。如果它仅偏离源于特定上下文的数据点,则称为上下文异常值。此外,当一组数据点与其他数据点偏离很大时,它们也可能是异常值。

Tietjen-Moore 检验对于确定数据集中的多个异常值非常有用。此测试的零假设是—数据中没有异常值。

Python 实现:

import scikit_posthocs
x = np.array([-1.40, -0.44, -0.30, -0.24, -0.22, -0.13, -0.05, 0.06, 0.10, 0.18, 0.20, 0.39, 0.48, 0.63, 1.01])
scikit_posthocs.outliers_tietjen(x, 2)

3。如何检验两个变量相关系数的显著性?

在数据科学中,我们处理许多解释因变量行为的自变量。自变量之间的显著相关性可能会影响变量的估计系数。这使得回归系数的标准误差不可靠。这损害了回归的可解释性。

当我们计算两个变量之间的相关性时,我们应该检查相关性的显著性。可以用 t 检验来检验。该检验的零假设假设变量之间的相关性不显著。

Python 实现:

from scipy.stats import pearsonr
data1 = stats.norm.rvs(loc=3, scale=1.5, size=20)
data2 = stats.norm.rvs(loc=-5, scale=0.5, size=20)
stat, p = pearsonr(data1, data2)
print(stat, p)

4。如何在两个数据集中检验一个分类变量的同质性?

如果我用一个例子来解释同质性检验会很方便。假设你,我们想检查网飞用户的观看偏好对于男性和女性是否相同。你可以用卡方检验来证明相同。你必须检查男性和女性的频率分布是否明显不同。

测试的零假设是两个数据集是同质的。

Python 实现:

import scipy
import scipy.stats
from scipy.stats import chisquare
data1 = stats.norm.rvs(loc=3, scale=1.5, size=20)
data2 = stats.norm.rvs(loc=-5, scale=0.5, size=20)
chisquare(data1, data2)

5。如何检查给定的数据集是否遵循特定的分布?

有时在数据分析中,我们需要检查数据是否遵循特定的分布。甚至我们可能想要检查两个样本是否遵循相同的分布。在这种情况下,我们使用 Kolmogorov-Smirnov (KS)检验。我们经常使用 KS 检验来检验回归模型的拟合优度。

该测试将经验累积分布函数(ECDF)与理论分布函数进行比较。此测试的零假设假设给定数据遵循指定的分布。

Python 实现:

from scipy import stats
x = np.linspace(-25, 17, 6)
stats.kstest(x, ‘norm’)

回归和分类

我们在数据科学中做的大多数建模要么属于回归,要么属于分类。每当我们预测某个值或某个类时,我们都会借助这两种方法。

回归和分类都涉及决策不同阶段的统计测试。此外,数据需要满足一些先决条件,才能胜任这些任务。需要进行一些测试来检查这些条件。

一些与回归和分类相关的常见统计测试是—

  1. 异方差检验

2.多重共线性测试

3.回归系数的显著性检验

4.回归或分类模型的方差分析

1。如何检验异方差性?

异方差是一个相当沉重的术语。它只是意味着不平等的方差。我举个例子解释一下。假设您正在收集不同城市的收入数据。你会发现不同城市的收入差异很大。

如果数据是异方差的,它会极大地影响回归系数的估计。这使得回归系数不太精确。估计值将与实际值相差甚远。

为了检验数据中的异方差性,可以使用怀特检验。White 的测试考虑了零假设,即数据的方差是常数。

Python 实现:

from statsmodels.stats.diagnostic import het_white
from statsmodels.compat import lzip
expr = ‘y_var ~ x_var’
y, X = dmatrices(expr, df, return_type=’dataframe’)
keys = [‘LM stat’, ‘LM test p-value’, ‘F-stat’, ‘F-test p-value’]
results = het_white(olsr_results.resid, X)
lzip(keys, results)

2。如何测试变量中的多重共线性?

数据科学问题通常包括多个解释变量。有时,这些变量由于其来源和性质而变得相关。此外,有时我们会从相同的潜在事实中创建多个变量。在这些情况下,变量变得高度相关。这就是所谓的多重共线性。

多重共线性的存在会增加回归或分类模型系数的标准误差。它使得一些重要的变量在模型中变得无关紧要。

法勒-格劳伯检验可用于检查数据中多重共线性的存在。

3。如何检验模型系数是否显著?

在分类或回归模型中,我们需要识别对目标变量有强烈影响的重要变量。模型执行一些测试,并为我们提供变量的重要程度。

t 检验用于模型中检查变量的显著性。检验的无效假设是-系数为零。您需要检查测试的 p 值,以了解系数的显著性。

Python 实现:

from scipy import stats
rvs1 = stats.norm.rvs(loc=5,scale=10,size=500)
stats.ttest_1samp(rvs1, 7)

4。如何检验一个模型的统计显著性?

在开发回归或分类模型时,我们进行方差分析(ANOVA)。它检查回归系数的有效性。ANOVA 将模型引起的变化与误差引起的变化进行比较。如果模型引起的变化与误差引起的变化显著不同,则变量的影响显著。

f 检验用于做出决定。此测试中的零假设是—回归系数等于零。

Python 实现:

import scipy.stats as stats
data1 = stats.norm.rvs(loc=3, scale=1.5, size=20)
data2 = stats.norm.rvs(loc=-5, scale=0.5, size=20)
stats.f_oneway(data1,data2)

预测

在数据科学中,我们处理两种数据——横截面和时间序列。电子商务网站上的一组客户的简档是横截面数据。但是,电子商务网站中一个项目一年的日销售额将是时间序列数据。

我们经常使用时间序列数据的预测模型来估计未来的销售额或利润。但是,在预测之前,我们会对数据进行一些诊断性检查,以了解数据模式及其对预测的适用性。

作为一名数据科学家,我经常对时间序列数据使用这些测试:

  1. 趋势测试

2.平稳性测试

3.自相关测试

4.因果关系检验

5.时间关系测试

1。如何测试时间序列数据的趋势?

随着时间的推移,从业务中生成的数据通常会显示上升或下降的趋势。无论是销售或利润,还是任何其他描述业务绩效的绩效指标,我们总是更喜欢估计未来的变化。

为了预测这种变化,你需要估计或消除趋势成分。要了解趋势是否显著,您可以使用一些统计测试。

曼-肯德尔检验可以用来检验趋势的存在性。零假设假设没有显著的趋势。

Python 实现:

pip install pymannkendall
import numpy as np
import pymannkendall as mk
data = np.random.rand(250,1)
test_result = mk.original_test(data)
print(test_result)

2。如何检验一个时间序列数据是否平稳?

非平稳性是大多数时间序列数据的固有特征。在任何时间序列建模之前,我们总是需要测试平稳性。如果数据不稳定,建模后可能会产生不可靠和虚假的结果。会导致对数据理解不佳。

扩充的 Dickey-Fuller (ADF)可用于检查非平稳性。ADF 的零假设是序列是非平稳的。在 5%的显著性水平,如果 p 值小于 0.05,我们拒绝零假设。

Python 实现:

from statsmodels.tsa.stattools import adfuller
X = [15, 20, 21, 20, 21, 30, 33, 45, 56]
result = adfuller(X)
print(result)

3。如何检查时间序列值之间的自相关性?

对于时间序列数据,过去值和现在值之间的因果关系是一种普遍现象。对于金融时间序列,我们经常看到当前价格受到前几天价格的影响。时间序列数据的这一特征是通过自相关来度量的。

要知道自相关性是否足够强,可以测试一下。德宾-沃森测试揭示了它的程度。此测试的零假设假设值之间没有自相关。

Python 实现:

from statsmodels.stats.stattools import durbin_watson
X = [15, 20, 21, 20, 21, 30, 33, 45, 56]
result = durbin_watson(X)
print(result)

4。如何测试一个变量对另一个变量有因果关系?

两个时间序列变量可以共享因果关系。如果你熟悉金融衍生品,一种定义在基础股票上的金融工具,你会知道现货和期货价值有因果关系。他们根据情况相互影响。

格兰杰因果检验可以检验两个变量之间的因果关系。该测试使用回归设置。一个变量的当前值根据另一个变量的滞后值以及自身的滞后值回归。f 检验确定无因果关系的零假设。

Python 实现:

import statsmodels.api as sm
from statsmodels.tsa.stattools import grangercausalitytests
import numpy as np
data = sm.datasets.macrodata.load_pandas()
data = data.data[[“realgdp”, “realcons”]].pct_change().dropna()
gc_res = grangercausalitytests(data, 4)

5。如何检查两个变量之间的时间关系?

两个时间序列有时会一起移动。在金融时间序列中,你会经常观察到衍生品的现货和期货价格一起变动。

这种协同运动可以通过一个叫做协整的特征来检验。这种协整可以用 Johansen 的检验来检验。该检验的零假设假设变量之间没有协整关系。

Python 实现:

from statsmodels.tsa.vector_ar.vecm import coint_johansen
data = sm.datasets.macrodata.load_pandas()
data = data.data[[“realgdp”, “realcons”]].pct_change().dropna()
#x = getx() # dataframe of n series for cointegration analysis
jres = coint_johansen(data, det_order=0, k_ar_diff=1
print(jres.max_eig_stat)
print(jres.max_eig_stat_crit_vals)

数据分组

在现实生活中,我们经常试图在数据点之间寻找相似性。目的是将它们组合在一些桶中,并仔细研究它们以了解不同桶的行为。

这同样适用于变量。我们识别一些潜在的变量,这些变量是由一些可观察的变量组合而成的。

零售店可能有兴趣对其客户进行细分,如成本意识、品牌意识、批量购买者等。它需要根据客户的特征(如交易、人口统计、心理特征等)对客户进行分组。

在这方面,我们经常会遇到以下测试:

1.球形度测试

2.抽样充分性测试

3.聚类趋势测试

1。如何检验变量的球形度?

如果数据中的变量数量非常多,这种情况下的回归模型往往表现不佳。此外,识别重要变量变得具有挑战性。在这种情况下,我们试图减少变量的数量。

主成分分析(PCA)是一种减少变量数量和识别主要因素的方法。这些因素将帮助你建立一个降维的回归模型。此外,帮助识别任何感兴趣的对象或事件的关键特征。

现在,变量只有在它们有一定的相关性时才能形成因子。它是通过巴特列氏试验来检验的。该检验的无效假设是——变量不相关。

Python 实现:

from scipy.stats import bartlett
a = [8.88, 9.12, 9.04, 8.98, 9.00, 9.08, 9.01, 8.85, 9.06, 8.99]
b = [8.88, 8.95, 9.29, 9.44, 9.15, 9.58, 8.36, 9.18, 8.67, 9.05]
c = [8.95, 9.12, 8.95, 8.85, 9.03, 8.84, 9.07, 8.98, 8.86, 8.98]
stat, p = bartlett(a, b, c)
print(p, stat)

2。如何检验变量的抽样充分性?

当样本量足够大时,PCA 方法将产生可靠的结果。这被称为抽样充分性。将对每个变量进行检查。

凯泽-迈耶-奥尔金(KMO)检验用于检查整个数据集的抽样充分性。该统计测量变量中可能是普通方差的方差的比例。

Python 实现:

import pandas as pd
from factor_analyzer.factor_analyzer import calculate_kmo
a = [8.88, 9.12, 9.04, 8.98, 9.00, 9.08, 9.01, 8.85, 9.06, 8.99]
b = [8.88, 8.95, 9.29, 9.44, 9.15, 9.58, 8.36, 9.18, 8.67, 9.05]
c = [8.95, 9.12, 8.95, 8.85, 9.03, 8.84, 9.07, 8.98, 8.86, 8.98]
df= pd.DataFrame({‘x’:a,’y’:b,’z’:c})
kmo_all,kmo_model=calculate_kmo(df)
print(kmo_all,kmo_model)

3。如何测试数据集的聚类趋势?

为了将不同桶中的数据分组,我们使用了聚类技术。但是在进行聚类之前,你需要检查数据中是否有聚类趋势。如果数据具有均匀分布,则不适合聚类。

霍普金斯检验可以检查变量的空间随机性。此测试中的零假设是—数据是从非随机、均匀分布中生成的。

Python 实现:

from sklearn import datasets
from pyclustertend import hopkins
from sklearn.preprocessing import scale
X = scale(datasets.load_iris().data)
hopkins(X,150)

在本文中,我提到了一些数据科学中常用的测试。还有很多其他的我不能提及。如果你发现了一些我在这里没有提到的,请告诉我。

参考:

https://www . stats models . org/dev/generated/stats models . TSA . stat tools . grangercausalitytests . html

https://pypi.org/project/pyclustertend/

数据可视化的重要原则是什么?

原文:https://towardsdatascience.com/what-are-the-important-principles-of-data-visualization-3d3ca6c8c303?source=collection_archive---------29-----------------------

数据科学,数据可视化

数据可视化的架构必须专注于增强您公司的能力。要做到这一点,需要实践一些重要的原则。

卢克·切瑟在 Unsplash 上的照片

在这篇文章中,你可以探索数据可视化,什么样的可视化编码技术应该被考虑,你如何可以完善可视化,你所说的叙事可视化是什么意思?

“没有信息过载这回事。只有糟糕的设计。”—爱德华·塔夫特

“为了找到数据中的信号,我们必须学会减少噪音——不仅是数据中的噪音,还有我们身上的噪音。除了数据中的噪音,嘈杂的大脑几乎不可能感知到任何东西。”—斯蒂芬·诺

你说的数据可视化是什么意思?

数据可视化是将原始数据转化为图表的过程,这些图表解释了数字,并使我们能够深入了解它们。它改变了我们利用知识构建意义、发现新模式和识别趋势的方式。

作为人类,我们通过视觉化快速理解信息。通俗地说,数据可视化就是获取数据的图形化表示。这使得决策者能够根据可视化和呈现的证据更有效地采取行动。

数据的可视化可以帮助企业。分析并将数据整合到企业中,将赋予原始数据更大的意义和用途。在旅游行业,数据可视化通过为服务提供透明和可操作的信息,真正使旅游管理员和消费者能够进行报告。数据驱动软件为所有利益相关者带来了好处,从财务总监到安全经理,从人力资源经理到旅行者本人。

数据可视化是任何分析师甚至企业最重要的技能之一。无论一个人在分析数据方面有多好,如果他们不能以一种传达他们想要呈现的内容的方式进行打包,并且人们不容易理解,那么很多分析就会丢失。

你应该考虑什么样的视觉编码?

(Smyers,2013)指出,数据可视化正在塑造我们的行业。更进一步,(Steele 等人,无日期)建议,当你详细了解你的数据时,你可以做视觉编码。

颜色并不是按照人脑的自然顺序排列的。因此,应避免误用颜色,如过度明亮的颜色。

根据(几个,2006)一个线图应该只用于时间序列数据。它有助于我们显示跨时间序列的多个数据点。

来源:https://www . perceptual edge . com/articles/b-eye/encoding _ values _ in _ graph . pdf

尝试显示时间序列数据的折线图,以避免遮挡,遮挡意味着隐藏数据。

来源:https://en.rockcontent.com/blog/line-vs-area-charts/

(Lundblad,noDate)指出,对于编码过程,长度、方向、角度、面积和体积、颜色阴影都应考虑在内。

来源:https://blog.qlik.com/visual-encoding

据《纽约时报》报道,近年来的饼状图受到观众的回避。此外,与可用于物品的水平条相比,垂直条应仅在物品较少时使用。此外,与抖动图相比,箱形图给出了清晰的结果。

(利略等人,2004 年)建议在给数据图形着色时应该考虑到贝佐尔德效应。贝佐尔德效应显示了观众感知的颜色是如何受到周围颜色的影响的。这意味着一种颜色会改变整个设计。

来源:https://en.wikipedia.org/wiki/Bezold_effect

类似地,(Bradley,2014)陈述了 prgnanz 定律,即观众能快速感知简单、清晰且易于理解的事物。

来源:https://www . smashingmagazine . com/2014/03/design-principles-visual-perception-and-the-principles-of-gestalt/

我们在选择颜色时需要非常小心,并且需要挑选颜色顺序。避免在同一个图形中使用红色和绿色,以保证色盲的人可以很容易地分辨数据。

如何提炼自己的可视化?

(Nelson,2016)指出 Tufte Lie Factor 有助于评估如何完美呈现视觉效果。这意味着图像中显示的效果大小应该等于数据的效果大小。你的数据应该有故事。

来源:自己的工作

根据(Bernhard,2012)不要标记所有的图,只标记重要的图。擦除冗余非墨迹数据就好。遵循这些原则将有助于观众快速理解图形。请尽量避免网格线。

来源:自己的工作

请尽量避免在图形中使用阴影

来源:https://silo.tips/download/principles-of-data-visualization

尽量显示数据变化,避免显示设计变化。

来源:https://silo.tips/download/principles-of-data-visualization

(Giard,2011 年)指出应该删除网格线,还指出当它在图表中过度使用时会引起振动,这会分散观众的注意力。

来源:http://davidgiard . com/2011/05/13/data visualization part 6 chart junk . aspx

(少,2011)建议应避免图表垃圾。装饰图形的内部对观众没有帮助,这是多余的数据墨水,不创造任何价值。请尽量避免在图形上使用装饰性的修饰。这也分散了观众对数据的理解。图表垃圾有利于视觉,但不利于理解数据。

来源:https://www . perceptual edge . com/articles/visual _ business _ intelligence/the _ chart junk _ debate . pdf

你说的叙事视觉化是什么意思?

(Taylor,2014 年)指出可视仪表板应以概述开始,其中应给出故事摘要。此外,使用放大和向下钻取来聚焦数据。

来源:https://public.tableau.com/profile/saurav.singla08#!/viz home/ukroadincidentsanalysis 2015 _ 15973397476360/ukroadincidentsanalysis 2015

请尝试实现故事的互斥和集体穷尽(MECE)技术。在故事构建中,请考虑纵向和横向逻辑。

来源:https://www.caseinterview.com/mece

来源:https://depictdatastudio . com/when-to-use-horizontal-bar-charts-vs . vertical-column-charts/

在叙述以下问题时应予以考虑:

  • 作为数据可视化工作的结果,你想提出什么要点?
  • 在浏览者看完你的数据图表后,你希望他们带着什么样的信息离开?
  • 你发现了哪些重要的趋势?
  • 有没有特别不寻常的例子你应该强调一下?

结论

数据可视化使得从数据中看到趋势和模式变得更加容易。遵循基本原则,每个人都很容易在视觉上感知物体。它有助于描绘来自数据的洞察力。它使决策者能够直观地查看数据,以便他们能够理解复杂的概念或识别新的模式。

参考

●伯恩哈德律师事务所,2012 年。数据可视化原理。可从网站 http://stat . pugetsound . edu/courses/class 13/data visualization . pdf获取

●南布拉德利,2014 年。设计原则:视觉感知和格式塔原则。可从https://www . smashingmagazine . com/2014/03/design-principles-visual-perception-and-the-principles-of-gestalt/获取

●利特尔·s,2006 年。可从https://www . perceptual edge . com/articles/b-eye/encoding _ values _ in _ graph . pdf获取

●少,s,2011 年。关于海图垃圾的辩论。可从https://www . perceptual edge . com/articles/visual _ business _ intelligence/the _ chart junk _ debate . pdf获取

●卡尼尔,s .没有日期。可从https://www . rdocumentation . org/packages/viridis/versions/0 . 4 . 1获得。

●贾德博士,2011 年。数据可视化,第六部分:图表垃圾。可查阅http://davidgiard . com/2011/05/13/data visualization part 6 chart junk . aspx

●j .利略、l .阿瓜多、h .莫雷拉和 I .戴维斯,2004 年。明度和色调感知:贝佐尔德-布鲁克效应和颜色基本范畴。Psicológica,25(1)。

●Lundblad,p .,noDate。将数据映射到可视化的第二个支柱:可视化编码。可从https://blog.qlik.com/visual-encoding获得

●g .尼尔森,2016。不要被发现用数据撒谎——看看 Tufte 的谎言因素。可从https://www . thot wave . com/blog/2016/08/15/don-get-catched-lie-with-data-check-out-tuftes-lie-factor/获取

斯迈尔斯,英国,2013 年。约翰·怀尔德·图基:大数据和可视化的先驱。可从 http://control trends . org/building-automation-and-integration/05/John-wilder-tukey-the-pioneer-of-big-data-and-visualization/获得

●斯蒂尔,j .,伊林斯基,n .,诺达特。第四章。从https://www . safari books online . com/library/view/designing-data-visualizations/9781449314774/ch04 . html中选择适当的可视编码

●t .泰勒,2014 年。如何在网络情报仪表板中使用信息搜索咒语?可从 https://www.recordedfuture.com/information-seeking-mantra/获得

●纽约时报,没有日期。数据可视化:基本原理。可从 http://paldhous.github.io/ucb/2016/dataviz/week2.html获得

现在,把你对TwitterLinkedin,以及Github!!

同意 还是 不同意 与 Saurav Singla 的观点和例子?想告诉我们你的故事吗?

他乐于接受建设性的反馈——如果您对此分析有后续想法,请在下面的 评论 或联系我们!!

推文@ SauravSingla _ 08,评论Saurav _ Singla,还有明星SauravSingla马上!

2020 年数据科学家需要什么技能

原文:https://towardsdatascience.com/what-are-the-in-demand-skills-for-data-scientists-in-2020-a060b7f31b11?source=collection_archive---------20-----------------------

将自然语言处理应用于实际的工作发布

来源: pixabay

如果你想成为一名数据科学家,你可能会问:

应该学习哪些数据科学语言/工具?

雇主想要的顶级技能是什么?

对学历的最低要求是什么?

为了以数据科学家的方式回答这些问题,我们对的职位描述应用了自然语言处理(NLP)技术。我们纳入了 2020 年 1 月 25 日来自北美 8 个城市的 2,681 份数据科学家职位发布。

来源:的确

很快我们也会在本文后面贴出用 Python 编写的分步分析。敬请关注。

更新:我们已经贴出了这篇文章的技术部分。查看如何在 Python 中使用 NLP:一个实用的分步示例——了解数据科学家对 NLTK 的需求技能。

先看结果吧!

热门工具需求

在分析中包含的工作公告中, 86% 列出了工作所需的特定工具。没有这些工具/语言,数据科学家就无法工作。

雇主需要的十大工具有:

  • 计算机编程语言
  • 结构化查询语言
  • 稀有
  • 火花
  • 亚马逊网络服务
  • Java 语言(一种计算机语言,尤用于创建网站)
  • 张量流
  • Hadoop
  • 斯堪的纳维亚航空公司

Python 是无可争议的赢家。62%的招聘信息要求具备 Python 知识。而其他一些需要 Python 相关的工具或包,如 Pytorch、Pandas、Numpy。

为什么?

因为 Python 是一种如此强大而简单的语言,它能做的不仅仅是机器学习建模。例如,数据科学家也可以使用它来自动化任务,使用云服务,并进行 web 开发。

要成为数据科学家,应该先学习哪种工具?

Python

SQL 也出现在 40%的招聘信息中。了解这种数据库查询语言仍然是一个好主意。经典永远不会过时。

人们经常认为 R 是 Python 的竞争对手。但是,根据这一分析,它并不接近。只有 39%的数据科学家的职位描述提到了 r。

其他与大数据相关的工具,如 SparkCloudAWSTensorflow 和 Hadoop 也很受欢迎。当雇主拥有大量数据时,这些都是基本要素。

除了 Python 和 R, Java 对一些雇主来说也很有价值。这对数据工程师来说更重要,但对数据科学家来说也很有用。

虽然 SAS在大公司中仍然很受欢迎,但对数据科学家的需求却减少了。该软件更适合报告,但在数据分析方面不够灵活。

数据科学家的招聘信息中提到的前 50 名工具列表如下。

数据科学家的 50 大工具

每个工具类别在职务公告中不会相互排斥,即一个公告可能会提到多个工具。“没有指定”意味着工作描述没有要求任何工具。

顶级技能需求

除了工具之外,数据科学家必须具备特定的技能或技巧才能成功。

用人单位要求的十大技能有:

  • 机器学习
  • 统计数字
  • 研究
  • 预言;预测;预告
  • 形象化
  • 建议
  • 最佳化
  • 深度学习
  • 自然语言处理
  • 回归

对许多人来说,机器学习就是数据科学家所做的一切。这个概念是有原因的。64%的招聘信息提到了机器学习。

数据科学家需要学习监督/非监督学习、强化学习等不同的算法;还有不同的模型,如决策树、人工神经网络、支持向量机。

机器学习是对算法和统计模型的科学研究,计算机系统使用这些算法和统计模型来执行特定的任务,而不使用明确的指令,而是依靠模式和推理。它被视为人工智能的一个子集。

根据维基百科的定义,它是计算机科学和统计学的混合领域。

统计学知识为数据科学家奠定了坚实的基础。59%的职位招聘都需要它。要成为数据科学家,我们应该学习数据收集、实验设计、概率分布和其他统计概念。

研究也被认为是数据科学家的一项重要技能。50%的工作要求这样做。数据科学是一个快速发展的领域。数据科学家必须具有创造性和适应性;探索和应用新概念。

机器学习或统计技能的子集,包括预测推荐优化、深度学习、自然语言处理和回归,也有需求。

不同的雇主需要不同的技巧。例如,一家信用卡公司可能希望我们预测客户的信用状况;一家聊天机器人公司希望我们分析自然语言。

数据可视化也越来越受欢迎。一张图胜过千言万语;右图或图像是大数据的总结。数据科学家需要很好地展示他们的分析结果。

下面是数据科学家招聘信息中提到的 50 大技能列表。

数据科学家的 50 大技能

像工具一样,每个技能类别在职位发布中并不相互排斥,即一个发布可能会提到多种技能。

最低教育要求

而且数据科学家往往被要求有较高的教育水平。

  • 49%的招聘信息要求最低学历为学士学位。
  • 27%提到了硕士以上学历。
  • 9%要求博士
  • 只有很少的职位要求博士后或工商管理硕士。
  • 15%的职位要求“未指定”,可以更开放一些。

所以好消息,相关领域的学士学位就够了。也就是说,拥有硕士或博士学位的人更有竞争力。

数据科学家的最低教育水平

成为数据科学家是一个令人兴奋但充满挑战的旅程。

但是正如我们所有人都知道的,在可预见的未来,数据科学将继续受到需求。

无论你是否已经拥有这些技能,开始都不晚!

资料来源:吉菲

在你离开之前,别忘了 报名参加刚刚进入数据快讯 !或者通过推特脸书与我们联系。
所以您不会错过我们的任何新数据科学文章!

更多来自 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/) [## 如何像老板一样操纵 Python 中的日期和时间——只处理数据

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

www.justintodata.com](https://www.justintodata.com/manipulate-date-and-time-in-python/)

Matplotlib 中的“plt”和“ax”到底是什么?

原文:https://towardsdatascience.com/what-are-the-plt-and-ax-in-matplotlib-exactly-d2cf4bf164a9?source=collection_archive---------0-----------------------

图像由 MediamodifierPixabay 上生成

在纸上绘图,还是在纸上的单元格中绘图?

事实上,作为最流行和最基本的数据可视化库,Matplotlib 从某些角度来看有点令人困惑。通常是看到有人问起

  • 什么时候应该用“斧子”?
  • 为什么有些例子用“plt ”,而另一些用“ax ”?
  • 两者有什么区别?

网上有那么多例子向人们展示如何使用 Matplotlib 绘制这种图表或那种图表,这很好,但我很少看到有教程提到“为什么”。这可能会让编程经验比较少或者是从 R 之类的其他语言切换过来的人变得非常困惑。

在本文中,我不会教你使用 Matplotlib 绘制任何特定的图表,但会尝试解释关于 Matplotlib 的基本但重要的内容——人们通常使用的“plt”和“ax”是什么。

概念

absolute visionPixabay 上拍摄的照片

澄清一下,我说的“plt”,在 Matplotlib 库中是不存在的。之所以叫“plt”是因为大部分 Python 程序员喜欢导入 Matplotlib,做一个别名叫“plt”,这个我相信你应该知道,但是以防万一。

import matplotlib.pyplot as plt

然后,回到我们的主要话题。让我们画一个简单的图表来演示一下。

import numpy as npplt.plot(np.random.rand(20))
plt.title('test title')
plt.show()

如上面注释的截图所示,当我们使用plt绘制图形时:

  1. 生成一个Figure对象(显示为绿色)
  2. 一个Axes对象被生成隐式带有绘制的折线图(显示为红色)
  3. 所有绘图元素,如 x 轴和 y 轴,都呈现在Axes对象内(显示为蓝色)

好吧,如果我们在这里使用某种隐喻:

  • Figure就像一张纸,你可以画任何你想画的东西
  • 我们要在一个“单元格”里画一个图表,在这个上下文里就是Axes
  • 如果我们只画一个图形,我们不必先画一个“单元格”,只要在纸上简单地画就行了。所以,我们可以用plt.plot(...)

明确地画出“细胞”

照片由 LUM3NPixabay 上拍摄

当然,我们可以在“纸上”明确地画一个“单元格”,告诉 Matplotlib 我们要在这个单元格内画一个图表。然后,我们有下面的代码。

fig, ax = plt.subplots()
ax.plot(np.random.rand(20))
ax.set_title('test title')
plt.show()

完全一样的结果。唯一的区别是我们显式地绘制了“单元格”,这样我们就可以得到FigureAxes对象。

事实上,当我们只想绘制一个图形时,没有必要“画”这个单元格。但是,你必须注意,当我们想要在一个图中绘制多个图形时,我们必须这样做。换句话说,次要情节。

n_rows = 2
n_cols = 2fig, axes = plt.subplots(n_rows, n_cols)
for row_num in range(n_rows):
    for col_num in range(n_cols):
        ax = axes[row_num][col_num]
        ax.plot(np.random.rand(20))
        ax.set_title(f'Plot ({row_num+1}, {col_num+1})')fig.suptitle('Main title')
fig.tight_layout()
plt.show()

在这个代码片段中,我们首先声明了我们想要“绘制”多少行和列。2 乘 2 意味着我们要画 4 个“单元格”。

然后,在每个单元格中,我们绘制一个随机折线图,并根据其行号和列号分配一个标题。请注意,我们使用的是Axes实例。

之后,我们在“论文”上定义一个“主标题”,就是Figure实例。所以,我们有了这个不属于任何“细胞”的超级标题,而是在纸上。

最后,在调用show()方法之前,我们需要请求“paper”——Figure实例——通过调用它的tight_layout()方法自动在单元格之间给出足够的填充。否则,

摘要

博多贝Pixabay 上拍摄的照片

希望现在你能更好地理解什么是人们正在使用的pltax

基本上,plt是大多数人常用的matplotlib.pyplot的别名。当我们使用plt比如plt.line(...)绘制东西时,我们隐式地在Figure对象中创建了一个Figure实例和一个Axes。当我们只想画一个图形时,这完全没问题,而且非常方便。

但是,我们可以显式调用plt.subplots()来获得Figure对象和Axes对象,以便对它们做更多的事情。当我们想在一个Figure上绘制多个支线剧情时,通常需要使用这种方法。

此外,这里是 Matplotlib 官方 API 对FigureAxes类的参考。强烈建议你去看看,自己尝试一些方法,以确保你理解得更深。

[## Matplotlib . axes-Matplotlib 3 . 3 . 1 文档

实例通过实例的回调属性支持回调。您可以连接到的事件有…

matplotlib.org](https://matplotlib.org/api/axes_api.html?highlight=axes#matplotlib.axes.Axes) [## Matplotlib . figure . figure-Matplotlib 3 . 3 . 1 文档

所有绘图元素的顶层容器。Figure 实例通过回调属性支持回调…

matplotlib.org](https://matplotlib.org/api/_as_gen/matplotlib.figure.Figure.html#matplotlib.figure.Figure) [## 通过我的推荐链接加入 Medium 克里斯托弗·陶

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

medium.com](https://medium.com/@qiuyujx/membership)

如果你觉得我的文章有帮助,请考虑加入 Medium 会员来支持我和成千上万的其他作者!(点击上面的链接)

机器学习有什么实际好处?

原文:https://towardsdatascience.com/what-are-the-practical-benefits-of-machine-learning-c9820dbdd67c?source=collection_archive---------64-----------------------

从非技术角度了解机器学习和数据科学在我们日常生活中的实际使用案例和影响。

Unsplash 上由 Franck V. 拍摄的照片

我在之前的一些关于机器学习和数据科学的入门帖子有点技术性。然而,我这篇文章的目的是从一个以前从未接触过 ML 的非技术性门外汉的角度来解释一些 ML 的实际使用案例。为了满足您的好奇心,如果您想了解更多,我还将提到通常适用于每个用例的特定 ML 算法。

ML 帮助我们解决什么类型的问题?不考虑具体领域,它提供了什么答案或可行的见解?我们在这里将更多地关注“是什么”和“为什么”,而不是“如何”。

这是什么?a 还是 B?

这个 ML 算法家族预测一个观察值属于仅有的两个可能类别中的哪一个。没有其他第三种可能的选择。假设管理层想要预测哪些现有客户会流失。答案只能是特定客户会不会流失。其他实例包括:

  • 这是不是垃圾邮件?
  • 这个客户会不会违约?
  • 这些症状是否是特定疾病的症状?
  • 该客户是否会继续购买?
  • 这是男孩还是女孩的形象?

正式名称为二元分类,相关算法包括:

  • 逻辑回归
  • 支持向量机
  • k-最近邻
  • 分类决策树

这是什么?a 还是 B 还是 C 还是 D(或者别的什么)?

二元分类的扩展,这里,潜在类别的数量可以多于两个。假设您正在开发一个人脸识别模型;特定图片中的人可以是数据库中的任何个人。可能正确答案的数量仅限于模型开发过程中使用的数据量。其他实例包括:

  • 光学字符识别:这是哪个字符?
  • 这幅图中是哪种动物?
  • 这部电影属于哪种类型?
  • 情绪分析:与这条推文相关的感觉是什么?
  • 这段录音里是谁的声音?

正式名称为多类分类,相关算法包括:

  • 随机森林
  • 分类决策树
  • XGBoost
  • k-最近邻
  • 人工神经网络

有多少或多少东西值得期待?

这一系列的 ML 算法将某事物的数量预测为连续的输出或数字(即,预测可以是无限数量的可能结果中的任何一个)。没有可以预测的固定的可能类别,例如,预测下一季度的销售量。该销售预测可以是 1,000 台、10,000 台、1,200 台或任何其他正实数。

这些算法的输出可以是任何实数(正数、负数、零、分数);然而,您的具体用例将决定是否可以预期和接受负数或分数。例如,销售预测不能为负数。

这类算法的其他实际使用案例包括:

  • 明天的温度是多少?
  • 下个季度我们可以与多少潜在客户签约?
  • 下个月我们的能源消耗是多少?
  • 一个事件发生需要多长时间?

正式名称为回归,相关算法包括:

  • 线性回归
  • 回归决策树
  • XGBoost
  • 人工神经网络

这个数据是正常还是异常?

通常,我们更感兴趣的是某个特定的观察结果是不典型的、异常的还是异常的。或者仅仅是一个正常和平常的观察。我们可以将历史观察分为异常或非异常。或者可能是这种历史分类不存在的情况,并且将使用 ML 算法来检测任何异常值。

典型的使用案例包括:

  • 这次购买与客户过去的购买有实质性的不同吗?
  • 这种来自计算机网络的流量模式是典型的吗?
  • 这些来自工业设备的输出是非典型的吗?

正式名称为异常值或异常检测,相关算法包括:

  • 隔离森林
  • 基于密度的噪声应用空间聚类(DBSCAN)
  • z 分数(技术上不是 ML 算法,而是识别异常值的统计测试)
  • 单类支持向量机

我们如何组织这些数据?

是否有任何潜在的可识别特征可用于将数据分类和组织到特定的组(也称为簇或段)中?我们不知道这些独特的特征,通常,甚至不知道潜在簇的数量。对数据进行聚类或组织可能有助于您进一步分析或制定特定于聚类的策略。

例如,我们可以根据客户的年龄、性别、购买历史等将他们划分为不同的群体。设计特定细分市场的销售、营销或促销策略。

这类算法的其他实际使用案例包括:

  • 我们的哪些订户喜欢类似的电影或歌曲?
  • 我们如何对几个文本文档或录音进行分类?
  • 我们如何更好地细分我们的产品或服务?
  • 哪种型号的机器更容易出故障?

正式名称为聚类,相关算法包括:

  • k 均值聚类
  • 均值漂移聚类
  • 基于密度的噪声应用空间聚类(DBSCAN)
  • 凝聚层次聚类
  • 使用层次结构的平衡迭代约简和聚类(BIRCH)

下一步做什么?

这就是 ML 变得真正有趣的地方,ML 算法不仅预测,而且告诉我们如何给定它的预测。这个 ML 算法家族对于所有用例来说可能还不够成熟;然而,鉴于先进的深度学习算法和我们可用的更大处理能力,最近取得了实质性进展。

这些算法依赖于反复试验和多重反馈循环,而不像其他算法那样严重依赖数据。主要适用于自动化系统,推荐的操作通常由机器执行。

正式名称为强化学习,通常通过深度神经网络实现。

强化学习的一些实际应用包括:

  • 在工业企业的情况下,机器人下一步应该做什么?
  • 我们应该调节温度还是保持不变?
  • 自动驾驶汽车应该如何反应(加速、减速、刹车等)。)鉴于前方的危险?

结论

现在你有了:一个实用的、严肃的功能场景介绍,其中 ML 用简单的语言帮助我们。

如果您想进一步讨论与机器学习、数据分析、风险评分和金融分析相关的任何内容,请自由发表评论或联系 me

下次见,继续!

我们是什么,心理学家?

原文:https://towardsdatascience.com/what-are-we-psychologists-e33f82bf263d?source=collection_archive---------31-----------------------

肯定不是,但是我们可以通过在代码中输入电影名称来模仿它们

有时会有一个突然的想法,比如“自 1990 年以来,每年最畅销的电影是什么?”当我们在找事情做的时候突然出现。但是我们不想浪费时间去探究每一条独立的信息,比如发布日期、受欢迎程度、评论或者谷歌、IMDb、TMDb 或烂番茄的平均评分。

对于那些想尽快得到这些信息的人,我写了一些代码来加载电影信息,只需输入标题就可以快速分析电影评论。仅供参考,我使用 TMDb 的 API 编写代码。

在抓取网站之前

必须检查该网站的“robots.txt”文件,以确定该网站是否允许其内容被抓取。要查找给定网站的 robots.txt 文件,请键入基本 URL 并添加“/robots.txt”。

例如,如果我们想从 google.com 搜集一些数据,在 URL 框中输入 https://www.google.com/robots.txt。

  • 如果 robots.txt 允许完全访问,则不允许字段将为空,例如:

用户代理:*

不允许:

  • 如果 robots.txt 阻止所有访问,不允许字段将包含反斜杠,例如:

用户代理:*

不允许:/

  • 如果 robots.txt 允许部分访问,禁止和允许的部分将用一对反斜杠标识,例如:

用户代理:*

不允许:/section/

允许:/section/

例如,我键入https://www.imdb.com/robots.txt来检查来自 IMDb 的 API 可用性,但是它似乎不可用。

幸运的是,电影数据库(TMDb)在其网站上提供了开放的 API,所以我选择了 TMDb API 来编写代码。

首先安装所有模块

首先,我安装了所有用于编写代码的模块,包括使用 TMDb 数据的 tmdbsimple 模块。这个模块是 TMDb API 的包装器。

安装所有模块

输入 API 密钥(该密钥可在 TMDb 网站上获得)

用标题和上映日期(年份)搜索电影

设置 tmdb。Search() 模块,然后输入您想要搜索的任何电影名称。

年份是可选的(如果您不知道确切的发布日期,可以将该字段留空)

我搜索了“寄生虫”,年份为空。

输入'寄生虫'后,上述代码中的信息

为了可读性,只提取标题、id、流行度、发布日期

我提取了标题、id、人气、发布日期数据,并将这些数据输入到 Moive_info 列表中。之后,我把 Movie_info 列表转换成 Pandas DataFrame。

数据帧中的电影信息

在数据中,id 是一个唯一的值,因此它可以区分相同或相似的数据。比如上表中有那么多含有“寄生虫”的标题。即使这些电影在不同的日期上映,如果只有片名信息,人们可能会感到困惑。然而,如果他们有电影 id,这意味着他们有关于每部电影的唯一信息。因此,他们只能得到他们想得到的信息。如果他们使用标题来搜索电影评论,结果会与其他电影的相同或相似标题的评论混淆。

获取 TMDb 评论

因为 URL 通常包含 id 号来创建每部电影的网址,所以我们需要这个惟一的值来获得电影评论页面。例如,我使用上表中的 id‘496243’来获取 TMDb 上寄生虫的网页。

获得 API 链接后,我使用requests . get 模块请求 HTTP。<响应【200】>表示效果良好。然后我通过解析 API URL 得到了一个包含“寄生虫”电影评论的数据帧。TMDb 上好像有五条关于“寄生虫”的评论。

之后,我提取了“结果”列,其中包含了评论、作者、内容等等。

在 4 个关键字中,实际的评论包含在“内容”关键字中

然后我做了一个空列表,然后把“内容键”放入“评论”列表

[输出]:

应用分词器分析评论中的每个单词

标记化是文本清洗的一种方式。将一段文本分割成更小的子段——通常,这可以分解到单个单词的级别,即每个不同的单词都成为一个“标记”,并且一个单词或短语的所有后续实例都被赋予相同的标记值。

将评论从 NLTK 库输入到 word_tokenize 模块对句子进行分词,然后打印分词器创建的分词。

[输出]:

标记化句子

从文本中删除停用词

停用词是经常出现的词,通常不作为名词或动词传达实质意义。一些例子:“一个”,“一个”,“the”,“and”,“or”等。在文本挖掘过程中,停用词经常被丢弃/忽略。

导入停用词

从列表“tokens”中获取不包括在英语停用词中的单词,然后将提取的单词放入列表“word_list”中。

情感分析

Afinn 库

我使用了 Afinn 库,这是一个情感分析库,显示了从-5 到+5 的整数形式的英语单词的积极和消极水平。给句子打分时,会计算句子中的所有单词。这是一个非常简单的库,但是它最常用于情感分析。

我通过使用连接函数将列表形式转换为字符串。join 函数将列表转换为包含特定分隔符的字符串。之后,将字符串放入 Afinn 库中以获得情感分数。

[输出]:

至于结果,每篇评论的总分是 7.0、30.0、1.0、26.0、41.0。例如,第一篇评论中有许多来自整个句子的单词——[‘什么,使,寄生,满足,提交,两者都不是,错误,…..It,电影,节日,评论']。最后 7.0 分是每个单词得分的总和。

EmoLex 库

这一次,我尝试用不同的方式分析相同的字符串:使用 NRC 字典的 EmoLex 库。NRC 的数据可以在这里获得用于非商业研究用途。

141,820 行

提取得分为 1(非 0)的标签来评估情感得分

[输出]:

13,901 行

141,820 行→ 13,901 行—大幅缩减!

之后,为了保持一致,我将所有文本转换为小写的

文本清理—将所有文本转换为小写****

然后,我将“寄生虫”电影评论中的字符串与 NRC 字典中的情感文本进行匹配,以获得情感得分。

[输出]:

可视化

使用 plot.bar() 函数创建一个条形图。

[输出]:

****

表格中的相同数字可视化,以方便读者阅读

我们要去哪里

现在我们发现对《寄生虫》的评论总体上是正面的。我为情感分析生成了非常简单的代码,在下一篇文章中,我将通过数据清理和正则表达式来分析更多的评论。

一般来说,情感分析的目标是分析新闻报道、电影、社交媒体帖子(如推文、Instagram 帖子等)的观点,以引导消费者做出理性决策。例如,分析“寄生虫”评论的结果可以让人们决定他们是否要看这部电影。

情绪分析是目前每个人都想谈论的话题,因为人们知道感觉总是先于决策。换句话说,沉浸在情绪分析中已经开始了,人们希望很容易地看到当代趋势。

从你渴望了解更多的话题中分析感悟。如果你这样做了,你会比任何人都更早了解到你感兴趣的最新趋势。

大数据到底意味着什么

原文:https://towardsdatascience.com/what-big-data-actually-means-d4b00e8ae00?source=collection_archive---------38-----------------------

本文简要总结了您必须了解的大数据这个术语

红杉——世界上最大的树,图片由作者提供

一般定义

大数据是指来自互联网、移动电话、金融行业、能源行业、医疗保健等领域的大量数据。以及智能代理、社交媒体、智能计量系统、车辆等来源。使用特殊解决方案对其进行存储、处理和评估[1]。

与大数据相关的领域和术语—按作者分类的图片

4 伏电压

为了处理、存储和分析数据,必须考虑以下四个挑战:

  • (庞大的数据量——2025 年的数据将是 2017 年的八倍[2])
  • 速度(数据生成和处理的速度,例如流媒体、IOT、社交媒体)
  • 多样性(结构化和日益非结构化的数据)
  • 准确性(缺乏数据质量和评估技术)

技术方面

但是我们什么时候谈论大数据呢?必须收集多少数据?正常的数据存储技术通常以兆字节/千兆字节工作。当数据量达到万亿字节/千兆字节时,我们就在谈论大数据。这种经验法则的原因是,当处理这种数据量时,传统系统不再足够强大,而且成本也明显更高。

大数据(存储)技术的典型特征是:

  • 分布式存储
  • 数据复制
  • 本地数据处理
  • 高可用性
  • 数据划分
  • 非规范化数据
  • 处理结构化和非结构化数据

分析和可视化方面

通过使用大数据技术,使用和分析数据有了新的可能性:

  • 通过更多可用的计算能力(关键词:云),可以更快地处理/分析更大量的数据(例如,对于机器学习是必不可少的)
  • 深度学习(基于大量数据,例如图像)
  • 实现实时报告是必要的,例如在物联网领域

但是由于大量的数据,可视化领域也带来了新的方法和挑战。因此,必须创建新的可视化技术,以使数据量对用户来说更加有形。

下图显示了一些可视化示例:

可视化—来源:https://gear heart . io/blog/how-build-custom-data-visualization-software/[3]

未来会带来什么?

虽然就数据量而言,许多公司尚未进入大数据世界,但大数据的一两个特征可能适用于他们的数据。但是有一点是明确的:数据量将不断增长,即使不是指数增长,因此为这个主题做好准备也是有用的。人们在考虑他们的 IT 架构和系统环境时,需要考虑大数据。

还有一点,深度/机器学习这个新兴领域,通过更多的数据进行训练,变得越来越高效。因此,该区域是大数据的完美补充。借助功能强大且易于使用的公共云提供商服务,人们能够更快、更轻松地处理、存储和分析大数据。这对于中小型公司来说尤其有利[4]。

结论

大数据绝对是一个时髦词,并不是每个公司都需要大数据,但如果大数据领域提供了巨大的优势和处理数据的新方法。然而,它带来了需要克服的技术挑战。有了公共云服务,这一挑战更容易应对。

来源

[1]谷歌,【https://cloud.google.com/what-is-big-data

[2]麦肯锡公司,人工智能下一个数字前沿? (2017)

[3] itsvit,https://it svit . com/blog/big-data-information-visualization-techniques/

[4] Bernice M Purce 大数据利用云计算 (2013)

进一步阅读

[## 大数据:信息可视化技术

我们最近探讨了大数据可视化原则。现在是时候深入研究大数据可视化了…

towardsdatascience.com](/big-data-information-visualization-techniques-f29150dea190) [## 如何构建一个自定义的数据可视化软件?

在大数据成为新石油的时代,几乎任何有销售历史的公司都需要新的决策方法…

gearheart.io](https://gearheart.io/blog/how-build-custom-data-visualization-software/)

博士学位能给你的数据科学职业生涯增加什么?

原文:https://towardsdatascience.com/what-can-a-phd-add-to-your-data-science-career-b7204ef1c7bc?source=collection_archive---------18-----------------------

约书亚·厄尔在 Unsplash 上的照片

(你花了多少钱。)

有许多通向数据科学的职业道路。尽管这个领域最初主要由有学术背景的人组成,但这绝对不是唯一有效的切入点。关于是否应该拥有博士学位才能成为数据科学家的长期争论已经得到解决:你不需要。然而,博士学位绝对可以提供一些非常独特的好处,可以提升你的工作和生活。在这篇文章中,我的目的是客观地提供这条道路最重要的优点和缺点。

在我们继续之前,我要做的正确的事情是介绍我自己,向你表明我是根据个人经历来说的。所以,我是一个训练有素的纯数学家。我已经完成了我所有的数学学位(学士、硕士和博士),因为我太喜欢它了。读完博士后,我加入了一个计算生物学研究小组,担任博士后研究员,这是我通向机器学习的大门。在接下来的三年里,我将深度学习应用于各种细胞生物学问题,主要与高通量显微镜有关。目前,我正致力于建立我的创业公司。我从个人经历中知道,博士学位可能是一段美丽而又艰辛的旅程。如果你在做这个选择之前,我希望我能为你提供有用的信息来做决定。

你想要博士学位吗?

如果你想获得博士学位,有一个基本要求必须满足。在我从事学术界的七年时间里,我遇到过无数在终点线前放弃的学生。

有一个因素决定谁成功谁失败:推动知识边界的深层内在动力。

我认识的那些完全为了可能的职业发展而开始旅程的人没有一个例外地完成了学位。读博对他们来说是一段痛苦的经历。如果你真的不想读博士,那么,好吧,别读了。如果是这样的话,有更多的最优路径让你成长。

然而,如果你有某种内在驱动力,你会发现这条路有几个独特的价值。

好的一面

每个工作和博士职位都不一样。从每个方面来看,它们分布在一个很宽的范围内,在这个范围内,极端是可能的。这意味着我在这里提到的好处并不仅限于学术界,在某些情况下,它们可能根本不存在。例如,我首先要谈的是学术自由。有些公司可能会允许你控制发展方向,因为有些研究小组你无法影响你作为博士生的研究方向。

话虽如此,趋势是明显的。平均而言,行业职位往往落在光谱的一边,而博士职位则落在另一边。

学术自由

当你有一个博士职位时,它不同于任何工作。如果你受雇于一家公司,除非你得到了一个非常高级的职位,或者你是一家初创公司的首批雇员之一,否则你影响企业方向的空间将是有限的,甚至是不存在的。但是,当你在做研究的时候,通常不是这样。作为一名博士生,你被期望控制项目的计划和执行,有可能自己探索新颖的想法。与工业相反,在这里兴趣常常胜过实用性。这种自由既是福也是祸:你可以追求广泛的主题,但很难决定哪些是值得的。

深入研究一个课题

在你的研究中,你必须成为你狭窄领域的顶尖专家。如果你能在未来的工作中找到利用这些知识的方法,这会让你远远领先于所有人。这是一个你不太可能在工业界得到的机会,因为那里的事情进行得更快,而且通常你没有时间真正深入。

启发智力的环境

你的环境在你的成长中起着重要的作用。和非常聪明的人在一起是提升自己的好方法。你的导师、教员和你的同学都是想法和激发讨论的极好来源。就其本质而言,学术是推动艺术发展的地方。

拓展知识的边界

创新需要失败,这在行业环境中通常是不可取的。然而,在研究中并非如此,所以作为一名博士生,你被给予了经常失败的机会。(相信我,这一点非常重要。)你没有要服务的用户,没有要维护的产品,这让你可以专注于不断前进。在典型的行业环境中,这样做的动机通常很少。

更多展示你作品的机会

作为一名博士生,一个重要的部分就是在会议上展示你的演讲。通常在科学基金中有一个特别的预算分配,或者会议可以自己提供基金。除了 Twitter 等在线媒体,会议是展示你的工作、获得反馈和建立关系网的最佳方式。

不好的一面

除了好东西,学术道路还有几个困难。如果你正在考虑这个方向,你必须意识到这一点。如果你意识到了,一些潜在的麻烦可以减轻。

机会成本

从职业的角度来看,花在读博士上的时间并不是花在建立学术之外的职业生涯上。如果你希望最终进入这个行业,那你就错过了那些年。获得学位后,你很可能仍会被聘用到初级职位,这实际上让你落在了后面。博士学位是对知识的投资,需要数年才能收回。

财务成本

这取决于你的国家的高等教育体系,但一般来说,你获得的奖学金远远超过了工业工资,即使是大三学生。你甚至可能不得不支付非常昂贵的学费,这可能会让你负债累累。如果你不确定这项投资会有回报,让自己负债并不是一个好主意。

长期时间承诺

如果你开始了一份新工作,但很快你意识到它并不适合你,通常你可以离开而不会对你的职业生涯产生负面影响。但是,对于 PhD 来说就不是这样了。研究生课程的结构是这样的,最大的回报——你的博士学位——本质上是在一个时间门之后。提前退出这个项目就像在你的授权期开始前放弃一份创业工作。不幸的是,正如我们看到的,有很多理由离开。

没有动力去正确地建造东西

在研究中,第一个解决问题或有所发现是最重要的。如果你的竞争对手刚好在你之前冲过终点线,基本上你所有的工作都白费了。你将不能发表文章,也不会被承认你的成果。正因为如此,一些东西常常被拼凑在一起,只是为了让它们更快地工作,这使得其他人很难在结果的基础上进行构建。此外,你通过出版来推进你的事业,这也激励你快速前进。

幸运的是,这些趋势正在慢慢改变,至少在计算机科学和数据科学领域是如此。

没有人在那里帮助你

在研究中,荣誉很重要。每个博士生都在做他们的大项目,这对合作是不利的。然而,各研究领域之间存在差异。在计算机科学领域,人们更倾向于合作,但在生命科学领域,你几乎肯定是孤立的,你的同学可能是你的竞争对手。滥用职权的主管会让这种情况变得更糟。我曾见过导师将几个学生放在同一个问题上,让他们相互对抗以激发竞争。第一个解决问题的人能够毕业,其余的人不能。

独自工作也会影响工作本身的数量。没有 DevOps 团队来帮助你,没有人会代替你写文章,没有人会画插图,拼凑一个合适的用户界面,推广你的作品等等。最有可能的是,你必须独自完成这项工作。

压力大

由于我们已经谈论的所有事情,压力对一个学生来说经常是巨大的。这些来源既有内在的,也有外在的,往往在恶性循环中相互助长。对于一个研究人员来说,这是一个很难做到的事情。这导致了潜在的精神问题,使完成目标更加困难,进一步放大了内部斗争。

心理健康问题在博士生中频繁出现并非偶然。有几个关于这个的研究,例如下面的一个强调了在几个组中受每个问题影响的人的比例。

来源:工作组织与博士生心理健康问题,Katia Levecque 等人。

杀不死你的会让你变得更强

根据我的个人经验,我知道我们刚刚讨论的所有内容。我有经济困难,与我的导师关系不好,在出版压力下挣扎,有自杀倾向,不得不寻求帮助,还有许多其他问题。但是每一步,我都努力克服这些,我最终成功了。

我从博士学位中获得的最重要的东西是勇气。

最有价值的收获不是职业利益,也不是渊博的知识。它从另一边走出来,知道所有的障碍都可以通过艰苦的工作和努力来克服。

如果你喜欢把机器学习概念拆开,理解是什么让它们运转,我们有很多共同点。看看我的博客,我经常在那里发表这样的技术文章!

AI 能从大脑学到什么?

原文:https://towardsdatascience.com/what-can-ai-learn-from-the-brain-e981e2f0ef4f?source=collection_archive---------40-----------------------

什么是智能?以及大脑如何成为人工智能的灵感。

亚历山大·奈特Unsplash 上拍照

本文将分享以下内容:

什么是智能?

当我们在军事意义上思考情报时,我们想到的是知识。其他人可能会在智力的定义中加入技能。还有一些人认为智力是获得知识和技能的能力。我认为我见过的对智力的最好定义是由谷歌深度学习研究员 Francois Chollet 给出的,他本质上说,智力是有效地学习技能和知识以解决以前没有见过的新问题的能力。这个定义中有一些有趣的东西:

  1. 拥有知识或技能不被定义为智力。因此,当 IBM 的沃森在《危险边缘》中击败肯·詹宁斯时,或者深蓝在国际象棋中击败卡斯帕罗夫时,他们都是令人印象深刻的技术壮举,但他们是 T42 而不是智力的展示。这些系统依赖于人类程序员的聪明才智和插入到这些系统中的知识。沃森或深蓝无法看到一些如何烹饪的例子,并开始制作意大利晚餐。
  2. 这个定义特别强调了新技能的高效学习。像 GPT-3 这样的系统已经展示了令人难以置信的自然语言和生成文本的能力——但是它们是使用大多数网络公开知识训练出来的(从 45TB 文本开始!).很难说这是有效的。更重要的是,GPT-3 仅限于文本相关的任务。你不能提供一个新的任务——比如叠衣服或如何识别一个成熟的鳄梨——并希望同一个系统能够有效或高效地学习这项任务。

Chollet 在人工系统的智能测量方面开创了一些有趣的工作。他试图量化指标,并提出了一种方法和一些初步测试来量化系统的有效学习能力。没有这样的客观测量,很难判断我们是否正在向真正的智能系统发展。这是他关于智力测量的论文的链接,但是这个播客有一个很好的对话和概述,正如这个博客帖子一样。额外的此类测试包括原始的 Winograd Challenge 和修订的wino grade Challenge以更好地尝试理解常识推理。

[## #120 -弗朗索瓦·乔莱:智力测量|麻省理工学院|人工智能播客

弗朗索瓦·乔莱(Franç ois Chollet)是谷歌的人工智能研究员,也是 Keras 的创始人。

lexfridman.com](https://lexfridman.com/francois-chollet-2/)

神经网络

"N 神经网络是一系列模拟人脑运作的算法,用来识别大量数据之间的关系。"这里有一个简单的图像来帮助形象化这个概念:

形象信用

至少有一些变化,但是机器学习(例如监督机器学习)的基本概念是:

  1. 计算任务可以被建模为神经网络。以计算机视觉和识别图像是猫还是狗为例。该任务是复杂的非线性函数,其中输入是一组像素(例如输入图像),输出是表示图像是猫或狗的标志。
  2. 人类标注的数据可以用来训练系统。由人类识别和标记的狗和猫的已知图像可以被输入到系统中,以训练函数的参数。

一个简短的时间线:受大脑生物学的启发,神经网络在 20 世纪 40 年代构思,在 60 年代末和 70 年代初普及,在 80 年代复兴,在 90 年代消亡,在 21 世纪初再次崛起。在过去的 10 年里,随着深度学习(deep learning)的出现,它们真正变得有用了。深度学习是指用于解决计算机视觉、语音识别等有趣问题的深度多层神经网络,互联网提供了大量的训练数据,计算能力的大幅提高使这些计算和算法变得实用。

深度学习的挑战

虽然受到大脑的启发,并且取得了令人印象深刻的成就,但神经网络和深度学习仍然相对简单。正如我们在 GPT-3 的例子中看到的,训练一个系统可能需要大量的数据,而这些系统只能获得有限的知识,不能灵活地学习另一项任务。

根据 NYU 大学心理学和人工智能教授 Gary Marcus 的说法,深度学习面临几个这样的挑战:数据效率转移学习,分层知识,开放式推理,可解释性,整合先验知识,因果推理,不稳定世界建模,以及鲁棒性。

从根本上说,这些深度学习系统最多是为了狭隘的理解而设置的。它们对环境的重大变化或稍微不同的任务并不健壮。他们没有常识性的理解。他们没有能力将学习从一项任务转移到另一项任务。

AI 如何向大脑学习?

在设计人工智能系统时,仍有许多人从儿童如何学习中获得灵感。孩子们表现出难以置信的学习能力,并有效地利用一系列工具。加州大学伯克利分校的人工智能教授 Jatindra Malik 在本期播客中,结合这篇论文,分享了以下 6 件人工智能可以从孩子身上学到的事情:

  • 多模态
  • 是递增的
  • 探索
  • 社交化
  • 身体力行
  • 使用语言

[## #110 - Jitendra Malik:计算机视觉|麻省理工学院|人工智能播客

Jitendra Malik 是伯克利的教授,是计算机视觉领域的开创性人物之一,是那种…

lexfridman.com](https://lexfridman.com/jitendra-malik/)

例如,儿童使用多种方式学习——也就是说,他们会看到、触摸、听到他们周围的世界,并通过这种方式收集关于行为的情报和知识。

他们以增量方式做这件事开始时几乎没有什么知识,随着他们的经历,他们将脚手架和新知识添加到结构中。

当你把玻璃杯掉在地上时,你可以听到它破碎的声音。所以看起来像玻璃的东西通常是易碎的。多种模态——例如整合视觉和听觉——和增量学习可能是加速人工智能系统学习的重要构造。

孩子们也探索 T21,和他们周围的世界玩耍。他们会尝试一些事情。如果有些东西不起作用,他们可以继续尝试,或者他们身边会有一个更有经验的人(例如父母)来纠正他们或教他们;这是他们生活的社会世界的本质,这可能对人工智能有用。尝试某事的想法——而不是输入一堆静态的历史数据或标签数据——是一种思考学习、与世界互动的有趣方式,或许能更有效地加速我们对它的学习。

加里·马库斯关于“为什么初学走路的孩子比电脑聪明”的 TED 演讲准确地解释了这些概念:

强化学习是机器学习中的一种相关技术,它可以更少地依赖于训练数据,而更多地依赖于实现目标和自我游戏。这种技术在 AlphaGo 项目中被广泛使用,成功击败了围棋世界冠军。AlphaGo 通过独自玩游戏****数百万次,并学习哪些策略有效,哪些策略无效,从而学会了下围棋。虽然效率不高,也不完全可移植,但这些概念似乎很有前途。如果你还没有看过,我强烈推荐 AlphaGo 纪录片——我既被创造这个系统的团队的独创性所鼓舞,又在看着一个人输给这台机器时感到矛盾。

** [## 谷歌的 AlphaGo 如何击败围棋世界冠军

2016 年 3 月 19 日,世界上最强的围棋选手李·塞多尔坐下来与谷歌 DeepMind 的…

www.theatlantic.com](https://www.theatlantic.com/technology/archive/2016/03/the-invisible-opponent/475611/)

直接引用史密斯和加塞的论文来总结人工智能可以从大脑学习的最后两个领域:

婴儿生活在一个物理世界里,充满了丰富的规律来组织感知、行动和最终的思维。婴儿的智力不仅存在于他们自身,还分布在他们在现实世界中的互动和经历中。物质世界有助于提升更高的精神功能。

婴儿学习一种语言,这是一种共享的交流系统,具有象征意义。这改变了一切,使孩子们能够形成更高层次和更抽象的区别。

总之,人类学习的方式有许多方面——社会地、渐进地、通过多种方式——人工智能可以从 中获得灵感,从而实现 真正的智能,也就是高效地学习全新的任务。

我们能从整个社会学习吗?

虽然人工智能研究可以从研究个体人类学习中受益和进步,但人工智能可以从整个社会中学到什么?如果你把一个今天的婴儿和一万年前的婴儿放在一起,他们在生物学上非常相似,但是今天的婴儿会比他/她的生物祖先学得更多,也许更快。为什么?是的,现在有了更多的信息,但是除了书籍和维基百科,这些信息是如何编码的呢?我们如何转移这样的常识和文化学习?社交学习、编码习俗、行为甚至价值观的概念是一个有趣的概念,观察我们如何将文化和相互依赖塑造成未来的自主代理人将是一件有趣的事情。

结论

如今,机器学习取得了令人难以置信的进步和发展,这得益于更多的数据、更快的计算以及更好的算法和架构。然而,我们离智力和学习的一般理论还很远,从理解我们的生物学习系统中,我们还有很多要学习和收获的。我对认知科学、心理学、神经科学和计算机科学之间的多学科学习以及改善我们自己的生物——以及推进人工智能的前景感到鼓舞、兴奋和高度乐观。**

这篇文章是关于大脑的系列文章的一部分。请随意点击这里的查看这个系列的开头,它包括了关于神经解剖学、行为、学习、人工智能和自由意志的其他文章的链接。

参考

分析 200 多万个街道名称能揭示什么?

原文:https://towardsdatascience.com/what-can-analysing-more-than-2-million-street-names-reveal-c94be585759?source=collection_archive---------16-----------------------

我分析了英国的每一个街道名称,以下是四个最令人兴奋的结果。

林肯郡范妮·汉兹巷。来源

争论场、裤裆新月、屎特顿、公鸡巷、乳头街都是英国有趣的街道名称。这些街道名称不仅有趣,而且揭示了许多关于社区、他们的文化和历史。最近对英国愚蠢名字的抱怨包括房价下跌和住在这些愚蠢街道名字里的孩子受到更多欺负。

街道命名不仅是政治和行政决策,也反映了城市的社会和文化价值。我们道路的名字象征着文化、价值观和历史。我们以传说、名人和历史事件来命名街道。

然而,街道名称的定量数据来源和实证分析探讨较少。在分析社区、城市和地区的街道名称时,大数据分析和数据可视化可以揭示什么?他们能表现出多大的性别失衡?宗教狂热和街道名称呢?我们的道路比街道多吗?车道、大道或车道呢?最著名的书名有哪些?

为了深入了解这些问题,我分析了英国 200 多万条街道的名称。Github 上提供了数据的代码和预处理。我将在这里揭示通过数据可视化分析得出的四个最重要的见解。

1.最受欢迎的街道名称——高街 vs 车站路

在 2,323,627 个街道名称中,“高街”是最受欢迎的名称,出现频率为 16593 次,其次是“车站路”和“主街道”,分别有 11521 个和 7623 个条目。下图显示了英国 30 个最常见的街道名称。

也可以深入挖掘,找到每个区最常见的街道名称。例如,诺里奇的“迪尔罕路”是最常见的名称,而伊普斯威奇的“纳克顿路”是最常见的名称。另一方面,我们可以在更高的级别上进行汇总,以找出最著名的街道名称:

英国——“高街”

苏格兰——“主街”

威尔士“高街”

2.后缀—道路与车道

不同城市的名字后缀差别很大。尽管有一些通用的标准将后缀分类为道路、小巷或街道。通过对数据的一点点预处理,我们还可以找到最流行的后缀。下图显示了街道名称中最常用的 20 个后缀。

“道路”后缀占主导地位(775,537),其次是小巷和街道,分别有 238726 和 213881 个频率。我们可以看看这些名字在地理上是如何分布的。这里,我们汇总了每个城市的所有后缀,并取每个城市中出现频率最高的街道后缀名称。结果很能说明问题。

这张地图显示了所有地区用作后缀的“道路”的数量。事实上,只有 18 个区的「路」字尾不在最前面。这是所有 18 个地区的名称和最常用的后缀。

3.街道名称中的性别失衡

街道名称也能让我们描绘出性别失衡的地图。性别方面是一个独特的机会,因为在城市一级往往很难找到性别不平衡的指标。

为了将名字按性别分类,我使用了性别化服务,它允许你每天自由地对 1000 个名字进行编码和性别化。我数了每个名字及其出现的次数,根据它们的出现次数进行了分类,并取了前 1000 个。根据出现的总次数来选择最著名的名字是有好处的。虽然数据集中有 99,088 个独特的街道名称,但通过对前 1000 个进行性别区分,我们覆盖了几乎 50%的数据集。然而,这也有它的缺点,因为它留下不太有名的名字,可能会给出不同的结果。

最常用的 1000 个街道名称的性别分类

上图显示了街道名称中明显的性别不平衡。大多数流行的街道名称都是以男性分类名称命名的。

为了更深入的理解,也由于性别化 API 的限制,我选择了利物浦市并对其所有街道名称进行了分类。这是一张有性别分类百分比的地图。

利物浦的调查结果也清楚地指出了街道名称中的性别不平衡。看看其他城市并找出结果将会很有趣。

4.虔诚

街道名称有多大的宗教影响?我们能量化它们吗?为了找到答案,我们可以假设有强烈宗教倾向的社区倾向于用宗教名称来命名更多的地方。

使用 Oto‐Peralias 方法,我们可以按如下方式衡量一个城市的宗教程度:

Religiosity = R / N x 100

其中,分子 R 是城镇中包含下列宗教名称的街道数量。

Church, Chapel, Augustine, Bethlehem, St., St. John’s, Mary’s, Jerusalem, Palestine, Jesus, Christian, Father, Trinity, Babylon, Bethel, Presbyterian, Baptist, Gospel, Hell, Paradise, Jericho, Nazareth, Nimrod, Ninevah, Ophir, Patmos, Zion, Antioch, Canaan, & Heaven.

虽然搜索的术语不是所有宗教名称的综合列表,但它是迄今为止使用最广泛的街道名称。

分母 N 包含每个城市的街道总数。

分析结果如下图所示。

宗教街道名称的比例较高,主要出现在英格兰,尤其是东部地区。在城市中,锡利岛和萨福克中部的宗教街道名称比例最高。

结论

街道名称是定量数据分析的一个很好的来源,可以揭示许多关于社区及其历史的信息。这是一个尚未开发的数据源,在本文中,我们只是触及了皮毛。

本文使用的数据来自法令调查,可从此处访问。

关于过度拟合,博尔赫斯能教你什么?

原文:https://towardsdatascience.com/what-can-borges-teach-you-about-overfitting-e5ac2dd21217?source=collection_archive---------63-----------------------

豪尔赫·路易斯·博尔赫斯(1899–1986)是一位才华横溢的作家,也是有史以来最有影响力的作家之一。但是博尔赫斯能教你什么是过度拟合呢?

Funes 纪念馆

博尔赫斯在 1954 年写了《纪念的 Funes》(原名《纪念的 Funes el memorioso》)。这个故事诞生于作者失眠之后。这个故事讲述了患有健忘症的 Ireneo Funes 的故事。在一次骑马事故后,富内斯发现他可以记住几乎所有的事情:一天中每时每刻云的形状,房子每个角落灯光的位置,两个月前他每分钟都做了什么,等等。

公共领域下的博尔赫斯形象。

在这个故事中,博尔赫斯探讨了关于我们生活中需要“遗忘的艺术”的几个方面的各种主题。通过完全记住每件事,Funes 失去了思维过程中最重要的特征之一:概括。Funes 不能理解为什么“狗”这个词可以把每只狗归为一类,如果它们明显不同的话。他可以很容易地区分眼睛发亮的小黑狗和左眼有红点的小黑狗,但他不明白是什么让狗成为狗。

过度拟合或泛化能力的丧失

健忘症与其说是礼物,不如说是不幸。没有概括就不可能使用抽象思维。而且没有抽象思维,Funes 更接近机器而不是人。他进入了我们期望从机器学习中获得的相反方向。

过度拟合 对于机器学习来说,就像健忘症对于 Funes 一样。过度拟合的模型无法区分噪声观测和基础模型。这是,他们不能一概而论。

下图显示了两个二元分类器(黑线和绿线)。过度拟合的分类器(绿线)非常依赖于训练数据,当新的观测值到达时,它很可能表现不佳。

Ignacio Icke维基百科的知识共享下

我如何知道我有一个过度拟合的模型?
当您观察到训练集中的性能比测试集中的性能好得多时。

那么,如何防止过度拟合呢?

  • 考虑足够大的数据集。如果你的数据集太小,你的模型会简单地记住所有的规则。
  • 交叉验证时刻牢记。
  • 正规化总是有帮助的。
  • 模型的集合有助于归纳。
  • 提前停车。迭代算法(CNN,DNN,RNN 等。)苦于局部极小问题。按时停车能给你更好的效果。

希望你会考虑读 Funes the memorious 或任何博尔赫斯的故事。希望,当你找到下一个过度装配的模型时,你会想到有趣的事。

最初发布于:https://jmtirado . net/what-can-Borges-teach-you-about-over fitting/

新冠肺炎预测者能从帕斯卡的赌注中学到什么

原文:https://towardsdatascience.com/what-can-covid-19-forecasters-learn-from-pascals-wager-acb010f347e0?source=collection_archive---------46-----------------------

在本文中,我们分析了一个锁定了一个国家的预测,并展示了在建模中犯小错误导致结果中的大问题是多么容易。

来源:Adobe Stock

在此分析中,我们将验证重症监护病房(ICU)的峰值负荷预测。这一预测是由国家卫生官员做出的。这种预测在时间有限的政策决策中发挥着突出的作用,这些决策试图在完全的社会瘫痪和不必要的生命损失之间取得平衡。对每一个参数值、模型和图形的仔细检查是最重要的。只有通过审查,才能根据数据和建模做出合理的决策。

我们将以芬兰卫生当局——THL——和他们的 ICU 高峰负荷预测为例。文章中的所有内容都可以应用于其他类似的预测。

我们已经使所有的发现,材料和代码允许直接复制的结果可用。你可以在文章末尾找到链接。

在这份报告中,我们得出以下结论:

  • 当我们修正 THL 的模型参数以符合经验证据时,否则保持模型原样,我们发现在公布的预测中有 45%的误差
  • THL 的模型假设了一条明显落后于经验时间序列数据的曲线
  • THL 的模型是基于每 23 天的指数增长,根据证据,增长率接近 10 天
  • 为了重现 THL 的预测,我们使用了蒙特卡罗模拟,找到了有限的几种可能的情况

经验证据、可比方法和 THL 模型假设中的明显误差表明,预测的 ICU 高峰负荷实际上是不可能实现的。尽管在本报告中,我们没有提出替代预测,但我们得出结论,使用我们公布的方法[ 1 ],很容易观察到更高的 ICU 高峰负荷是可能的。足以引出一个重要的问题。

较高的数字会如何改变基于较低的数字已经做出的决定?

我们所做的模拟是基于蒙特卡罗方法,即使没有受过正规统计训练的人也很容易理解。使用更简单的版本[ 2 ],我们通过改变 doubles_in_days、max _ patient _ capacity、case _ deactivity _ rate输入参数,经历了大量可能的情况。我们已经用一个更精细的[ 3 ]验证了结果,该模拟器也是基于蒙特卡罗的,允许更多的输入参数,并将标准 ICU 负荷与通气 ICU 负荷分开。

在一个为期 20 天的模拟中,我们发现大约一半的可能情况以生命损失告终,因为对 ICU 的需求超过了能力。

模拟的详细结果超出了本文的范围,我们将在两周内以另一篇文章的形式发布。

什么是好的数据驱动决策?

有许多方法可以利用现有的信息来支持决策;基于基于当前理解(理论)和基于直觉的数据。基于数据的决策可以基于最近的事件或历史趋势。当我们使用数据时,无论是历史数据还是当前数据,我们的目标都是利用这些数据来预测未来。当理论、直觉和数据都说同样的事情时,它可以给预测或发现带来可信度。该发现必须是可重复的;否则,它必须被视为一个错误。即使该发现在其他方面符合可信度的标准,除非它可以被复制,否则只能保证低可信度

然而,我们必须记住,即使一个发现是可信的,也不意味着我们可以预测未来。我们可以尝试,有时我们会做得很好,但我们永远不能用历史来预测未来。唯一可以用来预测未来的工具当然是“一个有效的推论”,一个用在哲学中的工具。例如,我们当然可以说,只要有燃烧,就会有一些热量。但是作为数据科学家,我们没有那种奢侈。我们总是研究概率和分布。从不确定。这是我们工作领域中一个微妙但非常重要的点。

帕斯卡的赌注

来源:维基媒体

概率方法之父布莱士·帕斯卡发展了统计学来回答上帝是否存在的问题。在研究这个问题多年后,帕斯卡最终得出结论,即使上帝存在的可能性非常小,人们也不应该冒险过着不真实的生活。这被称为“帕斯卡赌注”,这是应用概率方法的一个关键原则。特别是在介绍我们工作结果的责任方面。“帕斯卡赌注”适用于所有至关重要的预测,例如人类生命的损失是预测错误的结果。一种有意义的呈现发现的方式是在概率和与方法相关的警告之间保持平衡。但尤其是在演示阶段。

经验证据的重要性

建模必须以经验证据为基础。关于新冠肺炎,在许多领域,我们的情况是,现有数据描绘了一幅有意义的问题图。下面我们总结了本报告中使用的可用证据,这些证据有助于建立 ICU 峰值负荷模型。所有数字都基于芬兰现有的最新数据。大多数国家都提供类似的数据。

这种病毒有多常见?
所有检测病例中大约有 6%呈阳性。

有多少检测呈阳性的人需要住院治疗? 超过 10%的检测呈阳性者需要住院治疗。

有多少住院病人需要重症监护?大约 40%的住院病人需要重症监护。

ICU 中有多少人需要通气?
根据现有文献,我们估计它在 55%[ 4 ]和 65%[ 5 ]之间

ICU 停留时间有多长? 根据来源不同,我们估计平均持续时间在 7-12[6][7]天之间。我们注意到,较低的数字可能是由于能力问题导致死亡率上升。我们发现,在流感患者中,ICU 停留的平均时间为 12 天。

目前有多少 ICU 病人?
截至 2020 年 4 月 6 日,有 81 名 ICU 患者。

目前 ICU 负担的增长因素是什么? 每周大致 50%。

批判性地评估已经做出的预测

THL 提出,ICU 负担高峰将少于 300 人。峰值预计出现在曲线的第 9 周。包括总理在内的芬兰政治家一再提到 THL 的预测推动了各种措施,如社会距离。THL 的模型以大约 60 名 ICU 患者为起点,并以几乎四周的速度翻倍。

资料来源:Yle

基于 3 月至 4 月间 ICU 患者数量的经验倍增率大约是这个数字的一半。换句话说,实际增长大约是 THL 预测的两倍。

即使生长因子中相对较小的误差也会对结果产生显著的影响。THL 的模型假设周增长率为 1.2 倍。如果增长率是 1.3 倍,预测的相对准确性是 91.7%,但绝对 ICU 负担几乎翻倍。1.4 倍的周增长率(相对准确性仅相差 15%)导致超过 3 倍的绝对峰值负载。

THL 模型中的另一个重要假设是住院和重症监护需求之间的关系。例如,在曲线的第二周,THL 预测有 283 人住院,其中 88 人需要重症监护。这意味着 THL 假定有 31%的重症监护室率。根据现有数据,芬兰的实际失业率为 39%,比 THL 的假设高出 21%。从经验数据来看,这种程度的偏差可以认为是重要的。此外,THL 解释说,该模型假设重症监护室平均停留时间为 8 天。根据现有的文献,这可能是十天左右。根据历史患者记录,ICU 平均住院时间为 8.5 天,但流感患者的平均住院时间为 10.5 天[ 11 ]。因此,我们发现 THL 的预测有 20%的额外误差。

结合基本假设偏离经验数据的方式所产生的误差,我们不得不假设,基于 THL 的模型,峰值负担将是 406 而不是 280。我们发现,虽然模型本身可能是有用的,但目前公布的预测包含一个重要的错误。这个 45%的误差是假设没有其他偏差可以识别,即,这不包括模型中的任何其他问题。简而言之,当我们修正 THL 模型中的输入参数以遵循经验证据时,基于该模型发布的预测包含了一个重要的错误。

我们还发现,当比较 THL 的模型与几个可用的模型,明显较高的峰值负荷值是突出的。

重要的是要明白,偏离事实是可能的;世界上还没有人清楚地了解新冠肺炎预测问题。十年来,在超过 60,000 名 ICU 住院患者中,我们发现 187 例出现了流感和肺炎患者。目前,许多医院一天要处理更多的病例,显然我们都在探索新的领域。这使得建模和预测非常困难,并突出了利用经验数据的时间序列预测和影响输入参数范围的经验数据的蒙特卡罗模拟等方法的重要性。这一点,以及与金融科技(fintech)和广告科技(adtech)等相关领域的密切合作。

骑在虎背上,小心行事

正如帕斯卡的赌注所规定的,模型的输出应该根据一个错误决策能造成多大的损失来评估。例如,如果肺癌被错误地诊断为阴性,患者的生存几率就会急剧下降。类似地,如果对 ICU 容量的需求被错误地预测为低于实际需求,患者存活的几率就会大幅下降。对于新冠肺炎患者和所有在高峰容量期间需要重症监护的患者来说都是如此。由于重症监护的结构是在生命无法维持的情况下维持生命,可以有把握地认为,一旦需要重症监护的病人被拒绝,该病人存活的机会就降到了零。

使用的方法

检验声明的最佳方式是使用各种不同的方法重现它。使用下面强调的方法,我们试图重现 THL 的预测,但失败了。只有当我们偏离经验上合理的输入参数时,我们才能始终如一地实现它。

  • 文献评论
  • 审查公开可用的模型
  • ICU 住院数据的定量分析
  • 可用经验数据的回归分析

我们制作了所有的发现、材料和代码,允许通过https://autonom.io/icu_burden直接复制结果,并鼓励所有研究人员在工作中做同样的事情。

你能以同样的方式仔细检查你国家的官方预测吗?还是我们在这篇文章中提出的主张?审视是推动知识前进的力量。做吧,去仔细检查。

编者注: 走向数据科学 是一份以研究数据科学和机器学习为主的中型刊物。我们不是健康专家,这篇文章的观点不应被解释为专业建议。

数据科学家能从点击流和尾气数据中学到什么?

原文:https://towardsdatascience.com/what-can-data-scientists-learn-from-exhaust-data-some-lessons-and-tips-from-industry-e212cac8795?source=collection_archive---------65-----------------------

不是你做什么,而是你做的方式

排气数据从来没有这么干净

最近一直在想尾气数据到底有多有用,想分享一些想法。下面,我列出了什么是尾气数据,一些例子,它如何可以增加大量的价值,以及一些实用的建议,数据科学家如何使用它。

排气数据

什么是尾气数据,我为什么要关心?

任何一家有网络足迹的公司都会有大量的数据堆积在某个地方的数据存储中。尾气数据是用户活动的副产品。它不包括“主要”或“核心”数据,如用户保存的登录详细信息或交易历史,但包括用户与您的数字产品互动时产生的所有数据。

例如,我曾经在交通应用程序 Citymapper 担任数据科学家。你可以使用该应用程序获取公交路线,还可以使用名为 Pass 的订阅票务产品来支付旅程费用。比方说,你想从家里旅行到你最喜欢的共产主义独裁者主题披萨和鸡尾酒吧(当然是在 Covid 之前)。你可以打开应用程序,输入地址,浏览一些交通选项,选择一个,按照指示,用你的通行证支付旅程费用。关于交易的数据将被记录,并被算作核心数据,因为付费交易是业务功能的核心。

一个获取 Citymapper 公交路线的例子,它产生尾气数据。来源: The Verge

你在应用程序中所做的所有其他事情的事件日志也会被记录下来——包括你输入的起始和结束地址,你显示的选项,你点击的选项,你最后选择的选项是什么;如果你使用逐步路线指南(“Go 模式”),你的 GPS 位置也会每 10 秒钟被记录一次。所有这些都是无用的数据。类似地,电子商务网站的穷尽数据将包括点击流数据——包括你点击的每个产品、你在每个页面停留的时间、你查看了每个页面的哪些部分以及你采取了什么行动。

尾气数据大。非常大。它经常需要应用规则来阻止它变得更大。在 Citymapper 示例中,我们可以在 Go 模式下每秒记录一次用户位置,而不是每 10 秒记录一次,但这样我们将拥有 10 倍的数据,而不一定会获得 10 倍的价值。它也可能很乱,很难处理;尤其是在将其提炼为更容易理解的内容方面,以及在能够及时访问您需要的数据而不会挂在笔记本上或爆炸的方面。

给垃圾数据的情书

Exhaust 数据通常是一大堆庞大、复杂、微妙且极不性感的数据,这在试图从中获得任何洞察力时都会带来重大挑战。这也是关于用户行为的奇妙的、迷人的、最惊人的信息来源。由于使用它的内在困难,它经常得不到充分利用,因此它可能是一个组织尚未开发的巨大价值来源。

排气数据非常有用,因为它不仅告诉我们一个人做了什么,还告诉我们如何做的(甚至可能告诉我们为什么做)。

在我攻读博士学位期间,在统计学和数据科学应用于人类进化考古学这一非常模糊的领域,我第一次意识到作为核心活动副产品产生的大量杂乱数据有多么重要。直到现在回顾我的博士论文,受益于在现实世界中使用数据科学的几年,我才意识到我的整个博士论文都是关于尾气数据的重要性。

在我的领域中,以前的工作往往侧重于最终产品的数据,在我的例子中是石器,但在我上面的例子中,这可能是交通预订卡或电子商务网站上的最终交易。但是通过观察尾气数据,我能够了解到更多关于人类行为的信息。在我的博士学位中,废气数据实际上是垃圾数据,因为它来自于对石头碎片的测量,这些石头碎片是制造箭头的副产品。但在商业环境中,这可能是记录用户在选择旅程路线之前在应用程序上的每次点击的事件日志,或者是用户在最终购买之前在电子商务网站上查看的一系列产品。

排气数据非常有用,因为它不仅能告诉我们一个人做了什么,还能告诉我们他们是如何做的。因此,我写这篇博客是为了向 exhaust data 致敬。

石器和统计学

关于人类行为,石器能告诉我们什么?

我在 2015 年完成了牛津大学考古系的博士学位。我对人类行为的进化很感兴趣,特别是当我们开始以可识别的“人类”方式行事时,以及我们的物种是如何在世界各地传播的。骨头和石头通常是我感兴趣的那个时代仅存的东西,所以我试图通过观察石器技术来回答这些问题。

传统上,旧石器时代或石器时代的考古学家会看一些来自两个不同地区的箭头,决定它们看起来有点相似,然后去写一篇关于同一群人如何生活在这两个地区的论文。事实上,这正是以前占主导地位的关于我们物种在世界各地扩散的理论是如何诞生的。这个理论是基于一种叫做细石器的石器技术的出现。顾名思义,细石器是非常小的石头工具——像箭头、矛边的石倒钩、鱼钩和非常小的刀片。

大约 9000 年前重建的瑞典细石器。资料来源:Larsson 等人 (2017 年),载于《隆德考古评论》第 22 期。

我们在大约 7 万年前的南部非洲、大约 5 万年前的东非和大约 4 万年前的南亚发现了类似的石器。因此,该理论认为,早期现代人类一定是在大约 50,000 年前离开非洲,带着他们的箭头传播到世界各地。早期现代人类发展的故事被简化成一张地图,上面画着一个大箭头,上面写着“人类往这边走”;这是一个人类跟随这支大箭从非洲到亚洲甚至更远的地方的故事,沿途丢下像面包屑一样的箭头。

我在南非(A 和 B)和斯里兰卡(C)拍摄的细石器。资料来源: Lewis 等人(2014)在《第四纪国际》第 350 期

输入考古排气数据

我有一个不同的想法——当时是异端,现在被广泛接受,是许多论文和会议的主题。我的想法是,与其看着一些箭头,决定它们看起来相似然后就此结束,我们应该超越完成的工具本身。石器是一个漫长的过程的最终结果,用正确的方式,正确的角度和正确的力量将石头敲打在一起,创造出你想要的工具。在制作你可爱的小箭头的过程中,你最终会得到一大堆你不在乎的粉碎的石头——或者借用一个花哨的考古学术语(所有最好的考古学术语都是法语)。

然后,几千年后,一个穿着难看的米色裤子戴着傻帽的考古学家出现了,发现了你的借条。她很高兴找到你的岩石碎片,因为现在她不仅能知道你做了什么,还能知道 T2 是怎么做的。如果最终的石器是你的核心数据,这些剩余的岩石就是你的耗尽数据。

我上辈子是一名考古学家,戴着一顶傻帽,非常高兴在西班牙阿塔普尔卡发现岩石碎片。

借记可以告诉你一大堆关于一个工具是如何制造的。你可以了解一个人选择了什么样的石头,他们如何拿着它,他们如何击打它,他们用什么击打它,他们的技术是什么,他们是否换了锤子,他们是否放下它然后再回来,他们是否用同一块石头制作了其他工具,他们在制作这个工具时最关心什么,以及他们行为的许多其他方面。有时你甚至可以像拼图游戏一样把整个核心重新拼在一起,重建整个过程(有时是真的——我的一个朋友过去常常在他所在系的桌子上留下一堆借条,以便无聊的本科生偶尔会停下来把碎片拼在一起),有时会有缺口,但总会有有用的行为见解闪现出来。

当然,找到一个箭头可能会告诉你人们在制造箭头。但是确切地知道它是如何制作的可以告诉你更多关于制作它的人的行为,以及他们的文化和传统。重要的是,在我的研究背景下,它可以告诉我是相同的人以相同的方式制造相同的工具,还是不同的人以不同的方式制造相同的工具。在生物学中,这被称为趋同进化,即两个物种分别进化出相同的特征,因为它们正在应对相同的环境挑战,即使它们从未见过面交换过信息。例如,鲨鱼和海豚都是聪明的海洋生物,它们捕食鱼类,有着相似的鳍——但一个是鱼,一个是哺乳动物,它们已经分别进化了大约 3 亿年。

对于数据科学来说,重要的一点是,尽管结果是相同的,但只有通过查看与他们实现目标的过程相关的数据,而不仅仅是最终结果,才能发现不同的人在做不同的事情。

输入统计数据

跳到最后,在花了几个月时间在世界各地测量石器及其相关的石器,并应用各种统计技术和模型来寻找数据中的模式后,趋同进化正是我所发现的。南非和莱索托的人们制造的工具与印度和斯里兰卡的非常相似。但是他们这样做的方式非常不同,可能是出于不同的原因——例如,在斯里兰卡的雨林中猎杀猴子,在南非大草原上猎杀羚羊。

对于数据科学来说,重要的一点是,尽管结果是相同的,但只有通过查看与他们实现目标的过程相关的数据,而不仅仅是最终结果,才能发现不同的人在做不同的事情。现在,我是一名在工业界工作的数据科学家,而不是学术界的一个模糊角落,我意识到这是一个非常重要的教训,有助于更普遍地思考一个组织的数据。

这一切和现实世界中的尾气数据有什么关系?

将同样的方法应用于商业数据

公司和其他组织可以使用完全相同的方法从他们存储的关于客户的尾气数据中提取价值和确定洞察力。也许你和我都去了同一个电子商务网站,买了一本关于我博士研究的书(尽管我非常怀疑——它非常小众)。单看核心数据,我们会显示相同的内容,因为我们在网站上的最终交易是购买同一本书。

但也许你直接去了网站,输入了书名,去了产品页面,买了就离开了网站。与此同时,也许我去了网站的图书区,看了很多不同的产品页面,在每个页面上花了更长的时间,读了所有的评论,被一个夜光弹珠跑吸引了一下,然后回来看这本书,最后买了下来。也许这两个过程都很能代表我们的购物和浏览习惯。我们是不同类型的顾客,有着不同的购物习惯,尽管最终购买的是同一件商品。正如上面我谈到的不同的人以不同的方式制造相同的工具,我们是不同的人以不同的方式购买相同的产品。

从排气数据中获取价值的实用建议

通过查看这样的尾气数据,你可能会获得各种有用的见解。例如:

  • 这些习惯可能代表了更广泛的购物者类别,因此某种针对客户细分的(一种无监督的机器学习)可能会帮助你更好地了解你的客户——也许是通过一些有效的 数据,即 。它还可以帮助你的营销部门创建用户角色。
  • 或者,他们可以让你帮助产品管理人员弄清楚不同的用户群需要什么,以及哪些功能应该优先考虑。例如,在我上面的例子中,我可能会花很多时间在不同的产品页面上,因为我很难发现我到底对哪些产品感兴趣——所以某种形式的产品 推荐系统 可能是合适的,或者是对现有系统的改进。
  • 相反,在上面的例子中,你可能只使用该网站购买其他人已经推荐给你的特定东西(也许我在酒吧告诉你我的书,你答应买它以阻止我谈论考古学)。这很好,但也许网站上还有其他你可能喜欢但你还不知道的项目。数据科学家可能想尝试一些 AB 测试 来试验网站上的不同页面,看看对布局或内容进行一些改变是否能鼓励客户在网站上花更长时间,并查看他们可能喜欢的其他产品。

摘要

花时间清理、理解、提取和分析尾气数据对一家公司来说非常有价值。它可以帮助你在更精细的层次上理解你的客户——不仅仅是他们用你的产品做什么,而是他们到底是怎么做的。当数据科学直接帮助客户时,它处于最佳状态。即使处理大量数据可能会有点累(抱歉),但考虑客户的所有数据是真正了解他们行为的好方法,可以为他们提供最好的产品。

数据可视化在对抗新型冠状病毒的战斗中有什么帮助?

原文:https://towardsdatascience.com/what-can-data-visualization-help-in-the-battle-against-the-novel-coronavirus-bad9b2c7fb2b?source=collection_archive---------32-----------------------

我设计了五个场景的仪表盘,帮助监控冠状病毒爆发的情况,开展防控工作。

这种新型冠状病毒(现在正式命名为新冠肺炎)首次在中国武汉市发现,在过去的六周内,已经感染了 59,000 多名中国公民,并导致 1,000 多人死亡。

除了加快病毒疫苗研究和加强人员流动管理外,人员信息的及时收集、传递和管理也成为这场对抗病毒战役中至关重要的一环。在社会的各个方面都有巨大的挑战:商业和学校的恢复,医院治疗,社区管理…

为此,我已经利用数据可视化的知识,设计了五种场景的仪表盘模板,希望能够帮助相关机构或企业有效监测疫情,开展防控工作。

现在,让我向您展示这些不同类型的仪表板,并解释数据可视化可以在对抗冠状病毒的战斗中提供什么帮助。

1.冠状病毒爆发的实时监控

疫情数据不断更新。我们可能需要寻找各种新闻或信息渠道来获取最新数据。这时候一个实时监控仪表盘就可以整合最全面的疫情分析,实时更新数据,供大家查阅。

1.1 冠状病毒爆发分析仪表板

这个仪表板整合了核心数据,直观地显示了新型冠状病毒的确诊、疑似、死亡和治愈病例。从地域维度分析感染分布,从时间维度分析感染趋势。此外,仪表板上的地图可以从一个省到另一个城市进行深入查看。还有一部分展示了关于病毒的谣言和真相。

我用来制作所有这些仪表板的工具是 BI 报告和仪表板软件 FineReport 。这个工具是由我工作的数据研究所开发的。个人使用完全免费。可以 下载 练习制作报表和仪表盘。

这些仪表板主要用于分析中国冠状病毒爆发的情况,并为防控工作做出贡献。所以最初仪表板上的所有文字都是中文的。为了让大家更容易理解,我用了网页上的谷歌翻译功能把中文翻译成英文,但可能会有一些错误。

1.2 人口迁移分析仪表板

此次疫情爆发恰逢中国最重要的节日春节。政府延长了假期,但全社会仍需投入生产。中国预计下周将有大约 1.6 亿员工重返工作岗位。必须采取行动,在大规模人员流动中降低传播风险。所以我们需要一个仪表板来分析全国的人口迁移。下面的仪表板提供了全国范围内进出移民的每日数据分析以及每个地区进出移民的趋势,以帮助每个人了解其当前位置或目标区域的风险情况。

2.企业恢复管理

2.1 远程办公分析仪表板

在各地延期返工的情况下,很多中国企业选择了让员工在家远程办公。此时,他们可能需要一个远程办公分析仪表板,以提高冠状病毒爆发期间的工作效率,并了解员工的出勤情况。

2.2 员工差旅统计仪表板

员工从家乡回到工作场所,都避免不了接触更多的人。为了对自己和同事负责,春节期间员工的出行情况需要公开透明,以便及时发现潜在的隐患,保证公司工作环境的绝对安全。

2.3 移动数据输入模板—员工信息

为了更好的收集信息,我还做了一些手机数据录入模板。员工可在手机(或 PC)上随时点击链接填报。这些信息将立即输入数据库,并连接到上述仪表板。因此数据是实时显示的。

本文中所有的移动数据录入模板也是用数据可视化工具【FineReport】制作的。

3.医院管理

3.1 医疗用品监控仪表板

由于病毒,口罩和酒精等医疗用品一度成为硬通货。对于医院等一些企业来说,材料来源和收据信息的不透明也会造成不必要的误解。因此,医疗用品监控仪表板将非常有助于实时监控当前的材料库存和接收详情。

3.2 医院疫情监控仪表板

医院需要比国家或城市更细致的疫情监测。于是我设计了医院疫情监控仪表盘,根据医院上报的实时数据来显示医院的情况。它综合分析了各个科室的分布情况,每个症状,以及不同层次的患者人数趋势。

3.3 防控形势分析仪表板

从确诊病例分布、流行趋势、风险监测等维度,全面分析医院对冠状病毒疫情的防控工作。

3.4 移动数据输入模板—医院信息

移动数据输入为上述仪表板提供了数据基础。另外,每个人都可以在手机上随时填写报告。这种非面对面的信息采集形式,大大提高了环境危险的医院的安全性。

4.学校管理

4.1 返校学生分析仪表板

虽然很多学校都推迟了开学时间,但仍有部分学生提前返校,而且这个数字还会随着时间的推移而增加。迫切需要对归国留学生的信息进行分析。

4.2 学生健康监测仪表板

随着教育资源的日益共享,学校学生来自不同地区的情况不仅限于大学,因此在校学生更容易接触不同地区的人。学生健康的日常监测不容忽视。

5.社区管理

5.1 社区访问分析仪表板

社区作为生活场景中联系最紧密的群体,人们进出社区的潜在风险也影响着生活在社区中的人们。尤其是对易受新型冠状病毒侵害的老年人群,在企业、学校接触不会太多,但对社区疫情防控情况有直接影响。

5.2 移动数据输入模板—社区信息

以下是出入境登记表。移动数据录入可以最大限度减少与陌生人接触的机会,减少感染,在保证安全的情况下有效收集信息。

最后

冠状病毒疫情信息的收集、处理和实时显示是社会防控工作的重要组成部分。数据可视化有助于我们根据实时情况快速做出决策,避免滞后信息带来的损失风险。

如果你有这方面的需求,可以在 LinkedIn 上联系我,我很乐意免费分享这些仪表盘模板。相信有了科学的防控措施,一定能早日战胜冠状病毒!

[## Lewis Chou -区域经理- FineReport 报告软件| LinkedIn

查看世界上最大的职业社区 LinkedIn 上的 Lewis Chou 的个人资料。刘易斯有 3 份工作列在他们的…

www.linkedin.com](https://www.linkedin.com/in/lewis-chou-a54585181/)

您可能也会对…感兴趣

[## 2019 年你不能错过的 9 个数据可视化工具

在数据科学领域,数据可视化无疑是当今的热门词汇。

towardsdatascience.com](/9-data-visualization-tools-that-you-cannot-miss-in-2019-3ff23222a927) [## 制作销售仪表板的分步指南

我已经写了一些关于业务仪表板数据可视化的入门指南,但是那些文章仍然是一个…

towardsdatascience.com](/a-step-by-step-guide-to-making-sales-dashboards-34c999cfc28b) [## 让您的数据报告脱颖而出的指南

当数据报告由杂乱无章的数字组成时,我们无法想象技术已经发生了革命性的变化…

towardsdatascience.com](/a-guide-to-making-your-data-reporting-stand-out-cccd3b99e293)

我可以用 WhatsApp 做什么?

原文:https://towardsdatascience.com/what-can-i-do-with-whatsapp-661fc3cdd5c5?source=collection_archive---------34-----------------------

分析你的朋友。

构建一个词云,用 Python 运行情感分析。

WhatsApp 有“导出聊天”功能。你可以用这些数据做一些有趣的事情。这篇文章将带你构建一个单词云,以及一些情感分析。

来自 WhatsApp 聊天的单词云,按频率显示单词大小。

不久前,我试图消除生活中的消极因素。一方面是我的消极朋友。这可不行。我需要一种科学的方法来一劳永逸地证明我的朋友比我更消极。使用 Whatsapp、Python 和 NTLK 情感库,我创建了以下图表:

最后,我证明了我是同龄人中最优秀的。在本教程结束时,您将能够:

  • 导出 Whatsapp 数据
  • 将其转换成语言可读的格式
  • 分析数据
  • 统计单词的频率
  • 构建单词云
  • 执行情感分析

可访问性和隐私

我将尽可能使用非技术工具,努力让这一点变得容易理解。您将需要 Python 和 Pip 的知识,尽管我将深入研究一些基于 Excel 的解决方案。

WhatsApp 聊天中发送的每条消息和文件都可以被该聊天的成员访问并导出。这些加密的数据仍然对聊天中的人有意义。在你这样做之前,联系你聊天的其他成员,看看他们对你的分析是否满意。

导出 WhatsApp 聊天

  1. 导航到 WhatsApp 聊天。
  2. 单击“更多按钮”。
  3. 点击“导出聊天”。
  4. 选择“无媒体”
  5. 选择你想分享的地方,我推荐 Google Drive。

数据格式

此导出是一个. txt 文件。该文件有几种不同的格式:

  • 用户消息:“2019 年 2 月 21 日,上午 9 点 09 分——乔:嘿,伙计们,就是这里了”
  • 媒体遗漏:“19 年 6 月 1 日,下午 2 点 59 分——乔:<媒体遗漏>
  • WhatsApp 消息:“此消息已删除”

在这个阶段,我们不能处理这些数据,多种格式是没有用的。我们希望保留日期、时间、用户和消息内容。

工作表中的数据清理

  • 将整个文本文件内容粘贴到一个空的 Google 表单中。
  • 选择整个列“A”。
  • 在菜单中选择数据>分栏文本。
  • 将分隔符更改为每个名称后面的任何字符,在本例中为“:”。
  • 现在这两列是分开的,您可以删除 A 列和 B 列,只留下消息。
  • 复制这一整列。

建立一个单词云

此时,您已经有了原始的消息数据,并准备好粘贴到一个在线单词云构建器中。

  • 在菜单中单击文件>粘贴/键入文本
  • 随心所欲地改变颜色和形状选项

现在这里有几个问题:

  • 审查——有名字在里面,这带来了我们以前的隐私问题。您聊天中的一些单词脱离上下文可能看起来不太好。我们需要一个审查系统。
  • 媒体—“媒体省略”是我们最常用的短语,因为此文本替换了所有图像。这个需要去掉。
  • 重复单词——每个单词都可以是大写和小写。例如,“乔”和“乔”都出现了。

为了解决这些问题,我转向了 Python。

Python 中的数据清理

我已经修改了一个工具。txt 文件转换成格式化的. csv 文件。它需要 pip3 和 python3。这将转换此表单中的数据:

2/20/19, 10:14 PM - Messages to this group are now secured with end-to-end encryption. Tap for more info.
2/20/19, 10:14 PM - You created group "Example chat"
2/21/19, 9:09 AM - Joe: Wow what an amazing chat!
2/21/19, 9:10 AM - Dom: I agree, it is amazing!
2/21/19, 9:12 AM - Joe: You're the best!
2/21/19, 9:12 AM - Dom: No, you are the best!

收件人:

datetime|name|message|
2019-02-21 09:09| Joe|Wow what an amazing chat!
2019-02-21 09:10| Dom|I agree, it is amazing!
2019-02-21 09:12| Joe|You're the best!
2019-02-21 09:12| Dom|No, you are the best!

最后,我们还有停用词的问题。这些是被认为对信息内容不重要的常用词。想想像“和”、“要”、“我”这样的词。现在,这些在许多自然语言处理中被认为是重要的,但是它们导致了垃圾单词云。NLTK 可以帮助我们。

为了处理停用词和上面的进一步问题,我写了一个笔记本

现在我们有了以下内容:

情感分析

情感分析是自然语言处理的一个领域,专注于识别一段文本中的观点。使用 NLTK 库我们可以得到文本的阳性、阴性和中性。

积极的 1 分意味着它是完全积极的。0 分意味着它没有积极性。例如:

我喜欢乔,他超级酷

多好的一句话!这让我很开心,但这在数学上是正的吗?穿越 VADER,我们得到:

compound: 0.886, neg: 0.0, neu: 0.224, pos: 0.776

化合物是从 1 到-1 的分数,其中:

  • 1 是正数,
  • 0 是中性的,
  • -1 是负数。

想象一下,如果有人说:

哦,傻瓜,乔太逊了。真是个失败者!

多么刻薄的一句话,但是单词并不影响我,只有它们潜在的数学否定影响我!

compound: -0.8712, neg: 0.664, neu: 0.336, pos: 0.0

将情感分析应用于 WhatsApp

我写了一个笔记本概述了如何使用 Python 计算情绪。本笔记本概述了如何计算情绪,将其应用于我们的 CSV,并可视化每个人和一段时间内的情绪。

我们可以看看每个人的总情绪。

久而久之群体情绪。

和个人的情绪。

感谢阅读。如果您有任何进一步的问题,请随时在我的 GitHub 上打开问题。

我们能做些什么来帮助转化销售线索?

原文:https://towardsdatascience.com/what-can-we-do-to-help-convert-leads-8cbbcaee3e61?source=collection_archive---------40-----------------------

机器学习结果可视化简介

概述

这篇博客文章旨在展示对机器学习模型输出和各种输入变量之间关系的研究和解释,以此作为优化销售线索转化的起点。

商业背景方面,我们将了解一家名为 X 教育 的在线教育公司,该公司向行业专业人士出售在线课程。在资源有限的情况下,公司确定哪些用户更有可能转化为潜在客户非常重要。

我们将主要使用 R 来执行分析和可视化。

现场演示:https://jameschen4.shinyapps.io/leads/

作者图片:用 reactable 和 R shiny 构建的最终可视化截图

库(data.table)
库(caret)
库(xgboost)
库(pROC)
库(xgboostexplaner)
库(dplyr)
库(tidyr)
库(reactable)
库(htmltools)

数据

数据可在 Kaggle 上获得。这个数据集的一个好处是它附带了一个数据字典,解释了键列的含义。有 37 个变量和大约 10k 个记录。

作者图片:取自数据字典文件

预处理

已经有一个由 Ashish 用 Python 写的很好的 EDA 了。我们将直接从他那里获取干净的数据集,并专注于模拟和可视化部分。

作者图片:清理前的原始数据

作者图片:干净和预处理的数据

我们还将删除这些列,它们主要与销售线索相关:

  • 线索质量(相关性低,可能,不确定,最差)
  • 销售线索来源(登录页提交、销售线索添加表单、销售线索导入)
  • 线索来源(脸书,谷歌,Olark 聊天,有机搜索..等等)

培训

在这里,我们将使用 10 重交叉验证来训练 XGBoost 模型,其中目标变量是用户是否转化为潜在客户(0-否,1-是)。下面的代码直接取自大卫·福斯特

原来基线模型已经给出了很好的结果:AUC 0.9650633。

使用xgboosterplainer软件包,我们能够确定一些有助于销售线索转化的重要变量。

该软件包创建了一个瀑布图,可以帮助我们确定销售线索转化时最重要的促成因素。

对于下面的记录(取自测试集):

预测值:0.9630512

重量:3.260574

作者图片:单次预测的样本输出来自xgboostexplaner

在回顾了更多案例后,我们确定了可能有助于转化销售线索的 6 个变量:

  • 总计。花在网站上的时间
  • 最后。活动 _ 短信。发送/最后一次。值得注意的. Activity_SMS。送
  • tags _ will . revert . after . reading . the . email
  • 专业化 _ 其他 _ 专业化
  • Tags_Lost.to.EINS
  • 总访问量

模拟

这里的核心思想是,如果变量是独立的,我们可以玩不同的输入,看看预测将如何变化。

从 Ashish 的 EDA 中我们已经知道,不存在任何严重的共线性(通常当 VIF > 5 时):

来源:https://www . ka ggle . com/ashydv/lead-scoring-logistic-regression/notebook

数值变量

首先,我们将创建一个百分比列表和一个种子列表进行迭代。这里的百分比是指可能受到影响的用户群的百分比。例如,如果 perc = 0.2,这意味着我们将随机选择 20%的记录(同样,来自测试数据),并向总数添加 600 秒。time . spend . on . website 变量,而其他变量对于那 20%的记录保持不变。

这里的多样化播种只是为了确保模拟更加健壮。对于每次迭代,我们将取预测的中间值。请注意,在我们进行任何模拟之前,中值预测的基线约为 0.152。

按作者分类的图片:对每个变量的模拟,包括不同的用户群百分比和播种组合

一个附带说明是,尽管不存在严重的共线性,但当 TotalVisits = 0 时,Total。time . spend . on . website 也必须为 0。为了简单起见,我们暂时忽略这一点。

另一个注意事项是,这里我们只演示了连续变量的固定提升(例如,增加 600 秒),我们也可以尝试不同的组合。

单热变量

对于一次性变量,一种方法是首先将 0 和 1 分开,然后在 0(目标)上随机抽取一个百分比,并将其转换为 1,这意味着发送的短信成为这些选定记录的最后一项活动。

然后,我们对其余 4 个变量重复该过程,合计转换率如下:

作者图片:宽格式的汇总销售线索转化率模拟

可视化

在可视化之前,让我们也为最终数据添加更多细节:

作者图片:帮助可视化的附加信息

对于实际的可视化,我们将使用reactable包构建一个表格格式的热图——最佳部分?它与 R Shiny 兼容。**

****现场演示:https://jameschen4.shinyapps.io/leads/

作者图片:用 reactable 和 R shiny 构建的最终可视化截图

这一可视化背后的一些想法:

  • 向上和向下箭头图标用于说明增加/减少目标,这样更引人注目
  • 基线分类和数字只是当前测试数据的参考点(在任何模拟之前),将用于评估设置所述目标的可行性。例如,从 EINS 教育(一家竞争对手公司)收集 50%以上的用户可能不现实,因为当前的基线仅为 2%
  • 数字通常靠右对齐,文本靠左对齐。然而,由于我们只有少数几个数字,用%和#居中对齐看起来更好
  • 在销售线索模拟的第一列以及间接费用描述中强调 X=10% 以及 X%的用户…

接下来要问的高优先级问题:

  • 我们能做些什么来吸引 EINS 教育的用户?
  • EINS 教育采用了什么策略?
  • 为什么用户同时从美国和 EINS 购买?
  • 我们的电子邮件和短信营销活动是否成功——我们从哪里可以获得更多相关数据?
  • 为什么没有专业化的用户更不容易转化?是因为他们实际上没有,还是他们不想告诉我们这些信息?

最终想法

我们在这里关注的是目标(我们想要达到的目标),而不是我们正在采取的实际方法,因为它可能需要更深入的分析和在线教育领域的知识,才能提出可靠的优化计划(例如,研究为什么某些用户在网站上花费 2000 多秒——是因为某些内容吗?).

还要注意,在适当的设置中,应该有 A/B 测试来验证 XGBoost 模型揭示的相关性。但同样,这篇博客中的分析只应作为线索转化优化的起点,它是一个与不同利益相关者一起细化分析的迭代过程。

机器学习模型通常被认为是一个黑盒,社区也很清楚这一点(因此我们看到了 xgboostexplainer 和 shap 这样的包)。有时,即使是最简单的线性回归对其他人来说也很难理解——这就是模拟或基于灵敏度的分析可以增加价值的地方。还有其他的方法来进行这样的分析:

从变量 *A* *B* *C* *D* *A* *B* *C* (不触及 *D* )的值组合将目标值 *y* 增加 10,使 *A* *B* *C* 之和最小化。**

问问题?

jchen6912@gmail.com

你能用新的“熊猫”做什么?

原文:https://towardsdatascience.com/what-can-you-do-with-the-new-pandas-2d24cf8d8b4b?source=collection_archive---------19-----------------------

熊猫 1.0.0 版本出来了。这些更新不仅是 Python 社区期待已久的,也是整个数据科学社区期待已久的。在这篇文章中,我谈论了我认为在这个版本中很重要的 5 个主要变化。

欢迎发表评论,让我知道您认为重要的其他变化以及数据科学社区如何利用它们。

新熊猫【来源】

但是,熊猫是什么?

Pandas 是 Python 中数据分析使用最多的库。它的框架结构和方法使得来自所有起步背景的数据分析师更容易入门数据科学。这是一个灵活、强大且易于使用的工具。

我们开始吧,好吗?👌

a)使用 Numba 让熊猫跑得更快

什么是 Numba?它是一个开源的实时(JIT)编译器,将 Python 和 Numpy 代码翻译成更快的机器翻译代码。换句话说,它可以帮助在多个 CPU 内核上执行 Numpy 表达式。

apply() 函数可以通过将引擎关键字指定为‘Numba’来利用 Numba。这使得对大型数据集(100 万行或更大)执行函数变得更加容易。

对于此功能,Numba 库应该有版本 0.46.0 或更高版本。

**In [1]: data = pd.Series(range(1000))****In [2]: roll = data.rolling(10)****In [3]: %timeit -r 1 -n 1 roll.apply(lambda x: np.sum(x), engine='numba',  raw=True)** 1.15 s ± 0 ns per loop (mean ± std. dev. of 1 run, 1 loop each)**## Function is cached when you run the second time - so faster
In [4]: %timeit roll.apply(lambda x: np.sum(x), engine='numba', raw=True)** 368 ms ± 3.65 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

b)一种“专用”管柱类型

在以前版本的 Pandas 中,字符串存储在 object numpy 数组中。在新版本中,增加了一个专用于字符串数据的类型— StringDType。这解决了许多问题,例如:

  1. 它消除了包含字符串和非字符串的混合型数组的混乱
  2. 它帮助我们执行只针对字符串的函数。

为了使用这个功能,我们可以显式地将类型设置为string

**# Can also string type using `pd.StringDType()` 
In [1]: x = pd.Series(['name', None, 'class'], dtype='string')****In [2]: x** 0     name
1    <NA>
2     class
dtype: string

c)一个‘专用’布尔类型

在以前版本的 Pandas 中,布尔数组只能保存TrueFalse值。丢失的数据无法合并到这些数组中。现在创建了一个专门用于布尔类型的新类型— BooleanDType,它可以保存缺失值。已经为缺少的值创建了一个新的掩码。

这对于数据分析师来说很重要,因为他们总是在处理缺失值,使用这种类型会使数据集更加明确。

**# Can also string type using `pd.BooleanDType()` 
In [1]: x = pd.Series([True, None, False], dtype='boolean')****In [2]: x** 0     True
1    <NA>
2     False
dtype: boolean

d)处理 **parquet** 文件变得更加容易

对于那些一直在使用 PySpark 的人来说,有时数据分析师会在 Spark 中处理数据,并将其保存为一个 Parquet 文件。然后,他们喜欢在拼花地板上用熊猫来做不那么“繁重”的工作。但是如果 parquet 文件有一个用户定义的模式,Pandas 中以前的版本会抛出一个错误,指出它不能集成 Pandas 中的模式。

在新版本中,Pandas 处理用户定义模式的模式参数。schema现在与 pyarrow 引擎一起处理模式参数。

**In [1]:** import pyarrow as pa ## pyspark engine import**In [2]: x = pd.DataFrame({'a': list('abc'), 'b': list(range(1, 4))})****In [3]:** **schema = pa.schema([('a', pa.string()), ('b', pa.int64())])****# Can also be used for `read_parquet` as well
In [4]: x.to_parquet('test.parquet', schema=schema)**

e)要降价的桌子!

当你训练了一个模型或者对数据做了一些分析之后,你就可以生成表格(用于结果)。这些表格需要以 markdown 或 latex 的形式填写——在工作过程中或工作后进行报告。

由于可以将 DataFrame 对象转换成 markdown 格式作为输出,因此用新的格式编写文档变得更加容易。这确实是一个很好的特性,因为现在表格的降价可以动态生成。

**In [1]:** x = pd.DataFrame({'A': [1,2], 'B': [3,4]})**In [2]: print(x.to_markdown())** |    |   A |   B |
|---:|----:|----:| 
|  0 |   1 |   3 |
|  1 |   2 |   4 |

此外,还修复了多个不同主题的错误,如绘图I/O日期时间等。关于这些的更多信息可以在 1.0.0 的 Pandas 文档中找到。

想安装/升级熊猫?

要使用 pip 安装 Pandas(针对首次用户):

pip install pandas

对于已经有旧版本 Pandas 但想升级的用户:

pip install --upgrade pandas

也感谢所有管理和开发熊猫的贡献者/开发者🎉。

我希望你觉得这篇文章有趣并且有用。如果你有,请分享。

此外,如果你觉得有更重要的变化,请随时写在评论中。

🐼🐼🐼🐼🐼🐼谢谢大家!


  1. l ↩︎

  2. l ↩︎

  3. l ↩︎

  4. l ↩︎

posted @ 2024-10-16 08:59  绝不原创的飞龙  阅读(327)  评论(0)    收藏  举报